summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.kmk2
-rw-r--r--src/VBox/Additions/Makefile.kmk21
-rw-r--r--src/VBox/Additions/common/Makefile.kmk2
-rw-r--r--src/VBox/Additions/common/VBoxControl/Makefile.kmk2
-rw-r--r--src/VBox/Additions/common/VBoxControl/VBoxControl.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxControl/VBoxControl.rc2
-rw-r--r--src/VBox/Additions/common/VBoxControl/testcase/Makefile.kmk2
-rw-r--r--src/VBox/Additions/common/VBoxControl/testcase/tstVBoxControl.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/Makefile.kmk3
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.def2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-pnp.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp157
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h5
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest2.cpp10
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest2.h2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuestA-os2.asm2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/freebsd/Makefile3
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/common/VBoxGuest/freebsd/files_vboxguest5
-rw-r--r--src/VBox/Additions/common/VBoxGuest/linux/Makefile234
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest17
-rw-r--r--src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.inf21
-rw-r--r--src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.rc2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/Init.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/PhysHeap.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/SysHlp.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/SysHlp.h2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBGLInternal.h12
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBGLR3Internal.h2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c3
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp12
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAdditions.cpp6
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibBalloon.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibClipboard.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCoreDump.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCpuHotPlug.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCredentials.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibEvent.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGR.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp139
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp16
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibLog.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibModule.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMouse.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibRuntimeXF86.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSeamless.cpp22
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSharedFolders.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibStat.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibTime.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VbglR0CanUsePhysPageList.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxService/Makefile.kmk3
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxService-win.cpp22
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxService-win.rc2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxService.cpp266
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp18
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceClipboard-os2.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp16
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceControlDir.cpp90
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp40
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp8
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h12
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.h2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServicePropCache.cpp4
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceResource-win.h2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp14
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp1248
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceUtils.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceUtils.h2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxService/testcase/Makefile.kmk2
-rw-r--r--src/VBox/Additions/common/VBoxService/testcase/tstUserInfo.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp2
-rw-r--r--src/VBox/Additions/common/VBoxVideo/Modesetting.cpp106
-rw-r--r--src/VBox/Additions/common/VBoxVideo/VBVABase.cpp2
-rw-r--r--src/VBox/Additions/common/crOpenGL/Makefile.kmk2
-rw-r--r--src/VBox/Additions/common/crOpenGL/VBoxCROGL.rc2
-rw-r--r--src/VBox/Additions/common/crOpenGL/array/arrayspu.rc2
-rw-r--r--src/VBox/Additions/common/crOpenGL/context.c10
-rw-r--r--src/VBox/Additions/common/crOpenGL/dri_drv.c2
-rw-r--r--src/VBox/Additions/common/crOpenGL/dri_drv.h2
-rw-r--r--src/VBox/Additions/common/crOpenGL/dri_glx.h2
-rw-r--r--src/VBox/Additions/common/crOpenGL/fakedri_drv.c6
-rw-r--r--src/VBox/Additions/common/crOpenGL/fakedri_drv.h2
-rw-r--r--src/VBox/Additions/common/crOpenGL/fakedri_glfuncsList.h2
-rw-r--r--src/VBox/Additions/common/crOpenGL/fakedri_glxfuncsList.h2
-rw-r--r--src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c2
-rw-r--r--src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.rc2
-rw-r--r--src/VBox/Additions/common/crOpenGL/glx.c16
-rw-r--r--src/VBox/Additions/common/crOpenGL/glx_c_exports.c2
-rw-r--r--src/VBox/Additions/common/crOpenGL/glx_proto.h2
-rw-r--r--src/VBox/Additions/common/crOpenGL/icd_drv.c21
-rw-r--r--src/VBox/Additions/common/crOpenGL/icd_drv.h2
-rw-r--r--src/VBox/Additions/common/crOpenGL/load.c23
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu.rc2
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_client.c9
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c2
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_get.py9
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c8
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c20
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c2
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c50
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_net.c8
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_special1
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c2
-rw-r--r--src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.rc2
-rw-r--r--src/VBox/Additions/common/crOpenGL/stub.c11
-rw-r--r--src/VBox/Additions/common/crOpenGL/wgl.c11
-rw-r--r--src/VBox/Additions/common/pam/Makefile.kmk2
-rw-r--r--src/VBox/Additions/common/pam/pam_vbox.c9
-rw-r--r--src/VBox/Additions/common/testcase/Makefile.kmk2
-rw-r--r--src/VBox/Additions/common/testcase/tstPageFusion.cpp5
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/freebsd/Installer/vboxguest.sh0
-rw-r--r--src/VBox/Additions/freebsd/Makefile.kmk2
-rw-r--r--src/VBox/Additions/freebsd/drm/Makefile2
-rw-r--r--src/VBox/Additions/freebsd/drm/Makefile.kmk2
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/freebsd/drm/files_vboxvideo_drm2
-rw-r--r--src/VBox/Additions/freebsd/drm/vboxvideo_drm.c2
-rw-r--r--src/VBox/Additions/freebsd/vboxvfs/Makefile.kmk2
-rw-r--r--src/VBox/Additions/freebsd/vboxvfs/vboxvfs.h2
-rw-r--r--src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vfsops.c2
-rw-r--r--src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vnops.c2
-rw-r--r--src/VBox/Additions/linux/Makefile.kmk32
-rw-r--r--src/VBox/Additions/linux/drm/Makefile.kmk2
-rw-r--r--src/VBox/Additions/linux/drm/Makefile.module232
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/linux/drm/files_vboxvideo_drm4
-rw-r--r--src/VBox/Additions/linux/drm/vboxvideo_drm.c2
-rw-r--r--src/VBox/Additions/linux/drm/vboxvideo_drm.h2
-rw-r--r--src/VBox/Additions/linux/installer/90-vboxguest.fdi2
-rw-r--r--src/VBox/Additions/linux/installer/Makefile.include.header94
-rw-r--r--src/VBox/Additions/linux/installer/Makefile.test116
-rw-r--r--src/VBox/Additions/linux/installer/Makefile.test.drm22
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/linux/installer/autorun.sh2
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/linux/installer/deffiles0
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/linux/installer/vboxadd-service.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/linux/installer/vboxadd-x11.sh2
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/linux/installer/vboxadd.sh29
-rw-r--r--src/VBox/Additions/linux/sharedfolders/Makefile.kmk2
-rw-r--r--src/VBox/Additions/linux/sharedfolders/Makefile.module227
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/linux/sharedfolders/files_vboxsf4
-rw-r--r--src/VBox/Additions/linux/sharedfolders/vbsfmount.c2
-rw-r--r--src/VBox/Additions/solaris/DRM/Makefile.kmk2
-rw-r--r--src/VBox/Additions/solaris/DRM/vboxvideo_drm.c2
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/solaris/Installer/makepackage.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/solaris/Installer/postinstall.sh30
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/solaris/Installer/preremove.sh0
-rw-r--r--src/VBox/Additions/solaris/Makefile.kmk365
-rw-r--r--src/VBox/Additions/solaris/SharedFolders/Makefile.kmk5
-rw-r--r--src/VBox/Additions/solaris/SharedFolders/vboxfs.h2
-rw-r--r--src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c13
-rw-r--r--src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h2
-rw-r--r--src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h2
-rw-r--r--src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c391
-rw-r--r--src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h5
-rw-r--r--src/VBox/Additions/solaris/Virtio/Makefile.kmk2
-rw-r--r--src/VBox/Additions/solaris/Virtio/Virtio-solaris.c2
-rw-r--r--src/VBox/Additions/solaris/Virtio/Virtio-solaris.h2
-rw-r--r--src/VBox/Additions/solaris/Virtio/VirtioNet-solaris.c2
-rw-r--r--src/VBox/Additions/solaris/Virtio/VirtioPci-solaris.c2
-rw-r--r--src/VBox/Additions/solaris/Virtio/VirtioPci-solaris.h2
-rw-r--r--src/VBox/Additions/solaris/Virtio/VirtioRing-solaris.c2
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/x11/Installer/98vboxadd-xclient0
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/x11/Installer/x11config.pl0
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/x11/Installer/x11config.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/x11/Installer/x11config15.pl0
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/x11/Installer/x11config15sol.pl0
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/x11/Installer/x11config15suse.pl0
-rw-r--r--[-rwxr-xr-x]src/VBox/Additions/x11/Installer/x11restore.pl2
-rw-r--r--src/VBox/Additions/x11/Makefile.kmk2
-rw-r--r--src/VBox/Additions/x11/VBoxClient/Makefile.kmk18
-rw-r--r--src/VBox/Additions/x11/VBoxClient/VBoxClient.h2
-rw-r--r--src/VBox/Additions/x11/VBoxClient/clipboard.cpp4
-rw-r--r--src/VBox/Additions/x11/VBoxClient/clipboard.h4
-rw-r--r--src/VBox/Additions/x11/VBoxClient/display.cpp2
-rw-r--r--src/VBox/Additions/x11/VBoxClient/hostversion.cpp9
-rw-r--r--src/VBox/Additions/x11/VBoxClient/seamless-guest.h35
-rw-r--r--src/VBox/Additions/x11/VBoxClient/seamless-host.cpp6
-rw-r--r--src/VBox/Additions/x11/VBoxClient/seamless-host.h11
-rw-r--r--src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp264
-rw-r--r--src/VBox/Additions/x11/VBoxClient/seamless-x11.h259
-rw-r--r--src/VBox/Additions/x11/VBoxClient/seamless.h2
-rw-r--r--src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp152
-rw-r--r--src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp84
-rw-r--r--src/VBox/Additions/x11/VBoxClient/thread.cpp22
-rw-r--r--src/VBox/Additions/x11/vboxmouse/Makefile.kmk2
-rw-r--r--src/VBox/Additions/x11/vboxmouse/undefined_151
-rw-r--r--src/VBox/Additions/x11/vboxmouse/undefined_701
-rw-r--r--src/VBox/Additions/x11/vboxmouse/undefined_711
-rw-r--r--src/VBox/Additions/x11/vboxmouse/vboxmouse_15.c4
-rw-r--r--src/VBox/Additions/x11/vboxvideo/Makefile.kmk36
-rw-r--r--src/VBox/Additions/x11/vboxvideo/edid.c2
-rw-r--r--src/VBox/Additions/x11/vboxvideo/pointer.c591
-rw-r--r--src/VBox/Additions/x11/vboxvideo/setmode.c194
-rw-r--r--src/VBox/Additions/x11/vboxvideo/testcase/Makefile.kmk48
-rw-r--r--src/VBox/Additions/x11/vboxvideo/testcase/tstSetModeXOrg.c141
-rw-r--r--src/VBox/Additions/x11/vboxvideo/undefined (renamed from src/VBox/Additions/x11/vboxvideo/undefined_13)36
-rw-r--r--src/VBox/Additions/x11/vboxvideo/undefined_68108
-rw-r--r--src/VBox/Additions/x11/vboxvideo/undefined_70197
-rw-r--r--src/VBox/Additions/x11/vboxvideo/vboxutils.c792
-rw-r--r--src/VBox/Additions/x11/vboxvideo/vboxvideo.c380
-rw-r--r--src/VBox/Additions/x11/vboxvideo/vboxvideo.h54
-rw-r--r--src/VBox/Additions/x11/vboxvideo/vboxvideo_70.c1136
-rw-r--r--src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c2
-rw-r--r--src/VBox/Additions/x11/vboxvideo/vbva.c269
-rw-r--r--src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/sparc/sparc.h2
-rw-r--r--src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86-64/x86-64.h2
-rw-r--r--src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/3dnow.h2
-rw-r--r--src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/clip_args.h2
-rw-r--r--src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_asm.h2
-rw-r--r--src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_features.h2
-rw-r--r--src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_macros.h2
-rw-r--r--src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/norm_args.h2
-rw-r--r--src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/sse.h2
-rw-r--r--src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/x86.h2
-rw-r--r--src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/xform_args.h2
-rw-r--r--src/VBox/Additions/x11/x11stubs/Makefile.kmk2
-rw-r--r--src/VBox/Additions/x11/x11stubs/libXcomposite-1.0.0/libXcomposite.c2
-rw-r--r--src/VBox/Additions/x11/x11stubs/libXdamage-1.1.0/libXdamage.c2
-rw-r--r--src/VBox/Additions/x11/x11stubs/libXext-6.4.0/libXext.c2
-rw-r--r--src/VBox/Additions/x11/x11stubs/libXfixes-3.1.0/libXfixes.c2
-rw-r--r--src/VBox/Debugger/DBGCBuiltInSymbols.cpp498
-rw-r--r--src/VBox/Debugger/DBGCCmdHlp.cpp642
-rw-r--r--src/VBox/Debugger/DBGCCmdWorkers.cpp210
-rw-r--r--src/VBox/Debugger/DBGCCommands.cpp240
-rw-r--r--src/VBox/Debugger/DBGCEmulateCodeView.cpp701
-rw-r--r--src/VBox/Debugger/DBGCEval.cpp1160
-rw-r--r--src/VBox/Debugger/DBGCGdbRemoteStub.cpp4
-rw-r--r--src/VBox/Debugger/DBGCInternal.h34
-rw-r--r--src/VBox/Debugger/DBGCOps.cpp408
-rw-r--r--src/VBox/Debugger/DBGCTcp.cpp6
-rw-r--r--src/VBox/Debugger/DBGConsole.cpp1232
-rw-r--r--src/VBox/Debugger/DBGPlugInCommonELF.cpp2
-rw-r--r--src/VBox/Debugger/DBGPlugInCommonELF.h2
-rw-r--r--src/VBox/Debugger/DBGPlugInCommonELFTmpl.cpp.h2
-rw-r--r--src/VBox/Debugger/DBGPlugInDiggers.cpp2
-rw-r--r--src/VBox/Debugger/DBGPlugInLinux.cpp2
-rw-r--r--src/VBox/Debugger/DBGPlugInSolaris.cpp2
-rw-r--r--src/VBox/Debugger/DBGPlugInWinNt.cpp4
-rw-r--r--src/VBox/Debugger/DBGPlugIns.h2
-rw-r--r--src/VBox/Debugger/Makefile.kmk3
-rw-r--r--src/VBox/Debugger/VBoxDbg.cpp2
-rw-r--r--src/VBox/Debugger/VBoxDbgBase.cpp2
-rw-r--r--src/VBox/Debugger/VBoxDbgBase.h2
-rw-r--r--src/VBox/Debugger/VBoxDbgConsole.cpp2
-rw-r--r--src/VBox/Debugger/VBoxDbgConsole.h2
-rw-r--r--src/VBox/Debugger/VBoxDbgDisas.h2
-rw-r--r--src/VBox/Debugger/VBoxDbgGui.cpp2
-rw-r--r--src/VBox/Debugger/VBoxDbgGui.h2
-rw-r--r--src/VBox/Debugger/VBoxDbgStatsQt4.cpp2
-rw-r--r--src/VBox/Debugger/VBoxDbgStatsQt4.h2
-rw-r--r--src/VBox/Debugger/testcase/tstDBGCParser.cpp169
-rw-r--r--src/VBox/Debugger/testcase/tstDBGCStubs.cpp48
-rw-r--r--src/VBox/Debugger/testcase/tstVBoxDbg.cpp2
-rw-r--r--src/VBox/Devices/Audio/DevCodec.cpp501
-rw-r--r--src/VBox/Devices/Audio/DevCodec.h125
-rw-r--r--src/VBox/Devices/Audio/DevIchAc97.cpp2
-rw-r--r--src/VBox/Devices/Audio/DevIchIntelHDA.cpp514
-rw-r--r--src/VBox/Devices/Audio/DevSB16.cpp2
-rw-r--r--src/VBox/Devices/Audio/alsa_stubs.c2
-rw-r--r--src/VBox/Devices/Audio/audiosniffer.c2
-rw-r--r--src/VBox/Devices/Audio/coreaudio.c2
-rw-r--r--src/VBox/Devices/Audio/filteraudio.c2
-rw-r--r--src/VBox/Devices/Audio/pulse_stubs.c2
-rw-r--r--src/VBox/Devices/Audio/solaudio.c2
-rw-r--r--src/VBox/Devices/Bus/DevPCI.cpp40
-rw-r--r--src/VBox/Devices/Bus/DevPciIch9.cpp735
-rw-r--r--src/VBox/Devices/Bus/DevPciRaw.cpp530
-rw-r--r--src/VBox/Devices/Bus/MsiCommon.cpp21
-rw-r--r--src/VBox/Devices/Bus/MsiCommon.h11
-rw-r--r--src/VBox/Devices/Bus/MsixCommon.cpp37
-rw-r--r--src/VBox/Devices/Bus/PCIInternal.h44
-rw-r--r--src/VBox/Devices/Bus/SrvPciRawR0.cpp1031
-rw-r--r--src/VBox/Devices/EFI/DevEFI.cpp2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/DevEFI.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/DevEFI.mac2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxDebugLib.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxMemLayout.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxPkg.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxDebugLib.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxDebugLib.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintChar.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintGuid.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintHex.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintHexDump.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintString.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsBoot.c110
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsConnect.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsConsole.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsMisc.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/Bmp.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/DevicePath.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/InternalBdsLib.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/Performance.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/VBoxGenericBdsLib.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxOemHookStatusCodeLib/VBoxOemHookStatusCodeLib.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxOemHookStatusCodeLib/VBoxOemHookStatusCodeLib.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/BasePeCoff.c10
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/BasePeCoffLibInternals.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/PeCoffLoaderEx.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/VBoxPeCoffLib.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/ReadMe.txt6
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/Console.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/ConsoleControl.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/Cpu.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/VBoxAppleSim.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/VBoxAppleSim.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsole.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsole.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsoleDxe.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFsDxe.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFsDxe.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFswParam.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxHfs.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxIso9660.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_base.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_core.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_core.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi_base.h6
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi_lib.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_hfs.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_hfs.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_iso9660.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_iso9660.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_lib.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_strfunc.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/hfs_format.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/test/fsw_posix_base.h17
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ata.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Atapi.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/ComponentName.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/ComponentName.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/DriverConfiguration.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/DriverDiagnostics.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ide.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ide.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeBus.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeBus.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeData.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/VBoxIdeBusDxe.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxMisc/Makefile2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxMisc/efi-app/Readme.txt2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxOSELogo/VBoxOSELogo.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.dec2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.dsc2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.fdf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSE.dsc2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSE.fdf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSEX64.dsc2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgX64.dsc2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/LegacyBiosMpTable.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/TableConversion.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/VBoxSysTables.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/VBoxSysTables.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/ComponentName.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/DriverSupportedEfiVersion.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/Edid.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVga.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVga.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaDxe.inf2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaGraphicsOutput.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaI2c.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaI2c.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaUgaDraw.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x14.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x16.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x8.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFonts.h2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaMiniPortDxe.c2
-rw-r--r--src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaMiniPortDxe.inf2
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware2/VBoxPkg/env.sh2
-rw-r--r--src/VBox/Devices/EFI/Thunk/EfiThunk.asm4
-rw-r--r--src/VBox/Devices/EFI/Thunk/Makefile.kmk2
-rw-r--r--src/VBox/Devices/Graphics/BIOS/Makefile.kmk2
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/Graphics/BIOS/dataseghack0
-rw-r--r--src/VBox/Devices/Graphics/BIOS/vgatables.h21
-rw-r--r--src/VBox/Devices/Graphics/DevVGA.cpp107
-rw-r--r--src/VBox/Devices/Graphics/DevVGA.h25
-rw-r--r--src/VBox/Devices/Graphics/DevVGAModes.h2
-rw-r--r--src/VBox/Devices/Graphics/DevVGASavedState.h3
-rw-r--r--src/VBox/Devices/Graphics/DevVGATmpl.h2
-rw-r--r--src/VBox/Devices/Graphics/DevVGA_VDMA.cpp26
-rw-r--r--src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp2
-rw-r--r--src/VBox/Devices/Input/DevPS2.cpp31
-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.cpp37
-rw-r--r--src/VBox/Devices/Input/UsbMouse.cpp67
-rw-r--r--src/VBox/Devices/Makefile.kmk107
-rw-r--r--src/VBox/Devices/Network/DevE1000.cpp79
-rw-r--r--src/VBox/Devices/Network/DevE1000Phy.cpp2
-rw-r--r--src/VBox/Devices/Network/DevE1000Phy.h2
-rw-r--r--src/VBox/Devices/Network/DevEEPROM.cpp2
-rw-r--r--src/VBox/Devices/Network/DevEEPROM.h2
-rw-r--r--src/VBox/Devices/Network/DevINIP.cpp4
-rw-r--r--src/VBox/Devices/Network/DevPCNet.cpp25
-rw-r--r--src/VBox/Devices/Network/DevVirtioNet.cpp6
-rw-r--r--src/VBox/Devices/Network/DrvDedicatedNic.cpp2
-rw-r--r--src/VBox/Devices/Network/DrvIntNet.cpp32
-rw-r--r--src/VBox/Devices/Network/DrvNAT.cpp70
-rw-r--r--src/VBox/Devices/Network/DrvNetSniffer.cpp28
-rw-r--r--src/VBox/Devices/Network/DrvTAP.cpp115
-rw-r--r--src/VBox/Devices/Network/DrvUDPTunnel.cpp650
-rw-r--r--src/VBox/Devices/Network/DrvVDE.cpp76
-rw-r--r--src/VBox/Devices/Network/Pcap.cpp2
-rw-r--r--src/VBox/Devices/Network/Pcap.h2
-rw-r--r--src/VBox/Devices/Network/SrvIntNetR0.cpp49
-rw-r--r--src/VBox/Devices/Network/lwip/src/netif/ppp/chap.h2
-rw-r--r--src/VBox/Devices/Network/lwip/src/netif/ppp/chpms.h2
-rw-r--r--src/VBox/Devices/Network/lwip/src/netif/ppp/fsm.h2
-rw-r--r--src/VBox/Devices/Network/lwip/src/netif/ppp/ipcp.h2
-rw-r--r--src/VBox/Devices/Network/lwip/src/netif/ppp/lcp.h2
-rw-r--r--src/VBox/Devices/Network/lwip/src/netif/ppp/magic.h2
-rw-r--r--src/VBox/Devices/Network/lwip/src/netif/ppp/vj.h2
-rw-r--r--src/VBox/Devices/Network/lwip/vbox/sys_arch.c2
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/Network/scripts/VBoxConvertNATStats.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/Network/scripts/VBoxPortForwarding.py0
-rw-r--r--src/VBox/Devices/Network/slirp/bootp.c22
-rw-r--r--src/VBox/Devices/Network/slirp/bootp.h2
-rw-r--r--src/VBox/Devices/Network/slirp/bsd/kern/kern_mbuf.c8
-rw-r--r--src/VBox/Devices/Network/slirp/cksum.c2
-rw-r--r--src/VBox/Devices/Network/slirp/counters.h2
-rw-r--r--src/VBox/Devices/Network/slirp/ctl.h2
-rw-r--r--src/VBox/Devices/Network/slirp/debug.c134
-rw-r--r--src/VBox/Devices/Network/slirp/debug.h13
-rw-r--r--src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.c6
-rw-r--r--src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.h2
-rw-r--r--src/VBox/Devices/Network/slirp/dnsproxy/hash.c2
-rw-r--r--src/VBox/Devices/Network/slirp/ext.h2
-rw-r--r--src/VBox/Devices/Network/slirp/icmp_var.h2
-rw-r--r--src/VBox/Devices/Network/slirp/if.h2
-rw-r--r--src/VBox/Devices/Network/slirp/ip.h2
-rw-r--r--src/VBox/Devices/Network/slirp/ip_icmp.c41
-rw-r--r--src/VBox/Devices/Network/slirp/ip_icmp.h2
-rw-r--r--src/VBox/Devices/Network/slirp/ip_input.c29
-rw-r--r--src/VBox/Devices/Network/slirp/ip_output.c56
-rw-r--r--src/VBox/Devices/Network/slirp/libalias/alias_dns.c6
-rw-r--r--src/VBox/Devices/Network/slirp/libslirp.h3
-rw-r--r--src/VBox/Devices/Network/slirp/main.h2
-rw-r--r--src/VBox/Devices/Network/slirp/misc.c66
-rw-r--r--src/VBox/Devices/Network/slirp/misc.h2
-rw-r--r--src/VBox/Devices/Network/slirp/queue.h2
-rw-r--r--src/VBox/Devices/Network/slirp/sbuf.c4
-rw-r--r--src/VBox/Devices/Network/slirp/sbuf.h2
-rw-r--r--src/VBox/Devices/Network/slirp/slirp.c69
-rw-r--r--src/VBox/Devices/Network/slirp/slirp.h2
-rw-r--r--src/VBox/Devices/Network/slirp/slirp_config.h2
-rw-r--r--src/VBox/Devices/Network/slirp/slirp_state.h2
-rw-r--r--src/VBox/Devices/Network/slirp/socket.c72
-rw-r--r--src/VBox/Devices/Network/slirp/socket.h2
-rw-r--r--src/VBox/Devices/Network/slirp/tcp.h2
-rw-r--r--src/VBox/Devices/Network/slirp/tcp_input.c122
-rw-r--r--src/VBox/Devices/Network/slirp/tcp_output.c4
-rw-r--r--src/VBox/Devices/Network/slirp/tcp_subr.c28
-rw-r--r--src/VBox/Devices/Network/slirp/tcp_timer.c8
-rw-r--r--src/VBox/Devices/Network/slirp/tcp_timer.h2
-rw-r--r--src/VBox/Devices/Network/slirp/tcp_var.h2
-rw-r--r--src/VBox/Devices/Network/slirp/tcpip.h2
-rw-r--r--src/VBox/Devices/Network/slirp/tftp.c2
-rw-r--r--src/VBox/Devices/Network/slirp/tftp.h2
-rw-r--r--src/VBox/Devices/Network/slirp/udp.c23
-rw-r--r--src/VBox/Devices/Network/slirp/udp.h2
-rw-r--r--src/VBox/Devices/Network/solaris/vbox-libdlpi.cpp2
-rw-r--r--src/VBox/Devices/Network/solaris/vbox-libdlpi.h2
-rw-r--r--src/VBox/Devices/Network/testcase/tstDevEEPROM.cpp2
-rw-r--r--src/VBox/Devices/Network/testcase/tstDevPhy.cpp2
-rw-r--r--src/VBox/Devices/Network/testcase/tstIntNet-1.cpp4
-rw-r--r--src/VBox/Devices/Network/testcase/tstIntNetR0.cpp2
-rw-r--r--src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp2
-rw-r--r--src/VBox/Devices/PC/BIOS/Makefile.kmk5
-rw-r--r--src/VBox/Devices/PC/BIOS/ahci.c1698
-rw-r--r--src/VBox/Devices/PC/BIOS/logo.c2
-rw-r--r--src/VBox/Devices/PC/BIOS/rombios.c102
-rw-r--r--src/VBox/Devices/PC/BIOS/scsi.c7
-rw-r--r--src/VBox/Devices/PC/DevACPI.cpp2666
-rw-r--r--src/VBox/Devices/PC/DevAPIC.cpp1628
-rw-r--r--src/VBox/Devices/PC/DevApic.h77
-rw-r--r--src/VBox/Devices/PC/DevDMA.cpp1373
-rw-r--r--src/VBox/Devices/PC/DevFwCommon.cpp2
-rw-r--r--src/VBox/Devices/PC/DevFwCommon.h2
-rw-r--r--src/VBox/Devices/PC/DevHPET.cpp1584
-rw-r--r--src/VBox/Devices/PC/DevIoApic.cpp729
-rw-r--r--src/VBox/Devices/PC/DevLPC.cpp4
-rw-r--r--src/VBox/Devices/PC/DevPIC.cpp33
-rw-r--r--src/VBox/Devices/PC/DevPcArch.c2
-rw-r--r--src/VBox/Devices/PC/DevPcBios.cpp116
-rw-r--r--src/VBox/Devices/PC/DevPcBios.h2
-rw-r--r--src/VBox/Devices/PC/DevPit-i8254.cpp158
-rw-r--r--src/VBox/Devices/PC/DevRTC.cpp725
-rw-r--r--src/VBox/Devices/PC/DevSMC.cpp2
-rw-r--r--src/VBox/Devices/PC/DrvACPI.cpp2
-rw-r--r--src/VBox/Devices/PC/DrvAcpiCpu.cpp2
-rw-r--r--src/VBox/Devices/PC/Etherboot-src/Makefile.kmk2
-rw-r--r--src/VBox/Devices/PC/Etherboot-src/arch/i386/drivers/net/undi.c2
-rw-r--r--src/VBox/Devices/PC/Etherboot-src/arch/i386/drivers/net/undi.h2
-rw-r--r--src/VBox/Devices/PC/Etherboot-src/arch/i386/firmware/pcbios/basemem.c2
-rw-r--r--src/VBox/Devices/PC/Etherboot-src/arch/i386/include/callbacks_arch.h2
-rw-r--r--src/VBox/Devices/PC/Etherboot-src/core/dns_resolver.c4
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/PC/Etherboot-src/genrules.pl0
-rw-r--r--src/VBox/Devices/PC/Etherboot-src/include/callbacks.h2
-rw-r--r--src/VBox/Devices/PC/Etherboot-src/include/pxe.h2
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/PC/Etherboot-src/util/catrom.pl0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/PC/Etherboot-src/util/disrom.pl0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/PC/Etherboot-src/util/geniso0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/PC/Etherboot-src/util/genliso0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/PC/Etherboot-src/util/get-pci-ids0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/PC/Etherboot-src/util/makelilo.pl0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/PC/Etherboot-src/util/makerom.pl0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/PC/Etherboot-src/util/modrom.pl0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/PC/Etherboot-src/util/swapdevids.pl0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/PC/Etherboot-src/util/zfilelen.pl0
-rw-r--r--src/VBox/Devices/PC/vbox-cpuhotplug.dsl2
-rw-r--r--src/VBox/Devices/PC/vbox-standard.dsl2
-rw-r--r--src/VBox/Devices/PC/vbox.dsl72
-rw-r--r--src/VBox/Devices/Parallel/DevParallel.cpp4
-rw-r--r--src/VBox/Devices/Parallel/DrvHostParallel.cpp107
-rw-r--r--src/VBox/Devices/Samples/Makefile.kmk2
-rw-r--r--src/VBox/Devices/Samples/VBoxSampleDevice.cpp2
-rw-r--r--src/VBox/Devices/Serial/DevSerial.cpp79
-rw-r--r--src/VBox/Devices/Serial/DrvChar.cpp15
-rw-r--r--src/VBox/Devices/Serial/DrvHostSerial.cpp143
-rw-r--r--src/VBox/Devices/Serial/DrvNamedPipe.cpp2
-rw-r--r--src/VBox/Devices/Serial/DrvRawFile.cpp28
-rw-r--r--src/VBox/Devices/Storage/ATAController.cpp273
-rw-r--r--src/VBox/Devices/Storage/ATAController.h54
-rw-r--r--src/VBox/Devices/Storage/Debug.cpp2
-rw-r--r--src/VBox/Devices/Storage/DevAHCI.cpp1178
-rw-r--r--src/VBox/Devices/Storage/DevATA.cpp215
-rw-r--r--src/VBox/Devices/Storage/DevBusLogic.cpp41
-rw-r--r--src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp33
-rw-r--r--src/VBox/Devices/Storage/DevLsiLogicSCSI.h2
-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/DrvHostBase.cpp191
-rw-r--r--src/VBox/Devices/Storage/DrvHostBase.h6
-rw-r--r--src/VBox/Devices/Storage/DrvHostDVD.cpp40
-rw-r--r--src/VBox/Devices/Storage/DrvHostFloppy.cpp8
-rw-r--r--src/VBox/Devices/Storage/DrvMediaISO.cpp46
-rw-r--r--src/VBox/Devices/Storage/DrvRawImage.cpp53
-rw-r--r--src/VBox/Devices/Storage/DrvSCSI.cpp2
-rw-r--r--src/VBox/Devices/Storage/DrvSCSIHost.cpp21
-rw-r--r--src/VBox/Devices/Storage/DrvVD.cpp18
-rw-r--r--src/VBox/Devices/Storage/UsbMsd.cpp4
-rw-r--r--src/VBox/Devices/Storage/VBoxSCSI.cpp2
-rw-r--r--src/VBox/Devices/Storage/VBoxSCSI.h2
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp2
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSIInline.h2
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h2
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSIIoReq.cpp2
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSILun.cpp2
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp2
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSISense.cpp2
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSISgBuf.cpp2
-rw-r--r--src/VBox/Devices/Storage/fdc.c31
-rw-r--r--src/VBox/Devices/Storage/ide.h22
-rw-r--r--src/VBox/Devices/USB/DevOHCI.cpp30
-rw-r--r--src/VBox/Devices/USB/DrvVUSBRootHub.cpp2
-rw-r--r--src/VBox/Devices/USB/USBProxyDevice-stub.cpp2
-rw-r--r--src/VBox/Devices/USB/USBProxyDevice.cpp6
-rw-r--r--src/VBox/Devices/USB/USBProxyDevice.h4
-rw-r--r--src/VBox/Devices/USB/VUSBDevice.cpp2
-rw-r--r--src/VBox/Devices/USB/VUSBInternal.h2
-rw-r--r--src/VBox/Devices/USB/VUSBReadAhead.cpp2
-rw-r--r--src/VBox/Devices/USB/VUSBUrb.cpp2
-rw-r--r--src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp2
-rw-r--r--src/VBox/Devices/USB/freebsd/USBProxyDevice-freebsd.cpp41
-rw-r--r--src/VBox/Devices/USB/linux/USBProxyDevice-linux.cpp40
-rw-r--r--src/VBox/Devices/USB/os2/USBProxyDevice-os2.cpp2
-rw-r--r--src/VBox/Devices/USB/solaris/USBProxyDevice-solaris.cpp42
-rw-r--r--src/VBox/Devices/USB/testcase/tstPalmOne.c2
-rw-r--r--src/VBox/Devices/USB/testcase/tstTrekStorGo.c2
-rw-r--r--src/VBox/Devices/USB/vrdp/USBProxyDevice-vrdp.cpp2
-rw-r--r--src/VBox/Devices/USB/win/USBProxyDevice-win.cpp91
-rw-r--r--src/VBox/Devices/VMMDev/VMMDev.cpp53
-rw-r--r--src/VBox/Devices/VMMDev/VMMDevHGCM.cpp2
-rw-r--r--src/VBox/Devices/VMMDev/VMMDevState.h6
-rw-r--r--src/VBox/Devices/VMMDev/VMMDevTesting.cpp4
-rw-r--r--src/VBox/Devices/VMMDev/VMMDevTesting.h2
-rw-r--r--src/VBox/Devices/VirtIO/Virtio.cpp5
-rw-r--r--src/VBox/Devices/VirtIO/Virtio.h2
-rw-r--r--src/VBox/Devices/build/Makefile.kup (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/Makefile.kup)0
-rw-r--r--src/VBox/Devices/build/VBoxDD-dtrace.d2
-rw-r--r--src/VBox/Devices/build/VBoxDD.cpp23
-rw-r--r--src/VBox/Devices/build/VBoxDD.h9
-rw-r--r--src/VBox/Devices/build/VBoxDD2.h2
-rw-r--r--src/VBox/Devices/build/VBoxDD2R0.cpp31
-rw-r--r--src/VBox/Devices/build/VBoxDDR0.cpp31
-rw-r--r--src/VBox/Devices/build/VBoxDDUDeps.cpp2
-rw-r--r--src/VBox/Devices/build/vl_vbox.h2
-rw-r--r--src/VBox/Devices/testcase/Makefile.kmk8
-rw-r--r--src/VBox/Devices/testcase/tstDeviceStructSize.cpp21
-rw-r--r--src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp61
-rw-r--r--src/VBox/Disassembler/DisasmFormatBytes.cpp2
-rw-r--r--src/VBox/Disassembler/DisasmFormatYasm.cpp2
-rw-r--r--src/VBox/Disassembler/DisasmTables.cpp26
-rw-r--r--src/VBox/Disassembler/DisasmTestA.asm4
-rw-r--r--src/VBox/Disassembler/Makefile.kmk2
-rw-r--r--src/VBox/Disassembler/testcase/Makefile.kmk2
-rw-r--r--src/VBox/Disassembler/testcase/tstAsm.mac2
-rw-r--r--src/VBox/Disassembler/testcase/tstAsmFnstsw-1.asm2
-rw-r--r--src/VBox/Disassembler/testcase/tstAsmLock-1.asm2
-rw-r--r--src/VBox/Disassembler/testcase/tstAsmLock-2.asm2
-rw-r--r--src/VBox/Disassembler/testcase/tstAsmLock-3.asm2
-rw-r--r--src/VBox/Disassembler/testcase/tstAsmMovSeg-1.asm2
-rw-r--r--src/VBox/Disassembler/testcase/tstAsmMovzx-1.asm2
-rw-r--r--src/VBox/Disassembler/testcase/tstAsmPop-1.asm2
-rw-r--r--src/VBox/Disassembler/testcase/tstAsmPush-1.asm2
-rw-r--r--src/VBox/Disassembler/testcase/tstAsmRegs-1.asm2
-rw-r--r--src/VBox/Disassembler/testcase/tstAsmSignExtend-1.asm2
-rw-r--r--src/VBox/Disassembler/testcase/tstDisasm-2.cpp2
-rw-r--r--src/VBox/ExtPacks/BusMouseSample/BusMouse.cpp886
-rw-r--r--src/VBox/ExtPacks/Skeleton/ExtPack.xml10
-rw-r--r--src/VBox/ExtPacks/Skeleton/Makefile.kmk163
-rw-r--r--src/VBox/ExtPacks/Skeleton/VBoxSkeletonMain.cpp137
-rw-r--r--src/VBox/Frontends/Common/Makefile.kmk2
-rw-r--r--src/VBox/Frontends/Common/VBoxKeyboard/Makefile.kmk8
-rw-r--r--src/VBox/Frontends/Common/VBoxKeyboard/keyboard-layouts.h2
-rw-r--r--src/VBox/Frontends/Common/VBoxKeyboard/keyboard-list.h2
-rw-r--r--src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h2
-rw-r--r--src/VBox/Frontends/Common/VBoxKeyboard/keyboard-types.h2
-rw-r--r--src/VBox/Frontends/Common/VBoxKeyboard/keyboard.c2
-rw-r--r--src/VBox/Frontends/Common/VBoxKeyboard/xkbtoscan.h2
-rw-r--r--src/VBox/Frontends/Makefile.kmk2
-rw-r--r--src/VBox/Frontends/VBoxBFE/COMDefs.h3
-rw-r--r--src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp13
-rw-r--r--src/VBox/Frontends/VBoxBFE/DisplayImpl.h2
-rw-r--r--src/VBox/Frontends/VBoxBFE/HostUSBDeviceImpl.cpp540
-rw-r--r--src/VBox/Frontends/VBoxBFE/HostUSBDeviceImpl.h126
-rw-r--r--src/VBox/Frontends/VBoxBFE/HostUSBImpl.cpp310
-rw-r--r--src/VBox/Frontends/VBoxBFE/HostUSBImpl.h67
-rw-r--r--src/VBox/Frontends/VBoxBFE/KeyboardImpl.cpp2
-rw-r--r--src/VBox/Frontends/VBoxBFE/KeyboardImpl.h2
-rw-r--r--src/VBox/Frontends/VBoxBFE/Makefile.kmk61
-rw-r--r--src/VBox/Frontends/VBoxBFE/StatusImpl.cpp2
-rw-r--r--src/VBox/Frontends/VBoxBFE/StatusImpl.h2
-rw-r--r--src/VBox/Frontends/VBoxBFE/USBProxyService.cpp386
-rw-r--r--src/VBox/Frontends/VBoxBFE/USBProxyService.h240
-rw-r--r--src/VBox/Frontends/VBoxBFE/USBProxyServiceLinux.cpp1051
-rw-r--r--src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp158
-rw-r--r--src/VBox/Frontends/VBoxBFE/VBoxBFE.h2
-rw-r--r--src/VBox/Frontends/VBoxBFE/VBoxBFEHardened.cpp2
-rw-r--r--src/VBox/Frontends/VBoxBFE/VMMDev.h2
-rw-r--r--src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp5
-rw-r--r--src/VBox/Frontends/VBoxBFE/VirtualBoxBase.h46
-rw-r--r--src/VBox/Frontends/VBoxBFE/testcase/Makefile.kup (renamed from src/VBox/HostDrivers/VBoxUSB/win/Device/Makefile.kup)0
-rw-r--r--src/VBox/Frontends/VBoxBFE/testcase/tstMouseImpl.cpp387
-rw-r--r--src/VBox/Frontends/VBoxBalloonCtrl/Makefile.kmk2
-rw-r--r--src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.cpp22
-rw-r--r--src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.h2
-rw-r--r--src/VBox/Frontends/VBoxFB/Makefile.kmk2
-rw-r--r--src/VBox/Frontends/VBoxFB/VBoxFB.h5
-rw-r--r--src/VBox/Frontends/VBoxHeadless/FramebufferVNC.cpp2
-rw-r--r--src/VBox/Frontends/VBoxHeadless/FramebufferVNC.h2
-rw-r--r--src/VBox/Frontends/VBoxHeadless/Makefile.kmk2
-rw-r--r--src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp67
-rw-r--r--src/VBox/Frontends/VBoxHeadless/VBoxHeadlessHardened.cpp2
-rw-r--r--src/VBox/Frontends/VBoxHeadless/VideoCapture/Makefile.kmk2
-rw-r--r--src/VBox/Frontends/VBoxHeadless/testcase/Makefile.kmk2
-rw-r--r--src/VBox/Frontends/VBoxManage/Makefile.kmk72
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp149
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManage.cpp19
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManage.h23
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp52
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp2
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp156
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp2
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp2
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp22
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp1933
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp7
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp63
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageHostonly.cpp2
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp310
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageList.cpp13
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp2
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp251
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp262
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp2
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp291
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp2
-rw-r--r--src/VBox/Frontends/VBoxSDL/Helper.cpp3
-rw-r--r--src/VBox/Frontends/VBoxSDL/Makefile.kmk2
-rw-r--r--src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp64
-rw-r--r--src/VBox/Frontends/VBoxSDL/VBoxSDLHardened.cpp2
-rwxr-xr-x[-rw-r--r--]src/VBox/Frontends/VBoxSDL/VBoxSDLMain-darwin.m0
-rw-r--r--src/VBox/Frontends/VBoxSDL/VBoxSDLTest.cpp2
-rw-r--r--src/VBox/Frontends/VBoxShell/Makefile.kmk4
-rw-r--r--[-rwxr-xr-x]src/VBox/Frontends/VBoxShell/vboxshell.py208
-rw-r--r--src/VBox/Frontends/VirtualBox/Makefile.kmk43
-rw-r--r--src/VBox/Frontends/VirtualBox/VBoxUI.pro14
-rw-r--r--src/VBox/Frontends/VirtualBox/VirtualBox1.qrc4
-rw-r--r--src/VBox/Frontends/VirtualBox/VirtualBox2.qrc9
-rw-r--r--src/VBox/Frontends/VirtualBox/VirtualBoxMac.qrc1
-rw-r--r--src/VBox/Frontends/VirtualBox/VirtualBoxOther.qrc1
-rw-r--r--src/VBox/Frontends/VirtualBox/images/os_opensolaris.pngbin3046 -> 0 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/images/os_opensolaris_64.pngbin2885 -> 0 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/images/os_oraclesolaris.pngbin0 -> 4361 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/images/os_oraclesolaris_64.pngbin0 -> 4608 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/images/progress_clone_90px.pngbin0 -> 10634 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/images/proxy_16px.pngbin0 -> 3402 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/images/proxy_32px.pngbin0 -> 4524 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/images/proxy_disabled_16px.pngbin0 -> 3322 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/images/proxy_disabled_32px.pngbin0 -> 4251 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/images/vm_clone_16px.pngbin0 -> 3590 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/images/vm_clone_disabled_16px.pngbin0 -> 3544 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/images/vmw_clone.pngbin0 -> 30619 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/images/vmw_clone_bg.pngbin0 -> 47316 bytes
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/ApprovedLanguages.kmk2
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ar.ts954
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_bg.ts1025
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts1023
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca_VA.ts1073
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_cs.ts1013
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_da.ts1029
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_de.ts1121
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_el.ts917
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_es.ts1113
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_eu.ts991
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_fi.ts1010
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_fr.ts1015
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_gl_ES.ts1011
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_hu.ts1025
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_id.ts991
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts1033
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ja.ts4694
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_km_KH.ts1009
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ko.ts1031
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts1037
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts1025
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_pl.ts997
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt.ts2549
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt_BR.ts1073
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ro.ts1002
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ru.ts1029
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_sk.ts1009
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_sr.ts1716
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_sv.ts1041
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_tr.ts1012
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_uk.ts1025
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_xx_YY.ts917
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_CN.ts1006
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_TW.ts1037
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/qt_sv.ts8117
-rw-r--r--src/VBox/Frontends/VirtualBox/src/UIMediumTypeChangeDialog.cpp187
-rw-r--r--src/VBox/Frontends/VirtualBox/src/UIMediumTypeChangeDialog.h76
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxAboutDlg.cpp4
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxGLSupportInfo.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxGlobalSettings.cpp6
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxGlobalSettings.h7
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxHelpActions.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxLicenseViewer.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.cpp120
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.h6
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.ui64
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxMedium.cpp5
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxMedium.h4
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxSnapshotDetailsDlg.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxTakeSnapshotDlg.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxUpdateDlg.cpp16
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxVMInformationDlg.cpp7
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxVMLogViewer.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIAdvancedSlider.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIArrowButtonPress.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIArrowButtonSwitch.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIArrowSplitter.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIDialog.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIDialogButtonBox.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIFileDialog.cpp23
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIHttp.h6
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QILabel.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QILabelSeparator.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QILineEdit.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIListView.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIMainDialog.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.h4
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIRichToolButton.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QISplitter.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIStateIndicator.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIStatusBar.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QITableView.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QITreeView.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QITreeWidget.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIWidgetValidator.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/extensions/QIWizard.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/COMDefs.cpp12
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h144
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/COMWrappers.xsl62
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.cpp6
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/UIIconPool.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/UIImageTools.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.cpp29
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.h8
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.h2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp125
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h29
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.cpp224
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.h27
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/VBoxUtils.h74
-rw-r--r--src/VBox/Frontends/VirtualBox/src/hardenedmain.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/main.cpp32
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/CocoaEventHelper.mm2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/DockIconPreview.h2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/Info.plist24
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/UIAbstractDockIconPreview.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/UIAbstractDockIconPreview.h2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.mm2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaDockIconPreview.h2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaDockIconPreview.mm2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaSpecialControls.mm10
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/UIDesktopServices_darwin.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/UIDesktopServices_darwin_cocoa.mm2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/UIWindowMenuManager.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxIChatTheaterWrapper.h2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxIChatTheaterWrapper.m2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin-cocoa.mm2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.cpp3
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/tstDarwinKeyboard.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/darwin/vmstarter.mm2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/os2/VBoxHlp.asm2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/os2/VBoxHlp.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/win/UIDesktopServices_win.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/win/VBoxUtils-win.cpp79
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/win/VBoxUtils-win.h36
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/x11/UIDesktopServices_x11.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/x11/VBoxX11Helper.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/platform/x11/XKeyboard-new.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/precomp.h2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.cpp233
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.h15
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIConsoleEventHandler.cpp19
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIConsoleEventHandler.h2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferDirectDraw.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQGL.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.cpp4
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQuartz2D.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferSDL.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.cpp23
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp415
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.h10
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp250
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h7
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.cpp31
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.h1
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMachineShortcuts.cpp17
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMachineShortcuts.h15
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp43
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.h2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.cpp88
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.h1
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp50
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UISession.h3
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIVMCloseDialog.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIKeyboardHandlerFullscreen.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp15
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/normal/UIKeyboardHandlerNormal.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp15
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h1
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/scale/UIKeyboardHandlerScale.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineLogicScale.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineViewScale.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp8
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIKeyboardHandlerSeamless.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp15
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.cpp3
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.h1
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp234
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/UIVMItem.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/UIVMListView.cpp4
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/UIVMPreviewWindow.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/UIVirtualBoxEventHandler.cpp6
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp120
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.h3
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp263
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.h19
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/UISettingsDefs.cpp49
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/UISettingsDefs.h167
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.cpp132
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.h51
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp500
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.h38
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.cpp97
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.h78
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/VBoxSettingsSelector.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsGeneral.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsInput.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsLanguage.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetwork.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetworkDetails.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsProxy.cpp166
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsProxy.h88
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsProxy.ui214
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsUpdate.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsAudio.cpp88
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsAudio.h30
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp407
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.h73
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.ui3
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp177
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.h53
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp1487
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.h203
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.ui166
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsParallel.cpp199
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsParallel.h57
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsPortForwardingDlg.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsPortForwardingDlg.h10
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp528
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.h73
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSFDetails.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.cpp236
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.h60
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp979
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.h121
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.ui88
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.cpp301
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.h71
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.ui108
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.cpp667
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.h90
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.ui19
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSBFilterDetails.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/UIBar.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/UIBootTable.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.cpp35
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderUserManual.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/UIHotKeyEditor.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/UIPopupBox.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/UIProgressDialog.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/UISpecialControls.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.cpp5
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.ui19
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxExportApplianceWgt.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxFilePathSelectorWidget.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxImportApplianceWgt.cpp9
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxLineTextEdit.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorButton.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxWarningPane.cpp9
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/clonevm/Makefile.kup (renamed from src/VBox/HostDrivers/VBoxUSB/win/Filter/Makefile.kup)0
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.cpp268
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.h136
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizardPage1.ui90
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizardPage2.ui91
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIExportApplianceWzd.cpp3
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIFirstRunWzd.cpp4
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIImportApplianceWzd.cpp3
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizard.cpp1083
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizard.h332
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageFormat.ui (renamed from src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzdPage1.ui)20
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageOptions.ui (renamed from src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzdPage3.ui)26
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageSummary.ui (renamed from src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzdPage4.ui)17
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageVariant.ui72
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageWelcome.ui (renamed from src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzdPage2.ui)46
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzd.cpp544
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzd.h198
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/newvm/UINewVMWzd.cpp30
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/registration/UIRegistrationWzd.cpp2
-rw-r--r--src/VBox/GuestHost/HGSMI/Makefile.kmk2
-rw-r--r--src/VBox/GuestHost/Makefile.kmk2
-rw-r--r--src/VBox/GuestHost/OpenGL/Makefile.kmk2
-rw-r--r--src/VBox/GuestHost/OpenGL/error/error.py3
-rw-r--r--src/VBox/GuestHost/OpenGL/error/errorspu.rc2
-rw-r--r--[-rwxr-xr-x]src/VBox/GuestHost/OpenGL/glapi_parser/apiutil.py0
-rw-r--r--src/VBox/GuestHost/OpenGL/include/cr_glstate.h3
-rw-r--r--src/VBox/GuestHost/OpenGL/include/cr_hash.h2
-rw-r--r--src/VBox/GuestHost/OpenGL/include/cr_server.h45
-rw-r--r--src/VBox/GuestHost/OpenGL/include/cr_spu.h1
-rw-r--r--src/VBox/GuestHost/OpenGL/include/state/cr_buffer.h5
-rw-r--r--src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h2
-rw-r--r--src/VBox/GuestHost/OpenGL/include/state/cr_glsl.h2
-rw-r--r--src/VBox/GuestHost/OpenGL/packer/pack_client.c2
-rw-r--r--src/VBox/GuestHost/OpenGL/packer/pack_framebuffer.c2
-rw-r--r--src/VBox/GuestHost/OpenGL/packer/pack_shaders.c46
-rw-r--r--src/VBox/GuestHost/OpenGL/packer/pack_texture.c8
-rwxr-xr-x[-rw-r--r--]src/VBox/GuestHost/OpenGL/packer/pack_visibleregion.c0
-rw-r--r--src/VBox/GuestHost/OpenGL/spu_loader/glloader.py2
-rw-r--r--src/VBox/GuestHost/OpenGL/spu_loader/loader.def1
-rw-r--r--src/VBox/GuestHost/OpenGL/spu_loader/spuchange.py17
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_buffer.c7
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_client.c74
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c72
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c5
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c10
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_init.c5
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_program.c83
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c74
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_texdiff.c184
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c14
-rw-r--r--src/VBox/GuestHost/OpenGL/util/hash.c13
-rw-r--r--src/VBox/GuestHost/OpenGL/util/util.rc2
-rw-r--r--src/VBox/GuestHost/OpenGL/util/vboxhgcm.c93
-rw-r--r--src/VBox/GuestHost/OpenGL/util/vboxhgsmi.c2
-rw-r--r--src/VBox/GuestHost/SharedClipboard/Makefile.kmk2
-rw-r--r--src/VBox/GuestHost/SharedClipboard/clipboard-helper.cpp2
-rw-r--r--src/VBox/GuestHost/SharedClipboard/x11-clipboard.cpp53
-rw-r--r--src/VBox/HostDrivers/Makefile.kmk12
-rw-r--r--src/VBox/HostDrivers/Support/Makefile.kmk15
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrv-dtrace.d2
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrv.c120
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrvIDC.h2
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrvIOC.h10
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrvInternal.h16
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrvSem.c2
-rw-r--r--src/VBox/HostDrivers/Support/SUPLib.cpp39
-rw-r--r--src/VBox/HostDrivers/Support/SUPLibInternal.h15
-rw-r--r--src/VBox/HostDrivers/Support/SUPLibSem.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/SUPR0.def5
-rw-r--r--src/VBox/HostDrivers/Support/SUPR0IdcClient.c2
-rw-r--r--src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c2
-rw-r--r--src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h2
-rw-r--r--src/VBox/HostDrivers/Support/SUPR0IdcClientStubs.c2
-rw-r--r--src/VBox/HostDrivers/Support/SUPR3HardenedIPRT.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp8
-rw-r--r--src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp11
-rw-r--r--src/VBox/HostDrivers/Support/SUPSvc.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/SUPSvcGlobal.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/SUPSvcGrant.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/SUPSvcInternal.h2
-rw-r--r--src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp24
-rw-r--r--src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp8
-rw-r--r--src/VBox/HostDrivers/Support/darwin/SUPR0IdcClient-darwin.c2
-rw-r--r--src/VBox/HostDrivers/Support/freebsd/Makefile7
-rw-r--r--src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c6
-rw-r--r--src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp6
-rw-r--r--src/VBox/HostDrivers/Support/freebsd/SUPR0IdcClient-freebsd.c2
-rw-r--r--[-rwxr-xr-x]src/VBox/HostDrivers/Support/freebsd/files_vboxdrv7
-rw-r--r--src/VBox/HostDrivers/Support/linux/Makefile5
-rw-r--r--src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c23
-rw-r--r--src/VBox/HostDrivers/Support/linux/SUPDrv-linux.mod.c2
-rw-r--r--src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp10
-rw-r--r--src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c2
-rw-r--r--[-rwxr-xr-x]src/VBox/HostDrivers/Support/linux/files_vboxdrv15
-rw-r--r--src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp6
-rw-r--r--src/VBox/HostDrivers/Support/os2/SUPDrv-os2.def2
-rw-r--r--src/VBox/HostDrivers/Support/os2/SUPDrvA-os2.asm2
-rw-r--r--src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp8
-rw-r--r--src/VBox/HostDrivers/Support/os2/SUPR0IdcClient-os2.c2
-rw-r--r--src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c238
-rw-r--r--src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp6
-rw-r--r--src/VBox/HostDrivers/Support/solaris/SUPR0IdcClient-solaris.c2
-rwxr-xr-xsrc/VBox/HostDrivers/Support/solaris/mod.sh6
-rw-r--r--src/VBox/HostDrivers/Support/testcase/Makefile.kmk2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/SUPInstall.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/SUPLoggerCtl.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/SUPUninstall.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstContiguous.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstGetPagingMode.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstInit.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstInt.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstLow.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstPage.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstPin.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstSupLoadModule.cpp4
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstSupSem-Zombie.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp6
-rw-r--r--src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm2
-rw-r--r--src/VBox/HostDrivers/Support/win/SUPLib-win.cpp8
-rw-r--r--src/VBox/HostDrivers/Support/win/SUPR0IdcClient-win.c2
-rw-r--r--src/VBox/HostDrivers/Support/win/SUPSvc-win.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/win/VBoxDrv.inf2
-rw-r--r--src/VBox/HostDrivers/Support/win/VBoxDrv.rc2
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/Makefile.kmk2
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdp.c6
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h2
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/darwin/VBoxNetAdp-darwin.cpp5
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/freebsd/Makefile2
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c2
-rw-r--r--[-rwxr-xr-x]src/VBox/HostDrivers/VBoxNetAdp/freebsd/files_vboxnetadp2
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/linux/VBoxNetAdp-linux.c2
-rw-r--r--[-rwxr-xr-x]src/VBox/HostDrivers/VBoxNetAdp/linux/files_vboxnetadp3
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/solaris/VBoxNetAdp-solaris.c61
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk152
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h8
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c40
-rw-r--r--[-rwxr-xr-x]src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c21
-rw-r--r--[-rwxr-xr-x]src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c147
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c47
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client.h199
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client_priv.h156
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_provider.h498
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxbow.conf21
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h501
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c2807
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h46
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c2512
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h43
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp4368
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/cfg/Makefile.kup (renamed from src/VBox/HostDrivers/VBoxUSB/win/Monitor/Makefile.kup)0
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp2771
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetAdp.inf (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetAdp.inf)22
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.rc)5
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt.inf (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt.inf)75
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltCmn-win.h544
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.cpp1552
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.h42
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM.inf (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt_m.inf)31
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.cpp1580
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.h29
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.cpp (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.c)1954
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.h (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h)477
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.cpp585
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.def22
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.h73
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rc (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rc)30
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rgs (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rgs)2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjRc.h (renamed from src/VBox/Additions/linux/installer/test_drm.c)31
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjT.idl (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyn.idl)29
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp769
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.def6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h133
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyRc.h6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/tools/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetAdpInstall.cpp (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpInstall.cpp)18
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetAdpUninstall.cpp (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpUninstall.cpp)15
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetFltInstall.cpp (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/NetFltInstall.cpp)33
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetFltUninstall.cpp (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/NetFltUninstall.cpp)18
-rw-r--r--src/VBox/HostDrivers/VBoxPci/Makefile.kmk78
-rw-r--r--src/VBox/HostDrivers/VBoxPci/VBoxPci.c791
-rw-r--r--src/VBox/HostDrivers/VBoxPci/VBoxPciInternal.h189
-rw-r--r--src/VBox/HostDrivers/VBoxPci/linux/Makefile235
-rw-r--r--src/VBox/HostDrivers/VBoxPci/linux/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c1012
-rw-r--r--src/VBox/HostDrivers/VBoxPci/linux/dkms.conf7
-rw-r--r--src/VBox/HostDrivers/VBoxPci/linux/files_vboxpci81
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/Makefile.kmk6
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/USBFilter.cpp2
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/USBLib.cpp2
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/VBoxUSBFilterMgr.cpp128
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/VBoxUSBFilterMgr.h20
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/Info.plist4
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/Makefile.kmk2
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/USBLib-darwin.cpp2
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSB.cpp2
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSBInterface.h2
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/testcase/tstOpenUSBDev.cpp4
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/solaris/Makefile.kmk2
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/solaris/USBLib-solaris.cpp8
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c83
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSBMon-solaris.c174
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/testcase/tstUSBFilter.cpp2
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Device/vboxdev.cpp3103
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Device/vboxdev.h140
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpnp.cpp2752
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpnp.h199
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpwr.cpp1645
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpwr.h167
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Device/vboxrwr.cpp309
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Device/vboxrwr.h58
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Device/vboxusb.cpp582
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Device/vboxusb.h373
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilt-win32.cpp858
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilter.c1063
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilter.h236
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilter.rc50
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Filter/VBoxUSBFlt.inf70
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Install/USBInstall.cpp53
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Install/USBUninstall.cpp43
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Makefile.kmk72
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMon.cpp1007
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMon.h241
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMonFlt.cpp1065
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/USBLib-win.cpp2940
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/cmn/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp212
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.h118
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbIdc.h72
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.cpp406
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.h66
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/dev/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUSB.inf (renamed from src/VBox/HostDrivers/VBoxUSB/win/Device/VBoxUSB.inf)2
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbCmn.h80
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.cpp335
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.h197
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.rc (renamed from src/VBox/HostDrivers/VBoxUSB/win/Device/vboxusb.rc)4
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.cpp277
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.h (renamed from src/VBox/Additions/linux/installer/test.c)28
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.cpp438
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.h29
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.cpp1576
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.h73
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/lib/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/lib/VBoxUsbLib-win.cpp1545
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/mon/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUSBMon.inf (renamed from src/VBox/HostDrivers/VBoxUSB/win/Monitor/VBoxUSBMon.inf)6
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp1387
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.h53
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbHook.cpp186
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbHook.h74
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.cpp1262
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.h64
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.rc (renamed from src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMon.rc)4
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/testcase/USBTest.cpp85
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/usbdesc.h318
-rw-r--r--src/VBox/HostDrivers/darwin/Makefile.kmk2
-rw-r--r--[-rwxr-xr-x]src/VBox/HostDrivers/darwin/loadall.sh0
-rw-r--r--src/VBox/HostDrivers/linux/Makefile23
-rw-r--r--src/VBox/HostDrivers/linux/dkms.conf4
-rw-r--r--[-rwxr-xr-x]src/VBox/HostDrivers/linux/do_Module.symvers0
-rwxr-xr-xsrc/VBox/HostDrivers/linux/export_modules19
-rw-r--r--src/VBox/HostDrivers/win/Makefile.kmk29
-rw-r--r--src/VBox/HostDrivers/win/cfg/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp812
-rw-r--r--src/VBox/HostServices/GuestControl/Makefile.kmk6
-rw-r--r--src/VBox/HostServices/GuestControl/gctrl.cpp2
-rw-r--r--src/VBox/HostServices/GuestControl/service.cpp189
-rw-r--r--src/VBox/HostServices/GuestControl/testcase/Makefile.kmk2
-rw-r--r--src/VBox/HostServices/GuestControl/testcase/tstGuestControlSvc.cpp1230
-rw-r--r--src/VBox/HostServices/GuestProperties/Makefile.kmk2
-rw-r--r--src/VBox/HostServices/GuestProperties/service.cpp4
-rw-r--r--src/VBox/HostServices/GuestProperties/testcase/Makefile.kmk2
-rw-r--r--src/VBox/HostServices/GuestProperties/testcase/tstGuestPropSvc.cpp2
-rw-r--r--src/VBox/HostServices/Makefile.kmk2
-rw-r--r--src/VBox/HostServices/SharedClipboard/Makefile.kmk5
-rw-r--r--src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp2
-rw-r--r--src/VBox/HostServices/SharedClipboard/VBoxClipboard.h9
-rw-r--r--src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp2
-rw-r--r--src/VBox/HostServices/SharedClipboard/darwin-pasteboard.h2
-rw-r--r--src/VBox/HostServices/SharedClipboard/darwin.cpp4
-rw-r--r--src/VBox/HostServices/SharedClipboard/service.cpp54
-rw-r--r--src/VBox/HostServices/SharedClipboard/testcase/Makefile.kmk33
-rw-r--r--src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceHost.cpp164
-rw-r--r--src/VBox/HostServices/SharedClipboard/x11-clipboard.cpp9
-rw-r--r--src/VBox/HostServices/SharedFolders/Makefile.kmk2
-rw-r--r--src/VBox/HostServices/SharedFolders/testcase/Makefile.kmk2
-rw-r--r--src/VBox/HostServices/SharedOpenGL/Makefile.kmk2
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp270
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/get_components.py3
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server.h1
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c3
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c32
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_framebuffer.c2
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_getshaders.c2
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_glsl.c2
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c52
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c274
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_texture.c2
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c25
-rw-r--r--src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m8
-rw-r--r--src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c24
-rw-r--r--src/VBox/HostServices/SharedOpenGL/unpacker/unpack_framebuffer.c2
-rw-r--r--src/VBox/HostServices/SharedOpenGL/unpacker/unpack_shaders.c2
-rwxr-xr-x[-rw-r--r--]src/VBox/HostServices/SharedOpenGL/unpacker/unpack_visibleregion.c2
-rw-r--r--src/VBox/HostServices/auth/Makefile.kmk2
-rw-r--r--src/VBox/HostServices/testcase/Makefile.kmk2
-rw-r--r--src/VBox/HostServices/testcase/tstHGCMSvc.cpp2
-rw-r--r--src/VBox/ImageMounter/VBoxFUSE/Makefile.kmk2
-rw-r--r--src/VBox/ImageMounter/VBoxFUSE/VBoxFUSE.cpp2
-rw-r--r--src/VBox/Installer/Makefile.kmk2
-rw-r--r--src/VBox/Installer/common/Makefile.kmk4
-rw-r--r--src/VBox/Installer/common/virtualbox.xml28
-rw-r--r--src/VBox/Installer/darwin/Makefile.kmk6
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/darwin/VirtualBox/postflight0
-rw-r--r--src/VBox/Installer/freebsd/Makefile.kmk2
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/freebsd/postdeinstall.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/freebsd/postinstall.sh0
-rw-r--r--src/VBox/Installer/linux/Makefile.include.footer92
-rw-r--r--src/VBox/Installer/linux/Makefile.include.header (renamed from src/VBox/Additions/linux/installer/Makefile.include.footer)160
-rw-r--r--src/VBox/Installer/linux/Makefile.kmk49
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/linux/VBox.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/linux/VBoxCreateUSBNode.sh22
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/linux/VBoxSysInfo.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/linux/deffiles1
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/linux/install.sh41
-rw-r--r--src/VBox/Installer/linux/installer-utils.sh114
-rw-r--r--src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec48
-rwxr-xr-xsrc/VBox/Installer/linux/rpm/rules8
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/linux/run-inst.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/linux/runasroot.sh2
-rw-r--r--src/VBox/Installer/linux/sh-utils.sh2
-rw-r--r--src/VBox/Installer/linux/testcase/Makefile.kmk40
-rw-r--r--src/VBox/Installer/linux/testcase/tstInstaller.sh66
-rw-r--r--src/VBox/Installer/linux/testcase/tstInstallerLinux.sh88
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/linux/uninstall.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/linux/vboxballoonctrl-service.sh.in0
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/linux/vboxdrv.sh.in33
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/linux/vboxweb-service.sh.in0
-rw-r--r--src/VBox/Installer/solaris/Makefile.kmk11
-rw-r--r--src/VBox/Installer/solaris/VBoxISAExec.c2
-rw-r--r--src/VBox/Installer/solaris/VBoxZoneAccess.c2
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/solaris/checkinstall.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/solaris/makepackage.sh4
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/solaris/pkginstall.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/solaris/postinstall.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/solaris/preremove.sh0
-rwxr-xr-xsrc/VBox/Installer/solaris/smf-vboxballoonctrl.sh2
-rwxr-xr-xsrc/VBox/Installer/solaris/smf-vboxwebsrv.sh2
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/solaris/vbi/makepackage.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/solaris/vbi/preremove.sh0
-rw-r--r--[-rwxr-xr-x]src/VBox/Installer/solaris/vboxconfig.sh271
-rw-r--r--src/VBox/Installer/solaris/virtualbox.applications.in2
-rw-r--r--src/VBox/Installer/solaris/virtualbox.keys39
-rw-r--r--src/VBox/Installer/solaris/virtualbox.mime12
-rw-r--r--src/VBox/Installer/win/InstallHelper/Makefile.kmk10
-rw-r--r--src/VBox/Installer/win/InstallHelper/VBoxCommon.cpp3
-rw-r--r--src/VBox/Installer/win/InstallHelper/VBoxCommon.h2
-rw-r--r--src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.cpp857
-rw-r--r--src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.def2
-rw-r--r--src/VBox/Installer/win/Languages/de_DE.wxl6
-rw-r--r--src/VBox/Installer/win/Languages/en_US.wxl4
-rw-r--r--src/VBox/Installer/win/Languages/fr_FR.wxl2
-rw-r--r--src/VBox/Installer/win/Makefile.kmk118
-rw-r--r--src/VBox/Installer/win/Resources/Makefile.kmk22
-rw-r--r--src/VBox/Installer/win/Resources/VBoxRes.rc2
-rw-r--r--src/VBox/Installer/win/Resources/dummy.cpp2
-rw-r--r--src/VBox/Installer/win/Resources/resource.h6
-rw-r--r--src/VBox/Installer/win/Stub/Makefile.kmk17
-rw-r--r--src/VBox/Installer/win/Stub/VBoxStub.cpp13
-rw-r--r--src/VBox/Installer/win/Stub/VBoxStub.h2
-rw-r--r--src/VBox/Installer/win/Stub/VBoxStub.manifest22
-rw-r--r--src/VBox/Installer/win/Stub/VBoxStub.rc5
-rw-r--r--src/VBox/Installer/win/Stub/resource.h7
-rw-r--r--src/VBox/Installer/win/StubBld/Makefile.kmk2
-rw-r--r--src/VBox/Installer/win/StubBld/VBoxStubBld.cpp2
-rw-r--r--src/VBox/Installer/win/StubBld/VBoxStubBld.h2
-rw-r--r--src/VBox/Installer/win/UserInterface.wxi835
-rw-r--r--src/VBox/Installer/win/VBoxKey.wxi6
-rw-r--r--src/VBox/Installer/win/VirtualBox.wxs620
-rw-r--r--src/VBox/Installer/win/VirtualBox_TypeLib.xsl3
-rw-r--r--src/VBox/Installer/win/dep.sed8
-rw-r--r--src/VBox/Main/Makefile.kmk44
-rw-r--r--src/VBox/Main/cbinding/Makefile.kmk2
-rw-r--r--src/VBox/Main/cbinding/VBoxXPCOMC.cpp2
-rw-r--r--src/VBox/Main/cbinding/VBoxXPCOMCGlue.c2
-rw-r--r--src/VBox/Main/cbinding/VBoxXPCOMCGlue.h2
-rw-r--r--src/VBox/Main/cbinding/makefile.tstXPCOMCGlue2
-rw-r--r--src/VBox/Main/cbinding/tstXPCOMCCall.c2
-rw-r--r--src/VBox/Main/cbinding/tstXPCOMCGlue.c2
-rw-r--r--src/VBox/Main/cbinding/xpcidl.xsl2
-rw-r--r--src/VBox/Main/glue/ErrorInfo.cpp2
-rw-r--r--src/VBox/Main/glue/EventQueue.cpp2
-rw-r--r--src/VBox/Main/glue/VirtualBoxErrorInfo.cpp2
-rw-r--r--src/VBox/Main/glue/com.cpp2
-rw-r--r--src/VBox/Main/glue/errorprint.cpp2
-rw-r--r--src/VBox/Main/glue/glue-java.xsl223
-rw-r--r--src/VBox/Main/glue/initterm.cpp94
-rw-r--r--src/VBox/Main/glue/string.cpp82
-rw-r--r--src/VBox/Main/glue/tests/TestVBox.java4
-rw-r--r--src/VBox/Main/idl/VirtualBox.xidl1554
-rw-r--r--src/VBox/Main/idl/comimpl.xsl8
-rw-r--r--src/VBox/Main/idl/midl.xsl8
-rw-r--r--src/VBox/Main/idl/xpidl.xsl2
-rw-r--r--src/VBox/Main/include/AdditionsFacilityImpl.h94
-rw-r--r--src/VBox/Main/include/ApplianceImpl.h20
-rw-r--r--src/VBox/Main/include/ApplianceImplPrivate.h1
-rw-r--r--src/VBox/Main/include/AudioAdapterImpl.h6
-rw-r--r--src/VBox/Main/include/BIOSSettingsImpl.h6
-rw-r--r--src/VBox/Main/include/BandwidthControlImpl.h4
-rw-r--r--src/VBox/Main/include/BandwidthGroupImpl.h4
-rw-r--r--src/VBox/Main/include/BusAssignmentManager.h21
-rw-r--r--src/VBox/Main/include/ConsoleImpl.h130
-rw-r--r--src/VBox/Main/include/ConsoleVRDPServer.h49
-rw-r--r--src/VBox/Main/include/DHCPServerImpl.h6
-rw-r--r--src/VBox/Main/include/DHCPServerRunner.h2
-rw-r--r--src/VBox/Main/include/DisplayImpl.h6
-rw-r--r--src/VBox/Main/include/EventImpl.h12
-rw-r--r--src/VBox/Main/include/ExtPackManagerImpl.h15
-rw-r--r--src/VBox/Main/include/ExtPackUtil.h30
-rw-r--r--src/VBox/Main/include/FramebufferImpl.h6
-rw-r--r--src/VBox/Main/include/Global.h2
-rw-r--r--src/VBox/Main/include/GuestImpl.h145
-rw-r--r--src/VBox/Main/include/GuestOSTypeImpl.h4
-rw-r--r--src/VBox/Main/include/HostHardwareLinux.h16
-rw-r--r--src/VBox/Main/include/HostImpl.h55
-rw-r--r--src/VBox/Main/include/HostNetworkInterfaceImpl.h6
-rw-r--r--src/VBox/Main/include/HostUSBDeviceImpl.h6
-rw-r--r--src/VBox/Main/include/KeyboardImpl.h6
-rw-r--r--src/VBox/Main/include/Logging.h51
-rw-r--r--src/VBox/Main/include/MachineDebuggerImpl.h6
-rw-r--r--src/VBox/Main/include/MachineImpl.h80
-rw-r--r--src/VBox/Main/include/MachineImplCloneVM.h51
-rw-r--r--src/VBox/Main/include/MediumAttachmentImpl.h23
-rw-r--r--src/VBox/Main/include/MediumFormatImpl.h14
-rw-r--r--src/VBox/Main/include/MediumImpl.h12
-rw-r--r--src/VBox/Main/include/MediumLock.h2
-rw-r--r--src/VBox/Main/include/MouseImpl.h23
-rw-r--r--src/VBox/Main/include/NATEngineImpl.h6
-rw-r--r--src/VBox/Main/include/NetworkAdapterImpl.h114
-rw-r--r--src/VBox/Main/include/ParallelPortImpl.h6
-rw-r--r--src/VBox/Main/include/PciDeviceAttachmentImpl.h21
-rw-r--r--src/VBox/Main/include/PciRawDevImpl.h54
-rw-r--r--src/VBox/Main/include/Performance.h245
-rw-r--r--src/VBox/Main/include/PerformanceImpl.h25
-rw-r--r--src/VBox/Main/include/ProgressCombinedImpl.h6
-rw-r--r--src/VBox/Main/include/ProgressImpl.h7
-rw-r--r--src/VBox/Main/include/ProgressProxyImpl.h6
-rw-r--r--src/VBox/Main/include/RemoteUSBDeviceImpl.h6
-rw-r--r--src/VBox/Main/include/SerialPortImpl.h6
-rw-r--r--src/VBox/Main/include/SessionImpl.h8
-rw-r--r--src/VBox/Main/include/SharedFolderImpl.h4
-rw-r--r--src/VBox/Main/include/SnapshotImpl.h13
-rw-r--r--src/VBox/Main/include/StorageControllerImpl.h6
-rw-r--r--src/VBox/Main/include/SystemPropertiesImpl.h9
-rw-r--r--src/VBox/Main/include/USBControllerImpl.h6
-rw-r--r--src/VBox/Main/include/USBDeviceFilterImpl.h10
-rw-r--r--src/VBox/Main/include/USBDeviceImpl.h6
-rw-r--r--src/VBox/Main/include/USBGetDevices.h35
-rw-r--r--src/VBox/Main/include/USBProxyService.h53
-rw-r--r--src/VBox/Main/include/VFSExplorerImpl.h10
-rw-r--r--src/VBox/Main/include/VRDEServerImpl.h6
-rw-r--r--src/VBox/Main/include/VirtualBoxBase.h34
-rw-r--r--src/VBox/Main/include/VirtualBoxClientImpl.h6
-rw-r--r--src/VBox/Main/include/VirtualBoxImpl.h18
-rw-r--r--src/VBox/Main/include/ovfreader.h84
-rw-r--r--src/VBox/Main/src-all/DisplayPNGUtil.cpp2
-rw-r--r--src/VBox/Main/src-all/DisplayUtils.cpp2
-rw-r--r--src/VBox/Main/src-all/EventImpl.cpp41
-rw-r--r--src/VBox/Main/src-all/ExtPackManagerImpl.cpp74
-rw-r--r--src/VBox/Main/src-all/ExtPackUtil.cpp84
-rw-r--r--src/VBox/Main/src-all/Global.cpp4
-rw-r--r--src/VBox/Main/src-all/PciDeviceAttachmentImpl.cpp43
-rw-r--r--src/VBox/Main/src-all/ProgressImpl.cpp91
-rw-r--r--src/VBox/Main/src-all/SharedFolderImpl.cpp3
-rw-r--r--src/VBox/Main/src-all/VirtualBoxBase.cpp5
-rw-r--r--src/VBox/Main/src-client/AdditionsFacilityImpl.cpp213
-rw-r--r--src/VBox/Main/src-client/AudioSnifferInterface.cpp2
-rw-r--r--src/VBox/Main/src-client/BusAssignmentManager.cpp58
-rw-r--r--src/VBox/Main/src-client/ConsoleImpl.cpp1631
-rw-r--r--src/VBox/Main/src-client/ConsoleImpl2.cpp676
-rw-r--r--src/VBox/Main/src-client/ConsoleImplTeleporter.cpp77
-rw-r--r--src/VBox/Main/src-client/ConsoleVRDPServer.cpp547
-rw-r--r--src/VBox/Main/src-client/DisplayImpl.cpp13
-rw-r--r--src/VBox/Main/src-client/GuestCtrlImpl.cpp2345
-rw-r--r--src/VBox/Main/src-client/GuestImpl.cpp201
-rw-r--r--src/VBox/Main/src-client/HGCMObjects.cpp2
-rw-r--r--src/VBox/Main/src-client/HGCMThread.cpp2
-rw-r--r--src/VBox/Main/src-client/KeyboardImpl.cpp17
-rw-r--r--src/VBox/Main/src-client/MachineDebuggerImpl.cpp5
-rw-r--r--src/VBox/Main/src-client/MouseImpl.cpp80
-rw-r--r--src/VBox/Main/src-client/PciRawDevImpl.cpp229
-rw-r--r--src/VBox/Main/src-client/RemoteUSBDeviceImpl.cpp5
-rw-r--r--src/VBox/Main/src-client/SessionImpl.cpp29
-rw-r--r--src/VBox/Main/src-client/USBDeviceImpl.cpp5
-rw-r--r--src/VBox/Main/src-client/VBoxDriversRegister.cpp19
-rw-r--r--src/VBox/Main/src-client/VMMDevInterface.cpp18
-rw-r--r--src/VBox/Main/src-client/VirtualBoxClientImpl.cpp7
-rw-r--r--src/VBox/Main/src-client/win/VBoxC.rc2
-rw-r--r--src/VBox/Main/src-client/xpcom/module.cpp28
-rw-r--r--src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.cpp8
-rw-r--r--src/VBox/Main/src-server/ApplianceImpl.cpp6
-rw-r--r--src/VBox/Main/src-server/ApplianceImplExport.cpp4
-rw-r--r--src/VBox/Main/src-server/ApplianceImplIO.cpp2
-rw-r--r--src/VBox/Main/src-server/ApplianceImplImport.cpp39
-rw-r--r--src/VBox/Main/src-server/AudioAdapterImpl.cpp3
-rw-r--r--src/VBox/Main/src-server/BIOSSettingsImpl.cpp3
-rw-r--r--src/VBox/Main/src-server/BandwidthControlImpl.cpp3
-rw-r--r--src/VBox/Main/src-server/BandwidthGroupImpl.cpp3
-rw-r--r--src/VBox/Main/src-server/DHCPServerImpl.cpp6
-rw-r--r--src/VBox/Main/src-server/DHCPServerRunner.cpp2
-rw-r--r--src/VBox/Main/src-server/GuestOSTypeImpl.cpp4
-rw-r--r--src/VBox/Main/src-server/HostImpl.cpp49
-rw-r--r--src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp14
-rw-r--r--src/VBox/Main/src-server/HostPower.cpp8
-rw-r--r--src/VBox/Main/src-server/HostUSBDeviceImpl.cpp5
-rw-r--r--src/VBox/Main/src-server/Logging.cpp133
-rw-r--r--src/VBox/Main/src-server/MachineImpl.cpp1109
-rw-r--r--src/VBox/Main/src-server/MachineImplCloneVM.cpp1090
-rw-r--r--src/VBox/Main/src-server/Matching.cpp3
-rw-r--r--src/VBox/Main/src-server/MediumAttachmentImpl.cpp115
-rw-r--r--src/VBox/Main/src-server/MediumFormatImpl.cpp21
-rw-r--r--src/VBox/Main/src-server/MediumImpl.cpp152
-rw-r--r--src/VBox/Main/src-server/NATEngineImpl.cpp5
-rw-r--r--src/VBox/Main/src-server/NetworkAdapterImpl.cpp824
-rw-r--r--src/VBox/Main/src-server/ParallelPortImpl.cpp5
-rw-r--r--src/VBox/Main/src-server/Performance.cpp308
-rw-r--r--src/VBox/Main/src-server/PerformanceImpl.cpp125
-rw-r--r--src/VBox/Main/src-server/ProgressProxyImpl.cpp4
-rw-r--r--src/VBox/Main/src-server/SerialPortImpl.cpp3
-rw-r--r--src/VBox/Main/src-server/SnapshotImpl.cpp343
-rw-r--r--src/VBox/Main/src-server/StorageControllerImpl.cpp24
-rw-r--r--src/VBox/Main/src-server/SystemPropertiesImpl.cpp78
-rw-r--r--src/VBox/Main/src-server/USBControllerImpl.cpp5
-rw-r--r--src/VBox/Main/src-server/USBDeviceFilterImpl.cpp5
-rw-r--r--src/VBox/Main/src-server/USBProxyService.cpp8
-rw-r--r--src/VBox/Main/src-server/VFSExplorerImpl.cpp4
-rw-r--r--src/VBox/Main/src-server/VRDEServerImpl.cpp7
-rw-r--r--src/VBox/Main/src-server/VirtualBoxImpl.cpp296
-rw-r--r--src/VBox/Main/src-server/darwin/NetIf-darwin.cpp2
-rw-r--r--src/VBox/Main/src-server/darwin/OpenGLTestDarwin.cpp2
-rw-r--r--src/VBox/Main/src-server/darwin/PerformanceDarwin.cpp2
-rw-r--r--src/VBox/Main/src-server/darwin/USBProxyServiceDarwin.cpp8
-rw-r--r--src/VBox/Main/src-server/darwin/iokit.cpp2
-rw-r--r--src/VBox/Main/src-server/darwin/iokit.h2
-rw-r--r--src/VBox/Main/src-server/freebsd/HostHardwareFreeBSD.cpp20
-rw-r--r--src/VBox/Main/src-server/freebsd/NetIf-freebsd.cpp4
-rw-r--r--src/VBox/Main/src-server/freebsd/PerformanceFreeBSD.cpp2
-rw-r--r--src/VBox/Main/src-server/freebsd/USBProxyServiceFreeBSD.cpp8
-rw-r--r--src/VBox/Main/src-server/generic/NetIf-generic.cpp4
-rw-r--r--src/VBox/Main/src-server/generic/OpenGLTest.cpp2
-rw-r--r--src/VBox/Main/src-server/generic/OpenGLTestApp.cpp2
-rw-r--r--src/VBox/Main/src-server/linux/HostHardwareLinux.cpp3
-rw-r--r--src/VBox/Main/src-server/linux/NetIf-linux.cpp2
-rw-r--r--src/VBox/Main/src-server/linux/PerformanceLinux.cpp12
-rw-r--r--src/VBox/Main/src-server/linux/USBGetDevices.cpp181
-rw-r--r--src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp200
-rw-r--r--src/VBox/Main/src-server/os2/NetIf-os2.cpp2
-rw-r--r--src/VBox/Main/src-server/os2/PerformanceOs2.cpp2
-rw-r--r--src/VBox/Main/src-server/os2/USBProxyServiceOs2.cpp2
-rw-r--r--src/VBox/Main/src-server/solaris/DynLoadLibSolaris.cpp2
-rw-r--r--src/VBox/Main/src-server/solaris/DynLoadLibSolaris.h2
-rw-r--r--src/VBox/Main/src-server/solaris/NetIf-solaris.cpp18
-rw-r--r--src/VBox/Main/src-server/solaris/PerformanceSolaris.cpp3
-rw-r--r--src/VBox/Main/src-server/solaris/USBProxyServiceSolaris.cpp100
-rw-r--r--src/VBox/Main/src-server/win/NetIf-win.cpp91
-rw-r--r--src/VBox/Main/src-server/win/PerformanceWin.cpp2
-rw-r--r--src/VBox/Main/src-server/win/USBProxyServiceWindows.cpp119
-rw-r--r--src/VBox/Main/src-server/win/VBoxSVC.rc2
-rw-r--r--src/VBox/Main/src-server/win/svcmain.cpp274
-rw-r--r--src/VBox/Main/src-server/xpcom/server.cpp106
-rw-r--r--src/VBox/Main/src-server/xpcom/server_module.cpp1
-rw-r--r--src/VBox/Main/testcase/Makefile.kmk30
-rw-r--r--src/VBox/Main/testcase/tstAPI.cpp38
-rw-r--r--src/VBox/Main/testcase/tstCollector.cpp2
-rw-r--r--src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp302
-rw-r--r--src/VBox/Main/testcase/tstHostHardwareLinux.cpp155
-rw-r--r--src/VBox/Main/testcase/tstOVF.cpp5
-rw-r--r--src/VBox/Main/testcase/tstUSBLinux.h2
-rw-r--r--src/VBox/Main/testcase/tstUSBProxyLinux.cpp44
-rw-r--r--src/VBox/Main/testcase/tstVBoxAPILinux.cpp4
-rw-r--r--src/VBox/Main/testcase/tstVBoxAPIWin.cpp2
-rw-r--r--src/VBox/Main/webservice/Makefile.kmk92
-rw-r--r--src/VBox/Main/webservice/glue-jaxws.xsl1353
-rw-r--r--[-rwxr-xr-x]src/VBox/Main/webservice/samples/perl/clienttest.pl0
-rw-r--r--src/VBox/Main/webservice/vboxweb.cpp71
-rw-r--r--src/VBox/Main/webservice/vboxweb.h3
-rw-r--r--src/VBox/Main/webservice/websrv-cpp.xsl24
-rw-r--r--src/VBox/Main/webservice/websrv-python.xsl88
-rw-r--r--src/VBox/Main/webservice/websrv-wsdl.xsl8
-rw-r--r--src/VBox/Main/win/samples/VBoxCallbacks.java61
-rw-r--r--src/VBox/Main/win/samples/VBoxTest.java104
-rw-r--r--src/VBox/Main/win/samples/run.bat20
-rw-r--r--src/VBox/Main/xml/Settings.cpp375
-rw-r--r--src/VBox/Main/xml/VirtualBox-settings-common.xsd16
-rw-r--r--src/VBox/Main/xml/ovfreader.cpp42
-rw-r--r--src/VBox/Makefile.kmk2
-rw-r--r--src/VBox/NetworkServices/DHCP/Makefile.kmk2
-rw-r--r--src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp2
-rw-r--r--src/VBox/NetworkServices/DHCP/VBoxNetDHCPHardened.cpp2
-rw-r--r--src/VBox/NetworkServices/Makefile.kmk2
-rw-r--r--src/VBox/NetworkServices/NAT/Makefile.kmk3
-rw-r--r--src/VBox/NetworkServices/NAT/VBoxNetNAT.cpp51
-rw-r--r--src/VBox/NetworkServices/NAT/VBoxNetNATHardened.cpp2
-rw-r--r--src/VBox/NetworkServices/NetLib/VBoxNetARP.cpp2
-rw-r--r--src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp4
-rw-r--r--src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h2
-rw-r--r--src/VBox/NetworkServices/NetLib/VBoxNetIntIf.cpp2
-rw-r--r--src/VBox/NetworkServices/NetLib/VBoxNetLib.h2
-rw-r--r--src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp2
-rw-r--r--src/VBox/RDP/client/Makefile.kmk2
-rw-r--r--src/VBox/RDP/client/doc/AUTHORS20
-rw-r--r--src/VBox/RDP/client/doc/ChangeLog127
-rw-r--r--src/VBox/RDP/client/doc/HACKING45
-rw-r--r--src/VBox/RDP/client/doc/TODO102
-rw-r--r--src/VBox/RDP/client/doc/ipv6.txt29
-rw-r--r--src/VBox/RDP/client/doc/keymap-names.txt124
-rw-r--r--src/VBox/RDP/client/doc/keymapping.txt275
-rw-r--r--src/VBox/RDP/client/doc/licensing.txt56
-rw-r--r--src/VBox/RDP/client/doc/patches.txt340
-rw-r--r--src/VBox/RDP/client/doc/rdesktop.1291
-rw-r--r--src/VBox/RDP/client/doc/redirection.txt74
-rw-r--r--src/VBox/RDP/client/files_rdesktop-vrdp4
-rw-r--r--src/VBox/RDP/client/keymaps/ar98
-rw-r--r--src/VBox/RDP/client/keymaps/common229
-rwxr-xr-xsrc/VBox/RDP/client/keymaps/convert-map63
-rw-r--r--src/VBox/RDP/client/keymaps/cs87
-rw-r--r--src/VBox/RDP/client/keymaps/da120
-rw-r--r--src/VBox/RDP/client/keymaps/de114
-rw-r--r--src/VBox/RDP/client/keymaps/de-ch169
-rw-r--r--src/VBox/RDP/client/keymaps/en-dv216
-rw-r--r--src/VBox/RDP/client/keymaps/en-gb119
-rw-r--r--src/VBox/RDP/client/keymaps/en-us35
-rw-r--r--src/VBox/RDP/client/keymaps/es105
-rw-r--r--src/VBox/RDP/client/keymaps/et86
-rw-r--r--src/VBox/RDP/client/keymaps/fi122
-rw-r--r--src/VBox/RDP/client/keymaps/fo77
-rw-r--r--src/VBox/RDP/client/keymaps/fr181
-rw-r--r--src/VBox/RDP/client/keymaps/fr-be135
-rw-r--r--src/VBox/RDP/client/keymaps/fr-ca53
-rw-r--r--src/VBox/RDP/client/keymaps/fr-ch169
-rw-r--r--src/VBox/RDP/client/keymaps/he91
-rw-r--r--src/VBox/RDP/client/keymaps/hr125
-rw-r--r--src/VBox/RDP/client/keymaps/hu115
-rw-r--r--src/VBox/RDP/client/keymaps/is140
-rw-r--r--src/VBox/RDP/client/keymaps/it115
-rw-r--r--src/VBox/RDP/client/keymaps/ja119
-rw-r--r--src/VBox/RDP/client/keymaps/ko37
-rw-r--r--src/VBox/RDP/client/keymaps/lt57
-rw-r--r--src/VBox/RDP/client/keymaps/lv128
-rw-r--r--src/VBox/RDP/client/keymaps/mk101
-rw-r--r--src/VBox/RDP/client/keymaps/modifiers18
-rw-r--r--src/VBox/RDP/client/keymaps/nl60
-rw-r--r--src/VBox/RDP/client/keymaps/nl-be142
-rw-r--r--src/VBox/RDP/client/keymaps/no119
-rw-r--r--src/VBox/RDP/client/keymaps/pl122
-rw-r--r--src/VBox/RDP/client/keymaps/pt113
-rw-r--r--src/VBox/RDP/client/keymaps/pt-br69
-rw-r--r--src/VBox/RDP/client/keymaps/ru109
-rw-r--r--src/VBox/RDP/client/keymaps/sl110
-rw-r--r--src/VBox/RDP/client/keymaps/sv80
-rw-r--r--src/VBox/RDP/client/keymaps/th131
-rw-r--r--src/VBox/RDP/client/keymaps/tr138
-rw-r--r--src/VBox/RDP/client/vrdp/rdpusb.c21
-rw-r--r--src/VBox/Resources/darwin/virtualbox-hdd.icnsbin0 -> 227127 bytes
-rw-r--r--src/VBox/Resources/darwin/virtualbox-vdi.icnsbin0 -> 237080 bytes
-rw-r--r--src/VBox/Resources/darwin/virtualbox-vhd.icnsbin0 -> 214372 bytes
-rw-r--r--src/VBox/Resources/darwin/virtualbox-vmdk.icnsbin0 -> 226107 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-128px.pngbin0 -> 17558 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-16px.pngbin0 -> 3541 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-20px.pngbin0 -> 3790 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-24px.pngbin0 -> 4093 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-256px.pngbin0 -> 41789 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-32px.pngbin0 -> 4825 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-40px.pngbin0 -> 5574 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-48px.pngbin0 -> 6554 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-512px.pngbin0 -> 113036 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-64px.pngbin0 -> 8486 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-72px.pngbin0 -> 9593 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-80px.pngbin0 -> 10585 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-hdd-96px.pngbin0 -> 12740 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-128px.pngbin0 -> 18995 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-16px.pngbin0 -> 3532 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-20px.pngbin0 -> 3832 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-24px.pngbin0 -> 4182 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-256px.pngbin0 -> 46956 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-32px.pngbin0 -> 4867 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-40px.pngbin0 -> 5747 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-48px.pngbin0 -> 6929 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-512px.pngbin0 -> 128080 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-64px.pngbin0 -> 9277 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-72px.pngbin0 -> 9912 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-80px.pngbin0 -> 11115 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vdi-96px.pngbin0 -> 13641 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-128px.pngbin0 -> 17336 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-16px.pngbin0 -> 3536 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-20px.pngbin0 -> 3770 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-24px.pngbin0 -> 4088 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-256px.pngbin0 -> 41809 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-32px.pngbin0 -> 4825 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-40px.pngbin0 -> 5526 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-48px.pngbin0 -> 6480 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-512px.pngbin0 -> 112847 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-64px.pngbin0 -> 8509 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-72px.pngbin0 -> 9476 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-80px.pngbin0 -> 10406 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vhd-96px.pngbin0 -> 12597 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-128px.pngbin0 -> 17594 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-16px.pngbin0 -> 3546 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-20px.pngbin0 -> 3770 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-24px.pngbin0 -> 4094 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-256px.pngbin0 -> 42038 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-32px.pngbin0 -> 4808 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-40px.pngbin0 -> 5698 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-48px.pngbin0 -> 6487 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-512px.pngbin0 -> 115635 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-64px.pngbin0 -> 8388 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-72px.pngbin0 -> 9509 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-80px.pngbin0 -> 10593 bytes
-rw-r--r--src/VBox/Resources/other/virtualbox-vmdk-96px.pngbin0 -> 12731 bytes
-rw-r--r--src/VBox/Resources/win/virtualbox-hdd.icobin0 -> 229024 bytes
-rw-r--r--src/VBox/Resources/win/virtualbox-vdi.icobin0 -> 234089 bytes
-rw-r--r--src/VBox/Resources/win/virtualbox-vhd.icobin0 -> 228748 bytes
-rw-r--r--src/VBox/Resources/win/virtualbox-vmdk.icobin0 -> 229177 bytes
-rw-r--r--src/VBox/Runtime/.scm-settings2
-rw-r--r--src/VBox/Runtime/Doxyfile2
-rw-r--r--src/VBox/Runtime/Makefile.kmk214
-rw-r--r--src/VBox/Runtime/VBox/RTAssertShouldPanic-vbox.cpp35
-rw-r--r--src/VBox/Runtime/VBox/VBoxRTDeps.cpp10
-rw-r--r--src/VBox/Runtime/VBox/VBoxRTImp.def2
-rw-r--r--src/VBox/Runtime/VBox/log-vbox.cpp7
-rw-r--r--src/VBox/Runtime/VBox/logbackdoor-redirect.cpp2
-rw-r--r--src/VBox/Runtime/VBox/logbackdoor.cpp2
-rw-r--r--src/VBox/Runtime/common/alloc/alloc.cpp6
-rw-r--r--src/VBox/Runtime/common/alloc/heapoffset.cpp2
-rw-r--r--src/VBox/Runtime/common/alloc/heapsimple.cpp2
-rw-r--r--src/VBox/Runtime/common/alloc/memcache.cpp2
-rw-r--r--src/VBox/Runtime/common/alloc/memtracker.cpp1306
-rw-r--r--src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm2
-rw-r--r--src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm2
-rw-r--r--src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU8.asm2
-rw-r--r--src/VBox/Runtime/common/asm/ASMAtomicReadU64.asm2
-rw-r--r--src/VBox/Runtime/common/asm/ASMAtomicUoReadU64.asm2
-rw-r--r--src/VBox/Runtime/common/asm/ASMAtomicXchgU64.asm2
-rw-r--r--src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32.asm2
-rw-r--r--src/VBox/Runtime/common/asm/ASMNopPause.asm2
-rw-r--r--src/VBox/Runtime/common/asm/asm-fake.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/RTSha1Digest.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/adler32.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/crc32-zlib.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/crc32.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/crc64.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/ipv4.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/ipv6.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/manifest-file.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/manifest.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/manifest2.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/manifest3.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/md5.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/md5str.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/sha1.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/sha1str.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/sha256.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/sha256str.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/sha512.cpp2
-rw-r--r--src/VBox/Runtime/common/checksum/sha512str.cpp2
-rw-r--r--src/VBox/Runtime/common/dbg/dbg.cpp2
-rw-r--r--src/VBox/Runtime/common/dbg/dbgas.cpp2
-rw-r--r--src/VBox/Runtime/common/dbg/dbgmod.cpp2
-rw-r--r--src/VBox/Runtime/common/dbg/dbgmodcontainer.cpp2
-rw-r--r--src/VBox/Runtime/common/dbg/dbgmodnm.cpp4
-rw-r--r--src/VBox/Runtime/common/dvm/Makefile.kup0
-rw-r--r--src/VBox/Runtime/common/dvm/dvm.cpp481
-rw-r--r--src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp517
-rw-r--r--src/VBox/Runtime/common/dvm/dvmgpt.cpp536
-rw-r--r--src/VBox/Runtime/common/dvm/dvmmbr.cpp406
-rw-r--r--src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp2
-rw-r--r--src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp3
-rw-r--r--src/VBox/Runtime/common/err/errinfo.cpp2
-rw-r--r--src/VBox/Runtime/common/err/errmsg.cpp2
-rw-r--r--src/VBox/Runtime/common/err/errmsg.sed10
-rw-r--r--src/VBox/Runtime/common/err/errmsgcom.sed2
-rw-r--r--src/VBox/Runtime/common/err/errmsgxpcom.cpp2
-rw-r--r--src/VBox/Runtime/common/ldr/ldr.cpp21
-rw-r--r--src/VBox/Runtime/common/ldr/ldrELF.cpp2
-rw-r--r--src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h2
-rw-r--r--src/VBox/Runtime/common/ldr/ldrEx.cpp2
-rw-r--r--src/VBox/Runtime/common/ldr/ldrFile.cpp21
-rw-r--r--src/VBox/Runtime/common/ldr/ldrNative.cpp2
-rw-r--r--src/VBox/Runtime/common/ldr/ldrPE.cpp2
-rw-r--r--src/VBox/Runtime/common/ldr/ldrkStuff.cpp2
-rw-r--r--src/VBox/Runtime/common/log/log.cpp728
-rw-r--r--src/VBox/Runtime/common/log/logcom.cpp2
-rw-r--r--src/VBox/Runtime/common/log/logellipsis.cpp2
-rw-r--r--src/VBox/Runtime/common/log/logformat.cpp2
-rw-r--r--src/VBox/Runtime/common/log/logrel.cpp2
-rw-r--r--src/VBox/Runtime/common/log/logrelellipsis.cpp2
-rw-r--r--src/VBox/Runtime/common/log/tracebuf.cpp662
-rw-r--r--src/VBox/Runtime/common/log/tracedefault.cpp57
-rw-r--r--src/VBox/Runtime/common/math/ceill.asm2
-rw-r--r--src/VBox/Runtime/common/math/cosl.asm2
-rw-r--r--src/VBox/Runtime/common/math/fabs.asm2
-rw-r--r--src/VBox/Runtime/common/math/fabsf.asm2
-rw-r--r--src/VBox/Runtime/common/math/fabsl.asm2
-rw-r--r--src/VBox/Runtime/common/math/floor.asm2
-rw-r--r--src/VBox/Runtime/common/math/floorf.asm2
-rw-r--r--src/VBox/Runtime/common/math/floorl.asm2
-rw-r--r--src/VBox/Runtime/common/math/ldexpl.asm2
-rw-r--r--src/VBox/Runtime/common/math/llrint.asm2
-rw-r--r--src/VBox/Runtime/common/math/llrintf.asm2
-rw-r--r--src/VBox/Runtime/common/math/llrintl.asm2
-rw-r--r--src/VBox/Runtime/common/math/logl.asm2
-rw-r--r--src/VBox/Runtime/common/math/lrint.asm2
-rw-r--r--src/VBox/Runtime/common/math/lrintf.asm2
-rw-r--r--src/VBox/Runtime/common/math/lrintl.asm2
-rw-r--r--src/VBox/Runtime/common/math/remainder.asm2
-rw-r--r--src/VBox/Runtime/common/math/remainderf.asm2
-rw-r--r--src/VBox/Runtime/common/math/remainderl.asm2
-rw-r--r--src/VBox/Runtime/common/math/sinl.asm2
-rw-r--r--src/VBox/Runtime/common/math/tanl.asm2
-rw-r--r--src/VBox/Runtime/common/math/trunc.asm2
-rw-r--r--src/VBox/Runtime/common/math/truncf.asm2
-rw-r--r--src/VBox/Runtime/common/math/truncl.asm2
-rw-r--r--src/VBox/Runtime/common/misc/RTAssertMsg1Weak.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/RTAssertMsg2.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/RTAssertMsg2Add.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/RTAssertMsg2AddWeak.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/RTAssertMsg2AddWeakV.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/RTAssertMsg2Weak.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/RTAssertMsg2WeakV.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/RTFileOpenF.cpp4
-rw-r--r--src/VBox/Runtime/common/misc/RTFileOpenV.cpp4
-rw-r--r--src/VBox/Runtime/common/misc/RTMemWipeThoroughly.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/assert.cpp16
-rw-r--r--src/VBox/Runtime/common/misc/buildconfig.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/cidr.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/circbuf.cpp121
-rw-r--r--src/VBox/Runtime/common/misc/getopt.cpp20
-rw-r--r--src/VBox/Runtime/common/misc/getoptargv.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/handle.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/handletable.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/handletable.h2
-rw-r--r--src/VBox/Runtime/common/misc/handletablectx.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/handletablesimple.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/lockvalidator.cpp30
-rw-r--r--src/VBox/Runtime/common/misc/message.cpp37
-rw-r--r--src/VBox/Runtime/common/misc/once.cpp6
-rw-r--r--src/VBox/Runtime/common/misc/req.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/s3.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/sanity-c.c2
-rw-r--r--src/VBox/Runtime/common/misc/sanity-cpp.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/sanity.h2
-rw-r--r--src/VBox/Runtime/common/misc/semspingpong.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/setjmp.asm2
-rw-r--r--src/VBox/Runtime/common/misc/sg.cpp9
-rw-r--r--src/VBox/Runtime/common/misc/term.cpp2
-rw-r--r--src/VBox/Runtime/common/misc/thread.cpp203
-rw-r--r--src/VBox/Runtime/common/path/RTPathAbsDup.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathAbsEx.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathAbsExDup.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathAppend.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathAppendEx.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathChangeToDosSlashes.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathChangeToUnixSlashes.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathCopyComponents.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathCountComponents.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathExt.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathFilename.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathHaveExt.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathHavePath.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathJoin.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathJoinA.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathJoinEx.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathParse.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathRealDup.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathStartsWithRoot.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathStripExt.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathStripFilename.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathStripTrailingSlash.cpp2
-rw-r--r--src/VBox/Runtime/common/path/RTPathTraverseList.cpp2
-rw-r--r--src/VBox/Runtime/common/path/comparepaths.cpp2
-rw-r--r--src/VBox/Runtime/common/path/rtPathRootSpecLen.cpp2
-rw-r--r--src/VBox/Runtime/common/path/rtPathVolumeSpecLen.cpp2
-rw-r--r--src/VBox/Runtime/common/rand/rand.cpp2
-rw-r--r--src/VBox/Runtime/common/rand/randadv.cpp22
-rw-r--r--src/VBox/Runtime/common/rand/randparkmiller.cpp2
-rw-r--r--src/VBox/Runtime/common/sort/RTSortApvIsSorted.cpp2
-rw-r--r--src/VBox/Runtime/common/sort/RTSortIsSorted.cpp2
-rw-r--r--src/VBox/Runtime/common/sort/shellsort.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrCat.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrCatEx.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrCatP.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrCatPEx.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrCmp.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrConvertHexBytes.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrCopy.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrCopyEx.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrCopyP.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrCopyPEx.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrNCmp.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrNLen.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrNLenEx.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrPrintHexBytes.cpp2
-rw-r--r--src/VBox/Runtime/common/string/RTStrStr.cpp2
-rw-r--r--src/VBox/Runtime/common/string/base64.cpp2
-rw-r--r--src/VBox/Runtime/common/string/memchr.asm2
-rw-r--r--src/VBox/Runtime/common/string/memchr.cpp2
-rw-r--r--src/VBox/Runtime/common/string/memchr_alias.c2
-rw-r--r--src/VBox/Runtime/common/string/memcmp.asm2
-rw-r--r--src/VBox/Runtime/common/string/memcmp.cpp2
-rw-r--r--src/VBox/Runtime/common/string/memcmp_alias.c2
-rw-r--r--src/VBox/Runtime/common/string/memcpy.asm2
-rw-r--r--src/VBox/Runtime/common/string/memcpy.cpp2
-rw-r--r--src/VBox/Runtime/common/string/memcpy_alias.c2
-rw-r--r--src/VBox/Runtime/common/string/memmove.asm2
-rw-r--r--src/VBox/Runtime/common/string/memmove_alias.c2
-rw-r--r--src/VBox/Runtime/common/string/mempcpy.asm2
-rw-r--r--src/VBox/Runtime/common/string/memset.asm2
-rw-r--r--src/VBox/Runtime/common/string/memset.cpp2
-rw-r--r--src/VBox/Runtime/common/string/memset_alias.c2
-rw-r--r--src/VBox/Runtime/common/string/ministring.cpp140
-rw-r--r--src/VBox/Runtime/common/string/simplepattern.cpp2
-rw-r--r--src/VBox/Runtime/common/string/straprintf.cpp2
-rw-r--r--src/VBox/Runtime/common/string/strcache.cpp2
-rw-r--r--src/VBox/Runtime/common/string/strchr.asm2
-rw-r--r--src/VBox/Runtime/common/string/strchr_alias.c2
-rw-r--r--src/VBox/Runtime/common/string/strcmp.asm2
-rw-r--r--src/VBox/Runtime/common/string/strcmp_alias.c2
-rw-r--r--src/VBox/Runtime/common/string/strcpy.asm2
-rw-r--r--src/VBox/Runtime/common/string/strcpy.cpp2
-rw-r--r--src/VBox/Runtime/common/string/strcpy_alias.c2
-rw-r--r--src/VBox/Runtime/common/string/strformat.cpp2
-rw-r--r--src/VBox/Runtime/common/string/strformatnum.cpp2
-rw-r--r--src/VBox/Runtime/common/string/strformatrt.cpp140
-rw-r--r--src/VBox/Runtime/common/string/strformattype.cpp5
-rw-r--r--src/VBox/Runtime/common/string/stringalloc.cpp2
-rw-r--r--src/VBox/Runtime/common/string/strlen.asm2
-rw-r--r--src/VBox/Runtime/common/string/strlen.cpp2
-rw-r--r--src/VBox/Runtime/common/string/strlen_alias.c2
-rw-r--r--src/VBox/Runtime/common/string/strncmp.cpp2
-rw-r--r--src/VBox/Runtime/common/string/strpbrk.cpp2
-rw-r--r--src/VBox/Runtime/common/string/strprintf.cpp2
-rw-r--r--src/VBox/Runtime/common/string/strspace.cpp42
-rw-r--r--src/VBox/Runtime/common/string/strstrip.cpp2
-rw-r--r--src/VBox/Runtime/common/string/strtonum.cpp2
-rw-r--r--src/VBox/Runtime/common/string/strversion.cpp2
-rw-r--r--src/VBox/Runtime/common/string/uni.cpp2
-rw-r--r--src/VBox/Runtime/common/string/unidata.cpp2
-rw-r--r--src/VBox/Runtime/common/string/uniread.cpp2
-rw-r--r--src/VBox/Runtime/common/string/utf-16.cpp2
-rw-r--r--src/VBox/Runtime/common/string/utf-8-case.cpp2
-rw-r--r--src/VBox/Runtime/common/string/utf-8.cpp4
-rw-r--r--src/VBox/Runtime/common/table/avl_Base.cpp.h14
-rw-r--r--src/VBox/Runtime/common/table/avl_Destroy.cpp.h4
-rw-r--r--src/VBox/Runtime/common/table/avl_DoWithAll.cpp.h4
-rw-r--r--src/VBox/Runtime/common/table/avl_Enum.cpp.h10
-rw-r--r--src/VBox/Runtime/common/table/avl_Get.cpp.h4
-rw-r--r--src/VBox/Runtime/common/table/avl_GetBestFit.cpp.h4
-rw-r--r--src/VBox/Runtime/common/table/avl_Range.cpp.h4
-rw-r--r--src/VBox/Runtime/common/table/avl_RemoveBestFit.cpp.h4
-rw-r--r--src/VBox/Runtime/common/table/avlgcphys.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlgcptr.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlhcphys.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avllu32.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlogcphys.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlogcptr.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlohcphys.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avloioport.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlou32.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlpv.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlrfoff.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlrgcptr.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlrogcphys.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlrogcptr.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlroioport.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlroogcptr.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlrpv.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlru64.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlruintptr.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlu32.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avluintptr.cpp2
-rw-r--r--src/VBox/Runtime/common/table/avlul.cpp2
-rw-r--r--src/VBox/Runtime/common/table/table.cpp2
-rw-r--r--src/VBox/Runtime/common/time/time.cpp4
-rw-r--r--src/VBox/Runtime/common/time/timeprog.cpp2
-rw-r--r--src/VBox/Runtime/common/time/timesup.cpp4
-rw-r--r--src/VBox/Runtime/common/time/timesupA.asm2
-rw-r--r--src/VBox/Runtime/common/time/timesupA.mac2
-rw-r--r--src/VBox/Runtime/common/time/timesupref.cpp2
-rw-r--r--src/VBox/Runtime/common/time/timesupref.h2
-rw-r--r--src/VBox/Runtime/common/time/timesysalias.cpp2
-rw-r--r--src/VBox/Runtime/common/vfs/vfsbase.cpp4
-rw-r--r--src/VBox/Runtime/common/vfs/vfschain.cpp6
-rw-r--r--src/VBox/Runtime/common/vfs/vfsiosmisc.cpp2
-rw-r--r--src/VBox/Runtime/common/vfs/vfsmemory.cpp4
-rw-r--r--src/VBox/Runtime/common/vfs/vfsmisc.cpp4
-rw-r--r--src/VBox/Runtime/common/vfs/vfsstdfile.cpp8
-rw-r--r--src/VBox/Runtime/common/zip/gzipvfs.cpp2
-rw-r--r--src/VBox/Runtime/common/zip/tar.cpp2
-rw-r--r--src/VBox/Runtime/common/zip/tar.h2
-rw-r--r--src/VBox/Runtime/common/zip/tarcmd.cpp2
-rw-r--r--src/VBox/Runtime/common/zip/tarvfs.cpp2
-rw-r--r--src/VBox/Runtime/common/zip/zip.cpp2
-rw-r--r--src/VBox/Runtime/darwin/RTErrConvertFromDarwin.cpp2
-rw-r--r--src/VBox/Runtime/darwin/RTErrConvertFromDarwinCOM.cpp2
-rw-r--r--src/VBox/Runtime/darwin/RTErrConvertFromDarwinIO.cpp2
-rw-r--r--src/VBox/Runtime/darwin/RTErrConvertFromDarwinKern.cpp2
-rw-r--r--src/VBox/Runtime/gc/initterm-gc.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTAssertShouldPanic-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTDirCreateTemp-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTDirCreateUniqueNumbered-generic.cpp102
-rw-r--r--src/VBox/Runtime/generic/RTDirExists-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTDirQueryInfo-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTDirSetTimes-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTEnvDupEx-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTFileCopy-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTFileExists-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTFileMove-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTFileQuerySize-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTFileReadAll-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTFileReadAllByHandle-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTFileReadAllByHandleEx-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTFileReadAllEx-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTFileReadAllFree-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTLogDefaultInit-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTLogWriteDebugger-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTLogWriteStdErr-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTLogWriteStdErr-stub-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTLogWriteStdOut-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTLogWriteStdOut-stub-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTLogWriteUser-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpCpuId-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpCpuIdFromSetIndex-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpCpuIdToSetIndex-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpGetArraySize-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpGetCount-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpGetCurFrequency-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpGetDescription-generic-stub.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpGetDescription-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpGetMaxCpuId-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpGetMaxFrequency-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpGetOnlineCount-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpGetOnlineSet-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpGetSet-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpIsCpuOnline-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTMpIsCpuPossible-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTProcDaemonize-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTProcIsRunningByName-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTRandAdvCreateSystemFaster-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTRandAdvCreateSystemTruer-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTSemEventMultiWait-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTSemEventWait-2-ex-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTSemEventWait-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTSemEventWaitNoResume-2-ex-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTSemMutexRequest-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTSemMutexRequestDebug-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTSystemQueryDmiString-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTSystemQueryOSInfo-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTThreadGetAffinity-stub-generic.cpp44
-rw-r--r--src/VBox/Runtime/generic/RTThreadGetNativeState-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTThreadSetAffinity-stub-generic.cpp46
-rw-r--r--src/VBox/Runtime/generic/RTThreadSetAffinityToCpu-generic.cpp59
-rw-r--r--src/VBox/Runtime/generic/RTTimeLocalDeltaNano-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTTimeLocalExplode-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTTimerCreate-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTTimerLRCreate-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/RTUuidCreate-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/critsect-generic.cpp56
-rw-r--r--src/VBox/Runtime/generic/env-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/errvars-generic.cpp66
-rw-r--r--src/VBox/Runtime/generic/fs-stubs-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/mempool-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/mppresent-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/pathhost-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/sched-generic.cpp8
-rw-r--r--src/VBox/Runtime/generic/semfastmutex-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/semrw-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/semrw-lockless-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/semxroads-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/spinlock-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/strcache-stubs-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/timer-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/timerlr-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/tls-generic.cpp4
-rw-r--r--src/VBox/Runtime/generic/utf16locale-generic.cpp2
-rw-r--r--src/VBox/Runtime/generic/uuid-generic.cpp2
-rw-r--r--src/VBox/Runtime/include/internal/alignmentchecks.h2
-rw-r--r--src/VBox/Runtime/include/internal/assert.h6
-rw-r--r--src/VBox/Runtime/include/internal/dbgmod.h2
-rw-r--r--src/VBox/Runtime/include/internal/dir.h2
-rw-r--r--src/VBox/Runtime/include/internal/dvm.h286
-rw-r--r--src/VBox/Runtime/include/internal/file.h16
-rw-r--r--src/VBox/Runtime/include/internal/fileaio.h2
-rw-r--r--src/VBox/Runtime/include/internal/fs.h2
-rw-r--r--src/VBox/Runtime/include/internal/initterm.h6
-rw-r--r--src/VBox/Runtime/include/internal/iprt.h2
-rw-r--r--src/VBox/Runtime/include/internal/ldr.h2
-rw-r--r--src/VBox/Runtime/include/internal/ldrELF.h2
-rw-r--r--src/VBox/Runtime/include/internal/ldrELF32.h2
-rw-r--r--src/VBox/Runtime/include/internal/ldrELF64.h2
-rw-r--r--src/VBox/Runtime/include/internal/ldrMZ.h2
-rw-r--r--src/VBox/Runtime/include/internal/ldrMach-O.h2
-rw-r--r--src/VBox/Runtime/include/internal/ldrPE.h2
-rw-r--r--src/VBox/Runtime/include/internal/lockvalidator.h2
-rw-r--r--src/VBox/Runtime/include/internal/magics.h46
-rw-r--r--src/VBox/Runtime/include/internal/mem.h2
-rw-r--r--src/VBox/Runtime/include/internal/memobj.h40
-rw-r--r--src/VBox/Runtime/include/internal/path.h2
-rw-r--r--src/VBox/Runtime/include/internal/pipe.h2
-rw-r--r--src/VBox/Runtime/include/internal/process.h17
-rw-r--r--src/VBox/Runtime/include/internal/rand.h42
-rw-r--r--src/VBox/Runtime/include/internal/sched.h4
-rw-r--r--src/VBox/Runtime/include/internal/socket.h2
-rw-r--r--src/VBox/Runtime/include/internal/strhash.h94
-rw-r--r--src/VBox/Runtime/include/internal/strict.h2
-rw-r--r--src/VBox/Runtime/include/internal/string.h24
-rw-r--r--src/VBox/Runtime/include/internal/thread.h39
-rw-r--r--src/VBox/Runtime/include/internal/time.h10
-rw-r--r--src/VBox/Runtime/nt/NtProcessStartup-stub.cpp2
-rw-r--r--src/VBox/Runtime/nt/RTErrConvertFromNtStatus.cpp2
-rw-r--r--src/VBox/Runtime/os2/RTErrConvertFromOS2.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/alloc-r0drv.cpp97
-rw-r--r--src/VBox/Runtime/r0drv/alloc-r0drv.h6
-rw-r--r--src/VBox/Runtime/r0drv/darwin/RTLogWriteDebugger-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/RTLogWriteStdOut-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/alloc-r0drv-darwin.cpp6
-rw-r--r--src/VBox/Runtime/r0drv/darwin/assert-r0drv-darwin.cpp6
-rw-r--r--src/VBox/Runtime/r0drv/darwin/initterm-r0drv-darwin.cpp6
-rw-r--r--src/VBox/Runtime/r0drv/darwin/mach_kernel-r0drv-darwin.cpp27
-rw-r--r--src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp36
-rw-r--r--src/VBox/Runtime/r0drv/darwin/memuserkernel-r0drv-darwin.cpp3
-rw-r--r--src/VBox/Runtime/r0drv/darwin/mp-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/process-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/semevent-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/semeventmulti-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/semfastmutex-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/semmutex-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/spinlock-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/the-darwin-kernel.h2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp12
-rw-r--r--src/VBox/Runtime/r0drv/darwin/threadpreempt-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/time-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/alloc-r0drv-freebsd.c6
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/assert-r0drv-freebsd.c6
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/initterm-r0drv-freebsd.c6
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c45
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/memuserkernel-r0drv-freebsd.c2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/mp-r0drv-freebsd.c32
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/process-r0drv-freebsd.c2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/semevent-r0drv-freebsd.c2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/semeventmulti-r0drv-freebsd.c2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/semfastmutex-r0drv-freebsd.c2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/semmutex-r0drv-freebsd.c2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/sleepqueue-r0drv-freebsd.h2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/spinlock-r0drv-freebsd.c2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/the-freebsd-kernel.h2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/thread-r0drv-freebsd.c2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/thread2-r0drv-freebsd.c12
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/time-r0drv-freebsd.c2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/timer-r0drv-freebsd.c2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTMpOn-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTMpPokeCpu-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPending-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPendingTrusty-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/mpnotification-r0drv-generic.cpp6
-rw-r--r--src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c2
-rw-r--r--src/VBox/Runtime/r0drv/initterm-r0drv.cpp8
-rw-r--r--src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c24
-rw-r--r--src/VBox/Runtime/r0drv/linux/assert-r0drv-linux.c6
-rw-r--r--src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c8
-rw-r--r--src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c54
-rw-r--r--src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c34
-rw-r--r--src/VBox/Runtime/r0drv/linux/mpnotification-r0drv-linux.c79
-rw-r--r--src/VBox/Runtime/r0drv/linux/process-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/semfastmutex-r0drv-linux.c14
-rw-r--r--src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/spinlock-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/string.h2
-rw-r--r--src/VBox/Runtime/r0drv/linux/the-linux-kernel.h8
-rw-r--r--src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c109
-rw-r--r--src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/waitqueue-r0drv-linux.h2
-rw-r--r--src/VBox/Runtime/r0drv/memobj-r0drv.cpp15
-rw-r--r--src/VBox/Runtime/r0drv/mp-r0drv.h12
-rw-r--r--src/VBox/Runtime/r0drv/mpnotification-r0drv.c10
-rw-r--r--src/VBox/Runtime/r0drv/nt/RTLogWriteDebugger-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/RTTimerGetSystemGranularity-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/alloc-r0drv-nt.cpp6
-rw-r--r--src/VBox/Runtime/r0drv/nt/assert-r0drv-nt.cpp6
-rw-r--r--src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp6
-rw-r--r--src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h2
-rw-r--r--src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp34
-rw-r--r--src/VBox/Runtime/r0drv/nt/memuserkernel-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp10
-rw-r--r--src/VBox/Runtime/r0drv/nt/mpnotification-r0drv-nt.cpp10
-rw-r--r--src/VBox/Runtime/r0drv/nt/process-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/semevent-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/semeventmulti-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/semfastmutex-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/spinlock-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/the-nt-kernel.h2
-rw-r--r--src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp12
-rw-r--r--src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/os2/RTR0AssertPanicSystem-r0drv-os2.asm2
-rw-r--r--src/VBox/Runtime/r0drv/os2/RTR0Os2DHQueryDOSVar.asm2
-rw-r--r--src/VBox/Runtime/r0drv/os2/RTR0Os2DHVMGlobalToProcess.asm2
-rw-r--r--src/VBox/Runtime/r0drv/os2/alloc-r0drv-os2.cpp6
-rw-r--r--src/VBox/Runtime/r0drv/os2/assert-r0drv-os2.cpp6
-rw-r--r--src/VBox/Runtime/r0drv/os2/assertA-r0drv-os2.asm2
-rw-r--r--src/VBox/Runtime/r0drv/os2/initterm-r0drv-os2.cpp6
-rw-r--r--src/VBox/Runtime/r0drv/os2/memobj-r0drv-os2.cpp36
-rw-r--r--src/VBox/Runtime/r0drv/os2/memuserkernel-r0drv-os2.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/os2/process-r0drv-os2.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/os2/semevent-r0drv-os2.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/os2/semeventmulti-r0drv-os2.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/os2/semfastmutex-r0drv-os2.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/os2/spinlock-r0drv-os2.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/os2/the-os2-kernel.h2
-rw-r--r--src/VBox/Runtime/r0drv/os2/thread-r0drv-os2.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/os2/thread2-r0drv-os2.cpp12
-rw-r--r--src/VBox/Runtime/r0drv/os2/time-r0drv-os2.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/os2/timer-r0drv-os2.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/os2/timerA-r0drv-os2.asm2
-rw-r--r--src/VBox/Runtime/r0drv/power-r0drv.h6
-rw-r--r--src/VBox/Runtime/r0drv/powernotification-r0drv.c8
-rw-r--r--src/VBox/Runtime/r0drv/solaris/RTLogWriteDebugger-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/assert-r0drv-solaris.c6
-rw-r--r--src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c6
-rw-r--r--src/VBox/Runtime/r0drv/solaris/memuserkernel-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/modulestub-r0drv-solaris.c55
-rw-r--r--src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c3
-rw-r--r--src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c3
-rw-r--r--src/VBox/Runtime/r0drv/solaris/semeventwait-r0drv-solaris.h2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/semfastmutex-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/semmutex-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/spinlock-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/the-solaris-kernel.h2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/RTMpPokeCpu-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/alloc-r0drv-solaris.c6
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c299
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/i86pc/sys/vbi.h19
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/memobj-r0drv-solaris.c331
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/mp-r0drv-solaris.c12
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/mpnotification-r0drv-solaris.c56
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/process-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/thread-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/thread2-r0drv-solaris.c12
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/time-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/timer-r0drv-solaris.c4
-rw-r--r--src/VBox/Runtime/r3/alloc-ef-cpp.cpp2
-rw-r--r--src/VBox/Runtime/r3/alloc-ef.cpp2
-rw-r--r--src/VBox/Runtime/r3/alloc-ef.h2
-rw-r--r--src/VBox/Runtime/r3/alloc.cpp33
-rw-r--r--src/VBox/Runtime/r3/darwin/RTPathUserDocuments-darwin.cpp55
-rw-r--r--src/VBox/Runtime/r3/darwin/RTSystemQueryDmiString-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r3/darwin/filelock-darwin.cpp20
-rw-r--r--src/VBox/Runtime/r3/darwin/mp-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r3/darwin/pathhost-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r3/darwin/rtProcInitExePath-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r3/darwin/sched-darwin.cpp8
-rw-r--r--src/VBox/Runtime/r3/darwin/time-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r3/dir.cpp2
-rw-r--r--src/VBox/Runtime/r3/dir2.cpp2
-rw-r--r--src/VBox/Runtime/r3/fileio.cpp20
-rw-r--r--src/VBox/Runtime/r3/freebsd/fileaio-freebsd.cpp6
-rw-r--r--src/VBox/Runtime/r3/freebsd/mp-freebsd.cpp2
-rw-r--r--src/VBox/Runtime/r3/freebsd/rtProcInitExePath-freebsd.cpp2
-rw-r--r--src/VBox/Runtime/r3/fs.cpp2
-rw-r--r--src/VBox/Runtime/r3/generic/semspinmutex-r3-generic.cpp2
-rw-r--r--src/VBox/Runtime/r3/init.cpp32
-rw-r--r--src/VBox/Runtime/r3/isofs.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/RTProcIsRunningByName-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/RTSystemQueryDmiString-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/RTThreadGetNativeState-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/fileaio-linux.cpp6
-rw-r--r--src/VBox/Runtime/r3/linux/mp-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/rtProcInitExePath-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/sched-linux.cpp8
-rw-r--r--src/VBox/Runtime/r3/linux/semevent-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp4
-rw-r--r--src/VBox/Runtime/r3/linux/semmutex-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/sysfs.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/thread-affinity-linux.cpp95
-rw-r--r--src/VBox/Runtime/r3/linux/time-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/os2/filelock-os2.cpp2
-rw-r--r--src/VBox/Runtime/r3/os2/mp-os2.cpp2
-rw-r--r--src/VBox/Runtime/r3/os2/pipe-os2.cpp2
-rw-r--r--src/VBox/Runtime/r3/os2/poll-os2.cpp2
-rw-r--r--src/VBox/Runtime/r3/os2/rtProcInitExePath-os2.cpp2
-rw-r--r--src/VBox/Runtime/r3/os2/sched-os2.cpp8
-rw-r--r--src/VBox/Runtime/r3/os2/sems-os2.cpp2
-rw-r--r--src/VBox/Runtime/r3/os2/thread-os2.cpp32
-rw-r--r--src/VBox/Runtime/r3/os2/time-os2.cpp2
-rw-r--r--src/VBox/Runtime/r3/path.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/RTFileQueryFsSizes-posix.cpp4
-rw-r--r--src/VBox/Runtime/r3/posix/RTHandleGetStandard-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/RTMemProtect-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/RTMpGetCount-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/RTPathUserDocuments-posix.cpp52
-rw-r--r--src/VBox/Runtime/r3/posix/RTPathUserHome-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/RTSystemQueryOSInfo-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/RTSystemQueryTotalRam-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/RTTimeNow-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/RTTimeSet-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/dir-posix.cpp31
-rw-r--r--src/VBox/Runtime/r3/posix/env-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/errvars-posix.cpp78
-rw-r--r--src/VBox/Runtime/r3/posix/fileaio-posix.cpp8
-rw-r--r--src/VBox/Runtime/r3/posix/fileio-posix.cpp115
-rw-r--r--src/VBox/Runtime/r3/posix/fileio2-posix.cpp32
-rw-r--r--src/VBox/Runtime/r3/posix/filelock-posix.cpp16
-rw-r--r--src/VBox/Runtime/r3/posix/fs-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/fs2-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/fs3-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/ldrNative-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/path-posix.cpp14
-rw-r--r--src/VBox/Runtime/r3/posix/path2-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/pathhost-posix.cpp3
-rw-r--r--src/VBox/Runtime/r3/posix/pipe-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/poll-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/process-creation-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/process-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/rand-posix.cpp4
-rw-r--r--src/VBox/Runtime/r3/posix/rtmempage-exec-mmap-heap-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/rtmempage-exec-mmap-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/sched-posix.cpp8
-rw-r--r--src/VBox/Runtime/r3/posix/semevent-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/semmutex-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/semrw-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/symlink-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/thread-posix.cpp99
-rw-r--r--src/VBox/Runtime/r3/posix/thread2-posix.cpp116
-rw-r--r--src/VBox/Runtime/r3/posix/time-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/timer-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/tls-posix.cpp2
-rw-r--r--src/VBox/Runtime/r3/posix/utf8-posix.cpp14
-rw-r--r--src/VBox/Runtime/r3/process.cpp2
-rw-r--r--src/VBox/Runtime/r3/socket.cpp292
-rw-r--r--src/VBox/Runtime/r3/solaris/RTSystemQueryDmiString-solaris.cpp2
-rw-r--r--src/VBox/Runtime/r3/solaris/coredumper-solaris.cpp941
-rw-r--r--src/VBox/Runtime/r3/solaris/coredumper-solaris.h144
-rw-r--r--src/VBox/Runtime/r3/solaris/fileaio-solaris.cpp2
-rw-r--r--src/VBox/Runtime/r3/solaris/mp-solaris.cpp2
-rw-r--r--src/VBox/Runtime/r3/solaris/rtProcInitExePath-solaris.cpp2
-rw-r--r--src/VBox/Runtime/r3/solaris/thread-affinity-solaris.cpp94
-rw-r--r--src/VBox/Runtime/r3/stream.cpp2
-rw-r--r--src/VBox/Runtime/r3/tcp.cpp2
-rw-r--r--src/VBox/Runtime/r3/test.cpp2
-rw-r--r--src/VBox/Runtime/r3/testi.cpp2
-rw-r--r--src/VBox/Runtime/r3/udp.cpp726
-rw-r--r--src/VBox/Runtime/r3/win/RTHandleGetStandard-win.cpp4
-rw-r--r--src/VBox/Runtime/r3/win/RTLogWriteDebugger-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/RTSystemQueryDmiString-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/RTSystemQueryOSInfo-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/RTSystemQueryTotalRam-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/RTUuidCreate-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/VBoxRT-openssl-ose.def56
-rw-r--r--src/VBox/Runtime/r3/win/VBoxRT-openssl.def897
-rw-r--r--src/VBox/Runtime/r3/win/VBoxRT-win32.def2
-rw-r--r--src/VBox/Runtime/r3/win/VBoxRT-win64.def2
-rw-r--r--src/VBox/Runtime/r3/win/alloc-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/dir-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/dllmain-win.cpp21
-rw-r--r--src/VBox/Runtime/r3/win/errvars-win.cpp83
-rw-r--r--src/VBox/Runtime/r3/win/fileaio-win.cpp8
-rw-r--r--src/VBox/Runtime/r3/win/fileio-win.cpp190
-rw-r--r--src/VBox/Runtime/r3/win/fs-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/ldrNative-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/localipc-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/mp-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/ntdll-mini-implib.c2
-rw-r--r--src/VBox/Runtime/r3/win/ntdll-mini-implib.def2
-rw-r--r--src/VBox/Runtime/r3/win/path-win.cpp41
-rw-r--r--src/VBox/Runtime/r3/win/pipe-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/poll-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/process-win.cpp3
-rw-r--r--src/VBox/Runtime/r3/win/rtFileNativeSetAttributes-win.cpp4
-rw-r--r--src/VBox/Runtime/r3/win/rtProcInitExePath-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/sched-win.cpp10
-rw-r--r--src/VBox/Runtime/r3/win/semevent-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/semeventmulti-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/semmutex-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/symlink-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/thread-win.cpp73
-rw-r--r--src/VBox/Runtime/r3/win/thread2-win.cpp (renamed from src/VBox/Runtime/r0drv/solaris/mpnotification-r0drv-solaris.c)63
-rw-r--r--src/VBox/Runtime/r3/win/time-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/timer-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/tls-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/utf16locale-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/utf8-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/win/uuid-win.cpp2
-rw-r--r--src/VBox/Runtime/r3/xml.cpp37
-rw-r--r--src/VBox/Runtime/testcase/Makefile.kmk19
-rw-r--r--src/VBox/Runtime/testcase/ioctl.h2
-rw-r--r--src/VBox/Runtime/testcase/ntGetTimerResolution.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstDir-2.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstDir-3.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstDir.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstEnv.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstErrUnique.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstFile.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstFileAppendWin-1.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstFileLock.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstFork.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstHandleTable.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstIoCtl.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstIprtList.cpp612
-rw-r--r--src/VBox/Runtime/testcase/tstIprtMiniString.cpp174
-rw-r--r--src/VBox/Runtime/testcase/tstLdr-2.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstLdr-3.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstLdr-4.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstLdr.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstLdrLoad.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstLdrObj.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstLdrObjR0.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstLog.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstMemAutoPtr.cpp32
-rw-r--r--src/VBox/Runtime/testcase/tstMove.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstMp-1.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstNoCrt-1.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstOnce.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstPrfRT.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstR0ThreadPreemption.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstR0ThreadPreemption.h2
-rw-r--r--src/VBox/Runtime/testcase/tstR0ThreadPreemptionDriver.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTAssertCompile.cpp6
-rw-r--r--src/VBox/Runtime/testcase/tstRTAvl.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTBase64.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTBitOperations.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTCidr.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTCircBuf.cpp14
-rw-r--r--src/VBox/Runtime/testcase/tstRTCoreDump.cpp70
-rw-r--r--src/VBox/Runtime/testcase/tstRTCoreDump.h2
-rw-r--r--src/VBox/Runtime/testcase/tstRTCritSect.cpp7
-rw-r--r--src/VBox/Runtime/testcase/tstRTDarwinMachKernel.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTDigest.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTDirCreateUniqueNumbered.cpp129
-rw-r--r--src/VBox/Runtime/testcase/tstRTDvm.cpp221
-rw-r--r--src/VBox/Runtime/testcase/tstRTFileAio.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTFileAppend-1.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTFsQueries.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTGetOpt.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTGetOptArgv.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTHeapOffset.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTHeapSimple.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTInlineAsm.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTList.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTLockValidator.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTManifest.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTMemCache.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTMemEf.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTMemPool.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTPath.cpp15
-rw-r--r--src/VBox/Runtime/testcase/tstRTPipe.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTPoll.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTPrfIO.cpp4
-rw-r--r--src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTProcIsRunningByName.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTProcWait.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTR0Common.h2
-rw-r--r--src/VBox/Runtime/testcase/tstRTR0CommonDriver.h2
-rw-r--r--src/VBox/Runtime/testcase/tstRTR0CommonReq.h2
-rw-r--r--src/VBox/Runtime/testcase/tstRTR0MemUserKernel.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTR0MemUserKernel.h2
-rw-r--r--src/VBox/Runtime/testcase/tstRTR0MemUserKernelDriver.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTR0SemMutex.h2
-rw-r--r--src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTR0Timer.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTR0Timer.h2
-rw-r--r--src/VBox/Runtime/testcase/tstRTR0TimerDriver.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTS3.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTSemEventMulti.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTSemRW.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTSemXRoads.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTSort.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTStrAlloc.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTStrCache.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTStrCatCopy.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTStrFormat.cpp13
-rw-r--r--src/VBox/Runtime/testcase/tstRTStrVersion.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTSymlink.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTSystemQueryDmi.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTSystemQueryOsInfo.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTTemp.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTThreadExecutionTime.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTThreadPoke.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTTimeSpec.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRTUuid.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstRand.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstSemMutex.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstSemPingPong.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstStrSimplePattern.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstStrToNum.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstTSC.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstTermCallbacks.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstThread-1.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstTime-2.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstTime-3.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstTime-4.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstTime.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstTimer.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstTimerLR.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstUtf8.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstVector.cpp234
-rw-r--r--src/VBox/Runtime/tools/Makefile.kmk2
-rw-r--r--src/VBox/Runtime/tools/RTGzip.cpp2
-rw-r--r--src/VBox/Runtime/tools/RTLdrFlt.cpp4
-rw-r--r--src/VBox/Runtime/tools/RTManifest.cpp2
-rw-r--r--src/VBox/Runtime/tools/RTTar.cpp2
-rw-r--r--src/VBox/Runtime/win/RTErrConvertFromWin32.cpp2
-rw-r--r--src/VBox/Runtime/win/errmsgwin.cpp2
-rw-r--r--src/VBox/Storage/DMG.cpp7
-rw-r--r--src/VBox/Storage/ISCSI.cpp73
-rw-r--r--src/VBox/Storage/Makefile.kmk2
-rw-r--r--src/VBox/Storage/Parallels.cpp17
-rw-r--r--src/VBox/Storage/RAW.cpp10
-rw-r--r--src/VBox/Storage/VCICache.cpp2
-rw-r--r--src/VBox/Storage/VD.cpp64
-rw-r--r--src/VBox/Storage/VDI.cpp12
-rw-r--r--src/VBox/Storage/VDICore.h2
-rw-r--r--src/VBox/Storage/VHD.cpp260
-rw-r--r--src/VBox/Storage/VMDK.cpp108
-rw-r--r--src/VBox/Storage/testcase/Makefile.kmk77
-rw-r--r--src/VBox/Storage/testcase/VDIoBackendMem.cpp53
-rw-r--r--src/VBox/Storage/testcase/VDIoBackendMem.h2
-rw-r--r--src/VBox/Storage/testcase/VDIoRnd.cpp4
-rw-r--r--src/VBox/Storage/testcase/VDMemDisk.cpp69
-rw-r--r--src/VBox/Storage/testcase/VDMemDisk.h12
-rw-r--r--src/VBox/Storage/testcase/tstVD.cpp2
-rw-r--r--src/VBox/Storage/testcase/tstVDCompact.vd77
-rw-r--r--src/VBox/Storage/testcase/tstVDIo.cpp1554
-rw-r--r--src/VBox/Storage/testcase/tstVDIo.vd67
-rw-r--r--src/VBox/Storage/testcase/tstVDShareable.cpp2
-rw-r--r--src/VBox/Storage/testcase/tstVDShareable.vd53
-rw-r--r--src/VBox/Storage/testcase/vbox-img.cpp2
-rw-r--r--src/VBox/VMM/Docs-CodingGuidelines.cpp2
-rw-r--r--src/VBox/VMM/Docs-RawMode.cpp2
-rw-r--r--src/VBox/VMM/Makefile.kmk36
-rw-r--r--src/VBox/VMM/VMMAll/CPUMAllA.asm4
-rw-r--r--src/VBox/VMM/VMMAll/CPUMAllRegs.cpp51
-rw-r--r--src/VBox/VMM/VMMAll/CPUMStack.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/CSAMAll.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/DBGFAll.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/EMAll.cpp17
-rw-r--r--src/VBox/VMM/VMMAll/EMAllA.asm4
-rw-r--r--src/VBox/VMM/VMMAll/FTMAll.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/HWACCMAll.cpp140
-rw-r--r--src/VBox/VMM/VMMAll/IEMAll.cpp6254
-rw-r--r--src/VBox/VMM/VMMAll/IEMAllAImpl.asm1235
-rw-r--r--src/VBox/VMM/VMMAll/IEMAllAImplC.cpp48
-rw-r--r--src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h3045
-rw-r--r--src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h1403
-rw-r--r--src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h11607
-rw-r--r--src/VBox/VMM/VMMAll/IOMAll.cpp336
-rw-r--r--src/VBox/VMM/VMMAll/IOMAllMMIO.cpp241
-rw-r--r--src/VBox/VMM/VMMAll/MMAll.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/MMAllHyper.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/MMAllPagePool.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/PATMAll.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/PDMAll.cpp23
-rw-r--r--src/VBox/VMM/VMMAll/PDMAllCritSect.cpp111
-rw-r--r--src/VBox/VMM/VMMAll/PDMAllQueue.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/PGMAll.cpp134
-rw-r--r--src/VBox/VMM/VMMAll/PGMAllBth.h79
-rw-r--r--src/VBox/VMM/VMMAll/PGMAllGst.h10
-rw-r--r--src/VBox/VMM/VMMAll/PGMAllHandler.cpp90
-rw-r--r--src/VBox/VMM/VMMAll/PGMAllMap.cpp22
-rw-r--r--src/VBox/VMM/VMMAll/PGMAllPhys.cpp390
-rw-r--r--src/VBox/VMM/VMMAll/PGMAllPool.cpp172
-rw-r--r--src/VBox/VMM/VMMAll/PGMAllShw.h11
-rw-r--r--src/VBox/VMM/VMMAll/REMAll.cpp4
-rw-r--r--src/VBox/VMM/VMMAll/SELMAll.cpp4
-rw-r--r--src/VBox/VMM/VMMAll/TMAll.cpp1577
-rw-r--r--src/VBox/VMM/VMMAll/TMAllCpu.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/TMAllReal.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/TMAllVirtual.cpp65
-rw-r--r--src/VBox/VMM/VMMAll/TRPMAll.cpp4
-rw-r--r--src/VBox/VMM/VMMAll/VMAll.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/VMMAll.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/VMMAllA.asm2
-rw-r--r--src/VBox/VMM/VMMR0/CPUMR0.cpp4
-rw-r--r--src/VBox/VMM/VMMR0/CPUMR0A.asm4
-rw-r--r--src/VBox/VMM/VMMR0/CPUMR0UnusedA.asm4
-rw-r--r--src/VBox/VMM/VMMR0/GMMR0.cpp2498
-rw-r--r--src/VBox/VMM/VMMR0/GMMR0Internal.h35
-rw-r--r--src/VBox/VMM/VMMR0/GVMMR0.cpp15
-rw-r--r--src/VBox/VMM/VMMR0/GVMMR0Internal.h2
-rw-r--r--src/VBox/VMM/VMMR0/HWACCMR0.cpp1712
-rw-r--r--src/VBox/VMM/VMMR0/HWACCMR0A.asm4
-rw-r--r--src/VBox/VMM/VMMR0/HWACCMR0Mixed.mac2
-rw-r--r--src/VBox/VMM/VMMR0/HWSVMR0.cpp64
-rw-r--r--src/VBox/VMM/VMMR0/HWSVMR0.h8
-rw-r--r--src/VBox/VMM/VMMR0/HWVMXR0.cpp208
-rw-r--r--src/VBox/VMM/VMMR0/HWVMXR0.h8
-rw-r--r--src/VBox/VMM/VMMR0/PDMR0Device.cpp33
-rw-r--r--src/VBox/VMM/VMMR0/PDMR0Driver.cpp2
-rw-r--r--src/VBox/VMM/VMMR0/PGMR0.cpp196
-rw-r--r--src/VBox/VMM/VMMR0/PGMR0Bth.h2
-rw-r--r--src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp20
-rw-r--r--src/VBox/VMM/VMMR0/TRPMR0.cpp2
-rw-r--r--src/VBox/VMM/VMMR0/TRPMR0A.asm4
-rw-r--r--src/VBox/VMM/VMMR0/VMMR0.cpp105
-rw-r--r--src/VBox/VMM/VMMR0/VMMR0.def10
-rw-r--r--src/VBox/VMM/VMMR0/VMMR0JmpA-amd64.asm5
-rw-r--r--src/VBox/VMM/VMMR0/VMMR0JmpA-x86.asm2
-rw-r--r--src/VBox/VMM/VMMR3/CFGM.cpp4
-rw-r--r--src/VBox/VMM/VMMR3/CPUM.cpp20
-rw-r--r--src/VBox/VMM/VMMR3/CPUMDbg.cpp32
-rw-r--r--src/VBox/VMM/VMMR3/CSAM.cpp44
-rw-r--r--src/VBox/VMM/VMMR3/DBGF.cpp8
-rw-r--r--src/VBox/VMM/VMMR3/DBGFAddr.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/DBGFBp.cpp46
-rw-r--r--src/VBox/VMM/VMMR3/DBGFCoreWrite.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/DBGFCpu.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/DBGFDisas.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/DBGFInfo.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/DBGFLog.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/DBGFMem.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/DBGFModule.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/DBGFOS.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/DBGFR3Trace.cpp200
-rw-r--r--src/VBox/VMM/VMMR3/DBGFReg.cpp78
-rw-r--r--src/VBox/VMM/VMMR3/DBGFStack.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/DBGFSym.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/EM.cpp49
-rw-r--r--src/VBox/VMM/VMMR3/EMHwaccm.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/EMRaw.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/FTM.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/GMM.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/HWACCM.cpp59
-rw-r--r--src/VBox/VMM/VMMR3/IEMR3.cpp56
-rw-r--r--src/VBox/VMM/VMMR3/IOM.cpp166
-rw-r--r--src/VBox/VMM/VMMR3/MM.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/MMHeap.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/MMHyper.cpp72
-rw-r--r--src/VBox/VMM/VMMR3/MMPagePool.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/MMUkHeap.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/PATM.cpp97
-rw-r--r--src/VBox/VMM/VMMR3/PATMA.asm148
-rw-r--r--src/VBox/VMM/VMMR3/PATMA.mac2
-rw-r--r--src/VBox/VMM/VMMR3/PATMGuest.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/PATMPatch.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/PATMPatch.h2
-rw-r--r--src/VBox/VMM/VMMR3/PATMSSM.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/PDM.cpp23
-rw-r--r--src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp4
-rw-r--r--src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp232
-rw-r--r--src/VBox/VMM/VMMR3/PDMAsyncCompletionFileFailsafe.cpp71
-rw-r--r--src/VBox/VMM/VMMR3/PDMAsyncCompletionFileNormal.cpp42
-rw-r--r--src/VBox/VMM/VMMR3/PDMBlkCache.cpp8
-rw-r--r--src/VBox/VMM/VMMR3/PDMCritSect.cpp78
-rw-r--r--src/VBox/VMM/VMMR3/PDMDevHlp.cpp164
-rw-r--r--src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp59
-rw-r--r--src/VBox/VMM/VMMR3/PDMDevice.cpp93
-rw-r--r--src/VBox/VMM/VMMR3/PDMDriver.cpp6
-rw-r--r--src/VBox/VMM/VMMR3/PDMLdr.cpp37
-rw-r--r--src/VBox/VMM/VMMR3/PDMQueue.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/PDMThread.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/PDMUsb.cpp23
-rw-r--r--src/VBox/VMM/VMMR3/PGM.cpp146
-rw-r--r--src/VBox/VMM/VMMR3/PGMBth.h2
-rw-r--r--src/VBox/VMM/VMMR3/PGMDbg.cpp14
-rw-r--r--src/VBox/VMM/VMMR3/PGMGst.h2
-rw-r--r--src/VBox/VMM/VMMR3/PGMHandler.cpp29
-rw-r--r--src/VBox/VMM/VMMR3/PGMMap.cpp10
-rw-r--r--src/VBox/VMM/VMMR3/PGMPhys.cpp719
-rw-r--r--src/VBox/VMM/VMMR3/PGMPhysRWTmpl.h2
-rw-r--r--src/VBox/VMM/VMMR3/PGMPool.cpp112
-rw-r--r--src/VBox/VMM/VMMR3/PGMSavedState.cpp46
-rw-r--r--src/VBox/VMM/VMMR3/PGMSharedPage.cpp13
-rw-r--r--src/VBox/VMM/VMMR3/PGMShw.h2
-rw-r--r--src/VBox/VMM/VMMR3/SELM.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/SSM.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/STAM.cpp37
-rw-r--r--src/VBox/VMM/VMMR3/TM.cpp263
-rw-r--r--src/VBox/VMM/VMMR3/TRPM.cpp4
-rw-r--r--src/VBox/VMM/VMMR3/VBoxVMMDeps.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/VM.cpp328
-rw-r--r--src/VBox/VMM/VMMR3/VMEmt.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/VMM.cpp73
-rw-r--r--src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/VMMR3.def10
-rw-r--r--src/VBox/VMM/VMMR3/VMMSwitcher.cpp4
-rw-r--r--src/VBox/VMM/VMMR3/VMMTests.cpp4
-rw-r--r--src/VBox/VMM/VMMR3/VMReq.cpp2
-rw-r--r--src/VBox/VMM/VMMRC/CPUMRC.cpp2
-rw-r--r--src/VBox/VMM/VMMRC/CPUMRCA.asm4
-rw-r--r--src/VBox/VMM/VMMRC/CSAMRC.cpp2
-rw-r--r--src/VBox/VMM/VMMRC/EMRCA.asm4
-rw-r--r--src/VBox/VMM/VMMRC/HWACCMRCA.asm20
-rw-r--r--src/VBox/VMM/VMMRC/IOMRC.cpp2
-rw-r--r--src/VBox/VMM/VMMRC/MMRamRC.cpp2
-rw-r--r--src/VBox/VMM/VMMRC/MMRamRCA.asm4
-rw-r--r--src/VBox/VMM/VMMRC/PATMRC.cpp2
-rw-r--r--src/VBox/VMM/VMMRC/PDMRCDevice.cpp16
-rw-r--r--src/VBox/VMM/VMMRC/PGMRC.cpp2
-rw-r--r--src/VBox/VMM/VMMRC/PGMRCBth.h2
-rw-r--r--src/VBox/VMM/VMMRC/PGMRCGst.h2
-rw-r--r--src/VBox/VMM/VMMRC/PGMRCShw.h2
-rw-r--r--src/VBox/VMM/VMMRC/SELMRC.cpp2
-rw-r--r--src/VBox/VMM/VMMRC/TRPMRC.cpp6
-rw-r--r--src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp10
-rw-r--r--src/VBox/VMM/VMMRC/TRPMRCHandlersA.asm4
-rw-r--r--src/VBox/VMM/VMMRC/VMMRC.cpp4
-rw-r--r--src/VBox/VMM/VMMRC/VMMRC.def8
-rw-r--r--src/VBox/VMM/VMMRC/VMMRC.mac2
-rw-r--r--src/VBox/VMM/VMMRC/VMMRC0.asm2
-rw-r--r--src/VBox/VMM/VMMRC/VMMRC99.asm2
-rw-r--r--src/VBox/VMM/VMMRC/VMMRCA.asm4
-rw-r--r--src/VBox/VMM/VMMRC/VMMRCBuiltin.def2
-rw-r--r--src/VBox/VMM/VMMRC/VMMRCDeps.cpp2
-rw-r--r--src/VBox/VMM/VMMRZ/DBGFRZ.cpp2
-rw-r--r--src/VBox/VMM/VMMRZ/PGMRZDynMap.cpp2
-rw-r--r--src/VBox/VMM/VMMRZ/VMMRZ.cpp2
-rw-r--r--src/VBox/VMM/VMMSwitcher/32BitTo32Bit.asm2
-rw-r--r--src/VBox/VMM/VMMSwitcher/32BitToAMD64.asm2
-rw-r--r--src/VBox/VMM/VMMSwitcher/32BitToPAE.asm2
-rw-r--r--src/VBox/VMM/VMMSwitcher/AMD64To32Bit.asm2
-rw-r--r--src/VBox/VMM/VMMSwitcher/AMD64ToPAE.asm2
-rw-r--r--src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac15
-rw-r--r--src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac2
-rw-r--r--src/VBox/VMM/VMMSwitcher/PAETo32Bit.asm2
-rw-r--r--src/VBox/VMM/VMMSwitcher/PAEToAMD64.asm2
-rw-r--r--src/VBox/VMM/VMMSwitcher/PAEToPAE.asm2
-rw-r--r--src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac4
-rw-r--r--src/VBox/VMM/include/CFGMInternal.h2
-rw-r--r--src/VBox/VMM/include/CPUMInternal.h4
-rw-r--r--src/VBox/VMM/include/CPUMInternal.mac2
-rw-r--r--src/VBox/VMM/include/CSAMInternal.h2
-rw-r--r--src/VBox/VMM/include/DBGFInternal.h13
-rw-r--r--src/VBox/VMM/include/EMHandleRCTmpl.h2
-rw-r--r--src/VBox/VMM/include/EMInternal.h2
-rw-r--r--src/VBox/VMM/include/FTMInternal.h2
-rw-r--r--src/VBox/VMM/include/HWACCMInternal.h89
-rw-r--r--src/VBox/VMM/include/HWACCMInternal.mac12
-rw-r--r--src/VBox/VMM/include/IEMInternal.h1004
-rw-r--r--src/VBox/VMM/include/IOMInline.h197
-rw-r--r--src/VBox/VMM/include/IOMInternal.h148
-rw-r--r--src/VBox/VMM/include/MMInternal.h11
-rw-r--r--src/VBox/VMM/include/PATMA.h2
-rw-r--r--src/VBox/VMM/include/PATMInternal.h467
-rw-r--r--src/VBox/VMM/include/PDMAsyncCompletionFileInternal.h17
-rw-r--r--src/VBox/VMM/include/PDMAsyncCompletionInternal.h2
-rw-r--r--src/VBox/VMM/include/PDMBlkCacheInternal.h56
-rw-r--r--src/VBox/VMM/include/PDMInternal.h44
-rw-r--r--src/VBox/VMM/include/PGMGstDefs.h4
-rw-r--r--src/VBox/VMM/include/PGMInline.h307
-rw-r--r--src/VBox/VMM/include/PGMInternal.h614
-rw-r--r--src/VBox/VMM/include/REMInternal.h4
-rw-r--r--src/VBox/VMM/include/SELMInternal.h2
-rw-r--r--src/VBox/VMM/include/SSMInternal.h2
-rw-r--r--src/VBox/VMM/include/STAMInternal.h2
-rw-r--r--src/VBox/VMM/include/TMInline.h56
-rw-r--r--src/VBox/VMM/include/TMInternal.h93
-rw-r--r--src/VBox/VMM/include/TRPMInternal.h2
-rw-r--r--src/VBox/VMM/include/TRPMInternal.mac2
-rw-r--r--src/VBox/VMM/include/VMInternal.h12
-rw-r--r--src/VBox/VMM/include/VMMInternal.h3
-rw-r--r--src/VBox/VMM/include/VMMInternal.mac2
-rw-r--r--src/VBox/VMM/include/VMMSwitcher.h2
-rw-r--r--src/VBox/VMM/include/VMMSwitcher.mac2
-rw-r--r--src/VBox/VMM/include/internal/em.h2
-rw-r--r--src/VBox/VMM/include/internal/pgm.h2
-rw-r--r--src/VBox/VMM/include/internal/vm.h2
-rwxr-xr-xsrc/VBox/VMM/pure_test.sh2
-rw-r--r--src/VBox/VMM/testcase/Makefile.kmk23
-rw-r--r--[-rwxr-xr-x]src/VBox/VMM/testcase/mkdsk.sh0
-rw-r--r--src/VBox/VMM/testcase/tstAnimate.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstAsmStructs.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstAsmStructsAsm.asm2
-rw-r--r--src/VBox/VMM/testcase/tstCFGM.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstCompiler.cpp4
-rw-r--r--src/VBox/VMM/testcase/tstCompressionBenchmark.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstGlobalConfig.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstHelp.h15
-rw-r--r--src/VBox/VMM/testcase/tstIEMCheckMc.cpp410
-rw-r--r--src/VBox/VMM/testcase/tstInstrEmul.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstMMHyperHeap.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstMicro.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstMicro.h2
-rw-r--r--src/VBox/VMM/testcase/tstMicro.mac2
-rw-r--r--src/VBox/VMM/testcase/tstMicroRC.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstMicroRCA.asm4
-rw-r--r--src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstSSM.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstVMM-HwAccm.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstVMM.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstVMMFork.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstVMREQ.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstVMStructRC.cpp42
-rw-r--r--src/VBox/VMM/testcase/tstVMStructSize.cpp99
-rw-r--r--src/VBox/VMM/testcase/tstX86-1.cpp206
-rw-r--r--src/VBox/VMM/testcase/tstX86-1A.asm588
-rw-r--r--src/apps/Makefile.kmk2
-rw-r--r--src/apps/adpctl/Makefile.kmk2
-rw-r--r--src/apps/adpctl/VBoxNetAdpCtl.cpp19
-rw-r--r--src/apps/svnsync-vbox/Makefile.kmk2
-rw-r--r--src/apps/svnsync-vbox/main.c2
-rw-r--r--src/apps/svnsync-vbox/svn_private_config.h2
-rw-r--r--src/apps/tunctl/Makefile.kmk2
-rw-r--r--src/bldprogs/Makefile.kmk2
-rw-r--r--src/bldprogs/bin2c.c2
-rw-r--r--src/bldprogs/biossums.c2
-rw-r--r--[-rwxr-xr-x]src/bldprogs/checkUndefined.sh0
-rw-r--r--src/bldprogs/deftoimp.sed2
-rw-r--r--src/bldprogs/filesplitter.cpp2
-rw-r--r--src/bldprogs/preload.cpp4
-rw-r--r--src/bldprogs/scm.cpp4
-rw-r--r--src/libs/Makefile.kmk2
-rw-r--r--src/libs/kStuff/Makefile.kmk2
-rw-r--r--src/libs/kStuff/iprt/kHlpAlloc-iprt.cpp2
-rw-r--r--src/libs/kStuff/iprt/kHlpAssert-iprt.cpp2
-rw-r--r--src/libs/kStuff/iprt/kHlpEnv-iprt.cpp2
-rw-r--r--src/libs/kStuff/iprt/kHlpPage-iprt.cpp2
-rw-r--r--src/libs/kStuff/iprt/kHlpString-iprt.cpp2
-rw-r--r--src/libs/kStuff/iprt/kRdrFile-iprt.cpp2
-rw-r--r--src/libs/liblzf-3.4/Makefile.kmk2
-rw-r--r--src/libs/xpcom18a4/Config.kmk2
-rw-r--r--src/libs/xpcom18a4/Makefile.kmk6
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp2
-rw-r--r--src/libs/xpcom18a4/java/Makefile.kmk2
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxy.java1
-rw-r--r--src/libs/xpcom18a4/java/src/org/virtualbox/VBoxObjectBase.java2
-rw-r--r--src/libs/xpcom18a4/java/src/org/virtualbox/VirtualBoxManager.java125
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/java/tools/gen-nsError.pl0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/Makefile.in0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/admin/explode.pl0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/admin/makeTargetDirs.sh0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/admin/repackage.sh0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/admin/symlinks.sh0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/config/Makefile.in0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/config/config.mk0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/config/nfspwd.pl0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/config/nspr-config.in0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/config/rules.mk0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/configure0
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/linux/Makefile.in2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.com2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.in2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.targ2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/Makefile.in2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/depend2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_com2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_i3862
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_sparc2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/Makefile.in2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/depend2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/pkginfo.tmpl2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/prototype_com2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/prototype_sparc2
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh2
-rw-r--r--src/libs/xpcom18a4/nsprpub/pr/include/md/_iprt_atomic.h2
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/pr/src/misc/compile-et.pl0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/pr/tests/runtests.ksh0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/pr/tests/runtests.sh0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/nsprpub/pr/tests/runy2ktests.ksh0
-rw-r--r--src/libs/xpcom18a4/python/Makefile.kmk5
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/xpcom/reflect/xptcall/public/genstubs.pl0
-rw-r--r--[-rwxr-xr-x]src/libs/xpcom18a4/xpcom/tools/analyze-xpcom-log.pl0
-rw-r--r--src/recompiler/COPYING.LIB6
-rw-r--r--src/recompiler/Makefile-old.kmk314
-rw-r--r--src/recompiler/Makefile.kmk24
-rw-r--r--src/recompiler/README.vbox6
-rw-r--r--src/recompiler/REAMDE.vbox3
-rw-r--r--src/recompiler/Sun/config-host.h10
-rw-r--r--src/recompiler/Sun/config.h3
-rw-r--r--src/recompiler/Sun/crt/stdio.h2
-rw-r--r--src/recompiler/Sun/deftoimp.sed2
-rw-r--r--src/recompiler/Sun/kvm.h (renamed from src/VBox/HostDrivers/VBoxUSB/USBLibInternal.h)25
-rw-r--r--src/recompiler/Sun/testmath.c2
-rw-r--r--src/recompiler/VBoxREM.def2
-rw-r--r--src/recompiler/VBoxREMWrapper.cpp3
-rw-r--r--src/recompiler/VBoxREMWrapperA.asm2
-rw-r--r--src/recompiler/VBoxRecompiler.c633
-rw-r--r--src/recompiler/a.out.h431
-rw-r--r--src/recompiler/bswap.h136
-rw-r--r--src/recompiler/cache-utils.h41
-rw-r--r--src/recompiler/cpu-all.h821
-rw-r--r--src/recompiler/cpu-common.h135
-rw-r--r--src/recompiler/cpu-defs.h145
-rw-r--r--src/recompiler/cpu-exec.c1377
-rw-r--r--src/recompiler/cutils.c168
-rw-r--r--src/recompiler/def-helper.h258
-rw-r--r--src/recompiler/disas.h36
-rw-r--r--src/recompiler/dyngen-exec.h218
-rw-r--r--src/recompiler/elf.h40
-rw-r--r--src/recompiler/exec-all.h275
-rw-r--r--src/recompiler/exec.c3062
-rw-r--r--src/recompiler/fpu/softfloat-macros.h4
-rw-r--r--src/recompiler/fpu/softfloat-native.c39
-rw-r--r--src/recompiler/fpu/softfloat-native.h40
-rw-r--r--src/recompiler/fpu/softfloat-specialize.h12
-rw-r--r--src/recompiler/fpu/softfloat.c229
-rw-r--r--src/recompiler/fpu/softfloat.h15
-rw-r--r--src/recompiler/gen-icount.h40
-rw-r--r--src/recompiler/host-utils.c7
-rw-r--r--src/recompiler/host-utils.h110
-rw-r--r--src/recompiler/hostregs_helper.h61
-rw-r--r--src/recompiler/ioport.h71
-rw-r--r--src/recompiler/osdep.h110
-rw-r--r--src/recompiler/qemu-barrier.h10
-rw-r--r--src/recompiler/qemu-common.h249
-rw-r--r--src/recompiler/qemu-lock.h33
-rw-r--r--src/recompiler/qemu-log.h128
-rw-r--r--src/recompiler/qemu-queue.h449
-rw-r--r--src/recompiler/qemu-timer.h272
-rw-r--r--src/recompiler/softmmu_defs.h8
-rw-r--r--src/recompiler/softmmu_exec.h98
-rw-r--r--src/recompiler/softmmu_header.h180
-rw-r--r--src/recompiler/softmmu_template.h66
-rw-r--r--src/recompiler/target-i386/TODO32
-rw-r--r--src/recompiler/target-i386/cpu.h433
-rw-r--r--src/recompiler/target-i386/exec.h345
-rw-r--r--src/recompiler/target-i386/helper.c880
-rw-r--r--src/recompiler/target-i386/helper.h447
-rw-r--r--src/recompiler/target-i386/helper_template.h7
-rw-r--r--src/recompiler/target-i386/op_helper.c1343
-rw-r--r--src/recompiler/target-i386/opreg_template.h200
-rw-r--r--src/recompiler/target-i386/ops_mem.h156
-rw-r--r--src/recompiler/target-i386/ops_sse.h137
-rw-r--r--src/recompiler/target-i386/ops_sse_header.h426
-rw-r--r--src/recompiler/target-i386/ops_template.h607
-rw-r--r--src/recompiler/target-i386/ops_template_mem.h493
-rw-r--r--src/recompiler/target-i386/svm.h16
-rw-r--r--src/recompiler/target-i386/translate.c2108
-rw-r--r--src/recompiler/targphys.h21
-rw-r--r--src/recompiler/tcg-runtime.c (renamed from src/recompiler/tcg/tcg-runtime.c)38
-rw-r--r--src/recompiler/tcg/README150
-rw-r--r--src/recompiler/tcg/TODO3
-rw-r--r--src/recompiler/tcg/i386/Makefile.kup0
-rw-r--r--src/recompiler/tcg/i386/tcg-target.c2218
-rw-r--r--src/recompiler/tcg/i386/tcg-target.h93
-rw-r--r--src/recompiler/tcg/tcg-dyngen.c4
-rw-r--r--src/recompiler/tcg/tcg-op.h2871
-rw-r--r--src/recompiler/tcg/tcg-opc.h337
-rw-r--r--src/recompiler/tcg/tcg-runtime.h18
-rw-r--r--src/recompiler/tcg/tcg.c709
-rw-r--r--src/recompiler/tcg/tcg.h283
-rw-r--r--src/recompiler/tcg/x86_64/tcg-target.c1462
-rw-r--r--src/recompiler/tcg/x86_64/tcg-target.h78
-rw-r--r--src/recompiler/tests/Makefile43
-rw-r--r--src/recompiler/tests/linux-test.c41
-rw-r--r--src/recompiler/tests/qruncom.c79
-rw-r--r--src/recompiler/tests/runcom.c12
-rw-r--r--src/recompiler/tests/sha1.c28
-rw-r--r--src/recompiler/tests/test-i386-code16.S14
-rw-r--r--src/recompiler/tests/test-i386-shift.h4
-rw-r--r--src/recompiler/tests/test-i386-ssse3.c57
-rw-r--r--src/recompiler/tests/test-i386-vm86.S25
-rw-r--r--src/recompiler/tests/test-i386.c406
-rw-r--r--src/recompiler/tests/test-mmap.c485
-rw-r--r--src/recompiler/tests/test_path.c1
-rw-r--r--src/recompiler/translate-all.c62
-rw-r--r--src/recompiler/vl.h1414
-rw-r--r--src/testcase/Makefile.kmk2
-rw-r--r--src/testcase/tstRunTestcases.cpp2
2966 files changed, 179157 insertions, 101774 deletions
diff --git a/src/Makefile.kmk b/src/Makefile.kmk
index 687e28aa9..68f8f31d3 100644
--- a/src/Makefile.kmk
+++ b/src/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 34662 2010-12-02 21:51:17Z vboxsync $
## @file
# Top-level makefile for the src directory.
#
diff --git a/src/VBox/Additions/Makefile.kmk b/src/VBox/Additions/Makefile.kmk
index 273240621..d18ac300c 100644
--- a/src/VBox/Additions/Makefile.kmk
+++ b/src/VBox/Additions/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 38005 2011-07-18 10:17:43Z vboxsync $
## @file
# Top-level makefile for the VirtualBox Guest Additions.
#
@@ -73,7 +73,7 @@ ifndef VBOX_ONLY_TESTSUITE
ifeq ($(KBUILD_TARGET),linux)
INSTALLS += LnxAddIso-scripts
- LnxAddIso-scripts_INST = bin/additions
+ LnxAddIso-scripts_INST = $(INST_ADDITIONS)
LnxAddIso-scripts_MODE = a+rx,u+w
LnxAddIso-scripts_SOURCES = \
$(LnxAddIso-scripts_0_OUTDIR)/runasroot.sh \
@@ -122,8 +122,7 @@ ifndef VBOX_ONLY_TESTSUITE
$(PATH_TARGET)/VBoxGuestCat.dir/VBoxGuest.cat \
$(PATH_TARGET)/VBoxGuestCat.dir/VBoxGuest.sys \
$(PATH_TARGET)/VBoxGuestCat.dir/VBoxControl.exe \
- $(PATH_TARGET)/VBoxGuestCat.dir/VBoxTray.exe \
- $(PATH_TARGET)/VBoxGuestCat.dir/VBCoInst.dll
+ $(PATH_TARGET)/VBoxGuestCat.dir/VBoxTray.exe
endif # signing
VBoxGuest-inf_CLEAN = $(VBoxGuest-inf_SOURCES)
VBoxGuest-inf_BLDDIRS = \
@@ -133,24 +132,20 @@ ifndef VBOX_ONLY_TESTSUITE
$(call MSG_GENERATE,VBoxGuest-inf,$@,$<)
$(call VBOX_EDIT_INF_FN,$<,$@)
- $(PATH_TARGET)/VBoxGuestCat.dir/VBoxGuest.sys: $$(TARGET_VBoxGuest) | $$(dir $$@)
+ $(PATH_TARGET)/VBoxGuestCat.dir/VBoxGuest.sys: $$(VBoxGuest_1_TARGET) | $$(dir $$@)
$(INSTALL) -m 644 $< $(@D)
- $(PATH_TARGET)/VBoxGuestCat.dir/VBoxControl.exe: $$(TARGET_VBoxControl) | $$(dir $$@)
+ $(PATH_TARGET)/VBoxGuestCat.dir/VBoxControl.exe: $$(VBoxControl_1_TARGET) | $$(dir $$@)
$(INSTALL) -m 755 $< $(@D)
- $(PATH_TARGET)/VBoxGuestCat.dir/VBoxTray.exe: $$(TARGET_VBoxTray) | $$(dir $$@)
+ $(PATH_TARGET)/VBoxGuestCat.dir/VBoxTray.exe: $$(VBoxTray_1_TARGET) | $$(dir $$@)
$(INSTALL) -m 755 $< $(@D)
- $(PATH_TARGET)/VBoxGuestCat.dir/VBCoInst.dll: $$(TARGET_VBCoInst) | $$(dir $$@)
- $(INSTALL) -m 644 $< $(@D)
-
$(PATH_TARGET)/VBoxGuestCat.dir/VBoxGuest.cat: \
$(PATH_TARGET)/VBoxGuestCat.dir/VBoxGuest.inf \
$(PATH_TARGET)/VBoxGuestCat.dir/VBoxGuest.sys \
$(PATH_TARGET)/VBoxGuestCat.dir/VBoxControl.exe \
- $(PATH_TARGET)/VBoxGuestCat.dir/VBoxTray.exe \
- $(PATH_TARGET)/VBoxGuestCat.dir/VBCoInst.dll
+ $(PATH_TARGET)/VBoxGuestCat.dir/VBoxTray.exe
$(call MSG_TOOL,Inf2Cat,VBoxGuest-inf,$@,$<)
$(call VBOX_MAKE_CAT_FN, $(@D),$@)
endif # KBUILD_TARGET == win
@@ -303,7 +298,7 @@ $(VBOX_PATH_ADDITIONS_ISO)/VBoxGuestAdditions.iso: \
@# use iso-level 3 which is the most ISO conforming level with least restrictions; iso-level 4 maps to iso-level 2
@# with some extra restrictions removal (not conforming to ISO9660) which some platforms like Solaris 10 does not like.
$(VBOX_MKISOFS) -rational-rock -joliet -iso-level 3 \
- -volid "VBOXADDITIONS_$(VBOX_VERSION_STRING)_$(VBOX_SVN_REV)" -l -graft-points -o $@ \
+ -volid "VBOXADDITIONS_$(VBOX_VERSION_STRING_RAW)_$(VBOX_SVN_REV)" -l -graft-points -o $@ \
$(GUESTADDITIONS_FILESPEC.win) \
$(GUESTADDITIONS_FILESPEC.win.x86) \
$(GUESTADDITIONS_FILESPEC.win.amd64) \
diff --git a/src/VBox/Additions/common/Makefile.kmk b/src/VBox/Additions/common/Makefile.kmk
index dc6d66fbb..1dab16ba2 100644
--- a/src/VBox/Additions/common/Makefile.kmk
+++ b/src/VBox/Additions/common/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 34817 2010-12-07 21:36:12Z vboxsync $
## @file
# Sub-Makefile for the common addition code.
#
diff --git a/src/VBox/Additions/common/VBoxControl/Makefile.kmk b/src/VBox/Additions/common/VBoxControl/Makefile.kmk
index f3c520307..c57b43c28 100644
--- a/src/VBox/Additions/common/VBoxControl/Makefile.kmk
+++ b/src/VBox/Additions/common/VBoxControl/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 31002 2010-07-22 14:45:41Z vboxsync $
## @file
# Sub-Makefile for the Guest Additions Command Line Management Interface.
#
diff --git a/src/VBox/Additions/common/VBoxControl/VBoxControl.cpp b/src/VBox/Additions/common/VBoxControl/VBoxControl.cpp
index 5f2c9e015..e97876e93 100644
--- a/src/VBox/Additions/common/VBoxControl/VBoxControl.cpp
+++ b/src/VBox/Additions/common/VBoxControl/VBoxControl.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxControl.cpp $ */
+/* $Id: VBoxControl.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxControl - Guest Additions Command Line Management Interface.
*/
diff --git a/src/VBox/Additions/common/VBoxControl/VBoxControl.rc b/src/VBox/Additions/common/VBoxControl/VBoxControl.rc
index c9d1dd83a..e24f5fdfb 100644
--- a/src/VBox/Additions/common/VBoxControl/VBoxControl.rc
+++ b/src/VBox/Additions/common/VBoxControl/VBoxControl.rc
@@ -1,4 +1,4 @@
-/* $Id: VBoxControl.rc $ */
+/* $Id: VBoxControl.rc 32394 2010-09-10 12:13:11Z vboxsync $ */
/** @file
* VBoxControl - Resource file containing version info and icon.
*/
diff --git a/src/VBox/Additions/common/VBoxControl/testcase/Makefile.kmk b/src/VBox/Additions/common/VBoxControl/testcase/Makefile.kmk
index 05a94c447..77c765d90 100644
--- a/src/VBox/Additions/common/VBoxControl/testcase/Makefile.kmk
+++ b/src/VBox/Additions/common/VBoxControl/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the VBoxControl testcases.
#
diff --git a/src/VBox/Additions/common/VBoxControl/testcase/tstVBoxControl.cpp b/src/VBox/Additions/common/VBoxControl/testcase/tstVBoxControl.cpp
index 7536162bb..e1b489607 100644
--- a/src/VBox/Additions/common/VBoxControl/testcase/tstVBoxControl.cpp
+++ b/src/VBox/Additions/common/VBoxControl/testcase/tstVBoxControl.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstVBoxControl.cpp $ */
+/* $Id: tstVBoxControl.cpp 32705 2010-09-23 07:06:34Z vboxsync $ */
/** @file
* VBoxControl - Guest Additions Command Line Management Interface, test case
*/
diff --git a/src/VBox/Additions/common/VBoxGuest/Makefile.kmk b/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
index df0cda7ef..6c02155b1 100644
--- a/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
+++ b/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37981 2011-07-15 14:19:10Z vboxsync $
## @file
# Makefile for the Cross Platform Guest Additions Driver.
#
@@ -51,6 +51,7 @@ if1of ($(KBUILD_TARGET), freebsd $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linu
VBoxGuest_INCS = .
VBoxGuest_INCS.freebsd = $(PATH_VBoxGuest) $(PATH_INS)/gen-sys-hdrs
VBoxGuest_INCS.linux = ../../../Runtime/r0drv/linux
+ VBoxGuest_LDFLAGS.solaris += -N misc/ctf
ifneq ($(KBUILD_TARGET),os2)
ifeq ($(KBUILD_TARGET),win)
VBoxGuest_LDFLAGS.x86 = -Entry:DriverEntry@8
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c
index 680b5eef1..bdc48e6eb 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuest-freebsd.c $ */
+/* $Id: VBoxGuest-freebsd.c 34521 2010-11-30 14:35:40Z vboxsync $ */
/** @file
* VirtualBox Guest Additions Driver for FreeBSD.
*/
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c
index a404b19d2..89b02e1fa 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c
@@ -1,4 +1,4 @@
-/* $Rev: 67140 $ */
+/* $Rev: 36408 $ */
/** @file
* VBoxGuest - Linux specifics.
*
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.cpp
index b1ae4156f..1feac79d1 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuest-os2.cpp $ */
+/* $Id: VBoxGuest-os2.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxGuest - OS/2 specifics.
*/
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.def b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.def
index 4728686eb..c1526e368 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.def
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.def
@@ -1,4 +1,4 @@
-; $Id: VBoxGuest-os2.def $
+; $Id: VBoxGuest-os2.def 31517 2010-08-10 11:28:35Z vboxsync $
;; @file
; VBoxGuest - OS/2 definition file.
;
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c
index b1868c5bc..d87907ad3 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuest-solaris.c $ */
+/* $Id: VBoxGuest-solaris.c 36408 2011-03-24 16:25:47Z vboxsync $ */
/** @file
* VirtualBox Guest Additions Driver for Solaris.
*/
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-pnp.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-pnp.cpp
index 8e2f8c0e7..fb844b78e 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-pnp.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-pnp.cpp
@@ -208,7 +208,7 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
VBOXGUEST_UPDATE_DEVSTATE(pDevExt, SURPRISEREMOVED);
- /* Do nothing here actually. Cleanup is done in IRP_MN_REMOVE_DEVICE.
+ /* Do nothing here actually. Cleanup is done in IRP_MN_REMOVE_DEVICE.
* This request is not expected for VBoxGuest.
*/
LogRel(("VBoxGuest: unexpected device removal\n"));
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
index b04292694..bab93c98d 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
@@ -25,24 +25,17 @@
#include <VBox/log.h>
#include <VBox/VBoxGuestLib.h>
-#include <VBoxGuestInternal.h>
-
-#ifdef TARGET_NT4
/*
* XP DDK #defines ExFreePool to ExFreePoolWithTag. The latter does not exist
* on NT4, so... The same for ExAllocatePool.
*/
-#undef ExAllocatePool
-#undef ExFreePool
+#ifdef TARGET_NT4
+# undef ExAllocatePool
+# undef ExFreePool
#endif
/*******************************************************************************
-* Defined Constants And Macros *
-*******************************************************************************/
-
-
-/*******************************************************************************
-* Entry Points *
+* Internal Functions *
*******************************************************************************/
RT_C_DECLS_BEGIN
static NTSTATUS vboxguestwinAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj);
@@ -50,18 +43,12 @@ static void vboxguestwinUnload(PDRIVER_OBJECT pDrvObj);
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 vboxguestwinSystemControl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
static NTSTATUS vboxguestwinShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp);
static NTSTATUS vboxguestwinNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-RT_C_DECLS_END
-
-
-/*******************************************************************************
-* Internal Functions *
-*******************************************************************************/
-RT_C_DECLS_BEGIN
#ifdef DEBUG
- static void vboxguestwinDoTests(void);
+static void vboxguestwinDoTests(void);
#endif
RT_C_DECLS_END
@@ -88,7 +75,6 @@ RT_C_DECLS_END
/** The detected Windows version. */
winVersion_t g_winVersion;
-
/**
* Driver entry point.
*
@@ -165,7 +151,7 @@ ULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
pDrvObj->MajorFunction[IRP_MJ_CREATE] = vboxguestwinCreate;
pDrvObj->MajorFunction[IRP_MJ_CLOSE] = vboxguestwinClose;
pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = vboxguestwinIOCtl;
- pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = vboxguestwinIOCtl;
+ pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = vboxguestwinInternalIOCtl;
pDrvObj->MajorFunction[IRP_MJ_SHUTDOWN] = vboxguestwinShutdown;
pDrvObj->MajorFunction[IRP_MJ_READ] = vboxguestwinNotSupportedStub;
pDrvObj->MajorFunction[IRP_MJ_WRITE] = vboxguestwinNotSupportedStub;
@@ -221,6 +207,8 @@ static NTSTATUS vboxguestwinAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDe
pDevExt = (PVBOXGUESTDEVEXT)pDeviceObject->DeviceExtension;
RtlZeroMemory(pDevExt, sizeof(VBOXGUESTDEVEXT));
+ KeInitializeSpinLock(&pDevExt->win.s.MouseEventAccessLock);
+
pDevExt->win.s.pDeviceObject = pDeviceObject;
pDevExt->win.s.prevDevState = STOPPED;
pDevExt->win.s.devState = STOPPED;
@@ -541,7 +529,7 @@ NTSTATUS vboxguestwinCleanup(PDEVICE_OBJECT pDevObj)
*
* @param pDrvObj Driver object.
*/
-void vboxguestwinUnload(PDRIVER_OBJECT pDrvObj)
+static void vboxguestwinUnload(PDRIVER_OBJECT pDrvObj)
{
Log(("VBoxGuest::vboxguestwinGuestUnload\n"));
#ifdef TARGET_NT4
@@ -576,7 +564,7 @@ void vboxguestwinUnload(PDRIVER_OBJECT pDrvObj)
* @param pDevObj Device object.
* @param pIrp Request packet.
*/
-NTSTATUS vboxguestwinCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+static NTSTATUS vboxguestwinCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
/** @todo AssertPtrReturn(pIrp); */
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
@@ -645,7 +633,7 @@ NTSTATUS vboxguestwinCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* @param pDevObj Device object.
* @param pIrp Request packet.
*/
-NTSTATUS vboxguestwinClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+static NTSTATUS vboxguestwinClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
@@ -676,20 +664,20 @@ NTSTATUS vboxguestwinClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* @param pDevObj Device object.
* @param pIrp Request packet.
*/
-NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+static NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
- NTSTATUS Status = STATUS_SUCCESS;
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
- PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
- unsigned int uCmd = (unsigned int)pStack->Parameters.DeviceIoControl.IoControlCode;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
+ PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
+ unsigned int uCmd = (unsigned int)pStack->Parameters.DeviceIoControl.IoControlCode;
- char *pBuf = (char *)pIrp->AssociatedIrp.SystemBuffer; /* All requests are buffered. */
- size_t cbData = pStack->Parameters.DeviceIoControl.InputBufferLength;
- unsigned cbOut = 0;
+ char *pBuf = (char *)pIrp->AssociatedIrp.SystemBuffer; /* All requests are buffered. */
+ size_t cbData = pStack->Parameters.DeviceIoControl.InputBufferLength;
+ unsigned cbOut = 0;
/* Do we have a file object associated?*/
- PFILE_OBJECT pFileObj = pStack->FileObject;
- PVBOXGUESTSESSION pSession = NULL;
+ PFILE_OBJECT pFileObj = pStack->FileObject;
+ PVBOXGUESTSESSION pSession = NULL;
if (pFileObj) /* ... then we might have a session object as well! */
pSession = (PVBOXGUESTSESSION)pFileObj->FsContext;
@@ -698,6 +686,8 @@ NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
/* We don't have a session associated with the file object? So this seems
* to be a kernel call then. */
+ /** @todo r=bird: What on earth is this supposed to be? Each kernel session
+ * shall have its own context of course, no hacks, pleeease. */
if (pSession == NULL)
{
Log(("VBoxGuest::vboxguestwinIOCtl: Using kernel session data ...\n"));
@@ -755,7 +745,7 @@ NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* Process the common IOCtls.
*/
size_t cbDataReturned;
- int vrc = VBoxGuestCommonIOCtl(uCmd, pDevExt, pSession, (void*)pBuf, cbData, &cbDataReturned);
+ int vrc = VBoxGuestCommonIOCtl(uCmd, pDevExt, pSession, pBuf, cbData, &cbDataReturned);
Log(("VBoxGuest::vboxguestwinGuestDeviceControl: rc=%Rrc, pBuf=0x%p, cbData=%u, cbDataReturned=%u\n",
vrc, pBuf, cbData, cbDataReturned));
@@ -794,6 +784,71 @@ NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
return Status;
}
+/**
+ * Internal Device I/O Control entry point.
+ *
+ * We do not want to allow some IOCTLs to be originated from user mode, this is
+ * why we have a different entry point for internal IOCTLs.
+ *
+ * @param pDevObj Device object.
+ * @param pIrp Request packet.
+ *
+ * @todo r=bird: This is no need for this extra function for the purpose of
+ * securing an IOCTL from user space access. VBoxGuestCommonIOCtl
+ * has a way to do this already, see VBOXGUEST_IOCTL_GETVMMDEVPORT.
+ */
+static NTSTATUS vboxguestwinInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
+ PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
+ unsigned int uCmd = (unsigned int)pStack->Parameters.DeviceIoControl.IoControlCode;
+ bool fProcessed = false;
+ unsigned Info = 0;
+
+ switch (uCmd)
+ {
+ case VBOXGUEST_IOCTL_INTERNAL_SET_MOUSE_NOTIFY_CALLBACK:
+ {
+ PVOID pvBuf = pStack->Parameters.Others.Argument1;
+ size_t cbData = (size_t)pStack->Parameters.Others.Argument2;
+ fProcessed = true;
+ if (cbData != sizeof(VBoxGuestMouseSetNotifyCallback))
+ {
+ AssertFailed();
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ KIRQL OldIrql;
+ VBoxGuestMouseSetNotifyCallback *pInfo = (VBoxGuestMouseSetNotifyCallback*)pvBuf;
+ /* we need a lock here to avoid concurrency with the set event functionality */
+ KeAcquireSpinLock(&pDevExt->win.s.MouseEventAccessLock, &OldIrql);
+ pDevExt->win.s.pfnMouseNotify = pInfo->pfnNotify;
+ pDevExt->win.s.pvMouseNotify = pInfo->pvNotify;
+ KeReleaseSpinLock(&pDevExt->win.s.MouseEventAccessLock, OldIrql);
+
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ default:
+ break;
+ }
+
+
+ if (fProcessed)
+ {
+ pIrp->IoStatus.Status = Status;
+ pIrp->IoStatus.Information = Info;
+
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ return Status;
+ }
+
+ return vboxguestwinIOCtl(pDevObj, pIrp);
+}
+
/**
* IRP_MJ_SYSTEM_CONTROL handler.
@@ -878,6 +933,20 @@ void vboxguestwinDpcHandler(PKDPC pDPC, PDEVICE_OBJECT pDevObj,
PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
Log(("VBoxGuest::vboxguestwinGuestDpcHandler: pDevExt=0x%p\n", pDevExt));
+ /* test & reset the counter */
+ if (ASMAtomicXchgU32(&pDevExt->u32MousePosChangedSeq, 0))
+ {
+ Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
+ /* we need a lock here to avoid concurrency with the set event ioctl handler thread,
+ * i.e. to prevent the event from destroyed while we're using it */
+ KeAcquireSpinLockAtDpcLevel(&pDevExt->win.s.MouseEventAccessLock);
+ if (pDevExt->win.s.pfnMouseNotify)
+ {
+ pDevExt->win.s.pfnMouseNotify(pDevExt->win.s.pvMouseNotify);
+ }
+ KeReleaseSpinLockFromDpcLevel(&pDevExt->win.s.MouseEventAccessLock);
+ }
+
/* Process the wake-up list we were asked by the scheduling a DPC
* in vboxguestwinIsrHandler(). */
VBoxGuestWaitDoWakeUps(pDevExt);
@@ -909,7 +978,7 @@ BOOLEAN vboxguestwinIsrHandler(PKINTERRUPT pInterrupt, PVOID pServiceContext)
{
Log(("VBoxGuest::vboxguestwinGuestIsrHandler: IRQ was taken! pInterrupt = 0x%p, pDevExt = 0x%p\n",
pInterrupt, pDevExt));
- if (!RTListIsEmpty(&pDevExt->WakeUpList))
+ if (ASMAtomicUoReadU32(&pDevExt->u32MousePosChangedSeq) || !RTListIsEmpty(&pDevExt->WakeUpList))
{
Log(("VBoxGuest::vboxguestwinGuestIsrHandler: Requesting DPC ...\n"));
IoRequestDpc(pDevExt->win.s.pDeviceObject, pDevExt->win.s.pCurrentIrp, NULL);
@@ -920,14 +989,16 @@ BOOLEAN vboxguestwinIsrHandler(PKINTERRUPT pInterrupt, PVOID pServiceContext)
/*
- * Overridden routine for mouse polling events. Not
- * used at the moment on Windows.
+ * Overridden routine for mouse polling events.
*
* @param pDevExt Device extension structure.
*/
void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
{
NOREF(pDevExt);
+ /* nothing to do here - i.e. since we can not KeSetEvent from ISR level,
+ * we rely on the pDevExt->u32MousePosChangedSeq to be set to a non-zero value on a mouse event
+ * and queue the DPC in our ISR routine in that case doing KeSetEvent from the DPC routine */
}
@@ -1192,10 +1263,10 @@ VBOXOSTYPE vboxguestwinVersionToOSType(winVersion_t winVer)
return enmOsType;
}
-
#ifdef DEBUG
-/** A quick implementation of AtomicTestAndClear for uint32_t and multiple
- * bits.
+
+/**
+ * A quick implementation of AtomicTestAndClear for uint32_t and multiple bits.
*/
static uint32_t vboxugestwinAtomicBitsTestAndClear(void *pu32Bits, uint32_t u32Mask)
{
@@ -1244,4 +1315,6 @@ static void vboxguestwinDoTests()
vboxguestwinTestAtomicTestAndClearBitsU32(0x11, 0x32, 0x10);
vboxguestwinTestAtomicTestAndClearBitsU32(0x22, 0x23, 0x22);
}
-#endif
+
+#endif /* DEBUG */
+
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h
index f0a3f41a0..db3307dd0 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h
@@ -115,6 +115,11 @@ typedef struct VBOXGUESTDEVEXTWIN
/** Pre-allocated kernel session data. This is needed
* for handling kernel IOCtls. */
PVBOXGUESTSESSION pKernelSession;
+
+
+ KSPIN_LOCK MouseEventAccessLock;
+ PFNVBOXMOUSENOTIFYCB pfnMouseNotify;
+ void *pvMouseNotify;
} VBOXGUESTDEVEXTWIN, *PVBOXGUESTDEVEXTWIN;
#define VBOXGUEST_UPDATE_DEVSTATE(_pDevExt, _newDevState) do { \
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
index 10138d797..77a66bcd9 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuest.cpp $ */
+/* $Id: VBoxGuest.cpp 34406 2010-11-26 16:45:34Z vboxsync $ */
/** @file
* VBoxGuest - Guest Additions Driver, Common Code.
*/
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest2.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest2.cpp
index 799a12e3a..a326513cf 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest2.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest2.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxGuest2.cpp $ */
+/* $Id: VBoxGuest2.cpp 35907 2011-02-09 11:20:31Z vboxsync $ */
/** @file
* VBoxGuest - Guest Additions Driver, bits shared with the windows code.
*/
/*
- * Copyright (C) 2010 Oracle Corporation
+ * 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;
@@ -115,10 +115,10 @@ int VBoxGuestReportDriverStatus(bool fActive)
Log(("VBoxGuestReportDriverStatus: VbglGRAlloc VMMDevReportGuestStatus completed with rc=%Rrc\n", rc));
if (RT_SUCCESS(rc))
{
- pReq2->guestStatus.facility = VBoxGuestStatusFacility_VBoxGuestDriver;
+ pReq2->guestStatus.facility = VBoxGuestFacilityType_VBoxGuestDriver;
pReq2->guestStatus.status = fActive ?
- VBoxGuestStatusCurrent_Active
- : VBoxGuestStatusCurrent_Inactive;
+ VBoxGuestFacilityStatus_Active
+ : VBoxGuestFacilityStatus_Inactive;
pReq2->guestStatus.flags = 0;
rc = VbglGRPerform(&pReq2->header);
Log(("VBoxGuestReportDriverStatus: VbglGRPerform VMMDevReportGuestStatus completed with fActive=%d, rc=%Rrc\n",
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest2.h b/src/VBox/Additions/common/VBoxGuest/VBoxGuest2.h
index 74fac205d..a7214d7a9 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest2.h
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest2.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuest2.h $ */
+/* $Id: VBoxGuest2.h 32434 2010-09-12 23:11:51Z vboxsync $ */
/** @file
* VBoxGuest - Guest Additions Driver, bits shared with the windows code.
*/
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuestA-os2.asm b/src/VBox/Additions/common/VBoxGuest/VBoxGuestA-os2.asm
index bb8757f19..bb018c4de 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuestA-os2.asm
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuestA-os2.asm
@@ -1,4 +1,4 @@
-; $Id: VBoxGuestA-os2.asm $
+; $Id: VBoxGuestA-os2.asm 31517 2010-08-10 11:28:35Z vboxsync $
;; @file
; VBoxGuest - OS/2 assembly file, the first file in the link.
;
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h b/src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h
index bc9ae6d38..be447cc0e 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h
@@ -1,4 +1,4 @@
-/* $Rev: 67205 $ */
+/* $Rev: 33595 $ */
/** @file
* VBoxGuest - Inter Driver Communication, unix implementation.
*
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h b/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
index 14c32651f..a82215821 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestInternal.h $ */
+/* $Id: VBoxGuestInternal.h 33750 2010-11-03 21:00:26Z vboxsync $ */
/** @file
* VBoxGuest - Guest Additions Driver.
*/
diff --git a/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile b/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile
index cf5588377..a295456af 100644
--- a/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile
+++ b/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile $
+# $Id: Makefile 37233 2011-05-27 13:31:57Z vboxsync $
## @file
# VirtualBox Guest Additions Module Makefile.
#
@@ -123,6 +123,7 @@ SRCS += \
RTSemEventMultiWaitNoResume-2-ex-generic.c \
RTTimerCreate-generic.c \
timer-generic.c \
+ errvars-generic.c \
mppresent-generic.c
.PATH: ${.CURDIR}/r0drv
diff --git a/src/VBox/Additions/common/VBoxGuest/freebsd/files_vboxguest b/src/VBox/Additions/common/VBoxGuest/freebsd/files_vboxguest
index 876b54afa..7d022ca77 100755..100644
--- a/src/VBox/Additions/common/VBoxGuest/freebsd/files_vboxguest
+++ b/src/VBox/Additions/common/VBoxGuest/freebsd/files_vboxguest
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: files_vboxguest $
+# $Id: files_vboxguest 37955 2011-07-14 12:23:02Z vboxsync $
## @file
# Shared file between Makefile.kmk and export_modules
#
@@ -57,13 +57,13 @@ FILES_VBOXGUEST_NOBIN=" \
${PATH_ROOT}/include/iprt/path.h=>include/iprt/path.h \
${PATH_ROOT}/include/iprt/once.h=>include/iprt/once.h \
${PATH_ROOT}/include/iprt/critsect.h=>include/iprt/critsect.h \
+ ${PATH_ROOT}/include/iprt/x86.h=>include/iprt/x86.h \
${PATH_ROOT}/include/iprt/nocrt/limits.h=>include/iprt/nocrt/limits.h \
${PATH_ROOT}/include/VBox/cdefs.h=>include/VBox/cdefs.h \
${PATH_ROOT}/include/VBox/err.h=>include/VBox/err.h \
${PATH_ROOT}/include/VBox/log.h=>include/VBox/log.h \
${PATH_ROOT}/include/VBox/param.h=>include/VBox/param.h \
${PATH_ROOT}/include/VBox/types.h=>include/VBox/types.h \
- ${PATH_ROOT}/include/VBox/x86.h=>include/VBox/x86.h \
${PATH_ROOT}/include/VBox/ostypes.h=>include/VBox/ostypes.h \
${PATH_ROOT}/include/VBox/VMMDev.h=>include/VBox/VMMDev.h \
${PATH_ROOT}/include/VBox/VMMDev2.h=>include/VBox/VMMDev2.h \
@@ -156,6 +156,7 @@ FILES_VBOXGUEST_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp=>generic/RTSemEventMultiWait-2-ex-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventMultiWaitNoResume-2-ex-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTTimerCreate-generic.cpp=>generic/RTTimerCreate-generic.c \
+ ${PATH_ROOT}/src/VBox/Runtime/generic/errvars-generic.cpp=>generic/errvars-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/timer-generic.cpp=>generic/timer-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/mppresent-generic.cpp=>generic/mppresent-generic.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.cpp=>r0drv/alloc-r0drv.c \
diff --git a/src/VBox/Additions/common/VBoxGuest/linux/Makefile b/src/VBox/Additions/common/VBoxGuest/linux/Makefile
index 61a1cd53c..c14476892 100644
--- a/src/VBox/Additions/common/VBoxGuest/linux/Makefile
+++ b/src/VBox/Additions/common/VBoxGuest/linux/Makefile
@@ -1,10 +1,10 @@
-# $Revision: 70883 $
+# $Revision: 37233 $
## @file
# VirtualBox Guest Additions Module Makefile.
#
#
-# 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;
@@ -15,52 +15,13 @@
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
-#
-# First, figure out which architecture we're targeting and the build type.
-# (We have to support basic cross building (ARCH=i386|x86_64).)
-# While at it, warn about BUILD_* vars found to help with user problems.
-#
-ifeq ($(filter-out x86_64 amd64 AMD64,$(shell uname -m)),)
- BUILD_TARGET_ARCH_DEF := amd64
-else
- BUILD_TARGET_ARCH_DEF := x86
-endif
-ifneq ($(filter-out amd64 x86,$(BUILD_TARGET_ARCH)),)
- $(warning Ignoring unknown BUILD_TARGET_ARCH value '$(BUILD_TARGET_ARCH)'.)
- BUILD_TARGET_ARCH :=
-endif
-ifeq ($(BUILD_TARGET_ARCH),)
- ifeq ($(ARCH),x86_64)
- BUILD_TARGET_ARCH := amd64
- else
- ifeq ($(ARCH),i386)
- BUILD_TARGET_ARCH := x86
- else
- BUILD_TARGET_ARCH := $(BUILD_TARGET_ARCH_DEF)
- endif
- endif
-else
- ifneq ($(BUILD_TARGET_ARCH),$(BUILD_TARGET_ARCH_DEF))
- $(warning Using BUILD_TARGET_ARCH='$(BUILD_TARGET_ARCH)' from the $(origin BUILD_TARGET_ARCH).)
- endif
-endif
-
-ifneq ($(filter-out release profile debug strict,$(BUILD_TYPE)),)
- $(warning Ignoring unknown BUILD_TYPE value '$(BUILD_TYPE)'.)
- BUILD_TYPE :=
-endif
-ifeq ($(BUILD_TYPE),)
- BUILD_TYPE := release
-else
- ifneq ($(BUILD_TYPE),release)
- $(warning Using BUILD_TYPE='$(BUILD_TYPE)' from the $(origin BUILD_TYPE).)
- endif
-endif
+# Linux kbuild sets this to our source directory if we are called from there
+obj ?= $(CURDIR)
+include $(obj)/Makefile.include.header
+MOD_NAME = vboxguest
-# override is required by the Debian guys
-override MODULE = vboxguest
-OBJS = \
+MOD_OBJS = \
VBoxGuest-linux.o \
VBoxGuest.o \
VBoxGuest2.o \
@@ -88,6 +49,7 @@ OBJS = \
r0drv/linux/semfastmutex-r0drv-linux.o \
r0drv/linux/spinlock-r0drv-linux.o \
r0drv/linux/thread-r0drv-linux.o \
+ r0drv/linux/thread2-r0drv-linux.o \
r0drv/linux/time-r0drv-linux.o \
r0drv/linux/RTLogWriteDebugger-r0drv-linux.o \
r0drv/generic/semspinmutex-r0drv-generic.o \
@@ -108,6 +70,7 @@ OBJS = \
common/misc/RTAssertMsg2Weak.o \
common/misc/RTAssertMsg2WeakV.o \
common/misc/assert.o \
+ common/misc/thread.o \
common/string/RTStrCopy.o \
common/string/RTStrCopyP.o \
common/string/strformat.o \
@@ -115,6 +78,7 @@ OBJS = \
common/string/strformattype.o \
common/string/strprintf.o \
common/string/strtonum.o \
+ common/table/avlpv.o \
common/time/time.o \
generic/RTAssertShouldPanic-generic.o \
generic/RTLogWriteStdErr-stub-generic.o \
@@ -123,10 +87,11 @@ OBJS = \
generic/RTSemEventWaitNoResume-2-ex-generic.o \
generic/RTSemEventMultiWait-2-ex-generic.o \
generic/RTSemEventMultiWaitNoResume-2-ex-generic.o \
+ generic/errvars-generic.o \
VBox/log-vbox.o \
VBox/logbackdoor.o
ifeq ($(BUILD_TARGET_ARCH),x86)
-OBJS += \
+MOD_OBJS += \
common/math/gcc/divdi3.o \
common/math/gcc/moddi3.o \
common/math/gcc/udivdi3.o \
@@ -134,176 +99,45 @@ OBJS += \
common/math/gcc/qdivrem.o
endif
ifeq ($(BUILD_TARGET_ARCH),amd64)
-OBJS += common/alloc/heapsimple.o
+MOD_OBJS += common/alloc/heapsimple.o
endif
-ifneq ($(MAKECMDGOALS),clean)
-
-ifeq ($(KERNELRELEASE),)
-
- #
- # building from this directory
- #
-
- # kernel base directory
- ifndef KERN_DIR
- KERN_DIR := /lib/modules/$(shell uname -r)/build
- ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
- KERN_DIR := /usr/src/linux
- ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
- $(error Error: unable to find the sources of your current Linux kernel. \
- Specify KERN_DIR=<directory> and run Make again)
- endif
- $(warning Warning: using /usr/src/linux as the source directory of your \
- Linux kernel. If this is not correct, specify \
- KERN_DIR=<directory> and run Make again.)
- endif
- else
- ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
- $(error Error: KERN_DIR does not point to a directory)
- endif
- endif
-
- # includes
- ifndef KERN_INCL
- KERN_INCL = $(KERN_DIR)/include
- endif
- ifneq ($(shell if test -d $(KERN_INCL); then echo yes; fi),yes)
- $(error Error: unable to find the include directory for your current Linux \
- kernel. Specify KERN_INCL=<directory> and run Make again)
- endif
-
- # module install dir, only for current kernel
- ifneq ($(filter install install_rpm,$(MAKECMDGOALS)),)
- ifndef MODULE_DIR
- MODULE_DIR_TST := /lib/modules/$(shell uname -r)
- ifeq ($(shell if test -d $(MODULE_DIR_TST); then echo yes; fi),yes)
- MODULE_DIR := $(MODULE_DIR_TST)/misc
- else
- $(error Unable to find the folder to install the additions driver to)
- endif
- endif # MODULE_DIR unspecified
- endif
-
- # guess kernel version (24 or 26)
- ifeq ($(shell if grep '"2\.4\.' $(KERN_INCL)/linux/version.h > /dev/null; then echo yes; fi),yes)
- KERN_VERSION := 24
- else
- KERN_VERSION := 26
- endif
-
-else # neq($(KERNELRELEASE),)
-
- #
- # building from kbuild (make -C <kernel_directory> M=`pwd`)
- #
-
- # guess kernel version (24 or 26)
- ifeq ($(shell if echo "$(VERSION).$(PATCHLEVEL)." | grep '2\.4\.' > /dev/null; then echo yes; fi),yes)
- KERN_VERSION := 24
- else
- KERN_VERSION := 26
- endif
-
-endif # neq($(KERNELRELEASE),)
-
-# debug - show guesses.
-ifdef DEBUG
-$(warning dbg: KERN_DIR = $(KERN_DIR))
-$(warning dbg: KERN_INCL = $(KERN_INCL))
-$(warning dbg: MODULE_DIR = $(MODULE_DIR))
-$(warning dbg: KERN_VERSION = $(KERN_VERSION))
+MOD_DEFS = -DVBOX -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 -DIN_GUEST \
+ -DIN_GUEST_R0 -DIN_MODULE -DRT_WITH_VBOX -DVBGL_VBOXGUEST \
+ -DVBOX_WITH_HGCM
+ifeq ($(BUILD_TARGET_ARCH),amd64)
+ MOD_DEFS += -DRT_ARCH_AMD64
+else
+ MOD_DEFS += -DRT_ARCH_X86
endif
-
-KBUILD_VERBOSE ?= 1
-
-#
-# Compiler options
-#
-ifndef INCL
- INCL := $(addprefix -I,$(KERN_INCL) $(EXTRA_INCL))
- ifndef KBUILD_EXTMOD
- KBUILD_EXTMOD := $(shell pwd)
- endif
- INCL += $(addprefix -I$(KBUILD_EXTMOD),/ /include /r0drv/linux)
- INCL += $(addprefix -I$(KBUILD_EXTMOD)/vboxguest,/ /include /r0drv/linux)
- export INCL
+ifeq ($(BUILD_TARGET_ARCH),amd64)
+ MOD_DEFS += -DVBOX_WITH_64_BITS_GUESTS
endif
+MOD_INCL = $(addprefix -I$(KBUILD_EXTMOD),/ /include /r0drv/linux)
+MOD_INCL += $(addprefix -I$(KBUILD_EXTMOD)/vboxguest,/ /include /r0drv/linux)
+
ifneq ($(wildcard $(KBUILD_EXTMOD)/vboxguest),)
MANGLING := $(KBUILD_EXTMOD)/vboxguest/include/VBox/VBoxGuestMangling.h
else
MANGLING := $(KBUILD_EXTMOD)/include/VBox/VBoxGuestMangling.h
endif
-KFLAGS := -D__KERNEL__ -DMODULE \
- -DVBOX -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 -DIN_GUEST -DIN_GUEST_R0 \
- -DIN_MODULE -DRT_WITH_VBOX -DVBGL_VBOXGUEST -DVBOX_WITH_HGCM
-ifeq ($(BUILD_TARGET_ARCH),amd64)
- KFLAGS += -DRT_ARCH_AMD64 -DVBOX_WITH_64_BITS_GUESTS
+ifeq ($(KERN_VERSION),24)
+ ## @todo move to MOD_DEFS when we have finished refactoring
+ MOD_CFLAGS = -DEXPORT_SYMTAB
else
- KFLAGS += -DRT_ARCH_X86
-endif
-ifeq ($(BUILD_TYPE),debug)
-KFLAGS += -DDEBUG
-endif
-
-ifeq ($(KERN_VERSION), 24)
-#
-# 2.4
-#
-
-ifeq ($(BUILD_TARGET_ARCH),amd64)
- KFLAGS += -mcmodel=kernel
+ MOD_CFLAGS = -include $(MANGLING)
endif
-CFLAGS := -O2 -DVBOX_LINUX_2_4 -DEXPORT_SYMTAB $(INCL) $(KFLAGS) $(KDEBUG)
-MODULE_EXT := o
+MOD_CLEAN = . linux r0drv generic r0drv/linux r0drv/generic VBox \
+ common/alloc common/err common/log common/math/gcc common/misc \
+ common/string common/time
-# 2.4 Module linking
-$(MODULE).o: $(OBJS)
- $(LD) -o $@ -r $(OBJS)
+include $(obj)/Makefile.include.footer
-.PHONY: $(MODULE)
-all: $(MODULE)
-$(MODULE): $(MODULE).o
-
-else
-#
-# 2.6 and later
-#
-
-MODULE_EXT := ko
-
-$(MODULE)-y := $(OBJS)
-
-# build defs
-EXTRA_CFLAGS += -include $(MANGLING) $(INCL) $(KFLAGS) $(KDEBUG)
-
-all: $(MODULE)
-
-obj-m += $(MODULE).o
-
-$(MODULE):
- $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C $(KERN_DIR) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) modules
-
-endif
-
-install: $(MODULE)
- @mkdir -p $(MODULE_DIR); \
- install -m 0664 -o root -g root $(MODULE).$(MODULE_EXT) $(MODULE_DIR); \
- PATH="$(PATH):/bin:/sbin" depmod -a;
-
-endif # eq($(MAKECMDGOALS),clean)
-
-check: $(MODULE)
+check: $(MOD_NAME)
@if ! readelf -p __ksymtab_strings vboxguest.ko | grep -E "\[.*\] *(RT|g_..*RT.*)"; then \
echo "All exported IPRT symbols are properly renamed!"; \
else \
echo "error: Some exported IPRT symbols was not properly renamed! See above." >&2; \
false; \
fi
-
-clean:
- for f in . linux r0drv generic r0drv/linux r0drv/generic VBox \
- common/alloc common/err common/log common/math/gcc common/misc common/string common/time; \
- do rm -f $$f/*.o $$f/.*.cmd $$f/.*.flags; done
- rm -rf .vboxguest* .tmp_ver* vboxguest.* Module.symvers Modules.symvers modules.order
diff --git a/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest b/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest
index 9a23c6159..8c56bcd8c 100755..100644
--- a/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest
+++ b/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: files_vboxguest $
+# $Id: files_vboxguest 37964 2011-07-14 13:20:55Z vboxsync $
## @file
# Shared file between Makefile.kmk and export_modules
#
@@ -52,6 +52,7 @@ FILES_VBOXGUEST_NOBIN=" \
${PATH_ROOT}/include/iprt/time.h=>include/iprt/time.h \
${PATH_ROOT}/include/iprt/types.h=>include/iprt/types.h \
${PATH_ROOT}/include/iprt/uni.h=>include/iprt/uni.h \
+ ${PATH_ROOT}/include/iprt/x86.h=>include/iprt/x86.h \
${PATH_ROOT}/include/VBox/cdefs.h=>include/VBox/cdefs.h \
${PATH_ROOT}/include/VBox/err.h=>include/VBox/err.h \
${PATH_ROOT}/include/VBox/log.h=>include/VBox/log.h \
@@ -81,6 +82,8 @@ FILES_VBOXGUEST_NOBIN=" \
${PATH_ROOT}/src/VBox/Additions/common/VBoxGuestLib/VBGLInternal.h=>VBGLInternal.h \
${PATH_ROOT}/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestLog.h=>VBoxGuestLog.h \
${PATH_ROOT}/src/VBox/Additions/common/VBoxGuestLib/VMMDev.cpp=>VMMDev.c \
+ ${PATH_ROOT}/src/VBox/Installer/linux/Makefile.include.header=>Makefile.include.header \
+ ${PATH_ROOT}/src/VBox/Installer/linux/Makefile.include.footer=>Makefile.include.footer \
${PATH_ROOT}/src/VBox/Runtime/include/internal/assert.h=>include/internal/assert.h \
${PATH_ROOT}/src/VBox/Runtime/include/internal/initterm.h=>include/internal/initterm.h \
${PATH_ROOT}/src/VBox/Runtime/include/internal/iprt.h=>include/internal/iprt.h \
@@ -90,6 +93,8 @@ FILES_VBOXGUEST_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/include/internal/string.h=>include/internal/string.h \
${PATH_ROOT}/src/VBox/Runtime/include/internal/thread.h=>include/internal/thread.h \
${PATH_ROOT}/src/VBox/Runtime/include/internal/time.h=>include/internal/time.h \
+ ${PATH_ROOT}/src/VBox/Runtime/include/internal/sched.h=>include/internal/sched.h \
+ ${PATH_ROOT}/src/VBox/Runtime/include/internal/process.h=>include/internal/process.h \
${PATH_ROOT}/src/VBox/Runtime/common/alloc/alloc.cpp=>common/alloc/alloc.c \
${PATH_ROOT}/src/VBox/Runtime/common/alloc/heapsimple.cpp=>common/alloc/heapsimple.c \
${PATH_ROOT}/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp=>common/err/RTErrConvertFromErrno.c \
@@ -114,6 +119,7 @@ FILES_VBOXGUEST_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/common/misc/RTAssertMsg2Weak.cpp=>common/misc/RTAssertMsg2Weak.c \
${PATH_ROOT}/src/VBox/Runtime/common/misc/RTAssertMsg2WeakV.cpp=>common/misc/RTAssertMsg2WeakV.c \
${PATH_ROOT}/src/VBox/Runtime/common/misc/assert.cpp=>common/misc/assert.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/misc/thread.cpp=>common/misc/thread.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopy.cpp=>common/string/RTStrCopy.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyP.cpp=>common/string/RTStrCopyP.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/strformat.cpp=>common/string/strformat.c \
@@ -121,6 +127,13 @@ FILES_VBOXGUEST_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/common/string/strformattype.cpp=>common/string/strformattype.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf.cpp=>common/string/strprintf.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/strtonum.cpp=>common/string/strtonum.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avlpv.cpp=>common/table/avlpv.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_Base.cpp.h=>common/table/avl_Base.cpp.h \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_Get.cpp.h=>common/table/avl_Get.cpp.h \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_GetBestFit.cpp.h=>common/table/avl_GetBestFit.cpp.h \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_RemoveBestFit.cpp.h=>common/table/avl_RemoveBestFit.cpp.h \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_DoWithAll.cpp.h=>common/table/avl_DoWithAll.cpp.h \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_Destroy.cpp.h=>common/table/avl_Destroy.cpp.h \
${PATH_ROOT}/src/VBox/Runtime/common/time/time.cpp=>common/time/time.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTAssertShouldPanic-generic.cpp=>generic/RTAssertShouldPanic-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTLogWriteStdErr-stub-generic.cpp=>generic/RTLogWriteStdErr-stub-generic.c \
@@ -129,6 +142,7 @@ FILES_VBOXGUEST_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventWaitNoResume-2-ex-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp=>generic/RTSemEventMultiWait-2-ex-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventMultiWaitNoResume-2-ex-generic.c \
+ ${PATH_ROOT}/src/VBox/Runtime/generic/errvars-generic.cpp=>generic/errvars-generic.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.cpp=>r0drv/alloc-r0drv.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.h=>r0drv/alloc-r0drv.h \
${PATH_ROOT}/src/VBox/Runtime/r0drv/initterm-r0drv.cpp=>r0drv/initterm-r0drv.c \
@@ -152,6 +166,7 @@ FILES_VBOXGUEST_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/string.h=>r0drv/linux/string.h \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h=>r0drv/linux/the-linux-kernel.h \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c=>r0drv/linux/thread-r0drv-linux.c \
+ ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c=>r0drv/linux/thread2-r0drv-linux.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c=>r0drv/linux/time-r0drv-linux.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/waitqueue-r0drv-linux.h=>r0drv/linux/waitqueue-r0drv-linux.h \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c=>r0drv/linux/RTLogWriteDebugger-r0drv-linux.c \
diff --git a/src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.inf b/src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.inf
index 1fc7a93f3..09b56d398 100644
--- a/src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.inf
+++ b/src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.inf
@@ -1,7 +1,7 @@
;
; INF file for installing the VirtualBox Windows guest driver
;
-; Copyright (C) 2006-2007 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;
@@ -14,10 +14,10 @@
[Version]
Signature="$WINDOWS NT$"
-Class=System
-ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318}
Provider=%ORACLE%
-LayoutFile=layout.inf
+ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318}
+Class=System
+DriverPackageType=PlugAndPlay
;edit-DriverVer=08/26/2008,2.00.0000
;cat CatalogFile=VBoxGuest.cat
@@ -25,17 +25,14 @@ LayoutFile=layout.inf
1 = %VBoxGuest.MediaDesc%
2 = %VBoxControl.MediaDesc%
3 = %VBoxTray.MediaDesc%
-4 = %vbcoinst.MediaDesc%
[SourceDisksFiles]
VBoxGuest.sys = 1
VBoxControl.exe = 2
VBoxTray.exe = 3
-vbcoinst.dll = 4
[DestinationDirs]
DefaultDestDir = 12 ; drivers
-VBox_CoInstaller_CopyFiles = 11 ; system32
VBoxTray_CopyFiles = 11 ; system32
[Manufacturer]
@@ -72,16 +69,6 @@ ServiceBinary = %12%\VBoxGuest.sys
[VBoxTray_Add_Reg]
HKLM, SOFTWARE\Microsoft\Windows\CurrentVersion\Run, VBoxTray, 0x00000000, %11%\VBoxTray.exe
-[VBoxGuest_Install.CoInstallers]
-AddReg = VBoxGuest_Install_CoInstallers_reg
-CopyFiles = VBox_CoInstaller_CopyFiles
-
-[VBox_CoInstaller_CopyFiles]
-vbcoinst.dll
-
-[VBoxGuest_Install_CoInstallers_reg]
-HKR,,CoInstallers32,0x00010000,"vbcoinst.dll,VBoxCoInstaller"
-
[ClassInstall32]
; This should fix the error 0xe0000101 (The required section was not found in the INF).
diff --git a/src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.rc b/src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.rc
index 0b2920e9e..f08489a4d 100644
--- a/src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.rc
+++ b/src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.rc
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuest.rc $ */
+/* $Id: VBoxGuest.rc 32399 2010-09-10 12:47:16Z vboxsync $ */
/** @file
* VBoxGuest - Resource file containing version info and icon.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp b/src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp
index bea8334bd..01cf1c682 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp
@@ -1,4 +1,4 @@
-/* $Revision: 71297 $ */
+/* $Revision: 36740 $ */
/** @file
* VBoxGuestLibR0 - Generic VMMDev request management.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp b/src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp
index 7fef12879..1c7b2a572 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp
@@ -1,4 +1,4 @@
-/* $Revision: 60692 $ */
+/* $Revision: 28800 $ */
/** @file
* VBoxGuestLib - Host-Guest Communication Manager.
*
diff --git a/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp b/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
index 733560430..d2f726a8a 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
@@ -1,4 +1,4 @@
-/* $Revision: 70398 $ */
+/* $Revision: 36373 $ */
/** @file
* VBoxGuestLib - Host-Guest Communication Manager internal functions, implemented by VBoxGuest
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/Init.cpp b/src/VBox/Additions/common/VBoxGuestLib/Init.cpp
index 4a736a345..f76743293 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/Init.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/Init.cpp
@@ -1,4 +1,4 @@
-/* $Revision: 67748 $ */
+/* $Revision: 34066 $ */
/** @file
* VBoxGuestLibR0 - Library initialization.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk b/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk
index 242aeb5b9..7d5e1a9e6 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk
+++ b/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Sub-Makefile for the common guest addition code library.
#
diff --git a/src/VBox/Additions/common/VBoxGuestLib/PhysHeap.cpp b/src/VBox/Additions/common/VBoxGuestLib/PhysHeap.cpp
index 51f1281d0..407f14c94 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/PhysHeap.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/PhysHeap.cpp
@@ -1,4 +1,4 @@
-/* $Revision: 67140 $ */
+/* $Revision: 33540 $ */
/** @file
* VBoxGuestLibR0 - Physical memory heap.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/SysHlp.cpp b/src/VBox/Additions/common/VBoxGuestLib/SysHlp.cpp
index 4b40de0c5..3cc126602 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/SysHlp.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/SysHlp.cpp
@@ -1,4 +1,4 @@
-/* $Revision: 67140 $ */
+/* $Revision: 33540 $ */
/** @file
* VBoxGuestLibR0 - IDC with VBoxGuest and HGCM helpers.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/SysHlp.h b/src/VBox/Additions/common/VBoxGuestLib/SysHlp.h
index 8b68df513..80b50f895 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/SysHlp.h
+++ b/src/VBox/Additions/common/VBoxGuestLib/SysHlp.h
@@ -1,4 +1,4 @@
-/* $Revision: 60692 $ */
+/* $Revision: 28800 $ */
/** @file
* VBoxGuestLibR0 - System dependent helpers internal header.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBGLInternal.h b/src/VBox/Additions/common/VBoxGuestLib/VBGLInternal.h
index 711761aad..0c511956f 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBGLInternal.h
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBGLInternal.h
@@ -1,4 +1,4 @@
-/* $Revision: 60692 $ */
+/* $Revision: 36318 $ */
/** @file
* VBoxGuestLibR0 - Internal header.
*/
@@ -35,11 +35,11 @@
#ifdef RT_OS_WINDOWS /** @todo dprintf() -> Log() */
-#if (defined(DEBUG) && !defined(NO_LOGGING)) || defined(LOG_ENABLED)
-# define dprintf(a) RTLogBackdoorPrintf a
-#else
-# define dprintf(a) do {} while (0)
-#endif
+# if (defined(DEBUG) && !defined(NO_LOGGING)) || defined(LOG_ENABLED)
+# define dprintf(a) RTLogBackdoorPrintf a
+# else
+# define dprintf(a) do {} while (0)
+# endif
#else
# define dprintf(a) Log(a)
#endif
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBGLR3Internal.h b/src/VBox/Additions/common/VBoxGuestLib/VBGLR3Internal.h
index a36e81291..8a767d0da 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBGLR3Internal.h
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBGLR3Internal.h
@@ -1,4 +1,4 @@
-/* $Id: VBGLR3Internal.h $ */
+/* $Id: VBGLR3Internal.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 support library for the guest additions, Internal header.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
index b32b60a4d..6ca0c727a 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
@@ -1,4 +1,4 @@
-/* $Revision: 67658 $ */
+/* $Revision: 37672 $ */
/** @file
* VBoxGuestR0LibSharedFolders - Ring 0 Shared Folders calls.
*/
@@ -111,6 +111,7 @@ DECLVBGL(void) vboxDisconnect (PVBSFCLIENT pClient)
data.u32ClientID = pClient->ulClientID;
rc = VbglHGCMDisconnect (pClient->handle, &data);
+ NOREF(rc);
/* Log(("VBOXSF: VBoxSF::vboxDisconnect: "
"VbglHGCMDisconnect rc = %#x, result = %#x\n", rc, data.result));
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp
index ce834f4ba..dffa3ca86 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3Lib.cpp $ */
+/* $Id: VBoxGuestR3Lib.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Core.
*/
@@ -187,7 +187,7 @@ static int vbglR3Init(const char *pszDeviceName)
DosClose(ahfs[i]);
}
}
- g_File = hf;
+ g_File = (RTFILE)hf;
#elif defined(VBOX_VBGLR3_XFREE86)
int File = xf86open(pszDeviceName, XF86_O_RDWR);
@@ -266,7 +266,7 @@ VBGLR3DECL(void) VbglR3Term(void)
RTFILE File = g_File;
g_File = NIL_RTFILE;
AssertReturnVoid(File != NIL_RTFILE);
- APIRET rc = DosClose(File);
+ APIRET rc = DosClose((uintptr_t)File);
AssertMsg(!rc, ("%ld\n", rc));
# else /* The IPRT case. */
@@ -322,7 +322,7 @@ int vbglR3DoIOCtl(unsigned iFunction, void *pvData, size_t cbData)
ULONG cbOS2Parm = cbData;
int32_t vrc = VERR_INTERNAL_ERROR;
ULONG cbOS2Data = sizeof(vrc);
- APIRET rc = DosDevIOCtl(g_File, VBOXGUEST_IOCTL_CATEGORY, iFunction,
+ APIRET rc = DosDevIOCtl((uintptr_t)g_File, VBOXGUEST_IOCTL_CATEGORY, iFunction,
pvData, cbData, &cbOS2Parm,
&vrc, sizeof(vrc), &cbOS2Data);
if (RT_LIKELY(!rc))
@@ -343,7 +343,7 @@ int vbglR3DoIOCtl(unsigned iFunction, void *pvData, size_t cbData)
* error instead of an errno.h one. Alternatively, extend/redefine the
* header with an error code return field (much better alternative
* actually). */
- int rc = ioctl((int)g_File, iFunction, &Hdr);
+ int rc = ioctl(RTFileToNative(g_File), iFunction, &Hdr);
if (rc == -1)
{
rc = errno;
@@ -355,7 +355,7 @@ int vbglR3DoIOCtl(unsigned iFunction, void *pvData, size_t cbData)
# ifdef VBOX_VBGLR3_XFREE86
int rc = xf86ioctl((int)g_File, iFunction, pvData);
# else
- int rc = ioctl((int)g_File, iFunction, pvData);
+ int rc = ioctl(RTFileToNative(g_File), iFunction, pvData);
# endif
if (RT_LIKELY(rc == 0))
return VINF_SUCCESS;
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAdditions.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAdditions.cpp
index 0353f046a..bfc9e4a24 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAdditions.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAdditions.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibAdditions.cpp $ */
+/* $Id: VBoxGuestR3LibAdditions.cpp 37262 2011-05-30 14:13:17Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Additions Info.
*/
@@ -158,8 +158,8 @@ static int vbglR3CloseAdditionsWinStoragePath(HKEY hKey)
* @param enmStatus The new status of the facility.
* @param fReserved Reserved for future use (what?).
*/
-VBGLR3DECL(int) VbglR3ReportAdditionsStatus(VBoxGuestStatusFacility enmFacility,
- VBoxGuestStatusCurrent enmStatusCurrent,
+VBGLR3DECL(int) VbglR3ReportAdditionsStatus(VBoxGuestFacilityType enmFacility,
+ VBoxGuestFacilityStatus enmStatusCurrent,
uint32_t fReserved)
{
VMMDevReportGuestStatus Report;
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibBalloon.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibBalloon.cpp
index cd4279bb0..076fe9721 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibBalloon.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibBalloon.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibBalloon.cpp $ */
+/* $Id: VBoxGuestR3LibBalloon.cpp 31045 2010-07-23 09:48:52Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Ballooning.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibClipboard.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibClipboard.cpp
index 2c13b0aa1..ad21c4873 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibClipboard.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibClipboard.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibClipboard.cpp $ */
+/* $Id: VBoxGuestR3LibClipboard.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Clipboard.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCoreDump.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCoreDump.cpp
index 8ef0006b4..0ff3e2140 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCoreDump.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCoreDump.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibCoreDump.cpp $ */
+/* $Id: VBoxGuestR3LibCoreDump.cpp 32574 2010-09-16 17:44:29Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Core Dumps.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCpuHotPlug.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCpuHotPlug.cpp
index 563548394..5c626654f 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCpuHotPlug.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCpuHotPlug.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibCpuHotPlug.cpp $ */
+/* $Id: VBoxGuestR3LibCpuHotPlug.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, CPU Hot Plugging.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCredentials.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCredentials.cpp
index 678d32ee3..25c72bd18 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCredentials.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCredentials.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibCredentials.cpp $ */
+/* $Id: VBoxGuestR3LibCredentials.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, user credentials.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp
index a314e522c..9ca617fb7 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp
@@ -1,4 +1,4 @@
-/** $Id: VBoxGuestR3LibDaemonize.cpp $ */
+/** $Id: VBoxGuestR3LibDaemonize.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, daemonize a process.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibEvent.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibEvent.cpp
index f1d901428..93caeb8a3 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibEvent.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibEvent.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibEvent.cpp $ */
+/* $Id: VBoxGuestR3LibEvent.cpp 29291 2010-05-10 10:12:44Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Events.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGR.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGR.cpp
index b8a3fa7f2..133b6a80f 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGR.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGR.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibGR.cpp $ */
+/* $Id: VBoxGuestR3LibGR.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, GR.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp
index b35349e62..e9ee37bbd 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibGuestCtrl.cpp $ */
+/* $Id: VBoxGuestR3LibGuestCtrl.cpp 37375 2011-06-08 10:51:26Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, guest control.
*/
@@ -92,8 +92,7 @@ VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t u32ClientId)
/**
- * Gets a host message.
- *
+ * Waits until a new host message arrives.
* This will block until a message becomes available.
*
* @returns VBox status code.
@@ -102,7 +101,7 @@ VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t u32ClientId)
* @param puNumParms Where to store the number of parameters which will be received
* in a second call to the host.
*/
-VBGLR3DECL(int) VbglR3GuestCtrlGetHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms)
+VBGLR3DECL(int) VbglR3GuestCtrlWaitForHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms)
{
AssertPtrReturn(puMsg, VERR_INVALID_PARAMETER);
AssertPtrReturn(puNumParms, VERR_INVALID_PARAMETER);
@@ -158,6 +157,138 @@ VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId)
/**
+ * Closes a formerly opened guest directory.
+ *
+ * @return IPRT status code.
+ ** @todo Docs!
+ */
+VBGLR3DECL(int) VbglR3GuestCtrlGetCmdDirClose(uint32_t u32ClientId, uint32_t uNumParms,
+ uint32_t *puContext, uint32_t *puHandle)
+{
+ AssertPtrReturn(puContext, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(puHandle, VERR_INVALID_PARAMETER);
+
+ VBoxGuestCtrlHGCMMsgDirClose Msg;
+
+ Msg.hdr.result = VERR_WRONG_ORDER;
+ Msg.hdr.u32ClientID = u32ClientId;
+ Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
+ Msg.hdr.cParms = uNumParms;
+
+ VbglHGCMParmUInt32Set(&Msg.context, 0);
+ VbglHGCMParmUInt32Set(&Msg.handle, 0);
+
+ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
+ if (RT_SUCCESS(rc))
+ {
+ int rc2 = Msg.hdr.result;
+ if (RT_FAILURE(rc2))
+ {
+ rc = rc2;
+ }
+ else
+ {
+ Msg.context.GetUInt32(puContext);
+ Msg.handle.GetUInt32(puHandle);
+ }
+ }
+ return rc;
+}
+
+
+/**
+ * Opens a guest directory for reading.
+ *
+ * @return IPRT status code.
+ ** @todo Docs!
+ */
+VBGLR3DECL(int) VbglR3GuestCtrlGetCmdDirOpen(uint32_t u32ClientId, uint32_t uNumParms,
+ uint32_t *puContext,
+ char *pszDir, uint32_t cbDir,
+ char *pszFilter, uint32_t cbFilter,
+ uint32_t *puFlags,
+ char *pszUser, uint32_t cbUser,
+ char *pszPassword, uint32_t cbPassword)
+{
+ AssertPtrReturn(pszDir, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pszFilter, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(puFlags, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pszUser, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pszPassword, VERR_INVALID_PARAMETER);
+
+ VBoxGuestCtrlHGCMMsgDirOpen Msg;
+
+ Msg.hdr.result = VERR_WRONG_ORDER;
+ Msg.hdr.u32ClientID = u32ClientId;
+ Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
+ Msg.hdr.cParms = uNumParms;
+
+ VbglHGCMParmUInt32Set(&Msg.context, 0);
+ VbglHGCMParmPtrSet(&Msg.directory, pszDir, cbDir);
+ VbglHGCMParmPtrSet(&Msg.filter, pszFilter, cbFilter);
+ VbglHGCMParmUInt32Set(&Msg.flags, 0);
+ VbglHGCMParmPtrSet(&Msg.username, pszUser, cbUser);
+ VbglHGCMParmPtrSet(&Msg.password, pszPassword, cbPassword);
+
+ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
+ if (RT_SUCCESS(rc))
+ {
+ int rc2 = Msg.hdr.result;
+ if (RT_FAILURE(rc2))
+ {
+ rc = rc2;
+ }
+ else
+ {
+ Msg.context.GetUInt32(puContext);
+ Msg.flags.GetUInt32(puFlags);
+ }
+ }
+ return rc;
+}
+
+
+/**
+ * Opens a guest directory for reading.
+ *
+ * @return IPRT status code.
+ ** @todo Docs!
+ */
+VBGLR3DECL(int) VbglR3GuestCtrlGetCmdDirRead(uint32_t u32ClientId, uint32_t uNumParms,
+ uint32_t *puContext, uint32_t *puHandle)
+{
+ AssertPtrReturn(puContext, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(puHandle, VERR_INVALID_PARAMETER);
+
+ VBoxGuestCtrlHGCMMsgDirRead Msg;
+
+ Msg.hdr.result = VERR_WRONG_ORDER;
+ Msg.hdr.u32ClientID = u32ClientId;
+ Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
+ Msg.hdr.cParms = uNumParms;
+
+ VbglHGCMParmUInt32Set(&Msg.context, 0);
+ VbglHGCMParmUInt32Set(&Msg.handle, 0);
+
+ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
+ if (RT_SUCCESS(rc))
+ {
+ int rc2 = Msg.hdr.result;
+ if (RT_FAILURE(rc2))
+ {
+ rc = rc2;
+ }
+ else
+ {
+ Msg.context.GetUInt32(puContext);
+ Msg.handle.GetUInt32(puHandle);
+ }
+ }
+ return rc;
+}
+
+
+/**
* Allocates and gets host data, based on the message id.
*
* This will block until data becomes available.
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp
index 27f86c4b9..1014b44d6 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibGuestProp.cpp $ */
+/* $Id: VBoxGuestR3LibGuestProp.cpp 36638 2011-04-11 09:51:59Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, guest properties.
*/
@@ -30,7 +30,7 @@
*******************************************************************************/
#include <iprt/string.h>
#ifndef VBOX_VBGLR3_XFREE86
-# include <iprt/mem.h>
+# include <iprt/cpp/mem.h>
#endif
#include <iprt/assert.h>
#include <iprt/stdarg.h>
@@ -57,7 +57,8 @@ extern "C" void* xf86memset(const void*,int,xf86size_t);
DECLINLINE(char const *) RTStrEnd(char const *pszString, size_t cchMax)
{
- /* Avoid potential issues with memchr seen in glibc. */
+ /* Avoid potential issues with memchr seen in glibc.
+ * See sysdeps/x86_64/memchr.S in glibc versions older than 2.11 */
while (cchMax > RTSTR_MEMCHR_MAX)
{
char const *pszRet = (char const *)memchr(pszString, '\0', RTSTR_MEMCHR_MAX);
@@ -71,7 +72,8 @@ DECLINLINE(char const *) RTStrEnd(char const *pszString, size_t cchMax)
DECLINLINE(char *) RTStrEnd(char *pszString, size_t cchMax)
{
- /* Avoid potential issues with memchr seen in glibc. */
+ /* Avoid potential issues with memchr seen in glibc.
+ * See sysdeps/x86_64/memchr.S in glibc versions older than 2.11 */
while (cchMax > RTSTR_MEMCHR_MAX)
{
char *pszRet = (char *)memchr(pszString, '\0', RTSTR_MEMCHR_MAX);
@@ -606,7 +608,7 @@ VBGLR3DECL(int) VbglR3GuestPropEnum(uint32_t u32ClientId,
char const **ppszFlags)
{
/* Create the handle. */
- RTMemAutoPtr<VBGLR3GUESTPROPENUM, VbglR3GuestPropEnumFree> Handle;
+ RTCMemAutoPtr<VBGLR3GUESTPROPENUM, VbglR3GuestPropEnumFree> Handle;
Handle = (PVBGLR3GUESTPROPENUM)RTMemAllocZ(sizeof(VBGLR3GUESTPROPENUM));
if (!Handle)
return VERR_NO_MEMORY;
@@ -617,7 +619,7 @@ VBGLR3DECL(int) VbglR3GuestPropEnum(uint32_t u32ClientId,
cchPatterns += strlen(papszPatterns[i]) + 1;
/* Pack the pattern array */
- RTMemAutoPtr<char> Patterns;
+ RTCMemAutoPtr<char> Patterns;
Patterns = (char *)RTMemAlloc(cchPatterns);
size_t off = 0;
for (uint32_t i = 0; i < cPatterns; ++i)
@@ -631,7 +633,7 @@ VBGLR3DECL(int) VbglR3GuestPropEnum(uint32_t u32ClientId,
/* Randomly chosen initial size for the buffer to hold the enumeration
* information. */
uint32_t cchBuf = 4096;
- RTMemAutoPtr<char> Buf;
+ RTCMemAutoPtr<char> Buf;
/* In reading the guest property data we are racing against the host
* adding more of it, so loop a few times and retry on overflow. */
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibLog.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibLog.cpp
index 01aacd4ed..468c37971 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibLog.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibLog.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibLog.cpp $ */
+/* $Id: VBoxGuestR3LibLog.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Logging.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp
index cc298cb26..5cdcadd97 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibMisc.cpp $ */
+/* $Id: VBoxGuestR3LibMisc.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Misc.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibModule.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibModule.cpp
index f0bb28d50..1807bdc03 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibModule.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibModule.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibModule.cpp $ */
+/* $Id: VBoxGuestR3LibModule.cpp 30061 2010-06-07 09:34:15Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Shared modules.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMouse.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMouse.cpp
index 4306eb586..c23134dca 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMouse.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMouse.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibMouse.cpp $ */
+/* $Id: VBoxGuestR3LibMouse.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Mouse.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibRuntimeXF86.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibRuntimeXF86.cpp
index 36427fe87..c1f0af5bd 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibRuntimeXF86.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibRuntimeXF86.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibRuntimeXF86.cpp $ */
+/* $Id: VBoxGuestR3LibRuntimeXF86.cpp 31159 2010-07-28 03:28:00Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions,
* implements the minimum of runtime functions needed for
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSeamless.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSeamless.cpp
index c82ed08ca..a0ba5e5c1 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSeamless.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSeamless.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibSeamless.cpp $ */
+/* $Id: VBoxGuestR3LibSeamless.cpp 37384 2011-06-08 15:09:14Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Seamless mode.
*/
@@ -136,30 +136,38 @@ VBGLR3DECL(int) VbglR3SeamlessGetLastEvent(VMMDevSeamlessMode *pMode)
* @todo A scatter-gather version of vbglR3GRPerform would be nice, so that we don't have
* to copy our rectangle and header data into a single structure and perform an
* additional allocation.
+ * @todo Would that really gain us much, given that the rectangles may not
+ * be grouped at all, or in the format we need? Keeping the memory
+ * for our "single structure" around (re-alloc-ing it if necessary)
+ * sounds like a simpler optimisation if we need it.
*/
VBGLR3DECL(int) VbglR3SeamlessSendRects(uint32_t cRects, PRTRECT pRects)
{
VMMDevVideoSetVisibleRegion *pReq;
int rc;
- if (!cRects || !pRects)
- return VINF_SUCCESS;
+ AssertReturn(pRects || cRects == 0, VERR_INVALID_PARAMETER);
AssertMsgReturn(cRects <= _1M, ("%u\n", cRects), VERR_OUT_OF_RANGE);
- AssertReturn(sizeof(VMMDevVideoSetVisibleRegion)+(cRects-1)*sizeof(RTRECT)
- == sizeof(VMMDevVideoSetVisibleRegion)+(uint64_t)(cRects-1)*sizeof(RTRECT), VERR_INVALID_PARAMETER);
rc = vbglR3GRAlloc((VMMDevRequestHeader **)&pReq,
- sizeof(VMMDevVideoSetVisibleRegion) + (cRects - 1) * sizeof(RTRECT),
+ sizeof(VMMDevVideoSetVisibleRegion)
+ + cRects * sizeof(RTRECT)
+ - sizeof(RTRECT),
VMMDevReq_VideoSetVisibleRegion);
if (RT_SUCCESS(rc))
{
pReq->cRect = cRects;
- memcpy(&pReq->Rect, pRects, cRects * sizeof(RTRECT));
+ if (cRects)
+ memcpy(&pReq->Rect, pRects, cRects * sizeof(RTRECT));
+ /* This will fail harmlessly for cRect == 0 and older host code */
rc = vbglR3GRPerform(&pReq->header);
+ LogFunc(("Visible region request returned %Rrc, internal %Rrc.\n",
+ rc, pReq->header.rc));
if (RT_SUCCESS(rc))
rc = pReq->header.rc;
vbglR3GRFree(&pReq->header);
}
+ LogFunc(("Sending %u rectangles to the host: %Rrc\n", cRects, rc));
return rc;
}
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSharedFolders.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSharedFolders.cpp
index 11123a847..a481a8bcf 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSharedFolders.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSharedFolders.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibSharedFolders.cpp $ */
+/* $Id: VBoxGuestR3LibSharedFolders.cpp 35351 2010-12-27 17:04:17Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, shared folders.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibStat.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibStat.cpp
index 289181a1d..6609aa41d 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibStat.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibStat.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibStat.cpp $ */
+/* $Id: VBoxGuestR3LibStat.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Statistics.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibTime.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibTime.cpp
index c03b2c222..9275900c0 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibTime.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibTime.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibTime.cpp $ */
+/* $Id: VBoxGuestR3LibTime.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Time.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp
index 3298d85d8..8d1e989dd 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestR3LibVideo.cpp $ */
+/* $Id: VBoxGuestR3LibVideo.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Video.
*/
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VbglR0CanUsePhysPageList.cpp b/src/VBox/Additions/common/VBoxGuestLib/VbglR0CanUsePhysPageList.cpp
index c95198f0f..74a2c69d4 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VbglR0CanUsePhysPageList.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VbglR0CanUsePhysPageList.cpp
@@ -1,4 +1,4 @@
-/* $Revision: 60692 $ */
+/* $Revision: 28800 $ */
/** @file
* VBoxGuestLibR0 - Physical memory heap.
*/
diff --git a/src/VBox/Additions/common/VBoxService/Makefile.kmk b/src/VBox/Additions/common/VBoxService/Makefile.kmk
index ee88c6ba8..12eafcb77 100644
--- a/src/VBox/Additions/common/VBoxService/Makefile.kmk
+++ b/src/VBox/Additions/common/VBoxService/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37375 2011-06-08 10:51:26Z vboxsync $
## @file
# Sub-Makefile for the Cross Platform Guest Addition Services.
#
@@ -68,6 +68,7 @@ VBoxService_SOURCES = \
ifdef VBOX_WITH_GUEST_CONTROL
VBoxService_SOURCES += \
VBoxServiceControl.cpp \
+ VBoxServiceControlDir.cpp \
VBoxServiceControlExec.cpp \
VBoxServiceControlExecThread.cpp \
VBoxServicePipeBuf.cpp
diff --git a/src/VBox/Additions/common/VBoxService/VBoxService-win.cpp b/src/VBox/Additions/common/VBoxService/VBoxService-win.cpp
index 06bb3f706..6f0a51b53 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxService-win.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxService-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxService-win.cpp $ */
+/* $Id: VBoxService-win.cpp 36338 2011-03-22 10:57:01Z vboxsync $ */
/** @file
* VBoxService - Guest Additions Service Skeleton, Windows Specific Parts.
*/
@@ -308,8 +308,7 @@ static int vboxServiceWinStart(void)
0, 0, 0, 0, 0, 0, 0,
&pBuiltinUsersSID))
{
- /**@todo r=bird: rc = RTErrConvertFromWin32(GetLastError()); ?*/
- VBoxServiceError("AllocateAndInitializeSid: Error %u\n", GetLastError());
+ rc = RTErrConvertFromWin32(GetLastError());
}
else
{
@@ -344,9 +343,15 @@ static int vboxServiceWinStart(void)
VBoxServiceMainWait();
}
else
+ {
vboxServiceWinSetStatus(SERVICE_STOPPED, 0);
+#if 0 /** @todo r=bird: Enable this if SERVICE_CONTROL_STOP isn't triggered automatically */
+ VBoxServiceStopServices();
+#endif
+ }
}
- /**@todo r=bird: else vboxServiceWinSetStatus(SERVICE_STOPPED, 0); ? */
+ else
+ vboxServiceWinSetStatus(SERVICE_STOPPED, 0);
if (RT_FAILURE(rc))
VBoxServiceError("Service failed to start with rc=%Rrc!\n", rc);
@@ -367,7 +372,7 @@ static int vboxServiceWinStart(void)
RTEXITCODE VBoxServiceWinEnterCtrlDispatcher(void)
{
if (!StartServiceCtrlDispatcher(&g_aServiceTable[0]))
- return VBoxServiceError("StartServiceCtrlDispatcher: %u. Please start %s with option -f (foreground)!",
+ return VBoxServiceError("StartServiceCtrlDispatcher: %u. Please start %s with option -f (foreground)!\n",
GetLastError(), g_pszProgName);
return RTEXITCODE_SUCCESS;
}
@@ -384,7 +389,7 @@ static DWORD WINAPI vboxServiceWinCtrlHandler(DWORD dwControl, DWORD dwEventType
#ifdef TARGET_NT4
VBoxServiceVerbose(2, "Control handler: Control=%#x\n", dwControl);
#else
- VBoxServiceVerbose(2, "Control handler: Control=%#x EventType=%#x\n", dwControl, dwEventType);
+ VBoxServiceVerbose(2, "Control handler: Control=%#x, EventType=%#x\n", dwControl, dwEventType);
#endif
switch (dwControl)
@@ -401,6 +406,11 @@ static DWORD WINAPI vboxServiceWinCtrlHandler(DWORD dwControl, DWORD dwEventType
int rc2 = VBoxServiceStopServices();
if (RT_FAILURE(rc2))
rcRet = ERROR_GEN_FAILURE;
+ else
+ {
+ rc2 = VBoxServiceReportStatus(VBoxGuestFacilityStatus_Terminated);
+ AssertRC(rc2);
+ }
vboxServiceWinSetStatus(SERVICE_STOPPED, 0);
break;
diff --git a/src/VBox/Additions/common/VBoxService/VBoxService-win.rc b/src/VBox/Additions/common/VBoxService/VBoxService-win.rc
index 91db5f56c..28ff919ba 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxService-win.rc
+++ b/src/VBox/Additions/common/VBoxService/VBoxService-win.rc
@@ -1,4 +1,4 @@
-/* $Id: VBoxService-win.rc $ */
+/* $Id: VBoxService-win.rc 32394 2010-09-10 12:13:11Z vboxsync $ */
/** @file
* VBoxService - Resource file containing version info and icon.
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxService.cpp b/src/VBox/Additions/common/VBoxService/VBoxService.cpp
index d8880addd..cb7b43efb 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxService.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxService.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxService.cpp $ */
+/* $Id: VBoxService.cpp 36745 2011-04-20 10:08:26Z vboxsync $ */
/** @file
* VBoxService - Guest Additions Service Skeleton.
*/
/*
- * Copyright (C) 2007-2010 Oracle Corporation
+ * Copyright (C) 2007-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;
@@ -39,13 +39,13 @@
#include <iprt/asm.h>
#include <iprt/buildconfig.h>
#include <iprt/initterm.h>
+#include <iprt/message.h>
#include <iprt/path.h>
#include <iprt/semaphore.h>
#include <iprt/string.h>
#include <iprt/stream.h>
#include <iprt/thread.h>
-#include <VBox/VBoxGuestLib.h>
#include <VBox/log.h>
#include "VBoxServiceInternal.h"
@@ -76,6 +76,8 @@ static struct
PCVBOXSERVICE pDesc;
/** The worker thread. NIL_RTTHREAD if it's the main thread. */
RTTHREAD Thread;
+ /** Whether Pre-init was called. */
+ bool fPreInited;
/** Shutdown indicator. */
bool volatile fShutdown;
/** Indicator set by the service thread exiting. */
@@ -87,31 +89,31 @@ static struct
} g_aServices[] =
{
#ifdef VBOXSERVICE_CONTROL
- { &g_Control, NIL_RTTHREAD, false, false, false, true },
+ { &g_Control, NIL_RTTHREAD, false, false, false, false, true },
#endif
#ifdef VBOXSERVICE_TIMESYNC
- { &g_TimeSync, NIL_RTTHREAD, false, false, false, true },
+ { &g_TimeSync, NIL_RTTHREAD, false, false, false, false, true },
#endif
#ifdef VBOXSERVICE_CLIPBOARD
- { &g_Clipboard, NIL_RTTHREAD, false, false, false, true },
+ { &g_Clipboard, NIL_RTTHREAD, false, false, false, false, true },
#endif
#ifdef VBOXSERVICE_VMINFO
- { &g_VMInfo, NIL_RTTHREAD, false, false, false, true },
+ { &g_VMInfo, NIL_RTTHREAD, false, false, false, false, true },
#endif
#ifdef VBOXSERVICE_CPUHOTPLUG
- { &g_CpuHotPlug, NIL_RTTHREAD, false, false, false, true },
+ { &g_CpuHotPlug, NIL_RTTHREAD, false, false, false, false, true },
#endif
#ifdef VBOXSERVICE_MANAGEMENT
# ifdef VBOX_WITH_MEMBALLOON
- { &g_MemBalloon, NIL_RTTHREAD, false, false, false, true },
+ { &g_MemBalloon, NIL_RTTHREAD, false, false, false, false, true },
# endif
- { &g_VMStatistics, NIL_RTTHREAD, false, false, false, true },
+ { &g_VMStatistics, NIL_RTTHREAD, false, false, false, false, true },
#endif
#if defined(VBOX_WITH_PAGE_SHARING) && defined(RT_OS_WINDOWS)
- { &g_PageSharing, NIL_RTTHREAD, false, false, false, true },
+ { &g_PageSharing, NIL_RTTHREAD, false, false, false, false, true },
#endif
#ifdef VBOX_WITH_SHARED_FOLDERS
- { &g_AutoMount, NIL_RTTHREAD, false, false, false, true },
+ { &g_AutoMount, NIL_RTTHREAD, false, false, false, false, true },
#endif
};
@@ -121,7 +123,7 @@ static struct
*
* @returns 1.
*/
-static int VBoxServiceUsage(void)
+static int vboxServiceUsage(void)
{
RTPrintf("Usage:\n"
" %-12s [-f|--foreground] [-v|--verbose] [-i|--interval <seconds>]\n"
@@ -137,6 +139,7 @@ static int VBoxServiceUsage(void)
" -i | --interval The default interval.\n"
" -f | --foreground Don't daemonize the program. For debugging.\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"
);
#ifdef RT_OS_WINDOWS
@@ -228,6 +231,36 @@ void VBoxServiceVerbose(int iLevel, const char *pszFormat, ...)
/**
+ * Reports the current VBoxService 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.
+ */
+int VBoxServiceReportStatus(VBoxGuestFacilityStatus enmStatus)
+{
+ /*
+ * VBoxGuestFacilityStatus_Failed is sticky.
+ */
+ static VBoxGuestFacilityStatus s_enmLastStatus = VBoxGuestFacilityStatus_Inactive;
+ VBoxServiceVerbose(4, "Setting VBoxService status to %u\n", enmStatus);
+ if (s_enmLastStatus != VBoxGuestFacilityStatus_Failed)
+ {
+ int rc = VbglR3ReportAdditionsStatus(VBoxGuestFacilityType_VBoxService,
+ enmStatus, 0 /* Flags */);
+ if (RT_FAILURE(rc))
+ {
+ VBoxServiceError("Could not report VBoxService status (%u), rc=%Rrc\n", enmStatus, rc);
+ return rc;
+ }
+ s_enmLastStatus = enmStatus;
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
* Gets a 32-bit value argument.
*
* @returns 0 on success, non-zero exit code on error.
@@ -268,7 +301,7 @@ int VBoxServiceArgUInt32(int argc, char **argv, const char *psz, int *pi, uint32
* @param ThreadSelf My thread handle.
* @param pvUser The service index.
*/
-static DECLCALLBACK(int) VBoxServiceThread(RTTHREAD ThreadSelf, void *pvUser)
+static DECLCALLBACK(int) vboxServiceThread(RTTHREAD ThreadSelf, void *pvUser)
{
const unsigned i = (uintptr_t)pvUser;
@@ -289,15 +322,33 @@ static DECLCALLBACK(int) VBoxServiceThread(RTTHREAD ThreadSelf, void *pvUser)
/**
- * Check if at least one service should be started.
+ * Lazily calls the pfnPreInit method on each service.
+ *
+ * @returns VBox status code, error message displayed.
*/
-static bool VBoxServiceCheckStartedServices(void)
+static RTEXITCODE vboxServiceLazyPreInit(void)
{
for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
- if (g_aServices[j].fEnabled)
- return true;
+ if (!g_aServices[j].fPreInited)
+ {
+ int rc = g_aServices[j].pDesc->pfnPreInit();
+ if (RT_FAILURE(rc))
+ return VBoxServiceError("Service '%s' failed pre-init: %Rrc\n", g_aServices[j].pDesc->pszName, rc);
+ g_aServices[j].fPreInited = true;
+ }
+ return RTEXITCODE_SUCCESS;
+}
+
- return false;
+/**
+ * Count the number of enabled services.
+ */
+static unsigned vboxServiceCountEnabledServices(void)
+{
+ unsigned cEnabled = 0;
+ for (unsigned i = 0; i < RT_ELEMENTS(g_aServices); i++)
+ cEnabled += g_aServices[i].fEnabled;
+ return cEnabled;
}
@@ -310,6 +361,8 @@ int VBoxServiceStartServices(void)
{
int rc;
+ VBoxServiceReportStatus(VBoxGuestFacilityStatus_Init);
+
/*
* Initialize the services.
*/
@@ -324,6 +377,7 @@ int VBoxServiceStartServices(void)
{
VBoxServiceError("Service '%s' failed to initialize: %Rrc\n",
g_aServices[j].pDesc->pszName, rc);
+ VBoxServiceReportStatus(VBoxGuestFacilityStatus_Failed);
return rc;
}
g_aServices[j].fEnabled = false;
@@ -344,7 +398,7 @@ int VBoxServiceStartServices(void)
continue;
VBoxServiceVerbose(2, "Starting service '%s' ...\n", g_aServices[j].pDesc->pszName);
- rc = RTThreadCreate(&g_aServices[j].Thread, VBoxServiceThread, (void *)(uintptr_t)j, 0,
+ rc = RTThreadCreate(&g_aServices[j].Thread, vboxServiceThread, (void *)(uintptr_t)j, 0,
RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, g_aServices[j].pDesc->pszName);
if (RT_FAILURE(rc))
{
@@ -353,13 +407,12 @@ int VBoxServiceStartServices(void)
}
g_aServices[j].fStarted = true;
- /* Wait for the thread to initialize.
- *
- * @todo There is a race between waiting and checking
- * the fShutdown flag of a thread here and processing
- * the thread's actual worker loop. If the thread decides
- * to exit the loop before we skipped the fShutdown check
- * below the service will fail to start! */
+ /* Wait for the thread to initialize. */
+ /** @todo There is a race between waiting and checking
+ * the fShutdown flag of a thread here and processing
+ * the thread's actual worker loop. If the thread decides
+ * to exit the loop before we skipped the fShutdown check
+ * below the service will fail to start! */
RTThreadUserWait(g_aServices[j].Thread, 60 * 1000);
if (g_aServices[j].fShutdown)
{
@@ -371,7 +424,10 @@ int VBoxServiceStartServices(void)
if (RT_SUCCESS(rc))
VBoxServiceVerbose(1, "All services started.\n");
else
+ {
VBoxServiceError("An error occcurred while the services!\n");
+ VBoxServiceReportStatus(VBoxGuestFacilityStatus_Failed);
+ }
return rc;
}
@@ -384,7 +440,7 @@ int VBoxServiceStartServices(void)
*/
int VBoxServiceStopServices(void)
{
- int rc = VINF_SUCCESS;
+ VBoxServiceReportStatus(VBoxGuestFacilityStatus_Terminating);
/*
* Signal all the services.
@@ -405,6 +461,7 @@ int VBoxServiceStopServices(void)
/*
* Wait for all the service threads to complete.
*/
+ int rc = VINF_SUCCESS;
for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
{
if (!g_aServices[j].fEnabled) /* Only stop services which were started before. */
@@ -412,18 +469,22 @@ int VBoxServiceStopServices(void)
if (g_aServices[j].Thread != NIL_RTTHREAD)
{
VBoxServiceVerbose(2, "Waiting for service '%s' to stop ...\n", g_aServices[j].pDesc->pszName);
+ int rc2 = VINF_SUCCESS;
for (int i = 0; i < 30; i++) /* Wait 30 seconds in total */
{
- rc = RTThreadWait(g_aServices[j].Thread, 1000 /* Wait 1 second */, NULL);
- if (RT_SUCCESS(rc))
+ rc2 = RTThreadWait(g_aServices[j].Thread, 1000 /* Wait 1 second */, NULL);
+ if (RT_SUCCESS(rc2))
break;
#ifdef RT_OS_WINDOWS
/* Notify SCM that it takes a bit longer ... */
VBoxServiceWinSetStopPendingStatus(i + j*32);
#endif
}
- if (RT_FAILURE(rc))
- VBoxServiceError("Service '%s' failed to stop. (%Rrc)\n", g_aServices[j].pDesc->pszName, rc);
+ if (RT_FAILURE(rc2))
+ {
+ VBoxServiceError("Service '%s' failed to stop. (%Rrc)\n", g_aServices[j].pDesc->pszName, rc2);
+ rc = rc2;
+ }
}
VBoxServiceVerbose(3, "Terminating service '%s' (%d) ...\n", g_aServices[j].pDesc->pszName, j);
g_aServices[j].pDesc->pfnTerm();
@@ -434,16 +495,17 @@ int VBoxServiceStopServices(void)
* Wake up and tell the main() thread that we're shutting down (it's
* sleeping in VBoxServiceMainWait).
*/
+ ASMAtomicWriteBool(&g_fWindowsServiceShutdown, true);
if (g_hEvtWindowsService != NIL_RTSEMEVENT)
{
VBoxServiceVerbose(3, "Stopping the main thread...\n");
- ASMAtomicWriteBool(&g_fWindowsServiceShutdown, true);
- rc = RTSemEventSignal(g_hEvtWindowsService);
- AssertRC(rc);
+ int rc2 = RTSemEventSignal(g_hEvtWindowsService);
+ AssertRC(rc2);
}
#endif
- VBoxServiceVerbose(2, "Stopping services returned: rc=%Rrc\n", rc);
+ VBoxServiceVerbose(2, "Stopping services returning: %Rrc\n", rc);
+ VBoxServiceReportStatus(RT_SUCCESS(rc) ? VBoxGuestFacilityStatus_Paused : VBoxGuestFacilityStatus_Failed);
return rc;
}
@@ -455,13 +517,7 @@ void VBoxServiceMainWait(void)
{
int rc;
- /* Report the host that we're up and running! */
- rc = VbglR3ReportAdditionsStatus(VBoxGuestStatusFacility_VBoxService,
- VBoxGuestStatusCurrent_Active,
- 0 /* Flags */);
- if (RT_FAILURE(rc))
- VBoxServiceError("Could not report facility (%u) status %u, rc=%Rrc\n",
- VBoxGuestStatusFacility_VBoxService, VBoxGuestStatusCurrent_Active, rc);
+ VBoxServiceReportStatus(VBoxGuestFacilityStatus_Active);
#ifdef RT_OS_WINDOWS
/*
@@ -519,11 +575,11 @@ int main(int argc, char **argv)
/*
* Init globals and such.
*/
- RTR3Init();
-
+ int rc = RTR3Init();
+ if (RT_FAILURE(rc))
+ return RTMsgInitFailure(rc);
g_pszProgName = RTPathFilename(argv[0]);
-
#ifdef VBOXSERVICE_TOOLBOX
/*
* Run toolbox code before all other stuff since these things are simpler
@@ -542,9 +598,14 @@ int main(int argc, char **argv)
* do to some initial stuff with it.
*/
VBoxServiceVerbose(2, "Calling VbgR3Init()\n");
- int rc = VbglR3Init();
+ rc = VbglR3Init();
if (RT_FAILURE(rc))
+ {
+ if (rc == VERR_ACCESS_DENIED)
+ return VBoxServiceError("Insufficient privileges to start %s! Please start with Administrator/root privileges!\n",
+ g_pszProgName);
return VBoxServiceError("VbglR3Init failed with rc=%Rrc.\n", rc);
+ }
#ifdef RT_OS_WINDOWS
/*
@@ -557,40 +618,9 @@ int main(int argc, char **argv)
#endif
/*
- * Do pre-init of services.
- */
- for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
- {
- rc = g_aServices[j].pDesc->pfnPreInit();
- if (RT_FAILURE(rc))
- return VBoxServiceError("Service '%s' failed pre-init: %Rrc\n", g_aServices[j].pDesc->pszName, rc);
- }
-#ifdef RT_OS_WINDOWS
- /*
- * Make sure only one instance of VBoxService runs at a time. Create a
- * global mutex for that. Do not use a global namespace ("Global\\") for
- * mutex name here, will blow up NT4 compatibility!
- */
- /** @todo r=bird: Use Global\\ prefix or this serves no purpose on terminal servers. */
- HANDLE hMutexAppRunning = CreateMutex(NULL, FALSE, VBOXSERVICE_NAME);
- if ( hMutexAppRunning != NULL
- && GetLastError() == ERROR_ALREADY_EXISTS)
- {
- VBoxServiceError("%s is already running! Terminating.", g_pszProgName);
-
- /* Close the mutex for this application instance. */
- CloseHandle(hMutexAppRunning);
- hMutexAppRunning = NULL;
-
- /** @todo r=bird: How does this cause us to terminate? Btw. Why do
- * we do this before parsing parameters? 'VBoxService --help'
- * and 'VBoxService --version' won't work now when the service
- * is running... */
- }
-#endif
-
- /*
* Parse the arguments.
+ *
+ * Note! This code predates RTGetOpt, thus the manual parsing.
*/
bool fDaemonize = true;
bool fDaemonized = false;
@@ -612,6 +642,8 @@ int main(int argc, char **argv)
psz = "f";
else if (MATCHES("verbose"))
psz = "v";
+ else if (MATCHES("version"))
+ psz = "V";
else if (MATCHES("help"))
psz = "h";
else if (MATCHES("interval"))
@@ -642,6 +674,11 @@ int main(int argc, char **argv)
g_aServices[j].fEnabled = false;
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);
@@ -651,6 +688,7 @@ int main(int argc, char **argv)
if (rc != -1)
return rc;
}
+ }
if (!fFound)
return VBoxServiceSyntax("Unknown option '%s'\n", argv[i]);
continue;
@@ -679,9 +717,13 @@ int main(int argc, char **argv)
g_cVerbosity++;
break;
+ case 'V':
+ RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr());
+ return RTEXITCODE_SUCCESS;
+
case 'h':
case '?':
- return VBoxServiceUsage();
+ return vboxServiceUsage();
#ifdef RT_OS_WINDOWS
case 'r':
@@ -693,11 +735,15 @@ int main(int argc, char **argv)
default:
{
+ rcExit = vboxServiceLazyPreInit();
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
bool fFound = false;
for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
{
rc = g_aServices[j].pDesc->pfnOption(&psz, argc, argv, &i);
- fFound = rc == 0;
+ fFound = rc == VINF_SUCCESS;
if (fFound)
break;
if (rc != -1)
@@ -710,11 +756,52 @@ int main(int argc, char **argv)
}
} while (psz && *++psz);
}
+
+ /* Check that at least one service is enabled. */
+ if (vboxServiceCountEnabledServices() == 0)
+ return VBoxServiceSyntax("At least one service must be enabled.\n");
+
+ /* Call pre-init if we didn't do it already. */
+ rcExit = vboxServiceLazyPreInit();
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+#ifdef RT_OS_WINDOWS
/*
- * Check that at least one service is enabled.
+ * Make sure only one instance of VBoxService runs at a time. Create a
+ * global mutex for that.
+ *
+ * Note! The \\Global\ namespace was introduced with Win2K, thus the
+ * version check.
+ * Note! If the mutex exists CreateMutex will open it and set last error to
+ * ERROR_ALREADY_EXISTS.
*/
- if (!VBoxServiceCheckStartedServices())
- return VBoxServiceSyntax("At least one service must be enabled.\n");
+ OSVERSIONINFOEX OSInfoEx;
+ RT_ZERO(OSInfoEx);
+ OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+
+ SetLastError(NO_ERROR);
+ HANDLE hMutexAppRunning;
+ if ( GetVersionEx((LPOSVERSIONINFO)&OSInfoEx)
+ && OSInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT
+ && OSInfoEx.dwMajorVersion >= 5 /* NT 5.0 a.k.a W2K */)
+ hMutexAppRunning = CreateMutex(NULL, FALSE, "Global\\" VBOXSERVICE_NAME);
+ else
+ hMutexAppRunning = CreateMutex(NULL, FALSE, VBOXSERVICE_NAME);
+ if (hMutexAppRunning == NULL)
+ {
+ 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 */
VBoxServiceVerbose(0, "%s r%s started. Verbose level = %d\n",
RTBldCfgVersion(), RTBldCfgRevisionStr(), g_cVerbosity);
@@ -753,16 +840,13 @@ int main(int argc, char **argv)
VBoxServiceMainWait();
VBoxServiceStopServices();
}
+ VBoxServiceReportStatus(VBoxGuestFacilityStatus_Terminated);
#ifdef RT_OS_WINDOWS
/*
- * Release instance mutex if we got it.
+ * Cleanup mutex.
*/
- if (hMutexAppRunning != NULL)
- {
- ::CloseHandle(hMutexAppRunning);
- hMutexAppRunning = NULL;
- }
+ CloseHandle(hMutexAppRunning);
#endif
VBoxServiceVerbose(0, "Ended.\n");
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp
index 70f6127ba..5f8db00a1 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxServiceAutoMount.cpp $ */
+/* $Id: VBoxServiceAutoMount.cpp 37832 2011-07-08 10:13:18Z vboxsync $ */
/** @file
* VBoxService - Auto-mounting for Shared Folders.
*/
/*
- * 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;
@@ -260,15 +260,19 @@ static int VBoxServiceAutoMountSharedFolder(const char *pszShareName, const char
if (RT_SUCCESS(rc))
{
#ifdef RT_OS_SOLARIS
- int flags = 0; /* No flags used yet. */
+ char achOptBuf[MAX_MNTOPT_STR] = { '\0', };
+ int flags = 0;
+ if (pOpts->ronly)
+ flags |= MS_RDONLY;
+ RTStrPrintf(achOptBuf, sizeof(achOptBuf), "uid=%d,gid=%d", pOpts->uid, pOpts->gid);
int r = mount(pszShareName,
pszMountPoint,
- flags,
- "vboxsf",
+ flags | MS_OPTIONSTR,
+ "vboxfs",
NULL, /* char *dataptr */
0, /* int datalen */
- NULL, /* char *optptr */
- 0); /* int optlen */
+ achOptBuf,
+ sizeof(achOptBuf));
if (r == 0)
{
VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp
index 8b609d432..800427066 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceBalloon.cpp $ */
+/* $Id: VBoxServiceBalloon.cpp 32813 2010-09-29 11:50:19Z vboxsync $ */
/** @file
* VBoxService - Memory Ballooning.
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceClipboard-os2.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceClipboard-os2.cpp
index ea32683cf..978cdd2d0 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceClipboard-os2.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceClipboard-os2.cpp
@@ -1,4 +1,4 @@
-/** $Id: VBoxServiceClipboard-os2.cpp $ */
+/** $Id: VBoxServiceClipboard-os2.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxService - Guest Additions Clipboard Service, OS/2.
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
index 63943e688..b2f0d40be 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceControl.cpp $ */
+/* $Id: VBoxServiceControl.cpp 37375 2011-06-08 10:51:26Z vboxsync $ */
/** @file
* VBoxServiceControl - Host-driven Guest Control.
*/
@@ -129,7 +129,7 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown)
uint32_t uMsg;
uint32_t uNumParms;
VBoxServiceVerbose(3, "Control: Waiting for host msg ...\n");
- rc = VbglR3GuestCtrlGetHostMsg(g_GuestControlSvcClientID, &uMsg, &uNumParms);
+ rc = VbglR3GuestCtrlWaitForHostMsg(g_GuestControlSvcClientID, &uMsg, &uNumParms);
if (RT_FAILURE(rc))
{
if (rc == VERR_TOO_MUCH_DATA)
@@ -163,6 +163,18 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown)
rc = VBoxServiceControlExecHandleCmdGetOutput(g_GuestControlSvcClientID, uNumParms);
break;
+ case HOST_DIR_CLOSE:
+ rc = VBoxServiceGCtrlDirClose(g_GuestControlSvcClientID, uNumParms);
+ break;
+
+ case HOST_DIR_OPEN:
+ rc = VBoxServiceGCtrlDirOpen(g_GuestControlSvcClientID, uNumParms);
+ break;
+
+ case HOST_DIR_READ:
+ rc = VBoxServiceGCtrlDirRead(g_GuestControlSvcClientID, uNumParms);
+ break;
+
default:
VBoxServiceVerbose(3, "Control: Unsupported message from host! Msg=%u\n", uMsg);
/* Don't terminate here; just wait for the next message. */
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControlDir.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControlDir.cpp
new file mode 100644
index 000000000..ae87d5502
--- /dev/null
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControlDir.cpp
@@ -0,0 +1,90 @@
+/* $Id: VBoxServiceControlDir.cpp 37375 2011-06-08 10:51:26Z vboxsync $ */
+/** @file
+ * VBoxServiceControlDir - Utility functions for guest directory handling.
+ */
+
+/*
+ * 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 <VBox/VBoxGuestLib.h>
+#include <VBox/HostServices/GuestControlSvc.h>
+
+#include "VBoxServiceInternal.h"
+#include "VBoxServiceUtils.h"
+
+using namespace guestControl;
+
+int VBoxServiceGCtrlDirClose(uint32_t u32ClientId, uint32_t uNumParms)
+{
+ uint32_t uContextID;
+ uint32_t uHandle;
+
+ int rc = VbglR3GuestCtrlGetCmdDirClose(u32ClientId, uNumParms,
+ &uContextID, &uHandle);
+ if (RT_SUCCESS(rc))
+ {
+
+ }
+ else
+ VBoxServiceError(" VBoxServiceGCtrlDir: Failed to retrieve close command! Error: %Rrc\n", rc);
+ VBoxServiceVerbose(3, " VBoxServiceGCtrlDir: VBoxServiceGCtrlDirClose returned with %Rrc\n", rc);
+ return rc;
+}
+
+int VBoxServiceGCtrlDirOpen(uint32_t u32ClientId, uint32_t uNumParms)
+{
+ uint32_t uContextID;
+ char szDir[_1K];
+ char szFilter[_1K];
+ uint32_t uFlags;
+ char szUser[128];
+ char szPassword[128];
+
+ int rc = VbglR3GuestCtrlGetCmdDirOpen(u32ClientId, uNumParms,
+ &uContextID,
+ szDir, sizeof(szDir),
+ szFilter, sizeof(szFilter),
+ &uFlags,
+ szUser, sizeof(szUser),
+ szPassword, sizeof(szPassword));
+ if (RT_SUCCESS(rc))
+ {
+
+ }
+ else
+ VBoxServiceError(" VBoxServiceGCtrlDir: Failed to retrieve open command! Error: %Rrc\n", rc);
+ VBoxServiceVerbose(3, " VBoxServiceGCtrlDir: VBoxServiceGCtrlDirOpen returned with %Rrc\n", rc);
+ return rc;
+}
+
+int VBoxServiceGCtrlDirRead(uint32_t u32ClientId, uint32_t uNumParms)
+{
+ uint32_t uContextID;
+ uint32_t uHandle;
+
+ int rc = VbglR3GuestCtrlGetCmdDirRead(u32ClientId, uNumParms,
+ &uContextID, &uHandle);
+ if (RT_SUCCESS(rc))
+ {
+
+ }
+ else
+ VBoxServiceError(" VBoxServiceGCtrlDir: Failed to retrieve read command! Error: %Rrc\n", rc);
+ VBoxServiceVerbose(3, " VBoxServiceGCtrlDir: VBoxServiceGCtrlDirRead returned with %Rrc\n", rc);
+ return rc;
+}
+
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
index 0e5155ef5..8be9dafe0 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceControlExec.cpp $ */
+/* $Id: VBoxServiceControlExec.cpp 37816 2011-07-07 11:52:16Z vboxsync $ */
/** @file
* VBoxServiceControlExec - Utility functions for process execution.
*/
@@ -190,24 +190,24 @@ static int VBoxServiceControlExecProcHandleStdInWritableEvent(RTPOLLSET hPollSe
/**
- * Handle pending output data or error on standard out, standard error or the
- * test pipe.
+ * Handle pending output data/error on standard out or standard error.
*
- * @returns IPRT status code from client send.
- * @param pThread The thread specific data.
+ * @return IPRT status code.
* @param hPollSet The polling set.
* @param fPollEvt The event mask returned by RTPollNoResume.
- * @param phPipeR The pipe handle.
- * @param pu32Crc The current CRC-32 of the stream. (In/Out)
- * @param uHandleId The handle ID.
- *
- * @todo Put the last 4 parameters into a struct!
+ * @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 pStdOutBuf)
+ uint32_t uHandleId, PVBOXSERVICECTRLEXECPIPEBUF pBuf)
{
+ AssertPtrReturn(phPipeR, VERR_INVALID_POINTER);
+ AssertPtrReturn(pBuf, VERR_INVALID_POINTER);
+
#ifdef DEBUG
- VBoxServiceVerbose(4, "ControlExec: HandleOutputEvent: fPollEvt=%#x\n", fPollEvt);
+ VBoxServiceVerbose(4, "ControlExec: HandleOutputEvent: fPollEvt=%#x, uHandle=%u\n",
+ fPollEvt, uHandleId);
#endif
/*
@@ -221,7 +221,7 @@ static int VBoxServiceControlExecProcHandleOutputEvent(RTPOLLSET hPollSet, uint3
if (RT_SUCCESS(rc2) && cbRead)
{
uint32_t cbWritten;
- rc = VBoxServicePipeBufWriteToBuf(pStdOutBuf, abBuf,
+ rc = VBoxServicePipeBufWriteToBuf(pBuf, abBuf,
cbRead, false /* Pending close */, &cbWritten);
if (RT_SUCCESS(rc))
{
@@ -375,7 +375,7 @@ static int VBoxServiceControlExecProcLoop(PVBOXSERVICECTRLTHREAD pThread,
case VBOXSERVICECTRLPIPEID_STDERR:
rc = VBoxServiceControlExecProcHandleOutputEvent(hPollSet, fPollEvt, phStdErrR,
- VBOXSERVICECTRLPIPEID_STDERR, &pData->stdOut);
+ VBOXSERVICECTRLPIPEID_STDERR, &pData->stdErr);
break;
default:
@@ -579,18 +579,22 @@ static int VBoxServiceControlExecProcLoop(PVBOXSERVICECTRLTHREAD pThread,
*/
if (g_cVerbosity >= 5)
{
+ VBoxServiceVerbose(5, "StdOut of process (PID %u):\n", pData->uPID);
+
uint8_t szBuf[_64K];
uint32_t cbOffset = 0;
uint32_t cbRead, cbLeft;
- while (RT_SUCCESS( VBoxServicePipeBufPeek(&pData->stdOut, szBuf, sizeof(szBuf),
+ while ( RT_SUCCESS(VBoxServicePipeBufPeek(&pData->stdOut, szBuf, sizeof(szBuf),
cbOffset, &cbRead, &cbLeft))
- && cbRead)
+ && cbRead)
{
- VBoxServiceVerbose(5, "[%u]: %s\n", pData->uPID, szBuf);
+ RTStrmWrite(g_pStdOut, szBuf, cbRead);
cbOffset += cbRead;
if (!cbLeft)
break;
}
+
+ VBoxServiceVerbose(5, "\n");
}
}
else
@@ -1350,7 +1354,7 @@ int VBoxServiceControlExecHandleCmdGetOutput(uint32_t u32ClientId, uint32_t uNum
* regardless whether we got data or not! Otherwise the progress object
* on the host never will get completed! */
/* cbRead now contains actual size. */
- rc = VbglR3GuestCtrlExecSendOut(u32ClientId, uContextID, uPID, uHandleID, 0 /* Flags */,
+ rc = VbglR3GuestCtrlExecSendOut(u32ClientId, uContextID, uPID, uHandleID, uFlags,
pBuf, cbRead);
}
RTMemFree(pBuf);
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp
index fc5879b8e..54b967e07 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceControlExecThread.cpp $ */
+/* $Id: VBoxServiceControlExecThread.cpp 36887 2011-04-29 10:04:52Z vboxsync $ */
/** @file
* VBoxServiceControlExecThread - Thread for an executed guest process.
*/
@@ -27,6 +27,8 @@
#include <iprt/semaphore.h>
#include <iprt/string.h>
+#include <VBox/HostServices/GuestControlSvc.h>
+
#include "VBoxServicePipeBuf.h"
#include "VBoxServiceControlExecThread.h"
@@ -284,11 +286,11 @@ int VBoxServiceControlExecThreadGetOutput(uint32_t uPID, uint32_t uHandleId, uin
PVBOXSERVICECTRLEXECPIPEBUF pPipeBuf;
switch (uHandleId)
{
- case 2: /* StdErr */
+ case OUTPUT_HANDLE_ID_STDERR: /* StdErr */
pPipeBuf = &pData->stdErr;
break;
- case 0: /* StdOut */
+ case OUTPUT_HANDLE_ID_STDOUT: /* StdOut */
default:
pPipeBuf = &pData->stdOut;
break;
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h
index 5caf644a0..7fb2ed92e 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceControlExecThread.h $ */
+/* $Id: VBoxServiceControlExecThread.h 36548 2011-04-05 09:27:33Z vboxsync $ */
/** @file
* VBoxServiceControlExecThread - Thread for an executed guest process.
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp
index 600ef09b0..25616a759 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceCpuHotPlug.cpp $ */
+/* $Id: VBoxServiceCpuHotPlug.cpp 33468 2010-10-26 12:49:59Z vboxsync $ */
/** @file
* VBoxService - Guest Additions CPU Hot Plugging Service.
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h b/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
index 020651b98..0c7aeb5cd 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceInternal.h $ */
+/* $Id: VBoxServiceInternal.h 37375 2011-06-08 10:51:26Z vboxsync $ */
/** @file
* VBoxService - Guest Additions Services.
*/
@@ -27,6 +27,8 @@
#include <iprt/list.h>
#include <iprt/critsect.h>
+#include <VBox/VBoxGuestLib.h>
+
/**
* A service descriptor.
*/
@@ -91,7 +93,8 @@ typedef VBOXSERVICE *PVBOXSERVICE;
/** Pointer to a const VBOXSERVICE. */
typedef VBOXSERVICE const *PCVBOXSERVICE;
-/** The service name (needed for mutex creation on Windows). */
+/** The service name.
+ * @note Used on windows to name the service as well as the global mutex. */
#define VBOXSERVICE_NAME "VBoxService"
#ifdef RT_OS_WINDOWS
@@ -276,6 +279,7 @@ extern int VBoxServiceArgUInt32(int argc, char **argv, const char *psz,
extern int VBoxServiceStartServices(void);
extern int VBoxServiceStopServices(void);
extern void VBoxServiceMainWait(void);
+extern int VBoxServiceReportStatus(VBoxGuestFacilityStatus enmStatus);
#ifdef RT_OS_WINDOWS
extern RTEXITCODE VBoxServiceWinInstall(void);
extern RTEXITCODE VBoxServiceWinUninstall(void);
@@ -295,6 +299,10 @@ extern int VBoxServiceWinGetComponentVersions(uint32_t uiClientID);
#endif /* RT_OS_WINDOWS */
#ifdef VBOX_WITH_GUEST_CONTROL
+extern int VBoxServiceGCtrlDirClose(uint32_t u32ClientId, uint32_t uNumParms);
+extern int VBoxServiceGCtrlDirOpen(uint32_t u32ClientId, uint32_t uNumParms);
+extern int VBoxServiceGCtrlDirRead(uint32_t u32ClientId, uint32_t uNumParms);
+
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);
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp b/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp
index 23d2a6069..b9bc5414c 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServicePageSharing.cpp $ */
+/* $Id: VBoxServicePageSharing.cpp 35036 2010-12-13 16:56:27Z vboxsync $ */
/** @file
* VBoxService - Guest page sharing.
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.cpp b/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.cpp
index 8f652e8bc..98c1ff0a5 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServicePipeBuf.cpp $ */
+/* $Id: VBoxServicePipeBuf.cpp 36880 2011-04-29 09:16:41Z vboxsync $ */
/** @file
* VBoxServicePipeBuf - Pipe buffering.
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.h b/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.h
index 89e2c4317..5fbb5ee21 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.h
+++ b/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxServicePipeBuf.h $ */
+/* $Id: VBoxServicePipeBuf.h 36744 2011-04-20 10:05:09Z vboxsync $ */
/** @file
* VBoxServicePipeBuf - Pipe buffering.
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServicePropCache.cpp b/src/VBox/Additions/common/VBoxService/VBoxServicePropCache.cpp
index a06aabe86..c0d378f2f 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServicePropCache.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServicePropCache.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServicePropCache.cpp $ */
+/* $Id: VBoxServicePropCache.cpp 36249 2011-03-10 12:18:20Z vboxsync $ */
/** @file
* VBoxServicePropCache - Guest property cache.
*/
@@ -112,6 +112,8 @@ int vboxServicePropCacheWritePropF(uint32_t u32ClientId, const char *pszName, ui
/* Host does not support the "TRANSRESET" flag, so only
* use the "TRANSIENT" flag -- better than nothing :-). */
rc = VbglR3GuestPropWrite(u32ClientId, pszName, pszValue, "TRANSIENT");
+ /** @todo r=bird: Remember that the host doesn't support
+ * this. */
}
}
else
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceResource-win.h b/src/VBox/Additions/common/VBoxService/VBoxServiceResource-win.h
index cf932cbe2..d484a17ec 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceResource-win.h
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceResource-win.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceResource-win.h $ */
+/* $Id: VBoxServiceResource-win.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxService - Guest Additions Service, resource IDs.
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp
index 6f51be217..b81330e69 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceStats.cpp $ */
+/* $Id: VBoxServiceStats.cpp 32813 2010-09-29 11:50:19Z vboxsync $ */
/** @file
* VBoxStats - Guest statistics notification
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp
index 07f33206e..70cb0781f 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceTimeSync.cpp $ */
+/* $Id: VBoxServiceTimeSync.cpp 37608 2011-06-23 11:47:33Z vboxsync $ */
/** @file
* VBoxService - Guest Additions TimeSync Service.
*/
@@ -164,7 +164,13 @@ static DECLCALLBACK(int) VBoxServiceTimeSyncPreInit(void)
int rc = VbglR3GuestPropConnect(&uGuestPropSvcClientID);
if (RT_FAILURE(rc))
{
- VBoxServiceError("VBoxServiceTimeSyncPreInit: Failed to connect to the guest property service! Error: %Rrc\n", rc);
+ if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */
+ {
+ VBoxServiceVerbose(0, "VMInfo: Guest property service is not available, skipping\n");
+ rc = VINF_SUCCESS;
+ }
+ else
+ VBoxServiceError("Failed to connect to the guest property service! Error: %Rrc\n", rc);
}
else
{
@@ -666,8 +672,8 @@ VBOXSERVICE g_TimeSync =
/* pszUsage. */
" [--timesync-interval <ms>] [--timesync-min-adjust <ms>]\n"
" [--timesync-latency-factor <x>] [--timesync-max-latency <ms>]\n"
- " [--timesync-set-threshold <ms>] [--timesync-set-start]"
- " [--timesync-set-restore 0|1]\n"
+ " [--timesync-set-threshold <ms>] [--timesync-set-start]\n"
+ " [--timesync-set-on-restore 0|1]"
,
/* pszOptions. */
" --timesync-interval Specifies the interval at which to synchronize the\n"
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp
index 8584eef46..3bc0e1e3f 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxServiceToolBox.cpp $ */
+/* $Id: VBoxServiceToolBox.cpp 38015 2011-07-18 12:49:31Z vboxsync $ */
/** @file
- * VBoxServiceToolBox - Internal (BusyBox-like) toolbox.
+ * VBoxServiceToolbox - Internal (BusyBox-like) toolbox.
*/
/*
- * Copyright (C) 2010 Oracle Corporation
+ * 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;
@@ -34,7 +34,7 @@
#include <iprt/stream.h>
#ifndef RT_OS_WINDOWS
-#include <sys/stat.h>
+# include <sys/stat.h> /* need umask */
#endif
#include <VBox/VBoxGuestLib.h>
@@ -43,7 +43,52 @@
#include "VBoxServiceUtils.h"
-#define CAT_OPT_NO_CONTENT_INDEXED 1000
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+
+/** Options indices for "vbox_cat". */
+typedef enum VBOXSERVICETOOLBOXCATOPT
+{
+ VBOXSERVICETOOLBOXCATOPT_NO_CONTENT_INDEXED = 1000
+} VBOXSERVICETOOLBOXCATOPT;
+
+/** Options indices for "vbox_ls". */
+typedef enum VBOXSERVICETOOLBOXLSOPT
+{
+ VBOXSERVICETOOLBOXLSOPT_MACHINE_READABLE = 1000,
+ VBOXSERVICETOOLBOXLSOPT_VERBOSE
+} VBOXSERVICETOOLBOXLSOPT;
+
+/** Options indices for "vbox_stat". */
+typedef enum VBOXSERVICETOOLBOXSTATOPT
+{
+ VBOXSERVICETOOLBOXSTATOPT_MACHINE_READABLE = 1000
+} VBOXSERVICETOOLBOXSTATOPT;
+
+
+/** Flags for "vbox_ls". */
+typedef enum VBOXSERVICETOOLBOXLSFLAG
+{
+ VBOXSERVICETOOLBOXLSFLAG_NONE = 0x0,
+ VBOXSERVICETOOLBOXLSFLAG_RECURSIVE = 0x1,
+ VBOXSERVICETOOLBOXLSFLAG_SYMLINKS = 0x2
+} VBOXSERVICETOOLBOXLSFLAG;
+
+/** Flags for fs object output. */
+typedef enum VBOXSERVICETOOLBOXOUTPUTFLAG
+{
+ VBOXSERVICETOOLBOXOUTPUTFLAG_NONE = 0x0,
+ VBOXSERVICETOOLBOXOUTPUTFLAG_LONG = 0x1,
+ VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE = 0x2
+} VBOXSERVICETOOLBOXOUTPUTFLAG;
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/** Pointer to a handler function. */
+typedef RTEXITCODE (*PFNHANDLER)(int , char **);
/**
* An file/directory entry. Used to cache
@@ -57,6 +102,14 @@ typedef struct VBOXSERVICETOOLBOXPATHENTRY
char *pszName;
} VBOXSERVICETOOLBOXPATHENTRY, *PVBOXSERVICETOOLBOXPATHENTRY;
+typedef struct VBOXSERVICETOOLBOXDIRENTRY
+{
+ /** Our node. */
+ RTLISTNODE Node;
+ /** The actual entry. */
+ RTDIRENTRYEX dirEntry;
+} VBOXSERVICETOOLBOXDIRENTRY, *PVBOXSERVICETOOLBOXDIRENTRY;
+
/**
* Displays a help text to stdout.
@@ -67,7 +120,14 @@ static void VBoxServiceToolboxShowUsage(void)
"cat [FILE] - Concatenate FILE(s), or standard input, to standard output.\n"
"\n"
/** @todo Document options! */
- "mkdir [OPTION] DIRECTORY... - Create the DIRECTORY(ies), if they do not already exist.\n"
+ "ls [OPTION]... FILE... - List information about the FILEs (the current directory by default).\n"
+ "\n"
+ /** @todo Document options! */
+ "mkdir [OPTION]... DIRECTORY... - Create the DIRECTORY(ies), if they do not already exist.\n"
+ "\n"
+ /** @todo Document options! */
+ "stat [OPTION]... FILE... - Display file or file system status.\n"
+ "\n"
/** @todo Document options! */
"\n");
}
@@ -83,22 +143,28 @@ static void VBoxServiceToolboxShowVersion(void)
/**
- * Displays an error message because of syntax error.
+ * Prints a parseable stream header which contains the actual tool
+ * which was called/used along with its stream version.
*
- * @return VERR_INVALID_PARAMETER
- * @param pszFormat
+ * @param pszToolName Name of the tool being used, e.g. "vbt_ls".
+ * @param uVersion Stream version name. Handy for distinguishing
+ * different stream versions later.
*/
-static int VBoxServiceToolboxErrorSyntax(const char *pszFormat, ...)
+static void VBoxServiceToolboxPrintStrmHeader(const char *pszToolName, uint32_t uVersion)
{
- va_list args;
-
- va_start(args, pszFormat);
- RTPrintf("\n"
- "Syntax error: %N\n", pszFormat, &args);
- va_end(args);
- return VERR_INVALID_PARAMETER;
+ AssertPtrReturnVoid(pszToolName);
+ RTPrintf("hdr_id=%s%chdr_ver=%u%c", pszToolName, 0, uVersion, 0);
}
+/**
+ * Prints a standardized termination sequence indicating that the
+ * parseable stream just ended.
+ *
+ */
+static void VBoxServiceToolboxPrintStrmTermination()
+{
+ RTPrintf("%c%c%c%c", 0, 0, 0, 0);
+}
/**
* Destroys a path buffer list.
@@ -168,14 +234,14 @@ static int VBoxServiceToolboxCatOutput(RTFILE hInput, RTFILE hOutput)
{
rc = RTFileFromNative(&hInput, RTFILE_NATIVE_STDIN);
if (RT_FAILURE(rc))
- RTMsgError("cat: Could not translate input file to native handle, rc=%Rrc\n", rc);
+ RTMsgError("Could not translate input file to native handle, rc=%Rrc\n", rc);
}
if (hOutput == NIL_RTFILE)
{
rc = RTFileFromNative(&hOutput, RTFILE_NATIVE_STDOUT);
if (RT_FAILURE(rc))
- RTMsgError("cat: Could not translate output file to native handle, rc=%Rrc\n", rc);
+ RTMsgError("Could not translate output file to native handle, rc=%Rrc\n", rc);
}
if (RT_SUCCESS(rc))
@@ -195,16 +261,619 @@ static int VBoxServiceToolboxCatOutput(RTFILE hInput, RTFILE hOutput)
if (rc == VERR_BROKEN_PIPE)
rc = VINF_SUCCESS;
else if (RT_FAILURE(rc))
- RTMsgError("cat: Error while reading input, rc=%Rrc\n", rc);
+ RTMsgError("Error while reading input, rc=%Rrc\n", rc);
+ break;
+ }
+ }
+ }
+ return rc;
+}
+
+
+/**
+ * Main function for tool "vbox_cat".
+ *
+ * @return RTEXITCODE.
+ * @param argc Number of arguments.
+ * @param argv Pointer to argument array.
+ */
+static RTEXITCODE VBoxServiceToolboxCat(int argc, char **argv)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ /* Sorted by short ops. */
+ { "--show-all", 'a', RTGETOPT_REQ_NOTHING },
+ { "--number-nonblank", 'b', RTGETOPT_REQ_NOTHING},
+ { NULL, 'e', RTGETOPT_REQ_NOTHING},
+ { NULL, 'E', RTGETOPT_REQ_NOTHING},
+ { "--flags", 'f', RTGETOPT_REQ_STRING},
+ { "--no-content-indexed", VBOXSERVICETOOLBOXCATOPT_NO_CONTENT_INDEXED, RTGETOPT_REQ_NOTHING},
+ { "--number", 'n', RTGETOPT_REQ_NOTHING},
+ { "--output", 'o', RTGETOPT_REQ_STRING},
+ { "--squeeze-blank", 's', RTGETOPT_REQ_NOTHING},
+ { NULL, 't', RTGETOPT_REQ_NOTHING},
+ { "--show-tabs", 'T', RTGETOPT_REQ_NOTHING},
+ { NULL, 'u', RTGETOPT_REQ_NOTHING},
+ { "--show-noneprinting", 'v', RTGETOPT_REQ_NOTHING}
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+
+ RTGetOptInit(&GetState, argc, argv,
+ s_aOptions, RT_ELEMENTS(s_aOptions),
+ 1 /*iFirst*/, 0 /*fFlags*/);
+
+ int rc = VINF_SUCCESS;
+ bool fUsageOK = true;
+
+ char szOutput[RTPATH_MAX] = { 0 };
+ RTFILE hOutput = NIL_RTFILE;
+ uint32_t fFlags = RTFILE_O_CREATE_REPLACE /* Output file flags. */
+ | RTFILE_O_WRITE
+ | RTFILE_O_DENY_WRITE;
+
+ /* Init directory list. */
+ RTLISTNODE inputList;
+ RTListInit(&inputList);
+
+ while ( (ch = RTGetOpt(&GetState, &ValueUnion))
+ && RT_SUCCESS(rc))
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ case 'a':
+ case 'b':
+ case 'e':
+ case 'E':
+ case 'n':
+ case 's':
+ case 't':
+ case 'T':
+ case 'v':
+ RTMsgError("Sorry, option '%s' is not implemented yet!\n",
+ ValueUnion.pDef->pszLong);
+ rc = VERR_INVALID_PARAMETER;
+ break;
+
+ case 'h':
+ VBoxServiceToolboxShowUsage();
+ return RTEXITCODE_SUCCESS;
+
+ case 'o':
+ if (!RTStrPrintf(szOutput, sizeof(szOutput), ValueUnion.psz))
+ rc = VERR_NO_MEMORY;
+ break;
+
+ case 'u':
+ /* Ignored. */
+ break;
+
+ case 'V':
+ VBoxServiceToolboxShowVersion();
+ return RTEXITCODE_SUCCESS;
+
+ case VBOXSERVICETOOLBOXCATOPT_NO_CONTENT_INDEXED:
+ fFlags |= RTFILE_O_NOT_CONTENT_INDEXED;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ {
+ /* Add file(s) to buffer. This enables processing multiple paths
+ * at once.
+ *
+ * Since the non-options (RTGETOPTINIT_FLAGS_OPTS_FIRST) come last when
+ * processing this loop it's safe to immediately exit on syntax errors
+ * or showing the help text (see above). */
+ rc = VBoxServiceToolboxPathBufAddPathEntry(&inputList, ValueUnion.psz);
+ break;
+ }
+
+ default:
+ return RTGetOptPrintError(ch, &ValueUnion);
+ }
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ if (strlen(szOutput))
+ {
+ rc = RTFileOpen(&hOutput, szOutput, fFlags);
+ if (RT_FAILURE(rc))
+ RTMsgError("Could not create output file '%s', rc=%Rrc\n",
+ szOutput, rc);
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ /* Process each input file. */
+ PVBOXSERVICETOOLBOXPATHENTRY pNodeIt;
+ RTFILE hInput = NIL_RTFILE;
+ RTListForEach(&inputList, pNodeIt, VBOXSERVICETOOLBOXPATHENTRY, Node)
+ {
+ rc = RTFileOpen(&hInput, pNodeIt->pszName,
+ RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+ if (RT_SUCCESS(rc))
+ {
+ rc = VBoxServiceToolboxCatOutput(hInput, hOutput);
+ RTFileClose(hInput);
+ }
+ else
+ {
+ PCRTSTATUSMSG pMsg = RTErrGet(rc);
+ if (pMsg)
+ RTMsgError("Could not open input file '%s': %s\n",
+ pNodeIt->pszName, pMsg->pszMsgFull);
+ else
+ RTMsgError("Could not open input file '%s', rc=%Rrc\n", pNodeIt->pszName, rc);
+ }
+
+ if (RT_FAILURE(rc))
+ break;
+ }
+
+ /* If not input files were defined, process stdin. */
+ if (RTListNodeIsFirst(&inputList, &inputList))
+ rc = VBoxServiceToolboxCatOutput(hInput, hOutput);
+ }
+ }
+
+ if (hOutput != NIL_RTFILE)
+ RTFileClose(hOutput);
+ VBoxServiceToolboxPathBufDestroy(&inputList);
+
+ return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+/**
+ * Prints information (based on given flags) of a file system object (file/directory/...)
+ * to stdout.
+ *
+ * @return IPRT status code.
+ * @param pszName Object name.
+ * @param cbName Size of object name.
+ * @param uOutputFlags Output / handling flags of type VBOXSERVICETOOLBOXOUTPUTFLAG.
+ * @param pObjInfo Pointer to object information.
+ */
+static int VBoxServiceToolboxPrintFsInfo(const char *pszName, uint16_t cbName,
+ uint32_t uOutputFlags,
+ PRTFSOBJINFO pObjInfo)
+{
+ AssertPtrReturn(pszName, VERR_INVALID_POINTER);
+ AssertReturn(cbName, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pObjInfo, VERR_INVALID_POINTER);
+
+ RTFMODE fMode = pObjInfo->Attr.fMode;
+ char chFileType;
+ switch (fMode & RTFS_TYPE_MASK)
+ {
+ case RTFS_TYPE_FIFO: chFileType = 'f'; break;
+ case RTFS_TYPE_DEV_CHAR: chFileType = 'c'; break;
+ case RTFS_TYPE_DIRECTORY: chFileType = 'd'; break;
+ case RTFS_TYPE_DEV_BLOCK: chFileType = 'b'; break;
+ case RTFS_TYPE_FILE: chFileType = '-'; break;
+ case RTFS_TYPE_SYMLINK: chFileType = 'l'; break;
+ case RTFS_TYPE_SOCKET: chFileType = 's'; break;
+ case RTFS_TYPE_WHITEOUT: chFileType = 'w'; break;
+ default: chFileType = '?'; break;
+ }
+ /** @todo sticy bits++ */
+
+ if (!(uOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_LONG))
+ {
+ if (uOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE)
+ {
+ /** @todo Skip node_id if not present/available! */
+ RTPrintf("ftype=%c%cnode_id=%RU64%cname_len=%RU16%cname=%s%c",
+ chFileType, 0, (uint64_t)pObjInfo->Attr.u.Unix.INodeId, 0,
+ cbName, 0, pszName, 0);
+ }
+ else
+ RTPrintf("%c %#18llx %3d %s\n",
+ chFileType, (uint64_t)pObjInfo->Attr.u.Unix.INodeId, cbName, pszName);
+
+ if (uOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE) /* End of data block. */
+ RTPrintf("%c%c", 0, 0);
+ }
+ else
+ {
+ if (uOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE)
+ {
+ RTPrintf("ftype=%c%c", chFileType, 0);
+ RTPrintf("owner_mask=%c%c%c%c",
+ fMode & RTFS_UNIX_IRUSR ? 'r' : '-',
+ fMode & RTFS_UNIX_IWUSR ? 'w' : '-',
+ fMode & RTFS_UNIX_IXUSR ? 'x' : '-', 0);
+ RTPrintf("group_mask=%c%c%c%c",
+ fMode & RTFS_UNIX_IRGRP ? 'r' : '-',
+ fMode & RTFS_UNIX_IWGRP ? 'w' : '-',
+ fMode & RTFS_UNIX_IXGRP ? 'x' : '-', 0);
+ RTPrintf("other_mask=%c%c%c%c",
+ fMode & RTFS_UNIX_IROTH ? 'r' : '-',
+ fMode & RTFS_UNIX_IWOTH ? 'w' : '-',
+ fMode & RTFS_UNIX_IXOTH ? 'x' : '-', 0);
+ RTPrintf("dos_mask=%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
+ fMode & RTFS_DOS_READONLY ? 'R' : '-',
+ fMode & RTFS_DOS_HIDDEN ? 'H' : '-',
+ fMode & RTFS_DOS_SYSTEM ? 'S' : '-',
+ fMode & RTFS_DOS_DIRECTORY ? 'D' : '-',
+ fMode & RTFS_DOS_ARCHIVED ? 'A' : '-',
+ fMode & RTFS_DOS_NT_DEVICE ? 'd' : '-',
+ fMode & RTFS_DOS_NT_NORMAL ? 'N' : '-',
+ fMode & RTFS_DOS_NT_TEMPORARY ? 'T' : '-',
+ fMode & RTFS_DOS_NT_SPARSE_FILE ? 'P' : '-',
+ fMode & RTFS_DOS_NT_REPARSE_POINT ? 'J' : '-',
+ fMode & RTFS_DOS_NT_COMPRESSED ? 'C' : '-',
+ fMode & RTFS_DOS_NT_OFFLINE ? 'O' : '-',
+ fMode & RTFS_DOS_NT_NOT_CONTENT_INDEXED ? 'I' : '-',
+ fMode & RTFS_DOS_NT_ENCRYPTED ? 'E' : '-', 0);
+
+ char szTimeBirth[256];
+ RTTimeSpecToString(&pObjInfo->BirthTime, szTimeBirth, sizeof(szTimeBirth));
+ char szTimeChange[256];
+ RTTimeSpecToString(&pObjInfo->ChangeTime, szTimeChange, sizeof(szTimeChange));
+ char szTimeModification[256];
+ RTTimeSpecToString(&pObjInfo->ModificationTime, szTimeModification, sizeof(szTimeModification));
+ char szTimeAccess[256];
+ RTTimeSpecToString(&pObjInfo->AccessTime, szTimeAccess, sizeof(szTimeAccess));
+
+ RTPrintf("hlinks=%RU32%cuid=%RU32%cgid=%RU32%cst_size=%RI64%calloc=%RI64%c"
+ "st_birthtime=%s%cst_ctime=%s%cst_mtime=%s%cst_atime=%s%c",
+ pObjInfo->Attr.u.Unix.cHardlinks, 0,
+ pObjInfo->Attr.u.Unix.uid, 0,
+ pObjInfo->Attr.u.Unix.gid, 0,
+ pObjInfo->cbObject, 0,
+ pObjInfo->cbAllocated, 0,
+ szTimeBirth, 0,
+ szTimeChange, 0,
+ szTimeModification, 0,
+ szTimeAccess, 0);
+ RTPrintf("cname_len=%RU16%cname=%s%c",
+ cbName, 0, pszName, 0);
+
+ /* End of data block. */
+ RTPrintf("%c%c", 0, 0);
+ }
+ else
+ {
+ RTPrintf("%c", chFileType);
+ RTPrintf("%c%c%c",
+ fMode & RTFS_UNIX_IRUSR ? 'r' : '-',
+ fMode & RTFS_UNIX_IWUSR ? 'w' : '-',
+ fMode & RTFS_UNIX_IXUSR ? 'x' : '-');
+ RTPrintf("%c%c%c",
+ fMode & RTFS_UNIX_IRGRP ? 'r' : '-',
+ fMode & RTFS_UNIX_IWGRP ? 'w' : '-',
+ fMode & RTFS_UNIX_IXGRP ? 'x' : '-');
+ RTPrintf("%c%c%c",
+ fMode & RTFS_UNIX_IROTH ? 'r' : '-',
+ fMode & RTFS_UNIX_IWOTH ? 'w' : '-',
+ fMode & RTFS_UNIX_IXOTH ? 'x' : '-');
+ RTPrintf(" %c%c%c%c%c%c%c%c%c%c%c%c%c%c",
+ fMode & RTFS_DOS_READONLY ? 'R' : '-',
+ fMode & RTFS_DOS_HIDDEN ? 'H' : '-',
+ fMode & RTFS_DOS_SYSTEM ? 'S' : '-',
+ fMode & RTFS_DOS_DIRECTORY ? 'D' : '-',
+ fMode & RTFS_DOS_ARCHIVED ? 'A' : '-',
+ fMode & RTFS_DOS_NT_DEVICE ? 'd' : '-',
+ fMode & RTFS_DOS_NT_NORMAL ? 'N' : '-',
+ fMode & RTFS_DOS_NT_TEMPORARY ? 'T' : '-',
+ fMode & RTFS_DOS_NT_SPARSE_FILE ? 'P' : '-',
+ fMode & RTFS_DOS_NT_REPARSE_POINT ? 'J' : '-',
+ fMode & RTFS_DOS_NT_COMPRESSED ? 'C' : '-',
+ fMode & RTFS_DOS_NT_OFFLINE ? 'O' : '-',
+ fMode & RTFS_DOS_NT_NOT_CONTENT_INDEXED ? 'I' : '-',
+ fMode & RTFS_DOS_NT_ENCRYPTED ? 'E' : '-');
+ RTPrintf(" %d %4d %4d %10lld %10lld %#llx %#llx %#llx %#llx",
+ pObjInfo->Attr.u.Unix.cHardlinks,
+ pObjInfo->Attr.u.Unix.uid,
+ pObjInfo->Attr.u.Unix.gid,
+ pObjInfo->cbObject,
+ pObjInfo->cbAllocated,
+ pObjInfo->BirthTime,
+ pObjInfo->ChangeTime,
+ pObjInfo->ModificationTime,
+ pObjInfo->AccessTime);
+ RTPrintf(" %2d %s\n", cbName, pszName);
+ }
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Helper routine for ls tool doing the actual parsing and output of
+ * a specified directory.
+ *
+ * @return IPRT status code.
+ * @param pszDir Directory (path) to ouptut.
+ * @param uFlags Flags of type VBOXSERVICETOOLBOXLSFLAG.
+ * @param uOutputFlags Flags of type VBOXSERVICETOOLBOXOUTPUTFLAG.
+ */
+static int VBoxServiceToolboxLsHandleDir(const char *pszDir,
+ uint32_t uFlags, uint32_t uOutputFlags)
+{
+ AssertPtrReturn(pszDir, VERR_INVALID_PARAMETER);
+
+ if (uFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE)
+ RTPrintf("dname=%s%c", pszDir, 0);
+ else if (uFlags & VBOXSERVICETOOLBOXLSFLAG_RECURSIVE)
+ RTPrintf("%s:\n", pszDir);
+
+ char szPathAbs[RTPATH_MAX + 1];
+ int rc = RTPathAbs(pszDir, szPathAbs, sizeof(szPathAbs));
+ if (RT_FAILURE(rc))
+ {
+ RTMsgError("Failed to retrieve absolute path of '%s', rc=%Rrc\n", pszDir, rc);
+ return rc;
+ }
+
+ PRTDIR pDir;
+ rc = RTDirOpen(&pDir, szPathAbs);
+ if (RT_FAILURE(rc))
+ {
+ RTMsgError("Failed to open directory '%s', rc=%Rrc\n", szPathAbs, rc);
+ return rc;
+ }
+
+ RTLISTNODE dirList;
+ RTListInit(&dirList);
+
+ /* To prevent races we need to read in the directory entries once
+ * and process them afterwards: First loop is displaying the current
+ * directory's content and second loop is diving deeper into
+ * sub directories (if wanted). */
+ for (;RT_SUCCESS(rc);)
+ {
+ RTDIRENTRYEX DirEntry;
+ rc = RTDirReadEx(pDir, &DirEntry, NULL, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
+ if (RT_SUCCESS(rc))
+ {
+ PVBOXSERVICETOOLBOXDIRENTRY pNode = (PVBOXSERVICETOOLBOXDIRENTRY)RTMemAlloc(sizeof(VBOXSERVICETOOLBOXDIRENTRY));
+ if (pNode)
+ {
+ memcpy(&pNode->dirEntry, &DirEntry, sizeof(RTDIRENTRYEX));
+ /*rc =*/ RTListAppend(&dirList, &pNode->Node);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ }
+ }
+
+ if (rc == VERR_NO_MORE_FILES)
+ rc = VINF_SUCCESS;
+
+ int rc2 = RTDirClose(pDir);
+ if (RT_FAILURE(rc2))
+ {
+ RTMsgError("Failed to close dir '%s', rc=%Rrc\n",
+ pszDir, rc2);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ PVBOXSERVICETOOLBOXDIRENTRY pNodeIt;
+ RTListForEach(&dirList, pNodeIt, VBOXSERVICETOOLBOXDIRENTRY, Node)
+ {
+ rc = VBoxServiceToolboxPrintFsInfo(pNodeIt->dirEntry.szName, pNodeIt->dirEntry.cbName,
+ uOutputFlags,
+ &pNodeIt->dirEntry.Info);
+ if (RT_FAILURE(rc))
break;
+ }
+
+ /* If everything went fine we do the second run (if needed) ... */
+ if ( RT_SUCCESS(rc)
+ && (uFlags & VBOXSERVICETOOLBOXLSFLAG_RECURSIVE))
+ {
+ /* Process all sub-directories. */
+ RTListForEach(&dirList, pNodeIt, VBOXSERVICETOOLBOXDIRENTRY, Node)
+ {
+ RTFMODE fMode = pNodeIt->dirEntry.Info.Attr.fMode;
+ switch (fMode & RTFS_TYPE_MASK)
+ {
+ case RTFS_TYPE_SYMLINK:
+ if (!(uFlags & VBOXSERVICETOOLBOXLSFLAG_SYMLINKS))
+ break;
+ /* Fall through is intentional. */
+ case RTFS_TYPE_DIRECTORY:
+ {
+ const char *pszName = pNodeIt->dirEntry.szName;
+ if ( !RTStrICmp(pszName, ".")
+ || !RTStrICmp(pszName, ".."))
+ {
+ /* Skip dot directories. */
+ continue;
+ }
+
+ char szPath[RTPATH_MAX];
+ rc = RTPathJoin(szPath, sizeof(szPath),
+ pszDir, pNodeIt->dirEntry.szName);
+ if (RT_SUCCESS(rc))
+ rc = VBoxServiceToolboxLsHandleDir(szPath,
+ uFlags, uOutputFlags);
+ }
+ break;
+
+ default: /* Ignore the rest. */
+ break;
+ }
+ if (RT_FAILURE(rc))
+ break;
}
}
}
+
+ /* Clean up the mess. */
+ PVBOXSERVICETOOLBOXDIRENTRY pNode, pSafe;
+ RTListForEachSafe(&dirList, pNode, pSafe, VBOXSERVICETOOLBOXDIRENTRY, Node)
+ {
+ RTListNodeRemove(&pNode->Node);
+ RTMemFree(pNode);
+ }
return rc;
}
/**
+ * Main function for tool "vbox_ls".
+ *
+ * @return RTEXITCODE.
+ * @param argc Number of arguments.
+ * @param argv Pointer to argument array.
+ */
+static RTEXITCODE VBoxServiceToolboxLs(int argc, char **argv)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--machinereadable", VBOXSERVICETOOLBOXLSOPT_MACHINE_READABLE, RTGETOPT_REQ_NOTHING },
+ { "--dereference", 'L', RTGETOPT_REQ_NOTHING },
+ { NULL, 'l', RTGETOPT_REQ_NOTHING },
+ { NULL, 'R', RTGETOPT_REQ_NOTHING },
+ { "--verbose", VBOXSERVICETOOLBOXLSOPT_VERBOSE, RTGETOPT_REQ_NOTHING}
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ int rc = RTGetOptInit(&GetState, argc, argv,
+ s_aOptions, RT_ELEMENTS(s_aOptions),
+ 1 /*iFirst*/, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+ AssertRCReturn(rc, RTEXITCODE_INIT);
+
+ bool fVerbose = false;
+ uint32_t fFlags = VBOXSERVICETOOLBOXLSFLAG_NONE;
+ uint32_t fOutputFlags = VBOXSERVICETOOLBOXOUTPUTFLAG_NONE;
+
+ /* Init file list. */
+ RTLISTNODE fileList;
+ RTListInit(&fileList);
+
+ while ( (ch = RTGetOpt(&GetState, &ValueUnion))
+ && RT_SUCCESS(rc))
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ case 'h':
+ VBoxServiceToolboxShowUsage();
+ return RTEXITCODE_SUCCESS;
+
+ case 'L': /* Dereference symlinks. */
+ fFlags |= VBOXSERVICETOOLBOXLSFLAG_SYMLINKS;
+ break;
+
+ case 'l': /* Print long format. */
+ fOutputFlags |= VBOXSERVICETOOLBOXOUTPUTFLAG_LONG;
+ break;
+
+ case VBOXSERVICETOOLBOXLSOPT_MACHINE_READABLE:
+ fOutputFlags |= VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE;
+ break;
+
+ case 'R': /* Recursive processing. */
+ fFlags |= VBOXSERVICETOOLBOXLSFLAG_RECURSIVE;
+ break;
+
+ case VBOXSERVICETOOLBOXLSOPT_VERBOSE:
+ fVerbose = true;
+ break;
+
+ case 'V':
+ VBoxServiceToolboxShowVersion();
+ return RTEXITCODE_SUCCESS;
+
+ case VINF_GETOPT_NOT_OPTION:
+ /* Add file(s) to buffer. This enables processing multiple files
+ * at once.
+ *
+ * Since the non-options (RTGETOPTINIT_FLAGS_OPTS_FIRST) come last when
+ * processing this loop it's safe to immediately exit on syntax errors
+ * or showing the help text (see above). */
+ rc = VBoxServiceToolboxPathBufAddPathEntry(&fileList, ValueUnion.psz);
+ /** @todo r=bird: Nit: creating a list here is not really
+ * necessary since you've got one in argv that's
+ * accessible via RTGetOpt. */
+ break;
+
+ default:
+ return RTGetOptPrintError(ch, &ValueUnion);
+ }
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ /* If not files given add current directory to list. */
+ if (RTListIsEmpty(&fileList))
+ {
+ char szDirCur[RTPATH_MAX + 1];
+ rc = RTPathGetCurrent(szDirCur, sizeof(szDirCur));
+ if (RT_SUCCESS(rc))
+ {
+ rc = VBoxServiceToolboxPathBufAddPathEntry(&fileList, szDirCur);
+ if (RT_FAILURE(rc))
+ RTMsgError("Adding current directory failed, rc=%Rrc\n", rc);
+ }
+ else
+ RTMsgError("Getting current directory failed, rc=%Rrc\n", rc);
+ }
+
+ /* Print magic/version. */
+ if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE)
+ VBoxServiceToolboxPrintStrmHeader("vbt_ls", 1 /* Stream version */);
+
+ PVBOXSERVICETOOLBOXPATHENTRY pNodeIt;
+ RTListForEach(&fileList, pNodeIt, VBOXSERVICETOOLBOXPATHENTRY, Node)
+ {
+ if (RTFileExists(pNodeIt->pszName))
+ {
+ RTFSOBJINFO objInfo;
+ int rc2 = RTPathQueryInfoEx(pNodeIt->pszName, &objInfo,
+ RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK /* @todo Follow link? */);
+ if (RT_FAILURE(rc2))
+ {
+ RTMsgError("Cannot access '%s': No such file or directory\n",
+ pNodeIt->pszName);
+ rc = VERR_FILE_NOT_FOUND;
+ /* Do not break here -- process every element in the list
+ * and keep failing rc. */
+ }
+ else
+ {
+ rc2 = VBoxServiceToolboxPrintFsInfo(pNodeIt->pszName,
+ strlen(pNodeIt->pszName) /* cbName */,
+ fOutputFlags,
+ &objInfo);
+ if (RT_FAILURE(rc2))
+ rc = rc2;
+ }
+ }
+ else
+ {
+ int rc2 = VBoxServiceToolboxLsHandleDir(pNodeIt->pszName,
+ fFlags, fOutputFlags);
+ if (RT_FAILURE(rc2))
+ rc = rc2;
+ }
+ }
+
+ if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE) /* Output termination. */
+ VBoxServiceToolboxPrintStrmTermination();
+ }
+ else if (fVerbose)
+ RTMsgError("Failed with rc=%Rrc\n", rc);
+
+ VBoxServiceToolboxPathBufDestroy(&fileList);
+ return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/**
* Main function for tool "vbox_mkdir".
*
* @return RTEXITCODE.
@@ -213,271 +882,262 @@ static int VBoxServiceToolboxCatOutput(RTFILE hInput, RTFILE hOutput)
*/
static RTEXITCODE VBoxServiceToolboxMkDir(int argc, char **argv)
{
- static const RTGETOPTDEF s_aOptions[] =
- {
- { "--mode", 'm', RTGETOPT_REQ_STRING },
- { "--parents", 'p', RTGETOPT_REQ_NOTHING },
- { "--verbose", 'v', RTGETOPT_REQ_NOTHING }
- };
-
- int ch;
- RTGETOPTUNION ValueUnion;
- RTGETOPTSTATE GetState;
- RTGetOptInit(&GetState, argc, argv,
- s_aOptions, RT_ELEMENTS(s_aOptions),
- 1 /* Index of argv to start with. */, RTGETOPTINIT_FLAGS_OPTS_FIRST);
-
- int rc = VINF_SUCCESS;
- bool fMakeParentDirs = false;
- bool fVerbose = false;
-
- RTFMODE newMode = 0;
- RTFMODE dirMode = RTFS_UNIX_IRWXU | RTFS_UNIX_IRWXG | RTFS_UNIX_IRWXO;
-
- /* Init directory list. */
- RTLISTNODE dirList;
- RTListInit(&dirList);
-
- while ( (ch = RTGetOpt(&GetState, &ValueUnion))
- && RT_SUCCESS(rc))
- {
- /* For options that require an argument, ValueUnion has received the value. */
- switch (ch)
- {
- case 'h':
- VBoxServiceToolboxShowUsage();
- return RTEXITCODE_SUCCESS;
-
- case 'p':
- fMakeParentDirs = true;
- break;
-
- case 'm':
- rc = RTStrToUInt32Ex(ValueUnion.psz, NULL, 8 /* Base */, &newMode);
- if (RT_FAILURE(rc)) /* Only octet based values supported right now! */
- {
- RTMsgError("mkdir: Mode flag strings not implemented yet! Use octal numbers instead.\n");
- return RTEXITCODE_SYNTAX;
- }
- break;
-
- case 'v':
- fVerbose = true;
- break;
-
- case 'V':
- VBoxServiceToolboxShowVersion();
- return RTEXITCODE_SUCCESS;
-
- case VINF_GETOPT_NOT_OPTION:
- {
- /* Add path(s) to buffer. This enables processing multiple paths
- * at once.
- *
- * Since the non-options (RTGETOPTINIT_FLAGS_OPTS_FIRST) come last when
- * processing this loop it's safe to immediately exit on syntax errors
- * or showing the help text (see above). */
- rc = VBoxServiceToolboxPathBufAddPathEntry(&dirList, ValueUnion.psz);
- break;
- }
-
- default:
- return RTGetOptPrintError(ch, &ValueUnion);
- }
- }
-
- if (RT_SUCCESS(rc))
- {
- if (fMakeParentDirs || newMode)
- {
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--mode", 'm', RTGETOPT_REQ_STRING },
+ { "--parents", 'p', RTGETOPT_REQ_NOTHING},
+ { "--verbose", 'v', RTGETOPT_REQ_NOTHING}
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ int rc = RTGetOptInit(&GetState, argc, argv,
+ s_aOptions, RT_ELEMENTS(s_aOptions),
+ 1 /*iFirst*/, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+ AssertRCReturn(rc, RTEXITCODE_INIT);
+
+ bool fMakeParentDirs = false;
+ bool fVerbose = false;
+ RTFMODE fDirMode = RTFS_UNIX_IRWXU | RTFS_UNIX_IRWXG | RTFS_UNIX_IRWXO;
+ int cDirsCreated = 0;
+
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ case 'p':
+ fMakeParentDirs = true;
+#ifndef RT_OS_WINDOWS
+ umask(0); /* RTDirCreate workaround */
+#endif
+ break;
+
+ case 'm':
+ rc = RTStrToUInt32Ex(ValueUnion.psz, NULL, 8 /* Base */, &fDirMode);
+ if (RT_FAILURE(rc)) /* Only octet based values supported right now! */
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX,
+ "Mode flag strings not implemented yet! Use octal numbers instead. (%s)\n",
+ ValueUnion.psz);
#ifndef RT_OS_WINDOWS
- mode_t umaskMode = umask(0); /* Get current umask. */
- if (newMode)
- dirMode = newMode;
+ umask(0); /* RTDirCreate workaround */
#endif
- }
-
- PVBOXSERVICETOOLBOXPATHENTRY pNodeIt;
- RTListForEach(&dirList, pNodeIt, VBOXSERVICETOOLBOXPATHENTRY, Node)
- {
- rc = fMakeParentDirs ?
- RTDirCreateFullPath(pNodeIt->pszName, dirMode)
- : RTDirCreate(pNodeIt->pszName, dirMode);
-
- if (RT_SUCCESS(rc) && fVerbose)
- RTMsgError("mkdir: Created directory 's', mode %#RTfmode\n", pNodeIt->pszName, dirMode);
- else if (RT_FAILURE(rc)) /** @todo Add a switch with more helpful error texts! */
- {
- PCRTSTATUSMSG pMsg = RTErrGet(rc);
- if (pMsg)
- RTMsgError("mkdir: Could not create directory '%s': %s\n",
- pNodeIt->pszName, pMsg->pszMsgFull);
- else
- RTMsgError("mkdir: Could not create directory '%s', rc=%Rrc\n", pNodeIt->pszName, rc);
- break;
- }
- }
- }
- else if (fVerbose)
- RTMsgError("mkdir: Failed with rc=%Rrc\n", rc);
-
- VBoxServiceToolboxPathBufDestroy(&dirList);
- return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+ break;
+
+ case 'v':
+ fVerbose = true;
+ break;
+
+ case 'h':
+ RTPrintf("Usage: %s [options] dir1 [dir2...]\n"
+ "\n"
+ "Options:\n"
+ " -m,--mode=<mode> The file mode to set (chmod) on the created\n"
+ " directories. Default: a=rwx & umask.\n"
+ " -p,--parents Create parent directories as needed, no\n"
+ " error if the directory already exists.\n"
+ " -v,--verbose Display a message for each created directory.\n"
+ " -V,--version Display the version and exit\n"
+ " -h,--help Display this help text and exit.\n"
+ , argv[0]);
+ return RTEXITCODE_SUCCESS;
+
+ case 'V':
+ VBoxServiceToolboxShowVersion();
+ return RTEXITCODE_SUCCESS;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (fMakeParentDirs)
+ /** @todo r=bird: If fVerbose is set, we should also show
+ * which directories that get created, parents as well as
+ * omitting existing final dirs. Annoying, but check any
+ * mkdir implementation (try "mkdir -pv asdf/1/2/3/4"
+ * twice). */
+ rc = RTDirCreateFullPath(ValueUnion.psz, fDirMode);
+ else
+ rc = RTDirCreate(ValueUnion.psz, fDirMode);
+ if (RT_FAILURE(rc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Could not create directory '%s': %Rra\n",
+ ValueUnion.psz, rc);
+ if (fVerbose)
+ RTMsgInfo("Created directory '%s', mode %#RTfmode\n", ValueUnion.psz, fDirMode);
+ cDirsCreated++;
+ break;
+
+ default:
+ return RTGetOptPrintError(ch, &ValueUnion);
+ }
+ }
+ AssertRC(rc);
+
+ if (cDirsCreated == 0)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No directory argument.");
+
+ return RTEXITCODE_SUCCESS;
}
/**
- * Main function for tool "vbox_cat".
+ * Main function for tool "vbox_stat".
*
* @return RTEXITCODE.
* @param argc Number of arguments.
* @param argv Pointer to argument array.
*/
-static RTEXITCODE VBoxServiceToolboxCat(int argc, char **argv)
+static RTEXITCODE VBoxServiceToolboxStat(int argc, char **argv)
{
- static const RTGETOPTDEF s_aOptions[] =
- {
- /* Sorted by short ops. */
- { "--show-all", 'a', RTGETOPT_REQ_NOTHING },
- { "--number-nonblank", 'b', RTGETOPT_REQ_NOTHING },
- { NULL, 'e', RTGETOPT_REQ_NOTHING },
- { NULL, 'E', RTGETOPT_REQ_NOTHING },
- { "--flags", 'f', RTGETOPT_REQ_STRING },
- { "--no-content-indexed", CAT_OPT_NO_CONTENT_INDEXED, RTGETOPT_REQ_NOTHING },
- { "--number", 'n', RTGETOPT_REQ_NOTHING },
- { "--output", 'o', RTGETOPT_REQ_STRING },
- { "--squeeze-blank", 's', RTGETOPT_REQ_NOTHING },
- { NULL, 't', RTGETOPT_REQ_NOTHING },
- { "--show-tabs", 'T', RTGETOPT_REQ_NOTHING },
- { NULL, 'u', RTGETOPT_REQ_NOTHING },
- { "--show-noneprinting", 'v', RTGETOPT_REQ_NOTHING }
- };
-
- int ch;
- RTGETOPTUNION ValueUnion;
- RTGETOPTSTATE GetState;
- RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
-
- int rc = VINF_SUCCESS;
- bool fUsageOK = true;
-
- char szOutput[RTPATH_MAX] = { 0 };
- RTFILE hOutput = NIL_RTFILE;
- uint32_t fFlags = RTFILE_O_CREATE_REPLACE /* Output file flags. */
- | RTFILE_O_WRITE
- | RTFILE_O_DENY_WRITE;
-
- /* Init directory list. */
- RTLISTNODE inputList;
- RTListInit(&inputList);
-
- while ( (ch = RTGetOpt(&GetState, &ValueUnion))
- && RT_SUCCESS(rc))
- {
- /* For options that require an argument, ValueUnion has received the value. */
- switch (ch)
- {
- case 'a':
- case 'b':
- case 'e':
- case 'E':
- case 'n':
- case 's':
- case 't':
- case 'T':
- case 'v':
- RTMsgError("cat: Sorry, option '%s' is not implemented yet!\n",
- ValueUnion.pDef->pszLong);
- rc = VERR_INVALID_PARAMETER;
- break;
-
- case 'h':
- VBoxServiceToolboxShowUsage();
- return RTEXITCODE_SUCCESS;
-
- case 'o':
- if (!RTStrPrintf(szOutput, sizeof(szOutput), ValueUnion.psz))
- rc = VERR_NO_MEMORY;
- break;
-
- case 'u':
- /* Ignored. */
- break;
-
- case 'V':
- VBoxServiceToolboxShowVersion();
- return RTEXITCODE_SUCCESS;
-
- case CAT_OPT_NO_CONTENT_INDEXED:
- fFlags |= RTFILE_O_NOT_CONTENT_INDEXED;
- break;
-
- case VINF_GETOPT_NOT_OPTION:
- {
- /* Add file(s) to buffer. This enables processing multiple paths
- * at once.
- *
- * Since the non-options (RTGETOPTINIT_FLAGS_OPTS_FIRST) come last when
- * processing this loop it's safe to immediately exit on syntax errors
- * or showing the help text (see above). */
- rc = VBoxServiceToolboxPathBufAddPathEntry(&inputList, ValueUnion.psz);
- break;
- }
-
- default:
- return RTGetOptPrintError(ch, &ValueUnion);
- }
- }
-
- if (RT_SUCCESS(rc))
- {
- if (strlen(szOutput))
- {
- rc = RTFileOpen(&hOutput, szOutput, fFlags);
- if (RT_FAILURE(rc))
- RTMsgError("cat: Could not create output file '%s'! rc=%Rrc\n",
- szOutput, rc);
- }
-
- if (RT_SUCCESS(rc))
- {
- /* Process each input file. */
- PVBOXSERVICETOOLBOXPATHENTRY pNodeIt;
- RTFILE hInput = NIL_RTFILE;
- RTListForEach(&inputList, pNodeIt, VBOXSERVICETOOLBOXPATHENTRY, Node)
- {
- rc = RTFileOpen(&hInput, pNodeIt->pszName,
- RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
- if (RT_SUCCESS(rc))
- {
- rc = VBoxServiceToolboxCatOutput(hInput, hOutput);
- RTFileClose(hInput);
- }
- else
- {
- PCRTSTATUSMSG pMsg = RTErrGet(rc);
- if (pMsg)
- RTMsgError("cat: Could not open input file '%s': %s\n",
- pNodeIt->pszName, pMsg->pszMsgFull);
- else
- RTMsgError("cat: Could not open input file '%s', rc=%Rrc\n", pNodeIt->pszName, rc);
- }
-
- if (RT_FAILURE(rc))
- break;
- }
-
- /* If not input files were defined, process stdin. */
- if (RTListNodeIsFirst(&inputList, &inputList))
- rc = VBoxServiceToolboxCatOutput(hInput, hOutput);
- }
- }
-
- if (hOutput != NIL_RTFILE)
- RTFileClose(hOutput);
- VBoxServiceToolboxPathBufDestroy(&inputList);
-
- return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--file-system", 'f', RTGETOPT_REQ_NOTHING },
+ { "--dereference", 'L', RTGETOPT_REQ_NOTHING },
+ { "--machinereadable", VBOXSERVICETOOLBOXLSOPT_MACHINE_READABLE, RTGETOPT_REQ_NOTHING },
+ { "--terse", 't', RTGETOPT_REQ_NOTHING },
+ { "--verbose", 'v', RTGETOPT_REQ_NOTHING }
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv,
+ s_aOptions, RT_ELEMENTS(s_aOptions),
+ 1 /*iFirst*/, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ int rc = VINF_SUCCESS;
+ bool fVerbose = false;
+ uint32_t fOutputFlags = VBOXSERVICETOOLBOXOUTPUTFLAG_LONG; /* Use long mode by default. */
+
+ /* Init file list. */
+ RTLISTNODE fileList;
+ RTListInit(&fileList);
+
+ while ( (ch = RTGetOpt(&GetState, &ValueUnion))
+ && RT_SUCCESS(rc))
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ case 'f':
+ case 'L':
+ RTMsgError("Sorry, option '%s' is not implemented yet!\n", ValueUnion.pDef->pszLong);
+ rc = VERR_INVALID_PARAMETER;
+ break;
+
+ case VBOXSERVICETOOLBOXLSOPT_MACHINE_READABLE:
+ fOutputFlags |= VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE;
+ break;
+
+ case 'v': /** @todo r=bird: There is no verbose option for stat. */
+ fVerbose = true;
+ break;
+
+ case 'h':
+ VBoxServiceToolboxShowUsage();
+ return RTEXITCODE_SUCCESS;
+
+ case 'V':
+ VBoxServiceToolboxShowVersion();
+ return RTEXITCODE_SUCCESS;
+
+ case VINF_GETOPT_NOT_OPTION:
+ {
+ /* Add file(s) to buffer. This enables processing multiple files
+ * at once.
+ *
+ * Since the non-options (RTGETOPTINIT_FLAGS_OPTS_FIRST) come last when
+ * processing this loop it's safe to immediately exit on syntax errors
+ * or showing the help text (see above). */
+ rc = VBoxServiceToolboxPathBufAddPathEntry(&fileList, ValueUnion.psz);
+ break;
+ }
+
+ default:
+ return RTGetOptPrintError(ch, &ValueUnion);
+ }
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE) /* Output termination. */
+ VBoxServiceToolboxPrintStrmHeader("vbt_stat", 1 /* Stream version */);
+
+ PVBOXSERVICETOOLBOXPATHENTRY pNodeIt;
+ RTListForEach(&fileList, pNodeIt, VBOXSERVICETOOLBOXPATHENTRY, Node)
+ {
+ RTFSOBJINFO objInfo;
+ int rc2 = RTPathQueryInfoEx(pNodeIt->pszName, &objInfo,
+ RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK /* @todo Follow link? */);
+ if (RT_FAILURE(rc2))
+ {
+ RTMsgError("Cannot stat for '%s': No such file or directory\n",
+ pNodeIt->pszName);
+ rc = VERR_FILE_NOT_FOUND;
+ /* Do not break here -- process every element in the list
+ * and keep failing rc. */
+ }
+ else
+ {
+ rc2 = VBoxServiceToolboxPrintFsInfo(pNodeIt->pszName,
+ strlen(pNodeIt->pszName) /* cbName */,
+ fOutputFlags,
+ &objInfo);
+ if (RT_FAILURE(rc2))
+ rc = rc2;
+ }
+ }
+
+ if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE) /* Output termination. */
+ VBoxServiceToolboxPrintStrmTermination();
+
+ /* At this point the overall result (success/failure) should be in rc. */
+
+ if (RTListIsEmpty(&fileList))
+ RTMsgError("Missing operand\n");
+ }
+ else if (fVerbose)
+ RTMsgError("Failed with rc=%Rrc\n", rc);
+
+ VBoxServiceToolboxPathBufDestroy(&fileList);
+ return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+
+/**
+ * Looks up the handler for the tool give by @a pszTool.
+ *
+ * @returns Pointer to handler function. NULL if not found.
+ * @param pszTool The name of the tool.
+ */
+static PFNHANDLER vboxServiceToolboxLookUpHandler(const char *pszTool)
+{
+ static struct
+ {
+ const char *pszName;
+ RTEXITCODE (*pfnHandler)(int argc, char **argv);
+ }
+ const s_aTools[] =
+ {
+ { "cat", VBoxServiceToolboxCat },
+ { "ls", VBoxServiceToolboxLs },
+ { "mkdir", VBoxServiceToolboxMkDir },
+ { "stat", VBoxServiceToolboxStat },
+ };
+
+ /* Skip optional 'vbox_' prefix. */
+ if ( pszTool[0] == 'v'
+ && pszTool[1] == 'b'
+ && pszTool[2] == 'o'
+ && pszTool[3] == 'x'
+ && pszTool[4] == '_')
+ pszTool += 5;
+
+ /* Do a linear search, since we don't have that much stuff in the table. */
+ for (unsigned i = 0; i < RT_ELEMENTS(s_aTools); i++)
+ if (!strcmp(s_aTools[i].pszName, pszTool))
+ return s_aTools[i].pfnHandler;
+
+ return NULL;
}
@@ -492,22 +1152,38 @@ static RTEXITCODE VBoxServiceToolboxCat(int argc, char **argv)
*/
bool VBoxServiceToolboxMain(int argc, char **argv, RTEXITCODE *prcExit)
{
- if (argc > 0) /* Do we have at least a main command? */
- {
- if ( !strcmp(argv[0], "cat")
- || !strcmp(argv[0], "vbox_cat"))
- {
- *prcExit = VBoxServiceToolboxCat(argc, argv);
- return true;
- }
- if ( !strcmp(argv[0], "mkdir")
- || !strcmp(argv[0], "vbox_mkdir"))
+ /*
+ * Check if the file named in argv[0] is one of the toolbox programs.
+ */
+ AssertReturn(argc > 0, false);
+ const char *pszTool = RTPathFilename(argv[0]);
+ PFNHANDLER pfnHandler = vboxServiceToolboxLookUpHandler(pszTool);
+ if (!pfnHandler)
+ {
+ /*
+ * For debugging and testing purposes we also allow toolbox program access
+ * when the first VBoxService argument is --use-toolbox.
+ */
+ if (argc < 3 || strcmp(argv[1], "--use-toolbox"))
+ return false;
+ argc -= 2;
+ argv += 2;
+ pszTool = argv[0];
+ pfnHandler = vboxServiceToolboxLookUpHandler(pszTool);
+ if (!pfnHandler)
{
- *prcExit = VBoxServiceToolboxMkDir(argc, argv);
- return true;
+ *prcExit = RTMsgErrorExit(RTEXITCODE_SYNTAX, "Toolbox program '%s' does not exist", pszTool);
+ return true;
}
}
- return false;
+
+ /*
+ * Invoke the handler.
+ */
+ RTMsgSetProgName("VBoxService/%s", pszTool);
+ *prcExit = pfnHandler(argc, argv);
+ return true;
+
}
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceUtils.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceUtils.cpp
index 6dcff3a89..d988b992e 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceUtils.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceUtils.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceUtils.cpp $ */
+/* $Id: VBoxServiceUtils.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxServiceUtils - Some utility functions.
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceUtils.h b/src/VBox/Additions/common/VBoxService/VBoxServiceUtils.h
index 7cd6dfc96..bc4ad0031 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceUtils.h
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceUtils.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceUtils.h $ */
+/* $Id: VBoxServiceUtils.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxServiceUtils - Guest Additions Services (Utilities).
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
index 975d85629..d69de494d 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceVMInfo-win.cpp $ */
+/* $Id: VBoxServiceVMInfo-win.cpp 33895 2010-11-09 12:41:28Z vboxsync $ */
/** @file
* VBoxService - Virtual Machine Information for the Host, Windows specifics.
*/
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
index 85f17e5ef..d02ff57b5 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxServiceVMInfo.cpp $ */
+/* $Id: VBoxServiceVMInfo.cpp 37256 2011-05-30 12:39:03Z vboxsync $ */
/** @file
* VBoxService - Virtual Machine Information for the Host.
*/
diff --git a/src/VBox/Additions/common/VBoxService/testcase/Makefile.kmk b/src/VBox/Additions/common/VBoxService/testcase/Makefile.kmk
index d75c86ff9..678611500 100644
--- a/src/VBox/Additions/common/VBoxService/testcase/Makefile.kmk
+++ b/src/VBox/Additions/common/VBoxService/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 32634 2010-09-20 12:00:44Z vboxsync $
## @file
# Sub-Makefile for VBoxServicec test cases.
#
diff --git a/src/VBox/Additions/common/VBoxService/testcase/tstUserInfo.cpp b/src/VBox/Additions/common/VBoxService/testcase/tstUserInfo.cpp
index b27e986a6..b9a2405b9 100644
--- a/src/VBox/Additions/common/VBoxService/testcase/tstUserInfo.cpp
+++ b/src/VBox/Additions/common/VBoxService/testcase/tstUserInfo.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstUserInfo.cpp $ */
+/* $Id: tstUserInfo.cpp 32652 2010-09-21 07:04:49Z vboxsync $ */
/** @file
* Test case for correct user environment.
*/
diff --git a/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp b/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
index 5f37c56f0..387c2d871 100644
--- a/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
+++ b/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
@@ -1,4 +1,4 @@
-/* $Id: HGSMIBase.cpp $ */
+/* $Id: HGSMIBase.cpp 35398 2011-01-04 09:39:07Z vboxsync $ */
/** @file
* VirtualBox Video driver, common code - HGSMI initialisation and helper
* functions.
diff --git a/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp b/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
index 93ab8cb60..bd717a4e9 100644
--- a/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
+++ b/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
@@ -1,4 +1,4 @@
-/* $Id: Modesetting.cpp $ */
+/* $Id: Modesetting.cpp 35999 2011-02-16 17:38:01Z vboxsync $ */
/** @file
* VirtualBox Video driver, common code - HGSMI initialisation and helper
* functions.
@@ -84,38 +84,120 @@ RTDECL(int) VBoxHGSMISendViewInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
/**
* Set a video mode using port registers. This must be done for the first
* screen before every HGSMI modeset and also works when HGSM is not enabled.
- * @param cWidth the mode width
- * @param cHeight the mode height
- * @param cBPP the colour depth of the mode
- * @param cx the horizontal panning offset
- * @param cy the vertical panning offset
+ * @param cWidth the mode width
+ * @param cHeight the mode height
+ * @param cVirtWidth the mode pitch
+ * @param cBPP the colour depth of the mode
+ * @param fFlags flags for the mode. These will be or-ed with the
+ * default _ENABLED flag, so unless you are restoring
+ * a saved mode or have special requirements you can pass
+ * zero here.
+ * @param cx the horizontal panning offset
+ * @param cy the vertical panning offset
*/
RTDECL(void) VBoxVideoSetModeRegisters(uint16_t cWidth, uint16_t cHeight,
uint16_t cVirtWidth, uint16_t cBPP,
- uint16_t cx, uint16_t cy)
+ uint16_t fFlags, uint16_t cx,
+ uint16_t cy)
{
/* set the mode characteristics */
VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cWidth);
VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cHeight);
- VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIRT_WIDTH);
+ VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+ VBE_DISPI_INDEX_VIRT_WIDTH);
VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cVirtWidth);
VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cBPP);
/* enable the mode */
- VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
- VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
+ VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+ VBE_DISPI_INDEX_ENABLE);
+ VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA,
+ fFlags | VBE_DISPI_ENABLED);
/* Panning registers */
- VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_X_OFFSET);
+ VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+ VBE_DISPI_INDEX_X_OFFSET);
VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cx);
- VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_Y_OFFSET);
+ VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+ VBE_DISPI_INDEX_Y_OFFSET);
VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cy);
/** @todo read from the port to see if the mode switch was successful */
}
/**
+ * Get the video mode for the first screen using the port registers. All
+ * parameters are optional
+ * @returns true if the VBE mode returned is active, false if we are in VGA
+ * mode
+ * @note If anyone else needs additional register values just extend the
+ * function with additional parameters and fix any existing callers.
+ * @param pcWidth where to store the mode width
+ * @param pcHeight where to store the mode height
+ * @param pcVirtWidth where to store the mode pitch
+ * @param pcBPP where to store the colour depth of the mode
+ * @param pfFlags where to store the flags for the mode
+ */
+RTDECL(bool) VBoxVideoGetModeRegisters(uint16_t *pcWidth, uint16_t *pcHeight,
+ uint16_t *pcVirtWidth, uint16_t *pcBPP,
+ uint16_t *pfFlags)
+{
+ uint16_t fFlags;
+
+ VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+ VBE_DISPI_ENABLED);
+ fFlags = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
+ if (pcWidth)
+ {
+ VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+ VBE_DISPI_INDEX_XRES);
+ *pcWidth = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
+ }
+ if (pcHeight)
+ {
+ VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+ VBE_DISPI_INDEX_YRES);
+ *pcHeight = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
+ }
+ if (pcVirtWidth)
+ {
+ VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+ VBE_DISPI_INDEX_VIRT_WIDTH);
+ *pcVirtWidth = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
+ }
+ if (pcBPP)
+ {
+ VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+ VBE_DISPI_INDEX_BPP);
+ *pcBPP = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
+ }
+ if (pfFlags)
+ *pfFlags = fFlags;
+ return RT_BOOL(fFlags & VBE_DISPI_ENABLED);
+}
+
+
+/**
+ * Get the video mode for the first screen using the port registers. All
+ * parameters are optional
+ * @note If anyone else needs additional values just extend the function with
+ * additional parameters and fix any existing callers.
+ * @param pcWidth where to store the mode width
+ * @param pcHeight where to store the mode height
+ * @param pcVirtWidth where to store the mode pitch
+ * @param pcBPP where to store the colour depth of the mode
+ * @param pfFlags where to store the flags for the mode
+ */
+RTDECL(void) VBoxVideoDisableVBE(void)
+{
+ VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+ VBE_DISPI_INDEX_ENABLE);
+ VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, 0);
+}
+
+
+/**
* Set a video mode via an HGSMI request. The views must have been
* initialised first using @a VBoxHGSMISendViewInfo and if the mode is being
* set on the first display then it must be set first using registers.
diff --git a/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp b/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp
index 5f481049c..e29186999 100644
--- a/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp
+++ b/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBVABase.cpp $ */
+/* $Id: VBVABase.cpp 35398 2011-01-04 09:39:07Z vboxsync $ */
/** @file
* VirtualBox Video driver, common code - VBVA initialisation and helper
* functions.
diff --git a/src/VBox/Additions/common/crOpenGL/Makefile.kmk b/src/VBox/Additions/common/crOpenGL/Makefile.kmk
index e4f3092a5..13498c054 100644
--- a/src/VBox/Additions/common/crOpenGL/Makefile.kmk
+++ b/src/VBox/Additions/common/crOpenGL/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35578 2011-01-16 19:39:38Z vboxsync $
## @file
# Sub-Makefile for the VirtualBox Guest OpenGL part
#
diff --git a/src/VBox/Additions/common/crOpenGL/VBoxCROGL.rc b/src/VBox/Additions/common/crOpenGL/VBoxCROGL.rc
index fe7f561bf..f5240bf22 100644
--- a/src/VBox/Additions/common/crOpenGL/VBoxCROGL.rc
+++ b/src/VBox/Additions/common/crOpenGL/VBoxCROGL.rc
@@ -1,4 +1,4 @@
-/* $Id: VBoxCROGL.rc $ */
+/* $Id: VBoxCROGL.rc 35319 2010-12-24 15:42:36Z vboxsync $ */
/** @file
* VBoxCROGL - Resource file containing version info and icon.
*/
diff --git a/src/VBox/Additions/common/crOpenGL/array/arrayspu.rc b/src/VBox/Additions/common/crOpenGL/array/arrayspu.rc
index 19972f35b..bff467cf2 100644
--- a/src/VBox/Additions/common/crOpenGL/array/arrayspu.rc
+++ b/src/VBox/Additions/common/crOpenGL/array/arrayspu.rc
@@ -1,4 +1,4 @@
-/* $Id: arrayspu.rc $ */
+/* $Id: arrayspu.rc 35319 2010-12-24 15:42:36Z vboxsync $ */
/** @file
* VBoxOGLarrayspu.so - Resource file containing version info and icon.
*/
diff --git a/src/VBox/Additions/common/crOpenGL/context.c b/src/VBox/Additions/common/crOpenGL/context.c
index 1bb3afc92..f77ea413d 100644
--- a/src/VBox/Additions/common/crOpenGL/context.c
+++ b/src/VBox/Additions/common/crOpenGL/context.c
@@ -496,8 +496,8 @@ InstantiateNativeContext( WindowInfo *window, ContextInfo *context )
#ifdef WINDOWS
void
-stubGetWindowGeometry( const WindowInfo *window, int *x, int *y,
- unsigned int *w, unsigned int *h )
+stubGetWindowGeometry(const WindowInfo *window, int *x, int *y,
+ unsigned int *w, unsigned int *h )
{
RECT rect;
@@ -1132,6 +1132,9 @@ stubDestroyContext( unsigned long contextId )
if (!stub.contextTable) {
return;
}
+
+ crHashtableLock(stub.contextTable);
+
context = (ContextInfo *) crHashtableSearch(stub.contextTable, contextId);
CRASSERT(context);
@@ -1166,8 +1169,9 @@ stubDestroyContext( unsigned long contextId )
crMemZero(context, sizeof(ContextInfo)); /* just to be safe */
crHashtableDelete(stub.contextTable, contextId, crFree);
-}
+ crHashtableUnlock(stub.contextTable);
+}
void
stubSwapBuffers(WindowInfo *window, GLint flags)
diff --git a/src/VBox/Additions/common/crOpenGL/dri_drv.c b/src/VBox/Additions/common/crOpenGL/dri_drv.c
index d19b99b1c..55734ccf3 100644
--- a/src/VBox/Additions/common/crOpenGL/dri_drv.c
+++ b/src/VBox/Additions/common/crOpenGL/dri_drv.c
@@ -1,4 +1,4 @@
-/* $Id: dri_drv.c $ */
+/* $Id: dri_drv.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBox OpenGL DRI driver functions
diff --git a/src/VBox/Additions/common/crOpenGL/dri_drv.h b/src/VBox/Additions/common/crOpenGL/dri_drv.h
index 9ee57766c..13b5b0b9d 100644
--- a/src/VBox/Additions/common/crOpenGL/dri_drv.h
+++ b/src/VBox/Additions/common/crOpenGL/dri_drv.h
@@ -1,4 +1,4 @@
-/* $Id: dri_drv.h $ */
+/* $Id: dri_drv.h 32404 2010-09-10 13:17:42Z vboxsync $ */
/** @file
*
diff --git a/src/VBox/Additions/common/crOpenGL/dri_glx.h b/src/VBox/Additions/common/crOpenGL/dri_glx.h
index a2a389701..366417a35 100644
--- a/src/VBox/Additions/common/crOpenGL/dri_glx.h
+++ b/src/VBox/Additions/common/crOpenGL/dri_glx.h
@@ -1,4 +1,4 @@
-/* $Id: dri_glx.h $ */
+/* $Id: dri_glx.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
*
diff --git a/src/VBox/Additions/common/crOpenGL/fakedri_drv.c b/src/VBox/Additions/common/crOpenGL/fakedri_drv.c
index 422250fe5..3159e9eb4 100644
--- a/src/VBox/Additions/common/crOpenGL/fakedri_drv.c
+++ b/src/VBox/Additions/common/crOpenGL/fakedri_drv.c
@@ -1,4 +1,4 @@
-/* $Id: fakedri_drv.c $ */
+/* $Id: fakedri_drv.c 37594 2011-06-22 16:26:29Z vboxsync $ */
/** @file
* VBox OpenGL DRI driver functions
@@ -37,10 +37,10 @@
//@todo this could be different...
#ifdef RT_ARCH_AMD64
-# define DRI_DEFAULT_DRIVER_DIR "/usr/lib64/dri:/usr/lib/dri"
+# define DRI_DEFAULT_DRIVER_DIR "/usr/lib64/dri:/usr/lib/dri:/usr/lib/x86_64-linux-gnu/dri"
# define DRI_XORG_DRV_DIR "/usr/lib/xorg/modules/drivers/"
#else
-# define DRI_DEFAULT_DRIVER_DIR "/usr/lib/dri"
+# define DRI_DEFAULT_DRIVER_DIR "/usr/lib/dri:/usr/lib/i386-linux-gnu/dri"
# define DRI_XORG_DRV_DIR "/usr/lib/xorg/modules/drivers/"
#endif
diff --git a/src/VBox/Additions/common/crOpenGL/fakedri_drv.h b/src/VBox/Additions/common/crOpenGL/fakedri_drv.h
index 0d94e1c3a..2fff8be8a 100644
--- a/src/VBox/Additions/common/crOpenGL/fakedri_drv.h
+++ b/src/VBox/Additions/common/crOpenGL/fakedri_drv.h
@@ -1,4 +1,4 @@
-/* $Id: fakedri_drv.h $ */
+/* $Id: fakedri_drv.h 32404 2010-09-10 13:17:42Z vboxsync $ */
/** @file
*
diff --git a/src/VBox/Additions/common/crOpenGL/fakedri_glfuncsList.h b/src/VBox/Additions/common/crOpenGL/fakedri_glfuncsList.h
index ce5510f51..8caeef2d7 100644
--- a/src/VBox/Additions/common/crOpenGL/fakedri_glfuncsList.h
+++ b/src/VBox/Additions/common/crOpenGL/fakedri_glfuncsList.h
@@ -1,4 +1,4 @@
-/* $Id: fakedri_glfuncsList.h $ */
+/* $Id: fakedri_glfuncsList.h 35039 2010-12-13 17:37:15Z vboxsync $ */
/** @file
* VBox OpenGL list of opengl functions common in Mesa and vbox opengl stub
diff --git a/src/VBox/Additions/common/crOpenGL/fakedri_glxfuncsList.h b/src/VBox/Additions/common/crOpenGL/fakedri_glxfuncsList.h
index c1592cdf1..34ce69304 100644
--- a/src/VBox/Additions/common/crOpenGL/fakedri_glxfuncsList.h
+++ b/src/VBox/Additions/common/crOpenGL/fakedri_glxfuncsList.h
@@ -1,4 +1,4 @@
-/* $Id: fakedri_glxfuncsList.h $ */
+/* $Id: fakedri_glxfuncsList.h 32404 2010-09-10 13:17:42Z vboxsync $ */
/** @file
* VBox OpenGL list of opengl functions common in Mesa and vbox opengl stub
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c b/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c
index e285e585c..630c12708 100644
--- a/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c
@@ -1,4 +1,4 @@
-/* $Id: feedback_context.c $ */
+/* $Id: feedback_context.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox feedback spu, context tracking.
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.rc b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.rc
index 36f5fa54d..64dbaddc9 100644
--- a/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.rc
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.rc
@@ -1,4 +1,4 @@
-/* $Id: feedbackspu.rc $ */
+/* $Id: feedbackspu.rc 35319 2010-12-24 15:42:36Z vboxsync $ */
/** @file
* VBoxOGLfeedbackspu - Resource file containing version info and icon.
*/
diff --git a/src/VBox/Additions/common/crOpenGL/glx.c b/src/VBox/Additions/common/crOpenGL/glx.c
index bfd727cff..8dc50479b 100644
--- a/src/VBox/Additions/common/crOpenGL/glx.c
+++ b/src/VBox/Additions/common/crOpenGL/glx.c
@@ -681,7 +681,11 @@ DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrent)( Display *dpy, GLXDrawable drawable,
}
}
- if (ctx && drawable) {
+ if (ctx && drawable)
+ {
+ crHashtableLock(stub.windowTable);
+ crHashtableLock(stub.contextTable);
+
context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) ctx);
window = stubGetWindowInfo(dpy, drawable);
@@ -691,7 +695,8 @@ DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrent)( Display *dpy, GLXDrawable drawable,
XUNLOCK(dpy);
}
}
- else {
+ else
+ {
dpy = NULL;
window = NULL;
context = NULL;
@@ -701,6 +706,13 @@ DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrent)( Display *dpy, GLXDrawable drawable,
currentDrawable = drawable;
retVal = stubMakeCurrent(window, context);
+
+ if (ctx && drawable)
+ {
+ crHashtableUnlock(stub.contextTable);
+ crHashtableUnlock(stub.windowTable);
+ }
+
return retVal;
}
diff --git a/src/VBox/Additions/common/crOpenGL/glx_c_exports.c b/src/VBox/Additions/common/crOpenGL/glx_c_exports.c
index 4f94870ae..cb6f645e0 100644
--- a/src/VBox/Additions/common/crOpenGL/glx_c_exports.c
+++ b/src/VBox/Additions/common/crOpenGL/glx_c_exports.c
@@ -1,4 +1,4 @@
-/* $Id: glx_c_exports.c $ */
+/* $Id: glx_c_exports.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
*
* VirtualBox guest OpenGL DRI GLX C stubs
diff --git a/src/VBox/Additions/common/crOpenGL/glx_proto.h b/src/VBox/Additions/common/crOpenGL/glx_proto.h
index 2ab6d05cb..63b5dda4b 100644
--- a/src/VBox/Additions/common/crOpenGL/glx_proto.h
+++ b/src/VBox/Additions/common/crOpenGL/glx_proto.h
@@ -1,4 +1,4 @@
-/* $Id: glx_proto.h $ */
+/* $Id: glx_proto.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
*
* VirtualBox guest OpenGL DRI GLX header C prototypes
diff --git a/src/VBox/Additions/common/crOpenGL/icd_drv.c b/src/VBox/Additions/common/crOpenGL/icd_drv.c
index 8a8c6a7a8..14b896986 100644
--- a/src/VBox/Additions/common/crOpenGL/icd_drv.c
+++ b/src/VBox/Additions/common/crOpenGL/icd_drv.c
@@ -1,4 +1,4 @@
-/* $Id: icd_drv.c $ */
+/* $Id: icd_drv.c 37986 2011-07-15 15:14:35Z vboxsync $ */
/** @file
* VBox OpenGL windows ICD driver functions
@@ -94,19 +94,23 @@ PICDTABLE APIENTRY DrvSetContext(HDC hdc, HGLRC hglrc, void *callback)
{
ContextInfo *context;
WindowInfo *window;
+ BOOL ret;
/*crDebug( "DrvSetContext called(0x%x, 0x%x)", hdc, hglrc );*/
(void) (callback);
+ crHashtableLock(stub.windowTable);
+ crHashtableLock(stub.contextTable);
+
context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc);
window = stubGetWindowInfo(hdc);
- if (stubMakeCurrent( window, context )) {
- return &icdTable;
- }
- else {
- return NULL;
- }
+ ret = stubMakeCurrent(window, context);
+
+ crHashtableUnlock(stub.contextTable);
+ crHashtableUnlock(stub.windowTable);
+
+ return ret ? &icdTable:NULL;
}
BOOL APIENTRY DrvSetPixelFormat(HDC hdc, int iPixelFormat)
@@ -291,8 +295,7 @@ BOOL APIENTRY DrvSwapLayerBuffers(HDC hdc, UINT fuPlanes)
{
if (fuPlanes == 1)
{
- DrvSwapBuffers(hdc);
- return 1;
+ return DrvSwapBuffers(hdc);
}
else
{
diff --git a/src/VBox/Additions/common/crOpenGL/icd_drv.h b/src/VBox/Additions/common/crOpenGL/icd_drv.h
index e610de150..a0109ea11 100644
--- a/src/VBox/Additions/common/crOpenGL/icd_drv.h
+++ b/src/VBox/Additions/common/crOpenGL/icd_drv.h
@@ -1,4 +1,4 @@
-/* $Id: icd_drv.h $ */
+/* $Id: icd_drv.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
diff --git a/src/VBox/Additions/common/crOpenGL/load.c b/src/VBox/Additions/common/crOpenGL/load.c
index 9d03f91cf..de41a43a8 100644
--- a/src/VBox/Additions/common/crOpenGL/load.c
+++ b/src/VBox/Additions/common/crOpenGL/load.c
@@ -33,8 +33,8 @@
#ifdef VBOX_WITH_WDDM
#include <d3d9types.h>
#include <D3dumddi.h>
-#include "../../WINNT/Graphics/Miniport/wddm/VBoxVideoIf.h"
-#include "../../WINNT/Graphics/Display/wddm/vboxdispmp.h"
+#include "../../WINNT/Graphics/Video/common/wddm/VBoxMPIf.h"
+#include "../../WINNT/Graphics/Video/disp/wddm/VBoxDispMp.h"
#endif
/**
@@ -857,6 +857,25 @@ static void stubSyncTrUpdateWindowCB(unsigned long key, void *data1, void *data2
if (hNewRgn!=INVALID_HANDLE_VALUE)
{
+ if (pRegions->pRegions->fFlags.bSetVisibleRects)
+ {
+ HRGN hEmptyRgn = CreateRectRgn(0, 0, 0, 0);
+
+ if (hEmptyRgn!=INVALID_HANDLE_VALUE)
+ {
+ if (pWindow->hVisibleRegion==INVALID_HANDLE_VALUE || EqualRgn(pWindow->hVisibleRegion, hEmptyRgn))
+ {
+ SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0, SMTO_NORMAL, 1000, NULL);
+ }
+
+ DeleteObject(hEmptyRgn);
+ }
+ else
+ {
+ crWarning("Failed to created empty region!");
+ }
+ }
+
OffsetRgn(hNewRgn, -pWindow->x, -pWindow->y);
if (pWindow->hVisibleRegion!=INVALID_HANDLE_VALUE)
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu.rc b/src/VBox/Additions/common/crOpenGL/pack/packspu.rc
index 4b4961087..337538c26 100644
--- a/src/VBox/Additions/common/crOpenGL/pack/packspu.rc
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu.rc
@@ -1,4 +1,4 @@
-/* $Id: packspu.rc $ */
+/* $Id: packspu.rc 35319 2010-12-24 15:42:36Z vboxsync $ */
/** @file
* VBoxOGLpackspu.so - Resource file containing version info and icon.
*/
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c
index 0f08a129e..a273c6743 100644
--- a/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c
@@ -596,6 +596,13 @@ void PACKSPU_APIENTRY packspu_LockArraysEXT(GLint first, GLint count)
void PACKSPU_APIENTRY packspu_UnlockArraysEXT()
{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (clientState->array.locked && clientState->array.synced)
+ {
+ crPackUnlockArraysEXT();
+ }
+
crStateUnlockArraysEXT();
- crPackUnlockArraysEXT();
}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c
index 4c010f35a..c7dd95ec4 100644
--- a/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c
@@ -1,4 +1,4 @@
-/* $Id: packspu_framebuffer.c $ */
+/* $Id: packspu_framebuffer.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox OpenGL FBO related functions
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py
index b496c9d5e..6c6872844 100644
--- a/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py
@@ -114,10 +114,17 @@ for func_name in keys:
#ifdef CR_ARB_texture_cube_map
|| pname == GL_TEXTURE_BINDING_CUBE_MAP_ARB
#endif
+#ifdef CR_ARB_vertex_program
+ || pname == GL_MAX_VERTEX_ATTRIBS_ARB
+#endif
)
{
#ifdef DEBUG
- if (!crPackIsPixelStoreParm(pname))
+ if (!crPackIsPixelStoreParm(pname)
+#ifdef CR_ARB_vertex_program
+ && (pname!=GL_MAX_VERTEX_ATTRIBS_ARB)
+#endif
+ )
{
%s localparams;
localparams = (%s) crAlloc(__numValues(pname) * sizeof(*localparams));
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c
index ef30f6868..694fcf642 100644
--- a/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c
@@ -1,4 +1,4 @@
-/* $Id: packspu_getshaders.c $ */
+/* $Id: packspu_getshaders.c 37157 2011-05-19 14:53:33Z vboxsync $ */
/** @file
* VBox OpenGL GLSL related functions
@@ -207,5 +207,11 @@ void PACKSPU_APIENTRY packspu_GetShaderSource(GLuint shader, GLsizei bufSize, GL
if (length) *length=*pLocal;
crMemcpy(source, &pLocal[1], (bufSize >= pLocal[0]) ? pLocal[0] : bufSize);
+
+ if (bufSize > pLocal[0])
+ {
+ source[pLocal[0]] = 0;
+ }
+
crFree(pLocal);
}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c
index 02fc10582..0d9a480cd 100644
--- a/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c
@@ -9,6 +9,8 @@
#include "state/cr_statefuncs.h"
#include "cr_string.h"
#include "packspu_proto.h"
+#include "cr_mem.h"
+#include <locale.h>
static GLubyte gpszExtensions[10000];
#ifdef CR_OPENGL_VERSION_2_0
@@ -93,7 +95,7 @@ GetExtensions(void)
#ifdef WINDOWS
static bool packspuRunningUnderWine(void)
{
- return NULL != GetModuleHandle("wined3d.dll") || NULL != GetModuleHandle("wined3dwddm.dll");
+ return NULL != GetModuleHandle("wined3d.dll") || NULL != GetModuleHandle("wined3dwddm.dll") || NULL != GetModuleHandle("wined3dwddm-x86.dll");
}
#endif
@@ -115,8 +117,22 @@ const GLubyte * PACKSPU_APIENTRY packspu_GetString( GLenum name )
else
#endif
{
- float version = GetVersionString();
+ char *oldlocale;
+ float version;
+
+ oldlocale = setlocale(LC_NUMERIC, NULL);
+ oldlocale = crStrdup(oldlocale);
+ setlocale(LC_NUMERIC, "C");
+
+ version = GetVersionString();
sprintf((char*)ctx->glVersion, "%.1f Chromium %s", version, CR_VERSION_STRING);
+
+ if (oldlocale)
+ {
+ setlocale(LC_NUMERIC, oldlocale);
+ crFree(oldlocale);
+ }
+
return ctx->glVersion;
}
case GL_VENDOR:
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c
index 71295d15e..bf36b6d35 100644
--- a/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c
@@ -1,4 +1,4 @@
-/* $Id: packspu_glsl.c $ */
+/* $Id: packspu_glsl.c 33988 2010-11-11 13:03:17Z vboxsync $ */
/** @file
* VBox OpenGL GLSL related functions
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c
index 071f5297b..19f34fc90 100644
--- a/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c
@@ -103,10 +103,13 @@ void PACKSPU_APIENTRY packspu_Finish( void )
}
}
+#define PACK_FORCED_SYNC
+
void PACKSPU_APIENTRY packspu_Flush( void )
{
GET_THREAD(thread);
int writeback = 1;
+ int found=0;
if (!thread->bInjectThread)
{
@@ -125,29 +128,57 @@ void PACKSPU_APIENTRY packspu_Flush( void )
crLockMutex(&_PackMutex);
- /*Make sure we process commands in order they should appear, so flush thread being injected first*/
+ /*Make sure we process commands in order they should appear, so flush other threads first*/
for (i=0; i<MAX_THREADS; ++i)
{
if (pack_spu.thread[i].inUse
&& (thread != &pack_spu.thread[i]) && pack_spu.thread[i].netServer.conn
- && (pack_spu.thread[i].netServer.conn->u32ClientID == thread->netServer.conn->u32InjectClientID)
&& pack_spu.thread[i].packer && pack_spu.thread[i].packer->currentBuffer)
{
+#ifdef PACK_FORCED_SYNC
+ CRPackContext *pc = pack_spu.thread[i].packer;
+ unsigned char *data_ptr;
+
+ CR_GET_BUFFERED_POINTER( pc, 16 );
+ WRITE_DATA( 0, GLint, 16 );
+ WRITE_DATA( 4, GLenum, CR_WRITEBACK_EXTEND_OPCODE );
+ WRITE_NETWORK_POINTER( 8, (void *) &writeback );
+ WRITE_OPCODE( pc, CR_EXTEND_OPCODE );
+ CR_UNLOCK_PACKER_CONTEXT(pc);
+#endif
packspuFlush((void *) &pack_spu.thread[i]);
- break;
+
+ if (pack_spu.thread[i].netServer.conn->u32ClientID == thread->netServer.conn->u32InjectClientID)
+ {
+ found=1;
+ }
+
+#ifdef PACK_FORCED_SYNC
+ while (writeback)
+ crNetRecv();
+#endif
}
}
- if (i>=MAX_THREADS)
+ if (!found)
{
/*Thread we're supposed to inject commands for has been detached,
so there's nothing to sync with and we should just pass commands through our own connection.
*/
thread->netServer.conn->u32InjectClientID=0;
}
- crUnlockMutex(&_PackMutex);
+#ifdef PACK_FORCED_SYNC
+ writeback = 1;
+ crPackWriteback(&writeback);
+#endif
packspuFlush((void *) thread);
+
+#ifdef PACK_FORCED_SYNC
+ while (writeback)
+ crNetRecv();
+#endif
+ crUnlockMutex(&_PackMutex);
}
}
@@ -369,6 +400,15 @@ void PACKSPU_APIENTRY packspu_GetPixelMapusv( GLenum map, GLushort * values )
}
}
+void PACKSPU_APIENTRY packspu_ChromiumParameteriCR(GLenum target, GLint value)
+{
+ if (GL_SHARE_CONTEXT_RESOURCES_CR==target)
+ {
+ crStateShareContext(value);
+ }
+ crPackChromiumParameteriCR(target, value);
+}
+
#ifdef CHROMIUM_THREADSAFE
void PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(void)
{
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c
index ea8bd8796..f28fd7462 100644
--- a/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c
@@ -119,12 +119,8 @@ void packspuFlush(void *arg )
CRMessageOpcodes *hdr;
CRPackBuffer *buf;
-#ifdef CHROMIUM_THREADSAFE
- crLockMutex(&_PackMutex);
-#endif
-
/* we should _always_ pass a valid <arg> value */
- CRASSERT(thread);
+ CRASSERT(thread && thread->inUse);
#ifdef CHROMIUM_THREADSAFE
CR_LOCK_PACKER_CONTEXT(thread->packer);
#endif
@@ -151,7 +147,6 @@ void packspuFlush(void *arg )
crPackResetPointers(thread->packer);
#ifdef CHROMIUM_THREADSAFE
CR_UNLOCK_PACKER_CONTEXT(thread->packer);
- crUnlockMutex(&_PackMutex);
#endif
return;
}
@@ -182,7 +177,6 @@ void packspuFlush(void *arg )
#ifdef CHROMIUM_THREADSAFE
CR_UNLOCK_PACKER_CONTEXT(thread->packer);
- crUnlockMutex(&_PackMutex);
#endif
}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_special b/src/VBox/Additions/common/crOpenGL/pack/packspu_special
index ca61e0d3d..34f0c7c8a 100644
--- a/src/VBox/Additions/common/crOpenGL/pack/packspu_special
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_special
@@ -106,3 +106,4 @@ VBoxPackGetInjectID
VBoxPackSetInjectID
VBoxPackAttachThread
VBoxPackDetachThread
+ChromiumParameteriCR
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c
index b5c60aec5..342c96861 100644
--- a/src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c
@@ -1,4 +1,4 @@
-/* $Id: packspu_texture.c $ */
+/* $Id: packspu_texture.c 29298 2010-05-10 12:16:24Z vboxsync $ */
/** @file
* VBox OpenGL DRI driver functions
diff --git a/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.rc b/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.rc
index 9569ed3d6..2f0e60117 100644
--- a/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.rc
+++ b/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.rc
@@ -1,4 +1,4 @@
-/* $Id: passthroughspu.rc $ */
+/* $Id: passthroughspu.rc 35319 2010-12-24 15:42:36Z vboxsync $ */
/** @file
* VBoxOGLpassthroughspu - Resource file containing version info and icon.
*/
diff --git a/src/VBox/Additions/common/crOpenGL/stub.c b/src/VBox/Additions/common/crOpenGL/stub.c
index 25a6c457e..82d93ed7d 100644
--- a/src/VBox/Additions/common/crOpenGL/stub.c
+++ b/src/VBox/Additions/common/crOpenGL/stub.c
@@ -126,10 +126,10 @@ void APIENTRY crWindowDestroy( GLint window )
crHashtableSearch(stub.windowTable, (unsigned int) window);
if (winInfo && winInfo->type == CHROMIUM && stub.spu)
{
+ crHashtableLock(stub.windowTable);
+
stub.spu->dispatch_table.WindowDestroy( winInfo->spuWindow );
-#ifdef CR_NEWWINTRACK
- crLockMutex(&stub.mutex);
-#endif
+
#ifdef WINDOWS
if (winInfo->hVisibleRegion != INVALID_HANDLE_VALUE)
{
@@ -147,11 +147,10 @@ void APIENTRY crWindowDestroy( GLint window )
}
# endif
#endif
-#ifdef CR_NEWWINTRACK
- crUnlockMutex(&stub.mutex);
-#endif
crForcedFlush();
crHashtableDelete(stub.windowTable, window, crFree);
+
+ crHashtableUnlock(stub.windowTable);
}
}
diff --git a/src/VBox/Additions/common/crOpenGL/wgl.c b/src/VBox/Additions/common/crOpenGL/wgl.c
index 9e7b1a828..99a9c0aaa 100644
--- a/src/VBox/Additions/common/crOpenGL/wgl.c
+++ b/src/VBox/Additions/common/crOpenGL/wgl.c
@@ -361,8 +361,15 @@ BOOL WINAPI wglUseFontOutlinesW_prox( HDC hdc, DWORD first, DWORD count, DWORD l
BOOL WINAPI wglSwapLayerBuffers_prox( HDC hdc, UINT planes )
{
- crWarning( "wglSwapLayerBuffers: unsupported" );
- return 0;
+ if (planes == WGL_SWAP_MAIN_PLANE)
+ {
+ return wglSwapBuffers_prox(hdc);
+ }
+ else
+ {
+ crWarning( "wglSwapLayerBuffers: unsupported" );
+ return 0;
+ }
}
BOOL WINAPI wglChoosePixelFormatEXT_prox
diff --git a/src/VBox/Additions/common/pam/Makefile.kmk b/src/VBox/Additions/common/pam/Makefile.kmk
index cff82bb67..3d30ea769 100644
--- a/src/VBox/Additions/common/pam/Makefile.kmk
+++ b/src/VBox/Additions/common/pam/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 29058 2010-05-05 08:49:52Z vboxsync $
## @file
# Makefile for VBox PAM module for automated logons.
#
diff --git a/src/VBox/Additions/common/pam/pam_vbox.c b/src/VBox/Additions/common/pam/pam_vbox.c
index ddc822fbf..603a91e56 100644
--- a/src/VBox/Additions/common/pam/pam_vbox.c
+++ b/src/VBox/Additions/common/pam/pam_vbox.c
@@ -1,10 +1,10 @@
-/* $Id: pam_vbox.c $ */
+/* $Id: pam_vbox.c 36051 2011-02-22 11:55:10Z vboxsync $ */
/** @file
* pam_vbox - PAM module for auto logons.
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -209,8 +209,13 @@ static int pam_vbox_do_check(pam_handle_t *h)
}
else
{
+#ifdef _DEBUG
pam_vbox_log(h, "pam_vbox_do_check: credentials retrieved: user=%s, password=%s, domain=%s\n",
pszUsername, pszPassword, pszDomain);
+#else
+ pam_vbox_log(h, "pam_vbox_do_check: credentials retrieved: user=%s, password=XXX, domain=%s\n",
+ pszUsername, pszDomain);
+#endif
/* Fill credentials into PAM. */
pamrc = pam_set_item(h, PAM_USER, pszUsername);
if (pamrc != PAM_SUCCESS)
diff --git a/src/VBox/Additions/common/testcase/Makefile.kmk b/src/VBox/Additions/common/testcase/Makefile.kmk
index e2c478319..8fa7d1ff0 100644
--- a/src/VBox/Additions/common/testcase/Makefile.kmk
+++ b/src/VBox/Additions/common/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 32431 2010-09-11 18:02:17Z vboxsync $
## @file
# Sub-Makefile for the Cross Platform Guest Addition test cases.
#
diff --git a/src/VBox/Additions/common/testcase/tstPageFusion.cpp b/src/VBox/Additions/common/testcase/tstPageFusion.cpp
index b6dcc268c..1a2d60ab1 100644
--- a/src/VBox/Additions/common/testcase/tstPageFusion.cpp
+++ b/src/VBox/Additions/common/testcase/tstPageFusion.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstPageFusion.cpp $ */
+/* $Id: tstPageFusion.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* VBoxService - Guest page sharing testcase
*/
@@ -26,9 +26,10 @@
#include <iprt/string.h>
#include <iprt/initterm.h>
#include <VBox/VBoxGuestLib.h>
-#include <VBox/x86.h>
+#include <iprt/x86.h>
#include <stdio.h>
+
/*******************************************************************************
* Global Variables *
*******************************************************************************/
diff --git a/src/VBox/Additions/freebsd/Installer/vboxguest.sh b/src/VBox/Additions/freebsd/Installer/vboxguest.sh
index 85bec4e87..85bec4e87 100755..100644
--- a/src/VBox/Additions/freebsd/Installer/vboxguest.sh
+++ b/src/VBox/Additions/freebsd/Installer/vboxguest.sh
diff --git a/src/VBox/Additions/freebsd/Makefile.kmk b/src/VBox/Additions/freebsd/Makefile.kmk
index c31c3ccbb..bab1dda0a 100644
--- a/src/VBox/Additions/freebsd/Makefile.kmk
+++ b/src/VBox/Additions/freebsd/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the FreeBSD guest additions base directory.
#
diff --git a/src/VBox/Additions/freebsd/drm/Makefile b/src/VBox/Additions/freebsd/drm/Makefile
index 15a581a4d..1022bb574 100644
--- a/src/VBox/Additions/freebsd/drm/Makefile
+++ b/src/VBox/Additions/freebsd/drm/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile $
+# $Id: Makefile 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Makefile for the VirtualBox FreeBSD Host Driver.
#
diff --git a/src/VBox/Additions/freebsd/drm/Makefile.kmk b/src/VBox/Additions/freebsd/drm/Makefile.kmk
index f9bf3da31..ae7c507bb 100644
--- a/src/VBox/Additions/freebsd/drm/Makefile.kmk
+++ b/src/VBox/Additions/freebsd/drm/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Sub-Makefile for the vboxvideo DRM module (FreeBSD kernel OpenGL module).
#
diff --git a/src/VBox/Additions/freebsd/drm/files_vboxvideo_drm b/src/VBox/Additions/freebsd/drm/files_vboxvideo_drm
index 67fdecb65..9d806b766 100755..100644
--- a/src/VBox/Additions/freebsd/drm/files_vboxvideo_drm
+++ b/src/VBox/Additions/freebsd/drm/files_vboxvideo_drm
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: files_vboxvideo_drm $
+# $Id: files_vboxvideo_drm 29250 2010-05-09 17:53:58Z vboxsync $
## @file
# Shared file between Makefile.kmk and export_modules
#
diff --git a/src/VBox/Additions/freebsd/drm/vboxvideo_drm.c b/src/VBox/Additions/freebsd/drm/vboxvideo_drm.c
index 2e2a91d80..163fba369 100644
--- a/src/VBox/Additions/freebsd/drm/vboxvideo_drm.c
+++ b/src/VBox/Additions/freebsd/drm/vboxvideo_drm.c
@@ -1,4 +1,4 @@
-/* $Id: vboxvideo_drm.c $ */
+/* $Id: vboxvideo_drm.c 28854 2010-04-27 19:41:12Z vboxsync $ */
/** @file
* VirtualBox Guest Additions - vboxvideo DRM module.
* FreeBSD kernel OpenGL module.
diff --git a/src/VBox/Additions/freebsd/vboxvfs/Makefile.kmk b/src/VBox/Additions/freebsd/vboxvfs/Makefile.kmk
index b605540e5..b3f855009 100644
--- a/src/VBox/Additions/freebsd/vboxvfs/Makefile.kmk
+++ b/src/VBox/Additions/freebsd/vboxvfs/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Sub-Makefile for the FreeBSD Shared folder kernel module.
#
diff --git a/src/VBox/Additions/freebsd/vboxvfs/vboxvfs.h b/src/VBox/Additions/freebsd/vboxvfs/vboxvfs.h
index 7c9b8f4d6..6d5d466d0 100644
--- a/src/VBox/Additions/freebsd/vboxvfs/vboxvfs.h
+++ b/src/VBox/Additions/freebsd/vboxvfs/vboxvfs.h
@@ -1,4 +1,4 @@
-/* $Id: vboxvfs.h $ */
+/* $Id: vboxvfs.h 31012 2010-07-22 15:55:04Z vboxsync $ */
/** @file
* Description.
*/
diff --git a/src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vfsops.c b/src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vfsops.c
index a9d9c14a3..a4292513b 100644
--- a/src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vfsops.c
+++ b/src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $Id: vboxvfs_vfsops.c $ */
+/* $Id: vboxvfs_vfsops.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Description.
*/
diff --git a/src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vnops.c b/src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vnops.c
index 575a55ed2..3e1d06506 100644
--- a/src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vnops.c
+++ b/src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vnops.c
@@ -1,4 +1,4 @@
-/* $Id: vboxvfs_vnops.c $ */
+/* $Id: vboxvfs_vnops.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Description.
*/
diff --git a/src/VBox/Additions/linux/Makefile.kmk b/src/VBox/Additions/linux/Makefile.kmk
index 6c51aa7e4..62c50a9dc 100644
--- a/src/VBox/Additions/linux/Makefile.kmk
+++ b/src/VBox/Additions/linux/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 38005 2011-07-18 10:17:43Z vboxsync $
## @file
# Makefile for the linux guest additions base directory.
#
@@ -322,39 +322,13 @@ lnx_add_inst-noexec_SOURCES = \
selinux-fedora/vbox_accel.pp
INSTALLS += lnx_add_inst-license
-lnx_add_inst-license_INST = $(subst $(PATH_TARGET),obj,$(VBOX_LNX_ADD_INST_OUT_DIR))/
+lnx_add_inst-license_INST = $(subst $(PATH_TARGET),obj,$(VBOX_LNX_ADD_INST_OUT_DIR))
lnx_add_inst-license_MODE = a+r,u+w
lnx_add_inst-license_SOURCES = \
$(VBOX_BRAND_LICENSE_TXT)=>LICENSE
#
-# Install the sources of our (sanity) test kernel module
-#
-INSTALLS += LnxAddTest-src
-LnxAddTest-src_INST = $(subst $(PATH_TARGET),obj,$(VBOX_LNX_ADD_INST_SHARE_DIR)$(VBOX_LNX_ADD_PACKAGE_NAME))/test/
-LnxAddTest-src_MODE = a+r,u+w
-LnxAddTest-src_SOURCES = \
- $(VBOX_REL_LNX_ADD_INST)Makefile.test=>Makefile \
- $(PATH_BIN)/additions/src/vboxguest/build_in_tmp \
- $(VBOX_REL_LNX_ADD_INST)test.c
-
-
-#
-# Install the sources of our (sanity) test kernel rendering (DRM) module
-#
-INSTALLS += LnxAddDRM-src
-LnxAddDRM-src_INST = $(subst $(PATH_TARGET),obj,$(VBOX_LNX_ADD_INST_SHARE_DIR)$(VBOX_LNX_ADD_PACKAGE_NAME))/test_drm/
-LnxAddDRM-src_MODE = a+r,u+w
-LnxAddDRM-src_SOURCES = \
- $(VBOX_REL_LNX_ADD_INST)Makefile.include.header \
- $(VBOX_REL_LNX_ADD_INST)Makefile.include.footer \
- $(VBOX_REL_LNX_ADD_INST)Makefile.test.drm=>Makefile \
- $(PATH_BIN)/additions/src/vboxguest/build_in_tmp \
- $(VBOX_REL_LNX_ADD_INST)test_drm.c
-
-
-#
# We need our routines.sh and the uninstallation scripts in the staging
# directory too
#
@@ -383,7 +357,7 @@ LnxAdd-Nostrip-Bin_SOURCES = \
# And the init scripts
#
INSTALLS += LnxAdd-init-scripts
-LnxAdd-init-scripts_INST = bin/additions
+LnxAdd-init-scripts_INST = $(INST_ADDITIONS)
LnxAdd-init-scripts_MODE = a+rx,u+w
LnxAdd-init-scripts_SOURCES = \
$(foreach i,$(VBOX_LNX_ADD_INIT), installer/$(i).sh=>$(i))
diff --git a/src/VBox/Additions/linux/drm/Makefile.kmk b/src/VBox/Additions/linux/drm/Makefile.kmk
index 6fc51e3c9..8dae9fbcf 100644
--- a/src/VBox/Additions/linux/drm/Makefile.kmk
+++ b/src/VBox/Additions/linux/drm/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Sub-Makefile for the vboxvideo DRM module (linux kernel OpenGL module).
#
diff --git a/src/VBox/Additions/linux/drm/Makefile.module b/src/VBox/Additions/linux/drm/Makefile.module
index 5611df78f..c382be7bd 100644
--- a/src/VBox/Additions/linux/drm/Makefile.module
+++ b/src/VBox/Additions/linux/drm/Makefile.module
@@ -14,231 +14,33 @@
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
-## @todo We must make this into a common template *soon*.
+# Linux kbuild sets this to our source directory if we are called from there
+obj ?= $(CURDIR)
+include $(obj)/Makefile.include.header
-#
-# First, figure out which architecture we're targeting and the build type.
-# (We have to support basic cross building (ARCH=i386|x86_64).)
-# While at it, warn about BUILD_* vars found to help with user problems.
-#
-ifeq ($(filter-out x86_64 amd64 AMD64,$(shell uname -m)),)
- BUILD_TARGET_ARCH_DEF := amd64
-else
- BUILD_TARGET_ARCH_DEF := x86
-endif
-ifneq ($(filter-out amd64 x86,$(BUILD_TARGET_ARCH)),)
- $(warning Ignoring unknown BUILD_TARGET_ARCH value '$(BUILD_TARGET_ARCH)'.)
- BUILD_TARGET_ARCH :=
-endif
-ifeq ($(BUILD_TARGET_ARCH),)
- ifeq ($(ARCH),x86_64)
- BUILD_TARGET_ARCH := amd64
- else
- ifeq ($(ARCH),i386)
- BUILD_TARGET_ARCH := x86
- else
- BUILD_TARGET_ARCH := $(BUILD_TARGET_ARCH_DEF)
- endif
- endif
-else
- ifneq ($(BUILD_TARGET_ARCH),$(BUILD_TARGET_ARCH_DEF))
- $(warning Using BUILD_TARGET_ARCH='$(BUILD_TARGET_ARCH)' from the $(origin BUILD_TARGET_ARCH).)
- endif
-endif
-
-ifneq ($(filter-out release profile debug strict,$(BUILD_TYPE)),)
- $(warning Ignoring unknown BUILD_TYPE value '$(BUILD_TYPE)'.)
- BUILD_TYPE :=
-endif
-ifeq ($(BUILD_TYPE),)
- BUILD_TYPE := release
-else
- ifneq ($(BUILD_TYPE),release)
- $(warning Using BUILD_TYPE='$(BUILD_TYPE)' from the $(origin BUILD_TYPE).)
- endif
-endif
-
-EXTRA_CFLAGS = -fshort-wchar
-
-ifneq ($(MAKECMDGOALS),clean)
-
-ifeq ($(KERNELRELEASE),)
+MOD_NAME = vboxvideo
- #
- # building from this directory
- #
+MOD_OBJS = vboxvideo_drm.o
- # kernel base directory
- ifndef KERN_DIR
- KERN_DIR := /lib/modules/$(shell uname -r)/build
- ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
- KERN_DIR := /usr/src/linux
- ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
- $(error Error: unable to find the sources of your current Linux kernel. \
- Specify KERN_DIR=<directory> and run Make again)
- endif
- $(warning Warning: using /usr/src/linux as the source directory of your \
- Linux kernel. If this is not correct, specify \
- KERN_DIR=<directory> and run Make again.)
- endif
- else
- ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
- $(error Error: KERN_DIR does not point to a directory)
- endif
- endif
-
- # includes
- ifndef KERN_INCL
- KERN_INCL = $(KERN_DIR)/include
- endif
- ifneq ($(shell if test -d $(KERN_INCL); then echo yes; fi),yes)
- $(error Error: unable to find the include directory for your current Linux \
- kernel. Specify KERN_INCL=<directory> and run Make again)
- endif
-
- # module install dir.
- ifneq ($(filter install install_rpm,$(MAKECMDGOALS)),)
- ifndef MODULE_DIR
- MODULE_DIR_TST := /lib/modules/$(shell uname -r)
- ifeq ($(shell if test -d $(MODULE_DIR_TST); then echo yes; fi),yes)
- MODULE_DIR := $(MODULE_DIR_TST)/misc
- else
- $(error Unable to find the folder to install the DRM driver to)
- endif
- endif # MODULE_DIR unspecified
- endif
-
- # guess kernel version (24 or 26)
- ifeq ($(shell if grep '"2\.4\.' $(KERN_INCL)/linux/version.h > /dev/null; then echo yes; fi),yes)
- KERN_VERSION := 24
- else
- KERN_VERSION := 26
- endif
-
-else # neq($(KERNELRELEASE),)
-
- #
- # building from kbuild (make -C <kernel_directory> M=`pwd`)
- #
-
- # guess kernel version (24 or 26)
- ifeq ($(shell if echo "$(VERSION).$(PATCHLEVEL)." | grep '2\.4\.' > /dev/null; then echo yes; fi),yes)
- KERN_VERSION := 24
- else
- KERN_VERSION := 26
- endif
-
-endif # neq($(KERNELRELEASE),)
-
-# debug - show guesses.
-ifdef DEBUG
-$(warning dbg: KERN_DIR = $(KERN_DIR))
-$(warning dbg: KERN_INCL = $(KERN_INCL))
-$(warning dbg: MODULE_DIR = $(MODULE_DIR))
-$(warning dbg: KERN_VERSION = $(KERN_VERSION))
-endif
-
-KBUILD_VERBOSE ?= 1
-
-#
-# Compiler options
-#
-ifndef INCL
- INCL := $(addprefix -I,$(KERN_INCL) $(EXTRA_INCL))
- ifndef KBUILD_EXTMOD
- KBUILD_EXTMOD := $(shell pwd)
- endif
- INCL += $(addprefix -I$(KBUILD_EXTMOD),/ /include /r0drv/linux)
- INCL += $(addprefix -I$(KBUILD_EXTMOD)/vboxvideo,/ /include /r0drv/linux)
- export INCL
-endif
ifneq ($(wildcard $(KBUILD_EXTMOD)/vboxvideo),)
MANGLING := $(KBUILD_EXTMOD)/vboxvideo/include/VBox/VBoxGuestMangling.h
else
MANGLING := $(KBUILD_EXTMOD)/include/VBox/VBoxGuestMangling.h
endif
-KFLAGS := -D__KERNEL__ -DMODULE -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 \
- -DIN_SUP_R0 -DVBOX -DVBOX_WITH_HGCM -DLOG_TO_BACKDOOR -DIN_MODULE \
- -DIN_GUEST_R0
+MOD_CFLAGS = -fshort-wchar -include $(MANGLING)
+MOD_INCL = $(addprefix -I$(KBUILD_EXTMOD),/ /include /r0drv/linux)
+# What on earth is this?
+MOD_INCL += $(addprefix -I$(KBUILD_EXTMOD)/vboxvideo,/ /include /r0drv/linux)
+MOD_DEFS := -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 \
+ -DIN_SUP_R0 -DVBOX -DVBOX_WITH_HGCM -DLOG_TO_BACKDOOR -DIN_MODULE \
+ -DIN_GUEST_R0
# our module does not export any symbol
-KFLAGS += -DRT_NO_EXPORT_SYMBOL
+MOD_DEFS += -DRT_NO_EXPORT_SYMBOL
ifeq ($(BUILD_TARGET_ARCH),amd64)
- KFLAGS += -DRT_ARCH_AMD64 -DVBOX_WITH_64_BITS_GUESTS
+ MOD_DEFS += -DRT_ARCH_AMD64 -DVBOX_WITH_64_BITS_GUESTS
else
- KFLAGS += -DRT_ARCH_X86
-endif
-ifeq ($(BUILD_TYPE),debug)
-KFLAGS += -DDEBUG
+ MOD_DEFS += -DRT_ARCH_X86
endif
+MOD_CLEAN = . linux r0drv r0drv/linux
-# override is required by the Debian guys
-override MODULE = vboxvideo
-OBJS = vboxvideo_drm.o
-
-ifeq ($(KERN_VERSION), 24)
-#
-# 2.4
-#
-
-CFLAGS := -O2 -DVBOX_LINUX_2_4 $(INCL) $(KFLAGS) $(KDEBUG)
-MODULE_EXT := o
-
-# 2.4 Module linking
-$(MODULE).o: $(OBJS)
- $(LD) -o $@ -r $(OBJS)
-
-.PHONY: $(MODULE)
-all: $(MODULE)
-$(MODULE): $(MODULE).o
-
-else
-#
-# 2.6 and later
-#
-
-MODULE_EXT := ko
-
-$(MODULE)-y := $(OBJS)
-
-# special hack for Fedora Core 6 2.6.18 (fc6), rhel5 2.6.18 (el5),
-# ClarkConnect 4.3 (cc4) and ClarkConnect 5 (v5)
-ifeq ($(KERNELRELEASE),)
- KFLAGS += $(foreach inc,$(KERN_INCL),\
- $(if $(wildcard $(inc)/linux/utsrelease.h),\
- $(if $(shell grep '"2.6.18.*fc6.*"' $(inc)/linux/utsrelease.h; \
- grep '"2.6.18.*el5.*"' $(inc)/linux/utsrelease.h; \
- grep '"2.6.18.*v5.*"' $(inc)/linux/utsrelease.h; \
- grep '"2.6.18.*cc4.*"' $(inc)/linux/utsrelease.h),\
- -DKERNEL_FC6,),))
-else
- KFLAGS += $(if $(shell echo "$(KERNELRELEASE)"|grep '2.6.18.*fc6.*';\
- echo "$(KERNELRELEASE)"|grep '2.6.18.*el5.*';\
- echo "$(KERNELRELEASE)"|grep '2.6.18.*v5.*';\
- echo "$(KERNELRELEASE)"|grep '2.6.18.*cc4.*'),\
- -DKERNEL_FC6,)
-endif
-
-# build defs
-EXTRA_CFLAGS += -include $(MANGLING) $(INCL) $(KFLAGS) $(KDEBUG)
-
-all: $(MODULE)
-
-obj-m += $(MODULE).o
-
-$(MODULE):
- $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C $(KERN_DIR) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) modules
-
-endif
-
-install: $(MODULE)
- @mkdir -p $(MODULE_DIR); \
- install -m 0664 -o root -g root $(MODULE).$(MODULE_EXT) $(MODULE_DIR); \
- PATH="$(PATH):/bin:/sbin" depmod -a;
-
-endif # eq($(MAKECMDGOALS),clean)
-
-# important: Don't remove Module.symvers! DKMS does 'make clean' before building ...
-clean:
- for f in . linux r0drv r0drv/linux; do rm -f $$f/*.o $$f/.*.cmd $$f/.*.flags; done
- rm -rf .vboxvideo* .tmp_ver* vboxvideo.* Modules.symvers modules.order
-
+include $(obj)/Makefile.include.footer
diff --git a/src/VBox/Additions/linux/drm/files_vboxvideo_drm b/src/VBox/Additions/linux/drm/files_vboxvideo_drm
index 038acc5cb..c27650459 100755..100644
--- a/src/VBox/Additions/linux/drm/files_vboxvideo_drm
+++ b/src/VBox/Additions/linux/drm/files_vboxvideo_drm
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: files_vboxvideo_drm $
+# $Id: files_vboxvideo_drm 37350 2011-06-07 13:44:25Z vboxsync $
## @file
# Shared file between Makefile.kmk and export_modules
#
@@ -21,6 +21,8 @@ FILES_VBOXVIDEO_DRM_NOBIN=" \
${PATH_ROOT}/include/VBox/VBoxGuestMangling.h=>include/VBox/VBoxGuestMangling.h \
${PATH_ROOT}/src/VBox/Additions/linux/drm/vboxvideo_drm.c=>vboxvideo_drm.c \
${PATH_ROOT}/src/VBox/Additions/linux/drm/vboxvideo_drm.h=>vboxvideo_drm.h \
+ ${PATH_ROOT}/src/VBox/Installer/linux/Makefile.include.header=>Makefile.include.header \
+ ${PATH_ROOT}/src/VBox/Installer/linux/Makefile.include.footer=>Makefile.include.footer \
${PATH_OUT}/version-generated.h=>version-generated.h \
${PATH_OUT}/product-generated.h=>product-generated.h \
${PATH_ROOT}/src/VBox/Additions/linux/drm/Makefile.module=>Makefile \
diff --git a/src/VBox/Additions/linux/drm/vboxvideo_drm.c b/src/VBox/Additions/linux/drm/vboxvideo_drm.c
index b335f76eb..4a0a89cd9 100644
--- a/src/VBox/Additions/linux/drm/vboxvideo_drm.c
+++ b/src/VBox/Additions/linux/drm/vboxvideo_drm.c
@@ -1,4 +1,4 @@
-/** @file $Id: vboxvideo_drm.c $
+/** @file $Id: vboxvideo_drm.c 37351 2011-06-07 13:45:11Z vboxsync $
*
* VirtualBox Additions Linux kernel driver, DRM support
*/
diff --git a/src/VBox/Additions/linux/drm/vboxvideo_drm.h b/src/VBox/Additions/linux/drm/vboxvideo_drm.h
index 0613a9d23..239d7ed6a 100644
--- a/src/VBox/Additions/linux/drm/vboxvideo_drm.h
+++ b/src/VBox/Additions/linux/drm/vboxvideo_drm.h
@@ -1,4 +1,4 @@
-/** @file $Id: vboxvideo_drm.h $
+/** @file $Id: vboxvideo_drm.h 28800 2010-04-27 08:22:32Z vboxsync $
*
* VirtualBox Additions Linux kernel driver, DRM support
*/
diff --git a/src/VBox/Additions/linux/installer/90-vboxguest.fdi b/src/VBox/Additions/linux/installer/90-vboxguest.fdi
index bb4ffba1b..4583a27cc 100644
--- a/src/VBox/Additions/linux/installer/90-vboxguest.fdi
+++ b/src/VBox/Additions/linux/installer/90-vboxguest.fdi
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
# Hal driver description for the vboxmouse driver
-# $Id: 90-vboxguest.fdi $
+# $Id: 90-vboxguest.fdi 32396 2010-09-10 12:22:20Z vboxsync $
Copyright (C) 2008-2010 Oracle Corporation
diff --git a/src/VBox/Additions/linux/installer/Makefile.include.header b/src/VBox/Additions/linux/installer/Makefile.include.header
deleted file mode 100644
index 5698240de..000000000
--- a/src/VBox/Additions/linux/installer/Makefile.include.header
+++ /dev/null
@@ -1,94 +0,0 @@
-#
-# VirtualBox Guest Additions kernel module Makefile, common parts.
-#
-# (For 2.6.x, the main file must be called 'Makefile'!)
-#
-# Copyright (C) 2006-2007 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.
-#
-
-#
-# These file should be included by the Makefiles for any kernel modules we
-# build as part of the Guest Additions. The intended way of doing this is as
-# follows:
-#
-# # Linux kbuild sets this to our source directory if we are called from
-# # there
-# obj ?= $(CURDIR)
-# include $(obj)/Makefile.include.header
-# MOD_NAME = <name of the module to be built, without extension>
-# MOD_OBJS = <list of object files which should be included>
-# MOD_FLAGS = <any additional CFLAGS which this module needs>
-# include $(obj)/Makefile.include.footer
-#
-# The kmk kBuild define KBUILD_TARGET_ARCH is available.
-#
-# @todo the shared folders module Makefile also includes the following bits.
-# Integrate them if necessary.
-# MOD_FLAGS += -DEXPORT_SYMTAB -DVBGL_VBOXGUEST -DRT_WITH_VBOX
-#
-# # special hack for Fedora Core 6 2.6.18 (fc6), rhel5 2.6.18 (el5),
-# # ClarkConnect 4.3 (cc4) and ClarkConnect 5 (v5)
-# ifeq ($(KERNELRELEASE),)
-# KFLAGS += $(foreach inc,$(KERN_INCL),\
-# $(if $(wildcard $(inc)/linux/utsrelease.h),\
-# $(if $(shell grep '"2.6.18.*fc6.*"' $(inc)/linux/utsrelease.h; \
-# grep '"2.6.18.*el5.*"' $(inc)/linux/utsrelease.h; \
-# grep '"2.6.18.*v5.*"' $(inc)/linux/utsrelease.h; \
-# grep '"2.6.18.*cc4.*"' $(inc)/linux/utsrelease.h),\
-# -DKERNEL_FC6,),))
-# else
-# KFLAGS += $(if $(shell echo "$(KERNELRELEASE)"|grep '2.6.18.*fc6.*';\
-# echo "$(KERNELRELEASE)"|grep '2.6.18.*el5.*';\
-# echo "$(KERNELRELEASE)"|grep '2.6.18.*v5.*';\
-# echo "$(KERNELRELEASE)"|grep '2.6.18.*cc4.*'),\
-# -DKERNEL_FC6,)
-# endif
-#
-## important: Don't remove Module.symvers! DKMS does 'make clean' before building ...
-# rm -rf .vboxsf* .tmp_ver* vboxsf.* Modules.symvers modules.order
-#
-
-#
-# First, figure out which architecture we're targeting and the build type.
-# (We have to support basic cross building (ARCH=i386|x86_64).)
-# While at it, warn about BUILD_* vars found to help with user problems.
-#
-ifneq ($(filter-out amd64 x86,$(BUILD_TARGET_ARCH)),)
- $(warning Ignoring unknown BUILD_TARGET_ARCH value '$(BUILD_TARGET_ARCH)'.)
- BUILD_TARGET_ARCH :=
-endif
-ifeq ($(BUILD_TARGET_ARCH),)
- ifeq ($(ARCH),x86_64)
- BUILD_TARGET_ARCH := amd64
- else
- ifeq ($(ARCH),i386)
- BUILD_TARGET_ARCH := x86
- else
- ifeq ($(filter-out x86_64 amd64 AMD64,$(shell uname -m)),)
- BUILD_TARGET_ARCH := amd64
- else
- BUILD_TARGET_ARCH := x86
- endif
- endif
- endif
-else
- $(warning Using BUILD_TARGET_ARCH='$(BUILD_TARGET_ARCH)' from the $(origin BUILD_TARGET_ARCH).)
-endif
-
-ifneq ($(filter-out release profile debug strict,$(BUILD_TYPE)),)
- $(warning Ignoring unknown BUILD_TYPE value '$(BUILD_TYPE)'.)
- BUILD_TYPE :=
-endif
-ifeq ($(BUILD_TYPE),)
- BUILD_TYPE := release
-else
- $(warning Using BUILD_TYPE='$(BUILD_TYPE)' from the $(origin BUILD_TYPE).)
-endif
diff --git a/src/VBox/Additions/linux/installer/Makefile.test b/src/VBox/Additions/linux/installer/Makefile.test
deleted file mode 100644
index ec32672cb..000000000
--- a/src/VBox/Additions/linux/installer/Makefile.test
+++ /dev/null
@@ -1,116 +0,0 @@
-#
-# VirtualBox Guest Additions Module Makefile.
-#
-# (For 2.6.x this file must be 'Makefile'!)
-#
-# Copyright (C) 2006-2010 Oracle Corporation
-#
-# Use only with permission
-#
-
-#
-MODULE = vboxadd_test
-OBJS = test.o
-
-ifneq ($(MAKECMDGOALS),clean)
-
-# kernel base directory
-ifndef KERN_DIR
- KERN_DIR := /lib/modules/$(shell uname -r)/build
- ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
- KERN_DIR := /usr/src/linux
- ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
- $(error Error: unable to find the sources of your current Linux kernel. Specify KERN_DIR=<directory> and run Make again.)
- endif
- $(warning Warning: using /usr/src/linux as the source directory of your Linux kernel. If this is not correct, specify KERN_DIR=<directory> and run Make again.)
- endif
-else
- ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
- $(error Error: KERN_DIR does not point to a directory.)
- endif
-endif
-
-# includes
-ifndef KERN_INCL
- KERN_INCL = $(KERN_DIR)/include
-endif
-ifneq ($(shell if test -d $(KERN_INCL); then echo yes; fi),yes)
- $(error Error: unable to find the include directory for your current Linux kernel. Specify KERN_INCL=<directory> and run Make again.)
-endif
-
-# guess kernel version (24 or 26)
-ifeq ($(shell if grep '"2.4.' $(KERN_INCL)/linux/version.h > /dev/null; then echo yes; fi),yes)
-KERN_VERSION := 24
-else
-KERN_VERSION := 26
-endif
-# KERN_VERSION := $(if $(wildcard $(KERN_DIR)/Rules.make),24,26)
-
-# debug - show guesses.
-ifdef DEBUG
-$(warning dbg: KERN_DIR = $(KERN_DIR))
-$(warning dbg: KERN_INCL = $(KERN_INCL))
-$(warning dbg: MODULE_DIR = $(MODULE_DIR))
-$(warning dbg: KERN_VERSION = $(KERN_VERSION))
-endif
-
-
-#
-# Compiler options
-#
-ifndef INCL
- INCL := -I$(KERN_INCL) $(addprefix -I, $(EXTRA_INCL))
- ifndef KBUILD_EXTMOD
- KBUILD_EXTMOD := $(shell pwd)
- endif
- INCL += $(addprefix -I$(KBUILD_EXTMOD),/ /include /r0drv/linux)
- export INCL
-endif
-KFLAGS := -D__KERNEL__ -DMODULE -DRT_OS_LINUX -DIN_RING0 -D_X86_ -DIN_RT_R0 -DIN_SUP_R0 \
- -DVBGL_VBOXGUEST -DVBGL_HGCM -DVBOX_WITH_HGCM
-ifeq ($(BUILD_TYPE),debug)
-KFLAGS += -DDEBUG
-endif
-
-ifeq ($(KERN_VERSION), 24)
-#
-# 2.4
-#
-
-CFLAGS := -DVBOX_LINUX_2_4 $(INCL) $(KFLAGS) $(KDEBUG)
-MODULE_EXT := o
-
-# 2.4 Module linking
-$(MODULE).o: $(OBJS)
- $(LD) -o $@ -r $(OBJS)
-
-.PHONY: $(MODULE)
-all: $(MODULE)
-$(MODULE): $(MODULE).o
-
-else
-#
-# 2.6 and later
-#
-
-MODULE_EXT := ko
-
-$(MODULE)-y := $(OBJS)
-
-# build defs
-EXTRA_CFLAGS += $(INCL) $(KFLAGS) $(KDEBUG)
-
-all: $(MODULE)
-
-obj-m += $(MODULE).o
-
-$(MODULE):
- $(MAKE) KBUILD_VERBOSE=1 -C $(KERN_DIR) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) modules
-
-endif
-
-endif # eq($(MAKECMDGOALS),clean)
-
-clean:
- for f in . linux r0drv r0drv/linux; do rm -f $$f/*.o $$f/.*.cmd $$f/.*.flags; done
- rm -rf .vboxdrv* .tmp_ver* vboxdrv.* Module.symvers Modules.symvers
diff --git a/src/VBox/Additions/linux/installer/Makefile.test.drm b/src/VBox/Additions/linux/installer/Makefile.test.drm
deleted file mode 100644
index 060a6915e..000000000
--- a/src/VBox/Additions/linux/installer/Makefile.test.drm
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# VirtualBox Guest Additions Module Makefile.
-#
-# (For 2.6.x this file must be 'Makefile'!)
-#
-# Copyright (C) 2006-2010 Oracle Corporation
-#
-#
-# Use only with permission
-#
-
-# Linux kbuild sets this to our source directory if we are called from there
-obj ?= $(CURDIR)
-
-include $(obj)/Makefile.include.header
-
-MOD_NAME = vboxadd_test_drm
-MOD_OBJS = test_drm.o
-# These are present in the shared folders Makefile but not the main one.
-# MOD_FLAGS = -DEXPORT_SYMTAB -DVBGL_VBOXGUEST -DRT_WITH_VBOX
-
-include $(obj)/Makefile.include.footer
diff --git a/src/VBox/Additions/linux/installer/autorun.sh b/src/VBox/Additions/linux/installer/autorun.sh
index 45afb034a..28997631f 100755..100644
--- a/src/VBox/Additions/linux/installer/autorun.sh
+++ b/src/VBox/Additions/linux/installer/autorun.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: autorun.sh $
+# $Id: autorun.sh 36759 2011-04-20 16:40:13Z vboxsync $
#
# VirtualBox Guest Additions installation script for *nix guests
#
diff --git a/src/VBox/Additions/linux/installer/deffiles b/src/VBox/Additions/linux/installer/deffiles
index 17b877849..17b877849 100755..100644
--- a/src/VBox/Additions/linux/installer/deffiles
+++ b/src/VBox/Additions/linux/installer/deffiles
diff --git a/src/VBox/Additions/linux/installer/vboxadd-service.sh b/src/VBox/Additions/linux/installer/vboxadd-service.sh
index 02016ee4a..02016ee4a 100755..100644
--- a/src/VBox/Additions/linux/installer/vboxadd-service.sh
+++ b/src/VBox/Additions/linux/installer/vboxadd-service.sh
diff --git a/src/VBox/Additions/linux/installer/vboxadd-x11.sh b/src/VBox/Additions/linux/installer/vboxadd-x11.sh
index 55e6ec640..285173ae1 100755..100644
--- 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: 71770 $)
+# Linux Additions X11 setup init script ($Revision: 37104 $)
#
#
diff --git a/src/VBox/Additions/linux/installer/vboxadd.sh b/src/VBox/Additions/linux/installer/vboxadd.sh
index 4f02c64c9..11732566d 100755..100644
--- 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: 71770 $)
+# Linux Additions kernel module init script ($Revision: 37160 $)
#
#
@@ -188,7 +188,9 @@ test_sane_kernel_dir()
if [ "$system" = "redhat" ]; then
printf "The missing package can be probably installed with\nyum install kernel-devel-$KERN_VER\n"
elif [ "$system" = "suse" ]; then
- printf "The missing package can be probably installed with\nzypper install kernel-$KERN_VER\n"
+ KERN_VER_SUSE=`echo "$KERN_VER" | sed 's/.*-\([^-]*\)/\1/g'`
+ KERN_VER_BASE=`echo "$KERN_VER" | sed 's/\(.*\)-[^-]*/\1/g'`
+ printf "The missing package can be probably installed with\nzypper install kernel-$KERN_VER_SUSE-devel-$KERN_VER_BASE\n"
elif [ "$system" = "debian" ]; then
printf "The missing package can be probably installed with\napt-get install linux-headers-$KERN_VER\n"
fi
@@ -271,7 +273,9 @@ do_vboxguest_non_udev()
start()
{
begin "Starting the VirtualBox Guest Additions ";
- which udevd >/dev/null 2>&1 || no_udev=1
+ uname -r | grep -q '^2\.6' 2>/dev/null &&
+ ps -A -o comm | grep -q '/*udevd$' 2>/dev/null ||
+ no_udev=1
running_vboxguest || {
rm -f $dev || {
fail "Cannot remove $dev"
@@ -373,19 +377,12 @@ setup_modules()
test_for_gcc_and_make
test_sane_kernel_dir
- if ! sh /usr/share/$PACKAGE/test/build_in_tmp \
- --no-print-directory >> $LOG 2>&1; then
- fail_msg
- printf "Your system does not seem to be set up to build kernel modules.\nLook at $LOG to find out what went wrong.\nOnce you have corrected it, you can run\n\n /etc/init.d/vboxadd setup\n\nto build them.\n\n"
- return 1
- else
- if ! sh /usr/share/$PACKAGE/test_drm/build_in_tmp \
- --no-print-directory >> $LOG 2>&1; then
- printf "\nYour guest system does not seem to have sufficient OpenGL support to enable\naccelerated 3D effects (this requires Linux 2.6.27 or later in the guest\nsystem). This Guest Additions feature will be disabled.\n\n"
- BUILDVBOXVIDEO=""
- fi
- fi
echo
+ if expr `uname -r` '<' '2.6.27' > /dev/null; then
+ echo "Not building the VirtualBox advanced graphics driver as this Linux version is"
+ echo "too old to use it."
+ BUILDVBOXVIDEO=
+ fi
if [ -n "$BUILDVBOXGUEST" ]; then
begin "Building the main Guest Additions module"
if ! $BUILDVBOXGUEST \
@@ -539,7 +536,7 @@ status)
dmnstatus
;;
*)
- echo "Usage: $0 {start|stop|restart|status}"
+ echo "Usage: $0 {start|stop|restart|status|setup}"
exit 1
esac
diff --git a/src/VBox/Additions/linux/sharedfolders/Makefile.kmk b/src/VBox/Additions/linux/sharedfolders/Makefile.kmk
index ba60fa987..d4696f6a5 100644
--- a/src/VBox/Additions/linux/sharedfolders/Makefile.kmk
+++ b/src/VBox/Additions/linux/sharedfolders/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Sub-Makefile for the vboxsf (linux shared folders module).
#
diff --git a/src/VBox/Additions/linux/sharedfolders/Makefile.module b/src/VBox/Additions/linux/sharedfolders/Makefile.module
index d17eced2a..057030ab8 100644
--- a/src/VBox/Additions/linux/sharedfolders/Makefile.module
+++ b/src/VBox/Additions/linux/sharedfolders/Makefile.module
@@ -3,7 +3,7 @@
#
# (For 2.6.x this file must be 'Makefile'!)
#
-# 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;
@@ -14,52 +14,12 @@
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
-#
-# First, figure out which architecture we're targeting and the build type.
-# (We have to support basic cross building (ARCH=i386|x86_64).)
-# While at it, warn about BUILD_* vars found to help with user problems.
-#
-ifeq ($(filter-out x86_64 amd64 AMD64,$(shell uname -m)),)
- BUILD_TARGET_ARCH_DEF := amd64
-else
- BUILD_TARGET_ARCH_DEF := x86
-endif
-ifneq ($(filter-out amd64 x86,$(BUILD_TARGET_ARCH)),)
- $(warning Ignoring unknown BUILD_TARGET_ARCH value '$(BUILD_TARGET_ARCH)'.)
- BUILD_TARGET_ARCH :=
-endif
-ifeq ($(BUILD_TARGET_ARCH),)
- ifeq ($(ARCH),x86_64)
- BUILD_TARGET_ARCH := amd64
- else
- ifeq ($(ARCH),i386)
- BUILD_TARGET_ARCH := x86
- else
- BUILD_TARGET_ARCH := $(BUILD_TARGET_ARCH_DEF)
- endif
- endif
-else
- ifneq ($(BUILD_TARGET_ARCH),$(BUILD_TARGET_ARCH_DEF))
- $(warning Using BUILD_TARGET_ARCH='$(BUILD_TARGET_ARCH)' from the $(origin BUILD_TARGET_ARCH).)
- endif
-endif
-
-ifneq ($(filter-out release profile debug strict,$(BUILD_TYPE)),)
- $(warning Ignoring unknown BUILD_TYPE value '$(BUILD_TYPE)'.)
- BUILD_TYPE :=
-endif
-ifeq ($(BUILD_TYPE),)
- BUILD_TYPE := release
-else
- ifneq ($(BUILD_TYPE),release)
- $(warning Using BUILD_TYPE='$(BUILD_TYPE)' from the $(origin BUILD_TYPE).)
- endif
-endif
+# Linux kbuild sets this to our source directory if we are called from there
+obj ?= $(CURDIR)
+include $(obj)/Makefile.include.header
-
-# override is required by the Debian guys
-override MODULE = vboxsf
-OBJS = \
+MOD_NAME = vboxsf
+MOD_OBJS = \
vfsmod.o \
dirops.o \
lnkops.o \
@@ -74,7 +34,7 @@ OBJS = \
VBoxGuestR0LibSharedFolders.o \
VbglR0CanUsePhysPageList.o
ifeq ($(BUILD_TARGET_ARCH),x86)
-OBJS += \
+MOD_OBJS += \
divdi3.o \
moddi3.o \
udivdi3.o \
@@ -82,185 +42,50 @@ OBJS += \
qdivrem.o
endif
-EXTRA_CFLAGS = -fshort-wchar
-
-ifneq ($(MAKECMDGOALS),clean)
-
-ifeq ($(KERNELRELEASE),)
-
- #
- # building from this directory
- #
-
- # kernel base directory
- ifndef KERN_DIR
- KERN_DIR := /lib/modules/$(shell uname -r)/build
- ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
- KERN_DIR := /usr/src/linux
- ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
- $(error Error: unable to find the sources of your current Linux kernel. \
- Specify KERN_DIR=<directory> and run Make again)
- endif
- $(warning Warning: using /usr/src/linux as the source directory of your \
- Linux kernel. If this is not correct, specify \
- KERN_DIR=<directory> and run Make again.)
- endif
- else
- ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
- $(error Error: KERN_DIR does not point to a directory)
- endif
- endif
-
- # includes
- ifndef KERN_INCL
- KERN_INCL = $(KERN_DIR)/include
- endif
- ifneq ($(shell if test -d $(KERN_INCL); then echo yes; fi),yes)
- $(error Error: unable to find the include directory for your current Linux \
- kernel. Specify KERN_INCL=<directory> and run Make again)
- endif
-
- # module install dir.
- ifneq ($(filter install install_rpm,$(MAKECMDGOALS)),)
- ifndef MODULE_DIR
- MODULE_DIR_TST := /lib/modules/$(shell uname -r)
- ifeq ($(shell if test -d $(MODULE_DIR_TST); then echo yes; fi),yes)
- MODULE_DIR := $(MODULE_DIR_TST)/misc
- else
- $(error Unable to find the folder to install the shared folders driver to)
- endif
- endif # MODULE_DIR unspecified
- endif
-
- # guess kernel version (24 or 26)
- ifeq ($(shell if grep '"2\.4\.' $(KERN_INCL)/linux/version.h > /dev/null; then echo yes; fi),yes)
- KERN_VERSION := 24
- else
- KERN_VERSION := 26
- endif
-
-else # neq($(KERNELRELEASE),)
-
- #
- # building from kbuild (make -C <kernel_directory> M=`pwd`)
- #
-
- # guess kernel version (24 or 26)
- ifeq ($(shell if echo "$(VERSION).$(PATCHLEVEL)." | grep '2\.4\.' > /dev/null; then echo yes; fi),yes)
- KERN_VERSION := 24
- else
- KERN_VERSION := 26
- endif
-
-endif # neq($(KERNELRELEASE),)
-
-# debug - show guesses.
-ifdef DEBUG
-$(warning dbg: KERN_DIR = $(KERN_DIR))
-$(warning dbg: KERN_INCL = $(KERN_INCL))
-$(warning dbg: MODULE_DIR = $(MODULE_DIR))
-$(warning dbg: KERN_VERSION = $(KERN_VERSION))
-endif
-
-KBUILD_VERBOSE ?= 1
+MOD_INCL = \
+ $(addprefix -I$(KBUILD_EXTMOD),/ /include /r0drv/linux) \
+ $(addprefix -I$(KBUILD_EXTMOD)/vboxsf,/ /include /r0drv/linux)
-#
-# Compiler options
-#
-ifndef INCL
- INCL := $(addprefix -I,$(KERN_INCL) $(EXTRA_INCL))
- ifndef KBUILD_EXTMOD
- KBUILD_EXTMOD := $(shell pwd)
- endif
- INCL += $(addprefix -I$(KBUILD_EXTMOD),/ /include /r0drv/linux)
- INCL += $(addprefix -I$(KBUILD_EXTMOD)/vboxsf,/ /include /r0drv/linux)
- export INCL
-endif
ifneq ($(wildcard $(KBUILD_EXTMOD)/vboxsf),)
MANGLING := $(KBUILD_EXTMOD)/vboxsf/include/VBox/VBoxGuestMangling.h
else
MANGLING := $(KBUILD_EXTMOD)/include/VBox/VBoxGuestMangling.h
endif
-KFLAGS := -D__KERNEL__ -DMODULE -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 \
+
+MOD_DEFS = -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 \
-DIN_SUP_R0 -DVBOX -DVBOX_WITH_HGCM -DIN_MODULE -DIN_GUEST_R0
# our module does not export any symbol
-KFLAGS += -DRT_NO_EXPORT_SYMBOL
+MOD_DEFS += -DRT_NO_EXPORT_SYMBOL
ifeq ($(BUILD_TARGET_ARCH),amd64)
- KFLAGS += -DRT_ARCH_AMD64 -DVBOX_WITH_64_BITS_GUESTS
+ MOD_DEFS += -DRT_ARCH_AMD64 -DVBOX_WITH_64_BITS_GUESTS
else
- KFLAGS += -DRT_ARCH_X86
-endif
-ifeq ($(BUILD_TYPE),debug)
- KFLAGS += -DDEBUG
+ MOD_DEFS += -DRT_ARCH_X86
endif
ifeq ($(KERN_VERSION), 24)
-#
-# 2.4
-#
-
-ifeq ($(BUILD_TARGET_ARCH),amd64)
- KFLAGS += -mcmodel=kernel
-endif
-
-CFLAGS := -O2 -DVBOX_LINUX_2_4 $(INCL) $(KFLAGS) $(KDEBUG)
-MODULE_EXT := o
-
-# 2.4 Module linking
-$(MODULE).o: $(OBJS)
- $(LD) -o $@ -r $(OBJS)
-
-.PHONY: $(MODULE)
-all: $(MODULE)
-$(MODULE): $(MODULE).o
-
+ MOD_CFLAGS =
else
-#
-# 2.6 and later
-#
-
-MODULE_EXT := ko
-
-$(MODULE)-y := $(OBJS)
+ MOD_CFLAGS = -fshort-wchar -include $(MANGLING)
# special hack for Fedora Core 6 2.6.18 (fc6), rhel5 2.6.18 (el5),
# ClarkConnect 4.3 (cc4) and ClarkConnect 5 (v5)
-ifeq ($(KERNELRELEASE),)
- KFLAGS += $(foreach inc,$(KERN_INCL),\
- $(if $(wildcard $(inc)/linux/utsrelease.h),\
- $(if $(shell grep '"2.6.18.*fc6.*"' $(inc)/linux/utsrelease.h; \
+ ifeq ($(KERNELRELEASE),)
+ MOD_EXTRA += $(foreach inc,$(KERN_INCL),\
+ $(if $(wildcard $(inc)/linux/utsrelease.h),\
+ $(if $(shell grep '"2.6.18.*fc6.*"' $(inc)/linux/utsrelease.h; \
grep '"2.6.18.*el5.*"' $(inc)/linux/utsrelease.h; \
grep '"2.6.18.*v5.*"' $(inc)/linux/utsrelease.h; \
grep '"2.6.18.*cc4.*"' $(inc)/linux/utsrelease.h),\
-DKERNEL_FC6,),))
-else
- KFLAGS += $(if $(shell echo "$(KERNELRELEASE)"|grep '2.6.18.*fc6.*';\
+ else
+ MOD_EXTRA += $(if $(shell echo "$(KERNELRELEASE)"|grep '2.6.18.*fc6.*';\
echo "$(KERNELRELEASE)"|grep '2.6.18.*el5.*';\
echo "$(KERNELRELEASE)"|grep '2.6.18.*v5.*';\
echo "$(KERNELRELEASE)"|grep '2.6.18.*cc4.*'),\
-DKERNEL_FC6,)
+ endif
endif
-# build defs
-EXTRA_CFLAGS += -include $(MANGLING) $(INCL) $(KFLAGS) $(KDEBUG)
-
-all: $(MODULE)
-
-obj-m += $(MODULE).o
-
-$(MODULE):
- $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C $(KERN_DIR) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) modules
-
-endif
-
-install: $(MODULE)
- @mkdir -p $(MODULE_DIR); \
- install -m 0664 -o root -g root $(MODULE).$(MODULE_EXT) $(MODULE_DIR); \
- PATH="$(PATH):/bin:/sbin" depmod -a;
-
-endif # eq($(MAKECMDGOALS),clean)
+MOD_CLEAN = . linux r0drv r0drv/linux
-# important: Don't remove Module.symvers! DKMS does 'make clean' before building ...
-clean:
- for f in . linux r0drv r0drv/linux; do rm -f $$f/*.o $$f/.*.cmd $$f/.*.flags; done
- rm -rf .vboxsf* .tmp_ver* vboxsf.* Modules.symvers modules.order
+include $(obj)/Makefile.include.footer
diff --git a/src/VBox/Additions/linux/sharedfolders/files_vboxsf b/src/VBox/Additions/linux/sharedfolders/files_vboxsf
index 94c98f5dc..6d94398c8 100755..100644
--- a/src/VBox/Additions/linux/sharedfolders/files_vboxsf
+++ b/src/VBox/Additions/linux/sharedfolders/files_vboxsf
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: files_vboxsf $
+# $Id: files_vboxsf 37350 2011-06-07 13:44:25Z vboxsync $
## @file
# Shared file between Makefile.kmk and export_modules
#
@@ -64,6 +64,8 @@ FILES_VBOXSF_NOBIN=" \
${PATH_ROOT}/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestLog.h=>VBoxGuestLog.h \
${PATH_ROOT}/src/VBox/Additions/common/VBoxGuestLib/VMMDev.cpp=>VMMDev.c \
${PATH_ROOT}/src/VBox/Additions/common/VBoxGuestLib/VbglR0CanUsePhysPageList.cpp=>VbglR0CanUsePhysPageList.c \
+ ${PATH_ROOT}/src/VBox/Installer/linux/Makefile.include.header=>Makefile.include.header \
+ ${PATH_ROOT}/src/VBox/Installer/linux/Makefile.include.footer=>Makefile.include.footer \
${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/divdi3.c=>divdi3.c \
${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/moddi3.c=>moddi3.c \
${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/qdivrem.c=>qdivrem.c \
diff --git a/src/VBox/Additions/linux/sharedfolders/vbsfmount.c b/src/VBox/Additions/linux/sharedfolders/vbsfmount.c
index f6f704cb8..2f580db50 100644
--- a/src/VBox/Additions/linux/sharedfolders/vbsfmount.c
+++ b/src/VBox/Additions/linux/sharedfolders/vbsfmount.c
@@ -1,4 +1,4 @@
-/* $Id: vbsfmount.c $ */
+/* $Id: vbsfmount.c 31205 2010-07-29 12:48:43Z vboxsync $ */
/** @file
* vbsfmount - Commonly used code to mount shared folders on Linux-based
* systems. Currently used by mount.vboxsf and VBoxService.
diff --git a/src/VBox/Additions/solaris/DRM/Makefile.kmk b/src/VBox/Additions/solaris/DRM/Makefile.kmk
index 0daddebd6..320f3c035 100644
--- a/src/VBox/Additions/solaris/DRM/Makefile.kmk
+++ b/src/VBox/Additions/solaris/DRM/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 33656 2010-11-01 14:18:11Z vboxsync $
## @file
# Sub-Makefile for the vboxvideo DRM module (Solaris kernel OpenGL module).
#
diff --git a/src/VBox/Additions/solaris/DRM/vboxvideo_drm.c b/src/VBox/Additions/solaris/DRM/vboxvideo_drm.c
index c49ec803b..e7e7561f1 100644
--- a/src/VBox/Additions/solaris/DRM/vboxvideo_drm.c
+++ b/src/VBox/Additions/solaris/DRM/vboxvideo_drm.c
@@ -1,4 +1,4 @@
-/* $Id: vboxvideo_drm.c $ */
+/* $Id: vboxvideo_drm.c 33656 2010-11-01 14:18:11Z vboxsync $ */
/** @file
* vboxvideo_drm - Direct Rendering Module, Solaris Specific Code.
*/
diff --git a/src/VBox/Additions/solaris/Installer/makepackage.sh b/src/VBox/Additions/solaris/Installer/makepackage.sh
index b3b804487..b3b804487 100755..100644
--- a/src/VBox/Additions/solaris/Installer/makepackage.sh
+++ b/src/VBox/Additions/solaris/Installer/makepackage.sh
diff --git a/src/VBox/Additions/solaris/Installer/postinstall.sh b/src/VBox/Additions/solaris/Installer/postinstall.sh
index 467605307..262499b86 100755..100644
--- a/src/VBox/Additions/solaris/Installer/postinstall.sh
+++ b/src/VBox/Additions/solaris/Installer/postinstall.sh
@@ -53,24 +53,24 @@ uncompress_files()
# VBox Xorg Video drivers
uncompress_file "$1" "vboxvideo_drv_13.so"
- uncompress_file "$1" "vboxvideo_drv_14.so"
- uncompress_file "$1" "vboxvideo_drv_15.so"
- uncompress_file "$1" "vboxvideo_drv_16.so"
- uncompress_file "$1" "vboxvideo_drv_17.so"
- uncompress_file "$1" "vboxvideo_drv_18.so"
- uncompress_file "$1" "vboxvideo_drv_19.so"
+ uncompress_file "$1" "vboxvideo_drv_14.so"
+ uncompress_file "$1" "vboxvideo_drv_15.so"
+ uncompress_file "$1" "vboxvideo_drv_16.so"
+ uncompress_file "$1" "vboxvideo_drv_17.so"
+ uncompress_file "$1" "vboxvideo_drv_18.so"
+ uncompress_file "$1" "vboxvideo_drv_19.so"
uncompress_file "$1" "vboxvideo_drv_110.so"
- uncompress_file "$1" "vboxvideo_drv_70.so"
- uncompress_file "$1" "vboxvideo_drv_71.so"
+ uncompress_file "$1" "vboxvideo_drv_70.so"
+ uncompress_file "$1" "vboxvideo_drv_71.so"
# VBox Xorg Mouse drivers
- uncompress_file "$1" "vboxmouse_drv_13.so"
- uncompress_file "$1" "vboxmouse_drv_14.so"
- uncompress_file "$1" "vboxmouse_drv_15.so"
- uncompress_file "$1" "vboxmouse_drv_16.so"
- uncompress_file "$1" "vboxmouse_drv_17.so"
- uncompress_file "$1" "vboxmouse_drv_18.so"
- uncompress_file "$1" "vboxmouse_drv_19.so"
+ uncompress_file "$1" "vboxmouse_drv_13.so"
+ uncompress_file "$1" "vboxmouse_drv_14.so"
+ uncompress_file "$1" "vboxmouse_drv_15.so"
+ uncompress_file "$1" "vboxmouse_drv_16.so"
+ uncompress_file "$1" "vboxmouse_drv_17.so"
+ uncompress_file "$1" "vboxmouse_drv_18.so"
+ uncompress_file "$1" "vboxmouse_drv_19.so"
uncompress_file "$1" "vboxmouse_drv_110.so"
uncompress_file "$1" "vboxmouse_drv_70.so"
uncompress_file "$1" "vboxmouse_drv_71.so"
diff --git a/src/VBox/Additions/solaris/Installer/preremove.sh b/src/VBox/Additions/solaris/Installer/preremove.sh
index 58bade74c..58bade74c 100755..100644
--- a/src/VBox/Additions/solaris/Installer/preremove.sh
+++ b/src/VBox/Additions/solaris/Installer/preremove.sh
diff --git a/src/VBox/Additions/solaris/Makefile.kmk b/src/VBox/Additions/solaris/Makefile.kmk
index 8558523a7..7432299be 100644
--- a/src/VBox/Additions/solaris/Makefile.kmk
+++ b/src/VBox/Additions/solaris/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 36792 2011-04-21 14:40:16Z vboxsync $
## @file
# Makefile for the Solaris guest additions base directory.
#
@@ -184,7 +184,7 @@ SOLARIS_ADD_XORG_DRIVERS = \
vboxmouse_drv_17.so \
vboxmouse_drv_18.so \
vboxmouse_drv_19.so \
- vboxmouse_drv_110.so \
+ vboxmouse_drv_110.so \
vboxmouse_drv_70.so \
vboxmouse_drv_71.so \
vboxvideo_drv_13.so \
@@ -194,7 +194,7 @@ SOLARIS_ADD_XORG_DRIVERS = \
vboxvideo_drv_17.so \
vboxvideo_drv_18.so \
vboxvideo_drv_19.so \
- vboxvideo_drv_110.so \
+ vboxvideo_drv_110.so \
vboxvideo_drv_70.so \
vboxvideo_drv_71.so
@@ -399,362 +399,3 @@ $(addprefix $(SOLARIS_ADD_USRBIN_DIR)/,$(SOLARIS_ADD_USRBIN_LINKS)): \
$(SOLARIS_ADD_USRBIN_DIR)/% : % | $$(dir $$@)
$(LN_SYMLINK) -f ../..$(SOLARIS_VBOXADDINST_SUBDIR)/$< $@
-
-
-#
-# @todo Delete once the new packaging works
-#
-ifdef OBSOLETE_PACKAGING
-#
-# If we are doing a combined package (x86+amd64) include the binaries from both
-# architectures otherwise use the one from $(PATH_BIN)/additions
-#
-VBOX_CROGL_FILES = \
- VBoxOGL.so \
- VBoxOGLcrutil.so \
- VBoxOGLfeedbackspu.so \
- VBoxOGLpassthroughspu.so \
- VBoxOGLarrayspu.so \
- VBoxOGLerrorspu.so \
- VBoxOGLpackspu.so
-VBOX_CROGL_FILES_32 = $(addprefix $(SOLARIS_ADD_BIN_32)/,$(VBOX_CROGL_FILES))
-VBOX_CROGL_FILES_64 = $(addprefix $(SOLARIS_ADD_BIN_64)/,$(VBOX_CROGL_FILES))
-VBOX_CROGL_FILES_ISA = $(addprefix $(SOLARIS_ADD_BIN)/,$(VBOX_CROGL_FILES))
-
-ifdef VBOX_WITH_COMBINED_SOLARIS_GUEST_PACKAGE
- SOLARIS_ADD_BIN_64 := $(PATH_OUT_BASE)/solaris.amd64/$(KBUILD_TYPE)/bin/additions
- SOLARIS_ADD_BIN_32 := $(PATH_OUT_BASE)/solaris.x86/$(KBUILD_TYPE)/bin/additions
- SOLARIS_ADD_INST_DIR_64 := $(SOLARIS_ADD_INST_DIR)/amd64
- SOLARIS_ADD_INST_DIR_32 := $(SOLARIS_ADD_INST_DIR)
- VBOX_SOLPACKFILES = \
- $(SOLARIS_ADD_BIN_64)/vboxguest \
- $(SOLARIS_ADD_BIN_64)/vboxfs \
- $(if $(VBOX_OSE),,$(SOLARIS_ADD_BIN_64)/vboxfs_s10) \
- $(SOLARIS_ADD_BIN_64)/VBoxClient \
- $(SOLARIS_ADD_BIN_64)/VBoxService \
- $(SOLARIS_ADD_BIN_64)/VBoxControl \
- $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_13.so \
- $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_14.so \
- $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_15.so \
- $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_16.so \
- $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_17.so \
- $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_18.so \
- $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_19.so \
- $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_110.so \
- $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_70.so \
- $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_71.so \
- $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_14.so \
- $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_15.so \
- $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_16.so \
- $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_17.so \
- $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_18.so \
- $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_19.so \
- $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_110.so \
- $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_70.so \
- $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_71.so \
- $(SOLARIS_ADD_BIN_32)/vboxguest \
- $(SOLARIS_ADD_BIN_32)/vboxfs \
- $(if $(VBOX_OSE),,$(SOLARIS_ADD_BIN_32)/vboxfs_s10) \
- $(SOLARIS_ADD_BIN_32)/vboxfsmount \
- $(SOLARIS_ADD_BIN_32)/VBoxClient \
- $(SOLARIS_ADD_BIN_32)/VBoxService \
- $(SOLARIS_ADD_BIN_32)/VBoxControl \
- $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_13.so \
- $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_14.so \
- $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_15.so \
- $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_16.so \
- $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_17.so \
- $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_18.so \
- $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_19.so \
- $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_110.so \
- $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_70.so \
- $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_71.so \
- $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_14.so \
- $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_15.so \
- $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_16.so \
- $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_17.so \
- $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_18.so \
- $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_19.so \
- $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_110.so \
- $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_70.so \
- $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_71.so
- ifdef VBOX_WITH_CROGL
- VBOX_SOLPACKFILES += \
- $(VBOX_CROGL_FILES_32) \
- $(VBOX_CROGL_FILES_64)
- endif
-else
- SOLARIS_ADD_BIN := $(PATH_BIN)/additions
- ifeq ($(KBUILD_TARGET_ARCH),x86)
- SOLARIS_ADD_INST_DIR_ISA := $(SOLARIS_ADD_INST_DIR)
- else
- SOLARIS_ADD_INST_DIR_ISA := $(SOLARIS_ADD_INST_DIR)/amd64
- endif
- VBOX_SOLPACKFILES = \
- $(SOLARIS_ADD_BIN)/vboxguest \
- $(SOLARIS_ADD_BIN)/vboxfs \
- $(if $(VBOX_OSE),,$(SOLARIS_ADD_BIN)/vboxfs_s10) \
- $(SOLARIS_ADD_BIN)/vboxfsmount \
- $(SOLARIS_ADD_BIN)/VBoxClient \
- $(SOLARIS_ADD_BIN)/VBoxService \
- $(SOLARIS_ADD_BIN)/VBoxControl \
- $(SOLARIS_ADD_BIN)/vboxvideo_drv_13.so \
- $(SOLARIS_ADD_BIN)/vboxvideo_drv_14.so \
- $(SOLARIS_ADD_BIN)/vboxvideo_drv_15.so \
- $(SOLARIS_ADD_BIN)/vboxvideo_drv_16.so \
- $(SOLARIS_ADD_BIN)/vboxvideo_drv_17.so \
- $(SOLARIS_ADD_BIN)/vboxvideo_drv_18.so \
- $(SOLARIS_ADD_BIN)/vboxvideo_drv_19.so \
- $(SOLARIS_ADD_BIN)/vboxvideo_drv_110.so \
- $(SOLARIS_ADD_BIN)/vboxvideo_drv_70.so \
- $(SOLARIS_ADD_BIN)/vboxvideo_drv_71.so \
- $(SOLARIS_ADD_BIN)/vboxmouse_drv_14.so \
- $(SOLARIS_ADD_BIN)/vboxmouse_drv_15.so \
- $(SOLARIS_ADD_BIN)/vboxmouse_drv_16.so \
- $(SOLARIS_ADD_BIN)/vboxmouse_drv_17.so \
- $(SOLARIS_ADD_BIN)/vboxmouse_drv_18.so \
- $(SOLARIS_ADD_BIN)/vboxmouse_drv_19.so \
- $(SOLARIS_ADD_BIN)/vboxmouse_drv_110.so \
- $(SOLARIS_ADD_BIN)/vboxmouse_drv_70.so \
- $(SOLARIS_ADD_BIN)/vboxmouse_drv_71.so
- ifdef VBOX_WITH_CROGL
- VBOX_SOLPACKFILES += \
- $(VBOX_CROGL_FILES_ISA)
- endif
-endif
-
-include $(KBUILD_PATH)/subfooter.kmk
-
-$(PATH_BIN)/additions/VBoxSolarisAdditions.pkg: \
- $(VBOX_VERSION_STAMP) \
- $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/makepackage.sh \
- $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/postinstall.sh \
- $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/preremove.sh \
- $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/vboxguest.pkginfo \
- $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/vboxguest.depend \
- $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/vboxguest.sh \
- $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/vboxservice.xml \
- $(VBOX_PATH_X11_ADDITION_INSTALLER)/98vboxadd-xclient \
- $(VBOX_PATH_X11_ADDITION_INSTALLER)/x11config.pl \
- $(VBOX_PATH_X11_ADDITION_INSTALLER)/x11config15sol.pl \
- $(VBOX_PATH_X11_ADDITION_INSTALLER)/x11restore.pl \
- $(VBOX_PATH_X11_ADDITION_INSTALLER)/solaris_xorg.conf \
- $(VBOX_PATH_X11_ADDITION_INSTALLER)/solaris_xorg_modeless.conf \
- $(VBOX_SOLPACKFILES) \
- $(VBOX_BRAND_LICENSE_TXT) \
- $(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.conf \
- $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/VBox.sh \
- $(PATH_SUB_CURRENT)/solaris/Makefile.kmk
- $(call MSG_L1,Installing guest additions)
- @# Clear out the existing package files if needed
- $(QUIET)rm -rf $(SOLARIS_ADD_INST_DIR)
- $(QUIET)$(MKDIR) -p $(SOLARIS_ADD_INST_DIR)
- $(QUIET)$(if $(VBOX_WITH_COMBINED_SOLARIS_GUEST_PACKAGE),$(MKDIR) -p $(SOLARIS_ADD_INST_DIR_64),$(MKDIR) -p $(SOLARIS_ADD_INST_DIR_ISA))
- $(QUIET)$(MKDIR) -p $(SOLARIS_ADD_INST_DIR)/etc
- $(QUIET)$(SED) \
- -e "s/@VBOX_PRODUCT@/$(VBOX_PRODUCT)/g" \
- -e "s/@VBOX_VENDOR@/$(VBOX_VENDOR)/g" \
- -e "s/@VBOX_VERSION_STRING@/$(VBOX_VERSION_STRING)/g" \
- -e "s/@VBOX_SVN_REV@/$(VBOX_SVN_REV)/g" \
- -e "s/@VBOX_VERSION_REVSTAMP@/$(PKGINFO_REVSTAMP)/g" \
- -e "s/@UNAME_P@/$(PKGINFO_ARCH)/g" \
- --output $(SOLARIS_ADD_INST_DIR)/vboxguest.pkginfo \
- $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/vboxguest.pkginfo
- $(QUIET)$(INSTALL) -m 0755 $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/makepackage.sh $(SOLARIS_ADD_INST_DIR)/makepackage.sh
- $(QUIET)$(INSTALL) -m 0755 $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/postinstall.sh $(SOLARIS_ADD_INST_DIR)/postinstall.sh
- $(QUIET)$(INSTALL) -m 0755 $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/preremove.sh $(SOLARIS_ADD_INST_DIR)/preremove.sh
- $(QUIET)$(INSTALL) -m 0755 $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/vboxguest.sh $(SOLARIS_ADD_INST_DIR)/vboxguest.sh
- $(QUIET)$(INSTALL) -m 0644 $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/vboxservice.xml $(SOLARIS_ADD_INST_DIR)/vboxservice.xml
- $(QUIET)$(INSTALL) -m 0644 $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/vboxguest.space $(SOLARIS_ADD_INST_DIR)/vboxguest.space
- $(QUIET)$(INSTALL) -m 0644 $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/vboxguest.depend $(SOLARIS_ADD_INST_DIR)/vboxguest.depend
- $(QUIET)$(INSTALL) -m 0644 $(VBOX_BRAND_LICENSE_TXT) $(SOLARIS_ADD_INST_DIR)/LICENSE
- # don't display the license on package install, since 4.0
- #$(QUIET)$(INSTALL) -m 0644 $(VBOX_BRAND_LICENSE_TXT) $(SOLARIS_ADD_INST_DIR)/vboxguest.copyright
- $(QUIET)$(INSTALL) -m 0644 $(VBOX_PATH_X11_ADDITION_INSTALLER)/vboxclient.desktop $(SOLARIS_ADD_INST_DIR)/vboxclient.desktop
- $(QUIET)$(INSTALL) -m 0755 $(VBOX_PATH_X11_ADDITION_INSTALLER)/98vboxadd-xclient $(SOLARIS_ADD_INST_DIR)/1099.vboxclient
- $(QUIET)$(INSTALL) -m 0755 $(VBOX_PATH_X11_ADDITION_INSTALLER)/x11config.pl $(SOLARIS_ADD_INST_DIR)/x11config.pl
- $(QUIET)$(INSTALL) -m 0755 $(VBOX_PATH_X11_ADDITION_INSTALLER)/x11config15sol.pl $(SOLARIS_ADD_INST_DIR)/x11config15sol.pl
- $(QUIET)$(INSTALL) -m 0755 $(VBOX_PATH_X11_ADDITION_INSTALLER)/x11restore.pl $(SOLARIS_ADD_INST_DIR)/x11restore.pl
- $(QUIET)$(INSTALL) -m 0644 $(VBOX_PATH_X11_ADDITION_INSTALLER)/solaris_xorg.conf $(SOLARIS_ADD_INST_DIR)/solaris_xorg.conf
- $(QUIET)$(INSTALL) -m 0644 $(VBOX_PATH_X11_ADDITION_INSTALLER)/solaris_xorg_modeless.conf $(SOLARIS_ADD_INST_DIR)/solaris_xorg_modeless.conf
- $(QUIET)$(INSTALL) -m 0644 $(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.conf $(SOLARIS_ADD_INST_DIR)/vboxguest.conf
-ifdef VBOX_WITH_COMBINED_SOLARIS_GUEST_PACKAGE
- $(QUIET)$(INSTALL) -m 0644 $(SOLARIS_ADD_BIN_64)/vboxguest $(SOLARIS_ADD_INST_DIR_64)/vboxguest
- $(QUIET)$(INSTALL) -m 0644 $(SOLARIS_ADD_BIN_64)/vboxfs $(SOLARIS_ADD_INST_DIR_64)/vboxfs
- $(QUIET)$(if $(VBOX_OSE),,$(INSTALL) -m 0644 $(SOLARIS_ADD_BIN_64)/vboxfs_s10 $(SOLARIS_ADD_INST_DIR_64)/vboxfs_s10)
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_64)/VBoxClient $(SOLARIS_ADD_INST_DIR_64)/VBoxClient
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_64)/VBoxService $(SOLARIS_ADD_INST_DIR_64)/VBoxService
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_64)/VBoxControl $(SOLARIS_ADD_INST_DIR_64)/VBoxControl
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_13.so $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_13.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_14.so $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_14.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_15.so $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_15.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_16.so $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_16.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_17.so $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_17.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_18.so $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_18.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_19.so $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_19.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_110.so $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_110.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_70.so $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_70.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxvideo_drv_71.so $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_71.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_14.so $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_14.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_15.so $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_15.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_16.so $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_16.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_17.so $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_17.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_18.so $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_18.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_19.so $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_19.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_110.so $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_110.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_70.so $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_70.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_64)/vboxmouse_drv_71.so $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_71.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_64)/VBoxOGL.so $(SOLARIS_ADD_INST_DIR_64)/VBoxOGL.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_64)/VBoxOGLcrutil.so $(SOLARIS_ADD_INST_DIR_64)/VBoxOGLcrutil.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_64)/VBoxOGLfeedbackspu.so $(SOLARIS_ADD_INST_DIR_64)/VBoxOGLfeedbackspu.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_64)/VBoxOGLpassthroughspu.so $(SOLARIS_ADD_INST_DIR_64)/VBoxOGLpassthroughspu.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_64)/VBoxOGLarrayspu.so $(SOLARIS_ADD_INST_DIR_64)/VBoxOGLarrayspu.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_64)/VBoxOGLerrorspu.so $(SOLARIS_ADD_INST_DIR_64)/VBoxOGLerrorspu.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_64)/VBoxOGLpackspu.so $(SOLARIS_ADD_INST_DIR_64)/VBoxOGLpackspu.so
- $(QUIET)$(INSTALL) -m 0644 $(SOLARIS_ADD_BIN_32)/vboxguest $(SOLARIS_ADD_INST_DIR_32)/vboxguest
- $(QUIET)$(INSTALL) -m 0644 $(SOLARIS_ADD_BIN_32)/vboxfs $(SOLARIS_ADD_INST_DIR_32)/vboxfs
- $(QUIET)$(if $(VBOX_OSE),,$(INSTALL) -m 0644 $(SOLARIS_ADD_BIN_32)/vboxfs_s10 $(SOLARIS_ADD_INST_DIR_32)/vboxfs_s10)
- $(QUIET)$(INSTALL) -m 0755 $(SOLARIS_ADD_BIN_32)/vboxfsmount $(SOLARIS_ADD_INST_DIR_32)/vboxfsmount
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_32)/VBoxClient $(SOLARIS_ADD_INST_DIR_32)/VBoxClient
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_32)/VBoxService $(SOLARIS_ADD_INST_DIR_32)/VBoxService
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_32)/VBoxControl $(SOLARIS_ADD_INST_DIR_32)/VBoxControl
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_13.so $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_13.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_14.so $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_14.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_15.so $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_15.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_16.so $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_16.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_17.so $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_17.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_18.so $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_18.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_19.so $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_19.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_110.so $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_110.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_70.so $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_70.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxvideo_drv_71.so $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_71.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_14.so $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_14.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_15.so $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_15.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_16.so $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_16.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_17.so $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_17.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_18.so $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_18.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_19.so $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_19.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_110.so $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_110.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_70.so $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_70.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN_32)/vboxmouse_drv_71.so $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_71.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_32)/VBoxOGL.so $(SOLARIS_ADD_INST_DIR_32)/VBoxOGL.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_32)/VBoxOGLcrutil.so $(SOLARIS_ADD_INST_DIR_32)/VBoxOGLcrutil.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_32)/VBoxOGLfeedbackspu.so $(SOLARIS_ADD_INST_DIR_32)/VBoxOGLfeedbackspu.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_32)/VBoxOGLpassthroughspu.so $(SOLARIS_ADD_INST_DIR_32)/VBoxOGLpassthroughspu.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_32)/VBoxOGLarrayspu.so $(SOLARIS_ADD_INST_DIR_32)/VBoxOGLarrayspu.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_32)/VBoxOGLerrorspu.so $(SOLARIS_ADD_INST_DIR_32)/VBoxOGLerrorspu.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN_32)/VBoxOGLpackspu.so $(SOLARIS_ADD_INST_DIR_32)/VBoxOGLpackspu.so
- ifdef VBOX_COMPRESS
- # Compress binaries as we distribute uncompressed pkgs
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/VBoxClient
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/VBoxService
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/VBoxControl
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_13.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_14.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_15.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_16.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_17.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_18.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_19.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_110.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_70.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxvideo_drv_71.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_14.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_15.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_16.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_17.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_18.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_19.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_110.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_70.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_64)/vboxmouse_drv_71.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/VBoxClient
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/VBoxService
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/VBoxControl
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_13.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_14.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_15.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_16.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_17.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_18.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_19.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_110.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_70.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxvideo_drv_71.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_14.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_15.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_16.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_17.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_18.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_19.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_110.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_70.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_32)/vboxmouse_drv_71.so
- endif # VBOX_COMPRESS
-else # !VBOX_WITH_COMBINED_SOLARIS_GUEST_PACKAGE
- $(QUIET)$(INSTALL) -m 0644 $(SOLARIS_ADD_BIN)/vboxguest $(SOLARIS_ADD_INST_DIR_ISA)/vboxguest
- $(QUIET)$(INSTALL) -m 0644 $(SOLARIS_ADD_BIN)/vboxfs $(SOLARIS_ADD_INST_DIR_ISA)/vboxfs
- $(QUIET)$(INSTALL) -m 0644 $(SOLARIS_ADD_BIN)/vboxfs_s10 $(SOLARIS_ADD_INST_DIR_ISA)/vboxfs_s10
- $(QUIET)$(INSTALL) -m 0755 $(SOLARIS_ADD_BIN)/vboxfsmount $(SOLARIS_ADD_INST_DIR_ISA)/vboxfsmount
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN)/VBoxClient $(SOLARIS_ADD_INST_DIR_ISA)/VBoxClient
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN)/VBoxService $(SOLARIS_ADD_INST_DIR_ISA)/VBoxService
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN)/VBoxControl $(SOLARIS_ADD_INST_DIR_ISA)/VBoxControl
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxvideo_drv_13.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_13.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxvideo_drv_14.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_14.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxvideo_drv_15.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_15.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxvideo_drv_16.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_16.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxvideo_drv_17.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_17.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxvideo_drv_18.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_18.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxvideo_drv_19.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_19.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxvideo_drv_110.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_110.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxvideo_drv_70.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_70.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxvideo_drv_71.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_71.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxmouse_drv_14.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_14.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxmouse_drv_15.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_15.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxmouse_drv_16.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_16.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxmouse_drv_17.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_17.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxmouse_drv_18.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_18.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxmouse_drv_19.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_19.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxmouse_drv_110.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_110.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxmouse_drv_70.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_70.so
- $(QUIET)$(BIN_COPY) $(SOLARIS_ADD_BIN)/vboxmouse_drv_71.so $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_71.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN)/VBoxOGL.so $(SOLARIS_ADD_INST_DIR_ISA)/VBoxOGL.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN)/VBoxOGLcrutil.so $(SOLARIS_ADD_INST_DIR_ISA)/VBoxOGLcrutil.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN)/VBoxOGLfeedbackspu.so $(SOLARIS_ADD_INST_DIR_ISA)/VBoxOGLfeedbackspu.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN)/VBoxOGLpassthroughspu.so $(SOLARIS_ADD_INST_DIR_ISA)/VBoxOGLpassthroughspu.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN)/VBoxOGLarrayspu.so $(SOLARIS_ADD_INST_DIR_ISA)/VBoxOGLarrayspu.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN)/VBoxOGLerrorspu.so $(SOLARIS_ADD_INST_DIR_ISA)/VBoxOGLerrorspu.so
- $(QUIET)$(INSTALL) -s -m 0755 $(SOLARIS_ADD_BIN)/VBoxOGLpackspu.so $(SOLARIS_ADD_INST_DIR_ISA)/VBoxOGLpackspu.so
- ifdef VBOX_COMPRESS
- # Compress binaries as we distribute uncompressed pkgs
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/VBoxClient
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/VBoxService
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/VBoxControl
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_13.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_14.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_15.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_16.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_17.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_18.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_19.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_110.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_70.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxvideo_drv_71.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_14.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_15.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_16.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_17.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_18.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_19.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_110.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_70.so
- $(QUIET)$(VBOX_COMPRESS) $(SOLARIS_ADD_INST_DIR_ISA)/vboxmouse_drv_71.so
- endif # VBOX_COMPRESS
-endif # !VBOX_WITH_COMBINED_SOLARIS_GUEST_PACKAGE
- $(QUIET)$(INSTALL) -m 0755 $(VBOX_PATH_SOLARIS_ADDITION_INSTALLER)/VBox.sh $(SOLARIS_ADD_INST_DIR)/VBox.sh
- $(call MSG_L1,Creating install package: $@)
- $(QUIET)$(SOLARIS_ADD_INST_DIR)/makepackage.sh $(SOLARIS_ADD_INST_DIR) $(PKGFILENAME) $(VBOX_SVN_REV)
- $(QUIET)$(INSTALL) -m 0644 $(SOLARIS_ADD_INST_DIR)/$(PKGFILENAME) $(PATH_BIN)/additions/$(PKGFILENAME)
-
-endif
-
diff --git a/src/VBox/Additions/solaris/SharedFolders/Makefile.kmk b/src/VBox/Additions/solaris/SharedFolders/Makefile.kmk
index 931677aed..64a71dee6 100644
--- a/src/VBox/Additions/solaris/SharedFolders/Makefile.kmk
+++ b/src/VBox/Additions/solaris/SharedFolders/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37423 2011-06-12 18:37:56Z vboxsync $
## @file
# Sub-Makefile for the Solaris Shared folder kernel module.
#
@@ -45,8 +45,7 @@ vboxfs_SOURCES = \
vboxfs_vnode.c \
vboxfs_prov.c
vboxfs_LIBS = \
- $(VBOX_LIB_VBGL_R0) \
- $(VBOX_LIB_IPRT_GUEST_R0)
+ $(VBOX_LIB_VBGL_R0)
vboxfs_LDFLAGS += -N drv/vboxguest
diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs.h b/src/VBox/Additions/solaris/SharedFolders/vboxfs.h
index 1e15e922d..13654a569 100644
--- a/src/VBox/Additions/solaris/SharedFolders/vboxfs.h
+++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs.h
@@ -1,4 +1,4 @@
-/* $Id: vboxfs.h $ */
+/* $Id: vboxfs.h 33994 2010-11-11 14:26:08Z vboxsync $ */
/** @file
* VirtualBox File System Driver for Solaris Guests, Internal Header.
*/
diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c
index 98bf14c88..531e4e9b3 100644
--- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c
+++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c
@@ -1,4 +1,4 @@
-/* $Id: vboxfs_mount.c $ */
+/* $Id: vboxfs_mount.c 37833 2011-07-08 10:16:08Z vboxsync $ */
/** @file
* VirtualBox File System Mount Helper, Solaris host.
* Userspace mount wrapper that parses mount (or user-specified) options
@@ -41,7 +41,6 @@
* Global Variables *
*******************************************************************************/
static char g_achOptBuf[MAX_MNTOPT_STR] = { '\0', };
-static int g_cbOptBuf = 0;
static const int g_RetErr = 33;
static const int g_RetMagic = 2;
static const int g_RetOK = 0;
@@ -61,12 +60,13 @@ static void Usage(char *pszName)
" ro mount read only\n"
" uid=UID set the default file owner user id to UID\n"
" gid=GID set the default file owner group id to GID\n"
- " stat_ttl=TTL set the \"time to live\" (in ms) for the stat caches (default %d)\n"
+ " stat_ttl=TTL set the \"time to live\" (in ms) for the stat caches (default %d)\n", DEF_STAT_TTL_MS);
+ fprintf(stderr,
" fsync honor fsync calls instead of ignoring them\n"
" ttl=TTL set the \"time to live\" to TID for the dentry\n"
" iocharset CHARSET use the character set CHARSET for i/o operations (default utf8)\n"
- " convertcp CHARSET convert the shared folder name from the character set CHARSET to utf8\n\n", DEF_STAT_TTL_MS);
- fprintf(stderr, "Less common used options:\n"
+ " convertcp CHARSET convert the shared folder name from the character set CHARSET to utf8\n\n"
+ "Less common used options:\n"
" noexec,exec,nodev,dev,nosuid,suid\n");
exit(1);
}
@@ -128,7 +128,6 @@ int main(int argc, char **argv)
fprintf(stderr, "%s: invalid argument: %s\n", pszName, optarg);
return g_RetMagic;
}
- g_cbOptBuf = strlen(g_achOptBuf);
break;
}
@@ -149,7 +148,7 @@ int main(int argc, char **argv)
pszSpecial = argv[argc - 2];
pszMount = argv[argc - 1];
- rc = mount(pszSpecial, pszMount, mntFlags | MS_OPTIONSTR, DEVICE_NAME, NULL, 0, g_achOptBuf, MAX_MNTOPT_STR);
+ rc = mount(pszSpecial, pszMount, mntFlags | MS_OPTIONSTR, DEVICE_NAME, NULL, 0, g_achOptBuf, sizeof(g_achOptBuf));
if (rc)
{
fprintf(stderr, "mount:");
diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h
index 0dd49d17b..77939ff74 100644
--- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h
+++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h
@@ -1,4 +1,4 @@
-/* $Id: vboxfs_prov.h $ */
+/* $Id: vboxfs_prov.h 31691 2010-08-16 12:59:23Z vboxsync $ */
/** @file
* VirtualBox File System for Solaris Guests, provider header.
* Portions contributed by: Ronald.
diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h
index f222b808a..d088d818d 100644
--- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h
+++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h
@@ -1,4 +1,4 @@
-/* $Id: vboxfs_vfs.h $ */
+/* $Id: vboxfs_vfs.h 31691 2010-08-16 12:59:23Z vboxsync $ */
/** @file
* VirtualBox File System for Solaris Guests, VFS header.
*/
diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
index c932111b7..a6d9c755e 100644
--- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
+++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
@@ -67,6 +67,7 @@
*/
#include <VBox/log.h>
+#include <iprt/asm.h>
#include <unistd.h>
#include <sys/types.h>
@@ -81,6 +82,9 @@
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/vfs.h>
+#include <sys/vmsystm.h>
+#include <vm/seg_kpm.h>
+#include <vm/pvn.h>
#if !defined(VBOX_VFS_SOLARIS_10U6)
#include <sys/vfs_opreg.h>
#endif
@@ -393,8 +397,8 @@ sfnode_make_stale(sfnode_t *node)
static uint64_t
sfnode_cur_time_usec(void)
{
- timestruc_t now = hrestime;
- return (now.tv_sec * 1000000L + now.tv_nsec / 1000L);
+ clock_t now = drv_hztousec(ddi_get_lbolt());
+ return now;
}
static int
@@ -1452,6 +1456,364 @@ done:
}
+#if 0
+static caddr_t
+sffs_page_map(
+ page_t *ppage,
+ enum seg_rw segaccess)
+{
+ /* Use seg_kpm driver if possible (64-bit) */
+ if (kpm_enable)
+ return (hat_kpm_mapin(ppage, NULL));
+ ASSERT(segaccess == S_READ || segaccess == S_WRITE);
+ return (ppmapin(ppage, PROT_READ | ((segaccess == S_WRITE) ? PROT_WRITE : 0), (caddr_t)-1));
+}
+
+
+static void
+sffs_page_unmap(
+ page_t *ppage,
+ caddr_t addr)
+{
+ if (kpm_enable)
+ hat_kpm_mapout(ppage, NULL, addr);
+ else
+ ppmapout(addr);
+}
+
+
+/*
+ * Called when there's no page in the cache. This will create new page(s) and read
+ * the file data into it.
+ */
+static int
+sffs_readpages(
+ vnode_t *dvp,
+ offset_t off,
+ page_t *pagelist[],
+ size_t pagelistsize,
+ struct seg *segp,
+ caddr_t addr,
+ enum seg_rw segaccess)
+{
+ ASSERT(MUTEX_HELD(&sffs_lock));
+
+ int error = 0;
+ u_offset_t io_off, total;
+ size_t io_len;
+ page_t *ppages;
+ page_t *pcur;
+
+ sfnode_t *node = VN2SFN(dvp);
+ ASSERT(node);
+ ASSERT(node->sf_file);
+
+ if (pagelistsize == PAGESIZE)
+ {
+ io_off = off;
+ io_len = PAGESIZE;
+
+ ppages = page_create_va(dvp, io_off, io_len, PG_WAIT | PG_EXCL, segp, addr);
+ }
+ else
+ ppages = pvn_read_kluster(dvp, off, segp, addr, &io_off, &io_len, off, pagelistsize, 0);
+
+ /* If page already exists return success */
+ if (!ppages)
+ {
+ *pagelist = NULL;
+ return (0);
+ }
+
+ /*
+ * Map & read page-by-page.
+ */
+ total = io_off + io_len;
+ pcur = ppages;
+ while (io_off < total)
+ {
+ ASSERT3U(io_off, ==, pcur->p_offset);
+
+ caddr_t virtaddr = sffs_page_map(pcur, segaccess);
+ uint32_t bytes = PAGESIZE;
+ error = sfprov_read(node->sf_file, virtaddr, io_off, &bytes);
+ sffs_page_unmap(pcur, virtaddr);
+ if (error != 0 || bytes < PAGESIZE)
+ {
+ /* Get rid of all kluster pages read & bail. */
+ pvn_read_done(ppages, B_ERROR);
+ return (error);
+ }
+ pcur = pcur->p_next;
+ io_off += PAGESIZE;
+ }
+
+ /*
+ * Fill in the pagelist from kluster at the requested offset.
+ */
+ pvn_plist_init(ppages, pagelist, pagelistsize, off, io_len, segaccess);
+ ASSERT(pagelist == NULL || (*pagelist)->p_offset == off);
+ return (0);
+}
+
+
+/*ARGSUSED*/
+static int
+sffs_getpage(
+ vnode_t *dvp,
+ offset_t off,
+ size_t len,
+ uint_t *protp,
+ page_t *pagelist[],
+ size_t pagelistsize,
+ struct seg *segp,
+ caddr_t addr,
+ enum seg_rw segaccess,
+ cred_t *credp
+#if !defined(VBOX_VFS_SOLARIS_10U6)
+ , caller_context_t *ct
+#endif
+ )
+{
+ int error = 0;
+ page_t **pageliststart = pagelist;
+
+ if (segaccess == S_WRITE)
+ return (ENOSYS); /* Will this ever happen? */
+
+ if (protp)
+ *protp = PROT_ALL;
+
+ /* We don't really support async ops, pretend success. */
+ if (pagelist == NULL)
+ return (0);
+
+ if (len > pagelistsize)
+ len = pagelistsize;
+ else
+ len = P2ROUNDUP(len, PAGESIZE);
+ ASSERT(pagelistsize >= len);
+
+ mutex_enter(&sffs_lock);
+
+ while (len > 0)
+ {
+ /*
+ * Look for pages in the requested offset range, or create them if we can't find any.
+ */
+ if ((*pagelist = page_lookup(dvp, off, SE_SHARED)) != NULL)
+ *(pagelist + 1) = NULL;
+ else if ((error = sffs_readpages(dvp, off, pagelist, pagelistsize, segp, addr, segaccess)) != 0)
+ {
+ while (pagelist > pageliststart)
+ page_unlock(*--pagelist);
+
+ *pagelist = NULL;
+ mutex_exit(&sffs_lock);
+ return (error);
+ }
+
+ while (*pagelist)
+ {
+ ASSERT3U((*pagelist)->p_offset, ==, off);
+ off += PAGESIZE;
+ addr += PAGESIZE;
+ if (len > 0)
+ {
+ ASSERT3U(len, >=, PAGESIZE);
+ len -= PAGESIZE;
+ }
+
+ ASSERT3U(pagelistsize, >=, PAGESIZE);
+ pagelistsize -= PAGESIZE;
+ pagelist++;
+ }
+
+ /*
+ * Fill the page list array with any pages left in the cache.
+ */
+ while (pagelistsize > 0)
+ {
+ if ((*pagelist++ = page_lookup_nowait(dvp, off, SE_SHARED)) != NULL)
+ {
+ off += PAGESIZE;
+ pagelistsize -= PAGESIZE;
+ }
+ else
+ break;
+ }
+ }
+
+ *pagelist = NULL;
+ mutex_exit(&sffs_lock);
+ return (error);
+}
+
+
+/*ARGSUSED*/
+static int
+sffs_putpage(
+ vnode_t *dvp,
+ offset_t off,
+ size_t len,
+ int flags,
+ cred_t *credp
+#if !defined(VBOX_VFS_SOLARIS_10U6)
+ , caller_context_t *ct
+#endif
+ )
+{
+ /*
+ * 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.
+ */
+ return (ENOSYS);
+}
+
+
+/*ARGSUSED*/
+static int
+sffs_map(
+ vnode_t *dvp,
+ offset_t off,
+ struct as *asp,
+ caddr_t *addrp,
+ size_t len,
+ uchar_t prot,
+ uchar_t maxprot,
+ uint_t flags,
+ cred_t *credp
+#if !defined(VBOX_VFS_SOLARIS_10U6)
+ , caller_context_t *ct
+#endif
+ )
+{
+ /*
+ * Invocation: mmap()->smmap_common()->VOP_MAP()->sffs_map(). Once the
+ * segment driver creates the new segment via segvn_create(), it'll
+ * invoke down the line VOP_ADDMAP()->sffs_addmap()
+ */
+ int error = 0;
+ sfnode_t *node = VN2SFN(dvp);
+ ASSERT(node);
+ if ((prot & PROT_WRITE))
+ return (ENOTSUP);
+
+ if (off < 0 || len > MAXOFFSET_T - off)
+ return (ENXIO);
+
+ if (dvp->v_type != VREG)
+ return (ENODEV);
+
+ if (dvp->v_flag & VNOMAP)
+ return (ENOSYS);
+
+ if (vn_has_mandatory_locks(dvp, node->sf_stat.sf_mode))
+ return (EAGAIN);
+
+ mutex_enter(&sffs_lock);
+ as_rangelock(asp);
+
+#if defined(VBOX_VFS_SOLARIS_10U6)
+ if ((flags & MAP_FIXED) == 0)
+ {
+ map_addr(addrp, len, off, 1, flags);
+ if (*addrp == NULL)
+ error = ENOMEM;
+ }
+ else
+ as_unmap(asp, *addrp, len); /* User specified address, remove any previous mappings */
+#else
+ error = choose_addr(asp, addrp, len, off, ADDR_VACALIGN, flags);
+#endif
+
+ if (error)
+ {
+ as_rangeunlock(asp);
+ mutex_exit(&sffs_lock);
+ return (error);
+ }
+
+ segvn_crargs_t vnodeargs;
+ memset(&vnodeargs, 0, sizeof(vnodeargs));
+ vnodeargs.vp = dvp;
+ vnodeargs.cred = credp;
+ vnodeargs.offset = off;
+ vnodeargs.type = flags & MAP_TYPE;
+ vnodeargs.prot = prot;
+ vnodeargs.maxprot = maxprot;
+ vnodeargs.flags = flags & ~MAP_TYPE;
+ vnodeargs.amp = NULL; /* anon. mapping */
+ vnodeargs.szc = 0; /* preferred page size code */
+ vnodeargs.lgrp_mem_policy_flags = 0;
+
+ error = as_map(asp, *addrp, len, segvn_create, &vnodeargs);
+
+ as_rangeunlock(asp);
+ mutex_exit(&sffs_lock);
+ return (error);
+}
+
+
+/*ARGSUSED*/
+static int
+sffs_addmap(
+ vnode_t *dvp,
+ offset_t off,
+ struct as *asp,
+ caddr_t addr,
+ size_t len,
+ uchar_t prot,
+ uchar_t maxprot,
+ uint_t flags,
+ cred_t *credp
+#if !defined(VBOX_VFS_SOLARIS_10U6)
+ , caller_context_t *ct
+#endif
+ )
+{
+ sfnode_t *node = VN2SFN(dvp);
+ uint64_t npages = btopr(len);
+
+ if (dvp->v_flag & VNOMAP)
+ return (ENOSYS);
+
+ ASSERT(node);
+ ASMAtomicAddU64(&node->sf_mapcnt, npages);
+ return (0);
+}
+
+
+/*ARGSUSED*/
+static int
+sffs_delmap(
+ vnode_t *dvp,
+ offset_t off,
+ struct as *asp,
+ caddr_t addr,
+ size_t len,
+ uint_t prot,
+ uint_t maxprot,
+ uint_t flags,
+ cred_t *credp
+#if !defined(VBOX_VFS_SOLARIS_10U6)
+ , caller_context_t *ct
+#endif
+ )
+{
+ sfnode_t *node = VN2SFN(dvp);
+ uint64_t npages = btopr(len);
+
+ if (dvp->v_flag & VNOMAP)
+ return (ENOSYS);
+
+ ASSERT(node->sf_mapcnt >= npages);
+ ASMAtomicSubU64(&node->sf_mapcnt, npages);
+ return (0);
+}
+#endif
+
+
/*ARGSUSED*/
static int
sffs_remove(
@@ -1758,6 +2120,15 @@ const fs_operation_def_t sffs_ops_template[] = {
VOPNAME_SETATTR, sffs_setattr,
VOPNAME_SPACE, sffs_space,
VOPNAME_WRITE, sffs_write,
+
+# if 0
+ VOPNAME_MAP, sffs_map,
+ VOPNAME_ADDMAP, sffs_addmap,
+ VOPNAME_DELMAP, sffs_delmap,
+ VOPNAME_GETPAGE, sffs_getpage,
+ VOPNAME_PUTPAGE, sffs_putpage,
+# endif
+
NULL, NULL
#else
VOPNAME_ACCESS, { .vop_access = sffs_access },
@@ -1780,6 +2151,15 @@ const fs_operation_def_t sffs_ops_template[] = {
VOPNAME_SETATTR, { .vop_setattr = sffs_setattr },
VOPNAME_SPACE, { .vop_space = sffs_space },
VOPNAME_WRITE, { .vop_write = sffs_write },
+
+# if 0
+ VOPNAME_MAP, { .vop_map = sffs_map },
+ VOPNAME_ADDMAP, { .vop_addmap = sffs_addmap },
+ VOPNAME_DELMAP, { .vop_delmap = sffs_delmap },
+ VOPNAME_GETPAGE, { .vop_getpage = sffs_getpage },
+ VOPNAME_PUTPAGE, { .vop_putpage = sffs_putpage },
+# endif
+
NULL, NULL
#endif
};
@@ -1873,6 +2253,8 @@ sffs_purge(struct sffs_data *sffs)
return (0);
}
+#if 0
+/* Debug helper functions */
static void
sfnode_print(sfnode_t *node)
{
@@ -1891,8 +2273,8 @@ sfnode_print(sfnode_t *node)
Log(("%s\n", node->sf_is_stale ? " STALE" : ""));
}
-void
-sfnode_list()
+static void
+sfnode_list(void)
{
sfnode_t *n;
for (n = avl_first(&sfnodes); n != NULL; n = AVL_NEXT(&sfnodes, n))
@@ -1901,4 +2283,5 @@ sfnode_list()
n = AVL_NEXT(&stale_sfnodes, n))
sfnode_print(n);
}
+#endif
diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h
index 2973086ff..df663f832 100644
--- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h
+++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h
@@ -1,4 +1,4 @@
-/* $Id: vboxfs_vnode.h $ */
+/* $Id: vboxfs_vnode.h 37806 2011-07-06 15:11:02Z vboxsync $ */
/** @file
* VirtualBox File System for Solaris Guests, VNode header.
*/
@@ -60,6 +60,9 @@ typedef struct sfnode {
uint64_t sf_stat_time; /* last-modified time of sf_stat */
sffs_dirents_t *sf_dir_list; /* list of entries for this directory */
sffs_stats_t *sf_dir_stats; /* file attrs for the above entries */
+#if 0
+ volatile uint64_t sf_mapcnt; /* number of mapped pages */
+#endif
} sfnode_t;
#define VN2SFN(vp) ((sfnode_t *)(vp)->v_data)
diff --git a/src/VBox/Additions/solaris/Virtio/Makefile.kmk b/src/VBox/Additions/solaris/Virtio/Makefile.kmk
index 9a80aef1e..6c92a5679 100644
--- a/src/VBox/Additions/solaris/Virtio/Makefile.kmk
+++ b/src/VBox/Additions/solaris/Virtio/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 34233 2010-11-22 11:25:55Z vboxsync $
## @file
# Sub-Makefile for Solaris Virtio drivers.
#
diff --git a/src/VBox/Additions/solaris/Virtio/Virtio-solaris.c b/src/VBox/Additions/solaris/Virtio/Virtio-solaris.c
index c521c0be9..370221bac 100644
--- a/src/VBox/Additions/solaris/Virtio/Virtio-solaris.c
+++ b/src/VBox/Additions/solaris/Virtio/Virtio-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: Virtio-solaris.c $ */
+/* $Id: Virtio-solaris.c 34233 2010-11-22 11:25:55Z vboxsync $ */
/** @file
* VirtualBox Guest Additions: Virtio Driver for Solaris.
*/
diff --git a/src/VBox/Additions/solaris/Virtio/Virtio-solaris.h b/src/VBox/Additions/solaris/Virtio/Virtio-solaris.h
index b7bef0736..68e389b9d 100644
--- a/src/VBox/Additions/solaris/Virtio/Virtio-solaris.h
+++ b/src/VBox/Additions/solaris/Virtio/Virtio-solaris.h
@@ -1,4 +1,4 @@
-/* $Id: Virtio-solaris.h $ */
+/* $Id: Virtio-solaris.h 34233 2010-11-22 11:25:55Z vboxsync $ */
/** @file
* VirtualBox Guest Additions: Virtio Driver for Solaris, header.
*/
diff --git a/src/VBox/Additions/solaris/Virtio/VirtioNet-solaris.c b/src/VBox/Additions/solaris/Virtio/VirtioNet-solaris.c
index 0fe733ce2..91c2f638f 100644
--- a/src/VBox/Additions/solaris/Virtio/VirtioNet-solaris.c
+++ b/src/VBox/Additions/solaris/Virtio/VirtioNet-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: VirtioNet-solaris.c $ */
+/* $Id: VirtioNet-solaris.c 34143 2010-11-17 20:05:36Z vboxsync $ */
/** @file
* VirtualBox Guest Additions: Virtio Network Driver for Solaris.
*/
diff --git a/src/VBox/Additions/solaris/Virtio/VirtioPci-solaris.c b/src/VBox/Additions/solaris/Virtio/VirtioPci-solaris.c
index 4a5737a10..0d5fe55f3 100644
--- a/src/VBox/Additions/solaris/Virtio/VirtioPci-solaris.c
+++ b/src/VBox/Additions/solaris/Virtio/VirtioPci-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: VirtioPci-solaris.c $ */
+/* $Id: VirtioPci-solaris.c 34233 2010-11-22 11:25:55Z vboxsync $ */
/** @file
* VirtualBox Guest Additions: Virtio Driver for Solaris, PCI Hypervisor Interface.
*/
diff --git a/src/VBox/Additions/solaris/Virtio/VirtioPci-solaris.h b/src/VBox/Additions/solaris/Virtio/VirtioPci-solaris.h
index df9ab0ed8..004cc8106 100644
--- a/src/VBox/Additions/solaris/Virtio/VirtioPci-solaris.h
+++ b/src/VBox/Additions/solaris/Virtio/VirtioPci-solaris.h
@@ -1,4 +1,4 @@
-/* $Id: VirtioPci-solaris.h $ */
+/* $Id: VirtioPci-solaris.h 34233 2010-11-22 11:25:55Z vboxsync $ */
/** @file
* VirtualBox Guest Additions: Virtio Driver for Solaris, PCI Hypervisor Interface.
*/
diff --git a/src/VBox/Additions/solaris/Virtio/VirtioRing-solaris.c b/src/VBox/Additions/solaris/Virtio/VirtioRing-solaris.c
index 81e3a12db..d8e6921ca 100644
--- a/src/VBox/Additions/solaris/Virtio/VirtioRing-solaris.c
+++ b/src/VBox/Additions/solaris/Virtio/VirtioRing-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: VirtioRing-solaris.c $ */
+/* $Id: VirtioRing-solaris.c 34233 2010-11-22 11:25:55Z vboxsync $ */
/** @file
* VirtualBox Guest Additions: Virtio Driver for Solaris, Ring implementation.
*/
diff --git a/src/VBox/Additions/x11/Installer/98vboxadd-xclient b/src/VBox/Additions/x11/Installer/98vboxadd-xclient
index f35942230..f35942230 100755..100644
--- a/src/VBox/Additions/x11/Installer/98vboxadd-xclient
+++ b/src/VBox/Additions/x11/Installer/98vboxadd-xclient
diff --git a/src/VBox/Additions/x11/Installer/x11config.pl b/src/VBox/Additions/x11/Installer/x11config.pl
index 333c659f2..333c659f2 100755..100644
--- a/src/VBox/Additions/x11/Installer/x11config.pl
+++ b/src/VBox/Additions/x11/Installer/x11config.pl
diff --git a/src/VBox/Additions/x11/Installer/x11config.sh b/src/VBox/Additions/x11/Installer/x11config.sh
index 2fd36d08f..2fd36d08f 100755..100644
--- a/src/VBox/Additions/x11/Installer/x11config.sh
+++ b/src/VBox/Additions/x11/Installer/x11config.sh
diff --git a/src/VBox/Additions/x11/Installer/x11config15.pl b/src/VBox/Additions/x11/Installer/x11config15.pl
index 877add382..877add382 100755..100644
--- a/src/VBox/Additions/x11/Installer/x11config15.pl
+++ b/src/VBox/Additions/x11/Installer/x11config15.pl
diff --git a/src/VBox/Additions/x11/Installer/x11config15sol.pl b/src/VBox/Additions/x11/Installer/x11config15sol.pl
index dc6e59579..dc6e59579 100755..100644
--- a/src/VBox/Additions/x11/Installer/x11config15sol.pl
+++ b/src/VBox/Additions/x11/Installer/x11config15sol.pl
diff --git a/src/VBox/Additions/x11/Installer/x11config15suse.pl b/src/VBox/Additions/x11/Installer/x11config15suse.pl
index e75fdcc2b..e75fdcc2b 100755..100644
--- a/src/VBox/Additions/x11/Installer/x11config15suse.pl
+++ b/src/VBox/Additions/x11/Installer/x11config15suse.pl
diff --git a/src/VBox/Additions/x11/Installer/x11restore.pl b/src/VBox/Additions/x11/Installer/x11restore.pl
index 96c1aae97..eba375855 100755..100644
--- a/src/VBox/Additions/x11/Installer/x11restore.pl
+++ b/src/VBox/Additions/x11/Installer/x11restore.pl
@@ -1,5 +1,5 @@
#!/usr/bin/perl -w
-# $Revision: 65744 $
+# $Revision: 32388 $
#
# Restore xorg.conf while removing Guest Additions.
#
diff --git a/src/VBox/Additions/x11/Makefile.kmk b/src/VBox/Additions/x11/Makefile.kmk
index c810f328b..2d1c46c4a 100644
--- a/src/VBox/Additions/x11/Makefile.kmk
+++ b/src/VBox/Additions/x11/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the X11 Guest Additions.
#
diff --git a/src/VBox/Additions/x11/VBoxClient/Makefile.kmk b/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
index 8dabb482c..38e557567 100644
--- a/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
+++ b/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37720 2011-06-30 20:27:48Z vboxsync $
## @file
# Sub-Makefile for the VirtualBox Guest Addition X11 Client.
#
@@ -23,7 +23,7 @@ include $(KBUILD_PATH)/subheader.kmk
#
PROGRAMS += VBoxClient
-VBoxClient_TEMPLATE = VBOXGUESTR3CPPEXE
+VBoxClient_TEMPLATE = VBOXGUESTR3EXE
VBoxClient_DEFS += VBOX_X11_CLIPBOARD VBOX_WITH_HGCM
ifdef VBOX_WITH_DBUS
VBoxClient_DEFS += VBOX_WITH_DBUS
@@ -69,20 +69,6 @@ endif
ifdef VBOX_WITH_GUEST_PROPS
VBoxClient_DEFS += VBOX_WITH_GUEST_PROPS
endif
-#
-# Link against libstdc++.a. (http://www.trilithium.com/johan/2005/06/static-libstdc/).
-# (It would've been preferred to avoid features depending on libstdc++, of course...)
-#
-# Actually, this is darn annoying and will *NOT* be tolerated for any new code!
-#
-VBoxClient_LIBPATH += $(VBoxClient_0_OUTDIR)
-VBoxClient_ORDERDEPS = $(VBoxClient_0_OUTDIR)/libstdc++.a
-VBoxClient_CLEAN = $(VBoxClient_0_OUTDIR)/libstdc++.a
-$$(VBoxClient_0_OUTDIR)/libstdc++.a:
- $(call MSG_L1,Forcing static libstdc++)
- $(QUIET)$(MKDIR) -p $(@D)
- $(QUIET)$(LN_EXT) -sf `$(TOOL_$(VBOX_GCC_TOOL)_CXX) $(TEMPLATE_VBOXGUESTR3CPPEXE_CXXFLAGS.$(KBUILD_TARGET_ARCH)) -print-file-name=libstdc++.a` $@ \
- || $(CP_EXT) -f `$(TOOL_$(VBOX_GCC_TOOL)_CXX) $(TEMPLATE_VBOXGUESTR3CPPEXE_CXXFLAGS.$(KBUILD_TARGET_ARCH)) -print-file-name=libstdc++.a` $@
ifdef VBOX_X11_SEAMLESS_GUEST
if defined(VBOX_WITH_TESTCASES) && !defined(VBOX_ONLY_ADDITIONS) && !defined(VBOX_ONLY_SDK)
diff --git a/src/VBox/Additions/x11/VBoxClient/VBoxClient.h b/src/VBox/Additions/x11/VBoxClient/VBoxClient.h
index 63a1f9098..252cd01bc 100644
--- a/src/VBox/Additions/x11/VBoxClient/VBoxClient.h
+++ b/src/VBox/Additions/x11/VBoxClient/VBoxClient.h
@@ -25,7 +25,7 @@ namespace VBoxClient {
/** A simple class describing a service. VBoxClient will run exactly one
* service per invocation. */
-class Service : public iprt::non_copyable
+class Service : public RTCNonCopyable
{
public:
/** Get the services default path to pidfile, relative to $HOME */
diff --git a/src/VBox/Additions/x11/VBoxClient/clipboard.cpp b/src/VBox/Additions/x11/VBoxClient/clipboard.cpp
index 06a1cd302..60eb2a04c 100644
--- a/src/VBox/Additions/x11/VBoxClient/clipboard.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/clipboard.cpp
@@ -1,4 +1,4 @@
-/** $Id: clipboard.cpp $ */
+/** $Id: clipboard.cpp 37434 2011-06-14 13:14:57Z vboxsync $ */
/** @file
* Guest Additions - X11 Shared Clipboard.
*/
@@ -185,7 +185,7 @@ int vboxClipboardConnect(void)
/* Sanity */
AssertReturn(g_ctx.client == 0, VERR_WRONG_ORDER);
- g_ctx.pBackend = ClipConstructX11(&g_ctx);
+ g_ctx.pBackend = ClipConstructX11(&g_ctx, false);
if (!g_ctx.pBackend)
rc = VERR_NO_MEMORY;
if (RT_SUCCESS(rc))
diff --git a/src/VBox/Additions/x11/VBoxClient/clipboard.h b/src/VBox/Additions/x11/VBoxClient/clipboard.h
index 10f4afe62..0d47efe22 100644
--- a/src/VBox/Additions/x11/VBoxClient/clipboard.h
+++ b/src/VBox/Additions/x11/VBoxClient/clipboard.h
@@ -118,9 +118,7 @@ public:
{
LogRelFlowFunc(("\n"));
if (mInit)
- try {
- uninit(2000);
- } catch (...) { }
+ uninit(2000);
LogRelFlowFunc(("returning\n"));
}
};
diff --git a/src/VBox/Additions/x11/VBoxClient/display.cpp b/src/VBox/Additions/x11/VBoxClient/display.cpp
index f86dac132..645273033 100644
--- a/src/VBox/Additions/x11/VBoxClient/display.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/display.cpp
@@ -1,4 +1,4 @@
-/* $Id: display.cpp $ */
+/* $Id: display.cpp 34918 2010-12-09 18:08:01Z vboxsync $ */
/** @file
* X11 guest client - display management.
*/
diff --git a/src/VBox/Additions/x11/VBoxClient/hostversion.cpp b/src/VBox/Additions/x11/VBoxClient/hostversion.cpp
index 111fe2cd2..cf55d1771 100644
--- a/src/VBox/Additions/x11/VBoxClient/hostversion.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/hostversion.cpp
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * 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;
@@ -128,7 +128,7 @@ public:
virtual int run(bool fDaemonised /* = false */)
{
int rc;
- LogRelFlowFunc(("\n"));
+ LogFlowFunc(("\n"));
/* Because we need desktop notifications to be displayed, wait
* some time to make the desktop environment load (as a work around). */
@@ -149,7 +149,7 @@ public:
{
rc = VbglR3GuestPropConnect(&uGuestPropSvcClientID);
if (RT_FAILURE(rc))
- LogRel(("Cannot connect to guest property service! rc = %Rrc\n", rc));
+ LogRel(("VBoxClient: Cannot connect to guest property service while chcking for host version! rc = %Rrc\n", rc));
}
if (RT_SUCCESS(rc))
@@ -186,7 +186,7 @@ public:
VbglR3GuestPropDisconnect(uGuestPropSvcClientID);
}
# endif /* VBOX_WITH_GUEST_PROPS */
- LogRelFlowFunc(("returning %Rrc\n", rc));
+ LogFlowFunc(("returning %Rrc\n", rc));
return rc;
}
@@ -201,3 +201,4 @@ VBoxClient::Service *VBoxClient::GetHostVersionService()
{
return new HostVersionService;
}
+
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-guest.h b/src/VBox/Additions/x11/VBoxClient/seamless-guest.h
index 092f2a25f..4a2d42205 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless-guest.h
+++ b/src/VBox/Additions/x11/VBoxClient/seamless-guest.h
@@ -19,9 +19,6 @@
#ifndef __Additions_client_seamless_guest_h
# define __Additions_client_seamless_guest_h
-#include <memory> /* for auto_ptr */
-#include <vector> /* for vector */
-
#include <iprt/types.h> /* for RTRECT */
#include "seamless-glue.h"
@@ -44,38 +41,6 @@ public:
/** Seamless mode is no longer supported */
INCAPABLE
};
-
- /**
- * Initialise the guest and ensure that it is capable of handling seamless mode
- *
- * @param pObserver An observer object to which to report changes in state and events
- * by calling its notify() method. A state change to CAPABLE also
- * signals new seamless data.
- * @returns iprt status code
- */
- int init(VBoxGuestSeamlessObserver *pObserver);
-
- /**
- * Shutdown seamless event monitoring.
- */
- void uninit(void);
-
- /**
- * Initialise seamless event reporting in the guest.
- *
- * @returns IPRT status code
- */
- int start(void);
- /** Stop reporting seamless events. */
- void stop(void);
- /** Get the current state of the guest (capable or incapable of seamless mode). */
- // meEvent getState(void);
- /** Get the current list of visible rectangles. */
- std::auto_ptr<std::vector<RTRECT> > getRects(void);
- /** Process next event in the guest event queue - called by the event thread. */
- void nextEvent(void);
- /** Wake up the event thread if it is waiting for an event so that it can exit. */
- bool interruptEvent(void);
};
#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp b/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp
index 33170ea6a..ab04873bb 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp
@@ -133,15 +133,15 @@ int VBoxGuestSeamlessHost::nextEvent(void)
/**
* Update the set of visible rectangles in the host.
*/
-void VBoxGuestSeamlessHost::updateRects(std::auto_ptr<std::vector<RTRECT> > pRects)
+void VBoxGuestSeamlessHost::updateRects(RTRECT *pRects, size_t cRects)
{
LogRelFlowFunc(("\n"));
- if (0 == pRects.get()) /* Assertion */
+ if (cRects && !pRects) /* Assertion */
{
LogRelThisFunc(("ERROR: called with null pointer!\n"));
return;
}
- VbglR3SeamlessSendRects(pRects.get()->size(), pRects.get()->empty() ? NULL : &pRects.get()->front());
+ VbglR3SeamlessSendRects(cRects, pRects);
LogRelFlowFunc(("returning\n"));
}
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-host.h b/src/VBox/Additions/x11/VBoxClient/seamless-host.h
index 5ab5213af..d10523bc7 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless-host.h
+++ b/src/VBox/Additions/x11/VBoxClient/seamless-host.h
@@ -18,9 +18,6 @@
#ifndef __Additions_client_seamless_host_h
# define __Additions_client_seamless_host_h
-#include <memory> /* for auto_ptr */
-#include <vector> /* for vector */
-
#include <VBox/log.h>
#include <VBox/VBoxGuestLib.h> /* for the R3 guest library functions */
@@ -150,7 +147,7 @@ public:
/**
* Update the set of visible rectangles in the host.
*/
- void updateRects(std::auto_ptr<std::vector<RTRECT> > pRects);
+ void updateRects(RTRECT *pRects, size_t cRects);
VBoxGuestSeamlessHost(void) : mThreadFunction(this),
mThread(&mThreadFunction, 0, RTTHREADTYPE_MSG_PUMP,
@@ -167,11 +164,7 @@ public:
if (mRunning) /* Assertion */
{
LogRel(("VBoxClient: seamless host object still running! Stopping...\n"));
- try
- {
- stop(2000);
- }
- catch(...) {}
+ stop(2000);
}
LogRelFlowFunc(("returning\n"));
}
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp b/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp
index 36aa6fb19..9e345d84a 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp
@@ -20,6 +20,7 @@
#include <iprt/err.h>
#include <iprt/assert.h>
+#include <iprt/vector.h>
#include <VBox/log.h>
#include "seamless-guest.h"
@@ -79,7 +80,7 @@ int VBoxGuestSeamlessX11::init(VBoxGuestSeamlessObserver *pObserver)
LogRel(("VBoxClient: ERROR: attempt to initialise seamless guest object twice!\n"));
return VERR_INTERNAL_ERROR;
}
- if (!mDisplay.init())
+ if (!(mDisplay = XOpenDisplay(NULL)))
{
LogRel(("VBoxClient: seamless guest object failed to acquire a connection to the display.\n"));
return VERR_ACCESS_DENIED;
@@ -126,13 +127,13 @@ void VBoxGuestSeamlessX11::stop(void)
void VBoxGuestSeamlessX11::monitorClientList(void)
{
LogRelFlowFunc(("called\n"));
- XSelectInput(mDisplay, DefaultRootWindow(mDisplay.get()), SubstructureNotifyMask);
+ XSelectInput(mDisplay, DefaultRootWindow(mDisplay), SubstructureNotifyMask);
}
void VBoxGuestSeamlessX11::unmonitorClientList(void)
{
LogRelFlowFunc(("called\n"));
- XSelectInput(mDisplay, DefaultRootWindow(mDisplay.get()), 0);
+ XSelectInput(mDisplay, DefaultRootWindow(mDisplay), 0);
}
/**
@@ -143,7 +144,7 @@ void VBoxGuestSeamlessX11::rebuildWindowTree(void)
{
LogRelFlowFunc(("called\n"));
freeWindowTree();
- addClients(DefaultRootWindow(mDisplay.get()));
+ addClients(DefaultRootWindow(mDisplay));
mChanged = true;
}
@@ -159,18 +160,19 @@ void VBoxGuestSeamlessX11::addClients(const Window hRoot)
/** Unused out parameters of XQueryTree */
Window hRealRoot, hParent;
/** The list of children of the root supplied, raw pointer */
- Window *phChildrenRaw;
+ Window *phChildrenRaw = NULL;
/** The list of children of the root supplied, auto-pointer */
- VBoxGuestX11Pointer<Window> phChildren;
+ Window *phChildren;
/** The number of children of the root supplied */
unsigned cChildren;
LogRelFlowFunc(("\n"));
- if (!XQueryTree(mDisplay.get(), hRoot, &hRealRoot, &hParent, &phChildrenRaw, &cChildren))
+ if (!XQueryTree(mDisplay, hRoot, &hRealRoot, &hParent, &phChildrenRaw, &cChildren))
return;
phChildren = phChildrenRaw;
for (unsigned i = 0; i < cChildren; ++i)
- addClientWindow(phChildren.get()[i]);
+ addClientWindow(phChildren[i]);
+ XFree(phChildrenRaw);
LogRelFlowFunc(("returning\n"));
}
@@ -180,7 +182,6 @@ void VBoxGuestSeamlessX11::addClientWindow(const Window hWin)
LogRelFlowFunc(("\n"));
XWindowAttributes winAttrib;
bool fAddWin = true;
- char *pszWinName = NULL;
Window hClient = XmuClientWindow(mDisplay, hWin);
if (isVirtualRoot(hClient))
@@ -203,7 +204,7 @@ void VBoxGuestSeamlessX11::addClientWindow(const Window hWin)
}
if (fAddWin)
{
- VBoxGuestX11Pointer<XRectangle> rects;
+ XRectangle *pRects = NULL;
int cRects = 0, iOrdering;
bool hasShape = false;
@@ -212,22 +213,23 @@ void VBoxGuestSeamlessX11::addClientWindow(const Window hWin)
if (mSupportsShape)
{
XShapeSelectInput(mDisplay, hWin, ShapeNotifyMask);
- rects = XShapeGetRectangles(mDisplay, hWin, ShapeBounding, &cRects, &iOrdering);
- if (0 == rects.get())
+ pRects = XShapeGetRectangles(mDisplay, hWin, ShapeBounding, &cRects, &iOrdering);
+ if (!pRects)
cRects = 0;
else
{
if ( (cRects > 1)
- || (rects.get()[0].x != 0)
- || (rects.get()[0].y != 0)
- || (rects.get()[0].width != winAttrib.width)
- || (rects.get()[0].height != winAttrib.height)
+ || (pRects[0].x != 0)
+ || (pRects[0].y != 0)
+ || (pRects[0].width != winAttrib.width)
+ || (pRects[0].height != winAttrib.height)
)
hasShape = true;
}
}
mGuestWindows.addWindow(hWin, hasShape, winAttrib.x, winAttrib.y,
- winAttrib.width, winAttrib.height, cRects, rects);
+ winAttrib.width, winAttrib.height, cRects,
+ pRects);
}
LogRelFlowFunc(("returning\n"));
}
@@ -240,8 +242,8 @@ void VBoxGuestSeamlessX11::addClientWindow(const Window hWin)
*/
bool VBoxGuestSeamlessX11::isVirtualRoot(Window hWin)
{
- unsigned char *windowTypeRaw;
- VBoxGuestX11Pointer<Atom> windowType;
+ unsigned char *windowTypeRaw = NULL;
+ Atom *windowType;
unsigned long ulCount;
bool rc = false;
@@ -249,15 +251,25 @@ bool VBoxGuestSeamlessX11::isVirtualRoot(Window hWin)
windowTypeRaw = XXGetProperty(mDisplay, hWin, XA_ATOM, WM_TYPE_PROP, &ulCount);
if (windowTypeRaw != NULL)
{
- windowType = reinterpret_cast<Atom *>(windowTypeRaw);
+ windowType = (Atom *)(windowTypeRaw);
if ( (ulCount != 0)
&& (*windowType == XInternAtom(mDisplay, WM_TYPE_DESKTOP_PROP, True)))
rc = true;
}
- LogRelFlowFunc(("returning %s\n", rc ? "true" : "false"));
+ if (windowTypeRaw)
+ XFree(windowTypeRaw);
+ LogRelFlowFunc(("returning %RTbool\n", rc));
return rc;
}
+DECLCALLBACK(int) VBoxGuestWinFree(VBoxGuestWinInfo *pInfo, void *pvParam)
+{
+ Display *pDisplay = (Display *)pvParam;
+
+ XShapeSelectInput(pDisplay, pInfo->Core.Key, 0);
+ delete pInfo;
+ return VINF_SUCCESS;
+}
/**
* Free all information in the tree of visible windows
@@ -266,11 +278,7 @@ void VBoxGuestSeamlessX11::freeWindowTree(void)
{
/* We use post-increment in the operation to prevent the iterator from being invalidated. */
LogRelFlowFunc(("\n"));
- for (VBoxGuestWindowList::iterator it = mGuestWindows.begin(); it != mGuestWindows.end();
- mGuestWindows.removeWindow(it++))
- {
- XShapeSelectInput(mDisplay, it->first, 0);
- }
+ mGuestWindows.detachAll(VBoxGuestWinFree, mDisplay);
LogRelFlowFunc(("returning\n"));
}
@@ -288,22 +296,41 @@ void VBoxGuestSeamlessX11::nextEvent(void)
/* Start by sending information about the current window setup to the host. We do this
here because we want to send all such information from a single thread. */
if (mChanged)
+ {
+ updateRects();
mObserver->notify();
+ }
mChanged = false;
XNextEvent(mDisplay, &event);
switch (event.type)
{
case ConfigureNotify:
+ {
+ XConfigureEvent *pConf = &event.xconfigure;
+ LogRelFlowFunc(("configure event, window=%lu, x=%i, y=%i, w=%i, h=%i, send_event=%RTbool\n",
+ (unsigned long) pConf->window, (int) pConf->x,
+ (int) pConf->y, (int) pConf->width,
+ (int) pConf->height, pConf->send_event));
+ }
doConfigureEvent(event.xconfigure.window);
break;
case MapNotify:
+ LogRelFlowFunc(("map event, window=%lu, send_event=%RTbool\n",
+ (unsigned long) event.xmap.window,
+ event.xmap.send_event));
doMapEvent(event.xmap.window);
break;
case VBoxShapeNotify: /* This is defined wrong in my X11 header files! */
+ LogRelFlowFunc(("shape event, window=%lu, send_event=%RTbool\n",
+ (unsigned long) event.xany.window,
+ event.xany.send_event));
/* the window member in xany is in the same place as in the shape event */
doShapeEvent(event.xany.window);
break;
case UnmapNotify:
+ LogRelFlowFunc(("unmap event, window=%lu, send_event=%RTbool\n",
+ (unsigned long) event.xunmap.window,
+ event.xunmap.send_event));
doUnmapEvent(event.xunmap.window);
break;
default:
@@ -319,35 +346,33 @@ void VBoxGuestSeamlessX11::nextEvent(void)
*/
void VBoxGuestSeamlessX11::doConfigureEvent(Window hWin)
{
- LogRelFlowFunc(("\n"));
- VBoxGuestWindowList::iterator iter;
-
- iter = mGuestWindows.find(hWin);
- if (iter != mGuestWindows.end())
+ VBoxGuestWinInfo *pInfo = mGuestWindows.find(hWin);
+ if (pInfo)
{
XWindowAttributes winAttrib;
if (!XGetWindowAttributes(mDisplay, hWin, &winAttrib))
return;
- iter->second->mX = winAttrib.x;
- iter->second->mY = winAttrib.y;
- iter->second->mWidth = winAttrib.width;
- iter->second->mHeight = winAttrib.height;
- if (iter->second->mhasShape)
+ pInfo->mX = winAttrib.x;
+ pInfo->mY = winAttrib.y;
+ pInfo->mWidth = winAttrib.width;
+ pInfo->mHeight = winAttrib.height;
+ if (pInfo->mhasShape)
{
- VBoxGuestX11Pointer<XRectangle> rects;
+ XRectangle *pRects;
int cRects = 0, iOrdering;
- rects = XShapeGetRectangles(mDisplay, hWin, ShapeBounding,
- &cRects, &iOrdering);
- if (rects.get() == NULL)
+ pRects = XShapeGetRectangles(mDisplay, hWin, ShapeBounding,
+ &cRects, &iOrdering);
+ if (!pRects)
cRects = 0;
- iter->second->mcRects = cRects;
- iter->second->mapRects = rects;
+ if (pInfo->mpRects)
+ XFree(pInfo->mpRects);
+ pInfo->mcRects = cRects;
+ pInfo->mpRects = pRects;
}
mChanged = true;
}
- LogRelFlowFunc(("returning\n"));
}
/**
@@ -358,10 +383,8 @@ void VBoxGuestSeamlessX11::doConfigureEvent(Window hWin)
void VBoxGuestSeamlessX11::doMapEvent(Window hWin)
{
LogRelFlowFunc(("\n"));
- VBoxGuestWindowList::iterator iter;
-
- iter = mGuestWindows.find(hWin);
- if (mGuestWindows.end() == iter)
+ VBoxGuestWinInfo *pInfo = mGuestWindows.find(hWin);
+ if (!pInfo)
{
addClientWindow(hWin);
mChanged = true;
@@ -378,21 +401,21 @@ void VBoxGuestSeamlessX11::doMapEvent(Window hWin)
void VBoxGuestSeamlessX11::doShapeEvent(Window hWin)
{
LogRelFlowFunc(("\n"));
- VBoxGuestWindowList::iterator iter;
-
- iter = mGuestWindows.find(hWin);
- if (iter != mGuestWindows.end())
+ VBoxGuestWinInfo *pInfo = mGuestWindows.find(hWin);
+ if (pInfo)
{
- VBoxGuestX11Pointer<XRectangle> rects;
+ XRectangle *pRects;
int cRects = 0, iOrdering;
- rects = XShapeGetRectangles(mDisplay, hWin, ShapeBounding, &cRects,
- &iOrdering);
- if (rects.get() == NULL)
+ pRects = XShapeGetRectangles(mDisplay, hWin, ShapeBounding, &cRects,
+ &iOrdering);
+ if (!pRects)
cRects = 0;
- iter->second->mhasShape = true;
- iter->second->mcRects = cRects;
- iter->second->mapRects = rects;
+ pInfo->mhasShape = true;
+ if (pInfo->mpRects)
+ XFree(pInfo->mpRects);
+ pInfo->mcRects = cRects;
+ pInfo->mpRects = pRects;
mChanged = true;
}
LogRelFlowFunc(("returning\n"));
@@ -406,68 +429,97 @@ void VBoxGuestSeamlessX11::doShapeEvent(Window hWin)
void VBoxGuestSeamlessX11::doUnmapEvent(Window hWin)
{
LogRelFlowFunc(("\n"));
- VBoxGuestWindowList::iterator iter;
-
- iter = mGuestWindows.find(hWin);
- if (mGuestWindows.end() != iter)
+ VBoxGuestWinInfo *pInfo = mGuestWindows.removeWindow(hWin);
+ if (pInfo)
{
- mGuestWindows.removeWindow(iter);
+ VBoxGuestWinFree(pInfo, mDisplay);
mChanged = true;
}
LogRelFlowFunc(("returning\n"));
}
/**
- * Sends an updated list of visible rectangles to the host
+ * Gets the list of visible rectangles
*/
-std::auto_ptr<std::vector<RTRECT> > VBoxGuestSeamlessX11::getRects(void)
+RTRECT *VBoxGuestSeamlessX11::getRects(void)
+{
+ return mpRects;
+}
+
+/**
+ * Gets the number of rectangles in the visible rectangle list
+ */
+size_t VBoxGuestSeamlessX11::getRectCount(void)
+{
+ return mcRects;
+}
+
+RTVEC_DECL(RectList, RTRECT)
+
+DECLCALLBACK(int) getRectsCallback(VBoxGuestWinInfo *pInfo,
+ struct RectList *pRects)
+{
+ if (pInfo->mhasShape)
+ {
+ for (int i = 0; i < pInfo->mcRects; ++i)
+ {
+ RTRECT *pRect;
+
+ pRect = RectListPushBack(pRects);
+ if (!pRect)
+ return VERR_NO_MEMORY;
+ pRect->xLeft = pInfo->mX
+ + pInfo->mpRects[i].x;
+ pRect->yBottom = pInfo->mY
+ + pInfo->mpRects[i].y
+ + pInfo->mpRects[i].height;
+ pRect->xRight = pInfo->mX
+ + pInfo->mpRects[i].x
+ + pInfo->mpRects[i].width;
+ pRect->yTop = pInfo->mY
+ + pInfo->mpRects[i].y;
+ }
+ }
+ else
+ {
+ RTRECT *pRect;
+
+ pRect = RectListPushBack(pRects);
+ if (!pRect)
+ return VERR_NO_MEMORY;
+ pRect->xLeft = pInfo->mX;
+ pRect->yBottom = pInfo->mY
+ + pInfo->mHeight;
+ pRect->xRight = pInfo->mX
+ + pInfo->mWidth;
+ pRect->yTop = pInfo->mY;
+ }
+ return VINF_SUCCESS;
+}
+
+/**
+ * Updates the list of seamless rectangles
+ */
+int VBoxGuestSeamlessX11::updateRects(void)
{
LogRelFlowFunc(("\n"));
unsigned cRects = 0;
- std::auto_ptr<std::vector<RTRECT> > apRects(new std::vector<RTRECT>);
+ struct RectList rects = RTVEC_INITIALIZER;
if (0 != mcRects)
{
- apRects.get()->reserve(mcRects * 2);
- }
- for (VBoxGuestWindowList::iterator it = mGuestWindows.begin();
- it != mGuestWindows.end(); ++it)
- {
- if (it->second->mhasShape)
- {
- for (int i = 0; i < it->second->mcRects; ++i)
- {
- RTRECT rect;
- rect.xLeft = it->second->mX
- + it->second->mapRects.get()[i].x;
- rect.yBottom = it->second->mY
- + it->second->mapRects.get()[i].y
- + it->second->mapRects.get()[i].height;
- rect.xRight = it->second->mX
- + it->second->mapRects.get()[i].x
- + it->second->mapRects.get()[i].width;
- rect.yTop = it->second->mY
- + it->second->mapRects.get()[i].y;
- apRects.get()->push_back(rect);
- }
- cRects += it->second->mcRects;
- }
- else
- {
- RTRECT rect;
- rect.xLeft = it->second->mX;
- rect.yBottom = it->second->mY
- + it->second->mHeight;
- rect.xRight = it->second->mX
- + it->second->mWidth;
- rect.yTop = it->second->mY;
- apRects.get()->push_back(rect);
- ++cRects;
- }
+ int rc = RectListReserve(&rects, mcRects * 2);
+ if (RT_FAILURE(rc))
+ return rc;
}
- mcRects = cRects;
+ mGuestWindows.doWithAll((PVBOXGUESTWINCALLBACK)getRectsCallback,
+ &rects);
+ if (mpRects)
+ RTMemFree(mpRects);
+ mcRects = RectListSize(&rects);
+ mpRects = RectListDetach(&rects);
LogRelFlowFunc(("returning\n"));
- return apRects;
+ return VINF_SUCCESS;
}
/**
@@ -483,12 +535,12 @@ bool VBoxGuestSeamlessX11::interruptEvent(void)
/* Message contents set to zero. */
XClientMessageEvent clientMessage = { ClientMessage, 0, 0, 0, 0, 0, 8 };
- if (0 != XSendEvent(mDisplay, DefaultRootWindow(mDisplay.get()), false, PropertyChangeMask,
+ if (0 != XSendEvent(mDisplay, DefaultRootWindow(mDisplay), false, PropertyChangeMask,
reinterpret_cast<XEvent *>(&clientMessage)))
{
XFlush(mDisplay);
rc = true;
}
- LogRelFlowFunc(("returning %s\n", rc ? "true" : "false"));
+ LogRelFlowFunc(("returning %RTbool\n", rc));
return rc;
}
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-x11.h b/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
index 9277644b2..db2a6f125 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
+++ b/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
@@ -20,6 +20,7 @@
# define __Additions_linux_seamless_x11_h
#include <VBox/log.h>
+#include <iprt/avl.h>
#include "seamless-guest.h"
@@ -27,147 +28,18 @@
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
-#include <map>
-#include <vector>
-
#define WM_TYPE_PROP "_NET_WM_WINDOW_TYPE"
#define WM_TYPE_DESKTOP_PROP "_NET_WM_WINDOW_TYPE_DESKTOP"
/* This is defined wrong in my X11 header files! */
#define VBoxShapeNotify 64
-/**
- * Wrapper class around the VBoxGuestX11Pointer to provide reference semantics.
- * See auto_ptr in the C++ <memory> header.
- */
-template <class T>
-struct VBoxGuestX11PointerRef
-{
- T *mValue;
-
- VBoxGuestX11PointerRef(T* pValue) { mValue = pValue; }
-};
-
-/** An auto pointer for pointers which have to be XFree'd. */
-template <class T>
-class VBoxGuestX11Pointer
-{
-private:
- T *mValue;
-public:
- VBoxGuestX11Pointer(T *pValue = 0) { mValue = pValue; }
- ~VBoxGuestX11Pointer() { if (0 != mValue) XFree(mValue); }
-
- /** release method to get the pointer's value and "reset" the pointer. */
- T *release(void) { T *pTmp = mValue; mValue = 0; return pTmp; }
-
- /** reset the pointer value to zero or to another pointer. */
- void reset(T* pValue = 0) { if (pValue != mValue) { XFree(mValue); mValue = pValue; } }
-
- /** Copy constructor */
- VBoxGuestX11Pointer(VBoxGuestX11Pointer &orig) { mValue = orig.release(); }
-
- /** Copy from equivalent class */
- template <class T1>
- VBoxGuestX11Pointer(VBoxGuestX11Pointer<T1> &orig) { mValue = orig.release(); }
-
- /** Assignment operator. */
- VBoxGuestX11Pointer& operator=(VBoxGuestX11Pointer &orig)
- {
- reset(orig.release());
- return *this;
- }
-
- /** Assignment from equivalent class. */
- template <class T1>
- VBoxGuestX11Pointer& operator=(VBoxGuestX11Pointer<T1> &orig)
- {
- reset(orig.release);
- return *this;
- }
-
- /** Assignment from a pointer. */
- VBoxGuestX11Pointer& operator=(T *pValue)
- {
- if (0 != mValue)
- {
- XFree(mValue);
- }
- mValue = pValue;
- return *this;
- }
-
- /** Dereference with * operator. */
- T &operator*() { return *mValue; }
-
- /** Dereference with -> operator. */
- T *operator->() { return mValue; }
-
- /** Accessing the value inside. */
- T *get(void) { return mValue; }
-
- /** Convert a reference structure into an X11 pointer. */
- VBoxGuestX11Pointer(VBoxGuestX11PointerRef<T> ref) { mValue = ref.mValue; }
-
- /** Assign from a reference structure into an X11 pointer. */
- VBoxGuestX11Pointer& operator=(VBoxGuestX11PointerRef<T> ref)
- {
- if (ref.mValue != mValue)
- {
- XFree(mValue);
- mValue = ref.mValue;
- }
- return *this;
- }
-
- /** Typecast an X11 pointer to a reference structure. */
- template <class T1>
- operator VBoxGuestX11PointerRef<T1>() { return VBoxGuestX11PointerRef<T1>(release()); }
-
- /** Typecast an X11 pointer to an X11 pointer around a different type. */
- template <class T1>
- operator VBoxGuestX11Pointer<T1>() { return VBoxGuestX11Pointer<T1>(release()); }
-};
-
-/**
- * Wrapper class around an X11 display pointer which takes care of closing the display
- * when it is destroyed at the latest.
- */
-class VBoxGuestX11Display
-{
-private:
- Display *mDisplay;
-public:
- VBoxGuestX11Display(void) { mDisplay = NULL; }
- bool init(char *name = NULL)
- {
- LogRelFlowFunc(("\n"));
- mDisplay = XOpenDisplay(name);
- LogRelFlowFunc(("returning\n"));
- return (mDisplay != NULL);
- }
- operator Display *() { return mDisplay; }
- Display *get(void) { return mDisplay; }
- bool isValid(void) { return (mDisplay != NULL); }
- int close(void)
- {
- LogRelFlowFunc(("\n"));
- int rc = XCloseDisplay(mDisplay);
- mDisplay = NULL;
- LogRelFlowFunc(("returning\n"));
- return rc;
- }
- ~VBoxGuestX11Display()
- {
- if (mDisplay != NULL)
- close();
- }
-};
-
/** Structure containing information about a guest window's position and visible area.
Used inside of VBoxGuestWindowList. */
struct VBoxGuestWinInfo {
public:
+ /** Header structure for insertion into an AVL tree */
+ AVLU32NODECORE Core;
/** Is the window currently mapped? */
bool mhasShape;
/** Co-ordinates in the guest screen. */
@@ -176,15 +48,21 @@ public:
int mWidth, mHeight;
/** Number of rectangles used to represent the visible area. */
int mcRects;
- /** Rectangles representing the visible area. These must be allocated by XMalloc
- and will be freed automatically if non-null when the class is destroyed. */
- VBoxGuestX11Pointer<XRectangle> mapRects;
+ /** Rectangles representing the visible area. These must be allocated
+ * by XMalloc and will be freed automatically if non-null when the class
+ * is destroyed. */
+ XRectangle *mpRects;
/** Constructor. */
VBoxGuestWinInfo(bool hasShape, int x, int y, int w, int h, int cRects,
- VBoxGuestX11Pointer<XRectangle> rects)
- : mapRects(rects)
+ XRectangle *pRects)
+ : mhasShape(hasShape), mX(x), mY(y), mWidth(w), mHeight(h),
+ mcRects(cRects), mpRects(pRects) {}
+
+ /** Destructor */
+ ~VBoxGuestWinInfo()
{
- mhasShape = hasShape, mX = x; mY = y; mWidth = w; mHeight = h; mcRects = cRects;
+ if (mpRects)
+ XFree(mpRects);
}
private:
@@ -193,11 +71,22 @@ private:
VBoxGuestWinInfo& operator=(const VBoxGuestWinInfo&);
};
+/** Callback type used for "DoWithAll" calls */
+typedef DECLCALLBACK(int) VBOXGUESTWINCALLBACK(VBoxGuestWinInfo *, void *);
+/** Pointer to VBOXGUESTWINCALLBACK */
+typedef VBOXGUESTWINCALLBACK *PVBOXGUESTWINCALLBACK;
+
+DECLCALLBACK(int) inline VBoxGuestWinCleanup(VBoxGuestWinInfo *pInfo, void *)
+{
+ delete pInfo;
+ return VINF_SUCCESS;
+}
+
/**
- * This class is just a wrapper around a map of structures containing information about
- * the windows on the guest system. It has a function for adding a structure (see addWindow),
- * for removing it by window handle (see removeWindow) and an iterator for
- * going through the list.
+ * This class is just a wrapper around a map of structures containing
+ * information about the windows on the guest system. It has a function for
+ * adding a structure (see addWindow) and one for removing it by window
+ * handle (see removeWindow).
*/
class VBoxGuestWindowList
{
@@ -207,56 +96,52 @@ private:
VBoxGuestWindowList& operator=(const VBoxGuestWindowList&);
// Private class members
- std::map<Window, VBoxGuestWinInfo *> mWindows;
+ AVLU32TREE mWindows;
public:
- // Just proxy iterators to map::iterator
- typedef std::map<Window, VBoxGuestWinInfo *>::const_iterator const_iterator;
- typedef std::map<Window, VBoxGuestWinInfo *>::iterator iterator;
-
// Constructor
- VBoxGuestWindowList(void) {}
+ VBoxGuestWindowList(void) : mWindows(NULL) {}
// Destructor
~VBoxGuestWindowList()
{
- /* We use post-increment in the operation to prevent the iterator from being invalidated. */
- try
- {
- for (iterator it = begin(); it != end(); removeWindow(it++))
- ;
- }
- catch(...) {}
+ /** @todo having this inside the container class hard codes that the
+ * elements have to be allocated with the "new" operator, and
+ * I don't see a need to require this. */
+ doWithAll(VBoxGuestWinCleanup, NULL);
}
// Standard operations
- const_iterator begin() const { return mWindows.begin(); }
- iterator begin() { return mWindows.begin(); }
- const_iterator end() const { return mWindows.end(); }
- iterator end() { return mWindows.end(); }
- const_iterator find(Window win) const { return mWindows.find(win); }
- iterator find(Window win) { return mWindows.find(win); }
-
- void addWindow(Window hWin, bool isMapped, int x, int y, int w, int h, int cRects,
- VBoxGuestX11Pointer<XRectangle> rects)
+ VBoxGuestWinInfo *find(Window hWin)
{
- LogRelFlowFunc(("\n"));
- VBoxGuestWinInfo *pInfo = new VBoxGuestWinInfo(isMapped, x, y, w, h, cRects,
- rects);
- mWindows.insert(std::pair<Window, VBoxGuestWinInfo *>(hWin, pInfo));
- LogRelFlowFunc(("returning\n"));
+ return (VBoxGuestWinInfo *)RTAvlU32Get(&mWindows, hWin);
}
- void removeWindow(iterator it)
+ void detachAll(PVBOXGUESTWINCALLBACK pCallback, void *pvParam)
{
- LogRelFlowFunc(("called\n"));
- delete it->second;
- mWindows.erase(it);
+ RTAvlU32Destroy(&mWindows, (PAVLU32CALLBACK)pCallback, pvParam);
+ }
+
+ int doWithAll(PVBOXGUESTWINCALLBACK pCallback, void *pvParam)
+ {
+ return RTAvlU32DoWithAll(&mWindows, 1, (PAVLU32CALLBACK)pCallback,
+ pvParam);
+ }
+
+ bool addWindow(Window hWin, bool isMapped, int x, int y, int w, int h, int cRects,
+ XRectangle *pRects)
+ {
+ LogRelFlowFunc(("\n"));
+ VBoxGuestWinInfo *pInfo = new VBoxGuestWinInfo(isMapped, x, y, w, h, cRects,
+ pRects);
+ pInfo->Core.Key = hWin;
+ LogRelFlowFunc(("returning\n"));
+ return RTAvlU32Insert(&mWindows, &pInfo->Core);
}
- void removeWindow(Window hWin)
+ VBoxGuestWinInfo *removeWindow(Window hWin)
{
LogRelFlowFunc(("called\n"));
- removeWindow(find(hWin));
+ return (VBoxGuestWinInfo *)RTAvlU32Remove(&mWindows, hWin);
}
};
@@ -273,12 +158,12 @@ private:
/** Pointer to the observer class. */
VBoxGuestSeamlessObserver *mObserver;
/** Our connection to the X11 display we are running on. */
- VBoxGuestX11Display mDisplay;
+ Display *mDisplay;
/** Class to keep track of visible guest windows. */
VBoxGuestWindowList mGuestWindows;
- /** Keeps track of the total number of rectangles needed for the visible area of all
- guest windows on the last call to getRects. Used for pre-allocating space in
- the vector of rectangles passed to the host. */
+ /** The current set of seamless rectangles. */
+ RTRECT *mpRects;
+ /** The current number of seamless rectangles. */
int mcRects;
/** Do we support the X shaped window extension? */
bool mSupportsShape;
@@ -306,6 +191,7 @@ private:
void addClientWindow(Window hWin);
void freeWindowTree(void);
void updateHostSeamlessInfo(void);
+ int updateRects(void);
public:
/**
@@ -337,7 +223,9 @@ public:
/** Stop reporting seamless events. */
void stop(void);
/** Get the current list of visible rectangles. */
- std::auto_ptr<std::vector<RTRECT> > getRects(void);
+ RTRECT *getRects(void);
+ /** Get the number of visible rectangles in the current list */
+ size_t getRectCount(void);
/** Process next event in the guest event queue - called by the event thread. */
void nextEvent(void);
@@ -352,17 +240,14 @@ public:
void doShapeEvent(Window hWin);
VBoxGuestSeamlessX11(void)
- {
- mObserver = 0; mcRects = 0; mEnabled = false; mSupportsShape = false;
- }
+ : mObserver(0), mDisplay(NULL), mpRects(NULL), mcRects(0),
+ mSupportsShape(false), mEnabled(false), mChanged(false) {}
~VBoxGuestSeamlessX11()
{
- try
- {
- uninit();
- }
- catch(...) {}
+ uninit();
+ if (mDisplay)
+ XCloseDisplay(mDisplay);
}
};
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless.h b/src/VBox/Additions/x11/VBoxClient/seamless.h
index 61e8900ae..46b45b6e9 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless.h
+++ b/src/VBox/Additions/x11/VBoxClient/seamless.h
@@ -123,7 +123,7 @@ public:
virtual void notify(void)
{
- mHost->updateRects(mGuest->getRects());
+ mHost->updateRects(mGuest->getRects(), mGuest->getRectCount());
}
};
diff --git a/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp b/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp
index 17ecfdea7..481f7f157 100644
--- a/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp
@@ -1,5 +1,6 @@
/** @file
* Automated test of the X11 seamless Additions code.
+ * @todo Better separate test data from implementation details!
*/
/*
@@ -14,7 +15,6 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include <iostream>
#include <stdlib.h> /* exit() */
#include <X11/Xatom.h>
@@ -67,6 +67,7 @@ extern "C" Atom XInternAtom(Display *display, const char *atom_name,
Bool only_if_exists);
Atom XInternAtom(Display *display, const char *atom_name, Bool only_if_exists)
{
+ Assert(display == TEST_DISPLAY);
if (!RTStrCmp(atom_name, WM_TYPE_PROP))
return (Atom) ATOM_PROP;
if (!RTStrCmp(atom_name, WM_TYPE_DESKTOP_PROP))
@@ -95,8 +96,9 @@ int XGetWindowProperty(Display *display, Window w, Atom property,
unsigned long *bytes_after_return,
unsigned char **prop_return)
{
- Atom atomType = XInternAtom (NULL, WM_TYPE_PROP, true);
- Atom atomTypeDesktop = XInternAtom (NULL, WM_TYPE_DESKTOP_PROP, true);
+ Assert(display == TEST_DISPLAY);
+ Atom atomType = XInternAtom (display, WM_TYPE_PROP, true);
+ Atom atomTypeDesktop = XInternAtom (display, WM_TYPE_DESKTOP_PROP, true);
/* We only handle things we expect. */
AssertReturn((req_type == XA_ATOM) || (req_type == AnyPropertyType),
0xffff);
@@ -130,6 +132,7 @@ extern "C" Bool XShapeQueryExtension (Display *dpy, int *event_basep,
int *error_basep);
Bool XShapeQueryExtension (Display *dpy, int *event_basep, int *error_basep)
{
+ Assert(dpy == TEST_DISPLAY);
return true;
}
@@ -137,6 +140,7 @@ Bool XShapeQueryExtension (Display *dpy, int *event_basep, int *error_basep)
extern "C" int XSelectInput(Display *display, Window w, long event_mask);
int XSelectInput(Display *display, Window w, long event_mask)
{
+ Assert(display == TEST_DISPLAY);
return 0;
}
@@ -144,11 +148,14 @@ int XSelectInput(Display *display, Window w, long event_mask)
extern "C" void XShapeSelectInput(Display *display, Window w,
unsigned long event_mask);
void XShapeSelectInput(Display *display, Window w, unsigned long event_mask)
-{}
+{
+ Assert(display == TEST_DISPLAY);
+}
extern "C" Window XDefaultRootWindow(Display *display);
Window XDefaultRootWindow(Display *display)
{
+ Assert(display == TEST_DISPLAY);
return TEST_ROOT;
}
@@ -164,6 +171,7 @@ Status XQueryTree(Display *display, Window w, Window *root_return,
Window *parent_return, Window **children_return,
unsigned int *nchildren_return)
{
+ Assert(display == TEST_DISPLAY);
AssertReturn(w == TEST_ROOT, False); /* We support nothing else */
AssertPtrReturn(children_return, False);
AssertReturn(g_paSmlsWindows, False);
@@ -181,6 +189,7 @@ Status XQueryTree(Display *display, Window w, Window *root_return,
extern "C" Window XmuClientWindow(Display *dpy, Window win);
Window XmuClientWindow(Display *dpy, Window win)
{
+ Assert(dpy == TEST_DISPLAY);
return win;
}
@@ -189,6 +198,7 @@ extern "C" Status XGetWindowAttributes(Display *display, Window w,
Status XGetWindowAttributes(Display *display, Window w,
XWindowAttributes *window_attributes_return)
{
+ Assert(display == TEST_DISPLAY);
AssertPtrReturn(window_attributes_return, 1);
for (unsigned i = 0; i < g_cSmlsWindows; ++i)
if (g_paSmlsWindows[i] == w)
@@ -206,6 +216,7 @@ extern "C" Status XGetWMNormalHints(Display *display, Window w,
Status XGetWMNormalHints(Display *display, Window w,
XSizeHints *hints_return, long *supplied_return)
{
+ Assert(display == TEST_DISPLAY);
return 1;
}
@@ -229,6 +240,7 @@ extern "C" XRectangle *XShapeGetRectangles (Display *dpy, Window window,
XRectangle *XShapeGetRectangles (Display *dpy, Window window, int kind,
int *count, int *ordering)
{
+ Assert(dpy == TEST_DISPLAY);
if ((window != g_SmlsShapedWindow) || (window == 0))
return NULL; /* Probably not correct, but works for us. */
*count = g_cSmlsShapeRectangles;
@@ -246,11 +258,24 @@ static void smlsSetShapeRectangles(Window window, int cRects,
g_pSmlsShapeRectangles = pRects;
}
+static int g_SmlsEventType = 0;
+static Window g_SmlsEventWindow = 0;
+
/* This should not be needed in the bits of the code we test. */
extern "C" int XNextEvent(Display *display, XEvent *event_return);
int XNextEvent(Display *display, XEvent *event_return)
{
- AssertFailedReturn(0);
+ Assert(display == TEST_DISPLAY);
+ event_return->xany.type = g_SmlsEventType;
+ event_return->xany.window = g_SmlsEventWindow;
+ event_return->xmap.window = g_SmlsEventWindow;
+ return True;
+}
+
+static void smlsSetNextEvent(int type, Window window)
+{
+ g_SmlsEventType = type;
+ g_SmlsEventWindow = window;
}
/* This should not be needed in the bits of the code we test. */
@@ -259,6 +284,7 @@ extern "C" Status XSendEvent(Display *display, Window w, Bool propagate,
Status XSendEvent(Display *display, Window w, Bool propagate,
long event_mask, XEvent *event_send)
{
+ Assert(display == TEST_DISPLAY);
AssertFailedReturn(0);
}
@@ -266,9 +292,24 @@ Status XSendEvent(Display *display, Window w, Bool propagate,
extern "C" int XFlush(Display *display);
int XFlush(Display *display)
{
+ Assert(display == TEST_DISPLAY);
AssertFailedReturn(0);
}
+/** Dummy observer class */
+class testObserver: public VBoxGuestSeamlessObserver
+{
+ bool mfNotified;
+public:
+ testObserver() : mfNotified(false) {}
+ virtual void notify(void)
+ {
+ mfNotified = true;
+ }
+ virtual ~testObserver() {}
+ bool isNotified(void) { return mfNotified; }
+};
+
/*****************************
* The actual tests to be run *
*****************************/
@@ -286,9 +327,6 @@ static const char *g_pszTestName = NULL;
* report them in, @todo sort this). We expect that the set of visible
* windows will be the same whether we start the code before the event and
* handle it or start the code after the event.
- *
- * If it is ever needed I could write a small tool to record a fixture on
- * a live guest, but I will put that off as long as I can.
*/
struct SMLSFIXTURE
{
@@ -326,7 +364,7 @@ struct SMLSFIXTURE
XRectangle *paShapeRectsAfter;
/** The event to delivered */
int x11EventType;
- /** The windows for which the event in @enmEvent is delivered */
+ /** The window for which the event in @enmEvent is delivered */
Window hEventWindow;
/** The number of windows expected to be reported at the end of the
* fixture */
@@ -448,7 +486,7 @@ static SMLSFIXTURE g_testMap =
g_aRects1
};
-/*** Test fixture to test the code against X11 unmap events ***/
+/*** Test fixtures to test the code against X11 unmap events ***/
static XWindowAttributes g_aAttrib4After[] =
{ { 100, 200, 300, 400, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IsUnmapped }
@@ -478,6 +516,37 @@ static SMLSFIXTURE g_testUnmap =
NULL
};
+/*** A window we are not monitoring has been unmapped. Nothing should
+ *** happen, especially nothing bad. ***/
+
+static RTRECT g_aRects2[] =
+{
+ { 100, 200, 150, 250 },
+ { 150, 250, 300, 500 }
+};
+
+static SMLSFIXTURE g_testUnmapOther =
+{
+ RT_ELEMENTS(g_ahWin1),
+ g_ahWin1,
+ g_aAttrib1Before,
+ g_apszNames1,
+ 20,
+ RT_ELEMENTS(g_aRectangle1),
+ g_aRectangle1,
+ RT_ELEMENTS(g_ahWin1),
+ g_ahWin1,
+ g_aAttrib1Before,
+ g_apszNames1,
+ 20,
+ RT_ELEMENTS(g_aRectangle1),
+ g_aRectangle1,
+ UnmapNotify,
+ 21,
+ RT_ELEMENTS(g_aRects2),
+ g_aRects2
+};
+
/*** Test fixture to test the code against X11 shape events ***/
static XRectangle g_aRectangle5Before[] =
@@ -529,9 +598,10 @@ static void smlsPrintDiffRects(RTRECT *pExp, RTRECT *pGot)
static unsigned smlsDoFixture(SMLSFIXTURE *pFixture, const char *pszDesc)
{
VBoxGuestSeamlessX11 subject;
+ testObserver observer;
unsigned cErrs = 0;
- subject.init(NULL);
+ subject.init(&observer);
smlsSetWindowAttributes(pFixture->paAttribsBefore,
pFixture->pahWindowsBefore,
pFixture->cWindowsBefore,
@@ -547,59 +617,65 @@ static unsigned smlsDoFixture(SMLSFIXTURE *pFixture, const char *pszDesc)
smlsSetShapeRectangles(pFixture->hShapeWindowAfter,
pFixture->cShapeRectsAfter,
pFixture->paShapeRectsAfter);
- switch(pFixture->x11EventType)
+ smlsSetNextEvent(pFixture->x11EventType, pFixture->hEventWindow);
+ if (observer.isNotified()) /* Initial window tree rebuild */
{
- case ConfigureNotify:
- subject.doConfigureEvent(pFixture->hEventWindow);
- break;
- case MapNotify:
- subject.doMapEvent(pFixture->hEventWindow);
- break;
- case UnmapNotify:
- subject.doUnmapEvent(pFixture->hEventWindow);
- break;
- case VBoxShapeNotify:
- subject.doShapeEvent(pFixture->hEventWindow);
- break;
- default:
- break;
+ RTPrintf("%s: fixture: %s. Notification was set before the first event!!!\n",
+ g_pszTestName, pszDesc);
+ ++cErrs;
+ }
+ subject.nextEvent();
+ if (!observer.isNotified())
+ {
+ RTPrintf("%s: fixture: %s. No notification was sent for the initial window tree rebuild.\n",
+ g_pszTestName, pszDesc);
+ ++cErrs;
+ }
+ smlsSetNextEvent(0, 0);
+ subject.nextEvent();
+ if (!observer.isNotified())
+ {
+ RTPrintf("%s: fixture: %s. No notification was sent after the event.\n",
+ g_pszTestName, pszDesc);
+ ++cErrs;
}
- std::auto_ptr<std::vector<RTRECT> > rects = subject.getRects();
- if (rects->size() != pFixture->cReportedRects)
+ RTRECT *pRects = subject.getRects();
+ size_t cRects = subject.getRectCount();
+ if (cRects != pFixture->cReportedRects)
{
RTPrintf("%s: fixture: %s. Wrong number of rectangles reported after processing event (expected %u, got %u).\n",
g_pszTestName, pszDesc, pFixture->cReportedRects,
- (*rects).size());
+ cRects);
++cErrs;
}
else
- for (unsigned i = 0; i < rects->size(); ++i)
- if (!smlsCompRect(&(*rects)[i], &pFixture->paReportedRects[i]))
+ for (unsigned i = 0; i < cRects; ++i)
+ if (!smlsCompRect(&pRects[i], &pFixture->paReportedRects[i]))
{
RTPrintf("%s: fixture: %s. Rectangle %u wrong after processing event.\n",
g_pszTestName, pszDesc, i);
smlsPrintDiffRects(&pFixture->paReportedRects[i],
- &(*rects)[i]);
+ &pRects[i]);
++cErrs;
break;
}
subject.stop();
subject.start();
- if (rects->size() != pFixture->cReportedRects)
+ if (cRects != pFixture->cReportedRects)
{
RTPrintf("%s: fixture: %s. Wrong number of rectangles reported without processing event (expected %u, got %u).\n",
g_pszTestName, pszDesc, pFixture->cReportedRects,
- (*rects).size());
+ cRects);
++cErrs;
}
else
- for (unsigned i = 0; i < rects->size(); ++i)
- if (!smlsCompRect(&(*rects)[i], &pFixture->paReportedRects[i]))
+ for (unsigned i = 0; i < cRects; ++i)
+ if (!smlsCompRect(&pRects[i], &pFixture->paReportedRects[i]))
{
RTPrintf("%s: fixture: %s. Rectangle %u wrong without processing event.\n",
g_pszTestName, pszDesc, i);
smlsPrintDiffRects(&pFixture->paReportedRects[i],
- &(*rects)[i]);
+ &pRects[i]);
++cErrs;
break;
}
@@ -620,6 +696,8 @@ int main( int argc, char **argv)
"ConfigureNotify event (window resized)");
cErrs += smlsDoFixture(&g_testMap, "MapNotify event");
cErrs += smlsDoFixture(&g_testUnmap, "UnmapNotify event");
+ cErrs += smlsDoFixture(&g_testUnmapOther,
+ "UnmapNotify event for unmonitored window");
cErrs += smlsDoFixture(&g_testShape, "ShapeNotify event");
if (cErrs > 0)
RTPrintf("%u errors\n", cErrs);
diff --git a/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp b/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
index f23665553..8e6192bbf 100644
--- a/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
@@ -14,11 +14,11 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include <iostream>
#include <stdlib.h> /* exit() */
#include <iprt/initterm.h>
#include <iprt/semaphore.h>
+#include <iprt/stream.h>
#include <VBox/VBoxGuestLib.h>
#include "../seamless.h"
@@ -27,28 +27,27 @@ static RTSEMEVENT eventSem;
int VbglR3SeamlessSendRects(uint32_t cRects, PRTRECT pRects)
{
- std::cout << "Received rectangle update (" << cRects << " rectangles):" << std::endl;
+ RTPrintf("Received rectangle update (%u rectangles):\n", cRects);
for (unsigned i = 0; i < cRects; ++i)
{
- std::cout << " xLeft: " << pRects[i].xLeft << " yTop: " << pRects[i].yTop
- << " xRight: " << pRects[i].xRight << " yBottom: " << pRects[i].yBottom
- << std::endl;
+ RTPrintf(" xLeft: %d yTop: %d xRight: %d yBottom: %d\n",
+ pRects[i].xLeft, pRects[i].yTop, pRects[i].xRight,
+ pRects[i].yBottom);
}
return true;
}
int VbglR3SeamlessSetCap(bool bState)
{
- std::cout << (bState ? "Seamless capability set" : "Seamless capability unset")
- << std::endl;
+ RTPrintf("%s\n", bState ? "Seamless capability set"
+ : "Seamless capability unset");
return true;
}
int VbglR3CtlFilterMask(uint32_t u32OrMask, uint32_t u32NotMask)
{
- std::cout << "IRQ filter mask changed. Or mask: 0x" << std::hex << u32OrMask
- << ". Not mask: 0x" << u32NotMask << std::dec
- << std::endl;
+ RTPrintf("IRQ filter mask changed. Or mask: 0x%x. Not mask: 0x%x\n",
+ u32OrMask, u32NotMask);
return true;
}
@@ -88,74 +87,45 @@ int vboxClientXLibErrorHandler(Display *pDisplay, XErrorEvent *pError)
if (pError->error_code == BadWindow)
{
/* This can be triggered if a guest application destroys a window before we notice. */
- std::cout << "ignoring BadAtom error and returning" << std::endl;
+ RTPrintf("ignoring BadAtom error and returning\n");
return 0;
}
XGetErrorText(pDisplay, pError->error_code, errorText, sizeof(errorText));
- std::cout << "An X Window protocol error occurred: " << errorText << std::endl
- << " Request code: " << int(pError->request_code) << std::endl
- << " Minor code: " << int(pError->minor_code) << std::endl
- << " Serial number of the failed request: " << int(pError->serial)
- << std::endl;
- std::cout << std::endl << "exiting." << std::endl;
+ RTPrintf("An X Window protocol error occurred: %s\n"
+ " Request code: %d\n"
+ " Minor code: %d\n"
+ " Serial number of the failed request: %d\n\n"
+ "exiting.\n",
+ errorText, (int)pError->request_code, (int)pError->minor_code,
+ (int)pError->serial);
exit(1);
}
int main( int argc, char **argv)
{
int rc = VINF_SUCCESS;
- std::string sTmp;
+ char ach[2];
RTR3Init();
- std::cout << "VirtualBox guest additions X11 seamless mode testcase" << std::endl;
+ RTPrintf("VirtualBox guest additions X11 seamless mode testcase\n");
if (0 == XInitThreads())
{
- std::cout << "Failed to initialise X11 threading, exiting." << std::endl;
+ RTPrintf("Failed to initialise X11 threading, exiting.\n");
exit(1);
}
/* Set an X11 error handler, so that we don't die when we get unavoidable errors. */
XSetErrorHandler(vboxClientXLibErrorHandler);
- std::cout << std::endl << "Press <Enter> to exit..." << std::endl;
+ RTPrintf("\nPress <Enter> to exit...\n");
RTSemEventCreate(&eventSem);
/** Our instance of the seamless class. */
VBoxGuestSeamless seamless;
- try
+ LogRel(("Starting seamless Guest Additions...\n"));
+ rc = seamless.init();
+ if (rc != VINF_SUCCESS)
{
- LogRel(("Starting seamless Guest Additions...\n"));
- rc = seamless.init();
- if (rc != VINF_SUCCESS)
- {
- std::cout << "Failed to initialise seamless Additions, rc = " << rc << std::endl;
- }
- }
- catch (std::exception e)
- {
- std::cout << "Failed to initialise seamless Additions - caught exception: " << e.what()
- << std::endl;
- rc = VERR_UNRESOLVED_ERROR;
- }
- catch (...)
- {
- std::cout << "Failed to initialise seamless Additions - caught unknown exception.\n"
- << std::endl;
- rc = VERR_UNRESOLVED_ERROR;
- }
- std::getline(std::cin, sTmp);
- try
- {
- seamless.uninit();
- }
- catch (std::exception e)
- {
- std::cout << "Error shutting down seamless Additions - caught exception: " << e.what()
- << std::endl;
- rc = VERR_UNRESOLVED_ERROR;
- }
- catch (...)
- {
- std::cout << "Error shutting down seamless Additions - caught unknown exception.\n"
- << std::endl;
- rc = VERR_UNRESOLVED_ERROR;
+ RTPrintf("Failed to initialise seamless Additions, rc = %d\n", rc);
}
+ RTStrmGetLine(g_pStdIn, ach, sizeof(ach));
+ seamless.uninit();
return rc;
}
diff --git a/src/VBox/Additions/x11/VBoxClient/thread.cpp b/src/VBox/Additions/x11/VBoxClient/thread.cpp
index 0a7f696dd..182070f39 100644
--- a/src/VBox/Additions/x11/VBoxClient/thread.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/thread.cpp
@@ -16,7 +16,6 @@
*/
#include <VBox/log.h>
-#include <iostream> /* For std::exception */
#include "thread.h"
@@ -56,11 +55,7 @@ VBoxGuestThread::~VBoxGuestThread(void)
if (NIL_RTTHREAD != mSelf)
{
LogRelThisFunc(("Warning! Stopping thread %s, as it is still running!\n", mName));
- try
- {
- stop(2000, 0);
- }
- catch(...) {}
+ stop(2000, 0);
}
LogRelFlowFunc(("returning\n"));
}
@@ -97,20 +92,7 @@ int VBoxGuestThread::threadFunction(RTTHREAD self, void *pvUser)
LogRelFlowFunc(("\n"));
PSELF pSelf = reinterpret_cast<PSELF>(pvUser);
pSelf->mRunning = true;
- try
- {
- rc = pSelf->mFunction->threadFunction(pSelf);
- }
- catch (const std::exception &e)
- {
- LogRelFunc(("Caught exception in thread: %s\n", e.what()));
- rc = VERR_UNRESOLVED_ERROR;
- }
- catch (...)
- {
- LogRelFunc(("Caught unknown exception in thread.\n"));
- rc = VERR_UNRESOLVED_ERROR;
- }
+ rc = pSelf->mFunction->threadFunction(pSelf);
pSelf->mRunning = false;
LogRelFlowFunc(("returning %Rrc\n", rc));
return rc;
diff --git a/src/VBox/Additions/x11/vboxmouse/Makefile.kmk b/src/VBox/Additions/x11/vboxmouse/Makefile.kmk
index 5a3183f89..1810df41c 100644
--- a/src/VBox/Additions/x11/vboxmouse/Makefile.kmk
+++ b/src/VBox/Additions/x11/vboxmouse/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 36388 2011-03-24 09:28:16Z vboxsync $
## @file
# Sub-Makefile for the VBox Additions XFree86 and X.org mouse drivers.
#
diff --git a/src/VBox/Additions/x11/vboxmouse/undefined_15 b/src/VBox/Additions/x11/vboxmouse/undefined_15
index 92bc3b391..2e01a28c0 100644
--- a/src/VBox/Additions/x11/vboxmouse/undefined_15
+++ b/src/VBox/Additions/x11/vboxmouse/undefined_15
@@ -48,6 +48,7 @@ lchown
lseek
lseek64
malloc
+nanosleep
memalign
memchr
memcmp
diff --git a/src/VBox/Additions/x11/vboxmouse/undefined_70 b/src/VBox/Additions/x11/vboxmouse/undefined_70
index 956164712..5443bc061 100644
--- a/src/VBox/Additions/x11/vboxmouse/undefined_70
+++ b/src/VBox/Additions/x11/vboxmouse/undefined_70
@@ -59,6 +59,7 @@ lchown
lseek
lseek64
malloc
+nanosleep
memalign
memchr
memcmp
diff --git a/src/VBox/Additions/x11/vboxmouse/undefined_71 b/src/VBox/Additions/x11/vboxmouse/undefined_71
index b313f0fad..b88a88a6a 100644
--- a/src/VBox/Additions/x11/vboxmouse/undefined_71
+++ b/src/VBox/Additions/x11/vboxmouse/undefined_71
@@ -62,6 +62,7 @@ lchown
lseek
lseek64
malloc
+nanosleep
memalign
memchr
memcmp
diff --git a/src/VBox/Additions/x11/vboxmouse/vboxmouse_15.c b/src/VBox/Additions/x11/vboxmouse/vboxmouse_15.c
index 9bda24c57..010c5f94c 100644
--- a/src/VBox/Additions/x11/vboxmouse/vboxmouse_15.c
+++ b/src/VBox/Additions/x11/vboxmouse/vboxmouse_15.c
@@ -135,7 +135,7 @@ VBoxInit(DeviceIntPtr device)
10000, 0, 10000
# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
, Absolute
-# endif
+# endif
);
xf86InitValuatorAxisStruct(device, 1,
@@ -146,7 +146,7 @@ VBoxInit(DeviceIntPtr device)
10000, 0, 10000
# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
, Absolute
-# endif
+# endif
);
#endif
xf86InitValuatorDefaults(device, 0);
diff --git a/src/VBox/Additions/x11/vboxvideo/Makefile.kmk b/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
index fe6d31a0c..126b2700a 100644
--- a/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
+++ b/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37520 2011-06-16 20:57:39Z vboxsync $
## @file
# Sub-Makefile for the VBox Linux Additions X.org graphics driver.
#
@@ -19,6 +19,11 @@ SUB_DEPTH = ../../../../..
include $(KBUILD_PATH)/subheader.kmk
#
+# Include sub-makefile(s).
+#
+include $(PATH_SUB_CURRENT)/testcase/Makefile.kmk
+
+#
# vboxvideo_drv
#
if1of ($(KBUILD_TARGET), linux)
@@ -37,7 +42,7 @@ vboxvideo_drv_DEFS = \
GCCUSESGAS AVOID_GLYPHBLT PIXPRIV SINGLEDEPTH XFreeXDGA XvExtension \
XFree86LOADER XFree86Server XF86VIDMODE XvMCExtension SMART_SCHEDULE \
BUILDDEBUG X_BYTE_ORDER=X_LITTLE_ENDIAN DNDEBUG FUNCPROTO=15 NARROWPROTO \
- IN_MODULE XFree86Module IN_XF86_MODULE
+ IN_MODULE XFree86Module IN_XF86_MODULE IN_RT_STATIC
vboxvideo_drv_DEFS += memset=xf86memset memcpy=xf86memcpy
vboxvideo_drv_INCS = \
$(VBOX_PATH_X11_XFREE_4_3)/include \
@@ -71,8 +76,11 @@ vboxvideo_drv_INCS = \
$(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/Xext
vboxvideo_drv_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
vboxvideo_drv_SOURCES = \
+ pointer.c \
+ setmode.c \
vboxutils.c \
vboxvideo.c \
+ vbva.c \
$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp \
$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp \
@@ -96,7 +104,7 @@ if1of ($(KBUILD_TARGET), linux)
-Wno-conversion -Wno-unused-parameter $(VBOX_GCC_Wno-variadic-macros) # template?
endif
vboxvideo_drv_70_DEFS := \
- XFree86Server IN_MODULE XFree86Module XFree86LOADER XORG_7X RENDER=1 IN_XF86_MODULE
+ XFree86Server IN_MODULE XFree86Module XFree86LOADER XORG_7X RENDER=1 IN_XF86_MODULE IN_RT_STATIC
ifeq ($(KBUILD_TARGET),solaris) # don't use .solaris or anything here.
vboxvideo_drv_70_DEFS += __EXTENSIONS__
vboxvideo_drv_70_CFLAGS += -D_XPG6 # Until we have moved the C++ bits into a library
@@ -332,7 +340,7 @@ ifdef VBOX_WITH_TESTCASES
$$(vboxvideo_drv_0_OUTDIR)/tstvboxvideo68.run: $$(INSTARGET_vboxvideo_drv)
$(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
$(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \
- $(INSTARGET_vboxvideo_drv) $(VBOXVIDEO_SRC_PATH)/undefined_68 --static
+ $(INSTARGET_vboxvideo_drv) $(VBOXVIDEO_SRC_PATH)/undefined --static
$(QUIET)$(APPEND) -t "$@" "done"
endif
@@ -341,7 +349,7 @@ $$(vboxvideo_drv_0_OUTDIR)/tstvboxvideo68.run: $$(INSTARGET_vboxvideo_drv)
$$(vboxvideo_drv_70_0_OUTDIR)/tstvboxvideo70.run: $$(INSTARGET_vboxvideo_drv_70)
$(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
$(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \
- $(INSTARGET_vboxvideo_drv_70) $(VBOXVIDEO_SRC_PATH)/undefined_70
+ $(INSTARGET_vboxvideo_drv_70) $(VBOXVIDEO_SRC_PATH)/undefined
$(QUIET)$(APPEND) -t "$@" "done"
TESTING += $(vboxvideo_drv_71_0_OUTDIR)/tstvboxvideo71.run
@@ -349,7 +357,7 @@ $$(vboxvideo_drv_70_0_OUTDIR)/tstvboxvideo70.run: $$(INSTARGET_vboxvideo_drv_70)
$$(vboxvideo_drv_71_0_OUTDIR)/tstvboxvideo71.run: $$(INSTARGET_vboxvideo_drv_71)
$(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
$(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \
- $(INSTARGET_vboxvideo_drv_71) $(VBOXVIDEO_SRC_PATH)/undefined_70
+ $(INSTARGET_vboxvideo_drv_71) $(VBOXVIDEO_SRC_PATH)/undefined
$(QUIET)$(APPEND) -t "$@" "done"
TESTING += $(vboxvideo_drv_13_0_OUTDIR)/tstvboxvideo13.run
@@ -357,7 +365,7 @@ $$(vboxvideo_drv_71_0_OUTDIR)/tstvboxvideo71.run: $$(INSTARGET_vboxvideo_drv_71)
$$(vboxvideo_drv_13_0_OUTDIR)/tstvboxvideo13.run: $$(INSTARGET_vboxvideo_drv_13)
$(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
$(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \
- $(INSTARGET_vboxvideo_drv_13) $(VBOXVIDEO_SRC_PATH)/undefined_13
+ $(INSTARGET_vboxvideo_drv_13) $(VBOXVIDEO_SRC_PATH)/undefined
$(QUIET)$(APPEND) -t "$@" "done"
TESTING += $(vboxvideo_drv_14_0_OUTDIR)/tstvboxvideo14.run
@@ -365,7 +373,7 @@ $$(vboxvideo_drv_13_0_OUTDIR)/tstvboxvideo13.run: $$(INSTARGET_vboxvideo_drv_13)
$$(vboxvideo_drv_14_0_OUTDIR)/tstvboxvideo14.run: $$(INSTARGET_vboxvideo_drv_14)
$(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
$(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \
- $(INSTARGET_vboxvideo_drv_14) $(VBOXVIDEO_SRC_PATH)/undefined_13
+ $(INSTARGET_vboxvideo_drv_14) $(VBOXVIDEO_SRC_PATH)/undefined
$(QUIET)$(APPEND) -t "$@" "done"
TESTING += $(vboxvideo_drv_15_0_OUTDIR)/tstvboxvideo15.run
@@ -373,7 +381,7 @@ $$(vboxvideo_drv_14_0_OUTDIR)/tstvboxvideo14.run: $$(INSTARGET_vboxvideo_drv_14)
$$(vboxvideo_drv_15_0_OUTDIR)/tstvboxvideo15.run: $$(INSTARGET_vboxvideo_drv_15)
$(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
$(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \
- $(INSTARGET_vboxvideo_drv_15) $(VBOXVIDEO_SRC_PATH)/undefined_13
+ $(INSTARGET_vboxvideo_drv_15) $(VBOXVIDEO_SRC_PATH)/undefined
$(QUIET)$(APPEND) -t "$@" "done"
TESTING += $(vboxvideo_drv_16_0_OUTDIR)/tstvboxvideo16.run
@@ -381,7 +389,7 @@ $$(vboxvideo_drv_15_0_OUTDIR)/tstvboxvideo15.run: $$(INSTARGET_vboxvideo_drv_15)
$$(vboxvideo_drv_16_0_OUTDIR)/tstvboxvideo16.run: $$(INSTARGET_vboxvideo_drv_16)
$(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
$(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \
- $(INSTARGET_vboxvideo_drv_16) $(VBOXVIDEO_SRC_PATH)/undefined_13
+ $(INSTARGET_vboxvideo_drv_16) $(VBOXVIDEO_SRC_PATH)/undefined
$(QUIET)$(APPEND) -t "$@" "done"
TESTING += $(vboxvideo_drv_17_0_OUTDIR)/tstvboxvideo17.run
@@ -389,7 +397,7 @@ $$(vboxvideo_drv_16_0_OUTDIR)/tstvboxvideo16.run: $$(INSTARGET_vboxvideo_drv_16)
$$(vboxvideo_drv_17_0_OUTDIR)/tstvboxvideo17.run: $$(INSTARGET_vboxvideo_drv_17)
$(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
$(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \
- $(INSTARGET_vboxvideo_drv_17) $(VBOXVIDEO_SRC_PATH)/undefined_13
+ $(INSTARGET_vboxvideo_drv_17) $(VBOXVIDEO_SRC_PATH)/undefined
$(QUIET)$(APPEND) -t "$@" "done"
TESTING += $(vboxvideo_drv_18_0_OUTDIR)/tstvboxvideo18.run
@@ -397,7 +405,7 @@ $$(vboxvideo_drv_17_0_OUTDIR)/tstvboxvideo17.run: $$(INSTARGET_vboxvideo_drv_17)
$$(vboxvideo_drv_18_0_OUTDIR)/tstvboxvideo18.run: $$(INSTARGET_vboxvideo_drv_18)
$(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
$(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \
- $(INSTARGET_vboxvideo_drv_18) $(VBOXVIDEO_SRC_PATH)/undefined_13
+ $(INSTARGET_vboxvideo_drv_18) $(VBOXVIDEO_SRC_PATH)/undefined
$(QUIET)$(APPEND) -t "$@" "done"
TESTING += $(vboxvideo_drv_19_0_OUTDIR)/tstvboxvideo19.run
@@ -405,7 +413,7 @@ $$(vboxvideo_drv_18_0_OUTDIR)/tstvboxvideo18.run: $$(INSTARGET_vboxvideo_drv_18)
$$(vboxvideo_drv_19_0_OUTDIR)/tstvboxvideo19.run: $$(INSTARGET_vboxvideo_drv_19)
$(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
$(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \
- $(INSTARGET_vboxvideo_drv_19) $(VBOXVIDEO_SRC_PATH)/undefined_13
+ $(INSTARGET_vboxvideo_drv_19) $(VBOXVIDEO_SRC_PATH)/undefined
$(QUIET)$(APPEND) -t "$@" "done"
TESTING += $(vboxvideo_drv_110_0_OUTDIR)/tstvboxvideo110.run
@@ -413,7 +421,7 @@ $$(vboxvideo_drv_19_0_OUTDIR)/tstvboxvideo19.run: $$(INSTARGET_vboxvideo_drv_19)
$$(vboxvideo_drv_110_0_OUTDIR)/tstvboxvideo110.run: $$(INSTARGET_vboxvideo_drv_110)
$(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
$(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \
- $(INSTARGET_vboxvideo_drv_110) $(VBOXVIDEO_SRC_PATH)/undefined_13
+ $(INSTARGET_vboxvideo_drv_110) $(VBOXVIDEO_SRC_PATH)/undefined
$(QUIET)$(APPEND) -t "$@" "done"
endif # ! VBOX_ONLY_SDK
diff --git a/src/VBox/Additions/x11/vboxvideo/edid.c b/src/VBox/Additions/x11/vboxvideo/edid.c
index 9f7f73a6e..c73a70fce 100644
--- a/src/VBox/Additions/x11/vboxvideo/edid.c
+++ b/src/VBox/Additions/x11/vboxvideo/edid.c
@@ -1,4 +1,4 @@
-/* $Id: edid.c $ */
+/* $Id: edid.c 35776 2011-01-30 00:14:29Z vboxsync $ */
/** @file
*
* Linux Additions X11 graphics driver, EDID construction
diff --git a/src/VBox/Additions/x11/vboxvideo/pointer.c b/src/VBox/Additions/x11/vboxvideo/pointer.c
new file mode 100644
index 000000000..f59fd4867
--- /dev/null
+++ b/src/VBox/Additions/x11/vboxvideo/pointer.c
@@ -0,0 +1,591 @@
+/** @file
+ * VirtualBox X11 Additions graphics driver utility functions
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuestLib.h>
+
+#ifndef PCIACCESS
+# include <xf86Pci.h>
+# include <Pci.h>
+#endif
+
+#include "xf86.h"
+#define NEED_XF86_TYPES
+#include <iprt/string.h>
+#include "compiler.h"
+#include "cursorstr.h"
+
+#include "vboxvideo.h"
+
+#define VBOX_MAX_CURSOR_WIDTH 64
+#define VBOX_MAX_CURSOR_HEIGHT 64
+
+/**************************************************************************
+* Debugging functions and macros *
+**************************************************************************/
+
+/* #define DEBUG_POINTER */
+
+#ifdef DEBUG
+# define PUT_PIXEL(c) ErrorF ("%c", c)
+#else /* DEBUG_VIDEO not defined */
+# define PUT_PIXEL(c) do { } while(0)
+#endif /* DEBUG_VIDEO not defined */
+
+/** Macro to printf an error message and return from a function */
+#define RETERROR(scrnIndex, RetVal, ...) \
+ do \
+ { \
+ xf86DrvMsg(scrnIndex, X_ERROR, __VA_ARGS__); \
+ return RetVal; \
+ } \
+ while (0)
+
+/** Structure to pass cursor image data between realise_cursor() and
+ * load_cursor_image(). The members match the parameters to
+ * @a VBoxHGSMIUpdatePointerShape(). */
+struct vboxCursorImage
+{
+ uint32_t fFlags;
+ uint32_t cHotX;
+ uint32_t cHotY;
+ uint32_t cWidth;
+ uint32_t cHeight;
+ uint8_t *pPixels;
+ uint32_t cbLength;
+};
+
+#ifdef DEBUG_POINTER
+static void
+vbox_show_shape(unsigned short w, unsigned short h, CARD32 bg, unsigned char *image)
+{
+ size_t x, y;
+ unsigned short pitch;
+ CARD32 *color;
+ unsigned char *mask;
+ size_t sizeMask;
+
+ image += sizeof(struct vboxCursorImage);
+ mask = image;
+ pitch = (w + 7) / 8;
+ sizeMask = (pitch * h + 3) & ~3;
+ color = (CARD32 *)(image + sizeMask);
+
+ TRACE_ENTRY();
+ for (y = 0; y < h; ++y, mask += pitch, color += w)
+ {
+ for (x = 0; x < w; ++x)
+ {
+ if (mask[x / 8] & (1 << (7 - (x % 8))))
+ ErrorF (" ");
+ else
+ {
+ CARD32 c = color[x];
+ if (c == bg)
+ ErrorF("Y");
+ else
+ ErrorF("X");
+ }
+ }
+ ErrorF("\n");
+ }
+}
+#endif
+
+/**************************************************************************
+* Helper functions and macros *
+**************************************************************************/
+
+/* This is called by the X server every time it loads a new cursor to see
+ * whether our "cursor hardware" can handle the cursor. This provides us with
+ * a mechanism (the only one!) to switch back from a software to a hardware
+ * cursor. */
+static Bool
+vbox_host_uses_hwcursor(ScrnInfoPtr pScrn)
+{
+ Bool rc = TRUE;
+ uint32_t fFeatures = 0;
+ VBOXPtr pVBox = pScrn->driverPrivate;
+
+ /* We may want to force the use of a software cursor. Currently this is
+ * needed if the guest uses a large virtual resolution, as in this case
+ * the host and guest tend to disagree about the pointer location. */
+ if (pVBox->forceSWCursor)
+ rc = FALSE;
+ /* Query information about mouse integration from the host. */
+ if (rc) {
+ int vrc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
+ if (RT_FAILURE(vrc)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unable to determine whether the virtual machine supports mouse pointer integration - request initialization failed with return code %d\n", vrc);
+ rc = FALSE;
+ }
+ }
+ /* If we got the information from the host then make sure the host wants
+ * to draw the pointer. */
+ if (rc)
+ {
+ if ( (fFeatures & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE)
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5
+ /* As of this version (server 1.6) all major Linux releases
+ * are known to handle USB tablets correctly. */
+ || (fFeatures & VMMDEV_MOUSE_HOST_HAS_ABS_DEV)
+#endif
+ )
+ /* Assume this will never be unloaded as long as the X session is
+ * running. */
+ pVBox->guestCanAbsolute = TRUE;
+ if ( (fFeatures & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER)
+ || !pVBox->guestCanAbsolute
+ || !(fFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)
+ )
+ rc = FALSE;
+ }
+ return rc;
+}
+
+/**************************************************************************
+* Main functions *
+**************************************************************************/
+
+void
+vbox_close(ScrnInfoPtr pScrn, VBOXPtr pVBox)
+{
+ TRACE_ENTRY();
+
+ xf86DestroyCursorInfoRec(pVBox->pCurs);
+ pVBox->pCurs = NULL;
+ TRACE_EXIT();
+}
+
+Bool
+vbox_init(int scrnIndex, VBOXPtr pVBox)
+{
+ Bool rc = TRUE;
+ int vrc;
+ uint32_t fMouseFeatures = 0;
+
+ TRACE_ENTRY();
+ vrc = VbglR3Init();
+ if (RT_FAILURE(vrc))
+ {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Failed to initialize the VirtualBox device (rc=%d) - make sure that the VirtualBox guest additions are properly installed. If you are not sure, try reinstalling them. The X Window graphics drivers will run in compatibility mode.\n",
+ vrc);
+ rc = FALSE;
+ }
+ pVBox->useDevice = rc;
+ /* We can't switch to a software cursor at will without help from
+ * VBoxClient. So tell that to the host and wait for VBoxClient to
+ * change this. */
+ vrc = VbglR3GetMouseStatus(&fMouseFeatures, NULL, NULL);
+ if (RT_SUCCESS(vrc))
+ VbglR3SetMouseStatus( fMouseFeatures
+ | VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR);
+ return rc;
+}
+
+static void
+vbox_vmm_hide_cursor(ScrnInfoPtr pScrn, VBOXPtr pVBox)
+{
+ int rc;
+
+ rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, 0, 0, 0, 0, 0, NULL, 0);
+ if (RT_FAILURE(rc))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not hide the virtual mouse pointer, VBox error %d.\n", rc);
+ /* Play safe, and disable the hardware cursor until the next mode
+ * switch, since obviously something happened that we didn't
+ * anticipate. */
+ pVBox->forceSWCursor = TRUE;
+ }
+}
+
+static void
+vbox_vmm_show_cursor(ScrnInfoPtr pScrn, VBOXPtr pVBox)
+{
+ int rc;
+
+ if (!vbox_host_uses_hwcursor(pScrn))
+ return;
+ rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, VBOX_MOUSE_POINTER_VISIBLE,
+ 0, 0, 0, 0, NULL, 0);
+ if (RT_FAILURE(rc)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not unhide the virtual mouse pointer.\n");
+ /* Play safe, and disable the hardware cursor until the next mode
+ * switch, since obviously something happened that we didn't
+ * anticipate. */
+ pVBox->forceSWCursor = TRUE;
+ }
+}
+
+static void
+vbox_vmm_load_cursor_image(ScrnInfoPtr pScrn, VBOXPtr pVBox,
+ unsigned char *pvImage)
+{
+ int rc;
+ struct vboxCursorImage *pImage;
+ pImage = (struct vboxCursorImage *)pvImage;
+
+#ifdef DEBUG_POINTER
+ vbox_show_shape(pImage->cWidth, pImage->cHeight, 0, pvImage);
+#endif
+
+ rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, pImage->fFlags,
+ pImage->cHotX, pImage->cHotY, pImage->cWidth, pImage->cHeight,
+ pImage->pPixels, pImage->cbLength);
+ if (RT_FAILURE(rc)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to set the virtual mouse pointer image.\n");
+ /* Play safe, and disable the hardware cursor until the next mode
+ * switch, since obviously something happened that we didn't
+ * anticipate. */
+ pVBox->forceSWCursor = TRUE;
+ }
+}
+
+static void
+vbox_set_cursor_colors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ NOREF(pScrn);
+ NOREF(bg);
+ NOREF(fg);
+ /* ErrorF("vbox_set_cursor_colors NOT IMPLEMENTED\n"); */
+}
+
+
+static void
+vbox_set_cursor_position(ScrnInfoPtr pScrn, int x, int y)
+{
+ /* Nothing to do here, as we are telling the guest where the mouse is,
+ * not vice versa. */
+ NOREF(pScrn);
+ NOREF(x);
+ NOREF(y);
+}
+
+static void
+vbox_hide_cursor(ScrnInfoPtr pScrn)
+{
+ VBOXPtr pVBox = pScrn->driverPrivate;
+
+ vbox_vmm_hide_cursor(pScrn, pVBox);
+}
+
+static void
+vbox_show_cursor(ScrnInfoPtr pScrn)
+{
+ VBOXPtr pVBox = pScrn->driverPrivate;
+
+ vbox_vmm_show_cursor(pScrn, pVBox);
+}
+
+static void
+vbox_load_cursor_image(ScrnInfoPtr pScrn, unsigned char *image)
+{
+ VBOXPtr pVBox = pScrn->driverPrivate;
+
+ vbox_vmm_load_cursor_image(pScrn, pVBox, image);
+}
+
+static Bool
+vbox_use_hw_cursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ return vbox_host_uses_hwcursor(pScrn);
+}
+
+static unsigned char
+color_to_byte(unsigned c)
+{
+ return (c >> 8) & 0xff;
+}
+
+static unsigned char *
+vbox_realize_cursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+ VBOXPtr pVBox;
+ CursorBitsPtr bitsp;
+ unsigned short w, h, x, y;
+ unsigned char *c, *p, *pm, *ps, *m;
+ size_t sizeRequest, sizeRgba, sizeMask, srcPitch, dstPitch;
+ CARD32 fc, bc, *cp;
+ int rc, scrnIndex = infoPtr->pScrn->scrnIndex;
+ struct vboxCursorImage *pImage;
+
+ pVBox = infoPtr->pScrn->driverPrivate;
+ bitsp = pCurs->bits;
+ w = bitsp->width;
+ h = bitsp->height;
+
+ if (!w || !h || w > VBOX_MAX_CURSOR_WIDTH || h > VBOX_MAX_CURSOR_HEIGHT)
+ RETERROR(scrnIndex, NULL,
+ "Error invalid cursor dimensions %dx%d\n", w, h);
+
+ if ((bitsp->xhot > w) || (bitsp->yhot > h))
+ RETERROR(scrnIndex, NULL,
+ "Error invalid cursor hotspot location %dx%d (max %dx%d)\n",
+ bitsp->xhot, bitsp->yhot, w, h);
+
+ srcPitch = PixmapBytePad (bitsp->width, 1);
+ dstPitch = (w + 7) / 8;
+ sizeMask = ((dstPitch * h) + 3) & (size_t) ~3;
+ sizeRgba = w * h * 4;
+ sizeRequest = sizeMask + sizeRgba + sizeof(*pImage);
+
+ p = c = calloc (1, sizeRequest);
+ if (!c)
+ RETERROR(scrnIndex, NULL,
+ "Error failed to alloc %lu bytes for cursor\n",
+ (unsigned long) sizeRequest);
+
+ pImage = (struct vboxCursorImage *)p;
+ pImage->pPixels = m = p + sizeof(*pImage);
+ cp = (CARD32 *)(m + sizeMask);
+
+ TRACE_LOG ("w=%d h=%d sm=%d sr=%d p=%d\n",
+ w, h, (int) sizeMask, (int) sizeRgba, (int) dstPitch);
+ TRACE_LOG ("m=%p c=%p cp=%p\n", m, c, (void *)cp);
+
+ fc = color_to_byte (pCurs->foreBlue)
+ | (color_to_byte (pCurs->foreGreen) << 8)
+ | (color_to_byte (pCurs->foreRed) << 16);
+
+ bc = color_to_byte (pCurs->backBlue)
+ | (color_to_byte (pCurs->backGreen) << 8)
+ | (color_to_byte (pCurs->backRed) << 16);
+
+ /*
+ * Convert the Xorg source/mask bits to the and/xor bits VBox needs.
+ * Xorg:
+ * The mask is a bitmap indicating which parts of the cursor are
+ * transparent and which parts are drawn. The source is a bitmap
+ * indicating which parts of the non-transparent portion of the
+ * the cursor should be painted in the foreground color and which
+ * should be painted in the background color. By default, set bits
+ * indicate the opaque part of the mask bitmap and clear bits
+ * indicate the transparent part.
+ * VBox:
+ * The color data is the XOR mask. The AND mask bits determine
+ * which pixels of the color data (XOR mask) will replace (overwrite)
+ * the screen pixels (AND mask bit = 0) and which ones will be XORed
+ * with existing screen pixels (AND mask bit = 1).
+ * For example when you have the AND mask all 0, then you see the
+ * correct mouse pointer image surrounded by black square.
+ */
+ for (pm = bitsp->mask, ps = bitsp->source, y = 0;
+ y < h;
+ ++y, pm += srcPitch, ps += srcPitch, m += dstPitch)
+ {
+ for (x = 0; x < w; ++x)
+ {
+ if (pm[x / 8] & (1 << (x % 8)))
+ {
+ /* opaque, leave AND mask bit at 0 */
+ if (ps[x / 8] & (1 << (x % 8)))
+ {
+ *cp++ = fc;
+ PUT_PIXEL('X');
+ }
+ else
+ {
+ *cp++ = bc;
+ PUT_PIXEL('*');
+ }
+ }
+ else
+ {
+ /* transparent, set AND mask bit */
+ m[x / 8] |= 1 << (7 - (x % 8));
+ /* don't change the screen pixel */
+ *cp++ = 0;
+ PUT_PIXEL(' ');
+ }
+ }
+ PUT_PIXEL('\n');
+ }
+
+ pImage->cWidth = w;
+ pImage->cHeight = h;
+ pImage->cHotX = bitsp->xhot;
+ pImage->cHotY = bitsp->yhot;
+ pImage->fFlags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE;
+ pImage->cbLength = sizeRequest - sizeof(*pImage);
+
+#ifdef DEBUG_POINTER
+ ErrorF("shape = %p\n", p);
+ vbox_show_shape(w, h, bc, c);
+#endif
+
+ return p;
+}
+
+#ifdef ARGB_CURSOR
+static Bool
+vbox_use_hw_cursor_argb(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ Bool rc = TRUE;
+
+ if (!vbox_host_uses_hwcursor(pScrn))
+ rc = FALSE;
+ if ( rc
+ && ( (pCurs->bits->height > VBOX_MAX_CURSOR_HEIGHT)
+ || (pCurs->bits->width > VBOX_MAX_CURSOR_WIDTH)
+ || (pScrn->bitsPerPixel <= 8)
+ )
+ )
+ rc = FALSE;
+#ifndef VBOXVIDEO_13
+ /* Evil hack - we use this as another way of poking the driver to update
+ * our list of video modes. */
+ vboxWriteHostModes(pScrn, pScrn->currentMode);
+#endif
+ return rc;
+}
+
+
+static void
+vbox_load_cursor_argb(ScrnInfoPtr pScrn, CursorPtr pCurs)
+{
+ VBOXPtr pVBox;
+ VMMDevReqMousePointer *reqp;
+ CursorBitsPtr bitsp;
+ unsigned short w, h;
+ unsigned short cx, cy;
+ unsigned char *pm;
+ CARD32 *pc;
+ size_t sizeData, sizeMask;
+ CARD8 *p;
+ int scrnIndex;
+ uint32_t fFlags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE
+ | VBOX_MOUSE_POINTER_ALPHA;
+ int rc;
+
+ pVBox = pScrn->driverPrivate;
+ bitsp = pCurs->bits;
+ w = bitsp->width;
+ h = bitsp->height;
+ scrnIndex = pScrn->scrnIndex;
+
+ /* Mask must be generated for alpha cursors, that is required by VBox. */
+ /* note: (michael) the next struct must be 32bit aligned. */
+ sizeMask = ((w + 7) / 8 * h + 3) & ~3;
+
+ if (!w || !h || w > VBOX_MAX_CURSOR_WIDTH || h > VBOX_MAX_CURSOR_HEIGHT)
+ RETERROR(scrnIndex, ,
+ "Error invalid cursor dimensions %dx%d\n", w, h);
+
+ if ((bitsp->xhot > w) || (bitsp->yhot > h))
+ RETERROR(scrnIndex, ,
+ "Error invalid cursor hotspot location %dx%d (max %dx%d)\n",
+ bitsp->xhot, bitsp->yhot, w, h);
+
+ sizeData = w * h * 4 + sizeMask;
+ p = calloc(1, sizeData);
+ if (!p)
+ RETERROR(scrnIndex, ,
+ "Error failed to alloc %lu bytes for cursor\n",
+ (unsigned long)sizeData);
+
+ memcpy(p + sizeMask, bitsp->argb, w * h * 4);
+
+ /* Emulate the AND mask. */
+ pm = p;
+ pc = bitsp->argb;
+
+ /* Init AND mask to 1 */
+ memset(pm, 0xFF, sizeMask);
+
+ /*
+ * The additions driver must provide the AND mask for alpha cursors. The host frontend
+ * which can handle alpha channel, will ignore the AND mask and draw an alpha cursor.
+ * But if the host does not support ARGB, then it simply uses the AND mask and the color
+ * data to draw a normal color cursor.
+ */
+ for (cy = 0; cy < h; cy++)
+ {
+ unsigned char bitmask = 0x80;
+
+ for (cx = 0; cx < w; cx++, bitmask >>= 1)
+ {
+ if (bitmask == 0)
+ bitmask = 0x80;
+
+ if (pc[cx] >= 0xF0000000)
+ pm[cx / 8] &= ~bitmask;
+ }
+
+ /* Point to next source and dest scans */
+ pc += w;
+ pm += (w + 7) / 8;
+ }
+
+ rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, fFlags, bitsp->xhot,
+ bitsp->yhot, w, h, p, sizeData);
+ free(p);
+}
+#endif
+
+Bool
+vbox_cursor_init(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VBOXPtr pVBox = pScrn->driverPrivate;
+ xf86CursorInfoPtr pCurs = NULL;
+ Bool rc = TRUE;
+
+ TRACE_ENTRY();
+ if (!pVBox->fHaveHGSMI)
+ return FALSE;
+ pVBox->pCurs = pCurs = xf86CreateCursorInfoRec();
+ if (!pCurs) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to create X Window cursor information structures for virtual mouse.\n");
+ rc = FALSE;
+ }
+ if (rc) {
+ pCurs->MaxWidth = VBOX_MAX_CURSOR_WIDTH;
+ pCurs->MaxHeight = VBOX_MAX_CURSOR_HEIGHT;
+ pCurs->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
+ | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1
+ | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
+
+ pCurs->SetCursorColors = vbox_set_cursor_colors;
+ pCurs->SetCursorPosition = vbox_set_cursor_position;
+ pCurs->LoadCursorImage = vbox_load_cursor_image;
+ pCurs->HideCursor = vbox_hide_cursor;
+ pCurs->ShowCursor = vbox_show_cursor;
+ pCurs->UseHWCursor = vbox_use_hw_cursor;
+ pCurs->RealizeCursor = vbox_realize_cursor;
+
+#ifdef ARGB_CURSOR
+ pCurs->UseHWCursorARGB = vbox_use_hw_cursor_argb;
+ pCurs->LoadCursorARGB = vbox_load_cursor_argb;
+#endif
+
+ /* Hide the host cursor before we initialise if we wish to use a
+ * software cursor. */
+ if (pVBox->forceSWCursor)
+ vbox_vmm_hide_cursor(pScrn, pVBox);
+ rc = xf86InitCursor(pScreen, pCurs);
+ }
+ if (!rc)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to enable mouse pointer integration.\n");
+ if (!rc && (pCurs != NULL))
+ xf86DestroyCursorInfoRec(pCurs);
+ return rc;
+}
diff --git a/src/VBox/Additions/x11/vboxvideo/setmode.c b/src/VBox/Additions/x11/vboxvideo/setmode.c
new file mode 100644
index 000000000..00c69070b
--- /dev/null
+++ b/src/VBox/Additions/x11/vboxvideo/setmode.c
@@ -0,0 +1,194 @@
+/* $Id: setmode.c 36020 2011-02-18 14:18:51Z vboxsync $ */
+/** @file
+ *
+ * Linux Additions X11 graphics driver, mode setting
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on:
+ *
+ * X11 VESA driver
+ *
+ * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * CONECTIVA LINUX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Conectiva Linux shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization from
+ * Conectiva Linux.
+ *
+ * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
+ */
+
+#ifdef XORG_7X
+# include "xorg-server.h"
+# include <string.h>
+#endif
+#include "vboxvideo.h"
+#include <iprt/asm-math.h>
+#include "version-generated.h"
+#include "product-generated.h"
+#include <xf86.h>
+#include <misc.h>
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* Colormap handling */
+#include "micmap.h"
+#include "xf86cmap.h"
+
+/* DPMS */
+/* #define DPMS_SERVER
+#include "extensions/dpms.h" */
+
+/* VGA hardware functions for setting and restoring text mode */
+#include "vgaHW.h"
+
+/** Clear the virtual framebuffer in VRAM. Optionally also clear up to the
+ * size of a new framebuffer. Framebuffer sizes larger than available VRAM
+ * be treated as zero and passed over. */
+void vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY)
+{
+ VBOXPtr pVBox = VBOXGetRec(pScrn);
+ uint64_t cbOldFB, cbNewFB;
+
+ cbOldFB = pVBox->cbLine * pScrn->virtualX;
+ cbNewFB = vboxLineLength(pScrn, cNewX) * cNewY;
+ if (cbOldFB > (uint64_t)pVBox->cbFBMax)
+ cbOldFB = 0;
+ if (cbNewFB > (uint64_t)pVBox->cbFBMax)
+ cbNewFB = 0;
+ memset(pVBox->base, 0, max(cbOldFB, cbNewFB));
+}
+
+/** Set a graphics mode. Poke any required values into registers, do an HGSMI
+ * mode set and tell the host we support advanced graphics functions. This
+ * procedure is complicated by the fact that X.Org can implicitly disable a
+ * screen by resizing the virtual framebuffer so that the screen is no longer
+ * inside it. We have to spot and handle this.
+ */
+Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
+ unsigned cHeight, int x, int y)
+{
+ VBOXPtr pVBox = VBOXGetRec(pScrn);
+ uint32_t offStart, cwReal = cWidth;
+
+ TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n",
+ cDisplay, cWidth, cHeight, x, y, pScrn->displayWidth);
+ pVBox->aScreenLocation[cDisplay].cx = cWidth;
+ pVBox->aScreenLocation[cDisplay].cy = cHeight;
+ pVBox->aScreenLocation[cDisplay].x = x;
+ pVBox->aScreenLocation[cDisplay].y = y;
+ offStart = y * pVBox->cbLine + x * vboxBPP(pScrn) / 8;
+ /* Deactivate the screen if the mode - specifically the virtual width - is
+ * too large for VRAM as we sometimes have to do this - see comments in
+ * VBOXPreInit. */
+ if ( offStart + pVBox->cbLine * cHeight > pVBox->cbFBMax
+ || pVBox->cbLine * pScrn->virtualY > pVBox->cbFBMax)
+ return FALSE;
+ /* Deactivate the screen if it is outside of the virtual framebuffer and
+ * clamp it to lie inside if it is partly outside. */
+ if (x >= pScrn->displayWidth || x + (int) cWidth <= 0)
+ return FALSE;
+ else
+ cwReal = RT_MIN((int) cWidth, pScrn->displayWidth - x);
+ TRACE_LOG("pVBox->afDisabled[cDisplay]=%d\n",
+ (int)pVBox->afDisabled[cDisplay]);
+ /* Don't fiddle with the hardware if we are switched
+ * to a virtual terminal. */
+ if (pVBox->vtSwitch)
+ return TRUE;
+ if (cDisplay == 0)
+ VBoxVideoSetModeRegisters(cwReal, cHeight, pScrn->displayWidth,
+ vboxBPP(pScrn), 0, x, y);
+ /* Tell the host we support graphics */
+ if (vbox_device_available(pVBox))
+ vboxEnableGraphicsCap(pVBox);
+ if (pVBox->fHaveHGSMI)
+ {
+ uint16_t fFlags = VBVA_SCREEN_F_ACTIVE;
+ fFlags |= (pVBox->afDisabled[cDisplay] ? VBVA_SCREEN_F_DISABLED : 0);
+ VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x, y,
+ offStart, pVBox->cbLine, cwReal, cHeight,
+ vboxBPP(pScrn), fFlags);
+ }
+ return TRUE;
+}
+
+/** Resize the virtual framebuffer. After resizing we reset all modes
+ * (X.Org 1.3+) to adjust them to the new framebuffer.
+ */
+Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen);
+ VBOXPtr pVBox = VBOXGetRec(pScrn);
+ uint64_t cbLine = vboxLineLength(pScrn, width);
+
+ TRACE_LOG("width=%d, height=%d\n", width, height);
+ if (!pPixmap) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to get the screen pixmap.\n");
+ return FALSE;
+ }
+ if (cbLine > UINT32_MAX || cbLine * height >= pVBox->cbFBMax)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unable to set up a virtual screen size of %dx%d with %lu of %d Kb of video memory available. Please increase the video memory size.\n",
+ width, height, pVBox->cbFBMax / 1024, pScrn->videoRam);
+ return FALSE;
+ }
+ pScreen->ModifyPixmapHeader(pPixmap, width, height,
+ pScrn->depth, vboxBPP(pScrn), cbLine,
+ pVBox->base);
+ vboxClearVRAM(pScrn, width, height);
+ pScrn->virtualX = width;
+ pScrn->virtualY = height;
+ pScrn->displayWidth = vboxDisplayPitch(pScrn, cbLine);
+ pVBox->cbLine = cbLine;
+#ifdef VBOX_DRI
+ if (pVBox->useDRI)
+ VBOXDRIUpdateStride(pScrn, pVBox);
+#endif
+#ifdef VBOXVIDEO_13
+ /* Write the new values to the hardware */
+ {
+ unsigned i;
+ for (i = 0; i < pVBox->cScreens; ++i)
+ VBOXSetMode(pScrn, i, pVBox->aScreenLocation[i].cx,
+ pVBox->aScreenLocation[i].cy,
+ pVBox->aScreenLocation[i].x,
+ pVBox->aScreenLocation[i].y);
+ }
+#endif
+ return TRUE;
+}
diff --git a/src/VBox/Additions/x11/vboxvideo/testcase/Makefile.kmk b/src/VBox/Additions/x11/vboxvideo/testcase/Makefile.kmk
new file mode 100644
index 000000000..ca773307f
--- /dev/null
+++ b/src/VBox/Additions/x11/vboxvideo/testcase/Makefile.kmk
@@ -0,0 +1,48 @@
+# $Id: Makefile.kmk 37520 2011-06-16 20:57:39Z vboxsync $
+## @file
+# Sub-Makefile for the vboxvideo testcases.
+#
+
+#
+# Copyright (C) 2006-2007 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+SUB_DEPTH = ../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+#
+# Target
+#
+ifndef VBOX_ONLY_SDK
+ ifndef VBOX_ONLY_ADDITIONS
+ if defined(VBOX_WITH_TESTCASES)
+ PROGRAMS += \
+ tstSetModeXOrg
+ endif # !VBOX_WITH_TESTCASES
+ endif #!VBOX_ONLY_ADDITIONS
+endif # !VBOX_ONLY_SDK
+
+
+#
+# tstSetModeXOrg
+#
+tstSetModeXOrg_TEMPLATE = VBOXR3TSTEXE
+tstSetModeXOrg_CFLAGS += -std=c99
+tstSetModeXOrg_DEFS = $(filter-out IN_RT_STATIC,$(vboxvideo_drv_15_DEFS)) TESTCASE
+tstSetModeXOrg_SOURCES = \
+ tstSetModeXOrg.c \
+ ../setmode.c
+tstSetModeXOrg_INCS = $(vboxvideo_drv_15_INCS)
+
+
+# generate rules.
+include $(KBUILD_PATH)/subfooter.kmk
+
diff --git a/src/VBox/Additions/x11/vboxvideo/testcase/tstSetModeXOrg.c b/src/VBox/Additions/x11/vboxvideo/testcase/tstSetModeXOrg.c
new file mode 100644
index 000000000..0bc1020b4
--- /dev/null
+++ b/src/VBox/Additions/x11/vboxvideo/testcase/tstSetModeXOrg.c
@@ -0,0 +1,141 @@
+/* $Id: tstSetModeXOrg.c 37423 2011-06-12 18:37:56Z vboxsync $ */
+/** @file
+ * vboxvideo unit test - modesetting.
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+
+#include "../vboxvideo.h"
+
+#include <VBox/VBoxVideoGuest.h>
+
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/test.h>
+
+#include <xf86.h>
+
+void xf86Msg(MessageType type, const char *format, ...) {}
+void xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...) {}
+
+static ScrnInfoRec scrnInfo[1];
+static ScrnInfoPtr pScrns[1] = { &scrnInfo[0] };
+ScrnInfoPtr *xf86Screens = pScrns;
+
+Bool vbox_device_available(VBOXPtr pVBox)
+{
+ return TRUE;
+}
+
+Bool vboxEnableGraphicsCap(VBOXPtr pVBox)
+{
+ return TRUE;
+}
+
+void VBOXDRIUpdateStride(ScrnInfoPtr pScrn, VBOXPtr pVBox) {}
+
+static struct
+{
+ uint16_t cWidth;
+ uint16_t cHeight;
+ uint16_t cVirtWidth;
+ uint16_t cBPP;
+ uint16_t fFlags;
+ uint16_t cx;
+ uint16_t cy;
+} s_ModeRegs;
+
+RTDECL(void) VBoxVideoSetModeRegisters(uint16_t cWidth, uint16_t cHeight,
+ uint16_t cVirtWidth, uint16_t cBPP,
+ uint16_t fFlags,
+ uint16_t cx, uint16_t cy)
+{
+ s_ModeRegs.cWidth = cWidth;
+ s_ModeRegs.cHeight = cHeight;
+ s_ModeRegs.cVirtWidth = cVirtWidth;
+ s_ModeRegs.cBPP = cBPP;
+ s_ModeRegs.fFlags = fFlags;
+ s_ModeRegs.cx = cx;
+ s_ModeRegs.cy = cy;
+}
+
+static struct
+{
+ PHGSMIGUESTCOMMANDCONTEXT pCtx;
+ uint32_t cDisplay;
+ int32_t cOriginX;
+ int32_t cOriginY;
+ uint32_t offStart;
+ uint32_t cbPitch;
+ uint32_t cWidth;
+ uint32_t cHeight;
+ uint16_t cBPP;
+ uint16_t fFlags;
+} s_DisplayInfo;
+
+void VBoxHGSMIProcessDisplayInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ uint32_t cDisplay, int32_t cOriginX,
+ int32_t cOriginY, uint32_t offStart,
+ uint32_t cbPitch, uint32_t cWidth,
+ uint32_t cHeight, uint16_t cBPP,
+ uint16_t fFlags)
+{
+ s_DisplayInfo.pCtx = pCtx;
+ s_DisplayInfo.cDisplay = cDisplay;
+ s_DisplayInfo.cOriginX = cOriginX;
+ s_DisplayInfo.cOriginY = cOriginY;
+ s_DisplayInfo.offStart = offStart;
+ s_DisplayInfo.cbPitch = cbPitch;
+ s_DisplayInfo.cWidth = cWidth;
+ s_DisplayInfo.cHeight = cHeight;
+ s_DisplayInfo.cBPP = cBPP;
+ s_DisplayInfo.fFlags = fFlags;
+}
+
+
+static int setup(void)
+{
+ return VINF_SUCCESS;
+}
+
+static void teardown(void)
+{
+}
+
+int main(void)
+{
+ /*
+ * Init the runtime, test and say hello.
+ */
+ RTTEST hTest;
+ RTEXITCODE rcExit = RTTestInitAndCreate("tstVBoxVideoXOrg", &hTest);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ RTTestBanner(hTest);
+
+ /*
+ * Run the tests.
+ */
+ AssertRC(setup());
+ teardown();
+
+ /*
+ * Summary
+ */
+ return RTTestSummaryAndDestroy(hTest);
+}
+
diff --git a/src/VBox/Additions/x11/vboxvideo/undefined_13 b/src/VBox/Additions/x11/vboxvideo/undefined
index f0ab6e3ef..b5152bd88 100644
--- a/src/VBox/Additions/x11/vboxvideo/undefined_13
+++ b/src/VBox/Additions/x11/vboxvideo/undefined
@@ -15,14 +15,9 @@ MakeAtom
PixmapWidthPaddingInfo
RRChangeOutputProperty
ShadowFBInit2
-VBEExtendedInit
-VBEGetVBEMode
-VBESaveRestore
-VBESetDisplayStart
-VBESetGetPaletteData
-VBESetVBEMode
XNFcalloc
XNFstrdup
+Xalloc
_Jv_RegisterClasses
___errno
__cxa_finalize
@@ -72,6 +67,7 @@ lchown
lseek
lseek64
malloc
+nanosleep
memalign
memchr
memcmp
@@ -90,15 +86,9 @@ munmap
nl_langinfo
open
open64
-pciFindFirst
-pciReadLong
pciTag
pci_device_map_range
-pci_device_next
-pci_device_probe
pci_device_unmap_range
-pci_id_match_iterator_create
-pci_iterator_destroy
posix_memalign
pthread_sigmask
putenv
@@ -134,27 +124,21 @@ utimes
vgaHWFreeHWRec
vgaHWGetHWRec
vgaHWGetIndex
-vgaHWHandleColormaps
-vgaHWMapMem
-vgaHWRestoreFonts
-vgaHWSaveFonts
-vgaHWUnmapMem
+vgaHWGetIOBase
+vgaHWRestore
+vgaHWSave
write
xf86AddDriver
-xf86CVTMode
-xf86CheckModeForMonitor
-xf86CollectOptions
xf86ConfigPciEntity
+xf86CrtcConfigPrivateIndex
xf86CreateCursorInfoRec
xf86CrtcConfigInit
-xf86CrtcConfigPrivateIndex
xf86CrtcCreate
xf86CrtcScreenInit
xf86CrtcSetSizeRange
xf86DPMSInit
xf86DPMSSet
xf86DestroyCursorInfoRec
-xf86DiDGAInit
xf86DrvMsg
xf86GetEntityInfo
xf86GetPciInfoForEntity
@@ -167,7 +151,6 @@ xf86InterpretEDID
xf86LoadSubModule
xf86LoaderCheckSymbol
xf86LoaderReqSymLists
-xf86MapDomainMemory
xf86MapPciMem
xf86MatchDevice
xf86MatchPciInstances
@@ -178,7 +161,6 @@ xf86OutputUseScreenMonitor
xf86PrintChipsets
xf86PrintDepthBpp
xf86PrintModes
-xf86ProcessOptions
xf86SaveScreen
xf86Screens
xf86SetBackingStore
@@ -193,7 +175,7 @@ xf86SetModeDefaultName
xf86SetSingleMode
xf86SetWeight
xf86ShowUnusedOptions
-xf86SlowBcopy
xf86UnMapVidMem
-xf86sprintf
-xf86snprintf
+xf86errno
+xf86isspace
+xf86strtoul
diff --git a/src/VBox/Additions/x11/vboxvideo/undefined_68 b/src/VBox/Additions/x11/vboxvideo/undefined_68
deleted file mode 100644
index da29f0e49..000000000
--- a/src/VBox/Additions/x11/vboxvideo/undefined_68
+++ /dev/null
@@ -1,108 +0,0 @@
-DGAInit
-ErrorF
-FatalError
-LoaderRefSymLists
-PixmapWidthPaddingInfo
-SetTimeSinceLastInputEvent
-ShadowFBInit2
-VBEExtendedInit
-VBEGetVBEMode
-VBEInit
-VBESaveRestore
-VBESetDisplayStart
-VBESetGetPaletteData
-VBESetVBEMode
-VErrorF
-XNFalloc
-XNFcalloc
-XNFrealloc
-XNFstrdup
-Xalloc
-Xcalloc
-Xfree
-Xrealloc
-fbPictureInit
-fbScreenInit
-flock
-miClearVisualTypes
-miCreateDefColormap
-miDCInitialize
-miInitializeBackingStore
-miSetPixmapDepths
-miSetVisualTypes
-pciFindFirst
-pciReadLong
-pciTag
-pthread_sigmask
-resVgaShared
-serverGeneration
-sigdelset
-sigfillset
-vgaHWDPMSSet
-vgaHWFreeHWRec
-vgaHWGetHWRec
-vgaHWGetIndex
-vgaHWHandleColormaps
-vgaHWMapMem
-vgaHWRestoreFonts
-vgaHWSaveFonts
-vgaHWSaveScreen
-vgaHWUnmapMem
-xf86AddDriver
-xf86CollectOptions
-xf86ConfigPciEntity
-xf86CreateCursorInfoRec
-xf86DPMSInit
-xf86DestroyCursorInfoRec
-xf86DrvMsg
-xf86GetEntityInfo
-xf86GetPciInfoForEntity
-xf86GetPciVideoInfo
-xf86GetPointerScreenFuncs
-xf86HandleColormaps
-xf86InitCursor
-xf86IsUnblank
-xf86LoadSubModule
-xf86LoaderReqSymLists
-xf86MapPciMem
-xf86MapVidMem
-xf86MatchDevice
-xf86MatchPciInstances
-xf86Msg
-xf86PrintChipsets
-xf86PrintDepthBpp
-xf86PrintModes
-xf86ProcessOptions
-xf86PruneDriverModes
-xf86Screens
-xf86SetBackingStore
-xf86SetBlackWhitePixels
-xf86SetDefaultVisual
-xf86SetDepthBpp
-xf86SetDpi
-xf86SetGamma
-xf86SetWeight
-xf86ShowUnusedOptions
-xf86SlowBcopy
-xf86UnMapVidMem
-xf86ValidateModes
-xf86calloc
-xf86close
-xf86errno
-xf86free
-xf86ioctl
-xf86isspace
-xf86malloc
-xf86memchr
-xf86memcpy
-xf86memset
-xf86open
-xf86sprintf
-xf86sscanf
-xf86strcmp
-xf86strcpy
-xf86strdup
-xf86strerror
-xf86strlen
-xf86strtoul
-xf86vsnprintf
diff --git a/src/VBox/Additions/x11/vboxvideo/undefined_70 b/src/VBox/Additions/x11/vboxvideo/undefined_70
deleted file mode 100644
index 1e3385fd4..000000000
--- a/src/VBox/Additions/x11/vboxvideo/undefined_70
+++ /dev/null
@@ -1,197 +0,0 @@
-DGAInit
-DRICloseScreen
-DRICreateInfoRec
-DRICreateInfoRec sprintf
-DRICreatePCIBusID
-DRIDestroyInfoRec
-DRIFinishScreenInit
-DRILock
-DRIQueryVersion
-DRIScreenInit
-DRIUnlock
-ErrorF
-FatalError
-GlxSetVisualConfigs
-LoaderRefSymLists
-PixmapWidthPaddingInfo
-SetTimeSinceLastInputEvent
-ShadowFBInit2
-VBEExtendedInit
-VBEGetVBEMode
-VBESaveRestore
-VBESetDisplayStart
-VBESetGetPaletteData
-VBESetVBEMode
-XNFalloc
-XNFcalloc
-XNFprintf
-XNFrealloc
-XNFstrdup
-Xalloc
-Xcalloc
-Xfree
-Xrealloc
-_GLOBAL_OFFSET_TABLE_
-_Jv_RegisterClasses
-___errno
-__cxa_finalize
-__deregister_frame_info_bases
-__divdi3
-__errno_location
-__fxstat64
-__gmon_start__
-__iob
-__isoc99_sscanf
-__moddi3
-__register_frame_info_bases
-__stack_chk_fail
-__udivdi3
-__umoddi3
-__xstat64
-calloc
-chdir
-chmod
-chown
-close
-drmFreeVersion
-drmGetVersion
-fbPictureInit
-fbScreenInit
-fchmod
-fcntl
-fflush
-flock
-fprintf
-fputs
-free
-fstat
-fsync
-ftruncate
-ftruncate64
-futimes
-getcwd
-getenv
-geteuid
-getpwuid_r
-iconv
-iconv_close
-iconv_open
-ioctl
-lchown
-lseek
-lseek64
-malloc
-memalign
-memchr
-memcmp
-memcpy
-memmove
-memset
-miClearVisualTypes
-miCreateDefColormap
-miDCInitialize
-miInitializeBackingStore
-miSetPixmapDepths
-miSetVisualTypes
-mmap64
-mprotect
-munmap
-nl_langinfo
-open
-open64
-pciFindFirst
-pciReadLong
-pciTag
-pci_device_map_range
-pci_device_next
-pci_device_probe
-pci_device_unmap_range
-pci_id_match_iterator_create
-pci_iterator_destroy
-posix_memalign
-pthread_sigmask
-putenv
-read
-realloc
-realpath
-rename
-resVgaShared
-screenInfo
-serverGeneration
-setenv
-sigdelset
-sigfillset
-sprintf
-stat
-stderr
-strchr
-strcmp
-strcpy
-strlen
-strncmp
-strpbrk
-strstr
-symlink
-tolower
-unlink
-unsetenv
-utimes
-vgaHWDPMSSet
-vgaHWFreeHWRec
-vgaHWGetHWRec
-vgaHWGetIndex
-vgaHWHandleColormaps
-vgaHWMapMem
-vgaHWRestoreFonts
-vgaHWSaveFonts
-vgaHWSaveScreen
-vgaHWUnmapMem
-write
-xf86AddDriver
-xf86CollectOptions
-xf86ConfigPciEntity
-xf86CreateCursorInfoRec
-xf86DPMSInit
-xf86DestroyCursorInfoRec
-xf86DrvMsg
-xf86GetEntityInfo
-xf86GetPciInfoForEntity
-xf86GetPciVideoInfo
-xf86GetPointerScreenFuncs
-xf86HandleColormaps
-xf86InitCursor
-xf86IsUnblank
-xf86LoadSubModule
-xf86LoaderCheckSymbol
-xf86LoaderReqSymLists
-xf86MapDomainMemory
-xf86MapPciMem
-xf86MatchDevice
-xf86MatchPciInstances
-xf86Msg
-xf86PrintChipsets
-xf86PrintDepthBpp
-xf86PrintModes
-xf86ProcessOptions
-xf86PruneDriverModes
-xf86Screens
-xf86SetBackingStore
-xf86SetBlackWhitePixels
-xf86SetDefaultVisual
-xf86SetDepthBpp
-xf86SetDpi
-xf86SetGamma
-xf86SetWeight
-xf86ShowUnusedOptions
-xf86SlowBcopy
-xf86UnMapVidMem
-xf86ValidateModes
-xf86errno
-xf86isspace
-xf86memcpy
-xf86memset
-xf86sprintf
-xf86sscanf
-xf86strdup
-xf86strtoul
-xf86vsnprintf
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxutils.c b/src/VBox/Additions/x11/vboxvideo/vboxutils.c
index c7d419a84..06530b8c4 100644
--- a/src/VBox/Additions/x11/vboxvideo/vboxutils.c
+++ b/src/VBox/Additions/x11/vboxvideo/vboxutils.c
@@ -26,805 +26,13 @@
#define NEED_XF86_TYPES
#include <iprt/string.h>
#include "compiler.h"
-#include "cursorstr.h"
#include "vboxvideo.h"
-#define VBOX_MAX_CURSOR_WIDTH 64
-#define VBOX_MAX_CURSOR_HEIGHT 64
-
-/**************************************************************************
-* Debugging functions and macros *
-**************************************************************************/
-
-/* #define DEBUG_POINTER */
-
-#ifdef DEBUG
-# define PUT_PIXEL(c) ErrorF ("%c", c)
-#else /* DEBUG_VIDEO not defined */
-# define PUT_PIXEL(c) do { } while(0)
-#endif /* DEBUG_VIDEO not defined */
-
-/** Macro to printf an error message and return from a function */
-#define RETERROR(scrnIndex, RetVal, ...) \
- do \
- { \
- xf86DrvMsg(scrnIndex, X_ERROR, __VA_ARGS__); \
- return RetVal; \
- } \
- while (0)
-
-/** Structure to pass cursor image data between realise_cursor() and
- * load_cursor_image(). The members match the parameters to
- * @a VBoxHGSMIUpdatePointerShape(). */
-struct vboxCursorImage
-{
- uint32_t fFlags;
- uint32_t cHotX;
- uint32_t cHotY;
- uint32_t cWidth;
- uint32_t cHeight;
- uint8_t *pPixels;
- uint32_t cbLength;
-};
-
-#ifdef DEBUG_POINTER
-static void
-vbox_show_shape(unsigned short w, unsigned short h, CARD32 bg, unsigned char *image)
-{
- size_t x, y;
- unsigned short pitch;
- CARD32 *color;
- unsigned char *mask;
- size_t sizeMask;
-
- image += sizeof(struct vboxCursorImage);
- mask = image;
- pitch = (w + 7) / 8;
- sizeMask = (pitch * h + 3) & ~3;
- color = (CARD32 *)(image + sizeMask);
-
- TRACE_ENTRY();
- for (y = 0; y < h; ++y, mask += pitch, color += w)
- {
- for (x = 0; x < w; ++x)
- {
- if (mask[x / 8] & (1 << (7 - (x % 8))))
- ErrorF (" ");
- else
- {
- CARD32 c = color[x];
- if (c == bg)
- ErrorF("Y");
- else
- ErrorF("X");
- }
- }
- ErrorF("\n");
- }
-}
-#endif
-
-/**************************************************************************
-* Helper functions and macros *
-**************************************************************************/
-
-/* This is called by the X server every time it loads a new cursor to see
- * whether our "cursor hardware" can handle the cursor. This provides us with
- * a mechanism (the only one!) to switch back from a software to a hardware
- * cursor. */
-static Bool
-vbox_host_uses_hwcursor(ScrnInfoPtr pScrn)
-{
- Bool rc = TRUE;
- uint32_t fFeatures = 0;
- VBOXPtr pVBox = pScrn->driverPrivate;
-
- /* We may want to force the use of a software cursor. Currently this is
- * needed if the guest uses a large virtual resolution, as in this case
- * the host and guest tend to disagree about the pointer location. */
- if (pVBox->forceSWCursor)
- rc = FALSE;
- /* Query information about mouse integration from the host. */
- if (rc) {
- int vrc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
- if (RT_FAILURE(vrc)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Unable to determine whether the virtual machine supports mouse pointer integration - request initialization failed with return code %d\n", vrc);
- rc = FALSE;
- }
- }
- /* If we got the information from the host then make sure the host wants
- * to draw the pointer. */
- if (rc)
- {
- if ( (fFeatures & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE)
-#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5
- /* As of this version (server 1.6) all major Linux releases
- * are known to handle USB tablets correctly. */
- || (fFeatures & VMMDEV_MOUSE_HOST_HAS_ABS_DEV)
-#endif
- )
- /* Assume this will never be unloaded as long as the X session is
- * running. */
- pVBox->guestCanAbsolute = TRUE;
- if ( (fFeatures & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER)
- || !pVBox->guestCanAbsolute
- || !(fFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)
- )
- rc = FALSE;
- }
- return rc;
-}
-
/**************************************************************************
* Main functions *
**************************************************************************/
-void
-vbox_close(ScrnInfoPtr pScrn, VBOXPtr pVBox)
-{
- TRACE_ENTRY();
-
- xf86DestroyCursorInfoRec(pVBox->pCurs);
- pVBox->pCurs = NULL;
- TRACE_EXIT();
-}
-
-/**
- * Callback function called by the X server to tell us about dirty
- * rectangles in the video buffer.
- *
- * @param pScreen pointer to the information structure for the current
- * screen
- * @param iRects Number of dirty rectangles to update
- * @param aRects Array of structures containing the coordinates of the
- * rectangles
- */
-static void
-vboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
-{
- VBVACMDHDR cmdHdr;
- VBOXPtr pVBox;
- int i;
- unsigned j;
-
- pVBox = pScrn->driverPrivate;
- if (pVBox->fHaveHGSMI == FALSE || pVBox->vtSwitch)
- return;
-
- for (i = 0; i < iRects; ++i)
- for (j = 0; j < pVBox->cScreens; ++j)
- {
- /* Just continue quietly if VBVA is not currently active. */
- struct VBVABUFFER *pVBVA = pVBox->aVbvaCtx[j].pVBVA;
- if ( !pVBVA
- || !(pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
- continue;
- if ( aRects[i].x1 > pVBox->aScreenLocation[j].x
- + pVBox->aScreenLocation[j].cx
- || aRects[i].y1 > pVBox->aScreenLocation[j].y
- + pVBox->aScreenLocation[j].cy
- || aRects[i].x2 < pVBox->aScreenLocation[j].x
- || aRects[i].y2 < pVBox->aScreenLocation[j].y)
- continue;
- cmdHdr.x = (int16_t)aRects[i].x1;
- cmdHdr.y = (int16_t)aRects[i].y1;
- cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
- cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
-
-#if 0
- TRACE_LOG("display=%u, x=%d, y=%d, w=%d, h=%d\n",
- j, cmdHdr.x, cmdHdr.y, cmdHdr.w, cmdHdr.h);
-#endif
-
- if (VBoxVBVABufferBeginUpdate(&pVBox->aVbvaCtx[j],
- &pVBox->guestCtx))
- {
- VBoxVBVAWrite(&pVBox->aVbvaCtx[j], &pVBox->guestCtx, &cmdHdr,
- sizeof(cmdHdr));
- VBoxVBVABufferEndUpdate(&pVBox->aVbvaCtx[j]);
- }
- }
-}
-
-/** Callback to fill in the view structures */
-static int
-vboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews)
-{
- VBOXPtr pVBox = (VBOXPtr)pvVBox;
- unsigned i;
- for (i = 0; i < cViews; ++i)
- {
- pViews[i].u32ViewIndex = i;
- pViews[i].u32ViewOffset = 0;
- pViews[i].u32ViewSize = pVBox->cbView;
- pViews[i].u32MaxScreenSize = pVBox->cbFBMax;
- }
- return VINF_SUCCESS;
-}
-
-/**
- * Initialise VirtualBox's accelerated video extensions.
- *
- * @returns TRUE on success, FALSE on failure
- */
-static Bool
-vboxInitVbva(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- int rc = VINF_SUCCESS;
-
- pVBox->cScreens = 1;
- if (!VBoxHGSMIIsSupported())
- {
- xf86DrvMsg(scrnIndex, X_ERROR, "The graphics device does not seem to support HGSMI. Disableing video acceleration.\n");
- return FALSE;
- }
-
- /* Set up the dirty rectangle handler. It will be added into a function
- * chain and gets removed when the screen is cleaned up. */
- if (ShadowFBInit2(pScreen, NULL, vboxHandleDirtyRect) != TRUE)
- {
- xf86DrvMsg(scrnIndex, X_ERROR,
- "Unable to install dirty rectangle handler for VirtualBox graphics acceleration.\n");
- return FALSE;
- }
- return TRUE;
-}
-
-/**
- * Initialise VirtualBox's accelerated video extensions.
- *
- * @returns TRUE on success, FALSE on failure
- */
-static Bool
-vboxSetupVRAMVbva(ScrnInfoPtr pScrn, VBOXPtr pVBox)
-{
- int rc = VINF_SUCCESS;
- unsigned i;
- uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory;
- void *pvGuestHeapMemory;
-
- if (!pVBox->fHaveHGSMI)
- return FALSE;
- VBoxHGSMIGetBaseMappingInfo(pScrn->videoRam * 1024, &offVRAMBaseMapping,
- NULL, &offGuestHeapMemory, &cbGuestHeapMemory,
- NULL);
- pvGuestHeapMemory = ((uint8_t *)pVBox->base) + offVRAMBaseMapping
- + offGuestHeapMemory;
- TRACE_LOG("video RAM: %u KB, guest heap offset: 0x%x, cbGuestHeapMemory: %u\n",
- pScrn->videoRam, offVRAMBaseMapping + offGuestHeapMemory,
- cbGuestHeapMemory);
- rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory,
- cbGuestHeapMemory,
- offVRAMBaseMapping + offGuestHeapMemory);
- if (RT_FAILURE(rc))
- {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up the guest-to-host communication context, rc=%d\n", rc);
- return FALSE;
- }
- pVBox->cbView = pVBox->cbFBMax = offVRAMBaseMapping;
- pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n",
- pVBox->cScreens);
- for (i = 0; i < pVBox->cScreens; ++i)
- {
- pVBox->cbFBMax -= VBVA_MIN_BUFFER_SIZE;
- pVBox->aoffVBVABuffer[i] = pVBox->cbFBMax;
- TRACE_LOG("VBVA buffer offset for screen %u: 0x%lx\n", i,
- (unsigned long) pVBox->cbFBMax);
- VBoxVBVASetupBufferContext(&pVBox->aVbvaCtx[i],
- pVBox->aoffVBVABuffer[i],
- VBVA_MIN_BUFFER_SIZE);
- }
- TRACE_LOG("Maximum framebuffer size: %lu (0x%lx)\n",
- (unsigned long) pVBox->cbFBMax,
- (unsigned long) pVBox->cbFBMax);
- rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens,
- vboxFillViewInfo, (void *)pVBox);
- if (RT_FAILURE(rc))
- {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to send the view information to the host, rc=%d\n", rc);
- return FALSE;
- }
- return TRUE;
-}
-
-Bool
-vbox_init(int scrnIndex, VBOXPtr pVBox)
-{
- Bool rc = TRUE;
- int vrc;
- uint32_t fMouseFeatures = 0;
-
- TRACE_ENTRY();
- vrc = VbglR3Init();
- if (RT_FAILURE(vrc))
- {
- xf86DrvMsg(scrnIndex, X_ERROR,
- "Failed to initialize the VirtualBox device (rc=%d) - make sure that the VirtualBox guest additions are properly installed. If you are not sure, try reinstalling them. The X Window graphics drivers will run in compatibility mode.\n",
- vrc);
- rc = FALSE;
- }
- pVBox->useDevice = rc;
- /* We can't switch to a software cursor at will without help from
- * VBoxClient. So tell that to the host and wait for VBoxClient to
- * change this. */
- vrc = VbglR3GetMouseStatus(&fMouseFeatures, NULL, NULL);
- if (RT_SUCCESS(vrc))
- VbglR3SetMouseStatus( fMouseFeatures
- | VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR);
- return rc;
-}
-
-Bool
-vbox_open(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
-{
- TRACE_ENTRY();
-
- pVBox->fHaveHGSMI = vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox);
- return pVBox->fHaveHGSMI;
-}
-
-Bool
-vbox_device_available(VBOXPtr pVBox)
-{
- return pVBox->useDevice;
-}
-
-static void
-vbox_vmm_hide_cursor(ScrnInfoPtr pScrn, VBOXPtr pVBox)
-{
- int rc;
-
- rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, 0, 0, 0, 0, 0, NULL, 0);
- if (RT_FAILURE(rc))
- {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not hide the virtual mouse pointer, VBox error %d.\n", rc);
- /* Play safe, and disable the hardware cursor until the next mode
- * switch, since obviously something happened that we didn't
- * anticipate. */
- pVBox->forceSWCursor = TRUE;
- }
-}
-
-static void
-vbox_vmm_show_cursor(ScrnInfoPtr pScrn, VBOXPtr pVBox)
-{
- int rc;
-
- if (!vbox_host_uses_hwcursor(pScrn))
- return;
- rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, VBOX_MOUSE_POINTER_VISIBLE,
- 0, 0, 0, 0, NULL, 0);
- if (RT_FAILURE(rc)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not unhide the virtual mouse pointer.\n");
- /* Play safe, and disable the hardware cursor until the next mode
- * switch, since obviously something happened that we didn't
- * anticipate. */
- pVBox->forceSWCursor = TRUE;
- }
-}
-
-static void
-vbox_vmm_load_cursor_image(ScrnInfoPtr pScrn, VBOXPtr pVBox,
- unsigned char *pvImage)
-{
- int rc;
- struct vboxCursorImage *pImage;
- pImage = (struct vboxCursorImage *)pvImage;
-
-#ifdef DEBUG_POINTER
- vbox_show_shape(pImage->cWidth, pImage->cHeight, 0, pvImage);
-#endif
-
- rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, pImage->fFlags,
- pImage->cHotX, pImage->cHotY, pImage->cWidth, pImage->cHeight,
- pImage->pPixels, pImage->cbLength);
- if (RT_FAILURE(rc)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to set the virtual mouse pointer image.\n");
- /* Play safe, and disable the hardware cursor until the next mode
- * switch, since obviously something happened that we didn't
- * anticipate. */
- pVBox->forceSWCursor = TRUE;
- }
-}
-
-static void
-vbox_set_cursor_colors(ScrnInfoPtr pScrn, int bg, int fg)
-{
- NOREF(pScrn);
- NOREF(bg);
- NOREF(fg);
- /* ErrorF("vbox_set_cursor_colors NOT IMPLEMENTED\n"); */
-}
-
-
-static void
-vbox_set_cursor_position(ScrnInfoPtr pScrn, int x, int y)
-{
- /* Nothing to do here, as we are telling the guest where the mouse is,
- * not vice versa. */
- NOREF(pScrn);
- NOREF(x);
- NOREF(y);
-}
-
-static void
-vbox_hide_cursor(ScrnInfoPtr pScrn)
-{
- VBOXPtr pVBox = pScrn->driverPrivate;
-
- vbox_vmm_hide_cursor(pScrn, pVBox);
-}
-
-static void
-vbox_show_cursor(ScrnInfoPtr pScrn)
-{
- VBOXPtr pVBox = pScrn->driverPrivate;
-
- vbox_vmm_show_cursor(pScrn, pVBox);
-}
-
-static void
-vbox_load_cursor_image(ScrnInfoPtr pScrn, unsigned char *image)
-{
- VBOXPtr pVBox = pScrn->driverPrivate;
-
- vbox_vmm_load_cursor_image(pScrn, pVBox, image);
-}
-
-static Bool
-vbox_use_hw_cursor(ScreenPtr pScreen, CursorPtr pCurs)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- return vbox_host_uses_hwcursor(pScrn);
-}
-
-static unsigned char
-color_to_byte(unsigned c)
-{
- return (c >> 8) & 0xff;
-}
-
-static unsigned char *
-vbox_realize_cursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
-{
- VBOXPtr pVBox;
- CursorBitsPtr bitsp;
- unsigned short w, h, x, y;
- unsigned char *c, *p, *pm, *ps, *m;
- size_t sizeRequest, sizeRgba, sizeMask, srcPitch, dstPitch;
- CARD32 fc, bc, *cp;
- int rc, scrnIndex = infoPtr->pScrn->scrnIndex;
- struct vboxCursorImage *pImage;
-
- pVBox = infoPtr->pScrn->driverPrivate;
- bitsp = pCurs->bits;
- w = bitsp->width;
- h = bitsp->height;
-
- if (!w || !h || w > VBOX_MAX_CURSOR_WIDTH || h > VBOX_MAX_CURSOR_HEIGHT)
- RETERROR(scrnIndex, NULL,
- "Error invalid cursor dimensions %dx%d\n", w, h);
-
- if ((bitsp->xhot > w) || (bitsp->yhot > h))
- RETERROR(scrnIndex, NULL,
- "Error invalid cursor hotspot location %dx%d (max %dx%d)\n",
- bitsp->xhot, bitsp->yhot, w, h);
-
- srcPitch = PixmapBytePad (bitsp->width, 1);
- dstPitch = (w + 7) / 8;
- sizeMask = ((dstPitch * h) + 3) & (size_t) ~3;
- sizeRgba = w * h * 4;
- sizeRequest = sizeMask + sizeRgba + sizeof(*pImage);
-
- p = c = calloc (1, sizeRequest);
- if (!c)
- RETERROR(scrnIndex, NULL,
- "Error failed to alloc %lu bytes for cursor\n",
- (unsigned long) sizeRequest);
-
- pImage = (struct vboxCursorImage *)p;
- pImage->pPixels = m = p + sizeof(*pImage);
- cp = (CARD32 *)(m + sizeMask);
-
- TRACE_LOG ("w=%d h=%d sm=%d sr=%d p=%d\n",
- w, h, (int) sizeMask, (int) sizeRgba, (int) dstPitch);
- TRACE_LOG ("m=%p c=%p cp=%p\n", m, c, (void *)cp);
-
- fc = color_to_byte (pCurs->foreBlue)
- | (color_to_byte (pCurs->foreGreen) << 8)
- | (color_to_byte (pCurs->foreRed) << 16);
-
- bc = color_to_byte (pCurs->backBlue)
- | (color_to_byte (pCurs->backGreen) << 8)
- | (color_to_byte (pCurs->backRed) << 16);
-
- /*
- * Convert the Xorg source/mask bits to the and/xor bits VBox needs.
- * Xorg:
- * The mask is a bitmap indicating which parts of the cursor are
- * transparent and which parts are drawn. The source is a bitmap
- * indicating which parts of the non-transparent portion of the
- * the cursor should be painted in the foreground color and which
- * should be painted in the background color. By default, set bits
- * indicate the opaque part of the mask bitmap and clear bits
- * indicate the transparent part.
- * VBox:
- * The color data is the XOR mask. The AND mask bits determine
- * which pixels of the color data (XOR mask) will replace (overwrite)
- * the screen pixels (AND mask bit = 0) and which ones will be XORed
- * with existing screen pixels (AND mask bit = 1).
- * For example when you have the AND mask all 0, then you see the
- * correct mouse pointer image surrounded by black square.
- */
- for (pm = bitsp->mask, ps = bitsp->source, y = 0;
- y < h;
- ++y, pm += srcPitch, ps += srcPitch, m += dstPitch)
- {
- for (x = 0; x < w; ++x)
- {
- if (pm[x / 8] & (1 << (x % 8)))
- {
- /* opaque, leave AND mask bit at 0 */
- if (ps[x / 8] & (1 << (x % 8)))
- {
- *cp++ = fc;
- PUT_PIXEL('X');
- }
- else
- {
- *cp++ = bc;
- PUT_PIXEL('*');
- }
- }
- else
- {
- /* transparent, set AND mask bit */
- m[x / 8] |= 1 << (7 - (x % 8));
- /* don't change the screen pixel */
- *cp++ = 0;
- PUT_PIXEL(' ');
- }
- }
- PUT_PIXEL('\n');
- }
-
- pImage->cWidth = w;
- pImage->cHeight = h;
- pImage->cHotX = bitsp->xhot;
- pImage->cHotY = bitsp->yhot;
- pImage->fFlags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE;
- pImage->cbLength = sizeRequest - sizeof(*pImage);
-
-#ifdef DEBUG_POINTER
- ErrorF("shape = %p\n", p);
- vbox_show_shape(w, h, bc, c);
-#endif
-
- return p;
-}
-
-#ifdef ARGB_CURSOR
-static Bool
-vbox_use_hw_cursor_argb(ScreenPtr pScreen, CursorPtr pCurs)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- Bool rc = TRUE;
-
- if (!vbox_host_uses_hwcursor(pScrn))
- rc = FALSE;
- if ( rc
- && ( (pCurs->bits->height > VBOX_MAX_CURSOR_HEIGHT)
- || (pCurs->bits->width > VBOX_MAX_CURSOR_WIDTH)
- || (pScrn->bitsPerPixel <= 8)
- )
- )
- rc = FALSE;
-#ifndef VBOXVIDEO_13
- /* Evil hack - we use this as another way of poking the driver to update
- * our list of video modes. */
- vboxWriteHostModes(pScrn, pScrn->currentMode);
-#endif
- return rc;
-}
-
-
-static void
-vbox_load_cursor_argb(ScrnInfoPtr pScrn, CursorPtr pCurs)
-{
- VBOXPtr pVBox;
- VMMDevReqMousePointer *reqp;
- CursorBitsPtr bitsp;
- unsigned short w, h;
- unsigned short cx, cy;
- unsigned char *pm;
- CARD32 *pc;
- size_t sizeData, sizeMask;
- CARD8 *p;
- int scrnIndex;
- uint32_t fFlags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE
- | VBOX_MOUSE_POINTER_ALPHA;
- int rc;
-
- pVBox = pScrn->driverPrivate;
- bitsp = pCurs->bits;
- w = bitsp->width;
- h = bitsp->height;
- scrnIndex = pScrn->scrnIndex;
-
- /* Mask must be generated for alpha cursors, that is required by VBox. */
- /* note: (michael) the next struct must be 32bit aligned. */
- sizeMask = ((w + 7) / 8 * h + 3) & ~3;
-
- if (!w || !h || w > VBOX_MAX_CURSOR_WIDTH || h > VBOX_MAX_CURSOR_HEIGHT)
- RETERROR(scrnIndex, ,
- "Error invalid cursor dimensions %dx%d\n", w, h);
-
- if ((bitsp->xhot > w) || (bitsp->yhot > h))
- RETERROR(scrnIndex, ,
- "Error invalid cursor hotspot location %dx%d (max %dx%d)\n",
- bitsp->xhot, bitsp->yhot, w, h);
-
- sizeData = w * h * 4 + sizeMask;
- p = calloc(1, sizeData);
- if (!p)
- RETERROR(scrnIndex, ,
- "Error failed to alloc %lu bytes for cursor\n",
- (unsigned long)sizeData);
-
- memcpy(p + sizeMask, bitsp->argb, w * h * 4);
-
- /* Emulate the AND mask. */
- pm = p;
- pc = bitsp->argb;
-
- /* Init AND mask to 1 */
- memset(pm, 0xFF, sizeMask);
-
- /*
- * The additions driver must provide the AND mask for alpha cursors. The host frontend
- * which can handle alpha channel, will ignore the AND mask and draw an alpha cursor.
- * But if the host does not support ARGB, then it simply uses the AND mask and the color
- * data to draw a normal color cursor.
- */
- for (cy = 0; cy < h; cy++)
- {
- unsigned char bitmask = 0x80;
-
- for (cx = 0; cx < w; cx++, bitmask >>= 1)
- {
- if (bitmask == 0)
- bitmask = 0x80;
-
- if (pc[cx] >= 0xF0000000)
- pm[cx / 8] &= ~bitmask;
- }
-
- /* Point to next source and dest scans */
- pc += w;
- pm += (w + 7) / 8;
- }
-
- rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, fFlags, bitsp->xhot,
- bitsp->yhot, w, h, p, sizeData);
- free(p);
-}
-#endif
-
-Bool
-vbox_cursor_init(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- VBOXPtr pVBox = pScrn->driverPrivate;
- xf86CursorInfoPtr pCurs = NULL;
- Bool rc = TRUE;
-
- TRACE_ENTRY();
- if (!pVBox->fHaveHGSMI)
- return FALSE;
- pVBox->pCurs = pCurs = xf86CreateCursorInfoRec();
- if (!pCurs) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to create X Window cursor information structures for virtual mouse.\n");
- rc = FALSE;
- }
- if (rc) {
- pCurs->MaxWidth = VBOX_MAX_CURSOR_WIDTH;
- pCurs->MaxHeight = VBOX_MAX_CURSOR_HEIGHT;
- pCurs->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
- | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1
- | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
-
- pCurs->SetCursorColors = vbox_set_cursor_colors;
- pCurs->SetCursorPosition = vbox_set_cursor_position;
- pCurs->LoadCursorImage = vbox_load_cursor_image;
- pCurs->HideCursor = vbox_hide_cursor;
- pCurs->ShowCursor = vbox_show_cursor;
- pCurs->UseHWCursor = vbox_use_hw_cursor;
- pCurs->RealizeCursor = vbox_realize_cursor;
-
-#ifdef ARGB_CURSOR
- pCurs->UseHWCursorARGB = vbox_use_hw_cursor_argb;
- pCurs->LoadCursorARGB = vbox_load_cursor_argb;
-#endif
-
- /* Hide the host cursor before we initialise if we wish to use a
- * software cursor. */
- if (pVBox->forceSWCursor)
- vbox_vmm_hide_cursor(pScrn, pVBox);
- rc = xf86InitCursor(pScreen, pCurs);
- }
- if (!rc)
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to enable mouse pointer integration.\n");
- if (!rc && (pCurs != NULL))
- xf86DestroyCursorInfoRec(pCurs);
- return rc;
-}
-
-/**
- * Inform VBox that we will supply it with dirty rectangle information
- * and install the dirty rectangle handler.
- *
- * @returns TRUE for success, FALSE for failure
- * @param pScrn Pointer to a structure describing the X screen in use
- */
-Bool
-vboxEnableVbva(ScrnInfoPtr pScrn)
-{
- bool rc = TRUE;
- int scrnIndex = pScrn->scrnIndex;
- unsigned i;
- VBOXPtr pVBox = pScrn->driverPrivate;
-
- TRACE_ENTRY();
- if (!vboxSetupVRAMVbva(pScrn, pVBox))
- return FALSE;
- for (i = 0; i < pVBox->cScreens; ++i)
- {
- struct VBVABUFFER *pVBVA;
-
- pVBVA = (struct VBVABUFFER *) ( ((uint8_t *)pVBox->base)
- + pVBox->aoffVBVABuffer[i]);
- if (!VBoxVBVAEnable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, pVBVA, i))
- rc = FALSE;
- }
- if (!rc)
- {
- /* Request not accepted - disable for old hosts. */
- xf86DrvMsg(scrnIndex, X_ERROR,
- "Failed to enable screen update reporting for at least one virtual monitor.\n");
- vboxDisableVbva(pScrn);
- }
- return rc;
-}
-
-/**
- * Inform VBox that we will stop supplying it with dirty rectangle
- * information. This function is intended to be called when an X
- * virtual terminal is disabled, or the X server is terminated.
- *
- * @returns TRUE for success, FALSE for failure
- * @param pScrn Pointer to a structure describing the X screen in use
- */
-void
-vboxDisableVbva(ScrnInfoPtr pScrn)
-{
- int rc;
- int scrnIndex = pScrn->scrnIndex;
- unsigned i;
- VBOXPtr pVBox = pScrn->driverPrivate;
-
- TRACE_ENTRY();
- if (!pVBox->fHaveHGSMI) /* Ths function should not have been called */
- return;
- for (i = 0; i < pVBox->cScreens; ++i)
- VBoxVBVADisable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, i);
-}
-
/**
* Inform VBox that we are aware of advanced graphics functions
* (i.e. dynamic resizing, seamless).
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxvideo.c b/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
index 21730b4b8..caae3d1ff 100644
--- a/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
+++ b/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
@@ -1,4 +1,4 @@
-/* $Id: vboxvideo.c $ */
+/* $Id: vboxvideo.c 36020 2011-02-18 14:18:51Z vboxsync $ */
/** @file
*
* Linux Additions X11 graphics driver
@@ -62,9 +62,6 @@
/* All drivers initialising the SW cursor need this */
#include "mipointer.h"
-/* All drivers implementing backing store need this */
-#include "mibstore.h"
-
/* Colormap handling */
#include "micmap.h"
#include "xf86cmap.h"
@@ -102,20 +99,16 @@ static void VBOXLeaveVT(int scrnIndex, int flags);
static Bool VBOXCloseScreen(int scrnIndex, ScreenPtr pScreen);
static Bool VBOXSaveScreen(ScreenPtr pScreen, int mode);
static Bool VBOXSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags);
-static Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
- unsigned cHeight, int x, int y);
static void VBOXAdjustFrame(int scrnIndex, int x, int y, int flags);
static void VBOXFreeScreen(int scrnIndex, int flags);
-static void VBOXFreeRec(ScrnInfoPtr pScrn);
static void VBOXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode,
int flags);
/* locally used functions */
static Bool VBOXMapVidMem(ScrnInfoPtr pScrn);
static void VBOXUnmapVidMem(ScrnInfoPtr pScrn);
-static Bool VBOXSaveRestore(ScrnInfoPtr pScrn,
- vbeSaveRestoreFunction function);
-static Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height);
+static void VBOXSaveMode(ScrnInfoPtr pScrn);
+static void VBOXRestoreMode(ScrnInfoPtr pScrn);
enum GenericTypes
{
@@ -198,28 +191,7 @@ static const char *fbSymbols[] = {
};
static const char *shadowfbSymbols[] = {
- "ShadowFBInit2",
- NULL
-};
-
-static const char *vbeSymbols[] = {
- "VBEExtendedInit",
- "VBEFindSupportedDepths",
- "VBEGetModeInfo",
- "VBEGetVBEInfo",
- "VBEGetVBEMode",
- "VBEPrintModes",
- "VBESaveRestore",
- "VBESetDisplayStart",
- "VBESetGetDACPaletteFormat",
- "VBESetGetLogicalScanlineLength",
- "VBESetGetPaletteData",
- "VBESetModeNames",
- "VBESetModeParameters",
- "VBESetVBEMode",
- "VBEValidateModes",
- "vbeDoEDID",
- "vbeFree",
+ "ShadowFBInit2",
NULL
};
@@ -230,41 +202,16 @@ static const char *ramdacSymbols[] = {
};
static const char *vgahwSymbols[] = {
- "vgaHWGetHWRec",
- "vgaHWHandleColormaps",
"vgaHWFreeHWRec",
- "vgaHWMapMem",
- "vgaHWUnmapMem",
- "vgaHWSaveFonts",
- "vgaHWRestoreFonts",
+ "vgaHWGetHWRec",
+ "vgaHWGetIOBase",
"vgaHWGetIndex",
- "vgaHWSaveScreen",
- "vgaHWDPMSSet",
+ "vgaHWRestore",
+ "vgaHWSave",
NULL
};
#endif /* !XORG_7X */
-static VBOXPtr
-VBOXGetRec(ScrnInfoPtr pScrn)
-{
- if (!pScrn->driverPrivate)
- {
- pScrn->driverPrivate = calloc(sizeof(VBOXRec), 1);
- }
-
- return ((VBOXPtr)pScrn->driverPrivate);
-}
-
-static void
-VBOXFreeRec(ScrnInfoPtr pScrn)
-{
- VBOXPtr pVBox = VBOXGetRec(pScrn);
- free(pVBox->savedPal);
- free(pVBox->fonts);
- free(pScrn->driverPrivate);
- pScrn->driverPrivate = NULL;
-}
-
#ifdef VBOXVIDEO_13
/* X.org 1.3+ mode-setting support ******************************************/
@@ -590,7 +537,6 @@ vboxSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor)
#ifndef XORG_7X
LoaderRefSymLists(fbSymbols,
shadowfbSymbols,
- vbeSymbols,
ramdacSymbols,
vgahwSymbols,
NULL);
@@ -738,28 +684,6 @@ vboxEnableDisableFBAccess(int scrnIndex, Bool enable)
TRACE_EXIT();
}
-/** Calculate the BPP from the screen depth */
-static uint16_t
-vboxBPP(ScrnInfoPtr pScrn)
-{
- return pScrn->depth == 24 ? 32 : 16;
-}
-
-/** Calculate the scan line length for a display width */
-static int32_t
-vboxLineLength(ScrnInfoPtr pScrn, int32_t cDisplayWidth)
-{
- uint64_t cbLine = ((uint64_t)cDisplayWidth * vboxBPP(pScrn) / 8 + 3) & ~3;
- return cbLine < INT32_MAX ? cbLine : INT32_MAX;
-}
-
-/** Calculate the display pitch from the scan line length */
-static int32_t
-vboxDisplayPitch(ScrnInfoPtr pScrn, int32_t cbLine)
-{
- return ASMDivU64ByU32RetU32((uint64_t)cbLine * 8, vboxBPP(pScrn));
-}
-
/*
* QUOTE from the XFree86 DESIGN document:
*
@@ -803,6 +727,8 @@ VBOXPreInit(ScrnInfoPtr pScrn, int flags)
/* Get our private data from the ScrnInfoRec structure. */
pVBox = VBOXGetRec(pScrn);
+ if (!pVBox)
+ return FALSE;
/* Initialise the guest library */
vbox_init(pScrn->scrnIndex, pVBox);
@@ -814,13 +740,8 @@ VBOXPreInit(ScrnInfoPtr pScrn, int flags)
if (!xf86LoadSubModule(pScrn, "ramdac"))
return FALSE;
- /* We need the vbe module because we use VBE code to save and restore
- text mode, in order to keep our code simple. */
- if (!xf86LoadSubModule(pScrn, "vbe"))
- return (FALSE);
-
/* The framebuffer module. */
- if (xf86LoadSubModule(pScrn, "fb") == NULL)
+ if (!xf86LoadSubModule(pScrn, "fb"))
return (FALSE);
if (!xf86LoadSubModule(pScrn, "shadowfb"))
@@ -849,10 +770,10 @@ VBOXPreInit(ScrnInfoPtr pScrn, int flags)
capabilities to X. */
pScrn->chipset = "vbox";
+ /** @note needed during colourmap initialisation */
pScrn->rgbBits = 8;
- /* Let's create a nice, capable virtual monitor.
- * This *is* still needed, at least for server version 1.3 */
+ /* Let's create a nice, capable virtual monitor. */
pScrn->monitor = pScrn->confScreen->monitor;
pScrn->monitor->DDC = NULL;
pScrn->monitor->nHsync = 1;
@@ -930,6 +851,12 @@ VBOXPreInit(ScrnInfoPtr pScrn, int flags)
xf86PrintModes(pScrn);
+ /* VGA hardware initialisation */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+ /* Must be called before any VGA registers are saved or restored */
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+
/* Colour weight - we always call this, since we are always in
truecolour. */
if (!xf86SetWeight(pScrn, rzeros, rzeros))
@@ -944,8 +871,14 @@ VBOXPreInit(ScrnInfoPtr pScrn, int flags)
/* Set the DPI. Perhaps we should read this from the host? */
xf86SetDpi(pScrn, 96, 96);
- /* Framebuffer-related setup */
- pScrn->bitmapBitOrder = BITMAP_BIT_ORDER;
+ if (pScrn->memPhysBase == 0) {
+#ifdef PCIACCESS
+ pScrn->memPhysBase = pVBox->pciInfo->regions[0].base_addr;
+#else
+ pScrn->memPhysBase = pVBox->pciInfo->memBase[0];
+#endif
+ pScrn->fbOffset = 0;
+ }
TRACE_EXIT();
return (TRUE);
@@ -987,36 +920,14 @@ VBOXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
TRACE_ENTRY();
- /* VGA hardware initialisation */
- if (!vgaHWGetHWRec(pScrn))
- return FALSE;
-
- /* We make use of the X11 VBE code to save and restore text mode, in
- order to keep our code simple. */
- if ((pVBox->pVbe = VBEExtendedInit(NULL, pVBox->pEnt->index,
- SET_BIOS_SCRATCH
- | RESTORE_BIOS_SCRATCH)) == NULL)
- return (FALSE);
-
- if (pScrn->memPhysBase == 0) {
-#ifdef PCIACCESS
- pScrn->memPhysBase = pVBox->pciInfo->regions[0].base_addr;
-#else
- pScrn->memPhysBase = pVBox->pciInfo->memBase[0];
-#endif
- pScrn->fbOffset = 0;
- }
-
if (!VBOXMapVidMem(pScrn))
return (FALSE);
/* save current video state */
- VBOXSaveRestore(pScrn, MODE_SAVE);
+ VBOXSaveMode(pScrn);
/* mi layer - reset the visual list (?)*/
miClearVisualTypes();
- if (!xf86SetDefaultVisual(pScrn, -1))
- return (FALSE);
if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
pScrn->rgbBits, TrueColor))
return (FALSE);
@@ -1027,8 +938,6 @@ VBOXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pVBox->useDRI = VBOXDRIScreenInit(scrnIndex, pScreen, pVBox);
#endif
- /* I checked in the sources, and XFree86 4.2 does seem to support
- this function for 32bpp. */
if (!fbScreenInit(pScreen, pVBox->base,
pScrn->virtualX, pScrn->virtualY,
pScrn->xDpi, pScrn->yDpi,
@@ -1036,6 +945,7 @@ VBOXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
return (FALSE);
/* Fixup RGB ordering */
+ /** @note the X server uses this even in true colour. */
visual = pScreen->visuals + pScreen->numVisuals;
while (--visual >= pScreen->visuals) {
if ((visual->class | DynamicClass) == DirectColor) {
@@ -1052,8 +962,6 @@ VBOXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
fbPictureInit(pScreen, 0, 0);
xf86SetBlackWhitePixels(pScreen);
- miInitializeBackingStore(pScreen);
- xf86SetBackingStore(pScreen);
/* We need to keep track of whether we are currently switched to a virtual
* terminal to know whether a mode set operation is currently safe to do.
@@ -1190,24 +1098,6 @@ VBOXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
return (TRUE);
}
-/** Clear the virtual framebuffer in VRAM. Optionally also clear up to the
- * size of a new framebuffer. Framebuffer sizes larger than available VRAM
- * be treated as zero and passed over. */
-static void
-vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY)
-{
- VBOXPtr pVBox = VBOXGetRec(pScrn);
- uint64_t cbOldFB, cbNewFB;
-
- cbOldFB = pVBox->cbLine * pScrn->virtualX;
- cbNewFB = vboxLineLength(pScrn, cNewX) * cNewY;
- if (cbOldFB > (uint64_t)pVBox->cbFBMax)
- cbOldFB = 0;
- if (cbNewFB > (uint64_t)pVBox->cbFBMax)
- cbNewFB = 0;
- memset(pVBox->base, 0, max(cbOldFB, cbNewFB));
-}
-
static Bool
VBOXEnterVT(int scrnIndex, int flags)
{
@@ -1246,7 +1136,7 @@ VBOXLeaveVT(int scrnIndex, int flags)
if (pVBox->fHaveHGSMI)
vboxDisableVbva(pScrn);
vboxClearVRAM(pScrn, 0, 0);
- VBOXSaveRestore(pScrn, MODE_RESTORE);
+ VBOXRestoreMode(pScrn);
vboxDisableGraphicsCap(pVBox);
#ifdef VBOX_DRI
if (pVBox->useDRI)
@@ -1272,15 +1162,12 @@ VBOXCloseScreen(int scrnIndex, ScreenPtr pScreen)
#endif
if (pScrn->vtSema) {
- VBOXSaveRestore(xf86Screens[scrnIndex], MODE_RESTORE);
+ VBOXRestoreMode(xf86Screens[scrnIndex]);
VBOXUnmapVidMem(pScrn);
}
pScrn->vtSema = FALSE;
- /* Destroy the VGA hardware record */
- vgaHWFreeHWRec(pScrn);
-
- /* And do additional bits which are separate for historical reasons */
+ /* Do additional bits which are separate for historical reasons */
vbox_close(pScrn, pVBox);
/* Remove our observer functions from the X server call chains. */
@@ -1324,110 +1211,6 @@ VBOXSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags)
return rc;
}
-/** Set a graphics mode. Poke any required values into registers, do an HGSMI
- * mode set and tell the host we support advanced graphics functions. This
- * procedure is complicated by the fact that X.Org can implicitly disable a
- * screen by resizing the virtual framebuffer so that the screen is no longer
- * inside it. We have to spot and handle this.
- */
-static Bool
-VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
- unsigned cHeight, int x, int y)
-{
- VBOXPtr pVBox = VBOXGetRec(pScrn);
- uint32_t offStart, cwReal = cWidth;
-
- TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n",
- cDisplay, cWidth, cHeight, x, y, pScrn->displayWidth);
- pVBox->aScreenLocation[cDisplay].cx = cWidth;
- pVBox->aScreenLocation[cDisplay].cy = cHeight;
- pVBox->aScreenLocation[cDisplay].x = x;
- pVBox->aScreenLocation[cDisplay].y = y;
- offStart = y * pVBox->cbLine + x * vboxBPP(pScrn) / 8;
- /* Deactivate the screen if the mode - specifically the virtual width - is
- * too large for VRAM as we sometimes have to do this - see comments in
- * VBOXPreInit. */
- if ( offStart + pVBox->cbLine * cHeight > pVBox->cbFBMax
- || pVBox->cbLine * pScrn->virtualY > pVBox->cbFBMax)
- return FALSE;
- /* Deactivate the screen if it is outside of the virtual framebuffer and
- * clamp it to lie inside if it is partly outside. */
- if (x >= pScrn->displayWidth || x + (int) cWidth <= 0)
- return FALSE;
- else
- cwReal = RT_MIN((int) cWidth, pScrn->displayWidth - x);
- TRACE_LOG("pVBox->afDisabled[cDisplay]=%d\n",
- (int)pVBox->afDisabled[cDisplay]);
- /* Don't fiddle with the hardware if we are switched
- * to a virtual terminal. */
- if (pVBox->vtSwitch)
- return TRUE;
- if (cDisplay == 0)
- VBoxVideoSetModeRegisters(cwReal, cHeight, pScrn->displayWidth,
- vboxBPP(pScrn), x, y);
- /* Tell the host we support graphics */
- if (vbox_device_available(pVBox))
- vboxEnableGraphicsCap(pVBox);
- if (pVBox->fHaveHGSMI)
- {
- uint16_t fFlags = VBVA_SCREEN_F_ACTIVE;
- fFlags |= (pVBox->afDisabled[cDisplay] ? VBVA_SCREEN_F_DISABLED : 0);
- VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x, y,
- offStart, pVBox->cbLine, cwReal, cHeight,
- vboxBPP(pScrn), fFlags);
- }
- return TRUE;
-}
-
-/** Resize the virtual framebuffer. After resizing we reset all modes
- * (X.Org 1.3+) to adjust them to the new framebuffer.
- */
-static Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
-{
- ScreenPtr pScreen = pScrn->pScreen;
- PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen);
- VBOXPtr pVBox = VBOXGetRec(pScrn);
- uint64_t cbLine = vboxLineLength(pScrn, width);
-
- TRACE_LOG("width=%d, height=%d\n", width, height);
- if (!pPixmap) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to get the screen pixmap.\n");
- return FALSE;
- }
- if (cbLine > UINT32_MAX || cbLine * height >= pVBox->cbFBMax)
- {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Unable to set up a virtual screen size of %dx%d with %lu of %d Kb of video memory available. Please increase the video memory size.\n",
- width, height, pVBox->cbFBMax / 1024, pScrn->videoRam);
- return FALSE;
- }
- pScreen->ModifyPixmapHeader(pPixmap, width, height,
- pScrn->depth, vboxBPP(pScrn), cbLine,
- pVBox->base);
- vboxClearVRAM(pScrn, width, height);
- pScrn->virtualX = width;
- pScrn->virtualY = height;
- pScrn->displayWidth = vboxDisplayPitch(pScrn, cbLine);
- pVBox->cbLine = cbLine;
-#ifdef VBOX_DRI
- if (pVBox->useDRI)
- VBOXDRIUpdateStride(pScrn, pVBox);
-#endif
-#ifdef VBOXVIDEO_13
- /* Write the new values to the hardware */
- {
- unsigned i;
- for (i = 0; i < pVBox->cScreens; ++i)
- VBOXSetMode(pScrn, i, pVBox->aScreenLocation[i].cx,
- pVBox->aScreenLocation[i].cy,
- pVBox->aScreenLocation[i].x,
- pVBox->aScreenLocation[i].y);
- }
-#endif
- return TRUE;
-}
-
static void
VBOXAdjustFrame(int scrnIndex, int x, int y, int flags)
{
@@ -1445,7 +1228,13 @@ VBOXAdjustFrame(int scrnIndex, int x, int y, int flags)
static void
VBOXFreeScreen(int scrnIndex, int flags)
{
- VBOXFreeRec(xf86Screens[scrnIndex]);
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ /* Destroy the VGA hardware record */
+ vgaHWFreeHWRec(pScrn);
+ /* And our private record */
+ free(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
}
static Bool
@@ -1469,13 +1258,7 @@ VBOXMapVidMem(ScrnInfoPtr pScrn)
pVBox->pciTag, pScrn->memPhysBase,
(unsigned) pScrn->videoRam * 1024);
#endif
- if (pVBox->base)
- {
- /* We need this for saving/restoring textmode */
- VGAHWPTR(pScrn)->IOBase = pScrn->domainIOBase;
- rc = vgaHWMapMem(pScrn);
- }
- else
+ if (!pVBox->base)
rc = FALSE;
}
TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
@@ -1499,7 +1282,6 @@ VBOXUnmapVidMem(ScrnInfoPtr pScrn)
xf86UnMapVidMem(pScrn->scrnIndex, pVBox->base,
(unsigned) pScrn->videoRam * 1024);
#endif
- vgaHWUnmapMem(pScrn);
pVBox->base = NULL;
TRACE_EXIT();
}
@@ -1511,67 +1293,37 @@ VBOXSaveScreen(ScreenPtr pScreen, int mode)
return TRUE;
}
-Bool
-VBOXSaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function)
+void
+VBOXSaveMode(ScrnInfoPtr pScrn)
{
- VBOXPtr pVBox;
- Bool rc = TRUE;
+ VBOXPtr pVBox = VBOXGetRec(pScrn);
+ vgaRegPtr vgaReg;
TRACE_ENTRY();
- if (MODE_QUERY < 0 || function > MODE_RESTORE)
- rc = FALSE;
-
- if (rc)
- {
- pVBox = VBOXGetRec(pScrn);
-
- /* Query amount of memory to save state */
- if (function == MODE_QUERY ||
- (function == MODE_SAVE && pVBox->state == NULL))
- {
+ vgaReg = &VGAHWPTR(pScrn)->SavedReg;
+ vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+ pVBox->fSavedVBEMode = VBoxVideoGetModeRegisters(&pVBox->cSavedWidth,
+ &pVBox->cSavedHeight,
+ &pVBox->cSavedPitch,
+ &pVBox->cSavedBPP,
+ &pVBox->fSavedFlags);
+}
- /* Make sure we save at least this information in case of failure */
- (void)VBEGetVBEMode(pVBox->pVbe, &pVBox->stateMode);
- vgaHWSaveFonts(pScrn, &pVBox->vgaRegs);
+void
+VBOXRestoreMode(ScrnInfoPtr pScrn)
+{
+ VBOXPtr pVBox = VBOXGetRec(pScrn);
+ vgaRegPtr vgaReg;
- if (!VBESaveRestore(pVBox->pVbe,function,(pointer)&pVBox->state,
- &pVBox->stateSize,&pVBox->statePage)
- )
- rc = FALSE;
- }
- }
- if (rc)
- {
- /* Save/Restore Super VGA state */
- if (function != MODE_QUERY) {
-
- if (function == MODE_RESTORE)
- memcpy(pVBox->state, pVBox->pstate,
- (unsigned) pVBox->stateSize);
-
- if ( (rc = VBESaveRestore(pVBox->pVbe,function,
- (pointer)&pVBox->state,
- &pVBox->stateSize,&pVBox->statePage)
- )
- && (function == MODE_SAVE)
- )
- {
- /* don't rely on the memory not being touched */
- if (pVBox->pstate == NULL)
- pVBox->pstate = malloc(pVBox->stateSize);
- memcpy(pVBox->pstate, pVBox->state,
- (unsigned) pVBox->stateSize);
- }
-
- if (function == MODE_RESTORE)
- {
- VBESetVBEMode(pVBox->pVbe, pVBox->stateMode, NULL);
- vgaHWRestoreFonts(pScrn, &pVBox->vgaRegs);
- }
- }
- }
- TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
- return rc;
+ TRACE_ENTRY();
+ vgaReg = &VGAHWPTR(pScrn)->SavedReg;
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+ if (pVBox->fSavedVBEMode)
+ VBoxVideoSetModeRegisters(pVBox->cSavedWidth, pVBox->cSavedHeight,
+ pVBox->cSavedPitch, pVBox->cSavedBPP,
+ pVBox->fSavedFlags, 0, 0);
+ else
+ VBoxVideoDisableVBE();
}
static void
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxvideo.h b/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
index ed4dca80c..bff0f882f 100644
--- a/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
+++ b/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
@@ -55,6 +55,8 @@
#include <VBox/VBoxVideoGuest.h>
#include <VBox/VBoxVideo.h>
+#include <iprt/asm-math.h>
+
#ifdef DEBUG
#define TRACE_ENTRY() \
@@ -116,11 +118,6 @@ if (!(expr)) \
# include "xf86Pci.h"
#endif
-#include "vgaHW.h"
-
-/* VBE/DDC support */
-#include "vbe.h"
-
/* ShadowFB support */
#include "shadowfb.h"
@@ -168,7 +165,6 @@ extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
typedef struct VBOXRec
{
- vbeInfoPtr pVbe; /** @todo do the VBE bits ourselves? */
EntityInfoPtr pEnt;
#ifdef PCIACCESS
struct pci_device *pciInfo;
@@ -184,11 +180,11 @@ typedef struct VBOXRec
unsigned long cbView;
/** The current line size in bytes */
uint32_t cbLine;
- CARD8 *state, *pstate; /* SVGA state */
- int statePage, stateSize, stateMode;
- CARD32 *savedPal;
- CARD8 *fonts;
- vgaRegRec vgaRegs; /* Space for saving VGA information */
+ /** Whether the pre-X-server mode was a VBE mode */
+ bool fSavedVBEMode;
+ /** Paramters of the saved pre-X-server VBE mode, invalid if there is none
+ */
+ uint16_t cSavedWidth, cSavedHeight, cSavedPitch, cSavedBPP, fSavedFlags;
CloseScreenProcPtr CloseScreen;
/** Default X server procedure for enabling and disabling framebuffer access */
xf86EnableDisableFBAccessProc *EnableDisableFBAccess;
@@ -277,5 +273,41 @@ extern void VBOXDRICloseScreen(ScreenPtr pScreen, VBOXPtr pVBox);
extern Bool VBOXEDIDSet(struct _xf86Output *output, DisplayModePtr pmode);
#endif
+/* Utilities */
+
+static inline VBOXPtr VBOXGetRec(ScrnInfoPtr pScrn)
+{
+ if (!pScrn->driverPrivate)
+ {
+ pScrn->driverPrivate = calloc(sizeof(VBOXRec), 1);
+ }
+
+ return ((VBOXPtr)pScrn->driverPrivate);
+}
+
+/** Calculate the BPP from the screen depth */
+static inline uint16_t vboxBPP(ScrnInfoPtr pScrn)
+{
+ return pScrn->depth == 24 ? 32 : 16;
+}
+
+/** Calculate the scan line length for a display width */
+static inline int32_t vboxLineLength(ScrnInfoPtr pScrn, int32_t cDisplayWidth)
+{
+ uint64_t cbLine = ((uint64_t)cDisplayWidth * vboxBPP(pScrn) / 8 + 3) & ~3;
+ return cbLine < INT32_MAX ? cbLine : INT32_MAX;
+}
+
+/** Calculate the display pitch from the scan line length */
+static inline int32_t vboxDisplayPitch(ScrnInfoPtr pScrn, int32_t cbLine)
+{
+ return ASMDivU64ByU32RetU32((uint64_t)cbLine * 8, vboxBPP(pScrn));
+}
+
+extern void vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY);
+extern Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
+ unsigned cHeight, int x, int y);
+extern Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height);
+
#endif /* _VBOXVIDEO_H_ */
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxvideo_70.c b/src/VBox/Additions/x11/vboxvideo/vboxvideo_70.c
deleted file mode 100644
index a32abcecf..000000000
--- a/src/VBox/Additions/x11/vboxvideo/vboxvideo_70.c
+++ /dev/null
@@ -1,1136 +0,0 @@
-/** @file
- *
- * Linux Additions X11 graphics driver
- */
-
-/*
- * Copyright (C) 2006-2007 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- * --------------------------------------------------------------------
- *
- * This code is based on:
- *
- * X11 VESA driver
- *
- * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * CONECTIVA LINUX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Conectiva Linux shall
- * not be used in advertising or otherwise to promote the sale, use or other
- * dealings in this Software without prior written authorization from
- * Conectiva Linux.
- *
- * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
- */
-
-#ifdef XORG_7X
-# include "xorg-server.h"
-# include <string.h>
-#endif
-#include "vboxvideo.h"
-#include "version-generated.h"
-#include "product-generated.h"
-#include <xf86.h>
-
-/* All drivers initialising the SW cursor need this */
-#include "mipointer.h"
-
-/* All drivers implementing backing store need this */
-#include "mibstore.h"
-
-/* Colormap handling */
-#include "micmap.h"
-#include "xf86cmap.h"
-
-/* DPMS */
-/* #define DPMS_SERVER
-#include "extensions/dpms.h" */
-
-/* VGA hardware functions for setting and restoring text mode */
-#include "vgaHW.h"
-
-/* Mandatory functions */
-
-static const OptionInfoRec * VBOXAvailableOptions(int chipid, int busid);
-static void VBOXIdentify(int flags);
-#ifndef PCIACCESS
-static Bool VBOXProbe(DriverPtr drv, int flags);
-#else
-static Bool VBOXPciProbe(DriverPtr drv, int entity_num,
- struct pci_device *dev, intptr_t match_data);
-#endif
-static Bool VBOXPreInit(ScrnInfoPtr pScrn, int flags);
-static Bool VBOXScreenInit(int Index, ScreenPtr pScreen, int argc,
- char **argv);
-static Bool VBOXEnterVT(int scrnIndex, int flags);
-static void VBOXLeaveVT(int scrnIndex, int flags);
-static Bool VBOXCloseScreen(int scrnIndex, ScreenPtr pScreen);
-static Bool VBOXSaveScreen(ScreenPtr pScreen, int mode);
-static Bool VBOXSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags);
-static Bool VBOXSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
-static void VBOXAdjustFrame(int scrnIndex, int x, int y, int flags);
-static void VBOXFreeScreen(int scrnIndex, int flags);
-static void VBOXFreeRec(ScrnInfoPtr pScrn);
-static void VBOXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode,
- int flags);
-
-/* locally used functions */
-static Bool VBOXMapVidMem(ScrnInfoPtr pScrn);
-static void VBOXUnmapVidMem(ScrnInfoPtr pScrn);
-static Bool VBOXSaveRestore(ScrnInfoPtr pScrn,
- vbeSaveRestoreFunction function);
-static bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, DisplayModePtr pMode);
-
-enum GenericTypes
-{
- CHIP_VBOX_GENERIC
-};
-
-#ifdef PCIACCESS
-static const struct pci_id_match vbox_device_match[] = {
- {
- VBOX_VENDORID, VBOX_DEVICEID, PCI_MATCH_ANY, PCI_MATCH_ANY,
- 0, 0, 0
- },
-
- { 0, 0, 0 },
-};
-#endif
-
-/*
- * This contains the functions needed by the server after loading the
- * driver module. It must be supplied, and gets added the driver list by
- * the Module Setup function in the dynamic case. In the static case a
- * reference to this is compiled in, and this requires that the name of
- * this DriverRec be an upper-case version of the driver name.
- */
-
-#ifdef XORG_7X
-_X_EXPORT
-#endif
-DriverRec VBOXVIDEO = {
- VBOX_VERSION,
- VBOX_DRIVER_NAME,
- VBOXIdentify,
-#ifdef PCIACCESS
- NULL,
-#else
- VBOXProbe,
-#endif
- VBOXAvailableOptions,
- NULL,
- 0,
-#ifdef XORG_7X
- NULL,
-#endif
-#ifdef PCIACCESS
- vbox_device_match,
- VBOXPciProbe
-#endif
-};
-
-/* Supported chipsets */
-static SymTabRec VBOXChipsets[] =
-{
- {VBOX_VESA_DEVICEID, "vbox"},
- {-1, NULL}
-};
-
-static PciChipsets VBOXPCIchipsets[] = {
- { VBOX_DEVICEID, VBOX_DEVICEID, RES_SHARED_VGA },
- { -1, -1, RES_UNDEFINED },
-};
-
-typedef enum {
- OPTION_SHADOW_FB,
- OPTION_DFLT_REFRESH,
- OPTION_MODESET_CLEAR_SCREEN
-} VBOXOpts;
-
-/* No options for now */
-static const OptionInfoRec VBOXOptions[] = {
- { -1, NULL, OPTV_NONE, {0}, FALSE }
-};
-
-/*
- * List of symbols from other modules that this module references. This
- * list is used to tell the loader that it is OK for symbols here to be
- * unresolved providing that it hasn't been told that they haven't been
- * told that they are essential via a call to xf86LoaderReqSymbols() or
- * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
- * unresolved symbols that are not required.
- */
-static const char *fbSymbols[] = {
- "fbPictureInit",
- "fbScreenInit",
- NULL
-};
-
-static const char *shadowfbSymbols[] = {
- "ShadowFBInit2",
- NULL
-};
-
-static const char *vbeSymbols[] = {
- "VBEExtendedInit",
- "VBEFindSupportedDepths",
- "VBEGetModeInfo",
- "VBEGetVBEInfo",
- "VBEGetVBEMode",
- "VBEPrintModes",
- "VBESaveRestore",
- "VBESetDisplayStart",
- "VBESetGetDACPaletteFormat",
- "VBESetGetLogicalScanlineLength",
- "VBESetGetPaletteData",
- "VBESetModeNames",
- "VBESetModeParameters",
- "VBESetVBEMode",
- "VBEValidateModes",
- "vbeDoEDID",
- "vbeFree",
- NULL
-};
-
-static const char *ramdacSymbols[] = {
- "xf86InitCursor",
- "xf86CreateCursorInfoRec",
- NULL
-};
-
-static const char *vgahwSymbols[] = {
- "vgaHWGetHWRec",
- "vgaHWHandleColormaps",
- "vgaHWFreeHWRec",
- "vgaHWMapMem",
- "vgaHWUnmapMem",
- "vgaHWSaveFonts",
- "vgaHWRestoreFonts",
- "vgaHWGetIndex",
- "vgaHWSaveScreen",
- "vgaHWDPMSSet",
- NULL
-};
-
-#ifdef XFree86LOADER
-/* Module loader interface */
-static MODULESETUPPROTO(vboxSetup);
-
-static XF86ModuleVersionInfo vboxVersionRec =
-{
- VBOX_DRIVER_NAME,
- VBOX_VENDOR,
- MODINFOSTRING1,
- MODINFOSTRING2,
-#ifdef XORG_7X
- XORG_VERSION_CURRENT,
-#else
- XF86_VERSION_CURRENT,
-#endif
- 1, /* Module major version. Xorg-specific */
- 0, /* Module minor version. Xorg-specific */
- 1, /* Module patchlevel. Xorg-specific */
- ABI_CLASS_VIDEODRV, /* This is a video driver */
- ABI_VIDEODRV_VERSION,
- MOD_CLASS_VIDEODRV,
- {0, 0, 0, 0}
-};
-
-/*
- * This data is accessed by the loader. The name must be the module name
- * followed by "ModuleData".
- */
-#ifdef XORG_7X
-_X_EXPORT
-#endif
-XF86ModuleData vboxvideoModuleData = { &vboxVersionRec, vboxSetup, NULL };
-
-static pointer
-vboxSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor)
-{
- static Bool Initialised = FALSE;
-
- if (!Initialised)
- {
- Initialised = TRUE;
-#ifdef PCIACCESS
- xf86AddDriver(&VBOXVIDEO, Module, HaveDriverFuncs);
-#else
- xf86AddDriver(&VBOXVIDEO, Module, 0);
-#endif
-#ifndef XORG_7X
- LoaderRefSymLists(fbSymbols,
- shadowfbSymbols,
- vbeSymbols,
- ramdacSymbols,
- vgahwSymbols,
- NULL);
-#endif
- xf86Msg(X_CONFIG, "Load address of symbol \"VBOXVIDEO\" is %p\n",
- (void *)&VBOXVIDEO);
- return (pointer)TRUE;
- }
-
- if (ErrorMajor)
- *ErrorMajor = LDR_ONCEONLY;
- return (NULL);
-}
-
-#endif /* XFree86Loader defined */
-
-static const OptionInfoRec *
-VBOXAvailableOptions(int chipid, int busid)
-{
- return (VBOXOptions);
-}
-
-static void
-VBOXIdentify(int flags)
-{
- xf86PrintChipsets(VBOX_NAME, "guest driver for VirtualBox", VBOXChipsets);
-}
-
-static VBOXPtr
-VBOXGetRec(ScrnInfoPtr pScrn)
-{
- if (!pScrn->driverPrivate)
- {
- pScrn->driverPrivate = xcalloc(sizeof(VBOXRec), 1);
-#if 0
- ((VBOXPtr)pScrn->driverPrivate)->vbox_fd = -1;
-#endif
- }
-
- return ((VBOXPtr)pScrn->driverPrivate);
-}
-
-static void
-VBOXFreeRec(ScrnInfoPtr pScrn)
-{
- VBOXPtr pVBox = VBOXGetRec(pScrn);
- xfree(pVBox->savedPal);
- xfree(pVBox->fonts);
- xfree(pScrn->driverPrivate);
- pScrn->driverPrivate = NULL;
-}
-
-/*
- * This function is called once, at the start of the first server generation to
- * do a minimal probe for supported hardware.
- */
-
-#ifdef PCIACCESS
-static Bool
-VBOXPciProbe(DriverPtr drv, int entity_num, struct pci_device *dev,
- intptr_t match_data)
-{
- ScrnInfoPtr pScrn;
-
- TRACE_ENTRY();
- pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, VBOXPCIchipsets,
- NULL, NULL, NULL, NULL, NULL);
- if (pScrn != NULL) {
- VBOXPtr pVBox = VBOXGetRec(pScrn);
-
- pScrn->driverVersion = VBOX_VERSION;
- pScrn->driverName = VBOX_DRIVER_NAME;
- pScrn->name = VBOX_NAME;
- pScrn->Probe = NULL;
- pScrn->PreInit = VBOXPreInit;
- pScrn->ScreenInit = VBOXScreenInit;
- pScrn->SwitchMode = VBOXSwitchMode;
- /* pScrn->ValidMode = VBOXValidMode; */
- pScrn->AdjustFrame = VBOXAdjustFrame;
- pScrn->EnterVT = VBOXEnterVT;
- pScrn->LeaveVT = VBOXLeaveVT;
- pScrn->FreeScreen = VBOXFreeScreen;
-
- pVBox->pciInfo = dev;
- }
-
- TRACE_LOG("returning %s\n", BOOL_STR(pScrn != NULL));
- return (pScrn != NULL);
-}
-#else /* !PCIACCESS */
-static Bool
-VBOXProbe(DriverPtr drv, int flags)
-{
- Bool foundScreen = FALSE;
- int numDevSections, numUsed;
- GDevPtr *devSections;
- int *usedChips;
- int i;
-
- /*
- * Find the config file Device sections that match this
- * driver, and return if there are none.
- */
- if ((numDevSections = xf86MatchDevice(VBOX_NAME,
- &devSections)) <= 0)
- return (FALSE);
-
- /* PCI BUS */
- if (xf86GetPciVideoInfo()) {
- numUsed = xf86MatchPciInstances(VBOX_NAME, VBOX_VENDORID,
- VBOXChipsets, VBOXPCIchipsets,
- devSections, numDevSections,
- drv, &usedChips);
- if (numUsed > 0) {
- if (flags & PROBE_DETECT)
- foundScreen = TRUE;
- else {
- for (i = 0; i < numUsed; i++) {
- ScrnInfoPtr pScrn = NULL;
- /* Allocate a ScrnInfoRec */
- if ((pScrn = xf86ConfigPciEntity(pScrn,0,usedChips[i],
- VBOXPCIchipsets,NULL,
- NULL,NULL,NULL,NULL))) {
- pScrn->driverVersion = VBOX_VERSION;
- pScrn->driverName = VBOX_DRIVER_NAME;
- pScrn->name = VBOX_NAME;
- pScrn->Probe = VBOXProbe;
- pScrn->PreInit = VBOXPreInit;
- pScrn->ScreenInit = VBOXScreenInit;
- pScrn->SwitchMode = VBOXSwitchMode;
- pScrn->AdjustFrame = VBOXAdjustFrame;
- pScrn->EnterVT = VBOXEnterVT;
- pScrn->LeaveVT = VBOXLeaveVT;
- pScrn->FreeScreen = VBOXFreeScreen;
- foundScreen = TRUE;
- }
- }
- }
- xfree(usedChips);
- }
- }
- xfree(devSections);
-
- return (foundScreen);
-}
-#endif /* !PCIACCESS */
-
-/**
- * This function hooks into the chain that is called when framebuffer access
- * is allowed or disallowed by a call to EnableDisableFBAccess in the server.
- * In other words, it observes when the server wishes access to the
- * framebuffer to be enabled and when it should be disabled. We need to know
- * this because we disable access ourselves during mode switches (presumably
- * the server should do this but it doesn't) and want to know whether to
- * restore it or not afterwards.
- */
-static void
-vboxEnableDisableFBAccess(int scrnIndex, Bool enable)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- VBOXPtr pVBox = VBOXGetRec(pScrn);
-
- pVBox->accessEnabled = enable;
- pVBox->EnableDisableFBAccess(scrnIndex, enable);
-}
-
-/*
- * QUOTE from the XFree86 DESIGN document:
- *
- * The purpose of this function is to find out all the information
- * required to determine if the configuration is usable, and to initialise
- * those parts of the ScrnInfoRec that can be set once at the beginning of
- * the first server generation.
- *
- * (...)
- *
- * This includes probing for video memory, clocks, ramdac, and all other
- * HW info that is needed. It includes determining the depth/bpp/visual
- * and related info. It includes validating and determining the set of
- * video modes that will be used (and anything that is required to
- * determine that).
- *
- * This information should be determined in the least intrusive way
- * possible. The state of the HW must remain unchanged by this function.
- * Although video memory (including MMIO) may be mapped within this
- * function, it must be unmapped before returning.
- *
- * END QUOTE
- */
-
-static Bool
-VBOXPreInit(ScrnInfoPtr pScrn, int flags)
-{
- VBOXPtr pVBox;
- Gamma gzeros = {0.0, 0.0, 0.0};
- rgb rzeros = {0, 0, 0};
- int i;
- unsigned DispiId;
- DisplayModePtr pMode;
- enum { MODE_MIN_SIZE = 64 };
-
- TRACE_ENTRY();
- /* Are we really starting the server, or is this just a dummy run? */
- if (flags & PROBE_DETECT)
- return (FALSE);
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "VirtualBox guest additions video driver version "
- VBOX_VERSION_STRING "\n");
-
- /* Get our private data from the ScrnInfoRec structure. */
- pVBox = VBOXGetRec(pScrn);
-
- /* Initialise the guest library */
- vbox_init(pScrn->scrnIndex, pVBox);
-
- /* Entity information seems to mean bus information. */
- pVBox->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
-
- /* The ramdac module is needed for the hardware cursor. */
- if (!xf86LoadSubModule(pScrn, "ramdac"))
- return FALSE;
-
- /* We need the vbe module because we use VBE code to save and restore
- text mode, in order to keep our code simple. */
- if (!xf86LoadSubModule(pScrn, "vbe"))
- return (FALSE);
-
- /* The framebuffer module. */
- if (xf86LoadSubModule(pScrn, "fb") == NULL)
- return (FALSE);
-
- if (!xf86LoadSubModule(pScrn, "shadowfb"))
- return FALSE;
-
- if (!xf86LoadSubModule(pScrn, "vgahw"))
- return FALSE;
-
-#ifdef VBOX_DRI
- /* Load the dri module. */
- if (!xf86LoadSubModule(pScrn, "dri"))
- return FALSE;
-#endif
-
-#ifndef PCIACCESS
- if (pVBox->pEnt->location.type != BUS_PCI)
- return FALSE;
-
- pVBox->pciInfo = xf86GetPciInfoForEntity(pVBox->pEnt->index);
- pVBox->pciTag = pciTag(pVBox->pciInfo->bus,
- pVBox->pciInfo->device,
- pVBox->pciInfo->func);
-#endif
-
- /* Set up our ScrnInfoRec structure to describe our virtual
- capabilities to X. */
-
- pScrn->rgbBits = 8;
-
- /* Let's create a nice, capable virtual monitor. */
- pScrn->monitor = pScrn->confScreen->monitor;
- pScrn->monitor->DDC = NULL;
- pScrn->monitor->nHsync = 1;
- pScrn->monitor->hsync[0].lo = 1;
- pScrn->monitor->hsync[0].hi = 10000;
- pScrn->monitor->nVrefresh = 1;
- pScrn->monitor->vrefresh[0].lo = 1;
- pScrn->monitor->vrefresh[0].hi = 100;
-
- pScrn->chipset = "vbox";
- pScrn->progClock = TRUE;
-
- /* Determine the size of the VBox video RAM from PCI data*/
-#if 0
- pScrn->videoRam = 1 << pVBox->pciInfo->size[0];
-#endif
- /* Using the PCI information caused problems with non-powers-of-two
- sized video RAM configurations */
- pScrn->videoRam = inl(VBE_DISPI_IOPORT_DATA) / 1024;
-
- /* Check if the chip restricts horizontal resolution or not. */
- outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
- outw(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_ANYX);
- DispiId = inw(VBE_DISPI_IOPORT_DATA);
- if (DispiId == VBE_DISPI_ID_ANYX)
- pVBox->fAnyX = TRUE;
- else
- pVBox->fAnyX = FALSE;
-
- /* Set up clock information that will support all modes we need. */
- pScrn->clockRanges = xnfcalloc(sizeof(ClockRange), 1);
- pScrn->clockRanges->minClock = 1000;
- pScrn->clockRanges->maxClock = 1000000000;
- pScrn->clockRanges->clockIndex = -1;
- pScrn->clockRanges->ClockMulFactor = 1;
- pScrn->clockRanges->ClockDivFactor = 1;
-
- /* Determine the preferred size and colour depth and setup video modes */
- {
- uint32_t cx = 0, cy = 0, cBits = 0;
-
- vboxGetPreferredMode(pScrn, &cx, &cy, &cBits);
- /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */
- if (cBits != 16)
- cBits = 24;
- if (!xf86SetDepthBpp(pScrn, cBits, 0, 0, Support32bppFb))
- return FALSE;
- vboxAddModes(pScrn, cx, cy);
- }
- if (pScrn->bitsPerPixel != 32 && pScrn->bitsPerPixel != 16)
- {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "The VBox additions only support 16 and 32bpp graphics modes\n");
- return FALSE;
- }
- xf86PrintDepthBpp(pScrn);
-
- /* Colour weight - we always call this, since we are always in
- truecolour. */
- if (!xf86SetWeight(pScrn, rzeros, rzeros))
- return (FALSE);
-
- /* visual init */
- if (!xf86SetDefaultVisual(pScrn, -1))
- return (FALSE);
-
- xf86SetGamma(pScrn, gzeros);
-
- /* We don't validate with xf86ValidateModes and xf86PruneModes as we
- * already know what we like and what we don't. */
-
- pScrn->currentMode = pScrn->modes;
-
- /* Set the right virtual resolution. */
- pScrn->virtualX = pScrn->currentMode->HDisplay;
- pScrn->virtualY = pScrn->currentMode->VDisplay;
-
- pScrn->displayWidth = pScrn->virtualX;
-
- xf86PrintModes(pScrn);
-
- /* Set the DPI. Perhaps we should read this from the host? */
- xf86SetDpi(pScrn, 96, 96);
-
- /* options */
- xf86CollectOptions(pScrn, NULL);
- if (!(pVBox->Options = xalloc(sizeof(VBOXOptions))))
- return FALSE;
- memcpy(pVBox->Options, VBOXOptions, sizeof(VBOXOptions));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pVBox->Options);
-
- /* Framebuffer-related setup */
- pScrn->bitmapBitOrder = BITMAP_BIT_ORDER;
-
- /* VGA hardware initialisation */
- if (!vgaHWGetHWRec(pScrn))
- return FALSE;
-
- TRACE_EXIT();
- return (TRUE);
-}
-
-/*
- * QUOTE from the XFree86 DESIGN document:
- *
- * This is called at the start of each server generation.
- *
- * (...)
- *
- * Decide which operations need to be placed under resource access
- * control. (...) Map any video memory or other memory regions. (...)
- * Save the video card state. (...) Initialise the initial video
- * mode.
- *
- * End QUOTE.
- */
-static Bool
-VBOXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- VBOXPtr pVBox = VBOXGetRec(pScrn);
- VisualPtr visual;
- unsigned flags;
-
- TRACE_ENTRY();
- /* We make use of the X11 VBE code to save and restore text mode, in
- order to keep our code simple. */
- if ((pVBox->pVbe = VBEExtendedInit(NULL, pVBox->pEnt->index,
- SET_BIOS_SCRATCH
- | RESTORE_BIOS_SCRATCH)) == NULL)
- return (FALSE);
-
- if (pScrn->memPhysBase == 0) {
-#ifdef PCIACCESS
- pScrn->memPhysBase = pVBox->pciInfo->regions[0].base_addr;
-#else
- pScrn->memPhysBase = pVBox->pciInfo->memBase[0];
-#endif
-/* pVBox->mapSize = 1 << pVBox->pciInfo->size[0]; */
- /* Using the PCI information caused problems with
- non-powers-of-two sized video RAM configurations */
- pVBox->mapSize = inl(VBE_DISPI_IOPORT_DATA);
- pScrn->fbOffset = 0;
- }
-
- if (!VBOXMapVidMem(pScrn))
- return (FALSE);
-
- /* save current video state */
- VBOXSaveRestore(pScrn, MODE_SAVE);
- pVBox->savedPal = VBESetGetPaletteData(pVBox->pVbe, FALSE, 0, 256,
- NULL, FALSE, FALSE);
-
- /* set the viewport */
- VBOXAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
- /* Blank the screen for aesthetic reasons. */
- VBOXSaveScreen(pScreen, SCREEN_SAVER_ON);
-
- /* mi layer - reset the visual list (?)*/
- miClearVisualTypes();
- if (!xf86SetDefaultVisual(pScrn, -1))
- return (FALSE);
- if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
- pScrn->rgbBits, TrueColor))
- return (FALSE);
- if (!miSetPixmapDepths())
- return (FALSE);
-
- /* Needed before we initialise DRI. */
- pScrn->virtualX = (pScrn->virtualX + 7) & ~7;
- pScrn->displayWidth = pScrn->virtualX;
-
-#ifdef VBOX_DRI
- pVBox->useDRI = VBOXDRIScreenInit(scrnIndex, pScreen, pVBox);
-#endif
-
- /* I checked in the sources, and XFree86 4.2 does seem to support
- this function for 32bpp. */
- if (!fbScreenInit(pScreen, pVBox->base,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi,
- pScrn->displayWidth, pScrn->bitsPerPixel))
- return (FALSE);
-
- /* Fixup RGB ordering */
- visual = pScreen->visuals + pScreen->numVisuals;
- while (--visual >= pScreen->visuals) {
- if ((visual->class | DynamicClass) == DirectColor) {
- visual->offsetRed = pScrn->offset.red;
- visual->offsetGreen = pScrn->offset.green;
- visual->offsetBlue = pScrn->offset.blue;
- visual->redMask = pScrn->mask.red;
- visual->greenMask = pScrn->mask.green;
- visual->blueMask = pScrn->mask.blue;
- }
- }
-
- /* must be after RGB ordering fixed */
- fbPictureInit(pScreen, 0, 0);
-
- xf86SetBlackWhitePixels(pScreen);
- miInitializeBackingStore(pScreen);
- xf86SetBackingStore(pScreen);
-
- /* We need to keep track of whether we are currently switched to a virtual
- * terminal to know whether a mode set operation is currently safe to do.
- */
- pVBox->vtSwitch = FALSE;
- /* software cursor */
- miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
-
- /* colourmap code - apparently, we need this even in Truecolour */
- if (!miCreateDefColormap(pScreen))
- return (FALSE);
-
- flags = CMAP_RELOAD_ON_MODE_SWITCH;
-
- if(!vgaHWHandleColormaps(pScreen))
- return (FALSE);
-
- /* Hook our observer function ito the chain which is called when
- * framebuffer access is enabled or disabled in the server, and
- * assume an initial state of enabled. */
- pVBox->accessEnabled = TRUE;
- pVBox->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
- pScrn->EnableDisableFBAccess = vboxEnableDisableFBAccess;
-
- pVBox->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = VBOXCloseScreen;
- pScreen->SaveScreen = VBOXSaveScreen;
-
- xf86DPMSInit(pScreen, VBOXDisplayPowerManagementSet, 0);
-
- /* Report any unused options (only for the first generation) */
- if (serverGeneration == 1)
- xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
-
- /* set first video mode */
- if (!VBOXSetMode(pScrn, pScrn->currentMode))
- return FALSE;
- /* And make sure that a non-current dynamic mode is at the front of the
- * list */
- vboxWriteHostModes(pScrn, pScrn->currentMode);
-
- if (vbox_open (pScrn, pScreen, pVBox)) {
- if (vbox_cursor_init(pScreen) != TRUE)
- xf86DrvMsg(scrnIndex, X_ERROR,
- "Unable to start the VirtualBox mouse pointer integration with the host system.\n");
- if (vboxEnableVbva(pScrn) == TRUE)
- xf86DrvMsg(scrnIndex, X_INFO,
- "The VBox video extensions are now enabled.\n");
- vboxEnableGraphicsCap(pVBox);
- }
-
-#ifdef VBOX_DRI
- if (pVBox->useDRI)
- pVBox->useDRI = VBOXDRIFinishScreenInit(pScreen);
-#endif
- TRACE_EXIT();
- return (TRUE);
-}
-
-static Bool
-VBOXEnterVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- VBOXPtr pVBox = VBOXGetRec(pScrn);
-
- TRACE_ENTRY();
- pVBox->vtSwitch = FALSE;
-#ifdef VBOX_DRI
- if (pVBox->useDRI)
- DRIUnlock(screenInfo.screens[scrnIndex]);
-#endif
- if (!VBOXSetMode(pScrn, pScrn->currentMode))
- return FALSE;
- VBOXAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
- if (pVBox->useVbva == TRUE)
- vboxEnableVbva(pScrn);
- return TRUE;
-}
-
-static void
-VBOXLeaveVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- VBOXPtr pVBox = VBOXGetRec(pScrn);
-
- TRACE_ENTRY();
- VBOXSaveRestore(pScrn, MODE_RESTORE);
- if (pVBox->useVbva == TRUE)
- vboxDisableVbva(pScrn);
- vboxDisableGraphicsCap(pVBox);
- pVBox->vtSwitch = TRUE;
-#ifdef VBOX_DRI
- if (pVBox->useDRI)
- DRILock(screenInfo.screens[scrnIndex], 0);
-#endif
-}
-
-static Bool
-VBOXCloseScreen(int scrnIndex, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- VBOXPtr pVBox = VBOXGetRec(pScrn);
-
-#ifdef VBOX_DRI
- if (pVBox->useDRI)
- VBOXDRICloseScreen(pScreen, pVBox);
- pVBox->useDRI = false;
-#endif
-
- if (pVBox->useVbva == TRUE)
- vboxDisableVbva(pScrn);
- vboxDisableGraphicsCap(pVBox);
- if (pScrn->vtSema) {
- VBOXSaveRestore(xf86Screens[scrnIndex], MODE_RESTORE);
- if (pVBox->savedPal)
- VBESetGetPaletteData(pVBox->pVbe, TRUE, 0, 256,
- pVBox->savedPal, FALSE, TRUE);
- VBOXUnmapVidMem(pScrn);
- }
- pScrn->vtSema = FALSE;
-
- /* Destroy the VGA hardware record */
- vgaHWFreeHWRec(pScrn);
-
- /* And do additional bits which are separate for historical reasons */
- vbox_close(pScrn, pVBox);
-
- pScreen->CloseScreen = pVBox->CloseScreen;
- return pScreen->CloseScreen(scrnIndex, pScreen);
-}
-
-static Bool
-VBOXSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags)
-{
- ScrnInfoPtr pScrn;
- VBOXPtr pVBox;
- Bool rc = TRUE;
-
- pScrn = xf86Screens[scrnIndex]; /* Why does X have three ways of referring to the screen? */
- pVBox = VBOXGetRec(pScrn);
- if (pVBox->useVbva)
- if (!vboxDisableVbva(pScrn)) /* This would be bad. */
- rc = FALSE;
- /* We want to disable access to the framebuffer before switching mode.
- * After doing the switch, we allow access if it was allowed before. */
- if (pVBox->accessEnabled)
- pVBox->EnableDisableFBAccess(scrnIndex, FALSE);
- if (rc && !VBOXSetMode(pScrn, pMode))
- rc = FALSE;
- if (rc && !VBOXAdjustScreenPixmap(pScrn, pMode))
- rc = FALSE;
- if (rc && !vboxGuestIsSeamless(pScrn))
- vboxSaveVideoMode(pScrn, pMode->HDisplay, pMode->VDisplay,
- pScrn->bitsPerPixel);
- if (rc)
- {
- vboxWriteHostModes(pScrn, pMode);
- xf86PrintModes(pScrn);
- }
- if (pVBox->accessEnabled)
- pVBox->EnableDisableFBAccess(scrnIndex, TRUE);
- if (pVBox->useVbva)
- if (!vboxEnableVbva(pScrn)) /* Bad but not fatal */
- pVBox->useVbva = FALSE;
- return rc;
-}
-
-/* Set a graphics mode */
-static Bool
-VBOXSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
-{
- TRACE_ENTRY();
- int bpp = pScrn->depth == 24 ? 32 : 16;
- VBOXPtr pVBox = VBOXGetRec(pScrn);
-
- /* Don't fiddle with the hardware if we are switched
- * to a virtual terminal. */
- if (pVBox->vtSwitch == TRUE)
- return TRUE;
- if (pScrn->virtualX * pScrn->virtualY * bpp / 8
- >= pScrn->videoRam * 1024)
- {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Unable to set up a virtual screen size of %dx%d with %d Kb of video memory. Please increase the video memory size.\n",
- pScrn->virtualX, pScrn->virtualY, pScrn->videoRam);
- return FALSE;
- }
-
- pScrn->vtSema = TRUE;
- /* Disable linear framebuffer mode before making changes to the resolution. */
- outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
- outw(VBE_DISPI_IOPORT_DATA,
- VBE_DISPI_DISABLED);
- /* Unlike the resolution, the depth is fixed for a given screen
- for the lifetime of the X session. */
- outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
- outw(VBE_DISPI_IOPORT_DATA, bpp);
- /* HDisplay and VDisplay are actually monitor information about
- the display part of the scanlines. */
- outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
- outw(VBE_DISPI_IOPORT_DATA, pMode->HDisplay);
- outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
- outw(VBE_DISPI_IOPORT_DATA, pMode->VDisplay);
- /* Enable linear framebuffer mode. */
- outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
- outw(VBE_DISPI_IOPORT_DATA,
- VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
- /* Set the virtual resolution. We are still using VESA to control
- the virtual offset. */
- outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIRT_WIDTH);
- outw(VBE_DISPI_IOPORT_DATA, pMode->HDisplay);
- vboxEnableGraphicsCap(pVBox);
- TRACE_EXIT();
- return (TRUE);
-}
-
-static bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, DisplayModePtr pMode)
-{
- ScreenPtr pScreen = pScrn->pScreen;
- PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen);
- VBOXPtr pVBox = VBOXGetRec(pScrn);
- int bpp = pScrn->depth == 24 ? 32 : 16;
- if (!pPixmap) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to get the screen pixmap.\n");
- return FALSE;
- }
- pScreen->ModifyPixmapHeader(pPixmap, pMode->HDisplay, pMode->VDisplay,
- pScrn->depth, bpp, pMode->HDisplay * bpp / 8,
- pVBox->base);
-#ifdef VBOX_DRI
- if (pVBox->useDRI)
- VBOXDRIUpdateStride(pScrn, pVBox);
-#endif
- pScrn->EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
- pScrn->EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
- return TRUE;
-}
-
-static void
-VBOXAdjustFrame(int scrnIndex, int x, int y, int flags)
-{
- VBOXPtr pVBox = VBOXGetRec(xf86Screens[scrnIndex]);
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
- /* Don't fiddle with the hardware if we are switched
- * to a virtual terminal. */
- if (pVBox->vtSwitch == TRUE)
- return;
- pVBox->viewportX = x;
- pVBox->viewportY = y;
- /* If VBVA is enabled the graphics card will not notice the change. */
- if (pVBox->useVbva == TRUE)
- vboxDisableVbva(pScrn);
- VBESetDisplayStart(pVBox->pVbe, x, y, TRUE);
- if (pVBox->useVbva == TRUE)
- vboxEnableVbva(pScrn);
-}
-
-static void
-VBOXFreeScreen(int scrnIndex, int flags)
-{
- VBOXFreeRec(xf86Screens[scrnIndex]);
-}
-
-static Bool
-VBOXMapVidMem(ScrnInfoPtr pScrn)
-{
- VBOXPtr pVBox = VBOXGetRec(pScrn);
-
- if (pVBox->base != NULL)
- return (TRUE);
-
-#ifdef PCIACCESS
- (void) pci_device_map_range(pVBox->pciInfo,
- pScrn->memPhysBase,
- pVBox->mapSize,
- PCI_DEV_MAP_FLAG_WRITABLE,
- & pVBox->base);
-#else
- pVBox->base = xf86MapPciMem(pScrn->scrnIndex,
- VIDMEM_FRAMEBUFFER,
- pVBox->pciTag, pScrn->memPhysBase,
- (unsigned) pVBox->mapSize);
-#endif
- if (pVBox->base)
- {
- /* We need this for saving/restoring textmode */
- VGAHWPTR(pScrn)->IOBase = pScrn->domainIOBase;
- return vgaHWMapMem(pScrn);
- }
- else
- return FALSE;
-}
-
-static void
-VBOXUnmapVidMem(ScrnInfoPtr pScrn)
-{
- VBOXPtr pVBox = VBOXGetRec(pScrn);
-
- if (pVBox->base == NULL)
- return;
-
-#ifdef PCIACCESS
- (void) pci_device_unmap_range(pVBox->pciInfo,
- pVBox->base,
- pVBox->mapSize);
-#else
- xf86UnMapVidMem(pScrn->scrnIndex, pVBox->base,
- (unsigned) pVBox->mapSize);
-#endif
- vgaHWUnmapMem(pScrn);
- pVBox->base = NULL;
-}
-
-static Bool
-VBOXSaveScreen(ScreenPtr pScreen, int mode)
-{
- return vgaHWSaveScreen(pScreen, mode);
-}
-
-Bool
-VBOXSaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function)
-{
- VBOXPtr pVBox;
-
- if (MODE_QUERY < 0 || function > MODE_RESTORE)
- return (FALSE);
-
- pVBox = VBOXGetRec(pScrn);
-
- /* Query amount of memory to save state */
- if (function == MODE_QUERY ||
- (function == MODE_SAVE && pVBox->state == NULL))
- {
- /* Make sure we save at least this information in case of failure */
- (void)VBEGetVBEMode(pVBox->pVbe, &pVBox->stateMode);
- vgaHWSaveFonts(pScrn, &pVBox->vgaRegs);
-
- if (!VBESaveRestore(pVBox->pVbe,function,(pointer)&pVBox->state,
- &pVBox->stateSize,&pVBox->statePage))
- return FALSE;
- }
-
- /* Save/Restore Super VGA state */
- if (function != MODE_QUERY) {
- Bool retval = TRUE;
-
- if (function == MODE_RESTORE)
- memcpy(pVBox->state, pVBox->pstate,
- (unsigned) pVBox->stateSize);
-
- if ((retval = VBESaveRestore(pVBox->pVbe,function,
- (pointer)&pVBox->state,
- &pVBox->stateSize,&pVBox->statePage))
- && function == MODE_SAVE)
- {
- /* don't rely on the memory not being touched */
- if (pVBox->pstate == NULL)
- pVBox->pstate = xalloc(pVBox->stateSize);
- memcpy(pVBox->pstate, pVBox->state,
- (unsigned) pVBox->stateSize);
- }
-
- if (function == MODE_RESTORE)
- {
- VBESetVBEMode(pVBox->pVbe, pVBox->stateMode, NULL);
- vgaHWRestoreFonts(pScrn, &pVBox->vgaRegs);
- }
-
- if (!retval)
- return (FALSE);
-
- }
-
- return (TRUE);
-}
-
-static void
-VBOXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode,
- int flags)
-{
- vgaHWDPMSSet(pScrn, mode, flags);
-}
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c b/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c
index ab9324ed3..644275933 100644
--- a/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c
+++ b/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c
@@ -1,4 +1,4 @@
-/** @file $Id: vboxvideo_dri.c $
+/** @file $Id: vboxvideo_dri.c 35268 2010-12-20 23:30:58Z vboxsync $
*
* VirtualBox X11 Additions graphics driver, DRI support
*/
diff --git a/src/VBox/Additions/x11/vboxvideo/vbva.c b/src/VBox/Additions/x11/vboxvideo/vbva.c
new file mode 100644
index 000000000..b48550d74
--- /dev/null
+++ b/src/VBox/Additions/x11/vboxvideo/vbva.c
@@ -0,0 +1,269 @@
+/** @file
+ * VirtualBox X11 Additions graphics driver 2D acceleration functions
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuestLib.h>
+
+#ifndef PCIACCESS
+# include <xf86Pci.h>
+# include <Pci.h>
+#endif
+
+#include "xf86.h"
+#define NEED_XF86_TYPES
+#include <iprt/string.h>
+#include "compiler.h"
+
+#include "vboxvideo.h"
+
+/**************************************************************************
+* Main functions *
+**************************************************************************/
+
+/**
+ * Callback function called by the X server to tell us about dirty
+ * rectangles in the video buffer.
+ *
+ * @param pScreen pointer to the information structure for the current
+ * screen
+ * @param iRects Number of dirty rectangles to update
+ * @param aRects Array of structures containing the coordinates of the
+ * rectangles
+ */
+static void
+vboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
+{
+ VBVACMDHDR cmdHdr;
+ VBOXPtr pVBox;
+ int i;
+ unsigned j;
+
+ pVBox = pScrn->driverPrivate;
+ if (pVBox->fHaveHGSMI == FALSE || pVBox->vtSwitch)
+ return;
+
+ for (i = 0; i < iRects; ++i)
+ for (j = 0; j < pVBox->cScreens; ++j)
+ {
+ /* Just continue quietly if VBVA is not currently active. */
+ struct VBVABUFFER *pVBVA = pVBox->aVbvaCtx[j].pVBVA;
+ if ( !pVBVA
+ || !(pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
+ continue;
+ if ( aRects[i].x1 > pVBox->aScreenLocation[j].x
+ + pVBox->aScreenLocation[j].cx
+ || aRects[i].y1 > pVBox->aScreenLocation[j].y
+ + pVBox->aScreenLocation[j].cy
+ || aRects[i].x2 < pVBox->aScreenLocation[j].x
+ || aRects[i].y2 < pVBox->aScreenLocation[j].y)
+ continue;
+ cmdHdr.x = (int16_t)aRects[i].x1;
+ cmdHdr.y = (int16_t)aRects[i].y1;
+ cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
+ cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
+
+#if 0
+ TRACE_LOG("display=%u, x=%d, y=%d, w=%d, h=%d\n",
+ j, cmdHdr.x, cmdHdr.y, cmdHdr.w, cmdHdr.h);
+#endif
+
+ if (VBoxVBVABufferBeginUpdate(&pVBox->aVbvaCtx[j],
+ &pVBox->guestCtx))
+ {
+ VBoxVBVAWrite(&pVBox->aVbvaCtx[j], &pVBox->guestCtx, &cmdHdr,
+ sizeof(cmdHdr));
+ VBoxVBVABufferEndUpdate(&pVBox->aVbvaCtx[j]);
+ }
+ }
+}
+
+/** Callback to fill in the view structures */
+static int
+vboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews)
+{
+ VBOXPtr pVBox = (VBOXPtr)pvVBox;
+ unsigned i;
+ for (i = 0; i < cViews; ++i)
+ {
+ pViews[i].u32ViewIndex = i;
+ pViews[i].u32ViewOffset = 0;
+ pViews[i].u32ViewSize = pVBox->cbView;
+ pViews[i].u32MaxScreenSize = pVBox->cbFBMax;
+ }
+ return VINF_SUCCESS;
+}
+
+/**
+ * Initialise VirtualBox's accelerated video extensions.
+ *
+ * @returns TRUE on success, FALSE on failure
+ */
+static Bool
+vboxInitVbva(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ int rc = VINF_SUCCESS;
+
+ pVBox->cScreens = 1;
+ if (!VBoxHGSMIIsSupported())
+ {
+ xf86DrvMsg(scrnIndex, X_ERROR, "The graphics device does not seem to support HGSMI. Disableing video acceleration.\n");
+ return FALSE;
+ }
+
+ /* Set up the dirty rectangle handler. It will be added into a function
+ * chain and gets removed when the screen is cleaned up. */
+ if (ShadowFBInit2(pScreen, NULL, vboxHandleDirtyRect) != TRUE)
+ {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Unable to install dirty rectangle handler for VirtualBox graphics acceleration.\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Initialise VirtualBox's accelerated video extensions.
+ *
+ * @returns TRUE on success, FALSE on failure
+ */
+static Bool
+vboxSetupVRAMVbva(ScrnInfoPtr pScrn, VBOXPtr pVBox)
+{
+ int rc = VINF_SUCCESS;
+ unsigned i;
+ uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory;
+ void *pvGuestHeapMemory;
+
+ if (!pVBox->fHaveHGSMI)
+ return FALSE;
+ VBoxHGSMIGetBaseMappingInfo(pScrn->videoRam * 1024, &offVRAMBaseMapping,
+ NULL, &offGuestHeapMemory, &cbGuestHeapMemory,
+ NULL);
+ pvGuestHeapMemory = ((uint8_t *)pVBox->base) + offVRAMBaseMapping
+ + offGuestHeapMemory;
+ TRACE_LOG("video RAM: %u KB, guest heap offset: 0x%x, cbGuestHeapMemory: %u\n",
+ pScrn->videoRam, offVRAMBaseMapping + offGuestHeapMemory,
+ cbGuestHeapMemory);
+ rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory,
+ cbGuestHeapMemory,
+ offVRAMBaseMapping + offGuestHeapMemory);
+ if (RT_FAILURE(rc))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up the guest-to-host communication context, rc=%d\n", rc);
+ return FALSE;
+ }
+ pVBox->cbView = pVBox->cbFBMax = offVRAMBaseMapping;
+ pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n",
+ pVBox->cScreens);
+ for (i = 0; i < pVBox->cScreens; ++i)
+ {
+ pVBox->cbFBMax -= VBVA_MIN_BUFFER_SIZE;
+ pVBox->aoffVBVABuffer[i] = pVBox->cbFBMax;
+ TRACE_LOG("VBVA buffer offset for screen %u: 0x%lx\n", i,
+ (unsigned long) pVBox->cbFBMax);
+ VBoxVBVASetupBufferContext(&pVBox->aVbvaCtx[i],
+ pVBox->aoffVBVABuffer[i],
+ VBVA_MIN_BUFFER_SIZE);
+ }
+ TRACE_LOG("Maximum framebuffer size: %lu (0x%lx)\n",
+ (unsigned long) pVBox->cbFBMax,
+ (unsigned long) pVBox->cbFBMax);
+ rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens,
+ vboxFillViewInfo, (void *)pVBox);
+ if (RT_FAILURE(rc))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to send the view information to the host, rc=%d\n", rc);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+Bool
+vbox_open(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
+{
+ TRACE_ENTRY();
+
+ pVBox->fHaveHGSMI = vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox);
+ return pVBox->fHaveHGSMI;
+}
+
+Bool
+vbox_device_available(VBOXPtr pVBox)
+{
+ return pVBox->useDevice;
+}
+
+/**
+ * Inform VBox that we will supply it with dirty rectangle information
+ * and install the dirty rectangle handler.
+ *
+ * @returns TRUE for success, FALSE for failure
+ * @param pScrn Pointer to a structure describing the X screen in use
+ */
+Bool
+vboxEnableVbva(ScrnInfoPtr pScrn)
+{
+ bool rc = TRUE;
+ int scrnIndex = pScrn->scrnIndex;
+ unsigned i;
+ VBOXPtr pVBox = pScrn->driverPrivate;
+
+ TRACE_ENTRY();
+ if (!vboxSetupVRAMVbva(pScrn, pVBox))
+ return FALSE;
+ for (i = 0; i < pVBox->cScreens; ++i)
+ {
+ struct VBVABUFFER *pVBVA;
+
+ pVBVA = (struct VBVABUFFER *) ( ((uint8_t *)pVBox->base)
+ + pVBox->aoffVBVABuffer[i]);
+ if (!VBoxVBVAEnable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, pVBVA, i))
+ rc = FALSE;
+ }
+ if (!rc)
+ {
+ /* Request not accepted - disable for old hosts. */
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Failed to enable screen update reporting for at least one virtual monitor.\n");
+ vboxDisableVbva(pScrn);
+ }
+ return rc;
+}
+
+/**
+ * Inform VBox that we will stop supplying it with dirty rectangle
+ * information. This function is intended to be called when an X
+ * virtual terminal is disabled, or the X server is terminated.
+ *
+ * @returns TRUE for success, FALSE for failure
+ * @param pScrn Pointer to a structure describing the X screen in use
+ */
+void
+vboxDisableVbva(ScrnInfoPtr pScrn)
+{
+ int rc;
+ int scrnIndex = pScrn->scrnIndex;
+ unsigned i;
+ VBOXPtr pVBox = pScrn->driverPrivate;
+
+ TRACE_ENTRY();
+ if (!pVBox->fHaveHGSMI) /* Ths function should not have been called */
+ return;
+ for (i = 0; i < pVBox->cScreens; ++i)
+ VBoxVBVADisable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, i);
+}
diff --git a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/sparc/sparc.h b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/sparc/sparc.h
index 835bdf4b1..55ab12122 100644
--- a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/sparc/sparc.h
+++ b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/sparc/sparc.h
@@ -1,4 +1,4 @@
-/* $Id: sparc.h $ */
+/* $Id: sparc.h,v 1.3 2001/06/06 22:55:28 davem69 Exp $ */
/*
* Mesa 3-D graphics library
diff --git a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86-64/x86-64.h b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86-64/x86-64.h
index a6b68d527..fdbd154d5 100644
--- a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86-64/x86-64.h
+++ b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86-64/x86-64.h
@@ -1,4 +1,4 @@
-/* $Id: x86-64.h $ */
+/* $Id: x86-64.h,v 1.1 2005/05/07 16:59:59 brianp Exp $ */
/*
* Mesa 3-D graphics library
diff --git a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/3dnow.h b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/3dnow.h
index 673d45994..1f2fd8e8b 100644
--- a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/3dnow.h
+++ b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/3dnow.h
@@ -1,4 +1,4 @@
-/* $Id: 3dnow.h $ */
+/* $Id: 3dnow.h,v 1.6 2002/04/09 14:58:03 keithw Exp $ */
/*
* Mesa 3-D graphics library
diff --git a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/clip_args.h b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/clip_args.h
index 7540c6a49..cccf80198 100644
--- a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/clip_args.h
+++ b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/clip_args.h
@@ -1,4 +1,4 @@
-/* $Id: clip_args.h $ */
+/* $Id: clip_args.h,v 1.5 2002/10/29 20:28:57 brianp Exp $ */
/*
* Mesa 3-D graphics library
diff --git a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_asm.h b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_asm.h
index e093b1872..997729832 100644
--- a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_asm.h
+++ b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_asm.h
@@ -1,4 +1,4 @@
-/* $Id: common_x86_asm.h $ */
+/* $Id: common_x86_asm.h,v 1.12 2005/07/16 00:56:20 ajax Exp $ */
/*
* Mesa 3-D graphics library
diff --git a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_features.h b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_features.h
index 9a0cedc99..90509775c 100644
--- a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_features.h
+++ b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_features.h
@@ -1,4 +1,4 @@
-/* $Id: common_x86_features.h $ */
+/* $Id: common_x86_features.h,v 1.6 2003/01/21 16:14:00 brianp Exp $ */
/*
* Mesa 3-D graphics library
diff --git a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_macros.h b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_macros.h
index 43033732b..ba155caae 100644
--- a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_macros.h
+++ b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/common_x86_macros.h
@@ -1,4 +1,4 @@
-/* $Id: common_x86_macros.h $ */
+/* $Id: common_x86_macros.h,v 1.3 2002/10/29 20:28:58 brianp Exp $ */
/*
* Mesa 3-D graphics library
diff --git a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/norm_args.h b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/norm_args.h
index 1e7d79c67..1b43d57a2 100644
--- a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/norm_args.h
+++ b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/norm_args.h
@@ -1,4 +1,4 @@
-/* $Id: norm_args.h $ */
+/* $Id: norm_args.h,v 1.4 2003/11/26 08:32:36 dborca Exp $ */
/*
* Mesa 3-D graphics library
diff --git a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/sse.h b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/sse.h
index fe1233653..98146a904 100644
--- a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/sse.h
+++ b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/sse.h
@@ -1,4 +1,4 @@
-/* $Id: sse.h $ */
+/* $Id: sse.h,v 1.2 2002/04/09 14:58:03 keithw Exp $ */
/*
* Mesa 3-D graphics library
diff --git a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/x86.h b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/x86.h
index 8d529110b..a646aff46 100644
--- a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/x86.h
+++ b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/x86.h
@@ -1,4 +1,4 @@
-/* $Id: x86.h $ */
+/* $Id: x86.h,v 1.5 2002/04/09 14:58:03 keithw Exp $ */
/*
* Mesa 3-D graphics library
diff --git a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/xform_args.h b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/xform_args.h
index 6bc1b8060..89a04205c 100644
--- a/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/xform_args.h
+++ b/src/VBox/Additions/x11/x11include/mesa-7.2/src/mesa/x86/xform_args.h
@@ -1,4 +1,4 @@
-/* $Id: xform_args.h $ */
+/* $Id: xform_args.h,v 1.5 2002/10/29 20:28:58 brianp Exp $ */
/*
* Mesa 3-D graphics library
diff --git a/src/VBox/Additions/x11/x11stubs/Makefile.kmk b/src/VBox/Additions/x11/x11stubs/Makefile.kmk
index 37279143c..b7f6bfe04 100644
--- a/src/VBox/Additions/x11/x11stubs/Makefile.kmk
+++ b/src/VBox/Additions/x11/x11stubs/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the X11 linker stub (import) libraries.
#
diff --git a/src/VBox/Additions/x11/x11stubs/libXcomposite-1.0.0/libXcomposite.c b/src/VBox/Additions/x11/x11stubs/libXcomposite-1.0.0/libXcomposite.c
index 401eec1d7..50aac7dd3 100644
--- a/src/VBox/Additions/x11/x11stubs/libXcomposite-1.0.0/libXcomposite.c
+++ b/src/VBox/Additions/x11/x11stubs/libXcomposite-1.0.0/libXcomposite.c
@@ -1,4 +1,4 @@
-/* $Id: libXcomposite.c $ */
+/* $Id: libXcomposite.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* X.Org libXcomposite.so linker stub
diff --git a/src/VBox/Additions/x11/x11stubs/libXdamage-1.1.0/libXdamage.c b/src/VBox/Additions/x11/x11stubs/libXdamage-1.1.0/libXdamage.c
index bcf008ea0..aa6dbabf1 100644
--- a/src/VBox/Additions/x11/x11stubs/libXdamage-1.1.0/libXdamage.c
+++ b/src/VBox/Additions/x11/x11stubs/libXdamage-1.1.0/libXdamage.c
@@ -1,4 +1,4 @@
-/* $Id: libXdamage.c $ */
+/* $Id: libXdamage.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* X.Org libXdamage.so linker stub
diff --git a/src/VBox/Additions/x11/x11stubs/libXext-6.4.0/libXext.c b/src/VBox/Additions/x11/x11stubs/libXext-6.4.0/libXext.c
index f83809adb..0aec41467 100644
--- a/src/VBox/Additions/x11/x11stubs/libXext-6.4.0/libXext.c
+++ b/src/VBox/Additions/x11/x11stubs/libXext-6.4.0/libXext.c
@@ -1,4 +1,4 @@
-/* $Id: libXext.c $ */
+/* $Id: libXext.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* X.Org libXext.so linker stub
diff --git a/src/VBox/Additions/x11/x11stubs/libXfixes-3.1.0/libXfixes.c b/src/VBox/Additions/x11/x11stubs/libXfixes-3.1.0/libXfixes.c
index 211f7f491..82dab131a 100644
--- a/src/VBox/Additions/x11/x11stubs/libXfixes-3.1.0/libXfixes.c
+++ b/src/VBox/Additions/x11/x11stubs/libXfixes-3.1.0/libXfixes.c
@@ -1,4 +1,4 @@
-/* $Id: libXfixes.c $ */
+/* $Id: libXfixes.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* X.Org libXfixes.so linker stub
diff --git a/src/VBox/Debugger/DBGCBuiltInSymbols.cpp b/src/VBox/Debugger/DBGCBuiltInSymbols.cpp
index 6a4e7075c..17abd3125 100644
--- a/src/VBox/Debugger/DBGCBuiltInSymbols.cpp
+++ b/src/VBox/Debugger/DBGCBuiltInSymbols.cpp
@@ -1,10 +1,10 @@
-/* $Id: DBGCBuiltInSymbols.cpp $ */
+/* $Id: DBGCBuiltInSymbols.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
* DBGC - Debugger Console, Built-In Symbols.
*/
/*
- * 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;
@@ -19,501 +19,13 @@
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DBGC
-#include <VBox/dbg.h>
-#include <VBox/vmm/dbgf.h>
-#include <VBox/vmm/vm.h>
-#include <VBox/vmm/vmm.h>
-#include <VBox/vmm/mm.h>
-#include <VBox/vmm/pgm.h>
-#include <VBox/vmm/selm.h>
-#include <VBox/dis.h>
-#include <VBox/param.h>
-#include <VBox/err.h>
-#include <VBox/log.h>
-
-#include <iprt/alloc.h>
-#include <iprt/alloca.h>
-#include <iprt/string.h>
-#include <iprt/assert.h>
-#include <iprt/ctype.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-
#include "DBGCInternal.h"
-/*******************************************************************************
-* Internal Functions *
-*******************************************************************************/
-static DECLCALLBACK(int) dbgcSymGetReg(PCDBGCSYM pSymDesc, PDBGCCMDHLP pCmdHlp, DBGCVARTYPE enmType, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcSymSetReg(PCDBGCSYM pSymDesc, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pValue);
-
-
-/*******************************************************************************
-* Global Variables *
-*******************************************************************************/
-/** Register symbol uUser value.
- * @{
- */
-/** If set the register set is the hypervisor and not the guest one. */
-#define SYMREG_FLAGS_HYPER RT_BIT(20)
-/** If set a far conversion of the value will use the high 16 bit for the selector.
- * If clear the low 16 bit will be used. */
-#define SYMREG_FLAGS_HIGH_SEL RT_BIT(21)
-/** The shift value to calc the size of a register symbol from the uUser value. */
-#define SYMREG_SIZE_SHIFT (24)
-/** Get the offset */
-#define SYMREG_OFFSET(uUser) (uUser & ((1 << 20) - 1))
-/** Get the size. */
-#define SYMREG_SIZE(uUser) ((uUser >> SYMREG_SIZE_SHIFT) & 0xff)
-/** 1 byte. */
-#define SYMREG_SIZE_1 ( 1 << SYMREG_SIZE_SHIFT)
-/** 2 byte. */
-#define SYMREG_SIZE_2 ( 2 << SYMREG_SIZE_SHIFT)
-/** 4 byte. */
-#define SYMREG_SIZE_4 ( 4 << SYMREG_SIZE_SHIFT)
-/** 6 byte. */
-#define SYMREG_SIZE_6 ( 6 << SYMREG_SIZE_SHIFT)
-/** 8 byte. */
-#define SYMREG_SIZE_8 ( 8 << SYMREG_SIZE_SHIFT)
-/** 10 bytes. */
-#define SYMREG_SIZE_10 (10 << SYMREG_SIZE_SHIFT)
-/** 12 byte. */
-#define SYMREG_SIZE_12 (12 << SYMREG_SIZE_SHIFT)
-/** 16 byte. */
-#define SYMREG_SIZE_16 (16 << SYMREG_SIZE_SHIFT)
-/** @} */
-
-/** Builtin Symbols.
- * ASSUMES little endian register representation!
- */
-static const DBGCSYM g_aSyms[] =
-{
- { "rax", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, rax) | SYMREG_SIZE_8 },
- { "eax", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eax) | SYMREG_SIZE_4 },
- { "ax", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eax) | SYMREG_SIZE_2 },
- { "al", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eax) | SYMREG_SIZE_1 },
- { "ah", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, eax) + 1)| SYMREG_SIZE_1 },
-
- { "rbx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, rbx) | SYMREG_SIZE_8 },
- { "ebx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebx) | SYMREG_SIZE_4 },
- { "bx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebx) | SYMREG_SIZE_2 },
- { "bl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebx) | SYMREG_SIZE_1 },
- { "bh", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, ebx) + 1)| SYMREG_SIZE_1 },
-
- { "rcx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_8 },
- { "ecx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_4 },
- { "cx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_2 },
- { "cl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_1 },
- { "ch", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, ecx) + 1)| SYMREG_SIZE_1 },
-
- { "rdx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, rdx) | SYMREG_SIZE_8 },
- { "edx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edx) | SYMREG_SIZE_4 },
- { "dx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edx) | SYMREG_SIZE_2 },
- { "dl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edx) | SYMREG_SIZE_1 },
- { "dh", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, edx) + 1)| SYMREG_SIZE_1 },
-
- { "rdi", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, rdi) | SYMREG_SIZE_8 },
- { "edi", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edi) | SYMREG_SIZE_4 },
- { "di", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edi) | SYMREG_SIZE_2 },
- { "dil", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edi) | SYMREG_SIZE_1 },
-
- { "rsi", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, rsi) | SYMREG_SIZE_8 },
- { "esi", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esi) | SYMREG_SIZE_4 },
- { "si", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esi) | SYMREG_SIZE_2 },
- { "sil", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esi) | SYMREG_SIZE_1 },
-
- { "rbp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, rbp) | SYMREG_SIZE_8 },
- { "ebp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebp) | SYMREG_SIZE_4 },
- { "bp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebp) | SYMREG_SIZE_2 },
- { "bpl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebp) | SYMREG_SIZE_1 },
-
- { "rsp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, rsp) | SYMREG_SIZE_8 },
- { "esp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esp) | SYMREG_SIZE_4 },
- { "sp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esp) | SYMREG_SIZE_2 },
- { "spl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esp) | SYMREG_SIZE_1 },
-
- { "r8", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r8) | SYMREG_SIZE_8 },
- { "r9", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r9) | SYMREG_SIZE_8 },
- { "r10", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r10) | SYMREG_SIZE_8 },
- { "r11", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r11) | SYMREG_SIZE_8 },
- { "r12", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r12) | SYMREG_SIZE_8 },
- { "r13", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r13) | SYMREG_SIZE_8 },
- { "r14", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r14) | SYMREG_SIZE_8 },
- { "r15", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r15) | SYMREG_SIZE_8 },
-
- { "r8d", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r8) | SYMREG_SIZE_4 },
- { "r9d", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r9) | SYMREG_SIZE_4 },
- { "r10d", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r10) | SYMREG_SIZE_4 },
- { "r11d", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r11) | SYMREG_SIZE_4 },
- { "r12d", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r12) | SYMREG_SIZE_4 },
- { "r13d", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r13) | SYMREG_SIZE_4 },
- { "r14d", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r14) | SYMREG_SIZE_4 },
- { "r15d", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r15) | SYMREG_SIZE_4 },
-
- { "r8w", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r8) | SYMREG_SIZE_2 },
- { "r9w", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r9) | SYMREG_SIZE_2 },
- { "r10w", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r10) | SYMREG_SIZE_2 },
- { "r11w", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r11) | SYMREG_SIZE_2 },
- { "r12w", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r12) | SYMREG_SIZE_2 },
- { "r13w", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r13) | SYMREG_SIZE_2 },
- { "r14w", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r14) | SYMREG_SIZE_2 },
- { "r15w", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r15) | SYMREG_SIZE_2 },
-
- { "r8b", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r8) | SYMREG_SIZE_1 },
- { "r9b", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r9) | SYMREG_SIZE_1 },
- { "r10b", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r10) | SYMREG_SIZE_1 },
- { "r11b", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r11) | SYMREG_SIZE_1 },
- { "r12b", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r12) | SYMREG_SIZE_1 },
- { "r13b", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r13) | SYMREG_SIZE_1 },
- { "r14b", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r14) | SYMREG_SIZE_1 },
- { "r15b", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, r15) | SYMREG_SIZE_1 },
-
- { "rip", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, rip) | SYMREG_SIZE_8 },
- { "eip", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eip) | SYMREG_SIZE_4 },
- { "ip", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eip) | SYMREG_SIZE_2 },
-
- { "rfl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, rflags) | SYMREG_SIZE_8 },
- { "rflags", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, rflags) | SYMREG_SIZE_8 },
- { "efl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_4 },
- { "eflags", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_4 },
- { "fl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_2 },
- { "flags", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_2 },
-
- { "cs", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cs) | SYMREG_SIZE_2 },
- { "ds", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ds) | SYMREG_SIZE_2 },
- { "es", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, es) | SYMREG_SIZE_2 },
- { "fs", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, fs) | SYMREG_SIZE_2 },
- { "gs", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gs) | SYMREG_SIZE_2 },
- { "ss", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ss) | SYMREG_SIZE_2 },
-
- { "cr0", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr0) | SYMREG_SIZE_8 },
- { "cr2", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr2) | SYMREG_SIZE_8 },
- { "cr3", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr3) | SYMREG_SIZE_8 },
- { "cr4", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr4) | SYMREG_SIZE_8 },
-
- { "tr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, tr) | SYMREG_SIZE_2 },
- { "ldtr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ldtr) | SYMREG_SIZE_2 },
-
- { "gdtr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gdtr) | SYMREG_SIZE_10 },
- { "gdtr.limit", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gdtr.cbGdt)| SYMREG_SIZE_2 },
- { "gdtr.base", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gdtr.pGdt)| SYMREG_SIZE_8 },
-
- { "idtr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, idtr) | SYMREG_SIZE_10 },
- { "idtr.limit", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, idtr.cbIdt)| SYMREG_SIZE_2 },
- { "idtr.base", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, idtr.pIdt)| SYMREG_SIZE_8 },
-
- /* hypervisor */
-
- {".eax", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eax) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".ax", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eax) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
- {".al", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eax) | SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
- {".ah", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, eax) + 1)| SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
-
- {".ebx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebx) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".bx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebx) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
- {".bl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebx) | SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
- {".bh", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, ebx) + 1)| SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
-
- {".ecx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".cx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
- {".cl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
- {".ch", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, ecx) + 1)| SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
-
- {".edx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edx) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".dx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edx) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
- {".dl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edx) | SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
- {".dh", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, edx) + 1)| SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
-
- {".edi", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edi) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".di", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edi) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
-
- {".esi", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esi) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".si", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esi) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
-
- {".ebp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebp) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".bp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebp) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
-
- {".esp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esp) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".sp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esp) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
-
- {".eip", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eip) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".ip", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eip) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
-
- {".efl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".eflags", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".fl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
- {".flags", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
-
- {".cs", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cs) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
- {".ds", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ds) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
- {".es", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, es) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
- {".fs", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, fs) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
- {".gs", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gs) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
- {".ss", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ss) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
-
- {".cr0", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr0) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".cr2", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr2) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".cr3", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr3) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
- {".cr4", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr4) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
-
- {".tr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, tr) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
- {".ldtr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ldtr) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
-
- {".gdtr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gdtr) | SYMREG_SIZE_10 | SYMREG_FLAGS_HYPER },
- {".gdtr.limit", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gdtr.cbGdt)| SYMREG_SIZE_2| SYMREG_FLAGS_HYPER },
- {".gdtr.base", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gdtr.pGdt)| SYMREG_SIZE_8 | SYMREG_FLAGS_HYPER },
-
- {".idtr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, idtr) | SYMREG_SIZE_10 | SYMREG_FLAGS_HYPER },
- {".idtr.limit", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, idtr.cbIdt)| SYMREG_SIZE_2| SYMREG_FLAGS_HYPER },
- {".idtr.base", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, idtr.pIdt)| SYMREG_SIZE_8 | SYMREG_FLAGS_HYPER },
-
-};
-
-
-
-/**
- * Get builtin register symbol.
- *
- * The uUser is special for these symbol descriptors. See the SYMREG_* \#defines.
- *
- * @returns 0 on success.
- * @returns VBox evaluation / parsing error code on failure.
- * The caller does the bitching.
- * @param pSymDesc Pointer to the symbol descriptor.
- * @param pCmdHlp Pointer to the command callback structure.
- * @param enmType The result type.
- * @param pResult Where to store the result.
- */
-static DECLCALLBACK(int) dbgcSymGetReg(PCDBGCSYM pSymDesc, PDBGCCMDHLP pCmdHlp, DBGCVARTYPE enmType, PDBGCVAR pResult)
-{
- LogFlow(("dbgcSymSetReg: pSymDesc->pszName=%d\n", pSymDesc->pszName));
-
- /*
- * pVM is required.
- */
- PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
- Assert(pDbgc->pVM);
-
- /*
- * Get the right CPU context.
- */
- PVMCPU pVCpu = VMMGetCpuById(pDbgc->pVM, pDbgc->idCpu);
- PCPUMCTX pCtx;
- int rc;
- if (!(pSymDesc->uUser & SYMREG_FLAGS_HYPER))
- {
- pCtx = CPUMQueryGuestCtxPtr(pVCpu);
- rc = VINF_SUCCESS;
- }
- else
- rc = CPUMQueryHyperCtxPtr(pVCpu, &pCtx);
- if (RT_FAILURE(rc))
- return rc;
-
- /*
- * Get the value.
- */
- void *pvValue = (char *)pCtx + SYMREG_OFFSET(pSymDesc->uUser);
- uint64_t u64;
- switch (SYMREG_SIZE(pSymDesc->uUser))
- {
- case 1: u64 = *(uint8_t *)pvValue; break;
- case 2: u64 = *(uint16_t *)pvValue; break;
- case 4: u64 = *(uint32_t *)pvValue; break;
- case 6: u64 = *(uint32_t *)pvValue | ((uint64_t)*(uint16_t *)((char *)pvValue + sizeof(uint32_t)) << 32); break;
- case 8: u64 = *(uint64_t *)pvValue; break;
- default:
- return VERR_PARSE_NOT_IMPLEMENTED;
- }
-
- /*
- * Construct the desired result.
- */
- if (enmType == DBGCVAR_TYPE_ANY)
- enmType = DBGCVAR_TYPE_NUMBER;
- pResult->pDesc = NULL;
- pResult->pNext = NULL;
- pResult->enmType = enmType;
- pResult->enmRangeType = DBGCVAR_RANGE_NONE;
- pResult->u64Range = 0;
-
- switch (enmType)
- {
- case DBGCVAR_TYPE_GC_FLAT:
- pResult->u.GCFlat = (RTGCPTR)u64;
- break;
-
- case DBGCVAR_TYPE_GC_FAR:
- switch (SYMREG_SIZE(pSymDesc->uUser))
- {
- case 4:
- if (!(pSymDesc->uUser & SYMREG_FLAGS_HIGH_SEL))
- {
- pResult->u.GCFar.off = (uint16_t)u64;
- pResult->u.GCFar.sel = (uint16_t)(u64 >> 16);
- }
- else
- {
- pResult->u.GCFar.sel = (uint16_t)u64;
- pResult->u.GCFar.off = (uint16_t)(u64 >> 16);
- }
- break;
- case 6:
- if (!(pSymDesc->uUser & SYMREG_FLAGS_HIGH_SEL))
- {
- pResult->u.GCFar.off = (uint32_t)u64;
- pResult->u.GCFar.sel = (uint16_t)(u64 >> 32);
- }
- else
- {
- pResult->u.GCFar.sel = (uint32_t)u64;
- pResult->u.GCFar.off = (uint16_t)(u64 >> 32);
- }
- break;
-
- default:
- return VERR_PARSE_BAD_RESULT_TYPE;
- }
- break;
-
- case DBGCVAR_TYPE_GC_PHYS:
- pResult->u.GCPhys = (RTGCPHYS)u64;
- break;
-
- case DBGCVAR_TYPE_HC_FLAT:
- pResult->u.pvHCFlat = (void *)(uintptr_t)u64;
- break;
-
- case DBGCVAR_TYPE_HC_FAR:
- switch (SYMREG_SIZE(pSymDesc->uUser))
- {
- case 4:
- if (!(pSymDesc->uUser & SYMREG_FLAGS_HIGH_SEL))
- {
- pResult->u.HCFar.off = (uint16_t)u64;
- pResult->u.HCFar.sel = (uint16_t)(u64 >> 16);
- }
- else
- {
- pResult->u.HCFar.sel = (uint16_t)u64;
- pResult->u.HCFar.off = (uint16_t)(u64 >> 16);
- }
- break;
- case 6:
- if (!(pSymDesc->uUser & SYMREG_FLAGS_HIGH_SEL))
- {
- pResult->u.HCFar.off = (uint32_t)u64;
- pResult->u.HCFar.sel = (uint16_t)(u64 >> 32);
- }
- else
- {
- pResult->u.HCFar.sel = (uint32_t)u64;
- pResult->u.HCFar.off = (uint16_t)(u64 >> 32);
- }
- break;
-
- default:
- return VERR_PARSE_BAD_RESULT_TYPE;
- }
- break;
-
- case DBGCVAR_TYPE_HC_PHYS:
- pResult->u.GCPhys = (RTGCPHYS)u64;
- break;
-
- case DBGCVAR_TYPE_NUMBER:
- pResult->u.u64Number = u64;
- break;
-
- case DBGCVAR_TYPE_STRING:
- case DBGCVAR_TYPE_UNKNOWN:
- default:
- return VERR_PARSE_BAD_RESULT_TYPE;
-
- }
-
- return 0;
-}
-
-
-/**
- * Set builtin register symbol.
- *
- * The uUser is special for these symbol descriptors. See the SYMREG_* #defines.
- *
- * @returns 0 on success.
- * @returns VBox evaluation / parsing error code on failure.
- * The caller does the bitching.
- * @param pSymDesc Pointer to the symbol descriptor.
- * @param pCmdHlp Pointer to the command callback structure.
- * @param pValue The value to assign the symbol.
- */
-static DECLCALLBACK(int) dbgcSymSetReg(PCDBGCSYM pSymDesc, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pValue)
-{
- LogFlow(("dbgcSymSetReg: pSymDesc->pszName=%d\n", pSymDesc->pszName));
-
- /*
- * pVM is required.
- */
- PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
- Assert(pDbgc->pVM);
-
- /*
- * Get the right CPU context.
- */
- PVMCPU pVCpu = VMMGetCpuById(pDbgc->pVM, pDbgc->idCpu);
- PCPUMCTX pCtx;
- int rc;
- if (!(pSymDesc->uUser & SYMREG_FLAGS_HYPER))
- {
- pCtx = CPUMQueryGuestCtxPtr(pVCpu);
- rc = VINF_SUCCESS;
- }
- else
- rc = CPUMQueryHyperCtxPtr(pVCpu, &pCtx);
- if (RT_FAILURE(rc))
- return rc;
-
- /*
- * Check the new value.
- */
- if (pValue->enmType != DBGCVAR_TYPE_NUMBER)
- return VERR_PARSE_ARGUMENT_TYPE_MISMATCH;
-
- /*
- * Set the value.
- */
- void *pvValue = (char *)pCtx + SYMREG_OFFSET(pSymDesc->uUser);
- switch (SYMREG_SIZE(pSymDesc->uUser))
- {
- case 1:
- *(uint8_t *)pvValue = (uint8_t)pValue->u.u64Number;
- break;
- case 2:
- *(uint16_t *)pvValue = (uint16_t)pValue->u.u64Number;
- break;
- case 4:
- *(uint32_t *)pvValue = (uint32_t)pValue->u.u64Number;
- break;
- case 6:
- *(uint32_t *)pvValue = (uint32_t)pValue->u.u64Number;
- ((uint16_t *)pvValue)[3] = (uint16_t)(pValue->u.u64Number >> 32);
- break;
- case 8:
- *(uint64_t *)pvValue = pValue->u.u64Number;
- break;
- default:
- return VERR_PARSE_NOT_IMPLEMENTED;
- }
-
- return VINF_SUCCESS;
-}
-
/**
* Finds a builtin symbol.
+ *
* @returns Pointer to symbol descriptor on success.
* @returns NULL on failure.
* @param pDbgc The debug console instance.
@@ -521,10 +33,6 @@ static DECLCALLBACK(int) dbgcSymSetReg(PCDBGCSYM pSymDesc, PDBGCCMDHLP pCmdHlp,
*/
PCDBGCSYM dbgcLookupRegisterSymbol(PDBGC pDbgc, const char *pszSymbol)
{
- for (unsigned iSym = 0; iSym < RT_ELEMENTS(g_aSyms); iSym++)
- if (!strcmp(pszSymbol, g_aSyms[iSym].pszName))
- return &g_aSyms[iSym];
-
/** @todo externally registered symbols. */
NOREF(pDbgc);
return NULL;
diff --git a/src/VBox/Debugger/DBGCCmdHlp.cpp b/src/VBox/Debugger/DBGCCmdHlp.cpp
index bf0861242..badf37e60 100644
--- a/src/VBox/Debugger/DBGCCmdHlp.cpp
+++ b/src/VBox/Debugger/DBGCCmdHlp.cpp
@@ -1,10 +1,10 @@
-/* $Id: DBGCCmdHlp.cpp $ */
+/* $Id: DBGCCmdHlp.cpp 36032 2011-02-21 12:46:48Z vboxsync $ */
/** @file
* DBGC - Debugger Console, Command Helpers.
*/
/*
- * 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;
@@ -21,52 +21,22 @@
#define LOG_GROUP LOG_GROUP_DBGC
#include <VBox/dbg.h>
#include <VBox/vmm/dbgf.h>
-#include <VBox/vmm/vm.h>
-#include <VBox/vmm/vmm.h>
-#include <VBox/vmm/mm.h>
#include <VBox/vmm/pgm.h>
-#include <VBox/vmm/selm.h>
-#include <VBox/dis.h>
#include <VBox/param.h>
#include <VBox/err.h>
#include <VBox/log.h>
-#include <iprt/alloc.h>
-#include <iprt/alloca.h>
-#include <iprt/string.h>
#include <iprt/assert.h>
#include <iprt/ctype.h>
+#include <iprt/mem.h>
+#include <iprt/string.h>
#include "DBGCInternal.h"
/**
- * Command helper for writing text to the debug console.
- *
- * @returns VBox status.
- * @param pCmdHlp Pointer to the command callback structure.
- * @param pvBuf What to write.
- * @param cbBuf Number of bytes to write.
- * @param pcbWritten Where to store the number of bytes actually written.
- * If NULL the entire buffer must be successfully written.
- */
-static DECLCALLBACK(int) dbgcHlpWrite(PDBGCCMDHLP pCmdHlp, const void *pvBuf, size_t cbBuf, size_t *pcbWritten)
-{
- PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
- return pDbgc->pBack->pfnWrite(pDbgc->pBack, pvBuf, cbBuf, pcbWritten);
-}
-
-
-/**
- * Command helper for writing formatted text to the debug console.
- *
- * @returns VBox status.
- * @param pCmdHlp Pointer to the command callback structure.
- * @param pcb Where to store the number of bytes written.
- * @param pszFormat The format string.
- * This is using the log formatter, so it's format extensions can be used.
- * @param ... Arguments specified in the format string.
+ * @interface_method_impl{DBGCCMDHLP,pfnPrintf}
*/
static DECLCALLBACK(int) dbgcHlpPrintf(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, ...)
{
@@ -82,7 +52,8 @@ static DECLCALLBACK(int) dbgcHlpPrintf(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten,
}
/**
- * Callback to format non-standard format specifiers.
+ * Callback to format non-standard format specifiers, employed by dbgcPrintfV
+ * and others.
*
* @returns The number of bytes formatted.
* @param pvArg Formatter argument.
@@ -128,8 +99,6 @@ static DECLCALLBACK(size_t) dbgcStringFormatter(void *pvArg, PFNRTSTROUTPUT pfnO
return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%%%%RGp", pVar->u.GCPhys);
case DBGCVAR_TYPE_HC_FLAT:
return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%#%RHv", (uintptr_t)pVar->u.pvHCFlat);
- case DBGCVAR_TYPE_HC_FAR:
- return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "#%04x:%08x", pVar->u.HCFar.sel, pVar->u.HCFar.off);
case DBGCVAR_TYPE_HC_PHYS:
return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "#%%%%%RHp", pVar->u.HCPhys);
case DBGCVAR_TYPE_STRING:
@@ -176,8 +145,6 @@ static DECLCALLBACK(size_t) dbgcStringFormatter(void *pvArg, PFNRTSTROUTPUT pfnO
return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%%%%RGp%s", pVar->u.GCPhys, szRange);
case DBGCVAR_TYPE_HC_FLAT:
return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%#%RHv%s", (uintptr_t)pVar->u.pvHCFlat, szRange);
- case DBGCVAR_TYPE_HC_FAR:
- return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "#%04x:%08x%s", pVar->u.HCFar.sel, pVar->u.HCFar.off, szRange);
case DBGCVAR_TYPE_HC_PHYS:
return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "#%%%%%RHp%s", pVar->u.HCPhys, szRange);
case DBGCVAR_TYPE_STRING:
@@ -199,7 +166,7 @@ static DECLCALLBACK(size_t) dbgcStringFormatter(void *pvArg, PFNRTSTROUTPUT pfnO
/**
- * Output callback.
+ * Output callback employed by dbgcHlpPrintfV.
*
* @returns number of bytes written.
* @param pvArg User argument.
@@ -208,11 +175,13 @@ static DECLCALLBACK(size_t) dbgcStringFormatter(void *pvArg, PFNRTSTROUTPUT pfnO
*/
static DECLCALLBACK(size_t) dbgcFormatOutput(void *pvArg, const char *pachChars, size_t cbChars)
{
- PDBGC pDbgc = (PDBGC)pvArg;
+ PDBGC pDbgc = (PDBGC)pvArg;
if (cbChars)
{
int rc = pDbgc->pBack->pfnWrite(pDbgc->pBack, pachChars, cbChars, NULL);
- if (RT_FAILURE(rc))
+ if (RT_SUCCESS(rc))
+ pDbgc->chLastOutput = pachChars[cbChars - 1];
+ else
{
pDbgc->rcOutput = rc;
cbChars = 0;
@@ -225,14 +194,7 @@ static DECLCALLBACK(size_t) dbgcFormatOutput(void *pvArg, const char *pachChars,
/**
- * Command helper for writing formatted text to the debug console.
- *
- * @returns VBox status.
- * @param pCmdHlp Pointer to the command callback structure.
- * @param pcbWritten Where to store the number of bytes written.
- * @param pszFormat The format string.
- * This is using the log formatter, so it's format extensions can be used.
- * @param args Arguments specified in the format string.
+ * @interface_method_impl{DBGCCMDHLP,pfnPrintfV}
*/
static DECLCALLBACK(int) dbgcHlpPrintfV(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, va_list args)
{
@@ -252,13 +214,7 @@ static DECLCALLBACK(int) dbgcHlpPrintfV(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten,
/**
- * Reports an error from a DBGF call.
- *
- * @returns VBox status code appropriate to return from a command.
- * @param pCmdHlp Pointer to command helpers.
- * @param rc The VBox status code returned by a DBGF call.
- * @param pszFormat Format string for additional messages. Can be NULL.
- * @param ... Format arguments, optional.
+ * @interface_method_impl{DBGCCMDHLP,pfnVBoxErrorV}
*/
static DECLCALLBACK(int) dbgcHlpVBoxErrorV(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, va_list args)
{
@@ -280,13 +236,7 @@ static DECLCALLBACK(int) dbgcHlpVBoxErrorV(PDBGCCMDHLP pCmdHlp, int rc, const ch
/**
- * Reports an error from a DBGF call.
- *
- * @returns VBox status code appropriate to return from a command.
- * @param pCmdHlp Pointer to command helpers.
- * @param rc The VBox status code returned by a DBGF call.
- * @param pszFormat Format string for additional messages. Can be NULL.
- * @param ... Format arguments, optional.
+ * @interface_method_impl{DBGCCMDHLP,pfnVBoxError}
*/
static DECLCALLBACK(int) dbgcHlpVBoxError(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...)
{
@@ -299,19 +249,7 @@ static DECLCALLBACK(int) dbgcHlpVBoxError(PDBGCCMDHLP pCmdHlp, int rc, const cha
/**
- * Command helper for reading memory specified by a DBGC variable.
- *
- * @returns VBox status code appropriate to return from a command.
- * @param pCmdHlp Pointer to the command callback structure.
- * @param pVM VM handle if GC or physical HC address.
- * @param pvBuffer Where to store the read data.
- * @param cbRead Number of bytes to read.
- * @param pVarPointer DBGC variable specifying where to start reading.
- * @param pcbRead Where to store the number of bytes actually read.
- * This optional, but it's useful when read GC virtual memory where a
- * page in the requested range might not be present.
- * If not specified not-present failure or end of a HC physical page
- * will cause failure.
+ * @interface_method_impl{DBGCCMDHLP,pfnMemRead}
*/
static DECLCALLBACK(int) dbgcHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead)
{
@@ -385,7 +323,6 @@ static DECLCALLBACK(int) dbgcHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBu
case DBGCVAR_TYPE_HC_PHYS:
break;
- case DBGCVAR_TYPE_HC_FAR: /* not supported yet! */
default:
return VERR_NOT_IMPLEMENTED;
}
@@ -430,7 +367,6 @@ static DECLCALLBACK(int) dbgcHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBu
case DBGCVAR_TYPE_HC_PHYS:
case DBGCVAR_TYPE_HC_FLAT:
- case DBGCVAR_TYPE_HC_FAR:
{
DBGCVAR Var2;
rc = dbgcOpAddrFlat(pDbgc, &Var, &Var2);
@@ -483,18 +419,9 @@ static DECLCALLBACK(int) dbgcHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBu
return 0;
}
+
/**
- * Command helper for writing memory specified by a DBGC variable.
- *
- * @returns VBox status code appropriate to return from a command.
- * @param pCmdHlp Pointer to the command callback structure.
- * @param pVM VM handle if GC or physical HC address.
- * @param pvBuffer What to write.
- * @param cbWrite Number of bytes to write.
- * @param pVarPointer DBGC variable specifying where to start reading.
- * @param pcbWritten Where to store the number of bytes written.
- * This is optional. If NULL be aware that some of the buffer
- * might have been written to the specified address.
+ * @interface_method_impl{DBGCCMDHLP,pfnMemWrite}
*/
static DECLCALLBACK(int) dbgcHlpMemWrite(PDBGCCMDHLP pCmdHlp, PVM pVM, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten)
{
@@ -581,7 +508,6 @@ static DECLCALLBACK(int) dbgcHlpMemWrite(PDBGCCMDHLP pCmdHlp, PVM pVM, const voi
case DBGCVAR_TYPE_HC_FLAT:
case DBGCVAR_TYPE_HC_PHYS:
- case DBGCVAR_TYPE_HC_FAR:
{
/*
* Copy HC memory page by page.
@@ -630,13 +556,7 @@ static DECLCALLBACK(int) dbgcHlpMemWrite(PDBGCCMDHLP pCmdHlp, PVM pVM, const voi
/**
- * Executes one command expression.
- * (Hopefully the parser and functions are fully reentrant.)
- *
- * @returns VBox status code appropriate to return from a command.
- * @param pCmdHlp Pointer to the command callback structure.
- * @param pszExpr The expression. Format string with the format DBGC extensions.
- * @param ... Format arguments.
+ * @interface_method_impl{DBGCCMDHLP,pfnHlpExec}
*/
static DECLCALLBACK(int) dbgcHlpExec(PDBGCCMDHLP pCmdHlp, const char *pszExpr, ...)
{
@@ -661,7 +581,7 @@ static DECLCALLBACK(int) dbgcHlpExec(PDBGCCMDHLP pCmdHlp, const char *pszExpr, .
* We save and restore the arg index and scratch buffer pointer.
*/
pDbgc->pszScratch = pDbgc->pszScratch + cb + 1;
- int rc = dbgcProcessCommand(pDbgc, pszScratch, cb, false /* fNoExecute */);
+ int rc = dbgcEvalCommand(pDbgc, pszScratch, cb, false /* fNoExecute */);
/* Restore the scratch state. */
pDbgc->iArg = iArg;
@@ -685,7 +605,7 @@ static DECLCALLBACK(int) dbgcHlpEvalV(PDBGCCMDHLP pCmdHlp, PDBGCVAR pResult, con
size_t cb = RTStrPrintfExV(dbgcStringFormatter, pDbgc, szExprFormatted, sizeof(szExprFormatted), pszExpr, va);
/* ignore overflows. */
- return dbgcEvalSub(pDbgc, &szExprFormatted[0], cb, pResult);
+ return dbgcEvalSub(pDbgc, &szExprFormatted[0], cb, DBGCVAR_CAT_ANY, pResult);
}
@@ -706,34 +626,158 @@ static DECLCALLBACK(int) dbgcHlpFailV(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, const
RTStrFormatV(dbgcFormatOutput, pDbgc, dbgcStringFormatter, pDbgc, pszFormat, va);
if (RT_FAILURE(pDbgc->rcOutput))
return pDbgc->rcOutput;
+ if (pDbgc->chLastOutput != '\n')
+ dbgcFormatOutput(pDbgc, "\n", 1);
+ return VERR_DBGC_COMMAND_FAILED;
+}
- /** @todo DBGC: Implement failure / success on command level. */
- return VINF_SUCCESS;
+
+/**
+ * @copydoc DBGCCMDHLP::pfnFailV
+ */
+static DECLCALLBACK(int) dbgcHlpFailRcV(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int rc, const char *pszFormat, va_list va)
+{
+ PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
+
+ /*
+ * Do the formatting and output.
+ */
+ pDbgc->rcOutput = VINF_SUCCESS;
+ RTStrFormat(dbgcFormatOutput, pDbgc, dbgcStringFormatter, pDbgc, "%s: error: ", pCmd->pszCmd);
+ if (RT_FAILURE(pDbgc->rcOutput))
+ return pDbgc->rcOutput;
+ RTStrFormatV(dbgcFormatOutput, pDbgc, dbgcStringFormatter, pDbgc, pszFormat, va);
+ if (RT_FAILURE(pDbgc->rcOutput))
+ return pDbgc->rcOutput;
+ RTStrFormat(dbgcFormatOutput, pDbgc, dbgcStringFormatter, pDbgc, ": %Rrc\n", rc);
+ if (RT_FAILURE(pDbgc->rcOutput))
+ return pDbgc->rcOutput;
+
+ return VERR_DBGC_COMMAND_FAILED;
}
/**
- * Converts a DBGC variable to a DBGF address structure.
- *
- * @returns VBox status code.
- * @param pCmdHlp Pointer to the command callback structure.
- * @param pVar The variable to convert.
- * @param pAddress The target address.
+ * @interface_method_impl{DBGCCMDHLP,pfnVarToDbgfAddr}
*/
static DECLCALLBACK(int) dbgcHlpVarToDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
- return dbgcVarToDbgfAddr(pDbgc, pVar, pAddress);
+ AssertPtr(pVar);
+ AssertPtr(pAddress);
+
+ switch (pVar->enmType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ DBGFR3AddrFromFlat(pDbgc->pVM, pAddress, pVar->u.GCFlat);
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_NUMBER:
+ DBGFR3AddrFromFlat(pDbgc->pVM, pAddress, (RTGCUINTPTR)pVar->u.u64Number);
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_GC_FAR:
+ return DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, pAddress, pVar->u.GCFar.sel, pVar->u.GCFar.off);
+
+ case DBGCVAR_TYPE_GC_PHYS:
+ DBGFR3AddrFromPhys(pDbgc->pVM, pAddress, pVar->u.GCPhys);
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_STRING:
+ case DBGCVAR_TYPE_SYMBOL:
+ {
+ DBGCVAR Var;
+ int rc = DBGCCmdHlpEval(&pDbgc->CmdHlp, &Var, "%%(%DV)", pVar);
+ if (RT_FAILURE(rc))
+ return rc;
+ return dbgcHlpVarToDbgfAddr(pCmdHlp, &Var, pAddress);
+ }
+
+ case DBGCVAR_TYPE_HC_FLAT:
+ case DBGCVAR_TYPE_HC_PHYS:
+ default:
+ return VERR_PARSE_CONVERSION_FAILED;
+ }
}
/**
- * Converts a DBGC variable to a boolean.
- *
- * @returns VBox status code.
- * @param pCmdHlp Pointer to the command callback structure.
- * @param pVar The variable to convert.
- * @param pf Where to store the boolean.
+ * @interface_method_impl{DBGCCMDHLP,pfnVarFromDbgfAddr}
+ */
+static DECLCALLBACK(int) dbgcHlpVarFromDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGFADDRESS pAddress, PDBGCVAR pResult)
+{
+ AssertPtrReturn(pAddress, VERR_INVALID_POINTER);
+ AssertReturn(DBGFADDRESS_IS_VALID(pAddress), VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pResult, VERR_INVALID_POINTER);
+
+ switch (pAddress->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK)
+ {
+ case DBGFADDRESS_FLAGS_FAR16:
+ case DBGFADDRESS_FLAGS_FAR32:
+ case DBGFADDRESS_FLAGS_FAR64:
+ DBGCVAR_INIT_GC_FAR(pResult, pAddress->Sel, pAddress->off);
+ break;
+
+ case DBGFADDRESS_FLAGS_FLAT:
+ DBGCVAR_INIT_GC_FLAT(pResult, pAddress->FlatPtr);
+ break;
+
+ case DBGFADDRESS_FLAGS_PHYS:
+ DBGCVAR_INIT_GC_PHYS(pResult, pAddress->FlatPtr);
+ break;
+
+ default:
+ DBGCVAR_INIT(pResult);
+ AssertMsgFailedReturn(("%#x\n", pAddress->fFlags), VERR_INVALID_PARAMETER);
+ break;
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{DBGCCMDHLP,pfnVarToNumber}
+ */
+static DECLCALLBACK(int) dbgcHlpVarToNumber(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t *pu64Number)
+{
+ PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
+ NOREF(pDbgc);
+
+ uint64_t u64Number;
+ switch (pVar->enmType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ u64Number = pVar->u.GCFlat;
+ break;
+ case DBGCVAR_TYPE_GC_PHYS:
+ u64Number = pVar->u.GCPhys;
+ break;
+ case DBGCVAR_TYPE_HC_FLAT:
+ u64Number = (uintptr_t)pVar->u.pvHCFlat;
+ break;
+ case DBGCVAR_TYPE_HC_PHYS:
+ u64Number = (uintptr_t)pVar->u.HCPhys;
+ break;
+ case DBGCVAR_TYPE_NUMBER:
+ u64Number = (uintptr_t)pVar->u.u64Number;
+ return VINF_SUCCESS;
+ case DBGCVAR_TYPE_GC_FAR:
+ u64Number = (uintptr_t)pVar->u.GCFar.off;
+ break;
+ case DBGCVAR_TYPE_SYMBOL:
+ case DBGCVAR_TYPE_STRING:
+ return VERR_PARSE_INCORRECT_ARG_TYPE; /** @todo better error code! */
+ default:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+ }
+ *pu64Number = u64Number;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{DBGCCMDHLP,pfnVarToBool}
*/
static DECLCALLBACK(int) dbgcHlpVarToBool(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf)
{
@@ -781,7 +825,6 @@ static DECLCALLBACK(int) dbgcHlpVarToBool(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, b
*pf = pVar->u.u64Number != 0;
return VINF_SUCCESS;
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_GC_FAR:
case DBGCVAR_TYPE_SYMBOL:
default:
@@ -815,11 +858,353 @@ static DECLCALLBACK(int) dbgcHlpVarGetRange(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar,
/**
- * Info helper callback wrapper - print formatted string.
- *
- * @param pHlp Pointer to this structure.
- * @param pszFormat The format string.
- * @param ... Arguments.
+ * @interface_method_impl{DBGCCMDHLP,pfnVarConvert}
+ */
+static DECLCALLBACK(int) dbgcHlpVarConvert(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pInVar, DBGCVARTYPE enmToType, bool fConvSyms,
+ PDBGCVAR pResult)
+{
+ PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
+ DBGCVAR const InVar = *pInVar; /* if pInVar == pResult */
+ PCDBGCVAR pArg = &InVar; /* lazy bird, clean up later */
+ DBGFADDRESS Address;
+ int rc;
+
+ Assert(pDbgc->pVM);
+
+ *pResult = InVar;
+ switch (InVar.enmType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ switch (enmToType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_GC_FAR:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_GC_PHYS:
+ pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
+ rc = DBGFR3AddrToPhys(pDbgc->pVM, pDbgc->idCpu,
+ DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
+ &pResult->u.GCPhys);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_HC_FLAT:
+ pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
+ rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu,
+ DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
+ false /*fReadOnly */,
+ &pResult->u.pvHCFlat);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_HC_PHYS:
+ pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
+ rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu,
+ DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
+ &pResult->u.GCPhys);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_NUMBER:
+ pResult->enmType = enmToType;
+ pResult->u.u64Number = InVar.u.GCFlat;
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_STRING:
+ case DBGCVAR_TYPE_SYMBOL:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_UNKNOWN:
+ case DBGCVAR_TYPE_ANY:
+ break;
+ }
+ break;
+
+ case DBGCVAR_TYPE_GC_FAR:
+ switch (enmToType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
+ if (RT_SUCCESS(rc))
+ {
+ pResult->enmType = DBGCVAR_TYPE_GC_FLAT;
+ pResult->u.GCFlat = Address.FlatPtr;
+ return VINF_SUCCESS;
+ }
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_GC_FAR:
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_GC_PHYS:
+ rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
+ if (RT_SUCCESS(rc))
+ {
+ pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
+ rc = DBGFR3AddrToPhys(pDbgc->pVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ }
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_HC_FLAT:
+ rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
+ if (RT_SUCCESS(rc))
+ {
+ pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
+ rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu, &Address,
+ false /*fReadOnly*/, &pResult->u.pvHCFlat);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ }
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_HC_PHYS:
+ rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
+ if (RT_SUCCESS(rc))
+ {
+ pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
+ rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ }
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_NUMBER:
+ pResult->enmType = enmToType;
+ pResult->u.u64Number = InVar.u.GCFar.off;
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_STRING:
+ case DBGCVAR_TYPE_SYMBOL:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_UNKNOWN:
+ case DBGCVAR_TYPE_ANY:
+ break;
+ }
+ break;
+
+ case DBGCVAR_TYPE_GC_PHYS:
+ switch (enmToType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ //rc = MMR3PhysGCPhys2GCVirtEx(pDbgc->pVM, pResult->u.GCPhys, ..., &pResult->u.GCFlat); - yea, sure.
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_GC_FAR:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_GC_PHYS:
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_HC_FLAT:
+ pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
+ rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu,
+ DBGFR3AddrFromPhys(pDbgc->pVM, &Address, pArg->u.GCPhys),
+ false /*fReadOnly */,
+ &pResult->u.pvHCFlat);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_HC_PHYS:
+ pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
+ rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu,
+ DBGFR3AddrFromPhys(pDbgc->pVM, &Address, pArg->u.GCPhys),
+ &pResult->u.HCPhys);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_NUMBER:
+ pResult->enmType = enmToType;
+ pResult->u.u64Number = InVar.u.GCPhys;
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_STRING:
+ case DBGCVAR_TYPE_SYMBOL:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_UNKNOWN:
+ case DBGCVAR_TYPE_ANY:
+ break;
+ }
+ break;
+
+ case DBGCVAR_TYPE_HC_FLAT:
+ switch (enmToType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_GC_FAR:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_GC_PHYS:
+ pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
+ rc = PGMR3DbgR3Ptr2GCPhys(pDbgc->pVM, pArg->u.pvHCFlat, &pResult->u.GCPhys);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ /** @todo more memory types! */
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_HC_FLAT:
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_HC_PHYS:
+ pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
+ rc = PGMR3DbgR3Ptr2HCPhys(pDbgc->pVM, pArg->u.pvHCFlat, &pResult->u.HCPhys);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ /** @todo more memory types! */
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_NUMBER:
+ pResult->enmType = enmToType;
+ pResult->u.u64Number = (uintptr_t)InVar.u.pvHCFlat;
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_STRING:
+ case DBGCVAR_TYPE_SYMBOL:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_UNKNOWN:
+ case DBGCVAR_TYPE_ANY:
+ break;
+ }
+ break;
+
+ case DBGCVAR_TYPE_HC_PHYS:
+ switch (enmToType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_GC_FAR:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_GC_PHYS:
+ pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
+ rc = PGMR3DbgHCPhys2GCPhys(pDbgc->pVM, pArg->u.HCPhys, &pResult->u.GCPhys);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_HC_FLAT:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_HC_PHYS:
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_NUMBER:
+ pResult->enmType = enmToType;
+ pResult->u.u64Number = InVar.u.HCPhys;
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_STRING:
+ case DBGCVAR_TYPE_SYMBOL:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_UNKNOWN:
+ case DBGCVAR_TYPE_ANY:
+ break;
+ }
+ break;
+
+ case DBGCVAR_TYPE_NUMBER:
+ switch (enmToType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ pResult->enmType = DBGCVAR_TYPE_GC_FLAT;
+ pResult->u.GCFlat = (RTGCPTR)InVar.u.u64Number;
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_GC_FAR:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_GC_PHYS:
+ pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
+ pResult->u.GCPhys = (RTGCPHYS)InVar.u.u64Number;
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_HC_FLAT:
+ pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
+ pResult->u.pvHCFlat = (void *)(uintptr_t)InVar.u.u64Number;
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_HC_PHYS:
+ pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
+ pResult->u.HCPhys = (RTHCPHYS)InVar.u.u64Number;
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_NUMBER:
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_STRING:
+ case DBGCVAR_TYPE_SYMBOL:
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_UNKNOWN:
+ case DBGCVAR_TYPE_ANY:
+ break;
+ }
+ break;
+
+ case DBGCVAR_TYPE_SYMBOL:
+ case DBGCVAR_TYPE_STRING:
+ switch (enmToType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ case DBGCVAR_TYPE_GC_FAR:
+ case DBGCVAR_TYPE_GC_PHYS:
+ case DBGCVAR_TYPE_HC_FLAT:
+ case DBGCVAR_TYPE_HC_PHYS:
+ case DBGCVAR_TYPE_NUMBER:
+ if (fConvSyms)
+ {
+ rc = dbgcSymbolGet(pDbgc, InVar.u.pszString, enmToType, pResult);
+ if (RT_SUCCESS(rc))
+ {
+ if (InVar.enmRangeType != DBGCVAR_RANGE_NONE)
+ {
+ pResult->enmRangeType = InVar.enmRangeType;
+ pResult->u64Range = InVar.u64Range;
+ }
+ return VINF_SUCCESS;
+ }
+ }
+ return VERR_PARSE_INCORRECT_ARG_TYPE;
+
+ case DBGCVAR_TYPE_STRING:
+ case DBGCVAR_TYPE_SYMBOL:
+ pResult->enmType = enmToType;
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_UNKNOWN:
+ case DBGCVAR_TYPE_ANY:
+ break;
+ }
+ break;
+
+ case DBGCVAR_TYPE_UNKNOWN:
+ case DBGCVAR_TYPE_ANY:
+ break;
+ }
+
+ AssertMsgFailed(("f=%d t=%d\n", InVar.enmType, enmToType));
+ return VERR_INVALID_PARAMETER;
+}
+
+
+/**
+ * @interface_method_impl{DBGFINFOHLP,pfnPrintf}
*/
static DECLCALLBACK(void) dbgcHlpGetDbgfOutputHlp_Printf(PCDBGFINFOHLP pHlp, const char *pszFormat, ...)
{
@@ -832,11 +1217,7 @@ static DECLCALLBACK(void) dbgcHlpGetDbgfOutputHlp_Printf(PCDBGFINFOHLP pHlp, con
/**
- * Info helper callback wrapper - print formatted string.
- *
- * @param pHlp Pointer to this structure.
- * @param pszFormat The format string.
- * @param args Argument list.
+ * @interface_method_impl{DBGFINFOHLP,pfnPrintfV}
*/
static DECLCALLBACK(void) dbgcHlpGetDbgfOutputHlp_PrintfV(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list args)
{
@@ -870,7 +1251,7 @@ static DECLCALLBACK(PCDBGFINFOHLP) dbgcHlpGetDbgfOutputHlp(PDBGCCMDHLP pCmdHlp)
*/
void dbgcInitCmdHlp(PDBGC pDbgc)
{
- pDbgc->CmdHlp.pfnWrite = dbgcHlpWrite;
+ pDbgc->CmdHlp.u32Magic = DBGCCMDHLP_MAGIC;
pDbgc->CmdHlp.pfnPrintfV = dbgcHlpPrintfV;
pDbgc->CmdHlp.pfnPrintf = dbgcHlpPrintf;
pDbgc->CmdHlp.pfnVBoxErrorV = dbgcHlpVBoxErrorV;
@@ -880,9 +1261,14 @@ void dbgcInitCmdHlp(PDBGC pDbgc)
pDbgc->CmdHlp.pfnEvalV = dbgcHlpEvalV;
pDbgc->CmdHlp.pfnExec = dbgcHlpExec;
pDbgc->CmdHlp.pfnFailV = dbgcHlpFailV;
+ pDbgc->CmdHlp.pfnFailRcV = dbgcHlpFailRcV;
pDbgc->CmdHlp.pfnVarToDbgfAddr = dbgcHlpVarToDbgfAddr;
+ pDbgc->CmdHlp.pfnVarFromDbgfAddr = dbgcHlpVarFromDbgfAddr;
+ pDbgc->CmdHlp.pfnVarToNumber = dbgcHlpVarToNumber;
pDbgc->CmdHlp.pfnVarToBool = dbgcHlpVarToBool;
pDbgc->CmdHlp.pfnVarGetRange = dbgcHlpVarGetRange;
+ pDbgc->CmdHlp.pfnVarConvert = dbgcHlpVarConvert;
pDbgc->CmdHlp.pfnGetDbgfOutputHlp = dbgcHlpGetDbgfOutputHlp;
+ pDbgc->CmdHlp.u32EndMarker = DBGCCMDHLP_MAGIC;
}
diff --git a/src/VBox/Debugger/DBGCCmdWorkers.cpp b/src/VBox/Debugger/DBGCCmdWorkers.cpp
index bbb297248..87af63717 100644
--- a/src/VBox/Debugger/DBGCCmdWorkers.cpp
+++ b/src/VBox/Debugger/DBGCCmdWorkers.cpp
@@ -1,10 +1,10 @@
-/* $Id: DBGCCmdWorkers.cpp $ */
+/* $Id: DBGCCmdWorkers.cpp 35673 2011-01-24 10:15:44Z vboxsync $ */
/** @file
* DBGC - Debugger Console, Command Worker Routines.
*/
/*
- * 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;
@@ -21,220 +21,18 @@
#define LOG_GROUP LOG_GROUP_DBGC
#include <VBox/dbg.h>
#include <VBox/vmm/dbgf.h>
-#include <VBox/vmm/vm.h>
-#include <VBox/vmm/vmm.h>
-#include <VBox/vmm/mm.h>
-#include <VBox/vmm/pgm.h>
-#include <VBox/vmm/selm.h>
-#include <VBox/dis.h>
#include <VBox/param.h>
#include <VBox/err.h>
#include <VBox/log.h>
#include <iprt/alloc.h>
-#include <iprt/alloca.h>
#include <iprt/string.h>
#include <iprt/assert.h>
-#include <iprt/ctype.h>
#include "DBGCInternal.h"
-//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
-//
-//
-// V a r i a b l e M a n i p u l a t i o n
-//
-//
-//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
-
-
-
-/** @todo move me!*/
-void dbgcVarInit(PDBGCVAR pVar)
-{
- if (pVar)
- {
- memset(pVar, 0, sizeof(*pVar));
- AssertCompile(DBGCVAR_TYPE_UNKNOWN == 0);
- AssertCompile(DBGCVAR_RANGE_NONE == 0);
- }
-}
-
-
-/** @todo move me!*/
-void dbgcVarSetGCFlat(PDBGCVAR pVar, RTGCPTR GCFlat)
-{
- if (pVar)
- {
- pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
- memset(&pVar->u, 0, sizeof(pVar->u));
- pVar->u.GCFlat = GCFlat;
- pVar->enmRangeType = DBGCVAR_RANGE_NONE;
- pVar->u64Range = 0;
- }
-}
-
-
-/** @todo move me!*/
-void dbgcVarSetGCFlatByteRange(PDBGCVAR pVar, RTGCPTR GCFlat, uint64_t cb)
-{
- if (pVar)
- {
- pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
- memset(&pVar->u, 0, sizeof(pVar->u));
- pVar->u.GCFlat = GCFlat;
- pVar->enmRangeType = DBGCVAR_RANGE_BYTES;
- pVar->u64Range = cb;
- }
-}
-
-
-/** @todo move me!*/
-void dbgcVarSetU64(PDBGCVAR pVar, uint64_t u64)
-{
- if (pVar)
- {
- pVar->enmType = DBGCVAR_TYPE_NUMBER;
- memset(&pVar->u, 0, sizeof(pVar->u));
- pVar->u.u64Number = u64;
- pVar->enmRangeType = DBGCVAR_RANGE_NONE;
- pVar->u64Range = 0;
- }
-}
-
-
-/** @todo move me!*/
-void dbgcVarSetVar(PDBGCVAR pVar, PCDBGCVAR pVar2)
-{
- if (pVar)
- {
- if (pVar2)
- *pVar = *pVar2;
- else
- {
- pVar->enmType = DBGCVAR_TYPE_UNKNOWN;
- memset(&pVar->u, 0, sizeof(pVar->u));
- pVar->enmRangeType = DBGCVAR_RANGE_NONE;
- pVar->u64Range = 0;
- }
- }
-}
-
-/** @todo move me!*/
-void dbgcVarSetDbgfAddr(PDBGCVAR pVar, PCDBGFADDRESS pAddress)
-{
- if (pVar)
- {
- memset(&pVar->u, 0, sizeof(pVar->u));
-
- Assert(!pAddress || DBGFADDRESS_IS_VALID(pAddress));
- if (pAddress && DBGFADDRESS_IS_VALID(pAddress))
- {
- switch (pAddress->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK)
- {
- case DBGFADDRESS_FLAGS_FAR16:
- case DBGFADDRESS_FLAGS_FAR32:
- case DBGFADDRESS_FLAGS_FAR64:
- pVar->enmType = DBGCVAR_TYPE_GC_FAR;
- pVar->u.GCFar.off = pAddress->off;
- pVar->u.GCFar.sel = pAddress->Sel;
- break;
-
- case DBGFADDRESS_FLAGS_FLAT:
- pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
- pVar->u.GCFlat = pAddress->FlatPtr;
- break;
-
- case DBGFADDRESS_FLAGS_PHYS:
- pVar->enmType = DBGCVAR_TYPE_GC_PHYS;
- pVar->u.GCPhys = pAddress->FlatPtr;
- break;
-
- default:
- AssertFailed();
- pVar->enmType = DBGCVAR_TYPE_UNKNOWN;
- break;
- }
- }
- else
- pVar->enmType = DBGCVAR_TYPE_UNKNOWN;
- pVar->enmRangeType = DBGCVAR_RANGE_NONE;
- pVar->u64Range = 0;
- }
-}
-
-
-/** @todo move me!*/
-void dbgcVarSetByteRange(PDBGCVAR pVar, uint64_t cb)
-{
- if (pVar)
- {
- pVar->enmRangeType = DBGCVAR_RANGE_BYTES;
- pVar->u64Range = cb;
- }
-}
-
-
-/** @todo move me!*/
-void dbgcVarSetNoRange(PDBGCVAR pVar)
-{
- if (pVar)
- {
- pVar->enmRangeType = DBGCVAR_RANGE_NONE;
- pVar->u64Range = 0;
- }
-}
-
-
-/**
- * Converts a DBGC variable to a DBGF address.
- *
- * @returns VBox status code.
- * @param pDbgc The DBGC instance.
- * @param pVar The variable.
- * @param pAddress Where to store the address.
- */
-int dbgcVarToDbgfAddr(PDBGC pDbgc, PCDBGCVAR pVar, PDBGFADDRESS pAddress)
-{
- AssertReturn(pVar, VERR_INVALID_PARAMETER);
- switch (pVar->enmType)
- {
- case DBGCVAR_TYPE_GC_FLAT:
- DBGFR3AddrFromFlat(pDbgc->pVM, pAddress, pVar->u.GCFlat);
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_NUMBER:
- DBGFR3AddrFromFlat(pDbgc->pVM, pAddress, (RTGCUINTPTR)pVar->u.u64Number);
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_GC_FAR:
- return DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, pAddress, pVar->u.GCFar.sel, pVar->u.GCFar.off);
-
- case DBGCVAR_TYPE_GC_PHYS:
- DBGFR3AddrFromPhys(pDbgc->pVM, pAddress, pVar->u.GCPhys);
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_STRING:
- case DBGCVAR_TYPE_SYMBOL:
- {
- DBGCVAR Var;
- int rc = DBGCCmdHlpEval(&pDbgc->CmdHlp, &Var, "%%(%DV)", pVar);
- if (RT_FAILURE(rc))
- return rc;
- return dbgcVarToDbgfAddr(pDbgc, &Var, pAddress);
- }
-
- case DBGCVAR_TYPE_HC_FLAT:
- case DBGCVAR_TYPE_HC_FAR:
- case DBGCVAR_TYPE_HC_PHYS:
- default:
- return VERR_PARSE_CONVERSION_FAILED;
- }
-}
-
-
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
//
@@ -383,7 +181,7 @@ PDBGCBP dbgcBpGet(PDBGC pDbgc, RTUINT iBp)
* @returns VINF_DBGC_BP_NO_COMMAND if there is no command associated with the breakpoint.
* @returns VERR_DBGC_BP_NOT_FOUND if the breakpoint wasn't found.
* @returns VERR_BUFFER_OVERFLOW if the is not enough space in the scratch buffer for the command.
- * @returns VBox status code from dbgcProcessCommand() other wise.
+ * @returns VBox status code from dbgcEvalCommand() otherwise.
* @param pDbgc The DBGC instance.
* @param iBp The breakpoint to execute.
*/
@@ -419,7 +217,7 @@ int dbgcBpExec(PDBGC pDbgc, RTUINT iBp)
/* Execute the command. */
pDbgc->pszScratch = pDbgc->pszScratch + pBp->cchCmd + 1;
- int rc = dbgcProcessCommand(pDbgc, pszScratch, pBp->cchCmd, false /* fNoExecute */);
+ int rc = dbgcEvalCommand(pDbgc, pszScratch, pBp->cchCmd, false /* fNoExecute */);
/* Restore the scratch state. */
pDbgc->iArg = iArg;
diff --git a/src/VBox/Debugger/DBGCCommands.cpp b/src/VBox/Debugger/DBGCCommands.cpp
index 07f487f3b..543f6b1d6 100644
--- a/src/VBox/Debugger/DBGCCommands.cpp
+++ b/src/VBox/Debugger/DBGCCommands.cpp
@@ -1,10 +1,10 @@
-/* $Id: DBGCCommands.cpp $ */
+/* $Id: DBGCCommands.cpp 35696 2011-01-24 18:03:33Z vboxsync $ */
/** @file
* DBGC - Debugger Console, Native Commands.
*/
/*
- * 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;
@@ -22,11 +22,6 @@
#include <VBox/dbg.h>
#include <VBox/vmm/dbgf.h>
#include <VBox/vmm/vm.h>
-#include <VBox/vmm/vmm.h>
-#include <VBox/vmm/mm.h>
-#include <VBox/vmm/pgm.h>
-#include <VBox/vmm/selm.h>
-#include <VBox/dis.h>
#include <VBox/param.h>
#include <VBox/err.h>
#include <VBox/log.h>
@@ -51,31 +46,31 @@
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
-static DECLCALLBACK(int) dbgcCmdHelp(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdQuit(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdStop(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdDetect(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdCpu(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdInfo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdLog(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdLogDest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdLogFlags(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdFormat(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdLoadImage(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdLoadMap(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdLoadSeg(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdLoadSyms(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdSet(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdUnset(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdLoadVars(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdShowVars(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdLoadPlugIn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdUnloadPlugIn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdShowPlugIns(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdHarakiri(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdEcho(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdRunScript(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdWriteCore(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
+static DECLCALLBACK(int) dbgcCmdHelp(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdQuit(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdStop(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdDetect(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdCpu(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdInfo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdLog(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdLogDest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdLogFlags(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdFormat(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdLoadImage(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdLoadMap(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdLoadSeg(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdLoadSyms(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdSet(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdUnset(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdLoadVars(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdShowVars(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdLoadPlugIn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdUnloadPlugIn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdShowPlugIns(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdHarakiri(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdEcho(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdRunScript(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdWriteCore(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
/*******************************************************************************
@@ -226,42 +221,42 @@ static const DBGCVARDESC g_aArgWriteCore[] =
/** Command descriptors for the basic commands. */
const DBGCCMD g_aCmds[] =
{
- /* pszCmd, cArgsMin, cArgsMax, paArgDescs, cArgDescs, pResultDesc,fFlags,pfnHandler pszSyntax, ....pszDescription */
- { "bye", 0, 0, NULL, 0, NULL, 0, dbgcCmdQuit, "", "Exits the debugger." },
- { "cpu", 0, 1, &g_aArgCpu[0], RT_ELEMENTS(g_aArgCpu), NULL, 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),NULL, 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, NULL, 0, dbgcCmdQuit, "", "Exits the debugger." },
- { "format", 1, 1, &g_aArgAny[0], RT_ELEMENTS(g_aArgAny), NULL, 0, dbgcCmdFormat, "", "Evaluates an expression and formats it." },
- { "detect", 0, 0, NULL, 0, NULL, 0, dbgcCmdDetect, "", "Detects or re-detects the guest os and starts the OS specific digger." },
- { "harakiri", 0, 0, NULL, 0, NULL, 0, dbgcCmdHarakiri, "", "Kills debugger process." },
- { "help", 0, ~0, &g_aArgHelp[0], RT_ELEMENTS(g_aArgHelp), NULL, 0, dbgcCmdHelp, "[cmd/op [..]]", "Display help. For help about info items try 'info help'." },
- { "info", 1, 2, &g_aArgInfo[0], RT_ELEMENTS(g_aArgInfo), NULL, 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),NULL, 0, dbgcCmdLoadImage, "<filename> <address> [name]",
- "Loads the symbols of an executable image at the specified address. "
- /*"Optionally giving the module a name other than the file name stem."*/ }, /** @todo implement line breaks */
- { "loadmap", 2, 5, &g_aArgLoadMap[0], RT_ELEMENTS(g_aArgLoadMap), NULL, 0, dbgcCmdLoadMap, "<filename> <address> [name] [subtrahend] [seg]",
- "Loads the symbols from a map file, usually at a specified address. "
- /*"Optionally giving the module a name other than the file name stem "
- "and a subtrahend to subtract from the addresses."*/ },
- { "loadplugin", 1, 1, &g_aArgPlugIn[0], RT_ELEMENTS(g_aArgPlugIn), NULL, 0, dbgcCmdLoadPlugIn,"<plugin1> [plugin2..N]", "Loads one or more plugins" },
- { "loadseg", 3, 4, &g_aArgLoadSeg[0], RT_ELEMENTS(g_aArgLoadSeg), NULL, 0, dbgcCmdLoadSeg, "<filename> <address> <seg> [name]",
- "Loads the symbols of a segment in the executable image at the specified address. "
- /*"Optionally giving the module a name other than the file name stem."*/ },
- { "loadsyms", 1, 5, &g_aArgLoadSyms[0], RT_ELEMENTS(g_aArgLoadSyms),NULL, 0, dbgcCmdLoadSyms, "<filename> [delta] [module] [module address]", "Loads symbols from a text file. Optionally giving a delta and a module." },
- { "loadvars", 1, 1, &g_aArgFilename[0], RT_ELEMENTS(g_aArgFilename),NULL, 0, dbgcCmdLoadVars, "<filename>", "Load variables from file. One per line, same as the args to the set command." },
- { "log", 1, 1, &g_aArgLog[0], RT_ELEMENTS(g_aArgLog), NULL, 0, dbgcCmdLog, "<group string>", "Modifies the logging group settings (VBOX_LOG)" },
- { "logdest", 1, 1, &g_aArgLogDest[0], RT_ELEMENTS(g_aArgLogDest), NULL, 0, dbgcCmdLogDest, "<dest string>", "Modifies the logging destination (VBOX_LOG_DEST)." },
- { "logflags", 1, 1, &g_aArgLogFlags[0], RT_ELEMENTS(g_aArgLogFlags),NULL, 0, dbgcCmdLogFlags, "<flags string>", "Modifies the logging flags (VBOX_LOG_FLAGS)." },
- { "quit", 0, 0, NULL, 0, NULL, 0, dbgcCmdQuit, "", "Exits the debugger." },
- { "runscript", 1, 1, &g_aArgFilename[0], RT_ELEMENTS(g_aArgFilename),NULL, 0, dbgcCmdRunScript, "<filename>", "Runs the command listed in the script. Lines starting with '#' "
- "(after removing blanks) are comment. blank lines are ignored. Stops on failure." },
- { "set", 2, 2, &g_aArgSet[0], RT_ELEMENTS(g_aArgSet), NULL, 0, dbgcCmdSet, "<var> <value>", "Sets a global variable." },
- { "showplugins",0, 0, NULL, 0, NULL, 0, dbgcCmdShowPlugIns,"", "List loaded plugins." },
- { "showvars", 0, 0, NULL, 0, NULL, 0, dbgcCmdShowVars, "", "List all the defined variables." },
- { "stop", 0, 0, NULL, 0, NULL, 0, dbgcCmdStop, "", "Stop execution." },
- { "unloadplugin", 1, ~0, &g_aArgPlugIn[0], RT_ELEMENTS(g_aArgPlugIn), NULL, 0, dbgcCmdUnloadPlugIn, "<plugin1> [plugin2..N]", "Unloads one or more plugins." },
- { "unset", 1, ~0, &g_aArgMultiStr[0], RT_ELEMENTS(g_aArgMultiStr),NULL, 0, dbgcCmdUnset, "<var1> [var1..[varN]]", "Unsets (delete) one or more global variables." },
- { "writecore", 1, 1, &g_aArgWriteCore[0], RT_ELEMENTS(g_aArgWriteCore), NULL, 0, dbgcCmdWriteCore, "<filename>", "Write core to file." },
+ /* 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." },
+ { "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'." },
+ { "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. "
+ /*"Optionally giving the module a name other than the file name stem."*/ }, /** @todo implement line breaks */
+ { "loadmap", 2, 5, &g_aArgLoadMap[0], RT_ELEMENTS(g_aArgLoadMap), 0, dbgcCmdLoadMap, "<filename> <address> [name] [subtrahend] [seg]",
+ "Loads the symbols from a map file, usually at a specified address. "
+ /*"Optionally giving the module a name other than the file name stem "
+ "and a subtrahend to subtract from the addresses."*/ },
+ { "loadplugin", 1, 1, &g_aArgPlugIn[0], RT_ELEMENTS(g_aArgPlugIn), 0, dbgcCmdLoadPlugIn,"<plugin1> [plugin2..N]", "Loads one or more plugins" },
+ { "loadseg", 3, 4, &g_aArgLoadSeg[0], RT_ELEMENTS(g_aArgLoadSeg), 0, dbgcCmdLoadSeg, "<filename> <address> <seg> [name]",
+ "Loads the symbols of a segment in the executable image at the specified address. "
+ /*"Optionally giving the module a name other than the file name stem."*/ },
+ { "loadsyms", 1, 5, &g_aArgLoadSyms[0], RT_ELEMENTS(g_aArgLoadSyms), 0, dbgcCmdLoadSyms, "<filename> [delta] [module] [module address]", "Loads symbols from a text file. Optionally giving a delta and a module." },
+ { "loadvars", 1, 1, &g_aArgFilename[0], RT_ELEMENTS(g_aArgFilename), 0, dbgcCmdLoadVars, "<filename>", "Load variables from file. One per line, same as the args to the set command." },
+ { "log", 1, 1, &g_aArgLog[0], RT_ELEMENTS(g_aArgLog), 0, dbgcCmdLog, "<group string>", "Modifies the logging group settings (VBOX_LOG)" },
+ { "logdest", 1, 1, &g_aArgLogDest[0], RT_ELEMENTS(g_aArgLogDest), 0, dbgcCmdLogDest, "<dest string>", "Modifies the logging destination (VBOX_LOG_DEST)." },
+ { "logflags", 1, 1, &g_aArgLogFlags[0], RT_ELEMENTS(g_aArgLogFlags), 0, dbgcCmdLogFlags, "<flags string>", "Modifies the logging flags (VBOX_LOG_FLAGS)." },
+ { "quit", 0, 0, NULL, 0, 0, dbgcCmdQuit, "", "Exits the debugger." },
+ { "runscript", 1, 1, &g_aArgFilename[0], RT_ELEMENTS(g_aArgFilename), 0, dbgcCmdRunScript, "<filename>", "Runs the command listed in the script. Lines starting with '#' "
+ "(after removing blanks) are comment. blank lines are ignored. Stops on failure." },
+ { "set", 2, 2, &g_aArgSet[0], RT_ELEMENTS(g_aArgSet), 0, dbgcCmdSet, "<var> <value>", "Sets a global variable." },
+ { "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." },
+ { "writecore", 1, 1, &g_aArgWriteCore[0], RT_ELEMENTS(g_aArgWriteCore), 0, dbgcCmdWriteCore, "<filename>", "Write core to file." },
};
/** The number of native commands. */
@@ -487,7 +482,7 @@ static int dbgcPrintHelp(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, bool fExternal)
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdHelp(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdHelp(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
int rc = VINF_SUCCESS;
@@ -627,7 +622,6 @@ static DECLCALLBACK(int) dbgcCmdHelp(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pV
NOREF(pCmd);
NOREF(pVM);
- NOREF(pResult);
return rc;
}
@@ -642,14 +636,13 @@ static DECLCALLBACK(int) dbgcCmdHelp(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdQuit(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdQuit(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Quitting console...\n");
NOREF(pCmd);
NOREF(pVM);
NOREF(paArgs);
NOREF(cArgs);
- NOREF(pResult);
return VERR_DBGC_QUIT;
}
@@ -664,7 +657,7 @@ static DECLCALLBACK(int) dbgcCmdQuit(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdStop(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdStop(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Check if the VM is halted or not before trying to halt it.
@@ -681,7 +674,7 @@ static DECLCALLBACK(int) dbgcCmdStop(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pV
rc = pCmdHlp->pfnVBoxError(pCmdHlp, rc, "Executing DBGFR3Halt().");
}
- NOREF(pCmd); NOREF(paArgs); NOREF(cArgs); NOREF(pResult);
+ NOREF(pCmd); NOREF(paArgs); NOREF(cArgs);
return rc;
}
@@ -696,7 +689,7 @@ static DECLCALLBACK(int) dbgcCmdStop(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdEcho(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdEcho(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Loop thru the arguments and print them with one space between.
@@ -711,7 +704,7 @@ static DECLCALLBACK(int) dbgcCmdEcho(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pV
if (RT_FAILURE(rc))
return rc;
}
- NOREF(pCmd); NOREF(pResult); NOREF(pVM);
+ NOREF(pCmd); NOREF(pVM);
return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "\n");
}
@@ -726,13 +719,16 @@ static DECLCALLBACK(int) dbgcCmdEcho(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdRunScript(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdRunScript(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/* check that the parser did what it's supposed to do. */
if ( cArgs != 1
|| paArgs[0].enmType != DBGCVAR_TYPE_STRING)
return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "parser error\n");
+ /** @todo Load the script here, but someone else should do the actual
+ * evaluation and execution of it. */
+
/*
* Try open the script.
*/
@@ -796,7 +792,7 @@ static DECLCALLBACK(int) dbgcCmdRunScript(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
fclose(pFile);
- NOREF(pCmd); NOREF(pResult); NOREF(pVM);
+ NOREF(pCmd); NOREF(pVM);
return rc;
}
@@ -811,7 +807,7 @@ static DECLCALLBACK(int) dbgcCmdRunScript(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdDetect(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdDetect(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/* check that the parser did what it's supposed to do. */
if (cArgs != 0)
@@ -834,7 +830,7 @@ static DECLCALLBACK(int) dbgcCmdDetect(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
}
else
rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Unable to figure out which guest OS it is, sorry.\n");
- NOREF(pCmd); NOREF(pResult); NOREF(paArgs);
+ NOREF(pCmd); NOREF(paArgs);
return rc;
}
@@ -849,7 +845,7 @@ static DECLCALLBACK(int) dbgcCmdDetect(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdCpu(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdCpu(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -866,6 +862,7 @@ static DECLCALLBACK(int) dbgcCmdCpu(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM
rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Current CPU ID: %u\n", pDbgc->idCpu);
else
{
+/** @todo add a DBGF getter for this. */
if (paArgs[0].u.u64Number >= pVM->cCpus)
rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: idCpu %u is out of range! Highest ID is %u.\n",
paArgs[0].u.u64Number, pVM->cCpus);
@@ -890,7 +887,7 @@ static DECLCALLBACK(int) dbgcCmdCpu(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdInfo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdInfo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -908,13 +905,14 @@ static DECLCALLBACK(int) dbgcCmdInfo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pV
/*
* Dump it.
*/
+ /** @todo DBGFR3Info should do this, not we. */
int rc = VMR3ReqCallWait(pVM, pDbgc->idCpu, (PFNRT)DBGFR3Info, 4,
pVM, paArgs[0].u.pszString, cArgs == 2 ? paArgs[1].u.pszString : NULL,
DBGCCmdHlpGetDbgfOutputHlp(pCmdHlp));
if (RT_FAILURE(rc))
return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3Info()\n");
- NOREF(pCmd); NOREF(pResult);
+ NOREF(pCmd);
return 0;
}
@@ -929,12 +927,12 @@ static DECLCALLBACK(int) dbgcCmdInfo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdLog(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdLog(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
int rc = DBGFR3LogModifyGroups(pVM, paArgs[0].u.pszString);
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
- NOREF(pCmd); NOREF(cArgs); NOREF(pResult);
+ NOREF(pCmd); NOREF(cArgs);
return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3LogModifyGroups(%p,'%s')\n", pVM, paArgs[0].u.pszString);
}
@@ -949,12 +947,12 @@ static DECLCALLBACK(int) dbgcCmdLog(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdLogDest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdLogDest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
int rc = DBGFR3LogModifyDestinations(pVM, paArgs[0].u.pszString);
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
- NOREF(pCmd); NOREF(cArgs); NOREF(pResult);
+ NOREF(pCmd); NOREF(cArgs);
return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3LogModifyDestinations(%p,'%s')\n", pVM, paArgs[0].u.pszString);
}
@@ -969,12 +967,12 @@ static DECLCALLBACK(int) dbgcCmdLogDest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdLogFlags(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdLogFlags(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
int rc = DBGFR3LogModifyFlags(pVM, paArgs[0].u.pszString);
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
- NOREF(pCmd); NOREF(cArgs); NOREF(pResult);
+ NOREF(pCmd); NOREF(cArgs);
return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3LogModifyFlags(%p,'%s')\n", pVM, paArgs[0].u.pszString);
}
@@ -989,7 +987,7 @@ static DECLCALLBACK(int) dbgcCmdLogFlags(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdFormat(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdFormat(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
LogFlow(("dbgcCmdFormat\n"));
static const char *apszRangeDesc[] =
@@ -1056,20 +1054,6 @@ static DECLCALLBACK(int) dbgcCmdFormat(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
"Host flat address: %%%08x\n",
paArgs[iArg].u.pvHCFlat);
break;
- case DBGCVAR_TYPE_HC_FAR:
- if (paArgs[iArg].enmRangeType != DBGCVAR_RANGE_NONE)
- rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL,
- "Host far address: %04x:%08x range %lld %s\n",
- paArgs[iArg].u.HCFar.sel,
- paArgs[iArg].u.HCFar.off,
- paArgs[iArg].u64Range,
- apszRangeDesc[paArgs[iArg].enmRangeType]);
- else
- rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL,
- "Host far address: %04x:%08x\n",
- paArgs[iArg].u.HCFar.sel,
- paArgs[iArg].u.HCFar.off);
- break;
case DBGCVAR_TYPE_HC_PHYS:
if (paArgs[iArg].enmRangeType != DBGCVAR_RANGE_NONE)
rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL,
@@ -1115,7 +1099,7 @@ static DECLCALLBACK(int) dbgcCmdFormat(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
}
} /* arg loop */
- NOREF(pCmd); NOREF(pVM); NOREF(pResult);
+ NOREF(pCmd); NOREF(pVM);
return 0;
}
@@ -1130,7 +1114,7 @@ static DECLCALLBACK(int) dbgcCmdFormat(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdLoadImage(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdLoadImage(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate the parsing and make sense of the input.
@@ -1165,7 +1149,7 @@ static DECLCALLBACK(int) dbgcCmdLoadImage(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3ModuleLoadImage(,,'%s','%s',%Dv,)\n",
pszFilename, pszModName, &paArgs[1]);
- NOREF(pCmd); NOREF(pResult);
+ NOREF(pCmd);
return VINF_SUCCESS;
}
@@ -1180,7 +1164,7 @@ static DECLCALLBACK(int) dbgcCmdLoadImage(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdLoadMap(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdLoadMap(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate the parsing and make sense of the input.
@@ -1232,7 +1216,7 @@ static DECLCALLBACK(int) dbgcCmdLoadMap(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3AsLoadMap(,,'%s','%s',%Dv,)\n",
pszFilename, pszModName, &paArgs[1]);
- NOREF(pCmd); NOREF(pResult);
+ NOREF(pCmd);
return VINF_SUCCESS;
}
@@ -1247,7 +1231,7 @@ static DECLCALLBACK(int) dbgcCmdLoadMap(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdLoadSeg(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdLoadSeg(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate the parsing and make sense of the input.
@@ -1288,7 +1272,7 @@ static DECLCALLBACK(int) dbgcCmdLoadSeg(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3ModuleLoadImage(,,'%s','%s',%Dv,)\n",
pszFilename, pszModName, &paArgs[1]);
- NOREF(pCmd); NOREF(pResult);
+ NOREF(pCmd);
return VINF_SUCCESS;
}
@@ -1303,7 +1287,7 @@ static DECLCALLBACK(int) dbgcCmdLoadSeg(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdLoadSyms(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdLoadSyms(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate the parsing and make sense of the input.
@@ -1376,7 +1360,7 @@ static DECLCALLBACK(int) dbgcCmdLoadSyms(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGInfoSymbolLoad(, '%s', %RGv, '%s', %RGv, 0)\n",
paArgs[0].u.pszString, Delta, pszModule, ModuleAddress);
- NOREF(pCmd); NOREF(pResult);
+ NOREF(pCmd);
return VINF_SUCCESS;
}
@@ -1391,7 +1375,7 @@ static DECLCALLBACK(int) dbgcCmdLoadSyms(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdSet(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdSet(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -1470,7 +1454,7 @@ static DECLCALLBACK(int) dbgcCmdSet(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM
}
pDbgc->papVars[pDbgc->cVars++] = pVar;
- NOREF(pCmd); NOREF(pVM); NOREF(cArgs); NOREF(pResult);
+ NOREF(pCmd); NOREF(pVM); NOREF(cArgs);
return 0;
}
@@ -1485,7 +1469,7 @@ static DECLCALLBACK(int) dbgcCmdSet(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdUnset(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdUnset(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -1528,7 +1512,7 @@ static DECLCALLBACK(int) dbgcCmdUnset(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM p
} /* lookup */
} /* arg loop */
- NOREF(pCmd); NOREF(pVM); NOREF(pResult);
+ NOREF(pCmd); NOREF(pVM);
return 0;
}
@@ -1543,7 +1527,7 @@ static DECLCALLBACK(int) dbgcCmdUnset(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM p
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdLoadVars(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdLoadVars(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Don't trust the parser.
@@ -1585,7 +1569,7 @@ static DECLCALLBACK(int) dbgcCmdLoadVars(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
else
return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Failed to open file '%s'.\n", paArgs[0].u.pszString);
- NOREF(pCmd); NOREF(pVM); NOREF(pResult);
+ NOREF(pCmd); NOREF(pVM);
return 0;
}
@@ -1600,7 +1584,7 @@ static DECLCALLBACK(int) dbgcCmdLoadVars(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdShowVars(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdShowVars(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -1608,12 +1592,12 @@ static DECLCALLBACK(int) dbgcCmdShowVars(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
{
int rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%-20s ", &pDbgc->papVars[iVar]->szName);
if (!rc)
- rc = dbgcCmdFormat(pCmd, pCmdHlp, pVM, &pDbgc->papVars[iVar]->Var, 1, NULL);
+ rc = dbgcCmdFormat(pCmd, pCmdHlp, pVM, &pDbgc->papVars[iVar]->Var, 1);
if (rc)
return rc;
}
- NOREF(paArgs); NOREF(cArgs); NOREF(pResult);
+ NOREF(paArgs); NOREF(cArgs);
return 0;
}
@@ -1925,7 +1909,7 @@ void dbgcPlugInAutoLoad(PDBGC pDbgc)
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdLoadPlugIn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdLoadPlugIn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -1992,7 +1976,7 @@ void dbgcPlugInUnloadAll(PDBGC pDbgc)
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdUnloadPlugIn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdUnloadPlugIn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -2044,7 +2028,7 @@ static DECLCALLBACK(int) dbgcCmdUnloadPlugIn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdShowPlugIns(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdShowPlugIns(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
PDBGCPLUGIN pPlugIn = pDbgc->pPlugInHead;
@@ -2074,12 +2058,12 @@ static DECLCALLBACK(int) dbgcCmdShowPlugIns(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdHarakiri(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdHarakiri(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
Log(("dbgcCmdHarakiri\n"));
for (;;)
exit(126);
- NOREF(pCmd); NOREF(pCmdHlp); NOREF(pVM); NOREF(paArgs); NOREF(cArgs); NOREF(pResult);
+ NOREF(pCmd); NOREF(pCmdHlp); NOREF(pVM); NOREF(paArgs); NOREF(cArgs);
}
@@ -2093,7 +2077,7 @@ static DECLCALLBACK(int) dbgcCmdHarakiri(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdWriteCore(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdWriteCore(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
Log(("dbgcCmdWriteCore\n"));
diff --git a/src/VBox/Debugger/DBGCEmulateCodeView.cpp b/src/VBox/Debugger/DBGCEmulateCodeView.cpp
index d67a6e2bf..7fcc363b4 100644
--- a/src/VBox/Debugger/DBGCEmulateCodeView.cpp
+++ b/src/VBox/Debugger/DBGCEmulateCodeView.cpp
@@ -1,10 +1,10 @@
-/* $Id: DBGCEmulateCodeView.cpp $ */
+/* $Id: DBGCEmulateCodeView.cpp 36640 2011-04-11 11:44:08Z vboxsync $ */
/** @file
* DBGC - Debugger Console, CodeView / WinDbg Emulation.
*/
/*
- * 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;
@@ -22,7 +22,6 @@
#include <VBox/dbg.h>
#include <VBox/vmm/dbgf.h>
#include <VBox/vmm/pgm.h>
-#include <VBox/vmm/selm.h>
#include <VBox/vmm/cpum.h>
#include <VBox/dis.h>
#include <VBox/param.h>
@@ -30,7 +29,6 @@
#include <VBox/log.h>
#include <iprt/asm.h>
-#include <iprt/alloca.h>
#include <iprt/mem.h>
#include <iprt/string.h>
#include <iprt/assert.h>
@@ -45,37 +43,37 @@
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
-static DECLCALLBACK(int) dbgcCmdBrkAccess(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdBrkClear(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdBrkDisable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdBrkEnable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdBrkList(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdBrkSet(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdBrkREM(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdDumpMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdDumpDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdDumpIDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdDumpPageDir(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdDumpPageDirBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdDumpPageHierarchy(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdDumpPageTable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdDumpPageTableBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdDumpTSS(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdEditMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdGo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdListModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdListNear(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdListSource(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdMemoryInfo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdReg(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdRegGuest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdRegHyper(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdRegTerse(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdSearchMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdSearchMemType(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdStack(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdTrace(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcCmdUnassemble(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
+static DECLCALLBACK(int) dbgcCmdBrkAccess(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdBrkClear(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdBrkDisable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdBrkEnable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdBrkList(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdBrkSet(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdBrkREM(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdDumpMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdDumpDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdDumpIDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdDumpPageDir(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdDumpPageDirBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdDumpPageHierarchy(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdDumpPageTable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdDumpPageTableBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdDumpTSS(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdEditMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdGo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdListModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdListNear(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdListSource(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdMemoryInfo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdReg(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdRegGuest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdRegHyper(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdRegTerse(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdSearchMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdSearchMemType(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdStack(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdTrace(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) dbgcCmdUnassemble(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
/*******************************************************************************
@@ -227,12 +225,6 @@ static const DBGCVARDESC g_aArgListNear[] =
{ 0, ~0, DBGCVAR_CAT_SYMBOL, 0, "symbol", "Symbol to lookup." },
};
-/** 'ln' return. */
-static const DBGCVARDESC g_RetListNear =
-{
- 1, 1, DBGCVAR_CAT_POINTER, 0, "address", "The last resolved symbol/address with adjusted range."
-};
-
/** 'ls' arguments. */
static const DBGCVARDESC g_aArgListSource[] =
@@ -297,81 +289,81 @@ static const DBGCVARDESC g_aArgUnassemble[] =
*/
const DBGCCMD g_aCmdsCodeView[] =
{
- /* pszCmd, cArgsMin, cArgsMax, paArgDescs, cArgDescs, pResultDesc, fFlags, pfnHandler pszSyntax, ....pszDescription */
- { "ba", 3, 6, &g_aArgBrkAcc[0], RT_ELEMENTS(g_aArgBrkAcc), NULL, 0, dbgcCmdBrkAccess, "<access> <size> <address> [passes [max passes]] [cmds]",
- "Sets a data access breakpoint." },
- { "bc", 1, ~0, &g_aArgBrks[0], RT_ELEMENTS(g_aArgBrks), NULL, 0, dbgcCmdBrkClear, "all | <bp#> [bp# []]", "Enabled a set of breakpoints." },
- { "bd", 1, ~0, &g_aArgBrks[0], RT_ELEMENTS(g_aArgBrks), NULL, 0, dbgcCmdBrkDisable, "all | <bp#> [bp# []]", "Disables a set of breakpoints." },
- { "be", 1, ~0, &g_aArgBrks[0], RT_ELEMENTS(g_aArgBrks), NULL, 0, dbgcCmdBrkEnable, "all | <bp#> [bp# []]", "Enabled a set of breakpoints." },
- { "bl", 0, 0, NULL, 0, NULL, 0, dbgcCmdBrkList, "", "Lists all the breakpoints." },
- { "bp", 1, 4, &g_aArgBrkSet[0], RT_ELEMENTS(g_aArgBrkSet), NULL, 0, dbgcCmdBrkSet, "<address> [passes [max passes]] [cmds]",
- "Sets a breakpoint (int 3)." },
- { "br", 1, 4, &g_aArgBrkREM[0], RT_ELEMENTS(g_aArgBrkREM), NULL, 0, dbgcCmdBrkREM, "<address> [passes [max passes]] [cmds]",
- "Sets a recompiler specific breakpoint." },
- { "d", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), NULL, 0, dbgcCmdDumpMem, "[addr]", "Dump memory using last element size." },
- { "da", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), NULL, 0, dbgcCmdDumpMem, "[addr]", "Dump memory as ascii string." },
- { "db", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), NULL, 0, dbgcCmdDumpMem, "[addr]", "Dump memory in bytes." },
- { "dd", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), NULL, 0, dbgcCmdDumpMem, "[addr]", "Dump memory in double words." },
- { "da", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), NULL, 0, dbgcCmdDumpMem, "[addr]", "Dump memory as ascii string." },
- { "dg", 0, ~0, &g_aArgDumpDT[0], RT_ELEMENTS(g_aArgDumpDT), NULL, 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the global descriptor table (GDT)." },
- { "dga", 0, ~0, &g_aArgDumpDT[0], RT_ELEMENTS(g_aArgDumpDT), NULL, 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the global descriptor table (GDT) including not-present entries." },
- { "di", 0, ~0, &g_aArgDumpIDT[0], RT_ELEMENTS(g_aArgDumpIDT), NULL, 0, dbgcCmdDumpIDT, "[int [..]]", "Dump the interrupt descriptor table (IDT)." },
- { "dia", 0, ~0, &g_aArgDumpIDT[0], RT_ELEMENTS(g_aArgDumpIDT), NULL, 0, dbgcCmdDumpIDT, "[int [..]]", "Dump the interrupt descriptor table (IDT) including not-present entries." },
- { "dl", 0, ~0, &g_aArgDumpDT[0], RT_ELEMENTS(g_aArgDumpDT), NULL, 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the local descriptor table (LDT)." },
- { "dla", 0, ~0, &g_aArgDumpDT[0], RT_ELEMENTS(g_aArgDumpDT), NULL, 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the local descriptor table (LDT) including not-present entries." },
- { "dpd", 0, 1, &g_aArgDumpPD[0], RT_ELEMENTS(g_aArgDumpPD), NULL, 0, dbgcCmdDumpPageDir, "[addr] [index]", "Dumps page directory entries of the default context." },
- { "dpda", 0, 1, &g_aArgDumpPDAddr[0],RT_ELEMENTS(g_aArgDumpPDAddr),NULL, 0, dbgcCmdDumpPageDir, "[addr]", "Dumps specified page directory." },
- { "dpdb", 1, 1, &g_aArgDumpPD[0], RT_ELEMENTS(g_aArgDumpPD), NULL, 0, dbgcCmdDumpPageDirBoth, "[addr] [index]", "Dumps page directory entries of the guest and the hypervisor. " },
- { "dpdg", 0, 1, &g_aArgDumpPD[0], RT_ELEMENTS(g_aArgDumpPD), NULL, 0, dbgcCmdDumpPageDir, "[addr] [index]", "Dumps page directory entries of the guest." },
- { "dpdh", 0, 1, &g_aArgDumpPD[0], RT_ELEMENTS(g_aArgDumpPD), NULL, 0, dbgcCmdDumpPageDir, "[addr] [index]", "Dumps page directory entries of the hypervisor. " },
- { "dph", 0, 3, &g_aArgDumpPH[0], RT_ELEMENTS(g_aArgDumpPH), NULL, 0, dbgcCmdDumpPageHierarchy, "[addr [cr3 [mode]]", "Dumps the paging hierarchy at for specfied address range. Default context." },
- { "dphg", 0, 3, &g_aArgDumpPH[0], RT_ELEMENTS(g_aArgDumpPH), NULL, 0, dbgcCmdDumpPageHierarchy, "[addr [cr3 [mode]]", "Dumps the paging hierarchy at for specfied address range. Guest context." },
- { "dphh", 0, 3, &g_aArgDumpPH[0], RT_ELEMENTS(g_aArgDumpPH), NULL, 0, dbgcCmdDumpPageHierarchy, "[addr [cr3 [mode]]", "Dumps the paging hierarchy at for specfied address range. Hypervisor context." },
- { "dpt", 1, 1, &g_aArgDumpPT[0], RT_ELEMENTS(g_aArgDumpPT), NULL, 0, dbgcCmdDumpPageTable,"<addr>", "Dumps page table entries of the default context." },
- { "dpta", 1, 1, &g_aArgDumpPTAddr[0],RT_ELEMENTS(g_aArgDumpPTAddr), NULL, 0, dbgcCmdDumpPageTable,"<addr>", "Dumps specified page table." },
- { "dptb", 1, 1, &g_aArgDumpPT[0], RT_ELEMENTS(g_aArgDumpPT), NULL, 0, dbgcCmdDumpPageTableBoth,"<addr>", "Dumps page table entries of the guest and the hypervisor." },
- { "dptg", 1, 1, &g_aArgDumpPT[0], RT_ELEMENTS(g_aArgDumpPT), NULL, 0, dbgcCmdDumpPageTable,"<addr>", "Dumps page table entries of the guest." },
- { "dpth", 1, 1, &g_aArgDumpPT[0], RT_ELEMENTS(g_aArgDumpPT), NULL, 0, dbgcCmdDumpPageTable,"<addr>", "Dumps page table entries of the hypervisor." },
- { "dq", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), NULL, 0, dbgcCmdDumpMem, "[addr]", "Dump memory in quad words." },
- { "dt", 0, 1, &g_aArgDumpTSS[0], RT_ELEMENTS(g_aArgDumpTSS), NULL, 0, dbgcCmdDumpTSS, "[tss|tss:ign|addr]", "Dump the task state segment (TSS)." },
- { "dt16", 0, 1, &g_aArgDumpTSS[0], RT_ELEMENTS(g_aArgDumpTSS), NULL, 0, dbgcCmdDumpTSS, "[tss|tss:ign|addr]", "Dump the 16-bit task state segment (TSS)." },
- { "dt32", 0, 1, &g_aArgDumpTSS[0], RT_ELEMENTS(g_aArgDumpTSS), NULL, 0, dbgcCmdDumpTSS, "[tss|tss:ign|addr]", "Dump the 32-bit task state segment (TSS)." },
- { "dt64", 0, 1, &g_aArgDumpTSS[0], RT_ELEMENTS(g_aArgDumpTSS), NULL, 0, dbgcCmdDumpTSS, "[tss|tss:ign|addr]", "Dump the 64-bit task state segment (TSS)." },
- { "dw", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), NULL, 0, dbgcCmdDumpMem, "[addr]", "Dump memory in words." },
+ /* 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." },
+ { "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)." },
+ { "br", 1, 4, &g_aArgBrkREM[0], RT_ELEMENTS(g_aArgBrkREM), 0, dbgcCmdBrkREM, "<address> [passes [max passes]] [cmds]",
+ "Sets a recompiler specific breakpoint." },
+ { "d", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), 0, dbgcCmdDumpMem, "[addr]", "Dump memory using last element size." },
+ { "da", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), 0, dbgcCmdDumpMem, "[addr]", "Dump memory as ascii string." },
+ { "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." },
+ { "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. " },
+ { "dpdg", 0, 1, &g_aArgDumpPD[0], RT_ELEMENTS(g_aArgDumpPD), 0, dbgcCmdDumpPageDir, "[addr] [index]", "Dumps page directory entries of the guest." },
+ { "dpdh", 0, 1, &g_aArgDumpPD[0], RT_ELEMENTS(g_aArgDumpPD), 0, dbgcCmdDumpPageDir, "[addr] [index]", "Dumps page directory entries of the hypervisor. " },
+ { "dph", 0, 3, &g_aArgDumpPH[0], RT_ELEMENTS(g_aArgDumpPH), 0, dbgcCmdDumpPageHierarchy, "[addr [cr3 [mode]]", "Dumps the paging hierarchy at for specfied address range. Default context." },
+ { "dphg", 0, 3, &g_aArgDumpPH[0], RT_ELEMENTS(g_aArgDumpPH), 0, dbgcCmdDumpPageHierarchy, "[addr [cr3 [mode]]", "Dumps the paging hierarchy at for specfied address range. Guest context." },
+ { "dphh", 0, 3, &g_aArgDumpPH[0], RT_ELEMENTS(g_aArgDumpPH), 0, dbgcCmdDumpPageHierarchy, "[addr [cr3 [mode]]", "Dumps the paging hierarchy at for specfied address range. Hypervisor context." },
+ { "dpt", 1, 1, &g_aArgDumpPT[0], RT_ELEMENTS(g_aArgDumpPT), 0, dbgcCmdDumpPageTable,"<addr>", "Dumps page table entries of the default context." },
+ { "dpta", 1, 1, &g_aArgDumpPTAddr[0],RT_ELEMENTS(g_aArgDumpPTAddr), 0, dbgcCmdDumpPageTable,"<addr>", "Dumps specified page table." },
+ { "dptb", 1, 1, &g_aArgDumpPT[0], RT_ELEMENTS(g_aArgDumpPT), 0, dbgcCmdDumpPageTableBoth,"<addr>", "Dumps page table entries of the guest and the hypervisor." },
+ { "dptg", 1, 1, &g_aArgDumpPT[0], RT_ELEMENTS(g_aArgDumpPT), 0, dbgcCmdDumpPageTable,"<addr>", "Dumps page table entries of the guest." },
+ { "dpth", 1, 1, &g_aArgDumpPT[0], RT_ELEMENTS(g_aArgDumpPT), 0, dbgcCmdDumpPageTable,"<addr>", "Dumps page table entries of the hypervisor." },
+ { "dq", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), 0, dbgcCmdDumpMem, "[addr]", "Dump memory in quad words." },
+ { "dt", 0, 1, &g_aArgDumpTSS[0], RT_ELEMENTS(g_aArgDumpTSS), 0, dbgcCmdDumpTSS, "[tss|tss:ign|addr]", "Dump the task state segment (TSS)." },
+ { "dt16", 0, 1, &g_aArgDumpTSS[0], RT_ELEMENTS(g_aArgDumpTSS), 0, dbgcCmdDumpTSS, "[tss|tss:ign|addr]", "Dump the 16-bit task state segment (TSS)." },
+ { "dt32", 0, 1, &g_aArgDumpTSS[0], RT_ELEMENTS(g_aArgDumpTSS), 0, dbgcCmdDumpTSS, "[tss|tss:ign|addr]", "Dump the 32-bit task state segment (TSS)." },
+ { "dt64", 0, 1, &g_aArgDumpTSS[0], RT_ELEMENTS(g_aArgDumpTSS), 0, dbgcCmdDumpTSS, "[tss|tss:ign|addr]", "Dump the 64-bit task state segment (TSS)." },
+ { "dw", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), 0, dbgcCmdDumpMem, "[addr]", "Dump memory in words." },
/** @todo add 'e', 'ea str', 'eza str', 'eu str' and 'ezu str'. See also
* dbgcCmdSearchMem and its dbgcVarsToBytes usage. */
- { "eb", 2, 2, &g_aArgEditMem[0], RT_ELEMENTS(g_aArgEditMem), NULL, 0, dbgcCmdEditMem, "<addr> <value>", "Write a 1-byte value to memory." },
- { "ew", 2, 2, &g_aArgEditMem[0], RT_ELEMENTS(g_aArgEditMem), NULL, 0, dbgcCmdEditMem, "<addr> <value>", "Write a 2-byte value to memory." },
- { "ed", 2, 2, &g_aArgEditMem[0], RT_ELEMENTS(g_aArgEditMem), NULL, 0, dbgcCmdEditMem, "<addr> <value>", "Write a 4-byte value to memory." },
- { "eq", 2, 2, &g_aArgEditMem[0], RT_ELEMENTS(g_aArgEditMem), NULL, 0, dbgcCmdEditMem, "<addr> <value>", "Write a 8-byte value to memory." },
- { "g", 0, 0, NULL, 0, NULL, 0, dbgcCmdGo, "", "Continue execution." },
- { "k", 0, 0, NULL, 0, NULL, 0, dbgcCmdStack, "", "Callstack." },
- { "kg", 0, 0, NULL, 0, NULL, 0, dbgcCmdStack, "", "Callstack - guest." },
- { "kh", 0, 0, NULL, 0, NULL, 0, dbgcCmdStack, "", "Callstack - hypervisor." },
- { "lm", 0, ~0, &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods), NULL, 0, dbgcCmdListModules, "[module [..]]", "List modules." },
- { "lmo", 0, ~0, &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods), NULL, 0, dbgcCmdListModules, "[module [..]]", "List modules and their segments." },
- { "ln", 0, ~0, &g_aArgListNear[0], RT_ELEMENTS(g_aArgListNear), &g_RetListNear, 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),NULL, 0, dbgcCmdListSource, "[addr]", "Source." },
- { "m", 1, 1, &g_aArgMemoryInfo[0],RT_ELEMENTS(g_aArgMemoryInfo),NULL, 0, dbgcCmdMemoryInfo, "<addr>", "Display information about that piece of memory." },
- { "r", 0, 2, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), NULL, 0, dbgcCmdReg, "[reg [newval]]", "Show or set register(s) - active reg set." },
- { "rg", 0, 2, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), NULL, 0, dbgcCmdRegGuest, "[reg [newval]]", "Show or set register(s) - guest reg set." },
- { "rg32", 0, 0, NULL, 0, NULL, 0, dbgcCmdRegGuest, "", "Show 32-bit guest registers." },
- { "rg64", 0, 0, NULL, 0, NULL, 0, dbgcCmdRegGuest, "", "Show 64-bit guest registers." },
- { "rh", 0, 2, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), NULL, 0, dbgcCmdRegHyper, "[reg [newval]]", "Show or set register(s) - hypervisor reg set." },
- { "rt", 0, 0, NULL, 0, NULL, 0, dbgcCmdRegTerse, "", "Toggles terse / verbose register info." },
- { "s", 0, ~0, &g_aArgSearchMem[0], RT_ELEMENTS(g_aArgSearchMem), NULL, 0, dbgcCmdSearchMem, "[options] <range> <pattern>", "Continue last search." },
- { "sa", 2, ~0, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType), NULL, 0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for an ascii string." },
- { "sb", 2, ~0, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType), NULL, 0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for one or more bytes." },
- { "sd", 2, ~0, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType), NULL, 0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for one or more double words." },
- { "sq", 2, ~0, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType), NULL, 0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for one or more quad words." },
- { "su", 2, ~0, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType), NULL, 0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for an unicode string." },
- { "sw", 2, ~0, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType), NULL, 0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for one or more words." },
- { "t", 0, 0, NULL, 0, NULL, 0, dbgcCmdTrace, "", "Instruction trace (step into)." },
- { "u", 0, 1, &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble),NULL, 0, dbgcCmdUnassemble, "[addr]", "Unassemble." },
- { "u64", 0, 1, &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble),NULL, 0, dbgcCmdUnassemble, "[addr]", "Unassemble 64-bit code." },
- { "u32", 0, 1, &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble),NULL, 0, dbgcCmdUnassemble, "[addr]", "Unassemble 32-bit code." },
- { "u16", 0, 1, &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble),NULL, 0, dbgcCmdUnassemble, "[addr]", "Unassemble 16-bit code." },
- { "uv86", 0, 1, &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble),NULL, 0, dbgcCmdUnassemble, "[addr]", "Unassemble 16-bit code with v8086/real mode addressing." },
+ { "eb", 2, 2, &g_aArgEditMem[0], RT_ELEMENTS(g_aArgEditMem), 0, dbgcCmdEditMem, "<addr> <value>", "Write a 1-byte value to memory." },
+ { "ew", 2, 2, &g_aArgEditMem[0], RT_ELEMENTS(g_aArgEditMem), 0, dbgcCmdEditMem, "<addr> <value>", "Write a 2-byte value to memory." },
+ { "ed", 2, 2, &g_aArgEditMem[0], RT_ELEMENTS(g_aArgEditMem), 0, dbgcCmdEditMem, "<addr> <value>", "Write a 4-byte value to memory." },
+ { "eq", 2, 2, &g_aArgEditMem[0], RT_ELEMENTS(g_aArgEditMem), 0, dbgcCmdEditMem, "<addr> <value>", "Write a 8-byte value to memory." },
+ { "g", 0, 0, NULL, 0, 0, dbgcCmdGo, "", "Continue execution." },
+ { "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." },
+ { "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." },
+ { "rg", 0, 2, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdRegGuest, "[reg [newval]]", "Show or set register(s) - guest reg set." },
+ { "rg32", 0, 0, NULL, 0, 0, dbgcCmdRegGuest, "", "Show 32-bit guest registers." },
+ { "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." },
+ { "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." },
+ { "u32", 0, 1, &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble), 0, dbgcCmdUnassemble, "[addr]", "Unassemble 32-bit code." },
+ { "u16", 0, 1, &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble), 0, dbgcCmdUnassemble, "[addr]", "Unassemble 16-bit code." },
+ { "uv86", 0, 1, &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble), 0, dbgcCmdUnassemble, "[addr]", "Unassemble 16-bit code with v8086/real mode addressing." },
};
/** The number of commands in the CodeView/WinDbg emulation. */
@@ -389,25 +381,22 @@ const unsigned g_cCmdsCodeView = RT_ELEMENTS(g_aCmdsCodeView);
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdGo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdGo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
+
/*
* Check if the VM is halted or not before trying to resume it.
*/
if (!DBGFR3IsHalted(pVM))
- pCmdHlp->pfnPrintf(pCmdHlp, NULL, "warning: The VM is already running...\n");
- else
- {
- int rc = DBGFR3Resume(pVM);
- if (RT_FAILURE(rc))
- return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "Executing DBGFR3Resume().");
- }
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "The VM is already running");
- NOREF(pCmd);
- NOREF(paArgs);
- NOREF(cArgs);
- NOREF(pResult);
- return 0;
+ int rc = DBGFR3Resume(pVM);
+ if (RT_FAILURE(rc))
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGFR3Resume");
+
+ NOREF(paArgs); NOREF(cArgs);
+ return VINF_SUCCESS;
}
@@ -421,15 +410,17 @@ static DECLCALLBACK(int) dbgcCmdGo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM,
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdBrkAccess(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR /*pResult*/)
+static DECLCALLBACK(int) dbgcCmdBrkAccess(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
+
/*
* Interpret access type.
*/
if ( !strchr("xrwi", paArgs[0].u.pszString[0])
|| paArgs[0].u.pszString[1])
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Invalid access type '%s' for '%s'. Valid types are 'e', 'r', 'w' and 'i'.\n",
- paArgs[0].u.pszString, pCmd->pszCmd);
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "Invalid access type '%s' for '%s'. Valid types are 'e', 'r', 'w' and 'i'",
+ paArgs[0].u.pszString, pCmd->pszCmd);
uint8_t fType = 0;
switch (paArgs[0].u.pszString[0])
{
@@ -443,8 +434,8 @@ static DECLCALLBACK(int) dbgcCmdBrkAccess(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
* Validate size.
*/
if (fType == X86_DR7_RW_EO && paArgs[1].u.u64Number != 1)
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Invalid access size %RX64 for '%s'. 'x' access type requires size 1!\n",
- paArgs[1].u.u64Number, pCmd->pszCmd);
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "Invalid access size %RX64 for '%s'. 'x' access type requires size 1!",
+ paArgs[1].u.u64Number, pCmd->pszCmd);
switch (paArgs[1].u.u64Number)
{
case 1:
@@ -453,8 +444,8 @@ static DECLCALLBACK(int) dbgcCmdBrkAccess(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
break;
/*case 8: - later*/
default:
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Invalid access size %RX64 for '%s'. 1, 2 or 4!\n",
- paArgs[1].u.u64Number, pCmd->pszCmd);
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "Invalid access size %RX64 for '%s'. 1, 2 or 4!",
+ paArgs[1].u.u64Number, pCmd->pszCmd);
}
uint8_t cb = (uint8_t)paArgs[1].u.u64Number;
@@ -462,9 +453,9 @@ static DECLCALLBACK(int) dbgcCmdBrkAccess(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
* Convert the pointer to a DBGF address.
*/
DBGFADDRESS Address;
- int rc = pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, &paArgs[2], &Address);
+ int rc = DBGCCmdHlpVarToDbgfAddr(pCmdHlp, &paArgs[2], &Address);
if (RT_FAILURE(rc))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Couldn't convert '%DV' to a DBGF address, rc=%Rrc.\n", &paArgs[2], rc);
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGCCmdHlpVarToDbgfAddr(,%DV,)", &paArgs[2]);
/*
* Pick out the optional arguments.
@@ -492,24 +483,24 @@ static DECLCALLBACK(int) dbgcCmdBrkAccess(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
/*
* Try set the breakpoint.
*/
- RTUINT iBp;
+ uint32_t iBp;
rc = DBGFR3BpSetReg(pVM, &Address, iHitTrigger, iHitDisable, fType, cb, &iBp);
if (RT_SUCCESS(rc))
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
rc = dbgcBpAdd(pDbgc, iBp, pszCmds);
if (RT_SUCCESS(rc))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Set access breakpoint %u at %RGv\n", iBp, Address.FlatPtr);
+ return DBGCCmdHlpPrintf(pCmdHlp, "Set access breakpoint %u at %RGv\n", iBp, Address.FlatPtr);
if (rc == VERR_DBGC_BP_EXISTS)
{
rc = dbgcBpUpdate(pDbgc, iBp, pszCmds);
if (RT_SUCCESS(rc))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Updated access breakpoint %u at %RGv\n", iBp, Address.FlatPtr);
+ return DBGCCmdHlpPrintf(pCmdHlp, "Updated access breakpoint %u at %RGv\n", iBp, Address.FlatPtr);
}
int rc2 = DBGFR3BpClear(pDbgc->pVM, iBp);
AssertRC(rc2);
}
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Failed to set access breakpoint at %RGv, rc=%Rrc.\n", Address.FlatPtr, rc);
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "Failed to set access breakpoint at %RGv", Address.FlatPtr);
}
@@ -523,29 +514,31 @@ static DECLCALLBACK(int) dbgcCmdBrkAccess(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdBrkClear(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR /*pResult*/)
+static DECLCALLBACK(int) dbgcCmdBrkClear(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
+
/*
* Enumerate the arguments.
*/
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
- int rc = VINF_SUCCESS;
+ int rc = VINF_SUCCESS;
for (unsigned iArg = 0; iArg < cArgs && RT_SUCCESS(rc); iArg++)
{
if (paArgs[iArg].enmType != DBGCVAR_TYPE_STRING)
{
/* one */
- RTUINT iBp = (RTUINT)paArgs[iArg].u.u64Number;
- if (iBp != paArgs[iArg].u.u64Number)
+ uint32_t iBp = (uint32_t)paArgs[iArg].u.u64Number;
+ if (iBp == paArgs[iArg].u.u64Number)
{
- rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Breakpoint id %RX64 is too large!\n", paArgs[iArg].u.u64Number);
- break;
+ int rc2 = DBGFR3BpClear(pVM, iBp);
+ if (RT_FAILURE(rc2))
+ rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc2, "DBGFR3BpClear(,%#x)", iBp);
+ if (RT_SUCCESS(rc2) || rc2 == VERR_DBGF_BP_NOT_FOUND)
+ dbgcBpDelete(pDbgc, iBp);
}
- int rc2 = DBGFR3BpClear(pVM, iBp);
- if (RT_FAILURE(rc2))
- rc = pCmdHlp->pfnVBoxError(pCmdHlp, rc2, "DBGFR3BpClear failed for breakpoint %u!\n", iBp);
- if (RT_SUCCESS(rc2) || rc2 == VERR_DBGF_BP_NOT_FOUND)
- dbgcBpDelete(pDbgc, iBp);
+ else
+ rc = DBGCCmdHlpFail(pCmdHlp, pCmd, "Breakpoint id %RX64 is too large", paArgs[iArg].u.u64Number);
}
else if (!strcmp(paArgs[iArg].u.pszString, "all"))
{
@@ -553,22 +546,18 @@ static DECLCALLBACK(int) dbgcCmdBrkClear(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
PDBGCBP pBp = pDbgc->pFirstBp;
while (pBp)
{
- RTUINT iBp = pBp->iBp;
+ uint32_t iBp = pBp->iBp;
pBp = pBp->pNext;
int rc2 = DBGFR3BpClear(pVM, iBp);
if (RT_FAILURE(rc2))
- rc = pCmdHlp->pfnVBoxError(pCmdHlp, rc2, "DBGFR3BpClear failed for breakpoint %u!\n", iBp);
+ rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc2, "DBGFR3BpClear(,%#x)", iBp);
if (RT_SUCCESS(rc2) || rc2 == VERR_DBGF_BP_NOT_FOUND)
dbgcBpDelete(pDbgc, iBp);
}
}
else
- {
- /* invalid parameter */
- rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Invalid argument '%s' to '%s'!\n", paArgs[iArg].u.pszString, pCmd->pszCmd);
- break;
- }
+ rc = DBGCCmdHlpFail(pCmdHlp, pCmd, "Invalid argument '%s'", paArgs[iArg].u.pszString);
}
return rc;
}
@@ -584,7 +573,7 @@ static DECLCALLBACK(int) dbgcCmdBrkClear(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdBrkDisable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR /*pResult*/)
+static DECLCALLBACK(int) dbgcCmdBrkDisable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Enumerate the arguments.
@@ -595,15 +584,15 @@ static DECLCALLBACK(int) dbgcCmdBrkDisable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
if (paArgs[iArg].enmType != DBGCVAR_TYPE_STRING)
{
/* one */
- RTUINT iBp = (RTUINT)paArgs[iArg].u.u64Number;
- if (iBp != paArgs[iArg].u.u64Number)
+ uint32_t iBp = (uint32_t)paArgs[iArg].u.u64Number;
+ if (iBp == paArgs[iArg].u.u64Number)
{
- rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Breakpoint id %RX64 is too large!\n", paArgs[iArg].u.u64Number);
- break;
+ rc = DBGFR3BpDisable(pVM, iBp);
+ if (RT_FAILURE(rc))
+ rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGFR3BpDisable failed for breakpoint %#x", iBp);
}
- rc = DBGFR3BpDisable(pVM, iBp);
- if (RT_FAILURE(rc))
- rc = pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3BpDisable failed for breakpoint %u!\n", iBp);
+ else
+ rc = DBGCCmdHlpFail(pCmdHlp, pCmd, "Breakpoint id %RX64 is too large", paArgs[iArg].u.u64Number);
}
else if (!strcmp(paArgs[iArg].u.pszString, "all"))
{
@@ -611,17 +600,13 @@ static DECLCALLBACK(int) dbgcCmdBrkDisable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
for (PDBGCBP pBp = pDbgc->pFirstBp; pBp; pBp = pBp->pNext)
{
- rc = DBGFR3BpDisable(pVM, pBp->iBp);
- if (RT_FAILURE(rc))
- rc = pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3BpDisable failed for breakpoint %u!\n", pBp->iBp);
+ int rc2 = DBGFR3BpDisable(pVM, pBp->iBp);
+ if (RT_FAILURE(rc2))
+ rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc2, "DBGFR3BpDisable failed for breakpoint %#x", pBp->iBp);
}
}
else
- {
- /* invalid parameter */
- rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Invalid argument '%s' to '%s'!\n", paArgs[iArg].u.pszString, pCmd->pszCmd);
- break;
- }
+ rc = DBGCCmdHlpFail(pCmdHlp, pCmd, "Invalid argument '%s'", paArgs[iArg].u.pszString);
}
return rc;
}
@@ -637,8 +622,10 @@ static DECLCALLBACK(int) dbgcCmdBrkDisable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdBrkEnable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR /*pResult*/)
+static DECLCALLBACK(int) dbgcCmdBrkEnable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
+
/*
* Enumerate the arguments.
*/
@@ -648,15 +635,15 @@ static DECLCALLBACK(int) dbgcCmdBrkEnable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
if (paArgs[iArg].enmType != DBGCVAR_TYPE_STRING)
{
/* one */
- RTUINT iBp = (RTUINT)paArgs[iArg].u.u64Number;
- if (iBp != paArgs[iArg].u.u64Number)
+ uint32_t iBp = (uint32_t)paArgs[iArg].u.u64Number;
+ if (iBp == paArgs[iArg].u.u64Number)
{
- rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Breakpoint id %RX64 is too large!\n", paArgs[iArg].u.u64Number);
- break;
+ rc = DBGFR3BpEnable(pVM, iBp);
+ if (RT_FAILURE(rc))
+ rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGFR3BpEnable failed for breakpoint %#x", iBp);
}
- rc = DBGFR3BpEnable(pVM, iBp);
- if (RT_FAILURE(rc))
- rc = pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3BpEnable failed for breakpoint %u!\n", iBp);
+ else
+ rc = DBGCCmdHlpFail(pCmdHlp, pCmd, "Breakpoint id %RX64 is too large", paArgs[iArg].u.u64Number);
}
else if (!strcmp(paArgs[iArg].u.pszString, "all"))
{
@@ -664,17 +651,13 @@ static DECLCALLBACK(int) dbgcCmdBrkEnable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
for (PDBGCBP pBp = pDbgc->pFirstBp; pBp; pBp = pBp->pNext)
{
- rc = DBGFR3BpEnable(pVM, pBp->iBp);
- if (RT_FAILURE(rc))
- rc = pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3BpEnable failed for breakpoint %u!\n", pBp->iBp);
+ int rc2 = DBGFR3BpEnable(pVM, pBp->iBp);
+ if (RT_FAILURE(rc2))
+ rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc2, "DBGFR3BpEnable failed for breakpoint %#x", pBp->iBp);
}
}
else
- {
- /* invalid parameter */
- rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Invalid argument '%s' to '%s'!\n", paArgs[iArg].u.pszString, pCmd->pszCmd);
- break;
- }
+ rc = DBGCCmdHlpFail(pCmdHlp, pCmd, "Invalid argument '%s'", paArgs[iArg].u.pszString);
}
return rc;
}
@@ -690,7 +673,7 @@ static DECLCALLBACK(int) dbgcCmdBrkEnable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
*/
static DECLCALLBACK(int) dbgcEnumBreakpointsCallback(PVM pVM, void *pvUser, PCDBGFBP pBp)
{
- PDBGC pDbgc = (PDBGC)pvUser;
+ PDBGC pDbgc = (PDBGC)pvUser;
PDBGCBP pDbgcBp = dbgcBpGet(pDbgc, pBp->iBp);
/*
@@ -723,13 +706,13 @@ static DECLCALLBACK(int) dbgcEnumBreakpointsCallback(PVM pVM, void *pvUser, PCDB
break;
}
- pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "%2u %c %d %c %RGv %04RX64 (%04RX64 to ",
- pBp->iBp, pBp->fEnabled ? 'e' : 'd', cb, chType,
- pBp->GCPtr, pBp->cHits, pBp->iHitTrigger);
+ DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%4#x %c %d %c %RGv %04RX64 (%04RX64 to ",
+ pBp->iBp, pBp->fEnabled ? 'e' : 'd', cb, chType,
+ pBp->GCPtr, pBp->cHits, pBp->iHitTrigger);
if (pBp->iHitDisable == ~(uint64_t)0)
- pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "~0) ");
+ DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "~0) ");
else
- pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "%04RX64)");
+ DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%04RX64)");
/*
* Try resolve the address.
@@ -741,11 +724,11 @@ static DECLCALLBACK(int) dbgcEnumBreakpointsCallback(PVM pVM, void *pvUser, PCDB
if (RT_SUCCESS(rc))
{
if (!off)
- pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "%s", Sym.szName);
+ DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%s", Sym.szName);
else if (off > 0)
- pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "%s+%RGv", Sym.szName, off);
+ DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%s+%RGv", Sym.szName, off);
else
- pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "%s+%RGv", Sym.szName, -off);
+ DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%s+%RGv", Sym.szName, -off);
}
/*
@@ -754,13 +737,12 @@ static DECLCALLBACK(int) dbgcEnumBreakpointsCallback(PVM pVM, void *pvUser, PCDB
if (pDbgcBp)
{
if (pDbgcBp->cchCmd)
- pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "\n cmds: '%s'\n",
- pDbgcBp->szCmd);
+ DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "\n cmds: '%s'\n", pDbgcBp->szCmd);
else
- pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "\n");
+ DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "\n");
}
else
- pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, " [unknown bp]\n");
+ DBGCCmdHlpPrintf(&pDbgc->CmdHlp, " [unknown bp]\n");
return VINF_SUCCESS;
}
@@ -776,16 +758,18 @@ static DECLCALLBACK(int) dbgcEnumBreakpointsCallback(PVM pVM, void *pvUser, PCDB
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdBrkList(PCDBGCCMD /*pCmd*/, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR /*paArgs*/, unsigned /*cArgs*/, PDBGCVAR /*pResult*/)
+static DECLCALLBACK(int) dbgcCmdBrkList(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR /*paArgs*/, unsigned cArgs)
{
- PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
+ DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs == 0);
/*
* Enumerate the breakpoints.
*/
+ PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
int rc = DBGFR3BpEnum(pVM, dbgcEnumBreakpointsCallback, pDbgc);
if (RT_FAILURE(rc))
- return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3BpEnum failed.\n");
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGFR3BpEnum");
return rc;
}
@@ -800,15 +784,15 @@ static DECLCALLBACK(int) dbgcCmdBrkList(PCDBGCCMD /*pCmd*/, PDBGCCMDHLP pCmdHlp,
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdBrkSet(PCDBGCCMD /*pCmd*/, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR /*pResult*/)
+static DECLCALLBACK(int) dbgcCmdBrkSet(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Convert the pointer to a DBGF address.
*/
DBGFADDRESS Address;
- int rc = pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, &paArgs[0], &Address);
+ int rc = DBGCCmdHlpVarToDbgfAddr(pCmdHlp, &paArgs[0], &Address);
if (RT_FAILURE(rc))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Couldn't convert '%DV' to a DBGF address, rc=%Rrc.\n", &paArgs[0], rc);
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGCCmdHlpVarToDbgfAddr(,'%DV',)", &paArgs[0]);
/*
* Pick out the optional arguments.
@@ -836,24 +820,24 @@ static DECLCALLBACK(int) dbgcCmdBrkSet(PCDBGCCMD /*pCmd*/, PDBGCCMDHLP pCmdHlp,
/*
* Try set the breakpoint.
*/
- RTUINT iBp;
+ uint32_t iBp;
rc = DBGFR3BpSet(pVM, &Address, iHitTrigger, iHitDisable, &iBp);
if (RT_SUCCESS(rc))
{
- PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
+ PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
rc = dbgcBpAdd(pDbgc, iBp, pszCmds);
if (RT_SUCCESS(rc))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Set breakpoint %u at %RGv\n", iBp, Address.FlatPtr);
+ return DBGCCmdHlpPrintf(pCmdHlp, "Set breakpoint %u at %RGv\n", iBp, Address.FlatPtr);
if (rc == VERR_DBGC_BP_EXISTS)
{
rc = dbgcBpUpdate(pDbgc, iBp, pszCmds);
if (RT_SUCCESS(rc))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Updated breakpoint %u at %RGv\n", iBp, Address.FlatPtr);
+ return DBGCCmdHlpPrintf(pCmdHlp, "Updated breakpoint %u at %RGv\n", iBp, Address.FlatPtr);
}
int rc2 = DBGFR3BpClear(pDbgc->pVM, iBp);
AssertRC(rc2);
}
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Failed to set breakpoint at %RGv, rc=%Rrc.\n", Address.FlatPtr, rc);
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "Failed to set breakpoint at %RGv", Address.FlatPtr);
}
@@ -867,15 +851,15 @@ static DECLCALLBACK(int) dbgcCmdBrkSet(PCDBGCCMD /*pCmd*/, PDBGCCMDHLP pCmdHlp,
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdBrkREM(PCDBGCCMD /*pCmd*/, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR /*pResult*/)
+static DECLCALLBACK(int) dbgcCmdBrkREM(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Convert the pointer to a DBGF address.
*/
DBGFADDRESS Address;
- int rc = pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, &paArgs[0], &Address);
+ int rc = DBGCCmdHlpVarToDbgfAddr(pCmdHlp, &paArgs[0], &Address);
if (RT_FAILURE(rc))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Couldn't convert '%DV' to a DBGF address, rc=%Rrc.\n", &paArgs[0], rc);
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGCCmdHlpVarToDbgfAddr(,'%DV',)", &paArgs[0]);
/*
* Pick out the optional arguments.
@@ -903,24 +887,24 @@ static DECLCALLBACK(int) dbgcCmdBrkREM(PCDBGCCMD /*pCmd*/, PDBGCCMDHLP pCmdHlp,
/*
* Try set the breakpoint.
*/
- RTUINT iBp;
+ uint32_t iBp;
rc = DBGFR3BpSetREM(pVM, &Address, iHitTrigger, iHitDisable, &iBp);
if (RT_SUCCESS(rc))
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
rc = dbgcBpAdd(pDbgc, iBp, pszCmds);
if (RT_SUCCESS(rc))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Set REM breakpoint %u at %RGv\n", iBp, Address.FlatPtr);
+ return DBGCCmdHlpPrintf(pCmdHlp, "Set REM breakpoint %u at %RGv\n", iBp, Address.FlatPtr);
if (rc == VERR_DBGC_BP_EXISTS)
{
rc = dbgcBpUpdate(pDbgc, iBp, pszCmds);
if (RT_SUCCESS(rc))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Updated REM breakpoint %u at %RGv\n", iBp, Address.FlatPtr);
+ return DBGCCmdHlpPrintf(pCmdHlp, "Updated REM breakpoint %u at %RGv\n", iBp, Address.FlatPtr);
}
int rc2 = DBGFR3BpClear(pDbgc->pVM, iBp);
AssertRC(rc2);
}
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Failed to set REM breakpoint at %RGv, rc=%Rrc.\n", Address.FlatPtr, rc);
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "Failed to set REM breakpoint at %RGv", Address.FlatPtr);
}
@@ -934,26 +918,24 @@ static DECLCALLBACK(int) dbgcCmdBrkREM(PCDBGCCMD /*pCmd*/, PDBGCCMDHLP pCmdHlp,
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdUnassemble(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdUnassemble(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
- PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
+ PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
/*
* Validate input.
*/
- if ( cArgs > 1
- || (cArgs == 1 && !DBGCVAR_ISPOINTER(paArgs[0].enmType)))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "internal error: The parser doesn't do its job properly yet.. It might help to use the '%%' operator.\n");
- if (!pVM && !cArgs && !DBGCVAR_ISPOINTER(pDbgc->DisasmPos.enmType))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Don't know where to start disassembling...\n");
- if (!pVM && cArgs && DBGCVAR_ISGCPOINTER(paArgs[0].enmType))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: GC address but no VM.\n");
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
+ DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs <= 1);
+ DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, cArgs == 0 || DBGCVAR_ISPOINTER(paArgs[0].enmType));
- unsigned fFlags = DBGF_DISAS_FLAGS_NO_ADDRESS;
+ if (!cArgs && !DBGCVAR_ISPOINTER(pDbgc->DisasmPos.enmType))
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "Don't know where to start disassembling");
/*
* Check the desired mode.
*/
+ unsigned fFlags = DBGF_DISAS_FLAGS_NO_ADDRESS;
switch (pCmd->pszCmd[1])
{
default: AssertFailed();
@@ -971,6 +953,7 @@ static DECLCALLBACK(int) dbgcCmdUnassemble(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
{
if (!DBGCVAR_ISPOINTER(pDbgc->DisasmPos.enmType))
{
+ /** @todo Batch query CS, RIP & CPU mode. */
PVMCPU pVCpu = VMMGetCpuById(pVM, pDbgc->idCpu);
if ( pDbgc->fRegCtxGuest
&& CPUMIsGuestIn64BitCodeEx(CPUMQueryGuestCtxPtr(pVCpu)))
@@ -1008,16 +991,16 @@ static DECLCALLBACK(int) dbgcCmdUnassemble(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
case DBGCVAR_RANGE_ELEMENTS:
if (pDbgc->DisasmPos.u64Range > 2048)
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Too many lines requested. Max is 2048 lines.\n");
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "Too many lines requested. Max is 2048 lines");
break;
case DBGCVAR_RANGE_BYTES:
if (pDbgc->DisasmPos.u64Range > 65536)
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: The requested range is too big. Max is 64KB.\n");
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "The requested range is too big. Max is 64KB");
break;
default:
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "internal error: Unknown range type %d.\n", pDbgc->DisasmPos.enmRangeType);
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "Unknown range type %d", pDbgc->DisasmPos.enmRangeType);
}
/*
@@ -1032,12 +1015,11 @@ static DECLCALLBACK(int) dbgcCmdUnassemble(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
case DBGCVAR_TYPE_GC_PHYS:
case DBGCVAR_TYPE_HC_FLAT:
case DBGCVAR_TYPE_HC_PHYS:
- case DBGCVAR_TYPE_HC_FAR:
{
DBGCVAR VarTmp;
rc = DBGCCmdHlpEval(pCmdHlp, &VarTmp, "%%(%Dv)", &pDbgc->DisasmPos);
if (RT_FAILURE(rc))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: failed to evaluate '%%(%Dv)' -> %Rrc .\n", &pDbgc->DisasmPos, rc);
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "failed to evaluate '%%(%Dv)'", &pDbgc->DisasmPos);
pDbgc->DisasmPos = VarTmp;
break;
}
@@ -1077,18 +1059,18 @@ static DECLCALLBACK(int) dbgcCmdUnassemble(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
if (RT_SUCCESS(rc))
{
/* print it */
- rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%-16DV %s\n", &pDbgc->DisasmPos, &szDis[0]);
+ rc = DBGCCmdHlpPrintf(pCmdHlp, "%-16DV %s\n", &pDbgc->DisasmPos, &szDis[0]);
if (RT_FAILURE(rc))
return rc;
}
else
{
/* bitch. */
- rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Failed to disassemble instruction, skipping one byte.\n");
+ rc = DBGCCmdHlpPrintf(pCmdHlp, "Failed to disassemble instruction, skipping one byte.\n");
if (RT_FAILURE(rc))
return rc;
if (cTries-- > 0)
- return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "Too many disassembly failures. Giving up.\n");
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "Too many disassembly failures. Giving up");
cbInstr = 1;
}
@@ -1101,14 +1083,14 @@ static DECLCALLBACK(int) dbgcCmdUnassemble(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
iRangeLeft -= cbInstr;
rc = DBGCCmdHlpEval(pCmdHlp, &pDbgc->DisasmPos, "(%Dv) + %x", &pDbgc->DisasmPos, cbInstr);
if (RT_FAILURE(rc))
- return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "Expression: (%Dv) + %x\n", &pDbgc->DisasmPos, cbInstr);
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGCCmdHlpEval(,,'(%Dv) + %x')", &pDbgc->DisasmPos, cbInstr);
if (iRangeLeft <= 0)
break;
fFlags &= ~(DBGF_DISAS_FLAGS_CURRENT_GUEST | DBGF_DISAS_FLAGS_CURRENT_HYPER);
}
- NOREF(pCmd); NOREF(pResult);
- return 0;
+ NOREF(pCmd);
+ return VINF_SUCCESS;
}
@@ -1122,7 +1104,7 @@ static DECLCALLBACK(int) dbgcCmdUnassemble(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdListSource(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdListSource(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -1166,7 +1148,6 @@ static DECLCALLBACK(int) dbgcCmdListSource(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
case DBGCVAR_TYPE_GC_FAR:
case DBGCVAR_TYPE_HC_FLAT:
case DBGCVAR_TYPE_HC_PHYS:
- case DBGCVAR_TYPE_HC_FAR:
{
int rc = DBGCCmdHlpEval(pCmdHlp, &pDbgc->SourcePos, "%%(%Dv)", &pDbgc->SourcePos);
if (RT_FAILURE(rc))
@@ -1300,7 +1281,7 @@ static DECLCALLBACK(int) dbgcCmdListSource(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
break;
}
- NOREF(pCmd); NOREF(pResult);
+ NOREF(pCmd);
return 0;
}
@@ -1315,12 +1296,12 @@ static DECLCALLBACK(int) dbgcCmdListSource(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdReg(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdReg(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
if (!pDbgc->fRegCtxGuest)
- return dbgcCmdRegHyper(pCmd, pCmdHlp, pVM, paArgs, cArgs, pResult);
- return dbgcCmdRegGuest(pCmd, pCmdHlp, pVM, paArgs, cArgs, pResult);
+ return dbgcCmdRegHyper(pCmd, pCmdHlp, pVM, paArgs, cArgs);
+ return dbgcCmdRegGuest(pCmd, pCmdHlp, pVM, paArgs, cArgs);
}
@@ -1336,55 +1317,92 @@ static DECLCALLBACK(int) dbgcCmdReg(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM
* @param pszPrefix The symbol prefix.
*/
static DECLCALLBACK(int) dbgcCmdRegCommon(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs,
- PDBGCVAR pResult, const char *pszPrefix)
+ const char *pszPrefix)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
+ Assert(cArgs == 1 || cArgs == 2); /* cArgs == 0 is handled by the caller */
+ if ( paArgs[0].enmType != DBGCVAR_TYPE_STRING
+ && paArgs[0].enmType != DBGCVAR_TYPE_SYMBOL)
+ return DBGCCmdHlpPrintf(pCmdHlp, "internal error: The parser doesn't do its job properly yet.. Try drop the '@' or/and quote the register name\n");
- Assert(cArgs != 0); /* handled by caller */
+ /*
+ * Parse the register name and kind.
+ */
+ const char *pszReg = paArgs[0].u.pszString;
+ if (*pszReg == '@')
+ pszReg++;
+ VMCPUID idCpu = pDbgc->idCpu;
+ if (*pszPrefix)
+ idCpu |= DBGFREG_HYPER_VMCPUID;
+ if (*pszReg == '.')
+ {
+ pszReg++;
+ idCpu |= DBGFREG_HYPER_VMCPUID;
+ }
+ const char * const pszActualPrefix = idCpu & DBGFREG_HYPER_VMCPUID ? "." : "";
/*
- * cArgs == 1: Show the register.
- * cArgs == 2: Modify the register.
+ * Query the register type & value (the setter needs the type).
*/
- if ( cArgs == 1
- || cArgs == 2)
+ DBGFREGVALTYPE enmType;
+ DBGFREGVAL Value;
+ int rc = DBGFR3RegNmQuery(pVM, idCpu, pszReg, &Value, &enmType);
+ if (RT_FAILURE(rc))
+ {
+ if (rc == VERR_DBGF_REGISTER_NOT_FOUND)
+ return DBGCCmdHlpVBoxError(pCmdHlp, VERR_INVALID_PARAMETER, "Unknown register: '%s%s'.\n",
+ pszActualPrefix, pszReg);
+ return DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegNmQuery failed querying '%s%s': %Rrc.\n",
+ pszActualPrefix, pszReg, rc);
+ }
+ if (cArgs == 1)
+ {
+ /*
+ * Show the register.
+ */
+ char szValue[160];
+ rc = DBGFR3RegFormatValue(szValue, sizeof(szValue), &Value, enmType, true /*fSpecial*/);
+ if (RT_SUCCESS(rc))
+ rc = DBGCCmdHlpPrintf(pCmdHlp, "%s%s=%s\n", pszActualPrefix, pszReg, szValue);
+ else
+ rc = DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegFormatValue failed: %Rrc.\n", rc);
+ }
+ else if (cArgs == 2)
{
- /* locate the register symbol. */
- const char *pszReg = paArgs[0].u.pszString;
- if ( *pszPrefix
- && pszReg[0] != *pszPrefix)
+ /*
+ * Modify the register.
+ */
+ if ( paArgs[1].enmType == DBGCVAR_TYPE_STRING
+ || paArgs[1].enmType == DBGCVAR_TYPE_SYMBOL)
+ return DBGCCmdHlpPrintf(pCmdHlp, "internal error: The parser doesn't do its job properly on the 2nd argument yet...\n");
+ if (enmType != DBGFREGVALTYPE_DTR)
{
- /* prepend the prefix. */
- char *psz = (char *)alloca(strlen(pszReg) + 2);
- psz[0] = *pszPrefix;
- strcpy(psz + 1, paArgs[0].u.pszString);
- pszReg = psz;
+ enmType = DBGFREGVALTYPE_U64;
+ rc = DBGCCmdHlpVarToNumber(pCmdHlp, &paArgs[1], &Value.u64);
}
- PCDBGCSYM pSym = dbgcLookupRegisterSymbol(pDbgc, pszReg);
- if (!pSym)
- return pCmdHlp->pfnVBoxError(pCmdHlp, VERR_INVALID_PARAMETER /* VERR_DBGC_INVALID_REGISTER */, "Invalid register name '%s'.\n", pszReg);
-
- /* show the register */
- if (cArgs == 1)
+ else
+ {
+ enmType = DBGFREGVALTYPE_DTR;
+ rc = DBGCCmdHlpVarToNumber(pCmdHlp, &paArgs[1], &Value.dtr.u64Base);
+ if (RT_SUCCESS(rc) && paArgs[1].enmRangeType != DBGCVAR_RANGE_NONE)
+ Value.dtr.u32Limit = (uint32_t)paArgs[1].u64Range;
+ }
+ if (RT_SUCCESS(rc))
{
- DBGCVAR Var;
- memset(&Var, 0, sizeof(Var));
- int rc = pSym->pfnGet(pSym, pCmdHlp, DBGCVAR_TYPE_NUMBER, &Var);
+ rc = DBGFR3RegNmSet(pVM, idCpu, pszReg, &Value, enmType);
if (RT_FAILURE(rc))
- return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "Failed getting value for register '%s'.\n", pszReg);
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%s=%Dv\n", pszReg, &Var);
+ rc = DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegNmSet failed settings '%s%s': %Rrc\n",
+ pszActualPrefix, pszReg, rc);
}
-
- /* change the register */
- int rc = pSym->pfnSet(pSym, pCmdHlp, &paArgs[1]);
- if (RT_FAILURE(rc))
- return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "Failed setting value for register '%s'.\n", pszReg);
- return VINF_SUCCESS;
+ else
+ rc = DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegFormatValue failed: %Rrc.\n", rc);
}
-
-
- NOREF(pCmd); NOREF(paArgs); NOREF(pResult);
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Huh? cArgs=%d Expected 0, 1 or 2!\n", cArgs);
+ else
+ {
+ NOREF(pCmd); NOREF(paArgs);
+ rc = DBGCCmdHlpPrintf(pCmdHlp, "Huh? cArgs=%d Expected 0, 1 or 2!\n", cArgs);
+ }
+ return rc;
}
@@ -1398,7 +1416,7 @@ static DECLCALLBACK(int) dbgcCmdRegCommon(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdRegGuest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdRegGuest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Show all registers our selves.
@@ -1448,7 +1466,7 @@ static DECLCALLBACK(int) dbgcCmdRegGuest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
"ss={%04VR{ss} base=%016VR{ss_base} limit=%08VR{ss_lim} flags=%04VR{ss_attr}}\n"
"dr0=%016VR{dr0} dr1=%016VR{dr1} dr2=%016VR{dr2} dr3=%016VR{dr3}\n"
"dr6=%016VR{dr6} dr7=%016VR{dr7}\n"
- "gdtr=%016VR{gdtr_base}:%04VR{gdtr_limit} idtr=%016VR{idtr_base}:%04VR{idtr_limit} rflags=%08VR{rflags}\n"
+ "gdtr=%016VR{gdtr_base}:%04VR{gdtr_lim} idtr=%016VR{idtr_base}:%04VR{idtr_lim} rflags=%08VR{rflags}\n"
"ldtr={%04VR{ldtr} base=%016VR{ldtr_base} limit=%08VR{ldtr_lim} flags=%08VR{ldtr_attr}}\n"
"tr ={%04VR{tr} base=%016VR{tr_base} limit=%08VR{tr_lim} flags=%08VR{tr_attr}}\n"
" sysenter={cs=%04VR{sysenter_cs} eip=%08VR{sysenter_eip} esp=%08VR{sysenter_esp}}\n"
@@ -1467,11 +1485,11 @@ static DECLCALLBACK(int) dbgcCmdRegGuest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
"eip=%08VR{eip} esp=%08VR{esp} ebp=%08VR{ebp} %VRF{eflags}\n"
"cs={%04VR{cs} base=%08VR{cs_base} limit=%08VR{cs_lim} flags=%04VR{cs_attr}} dr0=%08VR{dr0} dr1=%08VR{dr1}\n"
"ds={%04VR{ds} base=%08VR{ds_base} limit=%08VR{ds_lim} flags=%04VR{ds_attr}} dr2=%08VR{dr2} dr3=%08VR{dr3}\n"
- "es={%04VR{es} base=%08VR{es_base} limit=%08VR{es_lim} flags=%04VR{es_attr}} dr6=%08VR{dr6} dr6=%08VR{dr6}\n"
- "fs={%04VR{fs} base=%08VR{fs_base} limit=%08VR{fs_lim} flags=%04VR{fs_attr}} cr0=%08VR{cr0} cr2=%08VR{cr0}\n"
- "gs={%04VR{gs} base=%08VR{gs_base} limit=%08VR{gs_lim} flags=%04VR{gs_attr}} cr3=%08VR{cr0} cr4=%08VR{cr0}\n"
+ "es={%04VR{es} base=%08VR{es_base} limit=%08VR{es_lim} flags=%04VR{es_attr}} dr6=%08VR{dr6} dr7=%08VR{dr7}\n"
+ "fs={%04VR{fs} base=%08VR{fs_base} limit=%08VR{fs_lim} flags=%04VR{fs_attr}} cr0=%08VR{cr0} cr2=%08VR{cr2}\n"
+ "gs={%04VR{gs} base=%08VR{gs_base} limit=%08VR{gs_lim} flags=%04VR{gs_attr}} cr3=%08VR{cr3} cr4=%08VR{cr4}\n"
"ss={%04VR{ss} base=%08VR{ss_base} limit=%08VR{ss_lim} flags=%04VR{ss_attr}} cr8=%08VR{cr8}\n"
- "gdtr=%08VR{gdtr_base}:%04VR{gdtr_limit} idtr=%08VR{idtr_base}:%04VR{idtr_limit} eflags=%08VR{eflags}\n"
+ "gdtr=%08VR{gdtr_base}:%04VR{gdtr_lim} idtr=%08VR{idtr_base}:%04VR{idtr_lim} eflags=%08VR{eflags}\n"
"ldtr={%04VR{ldtr} base=%08VR{ldtr_base} limit=%08VR{ldtr_lim} flags=%04VR{ldtr_attr}}\n"
"tr ={%04VR{tr} base=%08VR{tr_base} limit=%08VR{tr_lim} flags=%04VR{tr_attr}}\n"
"sysenter={cs=%04VR{sysenter_cs} eip=%08VR{sysenter_eip} esp=%08VR{sysenter_esp}}\n"
@@ -1489,7 +1507,7 @@ static DECLCALLBACK(int) dbgcCmdRegGuest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
*/
return pCmdHlp->pfnExec(pCmdHlp, "%s", szDisAndRegs);
}
- return dbgcCmdRegCommon(pCmd, pCmdHlp, pVM, paArgs, cArgs, pResult, "");
+ return dbgcCmdRegCommon(pCmd, pCmdHlp, pVM, paArgs, cArgs, "");
}
@@ -1503,7 +1521,7 @@ static DECLCALLBACK(int) dbgcCmdRegGuest(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdRegHyper(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdRegHyper(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Show all registers our selves.
@@ -1531,7 +1549,7 @@ static DECLCALLBACK(int) dbgcCmdRegHyper(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
".fs={%04VR{fs} base=%08VR{fs_base} limit=%08VR{fs_lim} flags=%04VR{fs_attr}} .cr3=%016VR{cr3}\n"
".gs={%04VR{gs} base=%08VR{gs_base} limit=%08VR{gs_lim} flags=%04VR{gs_attr}}\n"
".ss={%04VR{ss} base=%08VR{ss_base} limit=%08VR{ss_lim} flags=%04VR{ss_attr}}\n"
- ".gdtr=%08VR{gdtr_base}:%04VR{gdtr_limit} .idtr=%08VR{idtr_base}:%04VR{idtr_limit} .eflags=%08VR{eflags}\n"
+ ".gdtr=%08VR{gdtr_base}:%04VR{gdtr_lim} .idtr=%08VR{idtr_base}:%04VR{idtr_lim} .eflags=%08VR{eflags}\n"
".ldtr={%04VR{ldtr} base=%08VR{ldtr_base} limit=%08VR{ldtr_lim} flags=%04VR{ldtr_attr}}\n"
".tr ={%04VR{tr} base=%08VR{tr_base} limit=%08VR{tr_lim} flags=%04VR{tr_attr}}\n"
);
@@ -1546,7 +1564,7 @@ static DECLCALLBACK(int) dbgcCmdRegHyper(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
*/
return pCmdHlp->pfnExec(pCmdHlp, "%s", szDisAndRegs);
}
- return dbgcCmdRegCommon(pCmd, pCmdHlp, pVM, paArgs, cArgs, pResult, ".");
+ return dbgcCmdRegCommon(pCmd, pCmdHlp, pVM, paArgs, cArgs, ".");
}
@@ -1560,9 +1578,9 @@ static DECLCALLBACK(int) dbgcCmdRegHyper(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdRegTerse(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdRegTerse(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
- NOREF(pCmd); NOREF(pVM); NOREF(paArgs); NOREF(cArgs); NOREF(pResult);
+ NOREF(pCmd); NOREF(pVM); NOREF(paArgs); NOREF(cArgs);
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
pDbgc->fRegTerse = !pDbgc->fRegTerse;
@@ -1580,7 +1598,7 @@ static DECLCALLBACK(int) dbgcCmdRegTerse(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdTrace(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdTrace(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -1590,7 +1608,7 @@ static DECLCALLBACK(int) dbgcCmdTrace(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM p
else
rc = pDbgc->CmdHlp.pfnVBoxError(&pDbgc->CmdHlp, rc, "When trying to single step VM %p\n", pDbgc->pVM);
- NOREF(pCmd); NOREF(paArgs); NOREF(cArgs); NOREF(pResult);
+ NOREF(pCmd); NOREF(paArgs); NOREF(cArgs);
return rc;
}
@@ -1605,7 +1623,7 @@ static DECLCALLBACK(int) dbgcCmdTrace(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM p
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdStack(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdStack(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -1702,7 +1720,7 @@ static DECLCALLBACK(int) dbgcCmdStack(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM p
DBGFR3StackWalkEnd(pFirstFrame);
- NOREF(paArgs); NOREF(cArgs); NOREF(pResult);
+ NOREF(paArgs); NOREF(cArgs);
return rc;
}
@@ -1725,7 +1743,7 @@ static int dbgcCmdDumpDTWorker64(PDBGCCMDHLP pCmdHlp, PCX86DESC64 pDesc, unsigne
"DownRO", /* 4 Expand-down, Read-Only */
"DownRO", /* 5 Expand-down, Read-Only - Accessed */
"DownRW", /* 6 Expand-down, Read/Write */
- "DownRO", /* 7 Expand-down, Read/Write - Accessed */
+ "DownRW", /* 7 Expand-down, Read/Write - Accessed */
"CodeEO", /* 8 Execute-Only */
"CodeEO", /* 9 Execute-Only - Accessed */
"CodeER", /* A Execute/Readable */
@@ -1874,7 +1892,7 @@ static int dbgcCmdDumpDTWorker32(PDBGCCMDHLP pCmdHlp, PCX86DESC pDesc, unsigned
"DownRO", /* 4 Expand-down, Read-Only */
"DownRO", /* 5 Expand-down, Read-Only - Accessed */
"DownRW", /* 6 Expand-down, Read/Write */
- "DownRO", /* 7 Expand-down, Read/Write - Accessed */
+ "DownRW", /* 7 Expand-down, Read/Write - Accessed */
"CodeEO", /* 8 Execute-Only */
"CodeEO", /* 9 Execute-Only - Accessed */
"CodeER", /* A Execute/Readable */
@@ -2009,7 +2027,7 @@ static int dbgcCmdDumpDTWorker32(PDBGCCMDHLP pCmdHlp, PCX86DESC pDesc, unsigned
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdDumpDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdDumpDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate input.
@@ -2065,7 +2083,6 @@ static DECLCALLBACK(int) dbgcCmdDumpDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
case DBGCVAR_TYPE_GC_FAR: u64 = paArgs[i].u.GCFar.sel; break;
case DBGCVAR_TYPE_GC_FLAT: u64 = paArgs[i].u.GCFlat; break;
case DBGCVAR_TYPE_GC_PHYS: u64 = paArgs[i].u.GCPhys; break;
- case DBGCVAR_TYPE_HC_FAR: u64 = paArgs[i].u.HCFar.sel; break;
case DBGCVAR_TYPE_HC_FLAT: u64 = (uintptr_t)paArgs[i].u.pvHCFlat; break;
case DBGCVAR_TYPE_HC_PHYS: u64 = paArgs[i].u.HCPhys; break;
default: u64 = _64K; break;
@@ -2120,7 +2137,6 @@ static DECLCALLBACK(int) dbgcCmdDumpDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: %llx is out of bounds\n", u64);
}
- NOREF(pResult);
return VINF_SUCCESS;
}
@@ -2135,7 +2151,7 @@ static DECLCALLBACK(int) dbgcCmdDumpDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdDumpIDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdDumpIDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate input.
@@ -2245,7 +2261,6 @@ static DECLCALLBACK(int) dbgcCmdDumpIDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: %llx is out of bounds (max 256)\n", paArgs[i].u.u64Number);
}
- NOREF(pResult);
return VINF_SUCCESS;
}
@@ -2260,7 +2275,7 @@ static DECLCALLBACK(int) dbgcCmdDumpIDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdDumpMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdDumpMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -2435,7 +2450,7 @@ static DECLCALLBACK(int) dbgcCmdDumpMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
break;
}
- NOREF(pCmd); NOREF(pResult);
+ NOREF(pCmd);
return VINF_SUCCESS;
}
@@ -2528,7 +2543,7 @@ static RTHCPHYS dbgcGetShadowPageMode(PDBGC pDbgc, bool *pfPAE, bool *pfLME, boo
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdDumpPageDir(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdDumpPageDir(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -2777,7 +2792,6 @@ static DECLCALLBACK(int) dbgcCmdDumpPageDir(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
VarGCPtr.u.GCFlat += fPAE ? RT_BIT_32(X86_PD_PAE_SHIFT) : RT_BIT_32(X86_PD_SHIFT);
} while (cEntries-- > 0);
- NOREF(pResult);
return VINF_SUCCESS;
}
@@ -2792,7 +2806,7 @@ static DECLCALLBACK(int) dbgcCmdDumpPageDir(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdDumpPageDirBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdDumpPageDirBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
if (!pVM)
return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: No VM.\n");
@@ -2800,7 +2814,7 @@ static DECLCALLBACK(int) dbgcCmdDumpPageDirBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmd
int rc2 = pCmdHlp->pfnExec(pCmdHlp, "dpdh %DV", &paArgs[0]);
if (RT_FAILURE(rc1))
return rc1;
- NOREF(pCmd); NOREF(paArgs); NOREF(cArgs); NOREF(pResult);
+ NOREF(pCmd); NOREF(paArgs); NOREF(cArgs);
return rc2;
}
@@ -2815,7 +2829,7 @@ static DECLCALLBACK(int) dbgcCmdDumpPageDirBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmd
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdDumpPageHierarchy(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdDumpPageHierarchy(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
if (!pVM)
@@ -2939,7 +2953,7 @@ static DECLCALLBACK(int) dbgcCmdDumpPageHierarchy(PCDBGCCMD pCmd, PDBGCCMDHLP pC
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdDumpPageTable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdDumpPageTable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -3154,7 +3168,6 @@ static DECLCALLBACK(int) dbgcCmdDumpPageTable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHl
VarGCPtr.u.GCFlat += PAGE_SIZE;
} while (cEntries-- > 0);
- NOREF(pResult);
return VINF_SUCCESS;
}
@@ -3169,7 +3182,7 @@ static DECLCALLBACK(int) dbgcCmdDumpPageTable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHl
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdDumpPageTableBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdDumpPageTableBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
if (!pVM)
return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: No VM.\n");
@@ -3177,7 +3190,7 @@ static DECLCALLBACK(int) dbgcCmdDumpPageTableBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pC
int rc2 = pCmdHlp->pfnExec(pCmdHlp, "dpth %DV", &paArgs[0]);
if (RT_FAILURE(rc1))
return rc1;
- NOREF(pCmd); NOREF(cArgs); NOREF(pResult);
+ NOREF(pCmd); NOREF(cArgs);
return rc2;
}
@@ -3192,7 +3205,7 @@ static DECLCALLBACK(int) dbgcCmdDumpPageTableBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pC
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdDumpTSS(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR /*pResult*/)
+static DECLCALLBACK(int) dbgcCmdDumpTSS(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
int rc;
@@ -3525,12 +3538,12 @@ static DECLCALLBACK(int) dbgcCmdDumpTSS(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdMemoryInfo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdMemoryInfo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
DBGCCmdHlpPrintf(pCmdHlp, "Address: %DV\n", &paArgs[0]);
if (!pVM)
return DBGCCmdHlpFail(pCmdHlp, pCmd, "No VM.\n");
- return dbgcCmdDumpPageHierarchy(pCmd, pCmdHlp, pVM, paArgs, cArgs, pResult);
+ return dbgcCmdDumpPageHierarchy(pCmd, pCmdHlp, pVM, paArgs, cArgs);
}
@@ -3568,7 +3581,6 @@ int dbgcVarsToBytes(PDBGCCMDHLP pCmdHlp, void *pvBuf, uint32_t *pcbBuf, size_t c
switch (paVars[i].enmType)
{
case DBGCVAR_TYPE_GC_FAR:
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_GC_FLAT:
case DBGCVAR_TYPE_GC_PHYS:
case DBGCVAR_TYPE_HC_FLAT:
@@ -3682,7 +3694,7 @@ int dbgcVarsToBytes(PDBGCCMDHLP pCmdHlp, void *pvBuf, uint32_t *pcbBuf, size_t c
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdEditMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdEditMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
unsigned iArg;
@@ -3734,7 +3746,6 @@ static DECLCALLBACK(int) dbgcCmdEditMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
return DBGCCmdHlpVBoxError(pCmdHlp, rc, "%%(%Dv)", &paArgs[0]);
}
- NOREF(pResult);
return VINF_SUCCESS;
}
@@ -3782,12 +3793,13 @@ static int dbgcCmdWorkerSearchMemDoIt(PDBGCCMDHLP pCmdHlp, PVM pVM, PDBGFADDRESS
/* report result */
DBGCVAR VarCur;
- dbgcVarInit(&VarCur);
- dbgcVarSetDbgfAddr(&VarCur, &HitAddress);
+ rc = DBGCCmdHlpVarFromDbgfAddr(pCmdHlp, &HitAddress, &VarCur);
+ if (RT_FAILURE(rc))
+ return DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGCCmdHlpVarFromDbgfAddr\n");
if (!pResult)
pCmdHlp->pfnExec(pCmdHlp, "db %DV LB 10", &VarCur);
else
- dbgcVarSetDbgfAddr(pResult, &HitAddress);
+ DBGCVAR_ASSIGN(pResult, &VarCur);
/* advance */
cbRange -= HitAddress.FlatPtr - pAddress->FlatPtr;
@@ -3883,7 +3895,7 @@ static int dbgcCmdWorkerSearchMemResume(PDBGCCMDHLP pCmdHlp, PVM pVM, PDBGCVAR p
static int dbgcCmdWorkerSearchMem(PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pAddress, uint64_t cMaxHits, char chType,
PCDBGCVAR paPatArgs, unsigned cPatArgs, PDBGCVAR pResult)
{
- dbgcVarSetGCFlat(pResult, 0);
+ DBGCVAR_INIT_GC_FLAT(pResult, 0);
/*
* Convert the search pattern into bytes and DBGFR3MemScan can deal with.
@@ -3954,7 +3966,7 @@ static int dbgcCmdWorkerSearchMem(PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pAddre
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdSearchMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdSearchMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/* check that the parser did what it's supposed to do. */
//if ( cArgs <= 2
@@ -3965,7 +3977,7 @@ static DECLCALLBACK(int) dbgcCmdSearchMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
* Repeat previous search?
*/
if (cArgs == 0)
- return dbgcCmdWorkerSearchMemResume(pCmdHlp, pVM, pResult);
+ return dbgcCmdWorkerSearchMemResume(pCmdHlp, pVM, NULL);
/*
* Parse arguments.
@@ -3985,13 +3997,13 @@ static DECLCALLBACK(int) dbgcCmdSearchMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, P
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdSearchMemType(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdSearchMemType(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/* check that the parser did what it's supposed to do. */
if ( cArgs < 2
|| !DBGCVAR_ISGCPOINTER(paArgs[0].enmType))
return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "parser error\n");
- return dbgcCmdWorkerSearchMem(pCmdHlp, pVM, &paArgs[0], pResult ? 1 : 25, pCmd->pszCmd[1], paArgs + 1, cArgs - 1, pResult);
+ return dbgcCmdWorkerSearchMem(pCmdHlp, pVM, &paArgs[0], 25, pCmd->pszCmd[1], paArgs + 1, cArgs - 1, NULL);
}
@@ -4003,10 +4015,9 @@ static DECLCALLBACK(int) dbgcCmdSearchMemType(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHl
* @param pVM Pointer to the current VM (if any).
* @param pArg Pointer to the address or symbol to lookup.
*/
-static int dbgcDoListNear(PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArg, PDBGCVAR pResult)
+static int dbgcDoListNear(PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArg)
{
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
- dbgcVarSetGCFlat(pResult, 0);
RTDBGSYMBOL Symbol;
int rc;
@@ -4020,7 +4031,6 @@ static int dbgcDoListNear(PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArg, PDBGCVAR
return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3AsSymbolByName(,,%s,)\n", pArg->u.pszString);
rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%Rptr %s\n", Symbol.Value, Symbol.szName);
- dbgcVarSetGCFlatByteRange(pResult, Symbol.Value, Symbol.cb);
}
else
{
@@ -4032,8 +4042,6 @@ static int dbgcDoListNear(PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArg, PDBGCVAR
if (RT_FAILURE(rc))
return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "%%(%DV)\n", pArg);
- dbgcVarSetVar(pResult, &AddrVar);
-
RTINTPTR offDisp;
DBGFADDRESS Addr;
rc = DBGFR3AsSymbolByAddr(pVM, pDbgc->hDbgAs, DBGFR3AddrFromFlat(pVM, &Addr, AddrVar.u.GCFlat), &offDisp, &Symbol, NULL);
@@ -4047,15 +4055,9 @@ static int dbgcDoListNear(PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArg, PDBGCVAR
else
rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%DV %s - %RGv", &AddrVar, Symbol.szName, -offDisp);
if ((RTGCINTPTR)Symbol.cb > -offDisp)
- {
rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, " LB %RGv\n", Symbol.cb + offDisp);
- dbgcVarSetByteRange(pResult, Symbol.cb + offDisp);
- }
else
- {
rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "\n");
- dbgcVarSetNoRange(pResult);
- }
}
return rc;
@@ -4072,9 +4074,8 @@ static int dbgcDoListNear(PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArg, PDBGCVAR
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdListNear(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdListNear(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
- dbgcVarSetGCFlat(pResult, 0);
if (!cArgs)
{
/*
@@ -4084,7 +4085,7 @@ static DECLCALLBACK(int) dbgcCmdListNear(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
int rc = DBGCCmdHlpEval(pCmdHlp, &AddrVar, "%%(cs:eip)");
if (RT_FAILURE(rc))
return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "%%(cs:eip)\n");
- return dbgcDoListNear(pCmdHlp, pVM, &AddrVar, pResult);
+ return dbgcDoListNear(pCmdHlp, pVM, &AddrVar);
}
/** @todo Fix the darn parser, it's resolving symbols specified as arguments before we get in here. */
@@ -4093,12 +4094,12 @@ static DECLCALLBACK(int) dbgcCmdListNear(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PV
*/
for (unsigned iArg = 0; iArg < cArgs; iArg++)
{
- int rc = dbgcDoListNear(pCmdHlp, pVM, &paArgs[iArg], pResult);
+ int rc = dbgcDoListNear(pCmdHlp, pVM, &paArgs[iArg]);
if (RT_FAILURE(rc))
return rc;
}
- NOREF(pCmd); NOREF(pResult);
+ NOREF(pCmd);
return VINF_SUCCESS;
}
@@ -4130,7 +4131,7 @@ static bool dbgcCmdListModuleMatch(const char *pszName, PCDBGCVAR paArgs, unsign
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) dbgcCmdListModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) dbgcCmdListModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
bool const fMappings = pCmd->pszCmd[2] == 'o';
PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
@@ -4205,6 +4206,6 @@ static DECLCALLBACK(int) dbgcCmdListModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
}
RTDbgAsRelease(hAs);
- NOREF(pCmd); NOREF(pResult);
+ NOREF(pCmd);
return VINF_SUCCESS;
}
diff --git a/src/VBox/Debugger/DBGCEval.cpp b/src/VBox/Debugger/DBGCEval.cpp
new file mode 100644
index 000000000..c9e6830d7
--- /dev/null
+++ b/src/VBox/Debugger/DBGCEval.cpp
@@ -0,0 +1,1160 @@
+/* $Id: DBGCEval.cpp 35696 2011-01-24 18:03:33Z vboxsync $ */
+/** @file
+ * DBGC - Debugger Console, command evaluator.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_DBGC
+#include <VBox/dbg.h>
+#include <VBox/err.h>
+#include <VBox/log.h>
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/string.h>
+#include <iprt/ctype.h>
+
+#include "DBGCInternal.h"
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/** Bitmap where set bits indicates the characters the may start an operator name. */
+static uint32_t g_bmOperatorChars[256 / (4*8)];
+
+
+
+/**
+ * Initializes g_bmOperatorChars.
+ */
+void dbgcEvalInit(void)
+{
+ memset(g_bmOperatorChars, 0, sizeof(g_bmOperatorChars));
+ for (unsigned iOp = 0; iOp < g_cOps; iOp++)
+ ASMBitSet(&g_bmOperatorChars[0], (uint8_t)g_aOps[iOp].szName[0]);
+}
+
+
+/**
+ * Checks whether the character may be the start of an operator.
+ *
+ * @returns true/false.
+ * @param ch The character.
+ */
+DECLINLINE(bool) dbgcIsOpChar(char ch)
+{
+ return ASMBitTest(&g_bmOperatorChars[0], (uint8_t)ch);
+}
+
+
+static int dbgcEvalSubString(PDBGC pDbgc, char *pszExpr, size_t cchExpr, PDBGCVAR pArg)
+{
+ Log2(("dbgcEvalSubString: cchExpr=%d pszExpr=%s\n", cchExpr, pszExpr));
+
+ /*
+ * Removing any quoting and escapings.
+ */
+ char ch = *pszExpr;
+ if (ch == '"' || ch == '\'' || ch == '`')
+ {
+ if (pszExpr[--cchExpr] != ch)
+ return VERR_PARSE_UNBALANCED_QUOTE;
+ cchExpr--;
+ pszExpr++;
+
+ /** @todo string unescaping. */
+ }
+ pszExpr[cchExpr] = '\0';
+
+ /*
+ * Make the argument.
+ */
+ pArg->pDesc = NULL;
+ pArg->pNext = NULL;
+ pArg->enmType = DBGCVAR_TYPE_STRING;
+ pArg->u.pszString = pszExpr;
+ pArg->enmRangeType = DBGCVAR_RANGE_BYTES;
+ pArg->u64Range = cchExpr;
+
+ NOREF(pDbgc);
+ return VINF_SUCCESS;
+}
+
+
+static int dbgcEvalSubNum(char *pszExpr, unsigned uBase, PDBGCVAR pArg)
+{
+ Log2(("dbgcEvalSubNum: uBase=%d pszExpr=%s\n", uBase, pszExpr));
+ /*
+ * Convert to number.
+ */
+ uint64_t u64 = 0;
+ char ch;
+ while ((ch = *pszExpr) != '\0')
+ {
+ uint64_t u64Prev = u64;
+ unsigned u = ch - '0';
+ if (u < 10 && u < uBase)
+ u64 = u64 * uBase + u;
+ else if (ch >= 'a' && (u = ch - ('a' - 10)) < uBase)
+ u64 = u64 * uBase + u;
+ else if (ch >= 'A' && (u = ch - ('A' - 10)) < uBase)
+ u64 = u64 * uBase + u;
+ else
+ return VERR_PARSE_INVALID_NUMBER;
+
+ /* check for overflow - ARG!!! How to detect overflow correctly!?!?!? */
+ if (u64Prev != u64 / uBase)
+ return VERR_PARSE_NUMBER_TOO_BIG;
+
+ /* next */
+ pszExpr++;
+ }
+
+ /*
+ * Initialize the argument.
+ */
+ pArg->pDesc = NULL;
+ pArg->pNext = NULL;
+ pArg->enmType = DBGCVAR_TYPE_NUMBER;
+ pArg->u.u64Number = u64;
+ pArg->enmRangeType = DBGCVAR_RANGE_NONE;
+ pArg->u64Range = 0;
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Match variable and variable descriptor, promoting the variable if necessary.
+ *
+ * @returns VBox status code.
+ * @param pDbgc Debug console instanace.
+ * @param pVar Variable.
+ * @param pVarDesc Variable descriptor.
+ */
+static int dbgcEvalSubMatchVar(PDBGC pDbgc, PDBGCVAR pVar, PCDBGCVARDESC pVarDesc)
+{
+ /*
+ * (If match or promoted to match, return, else break.)
+ */
+ switch (pVarDesc->enmCategory)
+ {
+ /*
+ * Anything goes
+ */
+ case DBGCVAR_CAT_ANY:
+ return VINF_SUCCESS;
+
+ /*
+ * Pointer with and without range.
+ * We can try resolve strings and symbols as symbols and promote
+ * numbers to flat GC pointers.
+ */
+ case DBGCVAR_CAT_POINTER_NO_RANGE:
+ case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE:
+ if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
+ return VERR_PARSE_NO_RANGE_ALLOWED;
+ /* fallthru */
+ case DBGCVAR_CAT_POINTER:
+ case DBGCVAR_CAT_POINTER_NUMBER:
+ switch (pVar->enmType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ case DBGCVAR_TYPE_GC_FAR:
+ case DBGCVAR_TYPE_GC_PHYS:
+ case DBGCVAR_TYPE_HC_FLAT:
+ case DBGCVAR_TYPE_HC_PHYS:
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_SYMBOL:
+ case DBGCVAR_TYPE_STRING:
+ {
+ DBGCVAR Var;
+ int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var);
+ if (RT_SUCCESS(rc))
+ {
+ /* deal with range */
+ if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
+ {
+ Var.enmRangeType = pVar->enmRangeType;
+ Var.u64Range = pVar->u64Range;
+ }
+ else if (pVarDesc->enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
+ Var.enmRangeType = DBGCVAR_RANGE_NONE;
+ *pVar = Var;
+ return rc;
+ }
+ break;
+ }
+
+ case DBGCVAR_TYPE_NUMBER:
+ if ( pVarDesc->enmCategory != DBGCVAR_CAT_POINTER_NUMBER
+ && pVarDesc->enmCategory != DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE)
+ {
+ RTGCPTR GCPtr = (RTGCPTR)pVar->u.u64Number;
+ pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
+ pVar->u.GCFlat = GCPtr;
+ }
+ return VINF_SUCCESS;
+
+ default:
+ break;
+ }
+ break;
+
+ /*
+ * GC pointer with and without range.
+ * We can try resolve strings and symbols as symbols and
+ * promote numbers to flat GC pointers.
+ */
+ case DBGCVAR_CAT_GC_POINTER_NO_RANGE:
+ if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
+ return VERR_PARSE_NO_RANGE_ALLOWED;
+ /* fallthru */
+ case DBGCVAR_CAT_GC_POINTER:
+ switch (pVar->enmType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ case DBGCVAR_TYPE_GC_FAR:
+ case DBGCVAR_TYPE_GC_PHYS:
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_HC_FLAT:
+ case DBGCVAR_TYPE_HC_PHYS:
+ return VERR_PARSE_CONVERSION_FAILED;
+
+ case DBGCVAR_TYPE_SYMBOL:
+ case DBGCVAR_TYPE_STRING:
+ {
+ DBGCVAR Var;
+ int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var);
+ if (RT_SUCCESS(rc))
+ {
+ /* deal with range */
+ if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
+ {
+ Var.enmRangeType = pVar->enmRangeType;
+ Var.u64Range = pVar->u64Range;
+ }
+ else if (pVarDesc->enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
+ Var.enmRangeType = DBGCVAR_RANGE_NONE;
+ *pVar = Var;
+ return rc;
+ }
+ break;
+ }
+
+ case DBGCVAR_TYPE_NUMBER:
+ {
+ RTGCPTR GCPtr = (RTGCPTR)pVar->u.u64Number;
+ pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
+ pVar->u.GCFlat = GCPtr;
+ return VINF_SUCCESS;
+ }
+
+ default:
+ break;
+ }
+ break;
+
+ /*
+ * Number with or without a range.
+ * Numbers can be resolved from symbols, but we cannot demote a pointer
+ * to a number.
+ */
+ case DBGCVAR_CAT_NUMBER_NO_RANGE:
+ if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
+ return VERR_PARSE_NO_RANGE_ALLOWED;
+ /* fallthru */
+ case DBGCVAR_CAT_NUMBER:
+ switch (pVar->enmType)
+ {
+ case DBGCVAR_TYPE_NUMBER:
+ return VINF_SUCCESS;
+
+ case DBGCVAR_TYPE_SYMBOL:
+ case DBGCVAR_TYPE_STRING:
+ {
+ DBGCVAR Var;
+ int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
+ if (RT_SUCCESS(rc))
+ {
+ *pVar = Var;
+ return rc;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ /*
+ * Strings can easily be made from symbols (and of course strings).
+ * We could consider reformatting the addresses and numbers into strings later...
+ */
+ case DBGCVAR_CAT_STRING:
+ switch (pVar->enmType)
+ {
+ case DBGCVAR_TYPE_SYMBOL:
+ pVar->enmType = DBGCVAR_TYPE_STRING;
+ /* fallthru */
+ case DBGCVAR_TYPE_STRING:
+ return VINF_SUCCESS;
+ default:
+ break;
+ }
+ break;
+
+ /*
+ * Symol is pretty much the same thing as a string (at least until we actually implement it).
+ */
+ case DBGCVAR_CAT_SYMBOL:
+ switch (pVar->enmType)
+ {
+ case DBGCVAR_TYPE_STRING:
+ pVar->enmType = DBGCVAR_TYPE_SYMBOL;
+ /* fallthru */
+ case DBGCVAR_TYPE_SYMBOL:
+ return VINF_SUCCESS;
+ default:
+ break;
+ }
+ break;
+
+ /*
+ * Anything else is illegal.
+ */
+ default:
+ AssertMsgFailed(("enmCategory=%d\n", pVar->enmType));
+ break;
+ }
+
+ return VERR_PARSE_NO_ARGUMENT_MATCH;
+}
+
+
+/**
+ * Matches a set of variables with a description set.
+ *
+ * This is typically used for routine arguments before a call. The effects in
+ * addition to the validation, is that some variables might be propagated to
+ * other types in order to match the description. The following transformations
+ * are supported:
+ * - String reinterpreted as a symbol and resolved to a number or pointer.
+ * - Number to a pointer.
+ * - Pointer to a number.
+ *
+ * @returns VBox status code. Modified @a paVars on success.
+ */
+static int dbgcEvalSubMatchVars(PDBGC pDbgc, unsigned cVarsMin, unsigned cVarsMax,
+ PCDBGCVARDESC paVarDescs, unsigned cVarDescs,
+ PDBGCVAR paVars, unsigned cVars)
+{
+ /*
+ * Just do basic min / max checks first.
+ */
+ if (cVars < cVarsMin)
+ return VERR_PARSE_TOO_FEW_ARGUMENTS;
+ if (cVars > cVarsMax)
+ return VERR_PARSE_TOO_MANY_ARGUMENTS;
+
+ /*
+ * Match the descriptors and actual variables.
+ */
+ PCDBGCVARDESC pPrevDesc = NULL;
+ unsigned cCurDesc = 0;
+ unsigned iVar = 0;
+ unsigned iVarDesc = 0;
+ while (iVar < cVars)
+ {
+ /* walk the descriptors */
+ if (iVarDesc >= cVarDescs)
+ return VERR_PARSE_TOO_MANY_ARGUMENTS;
+ if ( ( paVarDescs[iVarDesc].fFlags & DBGCVD_FLAGS_DEP_PREV
+ && &paVarDescs[iVarDesc - 1] != pPrevDesc)
+ || cCurDesc >= paVarDescs[iVarDesc].cTimesMax)
+ {
+ iVarDesc++;
+ if (iVarDesc >= cVarDescs)
+ return VERR_PARSE_TOO_MANY_ARGUMENTS;
+ cCurDesc = 0;
+ }
+
+ /*
+ * Skip thru optional arguments until we find something which matches
+ * or can easily be promoted to what the descriptor want.
+ */
+ for (;;)
+ {
+ int rc = dbgcEvalSubMatchVar(pDbgc, &paVars[iVar], &paVarDescs[iVarDesc]);
+ if (RT_SUCCESS(rc))
+ {
+ paVars[iVar].pDesc = &paVarDescs[iVarDesc];
+ cCurDesc++;
+ break;
+ }
+
+ /* can we advance? */
+ if (paVarDescs[iVarDesc].cTimesMin > cCurDesc)
+ return VERR_PARSE_ARGUMENT_TYPE_MISMATCH;
+ if (++iVarDesc >= cVarDescs)
+ return VERR_PARSE_ARGUMENT_TYPE_MISMATCH;
+ cCurDesc = 0;
+ }
+
+ /* next var */
+ iVar++;
+ }
+
+ /*
+ * Check that the rest of the descriptors are optional.
+ */
+ while (iVarDesc < cVarDescs)
+ {
+ if (paVarDescs[iVarDesc].cTimesMin > cCurDesc)
+ return VERR_PARSE_TOO_FEW_ARGUMENTS;
+ cCurDesc = 0;
+
+ /* next */
+ iVarDesc++;
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Evaluates one argument with respect to unary operators.
+ *
+ * @returns VBox status code. pResult contains the result on success.
+ *
+ * @param pDbgc Debugger console instance data.
+ * @param pszExpr The expression string.
+ * @param cchExpr The length of the expression.
+ * @param enmCategory The target category for the result.
+ * @param pResult Where to store the result of the expression evaluation.
+ */
+static int dbgcEvalSubUnary(PDBGC pDbgc, char *pszExpr, size_t cchExpr, DBGCVARCAT enmCategory, PDBGCVAR pResult)
+{
+ Log2(("dbgcEvalSubUnary: cchExpr=%d pszExpr=%s\n", cchExpr, pszExpr));
+
+ /*
+ * The state of the expression is now such that it will start by zero or more
+ * unary operators and being followed by an expression of some kind.
+ * The expression is either plain or in parenthesis.
+ *
+ * Being in a lazy, recursive mode today, the parsing is done as simple as possible. :-)
+ * ASSUME: unary operators are all of equal precedence.
+ */
+ int rc = VINF_SUCCESS;
+ PCDBGCOP pOp = dbgcOperatorLookup(pDbgc, pszExpr, false, ' ');
+ if (pOp)
+ {
+ /* binary operators means syntax error. */
+ if (pOp->fBinary)
+ return VERR_PARSE_UNEXPECTED_OPERATOR;
+
+ /*
+ * If the next expression (the one following the unary operator) is in a
+ * parenthesis a full eval is needed. If not the unary eval will suffice.
+ */
+ /* calc and strip next expr. */
+ char *pszExpr2 = pszExpr + pOp->cchName;
+ while (RT_C_IS_BLANK(*pszExpr2))
+ pszExpr2++;
+
+ if (!*pszExpr2)
+ rc = VERR_PARSE_EMPTY_ARGUMENT;
+ else
+ {
+ DBGCVAR Arg;
+ if (*pszExpr2 == '(')
+ rc = dbgcEvalSub(pDbgc, pszExpr2, cchExpr - (pszExpr2 - pszExpr), pOp->enmCatArg1, &Arg);
+ else
+ rc = dbgcEvalSubUnary(pDbgc, pszExpr2, cchExpr - (pszExpr2 - pszExpr), pOp->enmCatArg1, &Arg);
+ if (RT_SUCCESS(rc))
+ rc = pOp->pfnHandlerUnary(pDbgc, &Arg, pResult);
+ }
+ }
+ else
+ {
+ /*
+ * Didn't find any operators, so it we have to check if this can be an
+ * function call before assuming numeric or string expression.
+ *
+ * (ASSUMPTIONS:)
+ * A function name only contains alphanumerical chars and it can not start
+ * with a numerical character.
+ * Immediately following the name is a parenthesis which must over
+ * the remaining part of the expression.
+ */
+ bool fExternal = *pszExpr == '.';
+ char *pszFun = fExternal ? pszExpr + 1 : pszExpr;
+ char *pszFunEnd = NULL;
+ if (pszExpr[cchExpr - 1] == ')' && RT_C_IS_ALPHA(*pszFun))
+ {
+ pszFunEnd = pszExpr + 1;
+ while (*pszFunEnd != '(' && RT_C_IS_ALNUM(*pszFunEnd))
+ pszFunEnd++;
+ if (*pszFunEnd != '(')
+ pszFunEnd = NULL;
+ }
+
+ if (pszFunEnd)
+ {
+ /*
+ * Ok, it's a function call.
+ */
+ if (fExternal)
+ pszExpr++, cchExpr--;
+ PCDBGCCMD pFun = dbgcRoutineLookup(pDbgc, pszExpr, pszFunEnd - pszExpr, fExternal);
+ if (!pFun)
+ return VERR_PARSE_FUNCTION_NOT_FOUND;
+#if 0
+ if (!pFun->pResultDesc)
+ return VERR_PARSE_NOT_A_FUNCTION;
+
+ /*
+ * Parse the expression in parenthesis.
+ */
+ cchExpr -= pszFunEnd - pszExpr;
+ pszExpr = pszFunEnd;
+ /** @todo implement multiple arguments. */
+ DBGCVAR Arg;
+ rc = dbgcEvalSub(pDbgc, pszExpr, cchExpr, enmCategory, &Arg);
+ if (!rc)
+ {
+ rc = dbgcEvalSubMatchVars(pDbgc, pFun->cArgsMin, pFun->cArgsMax, pFun->paArgDescs, pFun->cArgDescs, &Arg, 1);
+ if (!rc)
+ rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, &Arg, 1, pResult);
+ }
+ else if (rc == VERR_PARSE_EMPTY_ARGUMENT && pFun->cArgsMin == 0)
+ rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, NULL, 0, pResult);
+#else
+ rc = VERR_NOT_IMPLEMENTED;
+#endif
+ }
+ else if ( enmCategory == DBGCVAR_CAT_STRING
+ || enmCategory == DBGCVAR_CAT_SYMBOL)
+ rc = dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
+ else
+ {
+ /*
+ * Didn't find any operators, so it must be a plain expression.
+ * This might be numeric or a string expression.
+ */
+ char ch = pszExpr[0];
+ char ch2 = pszExpr[1];
+ if (ch == '0' && (ch2 == 'x' || ch2 == 'X'))
+ rc = dbgcEvalSubNum(pszExpr + 2, 16, pResult);
+ else if (ch == '0' && (ch2 == 'i' || ch2 == 'i'))
+ rc = dbgcEvalSubNum(pszExpr + 2, 10, pResult);
+ else if (ch == '0' && (ch2 == 't' || ch2 == 'T'))
+ rc = dbgcEvalSubNum(pszExpr + 2, 8, pResult);
+ /// @todo 0b doesn't work as a binary prefix, we confuse it with 0bf8:0123 and stuff.
+ //else if (ch == '0' && (ch2 == 'b' || ch2 == 'b'))
+ // rc = dbgcEvalSubNum(pszExpr + 2, 2, pResult);
+ else
+ {
+ /*
+ * Hexadecimal number or a string?
+ */
+ char *psz = pszExpr;
+ while (RT_C_IS_XDIGIT(*psz))
+ psz++;
+ if (!*psz)
+ rc = dbgcEvalSubNum(pszExpr, 16, pResult);
+ else if ((*psz == 'h' || *psz == 'H') && !psz[1])
+ {
+ *psz = '\0';
+ rc = dbgcEvalSubNum(pszExpr, 16, pResult);
+ }
+ else
+ rc = dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
+ }
+ }
+ }
+
+ return rc;
+}
+
+
+/**
+ * Evaluates one argument.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDbgc Debugger console instance data.
+ * @param pszExpr The expression string.
+ * @param enmCategory The target category for the result.
+ * @param pResult Where to store the result of the expression evaluation.
+ */
+int dbgcEvalSub(PDBGC pDbgc, char *pszExpr, size_t cchExpr, DBGCVARCAT enmCategory, PDBGCVAR pResult)
+{
+ Log2(("dbgcEvalSub: cchExpr=%d pszExpr=%s\n", cchExpr, pszExpr));
+ /*
+ * First we need to remove blanks in both ends.
+ * ASSUMES: There is no quoting unless the entire expression is a string.
+ */
+
+ /* stripping. */
+ while (cchExpr > 0 && RT_C_IS_BLANK(pszExpr[cchExpr - 1]))
+ pszExpr[--cchExpr] = '\0';
+ while (RT_C_IS_BLANK(*pszExpr))
+ pszExpr++, cchExpr--;
+ if (!*pszExpr)
+ return VERR_PARSE_EMPTY_ARGUMENT;
+
+ /* it there is any kind of quoting in the expression, it's string meat. */
+ if (strpbrk(pszExpr, "\"'`"))
+ return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
+
+ /*
+ * Check if there are any parenthesis which needs removing.
+ */
+ if (pszExpr[0] == '(' && pszExpr[cchExpr - 1] == ')')
+ {
+ do
+ {
+ unsigned cPar = 1;
+ char *psz = pszExpr + 1;
+ char ch;
+ while ((ch = *psz) != '\0')
+ {
+ if (ch == '(')
+ cPar++;
+ else if (ch == ')')
+ {
+ if (cPar <= 0)
+ return VERR_PARSE_UNBALANCED_PARENTHESIS;
+ cPar--;
+ if (cPar == 0 && psz[1]) /* If not at end, there's nothing to do. */
+ break;
+ }
+ /* next */
+ psz++;
+ }
+ if (ch)
+ break;
+
+ /* remove the parenthesis. */
+ pszExpr++;
+ cchExpr -= 2;
+ pszExpr[cchExpr] = '\0';
+
+ /* strip blanks. */
+ while (cchExpr > 0 && RT_C_IS_BLANK(pszExpr[cchExpr - 1]))
+ pszExpr[--cchExpr] = '\0';
+ while (RT_C_IS_BLANK(*pszExpr))
+ pszExpr++, cchExpr--;
+ if (!*pszExpr)
+ return VERR_PARSE_EMPTY_ARGUMENT;
+ } while (pszExpr[0] == '(' && pszExpr[cchExpr - 1] == ')');
+ }
+
+ /* tabs to spaces. */
+ char *psz = pszExpr;
+ while ((psz = strchr(psz, '\t')) != NULL)
+ *psz = ' ';
+
+ /*
+ * Now, we need to look for the binary operator with the lowest precedence.
+ *
+ * If there are no operators we're left with a simple expression which we
+ * evaluate with respect to unary operators
+ */
+ char *pszOpSplit = NULL;
+ PCDBGCOP pOpSplit = NULL;
+ unsigned cBinaryOps = 0;
+ unsigned cPar = 0;
+ char ch;
+ char chPrev = ' ';
+ bool fBinary = false;
+ psz = pszExpr;
+
+ while ((ch = *psz) != '\0')
+ {
+ //Log2(("ch=%c cPar=%d fBinary=%d\n", ch, cPar, fBinary));
+ /*
+ * Parenthesis.
+ */
+ if (ch == '(')
+ {
+ cPar++;
+ fBinary = false;
+ }
+ else if (ch == ')')
+ {
+ if (cPar <= 0)
+ return VERR_PARSE_UNBALANCED_PARENTHESIS;
+ cPar--;
+ fBinary = true;
+ }
+ /*
+ * Potential operator.
+ */
+ else if (cPar == 0 && !RT_C_IS_BLANK(ch))
+ {
+ PCDBGCOP pOp = dbgcIsOpChar(ch)
+ ? dbgcOperatorLookup(pDbgc, psz, fBinary, chPrev)
+ : NULL;
+ if (pOp)
+ {
+ /* If not the right kind of operator we've got a syntax error. */
+ if (pOp->fBinary != fBinary)
+ return VERR_PARSE_UNEXPECTED_OPERATOR;
+
+ /*
+ * Update the parse state and skip the operator.
+ */
+ if (!pOpSplit)
+ {
+ pOpSplit = pOp;
+ pszOpSplit = psz;
+ cBinaryOps = fBinary;
+ }
+ else if (fBinary)
+ {
+ cBinaryOps++;
+ if (pOp->iPrecedence >= pOpSplit->iPrecedence)
+ {
+ pOpSplit = pOp;
+ pszOpSplit = psz;
+ }
+ }
+
+ psz += pOp->cchName - 1;
+ fBinary = false;
+ }
+ else
+ fBinary = true;
+ }
+
+ /* next */
+ psz++;
+ chPrev = ch;
+ } /* parse loop. */
+
+
+ /*
+ * Either we found an operator to divide the expression by
+ * or we didn't find any. In the first case it's divide and
+ * conquer. In the latter it's a single expression which
+ * needs dealing with its unary operators if any.
+ */
+ int rc;
+ if ( cBinaryOps
+ && pOpSplit->fBinary)
+ {
+ /* process 1st sub expression. */
+ *pszOpSplit = '\0';
+ DBGCVAR Arg1;
+ rc = dbgcEvalSub(pDbgc, pszExpr, pszOpSplit - pszExpr, pOpSplit->enmCatArg1, &Arg1);
+ if (RT_SUCCESS(rc))
+ {
+ /* process 2nd sub expression. */
+ char *psz2 = pszOpSplit + pOpSplit->cchName;
+ DBGCVAR Arg2;
+ rc = dbgcEvalSub(pDbgc, psz2, cchExpr - (psz2 - pszExpr), pOpSplit->enmCatArg2, &Arg2);
+ if (RT_SUCCESS(rc))
+ /* apply the operator. */
+ rc = pOpSplit->pfnHandlerBinary(pDbgc, &Arg1, &Arg2, pResult);
+ }
+ }
+ else if (cBinaryOps)
+ {
+ /* process sub expression. */
+ pszOpSplit += pOpSplit->cchName;
+ DBGCVAR Arg;
+ rc = dbgcEvalSub(pDbgc, pszOpSplit, cchExpr - (pszOpSplit - pszExpr), pOpSplit->enmCatArg1, &Arg);
+ if (RT_SUCCESS(rc))
+ /* apply the operator. */
+ rc = pOpSplit->pfnHandlerUnary(pDbgc, &Arg, pResult);
+ }
+ else
+ /* plain expression or using unary operators perhaps with parentheses. */
+ rc = dbgcEvalSubUnary(pDbgc, pszExpr, cchExpr, enmCategory, pResult);
+
+ return rc;
+}
+
+
+/**
+ * Parses the arguments of one command.
+ *
+ * @returns VBox statuc code. On parser errors the index of the troublesome
+ * argument is indicated by *pcArg.
+ *
+ * @param pDbgc Debugger console instance data.
+ * @param pCmd Pointer to the command descriptor.
+ * @param pszArg Pointer to the arguments to parse.
+ * @param paArgs Where to store the parsed arguments.
+ * @param cArgs Size of the paArgs array.
+ * @param pcArgs Where to store the number of arguments. In the event
+ * of an error this is (ab)used to store the index of the
+ * offending argument.
+ */
+static int dbgcProcessArguments(PDBGC pDbgc, PCDBGCCMD pCmd, char *pszArgs, PDBGCVAR paArgs, unsigned cArgs, unsigned *pcArgs)
+{
+ Log2(("dbgcProcessArguments: pCmd=%s pszArgs='%s'\n", pCmd->pszCmd, pszArgs));
+
+ /*
+ * Check if we have any argument and if the command takes any.
+ */
+ *pcArgs = 0;
+ /* strip leading blanks. */
+ while (*pszArgs && RT_C_IS_BLANK(*pszArgs))
+ pszArgs++;
+ if (!*pszArgs)
+ {
+ if (!pCmd->cArgsMin)
+ return VINF_SUCCESS;
+ return VERR_PARSE_TOO_FEW_ARGUMENTS;
+ }
+ /** @todo fixme - foo() doesn't work. */
+ if (!pCmd->cArgsMax)
+ return VERR_PARSE_TOO_MANY_ARGUMENTS;
+
+ /*
+ * This is a hack, it's "temporary" and should go away "when" the parser is
+ * modified to match arguments while parsing.
+ */
+ if ( pCmd->cArgsMax == 1
+ && pCmd->cArgsMin == 1
+ && pCmd->cArgDescs == 1
+ && ( pCmd->paArgDescs[0].enmCategory == DBGCVAR_CAT_STRING
+ || pCmd->paArgDescs[0].enmCategory == DBGCVAR_CAT_SYMBOL)
+ && cArgs >= 1)
+ {
+ *pcArgs = 1;
+ RTStrStripR(pszArgs);
+ return dbgcEvalSubString(pDbgc, pszArgs, strlen(pszArgs), &paArgs[0]);
+ }
+
+ /*
+ * The parse loop.
+ */
+ PDBGCVAR pArg0 = &paArgs[0];
+ PDBGCVAR pArg = pArg0;
+ *pcArgs = 0;
+ do
+ {
+ /*
+ * Can we have another argument?
+ */
+ if (*pcArgs >= pCmd->cArgsMax)
+ return VERR_PARSE_TOO_MANY_ARGUMENTS;
+ if (pArg >= &paArgs[cArgs])
+ return VERR_PARSE_ARGUMENT_OVERFLOW;
+
+ /*
+ * Find the end of the argument.
+ */
+ int cPar = 0;
+ char chQuote = '\0';
+ char *pszEnd = NULL;
+ char *psz = pszArgs;
+ char ch;
+ bool fBinary = false;
+ for (;;)
+ {
+ /*
+ * Check for the end.
+ */
+ if ((ch = *psz) == '\0')
+ {
+ if (chQuote)
+ return VERR_PARSE_UNBALANCED_QUOTE;
+ if (cPar)
+ return VERR_PARSE_UNBALANCED_PARENTHESIS;
+ pszEnd = psz;
+ break;
+ }
+ /*
+ * When quoted we ignore everything but the quotation char.
+ * We use the REXX way of escaping the quotation char, i.e. double occurrence.
+ */
+ else if (ch == '\'' || ch == '"' || ch == '`')
+ {
+ if (chQuote)
+ {
+ /* end quote? */
+ if (ch == chQuote)
+ {
+ if (psz[1] == ch)
+ psz++; /* skip the escaped quote char */
+ else
+ chQuote = '\0'; /* end of quoted string. */
+ }
+ }
+ else
+ chQuote = ch; /* open new quote */
+ }
+ /*
+ * Parenthesis can of course be nested.
+ */
+ else if (ch == '(')
+ {
+ cPar++;
+ fBinary = false;
+ }
+ else if (ch == ')')
+ {
+ if (!cPar)
+ return VERR_PARSE_UNBALANCED_PARENTHESIS;
+ cPar--;
+ fBinary = true;
+ }
+ else if (!chQuote && !cPar)
+ {
+ /*
+ * Encountering blanks may mean the end of it all. A binary operator
+ * will force continued parsing.
+ */
+ if (RT_C_IS_BLANK(*psz))
+ {
+ pszEnd = psz++; /* just in case. */
+ while (RT_C_IS_BLANK(*psz))
+ psz++;
+ PCDBGCOP pOp = dbgcOperatorLookup(pDbgc, psz, fBinary, ' ');
+ if (!pOp || pOp->fBinary != fBinary)
+ break; /* the end. */
+ psz += pOp->cchName;
+ while (RT_C_IS_BLANK(*psz)) /* skip blanks so we don't get here again */
+ psz++;
+ fBinary = false;
+ continue;
+ }
+
+ /*
+ * Look for operators without a space up front.
+ */
+ if (dbgcIsOpChar(*psz))
+ {
+ PCDBGCOP pOp = dbgcOperatorLookup(pDbgc, psz, fBinary, ' ');
+ if (pOp)
+ {
+ if (pOp->fBinary != fBinary)
+ {
+ pszEnd = psz;
+ /** @todo this is a parsing error really. */
+ break; /* the end. */
+ }
+ psz += pOp->cchName;
+ while (RT_C_IS_BLANK(*psz)) /* skip blanks so we don't get here again */
+ psz++;
+ fBinary = false;
+ continue;
+ }
+ }
+ fBinary = true;
+ }
+
+ /* next char */
+ psz++;
+ }
+ *pszEnd = '\0';
+ /* (psz = next char to process) */
+
+ /*
+ * Parse and evaluate the argument.
+ */
+ int rc = dbgcEvalSub(pDbgc, pszArgs, strlen(pszArgs), DBGCVAR_CAT_ANY, pArg);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ /*
+ * Next.
+ */
+ pArg++;
+ (*pcArgs)++;
+ pszArgs = psz;
+ while (*pszArgs && RT_C_IS_BLANK(*pszArgs))
+ pszArgs++;
+ } while (*pszArgs);
+
+ /*
+ * Match the arguments.
+ */
+ return dbgcEvalSubMatchVars(pDbgc, pCmd->cArgsMin, pCmd->cArgsMax, pCmd->paArgDescs, pCmd->cArgDescs, pArg0, pArg - pArg0);
+}
+
+
+/**
+ * Evaluate one command.
+ *
+ * @returns VBox status code. This is also stored in DBGC::rcCmd.
+ *
+ * @param pDbgc Debugger console instance data.
+ * @param pszCmd Pointer to the command.
+ * @param cchCmd Length of the command.
+ * @param fNoExecute Indicates that no commands should actually be executed.
+ *
+ * @todo Change pszCmd into argc/argv?
+ */
+int dbgcEvalCommand(PDBGC pDbgc, char *pszCmd, size_t cchCmd, bool fNoExecute)
+{
+ char *pszCmdInput = pszCmd;
+
+ /*
+ * Skip blanks.
+ */
+ while (RT_C_IS_BLANK(*pszCmd))
+ pszCmd++, cchCmd--;
+
+ /* external command? */
+ bool const fExternal = *pszCmd == '.';
+ if (fExternal)
+ pszCmd++, cchCmd--;
+
+ /*
+ * Find arguments.
+ */
+ char *pszArgs = pszCmd;
+ while (RT_C_IS_ALNUM(*pszArgs))
+ pszArgs++;
+ if (*pszArgs && (!RT_C_IS_BLANK(*pszArgs) || pszArgs == pszCmd))
+ {
+ DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "Syntax error: Invalid command '%s'!\n", pszCmdInput);
+ return pDbgc->rcCmd = VINF_PARSE_INVALD_COMMAND_NAME;
+ }
+
+ /*
+ * Find the command.
+ */
+ PCDBGCCMD pCmd = dbgcRoutineLookup(pDbgc, pszCmd, pszArgs - pszCmd, fExternal);
+ if (!pCmd)
+ {
+ DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "Syntax error: Unknown command '%s'!\n", pszCmdInput);
+ return pDbgc->rcCmd = VINF_PARSE_COMMAND_NOT_FOUND;
+ }
+
+ /*
+ * Parse arguments (if any).
+ */
+ unsigned cArgs;
+ int rc = dbgcProcessArguments(pDbgc, pCmd, pszArgs, &pDbgc->aArgs[pDbgc->iArg], RT_ELEMENTS(pDbgc->aArgs) - pDbgc->iArg, &cArgs);
+ if (RT_SUCCESS(rc))
+ {
+ AssertMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc));
+
+ /*
+ * Execute the command.
+ */
+ if (!fNoExecute)
+ rc = pCmd->pfnHandler(pCmd, &pDbgc->CmdHlp, pDbgc->pVM, &pDbgc->aArgs[0], cArgs);
+ pDbgc->rcCmd = rc;
+ if (rc == VERR_DBGC_COMMAND_FAILED)
+ rc = VINF_SUCCESS;
+ }
+ else
+ {
+ pDbgc->rcCmd = rc;
+
+ /* report parse / eval error. */
+ switch (rc)
+ {
+ case VERR_PARSE_TOO_FEW_ARGUMENTS:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Syntax error: Too few arguments. Minimum is %d for command '%s'.\n", pCmd->cArgsMin, pCmd->pszCmd);
+ break;
+ case VERR_PARSE_TOO_MANY_ARGUMENTS:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Syntax error: Too many arguments. Maximum is %d for command '%s'.\n", pCmd->cArgsMax, pCmd->pszCmd);
+ break;
+ case VERR_PARSE_ARGUMENT_OVERFLOW:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Syntax error: Too many arguments.\n");
+ break;
+ case VERR_PARSE_UNBALANCED_QUOTE:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Syntax error: Unbalanced quote (argument %d).\n", cArgs);
+ break;
+ case VERR_PARSE_UNBALANCED_PARENTHESIS:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Syntax error: Unbalanced parenthesis (argument %d).\n", cArgs);
+ break;
+ case VERR_PARSE_EMPTY_ARGUMENT:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Syntax error: An argument or subargument contains nothing useful (argument %d).\n", cArgs);
+ break;
+ case VERR_PARSE_UNEXPECTED_OPERATOR:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Syntax error: Invalid operator usage (argument %d).\n", cArgs);
+ break;
+ case VERR_PARSE_INVALID_NUMBER:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Syntax error: Ivalid numeric value (argument %d). If a string was the intention, then quote it.\n", cArgs);
+ break;
+ case VERR_PARSE_NUMBER_TOO_BIG:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Error: Numeric overflow (argument %d).\n", cArgs);
+ break;
+ case VERR_PARSE_INVALID_OPERATION:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Error: Invalid operation attempted (argument %d).\n", cArgs);
+ break;
+ case VERR_PARSE_FUNCTION_NOT_FOUND:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Error: Function not found (argument %d).\n", cArgs);
+ break;
+ case VERR_PARSE_NOT_A_FUNCTION:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Error: The function specified is not a function (argument %d).\n", cArgs);
+ break;
+ case VERR_PARSE_NO_MEMORY:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Error: Out memory in the regular heap! Expect odd stuff to happen...\n", cArgs);
+ break;
+ case VERR_PARSE_INCORRECT_ARG_TYPE:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Error: Incorrect argument type (argument %d?).\n", cArgs);
+ break;
+ case VERR_PARSE_VARIABLE_NOT_FOUND:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Error: An undefined variable was referenced (argument %d).\n", cArgs);
+ break;
+ case VERR_PARSE_CONVERSION_FAILED:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Error: A conversion between two types failed (argument %d).\n", cArgs);
+ break;
+ case VERR_PARSE_NOT_IMPLEMENTED:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Error: You hit a debugger feature which isn't implemented yet (argument %d).\n", cArgs);
+ break;
+ case VERR_PARSE_BAD_RESULT_TYPE:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Error: Couldn't satisfy a request for a specific result type (argument %d). (Usually applies to symbols)\n", cArgs);
+ break;
+ case VERR_PARSE_WRITEONLY_SYMBOL:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp,
+ "Error: Cannot get symbol, it's set only (argument %d).\n", cArgs);
+ break;
+
+ case VERR_DBGC_COMMAND_FAILED:
+ break;
+
+ default:
+ rc = DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "Error: Unknown error %d!\n", rc);
+ break;
+ }
+ }
+ return rc;
+}
+
diff --git a/src/VBox/Debugger/DBGCGdbRemoteStub.cpp b/src/VBox/Debugger/DBGCGdbRemoteStub.cpp
index 64104f9ee..ec5747ecc 100644
--- a/src/VBox/Debugger/DBGCGdbRemoteStub.cpp
+++ b/src/VBox/Debugger/DBGCGdbRemoteStub.cpp
@@ -1,10 +1,10 @@
-/* $Id: DBGCGdbRemoteStub.cpp $ */
+/* $Id: DBGCGdbRemoteStub.cpp 35628 2011-01-19 14:58:26Z vboxsync $ */
/** @file
* DBGC - Debugger Console, GDB Remote Stub.
*/
/*
- * 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;
diff --git a/src/VBox/Debugger/DBGCInternal.h b/src/VBox/Debugger/DBGCInternal.h
index 72ccd7e9b..7296bdb9c 100644
--- a/src/VBox/Debugger/DBGCInternal.h
+++ b/src/VBox/Debugger/DBGCInternal.h
@@ -1,10 +1,10 @@
-/* $Id: DBGCInternal.h $ */
+/* $Id: DBGCInternal.h 35694 2011-01-24 17:35:59Z vboxsync $ */
/** @file
* DBGC - Debugger Console, Internal Header File.
*/
/*
- * 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;
@@ -79,7 +79,7 @@ typedef struct DBGCBP
/** Pointer to the next breakpoint in the list. */
struct DBGCBP *pNext;
/** The breakpoint identifier. */
- RTUINT iBp;
+ uint32_t iBp;
/** The size of the command. */
size_t cchCmd;
/** The command to execute when the breakpoint is hit. */
@@ -151,7 +151,7 @@ typedef struct DBGC
/** Pointer to the current VM. */
PVM pVM;
- /** The current virtual CPU id. */
+ /** The ID of current virtual CPU. */
VMCPUID idCpu;
/** The current address space handle. */
RTDBGAS hDbgAs;
@@ -238,6 +238,9 @@ typedef struct DBGC
/** rc from the last dbgcHlpPrintfV(). */
int rcOutput;
+ /** The last character we wrote. */
+ char chLastOutput;
+
/** rc from the last command. */
int rcCmd;
/** @} */
@@ -315,6 +318,12 @@ typedef struct DBGCOP
PFNDBGCOPUNARY pfnHandlerUnary;
/** Binary operator handler. */
PFNDBGCOPBINARY pfnHandlerBinary;
+ /** The category of the 1st argument.
+ * Set to DBGCVAR_CAT_ANY if anything goes. */
+ DBGCVARCAT enmCatArg1;
+ /** The category of the 2nd argument.
+ * Set to DBGCVAR_CAT_ANY if anything goes. */
+ DBGCVARCAT enmCatArg2;
/** Operator description. */
const char *pszDescription;
} DBGCOP;
@@ -385,24 +394,16 @@ int dbgcBpDelete(PDBGC pDbgc, RTUINT iBp);
PDBGCBP dbgcBpGet(PDBGC pDbgc, RTUINT iBp);
int dbgcBpExec(PDBGC pDbgc, RTUINT iBp);
-void dbgcVarInit(PDBGCVAR pVar);
-void dbgcVarSetGCFlat(PDBGCVAR pVar, RTGCPTR GCFlat);
-void dbgcVarSetGCFlatByteRange(PDBGCVAR pVar, RTGCPTR GCFlat, uint64_t cb);
-void dbgcVarSetU64(PDBGCVAR pVar, uint64_t u64);
-void dbgcVarSetVar(PDBGCVAR pVar, PCDBGCVAR pVar2);
-void dbgcVarSetDbgfAddr(PDBGCVAR pVar, PCDBGFADDRESS pAddress);
-void dbgcVarSetNoRange(PDBGCVAR pVar);
-void dbgcVarSetByteRange(PDBGCVAR pVar, uint64_t cb);
-int dbgcVarToDbgfAddr(PDBGC pDbgc, PCDBGCVAR pVar, PDBGFADDRESS pAddress);
-
-int dbgcEvalSub(PDBGC pDbgc, char *pszExpr, size_t cchExpr, PDBGCVAR pResult);
-int dbgcProcessCommand(PDBGC pDbgc, char *pszCmd, size_t cchCmd, bool fNoExecute);
+void dbgcEvalInit(void);
+int dbgcEvalSub(PDBGC pDbgc, char *pszExpr, size_t cchExpr, DBGCVARCAT enmCategory, PDBGCVAR pResult);
+int dbgcEvalCommand(PDBGC pDbgc, char *pszCmd, size_t cchCmd, bool fNoExecute);
int dbgcSymbolGet(PDBGC pDbgc, const char *pszSymbol, DBGCVARTYPE enmType, PDBGCVAR pResult);
PCDBGCSYM dbgcLookupRegisterSymbol(PDBGC pDbgc, const char *pszSymbol);
PCDBGCOP dbgcOperatorLookup(PDBGC pDbgc, const char *pszExpr, bool fPreferBinary, char chPrev);
PCDBGCCMD dbgcRoutineLookup(PDBGC pDbgc, const char *pachName, size_t cchName, bool fExternal);
+DECLCALLBACK(int) dbgcOpRegister(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
DECLCALLBACK(int) dbgcOpAddrFlat(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
DECLCALLBACK(int) dbgcOpAddrHost(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
DECLCALLBACK(int) dbgcOpAddrPhys(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
@@ -432,3 +433,4 @@ extern const unsigned g_cOps;
#endif
+
diff --git a/src/VBox/Debugger/DBGCOps.cpp b/src/VBox/Debugger/DBGCOps.cpp
index ed8f18996..fac77b38d 100644
--- a/src/VBox/Debugger/DBGCOps.cpp
+++ b/src/VBox/Debugger/DBGCOps.cpp
@@ -1,10 +1,10 @@
-/* $Id: DBGCOps.cpp $ */
+/* $Id: DBGCOps.cpp 35637 2011-01-19 17:42:59Z vboxsync $ */
/** @file
* DBGC - Debugger Console, Operators.
*/
/*
- * 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;
@@ -22,24 +22,13 @@
#define LOG_GROUP LOG_GROUP_DBGC
#include <VBox/dbg.h>
#include <VBox/vmm/dbgf.h>
-#include <VBox/vmm/vm.h>
-#include <VBox/vmm/vmm.h>
-#include <VBox/vmm/mm.h>
-#include <VBox/vmm/pgm.h>
-#include <VBox/vmm/selm.h>
-#include <VBox/dis.h>
#include <VBox/param.h>
#include <VBox/err.h>
#include <VBox/log.h>
-#include <iprt/alloc.h>
-#include <iprt/alloca.h>
-#include <iprt/string.h>
#include <iprt/assert.h>
-#include <iprt/ctype.h>
-
-#include <stdlib.h>
-#include <stdio.h>
+#include <iprt/mem.h>
+#include <iprt/string.h>
#include "DBGCInternal.h"
@@ -52,7 +41,6 @@ static DECLCALLBACK(int) dbgcOpPluss(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResu
static DECLCALLBACK(int) dbgcOpBooleanNot(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpBitwiseNot(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpVar(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
-static DECLCALLBACK(int) dbgcOpRegister(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpAddrFar(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpMult(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
@@ -123,9 +111,6 @@ static DECLCALLBACK(int) dbgcOpRangeTo(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR p
case DBGCVAR_TYPE_HC_FLAT: \
(pResult)->u.pvHCFlat = (void *)((uintptr_t)(pResult)->u.pvHCFlat Operator u64Right); \
break; \
- case DBGCVAR_TYPE_HC_FAR: \
- (pResult)->u.HCFar.off = (pResult)->u.HCFar.off Operator u64Right; \
- break; \
case DBGCVAR_TYPE_HC_PHYS: \
(pResult)->u.HCPhys = (pResult)->u.HCPhys Operator u64Right; \
break; \
@@ -170,32 +155,32 @@ const DBGCOP g_aOps[] =
{
/* szName is initialized as a 4 char array because of M$C elsewise optimizing it away in /Ox mode (the 'const char' vs 'char' problem). */
/* szName, cchName, fBinary, iPrecedence, pfnHandlerUnary, pfnHandlerBitwise */
- { {'-'}, 1, false, 1, dbgcOpMinus, NULL, "Unary minus." },
- { {'+'}, 1, false, 1, dbgcOpPluss, NULL, "Unary plus." },
- { {'!'}, 1, false, 1, dbgcOpBooleanNot, NULL, "Boolean not." },
- { {'~'}, 1, false, 1, dbgcOpBitwiseNot, NULL, "Bitwise complement." },
- { {':'}, 1, true, 2, NULL, dbgcOpAddrFar, "Far pointer." },
- { {'%'}, 1, false, 3, dbgcOpAddrFlat, NULL, "Flat address." },
- { {'%','%'}, 2, false, 3, dbgcOpAddrPhys, NULL, "Physical address." },
- { {'#'}, 1, false, 3, dbgcOpAddrHost, NULL, "Flat host address." },
- { {'#','%','%'}, 3, false, 3, dbgcOpAddrHostPhys, NULL, "Physical host address." },
- { {'$'}, 1, false, 3, dbgcOpVar, NULL, "Reference a variable." },
- { {'@'}, 1, false, 3, dbgcOpRegister, NULL, "Reference a register." },
- { {'*'}, 1, true, 10, NULL, dbgcOpMult, "Multiplication." },
- { {'/'}, 1, true, 11, NULL, dbgcOpDiv, "Division." },
- { {'%'}, 1, true, 12, NULL, dbgcOpMod, "Modulus." },
- { {'+'}, 1, true, 13, NULL, dbgcOpAdd, "Addition." },
- { {'-'}, 1, true, 14, NULL, dbgcOpSub, "Subtraction." },
- { {'<','<'}, 2, true, 15, NULL, dbgcOpBitwiseShiftLeft, "Bitwise left shift." },
- { {'>','>'}, 2, true, 16, NULL, dbgcOpBitwiseShiftRight, "Bitwise right shift." },
- { {'&'}, 1, true, 17, NULL, dbgcOpBitwiseAnd, "Bitwise and." },
- { {'^'}, 1, true, 18, NULL, dbgcOpBitwiseXor, "Bitwise exclusiv or." },
- { {'|'}, 1, true, 19, NULL, dbgcOpBitwiseOr, "Bitwise inclusive or." },
- { {'&','&'}, 2, true, 20, NULL, dbgcOpBooleanAnd, "Boolean and." },
- { {'|','|'}, 2, true, 21, NULL, dbgcOpBooleanOr, "Boolean or." },
- { {'L'}, 1, true, 22, NULL, dbgcOpRangeLength, "Range elements." },
- { {'L','B'}, 2, true, 23, NULL, dbgcOpRangeLengthBytes, "Range bytes." },
- { {'T'}, 1, true, 24, NULL, dbgcOpRangeTo, "Range to." }
+ { {'-'}, 1, false, 1, dbgcOpMinus, NULL, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Unary minus." },
+ { {'+'}, 1, false, 1, dbgcOpPluss, NULL, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Unary plus." },
+ { {'!'}, 1, false, 1, dbgcOpBooleanNot, NULL, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Boolean not." },
+ { {'~'}, 1, false, 1, dbgcOpBitwiseNot, NULL, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Bitwise complement." },
+ { {':'}, 1, true, 2, NULL, dbgcOpAddrFar, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Far pointer." },
+ { {'%'}, 1, false, 3, dbgcOpAddrFlat, NULL, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Flat address." },
+ { {'%','%'}, 2, false, 3, dbgcOpAddrPhys, NULL, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Physical address." },
+ { {'#'}, 1, false, 3, dbgcOpAddrHost, NULL, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Flat host address." },
+ { {'#','%','%'}, 3, false, 3, dbgcOpAddrHostPhys, NULL, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Physical host address." },
+ { {'$'}, 1, false, 3, dbgcOpVar, NULL, DBGCVAR_CAT_STRING, DBGCVAR_CAT_ANY, "Reference a variable." },
+ { {'@'}, 1, false, 3, dbgcOpRegister, NULL, DBGCVAR_CAT_STRING, DBGCVAR_CAT_ANY, "Reference a register." },
+ { {'*'}, 1, true, 10, NULL, dbgcOpMult, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Multiplication." },
+ { {'/'}, 1, true, 11, NULL, dbgcOpDiv, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Division." },
+ { {'%'}, 1, true, 12, NULL, dbgcOpMod, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Modulus." },
+ { {'+'}, 1, true, 13, NULL, dbgcOpAdd, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Addition." },
+ { {'-'}, 1, true, 14, NULL, dbgcOpSub, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Subtraction." },
+ { {'<','<'}, 2, true, 15, NULL, dbgcOpBitwiseShiftLeft, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Bitwise left shift." },
+ { {'>','>'}, 2, true, 16, NULL, dbgcOpBitwiseShiftRight, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Bitwise right shift." },
+ { {'&'}, 1, true, 17, NULL, dbgcOpBitwiseAnd, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Bitwise and." },
+ { {'^'}, 1, true, 18, NULL, dbgcOpBitwiseXor, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Bitwise exclusiv or." },
+ { {'|'}, 1, true, 19, NULL, dbgcOpBitwiseOr, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Bitwise inclusive or." },
+ { {'&','&'}, 2, true, 20, NULL, dbgcOpBooleanAnd, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Boolean and." },
+ { {'|','|'}, 2, true, 21, NULL, dbgcOpBooleanOr, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Boolean or." },
+ { {'L'}, 1, true, 22, NULL, dbgcOpRangeLength, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Range elements." },
+ { {'L','B'}, 2, true, 23, NULL, dbgcOpRangeLengthBytes, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Range bytes." },
+ { {'T'}, 1, true, 24, NULL, dbgcOpRangeTo, DBGCVAR_CAT_ANY, DBGCVAR_CAT_ANY, "Range to." }
};
/** Number of operators in the operator array. */
@@ -227,9 +212,6 @@ static int dbgcOpHelperGetNumber(PDBGC pDbgc, PCDBGCVAR pArg, uint64_t *pu64Ret)
case DBGCVAR_TYPE_HC_FLAT:
*pu64Ret = (uintptr_t)Var.u.pvHCFlat;
break;
- case DBGCVAR_TYPE_HC_FAR:
- *pu64Ret = Var.u.HCFar.off;
- break;
case DBGCVAR_TYPE_HC_PHYS:
*pu64Ret = Var.u.HCPhys;
break;
@@ -279,9 +261,6 @@ static DECLCALLBACK(int) dbgcOpMinus(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResu
case DBGCVAR_TYPE_HC_FLAT:
pResult->u.pvHCFlat = (void *) -(intptr_t)pResult->u.pvHCFlat;
break;
- case DBGCVAR_TYPE_HC_FAR:
- pResult->u.HCFar.off = -(int32_t)pResult->u.HCFar.off;
- break;
case DBGCVAR_TYPE_HC_PHYS:
pResult->u.HCPhys = (RTHCPHYS) -(int64_t)pResult->u.HCPhys;
break;
@@ -319,7 +298,6 @@ static DECLCALLBACK(int) dbgcOpPluss(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResu
case DBGCVAR_TYPE_GC_FAR:
case DBGCVAR_TYPE_GC_PHYS:
case DBGCVAR_TYPE_HC_FLAT:
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
case DBGCVAR_TYPE_NUMBER:
break;
@@ -362,9 +340,6 @@ static DECLCALLBACK(int) dbgcOpBooleanNot(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR
case DBGCVAR_TYPE_HC_FLAT:
pResult->u.u64Number = !pResult->u.pvHCFlat;
break;
- case DBGCVAR_TYPE_HC_FAR:
- pResult->u.u64Number = !pResult->u.HCFar.off && pResult->u.HCFar.sel <= 3;
- break;
case DBGCVAR_TYPE_HC_PHYS:
pResult->u.u64Number = !pResult->u.HCPhys;
break;
@@ -413,9 +388,6 @@ static DECLCALLBACK(int) dbgcOpBitwiseNot(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR
case DBGCVAR_TYPE_HC_FLAT:
pResult->u.pvHCFlat = (void *)~(uintptr_t)pResult->u.pvHCFlat;
break;
- case DBGCVAR_TYPE_HC_FAR:
- pResult->u.HCFar.off= ~pResult->u.HCFar.off;
- break;
case DBGCVAR_TYPE_HC_PHYS:
pResult->u.HCPhys = ~pResult->u.HCPhys;
break;
@@ -480,14 +452,15 @@ static DECLCALLBACK(int) dbgcOpVar(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult
* @param pArg The argument.
* @param pResult Where to store the result.
*/
-static DECLCALLBACK(int) dbgcOpRegister(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
+DECLCALLBACK(int) dbgcOpRegister(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
{
LogFlow(("dbgcOpRegister: %s\n", pArg->u.pszString));
/*
* Parse sanity.
*/
- if (pArg->enmType != DBGCVAR_TYPE_STRING)
+ if ( pArg->enmType != DBGCVAR_TYPE_STRING
+ && pArg->enmType != DBGCVAR_TYPE_SYMBOL)
return VERR_PARSE_INCORRECT_ARG_TYPE;
/*
@@ -498,7 +471,6 @@ static DECLCALLBACK(int) dbgcOpRegister(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pR
int rc = DBGFR3RegNmQuery(pDbgc->pVM, pDbgc->idCpu, pArg->u.pszString, &Value, &enmType);
if (RT_SUCCESS(rc))
{
- rc = VERR_INTERNAL_ERROR_5;
switch (enmType)
{
case DBGFREGVALTYPE_U8:
@@ -538,6 +510,7 @@ static DECLCALLBACK(int) dbgcOpRegister(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pR
case DBGFREGVALTYPE_32BIT_HACK:
break;
}
+ rc = VERR_INTERNAL_ERROR_5;
}
return rc;
}
@@ -556,58 +529,8 @@ static DECLCALLBACK(int) dbgcOpRegister(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pR
DECLCALLBACK(int) dbgcOpAddrFlat(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
{
LogFlow(("dbgcOpAddrFlat\n"));
- int rc;
- *pResult = *pArg;
-
- switch (pArg->enmType)
- {
- case DBGCVAR_TYPE_GC_FLAT:
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_GC_FAR:
- {
- Assert(pDbgc->pVM);
- DBGFADDRESS Address;
- rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
- if (RT_SUCCESS(rc))
- {
- pResult->enmType = DBGCVAR_TYPE_GC_FLAT;
- pResult->u.GCFlat = Address.FlatPtr;
- return VINF_SUCCESS;
- }
- return VERR_PARSE_CONVERSION_FAILED;
- }
-
- case DBGCVAR_TYPE_GC_PHYS:
- //rc = MMR3PhysGCPhys2GCVirtEx(pDbgc->pVM, pResult->u.GCPhys, ..., &pResult->u.GCFlat); - yea, sure.
- return VERR_PARSE_INCORRECT_ARG_TYPE;
-
- case DBGCVAR_TYPE_HC_FLAT:
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_HC_FAR:
- return VERR_PARSE_INCORRECT_ARG_TYPE;
-
- case DBGCVAR_TYPE_HC_PHYS:
- Assert(pDbgc->pVM);
- pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
- rc = MMR3HCPhys2HCVirt(pDbgc->pVM, pResult->u.HCPhys, &pResult->u.pvHCFlat);
- if (RT_SUCCESS(rc))
- return VINF_SUCCESS;
- return VERR_PARSE_CONVERSION_FAILED;
-
- case DBGCVAR_TYPE_NUMBER:
- pResult->enmType = DBGCVAR_TYPE_GC_FLAT;
- pResult->u.GCFlat = (RTGCPTR)pResult->u.u64Number;
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_STRING:
- return dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_GC_FLAT, pResult);
-
- case DBGCVAR_TYPE_UNKNOWN:
- default:
- return VERR_PARSE_INCORRECT_ARG_TYPE;
- }
+ DBGCVARTYPE enmType = DBGCVAR_ISHCPOINTER(pArg->enmType) ? DBGCVAR_TYPE_HC_FLAT : DBGCVAR_TYPE_GC_FLAT;
+ return DBGCCmdHlpConvert(&pDbgc->CmdHlp, pArg, enmType, true /*fConvSyms*/, pResult);
}
@@ -624,65 +547,8 @@ DECLCALLBACK(int) dbgcOpAddrFlat(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
DECLCALLBACK(int) dbgcOpAddrPhys(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
{
LogFlow(("dbgcOpAddrPhys\n"));
- int rc;
- DBGFADDRESS Address;
-
- *pResult = *pArg;
- switch (pArg->enmType)
- {
- case DBGCVAR_TYPE_GC_FLAT:
- Assert(pDbgc->pVM);
- pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
- rc = DBGFR3AddrToPhys(pDbgc->pVM, pDbgc->idCpu,
- DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
- &pResult->u.GCPhys);
- if (RT_SUCCESS(rc))
- return VINF_SUCCESS;
- return VERR_PARSE_CONVERSION_FAILED;
-
- case DBGCVAR_TYPE_GC_FAR:
- Assert(pDbgc->pVM);
- rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
- if (RT_SUCCESS(rc))
- {
- pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
- rc = DBGFR3AddrToPhys(pDbgc->pVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys);
- if (RT_SUCCESS(rc))
- return VINF_SUCCESS;
- }
- return VERR_PARSE_CONVERSION_FAILED;
-
- case DBGCVAR_TYPE_GC_PHYS:
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_HC_FLAT:
- Assert(pDbgc->pVM);
- pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
- rc = PGMR3DbgR3Ptr2GCPhys(pDbgc->pVM, pArg->u.pvHCFlat, &pResult->u.GCPhys);
- if (RT_SUCCESS(rc))
- return VINF_SUCCESS;
- /** @todo more memory types! */
- return VERR_PARSE_CONVERSION_FAILED;
-
- case DBGCVAR_TYPE_HC_FAR:
- return VERR_PARSE_INCORRECT_ARG_TYPE;
-
- case DBGCVAR_TYPE_HC_PHYS:
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_NUMBER:
- pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
- pResult->u.GCPhys = (RTGCPHYS)pResult->u.u64Number;
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_STRING:
- return dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_GC_PHYS, pResult);
-
- case DBGCVAR_TYPE_UNKNOWN:
- default:
- return VERR_PARSE_INCORRECT_ARG_TYPE;
- }
- return VINF_SUCCESS;
+ DBGCVARTYPE enmType = DBGCVAR_ISHCPOINTER(pArg->enmType) ? DBGCVAR_TYPE_HC_PHYS : DBGCVAR_TYPE_GC_PHYS;
+ return DBGCCmdHlpConvert(&pDbgc->CmdHlp, pArg, enmType, true /*fConvSyms*/, pResult);
}
@@ -699,74 +565,7 @@ DECLCALLBACK(int) dbgcOpAddrPhys(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
DECLCALLBACK(int) dbgcOpAddrHostPhys(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
{
LogFlow(("dbgcOpAddrPhys\n"));
- DBGFADDRESS Address;
- int rc;
-
- *pResult = *pArg;
- switch (pArg->enmType)
- {
- case DBGCVAR_TYPE_GC_FLAT:
- Assert(pDbgc->pVM);
- pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
- rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu,
- DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
- &pResult->u.GCPhys);
- if (RT_SUCCESS(rc))
- return VINF_SUCCESS;
- return VERR_PARSE_CONVERSION_FAILED;
-
- case DBGCVAR_TYPE_GC_FAR:
- {
- Assert(pDbgc->pVM);
- rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
- if (RT_SUCCESS(rc))
- {
- pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
- rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys);
- if (RT_SUCCESS(rc))
- return VINF_SUCCESS;
- }
- return VERR_PARSE_CONVERSION_FAILED;
- }
-
- case DBGCVAR_TYPE_GC_PHYS:
- Assert(pDbgc->pVM);
- pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
- rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu,
- DBGFR3AddrFromPhys(pDbgc->pVM, &Address, pArg->u.GCPhys),
- &pResult->u.GCPhys);
- if (RT_SUCCESS(rc))
- return VINF_SUCCESS;
- return VERR_PARSE_CONVERSION_FAILED;
-
- case DBGCVAR_TYPE_HC_FLAT:
- Assert(pDbgc->pVM);
- pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
- rc = PGMR3DbgR3Ptr2HCPhys(pDbgc->pVM, pArg->u.pvHCFlat, &pResult->u.HCPhys);
- if (RT_SUCCESS(rc))
- return VINF_SUCCESS;
- /** @todo more memory types! */
- return VERR_PARSE_CONVERSION_FAILED;
-
- case DBGCVAR_TYPE_HC_FAR:
- return VERR_PARSE_INCORRECT_ARG_TYPE;
-
- case DBGCVAR_TYPE_HC_PHYS:
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_NUMBER:
- pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
- pResult->u.HCPhys = (RTGCPHYS)pResult->u.u64Number;
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_STRING:
- return dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_HC_PHYS, pResult);
-
- case DBGCVAR_TYPE_UNKNOWN:
- default:
- return VERR_PARSE_INCORRECT_ARG_TYPE;
- }
- return VINF_SUCCESS;
+ return DBGCCmdHlpConvert(&pDbgc->CmdHlp, pArg, DBGCVAR_TYPE_HC_PHYS, true /*fConvSyms*/, pResult);
}
@@ -783,67 +582,7 @@ DECLCALLBACK(int) dbgcOpAddrHostPhys(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResu
DECLCALLBACK(int) dbgcOpAddrHost(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
{
LogFlow(("dbgcOpAddrHost\n"));
- int rc;
- DBGFADDRESS Address;
-
- *pResult = *pArg;
- switch (pArg->enmType)
- {
- case DBGCVAR_TYPE_GC_FLAT:
- Assert(pDbgc->pVM);
- pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
- rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu,
- DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
- false /*fReadOnly */,
- &pResult->u.pvHCFlat);
- if (RT_SUCCESS(rc))
- return VINF_SUCCESS;
- return VERR_PARSE_CONVERSION_FAILED;
-
- case DBGCVAR_TYPE_GC_FAR:
- Assert(pDbgc->pVM);
- rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
- if (RT_SUCCESS(rc))
- {
- pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
- rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu, &Address,
- false /*fReadOnly*/, &pResult->u.pvHCFlat);
- if (RT_SUCCESS(rc))
- return VINF_SUCCESS;
- }
- return VERR_PARSE_CONVERSION_FAILED;
-
- case DBGCVAR_TYPE_GC_PHYS:
- Assert(pDbgc->pVM);
- pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
- rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu,
- DBGFR3AddrFromPhys(pDbgc->pVM, &Address, pArg->u.GCPhys),
- false /*fReadOnly */,
- &pResult->u.pvHCFlat);
- if (RT_SUCCESS(rc))
- return VINF_SUCCESS;
- return VERR_PARSE_CONVERSION_FAILED;
-
- case DBGCVAR_TYPE_HC_FLAT:
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_HC_FAR:
- case DBGCVAR_TYPE_HC_PHYS:
- /** @todo !*/
- return VERR_PARSE_CONVERSION_FAILED;
-
- case DBGCVAR_TYPE_NUMBER:
- pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
- pResult->u.pvHCFlat = (void *)(uintptr_t)pResult->u.u64Number;
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_STRING:
- return dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_HC_FLAT, pResult);
-
- case DBGCVAR_TYPE_UNKNOWN:
- default:
- return VERR_PARSE_INCORRECT_ARG_TYPE;
- }
+ return DBGCCmdHlpConvert(&pDbgc->CmdHlp, pArg, DBGCVAR_TYPE_HC_FLAT, true /*fConvSyms*/, pResult);
}
@@ -877,7 +616,6 @@ static DECLCALLBACK(int) dbgcOpAddrFar(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR p
case DBGCVAR_TYPE_GC_FAR:
case DBGCVAR_TYPE_GC_PHYS:
case DBGCVAR_TYPE_HC_FLAT:
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
case DBGCVAR_TYPE_UNKNOWN:
default:
@@ -894,7 +632,7 @@ static DECLCALLBACK(int) dbgcOpAddrFar(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR p
break;
case DBGCVAR_TYPE_HC_FLAT:
- pResult->u.HCFar.off = pArg2->u.GCFlat;
+ pResult->u.pvHCFlat = (void *)(uintptr_t)pArg2->u.GCFlat;
pResult->enmType = DBGCVAR_TYPE_GC_FAR;
break;
@@ -916,7 +654,6 @@ static DECLCALLBACK(int) dbgcOpAddrFar(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR p
case DBGCVAR_TYPE_GC_FAR:
case DBGCVAR_TYPE_GC_PHYS:
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
case DBGCVAR_TYPE_UNKNOWN:
default:
@@ -1036,7 +773,6 @@ static DECLCALLBACK(int) dbgcOpAdd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2
switch (pArg2->enmType)
{
case DBGCVAR_TYPE_HC_FLAT:
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
return VERR_PARSE_INVALID_OPERATION;
default:
@@ -1056,7 +792,6 @@ static DECLCALLBACK(int) dbgcOpAdd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2
switch (pArg2->enmType)
{
case DBGCVAR_TYPE_HC_FLAT:
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
return VERR_PARSE_INVALID_OPERATION;
case DBGCVAR_TYPE_NUMBER:
@@ -1082,7 +817,6 @@ static DECLCALLBACK(int) dbgcOpAdd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2
switch (pArg2->enmType)
{
case DBGCVAR_TYPE_HC_FLAT:
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
return VERR_PARSE_INVALID_OPERATION;
default:
@@ -1112,32 +846,6 @@ static DECLCALLBACK(int) dbgcOpAdd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2
break;
/*
- * HC Far
- */
- case DBGCVAR_TYPE_HC_FAR:
- switch (pArg2->enmType)
- {
- case DBGCVAR_TYPE_NUMBER:
- *pResult = *pArg1;
- pResult->u.HCFar.off += (uintptr_t)pArg2->u.u64Number;
- break;
-
- default:
- rc = dbgcOpAddrFlat(pDbgc, pArg1, pResult);
- if (RT_FAILURE(rc))
- return rc;
- rc = dbgcOpAddrHost(pDbgc, pArg2, &Var2);
- if (RT_FAILURE(rc))
- return rc;
- rc = dbgcOpAddrFlat(pDbgc, &Var2, &Var);
- if (RT_FAILURE(rc))
- return rc;
- pResult->u.pvHCFlat = (char *)pResult->u.pvHCFlat + (uintptr_t)Var.u.pvHCFlat;
- break;
- }
- break;
-
- /*
* HC Phys
*/
case DBGCVAR_TYPE_HC_PHYS:
@@ -1225,9 +933,6 @@ static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2
case DBGCVAR_TYPE_GC_FAR:
enmType = DBGCVAR_TYPE_GC_FLAT;
break;
- case DBGCVAR_TYPE_HC_FAR:
- enmType = DBGCVAR_TYPE_HC_FLAT;
- break;
default:
case DBGCVAR_TYPE_STRING:
@@ -1255,7 +960,6 @@ static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2
case DBGCVAR_TYPE_GC_PHYS:
pOp = dbgcOpAddrPhys;
break;
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_FLAT:
pOp = dbgcOpAddrHost;
break;
@@ -1294,7 +998,6 @@ static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2
switch (pArg2->enmType)
{
case DBGCVAR_TYPE_HC_FLAT:
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
return VERR_PARSE_INVALID_OPERATION;
default:
@@ -1314,7 +1017,6 @@ static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2
switch (pArg2->enmType)
{
case DBGCVAR_TYPE_HC_FLAT:
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
return VERR_PARSE_INVALID_OPERATION;
case DBGCVAR_TYPE_NUMBER:
@@ -1340,7 +1042,6 @@ static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2
switch (pArg2->enmType)
{
case DBGCVAR_TYPE_HC_FLAT:
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
return VERR_PARSE_INVALID_OPERATION;
default:
@@ -1370,32 +1071,6 @@ static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2
break;
/*
- * HC Far
- */
- case DBGCVAR_TYPE_HC_FAR:
- switch (pArg2->enmType)
- {
- case DBGCVAR_TYPE_NUMBER:
- *pResult = *pArg1;
- pResult->u.HCFar.off -= (uintptr_t)pArg2->u.u64Number;
- break;
-
- default:
- rc = dbgcOpAddrFlat(pDbgc, pArg1, pResult);
- if (RT_FAILURE(rc))
- return rc;
- rc = dbgcOpAddrHost(pDbgc, pArg2, &Var2);
- if (RT_FAILURE(rc))
- return rc;
- rc = dbgcOpAddrFlat(pDbgc, &Var2, &Var);
- if (RT_FAILURE(rc))
- return rc;
- pResult->u.pvHCFlat = (char *)pResult->u.pvHCFlat - (uintptr_t)Var.u.pvHCFlat;
- break;
- }
- break;
-
- /*
* HC Phys
*/
case DBGCVAR_TYPE_HC_PHYS:
@@ -1688,7 +1363,6 @@ static DECLCALLBACK(int) dbgcOpRangeTo(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR p
case DBGCVAR_TYPE_GC_FAR:
case DBGCVAR_TYPE_STRING:
- case DBGCVAR_TYPE_HC_FAR:
default:
AssertMsgFailed(("Impossible!\n"));
return VERR_PARSE_INVALID_OPERATION;
diff --git a/src/VBox/Debugger/DBGCTcp.cpp b/src/VBox/Debugger/DBGCTcp.cpp
index c9d5d6653..dc7501cf0 100644
--- a/src/VBox/Debugger/DBGCTcp.cpp
+++ b/src/VBox/Debugger/DBGCTcp.cpp
@@ -1,10 +1,10 @@
-/* $Id: DBGCTcp.cpp $ */
+/* $Id: DBGCTcp.cpp 35628 2011-01-19 14:58:26Z vboxsync $ */
/** @file
* DBGC - Debugger Console, TCP backend.
*/
/*
- * 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;
@@ -28,7 +28,7 @@
#include <VBox/log.h>
#include <iprt/assert.h>
-#include <string.h>
+#include <iprt/string.h>
/*******************************************************************************
diff --git a/src/VBox/Debugger/DBGConsole.cpp b/src/VBox/Debugger/DBGConsole.cpp
index 03115487e..e8804020b 100644
--- a/src/VBox/Debugger/DBGConsole.cpp
+++ b/src/VBox/Debugger/DBGConsole.cpp
@@ -1,10 +1,10 @@
-/* $Id: DBGConsole.cpp $ */
+/* $Id: DBGConsole.cpp 35829 2011-02-03 10:18:53Z vboxsync $ */
/** @file
* DBGC - Debugger Console.
*/
/*
- * 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;
@@ -133,67 +133,24 @@
#define LOG_GROUP LOG_GROUP_DBGC
#include <VBox/dbg.h>
#include <VBox/vmm/dbgf.h>
-#include <VBox/vmm/vm.h>
-#include <VBox/vmm/vmm.h>
-#include <VBox/vmm/mm.h>
-#include <VBox/vmm/pgm.h>
-#include <VBox/vmm/selm.h>
-#include <VBox/dis.h>
-#include <VBox/param.h>
#include <VBox/err.h>
#include <VBox/log.h>
#include <iprt/asm.h>
-#include <iprt/alloca.h>
#include <iprt/assert.h>
#include <iprt/mem.h>
#include <iprt/string.h>
-#include <iprt/ctype.h>
-
-#include <stdlib.h>
-#include <stdio.h>
#include "DBGCInternal.h"
#include "DBGPlugIns.h"
/*******************************************************************************
-* Global Variables *
-*******************************************************************************/
-/** Bitmap where set bits indicates the characters the may start an operator name. */
-static uint32_t g_bmOperatorChars[256 / (4*8)];
-
-
-/*******************************************************************************
* Internal Functions *
*******************************************************************************/
static int dbgcProcessLog(PDBGC pDbgc);
-
-/**
- * Initializes g_bmOperatorChars.
- */
-static void dbgcInitOpCharBitMap(void)
-{
- memset(g_bmOperatorChars, 0, sizeof(g_bmOperatorChars));
- for (unsigned iOp = 0; iOp < g_cOps; iOp++)
- ASMBitSet(&g_bmOperatorChars[0], (uint8_t)g_aOps[iOp].szName[0]);
-}
-
-
-/**
- * Checks whether the character may be the start of an operator.
- *
- * @returns true/false.
- * @param ch The character.
- */
-DECLINLINE(bool) dbgcIsOpChar(char ch)
-{
- return ASMBitTest(&g_bmOperatorChars[0], (uint8_t)ch);
-}
-
-
/**
* Resolves a symbol (or tries to do so at least).
*
@@ -201,15 +158,18 @@ DECLINLINE(bool) dbgcIsOpChar(char ch)
* @returns VBox status on failure.
* @param pDbgc The debug console instance.
* @param pszSymbol The symbol name.
- * @param enmType The result type.
+ * @param enmType The result type. Specifying DBGCVAR_TYPE_GC_FAR may
+ * cause failure, avoid it.
* @param pResult Where to store the result.
*/
int dbgcSymbolGet(PDBGC pDbgc, const char *pszSymbol, DBGCVARTYPE enmType, PDBGCVAR pResult)
{
+ int rc;
+
/*
* Builtin?
*/
- PCDBGCSYM pSymDesc = dbgcLookupRegisterSymbol(pDbgc, pszSymbol);
+ PCDBGCSYM pSymDesc = dbgcLookupRegisterSymbol(pDbgc, pszSymbol);
if (pSymDesc)
{
if (!pSymDesc->pfnGet)
@@ -217,37 +177,80 @@ int dbgcSymbolGet(PDBGC pDbgc, const char *pszSymbol, DBGCVARTYPE enmType, PDBGC
return pSymDesc->pfnGet(pSymDesc, &pDbgc->CmdHlp, enmType, pResult);
}
+ /*
+ * A typical register? (Guest only)
+ */
+ static const char s_szSixLetterRegisters[] =
+ "rflags;eflags;"
+ ;
+ static const char s_szThreeLetterRegisters[] =
+ "eax;rax;" "r10;" "r8d;r8w;r8b;" "cr0;" "dr0;"
+ "ebx;rbx;" "r11;" "r9d;r9w;r8b;" "dr1;"
+ "ecx;rcx;" "r12;" "cr2;" "dr2;"
+ "edx;rdx;" "r13;" "cr3;" "dr3;"
+ "edi;rdi;dil;" "r14;" "cr4;" "dr4;"
+ "esi;rsi;sil;" "r15;" "cr8;"
+ "ebp;rbp;"
+ "esp;rsp;" "dr6;"
+ "rip;eip;" "dr7;"
+ "efl;"
+ ;
+ static const char s_szTwoLetterRegisters[] =
+ "ax;al;ah;" "r8;"
+ "bx;bl;bh;" "r9;"
+ "cx;cl;ch;" "cs;"
+ "dx;dl;dh;" "ds;"
+ "di;" "es;"
+ "si;" "fs;"
+ "bp;" "gs;"
+ "sp;" "ss;"
+ "ip;"
+ ;
+ size_t const cchSymbol = strlen(pszSymbol);
+ if ( (cchSymbol == 2 && strstr(s_szTwoLetterRegisters, pszSymbol))
+ || (cchSymbol == 3 && strstr(s_szThreeLetterRegisters, pszSymbol))
+ || (cchSymbol == 6 && strstr(s_szSixLetterRegisters, pszSymbol)))
+ {
+ if (!strchr(pszSymbol, ';'))
+ {
+ DBGCVAR Var;
+ DBGCVAR_INIT_STRING(&Var, pszSymbol);
+ rc = dbgcOpRegister(pDbgc, &Var, pResult);
+ if (RT_SUCCESS(rc))
+ return DBGCCmdHlpConvert(&pDbgc->CmdHlp, &Var, enmType, false /*fConvSyms*/, pResult);
+ }
+ }
/*
* Ask PDM.
*/
/** @todo resolve symbols using PDM. */
-
/*
* Ask the debug info manager.
*/
RTDBGSYMBOL Symbol;
- int rc = DBGFR3AsSymbolByName(pDbgc->pVM, pDbgc->hDbgAs, pszSymbol, &Symbol, NULL);
+ rc = DBGFR3AsSymbolByName(pDbgc->pVM, pDbgc->hDbgAs, pszSymbol, &Symbol, NULL);
if (RT_SUCCESS(rc))
{
/*
* Default return is a flat gc address.
*/
- memset(pResult, 0, sizeof(*pResult));
- pResult->enmRangeType = Symbol.cb ? DBGCVAR_RANGE_BYTES : DBGCVAR_RANGE_NONE;
- pResult->u64Range = Symbol.cb;
- pResult->enmType = DBGCVAR_TYPE_GC_FLAT;
- pResult->u.GCFlat = Symbol.Value;
- DBGCVAR VarTmp;
+ DBGCVAR_INIT_GC_FLAT(pResult, Symbol.Value);
+ if (Symbol.cb)
+ DBGCVAR_SET_RANGE(pResult, DBGCVAR_RANGE_BYTES, Symbol.cb);
+
switch (enmType)
{
/* nothing to do. */
case DBGCVAR_TYPE_GC_FLAT:
- case DBGCVAR_TYPE_GC_FAR:
case DBGCVAR_TYPE_ANY:
return VINF_SUCCESS;
+ /* impossible at the moment. */
+ case DBGCVAR_TYPE_GC_FAR:
+ return VERR_PARSE_CONVERSION_FAILED;
+
/* simply make it numeric. */
case DBGCVAR_TYPE_NUMBER:
pResult->enmType = DBGCVAR_TYPE_NUMBER;
@@ -255,19 +258,10 @@ int dbgcSymbolGet(PDBGC pDbgc, const char *pszSymbol, DBGCVARTYPE enmType, PDBGC
return VINF_SUCCESS;
/* cast it. */
-
case DBGCVAR_TYPE_GC_PHYS:
- VarTmp = *pResult;
- return dbgcOpAddrPhys(pDbgc, &VarTmp, pResult);
-
- case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_FLAT:
- VarTmp = *pResult;
- return dbgcOpAddrHost(pDbgc, &VarTmp, pResult);
-
case DBGCVAR_TYPE_HC_PHYS:
- VarTmp = *pResult;
- return dbgcOpAddrHostPhys(pDbgc, &VarTmp, pResult);
+ return DBGCCmdHlpConvert(&pDbgc->CmdHlp, pResult, enmType, false /*fConvSyms*/, pResult);
default:
AssertMsgFailed(("Internal error enmType=%d\n", enmType));
@@ -279,1096 +273,6 @@ int dbgcSymbolGet(PDBGC pDbgc, const char *pszSymbol, DBGCVARTYPE enmType, PDBGC
}
-static int dbgcEvalSubString(PDBGC pDbgc, char *pszExpr, size_t cchExpr, PDBGCVAR pArg)
-{
- Log2(("dbgcEvalSubString: cchExpr=%d pszExpr=%s\n", cchExpr, pszExpr));
-
- /*
- * Removing any quoting and escapings.
- */
- char ch = *pszExpr;
- if (ch == '"' || ch == '\'' || ch == '`')
- {
- if (pszExpr[--cchExpr] != ch)
- return VERR_PARSE_UNBALANCED_QUOTE;
- cchExpr--;
- pszExpr++;
-
- /** @todo string unescaping. */
- }
- pszExpr[cchExpr] = '\0';
-
- /*
- * Make the argument.
- */
- pArg->pDesc = NULL;
- pArg->pNext = NULL;
- pArg->enmType = DBGCVAR_TYPE_STRING;
- pArg->u.pszString = pszExpr;
- pArg->enmRangeType = DBGCVAR_RANGE_BYTES;
- pArg->u64Range = cchExpr;
-
- NOREF(pDbgc);
- return 0;
-}
-
-
-static int dbgcEvalSubNum(char *pszExpr, unsigned uBase, PDBGCVAR pArg)
-{
- Log2(("dbgcEvalSubNum: uBase=%d pszExpr=%s\n", uBase, pszExpr));
- /*
- * Convert to number.
- */
- uint64_t u64 = 0;
- char ch;
- while ((ch = *pszExpr) != '\0')
- {
- uint64_t u64Prev = u64;
- unsigned u = ch - '0';
- if (u < 10 && u < uBase)
- u64 = u64 * uBase + u;
- else if (ch >= 'a' && (u = ch - ('a' - 10)) < uBase)
- u64 = u64 * uBase + u;
- else if (ch >= 'A' && (u = ch - ('A' - 10)) < uBase)
- u64 = u64 * uBase + u;
- else
- return VERR_PARSE_INVALID_NUMBER;
-
- /* check for overflow - ARG!!! How to detect overflow correctly!?!?!? */
- if (u64Prev != u64 / uBase)
- return VERR_PARSE_NUMBER_TOO_BIG;
-
- /* next */
- pszExpr++;
- }
-
- /*
- * Initialize the argument.
- */
- pArg->pDesc = NULL;
- pArg->pNext = NULL;
- pArg->enmType = DBGCVAR_TYPE_NUMBER;
- pArg->u.u64Number = u64;
- pArg->enmRangeType = DBGCVAR_RANGE_NONE;
- pArg->u64Range = 0;
-
- return 0;
-}
-
-
-/**
- * Match variable and variable descriptor, promoting the variable if necessary.
- *
- * @returns VBox status code.
- * @param pDbgc Debug console instanace.
- * @param pVar Variable.
- * @param pVarDesc Variable descriptor.
- */
-static int dbgcEvalSubMatchVar(PDBGC pDbgc, PDBGCVAR pVar, PCDBGCVARDESC pVarDesc)
-{
- /*
- * (If match or promoted to match, return, else break.)
- */
- switch (pVarDesc->enmCategory)
- {
- /*
- * Anything goes
- */
- case DBGCVAR_CAT_ANY:
- return VINF_SUCCESS;
-
- /*
- * Pointer with and without range.
- * We can try resolve strings and symbols as symbols and
- * promote numbers to flat GC pointers.
- */
- case DBGCVAR_CAT_POINTER_NO_RANGE:
- if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
- return VERR_PARSE_NO_RANGE_ALLOWED;
- /* fallthru */
- case DBGCVAR_CAT_POINTER:
- switch (pVar->enmType)
- {
- case DBGCVAR_TYPE_GC_FLAT:
- case DBGCVAR_TYPE_GC_FAR:
- case DBGCVAR_TYPE_GC_PHYS:
- case DBGCVAR_TYPE_HC_FLAT:
- case DBGCVAR_TYPE_HC_FAR:
- case DBGCVAR_TYPE_HC_PHYS:
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_SYMBOL:
- case DBGCVAR_TYPE_STRING:
- {
- DBGCVAR Var;
- int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var);
- if (RT_SUCCESS(rc))
- {
- /* deal with range */
- if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
- {
- Var.enmRangeType = pVar->enmRangeType;
- Var.u64Range = pVar->u64Range;
- }
- else if (pVarDesc->enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
- Var.enmRangeType = DBGCVAR_RANGE_NONE;
- *pVar = Var;
- return rc;
- }
- break;
- }
-
- case DBGCVAR_TYPE_NUMBER:
- {
- RTGCPTR GCPtr = (RTGCPTR)pVar->u.u64Number;
- pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
- pVar->u.GCFlat = GCPtr;
- return VINF_SUCCESS;
- }
-
- default:
- break;
- }
- break;
-
- /*
- * GC pointer with and without range.
- * We can try resolve strings and symbols as symbols and
- * promote numbers to flat GC pointers.
- */
- case DBGCVAR_CAT_GC_POINTER_NO_RANGE:
- if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
- return VERR_PARSE_NO_RANGE_ALLOWED;
- /* fallthru */
- case DBGCVAR_CAT_GC_POINTER:
- switch (pVar->enmType)
- {
- case DBGCVAR_TYPE_GC_FLAT:
- case DBGCVAR_TYPE_GC_FAR:
- case DBGCVAR_TYPE_GC_PHYS:
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_HC_FLAT:
- case DBGCVAR_TYPE_HC_FAR:
- case DBGCVAR_TYPE_HC_PHYS:
- return VERR_PARSE_CONVERSION_FAILED;
-
- case DBGCVAR_TYPE_SYMBOL:
- case DBGCVAR_TYPE_STRING:
- {
- DBGCVAR Var;
- int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var);
- if (RT_SUCCESS(rc))
- {
- /* deal with range */
- if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
- {
- Var.enmRangeType = pVar->enmRangeType;
- Var.u64Range = pVar->u64Range;
- }
- else if (pVarDesc->enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
- Var.enmRangeType = DBGCVAR_RANGE_NONE;
- *pVar = Var;
- return rc;
- }
- break;
- }
-
- case DBGCVAR_TYPE_NUMBER:
- {
- RTGCPTR GCPtr = (RTGCPTR)pVar->u.u64Number;
- pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
- pVar->u.GCFlat = GCPtr;
- return VINF_SUCCESS;
- }
-
- default:
- break;
- }
- break;
-
- /*
- * Number with or without a range.
- * Numbers can be resolved from symbols, but we cannot demote a pointer
- * to a number.
- */
- case DBGCVAR_CAT_NUMBER_NO_RANGE:
- if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
- return VERR_PARSE_NO_RANGE_ALLOWED;
- /* fallthru */
- case DBGCVAR_CAT_NUMBER:
- switch (pVar->enmType)
- {
- case DBGCVAR_TYPE_NUMBER:
- return VINF_SUCCESS;
-
- case DBGCVAR_TYPE_SYMBOL:
- case DBGCVAR_TYPE_STRING:
- {
- DBGCVAR Var;
- int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
- if (RT_SUCCESS(rc))
- {
- *pVar = Var;
- return rc;
- }
- break;
- }
- default:
- break;
- }
- break;
-
- /*
- * Strings can easily be made from symbols (and of course strings).
- * We could consider reformatting the addresses and numbers into strings later...
- */
- case DBGCVAR_CAT_STRING:
- switch (pVar->enmType)
- {
- case DBGCVAR_TYPE_SYMBOL:
- pVar->enmType = DBGCVAR_TYPE_STRING;
- /* fallthru */
- case DBGCVAR_TYPE_STRING:
- return VINF_SUCCESS;
- default:
- break;
- }
- break;
-
- /*
- * Symol is pretty much the same thing as a string (at least until we actually implement it).
- */
- case DBGCVAR_CAT_SYMBOL:
- switch (pVar->enmType)
- {
- case DBGCVAR_TYPE_STRING:
- pVar->enmType = DBGCVAR_TYPE_SYMBOL;
- /* fallthru */
- case DBGCVAR_TYPE_SYMBOL:
- return VINF_SUCCESS;
- default:
- break;
- }
- break;
-
- /*
- * Anything else is illegal.
- */
- default:
- AssertMsgFailed(("enmCategory=%d\n", pVar->enmType));
- break;
- }
-
- return VERR_PARSE_NO_ARGUMENT_MATCH;
-}
-
-
-/**
- * Matches a set of variables with a description set.
- *
- * This is typically used for routine arguments before a call. The effects in
- * addition to the validation, is that some variables might be propagated to
- * other types in order to match the description. The following transformations
- * are supported:
- * - String reinterpreted as a symbol and resolved to a number or pointer.
- * - Number to a pointer.
- * - Pointer to a number.
- * @returns 0 on success with paVars.
- * @returns VBox error code for match errors.
- */
-static int dbgcEvalSubMatchVars(PDBGC pDbgc, unsigned cVarsMin, unsigned cVarsMax,
- PCDBGCVARDESC paVarDescs, unsigned cVarDescs,
- PDBGCVAR paVars, unsigned cVars)
-{
- /*
- * Just do basic min / max checks first.
- */
- if (cVars < cVarsMin)
- return VERR_PARSE_TOO_FEW_ARGUMENTS;
- if (cVars > cVarsMax)
- return VERR_PARSE_TOO_MANY_ARGUMENTS;
-
- /*
- * Match the descriptors and actual variables.
- */
- PCDBGCVARDESC pPrevDesc = NULL;
- unsigned cCurDesc = 0;
- unsigned iVar = 0;
- unsigned iVarDesc = 0;
- while (iVar < cVars)
- {
- /* walk the descriptors */
- if (iVarDesc >= cVarDescs)
- return VERR_PARSE_TOO_MANY_ARGUMENTS;
- if ( ( paVarDescs[iVarDesc].fFlags & DBGCVD_FLAGS_DEP_PREV
- && &paVarDescs[iVarDesc - 1] != pPrevDesc)
- || cCurDesc >= paVarDescs[iVarDesc].cTimesMax)
- {
- iVarDesc++;
- if (iVarDesc >= cVarDescs)
- return VERR_PARSE_TOO_MANY_ARGUMENTS;
- cCurDesc = 0;
- }
-
- /*
- * Skip thru optional arguments until we find something which matches
- * or can easily be promoted to what the descriptor want.
- */
- for (;;)
- {
- int rc = dbgcEvalSubMatchVar(pDbgc, &paVars[iVar], &paVarDescs[iVarDesc]);
- if (RT_SUCCESS(rc))
- {
- paVars[iVar].pDesc = &paVarDescs[iVarDesc];
- cCurDesc++;
- break;
- }
-
- /* can we advance? */
- if (paVarDescs[iVarDesc].cTimesMin > cCurDesc)
- return VERR_PARSE_ARGUMENT_TYPE_MISMATCH;
- if (++iVarDesc >= cVarDescs)
- return VERR_PARSE_ARGUMENT_TYPE_MISMATCH;
- cCurDesc = 0;
- }
-
- /* next var */
- iVar++;
- }
-
- /*
- * Check that the rest of the descriptors are optional.
- */
- while (iVarDesc < cVarDescs)
- {
- if (paVarDescs[iVarDesc].cTimesMin > cCurDesc)
- return VERR_PARSE_TOO_FEW_ARGUMENTS;
- cCurDesc = 0;
-
- /* next */
- iVarDesc++;
- }
-
- return 0;
-}
-
-
-/**
- * Evaluates one argument with respect to unary operators.
- *
- * @returns 0 on success. pResult contains the result.
- * @returns VBox error code on parse or other evaluation error.
- *
- * @param pDbgc Debugger console instance data.
- * @param pszExpr The expression string.
- * @param pResult Where to store the result of the expression evaluation.
- */
-static int dbgcEvalSubUnary(PDBGC pDbgc, char *pszExpr, size_t cchExpr, PDBGCVAR pResult)
-{
- Log2(("dbgcEvalSubUnary: cchExpr=%d pszExpr=%s\n", cchExpr, pszExpr));
-
- /*
- * The state of the expression is now such that it will start by zero or more
- * unary operators and being followed by an expression of some kind.
- * The expression is either plain or in parenthesis.
- *
- * Being in a lazy, recursive mode today, the parsing is done as simple as possible. :-)
- * ASSUME: unary operators are all of equal precedence.
- */
- int rc = 0;
- PCDBGCOP pOp = dbgcOperatorLookup(pDbgc, pszExpr, false, ' ');
- if (pOp)
- {
- /* binary operators means syntax error. */
- if (pOp->fBinary)
- return VERR_PARSE_UNEXPECTED_OPERATOR;
-
- /*
- * If the next expression (the one following the unary operator) is in a
- * parenthesis a full eval is needed. If not the unary eval will suffice.
- */
- /* calc and strip next expr. */
- char *pszExpr2 = pszExpr + pOp->cchName;
- while (RT_C_IS_BLANK(*pszExpr2))
- pszExpr2++;
-
- if (!*pszExpr2)
- rc = VERR_PARSE_EMPTY_ARGUMENT;
- else
- {
- DBGCVAR Arg;
- if (*pszExpr2 == '(')
- rc = dbgcEvalSub(pDbgc, pszExpr2, cchExpr - (pszExpr2 - pszExpr), &Arg);
- else
- rc = dbgcEvalSubUnary(pDbgc, pszExpr2, cchExpr - (pszExpr2 - pszExpr), &Arg);
- if (RT_SUCCESS(rc))
- rc = pOp->pfnHandlerUnary(pDbgc, &Arg, pResult);
- }
- }
- else
- {
- /*
- * Didn't find any operators, so it we have to check if this can be an
- * function call before assuming numeric or string expression.
- *
- * (ASSUMPTIONS:)
- * A function name only contains alphanumerical chars and it can not start
- * with a numerical character.
- * Immediately following the name is a parenthesis which must over
- * the remaining part of the expression.
- */
- bool fExternal = *pszExpr == '.';
- char *pszFun = fExternal ? pszExpr + 1 : pszExpr;
- char *pszFunEnd = NULL;
- if (pszExpr[cchExpr - 1] == ')' && RT_C_IS_ALPHA(*pszFun))
- {
- pszFunEnd = pszExpr + 1;
- while (*pszFunEnd != '(' && RT_C_IS_ALNUM(*pszFunEnd))
- pszFunEnd++;
- if (*pszFunEnd != '(')
- pszFunEnd = NULL;
- }
-
- if (pszFunEnd)
- {
- /*
- * Ok, it's a function call.
- */
- if (fExternal)
- pszExpr++, cchExpr--;
- PCDBGCCMD pFun = dbgcRoutineLookup(pDbgc, pszExpr, pszFunEnd - pszExpr, fExternal);
- if (!pFun)
- return VERR_PARSE_FUNCTION_NOT_FOUND;
- if (!pFun->pResultDesc)
- return VERR_PARSE_NOT_A_FUNCTION;
-
- /*
- * Parse the expression in parenthesis.
- */
- cchExpr -= pszFunEnd - pszExpr;
- pszExpr = pszFunEnd;
- /** @todo implement multiple arguments. */
- DBGCVAR Arg;
- rc = dbgcEvalSub(pDbgc, pszExpr, cchExpr, &Arg);
- if (!rc)
- {
- rc = dbgcEvalSubMatchVars(pDbgc, pFun->cArgsMin, pFun->cArgsMax, pFun->paArgDescs, pFun->cArgDescs, &Arg, 1);
- if (!rc)
- rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, &Arg, 1, pResult);
- }
- else if (rc == VERR_PARSE_EMPTY_ARGUMENT && pFun->cArgsMin == 0)
- rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, NULL, 0, pResult);
- }
- else
- {
- /*
- * Didn't find any operators, so it must be a plain expression.
- * This might be numeric or a string expression.
- */
- char ch = pszExpr[0];
- char ch2 = pszExpr[1];
- if (ch == '0' && (ch2 == 'x' || ch2 == 'X'))
- rc = dbgcEvalSubNum(pszExpr + 2, 16, pResult);
- else if (ch == '0' && (ch2 == 'i' || ch2 == 'i'))
- rc = dbgcEvalSubNum(pszExpr + 2, 10, pResult);
- else if (ch == '0' && (ch2 == 't' || ch2 == 'T'))
- rc = dbgcEvalSubNum(pszExpr + 2, 8, pResult);
- /// @todo 0b doesn't work as a binary prefix, we confuse it with 0bf8:0123 and stuff.
- //else if (ch == '0' && (ch2 == 'b' || ch2 == 'b'))
- // rc = dbgcEvalSubNum(pszExpr + 2, 2, pResult);
- else
- {
- /*
- * Hexadecimal number or a string?
- */
- char *psz = pszExpr;
- while (RT_C_IS_XDIGIT(*psz))
- psz++;
- if (!*psz)
- rc = dbgcEvalSubNum(pszExpr, 16, pResult);
- else if ((*psz == 'h' || *psz == 'H') && !psz[1])
- {
- *psz = '\0';
- rc = dbgcEvalSubNum(pszExpr, 16, pResult);
- }
- else
- rc = dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
- }
- }
- }
-
- return rc;
-}
-
-
-/**
- * Evaluates one argument.
- *
- * @returns 0 on success. pResult contains the result.
- * @returns VBox error code on parse or other evaluation error.
- *
- * @param pDbgc Debugger console instance data.
- * @param pszExpr The expression string.
- * @param pResult Where to store the result of the expression evaluation.
- */
-int dbgcEvalSub(PDBGC pDbgc, char *pszExpr, size_t cchExpr, PDBGCVAR pResult)
-{
- Log2(("dbgcEvalSub: cchExpr=%d pszExpr=%s\n", cchExpr, pszExpr));
- /*
- * First we need to remove blanks in both ends.
- * ASSUMES: There is no quoting unless the entire expression is a string.
- */
-
- /* stripping. */
- while (cchExpr > 0 && RT_C_IS_BLANK(pszExpr[cchExpr - 1]))
- pszExpr[--cchExpr] = '\0';
- while (RT_C_IS_BLANK(*pszExpr))
- pszExpr++, cchExpr--;
- if (!*pszExpr)
- return VERR_PARSE_EMPTY_ARGUMENT;
-
- /* it there is any kind of quoting in the expression, it's string meat. */
- if (strpbrk(pszExpr, "\"'`"))
- return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
-
- /*
- * Check if there are any parenthesis which needs removing.
- */
- if (pszExpr[0] == '(' && pszExpr[cchExpr - 1] == ')')
- {
- do
- {
- unsigned cPar = 1;
- char *psz = pszExpr + 1;
- char ch;
- while ((ch = *psz) != '\0')
- {
- if (ch == '(')
- cPar++;
- else if (ch == ')')
- {
- if (cPar <= 0)
- return VERR_PARSE_UNBALANCED_PARENTHESIS;
- cPar--;
- if (cPar == 0 && psz[1]) /* If not at end, there's nothing to do. */
- break;
- }
- /* next */
- psz++;
- }
- if (ch)
- break;
-
- /* remove the parenthesis. */
- pszExpr++;
- cchExpr -= 2;
- pszExpr[cchExpr] = '\0';
-
- /* strip blanks. */
- while (cchExpr > 0 && RT_C_IS_BLANK(pszExpr[cchExpr - 1]))
- pszExpr[--cchExpr] = '\0';
- while (RT_C_IS_BLANK(*pszExpr))
- pszExpr++, cchExpr--;
- if (!*pszExpr)
- return VERR_PARSE_EMPTY_ARGUMENT;
- } while (pszExpr[0] == '(' && pszExpr[cchExpr - 1] == ')');
- }
-
- /* tabs to spaces. */
- char *psz = pszExpr;
- while ((psz = strchr(psz, '\t')) != NULL)
- *psz = ' ';
-
- /*
- * Now, we need to look for the binary operator with the lowest precedence.
- *
- * If there are no operators we're left with a simple expression which we
- * evaluate with respect to unary operators
- */
- char *pszOpSplit = NULL;
- PCDBGCOP pOpSplit = NULL;
- unsigned cBinaryOps = 0;
- unsigned cPar = 0;
- char ch;
- char chPrev = ' ';
- bool fBinary = false;
- psz = pszExpr;
-
- while ((ch = *psz) != '\0')
- {
- //Log2(("ch=%c cPar=%d fBinary=%d\n", ch, cPar, fBinary));
- /*
- * Parenthesis.
- */
- if (ch == '(')
- {
- cPar++;
- fBinary = false;
- }
- else if (ch == ')')
- {
- if (cPar <= 0)
- return VERR_PARSE_UNBALANCED_PARENTHESIS;
- cPar--;
- fBinary = true;
- }
- /*
- * Potential operator.
- */
- else if (cPar == 0 && !RT_C_IS_BLANK(ch))
- {
- PCDBGCOP pOp = dbgcIsOpChar(ch)
- ? dbgcOperatorLookup(pDbgc, psz, fBinary, chPrev)
- : NULL;
- if (pOp)
- {
- /* If not the right kind of operator we've got a syntax error. */
- if (pOp->fBinary != fBinary)
- return VERR_PARSE_UNEXPECTED_OPERATOR;
-
- /*
- * Update the parse state and skip the operator.
- */
- if (!pOpSplit)
- {
- pOpSplit = pOp;
- pszOpSplit = psz;
- cBinaryOps = fBinary;
- }
- else if (fBinary)
- {
- cBinaryOps++;
- if (pOp->iPrecedence >= pOpSplit->iPrecedence)
- {
- pOpSplit = pOp;
- pszOpSplit = psz;
- }
- }
-
- psz += pOp->cchName - 1;
- fBinary = false;
- }
- else
- fBinary = true;
- }
-
- /* next */
- psz++;
- chPrev = ch;
- } /* parse loop. */
-
-
- /*
- * Either we found an operator to divide the expression by
- * or we didn't find any. In the first case it's divide and
- * conquer. In the latter it's a single expression which
- * needs dealing with its unary operators if any.
- */
- int rc;
- if ( cBinaryOps
- && pOpSplit->fBinary)
- {
- /* process 1st sub expression. */
- *pszOpSplit = '\0';
- DBGCVAR Arg1;
- rc = dbgcEvalSub(pDbgc, pszExpr, pszOpSplit - pszExpr, &Arg1);
- if (RT_SUCCESS(rc))
- {
- /* process 2nd sub expression. */
- char *psz2 = pszOpSplit + pOpSplit->cchName;
- DBGCVAR Arg2;
- rc = dbgcEvalSub(pDbgc, psz2, cchExpr - (psz2 - pszExpr), &Arg2);
- if (RT_SUCCESS(rc))
- /* apply the operator. */
- rc = pOpSplit->pfnHandlerBinary(pDbgc, &Arg1, &Arg2, pResult);
- }
- }
- else if (cBinaryOps)
- {
- /* process sub expression. */
- pszOpSplit += pOpSplit->cchName;
- DBGCVAR Arg;
- rc = dbgcEvalSub(pDbgc, pszOpSplit, cchExpr - (pszOpSplit - pszExpr), &Arg);
- if (RT_SUCCESS(rc))
- /* apply the operator. */
- rc = pOpSplit->pfnHandlerUnary(pDbgc, &Arg, pResult);
- }
- else
- /* plain expression or using unary operators perhaps with parentheses. */
- rc = dbgcEvalSubUnary(pDbgc, pszExpr, cchExpr, pResult);
-
- return rc;
-}
-
-
-/**
- * Parses the arguments of one command.
- *
- * @returns 0 on success.
- * @returns VBox error code on parse error with *pcArg containing the argument causing trouble.
- * @param pDbgc Debugger console instance data.
- * @param pCmd Pointer to the command descriptor.
- * @param pszArg Pointer to the arguments to parse.
- * @param paArgs Where to store the parsed arguments.
- * @param cArgs Size of the paArgs array.
- * @param pcArgs Where to store the number of arguments.
- * In the event of an error this is used to store the index of the offending argument.
- */
-static int dbgcProcessArguments(PDBGC pDbgc, PCDBGCCMD pCmd, char *pszArgs, PDBGCVAR paArgs, unsigned cArgs, unsigned *pcArgs)
-{
- Log2(("dbgcProcessArguments: pCmd=%s pszArgs='%s'\n", pCmd->pszCmd, pszArgs));
- /*
- * Check if we have any argument and if the command takes any.
- */
- *pcArgs = 0;
- /* strip leading blanks. */
- while (*pszArgs && RT_C_IS_BLANK(*pszArgs))
- pszArgs++;
- if (!*pszArgs)
- {
- if (!pCmd->cArgsMin)
- return 0;
- return VERR_PARSE_TOO_FEW_ARGUMENTS;
- }
- /** @todo fixme - foo() doesn't work. */
- if (!pCmd->cArgsMax)
- return VERR_PARSE_TOO_MANY_ARGUMENTS;
-
- /*
- * This is a hack, it's "temporary" and should go away "when" the parser is
- * modified to match arguments while parsing.
- */
- if ( pCmd->cArgsMax == 1
- && pCmd->cArgsMin == 1
- && pCmd->cArgDescs == 1
- && pCmd->paArgDescs[0].enmCategory == DBGCVAR_CAT_STRING
- && cArgs >= 1)
- {
- *pcArgs = 1;
- RTStrStripR(pszArgs);
- return dbgcEvalSubString(pDbgc, pszArgs, strlen(pszArgs), &paArgs[0]);
- }
-
-
- /*
- * The parse loop.
- */
- PDBGCVAR pArg0 = &paArgs[0];
- PDBGCVAR pArg = pArg0;
- *pcArgs = 0;
- do
- {
- /*
- * Can we have another argument?
- */
- if (*pcArgs >= pCmd->cArgsMax)
- return VERR_PARSE_TOO_MANY_ARGUMENTS;
- if (pArg >= &paArgs[cArgs])
- return VERR_PARSE_ARGUMENT_OVERFLOW;
-
- /*
- * Find the end of the argument.
- */
- int cPar = 0;
- char chQuote = '\0';
- char *pszEnd = NULL;
- char *psz = pszArgs;
- char ch;
- bool fBinary = false;
- for (;;)
- {
- /*
- * Check for the end.
- */
- if ((ch = *psz) == '\0')
- {
- if (chQuote)
- return VERR_PARSE_UNBALANCED_QUOTE;
- if (cPar)
- return VERR_PARSE_UNBALANCED_PARENTHESIS;
- pszEnd = psz;
- break;
- }
- /*
- * When quoted we ignore everything but the quotation char.
- * We use the REXX way of escaping the quotation char, i.e. double occurrence.
- */
- else if (ch == '\'' || ch == '"' || ch == '`')
- {
- if (chQuote)
- {
- /* end quote? */
- if (ch == chQuote)
- {
- if (psz[1] == ch)
- psz++; /* skip the escaped quote char */
- else
- chQuote = '\0'; /* end of quoted string. */
- }
- }
- else
- chQuote = ch; /* open new quote */
- }
- /*
- * Parenthesis can of course be nested.
- */
- else if (ch == '(')
- {
- cPar++;
- fBinary = false;
- }
- else if (ch == ')')
- {
- if (!cPar)
- return VERR_PARSE_UNBALANCED_PARENTHESIS;
- cPar--;
- fBinary = true;
- }
- else if (!chQuote && !cPar)
- {
- /*
- * Encountering blanks may mean the end of it all. A binary operator
- * will force continued parsing.
- */
- if (RT_C_IS_BLANK(*psz))
- {
- pszEnd = psz++; /* just in case. */
- while (RT_C_IS_BLANK(*psz))
- psz++;
- PCDBGCOP pOp = dbgcOperatorLookup(pDbgc, psz, fBinary, ' ');
- if (!pOp || pOp->fBinary != fBinary)
- break; /* the end. */
- psz += pOp->cchName;
- while (RT_C_IS_BLANK(*psz)) /* skip blanks so we don't get here again */
- psz++;
- fBinary = false;
- continue;
- }
-
- /*
- * Look for operators without a space up front.
- */
- if (dbgcIsOpChar(*psz))
- {
- PCDBGCOP pOp = dbgcOperatorLookup(pDbgc, psz, fBinary, ' ');
- if (pOp)
- {
- if (pOp->fBinary != fBinary)
- {
- pszEnd = psz;
- /** @todo this is a parsing error really. */
- break; /* the end. */
- }
- psz += pOp->cchName;
- while (RT_C_IS_BLANK(*psz)) /* skip blanks so we don't get here again */
- psz++;
- fBinary = false;
- continue;
- }
- }
- fBinary = true;
- }
-
- /* next char */
- psz++;
- }
- *pszEnd = '\0';
- /* (psz = next char to process) */
-
- /*
- * Parse and evaluate the argument.
- */
- int rc = dbgcEvalSub(pDbgc, pszArgs, strlen(pszArgs), pArg);
- if (RT_FAILURE(rc))
- return rc;
-
- /*
- * Next.
- */
- pArg++;
- (*pcArgs)++;
- pszArgs = psz;
- while (*pszArgs && RT_C_IS_BLANK(*pszArgs))
- pszArgs++;
- } while (*pszArgs);
-
- /*
- * Match the arguments.
- */
- return dbgcEvalSubMatchVars(pDbgc, pCmd->cArgsMin, pCmd->cArgsMax, pCmd->paArgDescs, pCmd->cArgDescs, pArg0, pArg - pArg0);
-}
-
-
-/**
- * Process one command.
- *
- * @returns VBox status code. Any error indicates the termination of the console session.
- * @param pDbgc Debugger console instance data.
- * @param pszCmd Pointer to the command.
- * @param cchCmd Length of the command.
- * @param fNoExecute Indicates that no commands should actually be executed.
- */
-int dbgcProcessCommand(PDBGC pDbgc, char *pszCmd, size_t cchCmd, bool fNoExecute)
-{
- char *pszCmdInput = pszCmd;
-
- /*
- * Skip blanks.
- */
- while (RT_C_IS_BLANK(*pszCmd))
- pszCmd++, cchCmd--;
-
- /* external command? */
- bool fExternal = *pszCmd == '.';
- if (fExternal)
- pszCmd++, cchCmd--;
-
- /*
- * Find arguments.
- */
- char *pszArgs = pszCmd;
- while (RT_C_IS_ALNUM(*pszArgs))
- pszArgs++;
- if (*pszArgs && (!RT_C_IS_BLANK(*pszArgs) || pszArgs == pszCmd))
- {
- pDbgc->rcCmd = VINF_PARSE_INVALD_COMMAND_NAME;
- pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "Syntax error in command '%s'!\n", pszCmdInput);
- return 0;
- }
-
- /*
- * Find the command.
- */
- PCDBGCCMD pCmd = dbgcRoutineLookup(pDbgc, pszCmd, pszArgs - pszCmd, fExternal);
- if (!pCmd || (pCmd->fFlags & DBGCCMD_FLAGS_FUNCTION))
- {
- pDbgc->rcCmd = VINF_PARSE_COMMAND_NOT_FOUND;
- return pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "Unknown command '%s'!\n", pszCmdInput);
- }
-
- /*
- * Parse arguments (if any).
- */
- unsigned cArgs;
- int rc = dbgcProcessArguments(pDbgc, pCmd, pszArgs, &pDbgc->aArgs[pDbgc->iArg], RT_ELEMENTS(pDbgc->aArgs) - pDbgc->iArg, &cArgs);
-
- /*
- * Execute the command.
- */
- if (!rc)
- {
- if (!fNoExecute)
- rc = pCmd->pfnHandler(pCmd, &pDbgc->CmdHlp, pDbgc->pVM, &pDbgc->aArgs[0], cArgs, NULL);
- pDbgc->rcCmd = rc;
- if (rc == VERR_DBGC_COMMAND_FAILED)
- rc = VINF_SUCCESS;
- }
- else
- {
- pDbgc->rcCmd = rc;
-
- /* report parse / eval error. */
- switch (rc)
- {
- case VERR_PARSE_TOO_FEW_ARGUMENTS:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Syntax error: Too few arguments. Minimum is %d for command '%s'.\n", pCmd->cArgsMin, pCmd->pszCmd);
- break;
- case VERR_PARSE_TOO_MANY_ARGUMENTS:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Syntax error: Too many arguments. Maximum is %d for command '%s'.\n", pCmd->cArgsMax, pCmd->pszCmd);
- break;
- case VERR_PARSE_ARGUMENT_OVERFLOW:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Syntax error: Too many arguments.\n");
- break;
- case VERR_PARSE_UNBALANCED_QUOTE:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Syntax error: Unbalanced quote (argument %d).\n", cArgs);
- break;
- case VERR_PARSE_UNBALANCED_PARENTHESIS:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Syntax error: Unbalanced parenthesis (argument %d).\n", cArgs);
- break;
- case VERR_PARSE_EMPTY_ARGUMENT:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Syntax error: An argument or subargument contains nothing useful (argument %d).\n", cArgs);
- break;
- case VERR_PARSE_UNEXPECTED_OPERATOR:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Syntax error: Invalid operator usage (argument %d).\n", cArgs);
- break;
- case VERR_PARSE_INVALID_NUMBER:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Syntax error: Ivalid numeric value (argument %d). If a string was the intention, then quote it.\n", cArgs);
- break;
- case VERR_PARSE_NUMBER_TOO_BIG:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Error: Numeric overflow (argument %d).\n", cArgs);
- break;
- case VERR_PARSE_INVALID_OPERATION:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Error: Invalid operation attempted (argument %d).\n", cArgs);
- break;
- case VERR_PARSE_FUNCTION_NOT_FOUND:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Error: Function not found (argument %d).\n", cArgs);
- break;
- case VERR_PARSE_NOT_A_FUNCTION:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Error: The function specified is not a function (argument %d).\n", cArgs);
- break;
- case VERR_PARSE_NO_MEMORY:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Error: Out memory in the regular heap! Expect odd stuff to happen...\n", cArgs);
- break;
- case VERR_PARSE_INCORRECT_ARG_TYPE:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Error: Incorrect argument type (argument %d?).\n", cArgs);
- break;
- case VERR_PARSE_VARIABLE_NOT_FOUND:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Error: An undefined variable was referenced (argument %d).\n", cArgs);
- break;
- case VERR_PARSE_CONVERSION_FAILED:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Error: A conversion between two types failed (argument %d).\n", cArgs);
- break;
- case VERR_PARSE_NOT_IMPLEMENTED:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Error: You hit a debugger feature which isn't implemented yet (argument %d).\n", cArgs);
- break;
- case VERR_PARSE_BAD_RESULT_TYPE:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Error: Couldn't satisfy a request for a specific result type (argument %d). (Usually applies to symbols)\n", cArgs);
- break;
- case VERR_PARSE_WRITEONLY_SYMBOL:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Error: Cannot get symbol, it's set only (argument %d).\n", cArgs);
- break;
-
- case VERR_DBGC_COMMAND_FAILED:
- rc = VINF_SUCCESS;
- break;
-
- default:
- rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
- "Error: Unknown error %d!\n", rc);
- return rc;
- }
-
- /*
- * Parse errors are non fatal.
- */
- if (rc >= VERR_PARSE_FIRST && rc < VERR_PARSE_LAST)
- rc = VINF_SUCCESS;
- }
-
- return rc;
-}
-
-
/**
* Process all commands currently in the buffer.
*
@@ -1378,7 +282,9 @@ int dbgcProcessCommand(PDBGC pDbgc, char *pszCmd, size_t cchCmd, bool fNoExecute
*/
static int dbgcProcessCommands(PDBGC pDbgc, bool fNoExecute)
{
- int rc = 0;
+ /** @todo Replace this with a sh/ksh/csh/rexx like toplevel language that
+ * allows doing function, loops, if, cases, and such. */
+ int rc = VINF_SUCCESS;
while (pDbgc->cInputLines)
{
/*
@@ -1432,9 +338,11 @@ static int dbgcProcessCommands(PDBGC pDbgc, bool fNoExecute)
*/
pDbgc->pszScratch = psz;
pDbgc->iArg = 0;
- rc = dbgcProcessCommand(pDbgc, &pDbgc->achScratch[0], psz - &pDbgc->achScratch[0] - 1, fNoExecute);
- if (rc)
+ rc = dbgcEvalCommand(pDbgc, &pDbgc->achScratch[0], psz - &pDbgc->achScratch[0] - 1, fNoExecute);
+ if ( rc == VERR_DBGC_QUIT
+ || rc == VWRN_DBGC_CMD_PENDING)
break;
+ rc = VINF_SUCCESS; /* ignore other statuses */
}
return rc;
@@ -1954,7 +862,7 @@ int dbgcCreate(PDBGC *ppDbgc, PDBGCBACK pBack, unsigned fFlags)
dbgcInitCmdHlp(pDbgc);
pDbgc->pBack = pBack;
pDbgc->pVM = NULL;
- pDbgc->idCpu = NIL_VMCPUID;
+ pDbgc->idCpu = 0;
pDbgc->hDbgAs = DBGF_AS_GLOBAL;
pDbgc->pszEmulation = "CodeView/WinDbg";
pDbgc->paEmulationCmds = &g_aCmdsCodeView[0];
@@ -1990,7 +898,7 @@ int dbgcCreate(PDBGC *ppDbgc, PDBGCBACK pBack, unsigned fFlags)
//pDbgc->rcOutput = 0;
//pDbgc->rcCmd = 0;
- dbgcInitOpCharBitMap();
+ dbgcEvalInit();
*ppDbgc = pDbgc;
return VINF_SUCCESS;
@@ -2068,7 +976,7 @@ DBGDECL(int) DBGCCreate(PVM pVM, PDBGCBACK pBack, unsigned fFlags)
rc = DBGFR3Attach(pVM);
if (RT_SUCCESS(rc))
{
- pDbgc->pVM = pVM;
+ pDbgc->pVM = pVM;
pDbgc->idCpu = 0;
rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
"Current VM is %08x, CPU #%u\n" /** @todo get and print the VM name! */
diff --git a/src/VBox/Debugger/DBGPlugInCommonELF.cpp b/src/VBox/Debugger/DBGPlugInCommonELF.cpp
index 7b27b7d1a..bedab4a9a 100644
--- a/src/VBox/Debugger/DBGPlugInCommonELF.cpp
+++ b/src/VBox/Debugger/DBGPlugInCommonELF.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGPlugInCommonELF.cpp $ */
+/* $Id: DBGPlugInCommonELF.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGPlugInCommonELF - Common code for dealing with ELF images.
*/
diff --git a/src/VBox/Debugger/DBGPlugInCommonELF.h b/src/VBox/Debugger/DBGPlugInCommonELF.h
index 5590d45a8..c586c3968 100644
--- a/src/VBox/Debugger/DBGPlugInCommonELF.h
+++ b/src/VBox/Debugger/DBGPlugInCommonELF.h
@@ -1,4 +1,4 @@
-/* $Id: DBGPlugInCommonELF.h $ */
+/* $Id: DBGPlugInCommonELF.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* DBGPlugInCommonELF - Common code for dealing with ELF images, Header.
*/
diff --git a/src/VBox/Debugger/DBGPlugInCommonELFTmpl.cpp.h b/src/VBox/Debugger/DBGPlugInCommonELFTmpl.cpp.h
index 52419f35d..8de656ff5 100644
--- a/src/VBox/Debugger/DBGPlugInCommonELFTmpl.cpp.h
+++ b/src/VBox/Debugger/DBGPlugInCommonELFTmpl.cpp.h
@@ -1,4 +1,4 @@
-/* $Id: DBGPlugInCommonELFTmpl.cpp.h $ */
+/* $Id: DBGPlugInCommonELFTmpl.cpp.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* DBGPlugInCommonELF - Code Template for dealing with one kind of ELF.
*/
diff --git a/src/VBox/Debugger/DBGPlugInDiggers.cpp b/src/VBox/Debugger/DBGPlugInDiggers.cpp
index 48f550afc..f8b0d4f01 100644
--- a/src/VBox/Debugger/DBGPlugInDiggers.cpp
+++ b/src/VBox/Debugger/DBGPlugInDiggers.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGPlugInDiggers.cpp $ */
+/* $Id: DBGPlugInDiggers.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGPlugInDiggers - Debugger and Guest OS Digger Plug-in.
*/
diff --git a/src/VBox/Debugger/DBGPlugInLinux.cpp b/src/VBox/Debugger/DBGPlugInLinux.cpp
index 07fa9648b..71657cebb 100644
--- a/src/VBox/Debugger/DBGPlugInLinux.cpp
+++ b/src/VBox/Debugger/DBGPlugInLinux.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGPlugInLinux.cpp $ */
+/* $Id: DBGPlugInLinux.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGPlugInLinux - Debugger and Guest OS Digger Plugin For Linux.
*/
diff --git a/src/VBox/Debugger/DBGPlugInSolaris.cpp b/src/VBox/Debugger/DBGPlugInSolaris.cpp
index 6f717252b..341a5fa6b 100644
--- a/src/VBox/Debugger/DBGPlugInSolaris.cpp
+++ b/src/VBox/Debugger/DBGPlugInSolaris.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGPlugInSolaris.cpp $ */
+/* $Id: DBGPlugInSolaris.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGPlugInSolaris - Debugger and Guest OS Digger Plugin For Solaris.
*/
diff --git a/src/VBox/Debugger/DBGPlugInWinNt.cpp b/src/VBox/Debugger/DBGPlugInWinNt.cpp
index 1955a36df..626e50e26 100644
--- a/src/VBox/Debugger/DBGPlugInWinNt.cpp
+++ b/src/VBox/Debugger/DBGPlugInWinNt.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGPlugInWinNt.cpp $ */
+/* $Id: DBGPlugInWinNt.cpp 37809 2011-07-07 08:15:02Z vboxsync $ */
/** @file
* DBGPlugInWindows - Debugger and Guest OS Digger Plugin For Windows NT.
*/
@@ -305,7 +305,7 @@ static void dbgDiggerWinNtProcessImage(PDBGDIGGERWINNT pThis, PVM pVM, const cha
/* Dig out the NT/PE headers. */
IMAGE_DOS_HEADER const *pMzHdr = (IMAGE_DOS_HEADER const *)pbBuf;
- typedef union NTHDRS
+ typedef union NTHDRSU
{
IMAGE_NT_HEADERS64 vX_32;
IMAGE_NT_HEADERS64 vX_64;
diff --git a/src/VBox/Debugger/DBGPlugIns.h b/src/VBox/Debugger/DBGPlugIns.h
index bbb4a9d33..d060c3256 100644
--- a/src/VBox/Debugger/DBGPlugIns.h
+++ b/src/VBox/Debugger/DBGPlugIns.h
@@ -1,4 +1,4 @@
-/* $Id: DBGPlugIns.h $ */
+/* $Id: DBGPlugIns.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGPlugIns - Debugger Plug-Ins.
*
diff --git a/src/VBox/Debugger/Makefile.kmk b/src/VBox/Debugger/Makefile.kmk
index 59da7d698..23df33abb 100644
--- a/src/VBox/Debugger/Makefile.kmk
+++ b/src/VBox/Debugger/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35628 2011-01-19 14:58:26Z vboxsync $
## @file
# Makefile for the VBox debugger.
#
@@ -42,6 +42,7 @@ ifneq ($(KBUILD_TYPE),release)
endif
Debugger_SOURCES = \
DBGConsole.cpp \
+ DBGCEval.cpp \
DBGCBuiltInSymbols.cpp \
DBGCCmdHlp.cpp \
DBGCCmdWorkers.cpp \
diff --git a/src/VBox/Debugger/VBoxDbg.cpp b/src/VBox/Debugger/VBoxDbg.cpp
index 9c41c934c..9ec90c9d0 100644
--- a/src/VBox/Debugger/VBoxDbg.cpp
+++ b/src/VBox/Debugger/VBoxDbg.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxDbg.cpp $ */
+/* $Id: VBoxDbg.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBox Debugger GUI.
*/
diff --git a/src/VBox/Debugger/VBoxDbgBase.cpp b/src/VBox/Debugger/VBoxDbgBase.cpp
index 461c0e5de..5c400e754 100644
--- a/src/VBox/Debugger/VBoxDbgBase.cpp
+++ b/src/VBox/Debugger/VBoxDbgBase.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxDbgBase.cpp $ */
+/* $Id: VBoxDbgBase.cpp 31530 2010-08-10 12:24:45Z vboxsync $ */
/** @file
* VBox Debugger GUI - Base classes.
*/
diff --git a/src/VBox/Debugger/VBoxDbgBase.h b/src/VBox/Debugger/VBoxDbgBase.h
index 660d44e63..c54e1f826 100644
--- a/src/VBox/Debugger/VBoxDbgBase.h
+++ b/src/VBox/Debugger/VBoxDbgBase.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxDbgBase.h $ */
+/* $Id: VBoxDbgBase.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBox Debugger GUI - Base classes.
*/
diff --git a/src/VBox/Debugger/VBoxDbgConsole.cpp b/src/VBox/Debugger/VBoxDbgConsole.cpp
index 46756985c..ab0ae229d 100644
--- a/src/VBox/Debugger/VBoxDbgConsole.cpp
+++ b/src/VBox/Debugger/VBoxDbgConsole.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxDbgConsole.cpp $ */
+/* $Id: VBoxDbgConsole.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBox Debugger GUI - Console.
*/
diff --git a/src/VBox/Debugger/VBoxDbgConsole.h b/src/VBox/Debugger/VBoxDbgConsole.h
index ca762e96d..6b9a82163 100644
--- a/src/VBox/Debugger/VBoxDbgConsole.h
+++ b/src/VBox/Debugger/VBoxDbgConsole.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxDbgConsole.h $ */
+/* $Id: VBoxDbgConsole.h 31530 2010-08-10 12:24:45Z vboxsync $ */
/** @file
* VBox Debugger GUI - Console.
*/
diff --git a/src/VBox/Debugger/VBoxDbgDisas.h b/src/VBox/Debugger/VBoxDbgDisas.h
index bbd706fe4..c17df349d 100644
--- a/src/VBox/Debugger/VBoxDbgDisas.h
+++ b/src/VBox/Debugger/VBoxDbgDisas.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxDbgDisas.h $ */
+/* $Id: VBoxDbgDisas.h 31531 2010-08-10 12:29:45Z vboxsync $ */
/** @file
* VBox Debugger GUI - Disassembly View.
*/
diff --git a/src/VBox/Debugger/VBoxDbgGui.cpp b/src/VBox/Debugger/VBoxDbgGui.cpp
index d2f7f451e..9fbdb12f9 100644
--- a/src/VBox/Debugger/VBoxDbgGui.cpp
+++ b/src/VBox/Debugger/VBoxDbgGui.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxDbgGui.cpp $ */
+/* $Id: VBoxDbgGui.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBox Debugger GUI - The Manager.
*/
diff --git a/src/VBox/Debugger/VBoxDbgGui.h b/src/VBox/Debugger/VBoxDbgGui.h
index 01eb89722..093347c6a 100644
--- a/src/VBox/Debugger/VBoxDbgGui.h
+++ b/src/VBox/Debugger/VBoxDbgGui.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxDbgGui.h $ */
+/* $Id: VBoxDbgGui.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBox Debugger GUI - The Manager.
*/
diff --git a/src/VBox/Debugger/VBoxDbgStatsQt4.cpp b/src/VBox/Debugger/VBoxDbgStatsQt4.cpp
index 33c846da1..8d1e052d4 100644
--- a/src/VBox/Debugger/VBoxDbgStatsQt4.cpp
+++ b/src/VBox/Debugger/VBoxDbgStatsQt4.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxDbgStatsQt4.cpp $ */
+/* $Id: VBoxDbgStatsQt4.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBox Debugger GUI - Statistics.
*/
diff --git a/src/VBox/Debugger/VBoxDbgStatsQt4.h b/src/VBox/Debugger/VBoxDbgStatsQt4.h
index 2b8a2fc87..edc04d445 100644
--- a/src/VBox/Debugger/VBoxDbgStatsQt4.h
+++ b/src/VBox/Debugger/VBoxDbgStatsQt4.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxDbgStatsQt4.h $ */
+/* $Id: VBoxDbgStatsQt4.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBox Debugger GUI - Statistics.
*/
diff --git a/src/VBox/Debugger/testcase/tstDBGCParser.cpp b/src/VBox/Debugger/testcase/tstDBGCParser.cpp
index f0d6d8e24..77cd49c40 100644
--- a/src/VBox/Debugger/testcase/tstDBGCParser.cpp
+++ b/src/VBox/Debugger/testcase/tstDBGCParser.cpp
@@ -1,10 +1,10 @@
-/* $Id: tstDBGCParser.cpp $ */
+/* $Id: tstDBGCParser.cpp 35629 2011-01-19 15:15:21Z vboxsync $ */
/** @file
* DBGC Testcase - Command Parser.
*/
/*
- * 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;
@@ -29,8 +29,8 @@
* Internal Functions *
*******************************************************************************/
static DECLCALLBACK(bool) tstDBGCBackInput(PDBGCBACK pBack, uint32_t cMillies);
-static DECLCALLBACK(int) tstDBGCBackRead(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead);
-static DECLCALLBACK(int) tstDBGCBackWrite(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
+static DECLCALLBACK(int) tstDBGCBackRead(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead);
+static DECLCALLBACK(int) tstDBGCBackWrite(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
static DECLCALLBACK(void) tstDBGCBackSetReady(PDBGCBACK pBack, bool fReady);
@@ -268,6 +268,7 @@ int main()
/*
* Create a DBGC instance.
*/
+ RTTestSub(g_hTest, "dbgcCreate");
PDBGC pDbgc;
rc = dbgcCreate(&pDbgc, &g_tstBack, 0);
if (RT_SUCCESS(rc))
@@ -276,86 +277,98 @@ int main()
tstCompleteOutput();
if (RT_SUCCESS(rc))
{
+ RTTestSub(g_hTest, "basic parsing");
tstTry(pDbgc, "stop\n", VINF_SUCCESS);
tstTry(pDbgc, "format 1\n", VINF_SUCCESS);
tstTry(pDbgc, "format \n", VERR_PARSE_TOO_FEW_ARGUMENTS);
tstTry(pDbgc, "format 0 1 23 4\n", VERR_PARSE_TOO_MANY_ARGUMENTS);
tstTry(pDbgc, "sa 3 23 4 'q' \"21123123\" 'b' \n", VINF_SUCCESS);
- tstNumOp(pDbgc, "1", 1);
- tstNumOp(pDbgc, "1", 1);
- tstNumOp(pDbgc, "1", 1);
-
- tstNumOp(pDbgc, "+1", 1);
- tstNumOp(pDbgc, "++++++1", 1);
-
- tstNumOp(pDbgc, "-1", UINT64_MAX);
- tstNumOp(pDbgc, "--1", 1);
- tstNumOp(pDbgc, "---1", UINT64_MAX);
- tstNumOp(pDbgc, "----1", 1);
-
- tstNumOp(pDbgc, "~0", UINT64_MAX);
- tstNumOp(pDbgc, "~1", UINT64_MAX-1);
- tstNumOp(pDbgc, "~~0", 0);
- tstNumOp(pDbgc, "~~1", 1);
-
- tstNumOp(pDbgc, "!1", 0);
- tstNumOp(pDbgc, "!0", 1);
- tstNumOp(pDbgc, "!42", 0);
- tstNumOp(pDbgc, "!!42", 1);
- tstNumOp(pDbgc, "!!!42", 0);
- tstNumOp(pDbgc, "!!!!42", 1);
-
- tstNumOp(pDbgc, "1 +1", 2);
- tstNumOp(pDbgc, "1 + 1", 2);
- tstNumOp(pDbgc, "1+1", 2);
- tstNumOp(pDbgc, "1+ 1", 2);
-
- tstNumOp(pDbgc, "1 - 1", 0);
- tstNumOp(pDbgc, "99 - 90", 9);
-
- tstNumOp(pDbgc, "2 * 2", 4);
-
- tstNumOp(pDbgc, "2 / 2", 1);
- tstNumOp(pDbgc, "2 / 0", UINT64_MAX);
- tstNumOp(pDbgc, "0i1024 / 0i4", 256);
-
- tstNumOp(pDbgc, "1<<1", 2);
- tstNumOp(pDbgc, "1<<0i32", UINT64_C(0x0000000100000000));
- tstNumOp(pDbgc, "1<<0i48", UINT64_C(0x0001000000000000));
- tstNumOp(pDbgc, "1<<0i63", UINT64_C(0x8000000000000000));
-
- tstNumOp(pDbgc, "fedcba0987654321>>0i04", UINT64_C(0x0fedcba098765432));
- tstNumOp(pDbgc, "fedcba0987654321>>0i32", UINT64_C(0xfedcba09));
- tstNumOp(pDbgc, "fedcba0987654321>>0i48", UINT64_C(0x0000fedc));
-
- tstNumOp(pDbgc, "0ef & 4", 4);
- tstNumOp(pDbgc, "01234567891 & fff", UINT64_C(0x00000000891));
- tstNumOp(pDbgc, "01234567891 & ~fff", UINT64_C(0x01234567000));
-
- tstNumOp(pDbgc, "1 | 1", 1);
- tstNumOp(pDbgc, "0 | 4", 4);
- tstNumOp(pDbgc, "4 | 0", 4);
- tstNumOp(pDbgc, "4 | 4", 4);
- tstNumOp(pDbgc, "1 | 4 | 2", 7);
-
- tstNumOp(pDbgc, "1 ^ 1", 0);
- tstNumOp(pDbgc, "1 ^ 0", 1);
- tstNumOp(pDbgc, "0 ^ 1", 1);
- tstNumOp(pDbgc, "3 ^ 1", 2);
- tstNumOp(pDbgc, "7 ^ 3", 4);
-
- tstNumOp(pDbgc, "7 || 3", 1);
- tstNumOp(pDbgc, "1 || 0", 1);
- tstNumOp(pDbgc, "0 || 1", 1);
- tstNumOp(pDbgc, "0 || 0", 0);
-
- tstNumOp(pDbgc, "0 && 0", 0);
- tstNumOp(pDbgc, "1 && 0", 0);
- tstNumOp(pDbgc, "0 && 1", 0);
- tstNumOp(pDbgc, "1 && 1", 1);
- tstNumOp(pDbgc, "4 && 1", 1);
-
+ if (RTTestErrorCount(g_hTest) == 0)
+ {
+ RTTestSub(g_hTest, "Operators");
+ tstNumOp(pDbgc, "1", 1);
+ tstNumOp(pDbgc, "1", 1);
+ tstNumOp(pDbgc, "1", 1);
+
+ tstNumOp(pDbgc, "+1", 1);
+ tstNumOp(pDbgc, "++++++1", 1);
+
+ tstNumOp(pDbgc, "-1", UINT64_MAX);
+ tstNumOp(pDbgc, "--1", 1);
+ tstNumOp(pDbgc, "---1", UINT64_MAX);
+ tstNumOp(pDbgc, "----1", 1);
+
+ tstNumOp(pDbgc, "~0", UINT64_MAX);
+ tstNumOp(pDbgc, "~1", UINT64_MAX-1);
+ tstNumOp(pDbgc, "~~0", 0);
+ tstNumOp(pDbgc, "~~1", 1);
+
+ tstNumOp(pDbgc, "!1", 0);
+ tstNumOp(pDbgc, "!0", 1);
+ tstNumOp(pDbgc, "!42", 0);
+ tstNumOp(pDbgc, "!!42", 1);
+ tstNumOp(pDbgc, "!!!42", 0);
+ tstNumOp(pDbgc, "!!!!42", 1);
+
+ tstNumOp(pDbgc, "1 +1", 2);
+ tstNumOp(pDbgc, "1 + 1", 2);
+ tstNumOp(pDbgc, "1+1", 2);
+ tstNumOp(pDbgc, "1+ 1", 2);
+
+ tstNumOp(pDbgc, "1 - 1", 0);
+ tstNumOp(pDbgc, "99 - 90", 9);
+
+ tstNumOp(pDbgc, "2 * 2", 4);
+
+ tstNumOp(pDbgc, "2 / 2", 1);
+ tstNumOp(pDbgc, "2 / 0", UINT64_MAX);
+ tstNumOp(pDbgc, "0i1024 / 0i4", 256);
+
+ tstNumOp(pDbgc, "1<<1", 2);
+ tstNumOp(pDbgc, "1<<0i32", UINT64_C(0x0000000100000000));
+ tstNumOp(pDbgc, "1<<0i48", UINT64_C(0x0001000000000000));
+ tstNumOp(pDbgc, "1<<0i63", UINT64_C(0x8000000000000000));
+
+ tstNumOp(pDbgc, "fedcba0987654321>>0i04", UINT64_C(0x0fedcba098765432));
+ tstNumOp(pDbgc, "fedcba0987654321>>0i32", UINT64_C(0xfedcba09));
+ tstNumOp(pDbgc, "fedcba0987654321>>0i48", UINT64_C(0x0000fedc));
+
+ tstNumOp(pDbgc, "0ef & 4", 4);
+ tstNumOp(pDbgc, "01234567891 & fff", UINT64_C(0x00000000891));
+ tstNumOp(pDbgc, "01234567891 & ~fff", UINT64_C(0x01234567000));
+
+ tstNumOp(pDbgc, "1 | 1", 1);
+ tstNumOp(pDbgc, "0 | 4", 4);
+ tstNumOp(pDbgc, "4 | 0", 4);
+ tstNumOp(pDbgc, "4 | 4", 4);
+ tstNumOp(pDbgc, "1 | 4 | 2", 7);
+
+ tstNumOp(pDbgc, "1 ^ 1", 0);
+ tstNumOp(pDbgc, "1 ^ 0", 1);
+ tstNumOp(pDbgc, "0 ^ 1", 1);
+ tstNumOp(pDbgc, "3 ^ 1", 2);
+ tstNumOp(pDbgc, "7 ^ 3", 4);
+
+ tstNumOp(pDbgc, "7 || 3", 1);
+ tstNumOp(pDbgc, "1 || 0", 1);
+ tstNumOp(pDbgc, "0 || 1", 1);
+ tstNumOp(pDbgc, "0 || 0", 0);
+
+ tstNumOp(pDbgc, "0 && 0", 0);
+ tstNumOp(pDbgc, "1 && 0", 0);
+ tstNumOp(pDbgc, "0 && 1", 0);
+ tstNumOp(pDbgc, "1 && 1", 1);
+ tstNumOp(pDbgc, "4 && 1", 1);
+ }
+
+ if (RTTestErrorCount(g_hTest) == 0)
+ {
+ RTTestSub(g_hTest, "Odd cases");
+ tstTry(pDbgc, "r @rax\n", VINF_SUCCESS);
+ tstTry(pDbgc, "r @eax\n", VINF_SUCCESS);
+ tstTry(pDbgc, "r @ah\n", VINF_SUCCESS);
+ }
}
dbgcDestroy(pDbgc);
diff --git a/src/VBox/Debugger/testcase/tstDBGCStubs.cpp b/src/VBox/Debugger/testcase/tstDBGCStubs.cpp
index 717e6d909..528131547 100644
--- a/src/VBox/Debugger/testcase/tstDBGCStubs.cpp
+++ b/src/VBox/Debugger/testcase/tstDBGCStubs.cpp
@@ -1,10 +1,10 @@
-/* $Id: tstDBGCStubs.cpp $ */
+/* $Id: tstDBGCStubs.cpp 35629 2011-01-19 15:15:21Z vboxsync $ */
/** @file
* DBGC Testcase - Command Parser, VMM Stub Functions.
*/
/*
- * 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;
@@ -17,6 +17,7 @@
#include <VBox/err.h>
#include <VBox/vmm/vm.h>
+#include <iprt/string.h>
@@ -205,14 +206,49 @@ VMMR3DECL(int) DBGFR3RegCpuQueryU64( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uin
{
return VERR_INTERNAL_ERROR;
}
-VMMR3DECL(int) DBGFR3RegNmQuery( PVM pVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType)
-{
+VMMR3DECL(int) DBGFR3RegNmQuery(PVM pVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType)
+{
+ if (idDefCpu == 0 || idDefCpu == DBGFREG_HYPER_VMCPUID)
+ {
+ if (!strcmp(pszReg, "ah"))
+ {
+ pValue->u16 = 0xf0;
+ *penmType = DBGFREGVALTYPE_U8;
+ return VINF_SUCCESS;
+ }
+ if (!strcmp(pszReg, "ax"))
+ {
+ pValue->u16 = 0xbabe;
+ *penmType = DBGFREGVALTYPE_U16;
+ return VINF_SUCCESS;
+ }
+ if (!strcmp(pszReg, "eax"))
+ {
+ pValue->u32 = 0xcafebabe;
+ *penmType = DBGFREGVALTYPE_U32;
+ return VINF_SUCCESS;
+ }
+ if (!strcmp(pszReg, "rax"))
+ {
+ pValue->u64 = UINT64_C(0x00beef00feedface);
+ *penmType = DBGFREGVALTYPE_U32;
+ return VINF_SUCCESS;
+ }
+ }
return VERR_INTERNAL_ERROR;
}
VMMR3DECL(int) DBGFR3RegPrintf(PVM pVM, VMCPUID idCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...)
{
return VERR_INTERNAL_ERROR;
}
+VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3RegNmSet(PVM pVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType)
+{
+ return VERR_INTERNAL_ERROR;
+}
VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PVM pVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr)
{
@@ -355,6 +391,10 @@ VMMR3DECL(int) PGMR3DbgR3Ptr2HCPhys(PVM pVM, RTR3PTR R3Ptr, PRTHCPHYS pHCPhys)
{
return VERR_INTERNAL_ERROR;
}
+VMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PVM pVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys)
+{
+ return VERR_INTERNAL_ERROR;
+}
#include <VBox/vmm/vmm.h>
diff --git a/src/VBox/Debugger/testcase/tstVBoxDbg.cpp b/src/VBox/Debugger/testcase/tstVBoxDbg.cpp
index 13977789e..49aab8f01 100644
--- a/src/VBox/Debugger/testcase/tstVBoxDbg.cpp
+++ b/src/VBox/Debugger/testcase/tstVBoxDbg.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstVBoxDbg.cpp $ */
+/* $Id: tstVBoxDbg.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBox Debugger GUI, dummy testcase.
*/
diff --git a/src/VBox/Devices/Audio/DevCodec.cpp b/src/VBox/Devices/Audio/DevCodec.cpp
index 283dd67db..070d6b0a8 100644
--- a/src/VBox/Devices/Audio/DevCodec.cpp
+++ b/src/VBox/Devices/Audio/DevCodec.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevCodec.cpp $ */
+/* $Id: DevCodec.cpp 37482 2011-06-16 04:09:27Z vboxsync $ */
/** @file
* DevCodec - VBox ICH Intel HD Audio Codec.
*/
@@ -31,10 +31,10 @@ extern "C" {
#define CODECNODE_F0_PARAM_LENGTH 0x14
#define CODECNODE_F02_PARAM_LENGTH 16
+
typedef struct CODECCOMMONNODE
{
uint8_t id; /* 7 - bit format */
- const char *name;
/* RPM 5.3.6 */
uint32_t au32F00_param[CODECNODE_F0_PARAM_LENGTH];
uint32_t au32F02_param[CODECNODE_F02_PARAM_LENGTH];
@@ -273,12 +273,10 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
{
/* Root Node*/
case 0:
- pNode->root.node.name = "Root";
pNode->node.au32F00_param[2] = CODEC_MAKE_F00_02(0x1, 0x0, 0x34, 0x1); /* rev id */
break;
case 1:
- pNode->afg.node.name = "AFG";
- pNode->node.au32F00_param[8] = CODEC_MAKE_F00_08(CODEC_F00_08_BEEP_GEN, 0xd, 0xd);
+ pNode->node.au32F00_param[8] = CODEC_MAKE_F00_08(1, 0xd, 0xd);
pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
| CODEC_F00_0C_CAP_BALANCED_IO
| CODEC_F00_0C_CAP_INPUT
@@ -295,17 +293,9 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
pNode->afg.u32F17_param = 0;
break;
case 2:
- pNode->dac.node.name = "DAC0";
- goto dac_init;
case 3:
- pNode->dac.node.name = "DAC1";
- goto dac_init;
case 4:
- pNode->dac.node.name = "DAC2";
- goto dac_init;
case 5:
- pNode->dac.node.name = "DAC3";
- dac_init:
memset(pNode->dac.B_params, 0, AMPLIFIER_SIZE);
pNode->dac.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//RT_BIT(14)|(0x1 << 4)|0x1; /* 441000Hz/16bit/2ch */
@@ -321,11 +311,9 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
pNode->dac.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3, Set: D3 */
break;
case 6:
- pNode->adc.node.name = "ADC0";
pNode->node.au32F02_param[0] = 0x17;
goto adc_init;
case 7:
- pNode->adc.node.name = "ADC1";
pNode->node.au32F02_param[0] = 0x18;
adc_init:
pNode->adc.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//RT_BIT(14)|(0x1 << 3)|0x1; /* 441000Hz/16bit/2ch */
@@ -340,7 +328,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
| CODEC_F00_09_CAP_LSB;//RT_BIT(20)| (0xd << 16) | RT_BIT(10) | RT_BIT(8) | RT_BIT(6)| RT_BIT(0);
break;
case 8:
- pNode->spdifout.node.name = "SPDIFOut";
pNode->spdifout.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
pNode->spdifout.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 0x4, 0)
| CODEC_F00_09_CAP_DIGITAL
@@ -352,7 +339,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
pNode->spdifout.u32F0d_param = 0;
break;
case 9:
- pNode->node.name = "Reserved_0";
pNode->spdifin.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(0x1<<4) | 0x1;
pNode->spdifin.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_INPUT, 0x4, 0)
| CODEC_F00_09_CAP_DIGITAL
@@ -367,7 +353,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
pNode->spdifin.u32F0d_param = 0;
break;
case 0xA:
- pNode->node.name = "PortA";
pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
| CODEC_F00_0C_CAP_INPUT
| CODEC_F00_0C_CAP_OUTPUT
@@ -389,7 +374,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
0x2, 0);//RT_MAKE_U32_FROM_U8(0x20, 0x40, 0x21, 0x02);
goto port_init;
case 0xB:
- pNode->node.name = "PortB";
pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
| CODEC_F00_0C_CAP_INPUT
| CODEC_F00_0C_CAP_OUTPUT
@@ -408,7 +392,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
0x1, 0x1);//RT_MAKE_U32_FROM_U8(0x11, 0x60, 0x11, 0x01);
goto port_init;
case 0xC:
- pNode->node.name = "PortC";
pNode->node.au32F02_param[0] = 0x3;
pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
| CODEC_F00_0C_CAP_INPUT
@@ -426,7 +409,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
0x0, 0x1, 0x0);//RT_MAKE_U32_FROM_U8(0x10, 0x40, 0x11, 0x01);
goto port_init;
case 0xD:
- pNode->node.name = "PortD";
pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
| CODEC_F00_0C_CAP_INPUT
| CODEC_F00_0C_CAP_OUTPUT
@@ -452,7 +434,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//0x1;
break;
case 0xE:
- pNode->node.name = "PortE";
pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0)
| CODEC_F00_09_CAP_UNSOL
| CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(7)|RT_BIT(0);
@@ -471,7 +452,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
0x0, 0x4, 0x0);//0x01013040; /* Line Out */
break;
case 0xF:
- pNode->node.name = "PortF";
pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0x0)
| CODEC_F00_09_CAP_CONNECTION_LIST
| CODEC_F00_09_CAP_UNSOL
@@ -497,7 +477,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(0, CODEC_F09_ANALOG_NA);//0x7fffffff;
break;
case 0x10:
- pNode->node.name = "DigOut_0";
pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0x0)
| CODEC_F00_09_CAP_DIGITAL
| CODEC_F00_09_CAP_CONNECTION_LIST
@@ -514,7 +493,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
0x0, 0x3, 0x0);//RT_MAKE_U32_FROM_U8(0x30, 0x10, 0x45, 0x01);
break;
case 0x11:
- pNode->node.name = "DigIn_0";
pNode->node.au32F00_param[9] = (4 << 20)|(3<<16)|RT_BIT(10)|RT_BIT(9)|RT_BIT(7)|RT_BIT(0);
pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_EAPD
| CODEC_F00_0C_CAP_INPUT
@@ -533,11 +511,9 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
0x0, 0x6, 0x0);//(0x1 << 24) | (0xc5 << 16) | (0x10 << 8) | 0x60;
break;
case 0x12:
- pNode->node.name = "ADCMux_0";
pNode->adcmux.u32F01_param = 0;
goto adcmux_init;
case 0x13:
- pNode->node.name = "ADCMux_1";
pNode->adcmux.u32F01_param = 1;
adcmux_init:
pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_SELECTOR, 0x0, 0)
@@ -553,7 +529,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
pNode->node.au32F02_param[4] = RT_MAKE_U32_FROM_U8(0xc, 0xd, 0xa, 0x0);
break;
case 0x14:
- pNode->node.name = "PCBEEP";
pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_BEEP_GEN, 0, 0)
| CODEC_F00_09_CAP_AMP_FMT_OVERRIDE
| CODEC_F00_09_CAP_OUT_AMP_PRESENT;//(7 << 20) | RT_BIT(3) | RT_BIT(2);
@@ -562,7 +537,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
memset(pNode->pcbeep.B_params, 0, AMPLIFIER_SIZE);
break;
case 0x15:
- pNode->node.name = "CD";
pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0)
| CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(0);
pNode->node.au32F00_param[0xc] = CODEC_F00_0C_CAP_INPUT;//RT_BIT(5);
@@ -575,7 +549,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
0x0, 0x7, 0x0);//RT_MAKE_U32_FROM_U8(0x70, 0x0, 0x33, 0x90);
break;
case 0x16:
- pNode->node.name = "VolumeKnob";
pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VOLUME_KNOB, 0x0, 0x0);//(0x6 << 20);
pNode->node.au32F00_param[0x13] = RT_BIT(7)| 0x7F;
pNode->node.au32F00_param[0xe] = CODEC_MAKE_F00_0E(0, 0x4);
@@ -584,11 +557,9 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
pNode->volumeKnob.u32F0f_param = 0x7f;
break;
case 0x17:
- pNode->node.name = "ADC0Vol";
pNode->node.au32F02_param[0] = 0x12;
goto adcvol_init;
case 0x18:
- pNode->node.name = "ADC1Vol";
pNode->node.au32F02_param[0] = 0x13;
adcvol_init:
memset(pNode->adcvol.B_params, 0, AMPLIFIER_SIZE);
@@ -604,19 +575,16 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
pNode->adcvol.u32F0c_param = 0;
break;
case 0x19:
- pNode->node.name = "Reserved_1";
pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VENDOR_DEFINED, 0x3, 0)
| CODEC_F00_09_CAP_DIGITAL
| CODEC_F00_09_CAP_LSB;//(0xF << 20)|(0x3 << 16)|RT_BIT(9)|RT_BIT(0);
break;
case 0x1A:
- pNode->node.name = "Reserved_2";
pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 0x3, 0)
| CODEC_F00_09_CAP_DIGITAL
| CODEC_F00_09_CAP_LSB;//(0x3 << 16)|RT_BIT(9)|RT_BIT(0);
break;
case 0x1B:
- pNode->node.name = "Reserved_3";
pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0)
| CODEC_F00_09_CAP_DIGITAL
| CODEC_F00_09_CAP_CONNECTION_LIST
@@ -637,395 +605,6 @@ static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECN
return VINF_SUCCESS;
}
-/* ALC885 */
-const static uint8_t au8Alc885Ports[] = { 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0};
-const static uint8_t au8Alc885Dacs[] = { 0x2, 0x3, 0x4, 0x5, 0x25, 0};
-const static uint8_t au8Alc885Adcs[] = { 0x7, 0x8, 0x9, 0};
-const static uint8_t au8Alc885SpdifOuts[] = { 0x6, 0 };
-const static uint8_t au8Alc885SpdifIns[] = { 0xA, 0 };
-const static uint8_t au8Alc885DigOutPins[] = { 0x1E, 0 };
-const static uint8_t au8Alc885DigInPins[] = { 0x1F, 0 };
-const static uint8_t au8Alc885AdcVols[] = { 0xE, 0xF, 0xD, 0xC, 0x26, 0xB, 0};
-const static uint8_t au8Alc885AdcMuxs[] = { 0x22, 0x23, 0x24, 0};
-const static uint8_t au8Alc885Pcbeeps[] = { 0x1D, 0 };
-const static uint8_t au8Alc885Cds[] = { 0x1C, 0 };
-const static uint8_t au8Alc885VolKnobs[] = { 0x21, 0 };
-const static uint8_t au8Alc885Reserveds[] = { 0x10, 0x11, 0x12, 0x13, 0 };
-
-
-static int alc885ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode);
-
-static int alc885Construct(CODECState *pState)
-{
- unconst(pState->cTotalNodes) = 0x27;
- pState->u16VendorId = 0x10ec;
- pState->u16DeviceId = 0x0885;
- pState->u8BSKU = 0x08;
- pState->u8AssemblyId = 0x85;
- pState->pfnCodecNodeReset = alc885ResetNode;
- pState->pNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pState->cTotalNodes);
- pState->fInReset = false;
-#define ALC885WIDGET(type) pState->au8##type##s = au8Alc885##type##s
- ALC885WIDGET(Port);
- ALC885WIDGET(Dac);
- ALC885WIDGET(Adc);
- ALC885WIDGET(AdcVol);
- ALC885WIDGET(AdcMux);
- ALC885WIDGET(Pcbeep);
- ALC885WIDGET(SpdifIn);
- ALC885WIDGET(SpdifOut);
- ALC885WIDGET(DigInPin);
- ALC885WIDGET(DigOutPin);
- ALC885WIDGET(Cd);
- ALC885WIDGET(VolKnob);
- ALC885WIDGET(Reserved);
-#undef ALC885WIDGET
- /* @todo: test more */
- unconst(pState->u8AdcVolsLineIn) = 0x1a;
- unconst(pState->u8DacLineOut) = 0x0d;
-
- return VINF_SUCCESS;
-}
-
-static int alc885ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode)
-{
- pNode->node.id = nodenum;
- switch (nodenum)
- {
- case 0: /* Root */
- pNode->node.au32F00_param[2] = CODEC_MAKE_F00_02(0x1, 0x0, 0x0, 0x0); /* Realtek 889 (8.1.9)*/
- pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
-
- break;
- case 0x1: /* AFG */
- pNode->node.au32F00_param[0xB] = CODEC_F00_0B_PCM;
- pNode->node.au32F00_param[0x11] = RT_BIT(30)|0x2;
- break;
- /* DACs */
- case 0x2:
- pNode->node.name = "DAC-0";
- goto dac_init;
- case 0x3:
- pNode->node.name = "DAC-1";
- goto dac_init;
- case 0x4:
- pNode->node.name = "DAC-2";
- goto dac_init;
- case 0x5:
- pNode->node.name = "DAC-3";
- goto dac_init;
- case 0x25:
- pNode->node.name = "DAC-4";
- dac_init:
- pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
- pNode->node.au32F00_param[0x9] = 0x11;
- pNode->node.au32F00_param[0xB] = CODEC_F00_0B_PCM;
- pNode->dac.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
- break;
- /* SPDIFs */
- case 0x6:
- pNode->node.name = "SPDIFOUT-0";
- pNode->node.au32F00_param[0x9] = 0x211;
- pNode->node.au32F00_param[0xB] = 0x1;
- pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
- pNode->spdifout.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
- break;
- case 0xA:
- pNode->node.name = "SPDIFIN-0";
- pNode->node.au32F00_param[0x9] = 0x100391;
- pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
- pNode->node.au32F00_param[0xB] = 0x1;
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x1F, 0, 0, 0);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x1F, 0, 0, 0);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x1F, 0, 0, 0);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x1F, 0, 0, 0);
- pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
- pNode->spdifin.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
- break;
- /* VENDOR DEFINE */
- case 0x10:
- pNode->node.name = "VENDEF-0";
- goto vendor_define_init;
- case 0x11:
- pNode->node.name = "VENDEF-1";
- goto vendor_define_init;
- case 0x12:
- pNode->node.name = "VENDEF-2";
- goto vendor_define_init;
- case 0x13:
- pNode->node.name = "VENDEF-3";
- goto vendor_define_init;
- case 0x20:
- pNode->node.name = "VENDEF-4";
- vendor_define_init:
- pNode->node.au32F00_param[0x9] = 0xf00000;
- break;
-
- /* DIGPIN */
- case 0x1E:
- pNode->node.name = "DIGOUT-1";
- pNode->node.au32F00_param[0x9] = 0x400300;
- pNode->node.au32F00_param[0xE] = 0x1;
- pNode->port.u32F1c_param = 0x14be060;
- pNode->node.au32F00_param[0xC] = RT_BIT(4);
- /* N = 0~3 */
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x6, 0x0, 0x0, 0x0);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x6, 0x0, 0x0, 0x0);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x6, 0x0, 0x0, 0x0);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x6, 0x0, 0x0, 0x0);
- break;
- case 0x1F:
- pNode->node.name = "DIGIN-0";
- pNode->node.au32F00_param[9] = 0x400200;
- /* N = 0~3 */
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0xA, 0x0, 0x0, 0x0);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0xA, 0x0, 0x0, 0x0);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0xA, 0x0, 0x0, 0x0);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0xA, 0x0, 0x0, 0x0);
- break;
- /* ADCs */
- case 0x7:
- pNode->node.name = "ADC-0";
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x23, 0, 0, 0);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x23, 0, 0, 0);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x23, 0, 0, 0);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x23, 0, 0, 0);
- goto adc_init;
- break;
- case 0x8:
- pNode->node.name = "ADC-1";
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x24, 0, 0, 0);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x24, 0, 0, 0);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x24, 0, 0, 0);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x24, 0, 0, 0);
- goto adc_init;
- break;
- case 0x9:
- pNode->node.name = "ADC-2";
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x22, 0, 0, 0);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x22, 0, 0, 0);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x22, 0, 0, 0);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x22, 0, 0, 0);
- adc_init:
- pNode->node.au32F00_param[0xB] = 0x1;
- pNode->node.au32F00_param[0x9] = 0x10011b;
- pNode->node.au32F00_param[0xD] = 0x80032e10;
- pNode->node.au32F00_param[0xE] = 0x1;
- pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
- pNode->adc.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
- break;
- /* Ports */
- case 0x14:
- pNode->node.name = "PORT-D";
- pNode->port.u32F1c_param = 0x12b4050;
- pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
- goto port_init;
- break;
- case 0x15:
- pNode->node.name = "PORT-A";
- pNode->port.u32F1c_param = 0x18b3020;
- pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
- goto port_init;
- break;
- case 0x16:
- pNode->node.name = "PORT-G";
- pNode->port.u32F1c_param = 0x400000f0;
- pNode->node.au32F00_param[0xC] = RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
- goto port_init;
- break;
- case 0x17:
- pNode->node.name = "PORT-H";
- pNode->port.u32F1c_param = 0x400000f0;
- pNode->node.au32F00_param[0xC] = RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
- goto port_init;
- break;
- case 0x18:
- pNode->node.name = "PORT-B";
- pNode->port.u32F1c_param = 0x90100140;
- pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
- goto port_init;
- break;
- case 0x19:
- pNode->node.name = "PORT-F";
- pNode->port.u32F1c_param = 0x90a00110;
- pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
- goto port_init;
- break;
- case 0x1A:
- pNode->node.name = "PORT-C";
- pNode->port.u32F1c_param = 0x90100141;
- pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
- goto port_init;
- break;
- case 0x1B:
- pNode->node.name = "PORT-E";
- pNode->port.u32F1c_param = 0x400000f0;
- pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
- port_init:
- pNode->node.au32F00_param[0x9] = 0x40018f;
- pNode->node.au32F00_param[0xD] = 0x270300;
- pNode->node.au32F00_param[0xE] = 0x5;
- /* N = 0~3 */
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0xC, 0xD, 0xE, 0xF);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0xC, 0xD, 0xE, 0xF);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0xC, 0xD, 0xE, 0xF);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0xC, 0xD, 0xE, 0xF);
- /* N = 4~7 */
- pNode->node.au32F02_param[4] = RT_MAKE_U32_FROM_U8(0x26, 0, 0, 0);
- pNode->node.au32F02_param[5] = RT_MAKE_U32_FROM_U8(0x26, 0, 0, 0);
- pNode->node.au32F02_param[6] = RT_MAKE_U32_FROM_U8(0x26, 0, 0, 0);
- pNode->node.au32F02_param[7] = RT_MAKE_U32_FROM_U8(0x26, 0, 0, 0);
- break;
- /* ADCVols */
- case 0x26:
- pNode->node.name = "AdcVol-0";
- pNode->node.au32F00_param[0x9] = 0x20010f;
- pNode->node.au32F00_param[0xD] = 0x80000000;
- pNode->node.au32F00_param[0xE] = 0x2;
- pNode->node.au32F00_param[0x12] = 0x34040;
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x25, 0xB, 0, 0);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x25, 0xB, 0, 0);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x25, 0xB, 0, 0);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x25, 0xB, 0, 0);
- break;
- case 0xF:
- pNode->node.name = "AdcVol-1";
- pNode->node.au32F00_param[0x9] = 0x20010f;
- pNode->node.au32F00_param[0xE] = 0x2;
- pNode->node.au32F00_param[0x12] = 0x34040;
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x5, 0xB, 0, 0);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x5, 0xB, 0, 0);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x5, 0xB, 0, 0);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x5, 0xB, 0, 0);
- break;
- case 0xE:
- pNode->node.name = "AdcVol-2";
- pNode->node.au32F00_param[0x9] = 0x20010f;
- pNode->node.au32F00_param[0xE] = 0x2;
- pNode->node.au32F00_param[0xD] = 0x80000000;
- pNode->node.au32F00_param[0x12] = 0x34040;
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x4, 0xB, 0, 0);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x4, 0xB, 0, 0);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x4, 0xB, 0, 0);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x4, 0xB, 0, 0);
- break;
- case 0xD:
- pNode->node.name = "AdcVol-3";
- pNode->node.au32F00_param[0x9] = 0x20010f;
- pNode->node.au32F00_param[0xE] = 0x2;
- pNode->node.au32F00_param[0xD] = 0x80000000;
- pNode->node.au32F00_param[0x12] = 0x34040;
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x3, 0xB, 0, 0);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x3, 0xB, 0, 0);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x3, 0xB, 0, 0);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x3, 0xB, 0, 0);
- break;
- case 0xC:
- pNode->node.name = "AdcVol-4";
- pNode->node.au32F00_param[0x9] = 0x20010f;
- pNode->node.au32F00_param[0xE] = 0x2;
- pNode->node.au32F00_param[0xD] = 0x80000000;
- pNode->node.au32F00_param[0x12] = 0x34040;
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x2, 0xB, 0, 0);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x2, 0xB, 0, 0);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x2, 0xB, 0, 0);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x2, 0xB, 0, 0);
- break;
- case 0xB:
- pNode->node.name = "AdcVol-5";
- pNode->node.au32F00_param[0x9] = 0x20010b;
- pNode->node.au32F00_param[0xD] = 0x80051f17;
- /* N = 0~3 */
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
- /* N = 4~7 */
- pNode->node.au32F02_param[4] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
- pNode->node.au32F02_param[5] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
- pNode->node.au32F02_param[6] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
- pNode->node.au32F02_param[7] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
- /* N = 8~11 */
- pNode->node.au32F02_param[8] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0, 0);
- pNode->node.au32F02_param[9] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0, 0);
- pNode->node.au32F02_param[10] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0, 0);
- pNode->node.au32F02_param[11] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0, 0);
- break;
- /* AdcMuxs */
- case 0x22:
- pNode->node.name = "AdcMux-0";
- pNode->node.au32F00_param[0x9] = 0x20010b;
- pNode->node.au32F00_param[0xD] = 0x80000000;
- pNode->node.au32F00_param[0xE] = 0xb;
- goto adc_mux_init;
- case 0x23:
- pNode->node.name = "AdcMux-1";
- pNode->node.au32F00_param[0x9] = 0x20010b;
- pNode->node.au32F00_param[0xD] = 0x80000000;
- pNode->node.au32F00_param[0xE] = 0xb;
- adc_mux_init:
- /* N = 0~3 */
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
- /* N = 4~7 */
- pNode->node.au32F02_param[4] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
- pNode->node.au32F02_param[5] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
- pNode->node.au32F02_param[6] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
- pNode->node.au32F02_param[7] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
- /* N = 8~11 */
- pNode->node.au32F02_param[8] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0);
- pNode->node.au32F02_param[9] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0);
- pNode->node.au32F02_param[10] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0);
- pNode->node.au32F02_param[11] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0);
- break;
- case 0x24:
- pNode->node.name = "AdcMux-2";
- pNode->node.au32F00_param[0x9] = 0x20010b;
- pNode->node.au32F00_param[0xD] = 0x80000000;
- pNode->node.au32F00_param[0xE] = 0xb;
- /* N = 0~3 */
- pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
- pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
- pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
- pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
- /* N = 4~7 */
- pNode->node.au32F02_param[4] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
- pNode->node.au32F02_param[5] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
- pNode->node.au32F02_param[6] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
- pNode->node.au32F02_param[7] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
- /* N = 8~11 */
- pNode->node.au32F02_param[8] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0x12);
- pNode->node.au32F02_param[9] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0x12);
- pNode->node.au32F02_param[10] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0x12);
- pNode->node.au32F02_param[11] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0x12);
- break;
- /* PCBEEP */
- case 0x1D:
- pNode->node.name = "PCBEEP";
- pNode->node.au32F00_param[0x9] = 0x400000;
- pNode->port.u32F1c_param = 0x400000f0;
- pNode->node.au32F00_param[0xC] = RT_BIT(5);
- break;
- /* CD */
- case 0x1C:
- pNode->node.name = "CD";
- pNode->node.au32F00_param[0x9] = 0x400001;
- pNode->port.u32F1c_param = 0x400000f0;
- pNode->node.au32F00_param[0xC] = RT_BIT(5);
- break;
- case 0x21:
- pNode->node.name = "VolumeKnob";
- pNode->node.au32F00_param[0x9] = (0x6 << 20)|RT_BIT(7);
- break;
- default:
- AssertMsgFailed(("Unsupported Node"));
- }
- return VINF_SUCCESS;
-}
-
-
/* generic */
#define DECLISNODEOFTYPE(type) \
@@ -1332,8 +911,7 @@ static int codecSetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pR
else if (codecIsPcbeepNode(pState, CODEC_NID(cmd)))
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].pcbeep.u32F07_param;
else if ( codecIsReservedNode(pState, CODEC_NID(cmd))
- && CODEC_NID(cmd) == 0x1b
- && pState->enmCodec == STAC9220_CODEC)
+ && CODEC_NID(cmd) == 0x1b)
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F07_param;
Assert((pu32Reg));
if (pu32Reg)
@@ -2164,33 +1742,21 @@ int codecOpenVoice(CODECState *pState, ENMSOUNDSOURCE enmSoundSource, audsetting
return rc;
}
-int codecConstruct(PPDMDEVINS pDevIns, CODECState *pState, ENMCODEC enmCodec)
+int codecConstruct(PPDMDEVINS pDevIns, CODECState *pState, PCFGMNODE pCfgHandle)
{
audsettings_t as;
int rc;
pState->pVerbs = (CODECVERB *)&CODECVERBS;
pState->cVerbs = sizeof(CODECVERBS)/sizeof(CODECVERB);
pState->pfnLookup = codecLookup;
- pState->enmCodec = enmCodec;
- switch (enmCodec)
- {
- case STAC9220_CODEC:
- rc = stac9220Construct(pState);
- AssertRC(rc);
- break;
- case ALC885_CODEC:
- rc = alc885Construct(pState);
- AssertRC(rc);
- break;
- default:
- AssertMsgFailed(("Unsupported Codec"));
- }
+ rc = stac9220Construct(pState);
+ AssertRC(rc);
/* common root node initializers */
pState->pNodes[0].node.au32F00_param[0] = CODEC_MAKE_F00_00(pState->u16VendorId, pState->u16DeviceId);
pState->pNodes[0].node.au32F00_param[4] = CODEC_MAKE_F00_04(0x1, 0x1);
/* common AFG node initializers */
pState->pNodes[1].node.au32F00_param[4] = CODEC_MAKE_F00_04(0x2, pState->cTotalNodes - 2);
- pState->pNodes[1].node.au32F00_param[5] = CODEC_MAKE_F00_05(CODEC_F00_05_UNSOL, CODEC_F00_05_AFG);
+ pState->pNodes[1].node.au32F00_param[5] = CODEC_MAKE_F00_05(1, CODEC_F00_05_AFG);
pState->pNodes[1].afg.u32F20_param = CODEC_MAKE_F20(pState->u16VendorId, pState->u8BSKU, pState->u8AssemblyId);
//** @todo r=michaln: Was this meant to be 'HDA' or something like that? (AC'97 was on ICH0)
@@ -2269,13 +1835,58 @@ int codecSaveState(CODECState *pCodecState, PSSMHANDLE pSSMHandle)
return VINF_SUCCESS;
}
-int codecLoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle)
+static DECLCALLBACK(int)codecLoadV1(PCODECState pCodecState, PSSMHANDLE pSSMHandle, size_t cbOffset, size_t alignment)
{
- SSMR3GetMem (pSSMHandle, pCodecState->pNodes, sizeof(CODECNODE) * pCodecState->cTotalNodes);
+ size_t cbRawNodesV1 = (sizeof(CODECNODE) + cbOffset + alignment) * pCodecState->cTotalNodes;
+ uint8_t *pu8RawNodesV1 = (uint8_t *)RTMemAlloc(cbRawNodesV1);
+ uint8_t *pu8NodeV1 = NULL;
+ int idxNode = 0;
+ if (!pu8RawNodesV1)
+ return VERR_NO_MEMORY;
+ int rc = SSMR3GetMem (pSSMHandle, pu8RawNodesV1, cbRawNodesV1);
+
+ if (RT_FAILURE(rc))
+ {
+ RTMemFree(pu8RawNodesV1);
+ AssertRCReturn(rc, rc);
+ }
+ pu8NodeV1 = &pu8RawNodesV1[0];
+ for (idxNode = 0; idxNode < pCodecState->cTotalNodes; ++idxNode)
+ {
+ pCodecState->pNodes[idxNode].node.id = pu8NodeV1[0];
+ memcpy(pCodecState->pNodes[idxNode].node.au32F00_param,
+ pu8NodeV1 + RT_OFFSETOF(CODECCOMMONNODE, au32F00_param) + alignment,
+ sizeof(CODECNODE) - RT_OFFSETOF(CODECCOMMONNODE,au32F00_param));
+ pu8NodeV1 += sizeof(CODECNODE) + cbOffset;
+ }
+
+ RTMemFree(pu8RawNodesV1);
+ return rc;
+}
+
+int codecLoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle, uint32_t uVersion)
+{
+ int rc;
+ if (uVersion == HDA_SSM_VERSION_1)
+ {
+#if RT_ARCH_X86
+ if (SSMR3HandleHostBits(pSSMHandle) == 32)
+ rc = codecLoadV1(pCodecState, pSSMHandle, sizeof(long), 0);
+ else
+ rc = codecLoadV1(pCodecState, pSSMHandle, sizeof(uint64_t), 4);
+#else
+ if (SSMR3HandleHostBits(pSSMHandle) == 64)
+ rc = codecLoadV1(pCodecState, pSSMHandle, sizeof(long), 4);
+ else
+ rc = codecLoadV1(pCodecState, pSSMHandle, sizeof(uint32_t), 0);
+#endif
+ }
+ else
+ rc = SSMR3GetMem (pSSMHandle, pCodecState->pNodes, sizeof(CODECNODE) * pCodecState->cTotalNodes);
if (codecIsDacNode(pCodecState, pCodecState->u8DacLineOut))
codecToAudVolume(&pCodecState->pNodes[pCodecState->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
else if (codecIsSpdifOutNode(pCodecState, pCodecState->u8DacLineOut))
codecToAudVolume(&pCodecState->pNodes[pCodecState->u8DacLineOut].spdifout.B_params, AUD_MIXER_VOLUME);
codecToAudVolume(&pCodecState->pNodes[pCodecState->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
- return VINF_SUCCESS;
+ return rc;
}
diff --git a/src/VBox/Devices/Audio/DevCodec.h b/src/VBox/Devices/Audio/DevCodec.h
index 14ba9b7ea..682260e1d 100644
--- a/src/VBox/Devices/Audio/DevCodec.h
+++ b/src/VBox/Devices/Audio/DevCodec.h
@@ -1,4 +1,4 @@
-/* $Id: DevCodec.h $ */
+/* $Id: DevCodec.h 37482 2011-06-16 04:09:27Z vboxsync $ */
/** @file
* DevCodec - VBox ICH Intel HD Audio Codec.
*/
@@ -47,6 +47,9 @@ typedef FNCODECVERBPROCESSOR **PPFNCODECVERBPROCESSOR;
#define CODEC_VERB_CMD4(cmd) (CODEC_VERB_CMD((cmd), CODEC_VERB_4BIT_CMD, 4))
#define CODEC_VERB_CMD8(cmd) (CODEC_VERB_CMD((cmd), CODEC_VERB_8BIT_CMD, 8))
#define CODEC_VERB_CMD16(cmd) (CODEC_VERB_CMD((cmd), CODEC_VERB_16BIT_CMD, 16))
+#define CODEC_VERB_PAYLOAD4(cmd) ((cmd) & CODEC_VERB_4BIT_DATA)
+#define CODEC_VERB_PAYLOAD8(cmd) ((cmd) & CODEC_VERB_8BIT_DATA)
+#define CODEC_VERB_PAYLOAD16(cmd) ((cmd) & CODEC_VERB_16BIT_DATA)
#define CODEC_VERB_GET_AMP_DIRECTION RT_BIT(15)
#define CODEC_VERB_GET_AMP_SIDE RT_BIT(13)
@@ -73,22 +76,28 @@ typedef FNCODECVERBPROCESSOR **PPFNCODECVERBPROCESSOR;
/* HDA spec 7.3.3.1 defines layout of configuration registers/verbs (0xF00) */
/* VendorID (7.3.4.1) */
#define CODEC_MAKE_F00_00(vendorID, deviceID) (((vendorID) << 16) | (deviceID))
+#define CODEC_F00_00_VENDORID(f00_00) (((f00_00) >> 16) & 0xFFFF)
+#define CODEC_F00_00_DEVICEID(f00_00) ((f00_00) & 0xFFFF)
/* RevisionID (7.3.4.2)*/
#define CODEC_MAKE_F00_02(MajRev, MinRev, RevisionID, SteppingID) (((MajRev) << 20)|((MinRev) << 16)|((RevisionID) << 8)|(SteppingID))
/* Subordinate node count (7.3.4.3)*/
#define CODEC_MAKE_F00_04(startNodeNumber, totalNodeNumber) ((((startNodeNumber) & 0xFF) << 16)|((totalNodeNumber) & 0xFF))
+#define CODEC_F00_04_TO_START_NODE_NUMBER(f00_04) (((f00_04) >> 16) & 0xFF)
+#define CODEC_F00_04_TO_NODE_COUNT(f00_04) ((f00_04) & 0xFF)
/*
* Function Group Type (7.3.4.4)
* 0 & [0x3-0x7f] are reserved types
* [0x80 - 0xff] are vendor defined function groups
*/
-#define CODEC_MAKE_F00_05(UnSol, NodeType) ((UnSol)|(NodeType))
+#define CODEC_MAKE_F00_05(UnSol, NodeType) (((UnSol) << 8)|(NodeType))
#define CODEC_F00_05_UNSOL RT_BIT(8)
#define CODEC_F00_05_AFG (0x1)
#define CODEC_F00_05_MFG (0x2)
+#define CODEC_F00_05_IS_UNSOL(f00_05) RT_BOOL((f00_05) & RT_BIT(8))
+#define CODEC_F00_05_GROUP(f00_05) ((f00_05) & 0xff)
/* Audio Function Group capabilities (7.3.4.5) */
-#define CODEC_MAKE_F00_08(BeepGen, InputDelay, OutputDelay) ((BeepGen)| (((InputDelay) & 0xF) << 8) | ((OutputDelay) & 0xF))
-#define CODEC_F00_08_BEEP_GEN RT_BIT(16)
+#define CODEC_MAKE_F00_08(BeepGen, InputDelay, OutputDelay) ((((BeepGen) & 0x1) << 16)| (((InputDelay) & 0xF) << 8) | ((OutputDelay) & 0xF))
+#define CODEC_F00_08_BEEP_GEN(f00_08) ((f00_08) & RT_BIT(16)
/* Widget Capabilities (7.3.4.6) */
#define CODEC_MAKE_F00_09(type, delay, chanel_count) \
@@ -120,6 +129,22 @@ typedef FNCODECVERBPROCESSOR **PPFNCODECVERBPROCESSOR;
#define CODEC_F00_09_CAP_IN_AMP_PRESENT RT_BIT(1)
#define CODEC_F00_09_CAP_LSB RT_BIT(0)
+#define CODEC_F00_09_TYPE(f00_09) (((f00_09) >> 20) & 0xF)
+
+#define CODEC_F00_09_IS_CAP_CP(f00_09) RT_BOOL((f00_09) & RT_BIT(12))
+#define CODEC_F00_09_IS_CAP_L_R_SWAP(f00_09) RT_BOOL((f00_09) & RT_BIT(11))
+#define CODEC_F00_09_IS_CAP_POWER_CTRL(f00_09) RT_BOOL((f00_09) & RT_BIT(10))
+#define CODEC_F00_09_IS_CAP_DIGITAL(f00_09) RT_BOOL((f00_09) & RT_BIT(9))
+#define CODEC_F00_09_IS_CAP_CONNECTION_LIST(f00_09) RT_BOOL((f00_09) & RT_BIT(8))
+#define CODEC_F00_09_IS_CAP_UNSOL(f00_09) RT_BOOL((f00_09) & RT_BIT(7))
+#define CODEC_F00_09_IS_CAP_PROC_WIDGET(f00_09) RT_BOOL((f00_09) & RT_BIT(6))
+#define CODEC_F00_09_IS_CAP_STRIPE(f00_09) RT_BOOL((f00_09) & RT_BIT(5))
+#define CODEC_F00_09_IS_CAP_FMT_OVERRIDE(f00_09) RT_BOOL((f00_09) & RT_BIT(4))
+#define CODEC_F00_09_IS_CAP_AMP_OVERRIDE(f00_09) RT_BOOL((f00_09) & RT_BIT(3))
+#define CODEC_F00_09_IS_CAP_OUT_AMP_PRESENT(f00_09) RT_BOOL((f00_09) & RT_BIT(2))
+#define CODEC_F00_09_IS_CAP_IN_AMP_PRESENT(f00_09) RT_BOOL((f00_09) & RT_BIT(1))
+#define CODEC_F00_09_IS_CAP_LSB(f00_09) RT_BOOL((f00_09) & RT_BIT(0))
+
/* Supported PCM size, rates (7.3.4.7) */
#define CODEC_F00_0A_32_BIT RT_BIT(19)
#define CODEC_F00_0A_24_BIT RT_BIT(18)
@@ -163,17 +188,34 @@ typedef FNCODECVERBPROCESSOR **PPFNCODECVERBPROCESSOR;
#define CODEC_F00_0C_CAP_TRIGGER_REQUIRED RT_BIT(1)
#define CODEC_F00_0C_CAP_IMPENDANCE_SENSE RT_BIT(0)
-/* Amplifier capabilities (7.3.4.10) */
+#define CODEC_F00_0C_IS_CAP_HBR(f00_0c) ((f00_0c) & RT_BIT(27))
+#define CODEC_F00_0C_IS_CAP_DP(f00_0c) ((f00_0c) & RT_BIT(24))
+#define CODEC_F00_0C_IS_CAP_EAPD(f00_0c) ((f00_0c) & RT_BIT(16))
+#define CODEC_F00_0C_IS_CAP_HDMI(f00_0c) ((f00_0c) & RT_BIT(7))
+#define CODEC_F00_0C_IS_CAP_BALANCED_IO(f00_0c) ((f00_0c) & RT_BIT(6))
+#define CODEC_F00_0C_IS_CAP_INPUT(f00_0c) ((f00_0c) & RT_BIT(5))
+#define CODEC_F00_0C_IS_CAP_OUTPUT(f00_0c) ((f00_0c) & RT_BIT(4))
+#define CODEC_F00_0C_IS_CAP_HP(f00_0c) ((f00_0c) & RT_BIT(3))
+#define CODEC_F00_0C_IS_CAP_PRESENSE_DETECT(f00_0c) ((f00_0c) & RT_BIT(2))
+#define CODEC_F00_0C_IS_CAP_TRIGGER_REQUIRED(f00_0c) ((f00_0c) & RT_BIT(1))
+#define CODEC_F00_0C_IS_CAP_IMPENDANCE_SENSE(f00_0c) ((f00_0c) & RT_BIT(0))
+
+/* Input Amplifier capabilities (7.3.4.10) */
#define CODEC_MAKE_F00_0D(mute_cap, step_size, num_steps, offset) \
( (((mute_cap) & 0x1) << 31) \
| (((step_size) & 0xFF) << 16) \
| (((num_steps) & 0xFF) << 8) \
| ((offset) & 0xFF))
+/* Output Amplifier capabilities (7.3.4.10) */
+#define CODEC_MAKE_F00_12 CODEC_MAKE_F00_0D
+
/* Connection list lenght (7.3.4.11) */
#define CODEC_MAKE_F00_0E(long_form, length) \
( (((long_form) & 0x1) << 7) \
| ((length) & 0x7F))
+#define CODEC_F00_0E_IS_LONG(f00_0e) RT_BOOL((f00_0e) & RT_BIT(7))
+#define CODEC_F00_0E_COUNT(f00_0e) ((f00_0e) & 0x7F)
/* Supported Power States (7.3.4.12) */
#define CODEC_F00_0F_EPSS RT_BIT(31)
#define CODEC_F00_0F_CLKSTOP RT_BIT(30)
@@ -184,6 +226,11 @@ typedef FNCODECVERBPROCESSOR **PPFNCODECVERBPROCESSOR;
#define CODEC_F00_0F_D1 RT_BIT(1)
#define CODEC_F00_0F_D0 RT_BIT(0)
+/* Processing capabilities 7.3.4.13 */
+#define CODEC_MAKE_F00_10(num, benign) ((((num) & 0xFF) << 8) | ((benign) & 0x1))
+#define CODEC_F00_10_NUM(f00_10) (((f00_10) & (0xFF << 8)) >> 8)
+#define CODEC_F00_10_BENING(f00_10) ((f00_10) & 0x1)
+
/* CP/IO Count (7.3.4.14) */
#define CODEC_MAKE_F00_11(wake, unsol, numgpi, numgpo, numgpio) \
( (((wake) & 0x1) << 31) \
@@ -192,6 +239,10 @@ typedef FNCODECVERBPROCESSOR **PPFNCODECVERBPROCESSOR;
| (((numgpo) & 0xFF) << 8) \
| ((numgpio) & 0xFF))
+/* Processing States (7.3.3.4) */
+#define CODEC_F03_OFF (0)
+#define CODEC_F03_ON RT_BIT(0)
+#define CODEC_F03_BENING RT_BIT(1)
/* Power States (7.3.3.10) */
#define CODEC_MAKE_F05(reset, stopok, error, act, set) \
( (((reset) & 0x1) << 10) \
@@ -211,6 +262,9 @@ typedef FNCODECVERBPROCESSOR **PPFNCODECVERBPROCESSOR;
#define CODEC_F05_ACT(value) (((value) & 0x7) >> 4)
#define CODEC_F05_SET(value) (((value) & 0x7))
+#define CODEC_F05_GE(p0, p1) ((p0) <= (p1))
+#define CODEC_F05_LE(p0, p1) ((p0) >= (p1))
+
/* Pin Widged Control (7.3.3.13) */
#define CODEC_F07_VREF_HIZ (0)
#define CODEC_F07_VREF_50 (0x1)
@@ -221,6 +275,9 @@ typedef FNCODECVERBPROCESSOR **PPFNCODECVERBPROCESSOR;
#define CODEC_F07_OUT_ENABLE RT_BIT(6)
#define CODEC_F07_OUT_H_ENABLE RT_BIT(7)
+/* Unsolicited enabled (7.3.3.14) */
+#define CODEC_MAKE_F08(enable, tag) ((((enable) & 1) << 7) | ((tag) & 0x3F))
+
/* Converter formats (7.3.3.8) and (3.7.1) */
#define CODEC_MAKE_A(fNonPCM, f44_1BaseRate, mult, div, bits, chan) \
( (((fNonPCM) & 0x1) << 15) \
@@ -259,6 +316,10 @@ typedef FNCODECVERBPROCESSOR **PPFNCODECVERBPROCESSOR;
( (((fPresent) & 0x1) << 31) \
| (((fELDValid) & 0x1) << 30))
+#define CODEC_MAKE_F0C(lrswap, eapd, btl) ((((lrswap) & 1) << 2) | (((eapd) & 1) << 1) | ((btl) & 1))
+#define CODEC_FOC_IS_LRSWAP(f0c) RT_BOOL((f0c) & RT_BIT(2))
+#define CODEC_FOC_IS_EAPD(f0c) RT_BOOL((f0c) & RT_BIT(1))
+#define CODEC_FOC_IS_BTL(f0c) RT_BOOL((f0c) & RT_BIT(0))
/* HDA spec 7.3.3.31 defines layout of configuration registers/verbs (0xF1C) */
/* Configuration's port connection */
#define CODEC_F1C_PORT_MASK (0x3)
@@ -288,7 +349,7 @@ typedef FNCODECVERBPROCESSOR **PPFNCODECVERBPROCESSOR;
#define CODEC_F1C_LOCATION_BOTTOM (0x6)
#define CODEC_F1C_LOCATION_SPECIAL_0 (0x7)
#define CODEC_F1C_LOCATION_SPECIAL_1 (0x8)
-#define CODEC_F1C_LOCATION_SPECIAL_3 (0x9)
+#define CODEC_F1C_LOCATION_SPECIAL_2 (0x9)
/* Configuration's devices */
#define CODEC_F1C_DEVICE_MASK (0xF)
@@ -350,10 +411,10 @@ typedef FNCODECVERBPROCESSOR **PPFNCODECVERBPROCESSOR;
/* Configuration's misc */
#define CODEC_F1C_MISC_MASK (0xF)
#define CODEC_F1C_MISC_SHIFT (8)
-#define CODEC_F1C_MISC_JACK_DETECT RT_BIT(0)
-#define CODEC_F1C_MISC_RESERVED_0 RT_BIT(1)
-#define CODEC_F1C_MISC_RESERVED_1 RT_BIT(2)
-#define CODEC_F1C_MISC_RESERVED_2 RT_BIT(3)
+#define CODEC_F1C_MISC_JACK_DETECT (0)
+#define CODEC_F1C_MISC_RESERVED_0 (1)
+#define CODEC_F1C_MISC_RESERVED_1 (2)
+#define CODEC_F1C_MISC_RESERVED_2 (3)
/* Configuration's association */
#define CODEC_F1C_ASSOCIATION_MASK (0xF)
@@ -381,6 +442,7 @@ typedef FNCODECVERBPROCESSOR **PPFNCODECVERBPROCESSOR;
| ((sequence)))
+#ifndef VBOX_WITH_HDA_CODEC_EMU
typedef struct CODECVERB
{
uint32_t verb;
@@ -388,11 +450,14 @@ typedef struct CODECVERB
uint32_t mask;
PFNCODECVERBPROCESSOR pfn;
} CODECVERB;
+#endif
-#ifndef VBOX_HDA_CODEC_EMU
+#ifndef VBOX_WITH_HDA_CODEC_EMU
# define TYPE union
#else
# define TYPE struct
+typedef struct CODECEMU CODECEMU;
+typedef CODECEMU *PCODECEMU;
#endif
TYPE CODECNODE;
typedef TYPE CODECNODE CODECNODE;
@@ -407,11 +472,6 @@ typedef enum
LAST_INDEX
} ENMSOUNDSOURCE;
-typedef enum
-{
- STAC9220_CODEC,
- ALC885_CODEC
-} ENMCODEC;
typedef struct CODECState
{
@@ -420,17 +480,21 @@ typedef struct CODECState
uint16_t u16DeviceId;
uint8_t u8BSKU;
uint8_t u8AssemblyId;
+#ifndef VBOX_WITH_HDA_CODEC_EMU
CODECVERB *pVerbs;
int cVerbs;
+#else
+ PCODECEMU pCodecBackend;
+#endif
PCODECNODE pNodes;
QEMUSoundCard card;
/** PCM in */
SWVoiceIn *SwVoiceIn;
/** PCM out */
SWVoiceOut *SwVoiceOut;
- ENMCODEC enmCodec;
void *pHDAState;
bool fInReset;
+#ifndef VBOX_WITH_HDA_CODEC_EMU
const uint8_t cTotalNodes;
const uint8_t *au8Ports;
const uint8_t *au8Dacs;
@@ -447,18 +511,35 @@ typedef struct CODECState
const uint8_t *au8Reserveds;
const uint8_t u8AdcVolsLineIn;
const uint8_t u8DacLineOut;
+#endif
DECLR3CALLBACKMEMBER(int, pfnProcess, (struct CODECState *));
+ DECLR3CALLBACKMEMBER(void, pfnTransfer, (struct CODECState *pState, ENMSOUNDSOURCE, int avail));
+ /* These callbacks are set by Codec implementation */
DECLR3CALLBACKMEMBER(int, pfnLookup, (struct CODECState *pState, uint32_t verb, PPFNCODECVERBPROCESSOR));
DECLR3CALLBACKMEMBER(int, pfnReset, (struct CODECState *pState));
- DECLR3CALLBACKMEMBER(void, pfnTransfer, (struct CODECState *pState, ENMSOUNDSOURCE, int avail));
DECLR3CALLBACKMEMBER(int, pfnCodecNodeReset, (struct CODECState *pState, uint8_t, PCODECNODE));
+ /* These callbacks are set by codec implementation to answer debugger requests */
+ DECLR3CALLBACKMEMBER(void, pfnCodecDbgListNodes, (CODECState *pState, PCDBGFINFOHLP pHlp, const char *pszArgs));
+ DECLR3CALLBACKMEMBER(void, pfnCodecDbgSelector, (CODECState *pState, PCDBGFINFOHLP pHlp, const char *pszArgs));
+} CODECState, *PCODECState;
-} CODECState;
-
-int codecConstruct(PPDMDEVINS pDevIns, CODECState *pCodecState, ENMCODEC enmCodec);
+int codecConstruct(PPDMDEVINS pDevIns, CODECState *pCodecState, PCFGMNODE pCfgHandle);
int codecDestruct(CODECState *pCodecState);
int codecSaveState(CODECState *pCodecState, PSSMHANDLE pSSMHandle);
-int codecLoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle);
+int codecLoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle, uint32_t uVersion);
int codecOpenVoice(CODECState *pCodecState, ENMSOUNDSOURCE enmSoundSource, audsettings_t *pAudioSettings);
+#define HDA_SSM_VERSION 3
+#define HDA_SSM_VERSION_1 1
+#define HDA_SSM_VERSION_2 2
+
+# ifdef VBOX_WITH_HDA_CODEC_EMU
+/* */
+struct CODECEMU
+{
+ DECLR3CALLBACKMEMBER(int, pfnCodecEmuConstruct, (PCODECState pState));
+ DECLR3CALLBACKMEMBER(int, pfnCodecEmuDestruct, (PCODECState pState));
+ DECLR3CALLBACKMEMBER(int, pfnCodecEmuReset, (PCODECState pState, bool fInit));
+};
+# endif
#endif
diff --git a/src/VBox/Devices/Audio/DevIchAc97.cpp b/src/VBox/Devices/Audio/DevIchAc97.cpp
index e6bba5a73..b5fe6a7d6 100644
--- a/src/VBox/Devices/Audio/DevIchAc97.cpp
+++ b/src/VBox/Devices/Audio/DevIchAc97.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevIchAc97.cpp $ */
+/* $Id: DevIchAc97.cpp 35487 2011-01-11 13:45:20Z vboxsync $ */
/** @file
* DevIchAc97 - VBox ICH AC97 Audio Controller.
*/
diff --git a/src/VBox/Devices/Audio/DevIchIntelHDA.cpp b/src/VBox/Devices/Audio/DevIchIntelHDA.cpp
index e07c8f1d2..1e82865f6 100644
--- a/src/VBox/Devices/Audio/DevIchIntelHDA.cpp
+++ b/src/VBox/Devices/Audio/DevIchIntelHDA.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevIchIntelHDA.cpp $ */
+/* $Id: DevIchIntelHDA.cpp 37654 2011-06-28 06:02:23Z vboxsync $ */
/** @file
* DevIchIntelHD - VBox ICH Intel HD Audio Controller.
*/
@@ -52,11 +52,11 @@ extern "C" {
# error "Please specify your HDA device vendor/device IDs"
#endif
-#define HDA_SSM_VERSION 1
PDMBOTHCBDECL(int) hdaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
+PDMBOTHCBDECL(int) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb);
static DECLCALLBACK(void) hdaReset (PPDMDEVINS pDevIns);
+#define HDA_NREGS 112
/* Registers */
#define HDA_REG_IND_NAME(x) ICH6_HDA_REG_##x
#define HDA_REG_FIELD_NAME(reg, x) ICH6_HDA_##reg##_##x
@@ -262,6 +262,10 @@ static DECLCALLBACK(void) hdaReset (PPDMDEVINS pDevIns);
#define SDCTL_NUM(pState, num) ((SDCTL((pState), num) & HDA_REG_FIELD_MASK(SDCTL,NUM)) >> HDA_REG_FIELD_SHIFT(SDCTL, NUM))
#define ICH6_HDA_SDCTL_NUM_MASK (0xF)
#define ICH6_HDA_SDCTL_NUM_SHIFT (20)
+#define ICH6_HDA_SDCTL_DIR_SHIFT (19)
+#define ICH6_HDA_SDCTL_TP_SHIFT (18)
+#define ICH6_HDA_SDCTL_STRIPE_MASK (0x3)
+#define ICH6_HDA_SDCTL_STRIPE_SHIFT (16)
#define ICH6_HDA_SDCTL_DEIE_SHIFT (4)
#define ICH6_HDA_SDCTL_FEIE_SHIFT (3)
#define ICH6_HDA_SDCTL_ICE_SHIFT (2)
@@ -372,6 +376,8 @@ static DECLCALLBACK(void) hdaReset (PPDMDEVINS pDevIns);
#define ICH6_HDA_SDFMT_MULT_MASK (0x7)
#define ICH6_HDA_SDFMT_DIV_SHIFT (8)
#define ICH6_HDA_SDFMT_DIV_MASK (0x7)
+#define ICH6_HDA_SDFMT_BITS_SHIFT (4)
+#define ICH6_HDA_SDFMT_BITS_MASK (0x7)
#define SDFMT_BASE_RATE(pState, num) ((SDFMT(pState, num) & HDA_REG_FIELD_FLAG_MASK(SDFMT, BASE_RATE)) >> HDA_REG_FIELD_SHIFT(SDFMT, BASE_RATE))
#define SDFMT_MULT(pState, num) ((SDFMT((pState), num) & HDA_REG_FIELD_MASK(SDFMT,MULT)) >> HDA_REG_FIELD_SHIFT(SDFMT, MULT))
#define SDFMT_DIV(pState, num) ((SDFMT((pState), num) & HDA_REG_FIELD_MASK(SDFMT,DIV)) >> HDA_REG_FIELD_SHIFT(SDFMT, DIV))
@@ -412,6 +418,19 @@ typedef struct HDABDLEDESC
uint8_t au8HdaBuffer[HDA_SDONFIFO_256B + 1];
} HDABDLEDESC, *PHDABDLEDESC;
+static SSMFIELD const g_aHdaBDLEDescFields[] =
+{
+ SSMFIELD_ENTRY( HDABDLEDESC, u64BdleCviAddr),
+ SSMFIELD_ENTRY( HDABDLEDESC, u32BdleMaxCvi),
+ SSMFIELD_ENTRY( HDABDLEDESC, u32BdleCvi),
+ SSMFIELD_ENTRY( HDABDLEDESC, u32BdleCviLen),
+ SSMFIELD_ENTRY( HDABDLEDESC, u32BdleCviPos),
+ SSMFIELD_ENTRY( HDABDLEDESC, fBdleCviIoc),
+ SSMFIELD_ENTRY( HDABDLEDESC, cbUnderFifoW),
+ SSMFIELD_ENTRY( HDABDLEDESC, au8HdaBuffer),
+ SSMFIELD_ENTRY_TERM()
+};
+
typedef struct HDASTREAMTRANSFERDESC
{
uint64_t u64BaseDMA;
@@ -434,7 +453,7 @@ typedef struct INTELHDLinkState
/** The base interface for LUN\#0. */
PDMIBASE IBase;
RTGCPHYS addrMMReg;
- uint32_t au32Regs[113];
+ uint32_t au32Regs[HDA_NREGS];
HDABDLEDESC stInBdle;
HDABDLEDESC stOutBdle;
HDABDLEDESC stMicBdle;
@@ -515,12 +534,13 @@ DECLCALLBACK(int)hdaRegReadU8(INTELHDLinkState* pState, uint32_t offset, uint32_
DECLCALLBACK(int)hdaRegWriteU8(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t pu32Value);
static inline void hdaInitTransferDescriptor(PINTELHDLinkState pState, PHDABDLEDESC pBdle, uint8_t u8Strm, PHDASTREAMTRANSFERDESC pStreamDesc);
-static int hdaLookup(INTELHDLinkState* pState, uint32_t u32Offset);
+static int hdaMMIORegLookup(INTELHDLinkState* pState, uint32_t u32Offset);
static void hdaFetchBdle(INTELHDLinkState *pState, PHDABDLEDESC pBdle, PHDASTREAMTRANSFERDESC pStreamDesc);
#ifdef LOG_ENABLED
static void dump_bd(INTELHDLinkState *pState, PHDABDLEDESC pBdle, uint64_t u64BaseDMA);
#endif
+
/* see 302349 p 6.2*/
const static struct stIchIntelHDRegMap
{
@@ -540,7 +560,7 @@ const static struct stIchIntelHDRegMap
const char *abbrev;
/** Full name. */
const char *name;
-} s_ichIntelHDRegMap[] =
+} s_ichIntelHDRegMap[HDA_NREGS] =
{
/* offset size read mask write mask read callback write callback abbrev full name */
/*------- ------- ---------- ---------- ----------------------- ------------------------ ---------- ------------------------------*/
@@ -556,7 +576,7 @@ const static struct stIchIntelHDRegMap
{ 0x00020, 0x00004, 0xC00000FF, 0xC00000FF, hdaRegReadU32 , hdaRegWriteU32 , "INTCTL" , "Interrupt Control" },
{ 0x00024, 0x00004, 0xC00000FF, 0x00000000, hdaRegReadINTSTS , hdaRegWriteUnimplemented, "INTSTS" , "Interrupt Status" },
{ 0x00030, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadWALCLK , hdaRegWriteUnimplemented, "WALCLK" , "Wall Clock Counter" },
- //** @todo r=michaln: Doesn't the SSYNC register need to actually stop the stream(s)?
+ /// @todo r=michaln: Doesn't the SSYNC register need to actually stop the stream(s)?
{ 0x00034, 0x00004, 0x000000FF, 0x000000FF, hdaRegReadU32 , hdaRegWriteU32 , "SSYNC" , "Stream Synchronization" },
{ 0x00040, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32 , hdaRegWriteBase , "CORBLBASE" , "CORB Lower Base Address" },
{ 0x00044, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteBase , "CORBUBASE" , "CORB Upper Base Address" },
@@ -712,18 +732,11 @@ static int hdaProcessInterrupt(INTELHDLinkState* pState)
return VINF_SUCCESS;
}
-static int hdaLookup(INTELHDLinkState* pState, uint32_t u32Offset)
+static int hdaMMIORegLookup(INTELHDLinkState* pState, uint32_t u32Offset)
{
- int index = 0;
- //** @todo r=michaln: A linear search of an array with over 100 elements is very inefficient.
- for (;index < (int)(sizeof(s_ichIntelHDRegMap)/sizeof(s_ichIntelHDRegMap[0])); ++index)
- {
- if ( u32Offset >= s_ichIntelHDRegMap[index].offset
- && u32Offset < s_ichIntelHDRegMap[index].offset + s_ichIntelHDRegMap[index].size)
- {
- return index;
- }
- }
+ int idxMiddle;
+ int idxHigh = RT_ELEMENTS(s_ichIntelHDRegMap);
+ int idxLow = 0;
/* Aliases HDA spec 3.3.45 */
switch(u32Offset)
{
@@ -744,6 +757,30 @@ static int hdaLookup(INTELHDLinkState* pState, uint32_t u32Offset)
case 0x2164:
return HDA_REG_IND_NAME(SD7LPIB);
}
+ while (1)
+ {
+#ifdef DEBUG_vvl
+ Assert(( idxHigh >= 0
+ && idxLow >= 0));
+#endif
+ if ( idxHigh < idxLow
+ || idxHigh < 0)
+ break;
+ idxMiddle = idxLow + (idxHigh - idxLow)/2;
+ if (u32Offset < s_ichIntelHDRegMap[idxMiddle].offset)
+ {
+ idxHigh = idxMiddle - 1;
+ continue;
+ }
+ if (u32Offset >= s_ichIntelHDRegMap[idxMiddle].offset + s_ichIntelHDRegMap[idxMiddle].size)
+ {
+ idxLow = idxMiddle + 1;
+ continue;
+ }
+ if ( u32Offset >= s_ichIntelHDRegMap[idxMiddle].offset
+ && u32Offset < s_ichIntelHDRegMap[idxMiddle].offset + s_ichIntelHDRegMap[idxMiddle].size)
+ return idxMiddle;
+ }
return -1;
}
@@ -1248,7 +1285,31 @@ static void inline hdaSdFmtToAudSettings(uint32_t u32SdFmt, audsettings_t *pAudS
case 7: u32HzDiv = 8; break;
}
pAudSetting->freq = u32Hz * u32HzMult / u32HzDiv;
- pAudSetting->nchannels = 2;
+
+ switch (EXTRACT_VALUE(u32SdFmt, ICH6_HDA_SDFMT_BITS_MASK, ICH6_HDA_SDFMT_BITS_SHIFT))
+ {
+ case 0:
+ Log(("hda: %s requested 8 bit\n", __FUNCTION__));
+ pAudSetting->fmt = AUD_FMT_S8;
+ break;
+ case 1:
+ Log(("hda: %s requested 16 bit\n", __FUNCTION__));
+ pAudSetting->fmt = AUD_FMT_S16;
+ break;
+ case 2:
+ Log(("hda: %s requested 20 bit\n", __FUNCTION__));
+ break;
+ case 3:
+ Log(("hda: %s requested 24 bit\n", __FUNCTION__));
+ break;
+ case 4:
+ Log(("hda: %s requested 32 bit\n", __FUNCTION__));
+ pAudSetting->fmt = AUD_FMT_S32;
+ break;
+ default:
+ AssertMsgFailed(("Unsupported"));
+ }
+ pAudSetting->nchannels = (u32SdFmt & 0xf) + 1;
pAudSetting->fmt = AUD_FMT_S16;
pAudSetting->endianness = 0;
#undef EXTRACT_VALUE
@@ -1256,26 +1317,30 @@ static void inline hdaSdFmtToAudSettings(uint32_t u32SdFmt, audsettings_t *pAudS
DECLCALLBACK(int)hdaRegWriteSDFMT(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value)
{
-#if 0
- /* @todo here some more investigations are required. */
- audsettings_t as;
- /* no reason to reopen voice with same settings */
- if (u32Value == HDA_REG_IND(pState, index))
- return VINF_SUCCESS;
- hdaSdFmtToAudSettings(u32Value, &as);
- switch (index)
- {
- case ICH6_HDA_REG_SD0FMT:
- codecOpenVoice(&pState->Codec, PI_INDEX, &as);
- break;
- case ICH6_HDA_REG_SD4FMT:
- codecOpenVoice(&pState->Codec, PO_INDEX, &as);
- break;
- default:
- AssertMsgFailed(("unimplemented"));
- }
+#ifdef VBOX_WITH_HDA_CODEC_EMU
+ /* @todo here some more investigations are required. */
+ int rc = 0;
+ audsettings_t as;
+ /* no reason to reopen voice with same settings */
+ if (u32Value == HDA_REG_IND(pState, index))
+ return VINF_SUCCESS;
+ hdaSdFmtToAudSettings(u32Value, &as);
+ switch (index)
+ {
+ case ICH6_HDA_REG_SD0FMT:
+ rc = codecOpenVoice(&pState->Codec, PI_INDEX, &as);
+ break;
+ case ICH6_HDA_REG_SD4FMT:
+ rc = codecOpenVoice(&pState->Codec, PO_INDEX, &as);
+ break;
+ default:
+ Log(("HDA: attempt to change format on %d\n", index));
+ rc = 0;
+ }
+ return hdaRegWriteU16(pState, offset, index, u32Value);
+#else
+ return hdaRegWriteU16(pState, offset, index, u32Value);
#endif
- return hdaRegWriteU16(pState, offset, index, u32Value);
}
DECLCALLBACK(int)hdaRegWriteSDBDPL(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value)
@@ -1809,35 +1874,54 @@ PDMBOTHCBDECL(int) hdaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhys
{
int rc = VINF_SUCCESS;
PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
- uint32_t u32Offset = GCPhysAddr - pThis->hda.addrMMReg;
- int index = hdaLookup(&pThis->hda, u32Offset);
- if (pThis->hda.fInReset && index != ICH6_HDA_REG_GCTL)
+ uint32_t offReg = GCPhysAddr - pThis->hda.addrMMReg;
+ int idxReg = hdaMMIORegLookup(&pThis->hda, offReg);
+ if (pThis->hda.fInReset && idxReg != ICH6_HDA_REG_GCTL)
Log(("hda: access to registers except GCTL is blocked while reset\n"));
- if ( index == -1
- || cb > 4)
- LogRel(("hda: Invalid read access @0x%x(of bytes:%d)\n", u32Offset, cb));
+ if (idxReg == -1)
+ LogRel(("hda: Invalid read access @0x%x(of bytes:%d)\n", offReg, cb));
- if (index != -1)
+ if (idxReg != -1)
{
+ /** @todo r=bird: Accesses crossing register boundraries aren't handled
+ * right from what I can tell? If they are, please explain
+ * what the rules are. */
uint32_t mask = 0;
- uint32_t shift = (u32Offset - s_ichIntelHDRegMap[index].offset) % sizeof(uint32_t) * 8;
- uint32_t v = 0;
+ uint32_t shift = (s_ichIntelHDRegMap[idxReg].offset - offReg) % sizeof(uint32_t) * 8;
+ uint32_t u32Value = 0;
switch(cb)
{
case 1: mask = 0x000000ff; break;
case 2: mask = 0x0000ffff; break;
- case 3: mask = 0x00ffffff; break;
- case 4: mask = 0xffffffff; break;
+ case 4:
+ /* 18.2 of ICH6 datasheet defines wideness of the accesses byte, word and double word */
+ case 8:
+ mask = 0xffffffff;
+ cb = 4;
+ break;
}
+#if 0
+ /* cross register access. Mac guest hit this assert doing assumption 4 byte access to 3 byte registers e.g. {I,O}SDnCTL
+ */
+ //Assert((cb <= s_ichIntelHDRegMap[idxReg].size - (offReg - s_ichIntelHDRegMap[idxReg].offset)));
+ if (cb > s_ichIntelHDRegMap[idxReg].size - (offReg - s_ichIntelHDRegMap[idxReg].offset))
+ {
+ int off = cb - (s_ichIntelHDRegMap[idxReg].size - (offReg - s_ichIntelHDRegMap[idxReg].offset));
+ rc = hdaMMIORead(pDevIns, pvUser, GCPhysAddr + cb - off, (char *)pv + cb - off, off);
+ if (RT_FAILURE(rc))
+ AssertRCReturn (rc, rc);
+ }
+ //Assert(((offReg - s_ichIntelHDRegMap[idxReg].offset) == 0));
+#endif
mask <<= shift;
- rc = s_ichIntelHDRegMap[index].pfnRead(&pThis->hda, u32Offset, index, &v);
- *(uint32_t *)pv = (v & mask) >> shift;
- Log(("hda: read %s[%x/%x]\n", s_ichIntelHDRegMap[index].abbrev, v, *(uint32_t *)pv));
+ rc = s_ichIntelHDRegMap[idxReg].pfnRead(&pThis->hda, offReg, idxReg, &u32Value);
+ *(uint32_t *)pv |= (u32Value & mask);
+ Log(("hda: read %s[%x/%x]\n", s_ichIntelHDRegMap[idxReg].abbrev, u32Value, *(uint32_t *)pv));
return rc;
}
*(uint32_t *)pv = 0xFF;
- Log(("hda: hole at %X is accessed for read\n", u32Offset));
+ Log(("hda: hole at %x is accessed for read\n", offReg));
return rc;
}
@@ -1854,39 +1938,81 @@ PDMBOTHCBDECL(int) hdaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhys
* @param cb Number of bytes to write.
* @thread EMT
*/
-PDMBOTHCBDECL(int) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+PDMBOTHCBDECL(int) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
- int rc = VINF_SUCCESS;
- PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
- uint32_t u32Offset = GCPhysAddr - pThis->hda.addrMMReg;
- int index = hdaLookup(&pThis->hda, u32Offset);
+ PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
+ uint32_t offReg = GCPhysAddr - pThis->hda.addrMMReg;
+ int idxReg = hdaMMIORegLookup(&pThis->hda, offReg);
+ int rc = VINF_SUCCESS;
- if (pThis->hda.fInReset && index != ICH6_HDA_REG_GCTL)
+ if (pThis->hda.fInReset && idxReg != ICH6_HDA_REG_GCTL)
Log(("hda: access to registers except GCTL is blocked while reset\n"));
- if ( index == -1
- || cb > 4)
- LogRel(("hda: Invalid write access @0x%x(of bytes:%d)\n", u32Offset, cb));
+ if ( idxReg == -1
+ || cb > 4)
+ LogRel(("hda: Invalid write access @0x%x(of bytes:%d)\n", offReg, cb));
- if (index != -1)
+ if (idxReg != -1)
{
- uint32_t v = pThis->hda.au32Regs[index];
- uint32_t mask = 0;
- uint32_t shift = (u32Offset - s_ichIntelHDRegMap[index].offset) % sizeof(uint32_t) * 8;
- switch(cb)
+ /** @todo r=bird: This looks like code for handling unalinged register
+ * accesses. If it isn't then, add a comment explaing what you're
+ * trying to do here. OTOH, if it is then it has the following
+ * issues:
+ * -# You're calculating the wrong new value for the register.
+ * -# You're not handling cross register accesses. Imagine a
+ * 4-byte write starting at CORBCTL, or a 8-byte write.
+ *
+ * PS! consider dropping the 'offset' argument to pfnWrite/pfnRead as
+ * nobody seems to be using it and it just add complexity when reading
+ * the code.
+ *
+ */
+ uint32_t u32CurValue = pThis->hda.au32Regs[idxReg];
+ uint32_t u32NewValue;
+ uint32_t mask;
+ switch (cb)
+ {
+ case 1:
+ u32NewValue = *(uint8_t const *)pv;
+ mask = 0xff;
+ break;
+ case 2:
+ u32NewValue = *(uint16_t const *)pv;
+ mask = 0xffff;
+ break;
+ case 4:
+ case 8:
+ /* 18.2 of ICH6 datasheet defines wideness of the accesses byte, word and double word */
+ u32NewValue = *(uint32_t const *)pv;
+ mask = 0xffffffff;
+ cb = 4;
+ break;
+ default:
+ AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* shall not happen. */
+ }
+ /* cross register access, see corresponding comment in hdaMMIORead */
+#if 0
+ if (cb > s_ichIntelHDRegMap[idxReg].size - (offReg - s_ichIntelHDRegMap[idxReg].offset))
{
- case 1: mask = 0xffffff00; break;
- case 2: mask = 0xffff0000; break;
- case 3: mask = 0xff000000; break;
- case 4: mask = 0x00000000; break;
+ int off = cb - (s_ichIntelHDRegMap[idxReg].size - (offReg - s_ichIntelHDRegMap[idxReg].offset));
+ rc = hdaMMIOWrite(pDevIns, pvUser, GCPhysAddr + cb - off, (char *)pv + cb - off, off);
+ if (RT_FAILURE(rc))
+ AssertRCReturn (rc, rc);
}
+#endif
+ uint32_t shift = (s_ichIntelHDRegMap[idxReg].offset - offReg) % sizeof(uint32_t) * 8;
mask <<= shift;
- *(uint32_t *)pv = ((v & mask) | (*(uint32_t *)pv & ~mask)) >> shift;
- rc = s_ichIntelHDRegMap[index].pfnWrite(&pThis->hda, u32Offset, index, *(uint32_t *)pv);
- Log(("hda: write %s:(%x) %x => %x\n", s_ichIntelHDRegMap[index].abbrev, *(uint32_t *)pv, v, pThis->hda.au32Regs[index]));
+ u32NewValue <<= shift;
+ u32NewValue &= mask;
+ u32NewValue |= (u32CurValue & ~mask);
+
+ rc = s_ichIntelHDRegMap[idxReg].pfnWrite(&pThis->hda, offReg, idxReg, u32NewValue);
+ Log(("hda: write %s:(%x) %x => %x\n", s_ichIntelHDRegMap[idxReg].abbrev, u32NewValue,
+ u32CurValue, pThis->hda.au32Regs[idxReg]));
return rc;
}
- Log(("hda: hole at %X is accessed for write\n", u32Offset));
+
+ Log(("hda: hole at %x is accessed for write\n", offReg));
return rc;
}
@@ -1939,9 +2065,9 @@ static DECLCALLBACK(int) hdaSaveExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
/* Save MMIO registers */
SSMR3PutMem (pSSMHandle, pThis->hda.au32Regs, sizeof (pThis->hda.au32Regs));
/* Save HDA dma counters */
- SSMR3PutMem (pSSMHandle, &pThis->hda.stOutBdle, sizeof (HDABDLEDESC));
- SSMR3PutMem (pSSMHandle, &pThis->hda.stMicBdle, sizeof (HDABDLEDESC));
- SSMR3PutMem (pSSMHandle, &pThis->hda.stInBdle, sizeof (HDABDLEDESC));
+ SSMR3PutStruct (pSSMHandle, &pThis->hda.stOutBdle, g_aHdaBDLEDescFields);
+ SSMR3PutStruct (pSSMHandle, &pThis->hda.stMicBdle, g_aHdaBDLEDescFields);
+ SSMR3PutStruct (pSSMHandle, &pThis->hda.stInBdle, g_aHdaBDLEDescFields);
return VINF_SUCCESS;
}
@@ -1959,16 +2085,26 @@ static DECLCALLBACK(int) hdaLoadExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle,
{
PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
/* Load Codec nodes states */
- AssertMsgReturn (uVersion == HDA_SSM_VERSION, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
Assert (uPass == SSM_PASS_FINAL); NOREF(uPass);
- codecLoadState(&pThis->hda.Codec, pSSMHandle);
+ codecLoadState(&pThis->hda.Codec, pSSMHandle, uVersion);
/* Load MMIO registers */
SSMR3GetMem (pSSMHandle, pThis->hda.au32Regs, sizeof (pThis->hda.au32Regs));
/* Load HDA dma counters */
- SSMR3GetMem (pSSMHandle, &pThis->hda.stOutBdle, sizeof (HDABDLEDESC));
- SSMR3GetMem (pSSMHandle, &pThis->hda.stMicBdle, sizeof (HDABDLEDESC));
- SSMR3GetMem (pSSMHandle, &pThis->hda.stInBdle, sizeof (HDABDLEDESC));
+ if ( uVersion == HDA_SSM_VERSION_1
+ || uVersion == HDA_SSM_VERSION_2)
+ {
+ SSMR3GetMem (pSSMHandle, &pThis->hda.stOutBdle, sizeof (HDABDLEDESC));
+ SSMR3GetMem (pSSMHandle, &pThis->hda.stMicBdle, sizeof (HDABDLEDESC));
+ SSMR3GetMem (pSSMHandle, &pThis->hda.stInBdle, sizeof (HDABDLEDESC));
+ }
+ else
+ {
+ SSMR3GetStruct (pSSMHandle, &pThis->hda.stOutBdle, g_aHdaBDLEDescFields);
+ SSMR3GetStruct (pSSMHandle, &pThis->hda.stMicBdle, g_aHdaBDLEDescFields);
+ SSMR3GetStruct (pSSMHandle, &pThis->hda.stInBdle, g_aHdaBDLEDescFields);
+ }
+
AUD_set_active_in(pThis->hda.Codec.SwVoiceIn, SDCTL(&pThis->hda, 0) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
AUD_set_active_out(pThis->hda.Codec.SwVoiceOut, SDCTL(&pThis->hda, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
@@ -2060,7 +2196,214 @@ static DECLCALLBACK(void *) hdaQueryInterface (struct PDMIBASE *pInterface,
return NULL;
}
+static inline int hdaLookUpRegisterByName(INTELHDLinkState *pState, const char *pszArgs)
+{
+ int iReg = 0;
+ for (; iReg < HDA_NREGS; ++iReg)
+ if (!RTStrICmp(s_ichIntelHDRegMap[iReg].abbrev, pszArgs))
+ return iReg;
+ return -1;
+}
+static inline void hdaDbgPrintRegister(INTELHDLinkState *pState, PCDBGFINFOHLP pHlp, int iHdaIndex)
+{
+ Assert( pState
+ && iHdaIndex >= 0
+ && iHdaIndex < HDA_NREGS);
+ pHlp->pfnPrintf(pHlp, "hda: %s: 0x%x\n", s_ichIntelHDRegMap[iHdaIndex].abbrev, pState->au32Regs[iHdaIndex]);
+}
+static DECLCALLBACK(void) hdaDbgInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+ PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
+ INTELHDLinkState *hda = &pThis->hda;
+ int iHdaRegisterIndex = hdaLookUpRegisterByName(hda, pszArgs);
+ if (iHdaRegisterIndex != -1)
+ hdaDbgPrintRegister(hda, pHlp, iHdaRegisterIndex);
+ else
+ for(iHdaRegisterIndex = 0; (unsigned int)iHdaRegisterIndex < HDA_NREGS; ++iHdaRegisterIndex)
+ hdaDbgPrintRegister(hda, pHlp, iHdaRegisterIndex);
+}
+
+static inline void hdaDbgPrintStream(INTELHDLinkState *pState, PCDBGFINFOHLP pHlp, int iHdaStrmIndex)
+{
+ Assert( pState
+ && iHdaStrmIndex >= 0
+ && iHdaStrmIndex < 7);
+ pHlp->pfnPrintf(pHlp, "Dump of %d Hda Stream:\n", iHdaStrmIndex);
+ pHlp->pfnPrintf(pHlp, "SD%dCTL: %R[sdctl]\n", iHdaStrmIndex, HDA_STREAM_REG2(pState, CTL, iHdaStrmIndex));
+ pHlp->pfnPrintf(pHlp, "SD%dCTS: %R[sdsts]\n", iHdaStrmIndex, HDA_STREAM_REG2(pState, STS, iHdaStrmIndex));
+ pHlp->pfnPrintf(pHlp, "SD%dFIFOS: %R[sdfifos]\n", iHdaStrmIndex, HDA_STREAM_REG2(pState, FIFOS, iHdaStrmIndex));
+ pHlp->pfnPrintf(pHlp, "SD%dFIFOW: %R[sdfifow]\n", iHdaStrmIndex, HDA_STREAM_REG2(pState, FIFOW, iHdaStrmIndex));
+}
+
+static inline int hdaLookUpStreamIndex(INTELHDLinkState *pState, const char *pszArgs)
+{
+ /* todo: add args parsing */
+ return -1;
+}
+static DECLCALLBACK(void) hdaDbgStreamInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+ PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
+ INTELHDLinkState *hda = &pThis->hda;
+ int iHdaStrmIndex = hdaLookUpStreamIndex(hda, pszArgs);
+ if (iHdaStrmIndex != -1)
+ hdaDbgPrintStream(hda, pHlp, iHdaStrmIndex);
+ else
+ for(iHdaStrmIndex = 0; iHdaStrmIndex < 7; ++iHdaStrmIndex)
+ hdaDbgPrintStream(hda, pHlp, iHdaStrmIndex);
+}
+
+/* Codec debugger interface */
+static DECLCALLBACK(void) hdaCodecDbgNodes(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+ PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
+ INTELHDLinkState *hda = &pThis->hda;
+ if (hda->Codec.pfnCodecDbgListNodes)
+ hda->Codec.pfnCodecDbgListNodes(&hda->Codec, pHlp, pszArgs);
+ else
+ pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n");
+}
+
+static DECLCALLBACK(void) hdaCodecDbgSelector(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+ PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
+ INTELHDLinkState *hda = &pThis->hda;
+ if (hda->Codec.pfnCodecDbgSelector)
+ hda->Codec.pfnCodecDbgSelector(&hda->Codec, pHlp, pszArgs);
+ else
+ pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n");
+}
+
//#define HDA_AS_PCI_EXPRESS
+/* Misc routines */
+static inline bool printHdaIsValid(const char *pszType, const char *pszExpectedFlag)
+{
+ return (RTStrCmp(pszType, pszExpectedFlag) == 0);
+}
+static const char *printHdaYesNo(bool fFlag)
+{
+ return fFlag ? "yes" : "no";
+}
+static DECLCALLBACK(size_t)
+printHdaStrmCtl(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+ const char *pszType, void const *pvValue,
+ int cchWidth, int cchPrecision, unsigned fFlags,
+ void *pvUser)
+{
+ uint32_t sdCtl = (uint32_t)(uintptr_t)pvValue;
+ size_t cb = 0;
+ if (!printHdaIsValid(pszType, "sdctl"))
+ return cb;
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+ "SDCTL(raw: %#0x, strm:0x%x, dir:%s, tp:%s strip:%x, deie:%s, ioce:%s, run:%s, srst:%s)",
+ sdCtl,
+ ((sdCtl & HDA_REG_FIELD_MASK(SDCTL, NUM)) >> ICH6_HDA_SDCTL_NUM_SHIFT),
+ printHdaYesNo(RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, DIR))),
+ printHdaYesNo(RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, TP))),
+ ((sdCtl & HDA_REG_FIELD_MASK(SDCTL, STRIPE)) >> ICH6_HDA_SDCTL_STRIPE_SHIFT),
+ printHdaYesNo(RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, DEIE))),
+ printHdaYesNo(RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE))),
+ printHdaYesNo(RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN))),
+ printHdaYesNo(RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST))));
+ return cb;
+}
+
+static DECLCALLBACK(size_t)
+printHdaStrmFifos(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+ const char *pszType, void const *pvValue,
+ int cchWidth, int cchPrecision, unsigned fFlags,
+ void *pvUser)
+{
+ uint32_t sdFifos = (uint32_t)(uintptr_t)pvValue;
+ uint32_t u32Bytes = 0;
+ size_t cb = 0;
+ if (!printHdaIsValid(pszType, "sdfifos"))
+ return cb;
+ switch(sdFifos)
+ {
+ case HDA_SDONFIFO_16B: u32Bytes = 16; break;
+ case HDA_SDONFIFO_32B: u32Bytes = 32; break;
+ case HDA_SDONFIFO_64B: u32Bytes = 64; break;
+ case HDA_SDONFIFO_128B: u32Bytes = 128; break;
+ case HDA_SDONFIFO_192B: u32Bytes = 192; break;
+ case HDA_SDONFIFO_256B: u32Bytes = 256; break;
+ case HDA_SDINFIFO_120B: u32Bytes = 120; break;
+ case HDA_SDINFIFO_160B: u32Bytes = 160; break;
+ default:;
+ }
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+ "SDFIFOS(raw: %#0x, sdfifos:%d B)",
+ sdFifos,
+ u32Bytes);
+ return cb;
+}
+
+static DECLCALLBACK(size_t)
+printHdaStrmFifow(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+ const char *pszType, void const *pvValue,
+ int cchWidth, int cchPrecision, unsigned fFlags,
+ void *pvUser)
+{
+ uint32_t sdFifow = (uint32_t)(uintptr_t)pvValue;
+ uint32_t u32Bytes = 0;
+ size_t cb = 0;
+ if (!printHdaIsValid(pszType, "sdfifow"))
+ return cb;
+ switch(sdFifow)
+ {
+ case HDA_SDFIFOW_8B: u32Bytes = 8; break;
+ case HDA_SDFIFOW_16B: u32Bytes = 16; break;
+ case HDA_SDFIFOW_32B: u32Bytes = 32; break;
+ }
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+ "SDFIFOW(raw: %#0x, sdfifow:%d B)",
+ sdFifow,
+ u32Bytes);
+ return cb;
+}
+
+static DECLCALLBACK(size_t)
+printHdaStrmSts(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+ const char *pszType, void const *pvValue,
+ int cchWidth, int cchPrecision, unsigned fFlags,
+ void *pvUser)
+{
+ uint32_t sdSts = (uint32_t)(uintptr_t)pvValue;
+ size_t cb = 0;
+ if (!printHdaIsValid(pszType, "sdsts"))
+ return cb;
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+ "SDSTS(raw: %#0x, fifordy:%s, dese:%s, fifoe:%s, bcis:%s)",
+ sdSts,
+ printHdaYesNo(RT_BOOL(sdSts & HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY))),
+ printHdaYesNo(RT_BOOL(sdSts & HDA_REG_FIELD_FLAG_MASK(SDSTS, DE))),
+ printHdaYesNo(RT_BOOL(sdSts & HDA_REG_FIELD_FLAG_MASK(SDSTS, FE))),
+ printHdaYesNo(RT_BOOL(sdSts & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS))));
+ return cb;
+}
+/**
+ * This routine registers debugger info extensions and custom printf formatters
+ */
+static inline int hdaInitMisc(PPDMDEVINS pDevIns)
+{
+ int rc;
+ PDMDevHlpDBGFInfoRegister(pDevIns, "hda", "HDA info. (hda [register case-insensitive])", hdaDbgInfo);
+ PDMDevHlpDBGFInfoRegister(pDevIns, "hdastrm", "HDA stream info. (hdastrm [stream number])", hdaDbgStreamInfo);
+ PDMDevHlpDBGFInfoRegister(pDevIns, "hdcnodes", "HDA codec nodes.", hdaCodecDbgNodes);
+ PDMDevHlpDBGFInfoRegister(pDevIns, "hdcselector", "HDA codec's selector states [node number].", hdaCodecDbgSelector);
+ rc = RTStrFormatTypeRegister("sdctl", printHdaStrmCtl, NULL);
+ AssertRC(rc);
+ rc = RTStrFormatTypeRegister("sdsts", printHdaStrmSts, NULL);
+ AssertRC(rc);
+ rc = RTStrFormatTypeRegister("sdfifos", printHdaStrmFifos, NULL);
+ AssertRC(rc);
+ rc = RTStrFormatTypeRegister("sdfifow", printHdaStrmFifow, NULL);
+ AssertRC(rc);
+#if 0
+ rc = RTStrFormatTypeRegister("sdfmt", printHdaStrmFmt, NULL);
+ AssertRC(rc);
+#endif
+ return rc;
+}
/**
* @interface_method_impl{PDMDEVREG,pfnConstruct}
@@ -2116,7 +2459,7 @@ static DECLCALLBACK(int) hdaConstruct (PPDMDEVINS pDevIns, int iInstance,
PCIDevSetCapabilityList (&pThis->dev, 0x50); /* ICH6 datasheet 18.1.16 */
#endif
- //** @todo r=michaln: If there are really no PCIDevSetXx for these, the meaning
+ /// @todo r=michaln: If there are really no PCIDevSetXx for these, the meaning
// of these values needs to be properly documented!
/* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */
PCIDevSetByte(&pThis->dev, 0x40, 0x01);
@@ -2217,7 +2560,7 @@ static DECLCALLBACK(int) hdaConstruct (PPDMDEVINS pDevIns, int iInstance,
pThis->hda.Codec.pHDAState = (void *)&pThis->hda;
- rc = codecConstruct(pDevIns, &pThis->hda.Codec, /* ALC885_CODEC */ STAC9220_CODEC);
+ rc = codecConstruct(pDevIns, &pThis->hda.Codec, pCfgHandle);
if (RT_FAILURE(rc))
AssertRCReturn(rc, rc);
@@ -2238,6 +2581,7 @@ static DECLCALLBACK(int) hdaConstruct (PPDMDEVINS pDevIns, int iInstance,
*/
WAKEEN(&pThis->hda) = 0x0;
STATESTS(&pThis->hda) = 0x0;
+ hdaInitMisc(pDevIns);
return VINF_SUCCESS;
}
diff --git a/src/VBox/Devices/Audio/DevSB16.cpp b/src/VBox/Devices/Audio/DevSB16.cpp
index 393df6c49..7686ddb76 100644
--- a/src/VBox/Devices/Audio/DevSB16.cpp
+++ b/src/VBox/Devices/Audio/DevSB16.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevSB16.cpp $ */
+/* $Id: DevSB16.cpp 35487 2011-01-11 13:45:20Z vboxsync $ */
/** @file
* DevSB16 - VBox SB16 Audio Controller.
*
diff --git a/src/VBox/Devices/Audio/alsa_stubs.c b/src/VBox/Devices/Audio/alsa_stubs.c
index 4428d8905..442ddc519 100644
--- a/src/VBox/Devices/Audio/alsa_stubs.c
+++ b/src/VBox/Devices/Audio/alsa_stubs.c
@@ -1,4 +1,4 @@
-/* $Id: alsa_stubs.c $ */
+/* $Id: alsa_stubs.c 34451 2010-11-29 11:00:53Z vboxsync $ */
/** @file
* Stubs for libasound.
*/
diff --git a/src/VBox/Devices/Audio/audiosniffer.c b/src/VBox/Devices/Audio/audiosniffer.c
index 7cff38cda..72003d328 100644
--- a/src/VBox/Devices/Audio/audiosniffer.c
+++ b/src/VBox/Devices/Audio/audiosniffer.c
@@ -1,4 +1,4 @@
-/* $Id: audiosniffer.c $ */
+/* $Id: audiosniffer.c 35402 2011-01-04 14:59:31Z vboxsync $ */
/** @file
* VBox audio device: Audio sniffer device
*/
diff --git a/src/VBox/Devices/Audio/coreaudio.c b/src/VBox/Devices/Audio/coreaudio.c
index a9dbee6fd..e7606eacc 100644
--- a/src/VBox/Devices/Audio/coreaudio.c
+++ b/src/VBox/Devices/Audio/coreaudio.c
@@ -1,4 +1,4 @@
-/* $Id: coreaudio.c $ */
+/* $Id: coreaudio.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBox audio devices: Mac OS X CoreAudio audio driver
*/
diff --git a/src/VBox/Devices/Audio/filteraudio.c b/src/VBox/Devices/Audio/filteraudio.c
index 4a3bf9782..3f1319de0 100644
--- a/src/VBox/Devices/Audio/filteraudio.c
+++ b/src/VBox/Devices/Audio/filteraudio.c
@@ -1,4 +1,4 @@
-/* $Id: filteraudio.c $ */
+/* $Id: filteraudio.c 36327 2011-03-21 15:49:12Z vboxsync $ */
/** @file
* VBox audio devices: filter driver, which sits between the host audio driver
* and the virtual audio device and intercept all host driver operations.
diff --git a/src/VBox/Devices/Audio/pulse_stubs.c b/src/VBox/Devices/Audio/pulse_stubs.c
index 4fdb2bdcc..bbd757bad 100644
--- a/src/VBox/Devices/Audio/pulse_stubs.c
+++ b/src/VBox/Devices/Audio/pulse_stubs.c
@@ -1,4 +1,4 @@
-/* $Id: pulse_stubs.c $ */
+/* $Id: pulse_stubs.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Stubs for libpulse.
*/
diff --git a/src/VBox/Devices/Audio/solaudio.c b/src/VBox/Devices/Audio/solaudio.c
index 26c84734d..dc4c0900e 100644
--- a/src/VBox/Devices/Audio/solaudio.c
+++ b/src/VBox/Devices/Audio/solaudio.c
@@ -1,4 +1,4 @@
-/* $Id: solaudio.c $ */
+/* $Id: solaudio.c 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* VirtualBox Audio Driver - Solaris host.
*/
diff --git a/src/VBox/Devices/Bus/DevPCI.cpp b/src/VBox/Devices/Bus/DevPCI.cpp
index e6d7a2c3e..e9caba053 100644
--- a/src/VBox/Devices/Bus/DevPCI.cpp
+++ b/src/VBox/Devices/Bus/DevPCI.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevPCI.cpp $ */
+/* $Id: DevPCI.cpp 36079 2011-02-24 17:10:31Z vboxsync $ */
/** @file
* DevPCI - PCI BUS Device.
*/
@@ -772,7 +772,7 @@ DECLINLINE(PPCIDEVICE) pciFindBridge(PPCIBUS pBus, uint8_t iBus)
* If the target bus is in the range we pass the request on to the bridge.
*/
PPCIDEVICE pBridgeTemp = pBus->papBridgesR3[iBridge];
- AssertMsg(pBridgeTemp && PCIIsPci2PciBridge(pBridgeTemp),
+ AssertMsg(pBridgeTemp && pciDevIsPci2PciBridge(pBridgeTemp),
("Device is not a PCI bridge but on the list of PCI bridges\n"));
if ( iBus >= pBridgeTemp->config[VBOX_PCI_SECONDARY_BUS]
@@ -1720,7 +1720,7 @@ static int pciRegisterInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const
return VERR_PDM_TOO_PCI_MANY_DEVICES;
}
}
- PCIClearRequestedDevfunc(pPciDev);
+ pciDevClearRequestedDevfunc(pPciDev);
}
else
{
@@ -1741,14 +1741,14 @@ static int pciRegisterInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const
int iDevRel;
AssertReleaseMsg(!(iDev % 8), ("PCI Configuration Conflict! iDev=%d pszName=%s clashes with %s\n",
iDev, pszName, pBus->devices[iDev]->name));
- if ( PCIIsRequestedDevfunc(pBus->devices[iDev])
- || (pBus->devices[iDev + 1] && PCIIsRequestedDevfunc(pBus->devices[iDev + 1]))
- || (pBus->devices[iDev + 2] && PCIIsRequestedDevfunc(pBus->devices[iDev + 2]))
- || (pBus->devices[iDev + 3] && PCIIsRequestedDevfunc(pBus->devices[iDev + 3]))
- || (pBus->devices[iDev + 4] && PCIIsRequestedDevfunc(pBus->devices[iDev + 4]))
- || (pBus->devices[iDev + 5] && PCIIsRequestedDevfunc(pBus->devices[iDev + 5]))
- || (pBus->devices[iDev + 6] && PCIIsRequestedDevfunc(pBus->devices[iDev + 6]))
- || (pBus->devices[iDev + 7] && PCIIsRequestedDevfunc(pBus->devices[iDev + 7])))
+ if ( pciDevIsRequestedDevfunc(pBus->devices[iDev])
+ || (pBus->devices[iDev + 1] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 1]))
+ || (pBus->devices[iDev + 2] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 2]))
+ || (pBus->devices[iDev + 3] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 3]))
+ || (pBus->devices[iDev + 4] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 4]))
+ || (pBus->devices[iDev + 5] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 5]))
+ || (pBus->devices[iDev + 6] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 6]))
+ || (pBus->devices[iDev + 7] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 7])))
{
AssertReleaseMsgFailed(("Configuration error:'%s' and '%s' are both configured as device %d\n",
pszName, pBus->devices[iDev]->name, iDev));
@@ -1785,7 +1785,7 @@ static int pciRegisterInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const
return VERR_PDM_TOO_PCI_MANY_DEVICES;
}
} /* if conflict */
- PCISetRequestedDevfunc(pPciDev);
+ pciDevSetRequestedDevfunc(pPciDev);
}
Assert(!pBus->devices[iDev]);
@@ -1797,7 +1797,7 @@ static int pciRegisterInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const
pPciDev->Int.s.pfnConfigRead = pci_default_read_config;
pPciDev->Int.s.pfnConfigWrite = pci_default_write_config;
pBus->devices[iDev] = pPciDev;
- if (PCIIsPci2PciBridge(pPciDev))
+ if (pciDevIsPci2PciBridge(pPciDev))
{
AssertMsg(pBus->cBridges < RT_ELEMENTS(pBus->devices), ("Number of bridges exceeds the number of possible devices on the bus\n"));
AssertMsg(pPciDev->Int.s.pfnBridgeConfigRead && pPciDev->Int.s.pfnBridgeConfigWrite,
@@ -2023,8 +2023,8 @@ static DECLCALLBACK(void) pciReset(PPDMDEVINS pDevIns)
*/
static DECLCALLBACK(int) pciConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
{
- int rc;
Assert(iInstance == 0);
+ PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
/*
* Validate and read configuration.
@@ -2034,7 +2034,7 @@ static DECLCALLBACK(int) pciConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGM
/* query whether we got an IOAPIC */
bool fUseIoApic;
- rc = CFGMR3QueryBoolDef(pCfg, "IOAPIC", &fUseIoApic, false);
+ int rc = CFGMR3QueryBoolDef(pCfg, "IOAPIC", &fUseIoApic, false);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to query boolean value \"IOAPIC\""));
@@ -2110,7 +2110,7 @@ static DECLCALLBACK(int) pciConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGM
PCIDevSetHeaderType(&pBus->PciDev, 0x00);
pBus->PciDev.pDevIns = pDevIns;
- PCISetRequestedDevfunc(&pBus->PciDev);
+ pciDevSetRequestedDevfunc(&pBus->PciDev);
pciRegisterInternal(pBus, 0, &pBus->PciDev, "i440FX");
/* PIIX3 */
@@ -2121,7 +2121,7 @@ static DECLCALLBACK(int) pciConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGM
PCIDevSetHeaderType(&pGlobals->PIIX3State.dev, 0x80); /* PCI_multifunction, generic */
pGlobals->PIIX3State.dev.pDevIns = pDevIns;
- PCISetRequestedDevfunc(&pGlobals->PIIX3State.dev);
+ pciDevSetRequestedDevfunc(&pGlobals->PIIX3State.dev);
pciRegisterInternal(pBus, 8, &pGlobals->PIIX3State.dev, "PIIX3");
piix3_reset(&pGlobals->PIIX3State);
@@ -2416,7 +2416,7 @@ static DECLCALLBACK(void) pcibridgeRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDe
*/
static DECLCALLBACK(int) pcibridgeConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
{
- int rc;
+ PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
/*
* Validate and read configuration.
@@ -2426,7 +2426,7 @@ static DECLCALLBACK(int) pcibridgeConstruct(PPDMDEVINS pDevIns, int iInstance,
/* check if RC code is enabled. */
bool fGCEnabled;
- rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fGCEnabled, true);
+ int rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fGCEnabled, true);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to query boolean value \"GCEnabled\""));
@@ -2495,7 +2495,7 @@ static DECLCALLBACK(int) pcibridgeConstruct(PPDMDEVINS pDevIns, int iInstance,
pBus->PciDev.pDevIns = pDevIns;
/* Bridge-specific data */
- PCISetPci2PciBridge(&pBus->PciDev);
+ pciDevSetPci2PciBridge(&pBus->PciDev);
pBus->PciDev.Int.s.pfnBridgeConfigRead = pcibridgeConfigRead;
pBus->PciDev.Int.s.pfnBridgeConfigWrite = pcibridgeConfigWrite;
diff --git a/src/VBox/Devices/Bus/DevPciIch9.cpp b/src/VBox/Devices/Bus/DevPciIch9.cpp
index d01a92583..a0f2fea6a 100644
--- a/src/VBox/Devices/Bus/DevPciIch9.cpp
+++ b/src/VBox/Devices/Bus/DevPciIch9.cpp
@@ -1,10 +1,10 @@
-/* $Id: DevPciIch9.cpp $ */
+/* $Id: DevPciIch9.cpp 37636 2011-06-24 14:59:59Z vboxsync $ */
/** @file
- * DevPCI - ICH9 southbridge PCI bus emulation Device.
+ * DevPCI - ICH9 southbridge PCI bus emulation device.
*/
/*
- * 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;
@@ -16,11 +16,12 @@
*/
/*******************************************************************************
- * Header Files *
- *******************************************************************************/
+* Header Files *
+*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DEV_PCI
/* Hack to get PCIDEVICEINT declare at the right point - include "PCIInternal.h". */
#define PCI_INCLUDE_PRIVATE
+#define PCIBus ICH9PCIBus
#include <VBox/pci.h>
#include <VBox/msi.h>
#include <VBox/vmm/pdmdev.h>
@@ -35,10 +36,14 @@
#include "MsiCommon.h"
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
/**
* PCI Bus instance.
*/
-typedef struct PCIBus
+typedef struct ICH9PCIBus
{
/** Bus number. */
int32_t iBus;
@@ -68,7 +73,7 @@ typedef struct PCIBus
/** The PCI device for the PCI bridge. */
PCIDEVICE aPciDev;
-} PCIBUS, *PPCIBUS;
+} ICH9PCIBUS, *PICH9PCIBUS;
/** @def PCI_APIC_IRQ_PINS
@@ -92,9 +97,8 @@ typedef struct
uint32_t Alignment0;
#endif
- /** PCI bus which is attached to the host-to-PCI bridge. */
- PCIBUS aPciBus;
-
+ /** Config register. */
+ uint32_t uConfigReg;
/** I/O APIC irq levels */
volatile uint32_t uaPciApicIrqLevels[PCI_APIC_IRQ_PINS];
@@ -112,21 +116,23 @@ typedef struct
/* Length of PCI config space MMIO region */
uint64_t u64PciConfigMMioLength;
-
- /** Config register. */
- uint32_t uConfigReg;
-} PCIGLOBALS, *PPCIGLOBALS;
+ /** PCI bus which is attached to the host-to-PCI bridge. */
+ ICH9PCIBUS aPciBus;
+} ICH9PCIGLOBALS, *PICH9PCIGLOBALS;
-typedef struct {
+typedef struct
+{
uint8_t iBus;
uint8_t iDeviceFunc;
uint16_t iRegister;
} PciAddress;
+#ifndef VBOX_DEVICE_STRUCT_TESTCASE
+
/*******************************************************************************
- * Defined Constants And Macros *
- *******************************************************************************/
+* Defined Constants And Macros *
+*******************************************************************************/
/** @def VBOX_ICH9PCI_SAVED_STATE_VERSION
* Saved state version of the ICH9 PCI bus device.
@@ -137,14 +143,12 @@ typedef struct {
/** Converts a bus instance pointer to a device instance pointer. */
#define PCIBUS_2_DEVINS(pPciBus) ((pPciBus)->CTX_SUFF(pDevIns))
-/** Converts a device instance pointer to a PCIGLOBALS pointer. */
-#define DEVINS_2_PCIGLOBALS(pDevIns) ((PPCIGLOBALS)(PDMINS_2_DATA(pDevIns, PPCIGLOBALS)))
+/** Converts a device instance pointer to a ICH9PCIGLOBALS pointer. */
+#define DEVINS_2_PCIGLOBALS(pDevIns) ((PICH9PCIGLOBALS)(PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS)))
/** Converts a device instance pointer to a PCIBUS pointer. */
-#define DEVINS_2_PCIBUS(pDevIns) ((PPCIBUS)(&PDMINS_2_DATA(pDevIns, PPCIGLOBALS)->aPciBus))
-/** Converts a pointer to a PCI root bus instance to a PCIGLOBALS pointer.
- */
-#define PCIROOTBUS_2_PCIGLOBALS(pPciBus) ( (PPCIGLOBALS)((uintptr_t)(pPciBus) - RT_OFFSETOF(PCIGLOBALS, aPciBus)) )
-
+#define DEVINS_2_PCIBUS(pDevIns) ((PICH9PCIBUS)(&PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS)->aPciBus))
+/** Converts a pointer to a PCI root bus instance to a PCIGLOBALS pointer. */
+#define PCIROOTBUS_2_PCIGLOBALS(pPciBus) ( (PICH9PCIGLOBALS)((uintptr_t)(pPciBus) - RT_OFFSETOF(ICH9PCIGLOBALS, aPciBus)) )
/** @def PCI_LOCK
* Acquires the PDM lock. This is a NOP if locking is disabled. */
@@ -159,42 +163,27 @@ typedef struct {
#define PCI_UNLOCK(pDevIns) \
DEVINS_2_PCIBUS(pDevIns)->CTX_SUFF(pPciHlp)->pfnUnlock(pDevIns)
-#ifndef VBOX_DEVICE_STRUCT_TESTCASE
-
-RT_C_DECLS_BEGIN
-
-PDMBOTHCBDECL(void) ich9pciSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel);
-PDMBOTHCBDECL(void) ich9pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel);
-PDMBOTHCBDECL(int) ich9pciIOPortAddressWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) ich9pciIOPortAddressRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) ich9pciIOPortDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) ich9pciIOPortDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) ich9pciMcfgMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) ich9pciMcfgMMIORead (PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-
-RT_C_DECLS_END
-
/* Prototypes */
-static void ich9pciSetIrqInternal(PPCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev, int iIrq, int iLevel);
+static void ich9pciSetIrqInternal(PICH9PCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev, int iIrq, int iLevel);
#ifdef IN_RING3
static void ich9pcibridgeReset(PPDMDEVINS pDevIns);
-static int ich9pciRegisterInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const char *pszName);
+static int ich9pciRegisterInternal(PICH9PCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const char *pszName);
static void ich9pciUpdateMappings(PCIDevice *pDev);
static DECLCALLBACK(uint32_t) ich9pciConfigReadDev(PCIDevice *aDev, uint32_t u32Address, unsigned len);
-DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PPCIBUS pBus, uint8_t iBus);
-static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint8_t cBridgeDepth, uint8_t *paBridgePositions);
+DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PICH9PCIBUS pBus, uint8_t iBus);
+static void ich9pciBiosInitDevice(PICH9PCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn);
#endif
// See 7.2.2. PCI Express Enhanced Configuration Mechanism for details of address
// mapping, we take n=6 approach
-DECLINLINE(void) ich9pciPhysToPciAddr(PPCIGLOBALS pGlobals, RTGCPHYS GCPhysAddr, PciAddress* pPciAddr)
+DECLINLINE(void) ich9pciPhysToPciAddr(PICH9PCIGLOBALS pGlobals, RTGCPHYS GCPhysAddr, PciAddress* pPciAddr)
{
pPciAddr->iBus = (GCPhysAddr >> 20) & ((1<<6) - 1);
pPciAddr->iDeviceFunc = (GCPhysAddr >> 12) & ((1<<(5+3)) - 1); // 5 bits - device, 3 bits - function
pPciAddr->iRegister = (GCPhysAddr >> 0) & ((1<<(6+4+2)) - 1); // 6 bits - register, 4 bits - extended register, 2 bits -Byte Enable
}
-DECLINLINE(void) ich9pciStateToPciAddr(PPCIGLOBALS pGlobals, RTGCPHYS addr, PciAddress* pPciAddr)
+DECLINLINE(void) ich9pciStateToPciAddr(PICH9PCIGLOBALS pGlobals, RTGCPHYS addr, PciAddress* pPciAddr)
{
pPciAddr->iBus = (pGlobals->uConfigReg >> 16) & 0xff;
pPciAddr->iDeviceFunc = (pGlobals->uConfigReg >> 8) & 0xff;
@@ -203,7 +192,7 @@ DECLINLINE(void) ich9pciStateToPciAddr(PPCIGLOBALS pGlobals, RTGCPHYS addr, PciA
PDMBOTHCBDECL(void) ich9pciSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel)
{
- ich9pciSetIrqInternal(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), pPciDev->devfn, pPciDev, iIrq, iLevel);
+ ich9pciSetIrqInternal(PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS), pPciDev->devfn, pPciDev, iIrq, iLevel);
}
PDMBOTHCBDECL(void) ich9pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel)
@@ -215,10 +204,10 @@ PDMBOTHCBDECL(void) ich9pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev,
* We change iIrq here according to the spec and call the SetIrq function
* of our parent passing the device which asserted the interrupt instead of the device of the bridge.
*/
- PPCIBUS pBus = PDMINS_2_DATA(pDevIns, PPCIBUS);
- PPCIDEVICE pPciDevBus = pPciDev;
- int iIrqPinBridge = iIrq;
- uint8_t uDevFnBridge = 0;
+ PICH9PCIBUS pBus = PDMINS_2_DATA(pDevIns, PICH9PCIBUS);
+ PPCIDEVICE pPciDevBus = pPciDev;
+ int iIrqPinBridge = iIrq;
+ uint8_t uDevFnBridge = 0;
/* Walk the chain until we reach the host bus. */
do
@@ -248,11 +237,11 @@ PDMBOTHCBDECL(void) ich9pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev,
*/
PDMBOTHCBDECL(int) ich9pciIOPortAddressWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- Log(("ich9pciIOPortAddressWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
+ LogFlow(("ich9pciIOPortAddressWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
NOREF(pvUser);
if (cb == 4)
{
- PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
+ PICH9PCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_WRITE);
pThis->uConfigReg = u32 & ~3; /* Bits 0-1 are reserved and we silently clear them */
@@ -278,11 +267,11 @@ PDMBOTHCBDECL(int) ich9pciIOPortAddressRead(PPDMDEVINS pDevIns, void *pvUser, R
NOREF(pvUser);
if (cb == 4)
{
- PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
+ PICH9PCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_READ);
*pu32 = pThis->uConfigReg;
PCI_UNLOCK(pDevIns);
- Log(("pciIOPortAddressRead: Port=%#x cb=%d -> %#x\n", Port, cb, *pu32));
+ LogFlow(("ich9pciIOPortAddressRead: Port=%#x cb=%d -> %#x\n", Port, cb, *pu32));
return VINF_SUCCESS;
}
@@ -291,17 +280,11 @@ PDMBOTHCBDECL(int) ich9pciIOPortAddressRead(PPDMDEVINS pDevIns, void *pvUser, R
return VERR_IOM_IOPORT_UNUSED;
}
-static int ich9pciDataWriteAddr(PPCIGLOBALS pGlobals, PciAddress* pAddr,
+static int ich9pciDataWriteAddr(PICH9PCIGLOBALS pGlobals, PciAddress* pAddr,
uint32_t val, int cb, int rcReschedule)
{
int rc = VINF_SUCCESS;
- if (pAddr->iRegister > 0xff)
- {
- LogRel(("PCI: attempt to write extended register: %x (%d) <- val\n", pAddr->iRegister, cb, val));
- goto out;
- }
-
if (pAddr->iBus != 0)
{
if (pGlobals->aPciBus.cBridges)
@@ -329,7 +312,6 @@ static int ich9pciDataWriteAddr(PPCIGLOBALS pGlobals, PciAddress* pAddr,
{
#ifdef IN_RING3
R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pAddr->iDeviceFunc];
- Log(("ich9pciConfigWrite: %s: addr=%02x val=%08x len=%d\n", aDev->name, pAddr->iRegister, val, cb));
aDev->Int.s.pfnConfigWrite(aDev, pAddr->iRegister, val, cb);
#else
rc = rcReschedule;
@@ -346,7 +328,7 @@ static int ich9pciDataWriteAddr(PPCIGLOBALS pGlobals, PciAddress* pAddr,
return rc;
}
-static int ich9pciDataWrite(PPCIGLOBALS pGlobals, uint32_t addr, uint32_t val, int len)
+static int ich9pciDataWrite(PICH9PCIGLOBALS pGlobals, uint32_t addr, uint32_t val, int len)
{
PciAddress aPciAddr;
@@ -383,13 +365,13 @@ static void ich9pciNoMem(void* ptr, int cb)
*/
PDMBOTHCBDECL(int) ich9pciIOPortDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- Log(("pciIOPortDataWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
+ LogFlow(("ich9pciIOPortDataWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
NOREF(pvUser);
int rc = VINF_SUCCESS;
if (!(Port % cb))
{
PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_WRITE);
- rc = ich9pciDataWrite(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), Port, u32, cb);
+ rc = ich9pciDataWrite(PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS), Port, u32, cb);
PCI_UNLOCK(pDevIns);
}
else
@@ -397,19 +379,11 @@ PDMBOTHCBDECL(int) ich9pciIOPortDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTI
return rc;
}
-static int ich9pciDataReadAddr(PPCIGLOBALS pGlobals, PciAddress* pPciAddr, int cb,
+static int ich9pciDataReadAddr(PICH9PCIGLOBALS pGlobals, PciAddress* pPciAddr, int cb,
uint32_t *pu32, int rcReschedule)
{
int rc = VINF_SUCCESS;
- if (pPciAddr->iRegister > 0xff)
- {
- LogRel(("PCI: attempt to read extended register: %x\n", pPciAddr->iRegister));
- ich9pciNoMem(pu32, cb);
- goto out;
- }
-
-
if (pPciAddr->iBus != 0)
{
if (pGlobals->aPciBus.cBridges)
@@ -437,7 +411,6 @@ static int ich9pciDataReadAddr(PPCIGLOBALS pGlobals, PciAddress* pPciAddr, int c
#ifdef IN_RING3
R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pPciAddr->iDeviceFunc];
*pu32 = aDev->Int.s.pfnConfigRead(aDev, pPciAddr->iRegister, cb);
- Log(("ich9pciDataReadAddr: %s: addr=%02x val=%08x len=%d\n", aDev->name, pPciAddr->iRegister, *pu32, cb));
#else
rc = rcReschedule;
goto out;
@@ -448,14 +421,14 @@ static int ich9pciDataReadAddr(PPCIGLOBALS pGlobals, PciAddress* pPciAddr, int c
}
out:
- Log2(("ich9pciDataReadAddr: %02x:%02x:%02x reg %x(%d) gave %x %Rrc\n",
+ Log3(("ich9pciDataReadAddr: %02x:%02x:%02x reg %x(%d) gave %x %Rrc\n",
pPciAddr->iBus, pPciAddr->iDeviceFunc >> 3, pPciAddr->iDeviceFunc & 0x7, pPciAddr->iRegister,
cb, *pu32, rc));
return rc;
}
-static int ich9pciDataRead(PPCIGLOBALS pGlobals, uint32_t addr, int cb, uint32_t *pu32)
+static int ich9pciDataRead(PICH9PCIGLOBALS pGlobals, uint32_t addr, int cb, uint32_t *pu32)
{
PciAddress aPciAddr;
@@ -492,9 +465,9 @@ PDMBOTHCBDECL(int) ich9pciIOPortDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIO
if (!(Port % cb))
{
PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_READ);
- int rc = ich9pciDataRead(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), Port, cb, pu32);
+ int rc = ich9pciDataRead(PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS), Port, cb, pu32);
PCI_UNLOCK(pDevIns);
- Log(("pciIOPortDataRead: Port=%#x cb=%#x -> %#x (%Rrc)\n", Port, cb, *pu32, rc));
+ LogFlow(("ich9pciIOPortDataRead: Port=%#x cb=%#x -> %#x (%Rrc)\n", Port, cb, *pu32, rc));
return rc;
}
AssertMsgFailed(("Unaligned read from port %#x cb=%d\n", Port, cb));
@@ -520,18 +493,18 @@ DECLINLINE(int) ich9pciSlotGetPirq(uint8_t uBus, uint8_t uDevFn, int iIrqNum)
static const uint8_t aPciIrqs[4] = { 11, 10, 9, 5 };
/* Add one more level up request on APIC input line */
-DECLINLINE(void) ich9pciApicLevelUp(PPCIGLOBALS pGlobals, int irq_num)
+DECLINLINE(void) ich9pciApicLevelUp(PICH9PCIGLOBALS pGlobals, int irq_num)
{
ASMAtomicIncU32(&pGlobals->uaPciApicIrqLevels[irq_num]);
}
/* Remove one level up request on APIC input line */
-DECLINLINE(void) ich9pciApicLevelDown(PPCIGLOBALS pGlobals, int irq_num)
+DECLINLINE(void) ich9pciApicLevelDown(PICH9PCIGLOBALS pGlobals, int irq_num)
{
ASMAtomicDecU32(&pGlobals->uaPciApicIrqLevels[irq_num]);
}
-static void ich9pciApicSetIrq(PPCIBUS pBus, uint8_t uDevFn, PCIDevice *pPciDev, int irq_num1, int iLevel, int iForcedIrq)
+static void ich9pciApicSetIrq(PICH9PCIBUS pBus, uint8_t uDevFn, PCIDevice *pPciDev, int irq_num1, int iLevel, int iForcedIrq)
{
/* This is only allowed to be called with a pointer to the root bus. */
AssertMsg(pBus->iBus == 0, ("iBus=%u\n", pBus->iBus));
@@ -539,7 +512,7 @@ static void ich9pciApicSetIrq(PPCIBUS pBus, uint8_t uDevFn, PCIDevice *pPciDev,
if (iForcedIrq == -1)
{
int apic_irq, apic_level;
- PPCIGLOBALS pGlobals = PCIROOTBUS_2_PCIGLOBALS(pBus);
+ PICH9PCIGLOBALS pGlobals = PCIROOTBUS_2_PCIGLOBALS(pBus);
int irq_num = ich9pciSlot2ApicIrq(uDevFn >> 3, irq_num1);
if ((iLevel & PDM_IRQ_LEVEL_HIGH) == PDM_IRQ_LEVEL_HIGH)
@@ -555,7 +528,7 @@ static void ich9pciApicSetIrq(PPCIBUS pBus, uint8_t uDevFn, PCIDevice *pPciDev,
if ((iLevel & PDM_IRQ_LEVEL_FLIP_FLOP) == PDM_IRQ_LEVEL_FLIP_FLOP)
{
- /**
+ /*
* we raised it few lines above, as PDM_IRQ_LEVEL_FLIP_FLOP has
* PDM_IRQ_LEVEL_HIGH bit set
*/
@@ -573,7 +546,7 @@ static void ich9pciApicSetIrq(PPCIBUS pBus, uint8_t uDevFn, PCIDevice *pPciDev,
}
}
-static void ich9pciSetIrqInternal(PPCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev, int iIrq, int iLevel)
+static void ich9pciSetIrqInternal(PICH9PCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev, int iIrq, int iLevel)
{
if (PCIDevIsIntxDisabled(pPciDev))
@@ -592,7 +565,7 @@ static void ich9pciSetIrqInternal(PPCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVI
return;
}
- PPCIBUS pBus = &pGlobals->aPciBus;
+ PICH9PCIBUS pBus = &pGlobals->aPciBus;
const bool fIsAcpiDevice = PCIDevGetDeviceId(pPciDev) == 0x7113;
/* Check if the state changed. */
@@ -615,9 +588,9 @@ static void ich9pciSetIrqInternal(PPCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVI
}
}
-PDMBOTHCBDECL(int) ich9pciMcfgMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+PDMBOTHCBDECL(int) ich9pciMcfgMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
- PPCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
+ PICH9PCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
PciAddress aDest;
uint32_t u32 = 0;
@@ -650,7 +623,7 @@ PDMBOTHCBDECL(int) ich9pciMcfgMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCP
PDMBOTHCBDECL(int) ich9pciMcfgMMIORead (PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
{
- PPCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
+ PICH9PCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
PciAddress aDest;
uint32_t rv;
@@ -687,7 +660,7 @@ PDMBOTHCBDECL(int) ich9pciMcfgMMIORead (PPDMDEVINS pDevIns, void *pvUser, RTGCP
#ifdef IN_RING3
-DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PPCIBUS pBus, uint8_t iBus)
+DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PICH9PCIBUS pBus, uint8_t iBus)
{
/* Search for a fitting bridge. */
for (uint32_t iBridge = 0; iBridge < pBus->cBridges; iBridge++)
@@ -696,19 +669,40 @@ DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PPCIBUS pBus, uint8_t iBus)
* Examine secondary and subordinate bus number.
* If the target bus is in the range we pass the request on to the bridge.
*/
- PPCIDEVICE pBridgeTemp = pBus->papBridgesR3[iBridge];
- AssertMsg(pBridgeTemp && PCIIsPci2PciBridge(pBridgeTemp),
+ PPCIDEVICE pBridge = pBus->papBridgesR3[iBridge];
+ AssertMsg(pBridge && pciDevIsPci2PciBridge(pBridge),
("Device is not a PCI bridge but on the list of PCI bridges\n"));
-
- if ( iBus >= PCIDevGetByte(pBridgeTemp, VBOX_PCI_SECONDARY_BUS)
- && iBus <= PCIDevGetByte(pBridgeTemp, VBOX_PCI_SUBORDINATE_BUS))
- return pBridgeTemp;
+ uint32_t uSecondary = PCIDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS);
+ uint32_t uSubordinate = PCIDevGetByte(pBridge, VBOX_PCI_SUBORDINATE_BUS);
+ Log3(("ich9pciFindBridge on bus %p, bridge %d: %d in %d..%d\n", pBus, iBridge, iBus, uSecondary, uSubordinate));
+ if (iBus >= uSecondary && iBus <= uSubordinate)
+ return pBridge;
}
/* Nothing found. */
return NULL;
}
+static uint32_t ich9pciGetCfg(PCIDevice* aDev, int32_t iRegister, int cb)
+{
+ return aDev->Int.s.pfnConfigRead(aDev, iRegister, cb);
+}
+
+static uint8_t ich9pciGetByte(PCIDevice* aDev, int32_t iRegister)
+{
+ return (uint8_t)ich9pciGetCfg(aDev, iRegister, 1);
+}
+
+static uint16_t ich9pciGetWord(PCIDevice* aDev, int32_t iRegister)
+{
+ return (uint16_t)ich9pciGetCfg(aDev, iRegister, 2);
+}
+
+static uint32_t ich9pciGetDWord(PCIDevice* aDev, int32_t iRegister)
+{
+ return (uint32_t)ich9pciGetCfg(aDev, iRegister, 4);
+}
+
DECLINLINE(uint32_t) ich9pciGetRegionReg(int iRegion)
{
return (iRegion == VBOX_PCI_ROM_SLOT) ?
@@ -721,7 +715,7 @@ static int ich9pciUnmapRegion(PPCIDEVICE pDev, int iRegion)
{
PCIIORegion* pRegion = &pDev->Int.s.aIORegions[iRegion];
int rc = VINF_SUCCESS;
- PPCIBUS pBus = pDev->Int.s.CTX_SUFF(pBus);
+ PICH9PCIBUS pBus = pDev->Int.s.CTX_SUFF(pBus);
Assert (pRegion->size != 0);
@@ -755,21 +749,21 @@ static int ich9pciUnmapRegion(PPCIDEVICE pDev, int iRegion)
static void ich9pciUpdateMappings(PCIDevice* pDev)
{
- PPCIBUS pBus = pDev->Int.s.CTX_SUFF(pBus);
- uint32_t uLast, uNew;
+ PICH9PCIBUS pBus = pDev->Int.s.CTX_SUFF(pBus);
+ uint64_t uLast, uNew;
- int iCmd = PCIDevGetCommand(pDev);
+ int iCmd = ich9pciGetWord(pDev, VBOX_PCI_COMMAND);
for (int iRegion = 0; iRegion < PCI_NUM_REGIONS; iRegion++)
{
PCIIORegion* pRegion = &pDev->Int.s.aIORegions[iRegion];
- uint32_t uConfigReg = ich9pciGetRegionReg(iRegion);
- int32_t iRegionSize = pRegion->size;
+ uint32_t uConfigReg = ich9pciGetRegionReg(iRegion);
+ int64_t iRegionSize = pRegion->size;
int rc;
if (iRegionSize == 0)
continue;
- AssertMsg((pRegion->type & PCI_ADDRESS_SPACE_BAR64) == 0, ("64-bit BARs not yet implemented\n"));
+ bool f64Bit = (pRegion->type & PCI_ADDRESS_SPACE_BAR64) != 0;
if (pRegion->type & PCI_ADDRESS_SPACE_IO)
{
@@ -777,7 +771,7 @@ static void ich9pciUpdateMappings(PCIDevice* pDev)
if (iCmd & PCI_COMMAND_IOACCESS)
{
/* IO access allowed */
- uNew = ich9pciConfigReadDev(pDev, uConfigReg, 4);
+ uNew = ich9pciGetDWord(pDev, uConfigReg);
uNew &= ~(iRegionSize - 1);
uLast = uNew + iRegionSize - 1;
/* only 64K ioports on PC */
@@ -791,7 +785,19 @@ static void ich9pciUpdateMappings(PCIDevice* pDev)
/* MMIO region */
if (iCmd & PCI_COMMAND_MEMACCESS)
{
- uNew = ich9pciConfigReadDev(pDev, uConfigReg, 4);
+ uNew = ich9pciGetDWord(pDev, uConfigReg);
+
+ if (f64Bit)
+ {
+ uNew |= ((uint64_t)ich9pciGetDWord(pDev, uConfigReg+4)) << 32;
+ if (uNew > UINT64_C(0x0000010000000000))
+ {
+ /* Workaround for REM being unhapping with mapping very lange 64-bit addresses */
+ Log(("Ignoring too 64-bit BAR: %llx\n", uNew));
+ uNew = INVALID_PCI_ADDRESS;
+ }
+ }
+
/* the ROM slot has a specific enable bit */
if (iRegion == PCI_ROM_SLOT && !(uNew & 1))
uNew = INVALID_PCI_ADDRESS;
@@ -818,6 +824,7 @@ static void ich9pciUpdateMappings(PCIDevice* pDev)
pRegion->addr = uNew;
if (pRegion->addr != INVALID_PCI_ADDRESS)
{
+
/* finally, map the region */
rc = pRegion->map_func(pDev, iRegion,
pRegion->addr, pRegion->size,
@@ -830,7 +837,7 @@ static void ich9pciUpdateMappings(PCIDevice* pDev)
static DECLCALLBACK(int) ich9pciRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev)
{
- PPCIBUS pBus = DEVINS_2_PCIBUS(pDevIns);
+ PICH9PCIBUS pBus = DEVINS_2_PCIBUS(pDevIns);
/*
* Check input.
@@ -856,21 +863,21 @@ static DECLCALLBACK(int) ich9pciRegisterMsi(PPDMDEVINS pDevIns, PPCIDEVICE pPciD
int rc;
rc = MsiInit(pPciDev, pMsiReg);
- if (rc != VINF_SUCCESS)
+ if (RT_FAILURE(rc))
return rc;
rc = MsixInit(pPciDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pPciHlp), pPciDev, pMsiReg);
- if (rc != VINF_SUCCESS)
+ if (RT_FAILURE(rc))
return rc;
- return rc;
+ return VINF_SUCCESS;
}
static DECLCALLBACK(int) ich9pcibridgeRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev)
{
- PPCIBUS pBus = PDMINS_2_DATA(pDevIns, PPCIBUS);
+ PICH9PCIBUS pBus = PDMINS_2_DATA(pDevIns, PICH9PCIBUS);
/*
* Check input.
@@ -894,9 +901,12 @@ static DECLCALLBACK(int) ich9pciIORegionRegister(PPDMDEVINS pDevIns, PPCIDEVICE
/*
* Validate.
*/
- AssertMsgReturn( enmType == PCI_ADDRESS_SPACE_MEM
- || enmType == PCI_ADDRESS_SPACE_IO
- || enmType == PCI_ADDRESS_SPACE_MEM_PREFETCH,
+ AssertMsgReturn( enmType == (PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_BAR32)
+ || enmType == (PCI_ADDRESS_SPACE_MEM_PREFETCH | PCI_ADDRESS_SPACE_BAR32)
+ || enmType == (PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_BAR64)
+ || enmType == (PCI_ADDRESS_SPACE_MEM_PREFETCH | PCI_ADDRESS_SPACE_BAR64)
+ || enmType == PCI_ADDRESS_SPACE_IO
+ ,
("Invalid enmType=%#x? Or was this a bitmask after all...\n", enmType),
VERR_INVALID_PARAMETER);
AssertMsgReturn((unsigned)iRegion < PCI_NUM_REGIONS,
@@ -908,6 +918,12 @@ static DECLCALLBACK(int) ich9pciIORegionRegister(PPDMDEVINS pDevIns, PPCIDEVICE
("Invalid cbRegion=%#x iLastSet=%#x (not a power of 2 or 0)\n", cbRegion, iLastSet),
VERR_INVALID_PARAMETER);
+ Log(("ich9pciIORegionRegister: %s region %d size %d type %x\n",
+ pPciDev->name, iRegion, cbRegion, enmType));
+
+ /* Make sure that we haven't marked this region as continuation of 64-bit region. */
+ Assert(pPciDev->Int.s.aIORegions[iRegion].type != 0xff);
+
/*
* Register the I/O region.
*/
@@ -917,11 +933,18 @@ static DECLCALLBACK(int) ich9pciIORegionRegister(PPDMDEVINS pDevIns, PPCIDEVICE
pRegion->type = enmType;
pRegion->map_func = pfnCallback;
- /* Set type in the config space. */
- uint32_t u32Address = ich9pciGetRegionReg(iRegion);
- uint32_t u32Value = (enmType == PCI_ADDRESS_SPACE_MEM_PREFETCH ? (1 << 3) : 0)
- | (enmType == PCI_ADDRESS_SPACE_IO ? 1 : 0);
- PCIDevSetDWord(pPciDev, u32Address, u32Value);
+ if ((enmType & PCI_ADDRESS_SPACE_BAR64) != 0)
+ {
+ AssertMsgReturn(iRegion < 4,
+ ("Region %d cannot be 64-bit\n", iRegion),
+ VERR_INVALID_PARAMETER);
+ /* Mark next region as continuation of this one. */
+ pPciDev->Int.s.aIORegions[iRegion+1].type = 0xff;
+ }
+
+ /* Set type in the PCI config space. */
+ uint32_t u32Value = ((uint32_t)enmType) & (PCI_ADDRESS_SPACE_IO | PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_MEM_PREFETCH);
+ PCIDevSetDWord(pPciDev, ich9pciGetRegionReg(iRegion), u32Value);
return VINF_SUCCESS;
}
@@ -948,10 +971,11 @@ static DECLCALLBACK(void) ich9pciSetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVI
*/
static DECLCALLBACK(int) ich9pciGenericSaveExec(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSM)
{
+ Assert(!pciDevIsPassthrough(pPciDev));
return SSMR3PutMem(pSSM, &pPciDev->config[0], sizeof(pPciDev->config));
}
-static int ich9pciR3CommonSaveExec(PPCIBUS pBus, PSSMHANDLE pSSM)
+static int ich9pciR3CommonSaveExec(PICH9PCIBUS pBus, PSSMHANDLE pSSM)
{
/*
* Iterate thru all the devices.
@@ -967,7 +991,7 @@ static int ich9pciR3CommonSaveExec(PPCIBUS pBus, PSSMHANDLE pSSM)
SSMR3PutMem(pSSM, pDev->config, sizeof(pDev->config));
/* Device flags */
- int rc = SSMR3PutU32(pSSM, pDev->Int.s.uFlags);
+ int rc = SSMR3PutU32(pSSM, pDev->Int.s.fFlags);
if (RT_FAILURE(rc))
return rc;
@@ -1006,7 +1030,7 @@ static int ich9pciR3CommonSaveExec(PPCIBUS pBus, PSSMHANDLE pSSM)
static DECLCALLBACK(int) ich9pciR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
{
- PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
+ PICH9PCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
/*
* Bus state data.
@@ -1027,14 +1051,14 @@ static DECLCALLBACK(int) ich9pciR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
static DECLCALLBACK(int) ich9pcibridgeR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
{
- PPCIBUS pThis = PDMINS_2_DATA(pDevIns, PPCIBUS);
+ PICH9PCIBUS pThis = PDMINS_2_DATA(pDevIns, PICH9PCIBUS);
return ich9pciR3CommonSaveExec(pThis, pSSM);
}
static void ich9pcibridgeConfigWrite(PPDMDEVINSR3 pDevIns, uint8_t iBus, uint8_t iDevice, uint32_t u32Address, uint32_t u32Value, unsigned cb)
{
- PPCIBUS pBus = PDMINS_2_DATA(pDevIns, PPCIBUS);
+ PICH9PCIBUS pBus = PDMINS_2_DATA(pDevIns, PICH9PCIBUS);
LogFlowFunc((": pDevIns=%p iBus=%d iDevice=%d u32Address=%u u32Value=%u cb=%d\n", pDevIns, iBus, iDevice, u32Address, u32Value, cb));
@@ -1062,7 +1086,7 @@ static void ich9pcibridgeConfigWrite(PPDMDEVINSR3 pDevIns, uint8_t iBus, uint8_t
static uint32_t ich9pcibridgeConfigRead(PPDMDEVINSR3 pDevIns, uint8_t iBus, uint8_t iDevice, uint32_t u32Address, unsigned cb)
{
- PPCIBUS pBus = PDMINS_2_DATA(pDevIns, PPCIBUS);
+ PICH9PCIBUS pBus = PDMINS_2_DATA(pDevIns, PICH9PCIBUS);
uint32_t u32Value;
LogFlowFunc((": pDevIns=%p iBus=%d iDevice=%d u32Address=%u cb=%d\n", pDevIns, iBus, iDevice, u32Address, cb));
@@ -1200,7 +1224,9 @@ static void pciR3CommonRestoreConfig(PPCIDEVICE pDev, uint8_t const *pbSrcConfig
* Loop thru the fields covering the 64 bytes of standard registers.
*/
uint8_t const fBridge = fIsBridge ? 2 : 1;
+ Assert(!pciDevIsPassthrough(pDev));
uint8_t *pbDstConfig = &pDev->config[0];
+
for (uint32_t i = 0; i < RT_ELEMENTS(s_aFields); i++)
if (s_aFields[i].fBridge & fBridge)
{
@@ -1270,7 +1296,7 @@ static void pciR3CommonRestoreConfig(PPCIDEVICE pDev, uint8_t const *pbSrcConfig
* @param uVersion The data version.
* @param uPass The pass.
*/
-static DECLCALLBACK(int) ich9pciR3CommonLoadExec(PPCIBUS pBus, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
+static DECLCALLBACK(int) ich9pciR3CommonLoadExec(PICH9PCIBUS pBus, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
{
uint32_t u32;
uint32_t i;
@@ -1335,7 +1361,7 @@ static DECLCALLBACK(int) ich9pciR3CommonLoadExec(PPCIBUS pBus, PSSMHANDLE pSSM,
}
/* get the data */
- DevTmp.Int.s.uFlags = 0;
+ DevTmp.Int.s.fFlags = 0;
DevTmp.Int.s.u8MsiCapOffset = 0;
DevTmp.Int.s.u8MsiCapSize = 0;
DevTmp.Int.s.u8MsixCapOffset = 0;
@@ -1343,7 +1369,7 @@ static DECLCALLBACK(int) ich9pciR3CommonLoadExec(PPCIBUS pBus, PSSMHANDLE pSSM,
DevTmp.Int.s.uIrqPinState = ~0; /* Invalid value in case we have an older saved state to force a state change in pciSetIrq. */
SSMR3GetMem(pSSM, DevTmp.config, sizeof(DevTmp.config));
- rc = SSMR3GetU32(pSSM, &DevTmp.Int.s.uFlags);
+ rc = SSMR3GetU32(pSSM, &DevTmp.Int.s.fFlags);
if (RT_FAILURE(rc))
goto out;
@@ -1394,6 +1420,7 @@ static DECLCALLBACK(int) ich9pciR3CommonLoadExec(PPCIBUS pBus, PSSMHANDLE pSSM,
i, pDev->name, PCIDevGetVendorId(&DevTmp), PCIDevGetVendorId(pDev));
/* commit the loaded device config. */
+ Assert(!pciDevIsPassthrough(pDev));
pciR3CommonRestoreConfig(pDev, &DevTmp.config[0], false ); /** @todo fix bridge fun! */
pDev->Int.s.uIrqPinState = DevTmp.Int.s.uIrqPinState;
@@ -1425,15 +1452,16 @@ static DECLCALLBACK(int) ich9pciR3CommonLoadExec(PPCIBUS pBus, PSSMHANDLE pSSM,
*/
static DECLCALLBACK(int) ich9pciGenericLoadExec(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSM)
{
+ Assert(!pciDevIsPassthrough(pPciDev));
return SSMR3GetMem(pSSM, &pPciDev->config[0], sizeof(pPciDev->config));
}
static DECLCALLBACK(int) ich9pciR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
{
- PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
- PPCIBUS pBus = &pThis->aPciBus;
- uint32_t u32;
- int rc;
+ PICH9PCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
+ PICH9PCIBUS pBus = &pThis->aPciBus;
+ uint32_t u32;
+ int rc;
/* We ignore this version as there's no saved state with it anyway */
if (uVersion == VBOX_ICH9PCI_SAVED_STATE_VERSION_NOMSI)
@@ -1464,13 +1492,13 @@ static DECLCALLBACK(int) ich9pciR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM,
static DECLCALLBACK(int) ich9pcibridgeR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
{
- PPCIBUS pThis = PDMINS_2_DATA(pDevIns, PPCIBUS);
+ PICH9PCIBUS pThis = PDMINS_2_DATA(pDevIns, PICH9PCIBUS);
if (uVersion > VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI)
return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
return ich9pciR3CommonLoadExec(pThis, pSSM, uVersion, uPass);
}
-static uint32_t ich9pciConfigRead(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint32_t addr, uint32_t len)
+static uint32_t ich9pciConfigRead(PICH9PCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint32_t addr, uint32_t len)
{
/* Will only work in LSB case */
uint32_t u32Val;
@@ -1486,7 +1514,7 @@ static uint32_t ich9pciConfigRead(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uD
return u32Val;
}
-static void ich9pciConfigWrite(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint32_t addr, uint32_t val, uint32_t len)
+static void ich9pciConfigWrite(PICH9PCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint32_t addr, uint32_t val, uint32_t len)
{
PciAddress aPciAddr;
@@ -1499,7 +1527,7 @@ static void ich9pciConfigWrite(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevF
AssertRC(rc);
}
-static void ich9pciSetRegionAddress(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, int iRegion, uint32_t addr)
+static void ich9pciSetRegionAddress(PICH9PCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, int iRegion, uint64_t addr)
{
uint32_t uReg = ich9pciGetRegionReg(iRegion);
@@ -1508,6 +1536,9 @@ static void ich9pciSetRegionAddress(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t
/* Read command register. */
uint16_t uCmd = ich9pciConfigRead(pGlobals, uBus, uDevFn, VBOX_PCI_COMMAND, 2);
+ Log(("Set region address: %02x:%02x.%d region %d address=%lld\n",
+ uBus, uDevFn>>3, uDevFn&7, addr));
+
if ( iRegion == PCI_ROM_SLOT )
uCmd |= PCI_COMMAND_MEMACCESS;
else if ((uResourceType & PCI_ADDRESS_SPACE_IO) == PCI_ADDRESS_SPACE_IO)
@@ -1515,22 +1546,21 @@ static void ich9pciSetRegionAddress(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t
else /* The region is MMIO. */
uCmd |= PCI_COMMAND_MEMACCESS; /* Enable MMIO access. */
+ bool f64Bit = (uResourceType & PCI_ADDRESS_SPACE_BAR64) != 0;
+
/* Write address of the device. */
- ich9pciConfigWrite(pGlobals, uBus, uDevFn, uReg, addr, 4);
+ ich9pciConfigWrite(pGlobals, uBus, uDevFn, uReg, (uint32_t)addr, 4);
+ if (f64Bit)
+ ich9pciConfigWrite(pGlobals, uBus, uDevFn, uReg + 4, (uint32_t)(addr >> 32), 4);
/* enable memory mappings */
ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_COMMAND, uCmd, 2);
}
-static void ich9pciBiosInitBridge(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint8_t cBridgeDepth, uint8_t *paBridgePositions)
+static void ich9pciBiosInitBridge(PICH9PCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn)
{
- ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_SECONDARY_BUS, pGlobals->uBus, 1);
- /* Temporary until we know how many other bridges are behind this one. */
- ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_SUBORDINATE_BUS, 0xff, 1);
-
- /* Add position of this bridge into the array. */
- paBridgePositions[cBridgeDepth+1] = (uDevFn >> 3);
+ Log(("BIOS init bridge: %02x::%02x.%d\n", uBus, uDevFn >> 3, uDevFn & 7));
/*
* The I/O range for the bridge must be aligned to a 4KB boundary.
@@ -1555,13 +1585,11 @@ static void ich9pciBiosInitBridge(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uD
/* Save values to compare later to. */
uint32_t u32IoAddressBase = pGlobals->uPciBiosIo;
uint32_t u32MMIOAddressBase = pGlobals->uPciBiosMmio;
+ uint8_t uBridgeBus = ich9pciConfigRead(pGlobals, uBus, uDevFn, VBOX_PCI_SECONDARY_BUS, 1);
/* Init devices behind the bridge and possibly other bridges as well. */
for (int iDev = 0; iDev <= 255; iDev++)
- ich9pciBiosInitDevice(pGlobals, uBus + 1, iDev, cBridgeDepth + 1, paBridgePositions);
-
- /* The number of bridges behind the this one is now available. */
- ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_SUBORDINATE_BUS, pGlobals->uBus, 1);
+ ich9pciBiosInitDevice(pGlobals, uBridgeBus, iDev);
/*
* Set I/O limit register. If there is no device with I/O space behind the bridge
@@ -1596,9 +1624,8 @@ static void ich9pciBiosInitBridge(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uD
ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_PREF_LIMIT_UPPER32, 0x00, 4);
}
-static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint8_t cBridgeDepth, uint8_t *paBridgePositions)
+static void ich9pciBiosInitDevice(PICH9PCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn)
{
- uint32_t *paddr;
uint16_t uDevClass, uVendor, uDevice;
uint8_t uCmd;
@@ -1610,6 +1637,8 @@ static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uD
if (uVendor == 0xffff)
return;
+ Log(("BIOS init device: %02x:%02x.%d\n", uBus, uDevFn >> 3, uDevFn & 7));
+
switch (uDevClass)
{
case 0x0101:
@@ -1637,11 +1666,8 @@ static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uD
break;
case 0x0604:
/* PCI-to-PCI bridge. */
- ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_PRIMARY_BUS, uBus, 1);
-
AssertMsg(pGlobals->uBus < 255, ("Too many bridges on the bus\n"));
- pGlobals->uBus++;
- ich9pciBiosInitBridge(pGlobals, uBus, uDevFn, cBridgeDepth, paBridgePositions);
+ ich9pciBiosInitBridge(pGlobals, uBus, uDevFn);
break;
default:
default_map:
@@ -1657,34 +1683,61 @@ static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uD
/* Calculate size - we write all 1s into the BAR, and then evaluate which bits
are cleared. . */
uint8_t u8ResourceType = ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address, 1);
- ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address, UINT32_C(0xffffffff), 4);
- uint32_t u32Size = ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address, 4);
- /* Clear resource information depending on resource type. */
- if ((u8ResourceType & PCI_COMMAND_IOACCESS) == PCI_COMMAND_IOACCESS) /* I/O */
- u32Size &= ~(0x01);
- else /* MMIO */
- u32Size &= ~(0x0f);
+ bool f64bit = (u8ResourceType & PCI_ADDRESS_SPACE_BAR64) != 0;
bool fIsPio = ((u8ResourceType & PCI_COMMAND_IOACCESS) == PCI_COMMAND_IOACCESS);
- /*
- * Invert all bits and add 1 to get size of the region.
- * (From PCI implementation note)
- */
- if (fIsPio && (u32Size & UINT32_C(0xffff0000)) == 0)
- u32Size = (~(u32Size | UINT32_C(0xffff0000))) + 1;
+ uint64_t cbRegSize64 = 0;
+
+ if (f64bit)
+ {
+ ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address, UINT32_C(0xffffffff), 4);
+ ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address+4, UINT32_C(0xffffffff), 4);
+ cbRegSize64 = ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address, 4);
+ cbRegSize64 |= ((uint64_t)ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address+4, 4) << 32);
+ cbRegSize64 &= ~UINT64_C(0x0f);
+ cbRegSize64 = (~cbRegSize64) + 1;
+
+ /* No 64-bit PIO regions possible. */
+ Assert((u8ResourceType & PCI_COMMAND_IOACCESS) == 0);
+ }
else
- u32Size = (~u32Size) + 1;
+ {
+ uint32_t cbRegSize32;
+ ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address, UINT32_C(0xffffffff), 4);
+ cbRegSize32 = ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address, 4);
+
+ /* Clear resource information depending on resource type. */
+ if (fIsPio) /* PIO */
+ cbRegSize32 &= ~UINT32_C(0x01);
+ else /* MMIO */
+ cbRegSize32 &= ~UINT32_C(0x0f);
+
+ /*
+ * Invert all bits and add 1 to get size of the region.
+ * (From PCI implementation note)
+ */
+ if (fIsPio && (cbRegSize32 & UINT32_C(0xffff0000)) == 0)
+ cbRegSize32 = (~(cbRegSize32 | UINT32_C(0xffff0000))) + 1;
+ else
+ cbRegSize32 = (~cbRegSize32) + 1;
- Log(("%s: Size of region %u for device %d on bus %d is %u\n", __FUNCTION__, iRegion, uDevFn, uBus, u32Size));
+ cbRegSize64 = cbRegSize32;
+ }
+ Assert(cbRegSize64 == (uint32_t)cbRegSize64);
+ Log2(("%s: Size of region %u for device %d on bus %d is %lld\n", __FUNCTION__, iRegion, uDevFn, uBus, cbRegSize64));
- if (u32Size)
+ if (cbRegSize64)
{
- paddr = fIsPio ? &pGlobals->uPciBiosIo : &pGlobals->uPciBiosMmio;
- *paddr = (*paddr + u32Size - 1) & ~(u32Size - 1);
+ uint32_t cbRegSize32 = (uint32_t)cbRegSize64;
+ uint32_t* paddr = fIsPio ? &pGlobals->uPciBiosIo : &pGlobals->uPciBiosMmio;
+ *paddr = (*paddr + cbRegSize32 - 1) & ~(cbRegSize32 - 1);
Log(("%s: Start address of %s region %u is %#x\n", __FUNCTION__, (fIsPio ? "I/O" : "MMIO"), iRegion, *paddr));
ich9pciSetRegionAddress(pGlobals, uBus, uDevFn, iRegion, *paddr);
- *paddr += u32Size;
- Log(("%s: New address is %#x\n", __FUNCTION__, *paddr));
+ *paddr += cbRegSize32;
+ Log2(("%s: New address is %#x\n", __FUNCTION__, *paddr));
+
+ if (f64bit)
+ iRegion++; /* skip next region */
}
}
break;
@@ -1695,28 +1748,82 @@ static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uD
uint32_t iPin = ich9pciConfigRead(pGlobals, uBus, uDevFn, VBOX_PCI_INTERRUPT_PIN, 1);
if (iPin != 0)
{
- uint8_t uBridgeDevFn = uDevFn;
iPin--;
- /* We need to go up to the host bus to see which irq this device will assert there. */
- while (cBridgeDepth != 0)
+ if (uBus != 0)
{
- /* Get the pin the device would assert on the bridge. */
- iPin = ((uBridgeDevFn >> 3) + iPin) & 3;
- uBridgeDevFn = paBridgePositions[cBridgeDepth];
- cBridgeDepth--;
+ /* Find bus this device attached to. */
+ PICH9PCIBUS pBus = &pGlobals->aPciBus;
+ while (1)
+ {
+ PPCIDEVICE pBridge = ich9pciFindBridge(pBus, uBus);
+ if (!pBridge)
+ {
+ Assert(false);
+ break;
+ }
+ if (uBus == PCIDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS))
+ {
+ /* OK, found bus this device attached to. */
+ break;
+ }
+ pBus = PDMINS_2_DATA(pBridge->pDevIns, PICH9PCIBUS);
+ }
+
+ /* We need to go up to the host bus to see which irq pin this
+ * device will use there. See logic in ich9pcibridgeSetIrq().
+ */
+ while (pBus->iBus != 0)
+ {
+ /* Get the pin the device would assert on the bridge. */
+ iPin = ((pBus->aPciDev.devfn >> 3) + iPin) & 3;
+ pBus = pBus->aPciDev.Int.s.pBusR3;
+ };
}
int iIrq = aPciIrqs[ich9pciSlotGetPirq(uBus, uDevFn, iPin)];
+ Log(("Using pin %d and IRQ %d for device %02x:%02x.%d\n",
+ iPin, iIrq, uBus, uDevFn>>3, uDevFn&7));
ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_INTERRUPT_LINE, iIrq, 1);
}
}
+/* Initializes bridges registers used for routing. */
+static void ich9pciInitBridgeTopology(PICH9PCIGLOBALS pGlobals, PICH9PCIBUS pBus)
+{
+ PPCIDEVICE pBridgeDev = &pBus->aPciDev;
+
+ /* Set only if we are not on the root bus, it has no primary bus attached. */
+ if (pGlobals->uBus != 0)
+ {
+ PCIDevSetByte(pBridgeDev, VBOX_PCI_PRIMARY_BUS, pGlobals->uBus);
+ PCIDevSetByte(pBridgeDev, VBOX_PCI_SECONDARY_BUS, pGlobals->uBus);
+ }
+
+ pGlobals->uBus++;
+ for (uint32_t iBridge = 0; iBridge < pBus->cBridges; iBridge++)
+ {
+ PPCIDEVICE pBridge = pBus->papBridgesR3[iBridge];
+ AssertMsg(pBridge && pciDevIsPci2PciBridge(pBridge),
+ ("Device is not a PCI bridge but on the list of PCI bridges\n"));
+ PICH9PCIBUS pChildBus = PDMINS_2_DATA(pBridge->pDevIns, PICH9PCIBUS);
+ ich9pciInitBridgeTopology(pGlobals, pChildBus);
+ }
+ PCIDevSetByte(pBridgeDev, VBOX_PCI_SUBORDINATE_BUS, pGlobals->uBus);
+ Log2(("ich9pciInitBridgeTopology: for bus %p: primary=%d secondary=%d subordinate=%d\n",
+ pBus,
+ PCIDevGetByte(pBridgeDev, VBOX_PCI_PRIMARY_BUS),
+ PCIDevGetByte(pBridgeDev, VBOX_PCI_SECONDARY_BUS),
+ PCIDevGetByte(pBridgeDev, VBOX_PCI_SUBORDINATE_BUS)
+ ));
+}
+
+
static DECLCALLBACK(int) ich9pciFakePCIBIOS(PPDMDEVINS pDevIns)
{
unsigned i;
uint8_t elcr[2] = {0, 0};
- PPCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
+ PICH9PCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
PVM pVM = PDMDevHlpGetVM(pDevIns);
Assert(pVM);
@@ -1728,16 +1835,17 @@ static DECLCALLBACK(int) ich9pciFakePCIBIOS(PPDMDEVINS pDevIns)
pGlobals->uBus = 0;
/*
+ * Assign bridge topology, for further routing to work.
+ */
+ PICH9PCIBUS pBus = &pGlobals->aPciBus;
+ ich9pciInitBridgeTopology(pGlobals, pBus);
+
+ /*
* Init the devices.
*/
for (i = 0; i < 256; i++)
{
- uint8_t aBridgePositions[256];
-
- memset(aBridgePositions, 0, sizeof(aBridgePositions));
- Log2(("PCI: Initializing device %d (%#x)\n",
- i, 0x80000000 | (i << 8)));
- ich9pciBiosInitDevice(pGlobals, 0, i, 0, aBridgePositions);
+ ich9pciBiosInitDevice(pGlobals, 0, i);
}
return VINF_SUCCESS;
@@ -1747,10 +1855,14 @@ static DECLCALLBACK(uint32_t) ich9pciConfigReadDev(PCIDevice *aDev, uint32_t u32
{
if ((u32Address + len) > 256 && (u32Address + len) < 4096)
{
- AssertMsgReturn(false, ("Read from extended registers falled back to generic code\n"), 0);
+ LogRel(("Read from extended register %d fallen back to generic code\n",
+ u32Address));
+ return 0;
}
- if ( PCIIsMsiCapable(aDev)
+ AssertMsgReturn(u32Address + len <= 256, ("Read after the end of PCI config space\n"),
+ 0);
+ if ( pciDevIsMsiCapable(aDev)
&& (u32Address >= aDev->Int.s.u8MsiCapOffset)
&& (u32Address < aDev->Int.s.u8MsiCapOffset + aDev->Int.s.u8MsiCapSize)
)
@@ -1758,7 +1870,7 @@ static DECLCALLBACK(uint32_t) ich9pciConfigReadDev(PCIDevice *aDev, uint32_t u32
return MsiPciConfigRead(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), aDev, u32Address, len);
}
- if ( PCIIsMsixCapable(aDev)
+ if ( pciDevIsMsixCapable(aDev)
&& (u32Address >= aDev->Int.s.u8MsixCapOffset)
&& (u32Address < aDev->Int.s.u8MsixCapOffset + aDev->Int.s.u8MsixCapSize)
)
@@ -1785,12 +1897,21 @@ static DECLCALLBACK(uint32_t) ich9pciConfigReadDev(PCIDevice *aDev, uint32_t u32
DECLINLINE(void) ich9pciWriteBarByte(PCIDevice *aDev, int iRegion, int iOffset, uint8_t u8Val)
{
PCIIORegion * pRegion = &aDev->Int.s.aIORegions[iRegion];
-
- int iRegionSize = pRegion->size;
+ int64_t iRegionSize = pRegion->size;
Log3(("ich9pciWriteBarByte: region=%d off=%d val=%x size=%d\n",
iRegion, iOffset, u8Val, iRegionSize));
+ if (iOffset > 3)
+ Assert((aDev->Int.s.aIORegions[iRegion].type & PCI_ADDRESS_SPACE_BAR64) != 0);
+
+ /* Check if we're writing to upper part of 64-bit BAR. */
+ if (aDev->Int.s.aIORegions[iRegion].type == 0xff)
+ {
+ ich9pciWriteBarByte(aDev, iRegion-1, iOffset+4, u8Val);
+ return;
+ }
+
/* Region doesn't exist */
if (iRegionSize == 0)
return;
@@ -1798,7 +1919,7 @@ DECLINLINE(void) ich9pciWriteBarByte(PCIDevice *aDev, int iRegion, int iOffset,
uint32_t uAddr = ich9pciGetRegionReg(iRegion) + iOffset;
/* Region size must be power of two */
Assert((iRegionSize & (iRegionSize - 1)) == 0);
- uint8_t uMask = (((uint32_t)iRegionSize - 1) >> (iOffset*8) ) & 0xff;
+ uint8_t uMask = ((iRegionSize - 1) >> (iOffset*8) ) & 0xff;
if (iOffset == 0)
{
@@ -1815,6 +1936,7 @@ DECLINLINE(void) ich9pciWriteBarByte(PCIDevice *aDev, int iRegion, int iOffset,
PCIDevSetByte(aDev, uAddr, u8Val);
}
+
/**
* See paragraph 7.5 of PCI Express specification (p. 349) for definition of
* registers and their writability policy.
@@ -1826,12 +1948,14 @@ static DECLCALLBACK(void) ich9pciConfigWriteDev(PCIDevice *aDev, uint32_t u32Add
if ((u32Address + len) > 256 && (u32Address + len) < 4096)
{
- AssertMsgReturnVoid(false, ("Write to extended registers falled back to generic code\n"));
+ LogRel(("Write to extended register %d fallen back to generic code\n",
+ u32Address));
+ return;
}
AssertMsgReturnVoid(u32Address + len <= 256, ("Write after end of PCI config space\n"));
- if ( PCIIsMsiCapable(aDev)
+ if ( pciDevIsMsiCapable(aDev)
&& (u32Address >= aDev->Int.s.u8MsiCapOffset)
&& (u32Address < aDev->Int.s.u8MsiCapOffset + aDev->Int.s.u8MsiCapSize)
)
@@ -1842,7 +1966,7 @@ static DECLCALLBACK(void) ich9pciConfigWriteDev(PCIDevice *aDev, uint32_t u32Add
return;
}
- if ( PCIIsMsixCapable(aDev)
+ if ( pciDevIsMsixCapable(aDev)
&& (u32Address >= aDev->Int.s.u8MsixCapOffset)
&& (u32Address < aDev->Int.s.u8MsixCapOffset + aDev->Int.s.u8MsixCapSize)
)
@@ -1854,13 +1978,16 @@ static DECLCALLBACK(void) ich9pciConfigWriteDev(PCIDevice *aDev, uint32_t u32Add
}
uint32_t addr = u32Address;
- bool fUpdateMappings = false;
- bool fP2PBridge = false;
+ bool fUpdateMappings = false;
+ bool fP2PBridge = false;
+ bool fPassthrough = pciDevIsPassthrough(aDev);
+ uint8_t u8HeaderType = ich9pciGetByte(aDev, VBOX_PCI_HEADER_TYPE);
+
for (uint32_t i = 0; i < len; i++)
{
bool fWritable = false;
bool fRom = false;
- switch (PCIDevGetHeaderType(aDev))
+ switch (u8HeaderType)
{
case 0x00: /* normal device */
case 0x80: /* multi-function device */
@@ -1919,14 +2046,12 @@ static DECLCALLBACK(void) ich9pciConfigWriteDev(PCIDevice *aDev, uint32_t u32Add
{
case VBOX_PCI_COMMAND: /* Command register, bits 0-7. */
fUpdateMappings = true;
- PCIDevSetByte(aDev, addr, u8Val);
- break;
+ goto default_case;
case VBOX_PCI_COMMAND+1: /* Command register, bits 8-15. */
/* don't change reserved bits (11-15) */
u8Val &= UINT32_C(~0xf8);
fUpdateMappings = true;
- PCIDevSetByte(aDev, addr, u8Val);
- break;
+ goto default_case;
case VBOX_PCI_STATUS: /* Status register, bits 0-7. */
/* don't change read-only bits => actually all lower bits are read-only */
u8Val &= UINT32_C(~0xff);
@@ -1974,37 +2099,12 @@ static DECLCALLBACK(void) ich9pciConfigWriteDev(PCIDevice *aDev, uint32_t u32Add
ich9pciUpdateMappings(aDev);
}
-/* Slot/functions assignment per table at p. 12 of ICH9 family spec update */
-static const struct {
- const char* pszName;
- int32_t iSlot;
- int32_t iFunction;
-} PciSlotAssignments[] = {
- /* The only override that have to be here, as host controller is added in the way invisible to bus slot assignment management,
- maybe to be changed in the future. */
- {
- "i82801", 30, 0 /* Host Controller */
- },
-};
-
-static bool assignPosition(PPCIBUS pBus, PPCIDEVICE pPciDev, const char *pszName, int iDevFn, PciAddress* aPosition)
+static bool assignPosition(PICH9PCIBUS pBus, PPCIDEVICE pPciDev, const char *pszName, int iDevFn, PciAddress* aPosition)
{
aPosition->iBus = 0;
aPosition->iDeviceFunc = iDevFn;
aPosition->iRegister = 0; /* N/A */
- /* Hardcoded slots/functions, per chipset spec */
- for (size_t i = 0; i < RT_ELEMENTS(PciSlotAssignments); i++)
- {
- if (!strcmp(pszName, PciSlotAssignments[i].pszName))
- {
- PCISetRequestedDevfunc(pPciDev);
- aPosition->iDeviceFunc =
- (PciSlotAssignments[i].iSlot << 3) + PciSlotAssignments[i].iFunction;
- return true;
- }
- }
-
/* Explicit slot request */
if (iDevFn >=0 && iDevFn < (int)RT_ELEMENTS(pBus->apDevices))
return true;
@@ -2023,7 +2123,7 @@ static bool assignPosition(PPCIBUS pBus, PPCIDEVICE pPciDev, const char *pszName
&& !pBus->apDevices[iPos + 6]
&& !pBus->apDevices[iPos + 7])
{
- PCIClearRequestedDevfunc(pPciDev);
+ pciDevClearRequestedDevfunc(pPciDev);
aPosition->iDeviceFunc = iPos;
return true;
}
@@ -2032,22 +2132,22 @@ static bool assignPosition(PPCIBUS pBus, PPCIDEVICE pPciDev, const char *pszName
return false;
}
-static bool hasHardAssignedDevsInSlot(PPCIBUS pBus, int iSlot)
+static bool hasHardAssignedDevsInSlot(PICH9PCIBUS pBus, int iSlot)
{
PCIDevice** aSlot = &pBus->apDevices[iSlot << 3];
- return (aSlot[0] && PCIIsRequestedDevfunc(aSlot[0]))
- || (aSlot[1] && PCIIsRequestedDevfunc(aSlot[1]))
- || (aSlot[2] && PCIIsRequestedDevfunc(aSlot[2]))
- || (aSlot[3] && PCIIsRequestedDevfunc(aSlot[3]))
- || (aSlot[4] && PCIIsRequestedDevfunc(aSlot[4]))
- || (aSlot[5] && PCIIsRequestedDevfunc(aSlot[5]))
- || (aSlot[6] && PCIIsRequestedDevfunc(aSlot[6]))
- || (aSlot[7] && PCIIsRequestedDevfunc(aSlot[7]))
+ return (aSlot[0] && pciDevIsRequestedDevfunc(aSlot[0]))
+ || (aSlot[1] && pciDevIsRequestedDevfunc(aSlot[1]))
+ || (aSlot[2] && pciDevIsRequestedDevfunc(aSlot[2]))
+ || (aSlot[3] && pciDevIsRequestedDevfunc(aSlot[3]))
+ || (aSlot[4] && pciDevIsRequestedDevfunc(aSlot[4]))
+ || (aSlot[5] && pciDevIsRequestedDevfunc(aSlot[5]))
+ || (aSlot[6] && pciDevIsRequestedDevfunc(aSlot[6]))
+ || (aSlot[7] && pciDevIsRequestedDevfunc(aSlot[7]))
;
}
-static int ich9pciRegisterInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const char *pszName)
+static int ich9pciRegisterInternal(PICH9PCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const char *pszName)
{
PciAddress aPosition = {0, 0, 0};
@@ -2070,9 +2170,9 @@ static int ich9pciRegisterInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, c
* Check if we can really take this slot, possibly by relocating
* its current habitant, if it wasn't hard assigned too.
*/
- if (PCIIsRequestedDevfunc(pPciDev) &&
+ if (pciDevIsRequestedDevfunc(pPciDev) &&
pBus->apDevices[iDev] &&
- PCIIsRequestedDevfunc(pBus->apDevices[iDev]))
+ pciDevIsRequestedDevfunc(pBus->apDevices[iDev]))
{
AssertReleaseMsgFailed(("Configuration error:'%s' and '%s' are both configured as device %d\n",
pszName, pBus->apDevices[iDev]->name, iDev));
@@ -2115,17 +2215,18 @@ static int ich9pciRegisterInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, c
pPciDev->Int.s.pfnConfigRead = ich9pciConfigReadDev;
pPciDev->Int.s.pfnConfigWrite = ich9pciConfigWriteDev;
pBus->apDevices[iDev] = pPciDev;
- if (PCIIsPci2PciBridge(pPciDev))
+ if (pciDevIsPci2PciBridge(pPciDev))
{
AssertMsg(pBus->cBridges < RT_ELEMENTS(pBus->apDevices), ("Number of bridges exceeds the number of possible devices on the bus\n"));
AssertMsg(pPciDev->Int.s.pfnBridgeConfigRead && pPciDev->Int.s.pfnBridgeConfigWrite,
("device is a bridge but does not implement read/write functions\n"));
+ Log2(("Setting bridge %d on bus %p\n", pBus->cBridges, pBus));
pBus->papBridgesR3[pBus->cBridges] = pPciDev;
pBus->cBridges++;
}
- Log(("PCI: Registered device %d function %d (%#x) '%s'.\n",
- iDev >> 3, iDev & 7, 0x80000000 | (iDev << 8), pszName));
+ Log(("PCI: Registered device %d function %d on bus %d (%#x) '%s'.\n",
+ iDev >> 3, iDev & 7, pBus->iBus, 0x80000000 | (iDev << 8), pszName));
return VINF_SUCCESS;
}
@@ -2138,7 +2239,7 @@ static void printIndent(PCDBGFINFOHLP pHlp, int iIndent)
}
}
-static void ich9pciBusInfo(PPCIBUS pBus, PCDBGFINFOHLP pHlp, int iIndent, bool fRegisters)
+static void ich9pciBusInfo(PICH9PCIBUS pBus, PCDBGFINFOHLP pHlp, int iIndent, bool fRegisters)
{
for (uint32_t iDev = 0; iDev < RT_ELEMENTS(pBus->apDevices); iDev++)
{
@@ -2146,19 +2247,25 @@ static void ich9pciBusInfo(PPCIBUS pBus, PCDBGFINFOHLP pHlp, int iIndent, bool f
if (pPciDev != NULL)
{
printIndent(pHlp, iIndent);
- pHlp->pfnPrintf(pHlp, "%02x:%02x:%02x %s: %04x-%04x%s%s",
+
+ /*
+ * For passthrough devices MSI/MSI-X mostly reflects the way interrupts delivered to the guest,
+ * as host driver handles real devices interrupts.
+ */
+ pHlp->pfnPrintf(pHlp, "%02x:%02x:%02x %s%s: %04x-%04x%s%s",
pBus->iBus, (iDev >> 3) & 0xff, iDev & 0x7,
pPciDev->name,
- PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev),
- PCIIsMsiCapable(pPciDev) ? " MSI" : "",
- PCIIsMsixCapable(pPciDev) ? " MSI-X" : ""
+ pciDevIsPassthrough(pPciDev) ? " (PASSTHROUGH)" : "",
+ ich9pciGetWord(pPciDev, VBOX_PCI_VENDOR_ID), ich9pciGetWord(pPciDev, VBOX_PCI_DEVICE_ID),
+ pciDevIsMsiCapable(pPciDev) ? " MSI" : "",
+ pciDevIsMsixCapable(pPciDev) ? " MSI-X" : ""
);
- if (PCIDevGetInterruptPin(pPciDev) != 0)
- pHlp->pfnPrintf(pHlp, " IRQ%d", PCIDevGetInterruptLine(pPciDev));
+ if (ich9pciGetByte(pPciDev, VBOX_PCI_INTERRUPT_PIN) != 0)
+ pHlp->pfnPrintf(pHlp, " IRQ%d", ich9pciGetByte(pPciDev, VBOX_PCI_INTERRUPT_LINE));
pHlp->pfnPrintf(pHlp, "\n");
- int iCmd = PCIDevGetCommand(pPciDev);
+ int iCmd = ich9pciGetWord(pPciDev, VBOX_PCI_COMMAND);
if ((iCmd & (VBOX_PCI_COMMAND_IO | VBOX_PCI_COMMAND_MEMORY)) != 0)
{
for (int iRegion = 0; iRegion < PCI_NUM_REGIONS; iRegion++)
@@ -2169,23 +2276,30 @@ static void ich9pciBusInfo(PPCIBUS pBus, PCDBGFINFOHLP pHlp, int iIndent, bool f
if (iRegionSize == 0)
continue;
- uint32_t u32Addr = ich9pciConfigReadDev(pPciDev, ich9pciGetRegionReg(iRegion), 4);
- const char * szDesc;
+ uint32_t u32Addr = ich9pciGetDWord(pPciDev, ich9pciGetRegionReg(iRegion));
+ const char * pszDesc;
+ char szDescBuf[128];
+ bool f64Bit = (pRegion->type & PCI_ADDRESS_SPACE_BAR64);
if (pRegion->type & PCI_ADDRESS_SPACE_IO)
{
- szDesc = "IO";
+ pszDesc = "IO";
u32Addr &= ~0x3;
}
else
{
- szDesc = "MMIO";
+ RTStrPrintf(szDescBuf, sizeof(szDescBuf), "MMIO%s%s",
+ f64Bit ? "64" : "32",
+ (pRegion->type & PCI_ADDRESS_SPACE_MEM_PREFETCH) ? " PREFETCH" : "");
+ pszDesc = szDescBuf;
u32Addr &= ~0xf;
}
printIndent(pHlp, iIndent + 2);
pHlp->pfnPrintf(pHlp, " %s region #%d: %x..%x\n",
- szDesc, iRegion, u32Addr, u32Addr+iRegionSize);
+ pszDesc, iRegion, u32Addr, u32Addr+iRegionSize);
+ if (f64Bit)
+ iRegion++;
}
}
@@ -2201,7 +2315,7 @@ static void ich9pciBusInfo(PPCIBUS pBus, PCDBGFINFOHLP pHlp, int iIndent, bool f
while (iPerLine-- > 0)
{
- pHlp->pfnPrintf(pHlp, "%02x ", pPciDev->config[iReg++]);
+ pHlp->pfnPrintf(pHlp, "%02x ", ich9pciGetByte(pPciDev, iReg++));
}
pHlp->pfnPrintf(pHlp, "\n");
}
@@ -2215,7 +2329,7 @@ static void ich9pciBusInfo(PPCIBUS pBus, PCDBGFINFOHLP pHlp, int iIndent, bool f
pHlp->pfnPrintf(pHlp, "Registered %d bridges, subordinate buses info follows\n", pBus->cBridges);
for (uint32_t iBridge = 0; iBridge < pBus->cBridges; iBridge++)
{
- PPCIBUS pBusSub = PDMINS_2_DATA(pBus->papBridgesR3[iBridge]->pDevIns, PPCIBUS);
+ PICH9PCIBUS pBusSub = PDMINS_2_DATA(pBus->papBridgesR3[iBridge]->pDevIns, PICH9PCIBUS);
ich9pciBusInfo(pBusSub, pHlp, iIndent + 1, fRegisters);
}
}
@@ -2230,7 +2344,7 @@ static void ich9pciBusInfo(PPCIBUS pBus, PCDBGFINFOHLP pHlp, int iIndent, bool f
*/
static DECLCALLBACK(void) ich9pciInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
- PPCIBUS pBus = DEVINS_2_PCIBUS(pDevIns);
+ PICH9PCIBUS pBus = DEVINS_2_PCIBUS(pDevIns);
if (pszArgs == NULL || !strcmp(pszArgs, "basic"))
{
@@ -2251,8 +2365,8 @@ static DECLCALLBACK(int) ich9pciConstruct(PPDMDEVINS pDevIns,
int iInstance,
PCFGMNODE pCfg)
{
- int rc;
Assert(iInstance == 0);
+ PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
/*
* Validate and read configuration.
@@ -2268,7 +2382,7 @@ static DECLCALLBACK(int) ich9pciConstruct(PPDMDEVINS pDevIns,
/* query whether we got an IOAPIC */
bool fUseIoApic;
- rc = CFGMR3QueryBoolDef(pCfg, "IOAPIC", &fUseIoApic, false);
+ int rc = CFGMR3QueryBoolDef(pCfg, "IOAPIC", &fUseIoApic, false);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to query boolean value \"IOAPIC\""));
@@ -2279,7 +2393,6 @@ static DECLCALLBACK(int) ich9pciConstruct(PPDMDEVINS pDevIns,
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to query boolean value \"GCEnabled\""));
-
/* check if R0 code is enabled. */
bool fR0Enabled;
rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &fR0Enabled, true);
@@ -2292,8 +2405,8 @@ static DECLCALLBACK(int) ich9pciConstruct(PPDMDEVINS pDevIns,
/*
* Init data.
*/
- PPCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
- PPCIBUS pBus = &pGlobals->aPciBus;
+ PICH9PCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
+ PICH9PCIBUS pBus = &pGlobals->aPciBus;
/* Zero out everything */
memset(pGlobals, 0, sizeof(*pGlobals));
/* And fill values */
@@ -2348,35 +2461,26 @@ static DECLCALLBACK(int) ich9pciConstruct(PPDMDEVINS pDevIns,
/*
* Fill in PCI configs and add them to the bus.
*/
-
- /**
- * We emulate 82801IB ICH9 IO chip used in Q35,
- * see http://ark.intel.com/Product.aspx?id=31892
- *
- * Stepping S-Spec Top Marking
- *
- * A2 SLA9M NH82801IB
+ /** @todo: Disabled for now because this causes error messages with Linux guests.
+ * The guest loads the x38_edac device which tries to map a memory region
+ * using an address given at place 0x48 - 0x4f in the PCi config space.
+ * This fails. because we don't register such a region.
*/
+#if 0
/* Host bridge device */
- /* @todo: move to separate driver? */
PCIDevSetVendorId( &pBus->aPciDev, 0x8086); /* Intel */
- PCIDevSetDeviceId( &pBus->aPciDev, 0x244e); /* Desktop */
- PCIDevSetRevisionId(&pBus->aPciDev, 0x92); /* rev. A2 */
+ PCIDevSetDeviceId( &pBus->aPciDev, 0x29e0); /* Desktop */
+ PCIDevSetRevisionId(&pBus->aPciDev, 0x01); /* rev. 01 */
PCIDevSetClassBase( &pBus->aPciDev, 0x06); /* bridge */
- PCIDevSetClassSub( &pBus->aPciDev, 0x04); /* Host/PCI bridge */
- PCIDevSetClassProg( &pBus->aPciDev, 0x01); /* Supports subtractive decoding. */
- PCIDevSetHeaderType(&pBus->aPciDev, 0x01); /* bridge */
+ PCIDevSetClassSub( &pBus->aPciDev, 0x00); /* Host/PCI bridge */
+ PCIDevSetClassProg( &pBus->aPciDev, 0x00); /* Host/PCI bridge */
+ PCIDevSetHeaderType(&pBus->aPciDev, 0x00); /* bridge */
PCIDevSetWord(&pBus->aPciDev, VBOX_PCI_SEC_STATUS, 0x0280); /* secondary status */
- PCIDevSetDWord(&pBus->aPciDev, 0x4c, 0x00001200); /* Bridge policy configuration */
- PCIDevSetStatus (&pBus->aPciDev, VBOX_PCI_STATUS_CAP_LIST);
- PCIDevSetCapabilityList(&pBus->aPciDev, 0x50);
- /* capability */
- PCIDevSetWord(&pBus->aPciDev, 0x50, VBOX_PCI_CAP_ID_SSVID);
- PCIDevSetDWord(&pBus->aPciDev, 0x54, 0x00000000); /* Subsystem vendor ids */
pBus->aPciDev.pDevIns = pDevIns;
/* We register Host<->PCI controller on the bus */
- ich9pciRegisterInternal(pBus, -1, &pBus->aPciDev, "i82801");
+ ich9pciRegisterInternal(pBus, 0, &pBus->aPciDev, "dram");
+#endif
/*
* Register I/O ports and save state.
@@ -2468,7 +2572,6 @@ static DECLCALLBACK(int) ich9pciConstruct(PPDMDEVINS pDevIns,
/** @todo: other chipset devices shall be registered too */
- /** @todo: what to with bridges? */
PDMDevHlpDBGFInfoRegister(pDevIns, "pci", "Display PCI bus status. (no arguments)", ich9pciInfo);
@@ -2477,7 +2580,7 @@ static DECLCALLBACK(int) ich9pciConstruct(PPDMDEVINS pDevIns,
static void ich9pciResetDevice(PPCIDEVICE pDev)
{
- PPCIBUS pBus = pDev->Int.s.CTX_SUFF(pBus);
+ PICH9PCIBUS pBus = pDev->Int.s.CTX_SUFF(pBus);
int rc;
/* Clear regions */
@@ -2490,18 +2593,26 @@ static void ich9pciResetDevice(PPCIDEVICE pDev)
ich9pciUnmapRegion(pDev, iRegion);
}
- PCIDevSetCommand(pDev,
- PCIDevGetCommand(pDev)
- &
- ~(VBOX_PCI_COMMAND_IO |
- VBOX_PCI_COMMAND_MEMORY |
- VBOX_PCI_COMMAND_MASTER));
-
- /* Bridge device reset handlers processed later */
- if (!PCIIsPci2PciBridge(pDev))
+ if (pciDevIsPassthrough(pDev))
{
- PCIDevSetByte(pDev, VBOX_PCI_CACHE_LINE_SIZE, 0x0);
- PCIDevSetInterruptLine(pDev, 0x0);
+ // no reset handler - we can do what we need in PDM reset handler
+ // @todo: is it correct?
+ }
+ else
+ {
+ PCIDevSetCommand(pDev,
+ PCIDevGetCommand(pDev)
+ &
+ ~(VBOX_PCI_COMMAND_IO |
+ VBOX_PCI_COMMAND_MEMORY |
+ VBOX_PCI_COMMAND_MASTER));
+
+ /* Bridge device reset handlers processed later */
+ if (!pciDevIsPci2PciBridge(pDev))
+ {
+ PCIDevSetByte(pDev, VBOX_PCI_CACHE_LINE_SIZE, 0x0);
+ PCIDevSetInterruptLine(pDev, 0x0);
+ }
}
}
@@ -2511,8 +2622,8 @@ static void ich9pciResetDevice(PPCIDEVICE pDev)
*/
static DECLCALLBACK(void) ich9pciReset(PPDMDEVINS pDevIns)
{
- PPCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
- PPCIBUS pBus = &pGlobals->aPciBus;
+ PICH9PCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
+ PICH9PCIBUS pBus = &pGlobals->aPciBus;
/* PCI-specific reset for each device. */
for (uint32_t i = 0; i < RT_ELEMENTS(pBus->apDevices); i++)
@@ -2545,8 +2656,8 @@ static void ich9pciRelocateDevice(PPCIDEVICE pDev, RTGCINTPTR offDelta)
*/
static DECLCALLBACK(void) ich9pciRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
{
- PPCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
- PPCIBUS pBus = &pGlobals->aPciBus;
+ PICH9PCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
+ PICH9PCIBUS pBus = &pGlobals->aPciBus;
pGlobals->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
pBus->pPciHlpRC = pBus->pPciHlpR3->pfnGetRCHelpers(pDevIns);
@@ -2565,7 +2676,7 @@ static DECLCALLBACK(int) ich9pcibridgeConstruct(PPDMDEVINS pDevIns,
int iInstance,
PCFGMNODE pCfg)
{
- int rc;
+ PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
/*
* Validate and read configuration.
@@ -2575,7 +2686,7 @@ static DECLCALLBACK(int) ich9pcibridgeConstruct(PPDMDEVINS pDevIns,
/* check if RC code is enabled. */
bool fGCEnabled;
- rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fGCEnabled, true);
+ int rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fGCEnabled, true);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to query boolean value \"GCEnabled\""));
@@ -2591,7 +2702,7 @@ static DECLCALLBACK(int) ich9pcibridgeConstruct(PPDMDEVINS pDevIns,
/*
* Init data and register the PCI bus.
*/
- PPCIBUS pBus = PDMINS_2_DATA(pDevIns, PPCIBUS);
+ PICH9PCIBUS pBus = PDMINS_2_DATA(pDevIns, PICH9PCIBUS);
pBus->pDevInsR3 = pDevIns;
pBus->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
pBus->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
@@ -2644,7 +2755,7 @@ static DECLCALLBACK(int) ich9pcibridgeConstruct(PPDMDEVINS pDevIns,
pBus->aPciDev.pDevIns = pDevIns;
/* Bridge-specific data */
- PCISetPci2PciBridge(&pBus->aPciDev);
+ pciDevSetPci2PciBridge(&pBus->aPciDev);
pBus->aPciDev.Int.s.pfnBridgeConfigRead = ich9pcibridgeConfigRead;
pBus->aPciDev.Int.s.pfnBridgeConfigWrite = ich9pcibridgeConfigWrite;
@@ -2687,7 +2798,7 @@ static DECLCALLBACK(int) ich9pcibridgeConstruct(PPDMDEVINS pDevIns,
*/
static void ich9pcibridgeReset(PPDMDEVINS pDevIns)
{
- PPCIBUS pBus = PDMINS_2_DATA(pDevIns, PPCIBUS);
+ PICH9PCIBUS pBus = PDMINS_2_DATA(pDevIns, PICH9PCIBUS);
/* Reset config space to default values. */
PCIDevSetByte(&pBus->aPciDev, VBOX_PCI_PRIMARY_BUS, 0);
@@ -2708,7 +2819,7 @@ static void ich9pcibridgeReset(PPDMDEVINS pDevIns)
*/
static DECLCALLBACK(void) ich9pcibridgeRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
{
- PPCIBUS pBus = PDMINS_2_DATA(pDevIns, PPCIBUS);
+ PICH9PCIBUS pBus = PDMINS_2_DATA(pDevIns, PICH9PCIBUS);
pBus->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
/* Relocate RC pointers for the attached pci devices. */
@@ -2738,7 +2849,7 @@ const PDMDEVREG g_DevicePciIch9 =
/* cMaxInstances */
1,
/* cbInstance */
- sizeof(PCIGLOBALS),
+ sizeof(ICH9PCIGLOBALS),
/* pfnConstruct */
ich9pciConstruct,
/* pfnDestruct */
@@ -2794,7 +2905,7 @@ const PDMDEVREG g_DevicePciIch9Bridge =
/* cMaxInstances */
~0,
/* cbInstance */
- sizeof(PCIBUS),
+ sizeof(ICH9PCIBUS),
/* pfnConstruct */
ich9pcibridgeConstruct,
/* pfnDestruct */
diff --git a/src/VBox/Devices/Bus/DevPciRaw.cpp b/src/VBox/Devices/Bus/DevPciRaw.cpp
deleted file mode 100644
index 05910038e..000000000
--- a/src/VBox/Devices/Bus/DevPciRaw.cpp
+++ /dev/null
@@ -1,530 +0,0 @@
-/* $Id: DevPciRaw.cpp $ */
-/** @file
- * PCI passthrough device emulation.
- */
-
-/*
- * Copyright (C) 2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-/*******************************************************************************
-* Header Files *
-*******************************************************************************/
-#define LOG_GROUP LOG_GROUP_DEV_PCI
-#include <VBox/vmm/pdmdev.h>
-#include <VBox/log.h>
-#include <VBox/vmm/stam.h>
-#include <iprt/assert.h>
-#include <iprt/string.h>
-
-#include "VBoxDD.h"
-
-/*******************************************************************************
-* Defined Constants And Macros *
-*******************************************************************************/
-/** The version of the saved state. */
-#define PCIRAW_SAVED_STATE_VERSION 1
-
-/*******************************************************************************
- * Structures and Typedefs *
- *******************************************************************************/
-
-/* Temporary PDM stubs */
-typedef struct PDMPCIRAWREG
-{
- /** Struct version+magic number (PDM_PCIRAWREG_VERSION). */
- uint32_t u32Version;
-
-} PDMPCIRAWREG;
-/** Pointer to a raw PCI registration structure. */
-typedef PDMPCIRAWREG *PPDMPCIRAWREG;
-
-/** Current PDMPCIRAWREG version number. */
-#define PDM_PCIRAWREG_VERSION PDM_VERSION_MAKE(0xffe3, 1, 0)
-
-struct PDMPCIRAWHLPRC
-{
- uint32_t u32Version;
-};
-typedef RCPTRTYPE(PDMPCIRAWHLPRC *) PPDMPCIRAWHLPRC;
-typedef RCPTRTYPE(const PDMPCIRAWHLPRC *) PCPDMPCIRAWHLPRC;
-
-struct PDMPCIRAWHLPR0
-{
- uint32_t u32Version;
-};
-typedef R0PTRTYPE(PDMPCIRAWHLPR0 *) PPDMPCIRAWHLPR0;
-typedef R0PTRTYPE(const PDMPCIRAWHLPR0 *) PCPDMPCIRAWHLPR0;
-
-struct PDMPCIRAWHLPR3
-{
- uint32_t u32Version;
- /**
- * Gets the address of the RC PCI raw helpers.
- *
- * This should be called at both construction and relocation time
- * to obtain the correct address of the RC helpers.
- *
- * @returns RC pointer to the PCI raw helpers.
- * @param pDevIns Device instance of the raw PCI device.
- */
- DECLR3CALLBACKMEMBER(PCPDMPCIRAWHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
-
- /**
- * Gets the address of the R0 PCI raw helpers.
- *
- * This should be called at both construction and relocation time
- * to obtain the correct address of the R0 helpers.
- *
- * @returns R0 pointer to the PCI raw helpers.
- * @param pDevIns Device instance of the raw PCI device.
- */
- DECLR3CALLBACKMEMBER(PCPDMPCIRAWHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
-
- /** Just a safety precaution. */
- uint32_t u32TheEnd;
-};
-/** Pointer to raw PCI R3 helpers. */
-typedef R3PTRTYPE(PDMPCIRAWHLPR3 *) PPDMPCIRAWHLPR3;
-/** Pointer to const raw PCI R3 helpers. */
-typedef R3PTRTYPE(const PDMPCIRAWHLPR3 *) PCPDMPCIRAWHLPR3;
-
-/**
- * @copydoc PDMDEVHLPR3::pfnPciRawRegister
- */
-DECLINLINE(int) PDMDevHlpPciRawRegister(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3)
-{
- //return pDevIns->pHlpR3->pfnPciRawRegister(pDevIns, pPciRawReg, ppPciRawHlpR3);
- return VINF_SUCCESS;
-}
-
-/* End of PDM stubs */
-
-typedef struct PciRawState
-{
- /** Pointer to the device instance. - R3 ptr. */
- PPDMDEVINSR3 pDevInsR3;
- /** The PCI raw helpers - R3 Ptr. */
- PCPDMPCIRAWHLPR3 pPciRawHlpR3;
-
- /** Pointer to the device instance. - R0 ptr. */
- PPDMDEVINSR0 pDevInsR0;
- /** The PCI raw helpers - R0 Ptr. */
- PCPDMPCIRAWHLPR0 pPciRawHlpR0;
-
- /** Pointer to the device instance. - RC ptr. */
- PPDMDEVINSRC pDevInsRC;
- /** The PCI raw helpers - RC Ptr. */
- PCPDMPCIRAWHLPRC pPciRawHlpRC;
-
- /* Virtual PCI device */
- PCIDEVICE aPciDevice;
-
- /* Address of device on the host */
- PciBusAddress aHostDeviceAddress;
- /* Address of device in the guest */
- PciBusAddress aGuestDeviceAddress;
-
- /* Global device lock */
- PDMCRITSECT csLock;
-} PciRawState;
-
-
-#ifndef VBOX_DEVICE_STRUCT_TESTCASE
-
-RT_C_DECLS_BEGIN
-PDMBOTHCBDECL(int) pcirawMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) pcirawMMIORead (PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) pcirawIOPortWrite (PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) pcirawIOPortRead (PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t *pu32, unsigned cb);
-RT_C_DECLS_END
-
-/*
- * Temporary control to disable locking if problems found
- */
-DECLINLINE(int) pcirawLock(PciRawState* pThis, int rcBusy)
-{
- return PDMCritSectEnter(&pThis->csLock, rcBusy);
-}
-
-DECLINLINE(void) pcirawUnlock(PciRawState* pThis)
-{
- PDMCritSectLeave(&pThis->csLock);
-}
-
-
-PDMBOTHCBDECL(int) pcirawMMIORead(PPDMDEVINS pDevIns,
- void * pvUser,
- RTGCPHYS GCPhysAddr,
- void * pv,
- unsigned cb)
-{
- PciRawState * pThis = PDMINS_2_DATA(pDevIns, PciRawState*);
- int rc = VINF_SUCCESS;
-
- LogFlow(("pcirawMMIORead: %llx (%x)\n", (uint64_t)GCPhysAddr, cb));
-
- rc = pcirawLock(pThis, VINF_IOM_HC_MMIO_READ);
- if (RT_UNLIKELY(rc != VINF_SUCCESS))
- return rc;
-
- switch (cb)
- {
- case 1:
- case 2:
- case 4:
- case 8:
- {
- break;
- }
-
- default:
- AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
- rc = VINF_SUCCESS;
- }
-
- pcirawUnlock(pThis);
-
- return rc;
-}
-
-PDMBOTHCBDECL(int) pcirawMMIOWrite(PPDMDEVINS pDevIns,
- void * pvUser,
- RTGCPHYS GCPhysAddr,
- void * pv,
- unsigned cb)
-{
- PciRawState *pThis = PDMINS_2_DATA(pDevIns, PciRawState*);
- int rc = VINF_SUCCESS;
-
- LogFlow(("pcirawMMIOWrite: %llx (%d) <- %x\n",
- (uint64_t)GCPhysAddr, cb, *(uint32_t*)pv));
-
- rc = pcirawLock(pThis, VINF_IOM_HC_MMIO_WRITE);
- if (RT_UNLIKELY(rc != VINF_SUCCESS))
- return rc;
-
- switch (cb)
- {
- case 1:
- case 2:
- case 4:
- case 8:
- {
- break;
- }
-
- default:
- AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
- rc = VERR_INTERNAL_ERROR;
- }
-
- pcirawUnlock(pThis);
-
- return rc;
-}
-
-PDMBOTHCBDECL(int) pcirawIOPortWrite (PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t u32, unsigned cb)
-{
- return VINF_SUCCESS;
-}
-
-PDMBOTHCBDECL(int) pcirawIOPortRead (PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t *pu32, unsigned cb)
-{
- return VINF_SUCCESS;
-}
-
-#ifdef IN_RING3
-/**
- * @copydoc FNSSMDEVLIVEEXEC
- */
-static DECLCALLBACK(int) pcirawLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
-{
- PciRawState *pThis = PDMINS_2_DATA(pDevIns, PciRawState *);
-
-
- return VINF_SSM_DONT_CALL_AGAIN;
-}
-
-/**
- * Saves a state of the raw PCI device. Do nothing yet.
- *
- * @returns VBox status code.
- * @param pDevIns The device instance.
- * @param pSSMHandle The handle to save the state to.
- */
-static DECLCALLBACK(int) pcirawSaveExec(PPDMDEVINS pDevIns,
- PSSMHANDLE pSSM)
-{
- PciRawState *pThis = PDMINS_2_DATA(pDevIns, PciRawState *);
-
- /* The config. */
- pcirawLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
-
- return VINF_SUCCESS;
-}
-
-/**
- * Loads a state of the raw PCI device state.
- *
- * @returns VBox status code.
- * @param pDevIns The device instance.
- * @param pSSMHandle The handle to the saved state.
- * @param uVersion The data unit version number.
- * @param uPass The data pass.
- */
-static DECLCALLBACK(int) pcirawLoadExec(PPDMDEVINS pDevIns,
- PSSMHANDLE pSSM,
- uint32_t uVersion,
- uint32_t uPass)
-{
- PciRawState *pThis = PDMINS_2_DATA(pDevIns, PciRawState *);
- int rc;
-
- if (uVersion != PCIRAW_SAVED_STATE_VERSION)
- return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
-
- return VINF_SUCCESS;
-}
-
-/**
- * Relocation notification.
- *
- * @returns VBox status.
- * @param pDevIns The device instance data.
- * @param offDelta The delta relative to the old address.
- */
-static DECLCALLBACK(void) pcirawRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
-{
- PciRawState *pThis = PDMINS_2_DATA(pDevIns, PciRawState *);
- unsigned i;
- LogFlow(("pcirawRelocate:\n"));
-
- pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
- pThis->pPciRawHlpRC = pThis->pPciRawHlpR3->pfnGetRCHelpers(pDevIns);
-}
-
-/**
- * Reset notification.
- *
- * @returns VBox status.
- * @param pDevIns The device instance data.
- */
-static DECLCALLBACK(void) pcirawReset(PPDMDEVINS pDevIns)
-{
- PciRawState *pThis = PDMINS_2_DATA(pDevIns, PciRawState *);
- unsigned i;
-
- LogFlow(("pcirawReset:\n"));
-}
-
-/**
- * Initialization routine.
- *
- * @returns VBox status.
- * @param pDevIns The device instance data.
- */
-static int pcirawInit(PPDMDEVINS pDevIns, PciBusAddress hostAddress)
-{
- unsigned i;
- int rc;
- PciRawState *pThis = PDMINS_2_DATA(pDevIns, PciRawState *);
-
- memset(pThis, 0, sizeof(*pThis));
-
- pThis->pDevInsR3 = pDevIns;
- pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
- pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
-
- pThis->aHostDeviceAddress.init(hostAddress);
-
- pcirawReset(pDevIns);
-
- return VINF_SUCCESS;
-}
-
-/**
- * @interface_method_impl{PDMDEVREG,pfnConstruct}
- */
-static DECLCALLBACK(int) pcirawConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
-{
- PciRawState *pThis = PDMINS_2_DATA(pDevIns, PciRawState *);
- int rc;
- bool fRCEnabled = false;
- bool fR0Enabled = false;
- PDMPCIRAWREG PciRawReg;
-
- /*
- * Validate configuration.
- */
- if (!CFGMR3AreValuesValid(pCfg,
- "GCEnabled\0"
- "R0Enabled\0"
- "HostPCIBusNo\0"
- "HostPCIDeviceNo\0"
- "HostPCIFunctionNo\0"
- ))
- return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
-
- /* Query configuration. */
- rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fRCEnabled, true);
- if (RT_FAILURE(rc))
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("Configuration error: Querying \"GCEnabled\" as a bool failed"));
-
- rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &fR0Enabled, true);
- if (RT_FAILURE(rc))
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("Configuration error: failed to read R0Enabled as boolean"));
-
- /* Obtain host device address */
- uint32_t u32Bus, u32Device, u32Fn;
- rc = CFGMR3QueryU32(pCfg, "HostPCIBusNo", &u32Bus);
- if (RT_FAILURE(rc))
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("Configuration error: Querying \"HostPCIBusNo\" as a int failed"));
- rc = CFGMR3QueryU32(pCfg, "HostPCIDeviceNo", &u32Device);
- if (RT_FAILURE(rc))
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("Configuration error: Querying \"HostPCIDeviceNo\" as a int failed"));
- rc = CFGMR3QueryU32(pCfg, "HostPCIFunctionNo", &u32Fn);
- if (RT_FAILURE(rc))
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("Configuration error: Querying \"HostPCIFunctionNo\" as a int failed"));
-
-
- /* Initialize the device state */
- rc = pcirawInit(pDevIns, PciBusAddress(u32Bus, u32Device, u32Fn));
- if (RT_FAILURE(rc))
- return rc;
-
- pThis->pDevInsR3 = pDevIns;
- pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
- pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
-
- /*
- * Register the raw device and get helpers.
- */
- PciRawReg.u32Version = PDM_PCIRAWREG_VERSION;
- rc = PDMDevHlpPciRawRegister(pDevIns, &PciRawReg, &pThis->pPciRawHlpR3);
- if (RT_FAILURE(rc))
- {
- AssertMsgRC(rc, ("Cannot PciRawRegister: %Rrc\n", rc));
- return rc;
- }
-
- /*
- * Initialize critical section.
- */
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->csLock, RT_SRC_POS, "PCIRAW");
- if (RT_FAILURE(rc))
- return PDMDEV_SET_ERROR(pDevIns, rc, N_("Raw PCI device cannot initialize critical section"));
-
-#if 0
- /*
- * Register IO/MMIO ranges for guest, basing on real device ranges.
- */
- for (int iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++)
- {
-
- }
-#endif
-
- if (fRCEnabled)
- {
- pThis->pPciRawHlpRC = pThis->pPciRawHlpR3->pfnGetRCHelpers(pDevIns);
- if (!pThis->pPciRawHlpRC)
- {
- AssertReleaseMsgFailed(("cannot get RC helper\n"));
- return VERR_INTERNAL_ERROR;
- }
- }
- if (fR0Enabled)
- {
- pThis->pPciRawHlpR0 = pThis->pPciRawHlpR3->pfnGetR0Helpers(pDevIns);
- if (!pThis->pPciRawHlpR0)
- {
- AssertReleaseMsgFailed(("cannot get R0 helper\n"));
- return VERR_INTERNAL_ERROR;
- }
- }
-
- /* Register SSM callbacks */
- rc = PDMDevHlpSSMRegister3(pDevIns, PCIRAW_SAVED_STATE_VERSION, sizeof(*pThis), pcirawLiveExec, pcirawSaveExec, pcirawLoadExec);
- if (RT_FAILURE(rc))
- return rc;
-
- return VINF_SUCCESS;
-}
-
-
-/**
- * The device registration structure.
- */
-const PDMDEVREG g_DevicePciRaw =
-{
- /* u32Version */
- PDM_DEVREG_VERSION,
- /* szName */
- "pciraw",
- /* szRCMod */
- "VBoxDDGC.gc",
- /* szR0Mod */
- "VBoxDDR0.r0",
- /* pszDescription */
- "Raw PCI wrapper Device",
- /* fFlags */
- PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
- /* fClass */
- PDM_DEVREG_CLASS_HOST_DEV,
- /* cMaxInstances */
- ~0,
- /* cbInstance */
- sizeof(PciRawState),
- /* pfnConstruct */
- pcirawConstruct,
- /* pfnDestruct */
- NULL,
- /* pfnRelocate */
- pcirawRelocate,
- /* pfnIOCtl */
- NULL,
- /* pfnPowerOn */
- NULL,
- /* pfnReset */
- pcirawReset,
- /* pfnSuspend */
- NULL,
- /* pfnResume */
- NULL,
- /* pfnAttach */
- NULL,
- /* pfnDetach */
- NULL,
- /* pfnQueryInterface. */
- NULL,
- /* pfnInitComplete */
- NULL,
- /* pfnPowerOff */
- NULL,
- /* pfnSoftReset */
- NULL,
- /* u32VersionEnd */
- PDM_DEVREG_VERSION
-};
-
-#endif /* IN_RING3 */
-
-#endif /* VBOX_DEVICE_STRUCT_TESTCASE */
diff --git a/src/VBox/Devices/Bus/MsiCommon.cpp b/src/VBox/Devices/Bus/MsiCommon.cpp
index 5f5a088fa..ccd935156 100644
--- a/src/VBox/Devices/Bus/MsiCommon.cpp
+++ b/src/VBox/Devices/Bus/MsiCommon.cpp
@@ -1,4 +1,4 @@
-/* $Id: MsiCommon.cpp $ */
+/* $Id: MsiCommon.cpp 36663 2011-04-13 15:57:33Z vboxsync $ */
/** @file
* MSI support routines
*/
@@ -24,6 +24,7 @@
#include "MsiCommon.h"
+/** @todo: use accessors so that raw PCI devices work correctly with MSI. */
DECLINLINE(uint16_t) msiGetMessageControl(PPCIDEVICE pDev)
{
return PCIDevGetWord(pDev, pDev->Int.s.u8MsiCapOffset + VBOX_MSI_CAP_MESSAGE_CONTROL);
@@ -31,7 +32,7 @@ DECLINLINE(uint16_t) msiGetMessageControl(PPCIDEVICE pDev)
DECLINLINE(bool) msiIs64Bit(PPCIDEVICE pDev)
{
- return (msiGetMessageControl(pDev) & VBOX_PCI_MSI_FLAGS_64BIT) != 0;
+ return pciDevIsMsi64Capable(pDev);
}
DECLINLINE(uint32_t*) msiGetMaskBits(PPCIDEVICE pDev)
@@ -100,11 +101,11 @@ DECLINLINE(bool) msiBitJustSet(uint32_t uOldValue,
return (!(uOldValue & uMask) && !!(uNewValue & uMask));
}
-
+#ifdef IN_RING3
void MsiPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len)
{
int32_t iOff = u32Address - pDev->Int.s.u8MsiCapOffset;
- Assert(iOff >= 0 && (PCIIsMsiCapable(pDev) && iOff < pDev->Int.s.u8MsiCapSize));
+ Assert(iOff >= 0 && (pciDevIsMsiCapable(pDev) && iOff < pDev->Int.s.u8MsiCapSize));
Log2(("MsiPciConfigWrite: %d <- %x (%d)\n", iOff, val, len));
@@ -189,7 +190,7 @@ uint32_t MsiPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Addr
{
int32_t iOff = u32Address - pDev->Int.s.u8MsiCapOffset;
- Assert(iOff >= 0 && (PCIIsMsiCapable(pDev) && iOff < pDev->Int.s.u8MsiCapSize));
+ Assert(iOff >= 0 && (pciDevIsMsiCapable(pDev) && iOff < pDev->Int.s.u8MsiCapSize));
uint32_t rv = 0;
switch (len)
@@ -212,12 +213,14 @@ uint32_t MsiPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Addr
return rv;
}
-
int MsiInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg)
{
if (pMsiReg->cMsiVectors == 0)
return VINF_SUCCESS;
+ /* We cannot init MSI on raw devices yet. */
+ Assert(!pciDevIsPassthrough(pDev));
+
uint16_t cVectors = pMsiReg->cMsiVectors;
uint8_t iCapOffset = pMsiReg->iMsiCapOffset;
uint8_t iNextOffset = pMsiReg->iMsiNextOffset;
@@ -254,15 +257,17 @@ int MsiInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg)
*msiGetMaskBits(pDev) = 0;
*msiGetPendingBits(pDev) = 0;
- PCISetMsiCapable(pDev);
+ pciDevSetMsiCapable(pDev);
return VINF_SUCCESS;
}
+#endif /* IN_RING3 */
+
bool MsiIsEnabled(PPCIDEVICE pDev)
{
- return PCIIsMsiCapable(pDev) && msiIsEnabled(pDev);
+ return pciDevIsMsiCapable(pDev) && msiIsEnabled(pDev);
}
void MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel)
diff --git a/src/VBox/Devices/Bus/MsiCommon.h b/src/VBox/Devices/Bus/MsiCommon.h
index 68d7ac6f3..21ce870ba 100644
--- a/src/VBox/Devices/Bus/MsiCommon.h
+++ b/src/VBox/Devices/Bus/MsiCommon.h
@@ -1,4 +1,4 @@
-/* $Id: MsiCommon.h $ */
+/* $Id: MsiCommon.h 36663 2011-04-13 15:57:33Z vboxsync $ */
/** @file
* Header for MSI/MSI-X support routines.
*/
@@ -27,8 +27,10 @@ typedef PCPDMPCIHLPR0 PCPDMPCIHLP;
typedef PCPDMPCIHLPRC PCPDMPCIHLP;
#endif
+#ifdef IN_RING3
/* Init MSI support in the device. */
int MsiInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg);
+#endif
/* If MSI is enabled, so that MSINotify() shall be used for notifications. */
bool MsiIsEnabled(PPCIDEVICE pDev);
@@ -36,13 +38,14 @@ bool MsiIsEnabled(PPCIDEVICE pDev);
/* Device notification (aka interrupt). */
void MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel);
+#ifdef IN_RING3
/* PCI config space accessors for MSI registers */
void MsiPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len);
uint32_t MsiPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, unsigned len);
+#endif
-
-/* Init MSI-X support in the device. */
#ifdef IN_RING3
+/* Init MSI-X support in the device. */
int MsixInit(PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, PPDMMSIREG pMsiReg);
#endif
@@ -52,6 +55,8 @@ bool MsixIsEnabled(PPCIDEVICE pDev);
/* Device notification (aka interrupt). */
void MsixNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel);
+#ifdef IN_RING3
/* PCI config space accessors for MSI-X */
void MsixPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len);
uint32_t MsixPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, unsigned len);
+#endif
diff --git a/src/VBox/Devices/Bus/MsixCommon.cpp b/src/VBox/Devices/Bus/MsixCommon.cpp
index 49917f746..038336f02 100644
--- a/src/VBox/Devices/Bus/MsixCommon.cpp
+++ b/src/VBox/Devices/Bus/MsixCommon.cpp
@@ -1,4 +1,4 @@
-/* $Id: MsixCommon.cpp $ */
+/* $Id: MsixCommon.cpp 37636 2011-06-24 14:59:59Z vboxsync $ */
/** @file
* MSI-X support routines
*/
@@ -28,7 +28,8 @@
#include "MsiCommon.h"
#pragma pack(1)
-typedef struct {
+typedef struct
+{
uint32_t u32MsgAddressLo;
uint32_t u32MsgAddressHi;
uint32_t u32MsgData;
@@ -37,6 +38,7 @@ typedef struct {
AssertCompileSize(MsixTableRecord, VBOX_MSIX_ENTRY_SIZE);
#pragma pack()
+/** @todo: use accessors so that raw PCI devices work correctly with MSI-X. */
DECLINLINE(uint16_t) msixGetMessageControl(PPCIDEVICE pDev)
{
return PCIDevGetWord(pDev, pDev->Int.s.u8MsixCapOffset + VBOX_MSIX_CAP_MESSAGE_CONTROL);
@@ -126,7 +128,7 @@ PDMBOTHCBDECL(int) msixMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhy
return VINF_SUCCESS;
}
-PDMBOTHCBDECL(int) msixMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+PDMBOTHCBDECL(int) msixMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
/// @todo: qword accesses?
AssertMsgReturn(cb == 4,
@@ -165,24 +167,37 @@ int MsixInit(PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, PPDMMSIREG pMsiReg)
if (pMsiReg->cMsixVectors == 0)
return VINF_SUCCESS;
+ /* We cannot init MSI-X on raw devices yet. */
+ Assert(!pciDevIsPassthrough(pDev));
+
uint16_t cVectors = pMsiReg->cMsixVectors;
uint8_t iCapOffset = pMsiReg->iMsixCapOffset;
uint8_t iNextOffset = pMsiReg->iMsixNextOffset;
uint8_t iBar = pMsiReg->iMsixBar;
if (cVectors > VBOX_MSIX_MAX_ENTRIES)
+ {
+ AssertMsgFailed(("Too many MSI-X vectors: %d\n", cVectors));
return VERR_TOO_MUCH_DATA;
+ }
if (iBar > 5)
+ {
+ AssertMsgFailed(("Using wrong BAR for MSI-X: %d\n", iBar));
return VERR_INVALID_PARAMETER;
+ }
Assert(iCapOffset != 0 && iCapOffset < 0xff && iNextOffset < 0xff);
- int rc;
+ int rc = VINF_SUCCESS;
- rc = PDMDevHlpPCIIORegionRegister (pDev->pDevIns, iBar, 0x1000, PCI_ADDRESS_SPACE_MEM, msixMap);
- if (RT_FAILURE (rc))
- return rc;
+ /* If device is passthrough, BAR is registered using common mechanism. */
+ if (!pciDevIsPassthrough(pDev))
+ {
+ rc = PDMDevHlpPCIIORegionRegister (pDev->pDevIns, iBar, 0x1000, PCI_ADDRESS_SPACE_MEM, msixMap);
+ if (RT_FAILURE (rc))
+ return rc;
+ }
pDev->Int.s.u8MsixCapOffset = iCapOffset;
pDev->Int.s.u8MsixCapSize = VBOX_MSIX_CAP_SIZE;
@@ -209,7 +224,7 @@ int MsixInit(PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, PPDMMSIREG pMsiReg)
PCIDevSetDWord(pDev, iCapOffset + VBOX_MSIX_TABLE_BIROFFSET, offTable | iBar);
PCIDevSetDWord(pDev, iCapOffset + VBOX_MSIX_PBA_BIROFFSET, offPBA | iBar);
- PCISetMsixCapable(pDev);
+ pciDevSetMsixCapable(pDev);
return VINF_SUCCESS;
}
@@ -217,7 +232,7 @@ int MsixInit(PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, PPDMMSIREG pMsiReg)
bool MsixIsEnabled(PPCIDEVICE pDev)
{
- return PCIIsMsixCapable(pDev) && msixIsEnabled(pDev);
+ return pciDevIsMsixCapable(pDev) && msixIsEnabled(pDev);
}
void MsixNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel)
@@ -266,7 +281,7 @@ static void msixCheckPendingVectors(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPC
void MsixPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len)
{
int32_t iOff = u32Address - pDev->Int.s.u8MsixCapOffset;
- Assert(iOff >= 0 && (PCIIsMsixCapable(pDev) && iOff < pDev->Int.s.u8MsixCapSize));
+ Assert(iOff >= 0 && (pciDevIsMsixCapable(pDev) && iOff < pDev->Int.s.u8MsixCapSize));
Log2(("MsixPciConfigWrite: %d <- %x (%d)\n", iOff, val, len));
@@ -311,7 +326,7 @@ uint32_t MsixPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Add
{
int32_t iOff = u32Address - pDev->Int.s.u8MsixCapOffset;
- Assert(iOff >= 0 && (PCIIsMsixCapable(pDev) && iOff < pDev->Int.s.u8MsixCapSize));
+ Assert(iOff >= 0 && (pciDevIsMsixCapable(pDev) && iOff < pDev->Int.s.u8MsixCapSize));
uint32_t rv = 0;
switch (len)
diff --git a/src/VBox/Devices/Bus/PCIInternal.h b/src/VBox/Devices/Bus/PCIInternal.h
index c3f3b9c6e..82faa8810 100644
--- a/src/VBox/Devices/Bus/PCIInternal.h
+++ b/src/VBox/Devices/Bus/PCIInternal.h
@@ -1,4 +1,4 @@
-/* $Id: PCIInternal.h $ */
+/* $Id: PCIInternal.h 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
* DevPCI - PCI Internal header - Only for hiding bits of PCIDEVICE.
*/
@@ -23,10 +23,9 @@
*/
typedef struct PCIIOREGION
{
- /** Current PCI mapping address, 0xffffffff means not mapped.
- @todo: make address and size 64-bit. */
- uint32_t addr;
- uint32_t size;
+ /** Current PCI mapping address, 0xffffffff means not mapped. */
+ uint64_t addr;
+ uint64_t size;
uint8_t type; /* PCIADDRESSSPACE */
uint8_t padding[HC_ARCH_BITS == 32 ? 3 : 7];
/** Callback called when the region is mapped. */
@@ -86,7 +85,12 @@ enum {
PCIDEV_FLAG_MSI_CAPABLE = 1<<3,
/** Flag whether the device is capable of MSI-X.
* This one is set by MsixInit(). */
- PCIDEV_FLAG_MSIX_CAPABLE = 1<<4
+ PCIDEV_FLAG_MSIX_CAPABLE = 1<<4,
+ /** Flag if device represents real physical device in passthrough mode. */
+ PCIDEV_FLAG_PASSTHROUGH = 1<<5,
+ /** Flag whether the device is capable of MSI using 64-bit address. */
+ PCIDEV_FLAG_MSI64_CAPABLE = 1<<6
+
};
/**
@@ -96,21 +100,21 @@ typedef struct PCIDEVICEINT
{
/** I/O regions. */
PCIIOREGION aIORegions[PCI_NUM_REGIONS];
- /** Pointer to the PCI bus of the device. - R3 ptr */
+ /** Pointer to the PCI bus of the device. (R3 ptr) */
R3PTRTYPE(struct PCIBus *) pBusR3;
- /** Pointer to the PCI bus of the device. - R0 ptr */
+ /** Pointer to the PCI bus of the device. (R0 ptr) */
R0PTRTYPE(struct PCIBus *) pBusR0;
- /** Pointer to the PCI bus of the device. - RC ptr */
+ /** Pointer to the PCI bus of the device. (RC ptr) */
RCPTRTYPE(struct PCIBus *) pBusRC;
#if HC_ARCH_BITS == 64
RTRCPTR Alignment0;
#endif
- /* Page used for MSI-X state. - R3 ptr */
+ /** Page used for MSI-X state. (R3 ptr) */
R3PTRTYPE(void*) pMsixPageR3;
- /* Page used for MSI-X state. - R0 ptr */
+ /** Page used for MSI-X state. (R0 ptr) */
R0PTRTYPE(void*) pMsixPageR0;
- /* Page used for MSI-X state. - RC ptr */
+ /** Page used for MSI-X state. (RC ptr) */
RCPTRTYPE(void*) pMsixPageRC;
#if HC_ARCH_BITS == 64
RTRCPTR Alignment1;
@@ -122,23 +126,23 @@ typedef struct PCIDEVICEINT
/** Write config callback. */
R3PTRTYPE(PFNPCICONFIGWRITE) pfnConfigWrite;
- /* Flags of this PCI device, see PCIDEV_FLAG_ constants */
- uint32_t uFlags;
+ /** Flags of this PCI device, see PCIDEV_FLAG_XXX constants. */
+ uint32_t fFlags;
/** Current state of the IRQ pin of the device. */
int32_t uIrqPinState;
- /* Offset of MSI PCI capability in config space, or 0 */
+ /** Offset of MSI PCI capability in config space, or 0. */
uint8_t u8MsiCapOffset;
- /* Size of MSI PCI capability in config space, or 0 */
+ /** Size of MSI PCI capability in config space, or 0. */
uint8_t u8MsiCapSize;
- /* Offset of MSI-X PCI capability in config space, or 0 */
+ /** Offset of MSI-X PCI capability in config space, or 0. */
uint8_t u8MsixCapOffset;
- /* Size of MSI-X PCI capability in config space, or 0 */
+ /** Size of MSI-X PCI capability in config space, or 0. */
uint8_t u8MsixCapSize;
uint32_t Alignment2;
- /* Pointer to bus specific data. - R3 ptr */
+ /** Pointer to bus specific data. (R3 ptr) */
R3PTRTYPE(const void*) pPciBusPtrR3;
/** Read config callback for PCI bridges to pass requests
@@ -152,7 +156,7 @@ typedef struct PCIDEVICEINT
} PCIDEVICEINT;
-/* Indicate that PCIDEVICE::Int.s can be declared. */
+/** Indicate that PCIDEVICE::Int.s can be declared. */
#define PCIDEVICEINT_DECLARED
#endif
diff --git a/src/VBox/Devices/Bus/SrvPciRawR0.cpp b/src/VBox/Devices/Bus/SrvPciRawR0.cpp
new file mode 100644
index 000000000..084d5fdc6
--- /dev/null
+++ b/src/VBox/Devices/Bus/SrvPciRawR0.cpp
@@ -0,0 +1,1031 @@
+/* $Id: SrvPciRawR0.cpp 37810 2011-07-07 08:36:00Z vboxsync $ */
+/** @file
+ * PCI passthrough - The ring 0 service.
+ */
+
+/*
+ * 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 *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_DEV_PCI_RAW
+#include <VBox/log.h>
+#include <VBox/sup.h>
+#include <VBox/rawpci.h>
+#include <VBox/vmm/pdmpci.h>
+#include <VBox/vmm/pdm.h>
+#include <VBox/vmm/gvm.h>
+#include <VBox/vmm/gvmm.h>
+#include <VBox/vmm/vm.h>
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/handletable.h>
+#include <iprt/mp.h>
+#include <iprt/mem.h>
+#include <iprt/semaphore.h>
+#include <iprt/spinlock.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
+#include <iprt/time.h>
+#include <iprt/asm-amd64-x86.h>
+
+typedef struct PCIRAWSRVSTATE
+{
+ /** Structure lock. */
+ RTSPINLOCK hSpinlock;
+
+ /** Handle table for devices. */
+ RTHANDLETABLE hHtDevs;
+
+} PCIRAWSRVSTATE;
+typedef PCIRAWSRVSTATE *PPCIRAWSRVSTATE;
+
+typedef struct PCIRAWDEV
+{
+ /* Port pointer. */
+ PRAWPCIDEVPORT pPort;
+
+ /* Handle used by everybody else. */
+ PCIRAWDEVHANDLE hHandle;
+
+ /** The session this device is associated with. */
+ PSUPDRVSESSION pSession;
+
+ /** Structure lock. */
+ RTSPINLOCK hSpinlock;
+
+ /** Event for IRQ updates. */
+ RTSEMEVENT hIrqEvent;
+
+ /** Current pending IRQ for the device. */
+ int32_t iPendingIrq;
+
+ /** ISR handle. */
+ PCIRAWISRHANDLE hIsr;
+
+ /* If object is being destroyed. */
+ bool fTerminate;
+
+ /** The SUPR0 object. */
+ void *pvObj;
+} PCIRAWDEV;
+typedef PCIRAWDEV *PPCIRAWDEV;
+
+static PCIRAWSRVSTATE g_State;
+
+/* Interrupt handler. Could be called in the interrupt context,
+ * depending on host OS implmenetation. */
+static DECLCALLBACK(bool) pcirawr0Isr(void* pContext, int32_t iHostIrq)
+{
+ RTSPINLOCKTMP aTmp;
+ PPCIRAWDEV pThis = (PPCIRAWDEV)pContext;
+
+#ifdef VBOX_WITH_SHARED_PCI_INTERRUPTS
+ uint16_t uStatus;
+ PCIRAWMEMLOC Loc;
+ int rc;
+
+ Loc.cb = 2;
+ rc = pThis->pPort->pfnPciCfgRead(pThis->pPort, VBOX_PCI_STATUS, &Loc);
+ /* Cannot read, assume non-shared. */
+ if (RT_FAILURE(rc))
+ return false;
+
+ /* Check interrupt status bit. */
+ if ((Loc.u.u16 & (1 << 3)) == 0)
+ return false;
+#endif
+
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &aTmp);
+ pThis->iPendingIrq = iHostIrq;
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &aTmp);
+
+ /**
+ * @todo: RTSemEventSignal() docs claims that it's platform-dependent
+ * if RTSemEventSignal() could be called from the ISR, but it seems IPRT
+ * doesn't provide primitives that guaranteed to work this way.
+ */
+ RTSemEventSignal(pThis->hIrqEvent);
+
+ return true;
+}
+
+static DECLCALLBACK(int) pcirawr0DevRetainHandle(RTHANDLETABLE hHandleTable, void *pvObj, void *pvCtx, void *pvUser)
+{
+ NOREF(pvUser);
+ NOREF(hHandleTable);
+ PPCIRAWDEV pDev = (PPCIRAWDEV)pvObj;
+ if (pDev->hHandle != 0)
+ return SUPR0ObjAddRefEx(pDev->pvObj, (PSUPDRVSESSION)pvCtx, true /* fNoBlocking */);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Initializes the raw PCI ring-0 service.
+ *
+ * @returns VBox status code.
+ */
+PCIRAWR0DECL(int) PciRawR0Init(void)
+{
+ LogFlow(("PciRawR0Init:\n"));
+ int rc = VINF_SUCCESS;
+
+ rc = RTHandleTableCreateEx(&g_State.hHtDevs, RTHANDLETABLE_FLAGS_LOCKED | RTHANDLETABLE_FLAGS_CONTEXT,
+ UINT32_C(0xfefe0000), 4096, pcirawr0DevRetainHandle, NULL);
+
+ LogFlow(("PciRawR0Init: returns %Rrc\n", rc));
+ return rc;
+}
+
+/**
+ * Destroys raw PCI ring-0 service.
+ */
+PCIRAWR0DECL(void) PciRawR0Term(void)
+{
+ LogFlow(("PciRawR0Term:\n"));
+ RTHandleTableDestroy(g_State.hHtDevs, NULL, NULL);
+ g_State.hHtDevs = NIL_RTHANDLETABLE;
+}
+
+
+/**
+ * Per-VM R0 module init.
+ */
+PCIRAWR0DECL(int) PciRawR0InitVM(PVM pVM)
+{
+ PRAWPCIFACTORY pFactory = NULL;
+ int rc;
+
+ rc = SUPR0ComponentQueryFactory(pVM->pSession, "VBoxRawPci", RAWPCIFACTORY_UUID_STR, (void **)&pFactory);
+
+ if (RT_SUCCESS(rc))
+ {
+ if (pFactory)
+ {
+ PGVM pGVM = NULL;
+ rc = GVMMR0ByVM(pVM, &pGVM);
+ if (RT_SUCCESS(rc))
+ rc = pFactory->pfnInitVm(pFactory, pVM, &pGVM->rawpci.s);
+ pFactory->pfnRelease(pFactory);
+ }
+ }
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * Per-VM R0 module termination routine.
+ */
+PCIRAWR0DECL(void) PciRawR0TermVM(PVM pVM)
+{
+ PRAWPCIFACTORY pFactory = NULL;
+ int rc;
+
+ rc = SUPR0ComponentQueryFactory(pVM->pSession, "VBoxRawPci", RAWPCIFACTORY_UUID_STR, (void **)&pFactory);
+
+ if (RT_SUCCESS(rc))
+ {
+ if (pFactory)
+ {
+ PGVM pGVM = NULL;
+ rc = GVMMR0ByVM(pVM, &pGVM);
+ if (RT_SUCCESS(rc))
+ pFactory->pfnDeinitVm(pFactory, pVM, &pGVM->rawpci.s);
+ pFactory->pfnRelease(pFactory);
+ }
+ }
+}
+
+static int pcirawr0DevTerm(PPCIRAWDEV pThis, int32_t fFlags)
+{
+ ASMAtomicWriteBool(&pThis->fTerminate, true);
+
+ if (pThis->hIrqEvent)
+ RTSemEventSignal(pThis->hIrqEvent);
+
+ /* Enable that, once figure our how to make sure
+ IRQ getter thread notified and woke up. */
+#if 0
+ if (pThis->hIrqEvent)
+ {
+ RTSemEventDestroy(pThis->hIrqEvent);
+ pThis->hIrqEvent = NIL_RTSEMEVENT;
+ }
+#endif
+
+ if (pThis->hSpinlock)
+ {
+ RTSpinlockDestroy(pThis->hSpinlock);
+ pThis->hSpinlock = NIL_RTSPINLOCK;
+ }
+
+ /* Forcefully deinit. */
+ return pThis->pPort->pfnDeinit(pThis->pPort, fFlags);
+}
+
+#define GET_PORT(hDev) \
+ PPCIRAWDEV pDev = (PPCIRAWDEV)RTHandleTableLookupWithCtx(g_State.hHtDevs, hDev, pSession); \
+ if (!pDev) \
+ return VERR_INVALID_HANDLE; \
+ PRAWPCIDEVPORT pDevPort = pDev->pPort; \
+ AssertReturn(pDevPort != NULL, VERR_INVALID_PARAMETER); \
+ AssertReturn(pDevPort->u32Version == RAWPCIDEVPORT_VERSION, VERR_INVALID_PARAMETER); \
+ AssertReturn(pDevPort->u32VersionEnd == RAWPCIDEVPORT_VERSION, VERR_INVALID_PARAMETER);
+
+#define PUT_PORT() if (pDev->pvObj) SUPR0ObjRelease(pDev->pvObj, pSession)
+
+#ifdef DEBUG_nike
+
+/* Code to perform debugging without host driver. */
+typedef struct DUMMYRAWPCIINS
+{
+ /* Host PCI address of this device. */
+ uint32_t HostPciAddress;
+ /* Padding */
+ uint32_t pad0;
+
+ uint8_t aPciCfg[256];
+
+ /** Port, given to the outside world. */
+ RAWPCIDEVPORT DevPort;
+} DUMMYRAWPCIINS;
+typedef struct DUMMYRAWPCIINS *PDUMMYRAWPCIINS;
+
+#define DEVPORT_2_DUMMYRAWPCIINS(pPort) \
+ ( (PDUMMYRAWPCIINS)((uint8_t *)pPort - RT_OFFSETOF(DUMMYRAWPCIINS, DevPort)) )
+
+static uint8_t dummyPciGetByte(PDUMMYRAWPCIINS pThis, uint32_t iRegister)
+{
+ return pThis->aPciCfg[iRegister];
+}
+
+static void dummyPciSetByte(PDUMMYRAWPCIINS pThis, uint32_t iRegister, uint8_t u8)
+{
+ pThis->aPciCfg[iRegister] = u8;
+}
+
+static uint16_t dummyPciGetWord(PDUMMYRAWPCIINS pThis, uint32_t iRegister)
+{
+ uint16_t u16Value = *(uint16_t*)&pThis->aPciCfg[iRegister];
+ return RT_H2LE_U16(u16Value);
+}
+
+static void dummyPciSetWord(PDUMMYRAWPCIINS pThis, uint32_t iRegister, uint16_t u16)
+{
+ *(uint16_t*)&pThis->aPciCfg[iRegister] = RT_H2LE_U16(u16);
+}
+
+static uint32_t dummyPciGetDWord(PDUMMYRAWPCIINS pThis, uint32_t iRegister)
+{
+ uint32_t u32Value = *(uint32_t*)&pThis->aPciCfg[iRegister];
+ return RT_H2LE_U32(u32Value);
+}
+
+static void dummyPciSetDWord(PDUMMYRAWPCIINS pThis, uint32_t iRegister, uint32_t u32)
+{
+ *(uint32_t*)&pThis->aPciCfg[iRegister] = RT_H2LE_U32(u32);
+}
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnInit
+ */
+static DECLCALLBACK(int) dummyPciDevInit(PRAWPCIDEVPORT pPort, uint32_t fFlags)
+{
+ PDUMMYRAWPCIINS pThis = DEVPORT_2_DUMMYRAWPCIINS(pPort);
+
+ dummyPciSetWord(pThis, VBOX_PCI_VENDOR_ID, 0xccdd);
+ dummyPciSetWord(pThis, VBOX_PCI_DEVICE_ID, 0xeeff);
+ dummyPciSetWord(pThis, VBOX_PCI_COMMAND, PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS | PCI_COMMAND_BUSMASTER);
+ dummyPciSetByte(pThis, VBOX_PCI_INTERRUPT_PIN, 1);
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnDeinit
+ */
+static DECLCALLBACK(int) dummyPciDevDeinit(PRAWPCIDEVPORT pPort, uint32_t fFlags)
+{
+ PDUMMYRAWPCIINS pThis = DEVPORT_2_DUMMYRAWPCIINS(pPort);
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnDestroy
+ */
+static DECLCALLBACK(int) dummyPciDevDestroy(PRAWPCIDEVPORT pPort)
+{
+ PDUMMYRAWPCIINS pThis = DEVPORT_2_DUMMYRAWPCIINS(pPort);
+
+ RTMemFree(pThis);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnGetRegionInfo
+ */
+static DECLCALLBACK(int) dummyPciDevGetRegionInfo(PRAWPCIDEVPORT pPort,
+ int32_t iRegion,
+ RTHCPHYS *pRegionStart,
+ uint64_t *pu64RegionSize,
+ bool *pfPresent,
+ uint32_t *pfFlags)
+{
+ PDUMMYRAWPCIINS pThis = DEVPORT_2_DUMMYRAWPCIINS(pPort);
+
+ if (iRegion == 0)
+ {
+ *pfPresent = true;
+ *pRegionStart = 0xfef0;
+ *pu64RegionSize = 0x10;
+ *pfFlags = PCIRAW_ADDRESS_SPACE_IO;
+ }
+ else if (iRegion == 2)
+ {
+ *pfPresent = true;
+ *pRegionStart = 0xffff0000;
+ *pu64RegionSize = 0x1000;
+ *pfFlags = PCIRAW_ADDRESS_SPACE_BAR64 | PCIRAW_ADDRESS_SPACE_MEM;
+ }
+ else
+ *pfPresent = false;
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnMapRegion
+ */
+static DECLCALLBACK(int) dummyPciDevMapRegion(PRAWPCIDEVPORT pPort,
+ int32_t iRegion,
+ RTHCPHYS HCRegionStart,
+ uint64_t u64RegionSize,
+ int32_t fFlags,
+ RTR0PTR *pRegionBase)
+{
+ PDUMMYRAWPCIINS pThis = DEVPORT_2_DUMMYRAWPCIINS(pPort);
+ return VINF_SUCCESS;
+}
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnUnapRegion
+ */
+static DECLCALLBACK(int) dummyPciDevUnmapRegion(PRAWPCIDEVPORT pPort,
+ int32_t iRegion,
+ RTHCPHYS HCRegionStart,
+ uint64_t u64RegionSize,
+ RTR0PTR RegionBase)
+{
+ PDUMMYRAWPCIINS pThis = DEVPORT_2_DUMMYRAWPCIINS(pPort);
+ return VINF_SUCCESS;
+}
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnPciCfgRead
+ */
+static DECLCALLBACK(int) dummyPciDevPciCfgRead(PRAWPCIDEVPORT pPort,
+ uint32_t Register,
+ PCIRAWMEMLOC *pValue)
+{
+ PDUMMYRAWPCIINS pThis = DEVPORT_2_DUMMYRAWPCIINS(pPort);
+
+ switch (pValue->cb)
+ {
+ case 1:
+ pValue->u.u8 = dummyPciGetByte(pThis, Register);
+ break;
+ case 2:
+ pValue->u.u16 = dummyPciGetWord(pThis, Register);
+ break;
+ case 4:
+ pValue->u.u32 = dummyPciGetDWord(pThis, Register);
+ break;
+ }
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnPciCfgWrite
+ */
+static DECLCALLBACK(int) dummyPciDevPciCfgWrite(PRAWPCIDEVPORT pPort,
+ uint32_t Register,
+ PCIRAWMEMLOC *pValue)
+{
+ PDUMMYRAWPCIINS pThis = DEVPORT_2_DUMMYRAWPCIINS(pPort);
+
+ switch (pValue->cb)
+ {
+ case 1:
+ dummyPciSetByte(pThis, Register, pValue->u.u8);
+ break;
+ case 2:
+ dummyPciSetWord(pThis, Register, pValue->u.u16);
+ break;
+ case 4:
+ dummyPciSetDWord(pThis, Register, pValue->u.u32);
+ break;
+ }
+
+ return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) dummyPciDevRegisterIrqHandler(PRAWPCIDEVPORT pPort,
+ PFNRAWPCIISR pfnHandler,
+ void* pIrqContext,
+ PCIRAWISRHANDLE *phIsr)
+{
+ PDUMMYRAWPCIINS pThis = DEVPORT_2_DUMMYRAWPCIINS(pPort);
+ return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) dummyPciDevUnregisterIrqHandler(PRAWPCIDEVPORT pPort,
+ PCIRAWISRHANDLE hIsr)
+{
+ PDUMMYRAWPCIINS pThis = DEVPORT_2_DUMMYRAWPCIINS(pPort);
+ return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) dummyPciDevPowerStateChange(PRAWPCIDEVPORT pPort,
+ PCIRAWPOWERSTATE aState,
+ uint64_t *pu64Param)
+{
+ PDUMMYRAWPCIINS pThis = DEVPORT_2_DUMMYRAWPCIINS(pPort);
+ return VINF_SUCCESS;
+}
+
+static PRAWPCIDEVPORT pcirawr0CreateDummyDevice(uint32_t HostDevice, uint32_t fFlags)
+{
+ PDUMMYRAWPCIINS pNew = (PDUMMYRAWPCIINS)RTMemAllocZ(sizeof(*pNew));
+ if (!pNew)
+ return NULL;
+
+ pNew->HostPciAddress = HostDevice;
+
+ pNew->DevPort.u32Version = RAWPCIDEVPORT_VERSION;
+ pNew->DevPort.pfnInit = dummyPciDevInit;
+ pNew->DevPort.pfnDeinit = dummyPciDevDeinit;
+ pNew->DevPort.pfnDestroy = dummyPciDevDestroy;
+ pNew->DevPort.pfnGetRegionInfo = dummyPciDevGetRegionInfo;
+ pNew->DevPort.pfnMapRegion = dummyPciDevMapRegion;
+ pNew->DevPort.pfnUnmapRegion = dummyPciDevUnmapRegion;
+ pNew->DevPort.pfnPciCfgRead = dummyPciDevPciCfgRead;
+ pNew->DevPort.pfnPciCfgWrite = dummyPciDevPciCfgWrite;
+ pNew->DevPort.pfnRegisterIrqHandler = dummyPciDevRegisterIrqHandler;
+ pNew->DevPort.pfnUnregisterIrqHandler = dummyPciDevUnregisterIrqHandler;
+ pNew->DevPort.pfnPowerStateChange = dummyPciDevPowerStateChange;
+
+ pNew->DevPort.u32VersionEnd = RAWPCIDEVPORT_VERSION;
+
+ return &pNew->DevPort;
+}
+#endif
+
+static DECLCALLBACK(void) pcirawr0DevObjDestructor(void *pvObj, void *pvIns, void *pvUnused)
+{
+ PPCIRAWDEV pThis = (PPCIRAWDEV)pvIns;
+
+ /* Forcefully deinit. */
+ pcirawr0DevTerm(pThis, 0);
+
+ /* And destroy. */
+ pThis->pPort->pfnDestroy(pThis->pPort);
+
+ RTMemFree(pThis);
+}
+
+
+static int pcirawr0OpenDevice(PSUPDRVSESSION pSession,
+ PVM pVM,
+ uint32_t HostDevice,
+ uint32_t fFlags,
+ PCIRAWDEVHANDLE *pHandle,
+ uint32_t *pfDevFlags)
+{
+ /*
+ * Query the factory we want, then use it create and connect the host device.
+ */
+ PRAWPCIFACTORY pFactory = NULL;
+ PRAWPCIDEVPORT pDevPort = NULL;
+ int rc;
+ PPCIRAWDEV pNew;
+
+ pNew = (PPCIRAWDEV)RTMemAllocZ(sizeof(*pNew));
+ if (!pNew)
+ return VERR_NO_MEMORY;
+
+
+ rc = SUPR0ComponentQueryFactory(pSession, "VBoxRawPci", RAWPCIFACTORY_UUID_STR, (void **)&pFactory);
+ /* No host driver registered, provide some fake implementation
+ for debugging purposes. */
+#ifdef DEBUG_nike
+ if (rc == VERR_SUPDRV_COMPONENT_NOT_FOUND)
+ {
+ pDevPort = pcirawr0CreateDummyDevice(HostDevice, fFlags);
+ if (pDevPort)
+ {
+ pDevPort->pfnInit(pDevPort, fFlags);
+ rc = VINF_SUCCESS;
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ }
+#endif
+
+ if (RT_SUCCESS(rc))
+ {
+ if (pFactory)
+ {
+ PGVM pGVM = NULL;
+ rc = GVMMR0ByVM(pVM, &pGVM);
+
+ if (RT_SUCCESS(rc))
+ rc = pFactory->pfnCreateAndConnect(pFactory,
+ HostDevice,
+ fFlags,
+ &pGVM->rawpci.s,
+ &pDevPort,
+ pfDevFlags);
+ pFactory->pfnRelease(pFactory);
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTSpinlockCreate(&pNew->hSpinlock);
+ AssertRC(rc);
+ rc = RTSemEventCreate(&pNew->hIrqEvent);
+ AssertRC(rc);
+
+ pNew->pSession = pSession;
+ pNew->pPort = pDevPort;
+ pNew->pvObj = SUPR0ObjRegister(pSession, SUPDRVOBJTYPE_RAW_PCI_DEVICE,
+ pcirawr0DevObjDestructor, pNew, NULL);
+
+ uint32_t hHandle = 0;
+ rc = RTHandleTableAllocWithCtx(g_State.hHtDevs, pNew, pSession, &hHandle);
+ if (RT_SUCCESS(rc))
+ {
+ pNew->hHandle = (PCIRAWDEVHANDLE)hHandle;
+ *pHandle = pNew->hHandle;
+ }
+ else
+ {
+ SUPR0ObjRelease(pNew->pvObj, pSession);
+ RTSpinlockDestroy(pNew->hSpinlock);
+ RTSemEventDestroy(pNew->hIrqEvent);
+ }
+ }
+ }
+
+ if (RT_FAILURE(rc))
+ RTMemFree(pNew);
+
+ return rc;
+}
+
+static int pcirawr0CloseDevice(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice,
+ uint32_t fFlags)
+{
+ GET_PORT(TargetDevice);
+ int rc;
+
+ pDevPort->pfnUnregisterIrqHandler(pDevPort, pDev->hIsr);
+ pDev->hIsr = 0;
+
+ rc = pcirawr0DevTerm(pDev, fFlags);
+
+ RTHandleTableFreeWithCtx(g_State.hHtDevs, TargetDevice, pSession);
+
+ PUT_PORT();
+
+ return rc;
+}
+
+/* We may want to call many functions here directly, so no static */
+static int pcirawr0GetRegionInfo(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice,
+ int32_t iRegion,
+ RTHCPHYS *pRegionStart,
+ uint64_t *pu64RegionSize,
+ bool *pfPresent,
+ uint32_t *pfFlags)
+{
+ LogFlow(("pcirawr0GetRegionInfo: %d\n", iRegion));
+ GET_PORT(TargetDevice);
+
+ int rc = pDevPort->pfnGetRegionInfo(pDevPort, iRegion, pRegionStart, pu64RegionSize, pfPresent, pfFlags);
+
+ PUT_PORT();
+
+ return rc;
+}
+
+static int pcirawr0MapRegion(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice,
+ int32_t iRegion,
+ RTHCPHYS HCRegionStart,
+ uint64_t u64RegionSize,
+ uint32_t fFlags,
+ RTR3PTR *ppvAddressR3,
+ RTR0PTR *ppvAddressR0)
+{
+ LogFlow(("pcirawr0MapRegion\n"));
+ GET_PORT(TargetDevice);
+ int rc;
+
+ rc = pDevPort->pfnMapRegion(pDevPort, iRegion, HCRegionStart, u64RegionSize, fFlags, ppvAddressR0);
+ if (RT_SUCCESS(rc))
+ {
+ Assert(*ppvAddressR0 != NULL);
+
+ /* Do we need to do something to help with R3 mapping, if ((fFlags & PCIRAWRFLAG_ALLOW_R3MAP) != 0) */
+ }
+
+ *ppvAddressR3 = 0;
+
+ PUT_PORT();
+
+ return rc;
+}
+
+static int pcirawr0UnmapRegion(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice,
+ int32_t iRegion,
+ RTHCPHYS HCRegionStart,
+ uint64_t u64RegionSize,
+ RTR3PTR pvAddressR3,
+ RTR0PTR pvAddressR0)
+{
+ LogFlow(("pcirawr0UnmapRegion\n"));
+ int rc;
+
+ GET_PORT(TargetDevice);
+
+ rc = pDevPort->pfnUnmapRegion(pDevPort, iRegion, HCRegionStart, u64RegionSize, pvAddressR0);
+
+ PUT_PORT();
+
+ return rc;
+}
+
+static int pcirawr0PioWrite(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice,
+ uint16_t Port,
+ uint32_t u32,
+ unsigned cb)
+{
+ /// @todo: add check that port fits into device range
+ switch (cb)
+ {
+ case 1:
+ ASMOutU8 (Port, u32);
+ break;
+ case 2:
+ ASMOutU16(Port, u32);
+ break;
+ case 4:
+ ASMOutU32(Port, u32);
+ break;
+ default:
+ AssertMsgFailed(("Unhandled port write: %d\n", cb));
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+static int pcirawr0PioRead(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice,
+ uint16_t Port,
+ uint32_t *pu32,
+ unsigned cb)
+{
+ /// @todo: add check that port fits into device range
+ switch (cb)
+ {
+ case 1:
+ *pu32 = ASMInU8 (Port);
+ break;
+ case 2:
+ *pu32 = ASMInU16(Port);
+ break;
+ case 4:
+ *pu32 = ASMInU32(Port);
+ break;
+ default:
+ AssertMsgFailed(("Unhandled port read: %d\n", cb));
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+static int pcirawr0MmioRead(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice,
+ RTR0PTR Address,
+ PCIRAWMEMLOC *pValue)
+{
+ /// @todo: add check that address fits into device range
+#if 1
+ switch (pValue->cb)
+ {
+ case 1:
+ pValue->u.u8 = *(uint8_t*)Address;
+ break;
+ case 2:
+ pValue->u.u16 = *(uint16_t*)Address;
+ break;
+ case 4:
+ pValue->u.u32 = *(uint32_t*)Address;
+ break;
+ case 8:
+ pValue->u.u64 = *(uint64_t*)Address;
+ break;
+ }
+#else
+ memset(&pValue->u.u64, 0, 8);
+#endif
+ return VINF_SUCCESS;
+}
+
+static int pcirawr0MmioWrite(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice,
+ RTR0PTR Address,
+ PCIRAWMEMLOC *pValue)
+{
+ /// @todo: add check that address fits into device range
+#if 1
+ switch (pValue->cb)
+ {
+ case 1:
+ *(uint8_t*)Address = pValue->u.u8;
+ break;
+ case 2:
+ *(uint16_t*)Address = pValue->u.u16;
+ break;
+ case 4:
+ *(uint32_t*)Address = pValue->u.u32;
+ break;
+ case 8:
+ *(uint64_t*)Address = pValue->u.u64;
+ break;
+ }
+#endif
+ return VINF_SUCCESS;
+}
+
+static int pcirawr0PciCfgRead(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice,
+ uint32_t Register,
+ PCIRAWMEMLOC *pValue)
+{
+ GET_PORT(TargetDevice);
+
+ return pDevPort->pfnPciCfgRead(pDevPort, Register, pValue);
+}
+
+static int pcirawr0PciCfgWrite(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice,
+ uint32_t Register,
+ PCIRAWMEMLOC *pValue)
+{
+ int rc;
+
+ GET_PORT(TargetDevice);
+
+ rc = pDevPort->pfnPciCfgWrite(pDevPort, Register, pValue);
+
+ PUT_PORT();
+
+ return rc;
+}
+
+static int pcirawr0EnableIrq(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice)
+{
+ int rc = VINF_SUCCESS;
+ GET_PORT(TargetDevice);
+
+ rc = pDevPort->pfnRegisterIrqHandler(pDevPort, pcirawr0Isr, pDev,
+ &pDev->hIsr);
+
+ PUT_PORT();
+ return rc;
+}
+
+static int pcirawr0DisableIrq(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice)
+{
+ int rc = VINF_SUCCESS;
+ GET_PORT(TargetDevice);
+
+ rc = pDevPort->pfnUnregisterIrqHandler(pDevPort, pDev->hIsr);
+ pDev->hIsr = 0;
+
+ PUT_PORT();
+ return rc;
+}
+
+static int pcirawr0GetIrq(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice,
+ int64_t iTimeout,
+ int32_t *piIrq)
+{
+ int rc = VINF_SUCCESS;
+ RTSPINLOCKTMP aTmp;
+ bool fTerminate = false;
+ int32_t iPendingIrq = 0;
+
+ LogFlow(("pcirawr0GetIrq\n"));
+
+ GET_PORT(TargetDevice);
+
+ RTSpinlockAcquireNoInts(pDev->hSpinlock, &aTmp);
+ iPendingIrq = pDev->iPendingIrq;
+ pDev->iPendingIrq = 0;
+ fTerminate = pDev->fTerminate;
+ RTSpinlockReleaseNoInts(pDev->hSpinlock, &aTmp);
+
+ /* Block until new IRQs arrives */
+ if (!fTerminate)
+ {
+ if (iPendingIrq == 0)
+ {
+ rc = RTSemEventWaitNoResume(pDev->hIrqEvent, iTimeout);
+ if (RT_SUCCESS(rc))
+ {
+ /** @todo: racy */
+ if (!ASMAtomicReadBool(&pDev->fTerminate))
+ {
+ RTSpinlockAcquireNoInts(pDev->hSpinlock, &aTmp);
+ iPendingIrq = pDev->iPendingIrq;
+ pDev->iPendingIrq = 0;
+ RTSpinlockReleaseNoInts(pDev->hSpinlock, &aTmp);
+ }
+ else
+ rc = VERR_INTERRUPTED;
+ }
+ }
+
+ if (RT_SUCCESS(rc))
+ *piIrq = iPendingIrq;
+ }
+ else
+ rc = VERR_INTERRUPTED;
+
+ PUT_PORT();
+
+ return rc;
+}
+
+static int pcirawr0PowerStateChange(PSUPDRVSESSION pSession,
+ PCIRAWDEVHANDLE TargetDevice,
+ PCIRAWPOWERSTATE aState,
+ uint64_t *pu64Param)
+{
+ LogFlow(("pcirawr0PowerStateChange\n"));
+ GET_PORT(TargetDevice);
+
+ int rc = pDevPort->pfnPowerStateChange(pDevPort, aState, pu64Param);
+
+ PUT_PORT();
+
+ return rc;
+}
+
+/**
+ * Process PCI raw request
+ *
+ * @returns VBox status code.
+ */
+PCIRAWR0DECL(int) PciRawR0ProcessReq(PSUPDRVSESSION pSession, PVM pVM, PPCIRAWSENDREQ pReq)
+{
+ LogFlow(("PciRawR0ProcessReq: %d for %x\n", pReq->iRequest, pReq->TargetDevice));
+ int rc = VINF_SUCCESS;
+
+ /* Route request to the host driver */
+ switch (pReq->iRequest)
+ {
+ case PCIRAWR0_DO_OPEN_DEVICE:
+ rc = pcirawr0OpenDevice(pSession, pVM,
+ pReq->u.aOpenDevice.PciAddress,
+ pReq->u.aOpenDevice.fFlags,
+ &pReq->u.aOpenDevice.Device,
+ &pReq->u.aOpenDevice.fDevFlags);
+ break;
+ case PCIRAWR0_DO_CLOSE_DEVICE:
+ rc = pcirawr0CloseDevice(pSession,
+ pReq->TargetDevice,
+ pReq->u.aCloseDevice.fFlags);
+ break;
+ case PCIRAWR0_DO_GET_REGION_INFO:
+ rc = pcirawr0GetRegionInfo(pSession,
+ pReq->TargetDevice,
+ pReq->u.aGetRegionInfo.iRegion,
+ &pReq->u.aGetRegionInfo.RegionStart,
+ &pReq->u.aGetRegionInfo.u64RegionSize,
+ &pReq->u.aGetRegionInfo.fPresent,
+ &pReq->u.aGetRegionInfo.fFlags);
+ break;
+ case PCIRAWR0_DO_MAP_REGION:
+ rc = pcirawr0MapRegion(pSession,
+ pReq->TargetDevice,
+ pReq->u.aMapRegion.iRegion,
+ pReq->u.aMapRegion.StartAddress,
+ pReq->u.aMapRegion.iRegionSize,
+ pReq->u.aMapRegion.fFlags,
+ &pReq->u.aMapRegion.pvAddressR3,
+ &pReq->u.aMapRegion.pvAddressR0);
+ break;
+ case PCIRAWR0_DO_UNMAP_REGION:
+ rc = pcirawr0UnmapRegion(pSession,
+ pReq->TargetDevice,
+ pReq->u.aUnmapRegion.iRegion,
+ pReq->u.aUnmapRegion.StartAddress,
+ pReq->u.aUnmapRegion.iRegionSize,
+ pReq->u.aUnmapRegion.pvAddressR3,
+ pReq->u.aUnmapRegion.pvAddressR0);
+ break;
+ case PCIRAWR0_DO_PIO_WRITE:
+ rc = pcirawr0PioWrite(pSession,
+ pReq->TargetDevice,
+ pReq->u.aPioWrite.iPort,
+ pReq->u.aPioWrite.iValue,
+ pReq->u.aPioWrite.cb);
+ break;
+ case PCIRAWR0_DO_PIO_READ:
+ rc = pcirawr0PioRead(pSession,
+ pReq->TargetDevice,
+ pReq->u.aPioRead.iPort,
+ &pReq->u.aPioWrite.iValue,
+ pReq->u.aPioRead.cb);
+ break;
+ case PCIRAWR0_DO_MMIO_WRITE:
+ rc = pcirawr0MmioWrite(pSession,
+ pReq->TargetDevice,
+ pReq->u.aMmioWrite.Address,
+ &pReq->u.aMmioWrite.Value);
+ break;
+ case PCIRAWR0_DO_MMIO_READ:
+ rc = pcirawr0MmioRead(pSession,
+ pReq->TargetDevice,
+ pReq->u.aMmioRead.Address,
+ &pReq->u.aMmioRead.Value);
+ break;
+ case PCIRAWR0_DO_PCICFG_WRITE:
+ rc = pcirawr0PciCfgWrite(pSession,
+ pReq->TargetDevice,
+ pReq->u.aPciCfgWrite.iOffset,
+ &pReq->u.aPciCfgWrite.Value);
+ break;
+ case PCIRAWR0_DO_PCICFG_READ:
+ rc = pcirawr0PciCfgRead(pSession,
+ pReq->TargetDevice,
+ pReq->u.aPciCfgRead.iOffset,
+ &pReq->u.aPciCfgRead.Value);
+ break;
+ case PCIRAWR0_DO_ENABLE_IRQ:
+ rc = pcirawr0EnableIrq(pSession,
+ pReq->TargetDevice);
+ break;
+ case PCIRAWR0_DO_DISABLE_IRQ:
+ rc = pcirawr0DisableIrq(pSession,
+ pReq->TargetDevice);
+ break;
+ case PCIRAWR0_DO_GET_IRQ:
+ rc = pcirawr0GetIrq(pSession,
+ pReq->TargetDevice,
+ pReq->u.aGetIrq.iTimeout,
+ &pReq->u.aGetIrq.iIrq);
+ break;
+ case PCIRAWR0_DO_POWER_STATE_CHANGE:
+ rc = pcirawr0PowerStateChange(pSession,
+ pReq->TargetDevice,
+ (PCIRAWPOWERSTATE)pReq->u.aPowerStateChange.iState,
+ &pReq->u.aPowerStateChange.u64Param);
+ break;
+ default:
+ rc = VERR_NOT_SUPPORTED;
+ }
+
+ LogFlow(("PciRawR0ProcessReq: returns %Rrc\n", rc));
+ return rc;
+}
diff --git a/src/VBox/Devices/EFI/DevEFI.cpp b/src/VBox/Devices/EFI/DevEFI.cpp
index b6b57ff7e..413395fd1 100644
--- a/src/VBox/Devices/EFI/DevEFI.cpp
+++ b/src/VBox/Devices/EFI/DevEFI.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevEFI.cpp $ */
+/* $Id: DevEFI.cpp 35431 2011-01-07 15:19:34Z vboxsync $ */
/** @file
* DevEFI - EFI <-> VirtualBox Integration Framework.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/DevEFI.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/DevEFI.h
index eda72db03..a521ca87a 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/DevEFI.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/DevEFI.h
@@ -1,4 +1,4 @@
-/* $Id: DevEFI.h $ */
+/* $Id: DevEFI.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* EFI for VirtualBox Common Definitions.
*
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/DevEFI.mac b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/DevEFI.mac
index bf21d4d8b..6a02b9fb8 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/DevEFI.mac
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/DevEFI.mac
@@ -1,4 +1,4 @@
-; $Id: DevEFI.mac $
+; $Id: DevEFI.mac 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; DevEFI Interface Definitions, Assembly (Yasm) Variant.
;
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxDebugLib.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxDebugLib.h
index 4cb9cb4dd..b754141d6 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxDebugLib.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxDebugLib.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxDebugLib.h $ */
+/* $Id: VBoxDebugLib.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxDebugLib.h - Debug and logging routines implemented by VBoxDebugLib.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxMemLayout.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxMemLayout.h
index bf5caf4f1..f571c2818 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxMemLayout.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxMemLayout.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxMemLayout.h $ */
+/* $Id: VBoxMemLayout.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxMemLayout.h - Constants defining the memory layout. (Merge with DevEFI?)
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxPkg.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxPkg.h
index 58f6743ad..bee8d90da 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxPkg.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Include/VBoxPkg.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxPkg.h $ */
+/* $Id: VBoxPkg.h 29252 2010-05-09 17:58:53Z vboxsync $ */
/** @file
* VBoxPkg.h - Common header, must be include before IPRT and VBox headers.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxDebugLib.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxDebugLib.c
index 9652c44e4..51c4a34fc 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxDebugLib.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxDebugLib.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxDebugLib.c $ */
+/* $Id: VBoxDebugLib.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxDebugLib.c - Debug logging and assertions support routines using DevEFI.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxDebugLib.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxDebugLib.inf
index 8f3b1707f..e4dc33786 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxDebugLib.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxDebugLib.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxDebugLib.inf $
+# $Id: VBoxDebugLib.inf 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# VBoxDebugLib - Debug logging and assertions support routines using DevEFI.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintChar.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintChar.c
index d73dc1d83..c622bdadd 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintChar.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintChar.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxPrintChar.c $ */
+/* $Id: VBoxPrintChar.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxPrintChar.c - Implementation of the VBoxPrintChar() debug logging routine.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintGuid.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintGuid.c
index 6f3e21666..0fa49d6de 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintGuid.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintGuid.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxPrintGuid.c $ */
+/* $Id: VBoxPrintGuid.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxPrintGuid.c - Implementation of the VBoxPrintGuid() debug logging routine.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintHex.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintHex.c
index 532dea079..6fa88dda0 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintHex.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintHex.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxPrintHex.c $ */
+/* $Id: VBoxPrintHex.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxPrintHex.c - Implementation of the VBoxPrintHex() debug logging routine.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintHexDump.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintHexDump.c
index c1e2074a5..25ed77639 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintHexDump.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintHexDump.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxPrintHexDump.c $ */
+/* $Id: VBoxPrintHexDump.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxPrintHex.c - Implementation of the VBoxPrintHex() debug logging routine.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintString.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintString.c
index 8d789563b..723939124 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintString.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxDebugLib/VBoxPrintString.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxPrintString.c $ */
+/* $Id: VBoxPrintString.c 29085 2010-05-05 14:03:59Z vboxsync $ */
/** @file
* VBoxPrintString.c - Implementation of the VBoxPrintString() debug logging routine.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsBoot.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsBoot.c
index 9b0a5c885..25f66b4fb 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsBoot.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsBoot.c
@@ -1,4 +1,4 @@
-/* $Id: BdsBoot.c $ */
+/* $Id: BdsBoot.c 37147 2011-05-19 02:44:57Z vboxsync $ */
/** @file
* BdsBoot.c
*/
@@ -972,6 +972,33 @@ BdsDeleteAllInvalidEfiBootOption (
return Status;
}
+static BOOLEAN bdsCheckFileName(EFI_IMAGE_OPTIONAL_HEADER_UNION *pHdrData, EFI_HANDLE FileSystemHandle, CHAR16 *pu16FileName, CHAR16 **ppNewFileName)
+{
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
+ BOOLEAN fNeedDelete = TRUE;
+ CHAR16 *NewFileName;
+ EFI_STATUS Status;
+ Hdr.Union = pHdrData;
+ EFI_IMAGE_DOS_HEADER DosHeader;
+ Status = BdsLibGetImageHeader (
+ FileSystemHandle,
+ pu16FileName,
+ &DosHeader,
+ Hdr,
+ &NewFileName
+ );
+ if (!EFI_ERROR (Status)
+#ifndef VBOX
+ && EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
+ Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION
+#endif
+ ) {
+ fNeedDelete = FALSE;
+ }
+ if (ppNewFileName)
+ *ppNewFileName = NewFileName;
+ return fNeedDelete;
+}
/**
For EFI boot option, BDS separate them as six types:
@@ -1049,10 +1076,7 @@ BdsLibEnumerateAllBootOption (
EFI_HANDLE *FileSystemHandles;
UINTN NumberFileSystemHandles;
BOOLEAN NeedDelete;
- EFI_IMAGE_DOS_HEADER DosHeader;
EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData;
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
- CHAR16 *NewFileName;
FloppyNumber = 0;
CdromNumber = 0;
@@ -1188,35 +1212,12 @@ BdsLibEnumerateAllBootOption (
// Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
// machinename is ia32, ia64, x64, ...
//
- Hdr.Union = &HdrData;
NeedDelete = TRUE;
- Status = BdsLibGetImageHeader (
- FileSystemHandles[Index],
- EFI_REMOVABLE_MEDIA_FILE_NAME,
- &DosHeader,
- Hdr,
- &NewFileName
- );
- if (!EFI_ERROR (Status)
-#ifndef VBOX
- && EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
- Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION
-#endif
- ) {
- NeedDelete = FALSE;
- }
- Status = BdsLibGetImageHeader (
- FileSystemHandles[Index],
- L"\\System\\Library\\CoreServices\\boot.efi",
- &DosHeader,
- Hdr,
- &NewFileName
- );
- /* Here should be Mac Specific checks */
- if (!EFI_ERROR (Status)) {
- NeedDelete = FALSE;
- }
-
+ NeedDelete = bdsCheckFileName(&HdrData, FileSystemHandles[Index], EFI_REMOVABLE_MEDIA_FILE_NAME, NULL);
+ if (NeedDelete)
+ NeedDelete = bdsCheckFileName(&HdrData, FileSystemHandles[Index], L"\\Mac OS X Install Data\\boot.efi", NULL);
+ if (NeedDelete)
+ NeedDelete = bdsCheckFileName(&HdrData, FileSystemHandles[Index], L"\\System\\Library\\CoreServices\\boot.efi", NULL);
if (NeedDelete) {
//
// No such file or the file is not a EFI application, delete this boot option
@@ -1454,9 +1455,7 @@ BdsLibGetBootableHandle (
UINTN NumberSimpleFileSystemHandles;
UINTN Index;
- EFI_IMAGE_DOS_HEADER DosHeader;
EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData;
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
UpdatedDevicePath = DevicePath;
@@ -1556,40 +1555,15 @@ BdsLibGetBootableHandle (
// Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media
// machinename is ia32, ia64, x64, ...
//
- Hdr.Union = &HdrData;
- Status = BdsLibGetImageHeader (
- SimpleFileSystemHandles[Index],
- EFI_REMOVABLE_MEDIA_FILE_NAME,
- &DosHeader,
- Hdr,
- NewFileName
- );
- if (!EFI_ERROR (Status)
-#ifndef VBOX
- && EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
- Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION
-#endif
- ) {
- ReturnHandle = SimpleFileSystemHandles[Index];
- break;
- }
- Status = BdsLibGetImageHeader (
- SimpleFileSystemHandles[Index],
- L"\\System\\Library\\CoreServices\\boot.efi",
- &DosHeader,
- Hdr,
- NewFileName
- );
- /* Here should be Mac Specific checks */
- if (!EFI_ERROR (Status)
-#ifndef VBOX
- && EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
- Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION
-#endif
- ) {
- DEBUG((DEBUG_INFO, "%a:%d clear the timer \n", __FILE__, __LINE__));
- ReturnHandle = SimpleFileSystemHandles[Index];
- break;
+ BOOLEAN fNotFound = bdsCheckFileName(&HdrData, SimpleFileSystemHandles[Index], EFI_REMOVABLE_MEDIA_FILE_NAME, NewFileName);
+ if (fNotFound)
+ fNotFound = bdsCheckFileName(&HdrData, SimpleFileSystemHandles[Index], L"\\Mac OS X Install Data\\boot.efi", NewFileName);
+ if (fNotFound)
+ fNotFound = bdsCheckFileName(&HdrData, SimpleFileSystemHandles[Index], L"\\System\\Library\\CoreServices\\boot.efi", NewFileName);
+ if (!fNotFound)
+ {
+ ReturnHandle = SimpleFileSystemHandles[Index];
+ break;
}
}
}
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsConnect.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsConnect.c
index 2508caca9..dfdec7357 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsConnect.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsConnect.c
@@ -1,4 +1,4 @@
-/* $Id: BdsConnect.c $ */
+/* $Id: BdsConnect.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* BdsConnect.c - BDS Lib functions which relate with connect the device
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsConsole.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsConsole.c
index 5fc2f68e5..803832977 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsConsole.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsConsole.c
@@ -1,4 +1,4 @@
-/* $Id: BdsConsole.c $ */
+/* $Id: BdsConsole.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* BdsConsole.c - BDS Lib functions which contain all the code to connect console device.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsMisc.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsMisc.c
index ebac61360..613c5e994 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsMisc.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/BdsMisc.c
@@ -1,4 +1,4 @@
-/* $Id: BdsMisc.c $ */
+/* $Id: BdsMisc.c 33676 2010-11-02 09:48:24Z vboxsync $ */
/** @file
* BdsMisc.c - Misc BDS library function.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/Bmp.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/Bmp.h
index 62cb75d9b..de2fbf8b3 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/Bmp.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/Bmp.h
@@ -1,4 +1,4 @@
-/* $Id: Bmp.h $ */
+/* $Id: Bmp.h 29125 2010-05-06 09:43:05Z vboxsync $ */
/** @file
* Bmp.h - This file defines BMP file header data structures.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/DevicePath.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/DevicePath.c
index c4933c70d..140a6c240 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/DevicePath.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/DevicePath.c
@@ -1,4 +1,4 @@
-/* $Id: DevicePath.c $ */
+/* $Id: DevicePath.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* DevicePath.c - BDS internal function define the default device path string,
* it can be replaced by platform device path.
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/InternalBdsLib.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/InternalBdsLib.h
index 49f91d177..606499c22 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/InternalBdsLib.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/InternalBdsLib.h
@@ -1,4 +1,4 @@
-/* $Id: InternalBdsLib.h $ */
+/* $Id: InternalBdsLib.h 29125 2010-05-06 09:43:05Z vboxsync $ */
/** @file
* InternalBdsLib.h - BDS library definition, include the file and data structure
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/Performance.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/Performance.c
index c4c1a0c79..ac5823a05 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/Performance.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/Performance.c
@@ -1,4 +1,4 @@
-/* $Id: Performance.c $ */
+/* $Id: Performance.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Performance.c - This file include the file which can help to get the
* system performance, all the function will only include if the performance
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/VBoxGenericBdsLib.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/VBoxGenericBdsLib.inf
index 69b7b1177..8a5277ad5 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/VBoxGenericBdsLib.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxGenericBdsLib/VBoxGenericBdsLib.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxGenericBdsLib.inf $
+# $Id: VBoxGenericBdsLib.inf 33540 2010-10-28 09:27:05Z vboxsync $
#/** @file
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxOemHookStatusCodeLib/VBoxOemHookStatusCodeLib.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxOemHookStatusCodeLib/VBoxOemHookStatusCodeLib.c
index 53a1967c8..14e475f98 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxOemHookStatusCodeLib/VBoxOemHookStatusCodeLib.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxOemHookStatusCodeLib/VBoxOemHookStatusCodeLib.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxOemHookStatusCodeLib.c $ */
+/* $Id: VBoxOemHookStatusCodeLib.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* DxeVBoxOemHookStatusCodeLib.c - Logging.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxOemHookStatusCodeLib/VBoxOemHookStatusCodeLib.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxOemHookStatusCodeLib/VBoxOemHookStatusCodeLib.inf
index a282c5a85..a15f5aad7 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxOemHookStatusCodeLib/VBoxOemHookStatusCodeLib.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxOemHookStatusCodeLib/VBoxOemHookStatusCodeLib.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxOemHookStatusCodeLib.inf $
+# $Id: VBoxOemHookStatusCodeLib.inf 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# VBoxOemHookStatusCodeLib - Logging.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/BasePeCoff.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/BasePeCoff.c
index 7832ff383..2ded21fc0 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/BasePeCoff.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/BasePeCoff.c
@@ -1,4 +1,4 @@
-/* $Id: BasePeCoff.c $ */
+/* $Id: BasePeCoff.c 35644 2011-01-20 08:29:40Z vboxsync $ */
/** @file
* BasePeCoff.c
*/
@@ -103,7 +103,6 @@ PeCoffLoaderGetPeHeader (
&Size,
&Fat
);
- DEBUG((DEBUG_LOAD, "%a:%d - %r\n", __FILE__, __LINE__, Status));
if (!RETURN_ERROR(Status) && Fat.Signature == EFI_FAT_IMAGE_HEADER_SIGNATURE)
{
UINT32 i;
@@ -140,7 +139,6 @@ PeCoffLoaderGetPeHeader (
&Size,
&DosHdr
);
- DEBUG((DEBUG_LOAD, "%a:%d - %r\n", __FILE__, __LINE__, Status));
if (RETURN_ERROR (Status)) {
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
return Status;
@@ -168,7 +166,6 @@ PeCoffLoaderGetPeHeader (
&Size,
Hdr.Pe32
);
- DEBUG((DEBUG_LOAD, "%a:%d - %r\n", __FILE__, __LINE__, Status));
if (RETURN_ERROR (Status)) {
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
return Status;
@@ -194,7 +191,6 @@ PeCoffLoaderGetPeHeader (
ImageContext->Machine = Hdr.Pe32->FileHeader.Machine;
Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);
- DEBUG((DEBUG_LOAD, "%a:%d - %x\n", __FILE__, __LINE__, Magic));
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
@@ -461,7 +457,6 @@ PeCoffLoaderGetImageInfo (
&Size,
&SectionHeader
);
- DEBUG((DEBUG_LOAD, "%a:%d - %r\n", __FILE__, __LINE__, Status));
if (RETURN_ERROR (Status)) {
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
return Status;
@@ -1098,7 +1093,6 @@ PeCoffLoaderLoadImage (
ImageContext,
(UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint
);
- DEBUG((DEBUG_INFO, "%a:%d entry point %x\n", __FILE__, __LINE__, ImageContext->EntryPoint));
} else {
//
// Use PE32+ offset
@@ -1107,7 +1101,6 @@ PeCoffLoaderLoadImage (
ImageContext,
(UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfEntryPoint
);
- DEBUG((DEBUG_INFO, "%a:%d entry point %x\n", __FILE__, __LINE__, ImageContext->EntryPoint));
}
} else {
ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (
@@ -1116,7 +1109,6 @@ PeCoffLoaderLoadImage (
(UINTN)sizeof(EFI_TE_IMAGE_HEADER) -
(UINTN)Hdr.Te->StrippedSize
);
- DEBUG((DEBUG_INFO, "%a:%d entry point %x\n", __FILE__, __LINE__, ImageContext->EntryPoint));
}
//
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/BasePeCoffLibInternals.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/BasePeCoffLibInternals.h
index f04fc314d..665a123e6 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/BasePeCoffLibInternals.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/BasePeCoffLibInternals.h
@@ -1,4 +1,4 @@
-/* $Id: BasePeCoffLibInternals.h $ */
+/* $Id: BasePeCoffLibInternals.h 29081 2010-05-05 13:32:04Z vboxsync $ */
/** @file
* BasePeCoffLibInternals.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/PeCoffLoaderEx.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/PeCoffLoaderEx.c
index ab1ab7c39..7bbab5610 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/PeCoffLoaderEx.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/PeCoffLoaderEx.c
@@ -1,4 +1,4 @@
-/* $Id: PeCoffLoaderEx.c $ */
+/* $Id: PeCoffLoaderEx.c 29081 2010-05-05 13:32:04Z vboxsync $ */
/** @file
* PeCoffLoaderEx.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/VBoxPeCoffLib.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/VBoxPeCoffLib.inf
index ad441bf88..48572d525 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/VBoxPeCoffLib.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/Library/VBoxPeCoffLib/VBoxPeCoffLib.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxPeCoffLib.inf $
+# $Id: VBoxPeCoffLib.inf 29081 2010-05-05 13:32:04Z vboxsync $
## @file
# VBoxPeCoffLib.inf
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/ReadMe.txt b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/ReadMe.txt
index e91de307a..889069eb8 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/ReadMe.txt
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/ReadMe.txt
@@ -1,4 +1,4 @@
-$Id: ReadMe.txt $
+$Id: ReadMe.txt 36424 2011-03-25 12:29:29Z vboxsync $
Setting up the source trees
===========================
@@ -55,6 +55,10 @@ The binaries are available at:
http://sourceforge.net/projects/mingw-w64/files/
+on recent Ubuntu systems mingw-w64 is available in repository:
+
+ apt-get install mingw-w64
+
Some non-fatal warnings might appears while compiling on Linux machine so it
is recommended to disable -Werror at Conf/tools_def.txt:*_UNIXGCC_X64_CC_FLAGS.
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/Console.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/Console.c
index a2a755225..2563f9b7c 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/Console.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/Console.c
@@ -1,4 +1,4 @@
-/* $Id: Console.c $ */
+/* $Id: Console.c 29070 2010-05-05 12:32:52Z vboxsync $ */
/** @file
* Console.c - VirtualBox Console control emulation
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/ConsoleControl.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/ConsoleControl.h
index fcef0a049..beddbc2e2 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/ConsoleControl.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/ConsoleControl.h
@@ -1,4 +1,4 @@
-/* $Id: ConsoleControl.h $ */
+/* $Id: ConsoleControl.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* ConsoleControl.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/Cpu.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/Cpu.c
index 7f8579bd3..ed0598510 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/Cpu.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/Cpu.c
@@ -1,4 +1,4 @@
-/* $Id: Cpu.c $ */
+/* $Id: Cpu.c 29070 2010-05-05 12:32:52Z vboxsync $ */
/** @file
* Cpu.c - VirtualBox CPU descriptors
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/VBoxAppleSim.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/VBoxAppleSim.c
index 649db9ee1..a584318f8 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/VBoxAppleSim.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/VBoxAppleSim.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxAppleSim.c $ */
+/* $Id: VBoxAppleSim.c 35646 2011-01-20 09:40:17Z vboxsync $ */
/** @file
* VBoxAppleSim.c - VirtualBox Apple Firmware simulation support
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/VBoxAppleSim.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/VBoxAppleSim.inf
index d2a8d77cc..c0659cda0 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/VBoxAppleSim.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxAppleSim/VBoxAppleSim.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxAppleSim.inf $
+# $Id: VBoxAppleSim.inf 33540 2010-10-28 09:27:05Z vboxsync $
## @file
# VBoxAppleSim - VBox Apple interfaces simulation support.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsole.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsole.c
index 1ee7d6087..a05e7aeb8 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsole.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsole.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxConsole.c $ */
+/* $Id: VBoxConsole.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxConsole.c - Helper driver waiting for Ready to Boot event to switch graphic mode into user-defined one.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsole.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsole.h
index 564c4d50e..eabcc79f3 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsole.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsole.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxConsole.h $ */
+/* $Id: VBoxConsole.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxConsole.h - Some declarations.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsoleDxe.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsoleDxe.inf
index 643e16701..e5bb3dd4a 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsoleDxe.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxConsoleDxe/VBoxConsoleDxe.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxConsoleDxe.inf $
+# $Id: VBoxConsoleDxe.inf 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# VBoxConsole.inf - VBoxConsoleDxe module declarations.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFsDxe.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFsDxe.c
index af2922e94..2f962a07e 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFsDxe.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFsDxe.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxFsDxe.c $ */
+/* $Id: VBoxFsDxe.c 29125 2010-05-06 09:43:05Z vboxsync $ */
/** @file
* VBoxFsDxe.c - VirtualBox FS wrapper
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFsDxe.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFsDxe.inf
index fe075809c..dfcdfe194 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFsDxe.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFsDxe.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxFsDxe.inf $
+# $Id: VBoxFsDxe.inf 29125 2010-05-06 09:43:05Z vboxsync $
## @file
# VBoxFsDxe - VBox filesystem wrapper.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFswParam.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFswParam.h
index c9209fb03..4edefd155 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFswParam.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxFswParam.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxFswParam.h $ */
+/* $Id: VBoxFswParam.h 29125 2010-05-06 09:43:05Z vboxsync $ */
/** @file
* VBoxFswParam.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxHfs.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxHfs.inf
index 6bae40576..631dd1bb2 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxHfs.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxHfs.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxHfs.inf $
+# $Id: VBoxHfs.inf 29125 2010-05-06 09:43:05Z vboxsync $
## @file
# VBoxHfs - VBox HFS FS driver.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxIso9660.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxIso9660.inf
index 038ee85a9..7f8033ba1 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxIso9660.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/VBoxIso9660.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxIso9660.inf $
+# $Id: VBoxIso9660.inf 29125 2010-05-06 09:43:05Z vboxsync $
## @file
# VBox ISO9660 FS driver
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_base.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_base.h
index 01caaee13..03253f523 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_base.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_base.h
@@ -1,4 +1,4 @@
-/* $Id: fsw_base.h $ */
+/* $Id: fsw_base.h 29125 2010-05-06 09:43:05Z vboxsync $ */
/** @file
* fsw_base.h - Base definitions switch.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_core.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_core.c
index 84fca4e33..3bf13e135 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_core.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_core.c
@@ -1,4 +1,4 @@
-/* $Id: fsw_core.c $ */
+/* $Id: fsw_core.c 29125 2010-05-06 09:43:05Z vboxsync $ */
/** @file
* fsw_core.c - Core file system wrapper abstraction layer code.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_core.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_core.h
index 45661ac6f..872ef91bb 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_core.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_core.h
@@ -1,4 +1,4 @@
-/* $Id: fsw_core.h $ */
+/* $Id: fsw_core.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* fsw_core.h - Core file system wrapper abstraction layer header.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi.c
index 16c452763..9305d35ef 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi.c
@@ -1,4 +1,4 @@
-/* $Id: fsw_efi.c $ */
+/* $Id: fsw_efi.c 29125 2010-05-06 09:43:05Z vboxsync $ */
/** @file
* fsw_efi.c - EFI host environment code.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi.h
index aebc7df07..8e6c2b673 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi.h
@@ -1,4 +1,4 @@
-/* $Id: fsw_efi.h $ */
+/* $Id: fsw_efi.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* fsw_efi.h - EFI host environment header.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi_base.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi_base.h
index 6b55243ba..dd604de68 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi_base.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi_base.h
@@ -1,4 +1,4 @@
-/* $Id: fsw_efi_base.h $ */
+/* $Id: fsw_efi_base.h 36444 2011-03-28 03:14:24Z vboxsync $ */
/** @file
* fsw_efi_base.h - Base definitions for the EFI host environment.
*/
@@ -86,8 +86,8 @@ typedef UINT64 fsw_u64;
// message printing
-#define FSW_MSGSTR(s) L##s
-#define FSW_MSGFUNC Print
+#define FSW_MSGSTR(s) DEBUG_INFO, s
+#define FSW_MSGFUNC DebugPrint
// 64-bit hooks
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi_lib.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi_lib.c
index b2143f016..956e9ee40 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi_lib.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_efi_lib.c
@@ -1,4 +1,4 @@
-/* $Id: fsw_efi_lib.c $ */
+/* $Id: fsw_efi_lib.c 29125 2010-05-06 09:43:05Z vboxsync $ */
/** @file
* fsw_efi_lib.c - EFI host environment library functions.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_hfs.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_hfs.c
index d865734f5..a397b16cc 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_hfs.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_hfs.c
@@ -1,4 +1,4 @@
-/* $Id: fsw_hfs.c $ */
+/* $Id: fsw_hfs.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* fsw_hfs.c - HFS file system driver code, see
*
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_hfs.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_hfs.h
index 78e0f2e03..53600cba5 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_hfs.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_hfs.h
@@ -1,4 +1,4 @@
-/* $Id: fsw_hfs.h $ */
+/* $Id: fsw_hfs.h 29125 2010-05-06 09:43:05Z vboxsync $ */
/** @file
* fsw_hfs.h - HFS file system driver header.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_iso9660.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_iso9660.c
index 614b0d6d7..1651f9b16 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_iso9660.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_iso9660.c
@@ -1,4 +1,4 @@
-/* $Id: fsw_iso9660.c $ */
+/* $Id: fsw_iso9660.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* fsw_iso9660.c - ISO9660 file system driver code.
*
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_iso9660.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_iso9660.h
index 7a7518607..87138dd40 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_iso9660.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_iso9660.h
@@ -1,4 +1,4 @@
-/* $Id: fsw_iso9660.h $ */
+/* $Id: fsw_iso9660.h 29125 2010-05-06 09:43:05Z vboxsync $ */
/** @file
* fsw_iso9660.h - ISO9660 file system driver header.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_lib.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_lib.c
index 2412f36b2..ade2b6bad 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_lib.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_lib.c
@@ -1,4 +1,4 @@
-/* $Id: fsw_lib.c $ */
+/* $Id: fsw_lib.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* fsw_lib.c - Core file system wrapper library functions.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_strfunc.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_strfunc.h
index e803634a6..61cf25d87 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_strfunc.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/fsw_strfunc.h
@@ -1,4 +1,4 @@
-/* $Id: fsw_strfunc.h $ */
+/* $Id: fsw_strfunc.h 29125 2010-05-06 09:43:05Z vboxsync $ */
/** @file
* fsw_strfunc.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/hfs_format.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/hfs_format.h
index 96079cbe3..427c1fe0a 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/hfs_format.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/hfs_format.h
@@ -1,4 +1,4 @@
-/* $Id: hfs_format.h $ */
+/* $Id: hfs_format.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* hfs_format.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/test/fsw_posix_base.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/test/fsw_posix_base.h
index ee1d96c46..114e21fdf 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/test/fsw_posix_base.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe/test/fsw_posix_base.h
@@ -44,6 +44,7 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
+#include <stdint.h>
#define FSW_LITTLE_ENDIAN (1)
// TODO: use info from the headers to define FSW_LITTLE_ENDIAN or FSW_BIG_ENDIAN
@@ -51,14 +52,14 @@
// types
-typedef signed char fsw_s8;
-typedef unsigned char fsw_u8;
-typedef short fsw_s16;
-typedef unsigned short fsw_u16;
-typedef long fsw_s32;
-typedef unsigned long fsw_u32;
-typedef long long fsw_s64;
-typedef unsigned long long fsw_u64;
+typedef int8_t fsw_s8;
+typedef uint8_t fsw_u8;
+typedef int16_t fsw_s16;
+typedef uint16_t fsw_u16;
+typedef int32_t fsw_s32;
+typedef uint32_t fsw_u32;
+typedef int64_t fsw_s64;
+typedef uint64_t fsw_u64;
// allocation functions
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ata.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ata.c
index 2c89480e7..6bb6781bd 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ata.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ata.c
@@ -1,4 +1,4 @@
-/* $Id: Ata.c $ */
+/* $Id: Ata.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Ata.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Atapi.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Atapi.c
index 72d10146e..f0467474f 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Atapi.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Atapi.c
@@ -1,4 +1,4 @@
-/* $Id: Atapi.c $ */
+/* $Id: Atapi.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Atapi.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/ComponentName.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/ComponentName.c
index c033c7f23..312ca6310 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/ComponentName.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/ComponentName.c
@@ -1,4 +1,4 @@
-/* $Id: ComponentName.c $ */
+/* $Id: ComponentName.c 33027 2010-10-11 06:17:12Z vboxsync $ */
/** @file
* ComponentName.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/ComponentName.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/ComponentName.h
index e5e138e1d..fb46ce45d 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/ComponentName.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/ComponentName.h
@@ -1,4 +1,4 @@
-/* $Id: ComponentName.h $ */
+/* $Id: ComponentName.h 33027 2010-10-11 06:17:12Z vboxsync $ */
/** @file
* ComponentName.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/DriverConfiguration.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/DriverConfiguration.c
index 13ae2284f..6459ab90b 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/DriverConfiguration.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/DriverConfiguration.c
@@ -1,4 +1,4 @@
-/* $Id: DriverConfiguration.c $ */
+/* $Id: DriverConfiguration.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* DriverConfiguration.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/DriverDiagnostics.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/DriverDiagnostics.c
index b49fe36a4..8cb886816 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/DriverDiagnostics.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/DriverDiagnostics.c
@@ -1,4 +1,4 @@
-/* $Id: DriverDiagnostics.c $ */
+/* $Id: DriverDiagnostics.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* DriverDiagnostics.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ide.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ide.c
index c47cd919b..c2bb3b249 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ide.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ide.c
@@ -1,4 +1,4 @@
-/* $Id: Ide.c $ */
+/* $Id: Ide.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Ide.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ide.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ide.h
index 172f608ef..15b3f4a4e 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ide.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ide.h
@@ -1,4 +1,4 @@
-/* $Id: Ide.h $ */
+/* $Id: Ide.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Ide.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeBus.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeBus.c
index b5e982a76..b8525e7e8 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeBus.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeBus.c
@@ -1,4 +1,4 @@
-/* $Id: IdeBus.c $ */
+/* $Id: IdeBus.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IdeBus.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeBus.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeBus.h
index 727e9c389..a96d4f9ee 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeBus.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeBus.h
@@ -1,4 +1,4 @@
-/* $Id: IdeBus.h $ */
+/* $Id: IdeBus.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IdeBus.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeData.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeData.h
index cba6c9f78..961e502bb 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeData.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/IdeData.h
@@ -1,4 +1,4 @@
-/* $Id: IdeData.h $ */
+/* $Id: IdeData.h 33027 2010-10-11 06:17:12Z vboxsync $ */
/** @file
* IdeData.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/VBoxIdeBusDxe.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/VBoxIdeBusDxe.inf
index 0a7846097..26fbe956e 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/VBoxIdeBusDxe.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/VBoxIdeBusDxe.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxIdeBusDxe.inf $
+# $Id: VBoxIdeBusDxe.inf 33027 2010-10-11 06:17:12Z vboxsync $
## @file
# VBoxIdeBusDxe.inf
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxMisc/Makefile b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxMisc/Makefile
index e7e209b37..888cdce45 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxMisc/Makefile
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxMisc/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile $
+# $Id: Makefile 32404 2010-09-10 13:17:42Z vboxsync $
#* @file
# Makefile - assembling the iso image for experimenting with EFI.
#/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxMisc/efi-app/Readme.txt b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxMisc/efi-app/Readme.txt
index 04e688031..1aed898ce 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxMisc/efi-app/Readme.txt
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxMisc/efi-app/Readme.txt
@@ -1,4 +1,4 @@
-# $Id: Readme.txt $ */
+# $Id: Readme.txt 33540 2010-10-28 09:27:05Z vboxsync $ */
#* @file
# Readme.txt - Some description about using this module.
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxOSELogo/VBoxOSELogo.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxOSELogo/VBoxOSELogo.inf
index 53da9cf97..7bd8a7d12 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxOSELogo/VBoxOSELogo.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxOSELogo/VBoxOSELogo.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxOSELogo.inf $
+# $Id: VBoxOSELogo.inf 32404 2010-09-10 13:17:42Z vboxsync $
#* @file
# VBoxOSELogo.inf - Logo module declarations.
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.dec b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.dec
index 2179f15c3..6b006ad20 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.dec
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.dec
@@ -1,4 +1,4 @@
-# $Id: VBoxPkg.dec $
+# $Id: VBoxPkg.dec 32394 2010-09-10 12:13:11Z vboxsync $
## @file
# VBoxPkg.dec - VirtualBox Package description.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.dsc b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.dsc
index 92d0818f5..45fcaf707 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.dsc
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.dsc
@@ -1,4 +1,4 @@
-# $Id: VBoxPkg.dsc $
+# $Id: VBoxPkg.dsc 33540 2010-10-28 09:27:05Z vboxsync $
## @file
# VBoxPkg.dsc - VirtualBox Flash Device.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.fdf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.fdf
index a05f89187..7041ac11b 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.fdf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkg.fdf
@@ -1,4 +1,4 @@
-# $Id: VBoxPkg.fdf $
+# $Id: VBoxPkg.fdf 33028 2010-10-11 06:23:00Z vboxsync $
## @file
# VBoxPkg.fdf - VirtualBox Flash Device.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSE.dsc b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSE.dsc
index 22d30e9e8..cc12fb609 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSE.dsc
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSE.dsc
@@ -1,4 +1,4 @@
-# $Id: VBoxPkgOSE.dsc $
+# $Id: VBoxPkgOSE.dsc 33540 2010-10-28 09:27:05Z vboxsync $
## @file
# VBoxPkg.dsc - VirtualBox Flash Device.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSE.fdf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSE.fdf
index 6363b1984..bf2279657 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSE.fdf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSE.fdf
@@ -1,4 +1,4 @@
-# $Id: VBoxPkgOSE.fdf $
+# $Id: VBoxPkgOSE.fdf 32394 2010-09-10 12:13:11Z vboxsync $
## @file
# VBoxPkg.fdf - VirtualBox Flash Device.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSEX64.dsc b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSEX64.dsc
index 5b856eada..c199bab39 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSEX64.dsc
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgOSEX64.dsc
@@ -1,4 +1,4 @@
-# $Id: VBoxPkgOSEX64.dsc $
+# $Id: VBoxPkgOSEX64.dsc 32436 2010-09-13 07:30:33Z vboxsync $
#
# Copyright (C) 2009-2010 Oracle Corporation
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgX64.dsc b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgX64.dsc
index 96ca8ec35..9069909ac 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgX64.dsc
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxPkgX64.dsc
@@ -1,4 +1,4 @@
-# $Id: VBoxPkgX64.dsc $
+# $Id: VBoxPkgX64.dsc 33028 2010-10-11 06:23:00Z vboxsync $
#
# Copyright (C) 2009-2010 Oracle Corporation
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/LegacyBiosMpTable.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/LegacyBiosMpTable.h
index ebd0ca9ca..8b1b01163 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/LegacyBiosMpTable.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/LegacyBiosMpTable.h
@@ -1,4 +1,4 @@
-/* $Id: LegacyBiosMpTable.h $ */
+/* $Id: LegacyBiosMpTable.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* LegacyBiosMpTable.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/TableConversion.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/TableConversion.c
index deaaeaea3..1bb6026d9 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/TableConversion.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/TableConversion.c
@@ -1,4 +1,4 @@
-/* $Id: TableConversion.c $ */
+/* $Id: TableConversion.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* TableConversion.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/VBoxSysTables.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/VBoxSysTables.c
index 47331e5ef..5f5732feb 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/VBoxSysTables.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/VBoxSysTables.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxSysTables.c $ */
+/* $Id: VBoxSysTables.c 29081 2010-05-05 13:32:04Z vboxsync $ */
/** @file
* VBoxSysTables.c - VirtualBox system tables
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/VBoxSysTables.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/VBoxSysTables.inf
index e0d544f1d..b37637fa0 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/VBoxSysTables.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/VBoxSysTables.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxSysTables.inf $
+# $Id: VBoxSysTables.inf 29081 2010-05-05 13:32:04Z vboxsync $
## @file
# VBoxSysTables - VBox system tables.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/ComponentName.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/ComponentName.c
index b6cce90ae..e810c05a6 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/ComponentName.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/ComponentName.c
@@ -1,4 +1,4 @@
-/* $Id: ComponentName.c $ */
+/* $Id: ComponentName.c 29081 2010-05-05 13:32:04Z vboxsync $ */
/** @file
* ComponentName.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/DriverSupportedEfiVersion.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/DriverSupportedEfiVersion.c
index fbd3c9ac9..da6a85486 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/DriverSupportedEfiVersion.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/DriverSupportedEfiVersion.c
@@ -1,4 +1,4 @@
-/* $Id: DriverSupportedEfiVersion.c $ */
+/* $Id: DriverSupportedEfiVersion.c 29081 2010-05-05 13:32:04Z vboxsync $ */
/** @file
* DriverSupportedEfiVersion.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/Edid.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/Edid.c
index 5b2488aa9..7b2215a9b 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/Edid.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/Edid.c
@@ -1,4 +1,4 @@
-/* $Id: Edid.c $ */
+/* $Id: Edid.c 29081 2010-05-05 13:32:04Z vboxsync $ */
/** @file
* Edid.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVga.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVga.c
index 723dae26d..e1633f838 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVga.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVga.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxVga.c $ */
+/* $Id: VBoxVga.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxVga.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVga.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVga.h
index e1900807a..3d66f2b05 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVga.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVga.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxVga.h $ */
+/* $Id: VBoxVga.h 33086 2010-10-13 07:27:19Z vboxsync $ */
/** @file
* VBoxVga.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaDxe.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaDxe.inf
index 1f3057bc7..51e1272fc 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaDxe.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaDxe.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxVgaDxe.inf $
+# $Id: VBoxVgaDxe.inf 29081 2010-05-05 13:32:04Z vboxsync $
## @file
# VBoxVgaDxe.inf
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaGraphicsOutput.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaGraphicsOutput.c
index 6a704ea8a..5badfaee5 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaGraphicsOutput.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaGraphicsOutput.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxVgaGraphicsOutput.c $ */
+/* $Id: VBoxVgaGraphicsOutput.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* LegacyBiosMpTable.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaI2c.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaI2c.c
index f4b88a376..77aeaf08d 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaI2c.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaI2c.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxVgaI2c.c $ */
+/* $Id: VBoxVgaI2c.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxVgaI2c.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaI2c.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaI2c.h
index 4841cc75a..8e6fdd472 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaI2c.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaI2c.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxVgaI2c.h $ */
+/* $Id: VBoxVgaI2c.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxVgaI2c.h
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaUgaDraw.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaUgaDraw.c
index 5aa414d04..9d2bbdddc 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaUgaDraw.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVgaUgaDraw.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxVgaUgaDraw.c $ */
+/* $Id: VBoxVgaUgaDraw.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxVgaUgaDraw.c
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x14.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x14.h
index 2342f4a50..b81fcf363 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x14.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x14.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxVgaFont-8x14.h $ */
+/* $Id: VBoxVgaFont-8x14.h 29104 2010-05-05 19:06:09Z vboxsync $ */
/** @file
* VGA-ROM.F14 from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip .
* The package is (C) Joseph (Yossi) Gil.
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x16.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x16.h
index bb8b6b46a..358b6b730 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x16.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x16.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxVgaFont-8x16.h $ */
+/* $Id: VBoxVgaFont-8x16.h 29104 2010-05-05 19:06:09Z vboxsync $ */
/** @file
* VGA-ROM.F16 from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip .
* The package is (C) Joseph (Yossi) Gil.
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x8.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x8.h
index 369fbb118..6d491ced0 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x8.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFont-8x8.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxVgaFont-8x8.h $ */
+/* $Id: VBoxVgaFont-8x8.h 29104 2010-05-05 19:06:09Z vboxsync $ */
/** @file
* VGA-ROM.F8 from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip .
* The package is (C) Joseph (Yossi) Gil.
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFonts.h b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFonts.h
index ef94497de..df78da1b5 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFonts.h
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaFonts.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxVgaFonts.h $ */
+/* $Id: VBoxVgaFonts.h 29104 2010-05-05 19:06:09Z vboxsync $ */
/** @file
* Some of the VGA-ROM fonts from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip .
* The package is (C) Joseph (Yossi) Gil.
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaMiniPortDxe.c b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaMiniPortDxe.c
index 393d15939..519579fb4 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaMiniPortDxe.c
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaMiniPortDxe.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxVgaMiniPortDxe.c $ */
+/* $Id: VBoxVgaMiniPortDxe.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxVgaMiniPortDxe.c - VgaMiniPort Protocol Implementation.
*/
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaMiniPortDxe.inf b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaMiniPortDxe.inf
index 7987c5126..26132aa2a 100644
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaMiniPortDxe.inf
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaMiniPortDxe.inf
@@ -1,4 +1,4 @@
-# $Id: VBoxVgaMiniPortDxe.inf $
+# $Id: VBoxVgaMiniPortDxe.inf 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# VBoxVgaMiniPortDxe.inf - VgaMiniPort Protocol module declaration.
#
diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/env.sh b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/env.sh
index eab8a9081..1c85a744f 100755
--- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/env.sh
+++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/env.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# $Id: env.sh $
+# $Id: env.sh 30101 2010-06-09 09:48:56Z vboxsync $
# @file
# Environmental Setup Script for VBoxPkg + EDK2.
diff --git a/src/VBox/Devices/EFI/Thunk/EfiThunk.asm b/src/VBox/Devices/EFI/Thunk/EfiThunk.asm
index 728c050f0..6e7157b74 100644
--- a/src/VBox/Devices/EFI/Thunk/EfiThunk.asm
+++ b/src/VBox/Devices/EFI/Thunk/EfiThunk.asm
@@ -1,4 +1,4 @@
-; $Id: EfiThunk.asm $
+; $Id: EfiThunk.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; 16-bit EFI Thunk - 16-bit code executed immediately after CPU startup/reset,
; performs minimal setup, switches CPU to 32-bit mode
@@ -32,7 +32,7 @@
;* Header Files *
;*******************************************************************************
%include "VBox/asmdefs.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "DevEFI.mac"
;
diff --git a/src/VBox/Devices/EFI/Thunk/Makefile.kmk b/src/VBox/Devices/EFI/Thunk/Makefile.kmk
index e49574211..77b9bb3ac 100644
--- a/src/VBox/Devices/EFI/Thunk/Makefile.kmk
+++ b/src/VBox/Devices/EFI/Thunk/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for EFI thunking ROM image.
#
diff --git a/src/VBox/Devices/Graphics/BIOS/Makefile.kmk b/src/VBox/Devices/Graphics/BIOS/Makefile.kmk
index 73385fbd6..38f89c7b2 100644
--- a/src/VBox/Devices/Graphics/BIOS/Makefile.kmk
+++ b/src/VBox/Devices/Graphics/BIOS/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35440 2011-01-09 23:43:10Z vboxsync $
## @file
# VGA BIOS Sub-Makefile
#
diff --git a/src/VBox/Devices/Graphics/BIOS/dataseghack b/src/VBox/Devices/Graphics/BIOS/dataseghack
index 02a2d4c52..02a2d4c52 100755..100644
--- a/src/VBox/Devices/Graphics/BIOS/dataseghack
+++ b/src/VBox/Devices/Graphics/BIOS/dataseghack
diff --git a/src/VBox/Devices/Graphics/BIOS/vgatables.h b/src/VBox/Devices/Graphics/BIOS/vgatables.h
index fcbfad881..0b2160c01 100644
--- a/src/VBox/Devices/Graphics/BIOS/vgatables.h
+++ b/src/VBox/Devices/Graphics/BIOS/vgatables.h
@@ -418,15 +418,18 @@ static VideoParamTableEntry video_param_table[30] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
{
- /* index=0x16 no mode defined */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* index=0x18 ega mode 0x03 */
+ 80, 24, 14, 0x00, 0x10, /* tw, th-1, ch, slength */
+ 0x00, 0x03, 0x00, 0x02, /* sequ_regs */
+ 0x67, /* miscreg */
+ 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+ 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
+ 0xff, /* crtc_regs */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x0c, 0x00, 0x0f, 0x08, /* actl_regs */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, /* grdc_regs */
},
{
/* index=0x17 vga mode 0x01 */
diff --git a/src/VBox/Devices/Graphics/DevVGA.cpp b/src/VBox/Devices/Graphics/DevVGA.cpp
index 7cf9bb460..4339ca7f8 100644
--- a/src/VBox/Devices/Graphics/DevVGA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevVGA.cpp $ */
+/* $Id: DevVGA.cpp 37770 2011-07-04 17:43:06Z vboxsync $ */
/** @file
* DevVGA - VBox VGA/VESA device.
*/
@@ -293,39 +293,6 @@ static const uint8_t g_abLogoF12BootText[] =
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
-/*******************************************************************************
-* Internal Functions *
-*******************************************************************************/
-RT_C_DECLS_BEGIN
-
-PDMBOTHCBDECL(int) vgaIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) vgaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) vgaIOPortWriteVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) vgaIOPortWriteVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) vgaIOPortReadVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) vgaIOPortReadVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) vgaMMIOFill(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems);
-PDMBOTHCBDECL(int) vgaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) vgaIOPortReadBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) vgaIOPortWriteBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-#ifdef IN_RC
-PDMBOTHCBDECL(int) vgaGCLFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
-#endif
-#ifdef IN_RING0
-PDMBOTHCBDECL(int) vgaR0LFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
-#endif
-#ifdef IN_RING3
-# ifdef VBE_NEW_DYN_LIST
-PDMBOTHCBDECL(int) vbeIOPortReadVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) vbeIOPortWriteVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-# endif
-PDMBOTHCBDECL(int) vbeIOPortReadCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) vbeIOPortWriteCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-#endif /* IN_RING3 */
-
-
-RT_C_DECLS_END
/**
@@ -746,6 +713,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
s->msr = val & ~0x10;
if (s->fRealRetrace)
vga_update_retrace_state(s);
+ s->st00 = (s->st00 & ~0x10) | (0x90 >> ((val >> 2) & 0x3));
break;
case 0x3c4:
s->sr_index = val & 7;
@@ -932,6 +900,44 @@ static uint32_t calc_line_width(uint16_t bpp, uint32_t pitch)
return width;
}
+static void recaltulate_data(VGAState *s, bool fVirtHeightOnly)
+{
+ uint16_t cBPP = s->vbe_regs[VBE_DISPI_INDEX_BPP];
+ uint16_t cVirtWidth = s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH];
+ uint16_t cX = s->vbe_regs[VBE_DISPI_INDEX_XRES];
+ if (!cBPP || !cX)
+ return; /* Not enough data has been set yet. */
+ uint32_t cbLinePitch = calc_line_pitch(cBPP, cVirtWidth);
+ if (!cbLinePitch)
+ cbLinePitch = calc_line_pitch(cBPP, cX);
+ Assert(cbLinePitch != 0);
+ uint32_t cVirtHeight = s->vram_size / cbLinePitch;
+ if (!fVirtHeightOnly)
+ {
+ uint16_t offX = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
+ uint16_t offY = s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
+ uint32_t offStart = cbLinePitch * offY;
+ if (cBPP == 4)
+ offStart += offX >> 1;
+ else
+ offStart += offX * ((cBPP + 7) >> 3);
+ offStart >>= 2;
+ s->vbe_line_offset = RT_MIN(cbLinePitch, s->vram_size);
+ s->vbe_start_addr = RT_MIN(offStart, s->vram_size);
+ }
+
+ /* The VBE_DISPI_INDEX_VIRT_HEIGHT is used to prevent setting resolution bigger than VRAM permits
+ * it is used instead of VBE_DISPI_INDEX_YRES *only* in case
+ * s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] < s->vbe_regs[VBE_DISPI_INDEX_YRES]
+ * We can not simply do s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = cVirtHeight since
+ * the cVirtHeight we calculated can exceed the 16bit value range
+ * instead we'll check if it's bigger than s->vbe_regs[VBE_DISPI_INDEX_YRES], and if yes,
+ * assign the s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] with a dummy UINT16_MAX value
+ * that is always bigger than s->vbe_regs[VBE_DISPI_INDEX_YRES]
+ * to just ensure the s->vbe_regs[VBE_DISPI_INDEX_YRES] is always used */
+ s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = (cVirtHeight >= (uint32_t)s->vbe_regs[VBE_DISPI_INDEX_YRES]) ? UINT16_MAX : (uint16_t)cVirtHeight;
+}
+
static void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
{
VGAState *s = (VGAState*)opaque;
@@ -1146,27 +1152,7 @@ static int vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
}
if (fRecalculate)
{
- uint16_t cBPP = s->vbe_regs[VBE_DISPI_INDEX_BPP];
- uint16_t cVirtWidth = s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH];
- uint16_t cX = s->vbe_regs[VBE_DISPI_INDEX_XRES];
- uint16_t offX = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
- uint16_t offY = s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
- if (!cBPP || !cX)
- return VINF_SUCCESS; /* Not enough data has been set yet. */
- uint32_t cbLinePitch = calc_line_pitch(cBPP, cVirtWidth);
- if (!cbLinePitch)
- cbLinePitch = calc_line_pitch(cBPP, cX);
- Assert(cbLinePitch != 0);
- uint16_t cVirtHeight = s->vram_size / cbLinePitch;
- uint32_t offStart = cbLinePitch * offY;
- if (cBPP == 4)
- offStart += offX >> 1;
- else
- offStart += offX * ((cBPP + 7) >> 3);
- offStart >>= 2;
- s->vbe_line_offset = RT_MIN(cbLinePitch, s->vram_size);
- s->vbe_start_addr = RT_MIN(offStart, s->vram_size);
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = cVirtHeight;
+ recaltulate_data(s, false);
}
}
return VINF_SUCCESS;
@@ -1982,7 +1968,8 @@ static void vga_get_resolution(VGAState *s, int *pwidth, int *pheight)
#ifdef CONFIG_BOCHS_VBE
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
- height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
+ height = RT_MIN(s->vbe_regs[VBE_DISPI_INDEX_YRES],
+ s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT]);
} else
#endif
{
@@ -2460,6 +2447,8 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id)
qemu_get_be16s(f, &s->vbe_index);
for(i = 0; i < VBE_DISPI_INDEX_NB_SAVED; i++)
qemu_get_be16s(f, &s->vbe_regs[i]);
+ if (version_id <= VGA_SAVEDSTATE_VERSION_INV_VHEIGHT)
+ recaltulate_data(s, false); /* <- re-calculate the s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] since it might be invalid */
qemu_get_be32s(f, &s->vbe_start_addr);
qemu_get_be32s(f, &s->vbe_line_offset);
if (version_id < 2)
@@ -3266,7 +3255,7 @@ PDMBOTHCBDECL(int) vgaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhys
* @param pv Pointer to data.
* @param cb Bytes to write.
*/
-PDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+PDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
uint8_t *pu8 = (uint8_t *)pv;
@@ -6027,7 +6016,7 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
return rc;
/* Initialize the PDM lock. */
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->lock, RT_SRC_POS, "VGA");
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->lock, RT_SRC_POS, "VGA#u", iInstance);
if (RT_FAILURE(rc))
{
Log(("%s: Failed to create critical section.\n", __FUNCTION__));
@@ -6038,7 +6027,7 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
* Create the refresh timer.
*/
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_REAL, vgaTimerRefresh,
- pThis, TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo This needs to be fixed! We cannot take the I/O lock at this point! */
+ pThis, TMTIMER_FLAGS_NO_CRIT_SECT,
"VGA Refresh Timer", &pThis->RefreshTimer);
if (RT_FAILURE(rc))
return rc;
diff --git a/src/VBox/Devices/Graphics/DevVGA.h b/src/VBox/Devices/Graphics/DevVGA.h
index 0a4775c7c..6ca11f0df 100644
--- a/src/VBox/Devices/Graphics/DevVGA.h
+++ b/src/VBox/Devices/Graphics/DevVGA.h
@@ -1,4 +1,4 @@
-/* $Id: DevVGA.h $ */
+/* $Id: DevVGA.h 36899 2011-04-29 15:52:47Z vboxsync $ */
/** @file
* DevVGA - VBox VGA/VESA device, internal header.
*/
@@ -279,6 +279,13 @@ typedef struct VGAState {
R3PTRTYPE(PVBOXVDMAHOST) pVdma;
#endif
+#if HC_ARCH_BITS == 32
+# if defined(VBOX_WITH_HGSMI) != defined(VBOX_WITH_VDMA)
+ uint32_t Padding3;
+# endif
+#endif
+
+
uint32_t cMonitors;
/** Current refresh timer interval. */
uint32_t cMilliesRefreshInterval;
@@ -308,7 +315,7 @@ typedef struct VGAState {
PDMIDISPLAYVBVACALLBACKS IVBVACallbacks;
#else
# if HC_ARCH_BITS == 32
- uint32_t Padding3;
+ uint32_t Padding4;
# endif
#endif
/** Pointer to base interface of the driver. */
@@ -344,15 +351,15 @@ typedef struct VGAState {
# ifdef VBE_NEW_DYN_LIST
/** VBE Extra Data write address one byte buffer */
uint8_t cbWriteVBEExtraAddress;
- uint8_t Padding4;
+ uint8_t Padding5;
# else
- uint8_t Padding4[2];
+ uint8_t Padding5[2];
# endif
#endif
/** Retrace emulation state */
bool fRealRetrace;
- bool Padding5[HC_ARCH_BITS == 64 ? 7 : 3];
+ bool Padding6[HC_ARCH_BITS == 64 ? 7 : 3];
vga_retrace_s retrace_state;
#ifdef VBE_NEW_DYN_LIST
@@ -362,7 +369,7 @@ typedef struct VGAState {
uint16_t cbVBEExtraData;
/** The VBE BIOS current memory address. */
uint16_t u16VBEExtraAddress;
- uint16_t Padding6[2];
+ uint16_t Padding7[2];
#endif
/** Current logo data offset. */
uint32_t offLogoData;
@@ -392,7 +399,7 @@ typedef struct VGAState {
uint16_t cLogoPalEntries;
/** Clear screen flag. */
uint8_t fLogoClearScreen;
- uint8_t Padding7[7];
+ uint8_t Padding8[7];
/** Palette data. */
uint32_t au32LogoPalette[256];
/** The VGA BIOS ROM data. */
@@ -406,12 +413,12 @@ typedef struct VGAState {
/** Base port in the assigned PCI I/O space. */
RTIOPORT IOPortBase;
#ifdef VBOX_WITH_WDDM
- uint8_t Padding8[2];
+ uint8_t Padding9[2];
/* specifies guest driver caps, i.e. whether it can handle IRQs from the adapter,
* the way it can handle async HGSMI command completion, etc. */
uint32_t fGuestCaps;
#else
- uint8_t Padding8[6];
+ uint8_t Padding10[6];
#endif
#endif /* VBOX_WITH_HGSMI */
} VGAState;
diff --git a/src/VBox/Devices/Graphics/DevVGAModes.h b/src/VBox/Devices/Graphics/DevVGAModes.h
index f03f7e7e6..72bc923cb 100644
--- a/src/VBox/Devices/Graphics/DevVGAModes.h
+++ b/src/VBox/Devices/Graphics/DevVGAModes.h
@@ -1,4 +1,4 @@
-/* $Id: DevVGAModes.h $ */
+/* $Id: DevVGAModes.h 34399 2010-11-26 16:30:44Z vboxsync $ */
/** @file
* DevVGA - VBox VGA/VESA device, VBE modes.
*
diff --git a/src/VBox/Devices/Graphics/DevVGASavedState.h b/src/VBox/Devices/Graphics/DevVGASavedState.h
index f417331ca..5af682610 100644
--- a/src/VBox/Devices/Graphics/DevVGASavedState.h
+++ b/src/VBox/Devices/Graphics/DevVGASavedState.h
@@ -1,4 +1,4 @@
-/* $Id: DevVGASavedState.h $ */
+/* $Id: DevVGASavedState.h 37770 2011-07-04 17:43:06Z vboxsync $ */
/** @file
* DevVGA - Saved state versions.
*
@@ -23,6 +23,7 @@
#define Graphics_DevVGASavedState_h
#define VGA_SAVEDSTATE_VERSION 8
+#define VGA_SAVEDSTATE_VERSION_INV_VHEIGHT 8 /* <- states upto and including this version may contain invalid vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] value */
#define VGA_SAVEDSTATE_VERSION_WDDM 7
#define VGA_SAVEDSTATE_VERSION_PRE_WDDM 6
#define VGA_SAVEDSTATE_VERSION_HOST_HEAP 5
diff --git a/src/VBox/Devices/Graphics/DevVGATmpl.h b/src/VBox/Devices/Graphics/DevVGATmpl.h
index 8d6268db1..620731c7f 100644
--- a/src/VBox/Devices/Graphics/DevVGATmpl.h
+++ b/src/VBox/Devices/Graphics/DevVGATmpl.h
@@ -1,4 +1,4 @@
-/* $Id: DevVGATmpl.h $ */
+/* $Id: DevVGATmpl.h 34024 2010-11-12 09:47:37Z vboxsync $ */
/** @file
* DevVGA - VBox VGA/VESA device, code templates.
*/
diff --git a/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp b/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp
index e51ac4077..638db8656 100644
--- a/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp
@@ -313,9 +313,6 @@ int vboxVDMACrHgsmiControlCompleteAsync(PPDMIDISPLAYVBVACALLBACKS pInterface, PV
PVGASTATE pVGAState = PPDMIDISPLAYVBVACALLBACKS_2_PVGASTATE(pInterface);
PVBOXVDMACMD_CHROMIUM_CTL_PRIVATE pCmdPrivate = VBOXVDMACMD_CHROMIUM_CTL_PRIVATE_FROM_CTL(pCmd);
pCmdPrivate->rc = rc;
-#ifdef DEBUG_misha
- AssertRC(rc);
-#endif
if (pCmdPrivate->pfnCompletion)
{
pCmdPrivate->pfnCompletion(pVGAState, pCmd, pCmdPrivate->pvCompletion);
@@ -676,6 +673,10 @@ static int vboxVDMACmdExec(PVBOXVDMAHOST pVdma, const uint8_t *pvBuffer, uint32_
return cbTransfer; /* error */
break;
}
+ case VBOXVDMACMD_TYPE_DMA_NOP:
+ return VINF_SUCCESS;
+ case VBOXVDMACMD_TYPE_CHILD_STATUS_IRQ:
+ return VINF_SUCCESS;
default:
AssertBreakpoint();
return VERR_INVALID_FUNCTION;
@@ -1097,17 +1098,11 @@ int vboxVDMAConstruct(PVGASTATE pVGAState, uint32_t cPipeElements)
}
# if 0 //def VBOX_WITH_CRHGSMI
int tmpRc = vboxVDMACrCtlHgsmiSetup(pVdma);
-# ifdef DEBUG_misha
- AssertRC(tmpRc);
-# endif
# endif
#endif
pVGAState->pVdma = pVdma;
#ifdef VBOX_WITH_CRHGSMI
rc = vboxVDMACrCtlHgsmiSetup(pVdma);
-# ifdef DEBUG_misha
- AssertRC(rc);
-# endif
#endif
return VINF_SUCCESS;
#ifdef VBOX_VDMA_WITH_WORKERTHREAD
@@ -1271,17 +1266,20 @@ void vboxVDMAControl(struct VBOXVDMAHOST *pVdma, PVBOXVDMA_CTL pCmd)
void vboxVDMACommand(struct VBOXVDMAHOST *pVdma, PVBOXVDMACBUF_DR pCmd)
{
#ifdef VBOX_WITH_CRHGSMI
+ /* chromium commands are processed by crhomium hgcm thread independently from our internal cmd processing pipeline
+ * this is why we process them specially */
if (vboxVDMACmdCheckCrCmd(pVdma, pCmd))
return;
#endif
+#ifndef VBOX_VDMA_WITH_WORKERTHREAD
+ vboxVDMACommandProcess(pVdma, pCmd);
+#else
int rc = VERR_NOT_IMPLEMENTED;
-#ifdef VBOX_VDMA_WITH_WORKERTHREAD
-
-#ifdef DEBUG_misha
+# ifdef DEBUG_misha
Assert(0);
-#endif
+# endif
VBOXVDMACMD_SUBMIT_CONTEXT Context;
Context.pVdma = pVdma;
@@ -1300,11 +1298,11 @@ void vboxVDMACommand(struct VBOXVDMAHOST *pVdma, PVBOXVDMACBUF_DR pCmd)
}
rc = VERR_OUT_OF_RESOURCES;
}
-#endif
/* failure */
Assert(RT_FAILURE(rc));
PHGSMIINSTANCE pIns = pVdma->pHgsmi;
pCmd->rc = rc;
int tmpRc = VBoxSHGSMICommandComplete (pIns, pCmd);
AssertRC(tmpRc);
+#endif
}
diff --git a/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp b/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp
index 3f8ee26c7..40c23e0f7 100644
--- a/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp
+++ b/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp
@@ -1739,8 +1739,6 @@ int HGSMICompleteGuestCommand(PHGSMIINSTANCE pIns,
{
LogFlowFunc(("pIns = %p, pvMem = %p\n", pIns, pvMem));
- VM_ASSERT_OTHER_THREAD(pIns->pVM);
-
int rc = VINF_SUCCESS;
HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&pIns->hostHeap, pvMem);
Assert(offBuffer != HGSMIOFFSET_VOID);
diff --git a/src/VBox/Devices/Input/DevPS2.cpp b/src/VBox/Devices/Input/DevPS2.cpp
index cd61338b1..420ca6bf3 100644
--- a/src/VBox/Devices/Input/DevPS2.cpp
+++ b/src/VBox/Devices/Input/DevPS2.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevPS2.cpp $ */
+/* $Id: DevPS2.cpp 37466 2011-06-15 12:44:16Z vboxsync $ */
/** @file
* DevPS2 - PS/2 keyboard & mouse controller device.
*/
@@ -266,8 +266,8 @@ typedef struct KBDState {
} Mouse;
} KBDState;
-/* Table to convert from PC scancodes to raw scancodes. */
-static const unsigned char ps2_raw_keycode[128] = {
+/* Table to convert from PC scancodes to scan code set 2. */
+static const unsigned char ps2_raw_keycode_set2[128] = {
0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
@@ -278,6 +278,18 @@ static const unsigned char ps2_raw_keycode[128] = {
19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
};
+/* Table to convert from PC scancodes to scan code set 3. */
+static const unsigned char ps2_raw_keycode_set3[128] = {
+ 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
+ 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 17, 28, 27,
+ 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 92, 26, 34, 33, 42,
+ 50, 49, 58, 65, 73, 74, 89,124, 25, 41, 20, 5, 6, 4, 12, 3,
+ 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105,
+ 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63,
+ 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
+ 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
+};
+
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
/* update irq and KBD_STAT_[MOUSE_]OBF */
@@ -378,11 +390,14 @@ static void pc_kbd_put_keycode(void *opaque, int keycode)
KBDState *s = (KBDState*)opaque;
/* XXX: add support for scancode sets 1 and 3 */
- if (!s->translate && keycode < 0xe0 && s->scancode_set == 2)
+ if (!s->translate && keycode < 0xe0 && s->scancode_set >= 2)
{
if (keycode & 0x80)
kbd_queue(s, 0xf0, 0);
- keycode = ps2_raw_keycode[keycode & 0x7f];
+ if (s->scancode_set == 2)
+ keycode = ps2_raw_keycode_set2[keycode & 0x7f];
+ else if (s->scancode_set == 3)
+ keycode = ps2_raw_keycode_set3[keycode & 0x7f];
}
kbd_queue(s, keycode, 0);
}
@@ -637,8 +652,10 @@ static int kbd_write_keyboard(KBDState *s, int val)
else if (s->scancode_set == 3)
pc_kbd_put_keycode(s, 0x3f);
} else {
- if (val >= 1 && val <= 3)
+ if (val >= 1 && val <= 3) {
+ LogRel(("kbd: scan code set %d selected\n", val));
s->scancode_set = val;
+ }
kbd_queue(s, KBD_REPLY_ACK, 0);
}
#else
@@ -1761,7 +1778,7 @@ static DECLCALLBACK(int) kbdConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNO
/*
* Initialize the critical section.
*/
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "PS2KM#%d", iInstance);
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "PS2KM#%u", iInstance);
if (RT_FAILURE(rc))
return rc;
diff --git a/src/VBox/Devices/Input/DrvKeyboardQueue.cpp b/src/VBox/Devices/Input/DrvKeyboardQueue.cpp
index 449744dac..1fe7e8479 100644
--- a/src/VBox/Devices/Input/DrvKeyboardQueue.cpp
+++ b/src/VBox/Devices/Input/DrvKeyboardQueue.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvKeyboardQueue.cpp $ */
+/* $Id: DrvKeyboardQueue.cpp 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* VBox input devices: Keyboard queue driver
*/
diff --git a/src/VBox/Devices/Input/DrvMouseQueue.cpp b/src/VBox/Devices/Input/DrvMouseQueue.cpp
index f63fdfe1d..ed1689b18 100644
--- a/src/VBox/Devices/Input/DrvMouseQueue.cpp
+++ b/src/VBox/Devices/Input/DrvMouseQueue.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvMouseQueue.cpp $ */
+/* $Id: DrvMouseQueue.cpp 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* VBox input devices: Mouse queue driver
*/
diff --git a/src/VBox/Devices/Input/UsbKbd.cpp b/src/VBox/Devices/Input/UsbKbd.cpp
index 21e745232..8f709012c 100644
--- a/src/VBox/Devices/Input/UsbKbd.cpp
+++ b/src/VBox/Devices/Input/UsbKbd.cpp
@@ -1,4 +1,4 @@
-/* $Id: UsbKbd.cpp $ */
+/* $Id: UsbKbd.cpp 37795 2011-07-06 10:28:24Z vboxsync $ */
/** @file
* UsbKbd - USB Human Interface Device Emulation, Keyboard.
*/
@@ -42,6 +42,7 @@
/** @name USB HID specific descriptor types
* @{ */
+#define DT_IF_HID_DESCRIPTOR 0x21
#define DT_IF_HID_REPORT 0x22
/** @} */
@@ -317,8 +318,9 @@ static const VUSBDESCCONFIGEX g_UsbHidConfigDesc =
/* .bmAttributes = */ RT_BIT(7),
/* .MaxPower = */ 50 /* 100mA */
},
- NULL,
- &g_aUsbHidInterfaces[0]
+ NULL, /* pvMore */
+ &g_aUsbHidInterfaces[0],
+ NULL /* pvOriginal */
};
static const VUSBDESCDEVICE g_UsbHidDeviceDesc =
@@ -604,11 +606,11 @@ static int usbHidCompleteOk(PUSBHID pThis, PVUSBURB pUrb, size_t cbData)
/**
* Reset worker for usbHidUsbReset, usbHidUsbSetConfiguration and
- * usbHidUrbHandleDefaultPipe.
+ * usbHidHandleDefaultPipe.
*
* @returns VBox status code.
* @param pThis The HID instance.
- * @param pUrb Set when usbHidUrbHandleDefaultPipe is the
+ * @param pUrb Set when usbHidHandleDefaultPipe is the
* caller.
* @param fSetConfig Set when usbHidUsbSetConfiguration is the
* caller.
@@ -903,7 +905,7 @@ static DECLCALLBACK(int) usbHidKeyboardPutEvent(PPDMIKEYBOARDPORT pInterface, ui
u8HidCode = u32Usage & 0xFF;
AssertReturn(u8HidCode <= VBOX_USB_MAX_USAGE_CODE, VERR_INTERNAL_ERROR);
- LogRelFlowFunc(("key %s: 0x%x->0x%x\n",
+ LogFlowFunc(("key %s: 0x%x->0x%x\n",
fKeyDown ? "down" : "up", u8KeyCode, u8HidCode));
if (fKeyDown)
@@ -1083,7 +1085,20 @@ static int usbHidHandleDefaultPipe(PUSBHID pThis, PUSBHIDEP pEp, PVUSBURB pUrb)
{
switch (pSetup->wValue >> 8)
{
+ case DT_IF_HID_DESCRIPTOR:
+ {
+ uint32_t cbCopy;
+
+ /* Returned data is written after the setup message. */
+ cbCopy = pUrb->cbData - sizeof(*pSetup);
+ cbCopy = RT_MIN(cbCopy, sizeof(g_UsbHidIfHidDesc));
+ Log(("usbHidKbd: GET_DESCRIPTOR DT_IF_HID_DESCRIPTOR wValue=%#x wIndex=%#x cbCopy=%#x\n", pSetup->wValue, pSetup->wIndex, cbCopy));
+ memcpy(&pUrb->abData[sizeof(*pSetup)], &g_UsbHidIfHidDesc, cbCopy);
+ return usbHidCompleteOk(pThis, pUrb, cbCopy + sizeof(*pSetup));
+ }
+
case DT_IF_HID_REPORT:
+ {
uint32_t cbCopy;
/* Returned data is written after the setup message. */
@@ -1092,6 +1107,8 @@ static int usbHidHandleDefaultPipe(PUSBHID pThis, PUSBHIDEP pEp, PVUSBURB pUrb)
Log(("usbHid: GET_DESCRIPTOR DT_IF_HID_REPORT wValue=%#x wIndex=%#x cbCopy=%#x\n", pSetup->wValue, pSetup->wIndex, cbCopy));
memcpy(&pUrb->abData[sizeof(*pSetup)], &g_UsbHidReportDesc, cbCopy);
return usbHidCompleteOk(pThis, pUrb, cbCopy + sizeof(*pSetup));
+ }
+
default:
Log(("usbHid: GET_DESCRIPTOR, huh? wValue=%#x wIndex=%#x\n", pSetup->wValue, pSetup->wIndex));
break;
@@ -1225,7 +1242,7 @@ static int usbHidHandleDefaultPipe(PUSBHID pThis, PUSBHIDEP pEp, PVUSBURB pUrb)
/**
- * @copydoc PDMUSBREG::pfnQueue
+ * @copydoc PDMUSBREG::pfnUrbQueue
*/
static DECLCALLBACK(int) usbHidQueue(PPDMUSBINS pUsbIns, PVUSBURB pUrb)
{
@@ -1407,7 +1424,7 @@ static DECLCALLBACK(int) usbHidConstruct(PPDMUSBINS pUsbIns, int iInstance, PCFG
/*
* Attach the keyboard driver.
*/
- rc = pUsbIns->pHlpR3->pfnDriverAttach(pUsbIns, 0 /*iLun*/, &pThis->Lun0.IBase, &pThis->Lun0.pDrvBase, "Keyboard Port");
+ rc = PDMUsbHlpDriverAttach(pUsbIns, 0 /*iLun*/, &pThis->Lun0.IBase, &pThis->Lun0.pDrvBase, "Keyboard Port");
if (RT_FAILURE(rc))
return PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS, N_("HID failed to attach keyboard driver"));
@@ -1464,7 +1481,7 @@ const PDMUSBREG g_UsbHidKbd =
NULL,
/* pfnUsbReset */
usbHidUsbReset,
- /* pfnUsbGetCachedDescriptors */
+ /* pfnUsbGetDescriptorCache */
usbHidUsbGetDescriptorCache,
/* pfnUsbSetConfiguration */
usbHidUsbSetConfiguration,
@@ -1474,7 +1491,7 @@ const PDMUSBREG g_UsbHidKbd =
usbHidUsbClearHaltedEndpoint,
/* pfnUrbNew */
NULL/*usbHidUrbNew*/,
- /* pfnQueue */
+ /* pfnUrbQueue */
usbHidQueue,
/* pfnUrbCancel */
usbHidUrbCancel,
diff --git a/src/VBox/Devices/Input/UsbMouse.cpp b/src/VBox/Devices/Input/UsbMouse.cpp
index 3cc36854c..d6e48c6f6 100644
--- a/src/VBox/Devices/Input/UsbMouse.cpp
+++ b/src/VBox/Devices/Input/UsbMouse.cpp
@@ -42,6 +42,7 @@
/** @name USB HID specific descriptor types
* @{ */
+#define DT_IF_HID_DESCRIPTOR 0x21
#define DT_IF_HID_REPORT 0x22
/** @} */
@@ -151,6 +152,9 @@ typedef struct USBHID
/** Is this an absolute pointing device (tablet)? Relative (mouse) otherwise. */
bool isAbsolute;
+ /** Tablet coordinate shift factor for old and broken operating systems. */
+ uint8_t u8CoordShift;
+
/**
* Mouse port - LUN#0.
*
@@ -408,8 +412,9 @@ static const VUSBDESCCONFIGEX g_UsbHidMConfigDesc =
/* .bmAttributes = */ RT_BIT(7),
/* .MaxPower = */ 50 /* 100mA */
},
- NULL,
- &g_aUsbHidMInterfaces[0]
+ NULL, /* pvMore */
+ &g_aUsbHidMInterfaces[0],
+ NULL /* pvOriginal */
};
static const VUSBDESCCONFIGEX g_UsbHidTConfigDesc =
@@ -424,8 +429,9 @@ static const VUSBDESCCONFIGEX g_UsbHidTConfigDesc =
/* .bmAttributes = */ RT_BIT(7),
/* .MaxPower = */ 50 /* 100mA */
},
- NULL,
- &g_aUsbHidTInterfaces[0]
+ NULL, /* pvMore */
+ &g_aUsbHidTInterfaces[0],
+ NULL /* pvOriginal */
};
static const VUSBDESCDEVICE g_UsbHidMDeviceDesc =
@@ -641,11 +647,11 @@ static int usbHidCompleteOk(PUSBHID pThis, PVUSBURB pUrb, size_t cbData)
/**
* Reset worker for usbHidUsbReset, usbHidUsbSetConfiguration and
- * usbHidUrbHandleDefaultPipe.
+ * usbHidHandleDefaultPipe.
*
* @returns VBox status code.
* @param pThis The HID instance.
- * @param pUrb Set when usbHidUrbHandleDefaultPipe is the
+ * @param pUrb Set when usbHidHandleDefaultPipe is the
* caller.
* @param fSetConfig Set when usbHidUsbSetConfiguration is the
* caller.
@@ -799,8 +805,8 @@ static DECLCALLBACK(int) usbHidMousePutEventAbs(PPDMIMOUSEPORT pInterface, uint3
USBHIDT_REPORT report;
report.btn = pThis->PtrDelta.btn;
- report.cx = u32X / 2;
- report.cy = u32Y / 2;
+ report.cx = u32X >> pThis->u8CoordShift;
+ report.cy = u32Y >> pThis->u8CoordShift;
report.dz = clamp_i8(pThis->PtrDelta.dZ);
cbCopy = sizeof(report);
@@ -959,11 +965,32 @@ static int usbHidHandleDefaultPipe(PUSBHID pThis, PUSBHIDEP pEp, PVUSBURB pUrb)
{
switch (pSetup->wValue >> 8)
{
- case DT_IF_HID_REPORT:
- uint32_t cbCopy;
- uint32_t cbDesc;
- const uint8_t *pDesc;
+ uint32_t cbCopy;
+ uint32_t cbDesc;
+ const uint8_t *pDesc;
+
+ case DT_IF_HID_DESCRIPTOR:
+ {
+ if (pThis->isAbsolute)
+ {
+ cbDesc = sizeof(g_UsbHidTIfHidDesc);
+ pDesc = (const uint8_t *)&g_UsbHidTIfHidDesc;
+ }
+ else
+ {
+ cbDesc = sizeof(g_UsbHidMIfHidDesc);
+ pDesc = (const uint8_t *)&g_UsbHidMIfHidDesc;
+ }
+ /* Returned data is written after the setup message. */
+ cbCopy = pUrb->cbData - sizeof(*pSetup);
+ cbCopy = RT_MIN(cbCopy, cbDesc);
+ Log(("usbHidMouse: GET_DESCRIPTOR DT_IF_HID_DESCRIPTOR wValue=%#x wIndex=%#x cbCopy=%#x\n", pSetup->wValue, pSetup->wIndex, cbCopy));
+ memcpy(&pUrb->abData[sizeof(*pSetup)], pDesc, cbCopy);
+ return usbHidCompleteOk(pThis, pUrb, cbCopy + sizeof(*pSetup));
+ }
+ case DT_IF_HID_REPORT:
+ {
if (pThis->isAbsolute)
{
cbDesc = sizeof(g_UsbHidTReportDesc);
@@ -980,6 +1007,8 @@ static int usbHidHandleDefaultPipe(PUSBHID pThis, PUSBHIDEP pEp, PVUSBURB pUrb)
Log(("usbHid: GET_DESCRIPTOR DT_IF_HID_REPORT wValue=%#x wIndex=%#x cbCopy=%#x\n", pSetup->wValue, pSetup->wIndex, cbCopy));
memcpy(&pUrb->abData[sizeof(*pSetup)], pDesc, cbCopy);
return usbHidCompleteOk(pThis, pUrb, cbCopy + sizeof(*pSetup));
+ }
+
default:
Log(("usbHid: GET_DESCRIPTOR, huh? wValue=%#x wIndex=%#x\n", pSetup->wValue, pSetup->wIndex));
break;
@@ -1083,7 +1112,7 @@ static int usbHidHandleDefaultPipe(PUSBHID pThis, PUSBHIDEP pEp, PVUSBURB pUrb)
/**
- * @copydoc PDMUSBREG::pfnQueue
+ * @copydoc PDMUSBREG::pfnUrbQueue
*/
static DECLCALLBACK(int) usbHidQueue(PPDMUSBINS pUsbIns, PVUSBURB pUrb)
{
@@ -1257,7 +1286,7 @@ static DECLCALLBACK(int) usbHidConstruct(PPDMUSBINS pUsbIns, int iInstance, PCFG
/*
* Validate and read the configuration.
*/
- rc = CFGMR3ValidateConfig(pCfg, "/", "Absolute", "Config", "UsbHid", iInstance);
+ rc = CFGMR3ValidateConfig(pCfg, "/", "Absolute|CoordShift", "Config", "UsbHid", iInstance);
if (RT_FAILURE(rc))
return rc;
rc = CFGMR3QueryBoolDef(pCfg, "Absolute", &pThis->isAbsolute, false);
@@ -1271,7 +1300,7 @@ static DECLCALLBACK(int) usbHidConstruct(PPDMUSBINS pUsbIns, int iInstance, PCFG
/*
* Attach the mouse driver.
*/
- rc = pUsbIns->pHlpR3->pfnDriverAttach(pUsbIns, 0 /*iLun*/, &pThis->Lun0.IBase, &pThis->Lun0.pDrvBase, "Mouse Port");
+ rc = PDMUsbHlpDriverAttach(pUsbIns, 0 /*iLun*/, &pThis->Lun0.IBase, &pThis->Lun0.pDrvBase, "Mouse Port");
if (RT_FAILURE(rc))
return PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS, N_("HID failed to attach mouse driver"));
@@ -1279,6 +1308,10 @@ static DECLCALLBACK(int) usbHidConstruct(PPDMUSBINS pUsbIns, int iInstance, PCFG
if (!pThis->Lun0.pDrv)
return PDMUsbHlpVMSetError(pUsbIns, VERR_PDM_MISSING_INTERFACE, RT_SRC_POS, N_("HID failed to query mouse interface"));
+ rc = CFGMR3QueryU8Def(pCfg, "CoordShift", &pThis->u8CoordShift, 1);
+ if (RT_FAILURE(rc))
+ return PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS, N_("HID failed to query shift factor"));
+
return VINF_SUCCESS;
}
@@ -1328,7 +1361,7 @@ const PDMUSBREG g_UsbHidMou =
NULL,
/* pfnUsbReset */
usbHidUsbReset,
- /* pfnUsbGetCachedDescriptors */
+ /* pfnUsbGetDescriptorCache */
usbHidUsbGetDescriptorCache,
/* pfnUsbSetConfiguration */
usbHidUsbSetConfiguration,
@@ -1338,7 +1371,7 @@ const PDMUSBREG g_UsbHidMou =
usbHidUsbClearHaltedEndpoint,
/* pfnUrbNew */
NULL/*usbHidUrbNew*/,
- /* pfnQueue */
+ /* pfnUrbQueue */
usbHidQueue,
/* pfnUrbCancel */
usbHidUrbCancel,
diff --git a/src/VBox/Devices/Makefile.kmk b/src/VBox/Devices/Makefile.kmk
index ed95f4885..ce5a3bab4 100644
--- a/src/VBox/Devices/Makefile.kmk
+++ b/src/VBox/Devices/Makefile.kmk
@@ -1,10 +1,10 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37810 2011-07-07 08:36:00Z vboxsync $
## @file
# Top-level sub-makefile for the devices, drivers and services.
#
#
-# 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;
@@ -57,8 +57,8 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
ifdef VBOX_WITH_USB
VBoxDDU_DEFS += VBOX_WITH_USB IN_USBLIB
VBoxDDU_SDKS.win = WINPSDK W2K3DDK
- if defined(VBOX_WITH_EHCI) && !defined(VBOX_WITH_EXTPACK_PUEL)
- VBoxDDU_DEFS += VBOX_WITH_EHCI
+ if defined(VBOX_WITH_EHCI_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+ VBoxDDU_DEFS += VBOX_WITH_EHCI_IMPL
endif
ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
VBoxDDU_DEFS.darwin += VBOX_WITH_NEW_USB_CODE_ON_DARWIN
@@ -84,6 +84,8 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
ifdef VBOX_WITH_USB
VBoxDDU_LIBS += \
$(PATH_LIB)/USBLib$(VBOX_SUFF_LIB)
+ VBoxDDU_LIBS.win += \
+ $(PATH_LIB)/VBoxDrvCfg$(VBOX_SUFF_LIB)
endif
ifeq ($(KBUILD_TARGET),l4)
VBoxDDU_LIBS += \
@@ -120,8 +122,8 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
VBoxDD_DEFS = VBOX_ACPI
ifdef VBOX_WITH_USB
VBoxDD_DEFS += VBOX_WITH_USB
- if defined(VBOX_WITH_EHCI) && !defined(VBOX_WITH_EXTPACK_PUEL)
- VBoxDD_DEFS += VBOX_WITH_EHCI
+ if defined(VBOX_WITH_EHCI_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+ VBoxDD_DEFS += VBOX_WITH_EHCI_IMPL
endif
endif
ifdef VBOX_WITH_VUSB
@@ -157,9 +159,15 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
ifdef VBOX_WITH_DRV_DISK_INTEGRITY
VBoxDD_DEFS += VBOX_WITH_DRV_DISK_INTEGRITY
endif
+ ifdef VBOX_WITH_UDPTUNNEL
+ VBoxDD_DEFS += VBOX_WITH_UDPTUNNEL
+ endif
ifdef VBOX_WITH_VDE
VBoxDD_DEFS += VBOX_WITH_VDE
endif
+ if defined(VBOX_WITH_PCI_PASSTHROUGH_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+ VBoxDD_DEFS += VBOX_WITH_PCI_PASSTHROUGH_IMPL
+ endif
VBoxDD_LIBS = \
$(PATH_LIB)/DevicesR3$(VBOX_SUFF_LIB) \
@@ -230,6 +238,7 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
VBoxDD2_SOURCES = \
build/VBoxDD2.cpp \
PC/DevAPIC.cpp \
+ PC/DevIoApic.cpp \
PC/DevSMC.cpp \
PC/DevLPC.cpp
VBoxDD2_LIBS = \
@@ -261,6 +270,7 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
VBOX_HGCM_HOST_CODE \
VBOX_WITH_HGCM \
$(if $(VBOX_BIOS_DMI_FALLBACK),VBOX_BIOS_DMI_FALLBACK,)
+
DevicesR3_DEFS.linux += _GNU_SOURCE
DevicesR3_DEFS.l4 += _GNU_SOURCE
@@ -275,7 +285,6 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
Bus/DevPciIch9.cpp \
Bus/MsiCommon.cpp \
Bus/MsixCommon.cpp \
- Bus/DevPciRaw.cpp \
Graphics/DevVGA.cpp \
Storage/DevATA.cpp \
PC/DevPit-i8254.cpp \
@@ -437,12 +446,18 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
endif
ifdef VBOX_WITH_USB
DevicesR3_DEFS += VBOX_WITH_USB
- if defined(VBOX_WITH_EHCI) && !defined(VBOX_WITH_EXTPACK_PUEL)
- DevicesR3_DEFS += VBOX_WITH_EHCI
+ if defined(VBOX_WITH_EHCI_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+ DevicesR3_DEFS += VBOX_WITH_EHCI_IMPL
DevicesR3_SOURCES += \
USB/DevEHCI.cpp
endif
endif
+ if defined(VBOX_WITH_PCI_PASSTHROUGH_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+ DevicesR3_DEFS += VBOX_WITH_PCI_PASSTHROUGH_IMPL
+ DevicesR3_SOURCES += \
+ Bus/DevPciRaw.cpp
+
+ endif
ifdef VBOX_WITH_DTRACE_R3
DevicesR3_DEFS += VBOX_WITH_DTRACE
@@ -516,8 +531,9 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
# For finding PCIInternal.h from VBox/pci.h.
Bus/DevPCI.cpp_INCS = Bus
Bus/DevPciIch9.cpp_INCS = Bus
- Bus/MsiCommon.cpp_INCS = Bus
+ Bus/MsiCommon.cpp_INCS = Bus
Bus/MsixCommon.cpp_INCS = Bus
+ Bus/DevPciRaw.cpp_INCS = Bus
# For finding and generating vbetables.h (see Graphics/BIOS/Makefile.kmk).
Graphics/DevVGA.cpp_INCS = $(VgaBiosBin_0_OUTDIR)
@@ -539,7 +555,6 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
Bus/DevPciIch9.cpp \
Bus/MsiCommon.cpp \
Bus/MsixCommon.cpp \
- Bus/DevPciRaw.cpp \
Graphics/DevVGA.cpp \
Input/DevPS2.cpp \
PC/DevACPI.cpp \
@@ -592,8 +607,8 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
ifdef VBOX_WITH_USB
VBoxDDGC_DEFS += VBOX_WITH_USB
- if defined(VBOX_WITH_EHCI) && !defined(VBOX_WITH_EXTPACK_PUEL)
- VBoxDDGC_DEFS += VBOX_WITH_EHCI
+ if defined(VBOX_WITH_EHCI_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+ VBoxDDGC_DEFS += VBOX_WITH_EHCI_IMPL
VBoxDDGC_SOURCES += \
USB/DevEHCI.cpp
endif
@@ -638,11 +653,11 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
VBoxDDR0_DEFS = IN_RT_R0 VBOX_WITH_HGCM # - WTF is IN_RT_R0 doing here?
VBoxDDR0_INCS = build
VBoxDDR0_SOURCES = \
+ build/VBoxDDR0.cpp \
Bus/DevPCI.cpp \
Bus/DevPciIch9.cpp \
Bus/MsiCommon.cpp \
Bus/MsixCommon.cpp \
- Bus/DevPciRaw.cpp \
Graphics/DevVGA.cpp \
Input/DevPS2.cpp \
PC/DevACPI.cpp \
@@ -696,13 +711,18 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
endif
ifdef VBOX_WITH_USB
VBoxDDR0_DEFS += VBOX_WITH_USB
- if defined(VBOX_WITH_EHCI) && !defined(VBOX_WITH_EXTPACK_PUEL)
- VBoxDDR0_DEFS += VBOX_WITH_EHCI
+ if defined(VBOX_WITH_EHCI_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+ VBoxDDR0_DEFS += VBOX_WITH_EHCI_IMPL
VBoxDDR0_SOURCES += \
USB/DevEHCI.cpp
endif
endif
+ if defined(VBOX_WITH_PCI_PASSTHROUGH_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+ VBoxDDR0_SOURCES +=
+ Bus/DevPciRaw.cpp
+ endif
+
ifdef VBOX_WITH_AHCI
VBoxDDR0_DEFS += VBOX_WITH_AHCI IN_AHCI_R0
VBoxDDR0_SOURCES += \
@@ -744,12 +764,13 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
VBoxDD2GC_DEFS =
VBoxDD2GC_INCS = build
VBoxDD2GC_SOURCES = \
- PC/DevAPIC.cpp \
- PC/DevSMC.cpp
+ PC/DevAPIC.cpp \
+ PC/DevIoApic.cpp \
+ PC/DevSMC.cpp
if1of ($(VBOX_LDR_FMT32), pe lx)
- VBoxDD2GC_LIBS = \
- $(PATH_LIB)/VMMRCBuiltin$(VBOX_SUFF_LIB) \
- $(PATH_LIB)/VMMRCImp$(VBOX_SUFF_LIB)
+ VBoxDD2GC_LIBS = \
+ $(PATH_LIB)/VMMRCBuiltin$(VBOX_SUFF_LIB) \
+ $(PATH_LIB)/VMMRCImp$(VBOX_SUFF_LIB)
endif
endif
@@ -760,13 +781,15 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
VBoxDD2R0_DEFS = IN_RT_R0
VBoxDD2R0_INCS = build
VBoxDD2R0_SOURCES = \
- PC/DevAPIC.cpp \
- PC/DevSMC.cpp
+ build/VBoxDD2R0.cpp \
+ PC/DevAPIC.cpp \
+ PC/DevIoApic.cpp \
+ PC/DevSMC.cpp
if1of ($(VBOX_LDR_FMT), pe lx)
- VBoxDD2R0_LIBS = \
- $(PATH_LIB)/VMMR0Imp$(VBOX_SUFF_LIB) \
- $(PATH_LIB)/SUPR0$(VBOX_SUFF_LIB)
+ VBoxDD2R0_LIBS = \
+ $(PATH_LIB)/VMMR0Imp$(VBOX_SUFF_LIB) \
+ $(PATH_LIB)/SUPR0$(VBOX_SUFF_LIB)
endif
@@ -911,12 +934,16 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
Storage/DrvDiskIntegrity.cpp
endif
+ ifdef VBOX_WITH_UDPTUNNEL
+ Drivers_SOURCES += \
+ Network/DrvUDPTunnel.cpp
+ Drivers_DEFS += VBOX_WITH_UDPTUNNEL
+ endif
ifdef VBOX_WITH_VDE
- Drivers_SOURCES += \
+ Drivers_SOURCES += \
Network/DrvVDE.cpp \
Network/VDEPlug.cpp
- Drivers_DEFS += \
- VBOX_WITH_VDE
+ Drivers_DEFS += VBOX_WITH_VDE
endif
# -- OS specific --
@@ -1118,12 +1145,12 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
# Ring-0 Services (library, linked into VMMR0.r0)
#
ServicesR0_TEMPLATE = VBoxR0
- ServicesR0_DEFS = IN_INTNET_R0 IN_RT_R0
+ ServicesR0_DEFS = IN_INTNET_R0 IN_RT_R0 $(if $(VBOX_WITH_PCI_PASSTHROUGH_IMPL),IN_PCIRAW_R0,)
ServicesR0_SOURCES = \
- Network/SrvIntNetR0.cpp
+ Network/SrvIntNetR0.cpp \
+ $(if $(VBOX_WITH_PCI_PASSTHROUGH),Bus/SrvPciRawR0.cpp,)
Network/SrvIntNetR0.cpp_CXXFLAGS := $(if-expr $(KBUILD_TARGET) == "win",,$(VBOX_GCC_Wno-array_bounds))
-
#
# Internal Networking - Ring-3 Testcase for the Ring-0 code (a bit hackish).
#
@@ -1189,6 +1216,22 @@ ifdef VBOX_WITH_EXTPACK_PUEL
endif
endif
+ if defined(VBOX_WITH_PCI_PASSTHROUGH)
+ DLLS += VBoxPciRawR3
+ VBoxPciRawR3_TEMPLATE = VBoxR3ExtPackPuel
+ VBoxPciRawR3_SOURCES = Bus/DevPciRaw.cpp
+
+ DLLS += VBoxPciRawDrv
+ VBoxPciRawDrv_TEMPLATE = VBoxR3ExtPackPuel
+ VBoxPciRawDrv_SOURCES = Bus/DrvPciRaw.cpp
+
+ SYSMODS += VBoxPciRawR0
+ VBoxPciRawR0_TEMPLATE = VBoxR0ExtPackPuel
+ VBoxPciRawR0_SOURCES = Bus/DevPciRaw.cpp
+
+ Bus/DevPciRaw.cpp_INCS = Bus
+ endif
+
#
# The Intel PXE rom.
#
diff --git a/src/VBox/Devices/Network/DevE1000.cpp b/src/VBox/Devices/Network/DevE1000.cpp
index c367482ca..3bee0e4ae 100644
--- a/src/VBox/Devices/Network/DevE1000.cpp
+++ b/src/VBox/Devices/Network/DevE1000.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevE1000.cpp $ */
+/* $Id: DevE1000.cpp 37644 2011-06-27 11:09:36Z vboxsync $ */
/** @file
* DevE1000 - Intel 82540EM Ethernet Controller Emulation.
*
@@ -1124,13 +1124,6 @@ typedef struct E1kState_st E1KSTATE;
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
/* Forward declarations ******************************************************/
-RT_C_DECLS_BEGIN
-PDMBOTHCBDECL(int) e1kMMIORead (PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) e1kMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) e1kIOPortIn (PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) e1kIOPortOut(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t u32, unsigned cb);
-RT_C_DECLS_END
-
static int e1kXmitPending(E1KSTATE *pState, bool fOnWorkerThread);
static int e1kRegReadUnimplemented (E1KSTATE* pState, uint32_t offset, uint32_t index, uint32_t *pu32Value);
@@ -1414,6 +1407,7 @@ DECLINLINE(void) e1kCancelTimer(E1KSTATE *pState, PTMTIMER pTimer)
}
#ifdef E1K_GLOBAL_MUTEX
+
DECLINLINE(int) e1kCsEnter(E1KSTATE *pState, int iBusyRc)
{
return VINF_SUCCESS;
@@ -1423,11 +1417,11 @@ DECLINLINE(void) e1kCsLeave(E1KSTATE *pState)
{
}
-#define e1kCsRxEnter(ps, rc) VINF_SUCCESS
-#define e1kCsRxLeave(ps) do { } while (0)
+# define e1kCsRxEnter(ps, rc) VINF_SUCCESS
+# define e1kCsRxLeave(ps) do { } while (0)
-#define e1kCsTxEnter(ps, rc) VINF_SUCCESS
-#define e1kCsTxLeave(ps) do { } while (0)
+# define e1kCsTxEnter(ps, rc) VINF_SUCCESS
+# define e1kCsTxLeave(ps) do { } while (0)
DECLINLINE(int) e1kMutexAcquire(E1KSTATE *pState, int iBusyRc, RT_SRC_POS_DECL)
@@ -1455,18 +1449,18 @@ DECLINLINE(void) e1kMutexRelease(E1KSTATE *pState)
}
#else /* !E1K_GLOBAL_MUTEX */
-#define e1kCsEnter(ps, rc) PDMCritSectEnter(&ps->cs, rc)
-#define e1kCsLeave(ps) PDMCritSectLeave(&ps->cs)
+# define e1kCsEnter(ps, rc) PDMCritSectEnter(&ps->cs, rc)
+# define e1kCsLeave(ps) PDMCritSectLeave(&ps->cs)
-#define e1kCsRxEnter(ps, rc) PDMCritSectEnter(&ps->csRx, rc)
-#define e1kCsRxLeave(ps) PDMCritSectLeave(&ps->csRx)
+# define e1kCsRxEnter(ps, rc) PDMCritSectEnter(&ps->csRx, rc)
+# define e1kCsRxLeave(ps) PDMCritSectLeave(&ps->csRx)
-#define e1kCsTxEnter(ps, rc) VINF_SUCCESS
-#define e1kCsTxLeave(ps) do { } while (0)
-//#define e1kCsTxEnter(ps, rc) PDMCritSectEnter(&ps->csTx, rc)
-//#define e1kCsTxLeave(ps) PDMCritSectLeave(&ps->csTx)
+# define e1kCsTxEnter(ps, rc) VINF_SUCCESS
+# define e1kCsTxLeave(ps) do { } while (0)
+//# define e1kCsTxEnter(ps, rc) PDMCritSectEnter(&ps->csTx, rc)
+//# define e1kCsTxLeave(ps) PDMCritSectLeave(&ps->csTx)
-#if 0
+# if 0
DECLINLINE(int) e1kCsEnter(E1KSTATE *pState, PPDMCRITSECT pCs, int iBusyRc, RT_SRC_POS_DECL)
{
int rc = PDMCritSectEnter(pCs, iBusyRc);
@@ -1490,7 +1484,7 @@ DECLINLINE(void) e1kCsLeave(E1KSTATE *pState, PPDMCRITSECT pCs)
//E1kLog2(("%s <== Leaving critical section\n", INSTANCE(pState)));
PDMCritSectLeave(&pState->cs);
}
-#endif
+# endif
DECLINLINE(int) e1kMutexAcquire(E1KSTATE *pState, int iBusyRc, RT_SRC_POS_DECL)
{
return VINF_SUCCESS;
@@ -1499,9 +1493,10 @@ DECLINLINE(int) e1kMutexAcquire(E1KSTATE *pState, int iBusyRc, RT_SRC_POS_DECL)
DECLINLINE(void) e1kMutexRelease(E1KSTATE *pState)
{
}
-#endif /* !E1K_GLOBAL_MUTEX */
+#endif /* !E1K_GLOBAL_MUTEX */
#ifdef IN_RING3
+
/**
* Wakeup the RX thread.
*/
@@ -1522,7 +1517,7 @@ static void e1kWakeupReceive(PPDMDEVINS pDevIns)
*
* @param pState The device state structure.
*/
-PDMBOTHCBDECL(void) e1kHardReset(E1KSTATE *pState)
+static void e1kHardReset(E1KSTATE *pState)
{
E1kLog(("%s Hard reset triggered\n", INSTANCE(pState)));
memset(pState->auRegs, 0, sizeof(pState->auRegs));
@@ -1543,7 +1538,8 @@ PDMBOTHCBDECL(void) e1kHardReset(E1KSTATE *pState)
if (pState->pDrvR3)
pState->pDrvR3->pfnSetPromiscuousMode(pState->pDrvR3, false);
}
-#endif
+
+#endif /* IN_RING3 */
/**
* Compute Internet checksum.
@@ -1733,7 +1729,7 @@ static void e1kPrintTDesc(E1KSTATE* pState, E1KTXDESC* pDesc, const char* cszDir
*
* @param pState The device state structure.
*/
-PDMBOTHCBDECL(int) e1kRaiseInterrupt(E1KSTATE *pState, int rcBusy, uint32_t u32IntCause = 0)
+static int e1kRaiseInterrupt(E1KSTATE *pState, int rcBusy, uint32_t u32IntCause = 0)
{
int rc = e1kCsEnter(pState, rcBusy);
if (RT_UNLIKELY(rc != VINF_SUCCESS))
@@ -2852,6 +2848,14 @@ static DECLCALLBACK(void) e1kLinkUpTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, vo
{
E1KSTATE *pState = (E1KSTATE *)pvUser;
+ /*
+ * This can happen if we set the link status to down when the Link up timer was
+ * already armed (shortly after e1kLoadDone() or when the cable was disconnected
+ * and connect+disconnect the cable very quick.
+ */
+ if (!pState->fCableConnected)
+ return;
+
if (RT_LIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
{
STATUS |= STATUS_LU;
@@ -4269,7 +4273,8 @@ static int e1kRegRead(E1KSTATE *pState, uint32_t uOffset, void *pv, uint32_t cb)
//pState->fDelayInts = false;
//pState->iStatIntLost += pState->iStatIntLostOne;
//pState->iStatIntLostOne = 0;
- rc = s_e1kRegMap[index].pfnRead(pState, uOffset & 0xFFFFFFFC, index, &u32) & mask;
+ rc = s_e1kRegMap[index].pfnRead(pState, uOffset & 0xFFFFFFFC, index, &u32);
+ u32 &= mask;
//e1kCsLeave(pState);
e1kMutexRelease(pState);
E1kLog2(("%s At %08X read %s from %s (%s)\n",
@@ -4306,7 +4311,7 @@ static int e1kRegRead(E1KSTATE *pState, uint32_t uOffset, void *pv, uint32_t cb)
* @param cb Number of bytes to write.
* @thread EMT
*/
-static int e1kRegWrite(E1KSTATE *pState, uint32_t uOffset, void *pv, unsigned cb)
+static int e1kRegWrite(E1KSTATE *pState, uint32_t uOffset, void const *pv, unsigned cb)
{
int rc = VINF_SUCCESS;
int index = e1kRegLookup(pState, uOffset);
@@ -4409,7 +4414,7 @@ PDMBOTHCBDECL(int) e1kMMIORead(PPDMDEVINS pDevIns, void *pvUser,
* @thread EMT
*/
PDMBOTHCBDECL(int) e1kMMIOWrite(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+ RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
NOREF(pvUser);
E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE *);
@@ -4443,7 +4448,7 @@ PDMBOTHCBDECL(int) e1kMMIOWrite(PPDMDEVINS pDevIns, void *pvUser,
* @thread EMT
*/
PDMBOTHCBDECL(int) e1kIOPortIn(PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT port, uint32_t *pu32, unsigned cb)
+ RTIOPORT port, uint32_t *pu32, unsigned cb)
{
E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE *);
int rc = VINF_SUCCESS;
@@ -4494,7 +4499,7 @@ PDMBOTHCBDECL(int) e1kIOPortIn(PPDMDEVINS pDevIns, void *pvUser,
* @thread EMT
*/
PDMBOTHCBDECL(int) e1kIOPortOut(PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT port, uint32_t u32, unsigned cb)
+ RTIOPORT port, uint32_t u32, unsigned cb)
{
E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE *);
int rc = VINF_SUCCESS;
@@ -5829,7 +5834,7 @@ static DECLCALLBACK(int) e1kConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNO
#ifdef E1K_USE_TX_TIMERS
/* Create Transmit Interrupt Delay Timer */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kTxIntDelayTimer, pState,
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
+ TMTIMER_FLAGS_NO_CRIT_SECT,
"E1000 Transmit Interrupt Delay Timer", &pState->pTIDTimerR3);
if (RT_FAILURE(rc))
return rc;
@@ -5839,7 +5844,7 @@ static DECLCALLBACK(int) e1kConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNO
# ifndef E1K_NO_TAD
/* Create Transmit Absolute Delay Timer */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kTxAbsDelayTimer, pState,
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
+ TMTIMER_FLAGS_NO_CRIT_SECT,
"E1000 Transmit Absolute Delay Timer", &pState->pTADTimerR3);
if (RT_FAILURE(rc))
return rc;
@@ -5851,7 +5856,7 @@ static DECLCALLBACK(int) e1kConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNO
#ifdef E1K_USE_RX_TIMERS
/* Create Receive Interrupt Delay Timer */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kRxIntDelayTimer, pState,
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
+ TMTIMER_FLAGS_NO_CRIT_SECT,
"E1000 Receive Interrupt Delay Timer", &pState->pRIDTimerR3);
if (RT_FAILURE(rc))
return rc;
@@ -5860,7 +5865,7 @@ static DECLCALLBACK(int) e1kConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNO
/* Create Receive Absolute Delay Timer */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kRxAbsDelayTimer, pState,
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
+ TMTIMER_FLAGS_NO_CRIT_SECT,
"E1000 Receive Absolute Delay Timer", &pState->pRADTimerR3);
if (RT_FAILURE(rc))
return rc;
@@ -5870,7 +5875,7 @@ static DECLCALLBACK(int) e1kConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNO
/* Create Late Interrupt Timer */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kLateIntTimer, pState,
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
+ TMTIMER_FLAGS_NO_CRIT_SECT,
"E1000 Late Interrupt Timer", &pState->pIntTimerR3);
if (RT_FAILURE(rc))
return rc;
@@ -5879,7 +5884,7 @@ static DECLCALLBACK(int) e1kConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNO
/* Create Link Up Timer */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kLinkUpTimer, pState,
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
+ TMTIMER_FLAGS_NO_CRIT_SECT,
"E1000 Link Up Timer", &pState->pLUTimerR3);
if (RT_FAILURE(rc))
return rc;
diff --git a/src/VBox/Devices/Network/DevE1000Phy.cpp b/src/VBox/Devices/Network/DevE1000Phy.cpp
index 0d8af67a1..76d3e906c 100644
--- a/src/VBox/Devices/Network/DevE1000Phy.cpp
+++ b/src/VBox/Devices/Network/DevE1000Phy.cpp
@@ -1,4 +1,4 @@
-/** $Id: DevE1000Phy.cpp $ */
+/** $Id: DevE1000Phy.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DevE1000Phy - Intel 82540EM Ethernet Controller Internal PHY Emulation.
*
diff --git a/src/VBox/Devices/Network/DevE1000Phy.h b/src/VBox/Devices/Network/DevE1000Phy.h
index a4e6e2aa0..8fcdee246 100644
--- a/src/VBox/Devices/Network/DevE1000Phy.h
+++ b/src/VBox/Devices/Network/DevE1000Phy.h
@@ -1,4 +1,4 @@
-/** $Id: DevE1000Phy.h $ */
+/** $Id: DevE1000Phy.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* DevE1000Phy - Intel 82540EM Ethernet Controller Internal PHY Emulation, Header.
*/
diff --git a/src/VBox/Devices/Network/DevEEPROM.cpp b/src/VBox/Devices/Network/DevEEPROM.cpp
index 88272be3e..001b2f9f8 100644
--- a/src/VBox/Devices/Network/DevEEPROM.cpp
+++ b/src/VBox/Devices/Network/DevEEPROM.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevEEPROM.cpp $ */
+/* $Id: DevEEPROM.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DevEEPROM - Microware-compatible 64x16-bit 93C46 EEPROM Emulation.
*/
diff --git a/src/VBox/Devices/Network/DevEEPROM.h b/src/VBox/Devices/Network/DevEEPROM.h
index 20e829406..3dbb6bad5 100644
--- a/src/VBox/Devices/Network/DevEEPROM.h
+++ b/src/VBox/Devices/Network/DevEEPROM.h
@@ -1,4 +1,4 @@
-/* $Id: DevEEPROM.h $ */
+/* $Id: DevEEPROM.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* DevEEPROM - Microware-compatible 64x16-bit 93C46 EEPROM Emulation, Header.
*/
diff --git a/src/VBox/Devices/Network/DevINIP.cpp b/src/VBox/Devices/Network/DevINIP.cpp
index 5a44d8782..ed5e91c68 100644
--- a/src/VBox/Devices/Network/DevINIP.cpp
+++ b/src/VBox/Devices/Network/DevINIP.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevINIP.cpp $ */
+/* $Id: DevINIP.cpp 36044 2011-02-21 17:06:48Z vboxsync $ */
/** @file
* DevINIP - Internal Network IP stack device/service.
*/
@@ -74,7 +74,7 @@ typedef struct DEVINTNETIP
PDMIBASE IBase;
/** The network port this device provides (LUN\#0). */
PDMINETWORKDOWN INetworkDown;
- /** Tzhe network configuration port this device provides (LUN\#0). */
+ /** The network configuration port this device provides (LUN\#0). */
PDMINETWORKCONFIG INetworkConfig;
/** The base interface of the network driver below us. */
PPDMIBASE pDrvBase;
diff --git a/src/VBox/Devices/Network/DevPCNet.cpp b/src/VBox/Devices/Network/DevPCNet.cpp
index 64eb521fe..a9cd7b98a 100644
--- a/src/VBox/Devices/Network/DevPCNet.cpp
+++ b/src/VBox/Devices/Network/DevPCNet.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevPCNet.cpp $ */
+/* $Id: DevPCNet.cpp 37636 2011-06-24 14:59:59Z vboxsync $ */
/** @file
* DevPCNet - AMD PCnet-PCI II / PCnet-FAST III (Am79C970A / Am79C973) Ethernet Controller Emulation.
*
@@ -1143,18 +1143,6 @@ DECLINLINE(RTGCPHYS32) pcnetTdraAddr(PCNetState *pThis, int idx)
}
RT_C_DECLS_BEGIN
-PDMBOTHCBDECL(int) pcnetIOPortRead(PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) pcnetIOPortWrite(PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) pcnetIOPortAPromWrite(PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) pcnetIOPortAPromRead(PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) pcnetMMIORead(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) pcnetMMIOWrite(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
#ifndef IN_RING3
DECLEXPORT(int) pcnetHandleRingWrite(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame,
RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
@@ -3864,7 +3852,7 @@ PDMBOTHCBDECL(int) pcnetMMIORead(PPDMDEVINS pDevIns, void *pvUser,
* @param cb Number of bytes to write.
*/
PDMBOTHCBDECL(int) pcnetMMIOWrite(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+ RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
PCNetState *pThis = (PCNetState *)pvUser;
int rc = VINF_SUCCESS;
@@ -3915,6 +3903,8 @@ PDMBOTHCBDECL(int) pcnetMMIOWrite(PPDMDEVINS pDevIns, void *pvUser,
static DECLCALLBACK(void) pcnetTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
{
PCNetState *pThis = (PCNetState *)pvUser;
+ Assert(PDMCritSectIsOwner(&pThis->CritSect));
+
STAM_PROFILE_ADV_START(&pThis->StatTimer, a);
pcnetPollTimer(pThis);
STAM_PROFILE_ADV_STOP(&pThis->StatTimer, a);
@@ -3931,8 +3921,8 @@ static DECLCALLBACK(void) pcnetTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *
static DECLCALLBACK(void) pcnetTimerSoftInt(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
{
PCNetState *pThis = (PCNetState *)pvUser;
+ Assert(PDMCritSectIsOwner(&pThis->CritSect));
-/** @todo why aren't we taking any critsect here?!? */
pThis->aCSR[7] |= 0x0800; /* STINT */
pcnetUpdateIrq(pThis);
TMTimerSetNano(pThis->CTX_SUFF(pTimerSoftInt), 12800U * (pThis->aBCR[BCR_STVAL] & 0xffff));
@@ -5172,7 +5162,7 @@ static DECLCALLBACK(int) pcnetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGM
* This must be done before register the critsect with the timer code, and also before
* attaching drivers or anything else that may call us back.
*/
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "PCNet#%d", iInstance);
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "PCNet#%u", iInstance);
if (RT_FAILURE(rc))
return rc;
@@ -5200,11 +5190,12 @@ static DECLCALLBACK(int) pcnetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGM
{
/* Software Interrupt timer */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimerSoftInt, pThis, /** @todo r=bird: the locking here looks bogus now with SMP... */
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "PCNet SoftInt Timer", &pThis->pTimerSoftIntR3);
+ TMTIMER_FLAGS_NO_CRIT_SECT, "PCNet SoftInt Timer", &pThis->pTimerSoftIntR3);
if (RT_FAILURE(rc))
return rc;
pThis->pTimerSoftIntR0 = TMTimerR0Ptr(pThis->pTimerSoftIntR3);
pThis->pTimerSoftIntRC = TMTimerRCPtr(pThis->pTimerSoftIntR3);
+ TMR3TimerSetCritSect(pThis->pTimerSoftIntR3, &pThis->CritSect);
}
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimerRestore, pThis,
TMTIMER_FLAGS_NO_CRIT_SECT, "PCNet Restore Timer", &pThis->pTimerRestore);
diff --git a/src/VBox/Devices/Network/DevVirtioNet.cpp b/src/VBox/Devices/Network/DevVirtioNet.cpp
index 97a12c05f..ec7c9fd4a 100644
--- a/src/VBox/Devices/Network/DevVirtioNet.cpp
+++ b/src/VBox/Devices/Network/DevVirtioNet.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevVirtioNet.cpp $ */
+/* $Id: DevVirtioNet.cpp 37324 2011-06-03 16:28:03Z vboxsync $ */
/** @file
* DevVirtioNet - Virtio Network Device
*/
@@ -1996,7 +1996,7 @@ static DECLCALLBACK(int) vnetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
/* Create Link Up Timer */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetLinkUpTimer, pState,
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
+ TMTIMER_FLAGS_NO_CRIT_SECT,
"VirtioNet Link Up Timer", &pState->pLinkUpTimer);
if (RT_FAILURE(rc))
return rc;
@@ -2004,7 +2004,7 @@ static DECLCALLBACK(int) vnetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
#ifdef VNET_TX_DELAY
/* Create Transmit Delay Timer */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetTxTimer, pState,
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
+ TMTIMER_FLAGS_NO_CRIT_SECT,
"VirtioNet TX Delay Timer", &pState->pTxTimerR3);
if (RT_FAILURE(rc))
return rc;
diff --git a/src/VBox/Devices/Network/DrvDedicatedNic.cpp b/src/VBox/Devices/Network/DrvDedicatedNic.cpp
index 0196d30b1..5c789d7cb 100644
--- a/src/VBox/Devices/Network/DrvDedicatedNic.cpp
+++ b/src/VBox/Devices/Network/DrvDedicatedNic.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvDedicatedNic.cpp $ */
+/* $Id: DrvDedicatedNic.cpp 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* DrvDedicatedNic - Experimental network driver for using a dedicated (V)NIC.
*/
diff --git a/src/VBox/Devices/Network/DrvIntNet.cpp b/src/VBox/Devices/Network/DrvIntNet.cpp
index 11910b371..b40cf96e5 100644
--- a/src/VBox/Devices/Network/DrvIntNet.cpp
+++ b/src/VBox/Devices/Network/DrvIntNet.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvIntNet.cpp $ */
+/* $Id: DrvIntNet.cpp 37979 2011-07-15 14:04:24Z vboxsync $ */
/** @file
* DrvIntNet - Internal network transport driver.
*/
@@ -41,6 +41,9 @@
#include <iprt/time.h>
#include <iprt/thread.h>
#include <iprt/uuid.h>
+#if defined(RT_OS_DARWIN) && defined(IN_RING3)
+# include <iprt/system.h>
+#endif
#include "VBoxDD.h"
@@ -1357,7 +1360,8 @@ static DECLCALLBACK(int) drvR3IntNetConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg
"|TrunkPolicyHost"
"|TrunkPolicyWire"
"|IsService"
- "|IgnoreConnectFailure",
+ "|IgnoreConnectFailure"
+ "|Workaround1",
"");
/*
@@ -1600,6 +1604,30 @@ static DECLCALLBACK(int) drvR3IntNetConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg
return PDMDRV_SET_ERROR(pDrvIns, rc,
N_("Configuration error: Failed to get the \"IgnoreConnectFailure\" value"));
+ /** @cfgm{Workaround1, boolean, depends}
+ * Enables host specific workarounds, the default is depends on the whether
+ * we think the host requires it or not.
+ */
+ bool fWorkaround1 = false;
+#ifdef RT_OS_DARWIN
+ if (OpenReq.fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE)
+ {
+ char szKrnlVer[256];
+ RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szKrnlVer, sizeof(szKrnlVer));
+ if (strcmp(szKrnlVer, "10.7.0") >= 0)
+ {
+ LogRel(("IntNet#%u: Enables the workaround (ip_tos=0) for the little endian ip header checksum problem\n"));
+ fWorkaround1 = true;
+ }
+ }
+#endif
+ rc = CFGMR3QueryBoolDef(pCfg, "Workaround1", &fWorkaround1, fWorkaround1);
+ if (RT_FAILURE(rc))
+ return PDMDRV_SET_ERROR(pDrvIns, rc,
+ N_("Configuration error: Failed to get the \"Workaround1\" value"));
+ if (fWorkaround1)
+ OpenReq.fFlags |= INTNET_OPEN_FLAGS_WORKAROUND_1;
+
LogRel(("IntNet#%u: szNetwork={%s} enmTrunkType=%d szTrunk={%s} fFlags=%#x cbRecv=%u cbSend=%u fIgnoreConnectFailure=%RTbool\n",
pDrvIns->iInstance, OpenReq.szNetwork, OpenReq.enmTrunkType, OpenReq.szTrunk, OpenReq.fFlags,
OpenReq.cbRecv, OpenReq.cbSend, fIgnoreConnectFailure));
diff --git a/src/VBox/Devices/Network/DrvNAT.cpp b/src/VBox/Devices/Network/DrvNAT.cpp
index f9a8391e6..236e938d1 100644
--- a/src/VBox/Devices/Network/DrvNAT.cpp
+++ b/src/VBox/Devices/Network/DrvNAT.cpp
@@ -1,10 +1,10 @@
-/* $Id: DrvNAT.cpp $ */
+/* $Id: DrvNAT.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* DrvNAT - NAT network transport driver.
*/
/*
- * 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;
@@ -27,12 +27,14 @@
#include <VBox/vmm/pdmdrv.h>
#include <VBox/vmm/pdmnetifs.h>
#include <VBox/vmm/pdmnetinline.h>
+
#include <iprt/assert.h>
+#include <iprt/critsect.h>
+#include <iprt/cidr.h>
#include <iprt/file.h>
#include <iprt/mem.h>
+#include <iprt/pipe.h>
#include <iprt/string.h>
-#include <iprt/critsect.h>
-#include <iprt/cidr.h>
#include <iprt/stream.h>
#include <iprt/uuid.h>
@@ -162,9 +164,9 @@ typedef struct DRVNAT
#endif
#ifndef RT_OS_WINDOWS
/** The write end of the control pipe. */
- RTFILE PipeWrite;
+ RTPIPE hPipeWrite;
/** The read end of the control pipe. */
- RTFILE PipeRead;
+ RTPIPE hPipeRead;
#else
/** for external notification */
HANDLE hWakeupEvent;
@@ -471,8 +473,7 @@ static DECLCALLBACK(int) drvNATNetworkUp_AllocBuf(PPDMINETWORKUP pInterface, siz
if (!pSgBuf->pvAllocator)
{
RTMemFree(pSgBuf);
- /** @todo Implement the VERR_TRY_AGAIN semantics. */
- return VERR_NO_MEMORY;
+ return VERR_TRY_AGAIN;
}
}
else
@@ -486,8 +487,7 @@ static DECLCALLBACK(int) drvNATNetworkUp_AllocBuf(PPDMINETWORKUP pInterface, siz
RTMemFree(pSgBuf->aSegs[0].pvSeg);
RTMemFree(pSgBuf->pvUser);
RTMemFree(pSgBuf);
- /** @todo Implement the VERR_TRY_AGAIN semantics. */
- return VERR_NO_MEMORY;
+ return VERR_TRY_AGAIN;
}
}
@@ -570,7 +570,8 @@ static void drvNATNotifyNATThread(PDRVNAT pThis, const char *pszWho)
int rc;
#ifndef RT_OS_WINDOWS
/* kick poll() */
- rc = RTFileWrite(pThis->PipeWrite, "", 1, NULL);
+ size_t cbIgnored;
+ rc = RTPipeWrite(pThis->hPipeWrite, "", 1, &cbIgnored);
#else
/* kick WSAWaitForMultipleEvents */
rc = WSASetEvent(pThis->hWakeupEvent);
@@ -745,9 +746,9 @@ static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr
/* don't pass the management pipe */
slirp_select_fill(pThis->pNATState, &nFDs, &polls[1]);
- polls[0].fd = pThis->PipeRead;
+ polls[0].fd = RTPipeToNative(pThis->hPipeRead);
/* POLLRDBAND usually doesn't used on Linux but seems used on Solaris */
- polls[0].events = POLLRDNORM|POLLPRI|POLLRDBAND;
+ polls[0].events = POLLRDNORM | POLLPRI | POLLRDBAND;
polls[0].revents = 0;
int cChangedFDs = poll(polls, nFDs + 1, slirp_get_timeout_ms(pThis->pNATState));
@@ -771,23 +772,21 @@ static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr
slirp_select_poll(pThis->pNATState, &polls[1], nFDs);
if (polls[0].revents & (POLLRDNORM|POLLPRI|POLLRDBAND))
{
- /* drain the pipe */
- char ch[1];
- size_t cbRead;
- int counter = 0;
- /*
- * drvNATSend decoupled so we don't know how many times
+ /* drain the pipe
+ *
+ * Note! drvNATSend decoupled so we don't know how many times
* device's thread sends before we've entered multiplex,
* so to avoid false alarm drain pipe here to the very end
*
* @todo: Probably we should counter drvNATSend to count how
* deep pipe has been filed before drain.
*
- * XXX:Make it reading exactly we need to drain the pipe.
*/
- /** @todo use RTPipeCreate + RTPipeRead(,biggerbuffer) here, it's
- * non-blocking. */
- RTFileRead(pThis->PipeRead, &ch, 1, &cbRead);
+ /** @todo XXX: Make it reading exactly we need to drain the
+ * pipe.*/
+ char ch;
+ size_t cbRead;
+ RTPipeRead(pThis->hPipeRead, &ch, 1, &cbRead);
}
}
/* process _all_ outstanding requests but don't wait */
@@ -909,6 +908,16 @@ void slirp_urg_output(void *pvUser, struct mbuf *m, const uint8_t *pu8Buf, int c
}
/**
+ * Function called by slirp to wake up device after VERR_TRY_AGAIN
+ */
+void slirp_output_pending(void *pvUser)
+{
+ PDRVNAT pThis = (PDRVNAT)pvUser;
+ Assert(pThis);
+ pThis->pIAboveNet->pfnXmitPending(pThis->pIAboveNet);
+}
+
+/**
* Function called by slirp to feed incoming data to the NIC.
*/
void slirp_output(void *pvUser, struct mbuf *m, const uint8_t *pu8Buf, int cb)
@@ -1336,15 +1345,8 @@ static DECLCALLBACK(int) drvNATConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
/*
* Create the control pipe.
*/
- int fds[2];
- if (pipe(&fds[0]) != 0) /** @todo RTPipeCreate() or something... */
- {
- rc = RTErrConvertFromErrno(errno);
- AssertRC(rc);
- return rc;
- }
- pThis->PipeRead = fds[0];
- pThis->PipeWrite = fds[1];
+ rc = RTPipeCreate(&pThis->hPipeRead, &pThis->hPipeWrite, 0 /*fFlags*/);
+ AssertRCReturn(rc, rc);
#else
pThis->hWakeupEvent = CreateEvent(NULL, FALSE, FALSE, NULL); /* auto-reset event */
slirp_register_external_event(pThis->pNATState, pThis->hWakeupEvent,
@@ -1353,12 +1355,12 @@ static DECLCALLBACK(int) drvNATConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pSlirpThread, pThis, drvNATAsyncIoThread,
drvNATAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "NAT");
- AssertRC(rc);
+ AssertRCReturn(rc, rc);
#ifdef VBOX_WITH_SLIRP_MT
rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pGuestThread, pThis, drvNATAsyncIoGuest,
drvNATAsyncIoGuestWakeup, 128 * _1K, RTTHREADTYPE_IO, "NATGUEST");
- AssertRC(rc);
+ AssertRCReturn(rc, rc);
#endif
pThis->enmLinkState = pThis->enmLinkStateWant = PDMNETWORKLINKSTATE_UP;
diff --git a/src/VBox/Devices/Network/DrvNetSniffer.cpp b/src/VBox/Devices/Network/DrvNetSniffer.cpp
index 7aac425d1..fa371a7e2 100644
--- a/src/VBox/Devices/Network/DrvNetSniffer.cpp
+++ b/src/VBox/Devices/Network/DrvNetSniffer.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvNetSniffer.cpp $ */
+/* $Id: DrvNetSniffer.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* DrvNetSniffer - Network sniffer filter driver.
*/
@@ -65,7 +65,7 @@ typedef struct DRVNETSNIFFER
/** The filename. */
char szFilename[RTPATH_MAX];
/** The filehandle. */
- RTFILE File;
+ RTFILE hFile;
/** The lock serializing the file access. */
RTCRITSECT Lock;
/** The NanoTS delta we pass to the pcap writers. */
@@ -133,12 +133,12 @@ static DECLCALLBACK(int) drvNetSnifferUp_SendBuf(PPDMINETWORKUP pInterface, PPDM
/* output to sniffer */
RTCritSectEnter(&pThis->Lock);
if (!pSgBuf->pvUser)
- PcapFileFrame(pThis->File, pThis->StartNanoTS,
+ PcapFileFrame(pThis->hFile, pThis->StartNanoTS,
pSgBuf->aSegs[0].pvSeg,
pSgBuf->cbUsed,
RT_MIN(pSgBuf->cbUsed, pSgBuf->aSegs[0].cbSeg));
else
- PcapFileGsoFrame(pThis->File, pThis->StartNanoTS, (PCPDMNETWORKGSO)pSgBuf->pvUser,
+ PcapFileGsoFrame(pThis->hFile, pThis->StartNanoTS, (PCPDMNETWORKGSO)pSgBuf->pvUser,
pSgBuf->aSegs[0].pvSeg,
pSgBuf->cbUsed,
RT_MIN(pSgBuf->cbUsed, pSgBuf->aSegs[0].cbSeg));
@@ -205,7 +205,7 @@ static DECLCALLBACK(int) drvNetSnifferDown_Receive(PPDMINETWORKDOWN pInterface,
/* output to sniffer */
RTCritSectEnter(&pThis->Lock);
- PcapFileFrame(pThis->File, pThis->StartNanoTS, pvBuf, cb, cb);
+ PcapFileFrame(pThis->hFile, pThis->StartNanoTS, pvBuf, cb, cb);
RTCritSectLeave(&pThis->Lock);
/* pass up */
@@ -216,7 +216,7 @@ static DECLCALLBACK(int) drvNetSnifferDown_Receive(PPDMINETWORKDOWN pInterface,
Hdr.ts_sec = (uint32_t)(u64TS / 1000000000);
Hdr.ts_usec = (uint32_t)((u64TS / 1000) % 1000000);
Hdr.incl_len = 0;
- RTFileWrite(pThis->File, &Hdr, sizeof(Hdr), NULL);
+ RTFileWrite(pThis->hFile, &Hdr, sizeof(Hdr), NULL);
RTCritSectLeave(&pThis->Lock);
#endif
return rc;
@@ -357,11 +357,8 @@ static DECLCALLBACK(void) drvNetSnifferDestruct(PPDMDRVINS pDrvIns)
if (RTCritSectIsInitialized(&pThis->XmitLock))
RTCritSectDelete(&pThis->XmitLock);
- if (pThis->File != NIL_RTFILE)
- {
- RTFileClose(pThis->File);
- pThis->File = NIL_RTFILE;
- }
+ RTFileClose(pThis->hFile);
+ pThis->hFile = NIL_RTFILE;
}
@@ -379,7 +376,7 @@ static DECLCALLBACK(int) drvNetSnifferConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pC
* Init the static parts.
*/
pThis->pDrvIns = pDrvIns;
- pThis->File = NIL_RTFILE;
+ pThis->hFile = NIL_RTFILE;
/* The pcap file *must* start at time offset 0,0. */
pThis->StartNanoTS = RTTimeNanoTS() - RTTimeProgramNanoTS();
/* IBase */
@@ -482,7 +479,7 @@ static DECLCALLBACK(int) drvNetSnifferConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pC
/*
* Open output file / pipe.
*/
- rc = RTFileOpen(&pThis->File, pThis->szFilename,
+ rc = RTFileOpen(&pThis->hFile, pThis->szFilename,
RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_WRITE);
if (RT_FAILURE(rc))
return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
@@ -490,9 +487,10 @@ static DECLCALLBACK(int) drvNetSnifferConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pC
/*
* Write pcap header.
- * Some time is done since capturing pThis->StartNanoTS so capture the current time again.
+ * Some time has gone by since capturing pThis->StartNanoTS so get the
+ * current time again.
*/
- PcapFileHdr(pThis->File, RTTimeNanoTS());
+ PcapFileHdr(pThis->hFile, RTTimeNanoTS());
return VINF_SUCCESS;
}
diff --git a/src/VBox/Devices/Network/DrvTAP.cpp b/src/VBox/Devices/Network/DrvTAP.cpp
index 70077123c..6bfbe76cc 100644
--- a/src/VBox/Devices/Network/DrvTAP.cpp
+++ b/src/VBox/Devices/Network/DrvTAP.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvTAP.cpp $ */
+/* $Id: DrvTAP.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* DrvTAP - Universal TAP network transport driver.
*/
@@ -30,6 +30,7 @@
#include <iprt/file.h>
#include <iprt/mem.h>
#include <iprt/path.h>
+#include <iprt/pipe.h>
#include <iprt/semaphore.h>
#include <iprt/string.h>
#include <iprt/thread.h>
@@ -92,7 +93,7 @@ typedef struct DRVTAP
/** Pointer to the driver instance. */
PPDMDRVINS pDrvIns;
/** TAP device file handle. */
- RTFILE FileDevice;
+ RTFILE hFileDevice;
/** The configured TAP device name. */
char *pszDeviceName;
#ifdef RT_OS_SOLARIS
@@ -103,7 +104,7 @@ typedef struct DRVTAP
dlpi_handle_t pDeviceHandle;
# else
/** IP device file handle (/dev/udp). */
- RTFILE IPFileDevice;
+ int iIPFileDes;
# endif
/** Whether device name is obtained from setup application. */
bool fStatic;
@@ -113,9 +114,9 @@ typedef struct DRVTAP
/** TAP terminate application. */
char *pszTerminateApplication;
/** The write end of the control pipe. */
- RTFILE PipeWrite;
+ RTPIPE hPipeWrite;
/** The read end of the control pipe. */
- RTFILE PipeRead;
+ RTPIPE hPipeRead;
/** Reader thread. */
PPDMTHREAD pThread;
@@ -274,7 +275,7 @@ static DECLCALLBACK(int) drvTAPNetworkUp_SendBuf(PPDMINETWORKUP pInterface, PPDM
"%.*Rhxd\n",
pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, pSgBuf->cbUsed, pSgBuf->aSegs[0].pvSeg));
- rc = RTFileWrite(pThis->FileDevice, pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, NULL);
+ rc = RTFileWrite(pThis->hFileDevice, pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, NULL);
}
else
{
@@ -288,7 +289,7 @@ static DECLCALLBACK(int) drvTAPNetworkUp_SendBuf(PPDMINETWORKUP pInterface, PPDM
uint32_t cbSegFrame;
void *pvSegFrame = PDMNetGsoCarveSegmentQD(pGso, (uint8_t *)pbFrame, pSgBuf->cbUsed, abHdrScratch,
iSeg, cSegs, &cbSegFrame);
- rc = RTFileWrite(pThis->FileDevice, pvSegFrame, cbSegFrame, NULL);
+ rc = RTFileWrite(pThis->hFileDevice, pvSegFrame, cbSegFrame, NULL);
if (RT_FAILURE(rc))
break;
}
@@ -365,10 +366,10 @@ static DECLCALLBACK(int) drvTAPAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr
* Wait for something to become available.
*/
struct pollfd aFDs[2];
- aFDs[0].fd = pThis->FileDevice;
+ aFDs[0].fd = RTFileToNative(pThis->hFileDevice);
aFDs[0].events = POLLIN | POLLPRI;
aFDs[0].revents = 0;
- aFDs[1].fd = pThis->PipeRead;
+ aFDs[1].fd = RTPipeToNative(pThis->hPipeRead);
aFDs[1].events = POLLIN | POLLPRI | POLLERR | POLLHUP;
aFDs[1].revents = 0;
STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a);
@@ -397,7 +398,7 @@ static DECLCALLBACK(int) drvTAPAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr
/** @note At least on Linux we will never receive more than one network packet
* after poll() returned successfully. I don't know why but a second
* RTFileRead() operation will return with VERR_TRY_AGAIN in any case. */
- rc = RTFileRead(pThis->FileDevice, achBuf, sizeof(achBuf), &cbRead);
+ rc = RTFileRead(pThis->hFileDevice, achBuf, sizeof(achBuf), &cbRead);
#endif
if (RT_SUCCESS(rc))
{
@@ -458,7 +459,7 @@ static DECLCALLBACK(int) drvTAPAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr
/* drain the pipe */
char ch;
size_t cbRead;
- RTFileRead(pThis->PipeRead, &ch, 1, &cbRead);
+ RTPipeRead(pThis->hPipeRead, &ch, 1, &cbRead);
}
else
{
@@ -494,7 +495,8 @@ static DECLCALLBACK(int) drvTapAsyncIoWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThr
{
PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
- int rc = RTFileWrite(pThis->PipeWrite, "", 1, NULL);
+ size_t cbIgnored;
+ int rc = RTPipeWrite(pThis->hPipeWrite, "", 1, &cbIgnored);
AssertRC(rc);
return VINF_SUCCESS;
@@ -656,15 +658,19 @@ static int SolarisOpenVNIC(PDRVTAP pThis)
rc = g_pfnLibDlpiPromiscon(pThis->pDeviceHandle, DL_PROMISC_PHYS);
if (rc == DLPI_SUCCESS)
{
- pThis->FileDevice = g_pfnLibDlpiFd(pThis->pDeviceHandle);
+ int fd = g_pfnLibDlpiFd(pThis->pDeviceHandle);
if (pThis->FileDevice >= 0)
{
- Log(("SolarisOpenVNIC: %s -> %d\n", pThis->pszDeviceName, pThis->FileDevice));
- return VINF_SUCCESS;
+ rc = RTFileFromNative(&pThis->hFileDevice, fd);
+ if (RT_SUCCESS(rc))
+ {
+ Log(("SolarisOpenVNIC: %s -> %RTfile\n", pThis->pszDeviceName, pThis->hFileDevice));
+ return VINF_SUCCESS;
+ }
}
-
- rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
- N_("Failed to obtain file descriptor for VNIC"));
+ else
+ rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
+ N_("Failed to obtain file descriptor for VNIC"));
}
else
rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
@@ -878,8 +884,14 @@ static DECLCALLBACK(int) SolarisTAPAttach(PDRVTAP pThis)
N_("Failed to set Mux ID. Check TAP interface name. errno=%d"), errno);
}
- pThis->FileDevice = (RTFILE)TapFileDes;
- pThis->IPFileDevice = (RTFILE)IPFileDes;
+ int rc = RTFileFromNative(&pThis->hFileDevice, TapFileDes);
+ AssertLogRelRC(rc);
+ if (RT_FAILURE(rc)))
+ {
+ close(IPFileDes);
+ close(TapFileDes);
+ }
+ pThis->iIPFileDes = IPFileDes;
return VINF_SUCCESS;
}
@@ -921,34 +933,26 @@ static DECLCALLBACK(void) drvTAPDestruct(PPDMDRVINS pDrvIns)
/*
* Terminate the control pipe.
*/
- if (pThis->PipeWrite != NIL_RTFILE)
- {
- int rc = RTFileClose(pThis->PipeWrite);
- AssertRC(rc);
- pThis->PipeWrite = NIL_RTFILE;
- }
- if (pThis->PipeRead != NIL_RTFILE)
- {
- int rc = RTFileClose(pThis->PipeRead);
- AssertRC(rc);
- pThis->PipeRead = NIL_RTFILE;
- }
+ int rc;
+ rc = RTPipeClose(pThis->hPipeWrite); AssertRC(rc);
+ pThis->hPipeWrite = NIL_RTPIPE;
+ rc = RTPipeClose(pThis->hPipeRead); AssertRC(rc);
+ pThis->hPipeRead = NIL_RTPIPE;
#ifdef RT_OS_SOLARIS
/** @todo r=bird: This *does* need checking against ConsoleImpl2.cpp if used on non-solaris systems. */
- if (pThis->FileDevice != NIL_RTFILE)
+ if (pThis->hFileDevice != NIL_RTFILE)
{
- int rc = RTFileClose(pThis->FileDevice);
+ int rc = RTFileClose(pThis->hFileDevice);
AssertRC(rc);
- pThis->FileDevice = NIL_RTFILE;
+ pThis->hFileDevice = NIL_RTFILE;
}
# ifndef VBOX_WITH_CROSSBOW
- if (pThis->IPFileDevice != NIL_RTFILE)
+ if (pThis->iIPFileDes != -1)
{
- int rc = RTFileClose(pThis->IPFileDevice);
- AssertRC(rc);
- pThis->IPFileDevice = NIL_RTFILE;
+ close(pThis->iIPFileDes);
+ pThis->iIPFileDes = -1;
}
# endif
@@ -1006,13 +1010,13 @@ static DECLCALLBACK(int) drvTAPConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
* Init the static parts.
*/
pThis->pDrvIns = pDrvIns;
- pThis->FileDevice = NIL_RTFILE;
+ pThis->hFileDevice = NIL_RTFILE;
pThis->pszDeviceName = NULL;
#ifdef RT_OS_SOLARIS
# ifdef VBOX_WITH_CROSSBOW
pThis->pDeviceHandle = NULL;
# else
- pThis->IPFileDevice = NIL_RTFILE;
+ pThis->iIPFileDes = -1;
# endif
pThis->fStatic = true;
#endif
@@ -1125,15 +1129,15 @@ static DECLCALLBACK(int) drvTAPConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
#else /* !RT_OS_SOLARIS */
- int32_t iFile;
- rc = CFGMR3QueryS32(pCfg, "FileHandle", &iFile);
+ uint64_t u64File;
+ rc = CFGMR3QueryU64(pCfg, "FileHandle", &u64File);
if (RT_FAILURE(rc))
return PDMDRV_SET_ERROR(pDrvIns, rc,
N_("Configuration error: Query for \"FileHandle\" 32-bit signed integer failed"));
- pThis->FileDevice = (RTFILE)iFile;
- if (!RTFileIsValid(pThis->FileDevice))
+ pThis->hFileDevice = (RTFILE)(uintptr_t)u64File;
+ if (!RTFileIsValid(pThis->hFileDevice))
return PDMDrvHlpVMSetError(pDrvIns, VERR_INVALID_HANDLE, RT_SRC_POS,
- N_("The TAP file handle %RTfile is not valid"), pThis->FileDevice);
+ N_("The TAP file handle %RTfile is not valid"), pThis->hFileDevice);
#endif /* !RT_OS_SOLARIS */
/*
@@ -1148,29 +1152,18 @@ static DECLCALLBACK(int) drvTAPConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
* We should actually query if it's a TAP device, but I haven't
* found any way to do that.
*/
- if (fcntl(pThis->FileDevice, F_SETFL, O_NONBLOCK) == -1)
+ if (fcntl(RTFileToNative(pThis->hFileDevice), F_SETFL, O_NONBLOCK) == -1)
return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
N_("Configuration error: Failed to configure /dev/net/tun. errno=%d"), errno);
/** @todo determine device name. This can be done by reading the link /proc/<pid>/fd/<fd> */
- Log(("drvTAPContruct: %d (from fd)\n", pThis->FileDevice));
+ Log(("drvTAPContruct: %d (from fd)\n", pThis->hFileDevice));
rc = VINF_SUCCESS;
/*
* Create the control pipe.
*/
- int fds[2];
-#ifdef RT_OS_L4
- /* XXX We need to tell the library which interface we are using */
- fds[0] = vboxrtLinuxFd2VBoxFd(VBOXRT_FT_TAP, 0);
-#endif
- if (pipe(&fds[0]) != 0) /** @todo RTPipeCreate() or something... */
- {
- rc = RTErrConvertFromErrno(errno);
- AssertRC(rc);
- return rc;
- }
- pThis->PipeRead = fds[0];
- pThis->PipeWrite = fds[1];
+ rc = RTPipeCreate(&pThis->hPipeRead, &pThis->hPipeWrite, 0 /*fFlags*/);
+ AssertRCReturn(rc, rc);
/*
* Create the async I/O thread.
diff --git a/src/VBox/Devices/Network/DrvUDPTunnel.cpp b/src/VBox/Devices/Network/DrvUDPTunnel.cpp
new file mode 100644
index 000000000..3dce6ae6d
--- /dev/null
+++ b/src/VBox/Devices/Network/DrvUDPTunnel.cpp
@@ -0,0 +1,650 @@
+/* $Id: DrvUDPTunnel.cpp 37259 2011-05-30 13:31:21Z vboxsync $ */
+/** @file
+ * DrvUDPTunnel - UDP tunnel network transport driver
+ *
+ * Based on code contributed by Christophe Devriese
+ */
+
+/*
+ * Copyright (C) 2009-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 *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_DRV_UDPTUNNEL
+#include <VBox/log.h>
+#include <VBox/vmm/pdmdrv.h>
+#include <VBox/vmm/pdmnetifs.h>
+#include <VBox/vmm/pdmnetinline.h>
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/ctype.h>
+#include <iprt/udp.h>
+#include <iprt/mem.h>
+#include <iprt/path.h>
+#include <iprt/uuid.h>
+#include <iprt/string.h>
+#include <iprt/critsect.h>
+
+#include "VBoxDD.h"
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * UDP tunnel driver instance data.
+ *
+ * @implements PDMINETWORKUP
+ */
+typedef struct DRVUDPTUNNEL
+{
+ /** The network interface. */
+ PDMINETWORKUP INetworkUp;
+ /** The network interface. */
+ PPDMINETWORKDOWN pIAboveNet;
+ /** Pointer to the driver instance. */
+ PPDMDRVINS pDrvIns;
+ /** UDP tunnel source port. */
+ uint16_t uSrcPort;
+ /** UDP tunnel destination port. */
+ uint16_t uDestPort;
+ /** UDP tunnel destination IP address. */
+ char *pszDestIP;
+ /** UDP tunnel instance string. */
+ char *pszInstance;
+
+ /** UDP destination address. */
+ RTNETADDR DestAddress;
+ /** Transmit lock used by drvUDPTunnelUp_BeginXmit. */
+ RTCRITSECT XmitLock;
+ /** Server data structure for UDP communication. */
+ PRTUDPSERVER pServer;
+
+ /** Flag whether the link is down. */
+ bool volatile fLinkDown;
+
+#ifdef VBOX_WITH_STATISTICS
+ /** Number of sent packets. */
+ STAMCOUNTER StatPktSent;
+ /** Number of sent bytes. */
+ STAMCOUNTER StatPktSentBytes;
+ /** Number of received packets. */
+ STAMCOUNTER StatPktRecv;
+ /** Number of received bytes. */
+ STAMCOUNTER StatPktRecvBytes;
+ /** Profiling packet transmit runs. */
+ STAMPROFILE StatTransmit;
+ /** Profiling packet receive runs. */
+ STAMPROFILEADV StatReceive;
+#endif /* VBOX_WITH_STATISTICS */
+
+#ifdef LOG_ENABLED
+ /** The nano ts of the last transfer. */
+ uint64_t u64LastTransferTS;
+ /** The nano ts of the last receive. */
+ uint64_t u64LastReceiveTS;
+#endif
+} DRVUDPTUNNEL, *PDRVUDPTUNNEL;
+
+
+/** Converts a pointer to UDPTUNNEL::INetworkUp to a PRDVUDPTUNNEL. */
+#define PDMINETWORKUP_2_DRVUDPTUNNEL(pInterface) ( (PDRVUDPTUNNEL)((uintptr_t)pInterface - RT_OFFSETOF(DRVUDPTUNNEL, INetworkUp)) )
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+
+/**
+ * @interface_method_impl{PDMINETWORKUP,pfnBeginXmit}
+ */
+static DECLCALLBACK(int) drvUDPTunnelUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread)
+{
+ PDRVUDPTUNNEL pThis = PDMINETWORKUP_2_DRVUDPTUNNEL(pInterface);
+ int rc = RTCritSectTryEnter(&pThis->XmitLock);
+ if (RT_FAILURE(rc))
+ {
+ /** @todo XMIT thread */
+ rc = VERR_TRY_AGAIN;
+ }
+ return rc;
+}
+
+/**
+ * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf}
+ */
+static DECLCALLBACK(int) drvUDPTunnelUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,
+ PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf)
+{
+ PDRVUDPTUNNEL pThis = PDMINETWORKUP_2_DRVUDPTUNNEL(pInterface);
+ Assert(RTCritSectIsOwner(&pThis->XmitLock));
+
+ /*
+ * Allocate a scatter / gather buffer descriptor that is immediately
+ * followed by the buffer space of its single segment. The GSO context
+ * comes after that again.
+ */
+ PPDMSCATTERGATHER pSgBuf = (PPDMSCATTERGATHER)RTMemAlloc( RT_ALIGN_Z(sizeof(*pSgBuf), 16)
+ + RT_ALIGN_Z(cbMin, 16)
+ + (pGso ? RT_ALIGN_Z(sizeof(*pGso), 16) : 0));
+ if (!pSgBuf)
+ return VERR_NO_MEMORY;
+
+ /*
+ * Initialize the S/G buffer and return.
+ */
+ pSgBuf->fFlags = PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1;
+ pSgBuf->cbUsed = 0;
+ pSgBuf->cbAvailable = RT_ALIGN_Z(cbMin, 16);
+ pSgBuf->pvAllocator = NULL;
+ if (!pGso)
+ pSgBuf->pvUser = NULL;
+ else
+ {
+ pSgBuf->pvUser = (uint8_t *)(pSgBuf + 1) + pSgBuf->cbAvailable;
+ *(PPDMNETWORKGSO)pSgBuf->pvUser = *pGso;
+ }
+ pSgBuf->cSegs = 1;
+ pSgBuf->aSegs[0].cbSeg = pSgBuf->cbAvailable;
+ pSgBuf->aSegs[0].pvSeg = pSgBuf + 1;
+
+#if 0 /* poison */
+ memset(pSgBuf->aSegs[0].pvSeg, 'F', pSgBuf->aSegs[0].cbSeg);
+#endif
+ *ppSgBuf = pSgBuf;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{PDMINETWORKUP,pfnFreeBuf}
+ */
+static DECLCALLBACK(int) drvUDPTunnelUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf)
+{
+ PDRVUDPTUNNEL pThis = PDMINETWORKUP_2_DRVUDPTUNNEL(pInterface);
+ Assert(RTCritSectIsOwner(&pThis->XmitLock));
+ if (pSgBuf)
+ {
+ Assert((pSgBuf->fFlags & PDMSCATTERGATHER_FLAGS_MAGIC_MASK) == PDMSCATTERGATHER_FLAGS_MAGIC);
+ pSgBuf->fFlags = 0;
+ RTMemFree(pSgBuf);
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{PDMINETWORKUP,pfnSendBuf}
+ */
+static DECLCALLBACK(int) drvUDPTunnelUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread)
+{
+ PDRVUDPTUNNEL pThis = PDMINETWORKUP_2_DRVUDPTUNNEL(pInterface);
+ STAM_COUNTER_INC(&pThis->StatPktSent);
+ STAM_COUNTER_ADD(&pThis->StatPktSentBytes, pSgBuf->cbUsed);
+ STAM_PROFILE_START(&pThis->StatTransmit, a);
+
+ AssertPtr(pSgBuf);
+ Assert((pSgBuf->fFlags & PDMSCATTERGATHER_FLAGS_MAGIC_MASK) == PDMSCATTERGATHER_FLAGS_MAGIC);
+ Assert(RTCritSectIsOwner(&pThis->XmitLock));
+
+ /* Set an FTM checkpoint as this operation changes the state permanently. */
+ PDMDrvHlpFTSetCheckpoint(pThis->pDrvIns, FTMCHECKPOINTTYPE_NETWORK);
+
+ int rc;
+ if (!pSgBuf->pvUser)
+ {
+#ifdef LOG_ENABLED
+ uint64_t u64Now = RTTimeProgramNanoTS();
+ LogFunc(("%-4d bytes at %llu ns deltas: r=%llu t=%llu\n",
+ pSgBuf->cbUsed, u64Now, u64Now - pThis->u64LastReceiveTS, u64Now - pThis->u64LastTransferTS));
+ pThis->u64LastTransferTS = u64Now;
+#endif
+ Log2(("pSgBuf->aSegs[0].pvSeg=%p pSgBuf->cbUsed=%#x\n%.*Rhxd\n",
+ pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, pSgBuf->cbUsed, pSgBuf->aSegs[0].pvSeg));
+
+ rc = RTUdpWrite(pThis->pServer, pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, &pThis->DestAddress);
+ }
+ else
+ {
+ uint8_t abHdrScratch[256];
+ uint8_t const *pbFrame = (uint8_t const *)pSgBuf->aSegs[0].pvSeg;
+ PCPDMNETWORKGSO pGso = (PCPDMNETWORKGSO)pSgBuf->pvUser;
+ uint32_t const cSegs = PDMNetGsoCalcSegmentCount(pGso, pSgBuf->cbUsed); Assert(cSegs > 1);
+ rc = VINF_SUCCESS;
+ for (size_t iSeg = 0; iSeg < cSegs; iSeg++)
+ {
+ uint32_t cbSegFrame;
+ void *pvSegFrame = PDMNetGsoCarveSegmentQD(pGso, (uint8_t *)pbFrame, pSgBuf->cbUsed, abHdrScratch,
+ iSeg, cSegs, &cbSegFrame);
+ rc = RTUdpWrite(pThis->pServer, pvSegFrame, cbSegFrame, &pThis->DestAddress);
+ }
+ }
+
+ pSgBuf->fFlags = 0;
+ RTMemFree(pSgBuf);
+
+ STAM_PROFILE_STOP(&pThis->StatTransmit, a);
+ AssertRC(rc);
+ if (RT_FAILURE(rc))
+ {
+ if (rc == VERR_NO_MEMORY)
+ rc = VERR_NET_NO_BUFFER_SPACE;
+ else
+ rc = VERR_NET_DOWN;
+ }
+ return rc;
+}
+
+
+/**
+ * @interface_method_impl{PDMINETWORKUP,pfnEndXmit}
+ */
+static DECLCALLBACK(void) drvUDPTunnelUp_EndXmit(PPDMINETWORKUP pInterface)
+{
+ PDRVUDPTUNNEL pThis = PDMINETWORKUP_2_DRVUDPTUNNEL(pInterface);
+ RTCritSectLeave(&pThis->XmitLock);
+}
+
+
+/**
+ * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode}
+ */
+static DECLCALLBACK(void) drvUDPTunnelUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)
+{
+ LogFlowFunc(("fPromiscuous=%d\n", fPromiscuous));
+ /* nothing to do */
+}
+
+
+/**
+ * Notification on link status changes.
+ *
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param enmLinkState The new link state.
+ * @thread EMT
+ */
+static DECLCALLBACK(void) drvUDPTunnelUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)
+{
+ LogFlowFunc(("enmLinkState=%d\n", enmLinkState));
+ PDRVUDPTUNNEL pThis = PDMINETWORKUP_2_DRVUDPTUNNEL(pInterface);
+
+ bool fLinkDown;
+ switch (enmLinkState)
+ {
+ case PDMNETWORKLINKSTATE_DOWN:
+ case PDMNETWORKLINKSTATE_DOWN_RESUME:
+ fLinkDown = true;
+ break;
+ default:
+ AssertMsgFailed(("enmLinkState=%d\n", enmLinkState));
+ case PDMNETWORKLINKSTATE_UP:
+ fLinkDown = false;
+ break;
+ }
+ ASMAtomicXchgSize(&pThis->fLinkDown, fLinkDown);
+}
+
+
+static DECLCALLBACK(int) drvUDPTunnelReceive(RTSOCKET Sock, void *pvUser)
+{
+ PDRVUDPTUNNEL pThis = PDMINS_2_DATA((PPDMDRVINS)pvUser, PDRVUDPTUNNEL);
+ LogFlowFunc(("pThis=%p\n", pThis));
+
+ STAM_PROFILE_ADV_START(&pThis->StatReceive, a);
+
+ /*
+ * Read the frame.
+ */
+ char achBuf[16384];
+ size_t cbRead = 0;
+ int rc = RTUdpRead(Sock, achBuf, sizeof(achBuf), &cbRead, NULL);
+ if (RT_SUCCESS(rc))
+ {
+ if (!pThis->fLinkDown)
+ {
+ /*
+ * Wait for the device to have space for this frame.
+ * Most guests use frame-sized receive buffers, hence non-zero cbMax
+ * automatically means there is enough room for entire frame. Some
+ * guests (eg. Solaris) use large chains of small receive buffers
+ * (each 128 or so bytes large). We will still start receiving as soon
+ * as cbMax is non-zero because:
+ * - it would be quite expensive for pfnCanReceive to accurately
+ * determine free receive buffer space
+ * - if we were waiting for enough free buffers, there is a risk
+ * of deadlocking because the guest could be waiting for a receive
+ * overflow error to allocate more receive buffers
+ */
+ STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a);
+ rc = pThis->pIAboveNet->pfnWaitReceiveAvail(pThis->pIAboveNet, RT_INDEFINITE_WAIT);
+ STAM_PROFILE_ADV_START(&pThis->StatReceive, a);
+
+ /*
+ * A return code != VINF_SUCCESS means that we were woken up during a VM
+ * state transition. Drop the packet and wait for the next one.
+ */
+ if (RT_FAILURE(rc))
+ {
+ STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a);
+ return VINF_SUCCESS;
+ }
+
+ /*
+ * Pass the data up.
+ */
+#ifdef LOG_ENABLED
+ uint64_t u64Now = RTTimeProgramNanoTS();
+ LogFunc(("%-4d bytes at %llu ns deltas: r=%llu t=%llu\n",
+ cbRead, u64Now, u64Now - pThis->u64LastReceiveTS, u64Now - pThis->u64LastTransferTS));
+ pThis->u64LastReceiveTS = u64Now;
+#endif
+ Log2(("cbRead=%#x\n" "%.*Rhxd\n", cbRead, cbRead, achBuf));
+ STAM_COUNTER_INC(&pThis->StatPktRecv);
+ STAM_COUNTER_ADD(&pThis->StatPktRecvBytes, cbRead);
+ rc = pThis->pIAboveNet->pfnReceive(pThis->pIAboveNet, achBuf, cbRead);
+ AssertRC(rc);
+ }
+ }
+ else
+ {
+ STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a);
+ LogFunc(("RTUdpRead -> %Rrc\n", rc));
+ if (rc == VERR_INVALID_HANDLE)
+ return VERR_UDP_SERVER_STOP;
+ }
+
+ STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a);
+ return VINF_SUCCESS;
+}
+
+
+/* -=-=-=-=- PDMIBASE -=-=-=-=- */
+
+/**
+ * @interface_method_impl{PDMIBASE,pfnQueryInterface}
+ */
+static DECLCALLBACK(void *) drvUDPTunnelQueryInterface(PPDMIBASE pInterface, const char *pszIID)
+{
+ PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
+ PDRVUDPTUNNEL pThis = PDMINS_2_DATA(pDrvIns, PDRVUDPTUNNEL);
+
+ PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
+ PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKUP, &pThis->INetworkUp);
+ return NULL;
+}
+
+
+/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
+
+/**
+ * Destruct a driver instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that any non-VM
+ * resources can be freed correctly.
+ *
+ * @param pDrvIns The driver instance data.
+ */
+static DECLCALLBACK(void) drvUDPTunnelDestruct(PPDMDRVINS pDrvIns)
+{
+ LogFlowFunc(("\n"));
+ PDRVUDPTUNNEL pThis = PDMINS_2_DATA(pDrvIns, PDRVUDPTUNNEL);
+ PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
+ ASMAtomicXchgSize(&pThis->fLinkDown, true);
+
+ if (pThis->pszInstance)
+ RTStrFree(pThis->pszInstance);
+
+ if (pThis->pszDestIP)
+ MMR3HeapFree(pThis->pszDestIP);
+
+ if (pThis->pServer)
+ {
+ RTUdpServerDestroy(pThis->pServer);
+ pThis->pServer = NULL;
+ }
+
+ /*
+ * Kill the xmit lock.
+ */
+ if (RTCritSectIsInitialized(&pThis->XmitLock))
+ RTCritSectDelete(&pThis->XmitLock);
+
+#ifdef VBOX_WITH_STATISTICS
+ /*
+ * Deregister statistics.
+ */
+ PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatPktSent);
+ PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatPktSentBytes);
+ PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatPktRecv);
+ PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatPktRecvBytes);
+ PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatTransmit);
+ PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatReceive);
+#endif /* VBOX_WITH_STATISTICS */
+}
+
+
+/**
+ * Construct a UDP tunnel network transport driver instance.
+ *
+ * @copydoc FNPDMDRVCONSTRUCT
+ */
+static DECLCALLBACK(int) drvUDPTunnelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
+{
+ PDRVUDPTUNNEL pThis = PDMINS_2_DATA(pDrvIns, PDRVUDPTUNNEL);
+ PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
+
+ /*
+ * Init the static parts.
+ */
+ pThis->pDrvIns = pDrvIns;
+ pThis->pszDestIP = NULL;
+ pThis->pszInstance = NULL;
+
+ /* IBase */
+ pDrvIns->IBase.pfnQueryInterface = drvUDPTunnelQueryInterface;
+ /* INetwork */
+ pThis->INetworkUp.pfnBeginXmit = drvUDPTunnelUp_BeginXmit;
+ pThis->INetworkUp.pfnAllocBuf = drvUDPTunnelUp_AllocBuf;
+ pThis->INetworkUp.pfnFreeBuf = drvUDPTunnelUp_FreeBuf;
+ pThis->INetworkUp.pfnSendBuf = drvUDPTunnelUp_SendBuf;
+ pThis->INetworkUp.pfnEndXmit = drvUDPTunnelUp_EndXmit;
+ pThis->INetworkUp.pfnSetPromiscuousMode = drvUDPTunnelUp_SetPromiscuousMode;
+ pThis->INetworkUp.pfnNotifyLinkChanged = drvUDPTunnelUp_NotifyLinkChanged;
+
+#ifdef VBOX_WITH_STATISTICS
+ /*
+ * Statistics.
+ */
+ PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktSent, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of sent packets.", "/Drivers/UDPTunnel%d/Packets/Sent", pDrvIns->iInstance);
+ PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktSentBytes, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Number of sent bytes.", "/Drivers/UDPTunnel%d/Bytes/Sent", pDrvIns->iInstance);
+ PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktRecv, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of received packets.", "/Drivers/UDPTunnel%d/Packets/Received", pDrvIns->iInstance);
+ PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktRecvBytes, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Number of received bytes.", "/Drivers/UDPTunnel%d/Bytes/Received", pDrvIns->iInstance);
+ PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatTransmit, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling packet transmit runs.", "/Drivers/UDPTunnel%d/Transmit", pDrvIns->iInstance);
+ PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatReceive, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling packet receive runs.", "/Drivers/UDPTunnel%d/Receive", pDrvIns->iInstance);
+#endif /* VBOX_WITH_STATISTICS */
+
+ /*
+ * Validate the config.
+ */
+ if (!CFGMR3AreValuesValid(pCfg, "sport\0dest\0dport"))
+ return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES, "");
+
+ /*
+ * Check that no-one is attached to us.
+ */
+ AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
+ ("Configuration error: Not possible to attach anything to this driver!\n"),
+ VERR_PDM_DRVINS_NO_ATTACH);
+
+ /*
+ * Query the network port interface.
+ */
+ pThis->pIAboveNet = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKDOWN);
+ if (!pThis->pIAboveNet)
+ return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_ABOVE,
+ N_("Configuration error: The above device/driver didn't export the network port interface"));
+
+ /*
+ * Read the configuration.
+ */
+ int rc;
+ char szVal[16];
+ rc = CFGMR3QueryStringDef(pCfg, "sport", szVal, sizeof(szVal), "4444");
+ if (RT_FAILURE(rc))
+ rc = PDMDRV_SET_ERROR(pDrvIns, rc,
+ N_("DrvUDPTunnel: Configuration error: Querying \"sport\" as string failed"));
+ rc = RTStrToUInt16Full(szVal, 0, &pThis->uSrcPort);
+ if (RT_FAILURE(rc))
+ rc = PDMDRV_SET_ERROR(pDrvIns, rc,
+ N_("DrvUDPTunnel: Configuration error: Converting \"sport\" to integer failed"));
+ if (!pThis->uSrcPort)
+ pThis->uSrcPort = 4444;
+
+ rc = CFGMR3QueryStringDef(pCfg, "dport", szVal, sizeof(szVal), "4445");
+ if (RT_FAILURE(rc))
+ rc = PDMDRV_SET_ERROR(pDrvIns, rc,
+ N_("DrvUDPTunnel: Configuration error: Querying \"dport\" as string failed"));
+ rc = RTStrToUInt16Full(szVal, 0, &pThis->uDestPort);
+ if (RT_FAILURE(rc))
+ rc = PDMDRV_SET_ERROR(pDrvIns, rc,
+ N_("DrvUDPTunnel: Configuration error: Converting \"dport\" to integer failed"));
+ if (!pThis->uDestPort)
+ pThis->uDestPort = 4445;
+
+ rc = CFGMR3QueryStringAllocDef(pCfg, "dest", &pThis->pszDestIP, "127.0.0.1");
+ if (RT_FAILURE(rc))
+ rc = PDMDRV_SET_ERROR(pDrvIns, rc,
+ N_("DrvUDPTunnel: Configuration error: Querying \"dest\" as string failed"));
+
+ LogRel(("UDPTunnel#%d: sport=%d;dest=%s;dport=%d\n", pDrvIns->iInstance, pThis->uSrcPort, pThis->pszDestIP, pThis->uDestPort));
+
+ /*
+ * Set up destination address for UDP.
+ */
+ rc = RTSocketParseInetAddress(pThis->pszDestIP, pThis->uDestPort, &pThis->DestAddress);
+ AssertRCReturn(rc, rc);
+
+ /*
+ * Create unique thread name for the UDP receiver.
+ */
+ rc = RTStrAPrintf(&pThis->pszInstance, "UDPTunnel%d", pDrvIns->iInstance);
+ AssertRC(rc);
+
+ /*
+ * Start the UDP receiving thread.
+ */
+ rc = RTUdpServerCreate("", pThis->uSrcPort, RTTHREADTYPE_IO, pThis->pszInstance,
+ drvUDPTunnelReceive, pDrvIns, &pThis->pServer);
+ if (RT_FAILURE(rc))
+ return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
+ N_("UDPTunnel: Failed to start the UDP tunnel server"));
+
+ /*
+ * Create the transmit lock.
+ */
+ rc = RTCritSectInit(&pThis->XmitLock);
+ AssertRCReturn(rc, rc);
+
+ return rc;
+}
+
+
+/**
+ * Suspend notification.
+ *
+ * @param pDrvIns The driver instance.
+ */
+static DECLCALLBACK(void) drvUDPTunnelSuspend(PPDMDRVINS pDrvIns)
+{
+ LogFlowFunc(("\n"));
+ PDRVUDPTUNNEL pThis = PDMINS_2_DATA(pDrvIns, PDRVUDPTUNNEL);
+
+ if (pThis->pServer)
+ {
+ RTUdpServerDestroy(pThis->pServer);
+ pThis->pServer = NULL;
+ }
+}
+
+
+/**
+ * Resume notification.
+ *
+ * @param pDrvIns The driver instance.
+ */
+static DECLCALLBACK(void) drvUDPTunnelResume(PPDMDRVINS pDrvIns)
+{
+ LogFlowFunc(("\n"));
+ PDRVUDPTUNNEL pThis = PDMINS_2_DATA(pDrvIns, PDRVUDPTUNNEL);
+
+ int rc = RTUdpServerCreate("", pThis->uSrcPort, RTTHREADTYPE_IO, pThis->pszInstance,
+ drvUDPTunnelReceive, pDrvIns, &pThis->pServer);
+ if (RT_FAILURE(rc))
+ PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
+ N_("UDPTunnel: Failed to start the UDP tunnel server"));
+
+}
+
+
+/**
+ * UDP tunnel network transport driver registration record.
+ */
+const PDMDRVREG g_DrvUDPTunnel =
+{
+ /* u32Version */
+ PDM_DRVREG_VERSION,
+ /* szName */
+ "UDPTunnel",
+ /* szRCMod */
+ "",
+ /* szR0Mod */
+ "",
+ /* pszDescription */
+ "UDP Tunnel Network Transport Driver",
+ /* fFlags */
+ PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
+ /* fClass. */
+ PDM_DRVREG_CLASS_NETWORK,
+ /* cMaxInstances */
+ ~0,
+ /* cbInstance */
+ sizeof(DRVUDPTUNNEL),
+ /* pfnConstruct */
+ drvUDPTunnelConstruct,
+ /* pfnDestruct */
+ drvUDPTunnelDestruct,
+ /* pfnRelocate */
+ NULL,
+ /* pfnIOCtl */
+ NULL,
+ /* pfnPowerOn */
+ NULL,
+ /* pfnReset */
+ NULL,
+ /* pfnSuspend */
+ drvUDPTunnelSuspend,
+ /* pfnResume */
+ drvUDPTunnelResume,
+ /* pfnAttach */
+ NULL,
+ /* pfnDetach */
+ NULL,
+ /* pfnPowerOff */
+ NULL,
+ /* pfnSoftReset */
+ NULL,
+ /* u32EndVersion */
+ PDM_DRVREG_VERSION
+};
+
diff --git a/src/VBox/Devices/Network/DrvVDE.cpp b/src/VBox/Devices/Network/DrvVDE.cpp
index d1f5005ac..b09221b65 100644
--- a/src/VBox/Devices/Network/DrvVDE.cpp
+++ b/src/VBox/Devices/Network/DrvVDE.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvVDE.cpp $ */
+/* $Id: DrvVDE.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VDE network transport driver.
*/
@@ -33,6 +33,7 @@
#include <iprt/mem.h>
#include <iprt/param.h>
#include <iprt/path.h>
+#include <iprt/pipe.h>
#include <iprt/semaphore.h>
#include <iprt/string.h>
#include <iprt/thread.h>
@@ -63,18 +64,16 @@ typedef struct DRVVDE
PPDMINETWORKDOWN pIAboveNet;
/** Pointer to the driver instance. */
PPDMDRVINS pDrvIns;
- /** VDE device file handle. */
- RTFILE FileDevice;
/** The configured VDE device name. */
char *pszDeviceName;
/** The write end of the control pipe. */
- RTFILE PipeWrite;
+ RTPIPE hPipeWrite;
/** The read end of the control pipe. */
- RTFILE PipeRead;
+ RTPIPE hPipeRead;
/** Reader thread. */
PPDMTHREAD pThread;
/** The connection to the VDE switch */
- VDECONN *vdeconn;
+ VDECONN *pVdeConn;
/** @todo The transmit thread. */
/** Transmit lock used by drvTAPNetworkUp_BeginXmit. */
@@ -224,7 +223,7 @@ static DECLCALLBACK(int) drvVDENetworkUp_SendBuf(PPDMINETWORKUP pInterface, PPDM
pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, pSgBuf->cbUsed, pSgBuf->aSegs[0].pvSeg));
ssize_t cbSent;
- cbSent = vde_send(pThis->vdeconn, pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, 0);
+ cbSent = vde_send(pThis->pVdeConn, pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, 0);
rc = cbSent < 0 ? RTErrConvertFromErrno(-cbSent) : VINF_SUCCESS;
}
else
@@ -240,7 +239,7 @@ static DECLCALLBACK(int) drvVDENetworkUp_SendBuf(PPDMINETWORKUP pInterface, PPDM
void *pvSegFrame = PDMNetGsoCarveSegmentQD(pGso, (uint8_t *)pbFrame, pSgBuf->cbUsed, abHdrScratch,
iSeg, cSegs, &cbSegFrame);
ssize_t cbSent;
- cbSent = vde_send(pThis->vdeconn, pvSegFrame, cbSegFrame, 0);
+ cbSent = vde_send(pThis->pVdeConn, pvSegFrame, cbSegFrame, 0);
rc = cbSent < 0 ? RTErrConvertFromErrno(-cbSent) : VINF_SUCCESS;
if (RT_FAILURE(rc))
break;
@@ -318,10 +317,10 @@ static DECLCALLBACK(int) drvVDEAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr
* Wait for something to become available.
*/
struct pollfd aFDs[2];
- aFDs[0].fd = vde_datafd(pThis->vdeconn);
+ aFDs[0].fd = vde_datafd(pThis->pVdeConn);
aFDs[0].events = POLLIN | POLLPRI;
aFDs[0].revents = 0;
- aFDs[1].fd = pThis->PipeRead;
+ aFDs[1].fd = RTPipeToNative(pThis->hPipeRead);
aFDs[1].events = POLLIN | POLLPRI | POLLERR | POLLHUP;
aFDs[1].revents = 0;
STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a);
@@ -342,7 +341,7 @@ static DECLCALLBACK(int) drvVDEAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr
*/
char achBuf[16384];
ssize_t cbRead = 0;
- cbRead = vde_recv(pThis->vdeconn, achBuf, sizeof(achBuf), 0);
+ cbRead = vde_recv(pThis->pVdeConn, achBuf, sizeof(achBuf), 0);
rc = cbRead < 0 ? RTErrConvertFromErrno(-cbRead) : VINF_SUCCESS;
if (RT_SUCCESS(rc))
{
@@ -403,7 +402,7 @@ static DECLCALLBACK(int) drvVDEAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr
/* drain the pipe */
char ch;
size_t cbRead;
- RTFileRead(pThis->PipeRead, &ch, 1, &cbRead);
+ RTPipeRead(pThis->hPipeRead, &ch, 1, &cbRead);
}
else
{
@@ -439,7 +438,8 @@ static DECLCALLBACK(int) drvVDEAsyncIoWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThr
{
PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE);
- int rc = RTFileWrite(pThis->PipeWrite, "", 1, NULL);
+ size_t cbIgnored;
+ int rc = RTPipeWrite(pThis->hPipeWrite, "", 1, &cbIgnored);
AssertRC(rc);
return VINF_SUCCESS;
@@ -480,18 +480,10 @@ static DECLCALLBACK(void) drvVDEDestruct(PPDMDRVINS pDrvIns)
/*
* Terminate the control pipe.
*/
- if (pThis->PipeWrite != NIL_RTFILE)
- {
- int rc = RTFileClose(pThis->PipeWrite);
- AssertRC(rc);
- pThis->PipeWrite = NIL_RTFILE;
- }
- if (pThis->PipeRead != NIL_RTFILE)
- {
- int rc = RTFileClose(pThis->PipeRead);
- AssertRC(rc);
- pThis->PipeRead = NIL_RTFILE;
- }
+ RTPipeClose(pThis->hPipeWrite);
+ pThis->hPipeWrite = NIL_RTPIPE;
+ RTPipeClose(pThis->hPipeRead);
+ pThis->hPipeRead = NIL_RTPIPE;
MMR3HeapFree(pThis->pszDeviceName);
@@ -501,7 +493,9 @@ static DECLCALLBACK(void) drvVDEDestruct(PPDMDRVINS pDrvIns)
if (RTCritSectIsInitialized(&pThis->XmitLock))
RTCritSectDelete(&pThis->XmitLock);
- vde_close(pThis->vdeconn);
+ vde_close(pThis->pVdeConn);
+ pThis->pVdeConn = NULL;
+
#ifdef VBOX_WITH_STATISTICS
/*
* Deregister statistics.
@@ -529,14 +523,13 @@ static DECLCALLBACK(int) drvVDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
/*
* Init the static parts.
*/
- pThis->pDrvIns = pDrvIns;
- pThis->FileDevice = NIL_RTFILE;
- pThis->pszDeviceName = NULL;
- pThis->PipeRead = NIL_RTFILE;
- pThis->PipeWrite = NIL_RTFILE;
+ pThis->pDrvIns = pDrvIns;
+ pThis->pszDeviceName = NULL;
+ pThis->hPipeRead = NIL_RTPIPE;
+ pThis->hPipeWrite = NIL_RTPIPE;
/* IBase */
- pDrvIns->IBase.pfnQueryInterface = drvVDEQueryInterface;
+ pDrvIns->IBase.pfnQueryInterface = drvVDEQueryInterface;
/* INetwork */
pThis->INetworkUp.pfnBeginXmit = drvVDENetworkUp_BeginXmit;
pThis->INetworkUp.pfnAllocBuf = drvVDENetworkUp_AllocBuf;
@@ -561,7 +554,7 @@ static DECLCALLBACK(int) drvVDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
/*
* Validate the config.
*/
- if (!CFGMR3AreValuesValid(pCfg, "Network"))
+ if (!CFGMR3AreValuesValid(pCfg, "network"))
return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES, "");
/*
@@ -584,15 +577,15 @@ static DECLCALLBACK(int) drvVDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
*/
int rc;
char szNetwork[RTPATH_MAX];
- rc = CFGMR3QueryString(pCfg, "Network", szNetwork, sizeof(szNetwork));
+ rc = CFGMR3QueryString(pCfg, "network", szNetwork, sizeof(szNetwork));
if (RT_FAILURE(rc))
*szNetwork=0;
if (RT_FAILURE(DrvVDELoadVDEPlug()))
return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
N_("VDEplug library: not found"));
- pThis->vdeconn = vde_open(szNetwork, "VirtualBOX", NULL);
- if (pThis->vdeconn == NULL)
+ pThis->pVdeConn = vde_open(szNetwork, "VirtualBOX", NULL);
+ if (pThis->pVdeConn == NULL)
return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
N_("Failed to connect to the VDE SWITCH"));
@@ -605,15 +598,8 @@ static DECLCALLBACK(int) drvVDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
/*
* Create the control pipe.
*/
- int fds[2];
- if (pipe(&fds[0]) != 0) /** @todo RTPipeCreate() or something... */
- {
- rc = RTErrConvertFromErrno(errno);
- AssertRC(rc);
- return rc;
- }
- pThis->PipeRead = fds[0];
- pThis->PipeWrite = fds[1];
+ rc = RTPipeCreate(&pThis->hPipeRead, &pThis->hPipeWrite, 0 /*fFlags*/);
+ AssertRCReturn(rc, rc);
/*
* Create the async I/O thread.
diff --git a/src/VBox/Devices/Network/Pcap.cpp b/src/VBox/Devices/Network/Pcap.cpp
index 2c33563d8..0ab7422a5 100644
--- a/src/VBox/Devices/Network/Pcap.cpp
+++ b/src/VBox/Devices/Network/Pcap.cpp
@@ -1,4 +1,4 @@
-/* $Id: Pcap.cpp $ */
+/* $Id: Pcap.cpp 37369 2011-06-07 22:32:14Z vboxsync $ */
/** @file
* Helpers for writing libpcap files.
*/
diff --git a/src/VBox/Devices/Network/Pcap.h b/src/VBox/Devices/Network/Pcap.h
index c05b39030..dab0cd2eb 100644
--- a/src/VBox/Devices/Network/Pcap.h
+++ b/src/VBox/Devices/Network/Pcap.h
@@ -1,4 +1,4 @@
-/* $Id: Pcap.h $ */
+/* $Id: Pcap.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Helpers for writing libpcap files.
*/
diff --git a/src/VBox/Devices/Network/SrvIntNetR0.cpp b/src/VBox/Devices/Network/SrvIntNetR0.cpp
index 74a0ffb1f..5c58c3305 100644
--- a/src/VBox/Devices/Network/SrvIntNetR0.cpp
+++ b/src/VBox/Devices/Network/SrvIntNetR0.cpp
@@ -1,4 +1,4 @@
-/* $Id: SrvIntNetR0.cpp $ */
+/* $Id: SrvIntNetR0.cpp 37979 2011-07-15 14:04:24Z vboxsync $ */
/** @file
* Internal networking - The ring 0 service.
*/
@@ -282,6 +282,8 @@ typedef struct INTNETIF
PINTNETDSTTAB volatile pDstTab;
/** Pointer to the trunk's per interface data. Can be NULL. */
void *pvIfData;
+ /** Header buffer for when we're carving GSO frames. */
+ uint8_t abGsoHdrs[256];
} INTNETIF;
/** Pointer to an internal network interface. */
typedef INTNETIF *PINTNETIF;
@@ -318,8 +320,6 @@ typedef struct INTNETTRUNKIF
* This is as bit map where each bit represents the GSO type with the same
* number. */
uint32_t fHostGsoCapabilites;
- /** Header buffer for when we're carving GSO frames. */
- uint8_t abGsoHdrs[256];
/** The destination table spinlock, interrupt safe.
* Protects apTaskDstTabs and apIntDstTabs. */
RTSPINLOCK hDstTabSpinlock;
@@ -2664,11 +2664,11 @@ static int intnetR0TrunkIfSendGsoFallback(PINTNETTRUNKIF pThis, PINTNETIF pIfSen
{
uint32_t cbSegPayload;
uint32_t offSegPayload = PDMNetGsoCarveSegment(&pSG->GsoCtx, (uint8_t *)pSG->aSegs[0].pv, pSG->cbTotal, iSeg, cSegs,
- pThis->abGsoHdrs, &cbSegPayload);
+ pIfSender->abGsoHdrs, &cbSegPayload);
IntNetSgInitTempSegs(&u.SG, pSG->GsoCtx.cbHdrs + cbSegPayload, 2, 2);
u.SG.aSegs[0].Phys = NIL_RTHCPHYS;
- u.SG.aSegs[0].pv = pThis->abGsoHdrs;
+ u.SG.aSegs[0].pv = pIfSender->abGsoHdrs;
u.SG.aSegs[0].cb = pSG->GsoCtx.cbHdrs;
u.SG.aSegs[1].Phys = NIL_RTHCPHYS;
u.SG.aSegs[1].pv = (uint8_t *)pSG->aSegs[0].pv + offSegPayload;
@@ -2948,23 +2948,29 @@ static void intnetR0NetworkEditDhcpFromIntNet(PINTNETNETWORK pNetwork, PINTNETSG
return;
}
PCRTNETBOOTP pDhcp = (PCRTNETBOOTP)(pUdpHdr + 1);
- uint8_t MsgType;
- if (!RTNetIPv4IsDHCPValid(pUdpHdr, pDhcp, cbUdpPkt - sizeof(*pUdpHdr), &MsgType))
+ uint8_t bMsgType;
+ if (!RTNetIPv4IsDHCPValid(pUdpHdr, pDhcp, cbUdpPkt - sizeof(*pUdpHdr), &bMsgType))
{
Log6(("intnetR0NetworkEditDhcpFromIntNet: Bad DHCP packet\n"));
return;
}
- switch (MsgType)
+ switch (bMsgType)
{
case RTNET_DHCP_MT_DISCOVER:
case RTNET_DHCP_MT_REQUEST:
- Log6(("intnetR0NetworkEditDhcpFromIntNet: Setting broadcast flag in DHCP %#x, previously %x\n", MsgType, pDhcp->bp_flags));
+ /*
+ * Must set the broadcast flag or we won't catch the respons.
+ */
if (!(pDhcp->bp_flags & RT_H2BE_U16_C(RTNET_DHCP_FLAG_BROADCAST)))
{
+ Log6(("intnetR0NetworkEditDhcpFromIntNet: Setting broadcast flag in DHCP %#x, previously %x\n",
+ bMsgType, pDhcp->bp_flags));
+
/* Patch flags */
uint16_t uFlags = pDhcp->bp_flags | RT_H2BE_U16_C(RTNET_DHCP_FLAG_BROADCAST);
intnetR0SgWritePart(pSG, (uintptr_t)&pDhcp->bp_flags - (uintptr_t)pIpHdr + sizeof(RTNETETHERHDR), sizeof(uFlags), &uFlags);
+
/* Patch UDP checksum */
uint32_t uChecksum = (uint32_t)~pUdpHdr->uh_sum + RT_H2BE_U16_C(RTNET_DHCP_FLAG_BROADCAST);
while (uChecksum >> 16)
@@ -2972,6 +2978,31 @@ static void intnetR0NetworkEditDhcpFromIntNet(PINTNETNETWORK pNetwork, PINTNETSG
uChecksum = ~uChecksum;
intnetR0SgWritePart(pSG, (uintptr_t)&pUdpHdr->uh_sum - (uintptr_t)pIpHdr + sizeof(RTNETETHERHDR), sizeof(pUdpHdr->uh_sum), &uChecksum);
}
+
+#ifdef RT_OS_DARWIN
+ /*
+ * Work around little endian checksum issue in mac os x 10.7.0 GM.
+ */
+ if ( pIpHdr->ip_tos
+ && (pNetwork->fFlags & INTNET_OPEN_FLAGS_WORKAROUND_1))
+ {
+ /* Patch it. */
+ uint8_t uTos = pIpHdr->ip_tos;
+ uint8_t uZero = 0;
+ intnetR0SgWritePart(pSG, sizeof(RTNETETHERHDR) + 1, sizeof(uZero), &uZero);
+
+ /* Patch the IP header checksum. */
+ uint32_t uChecksum = (uint32_t)~pIpHdr->ip_sum - (uTos << 8);
+ while (uChecksum >> 16)
+ uChecksum = (uChecksum >> 16) + (uChecksum & 0xFFFF);
+ uChecksum = ~uChecksum;
+
+ Log(("intnetR0NetworkEditDhcpFromIntNet: cleared ip_tos (was %#04x); ip_sum=%#06x -> %#06x\n",
+ uTos, RT_BE2H_U16(pIpHdr->ip_sum), RT_BE2H_U16(uChecksum) ));
+ intnetR0SgWritePart(pSG, sizeof(RTNETETHERHDR) + RT_OFFSETOF(RTNETIPV4, ip_sum),
+ sizeof(pIpHdr->ip_sum), &uChecksum);
+ }
+#endif
break;
}
}
diff --git a/src/VBox/Devices/Network/lwip/src/netif/ppp/chap.h b/src/VBox/Devices/Network/lwip/src/netif/ppp/chap.h
index 06d1b15f8..6fd972752 100644
--- a/src/VBox/Devices/Network/lwip/src/netif/ppp/chap.h
+++ b/src/VBox/Devices/Network/lwip/src/netif/ppp/chap.h
@@ -62,7 +62,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: chap.h $
+ * $Id: chap.h,v 1.1 2003/05/27 14:37:56 jani Exp $
*/
#ifndef CHAP_H
diff --git a/src/VBox/Devices/Network/lwip/src/netif/ppp/chpms.h b/src/VBox/Devices/Network/lwip/src/netif/ppp/chpms.h
index cfb20471c..c58447215 100644
--- a/src/VBox/Devices/Network/lwip/src/netif/ppp/chpms.h
+++ b/src/VBox/Devices/Network/lwip/src/netif/ppp/chpms.h
@@ -51,7 +51,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: chpms.h $
+ * $Id: chpms.h,v 1.3 2004/02/07 00:30:03 likewise Exp $
*/
#ifndef CHPMS_H
diff --git a/src/VBox/Devices/Network/lwip/src/netif/ppp/fsm.h b/src/VBox/Devices/Network/lwip/src/netif/ppp/fsm.h
index 17bdd4a21..0e1d9f61a 100644
--- a/src/VBox/Devices/Network/lwip/src/netif/ppp/fsm.h
+++ b/src/VBox/Devices/Network/lwip/src/netif/ppp/fsm.h
@@ -48,7 +48,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: fsm.h $
+ * $Id: fsm.h,v 1.1 2003/05/27 14:37:56 jani Exp $
*/
#ifndef FSM_H
diff --git a/src/VBox/Devices/Network/lwip/src/netif/ppp/ipcp.h b/src/VBox/Devices/Network/lwip/src/netif/ppp/ipcp.h
index d96c02ec8..416aa79a2 100644
--- a/src/VBox/Devices/Network/lwip/src/netif/ppp/ipcp.h
+++ b/src/VBox/Devices/Network/lwip/src/netif/ppp/ipcp.h
@@ -48,7 +48,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: ipcp.h $
+ * $Id: ipcp.h,v 1.1 2003/05/27 14:37:56 jani Exp $
*/
#ifndef IPCP_H
diff --git a/src/VBox/Devices/Network/lwip/src/netif/ppp/lcp.h b/src/VBox/Devices/Network/lwip/src/netif/ppp/lcp.h
index 1decc386b..3876d39ae 100644
--- a/src/VBox/Devices/Network/lwip/src/netif/ppp/lcp.h
+++ b/src/VBox/Devices/Network/lwip/src/netif/ppp/lcp.h
@@ -48,7 +48,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: lcp.h $
+ * $Id: lcp.h,v 1.1 2003/05/27 14:37:56 jani Exp $
*/
#ifndef LCP_H
diff --git a/src/VBox/Devices/Network/lwip/src/netif/ppp/magic.h b/src/VBox/Devices/Network/lwip/src/netif/ppp/magic.h
index 54619b7b8..7574f32b9 100644
--- a/src/VBox/Devices/Network/lwip/src/netif/ppp/magic.h
+++ b/src/VBox/Devices/Network/lwip/src/netif/ppp/magic.h
@@ -48,7 +48,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: magic.h $
+ * $Id: magic.h,v 1.1 2003/05/27 14:37:56 jani Exp $
*/
#ifndef MAGIC_H
diff --git a/src/VBox/Devices/Network/lwip/src/netif/ppp/vj.h b/src/VBox/Devices/Network/lwip/src/netif/ppp/vj.h
index b7374b3f0..717208145 100644
--- a/src/VBox/Devices/Network/lwip/src/netif/ppp/vj.h
+++ b/src/VBox/Devices/Network/lwip/src/netif/ppp/vj.h
@@ -1,7 +1,7 @@
/*
* Definitions for tcp compression routines.
*
- * $Id: vj.h $
+ * $Id: vj.h,v 1.4 2004/02/07 00:30:03 likewise Exp $
*
* Copyright (c) 1989 Regents of the University of California.
* All rights reserved.
diff --git a/src/VBox/Devices/Network/lwip/vbox/sys_arch.c b/src/VBox/Devices/Network/lwip/vbox/sys_arch.c
index 047ecc2f6..0f247118f 100644
--- a/src/VBox/Devices/Network/lwip/vbox/sys_arch.c
+++ b/src/VBox/Devices/Network/lwip/vbox/sys_arch.c
@@ -1,4 +1,4 @@
-/** $Id: sys_arch.c $ */
+/** $Id: sys_arch.c 33464 2010-10-26 12:27:50Z vboxsync $ */
/** @file
* System dependent parts of lwIP, implemented with IPRT.
*/
diff --git a/src/VBox/Devices/Network/scripts/VBoxConvertNATStats.sh b/src/VBox/Devices/Network/scripts/VBoxConvertNATStats.sh
index 5c871dae9..5c871dae9 100755..100644
--- a/src/VBox/Devices/Network/scripts/VBoxConvertNATStats.sh
+++ b/src/VBox/Devices/Network/scripts/VBoxConvertNATStats.sh
diff --git a/src/VBox/Devices/Network/scripts/VBoxPortForwarding.py b/src/VBox/Devices/Network/scripts/VBoxPortForwarding.py
index 513b1d608..513b1d608 100755..100644
--- a/src/VBox/Devices/Network/scripts/VBoxPortForwarding.py
+++ b/src/VBox/Devices/Network/scripts/VBoxPortForwarding.py
diff --git a/src/VBox/Devices/Network/slirp/bootp.c b/src/VBox/Devices/Network/slirp/bootp.c
index ec567d71a..27855a2b7 100644
--- a/src/VBox/Devices/Network/slirp/bootp.c
+++ b/src/VBox/Devices/Network/slirp/bootp.c
@@ -1,4 +1,4 @@
-/* $Id: bootp.c $ */
+/* $Id: bootp.c 37746 2011-07-04 06:07:37Z vboxsync $ */
/** @file
* NAT - BOOTP/DHCP server emulation.
*/
@@ -255,9 +255,9 @@ static int dhcp_do_ack_offer(PNATState pData, struct mbuf *m, BOOTPClient *bc, i
Log(("NAT: DHCP: bp_file:%s\n", &rbp->bp_file));
/* Address/port of the DHCP server. */
rbp->bp_yiaddr = bc->addr; /* Client IP address */
- Log(("NAT: DHCP: bp_yiaddr:%R[IP4]\n", &rbp->bp_yiaddr));
+ Log(("NAT: DHCP: bp_yiaddr:%RTnaipv4\n", rbp->bp_yiaddr));
rbp->bp_siaddr = pData->tftp_server; /* Next Server IP address, i.e. TFTP */
- Log(("NAT: DHCP: bp_siaddr:%R[IP4]\n", &rbp->bp_siaddr));
+ Log(("NAT: DHCP: bp_siaddr:%RTnaipv4\n", rbp->bp_siaddr));
if (fDhcpRequest)
{
rbp->bp_ciaddr.s_addr = bc->addr.s_addr; /* Client IP address */
@@ -267,7 +267,7 @@ static int dhcp_do_ack_offer(PNATState pData, struct mbuf *m, BOOTPClient *bc, i
#else
saddr.s_addr = pData->special_addr.s_addr;
#endif
- Log(("NAT: DHCP: s_addr:%R[IP4]\n", &saddr));
+ Log(("NAT: DHCP: s_addr:%RTnaipv4\n", saddr));
#define FILL_BOOTP_EXT(q, tag, len, pvalue) \
do { \
@@ -454,7 +454,7 @@ static int dhcp_decode_request(PNATState pData, struct bootp_t *bp, const uint8_
{
if ((bp->bp_ciaddr.s_addr & RT_H2N_U32(pData->netmask)) != pData->special_addr.s_addr)
{
- LogRel(("NAT: Client %R[IP4] requested IP -- sending NAK\n", &bp->bp_ciaddr));
+ LogRel(("NAT: Client %RTnaipv4 requested IP -- sending NAK\n", bp->bp_ciaddr));
offReply = dhcp_send_nack(pData, bp, bc, m);
return offReply;
}
@@ -478,7 +478,7 @@ static int dhcp_decode_request(PNATState pData, struct bootp_t *bp, const uint8_
ui32 = *(uint32_t *)(req_ip + 2);
if ((ui32 & RT_H2N_U32(pData->netmask)) != pData->special_addr.s_addr)
{
- LogRel(("NAT: address %R[IP4] has been requested -- sending NAK\n", &ui32));
+ LogRel(("NAT: address %RTnaipv4 has been requested -- sending NAK\n", ui32));
offReply = dhcp_send_nack(pData, bp, bc, m);
return offReply;
}
@@ -502,7 +502,7 @@ static int dhcp_decode_request(PNATState pData, struct bootp_t *bp, const uint8_
break;
}
- LogRel(("NAT: DHCP offered IP address %R[IP4]\n", &bc->addr));
+ LogRel(("NAT: DHCP offered IP address %RTnaipv4\n", bc->addr));
offReply = dhcp_send_ack(pData, bp, bc, m, /* fDhcpRequest=*/ 1);
return offReply;
}
@@ -529,7 +529,7 @@ static int dhcp_decode_discover(PNATState pData, struct bootp_t *bp, const uint8
}
bc->xid = bp->bp_xid;
- LogRel(("NAT: DHCP offered IP address %R[IP4]\n", &bc->addr));
+ LogRel(("NAT: DHCP offered IP address %RTnaipv4\n", bc->addr));
offReply = dhcp_send_offer(pData, bp, bc, m);
return offReply;
}
@@ -542,7 +542,7 @@ static int dhcp_decode_discover(PNATState pData, struct bootp_t *bp, const uint8
return -1;
}
- LogRel(("NAT: DHCP offered IP address %R[IP4]\n", &bc->addr));
+ LogRel(("NAT: DHCP offered IP address %RTnaipv4\n", bc->addr));
offReply = dhcp_send_ack(pData, bp, bc, m, /* fDhcpRequest=*/ 0);
return offReply;
}
@@ -553,7 +553,7 @@ static int dhcp_decode_discover(PNATState pData, struct bootp_t *bp, const uint8
static int dhcp_decode_release(PNATState pData, struct bootp_t *bp, const uint8_t *buf, int size)
{
int rc = release_addr(pData, &bp->bp_ciaddr);
- LogRel(("NAT: %s %R[IP4]\n",
+ LogRel(("NAT: %s %RTnaipv4\n",
RT_SUCCESS(rc) ? "DHCP released IP address" : "Ignored DHCP release for IP address",
&bp->bp_ciaddr));
return 0;
@@ -709,7 +709,7 @@ static void dhcp_decode(PNATState pData, struct bootp_t *bp, const uint8_t *buf,
Assert(bc);
bc->addr.s_addr = req_ip.s_addr;
slirp_arp_who_has(pData, bc->addr.s_addr);
- LogRel(("NAT: %R[IP4] has been already registered\n", &req_ip));
+ LogRel(("NAT: %RTnaipv4 has been already registered\n", req_ip));
}
/* no response required */
break;
diff --git a/src/VBox/Devices/Network/slirp/bootp.h b/src/VBox/Devices/Network/slirp/bootp.h
index 1ffa3a5dd..7c2e3b869 100644
--- a/src/VBox/Devices/Network/slirp/bootp.h
+++ b/src/VBox/Devices/Network/slirp/bootp.h
@@ -1,4 +1,4 @@
-/* $Id: bootp.h $ */
+/* $Id: bootp.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - BOOTP/DHCP server emulation (declarations/defines).
*/
diff --git a/src/VBox/Devices/Network/slirp/bsd/kern/kern_mbuf.c b/src/VBox/Devices/Network/slirp/bsd/kern/kern_mbuf.c
index 3de3d0ea9..8bfe53dda 100644
--- a/src/VBox/Devices/Network/slirp/bsd/kern/kern_mbuf.c
+++ b/src/VBox/Devices/Network/slirp/bsd/kern/kern_mbuf.c
@@ -125,15 +125,7 @@ tunable_mbinit(void *dummy)
nmbclusters = 1024 + maxusers * 64;
nmbjumbop = nmbclusters / 2;
nmbjumbo9 = nmbjumbop / 2;
-#ifndef VBOX
nmbjumbo16 = nmbjumbo9 / 2;
-#else
- /* drvNATNetowrkUp_AllocBuf always requests mbuf from this
- * zones, that require more buffers allocated on jumbo16 zone,
- * in case of intensive communication like p2p and UDP benches.
- */
- nmbjumbo16 = nmbclusters;
-#endif
TUNABLE_INT_FETCH("kern.ipc.nmbclusters", &nmbclusters);
}
SYSINIT(tunable_mbinit, SI_SUB_TUNABLES, SI_ORDER_MIDDLE, tunable_mbinit, NULL);
diff --git a/src/VBox/Devices/Network/slirp/cksum.c b/src/VBox/Devices/Network/slirp/cksum.c
index 8e2cbd78a..0cfb94c02 100644
--- a/src/VBox/Devices/Network/slirp/cksum.c
+++ b/src/VBox/Devices/Network/slirp/cksum.c
@@ -1,4 +1,4 @@
-/* $Id: cksum.c $ */
+/* $Id: cksum.c 34103 2010-11-16 11:18:55Z vboxsync $ */
/** @file
* NAT - IP checksum generation.
*/
diff --git a/src/VBox/Devices/Network/slirp/counters.h b/src/VBox/Devices/Network/slirp/counters.h
index 14f353b41..9f0f9a169 100644
--- a/src/VBox/Devices/Network/slirp/counters.h
+++ b/src/VBox/Devices/Network/slirp/counters.h
@@ -1,4 +1,4 @@
-/** $Id: counters.h $ */
+/** $Id: counters.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Counters macro invocation template.
*
diff --git a/src/VBox/Devices/Network/slirp/ctl.h b/src/VBox/Devices/Network/slirp/ctl.h
index 172b0c075..fae638af7 100644
--- a/src/VBox/Devices/Network/slirp/ctl.h
+++ b/src/VBox/Devices/Network/slirp/ctl.h
@@ -1,4 +1,4 @@
-/* $Id: ctl.h $ */
+/* $Id: ctl.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - IP subnet constants.
*/
diff --git a/src/VBox/Devices/Network/slirp/debug.c b/src/VBox/Devices/Network/slirp/debug.c
index b6a51b11b..512145fe0 100644
--- a/src/VBox/Devices/Network/slirp/debug.c
+++ b/src/VBox/Devices/Network/slirp/debug.c
@@ -1,4 +1,4 @@
-/* $Id: debug.c $ */
+/* $Id: debug.c 37938 2011-07-14 04:28:46Z vboxsync $ */
/** @file
* NAT - debug helpers.
*/
@@ -34,8 +34,25 @@
void dump_packet(void *, int);
#endif
-#define IP4_ADDR_PRINTF_DECOMP(ip) ((ip) >> 24), ((ip) >> 16) & 0xff, ((ip) >> 8) & 0xff, (ip) & 0xff
-#define IP4_ADDR_PRINTF_FORMAT "%u.%u.%u.%u"
+#ifndef STRINGIFY
+# define STRINGIFY(x) #x
+#endif
+
+static char *g_apszTcpStates[TCP_NSTATES] =
+{
+ STRINGIFY(TCPS_CLOSED),
+ STRINGIFY(TCPS_LISTEN),
+ STRINGIFY(TCPS_SYN_SENT),
+ STRINGIFY(TCPS_SYN_RECEIVED),
+ STRINGIFY(TCPS_ESTABLISHED),
+ STRINGIFY(TCPS_CLOSE_WAIT),
+ STRINGIFY(TCPS_FIN_WAIT_1),
+ STRINGIFY(TCPS_CLOSING),
+ STRINGIFY(TCPS_LAST_ACK),
+ STRINGIFY(TCPS_FIN_WAIT_2),
+ STRINGIFY(TCPS_TIME_WAIT)
+};
+
/*
* Dump a packet in the same format as tcpdump -x
*/
@@ -227,39 +244,6 @@ sockstats(PNATState pData)
#endif
static DECLCALLBACK(size_t)
-print_ipv4_address(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
- const char *pszType, void const *pvValue,
- int cchWidth, int cchPrecision, unsigned fFlags,
- void *pvUser)
-{
- uint32_t ip;
-
- AssertReturn(strcmp(pszType, "IP4") == 0, 0);
-
- ip = RT_N2H_U32(*(uint32_t*)pvValue);
- return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, IP4_ADDR_PRINTF_FORMAT,
- IP4_ADDR_PRINTF_DECOMP(ip));
-}
-
-static DECLCALLBACK(size_t)
-print_ether_address(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
- const char *pszType, void const *pvValue,
- int cchWidth, int cchPrecision, unsigned fFlags,
- void *pvUser)
-{
- char *ether = (char *)pvValue;
-
- AssertReturn(strcmp(pszType, "ether") == 0, 0);
- if (ether)
- return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
- "[ether %hhx:%hhx:%hhx:%hhx:%hhx:%hhx]",
- ether[0], ether[1], ether[2],
- ether[3], ether[4], ether[5]);
- else
- return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "[ether null]");
-}
-
-static DECLCALLBACK(size_t)
print_socket(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
const char *pszType, void const *pvValue,
int cchWidth, int cchPrecision, unsigned fFlags,
@@ -288,13 +272,17 @@ print_socket(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
}
in_addr = (struct sockaddr_in *)&addr;
- ip = RT_N2H_U32(so->so_faddr.s_addr);
return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "socket %d:(proto:%u) "
- "state=%04x ip=" IP4_ADDR_PRINTF_FORMAT ":%d "
- "name=" IP4_ADDR_PRINTF_FORMAT ":%d",
- so->s, so->so_type, so->so_state, IP4_ADDR_PRINTF_DECOMP(ip),
+ "state=%04x "
+ "f_(addr:port)=%RTnaipv4:%d "
+ "l_(addr:port)=%RTnaipv4:%d "
+ "name=%RTnaipv4:%d",
+ so->s, so->so_type, so->so_state,
+ so->so_faddr.s_addr,
RT_N2H_U16(so->so_fport),
- IP4_ADDR_PRINTF_DECOMP(RT_N2H_U32(in_addr->sin_addr.s_addr)),
+ so->so_laddr.s_addr,
+ RT_N2H_U16(so->so_lport),
+ in_addr->sin_addr.s_addr,
RT_N2H_U16(in_addr->sin_port));
}
@@ -309,10 +297,17 @@ printTcpcbRfc793(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
{
size_t cb = 0;
const struct tcpcb *tp = (const struct tcpcb *)pvValue;
- AssertReturn(RTStrCmp(pszType, "tcpcb793") == 0 && tp, 0);
- cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "TCB793[ SND(UNA: %x, NXT: %x, UP: %x, WND: %x, WL1:%x, WL2:%x, ISS:%x), ",
- tp->snd_una, tp->snd_nxt, tp->snd_up, tp->snd_wnd, tp->snd_wl1, tp->snd_wl2, tp->iss);
- cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "RCV(WND: %x, NXT: %x, UP: %x, IRS:%x)]", tp->rcv_wnd, tp->rcv_nxt, tp->rcv_up, tp->irs);
+ AssertReturn(RTStrCmp(pszType, "tcpcb793") == 0, 0);
+ if (tp)
+ {
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "TCB793[ state:%R[tcpstate] SND(UNA: %x, NXT: %x, UP: %x, WND: %x, WL1:%x, WL2:%x, ISS:%x), ",
+ tp->t_state, tp->snd_una, tp->snd_nxt, tp->snd_up, tp->snd_wnd, tp->snd_wl1, tp->snd_wl2, tp->iss);
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "RCV(WND: %x, NXT: %x, UP: %x, IRS:%x)]", tp->rcv_wnd, tp->rcv_nxt, tp->rcv_up, tp->irs);
+ }
+ else
+ {
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "TCB793[ NULL ]");
+ }
return cb;
}
/*
@@ -332,6 +327,40 @@ printTcpSegmentRfc793(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
return cb;
}
+/*
+ * Prints TCP state
+ */
+static DECLCALLBACK(size_t)
+printTcpState(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+ const char *pszType, void const *pvValue,
+ int cchWidth, int cchPrecision, unsigned fFlags,
+ void *pvUser)
+{
+ size_t cb = 0;
+ const int idxTcpState = (int)(uintptr_t)pvValue;
+ char *pszTcpStateName = (idxTcpState >= 0 && idxTcpState < TCP_NSTATES) ? g_apszTcpStates[idxTcpState] : "TCPS_INVALIDE_STATE";
+ AssertReturn(RTStrCmp(pszType, "tcpstate") == 0, 0);
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%s", pszTcpStateName);
+ return cb;
+}
+
+/*
+ * Prints sbuf state
+ */
+static DECLCALLBACK(size_t)
+printSbuf(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+ const char *pszType, void const *pvValue,
+ int cchWidth, int cchPrecision, unsigned fFlags,
+ void *pvUser)
+{
+ size_t cb = 0;
+ const struct sbuf *sb = (struct sbuf *)pvValue;
+ AssertReturn(RTStrCmp(pszType, "sbuf") == 0, 0);
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "[sbuf:%p cc:%d, datalen:%d, wprt:%p, rptr:%p data:%p]",
+ sb, sb->sb_cc, sb->sb_datalen, sb->sb_wptr, sb->sb_rptr, sb->sb_data);
+ return cb;
+}
+
static DECLCALLBACK(size_t)
print_networkevents(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
const char *pszType, void const *pvValue,
@@ -389,23 +418,20 @@ debug_init()
if (!g_fFormatRegistered)
{
- /*
- * XXX(r - frank): Move this to IPRT using RTNETADDRIPV4.
- * Use the specifier %RNAipv4.
- */
- rc = RTStrFormatTypeRegister("IP4", print_ipv4_address, NULL);
- AssertRC(rc);
- rc = RTStrFormatTypeRegister("ether", print_ether_address, NULL);
- AssertRC(rc);
+
rc = RTStrFormatTypeRegister("natsock", print_socket, NULL);
AssertRC(rc);
rc = RTStrFormatTypeRegister("natwinnetevents",
- print_networkevents, NULL);
+ print_networkevents, NULL);
AssertRC(rc);
rc = RTStrFormatTypeRegister("tcpcb793", printTcpcbRfc793, NULL);
AssertRC(rc);
rc = RTStrFormatTypeRegister("tcpseg793", printTcpSegmentRfc793, NULL);
AssertRC(rc);
+ rc = RTStrFormatTypeRegister("tcpstate", printTcpState, NULL);
+ AssertRC(rc);
+ rc = RTStrFormatTypeRegister("sbuf", printSbuf, NULL);
+ AssertRC(rc);
g_fFormatRegistered = 1;
}
diff --git a/src/VBox/Devices/Network/slirp/debug.h b/src/VBox/Devices/Network/slirp/debug.h
index 5cbdfda96..cf7fd581d 100644
--- a/src/VBox/Devices/Network/slirp/debug.h
+++ b/src/VBox/Devices/Network/slirp/debug.h
@@ -1,4 +1,4 @@
-/* $Id: debug.h $ */
+/* $Id: debug.h 37738 2011-07-03 11:41:17Z vboxsync $ */
/** @file
* NAT - debug helpers (declarations/defines).
*/
@@ -39,4 +39,15 @@ void icmpstats (PNATState);
void mbufstats (PNATState);
void sockstats (PNATState);
+#ifdef LOG_ENABLED
+# define TCP_STATE_SWITCH_TO(tp, new_tcp_state) \
+do { \
+ Log2(("%R[tcpcb793] switch to %R[tcpstate] -> %R[tcpstate]\n", (tp), (tp), (tp->t_state) ,(new_tcp_state))); \
+ if ((tp)->t_socket) \
+ Log2(("%R[tcpcb793] %R[natsock]\n", (tp), (tp)->t_socket)); \
+ (tp)->t_state = (new_tcp_state); \
+} while(0)
+#else
+# define TCP_STATE_SWITCH_TO(tp, new_tcp_state) (tp)->t_state = (new_tcp_state)
+#endif
#endif
diff --git a/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.c b/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.c
index ea163f5ca..e8efbaee1 100644
--- a/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.c
+++ b/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.c
@@ -1,4 +1,4 @@
-/* $Id: dnsproxy.c $ */
+/* $Id: dnsproxy.c 37746 2011-07-04 06:07:37Z vboxsync $ */
/*
* Copyright (c) 2003,2004,2005 Armin Wolfermann
*
@@ -357,7 +357,7 @@ dnsproxy_query(PNATState pData, struct socket *so, struct mbuf *m, int iphlen)
addr.sin_port = htons(53);
so->so_expire = curtime + recursive_timeout * 1000; /* let's slirp to care about expiration */
/* send it to our authoritative server */
- Log2(("NAT: request will be sent to %R[IP4] on %R[natsock]\n", &addr.sin_addr, so));
+ Log2(("NAT: request will be sent to %RTnaipv4 on %R[natsock]\n", addr.sin_addr, so));
if ((byte = sendto(so->s, buf, (unsigned int)byte, 0,
(struct sockaddr *)&addr,
sizeof(struct sockaddr_in))) == -1) {
@@ -366,7 +366,7 @@ dnsproxy_query(PNATState pData, struct socket *so, struct mbuf *m, int iphlen)
return;
}
so->so_state = SS_ISFCONNECTED; /* now it's selected */
- Log2(("NAT: request was sent to %R[IP4] on %R[natsock]\n", &addr.sin_addr, so));
+ Log2(("NAT: request was sent to %RTnaipv4 on %R[natsock]\n", addr.sin_addr, so));
#endif
++authoritative_queries;
#ifndef VBOX
diff --git a/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.h b/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.h
index 9d9df8515..24a3b3aa9 100644
--- a/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.h
+++ b/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.h
@@ -1,4 +1,4 @@
-/* $Id: dnsproxy.h $ */
+/* $Id: dnsproxy.h 26495 2010-02-14 07:59:48Z vboxsync $ */
/*
* Copyright (c) 2003,2004,2005 Armin Wolfermann
*
diff --git a/src/VBox/Devices/Network/slirp/dnsproxy/hash.c b/src/VBox/Devices/Network/slirp/dnsproxy/hash.c
index 0d007d05a..f22ad1f9e 100644
--- a/src/VBox/Devices/Network/slirp/dnsproxy/hash.c
+++ b/src/VBox/Devices/Network/slirp/dnsproxy/hash.c
@@ -1,4 +1,4 @@
-/* $Id: hash.c $ */
+/* $Id: hash.c 18815 2009-04-07 12:34:27Z vboxsync $ */
/*
* Copyright (c) 2003,2004 Armin Wolfermann
*
diff --git a/src/VBox/Devices/Network/slirp/ext.h b/src/VBox/Devices/Network/slirp/ext.h
index b1812b874..53be7f25c 100644
--- a/src/VBox/Devices/Network/slirp/ext.h
+++ b/src/VBox/Devices/Network/slirp/ext.h
@@ -1,4 +1,4 @@
-/** $Id: ext.h $ */
+/** $Id: ext.h 30016 2010-06-03 18:31:14Z vboxsync $ */
/** @file
* NAT - some externals helpers
*/
diff --git a/src/VBox/Devices/Network/slirp/icmp_var.h b/src/VBox/Devices/Network/slirp/icmp_var.h
index 829182bec..adfc45d56 100644
--- a/src/VBox/Devices/Network/slirp/icmp_var.h
+++ b/src/VBox/Devices/Network/slirp/icmp_var.h
@@ -1,4 +1,4 @@
-/* $Id: icmp_var.h $ */
+/* $Id: icmp_var.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - ICMP handling (declarations/defines).
*/
diff --git a/src/VBox/Devices/Network/slirp/if.h b/src/VBox/Devices/Network/slirp/if.h
index 08cb4ea16..aa37c2104 100644
--- a/src/VBox/Devices/Network/slirp/if.h
+++ b/src/VBox/Devices/Network/slirp/if.h
@@ -1,4 +1,4 @@
-/* $Id: if.h $ */
+/* $Id: if.h 30016 2010-06-03 18:31:14Z vboxsync $ */
/** @file
* NAT - if_*.
*/
diff --git a/src/VBox/Devices/Network/slirp/ip.h b/src/VBox/Devices/Network/slirp/ip.h
index 1d1880296..985df9d92 100644
--- a/src/VBox/Devices/Network/slirp/ip.h
+++ b/src/VBox/Devices/Network/slirp/ip.h
@@ -1,4 +1,4 @@
-/* $Id: ip.h $ */
+/* $Id: ip.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - IP handling (declarations/defines).
*/
diff --git a/src/VBox/Devices/Network/slirp/ip_icmp.c b/src/VBox/Devices/Network/slirp/ip_icmp.c
index 8a4ca805c..c5029723c 100644
--- a/src/VBox/Devices/Network/slirp/ip_icmp.c
+++ b/src/VBox/Devices/Network/slirp/ip_icmp.c
@@ -1,4 +1,4 @@
-/* $Id: ip_icmp.c $ */
+/* $Id: ip_icmp.c 37936 2011-07-14 03:54:41Z vboxsync $ */
/** @file
* NAT - IP/ICMP handling.
*/
@@ -185,7 +185,7 @@ icmp_find_original_mbuf(PNATState pData, struct ip *ip)
fport = ~0;
- Log(("%s: processing (proto:%d)\n", __FUNCTION__, ip->ip_p));
+ LogFlowFunc(("ENTER: ip->ip_p:%d\n", ip->ip_p));
switch (ip->ip_p)
{
case IPPROTO_ICMP:
@@ -262,7 +262,7 @@ icmp_find_original_mbuf(PNATState pData, struct ip *ip)
for (so = head_socket->so_prev; so != head_socket; so = so->so_prev)
{
/* Should be reaplaced by hash here */
- Log(("trying:%R[natsock] against %R[IP4]:%d lport=%d hlport=%d\n", so, &faddr, fport, lport, so->so_hlport));
+ Log(("trying:%R[natsock] against %RTnaipv4:%d lport=%d hlport=%d\n", so, &faddr, fport, lport, so->so_hlport));
if ( so->so_faddr.s_addr == faddr.s_addr
&& so->so_fport == fport
&& so->so_hlport == lport)
@@ -294,11 +294,16 @@ icmp_find_original_mbuf(PNATState pData, struct ip *ip)
* better add flag if it should removed from lis
*/
LIST_INSERT_HEAD(&pData->icmp_msg_head, icm, im_list);
+ LogFlowFunc(("LEAVE: icm:%p\n", icm));
return (icm);
}
if (found == 1)
+ {
+ LogFlowFunc(("LEAVE: icm:%p\n", icm));
return icm;
+ }
+ LogFlowFunc(("LEAVE: NULL\n"));
return NULL;
}
@@ -334,7 +339,7 @@ icmp_input(PNATState pData, struct mbuf *m, int hlen)
/* int code; */
- LogFlow(("icmp_input: m = %lx, m_len = %d\n", (long)m, m ? m->m_len : 0));
+ LogFlowFunc(("ENTER: m = %lx, m_len = %d\n", (long)m, m ? m->m_len : 0));
icmpstat.icps_received++;
@@ -536,7 +541,7 @@ done:
* ICMP fragmentation is illegal. All machines must accept 576 bytes in one
* packet. The maximum payload is 576-20(ip hdr)-8(icmp hdr)=548
*
- * @note This function will NOT free msrc!
+ * @note This function will free msrc!
*/
#define ICMP_MAXDATALEN (IP_MSS-28)
@@ -590,25 +595,15 @@ void icmp_error(PNATState pData, struct mbuf *msrc, u_char type, u_char code, in
new_m_size = sizeof(struct ip) + ICMP_MINLEN + msrc->m_len + ICMP_MAXDATALEN;
if (new_m_size < MSIZE)
- {
size = MCLBYTES;
- }
else if (new_m_size < MCLBYTES)
- {
size = MCLBYTES;
- }
else if(new_m_size < MJUM9BYTES)
- {
size = MJUM9BYTES;
- }
else if (new_m_size < MJUM16BYTES)
- {
size = MJUM16BYTES;
- }
else
- {
AssertMsgFailed(("Unsupported size"));
- }
m = m_getjcl(pData, M_NOWAIT, MT_HEADER, M_PKTHDR, size);
if (!m)
goto end_error;
@@ -677,16 +672,29 @@ void icmp_error(PNATState pData, struct mbuf *msrc, u_char type, u_char code, in
ip->ip_dst = ip->ip_src; /* ip adresses */
ip->ip_src = alias_addr;
+ /* returns pointer back. */
+ m->m_data -= hlen;
+ m->m_len += hlen;
(void) ip_output0(pData, (struct socket *)NULL, m, 1);
icmpstat.icps_reflect++;
+ /* clear source datagramm in positive branch */
+ m_freem(pData, msrc);
+ LogFlowFuncLeave();
return;
end_error_free_m:
m_freem(pData, m);
end_error:
+
+ /*
+ * clear source datagramm in case if some of requirement haven't been met.
+ */
+ if (!msrc)
+ m_freem(pData, msrc);
+
{
static bool fIcmpErrorReported;
if (!fIcmpErrorReported)
@@ -695,6 +703,7 @@ end_error:
fIcmpErrorReported = true;
}
}
+ LogFlowFuncLeave();
}
#undef ICMP_MAXDATALEN
@@ -709,6 +718,7 @@ icmp_reflect(PNATState pData, struct mbuf *m)
int hlen = ip->ip_hl << 2;
int optlen = hlen - sizeof(struct ip);
register struct icmp *icp;
+ LogFlowFunc(("ENTER: m:%p\n", m));
/*
* Send an icmp packet back to the ip level,
@@ -727,4 +737,5 @@ icmp_reflect(PNATState pData, struct mbuf *m)
(void) ip_output(pData, (struct socket *)NULL, m);
icmpstat.icps_reflect++;
+ LogFlowFuncLeave();
}
diff --git a/src/VBox/Devices/Network/slirp/ip_icmp.h b/src/VBox/Devices/Network/slirp/ip_icmp.h
index b165ba5b5..46bb2c8b9 100644
--- a/src/VBox/Devices/Network/slirp/ip_icmp.h
+++ b/src/VBox/Devices/Network/slirp/ip_icmp.h
@@ -1,4 +1,4 @@
-/* $Id: ip_icmp.h $ */
+/* $Id: ip_icmp.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - IP/ICMP handling (declarations/defines).
*/
diff --git a/src/VBox/Devices/Network/slirp/ip_input.c b/src/VBox/Devices/Network/slirp/ip_input.c
index b2def5875..27bc598ae 100644
--- a/src/VBox/Devices/Network/slirp/ip_input.c
+++ b/src/VBox/Devices/Network/slirp/ip_input.c
@@ -1,4 +1,4 @@
-/* $Id: ip_input.c $ */
+/* $Id: ip_input.c 37936 2011-07-14 03:54:41Z vboxsync $ */
/** @file
* NAT - IP input.
*/
@@ -110,9 +110,9 @@ ip_input(PNATState pData, struct mbuf *m)
STAM_PROFILE_START(&pData->StatIP_input, a);
- LogFlow(("ip_input: m = %lx\n", (long)m));
+ LogFlowFunc(("ENTER: m = %lx\n", (long)m));
ip = mtod(m, struct ip *);
- Log2(("ip_dst=%R[IP4](len:%d) m_len = %d\n", &ip->ip_dst, RT_N2H_U16(ip->ip_len), m->m_len));
+ Log2(("ip_dst=%RTnaipv4(len:%d) m_len = %d\n", ip->ip_dst, RT_N2H_U16(ip->ip_len), m->m_len));
ipstat.ips_total++;
{
@@ -130,8 +130,7 @@ ip_input(PNATState pData, struct mbuf *m)
if (mlen < sizeof(struct ip))
{
ipstat.ips_toosmall++;
- STAM_PROFILE_STOP(&pData->StatIP_input, a);
- return;
+ goto bad_free_m;
}
ip = mtod(m, struct ip *);
@@ -193,7 +192,7 @@ ip_input(PNATState pData, struct mbuf *m)
if (ip->ip_ttl==0 || ip->ip_ttl == 1)
{
icmp_error(pData, m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, "ttl");
- goto bad_free_m;
+ goto no_free_m;
}
ip->ip_ttl--;
@@ -209,10 +208,7 @@ ip_input(PNATState pData, struct mbuf *m)
{
m = ip_reass(pData, m);
if (m == NULL)
- {
- STAM_PROFILE_STOP(&pData->StatIP_input, a);
- return;
- }
+ goto no_free_m;
ip = mtod(m, struct ip *);
hlen = ip->ip_hl << 2;
}
@@ -238,14 +234,15 @@ ip_input(PNATState pData, struct mbuf *m)
ipstat.ips_noproto++;
m_freem(pData, m);
}
- STAM_PROFILE_STOP(&pData->StatIP_input, a);
- return;
+ goto no_free_m;
bad_free_m:
- Log2(("NAT: IP datagram to %R[IP4] with size(%d) claimed as bad\n",
- &ip->ip_dst, ip->ip_len));
+ Log2(("NAT: IP datagram to %RTnaipv4 with size(%d) claimed as bad\n",
+ ip->ip_dst, ip->ip_len));
m_freem(pData, m);
+no_free_m:
STAM_PROFILE_STOP(&pData->StatIP_input, a);
+ LogFlowFuncLeave();
return;
}
@@ -260,12 +257,14 @@ ip_reass(PNATState pData, struct mbuf* m)
u_short hash;
/* If maxnipq or maxfragsperpacket are 0, never accept fragments. */
+ LogFlowFunc(("ENTER: m:%p\n", m));
if ( maxnipq == 0
|| maxfragsperpacket == 0)
{
ipstat.ips_fragments++;
ipstat.ips_fragdropped++;
m_freem(pData, m);
+ LogFlowFunc(("LEAVE: NULL\n"));
return (NULL);
}
@@ -533,6 +532,7 @@ found:
m_fixhdr(m);
#endif
ipstat.ips_reassembled++;
+ LogFlowFunc(("LEAVE: %p\n", m));
return (m);
dropfrag:
@@ -542,6 +542,7 @@ dropfrag:
m_freem(pData, m);
done:
+ LogFlowFunc(("LEAVE: NULL\n"));
return NULL;
#undef GETIP
diff --git a/src/VBox/Devices/Network/slirp/ip_output.c b/src/VBox/Devices/Network/slirp/ip_output.c
index 41d7908b4..8c4f4f36c 100644
--- a/src/VBox/Devices/Network/slirp/ip_output.c
+++ b/src/VBox/Devices/Network/slirp/ip_output.c
@@ -1,4 +1,4 @@
-/* $Id: ip_output.c $ */
+/* $Id: ip_output.c 37936 2011-07-14 03:54:41Z vboxsync $ */
/** @file
* NAT - IP output.
*/
@@ -72,23 +72,32 @@ static const uint8_t broadcast_ethaddr[6] =
static int rt_lookup_in_cache(PNATState pData, uint32_t dst, uint8_t *ether)
{
int rc;
+ LogFlowFunc(("ENTER: dst:%RTnaipv4, ether:%p\n", dst, ether));
if (dst == INADDR_BROADCAST)
{
memcpy(ether, broadcast_ethaddr, ETH_ALEN);
+ LogFlowFunc(("LEAVE: VINF_SUCCESS\n"));
return VINF_SUCCESS;
}
rc = slirp_arp_lookup_ether_by_ip(pData, dst, ether);
if (RT_SUCCESS(rc))
+ {
+ LogFlowFunc(("LEAVE: %Rrc\n", rc));
return rc;
+ }
rc = bootp_cache_lookup_ether_by_ip(pData, dst, ether);
if (RT_SUCCESS(rc))
+ {
+ LogFlowFunc(("LEAVE: %Rrc\n", rc));
return rc;
+ }
/*
* no chance to send this packet, sorry, we will request ether address via ARP
*/
slirp_arp_who_has(pData, dst);
+ LogFlowFunc(("LEAVE: VERR_NOT_FOUND\n"));
return VERR_NOT_FOUND;
}
@@ -119,7 +128,7 @@ ip_output0(PNATState pData, struct socket *so, struct mbuf *m0, int urg)
STAM_PROFILE_START(&pData->StatIP_output, a);
- LogFlow(("ip_output: so = %lx, m0 = %lx\n", (long)so, (long)m0));
+ LogFlowFunc(("ip_output: so = %R[natsock], m0 = %lx\n", so, (long)m0));
M_ASSERTPKTHDR(m);
Assert(m->m_pkthdr.header);
@@ -280,27 +289,34 @@ ip_output0(PNATState pData, struct socket *so, struct mbuf *m0, int urg)
ip->ip_sum = cksum(m, mhlen);
send_or_free:
+ {
+ /* @todo: We can't alias all fragments because the way libalias processing
+ * the fragments brake the sequence. libalias put alias_address to the source
+ * address of IP header of fragment, while IP header of the first packet is
+ * is unmodified. That confuses guest's TCP/IP stack and guest drop the sequence.
+ * Here we're letting libalias to process the first packet and send the rest as is,
+ * it's exactly the way in of packet are processing in proxyonly way.
+ * Here we need investigate what should be done to avoid such behavior and find right
+ * solution.
+ */
+ struct m_tag *t;
+ int rcLa;
+ if ((t = m_tag_find(m, PACKET_TAG_ALIAS, NULL)) != 0)
+ rcLa = LibAliasOut((struct libalias *)&t[1], mtod(m, char *), m->m_len);
+ else
+ rcLa = LibAliasOut(pData->proxy_alias, mtod(m, char *), m->m_len);
+
+ if (rcLa == PKT_ALIAS_IGNORED)
+ {
+ Log(("NAT: packet was droppped\n"));
+ goto exit_drop_package;
+ }
+ Log2(("NAT: LibAlias return %d\n", rcLa));
+ }
for (m = m0; m; m = m0)
{
m0 = m->m_nextpkt;
m->m_nextpkt = 0;
- {
- /* We're aliasing all fragments */
- struct m_tag *t;
- int rcLa;
-
- if ((t = m_tag_find(m, PACKET_TAG_ALIAS, NULL)) != 0)
- rcLa = LibAliasOut((struct libalias *)&t[1], mtod(m, char *), m->m_len);
- else
- rcLa = LibAliasOut(pData->proxy_alias, mtod(m, char *), m->m_len);
-
- if (rcLa == PKT_ALIAS_IGNORED)
- {
- Log(("NAT: packet was droppped\n"));
- goto exit_drop_package;
- }
- Log2(("NAT: LibAlias return %d\n", rcLa));
- }
if (error == 0)
{
m->m_data -= ETH_HLEN;
@@ -321,10 +337,12 @@ send_or_free:
done:
STAM_PROFILE_STOP(&pData->StatIP_output, a);
+ LogFlowFunc(("LEAVE: %d\n", error));
return error;
exit_drop_package:
m_freem(pData, m0);
STAM_PROFILE_STOP(&pData->StatIP_output, a);
+ LogFlowFunc(("LEAVE: %d\n", error));
return error;
}
diff --git a/src/VBox/Devices/Network/slirp/libalias/alias_dns.c b/src/VBox/Devices/Network/slirp/libalias/alias_dns.c
index fb263264f..fe6bd0c68 100644
--- a/src/VBox/Devices/Network/slirp/libalias/alias_dns.c
+++ b/src/VBox/Devices/Network/slirp/libalias/alias_dns.c
@@ -1,4 +1,4 @@
-/* $Id: alias_dns.c $ */
+/* $Id: alias_dns.c 37746 2011-07-04 06:07:37Z vboxsync $ */
/** @file
* libalias helper for using the host resolver instead of dnsproxy.
*/
@@ -78,9 +78,9 @@ fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
if (!ah->dport || !ah->sport || !ah->lnk)
return -1;
- Log(("NAT:%s: ah(dport: %hd, sport: %hd) oaddr:%R[IP4] aaddr:%R[IP4]\n",
+ Log(("NAT:%s: ah(dport: %hd, sport: %hd) oaddr:%RTnaipv4 aaddr:%RTnaipv4\n",
__FUNCTION__, ntohs(*ah->dport), ntohs(*ah->sport),
- &ah->oaddr, &ah->aaddr));
+ ah->oaddr, ah->aaddr));
if ( (ntohs(*ah->dport) == DNS_CONTROL_PORT_NUMBER
|| ntohs(*ah->sport) == DNS_CONTROL_PORT_NUMBER)
diff --git a/src/VBox/Devices/Network/slirp/libslirp.h b/src/VBox/Devices/Network/slirp/libslirp.h
index 3ae68b46a..4830e3c5d 100644
--- a/src/VBox/Devices/Network/slirp/libslirp.h
+++ b/src/VBox/Devices/Network/slirp/libslirp.h
@@ -1,4 +1,4 @@
-/* $Id: libslirp.h $ */
+/* $Id: libslirp.h 35922 2011-02-09 20:04:14Z vboxsync $ */
/** @file
* NAT - slirp interface.
*/
@@ -69,6 +69,7 @@ void slirp_set_ethaddr_and_activate_port_forwarding(PNATState pData, const uint8
void slirp_arm_fast_timer(void *pvUser);
int slirp_can_output(void * pvUser);
void slirp_output(void * pvUser, struct mbuf *m, const uint8_t *pkt, int pkt_len);
+void slirp_output_pending(void * pvUser);
void slirp_urg_output(void *pvUser, struct mbuf *, const uint8_t *pu8Buf, int cb);
void slirp_post_sent(PNATState pData, void *pvArg);
diff --git a/src/VBox/Devices/Network/slirp/main.h b/src/VBox/Devices/Network/slirp/main.h
index 52f292462..e1f72a91b 100644
--- a/src/VBox/Devices/Network/slirp/main.h
+++ b/src/VBox/Devices/Network/slirp/main.h
@@ -1,4 +1,4 @@
-/* $Id: main.h $ */
+/* $Id: main.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - main.
*/
diff --git a/src/VBox/Devices/Network/slirp/misc.c b/src/VBox/Devices/Network/slirp/misc.c
index bd7a5a6c1..dc55472fa 100644
--- a/src/VBox/Devices/Network/slirp/misc.c
+++ b/src/VBox/Devices/Network/slirp/misc.c
@@ -1,4 +1,4 @@
-/* $Id: misc.c $ */
+/* $Id: misc.c 35957 2011-02-14 12:27:21Z vboxsync $ */
/** @file
* NAT - helpers.
*/
@@ -125,9 +125,36 @@ struct uma_zone
LIST_HEAD(RT_NOTHING, item) free_items;
uma_zone_t master_zone;
void *area;
+ /** Needs call pfnXmitPending when memory becomes available if @c true.
+ * @remarks Only applies to the master zone (master_zone == NULL) */
+ bool fDoXmitPending;
};
+/**
+ * Called when memory becomes available, works pfnXmitPending.
+ *
+ * @note This will LEAVE the critical section of the zone and RE-ENTER it
+ * again. Changes to the zone data should be expected across calls to
+ * this function!
+ *
+ * @param zone The zone.
+ */
+DECLINLINE(void) slirp_zone_check_and_send_pending(uma_zone_t zone)
+{
+ if ( zone->fDoXmitPending
+ && zone->master_zone == NULL)
+ {
+ int rc2;
+ zone->fDoXmitPending = false;
+ rc2 = RTCritSectLeave(&zone->csZone); AssertRC(rc2);
+
+ slirp_output_pending(zone->pData->pvUser);
+
+ rc2 = RTCritSectEnter(&zone->csZone); AssertRC(rc2);
+ }
+}
+
static void *slirp_uma_alloc(uma_zone_t zone,
int size, uint8_t *pflags, int fWait)
{
@@ -151,10 +178,12 @@ static void *slirp_uma_alloc(uma_zone_t zone,
zone->cur_items++;
LIST_REMOVE(it, list);
LIST_INSERT_HEAD(&zone->used_items, it, list);
+ slirp_zone_check_and_send_pending(zone); /* may exit+enter the cs! */
ret = (void *)&it[1];
}
else
{
+ AssertMsgFailed(("NAT: item initialization failed for zone %s\n", zone->name));
ret = NULL;
}
break;
@@ -162,13 +191,15 @@ static void *slirp_uma_alloc(uma_zone_t zone,
if (!zone->master_zone)
{
- /* We're on master zone and we cant allocate more */
+ /* We're on the master zone and we can't allocate more. */
Log2(("NAT: no room on %s zone\n", zone->name));
+ /* AssertMsgFailed(("NAT: OOM!")); */
+ zone->fDoXmitPending = true;
break;
}
- /* we're on sub-zone we need get chunk of master zone and split
- * it for sub-zone conforming chunks.
+ /* we're on a sub-zone, we need get a chunk from the master zone and split
+ * it into sub-zone conforming chunks.
*/
sub_area = slirp_uma_alloc(zone->master_zone, zone->master_zone->size, NULL, 0);
if (!sub_area)
@@ -179,15 +210,16 @@ static void *slirp_uma_alloc(uma_zone_t zone,
}
zone->max_items++;
it = &((struct item *)sub_area)[-1];
- /* it's chunk descriptor of master zone we should remove it
- * from the master list first
+ /* It's the chunk descriptor of the master zone, we should remove it
+ * from the master list first.
*/
Assert((it->zone && it->zone->magic == ZONE_MAGIC));
RTCritSectEnter(&it->zone->csZone);
- /* @todo should we alter count of master counters? */
+ /** @todo should we alter count of master counters? */
LIST_REMOVE(it, list);
RTCritSectLeave(&it->zone->csZone);
- /* @todo '+ zone->size' should be depend on flag */
+
+ /** @todo '+ zone->size' should be depend on flag */
memset(it, 0, sizeof(struct item));
it->zone = zone;
it->magic = ITEM_MAGIC;
@@ -204,12 +236,14 @@ static void slirp_uma_free(void *item, int size, uint8_t flags)
struct item *it;
uma_zone_t zone;
uma_zone_t master_zone;
+
Assert(item);
it = &((struct item *)item)[-1];
Assert(it->magic == ITEM_MAGIC);
zone = it->zone;
- /* check bourder magic */
+ /* check border magic */
Assert((*(uint32_t *)(((uint8_t *)&it[1]) + zone->size) == 0xabadbabe));
+
RTCritSectEnter(&zone->csZone);
Assert(zone->magic == ZONE_MAGIC);
LIST_REMOVE(it, list);
@@ -223,6 +257,7 @@ static void slirp_uma_free(void *item, int size, uint8_t flags)
}
LIST_INSERT_HEAD(&zone->free_items, it, list);
zone->cur_items--;
+ slirp_zone_check_and_send_pending(zone); /* may exit+enter the cs! */
RTCritSectLeave(&zone->csZone);
}
@@ -299,7 +334,7 @@ void uma_zone_set_freef(uma_zone_t zone, uma_free_t pfFree)
uint32_t *uma_find_refcnt(uma_zone_t zone, void *mem)
{
- /*@todo (vvl) this function supposed to work with special zone storing
+ /** @todo (vvl) this function supposed to work with special zone storing
reference counters */
struct item *it = (struct item *)mem; /* 1st element */
Assert(mem != NULL);
@@ -360,28 +395,33 @@ void zone_drain(uma_zone_t zone)
{
struct item *it;
uma_zone_t master_zone;
+
/* vvl: Huh? What to do with zone which hasn't got backstore ? */
Assert((zone->master_zone));
master_zone = zone->master_zone;
- while(!LIST_EMPTY(&zone->free_items))
+ while (!LIST_EMPTY(&zone->free_items))
{
it = LIST_FIRST(&zone->free_items);
Assert((it->magic == ITEM_MAGIC));
+
RTCritSectEnter(&zone->csZone);
LIST_REMOVE(it, list);
zone->max_items--;
RTCritSectLeave(&zone->csZone);
+
it->zone = master_zone;
+
RTCritSectEnter(&master_zone->csZone);
LIST_INSERT_HEAD(&master_zone->free_items, it, list);
master_zone->cur_items--;
+ slirp_zone_check_and_send_pending(master_zone); /* may exit+enter the cs! */
RTCritSectLeave(&master_zone->csZone);
}
}
void slirp_null_arg_free(void *mem, void *arg)
{
- /*@todo (r=vvl) make it wiser*/
+ /** @todo (vvl) make it wiser */
Assert(mem);
RTMemFree(mem);
}
@@ -447,7 +487,7 @@ void m_fini(PNATState pData)
zone_destroy(pData->zone_jumbop);
zone_destroy(pData->zone_jumbo9);
zone_destroy(pData->zone_jumbo16);
- /*@todo do finalize here.*/
+ /** @todo do finalize here.*/
}
void
diff --git a/src/VBox/Devices/Network/slirp/misc.h b/src/VBox/Devices/Network/slirp/misc.h
index 2d5b8d2f5..95d464f19 100644
--- a/src/VBox/Devices/Network/slirp/misc.h
+++ b/src/VBox/Devices/Network/slirp/misc.h
@@ -1,4 +1,4 @@
-/* $Id: misc.h $ */
+/* $Id: misc.h 30016 2010-06-03 18:31:14Z vboxsync $ */
/** @file
* NAT - helpers (declarations/defines).
*/
diff --git a/src/VBox/Devices/Network/slirp/queue.h b/src/VBox/Devices/Network/slirp/queue.h
index 20535faba..7f99f7a31 100644
--- a/src/VBox/Devices/Network/slirp/queue.h
+++ b/src/VBox/Devices/Network/slirp/queue.h
@@ -1,4 +1,4 @@
-/* $Id: queue.h $ */
+/* $Id: queue.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - Queue handling.
*/
diff --git a/src/VBox/Devices/Network/slirp/sbuf.c b/src/VBox/Devices/Network/slirp/sbuf.c
index ee2cca3cf..41a8d0be9 100644
--- a/src/VBox/Devices/Network/slirp/sbuf.c
+++ b/src/VBox/Devices/Network/slirp/sbuf.c
@@ -1,4 +1,4 @@
-/* $Id: sbuf.c $ */
+/* $Id: sbuf.c 37936 2011-07-14 03:54:41Z vboxsync $ */
/** @file
* NAT - sbuf implemenation.
*/
@@ -283,7 +283,7 @@ sbappend (PNATState pData, struct socket *so, struct mbuf *m)
caddr_t buf = NULL;
STAM_PROFILE_START(&pData->StatIOSBAppend_pf, a);
- LogFlow(("sbappend: so = %lx, m = %lx, m->m_len = %d\n", (long)so, (long)m, m ? m->m_len : 0));
+ LogFlow(("sbappend: so = %R[natsock], m = %lx, m->m_len = %d\n", so, (long)m, m ? m->m_len : 0));
STAM_COUNTER_INC(&pData->StatIOSBAppend);
mlen = m_length(m, NULL);
diff --git a/src/VBox/Devices/Network/slirp/sbuf.h b/src/VBox/Devices/Network/slirp/sbuf.h
index 9035d3371..178c72eb1 100644
--- a/src/VBox/Devices/Network/slirp/sbuf.h
+++ b/src/VBox/Devices/Network/slirp/sbuf.h
@@ -1,4 +1,4 @@
-/* $Id: sbuf.h $ */
+/* $Id: sbuf.h 30045 2010-06-04 20:38:56Z vboxsync $ */
/** @file
* NAT - sbuf declarations/defines.
*/
diff --git a/src/VBox/Devices/Network/slirp/slirp.c b/src/VBox/Devices/Network/slirp/slirp.c
index a33a8fee4..ba23db977 100644
--- a/src/VBox/Devices/Network/slirp/slirp.c
+++ b/src/VBox/Devices/Network/slirp/slirp.c
@@ -1,4 +1,4 @@
-/* $Id: slirp.c $ */
+/* $Id: slirp.c 38044 2011-07-19 04:52:49Z vboxsync $ */
/** @file
* NAT - slirp glue.
*/
@@ -182,6 +182,8 @@
# define xfds_win_bit FD_OOB_BIT
# define closefds_win FD_CLOSE
# define closefds_win_bit FD_CLOSE_BIT
+# define connectfds_win FD_CONNECT
+# define connectfds_win_bit FD_CONNECT_BIT
# define closefds_win FD_CLOSE
# define closefds_win_bit FD_CLOSE_BIT
@@ -200,6 +202,12 @@
#define TCP_ENGAGE_EVENT2(so, fdset1, fdset2) \
DO_ENGAGE_EVENT2((so), fdset1, fdset2, tcp)
+#ifdef RT_OS_WINDOWS
+# define WIN_TCP_ENGAGE_EVENT2(so, fdset, fdset2) TCP_ENGAGE_EVENT2(so, fdset1, fdset2)
+#else
+# define WIN_TCP_ENGAGE_EVENT2(so, fdset, fdset2) do{}while(0)
+#endif
+
#define UDP_ENGAGE_EVENT(so, fdset) \
DO_ENGAGE_EVENT1((so), fdset, udp)
@@ -334,7 +342,7 @@ static int get_dns_addr_domain(PNATState pData, bool fVerbose,
return VERR_NO_MEMORY;
}
- Log(("NAT: adding %R[IP4] to DNS server list\n", &InAddr));
+ Log(("NAT: adding %RTnaipv4 to DNS server list\n", InAddr));
if ((InAddr.s_addr & RT_H2N_U32_C(IN_CLASSA_NET)) == RT_N2H_U32_C(INADDR_LOOPBACK & IN_CLASSA_NET))
pDns->de_addr.s_addr = RT_H2N_U32(RT_N2H_U32(pData->special_addr.s_addr) | CTL_ALIAS);
else
@@ -579,7 +587,7 @@ int slirp_init(PNATState *ppData, uint32_t u32NetAddr, uint32_t u32Netmask,
{
int fNATfailed = 0;
int rc;
- PNATState pData = RTMemAllocZ(sizeof(NATState));
+ PNATState pData = RTMemAllocZ(RT_ALIGN_Z(sizeof(NATState), sizeof(uint64_t)));
*ppData = pData;
if (!pData)
return VERR_NO_MEMORY;
@@ -932,7 +940,15 @@ void slirp_select_fill(PNATState pData, int *pnfds, struct pollfd *polls)
{
Log2(("connecting %R[natsock] engaged\n",so));
STAM_COUNTER_INC(&pData->StatTCPHot);
+#ifndef NAT_CONNECT_EXPERIMENT
+ TCP_ENGAGE_EVENT1(so, writefds);
+#else
+# ifdef RT_OS_WINDOWS
+ WIN_TCP_ENGAGE_EVENT2(so, writefds, connectfds);
+# else
TCP_ENGAGE_EVENT1(so, writefds);
+# endif
+#endif
}
/*
@@ -991,10 +1007,6 @@ void slirp_select_fill(PNATState pData, int *pnfds, struct pollfd *polls)
UDP_DETACH(pData, so, so_next);
CONTINUE_NO_UNLOCK(udp);
}
- else
- {
- do_slowtimo = 1; /* Let socket expire */
- }
}
/*
@@ -1151,6 +1163,14 @@ void slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs)
*/
&& !CHECK_FD_SET(so, NetworkEvents, closefds)
#endif
+#ifdef NAT_CONNECT_EXPERIMENT
+# ifdef RT_OS_WINDOWS
+ /**
+ * In some cases FD_CONNECT comes with FD_OOB, that confuse tcp processing.
+ */
+ && !WIN_CHECK_FD_SET(so, NetworkEvents, connectfds)
+# endif
+#endif
)
{
sorecvoob(pData, so);
@@ -1162,6 +1182,9 @@ void slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs)
else if ( CHECK_FD_SET(so, NetworkEvents, readfds)
|| WIN_CHECK_FD_SET(so, NetworkEvents, acceptds))
{
+#ifdef DEBUG_vvl
+ Assert(((so->so_state & SS_ISFCONNECTING) == 0));
+#endif
/*
* Check for incoming connections
*/
@@ -1213,7 +1236,11 @@ void slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs)
/*
* Check sockets for writing
*/
- if (CHECK_FD_SET(so, NetworkEvents, writefds))
+ if ( CHECK_FD_SET(so, NetworkEvents, writefds)
+#if defined(NAT_CONNECT_EXPERIMENT)
+ || WIN_CHECK_FD_SET(so, NetworkEvents, connectfds)
+#endif
+ )
{
/*
* Check for non-blocking, still-connecting sockets
@@ -1473,7 +1500,7 @@ static void arp_input(PNATState pData, struct mbuf *m)
static bool fGratuitousArpReported;
if (!fGratuitousArpReported)
{
- LogRel(("NAT: Gratuitous ARP [IP:%R[IP4], ether:%R[ether]]\n",
+ LogRel(("NAT: Gratuitous ARP [IP:%RTnaipv4, ether:%RTmac]\n",
ah->ar_sip, ah->ar_sha));
fGratuitousArpReported = true;
}
@@ -1689,8 +1716,8 @@ static void activate_port_forwarding(PNATState pData, const uint8_t *h_source)
rule->guest_addr.s_addr = guest_addr;
#endif
- LogRel(("NAT: set redirect %s host port %d => guest port %d @ %R[IP4]\n",
- rule->proto == IPPROTO_UDP ? "UDP" : "TCP", rule->host_port, rule->guest_port, &guest_addr));
+ LogRel(("NAT: set redirect %s host port %d => guest port %d @ %RTnaipv4\n",
+ rule->proto == IPPROTO_UDP ? "UDP" : "TCP", rule->host_port, rule->guest_port, guest_addr));
if (rule->proto == IPPROTO_UDP)
so = udp_listen(pData, rule->bind_ip.s_addr, RT_H2N_U16(rule->host_port), guest_addr,
@@ -1766,9 +1793,7 @@ int slirp_add_redirect(PNATState pData, int is_udp, struct in_addr host_addr, in
&& rule->host_port == host_port
&& rule->bind_ip.s_addr == host_addr.s_addr
&& rule->guest_port == guest_port
-#ifndef VBOX_WITH_NAT_SERVICE
&& rule->guest_addr.s_addr == guest_addr.s_addr
-#endif
)
return 0; /* rule has been already registered */
}
@@ -1780,9 +1805,7 @@ int slirp_add_redirect(PNATState pData, int is_udp, struct in_addr host_addr, in
rule->proto = (is_udp ? IPPROTO_UDP : IPPROTO_TCP);
rule->host_port = host_port;
rule->guest_port = guest_port;
-#ifndef VBOX_WITH_NAT_SERVICE
rule->guest_addr.s_addr = guest_addr.s_addr;
-#endif
rule->bind_ip.s_addr = host_addr.s_addr;
memcpy(rule->mac_address, ethaddr, ETH_ALEN);
/* @todo add mac address */
@@ -1804,13 +1827,11 @@ int slirp_remove_redirect(PNATState pData, int is_udp, struct in_addr host_addr,
&& rule->host_port == host_port
&& rule->guest_port == guest_port
&& rule->bind_ip.s_addr == host_addr.s_addr
-#ifndef VBOX_WITH_NAT_SERVICE
&& rule->guest_addr.s_addr == guest_addr.s_addr
-#endif
&& rule->activated)
{
- LogRel(("NAT: remove redirect %s host port %d => guest port %d @ %R[IP4]\n",
- rule->proto == IPPROTO_UDP ? "UDP" : "TCP", rule->host_port, rule->guest_port, &guest_addr));
+ LogRel(("NAT: remove redirect %s host port %d => guest port %d @ %RTnaipv4\n",
+ rule->proto == IPPROTO_UDP ? "UDP" : "TCP", rule->host_port, rule->guest_port, guest_addr));
LibAliasUninit(rule->so->so_la);
if (is_udp)
@@ -2104,8 +2125,8 @@ int slirp_arp_cache_update_or_add(PNATState pData, uint32_t dst, const uint8_t *
static bool fBroadcastEtherAddReported;
if (!fBroadcastEtherAddReported)
{
- LogRel(("NAT: Attempt to add pair [%R[ether]:%R[IP4]] in ARP cache was ignored\n",
- mac, &dst));
+ LogRel(("NAT: Attempt to add pair [%RTmac:%RTnaipv4] in ARP cache was ignored\n",
+ mac, dst));
fBroadcastEtherAddReported = true;
}
return 1;
@@ -2154,15 +2175,15 @@ void slirp_info(PNATState pData, PCDBGFINFOHLP pHlp, const char *pszArgs)
pHlp->pfnPrintf(pHlp, "NAT ARP cache:\n");
LIST_FOREACH(ac, &pData->arp_cache, list)
{
- pHlp->pfnPrintf(pHlp, " %R[IP4] %R[ether]\n", &ac->ip, &ac->ether);
+ pHlp->pfnPrintf(pHlp, " %RTnaipv4 %RTmac\n", ac->ip, &ac->ether);
}
pHlp->pfnPrintf(pHlp, "NAT rules:\n");
LIST_FOREACH(rule, &pData->port_forward_rule_head, list)
{
- pHlp->pfnPrintf(pHlp, " %s %d => %R[IP4]:%d %c\n",
+ pHlp->pfnPrintf(pHlp, " %s %d => %RTnaipv4:%d %c\n",
rule->proto == IPPROTO_UDP ? "UDP" : "TCP",
- rule->host_port, &rule->guest_addr.s_addr, rule->guest_port,
+ rule->host_port, rule->guest_addr.s_addr, rule->guest_port,
rule->activated ? ' ' : '*');
}
}
diff --git a/src/VBox/Devices/Network/slirp/slirp.h b/src/VBox/Devices/Network/slirp/slirp.h
index 26ff00790..e8c82b864 100644
--- a/src/VBox/Devices/Network/slirp/slirp.h
+++ b/src/VBox/Devices/Network/slirp/slirp.h
@@ -1,4 +1,4 @@
-/* $Id: slirp.h $ */
+/* $Id: slirp.h 36901 2011-04-29 18:03:48Z vboxsync $ */
/** @file
* NAT - slirp (declarations/defines).
*/
diff --git a/src/VBox/Devices/Network/slirp/slirp_config.h b/src/VBox/Devices/Network/slirp/slirp_config.h
index 481bc87db..390eed449 100644
--- a/src/VBox/Devices/Network/slirp/slirp_config.h
+++ b/src/VBox/Devices/Network/slirp/slirp_config.h
@@ -1,4 +1,4 @@
-/* $Id: slirp_config.h $ */
+/* $Id: slirp_config.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - compile-time configuration.
*/
diff --git a/src/VBox/Devices/Network/slirp/slirp_state.h b/src/VBox/Devices/Network/slirp/slirp_state.h
index 3c18219d8..d6b0ec7a4 100644
--- a/src/VBox/Devices/Network/slirp/slirp_state.h
+++ b/src/VBox/Devices/Network/slirp/slirp_state.h
@@ -78,9 +78,7 @@ struct port_forward_rule
uint16_t proto;
uint16_t host_port;
uint16_t guest_port;
-#ifndef VBOX_WITH_NAT_SERVICE
struct in_addr guest_addr;
-#endif
struct in_addr bind_ip;
uint8_t mac_address[6]; /*need ETH_ALEN here */
int activated;
diff --git a/src/VBox/Devices/Network/slirp/socket.c b/src/VBox/Devices/Network/slirp/socket.c
index 91cdebbc3..05ff7045d 100644
--- a/src/VBox/Devices/Network/slirp/socket.c
+++ b/src/VBox/Devices/Network/slirp/socket.c
@@ -1,4 +1,4 @@
-/* $Id: socket.c $ */
+/* $Id: socket.c 38057 2011-07-19 09:17:18Z vboxsync $ */
/** @file
* NAT - socket handling.
*/
@@ -151,7 +151,8 @@ soread(PNATState pData, struct socket *so)
SOCKET_LOCK(so);
QSOCKET_UNLOCK(tcb);
- LogFlow(("soread: so = %lx\n", (long)so));
+ LogFlow(("soread: so = %R[natsock]\n", so));
+ Log2(("%s: so = %R[natsock] so->so_snd = %R[sbuf]\n", __PRETTY_FUNCTION__, so, sb));
/*
* No need to check if there's enough room to read.
@@ -215,10 +216,11 @@ soread(PNATState pData, struct socket *so)
#ifdef HAVE_READV
nn = readv(so->s, (struct iovec *)iov, n);
- Log2((" ... read nn = %d bytes\n", nn));
#else
nn = recv(so->s, iov[0].iov_base, iov[0].iov_len, (so->so_tcpcb->t_force? MSG_OOB:0));
#endif
+ Log2(("%s: read(1) nn = %d bytes\n", __PRETTY_FUNCTION__, nn));
+ Log2(("%s: so = %R[natsock] so->so_snd = %R[sbuf]\n", __PRETTY_FUNCTION__, so, sb));
if (nn <= 0)
{
/*
@@ -232,7 +234,7 @@ soread(PNATState pData, struct socket *so)
unsigned long pending = 0;
status = ioctlsocket(so->s, FIONREAD, &pending);
if (status < 0)
- Log(("NAT:error in WSAIoctl: %d\n", errno));
+ Log(("NAT:%s: error in WSAIoctl: %d\n", __PRETTY_FUNCTION__, errno));
if (nn == 0 && (pending != 0))
{
SOCKET_UNLOCK(so);
@@ -251,8 +253,8 @@ soread(PNATState pData, struct socket *so)
else
{
/* nn == 0 means peer has performed an orderly shutdown */
- Log2((" --- soread() disconnected, nn = %d, errno = %d (%s)\n",
- nn, errno, strerror(errno)));
+ Log2(("%s: disconnected, nn = %d, errno = %d (%s)\n",
+ __PRETTY_FUNCTION__, nn, errno, strerror(errno)));
sofcantrcvmore(so);
tcp_sockclosed(pData, sototcpcb(so));
SOCKET_UNLOCK(so);
@@ -298,14 +300,18 @@ soread(PNATState pData, struct socket *so)
);
}
- Log2((" ... read nn = %d bytes\n", nn));
+ Log2(("%s: read(2) nn = %d bytes\n", __PRETTY_FUNCTION__, nn));
#endif
/* Update fields */
sb->sb_cc += nn;
sb->sb_wptr += nn;
+ Log2(("%s: update so_snd (readed nn = %d) %R[sbuf]\n", __PRETTY_FUNCTION__, nn, sb));
if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
+ {
sb->sb_wptr -= sb->sb_datalen;
+ Log2(("%s: alter sb_wptr so_snd = %R[sbuf]\n", __PRETTY_FUNCTION__, sb));
+ }
STAM_PROFILE_STOP(&pData->StatIOread, a);
SOCKET_UNLOCK(so);
return nn;
@@ -328,7 +334,7 @@ soread(PNATState pData, struct socket *so)
SOCKET_LOCK(so);
QSOCKET_UNLOCK(tcb);
- LogFlow(("soread: so = %lx\n", (long)so));
+ LogFlowFunc(("soread: so = %lx\n", (long)so));
if (len > mss)
len -= len % mss;
@@ -403,7 +409,7 @@ sorecvoob(PNATState pData, struct socket *so)
struct tcpcb *tp = sototcpcb(so);
ssize_t ret;
- LogFlow(("sorecvoob: so = %lx\n", (long)so));
+ LogFlowFunc(("sorecvoob: so = %R[natsock]\n", so));
/*
* We take a guess at how much urgent data has arrived.
@@ -432,7 +438,7 @@ sosendoob(struct socket *so)
int n, len;
- LogFlow(("sosendoob so = %lx\n", (long)so));
+ LogFlowFunc(("sosendoob so = %R[natsock]\n", so));
if (so->so_urgc > sizeof(buff))
so->so_urgc = sizeof(buff); /* XXX */
@@ -505,7 +511,8 @@ sowrite(PNATState pData, struct socket *so)
STAM_COUNTER_RESET(&pData->StatIOWrite_no_w);
STAM_COUNTER_RESET(&pData->StatIOWrite_rest);
STAM_COUNTER_RESET(&pData->StatIOWrite_rest_bytes);
- LogFlow(("sowrite: so = %lx\n", (long)so));
+ LogFlowFunc(("so = %R[natsock]\n", so));
+ Log2(("%s: so = %R[natsock] so->so_rcv = %R[sbuf]\n", __PRETTY_FUNCTION__, so, sb));
QSOCKET_LOCK(tcb);
SOCKET_LOCK(so);
QSOCKET_UNLOCK(tcb);
@@ -571,10 +578,10 @@ sowrite(PNATState pData, struct socket *so)
/* Check if there's urgent data to send, and if so, send it */
#ifdef HAVE_READV
nn = writev(so->s, (const struct iovec *)iov, n);
- Log2((" ... wrote nn = %d bytes\n", nn));
#else
nn = send(so->s, iov[0].iov_base, iov[0].iov_len, 0);
#endif
+ Log2(("%s: wrote(1) nn = %d bytes\n", __PRETTY_FUNCTION__, nn));
/* This should never happen, but people tell me it does *shrug* */
if ( nn < 0
&& ( errno == EAGAIN
@@ -588,8 +595,8 @@ sowrite(PNATState pData, struct socket *so)
if (nn < 0 || (nn == 0 && iov[0].iov_len > 0))
{
- Log2((" --- sowrite disconnected, so->so_state = %x, errno = %d\n",
- so->so_state, errno));
+ Log2(("%s: disconnected, so->so_state = %x, errno = %d\n",
+ __PRETTY_FUNCTION__, so->so_state, errno));
sofcantsendmore(so);
tcp_sockclosed(pData, sototcpcb(so));
SOCKET_UNLOCK(so);
@@ -612,14 +619,18 @@ sowrite(PNATState pData, struct socket *so)
}
});
}
- Log2((" ... wrote nn = %d bytes\n", nn));
+ Log2(("%s: wrote(2) nn = %d bytes\n", __PRETTY_FUNCTION__, nn));
#endif
/* Update sbuf */
sb->sb_cc -= nn;
sb->sb_rptr += nn;
+ Log2(("%s: update so_rcv (written nn = %d) %R[sbuf]\n", __PRETTY_FUNCTION__, nn, sb));
if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
+ {
sb->sb_rptr -= sb->sb_datalen;
+ Log2(("%s: alter sb_rptr of so_rcv %R[sbuf]\n", __PRETTY_FUNCTION__, sb));
+ }
/*
* If in DRAIN mode, and there's no more data, set
@@ -640,7 +651,7 @@ do_sosend(struct socket *so, int fUrg)
int n, len;
- LogFlow(("sosendoob: so = %lx\n", (long)so));
+ LogFlowFunc(("sosendoob: so = %R[natsock]\n", so));
len = sbuf_len(sb);
@@ -695,7 +706,7 @@ sorecvfrom(PNATState pData, struct socket *so)
struct sockaddr_in addr;
socklen_t addrlen = sizeof(struct sockaddr_in);
- LogFlow(("sorecvfrom: so = %lx\n", (long)so));
+ LogFlowFunc(("sorecvfrom: so = %lx\n", (long)so));
if (so->so_type == IPPROTO_ICMP)
{
@@ -814,7 +825,6 @@ sorecvfrom(PNATState pData, struct socket *so)
Log2((" rx error, tx icmp ICMP_UNREACH:%i\n", code));
icmp_error(pData, so->so_m, ICMP_UNREACH, code, 0, strerror(errno));
- m_freem(pData, so->so_m);
so->so_m = NULL;
}
else
@@ -869,10 +879,10 @@ sosendto(PNATState pData, struct socket *so, struct mbuf *m)
#if 0
struct sockaddr_in host_addr;
#endif
- caddr_t buf;
+ caddr_t buf = 0;
int mlen;
- LogFlow(("sosendto: so = %lx, m = %lx\n", (long)so, (long)m));
+ LogFlowFunc(("sosendto: so = %R[natsock], m = %lx\n", so, (long)m));
memset(&addr, 0, sizeof(struct sockaddr));
#ifdef RT_OS_DARWIN
@@ -920,16 +930,24 @@ sosendto(PNATState pData, struct socket *so, struct mbuf *m)
RT_N2H_U16(paddr->sin_port), inet_ntoa(paddr->sin_addr)));
/* Don't care what port we get */
+ /*
+ * > nmap -sV -T4 -O -A -v -PU3483 255.255.255.255
+ * generates bodyless messages, annoying memmory management system.
+ */
mlen = m_length(m, NULL);
- buf = RTMemAlloc(mlen);
- if (buf == NULL)
+ if (mlen > 0)
{
- return -1;
+ buf = RTMemAlloc(mlen);
+ if (buf == NULL)
+ {
+ return -1;
+ }
+ m_copydata(m, 0, mlen, buf);
}
- m_copydata(m, 0, mlen, buf);
ret = sendto(so->s, buf, mlen, 0,
(struct sockaddr *)&addr, sizeof (struct sockaddr));
- RTMemFree(buf);
+ if (buf)
+ RTMemFree(buf);
if (ret < 0)
{
Log2(("UDP: sendto fails (%s)\n", strerror(errno)));
@@ -958,7 +976,7 @@ solisten(PNATState pData, u_int32_t bind_addr, u_int port, u_int32_t laddr, u_in
int s, opt = 1;
int status;
- LogFlow(("solisten: port = %d, laddr = %x, lport = %d, flags = %x\n", port, laddr, lport, flags));
+ LogFlowFunc(("solisten: port = %d, laddr = %x, lport = %d, flags = %x\n", port, laddr, lport, flags));
if ((so = socreate()) == NULL)
{
@@ -1359,7 +1377,6 @@ sorecvfrom_icmp_win(PNATState pData, struct socket *so)
case IP_DEST_PORT_UNREACHABLE:
code = (code != ~0 ? code : ICMP_UNREACH_PORT);
icmp_error(pData, so->so_m, ICMP_UNREACH, code, 0, "Error occurred!!!");
- m_freem(pData, so->so_m);
so->so_m = NULL;
break;
case IP_SUCCESS: /* echo replied */
@@ -1478,7 +1495,6 @@ static void sorecvfrom_icmp_unix(PNATState pData, struct socket *so)
LogRel((" udp icmp rx errno = %d (%s)\n", errno, strerror(errno)));
icmp_error(pData, so->so_m, ICMP_UNREACH, code, 0, strerror(errno));
- m_freem(pData, so->so_m);
so->so_m = NULL;
Log(("sorecvfrom_icmp_unix: 1 - step can't read IP datagramm\n"));
return;
diff --git a/src/VBox/Devices/Network/slirp/socket.h b/src/VBox/Devices/Network/slirp/socket.h
index 15bea049f..3631ec4d5 100644
--- a/src/VBox/Devices/Network/slirp/socket.h
+++ b/src/VBox/Devices/Network/slirp/socket.h
@@ -1,4 +1,4 @@
-/* $Id: socket.h $ */
+/* $Id: socket.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - socket handling (declarations/defines).
*/
diff --git a/src/VBox/Devices/Network/slirp/tcp.h b/src/VBox/Devices/Network/slirp/tcp.h
index 71fb70dbc..d86772ffa 100644
--- a/src/VBox/Devices/Network/slirp/tcp.h
+++ b/src/VBox/Devices/Network/slirp/tcp.h
@@ -1,4 +1,4 @@
-/* $Id: tcp.h $ */
+/* $Id: tcp.h 30016 2010-06-03 18:31:14Z vboxsync $ */
/** @file
* NAT - TCP.
*/
diff --git a/src/VBox/Devices/Network/slirp/tcp_input.c b/src/VBox/Devices/Network/slirp/tcp_input.c
index 8dcf6637a..9373e68f7 100644
--- a/src/VBox/Devices/Network/slirp/tcp_input.c
+++ b/src/VBox/Devices/Network/slirp/tcp_input.c
@@ -1,4 +1,4 @@
-/* $Id: tcp_input.c $ */
+/* $Id: tcp_input.c 37936 2011-07-14 03:54:41Z vboxsync $ */
/** @file
* NAT - TCP input.
*/
@@ -98,6 +98,7 @@ tcp_reass(PNATState pData, struct tcpcb *tp, struct tcphdr *th, int *tlenp, stru
struct socket *so = tp->t_socket;
int flags;
STAM_PROFILE_START(&pData->StatTCP_reassamble, tcp_reassamble);
+ LogFlowFunc(("ENTER: pData:%p, tp:%R[tcpcb793], th:%p, tlenp:%p, m:%p\n", pData, tp, th, tlenp, m));
/*
* XXX: tcp_reass() is rather inefficient with its data structures
@@ -110,7 +111,10 @@ tcp_reass(PNATState pData, struct tcpcb *tp, struct tcphdr *th, int *tlenp, stru
* force pre-ESTABLISHED data up to user socket.
*/
if (th == NULL)
+ {
+ LogFlowFunc(("%d -> present\n", __LINE__));
goto present;
+ }
/*
* Limit the number of segments in the reassembly queue to prevent
@@ -128,6 +132,7 @@ tcp_reass(PNATState pData, struct tcpcb *tp, struct tcphdr *th, int *tlenp, stru
m_freem(pData, m);
*tlenp = 0;
STAM_PROFILE_STOP(&pData->StatTCP_reassamble, tcp_reassamble);
+ LogFlowFuncLeave();
return (0);
}
@@ -142,6 +147,7 @@ tcp_reass(PNATState pData, struct tcpcb *tp, struct tcphdr *th, int *tlenp, stru
m_freem(pData, m);
*tlenp = 0;
STAM_PROFILE_STOP(&pData->StatTCP_reassamble, tcp_reassamble);
+ LogFlowFuncLeave();
return (0);
}
tp->t_segqlen++;
@@ -183,6 +189,7 @@ tcp_reass(PNATState pData, struct tcpcb *tp, struct tcphdr *th, int *tlenp, stru
* This is needed after the 3-WHS
* completes.
*/
+ LogFlowFunc(("%d -> present\n", __LINE__));
goto present; /* ??? */
}
m_adj(m, i);
@@ -325,12 +332,14 @@ tcp_input(PNATState pData, register struct mbuf *m, int iphlen, struct socket *i
/* mbuf should be cleared in sofree called from tcp_close */
tcp_close(pData, tp);
STAM_PROFILE_STOP(&pData->StatTCP_input, counter_input);
+ LogFlowFuncLeave();
return;
}
tiwin = ti->ti_win;
tiflags = ti->ti_flags;
+ LogFlowFunc(("%d -> cont_conn\n", __LINE__));
goto cont_conn;
}
@@ -374,6 +383,7 @@ tcp_input(PNATState pData, register struct mbuf *m, int iphlen, struct socket *i
if (cksum(m, len))
{
tcpstat.tcps_rcvbadsum++;
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
}
@@ -386,6 +396,7 @@ tcp_input(PNATState pData, register struct mbuf *m, int iphlen, struct socket *i
|| off > tlen)
{
tcpstat.tcps_rcvbadoff++;
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
}
tlen -= off;
@@ -436,6 +447,7 @@ tcp_input(PNATState pData, register struct mbuf *m, int iphlen, struct socket *i
* Locate pcb for segment.
*/
findso:
+ LogFlowFunc(("(enter) findso: %R[natsock]\n", so));
if (so != NULL && so != &tcb)
SOCKET_UNLOCK(so);
QSOCKET_LOCK(tcb);
@@ -482,6 +494,7 @@ findso:
SOCKET_LOCK(so);
QSOCKET_UNLOCK(tcb);
}
+ LogFlowFunc(("(leave) findso: %R[natsock]\n", so));
/*
* If the state is CLOSED (i.e., TCB does not exist) then
@@ -499,13 +512,20 @@ findso:
if (so == 0)
{
if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN)
+ {
+ LogFlowFunc(("%d -> dropwithreset\n", __LINE__));
goto dropwithreset;
+ }
if ((so = socreate()) == NULL)
+ {
+ LogFlowFunc(("%d -> dropwithreset\n", __LINE__));
goto dropwithreset;
+ }
if (tcp_attach(pData, so) < 0)
{
RTMemFree(so); /* Not sofree (if it failed, it's not insqued) */
+ LogFlowFunc(("%d -> dropwithreset\n", __LINE__));
goto dropwithreset;
}
SOCKET_LOCK(so);
@@ -528,7 +548,7 @@ findso:
so->so_iptos = ((struct ip *)ti)->ip_tos;
tp = sototcpcb(so);
- tp->t_state = TCPS_LISTEN;
+ TCP_STATE_SWITCH_TO(tp, TCPS_LISTEN);
}
/*
@@ -538,6 +558,7 @@ findso:
*/
if (so->so_state & SS_ISFCONNECTING)
{
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
}
@@ -545,9 +566,13 @@ findso:
/* XXX Should never fail */
if (tp == 0)
+ {
+ LogFlowFunc(("%d -> dropwithreset\n", __LINE__));
goto dropwithreset;
+ }
if (tp->t_state == TCPS_CLOSED)
{
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
}
@@ -755,11 +780,20 @@ findso:
case TCPS_LISTEN:
{
if (tiflags & TH_RST)
+ {
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
+ }
if (tiflags & TH_ACK)
+ {
+ LogFlowFunc(("%d -> dropwithreset\n", __LINE__));
goto dropwithreset;
+ }
if ((tiflags & TH_SYN) == 0)
+ {
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
+ }
/*
* This has way too many gotos...
@@ -789,7 +823,6 @@ findso:
m->m_len += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
*ip = save_ip;
icmp_error(pData, m, ICMP_UNREACH, code, 0, strerror(errno));
- m_freem(pData, m);
tp->t_socket->so_m = NULL;
}
tp = tcp_close(pData, tp);
@@ -805,22 +838,26 @@ findso:
so->so_m = m;
so->so_ti = ti;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
- tp->t_state = TCPS_SYN_RECEIVED;
+ TCP_STATE_SWITCH_TO(tp, TCPS_SYN_RECEIVED);
}
SOCKET_UNLOCK(so);
STAM_PROFILE_STOP(&pData->StatTCP_input, counter_input);
+ LogFlowFuncLeave();
return;
cont_conn:
/* m==NULL
* Check if the connect succeeded
*/
+ LogFlowFunc(("cont_conn:\n"));
if (so->so_state & SS_NOFDREF)
{
tp = tcp_close(pData, tp);
+ LogFlowFunc(("%d -> dropwithreset\n", __LINE__));
goto dropwithreset;
}
cont_input:
+ LogFlowFunc(("cont_input:\n"));
tcp_template(tp);
if (optp)
@@ -835,9 +872,10 @@ cont_input:
tcp_sendseqinit(tp);
tcp_rcvseqinit(tp);
tp->t_flags |= TF_ACKNOW;
- tp->t_state = TCPS_SYN_RECEIVED;
+ TCP_STATE_SWITCH_TO(tp, TCPS_SYN_RECEIVED);
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
tcpstat.tcps_accepts++;
+ LogFlowFunc(("%d -> trimthenstep6\n", __LINE__));
goto trimthenstep6;
} /* case TCPS_LISTEN */
@@ -857,17 +895,22 @@ cont_input:
if ( (tiflags & TH_ACK)
&& ( SEQ_LEQ(ti->ti_ack, tp->iss)
|| SEQ_GT(ti->ti_ack, tp->snd_max)))
+ {
+ LogFlowFunc(("%d -> dropwithreset\n", __LINE__));
goto dropwithreset;
+ }
if (tiflags & TH_RST)
{
if (tiflags & TH_ACK)
tp = tcp_drop(pData, tp, 0); /* XXX Check t_softerror! */
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
}
if ((tiflags & TH_SYN) == 0)
{
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
}
if (tiflags & TH_ACK)
@@ -885,7 +928,7 @@ cont_input:
{
tcpstat.tcps_connects++;
soisfconnected(so);
- tp->t_state = TCPS_ESTABLISHED;
+ TCP_STATE_SWITCH_TO(tp, TCPS_ESTABLISHED);
/* Do window scaling on this connection? */
#if 0
@@ -905,9 +948,10 @@ cont_input:
tcp_xmit_timer(pData, tp, tp->t_rtt);
}
else
- tp->t_state = TCPS_SYN_RECEIVED;
+ TCP_STATE_SWITCH_TO(tp, TCPS_SYN_RECEIVED);
trimthenstep6:
+ LogFlowFunc(("trimthenstep6:\n"));
/*
* Advance ti->ti_seq to correspond to first data byte.
* If data, trim to stay within window,
@@ -925,7 +969,7 @@ trimthenstep6:
}
tp->snd_wl1 = ti->ti_seq - 1;
tp->rcv_up = ti->ti_seq;
- Log2(("hit6\n"));
+ LogFlowFunc(("%d -> step6\n", __LINE__));
goto step6;
} /* switch tp->t_state */
/*
@@ -1031,6 +1075,7 @@ trimthenstep6:
{
tp = tcp_close(pData, tp);
tcpstat.tcps_rcvafterclose++;
+ LogFlowFunc(("%d -> dropwithreset\n", __LINE__));
goto dropwithreset;
}
@@ -1058,6 +1103,7 @@ trimthenstep6:
iss = tp->rcv_nxt + TCP_ISSINCR;
tp = tcp_close(pData, tp);
SOCKET_UNLOCK(tp->t_socket);
+ LogFlowFunc(("%d -> findso\n", __LINE__));
goto findso;
}
/*
@@ -1073,7 +1119,10 @@ trimthenstep6:
tcpstat.tcps_rcvwinprobe++;
}
else
+ {
+ LogFlowFunc(("%d -> dropafterack\n", __LINE__));
goto dropafterack;
+ }
}
else
tcpstat.tcps_rcvbyteafterwin += todrop;
@@ -1111,6 +1160,7 @@ trimthenstep6:
{
case TCPS_SYN_RECEIVED:
/* so->so_error = ECONNREFUSED; */
+ LogFlowFunc(("%d -> close\n", __LINE__));
goto close;
case TCPS_ESTABLISHED:
@@ -1119,16 +1169,19 @@ trimthenstep6:
case TCPS_CLOSE_WAIT:
/* so->so_error = ECONNRESET; */
close:
- tp->t_state = TCPS_CLOSED;
- tcpstat.tcps_drops++;
- tp = tcp_close(pData, tp);
- goto drop;
+ LogFlowFunc(("close:\n"));
+ TCP_STATE_SWITCH_TO(tp, TCPS_CLOSED);
+ tcpstat.tcps_drops++;
+ tp = tcp_close(pData, tp);
+ LogFlowFunc(("%d -> drop\n", __LINE__));
+ goto drop;
case TCPS_CLOSING:
case TCPS_LAST_ACK:
case TCPS_TIME_WAIT:
- tp = tcp_close(pData, tp);
- goto drop;
+ tp = tcp_close(pData, tp);
+ LogFlowFunc(("%d -> drop\n", __LINE__));
+ goto drop;
}
/*
@@ -1138,6 +1191,7 @@ close:
if (tiflags & TH_SYN)
{
tp = tcp_drop(pData, tp, 0);
+ LogFlowFunc(("%d -> dropwithreset\n", __LINE__));
goto dropwithreset;
}
@@ -1146,6 +1200,7 @@ close:
*/
if ((tiflags & TH_ACK) == 0)
{
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
}
@@ -1164,7 +1219,7 @@ close:
|| SEQ_GT(ti->ti_ack, tp->snd_max))
goto dropwithreset;
tcpstat.tcps_connects++;
- tp->t_state = TCPS_ESTABLISHED;
+ TCP_STATE_SWITCH_TO(tp, TCPS_ESTABLISHED);
/*
* The sent SYN is ack'ed with our sequence number +1
* The first data byte already in the buffer will get
@@ -1187,6 +1242,7 @@ close:
(void) tcp_reass(pData, tp, (struct tcphdr *)0, (int *)0, (struct mbuf *)0);
tp->snd_wl1 = ti->ti_seq - 1;
/* Avoid ack processing; snd_una==ti_ack => dup ack */
+ LogFlowFunc(("%d -> synrx_to_est\n", __LINE__));
goto synrx_to_est;
/* fall into ... */
@@ -1254,12 +1310,14 @@ close:
tp->t_maxseg * tp->t_dupacks;
if (SEQ_GT(onxt, tp->snd_nxt))
tp->snd_nxt = onxt;
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
}
else if (tp->t_dupacks > tcprexmtthresh)
{
tp->snd_cwnd += tp->t_maxseg;
(void) tcp_output(pData, tp);
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
}
}
@@ -1268,6 +1326,7 @@ close:
break;
}
synrx_to_est:
+ LogFlowFunc(("synrx_to_est:\n"));
/*
* If the congestion window was inflated to account
* for the other side's cached packets, retract it.
@@ -1279,6 +1338,7 @@ synrx_to_est:
if (SEQ_GT(ti->ti_ack, tp->snd_max))
{
tcpstat.tcps_rcvacktoomuch++;
+ LogFlowFunc(("%d -> dropafterack\n", __LINE__));
goto dropafterack;
}
acked = ti->ti_ack - tp->snd_una;
@@ -1384,7 +1444,7 @@ synrx_to_est:
soisfdisconnected(so);
tp->t_timer[TCPT_2MSL] = tcp_maxidle;
}
- tp->t_state = TCPS_FIN_WAIT_2;
+ TCP_STATE_SWITCH_TO(tp, TCPS_FIN_WAIT_2);
}
break;
@@ -1397,7 +1457,7 @@ synrx_to_est:
case TCPS_CLOSING:
if (ourfinisacked)
{
- tp->t_state = TCPS_TIME_WAIT;
+ TCP_STATE_SWITCH_TO(tp, TCPS_TIME_WAIT);
tcp_canceltimers(tp);
tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
soisfdisconnected(so);
@@ -1414,6 +1474,7 @@ synrx_to_est:
if (ourfinisacked)
{
tp = tcp_close(pData, tp);
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
}
break;
@@ -1425,11 +1486,13 @@ synrx_to_est:
*/
case TCPS_TIME_WAIT:
tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
+ LogFlowFunc(("%d -> dropafterack\n", __LINE__));
goto dropafterack;
}
} /* switch(tp->t_state) */
step6:
+ LogFlowFunc(("step6:\n"));
/*
* Update window information.
* Don't look at window if no ACK: TAC's send garbage on first SYN.
@@ -1472,6 +1535,7 @@ step6:
{
ti->ti_urp = 0;
tiflags &= ~TH_URG;
+ LogFlowFunc(("%d -> dodata\n", __LINE__));
goto dodata;
}
#endif
@@ -1506,6 +1570,7 @@ step6:
if (SEQ_GT(tp->rcv_nxt, tp->rcv_up))
tp->rcv_up = tp->rcv_nxt;
dodata:
+ LogFlowFunc(("dodata:\n"));
/*
* If this is a small packet, then ACK now - with Nagel
@@ -1595,7 +1660,7 @@ dodata:
*/
case TCPS_SYN_RECEIVED:
case TCPS_ESTABLISHED:
- tp->t_state = TCPS_CLOSE_WAIT;
+ TCP_STATE_SWITCH_TO(tp, TCPS_CLOSE_WAIT);
break;
/*
@@ -1603,7 +1668,7 @@ dodata:
* enter the CLOSING state.
*/
case TCPS_FIN_WAIT_1:
- tp->t_state = TCPS_CLOSING;
+ TCP_STATE_SWITCH_TO(tp, TCPS_CLOSING);
break;
/*
@@ -1612,7 +1677,7 @@ dodata:
* standard timers.
*/
case TCPS_FIN_WAIT_2:
- tp->t_state = TCPS_TIME_WAIT;
+ TCP_STATE_SWITCH_TO(tp, TCPS_TIME_WAIT);
tcp_canceltimers(tp);
tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
soisfdisconnected(so);
@@ -1635,24 +1700,30 @@ dodata:
SOCKET_UNLOCK(so);
STAM_PROFILE_STOP(&pData->StatTCP_input, counter_input);
+ LogFlowFuncLeave();
return;
dropafterack:
- Log2(("drop after ack\n"));
+ LogFlowFunc(("dropafterack:\n"));
/*
* Generate an ACK dropping incoming segment if it occupies
* sequence space, where the ACK reflects our state.
*/
if (tiflags & TH_RST)
+ {
+ LogFlowFunc(("%d -> drop\n", __LINE__));
goto drop;
+ }
m_freem(pData, m);
tp->t_flags |= TF_ACKNOW;
(void) tcp_output(pData, tp);
SOCKET_UNLOCK(so);
STAM_PROFILE_STOP(&pData->StatTCP_input, counter_input);
+ LogFlowFuncLeave();
return;
dropwithreset:
+ LogFlowFunc(("dropwithreset:\n"));
/* reuses m if m!=NULL, m_free() unnecessary */
if (tiflags & TH_ACK)
tcp_respond(pData, tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST);
@@ -1667,9 +1738,11 @@ dropwithreset:
if (so != &tcb)
SOCKET_UNLOCK(so);
STAM_PROFILE_STOP(&pData->StatTCP_input, counter_input);
+ LogFlowFuncLeave();
return;
drop:
+ LogFlowFunc(("drop:\n"));
/*
* Drop space held by incoming segment and return.
*/
@@ -1683,6 +1756,7 @@ drop:
#endif
STAM_PROFILE_STOP(&pData->StatTCP_input, counter_input);
+ LogFlowFuncLeave();
return;
}
@@ -1692,7 +1766,7 @@ tcp_dooptions(PNATState pData, struct tcpcb *tp, u_char *cp, int cnt, struct tcp
u_int16_t mss;
int opt, optlen;
- LogFlow(("tcp_dooptions: tp = %lx, cnt=%i\n", (long)tp, cnt));
+ LogFlowFunc(("tcp_dooptions: tp = %R[tcpcb793], cnt=%i\n", tp, cnt));
for (; cnt > 0; cnt -= optlen, cp += optlen)
{
@@ -1803,7 +1877,7 @@ tcp_xmit_timer(PNATState pData, register struct tcpcb *tp, int rtt)
{
register short delta;
- LogFlow(("tcp_xmit_timer: tp = %lx rtt = %d\n", (long)tp, rtt));
+ LogFlowFunc(("ENTER: tcp_xmit_timer: tp = %R[tcpcb793] rtt = %d\n", tp, rtt));
tcpstat.tcps_rttupdated++;
if (tp->t_srtt != 0)
@@ -1893,7 +1967,7 @@ tcp_mss(PNATState pData, register struct tcpcb *tp, u_int offer)
struct socket *so = tp->t_socket;
int mss;
- LogFlow(("tcp_mss: tp = %lx, offet = %d\n", (long)tp, offer));
+ LogFlowFunc(("ENTER: tcp_mss: tp = %R[tcpcb793], offer = %d\n", tp, offer));
mss = min(if_mtu, if_mru) - sizeof(struct tcpiphdr);
if (offer)
diff --git a/src/VBox/Devices/Network/slirp/tcp_output.c b/src/VBox/Devices/Network/slirp/tcp_output.c
index 1734b8e29..2b9f93421 100644
--- a/src/VBox/Devices/Network/slirp/tcp_output.c
+++ b/src/VBox/Devices/Network/slirp/tcp_output.c
@@ -1,4 +1,4 @@
-/* $Id: tcp_output.c $ */
+/* $Id: tcp_output.c 37936 2011-07-14 03:54:41Z vboxsync $ */
/** @file
* NAT - TCP output.
*/
@@ -101,7 +101,7 @@ tcp_output(PNATState pData, register struct tcpcb *tp)
int idle, sendalot;
int size = 0;
- LogFlow(("tcp_output: tp = %lx\n", (long)tp));
+ LogFlow(("ENTER: tcp_output: tp = %R[tcpcb793]\n", tp));
/*
* Determine length of data that should be transmitted,
diff --git a/src/VBox/Devices/Network/slirp/tcp_subr.c b/src/VBox/Devices/Network/slirp/tcp_subr.c
index 1d3066b09..222dc13d9 100644
--- a/src/VBox/Devices/Network/slirp/tcp_subr.c
+++ b/src/VBox/Devices/Network/slirp/tcp_subr.c
@@ -1,4 +1,4 @@
-/* $Id: tcp_subr.c $ */
+/* $Id: tcp_subr.c 37936 2011-07-14 03:54:41Z vboxsync $ */
/** @file
* NAT - TCP support.
*/
@@ -128,8 +128,8 @@ tcp_respond(PNATState pData, struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf
register int tlen;
int win = 0;
- LogFlow(("tcp_respond: tp = %lx, ti = %lx, m = %lx, ack = %u, seq = %u, flags = %x\n",
- (long)tp, (long)ti, (long)m, ack, seq, flags));
+ LogFlowFunc(("ENTER: tp = %R[tcpcb793], ti = %lx, m = %lx, ack = %u, seq = %u, flags = %x\n",
+ tp, (long)ti, (long)m, ack, seq, flags));
if (tp)
win = sbspace(&tp->t_socket->so_rcv);
@@ -224,7 +224,7 @@ tcp_newtcpcb(PNATState pData, struct socket *so)
tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
- tp->t_state = TCPS_CLOSED;
+ TCP_STATE_SWITCH_TO(tp, TCPS_CLOSED);
so->so_tcpcb = tp;
@@ -243,11 +243,11 @@ struct tcpcb *tcp_drop(PNATState pData, struct tcpcb *tp, int err)
int errno;
{
*/
- LogFlow(("tcp_drop: tp = %lx, errno = %d\n", (long)tp, errno));
+ LogFlowFunc(("ENTER: tp = %R[tcpcb793], errno = %d\n", tp, errno));
if (TCPS_HAVERCVDSYN(tp->t_state))
{
- tp->t_state = TCPS_CLOSED;
+ TCP_STATE_SWITCH_TO(tp, TCPS_CLOSED);
(void) tcp_output(pData, tp);
tcpstat.tcps_drops++;
}
@@ -275,7 +275,7 @@ tcp_close(PNATState pData, register struct tcpcb *tp)
struct socket *so_next, *so_prev;
struct tseg_qent *te = NULL;
- LogFlow(("tcp_close: tp = %lx\n", (long)tp));
+ LogFlowFunc(("ENTER: tp = %R[tcpcb793]\n", tp));
so_next = so_prev = NULL;
/*XXX: freeing the reassembly queue */
while (!LIST_EMPTY(&tp->t_segq))
@@ -352,24 +352,24 @@ tcp_quench(i, int errno)
void
tcp_sockclosed(PNATState pData, struct tcpcb *tp)
{
- LogFlow(("tcp_sockclosed: tp = %lx\n", (long)tp));
+ LogFlowFunc(("ENTER: tp = %R[tcpcb793]\n", tp));
switch (tp->t_state)
{
case TCPS_CLOSED:
case TCPS_LISTEN:
case TCPS_SYN_SENT:
- tp->t_state = TCPS_CLOSED;
+ TCP_STATE_SWITCH_TO(tp, TCPS_CLOSED);
tp = tcp_close(pData, tp);
break;
case TCPS_SYN_RECEIVED:
case TCPS_ESTABLISHED:
- tp->t_state = TCPS_FIN_WAIT_1;
+ TCP_STATE_SWITCH_TO(tp, TCPS_FIN_WAIT_1);
break;
case TCPS_CLOSE_WAIT:
- tp->t_state = TCPS_LAST_ACK;
+ TCP_STATE_SWITCH_TO(tp, TCPS_LAST_ACK);
break;
}
/* soisfdisconnecting(tp->t_socket); */
@@ -402,7 +402,7 @@ int tcp_fconnect(PNATState pData, struct socket *so)
{
int ret = 0;
- LogFlow(("tcp_fconnect: so = %lx\n", (long)so));
+ LogFlowFunc(("ENTER: so = %R[natsock]\n", so));
if ((ret = so->s = socket(AF_INET, SOCK_STREAM, 0)) >= 0)
{
@@ -471,7 +471,7 @@ tcp_connect(PNATState pData, struct socket *inso)
socklen_t optlen;
static int cVerbose = 1;
- LogFlow(("tcp_connect: inso = %lx\n", (long)inso));
+ LogFlowFunc(("ENTER: inso = %R[natsock]\n", inso));
/*
* If it's an SS_ACCEPTONCE socket, no need to socreate()
@@ -583,7 +583,7 @@ tcp_connect(PNATState pData, struct socket *inso)
/* soisconnecting(so); */ /* NOFDREF used instead */
tcpstat.tcps_connattempt++;
- tp->t_state = TCPS_SYN_SENT;
+ TCP_STATE_SWITCH_TO(tp, TCPS_SYN_SENT);
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
tp->iss = tcp_iss;
tcp_iss += TCP_ISSINCR/2;
diff --git a/src/VBox/Devices/Network/slirp/tcp_timer.c b/src/VBox/Devices/Network/slirp/tcp_timer.c
index 31d09c1ca..542808fef 100644
--- a/src/VBox/Devices/Network/slirp/tcp_timer.c
+++ b/src/VBox/Devices/Network/slirp/tcp_timer.c
@@ -1,4 +1,4 @@
-/* $Id: tcp_timer.c $ */
+/* $Id: tcp_timer.c 37936 2011-07-14 03:54:41Z vboxsync $ */
/** @file
* NAT - TCP timers.
*/
@@ -65,7 +65,7 @@ tcp_fasttimo(PNATState pData)
register struct socket *so, *so_next;
register struct tcpcb *tp;
- LogFlow(("tcp_fasttimo:\n"));
+ LogFlowFuncEnter();
so = tcb.so_next;
if (so)
@@ -95,7 +95,7 @@ tcp_slowtimo(PNATState pData)
register struct tcpcb *tp;
register int i;
- LogFlow(("tcp_slowtimo:\n"));
+ LogFlowFuncEnter();
/*
* Search through tcb's and update active timers.
@@ -158,7 +158,7 @@ tcp_timers(PNATState pData, register struct tcpcb *tp, int timer)
{
register int rexmt;
- LogFlow(("tcp_timers:\n"));
+ LogFlowFunc(("ENTER: tp:%R[tcpcb793], timer:%d\n", tp, timer));
switch (timer)
{
diff --git a/src/VBox/Devices/Network/slirp/tcp_timer.h b/src/VBox/Devices/Network/slirp/tcp_timer.h
index 8e162325f..91aab640d 100644
--- a/src/VBox/Devices/Network/slirp/tcp_timer.h
+++ b/src/VBox/Devices/Network/slirp/tcp_timer.h
@@ -1,4 +1,4 @@
-/* $Id: tcp_timer.h $ */
+/* $Id: tcp_timer.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - TCP timer (declarations/defines).
*/
diff --git a/src/VBox/Devices/Network/slirp/tcp_var.h b/src/VBox/Devices/Network/slirp/tcp_var.h
index 5c24ad1e5..c3d19ca41 100644
--- a/src/VBox/Devices/Network/slirp/tcp_var.h
+++ b/src/VBox/Devices/Network/slirp/tcp_var.h
@@ -1,4 +1,4 @@
-/* $Id: tcp_var.h $ */
+/* $Id: tcp_var.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - TCP (declarations).
*/
diff --git a/src/VBox/Devices/Network/slirp/tcpip.h b/src/VBox/Devices/Network/slirp/tcpip.h
index e9b8e1680..d73942b60 100644
--- a/src/VBox/Devices/Network/slirp/tcpip.h
+++ b/src/VBox/Devices/Network/slirp/tcpip.h
@@ -1,4 +1,4 @@
-/* $Id: tcpip.h $ */
+/* $Id: tcpip.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - TCP/IP (declarations/defines).
*/
diff --git a/src/VBox/Devices/Network/slirp/tftp.c b/src/VBox/Devices/Network/slirp/tftp.c
index 8b77bf0c6..cb3560b96 100644
--- a/src/VBox/Devices/Network/slirp/tftp.c
+++ b/src/VBox/Devices/Network/slirp/tftp.c
@@ -1,4 +1,4 @@
-/* $Id: tftp.c $ */
+/* $Id: tftp.c 36901 2011-04-29 18:03:48Z vboxsync $ */
/** @file
* NAT - TFTP server.
*/
diff --git a/src/VBox/Devices/Network/slirp/tftp.h b/src/VBox/Devices/Network/slirp/tftp.h
index 6fb0ef7a1..44889624c 100644
--- a/src/VBox/Devices/Network/slirp/tftp.h
+++ b/src/VBox/Devices/Network/slirp/tftp.h
@@ -1,4 +1,4 @@
-/* $Id: tftp.h $ */
+/* $Id: tftp.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - TFTP server (declarations/defines).
*/
diff --git a/src/VBox/Devices/Network/slirp/udp.c b/src/VBox/Devices/Network/slirp/udp.c
index 1d1760744..4748ba250 100644
--- a/src/VBox/Devices/Network/slirp/udp.c
+++ b/src/VBox/Devices/Network/slirp/udp.c
@@ -1,4 +1,4 @@
-/* $Id: udp.c $ */
+/* $Id: udp.c 37936 2011-07-14 03:54:41Z vboxsync $ */
/** @file
* NAT - UDP protocol.
*/
@@ -94,9 +94,9 @@ udp_input(PNATState pData, register struct mbuf *m, int iphlen)
int ret;
int ttl;
- LogFlow(("udp_input: m = %lx, iphlen = %d\n", (long)m, iphlen));
+ LogFlowFunc(("ENTER: m = %p, iphlen = %d\n", m, iphlen));
ip = mtod(m, struct ip *);
- Log2(("%R[IP4] iphlen = %d\n", &ip->ip_dst, iphlen));
+ Log2(("%RTnaipv4 iphlen = %d\n", ip->ip_dst, iphlen));
udpstat.udps_ipackets++;
@@ -193,6 +193,7 @@ udp_input(PNATState pData, register struct mbuf *m, int iphlen)
m->m_data += sizeof(struct udpiphdr);
m->m_len -= sizeof(struct udpiphdr);
udp_output2(pData, NULL, m, &src, &dst, IPTOS_LOWDELAY);
+ LogFlowFuncLeave();
return;
}
/*
@@ -295,11 +296,11 @@ udp_input(PNATState pData, register struct mbuf *m, int iphlen)
m->m_len += iphlen;
m->m_data -= iphlen;
*ip = save_ip;
- Log2(("NAT: UDP tx errno = %d (%s) on sent to %R[IP4]\n",
- errno, strerror(errno), &ip->ip_dst));
+ Log2(("NAT: UDP tx errno = %d (%s) on sent to %RTnaipv4\n",
+ errno, strerror(errno), ip->ip_dst));
icmp_error(pData, m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
- m_freem(pData, m);
so->so_m = NULL;
+ LogFlowFuncLeave();
return;
}
@@ -311,10 +312,11 @@ udp_input(PNATState pData, register struct mbuf *m, int iphlen)
m->m_data -= iphlen;
*ip = save_ip;
so->so_m = m; /* ICMP backup */
+ LogFlowFuncLeave();
return;
bad_free_mbuf:
- Log2(("NAT: UDP(id: %hd) datagram to %R[IP4] with size(%d) claimed as bad\n",
+ Log2(("NAT: UDP(id: %hd) datagram to %RTnaipv4 with size(%d) claimed as bad\n",
ip->ip_id, &ip->ip_dst, ip->ip_len));
done_free_mbuf:
@@ -323,6 +325,7 @@ done_free_mbuf:
* buffers here.
*/
m_freem(pData, m);
+ LogFlowFuncLeave();
return;
}
@@ -339,8 +342,8 @@ int udp_output2(PNATState pData, struct socket *so, struct mbuf *m,
int error;
int mlen = 0;
- LogFlow(("udp_output: so = %lx, m = %lx, saddr = %lx, daddr = %lx\n",
- (long)so, (long)m, (long)saddr->sin_addr.s_addr, (long)daddr->sin_addr.s_addr));
+ LogFlowFunc(("ENTER: so = %R[natsock], m = %lx, saddr = %lx, daddr = %lx\n",
+ so, (long)m, (long)saddr->sin_addr.s_addr, (long)daddr->sin_addr.s_addr));
/*
* Adjust for header
@@ -518,7 +521,7 @@ udp_listen(PNATState pData, u_int32_t bind_addr, u_int port, u_int32_t laddr, u_
if (bind(so->s,(struct sockaddr *)&addr, addrlen) < 0)
{
- LogRel(("NAT: bind to %R[IP4] has been failed\n", &addr.sin_addr));
+ LogRel(("NAT: bind to %RTnaipv4 has been failed\n", addr.sin_addr));
udp_detach(pData, so);
return NULL;
}
diff --git a/src/VBox/Devices/Network/slirp/udp.h b/src/VBox/Devices/Network/slirp/udp.h
index fb1c76a37..66ad62eea 100644
--- a/src/VBox/Devices/Network/slirp/udp.h
+++ b/src/VBox/Devices/Network/slirp/udp.h
@@ -1,4 +1,4 @@
-/* $Id: udp.h $ */
+/* $Id: udp.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NAT - UDP protocol (declarations/defines).
*/
diff --git a/src/VBox/Devices/Network/solaris/vbox-libdlpi.cpp b/src/VBox/Devices/Network/solaris/vbox-libdlpi.cpp
index 568dfeead..2b47a4b97 100644
--- a/src/VBox/Devices/Network/solaris/vbox-libdlpi.cpp
+++ b/src/VBox/Devices/Network/solaris/vbox-libdlpi.cpp
@@ -1,4 +1,4 @@
-/** $Id: vbox-libdlpi.cpp $ */
+/** $Id: vbox-libdlpi.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Dynamically load libdpli & symbols on Solaris hosts, Internal header.
*/
diff --git a/src/VBox/Devices/Network/solaris/vbox-libdlpi.h b/src/VBox/Devices/Network/solaris/vbox-libdlpi.h
index 1707605b8..0d8ca42bb 100644
--- a/src/VBox/Devices/Network/solaris/vbox-libdlpi.h
+++ b/src/VBox/Devices/Network/solaris/vbox-libdlpi.h
@@ -1,4 +1,4 @@
-/** $Id: vbox-libdlpi.h $ */
+/** $Id: vbox-libdlpi.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Dynamically load libdpli & symbols on Solaris hosts, Internal header.
*/
diff --git a/src/VBox/Devices/Network/testcase/tstDevEEPROM.cpp b/src/VBox/Devices/Network/testcase/tstDevEEPROM.cpp
index ebec4d9c6..ca0b23475 100644
--- a/src/VBox/Devices/Network/testcase/tstDevEEPROM.cpp
+++ b/src/VBox/Devices/Network/testcase/tstDevEEPROM.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstDevEEPROM.cpp $ */
+/* $Id: tstDevEEPROM.cpp 31885 2010-08-24 07:22:23Z vboxsync $ */
/** @file
* EEPROM 93C46 unit tests.
*/
diff --git a/src/VBox/Devices/Network/testcase/tstDevPhy.cpp b/src/VBox/Devices/Network/testcase/tstDevPhy.cpp
index b6393beab..a0ea07092 100644
--- a/src/VBox/Devices/Network/testcase/tstDevPhy.cpp
+++ b/src/VBox/Devices/Network/testcase/tstDevPhy.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstDevPhy.cpp $ */
+/* $Id: tstDevPhy.cpp 31885 2010-08-24 07:22:23Z vboxsync $ */
/** @file
* PHY MDIO unit tests.
*/
diff --git a/src/VBox/Devices/Network/testcase/tstIntNet-1.cpp b/src/VBox/Devices/Network/testcase/tstIntNet-1.cpp
index b6b7c7497..851eb3e0a 100644
--- a/src/VBox/Devices/Network/testcase/tstIntNet-1.cpp
+++ b/src/VBox/Devices/Network/testcase/tstIntNet-1.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstIntNet-1.cpp $ */
+/* $Id: tstIntNet-1.cpp 36470 2011-03-30 09:36:09Z vboxsync $ */
/** @file
* VBox - Testcase for internal networking, simple NetFlt trunk creation.
*/
@@ -749,7 +749,7 @@ int main(int argc, char **argv)
return 1;
case 'V':
- RTPrintf("$Revision: 70859 $\n");
+ RTPrintf("$Revision: 36470 $\n");
return 0;
default:
diff --git a/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp b/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp
index 6d982f59a..a9b2e8b02 100644
--- a/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp
+++ b/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstIntNetR0.cpp $ */
+/* $Id: tstIntNetR0.cpp 33595 2010-10-29 10:35:00Z vboxsync $ */
/** @file
* Internal networking - Usermode testcase for the kernel mode bits.
*
diff --git a/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp b/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp
index 3f961b71e..c4aa304d0 100644
--- a/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp
+++ b/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxAcpi.cpp $ */
+/* $Id: VBoxAcpi.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBoxAcpi - VirtualBox ACPI manipulation functionality.
*/
diff --git a/src/VBox/Devices/PC/BIOS/Makefile.kmk b/src/VBox/Devices/PC/BIOS/Makefile.kmk
index acac83ad6..e979f3287 100644
--- a/src/VBox/Devices/PC/BIOS/Makefile.kmk
+++ b/src/VBox/Devices/PC/BIOS/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 36877 2011-04-28 19:38:13Z vboxsync $
## @file
# PC BIOS Sub-Makefile.
#
@@ -57,12 +57,13 @@ $$(PcBiosBin_0_OUTDIR)/PcBiosBin.c: $$(PcBiosBin_0_OUTDIR)/pcbios.bin $(VBOX_BIN
$$(PcBiosBin_0_OUTDIR)/_rombios_.c: $(PATH_SUB_CURRENT)/rombios.c $(PATH_SUB_CURRENT)/logo.c \
$(PATH_SUB_CURRENT)/apmbios.S $(if $(VBOX_WITH_SCSI),$(PATH_SUB_CURRENT)/scsi.c) \
$(PATH_SUB_CURRENT)/../DevPcBios.h $(PATH_ROOT)/include/VBox/bioslogo.h \
+ $(if $(VBOX_WITH_BIOS_AHCI),$(PATH_SUB_CURRENT)/ahci.c) \
$(VBOX_VERSION_STAMP) | $$(dir $$@)
$(call MSG_TOOL,cpp,PcBiosBin,$<,$@)
$(QUIET)$(TOOL_$(VBOX_GCC_TOOL)_CC) -E \
-I$(PcBiosBin_0_OUTDIR) -I$(VBOX_PATH_DEVICES_SRC)/PC -I$(PATH_ROOT)/include -I$(PATH_OUT) \
-DBX_SMP_PROCESSORS=1 -DVBOX -DVBOX_PC_BIOS $(addprefix -D,$(DEFS) $(DEFS.$(KBUILD_TYPE))) \
- $(if $(VBOX_WITH_SCSI),-DVBOX_WITH_SCSI) \
+ $(if $(VBOX_WITH_SCSI),-DVBOX_WITH_SCSI) $(if $(VBOX_WITH_BIOS_AHCI),-DVBOX_WITH_BIOS_AHCI) \
-P -o $@ $<
# 2. compile to intermediate asm file.
diff --git a/src/VBox/Devices/PC/BIOS/ahci.c b/src/VBox/Devices/PC/BIOS/ahci.c
new file mode 100644
index 000000000..24e632d91
--- /dev/null
+++ b/src/VBox/Devices/PC/BIOS/ahci.c
@@ -0,0 +1,1698 @@
+/* $Id: ahci.c 37427 2011-06-13 17:45:37Z vboxsync $ */
+/** @file
+ * AHCI host adapter driver to boot from SATA disks.
+ */
+
+/*
+ * 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.
+ */
+/**
+ * Parts are based on the int13_harddisk code in rombios.c
+ */
+
+#define AHCI_MAX_STORAGE_DEVICES 4
+
+/**
+ * AHCI device data.
+ */
+typedef struct
+{
+ Bit8u type; // Detected type of ata (ata/atapi/none/unknown/scsi)
+ Bit8u device; // Detected type of attached devices (hd/cd/none)
+ Bit8u removable; // Removable device flag
+ Bit8u lock; // Locks for removable devices
+ Bit16u blksize; // block size
+ chs_t lchs; // Logical CHS
+ chs_t pchs; // Physical CHS
+ Bit32u cSectors; // Total sectors count
+ Bit8u port; // Port this device is on.
+} ahci_device_t;
+
+/**
+ * AHCI controller data.
+ */
+typedef struct
+{
+ /** The AHCI command list as defined by chapter 4.2.2 of the Intel AHCI spec.
+ * Because the BIOS doesn't support NCQ only the first command header is defined
+ * to save memory. - Must be aligned on a 1K boundary.
+ */
+ Bit32u abCmdHdr[0x8];
+ /** Align the next structure on a 128 byte boundary. */
+ Bit8u abAlignment1[0x60];
+ /** The command table of one request as defined by chapter 4.2.3 of the Intel AHCI spec.
+ * Must be aligned on 128 byte boundary.
+ */
+ Bit8u abCmd[0x90];
+ /** Alignment */
+ Bit8u abAlignment2[0xF0];
+ /** Memory for the received command FIS area as specified by chapter 4.2.1
+ * of the Intel AHCI spec. This area is normally 256 bytes big but to save memory
+ * only the first 96 bytes are used because it is assumed that the controller
+ * never writes to the UFIS or reserved area. - Must be aligned on a 256byte boundary.
+ */
+ Bit8u abFisRecv[0x60];
+ /** Base I/O port for the index/data register pair. */
+ Bit16u iobase;
+ /** Current port which uses the memory to communicate with the controller. */
+ Bit8u port;
+ /** AHCI device information. */
+ ahci_device_t aDevices[AHCI_MAX_STORAGE_DEVICES];
+ /** Index of the next unoccupied device slot. */
+ Bit8u cDevices;
+ /** Map between (bios hd id - 0x80) and ahci devices. */
+ Bit8u cHardDisks;
+ Bit8u aHdIdMap[AHCI_MAX_STORAGE_DEVICES];
+ /** Map between (bios cd id - 0xE0) and ahci_devices. */
+ Bit8u cCdDrives;
+ Bit8u aCdIdMap[AHCI_MAX_STORAGE_DEVICES];
+ /** int13 handler to call if given device is not from AHCI. */
+ Bit16u pfnInt13Old;
+ /** Number of harddisks detected before the AHCI driver started detection. */
+ Bit8u cHardDisksOld;
+} ahci_t;
+
+#define AhciData ((ahci_t *) 0)
+
+/** Supported methods of the PCI BIOS. */
+#define PCIBIOS_ID 0xb1
+#define PCIBIOS_PCI_BIOS_PRESENT 0x01
+#define PCIBIOS_FIND_PCI_DEVICE 0x02
+#define PCIBIOS_FIND_CLASS_CODE 0x03
+#define PCIBIOS_GENERATE_SPECIAL_CYCLE 0x06
+#define PCIBIOS_READ_CONFIG_BYTE 0x08
+#define PCIBIOS_READ_CONFIG_WORD 0x09
+#define PCIBIOS_READ_CONFIG_DWORD 0x0a
+#define PCIBIOS_WRITE_CONFIG_BYTE 0x0b
+#define PCIBIOS_WRITE_CONFIG_WORD 0x0c
+#define PCIBIOS_WRITE_CONFIG_DWORD 0x0d
+#define PCIBIOS_GET_IRQ_ROUTING_OPTIONS 0x0e
+#define PCIBIOS_SET_PCI_IRQ 0x0f
+
+/** Status codes. */
+#define SUCCESSFUL 0x00
+#define FUNC_NOT_SUPPORTED 0x81
+#define BAD_VENDOR_ID 0x83
+#define DEVICE_NOT_FOUND 0x86
+#define BAD_REGISTER_NUMBER 0x87
+#define SET_FAILED 0x88
+#define BUFFER_TOO_SMALL 0x89
+
+/** PCI configuration fields. */
+#define PCI_CONFIG_CAP 0x34
+
+#define PCI_CAP_ID_SATACR 0x12
+#define VBOX_AHCI_NO_DEVICE 0xffff
+
+//#define VBOX_AHCI_DEBUG 1
+//#define VBOX_AHCI_INT13_DEBUG 1
+
+#ifdef VBOX_AHCI_DEBUG
+# define VBOXAHCI_DEBUG(a...) BX_INFO(a)
+#else
+# define VBOXAHCI_DEBUG(a...)
+#endif
+
+#ifdef VBOX_AHCI_INT13_DEBUG
+# define VBOXAHCI_INT13_DEBUG(a...) BX_INFO(a)
+#else
+# define VBOXAHCI_INT13_DEBUG(a...)
+#endif
+
+#define RT_BIT_32(bit) ((Bit32u)(1L << (bit)))
+
+/** Global register set. */
+#define AHCI_HBA_SIZE 0x100
+
+#define AHCI_REG_CAP ((Bit32u)0x00)
+#define AHCI_REG_GHC ((Bit32u)0x04)
+# define AHCI_GHC_AE RT_BIT_32(31)
+# define AHCI_GHC_IR RT_BIT_32(1)
+# define AHCI_GHC_HR RT_BIT_32(0)
+#define AHCI_REG_IS ((Bit32u)0x08)
+#define AHCI_REG_PI ((Bit32u)0x0c)
+#define AHCI_REG_VS ((Bit32u)0x10)
+
+/** Per port register set. */
+#define AHCI_PORT_SIZE 0x80
+
+#define AHCI_REG_PORT_CLB 0x00
+#define AHCI_REG_PORT_CLBU 0x04
+#define AHCI_REG_PORT_FB 0x08
+#define AHCI_REG_PORT_FBU 0x0c
+#define AHCI_REG_PORT_IS 0x10
+# define AHCI_REG_PORT_IS_DHRS RT_BIT_32(0)
+#define AHCI_REG_PORT_IE 0x14
+#define AHCI_REG_PORT_CMD 0x18
+# define AHCI_REG_PORT_CMD_ST RT_BIT_32(0)
+# define AHCI_REG_PORT_CMD_FRE RT_BIT_32(4)
+# define AHCI_REG_PORT_CMD_FR RT_BIT_32(14)
+# define AHCI_REG_PORT_CMD_CR RT_BIT_32(15)
+#define AHCI_REG_PORT_TFD 0x20
+#define AHCI_REG_PORT_SIG 0x24
+#define AHCI_REG_PORT_SSTS 0x28
+#define AHCI_REG_PORT_SCTL 0x2c
+#define AHCI_REG_PORT_SERR 0x30
+#define AHCI_REG_PORT_SACT 0x34
+#define AHCI_REG_PORT_CI 0x38
+
+/** Returns the absolute register offset from a given port and port register. */
+#define VBOXAHCI_PORT_REG(port, reg) ((Bit32u)(AHCI_HBA_SIZE + (port) * AHCI_PORT_SIZE + (reg)))
+
+#define VBOXAHCI_REG_IDX 0
+#define VBOXAHCI_REG_DATA 4
+
+/** Writes the given value to a AHCI register. */
+#define VBOXAHCI_WRITE_REG(iobase, reg, val) \
+ outl((iobase) + VBOXAHCI_REG_IDX, (Bit32u)(reg)); \
+ outl((iobase) + VBOXAHCI_REG_DATA, (Bit32u)(val))
+
+/** Reads from a AHCI register. */
+#define VBOXAHCI_READ_REG(iobase, reg, val) \
+ outl((iobase) + VBOXAHCI_REG_IDX, (Bit32u)(reg)); \
+ (val) = inl((iobase) + VBOXAHCI_REG_DATA)
+
+/** Writes to the given port register. */
+#define VBOXAHCI_PORT_WRITE_REG(iobase, port, reg, val) \
+ VBOXAHCI_WRITE_REG((iobase), VBOXAHCI_PORT_REG((port), (reg)), val)
+
+/** Reads from the given port register. */
+#define VBOXAHCI_PORT_READ_REG(iobase, port, reg, val) \
+ VBOXAHCI_READ_REG((iobase), VBOXAHCI_PORT_REG((port), (reg)), val)
+
+#define ATA_CMD_IDENTIFY_DEVICE 0xEC
+#define AHCI_CMD_READ_DMA_EXT 0x25
+#define AHCI_CMD_WRITE_DMA_EXT 0x35
+
+/**
+ * Returns the bus/device/function of a PCI device with
+ * the given classcode.
+ *
+ * @returns bus/device/fn in one 16bit integer where
+ * where the upper byte contains the bus number
+ * and lower one the device and function number.
+ * VBOX_AHCI_NO_DEVICE if no device was found.
+ * @param u16Class The classcode to search for.
+ */
+Bit16u ahci_pci_find_classcode(u16Class)
+ Bit32u u16Class;
+{
+ Bit16u u16BusDevFn;
+
+ASM_START
+ push bp
+ mov bp, sp
+
+ mov ah, #PCIBIOS_ID
+ mov al, #PCIBIOS_FIND_CLASS_CODE
+ mov ecx, _ahci_pci_find_classcode.u16Class + 2[bp]
+ mov si, #0 ; First controller
+ int 0x1a
+
+ ; Return from PCIBIOS
+ cmp ah, #SUCCESSFUL
+ jne ahci_pci_find_classcode_not_found
+
+ mov _ahci_pci_find_classcode.u16BusDevFn + 2[bp], bx
+ jmp ahci_pci_find_classcode_done
+
+ahci_pci_find_classcode_not_found:
+ mov _ahci_pci_find_classcode.u16BusDevFn + 2[bp], #VBOX_AHCI_NO_DEVICE
+
+ahci_pci_find_classcode_done:
+ pop bp
+ASM_END
+
+ return u16BusDevFn;
+}
+
+Bit8u ahci_pci_read_config_byte(u8Bus, u8DevFn, u8Reg)
+ Bit8u u8Bus, u8DevFn, u8Reg;
+{
+ Bit8u u8Val;
+
+ u8Val = 0;
+
+ASM_START
+ push bp
+ mov bp, sp
+
+ mov ah, #PCIBIOS_ID
+ mov al, #PCIBIOS_READ_CONFIG_BYTE
+ mov bh, _ahci_pci_read_config_byte.u8Bus + 2[bp]
+ mov bl, _ahci_pci_read_config_byte.u8DevFn + 2[bp]
+ mov di, _ahci_pci_read_config_byte.u8Reg + 2[bp]
+ int 0x1a
+
+ ; Return from PCIBIOS
+ cmp ah, #SUCCESSFUL
+ jne ahci_pci_read_config_byte_done
+
+ mov _ahci_pci_read_config_byte.u8Val + 2[bp], cl
+
+ahci_pci_read_config_byte_done:
+ pop bp
+ASM_END
+
+ return u8Val;
+}
+
+Bit16u ahci_pci_read_config_word(u8Bus, u8DevFn, u8Reg)
+ Bit8u u8Bus, u8DevFn, u8Reg;
+{
+ Bit16u u16Val;
+
+ u16Val = 0;
+
+ASM_START
+ push bp
+ mov bp, sp
+
+ mov ah, #PCIBIOS_ID
+ mov al, #PCIBIOS_READ_CONFIG_WORD
+ mov bh, _ahci_pci_read_config_word.u8Bus + 2[bp]
+ mov bl, _ahci_pci_read_config_word.u8DevFn + 2[bp]
+ mov di, _ahci_pci_read_config_word.u8Reg + 2[bp]
+ int 0x1a
+
+ ; Return from PCIBIOS
+ cmp ah, #SUCCESSFUL
+ jne ahci_pci_read_config_word_done
+
+ mov _ahci_pci_read_config_word.u16Val + 2[bp], cx
+
+ahci_pci_read_config_word_done:
+ pop bp
+ASM_END
+
+ return u16Val;
+}
+
+Bit32u ahci_pci_read_config_dword(u8Bus, u8DevFn, u8Reg)
+ Bit8u u8Bus, u8DevFn, u8Reg;
+{
+ Bit32u u32Val;
+
+ u32Val = 0;
+
+ASM_START
+ push bp
+ mov bp, sp
+
+ mov ah, #PCIBIOS_ID
+ mov al, #PCIBIOS_READ_CONFIG_DWORD
+ mov bh, _ahci_pci_read_config_dword.u8Bus + 2[bp]
+ mov bl, _ahci_pci_read_config_dword.u8DevFn + 2[bp]
+ mov di, _ahci_pci_read_config_dword.u8Reg + 2[bp]
+ int 0x1a
+
+ ; Return from PCIBIOS
+ cmp ah, #SUCCESSFUL
+ jne ahci_pci_read_config_dword_done
+
+ mov _ahci_pci_read_config_dword.u32Val + 2[bp], ecx
+
+ahci_pci_read_config_dword_done:
+ pop bp
+ASM_END
+
+ return u32Val;
+}
+
+#if 0 /* Disabled to save space because they are not needed. Might become useful in the future. */
+/**
+ * Returns the bus/device/function of a PCI device with
+ * the given vendor and device id.
+ *
+ * @returns bus/device/fn in one 16bit integer where
+ * where the upper byte contains the bus number
+ * and lower one the device and function number.
+ * VBOX_AHCI_NO_DEVICE if no device was found.
+ * @param u16Vendor The vendor ID.
+ * @param u16Device The device ID.
+ */
+Bit16u ahci_pci_find_device(u16Vendor, u16Device)
+ Bit16u u16Vendor;
+ Bit16u u16Device;
+{
+ Bit16u u16BusDevFn;
+
+ASM_START
+ push bp
+ mov bp, sp
+
+ mov ah, #PCIBIOS_ID
+ mov al, #PCIBIOS_FIND_PCI_DEVICE
+ mov cx, _ahci_pci_find_device.u16Device + 2[bp]
+ mov dx, _ahci_pci_find_device.u16Vendor + 2[bp]
+ mov si, #0 ; First controller
+ int 0x1a
+
+ ; Return from PCIBIOS
+ cmp ah, #SUCCESSFUL
+ jne ahci_pci_find_device_not_found
+
+ mov _ahci_pci_find_device.u16BusDevFn + 2[bp], bx
+ jmp ahci_pci_find_device_done
+
+ahci_pci_find_device_not_found:
+ mov _ahci_pci_find_device.u16BusDevFn + 2[bp], #VBOX_AHCI_NO_DEVICE
+
+ahci_pci_find_device_done:
+ pop bp
+ASM_END
+
+ return u16BusDevFn;
+}
+
+void ahci_pci_write_config_byte(u8Bus, u8DevFn, u8Reg, u8Val)
+ Bit8u u8Bus, u8DevFn, u8Reg, u8Val;
+{
+ASM_START
+ push bp
+ mov bp, sp
+
+ mov ah, #PCIBIOS_ID
+ mov al, #PCIBIOS_WRITE_CONFIG_BYTE
+ mov bh, _ahci_pci_write_config_byte.u8Bus + 2[bp]
+ mov bl, _ahci_pci_write_config_byte.u8DevFn + 2[bp]
+ mov di, _ahci_pci_write_config_byte.u8Reg + 2[bp]
+ mov cl, _ahci_pci_write_config_byte.u8Val + 2[bp]
+ int 0x1a
+
+ ; Return from PCIBIOS
+ pop bp
+ASM_END
+}
+
+void ahci_pci_write_config_word(u8Bus, u8DevFn, u8Reg, u16Val)
+ Bit8u u8Bus, u8DevFn, u8Reg;
+ Bit16u u16Val;
+{
+ASM_START
+ push bp
+ mov bp, sp
+
+ mov ah, #PCIBIOS_ID
+ mov al, #PCIBIOS_WRITE_CONFIG_WORD
+ mov bh, _ahci_pci_write_config_word.u8Bus + 2[bp]
+ mov bl, _ahci_pci_write_config_word.u8DevFn + 2[bp]
+ mov di, _ahci_pci_write_config_word.u8Reg + 2[bp]
+ mov cx, _ahci_pci_write_config_word.u16Val + 2[bp]
+ int 0x1a
+
+ ; Return from PCIBIOS
+ pop bp
+ASM_END
+}
+
+void ahci_pci_write_config_dword(u8Bus, u8DevFn, u8Reg, u32Val)
+ Bit8u u8Bus, u8DevFn, u8Reg;
+ Bit32u u32Val;
+{
+ASM_START
+ push bp
+ mov bp, sp
+
+ mov ah, #PCIBIOS_ID
+ mov al, #PCIBIOS_WRITE_CONFIG_WORD
+ mov bh, _ahci_pci_write_config_dword.u8Bus + 2[bp]
+ mov bl, _ahci_pci_write_config_dword.u8DevFn + 2[bp]
+ mov di, _ahci_pci_write_config_dword.u8Reg + 2[bp]
+ mov cx, _ahci_pci_write_config_dword.u32Val + 2[bp]
+ int 0x1a
+
+ ; Return from PCIBIOS
+ pop bp
+ASM_END
+}
+#endif /* 0 */
+
+/**
+ * Sets a given set of bits in a register.
+ */
+static void ahci_ctrl_set_bits(u16IoBase, u32Reg, u32Set)
+ Bit16u u16IoBase;
+ Bit32u u32Reg, u32Set;
+{
+ASM_START
+ push bp
+ mov bp, sp
+
+ push eax
+ push edx
+
+ ; Read from the register
+ mov eax, _ahci_ctrl_set_bits.u32Reg + 2[bp]
+ mov dx, _ahci_ctrl_set_bits.u16IoBase + 2[bp]
+ add dx, #VBOXAHCI_REG_IDX
+ out dx, eax
+
+ mov dx, _ahci_ctrl_set_bits.u16IoBase + 2[bp]
+ add dx, #VBOXAHCI_REG_DATA
+ in eax, dx
+
+ ; Set the new bits and write the result to the register again
+ or eax, _ahci_ctrl_set_bits.u32Set + 2[bp]
+ out dx, eax
+
+ pop edx
+ pop eax
+
+ pop bp
+ASM_END
+}
+
+/**
+ * Clears a given set of bits in a register.
+ */
+static void ahci_ctrl_clear_bits(u16IoBase, u32Reg, u32Clear)
+ Bit16u u16IoBase;
+ Bit32u u32Reg, u32Clear;
+{
+ASM_START
+ push bp
+ mov bp, sp
+
+ push eax
+ push ecx
+ push edx
+
+ ; Read from the register
+ mov eax, _ahci_ctrl_clear_bits.u32Reg + 2[bp]
+ mov dx, _ahci_ctrl_clear_bits.u16IoBase + 2[bp]
+ add dx, #VBOXAHCI_REG_IDX
+ out dx, eax
+
+ mov dx, _ahci_ctrl_clear_bits.u16IoBase + 2[bp]
+ add dx, #VBOXAHCI_REG_DATA
+ in eax, dx
+
+ ; Clear the bits and write the result to the register again
+ mov ecx, _ahci_ctrl_clear_bits.u32Clear + 2[bp]
+ not ecx
+ and eax, ecx
+ out dx, eax
+
+ pop edx
+ pop ecx
+ pop eax
+
+ pop bp
+ASM_END
+}
+
+/**
+ * Returns whether at least one of the bits in the given mask is set
+ * for a register.
+ */
+static Bit8u ahci_ctrl_is_bit_set(u16IoBase, u32Reg, u32Mask)
+ Bit16u u16IoBase;
+ Bit32u u32Reg, u32Mask;
+{
+ASM_START
+ push bp
+ mov bp, sp
+
+ push edx
+ push eax
+
+ ; Read from the register
+ mov eax, _ahci_ctrl_is_bit_set.u32Reg + 2[bp]
+ mov dx, _ahci_ctrl_is_bit_set.u16IoBase + 2[bp]
+ add dx, #VBOXAHCI_REG_IDX
+ out dx, eax
+
+ mov dx, _ahci_ctrl_is_bit_set.u16IoBase + 2[bp]
+ add dx, #VBOXAHCI_REG_DATA
+ in eax, dx
+
+ ; Check for set bits
+ mov edx, _ahci_ctrl_is_bit_set.u32Mask + 2[bp]
+ test eax, edx
+ je ahci_ctrl_is_bit_set_not_set
+ mov al, #1 ; At least one of the bits is set
+ jmp ahci_ctrl_is_bit_set_done
+
+ahci_ctrl_is_bit_set_not_set:
+ mov al, #0 ; No bit is set
+
+ahci_ctrl_is_bit_set_done:
+ pop edx ; restore upper 16 bits of eax
+ and edx, #0xffff0000
+ or eax, edx
+ pop edx
+
+ pop bp
+ASM_END
+}
+
+/**
+ * Extracts a range of bits from a register and shifts them
+ * to the right.
+ */
+static Bit16u ahci_ctrl_extract_bits(u32Reg, u32Mask, u8Shift)
+ Bit32u u32Reg, u32Mask, u8Shift;
+{
+ASM_START
+ push bp
+ mov bp, sp
+
+ push cx
+
+ mov eax, _ahci_ctrl_extract_bits.u32Reg + 2[bp]
+ mov cl, _ahci_ctrl_extract_bits.u8Shift + 2[bp]
+ and eax, _ahci_ctrl_extract_bits.u32Mask + 2[bp]
+ shr eax, cl
+
+ pop cx
+
+ pop bp
+ASM_END
+}
+
+/**
+ * Converts a segment:offset pair into a 32bit physical address.
+ */
+static Bit32u ahci_addr_to_phys(u16Segment, u16Offset)
+ Bit16u u16Segment, u16Offset;
+{
+ASM_START
+ push bp
+ mov bp, sp
+
+ push bx
+ push eax
+
+ xor eax, eax
+ xor ebx, ebx
+ mov ax, _ahci_addr_to_phys.u16Segment + 2[bp]
+ shl eax, #4
+ add bx, _ahci_addr_to_phys.u16Offset + 2[bp]
+ add eax, ebx
+
+ mov bx, ax
+ shr eax, #16
+ mov dx, ax
+
+ pop eax
+ mov ax, bx
+ pop bx
+
+ pop bp
+ASM_END
+}
+
+/**
+ * Issues a command to the SATA controller and waits for completion.
+ */
+static void ahci_port_cmd_sync(SegAhci, u16IoBase, fWrite, fAtapi, cFisDWords, cbData)
+ Bit16u SegAhci;
+ Bit16u u16IoBase;
+ bx_bool fWrite;
+ bx_bool fAtapi;
+ Bit8u cFisDWords;
+ Bit16u cbData;
+{
+ Bit8u u8Port;
+
+ u8Port = read_byte(SegAhci, &AhciData->port);
+
+ if (u8Port != 0xff)
+ {
+ Bit32u u32Val;
+
+ /* Prepare the command header. */
+ u32Val = (1L << 16) | RT_BIT_32(7);
+ if (fWrite)
+ u32Val |= RT_BIT_32(6);
+
+ if (fAtapi)
+ u32Val |= RT_BIT_32(5);
+
+ u32Val |= cFisDWords;
+
+ write_dword(SegAhci, &AhciData->abCmdHdr[0], u32Val);
+ write_dword(SegAhci, &AhciData->abCmdHdr[1], (Bit32u)cbData);
+ write_dword(SegAhci, &AhciData->abCmdHdr[2],
+ ahci_addr_to_phys(SegAhci, &AhciData->abCmd[0]));
+
+ /* Enable Command and FIS receive engine. */
+ ahci_ctrl_set_bits(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
+ AHCI_REG_PORT_CMD_FRE | AHCI_REG_PORT_CMD_ST);
+
+ /* Queue command. */
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_CI, 0x1L);
+
+ /* Wait for a D2H Fis. */
+ while (ahci_ctrl_is_bit_set(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_IS),
+ AHCI_REG_PORT_IS_DHRS) == 0)
+ {
+ VBOXAHCI_DEBUG("AHCI: Waiting for a D2H Fis\n");
+ }
+
+ ahci_ctrl_set_bits(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_IS),
+ AHCI_REG_PORT_IS_DHRS); /* Acknowledge received D2H FIS. */
+
+ /* Disable command engine. */
+ ahci_ctrl_clear_bits(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
+ AHCI_REG_PORT_CMD_ST);
+
+ /** @todo: Examine status. */
+ }
+ else
+ VBOXAHCI_DEBUG("AHCI: Invalid port given\n");
+}
+
+/**
+ * Issue command to device.
+ */
+static void ahci_cmd_data(SegAhci, u16IoBase, u8Cmd, u8Feat, u8Device, u8CylHigh, u8CylLow, u8Sect,
+ u8FeatExp, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp,
+ SegData, OffData, cbData, fWrite)
+ Bit16u SegAhci;
+ Bit16u u16IoBase;
+ Bit8u u8Cmd, u8Feat, u8Device, u8CylHigh, u8CylLow, u8Sect, u8FeatExp,
+ u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp;
+ Bit16u SegData, OffData, cbData;
+ bx_bool fWrite;
+{
+ memsetb(SegAhci, &AhciData->abCmd[0], 0, sizeof(AhciData->abCmd));
+
+ /* Prepare the FIS. */
+ write_byte(SegAhci, &AhciData->abCmd[0], 0x27); /* FIS type H2D. */
+ write_byte(SegAhci, &AhciData->abCmd[1], 1 << 7); /* Command update. */
+ write_byte(SegAhci, &AhciData->abCmd[2], u8Cmd);
+ write_byte(SegAhci, &AhciData->abCmd[3], u8Feat);
+
+ write_byte(SegAhci, &AhciData->abCmd[4], u8Sect);
+ write_byte(SegAhci, &AhciData->abCmd[5], u8CylLow);
+ write_byte(SegAhci, &AhciData->abCmd[6], u8CylHigh);
+ write_byte(SegAhci, &AhciData->abCmd[7], u8Device);
+
+ write_byte(SegAhci, &AhciData->abCmd[8], u8SectExp);
+ write_byte(SegAhci, &AhciData->abCmd[9], u8CylLowExp);
+ write_byte(SegAhci, &AhciData->abCmd[10], u8CylHighExp);
+ write_byte(SegAhci, &AhciData->abCmd[11], u8FeatExp);
+
+ write_byte(SegAhci, &AhciData->abCmd[12], u8SectCount);
+ write_byte(SegAhci, &AhciData->abCmd[13], u8SectCountExp);
+
+ /* Prepare PRDT. */
+ write_dword(SegAhci, &AhciData->abCmd[0x80], ahci_addr_to_phys(SegData, OffData));
+ write_dword(SegAhci, &AhciData->abCmd[0x8c], (Bit32u)(cbData - 1));
+
+ ahci_port_cmd_sync(SegAhci, u16IoBase, fWrite, 0, 5, cbData);
+}
+
+/**
+ * Deinits the curent active port.
+ */
+static void ahci_port_deinit_current(SegAhci, u16IoBase)
+ Bit16u SegAhci;
+ Bit16u u16IoBase;
+{
+ Bit8u u8Port;
+
+ u8Port = read_byte(SegAhci, &AhciData->port);
+
+ if (u8Port != 0xff)
+ {
+ /* Put the port into an idle state. */
+ ahci_ctrl_clear_bits(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
+ AHCI_REG_PORT_CMD_FRE | AHCI_REG_PORT_CMD_ST);
+
+ while (ahci_ctrl_is_bit_set(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
+ AHCI_REG_PORT_CMD_FRE | AHCI_REG_PORT_CMD_ST | AHCI_REG_PORT_CMD_FR | AHCI_REG_PORT_CMD_CR) == 1)
+ {
+ VBOXAHCI_DEBUG("AHCI: Waiting for the port to idle\n");
+ }
+
+ /*
+ * Port idles, set up memory for commands and received FIS and program the
+ * address registers.
+ */
+ memsetb(SegAhci, &AhciData->abFisRecv[0], 0, 0x60);
+ memsetb(SegAhci, &AhciData->abCmdHdr[0], 0, 0x20);
+ memsetb(SegAhci, &AhciData->abCmd[0], 0, 0x84);
+
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_FB, 0L);
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_FBU, 0L);
+
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_CLB, 0L);
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_CLBU, 0L);
+
+ /* Disable all interrupts. */
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_IE, 0L);
+
+ write_byte(SegAhci, &AhciData->port, 0xff);
+ }
+}
+
+/**
+ * Brings a port into a minimal state to make device detection possible
+ * or to queue requests.
+ */
+static void ahci_port_init(SegAhci, u16IoBase, u8Port)
+ Bit16u SegAhci;
+ Bit16u u16IoBase;
+ Bit8u u8Port;
+{
+ Bit32u u32PhysAddr;
+
+ /* Deinit any other port first. */
+ ahci_port_deinit_current(SegAhci, u16IoBase);
+
+ /* Put the port into an idle state. */
+ ahci_ctrl_clear_bits(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
+ AHCI_REG_PORT_CMD_FRE | AHCI_REG_PORT_CMD_ST);
+
+ while (ahci_ctrl_is_bit_set(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
+ AHCI_REG_PORT_CMD_FRE | AHCI_REG_PORT_CMD_ST | AHCI_REG_PORT_CMD_FR | AHCI_REG_PORT_CMD_CR) == 1)
+ {
+ VBOXAHCI_DEBUG("AHCI: Waiting for the port to idle\n");
+ }
+
+ /*
+ * Port idles, set up memory for commands and received FIS and program the
+ * address registers.
+ */
+ memsetb(SegAhci, &AhciData->abFisRecv[0], 0, 0x60);
+ memsetb(SegAhci, &AhciData->abCmdHdr[0], 0, 0x20);
+ memsetb(SegAhci, &AhciData->abCmd[0], 0, 0x84);
+
+ u32PhysAddr = ahci_addr_to_phys(SegAhci, &AhciData->abFisRecv);
+ VBOXAHCI_DEBUG("AHCI: FIS receive area %lx from %x:%x\n", u32PhysAddr, SegAhci, &AhciData->abFisRecv);
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_FB, u32PhysAddr);
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_FBU, 0L);
+
+ u32PhysAddr = ahci_addr_to_phys(SegAhci, &AhciData->abCmdHdr);
+ VBOXAHCI_DEBUG("AHCI: CMD list area %lx\n", u32PhysAddr);
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_CLB, u32PhysAddr);
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_CLBU, 0L);
+
+ /* Disable all interrupts. */
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_IE, 0L);
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_IS, 0xffffffffL);
+ /* Clear all errors. */
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_SERR, 0xffffffffL);
+
+ write_byte(SegAhci, &AhciData->port, u8Port);
+}
+
+/**
+ * Write data to the device.
+ */
+static void ahci_cmd_data_out(SegAhci, u16IoBase, u8Port, u8Cmd, u32Lba, u16Sectors, SegData, OffData)
+ Bit16u SegAhci, u16IoBase;
+ Bit8u u8Port, u8Cmd;
+ Bit32u u32Lba;
+ Bit16u u16Sectors;
+ Bit16u SegData, OffData;
+{
+ Bit8u u8CylLow, u8CylHigh, u8Device, u8Sect, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp;
+
+ u8SectCount = (Bit8u)(u16Sectors & 0xff);
+ u8SectCountExp = (Bit8u)((u16Sectors >> 8) & 0xff);;
+ u8Sect = (Bit8u)(u32Lba & 0xff);
+ u8SectExp = (Bit8u)((u32Lba >> 24) & 0xff);
+ u8CylLow = (Bit8u)((u32Lba >> 8) & 0xff);
+ u8CylLowExp = 0;
+ u8CylHigh = (Bit8u)((u32Lba >> 16) & 0xff);
+ u8CylHighExp = 0;
+ u8Device = (1 << 6); /* LBA access */
+
+ ahci_port_init(SegAhci, u16IoBase, u8Port);
+ ahci_cmd_data(SegAhci, u16IoBase, u8Cmd, 0, u8Device, u8CylHigh, u8CylLow,
+ u8Sect,0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount,
+ u8SectCountExp, SegData, OffData, u16Sectors * 512, 1);
+}
+
+/**
+ * Read data from the device.
+ */
+static void ahci_cmd_data_in(SegAhci, u16IoBase, u8Port, u8Cmd, u32Lba, u16Sectors, SegData, OffData)
+ Bit16u SegAhci, u16IoBase;
+ Bit8u u8Port, u8Cmd;
+ Bit32u u32Lba;
+ Bit16u u16Sectors;
+ Bit16u SegData, OffData;
+{
+ Bit8u u8CylLow, u8CylHigh, u8Device, u8Sect, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp;
+
+ u8SectCount = (Bit8u)(u16Sectors & 0xff);
+ u8SectCountExp = (Bit8u)((u16Sectors >> 8) & 0xff);;
+ u8Sect = (Bit8u)(u32Lba & 0xff);
+ u8SectExp = (Bit8u)((u32Lba >> 24) & 0xff);
+ u8CylLow = (Bit8u)((u32Lba >> 8) & 0xff);
+ u8CylLowExp = 0;
+ u8CylHigh = (Bit8u)((u32Lba >> 16) & 0xff);
+ u8CylHighExp = 0;
+
+ u8Device = (1 << 6); /* LBA access */
+
+ ahci_port_init(SegAhci, u16IoBase, u8Port);
+ ahci_cmd_data(SegAhci, u16IoBase, u8Cmd, 0, u8Device, u8CylHigh, u8CylLow,
+ u8Sect, 0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount,
+ u8SectCountExp, SegData, OffData, u16Sectors * 512, 0);
+}
+
+static void ahci_port_detect_device(SegAhci, u16IoBase, u8Port)
+ Bit16u SegAhci;
+ Bit16u u16IoBase;
+ Bit8u u8Port;
+{
+ Bit32u val;
+
+ ahci_port_init(SegAhci, u16IoBase, u8Port);
+
+ /* Reset connection. */
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_SCTL, 0x01L);
+ /*
+ * According to the spec we should wait at least 1msec until the reset
+ * is cleared but this is a virtual controller so we don't have to.
+ */
+ VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_SCTL, 0x00L);
+
+ /* Check if there is a device on the port. */
+ VBOXAHCI_PORT_READ_REG(u16IoBase, u8Port, AHCI_REG_PORT_SSTS, val);
+ if (ahci_ctrl_extract_bits(val, 0xfL, 0) == 0x3L)
+ {
+ Bit8u idxDevice;
+
+ idxDevice = read_byte(SegAhci, &AhciData->cDevices);
+ VBOXAHCI_DEBUG("AHCI: Device detected on port %d\n", u8Port);
+
+ if (idxDevice < AHCI_MAX_STORAGE_DEVICES)
+ {
+ /* Device detected, enable FIS receive. */
+ ahci_ctrl_set_bits(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
+ AHCI_REG_PORT_CMD_FRE);
+
+ /* Check signature to determine device type. */
+ VBOXAHCI_PORT_READ_REG(u16IoBase, u8Port, AHCI_REG_PORT_SIG, val);
+ if (val == 0x101L)
+ {
+ Bit8u idxHdCurr;
+ Bit32u cSectors;
+ Bit8u abBuffer[0x0200];
+ Bit8u fRemovable;
+ Bit16u cCylinders, cHeads, cSectorsPerTrack;
+ Bit8u cHardDisksOld;
+ Bit8u idxCmosChsBase;
+
+ idxHdCurr = read_byte(SegAhci, &AhciData->cHardDisks);
+ VBOXAHCI_DEBUG("AHCI: Detected hard disk\n");
+
+ /* Identify device. */
+ ahci_cmd_data(SegAhci, u16IoBase, ATA_CMD_IDENTIFY_DEVICE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, get_SS(), abBuffer, sizeof(abBuffer), 0);
+
+ write_byte(SegAhci, &AhciData->aDevices[idxDevice].port, u8Port);
+
+ fRemovable = (read_byte(get_SS(),abBuffer+0) & 0x80) ? 1 : 0;
+ cCylinders = read_word(get_SS(),abBuffer+(1*2)); // word 1
+ cHeads = read_word(get_SS(),abBuffer+(3*2)); // word 3
+ cSectorsPerTrack = read_word(get_SS(),abBuffer+(6*2)); // word 6
+ cSectors = read_dword(get_SS(),abBuffer+(60*2)); // word 60 and word 61
+
+ /** @todo update sectors to be a 64 bit number (also lba...). */
+ if (cSectors == 268435455)
+ cSectors = read_dword(get_SS(),abBuffer+(100*2)); // words 100 to 103 (someday)
+
+ VBOXAHCI_DEBUG("AHCI: %ld sectors\n", cSectors);
+
+ write_byte(SegAhci, &AhciData->aDevices[idxDevice].device,ATA_DEVICE_HD);
+ write_byte(SegAhci, &AhciData->aDevices[idxDevice].removable, fRemovable);
+ write_word(SegAhci, &AhciData->aDevices[idxDevice].blksize, 512);
+ write_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.heads, cHeads);
+ write_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.cylinders, cCylinders);
+ write_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.spt, cSectorsPerTrack);
+ write_dword(SegAhci, &AhciData->aDevices[idxDevice].cSectors, cSectors);
+
+ /* Get logical CHS geometry. */
+ switch (idxDevice)
+ {
+ case 0:
+ idxCmosChsBase = 0x40;
+ break;
+ case 1:
+ idxCmosChsBase = 0x48;
+ break;
+ case 2:
+ idxCmosChsBase = 0x50;
+ break;
+ case 3:
+ idxCmosChsBase = 0x58;
+ break;
+ default:
+ idxCmosChsBase = 0;
+ }
+ if (idxCmosChsBase != 0)
+ {
+ cCylinders = inb_cmos(idxCmosChsBase) + (inb_cmos(idxCmosChsBase+1) << 8);
+ cHeads = inb_cmos(idxCmosChsBase+2);
+ cSectorsPerTrack = inb_cmos(idxCmosChsBase+7);
+ }
+ else
+ {
+ cCylinders = 0;
+ cHeads = 0;
+ cSectorsPerTrack = 0;
+ }
+ write_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.heads, cHeads);
+ write_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.cylinders, cCylinders);
+ write_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.spt, cSectorsPerTrack);
+
+ write_byte(SegAhci, &AhciData->aHdIdMap[idxHdCurr], idxDevice);
+ idxHdCurr++;
+ write_byte(SegAhci, &AhciData->cHardDisks, idxHdCurr);
+
+ /* Update hdcount in the BDA. */
+ cHardDisksOld = read_byte(0x40, 0x75);
+ cHardDisksOld++;
+ write_byte(0x40, 0x75, cHardDisksOld);
+ }
+ else if (val == 0xeb140101)
+ {
+ VBOXAHCI_DEBUG("AHCI: Detected ATAPI device\n");
+ }
+ else
+ VBOXAHCI_DEBUG("AHCI: Unknown device ignoring\n");
+
+ idxDevice++;
+ write_byte(SegAhci, &AhciData->cDevices, idxDevice);
+ }
+ else
+ VBOXAHCI_DEBUG("AHCI: Reached maximum device count, skipping\n");
+ }
+}
+
+#define SET_DISK_RET_STATUS(status) write_byte(0x0040, 0x0074, status)
+
+/**
+ * Int 13 handler.
+ */
+static void ahci_int13(RET, ES, DS, DI, SI, BP, SP, BX, DX, CX, AX, IPIRET, CSIRET, FLAGSIRET, IP, CS, FLAGS)
+ Bit16u RET, ES, DS, AX, CX, DX, BX, SP, BP, SI, DI, IPIRET, CSIRET, FLAGSIRET, IP, CS, FLAGS;
+{
+ Bit16u ebda_seg;
+ Bit16u SegAhci, u16IoBase;
+ Bit8u idxDevice;
+ Bit8u cHardDisksOld;
+ Bit8u u8Port;
+
+ Bit32u lba;
+ Bit16u cylinder, head, sector;
+ Bit16u segment, offset;
+ Bit16u npc, nph, npspt, nlc, nlh, nlspt;
+ Bit16u size, count;
+ Bit8u status;
+
+ VBOXAHCI_INT13_DEBUG("AHCI: ahci_int13 AX=%x CX=%x DX=%x BX=%x SP=%x BP=%x SI=%x DI=%x IP=%x CS=%x FLAGS=%x\n",
+ AX, CX, DX, BX, SP, BP, SI, DI, IP, CS, FLAGS);
+
+ ebda_seg = read_word(0x0040, 0x000E);
+ SegAhci = read_word(ebda_seg, &EbdaData->SegAhci);
+ u16IoBase = read_word(SegAhci, &AhciData->iobase);
+ VBOXAHCI_INT13_DEBUG("AHCI: ahci_int13: SegAhci=%x u16IoBase=%x\n", SegAhci, u16IoBase);
+
+ cHardDisksOld = read_byte(SegAhci, &AhciData->cHardDisksOld);
+
+ /* Check if the device is controlled by us first. */
+ if ( (GET_DL() < 0x80)
+ || (GET_DL() < 0x80 + cHardDisksOld)
+ || ((GET_DL() & 0xe0) != 0x80) /* No CD-ROM drives supported for now */)
+ {
+ VBOXAHCI_INT13_DEBUG("AHCI: ahci_int13 device not controlled by us, forwarding to old handler (%d)\n", cHardDisksOld);
+ /* Fill the iret frame to jump to the old handler. */
+ IPIRET = read_word(SegAhci, &AhciData->pfnInt13Old);
+ CSIRET = 0xf000;
+ FLAGSIRET = FLAGS;
+ RET = 1;
+ return;
+ }
+
+ idxDevice = read_byte(SegAhci, &AhciData->aHdIdMap[GET_DL()-0x80-cHardDisksOld]);
+
+ if (idxDevice >= AHCI_MAX_STORAGE_DEVICES)
+ {
+ VBOXAHCI_INT13_DEBUG("AHCI: ahci_int13: function %02x, unmapped device for ELDL=%02x\n", GET_AH(), GET_DL());
+ goto ahci_int13_fail;
+ }
+
+ u8Port = read_byte(SegAhci, &AhciData->aDevices[idxDevice].port);
+
+ switch (GET_AH())
+ {
+ case 0x00: /* disk controller reset */
+ {
+ /** @todo: not really important I think. */
+ goto ahci_int13_success;
+ break;
+ }
+ case 0x01: /* read disk status */
+ {
+ status = read_byte(0x0040, 0x0074);
+ SET_AH(status);
+ SET_DISK_RET_STATUS(0);
+ /* set CF if error status read */
+ if (status)
+ goto ahci_int13_fail_nostatus;
+ else
+ goto ahci_int13_success_noah;
+ break;
+ }
+ case 0x02: // read disk sectors
+ case 0x03: // write disk sectors
+ case 0x04: // verify disk sectors
+ {
+ count = GET_AL();
+ cylinder = GET_CH();
+ cylinder |= ( ((Bit16u) GET_CL()) << 2) & 0x300;
+ sector = (GET_CL() & 0x3f);
+ head = GET_DH();
+
+ segment = ES;
+ offset = BX;
+
+ if ( (count > 128) || (count == 0) )
+ {
+ BX_INFO("int13_harddisk: function %02x, count out of range!\n",GET_AH());
+ goto ahci_int13_fail;
+ }
+
+ nlc = read_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.cylinders);
+ nlh = read_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.heads);
+ nlspt = read_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.spt);
+
+ // sanity check on cyl heads, sec
+ if( (cylinder >= nlc) || (head >= nlh) || (sector > nlspt ))
+ {
+ BX_INFO("ahci_int13: function %02x, disk %02x, parameters out of range %04x/%04x/%04x!\n", GET_AH(), GET_DL(), cylinder, head, sector);
+ goto ahci_int13_fail;
+ }
+
+ // FIXME verify
+ if ( GET_AH() == 0x04 )
+ goto ahci_int13_success;
+
+ lba = ((((Bit32u)cylinder * (Bit32u)nlh) + (Bit32u)head) * (Bit32u)nlspt) + (Bit32u)sector - 1;
+
+ status = 0;
+ if ( GET_AH() == 0x02 )
+ ahci_cmd_data_in(SegAhci, u16IoBase, u8Port, AHCI_CMD_READ_DMA_EXT, lba, count, segment, offset);
+ else
+ ahci_cmd_data_out(SegAhci, u16IoBase, u8Port, AHCI_CMD_WRITE_DMA_EXT, lba, count, segment, offset);
+
+ // Set nb of sector transferred
+ SET_AL(read_word(ebda_seg, &EbdaData->ata.trsfsectors));
+
+ if (status != 0)
+ {
+ BX_INFO("int13_harddisk: function %02x, error %02x !\n",GET_AH(),status);
+ SET_AH(0x0c);
+ goto ahci_int13_fail_noah;
+ }
+
+ goto ahci_int13_success;
+ break;
+ }
+ case 0x05: /* format disk track */
+ BX_INFO("format disk track called\n");
+ goto ahci_int13_success;
+ break;
+ case 0x08: /* read disk drive parameters */
+ {
+ // Get logical geometry from table
+ nlc = read_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.cylinders);
+ nlh = read_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.heads);
+ nlspt = read_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.spt);
+
+ count = read_byte(SegAhci, &AhciData->cHardDisks); /** @todo correct? */
+ /* Maximum cylinder number is just one less than the number of cylinders. */
+ nlc = nlc - 1; /* 0 based , last sector not used */
+ SET_AL(0);
+ SET_CH(nlc & 0xff);
+ SET_CL(((nlc >> 2) & 0xc0) | (nlspt & 0x3f));
+ SET_DH(nlh - 1);
+ SET_DL(count); /* FIXME returns 0, 1, or n hard drives */
+ // FIXME should set ES & DI
+ goto ahci_int13_success;
+ break;
+ }
+ case 0x10: /* check drive ready */
+ {
+ /** @todo */
+ goto ahci_int13_success;
+ break;
+ }
+ case 0x15: /* read disk drive size */
+ {
+ // Get physical geometry from table
+ npc = read_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.cylinders);
+ nph = read_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.heads);
+ npspt = read_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.spt);
+
+ // Compute sector count seen by int13
+ lba = (Bit32u)npc * (Bit32u)nph * (Bit32u)npspt;
+ CX = lba >> 16;
+ DX = lba & 0xffff;
+
+ SET_AH(3); // hard disk accessible
+ goto ahci_int13_success_noah;
+ break;
+ }
+#if 0
+ case 0x41: // IBM/MS installation check
+ {
+ BX=0xaa55; // install check
+ SET_AH(0x30); // EDD 3.0
+ CX=0x0007; // ext disk access and edd, removable supported
+ goto ahci_int13_success_noah;
+ break;
+ }
+ case 0x42: // IBM/MS extended read
+ case 0x43: // IBM/MS extended write
+ case 0x44: // IBM/MS verify
+ case 0x47: // IBM/MS extended seek
+ {
+ count=read_word(DS, SI+(Bit16u)&Int13Ext->count);
+ segment=read_word(DS, SI+(Bit16u)&Int13Ext->segment);
+ offset=read_word(DS, SI+(Bit16u)&Int13Ext->offset);
+
+ // Can't use 64 bits lba
+ lba=read_dword(DS, SI+(Bit16u)&Int13Ext->lba2);
+ if (lba != 0L)
+ {
+ BX_PANIC("int13_harddisk: function %02x. Can't use 64bits lba\n",GET_AH());
+ goto ahci_int13_fail;
+ }
+
+ // Get 32 bits lba and check
+ lba=read_dword(DS, SI+(Bit16u)&Int13Ext->lba1);
+
+ if (lba >= read_word(SegAhci, &AhciData->aDevices[idxDevice].cSectors) )
+ {
+ BX_INFO("int13_harddisk: function %02x. LBA out of range\n",GET_AH());
+ goto ahci_int13_fail;
+ }
+
+ // If verify or seek
+ if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 ))
+ goto ahci_int13_success;
+
+ // Execute the command
+ if ( GET_AH() == 0x42 )
+ {
+ if (lba + count >= 268435456)
+ status=ata_cmd_data_in(device, ATA_CMD_READ_SECTORS_EXT, count, 0, 0, 0, lba, segment, offset);
+ else
+ {
+ write_word(ebda_seg,&EbdaData->ata.devices[device].blksize,count * 0x200);
+ status=ata_cmd_data_in(device, ATA_CMD_READ_MULTIPLE, count, 0, 0, 0, lba, segment, offset);
+ write_word(ebda_seg,&EbdaData->ata.devices[device].blksize,0x200);
+ }
+ }
+ else
+ {
+ if (lba + count >= 268435456)
+ status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS_EXT, count, 0, 0, 0, lba, segment, offset);
+ else
+ status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS, count, 0, 0, 0, lba, segment, offset);
+ }
+
+ count=read_word(ebda_seg, &EbdaData->ata.trsfsectors);
+ write_word(DS, SI+(Bit16u)&Int13Ext->count, count);
+
+ if (status != 0)
+ {
+ BX_INFO("int13_harddisk: function %02x, error %02x !\n",GET_AH(),status);
+ SET_AH(0x0c);
+ goto ahci_int13_fail_noah;
+ }
+ goto ahci_int13_success;
+ break;
+ }
+ case 0x45: // IBM/MS lock/unlock drive
+ case 0x49: // IBM/MS extended media change
+ goto ahci_int13_success; // Always success for HD
+ break;
+ case 0x46: // IBM/MS eject media
+ SET_AH(0xb2); // Volume Not Removable
+ goto ahci_int13_fail_noah; // Always fail for HD
+ break;
+
+ case 0x48: // IBM/MS get drive parameters
+ size=read_word(DS,SI+(Bit16u)&Int13DPT->size);
+
+ // Buffer is too small
+ if(size < 0x1a)
+ goto ahci_int13_fail;
+
+ // EDD 1.x
+ if(size >= 0x1a)
+ {
+ Bit16u blksize;
+
+ npc = read_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.cylinders);
+ nph = read_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.heads);
+ npspt = read_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.spt);
+ lba = read_dword(SegAhci, &AhciData->aDevices[idxDevice].cSectors);
+ blksize = read_word(SegAhci, &AhciData->aDevices[idxDevice].blksize);
+
+ write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x1a);
+ write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x02); // geometry is valid
+ write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, (Bit32u)npc);
+ write_dword(DS, SI+(Bit16u)&Int13DPT->heads, (Bit32u)nph);
+ write_dword(DS, SI+(Bit16u)&Int13DPT->spt, (Bit32u)npspt);
+ write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count1, lba); // FIXME should be Bit64
+ write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count2, 0L);
+ write_word(DS, SI+(Bit16u)&Int13DPT->blksize, blksize);
+ }
+
+#if 0 /* Disable EDD 2.X and 3.x for now, don't know if it is required by any OS loader yet */
+ // EDD 2.x
+ if(size >= 0x1e)
+ {
+ Bit8u channel, dev, irq, mode, checksum, i, translation;
+ Bit16u iobase1, iobase2, options;
+
+ translation = ATA_TRANSLATION_LBA;
+
+ write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x1e);
+
+ write_word(DS, SI+(Bit16u)&Int13DPT->dpte_segment, ebda_seg);
+ write_word(DS, SI+(Bit16u)&Int13DPT->dpte_offset, &EbdaData->ata.dpte);
+
+ // Fill in dpte
+ channel = device / 2;
+ iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1);
+ iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2);
+ irq = read_byte(ebda_seg, &EbdaData->ata.channels[channel].irq);
+ mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode);
+ translation = read_byte(ebda_seg, &EbdaData->ata.devices[device].translation);
+
+ options = (translation==ATA_TRANSLATION_NONE?0:1<<3); // chs translation
+ options |= (1<<4); // lba translation
+ options |= (mode==ATA_MODE_PIO32?1:0<<7);
+ options |= (translation==ATA_TRANSLATION_LBA?1:0<<9);
+ options |= (translation==ATA_TRANSLATION_RECHS?3:0<<9);
+
+ write_word(ebda_seg, &EbdaData->ata.dpte.iobase1, iobase1);
+ write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2);
+ //write_byte(ebda_seg, &EbdaData->ata.dpte.prefix, (0xe | /*(device % 2))<<4*/ );
+ write_byte(ebda_seg, &EbdaData->ata.dpte.unused, 0xcb );
+ write_byte(ebda_seg, &EbdaData->ata.dpte.irq, irq );
+ write_byte(ebda_seg, &EbdaData->ata.dpte.blkcount, 1 );
+ write_byte(ebda_seg, &EbdaData->ata.dpte.dma, 0 );
+ write_byte(ebda_seg, &EbdaData->ata.dpte.pio, 0 );
+ write_word(ebda_seg, &EbdaData->ata.dpte.options, options);
+ write_word(ebda_seg, &EbdaData->ata.dpte.reserved, 0);
+ write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x11);
+
+ checksum=0;
+ for (i=0; i<15; i++)
+ checksum+=read_byte(ebda_seg, (&EbdaData->ata.dpte) + i);
+
+ checksum = -checksum;
+ write_byte(ebda_seg, &EbdaData->ata.dpte.checksum, checksum);
+ }
+
+ // EDD 3.x
+ if(size >= 0x42)
+ {
+ Bit8u channel, iface, checksum, i;
+ Bit16u iobase1;
+
+ channel = device / 2;
+ iface = read_byte(ebda_seg, &EbdaData->ata.channels[channel].iface);
+ iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1);
+
+ write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x42);
+ write_word(DS, SI+(Bit16u)&Int13DPT->key, 0xbedd);
+ write_byte(DS, SI+(Bit16u)&Int13DPT->dpi_length, 0x24);
+ write_byte(DS, SI+(Bit16u)&Int13DPT->reserved1, 0);
+ write_word(DS, SI+(Bit16u)&Int13DPT->reserved2, 0);
+
+ if (iface==ATA_IFACE_ISA) {
+ write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[0], 'I');
+ write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[1], 'S');
+ write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[2], 'A');
+ write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[3], 0);
+ }
+ else {
+ // FIXME PCI
+ }
+ write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[0], 'A');
+ write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[1], 'T');
+ write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[2], 'A');
+ write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[3], 0);
+
+ if (iface==ATA_IFACE_ISA) {
+ write_word(DS, SI+(Bit16u)&Int13DPT->iface_path[0], iobase1);
+ write_word(DS, SI+(Bit16u)&Int13DPT->iface_path[2], 0);
+ write_dword(DS, SI+(Bit16u)&Int13DPT->iface_path[4], 0L);
+ }
+ else {
+ // FIXME PCI
+ }
+ //write_byte(DS, SI+(Bit16u)&Int13DPT->device_path[0], device%2);
+ write_byte(DS, SI+(Bit16u)&Int13DPT->device_path[1], 0);
+ write_word(DS, SI+(Bit16u)&Int13DPT->device_path[2], 0);
+ write_dword(DS, SI+(Bit16u)&Int13DPT->device_path[4], 0L);
+
+ checksum=0;
+ for (i=30; i<64; i++) checksum+=read_byte(DS, SI + i);
+ checksum = -checksum;
+ write_byte(DS, SI+(Bit16u)&Int13DPT->checksum, checksum);
+ }
+#endif
+ goto ahci_int13_success;
+ break;
+ case 0x4e: // // IBM/MS set hardware configuration
+ // DMA, prefetch, PIO maximum not supported
+ switch (GET_AL())
+ {
+ case 0x01:
+ case 0x03:
+ case 0x04:
+ case 0x06:
+ goto ahci_int13_success;
+ break;
+ default :
+ goto ahci_int13_fail;
+ }
+ break;
+#endif
+ case 0x09: /* initialize drive parameters */
+ case 0x0c: /* seek to specified cylinder */
+ case 0x0d: /* alternate disk reset */
+ case 0x11: /* recalibrate */
+ case 0x14: /* controller internal diagnostic */
+ BX_INFO("ahci_int13: function %02xh unimplemented, returns success\n", GET_AH());
+ goto ahci_int13_success;
+ break;
+
+ case 0x0a: /* read disk sectors with ECC */
+ case 0x0b: /* write disk sectors with ECC */
+ case 0x18: // set media type for format
+ case 0x50: // IBM/MS send packet command
+ default:
+ BX_INFO("ahci_int13: function %02xh unsupported, returns fail\n", GET_AH());
+ goto ahci_int13_fail;
+ break;
+ }
+
+ahci_int13_fail:
+ SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
+ahci_int13_fail_noah:
+ SET_DISK_RET_STATUS(GET_AH());
+ahci_int13_fail_nostatus:
+ SET_CF(); // error occurred
+ return;
+
+ahci_int13_success:
+ SET_AH(0x00); // no error
+ahci_int13_success_noah:
+ SET_DISK_RET_STATUS(0x00);
+ CLEAR_CF(); // no error
+ return;
+}
+
+#undef SET_DISK_RET_STATUS
+
+/**
+ * Assembler part of the int 13 handler.
+ */
+ASM_START
+ahci_int13_handler:
+ ; Allocate space for an iret frame we have to use
+ ; to call the old int 13 handler
+ push #0x0000
+ push #0x0000
+ push #0x0000
+
+ pusha ; Save 16bit values as arguments
+ push ds
+ push es
+ mov ax, #0 ; Allocate room for the return value on the stack
+ push ax
+ call _ahci_int13
+ pop ax
+ pop es
+ pop ds
+ cmp ax, #0x0 ; Check if the handler processed the request
+ je ahci_int13_out
+ popa ; Restore the caller environment
+ iret ; Call the old interrupt handler. Will not come back here.
+
+ahci_int13_out:
+ popa
+ add sp, #6 ; Destroy the iret frame
+ iret
+ASM_END
+
+/**
+ * Install the in13 interrupt handler
+ * preserving the previous one.
+ */
+static void ahci_install_int_handler(SegAhci)
+ Bit16u SegAhci;
+{
+
+ Bit16u pfnInt13Old;
+
+ VBOXAHCI_DEBUG("AHCI: Hooking int 13h vector\n");
+
+ /* Read the old interrupt handler. */
+ pfnInt13Old = read_word(0x0000, 0x0013*4);
+ write_word(SegAhci, &AhciData->pfnInt13Old, pfnInt13Old);
+
+ /* Set our own */
+ ASM_START
+
+ push bp
+ mov bp, sp
+
+ push ax
+ SET_INT_VECTOR(0x13, #0xF000, #ahci_int13_handler)
+ pop ax
+
+ pop bp
+ ASM_END
+}
+
+/**
+ * Allocates 1K from the base memory.
+ */
+static Bit16u ahci_mem_alloc()
+{
+ Bit16u cBaseMem1K;
+ Bit16u SegStart;
+
+ cBaseMem1K = read_byte(0x00, 0x0413);
+
+ VBOXAHCI_DEBUG("AHCI: %x K of base memory available\n", cBaseMem1K);
+
+ if (cBaseMem1K == 0)
+ return 0;
+
+ cBaseMem1K--; /* Allocate one block. */
+ SegStart = (Bit16u)(((Bit32u)cBaseMem1K * 1024) >> 4); /* Calculate start segment. */
+
+ write_byte(0x00, 0x0413, cBaseMem1K);
+
+ return SegStart;
+}
+
+/**
+ * Initializes the SATA controller and detects attached devices.
+ */
+static int ahci_ctrl_init(u16IoBase)
+ Bit16u u16IoBase;
+{
+ Bit8u i, cPorts;
+ Bit32u val;
+ Bit16u ebda_seg;
+ Bit16u SegAhci;
+
+ ebda_seg = read_word(0x0040, 0x000E);
+
+ VBOXAHCI_READ_REG(u16IoBase, AHCI_REG_VS, val);
+ VBOXAHCI_DEBUG("AHCI: Controller has version: 0x%x (major) 0x%x (minor)\n",
+ ahci_ctrl_extract_bits(val, 0xffff0000, 16),
+ ahci_ctrl_extract_bits(val, 0x0000ffff, 0));
+
+ /* Allocate 1K of base memory. */
+ SegAhci = ahci_mem_alloc();
+ if (SegAhci == 0)
+ {
+ VBOXAHCI_DEBUG("AHCI: Could not allocate 1K of memory, can't boot from controller\n");
+ return 0;
+ }
+
+ write_word(ebda_seg, &EbdaData->SegAhci, SegAhci);
+ write_byte(SegAhci, &AhciData->port, 0xff);
+ write_word(SegAhci, &AhciData->iobase, u16IoBase);
+ write_byte(SegAhci, &AhciData->cHardDisksOld, read_byte(0x40, 0x75));
+
+ /* Reset the controller. */
+ ahci_ctrl_set_bits(u16IoBase, AHCI_REG_GHC, AHCI_GHC_HR);
+ do
+ {
+ VBOXAHCI_READ_REG(u16IoBase, AHCI_REG_GHC, val);
+ } while (val & AHCI_GHC_HR != 0);
+
+ VBOXAHCI_READ_REG(u16IoBase, AHCI_REG_CAP, val);
+ cPorts = ahci_ctrl_extract_bits(val, 0x1f, 0) + 1; /* Extract number of ports.*/
+
+ VBOXAHCI_DEBUG("AHCI: Controller has %u ports\n", cPorts);
+
+ /* Go through the ports. */
+ i = 0;
+ while (i < 32)
+ {
+ if (ahci_ctrl_is_bit_set(u16IoBase, AHCI_REG_PI, RT_BIT_32(i)) != 0)
+ {
+ VBOXAHCI_DEBUG("AHCI: Port %u is present\n", i);
+ ahci_port_detect_device(SegAhci, u16IoBase, i);
+ cPorts--;
+ if (cPorts == 0)
+ break;
+ }
+ i++;
+ }
+
+ if (read_byte(SegAhci, &AhciData->cDevices) > 0)
+ {
+ /*
+ * Init completed and there is at least one device present.
+ * Install our int13 handler.
+ */
+ ahci_install_int_handler(SegAhci);
+ }
+
+ return 0;
+}
+
+/**
+ * Init the AHCI driver and detect attached disks.
+ */
+void ahci_init( )
+{
+ Bit16u ebda_seg;
+ Bit16u busdevfn;
+
+ ebda_seg = read_word(0x0040, 0x000E);
+
+ busdevfn = ahci_pci_find_classcode(0x00010601);
+ if (busdevfn != VBOX_AHCI_NO_DEVICE)
+ {
+ Bit8u u8Bus, u8DevFn;
+ Bit8u u8PciCapOff;
+
+ u8Bus = (busdevfn & 0xff00) >> 8;
+ u8DevFn = busdevfn & 0x00ff;
+
+ VBOXAHCI_DEBUG("Found AHCI controller at Bus %u DevFn 0x%x (raw 0x%x)\n", u8Bus, u8DevFn, busdevfn);
+
+ /* Examine the capability list and search for the Serial ATA Capability Register. */
+ u8PciCapOff = ahci_pci_read_config_byte(u8Bus, u8DevFn, PCI_CONFIG_CAP);
+
+ while (u8PciCapOff != 0)
+ {
+ Bit8u u8PciCapId = ahci_pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff);
+
+ VBOXAHCI_DEBUG("Capability ID 0x%x at offset 0x%x found\n", u8PciCapId, u8PciCapOff);
+
+ if (u8PciCapId == PCI_CAP_ID_SATACR)
+ break;
+
+ /* Go on to the next capability. */
+ u8PciCapOff = ahci_pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff + 1);
+ }
+
+ if (u8PciCapOff != 0)
+ {
+ Bit8u u8Rev;
+
+ VBOXAHCI_DEBUG("AHCI controller with SATA Capability register at offset 0x%x found\n", u8PciCapOff);
+
+ /* Advance to the stuff behind the id and next capability pointer. */
+ u8PciCapOff += 2;
+
+ u8Rev = ahci_pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff);
+ if (u8Rev == 0x10)
+ {
+ /* Read the SATACR1 register and get the bar and offset of the index/data pair register. */
+ Bit8u u8Bar = 0x00;
+ Bit16u u16Off = 0x00;
+ Bit16u u16BarOff = ahci_pci_read_config_word(u8Bus, u8DevFn, u8PciCapOff + 2);
+
+ VBOXAHCI_DEBUG("SATACR1 register contains 0x%x\n", u16BarOff);
+
+ switch (u16BarOff & 0xf)
+ {
+ case 0x04:
+ u8Bar = 0x10;
+ break;
+ case 0x05:
+ u8Bar = 0x14;
+ break;
+ case 0x06:
+ u8Bar = 0x18;
+ break;
+ case 0x07:
+ u8Bar = 0x1c;
+ break;
+ case 0x08:
+ u8Bar = 0x20;
+ break;
+ case 0x09:
+ u8Bar = 0x24;
+ break;
+ case 0x0f:
+ default:
+ /* Reserved or unsupported. */
+ VBOXAHCI_DEBUG("BAR location 0x%x is unsupported\n", u16BarOff & 0xf);
+ }
+
+ /* Get the offset inside the BAR from bits 4:15. */
+ u16Off = (u16BarOff >> 4) * 4;
+
+ if (u8Bar != 0x00)
+ {
+ Bit32u u32Bar = ahci_pci_read_config_dword(u8Bus, u8DevFn, u8Bar);
+
+ VBOXAHCI_DEBUG("BAR at offset 0x%x contains 0x%x\n", u8Bar, u32Bar);
+
+ if ((u32Bar & 0x01) != 0)
+ {
+ int rc;
+ Bit16u u16AhciIoBase = (u32Bar & 0xfff0) + u16Off;
+
+ VBOXAHCI_DEBUG("I/O base is 0x%x\n", u16AhciIoBase);
+ rc = ahci_ctrl_init(u16AhciIoBase);
+ }
+ else
+ VBOXAHCI_DEBUG("BAR is MMIO\n");
+ }
+ }
+ else
+ VBOXAHCI_DEBUG("Invalid revision 0x%x\n", u8Rev);
+ }
+ else
+ VBOXAHCI_DEBUG("AHCI controller without usable Index/Data register pair found\n");
+ }
+ else
+ VBOXAHCI_DEBUG("No AHCI controller found\n");
+}
+
diff --git a/src/VBox/Devices/PC/BIOS/logo.c b/src/VBox/Devices/PC/BIOS/logo.c
index 1bace9174..afc1bdd15 100644
--- a/src/VBox/Devices/PC/BIOS/logo.c
+++ b/src/VBox/Devices/PC/BIOS/logo.c
@@ -1,4 +1,4 @@
-/* $Id: logo.c $ */
+/* $Id: logo.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Stuff for drawing the BIOS logo.
*/
diff --git a/src/VBox/Devices/PC/BIOS/rombios.c b/src/VBox/Devices/PC/BIOS/rombios.c
index 8d2eac282..f85947935 100644
--- a/src/VBox/Devices/PC/BIOS/rombios.c
+++ b/src/VBox/Devices/PC/BIOS/rombios.c
@@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
-// $Id: rombios.c $
+// $Id: rombios.c,v 1.176 2006/12/30 17:13:17 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@@ -805,6 +805,11 @@ typedef struct {
scsi_t scsi;
# endif
+#ifdef VBOX_WITH_BIOS_AHCI
+ // AHCI driver data segment;
+ Bit16u SegAhci;
+#endif
+
unsigned char uForceBootDrive;
unsigned char uForceBootDevice;
#endif /* VBOX */
@@ -927,7 +932,13 @@ static Bit8u inb_cmos();
static void outb();
static void outb_cmos();
static Bit16u inw();
+#ifdef VBOX_WITH_BIOS_AHCI
+static Bit32u inl();
+#endif
static void outw();
+#ifdef VBOX_WITH_BIOS_AHCI
+static void outl();
+#endif
static void init_rtc();
static bx_bool rtc_updating();
@@ -1264,6 +1275,29 @@ ASM_END
}
#endif
+#ifdef VBOX_WITH_BIOS_AHCI
+ Bit32u
+inl(port)
+ Bit16u port;
+{
+ASM_START
+ push bp
+ mov bp, sp
+
+ push bx
+ mov dx, 4[bp]
+ in eax, dx
+ mov bx, ax ; Save lower 16 bits
+ shr eax, #16
+ mov dx, ax
+ mov ax, bx
+ pop bx
+
+ pop bp
+ASM_END
+}
+#endif
+
void
outb(port, val)
Bit16u port;
@@ -1308,6 +1342,29 @@ ASM_END
}
#endif
+#ifdef VBOX_WITH_BIOS_AHCI
+ void
+outl(port, val)
+ Bit16u port;
+ Bit32u val;
+{
+ASM_START
+ push bp
+ mov bp, sp
+
+ push eax
+ push dx
+ mov dx, _outl.port + 2[bp]
+ mov eax, _outl.val + 2[bp]
+ out dx, eax
+ pop dx
+ pop eax
+
+ pop bp
+ASM_END
+}
+#endif
+
void
outb_cmos(cmos_reg, val)
Bit8u cmos_reg;
@@ -1783,12 +1840,12 @@ keyboard_init()
while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00);
/* flush incoming keys */
- max=0x2000;
+ max=4;
while (--max > 0) {
outb(0x80, 0x00);
if (inb(0x64) & 0x01) {
inb(0x60);
- max = 0x2000;
+ max = 4;
}
}
@@ -2507,6 +2564,7 @@ void ata_detect( )
case 3:
chsgeo_base = 0x70;
break;
+#ifndef VBOX_WITH_BIOS_AHCI
case 4:
chsgeo_base = 0x40;
break;
@@ -2519,6 +2577,7 @@ void ata_detect( )
case 7:
chsgeo_base = 0x58;
break;
+#endif
default:
chsgeo_base = 0;
}
@@ -2572,7 +2631,7 @@ void ata_detect( )
sum = 0;
for (i = 0; i < 0xf; i++)
sum += read_byte(ebda_seg, fdpt + i);
- sum = 1 - sum;
+ sum = -sum;
write_byte(ebda_seg, fdpt + 0x0f, sum);
}
#else /* !VBOX */
@@ -2672,6 +2731,9 @@ void ata_detect( )
cdcount++;
}
+#ifdef VBOX
+ // we don't want any noisy output for now
+#else /* !VBOX */
{
Bit32u sizeinmb;
Bit16u ataversion;
@@ -2705,9 +2767,6 @@ void ata_detect( )
break;
}
-#ifdef VBOX
- // we don't want any noisy output for now
-#else /* !VBOX */
switch (type) {
case ATA_TYPE_ATA:
printf("ata%d %s: ",channel,slave?" slave":"master");
@@ -2726,8 +2785,8 @@ void ata_detect( )
printf("ata%d %s: Unknown device\n",channel,slave?" slave":"master");
break;
}
-#endif /* !VBOX */
}
+#endif /* !VBOX */
}
// Store the devices counts
@@ -3817,6 +3876,10 @@ cdrom_boot()
# include "scsi.c"
#endif
+#ifdef VBOX_WITH_BIOS_AHCI
+# include "ahci.c"
+#endif
+
void
int14_function(regs, ds, iret_addr)
pusha_regs_t regs; // regs pushed from PUSHA instruction
@@ -4788,7 +4851,10 @@ ASM_END
/* Mark the BIOS as reserved. VBox doesn't currently
* use the 0xe0000-0xeffff area. It does use the
* 0xd0000-0xdffff area for the BIOS logo, but it's
- * not worth marking it as reserved. Note that various
+ * not worth marking it as reserved. (this is not
+ * true anymore because the VGA adapter handles the logo stuff)
+ * The whole 0xe0000-0xfffff can be used for the BIOS.
+ * Note that various
* Windows versions don't accept (read: in debug builds
* they trigger the "Too many similar traps" assertion)
* a single reserved range from 0xd0000 to 0xffffff.
@@ -5885,7 +5951,7 @@ int13_harddisk(EHBX, EHAX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLA
checksum=0;
for (i=0; i<15; i++) checksum+=read_byte(ebda_seg, (&EbdaData->ata.dpte) + i);
- checksum = ~checksum;
+ checksum = -checksum;
write_byte(ebda_seg, &EbdaData->ata.dpte.checksum, checksum);
}
@@ -5933,7 +5999,7 @@ int13_harddisk(EHBX, EHAX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLA
checksum=0;
for (i=30; i<64; i++) checksum+=read_byte(DS, SI + i);
- checksum = ~checksum;
+ checksum = -checksum;
write_byte(DS, SI+(Bit16u)&Int13DPT->checksum, checksum);
}
@@ -6233,7 +6299,7 @@ int13_cdrom_rme_end:
checksum=0;
for (i=0; i<15; i++) checksum+=read_byte(ebda_seg, (&EbdaData->ata.dpte) + i);
- checksum = ~checksum;
+ checksum = -checksum;
write_byte(ebda_seg, &EbdaData->ata.dpte.checksum, checksum);
}
@@ -6281,7 +6347,7 @@ int13_cdrom_rme_end:
checksum=0;
for (i=30; i<64; i++) checksum+=read_byte(DS, SI + i);
- checksum = ~checksum;
+ checksum = -checksum;
write_byte(DS, SI+(Bit16u)&Int13DPT->checksum, checksum);
}
@@ -9405,8 +9471,10 @@ hard_drive_post:
mov 0x048c, al /* hard disk status register */
mov 0x048d, al /* hard disk error register */
mov 0x048e, al /* hard disk task complete flag */
+#ifndef VBOX /* Why is this hardcoded to 1? */
mov al, #0x01
mov 0x0475, al /* hard disk number attached */
+#endif
mov al, #0xc0
mov 0x0476, al /* hard disk control byte */
SET_INT_VECTOR(0x13, #0xF000, #int13_handler)
@@ -11671,6 +11739,14 @@ post_default_ints:
;;
call hard_drive_post
+#ifdef VBOX_WITH_BIOS_AHCI
+ ;;
+ ;; AHCI driver setup
+ ;;
+ call _ahci_init
+ ;;
+#endif
+
#if BX_ELTORITO_BOOT
;;
;; eltorito floppy/harddisk emulation from cd
diff --git a/src/VBox/Devices/PC/BIOS/scsi.c b/src/VBox/Devices/PC/BIOS/scsi.c
index fe4fb6e9f..0d16601c2 100644
--- a/src/VBox/Devices/PC/BIOS/scsi.c
+++ b/src/VBox/Devices/PC/BIOS/scsi.c
@@ -1,4 +1,4 @@
-/* $Id: scsi.c $ */
+/* $Id: scsi.c 37427 2011-06-13 17:45:37Z vboxsync $ */
/** @file
* SCSI host adapter driver to boot from SCSI disks
*/
@@ -442,6 +442,11 @@ void scsi_enumerate_attached_devices(io_base)
hdcount++;
write_byte(ebda_seg, &EbdaData->ata.hdcount, hdcount);
+ /* Update hdcount in the BDA. */
+ hdcount = read_byte(0x40, 0x75);
+ hdcount++;
+ write_byte(0x40, 0x75, hdcount);
+
hdcount_scsi++;
write_byte(ebda_seg, &EbdaData->scsi.hdcount, hdcount_scsi);
}
diff --git a/src/VBox/Devices/PC/DevACPI.cpp b/src/VBox/Devices/PC/DevACPI.cpp
index f83d1f8f1..b20915635 100644
--- a/src/VBox/Devices/PC/DevACPI.cpp
+++ b/src/VBox/Devices/PC/DevACPI.cpp
@@ -1,10 +1,10 @@
-/* $Id: DevACPI.cpp $ */
+/* $Id: DevACPI.cpp 37526 2011-06-17 10:17:38Z vboxsync $ */
/** @file
* DevACPI - Advanced Configuration and Power Interface (ACPI) Device.
*/
/*
- * Copyright (C) 2006-2009 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;
@@ -21,6 +21,7 @@
#define LOG_GROUP LOG_GROUP_DEV_ACPI
#include <VBox/vmm/pdmdev.h>
#include <VBox/vmm/pgm.h>
+#include <VBox/vmm/dbgftrace.h>
#include <VBox/log.h>
#include <VBox/param.h>
#include <iprt/assert.h>
@@ -51,6 +52,19 @@ int acpiCleanupSsdt(PPDMDEVINS pDevIns, void* pPtr);
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
+#ifdef IN_RING3
+/** Locks the device state, ring-3 only. */
+# define DEVACPI_LOCK_R3(a_pThis) \
+ do { \
+ int rcLock = PDMCritSectEnter(&(a_pThis)->CritSect, VERR_IGNORED); \
+ AssertRC(rcLock); \
+ } while (0)
+#endif
+/** Unlocks the device state (all contexts). */
+#define DEVACPI_UNLOCK(a_pThis) \
+ do { PDMCritSectLeave(&(a_pThis)->CritSect); } while (0)
+
+
#define DEBUG_HEX 0x3000
#define DEBUG_CHR 0x3001
@@ -166,7 +180,11 @@ enum
SYSTEM_INFO_INDEX_HBC_ADDRESS = 19, /**< host bus controller PCI address */
SYSTEM_INFO_INDEX_PCI_BASE = 20, /**< PCI bus MCFG MMIO range base */
SYSTEM_INFO_INDEX_PCI_LENGTH = 21, /**< PCI bus MCFG MMIO range length */
- SYSTEM_INFO_INDEX_END = 22,
+ SYSTEM_INFO_INDEX_SERIAL0_IOBASE = 22,
+ SYSTEM_INFO_INDEX_SERIAL0_IRQ = 23,
+ SYSTEM_INFO_INDEX_SERIAL1_IOBASE = 24,
+ SYSTEM_INFO_INDEX_SERIAL1_IRQ = 25,
+ SYSTEM_INFO_INDEX_END = 26,
SYSTEM_INFO_INDEX_INVALID = 0x80,
SYSTEM_INFO_INDEX_VALID = 0x200
};
@@ -193,16 +211,18 @@ enum
typedef struct ACPIState
{
PCIDevice dev;
+ /** Critical section protecting the ACPI state. */
+ PDMCRITSECT CritSect;
+
uint16_t pm1a_en;
uint16_t pm1a_sts;
uint16_t pm1a_ctl;
/** Number of logical CPUs in guest */
uint16_t cCpus;
uint64_t u64PmTimerInitial;
- uint64_t u64PmTimerLastSeen;
- PTMTIMERR3 tsR3;
- PTMTIMERR0 tsR0;
- PTMTIMERRC tsRC;
+ PTMTIMERR3 pPmTimerR3;
+ PTMTIMERR0 pPmTimerR0;
+ PTMTIMERRC pPmTimerRC;
uint32_t gpe0_en;
uint32_t gpe0_sts;
@@ -282,7 +302,14 @@ typedef struct ACPIState
uint64_t u64PciConfigMMioAddress;
/* Length of PCI config space MMIO region */
uint64_t u64PciConfigMMioLength;
-
+ /** Serial 0 IRQ number */
+ uint8_t uSerial0Irq;
+ /** Serial 1 IRQ number */
+ uint8_t uSerial1Irq;
+ /** Serial 0 IO port base */
+ RTIOPORT uSerial0IoPortBase;
+ /** Serial 1 IO port base */
+ RTIOPORT uSerial1IoPortBase;
/** ACPI port base interface. */
PDMIBASE IBase;
/** ACPI port interface. */
@@ -649,9 +676,9 @@ public:
/**
* Size of MADT for given ACPI config, useful to compute layout.
*/
- static uint32_t sizeFor(ACPIState *s, uint32_t cIsos)
+ static uint32_t sizeFor(ACPIState *pThis, uint32_t cIsos)
{
- return AcpiTableMADT(s->cCpus, cIsos).size();
+ return AcpiTableMADT(pThis->cCpus, cIsos).size();
}
/*
@@ -681,391 +708,19 @@ public:
* Internal Functions *
*******************************************************************************/
RT_C_DECLS_BEGIN
-PDMBOTHCBDECL(int) acpiPMTmrRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-#ifdef IN_RING3
-PDMBOTHCBDECL(int) acpiPm1aEnRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) acpiPM1aEnWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) acpiPm1aStsRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) acpiPM1aStsWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) acpiPm1aCtlRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) acpiPM1aCtlWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) acpiSmiWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) acpiBatIndexWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) acpiBatDataRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) acpiSysInfoDataRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) acpiSysInfoDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) acpiGpe0EnRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) acpiGpe0EnWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) acpiGpe0StsRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) acpiGpe0StsWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) acpiResetWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-# ifdef DEBUG_ACPI
-PDMBOTHCBDECL(int) acpiDhexWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) acpiDchrWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-# endif
-#endif /* IN_RING3 */
+PDMBOTHCBDECL(int) acpiPMTmrRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
RT_C_DECLS_END
-
-
#ifdef IN_RING3
+static int acpiPlantTables(ACPIState *pThis);
+#endif
-static RTIOPORT acpiPmPort(ACPIState* pAcpi, int32_t offset)
-{
- Assert(pAcpi->uPmIoPortBase != 0);
-
- if (offset == -1)
- return 0;
-
- return RTIOPORT(pAcpi->uPmIoPortBase + offset);
-}
-
-/* Simple acpiChecksum: all the bytes must add up to 0. */
-static uint8_t acpiChecksum(const uint8_t * const data, size_t len)
-{
- uint8_t sum = 0;
- for (size_t i = 0; i < len; ++i)
- sum += data[i];
- return -sum;
-}
-
-static void acpiPrepareHeader(ACPITBLHEADER *header, const char au8Signature[4],
- uint32_t u32Length, uint8_t u8Revision)
-{
- memcpy(header->au8Signature, au8Signature, 4);
- header->u32Length = RT_H2LE_U32(u32Length);
- header->u8Revision = u8Revision;
- memcpy(header->au8OemId, "VBOX ", 6);
- memcpy(header->au8OemTabId, "VBOX", 4);
- memcpy(header->au8OemTabId+4, au8Signature, 4);
- header->u32OemRevision = RT_H2LE_U32(1);
- memcpy(header->au8CreatorId, "ASL ", 4);
- header->u32CreatorRev = RT_H2LE_U32(0x61);
-}
-
-static void acpiWriteGenericAddr(ACPIGENADDR *g, uint8_t u8AddressSpaceId,
- uint8_t u8RegisterBitWidth, uint8_t u8RegisterBitOffset,
- uint8_t u8AccessSize, uint64_t u64Address)
-{
- g->u8AddressSpaceId = u8AddressSpaceId;
- g->u8RegisterBitWidth = u8RegisterBitWidth;
- g->u8RegisterBitOffset = u8RegisterBitOffset;
- g->u8AccessSize = u8AccessSize;
- g->u64Address = RT_H2LE_U64(u64Address);
-}
-
-static void acpiPhyscpy(ACPIState *s, RTGCPHYS32 dst, const void * const src, size_t size)
-{
- PDMDevHlpPhysWrite(s->pDevIns, dst, src, size);
-}
-
-/** Differentiated System Description Table (DSDT) */
-
-static void acpiSetupDSDT(ACPIState *s, RTGCPHYS32 addr,
- void* pPtr, size_t uDsdtLen)
-{
- acpiPhyscpy(s, addr, pPtr, uDsdtLen);
-}
-
-/** Secondary System Description Table (SSDT) */
-
-static void acpiSetupSSDT(ACPIState *s, RTGCPHYS32 addr,
- void* pPtr, size_t uSsdtLen)
-{
- acpiPhyscpy(s, addr, pPtr, uSsdtLen);
-}
-
-/** Firmware ACPI Control Structure (FACS) */
-static void acpiSetupFACS(ACPIState *s, RTGCPHYS32 addr)
-{
- ACPITBLFACS facs;
-
- memset(&facs, 0, sizeof(facs));
- memcpy(facs.au8Signature, "FACS", 4);
- facs.u32Length = RT_H2LE_U32(sizeof(ACPITBLFACS));
- facs.u32HWSignature = RT_H2LE_U32(0);
- facs.u32FWVector = RT_H2LE_U32(0);
- facs.u32GlobalLock = RT_H2LE_U32(0);
- facs.u32Flags = RT_H2LE_U32(0);
- facs.u64X_FWVector = RT_H2LE_U64(0);
- facs.u8Version = 1;
-
- acpiPhyscpy(s, addr, (const uint8_t *)&facs, sizeof(facs));
-}
-
-/** Fixed ACPI Description Table (FADT aka FACP) */
-static void acpiSetupFADT(ACPIState *s, RTGCPHYS32 GCPhysAcpi1, RTGCPHYS32 GCPhysAcpi2, RTGCPHYS32 GCPhysFacs, RTGCPHYS GCPhysDsdt)
-{
- ACPITBLFADT fadt;
-
- /* First the ACPI version 2+ version of the structure. */
- memset(&fadt, 0, sizeof(fadt));
- acpiPrepareHeader(&fadt.header, "FACP", sizeof(fadt), 4);
- fadt.u32FACS = RT_H2LE_U32(GCPhysFacs);
- fadt.u32DSDT = RT_H2LE_U32(GCPhysDsdt);
- fadt.u8IntModel = 0; /* dropped from the ACPI 2.0 spec. */
- fadt.u8PreferredPMProfile = 0; /* unspecified */
- fadt.u16SCIInt = RT_H2LE_U16(SCI_INT);
- fadt.u32SMICmd = RT_H2LE_U32(SMI_CMD);
- fadt.u8AcpiEnable = ACPI_ENABLE;
- fadt.u8AcpiDisable = ACPI_DISABLE;
- fadt.u8S4BIOSReq = 0;
- fadt.u8PStateCnt = 0;
- fadt.u32PM1aEVTBLK = RT_H2LE_U32(acpiPmPort(s, PM1a_EVT_OFFSET));
- fadt.u32PM1bEVTBLK = RT_H2LE_U32(acpiPmPort(s, PM1b_EVT_OFFSET));
- fadt.u32PM1aCTLBLK = RT_H2LE_U32(acpiPmPort(s, PM1a_CTL_OFFSET));
- fadt.u32PM1bCTLBLK = RT_H2LE_U32(acpiPmPort(s, PM1b_CTL_OFFSET));
- fadt.u32PM2CTLBLK = RT_H2LE_U32(acpiPmPort(s, PM2_CTL_OFFSET));
- fadt.u32PMTMRBLK = RT_H2LE_U32(acpiPmPort(s, PM_TMR_OFFSET));
- fadt.u32GPE0BLK = RT_H2LE_U32(acpiPmPort(s, GPE0_OFFSET));
- fadt.u32GPE1BLK = RT_H2LE_U32(acpiPmPort(s, GPE1_OFFSET));
- fadt.u8PM1EVTLEN = 4;
- fadt.u8PM1CTLLEN = 2;
- fadt.u8PM2CTLLEN = 0;
- fadt.u8PMTMLEN = 4;
- fadt.u8GPE0BLKLEN = GPE0_BLK_LEN;
- fadt.u8GPE1BLKLEN = GPE1_BLK_LEN;
- fadt.u8GPE1BASE = GPE1_BASE;
- fadt.u8CSTCNT = 0;
- fadt.u16PLVL2LAT = RT_H2LE_U16(P_LVL2_LAT);
- fadt.u16PLVL3LAT = RT_H2LE_U16(P_LVL3_LAT);
- fadt.u16FlushSize = RT_H2LE_U16(FLUSH_SIZE);
- fadt.u16FlushStride = RT_H2LE_U16(FLUSH_STRIDE);
- fadt.u8DutyOffset = 0;
- fadt.u8DutyWidth = 0;
- fadt.u8DayAlarm = 0;
- fadt.u8MonAlarm = 0;
- fadt.u8Century = 0;
- fadt.u16IAPCBOOTARCH = RT_H2LE_U16(IAPC_BOOT_ARCH_LEGACY_DEV | IAPC_BOOT_ARCH_8042);
- /** @note WBINVD is required for ACPI versions newer than 1.0 */
- fadt.u32Flags = RT_H2LE_U32( FADT_FL_WBINVD
- | FADT_FL_FIX_RTC
- | FADT_FL_TMR_VAL_EXT
- | FADT_FL_RESET_REG_SUP);
-
- /* We have to force physical APIC mode or Linux can't use more than 8 CPUs */
- if (s->fCpuHotPlug)
- fadt.u32Flags |= RT_H2LE_U32(FADT_FL_FORCE_APIC_PHYS_DEST_MODE);
-
- acpiWriteGenericAddr(&fadt.ResetReg, 1, 8, 0, 1, ACPI_RESET_BLK);
- fadt.u8ResetVal = ACPI_RESET_REG_VAL;
- fadt.u64XFACS = RT_H2LE_U64((uint64_t)GCPhysFacs);
- fadt.u64XDSDT = RT_H2LE_U64((uint64_t)GCPhysDsdt);
- acpiWriteGenericAddr(&fadt.X_PM1aEVTBLK, 1, 32, 0, 2, acpiPmPort(s, PM1a_EVT_OFFSET));
- acpiWriteGenericAddr(&fadt.X_PM1bEVTBLK, 0, 0, 0, 0, acpiPmPort(s, PM1b_EVT_OFFSET));
- acpiWriteGenericAddr(&fadt.X_PM1aCTLBLK, 1, 16, 0, 2, acpiPmPort(s, PM1a_CTL_OFFSET));
- acpiWriteGenericAddr(&fadt.X_PM1bCTLBLK, 0, 0, 0, 0, acpiPmPort(s, PM1b_CTL_OFFSET));
- acpiWriteGenericAddr(&fadt.X_PM2CTLBLK, 0, 0, 0, 0, acpiPmPort(s, PM2_CTL_OFFSET));
- acpiWriteGenericAddr(&fadt.X_PMTMRBLK, 1, 32, 0, 3, acpiPmPort(s, PM_TMR_OFFSET));
- acpiWriteGenericAddr(&fadt.X_GPE0BLK, 1, 16, 0, 1, acpiPmPort(s, GPE0_OFFSET));
- acpiWriteGenericAddr(&fadt.X_GPE1BLK, 0, 0, 0, 0, acpiPmPort(s, GPE1_OFFSET));
- fadt.header.u8Checksum = acpiChecksum((uint8_t *)&fadt, sizeof(fadt));
- acpiPhyscpy(s, GCPhysAcpi2, &fadt, sizeof(fadt));
-
- /* Now the ACPI 1.0 version. */
- fadt.header.u32Length = ACPITBLFADT_VERSION1_SIZE;
- fadt.u8IntModel = INT_MODEL_DUAL_PIC;
- fadt.header.u8Checksum = 0; /* Must be zeroed before recalculating checksum! */
- fadt.header.u8Checksum = acpiChecksum((uint8_t *)&fadt, ACPITBLFADT_VERSION1_SIZE);
- acpiPhyscpy(s, GCPhysAcpi1, &fadt, ACPITBLFADT_VERSION1_SIZE);
-}
-
-/**
- * Root System Description Table.
- * The RSDT and XSDT tables are basically identical. The only difference is 32 vs 64 bits
- * addresses for description headers. RSDT is for ACPI 1.0. XSDT for ACPI 2.0 and up.
- */
-static int acpiSetupRSDT(ACPIState *s, RTGCPHYS32 addr, unsigned int nb_entries, uint32_t *addrs)
-{
- ACPITBLRSDT *rsdt;
- const size_t size = sizeof(ACPITBLHEADER) + nb_entries * sizeof(rsdt->u32Entry[0]);
-
- rsdt = (ACPITBLRSDT*)RTMemAllocZ(size);
- if (!rsdt)
- return PDMDEV_SET_ERROR(s->pDevIns, VERR_NO_TMP_MEMORY, N_("Cannot allocate RSDT"));
-
- acpiPrepareHeader(&rsdt->header, "RSDT", (uint32_t)size, 1);
- for (unsigned int i = 0; i < nb_entries; ++i)
- {
- rsdt->u32Entry[i] = RT_H2LE_U32(addrs[i]);
- Log(("Setup RSDT: [%d] = %x\n", i, rsdt->u32Entry[i]));
- }
- rsdt->header.u8Checksum = acpiChecksum((uint8_t*)rsdt, size);
- acpiPhyscpy(s, addr, rsdt, size);
- RTMemFree(rsdt);
- return VINF_SUCCESS;
-}
-
-/** Extended System Description Table. */
-static int acpiSetupXSDT(ACPIState *s, RTGCPHYS32 addr, unsigned int nb_entries, uint32_t *addrs)
-{
- ACPITBLXSDT *xsdt;
- const size_t size = sizeof(ACPITBLHEADER) + nb_entries * sizeof(xsdt->u64Entry[0]);
-
- xsdt = (ACPITBLXSDT*)RTMemAllocZ(size);
- if (!xsdt)
- return VERR_NO_TMP_MEMORY;
-
- acpiPrepareHeader(&xsdt->header, "XSDT", (uint32_t)size, 1 /* according to ACPI 3.0 specs */);
- for (unsigned int i = 0; i < nb_entries; ++i)
- {
- xsdt->u64Entry[i] = RT_H2LE_U64((uint64_t)addrs[i]);
- Log(("Setup XSDT: [%d] = %RX64\n", i, xsdt->u64Entry[i]));
- }
- xsdt->header.u8Checksum = acpiChecksum((uint8_t*)xsdt, size);
- acpiPhyscpy(s, addr, xsdt, size);
- RTMemFree(xsdt);
- return VINF_SUCCESS;
-}
-
-/** Root System Description Pointer (RSDP) */
-static void acpiSetupRSDP(ACPITBLRSDP *rsdp, RTGCPHYS32 GCPhysRsdt, RTGCPHYS GCPhysXsdt)
-{
- memset(rsdp, 0, sizeof(*rsdp));
-
- /* ACPI 1.0 part (RSDT */
- memcpy(rsdp->au8Signature, "RSD PTR ", 8);
- memcpy(rsdp->au8OemId, "VBOX ", 6);
- rsdp->u8Revision = ACPI_REVISION;
- rsdp->u32RSDT = RT_H2LE_U32(GCPhysRsdt);
- rsdp->u8Checksum = acpiChecksum((uint8_t*)rsdp, RT_OFFSETOF(ACPITBLRSDP, u32Length));
-
- /* ACPI 2.0 part (XSDT) */
- rsdp->u32Length = RT_H2LE_U32(sizeof(ACPITBLRSDP));
- rsdp->u64XSDT = RT_H2LE_U64(GCPhysXsdt);
- rsdp->u8ExtChecksum = acpiChecksum((uint8_t*)rsdp, sizeof(ACPITBLRSDP));
-}
-
-/**
- * Multiple APIC Description Table.
- *
- * @note APIC without IO-APIC hangs Windows Vista therefore we setup both
- *
- * @todo All hardcoded, should set this up based on the actual VM config!!!!!
- */
-static void acpiSetupMADT(ACPIState *s, RTGCPHYS32 addr)
-{
- uint16_t cpus = s->cCpus;
- AcpiTableMADT madt(cpus, NUMBER_OF_IRQ_SOURCE_OVERRIDES);
-
- acpiPrepareHeader(madt.header_addr(), "APIC", madt.size(), 2);
-
- *madt.u32LAPIC_addr() = RT_H2LE_U32(0xfee00000);
- *madt.u32Flags_addr() = RT_H2LE_U32(PCAT_COMPAT);
-
- /* LAPICs records */
- ACPITBLLAPIC* lapic = madt.LApics_addr();
- for (uint16_t i = 0; i < cpus; i++)
- {
- lapic->u8Type = 0;
- lapic->u8Length = sizeof(ACPITBLLAPIC);
- lapic->u8ProcId = i;
- /** Must match numbering convention in MPTABLES */
- lapic->u8ApicId = i;
- lapic->u32Flags = VMCPUSET_IS_PRESENT(&s->CpuSetAttached, i) ? RT_H2LE_U32(LAPIC_ENABLED) : 0;
- lapic++;
- }
-
- /* IO-APIC record */
- ACPITBLIOAPIC* ioapic = madt.IOApic_addr();
- ioapic->u8Type = 1;
- ioapic->u8Length = sizeof(ACPITBLIOAPIC);
- /** Must match MP tables ID */
- ioapic->u8IOApicId = cpus;
- ioapic->u8Reserved = 0;
- ioapic->u32Address = RT_H2LE_U32(0xfec00000);
- ioapic->u32GSIB = RT_H2LE_U32(0);
-
- /* Interrupt Source Overrides */
- /* Flags:
- bits[3:2]:
- 00 conforms to the bus
- 01 edge-triggered
- 10 reserved
- 11 level-triggered
- bits[1:0]
- 00 conforms to the bus
- 01 active-high
- 10 reserved
- 11 active-low */
- /* If changing, also update PDMIsaSetIrq() and MPS */
- ACPITBLISO* isos = madt.ISO_addr();
- /* Timer interrupt rule IRQ0 to GSI2 */
- isos[0].u8Type = 2;
- isos[0].u8Length = sizeof(ACPITBLISO);
- isos[0].u8Bus = 0; /* Must be 0 */
- isos[0].u8Source = 0; /* IRQ0 */
- isos[0].u32GSI = 2; /* connected to pin 2 */
- isos[0].u16Flags = 0; /* conform to the bus */
-
- /* ACPI interrupt rule - IRQ9 to GSI9 */
- isos[1].u8Type = 2;
- isos[1].u8Length = sizeof(ACPITBLISO);
- isos[1].u8Bus = 0; /* Must be 0 */
- isos[1].u8Source = 9; /* IRQ9 */
- isos[1].u32GSI = 9; /* connected to pin 9 */
- isos[1].u16Flags = 0xd; /* active high, level triggered */
- Assert(NUMBER_OF_IRQ_SOURCE_OVERRIDES == 2);
-
- madt.header_addr()->u8Checksum = acpiChecksum(madt.data(), madt.size());
- acpiPhyscpy(s, addr, madt.data(), madt.size());
-}
-
-
-/** High Performance Event Timer (HPET) descriptor */
-static void acpiSetupHPET(ACPIState *s, RTGCPHYS32 addr)
-{
- ACPITBLHPET hpet;
-
- memset(&hpet, 0, sizeof(hpet));
-
- acpiPrepareHeader(&hpet.aHeader, "HPET", sizeof(hpet), 1);
- /* Keep base address consistent with appropriate DSDT entry (vbox.dsl) */
- acpiWriteGenericAddr(&hpet.HpetAddr,
- 0 /* Memory address space */,
- 64 /* Register bit width */,
- 0 /* Bit offset */,
- 0, /* Register access size, is it correct? */
- 0xfed00000 /* Address */);
-
- hpet.u32Id = 0x8086a201; /* must match what HPET ID returns, is it correct ? */
- hpet.u32Number = 0;
- hpet.u32MinTick = 4096;
- hpet.u8Attributes = 0;
-
- hpet.aHeader.u8Checksum = acpiChecksum((uint8_t *)&hpet, sizeof(hpet));
-
- acpiPhyscpy(s, addr, (const uint8_t *)&hpet, sizeof(hpet));
-}
-
-/** MMCONFIG PCI config space access (MCFG) descriptor */
-static void acpiSetupMCFG(ACPIState *s, RTGCPHYS32 addr)
-{
- struct {
- ACPITBLMCFG hdr;
- ACPITBLMCFGENTRY entry;
- } tbl;
-
- uint8_t u8StartBus = 0;
- uint8_t u8EndBus = (s->u64PciConfigMMioLength >> 20) - 1;
-
- memset(&tbl, 0, sizeof(tbl));
-
- acpiPrepareHeader(&tbl.hdr.aHeader, "MCFG", sizeof(tbl), 1);
- tbl.entry.u64BaseAddress = s->u64PciConfigMMioAddress;
- tbl.entry.u8StartBus = u8StartBus;
- tbl.entry.u8EndBus = u8EndBus;
- // u16PciSegmentGroup must match _SEG in ACPI table
-
- tbl.hdr.aHeader.u8Checksum = acpiChecksum((uint8_t *)&tbl, sizeof(tbl));
-
- acpiPhyscpy(s, addr, (const uint8_t *)&tbl, sizeof(tbl));
-}
+#ifdef IN_RING3
/* SCI IRQ */
-DECLINLINE(void) acpiSetIrq(ACPIState *s, int level)
+DECLINLINE(void) acpiSetIrq(ACPIState *pThis, int level)
{
- if (s->pm1a_ctl & SCI_EN)
- PDMDevHlpPCISetIrq(s->pDevIns, -1, level);
+ if (pThis->pm1a_ctl & SCI_EN)
+ PDMDevHlpPCISetIrq(pThis->pDevIns, -1, level);
}
DECLINLINE(uint32_t) pm1a_pure_en(uint32_t en)
@@ -1078,67 +733,99 @@ DECLINLINE(uint32_t) pm1a_pure_sts(uint32_t sts)
return sts & ~(RSR_STS | IGN_STS);
}
-DECLINLINE(int) pm1a_level(ACPIState *s)
+DECLINLINE(int) pm1a_level(ACPIState *pThis)
{
- return (pm1a_pure_en(s->pm1a_en) & pm1a_pure_sts(s->pm1a_sts)) != 0;
+ return (pm1a_pure_en(pThis->pm1a_en) & pm1a_pure_sts(pThis->pm1a_sts)) != 0;
}
-DECLINLINE(int) gpe0_level(ACPIState *s)
+DECLINLINE(int) gpe0_level(ACPIState *pThis)
{
- return (s->gpe0_en & s->gpe0_sts) != 0;
+ return (pThis->gpe0_en & pThis->gpe0_sts) != 0;
}
-static void update_pm1a(ACPIState *s, uint32_t sts, uint32_t en)
+/**
+ * Used by acpiPM1aStsWrite, acpiPM1aEnWrite, acpiPmTimer,
+ * acpiPort_PowerBuffonPress and acpiPort_SleepButtonPress to
+ * update the GPE0.STS and GPE0.EN registers and trigger IRQs.
+ *
+ * Caller must hold the state lock.
+ *
+ * @param pThis The ACPI instance.
+ * @param sts The new GPE0.STS value.
+ * @param en The new GPE0.EN value.
+ */
+static void update_pm1a(ACPIState *pThis, uint32_t sts, uint32_t en)
{
- int old_level, new_level;
+ Assert(PDMCritSectIsOwner(&pThis->CritSect));
- if (gpe0_level(s))
+ if (gpe0_level(pThis))
return;
- old_level = pm1a_level(s);
- new_level = (pm1a_pure_en(en) & pm1a_pure_sts(sts)) != 0;
+ int const old_level = pm1a_level(pThis);
+ int const new_level = (pm1a_pure_en(en) & pm1a_pure_sts(sts)) != 0;
Log(("update_pm1a() old=%x new=%x\n", old_level, new_level));
- s->pm1a_en = en;
- s->pm1a_sts = sts;
+ pThis->pm1a_en = en;
+ pThis->pm1a_sts = sts;
if (new_level != old_level)
- acpiSetIrq(s, new_level);
+ acpiSetIrq(pThis, new_level);
}
-static void update_gpe0(ACPIState *s, uint32_t sts, uint32_t en)
+/**
+ * Used by acpiGpe0StsWrite, acpiGpe0EnWrite, acpiAttach and acpiDetach to
+ * update the GPE0.STS and GPE0.EN registers and trigger IRQs.
+ *
+ * Caller must hold the state lock.
+ *
+ * @param pThis The ACPI instance.
+ * @param sts The new GPE0.STS value.
+ * @param en The new GPE0.EN value.
+ */
+static void update_gpe0(ACPIState *pThis, uint32_t sts, uint32_t en)
{
- int old_level, new_level;
+ Assert(PDMCritSectIsOwner(&pThis->CritSect));
- if (pm1a_level(s))
+ if (pm1a_level(pThis))
return;
- old_level = (s->gpe0_en & s->gpe0_sts) != 0;
- new_level = (en & sts) != 0;
+ int const old_level = (pThis->gpe0_en & pThis->gpe0_sts) != 0;
+ int const new_level = (en & sts) != 0;
- s->gpe0_en = en;
- s->gpe0_sts = sts;
+ pThis->gpe0_en = en;
+ pThis->gpe0_sts = sts;
if (new_level != old_level)
- acpiSetIrq(s, new_level);
+ acpiSetIrq(pThis, new_level);
}
-static int acpiPowerDown(ACPIState *s)
+/**
+ * Used by acpiPM1aCtlWrite to power off the VM.
+ *
+ * @param pThis The ACPI instance.
+ * @returns Strict VBox status code.
+ */
+static int acpiPowerOff(ACPIState *pThis)
{
- int rc = PDMDevHlpVMPowerOff(s->pDevIns);
+ int rc = PDMDevHlpVMPowerOff(pThis->pDevIns);
if (RT_FAILURE(rc))
AssertMsgFailed(("Could not power down the VM. rc = %Rrc\n", rc));
return rc;
}
+/**
+ * Used by acpiPM1aCtlWrite to put the VM to sleep.
+ *
+ * @param pThis The ACPI instance.
+ * @returns Strict VBox status code.
+ */
static int acpiSleep(ACPIState *pThis)
{
- int rc;
-
/* We must set WAK_STS on resume (includes restore) so the guest knows that
we've woken up and can continue executing code. The guest is probably
reading the PMSTS register in a loop to check this. */
+ int rc;
pThis->fSetWakeupOnResume = true;
if (pThis->fSuspendToSavedState)
{
@@ -1160,56 +847,63 @@ static int acpiSleep(ACPIState *pThis)
return rc;
}
-/** Converts a ACPI port interface pointer to an ACPI state pointer. */
-#define IACPIPORT_2_ACPISTATE(pInterface) ( (ACPIState*)((uintptr_t)pInterface - RT_OFFSETOF(ACPIState, IACPIPort)) )
/**
- * Send an ACPI power off event.
- *
- * @returns VBox status code
- * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @interface_method_impl{PDMIACPIPORT,pfnPowerButtonPress}
*/
-static DECLCALLBACK(int) acpiPowerButtonPress(PPDMIACPIPORT pInterface)
+static DECLCALLBACK(int) acpiPort_PowerButtonPress(PPDMIACPIPORT pInterface)
{
- ACPIState *s = IACPIPORT_2_ACPISTATE(pInterface);
- Log(("acpiPowerButtonPress: handled=%d status=%x\n", s->fPowerButtonHandled, s->pm1a_sts));
- s->fPowerButtonHandled = false;
- update_pm1a(s, s->pm1a_sts | PWRBTN_STS, s->pm1a_en);
+ ACPIState *pThis = RT_FROM_MEMBER(pInterface, ACPIState, IACPIPort);
+ DEVACPI_LOCK_R3(pThis);
+
+ Log(("acpiPort_PowerButtonPress: handled=%d status=%x\n", pThis->fPowerButtonHandled, pThis->pm1a_sts));
+ pThis->fPowerButtonHandled = false;
+ update_pm1a(pThis, pThis->pm1a_sts | PWRBTN_STS, pThis->pm1a_en);
+
+ DEVACPI_UNLOCK(pThis);
return VINF_SUCCESS;
}
/**
- * Check if the ACPI power button event was handled.
- *
- * @returns VBox status code
- * @param pInterface Pointer to the interface structure containing the called function pointer.
- * @param pfHandled Return true if the power button event was handled by the guest.
+ * @interface_method_impl{PDMIACPIPORT,pfnGetPowerButtonHandled}
*/
-static DECLCALLBACK(int) acpiGetPowerButtonHandled(PPDMIACPIPORT pInterface, bool *pfHandled)
+static DECLCALLBACK(int) acpiPort_GetPowerButtonHandled(PPDMIACPIPORT pInterface, bool *pfHandled)
{
- ACPIState *s = IACPIPORT_2_ACPISTATE(pInterface);
- *pfHandled = s->fPowerButtonHandled;
+ ACPIState *pThis = RT_FROM_MEMBER(pInterface, ACPIState, IACPIPort);
+ DEVACPI_LOCK_R3(pThis);
+
+ *pfHandled = pThis->fPowerButtonHandled;
+
+ DEVACPI_UNLOCK(pThis);
return VINF_SUCCESS;
}
/**
- * Check if the Guest entered into G0 (working) or G1 (sleeping).
- *
- * @returns VBox status code
- * @param pInterface Pointer to the interface structure containing the called function pointer.
- * @param pfEntered Return true if the guest entered the ACPI mode.
+ * @interface_method_impl{PDMIACPIPORT,pfnGetGuestEnteredACPIMode, Check if the
+ * Guest entered into G0 (working) or G1 (sleeping)}
*/
-static DECLCALLBACK(int) acpiGetGuestEnteredACPIMode(PPDMIACPIPORT pInterface, bool *pfEntered)
+static DECLCALLBACK(int) acpiPort_GetGuestEnteredACPIMode(PPDMIACPIPORT pInterface, bool *pfEntered)
{
- ACPIState *s = IACPIPORT_2_ACPISTATE(pInterface);
- *pfEntered = (s->pm1a_ctl & SCI_EN) != 0;
+ ACPIState *pThis = RT_FROM_MEMBER(pInterface, ACPIState, IACPIPort);
+ DEVACPI_LOCK_R3(pThis);
+
+ *pfEntered = (pThis->pm1a_ctl & SCI_EN) != 0;
+
+ DEVACPI_UNLOCK(pThis);
return VINF_SUCCESS;
}
-static DECLCALLBACK(int) acpiGetCpuStatus(PPDMIACPIPORT pInterface, unsigned uCpu, bool *pfLocked)
+/**
+ * @interface_method_impl{PDMIACPIPORT,pfnGetCpuStatus}
+ */
+static DECLCALLBACK(int) acpiPort_GetCpuStatus(PPDMIACPIPORT pInterface, unsigned uCpu, bool *pfLocked)
{
- ACPIState *s = IACPIPORT_2_ACPISTATE(pInterface);
- *pfLocked = VMCPUSET_IS_PRESENT(&s->CpuSetLocked, uCpu);
+ ACPIState *pThis = RT_FROM_MEMBER(pInterface, ACPIState, IACPIPort);
+ DEVACPI_LOCK_R3(pThis);
+
+ *pfLocked = VMCPUSET_IS_PRESENT(&pThis->CpuSetLocked, uCpu);
+
+ DEVACPI_UNLOCK(pThis);
return VINF_SUCCESS;
}
@@ -1219,196 +913,72 @@ static DECLCALLBACK(int) acpiGetCpuStatus(PPDMIACPIPORT pInterface, unsigned uCp
* @returns VBox status code
* @param pInterface Pointer to the interface structure containing the called function pointer.
*/
-static DECLCALLBACK(int) acpiSleepButtonPress(PPDMIACPIPORT pInterface)
-{
- ACPIState *s = IACPIPORT_2_ACPISTATE(pInterface);
- update_pm1a(s, s->pm1a_sts | SLPBTN_STS, s->pm1a_en);
- return VINF_SUCCESS;
-}
-
-/* PM1a_EVT_BLK enable */
-static uint32_t acpiPm1aEnReadw(ACPIState *s, uint32_t addr)
-{
- uint16_t val = s->pm1a_en;
- Log(("acpi: acpiPm1aEnReadw -> %#x\n", val));
- return val;
-}
-
-static void acpiPM1aEnWritew(ACPIState *s, uint32_t addr, uint32_t val)
-{
- Log(("acpi: acpiPM1aEnWritew <- %#x (%#x)\n", val, val & ~(RSR_EN | IGN_EN)));
- val &= ~(RSR_EN | IGN_EN);
- update_pm1a(s, s->pm1a_sts, val);
-}
-
-/* PM1a_EVT_BLK status */
-static uint32_t acpiPm1aStsReadw(ACPIState *s, uint32_t addr)
+static DECLCALLBACK(int) acpiPort_SleepButtonPress(PPDMIACPIPORT pInterface)
{
- uint16_t val = s->pm1a_sts;
- Log(("acpi: acpiPm1aStsReadw -> %#x\n", val));
- return val;
-}
-
-static void acpiPM1aStsWritew(ACPIState *s, uint32_t addr, uint32_t val)
-{
- Log(("acpi: acpiPM1aStsWritew <- %#x (%#x)\n", val, val & ~(RSR_STS | IGN_STS)));
- if (val & PWRBTN_STS)
- s->fPowerButtonHandled = true; /* Remember that the guest handled the last power button event */
- val = s->pm1a_sts & ~(val & ~(RSR_STS | IGN_STS));
- update_pm1a(s, val, s->pm1a_en);
-}
-
-/* PM1a_CTL_BLK */
-static uint32_t acpiPm1aCtlReadw(ACPIState *s, uint32_t addr)
-{
- uint16_t val = s->pm1a_ctl;
- Log(("acpi: acpiPm1aCtlReadw -> %#x\n", val));
- return val;
-}
+ ACPIState *pThis = RT_FROM_MEMBER(pInterface, ACPIState, IACPIPort);
+ DEVACPI_LOCK_R3(pThis);
-static int acpiPM1aCtlWritew(ACPIState *s, uint32_t addr, uint32_t val)
-{
- uint32_t uSleepState;
+ update_pm1a(pThis, pThis->pm1a_sts | SLPBTN_STS, pThis->pm1a_en);
- Log(("acpi: acpiPM1aCtlWritew <- %#x (%#x)\n", val, val & ~(RSR_CNT | IGN_CNT)));
- s->pm1a_ctl = val & ~(RSR_CNT | IGN_CNT);
-
- uSleepState = (s->pm1a_ctl >> SLP_TYPx_SHIFT) & SLP_TYPx_MASK;
- if (uSleepState != s->uSleepState)
- {
- s->uSleepState = uSleepState;
- switch (uSleepState)
- {
- case 0x00: /* S0 */
- break;
- case 0x01: /* S1 */
- if (s->fS1Enabled)
- {
- LogRel(("Entering S1 power state (powered-on suspend)\n"));
- return acpiSleep(s);
- }
- else
- LogRel(("Ignoring guest attempt to enter S1 power state (powered-on suspend)!\n"));
- case 0x04: /* S4 */
- if (s->fS4Enabled)
- {
- LogRel(("Entering S4 power state (suspend to disk)\n"));
- return acpiPowerDown(s);/* Same behavior as S5 */
- }
- else
- LogRel(("Ignoring guest attempt to enter S4 power state (suspend to disk)!\n"));
- case 0x05: /* S5 */
- LogRel(("Entering S5 power state (power down)\n"));
- return acpiPowerDown(s);
- default:
- AssertMsgFailed(("Unknown sleep state %#x\n", uSleepState));
- break;
- }
- }
+ DEVACPI_UNLOCK(pThis);
return VINF_SUCCESS;
}
-/* GPE0_BLK */
-static uint32_t acpiGpe0EnReadb(ACPIState *s, uint32_t addr)
-{
- uint8_t val = s->gpe0_en;
- Log(("acpi: acpiGpe0EnReadl -> %#x\n", val));
- return val;
-}
-
-static void acpiGpe0EnWriteb(ACPIState *s, uint32_t addr, uint32_t val)
-{
- Log(("acpi: acpiGpe0EnWritel <- %#x\n", val));
- update_gpe0(s, s->gpe0_sts, val);
-}
-
-static uint32_t acpiGpe0StsReadb(ACPIState *s, uint32_t addr)
-{
- uint8_t val = s->gpe0_sts;
- Log(("acpi: acpiGpe0StsReadl -> %#x\n", val));
- return val;
-}
-
-static void acpiGpe0StsWriteb(ACPIState *s, uint32_t addr, uint32_t val)
-{
- val = s->gpe0_sts & ~val;
- update_gpe0(s, val, s->gpe0_en);
- Log(("acpi: acpiGpe0StsWritel <- %#x\n", val));
-}
-
-static int acpiResetWriteU8(ACPIState *s, uint32_t addr, uint32_t val)
-{
- int rc = VINF_SUCCESS;
-
- Log(("ACPI: acpiResetWriteU8: %x %x\n", addr, val));
- if (val == ACPI_RESET_REG_VAL)
- {
-# ifndef IN_RING3
- rc = VINF_IOM_HC_IOPORT_WRITE;
-# else /* IN_RING3 */
- rc = PDMDevHlpVMReset(s->pDevIns);
-# endif /* !IN_RING3 */
- }
- return rc;
-}
-
-/* SMI */
-static void acpiSmiWriteU8(ACPIState *s, uint32_t addr, uint32_t val)
-{
- Log(("acpi: acpiSmiWriteU8 %#x\n", val));
- if (val == ACPI_ENABLE)
- s->pm1a_ctl |= SCI_EN;
- else if (val == ACPI_DISABLE)
- s->pm1a_ctl &= ~SCI_EN;
- else
- Log(("acpi: acpiSmiWriteU8 %#x <- unknown value\n", val));
-}
-
-static uint32_t find_rsdp_space(void)
-{
- return 0xe0000;
-}
-
-static int acpiPMTimerReset(ACPIState *s)
+/**
+ * Used by acpiPmTimer to re-arm the PM timer.
+ *
+ * The caller is expected to either hold the clock lock or to have made sure
+ * the VM is resetting or loading state.
+ *
+ * @param pThis The ACPI instance.
+ * @param uNow The current time.
+ */
+static void acpiPmTimerReset(ACPIState *pThis, uint64_t uNow)
{
- uint64_t interval, freq;
-
- freq = TMTimerGetFreq(s->CTX_SUFF(ts));
- interval = ASMMultU64ByU32DivByU32(0xffffffff, freq, PM_TMR_FREQ);
- Log(("interval = %RU64\n", interval));
- TMTimerSet(s->CTX_SUFF(ts), TMTimerGet(s->CTX_SUFF(ts)) + interval);
-
- return VINF_SUCCESS;
+ uint64_t uTimerFreq = TMTimerGetFreq(pThis->CTX_SUFF(pPmTimer));
+ uint64_t uInterval = ASMMultU64ByU32DivByU32(0xffffffff, uTimerFreq, PM_TMR_FREQ);
+ TMTimerSet(pThis->pPmTimerR3, uNow + uInterval);
+ Log(("acpi: uInterval = %RU64\n", uInterval));
}
-static DECLCALLBACK(void) acpiTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
+/**
+ * @callback_method_impl{FNTMTIMERDEV, PM Timer callback}
+ */
+static DECLCALLBACK(void) acpiPmTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
{
- ACPIState *s = (ACPIState *)pvUser;
+ ACPIState *pThis = (ACPIState *)pvUser;
+ Assert(TMTimerIsLockOwner(pThis->pPmTimerR3));
+ DEVACPI_LOCK_R3(pThis);
Log(("acpi: pm timer sts %#x (%d), en %#x (%d)\n",
- s->pm1a_sts, (s->pm1a_sts & TMR_STS) != 0,
- s->pm1a_en, (s->pm1a_en & TMR_EN) != 0));
+ pThis->pm1a_sts, (pThis->pm1a_sts & TMR_STS) != 0,
+ pThis->pm1a_en, (pThis->pm1a_en & TMR_EN) != 0));
+ update_pm1a(pThis, pThis->pm1a_sts | TMR_STS, pThis->pm1a_en);
+ DEVACPI_UNLOCK(pThis);
- update_pm1a(s, s->pm1a_sts | TMR_STS, s->pm1a_en);
- acpiPMTimerReset(s);
+ acpiPmTimerReset(pThis, TMTimerGet(pThis->pPmTimerR3));
}
/**
- * _BST method.
+ * _BST method - used by acpiBatDataRead to implement BAT_STATUS_STATE and
+ * acpiLoadState.
+ *
+ * @returns VINF_SUCCESS.
+ * @param pThis The ACPI instance.
*/
-static int acpiFetchBatteryStatus(ACPIState *s)
+static int acpiFetchBatteryStatus(ACPIState *pThis)
{
- uint32_t *p = s->au8BatteryInfo;
+ uint32_t *p = pThis->au8BatteryInfo;
bool fPresent; /* battery present? */
PDMACPIBATCAPACITY hostRemainingCapacity; /* 0..100 */
PDMACPIBATSTATE hostBatteryState; /* bitfield */
uint32_t hostPresentRate; /* 0..1000 */
int rc;
- if (!s->pDrv)
+ if (!pThis->pDrv)
return VINF_SUCCESS;
- rc = s->pDrv->pfnQueryBatteryStatus(s->pDrv, &fPresent, &hostRemainingCapacity,
- &hostBatteryState, &hostPresentRate);
+ rc = pThis->pDrv->pfnQueryBatteryStatus(pThis->pDrv, &fPresent, &hostRemainingCapacity,
+ &hostBatteryState, &hostPresentRate);
AssertRC(rc);
/* default values */
@@ -1428,11 +998,15 @@ static int acpiFetchBatteryStatus(ACPIState *s)
}
/**
- * _BIF method.
+ * _BIF method - used by acpiBatDataRead to implement BAT_INFO_UNITS and
+ * acpiLoadState.
+ *
+ * @returns VINF_SUCCESS.
+ * @param pThis The ACPI instance.
*/
-static int acpiFetchBatteryInfo(ACPIState *s)
+static int acpiFetchBatteryInfo(ACPIState *pThis)
{
- uint32_t *p = s->au8BatteryInfo;
+ uint32_t *p = pThis->au8BatteryInfo;
p[BAT_INFO_UNITS] = 0; /* mWh */
p[BAT_INFO_DESIGN_CAPACITY] = 50000; /* mWh */
@@ -1448,9 +1022,12 @@ static int acpiFetchBatteryInfo(ACPIState *s)
}
/**
- * _STA method.
+ * The _STA method - used by acpiBatDataRead to implement BAT_DEVICE_STATUS.
+ *
+ * @returns status mask or 0.
+ * @param pThis The ACPI instance.
*/
-static uint32_t acpiGetBatteryDeviceStatus(ACPIState *s)
+static uint32_t acpiGetBatteryDeviceStatus(ACPIState *pThis)
{
bool fPresent; /* battery present? */
PDMACPIBATCAPACITY hostRemainingCapacity; /* 0..100 */
@@ -1458,10 +1035,10 @@ static uint32_t acpiGetBatteryDeviceStatus(ACPIState *s)
uint32_t hostPresentRate; /* 0..1000 */
int rc;
- if (!s->pDrv)
+ if (!pThis->pDrv)
return 0;
- rc = s->pDrv->pfnQueryBatteryStatus(s->pDrv, &fPresent, &hostRemainingCapacity,
- &hostBatteryState, &hostPresentRate);
+ rc = pThis->pDrv->pfnQueryBatteryStatus(pThis->pDrv, &fPresent, &hostRemainingCapacity,
+ &hostBatteryState, &hostPresentRate);
AssertRC(rc);
return fPresent
@@ -1473,524 +1050,687 @@ static uint32_t acpiGetBatteryDeviceStatus(ACPIState *s)
: 0; /* device not present */
}
-static uint32_t acpiGetPowerSource(ACPIState *s)
+/**
+ * Used by acpiBatDataRead to implement BAT_POWER_SOURCE.
+ *
+ * @returns status.
+ * @param pThis The ACPI instance.
+ */
+static uint32_t acpiGetPowerSource(ACPIState *pThis)
{
- PDMACPIPOWERSOURCE ps;
-
/* query the current power source from the host driver */
- if (!s->pDrv)
+ if (!pThis->pDrv)
return AC_ONLINE;
- int rc = s->pDrv->pfnQueryPowerSource(s->pDrv, &ps);
+
+ PDMACPIPOWERSOURCE ps;
+ int rc = pThis->pDrv->pfnQueryPowerSource(pThis->pDrv, &ps);
AssertRC(rc);
return ps == PDM_ACPI_POWER_SOURCE_BATTERY ? AC_OFFLINE : AC_ONLINE;
}
+/**
+ * @callback_method_impl{FNIOMIOPORTOUT, Battery status index}
+ */
PDMBOTHCBDECL(int) acpiBatIndexWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- ACPIState *s = (ACPIState *)pvUser;
+ Log(("acpiBatIndexWrite: %#x (%#x)\n", u32, u32 >> 2));
+ if (cb != 4)
+ return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x\n", cb, Port, u32);
- switch (cb)
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ u32 >>= pThis->u8IndexShift;
+ /* see comment at the declaration of u8IndexShift */
+ if (pThis->u8IndexShift == 0 && u32 == (BAT_DEVICE_STATUS << 2))
{
- case 4:
- u32 >>= s->u8IndexShift;
- /* see comment at the declaration of u8IndexShift */
- if (s->u8IndexShift == 0 && u32 == (BAT_DEVICE_STATUS << 2))
- {
- s->u8IndexShift = 2;
- u32 >>= 2;
- }
- Assert(u32 < BAT_INDEX_LAST);
- s->uBatteryIndex = u32;
- break;
- default:
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- break;
+ pThis->u8IndexShift = 2;
+ u32 >>= 2;
}
+ Assert(u32 < BAT_INDEX_LAST);
+ pThis->uBatteryIndex = u32;
+
+ DEVACPI_UNLOCK(pThis);
return VINF_SUCCESS;
}
+/**
+ * @callback_method_impl{FNIOMIOPORTIN, Battery status data}
+ */
PDMBOTHCBDECL(int) acpiBatDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
- ACPIState *s = (ACPIState *)pvUser;
+ if (cb != 4)
+ return VERR_IOM_IOPORT_UNUSED;
- switch (cb)
- {
- case 4:
- switch (s->uBatteryIndex)
- {
- case BAT_STATUS_STATE:
- acpiFetchBatteryStatus(s);
- case BAT_STATUS_PRESENT_RATE:
- case BAT_STATUS_REMAINING_CAPACITY:
- case BAT_STATUS_PRESENT_VOLTAGE:
- *pu32 = s->au8BatteryInfo[s->uBatteryIndex];
- break;
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
- case BAT_INFO_UNITS:
- acpiFetchBatteryInfo(s);
- case BAT_INFO_DESIGN_CAPACITY:
- case BAT_INFO_LAST_FULL_CHARGE_CAPACITY:
- case BAT_INFO_TECHNOLOGY:
- case BAT_INFO_DESIGN_VOLTAGE:
- case BAT_INFO_DESIGN_CAPACITY_OF_WARNING:
- case BAT_INFO_DESIGN_CAPACITY_OF_LOW:
- case BAT_INFO_CAPACITY_GRANULARITY_1:
- case BAT_INFO_CAPACITY_GRANULARITY_2:
- *pu32 = s->au8BatteryInfo[s->uBatteryIndex];
- break;
+ int rc = VINF_SUCCESS;
+ switch (pThis->uBatteryIndex)
+ {
+ case BAT_STATUS_STATE:
+ acpiFetchBatteryStatus(pThis);
+ /* fall thru */
+ case BAT_STATUS_PRESENT_RATE:
+ case BAT_STATUS_REMAINING_CAPACITY:
+ case BAT_STATUS_PRESENT_VOLTAGE:
+ *pu32 = pThis->au8BatteryInfo[pThis->uBatteryIndex];
+ break;
- case BAT_DEVICE_STATUS:
- *pu32 = acpiGetBatteryDeviceStatus(s);
- break;
+ case BAT_INFO_UNITS:
+ acpiFetchBatteryInfo(pThis);
+ /* fall thru */
+ case BAT_INFO_DESIGN_CAPACITY:
+ case BAT_INFO_LAST_FULL_CHARGE_CAPACITY:
+ case BAT_INFO_TECHNOLOGY:
+ case BAT_INFO_DESIGN_VOLTAGE:
+ case BAT_INFO_DESIGN_CAPACITY_OF_WARNING:
+ case BAT_INFO_DESIGN_CAPACITY_OF_LOW:
+ case BAT_INFO_CAPACITY_GRANULARITY_1:
+ case BAT_INFO_CAPACITY_GRANULARITY_2:
+ *pu32 = pThis->au8BatteryInfo[pThis->uBatteryIndex];
+ break;
- case BAT_POWER_SOURCE:
- *pu32 = acpiGetPowerSource(s);
- break;
+ case BAT_DEVICE_STATUS:
+ *pu32 = acpiGetBatteryDeviceStatus(pThis);
+ break;
- default:
- AssertMsgFailed(("Invalid battery index %d\n", s->uBatteryIndex));
- break;
- }
+ case BAT_POWER_SOURCE:
+ *pu32 = acpiGetPowerSource(pThis);
break;
+
default:
- return VERR_IOM_IOPORT_UNUSED;
+ rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u idx=%u\n", cb, Port, pThis->uBatteryIndex);
+ *pu32 = UINT32_MAX;
+ break;
}
- return VINF_SUCCESS;
+
+ DEVACPI_UNLOCK(pThis);
+ return rc;
}
+/**
+ * @callback_method_impl{FNIOMIOPORTOUT, System info index}
+ */
PDMBOTHCBDECL(int) acpiSysInfoIndexWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- ACPIState *s = (ACPIState *)pvUser;
+ Log(("acpiSysInfoIndexWrite: %#x (%#x)\n", u32, u32 >> 2));
+ if (cb != 4)
+ return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x\n", cb, Port, u32);
- Log(("system_index = %d, %d\n", u32, u32 >> 2));
- switch (cb)
- {
- case 4:
- if (u32 == SYSTEM_INFO_INDEX_VALID || u32 == SYSTEM_INFO_INDEX_INVALID)
- s->uSystemInfoIndex = u32;
- else
- {
- /* see comment at the declaration of u8IndexShift */
- if ((u32 > SYSTEM_INFO_INDEX_END) && (s->u8IndexShift == 0))
- {
- if (((u32 >> 2) < SYSTEM_INFO_INDEX_END) && ((u32 & 0x3)) == 0)
- {
- s->u8IndexShift = 2;
- }
- }
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
- u32 >>= s->u8IndexShift;
- Assert(u32 < SYSTEM_INFO_INDEX_END);
- s->uSystemInfoIndex = u32;
- }
- break;
+ if (u32 == SYSTEM_INFO_INDEX_VALID || u32 == SYSTEM_INFO_INDEX_INVALID)
+ pThis->uSystemInfoIndex = u32;
+ else
+ {
+ /* see comment at the declaration of u8IndexShift */
+ if (u32 > SYSTEM_INFO_INDEX_END && pThis->u8IndexShift == 0)
+ {
+ if ((u32 >> 2) < SYSTEM_INFO_INDEX_END && (u32 & 0x3) == 0)
+ pThis->u8IndexShift = 2;
+ }
- default:
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- break;
+ u32 >>= pThis->u8IndexShift;
+ Assert(u32 < SYSTEM_INFO_INDEX_END);
+ pThis->uSystemInfoIndex = u32;
}
+
+ DEVACPI_UNLOCK(pThis);
return VINF_SUCCESS;
}
+/**
+ * @callback_method_impl{FNIOMIOPORTIN, System info data}
+ */
PDMBOTHCBDECL(int) acpiSysInfoDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
- ACPIState *s = (ACPIState *)pvUser;
+ if (cb != 4)
+ return VERR_IOM_IOPORT_UNUSED;
- switch (cb)
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ int rc = VINF_SUCCESS;
+ unsigned const uSystemInfoIndex = pThis->uSystemInfoIndex;
+ switch (uSystemInfoIndex)
{
- case 4:
- switch (s->uSystemInfoIndex)
- {
- case SYSTEM_INFO_INDEX_LOW_MEMORY_LENGTH:
- *pu32 = s->cbRamLow;
- break;
+ case SYSTEM_INFO_INDEX_LOW_MEMORY_LENGTH:
+ *pu32 = pThis->cbRamLow;
+ break;
- case SYSTEM_INFO_INDEX_HIGH_MEMORY_LENGTH:
- *pu32 = s->cbRamHigh >> 16; /* 64KB units */
- Assert(((uint64_t)*pu32 << 16) == s->cbRamHigh);
- break;
+ case SYSTEM_INFO_INDEX_HIGH_MEMORY_LENGTH:
+ *pu32 = pThis->cbRamHigh >> 16; /* 64KB units */
+ Assert(((uint64_t)*pu32 << 16) == pThis->cbRamHigh);
+ break;
- case SYSTEM_INFO_INDEX_USE_IOAPIC:
- *pu32 = s->u8UseIOApic;
- break;
+ case SYSTEM_INFO_INDEX_USE_IOAPIC:
+ *pu32 = pThis->u8UseIOApic;
+ break;
- case SYSTEM_INFO_INDEX_HPET_STATUS:
- *pu32 = s->fUseHpet ? ( STA_DEVICE_PRESENT_MASK
- | STA_DEVICE_ENABLED_MASK
- | STA_DEVICE_SHOW_IN_UI_MASK
- | STA_DEVICE_FUNCTIONING_PROPERLY_MASK)
- : 0;
- break;
+ case SYSTEM_INFO_INDEX_HPET_STATUS:
+ *pu32 = pThis->fUseHpet
+ ? ( STA_DEVICE_PRESENT_MASK
+ | STA_DEVICE_ENABLED_MASK
+ | STA_DEVICE_SHOW_IN_UI_MASK
+ | STA_DEVICE_FUNCTIONING_PROPERLY_MASK)
+ : 0;
+ break;
- case SYSTEM_INFO_INDEX_SMC_STATUS:
- *pu32 = s->fUseSmc ? ( STA_DEVICE_PRESENT_MASK
- | STA_DEVICE_ENABLED_MASK
- /* no need to show this device in the UI */
- | STA_DEVICE_FUNCTIONING_PROPERLY_MASK)
- : 0;
- break;
+ case SYSTEM_INFO_INDEX_SMC_STATUS:
+ *pu32 = pThis->fUseSmc
+ ? ( STA_DEVICE_PRESENT_MASK
+ | STA_DEVICE_ENABLED_MASK
+ /* no need to show this device in the UI */
+ | STA_DEVICE_FUNCTIONING_PROPERLY_MASK)
+ : 0;
+ break;
- case SYSTEM_INFO_INDEX_FDC_STATUS:
- *pu32 = s->fUseFdc ? ( STA_DEVICE_PRESENT_MASK
- | STA_DEVICE_ENABLED_MASK
- | STA_DEVICE_SHOW_IN_UI_MASK
- | STA_DEVICE_FUNCTIONING_PROPERLY_MASK)
- : 0;
- break;
+ case SYSTEM_INFO_INDEX_FDC_STATUS:
+ *pu32 = pThis->fUseFdc
+ ? ( STA_DEVICE_PRESENT_MASK
+ | STA_DEVICE_ENABLED_MASK
+ | STA_DEVICE_SHOW_IN_UI_MASK
+ | STA_DEVICE_FUNCTIONING_PROPERLY_MASK)
+ : 0;
+ break;
- case SYSTEM_INFO_INDEX_NIC_ADDRESS:
- *pu32 = s->u32NicPciAddress;
- break;
+ case SYSTEM_INFO_INDEX_NIC_ADDRESS:
+ *pu32 = pThis->u32NicPciAddress;
+ break;
- case SYSTEM_INFO_INDEX_AUDIO_ADDRESS:
- *pu32 = s->u32AudioPciAddress;
- break;
+ case SYSTEM_INFO_INDEX_AUDIO_ADDRESS:
+ *pu32 = pThis->u32AudioPciAddress;
+ break;
- case SYSTEM_INFO_INDEX_POWER_STATES:
- *pu32 = RT_BIT(0) | RT_BIT(5); /* S1 and S5 always exposed */
- if (s->fS1Enabled) /* Optionally expose S1 and S4 */
- *pu32 |= RT_BIT(1);
- if (s->fS4Enabled)
- *pu32 |= RT_BIT(4);
- break;
+ case SYSTEM_INFO_INDEX_POWER_STATES:
+ *pu32 = RT_BIT(0) | RT_BIT(5); /* S1 and S5 always exposed */
+ if (pThis->fS1Enabled) /* Optionally expose S1 and S4 */
+ *pu32 |= RT_BIT(1);
+ if (pThis->fS4Enabled)
+ *pu32 |= RT_BIT(4);
+ break;
- case SYSTEM_INFO_INDEX_IOC_ADDRESS:
- *pu32 = s->u32IocPciAddress;
- break;
+ case SYSTEM_INFO_INDEX_IOC_ADDRESS:
+ *pu32 = pThis->u32IocPciAddress;
+ break;
- case SYSTEM_INFO_INDEX_HBC_ADDRESS:
- *pu32 = s->u32HbcPciAddress;
- break;
+ case SYSTEM_INFO_INDEX_HBC_ADDRESS:
+ *pu32 = pThis->u32HbcPciAddress;
+ break;
- case SYSTEM_INFO_INDEX_PCI_BASE:
- /** @todo: couldn't MCFG be in 64-bit range? */
- Assert(s->u64PciConfigMMioAddress < 0xffffffff);
- *pu32 = (uint32_t)s->u64PciConfigMMioAddress;
- break;
+ case SYSTEM_INFO_INDEX_PCI_BASE:
+ /** @todo couldn't MCFG be in 64-bit range? */
+ Assert(pThis->u64PciConfigMMioAddress < 0xffffffff);
+ *pu32 = (uint32_t)pThis->u64PciConfigMMioAddress;
+ break;
- case SYSTEM_INFO_INDEX_PCI_LENGTH:
- /** @todo: couldn't MCFG be in 64-bit range? */
- Assert(s->u64PciConfigMMioLength< 0xffffffff);
- *pu32 = (uint32_t)s->u64PciConfigMMioLength;
- break;
+ case SYSTEM_INFO_INDEX_PCI_LENGTH:
+ /** @todo couldn't MCFG be in 64-bit range? */
+ Assert(pThis->u64PciConfigMMioLength< 0xffffffff);
+ *pu32 = (uint32_t)pThis->u64PciConfigMMioLength;
+ break;
- /* This is only for compatibility with older saved states that
- may include ACPI code that read these values. Legacy is
- a wonderful thing, isn't it? :-) */
- case SYSTEM_INFO_INDEX_CPU0_STATUS:
- case SYSTEM_INFO_INDEX_CPU1_STATUS:
- case SYSTEM_INFO_INDEX_CPU2_STATUS:
- case SYSTEM_INFO_INDEX_CPU3_STATUS:
- *pu32 = ( s->fShowCpu
- && s->uSystemInfoIndex - SYSTEM_INFO_INDEX_CPU0_STATUS < s->cCpus
- && VMCPUSET_IS_PRESENT(&s->CpuSetAttached,
- s->uSystemInfoIndex - SYSTEM_INFO_INDEX_CPU0_STATUS))
- ? ( STA_DEVICE_PRESENT_MASK
- | STA_DEVICE_ENABLED_MASK
- | STA_DEVICE_SHOW_IN_UI_MASK
- | STA_DEVICE_FUNCTIONING_PROPERLY_MASK)
- : 0;
- break;
+ /* This is only for compatibility with older saved states that
+ may include ACPI code that read these values. Legacy is
+ a wonderful thing, isn't it? :-) */
+ case SYSTEM_INFO_INDEX_CPU0_STATUS:
+ case SYSTEM_INFO_INDEX_CPU1_STATUS:
+ case SYSTEM_INFO_INDEX_CPU2_STATUS:
+ case SYSTEM_INFO_INDEX_CPU3_STATUS:
+ *pu32 = ( pThis->fShowCpu
+ && pThis->uSystemInfoIndex - SYSTEM_INFO_INDEX_CPU0_STATUS < pThis->cCpus
+ && VMCPUSET_IS_PRESENT(&pThis->CpuSetAttached,
+ pThis->uSystemInfoIndex - SYSTEM_INFO_INDEX_CPU0_STATUS) )
+ ? ( STA_DEVICE_PRESENT_MASK
+ | STA_DEVICE_ENABLED_MASK
+ | STA_DEVICE_SHOW_IN_UI_MASK
+ | STA_DEVICE_FUNCTIONING_PROPERLY_MASK)
+ : 0;
+ break;
- case SYSTEM_INFO_INDEX_RTC_STATUS:
- *pu32 = s->fShowRtc ? ( STA_DEVICE_PRESENT_MASK
- | STA_DEVICE_ENABLED_MASK
- | STA_DEVICE_SHOW_IN_UI_MASK
- | STA_DEVICE_FUNCTIONING_PROPERLY_MASK)
- : 0;
- break;
+ case SYSTEM_INFO_INDEX_RTC_STATUS:
+ *pu32 = pThis->fShowRtc
+ ? ( STA_DEVICE_PRESENT_MASK
+ | STA_DEVICE_ENABLED_MASK
+ | STA_DEVICE_SHOW_IN_UI_MASK
+ | STA_DEVICE_FUNCTIONING_PROPERLY_MASK)
+ : 0;
+ break;
- case SYSTEM_INFO_INDEX_CPU_LOCKED:
- {
- if (s->idCpuLockCheck < VMM_MAX_CPU_COUNT)
- {
- *pu32 = VMCPUSET_IS_PRESENT(&s->CpuSetLocked, s->idCpuLockCheck);
- s->idCpuLockCheck = UINT32_C(0xffffffff); /* Make the entry invalid */
- }
- else
- {
- AssertMsgFailed(("ACPI: CPU lock check protocol violation\n"));
- /* Always return locked status just to be safe */
- *pu32 = 1;
- }
- break;
- }
+ case SYSTEM_INFO_INDEX_CPU_LOCKED:
+ if (pThis->idCpuLockCheck < VMM_MAX_CPU_COUNT)
+ {
+ *pu32 = VMCPUSET_IS_PRESENT(&pThis->CpuSetLocked, pThis->idCpuLockCheck);
+ pThis->idCpuLockCheck = UINT32_C(0xffffffff); /* Make the entry invalid */
+ }
+ else
+ {
+ rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "CPU lock check protocol violation (idCpuLockCheck=%#x)\n",
+ pThis->idCpuLockCheck);
+ /* Always return locked status just to be safe */
+ *pu32 = 1;
+ }
+ break;
- case SYSTEM_INFO_INDEX_CPU_EVENT_TYPE:
- *pu32 = s->u32CpuEventType;
- break;
+ case SYSTEM_INFO_INDEX_CPU_EVENT_TYPE:
+ *pu32 = pThis->u32CpuEventType;
+ break;
- case SYSTEM_INFO_INDEX_CPU_EVENT:
- *pu32 = s->u32CpuEvent;
- break;
+ case SYSTEM_INFO_INDEX_CPU_EVENT:
+ *pu32 = pThis->u32CpuEvent;
+ break;
- /* Solaris 9 tries to read from this index */
- case SYSTEM_INFO_INDEX_INVALID:
- *pu32 = 0;
- break;
+ case SYSTEM_INFO_INDEX_SERIAL0_IOBASE:
+ *pu32 = pThis->uSerial0IoPortBase;
+ break;
- default:
- AssertMsgFailed(("Invalid system info index %d\n", s->uSystemInfoIndex));
- break;
- }
+ case SYSTEM_INFO_INDEX_SERIAL0_IRQ:
+ *pu32 = pThis->uSerial0Irq;
+ break;
+
+ case SYSTEM_INFO_INDEX_SERIAL1_IOBASE:
+ *pu32 = pThis->uSerial1IoPortBase;
+ break;
+
+ case SYSTEM_INFO_INDEX_SERIAL1_IRQ:
+ *pu32 = pThis->uSerial1Irq;
+ break;
+
+ case SYSTEM_INFO_INDEX_END:
+ /** @todo why isn't this setting any output value? */
+ break;
+
+ /* Solaris 9 tries to read from this index */
+ case SYSTEM_INFO_INDEX_INVALID:
+ *pu32 = 0;
break;
default:
- return VERR_IOM_IOPORT_UNUSED;
+ *pu32 = UINT32_MAX;
+ rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u idx=%u\n", cb, Port, pThis->uBatteryIndex);
+ break;
}
- Log(("index %d val %d\n", s->uSystemInfoIndex, *pu32));
- return VINF_SUCCESS;
+ DEVACPI_UNLOCK(pThis);
+ Log(("acpiSysInfoDataRead: idx=%d val=%#x (%d) rc=%Rrc\n", uSystemInfoIndex, *pu32, *pu32, rc));
+ return rc;
}
+/**
+ * @callback_method_impl{FNIOMIOPORTOUT, System info data}
+ */
PDMBOTHCBDECL(int) acpiSysInfoDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- ACPIState *s = (ACPIState *)pvUser;
+ ACPIState *pThis = (ACPIState *)pvUser;
+ if (cb != 4)
+ return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x idx=%u\n", cb, Port, u32, pThis->uSystemInfoIndex);
- Log(("addr=%#x cb=%d u32=%#x si=%#x\n", Port, cb, u32, s->uSystemInfoIndex));
+ DEVACPI_LOCK_R3(pThis);
+ Log(("addr=%#x cb=%d u32=%#x si=%#x\n", Port, cb, u32, pThis->uSystemInfoIndex));
- if (cb == 4)
+ int rc = VINF_SUCCESS;
+ switch (pThis->uSystemInfoIndex)
{
- switch (s->uSystemInfoIndex)
- {
- case SYSTEM_INFO_INDEX_INVALID:
- AssertMsg(u32 == 0xbadc0de, ("u32=%u\n", u32));
- s->u8IndexShift = 0;
- break;
+ case SYSTEM_INFO_INDEX_INVALID:
+ AssertMsg(u32 == 0xbadc0de, ("u32=%u\n", u32));
+ pThis->u8IndexShift = 0;
+ break;
- case SYSTEM_INFO_INDEX_VALID:
- AssertMsg(u32 == 0xbadc0de, ("u32=%u\n", u32));
- s->u8IndexShift = 2;
- break;
+ case SYSTEM_INFO_INDEX_VALID:
+ AssertMsg(u32 == 0xbadc0de, ("u32=%u\n", u32));
+ pThis->u8IndexShift = 2;
+ break;
- case SYSTEM_INFO_INDEX_CPU_LOCK_CHECK:
- s->idCpuLockCheck = u32;
- break;
+ case SYSTEM_INFO_INDEX_CPU_LOCK_CHECK:
+ pThis->idCpuLockCheck = u32;
+ break;
- case SYSTEM_INFO_INDEX_CPU_LOCKED:
- if (u32 < s->cCpus)
- VMCPUSET_DEL(&s->CpuSetLocked, u32); /* Unlock the CPU */
- else
- LogRel(("ACPI: CPU %u does not exist\n", u32));
- break;
+ case SYSTEM_INFO_INDEX_CPU_LOCKED:
+ if (u32 < pThis->cCpus)
+ VMCPUSET_DEL(&pThis->CpuSetLocked, u32); /* Unlock the CPU */
+ else
+ LogRel(("ACPI: CPU %u does not exist\n", u32));
+ break;
- default:
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x system_index=%#x\n",
- Port, cb, u32, s->uSystemInfoIndex));
- break;
- }
+ default:
+ rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x idx=%u\n", cb, Port, u32, pThis->uSystemInfoIndex);
+ break;
}
- else
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- return VINF_SUCCESS;
-}
-/** @todo Don't call functions, but do the job in the read/write handlers
- * here! */
+ DEVACPI_UNLOCK(pThis);
+ return rc;
+}
-/* IO Helpers */
+/**
+ * @callback_method_impl{FNIOMIOPORTIN, PM1a Enable}
+ */
PDMBOTHCBDECL(int) acpiPm1aEnRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
- switch (cb)
- {
- case 2:
- *pu32 = acpiPm1aEnReadw((ACPIState*)pvUser, Port);
- break;
- default:
- return VERR_IOM_IOPORT_UNUSED;
- }
+ if (cb != 2)
+ return VERR_IOM_IOPORT_UNUSED;
+
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ *pu32 = pThis->pm1a_en;
+
+ DEVACPI_UNLOCK(pThis);
+ Log(("acpiPm1aEnRead -> %#x\n", *pu32));
return VINF_SUCCESS;
}
-PDMBOTHCBDECL(int) acpiPm1aStsRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
+/**
+ * @callback_method_impl{FNIOMIOPORTOUT, PM1a Enable}
+ */
+PDMBOTHCBDECL(int) acpiPM1aEnWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- switch (cb)
- {
- case 2:
- *pu32 = acpiPm1aStsReadw((ACPIState*)pvUser, Port);
- break;
- default:
- AssertMsgFailed(("PM1 status read: width %d\n", cb));
- return VERR_IOM_IOPORT_UNUSED;
- }
+ if (cb != 2 && cb != 4)
+ return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x\n", cb, Port, u32);
+
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ Log(("acpiPM1aEnWrite: %#x (%#x)\n", u32, u32 & ~(RSR_EN | IGN_EN) & 0xffff));
+ u32 &= ~(RSR_EN | IGN_EN);
+ u32 &= 0xffff;
+ update_pm1a(pThis, pThis->pm1a_sts, u32);
+
+ DEVACPI_UNLOCK(pThis);
return VINF_SUCCESS;
}
-PDMBOTHCBDECL(int) acpiPm1aCtlRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
+/**
+ * @callback_method_impl{FNIOMIOPORTIN, PM1a Status}
+ */
+PDMBOTHCBDECL(int) acpiPm1aStsRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
- switch (cb)
+ if (cb != 2)
{
- case 2:
- *pu32 = acpiPm1aCtlReadw((ACPIState*)pvUser, Port);
- break;
- default:
- AssertMsgFailed(("PM1 control read: width %d\n", cb));
- return VERR_IOM_IOPORT_UNUSED;
+ int rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u\n", cb, Port);
+ return rc == VINF_SUCCESS ? VERR_IOM_IOPORT_UNUSED : rc;
}
+
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ *pu32 = pThis->pm1a_sts;
+
+ DEVACPI_UNLOCK(pThis);
+ Log(("acpiPm1aStsRead: %#x\n", *pu32));
return VINF_SUCCESS;
}
-PDMBOTHCBDECL(int) acpiPM1aEnWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
+/**
+ * @callback_method_impl{FNIOMIOPORTOUT, PM1a Status}
+ */
+PDMBOTHCBDECL(int) acpiPM1aStsWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- switch (cb)
- {
- case 2:
- acpiPM1aEnWritew((ACPIState*)pvUser, Port, u32);
- break;
- case 4:
- acpiPM1aEnWritew((ACPIState*)pvUser, Port, u32 & 0xffff);
- break;
- default:
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- break;
- }
+ if (cb != 2 && cb != 4)
+ return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x\n", cb, Port, u32);
+
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ Log(("acpiPM1aStsWrite: %#x (%#x)\n", u32, u32 & ~(RSR_STS | IGN_STS) & 0xffff));
+ u32 &= 0xffff;
+ if (u32 & PWRBTN_STS)
+ pThis->fPowerButtonHandled = true; /* Remember that the guest handled the last power button event */
+ u32 = pThis->pm1a_sts & ~(u32 & ~(RSR_STS | IGN_STS));
+ update_pm1a(pThis, u32, pThis->pm1a_en);
+
+ DEVACPI_UNLOCK(pThis);
return VINF_SUCCESS;
}
-PDMBOTHCBDECL(int) acpiPM1aStsWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
+/**
+ * @callback_method_impl{FNIOMIOPORTIN, PM1a Control}
+ */
+PDMBOTHCBDECL(int) acpiPm1aCtlRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
- switch (cb)
+ if (cb != 2)
{
- case 2:
- acpiPM1aStsWritew((ACPIState*)pvUser, Port, u32);
- break;
- case 4:
- acpiPM1aStsWritew((ACPIState*)pvUser, Port, u32 & 0xffff);
- break;
- default:
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- break;
+ int rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u\n", cb, Port);
+ return rc == VINF_SUCCESS ? VERR_IOM_IOPORT_UNUSED : rc;
}
+
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ *pu32 = pThis->pm1a_ctl;
+
+ DEVACPI_UNLOCK(pThis);
+ Log(("acpiPm1aCtlRead: %#x\n", *pu32));
return VINF_SUCCESS;
}
+/**
+ * @callback_method_impl{FNIOMIOPORTOUT, PM1a Control}
+ */
PDMBOTHCBDECL(int) acpiPM1aCtlWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- switch (cb)
+ if (cb != 2 && cb != 4)
+ return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x\n", cb, Port, u32);
+
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ Log(("acpiPM1aCtlWrite: %#x (%#x)\n", u32, u32 & ~(RSR_CNT | IGN_CNT) & 0xffff));
+ u32 &= 0xffff;
+ pThis->pm1a_ctl = u32 & ~(RSR_CNT | IGN_CNT);
+
+ int rc = VINF_SUCCESS;
+ uint32_t const uSleepState = (pThis->pm1a_ctl >> SLP_TYPx_SHIFT) & SLP_TYPx_MASK;
+ if (uSleepState != pThis->uSleepState)
{
- case 2:
- return acpiPM1aCtlWritew((ACPIState*)pvUser, Port, u32);
- case 4:
- return acpiPM1aCtlWritew((ACPIState*)pvUser, Port, u32 & 0xffff);
- default:
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- break;
+ pThis->uSleepState = uSleepState;
+ switch (uSleepState)
+ {
+ case 0x00: /* S0 */
+ break;
+
+ case 0x01: /* S1 */
+ if (pThis->fS1Enabled)
+ {
+ LogRel(("Entering S1 power state (powered-on suspend)\n"));
+ rc = acpiSleep(pThis);
+ break;
+ }
+ LogRel(("Ignoring guest attempt to enter S1 power state (powered-on suspend)!\n"));
+ /* fall thru */
+
+ case 0x04: /* S4 */
+ if (pThis->fS4Enabled)
+ {
+ LogRel(("Entering S4 power state (suspend to disk)\n"));
+ rc = acpiPowerOff(pThis);/* Same behavior as S5 */
+ break;
+ }
+ LogRel(("Ignoring guest attempt to enter S4 power state (suspend to disk)!\n"));
+ /* fall thru */
+
+ case 0x05: /* S5 */
+ LogRel(("Entering S5 power state (power down)\n"));
+ rc = acpiPowerOff(pThis);
+ break;
+
+ default:
+ rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "Unknown sleep state %#x (u32=%#x)\n", uSleepState, u32);
+ break;
+ }
}
- return VINF_SUCCESS;
+
+ DEVACPI_UNLOCK(pThis);
+ Log(("acpiPM1aCtlWrite: rc=%Rrc\n", rc));
+ return rc;
}
#endif /* IN_RING3 */
/**
- * PMTMR readable from host/guest.
+ * @callback_method_impl{FNIOMIOPORTIN, PMTMR}
+ *
+ * @remarks Only I/O port currently implemented in all contexts.
*/
PDMBOTHCBDECL(int) acpiPMTmrRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
- if (cb == 4)
+ if (cb != 4)
+ return VERR_IOM_IOPORT_UNUSED;
+
+ ACPIState *pThis = PDMINS_2_DATA(pDevIns, ACPIState *);
+
+ /*
+ * We use the clock lock to serialize access to u64PmTimerInitial and to
+ * make sure we get a reliable time from the clock.
+ */
+ int rc = TMTimerLock(pThis->CTX_SUFF(pPmTimer), VINF_IOM_HC_IOPORT_READ);
+ if (rc == VINF_SUCCESS)
{
- ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *);
- uint64_t u64Now = TMTimerGet(s->CTX_SUFF(ts));
- uint64_t u64Seen;
- do
- {
- u64Seen = ASMAtomicReadU64(&s->u64PmTimerLastSeen);
- if (u64Now < u64Seen)
- u64Now = u64Seen + 1;
- } while (!ASMAtomicCmpXchgU64(&s->u64PmTimerLastSeen, u64Now, u64Seen));
+ uint64_t const u64PmTimerInitial = pThis->u64PmTimerInitial;
+ uint64_t u64Now = TMTimerGet(pThis->CTX_SUFF(pPmTimer));
+ TMTimerUnlock(pThis->CTX_SUFF(pPmTimer));
- uint64_t u64Elapsed = u64Now - s->u64PmTimerInitial;
- *pu32 = ASMMultU64ByU32DivByU32(u64Elapsed, PM_TMR_FREQ, TMTimerGetFreq(s->CTX_SUFF(ts)));
+ /*
+ * Calculate the return value.
+ */
+ DBGFTRACE_PDM_U64_TAG(pDevIns, u64Now, "acpi");
+ uint64_t u64Elapsed = u64Now - u64PmTimerInitial;
+ *pu32 = ASMMultU64ByU32DivByU32(u64Elapsed, PM_TMR_FREQ, TMTimerGetFreq(pThis->CTX_SUFF(pPmTimer)));
Log(("acpi: acpiPMTmrRead -> %#x\n", *pu32));
- return VINF_SUCCESS;
}
- return VERR_IOM_IOPORT_UNUSED;
+
+ return rc;
}
#ifdef IN_RING3
+/**
+ * @callback_method_impl{FNIOMIOPORTIN, GPE0 Status}
+ */
PDMBOTHCBDECL(int) acpiGpe0StsRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
- switch (cb)
+ if (cb != 1)
{
- case 1:
- *pu32 = acpiGpe0StsReadb((ACPIState*)pvUser, Port);
- break;
- default:
- return VERR_IOM_IOPORT_UNUSED;
+ int rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u\n", cb, Port);
+ return rc == VINF_SUCCESS ? VERR_IOM_IOPORT_UNUSED : rc;
}
+
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ *pu32 = pThis->gpe0_sts & 0xff;
+
+ DEVACPI_UNLOCK(pThis);
+ Log(("acpiGpe0StsRead: %#x\n", *pu32));
return VINF_SUCCESS;
}
-PDMBOTHCBDECL(int) acpiGpe0EnRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
+/**
+ * @callback_method_impl{FNIOMIOPORTOUT, GPE0 Status}
+ */
+PDMBOTHCBDECL(int) acpiGpe0StsWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- switch (cb)
- {
- case 1:
- *pu32 = acpiGpe0EnReadb((ACPIState*)pvUser, Port);
- break;
- default:
- return VERR_IOM_IOPORT_UNUSED;
- }
+ if (cb != 1)
+ return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x\n", cb, Port, u32);
+
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ Log(("acpiGpe0StsWrite: %#x (%#x)\n", u32, pThis->gpe0_sts & ~u32));
+ u32 = pThis->gpe0_sts & ~u32;
+ update_gpe0(pThis, u32, pThis->gpe0_en);
+
+ DEVACPI_UNLOCK(pThis);
return VINF_SUCCESS;
}
-PDMBOTHCBDECL(int) acpiGpe0StsWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
+/**
+ * @callback_method_impl{FNIOMIOPORTIN, GPE0 Enable}
+ */
+PDMBOTHCBDECL(int) acpiGpe0EnRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
- switch (cb)
+ if (cb != 1)
{
- case 1:
- acpiGpe0StsWriteb((ACPIState*)pvUser, Port, u32);
- break;
- default:
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- break;
+ int rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u\n", cb, Port);
+ return rc == VINF_SUCCESS ? VERR_IOM_IOPORT_UNUSED : rc;
}
+
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ *pu32 = pThis->gpe0_en & 0xff;
+
+ DEVACPI_UNLOCK(pThis);
+ Log(("acpiGpe0EnRead: %#x\n", *pu32));
return VINF_SUCCESS;
}
+/**
+ * @callback_method_impl{FNIOMIOPORTOUT, GPE0 Enable}
+ */
PDMBOTHCBDECL(int) acpiGpe0EnWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- switch (cb)
- {
- case 1:
- acpiGpe0EnWriteb((ACPIState*)pvUser, Port, u32);
- break;
- default:
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- break;
- }
+ if (cb != 1)
+ return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x\n", cb, Port, u32);
+
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ Log(("acpiGpe0EnWrite: %#x\n", u32));
+ update_gpe0(pThis, pThis->gpe0_sts, u32);
+
+ DEVACPI_UNLOCK(pThis);
return VINF_SUCCESS;
}
+/**
+ * @callback_method_impl{FNIOMIOPORTOUT, SMI_CMD}
+ */
PDMBOTHCBDECL(int) acpiSmiWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- switch (cb)
- {
- case 1:
- acpiSmiWriteU8((ACPIState*)pvUser, Port, u32);
- break;
- default:
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- break;
- }
+ Log(("acpiSmiWrite %#x\n", u32));
+ if (cb != 1)
+ return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x\n", cb, Port, u32);
+
+ ACPIState *pThis = (ACPIState *)pvUser;
+ DEVACPI_LOCK_R3(pThis);
+
+ if (u32 == ACPI_ENABLE)
+ pThis->pm1a_ctl |= SCI_EN;
+ else if (u32 == ACPI_DISABLE)
+ pThis->pm1a_ctl &= ~SCI_EN;
+ else
+ Log(("acpiSmiWrite: %#x <- unknown value\n", u32));
+
+ DEVACPI_UNLOCK(pThis);
return VINF_SUCCESS;
}
+/**
+ * @{FNIOMIOPORTOUT, ACPI_RESET_BLK}
+ */
PDMBOTHCBDECL(int) acpiResetWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- switch (cb)
- {
- case 1:
- return acpiResetWriteU8((ACPIState*)pvUser, Port, u32);
- default:
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- break;
- }
- return VINF_SUCCESS;
+ Log(("acpiResetWrite: %#x\n", u32));
+ if (cb != 1)
+ return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x\n", cb, Port, u32);
+
+ /* No state locking required. */
+ int rc = VINF_SUCCESS;
+ if (u32 == ACPI_RESET_REG_VAL)
+ rc = PDMDevHlpVMReset(pDevIns);
+ else
+ Log(("acpiResetWrite: %#x <- unknown value\n", u32));
+
+ return rc;
}
-#ifdef DEBUG_ACPI
+# ifdef DEBUG_ACPI
+/**
+ * @callback_method_impl{FNIOMIOPORTOUT, Debug hex value logger}
+ */
PDMBOTHCBDECL(int) acpiDhexWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
switch (cb)
@@ -2004,12 +1744,14 @@ PDMBOTHCBDECL(int) acpiDhexWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port
Log(("%#10x\n", u32));
break;
default:
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- break;
+ return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x\n", cb, Port, u32);
}
return VINF_SUCCESS;
}
+/**
+ * @callback_method_impl{FNIOMIOPORTOUT, Debug char logger}
+ */
PDMBOTHCBDECL(int) acpiDchrWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
switch (cb)
@@ -2018,21 +1760,44 @@ PDMBOTHCBDECL(int) acpiDchrWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port
Log(("%c", u32 & 0xff));
break;
default:
- AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- break;
+ return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x\n", cb, Port, u32);
}
return VINF_SUCCESS;
}
-#endif /* DEBUG_ACPI */
+# endif /* DEBUG_ACPI */
+
+/**
+ * Used to calculate the value of a PM I/O port.
+ *
+ * @returns The actual I/O port value.
+ * @param pThis The ACPI instance.
+ * @param offset The offset into the I/O space, or -1 if invalid.
+ */
+static RTIOPORT acpiCalcPmPort(ACPIState *pThis, int32_t offset)
+{
+ Assert(pThis->uPmIoPortBase != 0);
-static int acpiRegisterPmHandlers(ACPIState* pThis)
+ if (offset == -1)
+ return 0;
+
+ return (RTIOPORT)(pThis->uPmIoPortBase + offset);
+}
+
+/**
+ * Called by acpiLoadState and acpiUpdatePmHandlers to register the PM1a, PM
+ * timer and GPE0 I/O ports.
+ *
+ * @returns VBox status code.
+ * @param pThis The ACPI instance.
+ */
+static int acpiRegisterPmHandlers(ACPIState *pThis)
{
int rc = VINF_SUCCESS;
#define R(offset, cnt, writer, reader, description) \
do { \
- rc = PDMDevHlpIOPortRegister(pThis->pDevIns, acpiPmPort(pThis, offset), cnt, pThis, writer, reader, \
+ rc = PDMDevHlpIOPortRegister(pThis->pDevIns, acpiCalcPmPort(pThis, offset), cnt, pThis, writer, reader, \
NULL, NULL, description); \
if (RT_FAILURE(rc)) \
return rc; \
@@ -2051,7 +1816,7 @@ static int acpiRegisterPmHandlers(ACPIState* pThis)
/* register RC stuff */
if (pThis->fGCEnabled)
{
- rc = PDMDevHlpIOPortRegisterRC(pThis->pDevIns, acpiPmPort(pThis, PM_TMR_OFFSET),
+ rc = PDMDevHlpIOPortRegisterRC(pThis->pDevIns, acpiCalcPmPort(pThis, PM_TMR_OFFSET),
1, 0, NULL, "acpiPMTmrRead",
NULL, NULL, "ACPI PM Timer");
AssertRCReturn(rc, rc);
@@ -2060,7 +1825,7 @@ static int acpiRegisterPmHandlers(ACPIState* pThis)
/* register R0 stuff */
if (pThis->fR0Enabled)
{
- rc = PDMDevHlpIOPortRegisterR0(pThis->pDevIns, acpiPmPort(pThis, PM_TMR_OFFSET),
+ rc = PDMDevHlpIOPortRegisterR0(pThis->pDevIns, acpiCalcPmPort(pThis, PM_TMR_OFFSET),
1, 0, NULL, "acpiPMTmrRead",
NULL, NULL, "ACPI PM Timer");
AssertRCReturn(rc, rc);
@@ -2069,11 +1834,18 @@ static int acpiRegisterPmHandlers(ACPIState* pThis)
return rc;
}
+/**
+ * Called by acpiLoadState and acpiUpdatePmHandlers to unregister the PM1a, PM
+ * timer and GPE0 I/O ports.
+ *
+ * @returns VBox status code.
+ * @param pThis The ACPI instance.
+ */
static int acpiUnregisterPmHandlers(ACPIState *pThis)
{
#define U(offset, cnt) \
do { \
- int rc = PDMDevHlpIOPortDeregister(pThis->pDevIns, acpiPmPort(pThis, offset), cnt); \
+ int rc = PDMDevHlpIOPortDeregister(pThis->pDevIns, acpiCalcPmPort(pThis, offset), cnt); \
AssertRCReturn(rc, rc); \
} while (0)
#define L (GPE0_BLK_LEN / 2)
@@ -2091,6 +1863,41 @@ static int acpiUnregisterPmHandlers(ACPIState *pThis)
}
/**
+ * Called by acpiPciConfigWrite and acpiReset to change the location of the
+ * PM1a, PM timer and GPE0 ports.
+ *
+ * @returns VBox status code.
+ *
+ * @param pThis The ACPI instance.
+ * @param NewIoPortBase The new base address of the I/O ports.
+ */
+static int acpiUpdatePmHandlers(ACPIState *pThis, RTIOPORT NewIoPortBase)
+{
+ Log(("acpi: rebasing PM 0x%x -> 0x%x\n", pThis->uPmIoPortBase, NewIoPortBase));
+ if (NewIoPortBase != pThis->uPmIoPortBase)
+ {
+ int rc = acpiUnregisterPmHandlers(pThis);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ pThis->uPmIoPortBase = NewIoPortBase;
+
+ rc = acpiRegisterPmHandlers(pThis);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ /* We have to update FADT table acccording to the new base */
+ rc = acpiPlantTables(pThis);
+ AssertRC(rc);
+ if (RT_FAILURE(rc))
+ return rc;
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
* Saved state structure description, version 4.
*/
static const SSMFIELD g_AcpiSavedStateFields4[] =
@@ -2202,9 +2009,9 @@ static DECLCALLBACK(int) acpiLoadState(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle
rc = acpiFetchBatteryInfo(pThis);
if (RT_FAILURE(rc))
return rc;
- rc = acpiPMTimerReset(pThis);
- if (RT_FAILURE(rc))
- return rc;
+ TMTimerLock(pThis->pPmTimerR3, VERR_IGNORED);
+ acpiPmTimerReset(pThis, TMTimerGet(pThis->pPmTimerR3));
+ TMTimerUnlock(pThis->pPmTimerR3);
}
return rc;
}
@@ -2221,28 +2028,425 @@ static DECLCALLBACK(void *) acpiQueryInterface(PPDMIBASE pInterface, const char
}
/**
- * Create the ACPI tables.
+ * Calculate the check sum for some ACPI data before planting it.
+ *
+ * All the bytes must add up to 0.
+ *
+ * @returns check sum.
+ * @param pvSrc What to check sum.
+ * @param cbData The amount of data to checksum.
+ */
+static uint8_t acpiChecksum(const void * const pvSrc, size_t cbData)
+{
+ uint8_t const *pbSrc = (uint8_t const *)pvSrc;
+ uint8_t uSum = 0;
+ for (size_t i = 0; i < cbData; ++i)
+ uSum += pbSrc[i];
+ return -uSum;
+}
+
+/**
+ * Prepare a ACPI table header.
+ */
+static void acpiPrepareHeader(ACPITBLHEADER *header, const char au8Signature[4],
+ uint32_t u32Length, uint8_t u8Revision)
+{
+ memcpy(header->au8Signature, au8Signature, 4);
+ header->u32Length = RT_H2LE_U32(u32Length);
+ header->u8Revision = u8Revision;
+ memcpy(header->au8OemId, "VBOX ", 6);
+ memcpy(header->au8OemTabId, "VBOX", 4);
+ memcpy(header->au8OemTabId+4, au8Signature, 4);
+ header->u32OemRevision = RT_H2LE_U32(1);
+ memcpy(header->au8CreatorId, "ASL ", 4);
+ header->u32CreatorRev = RT_H2LE_U32(0x61);
+}
+
+/**
+ * Initialize a generic address structure (ACPIGENADDR).
*/
-static int acpiPlantTables(ACPIState *s)
+static void acpiWriteGenericAddr(ACPIGENADDR *g, uint8_t u8AddressSpaceId,
+ uint8_t u8RegisterBitWidth, uint8_t u8RegisterBitOffset,
+ uint8_t u8AccessSize, uint64_t u64Address)
+{
+ g->u8AddressSpaceId = u8AddressSpaceId;
+ g->u8RegisterBitWidth = u8RegisterBitWidth;
+ g->u8RegisterBitOffset = u8RegisterBitOffset;
+ g->u8AccessSize = u8AccessSize;
+ g->u64Address = RT_H2LE_U64(u64Address);
+}
+
+/**
+ * Wrapper around PDMDevHlpPhysWrite used when planting ACPI tables.
+ */
+static void acpiPhyscpy(ACPIState *pThis, RTGCPHYS32 dst, const void * const src, size_t size)
+{
+ PDMDevHlpPhysWrite(pThis->pDevIns, dst, src, size);
+}
+
+/**
+ * Plant the Differentiated System Description Table (DSDT).
+ */
+static void acpiSetupDSDT(ACPIState *pThis, RTGCPHYS32 addr,
+ void* pPtr, size_t uDsdtLen)
+{
+ acpiPhyscpy(pThis, addr, pPtr, uDsdtLen);
+}
+
+/**
+ * Plan the Secondary System Description Table (SSDT).
+ */
+static void acpiSetupSSDT(ACPIState *pThis, RTGCPHYS32 addr,
+ void* pPtr, size_t uSsdtLen)
+{
+ acpiPhyscpy(pThis, addr, pPtr, uSsdtLen);
+}
+
+/**
+ * Plant the Firmware ACPI Control Structure (FACS).
+ */
+static void acpiSetupFACS(ACPIState *pThis, RTGCPHYS32 addr)
+{
+ ACPITBLFACS facs;
+
+ memset(&facs, 0, sizeof(facs));
+ memcpy(facs.au8Signature, "FACS", 4);
+ facs.u32Length = RT_H2LE_U32(sizeof(ACPITBLFACS));
+ facs.u32HWSignature = RT_H2LE_U32(0);
+ facs.u32FWVector = RT_H2LE_U32(0);
+ facs.u32GlobalLock = RT_H2LE_U32(0);
+ facs.u32Flags = RT_H2LE_U32(0);
+ facs.u64X_FWVector = RT_H2LE_U64(0);
+ facs.u8Version = 1;
+
+ acpiPhyscpy(pThis, addr, (const uint8_t *)&facs, sizeof(facs));
+}
+
+/**
+ * Plant the Fixed ACPI Description Table (FADT aka FACP).
+ */
+static void acpiSetupFADT(ACPIState *pThis, RTGCPHYS32 GCPhysAcpi1, RTGCPHYS32 GCPhysAcpi2, RTGCPHYS32 GCPhysFacs, RTGCPHYS GCPhysDsdt)
+{
+ ACPITBLFADT fadt;
+
+ /* First the ACPI version 2+ version of the structure. */
+ memset(&fadt, 0, sizeof(fadt));
+ acpiPrepareHeader(&fadt.header, "FACP", sizeof(fadt), 4);
+ fadt.u32FACS = RT_H2LE_U32(GCPhysFacs);
+ fadt.u32DSDT = RT_H2LE_U32(GCPhysDsdt);
+ fadt.u8IntModel = 0; /* dropped from the ACPI 2.0 spec. */
+ fadt.u8PreferredPMProfile = 0; /* unspecified */
+ fadt.u16SCIInt = RT_H2LE_U16(SCI_INT);
+ fadt.u32SMICmd = RT_H2LE_U32(SMI_CMD);
+ fadt.u8AcpiEnable = ACPI_ENABLE;
+ fadt.u8AcpiDisable = ACPI_DISABLE;
+ fadt.u8S4BIOSReq = 0;
+ fadt.u8PStateCnt = 0;
+ fadt.u32PM1aEVTBLK = RT_H2LE_U32(acpiCalcPmPort(pThis, PM1a_EVT_OFFSET));
+ fadt.u32PM1bEVTBLK = RT_H2LE_U32(acpiCalcPmPort(pThis, PM1b_EVT_OFFSET));
+ fadt.u32PM1aCTLBLK = RT_H2LE_U32(acpiCalcPmPort(pThis, PM1a_CTL_OFFSET));
+ fadt.u32PM1bCTLBLK = RT_H2LE_U32(acpiCalcPmPort(pThis, PM1b_CTL_OFFSET));
+ fadt.u32PM2CTLBLK = RT_H2LE_U32(acpiCalcPmPort(pThis, PM2_CTL_OFFSET));
+ fadt.u32PMTMRBLK = RT_H2LE_U32(acpiCalcPmPort(pThis, PM_TMR_OFFSET));
+ fadt.u32GPE0BLK = RT_H2LE_U32(acpiCalcPmPort(pThis, GPE0_OFFSET));
+ fadt.u32GPE1BLK = RT_H2LE_U32(acpiCalcPmPort(pThis, GPE1_OFFSET));
+ fadt.u8PM1EVTLEN = 4;
+ fadt.u8PM1CTLLEN = 2;
+ fadt.u8PM2CTLLEN = 0;
+ fadt.u8PMTMLEN = 4;
+ fadt.u8GPE0BLKLEN = GPE0_BLK_LEN;
+ fadt.u8GPE1BLKLEN = GPE1_BLK_LEN;
+ fadt.u8GPE1BASE = GPE1_BASE;
+ fadt.u8CSTCNT = 0;
+ fadt.u16PLVL2LAT = RT_H2LE_U16(P_LVL2_LAT);
+ fadt.u16PLVL3LAT = RT_H2LE_U16(P_LVL3_LAT);
+ fadt.u16FlushSize = RT_H2LE_U16(FLUSH_SIZE);
+ fadt.u16FlushStride = RT_H2LE_U16(FLUSH_STRIDE);
+ fadt.u8DutyOffset = 0;
+ fadt.u8DutyWidth = 0;
+ fadt.u8DayAlarm = 0;
+ fadt.u8MonAlarm = 0;
+ fadt.u8Century = 0;
+ fadt.u16IAPCBOOTARCH = RT_H2LE_U16(IAPC_BOOT_ARCH_LEGACY_DEV | IAPC_BOOT_ARCH_8042);
+ /** @note WBINVD is required for ACPI versions newer than 1.0 */
+ fadt.u32Flags = RT_H2LE_U32( FADT_FL_WBINVD
+ | FADT_FL_FIX_RTC
+ | FADT_FL_TMR_VAL_EXT
+ | FADT_FL_RESET_REG_SUP);
+
+ /* We have to force physical APIC mode or Linux can't use more than 8 CPUs */
+ if (pThis->fCpuHotPlug)
+ fadt.u32Flags |= RT_H2LE_U32(FADT_FL_FORCE_APIC_PHYS_DEST_MODE);
+
+ acpiWriteGenericAddr(&fadt.ResetReg, 1, 8, 0, 1, ACPI_RESET_BLK);
+ fadt.u8ResetVal = ACPI_RESET_REG_VAL;
+ fadt.u64XFACS = RT_H2LE_U64((uint64_t)GCPhysFacs);
+ fadt.u64XDSDT = RT_H2LE_U64((uint64_t)GCPhysDsdt);
+ acpiWriteGenericAddr(&fadt.X_PM1aEVTBLK, 1, 32, 0, 2, acpiCalcPmPort(pThis, PM1a_EVT_OFFSET));
+ acpiWriteGenericAddr(&fadt.X_PM1bEVTBLK, 0, 0, 0, 0, acpiCalcPmPort(pThis, PM1b_EVT_OFFSET));
+ acpiWriteGenericAddr(&fadt.X_PM1aCTLBLK, 1, 16, 0, 2, acpiCalcPmPort(pThis, PM1a_CTL_OFFSET));
+ acpiWriteGenericAddr(&fadt.X_PM1bCTLBLK, 0, 0, 0, 0, acpiCalcPmPort(pThis, PM1b_CTL_OFFSET));
+ acpiWriteGenericAddr(&fadt.X_PM2CTLBLK, 0, 0, 0, 0, acpiCalcPmPort(pThis, PM2_CTL_OFFSET));
+ acpiWriteGenericAddr(&fadt.X_PMTMRBLK, 1, 32, 0, 3, acpiCalcPmPort(pThis, PM_TMR_OFFSET));
+ acpiWriteGenericAddr(&fadt.X_GPE0BLK, 1, 16, 0, 1, acpiCalcPmPort(pThis, GPE0_OFFSET));
+ acpiWriteGenericAddr(&fadt.X_GPE1BLK, 0, 0, 0, 0, acpiCalcPmPort(pThis, GPE1_OFFSET));
+ fadt.header.u8Checksum = acpiChecksum(&fadt, sizeof(fadt));
+ acpiPhyscpy(pThis, GCPhysAcpi2, &fadt, sizeof(fadt));
+
+ /* Now the ACPI 1.0 version. */
+ fadt.header.u32Length = ACPITBLFADT_VERSION1_SIZE;
+ fadt.u8IntModel = INT_MODEL_DUAL_PIC;
+ fadt.header.u8Checksum = 0; /* Must be zeroed before recalculating checksum! */
+ fadt.header.u8Checksum = acpiChecksum(&fadt, ACPITBLFADT_VERSION1_SIZE);
+ acpiPhyscpy(pThis, GCPhysAcpi1, &fadt, ACPITBLFADT_VERSION1_SIZE);
+}
+
+/**
+ * Plant the root System Description Table.
+ *
+ * The RSDT and XSDT tables are basically identical. The only difference is 32
+ * vs 64 bits addresses for description headers. RSDT is for ACPI 1.0. XSDT for
+ * ACPI 2.0 and up.
+ */
+static int acpiSetupRSDT(ACPIState *pThis, RTGCPHYS32 addr, unsigned int nb_entries, uint32_t *addrs)
+{
+ ACPITBLRSDT *rsdt;
+ const size_t size = sizeof(ACPITBLHEADER) + nb_entries * sizeof(rsdt->u32Entry[0]);
+
+ rsdt = (ACPITBLRSDT*)RTMemAllocZ(size);
+ if (!rsdt)
+ return PDMDEV_SET_ERROR(pThis->pDevIns, VERR_NO_TMP_MEMORY, N_("Cannot allocate RSDT"));
+
+ acpiPrepareHeader(&rsdt->header, "RSDT", (uint32_t)size, 1);
+ for (unsigned int i = 0; i < nb_entries; ++i)
+ {
+ rsdt->u32Entry[i] = RT_H2LE_U32(addrs[i]);
+ Log(("Setup RSDT: [%d] = %x\n", i, rsdt->u32Entry[i]));
+ }
+ rsdt->header.u8Checksum = acpiChecksum(rsdt, size);
+ acpiPhyscpy(pThis, addr, rsdt, size);
+ RTMemFree(rsdt);
+ return VINF_SUCCESS;
+}
+
+/**
+ * Plant the Extended System Description Table.
+ */
+static int acpiSetupXSDT(ACPIState *pThis, RTGCPHYS32 addr, unsigned int nb_entries, uint32_t *addrs)
+{
+ ACPITBLXSDT *xsdt;
+ const size_t size = sizeof(ACPITBLHEADER) + nb_entries * sizeof(xsdt->u64Entry[0]);
+
+ xsdt = (ACPITBLXSDT*)RTMemAllocZ(size);
+ if (!xsdt)
+ return VERR_NO_TMP_MEMORY;
+
+ acpiPrepareHeader(&xsdt->header, "XSDT", (uint32_t)size, 1 /* according to ACPI 3.0 specs */);
+ for (unsigned int i = 0; i < nb_entries; ++i)
+ {
+ xsdt->u64Entry[i] = RT_H2LE_U64((uint64_t)addrs[i]);
+ Log(("Setup XSDT: [%d] = %RX64\n", i, xsdt->u64Entry[i]));
+ }
+ xsdt->header.u8Checksum = acpiChecksum(xsdt, size);
+ acpiPhyscpy(pThis, addr, xsdt, size);
+ RTMemFree(xsdt);
+ return VINF_SUCCESS;
+}
+
+/**
+ * Plant the Root System Description Pointer (RSDP).
+ */
+static void acpiSetupRSDP(ACPITBLRSDP *rsdp, RTGCPHYS32 GCPhysRsdt, RTGCPHYS GCPhysXsdt)
+{
+ memset(rsdp, 0, sizeof(*rsdp));
+
+ /* ACPI 1.0 part (RSDT */
+ memcpy(rsdp->au8Signature, "RSD PTR ", 8);
+ memcpy(rsdp->au8OemId, "VBOX ", 6);
+ rsdp->u8Revision = ACPI_REVISION;
+ rsdp->u32RSDT = RT_H2LE_U32(GCPhysRsdt);
+ rsdp->u8Checksum = acpiChecksum(rsdp, RT_OFFSETOF(ACPITBLRSDP, u32Length));
+
+ /* ACPI 2.0 part (XSDT) */
+ rsdp->u32Length = RT_H2LE_U32(sizeof(ACPITBLRSDP));
+ rsdp->u64XSDT = RT_H2LE_U64(GCPhysXsdt);
+ rsdp->u8ExtChecksum = acpiChecksum(rsdp, sizeof(ACPITBLRSDP));
+}
+
+/**
+ * Plant the Multiple APIC Description Table (MADT).
+ *
+ * @note APIC without IO-APIC hangs Windows Vista therefore we setup both.
+ *
+ * @todo All hardcoded, should set this up based on the actual VM config!!!!!
+ */
+static void acpiSetupMADT(ACPIState *pThis, RTGCPHYS32 addr)
+{
+ uint16_t cpus = pThis->cCpus;
+ AcpiTableMADT madt(cpus, NUMBER_OF_IRQ_SOURCE_OVERRIDES);
+
+ acpiPrepareHeader(madt.header_addr(), "APIC", madt.size(), 2);
+
+ *madt.u32LAPIC_addr() = RT_H2LE_U32(0xfee00000);
+ *madt.u32Flags_addr() = RT_H2LE_U32(PCAT_COMPAT);
+
+ /* LAPICs records */
+ ACPITBLLAPIC* lapic = madt.LApics_addr();
+ for (uint16_t i = 0; i < cpus; i++)
+ {
+ lapic->u8Type = 0;
+ lapic->u8Length = sizeof(ACPITBLLAPIC);
+ lapic->u8ProcId = i;
+ /** Must match numbering convention in MPTABLES */
+ lapic->u8ApicId = i;
+ lapic->u32Flags = VMCPUSET_IS_PRESENT(&pThis->CpuSetAttached, i) ? RT_H2LE_U32(LAPIC_ENABLED) : 0;
+ lapic++;
+ }
+
+ /* IO-APIC record */
+ ACPITBLIOAPIC* ioapic = madt.IOApic_addr();
+ ioapic->u8Type = 1;
+ ioapic->u8Length = sizeof(ACPITBLIOAPIC);
+ /** Must match MP tables ID */
+ ioapic->u8IOApicId = cpus;
+ ioapic->u8Reserved = 0;
+ ioapic->u32Address = RT_H2LE_U32(0xfec00000);
+ ioapic->u32GSIB = RT_H2LE_U32(0);
+
+ /* Interrupt Source Overrides */
+ /* Flags:
+ bits[3:2]:
+ 00 conforms to the bus
+ 01 edge-triggered
+ 10 reserved
+ 11 level-triggered
+ bits[1:0]
+ 00 conforms to the bus
+ 01 active-high
+ 10 reserved
+ 11 active-low */
+ /* If changing, also update PDMIsaSetIrq() and MPS */
+ ACPITBLISO* isos = madt.ISO_addr();
+ /* Timer interrupt rule IRQ0 to GSI2 */
+ isos[0].u8Type = 2;
+ isos[0].u8Length = sizeof(ACPITBLISO);
+ isos[0].u8Bus = 0; /* Must be 0 */
+ isos[0].u8Source = 0; /* IRQ0 */
+ isos[0].u32GSI = 2; /* connected to pin 2 */
+ isos[0].u16Flags = 0; /* conform to the bus */
+
+ /* ACPI interrupt rule - IRQ9 to GSI9 */
+ isos[1].u8Type = 2;
+ isos[1].u8Length = sizeof(ACPITBLISO);
+ isos[1].u8Bus = 0; /* Must be 0 */
+ isos[1].u8Source = 9; /* IRQ9 */
+ isos[1].u32GSI = 9; /* connected to pin 9 */
+ isos[1].u16Flags = 0xd; /* active high, level triggered */
+ Assert(NUMBER_OF_IRQ_SOURCE_OVERRIDES == 2);
+
+ madt.header_addr()->u8Checksum = acpiChecksum(madt.data(), madt.size());
+ acpiPhyscpy(pThis, addr, madt.data(), madt.size());
+}
+
+/**
+ * Plant the High Performance Event Timer (HPET) descriptor.
+ */
+static void acpiSetupHPET(ACPIState *pThis, RTGCPHYS32 addr)
+{
+ ACPITBLHPET hpet;
+
+ memset(&hpet, 0, sizeof(hpet));
+
+ acpiPrepareHeader(&hpet.aHeader, "HPET", sizeof(hpet), 1);
+ /* Keep base address consistent with appropriate DSDT entry (vbox.dsl) */
+ acpiWriteGenericAddr(&hpet.HpetAddr,
+ 0 /* Memory address space */,
+ 64 /* Register bit width */,
+ 0 /* Bit offset */,
+ 0, /* Register access size, is it correct? */
+ 0xfed00000 /* Address */);
+
+ hpet.u32Id = 0x8086a201; /* must match what HPET ID returns, is it correct ? */
+ hpet.u32Number = 0;
+ hpet.u32MinTick = 4096;
+ hpet.u8Attributes = 0;
+
+ hpet.aHeader.u8Checksum = acpiChecksum(&hpet, sizeof(hpet));
+
+ acpiPhyscpy(pThis, addr, (const uint8_t *)&hpet, sizeof(hpet));
+}
+
+
+/**
+ * Used by acpiPlantTables to plant a MMCONFIG PCI config space access (MCFG)
+ * descriptor.
+ *
+ * @param pThis The ACPI instance.
+ * @param GCPhysDst Where to plant it.
+ */
+static void acpiSetupMCFG(ACPIState *pThis, RTGCPHYS32 GCPhysDst)
+{
+ struct
+ {
+ ACPITBLMCFG hdr;
+ ACPITBLMCFGENTRY entry;
+ } tbl;
+ uint8_t u8StartBus = 0;
+ uint8_t u8EndBus = (pThis->u64PciConfigMMioLength >> 20) - 1;
+
+ RT_ZERO(tbl);
+
+ acpiPrepareHeader(&tbl.hdr.aHeader, "MCFG", sizeof(tbl), 1);
+ tbl.entry.u64BaseAddress = pThis->u64PciConfigMMioAddress;
+ tbl.entry.u8StartBus = u8StartBus;
+ tbl.entry.u8EndBus = u8EndBus;
+ // u16PciSegmentGroup must match _SEG in ACPI table
+
+ tbl.hdr.aHeader.u8Checksum = acpiChecksum(&tbl, sizeof(tbl));
+
+ acpiPhyscpy(pThis, GCPhysDst, (const uint8_t *)&tbl, sizeof(tbl));
+}
+
+/**
+ * Used by acpiPlantTables and acpiConstruct.
+ *
+ * @returns Guest memory address.
+ */
+static uint32_t find_rsdp_space(void)
+{
+ return 0xe0000;
+}
+
+/**
+ * Create the ACPI tables in guest memory.
+ */
+static int acpiPlantTables(ACPIState *pThis)
{
int rc;
RTGCPHYS32 GCPhysCur, GCPhysRsdt, GCPhysXsdt, GCPhysFadtAcpi1, GCPhysFadtAcpi2, GCPhysFacs, GCPhysDsdt;
- RTGCPHYS32 GCPhysHpet = 0, GCPhysApic = 0, GCPhysSsdt = 0, GCPhysMcfg = 0;
+ RTGCPHYS32 GCPhysHpet = 0;
+ RTGCPHYS32 GCPhysApic = 0;
+ RTGCPHYS32 GCPhysSsdt = 0;
+ RTGCPHYS32 GCPhysMcfg = 0;
uint32_t addend = 0;
RTGCPHYS32 aGCPhysRsdt[8];
RTGCPHYS32 aGCPhysXsdt[8];
- uint32_t cAddr, iMadt = 0, iHpet = 0, iSsdt = 0, iMcfg = 0;
+ uint32_t cAddr;
+ uint32_t iMadt = 0;
+ uint32_t iHpet = 0;
+ uint32_t iSsdt = 0;
+ uint32_t iMcfg = 0;
size_t cbRsdt = sizeof(ACPITBLHEADER);
size_t cbXsdt = sizeof(ACPITBLHEADER);
cAddr = 1; /* FADT */
- if (s->u8UseIOApic)
+ if (pThis->u8UseIOApic)
iMadt = cAddr++; /* MADT */
- if (s->fUseHpet)
+ if (pThis->fUseHpet)
iHpet = cAddr++; /* HPET */
- if (s->fUseMcfg)
+ if (pThis->fUseMcfg)
iMcfg = cAddr++; /* MCFG */
iSsdt = cAddr++; /* SSDT */
@@ -2253,30 +2457,30 @@ static int acpiPlantTables(ACPIState *s)
cbRsdt += cAddr*sizeof(uint32_t); /* each entry: 32 bits phys. address. */
cbXsdt += cAddr*sizeof(uint64_t); /* each entry: 64 bits phys. address. */
- rc = CFGMR3QueryU64(s->pDevIns->pCfg, "RamSize", &s->u64RamSize);
+ rc = CFGMR3QueryU64(pThis->pDevIns->pCfg, "RamSize", &pThis->u64RamSize);
if (RT_FAILURE(rc))
- return PDMDEV_SET_ERROR(s->pDevIns, rc,
+ return PDMDEV_SET_ERROR(pThis->pDevIns, rc,
N_("Configuration error: Querying \"RamSize\" as integer failed"));
uint32_t cbRamHole;
- rc = CFGMR3QueryU32Def(s->pDevIns->pCfg, "RamHoleSize", &cbRamHole, MM_RAM_HOLE_SIZE_DEFAULT);
+ rc = CFGMR3QueryU32Def(pThis->pDevIns->pCfg, "RamHoleSize", &cbRamHole, MM_RAM_HOLE_SIZE_DEFAULT);
if (RT_FAILURE(rc))
- return PDMDEV_SET_ERROR(s->pDevIns, rc,
+ return PDMDEV_SET_ERROR(pThis->pDevIns, rc,
N_("Configuration error: Querying \"RamHoleSize\" as integer failed"));
/*
* Calculate the sizes for the high and low regions.
*/
const uint64_t offRamHole = _4G - cbRamHole;
- s->cbRamHigh = offRamHole < s->u64RamSize ? s->u64RamSize - offRamHole : 0;
- uint64_t cbRamLow = offRamHole < s->u64RamSize ? offRamHole : s->u64RamSize;
+ pThis->cbRamHigh = offRamHole < pThis->u64RamSize ? pThis->u64RamSize - offRamHole : 0;
+ uint64_t cbRamLow = offRamHole < pThis->u64RamSize ? offRamHole : pThis->u64RamSize;
if (cbRamLow > UINT32_C(0xffe00000)) /* See MEM3. */
{
/* Note: This is also enforced by DevPcBios.cpp. */
LogRel(("DevACPI: Clipping cbRamLow=%#RX64 down to 0xffe00000.\n", cbRamLow));
cbRamLow = UINT32_C(0xffe00000);
}
- s->cbRamLow = (uint32_t)cbRamLow;
+ pThis->cbRamLow = (uint32_t)cbRamLow;
GCPhysCur = 0;
GCPhysRsdt = GCPhysCur;
@@ -2294,26 +2498,26 @@ static int acpiPlantTables(ACPIState *s)
GCPhysFacs = GCPhysCur;
GCPhysCur = RT_ALIGN_32(GCPhysCur + sizeof(ACPITBLFACS), 16);
- if (s->u8UseIOApic)
+ if (pThis->u8UseIOApic)
{
GCPhysApic = GCPhysCur;
- GCPhysCur = RT_ALIGN_32(GCPhysCur + AcpiTableMADT::sizeFor(s, NUMBER_OF_IRQ_SOURCE_OVERRIDES), 16);
+ GCPhysCur = RT_ALIGN_32(GCPhysCur + AcpiTableMADT::sizeFor(pThis, NUMBER_OF_IRQ_SOURCE_OVERRIDES), 16);
}
- if (s->fUseHpet)
+ if (pThis->fUseHpet)
{
GCPhysHpet = GCPhysCur;
GCPhysCur = RT_ALIGN_32(GCPhysCur + sizeof(ACPITBLHPET), 16);
}
- if (s->fUseMcfg)
+ if (pThis->fUseMcfg)
{
GCPhysMcfg = GCPhysCur;
/* Assume one entry */
GCPhysCur = RT_ALIGN_32(GCPhysCur + sizeof(ACPITBLMCFG) + sizeof(ACPITBLMCFGENTRY), 16);
}
- void* pSsdtCode = NULL;
+ void *pvSsdtCode = NULL;
size_t cbSsdtSize = 0;
- rc = acpiPrepareSsdt(s->pDevIns, &pSsdtCode, &cbSsdtSize);
+ rc = acpiPrepareSsdt(pThis->pDevIns, &pvSsdtCode, &cbSsdtSize);
if (RT_FAILURE(rc))
return rc;
@@ -2322,114 +2526,92 @@ static int acpiPlantTables(ACPIState *s)
GCPhysDsdt = GCPhysCur;
- void* pDsdtCode = NULL;
+ void *pvDsdtCode = NULL;
size_t cbDsdtSize = 0;
- rc = acpiPrepareDsdt(s->pDevIns, &pDsdtCode, &cbDsdtSize);
+ rc = acpiPrepareDsdt(pThis->pDevIns, &pvDsdtCode, &cbDsdtSize);
if (RT_FAILURE(rc))
return rc;
GCPhysCur = RT_ALIGN_32(GCPhysCur + cbDsdtSize, 16);
if (GCPhysCur > 0x10000)
- return PDMDEV_SET_ERROR(s->pDevIns, VERR_TOO_MUCH_DATA,
+ return PDMDEV_SET_ERROR(pThis->pDevIns, VERR_TOO_MUCH_DATA,
N_("Error: ACPI tables bigger than 64KB"));
Log(("RSDP 0x%08X\n", find_rsdp_space()));
- addend = s->cbRamLow - 0x10000;
+ addend = pThis->cbRamLow - 0x10000;
Log(("RSDT 0x%08X XSDT 0x%08X\n", GCPhysRsdt + addend, GCPhysXsdt + addend));
Log(("FACS 0x%08X FADT (1.0) 0x%08X, FADT (2+) 0x%08X\n", GCPhysFacs + addend, GCPhysFadtAcpi1 + addend, GCPhysFadtAcpi2 + addend));
Log(("DSDT 0x%08X", GCPhysDsdt + addend));
- if (s->u8UseIOApic)
+ if (pThis->u8UseIOApic)
Log((" MADT 0x%08X", GCPhysApic + addend));
- if (s->fUseHpet)
+ if (pThis->fUseHpet)
Log((" HPET 0x%08X", GCPhysHpet + addend));
- if (s->fUseMcfg)
+ if (pThis->fUseMcfg)
Log((" MCFG 0x%08X", GCPhysMcfg + addend));
Log((" SSDT 0x%08X", GCPhysSsdt + addend));
Log(("\n"));
- acpiSetupRSDP((ACPITBLRSDP*)s->au8RSDPPage, GCPhysRsdt + addend, GCPhysXsdt + addend);
- acpiSetupDSDT(s, GCPhysDsdt + addend, pDsdtCode, cbDsdtSize);
- acpiCleanupDsdt(s->pDevIns, pDsdtCode);
- acpiSetupFACS(s, GCPhysFacs + addend);
- acpiSetupFADT(s, GCPhysFadtAcpi1 + addend, GCPhysFadtAcpi2 + addend, GCPhysFacs + addend, GCPhysDsdt + addend);
+ acpiSetupRSDP((ACPITBLRSDP *)pThis->au8RSDPPage, GCPhysRsdt + addend, GCPhysXsdt + addend);
+ acpiSetupDSDT(pThis, GCPhysDsdt + addend, pvDsdtCode, cbDsdtSize);
+ acpiCleanupDsdt(pThis->pDevIns, pvDsdtCode);
+ acpiSetupFACS(pThis, GCPhysFacs + addend);
+ acpiSetupFADT(pThis, GCPhysFadtAcpi1 + addend, GCPhysFadtAcpi2 + addend, GCPhysFacs + addend, GCPhysDsdt + addend);
aGCPhysRsdt[0] = GCPhysFadtAcpi1 + addend;
aGCPhysXsdt[0] = GCPhysFadtAcpi2 + addend;
- if (s->u8UseIOApic)
+ if (pThis->u8UseIOApic)
{
- acpiSetupMADT(s, GCPhysApic + addend);
+ acpiSetupMADT(pThis, GCPhysApic + addend);
aGCPhysRsdt[iMadt] = GCPhysApic + addend;
aGCPhysXsdt[iMadt] = GCPhysApic + addend;
}
- if (s->fUseHpet)
+ if (pThis->fUseHpet)
{
- acpiSetupHPET(s, GCPhysHpet + addend);
+ acpiSetupHPET(pThis, GCPhysHpet + addend);
aGCPhysRsdt[iHpet] = GCPhysHpet + addend;
aGCPhysXsdt[iHpet] = GCPhysHpet + addend;
}
- if (s->fUseMcfg)
+ if (pThis->fUseMcfg)
{
- acpiSetupMCFG(s, GCPhysMcfg + addend);
+ acpiSetupMCFG(pThis, GCPhysMcfg + addend);
aGCPhysRsdt[iMcfg] = GCPhysMcfg + addend;
aGCPhysXsdt[iMcfg] = GCPhysMcfg + addend;
}
- acpiSetupSSDT(s, GCPhysSsdt + addend, pSsdtCode, cbSsdtSize);
- acpiCleanupSsdt(s->pDevIns, pSsdtCode);
+ acpiSetupSSDT(pThis, GCPhysSsdt + addend, pvSsdtCode, cbSsdtSize);
+ acpiCleanupSsdt(pThis->pDevIns, pvSsdtCode);
aGCPhysRsdt[iSsdt] = GCPhysSsdt + addend;
aGCPhysXsdt[iSsdt] = GCPhysSsdt + addend;
- rc = acpiSetupRSDT(s, GCPhysRsdt + addend, cAddr, aGCPhysRsdt);
+ rc = acpiSetupRSDT(pThis, GCPhysRsdt + addend, cAddr, aGCPhysRsdt);
if (RT_FAILURE(rc))
return rc;
- return acpiSetupXSDT(s, GCPhysXsdt + addend, cAddr, aGCPhysXsdt);
+ return acpiSetupXSDT(pThis, GCPhysXsdt + addend, cAddr, aGCPhysXsdt);
}
-static int acpiUpdatePmHandlers(ACPIState *pThis, RTIOPORT uNewBase)
-{
- Log(("acpi: rebasing PM 0x%x -> 0x%x\n", pThis->uPmIoPortBase, uNewBase));
- if (uNewBase != pThis->uPmIoPortBase)
- {
- int rc;
-
- rc = acpiUnregisterPmHandlers(pThis);
- if (RT_FAILURE(rc))
- return rc;
-
- pThis->uPmIoPortBase = uNewBase;
-
- rc = acpiRegisterPmHandlers(pThis);
- if (RT_FAILURE(rc))
- return rc;
-
- /* We have to update FADT table acccording to the new base */
- rc = acpiPlantTables(pThis);
- AssertRC(rc);
- if (RT_FAILURE(rc))
- return rc;
- }
-
- return VINF_SUCCESS;
-}
-
-static uint32_t acpiPciConfigRead(PPCIDEVICE pPciDev, uint32_t Address, unsigned cb)
+/**
+ * @callback_method_impl{FNPCICONFIGREAD}
+ */
+static DECLCALLBACK(uint32_t) acpiPciConfigRead(PPCIDEVICE pPciDev, uint32_t Address, unsigned cb)
{
PPDMDEVINS pDevIns = pPciDev->pDevIns;
- ACPIState* pThis = PDMINS_2_DATA(pDevIns, ACPIState *);
+ ACPIState *pThis = PDMINS_2_DATA(pDevIns, ACPIState *);
Log2(("acpi: PCI config read: 0x%x (%d)\n", Address, cb));
-
return pThis->pfnAcpiPciConfigRead(pPciDev, Address, cb);
}
-static void acpiPciConfigWrite(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u32Value, unsigned cb)
+/**
+ * @callback_method_impl{FNPCICONFIGWRITE}
+ */
+static DECLCALLBACK(void) acpiPciConfigWrite(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u32Value, unsigned cb)
{
PPDMDEVINS pDevIns = pPciDev->pDevIns;
ACPIState *pThis = PDMINS_2_DATA(pDevIns, ACPIState *);
Log2(("acpi: PCI config write: 0x%x -> 0x%x (%d)\n", u32Value, Address, cb));
-
+ DEVACPI_LOCK_R3(pThis);
if (Address == VBOX_PCI_INTERRUPT_LINE)
{
@@ -2445,15 +2627,15 @@ static void acpiPciConfigWrite(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u3
/* Check Power Management IO Space Enable (PMIOSE) bit */
if (pPciDev->config[0x80] & 0x1)
{
- int rc;
-
- RTIOPORT uNewBase = RTIOPORT(PCIDevGetDWord(pPciDev, 0x40));
- uNewBase &= 0xffc0;
+ RTIOPORT NewIoPortBase = (RTIOPORT)PCIDevGetDWord(pPciDev, 0x40);
+ NewIoPortBase &= 0xffc0;
- rc = acpiUpdatePmHandlers(pThis, uNewBase);
+ int rc = acpiUpdatePmHandlers(pThis, NewIoPortBase);
AssertRC(rc);
}
}
+
+ DEVACPI_UNLOCK(pThis);
}
/**
@@ -2468,8 +2650,7 @@ static void acpiPciConfigWrite(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u3
*/
static DECLCALLBACK(int) acpiAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
{
- ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *);
-
+ ACPIState *pThis = PDMINS_2_DATA(pDevIns, ACPIState *);
LogFlow(("acpiAttach: pDevIns=%p iLUN=%u fFlags=%#x\n", pDevIns, iLUN, fFlags));
AssertMsgReturn(!(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG),
@@ -2478,27 +2659,30 @@ static DECLCALLBACK(int) acpiAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t
AssertReturn(iLUN < VMM_MAX_CPU_COUNT, VERR_PDM_NO_SUCH_LUN);
/* Check if it was already attached */
- if (VMCPUSET_IS_PRESENT(&s->CpuSetAttached, iLUN))
- return VINF_SUCCESS;
-
- PPDMIBASE IBaseTmp;
- int rc = PDMDevHlpDriverAttach(pDevIns, iLUN, &s->IBase, &IBaseTmp, "ACPI CPU");
-
- if (RT_SUCCESS(rc))
+ int rc = VINF_SUCCESS;
+ DEVACPI_LOCK_R3(pThis);
+ if (!VMCPUSET_IS_PRESENT(&pThis->CpuSetAttached, iLUN))
{
- /* Enable the CPU */
- VMCPUSET_ADD(&s->CpuSetAttached, iLUN);
-
- /*
- * Lock the CPU because we don't know if the guest will use it or not.
- * Prevents ejection while the CPU is still used
- */
- VMCPUSET_ADD(&s->CpuSetLocked, iLUN);
- s->u32CpuEventType = CPU_EVENT_TYPE_ADD;
- s->u32CpuEvent = iLUN;
- /* Notify the guest */
- update_gpe0(s, s->gpe0_sts | 0x2, s->gpe0_en);
+ PPDMIBASE IBaseTmp;
+ rc = PDMDevHlpDriverAttach(pDevIns, iLUN, &pThis->IBase, &IBaseTmp, "ACPI CPU");
+ if (RT_SUCCESS(rc))
+ {
+ /* Enable the CPU */
+ VMCPUSET_ADD(&pThis->CpuSetAttached, iLUN);
+
+ /*
+ * Lock the CPU because we don't know if the guest will use it or not.
+ * Prevents ejection while the CPU is still used
+ */
+ VMCPUSET_ADD(&pThis->CpuSetLocked, iLUN);
+ pThis->u32CpuEventType = CPU_EVENT_TYPE_ADD;
+ pThis->u32CpuEvent = iLUN;
+
+ /* Notify the guest */
+ update_gpe0(pThis, pThis->gpe0_sts | 0x2, pThis->gpe0_en);
+ }
}
+ DEVACPI_UNLOCK(pThis);
return rc;
}
@@ -2511,7 +2695,7 @@ static DECLCALLBACK(int) acpiAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t
*/
static DECLCALLBACK(void) acpiDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
{
- ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *);
+ ACPIState *pThis = PDMINS_2_DATA(pDevIns, ACPIState *);
LogFlow(("acpiDetach: pDevIns=%p iLUN=%u fFlags=%#x\n", pDevIns, iLUN, fFlags));
@@ -2519,17 +2703,23 @@ static DECLCALLBACK(void) acpiDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t
("Hot-plug flag is not set\n"));
/* Check if it was already detached */
- if (VMCPUSET_IS_PRESENT(&s->CpuSetAttached, iLUN))
+ DEVACPI_LOCK_R3(pThis);
+ if (VMCPUSET_IS_PRESENT(&pThis->CpuSetAttached, iLUN))
{
- AssertMsgReturnVoid(!(VMCPUSET_IS_PRESENT(&s->CpuSetLocked, iLUN)), ("CPU is still locked by the guest\n"));
-
- /* Disable the CPU */
- VMCPUSET_DEL(&s->CpuSetAttached, iLUN);
- s->u32CpuEventType = CPU_EVENT_TYPE_REMOVE;
- s->u32CpuEvent = iLUN;
- /* Notify the guest */
- update_gpe0(s, s->gpe0_sts | 0x2, s->gpe0_en);
+ if (!VMCPUSET_IS_PRESENT(&pThis->CpuSetLocked, iLUN))
+ {
+ /* Disable the CPU */
+ VMCPUSET_DEL(&pThis->CpuSetAttached, iLUN);
+ pThis->u32CpuEventType = CPU_EVENT_TYPE_REMOVE;
+ pThis->u32CpuEvent = iLUN;
+
+ /* Notify the guest */
+ update_gpe0(pThis, pThis->gpe0_sts | 0x2, pThis->gpe0_en);
+ }
+ else
+ AssertMsgFailed(("CPU is still locked by the guest\n"));
}
+ DEVACPI_UNLOCK(pThis);
}
/**
@@ -2551,23 +2741,25 @@ static DECLCALLBACK(void) acpiResume(PPDMDEVINS pDevIns)
*/
static DECLCALLBACK(void) acpiReset(PPDMDEVINS pDevIns)
{
- ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *);
+ ACPIState *pThis = PDMINS_2_DATA(pDevIns, ACPIState *);
- s->pm1a_en = 0;
- s->pm1a_sts = 0;
- s->pm1a_ctl = 0;
- s->u64PmTimerInitial = TMTimerGet(s->CTX_SUFF(ts));
- acpiPMTimerReset(s);
- s->uBatteryIndex = 0;
- s->uSystemInfoIndex = 0;
- s->gpe0_en = 0;
- s->gpe0_sts = 0;
- s->uSleepState = 0;
+ TMTimerLock(pThis->pPmTimerR3, VERR_IGNORED);
+ pThis->pm1a_en = 0;
+ pThis->pm1a_sts = 0;
+ pThis->pm1a_ctl = 0;
+ pThis->u64PmTimerInitial = TMTimerGet(pThis->pPmTimerR3);
+ acpiPmTimerReset(pThis, pThis->u64PmTimerInitial);
+ pThis->uBatteryIndex = 0;
+ pThis->uSystemInfoIndex = 0;
+ pThis->gpe0_en = 0;
+ pThis->gpe0_sts = 0;
+ pThis->uSleepState = 0;
+ TMTimerUnlock(pThis->pPmTimerR3);
/** @todo Should we really reset PM base? */
- acpiUpdatePmHandlers(s, PM_PORT_BASE);
+ acpiUpdatePmHandlers(pThis, PM_PORT_BASE);
- acpiPlantTables(s);
+ acpiPlantTables(pThis);
}
/**
@@ -2575,8 +2767,8 @@ static DECLCALLBACK(void) acpiReset(PPDMDEVINS pDevIns)
*/
static DECLCALLBACK(void) acpiRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
{
- ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *);
- s->tsRC = TMTimerRCPtr(s->CTX_SUFF(ts));
+ ACPIState *pThis = PDMINS_2_DATA(pDevIns, ACPIState *);
+ pThis->pPmTimerRC = TMTimerRCPtr(pThis->pPmTimerR3);
}
/**
@@ -2584,11 +2776,44 @@ static DECLCALLBACK(void) acpiRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
*/
static DECLCALLBACK(int) acpiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
{
- ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *);
- PCIDevice *dev = &s->dev;
+ ACPIState *pThis = PDMINS_2_DATA(pDevIns, ACPIState *);
PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
- /* Validate and read the configuration. */
+ /*
+ * Init data and set defaults.
+ */
+ /** @todo move more of the code up! */
+
+ pThis->pDevIns = pDevIns;
+ VMCPUSET_EMPTY(&pThis->CpuSetAttached);
+ VMCPUSET_EMPTY(&pThis->CpuSetLocked);
+ pThis->idCpuLockCheck = UINT32_C(0xffffffff);
+ pThis->u32CpuEventType = 0;
+ pThis->u32CpuEvent = UINT32_C(0xffffffff);
+
+ /* The first CPU can't be attached/detached */
+ VMCPUSET_ADD(&pThis->CpuSetAttached, 0);
+ VMCPUSET_ADD(&pThis->CpuSetLocked, 0);
+
+ /* IBase */
+ pThis->IBase.pfnQueryInterface = acpiQueryInterface;
+ /* IACPIPort */
+ pThis->IACPIPort.pfnSleepButtonPress = acpiPort_SleepButtonPress;
+ pThis->IACPIPort.pfnPowerButtonPress = acpiPort_PowerButtonPress;
+ pThis->IACPIPort.pfnGetPowerButtonHandled = acpiPort_GetPowerButtonHandled;
+ pThis->IACPIPort.pfnGetGuestEnteredACPIMode = acpiPort_GetGuestEnteredACPIMode;
+ pThis->IACPIPort.pfnGetCpuStatus = acpiPort_GetCpuStatus;
+
+ /* Set the default critical section to NOP (related to the PM timer). */
+ int rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
+ AssertRCReturn(rc, rc);
+
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "acpi%u", iInstance);
+ AssertRCReturn(rc, rc);
+
+ /*
+ * Validate and read the configuration.
+ */
if (!CFGMR3AreValuesValid(pCfg,
"RamSize\0"
"RamHoleSize\0"
@@ -2613,159 +2838,161 @@ static DECLCALLBACK(int) acpiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
"PowerS4Enabled\0"
"CpuHotPlug\0"
"AmlFilePath\0"
+ "Serial0IoPortBase\0"
+ "Serial1IoPortBase\0"
+ "Serial0Irq\0"
+ "Serial1Irq\0"
))
return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
N_("Configuration error: Invalid config key for ACPI device"));
- s->pDevIns = pDevIns;
-
/* query whether we are supposed to present an IOAPIC */
- int rc = CFGMR3QueryU8Def(pCfg, "IOAPIC", &s->u8UseIOApic, 1);
+ rc = CFGMR3QueryU8Def(pCfg, "IOAPIC", &pThis->u8UseIOApic, 1);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"IOAPIC\""));
- rc = CFGMR3QueryU16Def(pCfg, "NumCPUs", &s->cCpus, 1);
+ rc = CFGMR3QueryU16Def(pCfg, "NumCPUs", &pThis->cCpus, 1);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Querying \"NumCPUs\" as integer failed"));
/* query whether we are supposed to present an FDC controller */
- rc = CFGMR3QueryBoolDef(pCfg, "FdcEnabled", &s->fUseFdc, true);
+ rc = CFGMR3QueryBoolDef(pCfg, "FdcEnabled", &pThis->fUseFdc, true);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"FdcEnabled\""));
/* query whether we are supposed to present HPET */
- rc = CFGMR3QueryBoolDef(pCfg, "HpetEnabled", &s->fUseHpet, false);
+ rc = CFGMR3QueryBoolDef(pCfg, "HpetEnabled", &pThis->fUseHpet, false);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"HpetEnabled\""));
/* query MCFG configuration */
- rc = CFGMR3QueryU64Def(pCfg, "McfgBase", &s->u64PciConfigMMioAddress, 0);
+ rc = CFGMR3QueryU64Def(pCfg, "McfgBase", &pThis->u64PciConfigMMioAddress, 0);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"McfgBase\""));
- rc = CFGMR3QueryU64Def(pCfg, "McfgLength", &s->u64PciConfigMMioLength, 0);
+ rc = CFGMR3QueryU64Def(pCfg, "McfgLength", &pThis->u64PciConfigMMioLength, 0);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"McfgLength\""));
- s->fUseMcfg = (s->u64PciConfigMMioAddress != 0) && (s->u64PciConfigMMioLength != 0);
+ pThis->fUseMcfg = (pThis->u64PciConfigMMioAddress != 0) && (pThis->u64PciConfigMMioLength != 0);
/* query whether we are supposed to present SMC */
- rc = CFGMR3QueryBoolDef(pCfg, "SmcEnabled", &s->fUseSmc, false);
+ rc = CFGMR3QueryBoolDef(pCfg, "SmcEnabled", &pThis->fUseSmc, false);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"SmcEnabled\""));
/* query whether we are supposed to present RTC object */
- rc = CFGMR3QueryBoolDef(pCfg, "ShowRtc", &s->fShowRtc, false);
+ rc = CFGMR3QueryBoolDef(pCfg, "ShowRtc", &pThis->fShowRtc, false);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"ShowRtc\""));
/* query whether we are supposed to present CPU objects */
- rc = CFGMR3QueryBoolDef(pCfg, "ShowCpu", &s->fShowCpu, false);
+ rc = CFGMR3QueryBoolDef(pCfg, "ShowCpu", &pThis->fShowCpu, false);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"ShowCpu\""));
/* query primary NIC PCI address */
- rc = CFGMR3QueryU32Def(pCfg, "NicPciAddress", &s->u32NicPciAddress, 0);
+ rc = CFGMR3QueryU32Def(pCfg, "NicPciAddress", &pThis->u32NicPciAddress, 0);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"NicPciAddress\""));
/* query primary NIC PCI address */
- rc = CFGMR3QueryU32Def(pCfg, "AudioPciAddress", &s->u32AudioPciAddress, 0);
+ rc = CFGMR3QueryU32Def(pCfg, "AudioPciAddress", &pThis->u32AudioPciAddress, 0);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"AudioPciAddress\""));
/* query IO controller (southbridge) PCI address */
- rc = CFGMR3QueryU32Def(pCfg, "IocPciAddress", &s->u32IocPciAddress, 0);
+ rc = CFGMR3QueryU32Def(pCfg, "IocPciAddress", &pThis->u32IocPciAddress, 0);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"IocPciAddress\""));
/* query host bus controller PCI address */
- rc = CFGMR3QueryU32Def(pCfg, "HostBusPciAddress", &s->u32HbcPciAddress, 0);
+ rc = CFGMR3QueryU32Def(pCfg, "HostBusPciAddress", &pThis->u32HbcPciAddress, 0);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"HostBusPciAddress\""));
/* query whether S1 power state should be exposed */
- rc = CFGMR3QueryBoolDef(pCfg, "PowerS1Enabled", &s->fS1Enabled, false);
+ rc = CFGMR3QueryBoolDef(pCfg, "PowerS1Enabled", &pThis->fS1Enabled, false);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"PowerS1Enabled\""));
/* query whether S4 power state should be exposed */
- rc = CFGMR3QueryBoolDef(pCfg, "PowerS4Enabled", &s->fS4Enabled, false);
+ rc = CFGMR3QueryBoolDef(pCfg, "PowerS4Enabled", &pThis->fS4Enabled, false);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"PowerS4Enabled\""));
/* query whether S1 power state should save the VM state */
- rc = CFGMR3QueryBoolDef(pCfg, "EnableSuspendToDisk", &s->fSuspendToSavedState, false);
+ rc = CFGMR3QueryBoolDef(pCfg, "EnableSuspendToDisk", &pThis->fSuspendToSavedState, false);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"EnableSuspendToDisk\""));
/* query whether we are allow CPU hot plugging */
- rc = CFGMR3QueryBoolDef(pCfg, "CpuHotPlug", &s->fCpuHotPlug, false);
+ rc = CFGMR3QueryBoolDef(pCfg, "CpuHotPlug", &pThis->fCpuHotPlug, false);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"CpuHotPlug\""));
- rc = CFGMR3QueryBool(pCfg, "GCEnabled", &s->fGCEnabled);
+ rc = CFGMR3QueryBool(pCfg, "GCEnabled", &pThis->fGCEnabled);
if (rc == VERR_CFGM_VALUE_NOT_FOUND)
- s->fGCEnabled = true;
+ pThis->fGCEnabled = true;
else if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Failed to read \"GCEnabled\""));
- rc = CFGMR3QueryBool(pCfg, "R0Enabled", &s->fR0Enabled);
+ rc = CFGMR3QueryBool(pCfg, "R0Enabled", &pThis->fR0Enabled);
if (rc == VERR_CFGM_VALUE_NOT_FOUND)
- s->fR0Enabled = true;
+ pThis->fR0Enabled = true;
else if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("configuration error: failed to read R0Enabled as boolean"));
- /*
- * Interfaces
- */
- /* IBase */
- s->IBase.pfnQueryInterface = acpiQueryInterface;
- /* IACPIPort */
- s->IACPIPort.pfnSleepButtonPress = acpiSleepButtonPress;
- s->IACPIPort.pfnPowerButtonPress = acpiPowerButtonPress;
- s->IACPIPort.pfnGetPowerButtonHandled = acpiGetPowerButtonHandled;
- s->IACPIPort.pfnGetGuestEnteredACPIMode = acpiGetGuestEnteredACPIMode;
- s->IACPIPort.pfnGetCpuStatus = acpiGetCpuStatus;
-
- VMCPUSET_EMPTY(&s->CpuSetAttached);
- VMCPUSET_EMPTY(&s->CpuSetLocked);
- s->idCpuLockCheck = UINT32_C(0xffffffff);
- s->u32CpuEventType = 0;
- s->u32CpuEvent = UINT32_C(0xffffffff);
+ /* query serial info */
+ rc = CFGMR3QueryU8Def(pCfg, "Serial0Irq", &pThis->uSerial0Irq, 4);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("Configuration error: Failed to read \"Serial0Irq\""));
- /* The first CPU can't be attached/detached */
- VMCPUSET_ADD(&s->CpuSetAttached, 0);
- VMCPUSET_ADD(&s->CpuSetLocked, 0);
+ rc = CFGMR3QueryU16Def(pCfg, "Serial0IoPortBase", &pThis->uSerial0IoPortBase, 0x3f8);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("Configuration error: Failed to read \"Serial0IoPortBase\""));
+
+ /* Serial 1 is enabled, get config data */
+ rc = CFGMR3QueryU8Def(pCfg, "Serial1Irq", &pThis->uSerial1Irq, 3);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("Configuration error: Failed to read \"Serial1Irq\""));
+
+ rc = CFGMR3QueryU16Def(pCfg, "Serial1IoPortBase", &pThis->uSerial1IoPortBase, 0x2f8);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("Configuration error: Failed to read \"Serial1IoPortBase\""));
/* Try to attach the other CPUs */
- for (unsigned i = 1; i < s->cCpus; i++)
+ for (unsigned i = 1; i < pThis->cCpus; i++)
{
- if (s->fCpuHotPlug)
+ if (pThis->fCpuHotPlug)
{
PPDMIBASE IBaseTmp;
- rc = PDMDevHlpDriverAttach(pDevIns, i, &s->IBase, &IBaseTmp, "ACPI CPU");
+ rc = PDMDevHlpDriverAttach(pDevIns, i, &pThis->IBase, &IBaseTmp, "ACPI CPU");
if (RT_SUCCESS(rc))
{
- VMCPUSET_ADD(&s->CpuSetAttached, i);
- VMCPUSET_ADD(&s->CpuSetLocked, i);
+ VMCPUSET_ADD(&pThis->CpuSetAttached, i);
+ VMCPUSET_ADD(&pThis->CpuSetLocked, i);
Log(("acpi: Attached CPU %u\n", i));
}
else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
@@ -2776,44 +3003,49 @@ static DECLCALLBACK(int) acpiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
else
{
/* CPU is always attached if hot-plug is not enabled. */
- VMCPUSET_ADD(&s->CpuSetAttached, i);
- VMCPUSET_ADD(&s->CpuSetLocked, i);
+ VMCPUSET_ADD(&pThis->CpuSetAttached, i);
+ VMCPUSET_ADD(&pThis->CpuSetLocked, i);
}
}
/* Set default port base */
- s->uPmIoPortBase = PM_PORT_BASE;
+ pThis->uPmIoPortBase = PM_PORT_BASE;
/*
* FDC and SMC try to use the same non-shareable interrupt (6),
* enable only one device.
*/
- if (s->fUseSmc)
- s->fUseFdc = false;
+ if (pThis->fUseSmc)
+ pThis->fUseFdc = false;
- /* */
+ /*
+ * Plant ACPI tables.
+ */
RTGCPHYS32 GCPhysRsdp = find_rsdp_space();
if (!GCPhysRsdp)
return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY,
N_("Can not find space for RSDP. ACPI is disabled"));
- rc = acpiPlantTables(s);
+ rc = acpiPlantTables(pThis);
if (RT_FAILURE(rc))
return rc;
- rc = PDMDevHlpROMRegister(pDevIns, GCPhysRsdp, 0x1000, s->au8RSDPPage, 0x1000,
+ rc = PDMDevHlpROMRegister(pDevIns, GCPhysRsdp, 0x1000, pThis->au8RSDPPage, 0x1000,
PGMPHYS_ROM_FLAGS_PERMANENT_BINARY, "ACPI RSDP");
if (RT_FAILURE(rc))
return rc;
- rc = acpiRegisterPmHandlers(s);
+ /*
+ * Register I/O ports.
+ */
+ rc = acpiRegisterPmHandlers(pThis);
if (RT_FAILURE(rc))
return rc;
#define R(addr, cnt, writer, reader, description) \
do { \
- rc = PDMDevHlpIOPortRegister(pDevIns, addr, cnt, s, writer, reader, \
+ rc = PDMDevHlpIOPortRegister(pDevIns, addr, cnt, pThis, writer, reader, \
NULL, NULL, description); \
if (RT_FAILURE(rc)) \
return rc; \
@@ -2830,40 +3062,47 @@ static DECLCALLBACK(int) acpiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
R(ACPI_RESET_BLK, 1, acpiResetWrite, NULL, "ACPI Reset");
#undef R
- rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, acpiTimer, dev,
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "ACPI Timer", &s->tsR3);
- if (RT_FAILURE(rc))
- {
- AssertMsgFailed(("pfnTMTimerCreate -> %Rrc\n", rc));
- return rc;
- }
-
- s->tsR0 = TMTimerR0Ptr(s->tsR3);
- s->tsRC = TMTimerRCPtr(s->tsR3);
- s->u64PmTimerInitial = TMTimerGet(s->tsR3);
- acpiPMTimerReset(s);
+ /*
+ * Create the PM timer.
+ */
+ PTMTIMER pTimer;
+ rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, acpiPmTimer, &pThis->dev,
+ TMTIMER_FLAGS_NO_CRIT_SECT, "ACPI PM Timer", &pTimer);
+ AssertRCReturn(rc, rc);
+ pThis->pPmTimerR3 = pTimer;
+ pThis->pPmTimerR0 = TMTimerR0Ptr(pTimer);
+ pThis->pPmTimerRC = TMTimerRCPtr(pTimer);
+
+ rc = TMTimerLock(pTimer, VERR_IGNORED);
+ AssertRCReturn(rc, rc);
+ pThis->u64PmTimerInitial = TMTimerGet(pTimer);
+ acpiPmTimerReset(pThis, pThis->u64PmTimerInitial);
+ TMTimerUnlock(pTimer);
- PCIDevSetVendorId(dev, 0x8086); /* Intel */
- PCIDevSetDeviceId(dev, 0x7113); /* 82371AB */
+ /*
+ * Set up the PCI device.
+ */
+ PCIDevSetVendorId(&pThis->dev, 0x8086); /* Intel */
+ PCIDevSetDeviceId(&pThis->dev, 0x7113); /* 82371AB */
/* See p. 50 of PIIX4 manual */
- PCIDevSetCommand(dev, 0x01);
- PCIDevSetStatus(dev, 0x0280);
+ PCIDevSetCommand(&pThis->dev, 0x01);
+ PCIDevSetStatus(&pThis->dev, 0x0280);
- PCIDevSetRevisionId(dev, 0x08);
+ PCIDevSetRevisionId(&pThis->dev, 0x08);
- PCIDevSetClassProg(dev, 0x00);
- PCIDevSetClassSub(dev, 0x80);
- PCIDevSetClassBase(dev, 0x06);
+ PCIDevSetClassProg(&pThis->dev, 0x00);
+ PCIDevSetClassSub(&pThis->dev, 0x80);
+ PCIDevSetClassBase(&pThis->dev, 0x06);
- PCIDevSetHeaderType(dev, 0x80);
+ PCIDevSetHeaderType(&pThis->dev, 0x80);
- PCIDevSetBIST(dev, 0x00);
+ PCIDevSetBIST(&pThis->dev, 0x00);
- PCIDevSetInterruptLine(dev, SCI_INT);
- PCIDevSetInterruptPin (dev, 0x01);
+ PCIDevSetInterruptLine(&pThis->dev, SCI_INT);
+ PCIDevSetInterruptPin (&pThis->dev, 0x01);
- dev->config[0x40] = 0x01; /* PM base address, this bit marks it as IO range, not PA */
+ pThis->dev.config[0x40] = 0x01; /* PM base address, this bit marks it as IO range, not PA */
#if 0
int smb_io_base = 0xb100;
@@ -2871,26 +3110,29 @@ static DECLCALLBACK(int) acpiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
dev->config[0x90] = smb_io_base >> 8;
#endif
- rc = PDMDevHlpPCIRegister(pDevIns, dev);
+ rc = PDMDevHlpPCIRegister(pDevIns, &pThis->dev);
if (RT_FAILURE(rc))
return rc;
- PDMDevHlpPCISetConfigCallbacks(pDevIns, dev,
- acpiPciConfigRead, &s->pfnAcpiPciConfigRead,
- acpiPciConfigWrite, &s->pfnAcpiPciConfigWrite);
+ PDMDevHlpPCISetConfigCallbacks(pDevIns, &pThis->dev,
+ acpiPciConfigRead, &pThis->pfnAcpiPciConfigRead,
+ acpiPciConfigWrite, &pThis->pfnAcpiPciConfigWrite);
- rc = PDMDevHlpSSMRegister(pDevIns, 6, sizeof(*s), acpiSaveState, acpiLoadState);
+ /*
+ * Register the saved state.
+ */
+ rc = PDMDevHlpSSMRegister(pDevIns, 6, sizeof(*pThis), acpiSaveState, acpiLoadState);
if (RT_FAILURE(rc))
return rc;
/*
* Get the corresponding connector interface
*/
- rc = PDMDevHlpDriverAttach(pDevIns, 0, &s->IBase, &s->pDrvBase, "ACPI Driver Port");
+ rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "ACPI Driver Port");
if (RT_SUCCESS(rc))
{
- s->pDrv = PDMIBASE_QUERY_INTERFACE(s->pDrvBase, PDMIACPICONNECTOR);
- if (!s->pDrv)
+ pThis->pDrv = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIACPICONNECTOR);
+ if (!pThis->pDrv)
return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_MISSING_INTERFACE,
N_("LUN #0 doesn't have an ACPI connector interface"));
}
diff --git a/src/VBox/Devices/PC/DevAPIC.cpp b/src/VBox/Devices/PC/DevAPIC.cpp
index 59963a9c7..b1ff50975 100644
--- a/src/VBox/Devices/PC/DevAPIC.cpp
+++ b/src/VBox/Devices/PC/DevAPIC.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevAPIC.cpp $ */
+/* $Id: DevAPIC.cpp 37636 2011-06-24 14:59:59Z vboxsync $ */
/** @file
* Advanced Programmable Interrupt Controller (APIC) Device and
* I/O Advanced Programmable Interrupt Controller (IO-APIC) Device.
@@ -19,6 +19,24 @@
* This code is based on:
*
* apic.c revision 1.5 @@OSETODO
+ *
+ * APIC support
+ *
+ * Copyright (c) 2004-2005 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*******************************************************************************
@@ -35,7 +53,11 @@
#include <VBox/msi.h>
#include "VBoxDD2.h"
+#include "DevApic.h"
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
#define MSR_IA32_APICBASE 0x1b
#define MSR_IA32_APICBASE_BSP (1<<8)
#define MSR_IA32_APICBASE_ENABLE (1<<11)
@@ -59,45 +81,53 @@
/** @def APIC_LOCK
* Acquires the PDM lock. */
-#define APIC_LOCK(pThis, rcBusy) \
+#define APIC_LOCK(a_pDev, rcBusy) \
do { \
- int rc2 = PDMCritSectEnter((pThis)->CTX_SUFF(pCritSect), (rcBusy)); \
+ int rc2 = PDMCritSectEnter((a_pDev)->CTX_SUFF(pCritSect), (rcBusy)); \
if (rc2 != VINF_SUCCESS) \
return rc2; \
} while (0)
/** @def APIC_LOCK_VOID
* Acquires the PDM lock and does not expect failure (i.e. ring-3 only!). */
-#define APIC_LOCK_VOID(pThis, rcBusy) \
+#define APIC_LOCK_VOID(a_pDev, rcBusy) \
do { \
- int rc2 = PDMCritSectEnter((pThis)->CTX_SUFF(pCritSect), (rcBusy)); \
+ int rc2 = PDMCritSectEnter((a_pDev)->CTX_SUFF(pCritSect), (rcBusy)); \
AssertLogRelRCReturnVoid(rc2); \
} while (0)
/** @def APIC_UNLOCK
* Releases the PDM lock. */
-#define APIC_UNLOCK(pThis) \
- PDMCritSectLeave((pThis)->CTX_SUFF(pCritSect))
+#define APIC_UNLOCK(a_pDev) \
+ PDMCritSectLeave((a_pDev)->CTX_SUFF(pCritSect))
-/** @def IOAPIC_LOCK
- * Acquires the PDM lock. */
-#define IOAPIC_LOCK(pThis, rc) \
+/** @def APIC_AND_TM_LOCK
+ * Acquires the virtual sync clock lock as well as the PDM lock. */
+#define APIC_AND_TM_LOCK(a_pDev, a_pAcpi, rcBusy) \
do { \
- int rc2 = (pThis)->CTX_SUFF(pIoApicHlp)->pfnLock((pThis)->CTX_SUFF(pDevIns), rc); \
+ int rc2 = TMTimerLock((a_pAcpi)->CTX_SUFF(pTimer), (rcBusy)); \
if (rc2 != VINF_SUCCESS) \
return rc2; \
+ rc2 = PDMCritSectEnter((a_pDev)->CTX_SUFF(pCritSect), (rcBusy)); \
+ if (rc2 != VINF_SUCCESS) \
+ { \
+ TMTimerUnlock((a_pAcpi)->CTX_SUFF(pTimer)); \
+ return rc2; \
+ } \
} while (0)
-/** @def IOAPIC_UNLOCK
- * Releases the PDM lock. */
-#define IOAPIC_UNLOCK(pThis) (pThis)->CTX_SUFF(pIoApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns))
-
+/** @def APIC_AND_TM_UNLOCK
+ * Releases the PDM lock as well as the TM virtual sync clock lock. */
+#define APIC_AND_TM_UNLOCK(a_pDev, a_pAcpi) \
+ do { \
+ TMTimerUnlock((a_pAcpi)->CTX_SUFF(pTimer)); \
+ PDMCritSectLeave((a_pDev)->CTX_SUFF(pCritSect)); \
+ } while (0)
-#define foreach_apic(dev, mask, code) \
+#define foreach_apic(pDev, mask, code) \
do { \
- uint32_t i; \
- APICState *apic = (dev)->CTX_SUFF(paLapics); \
- for (i = 0; i < (dev)->cCpus; i++) \
+ APICState *apic = (pDev)->CTX_SUFF(paLapics); \
+ for (uint32_t i = 0; i < (pDev)->cCpus; i++) \
{ \
if (mask & (1 << (apic->id))) \
{ \
@@ -112,27 +142,7 @@
# define fls_bit(value) (ASMBitLastSetU32(value) - 1)
# define ffs_bit(value) (ASMBitFirstSetU32(value) - 1)
-/*
- * APIC support
- *
- * Copyright (c) 2004-2005 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
#define DEBUG_APIC
-#define DEBUG_IOAPIC
/* APIC Local Vector Table */
#define APIC_LVT_TIMER 0
@@ -166,8 +176,6 @@
#define APIC_INPUT_POLARITY (1<<13)
#define APIC_SEND_PENDING (1<<12)
-#define IOAPIC_NUM_PINS 0x18
-
#define ESR_ILLEGAL_ADDRESS (1 << 7)
#define APIC_SV_ENABLE (1 << 8)
@@ -177,6 +185,10 @@
typedef uint32_t PhysApicId;
typedef uint32_t LogApicId;
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
typedef struct APICState {
uint32_t apicbase;
/* Task priority register (interrupt level) */
@@ -244,40 +256,6 @@ AssertCompileMemberAlignment(APICState, initial_count_load_time, 8);
AssertCompileMemberAlignment(APICState, StatTimerSetInitialCount, 8);
# endif
-struct IOAPICState {
- uint8_t id;
- uint8_t ioregsel;
-
- uint32_t irr;
- uint64_t ioredtbl[IOAPIC_NUM_PINS];
-
- /** The device instance - R3 Ptr. */
- PPDMDEVINSR3 pDevInsR3;
- /** The IOAPIC helpers - R3 Ptr. */
- PCPDMIOAPICHLPR3 pIoApicHlpR3;
-
- /** The device instance - R0 Ptr. */
- PPDMDEVINSR0 pDevInsR0;
- /** The IOAPIC helpers - R0 Ptr. */
- PCPDMIOAPICHLPR0 pIoApicHlpR0;
-
- /** The device instance - RC Ptr. */
- PPDMDEVINSRC pDevInsRC;
- /** The IOAPIC helpers - RC Ptr. */
- PCPDMIOAPICHLPRC pIoApicHlpRC;
-
-# ifdef VBOX_WITH_STATISTICS
- STAMCOUNTER StatMMIOReadGC;
- STAMCOUNTER StatMMIOReadHC;
- STAMCOUNTER StatMMIOWriteGC;
- STAMCOUNTER StatMMIOWriteHC;
- STAMCOUNTER StatSetIrqGC;
- STAMCOUNTER StatSetIrqHC;
-# endif
-};
-
-typedef struct IOAPICState IOAPICState;
-
typedef struct
{
/** The device instance - R3 Ptr. */
@@ -337,104 +315,83 @@ AssertCompileMemberAlignment(APICDeviceInfo, StatMMIOReadGC, 8);
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
-RT_C_DECLS_BEGIN
-PDMBOTHCBDECL(int) apicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) apicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns);
-PDMBOTHCBDECL(bool) apicHasPendingIrq(PPDMDEVINS pDevIns);
-PDMBOTHCBDECL(void) apicSetBase(PPDMDEVINS pDevIns, uint64_t val);
-PDMBOTHCBDECL(uint64_t) apicGetBase(PPDMDEVINS pDevIns);
-PDMBOTHCBDECL(void) apicSetTPR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t val);
-PDMBOTHCBDECL(uint8_t) apicGetTPR(PPDMDEVINS pDevIns, VMCPUID idCpu);
-PDMBOTHCBDECL(int) apicBusDeliverCallback(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
- uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity,
- uint8_t u8TriggerMode);
-PDMBOTHCBDECL(int) apicLocalInterrupt(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level);
-PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value);
-PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value);
-PDMBOTHCBDECL(int) ioapicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) ioapicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(void) ioapicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
-PDMBOTHCBDECL(void) ioapicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue);
-
-static void apic_update_tpr(APICDeviceInfo *dev, APICState* s, uint32_t val);
-RT_C_DECLS_END
-
-static void apic_eoi(APICDeviceInfo *dev, APICState* s); /* */
-static uint32_t apic_get_delivery_bitmask(APICDeviceInfo* dev, uint8_t dest, uint8_t dest_mode);
-static int apic_deliver(APICDeviceInfo* dev, APICState *s,
+static void apic_update_tpr(APICDeviceInfo *pDev, APICState* s, uint32_t val);
+
+static void apic_eoi(APICDeviceInfo *pDev, APICState* s); /* */
+static uint32_t apic_get_delivery_bitmask(APICDeviceInfo* pDev, uint8_t dest, uint8_t dest_mode);
+static int apic_deliver(APICDeviceInfo* pDev, APICState *s,
uint8_t dest, uint8_t dest_mode,
uint8_t delivery_mode, uint8_t vector_num,
uint8_t polarity, uint8_t trigger_mode);
static int apic_get_arb_pri(APICState *s);
static int apic_get_ppr(APICState *s);
-static uint32_t apic_get_current_count(APICDeviceInfo* dev, APICState *s);
-static void apicTimerSetInitialCount(APICDeviceInfo *dev, APICState *s, uint32_t initial_count);
-static void apicTimerSetLvt(APICDeviceInfo *dev, APICState *pThis, uint32_t fNew);
-static void apicSendInitIpi(APICDeviceInfo* dev, APICState *s);
+static uint32_t apic_get_current_count(APICDeviceInfo* pDev, APICState *s);
+static void apicTimerSetInitialCount(APICDeviceInfo *pDev, APICState *s, uint32_t initial_count);
+static void apicTimerSetLvt(APICDeviceInfo *pDev, APICState *pApic, uint32_t fNew);
+static void apicSendInitIpi(APICDeviceInfo* pDev, APICState *s);
-static void apic_init_ipi(APICDeviceInfo* dev, APICState *s);
-static void apic_set_irq(APICDeviceInfo* dev, APICState *s, int vector_num, int trigger_mode);
-static bool apic_update_irq(APICDeviceInfo* dev, APICState *s);
+static void apic_init_ipi(APICDeviceInfo* pDev, APICState *s);
+static void apic_set_irq(APICDeviceInfo* pDev, APICState *s, int vector_num, int trigger_mode);
+static bool apic_update_irq(APICDeviceInfo* pDev, APICState *s);
-DECLINLINE(APICState*) getLapicById(APICDeviceInfo* dev, VMCPUID id)
+DECLINLINE(APICState*) getLapicById(APICDeviceInfo *pDev, VMCPUID id)
{
- AssertFatalMsg(id < dev->cCpus, ("CPU id %d out of range\n", id));
- return &dev->CTX_SUFF(paLapics)[id];
+ AssertFatalMsg(id < pDev->cCpus, ("CPU id %d out of range\n", id));
+ return &pDev->CTX_SUFF(paLapics)[id];
}
-DECLINLINE(APICState*) getLapic(APICDeviceInfo* dev)
+DECLINLINE(APICState*) getLapic(APICDeviceInfo* pDev)
{
/* LAPIC's array is indexed by CPU id */
- VMCPUID id = dev->CTX_SUFF(pApicHlp)->pfnGetCpuId(dev->CTX_SUFF(pDevIns));
- return getLapicById(dev, id);
+ VMCPUID id = pDev->CTX_SUFF(pApicHlp)->pfnGetCpuId(pDev->CTX_SUFF(pDevIns));
+ return getLapicById(pDev, id);
}
-DECLINLINE(VMCPUID) getCpuFromLapic(APICDeviceInfo* dev, APICState *s)
+DECLINLINE(VMCPUID) getCpuFromLapic(APICDeviceInfo* pDev, APICState *s)
{
/* for now we assume LAPIC physical id == CPU id */
return VMCPUID(s->phys_id);
}
-DECLINLINE(void) cpuSetInterrupt(APICDeviceInfo* dev, APICState *s, PDMAPICIRQ enmType = PDMAPICIRQ_HARDWARE)
+DECLINLINE(void) cpuSetInterrupt(APICDeviceInfo* pDev, APICState *s, PDMAPICIRQ enmType = PDMAPICIRQ_HARDWARE)
{
- LogFlow(("apic: setting interrupt flag for cpu %d\n", getCpuFromLapic(dev, s)));
- dev->CTX_SUFF(pApicHlp)->pfnSetInterruptFF(dev->CTX_SUFF(pDevIns), enmType,
- getCpuFromLapic(dev, s));
+ LogFlow(("apic: setting interrupt flag for cpu %d\n", getCpuFromLapic(pDev, s)));
+ pDev->CTX_SUFF(pApicHlp)->pfnSetInterruptFF(pDev->CTX_SUFF(pDevIns), enmType,
+ getCpuFromLapic(pDev, s));
}
-DECLINLINE(void) cpuClearInterrupt(APICDeviceInfo* dev, APICState *s, PDMAPICIRQ enmType = PDMAPICIRQ_HARDWARE)
+DECLINLINE(void) cpuClearInterrupt(APICDeviceInfo* pDev, APICState *s, PDMAPICIRQ enmType = PDMAPICIRQ_HARDWARE)
{
LogFlow(("apic: clear interrupt flag\n"));
- dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns), enmType,
- getCpuFromLapic(dev, s));
+ pDev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(pDev->CTX_SUFF(pDevIns), enmType,
+ getCpuFromLapic(pDev, s));
}
# ifdef IN_RING3
-DECLINLINE(void) cpuSendSipi(APICDeviceInfo* dev, APICState *s, int vector)
+DECLINLINE(void) cpuSendSipi(APICDeviceInfo* pDev, APICState *s, int vector)
{
Log2(("apic: send SIPI vector=%d\n", vector));
- dev->pApicHlpR3->pfnSendSipi(dev->pDevInsR3,
- getCpuFromLapic(dev, s),
+ pDev->pApicHlpR3->pfnSendSipi(pDev->pDevInsR3,
+ getCpuFromLapic(pDev, s),
vector);
}
-DECLINLINE(void) cpuSendInitIpi(APICDeviceInfo* dev, APICState *s)
+DECLINLINE(void) cpuSendInitIpi(APICDeviceInfo* pDev, APICState *s)
{
Log2(("apic: send init IPI\n"));
- dev->pApicHlpR3->pfnSendInitIpi(dev->pDevInsR3,
- getCpuFromLapic(dev, s));
+ pDev->pApicHlpR3->pfnSendInitIpi(pDev->pDevInsR3,
+ getCpuFromLapic(pDev, s));
}
# endif /* IN_RING3 */
-DECLINLINE(uint32_t) getApicEnableBits(APICDeviceInfo* dev)
+DECLINLINE(uint32_t) getApicEnableBits(APICDeviceInfo* pDev)
{
- switch (dev->enmVersion)
+ switch (pDev->enmVersion)
{
case PDMAPICVERSION_NONE:
return 0;
@@ -443,7 +400,7 @@ DECLINLINE(uint32_t) getApicEnableBits(APICDeviceInfo* dev)
case PDMAPICVERSION_X2APIC:
return MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_X2ENABLE ;
default:
- AssertMsgFailed(("Unsupported APIC version %d\n", dev->enmVersion));
+ AssertMsgFailed(("Unsupported APIC version %d\n", pDev->enmVersion));
return 0;
}
}
@@ -465,7 +422,7 @@ DECLINLINE(PDMAPICVERSION) getApicMode(APICState *apic)
}
}
-static int apic_bus_deliver(APICDeviceInfo* dev,
+static int apic_bus_deliver(APICDeviceInfo* pDev,
uint32_t deliver_bitmask, uint8_t delivery_mode,
uint8_t vector_num, uint8_t polarity,
uint8_t trigger_mode)
@@ -479,8 +436,8 @@ static int apic_bus_deliver(APICDeviceInfo* dev,
d = ffs_bit(deliver_bitmask);
if (d >= 0)
{
- APICState* apic = getLapicById(dev, d);
- apic_set_irq(dev, apic, vector_num, trigger_mode);
+ APICState* apic = getLapicById(pDev, d);
+ apic_set_irq(pDev, apic, vector_num, trigger_mode);
}
return VINF_SUCCESS;
}
@@ -489,20 +446,20 @@ static int apic_bus_deliver(APICDeviceInfo* dev,
break;
case APIC_DM_SMI:
- foreach_apic(dev, deliver_bitmask,
- cpuSetInterrupt(dev, apic, PDMAPICIRQ_SMI));
+ foreach_apic(pDev, deliver_bitmask,
+ cpuSetInterrupt(pDev, apic, PDMAPICIRQ_SMI));
return VINF_SUCCESS;
case APIC_DM_NMI:
- foreach_apic(dev, deliver_bitmask,
- cpuSetInterrupt(dev, apic, PDMAPICIRQ_NMI));
+ foreach_apic(pDev, deliver_bitmask,
+ cpuSetInterrupt(pDev, apic, PDMAPICIRQ_NMI));
return VINF_SUCCESS;
case APIC_DM_INIT:
/* normal INIT IPI sent to processors */
#ifdef IN_RING3
- foreach_apic(dev, deliver_bitmask,
- apicSendInitIpi(dev, apic));
+ foreach_apic(pDev, deliver_bitmask,
+ apicSendInitIpi(pDev, apic));
return VINF_SUCCESS;
#else
/* We shall send init IPI only in R3, R0 calls should be
@@ -517,27 +474,27 @@ static int apic_bus_deliver(APICDeviceInfo* dev,
return VINF_SUCCESS;
}
- foreach_apic(dev, deliver_bitmask,
- apic_set_irq (dev, apic, vector_num, trigger_mode));
+ foreach_apic(pDev, deliver_bitmask,
+ apic_set_irq (pDev, apic, vector_num, trigger_mode));
return VINF_SUCCESS;
}
PDMBOTHCBDECL(void) apicSetBase(PPDMDEVINS pDevIns, uint64_t val)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- Assert(PDMCritSectIsOwner(dev->CTX_SUFF(pCritSect)));
- APICState *s = getLapic(dev); /** @todo fix interface */
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ Assert(PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect)));
+ APICState *s = getLapic(pDev); /** @todo fix interface */
Log(("apicSetBase: %016RX64\n", val));
/** @todo: do we need to lock here ? */
- /* APIC_LOCK_VOID(dev, VERR_INTERNAL_ERROR); */
+ /* APIC_LOCK_VOID(pDev, VERR_INTERNAL_ERROR); */
/** @todo If this change is valid immediately, then we should change the MMIO registration! */
/* We cannot change if this CPU is BSP or not by writing to MSR - it's hardwired */
PDMAPICVERSION oldMode = getApicMode(s);
s->apicbase =
(val & 0xfffff000) | /* base */
- (val & getApicEnableBits(dev)) | /* mode */
+ (val & getApicEnableBits(pDev)) | /* mode */
(s->apicbase & MSR_IA32_APICBASE_BSP) /* keep BSP bit */;
PDMAPICVERSION newMode = getApicMode(s);
@@ -549,9 +506,9 @@ PDMBOTHCBDECL(void) apicSetBase(PPDMDEVINS pDevIns, uint64_t val)
{
s->spurious_vec &= ~APIC_SV_ENABLE;
/* Clear any pending APIC interrupt action flag. */
- cpuClearInterrupt(dev, s);
+ cpuClearInterrupt(pDev, s);
/** @todo: why do we do that? */
- dev->CTX_SUFF(pApicHlp)->pfnChangeFeature(pDevIns, PDMAPICVERSION_NONE);
+ pDev->CTX_SUFF(pApicHlp)->pfnChangeFeature(pDevIns, PDMAPICVERSION_NONE);
break;
}
case PDMAPICVERSION_APIC:
@@ -564,137 +521,180 @@ PDMBOTHCBDECL(void) apicSetBase(PPDMDEVINS pDevIns, uint64_t val)
break;
}
}
- /* APIC_UNLOCK(dev); */
+ /* APIC_UNLOCK(pDev); */
}
PDMBOTHCBDECL(uint64_t) apicGetBase(PPDMDEVINS pDevIns)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- Assert(PDMCritSectIsOwner(dev->CTX_SUFF(pCritSect)));
- APICState *s = getLapic(dev); /** @todo fix interface */
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ Assert(PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect)));
+ APICState *s = getLapic(pDev); /** @todo fix interface */
LogFlow(("apicGetBase: %016llx\n", (uint64_t)s->apicbase));
return s->apicbase;
}
PDMBOTHCBDECL(void) apicSetTPR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t val)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- Assert(PDMCritSectIsOwner(dev->CTX_SUFF(pCritSect)));
- APICState *s = getLapicById(dev, idCpu);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ Assert(PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect)));
+ APICState *s = getLapicById(pDev, idCpu);
LogFlow(("apicSetTPR: val=%#x (trp %#x -> %#x)\n", val, s->tpr, val));
- apic_update_tpr(dev, s, val);
+ apic_update_tpr(pDev, s, val);
}
PDMBOTHCBDECL(uint8_t) apicGetTPR(PPDMDEVINS pDevIns, VMCPUID idCpu)
{
/* We don't perform any locking here as that would cause a lot of contention for VT-x/AMD-V. */
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- APICState *s = getLapicById(dev, idCpu);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ APICState *s = getLapicById(pDev, idCpu);
Log2(("apicGetTPR: returns %#x\n", s->tpr));
return s->tpr;
}
/**
- * x2APIC MSR write interface.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param idCpu The ID of the virtual CPU and thereby APIC index.
- * @param u32Reg Register to write (ecx).
- * @param u64Value The value to write (eax:edx / rax).
+ * Writes to an APIC register via MMIO or MSR.
*
+ * @returns Strict VBox status code.
+ * @param pDev The PDM device instance.
+ * @param pApic The APIC being written to.
+ * @param iReg The APIC register index.
+ * @param u64Value The value being written.
+ * @param rcBusy The busy return code to employ. See
+ * PDMCritSectEnter for a description.
+ * @param fMsr Set if called via MSR, clear if MMIO.
*/
-PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value)
+static int apicWriteRegister(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg, uint64_t u64Value,
+ int rcBusy, bool fMsr)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- Assert(PDMCritSectIsOwner(dev->CTX_SUFF(pCritSect)));
- int rc = VINF_SUCCESS;
-
- if (dev->enmVersion < PDMAPICVERSION_X2APIC)
- return VERR_EM_INTERPRETER;
-
- APICState *pThis = getLapicById(dev, idCpu);
+ Assert(!PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect)));
- uint32_t index = (u32Reg - MSR_IA32_APIC_START) & 0xff;
- switch (index)
+ int rc = VINF_SUCCESS;
+ switch (iReg)
{
case 0x02:
- pThis->id = (u64Value >> 24);
+ APIC_LOCK(pDev, rcBusy);
+ pApic->id = (u64Value >> 24); /** @todo r=bird: Is the range supposed to be 40 bits??? */
+ APIC_UNLOCK(pDev);
break;
+
case 0x03:
+ /* read only, ignore write. */
break;
+
case 0x08:
- apic_update_tpr(dev, pThis, u64Value);
+ APIC_LOCK(pDev, rcBusy);
+ apic_update_tpr(pDev, pApic, u64Value);
+ APIC_UNLOCK(pDev);
break;
+
case 0x09: case 0x0a:
- Log(("apicWriteMSR: write to read-only register %d ignored\n", index));
+ Log(("apicWriteRegister: write to read-only register %d ignored\n", iReg));
break;
+
case 0x0b: /* EOI */
- apic_eoi(dev, pThis);
+ APIC_LOCK(pDev, rcBusy);
+ apic_eoi(pDev, pApic);
+ APIC_UNLOCK(pDev);
break;
+
case 0x0d:
- pThis->log_dest = u64Value >> 24;
+ APIC_LOCK(pDev, rcBusy);
+ pApic->log_dest = (u64Value >> 24) & 0xff;
+ APIC_UNLOCK(pDev);
break;
+
case 0x0e:
- pThis->dest_mode = u64Value >> 28;
+ APIC_LOCK(pDev, rcBusy);
+ pApic->dest_mode = u64Value >> 28; /** @todo r=bird: range? This used to be 32-bit before morphed into an MSR handler. */
+ APIC_UNLOCK(pDev);
break;
+
case 0x0f:
- pThis->spurious_vec = u64Value & 0x1ff;
- apic_update_irq(dev, pThis);
+ APIC_LOCK(pDev, rcBusy);
+ pApic->spurious_vec = u64Value & 0x1ff;
+ apic_update_irq(pDev, pApic);
+ APIC_UNLOCK(pDev);
break;
+
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
case 0x28:
- Log(("apicWriteMSR: write to read-only register %d ignored\n", index));
+ Log(("apicWriteRegister: write to read-only register %d ignored\n", iReg));
break;
case 0x30:
- /* Here one of the differences with regular APIC: ICR is single 64-bit register */
- pThis->icr[0] = (uint32_t)u64Value;
- pThis->icr[1] = (uint32_t)(u64Value >> 32);
- rc = apic_deliver(dev, pThis, (pThis->icr[1] >> 24) & 0xff, (pThis->icr[0] >> 11) & 1,
- (pThis->icr[0] >> 8) & 7, (pThis->icr[0] & 0xff),
- (pThis->icr[0] >> 14) & 1, (pThis->icr[0] >> 15) & 1);
+ APIC_LOCK(pDev, rcBusy);
+ pApic->icr[0] = (uint32_t)u64Value;
+ if (fMsr) /* Here one of the differences with regular APIC: ICR is single 64-bit register */
+ pApic->icr[1] = (uint32_t)(u64Value >> 32);
+ rc = apic_deliver(pDev, pApic, (pApic->icr[1] >> 24) & 0xff, (pApic->icr[0] >> 11) & 1,
+ (pApic->icr[0] >> 8) & 7, (pApic->icr[0] & 0xff),
+ (pApic->icr[0] >> 14) & 1, (pApic->icr[0] >> 15) & 1);
+ APIC_UNLOCK(pDev);
+ break;
+
+ case 0x31:
+ APIC_LOCK(pDev, rcBusy);
+ if (!fMsr)
+ pApic->icr[1] = (uint64_t)u64Value;
+ else
+ pApic->esr |= ESR_ILLEGAL_ADDRESS;
+ APIC_UNLOCK(pDev);
break;
+
case 0x32 + APIC_LVT_TIMER:
AssertCompile(APIC_LVT_TIMER == 0);
- apicTimerSetLvt(dev, pThis, u64Value);
+ APIC_AND_TM_LOCK(pDev, pApic, rcBusy);
+ apicTimerSetLvt(pDev, pApic, u64Value);
+ APIC_AND_TM_UNLOCK(pDev, pApic);
break;
case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
- pThis->lvt[index - 0x32] = u64Value;
+ APIC_LOCK(pDev, rcBusy);
+ pApic->lvt[iReg - 0x32] = u64Value;
+ APIC_UNLOCK(pDev);
break;
+
case 0x38:
- apicTimerSetInitialCount(dev, pThis, u64Value);
+ APIC_AND_TM_LOCK(pDev, pApic, rcBusy);
+ apicTimerSetInitialCount(pDev, pApic, u64Value);
+ APIC_AND_TM_UNLOCK(pDev, pApic);
break;
+
case 0x39:
- Log(("apicWriteMSR: write to read-only register %d ignored\n", index));
+ Log(("apicWriteRegister: write to read-only register %d ignored\n", iReg));
break;
+
case 0x3e:
{
- int v;
- pThis->divide_conf = u64Value & 0xb;
- v = (pThis->divide_conf & 3) | ((pThis->divide_conf >> 1) & 4);
- pThis->count_shift = (v + 1) & 7;
+ APIC_LOCK(pDev, rcBusy);
+ pApic->divide_conf = u64Value & 0xb;
+ int v = (pApic->divide_conf & 3) | ((pApic->divide_conf >> 1) & 4);
+ pApic->count_shift = (v + 1) & 7;
+ APIC_UNLOCK(pDev);
break;
}
+
case 0x3f:
- {
- /* Self IPI, see x2APIC book 2.4.5 */
- int vector = u64Value & 0xff;
- rc = apic_bus_deliver(dev,
- 1 << getLapicById(dev, idCpu)->id /* Self */,
- 0 /* Delivery mode - fixed */,
- vector,
- 0 /* Polarity - conform to the bus */,
- 0 /* Trigger mode - edge */);
- break;
- }
+ if (fMsr)
+ {
+ /* Self IPI, see x2APIC book 2.4.5 */
+ APIC_LOCK(pDev, rcBusy);
+ int vector = u64Value & 0xff;
+ rc = apic_bus_deliver(pDev,
+ 1 << pApic->id /* Self */,
+ 0 /* Delivery mode - fixed */,
+ vector,
+ 0 /* Polarity - conform to the bus */,
+ 0 /* Trigger mode - edge */);
+ APIC_UNLOCK(pDev);
+ break;
+ }
+ /* else: fall thru */
default:
- AssertMsgFailed(("apicWriteMSR: unknown index %x\n", index));
- pThis->esr |= ESR_ILLEGAL_ADDRESS;
+ AssertMsgFailed(("unknown iReg %x\n", iReg));
+ pApic->esr |= ESR_ILLEGAL_ADDRESS;
break;
}
@@ -702,26 +702,35 @@ PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32R
}
/**
- * x2APIC MSR read interface.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param idCpu The ID of the virtual CPU and thereby APIC index.
- * @param u32Reg Register to write (ecx).
- * @param pu64Value Where to return the value (eax:edx / rax).
+ * @interface_method_impl{PDMAPICREG,pfnWriteMSRR3}
+ */
+PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value)
+{
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ if (pDev->enmVersion < PDMAPICVERSION_X2APIC)
+ return VERR_EM_INTERPRETER; /** @todo tell the caller to raise hell (\#GP(0)). */
+
+ APICState *pApic = getLapicById(pDev, idCpu);
+ uint32_t iReg = (u32Reg - MSR_IA32_APIC_START) & 0xff;
+ return apicWriteRegister(pDev, pApic, iReg, u64Value, VINF_SUCCESS /*rcBusy*/, true /*fMsr*/);
+}
+
+
+/**
+ * @interface_method_impl{PDMAPICREG,pfnReadMSRR3}
*/
PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- Assert(PDMCritSectIsOwner(dev->CTX_SUFF(pCritSect)));
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ Assert(PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect)));
- if (dev->enmVersion < PDMAPICVERSION_X2APIC)
+ if (pDev->enmVersion < PDMAPICVERSION_X2APIC)
return VERR_EM_INTERPRETER;
- uint32_t index = (u32Reg - MSR_IA32_APIC_START) & 0xff;
- APICState* apic = getLapicById(dev, idCpu);
- uint64_t val = 0;
+ uint32_t index = (u32Reg - MSR_IA32_APIC_START) & 0xff;
+ APICState *apic = getLapicById(pDev, idCpu);
+ uint64_t val = 0;
+ int rc = VINF_SUCCESS;
switch (index)
{
@@ -729,9 +738,9 @@ PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Re
val = apic->id << 24;
break;
case 0x03: /* version */
- val = APIC_HW_VERSION |
- ((APIC_LVT_NB - 1) << 16) /* Max LVT index */ |
- (0 << 24) /* Support for EOI broadcast suppression */;
+ val = APIC_HW_VERSION
+ | ((APIC_LVT_NB - 1) << 16) /* Max LVT index */
+ | (0 << 24) /* Support for EOI broadcast suppression */;
break;
case 0x08:
val = apic->tpr;
@@ -755,7 +764,7 @@ PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Re
break;
case 0x0f:
val = apic->spurious_vec;
- break;
+ break;
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
val = apic->isr[index & 7];
break;
@@ -779,7 +788,7 @@ PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Re
val = apic->initial_count;
break;
case 0x39:
- val = apic_get_current_count(dev, apic);
+ val = apic_get_current_count(pDev, apic);
break;
case 0x3e:
val = apic->divide_conf;
@@ -803,7 +812,7 @@ PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Re
break;
}
*pu64Value = val;
- return VINF_SUCCESS;
+ return rc;
}
/**
@@ -814,11 +823,11 @@ PDMBOTHCBDECL(int) apicBusDeliverCallback(PPDMDEVINS pDevIns, uint8_t u8Dest, ui
uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity,
uint8_t u8TriggerMode)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- Assert(PDMCritSectIsOwner(dev->CTX_SUFF(pCritSect)));
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ Assert(PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect)));
LogFlow(("apicBusDeliverCallback: pDevIns=%p u8Dest=%#x u8DestMode=%#x u8DeliveryMode=%#x iVector=%#x u8Polarity=%#x u8TriggerMode=%#x\n",
pDevIns, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
- return apic_bus_deliver(dev, apic_get_delivery_bitmask(dev, u8Dest, u8DestMode),
+ return apic_bus_deliver(pDev, apic_get_delivery_bitmask(pDev, u8Dest, u8DestMode),
u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
}
@@ -828,10 +837,10 @@ PDMBOTHCBDECL(int) apicBusDeliverCallback(PPDMDEVINS pDevIns, uint8_t u8Dest, ui
*/
PDMBOTHCBDECL(int) apicLocalInterrupt(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- APICState *s = getLapicById(dev, 0);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ APICState *s = getLapicById(pDev, 0);
- Assert(PDMCritSectIsOwner(dev->CTX_SUFF(pCritSect)));
+ Assert(PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect)));
LogFlow(("apicLocalInterrupt: pDevIns=%p u8Pin=%x u8Level=%x\n", pDevIns, u8Pin, u8Level));
/* If LAPIC is disabled, go straight to the CPU. */
@@ -839,9 +848,9 @@ PDMBOTHCBDECL(int) apicLocalInterrupt(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t
{
LogFlow(("apicLocalInterrupt: LAPIC disabled, delivering directly to CPU core.\n"));
if (u8Level)
- cpuSetInterrupt(dev, s, PDMAPICIRQ_EXTINT);
+ cpuSetInterrupt(pDev, s, PDMAPICIRQ_EXTINT);
else
- cpuClearInterrupt(dev, s, PDMAPICIRQ_EXTINT);
+ cpuClearInterrupt(pDev, s, PDMAPICIRQ_EXTINT);
return VINF_SUCCESS;
}
@@ -872,9 +881,9 @@ PDMBOTHCBDECL(int) apicLocalInterrupt(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t
/* ExtINT can be both set and cleared, NMI/SMI/INIT can only be set. */
LogFlow(("apicLocalInterrupt: %s ExtINT interrupt\n", u8Level ? "setting" : "clearing"));
if (u8Level)
- cpuSetInterrupt(dev, s, enmType);
+ cpuSetInterrupt(pDev, s, enmType);
else
- cpuClearInterrupt(dev, s, enmType);
+ cpuClearInterrupt(pDev, s, enmType);
return VINF_SUCCESS;
case APIC_DM_NMI:
/* External NMI should be wired to LINT1, but Linux sometimes programs
@@ -907,7 +916,7 @@ PDMBOTHCBDECL(int) apicLocalInterrupt(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t
}
}
LogFlow(("apicLocalInterrupt: setting local interrupt type %d\n", enmType));
- cpuSetInterrupt(dev, s, enmType);
+ cpuSetInterrupt(pDev, s, enmType);
}
return VINF_SUCCESS;
}
@@ -957,13 +966,13 @@ static int apic_get_arb_pri(APICState *s)
}
/* signal the CPU if an irq is pending */
-static bool apic_update_irq(APICDeviceInfo *dev, APICState* s)
+static bool apic_update_irq(APICDeviceInfo *pDev, APICState* s)
{
int irrv, ppr;
if (!(s->spurious_vec & APIC_SV_ENABLE))
{
/* Clear any pending APIC interrupt action flag. */
- cpuClearInterrupt(dev, s);
+ cpuClearInterrupt(pDev, s);
return false;
}
@@ -973,7 +982,7 @@ static bool apic_update_irq(APICDeviceInfo *dev, APICState* s)
ppr = apic_get_ppr(s);
if (ppr && (irrv & 0xf0) <= (ppr & 0xf0))
return false;
- cpuSetInterrupt(dev, s);
+ cpuSetInterrupt(pDev, s);
return true;
}
@@ -981,13 +990,13 @@ static bool apic_update_irq(APICDeviceInfo *dev, APICState* s)
PDMBOTHCBDECL(bool) apicHasPendingIrq(PPDMDEVINS pDevIns)
{
int irrv, ppr;
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- if (!dev)
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ if (!pDev)
return false;
/* We don't perform any locking here as that would cause a lot of contention for VT-x/AMD-V. */
- APICState *s = getLapic(dev); /** @todo fix interface */
+ APICState *s = getLapic(pDev); /** @todo fix interface */
/*
* All our callbacks now come from single IOAPIC, thus locking
@@ -1005,25 +1014,25 @@ PDMBOTHCBDECL(bool) apicHasPendingIrq(PPDMDEVINS pDevIns)
return true;
}
-static void apic_update_tpr(APICDeviceInfo *dev, APICState* s, uint32_t val)
+static void apic_update_tpr(APICDeviceInfo *pDev, APICState* s, uint32_t val)
{
bool fIrqIsActive = false;
bool fIrqWasActive = false;
- fIrqWasActive = apic_update_irq(dev, s);
+ fIrqWasActive = apic_update_irq(pDev, s);
s->tpr = val;
- fIrqIsActive = apic_update_irq(dev, s);
+ fIrqIsActive = apic_update_irq(pDev, s);
/* If an interrupt is pending and now masked, then clear the FF flag. */
if (fIrqWasActive && !fIrqIsActive)
{
Log(("apic_update_tpr: deactivate interrupt that was masked by the TPR update (%x)\n", val));
- STAM_COUNTER_INC(&dev->StatClearedActiveIrq);
- cpuClearInterrupt(dev, s);
+ STAM_COUNTER_INC(&pDev->StatClearedActiveIrq);
+ cpuClearInterrupt(pDev, s);
}
}
-static void apic_set_irq(APICDeviceInfo *dev, APICState* s, int vector_num, int trigger_mode)
+static void apic_set_irq(APICDeviceInfo *pDev, APICState* s, int vector_num, int trigger_mode)
{
LogFlow(("CPU%d: apic_set_irq vector=%x, trigger_mode=%x\n", s->phys_id, vector_num, trigger_mode));
set_bit(s->irr, vector_num);
@@ -1031,10 +1040,10 @@ static void apic_set_irq(APICDeviceInfo *dev, APICState* s, int vector_num, int
set_bit(s->tmr, vector_num);
else
reset_bit(s->tmr, vector_num);
- apic_update_irq(dev, s);
+ apic_update_irq(pDev, s);
}
-static void apic_eoi(APICDeviceInfo *dev, APICState* s)
+static void apic_eoi(APICDeviceInfo *pDev, APICState* s)
{
int isrv;
isrv = get_highest_priority_int(s->isr);
@@ -1044,10 +1053,10 @@ static void apic_eoi(APICDeviceInfo *dev, APICState* s)
LogFlow(("CPU%d: apic_eoi isrv=%x\n", s->phys_id, isrv));
/* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to
set the remote IRR bit for level triggered interrupts. */
- apic_update_irq(dev, s);
+ apic_update_irq(pDev, s);
}
-static uint32_t apic_get_delivery_bitmask(APICDeviceInfo *dev, uint8_t dest, uint8_t dest_mode)
+static uint32_t apic_get_delivery_bitmask(APICDeviceInfo *pDev, uint8_t dest, uint8_t dest_mode)
{
uint32_t mask = 0;
@@ -1060,11 +1069,11 @@ static uint32_t apic_get_delivery_bitmask(APICDeviceInfo *dev, uint8_t dest, uin
}
else
{
- APICState *apic = dev->CTX_SUFF(paLapics);
+ APICState *apic = pDev->CTX_SUFF(paLapics);
uint32_t i;
/* XXX: cluster mode */
- for(i = 0; i < dev->cCpus; i++)
+ for(i = 0; i < pDev->cCpus; i++)
{
if (apic->dest_mode == APIC_DESTMODE_FLAT)
{
@@ -1088,7 +1097,7 @@ static uint32_t apic_get_delivery_bitmask(APICDeviceInfo *dev, uint8_t dest, uin
}
#ifdef IN_RING3
-static void apic_init_ipi(APICDeviceInfo* dev, APICState *s)
+static void apic_init_ipi(APICDeviceInfo* pDev, APICState *s)
{
int i;
@@ -1097,7 +1106,7 @@ static void apic_init_ipi(APICDeviceInfo* dev, APICState *s)
s->tpr = 0;
s->spurious_vec = 0xff;
s->log_dest = 0;
- s->dest_mode = 0xff;
+ s->dest_mode = 0xff; /** @todo 0xff???? */
memset(s->isr, 0, sizeof(s->isr));
memset(s->tmr, 0, sizeof(s->tmr));
memset(s->irr, 0, sizeof(s->irr));
@@ -1111,21 +1120,21 @@ static void apic_init_ipi(APICDeviceInfo* dev, APICState *s)
}
-static void apicSendInitIpi(APICDeviceInfo* dev, APICState *s)
+static void apicSendInitIpi(APICDeviceInfo* pDev, APICState *s)
{
- apic_init_ipi(dev, s);
- cpuSendInitIpi(dev, s);
+ apic_init_ipi(pDev, s);
+ cpuSendInitIpi(pDev, s);
}
/* send a SIPI message to the CPU to start it */
-static void apic_startup(APICDeviceInfo* dev, APICState *s, int vector_num)
+static void apic_startup(APICDeviceInfo* pDev, APICState *s, int vector_num)
{
Log(("[SMP] apic_startup: %d on CPUs %d\n", vector_num, s->phys_id));
- cpuSendSipi(dev, s, vector_num);
+ cpuSendSipi(pDev, s, vector_num);
}
#endif /* IN_RING3 */
-static int apic_deliver(APICDeviceInfo* dev, APICState *s,
+static int apic_deliver(APICDeviceInfo* pDev, APICState *s,
uint8_t dest, uint8_t dest_mode,
uint8_t delivery_mode, uint8_t vector_num,
uint8_t polarity, uint8_t trigger_mode)
@@ -1137,7 +1146,7 @@ static int apic_deliver(APICDeviceInfo* dev, APICState *s,
switch (dest_shorthand) {
case 0:
- deliver_bitmask = apic_get_delivery_bitmask(dev, dest, dest_mode);
+ deliver_bitmask = apic_get_delivery_bitmask(pDev, dest, dest_mode);
break;
case 1:
deliver_bitmask = (1 << s->id);
@@ -1156,7 +1165,7 @@ static int apic_deliver(APICDeviceInfo* dev, APICState *s,
int trig_mode = (s->icr[0] >> 15) & 1;
int level = (s->icr[0] >> 14) & 1;
if (level == 0 && trig_mode == 1) {
- foreach_apic(dev, deliver_bitmask,
+ foreach_apic(pDev, deliver_bitmask,
apic->arb_id = apic->id);
Log(("CPU%d: APIC_DM_INIT arbitration id(s) set\n", s->phys_id));
return VINF_SUCCESS;
@@ -1166,8 +1175,8 @@ static int apic_deliver(APICDeviceInfo* dev, APICState *s,
case APIC_DM_SIPI:
# ifdef IN_RING3
- foreach_apic(dev, deliver_bitmask,
- apic_startup(dev, apic, vector_num));
+ foreach_apic(pDev, deliver_bitmask,
+ apic_startup(pDev, apic, vector_num));
return VINF_SUCCESS;
# else
/* We shall send SIPI only in R3, R0 calls should be
@@ -1176,25 +1185,25 @@ static int apic_deliver(APICDeviceInfo* dev, APICState *s,
# endif
}
- return apic_bus_deliver(dev, deliver_bitmask, delivery_mode, vector_num,
+ return apic_bus_deliver(pDev, deliver_bitmask, delivery_mode, vector_num,
polarity, trigger_mode);
}
PDMBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
/* if the APIC is not installed or enabled, we let the 8259 handle the
IRQs */
- if (!dev)
+ if (!pDev)
{
Log(("apic_get_interrupt: returns -1 (!s)\n"));
return -1;
}
- Assert(PDMCritSectIsOwner(dev->CTX_SUFF(pCritSect)));
+ Assert(PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect)));
- APICState *s = getLapic(dev); /** @todo fix interface */
+ APICState *s = getLapic(pDev); /** @todo fix interface */
int intno;
if (!(s->spurious_vec & APIC_SV_ENABLE)) {
@@ -1214,16 +1223,24 @@ PDMBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns)
}
reset_bit(s->irr, intno);
set_bit(s->isr, intno);
- apic_update_irq(dev, s);
+ apic_update_irq(pDev, s);
LogFlow(("CPU%d: apic_get_interrupt: returns %d\n", s->phys_id, intno));
return intno;
}
-static uint32_t apic_get_current_count(APICDeviceInfo *dev, APICState *s)
+/**
+ * May return to ring-3 to acquire the TM and PDM lock.
+ */
+static uint32_t apic_get_current_count(APICDeviceInfo *pDev, APICState *s)
{
int64_t d;
uint32_t val;
+ /* Acquire the timer lock w/ lock order kludge. */
+ PDMCritSectLeave(pDev->CTX_SUFF(pCritSect));
+ TMTimerLock(s->CTX_SUFF(pTimer), VINF_SUCCESS);
+ PDMCritSectEnter(pDev->CTX_SUFF(pCritSect), VINF_SUCCESS);
+
d = (TMTimerGet(s->CTX_SUFF(pTimer)) - s->initial_count_load_time) >>
s->count_shift;
@@ -1236,32 +1253,35 @@ static uint32_t apic_get_current_count(APICDeviceInfo *dev, APICState *s)
else
val = s->initial_count - d;
}
+
+ TMTimerUnlock(s->CTX_SUFF(pTimer));
+
return val;
}
/**
* Does the frequency hinting and logging.
*
- * @param pThis The device state.
+ * @param pApic The device state.
*/
-DECLINLINE(void) apicDoFrequencyHinting(APICState *pThis)
+DECLINLINE(void) apicDoFrequencyHinting(APICState *pApic)
{
- if ( pThis->uHintedInitialCount != pThis->initial_count
- || pThis->uHintedCountShift != (uint32_t)pThis->count_shift)
+ if ( pApic->uHintedInitialCount != pApic->initial_count
+ || pApic->uHintedCountShift != (uint32_t)pApic->count_shift)
{
- pThis->uHintedInitialCount = pThis->initial_count;
- pThis->uHintedCountShift = pThis->count_shift;
+ pApic->uHintedInitialCount = pApic->initial_count;
+ pApic->uHintedCountShift = pApic->count_shift;
uint32_t uHz;
- if (pThis->initial_count > 0)
+ if (pApic->initial_count > 0)
{
- Assert((unsigned)pThis->count_shift < 30);
- uint64_t cTickPerPeriod = ((uint64_t)pThis->initial_count + 1) << pThis->count_shift;
- uHz = TMTimerGetFreq(pThis->CTX_SUFF(pTimer)) / cTickPerPeriod;
+ Assert((unsigned)pApic->count_shift < 30);
+ uint64_t cTickPerPeriod = ((uint64_t)pApic->initial_count + 1) << pApic->count_shift;
+ uHz = TMTimerGetFreq(pApic->CTX_SUFF(pTimer)) / cTickPerPeriod;
}
else
uHz = 0;
- TMTimerSetFrequencyHint(pThis->CTX_SUFF(pTimer), uHz);
+ TMTimerSetFrequencyHint(pApic->CTX_SUFF(pTimer), uHz);
Log(("apic: %u Hz\n", uHz));
}
}
@@ -1269,20 +1289,20 @@ DECLINLINE(void) apicDoFrequencyHinting(APICState *pThis)
/**
* Implementation of the 0380h access: Timer reset + new initial count.
*
- * @param dev The device state.
- * @param pThis The APIC sub-device state.
+ * @param pDev The device state.
+ * @param pApic The APIC sub-device state.
* @param u32NewInitialCount The new initial count for the timer.
*/
-static void apicTimerSetInitialCount(APICDeviceInfo *dev, APICState *pThis, uint32_t u32NewInitialCount)
+static void apicTimerSetInitialCount(APICDeviceInfo *pDev, APICState *pApic, uint32_t u32NewInitialCount)
{
- STAM_COUNTER_INC(&pThis->StatTimerSetInitialCount);
- pThis->initial_count = u32NewInitialCount;
+ STAM_COUNTER_INC(&pApic->StatTimerSetInitialCount);
+ pApic->initial_count = u32NewInitialCount;
/*
* Don't (re-)arm the timer if the it's masked or if it's
* a zero length one-shot timer.
*/
- if ( !(pThis->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)
+ if ( !(pApic->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)
&& u32NewInitialCount > 0)
{
/*
@@ -1291,46 +1311,47 @@ static void apicTimerSetInitialCount(APICDeviceInfo *dev, APICState *pThis, uint
*/
uint64_t cTicksNext = u32NewInitialCount;
cTicksNext += 1;
- cTicksNext <<= pThis->count_shift;
- TMTimerSetRelative(pThis->CTX_SUFF(pTimer), cTicksNext, &pThis->initial_count_load_time);
- pThis->next_time = pThis->initial_count_load_time + cTicksNext;
- pThis->fTimerArmed = true;
- apicDoFrequencyHinting(pThis);
- STAM_COUNTER_INC(&pThis->StatTimerSetInitialCountArm);
- Log(("apicTimerSetInitialCount: cTicksNext=%'llu (%#llx) ic=%#x sh=%#x nxt=%#llx\n", cTicksNext, cTicksNext, u32NewInitialCount, pThis->count_shift, pThis->next_time));
+ cTicksNext <<= pApic->count_shift;
+ TMTimerSetRelative(pApic->CTX_SUFF(pTimer), cTicksNext, &pApic->initial_count_load_time);
+ pApic->next_time = pApic->initial_count_load_time + cTicksNext;
+ pApic->fTimerArmed = true;
+ apicDoFrequencyHinting(pApic);
+ STAM_COUNTER_INC(&pApic->StatTimerSetInitialCountArm);
+ Log(("apicTimerSetInitialCount: cTicksNext=%'llu (%#llx) ic=%#x sh=%#x nxt=%#llx\n",
+ cTicksNext, cTicksNext, u32NewInitialCount, pApic->count_shift, pApic->next_time));
}
else
{
/* Stop it if necessary and record the load time for unmasking. */
- if (pThis->fTimerArmed)
+ if (pApic->fTimerArmed)
{
- STAM_COUNTER_INC(&pThis->StatTimerSetInitialCountDisarm);
- TMTimerStop(pThis->CTX_SUFF(pTimer));
- pThis->fTimerArmed = false;
- pThis->uHintedCountShift = pThis->uHintedInitialCount = 0;
+ STAM_COUNTER_INC(&pApic->StatTimerSetInitialCountDisarm);
+ TMTimerStop(pApic->CTX_SUFF(pTimer));
+ pApic->fTimerArmed = false;
+ pApic->uHintedCountShift = pApic->uHintedInitialCount = 0;
}
- pThis->initial_count_load_time = TMTimerGet(pThis->CTX_SUFF(pTimer));
- Log(("apicTimerSetInitialCount: ic=%#x sh=%#x iclt=%#llx\n", u32NewInitialCount, pThis->count_shift, pThis->initial_count_load_time));
+ pApic->initial_count_load_time = TMTimerGet(pApic->CTX_SUFF(pTimer));
+ Log(("apicTimerSetInitialCount: ic=%#x sh=%#x iclt=%#llx\n", u32NewInitialCount, pApic->count_shift, pApic->initial_count_load_time));
}
}
/**
* Implementation of the 0320h access: change the LVT flags.
*
- * @param dev The device state.
- * @param pThis The APIC sub-device state to operate on.
+ * @param pDev The device state.
+ * @param pApic The APIC sub-device state to operate on.
* @param fNew The new flags.
*/
-static void apicTimerSetLvt(APICDeviceInfo *dev, APICState *pThis, uint32_t fNew)
+static void apicTimerSetLvt(APICDeviceInfo *pDev, APICState *pApic, uint32_t fNew)
{
- STAM_COUNTER_INC(&pThis->StatTimerSetLvt);
+ STAM_COUNTER_INC(&pApic->StatTimerSetLvt);
/*
* Make the flag change, saving the old ones so we can avoid
* unnecessary work.
*/
- uint32_t const fOld = pThis->lvt[APIC_LVT_TIMER];
- pThis->lvt[APIC_LVT_TIMER] = fNew;
+ uint32_t const fOld = pApic->lvt[APIC_LVT_TIMER];
+ pApic->lvt[APIC_LVT_TIMER] = fNew;
/* Only the masked and peridic bits are relevant (see apic_timer_update). */
if ( (fOld & (APIC_LVT_MASKED | APIC_LVT_TIMER_PERIODIC))
@@ -1346,14 +1367,14 @@ static void apicTimerSetLvt(APICDeviceInfo *dev, APICState *pThis, uint32_t fNew
if ( (fOld & APIC_LVT_TIMER_PERIODIC)
&& !(fNew & APIC_LVT_TIMER_PERIODIC))
{
- STAM_COUNTER_INC(&pThis->StatTimerSetLvtClearPeriodic);
- uint64_t cTicks = (pThis->next_time - pThis->initial_count_load_time) >> pThis->count_shift;
- if (cTicks >= pThis->initial_count)
+ STAM_COUNTER_INC(&pApic->StatTimerSetLvtClearPeriodic);
+ uint64_t cTicks = (pApic->next_time - pApic->initial_count_load_time) >> pApic->count_shift;
+ if (cTicks >= pApic->initial_count)
{
/* not first period, stop it. */
- TMTimerStop(pThis->CTX_SUFF(pTimer));
- pThis->fTimerArmed = false;
- pThis->uHintedCountShift = pThis->uHintedInitialCount = 0;
+ TMTimerStop(pApic->CTX_SUFF(pTimer));
+ pApic->fTimerArmed = false;
+ pApic->uHintedCountShift = pApic->uHintedInitialCount = 0;
}
/* else: first period, let it fire normally. */
}
@@ -1364,9 +1385,9 @@ static void apicTimerSetLvt(APICDeviceInfo *dev, APICState *pThis, uint32_t fNew
* (apicTimerCallback will stop it if still masked.)
*/
if (fNew & APIC_LVT_MASKED)
- STAM_COUNTER_INC(&pThis->StatTimerSetLvtPostponed);
- else if (pThis->fTimerArmed)
- STAM_COUNTER_INC(&pThis->StatTimerSetLvtArmed);
+ STAM_COUNTER_INC(&pApic->StatTimerSetLvtPostponed);
+ else if (pApic->fTimerArmed)
+ STAM_COUNTER_INC(&pApic->StatTimerSetLvtArmed);
/*
* If unmasked, not armed and with a valid initial count value (according
* to our interpretation of the spec), we will have to rearm the timer so
@@ -1375,41 +1396,41 @@ static void apicTimerSetLvt(APICDeviceInfo *dev, APICState *pThis, uint32_t fNew
* N.B. This is code is currently RACING the virtual sync clock!
*/
else if ( (fOld & APIC_LVT_MASKED)
- && pThis->initial_count > 0)
+ && pApic->initial_count > 0)
{
- STAM_COUNTER_INC(&pThis->StatTimerSetLvtArm);
+ STAM_COUNTER_INC(&pApic->StatTimerSetLvtArm);
for (unsigned cTries = 0; ; cTries++)
{
uint64_t NextTS;
- uint64_t cTicks = (TMTimerGet(pThis->CTX_SUFF(pTimer)) - pThis->initial_count_load_time) >> pThis->count_shift;
+ uint64_t cTicks = (TMTimerGet(pApic->CTX_SUFF(pTimer)) - pApic->initial_count_load_time) >> pApic->count_shift;
if (fNew & APIC_LVT_TIMER_PERIODIC)
- NextTS = ((cTicks / ((uint64_t)pThis->initial_count + 1)) + 1) * ((uint64_t)pThis->initial_count + 1);
+ NextTS = ((cTicks / ((uint64_t)pApic->initial_count + 1)) + 1) * ((uint64_t)pApic->initial_count + 1);
else
{
- if (cTicks >= pThis->initial_count)
+ if (cTicks >= pApic->initial_count)
break;
- NextTS = (uint64_t)pThis->initial_count + 1;
+ NextTS = (uint64_t)pApic->initial_count + 1;
}
- NextTS <<= pThis->count_shift;
- NextTS += pThis->initial_count_load_time;
+ NextTS <<= pApic->count_shift;
+ NextTS += pApic->initial_count_load_time;
/* Try avoid the assertion in TM.cpp... this isn't perfect! */
- if ( NextTS > TMTimerGet(pThis->CTX_SUFF(pTimer))
+ if ( NextTS > TMTimerGet(pApic->CTX_SUFF(pTimer))
|| cTries > 10)
{
- TMTimerSet(pThis->CTX_SUFF(pTimer), NextTS);
- pThis->next_time = NextTS;
- pThis->fTimerArmed = true;
- apicDoFrequencyHinting(pThis);
- Log(("apicTimerSetLvt: ic=%#x sh=%#x nxt=%#llx\n", pThis->initial_count, pThis->count_shift, pThis->next_time));
+ TMTimerSet(pApic->CTX_SUFF(pTimer), NextTS);
+ pApic->next_time = NextTS;
+ pApic->fTimerArmed = true;
+ apicDoFrequencyHinting(pApic);
+ Log(("apicTimerSetLvt: ic=%#x sh=%#x nxt=%#llx\n", pApic->initial_count, pApic->count_shift, pApic->next_time));
break;
}
- STAM_COUNTER_INC(&pThis->StatTimerSetLvtArmRetries);
+ STAM_COUNTER_INC(&pApic->StatTimerSetLvtArmRetries);
}
}
}
else
- STAM_COUNTER_INC(&pThis->StatTimerSetLvtNoRelevantChange);
+ STAM_COUNTER_INC(&pApic->StatTimerSetLvtNoRelevantChange);
}
# ifdef IN_RING3
@@ -1422,37 +1443,39 @@ static void apicTimerSetLvt(APICDeviceInfo *dev, APICState *pThis, uint32_t fNew
*/
static DECLCALLBACK(void) apicTimerCallback(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- APICState *pThis = (APICState *)pvUser;
- Assert(pThis->pTimerR3 == pTimer);
- Assert(pThis->fTimerArmed);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ APICState *pApic = (APICState *)pvUser;
+ Assert(pApic->pTimerR3 == pTimer);
+ Assert(pApic->fTimerArmed);
+ Assert(PDMCritSectIsOwner(pDev->pCritSectR3));
+ Assert(TMTimerIsLockOwner(pTimer));
- if (!(pThis->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
+ if (!(pApic->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
LogFlow(("apic_timer: trigger irq\n"));
- apic_set_irq(dev, pThis, pThis->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE);
+ apic_set_irq(pDev, pApic, pApic->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE);
- if ( (pThis->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC)
- && pThis->initial_count > 0) {
+ if ( (pApic->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC)
+ && pApic->initial_count > 0) {
/* new interval. */
- pThis->next_time += (((uint64_t)pThis->initial_count + 1) << pThis->count_shift);
- TMTimerSet(pThis->CTX_SUFF(pTimer), pThis->next_time);
- pThis->fTimerArmed = true;
- apicDoFrequencyHinting(pThis);
- Log2(("apicTimerCallback: ic=%#x sh=%#x nxt=%#llx\n", pThis->initial_count, pThis->count_shift, pThis->next_time));
+ pApic->next_time += (((uint64_t)pApic->initial_count + 1) << pApic->count_shift);
+ TMTimerSet(pApic->CTX_SUFF(pTimer), pApic->next_time);
+ pApic->fTimerArmed = true;
+ apicDoFrequencyHinting(pApic);
+ Log2(("apicTimerCallback: ic=%#x sh=%#x nxt=%#llx\n", pApic->initial_count, pApic->count_shift, pApic->next_time));
} else {
/* single shot or disabled. */
- pThis->fTimerArmed = false;
- pThis->uHintedCountShift = pThis->uHintedInitialCount = 0;
+ pApic->fTimerArmed = false;
+ pApic->uHintedCountShift = pApic->uHintedInitialCount = 0;
}
} else {
/* masked, do not rearm. */
- pThis->fTimerArmed = false;
- pThis->uHintedCountShift = pThis->uHintedInitialCount = 0;
+ pApic->fTimerArmed = false;
+ pApic->uHintedCountShift = pApic->uHintedInitialCount = 0;
}
}
# endif /* IN_RING3 */
-static uint32_t apic_mem_readl(APICDeviceInfo* dev, APICState *s, RTGCPHYS addr)
+static uint32_t apic_mem_readl(APICDeviceInfo* pDev, APICState *s, RTGCPHYS addr)
{
uint32_t val;
int index;
@@ -1513,7 +1536,7 @@ static uint32_t apic_mem_readl(APICDeviceInfo* dev, APICState *s, RTGCPHYS addr)
val = s->initial_count;
break;
case 0x39:
- val = apic_get_current_count(dev, s);
+ val = apic_get_current_count(pDev, s);
break;
case 0x3e:
val = s->divide_conf;
@@ -1534,93 +1557,6 @@ static uint32_t apic_mem_readl(APICDeviceInfo* dev, APICState *s, RTGCPHYS addr)
return val;
}
-static int apic_mem_writel(APICDeviceInfo* dev, APICState *s, RTGCPHYS addr, uint32_t val)
-{
- int rc = VINF_SUCCESS;
- int index;
-
-#ifdef DEBUG_APIC
- Log(("CPU%d: APIC write: %08x = %08x\n", s->phys_id, (uint32_t)addr, val));
-#endif
-
- index = (addr >> 4) & 0xff;
-
- switch(index) {
- case 0x02:
- s->id = (val >> 24);
- break;
- case 0x03:
- Log(("apic_mem_writel: write to version register; ignored\n"));
- break;
- case 0x08:
- apic_update_tpr(dev, s, val);
- break;
- case 0x09:
- case 0x0a:
- Log(("apic_mem_writel: write to read-only register %d ignored\n", index));
- break;
- case 0x0b: /* EOI */
- apic_eoi(dev, s);
- break;
- case 0x0d:
- s->log_dest = val >> 24;
- break;
- case 0x0e:
- s->dest_mode = val >> 28;
- break;
- case 0x0f:
- s->spurious_vec = val & 0x1ff;
- apic_update_irq(dev, s);
- break;
- case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
- case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
- case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
- case 0x28:
- Log(("apic_mem_writel: write to read-only register %d ignored\n", index));
- break;
-
- case 0x30:
- s->icr[0] = val;
- rc = apic_deliver(dev, s, (s->icr[1] >> 24) & 0xff,
- (s->icr[0] >> 11) & 1,
- (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
- (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);
- break;
- case 0x31:
- s->icr[1] = val;
- break;
- case 0x32 + APIC_LVT_TIMER:
- AssertCompile(APIC_LVT_TIMER == 0);
- apicTimerSetLvt(dev, s, val);
- break;
- case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
- {
- int n = index - 0x32;
- s->lvt[n] = val;
- }
- break;
- case 0x38:
- apicTimerSetInitialCount(dev, s, val);
- break;
- case 0x39:
- Log(("apic_mem_writel: write to read-only register %d ignored\n", index));
- break;
- case 0x3e:
- {
- int v;
- s->divide_conf = val & 0xb;
- v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
- s->count_shift = (v + 1) & 7;
- }
- break;
- default:
- AssertMsgFailed(("apic_mem_writel: unknown index %x\n", index));
- s->esr |= ESR_ILLEGAL_ADDRESS;
- break;
- }
- return rc;
-}
-
#ifdef IN_RING3
static void apic_save(SSMHANDLE* f, void *opaque)
@@ -1715,244 +1651,21 @@ static int apic_load(SSMHANDLE *f, void *opaque, int version_id)
return VINF_SUCCESS; /** @todo darn mess! */
}
-#endif /* IN_RING3 */
-
-static void ioapic_service(IOAPICState *s)
-{
- uint8_t i;
- uint8_t trig_mode;
- uint8_t vector;
- uint8_t delivery_mode;
- uint32_t mask;
- uint64_t entry;
- uint8_t dest;
- uint8_t dest_mode;
- uint8_t polarity;
-
- for (i = 0; i < IOAPIC_NUM_PINS; i++) {
- mask = 1 << i;
- if (s->irr & mask) {
- entry = s->ioredtbl[i];
- if (!(entry & APIC_LVT_MASKED)) {
- trig_mode = ((entry >> 15) & 1);
- dest = entry >> 56;
- dest_mode = (entry >> 11) & 1;
- delivery_mode = (entry >> 8) & 7;
- polarity = (entry >> 13) & 1;
- if (trig_mode == APIC_TRIGGER_EDGE)
- s->irr &= ~mask;
- if (delivery_mode == APIC_DM_EXTINT)
- /* malc: i'm still not so sure about ExtINT delivery */
- {
- AssertMsgFailed(("Delivery mode ExtINT"));
- vector = 0xff; /* incorrect but shuts up gcc. */
- }
- else
- vector = entry & 0xff;
-
- int rc = s->CTX_SUFF(pIoApicHlp)->pfnApicBusDeliver(s->CTX_SUFF(pDevIns),
- dest,
- dest_mode,
- delivery_mode,
- vector,
- polarity,
- trig_mode);
- /* We must be sure that attempts to reschedule in R3
- never get here */
- Assert(rc == VINF_SUCCESS);
- }
- }
- }
-}
-
-
-static void ioapic_set_irq(void *opaque, int vector, int level)
-{
- IOAPICState *s = (IOAPICState*)opaque;
-
- if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
- uint32_t mask = 1 << vector;
- uint64_t entry = s->ioredtbl[vector];
-
- if ((entry >> 15) & 1) {
- /* level triggered */
- if (level) {
- s->irr |= mask;
- ioapic_service(s);
- if ((level & PDM_IRQ_LEVEL_FLIP_FLOP) == PDM_IRQ_LEVEL_FLIP_FLOP) {
- s->irr &= ~mask;
- }
- } else {
- s->irr &= ~mask;
- }
- } else {
- /* edge triggered */
- if (level) {
- s->irr |= mask;
- ioapic_service(s);
- }
- }
- }
-}
-
-static uint32_t ioapic_mem_readl(void *opaque, RTGCPHYS addr)
-{
- IOAPICState *s = (IOAPICState*)opaque;
- int index;
- uint32_t val = 0;
-
- addr &= 0xff;
- if (addr == 0x00) {
- val = s->ioregsel;
- } else if (addr == 0x10) {
- switch (s->ioregsel) {
- case 0x00:
- val = s->id << 24;
- break;
- case 0x01:
- val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */
- break;
- case 0x02:
- val = 0;
- break;
- default:
- index = (s->ioregsel - 0x10) >> 1;
- if (index >= 0 && index < IOAPIC_NUM_PINS) {
- if (s->ioregsel & 1)
- val = s->ioredtbl[index] >> 32;
- else
- val = s->ioredtbl[index] & 0xffffffff;
- }
- }
-#ifdef DEBUG_IOAPIC
- Log(("I/O APIC read: %08x = %08x\n", s->ioregsel, val));
-#endif
- }
- return val;
-}
-
-static void ioapic_mem_writel(void *opaque, RTGCPHYS addr, uint32_t val)
-{
- IOAPICState *s = (IOAPICState*)opaque;
- int index;
-
- addr &= 0xff;
- if (addr == 0x00) {
- s->ioregsel = val;
- return;
- } else if (addr == 0x10) {
-#ifdef DEBUG_IOAPIC
- Log(("I/O APIC write: %08x = %08x\n", s->ioregsel, val));
-#endif
- switch (s->ioregsel) {
- case 0x00:
- s->id = (val >> 24) & 0xff;
- return;
- case 0x01:
- case 0x02:
- return;
- default:
- index = (s->ioregsel - 0x10) >> 1;
- if (index >= 0 && index < IOAPIC_NUM_PINS) {
- if (s->ioregsel & 1) {
- s->ioredtbl[index] &= 0xffffffff;
- s->ioredtbl[index] |= (uint64_t)val << 32;
- } else {
- /* According to IOAPIC spec, vectors should be from 0x10 to 0xfe */
- uint8_t vec = val & 0xff;
- if ((val & APIC_LVT_MASKED) ||
- ((vec >= 0x10) && (vec < 0xff)))
- {
- s->ioredtbl[index] &= ~0xffffffffULL;
- s->ioredtbl[index] |= val;
- }
- else
- {
- /*
- * Linux 2.6 kernels has pretty strange function
- * unlock_ExtINT_logic() which writes
- * absolutely bogus (all 0) value into the vector
- * with pretty vague explanation why.
- * So we just ignore such writes.
- */
- LogRel(("IOAPIC GUEST BUG: bad vector writing %x(sel=%x) to %d\n", val, s->ioregsel, index));
- }
- }
- ioapic_service(s);
- }
- }
- }
-}
-
-#ifdef IN_RING3
-
-static void ioapic_save(SSMHANDLE *f, void *opaque)
-{
- IOAPICState *s = (IOAPICState*)opaque;
- int i;
-
- SSMR3PutU8(f, s->id);
- SSMR3PutU8(f, s->ioregsel);
- for (i = 0; i < IOAPIC_NUM_PINS; i++) {
- SSMR3PutU64(f, s->ioredtbl[i]);
- }
-}
-
-static int ioapic_load(SSMHANDLE *f, void *opaque, int version_id)
-{
- IOAPICState *s = (IOAPICState*)opaque;
- int i;
-
- if (version_id != 1)
- return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
-
- SSMR3GetU8(f, &s->id);
- SSMR3GetU8(f, &s->ioregsel);
- for (i = 0; i < IOAPIC_NUM_PINS; i++) {
- SSMR3GetU64(f, &s->ioredtbl[i]);
- }
- return 0;
-}
-
-static void ioapic_reset(void *opaque)
-{
- IOAPICState *s = (IOAPICState*)opaque;
- PPDMDEVINSR3 pDevIns = s->pDevInsR3;
- PCPDMIOAPICHLPR3 pIoApicHlp = s->pIoApicHlpR3;
- int i;
-
- memset(s, 0, sizeof(*s));
- for(i = 0; i < IOAPIC_NUM_PINS; i++)
- s->ioredtbl[i] = 1 << 16; /* mask LVT */
-
- if (pDevIns)
- {
- s->pDevInsR3 = pDevIns;
- s->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
- s->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
- }
- if (pIoApicHlp)
- {
- s->pIoApicHlpR3 = pIoApicHlp;
- s->pIoApicHlpRC = s->pIoApicHlpR3->pfnGetRCHelpers(pDevIns);
- s->pIoApicHlpR0 = s->pIoApicHlpR3->pfnGetR0Helpers(pDevIns);
- }
-}
#endif /* IN_RING3 */
/* LAPIC */
PDMBOTHCBDECL(int) apicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- APICState *s = getLapic(dev);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ APICState *s = getLapic(pDev);
Log(("CPU%d: apicMMIORead at %llx\n", s->phys_id, (uint64_t)GCPhysAddr));
/** @todo: add LAPIC range validity checks (different LAPICs can theoretically have
different physical addresses, see #3092) */
- STAM_COUNTER_INC(&CTXSUFF(dev->StatMMIORead));
+ STAM_COUNTER_INC(&CTXSUFF(pDev->StatMMIORead));
switch (cb)
{
case 1:
@@ -1982,9 +1695,9 @@ PDMBOTHCBDECL(int) apicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhy
}
#endif
#endif /* experimental */
- APIC_LOCK(dev, VINF_IOM_HC_MMIO_READ);
- *(uint32_t *)pv = apic_mem_readl(dev, s, GCPhysAddr);
- APIC_UNLOCK(dev);
+ APIC_LOCK(pDev, VINF_IOM_HC_MMIO_READ);
+ *(uint32_t *)pv = apic_mem_readl(pDev, s, GCPhysAddr);
+ APIC_UNLOCK(pDev);
break;
}
default:
@@ -1994,17 +1707,17 @@ PDMBOTHCBDECL(int) apicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhy
return VINF_SUCCESS;
}
-PDMBOTHCBDECL(int) apicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+PDMBOTHCBDECL(int) apicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- APICState *s = getLapic(dev);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ APICState *s = getLapic(pDev);
Log(("CPU%d: apicMMIOWrite at %llx\n", s->phys_id, (uint64_t)GCPhysAddr));
/** @todo: add LAPIC range validity checks (multiple LAPICs can theoretically have
different physical addresses, see #3092) */
- STAM_COUNTER_INC(&CTXSUFF(dev->StatMMIOWrite));
+ STAM_COUNTER_INC(&CTXSUFF(pDev->StatMMIOWrite));
switch (cb)
{
case 1:
@@ -2013,13 +1726,9 @@ PDMBOTHCBDECL(int) apicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPh
break;
case 4:
- {
- int rc;
- APIC_LOCK(dev, VINF_IOM_HC_MMIO_WRITE);
- rc = apic_mem_writel(dev, s, GCPhysAddr, *(uint32_t *)pv);
- APIC_UNLOCK(dev);
- return rc;
- }
+ /* It does its own locking. */
+ return apicWriteRegister(pDev, s, (GCPhysAddr >> 4) & 0xff, *(uint32_t const *)pv,
+ VINF_IOM_HC_MMIO_WRITE, false /*fMsr*/);
default:
AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
@@ -2031,75 +1740,75 @@ PDMBOTHCBDECL(int) apicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPh
#ifdef IN_RING3
/* Print a 8-dword LAPIC bit map (256 bits). */
-static void lapicDumpVec(APICDeviceInfo *dev, APICState *lapic, PCDBGFINFOHLP pHlp, unsigned start)
+static void lapicDumpVec(APICDeviceInfo *pDev, APICState *lapic, PCDBGFINFOHLP pHlp, unsigned start)
{
unsigned i;
uint32_t val;
for (i = 0; i < 8; ++i)
{
- val = apic_mem_readl(dev, lapic, start + (i << 4));
+ val = apic_mem_readl(pDev, lapic, start + (i << 4));
pHlp->pfnPrintf(pHlp, "%08X", val);
}
pHlp->pfnPrintf(pHlp, "\n");
}
/* Print basic LAPIC state. */
-static DECLCALLBACK(void) lapicInfoBasic(APICDeviceInfo *dev, APICState *lapic, PCDBGFINFOHLP pHlp)
+static DECLCALLBACK(void) lapicInfoBasic(APICDeviceInfo *pDev, APICState *lapic, PCDBGFINFOHLP pHlp)
{
uint32_t val;
unsigned max_lvt;
pHlp->pfnPrintf(pHlp, "Local APIC at %08X:\n", lapic->apicbase);
- val = apic_mem_readl(dev, lapic, 0x20);
+ val = apic_mem_readl(pDev, lapic, 0x20);
pHlp->pfnPrintf(pHlp, " LAPIC ID : %08X\n", val);
pHlp->pfnPrintf(pHlp, " APIC ID = %02X\n", (val >> 24) & 0xff);
- val = apic_mem_readl(dev, lapic, 0x30);
+ val = apic_mem_readl(pDev, lapic, 0x30);
max_lvt = (val >> 16) & 0xff;
pHlp->pfnPrintf(pHlp, " APIC VER : %08X\n", val);
pHlp->pfnPrintf(pHlp, " version = %02X\n", val & 0xff);
pHlp->pfnPrintf(pHlp, " lvts = %d\n", ((val >> 16) & 0xff) + 1);
- val = apic_mem_readl(dev, lapic, 0x80);
+ val = apic_mem_readl(pDev, lapic, 0x80);
pHlp->pfnPrintf(pHlp, " TPR : %08X\n", val);
pHlp->pfnPrintf(pHlp, " task pri = %d/%d\n", (val >> 4) & 0xf, val & 0xf);
- val = apic_mem_readl(dev, lapic, 0xA0);
+ val = apic_mem_readl(pDev, lapic, 0xA0);
pHlp->pfnPrintf(pHlp, " PPR : %08X\n", val);
pHlp->pfnPrintf(pHlp, " cpu pri = %d/%d\n", (val >> 4) & 0xf, val & 0xf);
- val = apic_mem_readl(dev, lapic, 0xD0);
+ val = apic_mem_readl(pDev, lapic, 0xD0);
pHlp->pfnPrintf(pHlp, " LDR : %08X\n", val);
pHlp->pfnPrintf(pHlp, " log id = %02X\n", (val >> 24) & 0xff);
- val = apic_mem_readl(dev, lapic, 0xE0);
+ val = apic_mem_readl(pDev, lapic, 0xE0);
pHlp->pfnPrintf(pHlp, " DFR : %08X\n", val);
- val = apic_mem_readl(dev, lapic, 0xF0);
+ val = apic_mem_readl(pDev, lapic, 0xF0);
pHlp->pfnPrintf(pHlp, " SVR : %08X\n", val);
pHlp->pfnPrintf(pHlp, " focus = %s\n", val & (1 << 9) ? "check off" : "check on");
pHlp->pfnPrintf(pHlp, " lapic = %s\n", val & (1 << 8) ? "ENABLED" : "DISABLED");
pHlp->pfnPrintf(pHlp, " vector = %02X\n", val & 0xff);
pHlp->pfnPrintf(pHlp, " ISR : ");
- lapicDumpVec(dev, lapic, pHlp, 0x100);
+ lapicDumpVec(pDev, lapic, pHlp, 0x100);
val = get_highest_priority_int(lapic->isr);
pHlp->pfnPrintf(pHlp, " highest = %02X\n", val == ~0U ? 0 : val);
pHlp->pfnPrintf(pHlp, " IRR : ");
- lapicDumpVec(dev, lapic, pHlp, 0x200);
+ lapicDumpVec(pDev, lapic, pHlp, 0x200);
val = get_highest_priority_int(lapic->irr);
pHlp->pfnPrintf(pHlp, " highest = %02X\n", val == ~0U ? 0 : val);
- val = apic_mem_readl(dev, lapic, 0x320);
+ val = apic_mem_readl(pDev, lapic, 0x320);
}
/* Print the more interesting LAPIC LVT entries. */
-static DECLCALLBACK(void) lapicInfoLVT(APICDeviceInfo *dev, APICState *lapic, PCDBGFINFOHLP pHlp)
+static DECLCALLBACK(void) lapicInfoLVT(APICDeviceInfo *pDev, APICState *lapic, PCDBGFINFOHLP pHlp)
{
uint32_t val;
static const char *dmodes[] = { "Fixed ", "Reserved", "SMI", "Reserved",
"NMI", "INIT", "Reserved", "ExtINT" };
- val = apic_mem_readl(dev, lapic, 0x320);
+ val = apic_mem_readl(pDev, lapic, 0x320);
pHlp->pfnPrintf(pHlp, " LVT Timer : %08X\n", val);
pHlp->pfnPrintf(pHlp, " mode = %s\n", val & (1 << 17) ? "periodic" : "one-shot");
pHlp->pfnPrintf(pHlp, " mask = %d\n", (val >> 16) & 1);
pHlp->pfnPrintf(pHlp, " status = %s\n", val & (1 << 12) ? "pending" : "idle");
pHlp->pfnPrintf(pHlp, " vector = %02X\n", val & 0xff);
- val = apic_mem_readl(dev, lapic, 0x350);
+ val = apic_mem_readl(pDev, lapic, 0x350);
pHlp->pfnPrintf(pHlp, " LVT LINT0 : %08X\n", val);
pHlp->pfnPrintf(pHlp, " mask = %d\n", (val >> 16) & 1);
pHlp->pfnPrintf(pHlp, " trigger = %s\n", val & (1 << 15) ? "level" : "edge");
@@ -2108,7 +1817,7 @@ static DECLCALLBACK(void) lapicInfoLVT(APICDeviceInfo *dev, APICState *lapic, P
pHlp->pfnPrintf(pHlp, " status = %s\n", val & (1 << 12) ? "pending" : "idle");
pHlp->pfnPrintf(pHlp, " delivry = %s\n", dmodes[(val >> 8) & 7]);
pHlp->pfnPrintf(pHlp, " vector = %02X\n", val & 0xff);
- val = apic_mem_readl(dev, lapic, 0x360);
+ val = apic_mem_readl(pDev, lapic, 0x360);
pHlp->pfnPrintf(pHlp, " LVT LINT1 : %08X\n", val);
pHlp->pfnPrintf(pHlp, " mask = %d\n", (val >> 16) & 1);
pHlp->pfnPrintf(pHlp, " trigger = %s\n", val & (1 << 15) ? "level" : "edge");
@@ -2120,17 +1829,17 @@ static DECLCALLBACK(void) lapicInfoLVT(APICDeviceInfo *dev, APICState *lapic, P
}
/* Print LAPIC timer state. */
-static DECLCALLBACK(void) lapicInfoTimer(APICDeviceInfo *dev, APICState *lapic, PCDBGFINFOHLP pHlp)
+static DECLCALLBACK(void) lapicInfoTimer(APICDeviceInfo *pDev, APICState *lapic, PCDBGFINFOHLP pHlp)
{
uint32_t val;
unsigned divider;
pHlp->pfnPrintf(pHlp, "Local APIC timer:\n");
- val = apic_mem_readl(dev, lapic, 0x380);
+ val = apic_mem_readl(pDev, lapic, 0x380);
pHlp->pfnPrintf(pHlp, " Initial count : %08X\n", val);
- val = apic_mem_readl(dev, lapic, 0x390);
+ val = apic_mem_readl(pDev, lapic, 0x390);
pHlp->pfnPrintf(pHlp, " Current count : %08X\n", val);
- val = apic_mem_readl(dev, lapic, 0x3E0);
+ val = apic_mem_readl(pDev, lapic, 0x3E0);
pHlp->pfnPrintf(pHlp, " Divide config : %08X\n", val);
divider = ((val >> 1) & 0x04) | (val & 0x03);
pHlp->pfnPrintf(pHlp, " divider = %d\n", divider == 7 ? 1 : 2 << divider);
@@ -2145,22 +1854,22 @@ static DECLCALLBACK(void) lapicInfoTimer(APICDeviceInfo *dev, APICState *lapic,
*/
static DECLCALLBACK(void) lapicInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
APICState *lapic;
- lapic = getLapic(dev);
+ lapic = getLapic(pDev);
if (pszArgs == NULL || !strcmp(pszArgs, "basic"))
{
- lapicInfoBasic(dev, lapic, pHlp);
+ lapicInfoBasic(pDev, lapic, pHlp);
}
else if (!strcmp(pszArgs, "lvt"))
{
- lapicInfoLVT(dev, lapic, pHlp);
+ lapicInfoLVT(pDev, lapic, pHlp);
}
else if (!strcmp(pszArgs, "timer"))
{
- lapicInfoTimer(dev, lapic, pHlp);
+ lapicInfoTimer(pDev, lapic, pHlp);
}
else
{
@@ -2173,11 +1882,11 @@ static DECLCALLBACK(void) lapicInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, cons
*/
static DECLCALLBACK(int) apicLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
{
- APICDeviceInfo *pThis = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- SSMR3PutU32( pSSM, pThis->cCpus);
- SSMR3PutBool(pSSM, pThis->fIoApic);
- SSMR3PutU32( pSSM, pThis->enmVersion);
+ SSMR3PutU32( pSSM, pDev->cCpus);
+ SSMR3PutBool(pSSM, pDev->fIoApic);
+ SSMR3PutU32( pSSM, pDev->enmVersion);
AssertCompile(PDMAPICVERSION_APIC == 2);
return VINF_SSM_DONT_CALL_AGAIN;
@@ -2188,13 +1897,13 @@ static DECLCALLBACK(int) apicLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint3
*/
static DECLCALLBACK(int) apicSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
/* config */
apicLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
/* save all APICs data, @todo: is it correct? */
- foreach_apic(dev, 0xffffffff, apic_save(pSSM, apic));
+ foreach_apic(pDev, 0xffffffff, apic_save(pSSM, apic));
return VINF_SUCCESS;
}
@@ -2204,7 +1913,7 @@ static DECLCALLBACK(int) apicSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
*/
static DECLCALLBACK(int) apicLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
{
- APICDeviceInfo *pThis = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
if ( uVersion != APIC_SAVED_STATE_VERSION
&& uVersion != APIC_SAVED_STATE_VERSION_VBOX_30
@@ -2215,31 +1924,31 @@ static DECLCALLBACK(int) apicLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint3
if (uVersion > APIC_SAVED_STATE_VERSION_VBOX_30) {
uint32_t cCpus;
int rc = SSMR3GetU32(pSSM, &cCpus); AssertRCReturn(rc, rc);
- if (cCpus != pThis->cCpus)
- return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - cCpus: saved=%#x config=%#x"), cCpus, pThis->cCpus);
+ if (cCpus != pDev->cCpus)
+ return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - cCpus: saved=%#x config=%#x"), cCpus, pDev->cCpus);
bool fIoApic;
rc = SSMR3GetBool(pSSM, &fIoApic); AssertRCReturn(rc, rc);
- if (fIoApic != pThis->fIoApic)
- return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - fIoApic: saved=%RTbool config=%RTbool"), fIoApic, pThis->fIoApic);
+ if (fIoApic != pDev->fIoApic)
+ return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - fIoApic: saved=%RTbool config=%RTbool"), fIoApic, pDev->fIoApic);
uint32_t uApicVersion;
rc = SSMR3GetU32(pSSM, &uApicVersion); AssertRCReturn(rc, rc);
- if (uApicVersion != (uint32_t)pThis->enmVersion)
- return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - uApicVersion: saved=%#x config=%#x"), uApicVersion, pThis->enmVersion);
+ if (uApicVersion != (uint32_t)pDev->enmVersion)
+ return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - uApicVersion: saved=%#x config=%#x"), uApicVersion, pDev->enmVersion);
}
if (uPass != SSM_PASS_FINAL)
return VINF_SUCCESS;
/* load all APICs data */ /** @todo: is it correct? */
- APIC_LOCK(pThis, VERR_INTERNAL_ERROR_3);
- foreach_apic(pThis, 0xffffffff,
+ APIC_LOCK(pDev, VERR_INTERNAL_ERROR_3);
+ foreach_apic(pDev, 0xffffffff,
if (apic_load(pSSM, apic, uVersion)) {
AssertFailed();
- APIC_UNLOCK(pThis);
+ APIC_UNLOCK(pDev);
return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
}
);
- APIC_UNLOCK(pThis);
+ APIC_UNLOCK(pDev);
return VINF_SUCCESS;
}
@@ -2248,18 +1957,17 @@ static DECLCALLBACK(int) apicLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint3
*/
static DECLCALLBACK(void) apicReset(PPDMDEVINS pDevIns)
{
- APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- unsigned i;
-
- APIC_LOCK_VOID(dev, VERR_INTERNAL_ERROR);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ TMTimerLock(pDev->paLapicsR3[0].pTimerR3, VERR_IGNORED);
+ APIC_LOCK_VOID(pDev, VERR_IGNORED);
/* Reset all APICs. */
- for (i = 0; i < dev->cCpus; i++) {
- APICState *pApic = &dev->CTX_SUFF(paLapics)[i];
+ for (VMCPUID i = 0; i < pDev->cCpus; i++) {
+ APICState *pApic = &pDev->CTX_SUFF(paLapics)[i];
TMTimerStop(pApic->CTX_SUFF(pTimer));
/* Clear LAPIC state as if an INIT IPI was sent. */
- apic_init_ipi(dev, pApic);
+ apic_init_ipi(pDev, pApic);
/* The IDs are not touched by apic_init_ipi() and must be reset now. */
pApic->arb_id = pApic->id = i;
Assert(pApic->id == pApic->phys_id); /* The two should match again. */
@@ -2269,13 +1977,14 @@ static DECLCALLBACK(void) apicReset(PPDMDEVINS pDevIns)
pApic->apicbase |= MSR_IA32_APICBASE_BSP;
/* Clear any pending APIC interrupt action flag. */
- cpuClearInterrupt(dev, pApic);
+ cpuClearInterrupt(pDev, pApic);
}
/** @todo r=bird: Why is this done everytime, while the constructor first
* checks the CPUID? Who is right? */
- dev->pApicHlpR3->pfnChangeFeature(dev->pDevInsR3, dev->enmVersion);
+ pDev->pApicHlpR3->pfnChangeFeature(pDev->pDevInsR3, pDev->enmVersion);
- APIC_UNLOCK(dev);
+ APIC_UNLOCK(pDev);
+ TMTimerUnlock(pDev->paLapicsR3[0].pTimerR3);
}
/**
@@ -2283,13 +1992,13 @@ static DECLCALLBACK(void) apicReset(PPDMDEVINS pDevIns)
*/
static DECLCALLBACK(void) apicRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
{
- APICDeviceInfo *pThis = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
- pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
- pThis->pApicHlpRC = pThis->pApicHlpR3->pfnGetRCHelpers(pDevIns);
- pThis->paLapicsRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), pThis->paLapicsR3);
- pThis->pCritSectRC = pThis->pApicHlpR3->pfnGetRCCritSect(pDevIns);
- for (uint32_t i = 0; i < pThis->cCpus; i++)
- pThis->paLapicsR3[i].pTimerRC = TMTimerRCPtr(pThis->paLapicsR3[i].pTimerR3);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ pDev->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+ pDev->pApicHlpRC = pDev->pApicHlpR3->pfnGetRCHelpers(pDevIns);
+ pDev->paLapicsRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), pDev->paLapicsR3);
+ pDev->pCritSectRC = pDev->pApicHlpR3->pfnGetRCCritSect(pDevIns);
+ for (uint32_t i = 0; i < pDev->cCpus; i++)
+ pDev->paLapicsR3[i].pTimerRC = TMTimerRCPtr(pDev->paLapicsR3[i].pTimerR3);
}
DECLINLINE(void) initApicData(APICState* apic, uint8_t id)
@@ -2319,7 +2028,7 @@ static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
bool fIoApic;
bool fGCEnabled;
bool fR0Enabled;
- APICDeviceInfo *pThis = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+ APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
uint32_t cCpus;
/*
@@ -2368,26 +2077,31 @@ static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
/*
* Init the data.
*/
- pThis->pDevInsR3 = pDevIns;
- pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
- pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
- pThis->cCpus = cCpus;
- pThis->fIoApic = fIoApic;
+ pDev->pDevInsR3 = pDevIns;
+ pDev->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
+ pDev->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+ pDev->cCpus = cCpus;
+ pDev->fIoApic = fIoApic;
/* Use PDMAPICVERSION_X2APIC to activate x2APIC mode */
- pThis->enmVersion = PDMAPICVERSION_APIC;
+ pDev->enmVersion = PDMAPICVERSION_APIC;
+
+ /* Disable locking in this device. */
+ rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
+ AssertRCReturn(rc, rc);
PVM pVM = PDMDevHlpGetVM(pDevIns);
+
/*
* We are not freeing this memory, as it's automatically released when guest exits.
*/
- rc = MMHyperAlloc(pVM, cCpus * sizeof(APICState), 1, MM_TAG_PDM_DEVICE_USER, (void **)&pThis->paLapicsR3);
+ rc = MMHyperAlloc(pVM, cCpus * sizeof(APICState), 1, MM_TAG_PDM_DEVICE_USER, (void **)&pDev->paLapicsR3);
if (RT_FAILURE(rc))
return VERR_NO_MEMORY;
- pThis->paLapicsR0 = MMHyperR3ToR0(pVM, pThis->paLapicsR3);
- pThis->paLapicsRC = MMHyperR3ToRC(pVM, pThis->paLapicsR3);
+ pDev->paLapicsR0 = MMHyperR3ToR0(pVM, pDev->paLapicsR3);
+ pDev->paLapicsRC = MMHyperR3ToRC(pVM, pDev->paLapicsR3);
for (i = 0; i < cCpus; i++)
- initApicData(&pThis->paLapicsR3[i], i);
+ initApicData(&pDev->paLapicsR3[i], i);
/*
* Register the APIC.
@@ -2450,9 +2164,9 @@ static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
ApicReg.pszLocalInterruptR0 = NULL;
}
- rc = PDMDevHlpAPICRegister(pDevIns, &ApicReg, &pThis->pApicHlpR3);
+ rc = PDMDevHlpAPICRegister(pDevIns, &ApicReg, &pDev->pApicHlpR3);
AssertLogRelRCReturn(rc, rc);
- pThis->pCritSectR3 = pThis->pApicHlpR3->pfnGetR3CritSect(pDevIns);
+ pDev->pCritSectR3 = pDev->pApicHlpR3->pfnGetR3CritSect(pDevIns);
/*
* The the CPUID feature bit.
@@ -2469,7 +2183,7 @@ static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
&& u32Ecx == X86_CPUID_VENDOR_AMD_ECX
&& u32Edx == X86_CPUID_VENDOR_AMD_EDX /* AuthenticAMD */)) {
LogRel(("Activating Local APIC\n"));
- pThis->pApicHlpR3->pfnChangeFeature(pDevIns, pThis->enmVersion);
+ pDev->pApicHlpR3->pfnChangeFeature(pDevIns, pDev->enmVersion);
}
}
@@ -2477,15 +2191,15 @@ static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
* Register the MMIO range.
* @todo: shall reregister, if base changes.
*/
- uint32_t ApicBase = pThis->paLapicsR3[0].apicbase & ~0xfff;
- rc = PDMDevHlpMMIORegister(pDevIns, ApicBase, 0x1000, pThis,
+ uint32_t ApicBase = pDev->paLapicsR3[0].apicbase & ~0xfff;
+ rc = PDMDevHlpMMIORegister(pDevIns, ApicBase, 0x1000, pDev,
apicMMIOWrite, apicMMIORead, NULL, "APIC Memory");
if (RT_FAILURE(rc))
return rc;
if (fGCEnabled) {
- pThis->pApicHlpRC = pThis->pApicHlpR3->pfnGetRCHelpers(pDevIns);
- pThis->pCritSectRC = pThis->pApicHlpR3->pfnGetRCCritSect(pDevIns);
+ pDev->pApicHlpRC = pDev->pApicHlpR3->pfnGetRCHelpers(pDevIns);
+ pDev->pCritSectRC = pDev->pApicHlpR3->pfnGetRCCritSect(pDevIns);
rc = PDMDevHlpMMIORegisterRC(pDevIns, ApicBase, 0x1000, 0,
"apicMMIOWrite", "apicMMIORead", NULL);
@@ -2494,8 +2208,8 @@ static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
}
if (fR0Enabled) {
- pThis->pApicHlpR0 = pThis->pApicHlpR3->pfnGetR0Helpers(pDevIns);
- pThis->pCritSectR0 = pThis->pApicHlpR3->pfnGetR0CritSect(pDevIns);
+ pDev->pApicHlpR0 = pDev->pApicHlpR3->pfnGetR0Helpers(pDevIns);
+ pDev->pCritSectR0 = pDev->pApicHlpR3->pfnGetR0CritSect(pDevIns);
rc = PDMDevHlpMMIORegisterR0(pDevIns, ApicBase, 0x1000, 0,
"apicMMIOWrite", "apicMMIORead", NULL);
@@ -2507,7 +2221,7 @@ static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
* Create the APIC timers.
*/
for (i = 0; i < cCpus; i++) {
- APICState *pApic = &pThis->paLapicsR3[i];
+ APICState *pApic = &pDev->paLapicsR3[i];
pApic->pszDesc = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_USER, "APIC Timer #%u", i);
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicTimerCallback, pApic,
TMTIMER_FLAGS_NO_CRIT_SECT, pApic->pszDesc, &pApic->pTimerR3);
@@ -2515,13 +2229,13 @@ static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
return rc;
pApic->pTimerR0 = TMTimerR0Ptr(pApic->pTimerR3);
pApic->pTimerRC = TMTimerRCPtr(pApic->pTimerR3);
- TMR3TimerSetCritSect(pApic->pTimerR3, pThis->pCritSectR3);
+ TMR3TimerSetCritSect(pApic->pTimerR3, pDev->pCritSectR3);
}
/*
* Saved state.
*/
- rc = PDMDevHlpSSMRegister3(pDevIns, APIC_SAVED_STATE_VERSION, sizeof(*pThis),
+ rc = PDMDevHlpSSMRegister3(pDevIns, APIC_SAVED_STATE_VERSION, sizeof(*pDev),
apicLiveExec, apicSaveExec, apicLoadExec);
if (RT_FAILURE(rc))
return rc;
@@ -2536,13 +2250,13 @@ static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
/*
* Statistics.
*/
- PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMMIOReadGC, STAMTYPE_COUNTER, "/Devices/APIC/MMIOReadGC", STAMUNIT_OCCURENCES, "Number of APIC MMIO reads in GC.");
- PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMMIOReadHC, STAMTYPE_COUNTER, "/Devices/APIC/MMIOReadHC", STAMUNIT_OCCURENCES, "Number of APIC MMIO reads in HC.");
- PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMMIOWriteGC, STAMTYPE_COUNTER, "/Devices/APIC/MMIOWriteGC", STAMUNIT_OCCURENCES, "Number of APIC MMIO writes in GC.");
- PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMMIOWriteHC, STAMTYPE_COUNTER, "/Devices/APIC/MMIOWriteHC", STAMUNIT_OCCURENCES, "Number of APIC MMIO writes in HC.");
- PDMDevHlpSTAMRegister(pDevIns, &pThis->StatClearedActiveIrq,STAMTYPE_COUNTER, "/Devices/APIC/MaskedActiveIRQ", STAMUNIT_OCCURENCES, "Number of cleared irqs.");
+ PDMDevHlpSTAMRegister(pDevIns, &pDev->StatMMIOReadGC, STAMTYPE_COUNTER, "/Devices/APIC/MMIOReadGC", STAMUNIT_OCCURENCES, "Number of APIC MMIO reads in GC.");
+ PDMDevHlpSTAMRegister(pDevIns, &pDev->StatMMIOReadHC, STAMTYPE_COUNTER, "/Devices/APIC/MMIOReadHC", STAMUNIT_OCCURENCES, "Number of APIC MMIO reads in HC.");
+ PDMDevHlpSTAMRegister(pDevIns, &pDev->StatMMIOWriteGC, STAMTYPE_COUNTER, "/Devices/APIC/MMIOWriteGC", STAMUNIT_OCCURENCES, "Number of APIC MMIO writes in GC.");
+ PDMDevHlpSTAMRegister(pDevIns, &pDev->StatMMIOWriteHC, STAMTYPE_COUNTER, "/Devices/APIC/MMIOWriteHC", STAMUNIT_OCCURENCES, "Number of APIC MMIO writes in HC.");
+ PDMDevHlpSTAMRegister(pDevIns, &pDev->StatClearedActiveIrq,STAMTYPE_COUNTER, "/Devices/APIC/MaskedActiveIRQ", STAMUNIT_OCCURENCES, "Number of cleared irqs.");
for (i = 0; i < cCpus; i++) {
- APICState *pApic = &pThis->paLapicsR3[i];
+ APICState *pApic = &pDev->paLapicsR3[i];
PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetInitialCount, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Calls to apicTimerSetInitialCount.", "/Devices/APIC/%u/TimerSetInitialCount", i);
PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetInitialCountArm, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerSetRelative calls.", "/Devices/APIC/%u/TimerSetInitialCount/Arm", i);
PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetInitialCountDisarm, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerStop calls.", "/Devices/APIC/%u/TimerSetInitialCount/Disasm", i);
@@ -2616,359 +2330,5 @@ const PDMDEVREG g_DeviceAPIC =
};
#endif /* IN_RING3 */
-
-
-/* IOAPIC */
-
-PDMBOTHCBDECL(int) ioapicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
-{
- IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
- IOAPIC_LOCK(s, VINF_IOM_HC_MMIO_READ);
-
- STAM_COUNTER_INC(&CTXSUFF(s->StatMMIORead));
- switch (cb) {
- case 1:
- *(uint8_t *)pv = ioapic_mem_readl(s, GCPhysAddr);
- break;
-
- case 2:
- *(uint16_t *)pv = ioapic_mem_readl(s, GCPhysAddr);
- break;
-
- case 4:
- *(uint32_t *)pv = ioapic_mem_readl(s, GCPhysAddr);
- break;
-
- default:
- AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
- IOAPIC_UNLOCK(s);
- return VERR_INTERNAL_ERROR;
- }
- IOAPIC_UNLOCK(s);
- return VINF_SUCCESS;
-}
-
-PDMBOTHCBDECL(int) ioapicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
-{
- IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
-
- STAM_COUNTER_INC(&CTXSUFF(s->StatMMIOWrite));
- switch (cb) {
- case 1:
- case 2:
- case 4:
- IOAPIC_LOCK(s, VINF_IOM_HC_MMIO_WRITE);
- ioapic_mem_writel(s, GCPhysAddr, *(uint32_t *)pv);
- IOAPIC_UNLOCK(s);
- break;
-
- default:
- AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
- return VERR_INTERNAL_ERROR;
- }
- return VINF_SUCCESS;
-}
-
-PDMBOTHCBDECL(void) ioapicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
- /* PDM lock is taken here; @todo add assertion */
- IOAPICState *pThis = PDMINS_2_DATA(pDevIns, IOAPICState *);
- STAM_COUNTER_INC(&pThis->CTXSUFF(StatSetIrq));
- LogFlow(("ioapicSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
- ioapic_set_irq(pThis, iIrq, iLevel);
-}
-
-PDMBOTHCBDECL(void) ioapicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue)
-{
- IOAPICState *pThis = PDMINS_2_DATA(pDevIns, IOAPICState *);
-
- LogFlow(("ioapicSendMsi: Address=%p uValue=%\n", GCAddr, uValue));
-
- uint8_t dest = (GCAddr & VBOX_MSI_ADDR_DEST_ID_MASK) >> VBOX_MSI_ADDR_DEST_ID_SHIFT;
- uint8_t vector_num = (uValue & VBOX_MSI_DATA_VECTOR_MASK) >> VBOX_MSI_DATA_VECTOR_SHIFT;
- uint8_t dest_mode = (GCAddr >> VBOX_MSI_ADDR_DEST_MODE_SHIFT) & 0x1;
- uint8_t trigger_mode = (uValue >> VBOX_MSI_DATA_TRIGGER_SHIFT) & 0x1;
- uint8_t delivery_mode = (uValue >> VBOX_MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
- /**
- * This bit indicates whether the message should be directed to the
- * processor with the lowest interrupt priority among
- * processors that can receive the interrupt, ignored ATM.
- */
- uint8_t redir_hint = (GCAddr >> VBOX_MSI_ADDR_REDIRECTION_SHIFT) & 0x1;
-
- int rc = pThis->CTX_SUFF(pIoApicHlp)->pfnApicBusDeliver(pDevIns,
- dest,
- dest_mode,
- delivery_mode,
- vector_num,
- 0 /* polarity, n/a */,
- trigger_mode);
- /* We must be sure that attempts to reschedule in R3
- never get here */
- Assert(rc == VINF_SUCCESS);
-}
-
-#ifdef IN_RING3
-
-/**
- * Info handler, device version. Dumps I/O APIC state.
- *
- * @param pDevIns Device instance which registered the info.
- * @param pHlp Callback functions for doing output.
- * @param pszArgs Argument string. Optional and specific to the handler.
- */
-static DECLCALLBACK(void) ioapicInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
-{
- IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
- uint32_t val;
- unsigned i;
- unsigned max_redir;
-
- pHlp->pfnPrintf(pHlp, "I/O APIC at %08X:\n", 0xfec00000);
- val = s->id << 24; /* Would be nice to call ioapic_mem_readl() directly, but that's not so simple. */
- pHlp->pfnPrintf(pHlp, " IOAPICID : %08X\n", val);
- pHlp->pfnPrintf(pHlp, " APIC ID = %02X\n", (val >> 24) & 0xff);
- val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16);
- max_redir = (val >> 16) & 0xff;
- pHlp->pfnPrintf(pHlp, " IOAPICVER : %08X\n", val);
- pHlp->pfnPrintf(pHlp, " version = %02X\n", val & 0xff);
- pHlp->pfnPrintf(pHlp, " redirs = %d\n", ((val >> 16) & 0xff) + 1);
- val = 0;
- pHlp->pfnPrintf(pHlp, " IOAPICARB : %08X\n", val);
- pHlp->pfnPrintf(pHlp, " arb ID = %02X\n", (val >> 24) & 0xff);
- Assert(sizeof(s->ioredtbl) / sizeof(s->ioredtbl[0]) > max_redir);
- pHlp->pfnPrintf(pHlp, "I/O redirection table\n");
- pHlp->pfnPrintf(pHlp, " idx dst_mode dst_addr mask trigger rirr polarity dlvr_st dlvr_mode vector\n");
- for (i = 0; i <= max_redir; ++i)
- {
- static const char *dmodes[] = { "Fixed ", "LowPri", "SMI ", "Resrvd",
- "NMI ", "INIT ", "Resrvd", "ExtINT" };
-
- pHlp->pfnPrintf(pHlp, " %02d %s %02X %d %s %d %s %s %s %3d (%016llX)\n",
- i,
- s->ioredtbl[i] & (1 << 11) ? "log " : "phys", /* dest mode */
- (int)(s->ioredtbl[i] >> 56), /* dest addr */
- (int)(s->ioredtbl[i] >> 16) & 1, /* mask */
- s->ioredtbl[i] & (1 << 15) ? "level" : "edge ", /* trigger */
- (int)(s->ioredtbl[i] >> 14) & 1, /* remote IRR */
- s->ioredtbl[i] & (1 << 13) ? "activelo" : "activehi", /* polarity */
- s->ioredtbl[i] & (1 << 12) ? "pend" : "idle", /* delivery status */
- dmodes[(s->ioredtbl[i] >> 8) & 0x07], /* delivery mode */
- (int)s->ioredtbl[i] & 0xff, /* vector */
- s->ioredtbl[i] /* entire register */
- );
- }
-}
-
-/**
- * @copydoc FNSSMDEVSAVEEXEC
- */
-static DECLCALLBACK(int) ioapicSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
-{
- IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
- ioapic_save(pSSM, s);
- return VINF_SUCCESS;
-}
-
-/**
- * @copydoc FNSSMDEVLOADEXEC
- */
-static DECLCALLBACK(int) ioapicLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
-{
- IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
-
- if (ioapic_load(pSSM, s, uVersion)) {
- AssertFailed();
- return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
- }
- Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
-
- return VINF_SUCCESS;
-}
-
-/**
- * @copydoc FNPDMDEVRESET
- */
-static DECLCALLBACK(void) ioapicReset(PPDMDEVINS pDevIns)
-{
- IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
- s->pIoApicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR);
- ioapic_reset(s);
- IOAPIC_UNLOCK(s);
-}
-
-/**
- * @copydoc FNPDMDEVRELOCATE
- */
-static DECLCALLBACK(void) ioapicRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
-{
- IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
- s->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
- s->pIoApicHlpRC = s->pIoApicHlpR3->pfnGetRCHelpers(pDevIns);
-}
-
-/**
- * @copydoc FNPDMDEVCONSTRUCT
- */
-static DECLCALLBACK(int) ioapicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
-{
- IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
- PDMIOAPICREG IoApicReg;
- bool fGCEnabled;
- bool fR0Enabled;
- int rc;
-
- Assert(iInstance == 0);
-
- /*
- * Validate and read the configuration.
- */
- if (!CFGMR3AreValuesValid(pCfg, "GCEnabled\0" "R0Enabled\0"))
- return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
-
- rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fGCEnabled, true);
- if (RT_FAILURE(rc))
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("Configuration error: Failed to query boolean value \"GCEnabled\""));
-
- rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &fR0Enabled, true);
- if (RT_FAILURE(rc))
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("Configuration error: Failed to query boolean value \"R0Enabled\""));
- Log(("IOAPIC: fR0Enabled=%RTbool fGCEnabled=%RTbool\n", fR0Enabled, fGCEnabled));
-
- /*
- * Initialize the state data.
- */
-
- s->pDevInsR3 = pDevIns;
- s->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
- s->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
- ioapic_reset(s);
- s->id = 0;
-
- /*
- * Register the IOAPIC and get helpers.
- */
- IoApicReg.u32Version = PDM_IOAPICREG_VERSION;
- IoApicReg.pfnSetIrqR3 = ioapicSetIrq;
- IoApicReg.pszSetIrqRC = fGCEnabled ? "ioapicSetIrq" : NULL;
- IoApicReg.pszSetIrqR0 = fR0Enabled ? "ioapicSetIrq" : NULL;
- IoApicReg.pfnSendMsiR3 = ioapicSendMsi;
- IoApicReg.pszSendMsiRC = fGCEnabled ? "ioapicSendMsi" : NULL;
- IoApicReg.pszSendMsiR0 = fR0Enabled ? "ioapicSendMsi" : NULL;
-
- rc = PDMDevHlpIOAPICRegister(pDevIns, &IoApicReg, &s->pIoApicHlpR3);
- if (RT_FAILURE(rc))
- {
- AssertMsgFailed(("IOAPICRegister -> %Rrc\n", rc));
- return rc;
- }
-
- /*
- * Register MMIO callbacks and saved state.
- */
- rc = PDMDevHlpMMIORegister(pDevIns, 0xfec00000, 0x1000, s,
- ioapicMMIOWrite, ioapicMMIORead, NULL, "I/O APIC Memory");
- if (RT_FAILURE(rc))
- return rc;
-
- if (fGCEnabled) {
- s->pIoApicHlpRC = s->pIoApicHlpR3->pfnGetRCHelpers(pDevIns);
-
- rc = PDMDevHlpMMIORegisterRC(pDevIns, 0xfec00000, 0x1000, 0,
- "ioapicMMIOWrite", "ioapicMMIORead", NULL);
- if (RT_FAILURE(rc))
- return rc;
- }
-
- if (fR0Enabled) {
- s->pIoApicHlpR0 = s->pIoApicHlpR3->pfnGetR0Helpers(pDevIns);
-
- rc = PDMDevHlpMMIORegisterR0(pDevIns, 0xfec00000, 0x1000, 0,
- "ioapicMMIOWrite", "ioapicMMIORead", NULL);
- if (RT_FAILURE(rc))
- return rc;
- }
-
- rc = PDMDevHlpSSMRegister(pDevIns, 1 /* version */, sizeof(*s), ioapicSaveExec, ioapicLoadExec);
- if (RT_FAILURE(rc))
- return rc;
-
- /*
- * Register debugger info callback.
- */
- PDMDevHlpDBGFInfoRegister(pDevIns, "ioapic", "Display I/O APIC state.", ioapicInfo);
-
-#ifdef VBOX_WITH_STATISTICS
- /*
- * Statistics.
- */
- PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOReadGC, STAMTYPE_COUNTER, "/Devices/IOAPIC/MMIOReadGC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO reads in GC.");
- PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOReadHC, STAMTYPE_COUNTER, "/Devices/IOAPIC/MMIOReadHC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO reads in HC.");
- PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOWriteGC, STAMTYPE_COUNTER, "/Devices/IOAPIC/MMIOWriteGC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO writes in GC.");
- PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOWriteHC, STAMTYPE_COUNTER, "/Devices/IOAPIC/MMIOWriteHC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO writes in HC.");
- PDMDevHlpSTAMRegister(pDevIns, &s->StatSetIrqGC, STAMTYPE_COUNTER, "/Devices/IOAPIC/SetIrqGC", STAMUNIT_OCCURENCES, "Number of IOAPIC SetIrq calls in GC.");
- PDMDevHlpSTAMRegister(pDevIns, &s->StatSetIrqHC, STAMTYPE_COUNTER, "/Devices/IOAPIC/SetIrqHC", STAMUNIT_OCCURENCES, "Number of IOAPIC SetIrq calls in HC.");
-#endif
-
- return VINF_SUCCESS;
-}
-
-/**
- * IO APIC device registration structure.
- */
-const PDMDEVREG g_DeviceIOAPIC =
-{
- /* u32Version */
- PDM_DEVREG_VERSION,
- /* szName */
- "ioapic",
- /* szRCMod */
- "VBoxDD2GC.gc",
- /* szR0Mod */
- "VBoxDD2R0.r0",
- /* pszDescription */
- "I/O Advanced Programmable Interrupt Controller (IO-APIC) Device",
- /* fFlags */
- PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
- /* fClass */
- PDM_DEVREG_CLASS_PIC,
- /* cMaxInstances */
- 1,
- /* cbInstance */
- sizeof(IOAPICState),
- /* pfnConstruct */
- ioapicConstruct,
- /* pfnDestruct */
- NULL,
- /* pfnRelocate */
- ioapicRelocate,
- /* pfnIOCtl */
- NULL,
- /* pfnPowerOn */
- NULL,
- /* pfnReset */
- ioapicReset,
- /* pfnSuspend */
- NULL,
- /* pfnResume */
- NULL,
- /* pfnAttach */
- NULL,
- /* pfnDetach */
- NULL,
- /* pfnQueryInterface. */
- NULL,
- /* pfnInitComplete */
- NULL,
- /* pfnPowerOff */
- NULL,
- /* pfnSoftReset */
- NULL,
- /* u32VersionEnd */
- PDM_DEVREG_VERSION
-};
-
-#endif /* IN_RING3 */
#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
+
diff --git a/src/VBox/Devices/PC/DevApic.h b/src/VBox/Devices/PC/DevApic.h
new file mode 100644
index 000000000..9a87d5fcf
--- /dev/null
+++ b/src/VBox/Devices/PC/DevApic.h
@@ -0,0 +1,77 @@
+/* $Id: DevApic.h 37481 2011-06-15 18:59:27Z vboxsync $ */
+/** @file
+ * Advanced Programmable Interrupt Controller (APIC) Device Definitions.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on:
+ *
+ * apic.c revision 1.5 @@OSETODO
+ *
+ * APIC support
+ *
+ * Copyright (c) 2004-2005 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef ___PC_DevApic_h
+#define ___PC_DevApic_h
+
+/* APIC Local Vector Table */
+#define APIC_LVT_TIMER 0
+#define APIC_LVT_THERMAL 1
+#define APIC_LVT_PERFORM 2
+#define APIC_LVT_LINT0 3
+#define APIC_LVT_LINT1 4
+#define APIC_LVT_ERROR 5
+#define APIC_LVT_NB 6
+
+/* APIC delivery modes */
+#define APIC_DM_FIXED 0
+#define APIC_DM_LOWPRI 1
+#define APIC_DM_SMI 2
+#define APIC_DM_NMI 4
+#define APIC_DM_INIT 5
+#define APIC_DM_SIPI 6
+#define APIC_DM_EXTINT 7
+
+/* APIC destination mode */
+#define APIC_DESTMODE_FLAT 0xf
+#define APIC_DESTMODE_CLUSTER 0x0
+
+#define APIC_TRIGGER_EDGE 0
+#define APIC_TRIGGER_LEVEL 1
+
+#define APIC_LVT_TIMER_PERIODIC (1<<17)
+#define APIC_LVT_MASKED (1<<16)
+#define APIC_LVT_LEVEL_TRIGGER (1<<15)
+#define APIC_LVT_REMOTE_IRR (1<<14)
+#define APIC_INPUT_POLARITY (1<<13)
+#define APIC_SEND_PENDING (1<<12)
+
+#endif
+
diff --git a/src/VBox/Devices/PC/DevDMA.cpp b/src/VBox/Devices/PC/DevDMA.cpp
index c503eb7fc..84e0d806b 100644
--- a/src/VBox/Devices/PC/DevDMA.cpp
+++ b/src/VBox/Devices/PC/DevDMA.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevDMA.cpp $ */
+/* $Id: DevDMA.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
* DevDMA - DMA Controller Device.
*/
@@ -15,7 +15,7 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
* --------------------------------------------------------------------
*
- * This code is based on:
+ * This code is loosely based on:
*
* QEMU DMA emulation
*
@@ -40,15 +40,13 @@
* THE SOFTWARE.
*/
-#ifdef VBOX
-
/*******************************************************************************
* Header Files *
*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_DEV_DMA
#include <VBox/vmm/pdmdev.h>
#include <VBox/err.h>
-#define LOG_GROUP LOG_GROUP_DEFAULT ///@todo LOG_GROUP_DEV_DMA
#include <VBox/log.h>
#include <iprt/assert.h>
#include <iprt/string.h>
@@ -57,829 +55,812 @@
#include <stdlib.h>
#include "VBoxDD.h"
-#include "vl_vbox.h"
-typedef PFNDMATRANSFERHANDLER DMA_transfer_handler;
-
-#else /* !VBOX */
-#include "vl.h"
-#endif
-/* #define DEBUG_DMA */
-
-#ifndef VBOX
-#ifndef __WIN32__
-#define dolog(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#ifdef DEBUG_DMA
-#define lwarn(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#define linfo(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#define ldebug(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#else
-#define lwarn(...)
-#define linfo(...)
-#define ldebug(...)
-#endif
-#else
-#define dolog()
-#define lwarn()
-#define linfo()
-#define ldebug()
-#endif
-#else /* VBOX */
-# ifdef LOG_ENABLED
-# define DEBUG_DMA
- static void DMA_DPRINTF (const char *fmt, ...)
- {
- if (LogIsEnabled ()) {
- va_list args;
- va_start (args, fmt);
- RTLogLogger (NULL, NULL, "dma: %N", fmt, &args); /* %N - nested va_list * type formatting call. */
- va_end (args);
- }
- }
-# else
- DECLINLINE(void) DMA_DPRINTF(const char *pszFmt, ...) {}
-# endif
-
-# define dolog DMA_DPRINTF
-# define lwarn DMA_DPRINTF
-# define linfo DMA_DPRINTF
-# define ldebug DMA_DPRINTF
-
-#endif /* VBOX */
-
-#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
-
-struct dma_regs {
- unsigned int now[2];
- uint16_t base[2];
- uint8_t mode;
- uint8_t page;
- uint8_t pageh;
- uint8_t dack;
- uint8_t eop;
- DMA_transfer_handler transfer_handler;
- void *opaque;
-};
+/* DMA Overview and notes
+ *
+ * Modern PCs typically emulate AT-compatible DMA. The IBM PC/AT used dual
+ * cascaded 8237A DMA controllers, augmented with a 74LS612 memory mapper.
+ * The 8237As are 8-bit parts, only capable of addressing up to 64KB; the
+ * 74LS612 extends addressing to 24 bits. That leads to well known and
+ * inconvenient DMA limitations:
+ * - DMA can only access physical memory under the 16MB line
+ * - DMA transfers must occur within a 64KB/128KB 'page'
+ *
+ * The 16-bit DMA controller added in the PC/AT shifts all 8237A addresses
+ * left by one, including the control registers addresses. The DMA register
+ * offsets (except for the page registers) are therefore "double spaced".
+ *
+ * Due to the address shifting, the DMA controller decodes more addresses
+ * than are usually documented, with aliasing. See the ICH8 datasheet.
+ *
+ * In the IBM PC and PC/XT, DMA channel 0 was used for memory refresh, thus
+ * preventing the use of memory-to-memory DMA transfers (which use channels
+ * 0 and 1). In the PC/AT, memory-to-memory DMA was theoretically possible.
+ * However, it would transfer a single byte at a time, while the CPU can
+ * transfer two (on a 286) or four (on a 386+) bytes at a time. On many
+ * compatibles, memory-to-memory DMA is not even implemented at all, and
+ * therefore has no practical use.
+ *
+ * Auto-init mode is handled implicitly; a device's transfer handler may
+ * return an end count lower than the start count.
+ *
+ * Naming convention: 'channel' refers to a system-wide DMA channel (0-7)
+ * while 'chidx' refers to a DMA channel index within a controller (0-3).
+ *
+ * References:
+ * - IBM Personal Computer AT Technical Reference, 1984
+ * - Intel 8237A-5 Datasheet, 1993
+ * - Frank van Gilluwe, The Undocumented PC, 1994
+ * - OPTi 82C206 Data Book, 1996 (or Chips & Tech 82C206)
+ * - Intel ICH8 Datasheet, 2007
+ */
-#define ADDR 0
-#define COUNT 1
-struct dma_cont {
- uint8_t status;
- uint8_t command;
- uint8_t mask;
- uint8_t flip_flop;
- unsigned int dshift;
- struct dma_regs regs[4];
-};
+/* Saved state versions. */
+#define DMA_SAVESTATE_OLD 1 /* The original saved state. */
+#define DMA_SAVESTATE_CURRENT 2 /* The new and improved saved state. */
+/* State information for a single DMA channel. */
+typedef struct {
+ void *pvUser; /* User specific context. */
+ PFNDMATRANSFERHANDLER pfnXferHandler; /* Transfer handler for channel. */
+ uint16_t u16BaseAddr; /* Base address for transfers. */
+ uint16_t u16BaseCount; /* Base count for transfers. */
+ uint16_t u16CurAddr; /* Current address. */
+ uint16_t u16CurCount; /* Current count. */
+ uint8_t u8Mode; /* Channel mode. */
+} DMAChannel;
+
+/* State information for a DMA controller (DMA8 or DMA16). */
+typedef struct {
+ DMAChannel ChState[4]; /* Per-channel state. */
+ uint8_t au8Page[8]; /* Page registers (A16-A23). */
+ uint8_t au8PageHi[8]; /* High page registers (A24-A31). */
+ uint8_t u8Command; /* Command register. */
+ uint8_t u8Status; /* Status register. */
+ uint8_t u8Mask; /* Mask register. */
+ uint8_t u8Temp; /* Temporary (mem/mem) register. */
+ uint8_t u8ModeCtr; /* Mode register counter for reads. */
+ bool bHiByte; /* Byte pointer (T/F -> high/low). */
+ uint32_t is16bit; /* True for 16-bit DMA. */
+} DMAControl;
+
+/* Complete DMA state information. */
typedef struct {
- PPDMDEVINS pDevIns;
- PCPDMDMACHLP pHlp;
- struct dma_cont dma_controllers[2];
+ PPDMDEVINS pDevIns; /* Device instance. */
+ PCPDMDMACHLP pHlp; /* PDM DMA helpers. */
+ DMAControl DMAC[2]; /* Two DMA controllers. */
} DMAState;
+/* DMA command register bits. */
enum {
- CMD_MEMORY_TO_MEMORY = 0x01,
- CMD_FIXED_ADDRESS = 0x02,
- CMD_BLOCK_CONTROLLER = 0x04,
- CMD_COMPRESSED_TIME = 0x08,
- CMD_CYCLIC_PRIORITY = 0x10,
- CMD_EXTENDED_WRITE = 0x20,
- CMD_LOW_DREQ = 0x40,
- CMD_LOW_DACK = 0x80,
- CMD_NOT_SUPPORTED = CMD_MEMORY_TO_MEMORY | CMD_FIXED_ADDRESS
- | CMD_COMPRESSED_TIME | CMD_CYCLIC_PRIORITY | CMD_EXTENDED_WRITE
- | CMD_LOW_DREQ | CMD_LOW_DACK
+ CMD_MEMTOMEM = 0x01, /* Enable mem-to-mem trasfers. */
+ CMD_ADRHOLD = 0x02, /* Address hold for mem-to-mem. */
+ CMD_DISABLE = 0x04, /* Disable controller. */
+ CMD_COMPRTIME = 0x08, /* Compressed timing. */
+ CMD_ROTPRIO = 0x10, /* Rotating priority. */
+ CMD_EXTWR = 0x20, /* Extended write. */
+ CMD_DREQHI = 0x40, /* DREQ is active high if set. */
+ CMD_DACKHI = 0x80, /* DACK is active high if set. */
+ CMD_UNSUPPORTED = CMD_MEMTOMEM | CMD_ADRHOLD | CMD_COMPRTIME
+ | CMD_EXTWR | CMD_DREQHI | CMD_DACKHI
+};
+/* DMA control register offsets for read accesses. */
+enum {
+ CTL_R_STAT, /* Read status registers. */
+ CTL_R_DMAREQ, /* Read DRQ register. */
+ CTL_R_CMD, /* Read command register. */
+ CTL_R_MODE, /* Read mode register. */
+ CTL_R_SETBPTR, /* Set byte pointer flip-flop. */
+ CTL_R_TEMP, /* Read temporary register. */
+ CTL_R_CLRMODE, /* Clear mode register counter. */
+ CTL_R_MASK /* Read all DRQ mask bits. */
};
-static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0};
+/* DMA control register offsets for read accesses. */
+enum {
+ CTL_W_CMD, /* Write command register. */
+ CTL_W_DMAREQ, /* Write DRQ register. */
+ CTL_W_MASKONE, /* Write single DRQ mask bit. */
+ CTL_W_MODE, /* Write mode register. */
+ CTL_W_CLRBPTR, /* Clear byte pointer flip-flop. */
+ CTL_W_MASTRCLR, /* Master clear. */
+ CTL_W_CLRMASK, /* Clear all DRQ mask bits. */
+ CTL_W_MASK /* Write all DRQ mask bits. */
+};
-static void write_page (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = (struct dma_cont*)opaque;
- int ichan;
+/* Convert DMA channel number (0-7) to controller number (0-1). */
+#define DMACH2C(c) (c < 4 ? 0 : 1)
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel %#x %#x\n", nport, data);
- return;
- }
- d->regs[ichan].page = data;
-}
+static int dmaChannelMap[8] = {-1, 2, 3, 1, -1, -1, -1, 0};
+/* Map a DMA page register offset (0-7) to channel index (0-3). */
+#define DMAPG2CX(c) (dmaChannelMap[c])
-static void write_pageh (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = (struct dma_cont*)opaque;
- int ichan;
+static int dmaMapChannel[4] = {7, 3, 1, 2};
+/* Map a channel index (0-3) to DMA page register offset (0-7). */
+#define DMACX2PG(c) (dmaMapChannel[c])
+/* Map a channel number (0-7) to DMA page register offset (0-7). */
+#define DMACH2PG(c) (dmaMapChannel[c & 3])
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel %#x %#x\n", nport, data);
- return;
- }
- d->regs[ichan].pageh = data;
-}
+/* Test the decrement bit of mode register. */
+#define IS_MODE_DEC(c) ((c) & 0x20)
+/* Test the auto-init bit of mode register. */
+#define IS_MODE_AI(c) ((c) & 0x10)
-static uint32_t read_page (void *opaque, uint32_t nport)
+/* Perform a master clear (reset) on a DMA controller. */
+static void dmaClear(DMAControl *dc)
{
- struct dma_cont *d = (struct dma_cont*)opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel read %#x\n", nport);
- return 0;
- }
- return d->regs[ichan].page;
+ dc->u8Command = 0;
+ dc->u8Status = 0;
+ dc->u8Temp = 0;
+ dc->u8ModeCtr = 0;
+ dc->bHiByte = false;
+ dc->u8Mask = ~0;
}
-static uint32_t read_pageh (void *opaque, uint32_t nport)
+/* Read the byte pointer and flip it. */
+static inline bool dmaReadBytePtr(DMAControl *dc)
{
- struct dma_cont *d = (struct dma_cont*)opaque;
- int ichan;
+ bool bHighByte;
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel read %#x\n", nport);
- return 0;
- }
- return d->regs[ichan].pageh;
+ bHighByte = !!dc->bHiByte;
+ dc->bHiByte ^= 1;
+ return bHighByte;
}
-static inline void init_chan (struct dma_cont *d, int ichan)
-{
- struct dma_regs *r;
-
- r = d->regs + ichan;
- r->now[ADDR] = r->base[ADDR] << d->dshift;
- r->now[COUNT] = 0;
-}
+/* DMA address registers writes and reads. */
-static inline int getff (struct dma_cont *d)
+static DECLCALLBACK(int) dmaWriteAddr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port,
+ uint32_t u32, unsigned cb)
{
- int ff;
-
- ff = d->flip_flop;
- d->flip_flop = !ff;
- return ff;
+ if (cb == 1)
+ {
+ DMAControl *dc = (DMAControl *)pvUser;
+ DMAChannel *ch;
+ int chidx, reg, is_count;
+
+ Assert(!(u32 & ~0xff)); /* Check for garbage in high bits. */
+ reg = (port >> dc->is16bit) & 0x0f;
+ chidx = reg >> 1;
+ is_count = reg & 1;
+ ch = &dc->ChState[chidx];
+ if (dmaReadBytePtr(dc))
+ {
+ /* Write the high byte. */
+ if (is_count)
+ ch->u16BaseCount = RT_MAKE_U16(ch->u16BaseCount, u32);
+ else
+ ch->u16BaseAddr = RT_MAKE_U16(ch->u16BaseAddr, u32);
+
+ ch->u16CurCount = 0;
+ ch->u16CurAddr = ch->u16BaseAddr;
+ }
+ else
+ {
+ /* Write the low byte. */
+ if (is_count)
+ ch->u16BaseCount = RT_MAKE_U16(u32, RT_HIBYTE(ch->u16BaseCount));
+ else
+ ch->u16BaseAddr = RT_MAKE_U16(u32, RT_HIBYTE(ch->u16BaseAddr));
+ }
+ Log2(("dmaWriteAddr: port %#06x, chidx %d, data %#02x\n",
+ port, chidx, u32));
+ }
+ else
+ {
+ /* Likely a guest bug. */
+ Log(("Bad size write to count register %#x (size %d, data %#x)\n",
+ port, cb, u32));
+ }
+ return VINF_SUCCESS;
}
-static uint32_t read_chan (void *opaque, uint32_t nport)
+static DECLCALLBACK(int) dmaReadAddr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port,
+ uint32_t *pu32, unsigned cb)
{
- struct dma_cont *d = (struct dma_cont*)opaque;
- int ichan, nreg, iport, ff, val, dir;
- struct dma_regs *r;
-
- iport = (nport >> d->dshift) & 0x0f;
- ichan = iport >> 1;
- nreg = iport & 1;
- r = d->regs + ichan;
-
- dir = ((r->mode >> 5) & 1) ? -1 : 1;
- ff = getff (d);
- if (nreg)
- val = (r->base[COUNT] << d->dshift) - r->now[COUNT];
- else
- val = r->now[ADDR] + r->now[COUNT] * dir;
+ if (cb == 1)
+ {
+ DMAControl *dc = (DMAControl *)pvUser;
+ DMAChannel *ch;
+ int chidx, reg, val, dir;
+ int bptr;
+
+ reg = (port >> dc->is16bit) & 0x0f;
+ chidx = reg >> 1;
+ ch = &dc->ChState[chidx];
+
+ dir = IS_MODE_DEC(ch->u8Mode) ? -1 : 1;
+ if (reg & 1)
+ val = ch->u16BaseCount - ch->u16CurCount;
+ else
+ val = ch->u16CurAddr + ch->u16CurCount * dir;
- ldebug ("read_chan %#x -> %d\n", iport, val);
- return (val >> (d->dshift + (ff << 3))) & 0xff;
-}
+ bptr = dmaReadBytePtr(dc);
+ *pu32 = RT_LOBYTE(val >> (bptr * 8));
-static void write_chan (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = (struct dma_cont*)opaque;
- int iport, ichan, nreg;
- struct dma_regs *r;
-
- iport = (nport >> d->dshift) & 0x0f;
- ichan = iport >> 1;
- nreg = iport & 1;
- r = d->regs + ichan;
- if (getff (d)) {
- r->base[nreg] = (r->base[nreg] & 0xff) | ((data << 8) & 0xff00);
- init_chan (d, ichan);
- } else {
- r->base[nreg] = (r->base[nreg] & 0xff00) | (data & 0xff);
+ Log(("Count read: port %#06x, reg %#04x, data %#x\n", port, reg, val));
+ return VINF_SUCCESS;
}
+ else
+ return VERR_IOM_IOPORT_UNUSED;
}
-static void write_cont (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = (struct dma_cont*)opaque;
- int iport, ichan = 0;
-
- iport = (nport >> d->dshift) & 0x0f;
- switch (iport) {
- case 0x08: /* command */
- if ((data != 0) && (data & CMD_NOT_SUPPORTED)) {
- dolog ("command %#x not supported\n", data);
- return;
- }
- d->command = data;
- break;
+/* DMA control registers writes and reads. */
- case 0x09:
- ichan = data & 3;
- if (data & 4) {
- d->status |= 1 << (ichan + 4);
- }
- else {
- d->status &= ~(1 << (ichan + 4));
- }
- d->status &= ~(1 << ichan);
- break;
+static DECLCALLBACK(int) dmaWriteCtl(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port,
+ uint32_t u32, unsigned cb)
+{
+ if (cb == 1)
+ {
+ DMAControl *dc = (DMAControl *)pvUser;
+ int chidx = 0;
+ int reg;
+
+ reg = ((port >> dc->is16bit) & 0x0f) - 8;
+ Assert((reg >= CTL_W_CMD && reg <= CTL_W_MASK));
+ Assert(!(u32 & ~0xff)); /* Check for garbage in high bits. */
+
+ switch (reg) {
+ case CTL_W_CMD:
+ /* Unsupported commands are entirely ignored. */
+ if (u32 & CMD_UNSUPPORTED)
+ {
+ Log(("DMA command %#x is not supported, ignoring!\n", u32));
+ break;
+ }
+ dc->u8Command = u32;
+ break;
+ case CTL_W_DMAREQ:
+ chidx = u32 & 3;
+ if (u32 & 4)
+ dc->u8Status |= 1 << (chidx + 4);
+ else
+ dc->u8Status &= ~(1 << (chidx + 4));
+ dc->u8Status &= ~(1 << chidx); /* Clear TC for channel. */
+ break;
+ case CTL_W_MASKONE:
+ chidx = u32 & 3;
+ if (u32 & 4)
+ dc->u8Mask |= 1 << chidx;
+ else
+ dc->u8Mask &= ~(1 << chidx);
+ break;
+ case CTL_W_MODE:
+ {
+ int op, opmode;
- case 0x0a: /* single mask */
- if (data & 4)
- d->mask |= 1 << (data & 3);
- else
- d->mask &= ~(1 << (data & 3));
- break;
+ chidx = u32 & 3;
+ op = (u32 >> 2) & 3;
+ opmode = (u32 >> 6) & 3;
+ Log2(("chidx %d, op %d, %sauto-init, %screment, opmode %d\n",
+ chidx, op, IS_MODE_AI(u32) ? "" : "no ",
+ IS_MODE_DEC(u32) ? "de" : "in", opmode));
- case 0x0b: /* mode */
- {
- ichan = data & 3;
-#ifdef DEBUG_DMA
- {
- int op, ai, dir, opmode;
- op = (data >> 2) & 3;
- ai = (data >> 4) & 1;
- dir = (data >> 5) & 1;
- opmode = (data >> 6) & 3;
-
- linfo ("ichan %d, op %d, ai %d, dir %d, opmode %d\n",
- ichan, op, ai, dir, opmode);
+ dc->ChState[chidx].u8Mode = u32;
+ break;
}
-#endif
- d->regs[ichan].mode = data;
+ case CTL_W_CLRBPTR:
+ dc->bHiByte = false;
+ break;
+ case CTL_W_MASTRCLR:
+ dmaClear(dc);
+ break;
+ case CTL_W_CLRMASK:
+ dc->u8Mask = 0;
+ break;
+ case CTL_W_MASK:
+ dc->u8Mask = u32;
+ break;
+ default:
+ Assert(0);
break;
}
+ Log(("dmaWriteCtl: port %#06x, chidx %d, data %#02x\n",
+ port, chidx, u32));
+ }
+ else
+ {
+ /* Likely a guest bug. */
+ Log(("Bad size write to controller register %#x (size %d, data %#x)\n",
+ port, cb, u32));
+ }
+ return VINF_SUCCESS;
+}
- case 0x0c: /* clear flip flop */
- d->flip_flop = 0;
- break;
-
- case 0x0d: /* reset */
- d->flip_flop = 0;
- d->mask = ~0;
- d->status = 0;
- d->command = 0;
- break;
+static DECLCALLBACK(int) dmaReadCtl(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port,
+ uint32_t *pu32, unsigned cb)
+{
+ if (cb == 1)
+ {
+ DMAControl *dc = (DMAControl *)pvUser;
+ uint8_t val = 0;
+ int reg;
- case 0x0e: /* clear mask for all channels */
- d->mask = 0;
- break;
+ reg = ((port >> dc->is16bit) & 0x0f) - 8;
+ Assert((reg >= CTL_R_STAT && reg <= CTL_R_MASK));
- case 0x0f: /* write mask for all channels */
- d->mask = data;
- break;
+ switch (reg) {
+ case CTL_R_STAT:
+ val = dc->u8Status;
+ dc->u8Status &= 0xf0; /* A read clears all TCs. */
+ break;
+ case CTL_R_DMAREQ:
+ val = (dc->u8Status >> 4) | 0xf0;
+ break;
+ case CTL_R_CMD:
+ val = dc->u8Command;
+ break;
+ case CTL_R_MODE:
+ val = dc->ChState[dc->u8ModeCtr].u8Mode | 3;
+ dc->u8ModeCtr = (dc->u8ModeCtr + 1) & 3;
+ case CTL_R_SETBPTR:
+ dc->bHiByte = true;
+ break;
+ case CTL_R_TEMP:
+ val = dc->u8Temp;
+ break;
+ case CTL_R_CLRMODE:
+ dc->u8ModeCtr = 0;
+ break;
+ case CTL_R_MASK:
+ val = dc->u8Mask;
+ break;
+ default:
+ Assert(0);
+ break;
+ }
- default:
- dolog ("unknown iport %#x\n", iport);
- break;
- }
+ Log(("Ctrl read: port %#06x, reg %#04x, data %#x\n", port, reg, val));
+ *pu32 = val;
-#ifdef DEBUG_DMA
- if (0xc != iport) {
- linfo ("write_cont: nport %#06x, ichan % 2d, val %#06x\n",
- nport, ichan, data);
+ return VINF_SUCCESS;
}
-#endif
+ else
+ return VERR_IOM_IOPORT_UNUSED;
}
-static uint32_t read_cont (void *opaque, uint32_t nport)
+/* DMA page registers. There are 16 R/W page registers for compatibility with
+ * the IBM PC/AT; only some of those registers are used for DMA. The page register
+ * accessible via port 80h may be read to insert small delays or used as a scratch
+ * register by a BIOS.
+ */
+static DECLCALLBACK(int) dmaReadPage(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port,
+ uint32_t *pu32, unsigned cb)
{
- struct dma_cont *d = (struct dma_cont*)opaque;
- int iport, val;
-
- iport = (nport >> d->dshift) & 0x0f;
- switch (iport) {
- case 0x08: /* status */
- val = d->status;
- d->status &= 0xf0;
- break;
- case 0x0f: /* mask */
- val = d->mask;
- break;
- default:
- val = 0;
- break;
- }
+ if (cb == 1)
+ {
+ DMAControl *dc = (DMAControl *)pvUser;
+ int reg;
- ldebug ("read_cont: nport %#06x, iport %#04x val %#x\n", nport, iport, val);
- return val;
+ reg = port & 7;
+ *pu32 = dc->au8Page[reg];
+ Log2(("Read %#x to from page register %#x (channel %d)\n",
+ *pu32, port, DMAPG2CX(reg)));
+ return VINF_SUCCESS;
+ }
+ else
+ return VERR_IOM_IOPORT_UNUSED;
}
-static uint8_t DMA_get_channel_mode (DMAState *s, int nchan)
+static DECLCALLBACK(int) dmaWritePage(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port,
+ uint32_t u32, unsigned cb)
{
- return s->dma_controllers[nchan > 3].regs[nchan & 3].mode;
+ if (cb == 1)
+ {
+ DMAControl *dc = (DMAControl *)pvUser;
+ int reg;
+
+ Assert(!(u32 & ~0xff)); /* Check for garbage in high bits. */
+ reg = port & 7;
+ dc->au8Page[reg] = u32;
+ dc->au8PageHi[reg] = 0; /* Corresponding high page cleared. */
+ Log2(("Wrote %#x to page register %#x (channel %d)\n",
+ u32, port, DMAPG2CX(reg)));
+ }
+ else
+ {
+ /* Likely a guest bug. */
+ Log(("Bad size write to page register %#x (size %d, data %#x)\n",
+ port, cb, u32));
+ }
+ return VINF_SUCCESS;
}
-static void DMA_hold_DREQ (DMAState *s, int nchan)
+/* EISA style high page registers, for extending the DMA addresses to cover
+ * the entire 32-bit address space.
+ */
+static DECLCALLBACK(int) dmaReadHiPage(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port,
+ uint32_t *pu32, unsigned cb)
{
- int ncont, ichan;
+ if (cb == 1)
+ {
+ DMAControl *dc = (DMAControl *)pvUser;
+ int reg;
- ncont = nchan > 3;
- ichan = nchan & 3;
- linfo ("held cont=%d chan=%d\n", ncont, ichan);
- s->dma_controllers[ncont].status |= 1 << (ichan + 4);
+ reg = port & 7;
+ *pu32 = dc->au8PageHi[reg];
+ Log2(("Read %#x to from high page register %#x (channel %d)\n",
+ *pu32, port, DMAPG2CX(reg)));
+ return VINF_SUCCESS;
+ }
+ else
+ return VERR_IOM_IOPORT_UNUSED;
}
-static void DMA_release_DREQ (DMAState *s, int nchan)
+static DECLCALLBACK(int) dmaWriteHiPage(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port,
+ uint32_t u32, unsigned cb)
{
- int ncont, ichan;
+ if (cb == 1)
+ {
+ DMAControl *dc = (DMAControl *)pvUser;
+ int reg;
- ncont = nchan > 3;
- ichan = nchan & 3;
- linfo ("released cont=%d chan=%d\n", ncont, ichan);
- s->dma_controllers[ncont].status &= ~(1 << (ichan + 4));
+ Assert(!(u32 & ~0xff)); /* Check for garbage in high bits. */
+ reg = port & 7;
+ dc->au8PageHi[reg] = u32;
+ Log2(("Wrote %#x to high page register %#x (channel %d)\n",
+ u32, port, DMAPG2CX(reg)));
+ }
+ else
+ {
+ /* Likely a guest bug. */
+ Log(("Bad size write to high page register %#x (size %d, data %#x)\n",
+ port, cb, u32));
+ }
+ return VINF_SUCCESS;
}
-static void channel_run (DMAState *s, int ncont, int ichan)
+/* Perform any pending transfers on a single DMA channel. */
+static void dmaRunChannel(DMAState *s, int ctlidx, int chidx)
{
- int n;
- struct dma_regs *r = &s->dma_controllers[ncont].regs[ichan];
-#ifdef DEBUG_DMA
- int dir, opmode;
+ DMAControl *dc = &s->DMAC[ctlidx];
+ DMAChannel *ch = &dc->ChState[chidx];
+ uint32_t start_cnt, end_cnt;
+ int opmode;
- dir = (r->mode >> 5) & 1;
- opmode = (r->mode >> 6) & 3;
+ opmode = (ch->u8Mode >> 6) & 3;
- if (dir) {
- dolog ("DMA in address decrement mode\n");
- }
- if (opmode != 1) {
- dolog ("DMA not in single mode select %#x\n", opmode);
- }
-#endif
+ Log3(("DMA address %screment, mode %d\n",
+ IS_MODE_DEC(ch->u8Mode) ? "de" : "in",
+ ch->u8Mode >> 6));
- r = s->dma_controllers[ncont].regs + ichan;
- n = r->transfer_handler (s->pDevIns, r->opaque, ichan + (ncont << 2),
- r->now[COUNT], (r->base[COUNT] + 1) << ncont);
- r->now[COUNT] = n;
- ldebug ("dma_pos %d size %d\n", n, (r->base[COUNT] + 1) << ncont);
+ /* Addresses and counts are shifted for 16-bit channels. */
+ start_cnt = ch->u16CurCount << dc->is16bit;
+ end_cnt = ch->pfnXferHandler(s->pDevIns, ch->pvUser, (ctlidx * 4) + chidx,
+ start_cnt, (ch->u16BaseCount + 1) << dc->is16bit);
+ ch->u16CurCount = end_cnt >> dc->is16bit;
+ Log3(("DMA position %d, size %d\n", end_cnt, (ch->u16BaseCount + 1) << dc->is16bit));
}
-static void DMA_run (DMAState *s)
+static bool dmaRun(PPDMDEVINS pDevIns)
{
- struct dma_cont *d;
- int icont, ichan;
-
- d = s->dma_controllers;
+ DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *);
+ DMAControl *dc;
+ int ctlidx, chidx, mask;
- for (icont = 0; icont < 2; icont++, d++) {
- for (ichan = 0; ichan < 4; ichan++) {
- int mask;
+ /* Run all controllers and channels. */
+ for (ctlidx = 0; ctlidx < 2; ++ctlidx)
+ {
+ dc = &s->DMAC[ctlidx];
- mask = 1 << ichan;
+ /* If controller is disabled, don't even bother. */
+ if (dc->u8Command & CMD_DISABLE)
+ continue;
- if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4))))
- channel_run (s, icont, ichan);
+ for (chidx = 0; chidx < 4; ++chidx)
+ {
+ mask = 1 << chidx;
+ if (!(dc->u8Mask & mask) && (dc->u8Status & (mask << 4)))
+ dmaRunChannel(s, ctlidx, chidx);
}
}
+ return 0;
}
-static void DMA_register_channel (DMAState *s, unsigned nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque)
+static void dmaRegister(PPDMDEVINS pDevIns, unsigned channel,
+ PFNDMATRANSFERHANDLER handler, void *pvUser)
{
- struct dma_regs *r;
- int ichan, ncont;
- LogFlow (("DMA_register_channel: s=%p nchan=%d transfer_handler=%p opaque=%p\n",
- s, nchan, transfer_handler, opaque));
+ DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *);
+ DMAChannel *ch = &s->DMAC[DMACH2C(channel)].ChState[channel & 3];
- ncont = nchan > 3;
- ichan = nchan & 3;
+ LogFlow(("dmaRegister: s=%p channel=%u XferHandler=%p pvUser=%p\n",
+ s, channel, handler, pvUser));
- r = s->dma_controllers[ncont].regs + ichan;
- r->transfer_handler = transfer_handler;
- r->opaque = opaque;
+ ch->pfnXferHandler = handler;
+ ch->pvUser = pvUser;
}
-static uint32_t DMA_read_memory (DMAState *s,
- unsigned nchan,
- void *buf,
- uint32_t pos,
- uint32_t len)
+/* Reverse the order of bytes in a memory buffer. */
+static void dmaReverseBuf8(void *buf, unsigned len)
{
- struct dma_regs *r = &s->dma_controllers[nchan > 3].regs[nchan & 3];
- uint32_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
+ uint8_t *pBeg, *pEnd;
+ uint8_t temp;
+
+ pBeg = (uint8_t *)buf;
+ pEnd = pBeg + len - 1;
+ for (len = len / 2; len; --len)
+ {
+ temp = *pBeg;
+ *pBeg++ = *pEnd;
+ *pEnd-- = temp;
+ }
+}
- if (r->mode & 0x20) {
- unsigned i;
- uint8_t *p = (uint8_t*)buf;
+/* Reverse the order of words in a memory buffer. */
+static void dmaReverseBuf16(void *buf, unsigned len)
+{
+ uint16_t *pBeg, *pEnd;
+ uint16_t temp;
-#ifdef VBOX
- PDMDevHlpPhysRead (s->pDevIns, addr - pos - len, buf, len);
-#else
- cpu_physical_memory_read (addr - pos - len, buf, len);
-#endif
- /* What about 16bit transfers? */
- for (i = 0; i < len >> 1; i++) {
- uint8_t b = p[len - i - 1];
- p[i] = b;
- }
+ Assert(!(len & 1));
+ len /= 2; /* Convert to word count. */
+ pBeg = (uint16_t *)buf;
+ pEnd = pBeg + len - 1;
+ for (len = len / 2; len; --len)
+ {
+ temp = *pBeg;
+ *pBeg++ = *pEnd;
+ *pEnd-- = temp;
}
- else
-#ifdef VBOX
- PDMDevHlpPhysRead (s->pDevIns, addr + pos, buf, len);
-#else
- cpu_physical_memory_read (addr + pos, buf, len);
-#endif
- return len;
}
-static uint32_t DMA_write_memory (DMAState *s,
- unsigned nchan,
- const void *buf,
- uint32_t pos,
- uint32_t len)
+static uint32_t dmaReadMemory(PPDMDEVINS pDevIns, unsigned channel,
+ void *buf, uint32_t pos, uint32_t len)
{
- struct dma_regs *r = &s->dma_controllers[nchan > 3].regs[nchan & 3];
- uint32_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
+ DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *);
+ DMAControl *dc = &s->DMAC[DMACH2C(channel)];
+ DMAChannel *ch = &dc->ChState[channel & 3];
+ uint32_t page, pagehi;
+ uint32_t addr;
- if (r->mode & 0x20) {
- unsigned i;
- uint8_t *p = (uint8_t *) buf;
+ LogFlow(("dmaReadMemory: s=%p channel=%u buf=%p pos=%u len=%u\n",
+ s, channel, buf, pos, len));
-#ifdef VBOX
- PDMDevHlpPhysWrite (s->pDevIns, addr - pos - len, buf, len);
-#else
- cpu_physical_memory_write (addr - pos - len, buf, len);
-#endif
- /* What about 16bit transfers? */
- for (i = 0; i < len; i++) {
- uint8_t b = p[len - i - 1];
- p[i] = b;
- }
+ /* Build the address for this transfer. */
+ page = dc->au8Page[DMACH2PG(channel)] & ~dc->is16bit;
+ pagehi = dc->au8PageHi[DMACH2PG(channel)];
+ addr = (pagehi << 24) | (page << 16) | (ch->u16CurAddr << dc->is16bit);
+
+ if (IS_MODE_DEC(ch->u8Mode))
+ {
+ PDMDevHlpPhysRead(s->pDevIns, addr - pos - len, buf, len);
+ if (dc->is16bit)
+ dmaReverseBuf16(buf, len);
+ else
+ dmaReverseBuf8(buf, len);
}
else
-#ifdef VBOX
- PDMDevHlpPhysWrite (s->pDevIns, addr + pos, buf, len);
-#else
- cpu_physical_memory_write (addr + pos, buf, len);
-#endif
+ PDMDevHlpPhysRead(s->pDevIns, addr + pos, buf, len);
return len;
}
-
-#ifndef VBOX
-/* request the emulator to transfer a new DMA memory block ASAP */
-void DMA_schedule(int nchan)
-{
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-#endif
-
-static void dma_reset(void *opaque)
+static uint32_t dmaWriteMemory(PPDMDEVINS pDevIns, unsigned channel,
+ const void *buf, uint32_t pos, uint32_t len)
{
- struct dma_cont *d = (struct dma_cont*)opaque;
- write_cont (d, (0x0d << d->dshift), 0);
-}
+ DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *);
+ DMAControl *dc = &s->DMAC[DMACH2C(channel)];
+ DMAChannel *ch = &dc->ChState[channel & 3];
+ uint32_t page, pagehi;
+ uint32_t addr;
-#ifdef VBOX
-#define IO_READ_PROTO(n) \
-static DECLCALLBACK(int) io_read_##n (PPDMDEVINS pDevIns, \
- void *pvUser, \
- RTIOPORT Port, \
- uint32_t *pu32, \
- unsigned cb)
+ LogFlow(("dmaWriteMemory: s=%p channel=%u buf=%p pos=%u len=%u\n",
+ s, channel, buf, pos, len));
+ /* Build the address for this transfer. */
+ page = dc->au8Page[DMACH2PG(channel)] & ~dc->is16bit;
+ pagehi = dc->au8PageHi[DMACH2PG(channel)];
+ addr = (pagehi << 24) | (page << 16) | (ch->u16CurAddr << dc->is16bit);
-#define IO_WRITE_PROTO(n) \
-static DECLCALLBACK(int) io_write_##n (PPDMDEVINS pDevIns, \
- void *pvUser, \
- RTIOPORT Port, \
- uint32_t u32, \
- unsigned cb)
-
-IO_WRITE_PROTO (chan)
-{
- if (cb == 1) {
- write_chan (pvUser, Port, u32);
- }
-#ifdef PARANOID
- else {
- Log (("Unknown write to %#x of size %d, value %#x\n",
- Port, cb, u32));
- }
+ if (IS_MODE_DEC(ch->u8Mode))
+ {
+ //@todo: This would need a temporary buffer.
+ Assert(0);
+#if 0
+ if (dc->is16bit)
+ dmaReverseBuf16(buf, len);
+ else
+ dmaReverseBuf8(buf, len);
#endif
- return VINF_SUCCESS;
-}
-
-IO_WRITE_PROTO (page)
-{
- if (cb == 1) {
- write_page (pvUser, Port, u32);
- }
-#ifdef PARANOID
- else {
- Log (("Unknown write to %#x of size %d, value %#x\n",
- Port, cb, u32));
+ PDMDevHlpPhysWrite(s->pDevIns, addr - pos - len, buf, len);
}
-#endif
- return VINF_SUCCESS;
-}
+ else
+ PDMDevHlpPhysWrite(s->pDevIns, addr + pos, buf, len);
-IO_WRITE_PROTO (pageh)
-{
- if (cb == 1) {
- write_pageh (pvUser, Port, u32);
- }
-#ifdef PARANOID
- else {
- Log (("Unknown write to %#x of size %d, value %#x\n",
- Port, cb, u32));
- }
-#endif
- return VINF_SUCCESS;
+ return len;
}
-IO_WRITE_PROTO (cont)
+static void dmaSetDREQ(PPDMDEVINS pDevIns, unsigned channel, unsigned level)
{
- if (cb == 1) {
- write_cont (pvUser, Port, u32);
- }
-#ifdef PARANOID
- else {
- Log (("Unknown write to %#x of size %d, value %#x\n",
- Port, cb, u32));
- }
-#endif
- return VINF_SUCCESS;
-}
+ DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *);
+ DMAControl *dc = &s->DMAC[DMACH2C(channel)];
+ int chidx;
-IO_READ_PROTO (chan)
-{
- if (cb == 1) {
- *pu32 = read_chan (pvUser, Port);
- return VINF_SUCCESS;
- }
- else {
- return VERR_IOM_IOPORT_UNUSED;
- }
-}
+ LogFlow(("dmaSetDREQ: s=%p channel=%u level=%u\n", s, channel, level));
-IO_READ_PROTO (page)
-{
- if (cb == 1) {
- *pu32 = read_page (pvUser, Port);
- return VINF_SUCCESS;
- }
- else {
- return VERR_IOM_IOPORT_UNUSED;
- }
+ chidx = channel & 3;
+ if (level)
+ dc->u8Status |= 1 << (chidx + 4);
+ else
+ dc->u8Status &= ~(1 << (chidx + 4));
}
-IO_READ_PROTO (pageh)
+static uint8_t dmaGetChannelMode(PPDMDEVINS pDevIns, unsigned channel)
{
- if (cb == 1) {
- *pu32 = read_pageh (pvUser, Port);
- return VINF_SUCCESS;
- }
- else {
- return VERR_IOM_IOPORT_UNUSED;
- }
-}
+ DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *);
-IO_READ_PROTO (cont)
-{
- if (cb == 1) {
- *pu32 = read_cont (pvUser, Port);
- return VINF_SUCCESS;
- }
- else {
- return VERR_IOM_IOPORT_UNUSED;
- }
-}
-#endif
+ LogFlow(("dmaGetChannelMode: s=%p channel=%u\n", s, channel));
-/* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
-static void dma_init2(DMAState *s, struct dma_cont *d, int base, int dshift,
- int page_base, int pageh_base)
-{
- const static int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
- int i;
-
- d->dshift = dshift;
- for (i = 0; i < 8; i++) {
-#ifdef VBOX
- PDMDevHlpIOPortRegister (s->pDevIns, base + (i << dshift), 1, d,
- io_write_chan, io_read_chan, NULL, NULL, "DMA");
-#else
- register_ioport_write (base + (i << dshift), 1, 1, write_chan, d);
- register_ioport_read (base + (i << dshift), 1, 1, read_chan, d);
-#endif
- }
- for (i = 0; i < LENOFA (page_port_list); i++) {
-#ifdef VBOX
- PDMDevHlpIOPortRegister (s->pDevIns, page_base + page_port_list[i], 1, d,
- io_write_page, io_read_page, NULL, NULL, "DMA Page");
-#else
- register_ioport_write (page_base + page_port_list[i], 1, 1,
- write_page, d);
- register_ioport_read (page_base + page_port_list[i], 1, 1,
- read_page, d);
-#endif
- if (pageh_base >= 0) {
-#ifdef VBOX
- PDMDevHlpIOPortRegister (s->pDevIns, pageh_base + page_port_list[i], 1, d,
- io_write_pageh, io_read_pageh, NULL, NULL, "DMA Page High");
-#else
- register_ioport_write (pageh_base + page_port_list[i], 1, 1,
- write_pageh, d);
- register_ioport_read (pageh_base + page_port_list[i], 1, 1,
- read_pageh, d);
-#endif
- }
- }
- for (i = 0; i < 8; i++) {
-#ifdef VBOX
- PDMDevHlpIOPortRegister (s->pDevIns, base + ((i + 8) << dshift), 1, d,
- io_write_cont, io_read_cont, NULL, NULL, "DMA cont");
-#else
- register_ioport_write (base + ((i + 8) << dshift), 1, 1,
- write_cont, d);
- register_ioport_read (base + ((i + 8) << dshift), 1, 1,
- read_cont, d);
-#endif
- }
-#ifndef VBOX
- qemu_register_reset(dma_reset, d);
-#endif
- dma_reset(d);
+ return s->DMAC[DMACH2C(channel)].ChState[channel & 3].u8Mode;
}
-static void dma_save (QEMUFile *f, void *opaque)
+static void dmaReset(PPDMDEVINS pDevIns)
{
- struct dma_cont *d = (struct dma_cont*)opaque;
- int i;
-
- /* qemu_put_8s (f, &d->status); */
- qemu_put_8s (f, &d->command);
- qemu_put_8s (f, &d->mask);
- qemu_put_8s (f, &d->flip_flop);
- qemu_put_be32s (f, &d->dshift);
-
- for (i = 0; i < 4; ++i) {
- struct dma_regs *r = &d->regs[i];
- qemu_put_be32s (f, &r->now[0]);
- qemu_put_be32s (f, &r->now[1]);
- qemu_put_be16s (f, &r->base[0]);
- qemu_put_be16s (f, &r->base[1]);
- qemu_put_8s (f, &r->mode);
- qemu_put_8s (f, &r->page);
- qemu_put_8s (f, &r->pageh);
- qemu_put_8s (f, &r->dack);
- qemu_put_8s (f, &r->eop);
- }
-}
+ DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *);
-static int dma_load (QEMUFile *f, void *opaque, int version_id)
-{
- struct dma_cont *d = (struct dma_cont*)opaque;
- int i;
-
- if (version_id != 1)
-#ifdef VBOX
- return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
-#else
- return -EINVAL;
-#endif
+ LogFlow(("dmaReset: s=%p\n", s));
- /* qemu_get_8s (f, &d->status); */
- qemu_get_8s (f, &d->command);
- qemu_get_8s (f, &d->mask);
- qemu_get_8s (f, &d->flip_flop);
- qemu_get_be32s (f, &d->dshift);
-
- for (i = 0; i < 4; ++i) {
- struct dma_regs *r = &d->regs[i];
- qemu_get_be32s (f, &r->now[0]);
- qemu_get_be32s (f, &r->now[1]);
- qemu_get_be16s (f, &r->base[0]);
- qemu_get_be16s (f, &r->base[1]);
- qemu_get_8s (f, &r->mode);
- qemu_get_8s (f, &r->page);
- qemu_get_8s (f, &r->pageh);
- qemu_get_8s (f, &r->dack);
- qemu_get_8s (f, &r->eop);
+ /* NB: The page and address registers are unaffected by a reset
+ * and in an undefined state after power-up.
+ */
+ dmaClear(&s->DMAC[0]);
+ dmaClear(&s->DMAC[1]);
+}
+
+/* Register DMA I/O port handlers. */
+static void dmaIORegister(PPDMDEVINS pDevIns, bool bHighPage)
+{
+ DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *);
+ DMAControl *dc8;
+ DMAControl *dc16;
+
+ dc8 = &s->DMAC[0];
+ dc16 = &s->DMAC[1];
+
+ dc8->is16bit = false;
+ dc16->is16bit = true;
+
+ /* Base and current address for each channel. */
+ PDMDevHlpIOPortRegister(s->pDevIns, 0x00, 8, dc8,
+ dmaWriteAddr, dmaReadAddr, NULL, NULL, "DMA8 Address");
+ PDMDevHlpIOPortRegister(s->pDevIns, 0xC0, 16, dc16,
+ dmaWriteAddr, dmaReadAddr, NULL, NULL, "DMA16 Address");
+ /* Control registers for both DMA controllers. */
+ PDMDevHlpIOPortRegister(s->pDevIns, 0x08, 8, dc8,
+ dmaWriteCtl, dmaReadCtl, NULL, NULL, "DMA8 Control");
+ PDMDevHlpIOPortRegister(s->pDevIns, 0xD0, 16, dc16,
+ dmaWriteCtl, dmaReadCtl, NULL, NULL, "DMA16 Control");
+ /* Page registers for each channel (plus a few unused ones). */
+ PDMDevHlpIOPortRegister(s->pDevIns, 0x80, 8, dc8,
+ dmaWritePage, dmaReadPage, NULL, NULL, "DMA8 Page");
+ PDMDevHlpIOPortRegister(s->pDevIns, 0x88, 8, dc16,
+ dmaWritePage, dmaReadPage, NULL, NULL, "DMA16 Page");
+ /* Optional EISA style high page registers (address bits 24-31). */
+ if (bHighPage)
+ {
+ PDMDevHlpIOPortRegister(s->pDevIns, 0x480, 8, dc8,
+ dmaWriteHiPage, dmaReadHiPage, NULL, NULL, "DMA8 Page High");
+ PDMDevHlpIOPortRegister(s->pDevIns, 0x488, 8, dc16,
+ dmaWriteHiPage, dmaReadHiPage, NULL, NULL, "DMA16 Page High");
}
- return 0;
}
-#ifndef VBOX
-void DMA_init (int high_page_enable)
+static void dmaSaveController(PSSMHANDLE pSSMHandle, DMAControl *dc)
{
- dma_init2(&dma_controllers[0], 0x00, 0, 0x80,
- high_page_enable ? 0x480 : -1);
- dma_init2(&dma_controllers[1], 0xc0, 1, 0x88,
- high_page_enable ? 0x488 : -1);
- register_savevm ("dma", 0, 1, dma_save, dma_load, &dma_controllers[0]);
- register_savevm ("dma", 1, 1, dma_save, dma_load, &dma_controllers[1]);
-}
-#endif
+ int chidx;
-#ifdef VBOX
-static bool run_wrapper (PPDMDEVINS pDevIns)
-{
- DMA_run (PDMINS_2_DATA (pDevIns, DMAState *));
- return 0;
-}
+ /* Save controller state... */
+ SSMR3PutU8(pSSMHandle, dc->u8Command);
+ SSMR3PutU8(pSSMHandle, dc->u8Mask);
+ SSMR3PutU8(pSSMHandle, dc->bHiByte);
+ SSMR3PutU32(pSSMHandle, dc->is16bit);
+ SSMR3PutU8(pSSMHandle, dc->u8Status);
+ SSMR3PutU8(pSSMHandle, dc->u8Temp);
+ SSMR3PutU8(pSSMHandle, dc->u8ModeCtr);
+ SSMR3PutMem(pSSMHandle, &dc->au8Page, sizeof(dc->au8Page));
+ SSMR3PutMem(pSSMHandle, &dc->au8PageHi, sizeof(dc->au8PageHi));
-static void register_channel_wrapper (PPDMDEVINS pDevIns,
- unsigned nchan,
- PFNDMATRANSFERHANDLER f,
- void *opaque)
-{
- DMAState *s = PDMINS_2_DATA (pDevIns, DMAState *);
- DMA_register_channel (s, nchan, f, opaque);
-}
+ /* ...and all four of its channels. */
+ for (chidx = 0; chidx < 4; ++chidx)
+ {
+ DMAChannel *ch = &dc->ChState[chidx];
-static uint32_t rd_mem_wrapper (PPDMDEVINS pDevIns,
- unsigned nchan,
- void *buf,
- uint32_t pos,
- uint32_t len)
-{
- DMAState *s = PDMINS_2_DATA (pDevIns, DMAState *);
- return DMA_read_memory (s, nchan, buf, pos, len);
+ SSMR3PutU16(pSSMHandle, ch->u16CurAddr);
+ SSMR3PutU16(pSSMHandle, ch->u16CurCount);
+ SSMR3PutU16(pSSMHandle, ch->u16BaseAddr);
+ SSMR3PutU16(pSSMHandle, ch->u16BaseCount);
+ SSMR3PutU8(pSSMHandle, ch->u8Mode);
+ }
}
-static uint32_t wr_mem_wrapper (PPDMDEVINS pDevIns,
- unsigned nchan,
- const void *buf,
- uint32_t pos,
- uint32_t len)
+static int dmaLoadController(PSSMHANDLE pSSMHandle, DMAControl *dc, int version)
{
- DMAState *s = PDMINS_2_DATA (pDevIns, DMAState *);
- return DMA_write_memory (s, nchan, buf, pos, len);
-}
+ uint8_t u8val;
+ uint32_t u32val;
+ int chidx;
-static void set_DREQ_wrapper (PPDMDEVINS pDevIns,
- unsigned nchan,
- unsigned level)
-{
- DMAState *s = PDMINS_2_DATA (pDevIns, DMAState *);
- if (level) {
- DMA_hold_DREQ (s, nchan);
- }
- else {
- DMA_release_DREQ (s, nchan);
+ SSMR3GetU8(pSSMHandle, &dc->u8Command);
+ SSMR3GetU8(pSSMHandle, &dc->u8Mask);
+ SSMR3GetU8(pSSMHandle, &u8val);
+ dc->bHiByte = !!u8val;
+ SSMR3GetU32(pSSMHandle, &dc->is16bit);
+ if (version > DMA_SAVESTATE_OLD)
+ {
+ SSMR3GetU8(pSSMHandle, &dc->u8Status);
+ SSMR3GetU8(pSSMHandle, &dc->u8Temp);
+ SSMR3GetU8(pSSMHandle, &dc->u8ModeCtr);
+ SSMR3GetMem(pSSMHandle, &dc->au8Page, sizeof(dc->au8Page));
+ SSMR3GetMem(pSSMHandle, &dc->au8PageHi, sizeof(dc->au8PageHi));
}
-}
-static uint8_t get_mode_wrapper (PPDMDEVINS pDevIns, unsigned nchan)
-{
- DMAState *s = PDMINS_2_DATA (pDevIns, DMAState *);
- return DMA_get_channel_mode (s, nchan);
-}
+ for (chidx = 0; chidx < 4; ++chidx)
+ {
+ DMAChannel *ch = &dc->ChState[chidx];
-static void dmaReset (PPDMDEVINS pDevIns)
-{
- DMAState *s = PDMINS_2_DATA (pDevIns, DMAState *);
- dma_reset (&s->dma_controllers[0]);
- dma_reset (&s->dma_controllers[1]);
+ if (version == DMA_SAVESTATE_OLD)
+ {
+ /* Convert from 17-bit to 16-bit format. */
+ SSMR3GetU32(pSSMHandle, &u32val);
+ ch->u16CurAddr = u32val >> dc->is16bit;
+ SSMR3GetU32(pSSMHandle, &u32val);
+ ch->u16CurCount = u32val >> dc->is16bit;
+ }
+ else
+ {
+ SSMR3GetU16(pSSMHandle, &ch->u16CurAddr);
+ SSMR3GetU16(pSSMHandle, &ch->u16CurCount);
+ }
+ SSMR3GetU16(pSSMHandle, &ch->u16BaseAddr);
+ SSMR3GetU16(pSSMHandle, &ch->u16BaseCount);
+ SSMR3GetU8(pSSMHandle, &ch->u8Mode);
+ /* Convert from old save state. */
+ if (version == DMA_SAVESTATE_OLD)
+ {
+ /* Remap page register contents. */
+ SSMR3GetU8(pSSMHandle, &u8val);
+ dc->au8Page[DMACX2PG(chidx)] = u8val;
+ SSMR3GetU8(pSSMHandle, &u8val);
+ dc->au8PageHi[DMACX2PG(chidx)] = u8val;
+ /* Throw away dack, eop. */
+ SSMR3GetU8(pSSMHandle, &u8val);
+ SSMR3GetU8(pSSMHandle, &u8val);
+ }
+ }
+ return 0;
}
static DECLCALLBACK(int) dmaSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
{
- DMAState *s = PDMINS_2_DATA (pDevIns, DMAState *);
- dma_save (pSSMHandle, &s->dma_controllers[0]);
- dma_save (pSSMHandle, &s->dma_controllers[1]);
+ DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *);
+
+ dmaSaveController(pSSMHandle, &s->DMAC[0]);
+ dmaSaveController(pSSMHandle, &s->DMAC[1]);
return VINF_SUCCESS;
}
-static DECLCALLBACK(int) dmaLoadExec (PPDMDEVINS pDevIns,
- PSSMHANDLE pSSMHandle,
- uint32_t uVersion,
- uint32_t uPass)
+static DECLCALLBACK(int) dmaLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle,
+ uint32_t uVersion, uint32_t uPass)
{
- DMAState *s = PDMINS_2_DATA (pDevIns, DMAState *);
+ DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *);
- AssertMsgReturn (uVersion == 1, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
- Assert (uPass == SSM_PASS_FINAL); NOREF(uPass);
+ AssertMsgReturn(uVersion <= DMA_SAVESTATE_CURRENT, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
+ Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
- dma_load (pSSMHandle, &s->dma_controllers[0], uVersion);
- return dma_load (pSSMHandle, &s->dma_controllers[1], uVersion);
+ dmaLoadController(pSSMHandle, &s->DMAC[0], uVersion);
+ return dmaLoadController(pSSMHandle, &s->DMAC[1], uVersion);
}
/**
* @interface_method_impl{PDMDEVREG,pfnConstruct}
*/
-static DECLCALLBACK(int) dmaConstruct(PPDMDEVINS pDevIns,
- int iInstance,
- PCFGMNODE pCfg)
+static DECLCALLBACK(int) dmaConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
{
- DMAState *s = PDMINS_2_DATA (pDevIns, DMAState *);
- bool high_page_enable = 0;
- PDMDMACREG reg;
- int rc;
+ DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *);
+ bool bHighPage = false;
+ PDMDMACREG reg;
+ int rc;
s->pDevIns = pDevIns;
@@ -890,31 +871,28 @@ static DECLCALLBACK(int) dmaConstruct(PPDMDEVINS pDevIns,
return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
#if 0
- rc = CFGMR3QueryBool (pCfg, "HighPageEnable", &high_page_enable);
- if (RT_FAILURE (rc)) {
+ rc = CFGMR3QueryBool(pCfg, "HighPageEnable", &bHighPage);
+ if (RT_FAILURE (rc))
return rc;
- }
#endif
- dma_init2(s, &s->dma_controllers[0], 0x00, 0, 0x80,
- high_page_enable ? 0x480 : -1);
- dma_init2(s, &s->dma_controllers[1], 0xc0, 1, 0x88,
- high_page_enable ? 0x488 : -1);
+ dmaIORegister(pDevIns, bHighPage);
+ dmaReset(pDevIns);
reg.u32Version = PDM_DMACREG_VERSION;
- reg.pfnRun = run_wrapper;
- reg.pfnRegister = register_channel_wrapper;
- reg.pfnReadMemory = rd_mem_wrapper;
- reg.pfnWriteMemory = wr_mem_wrapper;
- reg.pfnSetDREQ = set_DREQ_wrapper;
- reg.pfnGetChannelMode = get_mode_wrapper;
-
- rc = PDMDevHlpDMACRegister (pDevIns, &reg, &s->pHlp);
- if (RT_FAILURE (rc)) {
+ reg.pfnRun = dmaRun;
+ reg.pfnRegister = dmaRegister;
+ reg.pfnReadMemory = dmaReadMemory;
+ reg.pfnWriteMemory = dmaWriteMemory;
+ reg.pfnSetDREQ = dmaSetDREQ;
+ reg.pfnGetChannelMode = dmaGetChannelMode;
+
+ rc = PDMDevHlpDMACRegister(pDevIns, &reg, &s->pHlp);
+ if (RT_FAILURE (rc))
return rc;
- }
- rc = PDMDevHlpSSMRegister (pDevIns, 1 /*uVersion*/, sizeof (*s), dmaSaveExec, dmaLoadExec);
+ rc = PDMDevHlpSSMRegister(pDevIns, DMA_SAVESTATE_CURRENT, sizeof(*s),
+ dmaSaveExec, dmaLoadExec);
if (RT_FAILURE(rc))
return rc;
@@ -975,4 +953,3 @@ const PDMDEVREG g_DeviceDMA =
/* u32VersionEnd */
PDM_DEVREG_VERSION
};
-#endif /* VBOX */
diff --git a/src/VBox/Devices/PC/DevFwCommon.cpp b/src/VBox/Devices/PC/DevFwCommon.cpp
index 40160cf04..583bdcea0 100644
--- a/src/VBox/Devices/PC/DevFwCommon.cpp
+++ b/src/VBox/Devices/PC/DevFwCommon.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevFwCommon.cpp $ */
+/* $Id: DevFwCommon.cpp 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* FwCommon - Shared firmware code (used by DevPcBios & DevEFI).
*/
diff --git a/src/VBox/Devices/PC/DevFwCommon.h b/src/VBox/Devices/PC/DevFwCommon.h
index 239310702..2cf33094c 100644
--- a/src/VBox/Devices/PC/DevFwCommon.h
+++ b/src/VBox/Devices/PC/DevFwCommon.h
@@ -1,4 +1,4 @@
-/* $Id: DevFwCommon.h $ */
+/* $Id: DevFwCommon.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* FwCommon - Shared firmware code, header.
*/
diff --git a/src/VBox/Devices/PC/DevHPET.cpp b/src/VBox/Devices/PC/DevHPET.cpp
index ea3cdb147..c83d55379 100644
--- a/src/VBox/Devices/PC/DevHPET.cpp
+++ b/src/VBox/Devices/PC/DevHPET.cpp
@@ -1,10 +1,10 @@
-/* $Id: DevHPET.cpp $ */
+/* $Id: DevHPET.cpp 37636 2011-06-24 14:59:59Z vboxsync $ */
/** @file
* HPET virtual device - high precision event timer emulation
*/
/*
- * Copyright (C) 2009-2010 Oracle Corporation
+ * Copyright (C) 2009-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;
@@ -20,8 +20,8 @@
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DEV_HPET
#include <VBox/vmm/pdmdev.h>
-#include <VBox/log.h>
#include <VBox/vmm/stam.h>
+#include <VBox/log.h>
#include <iprt/assert.h>
#include <iprt/asm-math.h>
#include <iprt/string.h>
@@ -39,21 +39,24 @@
* - statistics not implemented
* - level-triggered mode not implemented
*/
-/*
- * Base address for MMIO
- */
+
+/** Base address for MMIO. */
#define HPET_BASE 0xfed00000
-/*
- * Number of available timers, cannot be changed without
- * breaking saved states.
+/** The number of timers for PIIX4 / PIIX3. */
+#define HPET_NUM_TIMERS_PIIX 3
+/** The number of timers for ICH9. */
+#define HPET_NUM_TIMERS_ICH9 4
+
+/** HPET clock period for PIIX4 / PIIX3.
+ * 10000000 femtoseconds == 10ns.
*/
-#define HPET_NUM_TIMERS 3
+#define HPET_CLK_PERIOD_PIIX UINT32_C(10000000)
-/*
- * 10000000 femtoseconds == 10ns
+/** HPET clock period for ICH9.
+ * 69841279 femtoseconds == 69.84 ns (1 / 14.31818MHz).
*/
-#define HPET_CLK_PERIOD 10000000UL
+#define HPET_CLK_PERIOD_ICH9 UINT32_C(69841279)
/*
* Femptosecods in nanosecond
@@ -88,26 +91,73 @@
#define HPET_TN_ROUTE 0x010
#define HPET_CFG_WRITE_MASK 0x3
-#define HPET_TN_INT_TYPE (1 << 1)
-#define HPET_TN_ENABLE (1 << 2)
-#define HPET_TN_PERIODIC (1 << 3)
-#define HPET_TN_PERIODIC_CAP (1 << 4)
-#define HPET_TN_SIZE_CAP (1 << 5)
-#define HPET_TN_SETVAL (1 << 6)
-#define HPET_TN_32BIT (1 << 8)
-#define HPET_TN_INT_ROUTE_MASK 0x3e00
-#define HPET_TN_CFG_WRITE_MASK 0x3f4e
+#define HPET_TN_INT_TYPE RT_BIT_64(1)
+#define HPET_TN_ENABLE RT_BIT_64(2)
+#define HPET_TN_PERIODIC RT_BIT_64(3)
+#define HPET_TN_PERIODIC_CAP RT_BIT_64(4)
+#define HPET_TN_SIZE_CAP RT_BIT_64(5)
+#define HPET_TN_SETVAL RT_BIT_64(6)
+#define HPET_TN_32BIT RT_BIT_64(8)
+#define HPET_TN_INT_ROUTE_MASK UINT64_C(0x3e00)
+#define HPET_TN_CFG_WRITE_MASK UINT64_C(0x3e46)
#define HPET_TN_INT_ROUTE_SHIFT 9
#define HPET_TN_INT_ROUTE_CAP_SHIFT 32
#define HPET_TN_CFG_BITS_READONLY_OR_RESERVED 0xffff80b1U
+/** Extract the timer count from the capabilities.
+ * @todo Check if the mask is correct. */
+#define HPET_CAP_GET_TIMERS(a_u32) ( ((a_u32) >> 8) & 0xf )
+
/** The version of the saved state. */
#define HPET_SAVED_STATE_VERSION 2
-
-/* Empty saved state */
+/** Empty saved state */
#define HPET_SAVED_STATE_VERSION_EMPTY 1
+/**
+ * Acquires the HPET lock or returns.
+ */
+#define DEVHPET_LOCK_RETURN(a_pThis, a_rcBusy) \
+ do { \
+ int rcLock = PDMCritSectEnter(&(a_pThis)->csLock, (a_rcBusy)); \
+ if (rcLock != VINF_SUCCESS) \
+ return rcLock; \
+ } while (0)
+
+/**
+ * Releases the HPET lock.
+ */
+#define DEVHPET_UNLOCK(a_pThis) \
+ do { PDMCritSectLeave(&(a_pThis)->csLock); } while (0)
+
+
+/**
+ * Acquires the TM lock and HPET lock, returns on failure.
+ */
+#define DEVHPET_LOCK_BOTH_RETURN(a_pThis, a_rcBusy) \
+ do { \
+ int rcLock = TMTimerLock((a_pThis)->aTimers[0].CTX_SUFF(pTimer), (a_rcBusy)); \
+ if (rcLock != VINF_SUCCESS) \
+ return rcLock; \
+ rcLock = PDMCritSectEnter(&(a_pThis)->csLock, (a_rcBusy)); \
+ if (rcLock != VINF_SUCCESS) \
+ { \
+ TMTimerUnlock((a_pThis)->aTimers[0].CTX_SUFF(pTimer)); \
+ return rcLock; \
+ } \
+ } while (0)
+
+
+/**
+ * Releases the HPET lock and TM lock.
+ */
+#define DEVHPET_UNLOCK_BOTH(a_pThis) \
+ do { \
+ PDMCritSectLeave(&(a_pThis)->csLock); \
+ TMTimerUnlock((a_pThis)->aTimers[0].CTX_SUFF(pTimer)); \
+ } while (0)
+
+
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
@@ -129,24 +179,30 @@ typedef struct HpetTimer
/** Pointer to the instance data - RC Ptr. */
RCPTRTYPE(struct HpetState *) pHpetRC;
- /* timer number*/
- uint8_t u8TimerNumber;
- /* Wrap */
+ /** Timer index. */
+ uint8_t idxTimer;
+ /** Wrap. */
uint8_t u8Wrap;
- /* Alignment */
+ /** Alignment. */
uint32_t alignment0;
- /* Memory-mapped, software visible timer registers */
- /* Configuration/capabilities */
+
+ /** @name Memory-mapped, software visible timer registers.
+ * @{ */
+ /** Configuration/capabilities. */
uint64_t u64Config;
- /* comparator */
+ /** Comparator. */
uint64_t u64Cmp;
- /* FSB route, not supported now */
+ /** FSB route, not supported now. */
uint64_t u64Fsb;
+ /** @} */
- /* Hidden register state */
- /* Last value written to comparator */
+ /** @name Hidden register state.
+ * @{ */
+ /** Last value written to comparator. */
uint64_t u64Period;
+ /** @} */
} HpetTimer;
+AssertCompileMemberAlignment(HpetTimer, u64Config, sizeof(uint64_t));
typedef struct HpetState
{
@@ -165,442 +221,517 @@ typedef struct HpetState
/** The HPET helpers - RC Ptr. */
PCPDMHPETHLPRC pHpetHlpRC;
- /* Timer structures */
- HpetTimer aTimers[HPET_NUM_TIMERS];
+ /** Timer structures. */
+ HpetTimer aTimers[RT_MAX(HPET_NUM_TIMERS_PIIX, HPET_NUM_TIMERS_ICH9)];
- /* Offset realtive to the system clock */
+ /** Offset realtive to the virtual sync clock. */
uint64_t u64HpetOffset;
- /* Memory-mapped, software visible registers */
- /* capabilities */
- uint64_t u64Capabilities;
- /* configuration */
+ /** @name Memory-mapped, software visible registers
+ * @{ */
+ /** Capabilities. */
+ uint32_t u32Capabilities;
+ /** HPET_PERIOD - . */
+ uint32_t u32Period;
+ /** Configuration. */
uint64_t u64HpetConfig;
- /* interrupt status register */
+ /** Interrupt status register. */
uint64_t u64Isr;
- /* main counter */
+ /** Main counter. */
uint64_t u64HpetCounter;
+ /** @} */
- /* Global device lock */
+ /** Global device lock. */
PDMCRITSECT csLock;
+
+ /** If we emulate ICH9 HPET (different frequency & timer count). */
+ bool fIch9;
+ uint8_t padding0[7];
} HpetState;
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
-/*
- * We shall declare MMIO accessors as extern "C" to avoid name mangling
- * and let them be found during R0/RC module init.
- * Maybe PDMBOTHCBDECL macro shall have extern "C" part in it.
- */
-
-RT_C_DECLS_BEGIN
-PDMBOTHCBDECL(int) hpetMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) hpetMMIORead (PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-RT_C_DECLS_END
-
-/*
- * Temporary control to disable locking if problems found
- */
-static const bool fHpetLocking = true;
-
-DECLINLINE(int) hpetLock(HpetState* pThis, int rcBusy)
+DECLINLINE(bool) hpet32bitTimer(HpetTimer *pHpetTimer)
{
- if (!fHpetLocking)
- return VINF_SUCCESS;
+ uint64_t u64Cfg = pHpetTimer->u64Config;
- return PDMCritSectEnter(&pThis->csLock, rcBusy);
+ return ((u64Cfg & HPET_TN_SIZE_CAP) == 0) || ((u64Cfg & HPET_TN_32BIT) != 0);
}
-DECLINLINE(void) hpetUnlock(HpetState* pThis)
+DECLINLINE(uint64_t) hpetInvalidValue(HpetTimer *pHpetTimer)
{
- if (!fHpetLocking)
- return;
-
- PDMCritSectLeave(&pThis->csLock);
+ return hpet32bitTimer(pHpetTimer) ? UINT32_MAX : UINT64_MAX;
}
-static uint32_t hpetTimeAfter32(uint64_t a, uint64_t b)
+DECLINLINE(uint32_t) hpetTimeAfter32(uint64_t a, uint64_t b)
{
return ((int32_t)(b) - (int32_t)(a) <= 0);
}
-static uint32_t hpetTimeAfter64(uint64_t a, uint64_t b)
+DECLINLINE(uint32_t) hpetTimeAfter64(uint64_t a, uint64_t b)
{
return ((int64_t)(b) - (int64_t)(a) <= 0);
}
-static uint64_t hpetTicksToNs(uint64_t value)
+DECLINLINE(uint64_t) hpetTicksToNs(HpetState *pThis, uint64_t value)
{
- return (ASMMultU64ByU32DivByU32(value, HPET_CLK_PERIOD, FS_PER_NS));
+ return ASMMultU64ByU32DivByU32(value, pThis->u32Period, FS_PER_NS);
}
-static uint64_t nsToHpetTicks(uint64_t u64Value)
+DECLINLINE(uint64_t) nsToHpetTicks(HpetState const *pThis, uint64_t u64Value)
{
- return (ASMMultU64ByU32DivByU32(u64Value, FS_PER_NS, HPET_CLK_PERIOD));
+ return ASMMultU64ByU32DivByU32(u64Value, FS_PER_NS, pThis->u32Period);
}
-static uint64_t hpetGetTicks(HpetState* pThis)
+DECLINLINE(uint64_t) hpetGetTicks(HpetState const *pThis)
{
/*
* We can use any timer to get current time, they all go
* with the same speed.
*/
- return nsToHpetTicks(TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer)) +
- pThis->u64HpetOffset);
+ return nsToHpetTicks(pThis,
+ TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer))
+ + pThis->u64HpetOffset);
}
-static uint64_t hpetUpdateMasked(uint64_t u64NewValue,
- uint64_t u64OldValue,
- uint64_t u64Mask)
+DECLINLINE(uint64_t) hpetUpdateMasked(uint64_t u64NewValue,
+ uint64_t u64OldValue,
+ uint64_t u64Mask)
{
u64NewValue &= u64Mask;
u64NewValue |= (u64OldValue & ~u64Mask);
return u64NewValue;
}
-static bool hpetBitJustSet(uint64_t u64OldValue,
- uint64_t u64NewValue,
- uint64_t u64Mask)
+DECLINLINE(bool) hpetBitJustSet(uint64_t u64OldValue,
+ uint64_t u64NewValue,
+ uint64_t u64Mask)
{
- return (!(u64OldValue & u64Mask) && !!(u64NewValue & u64Mask));
+ return !(u64OldValue & u64Mask)
+ && !!(u64NewValue & u64Mask);
}
-static bool hpetBitJustCleared(uint64_t u64OldValue,
- uint64_t u64NewValue,
- uint64_t u64Mask)
+DECLINLINE(bool) hpetBitJustCleared(uint64_t u64OldValue,
+ uint64_t u64NewValue,
+ uint64_t u64Mask)
{
- return (!!(u64OldValue & u64Mask) && !(u64NewValue & u64Mask));
+ return !!(u64OldValue & u64Mask)
+ && !(u64NewValue & u64Mask);
}
-DECLINLINE(uint64_t) hpetComputeDiff(HpetTimer* pTimer,
+DECLINLINE(uint64_t) hpetComputeDiff(HpetTimer *pHpetTimer,
uint64_t u64Now)
{
- if (pTimer->u64Config & HPET_TN_32BIT)
+ if (hpet32bitTimer(pHpetTimer))
{
uint32_t u32Diff;
- u32Diff = (uint32_t)pTimer->u64Cmp - (uint32_t)u64Now;
+ u32Diff = (uint32_t)pHpetTimer->u64Cmp - (uint32_t)u64Now;
u32Diff = ((int32_t)u32Diff > 0) ? u32Diff : (uint32_t)0;
return (uint64_t)u32Diff;
- } else {
+ }
+ else
+ {
uint64_t u64Diff;
- u64Diff = pTimer->u64Cmp - u64Now;
+ u64Diff = pHpetTimer->u64Cmp - u64Now;
u64Diff = ((int64_t)u64Diff > 0) ? u64Diff : (uint64_t)0;
return u64Diff;
}
}
-static void hpetAdjustComparator(HpetTimer* pTimer,
- uint64_t u64Now)
+static void hpetAdjustComparator(HpetTimer *pHpetTimer, uint64_t u64Now)
{
- uint64_t u64Period = pTimer->u64Period;
- if ((pTimer->u64Config & HPET_TN_PERIODIC) && (u64Period != 0))
+ uint64_t u64Period = pHpetTimer->u64Period;
+ if ( (pHpetTimer->u64Config & HPET_TN_PERIODIC)
+ && u64Period != 0)
{
/* While loop is suboptimal */
- if (pTimer->u64Config & HPET_TN_32BIT)
+ if (hpet32bitTimer(pHpetTimer))
{
- while (hpetTimeAfter32(u64Now, pTimer->u64Cmp))
- pTimer->u64Cmp = (uint32_t)(pTimer->u64Cmp + u64Period);
+ while (hpetTimeAfter32(u64Now, pHpetTimer->u64Cmp))
+ pHpetTimer->u64Cmp = (uint32_t)(pHpetTimer->u64Cmp + u64Period);
}
else
{
- while (hpetTimeAfter64(u64Now, pTimer->u64Cmp))
- pTimer->u64Cmp += u64Period;
+ while (hpetTimeAfter64(u64Now, pHpetTimer->u64Cmp))
+ pHpetTimer->u64Cmp += u64Period;
}
}
}
-static void hpetProgramTimer(HpetTimer *pTimer)
+
+/**
+ * Sets the frequency hint if it's a periodic timer.
+ *
+ * @param pThis The HPET state.
+ * @param pHpetTimer The timer.
+ */
+DECLINLINE(void) hpetTimerSetFrequencyHint(HpetState *pThis, HpetTimer *pHpetTimer)
{
- uint64_t u64Diff;
- uint32_t u32TillWrap;
- uint64_t u64Ticks = hpetGetTicks(pTimer->CTX_SUFF(pHpet));
+ if (pHpetTimer->u64Config & HPET_TN_PERIODIC)
+ {
+ uint64_t const u64Period = pHpetTimer->u64Period;
+ uint32_t const u32Freq = pThis->u32Period;
+ if (u64Period > 0 && u64Period < u32Freq)
+ TMTimerSetFrequencyHint(pHpetTimer->CTX_SUFF(pTimer), u32Freq / (uint32_t)u64Period);
+ }
+}
+
+static void hpetProgramTimer(HpetTimer *pHpetTimer)
+{
/* no wrapping on new timers */
- pTimer->u8Wrap = 0;
+ pHpetTimer->u8Wrap = 0;
- hpetAdjustComparator(pTimer, u64Ticks);
+ uint64_t u64Ticks = hpetGetTicks(pHpetTimer->CTX_SUFF(pHpet));
+ hpetAdjustComparator(pHpetTimer, u64Ticks);
- u64Diff = hpetComputeDiff(pTimer, u64Ticks);
+ uint64_t u64Diff = hpetComputeDiff(pHpetTimer, u64Ticks);
- /* Spec says in one-shot 32-bit mode, generate an interrupt when
+ /*
+ * HPET spec says in one-shot 32-bit mode, generate an interrupt when
* counter wraps in addition to an interrupt with comparator match.
*/
- if ((pTimer->u64Config & HPET_TN_32BIT) && !(pTimer->u64Config & HPET_TN_PERIODIC))
+ if ( hpet32bitTimer(pHpetTimer)
+ && !(pHpetTimer->u64Config & HPET_TN_PERIODIC))
{
- u32TillWrap = 0xffffffff - (uint32_t)u64Ticks + 1;
+ uint32_t u32TillWrap = 0xffffffff - (uint32_t)u64Ticks + 1;
if (u32TillWrap < (uint32_t)u64Diff)
{
+ Log(("wrap on timer %d: till=%u ticks=%lld diff64=%lld\n",
+ pHpetTimer->idxTimer, u32TillWrap, u64Ticks, u64Diff));
u64Diff = u32TillWrap;
- pTimer->u8Wrap = 1;
+ pHpetTimer->u8Wrap = 1;
}
}
- /* Avoid killing VM with interrupts */
-#if 1
- /* @todo: HACK, rethink, may have negative impact on the guest */
+ /*
+ * HACK ALERT! Avoid killing VM with interrupts.
+ */
+#if 1 /** @todo: HACK, rethink, may have negative impact on the guest */
if (u64Diff == 0)
u64Diff = 100000; /* 1 millisecond */
#endif
- Log4(("HPET: next IRQ in %lld ticks (%lld ns)\n", u64Diff, hpetTicksToNs(u64Diff)));
-
- TMTimerSetNano(pTimer->CTX_SUFF(pTimer), hpetTicksToNs(u64Diff));
+ Log4(("HPET: next IRQ in %lld ticks (%lld ns)\n", u64Diff, hpetTicksToNs(pHpetTimer->CTX_SUFF(pHpet), u64Diff)));
+ TMTimerSetNano(pHpetTimer->CTX_SUFF(pTimer), hpetTicksToNs(pHpetTimer->CTX_SUFF(pHpet), u64Diff));
+ hpetTimerSetFrequencyHint(pHpetTimer->CTX_SUFF(pHpet), pHpetTimer);
}
-static uint32_t getTimerIrq(struct HpetTimer *pTimer)
-{
- /*
- * Per spec, in legacy mode HPET timers wired as:
- * timer 0: IRQ0 for PIC and IRQ2 for APIC
- * timer 1: IRQ8 for both PIC and APIC
- *
- * ISA IRQ delivery logic will take care of correct delivery
- * to the different ICs.
- */
- if ((pTimer->u8TimerNumber <= 1) &&
- (pTimer->CTX_SUFF(pHpet)->u64HpetConfig & HPET_CFG_LEGACY))
- return (pTimer->u8TimerNumber == 0) ? 0 : 8;
- else
- return (pTimer->u64Config & HPET_TN_INT_ROUTE_MASK) >> HPET_TN_INT_ROUTE_SHIFT;
-}
-static int hpetTimerRegRead32(HpetState* pThis,
- uint32_t iTimerNo,
- uint32_t iTimerReg,
- uint32_t * pValue)
+/* -=-=-=-=-=- Timer register accesses -=-=-=-=-=- */
+
+
+/**
+ * Reads a HPET timer register.
+ *
+ * @returns VBox strict status code.
+ * @param pThis The HPET instance.
+ * @param iTimerNo The timer index.
+ * @param iTimerReg The index of the timer register to read.
+ * @param pu32Value Where to return the register value.
+ *
+ * @remarks ASSUMES the caller does holds the HPET lock.
+ */
+static int hpetTimerRegRead32(HpetState const *pThis, uint32_t iTimerNo, uint32_t iTimerReg, uint32_t *pu32Value)
{
- HpetTimer *pTimer;
+ Assert(PDMCritSectIsOwner(&pThis->csLock));
- if (iTimerNo >= HPET_NUM_TIMERS)
+ if (iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities))
{
- LogRel(("HPET: using timer above configured range: %d\n", iTimerNo));
+ static unsigned s_cOccurences = 0;
+ if (s_cOccurences++ < 10)
+ LogRel(("HPET: using timer above configured range: %d\n", iTimerNo));
+ *pu32Value = 0;
return VINF_SUCCESS;
}
- pTimer = &pThis->aTimers[iTimerNo];
-
+ HpetTimer const *pHpetTimer = &pThis->aTimers[iTimerNo];
+ uint32_t u32Value;
switch (iTimerReg)
{
case HPET_TN_CFG:
- Log(("read HPET_TN_CFG on %d\n", pTimer->u8TimerNumber));
- *pValue = (uint32_t)(pTimer->u64Config);
+ u32Value = (uint32_t)pHpetTimer->u64Config;
+ Log(("read HPET_TN_CFG on %d: %#x\n", iTimerNo, u32Value));
break;
+
case HPET_TN_CFG + 4:
- Log(("read HPET_TN_CFG+4 on %d\n", pTimer->u8TimerNumber));
- *pValue = (uint32_t)(pTimer->u64Config >> 32);
+ u32Value = (uint32_t)(pHpetTimer->u64Config >> 32);
+ Log(("read HPET_TN_CFG+4 on %d: %#x\n", iTimerNo, u32Value));
break;
+
case HPET_TN_CMP:
- Log(("read HPET_TN_CMP on %d, cmp=%llx\n", pTimer->u8TimerNumber, pTimer->u64Cmp));
- *pValue = (uint32_t)(pTimer->u64Cmp);
+ u32Value = (uint32_t)pHpetTimer->u64Cmp;
+ Log(("read HPET_TN_CMP on %d: %#x (%#llx)\n", pHpetTimer->idxTimer, u32Value, pHpetTimer->u64Cmp));
break;
+
case HPET_TN_CMP + 4:
- Log(("read HPET_TN_CMP+4 on %d, cmp=%llx\n", pTimer->u8TimerNumber, pTimer->u64Cmp));
- *pValue = (uint32_t)(pTimer->u64Cmp >> 32);
+ u32Value = (uint32_t)(pHpetTimer->u64Cmp >> 32);
+ Log(("read HPET_TN_CMP+4 on %d: %#x (%#llx)\n", pHpetTimer->idxTimer, u32Value, pHpetTimer->u64Cmp));
break;
+
case HPET_TN_ROUTE:
- Log(("read HPET_TN_ROUTE on %d\n", pTimer->u8TimerNumber));
- *pValue = (uint32_t)(pTimer->u64Fsb >> 32);
- break;
- default:
- LogRel(("invalid HPET register read %d on %d\n", iTimerReg, pTimer->u8TimerNumber));
+ u32Value = (uint32_t)(pHpetTimer->u64Fsb >> 32); /** @todo Looks wrong, but since it's not supported, who cares. */
+ Log(("read HPET_TN_ROUTE on %d: %#x\n", iTimerNo, u32Value));
break;
- }
- return VINF_SUCCESS;
-}
-
-static int hpetConfigRegRead32(HpetState* pThis,
- uint32_t iIndex,
- uint32_t *pValue)
-{
- switch (iIndex)
- {
- case HPET_ID:
- Log(("read HPET_ID\n"));
- *pValue = (uint32_t)(pThis->u64Capabilities);
- break;
- case HPET_PERIOD:
- Log(("read HPET_PERIOD\n"));
- *pValue = (uint32_t)(pThis->u64Capabilities >> 32);
- break;
- case HPET_CFG:
- Log(("read HPET_CFG\n"));
- *pValue = (uint32_t)(pThis->u64HpetConfig);
- break;
- case HPET_CFG + 4:
- Log(("read of HPET_CFG + 4\n"));
- *pValue = (uint32_t)(pThis->u64HpetConfig >> 32);
- break;
- case HPET_COUNTER:
- case HPET_COUNTER + 4:
+ default:
{
- uint64_t u64Ticks;
- Log(("read HPET_COUNTER\n"));
- if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
- u64Ticks = hpetGetTicks(pThis);
- else
- u64Ticks = pThis->u64HpetCounter;
- /** @todo: is it correct? */
- *pValue = (iIndex == HPET_COUNTER) ? (uint32_t)u64Ticks : (uint32_t)(u64Ticks >> 32);
+ static unsigned s_cOccurences = 0;
+ if (s_cOccurences++ < 10)
+ LogRel(("invalid HPET register read %d on %d\n", iTimerReg, pHpetTimer->idxTimer));
+ u32Value = 0;
break;
}
- case HPET_STATUS:
- Log(("read HPET_STATUS\n"));
- *pValue = (uint32_t)(pThis->u64Isr);
- break;
- default:
- Log(("invalid HPET register read: %x\n", iIndex));
- break;
}
+ *pu32Value = u32Value;
return VINF_SUCCESS;
}
-static int hpetTimerRegWrite32(HpetState* pThis,
- uint32_t iTimerNo,
- uint32_t iTimerReg,
- uint32_t iNewValue)
+
+/**
+ * 32-bit write to a HPET timer register.
+ *
+ * @returns Strict VBox status code.
+ *
+ * @param pThis The HPET state.
+ * @param idxReg The register being written to.
+ * @param u32NewValue The value being written.
+ *
+ * @remarks The caller should not hold the device lock, unless it also holds
+ * the TM lock.
+ */
+static int hpetTimerRegWrite32(HpetState *pThis, uint32_t iTimerNo, uint32_t iTimerReg, uint32_t u32NewValue)
{
- HpetTimer * pTimer;
- uint64_t iOldValue = 0;
- uint32_t u32Temp;
- int rc;
+ Assert(!PDMCritSectIsOwner(&pThis->csLock) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer)));
- if (iTimerNo >= HPET_NUM_TIMERS)
+ if (iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities))
{
- LogRel(("HPET: using timer above configured range: %d\n", iTimerNo));
+ static unsigned s_cOccurences = 0;
+ if (s_cOccurences++ < 10)
+ LogRel(("HPET: using timer above configured range: %d\n", iTimerNo));
return VINF_SUCCESS;
}
- pTimer = &pThis->aTimers[iTimerNo];
-
- rc = hpetTimerRegRead32(pThis, iTimerNo, iTimerReg, &u32Temp);
- if (RT_FAILURE(rc))
- return rc;
- iOldValue = u32Temp;
+ HpetTimer *pHpetTimer = &pThis->aTimers[iTimerNo];
switch (iTimerReg)
{
case HPET_TN_CFG:
{
- Log(("write HPET_TN_CFG: %d\n", iTimerNo));
- if (iNewValue & HPET_TN_32BIT)
+ DEVHPET_LOCK_RETURN(pThis, VINF_IOM_HC_MMIO_WRITE);
+ Log(("write HPET_TN_CFG: %d: %x\n", iTimerNo, u32NewValue));
+ uint64_t const iOldValue = (uint32_t)pHpetTimer->u64Config;
+
+ uint64_t u64Mask = HPET_TN_CFG_WRITE_MASK;
+ if (pHpetTimer->u64Config & HPET_TN_PERIODIC_CAP)
+ u64Mask |= HPET_TN_PERIODIC;
+
+ if (pHpetTimer->u64Config & HPET_TN_SIZE_CAP)
+ u64Mask |= HPET_TN_32BIT;
+ else
+ u32NewValue &= ~HPET_TN_32BIT;
+
+ if (u32NewValue & HPET_TN_32BIT)
{
- pTimer->u64Cmp = (uint32_t)pTimer->u64Cmp;
- pTimer->u64Period = (uint32_t)pTimer->u64Period;
+ Log(("setting timer %d to 32-bit mode\n", iTimerNo));
+ pHpetTimer->u64Cmp = (uint32_t)pHpetTimer->u64Cmp;
+ pHpetTimer->u64Period = (uint32_t)pHpetTimer->u64Period;
}
- if ((iNewValue & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_LEVEL)
+ if ((u32NewValue & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_LEVEL)
{
- LogRel(("level-triggered config not yet supported\n"));
- Assert(false);
+ static unsigned s_cOccurences = 0;
+ if (s_cOccurences++ < 10)
+ LogRel(("level-triggered config not yet supported\n"));
+ AssertFailed();
}
- /** We only care about lower 32-bits so far */
- pTimer->u64Config =
- hpetUpdateMasked(iNewValue, iOldValue, HPET_TN_CFG_WRITE_MASK);
+
+ /* We only care about lower 32-bits so far */
+ pHpetTimer->u64Config = hpetUpdateMasked(u32NewValue, iOldValue, u64Mask);
+ DEVHPET_UNLOCK(pThis);
break;
}
+
case HPET_TN_CFG + 4: /* Interrupt capabilities */
{
Log(("write HPET_TN_CFG + 4, useless\n"));
break;
}
+
case HPET_TN_CMP: /* lower bits of comparator register */
{
- Log(("write HPET_TN_CMP on %d: %x\n", iTimerNo, iNewValue));
- if (pTimer->u64Config & HPET_TN_32BIT)
- iNewValue = (uint32_t)iNewValue;
+ DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_HC_MMIO_WRITE);
+ Log(("write HPET_TN_CMP on %d: %#x\n", iTimerNo, u32NewValue));
- if (pTimer->u64Config & HPET_TN_SETVAL)
+ if (pHpetTimer->u64Config & HPET_TN_PERIODIC)
{
- /* HPET_TN_SETVAL allows to adjust comparator w/o updating period, and it's cleared on access */
- if (pTimer->u64Config & HPET_TN_32BIT)
- pTimer->u64Config &= ~HPET_TN_SETVAL;
- } else if (pTimer->u64Config & HPET_TN_PERIODIC)
- {
- iNewValue &= (pTimer->u64Config & HPET_TN_32BIT ? ~0U : ~0ULL) >> 1;
- pTimer->u64Period = (pTimer->u64Period & 0xffffffff00000000ULL)
- | iNewValue;
+ u32NewValue &= hpetInvalidValue(pHpetTimer) >> 1; /** @todo check this in the docs and add a not why? */
+ pHpetTimer->u64Period = RT_MAKE_U64(u32NewValue, pHpetTimer->u64Period);
}
-
- pTimer->u64Cmp = (pTimer->u64Cmp & 0xffffffff00000000ULL)
- | iNewValue;
-
- Log2(("after HPET_TN_CMP cmp=%llx per=%llx\n", pTimer->u64Cmp, pTimer->u64Period));
+ pHpetTimer->u64Cmp = RT_MAKE_U64(u32NewValue, pHpetTimer->u64Cmp);
+ pHpetTimer->u64Config &= ~HPET_TN_SETVAL;
+ Log2(("after HPET_TN_CMP cmp=%#llx per=%#llx\n", pHpetTimer->u64Cmp, pHpetTimer->u64Period));
if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
- hpetProgramTimer(pTimer);
+ hpetProgramTimer(pHpetTimer);
+ DEVHPET_UNLOCK_BOTH(pThis);
break;
}
+
case HPET_TN_CMP + 4: /* upper bits of comparator register */
{
- Log(("write HPET_TN_CMP + 4 on %d: %x\n", iTimerNo, iNewValue));
- if (pTimer->u64Config & HPET_TN_32BIT)
- break;
-
- if (pTimer->u64Config & HPET_TN_SETVAL)
- {
- /* HPET_TN_SETVAL allows to adjust comparator w/o updating period, and it's cleared on access */
- pTimer->u64Config &= ~HPET_TN_SETVAL;
- } else if (pTimer->u64Config & HPET_TN_PERIODIC)
+ DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_HC_MMIO_WRITE);
+ Log(("write HPET_TN_CMP + 4 on %d: %#x\n", iTimerNo, u32NewValue));
+ if (!hpet32bitTimer(pHpetTimer))
{
- pTimer->u64Period = (pTimer->u64Period & 0xffffffffULL)
- | ((uint64_t)iNewValue << 32);
- }
+ if (pHpetTimer->u64Config & HPET_TN_PERIODIC)
+ pHpetTimer->u64Period = RT_MAKE_U64(pHpetTimer->u64Period, u32NewValue);
+ pHpetTimer->u64Cmp = RT_MAKE_U64(pHpetTimer->u64Cmp, u32NewValue);
- pTimer->u64Cmp = (pTimer->u64Cmp & 0xffffffffULL)
- | ((uint64_t)iNewValue << 32);
+ Log2(("after HPET_TN_CMP+4 cmp=%llx per=%llx tmr=%d\n", pHpetTimer->u64Cmp, pHpetTimer->u64Period, iTimerNo));
- Log2(("after HPET_TN_CMP+4 cmp=%llx per=%llx\n", pTimer->u64Cmp, pTimer->u64Period));
+ pHpetTimer->u64Config &= ~HPET_TN_SETVAL;
- if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
- hpetProgramTimer(pTimer);
+ if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
+ hpetProgramTimer(pHpetTimer);
+ }
+ DEVHPET_UNLOCK_BOTH(pThis);
break;
}
+
case HPET_TN_ROUTE:
{
Log(("write HPET_TN_ROUTE\n"));
break;
}
+
case HPET_TN_ROUTE + 4:
{
Log(("write HPET_TN_ROUTE + 4\n"));
break;
}
+
default:
{
- LogRel(("invalid timer register write: %d\n", iTimerReg));
- Assert(false);
+ static unsigned s_cOccurences = 0;
+ if (s_cOccurences++ < 10)
+ LogRel(("invalid timer register write: %d\n", iTimerReg));
break;
}
}
+
return VINF_SUCCESS;
}
-static int hpetLegacyMode(HpetState* pThis,
- bool fActivate)
+
+/* -=-=-=-=-=- Non-timer register accesses -=-=-=-=-=- */
+
+
+/**
+ * Read a 32-bit HPET register.
+ *
+ * @returns Strict VBox status code.
+ * @param pThis The HPET state.
+ * @param idxReg The register to read.
+ * @param pu32Value Where to return the register value.
+ *
+ * @remarks The caller must not own the device lock if HPET_COUNTER is read.
+ */
+static int hpetConfigRegRead32(HpetState *pThis, uint32_t idxReg, uint32_t *pu32Value)
{
- int rc = VINF_SUCCESS;
-#ifndef IN_RING3
- /* Don't do anything complicated outside of R3 */
- rc = VINF_IOM_HC_MMIO_WRITE;
-#else /* IN_RING3 */
- if (pThis->pHpetHlpR3)
- rc = pThis->pHpetHlpR3->pfnSetLegacyMode(pThis->pDevInsR3, fActivate);
-#endif
- return rc;
+ Assert(!PDMCritSectIsOwner(&pThis->csLock) || (idxReg != HPET_COUNTER && idxReg != HPET_COUNTER + 4));
+
+ uint32_t u32Value;
+ switch (idxReg)
+ {
+ case HPET_ID:
+ DEVHPET_LOCK_RETURN(pThis, VINF_IOM_HC_MMIO_READ);
+ u32Value = pThis->u32Capabilities;
+ DEVHPET_UNLOCK(pThis);
+ Log(("read HPET_ID: %#x\n", u32Value));
+ break;
+
+ case HPET_PERIOD:
+ DEVHPET_LOCK_RETURN(pThis, VINF_IOM_HC_MMIO_READ);
+ u32Value = pThis->u32Period;
+ DEVHPET_UNLOCK(pThis);
+ Log(("read HPET_PERIOD: %#x\n", u32Value));
+ break;
+
+ case HPET_CFG:
+ DEVHPET_LOCK_RETURN(pThis, VINF_IOM_HC_MMIO_READ);
+ u32Value = (uint32_t)pThis->u64HpetConfig;
+ DEVHPET_UNLOCK(pThis);
+ Log(("read HPET_CFG: %#x\n", u32Value));
+ break;
+
+ case HPET_CFG + 4:
+ DEVHPET_LOCK_RETURN(pThis, VINF_IOM_HC_MMIO_READ);
+ u32Value = (uint32_t)(pThis->u64HpetConfig >> 32);
+ DEVHPET_UNLOCK(pThis);
+ Log(("read of HPET_CFG + 4: %#x\n", u32Value));
+ break;
+
+ case HPET_COUNTER:
+ case HPET_COUNTER + 4:
+ {
+ DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_HC_MMIO_READ);
+
+ uint64_t u64Ticks;
+ if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
+ u64Ticks = hpetGetTicks(pThis);
+ else
+ u64Ticks = pThis->u64HpetCounter;
+
+ DEVHPET_UNLOCK_BOTH(pThis);
+
+ /** @todo is it correct? */
+ u32Value = (idxReg == HPET_COUNTER) ? (uint32_t)u64Ticks : (uint32_t)(u64Ticks >> 32);
+ Log(("read HPET_COUNTER: %s part value %x (%#llx)\n",
+ (idxReg == HPET_COUNTER) ? "low" : "high", u32Value, u64Ticks));
+ break;
+ }
+
+ case HPET_STATUS:
+ DEVHPET_LOCK_RETURN(pThis, VINF_IOM_HC_MMIO_READ);
+ u32Value = (uint32_t)pThis->u64Isr;
+ DEVHPET_UNLOCK(pThis);
+ Log(("read HPET_STATUS: %#x\n", u32Value));
+ break;
+
+ default:
+ Log(("invalid HPET register read: %x\n", idxReg));
+ u32Value = 0;
+ break;
+ }
+
+ *pu32Value = u32Value;
+ return VINF_SUCCESS;
}
-static int hpetConfigRegWrite32(HpetState* pThis,
- uint32_t iIndex,
- uint32_t iNewValue)
+
+/**
+ * 32-bit write to a config register.
+ *
+ * @returns Strict VBox status code.
+ *
+ * @param pThis The HPET state.
+ * @param idxReg The register being written to.
+ * @param u32NewValue The value being written.
+ *
+ * @remarks The caller should not hold the device lock, unless it also holds
+ * the TM lock.
+ */
+static int hpetConfigRegWrite32(HpetState *pThis, uint32_t idxReg, uint32_t u32NewValue)
{
- int rc = VINF_SUCCESS;
+ Assert(!PDMCritSectIsOwner(&pThis->csLock) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer)));
- switch (iIndex)
+ int rc = VINF_SUCCESS;
+ switch (idxReg)
{
case HPET_ID:
case HPET_ID + 4:
@@ -608,482 +739,549 @@ static int hpetConfigRegWrite32(HpetState* pThis,
Log(("write HPET_ID, useless\n"));
break;
}
+
case HPET_CFG:
{
- uint32_t i, iOldValue;
-
- Log(("write HPET_CFG: %x\n", iNewValue));
-
- iOldValue = (uint32_t)(pThis->u64HpetConfig);
+ DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_HC_MMIO_WRITE);
+ uint32_t const iOldValue = (uint32_t)(pThis->u64HpetConfig);
+ Log(("write HPET_CFG: %x (old %x)\n", u32NewValue, iOldValue));
/*
* This check must be here, before actual update, as hpetLegacyMode
* may request retry in R3 - so we must keep state intact.
*/
- if (hpetBitJustSet(iOldValue, iNewValue, HPET_CFG_LEGACY))
- {
- rc = hpetLegacyMode(pThis, true);
- }
- else if (hpetBitJustCleared(iOldValue, iNewValue, HPET_CFG_LEGACY))
+ if ( ((iOldValue ^ u32NewValue) & HPET_CFG_LEGACY)
+ && pThis->pHpetHlpR3 != NIL_RTR3PTR)
{
- rc = hpetLegacyMode(pThis, false);
+#ifdef IN_RING3
+ rc = pThis->pHpetHlpR3->pfnSetLegacyMode(pThis->pDevInsR3, RT_BOOL(u32NewValue & HPET_CFG_LEGACY));
+ if (rc != VINF_SUCCESS)
+#else
+ rc = VINF_IOM_HC_MMIO_WRITE;
+#endif
+ {
+ DEVHPET_UNLOCK_BOTH(pThis);
+ break;
+ }
}
- if (rc != VINF_SUCCESS)
- return rc;
- pThis->u64HpetConfig = hpetUpdateMasked(iNewValue, iOldValue, HPET_CFG_WRITE_MASK);
- if (hpetBitJustSet(iOldValue, iNewValue, HPET_CFG_ENABLE))
+ pThis->u64HpetConfig = hpetUpdateMasked(u32NewValue, iOldValue, HPET_CFG_WRITE_MASK);
+
+ uint32_t const cTimers = HPET_CAP_GET_TIMERS(pThis->u32Capabilities);
+ if (hpetBitJustSet(iOldValue, u32NewValue, HPET_CFG_ENABLE))
{
+/** @todo Only get the time stamp once when reprogramming? */
/* Enable main counter and interrupt generation. */
- pThis->u64HpetOffset = hpetTicksToNs(pThis->u64HpetCounter)
- - TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer));
- for (i = 0; i < HPET_NUM_TIMERS; i++)
- if (pThis->aTimers[i].u64Cmp != ~0ULL)
+ pThis->u64HpetOffset = hpetTicksToNs(pThis, pThis->u64HpetCounter)
+ - TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer));
+ for (uint32_t i = 0; i < cTimers; i++)
+ if (pThis->aTimers[i].u64Cmp != hpetInvalidValue(&pThis->aTimers[i]))
hpetProgramTimer(&pThis->aTimers[i]);
}
- else if (hpetBitJustCleared(iOldValue, iNewValue, HPET_CFG_ENABLE))
+ else if (hpetBitJustCleared(iOldValue, u32NewValue, HPET_CFG_ENABLE))
{
/* Halt main counter and disable interrupt generation. */
pThis->u64HpetCounter = hpetGetTicks(pThis);
- for (i = 0; i < HPET_NUM_TIMERS; i++)
+ for (uint32_t i = 0; i < cTimers; i++)
TMTimerStop(pThis->aTimers[i].CTX_SUFF(pTimer));
}
+
+ DEVHPET_UNLOCK_BOTH(pThis);
break;
}
+
case HPET_CFG + 4:
{
- Log(("write HPET_CFG + 4: %x\n", iNewValue));
- pThis->u64HpetConfig = hpetUpdateMasked((uint64_t)iNewValue << 32,
+ DEVHPET_LOCK_RETURN(pThis, VINF_IOM_HC_MMIO_WRITE);
+ pThis->u64HpetConfig = hpetUpdateMasked((uint64_t)u32NewValue << 32,
pThis->u64HpetConfig,
- 0xffffffff00000000ULL);
+ UINT64_C(0xffffffff00000000));
+ Log(("write HPET_CFG + 4: %x -> %#llx\n", u32NewValue, pThis->u64HpetConfig));
+ DEVHPET_UNLOCK(pThis);
break;
}
+
case HPET_STATUS:
{
- Log(("write HPET_STATUS: %x\n", iNewValue));
- // clear ISR for all set bits in iNewValue, see p. 14 of HPET spec
- pThis->u64Isr &= ~((uint64_t)iNewValue);
+ DEVHPET_LOCK_RETURN(pThis, VINF_IOM_HC_MMIO_WRITE);
+ /* Clear ISR for all set bits in u32NewValue, see p. 14 of the HPET spec. */
+ pThis->u64Isr &= ~((uint64_t)u32NewValue);
+ Log(("write HPET_STATUS: %x -> ISR=%#llx\n", u32NewValue, pThis->u64Isr));
+ DEVHPET_UNLOCK(pThis);
break;
}
+
case HPET_STATUS + 4:
{
- Log(("write HPET_STATUS + 4: %x\n", iNewValue));
- if (iNewValue != 0)
- LogRel(("Writing HPET_STATUS + 4 with non-zero, ignored\n"));
+ Log(("write HPET_STATUS + 4: %x\n", u32NewValue));
+ if (u32NewValue != 0)
+ {
+ static unsigned s_cOccurrences = 0;
+ if (s_cOccurrences++ < 10)
+ LogRel(("Writing HPET_STATUS + 4 with non-zero, ignored\n"));
+ }
break;
}
+
case HPET_COUNTER:
{
- pThis->u64HpetCounter = (pThis->u64HpetCounter & 0xffffffff00000000ULL) | iNewValue;
- Log(("write HPET_COUNTER: %#x -> %llx\n",
- iNewValue, pThis->u64HpetCounter));
+ DEVHPET_LOCK_RETURN(pThis, VINF_IOM_HC_MMIO_WRITE);
+ pThis->u64HpetCounter = RT_MAKE_U64(u32NewValue, pThis->u64HpetCounter);
+ Log(("write HPET_COUNTER: %#x -> %llx\n", u32NewValue, pThis->u64HpetCounter));
+ DEVHPET_UNLOCK(pThis);
break;
}
+
case HPET_COUNTER + 4:
{
- pThis->u64HpetCounter = (pThis->u64HpetCounter & 0xffffffffULL)
- | (((uint64_t)iNewValue) << 32);
- Log(("write HPET_COUNTER + 4: %#x -> %llx\n",
- iNewValue, pThis->u64HpetCounter));
+ DEVHPET_LOCK_RETURN(pThis, VINF_IOM_HC_MMIO_WRITE);
+ pThis->u64HpetCounter = RT_MAKE_U64(pThis->u64HpetCounter, u32NewValue);
+ Log(("write HPET_COUNTER + 4: %#x -> %llx\n", u32NewValue, pThis->u64HpetCounter));
+ DEVHPET_UNLOCK(pThis);
break;
}
+
default:
- LogRel(("invalid HPET config write: %x\n", iIndex));
+ {
+ static unsigned s_cOccurences = 0;
+ if (s_cOccurences++ < 10)
+ LogRel(("invalid HPET config write: %x\n", idxReg));
break;
+ }
}
return rc;
}
-PDMBOTHCBDECL(int) hpetMMIORead(PPDMDEVINS pDevIns,
- void * pvUser,
- RTGCPHYS GCPhysAddr,
- void * pv,
- unsigned cb)
-{
- HpetState * pThis = PDMINS_2_DATA(pDevIns, HpetState*);
- int rc = VINF_SUCCESS;
- uint32_t iIndex = (uint32_t)(GCPhysAddr - HPET_BASE);
- LogFlow(("hpetMMIORead (%d): %llx (%x)\n", cb, (uint64_t)GCPhysAddr, iIndex));
+/* -=-=-=-=-=- MMIO callbacks -=-=-=-=-=- */
- rc = hpetLock(pThis, VINF_IOM_HC_MMIO_READ);
- if (RT_UNLIKELY(rc != VINF_SUCCESS))
- return rc;
+/**
+ * @callback_method_impl{FNIOMMMIOREAD}
+ */
+PDMBOTHCBDECL(int) hpetMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+{
+ HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState*);
+ uint32_t const idxReg = (uint32_t)(GCPhysAddr - HPET_BASE);
+
+ LogFlow(("hpetMMIORead (%d): %llx (%x)\n", cb, (uint64_t)GCPhysAddr, idxReg));
+
+ int rc = VINF_SUCCESS;
switch (cb)
{
- case 1:
- case 2:
- Log(("Narrow read: %d\n", cb));
- rc = VINF_SUCCESS;
- break;
case 4:
- {
- if ((iIndex >= 0x100) && (iIndex < 0x400))
- rc = hpetTimerRegRead32(pThis, (iIndex - 0x100) / 0x20, (iIndex - 0x100) % 0x20, (uint32_t*)pv);
+ if (idxReg >= 0x100 && idxReg < 0x400)
+ {
+ DEVHPET_LOCK_RETURN(pThis, VINF_IOM_HC_MMIO_READ);
+ rc = hpetTimerRegRead32(pThis,
+ (idxReg - 0x100) / 0x20,
+ (idxReg - 0x100) % 0x20,
+ (uint32_t *)pv);
+ DEVHPET_UNLOCK(pThis);
+ }
else
- rc = hpetConfigRegRead32(pThis, iIndex, (uint32_t*)pv);
+ rc = hpetConfigRegRead32(pThis, idxReg, (uint32_t *)pv);
break;
- }
+
case 8:
{
- union {
- uint32_t u32[2];
- uint64_t u64;
- } value;
-
/* Unaligned accesses not allowed */
- if (iIndex % 8 != 0)
+ if (RT_UNLIKELY(idxReg % 8 != 0))
{
- AssertMsgFailed(("Unaligned HPET read access\n"));
- rc = VINF_SUCCESS;
+ rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "idxReg=%#x cb=8\n", idxReg);
break;
}
- if ((iIndex >= 0x100) && (iIndex < 0x400))
+
+ /* Split the access except for timing sensitive registers. The
+ others assume the protection of the lock. */
+ PRTUINT64U pValue = (PRTUINT64U)pv;
+ if (idxReg == HPET_COUNTER)
{
- uint32_t iTimer = (iIndex - 0x100) / 0x20;
- uint32_t iTimerReg = (iIndex - 0x100) % 0x20;
-
- /* for most 8-byte accesses we just split them, happens under lock anyway. */
- rc = hpetTimerRegRead32(pThis, iTimer, iTimerReg, &value.u32[0]);
- if (RT_UNLIKELY(rc != VINF_SUCCESS))
- break;
- rc = hpetTimerRegRead32(pThis, iTimer, iTimerReg + 4, &value.u32[1]);
+ /* When reading HPET counter we must read it in a single read,
+ to avoid unexpected time jumps on 32-bit overflow. */
+ DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_HC_MMIO_READ);
+ if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
+ pValue->u = hpetGetTicks(pThis);
+ else
+ pValue->u = pThis->u64HpetCounter;
+ DEVHPET_UNLOCK_BOTH(pThis);
}
else
{
- if (iIndex == HPET_COUNTER)
+ DEVHPET_LOCK_RETURN(pThis, VINF_IOM_HC_MMIO_READ);
+ if (idxReg >= 0x100 && idxReg < 0x400)
{
- /* When reading HPET counter we must read it in a single read,
- to avoid unexpected time jumps on 32-bit overflow. */
- value.u64 =
- (pThis->u64HpetConfig & HPET_CFG_ENABLE) != 0
- ?
- hpetGetTicks(pThis)
- :
- pThis->u64HpetCounter;
- rc = VINF_SUCCESS;
+ uint32_t iTimer = (idxReg - 0x100) / 0x20;
+ uint32_t iTimerReg = (idxReg - 0x100) % 0x20;
+ rc = hpetTimerRegRead32(pThis, iTimer, iTimerReg, &pValue->s.Lo);
+ if (rc == VINF_SUCCESS)
+ rc = hpetTimerRegRead32(pThis, iTimer, iTimerReg + 4, &pValue->s.Hi);
}
else
{
/* for most 8-byte accesses we just split them, happens under lock anyway. */
-
- rc = hpetConfigRegRead32(pThis, iIndex, &value.u32[0]);
- if (RT_UNLIKELY(rc != VINF_SUCCESS))
- break;
- rc = hpetConfigRegRead32(pThis, iIndex+4, &value.u32[1]);
+ rc = hpetConfigRegRead32(pThis, idxReg, &pValue->s.Lo);
+ if (rc == VINF_SUCCESS)
+ rc = hpetConfigRegRead32(pThis, idxReg + 4, &pValue->s.Hi);
}
+ DEVHPET_UNLOCK(pThis);
}
- if (rc == VINF_SUCCESS)
- *(uint64_t*)pv = value.u64;
break;
}
+ case 1:
+ case 2:
+ Log(("Narrow read: %d\n", cb));
+ rc = VINF_SUCCESS;
+ break;
+
default:
AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
rc = VINF_SUCCESS;
}
- hpetUnlock(pThis);
-
return rc;
}
-PDMBOTHCBDECL(int) hpetMMIOWrite(PPDMDEVINS pDevIns,
- void * pvUser,
- RTGCPHYS GCPhysAddr,
- void * pv,
- unsigned cb)
-{
- HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState*);
- int rc = VINF_SUCCESS;
- uint32_t iIndex = (uint32_t)(GCPhysAddr - HPET_BASE);
- LogFlow(("hpetMMIOWrite (%d): %llx (%x) <- %x\n",
- cb, (uint64_t)GCPhysAddr, iIndex, cb >= 4 ? *(uint32_t*)pv : 0xdeadbeef));
-
- rc = hpetLock(pThis, VINF_IOM_HC_MMIO_WRITE);
- if (RT_UNLIKELY(rc != VINF_SUCCESS))
- return rc;
+/**
+ * @callback_method_impl{FNIOMMMIOWRITE}
+ */
+PDMBOTHCBDECL(int) hpetMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
+{
+ HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState*);
+ uint32_t idxReg = (uint32_t)(GCPhysAddr - HPET_BASE);
+ LogFlow(("hpetMMIOWrite: cb=%u reg=%03x (%RGp) val=%llx\n",
+ cb, idxReg, GCPhysAddr, cb == 4 ? *(uint32_t *)pv : cb == 8 ? *(uint64_t *)pv : 0xdeadbeef));
+ int rc;
switch (cb)
{
- case 1:
- case 2:
- Log(("Narrow write: %d\n", cb));
- rc = VINF_SUCCESS;
- break;
case 4:
- {
- if ((iIndex >= 0x100) && (iIndex < 0x400))
+ if (idxReg >= 0x100 && idxReg < 0x400)
rc = hpetTimerRegWrite32(pThis,
- (iIndex - 0x100) / 0x20,
- (iIndex - 0x100) % 0x20,
- *(uint32_t*)pv);
+ (idxReg - 0x100) / 0x20,
+ (idxReg - 0x100) % 0x20,
+ *(uint32_t const *)pv);
else
- rc = hpetConfigRegWrite32(pThis, iIndex, *(uint32_t*)pv);
+ rc = hpetConfigRegWrite32(pThis, idxReg, *(uint32_t const *)pv);
break;
- }
+
case 8:
{
- union {
- uint32_t u32[2];
- uint64_t u64;
- } value;
-
- /* Unaligned accesses not allowed */
- if (iIndex % 8 != 0)
+ /* Unaligned accesses are not allowed. */
+ if (RT_UNLIKELY(idxReg % 8 != 0))
{
- AssertMsgFailed(("Unaligned HPET write access\n"));
- rc = VINF_SUCCESS;
+ rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "idxReg=%#x cb=8\n", idxReg);
break;
}
- value.u64 = *(uint64_t*)pv;
- // for 8-byte accesses we just split them, happens under lock anyway
- if ((iIndex >= 0x100) && (iIndex < 0x400))
- {
- uint32_t iTimer = (iIndex - 0x100) / 0x20;
- uint32_t iTimerReg = (iIndex - 0x100) % 0x20;
- rc = hpetTimerRegWrite32(pThis, iTimer, iTimerReg, value.u32[0]);
- if (RT_UNLIKELY(rc != VINF_SUCCESS))
- break;
- rc = hpetTimerRegWrite32(pThis, iTimer, iTimerReg + 4, value.u32[1]);
+ /* Split the access and rely on the locking to prevent trouble. */
+ DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_HC_MMIO_WRITE);
+ RTUINT64U uValue;
+ uValue.u = *(uint64_t const *)pv;
+ if (idxReg >= 0x100 && idxReg < 0x400)
+ {
+ uint32_t iTimer = (idxReg - 0x100) / 0x20;
+ uint32_t iTimerReg = (idxReg - 0x100) % 0x20;
+/** @todo Consider handling iTimerReg == HPET_TN_CMP specially here */
+ rc = hpetTimerRegWrite32(pThis, iTimer, iTimerReg, uValue.s.Lo);
+ if (RT_LIKELY(rc == VINF_SUCCESS))
+ rc = hpetTimerRegWrite32(pThis, iTimer, iTimerReg + 4, uValue.s.Hi);
}
else
{
- rc = hpetConfigRegWrite32(pThis, iIndex, value.u32[0]);
- if (RT_UNLIKELY(rc != VINF_SUCCESS))
- break;
- rc = hpetConfigRegWrite32(pThis, iIndex+4, value.u32[1]);
+ rc = hpetConfigRegWrite32(pThis, idxReg, uValue.s.Lo);
+ if (RT_LIKELY(rc == VINF_SUCCESS))
+ rc = hpetConfigRegWrite32(pThis, idxReg + 4, uValue.s.Hi);
}
+ DEVHPET_UNLOCK_BOTH(pThis);
break;
}
+ case 1:
+ case 2:
+ Log(("Narrow write: %d\n", cb));
+ rc = VINF_SUCCESS;
+ break;
+
default:
AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
rc = VERR_INTERNAL_ERROR;
+ break;
}
- hpetUnlock(pThis);
-
return rc;
}
#ifdef IN_RING3
-static int hpetSaveTimer(HpetTimer *pTimer,
- PSSMHANDLE pSSM)
+/* -=-=-=-=-=- Timer Callback Processing -=-=-=-=-=- */
+
+/**
+ * Gets the IRQ of an HPET timer.
+ *
+ * @returns IRQ number.
+ * @param pHpetTimer The HPET timer.
+ */
+static uint32_t hpetTimerCbGetIrq(struct HpetTimer const *pHpetTimer)
+{
+ /*
+ * Per spec, in legacy mode HPET timers wired as:
+ * timer 0: IRQ0 for PIC and IRQ2 for APIC
+ * timer 1: IRQ8 for both PIC and APIC
+ *
+ * ISA IRQ delivery logic will take care of correct delivery
+ * to the different ICs.
+ */
+ if ( (pHpetTimer->idxTimer <= 1)
+ && (pHpetTimer->CTX_SUFF(pHpet)->u64HpetConfig & HPET_CFG_LEGACY))
+ return (pHpetTimer->idxTimer == 0) ? 0 : 8;
+
+ return (pHpetTimer->u64Config & HPET_TN_INT_ROUTE_MASK) >> HPET_TN_INT_ROUTE_SHIFT;
+}
+
+
+/**
+ * Used by hpetTimerCb to update the IRQ status.
+ *
+ * @param pThis The HPET device state.
+ * @param pHpetTimer The HPET timer.
+ */
+static void hpetTimerCbUpdateIrq(HpetState *pThis, struct HpetTimer *pHpetTimer)
{
- TMR3TimerSave(pTimer->pTimerR3, pSSM);
- SSMR3PutU8 (pSSM, pTimer->u8Wrap);
- SSMR3PutU64 (pSSM, pTimer->u64Config);
- SSMR3PutU64 (pSSM, pTimer->u64Cmp);
- SSMR3PutU64 (pSSM, pTimer->u64Fsb);
- SSMR3PutU64 (pSSM, pTimer->u64Period);
+ /** @todo: is it correct? */
+ if ( !!(pHpetTimer->u64Config & HPET_TN_ENABLE)
+ && !!(pThis->u64HpetConfig & HPET_CFG_ENABLE))
+ {
+ uint32_t irq = hpetTimerCbGetIrq(pHpetTimer);
+ Log4(("HPET: raising IRQ %d\n", irq));
- return VINF_SUCCESS;
+ /* ISR bits are only set in level-triggered mode. */
+ if ((pHpetTimer->u64Config & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_LEVEL)
+ pThis->u64Isr |= (uint64_t)(1 << pHpetTimer->idxTimer);
+
+ /* We trigger flip/flop in edge-triggered mode and do nothing in
+ level-triggered mode yet. */
+ if ((pHpetTimer->u64Config & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_EDGE)
+ pThis->pHpetHlpR3->pfnSetIrq(pThis->CTX_SUFF(pDevIns), irq, PDM_IRQ_LEVEL_FLIP_FLOP);
+ else
+ AssertFailed();
+ /** @todo: implement IRQs in level-triggered mode */
+ }
}
-static int hpetLoadTimer(HpetTimer *pTimer,
- PSSMHANDLE pSSM)
+/**
+ * Device timer callback function.
+ *
+ * @param pDevIns Device instance of the device which registered the timer.
+ * @param pTimer The timer handle.
+ * @param pvUser Pointer to the HPET timer state.
+ */
+static DECLCALLBACK(void) hpetTimerCb(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
{
- TMR3TimerLoad(pTimer->pTimerR3, pSSM);
- SSMR3GetU8(pSSM, &pTimer->u8Wrap);
- SSMR3GetU64(pSSM, &pTimer->u64Config);
- SSMR3GetU64(pSSM, &pTimer->u64Cmp);
- SSMR3GetU64(pSSM, &pTimer->u64Fsb);
- SSMR3GetU64(pSSM, &pTimer->u64Period);
+ HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
+ HpetTimer *pHpetTimer = (HpetTimer *)pvUser;
+ uint64_t u64Period = pHpetTimer->u64Period;
+ uint64_t u64CurTick = hpetGetTicks(pThis);
+ uint64_t u64Diff;
- return VINF_SUCCESS;
+ if ((pHpetTimer->u64Config & HPET_TN_PERIODIC) && (u64Period != 0))
+ {
+ hpetAdjustComparator(pHpetTimer, u64CurTick);
+
+ u64Diff = hpetComputeDiff(pHpetTimer, u64CurTick);
+
+ Log4(("HPET: periodical: next in %llu\n", hpetTicksToNs(pThis, u64Diff)));
+ TMTimerSetNano(pTimer, hpetTicksToNs(pThis, u64Diff));
+ }
+ else if ( hpet32bitTimer(pHpetTimer)
+ && !(pHpetTimer->u64Config & HPET_TN_PERIODIC))
+ {
+ if (pHpetTimer->u8Wrap)
+ {
+ u64Diff = hpetComputeDiff(pHpetTimer, u64CurTick);
+ TMTimerSetNano(pTimer, hpetTicksToNs(pThis, u64Diff));
+ pHpetTimer->u8Wrap = 0;
+ }
+ }
+
+ /* Should it really be under lock, does it really matter? */
+ hpetTimerCbUpdateIrq(pThis, pHpetTimer);
}
+
+/* -=-=-=-=-=- DBGF Info Handlers -=-=-=-=-=- */
+
+
+/**
+ * @callback_method_impl{FNDBGFHANDLERDEV}
+ */
+static DECLCALLBACK(void) hpetInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+ HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
+
+ pHlp->pfnPrintf(pHlp,
+ "HPET status:\n"
+ " config=%016RX64 isr=%016RX64\n"
+ " offset=%016RX64 counter=%016RX64 frequency=%08x\n"
+ " legacy-mode=%s timer-count=%u\n",
+ pThis->u64HpetConfig, pThis->u64Isr,
+ pThis->u64HpetOffset, pThis->u64HpetCounter, pThis->u32Period,
+ !!(pThis->u64HpetConfig & HPET_CFG_LEGACY) ? "on " : "off",
+ HPET_CAP_GET_TIMERS(pThis->u32Capabilities));
+ pHlp->pfnPrintf(pHlp,
+ "Timers:\n");
+ for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
+ {
+ pHlp->pfnPrintf(pHlp, " %d: comparator=%016RX64 period(hidden)=%016RX64 cfg=%016RX64\n",
+ pThis->aTimers[i].idxTimer,
+ pThis->aTimers[i].u64Cmp,
+ pThis->aTimers[i].u64Period,
+ pThis->aTimers[i].u64Config);
+ }
+}
+
+
+/* -=-=-=-=-=- Saved State -=-=-=-=-=- */
+
+
/**
- * @copydoc FNSSMDEVLIVEEXEC
+ * @callback_method_impl{FNSSMDEVLIVEEXEC}
*/
static DECLCALLBACK(int) hpetLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
{
HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
- SSMR3PutU8(pSSM, HPET_NUM_TIMERS);
+ SSMR3PutU8(pSSM, HPET_CAP_GET_TIMERS(pThis->u32Capabilities));
return VINF_SSM_DONT_CALL_AGAIN;
}
+
/**
- * Saves a state of the HPET device.
- *
- * @returns VBox status code.
- * @param pDevIns The device instance.
- * @param pSSMHandle The handle to save the state to.
+ * @callback_method_impl{FNSSMDEVSAVEEXEC}
*/
-static DECLCALLBACK(int) hpetSaveExec(PPDMDEVINS pDevIns,
- PSSMHANDLE pSSM)
+static DECLCALLBACK(int) hpetSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
{
HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
- uint32_t iTimer;
- int rc;
- /* The config. */
+ /*
+ * The config.
+ */
hpetLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
- for (iTimer = 0; iTimer < HPET_NUM_TIMERS; iTimer++)
+ /*
+ * The state.
+ */
+ uint32_t const cTimers = HPET_CAP_GET_TIMERS(pThis->u32Capabilities);
+ for (uint32_t iTimer = 0; iTimer < cTimers; iTimer++)
{
- rc = hpetSaveTimer(&pThis->aTimers[iTimer], pSSM);
- AssertRCReturn(rc, rc);
+ HpetTimer *pHpetTimer = &pThis->aTimers[iTimer];
+ TMR3TimerSave(pHpetTimer->pTimerR3, pSSM);
+ SSMR3PutU8(pSSM, pHpetTimer->u8Wrap);
+ SSMR3PutU64(pSSM, pHpetTimer->u64Config);
+ SSMR3PutU64(pSSM, pHpetTimer->u64Cmp);
+ SSMR3PutU64(pSSM, pHpetTimer->u64Fsb);
+ SSMR3PutU64(pSSM, pHpetTimer->u64Period);
}
SSMR3PutU64(pSSM, pThis->u64HpetOffset);
- SSMR3PutU64(pSSM, pThis->u64Capabilities);
+ uint64_t u64CapPer = RT_MAKE_U64(pThis->u32Capabilities, pThis->u32Period);
+ SSMR3PutU64(pSSM, u64CapPer);
SSMR3PutU64(pSSM, pThis->u64HpetConfig);
SSMR3PutU64(pSSM, pThis->u64Isr);
- SSMR3PutU64(pSSM, pThis->u64HpetCounter);
-
- return VINF_SUCCESS;
+ return SSMR3PutU64(pSSM, pThis->u64HpetCounter);
}
+
/**
- * Loads a HPET device state.
- *
- * @returns VBox status code.
- * @param pDevIns The device instance.
- * @param pSSMHandle The handle to the saved state.
- * @param uVersion The data unit version number.
- * @param uPass The data pass.
+ * @callback_method_impl{FNSSMDEVLOADEXEC}
*/
-static DECLCALLBACK(int) hpetLoadExec(PPDMDEVINS pDevIns,
- PSSMHANDLE pSSM,
- uint32_t uVersion,
- uint32_t uPass)
+static DECLCALLBACK(int) hpetLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
{
HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
- uint32_t iTimer;
- int rc;
+ /*
+ * Version checks.
+ */
if (uVersion == HPET_SAVED_STATE_VERSION_EMPTY)
return VINF_SUCCESS;
-
if (uVersion != HPET_SAVED_STATE_VERSION)
return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
- uint8_t u8NumTimers;
-
- rc = SSMR3GetU8(pSSM, &u8NumTimers); AssertRCReturn(rc, rc);
- if (u8NumTimers != HPET_NUM_TIMERS)
- return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - wrong number of timers: saved=%#x config=%#x"), u8NumTimers, HPET_NUM_TIMERS);
+ /*
+ * The config.
+ */
+ uint8_t cTimers;
+ int rc = SSMR3GetU8(pSSM, &cTimers);
+ AssertRCReturn(rc, rc);
+ if (cTimers > RT_ELEMENTS(pThis->aTimers))
+ return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - too many timers: saved=%#x config=%#x"),
+ cTimers, RT_ELEMENTS(pThis->aTimers));
if (uPass != SSM_PASS_FINAL)
return VINF_SUCCESS;
- for (iTimer = 0; iTimer < HPET_NUM_TIMERS; iTimer++)
+ /*
+ * The state.
+ */
+ for (uint32_t iTimer = 0; iTimer < cTimers; iTimer++)
{
- rc = hpetLoadTimer(&pThis->aTimers[iTimer], pSSM);
- AssertRCReturn(rc, rc);
+ HpetTimer *pHpetTimer = &pThis->aTimers[iTimer];
+ TMR3TimerLoad(pHpetTimer->pTimerR3, pSSM);
+ SSMR3GetU8(pSSM, &pHpetTimer->u8Wrap);
+ SSMR3GetU64(pSSM, &pHpetTimer->u64Config);
+ SSMR3GetU64(pSSM, &pHpetTimer->u64Cmp);
+ SSMR3GetU64(pSSM, &pHpetTimer->u64Fsb);
+ SSMR3GetU64(pSSM, &pHpetTimer->u64Period);
}
SSMR3GetU64(pSSM, &pThis->u64HpetOffset);
- SSMR3GetU64(pSSM, &pThis->u64Capabilities);
+ uint64_t u64CapPer;
+ SSMR3GetU64(pSSM, &u64CapPer);
SSMR3GetU64(pSSM, &pThis->u64HpetConfig);
SSMR3GetU64(pSSM, &pThis->u64Isr);
- SSMR3GetU64(pSSM, &pThis->u64HpetCounter);
-
- return VINF_SUCCESS;
-}
-
-static void hpetIrqUpdate(struct HpetTimer *pTimer)
-{
- uint32_t irq = getTimerIrq(pTimer);
- HpetState* pThis = pTimer->CTX_SUFF(pHpet);
+ rc = SSMR3GetU64(pSSM, &pThis->u64HpetCounter);
+ if (RT_FAILURE(rc))
+ return rc;
+ if (HPET_CAP_GET_TIMERS(RT_LO_U32(u64CapPer)) != cTimers)
+ return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Capabilities does not match timer count: cTimers=%#x caps=%#x"),
+ cTimers, (unsigned)HPET_CAP_GET_TIMERS(u64CapPer));
+ pThis->u32Capabilities = RT_LO_U32(u64CapPer);
+ pThis->u32Period = RT_HI_U32(u64CapPer);
- /** @todo: is it correct? */
- if (!!(pTimer->u64Config & HPET_TN_ENABLE) &&
- !!(pThis->u64HpetConfig & HPET_CFG_ENABLE))
+ /*
+ * Set the timer frequency hints.
+ */
+ PDMCritSectEnter(&pThis->csLock, VERR_IGNORED);
+ for (uint32_t iTimer = 0; iTimer < cTimers; iTimer++)
{
- Log4(("HPET: raising IRQ %d\n", irq));
-
- /* ISR bits are only set in level-triggered mode */
- if ((pTimer->u64Config & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_LEVEL)
- pThis->u64Isr |= (uint64_t)(1 << pTimer->u8TimerNumber);
-
- /* We trigger flip/flop in edge-triggered mode and do nothing in level-triggered mode yet */
- if ((pTimer->u64Config & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_EDGE)
- pThis->pHpetHlpR3->pfnSetIrq(pThis->CTX_SUFF(pDevIns), irq, PDM_IRQ_LEVEL_FLIP_FLOP);
- else
- Assert(false);
- /* @todo: implement IRQs in level-triggered mode */
+ HpetTimer *pHpetTimer = &pThis->aTimers[iTimer];
+ if (TMTimerIsActive(pHpetTimer->CTX_SUFF(pTimer)))
+ hpetTimerSetFrequencyHint(pThis, pHpetTimer);
}
+ PDMCritSectLeave(&pThis->csLock);
+ return VINF_SUCCESS;
}
-/**
- * Device timer callback function.
- *
- * @param pDevIns Device instance of the device which registered the timer.
- * @param pTimer The timer handle.
- * @param pvUser Pointer to the HPET timer state.
- */
-static DECLCALLBACK(void) hpetTimer(PPDMDEVINS pDevIns,
- PTMTIMER pTmTimer,
- void * pvUser)
-{
- HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
- HpetTimer *pTimer = (HpetTimer *)pvUser;
- uint64_t u64Period = pTimer->u64Period;
- uint64_t u64CurTick = hpetGetTicks(pThis);
- uint64_t u64Diff;
- int rc;
-
- if (pTimer == NULL)
- return;
-
- /* Lock in R3 must either block or succeed */
- rc = hpetLock(pThis, VERR_IGNORED);
-
- AssertLogRelRCReturnVoid(rc);
- if ((pTimer->u64Config & HPET_TN_PERIODIC) && (u64Period != 0))
- {
- hpetAdjustComparator(pTimer, u64CurTick);
-
- u64Diff = hpetComputeDiff(pTimer, u64CurTick);
+/* -=-=-=-=-=- PDMDEVREG -=-=-=-=-=- */
- Log4(("HPET: periodical: next in %lld\n", hpetTicksToNs(u64Diff)));
- TMTimerSetNano(pTmTimer, hpetTicksToNs(u64Diff));
- }
- else if ((pTimer->u64Config & HPET_TN_32BIT) &&
- !(pTimer->u64Config & HPET_TN_PERIODIC))
- {
- if (pTimer->u8Wrap)
- {
- u64Diff = hpetComputeDiff(pTimer, u64CurTick);
- TMTimerSetNano(pTmTimer, hpetTicksToNs(u64Diff));
- pTimer->u8Wrap = 0;
- }
- }
-
- /* Should it really be under lock, does it really matter? */
- hpetIrqUpdate(pTimer);
-
- hpetUnlock(pThis);
-}
/**
- * Relocation notification.
- *
- * @returns VBox status.
- * @param pDevIns The device instance data.
- * @param offDelta The delta relative to the old address.
+ * @interface_method_impl{PDMDEVREG,pfnRelocate}
*/
static DECLCALLBACK(void) hpetRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
{
HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
- unsigned i;
LogFlow(("hpetRelocate:\n"));
pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
pThis->pHpetHlpRC = pThis->pHpetHlpR3->pfnGetRCHelpers(pDevIns);
- for (i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
+ for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
{
HpetTimer *pTm = &pThis->aTimers[i];
if (pTm->pTimerR3)
@@ -1092,119 +1290,68 @@ static DECLCALLBACK(void) hpetRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
}
}
+
/**
- * Reset notification.
- *
- * @returns VBox status.
- * @param pDevIns The device instance data.
+ * @interface_method_impl{PDMDEVREG,pfnReset}
*/
static DECLCALLBACK(void) hpetReset(PPDMDEVINS pDevIns)
{
HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
- unsigned i;
-
LogFlow(("hpetReset:\n"));
- pThis->u64HpetConfig = 0;
- for (i = 0; i < HPET_NUM_TIMERS; i++)
+ /*
+ * The timers first.
+ */
+ TMTimerLock(pThis->aTimers[0].pTimerR3, VERR_IGNORED);
+ for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
{
- HpetTimer *pTimer = &pThis->aTimers[i];
- pTimer->u8TimerNumber = i;
- pTimer->u64Cmp = ~0ULL;
+ HpetTimer *pHpetTimer = &pThis->aTimers[i];
+ Assert(pHpetTimer->idxTimer == i);
+ TMTimerStop(pHpetTimer->pTimerR3);
+
/* capable of periodic operations and 64-bits */
- pTimer->u64Config = HPET_TN_PERIODIC_CAP | HPET_TN_SIZE_CAP;
+ if (pThis->fIch9)
+ pHpetTimer->u64Config = (i == 0)
+ ? (HPET_TN_PERIODIC_CAP | HPET_TN_SIZE_CAP)
+ : 0;
+ else
+ pHpetTimer->u64Config = HPET_TN_PERIODIC_CAP | HPET_TN_SIZE_CAP;
+
/* We can do all IRQs */
uint32_t u32RoutingCap = 0xffffffff;
- pTimer->u64Config |= ((uint64_t)u32RoutingCap) << 32;
- pTimer->u64Period = 0ULL;
- pTimer->u8Wrap = 0;
+ pHpetTimer->u64Config |= ((uint64_t)u32RoutingCap) << 32;
+ pHpetTimer->u64Period = 0;
+ pHpetTimer->u8Wrap = 0;
+ pHpetTimer->u64Cmp = hpetInvalidValue(pHpetTimer);
}
- pThis->u64HpetCounter = 0ULL;
- pThis->u64HpetOffset = 0ULL;
- /* 64-bit main counter; 3 timers supported; LegacyReplacementRoute. */
- uint32_t u32Vendor = 0x8086;
- uint32_t u32Caps =
- (1 << 15) /* LEG_RT_CAP, LegacyReplacementRoute capable */ |
- (1 << 13) /* COUNTER_SIZE_CAP, main counter is 64-bit capable */ |
- ((HPET_NUM_TIMERS-1) << 8) /* NUM_TIM_CAP, number of timers -1 */ |
- 1 /* REV_ID, revision, must not be 0 */;
- pThis->u64Capabilities = (u32Vendor << 16) | u32Caps;
- pThis->u64Capabilities |= ((uint64_t)(HPET_CLK_PERIOD) << 32);
-
- /* Notify PIT/RTC devices */
- hpetLegacyMode(pThis, false);
-}
+ TMTimerUnlock(pThis->aTimers[0].pTimerR3);
-/**
- * Initialization routine.
- *
- * @returns VBox status.
- * @param pDevIns The device instance data.
- */
-static int hpetInit(PPDMDEVINS pDevIns)
-{
- unsigned i;
- int rc;
- HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
-
- memset(pThis, 0, sizeof(*pThis));
-
- pThis->pDevInsR3 = pDevIns;
- pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
- pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
-
- for (i = 0; i < HPET_NUM_TIMERS; i++)
- {
- HpetTimer *timer = &pThis->aTimers[i];
-
- timer->pHpetR3 = pThis;
- timer->pHpetR0 = PDMINS_2_DATA_R0PTR(pDevIns);
- timer->pHpetRC = PDMINS_2_DATA_RCPTR(pDevIns);
-
- rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hpetTimer, timer,
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "HPET Timer",
- &pThis->aTimers[i].pTimerR3);
- if (RT_FAILURE(rc))
- return rc;
- pThis->aTimers[i].pTimerRC = TMTimerRCPtr(pThis->aTimers[i].pTimerR3);
- pThis->aTimers[i].pTimerR0 = TMTimerR0Ptr(pThis->aTimers[i].pTimerR3);
- }
-
- hpetReset(pDevIns);
+ /*
+ * The HPET state.
+ */
+ pThis->u64HpetConfig = 0;
+ pThis->u64HpetCounter = 0;
+ pThis->u64HpetOffset = 0;
- return VINF_SUCCESS;
-}
+ /* 64-bit main counter; 3 timers supported; LegacyReplacementRoute. */
+ pThis->u32Capabilities = (1 << 15) /* LEG_RT_CAP - LegacyReplacementRoute capable. */
+ | (1 << 13) /* COUNTER_SIZE_CAP - Main counter is 64-bit capable. */
+ | 1; /* REV_ID - Revision, must not be 0 */
+ if (pThis->fIch9) /* NUM_TIM_CAP - Number of timers -1. */
+ pThis->u32Capabilities |= (HPET_NUM_TIMERS_ICH9 - 1) << 8;
+ else
+ pThis->u32Capabilities |= (HPET_NUM_TIMERS_PIIX - 1) << 8;
+ pThis->u32Capabilities |= UINT32_C(0x80860000); /* VENDOR */
+ AssertCompile(HPET_NUM_TIMERS_ICH9 <= RT_ELEMENTS(pThis->aTimers));
+ AssertCompile(HPET_NUM_TIMERS_PIIX <= RT_ELEMENTS(pThis->aTimers));
-/**
- * Info handler, device version.
- *
- * @param pDevIns Device instance which registered the info.
- * @param pHlp Callback functions for doing output.
- * @param pszArgs Argument string. Optional and specific to the handler.
- */
-static DECLCALLBACK(void) hpetInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
-{
- HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
- int i;
+ pThis->u32Period = pThis->fIch9 ? HPET_CLK_PERIOD_ICH9 : HPET_CLK_PERIOD_PIIX;
- pHlp->pfnPrintf(pHlp,
- "HPET status:\n"
- " config = %016RX64\n"
- " offset = %016RX64 counter = %016RX64 isr = %016RX64\n"
- " legacy mode is %s\n",
- pThis->u64HpetConfig,
- pThis->u64HpetOffset, pThis->u64HpetCounter, pThis->u64Isr,
- !!(pThis->u64HpetConfig & HPET_CFG_LEGACY) ? "on" : "off");
- pHlp->pfnPrintf(pHlp,
- "Timers:\n");
- for (i = 0; i < HPET_NUM_TIMERS; i++)
- {
- pHlp->pfnPrintf(pHlp, " %d: comparator=%016RX64 period(hidden)=%016RX64 cfg=%016RX64\n",
- pThis->aTimers[i].u8TimerNumber,
- pThis->aTimers[i].u64Cmp,
- pThis->aTimers[i].u64Period,
- pThis->aTimers[i].u64Config);
- }
+ /*
+ * Notify the PIT/RTC devices.
+ */
+ if (pThis->pHpetHlpR3)
+ pThis->pHpetHlpR3->pfnSetLegacyMode(pDevIns, false /*fActive*/);
}
@@ -1213,57 +1360,78 @@ static DECLCALLBACK(void) hpetInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const
*/
static DECLCALLBACK(int) hpetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
{
+ PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
- int rc;
- bool fRCEnabled = false;
- bool fR0Enabled = false;
- PDMHPETREG HpetReg;
- /* Only one HPET device now */
+ /* Only one HPET device now, as we use fixed MMIO region. */
Assert(iInstance == 0);
/*
- * Validate configuration.
+ * Validate and read the configuration.
*/
- if (!CFGMR3AreValuesValid(pCfg, "GCEnabled\0" "R0Enabled\0"))
- return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
+ PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "GCEnabled|R0Enabled|ICH9", "");
- /* Query configuration. */
- rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fRCEnabled, true);
+ bool fRCEnabled;
+ int rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fRCEnabled, true);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Querying \"GCEnabled\" as a bool failed"));
+ bool fR0Enabled;
rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &fR0Enabled, true);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: failed to read R0Enabled as boolean"));
- /* Initialize the device state */
- rc = hpetInit(pDevIns);
+
+ rc = CFGMR3QueryBoolDef(pCfg, "ICH9", &pThis->fIch9, false);
if (RT_FAILURE(rc))
- return rc;
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("Configuration error: failed to read ICH9 as boolean"));
+ /*
+ * Initialize the device state.
+ */
pThis->pDevInsR3 = pDevIns;
pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
- /*
- * Register the HPET and get helpers.
- */
- HpetReg.u32Version = PDM_HPETREG_VERSION;
- rc = PDMDevHlpHPETRegister(pDevIns, &HpetReg, &pThis->pHpetHlpR3);
- if (RT_FAILURE(rc))
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->csLock, RT_SRC_POS, "HPET#%u", pDevIns->iInstance);
+ AssertRCReturn(rc, rc);
+
+ /* No automatic locking. */
+ rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
+ AssertRCReturn(rc, rc);
+
+ /* Init the HPET timers (init all regardless of how many we expose). */
+ for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
{
- AssertMsgRC(rc, ("Cannot HPETRegister: %Rrc\n", rc));
- return rc;
+ HpetTimer *pHpetTimer = &pThis->aTimers[i];
+
+ pHpetTimer->idxTimer = i;
+ pHpetTimer->pHpetR3 = pThis;
+ pHpetTimer->pHpetR0 = PDMINS_2_DATA_R0PTR(pDevIns);
+ pHpetTimer->pHpetRC = PDMINS_2_DATA_RCPTR(pDevIns);
+
+ rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hpetTimerCb, pHpetTimer,
+ TMTIMER_FLAGS_NO_CRIT_SECT, "HPET Timer",
+ &pThis->aTimers[i].pTimerR3);
+ AssertRCReturn(rc, rc);
+ pThis->aTimers[i].pTimerRC = TMTimerRCPtr(pThis->aTimers[i].pTimerR3);
+ pThis->aTimers[i].pTimerR0 = TMTimerR0Ptr(pThis->aTimers[i].pTimerR3);
+ rc = TMR3TimerSetCritSect(pThis->aTimers[i].pTimerR3, &pThis->csLock);
+ AssertRCReturn(rc, rc);
}
+ /* This must be done prior to registering the HPET, right? */
+ hpetReset(pDevIns);
+
/*
- * Initialize critical section.
+ * Register the HPET and get helpers.
*/
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->csLock, RT_SRC_POS, "HPET");
- if (RT_FAILURE(rc))
- return PDMDEV_SET_ERROR(pDevIns, rc, N_("HPET cannot initialize critical section"));
+ PDMHPETREG HpetReg;
+ HpetReg.u32Version = PDM_HPETREG_VERSION;
+ rc = PDMDevHlpHPETRegister(pDevIns, &HpetReg, &pThis->pHpetHlpR3);
+ AssertRCReturn(rc, rc);
/*
* Register the MMIO range, PDM API requests page aligned
@@ -1271,49 +1439,33 @@ static DECLCALLBACK(int) hpetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
*/
rc = PDMDevHlpMMIORegister(pDevIns, HPET_BASE, 0x1000, pThis,
hpetMMIOWrite, hpetMMIORead, NULL, "HPET Memory");
- if (RT_FAILURE(rc))
- {
- AssertMsgRC(rc, ("Cannot register MMIO: %Rrc\n", rc));
- return rc;
- }
+ AssertRCReturn(rc, rc);
if (fRCEnabled)
{
rc = PDMDevHlpMMIORegisterRC(pDevIns, HPET_BASE, 0x1000, 0,
"hpetMMIOWrite", "hpetMMIORead", NULL);
- if (RT_FAILURE(rc))
- return rc;
+ AssertRCReturn(rc, rc);
pThis->pHpetHlpRC = pThis->pHpetHlpR3->pfnGetRCHelpers(pDevIns);
- if (!pThis->pHpetHlpRC)
- {
- AssertReleaseMsgFailed(("cannot get RC helper\n"));
- return VERR_INTERNAL_ERROR;
- }
+ AssertReturn(pThis->pHpetHlpRC != NIL_RTRCPTR, VERR_INTERNAL_ERROR);
}
+
if (fR0Enabled)
{
rc = PDMDevHlpMMIORegisterR0(pDevIns, HPET_BASE, 0x1000, 0,
"hpetMMIOWrite", "hpetMMIORead", NULL);
- if (RT_FAILURE(rc))
- return rc;
+ AssertRCReturn(rc, rc);
pThis->pHpetHlpR0 = pThis->pHpetHlpR3->pfnGetR0Helpers(pDevIns);
- if (!pThis->pHpetHlpR0)
- {
- AssertReleaseMsgFailed(("cannot get R0 helper\n"));
- return VERR_INTERNAL_ERROR;
- }
+ AssertReturn(pThis->pHpetHlpR0 != NIL_RTR0PTR, VERR_INTERNAL_ERROR);
}
/* Register SSM callbacks */
rc = PDMDevHlpSSMRegister3(pDevIns, HPET_SAVED_STATE_VERSION, sizeof(*pThis), hpetLiveExec, hpetSaveExec, hpetLoadExec);
- if (RT_FAILURE(rc))
- return rc;
+ AssertRCReturn(rc, rc);
- /**
- * @todo Register statistics.
- */
+ /* Register an info callback. */
PDMDevHlpDBGFInfoRegister(pDevIns, "hpet", "Display HPET status. (no arguments)", hpetInfo);
return VINF_SUCCESS;
@@ -1376,5 +1528,5 @@ const PDMDEVREG g_DeviceHPET =
};
#endif /* IN_RING3 */
+#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
-#endif /* VBOX_DEVICE_STRUCT_TESTCASE */
diff --git a/src/VBox/Devices/PC/DevIoApic.cpp b/src/VBox/Devices/PC/DevIoApic.cpp
new file mode 100644
index 000000000..123d7c674
--- /dev/null
+++ b/src/VBox/Devices/PC/DevIoApic.cpp
@@ -0,0 +1,729 @@
+/* $Id: DevIoApic.cpp 37637 2011-06-24 15:06:23Z vboxsync $ */
+/** @file
+ * I/O Advanced Programmable Interrupt Controller (IO-APIC) Device.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on:
+ *
+ * apic.c revision 1.5 @@OSETODO
+ *
+ * APIC support
+ *
+ * Copyright (c) 2004-2005 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_DEV_APIC
+#include <VBox/vmm/pdmdev.h>
+
+#include <VBox/log.h>
+#include <VBox/vmm/stam.h>
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+
+#include <VBox/msi.h>
+
+#include "VBoxDD2.h"
+#include "DevApic.h"
+
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+/** @def IOAPIC_LOCK
+ * Acquires the PDM lock. */
+#define IOAPIC_LOCK(pThis, rc) \
+ do { \
+ int rc2 = (pThis)->CTX_SUFF(pIoApicHlp)->pfnLock((pThis)->CTX_SUFF(pDevIns), rc); \
+ if (rc2 != VINF_SUCCESS) \
+ return rc2; \
+ } while (0)
+
+/** @def IOAPIC_UNLOCK
+ * Releases the PDM lock. */
+#define IOAPIC_UNLOCK(pThis) (pThis)->CTX_SUFF(pIoApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns))
+
+
+#define foreach_apic(pDev, mask, code) \
+ do { \
+ APICState *apic = (pDev)->CTX_SUFF(paLapics); \
+ for (uint32_t i = 0; i < (pDev)->cCpus; i++) \
+ { \
+ if (mask & (1 << (apic->id))) \
+ { \
+ code; \
+ } \
+ apic++; \
+ } \
+ } while (0)
+
+# define set_bit(pvBitmap, iBit) ASMBitSet(pvBitmap, iBit)
+# define reset_bit(pvBitmap, iBit) ASMBitClear(pvBitmap, iBit)
+# define fls_bit(value) (ASMBitLastSetU32(value) - 1)
+# define ffs_bit(value) (ASMBitFirstSetU32(value) - 1)
+
+#define DEBUG_IOAPIC
+#define IOAPIC_NUM_PINS 0x18
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+struct IOAPICState {
+ uint8_t id;
+ uint8_t ioregsel;
+
+ uint32_t irr;
+ uint64_t ioredtbl[IOAPIC_NUM_PINS];
+
+ /** The device instance - R3 Ptr. */
+ PPDMDEVINSR3 pDevInsR3;
+ /** The IOAPIC helpers - R3 Ptr. */
+ PCPDMIOAPICHLPR3 pIoApicHlpR3;
+
+ /** The device instance - R0 Ptr. */
+ PPDMDEVINSR0 pDevInsR0;
+ /** The IOAPIC helpers - R0 Ptr. */
+ PCPDMIOAPICHLPR0 pIoApicHlpR0;
+
+ /** The device instance - RC Ptr. */
+ PPDMDEVINSRC pDevInsRC;
+ /** The IOAPIC helpers - RC Ptr. */
+ PCPDMIOAPICHLPRC pIoApicHlpRC;
+
+# ifdef VBOX_WITH_STATISTICS
+ STAMCOUNTER StatMMIOReadGC;
+ STAMCOUNTER StatMMIOReadHC;
+ STAMCOUNTER StatMMIOWriteGC;
+ STAMCOUNTER StatMMIOWriteHC;
+ STAMCOUNTER StatSetIrqGC;
+ STAMCOUNTER StatSetIrqHC;
+# endif
+};
+
+typedef struct IOAPICState IOAPICState;
+
+#ifndef VBOX_DEVICE_STRUCT_TESTCASE
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+
+
+static void ioapic_service(IOAPICState *s)
+{
+ uint8_t i;
+ uint8_t trig_mode;
+ uint8_t vector;
+ uint8_t delivery_mode;
+ uint32_t mask;
+ uint64_t entry;
+ uint8_t dest;
+ uint8_t dest_mode;
+ uint8_t polarity;
+
+ for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+ mask = 1 << i;
+ if (s->irr & mask) {
+ entry = s->ioredtbl[i];
+ if (!(entry & APIC_LVT_MASKED)) {
+ trig_mode = ((entry >> 15) & 1);
+ dest = entry >> 56;
+ dest_mode = (entry >> 11) & 1;
+ delivery_mode = (entry >> 8) & 7;
+ polarity = (entry >> 13) & 1;
+ if (trig_mode == APIC_TRIGGER_EDGE)
+ s->irr &= ~mask;
+ if (delivery_mode == APIC_DM_EXTINT)
+ /* malc: i'm still not so sure about ExtINT delivery */
+ {
+ AssertMsgFailed(("Delivery mode ExtINT"));
+ vector = 0xff; /* incorrect but shuts up gcc. */
+ }
+ else
+ vector = entry & 0xff;
+
+ int rc = s->CTX_SUFF(pIoApicHlp)->pfnApicBusDeliver(s->CTX_SUFF(pDevIns),
+ dest,
+ dest_mode,
+ delivery_mode,
+ vector,
+ polarity,
+ trig_mode);
+ /* We must be sure that attempts to reschedule in R3
+ never get here */
+ Assert(rc == VINF_SUCCESS);
+ }
+ }
+ }
+}
+
+
+static void ioapic_set_irq(void *opaque, int vector, int level)
+{
+ IOAPICState *s = (IOAPICState*)opaque;
+
+ if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
+ uint32_t mask = 1 << vector;
+ uint64_t entry = s->ioredtbl[vector];
+
+ if ((entry >> 15) & 1) {
+ /* level triggered */
+ if (level) {
+ s->irr |= mask;
+ ioapic_service(s);
+ if ((level & PDM_IRQ_LEVEL_FLIP_FLOP) == PDM_IRQ_LEVEL_FLIP_FLOP) {
+ s->irr &= ~mask;
+ }
+ } else {
+ s->irr &= ~mask;
+ }
+ } else {
+ /* edge triggered */
+ if (level) {
+ s->irr |= mask;
+ ioapic_service(s);
+ }
+ }
+ }
+}
+
+static uint32_t ioapic_mem_readl(void *opaque, RTGCPHYS addr)
+{
+ IOAPICState *s = (IOAPICState*)opaque;
+ int index;
+ uint32_t val = 0;
+
+ addr &= 0xff;
+ if (addr == 0x00) {
+ val = s->ioregsel;
+ } else if (addr == 0x10) {
+ switch (s->ioregsel) {
+ case 0x00:
+ val = s->id << 24;
+ break;
+ case 0x01:
+ val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */
+ break;
+ case 0x02:
+ val = 0;
+ break;
+ default:
+ index = (s->ioregsel - 0x10) >> 1;
+ if (index >= 0 && index < IOAPIC_NUM_PINS) {
+ if (s->ioregsel & 1)
+ val = s->ioredtbl[index] >> 32;
+ else
+ val = s->ioredtbl[index] & 0xffffffff;
+ }
+ }
+#ifdef DEBUG_IOAPIC
+ Log(("I/O APIC read: %08x = %08x\n", s->ioregsel, val));
+#endif
+ }
+ return val;
+}
+
+static void ioapic_mem_writel(void *opaque, RTGCPHYS addr, uint32_t val)
+{
+ IOAPICState *s = (IOAPICState*)opaque;
+ int index;
+
+ addr &= 0xff;
+ if (addr == 0x00) {
+ s->ioregsel = val;
+ return;
+ } else if (addr == 0x10) {
+#ifdef DEBUG_IOAPIC
+ Log(("I/O APIC write: %08x = %08x\n", s->ioregsel, val));
+#endif
+ switch (s->ioregsel) {
+ case 0x00:
+ s->id = (val >> 24) & 0xff;
+ return;
+ case 0x01:
+ case 0x02:
+ return;
+ default:
+ index = (s->ioregsel - 0x10) >> 1;
+ if (index >= 0 && index < IOAPIC_NUM_PINS) {
+ if (s->ioregsel & 1) {
+ s->ioredtbl[index] &= 0xffffffff;
+ s->ioredtbl[index] |= (uint64_t)val << 32;
+ } else {
+ /* According to IOAPIC spec, vectors should be from 0x10 to 0xfe */
+ uint8_t vec = val & 0xff;
+ if ((val & APIC_LVT_MASKED) ||
+ ((vec >= 0x10) && (vec < 0xff)))
+ {
+ s->ioredtbl[index] &= ~0xffffffffULL;
+ s->ioredtbl[index] |= val;
+ }
+ else
+ {
+ /*
+ * Linux 2.6 kernels has pretty strange function
+ * unlock_ExtINT_logic() which writes
+ * absolutely bogus (all 0) value into the vector
+ * with pretty vague explanation why.
+ * So we just ignore such writes.
+ */
+ LogRel(("IOAPIC GUEST BUG: bad vector writing %x(sel=%x) to %d\n", val, s->ioregsel, index));
+ }
+ }
+ ioapic_service(s);
+ }
+ }
+ }
+}
+
+#ifdef IN_RING3
+
+static void ioapic_save(SSMHANDLE *f, void *opaque)
+{
+ IOAPICState *s = (IOAPICState*)opaque;
+ int i;
+
+ SSMR3PutU8(f, s->id);
+ SSMR3PutU8(f, s->ioregsel);
+ for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+ SSMR3PutU64(f, s->ioredtbl[i]);
+ }
+}
+
+static int ioapic_load(SSMHANDLE *f, void *opaque, int version_id)
+{
+ IOAPICState *s = (IOAPICState*)opaque;
+ int i;
+
+ if (version_id != 1)
+ return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
+
+ SSMR3GetU8(f, &s->id);
+ SSMR3GetU8(f, &s->ioregsel);
+ for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+ SSMR3GetU64(f, &s->ioredtbl[i]);
+ }
+ return 0;
+}
+
+static void ioapic_reset(void *opaque)
+{
+ IOAPICState *s = (IOAPICState*)opaque;
+ PPDMDEVINSR3 pDevIns = s->pDevInsR3;
+ PCPDMIOAPICHLPR3 pIoApicHlp = s->pIoApicHlpR3;
+ int i;
+
+ memset(s, 0, sizeof(*s));
+ for(i = 0; i < IOAPIC_NUM_PINS; i++)
+ s->ioredtbl[i] = 1 << 16; /* mask LVT */
+
+ if (pDevIns)
+ {
+ s->pDevInsR3 = pDevIns;
+ s->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+ s->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
+ }
+ if (pIoApicHlp)
+ {
+ s->pIoApicHlpR3 = pIoApicHlp;
+ s->pIoApicHlpRC = s->pIoApicHlpR3->pfnGetRCHelpers(pDevIns);
+ s->pIoApicHlpR0 = s->pIoApicHlpR3->pfnGetR0Helpers(pDevIns);
+ }
+}
+
+#endif /* IN_RING3 */
+
+
+/* IOAPIC */
+
+PDMBOTHCBDECL(int) ioapicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+{
+ IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
+ IOAPIC_LOCK(s, VINF_IOM_HC_MMIO_READ);
+
+ STAM_COUNTER_INC(&CTXSUFF(s->StatMMIORead));
+ switch (cb) {
+ case 1:
+ *(uint8_t *)pv = ioapic_mem_readl(s, GCPhysAddr);
+ break;
+
+ case 2:
+ *(uint16_t *)pv = ioapic_mem_readl(s, GCPhysAddr);
+ break;
+
+ case 4:
+ *(uint32_t *)pv = ioapic_mem_readl(s, GCPhysAddr);
+ break;
+
+ default:
+ AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
+ IOAPIC_UNLOCK(s);
+ return VERR_INTERNAL_ERROR;
+ }
+ IOAPIC_UNLOCK(s);
+ return VINF_SUCCESS;
+}
+
+PDMBOTHCBDECL(int) ioapicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
+{
+ IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
+
+ STAM_COUNTER_INC(&CTXSUFF(s->StatMMIOWrite));
+ IOAPIC_LOCK(s, VINF_IOM_HC_MMIO_WRITE);
+ switch (cb)
+ {
+ case 1: ioapic_mem_writel(s, GCPhysAddr, *(uint8_t const *)pv); break;
+ case 2: ioapic_mem_writel(s, GCPhysAddr, *(uint16_t const *)pv); break;
+ case 4: ioapic_mem_writel(s, GCPhysAddr, *(uint32_t const *)pv); break;
+
+ default:
+ IOAPIC_UNLOCK(s);
+ AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
+ return VERR_INTERNAL_ERROR;
+ }
+ IOAPIC_UNLOCK(s);
+ return VINF_SUCCESS;
+}
+
+PDMBOTHCBDECL(void) ioapicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+ /* PDM lock is taken here; @todo add assertion */
+ IOAPICState *pThis = PDMINS_2_DATA(pDevIns, IOAPICState *);
+ STAM_COUNTER_INC(&pThis->CTXSUFF(StatSetIrq));
+ LogFlow(("ioapicSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
+ ioapic_set_irq(pThis, iIrq, iLevel);
+}
+
+PDMBOTHCBDECL(void) ioapicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue)
+{
+ IOAPICState *pThis = PDMINS_2_DATA(pDevIns, IOAPICState *);
+
+ LogFlow(("ioapicSendMsi: Address=%p uValue=%\n", GCAddr, uValue));
+
+ uint8_t dest = (GCAddr & VBOX_MSI_ADDR_DEST_ID_MASK) >> VBOX_MSI_ADDR_DEST_ID_SHIFT;
+ uint8_t vector_num = (uValue & VBOX_MSI_DATA_VECTOR_MASK) >> VBOX_MSI_DATA_VECTOR_SHIFT;
+ uint8_t dest_mode = (GCAddr >> VBOX_MSI_ADDR_DEST_MODE_SHIFT) & 0x1;
+ uint8_t trigger_mode = (uValue >> VBOX_MSI_DATA_TRIGGER_SHIFT) & 0x1;
+ uint8_t delivery_mode = (uValue >> VBOX_MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
+ /**
+ * This bit indicates whether the message should be directed to the
+ * processor with the lowest interrupt priority among
+ * processors that can receive the interrupt, ignored ATM.
+ */
+ uint8_t redir_hint = (GCAddr >> VBOX_MSI_ADDR_REDIRECTION_SHIFT) & 0x1;
+
+ int rc = pThis->CTX_SUFF(pIoApicHlp)->pfnApicBusDeliver(pDevIns,
+ dest,
+ dest_mode,
+ delivery_mode,
+ vector_num,
+ 0 /* polarity, n/a */,
+ trigger_mode);
+ /* We must be sure that attempts to reschedule in R3
+ never get here */
+ Assert(rc == VINF_SUCCESS);
+}
+
+#ifdef IN_RING3
+
+/**
+ * Info handler, device version. Dumps I/O APIC state.
+ *
+ * @param pDevIns Device instance which registered the info.
+ * @param pHlp Callback functions for doing output.
+ * @param pszArgs Argument string. Optional and specific to the handler.
+ */
+static DECLCALLBACK(void) ioapicInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+ IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
+ uint32_t val;
+ unsigned i;
+ unsigned max_redir;
+
+ pHlp->pfnPrintf(pHlp, "I/O APIC at %08X:\n", 0xfec00000);
+ val = s->id << 24; /* Would be nice to call ioapic_mem_readl() directly, but that's not so simple. */
+ pHlp->pfnPrintf(pHlp, " IOAPICID : %08X\n", val);
+ pHlp->pfnPrintf(pHlp, " APIC ID = %02X\n", (val >> 24) & 0xff);
+ val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16);
+ max_redir = (val >> 16) & 0xff;
+ pHlp->pfnPrintf(pHlp, " IOAPICVER : %08X\n", val);
+ pHlp->pfnPrintf(pHlp, " version = %02X\n", val & 0xff);
+ pHlp->pfnPrintf(pHlp, " redirs = %d\n", ((val >> 16) & 0xff) + 1);
+ val = 0;
+ pHlp->pfnPrintf(pHlp, " IOAPICARB : %08X\n", val);
+ pHlp->pfnPrintf(pHlp, " arb ID = %02X\n", (val >> 24) & 0xff);
+ Assert(sizeof(s->ioredtbl) / sizeof(s->ioredtbl[0]) > max_redir);
+ pHlp->pfnPrintf(pHlp, "I/O redirection table\n");
+ pHlp->pfnPrintf(pHlp, " idx dst_mode dst_addr mask trigger rirr polarity dlvr_st dlvr_mode vector\n");
+ for (i = 0; i <= max_redir; ++i)
+ {
+ static const char *dmodes[] = { "Fixed ", "LowPri", "SMI ", "Resrvd",
+ "NMI ", "INIT ", "Resrvd", "ExtINT" };
+
+ pHlp->pfnPrintf(pHlp, " %02d %s %02X %d %s %d %s %s %s %3d (%016llX)\n",
+ i,
+ s->ioredtbl[i] & (1 << 11) ? "log " : "phys", /* dest mode */
+ (int)(s->ioredtbl[i] >> 56), /* dest addr */
+ (int)(s->ioredtbl[i] >> 16) & 1, /* mask */
+ s->ioredtbl[i] & (1 << 15) ? "level" : "edge ", /* trigger */
+ (int)(s->ioredtbl[i] >> 14) & 1, /* remote IRR */
+ s->ioredtbl[i] & (1 << 13) ? "activelo" : "activehi", /* polarity */
+ s->ioredtbl[i] & (1 << 12) ? "pend" : "idle", /* delivery status */
+ dmodes[(s->ioredtbl[i] >> 8) & 0x07], /* delivery mode */
+ (int)s->ioredtbl[i] & 0xff, /* vector */
+ s->ioredtbl[i] /* entire register */
+ );
+ }
+}
+
+/**
+ * @copydoc FNSSMDEVSAVEEXEC
+ */
+static DECLCALLBACK(int) ioapicSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
+{
+ IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
+ ioapic_save(pSSM, s);
+ return VINF_SUCCESS;
+}
+
+/**
+ * @copydoc FNSSMDEVLOADEXEC
+ */
+static DECLCALLBACK(int) ioapicLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
+{
+ IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
+
+ if (ioapic_load(pSSM, s, uVersion)) {
+ AssertFailed();
+ return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
+ }
+ Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * @copydoc FNPDMDEVRESET
+ */
+static DECLCALLBACK(void) ioapicReset(PPDMDEVINS pDevIns)
+{
+ IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
+ s->pIoApicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR);
+ ioapic_reset(s);
+ IOAPIC_UNLOCK(s);
+}
+
+/**
+ * @copydoc FNPDMDEVRELOCATE
+ */
+static DECLCALLBACK(void) ioapicRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
+{
+ IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
+ s->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+ s->pIoApicHlpRC = s->pIoApicHlpR3->pfnGetRCHelpers(pDevIns);
+}
+
+/**
+ * @copydoc FNPDMDEVCONSTRUCT
+ */
+static DECLCALLBACK(int) ioapicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
+{
+ IOAPICState *s = PDMINS_2_DATA(pDevIns, IOAPICState *);
+ PDMIOAPICREG IoApicReg;
+ bool fGCEnabled;
+ bool fR0Enabled;
+ int rc;
+ uint32_t cCpus;
+
+ Assert(iInstance == 0);
+
+ /*
+ * Validate and read the configuration.
+ */
+ if (!CFGMR3AreValuesValid(pCfg,
+ "GCEnabled\0"
+ "R0Enabled\0"
+ "NumCPUs\0"))
+ return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
+
+ rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fGCEnabled, true);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("Configuration error: Failed to query boolean value \"GCEnabled\""));
+
+ rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &fR0Enabled, true);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("Configuration error: Failed to query boolean value \"R0Enabled\""));
+
+ rc = CFGMR3QueryU32Def(pCfg, "NumCPUs", &cCpus, 1);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("Configuration error: Failed to query integer value \"NumCPUs\""));
+
+ Log(("IOAPIC: fR0Enabled=%RTbool fGCEnabled=%RTbool\n", fR0Enabled, fGCEnabled));
+
+ /*
+ * Initialize the state data.
+ */
+
+ s->pDevInsR3 = pDevIns;
+ s->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
+ s->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+ ioapic_reset(s);
+ s->id = cCpus;
+
+ /*
+ * Register the IOAPIC and get helpers.
+ */
+ IoApicReg.u32Version = PDM_IOAPICREG_VERSION;
+ IoApicReg.pfnSetIrqR3 = ioapicSetIrq;
+ IoApicReg.pszSetIrqRC = fGCEnabled ? "ioapicSetIrq" : NULL;
+ IoApicReg.pszSetIrqR0 = fR0Enabled ? "ioapicSetIrq" : NULL;
+ IoApicReg.pfnSendMsiR3 = ioapicSendMsi;
+ IoApicReg.pszSendMsiRC = fGCEnabled ? "ioapicSendMsi" : NULL;
+ IoApicReg.pszSendMsiR0 = fR0Enabled ? "ioapicSendMsi" : NULL;
+
+ rc = PDMDevHlpIOAPICRegister(pDevIns, &IoApicReg, &s->pIoApicHlpR3);
+ if (RT_FAILURE(rc))
+ {
+ AssertMsgFailed(("IOAPICRegister -> %Rrc\n", rc));
+ return rc;
+ }
+
+ /*
+ * Register MMIO callbacks and saved state.
+ */
+ rc = PDMDevHlpMMIORegister(pDevIns, 0xfec00000, 0x1000, s,
+ ioapicMMIOWrite, ioapicMMIORead, NULL, "I/O APIC Memory");
+ if (RT_FAILURE(rc))
+ return rc;
+
+ if (fGCEnabled) {
+ s->pIoApicHlpRC = s->pIoApicHlpR3->pfnGetRCHelpers(pDevIns);
+
+ rc = PDMDevHlpMMIORegisterRC(pDevIns, 0xfec00000, 0x1000, 0,
+ "ioapicMMIOWrite", "ioapicMMIORead", NULL);
+ if (RT_FAILURE(rc))
+ return rc;
+ }
+
+ if (fR0Enabled) {
+ s->pIoApicHlpR0 = s->pIoApicHlpR3->pfnGetR0Helpers(pDevIns);
+
+ rc = PDMDevHlpMMIORegisterR0(pDevIns, 0xfec00000, 0x1000, 0,
+ "ioapicMMIOWrite", "ioapicMMIORead", NULL);
+ if (RT_FAILURE(rc))
+ return rc;
+ }
+
+ rc = PDMDevHlpSSMRegister(pDevIns, 1 /* version */, sizeof(*s), ioapicSaveExec, ioapicLoadExec);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ /*
+ * Register debugger info callback.
+ */
+ PDMDevHlpDBGFInfoRegister(pDevIns, "ioapic", "Display I/O APIC state.", ioapicInfo);
+
+#ifdef VBOX_WITH_STATISTICS
+ /*
+ * Statistics.
+ */
+ PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOReadGC, STAMTYPE_COUNTER, "/Devices/IOAPIC/MMIOReadGC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO reads in GC.");
+ PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOReadHC, STAMTYPE_COUNTER, "/Devices/IOAPIC/MMIOReadHC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO reads in HC.");
+ PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOWriteGC, STAMTYPE_COUNTER, "/Devices/IOAPIC/MMIOWriteGC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO writes in GC.");
+ PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOWriteHC, STAMTYPE_COUNTER, "/Devices/IOAPIC/MMIOWriteHC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO writes in HC.");
+ PDMDevHlpSTAMRegister(pDevIns, &s->StatSetIrqGC, STAMTYPE_COUNTER, "/Devices/IOAPIC/SetIrqGC", STAMUNIT_OCCURENCES, "Number of IOAPIC SetIrq calls in GC.");
+ PDMDevHlpSTAMRegister(pDevIns, &s->StatSetIrqHC, STAMTYPE_COUNTER, "/Devices/IOAPIC/SetIrqHC", STAMUNIT_OCCURENCES, "Number of IOAPIC SetIrq calls in HC.");
+#endif
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * IO APIC device registration structure.
+ */
+const PDMDEVREG g_DeviceIOAPIC =
+{
+ /* u32Version */
+ PDM_DEVREG_VERSION,
+ /* szName */
+ "ioapic",
+ /* szRCMod */
+ "VBoxDD2GC.gc",
+ /* szR0Mod */
+ "VBoxDD2R0.r0",
+ /* pszDescription */
+ "I/O Advanced Programmable Interrupt Controller (IO-APIC) Device",
+ /* fFlags */
+ PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+ /* fClass */
+ PDM_DEVREG_CLASS_PIC,
+ /* cMaxInstances */
+ 1,
+ /* cbInstance */
+ sizeof(IOAPICState),
+ /* pfnConstruct */
+ ioapicConstruct,
+ /* pfnDestruct */
+ NULL,
+ /* pfnRelocate */
+ ioapicRelocate,
+ /* pfnIOCtl */
+ NULL,
+ /* pfnPowerOn */
+ NULL,
+ /* pfnReset */
+ ioapicReset,
+ /* pfnSuspend */
+ NULL,
+ /* pfnResume */
+ NULL,
+ /* pfnAttach */
+ NULL,
+ /* pfnDetach */
+ NULL,
+ /* pfnQueryInterface. */
+ NULL,
+ /* pfnInitComplete */
+ NULL,
+ /* pfnPowerOff */
+ NULL,
+ /* pfnSoftReset */
+ NULL,
+ /* u32VersionEnd */
+ PDM_DEVREG_VERSION
+};
+
+#endif /* IN_RING3 */
+#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
diff --git a/src/VBox/Devices/PC/DevLPC.cpp b/src/VBox/Devices/PC/DevLPC.cpp
index 00a2ecc2e..6bcee81f1 100644
--- a/src/VBox/Devices/PC/DevLPC.cpp
+++ b/src/VBox/Devices/PC/DevLPC.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevLPC.cpp $ */
+/* $Id: DevLPC.cpp 37636 2011-06-24 14:59:59Z vboxsync $ */
/** @file
* DevLPC - LPC device emulation
*/
@@ -160,7 +160,7 @@ PDMBOTHCBDECL(int) lpcMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhy
* @param cb Number of bytes to write.
* @thread EMT
*/
-PDMBOTHCBDECL(int) lpcMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+PDMBOTHCBDECL(int) lpcMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
LPCState *s = PDMINS_2_DATA(pDevIns, LPCState*);
diff --git a/src/VBox/Devices/PC/DevPIC.cpp b/src/VBox/Devices/PC/DevPIC.cpp
index 6a138e70c..ce7f0a56a 100644
--- a/src/VBox/Devices/PC/DevPIC.cpp
+++ b/src/VBox/Devices/PC/DevPIC.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevPIC.cpp $ */
+/* $Id: DevPIC.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
* DevPIC - Intel 8259 Programmable Interrupt Controller (PIC) Device.
*/
@@ -611,7 +611,7 @@ static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
if (addr1 >> 7 || ret != 2)
pic_update_irq(pThis);
} else {
- ret = 0x07;
+ ret = 0;
pic_update_irq(pThis);
}
@@ -774,23 +774,20 @@ static DECLCALLBACK(void) picInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const
*/
for (int i=0;i<2;i++)
{
+ PicState *pPic;
+
+ pPic = &pThis->aPics[i];
pHlp->pfnPrintf(pHlp, "PIC%d:\n", i);
- pHlp->pfnPrintf(pHlp, " last_irr = %02x\n", pThis->aPics[i].last_irr);
- pHlp->pfnPrintf(pHlp, " irr = %02x\n", pThis->aPics[i].irr);
- pHlp->pfnPrintf(pHlp, " imr = %02x\n", pThis->aPics[i].imr);
- pHlp->pfnPrintf(pHlp, " isr = %02x\n", pThis->aPics[i].isr);
- pHlp->pfnPrintf(pHlp, " priority_add = %02x\n", pThis->aPics[i].priority_add);
- pHlp->pfnPrintf(pHlp, " irq_base = %02x\n", pThis->aPics[i].irq_base);
- pHlp->pfnPrintf(pHlp, " read_reg_select = %02x\n", pThis->aPics[i].read_reg_select);
- pHlp->pfnPrintf(pHlp, " poll = %02x\n", pThis->aPics[i].poll);
- pHlp->pfnPrintf(pHlp, " special_mask = %02x\n", pThis->aPics[i].special_mask);
- pHlp->pfnPrintf(pHlp, " init_state = %02x\n", pThis->aPics[i].init_state);
- pHlp->pfnPrintf(pHlp, " auto_eoi = %02x\n", pThis->aPics[i].auto_eoi);
- pHlp->pfnPrintf(pHlp, " rotate_on_auto_eoi = %02x\n", pThis->aPics[i].rotate_on_auto_eoi);
- pHlp->pfnPrintf(pHlp, " special_fully_nested_mode = %02x\n", pThis->aPics[i].special_fully_nested_mode);
- pHlp->pfnPrintf(pHlp, " init4 = %02x\n", pThis->aPics[i].init4);
- pHlp->pfnPrintf(pHlp, " elcr = %02x\n", pThis->aPics[i].elcr);
- pHlp->pfnPrintf(pHlp, " elcr_mask = %02x\n", pThis->aPics[i].elcr_mask);
+ pHlp->pfnPrintf(pHlp, " IMR :%02x ISR :%02x IRR :%02x LIRR:%02x\n",
+ pPic->imr, pPic->isr, pPic->irr, pPic->last_irr);
+ pHlp->pfnPrintf(pHlp, " Base:%02x PriAdd:%02x RegSel:%02x\n",
+ pPic->irq_base, pPic->priority_add, pPic->read_reg_select);
+ pHlp->pfnPrintf(pHlp, " Poll:%02x SpMask:%02x IState:%02x\n",
+ pPic->poll, pPic->special_mask, pPic->init_state);
+ pHlp->pfnPrintf(pHlp, " AEOI:%02x Rotate:%02x FNest :%02x Ini4:%02x\n",
+ pPic->auto_eoi, pPic->rotate_on_auto_eoi,
+ pPic->special_fully_nested_mode, pPic->init4);
+ pHlp->pfnPrintf(pHlp, " ELCR:%02x ELMask:%02x\n", pPic->elcr, pPic->elcr_mask);
}
}
diff --git a/src/VBox/Devices/PC/DevPcArch.c b/src/VBox/Devices/PC/DevPcArch.c
index 6c9ea9a8b..4470cbad6 100644
--- a/src/VBox/Devices/PC/DevPcArch.c
+++ b/src/VBox/Devices/PC/DevPcArch.c
@@ -1,4 +1,4 @@
-/* $Id: DevPcArch.c $ */
+/* $Id: DevPcArch.c 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* DevPcArch - PC Architecture Device.
*/
diff --git a/src/VBox/Devices/PC/DevPcBios.cpp b/src/VBox/Devices/PC/DevPcBios.cpp
index 85d5a831a..18a7d97ff 100644
--- a/src/VBox/Devices/PC/DevPcBios.cpp
+++ b/src/VBox/Devices/PC/DevPcBios.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevPcBios.cpp $ */
+/* $Id: DevPcBios.cpp 37917 2011-07-13 13:25:57Z vboxsync $ */
/** @file
* PC BIOS Device.
*/
@@ -156,7 +156,7 @@ typedef struct DEVPCBIOS
/** The system BIOS ROM data. */
uint8_t *pu8PcBios;
/** The size of the system BIOS ROM. */
- uint64_t cbPcBios;
+ uint32_t cbPcBios;
/** The name of the BIOS ROM file. */
char *pszPcBiosFile;
/** The LAN boot ROM data. */
@@ -1164,84 +1164,68 @@ static DECLCALLBACK(int) pcbiosConstruct(PPDMDEVINS pDevIns, int iInstance, PCF
pThis->pszPcBiosFile = NULL;
}
- const uint8_t *pu8PcBiosBinary = NULL;
- uint64_t cbPcBiosBinary;
- /*
- * Determine the system BIOS ROM size, open specified ROM file in the process.
- */
- RTFILE FilePcBios = NIL_RTFILE;
+ const uint8_t *pu8PcBiosBinary;
+ uint32_t cbPcBiosBinary;
if (pThis->pszPcBiosFile)
{
- rc = RTFileOpen(&FilePcBios, pThis->pszPcBiosFile,
+ /*
+ * Load the BIOS ROM.
+ */
+ RTFILE hFilePcBios;
+ rc = RTFileOpen(&hFilePcBios, pThis->pszPcBiosFile,
RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
if (RT_SUCCESS(rc))
{
- rc = RTFileGetSize(FilePcBios, &pThis->cbPcBios);
+ /* Figure the size and check restrictions. */
+ uint64_t cbPcBios;
+ rc = RTFileGetSize(hFilePcBios, &cbPcBios);
if (RT_SUCCESS(rc))
{
- /* The following checks should be in sync the AssertReleaseMsg's below. */
- if ( RT_ALIGN(pThis->cbPcBios, _64K) != pThis->cbPcBios
- || pThis->cbPcBios > 32 * _64K
- || pThis->cbPcBios < _64K)
- rc = VERR_TOO_MUCH_DATA;
+ pThis->cbPcBios = (uint32_t)cbPcBios;
+ if ( RT_ALIGN(pThis->cbPcBios, _64K) == pThis->cbPcBios
+ && pThis->cbPcBios == cbPcBios
+ && pThis->cbPcBios <= 32 * _64K
+ && pThis->cbPcBios >= _64K)
+ {
+ pThis->pu8PcBios = (uint8_t *)PDMDevHlpMMHeapAlloc(pDevIns, pThis->cbPcBios);
+ if (pThis->pu8PcBios)
+ {
+ rc = RTFileRead(hFilePcBios, pThis->pu8PcBios, pThis->cbPcBios, NULL);
+ if (RT_FAILURE(rc))
+ rc = PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
+ N_("Error reading the BIOS image ('%s)"), pThis->pszPcBiosFile);
+ }
+ else
+ rc = PDMDevHlpVMSetError(pDevIns, VERR_NO_MEMORY, RT_SRC_POS,
+ N_("Failed to allocate %#x bytes for loading the BIOS image"),
+ pThis->cbPcBios);
+ }
+ else
+ rc = PDMDevHlpVMSetError(pDevIns, VERR_OUT_OF_RANGE, RT_SRC_POS,
+ N_("Invalid system BIOS file size ('%s'): %#llx (%llu)"),
+ pThis->pszPcBiosFile, cbPcBios, cbPcBios);
}
+ else
+ rc = PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_("Failed to query the system BIOS file size ('%s')"),
+ pThis->pszPcBiosFile);
+ RTFileClose(hFilePcBios);
}
+ else
+ rc = PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_("Failed to open system BIOS file '%s'"), pThis->pszPcBiosFile);
if (RT_FAILURE(rc))
- {
- /*
- * In case of failure simply fall back to the built-in BIOS ROM.
- */
- Log(("pcbiosConstruct: Failed to open system BIOS ROM file '%s', rc=%Rrc!\n", pThis->pszPcBiosFile, rc));
- RTFileClose(FilePcBios);
- FilePcBios = NIL_RTFILE;
- MMR3HeapFree(pThis->pszPcBiosFile);
- pThis->pszPcBiosFile = NULL;
- }
- }
+ return rc;
- /*
- * Attempt to get the system BIOS ROM data from file.
- */
- if (pThis->pszPcBiosFile)
- {
- /*
- * Allocate buffer for the system BIOS ROM data.
- */
- pThis->pu8PcBios = (uint8_t *)PDMDevHlpMMHeapAlloc(pDevIns, pThis->cbPcBios);
- if (pThis->pu8PcBios)
- {
- rc = RTFileRead(FilePcBios, pThis->pu8PcBios, pThis->cbPcBios, NULL);
- if (RT_FAILURE(rc))
- {
- AssertMsgFailed(("RTFileRead(,,%d,NULL) -> %Rrc\n", pThis->cbPcBios, rc));
- MMR3HeapFree(pThis->pu8PcBios);
- pThis->pu8PcBios = NULL;
- }
- rc = VINF_SUCCESS;
- }
- else
- rc = VERR_NO_MEMORY;
+ pu8PcBiosBinary = pThis->pu8PcBios;
+ cbPcBiosBinary = pThis->cbPcBios;
+ LogRel(("Using BIOS ROM '%s' with a size of %#x bytes\n", pThis->pszPcBiosFile, pThis->cbPcBios));
}
else
- pThis->pu8PcBios = NULL;
-
- /* cleanup */
- if (FilePcBios != NIL_RTFILE)
- RTFileClose(FilePcBios);
-
- /* If we were unable to get the data from file for whatever reason, fall
- back to the built-in ROM image. */
- uint32_t fFlags = 0;
- if (pThis->pu8PcBios == NULL)
{
+ /*
+ * Use the embedded BIOS ROM image.
+ */
pu8PcBiosBinary = g_abPcBiosBinary;
cbPcBiosBinary = g_cbPcBiosBinary;
- fFlags = PGMPHYS_ROM_FLAGS_PERMANENT_BINARY;
- }
- else
- {
- pu8PcBiosBinary = pThis->pu8PcBios;
- cbPcBiosBinary = pThis->cbPcBios;
}
/*
@@ -1256,11 +1240,11 @@ static DECLCALLBACK(int) pcbiosConstruct(PPDMDEVINS pDevIns, int iInstance, PCF
("cbPcBiosBinary=%#x\n", cbPcBiosBinary));
cb = RT_MIN(cbPcBiosBinary, 128 * _1K); /* Effectively either 64 or 128K. */
rc = PDMDevHlpROMRegister(pDevIns, 0x00100000 - cb, cb, &pu8PcBiosBinary[cbPcBiosBinary - cb], cb,
- fFlags, "PC BIOS - 0xfffff");
+ PGMPHYS_ROM_FLAGS_PERMANENT_BINARY, "PC BIOS - 0xfffff");
if (RT_FAILURE(rc))
return rc;
rc = PDMDevHlpROMRegister(pDevIns, (uint32_t)-(int32_t)cbPcBiosBinary, cbPcBiosBinary, pu8PcBiosBinary, cbPcBiosBinary,
- fFlags, "PC BIOS - 0xffffffff");
+ PGMPHYS_ROM_FLAGS_PERMANENT_BINARY, "PC BIOS - 0xffffffff");
if (RT_FAILURE(rc))
return rc;
diff --git a/src/VBox/Devices/PC/DevPcBios.h b/src/VBox/Devices/PC/DevPcBios.h
index c340f069c..878c66155 100644
--- a/src/VBox/Devices/PC/DevPcBios.h
+++ b/src/VBox/Devices/PC/DevPcBios.h
@@ -1,4 +1,4 @@
-/* $Id: DevPcBios.h $ */
+/* $Id: DevPcBios.h 34081 2010-11-15 17:18:30Z vboxsync $ */
/** @file
* DevPcBios - PC BIOS Device, header shared with the BIOS code.
*/
diff --git a/src/VBox/Devices/PC/DevPit-i8254.cpp b/src/VBox/Devices/PC/DevPit-i8254.cpp
index d23c55bd5..ee8a53c71 100644
--- a/src/VBox/Devices/PC/DevPit-i8254.cpp
+++ b/src/VBox/Devices/PC/DevPit-i8254.cpp
@@ -1,10 +1,10 @@
-/* $Id: DevPit-i8254.cpp $ */
+/* $Id: DevPit-i8254.cpp 37526 2011-06-17 10:17:38Z vboxsync $ */
/** @file
* DevPIT-i8254 - Intel 8254 Programmable Interval Timer (PIT) And Dummy Speaker Device.
*/
/*
- * 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;
@@ -90,6 +90,62 @@
/** The effective counter mode - if bit 1 is set, bit 2 is ignored. */
#define EFFECTIVE_MODE(x) ((x) & ~(((x) & 2) << 1))
+
+/**
+ * Acquires the PIT lock or returns.
+ */
+#define DEVPIT_LOCK_RETURN(a_pThis, a_rcBusy) \
+ do { \
+ int rcLock = PDMCritSectEnter(&(a_pThis)->CritSect, (a_rcBusy)); \
+ if (rcLock != VINF_SUCCESS) \
+ return rcLock; \
+ } while (0)
+
+/**
+ * Releases the PIT lock.
+ */
+#define DEVPIT_UNLOCK(a_pThis) \
+ do { PDMCritSectLeave(&(a_pThis)->CritSect); } while (0)
+
+
+/**
+ * Acquires the TM lock and PIT lock, returns on failure.
+ */
+#define DEVPIT_LOCK_BOTH_RETURN(a_pThis, a_rcBusy) \
+ do { \
+ int rcLock = TMTimerLock((a_pThis)->channels[0].CTX_SUFF(pTimer), (a_rcBusy)); \
+ if (rcLock != VINF_SUCCESS) \
+ return rcLock; \
+ rcLock = PDMCritSectEnter(&(a_pThis)->CritSect, (a_rcBusy)); \
+ if (rcLock != VINF_SUCCESS) \
+ { \
+ TMTimerUnlock((a_pThis)->channels[0].CTX_SUFF(pTimer)); \
+ return rcLock; \
+ } \
+ } while (0)
+
+#if IN_RING3
+/**
+ * Acquires the TM lock and PIT lock, ignores failures.
+ */
+# define DEVPIT_R3_LOCK_BOTH(a_pThis) \
+ do { \
+ TMTimerLock((a_pThis)->channels[0].CTX_SUFF(pTimer), VERR_IGNORED); \
+ PDMCritSectEnter(&(a_pThis)->CritSect, VERR_IGNORED); \
+ } while (0)
+#endif /* IN_RING3 */
+
+/**
+ * Releases the PIT lock and TM lock.
+ */
+#define DEVPIT_UNLOCK_BOTH(a_pThis) \
+ do { \
+ PDMCritSectLeave(&(a_pThis)->CritSect); \
+ TMTimerUnlock((a_pThis)->channels[0].CTX_SUFF(pTimer)); \
+ } while (0)
+
+
+
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
@@ -140,6 +196,7 @@ typedef struct PITChannelState
typedef struct PITState
{
+ /** Channel state. Must come first? */
PITChannelState channels[3];
/** Speaker data. */
int32_t speaker_data_on;
@@ -163,6 +220,8 @@ typedef struct PITState
STAMCOUNTER StatPITIrq;
/** Profiling the timer callback handler. */
STAMPROFILEADV StatPITHandler;
+ /** Critical section protecting the state. */
+ PDMCRITSECT CritSect;
} PITState;
@@ -170,16 +229,9 @@ typedef struct PITState
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
-RT_C_DECLS_BEGIN
-PDMBOTHCBDECL(int) pitIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) pitIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) pitIOPortSpeakerRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
#ifdef IN_RING3
-PDMBOTHCBDECL(int) pitIOPortSpeakerWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
static void pit_irq_timer_update(PITChannelState *s, uint64_t current_time, uint64_t now, bool in_timer);
#endif
-RT_C_DECLS_END
-
@@ -188,6 +240,7 @@ static int pit_get_count(PITChannelState *s)
uint64_t d;
int counter;
PTMTIMER pTimer = s->CTX_SUFF(pPit)->channels[0].CTX_SUFF(pTimer);
+ Assert(TMTimerIsLockOwner(pTimer));
if (EFFECTIVE_MODE(s->mode) == 2)
{
@@ -293,6 +346,7 @@ static void pit_set_gate(PITState *pit, int channel, int val)
PITChannelState *s = &pit->channels[channel];
PTMTIMER pTimer = s->CTX_SUFF(pPit)->channels[0].CTX_SUFF(pTimer);
Assert((val & 1) == val);
+ Assert(TMTimerIsLockOwner(pTimer));
switch(EFFECTIVE_MODE(s->mode)) {
default:
@@ -323,9 +377,11 @@ static void pit_set_gate(PITState *pit, int channel, int val)
s->gate = val;
}
-DECLINLINE(void) pit_load_count(PITChannelState *s, int val)
+static void pit_load_count(PITChannelState *s, int val)
{
PTMTIMER pTimer = s->CTX_SUFF(pPit)->channels[0].CTX_SUFF(pTimer);
+ Assert(TMTimerIsLockOwner(pTimer));
+
if (val == 0)
val = 0x10000;
s->count_load_time = s->u64ReloadTS = TMTimerGet(pTimer);
@@ -434,6 +490,7 @@ static void pit_irq_timer_update(PITChannelState *s, uint64_t current_time, uint
int irq_level;
PPDMDEVINS pDevIns;
PTMTIMER pTimer = s->CTX_SUFF(pPit)->channels[0].CTX_SUFF(pTimer);
+ Assert(TMTimerIsLockOwner(pTimer));
if (!s->CTX_SUFF(pTimer))
return;
@@ -518,10 +575,13 @@ PDMBOTHCBDECL(int) pitIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port
PITState *pit = PDMINS_2_DATA(pDevIns, PITState *);
int ret;
PITChannelState *s = &pit->channels[Port];
+
+ DEVPIT_LOCK_RETURN(pit, VINF_IOM_HC_IOPORT_READ);
if (s->status_latched)
{
s->status_latched = 0;
ret = s->status;
+ DEVPIT_UNLOCK(pit);
}
else if (s->count_latched)
{
@@ -541,9 +601,12 @@ PDMBOTHCBDECL(int) pitIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port
s->count_latched = RW_STATE_MSB;
break;
}
+ DEVPIT_UNLOCK(pit);
}
else
{
+ DEVPIT_UNLOCK(pit);
+ DEVPIT_LOCK_BOTH_RETURN(pit, VINF_IOM_HC_IOPORT_READ);
int count;
switch (s->read_state)
{
@@ -567,6 +630,7 @@ PDMBOTHCBDECL(int) pitIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port
s->read_state = RW_STATE_WORD0;
break;
}
+ DEVPIT_UNLOCK_BOTH(pit);
}
*pu32 = ret;
@@ -620,6 +684,7 @@ PDMBOTHCBDECL(int) pitIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Por
if (channel == 3)
{
/* read-back command */
+ DEVPIT_LOCK_BOTH_RETURN(pit, VINF_IOM_HC_IOPORT_WRITE);
for (channel = 0; channel < RT_ELEMENTS(pit->channels); channel++)
{
PITChannelState *s = &pit->channels[channel];
@@ -639,15 +704,21 @@ PDMBOTHCBDECL(int) pitIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Por
}
}
}
+ DEVPIT_UNLOCK_BOTH(pit);
}
else
{
PITChannelState *s = &pit->channels[channel];
unsigned access = (u32 >> 4) & 3;
if (access == 0)
+ {
+ DEVPIT_LOCK_BOTH_RETURN(pit, VINF_IOM_HC_IOPORT_WRITE);
pit_latch_count(s);
+ DEVPIT_UNLOCK_BOTH(pit);
+ }
else
{
+ DEVPIT_LOCK_RETURN(pit, VINF_IOM_HC_IOPORT_WRITE);
s->rw_mode = access;
s->read_state = access;
s->write_state = access;
@@ -655,19 +726,24 @@ PDMBOTHCBDECL(int) pitIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Por
s->mode = (u32 >> 1) & 7;
s->bcd = u32 & 1;
/* XXX: update irq timer ? */
+ DEVPIT_UNLOCK(pit);
}
}
}
else
{
#ifndef IN_RING3
+ /** @todo There is no reason not to do this in all contexts these
+ * days... */
return VINF_IOM_HC_IOPORT_WRITE;
#else /* IN_RING3 */
/*
* Port 40-42h - Channel Data Ports.
*/
PITChannelState *s = &pit->channels[Port];
- switch(s->write_state)
+ uint8_t const write_state = s->write_state;
+ DEVPIT_LOCK_BOTH_RETURN(pit, VINF_IOM_HC_IOPORT_WRITE);
+ switch (s->write_state)
{
default:
case RW_STATE_LSB:
@@ -685,6 +761,7 @@ PDMBOTHCBDECL(int) pitIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Por
s->write_state = RW_STATE_WORD0;
break;
}
+ DEVPIT_UNLOCK_BOTH(pit);
#endif /* !IN_RING3 */
}
return VINF_SUCCESS;
@@ -708,6 +785,8 @@ PDMBOTHCBDECL(int) pitIOPortSpeakerRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPO
if (cb == 1)
{
PITState *pThis = PDMINS_2_DATA(pDevIns, PITState *);
+ DEVPIT_LOCK_BOTH_RETURN(pThis, VINF_IOM_HC_IOPORT_READ);
+
const uint64_t u64Now = TMTimerGet(pThis->channels[0].CTX_SUFF(pTimer));
Assert(TMTimerGetFreq(pThis->channels[0].CTX_SUFF(pTimer)) == 1000000000); /* lazy bird. */
@@ -728,6 +807,8 @@ PDMBOTHCBDECL(int) pitIOPortSpeakerRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPO
/* bit 0 - timer 2 clock gate to speaker status. */
const int fTimer2GateStatus = pit_get_gate(pThis, 2);
+ DEVPIT_UNLOCK_BOTH(pThis);
+
*pu32 = fTimer2GateStatus
| (fSpeakerStatus << 1)
| (fRefresh << 4)
@@ -758,8 +839,12 @@ PDMBOTHCBDECL(int) pitIOPortSpeakerWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOP
if (cb == 1)
{
PITState *pThis = PDMINS_2_DATA(pDevIns, PITState *);
+ DEVPIT_LOCK_BOTH_RETURN(pThis, VERR_IGNORED);
+
pThis->speaker_data_on = (u32 >> 1) & 1;
pit_set_gate(pThis, 2, u32 & 1);
+
+ DEVPIT_UNLOCK_BOTH(pThis);
}
Log(("pitIOPortSpeakerWrite: Port=%#x cb=%x u32=%#x\n", Port, cb, u32));
return VINF_SUCCESS;
@@ -785,13 +870,13 @@ static DECLCALLBACK(int) pitLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32
static DECLCALLBACK(int) pitSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
{
PITState *pThis = PDMINS_2_DATA(pDevIns, PITState *);
- unsigned i;
+ PDMCritSectEnter(&pThis->CritSect, VERR_IGNORED);
/* The config. */
pitLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
/* The state. */
- for (i = 0; i < RT_ELEMENTS(pThis->channels); i++)
+ for (unsigned i = 0; i < RT_ELEMENTS(pThis->channels); i++)
{
PITChannelState *s = &pThis->channels[i];
SSMR3PutU32(pSSM, s->count);
@@ -821,7 +906,10 @@ static DECLCALLBACK(int) pitSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
SSMR3PutS32(pSSM, 0);
#endif
- return SSMR3PutBool(pSSM, pThis->fDisabledByHpet);
+ SSMR3PutBool(pSSM, pThis->fDisabledByHpet);
+
+ PDMCritSectLeave(&pThis->CritSect);
+ return VINF_SUCCESS;
}
@@ -888,7 +976,9 @@ static DECLCALLBACK(int) pitLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32
TMR3TimerLoad(s->CTX_SUFF(pTimer), pSSM);
LogRel(("PIT: mode=%d count=%#x (%u) - %d.%02d Hz (ch=%d) (restore)\n",
s->mode, s->count, s->count, PIT_FREQ / s->count, (PIT_FREQ * 100 / s->count) % 100, i));
+ PDMCritSectEnter(&pThis->CritSect, VERR_IGNORED);
TMTimerSetFrequencyHint(s->CTX_SUFF(pTimer), PIT_FREQ / s->count);
+ PDMCritSectLeave(&pThis->CritSect);
}
pThis->channels[i].cRelLogEntries = 0;
}
@@ -918,8 +1008,13 @@ static DECLCALLBACK(void) pitTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pv
{
PITChannelState *s = (PITChannelState *)pvUser;
STAM_PROFILE_ADV_START(&s->CTX_SUFF(pPit)->StatPITHandler, a);
+
Log(("pitTimer\n"));
+ Assert(PDMCritSectIsOwner(&PDMINS_2_DATA(pDevIns, PITState *)->CritSect));
+ Assert(TMTimerIsLockOwner(pTimer));
+
pit_irq_timer_update(s, s->next_transition_time, TMTimerGet(pTimer), true);
+
STAM_PROFILE_ADV_STOP(&s->CTX_SUFF(pPit)->StatPITHandler, a);
}
@@ -986,7 +1081,11 @@ static DECLCALLBACK(void *) pitQueryInterface(PPDMIBASE pInterface, const char *
static DECLCALLBACK(void) pitNotifyHpetLegacyNotify_ModeChanged(PPDMIHPETLEGACYNOTIFY pInterface, bool fActivated)
{
PITState *pThis = RT_FROM_MEMBER(pInterface, PITState, IHpetLegacyNotify);
+ PDMCritSectEnter(&pThis->CritSect, VERR_IGNORED);
+
pThis->fDisabledByHpet = fActivated;
+
+ PDMCritSectLeave(&pThis->CritSect);
}
@@ -1000,10 +1099,9 @@ static DECLCALLBACK(void) pitNotifyHpetLegacyNotify_ModeChanged(PPDMIHPETLEGACYN
static DECLCALLBACK(void) pitRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
{
PITState *pThis = PDMINS_2_DATA(pDevIns, PITState *);
- unsigned i;
LogFlow(("pitRelocate: \n"));
- for (i = 0; i < RT_ELEMENTS(pThis->channels); i++)
+ for (unsigned i = 0; i < RT_ELEMENTS(pThis->channels); i++)
{
PITChannelState *pCh = &pThis->channels[i];
if (pCh->pTimerR3)
@@ -1022,12 +1120,13 @@ static DECLCALLBACK(void) pitRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
static DECLCALLBACK(void) pitReset(PPDMDEVINS pDevIns)
{
PITState *pThis = PDMINS_2_DATA(pDevIns, PITState *);
- unsigned i;
LogFlow(("pitReset: \n"));
+ DEVPIT_R3_LOCK_BOTH(pThis);
+
pThis->fDisabledByHpet = false;
- for (i = 0; i < RT_ELEMENTS(pThis->channels); i++)
+ for (unsigned i = 0; i < RT_ELEMENTS(pThis->channels); i++)
{
PITChannelState *s = &pThis->channels[i];
@@ -1048,6 +1147,8 @@ static DECLCALLBACK(void) pitReset(PPDMDEVINS pDevIns)
s->gate = (i != 2);
pit_load_count(s, 0);
}
+
+ DEVPIT_UNLOCK_BOTH(pThis);
}
@@ -1120,16 +1221,30 @@ static DECLCALLBACK(int) pitConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
pThis->IHpetLegacyNotify.pfnModeChanged = pitNotifyHpetLegacyNotify_ModeChanged;
/*
- * Create timer, register I/O Ports and save state.
+ * We do our own locking. This must be done before creating timers.
+ */
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "pit");
+ AssertRCReturn(rc, rc);
+
+ rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
+ AssertRCReturn(rc, rc);
+
+ /*
+ * Create the timer, make it take our critsect.
*/
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, pitTimer, &pThis->channels[0],
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "i8254 Programmable Interval Timer",
+ TMTIMER_FLAGS_NO_CRIT_SECT, "i8254 Programmable Interval Timer",
&pThis->channels[0].pTimerR3);
if (RT_FAILURE(rc))
return rc;
pThis->channels[0].pTimerRC = TMTimerRCPtr(pThis->channels[0].pTimerR3);
pThis->channels[0].pTimerR0 = TMTimerR0Ptr(pThis->channels[0].pTimerR3);
+ rc = TMR3TimerSetCritSect(pThis->channels[0].pTimerR3, &pThis->CritSect);
+ AssertRCReturn(rc, rc);
+ /*
+ * Register I/O ports.
+ */
rc = PDMDevHlpIOPortRegister(pDevIns, u16Base, 4, NULL, pitIOPortWrite, pitIOPortRead, NULL, NULL, "i8254 Programmable Interval Timer");
if (RT_FAILURE(rc))
return rc;
@@ -1159,6 +1274,9 @@ static DECLCALLBACK(int) pitConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
}
}
+ /*
+ * Saved state.
+ */
rc = PDMDevHlpSSMRegister3(pDevIns, PIT_SAVED_STATE_VERSION, sizeof(*pThis), pitLiveExec, pitSaveExec, pitLoadExec);
if (RT_FAILURE(rc))
return rc;
diff --git a/src/VBox/Devices/PC/DevRTC.cpp b/src/VBox/Devices/PC/DevRTC.cpp
index f894993dc..6a5a9e40d 100644
--- a/src/VBox/Devices/PC/DevRTC.cpp
+++ b/src/VBox/Devices/PC/DevRTC.cpp
@@ -1,10 +1,10 @@
-/* $Id: DevRTC.cpp $ */
+/* $Id: DevRTC.cpp 37526 2011-06-17 10:17:38Z vboxsync $ */
/** @file
* Motorola MC146818 RTC/CMOS Device with PIIX4 extensions.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -203,216 +203,328 @@ struct RTCState {
};
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
-static void rtc_set_time(RTCState *s);
-static void rtc_copy_date(RTCState *s);
-static void rtc_timer_update(RTCState *s, int64_t current_time)
+static void rtc_timer_update(RTCState *pThis, int64_t current_time)
{
int period_code, period;
uint64_t cur_clock, next_irq_clock;
uint32_t freq;
- period_code = s->cmos_data[RTC_REG_A] & 0x0f;
- if (period_code != 0 &&
- (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
+ Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
+ Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
+
+ period_code = pThis->cmos_data[RTC_REG_A] & 0x0f;
+ if ( period_code != 0
+ && (pThis->cmos_data[RTC_REG_B] & REG_B_PIE))
+ {
if (period_code <= 2)
period_code += 7;
/* period in 32 kHz cycles */
period = 1 << (period_code - 1);
/* compute 32 kHz clock */
- freq = TMTimerGetFreq(s->CTX_SUFF(pPeriodicTimer));
+ freq = TMTimerGetFreq(pThis->CTX_SUFF(pPeriodicTimer));
cur_clock = ASMMultU64ByU32DivByU32(current_time, 32768, freq);
next_irq_clock = (cur_clock & ~(uint64_t)(period - 1)) + period;
- s->next_periodic_time = ASMMultU64ByU32DivByU32(next_irq_clock, freq, 32768) + 1;
- TMTimerSet(s->CTX_SUFF(pPeriodicTimer), s->next_periodic_time);
+ pThis->next_periodic_time = ASMMultU64ByU32DivByU32(next_irq_clock, freq, 32768) + 1;
+ TMTimerSet(pThis->CTX_SUFF(pPeriodicTimer), pThis->next_periodic_time);
#ifdef IN_RING3
- if (RT_UNLIKELY(period != s->CurLogPeriod))
+ if (RT_UNLIKELY(period != pThis->CurLogPeriod))
#else
- if (RT_UNLIKELY(period != s->CurHintPeriod))
+ if (RT_UNLIKELY(period != pThis->CurHintPeriod))
#endif
{
#ifdef IN_RING3
- if (s->cRelLogEntries++ < 64)
+ if (pThis->cRelLogEntries++ < 64)
LogRel(("RTC: period=%#x (%d) %u Hz\n", period, period, _32K / period));
- s->CurLogPeriod = period;
+ pThis->CurLogPeriod = period;
#endif
- s->CurHintPeriod = period;
- TMTimerSetFrequencyHint(s->CTX_SUFF(pPeriodicTimer), _32K / period);
+ pThis->CurHintPeriod = period;
+ TMTimerSetFrequencyHint(pThis->CTX_SUFF(pPeriodicTimer), _32K / period);
}
- } else {
- if (TMTimerIsActive(s->CTX_SUFF(pPeriodicTimer)) && s->cRelLogEntries++ < 64)
+ }
+ else
+ {
+ if (TMTimerIsActive(pThis->CTX_SUFF(pPeriodicTimer)) && pThis->cRelLogEntries++ < 64)
LogRel(("RTC: stopped the periodic timer\n"));
- TMTimerStop(s->CTX_SUFF(pPeriodicTimer));
+ TMTimerStop(pThis->CTX_SUFF(pPeriodicTimer));
}
}
+
static void rtc_raise_irq(RTCState* pThis, uint32_t iLevel)
{
if (!pThis->fDisabledByHpet)
PDMDevHlpISASetIrq(pThis->CTX_SUFF(pDevIns), pThis->irq, iLevel);
}
-static void rtc_periodic_timer(void *opaque)
+
+DECLINLINE(int) to_bcd(RTCState *pThis, int a)
{
- RTCState *s = (RTCState*)opaque;
+ if (pThis->cmos_data[RTC_REG_B] & 0x04)
+ return a;
+ return ((a / 10) << 4) | (a % 10);
+}
- rtc_timer_update(s, s->next_periodic_time);
- s->cmos_data[RTC_REG_C] |= 0xc0;
- rtc_raise_irq(s, 1);
+DECLINLINE(int) from_bcd(RTCState *pThis, int a)
+{
+ if (pThis->cmos_data[RTC_REG_B] & 0x04)
+ return a;
+ return ((a >> 4) * 10) + (a & 0x0f);
}
-static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
+
+static void rtc_set_time(RTCState *pThis)
{
- RTCState *s = (RTCState*)opaque;
- uint32_t bank;
+ struct my_tm *tm = &pThis->current_tm;
- bank = (addr >> 1) & 1;
- if ((addr & 1) == 0) {
- s->cmos_index[bank] = (data & 0x7f) + (bank * 128);
- } else {
- Log(("CMOS: Write bank %d idx %#04x: %#04x (old %#04x)\n", bank,
- s->cmos_index[bank], data, s->cmos_data[s->cmos_index[bank]]));
- switch(s->cmos_index[bank]) {
- case RTC_SECONDS_ALARM:
- case RTC_MINUTES_ALARM:
- case RTC_HOURS_ALARM:
- s->cmos_data[s->cmos_index[0]] = data;
- break;
- case RTC_SECONDS:
- case RTC_MINUTES:
- case RTC_HOURS:
- case RTC_DAY_OF_WEEK:
- case RTC_DAY_OF_MONTH:
- case RTC_MONTH:
- case RTC_YEAR:
- s->cmos_data[s->cmos_index[0]] = data;
- /* if in set mode, do not update the time */
- if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- rtc_set_time(s);
- }
- break;
- case RTC_REG_A:
- /* UIP bit is read only */
- s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
- (s->cmos_data[RTC_REG_A] & REG_A_UIP);
- rtc_timer_update(s, TMTimerGet(s->CTX_SUFF(pPeriodicTimer)));
- break;
- case RTC_REG_B:
- if (data & REG_B_SET) {
- /* set mode: reset UIP mode */
- s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
-#if 0 /* This is probably wrong as it breaks changing the time/date in OS/2. */
- data &= ~REG_B_UIE;
-#endif
- } else {
- /* if disabling set mode, update the time */
- if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
- rtc_set_time(s);
- }
- }
- s->cmos_data[RTC_REG_B] = data;
- rtc_timer_update(s, TMTimerGet(s->CTX_SUFF(pPeriodicTimer)));
- break;
- case RTC_REG_C:
- case RTC_REG_D:
- /* cannot write to them */
- break;
- default:
- s->cmos_data[s->cmos_index[bank]] = data;
- break;
- }
- }
+ tm->tm_sec = from_bcd(pThis, pThis->cmos_data[RTC_SECONDS]);
+ tm->tm_min = from_bcd(pThis, pThis->cmos_data[RTC_MINUTES]);
+ tm->tm_hour = from_bcd(pThis, pThis->cmos_data[RTC_HOURS] & 0x7f);
+ if ( !(pThis->cmos_data[RTC_REG_B] & 0x02)
+ && (pThis->cmos_data[RTC_HOURS] & 0x80))
+ tm->tm_hour += 12;
+ tm->tm_wday = from_bcd(pThis, pThis->cmos_data[RTC_DAY_OF_WEEK]);
+ tm->tm_mday = from_bcd(pThis, pThis->cmos_data[RTC_DAY_OF_MONTH]);
+ tm->tm_mon = from_bcd(pThis, pThis->cmos_data[RTC_MONTH]) - 1;
+ tm->tm_year = from_bcd(pThis, pThis->cmos_data[RTC_YEAR]) + 100;
}
-static inline int to_bcd(RTCState *s, int a)
+
+/* -=-=-=-=-=- I/O Port Handlers -=-=-=-=-=- */
+
+
+/**
+ * Port I/O Handler for IN operations.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument - ignored.
+ * @param uPort Port number used for the IN operation.
+ * @param pu32 Where to store the result.
+ * @param cb Number of bytes read.
+ */
+PDMBOTHCBDECL(int) rtcIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
- if (s->cmos_data[RTC_REG_B] & 0x04) {
- return a;
- } else {
- return ((a / 10) << 4) | (a % 10);
+ NOREF(pvUser);
+ if (cb != 1)
+ return VERR_IOM_IOPORT_UNUSED;
+
+ RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
+ if ((Port & 1) == 0)
+ *pu32 = 0xff;
+ else
+ {
+ unsigned bank = (Port >> 1) & 1;
+ switch (pThis->cmos_index[bank])
+ {
+ case RTC_SECONDS:
+ case RTC_MINUTES:
+ case RTC_HOURS:
+ case RTC_DAY_OF_WEEK:
+ case RTC_DAY_OF_MONTH:
+ case RTC_MONTH:
+ case RTC_YEAR:
+ *pu32 = pThis->cmos_data[pThis->cmos_index[0]];
+ break;
+
+ case RTC_REG_A:
+ *pu32 = pThis->cmos_data[pThis->cmos_index[0]];
+ break;
+
+ case RTC_REG_C:
+ *pu32 = pThis->cmos_data[pThis->cmos_index[0]];
+ rtc_raise_irq(pThis, 0);
+ pThis->cmos_data[RTC_REG_C] = 0x00;
+ break;
+
+ default:
+ *pu32 = pThis->cmos_data[pThis->cmos_index[bank]];
+ break;
+ }
+
+ Log(("CMOS: Read bank %d idx %#04x: %#04x\n", bank, pThis->cmos_index[bank], *pu32));
}
+
+ return VINF_SUCCESS;
}
-static inline int from_bcd(RTCState *s, int a)
+
+/**
+ * Port I/O Handler for OUT operations.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument - ignored.
+ * @param uPort Port number used for the IN operation.
+ * @param u32 The value to output.
+ * @param cb The value size in bytes.
+ */
+PDMBOTHCBDECL(int) rtcIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- if (s->cmos_data[RTC_REG_B] & 0x04) {
- return a;
- } else {
- return ((a >> 4) * 10) + (a & 0x0f);
+ NOREF(pvUser);
+ if (cb != 1)
+ return VINF_SUCCESS;
+
+ RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
+ uint32_t bank = (Port >> 1) & 1;
+ if ((Port & 1) == 0)
+ {
+ pThis->cmos_index[bank] = (u32 & 0x7f) + (bank * 128);
}
-}
+ else
+ {
+ Log(("CMOS: Write bank %d idx %#04x: %#04x (old %#04x)\n", bank,
+ pThis->cmos_index[bank], u32, pThis->cmos_data[pThis->cmos_index[bank]]));
-static void rtc_set_time(RTCState *s)
-{
- struct my_tm *tm = &s->current_tm;
+ int const idx = pThis->cmos_index[bank];
+ switch (idx)
+ {
+ case RTC_SECONDS_ALARM:
+ case RTC_MINUTES_ALARM:
+ case RTC_HOURS_ALARM:
+ pThis->cmos_data[pThis->cmos_index[0]] = u32;
+ break;
+
+ case RTC_SECONDS:
+ case RTC_MINUTES:
+ case RTC_HOURS:
+ case RTC_DAY_OF_WEEK:
+ case RTC_DAY_OF_MONTH:
+ case RTC_MONTH:
+ case RTC_YEAR:
+ pThis->cmos_data[pThis->cmos_index[0]] = u32;
+ /* if in set mode, do not update the time */
+ if (!(pThis->cmos_data[RTC_REG_B] & REG_B_SET))
+ rtc_set_time(pThis);
+ break;
+
+ case RTC_REG_A:
+ case RTC_REG_B:
+ {
+ /* We need to acquire the clock lock, because of lock ordering
+ issues this means having to release the device lock. Since
+ we're letting IOM do the locking, we must not return without
+ holding the device lock.*/
+ PDMCritSectLeave(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo));
+ int rc1 = TMTimerLock(pThis->CTX_SUFF(pPeriodicTimer), VINF_SUCCESS /* must get it */);
+ int rc2 = PDMCritSectEnter(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo), VINF_SUCCESS /* must get it */);
+ AssertRCReturn(rc1, rc1);
+ AssertRCReturnStmt(rc2, TMTimerUnlock(pThis->CTX_SUFF(pPeriodicTimer)), rc2);
+
+ if (idx == RTC_REG_A)
+ {
+ /* UIP bit is read only */
+ pThis->cmos_data[RTC_REG_A] = (u32 & ~REG_A_UIP)
+ | (pThis->cmos_data[RTC_REG_A] & REG_A_UIP);
+ }
+ else
+ {
+ if (u32 & REG_B_SET)
+ {
+ /* set mode: reset UIP mode */
+ pThis->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
+#if 0 /* This is probably wrong as it breaks changing the time/date in OS/2. */
+ u32 &= ~REG_B_UIE;
+#endif
+ }
+ else
+ {
+ /* if disabling set mode, update the time */
+ if (pThis->cmos_data[RTC_REG_B] & REG_B_SET)
+ rtc_set_time(pThis);
+ }
+ pThis->cmos_data[RTC_REG_B] = u32;
+ }
- tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]);
- tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]);
- tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
- if (!(s->cmos_data[RTC_REG_B] & 0x02) &&
- (s->cmos_data[RTC_HOURS] & 0x80)) {
- tm->tm_hour += 12;
+ rtc_timer_update(pThis, TMTimerGet(pThis->CTX_SUFF(pPeriodicTimer)));
+
+ TMTimerUnlock(pThis->CTX_SUFF(pPeriodicTimer));
+ /* the caller leaves the other lock. */
+ break;
+ }
+
+ case RTC_REG_C:
+ case RTC_REG_D:
+ /* cannot write to them */
+ break;
+
+ default:
+ pThis->cmos_data[pThis->cmos_index[bank]] = u32;
+ break;
+ }
}
- tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]);
- tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
- tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
- tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + 100;
+
+ return VINF_SUCCESS;
}
-static void rtc_copy_date(RTCState *s)
+#ifdef IN_RING3
+
+/* -=-=-=-=-=- Timers and their support code -=-=-=-=-=- */
+
+
+/**
+ * Device timer callback function, periodic.
+ *
+ * @param pDevIns Device instance of the device which registered the timer.
+ * @param pTimer The timer handle.
+ * @param pvUser Pointer to the RTC state.
+ */
+static DECLCALLBACK(void) rtcTimerPeriodic(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
{
- const struct my_tm *tm = &s->current_tm;
+ RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
+ Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
+ Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
- s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
- s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
- if (s->cmos_data[RTC_REG_B] & 0x02) {
- /* 24 hour format */
- s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour);
- } else {
- /* 12 hour format */
- s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12);
- if (tm->tm_hour >= 12)
- s->cmos_data[RTC_HOURS] |= 0x80;
- }
- s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday);
- s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday);
- s->cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1);
- s->cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100);
+ rtc_timer_update(pThis, pThis->next_periodic_time);
+ pThis->cmos_data[RTC_REG_C] |= 0xc0;
+
+ rtc_raise_irq(pThis, 1);
}
+
/* month is between 0 and 11. */
static int get_days_in_month(int month, int year)
{
- static const int days_tab[12] = {
+ static const int days_tab[12] =
+ {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
int d;
+
if ((unsigned )month >= 12)
return 31;
+
d = days_tab[month];
- if (month == 1) {
+ if (month == 1)
+ {
if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
d++;
}
return d;
}
+
/* update 'tm' to the next second */
static void rtc_next_second(struct my_tm *tm)
{
int days_in_month;
tm->tm_sec++;
- if ((unsigned)tm->tm_sec >= 60) {
+ if ((unsigned)tm->tm_sec >= 60)
+ {
tm->tm_sec = 0;
tm->tm_min++;
- if ((unsigned)tm->tm_min >= 60) {
+ if ((unsigned)tm->tm_min >= 60)
+ {
tm->tm_min = 0;
tm->tm_hour++;
- if ((unsigned)tm->tm_hour >= 24) {
+ if ((unsigned)tm->tm_hour >= 24)
+ {
tm->tm_hour = 0;
/* next day */
tm->tm_wday++;
@@ -421,12 +533,14 @@ static void rtc_next_second(struct my_tm *tm)
days_in_month = get_days_in_month(tm->tm_mon,
tm->tm_year + 1900);
tm->tm_mday++;
- if (tm->tm_mday < 1) {
+ if (tm->tm_mday < 1)
tm->tm_mday = 1;
- } else if (tm->tm_mday > days_in_month) {
+ else if (tm->tm_mday > days_in_month)
+ {
tm->tm_mday = 1;
tm->tm_mon++;
- if (tm->tm_mon >= 12) {
+ if (tm->tm_mon >= 12)
+ {
tm->tm_mon = 0;
tm->tm_year++;
}
@@ -437,201 +551,119 @@ static void rtc_next_second(struct my_tm *tm)
}
-static void rtc_update_second(void *opaque)
+/**
+ * Device timer callback function, second.
+ *
+ * @param pDevIns Device instance of the device which registered the timer.
+ * @param pTimer The timer handle.
+ * @param pvUser Pointer to the RTC state.
+ */
+static DECLCALLBACK(void) rtcTimerSecond(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
{
- RTCState *s = (RTCState*)opaque;
+ RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
+ Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
+ Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
/* if the oscillator is not in normal operation, we do not update */
- if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
- s->next_second_time += TMTimerGetFreq(s->CTX_SUFF(pSecondTimer));
- TMTimerSet(s->CTX_SUFF(pSecondTimer), s->next_second_time);
- } else {
- rtc_next_second(&s->current_tm);
+ if ((pThis->cmos_data[RTC_REG_A] & 0x70) != 0x20)
+ {
+ pThis->next_second_time += TMTimerGetFreq(pThis->CTX_SUFF(pSecondTimer));
+ TMTimerSet(pThis->CTX_SUFF(pSecondTimer), pThis->next_second_time);
+ }
+ else
+ {
+ rtc_next_second(&pThis->current_tm);
- if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
+ if (!(pThis->cmos_data[RTC_REG_B] & REG_B_SET))
+ {
/* update in progress bit */
- Log2(("RTC: UIP %x -> 1\n", !!(s->cmos_data[RTC_REG_A] & REG_A_UIP)));
- s->cmos_data[RTC_REG_A] |= REG_A_UIP;
+ Log2(("RTC: UIP %x -> 1\n", !!(pThis->cmos_data[RTC_REG_A] & REG_A_UIP)));
+ pThis->cmos_data[RTC_REG_A] |= REG_A_UIP;
}
/* 244140 ns = 8 / 32768 seconds */
- uint64_t delay = TMTimerFromNano(s->CTX_SUFF(pSecondTimer2), 244140);
- TMTimerSet(s->CTX_SUFF(pSecondTimer2), s->next_second_time + delay);
+ uint64_t delay = TMTimerFromNano(pThis->CTX_SUFF(pSecondTimer2), 244140);
+ TMTimerSet(pThis->CTX_SUFF(pSecondTimer2), pThis->next_second_time + delay);
}
}
-static void rtc_update_second2(void *opaque)
-{
- RTCState *s = (RTCState*)opaque;
-
- if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- rtc_copy_date(s);
- }
-
- /* check alarm */
- if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
- if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
- from_bcd(s, s->cmos_data[RTC_SECONDS_ALARM]) == s->current_tm.tm_sec) &&
- ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
- from_bcd(s, s->cmos_data[RTC_MINUTES_ALARM]) == s->current_tm.tm_min) &&
- ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
- from_bcd(s, s->cmos_data[RTC_HOURS_ALARM]) == s->current_tm.tm_hour)) {
-
- s->cmos_data[RTC_REG_C] |= 0xa0;
- rtc_raise_irq(s, 1);
- }
- }
-
- /* update ended interrupt */
- if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
- s->cmos_data[RTC_REG_C] |= 0x90;
- rtc_raise_irq(s, 1);
- }
- /* clear update in progress bit */
- Log2(("RTC: UIP %x -> 0\n", !!(s->cmos_data[RTC_REG_A] & REG_A_UIP)));
- s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
-
- s->next_second_time += TMTimerGetFreq(s->CTX_SUFF(pSecondTimer));
- TMTimerSet(s->CTX_SUFF(pSecondTimer), s->next_second_time);
-}
-
-static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
+/* Used by rtc_set_date and rtcTimerSecond2. */
+static void rtc_copy_date(RTCState *pThis)
{
- RTCState *s = (RTCState*)opaque;
- int ret;
- unsigned bank;
+ const struct my_tm *tm = &pThis->current_tm;
- bank = (addr >> 1) & 1;
- if ((addr & 1) == 0) {
- return 0xff;
- } else {
- switch(s->cmos_index[bank]) {
- case RTC_SECONDS:
- case RTC_MINUTES:
- case RTC_HOURS:
- case RTC_DAY_OF_WEEK:
- case RTC_DAY_OF_MONTH:
- case RTC_MONTH:
- case RTC_YEAR:
- ret = s->cmos_data[s->cmos_index[0]];
- break;
- case RTC_REG_A:
- ret = s->cmos_data[s->cmos_index[0]];
- break;
- case RTC_REG_C:
- ret = s->cmos_data[s->cmos_index[0]];
- rtc_raise_irq(s, 0);
- s->cmos_data[RTC_REG_C] = 0x00;
- break;
- default:
- ret = s->cmos_data[s->cmos_index[bank]];
- break;
- }
- Log(("CMOS: Read bank %d idx %#04x: %#04x\n", bank, s->cmos_index[bank], ret));
- return ret;
+ pThis->cmos_data[RTC_SECONDS] = to_bcd(pThis, tm->tm_sec);
+ pThis->cmos_data[RTC_MINUTES] = to_bcd(pThis, tm->tm_min);
+ if (pThis->cmos_data[RTC_REG_B] & 0x02)
+ {
+ /* 24 hour format */
+ pThis->cmos_data[RTC_HOURS] = to_bcd(pThis, tm->tm_hour);
}
-}
-
-#ifdef IN_RING3
-static void rtc_set_memory(RTCState *s, int addr, int val)
-{
- if (addr >= 0 && addr <= 127)
- s->cmos_data[addr] = val;
-}
-
-static void rtc_set_date(RTCState *s, const struct my_tm *tm)
-{
- s->current_tm = *tm;
- rtc_copy_date(s);
-}
-
-#endif /* IN_RING3 */
-
-/* -=-=-=-=-=- wrappers / stuff -=-=-=-=-=- */
-
-/**
- * Port I/O Handler for IN operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param uPort Port number used for the IN operation.
- * @param pu32 Where to store the result.
- * @param cb Number of bytes read.
- */
-PDMBOTHCBDECL(int) rtcIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
-{
- NOREF(pvUser);
- if (cb == 1)
+ else
{
- *pu32 = cmos_ioport_read(PDMINS_2_DATA(pDevIns, RTCState *), Port);
- return VINF_SUCCESS;
+ /* 12 hour format */
+ pThis->cmos_data[RTC_HOURS] = to_bcd(pThis, tm->tm_hour % 12);
+ if (tm->tm_hour >= 12)
+ pThis->cmos_data[RTC_HOURS] |= 0x80;
}
- return VERR_IOM_IOPORT_UNUSED;
-}
-
-
-/**
- * Port I/O Handler for OUT operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param uPort Port number used for the IN operation.
- * @param u32 The value to output.
- * @param cb The value size in bytes.
- */
-PDMBOTHCBDECL(int) rtcIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
-{
- NOREF(pvUser);
- if (cb == 1)
- cmos_ioport_write(PDMINS_2_DATA(pDevIns, RTCState *), Port, u32);
- return VINF_SUCCESS;
+ pThis->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(pThis, tm->tm_wday);
+ pThis->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(pThis, tm->tm_mday);
+ pThis->cmos_data[RTC_MONTH] = to_bcd(pThis, tm->tm_mon + 1);
+ pThis->cmos_data[RTC_YEAR] = to_bcd(pThis, tm->tm_year % 100);
}
/**
- * Device timer callback function, periodic.
+ * Device timer callback function, second2.
*
* @param pDevIns Device instance of the device which registered the timer.
* @param pTimer The timer handle.
* @param pvUser Pointer to the RTC state.
*/
-PDMBOTHCBDECL(void) rtcTimerPeriodic(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
+static DECLCALLBACK(void) rtcTimerSecond2(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
{
- rtc_periodic_timer((RTCState *)pvUser);
-}
+ RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
+ Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
+ Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
+ if (!(pThis->cmos_data[RTC_REG_B] & REG_B_SET))
+ rtc_copy_date(pThis);
-/**
- * Device timer callback function, second.
- *
- * @param pDevIns Device instance of the device which registered the timer.
- * @param pTimer The timer handle.
- * @param pvUser Pointer to the RTC state.
- */
-PDMBOTHCBDECL(void) rtcTimerSecond(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
-{
- rtc_update_second((RTCState *)pvUser);
-}
+ /* check alarm */
+ if (pThis->cmos_data[RTC_REG_B] & REG_B_AIE)
+ {
+ if ( ( (pThis->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0
+ || from_bcd(pThis, pThis->cmos_data[RTC_SECONDS_ALARM]) == pThis->current_tm.tm_sec)
+ && ( (pThis->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0
+ || from_bcd(pThis, pThis->cmos_data[RTC_MINUTES_ALARM]) == pThis->current_tm.tm_min)
+ && ( (pThis->cmos_data[RTC_HOURS_ALARM ] & 0xc0) == 0xc0
+ || from_bcd(pThis, pThis->cmos_data[RTC_HOURS_ALARM ]) == pThis->current_tm.tm_hour)
+ )
+ {
+ pThis->cmos_data[RTC_REG_C] |= 0xa0;
+ rtc_raise_irq(pThis, 1);
+ }
+ }
+ /* update ended interrupt */
+ if (pThis->cmos_data[RTC_REG_B] & REG_B_UIE)
+ {
+ pThis->cmos_data[RTC_REG_C] |= 0x90;
+ rtc_raise_irq(pThis, 1);
+ }
-/**
- * Device timer callback function, second2.
- *
- * @param pDevIns Device instance of the device which registered the timer.
- * @param pTimer The timer handle.
- * @param pvUser Pointer to the RTC state.
- */
-PDMBOTHCBDECL(void) rtcTimerSecond2(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
-{
- rtc_update_second2((RTCState *)pvUser);
+ /* clear update in progress bit */
+ Log2(("RTC: UIP %x -> 0\n", !!(pThis->cmos_data[RTC_REG_A] & REG_A_UIP)));
+ pThis->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
+
+ pThis->next_second_time += TMTimerGetFreq(pThis->CTX_SUFF(pSecondTimer));
+ TMTimerSet(pThis->CTX_SUFF(pSecondTimer), pThis->next_second_time);
}
-#ifdef IN_RING3
+
+/* -=-=-=-=-=- Saved State -=-=-=-=-=- */
+
/**
* @copydoc FNSSMDEVLIVEEXEC
@@ -786,7 +818,7 @@ static void rtcCalcCRC(RTCState *pThis)
for (i = RTC_CRC_START, u16 = 0; i <= RTC_CRC_LAST; i++)
u16 += pThis->cmos_data[i];
- pThis->cmos_data[RTC_CRC_LOW] = u16 & 0xff;
+ pThis->cmos_data[RTC_CRC_LOW] = u16 & 0xff;
pThis->cmos_data[RTC_CRC_HIGH] = (u16 >> 8) & 0xff;
}
@@ -804,6 +836,8 @@ static DECLCALLBACK(int) rtcCMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t
RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
if (iReg < RT_ELEMENTS(pThis->cmos_data))
{
+ PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED);
+
pThis->cmos_data[iReg] = u8Value;
/* does it require checksum update? */
@@ -811,8 +845,10 @@ static DECLCALLBACK(int) rtcCMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t
&& iReg <= RTC_CRC_LAST)
rtcCalcCRC(pThis);
+ PDMCritSectLeave(pDevIns->pCritSectRoR3);
return VINF_SUCCESS;
}
+
AssertMsgFailed(("iReg=%d\n", iReg));
return VERR_INVALID_PARAMETER;
}
@@ -831,7 +867,11 @@ static DECLCALLBACK(int) rtcCMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t
RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
if (iReg < RT_ELEMENTS(pThis->cmos_data))
{
+ PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED);
+
*pu8Value = pThis->cmos_data[iReg];
+
+ PDMCritSectLeave(pDevIns->pCritSectRoR3);
return VINF_SUCCESS;
}
AssertMsgFailed(("iReg=%d\n", iReg));
@@ -839,8 +879,37 @@ static DECLCALLBACK(int) rtcCMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t
}
+/**
+ * @interface_method_impl{PDMIHPETLEGACYNOTIFY,pfnModeChanged}
+ */
+static DECLCALLBACK(void) rtcHpetLegacyNotify_ModeChanged(PPDMIHPETLEGACYNOTIFY pInterface, bool fActivated)
+{
+ RTCState *pThis = RT_FROM_MEMBER(pInterface, RTCState, IHpetLegacyNotify);
+ PDMCritSectEnter(pThis->pDevInsR3->pCritSectRoR3, VERR_IGNORED);
+
+ pThis->fDisabledByHpet = fActivated;
+
+ PDMCritSectLeave(pThis->pDevInsR3->pCritSectRoR3);
+}
+
+
/* -=-=-=-=-=- based on bits from pc.c -=-=-=-=-=- */
+
+static void rtc_set_memory(RTCState *pThis, int addr, int val)
+{
+ if (addr >= 0 && addr <= 127)
+ pThis->cmos_data[addr] = val;
+}
+
+
+static void rtc_set_date(RTCState *pThis, const struct my_tm *tm)
+{
+ pThis->current_tm = *tm;
+ rtc_copy_date(pThis);
+}
+
+
/** @copydoc FNPDMDEVINITCOMPLETE */
static DECLCALLBACK(int) rtcInitComplete(PPDMDEVINS pDevIns)
{
@@ -872,8 +941,8 @@ static DECLCALLBACK(int) rtcInitComplete(PPDMDEVINS pDevIns)
rtc_set_date(pThis, &Tm);
int iYear = to_bcd(pThis, (Tm.tm_year / 100) + 19); /* tm_year is 1900 based */
- rtc_set_memory(pThis, 0x32, iYear); /* 32h - Century Byte (BCD value for the century */
- rtc_set_memory(pThis, 0x37, iYear); /* 37h - (IBM PS/2) Date Century Byte */
+ rtc_set_memory(pThis, 0x32, iYear); /* 32h - Century Byte (BCD value for the century */
+ rtc_set_memory(pThis, 0x37, iYear); /* 37h - (IBM PS/2) Date Century Byte */
/*
* Recalculate the checksum just in case.
@@ -900,17 +969,6 @@ static DECLCALLBACK(void *) rtcQueryInterface(PPDMIBASE pInterface, const char *
return NULL;
}
-
-/**
- * @interface_method_impl{PDMIHPETLEGACYNOTIFY,pfnModeChanged}
- */
-static DECLCALLBACK(void) rtcHpetLegacyNotify_ModeChanged(PPDMIHPETLEGACYNOTIFY pInterface, bool fActivated)
-{
- RTCState *pThis = RT_FROM_MEMBER(pInterface, RTCState, IHpetLegacyNotify);
- pThis->fDisabledByHpet = fActivated;
-}
-
-
/**
* @copydoc
*/
@@ -999,56 +1057,71 @@ static DECLCALLBACK(int) rtcConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
pThis->IHpetLegacyNotify.pfnModeChanged = rtcHpetLegacyNotify_ModeChanged;
/*
- * Create timers, arm them, register I/O Ports and save state.
+ * Create timers.
*/
+ PTMTIMER pTimer;
+ /* Periodic timer. */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerPeriodic, pThis,
TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC/CMOS - Periodic",
- &pThis->pPeriodicTimerR3);
+ &pTimer);
if (RT_FAILURE(rc))
return rc;
- pThis->pPeriodicTimerR0 = TMTimerR0Ptr(pThis->pPeriodicTimerR3);
- pThis->pPeriodicTimerRC = TMTimerRCPtr(pThis->pPeriodicTimerR3);
+ pThis->pPeriodicTimerR3 = pTimer;
+ pThis->pPeriodicTimerR0 = TMTimerR0Ptr(pTimer);
+ pThis->pPeriodicTimerRC = TMTimerRCPtr(pTimer);
+ /* Seconds timer. */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerSecond, pThis,
TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC/CMOS - Second",
- &pThis->pSecondTimerR3);
+ &pTimer);
if (RT_FAILURE(rc))
return rc;
- pThis->pSecondTimerR0 = TMTimerR0Ptr(pThis->pSecondTimerR3);
- pThis->pSecondTimerRC = TMTimerRCPtr(pThis->pSecondTimerR3);
+ pThis->pSecondTimerR3 = pTimer;
+ pThis->pSecondTimerR0 = TMTimerR0Ptr(pTimer);
+ pThis->pSecondTimerRC = TMTimerRCPtr(pTimer);
+ /* The second2 timer, this is always active. */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerSecond2, pThis,
TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC/CMOS - Second2",
- &pThis->pSecondTimer2R3);
- if (RT_FAILURE(rc))
- return rc;
- pThis->pSecondTimer2R0 = TMTimerR0Ptr(pThis->pSecondTimer2R3);
- pThis->pSecondTimer2RC = TMTimerRCPtr(pThis->pSecondTimer2R3);
- pThis->next_second_time = TMTimerGet(pThis->CTX_SUFF(pSecondTimer2))
- + (TMTimerGetFreq(pThis->CTX_SUFF(pSecondTimer2)) * 99) / 100;
- rc = TMTimerSet(pThis->CTX_SUFF(pSecondTimer2), pThis->next_second_time);
+ &pTimer);
if (RT_FAILURE(rc))
return rc;
+ pThis->pSecondTimer2R3 = pTimer;
+ pThis->pSecondTimer2R0 = TMTimerR0Ptr(pTimer);
+ pThis->pSecondTimer2RC = TMTimerRCPtr(pTimer);
+ pThis->next_second_time = TMTimerGet(pTimer)
+ + (TMTimerGetFreq(pTimer) * 99) / 100;
+ rc = TMTimerLock(pTimer, VERR_IGNORED);
+ AssertRCReturn(rc, rc);
+ rc = TMTimerSet(pTimer, pThis->next_second_time);
+ TMTimerUnlock(pTimer);
+ AssertRCReturn(rc, rc);
+ /*
+ * Register I/O ports.
+ */
rc = PDMDevHlpIOPortRegister(pDevIns, pThis->IOPortBase, 4, NULL,
rtcIOPortWrite, rtcIOPortRead, NULL, NULL, "MC146818 RTC/CMOS");
if (RT_FAILURE(rc))
return rc;
if (fGCEnabled)
{
- rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->IOPortBase, 4, 0,
+ rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->IOPortBase, 4, NIL_RTRCPTR,
"rtcIOPortWrite", "rtcIOPortRead", NULL, NULL, "MC146818 RTC/CMOS");
if (RT_FAILURE(rc))
return rc;
}
if (fR0Enabled)
{
- rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->IOPortBase, 4, 0,
+ rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->IOPortBase, 4, NIL_RTR0PTR,
"rtcIOPortWrite", "rtcIOPortRead", NULL, NULL, "MC146818 RTC/CMOS");
if (RT_FAILURE(rc))
return rc;
}
+ /*
+ * Register the saved state.
+ */
rc = PDMDevHlpSSMRegister3(pDevIns, RTC_SAVED_STATE_VERSION, sizeof(*pThis), rtcLiveExec, rtcSaveExec, rtcLoadExec);
if (RT_FAILURE(rc))
return rc;
diff --git a/src/VBox/Devices/PC/DevSMC.cpp b/src/VBox/Devices/PC/DevSMC.cpp
index 01e76a0f5..a8047ee4b 100644
--- a/src/VBox/Devices/PC/DevSMC.cpp
+++ b/src/VBox/Devices/PC/DevSMC.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevSMC.cpp $ */
+/* $Id: DevSMC.cpp 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* DevSMC - SMC device emulation.
*/
diff --git a/src/VBox/Devices/PC/DrvACPI.cpp b/src/VBox/Devices/PC/DrvACPI.cpp
index 37e8cd569..4637b78f2 100644
--- a/src/VBox/Devices/PC/DrvACPI.cpp
+++ b/src/VBox/Devices/PC/DrvACPI.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvACPI.cpp $ */
+/* $Id: DrvACPI.cpp 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* DrvACPI - ACPI Host Driver.
*/
diff --git a/src/VBox/Devices/PC/DrvAcpiCpu.cpp b/src/VBox/Devices/PC/DrvAcpiCpu.cpp
index eebcfcb6b..70da6678b 100644
--- a/src/VBox/Devices/PC/DrvAcpiCpu.cpp
+++ b/src/VBox/Devices/PC/DrvAcpiCpu.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvAcpiCpu.cpp $ */
+/* $Id: DrvAcpiCpu.cpp 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* DrvAcpiCpu - ACPI CPU dummy driver for hotplugging.
*/
diff --git a/src/VBox/Devices/PC/Etherboot-src/Makefile.kmk b/src/VBox/Devices/PC/Etherboot-src/Makefile.kmk
index 92e3dd14c..a5a9d0fab 100644
--- a/src/VBox/Devices/PC/Etherboot-src/Makefile.kmk
+++ b/src/VBox/Devices/PC/Etherboot-src/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35399 2011-01-04 09:40:13Z vboxsync $
## @file
# VBox Etherboot Network boot ROM makefile.
#
diff --git a/src/VBox/Devices/PC/Etherboot-src/arch/i386/drivers/net/undi.c b/src/VBox/Devices/PC/Etherboot-src/arch/i386/drivers/net/undi.c
index 857a5dfee..6ba9ea2de 100644
--- a/src/VBox/Devices/PC/Etherboot-src/arch/i386/drivers/net/undi.c
+++ b/src/VBox/Devices/PC/Etherboot-src/arch/i386/drivers/net/undi.c
@@ -6,7 +6,7 @@ This file Copyright (C) 2003 Michael Brown <mbrown@fensystems.co.uk>
of Fen Systems Ltd. (http://www.fensystems.co.uk/). All rights
reserved.
-$Id: undi.c $
+$Id: undi.c 33656 2010-11-01 14:18:11Z vboxsync $
***************************************************************************/
/*
diff --git a/src/VBox/Devices/PC/Etherboot-src/arch/i386/drivers/net/undi.h b/src/VBox/Devices/PC/Etherboot-src/arch/i386/drivers/net/undi.h
index 535d2354d..ba0a07310 100644
--- a/src/VBox/Devices/PC/Etherboot-src/arch/i386/drivers/net/undi.h
+++ b/src/VBox/Devices/PC/Etherboot-src/arch/i386/drivers/net/undi.h
@@ -6,7 +6,7 @@ This file Copyright (C) 2003 Michael Brown <mbrown@fensystems.co.uk>
of Fen Systems Ltd. (http://www.fensystems.co.uk/). All rights
reserved.
-$Id: undi.h $
+$Id: undi.h 33656 2010-11-01 14:18:11Z vboxsync $
***************************************************************************/
/*
diff --git a/src/VBox/Devices/PC/Etherboot-src/arch/i386/firmware/pcbios/basemem.c b/src/VBox/Devices/PC/Etherboot-src/arch/i386/firmware/pcbios/basemem.c
index 5ba665960..8339ee020 100644
--- a/src/VBox/Devices/PC/Etherboot-src/arch/i386/firmware/pcbios/basemem.c
+++ b/src/VBox/Devices/PC/Etherboot-src/arch/i386/firmware/pcbios/basemem.c
@@ -7,7 +7,7 @@
* updating the Free Base Memory Size counter at 40:13h.
*
* Michael Brown <mbrown@fensystems.co.uk> (mcb30)
- * $Id: basemem.c $
+ * $Id: basemem.c 1 vboxsync $
*/
#define fbms ( ( uint16_t * ) phys_to_virt ( 0x413 ) )
diff --git a/src/VBox/Devices/PC/Etherboot-src/arch/i386/include/callbacks_arch.h b/src/VBox/Devices/PC/Etherboot-src/arch/i386/include/callbacks_arch.h
index 1deef4253..47dbe33c2 100644
--- a/src/VBox/Devices/PC/Etherboot-src/arch/i386/include/callbacks_arch.h
+++ b/src/VBox/Devices/PC/Etherboot-src/arch/i386/include/callbacks_arch.h
@@ -5,7 +5,7 @@
*
* Initial version by Michael Brown <mbrown@fensystems.co.uk>, January 2004.
*
- * $Id: callbacks_arch.h $
+ * $Id: callbacks_arch.h 1 vboxsync $
*/
#ifndef CALLBACKS_ARCH_H
diff --git a/src/VBox/Devices/PC/Etherboot-src/core/dns_resolver.c b/src/VBox/Devices/PC/Etherboot-src/core/dns_resolver.c
index f862bd6b6..cf8b3cb6d 100644
--- a/src/VBox/Devices/PC/Etherboot-src/core/dns_resolver.c
+++ b/src/VBox/Devices/PC/Etherboot-src/core/dns_resolver.c
@@ -22,8 +22,8 @@
* This code is using nuts and bolts from throughout etherboot.
* It is a fresh implementation according to the DNS RFC, #1035
*
-* $Revision: 67272 $
-* $Author: umoeller $
+* $Revision: 33656 $
+* $Author: vboxsync $
* $Date: 2010-11-01 15:18:11 +0100 (Mon, 01 Nov 2010) $
*
* REVISION HISTORY:
diff --git a/src/VBox/Devices/PC/Etherboot-src/genrules.pl b/src/VBox/Devices/PC/Etherboot-src/genrules.pl
index 3cf9c6d84..3cf9c6d84 100755..100644
--- a/src/VBox/Devices/PC/Etherboot-src/genrules.pl
+++ b/src/VBox/Devices/PC/Etherboot-src/genrules.pl
diff --git a/src/VBox/Devices/PC/Etherboot-src/include/callbacks.h b/src/VBox/Devices/PC/Etherboot-src/include/callbacks.h
index 95ba2af9b..2f635f27f 100644
--- a/src/VBox/Devices/PC/Etherboot-src/include/callbacks.h
+++ b/src/VBox/Devices/PC/Etherboot-src/include/callbacks.h
@@ -5,7 +5,7 @@
*
* Initial version by Michael Brown <mbrown@fensystems.co.uk>, January 2004.
*
- * $Id: callbacks.h $
+ * $Id: callbacks.h 1 vboxsync $
*/
#ifndef CALLBACKS_H
diff --git a/src/VBox/Devices/PC/Etherboot-src/include/pxe.h b/src/VBox/Devices/PC/Etherboot-src/include/pxe.h
index ec12cddce..396891864 100644
--- a/src/VBox/Devices/PC/Etherboot-src/include/pxe.h
+++ b/src/VBox/Devices/PC/Etherboot-src/include/pxe.h
@@ -632,7 +632,7 @@ typedef struct {
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: pxe.h $
+ * $Id: pxe.h 1 vboxsync $
*/
/*
diff --git a/src/VBox/Devices/PC/Etherboot-src/util/catrom.pl b/src/VBox/Devices/PC/Etherboot-src/util/catrom.pl
index fe37e6b6e..fe37e6b6e 100755..100644
--- a/src/VBox/Devices/PC/Etherboot-src/util/catrom.pl
+++ b/src/VBox/Devices/PC/Etherboot-src/util/catrom.pl
diff --git a/src/VBox/Devices/PC/Etherboot-src/util/disrom.pl b/src/VBox/Devices/PC/Etherboot-src/util/disrom.pl
index 64128698c..64128698c 100755..100644
--- a/src/VBox/Devices/PC/Etherboot-src/util/disrom.pl
+++ b/src/VBox/Devices/PC/Etherboot-src/util/disrom.pl
diff --git a/src/VBox/Devices/PC/Etherboot-src/util/geniso b/src/VBox/Devices/PC/Etherboot-src/util/geniso
index cf0469902..cf0469902 100755..100644
--- a/src/VBox/Devices/PC/Etherboot-src/util/geniso
+++ b/src/VBox/Devices/PC/Etherboot-src/util/geniso
diff --git a/src/VBox/Devices/PC/Etherboot-src/util/genliso b/src/VBox/Devices/PC/Etherboot-src/util/genliso
index b8d9a11df..b8d9a11df 100755..100644
--- a/src/VBox/Devices/PC/Etherboot-src/util/genliso
+++ b/src/VBox/Devices/PC/Etherboot-src/util/genliso
diff --git a/src/VBox/Devices/PC/Etherboot-src/util/get-pci-ids b/src/VBox/Devices/PC/Etherboot-src/util/get-pci-ids
index 6501a7f7c..6501a7f7c 100755..100644
--- a/src/VBox/Devices/PC/Etherboot-src/util/get-pci-ids
+++ b/src/VBox/Devices/PC/Etherboot-src/util/get-pci-ids
diff --git a/src/VBox/Devices/PC/Etherboot-src/util/makelilo.pl b/src/VBox/Devices/PC/Etherboot-src/util/makelilo.pl
index 8f995bc46..8f995bc46 100755..100644
--- a/src/VBox/Devices/PC/Etherboot-src/util/makelilo.pl
+++ b/src/VBox/Devices/PC/Etherboot-src/util/makelilo.pl
diff --git a/src/VBox/Devices/PC/Etherboot-src/util/makerom.pl b/src/VBox/Devices/PC/Etherboot-src/util/makerom.pl
index 9d751e190..9d751e190 100755..100644
--- a/src/VBox/Devices/PC/Etherboot-src/util/makerom.pl
+++ b/src/VBox/Devices/PC/Etherboot-src/util/makerom.pl
diff --git a/src/VBox/Devices/PC/Etherboot-src/util/modrom.pl b/src/VBox/Devices/PC/Etherboot-src/util/modrom.pl
index 695468c26..695468c26 100755..100644
--- a/src/VBox/Devices/PC/Etherboot-src/util/modrom.pl
+++ b/src/VBox/Devices/PC/Etherboot-src/util/modrom.pl
diff --git a/src/VBox/Devices/PC/Etherboot-src/util/swapdevids.pl b/src/VBox/Devices/PC/Etherboot-src/util/swapdevids.pl
index c6255ae73..c6255ae73 100755..100644
--- a/src/VBox/Devices/PC/Etherboot-src/util/swapdevids.pl
+++ b/src/VBox/Devices/PC/Etherboot-src/util/swapdevids.pl
diff --git a/src/VBox/Devices/PC/Etherboot-src/util/zfilelen.pl b/src/VBox/Devices/PC/Etherboot-src/util/zfilelen.pl
index 1f58ff9ee..1f58ff9ee 100755..100644
--- a/src/VBox/Devices/PC/Etherboot-src/util/zfilelen.pl
+++ b/src/VBox/Devices/PC/Etherboot-src/util/zfilelen.pl
diff --git a/src/VBox/Devices/PC/vbox-cpuhotplug.dsl b/src/VBox/Devices/PC/vbox-cpuhotplug.dsl
index 9da7063c4..b51670c83 100644
--- a/src/VBox/Devices/PC/vbox-cpuhotplug.dsl
+++ b/src/VBox/Devices/PC/vbox-cpuhotplug.dsl
@@ -1,4 +1,4 @@
-// $Id: vbox-cpuhotplug.dsl $
+// $Id: vbox-cpuhotplug.dsl 32786 2010-09-28 09:54:55Z vboxsync $
/// @file
//
// VirtualBox ACPI
diff --git a/src/VBox/Devices/PC/vbox-standard.dsl b/src/VBox/Devices/PC/vbox-standard.dsl
index a7bec34c7..52372876a 100644
--- a/src/VBox/Devices/PC/vbox-standard.dsl
+++ b/src/VBox/Devices/PC/vbox-standard.dsl
@@ -1,4 +1,4 @@
-// $Id: vbox-standard.dsl $
+// $Id: vbox-standard.dsl 28800 2010-04-27 08:22:32Z vboxsync $
/// @file
//
// VirtualBox ACPI
diff --git a/src/VBox/Devices/PC/vbox.dsl b/src/VBox/Devices/PC/vbox.dsl
index a23b2fcdb..c4bf42c38 100644
--- a/src/VBox/Devices/PC/vbox.dsl
+++ b/src/VBox/Devices/PC/vbox.dsl
@@ -1,4 +1,4 @@
-// $Id: vbox.dsl $
+// $Id: vbox.dsl 35782 2011-01-31 11:25:55Z vboxsync $
/// @file
//
// VirtualBox ACPI
@@ -149,6 +149,10 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, "VBOX ", "VBOXBIOS", 2)
HBCA, 32, // host bus controller address
PCIB, 32, // PCI MCFG base start
PCIL, 32, // PCI MCFG length
+ SL0B, 32, // Serial0 base IO address
+ SL0I, 32, // Serial0 IRQ
+ SL1B, 32, // Serial1 base IO address
+ SL1I, 32, // Serial1 IRQ
Offset (0x80),
ININ, 32,
Offset (0x200),
@@ -678,6 +682,72 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, "VBOX ", "VBOXBIOS", 2)
})
}
+ // Serial port 0
+ Device (^SRL0)
+ {
+ Name (_HID, EisaId ("PNP0501"))
+ Name (_UID, 0x01)
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LEqual (SL0B, Zero))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ Name (CRS, ResourceTemplate ()
+ {
+ IO (Decode16, 0x03F8, 0x03F8, 0x01, 0x08, _Y14)
+ IRQNoFlags (_Y15) {4}
+ })
+ Method (_CRS, 0, NotSerialized)
+ {
+ CreateWordField (CRS, \_SB.PCI0.SRL0._Y14._MIN, MIN0)
+ CreateWordField (CRS, \_SB.PCI0.SRL0._Y14._MAX, MAX0)
+ CreateWordField (CRS, \_SB.PCI0.SRL0._Y15._INT, IRQ0)
+ Store (SL0B, MIN0)
+ Store (SL0B, MAX0)
+ ShiftLeft (0x01, SL0I, IRQ0)
+ Return (CRS)
+ }
+ }
+
+ // Serial port 1
+ Device (^SRL1)
+ {
+ Name (_HID, EisaId ("PNP0501"))
+ Name (_UID, 0x02)
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LEqual (SL1B, Zero))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ Name (CRS, ResourceTemplate ()
+ {
+ IO (Decode16, 0x02F8, 0x02F8, 0x01, 0x08, _Y16)
+ IRQNoFlags (_Y17) {3}
+ })
+ Method (_CRS, 0, NotSerialized)
+ {
+ CreateWordField (CRS, \_SB.PCI0.SRL1._Y16._MIN, MIN1)
+ CreateWordField (CRS, \_SB.PCI0.SRL1._Y16._MAX, MAX1)
+ CreateWordField (CRS, \_SB.PCI0.SRL1._Y17._INT, IRQ1)
+ Store (SL1B, MIN1)
+ Store (SL1B, MAX1)
+ ShiftLeft (0x01, SL1I, IRQ1)
+ Return (CRS)
+ }
+ }
+
// Programmable Interval Timer (i8254)
Device (TIMR)
{
diff --git a/src/VBox/Devices/Parallel/DevParallel.cpp b/src/VBox/Devices/Parallel/DevParallel.cpp
index fb1864400..10eed9e4d 100644
--- a/src/VBox/Devices/Parallel/DevParallel.cpp
+++ b/src/VBox/Devices/Parallel/DevParallel.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevParallel.cpp $ */
+/* $Id: DevParallel.cpp 37466 2011-06-15 12:44:16Z vboxsync $ */
/** @file
* DevParallel - Parallel (Port) Device Emulation.
*
@@ -748,7 +748,7 @@ static DECLCALLBACK(int) parallelConstruct(PPDMDEVINS pDevIns,
* Initialize critical section and event semaphore.
* This must of course be done before attaching drivers or anything else which can call us back..
*/
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "Parallel#%d", iInstance);
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "Parallel#%u", iInstance);
if (RT_FAILURE(rc))
return rc;
diff --git a/src/VBox/Devices/Parallel/DrvHostParallel.cpp b/src/VBox/Devices/Parallel/DrvHostParallel.cpp
index 749e2b18a..6b8fdc193 100644
--- a/src/VBox/Devices/Parallel/DrvHostParallel.cpp
+++ b/src/VBox/Devices/Parallel/DrvHostParallel.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvHostParallel.cpp $ */
+/* $Id: DrvHostParallel.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VirtualBox Host Parallel Port Driver.
*
@@ -26,6 +26,7 @@
#include <iprt/asm.h>
#include <iprt/assert.h>
#include <iprt/file.h>
+#include <iprt/pipe.h>
#include <iprt/semaphore.h>
#include <iprt/stream.h>
#include <iprt/uuid.h>
@@ -63,13 +64,13 @@ typedef struct DRVHOSTPARALLEL
/** Device Path */
char *pszDevicePath;
/** Device Handle */
- RTFILE FileDevice;
+ RTFILE hFileDevice;
/** Thread waiting for interrupts. */
PPDMTHREAD pMonitorThread;
/** Wakeup pipe read end. */
- RTFILE WakeupPipeR;
+ RTPIPE hWakeupPipeR;
/** Wakeup pipe write end. */
- RTFILE WakeupPipeW;
+ RTPIPE hWakeupPipeW;
} DRVHOSTPARALLEL, *PDRVHOSTPARALLEL;
/** Converts a pointer to DRVHOSTPARALLEL::IHostDeviceConnector to a PDRHOSTPARALLEL. */
@@ -101,7 +102,7 @@ static DECLCALLBACK(int) drvHostParallelWrite(PPDMIHOSTPARALLELCONNECTOR pInterf
LogFlow(("%s: pvBuf=%#p cbWrite=%d\n", __FUNCTION__, pvBuf, *cbWrite));
- ioctl(pThis->FileDevice, PPWDATA, pBuffer);
+ ioctl(RTFileToNative(pThis->hFileDevice), PPWDATA, pBuffer);
*cbWrite = 1;
return VINF_SUCCESS;
@@ -114,7 +115,7 @@ static DECLCALLBACK(int) drvHostParallelRead(PPDMIHOSTPARALLELCONNECTOR pInterfa
LogFlow(("%s: pvBuf=%#p cbRead=%d\n", __FUNCTION__, pvBuf, cbRead));
- ioctl(pThis->FileDevice, PPRDATA, pBuffer);
+ ioctl(RTFileToNative(pThis->hFileDevice), PPRDATA, pBuffer);
*cbRead = 1;
return VINF_SUCCESS;
@@ -139,7 +140,7 @@ static DECLCALLBACK(int) drvHostParallelSetMode(PPDMIHOSTPARALLELCONNECTOR pInte
break;
}
- ioctl(pThis->FileDevice, PPSETMODE, &ppdev_mode);
+ ioctl(RTFileToNative(pThis->hFileDevice), PPSETMODE, &ppdev_mode);
return VINF_SUCCESS;
}
@@ -149,8 +150,7 @@ static DECLCALLBACK(int) drvHostParallelWriteControl(PPDMIHOSTPARALLELCONNECTOR
PDRVHOSTPARALLEL pThis = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface);
LogFlow(("%s: fReg=%d\n", __FUNCTION__, fReg));
-
- ioctl(pThis->FileDevice, PPWCONTROL, &fReg);
+ ioctl(RTFileToNative(pThis->hFileDevice), PPWCONTROL, &fReg);
return VINF_SUCCESS;
}
@@ -158,12 +158,10 @@ static DECLCALLBACK(int) drvHostParallelWriteControl(PPDMIHOSTPARALLELCONNECTOR
static DECLCALLBACK(int) drvHostParallelReadControl(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t *pfReg)
{
PDRVHOSTPARALLEL pThis = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface);
- uint8_t fReg;
-
- ioctl(pThis->FileDevice, PPRCONTROL, &fReg);
+ uint8_t fReg = 0;
+ ioctl(RTFileToNative(pThis->hFileDevice), PPRCONTROL, &fReg);
LogFlow(("%s: fReg=%d\n", __FUNCTION__, fReg));
-
*pfReg = fReg;
return VINF_SUCCESS;
@@ -172,12 +170,10 @@ static DECLCALLBACK(int) drvHostParallelReadControl(PPDMIHOSTPARALLELCONNECTOR p
static DECLCALLBACK(int) drvHostParallelReadStatus(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t *pfReg)
{
PDRVHOSTPARALLEL pThis = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface);
- uint8_t fReg;
-
- ioctl(pThis->FileDevice, PPRSTATUS, &fReg);
+ uint8_t fReg = 0;
+ ioctl(RTFileToNative(pThis->hFileDevice), PPRSTATUS, &fReg);
LogFlow(("%s: fReg=%d\n", __FUNCTION__, fReg));
-
*pfReg = fReg;
return VINF_SUCCESS;
@@ -195,10 +191,10 @@ static DECLCALLBACK(int) drvHostParallelMonitorThread(PPDMDRVINS pDrvIns, PPDMTH
{
int rc;
- aFDs[0].fd = pThis->FileDevice;
+ aFDs[0].fd = RTFileToNative(pThis->hFileDevice);
aFDs[0].events = POLLIN;
aFDs[0].revents = 0;
- aFDs[1].fd = pThis->WakeupPipeR;
+ aFDs[1].fd = RTPipeToNative(pThis->hWakeupPipeR);
aFDs[1].events = POLLIN | POLLERR | POLLHUP;
aFDs[1].revents = 0;
rc = poll(aFDs, RT_ELEMENTS(aFDs), -1);
@@ -217,7 +213,7 @@ static DECLCALLBACK(int) drvHostParallelMonitorThread(PPDMDRVINS pDrvIns, PPDMTH
/* notification to terminate -- drain the pipe */
char ch;
size_t cbRead;
- RTFileRead(pThis->WakeupPipeR, &ch, 1, &cbRead);
+ RTPipeRead(pThis->hWakeupPipeR, &ch, 1, &cbRead);
continue;
}
@@ -239,8 +235,8 @@ static DECLCALLBACK(int) drvHostParallelMonitorThread(PPDMDRVINS pDrvIns, PPDMTH
static DECLCALLBACK(int) drvHostParallelWakeupMonitorThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
{
PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
-
- return RTFileWrite(pThis->WakeupPipeW, "", 1, NULL);
+ size_t cbIgnored;
+ return RTPipeWrite(pThis->hWakeupPipeW, "", 1, &cbIgnored);
}
/**
@@ -256,27 +252,20 @@ static DECLCALLBACK(void) drvHostParallelDestruct(PPDMDRVINS pDrvIns)
PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+ int rc;
- ioctl(pThis->FileDevice, PPRELEASE);
+ if (pThis->hFileDevice != NIL_RTFILE)
+ ioctl(RTFileToNative(pThis->hFileDevice), PPRELEASE);
+
+ rc = RTPipeClose(pThis->hWakeupPipeW); AssertRC(rc);
+ pThis->hWakeupPipeW = NIL_RTPIPE;
+
+ rc = RTPipeClose(pThis->hWakeupPipeR); AssertRC(rc);
+ pThis->hWakeupPipeR = NIL_RTPIPE;
+
+ rc = RTFileClose(pThis->hFileDevice); AssertRC(rc);
+ pThis->hFileDevice = NIL_RTFILE;
- if (pThis->WakeupPipeW != NIL_RTFILE)
- {
- int rc = RTFileClose(pThis->WakeupPipeW);
- AssertRC(rc);
- pThis->WakeupPipeW = NIL_RTFILE;
- }
- if (pThis->WakeupPipeR != NIL_RTFILE)
- {
- int rc = RTFileClose(pThis->WakeupPipeR);
- AssertRC(rc);
- pThis->WakeupPipeR = NIL_RTFILE;
- }
- if (pThis->FileDevice != NIL_RTFILE)
- {
- int rc = RTFileClose(pThis->FileDevice);
- AssertRC(rc);
- pThis->FileDevice = NIL_RTFILE;
- }
if (pThis->pszDevicePath)
{
MMR3HeapFree(pThis->pszDevicePath);
@@ -296,15 +285,13 @@ static DECLCALLBACK(int) drvHostParallelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE
PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
/*
- * Validate the config.
- */
- if (!CFGMR3AreValuesValid(pCfg, "DevicePath\0"))
- return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
- N_("Unknown host parallel configuration option, only supports DevicePath"));
-
- /*
* Init basic data members and interfaces.
+ *
+ * Must be done before returning any failure because we've got a destructor.
*/
+ pThis->hFileDevice = NIL_RTFILE;
+ pThis->hWakeupPipeR = NIL_RTPIPE;
+ pThis->hWakeupPipeW = NIL_RTPIPE;
/* IBase. */
pDrvIns->IBase.pfnQueryInterface = drvHostParallelQueryInterface;
@@ -317,6 +304,13 @@ static DECLCALLBACK(int) drvHostParallelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE
pThis->IHostParallelConnector.pfnReadStatus = drvHostParallelReadStatus;
/*
+ * Validate the config.
+ */
+ if (!CFGMR3AreValuesValid(pCfg, "DevicePath\0"))
+ return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
+ N_("Unknown host parallel configuration option, only supports DevicePath"));
+
+ /*
* Query configuration.
*/
/* Device */
@@ -330,7 +324,7 @@ static DECLCALLBACK(int) drvHostParallelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE
/*
* Open the device
*/
- rc = RTFileOpen(&pThis->FileDevice, pThis->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ rc = RTFileOpen(&pThis->hFileDevice, pThis->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (RT_FAILURE(rc))
return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Parallel#%d could not open '%s'"),
pDrvIns->iInstance, pThis->pszDevicePath);
@@ -338,7 +332,7 @@ static DECLCALLBACK(int) drvHostParallelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE
/*
* Try to get exclusive access to parallel port
*/
- rc = ioctl(pThis->FileDevice, PPEXCL);
+ rc = ioctl(RTFileToNative(pThis->hFileDevice), PPEXCL);
if (rc < 0)
return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS,
N_("Parallel#%d could not get exclusive access for parallel port '%s'"
@@ -348,7 +342,7 @@ static DECLCALLBACK(int) drvHostParallelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE
/*
* Claim the parallel port
*/
- rc = ioctl(pThis->FileDevice, PPCLAIM);
+ rc = ioctl(RTFileToNative(pThis->hFileDevice), PPCLAIM);
if (rc < 0)
return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS,
N_("Parallel#%d could not claim parallel port '%s'"
@@ -366,15 +360,8 @@ static DECLCALLBACK(int) drvHostParallelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE
/*
* Create wakeup pipe.
*/
- int aFDs[2];
- if (pipe(aFDs) != 0)
- {
- rc = RTErrConvertFromErrno(errno);
- AssertRC(rc);
- return rc;
- }
- pThis->WakeupPipeR = aFDs[0];
- pThis->WakeupPipeW = aFDs[1];
+ rc = RTPipeCreate(&pThis->hWakeupPipeR, &pThis->hWakeupPipeR, 0 /*fFlags*/);
+ AssertRCReturn(rc, rc);
/*
* Start waiting for interrupts.
diff --git a/src/VBox/Devices/Samples/Makefile.kmk b/src/VBox/Devices/Samples/Makefile.kmk
index 3d68ec672..1a1a8d71c 100644
--- a/src/VBox/Devices/Samples/Makefile.kmk
+++ b/src/VBox/Devices/Samples/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Makefile for the device and driver samples.
#
diff --git a/src/VBox/Devices/Samples/VBoxSampleDevice.cpp b/src/VBox/Devices/Samples/VBoxSampleDevice.cpp
index 926d0277f..cff444956 100644
--- a/src/VBox/Devices/Samples/VBoxSampleDevice.cpp
+++ b/src/VBox/Devices/Samples/VBoxSampleDevice.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxSampleDevice.cpp $ */
+/* $Id: VBoxSampleDevice.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBox Sample Device.
*/
diff --git a/src/VBox/Devices/Serial/DevSerial.cpp b/src/VBox/Devices/Serial/DevSerial.cpp
index 5f577f740..d9fa695e3 100644
--- a/src/VBox/Devices/Serial/DevSerial.cpp
+++ b/src/VBox/Devices/Serial/DevSerial.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevSerial.cpp $ */
+/* $Id: DevSerial.cpp 37466 2011-06-15 12:44:16Z vboxsync $ */
/** @file
* DevSerial - 16550A UART emulation.
* (taken from hw/serial.c 2010/05/15 with modifications)
@@ -277,7 +277,7 @@ static int fifo_put(SerialState *s, int fifo, uint8_t chr)
if (f->count < UART_FIFO_LENGTH)
f->count++;
else if (fifo == XMIT_FIFO) /* need to at least adjust tail to maintain pipe state consistency */
- ++f->tail;
+ ++f->tail;
else if (fifo == RECV_FIFO)
s->lsr |= UART_LSR_OE;
@@ -826,14 +826,13 @@ static DECLCALLBACK(int) serialNotifyBreak(PPDMICHARPORT pInterface)
*/
static DECLCALLBACK(void) serialFifoTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
{
- SerialState *s = (SerialState*)pvUser;
- PDMCritSectEnter(&s->CritSect, VERR_PERMISSION_DENIED);
- if (s->recv_fifo.count)
+ SerialState *pThis = (SerialState *)pvUser;
+ Assert(PDMCritSectIsOwner(&pThis->CritSect));
+ if (pThis->recv_fifo.count)
{
- s->timeout_ipending = 1;
- serial_update_irq(s);
+ pThis->timeout_ipending = 1;
+ serial_update_irq(pThis);
}
- PDMCritSectLeave(&s->CritSect);
}
/**
@@ -846,10 +845,9 @@ static DECLCALLBACK(void) serialFifoTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, v
*/
static DECLCALLBACK(void) serialTransmitTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
{
- SerialState *s = (SerialState*)pvUser;
- PDMCritSectEnter(&s->CritSect, VERR_PERMISSION_DENIED);
- serial_xmit(s, true);
- PDMCritSectLeave(&s->CritSect);
+ SerialState *pThis = (SerialState *)pvUser;
+ Assert(PDMCritSectIsOwner(&pThis->CritSect));
+ serial_xmit(pThis, true);
}
/**
@@ -905,20 +903,19 @@ PDMBOTHCBDECL(int) serialIOPortWrite(PPDMDEVINS pDevIns, void *pvUser,
RTIOPORT Port, uint32_t u32, unsigned cb)
{
SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
- int rc = VINF_SUCCESS;
+ int rc;
+ Assert(PDMCritSectIsOwner(&pThis->CritSect));
if (cb == 1)
{
- rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_HC_IOPORT_WRITE);
- if (rc == VINF_SUCCESS)
- {
- Log2(("%s: port %#06x val %#04x\n", __FUNCTION__, Port, u32));
- rc = serial_ioport_write(pThis, Port, u32);
- PDMCritSectLeave(&pThis->CritSect);
- }
+ Log2(("%s: port %#06x val %#04x\n", __FUNCTION__, Port, u32));
+ rc = serial_ioport_write(pThis, Port, u32);
}
else
+ {
AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
+ rc = VINF_SUCCESS;
+ }
return rc;
}
@@ -938,17 +935,13 @@ PDMBOTHCBDECL(int) serialIOPortRead(PPDMDEVINS pDevIns, void *pvUser,
RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
- int rc = VINF_SUCCESS;
+ int rc;
+ Assert(PDMCritSectIsOwner(&pThis->CritSect));
if (cb == 1)
{
- rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_HC_IOPORT_READ);
- if (rc == VINF_SUCCESS)
- {
- *pu32 = serial_ioport_read(pThis, Port, &rc);
- Log2(("%s: port %#06x val %#04x\n", __FUNCTION__, Port, *pu32));
- PDMCritSectLeave(&pThis->CritSect);
- }
+ *pu32 = serial_ioport_read(pThis, Port, &rc);
+ Log2(("%s: port %#06x val %#04x\n", __FUNCTION__, Port, *pu32));
}
else
rc = VERR_IOM_IOPORT_UNUSED;
@@ -1271,25 +1264,35 @@ static DECLCALLBACK(int) serialConstruct(PPDMDEVINS pDevIns, int iInstance, PCFG
LogRel(("Serial#%d: emulating %s\n", pDevIns->iInstance, pThis->f16550AEnabled ? "16550A" : "16450"));
/*
- * Initialize critical section and the semaphore.
- * This must of course be done before attaching drivers or anything else which can call us back..
+ * Initialize critical section and the semaphore. Change the default
+ * critical section to ours so that TM and IOM will enter it before
+ * calling us.
+ *
+ * Note! This must of be done BEFORE creating timers, registering I/O ports
+ * and other things which might pick up the default CS or end up
+ * calling back into the device.
*/
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "Serial#%d", iInstance);
- if (RT_FAILURE(rc))
- return rc;
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "Serial#%u", iInstance);
+ AssertRCReturn(rc, rc);
+
+ rc = PDMDevHlpSetDeviceCritSect(pDevIns, &pThis->CritSect);
+ AssertRCReturn(rc, rc);
rc = RTSemEventCreate(&pThis->ReceiveSem);
- AssertRC(rc);
+ AssertRCReturn(rc, rc);
+ /*
+ * Create the timers.
+ */
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, serialFifoTimer, pThis,
- TMTIMER_FLAGS_NO_CRIT_SECT, "Serial Fifo Timer",
+ TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "Serial Fifo Timer",
&pThis->fifo_timeout_timer);
- AssertRC(rc);
+ AssertRCReturn(rc, rc);
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, serialTransmitTimer, pThis,
- TMTIMER_FLAGS_NO_CRIT_SECT, "Serial Transmit Timer",
+ TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "Serial Transmit Timer",
&pThis->transmit_timerR3);
- AssertRC(rc);
+ AssertRCReturn(rc, rc);
pThis->transmit_timerR0 = TMTimerR0Ptr(pThis->transmit_timerR3);
pThis->transmit_timerRC = TMTimerRCPtr(pThis->transmit_timerR3);
diff --git a/src/VBox/Devices/Serial/DrvChar.cpp b/src/VBox/Devices/Serial/DrvChar.cpp
index 3cf69c33d..a753a92eb 100644
--- a/src/VBox/Devices/Serial/DrvChar.cpp
+++ b/src/VBox/Devices/Serial/DrvChar.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvChar.cpp $ */
+/* $Id: DrvChar.cpp 37114 2011-05-16 16:34:49Z vboxsync $ */
/** @file
* Driver that adapts PDMISTREAM into PDMICHARCONNECTOR / PDMICHARPORT.
*
@@ -173,7 +173,10 @@ static DECLCALLBACK(int) drvCharSendLoop(RTTHREAD ThreadSelf, void *pvUser)
{
/* Normal case, just means that the stream didn't accept a new
* character before the timeout elapsed. Just retry. */
- rc = VINF_SUCCESS;
+
+ /* do not change the rc status here, otherwise the (rc == VERR_TIMEOUT) branch
+ * in the wait above will never get executed */
+ /* rc = VINF_SUCCESS; */
}
else
{
@@ -301,8 +304,6 @@ static DECLCALLBACK(void) drvCharDestruct(PPDMDRVINS pDrvIns)
if (pThis->SendSem != NIL_RTSEMEVENT)
{
RTSemEventSignal(pThis->SendSem);
- RTSemEventDestroy(pThis->SendSem);
- pThis->SendSem = NIL_RTSEMEVENT;
}
/*
@@ -326,6 +327,12 @@ static DECLCALLBACK(void) drvCharDestruct(PPDMDRVINS pDrvIns)
else
LogRel(("Char%d: send thread did not terminate (%Rrc)\n", pDrvIns->iInstance, rc));
}
+
+ if (pThis->SendSem != NIL_RTSEMEVENT)
+ {
+ RTSemEventDestroy(pThis->SendSem);
+ pThis->SendSem = NIL_RTSEMEVENT;
+ }
}
diff --git a/src/VBox/Devices/Serial/DrvHostSerial.cpp b/src/VBox/Devices/Serial/DrvHostSerial.cpp
index 39ab8b2a1..073f3abe6 100644
--- a/src/VBox/Devices/Serial/DrvHostSerial.cpp
+++ b/src/VBox/Devices/Serial/DrvHostSerial.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvHostSerial.cpp $ */
+/* $Id: DrvHostSerial.cpp 37597 2011-06-22 20:54:05Z vboxsync $ */
/** @file
* VBox stream I/O devices: Host serial driver
*/
@@ -29,6 +29,7 @@
#include <iprt/assert.h>
#include <iprt/file.h>
#include <iprt/mem.h>
+#include <iprt/pipe.h>
#include <iprt/semaphore.h>
#include <iprt/uuid.h>
@@ -102,16 +103,16 @@ typedef struct DRVHOSTSERIAL
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
/** the device handle */
- RTFILE DeviceFile;
+ RTFILE hDeviceFile;
# ifdef RT_OS_DARWIN
/** The device handle used for reading.
* Used to prevent the read select from blocking the writes. */
- RTFILE DeviceFileR;
+ RTFILE hDeviceFileR;
# endif
/** The read end of the control pipe */
- RTFILE WakeupPipeR;
+ RTPIPE hWakeupPipeR;
/** The write end of the control pipe */
- RTFILE WakeupPipeW;
+ RTPIPE hWakeupPipeW;
# ifndef RT_OS_LINUX
/** The current line status.
* Used by the polling version of drvHostSerialMonitorThread. */
@@ -264,14 +265,14 @@ static DECLCALLBACK(int) drvHostSerialSetParameters(PPDMICHARCONNECTOR pInterfac
default:
#ifdef RT_OS_LINUX
struct serial_struct serialStruct;
- if (ioctl(pThis->DeviceFile, TIOCGSERIAL, &serialStruct) != -1)
+ if (ioctl(RTFileToNative(pThis->hDeviceFile), TIOCGSERIAL, &serialStruct) != -1)
{
serialStruct.custom_divisor = serialStruct.baud_base / Bps;
if (!serialStruct.custom_divisor)
serialStruct.custom_divisor = 1;
serialStruct.flags &= ~ASYNC_SPD_MASK;
serialStruct.flags |= ASYNC_SPD_CUST;
- ioctl(pThis->DeviceFile, TIOCSSERIAL, &serialStruct);
+ ioctl(RTFileToNative(pThis->hDeviceFile), TIOCSSERIAL, &serialStruct);
baud_rate = B38400;
}
else
@@ -327,7 +328,7 @@ static DECLCALLBACK(int) drvHostSerialSetParameters(PPDMICHARCONNECTOR pInterfac
/* set serial port to raw input */
termiosSetup->c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL | ECHOK | ISIG | IEXTEN);
- tcsetattr(pThis->DeviceFile, TCSANOW, termiosSetup);
+ tcsetattr(RTFileToNative(pThis->hDeviceFile), TCSANOW, termiosSetup);
RTMemTmpFree(termiosSetup);
#ifdef RT_OS_LINUX
@@ -485,7 +486,7 @@ static DECLCALLBACK(int) drvHostSerialSendThread(PPDMDRVINS pDrvIns, PPDMTHREAD
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
size_t cbWritten;
- rc = RTFileWrite(pThis->DeviceFile, &ch, 1, &cbWritten);
+ rc = RTFileWrite(pThis->hDeviceFile, &ch, 1, &cbWritten);
if (rc == VERR_TRY_AGAIN)
cbWritten = 0;
if (cbWritten < 1 && (RT_SUCCESS(rc) || rc == VERR_TRY_AGAIN))
@@ -497,21 +498,21 @@ static DECLCALLBACK(int) drvHostSerialSendThread(PPDMDRVINS pDrvIns, PPDMTHREAD
/* wait */
fd_set WrSet;
FD_ZERO(&WrSet);
- FD_SET(pThis->DeviceFile, &WrSet);
+ FD_SET(RTFileToNative(pThis->hDeviceFile), &WrSet);
fd_set XcptSet;
FD_ZERO(&XcptSet);
- FD_SET(pThis->DeviceFile, &XcptSet);
+ FD_SET(RTFileToNative(pThis->hDeviceFile), &XcptSet);
# ifdef DEBUG
uint64_t u64Now = RTTimeMilliTS();
# endif
- rc = select(pThis->DeviceFile + 1, NULL, &WrSet, &XcptSet, NULL);
+ rc = select(RTFileToNative(pThis->hDeviceFile) + 1, NULL, &WrSet, &XcptSet, NULL);
/** @todo check rc? */
# ifdef DEBUG
Log2(("select wait for %dms\n", RTTimeMilliTS() - u64Now));
# endif
/* try write more */
- rc = RTFileWrite(pThis->DeviceFile, &ch, 1, &cbWritten);
+ rc = RTFileWrite(pThis->hDeviceFile, &ch, 1, &cbWritten);
if (rc == VERR_TRY_AGAIN)
cbWritten = 0;
else if (RT_FAILURE(rc))
@@ -626,17 +627,19 @@ static DECLCALLBACK(int) drvHostSerialRecvThread(PPDMDRVINS pDrvIns, PPDMTHREAD
#if defined(RT_OS_DARWIN) /* poll is broken on x86 darwin, returns POLLNVAL. */
fd_set RdSet;
FD_ZERO(&RdSet);
- FD_SET(pThis->DeviceFileR, &RdSet);
- FD_SET(pThis->WakeupPipeR, &RdSet);
+ FD_SET(RTFileToNative(pThis->hDeviceFileR), &RdSet);
+ FD_SET(RTPipeToNative(pThis->hWakeupPipeR), &RdSet);
fd_set XcptSet;
FD_ZERO(&XcptSet);
- FD_SET(pThis->DeviceFileR, &XcptSet);
- FD_SET(pThis->WakeupPipeR, &XcptSet);
+ FD_SET(RTFileToNative(pThis->hDeviceFile), &XcptSet);
+ FD_SET(RTPipeToNative(pThis->hWakeupPipeR), &XcptSet);
# if 1 /* it seems like this select is blocking the write... */
- rc = select(RT_MAX(pThis->WakeupPipeR, pThis->DeviceFileR) + 1, &RdSet, NULL, &XcptSet, NULL);
+ rc = select(RT_MAX(RTPipeToNative(pThis->hWakeupPipeR), RTFileToNative(pThis->hDeviceFileR)) + 1,
+ &RdSet, NULL, &XcptSet, NULL);
# else
struct timeval tv = { 0, 1000 };
- rc = select(RT_MAX(pThis->WakeupPipeR, pThis->DeviceFileR) + 1, &RdSet, NULL, &XcptSet, &tv);
+ rc = select(RTPipeToNative(pThis->hWakeupPipeR), RTFileToNative(pThis->hDeviceFileR) + 1,
+ &RdSet, NULL, &XcptSet, &tv);
# endif
if (rc == -1)
{
@@ -654,10 +657,10 @@ static DECLCALLBACK(int) drvHostSerialRecvThread(PPDMDRVINS pDrvIns, PPDMTHREAD
/* drain the wakeup pipe */
size_t cbRead;
- if ( FD_ISSET(pThis->WakeupPipeR, &RdSet)
- || FD_ISSET(pThis->WakeupPipeR, &XcptSet))
+ if ( FD_ISSET(RTPipeToNative(pThis->hWakeupPipeR), &RdSet)
+ || FD_ISSET(RTPipeToNative(pThis->hWakeupPipeR), &XcptSet))
{
- rc = RTFileRead(pThis->WakeupPipeR, abBuffer, 1, &cbRead);
+ rc = RTPipeRead(pThis->hWakeupPipeR, abBuffer, 1, &cbRead);
if (RT_FAILURE(rc))
{
LogRel(("HostSerial#%d: draining the wakeup pipe failed with %Rrc, terminating the worker thread.\n", pDrvIns->iInstance, rc));
@@ -668,7 +671,7 @@ static DECLCALLBACK(int) drvHostSerialRecvThread(PPDMDRVINS pDrvIns, PPDMTHREAD
}
/* read data from the serial port. */
- rc = RTFileRead(pThis->DeviceFileR, abBuffer, sizeof(abBuffer), &cbRead);
+ rc = RTFileRead(pThis->hDeviceFileR, abBuffer, sizeof(abBuffer), &cbRead);
if (RT_FAILURE(rc))
{
LogRel(("HostSerial#%d: (1) Read failed with %Rrc, terminating the worker thread.\n", pDrvIns->iInstance, rc));
@@ -681,10 +684,10 @@ static DECLCALLBACK(int) drvHostSerialRecvThread(PPDMDRVINS pDrvIns, PPDMTHREAD
size_t cbRead;
struct pollfd aFDs[2];
- aFDs[0].fd = pThis->DeviceFile;
+ aFDs[0].fd = RTFileToNative(pThis->hDeviceFile);
aFDs[0].events = POLLIN;
aFDs[0].revents = 0;
- aFDs[1].fd = pThis->WakeupPipeR;
+ aFDs[1].fd = RTPipeToNative(pThis->hWakeupPipeR);
aFDs[1].events = POLLIN | POLLERR | POLLHUP;
aFDs[1].revents = 0;
rc = poll(aFDs, RT_ELEMENTS(aFDs), -1);
@@ -703,10 +706,10 @@ static DECLCALLBACK(int) drvHostSerialRecvThread(PPDMDRVINS pDrvIns, PPDMTHREAD
if (aFDs[1].revents & (POLLHUP | POLLERR | POLLNVAL))
break;
/* notification to terminate -- drain the pipe */
- RTFileRead(pThis->WakeupPipeR, &abBuffer, 1, &cbRead);
+ RTPipeRead(pThis->hWakeupPipeR, &abBuffer, 1, &cbRead);
continue;
}
- rc = RTFileRead(pThis->DeviceFile, abBuffer, sizeof(abBuffer), &cbRead);
+ rc = RTFileRead(pThis->hDeviceFile, abBuffer, sizeof(abBuffer), &cbRead);
if (RT_FAILURE(rc))
{
/* don't terminate worker thread when data unavailable */
@@ -843,7 +846,9 @@ static DECLCALLBACK(int) drvHostSerialWakeupRecvThread(PPDMDRVINS pDrvIns, PPDMT
{
PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
- return RTFileWrite(pThis->WakeupPipeW, "", 1, NULL);
+ size_t cbIgnored;
+ return RTPipeWrite(pThis->hWakeupPipeW, "", 1, &cbIgnored);
+
#elif defined(RT_OS_WINDOWS)
if (!SetEvent(pThis->hHaltEventSem))
return RTErrConvertFromWin32(GetLastError());
@@ -882,7 +887,7 @@ static DECLCALLBACK(int) drvHostSerialMonitorThread(PPDMDRVINS pDrvIns, PPDMTHRE
/*
* Get the status line state.
*/
- rc = ioctl(pThis->DeviceFile, TIOCMGET, &statusLines);
+ rc = ioctl(RTFileToNative(pThis->hDeviceFile), TIOCMGET, &statusLines);
if (rc < 0)
{
PDMDrvHlpVMSetRuntimeError(pDrvIns, 0 /*fFlags*/, "DrvHostSerialFail",
@@ -915,7 +920,7 @@ static DECLCALLBACK(int) drvHostSerialMonitorThread(PPDMDRVINS pDrvIns, PPDMTHRE
* modem irqs and so the monitor thread never gets released. The workaround
* is to send a signal after each tcsetattr.
*/
- ioctl(pThis->DeviceFile, TIOCMIWAIT, uStatusLinesToCheck);
+ ioctl(RTFileToNative(pThis->hDeviceFile), TIOCMIWAIT, uStatusLinesToCheck);
# else
/* Poll for status line change. */
if (!((statusLines ^ pThis->fStatusLines) & uStatusLinesToCheck))
@@ -988,10 +993,10 @@ static DECLCALLBACK(int) drvHostSerialSetModemLines(PPDMICHARCONNECTOR pInterfac
modemStateClear |= TIOCM_DTR;
if (modemStateSet)
- ioctl(pThis->DeviceFile, TIOCMBIS, &modemStateSet);
+ ioctl(RTFileToNative(pThis->hDeviceFile), TIOCMBIS, &modemStateSet);
if (modemStateClear)
- ioctl(pThis->DeviceFile, TIOCMBIC, &modemStateClear);
+ ioctl(RTFileToNative(pThis->hDeviceFile), TIOCMBIC, &modemStateClear);
#elif defined(RT_OS_WINDOWS)
if (RequestToSend)
@@ -1023,9 +1028,9 @@ static DECLCALLBACK(int) drvHostSerialSetBreak(PPDMICHARCONNECTOR pInterface, bo
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
if (fBreak)
- ioctl(pThis->DeviceFile, TIOCSBRK);
+ ioctl(RTFileToNative(pThis->hDeviceFile), TIOCSBRK);
else
- ioctl(pThis->DeviceFile, TIOCCBRK);
+ ioctl(RTFileToNative(pThis->hDeviceFile), TIOCCBRK);
#elif defined(RT_OS_WINDOWS)
if (fBreak)
@@ -1057,40 +1062,29 @@ static DECLCALLBACK(void) drvHostSerialDestruct(PPDMDRVINS pDrvIns)
RTSemEventDestroy(pThis->SendSem);
pThis->SendSem = NIL_RTSEMEVENT;
+ int rc;
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
- if (pThis->WakeupPipeW != NIL_RTFILE)
- {
- int rc = RTFileClose(pThis->WakeupPipeW);
- AssertRC(rc);
- pThis->WakeupPipeW = NIL_RTFILE;
- }
- if (pThis->WakeupPipeR != NIL_RTFILE)
- {
- int rc = RTFileClose(pThis->WakeupPipeR);
- AssertRC(rc);
- pThis->WakeupPipeR = NIL_RTFILE;
- }
+ rc = RTPipeClose(pThis->hWakeupPipeW); AssertRC(rc);
+ pThis->hWakeupPipeW = NIL_RTPIPE;
+ rc = RTPipeClose(pThis->hWakeupPipeR); AssertRC(rc);
+ pThis->hWakeupPipeR = NIL_RTPIPE;
+
# if defined(RT_OS_DARWIN)
- if (pThis->DeviceFileR != NIL_RTFILE)
+ if (pThis->hDeviceFileR != NIL_RTFILE)
{
- if (pThis->DeviceFileR != pThis->DeviceFile)
+ if (pThis->hDeviceFileR != pThis->hDeviceFile)
{
- int rc = RTFileClose(pThis->DeviceFileR);
+ rc = RTFileClose(pThis->hDeviceFileR);
AssertRC(rc);
}
- pThis->DeviceFileR = NIL_RTFILE;
+ pThis->hDeviceFileR = NIL_RTFILE;
}
# endif
- if (pThis->DeviceFile != NIL_RTFILE)
- {
- int rc = RTFileClose(pThis->DeviceFile);
- AssertRC(rc);
- pThis->DeviceFile = NIL_RTFILE;
- }
+ rc = RTFileClose(pThis->hDeviceFile); AssertRC(rc);
+ pThis->hDeviceFile = NIL_RTFILE;
#elif defined(RT_OS_WINDOWS)
-
CloseHandle(pThis->hEventRecv);
CloseHandle(pThis->hEventSend);
CancelIo(pThis->hDeviceFile);
@@ -1120,12 +1114,16 @@ static DECLCALLBACK(int) drvHostSerialConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pC
* Init basic data members and interfaces.
*/
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
- pThis->DeviceFile = NIL_RTFILE;
+ pThis->hDeviceFile = NIL_RTFILE;
# ifdef RT_OS_DARWIN
- pThis->DeviceFileR = NIL_RTFILE;
+ pThis->hDeviceFileR = NIL_RTFILE;
# endif
- pThis->WakeupPipeR = NIL_RTFILE;
- pThis->WakeupPipeW = NIL_RTFILE;
+ pThis->hWakeupPipeR = NIL_RTPIPE;
+ pThis->hWakeupPipeW = NIL_RTPIPE;
+#elif defined(RT_OS_WINDOWS)
+ pThis->hEventRecv = INVALID_HANDLE_VALUE;
+ pThis->hEventSend = INVALID_HANDLE_VALUE;
+ pThis->hDeviceFile = INVALID_HANDLE_VALUE;
#endif
/* IBase. */
pDrvIns->IBase.pfnQueryInterface = drvHostSerialQueryInterface;
@@ -1190,15 +1188,15 @@ static DECLCALLBACK(int) drvHostSerialConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pC
/* This seems to be necessary on some Linux hosts, otherwise we hang here forever. */
fOpen |= RTFILE_O_NON_BLOCK;
# endif
- rc = RTFileOpen(&pThis->DeviceFile, pThis->pszDevicePath, fOpen);
+ rc = RTFileOpen(&pThis->hDeviceFile, pThis->pszDevicePath, fOpen);
# ifdef RT_OS_LINUX
/* RTFILE_O_NON_BLOCK not supported? */
if (rc == VERR_INVALID_PARAMETER)
- rc = RTFileOpen(&pThis->DeviceFile, pThis->pszDevicePath, fOpen & ~RTFILE_O_NON_BLOCK);
+ rc = RTFileOpen(&pThis->hDeviceFile, pThis->pszDevicePath, fOpen & ~RTFILE_O_NON_BLOCK);
# endif
# ifdef RT_OS_DARWIN
if (RT_SUCCESS(rc))
- rc = RTFileOpen(&pThis->DeviceFileR, pThis->pszDevicePath, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ rc = RTFileOpen(&pThis->hDeviceFileR, pThis->pszDevicePath, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
# endif
@@ -1231,19 +1229,12 @@ static DECLCALLBACK(int) drvHostSerialConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pC
/* Set to non blocking I/O */
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
- fcntl(pThis->DeviceFile, F_SETFL, O_NONBLOCK);
+ fcntl(RTFileToNative(pThis->hDeviceFile), F_SETFL, O_NONBLOCK);
# ifdef RT_OS_DARWIN
- fcntl(pThis->DeviceFileR, F_SETFL, O_NONBLOCK);
+ fcntl(RTFileToNative(pThis->hDeviceFileR), F_SETFL, O_NONBLOCK);
# endif
- int aFDs[2];
- if (pipe(aFDs) != 0)
- {
- rc = RTErrConvertFromErrno(errno);
- AssertRC(rc);
- return rc;
- }
- pThis->WakeupPipeR = aFDs[0];
- pThis->WakeupPipeW = aFDs[1];
+ rc = RTPipeCreate(&pThis->hWakeupPipeR, &pThis->hWakeupPipeW, 0 /*fFlags*/);
+ AssertRCReturn(rc, rc);
#elif defined(RT_OS_WINDOWS)
@@ -1284,7 +1275,7 @@ static DECLCALLBACK(int) drvHostSerialConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pC
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
/* Linux & darwin needs a separate thread which monitors the status lines. */
# ifndef RT_OS_LINUX
- ioctl(pThis->DeviceFile, TIOCMGET, &pThis->fStatusLines);
+ ioctl(RTFileToNative(pThis->hDeviceFile), TIOCMGET, &pThis->fStatusLines);
# endif
rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pMonitorThread, pThis, drvHostSerialMonitorThread, drvHostSerialWakeupMonitorThread, 0, RTTHREADTYPE_IO, "SerMon");
if (RT_FAILURE(rc))
diff --git a/src/VBox/Devices/Serial/DrvNamedPipe.cpp b/src/VBox/Devices/Serial/DrvNamedPipe.cpp
index f23160b46..d0687378a 100644
--- a/src/VBox/Devices/Serial/DrvNamedPipe.cpp
+++ b/src/VBox/Devices/Serial/DrvNamedPipe.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvNamedPipe.cpp $ */
+/* $Id: DrvNamedPipe.cpp 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* Named pipe / local socket stream driver.
*/
diff --git a/src/VBox/Devices/Serial/DrvRawFile.cpp b/src/VBox/Devices/Serial/DrvRawFile.cpp
index 2477e32f2..d239eb9c7 100644
--- a/src/VBox/Devices/Serial/DrvRawFile.cpp
+++ b/src/VBox/Devices/Serial/DrvRawFile.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvRawFile.cpp $ */
+/* $Id: DrvRawFile.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VBox stream drivers - Raw file output.
*/
@@ -59,7 +59,7 @@ typedef struct DRVRAWFILE
/** Pointer to the file name. (Freed by MM) */
char *pszLocation;
/** Flag whether VirtualBox represents the server or client side. */
- RTFILE OutputFile;
+ RTFILE hOutputFile;
} DRVRAWFILE, *PDRVRAWFILE;
@@ -74,14 +74,14 @@ static DECLCALLBACK(int) drvRawFileWrite(PPDMISTREAM pInterface, const void *pvB
LogFlow(("%s: pvBuf=%p *pcbWrite=%#x (%s)\n", __FUNCTION__, pvBuf, *pcbWrite, pThis->pszLocation));
Assert(pvBuf);
- if (pThis->OutputFile != NIL_RTFILE)
+ if (pThis->hOutputFile != NIL_RTFILE)
{
size_t cbWritten;
- rc = RTFileWrite(pThis->OutputFile, pvBuf, *pcbWrite, &cbWritten);
+ rc = RTFileWrite(pThis->hOutputFile, pvBuf, *pcbWrite, &cbWritten);
#if 0
/* don't flush here, takes too long and we will loose characters */
if (RT_SUCCESS(rc))
- RTFileFlush(pThis->OutputFile);
+ RTFileFlush(pThis->hOutputFile);
#endif
*pcbWrite = cbWritten;
}
@@ -120,11 +120,8 @@ static DECLCALLBACK(void) drvRawFilePowerOff(PPDMDRVINS pDrvIns)
PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
- if (pThis->OutputFile != NIL_RTFILE)
- {
- RTFileClose(pThis->OutputFile);
- pThis->OutputFile = NIL_RTFILE;
- }
+ RTFileClose(pThis->hOutputFile);
+ pThis->hOutputFile = NIL_RTFILE;
}
@@ -145,11 +142,8 @@ static DECLCALLBACK(void) drvRawFileDestruct(PPDMDRVINS pDrvIns)
if (pThis->pszLocation)
MMR3HeapFree(pThis->pszLocation);
- if (pThis->OutputFile != NIL_RTFILE)
- {
- RTFileClose(pThis->OutputFile);
- pThis->OutputFile = NIL_RTFILE;
- }
+ RTFileClose(pThis->hOutputFile);
+ pThis->hOutputFile = NIL_RTFILE;
}
@@ -168,7 +162,7 @@ static DECLCALLBACK(int) drvRawFileConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg,
*/
pThis->pDrvIns = pDrvIns;
pThis->pszLocation = NULL;
- pThis->OutputFile = NIL_RTFILE;
+ pThis->hOutputFile = NIL_RTFILE;
/* IBase */
pDrvIns->IBase.pfnQueryInterface = drvRawFileQueryInterface;
/* IStream */
@@ -187,7 +181,7 @@ static DECLCALLBACK(int) drvRawFileConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg,
/*
* Open the raw file.
*/
- rc = RTFileOpen(&pThis->OutputFile, pThis->pszLocation, RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE);
+ rc = RTFileOpen(&pThis->hOutputFile, pThis->pszLocation, RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE);
if (RT_FAILURE(rc))
{
LogRel(("RawFile%d: CreateFile failed rc=%Rrc\n", pDrvIns->iInstance));
diff --git a/src/VBox/Devices/Storage/ATAController.cpp b/src/VBox/Devices/Storage/ATAController.cpp
index 854276edc..9b125cf30 100644
--- a/src/VBox/Devices/Storage/ATAController.cpp
+++ b/src/VBox/Devices/Storage/ATAController.cpp
@@ -1,4 +1,4 @@
-/* $Id: ATAController.cpp $ */
+/* $Id: ATAController.cpp 37687 2011-06-29 15:22:11Z vboxsync $ */
/** @file
* DevATA, DevAHCI - Shared ATA/ATAPI controller code (disk and cdrom).
*
@@ -6,7 +6,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;
@@ -684,23 +684,9 @@ static void ataCmdError(AHCIATADevState *s, uint8_t uErrorCode)
static bool ataIdentifySS(AHCIATADevState *s)
{
uint16_t *p;
- char aSerial[20];
- int rc;
- RTUUID Uuid;
Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
Assert(s->cbElementaryTransfer == 512);
- rc = s->pDrvBlock ? s->pDrvBlock->pfnGetUuid(s->pDrvBlock, &Uuid) : RTUuidClear(&Uuid);
- if (RT_FAILURE(rc) || RTUuidIsNull(&Uuid))
- {
- PAHCIATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
- /* Generate a predictable serial for drives which don't have a UUID. */
- RTStrPrintf(aSerial, sizeof(aSerial), "VB%x-%04x%04x",
- s->iLUN + ATADEVSTATE_2_DEVINS(s)->iInstance * 32,
- pCtl->IOPortBase1, pCtl->IOPortBase2);
- }
- else
- RTStrPrintf(aSerial, sizeof(aSerial), "VB%08x-%08x", Uuid.au32[0], Uuid.au32[3]);
p = (uint16_t *)s->CTXALLSUFF(pbIOBuffer);
memset(p, 0, 512);
@@ -710,12 +696,12 @@ static bool ataIdentifySS(AHCIATADevState *s)
/* Block size; obsolete, but required for the BIOS. */
p[5] = RT_H2LE_U16(512);
p[6] = RT_H2LE_U16(s->PCHSGeometry.cSectors);
- ataPadString((uint8_t *)(p + 10), aSerial, 20); /* serial number */
+ ataPadString((uint8_t *)(p + 10), s->pszSerialNumber, ATA_SERIAL_NUMBER_LENGTH); /* serial number */
p[20] = RT_H2LE_U16(3); /* XXX: retired, cache type */
p[21] = RT_H2LE_U16(512); /* XXX: retired, cache size in sectors */
p[22] = RT_H2LE_U16(0); /* ECC bytes per sector */
- ataPadString((uint8_t *)(p + 23), "1.0", 8); /* firmware version */
- ataPadString((uint8_t *)(p + 27), "VBOX HARDDISK", 40); /* model */
+ ataPadString((uint8_t *)(p + 23), s->pszFirmwareRevision, ATA_FIRMWARE_REVISION_LENGTH); /* firmware version */
+ ataPadString((uint8_t *)(p + 27), s->pszModelNumber, ATA_MODEL_NUMBER_LENGTH); /* model */
#if ATA_MAX_MULT_SECTORS > 1
p[47] = RT_H2LE_U16(0x8000 | ATA_MAX_MULT_SECTORS);
#endif
@@ -776,6 +762,8 @@ static bool ataIdentifySS(AHCIATADevState *s)
p[102] = RT_H2LE_U16(s->cTotalSectors >> 32);
p[103] = RT_H2LE_U16(s->cTotalSectors >> 48);
}
+ if (s->fNonRotational)
+ p[217] = RT_H2LE_U16(1); /* Non-rotational medium */
uint32_t uCsum = ataChecksum(p, 510);
p[255] = RT_H2LE_U16(0xa5 | (uCsum << 8)); /* Integrity word */
@@ -811,33 +799,19 @@ static bool ataFlushSS(AHCIATADevState *s)
static bool atapiIdentifySS(AHCIATADevState *s)
{
uint16_t *p;
- char aSerial[20];
- RTUUID Uuid;
- int rc;
Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
Assert(s->cbElementaryTransfer == 512);
- rc = s->pDrvBlock ? s->pDrvBlock->pfnGetUuid(s->pDrvBlock, &Uuid) : RTUuidClear(&Uuid);
- if (RT_FAILURE(rc) || RTUuidIsNull(&Uuid))
- {
- PAHCIATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
- /* Generate a predictable serial for drives which don't have a UUID. */
- RTStrPrintf(aSerial, sizeof(aSerial), "VB%x-%04x%04x",
- s->iLUN + ATADEVSTATE_2_DEVINS(s)->iInstance * 32,
- pCtl->IOPortBase1, pCtl->IOPortBase2);
- }
- else
- RTStrPrintf(aSerial, sizeof(aSerial), "VB%08x-%08x", Uuid.au32[0], Uuid.au32[3]);
p = (uint16_t *)s->CTXALLSUFF(pbIOBuffer);
memset(p, 0, 512);
/* Removable CDROM, 50us response, 12 byte packets */
p[0] = RT_H2LE_U16(2 << 14 | 5 << 8 | 1 << 7 | 2 << 5 | 0 << 0);
- ataPadString((uint8_t *)(p + 10), aSerial, 20); /* serial number */
+ ataPadString((uint8_t *)(p + 10), s->pszSerialNumber, ATA_SERIAL_NUMBER_LENGTH); /* serial number */
p[20] = RT_H2LE_U16(3); /* XXX: retired, cache type */
p[21] = RT_H2LE_U16(512); /* XXX: retired, cache size in sectors */
- ataPadString((uint8_t *)(p + 23), "1.0", 8); /* firmware version */
- ataPadString((uint8_t *)(p + 27), "VBOX CD-ROM", 40); /* model */
+ ataPadString((uint8_t *)(p + 23), s->pszFirmwareRevision, ATA_FIRMWARE_REVISION_LENGTH); /* firmware version */
+ ataPadString((uint8_t *)(p + 27), s->pszModelNumber, ATA_MODEL_NUMBER_LENGTH); /* model */
p[49] = RT_H2LE_U16(1 << 11 | 1 << 9 | 1 << 8); /* DMA and LBA supported */
p[50] = RT_H2LE_U16(1 << 14); /* No drive specific standby timer minimum */
p[51] = RT_H2LE_U16(240); /* PIO transfer cycle */
@@ -1631,38 +1605,183 @@ static bool atapiReadTrackInformationSS(AHCIATADevState *s)
return false;
}
+static size_t atapiGetConfigurationFillFeatureListProfiles(AHCIATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 3*4)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x0); /* feature 0: list of profiles supported */
+ pbBuf[2] = (0 << 2) | (1 << 1) | (1 || 0); /* version 0, persistent, current */
+ pbBuf[3] = 8; /* additional bytes for profiles */
+ /* The MMC-3 spec says that DVD-ROM read capability should be reported
+ * before CD-ROM read capability. */
+ ataH2BE_U16(pbBuf + 4, 0x10); /* profile: read-only DVD */
+ pbBuf[6] = (0 << 0); /* NOT current profile */
+ ataH2BE_U16(pbBuf + 8, 0x08); /* profile: read only CD */
+ pbBuf[10] = (1 << 0); /* current profile */
+
+ return 3*4; /* Header + 2 profiles entries */
+}
+
+static size_t atapiGetConfigurationFillFeatureCore(AHCIATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 12)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x1); /* feature 0001h: Core Feature */
+ pbBuf[2] = (0x2 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 8; /* Additional length */
+ ataH2BE_U16(pbBuf + 4, 0x00000002); /* Physical interface ATAPI. */
+ pbBuf[8] = RT_BIT(0); /* DBE */
+ /* Rest is reserved. */
+
+ return 12;
+}
+
+static size_t atapiGetConfigurationFillFeatureMorphing(AHCIATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 8)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x2); /* feature 0002h: Morphing Feature */
+ pbBuf[2] = (0x1 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 4; /* Additional length */
+ pbBuf[4] = RT_BIT(1) | 0x0; /* OCEvent | !ASYNC */
+ /* Rest is reserved. */
+
+ return 8;
+}
+
+static size_t atapiGetConfigurationFillFeatureRemovableMedium(AHCIATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 8)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x3); /* feature 0003h: Removable Medium Feature */
+ pbBuf[2] = (0x2 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 4; /* Additional length */
+ /* Tray type loading | Load | Eject | !Pvnt Jmpr | !DBML | Lock */
+ pbBuf[4] = (0x2 << 5) | RT_BIT(4) | RT_BIT(3) | (0x0 << 2) | (0x0 << 1) | RT_BIT(0);
+ /* Rest is reserved. */
+
+ return 8;
+}
+
+static size_t atapiGetConfigurationFillFeatureRandomReadable(AHCIATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 12)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x10); /* feature 0010h: Random Readable Feature */
+ pbBuf[2] = (0x0 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 8; /* Additional length */
+ ataH2BE_U32(pbBuf + 4, 2048); /* Logical block size. */
+ ataH2BE_U16(pbBuf + 8, 0x10); /* Blocking (0x10 for DVD, CD is not defined). */
+ pbBuf[10] = 0; /* PP not present */
+ /* Rest is reserved. */
+
+ return 12;
+}
+
+static size_t atapiGetConfigurationFillFeatureCDRead(AHCIATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 8)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x1e); /* feature 001Eh: CD Read Feature */
+ pbBuf[2] = (0x2 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 0; /* Additional length */
+ pbBuf[4] = (0x0 << 7) | (0x0 << 1) | 0x0; /* !DAP | !C2-Flags | !CD-Text. */
+ /* Rest is reserved. */
+
+ return 8;
+}
+
+static size_t atapiGetConfigurationFillFeaturePowerManagement(AHCIATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 4)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x100); /* feature 0100h: Power Management Feature */
+ pbBuf[2] = (0x0 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 0; /* Additional length */
+
+ return 4;
+}
+
+static size_t atapiGetConfigurationFillFeatureTimeout(AHCIATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 8)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x105); /* feature 0105h: Timeout Feature */
+ pbBuf[2] = (0x0 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 4; /* Additional length */
+ pbBuf[4] = 0x0; /* !Group3 */
+
+ return 8;
+}
static bool atapiGetConfigurationSS(AHCIATADevState *s)
{
uint8_t *pbBuf = s->CTXALLSUFF(pbIOBuffer);
+ size_t cbBuf = s->cbIOBuffer;
+ size_t cbCopied = 0;
uint16_t u16Sfn = ataBE2H_U16(&s->aATAPICmd[2]);
Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
- Assert(s->cbElementaryTransfer <= 32);
+ Assert(s->cbElementaryTransfer <= 80);
/* Accept valid request types only, and only starting feature 0. */
if ((s->aATAPICmd[1] & 0x03) == 3 || u16Sfn != 0)
{
atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
return false;
}
- memset(pbBuf, '\0', 32);
- ataH2BE_U32(pbBuf, 16);
+ memset(pbBuf, '\0', cbBuf);
/** @todo implement switching between CD-ROM and DVD-ROM profile (the only
* way to differentiate them right now is based on the image size). */
if (s->cTotalSectors)
ataH2BE_U16(pbBuf + 6, 0x08); /* current profile: read-only CD */
else
ataH2BE_U16(pbBuf + 6, 0x00); /* current profile: none -> no media */
+ cbBuf -= 8;
+ pbBuf += 8;
+
+ cbCopied = atapiGetConfigurationFillFeatureListProfiles(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureCore(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureMorphing(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureRemovableMedium(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureRandomReadable(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureCDRead(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeaturePowerManagement(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureTimeout(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ /* Set data length now. */
+ ataH2BE_U32(s->CTX_SUFF(pbIOBuffer), s->cbIOBuffer - cbBuf);
- ataH2BE_U16(pbBuf + 8, 0); /* feature 0: list of profiles supported */
- pbBuf[10] = (0 << 2) | (1 << 1) | (1 || 0); /* version 0, persistent, current */
- pbBuf[11] = 8; /* additional bytes for profiles */
- /* The MMC-3 spec says that DVD-ROM read capability should be reported
- * before CD-ROM read capability. */
- ataH2BE_U16(pbBuf + 12, 0x10); /* profile: read-only DVD */
- pbBuf[14] = (0 << 0); /* NOT current profile */
- ataH2BE_U16(pbBuf + 16, 0x08); /* profile: read only CD */
- pbBuf[18] = (1 << 0); /* current profile */
/* Other profiles we might want to add in the future: 0x40 (BD-ROM) and 0x50 (HDDVD-ROM) */
s->iSourceSink = ATAFN_SS_NULL;
atapiCmdOK(s);
@@ -1764,9 +1883,9 @@ static bool atapiInquirySS(AHCIATADevState *s)
pbBuf[5] = 0; /* reserved */
pbBuf[6] = 0; /* reserved */
pbBuf[7] = 0; /* reserved */
- ataSCSIPadStr(pbBuf + 8, "VBOX", 8);
- ataSCSIPadStr(pbBuf + 16, "CD-ROM", 16);
- ataSCSIPadStr(pbBuf + 32, "1.0", 4);
+ ataSCSIPadStr(pbBuf + 8, s->pszInquiryVendorId, 8);
+ ataSCSIPadStr(pbBuf + 16, s->pszInquiryProductId, 16);
+ ataSCSIPadStr(pbBuf + 32, s->pszInquiryRevision, 4);
s->iSourceSink = ATAFN_SS_NULL;
atapiCmdOK(s);
return false;
@@ -2282,8 +2401,8 @@ static void atapiParseCmdVirtualATAPI(AHCIATADevState *s)
case 1: /* 01 - Start motor */
break;
case 2: /* 10 - Eject media */
+ {
/* This must be done from EMT. */
- {
PAHCIATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
@@ -2292,13 +2411,20 @@ static void atapiParseCmdVirtualATAPI(AHCIATADevState *s)
(PFNRT)s->pDrvMount->pfnUnmount, 3, s->pDrvMount,
false /*=fForce*/, true /*=fEeject*/);
Assert(RT_SUCCESS(rc) || (rc == VERR_PDM_MEDIA_LOCKED) || (rc = VERR_PDM_MEDIA_NOT_MOUNTED));
+ if (RT_SUCCESS(rc) && pCtl->pMediaNotify)
+ {
+ rc = VMR3ReqCallNoWait(PDMDevHlpGetVM(pDevIns), VMCPUID_ANY,
+ (PFNRT)pCtl->pMediaNotify->pfnEjected, 2,
+ pCtl->pMediaNotify, s->iLUN);
+ AssertRC(rc);
+ }
{
STAM_PROFILE_START(&pCtl->StatLockWait, a);
PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
}
- }
break;
+ }
case 3: /* 11 - Load media */
/** @todo rc = s->pDrvMount->pfnLoadMedia(s->pDrvMount) */
break;
@@ -2400,7 +2526,7 @@ static void atapiParseCmdVirtualATAPI(AHCIATADevState *s)
case SCSI_GET_CONFIGURATION:
/* No media change stuff here, it can confuse Linux guests. */
cbMax = ataBE2H_U16(pbPacket + 7);
- ataStartTransfer(s, RT_MIN(cbMax, 32), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_CONFIGURATION, true);
+ ataStartTransfer(s, RT_MIN(cbMax, 80), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_CONFIGURATION, true);
break;
case SCSI_INQUIRY:
cbMax = ataBE2H_U16(pbPacket + 3);
@@ -5447,19 +5573,29 @@ int ataControllerLoadExec(PAHCIATACONTROLLER pCtl, PSSMHANDLE pSSM)
}
int ataControllerInit(PPDMDEVINS pDevIns, PAHCIATACONTROLLER pCtl,
+ PPDMIMEDIANOTIFY pMediaNotify,
unsigned iLUNMaster, PPDMIBASE pDrvBaseMaster, PPDMLED pLedMaster,
PSTAMCOUNTER pStatBytesReadMaster, PSTAMCOUNTER pStatBytesWrittenMaster,
+ const char *pszSerialNumberMaster, const char *pszFirmwareRevisionMaster,
+ const char *pszModelNumberMaster, const char *pszInquiryVendorIdMaster,
+ const char *pszInquiryProductIdMaster, const char *pszInquiryRevisionMaster,
+ bool fNonRotationalMaster,
unsigned iLUNSlave, PPDMIBASE pDrvBaseSlave, PPDMLED pLedSlave,
PSTAMCOUNTER pStatBytesReadSlave, PSTAMCOUNTER pStatBytesWrittenSlave,
+ const char *pszSerialNumberSlave, const char *pszFirmwareRevisionSlave,
+ const char *pszModelNumberSlave, const char *pszInquiryVendorIdSlave,
+ const char *pszInquiryProductIdSlave, const char *pszInquiryRevisionSlave,
+ bool fNonRotationalSlave,
uint32_t *pcbSSMState, const char *szName)
{
- int rc;
+ int rc;
AssertMsg(pcbSSMState, ("pcbSSMState is invalid\n"));
pCtl->pDevInsR3 = pDevIns;
pCtl->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
pCtl->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+ pCtl->pMediaNotify = pMediaNotify;
pCtl->AsyncIOSem = NIL_RTSEMEVENT;
pCtl->SuspendIOSem = NIL_RTSEMEVENT;
pCtl->AsyncIORequestMutex = NIL_RTSEMMUTEX;
@@ -5467,16 +5603,23 @@ int ataControllerInit(PPDMDEVINS pDevIns, PAHCIATACONTROLLER pCtl,
for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
{
- pCtl->aIfs[j].iLUN = j == 0 ? iLUNMaster : iLUNSlave;
- pCtl->aIfs[j].pDevInsR3 = pDevIns;
- pCtl->aIfs[j].pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
- pCtl->aIfs[j].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
- pCtl->aIfs[j].pControllerR3 = pCtl;
- pCtl->aIfs[j].pControllerR0 = MMHyperR3ToR0(PDMDevHlpGetVM(pDevIns), pCtl);
- pCtl->aIfs[j].pControllerRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), pCtl);
- pCtl->aIfs[j].pLed = j == 0 ? pLedMaster : pLedSlave;
- pCtl->aIfs[j].pStatBytesRead = j == 0 ? pStatBytesReadMaster : pStatBytesReadSlave;
- pCtl->aIfs[j].pStatBytesWritten = j == 0 ? pStatBytesWrittenMaster : pStatBytesWrittenSlave;
+ pCtl->aIfs[j].iLUN = j == 0 ? iLUNMaster : iLUNSlave;
+ pCtl->aIfs[j].pDevInsR3 = pDevIns;
+ pCtl->aIfs[j].pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
+ pCtl->aIfs[j].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+ pCtl->aIfs[j].pControllerR3 = pCtl;
+ pCtl->aIfs[j].pControllerR0 = MMHyperR3ToR0(PDMDevHlpGetVM(pDevIns), pCtl);
+ pCtl->aIfs[j].pControllerRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), pCtl);
+ pCtl->aIfs[j].pLed = j == 0 ? pLedMaster : pLedSlave;
+ pCtl->aIfs[j].pStatBytesRead = j == 0 ? pStatBytesReadMaster : pStatBytesReadSlave;
+ pCtl->aIfs[j].pStatBytesWritten = j == 0 ? pStatBytesWrittenMaster : pStatBytesWrittenSlave;
+ pCtl->aIfs[j].pszSerialNumber = j == 0 ? pszSerialNumberMaster : pszSerialNumberSlave;
+ pCtl->aIfs[j].pszFirmwareRevision = j == 0 ? pszFirmwareRevisionMaster : pszFirmwareRevisionSlave;
+ pCtl->aIfs[j].pszModelNumber = j == 0 ? pszModelNumberMaster : pszModelNumberSlave;
+ pCtl->aIfs[j].pszInquiryVendorId = j == 0 ? pszInquiryVendorIdMaster : pszInquiryVendorIdSlave;
+ pCtl->aIfs[j].pszInquiryProductId = j == 0 ? pszInquiryProductIdMaster : pszInquiryProductIdSlave;
+ pCtl->aIfs[j].pszInquiryRevision = j == 0 ? pszInquiryRevisionMaster : pszInquiryRevisionSlave;
+ pCtl->aIfs[j].fNonRotational = j == 0 ? fNonRotationalMaster : fNonRotationalSlave;
}
/* Initialize per-controller critical section */
diff --git a/src/VBox/Devices/Storage/ATAController.h b/src/VBox/Devices/Storage/ATAController.h
index 7a648e8e5..6e71592a9 100644
--- a/src/VBox/Devices/Storage/ATAController.h
+++ b/src/VBox/Devices/Storage/ATAController.h
@@ -1,10 +1,10 @@
-/* $Id: ATAController.h $ */
+/* $Id: ATAController.h 37690 2011-06-29 16:05:54Z vboxsync $ */
/** @file
* DevATA, DevAHCI - Shared ATA/ATAPI controller types.
*/
/*
- * Copyright (C) 2006-2008 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;
@@ -212,6 +212,20 @@ typedef struct AHCIATADevState {
/** Statistics: number of flush operations and the time spend flushing. */
STAMPROFILE StatFlushes;
+ /** The serial number to use for IDENTIFY DEVICE commands. */
+ R3PTRTYPE(const char *) pszSerialNumber;
+ /** The firmware revision to use for IDENTIFY DEVICE commands. */
+ R3PTRTYPE(const char *) pszFirmwareRevision;
+ /** The model number to use for IDENTIFY DEVICE commands. */
+ R3PTRTYPE(const char *) pszModelNumber;
+ /** The vendor identification string for SCSI INQUIRY commands. */
+ R3PTRTYPE(const char *) pszInquiryVendorId;
+ /** The product identification string for SCSI INQUIRY commands. */
+ R3PTRTYPE(const char *) pszInquiryProductId;
+ /** The revision string for SCSI INQUIRY commands. */
+ R3PTRTYPE(const char *) pszInquiryRevision;
+ /** Mark the drive as having a non-rotational medium (i.e. as a SSD). */
+ bool fNonRotational;
/** Enable passing through commands directly to the ATAPI drive. */
bool fATAPIPassthrough;
/** Number of errors we've reported to the release log.
@@ -372,7 +386,9 @@ typedef struct AHCIATACONTROLLER
RTSEMMUTEX AsyncIORequestMutex;
/** The event semaphore the thread is waiting on during suspended I/O. */
RTSEMEVENT SuspendIOSem;
-#if 0 /*HC_ARCH_BITS == 32*/
+ /** Pointer to Media Notify interface. */
+ R3PTRTYPE(PPDMIMEDIANOTIFY) pMediaNotify;
+#if HC_ARCH_BITS == 32
uint32_t Alignment0;
#endif
@@ -414,16 +430,48 @@ RT_C_DECLS_END
* @returns VBox status code.
* @param pDevIns Pointer to the device instance which creates a controller.
* @param pCtl Pointer to the unitialized ATA controller structure.
+ * @param pMediaNotify Pointer to PDM interface for media eject.
+ * @param iLUNMaster Port number of the master device.
* @param pDrvBaseMaster Pointer to the base driver interface which acts as the master.
+ * @param pLedMaster Pointer to LED state for master device.
+ * @param pStatBytesReadMaster Pointer to statistics structure for reads.
+ * @param pStatBytesWrittenMaster Pointer to statistics structure for writes.
+ * @param pszSerialNumberMaster VPD serial number for master.
+ * @param pszFirmwareRevisionMaster VPD firmware revision for master
+ * @param pszModelNumberMaster VPD model number for master
+ * @param pszInquiryVendorIdMaster VPD vendor ID for master
+ * @param pszInquiryProductIdMaster VPD product ID for master
+ * @param pszInquiryRevisionMaster VPD revision for master
+ * @param fNonRotationalMaster Flag for non-rotational media.
+ * @param iLUNSlave Port number of the slave device.
* @param pDrvBaseSlave Pointer to the base driver interface which acts as the slave.
+ * @param pLedSlave Pointer to LED state for slave device.
+ * @param pStatBytesReadSlave Pointer to statistics structure for reads.
+ * @param pStatBytesWrittenSlave Pointer to statistics structure for writes.
+ * @param pszSerialNumberSlave VPD serial number for slave.
+ * @param pszFirmwareRevisionSlave VPD firmware revision for slave
+ * @param pszModelNumberSlave VPD model number for slave
+ * @param pszInquiryVendorIdSlave VPD vendor ID for slave
+ * @param pszInquiryProductIdSlave VPD product ID for slave
+ * @param pszInquiryRevisionSlave VPD revision for slave
+ * @param fNonRotationalSlave Flag for non-rotational media.
* @param pcbSSMState Where to store the size of the device state for loading/saving.
* @param szName Name of the controller (Used to initialize the critical section).
*/
int ataControllerInit(PPDMDEVINS pDevIns, PAHCIATACONTROLLER pCtl,
+ PPDMIMEDIANOTIFY pMediaNotify,
unsigned iLUNMaster, PPDMIBASE pDrvBaseMaster, PPDMLED pLedMaster,
PSTAMCOUNTER pStatBytesReadMaster, PSTAMCOUNTER pStatBytesWrittenMaster,
+ const char *pszSerialNumberMaster, const char *pszFirmwareRevisionMaster,
+ const char *pszModelNumberMaster, const char *pszInquiryVendorIdMaster,
+ const char *pszInquiryProductIdMaster, const char *pszInquiryRevisionMaster,
+ bool fNonRotationalMaster,
unsigned iLUNSlave, PPDMIBASE pDrvBaseSlave, PPDMLED pLedSlave,
PSTAMCOUNTER pStatBytesReadSlave, PSTAMCOUNTER pStatBytesWrittenSlave,
+ const char *pszSerialNumberSlave, const char *pszFirmwareRevisionSlave,
+ const char *pszModelNumberSlave, const char *pszInquiryVendorIdSlave,
+ const char *pszInquiryProductIdSlave, const char *pszInquiryRevisionSlave,
+ bool fNonRotationalSlave,
uint32_t *pcbSSMState, const char *szName);
/**
diff --git a/src/VBox/Devices/Storage/Debug.cpp b/src/VBox/Devices/Storage/Debug.cpp
index 774722734..f73d32d7c 100644
--- a/src/VBox/Devices/Storage/Debug.cpp
+++ b/src/VBox/Devices/Storage/Debug.cpp
@@ -1,4 +1,4 @@
-/* $Id: Debug.cpp $ */
+/* $Id: Debug.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox storage devices: debug helpers
*/
diff --git a/src/VBox/Devices/Storage/DevAHCI.cpp b/src/VBox/Devices/Storage/DevAHCI.cpp
index da2c39cea..bd6a2c961 100644
--- a/src/VBox/Devices/Storage/DevAHCI.cpp
+++ b/src/VBox/Devices/Storage/DevAHCI.cpp
@@ -1,11 +1,11 @@
-/* $Id: DevAHCI.cpp $ */
+/* $Id: DevAHCI.cpp 37887 2011-07-12 10:50:43Z vboxsync $ */
/** @file
* VBox storage devices: AHCI controller device (disk and cdrom).
* Implements the AHCI standard 1.1
*/
/*
- * Copyright (C) 2006-2009 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;
@@ -255,10 +255,29 @@ typedef enum AHCITXDIR
} AHCITXDIR;
/**
+ * Task state.
+ */
+typedef enum AHCITXSTATE
+{
+ /** Invalid. */
+ AHCITXSTATE_INVALID = 0,
+ /** Task is not active. */
+ AHCITXSTATE_FREE,
+ /** Task is active */
+ AHCITXSTATE_ACTIVE,
+ /** Task was canceled but the request didn't completed yet. */
+ AHCITXSTATE_CANCELED,
+ /** 32bit hack. */
+ AHCITXSTATE_32BIT_HACK = 0x7fffffff
+} AHCITXSTATE, *PAHCITXSTATE;
+
+/**
* A task state.
*/
typedef struct AHCIPORTTASKSTATE
{
+ /** Task state. */
+ volatile AHCITXSTATE enmTxState;
/** Tag of the task. */
uint32_t uTag;
/** Command is queued. */
@@ -306,10 +325,6 @@ typedef struct AHCIPORTTASKSTATE
* If this is set we will use a buffer for the data
* and the callback copies the data to the destination. */
PFNAHCIPOSTPROCESS pfnPostProcess;
-#ifdef RT_STRICT
- /** Flag whether the task state is currently active - used for debugging */
- volatile bool fActive;
-#endif
} AHCIPORTTASKSTATE;
/**
@@ -396,6 +411,8 @@ typedef struct AHCIPort
bool fSpunUp;
/** First D2H FIS was send. */
bool fFirstD2HFisSend;
+ /** Mark the drive as having a non-rotational medium (i.e. as a SSD). */
+ bool fNonRotational;
/** Attached device is a CD/DVD drive. */
bool fATAPI;
/** Passthrough SCSI commands. */
@@ -557,13 +574,17 @@ typedef struct AHCI
PDMILEDPORTS ILeds;
/** Status LUN: Partner of ILeds. */
R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector;
+ /** Status LUN: Media Notifys. */
+ R3PTRTYPE(PPDMIMEDIANOTIFY) pMediaNotify;
-#if HC_ARCH_BITS == 64
- uint32_t Alignment1[2];
+#if HC_ARCH_BITS == 32
+ uint32_t Alignment1;
#endif
/** Base address of the MMIO region. */
RTGCPHYS MMIOBase;
+ /** Base address of the I/O port region for Idx/Data. */
+ RTIOPORT IOPortBase;
/** Global Host Control register of the HBA */
@@ -582,6 +603,9 @@ typedef struct AHCI
/** Command completion coalescing ports */
uint32_t regHbaCccPorts;
+ /** Index register for BIOS access. */
+ uint32_t regIdx;
+
#if HC_ARCH_BITS == 64
uint32_t Alignment3;
#endif
@@ -873,26 +897,20 @@ typedef struct pAhciPort_opreg
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
RT_C_DECLS_BEGIN
-PDMBOTHCBDECL(int) ahciMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) ahciMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
static void ahciHBAReset(PAHCI pThis);
-PDMBOTHCBDECL(int) ahciIOPortWrite1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) ahciIOPortRead1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) ahciIOPortWrite2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) ahciIOPortRead2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) ahciLegacyFakeWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) ahciLegacyFakeRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
#ifdef IN_RING3
-static int ahciPostFisIntoMemory(PAHCIPort pAhciPort, unsigned uFisType, uint8_t *cmdFis);
+static int ahciPostFisIntoMemory(PAHCIPort pAhciPort, unsigned uFisType, uint8_t *cmdFis);
static void ahciPostFirstD2HFisIntoMemory(PAHCIPort pAhciPort);
-static int ahciScatterGatherListCopyFromBuffer(PAHCIPORTTASKSTATE pAhciPortTaskState, void *pvBuf, size_t cbBuf);
-static int ahciScatterGatherListCreate(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState, bool fReadonly);
-static int ahciScatterGatherListDestroy(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState);
+static int ahciScatterGatherListCopyFromBuffer(PAHCIPORTTASKSTATE pAhciPortTaskState, void *pvBuf, size_t cbBuf);
+static int ahciScatterGatherListCreate(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState, bool fReadonly);
+static void ahciScatterGatherListFree(PAHCIPORTTASKSTATE pAhciPortTaskState);
+static int ahciScatterGatherListDestroy(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState);
static void ahciCopyFromBufferIntoSGList(PPDMDEVINS pDevIns, PAHCIPORTTASKSTATESGENTRY pSGInfo);
static void ahciCopyFromSGListIntoBuffer(PPDMDEVINS pDevIns, PAHCIPORTTASKSTATESGENTRY pSGInfo);
static void ahciScatterGatherListGetTotalBufferSize(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState);
-static int ahciScatterGatherListCreateSafe(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState,
- bool fReadonly, unsigned cSGEntriesProcessed);
+static int ahciScatterGatherListCreateSafe(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState,
+ bool fReadonly, unsigned cSGEntriesProcessed);
+static bool ahciCancelActiveTasks(PAHCIPort pAhciPort);
#endif
RT_C_DECLS_END
@@ -1104,6 +1122,10 @@ static int PortSError_w(PAHCI ahci, PAHCIPort pAhciPort, uint32_t iReg, uint32_t
pAhciPort->regTFD &= ~(ATA_STAT_DRQ | ATA_STAT_BUSY);
}
+ if ( (u32Value & AHCI_PORT_SERR_N)
+ && (pAhciPort->regSERR & AHCI_PORT_SERR_N))
+ ASMAtomicAndU32(&pAhciPort->regIS, ~AHCI_PORT_IS_PRCS);
+
pAhciPort->regSERR &= ~u32Value;
return VINF_SUCCESS;
@@ -1122,8 +1144,17 @@ static int PortSControl_w(PAHCI ahci, PAHCIPort pAhciPort, uint32_t iReg, uint32
ahciLog(("%s: IPM=%d SPD=%d DET=%d\n", __FUNCTION__,
AHCI_PORT_SCTL_IPM_GET(u32Value), AHCI_PORT_SCTL_SPD_GET(u32Value), AHCI_PORT_SCTL_DET_GET(u32Value)));
+#ifndef IN_RING3
+ return VINF_IOM_HC_MMIO_WRITE;
+#else
if ((u32Value & AHCI_PORT_SCTL_DET) == AHCI_PORT_SCTL_DET_INIT)
{
+ bool fAllTasksCanceled;
+
+ /* Cancel all tasks first. */
+ fAllTasksCanceled = ahciCancelActiveTasks(pAhciPort);
+ Assert(fAllTasksCanceled);
+
ASMAtomicXchgBool(&pAhciPort->fPortReset, true);
pAhciPort->regSSTS = 0;
pAhciPort->regSIG = ~0;
@@ -1133,9 +1164,6 @@ static int PortSControl_w(PAHCI ahci, PAHCIPort pAhciPort, uint32_t iReg, uint32
else if ((u32Value & AHCI_PORT_SCTL_DET) == AHCI_PORT_SCTL_DET_NINIT && pAhciPort->pDrvBase &&
(pAhciPort->regSCTL & AHCI_PORT_SCTL_DET) == AHCI_PORT_SCTL_DET_INIT)
{
-#ifndef IN_RING3
- return VINF_IOM_HC_MMIO_WRITE;
-#else
if (pAhciPort->pDrvBase)
{
ASMAtomicXchgBool(&pAhciPort->fPortReset, false);
@@ -1182,12 +1210,12 @@ static int PortSControl_w(PAHCI ahci, PAHCIPort pAhciPort, uint32_t iReg, uint32
}
}
}
-#endif
}
pAhciPort->regSCTL = u32Value;
return VINF_SUCCESS;
+#endif
}
static int PortSControl_r(PAHCI ahci, PAHCIPort pAhciPort, uint32_t iReg, uint32_t *pu32Value)
@@ -1345,7 +1373,8 @@ static int PortCmd_w(PAHCI ahci, PAHCIPort pAhciPort, uint32_t iReg, uint32_t u3
u32Value |= AHCI_PORT_CMD_FR;
/* Send the first D2H FIS only if it wasn't already send. */
- if (!pAhciPort->fFirstD2HFisSend)
+ if ( !pAhciPort->fFirstD2HFisSend
+ && pAhciPort->pDrvBase)
{
#ifndef IN_RING3
return VINF_IOM_HC_MMIO_WRITE;
@@ -1489,6 +1518,8 @@ static int PortFisAddr_w(PAHCI ahci, PAHCIPort pAhciPort, uint32_t iReg, uint32_
{
ahciLog(("%s: write u32Value=%#010x\n", __FUNCTION__, u32Value));
+ Assert(!(u32Value & ~AHCI_PORT_FB_RESERVED));
+
pAhciPort->regFB = (u32Value & AHCI_PORT_FB_RESERVED);
pAhciPort->GCPhysAddrFb = AHCI_RTGCPHYS_FROM_U32(pAhciPort->regFBU, pAhciPort->regFB);
@@ -1535,6 +1566,8 @@ static int PortCmdLstAddr_w(PAHCI ahci, PAHCIPort pAhciPort, uint32_t iReg, uint
{
ahciLog(("%s: write u32Value=%#010x\n", __FUNCTION__, u32Value));
+ Assert(!(u32Value & ~AHCI_PORT_CLB_RESERVED));
+
pAhciPort->regCLB = (u32Value & AHCI_PORT_CLB_RESERVED);
pAhciPort->GCPhysAddrClb = AHCI_RTGCPHYS_FROM_U32(pAhciPort->regCLBU, pAhciPort->regCLB);
@@ -1674,10 +1707,14 @@ static int HbaControl_w(PAHCI ahci, uint32_t iReg, uint32_t u32Value)
__FUNCTION__, (u32Value & AHCI_HBA_CTRL_AE) >> 31, (u32Value & AHCI_HBA_CTRL_IE) >> 1,
(u32Value & AHCI_HBA_CTRL_HR)));
+#ifndef IN_RING3
+ return VINF_IOM_HC_MMIO_WRITE;
+#else
ahci->regHbaCtrl = (u32Value & AHCI_HBA_CTRL_RW_MASK) | AHCI_HBA_CTRL_AE;
if (ahci->regHbaCtrl & AHCI_HBA_CTRL_HR)
ahciHBAReset(ahci);
return VINF_SUCCESS;
+#endif
}
/**
@@ -1855,6 +1892,7 @@ static const AHCIPORTOPREG g_aPortOpRegs[] =
{"PortReserved2", PortInvalid_r, PortInvalid_w}, /* Not used. */
};
+#ifdef IN_RING3
/**
* Reset initiated by system software for one port.
*
@@ -1862,9 +1900,16 @@ static const AHCIPORTOPREG g_aPortOpRegs[] =
*/
static void ahciPortSwReset(PAHCIPort pAhciPort)
{
+ bool fAllTasksCanceled;
+
+ /* Cancel all tasks first. */
+ fAllTasksCanceled = ahciCancelActiveTasks(pAhciPort);
+ Assert(fAllTasksCanceled);
+
pAhciPort->regIS = 0;
pAhciPort->regIE = 0;
pAhciPort->regCMD = AHCI_PORT_CMD_CPD | /* Cold presence detection */
+ AHCI_PORT_CMD_HPCP | /* Hotplugging supported. */
AHCI_PORT_CMD_SUD | /* Device has spun up. */
AHCI_PORT_CMD_POD; /* Port is powered on. */
pAhciPort->regTFD = (1 << 8) | ATA_STAT_SEEK | ATA_STAT_WRERR;
@@ -1911,7 +1956,6 @@ static void ahciPortSwReset(PAHCIPort pAhciPort)
}
}
-#ifdef IN_RING3
/**
* Hardware reset used for machine power on and reset.
*
@@ -1929,7 +1973,6 @@ static void ahciPortHwReset(PAHCIPort pAhciPort)
pAhciPort->GCPhysAddrClb = 0;
pAhciPort->GCPhysAddrFb = 0;
}
-#endif
/**
* Create implemented ports bitmap.
@@ -2001,46 +2044,30 @@ static void ahciHBAReset(PAHCI pThis)
/* Clear the HBA Reset bit */
pThis->regHbaCtrl &= ~AHCI_HBA_CTRL_HR;
}
+#endif
/**
- * Memory mapped I/O Handler for read operations.
+ * Reads from a AHCI controller register.
*
* @returns VBox status code.
*
- * @param pDevIns The device instance.
- * @param pvUser User argument.
- * @param GCPhysAddr Physical address (in GC) where the read starts.
+ * @param pAhci The AHCI instance.
+ * @param uReg The register to write.
* @param pv Where to store the result.
* @param cb Number of bytes read.
*/
-PDMBOTHCBDECL(int) ahciMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+static int ahciRegisterRead(PAHCI pAhci, uint32_t uReg, void *pv, unsigned cb)
{
- PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
- int rc = VINF_SUCCESS;
-
- /* Break up 64 bits reads into two dword reads. */
- if (cb == 8)
- {
- rc = ahciMMIORead(pDevIns, pvUser, GCPhysAddr, pv, 4);
- if (RT_FAILURE(rc))
- return rc;
-
- return ahciMMIORead(pDevIns, pvUser, GCPhysAddr + 4, (uint8_t *)pv + 4, 4);
- }
-
- Log2(("#%d ahciMMIORead: pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp rc=%Rrc\n",
- pDevIns->iInstance, pv, cb, pv, cb, GCPhysAddr, rc));
+ int rc = VINF_SUCCESS;
+ uint32_t iReg;
/*
* If the access offset is smaller than AHCI_HBA_GLOBAL_SIZE the guest accesses the global registers.
* Otherwise it accesses the registers of a port.
*/
- uint32_t uOffset = (GCPhysAddr - pAhci->MMIOBase);
- uint32_t iReg;
-
- if (uOffset < AHCI_HBA_GLOBAL_SIZE)
+ if (uReg < AHCI_HBA_GLOBAL_SIZE)
{
- iReg = uOffset >> 2;
+ iReg = uReg >> 2;
Log3(("%s: Trying to read from global register %u\n", __FUNCTION__, iReg));
if (iReg < RT_ELEMENTS(g_aOpRegs))
{
@@ -2059,9 +2086,9 @@ PDMBOTHCBDECL(int) ahciMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhy
uint32_t iPort;
/* Calculate accessed port. */
- uOffset -= AHCI_HBA_GLOBAL_SIZE;
- iPort = uOffset / AHCI_PORT_REGISTER_SIZE;
- iRegOffset = (uOffset % AHCI_PORT_REGISTER_SIZE);
+ uReg -= AHCI_HBA_GLOBAL_SIZE;
+ iPort = uReg / AHCI_PORT_REGISTER_SIZE;
+ iRegOffset = (uReg % AHCI_PORT_REGISTER_SIZE);
iReg = iRegOffset >> 2;
Log3(("%s: Trying to read from port %u and register %u\n", __FUNCTION__, iPort, iReg));
@@ -2100,11 +2127,102 @@ PDMBOTHCBDECL(int) ahciMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhy
break;
}
default:
- AssertMsgFailed(("%s: unsupported access width cb=%d uOffset=%x iPort=%x iRegOffset=%x iReg=%x!!!\n", __FUNCTION__, cb, uOffset, iPort, iRegOffset, iReg));
+ AssertMsgFailed(("%s: unsupported access width cb=%d iPort=%x iRegOffset=%x iReg=%x!!!\n",
+ __FUNCTION__, cb, iPort, iRegOffset, iReg));
}
}
}
+ return rc;
+}
+
+/**
+ * Writes a value to one of the AHCI controller registers.
+ *
+ * @returns VBox status code.
+ *
+ * @param pAhci The AHCI instance.
+ * @param uReg The register to write.
+ * @param pv Where to fetch the result.
+ * @param cb Number of bytes to write.
+ */
+static int ahciRegisterWrite(PAHCI pAhci, uint32_t uReg, void const *pv, unsigned cb)
+{
+ int rc = VINF_SUCCESS;
+ uint32_t iReg;
+
+ if (uReg < AHCI_HBA_GLOBAL_SIZE)
+ {
+ Log3(("Write global HBA register\n"));
+ iReg = uReg >> 2;
+ if (iReg < RT_ELEMENTS(g_aOpRegs))
+ {
+ const AHCIOPREG *pReg = &g_aOpRegs[iReg];
+ rc = pReg->pfnWrite(pAhci, iReg, *(uint32_t *)pv);
+ }
+ else
+ {
+ Log3(("%s: Trying to write global register %u/%u!!!\n", __FUNCTION__, iReg, RT_ELEMENTS(g_aOpRegs)));
+ rc = VINF_SUCCESS;
+ }
+ }
+ else
+ {
+ uint32_t iPort;
+ Log3(("Write Port register\n"));
+ /* Calculate accessed port. */
+ uReg -= AHCI_HBA_GLOBAL_SIZE;
+ iPort = uReg / AHCI_PORT_REGISTER_SIZE;
+ iReg = (uReg % AHCI_PORT_REGISTER_SIZE) >> 2;
+ Log3(("%s: Trying to write to port %u and register %u\n", __FUNCTION__, iPort, iReg));
+ if (RT_LIKELY( iPort < pAhci->cPortsImpl
+ && iReg < RT_ELEMENTS(g_aPortOpRegs)))
+ {
+ const AHCIPORTOPREG *pPortReg = &g_aPortOpRegs[iReg];
+ rc = pPortReg->pfnWrite(pAhci, &pAhci->ahciPort[iPort], iReg, *(uint32_t *)pv);
+ }
+ else
+ {
+ Log3(("%s: Trying to write port %u register %u/%u!!!\n", __FUNCTION__, iPort, iReg, RT_ELEMENTS(g_aPortOpRegs)));
+ rc = VINF_SUCCESS;
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * Memory mapped I/O Handler for read operations.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument.
+ * @param GCPhysAddr Physical address (in GC) where the read starts.
+ * @param pv Where to store the result.
+ * @param cb Number of bytes read.
+ */
+PDMBOTHCBDECL(int) ahciMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+{
+ PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
+ int rc = VINF_SUCCESS;
+
+ /* Break up 64 bits reads into two dword reads. */
+ if (cb == 8)
+ {
+ rc = ahciMMIORead(pDevIns, pvUser, GCPhysAddr, pv, 4);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ return ahciMMIORead(pDevIns, pvUser, GCPhysAddr + 4, (uint8_t *)pv + 4, 4);
+ }
+
+ Log2(("#%d ahciMMIORead: pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp rc=%Rrc\n",
+ pDevIns->iInstance, pv, cb, pv, cb, GCPhysAddr, rc));
+
+ uint32_t uOffset = (GCPhysAddr - pAhci->MMIOBase);
+ rc = ahciRegisterRead(pAhci, uOffset, pv, cb);
+
Log2(("#%d ahciMMIORead: return pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp rc=%Rrc\n",
pDevIns->iInstance, pv, cb, pv, cb, GCPhysAddr, rc));
return rc;
@@ -2122,7 +2240,7 @@ PDMBOTHCBDECL(int) ahciMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhy
* @param pv Where to fetch the result.
* @param cb Number of bytes to write.
*/
-PDMBOTHCBDECL(int) ahciMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+PDMBOTHCBDECL(int) ahciMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
int rc = VINF_SUCCESS;
@@ -2177,43 +2295,7 @@ PDMBOTHCBDECL(int) ahciMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPh
* Otherwise it accesses the registers of a port.
*/
uint32_t uOffset = (GCPhysAddr - pAhci->MMIOBase);
- uint32_t iReg;
- if (uOffset < AHCI_HBA_GLOBAL_SIZE)
- {
- Log3(("Write global HBA register\n"));
- iReg = uOffset >> 2;
- if (iReg < RT_ELEMENTS(g_aOpRegs))
- {
- const AHCIOPREG *pReg = &g_aOpRegs[iReg];
- rc = pReg->pfnWrite(pAhci, iReg, *(uint32_t *)pv);
- }
- else
- {
- Log3(("%s: Trying to write global register %u/%u!!!\n", __FUNCTION__, iReg, RT_ELEMENTS(g_aOpRegs)));
- rc = VINF_SUCCESS;
- }
- }
- else
- {
- uint32_t iPort;
- Log3(("Write Port register\n"));
- /* Calculate accessed port. */
- uOffset -= AHCI_HBA_GLOBAL_SIZE;
- iPort = uOffset / AHCI_PORT_REGISTER_SIZE;
- iReg = (uOffset % AHCI_PORT_REGISTER_SIZE) >> 2;
- Log3(("%s: Trying to write to port %u and register %u\n", __FUNCTION__, iPort, iReg));
- if (RT_LIKELY( iPort < pAhci->cPortsImpl
- && iReg < RT_ELEMENTS(g_aPortOpRegs)))
- {
- const AHCIPORTOPREG *pPortReg = &g_aPortOpRegs[iReg];
- rc = pPortReg->pfnWrite(pAhci, &pAhci->ahciPort[iPort], iReg, *(uint32_t *)pv);
- }
- else
- {
- Log3(("%s: Trying to write port %u register %u/%u!!!\n", __FUNCTION__, iPort, iReg, RT_ELEMENTS(g_aPortOpRegs)));
- rc = VINF_SUCCESS;
- }
- }
+ rc = ahciRegisterWrite(pAhci, uOffset, pv, cb);
return rc;
}
@@ -2274,6 +2356,91 @@ PDMBOTHCBDECL(int) ahciLegacyFakeRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT
return VINF_SUCCESS;
}
+/**
+ * I/O port handler for writes to the index/data register pair.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument.
+ * @param Port Port address where the write starts.
+ * @param pv Where to fetch the result.
+ * @param cb Number of bytes to write.
+ */
+PDMBOTHCBDECL(int) ahciIdxDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
+{
+ PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
+ int rc = VINF_SUCCESS;
+
+ if (Port - pAhci->IOPortBase >= 8)
+ {
+ unsigned iReg = (Port - pAhci->IOPortBase - 8) / 4;
+
+ Assert(cb == 4);
+
+ if (iReg == 0)
+ {
+ /* Write the index register. */
+ pAhci->regIdx = u32;
+ }
+ else
+ {
+ Assert(iReg == 1);
+ rc = ahciRegisterWrite(pAhci, pAhci->regIdx, &u32, cb);
+ if (rc == VINF_IOM_HC_MMIO_WRITE)
+ rc = VINF_IOM_HC_IOPORT_WRITE;
+ }
+ }
+ /* else: ignore */
+
+ Log2(("#%d ahciIdxDataWrite: pu32=%p:{%.*Rhxs} cb=%d Port=%#x rc=%Rrc\n",
+ pDevIns->iInstance, &u32, cb, &u32, cb, Port, rc));
+ return rc;
+}
+
+/**
+ * I/O port handler for reads from the index/data register pair.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument.
+ * @param Port Port address where the read starts.
+ * @param pv Where to fetch the result.
+ * @param cb Number of bytes to write.
+ */
+PDMBOTHCBDECL(int) ahciIdxDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
+{
+ PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
+ int rc = VINF_SUCCESS;
+
+ if (Port - pAhci->IOPortBase >= 8)
+ {
+ unsigned iReg = (Port - pAhci->IOPortBase - 8) / 4;
+
+ Assert(cb == 4);
+
+ if (iReg == 0)
+ {
+ /* Read the index register. */
+ *pu32 = pAhci->regIdx;
+ }
+ else
+ {
+ Assert(iReg == 1);
+ rc = ahciRegisterRead(pAhci, pAhci->regIdx, pu32, cb);
+ if (rc == VINF_IOM_HC_MMIO_READ)
+ rc = VINF_IOM_HC_IOPORT_READ;
+ }
+ }
+ else
+ *pu32 = UINT32_C(0xffffffff);
+
+ Log2(("#%d ahciIdxDataRead: pu32=%p:{%.*Rhxs} cb=%d Port=%#x rc=%Rrc\n",
+ pDevIns->iInstance, pu32, cb, pu32, cb, Port, rc));
+ return rc;
+}
+
#ifndef IN_RING0
/**
* Port I/O Handler for primary port range IN string operations.
@@ -2384,6 +2551,45 @@ static DECLCALLBACK(int) ahciR3LegacyFakeIORangeMap(PPCIDEVICE pPciDev, /*unsign
return rc;
}
+/**
+ * Map the BMDMA I/O port range (used for the Index/Data pair register access)
+ */
+static DECLCALLBACK(int) ahciR3IdxDataIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
+{
+ PAHCI pThis = PCIDEV_2_PAHCI(pPciDev);
+ PPDMDEVINS pDevIns = pPciDev->pDevIns;
+ int rc = VINF_SUCCESS;
+
+ Log2(("%s: registering fake I/O area at GCPhysAddr=%RGp cb=%u\n", __FUNCTION__, GCPhysAddress, cb));
+
+ Assert(enmType == PCI_ADDRESS_SPACE_IO);
+
+ /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */
+ rc = PDMDevHlpIOPortRegister(pDevIns, (RTIOPORT)GCPhysAddress, cb, NULL,
+ ahciIdxDataWrite, ahciIdxDataRead, NULL, NULL, "AHCI IDX/DATA");
+ if (RT_FAILURE(rc))
+ return rc;
+
+ if (pThis->fR0Enabled)
+ {
+ rc = PDMDevHlpIOPortRegisterR0(pDevIns, (RTIOPORT)GCPhysAddress, cb, 0,
+ "ahciIdxDataWrite", "ahciIdxDataRead", NULL, NULL, "AHCI IDX/DATA");
+ if (RT_FAILURE(rc))
+ return rc;
+ }
+
+ if (pThis->fGCEnabled)
+ {
+ rc = PDMDevHlpIOPortRegisterRC(pDevIns, (RTIOPORT)GCPhysAddress, cb, 0,
+ "ahciIdxDataWrite", "ahciIdxDataRead", NULL, NULL, "AHCI IDX/DATA");
+ if (RT_FAILURE(rc))
+ return rc;
+ }
+
+ pThis->IOPortBase = (RTIOPORT)GCPhysAddress;
+ return rc;
+}
+
/* -=-=-=-=-=- PAHCI::ILeds -=-=-=-=-=- */
/**
@@ -2869,6 +3075,8 @@ static int ahciIdentifySS(PAHCIPort pAhciPort, void *pvBuf)
p[101] = RT_H2LE_U16(pAhciPort->cTotalSectors >> 16);
p[102] = RT_H2LE_U16(pAhciPort->cTotalSectors >> 32);
p[103] = RT_H2LE_U16(pAhciPort->cTotalSectors >> 48);
+ if (pAhciPort->fNonRotational)
+ p[217] = RT_H2LE_U16(1); /* Non-rotational medium */
/* The following are SATA specific */
p[75] = RT_H2LE_U16(pAhciPort->CTX_SUFF(pAhci)->cCmdSlotsAvail-1); /* Number of commands we support, 0's based */
@@ -3064,10 +3272,129 @@ static int atapiReadTrackInformationSS(PAHCIPORTTASKSTATE pAhciPortTaskState, PA
return VINF_SUCCESS;
}
+static size_t atapiGetConfigurationFillFeatureListProfiles(PAHCIPort pAhciPort, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 3*4)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x0); /* feature 0: list of profiles supported */
+ pbBuf[2] = (0 << 2) | (1 << 1) | (1 || 0); /* version 0, persistent, current */
+ pbBuf[3] = 8; /* additional bytes for profiles */
+ /* The MMC-3 spec says that DVD-ROM read capability should be reported
+ * before CD-ROM read capability. */
+ ataH2BE_U16(pbBuf + 4, 0x10); /* profile: read-only DVD */
+ pbBuf[6] = (0 << 0); /* NOT current profile */
+ ataH2BE_U16(pbBuf + 8, 0x08); /* profile: read only CD */
+ pbBuf[10] = (1 << 0); /* current profile */
+
+ return 3*4; /* Header + 2 profiles entries */
+}
+
+static size_t atapiGetConfigurationFillFeatureCore(PAHCIPort pAhciPort, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 12)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x1); /* feature 0001h: Core Feature */
+ pbBuf[2] = (0x2 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 8; /* Additional length */
+ ataH2BE_U16(pbBuf + 4, 0x00000002); /* Physical interface ATAPI. */
+ pbBuf[8] = RT_BIT(0); /* DBE */
+ /* Rest is reserved. */
+
+ return 12;
+}
+
+static size_t atapiGetConfigurationFillFeatureMorphing(PAHCIPort pAhciPort, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 8)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x2); /* feature 0002h: Morphing Feature */
+ pbBuf[2] = (0x1 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 4; /* Additional length */
+ pbBuf[4] = RT_BIT(1) | 0x0; /* OCEvent | !ASYNC */
+ /* Rest is reserved. */
+
+ return 8;
+}
+
+static size_t atapiGetConfigurationFillFeatureRemovableMedium(PAHCIPort pAhciPort, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 8)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x3); /* feature 0003h: Removable Medium Feature */
+ pbBuf[2] = (0x2 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 4; /* Additional length */
+ /* Tray type loading | Load | Eject | !Pvnt Jmpr | !DBML | Lock */
+ pbBuf[4] = (0x2 << 5) | RT_BIT(4) | RT_BIT(3) | (0x0 << 2) | (0x0 << 1) | RT_BIT(0);
+ /* Rest is reserved. */
+
+ return 8;
+}
+
+static size_t atapiGetConfigurationFillFeatureRandomReadable(PAHCIPort pAhciPort, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 12)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x10); /* feature 0010h: Random Readable Feature */
+ pbBuf[2] = (0x0 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 8; /* Additional length */
+ ataH2BE_U32(pbBuf + 4, 2048); /* Logical block size. */
+ ataH2BE_U16(pbBuf + 8, 0x10); /* Blocking (0x10 for DVD, CD is not defined). */
+ pbBuf[10] = 0; /* PP not present */
+ /* Rest is reserved. */
+
+ return 12;
+}
+
+static size_t atapiGetConfigurationFillFeatureCDRead(PAHCIPort pAhciPort, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 8)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x1e); /* feature 001Eh: CD Read Feature */
+ pbBuf[2] = (0x2 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 0; /* Additional length */
+ pbBuf[4] = (0x0 << 7) | (0x0 << 1) | 0x0; /* !DAP | !C2-Flags | !CD-Text. */
+ /* Rest is reserved. */
+
+ return 8;
+}
+
+static size_t atapiGetConfigurationFillFeaturePowerManagement(PAHCIPort pAhciPort, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 4)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x100); /* feature 0100h: Power Management Feature */
+ pbBuf[2] = (0x0 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 0; /* Additional length */
+
+ return 4;
+}
+
+static size_t atapiGetConfigurationFillFeatureTimeout(PAHCIPort pAhciPort, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 8)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x105); /* feature 0105h: Timeout Feature */
+ pbBuf[2] = (0x0 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 4; /* Additional length */
+ pbBuf[4] = 0x0; /* !Group3 */
+
+ return 8;
+}
static int atapiGetConfigurationSS(PAHCIPORTTASKSTATE pAhciPortTaskState, PAHCIPort pAhciPort, int *pcbData)
{
- uint8_t aBuf[32];
+ uint8_t aBuf[80];
+ uint8_t *pbBuf = &aBuf[0];
+ size_t cbBuf = sizeof(aBuf);
+ size_t cbCopied = 0;
/* Accept valid request types only, and only starting feature 0. */
if ((pAhciPortTaskState->aATAPICmd[1] & 0x03) == 3 || ataBE2H_U16(&pAhciPortTaskState->aATAPICmd[2]) != 0)
@@ -3075,24 +3402,49 @@ static int atapiGetConfigurationSS(PAHCIPORTTASKSTATE pAhciPortTaskState, PAHCIP
atapiCmdErrorSimple(pAhciPort, pAhciPortTaskState, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
return VINF_SUCCESS;
}
- memset(aBuf, '\0', 32);
- ataH2BE_U32(aBuf, 16);
/** @todo implement switching between CD-ROM and DVD-ROM profile (the only
* way to differentiate them right now is based on the image size). */
if (pAhciPort->cTotalSectors)
- ataH2BE_U16(aBuf + 6, 0x08); /* current profile: read-only CD */
+ ataH2BE_U16(pbBuf + 6, 0x08); /* current profile: read-only CD */
else
- ataH2BE_U16(aBuf + 6, 0x00); /* current profile: none -> no media */
+ ataH2BE_U16(pbBuf + 6, 0x00); /* current profile: none -> no media */
+ cbBuf -= 8;
+ pbBuf += 8;
- ataH2BE_U16(aBuf + 8, 0); /* feature 0: list of profiles supported */
- aBuf[10] = (0 << 2) | (1 << 1) | (1 || 0); /* version 0, persistent, current */
- aBuf[11] = 8; /* additional bytes for profiles */
- /* The MMC-3 spec says that DVD-ROM read capability should be reported
- * before CD-ROM read capability. */
- ataH2BE_U16(aBuf + 12, 0x10); /* profile: read-only DVD */
- aBuf[14] = (0 << 0); /* NOT current profile */
- ataH2BE_U16(aBuf + 16, 0x08); /* profile: read only CD */
- aBuf[18] = (1 << 0); /* current profile */
+ cbCopied = atapiGetConfigurationFillFeatureListProfiles(pAhciPort, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureCore(pAhciPort, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureMorphing(pAhciPort, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureRemovableMedium(pAhciPort, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureRandomReadable(pAhciPort, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureCDRead(pAhciPort, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeaturePowerManagement(pAhciPort, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureTimeout(pAhciPort, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ /* Set data length now. */
+ ataH2BE_U32(&aBuf[0], sizeof(aBuf) - cbBuf);
/* Copy the buffer in to the scatter gather list. */
*pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
@@ -3789,13 +4141,13 @@ static int atapiReadSectors(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTas
switch (cbSector)
{
case 2048:
- pAhciPortTaskState->uOffset = iATAPILBA * cbSector;
+ pAhciPortTaskState->uOffset = (uint64_t)iATAPILBA * cbSector;
pAhciPortTaskState->cbTransfer = cSectors * cbSector;
break;
case 2352:
{
pAhciPortTaskState->pfnPostProcess = atapiReadSectors2352PostProcess;
- pAhciPortTaskState->uOffset = iATAPILBA * 2048;
+ pAhciPortTaskState->uOffset = (uint64_t)iATAPILBA * 2048;
pAhciPortTaskState->cbTransfer = cSectors * 2048;
break;
}
@@ -4032,17 +4384,24 @@ static AHCITXDIR atapiParseCmdVirtualATAPI(PAHCIPort pAhciPort, PAHCIPORTTASKSTA
case 1: /* 01 - Start motor */
break;
case 2: /* 10 - Eject media */
+ {
/* This must be done from EMT. */
+ PAHCI pAhci = pAhciPort->CTX_SUFF(pAhci);
+ PPDMDEVINS pDevIns = pAhci->CTX_SUFF(pDevIns);
+
+ rc2 = VMR3ReqCallWait(PDMDevHlpGetVM(pDevIns), VMCPUID_ANY,
+ (PFNRT)pAhciPort->pDrvMount->pfnUnmount, 3,
+ pAhciPort->pDrvMount, false/*=fForce*/, true/*=fEject*/);
+ Assert(RT_SUCCESS(rc2) || (rc2 == VERR_PDM_MEDIA_LOCKED) || (rc2 = VERR_PDM_MEDIA_NOT_MOUNTED));
+ if (RT_SUCCESS(rc) && pAhci->pMediaNotify)
{
- PAHCI pAhci = pAhciPort->CTX_SUFF(pAhci);
- PPDMDEVINS pDevIns = pAhci->CTX_SUFF(pDevIns);
-
- rc2 = VMR3ReqCallWait(PDMDevHlpGetVM(pDevIns), VMCPUID_ANY,
- (PFNRT)pAhciPort->pDrvMount->pfnUnmount, 3,
- pAhciPort->pDrvMount, false/*=fForce*/, true/*=fEject*/);
- Assert(RT_SUCCESS(rc2) || (rc2 == VERR_PDM_MEDIA_LOCKED) || (rc2 = VERR_PDM_MEDIA_NOT_MOUNTED));
+ rc2 = VMR3ReqCallNoWait(PDMDevHlpGetVM(pDevIns), VMCPUID_ANY,
+ (PFNRT)pAhci->pMediaNotify->pfnEjected, 2,
+ pAhci->pMediaNotify, pAhciPort->iLUN);
+ AssertRC(rc);
}
break;
+ }
case 3: /* 11 - Load media */
/** @todo rc = s->pDrvMount->pfnLoadMedia(s->pDrvMount) */
break;
@@ -5397,6 +5756,30 @@ static int ahciScatterGatherListCreate(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE p
}
/**
+ * Free all memory of the scatter gather list.
+ *
+ * @returns nothing.
+ * @param pAhciPortTaskState Task state.
+ */
+static void ahciScatterGatherListFree(PAHCIPORTTASKSTATE pAhciPortTaskState)
+{
+ if (pAhciPortTaskState->pSGListHead)
+ RTMemFree(pAhciPortTaskState->pSGListHead);
+ if (pAhciPortTaskState->paSGEntries)
+ RTMemFree(pAhciPortTaskState->paSGEntries);
+ if (pAhciPortTaskState->pvBufferUnaligned)
+ RTMemPageFree(pAhciPortTaskState->pvBufferUnaligned, pAhciPortTaskState->cbBufferUnaligned);
+
+ /* Safety. */
+ pAhciPortTaskState->cSGListSize = 0;
+ pAhciPortTaskState->cSGListTooBig = 0;
+ pAhciPortTaskState->pSGListHead = NULL;
+ pAhciPortTaskState->paSGEntries = NULL;
+ pAhciPortTaskState->pvBufferUnaligned = NULL;
+ pAhciPortTaskState->cbBufferUnaligned = 0;
+}
+
+/**
* Destroy a scatter gather list and free all occupied resources (mappings, etc.)
*
* @returns VBox status code.
@@ -5441,18 +5824,7 @@ static int ahciScatterGatherListDestroy(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE
/* Free allocated memory if the list was too big too many times. */
if (pAhciPortTaskState->cSGListTooBig >= AHCI_NR_OF_ALLOWED_BIGGER_LISTS)
- {
- RTMemFree(pAhciPortTaskState->pSGListHead);
- RTMemFree(pAhciPortTaskState->paSGEntries);
- if (pAhciPortTaskState->pvBufferUnaligned)
- RTMemPageFree(pAhciPortTaskState->pvBufferUnaligned, pAhciPortTaskState->cbBufferUnaligned);
- pAhciPortTaskState->cSGListSize = 0;
- pAhciPortTaskState->cSGListTooBig = 0;
- pAhciPortTaskState->pSGListHead = NULL;
- pAhciPortTaskState->paSGEntries = NULL;
- pAhciPortTaskState->pvBufferUnaligned = NULL;
- pAhciPortTaskState->cbBufferUnaligned = 0;
- }
+ ahciScatterGatherListFree(pAhciPortTaskState);
STAM_PROFILE_STOP(&pAhciPort->StatProfileDestroyScatterGatherList, a);
@@ -5583,6 +5955,44 @@ static int ahciScatterGatherListCopyFromBuffer(PAHCIPORTTASKSTATE pAhciPortTaskS
return cbCopied;
}
+/**
+ * Cancels all active tasks on the port.
+ *
+ * @returns Whether all active tasks were canceled.
+ * @param pAhciPort The ahci port.
+ */
+static bool ahciCancelActiveTasks(PAHCIPort pAhciPort)
+{
+ for (unsigned i = 0; i < RT_ELEMENTS(pAhciPort->aCachedTasks); i++)
+ {
+ PAHCIPORTTASKSTATE pAhciPortTaskState = pAhciPort->aCachedTasks[i];
+
+ if (VALID_PTR(pAhciPortTaskState))
+ {
+ bool fXchg = false;
+ ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_CANCELED, AHCITXSTATE_ACTIVE, fXchg);
+
+ if (fXchg)
+ {
+ /* Task is active and was canceled. */
+ AssertMsg(pAhciPort->cTasksActive > 0, ("Task was canceled but none is active\n"));
+ ASMAtomicDecU32(&pAhciPort->cTasksActive);
+
+ /*
+ * Clear the pointer in the cached array. The controller will allocate a
+ * a new task structure for this tag.
+ */
+ ASMAtomicWriteNullPtr(&pAhciPort->aCachedTasks[i]);
+ }
+ else
+ AssertMsg(pAhciPortTaskState->enmTxState == AHCITXSTATE_FREE,
+ ("Invalid task state, must be free!\n"));
+ }
+ }
+
+ return true; /* always true for now because tasks don't use guest memory as the buffer which makes canceling a task impossible. */
+}
+
/* -=-=-=-=- IBlockAsyncPort -=-=-=-=- */
/** Makes a PAHCIPort out of a PPDMIBLOCKASYNCPORT. */
@@ -5652,89 +6062,120 @@ bool ahciIsRedoSetWarning(PAHCIPort pAhciPort, int rc)
*/
static int ahciTransferComplete(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState, int rcReq)
{
+ bool fXchg = false;
bool fRedo = false;
- /* Free system resources occupied by the scatter gather list. */
- if (pAhciPortTaskState->enmTxDir != AHCITXDIR_FLUSH)
- ahciScatterGatherListDestroy(pAhciPort, pAhciPortTaskState);
+ ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg);
- if (pAhciPortTaskState->enmTxDir == AHCITXDIR_READ)
- {
- STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesRead, pAhciPortTaskState->cbTransfer);
- pAhciPort->Led.Actual.s.fReading = 0;
- }
- else if (pAhciPortTaskState->enmTxDir == AHCITXDIR_WRITE)
+ if (fXchg)
{
- STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesWritten, pAhciPortTaskState->cbTransfer);
- pAhciPort->Led.Actual.s.fWriting = 0;
- }
+ /* Free system resources occupied by the scatter gather list. */
+ if (pAhciPortTaskState->enmTxDir != AHCITXDIR_FLUSH)
+ ahciScatterGatherListDestroy(pAhciPort, pAhciPortTaskState);
- if (RT_FAILURE(rcReq))
- {
- /* Log the error. */
- if (pAhciPort->cErrors++ < MAX_LOG_REL_ERRORS)
+ if (pAhciPortTaskState->enmTxDir == AHCITXDIR_READ)
{
- if (pAhciPortTaskState->enmTxDir == AHCITXDIR_FLUSH)
- LogRel(("AHCI#%u: Flush returned rc=%Rrc\n",
- pAhciPort->iLUN, rcReq));
- else
- LogRel(("AHCI#%u: %s at offset %llu (%u bytes left) returned rc=%Rrc\n",
- pAhciPort->iLUN,
- pAhciPortTaskState->enmTxDir == AHCITXDIR_READ
- ? "Read"
- : "Write",
- pAhciPortTaskState->uOffset,
- pAhciPortTaskState->cbTransfer, rcReq));
+ STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesRead, pAhciPortTaskState->cbTransfer);
+ pAhciPort->Led.Actual.s.fReading = 0;
+ }
+ else if (pAhciPortTaskState->enmTxDir == AHCITXDIR_WRITE)
+ {
+ STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesWritten, pAhciPortTaskState->cbTransfer);
+ pAhciPort->Led.Actual.s.fWriting = 0;
}
- fRedo = ahciIsRedoSetWarning(pAhciPort, rcReq);
- if (!fRedo)
+ if (RT_FAILURE(rcReq))
{
- pAhciPortTaskState->cmdHdr.u32PRDBC = 0;
- pAhciPortTaskState->uATARegError = ID_ERR;
- pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_ERR;
- ASMAtomicCmpXchgPtr(&pAhciPort->pTaskErr, pAhciPortTaskState, NULL);
+ /* Log the error. */
+ if (pAhciPort->cErrors++ < MAX_LOG_REL_ERRORS)
+ {
+ if (pAhciPortTaskState->enmTxDir == AHCITXDIR_FLUSH)
+ LogRel(("AHCI#%u: Flush returned rc=%Rrc\n",
+ pAhciPort->iLUN, rcReq));
+ else
+ LogRel(("AHCI#%u: %s at offset %llu (%u bytes left) returned rc=%Rrc\n",
+ pAhciPort->iLUN,
+ pAhciPortTaskState->enmTxDir == AHCITXDIR_READ
+ ? "Read"
+ : "Write",
+ pAhciPortTaskState->uOffset,
+ pAhciPortTaskState->cbTransfer, rcReq));
+ }
+
+ fRedo = ahciIsRedoSetWarning(pAhciPort, rcReq);
+ if (!fRedo)
+ {
+ pAhciPortTaskState->cmdHdr.u32PRDBC = 0;
+ pAhciPortTaskState->uATARegError = ID_ERR;
+ pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_ERR;
+ ASMAtomicCmpXchgPtr(&pAhciPort->pTaskErr, pAhciPortTaskState, NULL);
+ }
+ else
+ ASMAtomicOrU32(&pAhciPort->u32TasksNew, (1 << pAhciPortTaskState->uTag));
}
else
- ASMAtomicOrU32(&pAhciPort->u32TasksNew, (1 << pAhciPortTaskState->uTag));
- }
- else
- {
- pAhciPortTaskState->cmdHdr.u32PRDBC = pAhciPortTaskState->cbTransfer;
+ {
+ pAhciPortTaskState->cmdHdr.u32PRDBC = pAhciPortTaskState->cbTransfer;
- pAhciPortTaskState->uATARegError = 0;
- pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK;
+ pAhciPortTaskState->uATARegError = 0;
+ pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK;
- /* Write updated command header into memory of the guest. */
- PDMDevHlpPhysWrite(pAhciPort->CTX_SUFF(pDevIns), pAhciPortTaskState->GCPhysCmdHdrAddr,
- &pAhciPortTaskState->cmdHdr, sizeof(CmdHdr));
- }
+ /* Write updated command header into memory of the guest. */
+ PDMDevHlpPhysWrite(pAhciPort->CTX_SUFF(pDevIns), pAhciPortTaskState->GCPhysCmdHdrAddr,
+ &pAhciPortTaskState->cmdHdr, sizeof(CmdHdr));
+ }
-#ifdef RT_STRICT
- bool fXchg = ASMAtomicCmpXchgBool(&pAhciPortTaskState->fActive, false, true);
- AssertMsg(fXchg, ("Task is not active\n"));
-#endif
+ /* Add the task to the cache. */
+ ASMAtomicWritePtr(&pAhciPort->aCachedTasks[pAhciPortTaskState->uTag], pAhciPortTaskState);
+ ASMAtomicDecU32(&pAhciPort->cTasksActive);
- /* Add the task to the cache. */
- ASMAtomicWritePtr(&pAhciPort->aCachedTasks[pAhciPortTaskState->uTag], pAhciPortTaskState);
- ASMAtomicDecU32(&pAhciPort->cTasksActive);
+ if (!fRedo)
+ {
+ if (pAhciPortTaskState->fQueued)
+ {
+ if (RT_SUCCESS(rcReq) && !ASMAtomicReadPtrT(&pAhciPort->pTaskErr, PAHCIPORTTASKSTATE))
+ ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, (1 << pAhciPortTaskState->uTag));
- if (!fRedo)
+ /*
+ * Always raise an interrupt after task completion; delaying
+ * this (interrupt coalescing) increases latency and has a significant
+ * impact on performance (see #5071)
+ */
+ ahciSendSDBFis(pAhciPort, 0, true);
+ }
+ else
+ ahciSendD2HFis(pAhciPort, pAhciPortTaskState, pAhciPortTaskState->cmdFis, true);
+ }
+ }
+ else
{
- if (pAhciPortTaskState->fQueued)
+ /*
+ * Task was canceled, do the cleanup but DO NOT access the guest memory!
+ * The guest might use it for other things now because it doesn't know about that task anymore.
+ */
+ AssertMsg(pAhciPortTaskState->enmTxState == AHCITXSTATE_CANCELED,
+ ("Task is not active but wasn't canceled!\n"));
+
+ ahciScatterGatherListFree(pAhciPortTaskState);
+
+ /* Leave a log message about the canceled request. */
+ if (pAhciPort->cErrors++ < MAX_LOG_REL_ERRORS)
{
- if (RT_SUCCESS(rcReq) && !ASMAtomicReadPtrT(&pAhciPort->pTaskErr, PAHCIPORTTASKSTATE))
- ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, (1 << pAhciPortTaskState->uTag));
+ if (pAhciPortTaskState->enmTxDir == AHCITXDIR_FLUSH)
+ LogRel(("AHCI#%u: Canceled flush returned rc=%Rrc\n",
+ pAhciPort->iLUN, rcReq));
+ else
+ LogRel(("AHCI#%u: Canceled %s at offset %llu (%u bytes left) returned rc=%Rrc\n",
+ pAhciPort->iLUN,
+ pAhciPortTaskState->enmTxDir == AHCITXDIR_READ
+ ? "read"
+ : "write",
+ pAhciPortTaskState->uOffset,
+ pAhciPortTaskState->cbTransfer, rcReq));
+ }
- /*
- * Always raise an interrupt after task completion; delaying
- * this (interrupt coalescing) increases latency and has a significant
- * impact on performance (see #5071)
- */
- ahciSendSDBFis(pAhciPort, 0, true);
- }
- else
- ahciSendD2HFis(pAhciPort, pAhciPortTaskState, pAhciPortTaskState->cmdFis, true);
+ /* Finally free the task state structure because it is completely unused now. */
+ RTMemFree(pAhciPortTaskState);
}
return VINF_SUCCESS;
@@ -6181,14 +6622,14 @@ static DECLCALLBACK(bool) ahciNotifyQueueConsumer(PPDMDEVINS pDevIns, PPDMQUEUEI
{
pAhciPortTaskState = (PAHCIPORTTASKSTATE)RTMemAllocZ(sizeof(AHCIPORTTASKSTATE));
AssertMsg(pAhciPortTaskState, ("%s: Cannot allocate task state memory!\n"));
+ pAhciPortTaskState->enmTxState = AHCITXSTATE_FREE;
}
else
pAhciPortTaskState = pAhciPort->aCachedTasks[idx];
-#ifdef RT_STRICT
- bool fXchg = ASMAtomicCmpXchgBool(&pAhciPortTaskState->fActive, true, false);
+ bool fXchg;
+ ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_ACTIVE, AHCITXSTATE_FREE, fXchg);
AssertMsg(fXchg, ("Task is already active\n"));
-#endif
pAhciPortTaskState->uATARegStatus = 0;
pAhciPortTaskState->uATARegError = 0;
@@ -6217,20 +6658,18 @@ static DECLCALLBACK(bool) ahciNotifyQueueConsumer(PPDMDEVINS pDevIns, PPDMQUEUEI
pAhciPort->fResetDevice = true;
ahciSendD2HFis(pAhciPort, pAhciPortTaskState, pAhciPortTaskState->cmdFis, true);
pAhciPort->aCachedTasks[idx] = pAhciPortTaskState;
-#ifdef RT_STRICT
- fXchg = ASMAtomicCmpXchgBool(&pAhciPortTaskState->fActive, false, true);
+
+ ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg);
AssertMsg(fXchg, ("Task is not active\n"));
-#endif
return true;
}
else if (pAhciPort->fResetDevice) /* The bit is not set and we are in a reset state. */
{
ahciFinishStorageDeviceReset(pAhciPort, pAhciPortTaskState);
pAhciPort->aCachedTasks[idx] = pAhciPortTaskState;
-#ifdef RT_STRICT
- fXchg = ASMAtomicCmpXchgBool(&pAhciPortTaskState->fActive, false, true);
+
+ ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg);
AssertMsg(fXchg, ("Task is not active\n"));
-#endif
return true;
}
else /* We are not in a reset state update the control registers. */
@@ -6283,10 +6722,8 @@ static DECLCALLBACK(bool) ahciNotifyQueueConsumer(PPDMDEVINS pDevIns, PPDMQUEUEI
}
else
{
-#ifdef RT_STRICT
- fXchg = ASMAtomicCmpXchgBool(&pAhciPortTaskState->fActive, false, true);
+ ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg);
AssertMsg(fXchg, ("Task is not active\n"));
-#endif
/* There is nothing left to do. Notify the guest. */
ahciSendD2HFis(pAhciPort, pAhciPortTaskState, &pAhciPortTaskState->cmdFis[0], true);
@@ -6654,7 +7091,7 @@ static DECLCALLBACK(int) ahciAsyncIOLoopWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pT
/* -=-=-=-=- DBGF -=-=-=-=- */
/**
- * LsiLogic status info callback.
+ * AHCI status info callback.
*
* @param pDevIns The device instance.
* @param pHlp The output helpers.
@@ -7238,21 +7675,7 @@ static DECLCALLBACK(void) ahciMountNotify(PPDMIMOUNTNOTIFY pInterface)
ataMediumTypeSet(pAhciPort, ATA_MEDIA_TYPE_UNKNOWN);
}
else
- {
- pAhciPort->cTotalSectors = pAhciPort->pDrvBlock->pfnGetSize(pAhciPort->pDrvBlock) / 512;
-
- /*
- * Initialize registers
- */
- pAhciPort->regCMD |= AHCI_PORT_CMD_CPS;
- ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_CPDS | AHCI_PORT_IS_PRCS);
- pAhciPort->regSERR |= AHCI_PORT_SERR_N;
- if (pAhciPort->regIE & AHCI_PORT_IE_CPDE)
- {
- int rc = ahciHbaSetInterrupt(pAhciPort->CTX_SUFF(pAhci), pAhciPort->iLUN, VERR_IGNORED);
- AssertRC(rc);
- }
- }
+ AssertMsgFailed(("Hard disks don't have a mount interface!\n"));
}
/**
@@ -7279,20 +7702,7 @@ static DECLCALLBACK(void) ahciUnmountNotify(PPDMIMOUNTNOTIFY pInterface)
ataMediumTypeSet(pAhciPort, ATA_MEDIA_TYPE_UNKNOWN);
}
else
- {
- /*
- * Inform the guest about the removed device.
- */
- pAhciPort->regSSTS = 0;
- pAhciPort->regCMD &= ~AHCI_PORT_CMD_CPS;
- ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_CPDS | AHCI_PORT_IS_PRCS);
- pAhciPort->regSERR |= AHCI_PORT_SERR_N;
- if (pAhciPort->regIE & AHCI_PORT_IE_CPDE)
- {
- int rc = ahciHbaSetInterrupt(pAhciPort->CTX_SUFF(pAhci), pAhciPort->iLUN, VERR_IGNORED);
- AssertRC(rc);
- }
- }
+ AssertMsgFailed(("Hard disks don't have a mount interface!\n"));
}
/**
@@ -7474,10 +7884,121 @@ static DECLCALLBACK(void) ahciR3Resume(PPDMDEVINS pDevIns)
if (pAhci->fBootable)
for (uint32_t i = 0; i < RT_ELEMENTS(pAhci->aCts); i++)
ataControllerResume(&pAhci->aCts[i]);
- return;
}
/**
+ * Initializes the VPD data of a attached device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pAhciPort The attached device.
+ * @param szName Name of the port to get the CFGM node.
+ */
+static int ahciR3VpdInit(PPDMDEVINS pDevIns, PAHCIPort pAhciPort, const char *pszName)
+{
+ int rc = VINF_SUCCESS;
+ PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
+
+ /* Generate a default serial number. */
+ char szSerial[AHCI_SERIAL_NUMBER_LENGTH+1];
+ RTUUID Uuid;
+
+ if (pAhciPort->pDrvBlock)
+ rc = pAhciPort->pDrvBlock->pfnGetUuid(pAhciPort->pDrvBlock, &Uuid);
+ else
+ RTUuidClear(&Uuid);
+
+ if (RT_FAILURE(rc) || RTUuidIsNull(&Uuid))
+ {
+ /* Generate a predictable serial for drives which don't have a UUID. */
+ RTStrPrintf(szSerial, sizeof(szSerial), "VB%x-1a2b3c4d",
+ pAhciPort->iLUN);
+ }
+ else
+ RTStrPrintf(szSerial, sizeof(szSerial), "VB%08x-%08x", Uuid.au32[0], Uuid.au32[3]);
+
+ /* Get user config if present using defaults otherwise. */
+ PCFGMNODE pCfgNode = CFGMR3GetChild(pDevIns->pCfg, pszName);
+ rc = CFGMR3QueryStringDef(pCfgNode, "SerialNumber", pAhciPort->szSerialNumber, sizeof(pAhciPort->szSerialNumber),
+ szSerial);
+ if (RT_FAILURE(rc))
+ {
+ if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
+ return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
+ N_("AHCI configuration error: \"SerialNumber\" is longer than 20 bytes"));
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("AHCI configuration error: failed to read \"SerialNumber\" as string"));
+ }
+
+ rc = CFGMR3QueryStringDef(pCfgNode, "FirmwareRevision", pAhciPort->szFirmwareRevision, sizeof(pAhciPort->szFirmwareRevision),
+ "1.0");
+ if (RT_FAILURE(rc))
+ {
+ if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
+ return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
+ N_("AHCI configuration error: \"FirmwareRevision\" is longer than 8 bytes"));
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("AHCI configuration error: failed to read \"FirmwareRevision\" as string"));
+ }
+
+ rc = CFGMR3QueryStringDef(pCfgNode, "ModelNumber", pAhciPort->szModelNumber, sizeof(pAhciPort->szModelNumber),
+ pAhciPort->fATAPI ? "VBOX CD-ROM" : "VBOX HARDDISK");
+ if (RT_FAILURE(rc))
+ {
+ if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
+ return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
+ N_("AHCI configuration error: \"ModelNumber\" is longer than 40 bytes"));
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("AHCI configuration error: failed to read \"ModelNumber\" as string"));
+ }
+
+ rc = CFGMR3QueryBoolDef(pCfgNode, "NonRotationalMedium", &pAhciPort->fNonRotational, false);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("AHCI configuration error: failed to read \"NonRotationalMedium\" as boolean"));
+
+ /* There are three other identification strings for CD drives used for INQUIRY */
+ if (pAhciPort->fATAPI)
+ {
+ rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIVendorId", pAhciPort->szInquiryVendorId, sizeof(pAhciPort->szInquiryVendorId),
+ "VBOX");
+ if (RT_FAILURE(rc))
+ {
+ if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
+ return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
+ N_("AHCI configuration error: \"ATAPIVendorId\" is longer than 16 bytes"));
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("AHCI configuration error: failed to read \"ATAPIVendorId\" as string"));
+ }
+
+ rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIProductId", pAhciPort->szInquiryProductId, sizeof(pAhciPort->szInquiryProductId),
+ "CD-ROM");
+ if (RT_FAILURE(rc))
+ {
+ if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
+ return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
+ N_("AHCI configuration error: \"ATAPIProductId\" is longer than 16 bytes"));
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("AHCI configuration error: failed to read \"ATAPIProductId\" as string"));
+ }
+
+ rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIRevision", pAhciPort->szInquiryRevision, sizeof(pAhciPort->szInquiryRevision),
+ "1.0");
+ if (RT_FAILURE(rc))
+ {
+ if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
+ return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
+ N_("AHCI configuration error: \"ATAPIRevision\" is longer than 4 bytes"));
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("AHCI configuration error: failed to read \"ATAPIRevision\" as string"));
+ }
+ }
+
+ return rc;
+}
+
+
+/**
* Detach notification.
*
* One harddisk at one port has been unplugged.
@@ -7533,6 +8054,21 @@ static DECLCALLBACK(void) ahciR3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32
if (pAhciPort->fATAPI)
ahciMediumRemoved(pAhciPort);
+ if (!(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG))
+ {
+ /*
+ * Inform the guest about the removed device.
+ */
+ pAhciPort->regSSTS = 0;
+ ASMAtomicAndU32(&pAhciPort->regCMD, ~AHCI_PORT_CMD_CPS);
+ ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_CPDS | AHCI_PORT_IS_PRCS);
+ ASMAtomicOrU32(&pAhciPort->regSERR, AHCI_PORT_SERR_N);
+ if ( (pAhciPort->regIE & AHCI_PORT_IE_CPDE)
+ || (pAhciPort->regIE & AHCI_PORT_IE_PCE)
+ || (pAhciPort->regIE & AHCI_PORT_IE_PRCE))
+ ahciHbaSetInterrupt(pAhciPort->CTX_SUFF(pAhci), pAhciPort->iLUN, VERR_IGNORED);
+ }
+
/*
* Zero some important members.
*/
@@ -7606,6 +8142,9 @@ static DECLCALLBACK(int) ahciR3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32
if (RT_SUCCESS(rc))
{
+ char szName[24];
+ RTStrPrintf(szName, sizeof(szName), "Port%d", iLUN);
+
if ( pAhciPort->pDrvBlockAsync
&& !pAhciPort->fATAPI)
{
@@ -7613,9 +8152,6 @@ static DECLCALLBACK(int) ahciR3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32
}
else
{
- char szName[24];
- RTStrPrintf(szName, sizeof(szName), "Port%d", iLUN);
-
pAhciPort->fAsyncInterface = false;
/* Create event semaphore. */
@@ -7636,8 +8172,36 @@ static DECLCALLBACK(int) ahciR3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32
}
}
- if (RT_SUCCESS(rc) && pAhciPort->fATAPI)
- ahciMediumInserted(pAhciPort);
+ /*
+ * Init vendor product data.
+ */
+ if (RT_SUCCESS(rc))
+ rc = ahciR3VpdInit(pDevIns, pAhciPort, szName);
+
+ /* Inform the guest about the added device in case of hotplugging. */
+ if ( RT_SUCCESS(rc)
+ && !(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG))
+ {
+ /*
+ * Initialize registers
+ */
+ ASMAtomicOrU32(&pAhciPort->regCMD, AHCI_PORT_CMD_CPS);
+ ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_CPDS | AHCI_PORT_IS_PRCS | AHCI_PORT_IS_PCS);
+ ASMAtomicOrU32(&pAhciPort->regSERR, AHCI_PORT_SERR_X | AHCI_PORT_SERR_N);
+
+ if (pAhciPort->fATAPI)
+ pAhciPort->regSIG = AHCI_PORT_SIG_ATAPI;
+ else
+ pAhciPort->regSIG = AHCI_PORT_SIG_DISK;
+ pAhciPort->regSSTS = (0x01 << 8) | /* Interface is active. */
+ (0x02 << 4) | /* Generation 2 (3.0GBps) speed. */
+ (0x03 << 0); /* Device detected and communication established. */
+
+ if ( (pAhciPort->regIE & AHCI_PORT_IE_CPDE)
+ || (pAhciPort->regIE & AHCI_PORT_IE_PCE)
+ || (pAhciPort->regIE & AHCI_PORT_IE_PRCE))
+ ahciHbaSetInterrupt(pAhciPort->CTX_SUFF(pAhci), pAhciPort->iLUN, VERR_IGNORED);
+ }
}
}
@@ -7727,6 +8291,8 @@ static DECLCALLBACK(int) ahciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
uint32_t cbTotalBufferSize = 0;
PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
+ LogFlowFunc(("pThis=%#p\n", pThis));
+
/*
* Validate and read configuration.
*/
@@ -7818,7 +8384,7 @@ static DECLCALLBACK(int) ahciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
PCIDevSetInterruptPin (&pThis->dev, 0x01);
pThis->dev.config[0x70] = VBOX_PCI_CAP_ID_PM; /* Capability ID: PCI Power Management Interface */
- pThis->dev.config[0x71] = 0x00; /* next */
+ pThis->dev.config[0x71] = 0xa8; /* next */
pThis->dev.config[0x72] = 0x03; /* version ? */
pThis->dev.config[0x90] = 0x40; /* AHCI mode. */
@@ -7827,6 +8393,11 @@ static DECLCALLBACK(int) ahciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
pThis->dev.config[0x95] = 0x01;
pThis->dev.config[0x97] = 0x78;
+ pThis->dev.config[0xa8] = 0x12; /* SATACR capability */
+ pThis->dev.config[0xa9] = 0x00; /* next */
+ PCIDevSetWord(&pThis->dev, 0xaa, 0x0010); /* Revision */
+ PCIDevSetDWord(&pThis->dev, 0xac, 0x00000028); /* SATA Capability Register 1 */
+
/*
* Register the PCI device, it's I/O regions.
*/
@@ -7879,7 +8450,7 @@ static DECLCALLBACK(int) ahciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("AHCI cannot register PCI I/O region"));
- rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ahciR3LegacyFakeIORangeMap);
+ rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ahciR3IdxDataIORangeMap);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("AHCI cannot register PCI I/O region for BMDMA"));
@@ -7889,7 +8460,7 @@ static DECLCALLBACK(int) ahciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("AHCI cannot register PCI memory region for registers"));
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->lock, RT_SRC_POS, "AHCI%d", pDevIns->iInstance);
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->lock, RT_SRC_POS, "AHCI#%u", iInstance);
if (RT_FAILURE(rc))
{
Log(("%s: Failed to create critical section.\n", __FUNCTION__));
@@ -7897,11 +8468,8 @@ static DECLCALLBACK(int) ahciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
}
/* Create the timer for command completion coalescing feature. */
- /** @todo r=bird: Using the virtual sync clock needs some justification.
- * Currently not an issue as this feature isn't used by any guest
- * yet. */
- rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, ahciCccTimer, pThis,
- TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "AHCI CCC Timer", &pThis->pHbaCccTimerR3);
+ rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, ahciCccTimer, pThis,
+ TMTIMER_FLAGS_NO_CRIT_SECT, "AHCI CCC Timer", &pThis->pHbaCccTimerR3);
if (RT_FAILURE(rc))
{
AssertMsgFailed(("pfnTMTimerCreate -> %Rrc\n", rc));
@@ -8003,94 +8571,9 @@ static DECLCALLBACK(int) ahciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
/*
* Init vendor product data.
*/
- /* Generate a default serial number. */
- char szSerial[AHCI_SERIAL_NUMBER_LENGTH+1];
- RTUUID Uuid;
- if (pAhciPort->pDrvBlock)
- rc = pAhciPort->pDrvBlock->pfnGetUuid(pAhciPort->pDrvBlock, &Uuid);
- else
- RTUuidClear(&Uuid);
-
- if (RT_FAILURE(rc) || RTUuidIsNull(&Uuid))
- {
- /* Generate a predictable serial for drives which don't have a UUID. */
- RTStrPrintf(szSerial, sizeof(szSerial), "VB%x-1a2b3c4d",
- pAhciPort->iLUN);
- }
- else
- RTStrPrintf(szSerial, sizeof(szSerial), "VB%08x-%08x", Uuid.au32[0], Uuid.au32[3]);
-
- /* Get user config if present using defaults otherwise. */
- PCFGMNODE pCfgNode = CFGMR3GetChild(pCfg, szName);
- rc = CFGMR3QueryStringDef(pCfgNode, "SerialNumber", pAhciPort->szSerialNumber, sizeof(pAhciPort->szSerialNumber),
- szSerial);
+ rc = ahciR3VpdInit(pDevIns, pAhciPort, szName);
if (RT_FAILURE(rc))
- {
- if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
- return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
- N_("AHCI configuration error: \"SerialNumber\" is longer than 20 bytes"));
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("AHCI configuration error: failed to read \"SerialNumber\" as string"));
- }
-
- rc = CFGMR3QueryStringDef(pCfgNode, "FirmwareRevision", pAhciPort->szFirmwareRevision, sizeof(pAhciPort->szFirmwareRevision),
- "1.0");
- if (RT_FAILURE(rc))
- {
- if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
- return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
- N_("AHCI configuration error: \"FirmwareRevision\" is longer than 8 bytes"));
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("AHCI configuration error: failed to read \"FirmwareRevision\" as string"));
- }
-
- rc = CFGMR3QueryStringDef(pCfgNode, "ModelNumber", pAhciPort->szModelNumber, sizeof(pAhciPort->szModelNumber),
- pAhciPort->fATAPI ? "VBOX CD-ROM" : "VBOX HARDDISK");
- if (RT_FAILURE(rc))
- {
- if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
- return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
- N_("AHCI configuration error: \"ModelNumber\" is longer than 40 bytes"));
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("AHCI configuration error: failed to read \"ModelNumber\" as string"));
- }
-
- /* There are three other identification strings for CD drives used for INQUIRY */
- if (pAhciPort->fATAPI)
- {
- rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIVendorId", pAhciPort->szInquiryVendorId, sizeof(pAhciPort->szInquiryVendorId),
- "VBOX");
- if (RT_FAILURE(rc))
- {
- if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
- return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
- N_("PIIX3 configuration error: \"ATAPIVendorId\" is longer than 16 bytes"));
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("PIIX3 configuration error: failed to read \"ATAPIVendorId\" as string"));
- }
-
- rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIProductId", pAhciPort->szInquiryProductId, sizeof(pAhciPort->szInquiryProductId),
- "CD-ROM");
- if (RT_FAILURE(rc))
- {
- if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
- return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
- N_("PIIX3 configuration error: \"ATAPIProductId\" is longer than 16 bytes"));
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("PIIX3 configuration error: failed to read \"ATAPIProductId\" as string"));
- }
-
- rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIRevision", pAhciPort->szInquiryRevision, sizeof(pAhciPort->szInquiryRevision),
- "1.0");
- if (RT_FAILURE(rc))
- {
- if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
- return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
- N_("PIIX3 configuration error: \"ATAPIRevision\" is longer than 4 bytes"));
- return PDMDEV_SET_ERROR(pDevIns, rc,
- N_("PIIX3 configuration error: failed to read \"ATAPIRevision\" as string"));
- }
- }
+ return rc;
/*
* If the new async interface is available we use a PDMQueue to transmit
@@ -8132,7 +8615,10 @@ static DECLCALLBACK(int) ahciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
*/
rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThis->IBase, &pBase, "Status Port");
if (RT_SUCCESS(rc))
+ {
pThis->pLedsConnector = PDMIBASE_QUERY_INTERFACE(pBase, PDMILEDCONNECTORS);
+ pThis->pMediaNotify = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIANOTIFY);
+ }
else if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
{
AssertMsgFailed(("Failed to attach to status driver. rc=%Rrc\n", rc));
@@ -8184,15 +8670,29 @@ static DECLCALLBACK(int) ahciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
char szName[24];
RTStrPrintf(szName, sizeof(szName), "EmulatedATA%d", i);
- rc = ataControllerInit(pDevIns, pCtl,
+ rc = ataControllerInit(pDevIns, pCtl, pThis->pMediaNotify,
iPortMaster, pThis->ahciPort[iPortMaster].pDrvBase,
&pThis->ahciPort[iPortMaster].Led,
&pThis->ahciPort[iPortMaster].StatBytesRead,
&pThis->ahciPort[iPortMaster].StatBytesWritten,
+ pThis->ahciPort[iPortMaster].szSerialNumber,
+ pThis->ahciPort[iPortMaster].szFirmwareRevision,
+ pThis->ahciPort[iPortMaster].szModelNumber,
+ pThis->ahciPort[iPortMaster].szInquiryVendorId,
+ pThis->ahciPort[iPortMaster].szInquiryProductId,
+ pThis->ahciPort[iPortMaster].szInquiryRevision,
+ pThis->ahciPort[iPortMaster].fNonRotational,
iPortSlave, pThis->ahciPort[iPortSlave].pDrvBase,
&pThis->ahciPort[iPortSlave].Led,
&pThis->ahciPort[iPortSlave].StatBytesRead,
&pThis->ahciPort[iPortSlave].StatBytesWritten,
+ pThis->ahciPort[iPortSlave].szSerialNumber,
+ pThis->ahciPort[iPortSlave].szFirmwareRevision,
+ pThis->ahciPort[iPortSlave].szModelNumber,
+ pThis->ahciPort[iPortSlave].szInquiryVendorId,
+ pThis->ahciPort[iPortSlave].szInquiryProductId,
+ pThis->ahciPort[iPortSlave].szInquiryRevision,
+ pThis->ahciPort[iPortSlave].fNonRotational,
&cbSSMState, szName);
if (RT_FAILURE(rc))
return rc;
diff --git a/src/VBox/Devices/Storage/DevATA.cpp b/src/VBox/Devices/Storage/DevATA.cpp
index 3a8af99c0..1176d9dcf 100644
--- a/src/VBox/Devices/Storage/DevATA.cpp
+++ b/src/VBox/Devices/Storage/DevATA.cpp
@@ -1,10 +1,10 @@
-/* $Id: DevATA.cpp $ */
+/* $Id: DevATA.cpp 37687 2011-06-29 15:22:11Z vboxsync $ */
/** @file
* VBox storage devices: ATA/ATAPI controller device (disk and cdrom).
*/
/*
- * 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;
@@ -103,16 +103,6 @@
#define ATA_MEDIA_TYPE_DATA 1 /**< Data CD */
#define ATA_MEDIA_TYPE_CDDA 2 /**< CD-DA (audio) CD type */
-/**
- * Length of the configurable VPD data (without termination)
- */
-#define ATA_SERIAL_NUMBER_LENGTH 20
-#define ATA_FIRMWARE_REVISION_LENGTH 8
-#define ATA_MODEL_NUMBER_LENGTH 40
-#define ATAPI_INQUIRY_VENDOR_ID_LENGTH 8
-#define ATAPI_INQUIRY_PRODUCT_ID_LENGTH 16
-#define ATAPI_INQUIRY_REVISION_LENGTH 4
-
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
@@ -256,6 +246,8 @@ typedef struct ATADevState
/** Statistics: number of flush operations and the time spend flushing. */
STAMPROFILE StatFlushes;
+ /** Mark the drive as having a non-rotational medium (i.e. as a SSD). */
+ bool fNonRotational;
/** Enable passing through commands directly to the ATAPI drive. */
bool fATAPIPassthrough;
/** Number of errors we've reported to the release log.
@@ -483,6 +475,8 @@ typedef struct PCIATAState
PDMILEDPORTS ILeds;
/** Status LUN: Partner of ILeds. */
R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector;
+ /** Status LUN: Media Notify. */
+ R3PTRTYPE(PPDMIMEDIANOTIFY) pMediaNotify;
/** Flag whether GC is enabled. */
bool fGCEnabled;
/** Flag whether R0 is enabled. */
@@ -1245,6 +1239,8 @@ static bool ataIdentifySS(ATADevState *s)
p[102] = RT_H2LE_U16(s->cTotalSectors >> 32);
p[103] = RT_H2LE_U16(s->cTotalSectors >> 48);
}
+ if (s->fNonRotational)
+ p[217] = RT_H2LE_U16(1); /* Non-rotational medium */
uint32_t uCsum = ataChecksum(p, 510);
p[255] = RT_H2LE_U16(0xa5 | (uCsum << 8)); /* Integrity word */
s->iSourceSink = ATAFN_SS_NULL;
@@ -2325,38 +2321,183 @@ static bool atapiReadTrackInformationSS(ATADevState *s)
return false;
}
+static size_t atapiGetConfigurationFillFeatureListProfiles(ATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 3*4)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x0); /* feature 0: list of profiles supported */
+ pbBuf[2] = (0 << 2) | (1 << 1) | (1 || 0); /* version 0, persistent, current */
+ pbBuf[3] = 8; /* additional bytes for profiles */
+ /* The MMC-3 spec says that DVD-ROM read capability should be reported
+ * before CD-ROM read capability. */
+ ataH2BE_U16(pbBuf + 4, 0x10); /* profile: read-only DVD */
+ pbBuf[6] = (0 << 0); /* NOT current profile */
+ ataH2BE_U16(pbBuf + 8, 0x08); /* profile: read only CD */
+ pbBuf[10] = (1 << 0); /* current profile */
+
+ return 3*4; /* Header + 2 profiles entries */
+}
+
+static size_t atapiGetConfigurationFillFeatureCore(ATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 12)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x1); /* feature 0001h: Core Feature */
+ pbBuf[2] = (0x2 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 8; /* Additional length */
+ ataH2BE_U16(pbBuf + 4, 0x00000002); /* Physical interface ATAPI. */
+ pbBuf[8] = RT_BIT(0); /* DBE */
+ /* Rest is reserved. */
+
+ return 12;
+}
+
+static size_t atapiGetConfigurationFillFeatureMorphing(ATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 8)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x2); /* feature 0002h: Morphing Feature */
+ pbBuf[2] = (0x1 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 4; /* Additional length */
+ pbBuf[4] = RT_BIT(1) | 0x0; /* OCEvent | !ASYNC */
+ /* Rest is reserved. */
+
+ return 8;
+}
+
+static size_t atapiGetConfigurationFillFeatureRemovableMedium(ATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 8)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x3); /* feature 0003h: Removable Medium Feature */
+ pbBuf[2] = (0x2 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 4; /* Additional length */
+ /* Tray type loading | Load | Eject | !Pvnt Jmpr | !DBML | Lock */
+ pbBuf[4] = (0x2 << 5) | RT_BIT(4) | RT_BIT(3) | (0x0 << 2) | (0x0 << 1) | RT_BIT(0);
+ /* Rest is reserved. */
+
+ return 8;
+}
+
+static size_t atapiGetConfigurationFillFeatureRandomReadable(ATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 12)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x10); /* feature 0010h: Random Readable Feature */
+ pbBuf[2] = (0x0 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 8; /* Additional length */
+ ataH2BE_U32(pbBuf + 4, 2048); /* Logical block size. */
+ ataH2BE_U16(pbBuf + 8, 0x10); /* Blocking (0x10 for DVD, CD is not defined). */
+ pbBuf[10] = 0; /* PP not present */
+ /* Rest is reserved. */
+
+ return 12;
+}
+
+static size_t atapiGetConfigurationFillFeatureCDRead(ATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 8)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x1e); /* feature 001Eh: CD Read Feature */
+ pbBuf[2] = (0x2 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 0; /* Additional length */
+ pbBuf[4] = (0x0 << 7) | (0x0 << 1) | 0x0; /* !DAP | !C2-Flags | !CD-Text. */
+ /* Rest is reserved. */
+
+ return 8;
+}
+
+static size_t atapiGetConfigurationFillFeaturePowerManagement(ATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 4)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x100); /* feature 0100h: Power Management Feature */
+ pbBuf[2] = (0x0 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 0; /* Additional length */
+
+ return 4;
+}
+
+static size_t atapiGetConfigurationFillFeatureTimeout(ATADevState *s, uint8_t *pbBuf, size_t cbBuf)
+{
+ if (cbBuf < 8)
+ return 0;
+
+ ataH2BE_U16(pbBuf, 0x105); /* feature 0105h: Timeout Feature */
+ pbBuf[2] = (0x0 << 2) | RT_BIT(1) | RT_BIT(0); /* Version | Persistent | Current */
+ pbBuf[3] = 4; /* Additional length */
+ pbBuf[4] = 0x0; /* !Group3 */
+
+ return 8;
+}
static bool atapiGetConfigurationSS(ATADevState *s)
{
uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
+ size_t cbBuf = s->cbIOBuffer;
+ size_t cbCopied = 0;
uint16_t u16Sfn = ataBE2H_U16(&s->aATAPICmd[2]);
Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
- Assert(s->cbElementaryTransfer <= 32);
+ Assert(s->cbElementaryTransfer <= 80);
/* Accept valid request types only, and only starting feature 0. */
if ((s->aATAPICmd[1] & 0x03) == 3 || u16Sfn != 0)
{
atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
return false;
}
- memset(pbBuf, '\0', 32);
- ataH2BE_U32(pbBuf, 16);
+ memset(pbBuf, '\0', cbBuf);
/** @todo implement switching between CD-ROM and DVD-ROM profile (the only
* way to differentiate them right now is based on the image size). */
if (s->cTotalSectors)
ataH2BE_U16(pbBuf + 6, 0x08); /* current profile: read-only CD */
else
ataH2BE_U16(pbBuf + 6, 0x00); /* current profile: none -> no media */
+ cbBuf -= 8;
+ pbBuf += 8;
+
+ cbCopied = atapiGetConfigurationFillFeatureListProfiles(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureCore(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureMorphing(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureRemovableMedium(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureRandomReadable(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureCDRead(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeaturePowerManagement(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ cbCopied = atapiGetConfigurationFillFeatureTimeout(s, pbBuf, cbBuf);
+ cbBuf -= cbCopied;
+ pbBuf += cbCopied;
+
+ /* Set data length now - the field is not included in the final length. */
+ ataH2BE_U32(s->CTX_SUFF(pbIOBuffer), s->cbIOBuffer - cbBuf - 4);
- ataH2BE_U16(pbBuf + 8, 0); /* feature 0: list of profiles supported */
- pbBuf[10] = (0 << 2) | (1 << 1) | (1 || 0); /* version 0, persistent, current */
- pbBuf[11] = 8; /* additional bytes for profiles */
- /* The MMC-3 spec says that DVD-ROM read capability should be reported
- * before CD-ROM read capability. */
- ataH2BE_U16(pbBuf + 12, 0x10); /* profile: read-only DVD */
- pbBuf[14] = (0 << 0); /* NOT current profile */
- ataH2BE_U16(pbBuf + 16, 0x08); /* profile: read only CD */
- pbBuf[18] = (1 << 0); /* current profile */
/* Other profiles we might want to add in the future: 0x40 (BD-ROM) and 0x50 (HDDVD-ROM) */
s->iSourceSink = ATAFN_SS_NULL;
atapiCmdOK(s);
@@ -2976,23 +3117,31 @@ static void atapiParseCmdVirtualATAPI(ATADevState *s)
case 1: /* 01 - Start motor */
break;
case 2: /* 10 - Eject media */
+ {
/* This must be done from EMT. */
- {
PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
+ PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
PDMCritSectLeave(&pCtl->lock);
rc = VMR3ReqCallWait(PDMDevHlpGetVM(pDevIns), VMCPUID_ANY,
(PFNRT)s->pDrvMount->pfnUnmount, 3,
- s->pDrvMount /*=fForce*/, true /*=fEject*/);
+ s->pDrvMount, false /*=fForce*/, true /*=fEject*/);
Assert(RT_SUCCESS(rc) || (rc == VERR_PDM_MEDIA_LOCKED) || (rc = VERR_PDM_MEDIA_NOT_MOUNTED));
+ if (RT_SUCCESS(rc) && pThis->pMediaNotify)
+ {
+ rc = VMR3ReqCallNoWait(PDMDevHlpGetVM(pDevIns), VMCPUID_ANY,
+ (PFNRT)pThis->pMediaNotify->pfnEjected, 2,
+ pThis->pMediaNotify, s->iLUN);
+ AssertRC(rc);
+ }
{
STAM_PROFILE_START(&pCtl->StatLockWait, a);
PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
}
- }
break;
+ }
case 3: /* 11 - Load media */
/** @todo rc = s->pDrvMount->pfnLoadMedia(s->pDrvMount) */
break;
@@ -3094,7 +3243,7 @@ static void atapiParseCmdVirtualATAPI(ATADevState *s)
case SCSI_GET_CONFIGURATION:
/* No media change stuff here, it can confuse Linux guests. */
cbMax = ataBE2H_U16(pbPacket + 7);
- ataStartTransfer(s, RT_MIN(cbMax, 32), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_CONFIGURATION, true);
+ ataStartTransfer(s, RT_MIN(cbMax, 80), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_CONFIGURATION, true);
break;
case SCSI_INQUIRY:
cbMax = ataBE2H_U16(pbPacket + 3);
@@ -6892,7 +7041,7 @@ static DECLCALLBACK(int) ataR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
#endif /* VBOX_WITH_STATISTICS */
/* Initialize per-controller critical section */
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->aCts[i].lock, RT_SRC_POS, "ATA%u", i);
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->aCts[i].lock, RT_SRC_POS, "ATA#%u", i);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot initialize critical section"));
}
@@ -6902,7 +7051,10 @@ static DECLCALLBACK(int) ataR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
*/
rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThis->IBase, &pBase, "Status Port");
if (RT_SUCCESS(rc))
+ {
pThis->pLedsConnector = PDMIBASE_QUERY_INTERFACE(pBase, PDMILEDCONNECTORS);
+ pThis->pMediaNotify = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIANOTIFY);
+ }
else if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
{
AssertMsgFailed(("Failed to attach to status driver. rc=%Rrc\n", rc));
@@ -7016,6 +7168,11 @@ static DECLCALLBACK(int) ataR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
N_("PIIX3 configuration error: failed to read \"ModelNumber\" as string"));
}
+ rc = CFGMR3QueryBoolDef(pCfgNode, "NonRotationalMedium", &pIf->fNonRotational, false);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("PIIX3 configuration error: failed to read \"NonRotationalMedium\" as boolean"));
+
/* There are three other identification strings for CD drives used for INQUIRY */
if (pIf->fATAPI)
{
diff --git a/src/VBox/Devices/Storage/DevBusLogic.cpp b/src/VBox/Devices/Storage/DevBusLogic.cpp
index 5193030da..439384882 100644
--- a/src/VBox/Devices/Storage/DevBusLogic.cpp
+++ b/src/VBox/Devices/Storage/DevBusLogic.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevBusLogic.cpp $ */
+/* $Id: DevBusLogic.cpp 37636 2011-06-24 14:59:59Z vboxsync $ */
/** @file
* VBox storage devices: BusLogic SCSI host adapter BT-958.
*/
@@ -15,7 +15,9 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-/* Implemented looking at the driver source in the linux kernel (drivers/scsi/BusLogic.[ch]). */
+/* Implemented looking at the driver source in the linux kernel (drivers/scsi/BusLogic.[ch]).
+ * See also: http://www.drdobbs.com/184410111
+ */
/*******************************************************************************
* Header Files *
@@ -139,6 +141,8 @@ enum BUSLOGICCOMMAND
BUSLOGICCOMMAND_INQUIRE_INSTALLED_DEVICES_ID_8_TO_15 = 0x23,
BUSLOGICCOMMAND_INQUIRE_TARGET_DEVICES = 0x24,
BUSLOGICCOMMAND_DISABLE_HOST_ADAPTER_INTERRUPT = 0x25,
+ BUSLOGICCOMMAND_EXT_BIOS_INFO = 0x28,
+ BUSLOGICCOMMAND_UNLOCK_MAILBOX = 0x29,
BUSLOGICCOMMAND_INITIALIZE_EXTENDED_MAILBOX = 0x81,
BUSLOGICCOMMAND_EXECUTE_SCSI_COMMAND = 0x83,
BUSLOGICCOMMAND_INQUIRE_FIRMWARE_VERSION_3RD_LETTER = 0x84,
@@ -774,17 +778,6 @@ typedef struct BUSLOGICTASKSTATE
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
-RT_C_DECLS_BEGIN
-PDMBOTHCBDECL(int) buslogicIOPortWrite (PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) buslogicIOPortRead (PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) buslogicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) buslogicMMIORead(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-RT_C_DECLS_END
-
#define PDMIBASE_2_PBUSLOGICDEVICE(pInterface) ( (PBUSLOGICDEVICE)((uintptr_t)(pInterface) - RT_OFFSETOF(BUSLOGICDEVICE, IBase)) )
#define PDMISCSIPORT_2_PBUSLOGICDEVICE(pInterface) ( (PBUSLOGICDEVICE)((uintptr_t)(pInterface) - RT_OFFSETOF(BUSLOGICDEVICE, ISCSIPort)) )
#define PDMILEDPORTS_2_PBUSLOGICDEVICE(pInterface) ( (PBUSLOGICDEVICE)((uintptr_t)(pInterface) - RT_OFFSETOF(BUSLOGICDEVICE, ILed)) )
@@ -1530,6 +1523,15 @@ static int buslogicProcessCommand(PBUSLOGIC pBusLogic)
Log(("Bus-off time: %d\n", pBusLogic->aCommandBuffer[0]));
break;
}
+ case BUSLOGICCOMMAND_EXT_BIOS_INFO:
+ case BUSLOGICCOMMAND_UNLOCK_MAILBOX:
+ /* Commands valid for Adaptec 154xC which we don't handle since
+ * we pretend being 154xB compatible. Just mark the command as invalid.
+ */
+ Log(("Command %#x not valid for this adapter\n", pBusLogic->uOperationCode));
+ pBusLogic->cbReplyParametersLeft = 0;
+ pBusLogic->regStatus |= BUSLOGIC_REGISTER_STATUS_COMMAND_INVALID;
+ break;
case BUSLOGICCOMMAND_EXECUTE_MAILBOX_COMMAND: /* Should be handled already. */
default:
AssertMsgFailed(("Invalid command %#x\n", pBusLogic->uOperationCode));
@@ -1682,8 +1684,8 @@ static int buslogicRegisterWrite(PBUSLOGIC pBusLogic, unsigned iRegister, uint8_
pBusLogic->uOperationCode = uVal;
pBusLogic->iParameter = 0;
- /* Mark host adapter as busy. */
- pBusLogic->regStatus &= ~BUSLOGIC_REGISTER_STATUS_HOST_ADAPTER_READY;
+ /* Mark host adapter as busy and clear the invalid status bit. */
+ pBusLogic->regStatus &= ~(BUSLOGIC_REGISTER_STATUS_HOST_ADAPTER_READY | BUSLOGIC_REGISTER_STATUS_COMMAND_INVALID);
/* Get the number of bytes for parameters from the command code. */
switch (pBusLogic->uOperationCode)
@@ -1715,6 +1717,11 @@ static int buslogicRegisterWrite(PBUSLOGIC pBusLogic, unsigned iRegister, uint8_
case BUSLOGICCOMMAND_INITIALIZE_EXTENDED_MAILBOX:
pBusLogic->cbCommandParametersLeft = sizeof(RequestInitializeExtendedMailbox);
break;
+ case BUSLOGICCOMMAND_EXT_BIOS_INFO:
+ case BUSLOGICCOMMAND_UNLOCK_MAILBOX:
+ /* Invalid commands. */
+ pBusLogic->cbCommandParametersLeft = 0;
+ break;
case BUSLOGICCOMMAND_EXECUTE_MAILBOX_COMMAND: /* Should not come here anymore. */
default:
AssertMsgFailed(("Invalid operation code %#x\n", uVal));
@@ -1780,7 +1787,7 @@ PDMBOTHCBDECL(int) buslogicMMIORead(PPDMDEVINS pDevIns, void *pvUser,
* @param cb Number of bytes to write.
*/
PDMBOTHCBDECL(int) buslogicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+ RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
/* the linux driver does not make use of the MMIO area. */
AssertMsgFailed(("MMIO Write\n"));
@@ -3117,7 +3124,7 @@ static DECLCALLBACK(int) buslogicConstruct(PPDMDEVINS pDevIns, int iInstance, PC
pThis->pNotifierQueueR0 = PDMQueueR0Ptr(pThis->pNotifierQueueR3);
pThis->pNotifierQueueRC = PDMQueueRCPtr(pThis->pNotifierQueueR3);
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSectIntr, RT_SRC_POS, "BusLogic-Intr");
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSectIntr, RT_SRC_POS, "BusLogic-Intr#%u", pDevIns->iInstance);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("BusLogic: cannot create critical section"));
diff --git a/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp b/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
index 06d913392..cb51411a7 100644
--- a/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
+++ b/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevLsiLogicSCSI.cpp $ */
+/* $Id: DevLsiLogicSCSI.cpp 37636 2011-06-24 14:59:59Z vboxsync $ */
/** @file
* VBox storage devices: LsiLogic LSI53c1030 SCSI controller.
*/
@@ -370,18 +370,6 @@ typedef struct LSILOGICTASKSTATE
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
RT_C_DECLS_BEGIN
-PDMBOTHCBDECL(int) lsilogicIOPortWrite (PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t u32, unsigned cb);
-PDMBOTHCBDECL(int) lsilogicIOPortRead (PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) lsilogicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) lsilogicMMIORead(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) lsilogicDiagnosticWrite(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) lsilogicDiagnosticRead(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
#ifdef IN_RING3
static void lsilogicInitializeConfigurationPages(PLSILOGICSCSI pLsiLogic);
static void lsilogicConfigurationPagesFree(PLSILOGICSCSI pThis);
@@ -963,7 +951,7 @@ static int lsilogicProcessMessageRequest(PLSILOGICSCSI pLsiLogic, PMptMessageHdr
* @param pv Pointer to the value to write
* @param cb Number of bytes to write.
*/
-static int lsilogicRegisterWrite(PLSILOGICSCSI pThis, uint32_t uOffset, void *pv, unsigned cb)
+static int lsilogicRegisterWrite(PLSILOGICSCSI pThis, uint32_t uOffset, void const *pv, unsigned cb)
{
uint32_t u32 = *(uint32_t *)pv;
@@ -1337,7 +1325,7 @@ PDMBOTHCBDECL(int) lsilogicIOPortRead (PPDMDEVINS pDevIns, void *pvUser,
}
PDMBOTHCBDECL(int) lsilogicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+ RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
uint32_t uOffset = GCPhysAddr - pThis->GCPhysMMIOBase;
@@ -1355,7 +1343,7 @@ PDMBOTHCBDECL(int) lsilogicMMIORead(PPDMDEVINS pDevIns, void *pvUser,
}
PDMBOTHCBDECL(int) lsilogicDiagnosticWrite(PPDMDEVINS pDevIns, void *pvUser,
- RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+ RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
@@ -4955,7 +4943,7 @@ static DECLCALLBACK(int) lsilogicConstruct(PPDMDEVINS pDevIns, int iInstance, PC
PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
int rc = VINF_SUCCESS;
char *pszCtrlType = NULL;
- char szDevTag[20], szTaggedText[64];
+ char szDevTag[20];
bool fBootable = true;
PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
@@ -5010,7 +4998,7 @@ static DECLCALLBACK(int) lsilogicConstruct(PPDMDEVINS pDevIns, int iInstance, PC
rc = lsilogicGetCtrlTypeFromString(pThis, pszCtrlType);
MMR3HeapFree(pszCtrlType);
- RTStrPrintf(szDevTag, sizeof(szDevTag), "LSILOGIC%s-%d",
+ RTStrPrintf(szDevTag, sizeof(szDevTag), "LSILOGIC%s-%u",
pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI ? "SPI" : "SAS",
iInstance);
@@ -5117,6 +5105,7 @@ static DECLCALLBACK(int) lsilogicConstruct(PPDMDEVINS pDevIns, int iInstance, PC
return rc;
/* Initialize task queue. (Need two items to handle SMP guest concurrency.) */
+ char szTaggedText[64];
RTStrPrintf(szTaggedText, sizeof(szTaggedText), "%s-Task", szDevTag);
rc = PDMDevHlpQueueCreate(pDevIns, sizeof(PDMQUEUEITEMCORE), 2, 0,
lsilogicNotifyQueueConsumer, true,
@@ -5143,16 +5132,12 @@ static DECLCALLBACK(int) lsilogicConstruct(PPDMDEVINS pDevIns, int iInstance, PC
/*
* Create critical sections protecting the reply post and free queues.
*/
- RTStrPrintf(szTaggedText, sizeof(szTaggedText), "%sRFQ", szDevTag);
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->ReplyFreeQueueCritSect, RT_SRC_POS,
- szTaggedText);
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->ReplyFreeQueueCritSect, RT_SRC_POS, "%sRFQ", szDevTag);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("LsiLogic: cannot create critical section for reply free queue"));
- RTStrPrintf(szTaggedText, sizeof(szTaggedText), "%sRPQ", szDevTag);
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->ReplyPostQueueCritSect, RT_SRC_POS,
- szTaggedText);
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->ReplyPostQueueCritSect, RT_SRC_POS, "%sRPQ", szDevTag);
if (RT_FAILURE(rc))
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("LsiLogic: cannot create critical section for reply post queue"));
diff --git a/src/VBox/Devices/Storage/DevLsiLogicSCSI.h b/src/VBox/Devices/Storage/DevLsiLogicSCSI.h
index 527f5d30c..6044ccf9f 100644
--- a/src/VBox/Devices/Storage/DevLsiLogicSCSI.h
+++ b/src/VBox/Devices/Storage/DevLsiLogicSCSI.h
@@ -1,4 +1,4 @@
-/* $Id: DevLsiLogicSCSI.h $ */
+/* $Id: DevLsiLogicSCSI.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBox storage devices: LsiLogic LSI53c1030 SCSI controller - Defines and structures.
*/
diff --git a/src/VBox/Devices/Storage/DrvBlock.cpp b/src/VBox/Devices/Storage/DrvBlock.cpp
index 7a92757fa..4b45bc16a 100644
--- a/src/VBox/Devices/Storage/DrvBlock.cpp
+++ b/src/VBox/Devices/Storage/DrvBlock.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvBlock.cpp $ */
+/* $Id: DrvBlock.cpp 35560 2011-01-14 13:37:32Z vboxsync $ */
/** @file
* VBox storage devices: Generic block driver
*/
diff --git a/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp b/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
index 6fc17a927..bb2be1882 100644
--- a/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
+++ b/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvDiskIntegrity.cpp $ */
+/* $Id: DrvDiskIntegrity.cpp 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* VBox storage devices: Disk integrity check.
*/
diff --git a/src/VBox/Devices/Storage/DrvHostBase.cpp b/src/VBox/Devices/Storage/DrvHostBase.cpp
index 17fcd878d..ef7d4b3ad 100644
--- a/src/VBox/Devices/Storage/DrvHostBase.cpp
+++ b/src/VBox/Devices/Storage/DrvHostBase.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvHostBase.cpp $ */
+/* $Id: DrvHostBase.cpp 37780 2011-07-05 12:55:13Z vboxsync $ */
/** @file
* DrvHostBase - Host base drive access driver.
*/
@@ -184,24 +184,17 @@ static DECLCALLBACK(int) drvHostBaseRead(PPDMIBLOCK pInterface, uint64_t off, vo
/*
* Seek and read.
*/
- rc = RTFileSeek(pThis->FileDevice, off, RTFILE_SEEK_BEGIN, NULL);
+ rc = RTFileReadAt(pThis->hFileDevice, off, pvBuf, cbRead, NULL);
if (RT_SUCCESS(rc))
{
- rc = RTFileRead(pThis->FileDevice, pvBuf, cbRead, NULL);
- if (RT_SUCCESS(rc))
- {
- Log2(("%s-%d: drvHostBaseRead: off=%#llx cbRead=%#x\n"
- "%16.*Rhxd\n",
- pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, off, cbRead, cbRead, pvBuf));
- }
- else
- Log(("%s-%d: drvHostBaseRead: RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
- pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, pThis->FileDevice,
- pvBuf, cbRead, rc, off, pThis->pszDevice));
+ Log2(("%s-%d: drvHostBaseRead: off=%#llx cbRead=%#x\n"
+ "%16.*Rhxd\n",
+ pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, off, cbRead, cbRead, pvBuf));
}
else
- Log(("%s-%d: drvHostBaseRead: RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->pDrvIns->pReg->szName,
- pThis->pDrvIns->iInstance, pThis->FileDevice, off, rc));
+ Log(("%s-%d: drvHostBaseRead: RTFileReadAt(%RTfile, %#llx, %p, %#x) -> %Rrc ('%s')\n",
+ pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, pThis->hFileDevice,
+ off, pvBuf, cbRead, rc, pThis->pszDevice));
#endif
}
else
@@ -240,18 +233,11 @@ static DECLCALLBACK(int) drvHostBaseWrite(PPDMIBLOCK pInterface, uint64_t off, c
/*
* Seek and write.
*/
- rc = RTFileSeek(pThis->FileDevice, off, RTFILE_SEEK_BEGIN, NULL);
- if (RT_SUCCESS(rc))
- {
- rc = RTFileWrite(pThis->FileDevice, pvBuf, cbWrite, NULL);
- if (RT_FAILURE(rc))
- Log(("%s-%d: drvHostBaseWrite: RTFileWrite(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
- pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, pThis->FileDevice,
- pvBuf, cbWrite, rc, off, pThis->pszDevice));
- }
- else
- Log(("%s-%d: drvHostBaseWrite: RTFileSeek(%d,%#llx,) -> %Rrc\n",
- pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, pThis->FileDevice, off, rc));
+ rc = RTFileWriteAt(pThis->hFileDevice, off, pvBuf, cbWrite, NULL);
+ if (RT_FAILURE(rc))
+ Log(("%s-%d: drvHostBaseWrite: RTFileWriteAt(%RTfile, %#llx, %p, %#x) -> %Rrc ('%s')\n",
+ pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, pThis->hFileDevice,
+ off, pvBuf, cbWrite, rc, pThis->pszDevice));
#endif
}
else
@@ -281,7 +267,7 @@ static DECLCALLBACK(int) drvHostBaseFlush(PPDMIBLOCK pInterface)
rc = VINF_SUCCESS;
/** @todo scsi device buffer flush... */
#else
- rc = RTFileFlush(pThis->FileDevice);
+ rc = RTFileFlush(pThis->hFileDevice);
#endif
}
else
@@ -479,8 +465,39 @@ static DECLCALLBACK(int) drvHostBaseMount(PPDMIMOUNT pInterface, const char *psz
/** @copydoc PDMIMOUNT::pfnUnmount */
static DECLCALLBACK(int) drvHostBaseUnmount(PPDMIMOUNT pInterface, bool fForce, bool fEject)
{
- LogFlow(("drvHostBaseUnmount: returns VERR_NOT_SUPPORTED\n"));
- return VERR_NOT_SUPPORTED;
+ /* While we're not mountable (see drvHostBaseMount), we're unmountable. */
+ PDRVHOSTBASE pThis = PDMIMOUNT_2_DRVHOSTBASE(pInterface);
+ RTCritSectEnter(&pThis->CritSect);
+
+ /*
+ * Validate state.
+ */
+ int rc = VINF_SUCCESS;
+ if (!pThis->fLocked || fForce)
+ {
+ /* Unlock drive if necessary. */
+ if (pThis->fLocked)
+ {
+ if (pThis->pfnDoLock)
+ rc = pThis->pfnDoLock(pThis, false);
+ if (RT_SUCCESS(rc))
+ pThis->fLocked = false;
+ }
+
+ /*
+ * Media is no longer present.
+ */
+ DRVHostBaseMediaNotPresent(pThis);
+ }
+ else
+ {
+ Log(("drvHostiBaseUnmount: Locked\n"));
+ rc = VERR_PDM_MEDIA_LOCKED;
+ }
+
+ RTCritSectLeave(&pThis->CritSect);
+ LogFlow(("drvHostBaseUnmount: returns %Rrc\n", rc));
+ return rc;
}
@@ -761,7 +778,7 @@ static int drvHostBaseObtainExclusiveAccess(PDRVHOSTBASE pThis, io_object_t DVDS
*/
static int drvHostBaseOpen(PDRVHOSTBASE pThis, PRTFILE pFileDevice, bool fReadOnly)
{
-#ifdef RT_OS_DARWIN
+# ifdef RT_OS_DARWIN
/* Darwin is kind of special... */
Assert(!pFileDevice); NOREF(pFileDevice);
Assert(!pThis->cbBlock);
@@ -939,19 +956,9 @@ static int drvHostBaseOpen(PDRVHOSTBASE pThis, PRTFILE pFileDevice, bool fReadOn
IOObjectRelease(DVDServices);
return rc;
-#elif defined(RT_OS_LINUX)
- /** @todo we've got RTFILE_O_NON_BLOCK now. Change the code to use RTFileOpen. */
- int FileDevice = open(pThis->pszDeviceOpen, (pThis->fReadOnlyConfig ? O_RDONLY : O_RDWR) | O_NONBLOCK);
- if (FileDevice < 0)
- return RTErrConvertFromErrno(errno);
- *pFileDevice = FileDevice;
- return VINF_SUCCESS;
-
#elif defined(RT_OS_FREEBSD)
- int rc = VINF_SUCCESS;
- RTFILE FileDevice;
-
- rc = RTFileOpen(&FileDevice, pThis->pszDeviceOpen, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ RTFILE hFileDevice;
+ int rc = RTFileOpen(&hFileDevice, pThis->pszDeviceOpen, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (RT_FAILURE(rc))
return rc;
@@ -963,7 +970,7 @@ static int drvHostBaseOpen(PDRVHOSTBASE pThis, PRTFILE pFileDevice, bool fReadOn
memset(&DeviceCCB, 0, sizeof(DeviceCCB));
DeviceCCB.ccb_h.func_code = XPT_GDEVLIST;
- int rcBSD = ioctl(FileDevice, CAMGETPASSTHRU, &DeviceCCB);
+ int rcBSD = ioctl(RTFileToNative(hFileDevice), CAMGETPASSTHRU, &DeviceCCB);
if (!rcBSD)
{
char *pszPassthroughDevice = NULL;
@@ -971,16 +978,12 @@ static int drvHostBaseOpen(PDRVHOSTBASE pThis, PRTFILE pFileDevice, bool fReadOn
DeviceCCB.cgdl.periph_name, DeviceCCB.cgdl.unit_number);
if (rc >= 0)
{
- RTFILE PassthroughDevice;
-
- rc = RTFileOpen(&PassthroughDevice, pszPassthroughDevice, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
-
+ RTFILE hPassthroughDevice;
+ rc = RTFileOpen(&hPassthroughDevice, pszPassthroughDevice, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
RTStrFree(pszPassthroughDevice);
-
if (RT_SUCCESS(rc))
{
/* Get needed device parameters. */
- union ccb DeviceCCB;
/*
* The device path, target id and lun id. Those are
@@ -989,7 +992,7 @@ static int drvHostBaseOpen(PDRVHOSTBASE pThis, PRTFILE pFileDevice, bool fReadOn
memset(&DeviceCCB, 0, sizeof(DeviceCCB));
DeviceCCB.ccb_h.func_code = XPT_GDEVLIST;
- rcBSD = ioctl(PassthroughDevice, CAMGETPASSTHRU, &DeviceCCB);
+ rcBSD = ioctl(RTFileToNative(hPassthroughDevice), CAMGETPASSTHRU, &DeviceCCB);
if (!rcBSD)
{
if (DeviceCCB.cgdl.status != CAM_GDEVLIST_ERROR)
@@ -997,7 +1000,7 @@ static int drvHostBaseOpen(PDRVHOSTBASE pThis, PRTFILE pFileDevice, bool fReadOn
pThis->ScsiBus = DeviceCCB.ccb_h.path_id;
pThis->ScsiTargetID = DeviceCCB.ccb_h.target_id;
pThis->ScsiLunID = DeviceCCB.ccb_h.target_lun;
- *pFileDevice = PassthroughDevice;
+ *pFileDevice = hPassthroughDevice;
}
else
{
@@ -1009,7 +1012,7 @@ static int drvHostBaseOpen(PDRVHOSTBASE pThis, PRTFILE pFileDevice, bool fReadOn
rc = RTErrConvertFromErrno(errno);
if (RT_FAILURE(rc))
- RTFileClose(PassthroughDevice);
+ RTFileClose(hPassthroughDevice);
}
}
else
@@ -1018,11 +1021,15 @@ static int drvHostBaseOpen(PDRVHOSTBASE pThis, PRTFILE pFileDevice, bool fReadOn
else
rc = RTErrConvertFromErrno(errno);
- RTFileClose(FileDevice);
+ RTFileClose(hFileDevice);
return rc;
+
#else
- return RTFileOpen(pFileDevice, pThis->pszDeviceOpen,
- (fReadOnly ? RTFILE_O_READ : RTFILE_O_READWRITE) | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ uint32_t fFlags = (fReadOnly ? RTFILE_O_READ : RTFILE_O_READWRITE) | RTFILE_O_OPEN | RTFILE_O_DENY_NONE;
+# ifdef RT_OS_LINUX
+ fFlags |= RTFILE_O_NON_BLOCK;
+# endif
+ return RTFileOpen(pFileDevice, pThis->pszDeviceOpen, fFlags);
#endif
}
@@ -1072,22 +1079,22 @@ static int drvHostBaseReopen(PDRVHOSTBASE pThis)
#ifndef RT_OS_DARWIN /* Only *one* open for darwin. */
LogFlow(("%s-%d: drvHostBaseReopen: '%s'\n", pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, pThis->pszDeviceOpen));
- RTFILE FileDevice;
+ RTFILE hFileDevice;
#ifdef RT_OS_SOLARIS
- if (pThis->FileRawDevice != NIL_RTFILE)
+ if (pThis->hFileRawDevice != NIL_RTFILE)
{
- RTFileClose(pThis->FileRawDevice);
- pThis->FileRawDevice = NIL_RTFILE;
+ RTFileClose(pThis->hFileRawDevice);
+ pThis->hFileRawDevice = NIL_RTFILE;
}
- if (pThis->FileDevice != NIL_RTFILE)
+ if (pThis->hFileDevice != NIL_RTFILE)
{
- RTFileClose(pThis->FileDevice);
- pThis->FileDevice = NIL_RTFILE;
+ RTFileClose(pThis->hFileDevice);
+ pThis->hFileDevice = NIL_RTFILE;
}
- RTFILE FileRawDevice;
- int rc = drvHostBaseOpen(pThis, &FileDevice, &FileRawDevice, pThis->fReadOnlyConfig);
+ RTFILE hFileRawDevice;
+ int rc = drvHostBaseOpen(pThis, &hFileDevice, &hFileRawDevice, pThis->fReadOnlyConfig);
#else
- int rc = drvHostBaseOpen(pThis, &FileDevice, pThis->fReadOnlyConfig);
+ int rc = drvHostBaseOpen(pThis, &hFileDevice, pThis->fReadOnlyConfig);
#endif
if (RT_FAILURE(rc))
{
@@ -1095,9 +1102,9 @@ static int drvHostBaseReopen(PDRVHOSTBASE pThis)
{
LogFlow(("%s-%d: drvHostBaseReopen: '%s' - retry readonly (%Rrc)\n", pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, pThis->pszDeviceOpen, rc));
#ifdef RT_OS_SOLARIS
- rc = drvHostBaseOpen(pThis, &FileDevice, &FileRawDevice, false);
+ rc = drvHostBaseOpen(pThis, &hFileDevice, &hFileRawDevice, false);
#else
- rc = drvHostBaseOpen(pThis, &FileDevice, false);
+ rc = drvHostBaseOpen(pThis, &hFileDevice, false);
#endif
}
if (RT_FAILURE(rc))
@@ -1112,14 +1119,14 @@ static int drvHostBaseReopen(PDRVHOSTBASE pThis)
pThis->fReadOnly = pThis->fReadOnlyConfig;
#ifdef RT_OS_SOLARIS
- if (pThis->FileRawDevice != NIL_RTFILE)
- RTFileClose(pThis->FileRawDevice);
- pThis->FileRawDevice = FileRawDevice;
+ if (pThis->hFileRawDevice != NIL_RTFILE)
+ RTFileClose(pThis->hFileRawDevice);
+ pThis->hFileRawDevice = hFileRawDevice;
#endif
- if (pThis->FileDevice != NIL_RTFILE)
- RTFileClose(pThis->FileDevice);
- pThis->FileDevice = FileDevice;
+ if (pThis->hFileDevice != NIL_RTFILE)
+ RTFileClose(pThis->hFileDevice);
+ pThis->hFileDevice = hFileDevice;
#endif /* !RT_OS_DARWIN */
return VINF_SUCCESS;
}
@@ -1170,24 +1177,24 @@ static int drvHostBaseGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
* for secondary storage devices.
*/
struct dk_minfo MediaInfo;
- if (ioctl(pThis->FileRawDevice, DKIOCGMEDIAINFO, &MediaInfo) == 0)
+ if (ioctl(RTFileToNative(pThis->hFileRawDevice), DKIOCGMEDIAINFO, &MediaInfo) == 0)
{
*pcb = MediaInfo.dki_capacity * (uint64_t)MediaInfo.dki_lbsize;
return VINF_SUCCESS;
}
- return RTFileSeek(pThis->FileDevice, 0, RTFILE_SEEK_END, pcb);
+ return RTFileSeek(pThis->hFileDevice, 0, RTFILE_SEEK_END, pcb);
#elif defined(RT_OS_WINDOWS)
/* use NT api, retry a few times if the media is being verified. */
IO_STATUS_BLOCK IoStatusBlock = {0};
FILE_FS_SIZE_INFORMATION FsSize= {0};
- NTSTATUS rcNt = NtQueryVolumeInformationFile((HANDLE)pThis->FileDevice, &IoStatusBlock,
+ NTSTATUS rcNt = NtQueryVolumeInformationFile((HANDLE)RTFileToNative(pThis->hFileDevice), &IoStatusBlock,
&FsSize, sizeof(FsSize), FileFsSizeInformation);
int cRetries = 5;
while (rcNt == STATUS_VERIFY_REQUIRED && cRetries-- > 0)
{
RTThreadSleep(10);
- rcNt = NtQueryVolumeInformationFile((HANDLE)pThis->FileDevice, &IoStatusBlock,
+ rcNt = NtQueryVolumeInformationFile((HANDLE)RTFileToNative(pThis->hFileDevice), &IoStatusBlock,
&FsSize, sizeof(FsSize), FileFsSizeInformation);
}
if (rcNt >= 0)
@@ -1207,7 +1214,7 @@ static int drvHostBaseGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
LogFlow(("drvHostBaseGetMediaSize: NtQueryVolumeInformationFile -> %#lx\n", rcNt, rc));
return rc;
#else
- return RTFileSeek(pThis->FileDevice, 0, RTFILE_SEEK_END, pcb);
+ return RTFileSeek(pThis->hFileDevice, 0, RTFILE_SEEK_END, pcb);
#endif
}
@@ -1340,7 +1347,7 @@ DECLCALLBACK(int) DRVHostBaseScsiCmd(PDRVHOSTBASE pThis, const uint8_t *pbCmd, s
{
pDeviceCCB->ccb_h.func_code = XPT_GDEV_TYPE;
- rcBSD = ioctl(pThis->FileDevice, CAMIOCOMMAND, pDeviceCCB);
+ rcBSD = ioctl(RTFileToNative(pThis->hFileDevice), CAMIOCOMMAND, pDeviceCCB);
if (!rcBSD)
{
uint32_t cbCopy = cbBuf < sizeof(struct scsi_inquiry_data)
@@ -1375,7 +1382,7 @@ DECLCALLBACK(int) DRVHostBaseScsiCmd(PDRVHOSTBASE pThis, const uint8_t *pbCmd, s
cTimeoutMillies ? cTimeoutMillies : 30000/* timeout */);
/* Send command */
- rcBSD = ioctl(pThis->FileDevice, CAMIOCOMMAND, pDeviceCCB);
+ rcBSD = ioctl(RTFileToNative(pThis->hFileDevice), CAMIOCOMMAND, pDeviceCCB);
if (!rcBSD)
{
switch (pDeviceCCB->ccb_h.status & CAM_STATUS_MASK)
@@ -1715,7 +1722,7 @@ DECLCALLBACK(void) DRVHostBaseDestruct(PPDMDRVINS pDrvIns)
#else /** @todo Check if the other guys can mix pfnDoLock with scsi passthru.
* (We're currently not unlocking the device after use. See todo in DevATA.cpp.) */
if ( pThis->fLocked
- && pThis->FileDevice != NIL_RTFILE
+ && pThis->hFileDevice != NIL_RTFILE
#endif
&& pThis->pfnDoLock)
{
@@ -1785,20 +1792,20 @@ DECLCALLBACK(void) DRVHostBaseDestruct(PPDMDRVINS pDrvIns)
pThis->pDASession = NULL;
}
#else
- if (pThis->FileDevice != NIL_RTFILE)
+ if (pThis->hFileDevice != NIL_RTFILE)
{
- int rc = RTFileClose(pThis->FileDevice);
+ int rc = RTFileClose(pThis->hFileDevice);
AssertRC(rc);
- pThis->FileDevice = NIL_RTFILE;
+ pThis->hFileDevice = NIL_RTFILE;
}
#endif
#ifdef RT_OS_SOLARIS
- if (pThis->FileRawDevice != NIL_RTFILE)
+ if (pThis->hFileRawDevice != NIL_RTFILE)
{
- int rc = RTFileClose(pThis->FileRawDevice);
+ int rc = RTFileClose(pThis->hFileRawDevice);
AssertRC(rc);
- pThis->FileRawDevice = NIL_RTFILE;
+ pThis->hFileRawDevice = NIL_RTFILE;
}
if (pThis->pszRawDeviceOpen)
@@ -1863,10 +1870,10 @@ int DRVHostBaseInitData(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, PDMBLOCKTYPE enmType
pThis->pDADisk = NULL;
pThis->pDASession = NULL;
#else
- pThis->FileDevice = NIL_RTFILE;
+ pThis->hFileDevice = NIL_RTFILE;
#endif
#ifdef RT_OS_SOLARIS
- pThis->FileRawDevice = NIL_RTFILE;
+ pThis->hFileRawDevice = NIL_RTFILE;
#endif
pThis->enmType = enmType;
//pThis->cErrors = 0;
@@ -2110,10 +2117,10 @@ int DRVHostBaseInitFinish(PDRVHOSTBASE pThis)
if ( RTPathExists(pszDevice)
&& RT_SUCCESS(RTPathReal(pszDevice, szPathReal, sizeof(szPathReal))))
pszDevice = szPathReal;
- pThis->FileDevice = NIL_RTFILE;
+ pThis->hFileDevice = NIL_RTFILE;
#endif
#ifdef RT_OS_SOLARIS
- pThis->FileRawDevice = NIL_RTFILE;
+ pThis->hFileRawDevice = NIL_RTFILE;
#endif
/*
diff --git a/src/VBox/Devices/Storage/DrvHostBase.h b/src/VBox/Devices/Storage/DrvHostBase.h
index fb600be1d..e74442fbd 100644
--- a/src/VBox/Devices/Storage/DrvHostBase.h
+++ b/src/VBox/Devices/Storage/DrvHostBase.h
@@ -1,4 +1,4 @@
-/* $Id: DrvHostBase.h $ */
+/* $Id: DrvHostBase.h 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* DrvHostBase - Host base drive access driver.
*/
@@ -82,11 +82,11 @@ typedef struct DRVHOSTBASE
uint64_t volatile cbSize;
#if !defined(RT_OS_DARWIN)
/** The filehandle of the device. */
- RTFILE FileDevice;
+ RTFILE hFileDevice;
#endif
#ifdef RT_OS_SOLARIS
/** The raw filehandle of the device. */
- RTFILE FileRawDevice;
+ RTFILE hFileRawDevice;
#endif
/** Handle of the poller thread. */
diff --git a/src/VBox/Devices/Storage/DrvHostDVD.cpp b/src/VBox/Devices/Storage/DrvHostDVD.cpp
index d95e1c597..0767fa16d 100644
--- a/src/VBox/Devices/Storage/DrvHostDVD.cpp
+++ b/src/VBox/Devices/Storage/DrvHostDVD.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvHostDVD.cpp $ */
+/* $Id: DrvHostDVD.cpp 37601 2011-06-22 22:11:50Z vboxsync $ */
/** @file
* DrvHostDVD - Host DVD block driver.
*/
@@ -155,7 +155,7 @@ static DECLCALLBACK(int) drvHostDvdUnmount(PPDMIMOUNT pInterface, bool fForce, b
rc = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMBLOCKTXDIR_NONE, NULL, NULL, NULL, 0, 0);
#elif defined(RT_OS_LINUX)
- rc = ioctl(pThis->FileDevice, CDROMEJECT, 0);
+ rc = ioctl(RTFileToNative(pThis->hFileDevice), CDROMEJECT, 0);
if (rc < 0)
{
if (errno == EBUSY)
@@ -167,7 +167,7 @@ static DECLCALLBACK(int) drvHostDvdUnmount(PPDMIMOUNT pInterface, bool fForce, b
}
#elif defined(RT_OS_SOLARIS)
- rc = ioctl(pThis->FileRawDevice, DKIOCEJECT, 0);
+ rc = ioctl(RTFileToNative(pThis->hFileRawDevice), DKIOCEJECT, 0);
if (rc < 0)
{
if (errno == EBUSY)
@@ -181,14 +181,14 @@ static DECLCALLBACK(int) drvHostDvdUnmount(PPDMIMOUNT pInterface, bool fForce, b
}
#elif defined(RT_OS_WINDOWS)
- RTFILE FileDevice = pThis->FileDevice;
- if (FileDevice == NIL_RTFILE) /* obsolete crap */
- rc = RTFileOpen(&FileDevice, pThis->pszDeviceOpen, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ RTFILE hFileDevice = pThis->hFileDevice;
+ if (hFileDevice == NIL_RTFILE) /* obsolete crap */
+ rc = RTFileOpen(&hFileDevice, pThis->pszDeviceOpen, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (RT_SUCCESS(rc))
{
/* do ioctl */
DWORD cbReturned;
- if (DeviceIoControl((HANDLE)FileDevice, IOCTL_STORAGE_EJECT_MEDIA,
+ if (DeviceIoControl((HANDLE)RTFileToNative(hFileDevice), IOCTL_STORAGE_EJECT_MEDIA,
NULL, 0,
NULL, 0, &cbReturned,
NULL))
@@ -197,8 +197,8 @@ static DECLCALLBACK(int) drvHostDvdUnmount(PPDMIMOUNT pInterface, bool fForce, b
rc = RTErrConvertFromWin32(GetLastError());
/* clean up handle */
- if (FileDevice != pThis->FileDevice)
- RTFileClose(FileDevice);
+ if (hFileDevice != pThis->hFileDevice)
+ RTFileClose(hFileDevice);
}
else
AssertMsgFailed(("Failed to open '%s' for ejecting this tray.\n", rc));
@@ -245,7 +245,7 @@ static DECLCALLBACK(int) drvHostDvdDoLock(PDRVHOSTBASE pThis, bool fLock)
int rc = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMBLOCKTXDIR_NONE, NULL, NULL, NULL, 0, 0);
#elif defined(RT_OS_LINUX)
- int rc = ioctl(pThis->FileDevice, CDROM_LOCKDOOR, (int)fLock);
+ int rc = ioctl(RTFileToNative(pThis->hFileDevice), CDROM_LOCKDOOR, (int)fLock);
if (rc < 0)
{
if (errno == EBUSY)
@@ -257,7 +257,7 @@ static DECLCALLBACK(int) drvHostDvdDoLock(PDRVHOSTBASE pThis, bool fLock)
}
#elif defined(RT_OS_SOLARIS)
- int rc = ioctl(pThis->FileRawDevice, fLock ? DKIOCLOCK : DKIOCUNLOCK, 0);
+ int rc = ioctl(RTFileToNative(pThis->hFileRawDevice), fLock ? DKIOCLOCK : DKIOCUNLOCK, 0);
if (rc < 0)
{
if (errno == EBUSY)
@@ -273,7 +273,7 @@ static DECLCALLBACK(int) drvHostDvdDoLock(PDRVHOSTBASE pThis, bool fLock)
PREVENT_MEDIA_REMOVAL PreventMediaRemoval = {fLock};
DWORD cbReturned;
int rc;
- if (DeviceIoControl((HANDLE)pThis->FileDevice, IOCTL_STORAGE_MEDIA_REMOVAL,
+ if (DeviceIoControl((HANDLE)RTFileToNative(pThis->hFileDevice), IOCTL_STORAGE_MEDIA_REMOVAL,
&PreventMediaRemoval, sizeof(PreventMediaRemoval),
NULL, 0, &cbReturned,
NULL))
@@ -308,8 +308,8 @@ static int drvHostDvdGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
* Query the media size.
*/
/* Clear the media-changed-since-last-call-thingy just to be on the safe side. */
- ioctl(pThis->FileDevice, CDROM_MEDIA_CHANGED, CDSL_CURRENT);
- return RTFileSeek(pThis->FileDevice, 0, RTFILE_SEEK_END, pcb);
+ ioctl(RTFileToNative(pThis->hFileDevice), CDROM_MEDIA_CHANGED, CDSL_CURRENT);
+ return RTFileSeek(pThis->hFileDevice, 0, RTFILE_SEEK_END, pcb);
}
#endif /* RT_OS_LINUX */
@@ -356,7 +356,7 @@ DECLCALLBACK(int) drvHostDvdPoll(PDRVHOSTBASE pThis)
}
#elif defined(RT_OS_LINUX)
- bool fMediaPresent = ioctl(pThis->FileDevice, CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK;
+ bool fMediaPresent = ioctl(RTFileToNative(pThis->hFileDevice), CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK;
#elif defined(RT_OS_SOLARIS)
bool fMediaPresent = false;
@@ -365,7 +365,7 @@ DECLCALLBACK(int) drvHostDvdPoll(PDRVHOSTBASE pThis)
/* Need to pass the previous state and DKIO_NONE for the first time. */
static dkio_state s_DeviceState = DKIO_NONE;
dkio_state PreviousState = s_DeviceState;
- int rc2 = ioctl(pThis->FileRawDevice, DKIOCSTATE, &s_DeviceState);
+ int rc2 = ioctl(RTFileToNative(pThis->hFileRawDevice), DKIOCSTATE, &s_DeviceState);
if (rc2 == 0)
{
fMediaPresent = (s_DeviceState == DKIO_INSERTED);
@@ -397,7 +397,7 @@ DECLCALLBACK(int) drvHostDvdPoll(PDRVHOSTBASE pThis)
#if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
/* taken care of above. */
#elif defined(RT_OS_LINUX)
- bool fMediaChanged = ioctl(pThis->FileDevice, CDROM_MEDIA_CHANGED, CDSL_CURRENT) == 1;
+ bool fMediaChanged = ioctl(RTFileToNative(pThis->hFileDevice), CDROM_MEDIA_CHANGED, CDSL_CURRENT) == 1;
#else
# error "Unsupported platform."
#endif
@@ -483,7 +483,7 @@ static int drvHostDvdSendCmd(PPDMIBLOCK pInterface, const uint8_t *pbCmd,
cgc.data_direction = direction;
cgc.quiet = false;
cgc.timeout = cTimeoutMillies;
- rc = ioctl(pThis->FileDevice, CDROM_SEND_PACKET, &cgc);
+ rc = ioctl(RTFileToNative(pThis->hFileDevice), CDROM_SEND_PACKET, &cgc);
if (rc < 0)
{
if (errno == EBUSY)
@@ -559,7 +559,7 @@ static int drvHostDvdSendCmd(PPDMIBLOCK pInterface, const uint8_t *pbCmd,
uid_t effUserID = geteuid();
solarisEnterRootMode(&effUserID); /** @todo check return code when this really works. */
#endif
- rc = ioctl(pThis->FileRawDevice, USCSICMD, &usc);
+ rc = ioctl(RTFileToNative(pThis->hFileRawDevice), USCSICMD, &usc);
#ifdef VBOX_WITH_SUID_WRAPPER
solarisExitRootMode(&effUserID);
#endif
@@ -619,7 +619,7 @@ static int drvHostDvdSendCmd(PPDMIBLOCK pInterface, const uint8_t *pbCmd,
Assert(cbSense <= sizeof(Req.aSense));
Req.spt.SenseInfoLength = (UCHAR)RT_MIN(sizeof(Req.aSense), cbSense);
Req.spt.SenseInfoOffset = RT_OFFSETOF(struct _REQ, aSense);
- if (DeviceIoControl((HANDLE)pThis->FileDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT,
+ if (DeviceIoControl((HANDLE)RTFileToNative(pThis->hFileDevice), IOCTL_SCSI_PASS_THROUGH_DIRECT,
&Req, sizeof(Req), &Req, sizeof(Req), &cbReturned, NULL))
{
if (cbReturned > RT_OFFSETOF(struct _REQ, aSense))
diff --git a/src/VBox/Devices/Storage/DrvHostFloppy.cpp b/src/VBox/Devices/Storage/DrvHostFloppy.cpp
index da5723093..3f6620865 100644
--- a/src/VBox/Devices/Storage/DrvHostFloppy.cpp
+++ b/src/VBox/Devices/Storage/DrvHostFloppy.cpp
@@ -72,7 +72,7 @@ typedef struct DRVHOSTFLOPPY
*/
static DECLCALLBACK(int) drvHostFloppyGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
{
- int rc = ioctl(pThis->FileDevice, FDFLUSH);
+ int rc = ioctl(RTFileToNative(pThis->hFileDevice), FDFLUSH);
if (rc)
{
rc = RTErrConvertFromErrno (errno);
@@ -81,7 +81,7 @@ static DECLCALLBACK(int) drvHostFloppyGetMediaSize(PDRVHOSTBASE pThis, uint64_t
}
floppy_drive_struct DrvStat;
- rc = ioctl(pThis->FileDevice, FDGETDRVSTAT, &DrvStat);
+ rc = ioctl(RTFileToNative(pThis->hFileDevice), FDGETDRVSTAT, &DrvStat);
if (rc)
{
rc = RTErrConvertFromErrno(errno);
@@ -90,7 +90,7 @@ static DECLCALLBACK(int) drvHostFloppyGetMediaSize(PDRVHOSTBASE pThis, uint64_t
}
pThis->fReadOnly = !(DrvStat.flags & FD_DISK_WRITABLE);
- return RTFileSeek(pThis->FileDevice, 0, RTFILE_SEEK_END, pcb);
+ return RTFileSeek(pThis->hFileDevice, 0, RTFILE_SEEK_END, pcb);
}
#endif /* RT_OS_LINUX */
@@ -107,7 +107,7 @@ static DECLCALLBACK(int) drvHostFloppyPoll(PDRVHOSTBASE pThis)
{
PDRVHOSTFLOPPY pThisFloppy = (PDRVHOSTFLOPPY)pThis;
floppy_drive_struct DrvStat;
- int rc = ioctl(pThis->FileDevice, FDPOLLDRVSTAT, &DrvStat);
+ int rc = ioctl(RTFileToNative(pThis->hFileDevice), FDPOLLDRVSTAT, &DrvStat);
if (rc)
return RTErrConvertFromErrno(errno);
diff --git a/src/VBox/Devices/Storage/DrvMediaISO.cpp b/src/VBox/Devices/Storage/DrvMediaISO.cpp
index 2149abbc4..325c3e12d 100644
--- a/src/VBox/Devices/Storage/DrvMediaISO.cpp
+++ b/src/VBox/Devices/Storage/DrvMediaISO.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvMediaISO.cpp $ */
+/* $Id: DrvMediaISO.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VBox storage devices: ISO image media driver
*/
@@ -59,7 +59,7 @@ typedef struct DRVMEDIAISO
/** Pointer to the filename. (Freed by MM) */
char *pszFilename;
/** File handle of the ISO file. */
- RTFILE File;
+ RTFILE hFile;
} DRVMEDIAISO, *PDRVMEDIAISO;
@@ -73,7 +73,7 @@ static DECLCALLBACK(uint64_t) drvMediaISOGetSize(PPDMIMEDIA pInterface)
LogFlow(("drvMediaISOGetSize: '%s'\n", pThis->pszFilename));
uint64_t cbFile;
- int rc = RTFileGetSize(pThis->File, &cbFile);
+ int rc = RTFileGetSize(pThis->hFile, &cbFile);
if (RT_SUCCESS(rc))
{
LogFlow(("drvMediaISOGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
@@ -123,29 +123,21 @@ static DECLCALLBACK(int) drvMediaISORead(PPDMIMEDIA pInterface, uint64_t off, vo
PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
LogFlow(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
- Assert(pThis->File);
+ Assert(pThis->hFile != NIL_RTFILE);
Assert(pvBuf);
/*
* Seek to the position and read.
*/
- int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
+ int rc = RTFileReadAt(pThis->hFile, off, pvBuf, cbRead, NULL);
if (RT_SUCCESS(rc))
- {
- rc = RTFileRead(pThis->File, pvBuf, cbRead, NULL);
- if (RT_SUCCESS(rc))
- {
- Log2(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
- "%16.*Rhxd\n",
- off, pvBuf, cbRead, pThis->pszFilename,
- cbRead, pvBuf));
- }
- else
- AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
- pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
- }
+ Log2(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
+ "%16.*Rhxd\n",
+ off, pvBuf, cbRead, pThis->pszFilename,
+ cbRead, pvBuf));
else
- AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
+ AssertMsgFailed(("RTFileReadAt(%RTfile, %#llx, %p, %#x) -> %Rrc ('%s')\n",
+ pThis->hFile, off, pvBuf, cbRead, rc, pThis->pszFilename));
LogFlow(("drvMediaISORead: returns %Rrc\n", rc));
return rc;
}
@@ -211,13 +203,14 @@ static DECLCALLBACK(void) drvMediaISODestruct(PPDMDRVINS pDrvIns)
LogFlow(("drvMediaISODestruct: '%s'\n", pThis->pszFilename));
PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
- if (pThis->File != NIL_RTFILE)
- {
- RTFileClose(pThis->File);
- pThis->File = NIL_RTFILE;
- }
+ RTFileClose(pThis->hFile);
+ pThis->hFile = NIL_RTFILE;
+
if (pThis->pszFilename)
+ {
MMR3HeapFree(pThis->pszFilename);
+ pThis->pszFilename = NULL;
+ }
}
@@ -235,7 +228,7 @@ static DECLCALLBACK(int) drvMediaISOConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg
* Init the static parts.
*/
pThis->pDrvIns = pDrvIns;
- pThis->File = NIL_RTFILE;
+ pThis->hFile = NIL_RTFILE;
/* IBase */
pDrvIns->IBase.pfnQueryInterface = drvMediaISOQueryInterface;
/* IMedia */
@@ -264,8 +257,7 @@ static DECLCALLBACK(int) drvMediaISOConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg
/*
* Open the image.
*/
- rc = RTFileOpen(&pThis->File, pszName,
- RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+ rc = RTFileOpen(&pThis->hFile, pszName, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
if (RT_SUCCESS(rc))
{
LogFlow(("drvMediaISOConstruct: ISO image '%s' opened successfully.\n", pszName));
diff --git a/src/VBox/Devices/Storage/DrvRawImage.cpp b/src/VBox/Devices/Storage/DrvRawImage.cpp
index 4aba8d668..7f20558d5 100644
--- a/src/VBox/Devices/Storage/DrvRawImage.cpp
+++ b/src/VBox/Devices/Storage/DrvRawImage.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvRawImage.cpp $ */
+/* $Id: DrvRawImage.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VBox storage devices: Raw image driver
*/
@@ -60,7 +60,7 @@ typedef struct DRVRAWIMAGE
/** Pointer to the filename. (Freed by MM) */
char *pszFilename;
/** File handle of the raw image file. */
- RTFILE File;
+ RTFILE hFile;
/** True if the image is operating in readonly mode. */
bool fReadOnly;
} DRVRAWIMAGE, *PDRVRAWIMAGE;
@@ -76,7 +76,7 @@ static DECLCALLBACK(uint64_t) drvRawImageGetSize(PPDMIMEDIA pInterface)
LogFlow(("drvRawImageGetSize: '%s'\n", pThis->pszFilename));
uint64_t cbFile;
- int rc = RTFileGetSize(pThis->File, &cbFile);
+ int rc = RTFileGetSize(pThis->hFile, &cbFile);
if (RT_SUCCESS(rc))
{
LogFlow(("drvRawImageGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
@@ -126,16 +126,16 @@ static DECLCALLBACK(int) drvRawImageRead(PPDMIMEDIA pInterface, uint64_t off, vo
PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
LogFlow(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
- Assert(pThis->File);
+ Assert(pThis->hFile != NIL_RTFILE);
Assert(pvBuf);
/*
* Seek to the position and read.
*/
- int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
+ int rc = RTFileSeek(pThis->hFile, off, RTFILE_SEEK_BEGIN, NULL);
if (RT_SUCCESS(rc))
{
- rc = RTFileRead(pThis->File, pvBuf, cbRead, NULL);
+ rc = RTFileRead(pThis->hFile, pvBuf, cbRead, NULL);
if (RT_SUCCESS(rc))
{
Log2(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
@@ -144,11 +144,11 @@ static DECLCALLBACK(int) drvRawImageRead(PPDMIMEDIA pInterface, uint64_t off, vo
cbRead, pvBuf));
}
else
- AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
- pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
+ AssertMsgFailed(("RTFileRead(%RTfile, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
+ pThis->hFile, pvBuf, cbRead, rc, off, pThis->pszFilename));
}
else
- AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
+ AssertMsgFailed(("RTFileSeek(%RTfile,%#llx,) -> %Rrc\n", pThis->hFile, off, rc));
LogFlow(("drvRawImageRead: returns %Rrc\n", rc));
return rc;
}
@@ -160,16 +160,16 @@ static DECLCALLBACK(int) drvRawImageWrite(PPDMIMEDIA pInterface, uint64_t off, c
PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
LogFlow(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n", off, pvBuf, cbWrite, pThis->pszFilename));
- Assert(pThis->File);
+ Assert(pThis->hFile != NIL_RTFILE);
Assert(pvBuf);
/*
* Seek to the position and write.
*/
- int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
+ int rc = RTFileSeek(pThis->hFile, off, RTFILE_SEEK_BEGIN, NULL);
if (RT_SUCCESS(rc))
{
- rc = RTFileWrite(pThis->File, pvBuf, cbWrite, NULL);
+ rc = RTFileWrite(pThis->hFile, pvBuf, cbWrite, NULL);
if (RT_SUCCESS(rc))
{
Log2(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n"
@@ -178,11 +178,11 @@ static DECLCALLBACK(int) drvRawImageWrite(PPDMIMEDIA pInterface, uint64_t off, c
cbWrite, pvBuf));
}
else
- AssertMsgFailed(("RTFileWrite(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
- pThis->File, pvBuf, cbWrite, rc, off, pThis->pszFilename));
+ AssertMsgFailed(("RTFileWrite(%RTfile, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
+ pThis->hFile, pvBuf, cbWrite, rc, off, pThis->pszFilename));
}
else
- AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
+ AssertMsgFailed(("RTFileSeek(%RTfile,%#llx,) -> %Rrc\n", pThis->hFile, off, rc));
LogFlow(("drvRawImageWrite: returns %Rrc\n", rc));
return rc;
}
@@ -194,8 +194,8 @@ static DECLCALLBACK(int) drvRawImageFlush(PPDMIMEDIA pInterface)
PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
LogFlow(("drvRawImageFlush: (%s)\n", pThis->pszFilename));
- Assert(pThis->File != NIL_RTFILE);
- int rc = RTFileFlush(pThis->File);
+ Assert(pThis->hFile != NIL_RTFILE);
+ int rc = RTFileFlush(pThis->hFile);
LogFlow(("drvRawImageFlush: returns %Rrc\n", rc));
return rc;
}
@@ -248,13 +248,14 @@ static DECLCALLBACK(void) drvRawImageDestruct(PPDMDRVINS pDrvIns)
LogFlow(("drvRawImageDestruct: '%s'\n", pThis->pszFilename));
PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
- if (pThis->File != NIL_RTFILE)
- {
- RTFileClose(pThis->File);
- pThis->File = NIL_RTFILE;
- }
+ RTFileClose(pThis->hFile);
+ pThis->hFile = NIL_RTFILE;
+
if (pThis->pszFilename)
+ {
MMR3HeapFree(pThis->pszFilename);
+ pThis->pszFilename = NULL;
+ }
}
@@ -272,7 +273,7 @@ static DECLCALLBACK(int) drvRawImageConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg
* Init the static parts.
*/
pThis->pDrvIns = pDrvIns;
- pThis->File = NIL_RTFILE;
+ pThis->hFile = NIL_RTFILE;
/* IBase */
pDrvIns->IBase.pfnQueryInterface = drvRawImageQueryInterface;
/* IMedia */
@@ -304,8 +305,7 @@ static DECLCALLBACK(int) drvRawImageConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg
/*
* Open the image.
*/
- rc = RTFileOpen(&pThis->File, pszName,
- RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ rc = RTFileOpen(&pThis->hFile, pszName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (RT_SUCCESS(rc))
{
LogFlow(("drvRawImageConstruct: Raw image '%s' opened successfully.\n", pszName));
@@ -314,8 +314,7 @@ static DECLCALLBACK(int) drvRawImageConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg
}
else
{
- rc = RTFileOpen(&pThis->File, pszName,
- RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ rc = RTFileOpen(&pThis->hFile, pszName, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (RT_SUCCESS(rc))
{
LogFlow(("drvRawImageConstruct: Raw image '%s' opened successfully.\n", pszName));
diff --git a/src/VBox/Devices/Storage/DrvSCSI.cpp b/src/VBox/Devices/Storage/DrvSCSI.cpp
index 81de28295..f1ea50cd3 100644
--- a/src/VBox/Devices/Storage/DrvSCSI.cpp
+++ b/src/VBox/Devices/Storage/DrvSCSI.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvSCSI.cpp $ */
+/* $Id: DrvSCSI.cpp 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* VBox storage drivers: Generic SCSI command parser and execution driver
*/
diff --git a/src/VBox/Devices/Storage/DrvSCSIHost.cpp b/src/VBox/Devices/Storage/DrvSCSIHost.cpp
index 4f9535103..1bada3384 100644
--- a/src/VBox/Devices/Storage/DrvSCSIHost.cpp
+++ b/src/VBox/Devices/Storage/DrvSCSIHost.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvSCSIHost.cpp $ */
+/* $Id: DrvSCSIHost.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VBox storage drivers: Host SCSI access driver.
*/
@@ -57,7 +57,7 @@ typedef struct DRVSCSIHOST
/** Path to the device file. */
char *pszDevicePath;
/** Handle to the device. */
- RTFILE DeviceFile;
+ RTFILE hDeviceFile;
/** The dedicated I/O thread. */
PPDMTHREAD pAsyncIOThread;
@@ -301,8 +301,8 @@ static int drvscsihostProcessRequestOne(PDRVSCSIHOST pThis, PPDMSCSIREQUEST pReq
ScsiIoReq.timeout = UINT_MAX;
ScsiIoReq.flags |= SG_FLAG_DIRECT_IO;
- /** Issue command. */
- rc = ioctl(pThis->DeviceFile, SG_IO, &ScsiIoReq);
+ /* Issue command. */
+ rc = ioctl(RTFileToNative(pThis->hDeviceFile), SG_IO, &ScsiIoReq);
if (rc < 0)
{
AssertMsgFailed(("Ioctl failed with rc=%d\n", rc));
@@ -419,11 +419,14 @@ static DECLCALLBACK(void) drvscsihostDestruct(PPDMDRVINS pDrvIns)
PDRVSCSIHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSIHOST);
PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
- if (pThis->DeviceFile != NIL_RTFILE)
- RTFileClose(pThis->DeviceFile);
+ RTFileClose(pThis->hDeviceFile);
+ pThis->hDeviceFile = NIL_RTFILE;
if (pThis->pszDevicePath)
+ {
MMR3HeapFree(pThis->pszDevicePath);
+ pThis->pszDevicePath = NULL;
+ }
if (pThis->pQueueRequests)
{
@@ -456,8 +459,8 @@ static DECLCALLBACK(int) drvscsihostConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg
*/
pDrvIns->IBase.pfnQueryInterface = drvscsihostQueryInterface;
pThis->ISCSIConnector.pfnSCSIRequestSend = drvscsihostRequestSend;
- pThis->pDrvIns = pDrvIns;
- pThis->DeviceFile = NIL_RTFILE;
+ pThis->pDrvIns = pDrvIns;
+ pThis->hDeviceFile = NIL_RTFILE;
/* Query the SCSI port interface above. */
pThis->pDevScsiPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMISCSIPORT);
@@ -473,7 +476,7 @@ static DECLCALLBACK(int) drvscsihostConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg
return PDMDRV_SET_ERROR(pDrvIns, rc,
N_("Configuration error: Failed to get the \"DevicePath\" value"));
- rc = RTFileOpen(&pThis->DeviceFile, pThis->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ rc = RTFileOpen(&pThis->hDeviceFile, pThis->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (RT_FAILURE(rc))
return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
N_("DrvSCSIHost#%d: Failed to open device '%s'"), pDrvIns->iInstance, pThis->pszDevicePath);
diff --git a/src/VBox/Devices/Storage/DrvVD.cpp b/src/VBox/Devices/Storage/DrvVD.cpp
index 2b906cb24..e19b8a920 100644
--- a/src/VBox/Devices/Storage/DrvVD.cpp
+++ b/src/VBox/Devices/Storage/DrvVD.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvVD.cpp $ */
+/* $Id: DrvVD.cpp 37641 2011-06-26 17:16:35Z vboxsync $ */
/** @file
* DrvVD - Generic VBox disk media driver.
*/
@@ -190,6 +190,8 @@ typedef struct VBOXDISK
uint8_t *pbData;
/** Bandwidth group the disk is assigned to. */
char *pszBwGroup;
+ /** Flag whether async I/O using the host cache is enabled. */
+ bool fAsyncIoWithHostCache;
/** I/O interface for a cache image. */
VDINTERFACE VDIIOCache;
@@ -318,7 +320,7 @@ static DECLCALLBACK(void) drvvdAsyncTaskCompleted(PPDMDRVINS pDrvIns, void *pvTe
PVBOXDISK pThis = PDMINS_2_DATA(pDrvIns, PVBOXDISK);
PDRVVDSTORAGEBACKEND pStorageBackend = (PDRVVDSTORAGEBACKEND)pvTemplateUser;
- LogFlowFunc(("pDrvIns=%#p pvTemplateUser=%#p pvUser=%#p rcReq\n",
+ LogFlowFunc(("pDrvIns=%#p pvTemplateUser=%#p pvUser=%#p rcReq=%d\n",
pDrvIns, pvTemplateUser, pvUser, rcReq));
if (pStorageBackend->fSyncIoPending)
@@ -371,6 +373,8 @@ static DECLCALLBACK(int) drvvdAsyncIOOpen(void *pvUser, const char *pszLocation,
fFlags |= PDMACEP_FILE_FLAGS_DONT_LOCK;
}
+ if (pThis->fAsyncIoWithHostCache)
+ fFlags |= PDMACEP_FILE_FLAGS_HOST_CACHE_ENABLED;
rc = PDMR3AsyncCompletionEpCreateForFile(&pStorageBackend->pEndpoint,
pszLocation, fFlags,
@@ -2379,6 +2383,16 @@ static DECLCALLBACK(int) drvvdConstruct(PPDMDRVINS pDrvIns,
#endif /* VBOX_WITH_INIP */
}
+ /*
+ * The image has a bandwidth group but the host cache is enabled.
+ * Use the async I/O framework but tell it to enable the host cache.
+ */
+ if (!fUseNewIo && pThis->pszBwGroup)
+ {
+ pThis->fAsyncIoWithHostCache = true;
+ fUseNewIo = true;
+ }
+
/** @todo quick hack to work around problems in the async I/O
* implementation (rw semaphore thread ownership problem)
* while a merge is running. Remove once this is fixed. */
diff --git a/src/VBox/Devices/Storage/UsbMsd.cpp b/src/VBox/Devices/Storage/UsbMsd.cpp
index fe040ea7f..27c680e85 100644
--- a/src/VBox/Devices/Storage/UsbMsd.cpp
+++ b/src/VBox/Devices/Storage/UsbMsd.cpp
@@ -1,4 +1,4 @@
-/* $Id: UsbMsd.cpp $ */
+/* $Id: UsbMsd.cpp 37795 2011-07-06 10:28:24Z vboxsync $ */
/** @file
* UsbMSD - USB Mass Storage Device Emulation.
*/
@@ -1578,7 +1578,7 @@ static DECLCALLBACK(int) usbMsdConstruct(PPDMUSBINS pUsbIns, int iInstance, PCFG
/*
* Attach the SCSI driver.
*/
- rc = pUsbIns->pHlpR3->pfnDriverAttach(pUsbIns, 0 /*iLun*/, &pThis->Lun0.IBase, &pThis->Lun0.pIBase, "SCSI Port");
+ rc = PDMUsbHlpDriverAttach(pUsbIns, 0 /*iLun*/, &pThis->Lun0.IBase, &pThis->Lun0.pIBase, "SCSI Port");
if (RT_FAILURE(rc))
return PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS, N_("MSD failed to attach SCSI driver"));
pThis->Lun0.pIScsiConnector = PDMIBASE_QUERY_INTERFACE(pThis->Lun0.pIBase, PDMISCSICONNECTOR);
diff --git a/src/VBox/Devices/Storage/VBoxSCSI.cpp b/src/VBox/Devices/Storage/VBoxSCSI.cpp
index 80361100e..b96788779 100644
--- a/src/VBox/Devices/Storage/VBoxSCSI.cpp
+++ b/src/VBox/Devices/Storage/VBoxSCSI.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxSCSI.cpp $ */
+/* $Id: VBoxSCSI.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
*
* VBox storage devices:
diff --git a/src/VBox/Devices/Storage/VBoxSCSI.h b/src/VBox/Devices/Storage/VBoxSCSI.h
index c30749a5e..26366d197 100644
--- a/src/VBox/Devices/Storage/VBoxSCSI.h
+++ b/src/VBox/Devices/Storage/VBoxSCSI.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxSCSI.h $ */
+/* $Id: VBoxSCSI.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
*
* VBox storage devices:
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
index d912bf57f..78887ca4e 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
@@ -1,4 +1,4 @@
-/* $Id: VSCSIDevice.cpp $ */
+/* $Id: VSCSIDevice.cpp 32983 2010-10-07 15:14:54Z vboxsync $ */
/** @file
* Virtual SCSI driver: Device handling
*/
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSIInline.h b/src/VBox/Devices/Storage/VSCSI/VSCSIInline.h
index d897a21eb..67bcc6458 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSIInline.h
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSIInline.h
@@ -1,4 +1,4 @@
-/* $Id: VSCSIInline.h $ */
+/* $Id: VSCSIInline.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Virtual SCSI driver: Inline helpers
*/
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h b/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h
index 0b0d8b157..61dc71dec 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h
@@ -1,4 +1,4 @@
-/* $Id: VSCSIInternal.h $ */
+/* $Id: VSCSIInternal.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Virtual SCSI driver: Internal defines
*/
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSIIoReq.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSIIoReq.cpp
index 83888eecd..64f6a31f9 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSIIoReq.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSIIoReq.cpp
@@ -1,4 +1,4 @@
-/* $Id: VSCSIIoReq.cpp $ */
+/* $Id: VSCSIIoReq.cpp 32983 2010-10-07 15:14:54Z vboxsync $ */
/** @file
* Virtual SCSI driver: I/O request handling.
*/
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSILun.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSILun.cpp
index 5758a99bc..86911cd85 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSILun.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSILun.cpp
@@ -1,4 +1,4 @@
-/* $Id: VSCSILun.cpp $ */
+/* $Id: VSCSILun.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Virtual SCSI driver: LUN handling
*/
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp
index 102f76593..4d2cc2d5e 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp
@@ -1,4 +1,4 @@
-/* $Id: VSCSILunSbc.cpp $ */
+/* $Id: VSCSILunSbc.cpp 32983 2010-10-07 15:14:54Z vboxsync $ */
/** @file
* Virtual SCSI driver: SBC LUN implementation (hard disks)
*/
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSISense.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSISense.cpp
index 6c981dca5..48a84d986 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSISense.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSISense.cpp
@@ -1,4 +1,4 @@
-/* $Id: VSCSISense.cpp $ */
+/* $Id: VSCSISense.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Virtual SCSI driver: Sense handling
*/
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSISgBuf.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSISgBuf.cpp
index 8acd2ded7..820d93617 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSISgBuf.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSISgBuf.cpp
@@ -1,4 +1,4 @@
-/* $Id: VSCSISgBuf.cpp $ */
+/* $Id: VSCSISgBuf.cpp 35062 2010-12-14 11:05:57Z vboxsync $ */
/** @file
* Virtual SCSI driver: S/G list handling
*/
diff --git a/src/VBox/Devices/Storage/fdc.c b/src/VBox/Devices/Storage/fdc.c
index ea92c4108..3bd0ce43d 100644
--- a/src/VBox/Devices/Storage/fdc.c
+++ b/src/VBox/Devices/Storage/fdc.c
@@ -1,4 +1,4 @@
-/* $Id: fdc.c $ */
+/* $Id: fdc.c 37478 2011-06-15 18:49:40Z vboxsync $ */
/** @file
* VBox storage devices: Floppy disk controller
*/
@@ -188,6 +188,8 @@ typedef struct fdrive_t {
uint8_t media_rate; /* Data rate of medium */
} fdrive_t;
+#define NUM_SIDES(drv) (drv->flags & FDISK_DBL_SIDES ? 2 : 1)
+
static void fd_init(fdrive_t *drv)
{
/* Drive */
@@ -199,15 +201,15 @@ static void fd_init(fdrive_t *drv)
}
static int fd_sector_calc(uint8_t head, uint8_t track, uint8_t sect,
- uint8_t last_sect)
+ uint8_t last_sect, uint8_t num_sides)
{
- return (((track * 2) + head) * last_sect) + sect - 1; /* sect >= 1 */
+ return (((track * num_sides) + head) * last_sect) + sect - 1; /* sect >= 1 */
}
/* Returns current position, in sectors, for given drive */
static int fd_sector(fdrive_t *drv)
{
- return fd_sector_calc(drv->head, drv->track, drv->sect, drv->last_sect);
+ return fd_sector_calc(drv->head, drv->track, drv->sect, drv->last_sect, NUM_SIDES(drv));
}
/* Seek to a new position:
@@ -238,7 +240,7 @@ static int fd_seek(fdrive_t *drv, uint8_t head, uint8_t track, uint8_t sect,
drv->max_track, drv->last_sect);
return 3;
}
- sector = fd_sector_calc(head, track, sect, drv->last_sect);
+ sector = fd_sector_calc(head, track, sect, drv->last_sect, NUM_SIDES(drv));
ret = 0;
if (sector != fd_sector(drv)) {
#if 0
@@ -1158,7 +1160,7 @@ static void fdctrl_start_transfer(fdctrl_t *fdctrl, int direction)
ks = fdctrl->fifo[4];
FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",
GET_CUR_DRV(fdctrl), kh, kt, ks,
- fd_sector_calc(kh, kt, ks, cur_drv->last_sect));
+ fd_sector_calc(kh, kt, ks, cur_drv->last_sect, NUM_SIDES(cur_drv)));
switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
case 2:
/* sect too big */
@@ -1569,7 +1571,7 @@ static void fdctrl_format_sector(fdctrl_t *fdctrl)
ks = fdctrl->fifo[8];
FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n",
GET_CUR_DRV(fdctrl), kh, kt, ks,
- fd_sector_calc(kh, kt, ks, cur_drv->last_sect));
+ fd_sector_calc(kh, kt, ks, cur_drv->last_sect, NUM_SIDES(cur_drv)));
switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
case 2:
/* sect too big */
@@ -1636,7 +1638,7 @@ static void fdctrl_handle_lock(fdctrl_t *fdctrl, int direction)
{
fdctrl->lock = (fdctrl->fifo[0] & 0x80) ? 1 : 0;
fdctrl->fifo[0] = fdctrl->lock << 4;
- fdctrl_set_fifo(fdctrl, 1, fdctrl->lock);
+ fdctrl_set_fifo(fdctrl, 1, 0);
}
static void fdctrl_handle_dumpreg(fdctrl_t *fdctrl, int direction)
@@ -1668,12 +1670,12 @@ static void fdctrl_handle_version(fdctrl_t *fdctrl, int direction)
{
/* Controller's version */
fdctrl->fifo[0] = fdctrl->version;
- fdctrl_set_fifo(fdctrl, 1, 1);
+ fdctrl_set_fifo(fdctrl, 1, 0);
}
static void fdctrl_handle_partid(fdctrl_t *fdctrl, int direction)
{
- fdctrl->fifo[0] = 0x41; /* Stepping 1 */
+ fdctrl->fifo[0] = 0x01; /* Stepping 1 */
fdctrl_set_fifo(fdctrl, 1, 0);
}
@@ -1727,7 +1729,7 @@ static void fdctrl_handle_save(fdctrl_t *fdctrl, int direction)
fdctrl->fifo[12] = fdctrl->pwrd;
fdctrl->fifo[13] = 0;
fdctrl->fifo[14] = 0;
- fdctrl_set_fifo(fdctrl, 15, 1);
+ fdctrl_set_fifo(fdctrl, 15, 0);
}
static void fdctrl_handle_readid(fdctrl_t *fdctrl, int direction)
@@ -1882,7 +1884,7 @@ static void fdctrl_handle_powerdown_mode(fdctrl_t *fdctrl, int direction)
{
fdctrl->pwrd = fdctrl->fifo[1];
fdctrl->fifo[0] = fdctrl->fifo[1];
- fdctrl_set_fifo(fdctrl, 1, 1);
+ fdctrl_set_fifo(fdctrl, 1, 0);
}
static void fdctrl_handle_option(fdctrl_t *fdctrl, int direction)
@@ -1901,7 +1903,7 @@ static void fdctrl_handle_drive_specification_command(fdctrl_t *fdctrl, int dire
fdctrl->fifo[0] = fdctrl->fifo[1];
fdctrl->fifo[2] = 0;
fdctrl->fifo[3] = 0;
- fdctrl_set_fifo(fdctrl, 4, 1);
+ fdctrl_set_fifo(fdctrl, 4, 0);
} else {
fdctrl_reset_fifo(fdctrl);
}
@@ -1909,7 +1911,7 @@ static void fdctrl_handle_drive_specification_command(fdctrl_t *fdctrl, int dire
/* ERROR */
fdctrl->fifo[0] = 0x80 |
(cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
- fdctrl_set_fifo(fdctrl, 1, 1);
+ fdctrl_set_fifo(fdctrl, 1, 0);
}
}
@@ -2032,6 +2034,7 @@ static void fdctrl_write_data(fdctrl_t *fdctrl, uint32_t value)
pos = command_to_handler[value & 0xff];
FLOPPY_DPRINTF("%s command\n", handlers[pos].name);
fdctrl->data_len = handlers[pos].parameters + 1;
+ fdctrl->msr |= FD_MSR_CMDBUSY;
}
FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
diff --git a/src/VBox/Devices/Storage/ide.h b/src/VBox/Devices/Storage/ide.h
index d9e839cc1..81b147238 100644
--- a/src/VBox/Devices/Storage/ide.h
+++ b/src/VBox/Devices/Storage/ide.h
@@ -1,10 +1,10 @@
-/* $Id: ide.h $ */
+/* $Id: ide.h 37264 2011-05-30 14:47:02Z vboxsync $ */
/** @file
* VBox storage devices: ATA/ATAPI declarations
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -167,6 +167,13 @@ typedef enum ATACMD
( ((1 << (maxspeed + 1)) - 1) \
| ((((thismode ^ currmode) & 0xf8) == 0) ? 1 << ((currmode & 0x07) + 8) : 0))
+/**
+ * Length of the ATA VPD data (without termination)
+ */
+#define ATA_SERIAL_NUMBER_LENGTH 20
+#define ATA_FIRMWARE_REVISION_LENGTH 8
+#define ATA_MODEL_NUMBER_LENGTH 40
+
/* ATAPI defines */
@@ -178,6 +185,17 @@ typedef enum ATACMD
#define ATAPI_INT_REASON_REL 0x04
#define ATAPI_INT_REASON_TAG_MASK 0xf8
+
+/**
+ * Length of the ATAPI VPD data (without termination)
+ *
+ * @todo move to scsi.h
+ */
+#define ATAPI_INQUIRY_VENDOR_ID_LENGTH 8
+#define ATAPI_INQUIRY_PRODUCT_ID_LENGTH 16
+#define ATAPI_INQUIRY_REVISION_LENGTH 4
+
+
#if defined(DEBUG) && defined(IN_RING3)
const char * ATACmdText(uint8_t uCmd);
#endif
diff --git a/src/VBox/Devices/USB/DevOHCI.cpp b/src/VBox/Devices/USB/DevOHCI.cpp
index 841a8b2f2..636ee4127 100644
--- a/src/VBox/Devices/USB/DevOHCI.cpp
+++ b/src/VBox/Devices/USB/DevOHCI.cpp
@@ -1,4 +1,4 @@
-/* $Id: DevOHCI.cpp $ */
+/* $Id: DevOHCI.cpp 37668 2011-06-28 16:02:10Z vboxsync $ */
/** @file
* DevOHCI - Open Host Controller Interface for USB.
*/
@@ -765,8 +765,6 @@ static int ohci_in_done_queue_find(POHCI pOhci, uint32_t GCPhys
# endif
static DECLCALLBACK(void) ohciR3LoadReattachDevices(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser);
#endif /* IN_RING3 */
-PDMBOTHCBDECL(int) ohciWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
-PDMBOTHCBDECL(int) ohciRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
RT_C_DECLS_END
@@ -872,6 +870,8 @@ static DECLCALLBACK(unsigned) ohciRhGetAvailablePorts(PVUSBIROOTHUBPORT pInterfa
unsigned cPorts = 0;
memset(pAvailable, 0, sizeof(*pAvailable));
+
+ PDMCritSectEnter(pOhci->pDevInsR3->pCritSectRoR3, VERR_IGNORED);
for (iPort = 0; iPort < RT_ELEMENTS(pOhci->RootHub.aPorts); iPort++)
{
if (!pOhci->RootHub.aPorts[iPort].pDev)
@@ -880,6 +880,7 @@ static DECLCALLBACK(unsigned) ohciRhGetAvailablePorts(PVUSBIROOTHUBPORT pInterfa
ASMBitSet(pAvailable, iPort + 1);
}
}
+ PDMCritSectLeave(pOhci->pDevInsR3->pCritSectRoR3);
return cPorts;
}
@@ -908,6 +909,7 @@ static DECLCALLBACK(int) ohciRhAttach(PVUSBIROOTHUBPORT pInterface, PVUSBIDEVICE
{
POHCI pOhci = VUSBIROOTHUBPORT_2_OHCI(pInterface);
LogFlow(("ohciRhAttach: pDev=%p uPort=%u\n", pDev, uPort));
+ PDMCritSectEnter(pOhci->pDevInsR3->pCritSectRoR3, VERR_IGNORED);
/*
* Validate and adjust input.
@@ -926,6 +928,7 @@ static DECLCALLBACK(int) ohciRhAttach(PVUSBIROOTHUBPORT pInterface, PVUSBIDEVICE
ohci_remote_wakeup(pOhci);
ohciSetInterrupt(pOhci, OHCI_INTR_ROOT_HUB_STATUS_CHANGE);
+ PDMCritSectLeave(pOhci->pDevInsR3->pCritSectRoR3);
return VINF_SUCCESS;
}
@@ -941,6 +944,7 @@ static DECLCALLBACK(void) ohciRhDetach(PVUSBIROOTHUBPORT pInterface, PVUSBIDEVIC
{
POHCI pOhci = VUSBIROOTHUBPORT_2_OHCI(pInterface);
LogFlow(("ohciRhDetach: pDev=%p uPort=%u\n", pDev, uPort));
+ PDMCritSectEnter(pOhci->pDevInsR3->pCritSectRoR3, VERR_IGNORED);
/*
* Validate and adjust input.
@@ -960,6 +964,8 @@ static DECLCALLBACK(void) ohciRhDetach(PVUSBIROOTHUBPORT pInterface, PVUSBIDEVIC
ohci_remote_wakeup(pOhci);
ohciSetInterrupt(pOhci, OHCI_INTR_ROOT_HUB_STATUS_CHANGE);
+
+ PDMCritSectLeave(pOhci->pDevInsR3->pCritSectRoR3);
}
@@ -997,6 +1003,7 @@ static DECLCALLBACK(void) ohciRhResetDoneOneDev(PVUSBIDEVICE pDev, int rc, void
static DECLCALLBACK(int) ohciRhReset(PVUSBIROOTHUBPORT pInterface, bool fResetOnLinux)
{
POHCI pOhci = VUSBIROOTHUBPORT_2_OHCI(pInterface);
+ PDMCritSectEnter(pOhci->pDevInsR3->pCritSectRoR3, VERR_IGNORED);
pOhci->RootHub.status = 0;
pOhci->RootHub.desc_a = OHCI_RHA_NPS | OHCI_NDP;
@@ -1029,6 +1036,7 @@ static DECLCALLBACK(int) ohciRhReset(PVUSBIROOTHUBPORT pInterface, bool fResetOn
pOhci->RootHub.aPorts[iPort].fReg = 0;
}
+ PDMCritSectLeave(pOhci->pDevInsR3->pCritSectRoR3);
return VINF_SUCCESS;
}
@@ -1692,7 +1700,19 @@ static int ohci_in_done_queue_find(POHCI pOhci, uint32_t GCPhysTD)
static bool ohci_in_done_queue_check(POHCI pOhci, uint32_t GCPhysTD)
{
int i = ohci_in_done_queue_find(pOhci, GCPhysTD);
+#if 0
+ /* This condition has been observed with the USB tablet emulation or with
+ * a real USB mouse and an SMP XP guest. I am also not sure if this is
+ * really a problem for us. The assertion checks that the guest doesn't
+ * re-submit a TD which is still in the done queue. It seems to me that
+ * this should only be a problem if we either keep track of TDs in the done
+ * queue somewhere else as well (in which case we should also free those
+ * references in time, and I can't see any code doing that) or if we
+ * manipulate TDs in the done queue in some way that might fail if they are
+ * re-submitted (can't see anything like that either).
+ */
AssertMsg(i < 0, ("TD %#010x (i=%d)\n", GCPhysTD, i));
+#endif
return i < 0;
}
@@ -2401,6 +2421,7 @@ static DECLCALLBACK(void) ohciRhXferCompletion(PVUSBIROOTHUBPORT pInterface, PVU
POHCI pOhci = VUSBIROOTHUBPORT_2_OHCI(pInterface);
LogFlow(("%s: ohciRhXferCompletion: EdAddr=%#010RX32 cTds=%d TdAddr0=%#010RX32\n",
pUrb->pszDesc, pUrb->Hci.EdAddr, pUrb->Hci.cTds, pUrb->Hci.paTds[0].TdAddr));
+ Assert(PDMCritSectIsOwner(pOhci->pDevInsR3->pCritSectRoR3));
pOhci->fIdle = false; /* Mark as active */
@@ -2475,6 +2496,7 @@ static DECLCALLBACK(void) ohciRhXferCompletion(PVUSBIROOTHUBPORT pInterface, PVU
static DECLCALLBACK(bool) ohciRhXferError(PVUSBIROOTHUBPORT pInterface, PVUSBURB pUrb)
{
POHCI pOhci = VUSBIROOTHUBPORT_2_OHCI(pInterface);
+ Assert(PDMCritSectIsOwner(pOhci->pDevInsR3->pCritSectRoR3));
/*
* Isochronous URBs can't be retried.
@@ -4812,7 +4834,7 @@ PDMBOTHCBDECL(int) ohciRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAdd
* @param pv Pointer to the data being written.
* @param cb The size of the data being written.
*/
-PDMBOTHCBDECL(int) ohciWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+PDMBOTHCBDECL(int) ohciWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
POHCI pOhci = PDMINS_2_DATA(pDevIns, POHCI);
diff --git a/src/VBox/Devices/USB/DrvVUSBRootHub.cpp b/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
index cbc37c060..33472e577 100644
--- a/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
+++ b/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
@@ -1,4 +1,4 @@
-/* $Id: DrvVUSBRootHub.cpp $ */
+/* $Id: DrvVUSBRootHub.cpp 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* Virtual USB - Root Hub Driver.
*/
diff --git a/src/VBox/Devices/USB/USBProxyDevice-stub.cpp b/src/VBox/Devices/USB/USBProxyDevice-stub.cpp
index 236b023a4..baed9620d 100644
--- a/src/VBox/Devices/USB/USBProxyDevice-stub.cpp
+++ b/src/VBox/Devices/USB/USBProxyDevice-stub.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyDevice-stub.cpp $ */
+/* $Id: USBProxyDevice-stub.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* USB device proxy - Stub.
*/
diff --git a/src/VBox/Devices/USB/USBProxyDevice.cpp b/src/VBox/Devices/USB/USBProxyDevice.cpp
index 8c036e07b..c306d2c11 100644
--- a/src/VBox/Devices/USB/USBProxyDevice.cpp
+++ b/src/VBox/Devices/USB/USBProxyDevice.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyDevice.cpp $ */
+/* $Id: USBProxyDevice.cpp 36479 2011-03-31 11:34:56Z vboxsync $ */
/** @file
* USBProxy - USB device proxy.
*/
@@ -394,8 +394,7 @@ static int copy_interface(PVUSBINTERFACE pIf, uint8_t ifnum,
num_ep++;
break;
default:
- /** @todo Here be dragons! Additional descriptors needs copying into pvClass
- * (RTMemDup be your friend). @bugref{2693} */
+ /* Skip unknown descriptors. */
break;
}
}
@@ -720,7 +719,6 @@ static DECLCALLBACK(void) usbProxyDestruct(PPDMUSBINS pUsbIns)
RTMemFree((void *)pThis->paCfgDescs[i].paIfs);
RTMemFree((void *)pThis->paCfgDescs[i].pvOriginal);
}
- /** @todo bugref{2693} cleanup */
RTMemFree(pThis->paCfgDescs);
pThis->paCfgDescs = NULL;
}
diff --git a/src/VBox/Devices/USB/USBProxyDevice.h b/src/VBox/Devices/USB/USBProxyDevice.h
index afd6cd041..3f2f82831 100644
--- a/src/VBox/Devices/USB/USBProxyDevice.h
+++ b/src/VBox/Devices/USB/USBProxyDevice.h
@@ -1,4 +1,4 @@
-/* $Id: USBProxyDevice.h $ */
+/* $Id: USBProxyDevice.h 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* USBPROXY - USB proxy header
*/
@@ -206,7 +206,7 @@ typedef struct USBPROXYDEV
/** Pointer to some backend data.
* The Linux and Darwin backends are making use of this. */
void *pv;
- RTFILE File;
+ RTFILE hFile;
int fd;
struct vrdp_priv
{
diff --git a/src/VBox/Devices/USB/VUSBDevice.cpp b/src/VBox/Devices/USB/VUSBDevice.cpp
index 49ffcb47f..82305b380 100644
--- a/src/VBox/Devices/USB/VUSBDevice.cpp
+++ b/src/VBox/Devices/USB/VUSBDevice.cpp
@@ -1,4 +1,4 @@
-/* $Id: VUSBDevice.cpp $ */
+/* $Id: VUSBDevice.cpp 37359 2011-06-07 17:12:57Z vboxsync $ */
/** @file
* Virtual USB - Device.
*/
diff --git a/src/VBox/Devices/USB/VUSBInternal.h b/src/VBox/Devices/USB/VUSBInternal.h
index c325a7ab1..827e809c7 100644
--- a/src/VBox/Devices/USB/VUSBInternal.h
+++ b/src/VBox/Devices/USB/VUSBInternal.h
@@ -1,4 +1,4 @@
-/* $Id: VUSBInternal.h $ */
+/* $Id: VUSBInternal.h 37361 2011-06-07 18:31:56Z vboxsync $ */
/** @file
* Virtual USB - Internal header.
*
diff --git a/src/VBox/Devices/USB/VUSBReadAhead.cpp b/src/VBox/Devices/USB/VUSBReadAhead.cpp
index 69ba7f566..70dd00eee 100644
--- a/src/VBox/Devices/USB/VUSBReadAhead.cpp
+++ b/src/VBox/Devices/USB/VUSBReadAhead.cpp
@@ -1,4 +1,4 @@
-/* $Id: VUSBReadAhead.cpp $ */
+/* $Id: VUSBReadAhead.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* Virtual USB - Read-ahead buffering for periodic endpoints.
*/
diff --git a/src/VBox/Devices/USB/VUSBUrb.cpp b/src/VBox/Devices/USB/VUSBUrb.cpp
index 017e5a7e6..348689ab8 100644
--- a/src/VBox/Devices/USB/VUSBUrb.cpp
+++ b/src/VBox/Devices/USB/VUSBUrb.cpp
@@ -1,4 +1,4 @@
-/* $Id: VUSBUrb.cpp $ */
+/* $Id: VUSBUrb.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* Virtual USB - URBs.
*/
diff --git a/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp b/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp
index 79102d085..1f3f48a21 100644
--- a/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp
+++ b/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyDevice-darwin.cpp $ */
+/* $Id: USBProxyDevice-darwin.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* USB device proxy - the Darwin backend.
*/
diff --git a/src/VBox/Devices/USB/freebsd/USBProxyDevice-freebsd.cpp b/src/VBox/Devices/USB/freebsd/USBProxyDevice-freebsd.cpp
index e66fcb007..470778cb3 100644
--- a/src/VBox/Devices/USB/freebsd/USBProxyDevice-freebsd.cpp
+++ b/src/VBox/Devices/USB/freebsd/USBProxyDevice-freebsd.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyDevice-freebsd.cpp $ */
+/* $Id: USBProxyDevice-freebsd.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* USB device proxy - the FreeBSD backend.
*/
@@ -93,7 +93,7 @@ typedef struct USBENDPOINTFBSD
typedef struct USBPROXYDEVFBSD
{
/** The open file. */
- RTFILE File;
+ RTFILE hFile;
/** Software endpoint structures */
USBENDPOINTFBSD aSwEndpoint[USBFBSD_MAXENDPOINTS];
/** Flag whether an URB is cancelling. */
@@ -132,7 +132,7 @@ static int usbProxyFreeBSDDoIoCtl(PUSBPROXYDEV pProxyDev, unsigned long iCmd,
do
{
- rc = ioctl(pDevFBSD->File, iCmd, pvArg);
+ rc = ioctl(RTFileToNative(pDevFBSD->hFile), iCmd, pvArg);
if (rc >= 0)
return VINF_SUCCESS;
} while (errno == EINTR);
@@ -240,7 +240,7 @@ static void usbProxyFreeBSDSetupReq(struct usb_device_request *pSetupData,
static int usbProxyFreeBSDEndpointOpen(PUSBPROXYDEV pProxyDev, int Endpoint, bool fIsoc, int index)
{
PUSBPROXYDEVFBSD pDevFBSD = (PUSBPROXYDEVFBSD) pProxyDev->Backend.pv;
- PUSBENDPOINTFBSD pEndpointFBSD;
+ PUSBENDPOINTFBSD pEndpointFBSD = NULL; /* shut up gcc */
struct usb_fs_endpoint *pXferEndpoint;
struct usb_fs_open UsbFsOpen;
int rc;
@@ -368,29 +368,24 @@ static int usbProxyFreeBSDOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress,
/*
* Try open the device node.
*/
- RTFILE File;
-
- rc = RTFileOpen(&File, pszAddress, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ RTFILE hFile;
+ rc = RTFileOpen(&hFile, pszAddress, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (RT_SUCCESS(rc))
{
/*
- * Allocate and initialize the linux backend data.
- */
- PUSBPROXYDEVFBSD pDevFBSD = (PUSBPROXYDEVFBSD)
- RTMemAllocZ(sizeof(USBPROXYDEVFBSD));
-
+ * Allocate and initialize the linux backend data.
+ */
+ PUSBPROXYDEVFBSD pDevFBSD = (PUSBPROXYDEVFBSD)RTMemAllocZ(sizeof(USBPROXYDEVFBSD));
if (pDevFBSD)
{
- pDevFBSD->File = File;
+ pDevFBSD->hFile = hFile;
pProxyDev->Backend.pv = pDevFBSD;
rc = usbProxyFreeBSDFsInit(pProxyDev);
if (RT_SUCCESS(rc))
{
- LogFlow(("usbProxyFreeBSDOpen(%p, %s): returns "
- "successfully File=%d iActiveCfg=%d\n",
- pProxyDev, pszAddress,
- pDevFBSD->File, pProxyDev->iActiveCfg));
+ LogFlow(("usbProxyFreeBSDOpen(%p, %s): returns successfully hFile=%RTfile iActiveCfg=%d\n",
+ pProxyDev, pszAddress, pDevFBSD->hFile, pProxyDev->iActiveCfg));
return VINF_SUCCESS;
}
@@ -400,7 +395,7 @@ static int usbProxyFreeBSDOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress,
else
rc = VERR_NO_MEMORY;
- RTFileClose(File);
+ RTFileClose(hFile);
}
else if (rc == VERR_ACCESS_DENIED)
rc = VERR_VUSB_USBFS_PERMISSION;
@@ -454,7 +449,7 @@ static int usbProxyFreeBSDInit(PUSBPROXYDEV pProxyDev)
*/
static void usbProxyFreeBSDClose(PUSBPROXYDEV pProxyDev)
{
- PUSBPROXYDEVFBSD pDevFBSD = (PUSBPROXYDEVFBSD) pProxyDev->Backend.pv;
+ PUSBPROXYDEVFBSD pDevFBSD = (PUSBPROXYDEVFBSD)pProxyDev->Backend.pv;
LogFlow(("usbProxyFreeBSDClose: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));
@@ -463,12 +458,10 @@ static void usbProxyFreeBSDClose(PUSBPROXYDEV pProxyDev)
usbProxyFreeBSDFsUnInit(pProxyDev);
- RTFileClose(pDevFBSD->File);
-
- pDevFBSD->File = NIL_RTFILE;
+ RTFileClose(pDevFBSD->hFile);
+ pDevFBSD->hFile = NIL_RTFILE;
RTMemFree(pDevFBSD);
-
pProxyDev->Backend.pv = NULL;
LogFlow(("usbProxyFreeBSDClose: returns\n"));
@@ -990,7 +983,7 @@ repeat:
else if (cMillies && rc == VERR_RESOURCE_BUSY)
{
/* Poll for finished transfers */
- PollFd.fd = (int)pDevFBSD->File;
+ PollFd.fd = RTFileToNative(pDevFBSD->hFile);
PollFd.events = POLLIN | POLLRDNORM;
PollFd.revents = 0;
diff --git a/src/VBox/Devices/USB/linux/USBProxyDevice-linux.cpp b/src/VBox/Devices/USB/linux/USBProxyDevice-linux.cpp
index ad8970a14..82ca2ce75 100644
--- a/src/VBox/Devices/USB/linux/USBProxyDevice-linux.cpp
+++ b/src/VBox/Devices/USB/linux/USBProxyDevice-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyDevice-linux.cpp $ */
+/* $Id: USBProxyDevice-linux.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* USB device proxy - the Linux backend.
*/
@@ -136,7 +136,7 @@ typedef struct USBPROXYURBLNX
typedef struct USBPROXYDEVLNX
{
/** The open file. */
- RTFILE File;
+ RTFILE hFile;
/** Critical section protecting the two lists. */
RTCRITSECT CritSect;
/** The list of free linux URBs. Singly linked. */
@@ -193,7 +193,7 @@ static int usbProxyLinuxDoIoCtl(PUSBPROXYDEV pProxyDev, unsigned long iCmd, void
{
do
{
- rc = ioctl(pDevLnx->File, iCmd, pvArg);
+ rc = ioctl(RTFileToNative(pDevLnx->hFile), iCmd, pvArg);
if (rc >= 0)
return rc;
} while (errno == EINTR);
@@ -235,7 +235,7 @@ static void usbProxLinuxUrbUnplugged(PUSBPROXYDEV pProxyDev)
PUSBPROXYURBLNX pCur = pUrbLnx;
pUrbLnx = pUrbLnx->pNext;
- ioctl(pDevLnx->File, USBDEVFS_DISCARDURB, &pCur->KUrb); /* not sure if this is required.. */
+ ioctl(RTFileToNative(pDevLnx->hFile), USBDEVFS_DISCARDURB, &pCur->KUrb); /* not sure if this is required.. */
if (!pCur->KUrb.status)
pCur->KUrb.status = -ENODEV;
@@ -595,8 +595,8 @@ static int usbProxyLinuxFindActiveConfig(PUSBPROXYDEV pProxyDev, const char *psz
RTDECL(int) USBProxyDeviceLinuxGetFD(PUSBPROXYDEV pProxyDev)
{
PUSBPROXYDEVLNX pDevLnx = (PUSBPROXYDEVLNX)pProxyDev->Backend.pv;
- AssertReturn(pDevLnx->File != NIL_RTFILE, -1);
- return pDevLnx->File;
+ AssertReturn(pDevLnx->hFile != NIL_RTFILE, -1);
+ return RTFileToNative(pDevLnx->hFile);
}
@@ -652,8 +652,8 @@ static int usbProxyLinuxOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress, voi
/*
* Try open the device node.
*/
- RTFILE File;
- int rc = RTFileOpen(&File, pszDevNode, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ RTFILE hFile;
+ int rc = RTFileOpen(&hFile, pszDevNode, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (RT_SUCCESS(rc))
{
/*
@@ -665,14 +665,14 @@ static int usbProxyLinuxOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress, voi
pDevLnx->fUsingSysfs = fUsingSysfs;
memcpy(&pDevLnx->szPath[0], pszPath, cchPath);
pDevLnx->szPath[cchPath] = '\0';
- pDevLnx->File = File;
+ pDevLnx->hFile = hFile;
rc = RTCritSectInit(&pDevLnx->CritSect);
if (RT_SUCCESS(rc))
{
pProxyDev->Backend.pv = pDevLnx;
- LogFlow(("usbProxyLinuxOpen(%p, %s): returns successfully File=%d iActiveCfg=%d\n",
- pProxyDev, pszAddress, pDevLnx->File, pProxyDev->iActiveCfg));
+ LogFlow(("usbProxyLinuxOpen(%p, %s): returns successfully File=%RTfile iActiveCfg=%d\n",
+ pProxyDev, pszAddress, pDevLnx->hFile, pProxyDev->iActiveCfg));
return VINF_SUCCESS;
}
@@ -681,7 +681,7 @@ static int usbProxyLinuxOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress, voi
}
else
rc = VERR_NO_MEMORY;
- RTFileClose(File);
+ RTFileClose(hFile);
}
else if (rc == VERR_ACCESS_DENIED)
rc = VERR_VUSB_USBFS_PERMISSION;
@@ -811,8 +811,8 @@ static void usbProxyLinuxClose(PUSBPROXYDEV pProxyDev)
RTMemFree(pUrbLnx);
}
- RTFileClose(pDevLnx->File);
- pDevLnx->File = NIL_RTFILE;
+ RTFileClose(pDevLnx->hFile);
+ pDevLnx->hFile = NIL_RTFILE;
RTMemFree(pDevLnx);
pProxyDev->Backend.pv = NULL;
@@ -1277,7 +1277,7 @@ static bool usbProxyLinuxSubmitURB(PUSBPROXYDEV pProxyDev, PUSBPROXYURBLNX pCur,
PUSBPROXYDEVLNX pDevLnx = (PUSBPROXYDEVLNX)pProxyDev->Backend.pv;
unsigned cTries = 0;
- while (ioctl(pDevLnx->File, USBDEVFS_SUBMITURB, &pCur->KUrb))
+ while (ioctl(RTFileToNative(pDevLnx->hFile), USBDEVFS_SUBMITURB, &pCur->KUrb))
{
if (errno == EINTR)
continue;
@@ -1515,7 +1515,7 @@ static int usbProxyLinuxUrbQueue(PVUSBURB pUrb)
* Submit it.
*/
cTries = 0;
- while (ioctl(pDevLnx->File, USBDEVFS_SUBMITURB, &pUrbLnx->KUrb))
+ while (ioctl(RTFileToNative(pDevLnx->hFile), USBDEVFS_SUBMITURB, &pUrbLnx->KUrb))
{
if (errno == EINTR)
continue;
@@ -1759,13 +1759,11 @@ static PVUSBURB usbProxyLinuxUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMilli
for (;;)
{
struct pollfd pfd;
- int rc;
-
- pfd.fd = pDevLnx->File;
+ pfd.fd = RTFileToNative(pDevLnx->hFile);
pfd.events = POLLOUT | POLLWRNORM /* completed async */
| POLLERR | POLLHUP /* disconnected */;
pfd.revents = 0;
- rc = poll(&pfd, 1, cMillies);
+ int rc = poll(&pfd, 1, cMillies);
Log(("usbProxyLinuxUrbReap: poll rc = %d\n", rc));
if (rc >= 1)
break;
@@ -1789,7 +1787,7 @@ static PVUSBURB usbProxyLinuxUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMilli
for (;;)
{
struct usbdevfs_urb *pKUrb;
- while (ioctl(pDevLnx->File, USBDEVFS_REAPURBNDELAY, &pKUrb))
+ while (ioctl(RTFileToNative(pDevLnx->hFile), USBDEVFS_REAPURBNDELAY, &pKUrb))
if (errno != EINTR)
{
if (errno == ENODEV)
diff --git a/src/VBox/Devices/USB/os2/USBProxyDevice-os2.cpp b/src/VBox/Devices/USB/os2/USBProxyDevice-os2.cpp
index 58074a429..0440048f4 100644
--- a/src/VBox/Devices/USB/os2/USBProxyDevice-os2.cpp
+++ b/src/VBox/Devices/USB/os2/USBProxyDevice-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyDevice-os2.cpp $ */
+/* $Id: USBProxyDevice-os2.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* USB device proxy - the Linux backend.
*/
diff --git a/src/VBox/Devices/USB/solaris/USBProxyDevice-solaris.cpp b/src/VBox/Devices/USB/solaris/USBProxyDevice-solaris.cpp
index bee9fde9c..2a94a429a 100644
--- a/src/VBox/Devices/USB/solaris/USBProxyDevice-solaris.cpp
+++ b/src/VBox/Devices/USB/solaris/USBProxyDevice-solaris.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyDevice-solaris.cpp $ */
+/* $Id: USBProxyDevice-solaris.cpp 37811 2011-07-07 08:37:58Z vboxsync $ */
/** @file
* USB device proxy - the Solaris backend.
*/
@@ -79,7 +79,7 @@ typedef struct USBPROXYDEVSOL
/** Path of the USB device in the devices tree (persistent). */
char *pszDevicePath;
/** The connection to the client driver. */
- RTFILE File;
+ RTFILE hFile;
/** Pointer to the proxy device instance. */
PUSBPROXYDEV pProxyDev;
/** Critical section protecting the two lists. */
@@ -195,11 +195,8 @@ static void usbProxySolarisUrbFree(PUSBPROXYDEVSOL pDevSol, PUSBPROXYURBSOL pUrb
*/
static void usbProxySolarisCloseFile(PUSBPROXYDEVSOL pDevSol)
{
- if (pDevSol->File != NIL_RTFILE)
- {
- RTFileClose(pDevSol->File);
- pDevSol->File = NIL_RTFILE;
- }
+ RTFileClose(pDevSol->hFile);
+ pDevSol->hFile = NIL_RTFILE;
}
@@ -214,7 +211,7 @@ static void usbProxySolarisCloseFile(PUSBPROXYDEVSOL pDevSol)
*/
static int usbProxySolarisIOCtl(PUSBPROXYDEVSOL pDevSol, unsigned Function, void *pvData, size_t cbData)
{
- if (RT_UNLIKELY(pDevSol->File == NIL_RTFILE))
+ if (RT_UNLIKELY(pDevSol->hFile == NIL_RTFILE))
{
LogFlow((USBPROXY ":usbProxySolarisIOCtl connection to driver gone!\n"));
return VERR_VUSB_DEVICE_NOT_ATTACHED;
@@ -227,7 +224,7 @@ static int usbProxySolarisIOCtl(PUSBPROXYDEVSOL pDevSol, unsigned Function, void
Req.pvDataR3 = pvData;
int Ret = -1;
- int rc = RTFileIoCtl(pDevSol->File, Function, &Req, sizeof(Req), &Ret);
+ int rc = RTFileIoCtl(pDevSol->hFile, Function, &Req, sizeof(Req), &Ret);
if (RT_SUCCESS(rc))
{
if (RT_FAILURE(Req.rc))
@@ -326,11 +323,11 @@ static int usbProxySolarisOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress, v
/*
* Open the client driver.
*/
- RTFILE File;
- rc = RTFileOpen(&File, pDevSol->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ RTFILE hFile;
+ rc = RTFileOpen(&hFile, pDevSol->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (RT_SUCCESS(rc))
{
- pDevSol->File = File;
+ pDevSol->hFile = hFile;
pDevSol->pProxyDev = pProxyDev;
/*
@@ -362,8 +359,8 @@ static int usbProxySolarisOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress, v
LogRel((USBPROXY ":failed to query driver version. rc=%Rrc\n", rc));
}
- RTFileClose(pDevSol->File);
- pDevSol->File = NIL_RTFILE;
+ RTFileClose(pDevSol->hFile);
+ pDevSol->hFile = NIL_RTFILE;
pDevSol->pProxyDev = NULL;
}
else
@@ -597,16 +594,6 @@ static int usbProxySolarisUrbQueue(PVUSBURB pUrb)
LogFlowFunc((USBPROXY ": usbProxySolarisUrbQueue: pProxyDev=%s pUrb=%p EndPt=%#x enmDir=%d cbData=%d pvData=%p\n",
pProxyDev->pUsbIns->pszName, pUrb, pUrb->EndPt, pUrb->enmDir, pUrb->cbData, pUrb->abData));
- // Enable Isoc. Xfers
-#if 0
- if (pUrb->enmType == VUSBXFERTYPE_ISOC)
- {
- /* Not yet complete (disabled for now) */
- LogFlow((USBPROXY ":usbProxySolarisUrbQueue: Isoc. Xfers not supported\n"));
- return false;
- }
-#endif
-
PUSBPROXYURBSOL pUrbSol = usbProxySolarisUrbAlloc(pDevSol);
if (RT_UNLIKELY(!pUrbSol))
{
@@ -720,13 +707,10 @@ static PVUSBURB usbProxySolarisUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMil
for (;;)
{
struct pollfd pfd;
- int rc;
-
- pfd.fd = pDevSol->File;
+ pfd.fd = RTFileToNative(pDevSol->hFile);
pfd.events = POLLIN;
pfd.revents = 0;
- rc = poll(&pfd, 1, cMillies);
-
+ int rc = poll(&pfd, 1, cMillies);
if (rc > 0)
{
if (pfd.revents & POLLHUP)
diff --git a/src/VBox/Devices/USB/testcase/tstPalmOne.c b/src/VBox/Devices/USB/testcase/tstPalmOne.c
index 136c5d2ce..03656f01b 100644
--- a/src/VBox/Devices/USB/testcase/tstPalmOne.c
+++ b/src/VBox/Devices/USB/testcase/tstPalmOne.c
@@ -1,4 +1,4 @@
-/* $Id: tstPalmOne.c $ */
+/* $Id: tstPalmOne.c 33595 2010-10-29 10:35:00Z vboxsync $ */
/** @file
* USB PalmOne testcase
*/
diff --git a/src/VBox/Devices/USB/testcase/tstTrekStorGo.c b/src/VBox/Devices/USB/testcase/tstTrekStorGo.c
index 22c857725..33a484537 100644
--- a/src/VBox/Devices/USB/testcase/tstTrekStorGo.c
+++ b/src/VBox/Devices/USB/testcase/tstTrekStorGo.c
@@ -1,4 +1,4 @@
-/* $Id: tstTrekStorGo.c $ */
+/* $Id: tstTrekStorGo.c 33595 2010-10-29 10:35:00Z vboxsync $ */
/** @file
* Some simple inquiry test for the TrekStor USB-Stick GO, linux usbfs
*/
diff --git a/src/VBox/Devices/USB/vrdp/USBProxyDevice-vrdp.cpp b/src/VBox/Devices/USB/vrdp/USBProxyDevice-vrdp.cpp
index 9aeb0e4e2..1bb7e451f 100644
--- a/src/VBox/Devices/USB/vrdp/USBProxyDevice-vrdp.cpp
+++ b/src/VBox/Devices/USB/vrdp/USBProxyDevice-vrdp.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyDevice-vrdp.cpp $ */
+/* $Id: USBProxyDevice-vrdp.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* USB device proxy - the VRDP backend, calls the RemoteUSBBackend methods.
*/
diff --git a/src/VBox/Devices/USB/win/USBProxyDevice-win.cpp b/src/VBox/Devices/USB/win/USBProxyDevice-win.cpp
index 1bede8b31..d219cbb2e 100644
--- a/src/VBox/Devices/USB/win/USBProxyDevice-win.cpp
+++ b/src/VBox/Devices/USB/win/USBProxyDevice-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyDevice-win.cpp $ */
+/* $Id: USBProxyDevice-win.cpp 37346 2011-06-07 13:06:29Z vboxsync $ */
/** @file
* USBPROXY - USB proxy, Win32 backend
*
@@ -35,9 +35,9 @@
#include <iprt/err.h>
#include <iprt/string.h>
#include <iprt/thread.h>
+#include <iprt/asm.h>
#include "../USBProxyDevice.h"
#include <VBox/usblib.h>
-//#include "USBLibInternal.h"
/*******************************************************************************
@@ -310,7 +310,7 @@ static int usbProxyWinSetConfig(PUSBPROXYDEV pProxyDev, int cfg)
pProxyDev->fDetached = true;
}
else
- AssertMsgFailed(("lasterr=%d\n", GetLastError()));
+ AssertMsgFailed(("lasterr=%u\n", GetLastError()));
return 0;
}
@@ -427,7 +427,7 @@ static int usbProxyWinAbortEndPt(PUSBPROXYDEV pProxyDev, unsigned int ep)
pProxyDev->fDetached = true;
}
else
- AssertMsgFailed(("lasterr=%d\n", GetLastError()));
+ AssertMsgFailed(("lasterr=%d\n", rc));
return RTErrConvertFromWin32(rc);
}
@@ -441,23 +441,6 @@ static int usbProxyWinUrbQueue(PVUSBURB pUrb)
Assert(pPriv);
/*
- * Ensure we've got sufficient space in the arrays.
- */
- if (pPriv->cQueuedUrbs + 1 > pPriv->cAllocatedUrbs)
- {
- unsigned cNewMax = pPriv->cAllocatedUrbs + 32;
- void *pv = RTMemRealloc(pPriv->paHandles, sizeof(pPriv->paHandles[0]) * cNewMax);
- if (!pv)
- return false;
- pPriv->paHandles = (PHANDLE)pv;
- pv = RTMemRealloc(pPriv->paQueuedUrbs, sizeof(pPriv->paQueuedUrbs[0]) * cNewMax);
- if (!pv)
- return false;
- pPriv->paQueuedUrbs = (PQUEUED_URB *)pv;
- pPriv->cAllocatedUrbs = cNewMax;
- }
-
- /*
* Allocate and initialize a URB queue structure.
*/
/** @todo pool these */
@@ -521,14 +504,50 @@ static int usbProxyWinUrbQueue(PVUSBURB pUrb)
RTThreadSleep(1);
RTCritSectEnter(&pPriv->CritSect);
- pUrb->Dev.pvPrivate = pQUrbWin;
- pPriv->aPendingUrbs[pPriv->cPendingUrbs] = pQUrbWin;
- pPriv->cPendingUrbs++;
+ do
+ {
+ /* Ensure we've got sufficient space in the arrays.
+ * Do it inside the lock to ensure we do not concur
+ * with the usbProxyWinAsyncIoThread */
+ if (pPriv->cQueuedUrbs + 1 > pPriv->cAllocatedUrbs)
+ {
+ unsigned cNewMax = pPriv->cAllocatedUrbs + 32;
+ void *pv = RTMemRealloc(pPriv->paHandles, sizeof(pPriv->paHandles[0]) * cNewMax);
+ if (!pv)
+ {
+ AssertMsgFailed(("RTMemRealloc failed for paHandles[%d]", cNewMax));
+ break;
+ }
+ pPriv->paHandles = (PHANDLE)pv;
+
+ pv = RTMemRealloc(pPriv->paQueuedUrbs, sizeof(pPriv->paQueuedUrbs[0]) * cNewMax);
+ if (!pv)
+ {
+ AssertMsgFailed(("RTMemRealloc failed for paQueuedUrbs[%d]", cNewMax));
+ break;
+ }
+ pPriv->paQueuedUrbs = (PQUEUED_URB *)pv;
+ pPriv->cAllocatedUrbs = cNewMax;
+ }
+
+ pUrb->Dev.pvPrivate = pQUrbWin;
+ pPriv->aPendingUrbs[pPriv->cPendingUrbs] = pQUrbWin;
+ pPriv->cPendingUrbs++;
+ RTCritSectLeave(&pPriv->CritSect);
+ SetEvent(pPriv->hEventAsyncIo);
+ return true;
+ } while (0);
+
RTCritSectLeave(&pPriv->CritSect);
- SetEvent(pPriv->hEventAsyncIo);
- return true;
}
- Assert(pPriv->cPendingUrbs < RT_ELEMENTS(pPriv->aPendingUrbs));
+#ifdef DEBUG_misha
+ else
+ {
+ AssertMsgFailed(("FAILED!!, hEvent(0x%p), cPendingUrbs(%d)\n", pQUrbWin->overlapped.hEvent, pPriv->cPendingUrbs));
+ }
+#endif
+
+ Assert(pQUrbWin->overlapped.hEvent == INVALID_HANDLE_VALUE);
RTMemFree(pQUrbWin);
return false;
}
@@ -594,9 +613,16 @@ static PVUSBURB usbProxyWinUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMillies
/*
* Wait/poll.
+ *
+ * ASSUMPTIONS:
+ * 1. The usbProxyWinUrbReap can not be run concurrently with each other
+ * so racing the cQueuedUrbs access/modification can not occur.
+ * 2. The usbProxyWinUrbReap can not be run concurrently with
+ * usbProxyWinUrbQueue so they can not race the pPriv->paHandles
+ * access/realloc.
*/
+ unsigned cQueuedUrbs = ASMAtomicReadU32((volatile uint32_t *)&pPriv->cQueuedUrbs);
PVUSBURB pUrb = NULL;
- unsigned cQueuedUrbs = pPriv->cQueuedUrbs;
DWORD rc = WaitForMultipleObjects(cQueuedUrbs, pPriv->paHandles, FALSE, cMillies);
if (rc >= WAIT_OBJECT_0 && rc < WAIT_OBJECT_0 + cQueuedUrbs)
{
@@ -694,9 +720,12 @@ static DECLCALLBACK(int) usbProxyWinAsyncIoThread(RTTHREAD ThreadSelf, void *lpP
|| GetLastError() == ERROR_IO_PENDING)
{
/* insert into the queue */
- unsigned j = pPriv->cQueuedUrbs++;
+ unsigned j = pPriv->cQueuedUrbs;
pPriv->paQueuedUrbs[j] = pQUrbWin;
- pPriv->paHandles[j] = pQUrbWin->overlapped.hEvent;
+ pPriv->paHandles[j] = pQUrbWin->overlapped.hEvent;
+ /* do an atomic increment to allow usbProxyWinUrbReap thread get it outside a lock,
+ * being sure that pPriv->paHandles contains cQueuedUrbs valid handles */
+ ASMAtomicIncU32((uint32_t volatile *)&pPriv->cQueuedUrbs);
}
else
{
@@ -770,7 +799,7 @@ static void usbProxyWinUrbCancel(PVUSBURB pUrb)
pProxyDev->fDetached = true;
}
else
- AssertMsgFailed(("lasterr=%d\n", GetLastError()));
+ AssertMsgFailed(("lasterr=%d\n", rc));
}
diff --git a/src/VBox/Devices/VMMDev/VMMDev.cpp b/src/VBox/Devices/VMMDev/VMMDev.cpp
index a7ca0ca03..30abc2580 100644
--- a/src/VBox/Devices/VMMDev/VMMDev.cpp
+++ b/src/VBox/Devices/VMMDev/VMMDev.cpp
@@ -1,10 +1,10 @@
-/* $Id: VMMDev.cpp $ */
+/* $Id: VMMDev.cpp 38037 2011-07-18 17:31:38Z vboxsync $ */
/** @file
* VMMDev - Guest <-> VMM/Host communication device.
*/
/*
- * 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;
@@ -19,7 +19,7 @@
/*******************************************************************************
* Header Files *
*******************************************************************************/
-/* #define LOG_ENABLED */
+
/* Enable dev_vmm Log3 statements to get IRQ-related logging. */
#define LOG_GROUP LOG_GROUP_DEV_VMM
@@ -435,7 +435,8 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser,
if ( !pThis->fu32AdditionsOk
&& requestHeader.requestType != VMMDevReq_ReportGuestInfo2
&& requestHeader.requestType != VMMDevReq_ReportGuestInfo
- && requestHeader.requestType != VMMDevReq_WriteCoreDump)
+ && requestHeader.requestType != VMMDevReq_WriteCoreDump
+ && requestHeader.requestType != VMMDevReq_GetHostVersion) /* Always allow the guest to query the host capabilities. */
{
Log(("VMMDev: guest has not yet reported to us. Refusing operation of request #%d!\n",
requestHeader.requestType));
@@ -1470,7 +1471,8 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser,
case VMMDevReq_VideoSetVisibleRegion:
{
- if (pRequestHeader->size < sizeof(VMMDevVideoSetVisibleRegion))
+ if ( pRequestHeader->size + sizeof(RTRECT)
+ < sizeof(VMMDevVideoSetVisibleRegion))
{
Log(("VMMDevReq_VideoSetVisibleRegion request size too small!!!\n"));
pRequestHeader->rc = VERR_INVALID_PARAMETER;
@@ -1484,13 +1486,8 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser,
{
VMMDevVideoSetVisibleRegion *ptr = (VMMDevVideoSetVisibleRegion *)pRequestHeader;
- if (!ptr->cRect)
- {
- Log(("VMMDevReq_VideoSetVisibleRegion no rectangles!!!\n"));
- pRequestHeader->rc = VERR_INVALID_PARAMETER;
- }
- else if ( ptr->cRect > _1M /* restrict to sane range */
- || pRequestHeader->size != sizeof(VMMDevVideoSetVisibleRegion) + ptr->cRect * sizeof(RTRECT) - sizeof(RTRECT))
+ if ( ptr->cRect > _1M /* restrict to sane range */
+ || pRequestHeader->size != sizeof(VMMDevVideoSetVisibleRegion) + ptr->cRect * sizeof(RTRECT) - sizeof(RTRECT))
{
Log(("VMMDevReq_VideoSetVisibleRegion: cRects=%#x doesn't match size=%#x or is out of bounds\n",
ptr->cRect, pRequestHeader->size));
@@ -2190,15 +2187,13 @@ static DECLCALLBACK(int) vmmdevQueryStatusLed(PPDMILEDPORTS pInterface, unsigned
* @param pAbsX Pointer of result value, can be NULL
* @param pAbsY Pointer of result value, can be NULL
*/
-static DECLCALLBACK(int) vmmdevQueryAbsoluteMouse(PPDMIVMMDEVPORT pInterface, uint32_t *pAbsX, uint32_t *pAbsY)
+static DECLCALLBACK(int) vmmdevQueryAbsoluteMouse(PPDMIVMMDEVPORT pInterface, int32_t *pAbsX, int32_t *pAbsY)
{
VMMDevState *pThis = IVMMDEVPORT_2_VMMDEVSTATE(pInterface);
- AssertCompile(sizeof(pThis->mouseXAbs) == sizeof(*pAbsX));
- AssertCompile(sizeof(pThis->mouseYAbs) == sizeof(*pAbsY));
if (pAbsX)
- ASMAtomicReadSize(&pThis->mouseXAbs, pAbsX);
+ *pAbsX = ASMAtomicReadS32(&pThis->mouseXAbs); /* why the atomic read? */
if (pAbsY)
- ASMAtomicReadSize(&pThis->mouseYAbs, pAbsY);
+ *pAbsY = ASMAtomicReadS32(&pThis->mouseYAbs);
return VINF_SUCCESS;
}
@@ -2209,12 +2204,12 @@ static DECLCALLBACK(int) vmmdevQueryAbsoluteMouse(PPDMIVMMDEVPORT pInterface, ui
* @param absX New absolute X position
* @param absY New absolute Y position
*/
-static DECLCALLBACK(int) vmmdevSetAbsoluteMouse(PPDMIVMMDEVPORT pInterface, uint32_t absX, uint32_t absY)
+static DECLCALLBACK(int) vmmdevSetAbsoluteMouse(PPDMIVMMDEVPORT pInterface, int32_t absX, int32_t absY)
{
VMMDevState *pThis = IVMMDEVPORT_2_VMMDEVSTATE(pInterface);
PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
- if ((pThis->mouseXAbs == absX) && (pThis->mouseYAbs == absY))
+ if (pThis->mouseXAbs == absX && pThis->mouseYAbs == absY)
{
PDMCritSectLeave(&pThis->CritSect);
return VINF_SUCCESS;
@@ -2556,8 +2551,8 @@ static DECLCALLBACK(int) vmmdevSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
SSMR3PutU32(pSSM, pThis->hypervisorSize);
SSMR3PutU32(pSSM, pThis->mouseCapabilities);
- SSMR3PutU32(pSSM, pThis->mouseXAbs);
- SSMR3PutU32(pSSM, pThis->mouseYAbs);
+ SSMR3PutS32(pSSM, pThis->mouseXAbs);
+ SSMR3PutS32(pSSM, pThis->mouseYAbs);
SSMR3PutBool(pSSM, pThis->fNewGuestFilterMask);
SSMR3PutU32(pSSM, pThis->u32NewGuestFilterMask);
@@ -2624,8 +2619,8 @@ static DECLCALLBACK(int) vmmdevLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uin
/* state */
SSMR3GetU32(pSSM, &pThis->hypervisorSize);
SSMR3GetU32(pSSM, &pThis->mouseCapabilities);
- SSMR3GetU32(pSSM, &pThis->mouseXAbs);
- SSMR3GetU32(pSSM, &pThis->mouseYAbs);
+ SSMR3GetS32(pSSM, &pThis->mouseXAbs);
+ SSMR3GetS32(pSSM, &pThis->mouseYAbs);
SSMR3GetBool(pSSM, &pThis->fNewGuestFilterMask);
SSMR3GetU32(pSSM, &pThis->u32NewGuestFilterMask);
@@ -2760,8 +2755,6 @@ static DECLCALLBACK(void) vmmdevReset(PPDMDEVINS pDevIns)
pThis->hypervisorSize = 0;
- pThis->u32HostEventFlags = 0;
-
/* re-initialize the VMMDev memory */
if (pThis->pVMMDevRAMR3)
vmmdevInitRam(pThis);
@@ -2811,10 +2804,12 @@ static DECLCALLBACK(void) vmmdevReset(PPDMDEVINS pDevIns)
/*
* Clear the event variables.
*
- * Note: The pThis->u32HostEventFlags is not cleared.
- * It is designed that way so host events do not
- * depend on guest resets.
+ * XXX By design we should NOT clear pThis->u32HostEventFlags because it is designed
+ * that way so host events do not depend on guest resets. However, the pending
+ * event flags actually _were_ cleared since ages so we mask out events from
+ * clearing which we really need to survive the reset. See xtracker 5767.
*/
+ pThis->u32HostEventFlags &= VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
pThis->u32GuestFilterMask = 0;
pThis->u32NewGuestFilterMask = 0;
pThis->fNewGuestFilterMask = 0;
@@ -3015,7 +3010,7 @@ static DECLCALLBACK(int) vmmdevConstruct(PPDMDEVINS pDevIns, int iInstance, PCFG
/*
* Create the critical section for the device.
*/
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "VMMDev");
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "VMMDev#u", iInstance);
AssertRCReturn(rc, rc);
/* Later: pDevIns->pCritSectR3 = &pThis->CritSect; */
diff --git a/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp b/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp
index e4230cddb..9b264ba8d 100644
--- a/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp
+++ b/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMMDevHGCM.cpp $ */
+/* $Id: VMMDevHGCM.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VMMDev - HGCM - Host-Guest Communication Manager Device.
*/
diff --git a/src/VBox/Devices/VMMDev/VMMDevState.h b/src/VBox/Devices/VMMDev/VMMDevState.h
index 48f9519c3..ddb8396f4 100644
--- a/src/VBox/Devices/VMMDev/VMMDevState.h
+++ b/src/VBox/Devices/VMMDev/VMMDevState.h
@@ -1,4 +1,4 @@
-/* $Id: VMMDevState.h $ */
+/* $Id: VMMDevState.h 35989 2011-02-15 19:55:27Z vboxsync $ */
/** @file
* VMMDev - Guest <-> VMM/Host communication device, internal header.
*/
@@ -95,8 +95,8 @@ typedef struct VMMDevState
/** mouse capabilities of host and guest */
uint32_t mouseCapabilities;
/** absolute mouse position in pixels */
- uint32_t mouseXAbs;
- uint32_t mouseYAbs;
+ int32_t mouseXAbs;
+ int32_t mouseYAbs;
/** Does the guest currently want the host pointer to be shown? */
uint32_t fHostCursorRequested;
diff --git a/src/VBox/Devices/VMMDev/VMMDevTesting.cpp b/src/VBox/Devices/VMMDev/VMMDevTesting.cpp
index ced7e2110..c8b65c67c 100644
--- a/src/VBox/Devices/VMMDev/VMMDevTesting.cpp
+++ b/src/VBox/Devices/VMMDev/VMMDevTesting.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMMDevTesting.cpp $ */
+/* $Id: VMMDevTesting.cpp 37636 2011-06-24 14:59:59Z vboxsync $ */
/** @file
* VMMDev - Testing Extensions.
*/
@@ -41,7 +41,7 @@
/**
* @callback_method_impl{FNIOMMMIOWRITE}
*/
-PDMBOTHCBDECL(int) vmmdevTestingMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
+PDMBOTHCBDECL(int) vmmdevTestingMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
switch (GCPhysAddr)
{
diff --git a/src/VBox/Devices/VMMDev/VMMDevTesting.h b/src/VBox/Devices/VMMDev/VMMDevTesting.h
index aa8f28de5..5b5d5dab6 100644
--- a/src/VBox/Devices/VMMDev/VMMDevTesting.h
+++ b/src/VBox/Devices/VMMDev/VMMDevTesting.h
@@ -1,4 +1,4 @@
-/* $Id: VMMDevTesting.h $ */
+/* $Id: VMMDevTesting.h 30724 2010-07-08 08:30:20Z vboxsync $ */
/** @file
* VMMDev - Guest <-> VMM/Host communication device, internal header.
*/
diff --git a/src/VBox/Devices/VirtIO/Virtio.cpp b/src/VBox/Devices/VirtIO/Virtio.cpp
index 62b461a39..b40e134a0 100644
--- a/src/VBox/Devices/VirtIO/Virtio.cpp
+++ b/src/VBox/Devices/VirtIO/Virtio.cpp
@@ -1,4 +1,4 @@
-/* $Id: Virtio.cpp $ */
+/* $Id: Virtio.cpp 37466 2011-06-15 12:44:16Z vboxsync $ */
/** @file
* Virtio - Virtio Common Functions (VRing, VQueue, Virtio PCI)
*/
@@ -808,7 +808,6 @@ DECLCALLBACK(int) vpciConstruct(PPDMDEVINS pDevIns, VPCISTATE *pState,
uint16_t uSubsystemId, uint16_t uClass,
uint32_t nQueues)
{
- int rc = VINF_SUCCESS;
/* Init handles and log related stuff. */
RTStrPrintf(pState->szInstance, sizeof(pState->szInstance),
pcszNameFmt, iInstance);
@@ -821,7 +820,7 @@ DECLCALLBACK(int) vpciConstruct(PPDMDEVINS pDevIns, VPCISTATE *pState,
pState->ILeds.pfnQueryStatusLed = vpciQueryStatusLed;
/* Initialize critical section. */
- rc = PDMDevHlpCritSectInit(pDevIns, &pState->cs, RT_SRC_POS, "%s", pState->szInstance);
+ int rc = PDMDevHlpCritSectInit(pDevIns, &pState->cs, RT_SRC_POS, "%s", pState->szInstance);
if (RT_FAILURE(rc))
return rc;
diff --git a/src/VBox/Devices/VirtIO/Virtio.h b/src/VBox/Devices/VirtIO/Virtio.h
index 0dad92a06..96a66e743 100644
--- a/src/VBox/Devices/VirtIO/Virtio.h
+++ b/src/VBox/Devices/VirtIO/Virtio.h
@@ -1,4 +1,4 @@
-/* $Id: Virtio.h $ */
+/* $Id: Virtio.h 33325 2010-10-21 20:34:14Z vboxsync $ */
/** @file
* Virtio.h - Virtio Declarations
*/
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/Makefile.kup b/src/VBox/Devices/build/Makefile.kup
index e69de29bb..e69de29bb 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/Makefile.kup
+++ b/src/VBox/Devices/build/Makefile.kup
diff --git a/src/VBox/Devices/build/VBoxDD-dtrace.d b/src/VBox/Devices/build/VBoxDD-dtrace.d
index 0e0b90243..90c55221a 100644
--- a/src/VBox/Devices/build/VBoxDD-dtrace.d
+++ b/src/VBox/Devices/build/VBoxDD-dtrace.d
@@ -1,4 +1,4 @@
-/* $Id: VBoxDD-dtrace.d $ */
+/* $Id: VBoxDD-dtrace.d 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* VBoxDD - Static dtrace probes
*/
diff --git a/src/VBox/Devices/build/VBoxDD.cpp b/src/VBox/Devices/build/VBoxDD.cpp
index 44a55862c..2e416a70b 100644
--- a/src/VBox/Devices/build/VBoxDD.cpp
+++ b/src/VBox/Devices/build/VBoxDD.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxDD.cpp $ */
+/* $Id: VBoxDD.cpp 37781 2011-07-05 13:35:29Z vboxsync $ */
/** @file
* VBoxDD - Built-in drivers & devices (part 1).
*/
@@ -132,7 +132,7 @@ extern "C" DECLEXPORT(int) VBoxDevicesRegister(PPDMDEVREGCB pCallbacks, uint32_t
if (RT_FAILURE(rc))
return rc;
#endif
-#ifdef VBOX_WITH_EHCI
+#ifdef VBOX_WITH_EHCI_IMPL
rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceEHCI);
if (RT_FAILURE(rc))
return rc;
@@ -178,9 +178,12 @@ extern "C" DECLEXPORT(int) VBoxDevicesRegister(PPDMDEVREGCB pCallbacks, uint32_t
if (RT_FAILURE(rc))
return rc;
#endif
+
+#ifdef VBOX_WITH_PCI_PASSTHROUGH_IMPL
rc = pCallbacks->pfnRegister(pCallbacks, &g_DevicePciRaw);
if (RT_FAILURE(rc))
return rc;
+#endif
return VINF_SUCCESS;
}
@@ -226,16 +229,19 @@ extern "C" DECLEXPORT(int) VBoxDriversRegister(PCPDMDRVREGCB pCallbacks, uint32_
rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvRawImage);
if (RT_FAILURE(rc))
return rc;
-#ifndef RT_OS_L4
rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvNAT);
if (RT_FAILURE(rc))
return rc;
-#endif
#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostInterface);
if (RT_FAILURE(rc))
return rc;
#endif
+#ifdef VBOX_WITH_UDPTUNNEL
+ rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvUDPTunnel);
+ if (RT_FAILURE(rc))
+ return rc;
+#endif
#ifdef VBOX_WITH_VDE
rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvVDE);
if (RT_FAILURE(rc))
@@ -266,7 +272,6 @@ extern "C" DECLEXPORT(int) VBoxDriversRegister(PCPDMDRVREGCB pCallbacks, uint32_
return rc;
#endif
-#if !defined(RT_OS_L4)
rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvNamedPipe);
if (RT_FAILURE(rc))
return rc;
@@ -276,7 +281,6 @@ extern "C" DECLEXPORT(int) VBoxDriversRegister(PCPDMDRVREGCB pCallbacks, uint32_
rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvChar);
if (RT_FAILURE(rc))
return rc;
-#endif
#if defined(RT_OS_LINUX)
rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostParallel);
@@ -309,6 +313,12 @@ extern "C" DECLEXPORT(int) VBoxDriversRegister(PCPDMDRVREGCB pCallbacks, uint32_
return rc;
#endif
+#ifdef VBOX_WITH_PCI_PASSTHROUGH_IMPL
+ rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvPciRaw);
+ if (RT_FAILURED(rc))
+ return rc;
+#endif
+
return VINF_SUCCESS;
}
@@ -348,4 +358,3 @@ extern "C" DECLEXPORT(int) VBoxUsbRegister(PCPDMUSBREGCB pCallbacks, uint32_t u3
return rc;
}
-
diff --git a/src/VBox/Devices/build/VBoxDD.h b/src/VBox/Devices/build/VBoxDD.h
index 86955920e..f2fb28a29 100644
--- a/src/VBox/Devices/build/VBoxDD.h
+++ b/src/VBox/Devices/build/VBoxDD.h
@@ -1,10 +1,10 @@
-/* $Id: VBoxDD.h $ */
+/* $Id: VBoxDD.h 37781 2011-07-05 13:35:29Z vboxsync $ */
/** @file
* Built-in drivers & devices (part 1) header.
*/
/*
- * 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;
@@ -83,7 +83,9 @@ extern const PDMDEVREG g_DeviceLsiLogicSAS;
#ifdef VBOX_WITH_EFI
extern const PDMDEVREG g_DeviceEFI;
#endif
+#ifdef VBOX_WITH_PCI_PASSTHROUGH_IMPL
extern const PDMDEVREG g_DevicePciRaw;
+#endif
extern const PDMDRVREG g_DrvMouseQueue;
extern const PDMDRVREG g_DrvKeyboardQueue;
@@ -99,6 +101,9 @@ extern const PDMDRVREG g_DrvISCSITransportTcp;
#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
extern const PDMDRVREG g_DrvHostInterface;
#endif
+#ifdef VBOX_WITH_UDPTUNNEL
+extern const PDMDRVREG g_DrvUDPTunnel;
+#endif
#ifdef VBOX_WITH_VDE
extern const PDMDRVREG g_DrvVDE;
#endif
diff --git a/src/VBox/Devices/build/VBoxDD2.h b/src/VBox/Devices/build/VBoxDD2.h
index cef579d25..58d9150cf 100644
--- a/src/VBox/Devices/build/VBoxDD2.h
+++ b/src/VBox/Devices/build/VBoxDD2.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxDD2.h $ */
+/* $Id: VBoxDD2.h 35400 2011-01-04 11:58:52Z vboxsync $ */
/** @file
* Built-in drivers & devices part 2 header.
*
diff --git a/src/VBox/Devices/build/VBoxDD2R0.cpp b/src/VBox/Devices/build/VBoxDD2R0.cpp
new file mode 100644
index 000000000..ce2b5d323
--- /dev/null
+++ b/src/VBox/Devices/build/VBoxDD2R0.cpp
@@ -0,0 +1,31 @@
+/* $Id $ */
+/** @file
+ * VBoxDD2R0 - Built-in drivers & devices (part 2), ring-0 module.
+ */
+
+/*
+ * 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/types.h>
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+#if defined(RT_OS_SOLARIS) && defined(IN_RING0)
+/* Dependency information for the native solaris loader. */
+extern "C" { char _depends_on[] = "vboxdrv VMMR0.r0"; }
+#endif
+
diff --git a/src/VBox/Devices/build/VBoxDDR0.cpp b/src/VBox/Devices/build/VBoxDDR0.cpp
new file mode 100644
index 000000000..c715900a3
--- /dev/null
+++ b/src/VBox/Devices/build/VBoxDDR0.cpp
@@ -0,0 +1,31 @@
+/* $Id $ */
+/** @file
+ * VBoxDDR0 - Built-in drivers & devices (part 1), ring-0 module.
+ */
+
+/*
+ * 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/types.h>
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+#if defined(RT_OS_SOLARIS) && defined(IN_RING0)
+/* Dependency information for the native solaris loader. */
+extern "C" { char _depends_on[] = "vboxdrv VMMR0.r0"; }
+#endif
+
diff --git a/src/VBox/Devices/build/VBoxDDUDeps.cpp b/src/VBox/Devices/build/VBoxDDUDeps.cpp
index a614cef12..8372e8973 100644
--- a/src/VBox/Devices/build/VBoxDDUDeps.cpp
+++ b/src/VBox/Devices/build/VBoxDDUDeps.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxDDUDeps.cpp $ */
+/* $Id: VBoxDDUDeps.cpp 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* VBoxDDU - For dragging in library objects.
*/
diff --git a/src/VBox/Devices/build/vl_vbox.h b/src/VBox/Devices/build/vl_vbox.h
index ecf26a608..219954289 100644
--- a/src/VBox/Devices/build/vl_vbox.h
+++ b/src/VBox/Devices/build/vl_vbox.h
@@ -1,4 +1,4 @@
-/* $Id: vl_vbox.h $ */
+/* $Id: vl_vbox.h 35353 2010-12-27 17:25:52Z vboxsync $ */
/** @file
* VBox vl.h Replacement.
*
diff --git a/src/VBox/Devices/testcase/Makefile.kmk b/src/VBox/Devices/testcase/Makefile.kmk
index 4a5ba2ec7..1e3d21933 100644
--- a/src/VBox/Devices/testcase/Makefile.kmk
+++ b/src/VBox/Devices/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37781 2011-07-05 13:35:29Z vboxsync $
## @file
# Sub-Makefile for the device testcases.
#
@@ -28,7 +28,7 @@ BLDDIRS += $(VBOX_DEVICES_TEST_OUT_DIR)
VBOX_DEVICES_TESTS_FEATURES = \
$(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,) \
$(if $(VBOX_WITH_USB),VBOX_WITH_USB,) \
- $(if $(VBOX_WITH_EHCI),VBOX_WITH_EHCI,) \
+ $(if $(VBOX_WITH_EHCI_IMPL),VBOX_WITH_EHCI_IMPL,) \
$(if $(VBOX_WITH_AHCI),VBOX_WITH_AHCI,) \
$(if $(VBOX_WITH_E1000),VBOX_WITH_E1000,) \
$(if $(VBOX_WITH_VIRTIO),VBOX_WITH_VIRTIO,) \
@@ -39,7 +39,9 @@ VBOX_DEVICES_TESTS_FEATURES = \
$(if $(VBOX_WITH_CRHGSMI),VBOX_WITH_CRHGSMI,) \
$(if $(VBOX_WITH_VDMA),VBOX_WITH_VDMA,) \
$(if $(VBOX_WITH_WDDM),VBOX_WITH_WDDM,) \
- $(if $(VBOX_WITH_VIDEOHWACCEL),VBOX_WITH_VIDEOHWACCEL,)
+ $(if $(VBOX_WITH_VIDEOHWACCEL),VBOX_WITH_VIDEOHWACCEL,) \
+ $(if $(VBOX_WITH_PCI_PASSTHROUGH_IMPL),VBOX_WITH_PCI_PASSTHROUGH_IMPL,)
+
#
# We setup one 'other' target for executing the structure & alignment
diff --git a/src/VBox/Devices/testcase/tstDeviceStructSize.cpp b/src/VBox/Devices/testcase/tstDeviceStructSize.cpp
index 804e4c2c8..aafb8a627 100644
--- a/src/VBox/Devices/testcase/tstDeviceStructSize.cpp
+++ b/src/VBox/Devices/testcase/tstDeviceStructSize.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstDeviceStructSize.cpp $ */
+/* $Id: tstDeviceStructSize.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* tstDeviceStructSize - testcase for check structure sizes/alignment
* and to verify that HC and RC uses the same
@@ -21,7 +21,7 @@
* Header Files *
*******************************************************************************/
#include <VBox/types.h>
-#include <VBox/x86.h>
+#include <iprt/x86.h>
#define VBOX_WITH_HGCM /* grumble */
@@ -29,6 +29,8 @@
#undef LOG_GROUP
#include "../Bus/DevPCI.cpp"
#undef LOG_GROUP
+#include "../Bus/DevPciIch9.cpp"
+#undef LOG_GROUP
#include "../Graphics/DevVGA.cpp"
#undef LOG_GROUP
#include "../Input/DevPS2.cpp"
@@ -53,6 +55,8 @@
#undef LOG_GROUP
#include "../PC/DevAPIC.cpp"
#undef LOG_GROUP
+#include "../PC/DevIoApic.cpp"
+#undef LOG_GROUP
#include "../PC/DevHPET.cpp"
#undef LOG_GROUP
#include "../PC/DevLPC.cpp"
@@ -63,7 +67,7 @@
#ifdef VBOX_WITH_USB
# undef LOG_GROUP
# include "../USB/DevOHCI.cpp"
-# ifdef VBOX_WITH_EHCI
+# ifdef VBOX_WITH_EHCI_IMPL
# include "../USB/DevEHCI.cpp"
# endif
#endif
@@ -86,6 +90,11 @@
# include "../Storage/DevLsiLogicSCSI.cpp"
#endif
+#ifdef VBOX_WITH_PCI_PASSTHROUGH_IMPL
+# undef LOG_GROUP
+# include "../Bus/DevPciRaw.cpp"
+#endif
+
#include <stdio.h>
@@ -275,7 +284,7 @@ int main()
#endif
//CHECK_MEMBER_ALIGNMENT(E1KSTATE, csTx, 8);
#ifdef VBOX_WITH_USB
-# ifdef VBOX_WITH_EHCI
+# ifdef VBOX_WITH_EHCI_IMPL
CHECK_MEMBER_ALIGNMENT(EHCI, RootHub, 8);
# ifdef VBOX_WITH_STATISTICS
CHECK_MEMBER_ALIGNMENT(EHCI, StatCanceledIsocUrbs, 8);
@@ -316,6 +325,9 @@ int main()
CHECK_MEMBER_ALIGNMENT(VPCISTATE, led, 4);
CHECK_MEMBER_ALIGNMENT(VPCISTATE, Queues, 8);
#endif
+#ifdef VBOX_WITH_PCI_PASSTHROUGH_IMPL
+ CHECK_MEMBER_ALIGNMENT(PCIRAWSENDREQ, u.aGetRegionInfo.u64RegionSize, 8);
+#endif
#ifdef VBOX_WITH_RAW_MODE
/*
@@ -334,4 +346,3 @@ int main()
printf("tstDeviceStructSize: SUCCESS\n");
return rc;
}
-
diff --git a/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp b/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
index 1bee096f5..d5f260c8e 100644
--- a/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
+++ b/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstDeviceStructSizeRC.cpp $ */
+/* $Id: tstDeviceStructSizeRC.cpp 37752 2011-07-04 10:02:23Z vboxsync $ */
/** @file
* tstDeviceStructSizeGC - Generate structure member and size checks from the RC perspective.
*
@@ -38,6 +38,8 @@
#undef LOG_GROUP
#include "../Bus/DevPCI.cpp" /* must be first! */
#undef LOG_GROUP
+#include "../Bus/DevPciIch9.cpp"
+#undef LOG_GROUP
#include "../Graphics/DevVGA.cpp"
#undef LOG_GROUP
#include "../Input/DevPS2.cpp"
@@ -54,11 +56,13 @@
#undef LOG_GROUP
#include "../PC/DevAPIC.cpp"
#undef LOG_GROUP
+#include "../PC/DevIoApic.cpp"
+#undef LOG_GROUP
#include "../Storage/DevATA.cpp"
#ifdef VBOX_WITH_USB
# undef LOG_GROUP
# include "../USB/DevOHCI.cpp"
-# ifdef VBOX_WITH_EHCI
+# ifdef VBOX_WITH_EHCI_IMPL
# include "../USB/DevEHCI.cpp"
# endif
#endif
@@ -136,7 +140,7 @@ int main()
GEN_CHECK_OFF(PCIDEVICE, Int.s.pBusRC);
GEN_CHECK_OFF(PCIDEVICE, Int.s.pfnConfigRead);
GEN_CHECK_OFF(PCIDEVICE, Int.s.pfnConfigWrite);
- GEN_CHECK_OFF(PCIDEVICE, Int.s.uFlags);
+ GEN_CHECK_OFF(PCIDEVICE, Int.s.fFlags);
GEN_CHECK_OFF(PCIDEVICE, Int.s.uIrqPinState);
GEN_CHECK_OFF(PCIDEVICE, Int.s.pfnBridgeConfigRead);
GEN_CHECK_OFF(PCIDEVICE, Int.s.pfnBridgeConfigWrite);
@@ -173,6 +177,34 @@ int main()
GEN_CHECK_OFF(PCIGLOBALS, PIIX3State);
GEN_CHECK_OFF(PCIGLOBALS, PciBus);
+ /* DevPciIch9.cpp */
+ GEN_CHECK_SIZE(ICH9PCIBUS);
+ GEN_CHECK_OFF(ICH9PCIBUS, iBus);
+ GEN_CHECK_OFF(ICH9PCIBUS, cBridges);
+ GEN_CHECK_OFF(ICH9PCIBUS, apDevices);
+ GEN_CHECK_OFF(ICH9PCIBUS, apDevices[1]);
+ GEN_CHECK_OFF(ICH9PCIBUS, pDevInsR3);
+ GEN_CHECK_OFF(ICH9PCIBUS, pPciHlpR3);
+ GEN_CHECK_OFF(ICH9PCIBUS, papBridgesR3);
+ GEN_CHECK_OFF(ICH9PCIBUS, pDevInsR0);
+ GEN_CHECK_OFF(ICH9PCIBUS, pPciHlpR0);
+ GEN_CHECK_OFF(ICH9PCIBUS, pDevInsRC);
+ GEN_CHECK_OFF(ICH9PCIBUS, pPciHlpRC);
+ GEN_CHECK_OFF(ICH9PCIBUS, aPciDev);
+ GEN_CHECK_SIZE(ICH9PCIGLOBALS);
+ GEN_CHECK_OFF(ICH9PCIGLOBALS, pDevInsR3);
+ GEN_CHECK_OFF(ICH9PCIGLOBALS, pDevInsR0);
+ GEN_CHECK_OFF(ICH9PCIGLOBALS, pDevInsRC);
+ GEN_CHECK_OFF(ICH9PCIGLOBALS, uConfigReg);
+ GEN_CHECK_OFF(ICH9PCIGLOBALS, uaPciApicIrqLevels);
+ GEN_CHECK_OFF(ICH9PCIGLOBALS, uaPciApicIrqLevels[1]);
+ GEN_CHECK_OFF(ICH9PCIGLOBALS, uPciBiosIo);
+ GEN_CHECK_OFF(ICH9PCIGLOBALS, uPciBiosMmio);
+ GEN_CHECK_OFF(ICH9PCIGLOBALS, uBus);
+ GEN_CHECK_OFF(ICH9PCIGLOBALS, u64PciConfigMMioAddress);
+ GEN_CHECK_OFF(ICH9PCIGLOBALS, u64PciConfigMMioLength);
+ GEN_CHECK_OFF(ICH9PCIGLOBALS, aPciBus);
+
/* DevVGA.cpp */
GEN_CHECK_SIZE(VGASTATE);
GEN_CHECK_OFF(VGASTATE, vram_ptrR3);
@@ -450,9 +482,9 @@ int main()
GEN_CHECK_OFF(ACPIState, pm1a_sts);
GEN_CHECK_OFF(ACPIState, pm1a_ctl);
GEN_CHECK_OFF(ACPIState, u64PmTimerInitial);
- GEN_CHECK_OFF(ACPIState, tsR3);
- GEN_CHECK_OFF(ACPIState, tsR0);
- GEN_CHECK_OFF(ACPIState, tsRC);
+ GEN_CHECK_OFF(ACPIState, pPmTimerR3);
+ GEN_CHECK_OFF(ACPIState, pPmTimerR0);
+ GEN_CHECK_OFF(ACPIState, pPmTimerRC);
GEN_CHECK_OFF(ACPIState, gpe0_en);
GEN_CHECK_OFF(ACPIState, gpe0_sts);
GEN_CHECK_OFF(ACPIState, uBatteryIndex);
@@ -588,7 +620,7 @@ int main()
GEN_CHECK_OFF(RTCState, CurLogPeriod);
GEN_CHECK_OFF(RTCState, CurHintPeriod);
- /* PC/apic.c */
+ /* PC/DevAPIC.cpp */
GEN_CHECK_SIZE(APICState);
GEN_CHECK_OFF(APICState, apicbase);
GEN_CHECK_OFF(APICState, id);
@@ -647,6 +679,7 @@ int main()
GEN_CHECK_OFF(APICDeviceInfo, StatMMIOWriteHC);
#endif
+ /* PC/DevIoApic.cpp */
GEN_CHECK_SIZE(IOAPICState);
GEN_CHECK_OFF(IOAPICState, id);
GEN_CHECK_OFF(IOAPICState, ioregsel);
@@ -895,7 +928,7 @@ int main()
GEN_CHECK_OFF(OHCI, StatDroppedUrbs);
GEN_CHECK_OFF(OHCI, StatTimer);
# endif
-# ifdef VBOX_WITH_EHCI
+# ifdef VBOX_WITH_EHCI_IMPL
/* USB/DevEHCI.cpp */
GEN_CHECK_SIZE(EHCIHUBPORT);
GEN_CHECK_OFF(EHCIHUBPORT, fReg);
@@ -972,7 +1005,7 @@ int main()
GEN_CHECK_OFF(EHCI, pEOFTimerNoSyncRC);
GEN_CHECK_OFF(EHCI, pEOFTimerNoSyncR3);
GEN_CHECK_OFF(EHCI, pEOFTimerNoSyncR0);
-# endif /* VBOX_WITH_EHCI */
+# endif /* VBOX_WITH_EHCI_IMPL */
#endif /* VBOX_WITH_USB */
/* VMMDev/VBoxDev.cpp */
@@ -1207,6 +1240,8 @@ int main()
GEN_CHECK_OFF(AHCIPort, fPortReset);
GEN_CHECK_OFF(AHCIPort, fAsyncInterface);
GEN_CHECK_OFF(AHCIPort, fResetDevice);
+ GEN_CHECK_OFF(AHCIPort, fAsyncIOThreadIdle);
+ GEN_CHECK_OFF(AHCIPort, fRedo);
GEN_CHECK_OFF(AHCIPort, cTotalSectors);
GEN_CHECK_OFF(AHCIPort, cMultSectors);
GEN_CHECK_OFF(AHCIPort, uATATransferMode);
@@ -1276,6 +1311,7 @@ int main()
GEN_CHECK_OFF(AHCI, regHbaVs);
GEN_CHECK_OFF(AHCI, regHbaCccCtl);
GEN_CHECK_OFF(AHCI, regHbaCccPorts);
+ GEN_CHECK_OFF(AHCI, regIdx);
GEN_CHECK_OFF(AHCI, pHbaCccTimerR3);
GEN_CHECK_OFF(AHCI, pHbaCccTimerR0);
GEN_CHECK_OFF(AHCI, pHbaCccTimerRC);
@@ -1668,10 +1704,13 @@ int main()
GEN_CHECK_OFF(HpetState, pDevInsR0);
GEN_CHECK_OFF(HpetState, pDevInsRC);
GEN_CHECK_OFF(HpetState, u64HpetOffset);
- GEN_CHECK_OFF(HpetState, u64Capabilities);
+ GEN_CHECK_OFF(HpetState, u32Capabilities);
+ GEN_CHECK_OFF(HpetState, u32Period);
GEN_CHECK_OFF(HpetState, u64HpetConfig);
GEN_CHECK_OFF(HpetState, u64Isr);
GEN_CHECK_OFF(HpetState, u64HpetCounter);
+ GEN_CHECK_OFF(HpetState, csLock);
+ GEN_CHECK_OFF(HpetState, fIch9);
GEN_CHECK_SIZE(HpetTimer);
GEN_CHECK_OFF(HpetTimer, pTimerR3);
@@ -1680,7 +1719,7 @@ int main()
GEN_CHECK_OFF(HpetTimer, pHpetR0);
GEN_CHECK_OFF(HpetTimer, pTimerRC);
GEN_CHECK_OFF(HpetTimer, pHpetRC);
- GEN_CHECK_OFF(HpetTimer, u8TimerNumber);
+ GEN_CHECK_OFF(HpetTimer, idxTimer);
GEN_CHECK_OFF(HpetTimer, u64Config);
GEN_CHECK_OFF(HpetTimer, u64Cmp);
GEN_CHECK_OFF(HpetTimer, u64Fsb);
diff --git a/src/VBox/Disassembler/DisasmFormatBytes.cpp b/src/VBox/Disassembler/DisasmFormatBytes.cpp
index 2046fe0d3..f7c1ed70e 100644
--- a/src/VBox/Disassembler/DisasmFormatBytes.cpp
+++ b/src/VBox/Disassembler/DisasmFormatBytes.cpp
@@ -1,4 +1,4 @@
-/* $Id: DisasmFormatBytes.cpp $ */
+/* $Id: DisasmFormatBytes.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox Disassembler - Helper for formatting the opcode bytes.
*/
diff --git a/src/VBox/Disassembler/DisasmFormatYasm.cpp b/src/VBox/Disassembler/DisasmFormatYasm.cpp
index 4ad0a153d..792f55795 100644
--- a/src/VBox/Disassembler/DisasmFormatYasm.cpp
+++ b/src/VBox/Disassembler/DisasmFormatYasm.cpp
@@ -1,4 +1,4 @@
-/* $Id: DisasmFormatYasm.cpp $ */
+/* $Id: DisasmFormatYasm.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox Disassembler - Yasm(/Nasm) Style Formatter.
*/
diff --git a/src/VBox/Disassembler/DisasmTables.cpp b/src/VBox/Disassembler/DisasmTables.cpp
index 198715513..62907c4a2 100644
--- a/src/VBox/Disassembler/DisasmTables.cpp
+++ b/src/VBox/Disassembler/DisasmTables.cpp
@@ -453,10 +453,10 @@ const OPCODE g_aTwoByteMapX86[256] =
OP("sysenter", 0, 0, 0, OP_SYSENTER,OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_CONTROLFLOW),
OP("sysexit", 0, 0, 0, OP_SYSEXIT, OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_CONTROLFLOW | OPTYPE_UNCOND_CONTROLFLOW),
INVALID_OPCODE,
- INVALID_OPCODE,
+ INVALID_OPCODE, /** 0x37 - GETSEC */
OP("3 byte escape A4", IDX_ParseThreeByteEsc4,0, 0, OP_3B_ESC4, OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS),
INVALID_OPCODE,
- INVALID_OPCODE,
+ INVALID_OPCODE, /** 0x3A - 3-byte escape table A-5 */
INVALID_OPCODE,
/* SSE2 */
OP("movnti %Gv,%Ev", IDX_ParseModRM, IDX_UseModRM, 0, OP_MOVNTI, OP_PARM_Gv, OP_PARM_Ev, OP_PARM_NONE, OPTYPE_HARMLESS),
@@ -513,8 +513,8 @@ const OPCODE g_aTwoByteMapX86[256] =
OP("punpckhwd %Pq,%Qd", IDX_ParseModRM, IDX_UseModRM, 0, OP_PUNPCKHWD, OP_PARM_Pq, OP_PARM_Qd, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("punpckhdq %Pq,%Qd", IDX_ParseModRM, IDX_UseModRM, 0, OP_PUNPCKHDQ, OP_PARM_Pq, OP_PARM_Qd, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("packssdw %Pq,%Qd", IDX_ParseModRM, IDX_UseModRM, 0, OP_PACKSSDW,OP_PARM_Pq, OP_PARM_Qd, OP_PARM_NONE, OPTYPE_HARMLESS),
- INVALID_OPCODE,
- INVALID_OPCODE,
+ INVALID_OPCODE, /** @todo 0x0f 0x6c punpcklqdq Vdq,Wdq */
+ INVALID_OPCODE, /** @todo 0x0f 0x6d punpckhqdq Vdq,Wdq */
OP("movd %Pd,%Ed", IDX_ParseModRM, IDX_UseModRM, 0, OP_MOVD, OP_PARM_Pd, OP_PARM_Ed, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("movq %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_MOVQ, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
@@ -527,12 +527,12 @@ const OPCODE g_aTwoByteMapX86[256] =
OP("pcmpeqw %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PCMPEQW, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("pcmpeqd %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PCMPEQD, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("emms", 0, 0, 0, OP_EMMS, OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS),
- OP("MMX UD 0x78", 0, 0, 0, OP_MMX_UD78,OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS),
- OP("MMX UD 0x79", 0, 0, 0, OP_MMX_UD79,OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS),
+ OP("MMX UD 0x78", 0, 0, 0, OP_MMX_UD78,OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS), /** @todo 0x0f 0x78 VMREAD */
+ OP("MMX UD 0x79", 0, 0, 0, OP_MMX_UD79,OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS), /** @todo 0x0f 0x79 VMWRITE */
OP("MMX UD 0x7A", 0, 0, 0, OP_MMX_UD7A,OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("MMX UD 0x7B", 0, 0, 0, OP_MMX_UD7B,OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS),
- OP("MMX UD 0x7C", 0, 0, 0, OP_MMX_UD7C,OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS),
- OP("MMX UD 0x7D", 0, 0, 0, OP_MMX_UD7D,OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS),
+ OP("MMX UD 0x7C", 0, 0, 0, OP_MMX_UD7C,OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS), /** @todo 0x0f 0x7c haddpd/haddps */
+ OP("MMX UD 0x7D", 0, 0, 0, OP_MMX_UD7D,OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS), /** @todo 0x0f 0x7d hsubpd/hsubps */
OP("movd %Ed,%Pd", IDX_ParseModRM, IDX_UseModRM, 0, OP_MOVD, OP_PARM_Ed, OP_PARM_Pd, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("movq %Qq,%Pq", IDX_ParseModRM, IDX_UseModRM, 0, OP_MOVQ, OP_PARM_Qq, OP_PARM_Pq, OP_PARM_NONE, OPTYPE_HARMLESS),
@@ -599,7 +599,7 @@ const OPCODE g_aTwoByteMapX86[256] =
OP("lgs %Gv,%Mp", IDX_ParseModRM, IDX_UseModRM, 0, OP_LGS, OP_PARM_Gv, OP_PARM_Mp, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("movzx %Gv,%Eb", IDX_ParseModRM, IDX_UseModRM, 0, OP_MOVZX, OP_PARM_Gv, OP_PARM_Eb, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("movzx %Gv,%Ew", IDX_ParseModRM, IDX_UseModRM, 0, OP_MOVZX, OP_PARM_Gv, OP_PARM_Ew, OP_PARM_NONE, OPTYPE_HARMLESS),
- INVALID_OPCODE,
+ INVALID_OPCODE, /** @todo 0x0f 0xb8 popcnt Gv,Ev / jmpe */
OP("Grp10 Invalid Op", IDX_ParseGrp10, 0, 0, OP_GRP10_INV,OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("Grp8", IDX_ParseGrp8, 0, 0, OP_GRP8, OP_PARM_Ev, OP_PARM_Ib, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("btc %Ev,%Gv", IDX_ParseModRM, IDX_UseModRM, 0, OP_BTC, OP_PARM_Ev, OP_PARM_Gv, OP_PARM_NONE, OPTYPE_HARMLESS),
@@ -628,13 +628,13 @@ const OPCODE g_aTwoByteMapX86[256] =
OP("bswap EDI", IDX_ParseFixedReg, 0, 0, OP_BSWAP, OP_PARM_REG_EDI, OP_PARM_NONE, OP_PARM_NONE, OPTYPE_HARMLESS | OPTYPE_REXB_EXTENDS_OPREG),
/* d */
- INVALID_OPCODE,
+ INVALID_OPCODE, /** @todo 0x0f 0xd0 addsubpd/addsubps */
OP("psrlw %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSRLW, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("psrld %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSRLD, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("psrlq %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSRLQ, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("paddq %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PADDQ, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("pmullw %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PMULLW, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
- INVALID_OPCODE,
+ INVALID_OPCODE, /** @todo 0x0f 0xd7 pmovmskb/pmovmskb */
OP("pmovskb %Gd,%Pq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PMOVSKB, OP_PARM_Gd, OP_PARM_Pq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("psubusb %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSUBUSB, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("psubusw %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSUBUSW, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
@@ -652,7 +652,7 @@ const OPCODE g_aTwoByteMapX86[256] =
OP("pavgw %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PAVGW, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("pmulhuw %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PMULHUW, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("pmulhw %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PMULHW, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
- INVALID_OPCODE,
+ INVALID_OPCODE, /** @todo 0x0f 0xe6 cvtpd2dq// */
OP("movntq %Wq,%Vq", IDX_ParseModRM, IDX_UseModRM, 0, OP_MOVNTQ, OP_PARM_Wq, OP_PARM_Vq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("psubsb %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSUBSB, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("psubsw %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSUBSW, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
@@ -664,7 +664,7 @@ const OPCODE g_aTwoByteMapX86[256] =
OP("pxor %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PXOR, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
/* f */
- INVALID_OPCODE,
+ INVALID_OPCODE, /** @todo 0x0f 0xf0 lddqu */
OP("psllw %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSLLW, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("pslld %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSLLD, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
OP("psllq %Pq,%Qq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSSQ, OP_PARM_Pq, OP_PARM_Qq, OP_PARM_NONE, OPTYPE_HARMLESS),
diff --git a/src/VBox/Disassembler/DisasmTestA.asm b/src/VBox/Disassembler/DisasmTestA.asm
index 48f587a14..592641678 100644
--- a/src/VBox/Disassembler/DisasmTestA.asm
+++ b/src/VBox/Disassembler/DisasmTestA.asm
@@ -1,4 +1,4 @@
-; $Id: DisasmTestA.asm $
+; $Id: DisasmTestA.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; VBox disassembler: Assembler test routines
;
@@ -22,7 +22,7 @@
%include "VBox/vmm/vm.mac"
%include "VBox/err.mac"
%include "VBox/vmm/stam.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
BITS 32
diff --git a/src/VBox/Disassembler/Makefile.kmk b/src/VBox/Disassembler/Makefile.kmk
index e69ed588f..50635311e 100644
--- a/src/VBox/Disassembler/Makefile.kmk
+++ b/src/VBox/Disassembler/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the VBox Disassembler.
#
diff --git a/src/VBox/Disassembler/testcase/Makefile.kmk b/src/VBox/Disassembler/testcase/Makefile.kmk
index d5ca401fb..38ac657f4 100644
--- a/src/VBox/Disassembler/testcase/Makefile.kmk
+++ b/src/VBox/Disassembler/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35381 2010-12-30 16:12:47Z vboxsync $
## @file
# Sub-Makefile for the VBox Disassembler.
#
diff --git a/src/VBox/Disassembler/testcase/tstAsm.mac b/src/VBox/Disassembler/testcase/tstAsm.mac
index 0854d8615..ad135c9bb 100644
--- a/src/VBox/Disassembler/testcase/tstAsm.mac
+++ b/src/VBox/Disassembler/testcase/tstAsm.mac
@@ -1,4 +1,4 @@
-; $Id: tstAsm.mac $
+; $Id: tstAsm.mac 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; Disassembly testcase - Common header for the xREG macros.
;
diff --git a/src/VBox/Disassembler/testcase/tstAsmFnstsw-1.asm b/src/VBox/Disassembler/testcase/tstAsmFnstsw-1.asm
index 71416661b..61662310b 100644
--- a/src/VBox/Disassembler/testcase/tstAsmFnstsw-1.asm
+++ b/src/VBox/Disassembler/testcase/tstAsmFnstsw-1.asm
@@ -1,4 +1,4 @@
-; $Id: tstAsmLock-1.asm $
+; $Id: tstAsmLock-1.asm 60692 2010-04-27 08:22:32Z umoeller $
;; @file
; Disassembly testcase - Valid fnstsw* instructitons.
;
diff --git a/src/VBox/Disassembler/testcase/tstAsmLock-1.asm b/src/VBox/Disassembler/testcase/tstAsmLock-1.asm
index 533592011..7826591b7 100644
--- a/src/VBox/Disassembler/testcase/tstAsmLock-1.asm
+++ b/src/VBox/Disassembler/testcase/tstAsmLock-1.asm
@@ -1,4 +1,4 @@
-; $Id: tstAsmLock-1.asm $
+; $Id: tstAsmLock-1.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; Disassembly testcase - Valid lock sequences and related instructions.
;
diff --git a/src/VBox/Disassembler/testcase/tstAsmLock-2.asm b/src/VBox/Disassembler/testcase/tstAsmLock-2.asm
index f692b7e14..b050a6e5d 100644
--- a/src/VBox/Disassembler/testcase/tstAsmLock-2.asm
+++ b/src/VBox/Disassembler/testcase/tstAsmLock-2.asm
@@ -1,4 +1,4 @@
-; $Id: tstAsmLock-2.asm $
+; $Id: tstAsmLock-2.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; Disassembly testcase - Invalid invariants.
;
diff --git a/src/VBox/Disassembler/testcase/tstAsmLock-3.asm b/src/VBox/Disassembler/testcase/tstAsmLock-3.asm
index ece8485a4..c52573945 100644
--- a/src/VBox/Disassembler/testcase/tstAsmLock-3.asm
+++ b/src/VBox/Disassembler/testcase/tstAsmLock-3.asm
@@ -1,4 +1,4 @@
-; $Id: tstAsmLock-3.asm $
+; $Id: tstAsmLock-3.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; Disassembly testcase - Invalid lock sequences for non-locking instructions.
;
diff --git a/src/VBox/Disassembler/testcase/tstAsmMovSeg-1.asm b/src/VBox/Disassembler/testcase/tstAsmMovSeg-1.asm
index 8c6d0a5b1..5a4888822 100644
--- a/src/VBox/Disassembler/testcase/tstAsmMovSeg-1.asm
+++ b/src/VBox/Disassembler/testcase/tstAsmMovSeg-1.asm
@@ -1,4 +1,4 @@
-; $Id: tstAsmMovSeg-1.asm $
+; $Id: tstAsmMovSeg-1.asm 35474 2011-01-11 09:08:30Z vboxsync $
;; @file
; Disassembly testcase - Valid mov from/to segment instructions.
;
diff --git a/src/VBox/Disassembler/testcase/tstAsmMovzx-1.asm b/src/VBox/Disassembler/testcase/tstAsmMovzx-1.asm
index 57e72f13a..0cb415658 100644
--- a/src/VBox/Disassembler/testcase/tstAsmMovzx-1.asm
+++ b/src/VBox/Disassembler/testcase/tstAsmMovzx-1.asm
@@ -1,4 +1,4 @@
-; $Id: tstAsmMovzx-1.asm $
+; $Id: tstAsmMovzx-1.asm 35474 2011-01-11 09:08:30Z vboxsync $
;; @file
; Disassembly testcase - Valid movzx sequences and related instructions.
;
diff --git a/src/VBox/Disassembler/testcase/tstAsmPop-1.asm b/src/VBox/Disassembler/testcase/tstAsmPop-1.asm
index 25cae4eb4..f1af94b92 100644
--- a/src/VBox/Disassembler/testcase/tstAsmPop-1.asm
+++ b/src/VBox/Disassembler/testcase/tstAsmPop-1.asm
@@ -1,4 +1,4 @@
-; $Id: tstAsmPop-1.asm $
+; $Id: tstAsmPop-1.asm 35474 2011-01-11 09:08:30Z vboxsync $
;; @file
; Disassembly testcase - Valid pop sequences and related instructions.
;
diff --git a/src/VBox/Disassembler/testcase/tstAsmPush-1.asm b/src/VBox/Disassembler/testcase/tstAsmPush-1.asm
index 1c4286dc3..dd32571f8 100644
--- a/src/VBox/Disassembler/testcase/tstAsmPush-1.asm
+++ b/src/VBox/Disassembler/testcase/tstAsmPush-1.asm
@@ -1,4 +1,4 @@
-; $Id: tstAsmPush-1.asm $
+; $Id: tstAsmPush-1.asm 35474 2011-01-11 09:08:30Z vboxsync $
;; @file
; Disassembly testcase - Valid push sequences and related instructions.
;
diff --git a/src/VBox/Disassembler/testcase/tstAsmRegs-1.asm b/src/VBox/Disassembler/testcase/tstAsmRegs-1.asm
index daba0fadb..bb4543266 100644
--- a/src/VBox/Disassembler/testcase/tstAsmRegs-1.asm
+++ b/src/VBox/Disassembler/testcase/tstAsmRegs-1.asm
@@ -1,4 +1,4 @@
-; $Id: tstAsmRegs-1.asm $
+; $Id: tstAsmRegs-1.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; Disassembly testcase - Accessing all the registers
;
diff --git a/src/VBox/Disassembler/testcase/tstAsmSignExtend-1.asm b/src/VBox/Disassembler/testcase/tstAsmSignExtend-1.asm
index 97f5cf9c5..e8717e085 100644
--- a/src/VBox/Disassembler/testcase/tstAsmSignExtend-1.asm
+++ b/src/VBox/Disassembler/testcase/tstAsmSignExtend-1.asm
@@ -1,4 +1,4 @@
-; $Id: tstAsmSignExtend-1.asm $
+; $Id: tstAsmSignExtend-1.asm 35474 2011-01-11 09:08:30Z vboxsync $
;; @file
; Disassembly testcase - Valid sign extension instructions.
;
diff --git a/src/VBox/Disassembler/testcase/tstDisasm-2.cpp b/src/VBox/Disassembler/testcase/tstDisasm-2.cpp
index 670d1f5f5..64aacbd1a 100644
--- a/src/VBox/Disassembler/testcase/tstDisasm-2.cpp
+++ b/src/VBox/Disassembler/testcase/tstDisasm-2.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstDisasm-2.cpp $ */
+/* $Id: tstDisasm-2.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Testcase - Generic Disassembler Tool.
*/
diff --git a/src/VBox/ExtPacks/BusMouseSample/BusMouse.cpp b/src/VBox/ExtPacks/BusMouseSample/BusMouse.cpp
new file mode 100644
index 000000000..069ed6364
--- /dev/null
+++ b/src/VBox/ExtPacks/BusMouseSample/BusMouse.cpp
@@ -0,0 +1,886 @@
+/* $Id: BusMouse.cpp 35683 2011-01-24 15:28:09Z vboxsync $ */
+/** @file
+ * BusMouse - Microsoft Bus (parallel) mouse controller device.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_DEV_KBD
+#include "vl_vbox.h"
+#include <VBox/vmm/pdmdev.h>
+#include <iprt/assert.h>
+#include <iprt/uuid.h>
+
+#include "VBoxDD.h"
+
+/* The Microsoft Bus Mouse was an early mouse sold by Microsoft, originally
+ * introduced in 1983. The mouse had a D-shaped 9-pin connector which plugged
+ * into a small ISA add-in board.
+ * The mouse itself was very simple (compared to a serial mouse) and most of
+ * the logic was located on the ISA board. Later, Microsoft sold an InPort
+ * mouse, which was also called a "bus mouse", but used a different interface.
+ *
+ * Microsoft part numbers for the Bus Mouse were 037-099 (100 ppi)
+ * and 037-199 (200 ppi).
+ *
+ * The Bus Mouse adapter included IRQ configuration jumpers (ref. MS article
+ * Q12230). The IRQ could be set to one of 2, 3, 4, 5. The typical setting
+ * would be IRQ 2 for a PC/XT and IRQ 5 for an AT compatible. Because IRQ 5
+ * may conflict with a SoundBlaster or a PCI device, this device defaults to
+ * IRQ 3. Note that IRQ 3 is also used by the COM 2 device, not often needed.
+ *
+ * The ISA adapter was built around an Intel 8255A compatible chip (ref.
+ * MS article Q46369). Once enabled, the adapter raises the configured IRQ
+ * 30 times per second; the rate is not configurable. The interrupts
+ * occur regardless of whether the mouse state has changed or not.
+ *
+ * To function properly, the 8255A must be programmed as follows:
+ * - Port A: Input. Used to read motion deltas and button states.
+ * - Port B: Output. Not used except for mouse detection.
+ * - Port C: Split. Upper bits set as output, used for control purposes.
+ * Lower bits set as input, reflecting IRQ state.
+ *
+ * Detailed information was gleaned from Windows and OS/2 DDK mouse samples.
+ */
+
+/* The original bus mouse controller is fixed at I/O port 0x23C. */
+#define BMS_IO_BASE 0x23C
+#define BMS_IO_SIZE 4
+
+/* Offsets relative to the I/O base. */
+#define BMS_PORT_DATA 0 /* 8255 Port A. */
+#define BMS_PORT_SIG 1 /* 8255 Port B. */
+#define BMS_PORT_CTRL 2 /* 8255 Port C. */
+#define BMS_PORT_INIT 3 /* 8255 Control Port. */
+
+/* Port C bits (control port). */
+#define BMS_CTL_INT_DIS RT_BIT(4) /* Disable IRQ (else enabled). */
+#define BMS_CTL_SEL_HIGH RT_BIT(5) /* Select hi nibble (else lo). */
+#define BMS_CTL_SEL_Y RT_BIT(6) /* Select X to read (else Y). */
+#define BMS_CTL_HOLD RT_BIT(7) /* Hold counter (else clear). */
+
+/* Port A bits (data port). */
+#define BMS_DATA_DELTA 0x0F /* Motion delta in lower nibble. */
+#define BMS_DATA_B3_UP RT_BIT(5) /* Button 3 (right) is up. */
+#define BMS_DATA_B2_UP RT_BIT(6) /* Button 2 (middle) is up. */
+#define BMS_DATA_B1_UP RT_BIT(7) /* Button 1 (left) is up. */
+
+/* Convert IRQ level (2/3/4/5) to a bit in the control register. */
+#define BMS_IRQ_BIT(a) (1 << (5 - a))
+
+/* IRQ period, corresponds to approx. 30 Hz. */
+#define BMS_IRQ_PERIOD_MS 34
+
+/* Default IRQ setting. */
+#define BMS_DEFAULT_IRQ 3
+
+#define BMS_SAVED_STATE_VERSION 1
+
+
+typedef struct MouState {
+ /* 8255A state */
+ uint8_t port_a;
+ uint8_t port_b;
+ uint8_t port_c;
+ uint8_t ctrl_port;
+ uint8_t cnt_held; /* Counters held for reading. */
+ uint8_t held_dx;
+ uint8_t held_dy;
+ uint8_t irq; /* The "jumpered" IRQ level. */
+ int32_t irq_toggle_counter;
+ /** Mouse timer handle - HC. */
+ PTMTIMERR3 MouseTimer;
+ /** Timer period in milliseconds. */
+ uint32_t cTimerPeriodMs;
+ /* mouse state */
+ int32_t disable_counter;
+ uint8_t mouse_enabled;
+ int32_t mouse_dx; /* current values, needed for 'poll' mode */
+ int32_t mouse_dy;
+ uint8_t mouse_buttons;
+ uint8_t mouse_buttons_reported;
+
+ /** Pointer to the device instance - RC. */
+ PPDMDEVINSRC pDevInsRC;
+ /** Pointer to the device instance - R3 . */
+ PPDMDEVINSR3 pDevInsR3;
+ /** Pointer to the device instance. */
+ PPDMDEVINSR0 pDevInsR0;
+ /** Critical section protecting the state. */
+ PDMCRITSECT CritSect;
+ /**
+ * Mouse port - LUN#0.
+ *
+ * @implements PDMIBASE
+ * @implements PDMIMOUSEPORT
+ */
+ struct
+ {
+ /** The base interface for the mouse port. */
+ PDMIBASE IBase;
+ /** The mouse port base interface. */
+ PDMIMOUSEPORT IPort;
+
+ /** The base interface of the attached mouse driver. */
+ R3PTRTYPE(PPDMIBASE) pDrvBase;
+ /** The mouse interface of the attached mouse driver. */
+ R3PTRTYPE(PPDMIMOUSECONNECTOR) pDrv;
+ } Mouse;
+} MouState;
+
+#ifndef VBOX_DEVICE_STRUCT_TESTCASE
+
+#ifdef IN_RING3
+
+/* Report a change in status down the driver chain.
+ * We want to report the mouse as enabled if and only if the guest
+ * is "using" it. That way, other devices (e.g. a PS/2 or USB mouse)
+ * can receive mouse events when the bus mouse is disabled.
+ * Enabling interrupts constitutes enabling the bus mouse. The mouse
+ * is considered disabled if interrupts are disabled for several
+ * consecutive mouse timer ticks; this is because the interrupt handler
+ * in the guest typically temporarily disables interrupts and we do not
+ * want to toggle the enabled/disabled state more often than necessary.
+ */
+static void bms_update_downstream_status(MouState *pThis)
+{
+ PPDMIMOUSECONNECTOR pDrv = pThis->Mouse.pDrv;
+ bool fEnabled = !!pThis->mouse_enabled;
+ pDrv->pfnReportModes(pDrv, fEnabled, false);
+}
+
+/* Set the emulated hardware to a known initial state. */
+static void bms_reset(void *opaque)
+{
+ MouState *s = (MouState*)opaque;
+
+ /* Clear the device setup. */
+ s->port_a = s->port_b = 0;
+ s->port_c = BMS_CTL_INT_DIS; /* Interrupts disabled. */
+ s->ctrl_port = 0x91; /* Default 8255A setup. */
+
+ /* Clear motion/button state. */
+ s->cnt_held = false;
+ s->mouse_dx = s->mouse_dy = 0;
+ s->mouse_buttons = 0;
+ s->mouse_buttons_reported = 0;
+ s->disable_counter = 0;
+ s->irq_toggle_counter = 1000;
+
+ if (s->mouse_enabled)
+ {
+ s->mouse_enabled = false;
+ bms_update_downstream_status(s);
+ }
+}
+
+/* Process a mouse event coming from the host. */
+static void bms_mouse_event(void *opaque, int dx, int dy, int dz, int dw,
+ int buttons_state)
+{
+ MouState *s = (MouState*)opaque;
+
+ LogRel3(("%s: dx=%d, dy=%d, dz=%d, dw=%d, buttons_state=0x%x\n",
+ __PRETTY_FUNCTION__, dx, dy, dz, dw, buttons_state));
+
+ /* Only record X/Y movement and buttons. */
+ s->mouse_dx += dx;
+ s->mouse_dy += dy;
+ s->mouse_buttons = buttons_state;
+}
+
+static void bms_timer(void *opaque)
+{
+ MouState *s = (MouState*)opaque;
+ uint8_t irq_bit;
+
+ /* Toggle the IRQ line if interrupts are enabled. */
+ irq_bit = BMS_IRQ_BIT(s->irq);
+
+ if (s->port_c & irq_bit)
+ {
+ if (!(s->port_c & BMS_CTL_INT_DIS))
+ PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), s->irq, PDM_IRQ_LEVEL_LOW);
+ s->port_c &= ~irq_bit;
+ }
+ else
+ {
+ s->port_c |= irq_bit;
+ if (!(s->port_c & BMS_CTL_INT_DIS))
+ PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), s->irq, PDM_IRQ_LEVEL_HIGH);
+ }
+
+ /* Handle enabling/disabling of the mouse interface. */
+ if (s->port_c & BMS_CTL_INT_DIS)
+ {
+ if (s->disable_counter)
+ --s->disable_counter;
+
+ if (s->disable_counter == 0 && s->mouse_enabled)
+ {
+ s->mouse_enabled = false;
+ bms_update_downstream_status(s);
+ }
+ }
+ else
+ {
+ s->disable_counter = 8; /* Re-arm the disable countdown. */
+ if (!s->mouse_enabled)
+ {
+ s->mouse_enabled = true;
+ bms_update_downstream_status(s);
+ }
+ }
+}
+
+#endif /* IN_RING3 */
+
+static void bms_set_reported_buttons(MouState *s, unsigned fButtons, unsigned fButtonMask)
+{
+ s->mouse_buttons_reported |= (fButtons & fButtonMask);
+ s->mouse_buttons_reported &= (fButtons | ~fButtonMask);
+}
+
+/* Update the internal state after a write to port C. */
+static void bms_update_ctrl(MouState *s)
+{
+ int32_t dx, dy;
+
+ /* If the controller is in hold state, transfer data from counters. */
+ if (s->port_c & BMS_CTL_HOLD)
+ {
+ if (!s->cnt_held)
+ {
+ s->cnt_held = true;
+ dx = s->mouse_dx < 0 ? RT_MAX(s->mouse_dx, -128)
+ : RT_MIN(s->mouse_dx, 127);
+ dy = s->mouse_dy < 0 ? RT_MAX(s->mouse_dy, -128)
+ : RT_MIN(s->mouse_dy, 127);
+ s->mouse_dx -= dx;
+ s->mouse_dy -= dy;
+ bms_set_reported_buttons(s, s->mouse_buttons & 0x07, 0x07);
+
+ /* Force type conversion. */
+ s->held_dx = dx;
+ s->held_dy = dy;
+ }
+ }
+ else
+ s->cnt_held = false;
+
+ /* Move the appropriate nibble into port A. */
+ if (s->cnt_held)
+ {
+ if (s->port_c & BMS_CTL_SEL_Y)
+ {
+ if (s->port_c & BMS_CTL_SEL_HIGH)
+ s->port_a = s->held_dy >> 4;
+ else
+ s->port_a = s->held_dy & 0xF;
+ }
+ else
+ {
+ if (s->port_c & BMS_CTL_SEL_HIGH)
+ s->port_a = s->held_dx >> 4;
+ else
+ s->port_a = s->held_dx & 0xF;
+ }
+ /* And update the button bits. */
+ s->port_a |= s->mouse_buttons & 1 ? 0 : BMS_DATA_B1_UP;
+ s->port_a |= s->mouse_buttons & 2 ? 0 : BMS_DATA_B3_UP;
+ s->port_a |= s->mouse_buttons & 4 ? 0 : BMS_DATA_B2_UP;
+ }
+ /* Immediately clear the IRQ if necessary. */
+ if (s->port_c & BMS_CTL_INT_DIS)
+ {
+ PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), s->irq, PDM_IRQ_LEVEL_LOW);
+ s->port_c &= ~(BMS_IRQ_BIT(s->irq));
+ }
+}
+
+static int bms_write_port(void *opaque, uint32_t addr, uint32_t val)
+{
+ int rc = VINF_SUCCESS;
+ MouState *s = (MouState*)opaque;
+
+ LogRel3(("%s: write port %d: 0x%02x\n", __PRETTY_FUNCTION__, addr, val));
+
+ switch(addr) {
+ case BMS_PORT_SIG:
+ /* Update port B. */
+ s->port_b = val;
+ break;
+ case BMS_PORT_DATA:
+ /* Do nothing, port A is not writable. */
+ break;
+ case BMS_PORT_INIT:
+ s->ctrl_port = val;
+ break;
+ case BMS_PORT_CTRL:
+ /* Update the high nibble of port C. */
+ s->port_c = (val & 0xF0) | (s->port_c & 0x0F);
+ bms_update_ctrl(s);
+ break;
+ default:
+ AssertMsgFailed(("invalid port %#x\n", addr));
+ break;
+ }
+ return rc;
+}
+
+static uint32_t bms_read_port(void *opaque, uint32_t addr)
+{
+ MouState *s = (MouState*)opaque;
+ uint32_t val;
+
+ switch(addr) {
+ case BMS_PORT_DATA:
+ /* Read port A. */
+ val = s->port_a;
+ break;
+ case BMS_PORT_SIG:
+ /* Read port B. */
+ val = s->port_b;
+ break;
+ case BMS_PORT_CTRL:
+ /* Read port C. */
+ val = s->port_c;
+ /* Some Microsoft driver code reads the control port 10,000 times when
+ * determining the IRQ level. This can occur faster than the IRQ line
+ * transitions and the detection fails. To work around this, we force
+ * the IRQ bit to toggle every once in a while.
+ */
+ if (s->irq_toggle_counter)
+ s->irq_toggle_counter--;
+ else
+ {
+ s->irq_toggle_counter = 1000;
+ val ^= BMS_IRQ_BIT(s->irq);
+ }
+ break;
+ case BMS_PORT_INIT:
+ /* Read the 8255A control port. */
+ val = s->ctrl_port;
+ break;
+ default:
+ AssertMsgFailed(("invalid port %#x\n", addr));
+ break;
+ }
+ LogRel3(("%s: read port %d: 0x%02x\n", __PRETTY_FUNCTION__, addr, val));
+ return val;
+}
+
+/**
+ * Port I/O Handler for port IN operations.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument - ignored.
+ * @param Port Port number used for the IN operation.
+ * @param pu32 Where to store the result.
+ * @param cb Number of bytes read.
+ */
+PDMBOTHCBDECL(int) mouIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
+{
+ NOREF(pvUser);
+ if (cb == 1)
+ {
+ MouState *pThis = PDMINS_2_DATA(pDevIns, MouState *);
+ int rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_HC_IOPORT_READ);
+ if (RT_LIKELY(rc == VINF_SUCCESS))
+ {
+ *pu32 = bms_read_port(pThis, Port & 3);
+ PDMCritSectLeave(&pThis->CritSect);
+ Log2(("mouIOPortRead: Port=%#x cb=%d *pu32=%#x\n", Port, cb, *pu32));
+ }
+ return rc;
+ }
+ AssertMsgFailed(("Port=%#x cb=%d\n", Port, cb));
+ return VERR_IOM_IOPORT_UNUSED;
+}
+
+/**
+ * Port I/O Handler for port OUT operations.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument - ignored.
+ * @param Port Port number used for the IN operation.
+ * @param u32 The value to output.
+ * @param cb The value size in bytes.
+ */
+PDMBOTHCBDECL(int) mouIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
+{
+ int rc = VINF_SUCCESS;
+ NOREF(pvUser);
+ if (cb == 1)
+ {
+ MouState *pThis = PDMINS_2_DATA(pDevIns, MouState *);
+ rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_HC_IOPORT_WRITE);
+ if (RT_LIKELY(rc == VINF_SUCCESS))
+ {
+ rc = bms_write_port(pThis, Port & 3, u32);
+ PDMCritSectLeave(&pThis->CritSect);
+ Log2(("mouIOPortWrite: Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
+ }
+ }
+ else
+ AssertMsgFailed(("Port=%#x cb=%d\n", Port, cb));
+ return rc;
+}
+
+#ifdef IN_RING3
+
+/**
+ * Saves the state of the device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pSSMHandle The handle to save the state to.
+ */
+static DECLCALLBACK(int) mouSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
+{
+ MouState *s = PDMINS_2_DATA(pDevIns, MouState *);
+ int rc;
+
+ /* 8255A state. */
+ SSMR3PutU8(pSSMHandle, s->port_a);
+ SSMR3PutU8(pSSMHandle, s->port_b);
+ SSMR3PutU8(pSSMHandle, s->port_c);
+ SSMR3PutU8(pSSMHandle, s->ctrl_port);
+ /* Other device state. */
+ SSMR3PutU8(pSSMHandle, s->cnt_held);
+ SSMR3PutU8(pSSMHandle, s->held_dx);
+ SSMR3PutU8(pSSMHandle, s->held_dy);
+ SSMR3PutU8(pSSMHandle, s->irq);
+ SSMR3PutU32(pSSMHandle, s->cTimerPeriodMs);
+ /* Current mouse state deltas. */
+ SSMR3PutS32(pSSMHandle, s->mouse_dx);
+ SSMR3PutS32(pSSMHandle, s->mouse_dy);
+ SSMR3PutU8(pSSMHandle, s->mouse_buttons_reported);
+ /* Timer. */
+ rc = TMR3TimerSave(s->MouseTimer, pSSMHandle);
+
+ return rc;
+}
+
+
+/**
+ * Loads a saved device state.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pSSMHandle The handle to the saved state.
+ * @param uVersion The data unit version number.
+ * @param uPass The data pass.
+ */
+static DECLCALLBACK(int) mouLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t uVersion, uint32_t uPass)
+{
+ int rc;
+ MouState *s = PDMINS_2_DATA(pDevIns, MouState *);
+
+ Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
+
+ if (uVersion > BMS_SAVED_STATE_VERSION)
+ return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
+
+ /* 8255A state. */
+ SSMR3GetU8(pSSMHandle, &s->port_a);
+ SSMR3GetU8(pSSMHandle, &s->port_b);
+ SSMR3GetU8(pSSMHandle, &s->port_c);
+ SSMR3GetU8(pSSMHandle, &s->ctrl_port);
+ /* Other device state. */
+ SSMR3GetU8(pSSMHandle, &s->cnt_held);
+ SSMR3GetU8(pSSMHandle, &s->held_dx);
+ SSMR3GetU8(pSSMHandle, &s->held_dy);
+ SSMR3GetU8(pSSMHandle, &s->irq);
+ SSMR3GetU32(pSSMHandle, &s->cTimerPeriodMs);
+ /* Current mouse state deltas. */
+ SSMR3GetS32(pSSMHandle, &s->mouse_dx);
+ SSMR3GetS32(pSSMHandle, &s->mouse_dy);
+ SSMR3GetU8(pSSMHandle, &s->mouse_buttons_reported);
+ /* Timer. */
+ rc = TMR3TimerLoad(s->MouseTimer, pSSMHandle);
+ return rc;
+}
+
+/**
+ * Reset notification.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance data.
+ */
+static DECLCALLBACK(void) mouReset(PPDMDEVINS pDevIns)
+{
+ MouState *pThis = PDMINS_2_DATA(pDevIns, MouState *);
+
+ /* Reinitialize the timer. */
+ pThis->cTimerPeriodMs = BMS_IRQ_PERIOD_MS / 2;
+ TMTimerSetMillies(pThis->MouseTimer, pThis->cTimerPeriodMs);
+
+ bms_reset(pThis);
+}
+
+
+/* -=-=-=-=-=- Mouse: IBase -=-=-=-=-=- */
+
+/**
+ * @interface_method_impl{PDMIBASE,pfnQueryInterface}
+ */
+static DECLCALLBACK(void *) mouQueryMouseInterface(PPDMIBASE pInterface, const char *pszIID)
+{
+ MouState *pThis = RT_FROM_MEMBER(pInterface, MouState, Mouse.IBase);
+ PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->Mouse.IBase);
+ PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUSEPORT, &pThis->Mouse.IPort);
+ return NULL;
+}
+
+
+/* -=-=-=-=-=- Mouse: IMousePort -=-=-=-=-=- */
+
+/**
+ * @interface_method_impl{PDMIMOUSEPORT, pfnPutEvent}
+ */
+static DECLCALLBACK(int) mouPutEvent(PPDMIMOUSEPORT pInterface, int32_t iDeltaX, int32_t iDeltaY,
+ int32_t iDeltaZ, int32_t iDeltaW, uint32_t fButtonStates)
+{
+ MouState *pThis = RT_FROM_MEMBER(pInterface, MouState, Mouse.IPort);
+ int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
+ AssertReleaseRC(rc);
+
+ bms_mouse_event(pThis, iDeltaX, iDeltaY, iDeltaZ, iDeltaW, fButtonStates);
+
+ PDMCritSectLeave(&pThis->CritSect);
+ return VINF_SUCCESS;
+}
+
+/**
+ * @interface_method_impl{PDMIMOUSEPORT, pfnPutEventAbs}
+ */
+static DECLCALLBACK(int) mouPutEventAbs(PPDMIMOUSEPORT pInterface, uint32_t uX, uint32_t uY, int32_t iDeltaZ, int32_t iDeltaW, uint32_t fButtons)
+{
+ AssertFailedReturn(VERR_NOT_SUPPORTED);
+}
+
+static DECLCALLBACK(void) mouTimerCallback(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
+{
+ MouState *s = PDMINS_2_DATA(pDevIns, MouState *);
+
+ bms_timer(s);
+
+ /* Re-arm the timer. */
+ TMTimerSetMillies(pTimer, s->cTimerPeriodMs);
+}
+
+/* -=-=-=-=-=- setup code -=-=-=-=-=- */
+
+
+/**
+ * Attach command.
+ *
+ * This is called to let the device attach to a driver for a specified LUN
+ * during runtime. This is not called during VM construction, the device
+ * constructor have to attach to all the available drivers.
+ *
+ * This is like plugging in the mouse after turning on the PC.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param iLUN The logical unit which is being detached.
+ * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
+ * @remark The controller doesn't support this action, this is just
+ * implemented to try out the driver<->device structure.
+ */
+static DECLCALLBACK(int) mouAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
+{
+ int rc;
+ MouState *pThis = PDMINS_2_DATA(pDevIns, MouState *);
+
+ AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
+ ("Bus mouse device does not support hotplugging\n"),
+ VERR_INVALID_PARAMETER);
+
+ switch (iLUN)
+ {
+ /* LUN #0: mouse */
+ case 0:
+ rc = PDMDevHlpDriverAttach(pDevIns, iLUN, &pThis->Mouse.IBase, &pThis->Mouse.pDrvBase, "Bus Mouse Port");
+ if (RT_SUCCESS(rc))
+ {
+ pThis->Mouse.pDrv = PDMIBASE_QUERY_INTERFACE(pThis->Mouse.pDrvBase, PDMIMOUSECONNECTOR);
+ if (!pThis->Mouse.pDrv)
+ {
+ AssertLogRelMsgFailed(("LUN #0 doesn't have a mouse interface! rc=%Rrc\n", rc));
+ rc = VERR_PDM_MISSING_INTERFACE;
+ }
+ }
+ else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
+ {
+ Log(("%s/%d: warning: no driver attached to LUN #0!\n", pDevIns->pReg->szName, pDevIns->iInstance));
+ rc = VINF_SUCCESS;
+ }
+ else
+ AssertLogRelMsgFailed(("Failed to attach LUN #0! rc=%Rrc\n", rc));
+ break;
+
+ default:
+ AssertMsgFailed(("Invalid LUN #%d\n", iLUN));
+ return VERR_PDM_NO_SUCH_LUN;
+ }
+
+ return rc;
+}
+
+
+/**
+ * Detach notification.
+ *
+ * This is called when a driver is detaching itself from a LUN of the device.
+ * The device should adjust it's state to reflect this.
+ *
+ * This is like unplugging the network cable to use it for the laptop or
+ * something while the PC is still running.
+ *
+ * @param pDevIns The device instance.
+ * @param iLUN The logical unit which is being detached.
+ * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
+ * @remark The controller doesn't support this action, this is just
+ * implemented to try out the driver<->device structure.
+ */
+static DECLCALLBACK(void) mouDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
+{
+#if 0
+ /*
+ * Reset the interfaces and update the controller state.
+ */
+ MouState *pThis = PDMINS_2_DATA(pDevIns, MouState *);
+ switch (iLUN)
+ {
+ /* LUN #0: mouse */
+ case 0:
+ pThis->Mouse.pDrv = NULL;
+ pThis->Mouse.pDrvBase = NULL;
+ break;
+
+ default:
+ AssertMsgFailed(("Invalid LUN #%d\n", iLUN));
+ break;
+ }
+#endif
+}
+
+
+/**
+ * @copydoc FNPDMDEVRELOCATE
+ */
+static DECLCALLBACK(void) mouRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
+{
+ MouState *pThis = PDMINS_2_DATA(pDevIns, MouState *);
+ pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+}
+
+
+/**
+ * Destruct a device instance for a VM.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance data.
+ */
+static DECLCALLBACK(int) mouDestruct(PPDMDEVINS pDevIns)
+{
+ MouState *pThis = PDMINS_2_DATA(pDevIns, MouState *);
+ PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
+
+ PDMR3CritSectDelete(&pThis->CritSect);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnConstruct}
+ */
+static DECLCALLBACK(int) mouConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
+{
+ MouState *pThis = PDMINS_2_DATA(pDevIns, MouState *);
+ int rc;
+ bool fGCEnabled;
+ bool fR0Enabled;
+ uint8_t irq_lvl;
+ Assert(iInstance == 0);
+
+ PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
+
+ /*
+ * Validate and read the configuration.
+ */
+ if (!CFGMR3AreValuesValid(pCfg, "IRQ\0GCEnabled\0R0Enabled\0"))
+ return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
+ rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fGCEnabled, true);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to query \"GCEnabled\" from the config"));
+ rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &fR0Enabled, true);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to query \"R0Enabled\" from the config"));
+ rc = CFGMR3QueryU8Def(pCfg, "IRQ", &irq_lvl, BMS_DEFAULT_IRQ);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to query \"IRQ\" from the config"));
+ if ((irq_lvl < 2) || (irq_lvl > 5))
+ return PDMDEV_SET_ERROR(pDevIns, rc, N_("Invalid \"IRQ\" config setting"));
+
+ pThis->irq = irq_lvl;
+ //@todo: remove after properly enabling RC/GC support
+ fGCEnabled = fR0Enabled = false;
+ Log(("busmouse: IRQ=%d fGCEnabled=%RTbool fR0Enabled=%RTbool\n", irq_lvl, fGCEnabled, fR0Enabled));
+
+ /*
+ * Initialize the interfaces.
+ */
+ pThis->pDevInsR3 = pDevIns;
+ pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
+ pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+ pThis->Mouse.IBase.pfnQueryInterface = mouQueryMouseInterface;
+ pThis->Mouse.IPort.pfnPutEvent = mouPutEvent;
+ pThis->Mouse.IPort.pfnPutEventAbs = mouPutEventAbs;
+
+ /*
+ * Initialize the critical section.
+ */
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "BUSMS#%d", iInstance);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ /*
+ * Create the interrupt timer.
+ */
+ rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, mouTimerCallback,
+ pThis, TMTIMER_FLAGS_DEFAULT_CRIT_SECT,
+ "Bus Mouse Timer", &pThis->MouseTimer);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ /*
+ * Register I/O ports, saved state, and mouse event handlers.
+ */
+ rc = PDMDevHlpIOPortRegister(pDevIns, BMS_IO_BASE, BMS_IO_SIZE, NULL, mouIOPortWrite, mouIOPortRead, NULL, NULL, "Bus Mouse");
+ if (RT_FAILURE(rc))
+ return rc;
+ if (fGCEnabled)
+ {
+ rc = PDMDevHlpIOPortRegisterRC(pDevIns, BMS_IO_BASE, BMS_IO_SIZE, 0, "mouIOPortWrite", "mouIOPortRead", NULL, NULL, "Bus Mouse");
+ if (RT_FAILURE(rc))
+ return rc;
+ }
+ if (fR0Enabled)
+ {
+ rc = PDMDevHlpIOPortRegisterR0(pDevIns, BMS_IO_BASE, BMS_IO_SIZE, 0, "mouIOPortWrite", "mouIOPortRead", NULL, NULL, "Bus Mouse");
+ if (RT_FAILURE(rc))
+ return rc;
+ }
+ rc = PDMDevHlpSSMRegister(pDevIns, BMS_SAVED_STATE_VERSION, sizeof(*pThis), mouSaveExec, mouLoadExec);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ /*
+ * Attach to the mouse driver.
+ */
+ rc = mouAttach(pDevIns, 0, PDM_TACH_FLAGS_NOT_HOT_PLUG);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ /*
+ * Initialize the device state.
+ */
+ mouReset(pDevIns);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * The device registration structure.
+ */
+const PDMDEVREG g_DeviceBusMouse =
+{
+ /* u32Version */
+ PDM_DEVREG_VERSION,
+ /* szName */
+ "busmouse",
+ /* szRCMod */
+ "VBoxDDGC.gc",
+ /* szR0Mod */
+ "VBoxDDR0.r0",
+ /* pszDescription */
+ "Microsoft Bus Mouse controller. "
+ "LUN #0 is the mouse connector.",
+ /* fFlags */
+ PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+ /* fClass */
+ PDM_DEVREG_CLASS_INPUT,
+ /* cMaxInstances */
+ 1,
+ /* cbInstance */
+ sizeof(MouState),
+ /* pfnConstruct */
+ mouConstruct,
+ /* pfnDestruct */
+ mouDestruct,
+ /* pfnRelocate */
+ mouRelocate,
+ /* pfnIOCtl */
+ NULL,
+ /* pfnPowerOn */
+ NULL,
+ /* pfnReset */
+ mouReset,
+ /* pfnSuspend */
+ NULL,
+ /* pfnResume */
+ NULL,
+ /* pfnAttach */
+ mouAttach,
+ /* pfnDetach */
+ mouDetach,
+ /* pfnQueryInterface. */
+ NULL,
+ /* pfnInitComplete */
+ NULL,
+ /* pfnPowerOff */
+ NULL,
+ /* pfnSoftReset */
+ NULL,
+ /* u32VersionEnd */
+ PDM_DEVREG_VERSION
+};
+
+#endif /* IN_RING3 */
+#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
+
diff --git a/src/VBox/ExtPacks/Skeleton/ExtPack.xml b/src/VBox/ExtPacks/Skeleton/ExtPack.xml
new file mode 100644
index 000000000..40a081358
--- /dev/null
+++ b/src/VBox/ExtPacks/Skeleton/ExtPack.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<VirtualBoxExtensionPack xmlns="http://www.virtualbox.org/VirtualBoxExtensionPack" version="1.0">
+ <Name>Skeleton</Name>
+ <Description>The extension pack skeleton sample.</Description>
+ <Version revision="@VBOX_SVN_REV@">@VBOX_VERSION_STRING@</Version>
+ <MainModule>VBoxSkeletonMain</MainModule>
+ <!-- VRDEModule>VBoxVNC</VRDEModule -->
+ <ShowLicense/>
+</VirtualBoxExtensionPack>
+
diff --git a/src/VBox/ExtPacks/Skeleton/Makefile.kmk b/src/VBox/ExtPacks/Skeleton/Makefile.kmk
new file mode 100644
index 000000000..e742576e8
--- /dev/null
+++ b/src/VBox/ExtPacks/Skeleton/Makefile.kmk
@@ -0,0 +1,163 @@
+# $Id: Makefile.kmk 35991 2011-02-16 11:07:20Z vboxsync $
+## @file
+# Sub-Makefile for the Skeleton Extension Pack Sample.
+#
+
+#
+# Copyright (C) 2010-2011 Oracle Corporation
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+
+SUB_DEPTH = ../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+#
+# Extend the extension pack templates.
+#
+TEMPLATE_VBoxR3ExtPackSkeleton = For the ring-3 context modules in the Skeleton extension pack.
+TEMPLATE_VBoxR3ExtPackSkeleton_EXTENDS = VBoxR3ExtPack
+TEMPLATE_VBoxR3ExtPackSkeleton_INST = $(INST_EXTPACK)Skeleton/$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)/
+
+TEMPLATE_VBoxR0ExtPackSkeleton = For the ring-0 context modules in the Skeleton extension pack.
+TEMPLATE_VBoxR0ExtPackSkeleton_EXTENDS = VBoxR0ExtPack
+TEMPLATE_VBoxR0ExtPackSkeleton_INST = $(INST_EXTPACK)Skeleton/$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)/
+
+TEMPLATE_VBoxRcExtPackSkeleton = For the raw-mode context modules in the Skeleton extension pack.
+TEMPLATE_VBoxRcExtPackSkeleton_EXTENDS = VBoxRcExtPack
+TEMPLATE_VBoxRcExtPackSkeleton_INST = $(INST_EXTPACK)Skeleton/$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)/
+
+TEMPLATE_VBoxInsExtPackSkeleton = For the install targets of an extension pack.
+TEMPLATE_VBoxInsExtPackSkeleton_EXTENDS = VBoxR0ExtPack
+TEMPLATE_VBoxInsExtPackSkeleton_INST = $(INST_EXTPACK)Skeleton/
+
+#
+# Globals.
+#
+VBOX_SKELETON_NAME = Skeleton
+VBOX_SKELETON_MANGLED_NAME = Skeleton
+VBOX_PATH_EXTPACK_SKELETON = $(PATH_INS)/$(INST_EXTPACK)Skeleton
+
+
+#
+# VBoxSkeletonMain - The module which the VirtualBox Main API talks to.
+#
+DLLS += VBoxSkeletonMain
+VBoxSkeletonMain_TEMPLATE = VBoxR3ExtPackSkeleton
+VBoxSkeletonMain_SOURCES = VBoxSkeletonMain.cpp
+VBoxSkeletonMain_DEFS = \
+ $(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,)
+
+#
+# Install the description.
+#
+INSTALLS += VBoxSkeletonIns
+VBoxSkeletonIns_TEMPLATE = VBoxInsExtPackSkeleton
+VBoxSkeletonIns_SOURCES = \
+ $(VBoxSkeletonIns_0_OUTDIR)/ExtPack.xml
+$(call VBOX_EDIT_VERSION_RULE_FN,VBoxSkeletonIns,ExtPack.xml)
+
+
+#
+# Packing .
+#
+ifndef VBOX_WITHOUT_EXTPACK_SKELETON_PACKING
+ PACKING += $(VBOX_PATH_PACKAGES)/$(VBOX_SKELETON_MANGLED_NAME)-$(VBOX_VERSION_STRING)r$(VBOX_SVN_REV).vbox-extpack
+endif
+
+ifndef VBOX_WITH_EXTPACK_OS_ARCHS
+ ifeq ($(USER),bird) # for now
+ VBOX_WITH_EXTPACK_OS_ARCHS = $(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)
+ endif
+endif
+
+# Build the file list. The macro takes 1=darwin.x86, 2=dist/VirtualBox.app/Contents/MacOS, 3=dylib
+VBOX_SKELETON_FILES_MACRO = \
+ $(PATH_OUT_BASE)/$(1)/$(KBUILD_TYPE)/$(2)/ExtensionPacks/$(VBOX_SKELETON_MANGLED_NAME)/$(1)/VBoxSkeletonMain.$(3)=>$(1)/VBoxSkeletonMain.$(3)
+
+VBOX_SKELETON_FILES := \
+ $(VBOX_PATH_EXTPACK_SKELETON)/ExtPack.xml=>ExtPack.xml
+
+if1of (darwin.amd64, $(VBOX_WITH_EXTPACK_OS_ARCHS))
+ VBOX_SKELETON_FILES += $(call VBOX_SKELETON_FILES_MACRO,darwin.amd64,dist/VirtualBox.app/Contents/MacOS,dylib)
+endif
+if1of (darwin.x86, $(VBOX_WITH_EXTPACK_OS_ARCHS))
+ VBOX_SKELETON_FILES += $(call VBOX_SKELETON_FILES_MACRO,darwin.x86,dist/VirtualBox.app/Contents/MacOS,dylib)
+endif
+if1of (freebsd.amd64, $(VBOX_WITH_EXTPACK_OS_ARCHS))
+ VBOX_SKELETON_FILES += $(call VBOX_SKELETON_FILES_MACRO,freebsd.amd64,bin,so)
+endif
+if1of (freebsd.x86, $(VBOX_WITH_EXTPACK_OS_ARCHS))
+ VBOX_SKELETON_FILES += $(call VBOX_SKELETON_FILES_MACRO,freebsd.x86,bin,so)
+endif
+if1of (linux.amd64, $(VBOX_WITH_EXTPACK_OS_ARCHS))
+ VBOX_SKELETON_FILES += $(call VBOX_SKELETON_FILES_MACRO,linux.amd64,bin,so)
+endif
+if1of (linux.x86, $(VBOX_WITH_EXTPACK_OS_ARCHS))
+ VBOX_SKELETON_FILES += $(call VBOX_SKELETON_FILES_MACRO,linux.x86,bin,so)
+endif
+if1of (os2.x86, $(VBOX_WITH_EXTPACK_OS_ARCHS))
+ VBOX_SKELETON_FILES += $(call VBOX_SKELETON_FILES_MACRO,os2.x86,bin,so)
+endif
+if1of (solaris.amd64, $(VBOX_WITH_EXTPACK_OS_ARCHS))
+ VBOX_SKELETON_FILES += $(call VBOX_SKELETON_FILES_MACRO,solaris.amd64,bin,so)
+endif
+if1of (solaris.x86, $(VBOX_WITH_EXTPACK_OS_ARCHS))
+ VBOX_SKELETON_FILES += $(call VBOX_SKELETON_FILES_MACRO,solaris.x86,bin,so)
+endif
+if1of (win.amd64, $(VBOX_WITH_EXTPACK_OS_ARCHS))
+ VBOX_SKELETON_FILES += $(call VBOX_SKELETON_FILES_MACRO,win.amd64,bin,dll)
+endif
+if1of (win.x86, $(VBOX_WITH_EXTPACK_OS_ARCHS))
+ VBOX_SKELETON_FILES += $(call VBOX_SKELETON_FILES_MACRO,win.x86,bin,dll)
+endif
+
+# Pack it all up using a temporary staging directory.
+$(VBOX_PATH_PACKAGES)/$(VBOX_SKELETON_MANGLED_NAME)-$(VBOX_VERSION_STRING)r$(VBOX_SVN_REV).vbox-extpack: \
+ $$(foreach file, $$(VBOX_SKELETON_FILES), $$(firstword $$(subst =>,$$(SP),$$(file)))) \
+ | $(VBOX_PATH_PACKAGES)/
+ $(RM) -f $(wildcard $(VBOX_PATH_PACKAGES)/$(VBOX_SKELETON_MANGLED_NAME)-*.vbox-extpack) \
+ $(VBoxSkeletonIns_0_OUTDIR)/ExtPack.manifest \
+ $(VBoxSkeletonIns_0_OUTDIR)/ExtPack.signature
+# Stage all the files
+ $(RM) -Rf $(VBoxSkeletonIns_0_OUTDIR)/Stage/
+ $(foreach file, $(VBOX_SKELETON_FILES),\
+ $(NLTAB)$(MKDIR) -p $(dir $(lastword $(subst =>,$(SP)$(VBoxSkeletonIns_0_OUTDIR)/Stage/,$(file)))) \
+ $(NLTAB)$(CP) $(subst =>,$(SP)$(VBoxSkeletonIns_0_OUTDIR)/Stage/,$(file)) )
+# Create the manifest
+ $(VBOX_RTMANIFEST) \
+ --manifest $(VBoxSkeletonIns_0_OUTDIR)/Stage/ExtPack.manifest \
+ --chdir $(VBoxSkeletonIns_0_OUTDIR)/Stage/ \
+ $(foreach file, $(VBOX_SKELETON_FILES), $(lastword $(subst =>,$(SP),$(file))))
+ $(APPEND) $(VBoxSkeletonIns_0_OUTDIR)/Stage/ExtPack.signature "todo"
+ $(CHMOD) a+r \
+ $(VBoxSkeletonIns_0_OUTDIR)/Stage/ExtPack.manifest \
+ $(VBoxSkeletonIns_0_OUTDIR)/Stage/ExtPack.signature
+# Tar it up.
+ tar -cvf - -C $(VBoxSkeletonIns_0_OUTDIR)/Stage/ . | gzip -9c > $@
+# Clean up
+ $(RM) -Rf $(VBoxSkeletonIns_0_OUTDIR)/Stage/
+
+BLDDIRS += $(VBOX_PATH_PACKAGES)/ $(VBOX_PATH_PACKAGES)/
+
+include $(KBUILD_PATH)/subfooter.kmk
+
diff --git a/src/VBox/ExtPacks/Skeleton/VBoxSkeletonMain.cpp b/src/VBox/ExtPacks/Skeleton/VBoxSkeletonMain.cpp
new file mode 100644
index 000000000..7325a8991
--- /dev/null
+++ b/src/VBox/ExtPacks/Skeleton/VBoxSkeletonMain.cpp
@@ -0,0 +1,137 @@
+/* $Id: VBoxSkeletonMain.cpp 35963 2011-02-14 16:18:36Z vboxsync $ */
+/** @file
+ * Skeleton main module.
+ */
+
+/*
+ * Copyright (C) 2010-2010 Oracle Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include <VBox/ExtPack/ExtPack.h>
+
+#include <VBox/err.h>
+#include <VBox/version.h>
+#include <VBox/vmm/cfgm.h>
+#include <iprt/string.h>
+#include <iprt/param.h>
+#include <iprt/path.h>
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/** Pointer to the extension pack helpers. */
+static PCVBOXEXTPACKHLP g_pHlp;
+
+
+// /**
+// * @interface_method_impl{VBOXEXTPACKREG,pfnInstalled}
+// */
+// static DECLCALLBACK(void) vboxSkeletonExtPack_Installed(PCVBOXEXTPACKREG pThis, VBOXEXTPACK_IF_CS(IVirtualBox) *pVirtualBox);
+// /**
+// * @interface_method_impl{VBOXEXTPACKREG,pfnUninstall}
+// */
+// static DECLCALLBACK(int) vboxSkeletonExtPack_Uninstall(PCVBOXEXTPACKREG pThis, VBOXEXTPACK_IF_CS(IVirtualBox) *pVirtualBox);
+//
+// /**
+// * @interface_method_impl{VBOXEXTPACKREG,pfnVirtualBoxReady}
+// */
+// static DECLCALLBACK(void) vboxSkeletonExtPack_VirtualBoxReady(PCVBOXEXTPACKREG pThis, VBOXEXTPACK_IF_CS(IVirtualBox) *pVirtualBox);
+//
+// /**
+// * @interface_method_impl{VBOXEXTPACKREG,pfnUnload}
+// */
+// static DECLCALLBACK(void) vboxSkeletonExtPack_Unload(PCVBOXEXTPACKREG pThis);
+// /**
+// * @interface_method_impl{VBOXEXTPACKREG,pfnVMCreated}
+// */
+// static DECLCALLBACK(int) vboxSkeletonExtPack_VMCreated(PCVBOXEXTPACKREG pThis, VBOXEXTPACK_IF_CS(IVirtualBox) *pVirtualBox, IMachine *pMachine);
+//
+// /**
+// * @interface_method_impl{VBOXEXTPACKREG,pfnVMConfigureVMM}
+// */
+// static DECLCALLBACK(int) vboxSkeletonExtPack_VMConfigureVMM(PCVBOXEXTPACKREG pThis, IConsole *pConsole, PVM pVM);
+//
+// /**
+// * @interface_method_impl{VBOXEXTPACKREG,pfnVMPowerOn}
+// */
+// static DECLCALLBACK(int) vboxSkeletonExtPack_VMPowerOn(PCVBOXEXTPACKREG pThis, IConsole *pConsole, PVM pVM);
+// /**
+// * @interface_method_impl{VBOXEXTPACKREG,pfnVMPowerOff}
+// */
+// static DECLCALLBACK(void) vboxSkeletonExtPack_VMPowerOff(PCVBOXEXTPACKREG pThis, IConsole *pConsole, PVM pVM);
+// /**
+// * @interface_method_impl{VBOXEXTPACKREG,pfnVMPowerOff}
+// */
+// static DECLCALLBACK(void) vboxSkeletonExtPack_QueryObject(PCVBOXEXTPACKREG pThis, PCRTUUID pObjectId);
+
+
+static const VBOXEXTPACKREG g_vboxSkeletonExtPackReg =
+{
+ VBOXEXTPACKREG_VERSION,
+ /* .pfnInstalled = */ NULL,
+ /* .pfnUninstall = */ NULL,
+ /* .pfnVirtualBoxReady =*/ NULL,
+ /* .pfnConsoleReady = */ NULL,
+ /* .pfnUnload = */ NULL,
+ /* .pfnVMCreated = */ NULL,
+ /* .pfnVMConfigureVMM = */ NULL,
+ /* .pfnVMPowerOn = */ NULL,
+ /* .pfnVMPowerOff = */ NULL,
+ /* .pfnQueryObject = */ NULL,
+ VBOXEXTPACKREG_VERSION
+};
+
+
+/** @callback_method_impl{FNVBOXEXTPACKREGISTER} */
+extern "C" DECLEXPORT(int) VBoxExtPackRegister(PCVBOXEXTPACKHLP pHlp, PCVBOXEXTPACKREG *ppReg, PRTERRINFO pErrInfo)
+{
+ /*
+ * Check the VirtualBox version.
+ */
+ if (!VBOXEXTPACK_IS_VER_COMPAT(pHlp->u32Version, VBOXEXTPACKHLP_VERSION))
+ return RTErrInfoSetF(pErrInfo, VERR_VERSION_MISMATCH,
+ "Helper version mismatch - expected %#x got %#x",
+ VBOXEXTPACKHLP_VERSION, pHlp->u32Version);
+ if ( VBOX_FULL_VERSION_GET_MAJOR(pHlp->uVBoxFullVersion) != VBOX_VERSION_MAJOR
+ || VBOX_FULL_VERSION_GET_MINOR(pHlp->uVBoxFullVersion) != VBOX_VERSION_MINOR)
+ return RTErrInfoSetF(pErrInfo, VERR_VERSION_MISMATCH,
+ "VirtualBox version mismatch - expected %u.%u got %u.%u",
+ VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR,
+ VBOX_FULL_VERSION_GET_MAJOR(pHlp->uVBoxFullVersion),
+ VBOX_FULL_VERSION_GET_MINOR(pHlp->uVBoxFullVersion));
+
+ /*
+ * We're good, save input and return the registration structure.
+ */
+ g_pHlp = pHlp;
+ *ppReg = &g_vboxSkeletonExtPackReg;
+
+ return VINF_SUCCESS;
+}
+
diff --git a/src/VBox/Frontends/Common/Makefile.kmk b/src/VBox/Frontends/Common/Makefile.kmk
index 204889576..38ec05bf6 100644
--- a/src/VBox/Frontends/Common/Makefile.kmk
+++ b/src/VBox/Frontends/Common/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 30054 2010-06-07 08:13:46Z vboxsync $
## @file
# Top-level makefile for VBox frontends shared bits
#
diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/Makefile.kmk b/src/VBox/Frontends/Common/VBoxKeyboard/Makefile.kmk
index b88b1c11f..6041794ff 100644
--- a/src/VBox/Frontends/Common/VBoxKeyboard/Makefile.kmk
+++ b/src/VBox/Frontends/Common/VBoxKeyboard/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 36222 2011-03-09 12:36:23Z vboxsync $
## @file
# Makefile for the VirtualBox X11 keyboard library
#
@@ -68,11 +68,11 @@ $(PATH_BIN)/vboxkeyboard.tar.bz2: \
$(call MSG_L1,Packing $@)
$(QUIET)$(RM) -f -- $@ $(patsubst %.bz2,%,$@)
$(QUIET)$(MKDIR) -p $(@D)
-if1of ($(KBUILD_TARGET), freebsd)
- $(QUIET)tar -cjf $@ \
+ifdef VBOX_GTAR
+ $(QUIET)$(VBOX_GTAR) --owner 0 --group 0 --ignore-failed-read -cjRf $@ \
-C $(VBOX_KEYBOARD_STAGE_DIR) VBoxKeyboard
else
- $(QUIET)tar --owner 0 --group 0 --ignore-failed-read -cjRf $@ \
+ $(QUIET)tar -cjf $@ \
-C $(VBOX_KEYBOARD_STAGE_DIR) VBoxKeyboard
endif
$(QUIET)$(CHMOD) 0644 $@
diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-layouts.h b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-layouts.h
index 593eee719..896e6ab4c 100644
--- a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-layouts.h
+++ b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-layouts.h
@@ -1,4 +1,4 @@
-/* $Id: keyboard-layouts.h $ */
+/* $Id: keyboard-layouts.h 33656 2010-11-01 14:18:11Z vboxsync $ */
/** @file
* VBox/Frontends/Common - X11 keyboard driver translation tables (keyboard layouts).
*
diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-list.h b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-list.h
index 71f317f4e..9ba53c295 100644
--- a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-list.h
+++ b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-list.h
@@ -1,4 +1,4 @@
-/* $Id: keyboard-list.h $ */
+/* $Id: keyboard-list.h 33656 2010-11-01 14:18:11Z vboxsync $ */
/** @file
* VBox/Frontends/Common - X11 keyboard driver translation tables (keyboard layouts)
*/
diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h
index 5457a35f2..cd144230e 100644
--- a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h
+++ b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h
@@ -1,4 +1,4 @@
-/* $Id: keyboard-tables.h $ */
+/* $Id: keyboard-tables.h 35479 2011-01-11 11:37:08Z vboxsync $ */
/** @file
* VBox/Frontends/Common - X11 keyboard driver translation tables.
*/
diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-types.h b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-types.h
index f95ace725..2b2725ae1 100644
--- a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-types.h
+++ b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-types.h
@@ -1,4 +1,4 @@
-/* $Id: keyboard-types.h $ */
+/* $Id: keyboard-types.h 33656 2010-11-01 14:18:11Z vboxsync $ */
/** @file
* VBox/Frontends/Common - X11 keyboard driver translation tables (PC scan code
* mappings for known keyboard maps).
diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard.c b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard.c
index 835abe295..df4b01462 100644
--- a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard.c
+++ b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard.c
@@ -1,4 +1,4 @@
-/* $Id: keyboard.c $ */
+/* $Id: keyboard.c 36335 2011-03-21 21:58:58Z vboxsync $ */
/** @file
* VBox/Frontends/Common - X11 keyboard handler library.
*/
diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/xkbtoscan.h b/src/VBox/Frontends/Common/VBoxKeyboard/xkbtoscan.h
index f9f346b3d..4edace984 100644
--- a/src/VBox/Frontends/Common/VBoxKeyboard/xkbtoscan.h
+++ b/src/VBox/Frontends/Common/VBoxKeyboard/xkbtoscan.h
@@ -1,4 +1,4 @@
-/* $Id: xkbtoscan.h $ */
+/* $Id: xkbtoscan.h 36093 2011-02-26 21:14:12Z vboxsync $ */
/** @file
* VBox/Frontends/Common - X11 keyboard driver translation tables (XT scan
* code mappings for XKB key names).
diff --git a/src/VBox/Frontends/Makefile.kmk b/src/VBox/Frontends/Makefile.kmk
index 45c9f2b4f..f4f144d37 100644
--- a/src/VBox/Frontends/Makefile.kmk
+++ b/src/VBox/Frontends/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37429 2011-06-13 19:59:08Z vboxsync $
## @file
# Top-level makefile for the VBox frontends.
#
diff --git a/src/VBox/Frontends/VBoxBFE/COMDefs.h b/src/VBox/Frontends/VBoxBFE/COMDefs.h
index 5c8ea572f..e9fa6a905 100644
--- a/src/VBox/Frontends/VBoxBFE/COMDefs.h
+++ b/src/VBox/Frontends/VBoxBFE/COMDefs.h
@@ -46,6 +46,9 @@
#define COM_INTERFACE_ENTRY(a)
#define COM_INTERFACE_ENTRY2(a,b)
#define END_COM_MAP()
+#define VBOX_DEFAULT_INTERFACE_ENTRIES(a)
+#define BaseFinalConstruct() (S_OK)
+#define BaseFinalRelease()
#ifndef RT_OS_WINDOWS
typedef unsigned long HRESULT;
diff --git a/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp b/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp
index 53893b44e..5bdd60e4c 100644
--- a/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp
+++ b/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: DisplayImpl.cpp $ */
+/* $Id: DisplayImpl.cpp 36590 2011-04-06 15:35:26Z vboxsync $ */
/** @file
* VBox frontends: Basic Frontend (BFE):
* Implementation of Display class
@@ -37,12 +37,6 @@
#include <iprt/asm.h>
#include <iprt/uuid.h>
-#ifdef RT_OS_L4
-# include <stdio.h>
-# include <l4/util/util.h>
-# include <l4/log/l4log.h>
-#endif
-
#include "DisplayImpl.h"
#include "Framebuffer.h"
#include "VMMDev.h"
@@ -390,12 +384,7 @@ void Display::updateDisplayData()
while(!mFramebuffer)
{
-#if RT_OS_L4
- asm volatile ("nop":::"memory");
- l4_sleep(5);
-#else
RTThreadYield();
-#endif
}
Assert(mFramebuffer);
// the driver might not have been constructed yet
diff --git a/src/VBox/Frontends/VBoxBFE/DisplayImpl.h b/src/VBox/Frontends/VBoxBFE/DisplayImpl.h
index be620b12f..9b329f200 100644
--- a/src/VBox/Frontends/VBoxBFE/DisplayImpl.h
+++ b/src/VBox/Frontends/VBoxBFE/DisplayImpl.h
@@ -1,4 +1,4 @@
-/* $Id: DisplayImpl.h $ */
+/* $Id: DisplayImpl.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBox frontends: Basic Frontend (BFE):
* Declaration of Display class
diff --git a/src/VBox/Frontends/VBoxBFE/HostUSBDeviceImpl.cpp b/src/VBox/Frontends/VBoxBFE/HostUSBDeviceImpl.cpp
deleted file mode 100644
index 7f9425e13..000000000
--- a/src/VBox/Frontends/VBoxBFE/HostUSBDeviceImpl.cpp
+++ /dev/null
@@ -1,540 +0,0 @@
-/** @file
- *
- * VBox frontends: Basic Frontend (BFE):
- * Implementation of HostUSBDevice
- */
-
-/*
- * Copyright (C) 2006-2007 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#include "HostUSBDeviceImpl.h"
-#include "USBProxyService.h"
-#include "Logging.h"
-
-#include <VBox/err.h>
-
-
-// constructor / destructor
-/////////////////////////////////////////////////////////////////////////////
-
-HostUSBDevice::HostUSBDevice()
- : mUSBProxyService (NULL), m_pUsb (NULL)
-{
-}
-
-HostUSBDevice::~HostUSBDevice()
-{
- if (m_pUsb)
- {
- USBProxyService::freeDevice (m_pUsb);
- m_pUsb = NULL;
- }
-}
-
-// public initializer/uninitializer for internal purposes only
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Initializes the USB device object.
- *
- * @returns COM result indicator
- * @param aUsb Pointer to the usb device structure for which the object is to be a wrapper.
- * This structure is now fully owned by the HostUSBDevice object and will be
- * freed when it is destructed.
- * @param aUSBProxyService Pointer to the USB Proxy Service object.
- */
-HRESULT HostUSBDevice::init(PUSBDEVICE aUsb, USBProxyService *aUSBProxyService)
-{
- ComAssertRet (aUsb, E_INVALIDARG);
-
- AutoLock alock (this);
-
- /*
- * We need a unique ID for this VBoxSVC session.
- * The UUID isn't stored anywhere.
- */
- RTUuidCreate(&mId);
-
- /*
- * Convert from USBDEVICESTATE to USBDeviceState.
- *
- * Note that not all proxy backend can detect the HELD_BY_PROXY
- * and USED_BY_GUEST states. But that shouldn't matter much.
- */
- switch (aUsb->enmState)
- {
- default:
- AssertMsgFailed(("aUsb->enmState=%d\n", aUsb->enmState));
- case USBDEVICESTATE_UNSUPPORTED:
- mState = USBDeviceState_NotSupported;
- break;
- case USBDEVICESTATE_USED_BY_HOST:
- mState = USBDeviceState_Unavailable;
- break;
- case USBDEVICESTATE_USED_BY_HOST_CAPTURABLE:
- mState = USBDeviceState_Busy;
- break;
- case USBDEVICESTATE_UNUSED:
- mState = USBDeviceState_Available;
- break;
- case USBDEVICESTATE_HELD_BY_PROXY:
- mState = USBDeviceState_Held;
- break;
- case USBDEVICESTATE_USED_BY_GUEST:
- mState = USBDeviceState_Captured;
- break;
- }
-
- /*
- * Other data members.
- */
- mIgnored = false;
- mUSBProxyService = aUSBProxyService;
- m_pUsb = aUsb;
-
- setReady (true);
- return S_OK;
-}
-
-// IUSBDevice properties
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Returns the GUID.
- *
- * @returns COM status code
- * @param aId Address of result variable.
- */
-STDMETHODIMP HostUSBDevice::COMGETTER(Id)(RTUUID &aId)
-{
-/* AutoLock alock (this); */
- CHECK_READY();
-
- aId = mId;
- return S_OK;
-}
-
-
-/**
- * Returns the vendor Id.
- *
- * @returns COM status code
- * @param aVendorId Where to store the vendor id.
- */
-STDMETHODIMP HostUSBDevice::COMGETTER(VendorId)(USHORT *aVendorId)
-{
- if (!aVendorId)
- return E_INVALIDARG;
-
- AutoLock alock (this);
- CHECK_READY();
-
- *aVendorId = m_pUsb->idVendor;
- return S_OK;
-}
-
-
-/**
- * Returns the product Id.
- *
- * @returns COM status code
- * @param aProductId Where to store the product id.
- */
-STDMETHODIMP HostUSBDevice::COMGETTER(ProductId)(USHORT *aProductId)
-{
- if (!aProductId)
- return E_INVALIDARG;
-
- AutoLock alock (this);
- CHECK_READY();
-
- *aProductId = m_pUsb->idProduct;
- return S_OK;
-}
-
-
-/**
- * Returns the revision BCD.
- *
- * @returns COM status code
- * @param aRevision Where to store the revision BCD.
- */
-STDMETHODIMP HostUSBDevice::COMGETTER(Revision)(USHORT *aRevision)
-{
- if (!aRevision)
- return E_INVALIDARG;
-
- AutoLock alock (this);
- CHECK_READY();
-
- *aRevision = m_pUsb->bcdDevice;
- return S_OK;
-}
-
-/**
- * Returns the manufacturer string.
- *
- * @returns COM status code
- * @param aManufacturer Where to put the return string.
- */
-STDMETHODIMP HostUSBDevice::COMGETTER(Manufacturer)
- (std::string *aManufacturer)
-{
- if (!aManufacturer)
- return E_INVALIDARG;
-
- AutoLock alock (this);
- CHECK_READY();
-
- *aManufacturer = m_pUsb->pszManufacturer;
- return S_OK;
-}
-
-
-/**
- * Returns the product string.
- *
- * @returns COM status code
- * @param aProduct Where to put the return string.
- */
-STDMETHODIMP HostUSBDevice::COMGETTER(Product)(std::string *aProduct)
-{
- if (!aProduct)
- return E_INVALIDARG;
-
- AutoLock alock (this);
- CHECK_READY();
-
- *aProduct = m_pUsb->pszProduct;
- return S_OK;
-}
-
-
-/**
- * Returns the serial number string.
- *
- * @returns COM status code
- * @param aSerialNumber Where to put the return string.
- */
-STDMETHODIMP HostUSBDevice::COMGETTER(SerialNumber)
- (std::string *aSerialNumber)
-{
- if (!aSerialNumber)
- return E_INVALIDARG;
-
- AutoLock alock (this);
- CHECK_READY();
-
- *aSerialNumber = m_pUsb->pszSerialNumber;
- return S_OK;
-}
-
-/**
- * Returns the device address string.
- *
- * @returns COM status code
- * @param aAddress Where to put the returned string.
- */
-STDMETHODIMP HostUSBDevice::COMGETTER(Address)(std::string *aAddress)
-{
- if (!aAddress)
- return E_INVALIDARG;
-
- AutoLock alock (this);
- CHECK_READY();
-
- *aAddress = m_pUsb->pszAddress;
- return S_OK;
-}
-
-STDMETHODIMP HostUSBDevice::COMGETTER(Port)(USHORT *aPort)
-{
- if (!aPort)
- return E_INVALIDARG;
-
- AutoLock alock (this);
- CHECK_READY();
-
- ///@todo implement
- aPort = 0;
- return S_OK;
-}
-
-STDMETHODIMP HostUSBDevice::COMGETTER(Remote)(BOOL *aRemote)
-{
- if (!aRemote)
- return E_INVALIDARG;
-
- AutoLock alock (this);
- CHECK_READY();
-
- *aRemote = FALSE;
- return S_OK;
-}
-
-// IHostUSBDevice properties
-/////////////////////////////////////////////////////////////////////////////
-
-STDMETHODIMP HostUSBDevice::COMGETTER(State) (USBDeviceState_T *aState)
-{
- if (!aState)
- return E_POINTER;
-
- AutoLock lock (this);
- CHECK_READY();
-
- *aState = mState;
- return S_OK;
-}
-
-
-// public methods only for internal purposes
-////////////////////////////////////////////////////////////////////////////////
-
-/** Sets the ignored flag and returns the device to the host */
-void HostUSBDevice::setIgnored()
-{
- AutoLock alock (this);
- AssertReturn (isReady(), (void) 0);
-
- AssertReturn (!mIgnored, (void) 0);
-
- mIgnored = false;
- setHostDriven();
-}
-
-/** Requests the capture */
-void HostUSBDevice::setCaptured ()
-{
- AutoLock alock (this);
- Assert (isReady());
-
- Assert (
- mState == USBDeviceState_Busy ||
- mState == USBDeviceState_Available ||
- mState == USBDeviceState_Held);
-
- mUSBProxyService->captureDevice (this);
-
- mState = USBDeviceState_Captured;
-}
-
-/**
- * Returns the device back to the host
- *
- * @returns VBox status code.
- */
-int HostUSBDevice::setHostDriven()
-{
- AutoLock alock (this);
- AssertReturn (isReady(), VERR_INVALID_PARAMETER);
-
- AssertReturn (mState == USBDeviceState_Held, VERR_INVALID_PARAMETER);
-
- mState = USBDeviceState_Available;
-
- return mUSBProxyService->releaseDevice (this);
-}
-
-/**
- * Resets the device as if it were just attached to the host
- *
- * @returns VBox status code.
- */
-int HostUSBDevice::reset()
-{
- AutoLock alock (this);
- AssertReturn (isReady(), VERR_INVALID_PARAMETER);
-
- mState = USBDeviceState_Held;
- mIgnored = false;
-
- /** @todo this operation might fail and cause the device to the reattached with a different address and all that. */
- return mUSBProxyService->resetDevice (this);
-}
-
-/**
- * Sets the state of the device, as it was reported by the host.
- * This method applicable only for devices currently controlled by the host.
- *
- * @param aState new state
- */
-void HostUSBDevice::setHostState (USBDeviceState_T aState)
-{
- AssertReturn (
- aState == USBDeviceState_Unavailable ||
- aState == USBDeviceState_Busy ||
- aState == USBDeviceState_Available,
- (void) 0);
-
- AssertReturn (
- mState == USBDeviceState_NotSupported || /* initial state */
- mState == USBDeviceState_Unavailable ||
- mState == USBDeviceState_Busy ||
- mState == USBDeviceState_Available,
- (void) 0);
-
- if (mState != aState)
- {
- mState = aState;
- }
-}
-
-
-/**
- * Compares this device with a USBDEVICE and decides which comes first.
- *
- * @returns < 0 if this should come before pDev2.
- * @returns 0 if this and pDev2 are equal.
- * @returns > 0 if this should come after pDev2.
- *
- * @param pDev2 Device 2.
- */
-int HostUSBDevice::compare (PCUSBDEVICE pDev2)
-{
- return compare (m_pUsb, pDev2);
-}
-
-
-/**
- * Compares two USB devices and decides which comes first.
- *
- * @returns < 0 if pDev1 should come before pDev2.
- * @returns 0 if pDev1 and pDev2 are equal.
- * @returns > 0 if pDev1 should come after pDev2.
- *
- * @param pDev1 Device 1.
- * @param pDev2 Device 2.
- */
-/*static*/ int HostUSBDevice::compare (PCUSBDEVICE pDev1, PCUSBDEVICE pDev2)
-{
- int iDiff = pDev1->idVendor - pDev2->idVendor;
- if (iDiff)
- return iDiff;
-
- iDiff = pDev1->idProduct - pDev2->idProduct;
- if (iDiff)
- return iDiff;
-
- /** @todo Sander, will this work on windows as well? Linux won't reuse an address for quite a while. */
- return strcmp(pDev1->pszAddress, pDev2->pszAddress);
-}
-
-/**
- * Updates the state of the device.
- *
- * @returns true if the state has actually changed.
- * @returns false if the stat didn't change, or the change might have been cause by VBox.
- *
- * @param aDev The current device state as seen by the proxy backend.
- */
-bool HostUSBDevice::updateState (PCUSBDEVICE aDev)
-{
- AutoLock alock (this);
-
- /*
- * We have to be pretty conservative here because the proxy backend
- * doesn't necessarily know everything that's going on. So, rather
- * be overly careful than changing the state once when we shouldn't!
- */
- switch (aDev->enmState)
- {
- default:
- AssertMsgFailed (("aDev->enmState=%d\n", aDev->enmState));
- case USBDEVICESTATE_UNSUPPORTED:
- Assert (mState == USBDeviceState_NotSupported);
- return false;
-
- case USBDEVICESTATE_USED_BY_HOST:
- switch (mState)
- {
- case USBDeviceState_Unavailable:
- /* the proxy may confuse following states with unavailable */
- case USBDeviceState_Held:
- case USBDeviceState_Captured:
- return false;
- default:
- LogFlowMember ((" HostUSBDevice::updateState: %d -> %d\n",
- mState, USBDeviceState_Unavailable));
- mState = USBDeviceState_Unavailable;
- return true;
- }
- break;
-
- case USBDEVICESTATE_USED_BY_HOST_CAPTURABLE:
- switch (mState)
- {
- case USBDeviceState_Busy:
- /* the proxy may confuse following states with capturable */
- case USBDeviceState_Held:
- case USBDeviceState_Captured:
- return false;
- default:
- LogFlowMember ((" HostUSBDevice::updateState: %d -> %d\n",
- mState, USBDeviceState_Busy));
- mState = USBDeviceState_Busy;
- return true;
- }
- break;
-
- case USBDEVICESTATE_UNUSED:
- switch (mState)
- {
- case USBDeviceState_Available:
- /* the proxy may confuse following state(s) with available */
- case USBDeviceState_Held:
- case USBDeviceState_Captured:
- return false;
- default:
- LogFlowMember ((" HostUSBDevice::updateState: %d -> %d\n",
- mState, USBDeviceState_Available));
- mState = USBDeviceState_Available;
- return true;
- }
- break;
-
- case USBDEVICESTATE_HELD_BY_PROXY:
- switch (mState)
- {
- case USBDeviceState_Held:
- /* the proxy may confuse following state(s) with held */
- case USBDeviceState_Available:
- case USBDeviceState_Busy:
- case USBDeviceState_Captured:
- return false;
- default:
- LogFlowMember ((" HostUSBDevice::updateState: %d -> %d\n",
- mState, USBDeviceState_Held));
- mState = USBDeviceState_Held;
- return true;
- }
- break;
-
- case USBDEVICESTATE_USED_BY_GUEST:
- switch (mState)
- {
- case USBDeviceState_Captured:
- /* the proxy may confuse following state(s) with captured */
- case USBDeviceState_Held:
- case USBDeviceState_Available:
- case USBDeviceState_Busy:
- return false;
- default:
- LogFlowMember ((" HostUSBDevice::updateState: %d -> %d\n",
- mState, USBDeviceState_Held));
- mState = USBDeviceState_Held;
- return true;
- }
- break;
- }
-}
-
diff --git a/src/VBox/Frontends/VBoxBFE/HostUSBDeviceImpl.h b/src/VBox/Frontends/VBoxBFE/HostUSBDeviceImpl.h
deleted file mode 100644
index 336a9e9a2..000000000
--- a/src/VBox/Frontends/VBoxBFE/HostUSBDeviceImpl.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/** @file
- *
- * VBox frontends: Basic Frontend (BFE):
- * Declaration of HostUSBDevice
- */
-
-/*
- * Copyright (C) 2006-2007 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 ____H_HOSTUSBDEVICEIMPL
-#define ____H_HOSTUSBDEVICEIMPL
-
-#ifndef VBOXBFE_WITH_USB
-# error "misconfiguration VBOXBFE_WITH_USB isn't defined and HostUSBDeviceImpl.h was included."
-#endif
-#include <string>
-
-#include "VirtualBoxBase.h"
-// #include "USBDeviceFilterImpl.h"
-/* #include "USBProxyService.h" circular on Host/HostUSBDevice, the includer must include this. */
-// #include "Collection.h"
-
-#include <VBox/usb.h>
-#include <iprt/uuid.h>
-
-class USBProxyService;
-
-/**
- * The state of a given USB device in the host and in the guest.
- * Originally part of the COM interface.
- */
-typedef enum {
- /** Not supported by the VirtualBox server, not available to
- guests. */
- USBDeviceState_NotSupported,
- /** Being used by the host computer exclusively, not available
- to guests. */
- USBDeviceState_Unavailable,
- /** Being used by the host computer, potentially available to
- guests. */
- USBDeviceState_Busy,
- /** Not used by the host computer, available to guests. The
- host computer can also start using the device at any time. */
- USBDeviceState_Available,
- /** Held by the VirtualBox server (ignored by the host computer),
- available to guests. */
- USBDeviceState_Held,
- /** Captured by one of the guest computers, not available to
- anybody else. */
- USBDeviceState_Captured
-} USBDeviceState_T;
-
-/**
- * Object class used for the Host USBDevices property.
- */
-class HostUSBDevice : public VirtualBoxBase
-{
-public:
-
- HostUSBDevice();
- virtual ~HostUSBDevice();
-
- // public initializer/uninitializer for internal purposes only
- HRESULT init(PUSBDEVICE aUsb, USBProxyService *aUSBProxyService);
-
- // IUSBDevice properties
- STDMETHOD(COMGETTER(Id))(RTUUID &aId);
- STDMETHOD(COMGETTER(VendorId))(USHORT *aVendorId);
- STDMETHOD(COMGETTER(ProductId))(USHORT *aProductId);
- STDMETHOD(COMGETTER(Revision))(USHORT *aRevision);
- STDMETHOD(COMGETTER(Manufacturer))(std::string *aManufacturer);
- STDMETHOD(COMGETTER(Product))(std::string *aProduct);
- STDMETHOD(COMGETTER(SerialNumber))(std::string *aSerialNumber);
- STDMETHOD(COMGETTER(Address))(std::string *aAddress);
- STDMETHOD(COMGETTER(Port))(USHORT *aPort);
- STDMETHOD(COMGETTER(Remote))(BOOL *aRemote);
-
- // IHostUSBDevice properties
- STDMETHOD(COMGETTER(State))(USBDeviceState_T *aState);
-
- // public methods only for internal purposes
-
- const RTUUID &id() { return mId; }
- USBDeviceState_T state() { return mState; }
- bool isIgnored() { return mIgnored; }
-
- void setIgnored();
- void setCaptured ();
- bool isCaptured()
- { return mState == USBDeviceState_Captured; }
- int setHostDriven();
- int reset();
-
- void setHostState (USBDeviceState_T aState);
-
- int compare (PCUSBDEVICE pDev2);
- static int compare (PCUSBDEVICE pDev1, PCUSBDEVICE pDev2);
-
- bool updateState (PCUSBDEVICE aDev);
-
- // for VirtualBoxSupportErrorInfoImpl
- static const wchar_t *getComponentName() { return L"HostUSBDevice"; }
-
-private:
-
- RTUUID mId;
- USBDeviceState_T mState;
- bool mIgnored;
- /** Pointer to the USB Proxy Service instance. */
- USBProxyService *mUSBProxyService;
-
- /** Pointer to the USB Device structure owned by this device.
- * Only used for host devices. */
- PUSBDEVICE m_pUsb;
-};
-
-#endif // ____H_HOSTUSBDEVICEIMPL
diff --git a/src/VBox/Frontends/VBoxBFE/HostUSBImpl.cpp b/src/VBox/Frontends/VBoxBFE/HostUSBImpl.cpp
deleted file mode 100644
index db2c2ba26..000000000
--- a/src/VBox/Frontends/VBoxBFE/HostUSBImpl.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-/** @file
- *
- * VBox frontends: Basic Frontend (BFE):
- * Implementation of HostUSB
- */
-
-/*
- * Copyright (C) 2006-2007 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.
- */
-
-/* r=michael: I have removed almost all functionality from the Main
- * version of this file, but left the structure as similar
- * as I could in case we do need some of it some day. */
-
-#include <string>
-
-#ifdef RT_OS_LINUX
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <mntent.h>
-/* bird: This is a hack to work around conflicts between these linux kernel headers
- * and the GLIBC tcpip headers. They have different declarations of the 4
- * standard byte order functions. */
-#define _LINUX_BYTEORDER_GENERIC_H
-#include <linux/cdrom.h>
-#include <errno.h>
-#endif /* RT_OS_LINUX */
-
-#include "HostUSBImpl.h"
-#include "HostUSBDeviceImpl.h"
-#include "USBProxyService.h"
-#include "Logging.h"
-
-#include <VBox/vmm/pdm.h>
-#include <VBox/vusb.h>
-#include <VBox/usb.h>
-#include <VBox/err.h>
-#include <iprt/string.h>
-#include <iprt/time.h>
-#include <stdio.h>
-
-#include <algorithm>
-
-// destructor
-/////////////////////////////////////////////////////////////////////////////
-
-HostUSB::~HostUSB()
-{
- if (isReady())
- uninit();
-}
-
-// public initializer/uninitializer for internal purposes only
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Initializes the host USB object.
- *
- * @returns COM result indicator
- * @param parent handle of our parent object
- */
-HRESULT HostUSB::init(PVM pVM)
-{
- LogFlowMember(("HostUSB::init(): isReady=%d\n", isReady()));
-
- ComAssertRet (!isReady(), E_UNEXPECTED);
-
- /* Save pointer to the VM */
- mpVM = pVM;
-
-/*
-#ifdef RT_OS_LINUX
- mUSBProxyService = new USBProxyServiceLinux (this);
-#elif defined RT_OS_WINDOWS
- mUSBProxyService = new USBProxyServiceWin32 (this);
-*/
-#ifdef RT_OS_L4
- mUSBProxyService = new USBProxyServiceLinux (this);
-#else
- mUSBProxyService = new USBProxyService (this);
-#endif
- /** @todo handle !mUSBProxySerivce->isActive() and mUSBProxyService->getLastError()
- * and somehow report or whatever that the proxy failed to startup.
- * Also, there might be init order issues... */
-
- setReady(true);
- return S_OK;
-}
-
-/**
- * Uninitializes the host object and sets the ready flag to FALSE.
- * Called either from FinalRelease() or by the parent when it gets destroyed.
- */
-void HostUSB::uninit()
-{
- LogFlowMember(("HostUSB::uninit(): isReady=%d\n", isReady()));
-
- AssertReturn (isReady(), (void) 0);
-
- delete mUSBProxyService;
- mUSBProxyService = NULL;
-
- mUSBDevices.clear();
-
- setReady (FALSE);
-}
-
-// private methods
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Called by USB proxy service when a new device is physically attached
- * to the host.
- *
- * @param aDevice Pointer to the device which has been attached.
- */
-void HostUSB::onUSBDeviceAttached (HostUSBDevice *aDevice)
-{
- LogFlowMember (("HostUSB::onUSBDeviceAttached: aDevice=%p\n",
- aDevice));
- HostUSB::AutoLock alock (this);
-
- // add to the collecion
- mUSBDevices.push_back (aDevice);
-
- // apply all filters (no need to lock the device, nobody can access it yet)
- HRESULT rc = AttachUSBDevice(aDevice);
- AssertComRC (rc);
-}
-
-/**
- * Called by USB proxy service (?) when the device is physically detached
- * from the host.
- *
- * @param aDevice Pointer to the device which has been detached.
- */
-void HostUSB::onUSBDeviceDetached (HostUSBDevice *aDevice)
-{
- LogFlowMember (("HostUSB::onUSBDeviceDetached: aDevice=%p\n",
- &aDevice));
- HostUSB::AutoLock alock (this);
-
- RTUUID id = aDevice->id();
-
- HostUSBDevice *device = 0;
- HostUSB::USBDeviceList::iterator it = mUSBDevices.begin();
- while (it != mUSBDevices.end())
- {
- if (RTUuidCompare(&(*it)->id(), &id) == 0)
- {
- device = (*it);
- break;
- }
- ++ it;
- }
-
- AssertReturn (!!device, (void) 0);
-
- // remove from the collecion
- mUSBDevices.erase (it);
-
- if (device->isCaptured())
- {
- // the device is captured, release it
- alock.unlock();
- HRESULT rc = DetachUSBDevice (device);
- AssertComRC (rc);
- }
-}
-
-/**
- * Called by USB proxy service when the state of the host-driven device
- * has changed because of non proxy interaction.
- *
- * @param aDevice The device in question.
- */
-void HostUSB::onUSBDeviceStateChanged (HostUSBDevice *aDevice)
-{
- LogFlowMember (("HostUSB::onUSBDeviceStateChanged: \n"));
- HostUSB::AutoLock alock (this);
-
- /** @todo dmik, is there anything we should do here? For instance if the device now is available? */
-}
-
-STDMETHODIMP HostUSB::AttachUSBDevice (HostUSBDevice *hostDevice)
-{
- AutoLock alock (this);
- /* This originally checked that the console object was ready.
- * Unfortunately, this method now belongs to HostUSB, and can get
- * called during construction - so before we are "ready". */
-// CHECK_READY();
-
- /*
- * Don't proceed unless we've found the usb controller.
- */
- if (!mpVM)
- return setError (E_FAIL, tr ("VM is not powered up"));
- PPDMIBASE pBase;
- int vrc = PDMR3QueryLun (mpVM, "usb-ohci", 0, 0, &pBase);
- if (RT_FAILURE (vrc))
- return setError (E_FAIL, tr ("VM doesn't have a USB controller"));
- /*
- * Make sure that the device is in a captureable state
- */
- USBDeviceState_T eState = hostDevice->state();
- if (eState != USBDeviceState_Busy &&
- eState != USBDeviceState_Available &&
- eState != USBDeviceState_Held)
- return setError (E_FAIL,
- tr ("Device is not in a capturable state"));
- PVUSBIRHCONFIG pRhConfig = PDMIBASE_QUERY_INTERFACE(pBase, VUSBIRHCONFIG);
- AssertReturn(pRhConfig, E_FAIL);
-
- /*
- * Get the address and the Uuid, and call the pfnCreateProxyDevice roothub method in EMT.
- */
- std::string Address;
- HRESULT hrc = hostDevice->COMGETTER (Address) (&Address);
- AssertComRC (hrc);
-
- RTUUID Uuid;
- hrc = hostDevice->COMGETTER (Id) (Uuid);
- AssertComRC (hrc);
-
- /* No remote devices for now */
- BOOL fRemote = FALSE;
- void *pvRemote = NULL;
-
- LogFlowMember (("Console::AttachUSBDevice: Proxying USB device '%s' %RTuuid...\n", Address.c_str(), &Uuid));
- vrc = VMR3ReqCallWait (mpVM, VMCPUID_ANY,
- (PFNRT)pRhConfig->pfnCreateProxyDevice,
- 5, pRhConfig, &Uuid, fRemote,
- Address.c_str(), pvRemote);
- if (RT_SUCCESS (vrc))
- hostDevice->setCaptured();
- else
- {
- Log (("Console::AttachUSBDevice: Failed to create proxy device for '%s' %RTuuid, vrc=%Rrc\n", Address.c_str(),
- &Uuid, vrc));
- AssertRC (vrc);
- /* michael: I presume this is not needed. */
-/* hrc = mControl->ReleaseUSBDevice (Uuid);
- AssertComRC (hrc); */
- switch (vrc)
- {
- case VERR_VUSB_NO_PORTS:
- hrc = setError (E_FAIL, tr ("No available ports on the USB controller"));
- break;
- case VERR_VUSB_USBFS_PERMISSION:
- hrc = setError (E_FAIL, tr ("Not permitted to open the USB device, check usbfs options"));
- break;
- default:
- hrc = setError (E_FAIL, tr ("Failed to create USB proxy device: %Rrc"), vrc);
- break;
- }
- return hrc;
- }
-
- return S_OK;
-}
-
-STDMETHODIMP HostUSB::DetachUSBDevice (HostUSBDevice *aDevice)
-{
- AutoLock alock (this);
- /* This originally checked that the console object was ready.
- * Unfortunately, this method now belongs to HostUSB, and can get
- * called during construction - so before we are "ready". */
-// CHECK_READY();
-
- /*
- * Detach the device from the VM
- */
- int vrc = VERR_PDM_DEVICE_NOT_FOUND;
- if (mpVM)
- {
- PPDMIBASE pBase;
- vrc = PDMR3QueryLun (mpVM, "usb-ohci", 0, 0, &pBase);
- if (RT_SUCCESS (vrc))
- {
- PVUSBIRHCONFIG pRhConfig = PDMIBASE_QUERY_INTERFACE(pBase, VUSBIRHCONFIG);
- Assert(pRhConfig);
-
- RTUUID Uuid = aDevice->id();
- LogFlowMember (("Console::DetachUSBDevice: Detaching USB proxy device %RTuuid...\n", &Uuid));
- vrc = VMR3ReqCallWait (mpVM, VMCPUID_ANY, (PFNRT)pRhConfig->pfnDestroyProxyDevice,
- 2, pRhConfig, &Uuid);
- }
- }
- if ( vrc == VERR_PDM_DEVICE_NOT_FOUND
- || vrc == VERR_PDM_DEVICE_INSTANCE_NOT_FOUND)
- {
- Log (("Console::DetachUSBDevice: USB isn't enabled.\n"));
- vrc = VINF_SUCCESS;
- }
- if (RT_SUCCESS (vrc))
- return S_OK;
- Log (("Console::AttachUSBDevice: Failed to detach the device from the USB controller, vrc=%Rrc.\n", vrc));
- return(setError (E_UNEXPECTED, tr ("Failed to destroy the USB proxy device: %Rrc"), vrc));
-}
diff --git a/src/VBox/Frontends/VBoxBFE/HostUSBImpl.h b/src/VBox/Frontends/VBoxBFE/HostUSBImpl.h
deleted file mode 100644
index 6589d9904..000000000
--- a/src/VBox/Frontends/VBoxBFE/HostUSBImpl.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/** @file
- *
- * VBox frontends: Basic Frontend (BFE):
- * Declaration of HostUSB
- */
-
-/*
- * Copyright (C) 2006-2007 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 ____H_HOSTUSBIMPL
-#define ____H_HOSTUSBIMPL
-
-#ifndef VBOXBFE_WITH_USB
-# error "misconfiguration VBOXBFE_WITH_USB isn't defined and HostUSBImpl.h was included."
-#endif
-
-#include "VirtualBoxBase.h"
-#include "HostUSBDeviceImpl.h"
-
-/* We do not support loadable configurations here */
-// #include <VBox/settings.h>
-
-#include <list>
-
-class HostUSB :
- public VirtualBoxBase
-{
-public:
- ~HostUSB();
-
- // public initializer/uninitializer for internal purposes only
- HRESULT init (PVM pVM);
- void uninit();
-
- // public methods only for internal purposes
-
- void onUSBDeviceAttached (HostUSBDevice *aDevice);
- void onUSBDeviceDetached (HostUSBDevice *aDevice);
- void onUSBDeviceStateChanged (HostUSBDevice *aDevice);
-
- USBProxyService *usbProxyService() { return mUSBProxyService; }
-
-private:
-
- typedef std::list <HostUSBDevice *> USBDeviceList;
- USBDeviceList mUSBDevices;
-
- /** Pointer to the VM */
- PVM mpVM;
-
- /** Pointer to the USBProxyService object. */
- USBProxyService *mUSBProxyService;
-
- STDMETHODIMP AttachUSBDevice (HostUSBDevice *hostDevice);
- STDMETHODIMP DetachUSBDevice (HostUSBDevice *aDevice);
-};
-
-#endif // ____H_HOSTUSBIMPL
diff --git a/src/VBox/Frontends/VBoxBFE/KeyboardImpl.cpp b/src/VBox/Frontends/VBoxBFE/KeyboardImpl.cpp
index 9c40b20e4..42195032e 100644
--- a/src/VBox/Frontends/VBoxBFE/KeyboardImpl.cpp
+++ b/src/VBox/Frontends/VBoxBFE/KeyboardImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: KeyboardImpl.cpp $ */
+/* $Id: KeyboardImpl.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBox frontends: Basic Frontend (BFE):
* Implementation of Keyboard class and related things
diff --git a/src/VBox/Frontends/VBoxBFE/KeyboardImpl.h b/src/VBox/Frontends/VBoxBFE/KeyboardImpl.h
index 434da9f14..0e6c3aff3 100644
--- a/src/VBox/Frontends/VBoxBFE/KeyboardImpl.h
+++ b/src/VBox/Frontends/VBoxBFE/KeyboardImpl.h
@@ -1,4 +1,4 @@
-/* $Id: KeyboardImpl.h $ */
+/* $Id: KeyboardImpl.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBox frontends: Basic Frontend (BFE):
* Declaration of Keyboard class and related things
diff --git a/src/VBox/Frontends/VBoxBFE/Makefile.kmk b/src/VBox/Frontends/VBoxBFE/Makefile.kmk
index 6e9582723..e8ca179af 100644
--- a/src/VBox/Frontends/VBoxBFE/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxBFE/Makefile.kmk
@@ -1,10 +1,10 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 36586 2011-04-06 15:19:46Z vboxsync $
## @file
# Sub-Makefile for VBoxBFE (a basic frontend which doesn't make use of Main).
#
#
-# Copyright (C) 2006-2007 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;
@@ -56,7 +56,6 @@ ifdef VBOX_WITH_LINUX_COMPILER_H
VBoxBFE_DEFS += VBOX_WITH_LINUX_COMPILER_H
endif
VBoxBFE_DEFS.freebsd = VBOXBFE_WITH_X11
-VBoxBFE_DEFS.l4 = _GNU_SOURCE
VBoxBFE_DEFS.linux = _GNU_SOURCE VBOXBFE_WITH_X11
VBoxBFE_DEFS.solaris = VBOXBFE_WITH_X11
ifdef VBOX_WITH_CROSSBOW
@@ -85,39 +84,18 @@ endif
VBoxBFE_SOURCES.darwin = \
VBoxBFEMain-darwin.m
-VBoxBFE_SOURCES.l4 = \
- L4Console.cpp \
- L4Framebuffer.cpp \
- L4IDLInterface.cpp \
- EmulCpp.cpp
-
# SDL
-ifneq ($(KBUILD_TARGET),l4)
VBoxBFE_SDKS += LIBSDL
VBoxBFE_DEFS += USE_SDL
VBoxBFE_SOURCES += \
SDLConsole.cpp \
SDLFramebuffer.cpp
-endif
-
-# USB Support
-if1of ($(KBUILD_TARGET), l4 win)
-VBoxBFE_DEFS += VBOXBFE_WITH_USB
-VBoxBFE_SOURCES += \
- HostUSBImpl.cpp \
- HostUSBDeviceImpl.cpp \
- USBProxyService.cpp
-VBoxBFE_SOURCES.l4 += \
- USBProxyServiceLinux.cpp
-VBoxBFE_SOURCES.linux += \
- USBProxyServiceLinux.cpp
-endif
VBoxBFE_INCS = \
$(VBoxBFE_0_OUTDIR) \
$(VBOX_PATH_SDK)/include \
$(PATH_ROOT)/src/VBox/Frontends/VBoxBFE
-ifneq ($(filter-out win os2 l4 darwin,$(KBUILD_TARGET)),) # X11
+ifneq ($(filter-out win os2 darwin,$(KBUILD_TARGET)),) # X11
VBoxBFE_INCS += \
$(VBOX_XCURSOR_INCS)
endif
@@ -125,11 +103,11 @@ endif
VBoxBFE_LIBS = \
$(LIB_RUNTIME) \
$(LIB_VMM)
-ifneq ($(filter-out win os2 l4,$(KBUILD_TARGET)),)
+ifneq ($(filter-out win os2,$(KBUILD_TARGET)),)
VBoxBFE_LIBS += \
$(LIB_REM)
endif
-ifneq ($(filter-out win os2 l4 darwin,$(KBUILD_TARGET)),) # X11
+ifneq ($(filter-out win os2 darwin,$(KBUILD_TARGET)),) # X11
VBoxBFE_LIBS += \
$(VBOX_XCURSOR_LIBS) \
X11
@@ -140,17 +118,10 @@ ifndef VBOX_WITHOUT_COM
VBoxBFE_LIBS.win = \
$(PATH_TOOL_$(VBOX_VCC_TOOL)_ATLMFC_LIB)/atls.lib
endif
-VBoxBFE_LIBS.l4 = \
- $(L4_LIBDIR)/libl4con-idl.a \
- $(L4_LIBDIR)/libconstream-server.a \
- $(L4_LIBDIR)/libvboxctrl-server.a \
- $(L4_LIBDIR)/libl4sys.a
VBoxBFE_LIBS.darwin = \
$(LIB_SDK_LIBSDL_SDLMAIN)
VBoxBFE_LDFLAGS.darwin = -framework Foundation -framework AppKit
-VBoxBFE_CXXFLAGS.l4 += -fno-rtti -nostdinc -Wno-non-virtual-dtor \
- $(addprefix -I,$(VBOX_L4_GCC3_INCS) $(L4_INCDIR))
## @todo why is it all this cool stuff here only for linux? If it's important, -fshort-wchar would apply to all GCC platforms.
VBoxBFE_DEFS.linux = \
NDEBUG TRIMMED
@@ -166,8 +137,8 @@ $$(VBoxBFE_0_OUTDIR)/Ico64x01.h: $(PATH_ROOT)/src/VBox/Frontends/VBoxBFE/ico64x0
$(QUIET)$(VBOX_BIN2C) Ico64x01 $< $@
# Files we share with Main needs to be copied into the output dir.
-VBoxBFE_INTERMEDIATES += $(addprefix $(VBoxBFE_0_OUTDIR)/,$(VBOXBFE_MAIN_HDRS))
-VBoxBFE_CLEAN += $(addprefix $(VBoxBFE_0_OUTDIR)/, $(VBOXBFE_MAIN_HDRS) $(VBOXBFE_MAIN_SRCS))
+VBoxBFE_INTERMEDIATES = $(addprefix $(VBoxBFE_0_OUTDIR)/, $(VBOXBFE_MAIN_HDRS))
+VBoxBFE_CLEAN += $(addprefix $(VBoxBFE_0_OUTDIR)/, $(VBOXBFE_MAIN_HDRS) $(notdir $(VBOXBFE_MAIN_SRCS)))
define def_copy_main_file
$$(VBoxBFE_0_OUTDIR)/$(notdir $(file)): $(PATH_ROOT)/src/VBox/Main/$(file) | $$(dir $$@)
@@ -179,6 +150,24 @@ $(foreach file,$(VBOXBFE_MAIN_SRCS), $(evalval def_copy_main_file))
+if !defined(VBOX_ONLY_SDK) && defined(VBOX_WITH_TESTCASES)
+ #
+ # tstMouseImpl
+ #
+ PROGRAMS += tstMouseImpl
+ tstMouseImpl_TEMPLATE = VBOXR3TSTEXE
+ tstMouseImpl_DEFS = VBOXBFE_WITHOUT_COM
+ tstMouseImpl_SOURCES = \
+ testcase/tstMouseImpl.cpp \
+ $(addprefix $(VBoxBFE_0_OUTDIR)/,$(notdir $(VBOXBFE_MAIN_SRCS)))
+ tstMouseImpl_INCS = \
+ $(VBoxBFE_0_OUTDIR) \
+ $(VBOX_PATH_SDK)/include \
+ .
+ tstMouseImpl_INTERMEDIATES = $(addprefix $(VBoxBFE_0_OUTDIR)/, $(VBOXBFE_MAIN_HDRS))
+endif # !VBOX_ONLY_SDK
+
+
endif # !VBOX_WITH_HARDENING || !darwin
include $(KBUILD_PATH)/subfooter.kmk
diff --git a/src/VBox/Frontends/VBoxBFE/StatusImpl.cpp b/src/VBox/Frontends/VBoxBFE/StatusImpl.cpp
index c4906487a..181f9f846 100644
--- a/src/VBox/Frontends/VBoxBFE/StatusImpl.cpp
+++ b/src/VBox/Frontends/VBoxBFE/StatusImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: StatusImpl.cpp $ */
+/* $Id: StatusImpl.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBox frontends: Basic Frontend (BFE):
* Implementation of VMStatus class
diff --git a/src/VBox/Frontends/VBoxBFE/StatusImpl.h b/src/VBox/Frontends/VBoxBFE/StatusImpl.h
index 83347d4a1..c66cb1c5f 100644
--- a/src/VBox/Frontends/VBoxBFE/StatusImpl.h
+++ b/src/VBox/Frontends/VBoxBFE/StatusImpl.h
@@ -1,4 +1,4 @@
-/* $Id: StatusImpl.h $ */
+/* $Id: StatusImpl.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBox frontends: Basic Frontend (BFE):
* Declaration of VMStatus class
diff --git a/src/VBox/Frontends/VBoxBFE/USBProxyService.cpp b/src/VBox/Frontends/VBoxBFE/USBProxyService.cpp
deleted file mode 100644
index 6ab6c97e7..000000000
--- a/src/VBox/Frontends/VBoxBFE/USBProxyService.cpp
+++ /dev/null
@@ -1,386 +0,0 @@
-/** @file
- *
- * VBox frontends: Basic Frontend (BFE):
- * Implementation of USBProxyService class
- */
-
-/*
- * Copyright (C) 2006-2007 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#include "USBProxyService.h"
-#include "Logging.h"
-
-#include <VBox/err.h>
-#include <iprt/asm.h>
-#include <iprt/semaphore.h>
-
-
-
-/** @todo add the required locking. */
-
-/**
- * Initialize data members.
- */
-USBProxyService::USBProxyService (HostUSB *aHost)
- : mHost (aHost), mThread (NIL_RTTHREAD), mTerminate (false), mDevices (), mLastError (VINF_SUCCESS)
-{
- LogFlowMember (("USBProxyService::USBProxyService: aHost=%p\n", aHost));
-}
-
-
-/**
- * Empty destructor.
- */
-USBProxyService::~USBProxyService()
-{
- LogFlowMember (("USBProxyService::~USBProxyService: \n"));
- Assert (mThread == NIL_RTTHREAD);
- mDevices.clear();
- mTerminate = true;
- mHost = NULL;
-}
-
-
-bool USBProxyService::isActive (void)
-{
- return mThread != NIL_RTTHREAD;
-}
-
-
-int USBProxyService::getLastError (void)
-{
- return mLastError;
-}
-
-
-int USBProxyService::start (void)
-{
- int rc = VINF_SUCCESS;
- if (mThread == NIL_RTTHREAD)
- {
- /*
- * Force update before starting the poller thread.
- */
- wait (0);
- processChanges ();
-
- /*
- * Create the poller thread which will look for changes.
- */
- mTerminate = false;
- rc = RTThreadCreate (&mThread, USBProxyService::serviceThread, this,
- 0, RTTHREADTYPE_INFREQUENT_POLLER, RTTHREADFLAGS_WAITABLE, "USBPROXY");
- AssertRC (rc);
- if (RT_SUCCESS (rc))
- LogFlow (("USBProxyService::start: started mThread=%RTthrd\n", mThread));
- else
- {
- mThread = NIL_RTTHREAD;
- mLastError = rc;
- }
- }
- else
- LogFlow (("USBProxyService::start: already running, mThread=%RTthrd\n", mThread));
- return rc;
-}
-
-
-int USBProxyService::stop (void)
-{
- int rc = VINF_SUCCESS;
- if (mThread != NIL_RTTHREAD)
- {
- /*
- * Mark the thread for termination and kick it.
- */
- ASMAtomicXchgSize (&mTerminate, true);
- rc = interruptWait();
- AssertRC (rc);
-
- /*
- * Wait for the thread to finish and then update the state.
- */
- rc = RTThreadWait (mThread, 60000, NULL);
- if (rc == VERR_INVALID_HANDLE)
- rc = VINF_SUCCESS;
- if (RT_SUCCESS (rc))
- {
- LogFlowMember (("USBProxyService::stop: stopped mThread=%RTthrd\n", mThread));
- mThread = NIL_RTTHREAD;
- mTerminate = false;
- }
- else
- {
- AssertRC (rc);
- mLastError = rc;
- }
- }
- else
- LogFlowMember (("USBProxyService::stop: not active\n"));
-
- return rc;
-}
-
-
-/**
- * Sort a list of USB devices.
- *
- * @returns Pointer to the head of the sorted doubly linked list.
- * @param aDevices Head pointer (can be both singly and doubly linked list).
- */
-static PUSBDEVICE sortDevices (PUSBDEVICE pDevices)
-{
- PUSBDEVICE pHead = NULL;
- PUSBDEVICE pTail = NULL;
- while (pDevices)
- {
- /* unlink head */
- PUSBDEVICE pDev = pDevices;
- pDevices = pDev->pNext;
- if (pDevices)
- pDevices->pPrev = NULL;
-
- /* find location. */
- PUSBDEVICE pCur = pTail;
- while ( pCur
- && HostUSBDevice::compare (pCur, pDev) > 0)
- pCur = pCur->pPrev;
-
- /* insert (after pCur) */
- pDev->pPrev = pCur;
- if (pCur)
- {
- pDev->pNext = pCur->pNext;
- pCur->pNext = pDev;
- if (pDev->pNext)
- pDev->pNext->pPrev = pDev;
- else
- pTail = pDev;
- }
- else
- {
- pDev->pNext = pHead;
- if (pHead)
- pHead->pPrev = pDev;
- else
- pTail = pDev;
- pHead = pDev;
- }
- }
-
- return pHead;
-}
-
-
-void USBProxyService::processChanges (void)
-{
- LogFlowMember (("USBProxyService::processChanges: \n"));
-
- /*
- * Get the sorted list of USB devices.
- */
- PUSBDEVICE pDevices = getDevices();
- if (pDevices)
- {
- pDevices = sortDevices (pDevices);
-
- /*
- * Compare previous list with the previous list of devices
- * and merge in any changes while notifying Host.
- */
- HostUSBDeviceList::iterator It = this->mDevices.begin();
- while ( It != mDevices.end()
- || pDevices)
- {
- /*
- * Compare.
- */
- HostUSBDevice *DevPtr = 0; /* shut up gcc */
- int iDiff;
- if (It == mDevices.end())
- iDiff = 1;
- else
- {
- DevPtr = *It;
- if (!pDevices)
- iDiff = -1;
- else
- iDiff = DevPtr->compare (pDevices);
- }
- if (!iDiff)
- {
- /*
- * Device still there, update the state and move on.
- */
- if (DevPtr->updateState (pDevices))
- mHost->onUSBDeviceStateChanged (DevPtr);
- It++;
- PUSBDEVICE pFree = pDevices;
- pDevices = pDevices->pNext; /* treated as singly linked */
- freeDevice (pFree);
- /** @todo detect status changes! */
- }
- else
- {
- if (iDiff > 0)
- {
- /*
- * Head of pDevices was attached.
- */
- PUSBDEVICE pNew = pDevices;
- pDevices = pDevices->pNext;
- pNew->pPrev = pNew->pNext = NULL;
-
- HostUSBDevice *NewObj = new HostUSBDevice;
- NewObj->init (pNew, this);
- Log (("USBProxyService::processChanges: attached %p/%p:{.idVendor=%#06x, .idProduct=%#06x, .pszProduct=\"%s\", .pszManufacturer=\"%s\"}\n",
- NewObj, pNew, pNew->idVendor, pNew->idProduct,
- pNew->pszProduct, pNew->pszManufacturer));
-
- mDevices.insert (It, NewObj);
- mHost->onUSBDeviceAttached (NewObj);
- }
- else
- {
- /*
- * DevPtr was detached.
- */
- It = mDevices.erase (It);
- mHost->onUSBDeviceDetached (DevPtr);
- Log (("USBProxyService::processChanges: detached %p\n", (HostUSBDevice *)DevPtr)); /** @todo add details .*/
- }
- }
- } /* while */
- }
- else
- {
- /* All devices were detached */
- HostUSBDeviceList::iterator It = this->mDevices.begin();
- while (It != mDevices.end())
- {
- HostUSBDevice *DevPtr = *It;
- /*
- * DevPtr was detached.
- */
- It = mDevices.erase (It);
- mHost->onUSBDeviceDetached (DevPtr);
- Log (("USBProxyService::processChanges: detached %p\n", (HostUSBDevice *)DevPtr)); /** @todo add details .*/
- }
- }
-
- LogFlowMember (("USBProxyService::processChanges: returns void\n"));
-}
-
-
-/*static*/ DECLCALLBACK (int) USBProxyService::serviceThread (RTTHREAD Thread, void *pvUser)
-{
- USBProxyService *pThis = (USBProxyService *)pvUser;
- LogFlow (("USBProxyService::serviceThread: pThis=%p\n", pThis));
-
- /*
- * Processing loop.
- */
- for (;;)
- {
- pThis->wait (RT_INDEFINITE_WAIT);
- if (pThis->mTerminate)
- break;
- pThis->processChanges();
- }
-
- LogFlow (("USBProxyService::serviceThread: returns VINF_SUCCESS\n"));
- return VINF_SUCCESS;
-}
-
-
-/*static*/ void USBProxyService::freeDevice (PUSBDEVICE pDevice)
-{
- RTStrFree ((char *)pDevice->pszManufacturer);
- pDevice->pszManufacturer = NULL;
- RTStrFree ((char *)pDevice->pszProduct);
- pDevice->pszProduct = NULL;
- RTStrFree ((char *)pDevice->pszSerialNumber);
- pDevice->pszSerialNumber = NULL;
-
- RTStrFree ((char *)pDevice->pszAddress);
- pDevice->pszAddress = NULL;
-
- RTMemFree (pDevice);
-
-}
-
-
-/* static */ uint64_t USBProxyService::calcSerialHash (const char *aSerial)
-{
- if (!aSerial)
- aSerial = "";
-
- register const uint8_t *pu8 = (const uint8_t *)aSerial;
- register uint64_t u64 = 14695981039346656037ULL;
- for (;;)
- {
- register uint8_t u8 = *pu8;
- if (!u8)
- break;
- u64 = (u64 * 1099511628211ULL) ^ u8;
- pu8++;
- }
-
- return u64;
-}
-
-
-
-/* Stubs which the host specific classes overrides: */
-
-
-int USBProxyService::wait (unsigned aMillies)
-{
- return RTThreadSleep (250);
-}
-
-
-int USBProxyService::interruptWait (void)
-{
- return VERR_NOT_IMPLEMENTED;
-}
-
-
-PUSBDEVICE USBProxyService::getDevices (void)
-{
- return NULL;
-}
-
-
-int USBProxyService::captureDevice (HostUSBDevice *pDevice)
-{
- return VERR_NOT_IMPLEMENTED;
-}
-
-
-int USBProxyService::holdDevice (HostUSBDevice *pDevice)
-{
- return VERR_NOT_IMPLEMENTED;
-}
-
-
-int USBProxyService::releaseDevice (HostUSBDevice *pDevice)
-{
- return VERR_NOT_IMPLEMENTED;
-}
-
-
-int USBProxyService::resetDevice (HostUSBDevice *pDevice)
-{
- return VERR_NOT_IMPLEMENTED;
-}
-
diff --git a/src/VBox/Frontends/VBoxBFE/USBProxyService.h b/src/VBox/Frontends/VBoxBFE/USBProxyService.h
deleted file mode 100644
index 2e4188027..000000000
--- a/src/VBox/Frontends/VBoxBFE/USBProxyService.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/** @file
- *
- * VBox frontends: Basic Frontend (BFE):
- * Declaration of USBProxyService and USBProxyServiceLinux classes
- */
-
-/*
- * Copyright (C) 2006-2007 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 ____H_USBPROXYSERVICE
-#define ____H_USBPROXYSERVICE
-
-#ifndef VBOXBFE_WITH_USB
-# error "misconfiguration VBOXBFE_WITH_USB isn't defined and USBProxyService.h was included."
-#endif
-
-#include "HostUSBImpl.h"
-#include "HostUSBDeviceImpl.h"
-
-/**
- * Base class for the USB Proxy service.
- */
-class USBProxyService
-{
-public:
- USBProxyService (HostUSB *aHost);
- virtual ~USBProxyService();
-
- /**
- * A VM is trying to capture a device, do necessary preparations.
- *
- * @returns VBox status code.
- * @param pDevice The device in question.
- */
- virtual int captureDevice (HostUSBDevice *pDevice);
-
- /**
- * The device is to be held so that the host OS will not start using it.
- *
- * @returns VBox status code.
- * @param pDevice The device in question.
- */
- virtual int holdDevice (HostUSBDevice *pDevice);
-
- /**
- * A VM is releasing a device back to the host.
- *
- * @returns VBox status code.
- * @param pDevice The device in question.
- */
- virtual int releaseDevice (HostUSBDevice *pDevice);
-
- /**
- * A VM is releasing a device back to be held or assigned to another VM.
- * A port reset should be performed.
- *
- * @returns VBox status code.
- * @param pDevice The device in question.
- */
- virtual int resetDevice (HostUSBDevice *pDevice);
-
- /**
- * Query if the service is active and working.
- *
- * @returns true if the service is up running.
- * @returns false if the service isn't running.
- */
- bool isActive (void);
-
- /**
- * Get last error.
- * Can be used to check why the proxy !isActive() upon construction.
- *
- * @returns VBox status code.
- */
- int getLastError (void);
-
- /**
- * Calculate the hash of the serial string.
- *
- * 64bit FNV1a, chosen because it is designed to hash in to a power of two
- * space, and is much quicker and simpler than, say, a half MD4.
- *
- * @returns the hash.
- * @param aSerial The serial string.
- */
- static uint64_t calcSerialHash (const char *aSerial);
-
-protected:
-
- /**
- * Starts the service.
- *
- * @returns VBox status.
- */
- int start (void);
-
- /**
- * Stops the service.
- *
- * @returns VBox status.
- */
- int stop (void);
-
- /**
- * Wait for a change in the USB devices attached to the host.
- *
- * @returns VBox status (ignored).
- * @param aMillies Number of milliseconds to wait.
- */
- virtual int wait (unsigned aMillies);
-
- /**
- * Interrupt any wait() call in progress.
- *
- * @returns VBox status.
- */
- virtual int interruptWait (void);
-
- /**
- * Get a list of USB device currently attached to the host.
- *
- * @returns Pointer to a list of USB devices.
- * The list nodes are freed individually by calling freeDevice().
- */
- virtual PUSBDEVICE getDevices (void);
-
-public:
- /**
- * Free one USB device returned by getDevice().
- *
- * @param pDevice Pointer to the device.
- */
- static void freeDevice (PUSBDEVICE pDevice);
-
-private:
- /**
- * Process any relevant changes in the attached USB devices.
- */
- void processChanges (void);
-
- /**
- * The service thread created by start().
- *
- * @param Thread The thread handle.
- * @param pvUser Pointer to the USBProxyService instance.
- */
- static DECLCALLBACK (int) serviceThread (RTTHREAD Thread, void *pvUser);
-
-protected:
- /** Pointer to the HostUSB object. */
- HostUSB *mHost;
- /** Thread handle of the service thread. */
- RTTHREAD mThread;
- /** Flag which stop() sets to cause serviceThread to return. */
- bool volatile mTerminate;
- /** List of smart HostUSBDevice pointers. */
- typedef std::list <HostUSBDevice *> HostUSBDeviceList;
- /** List of the known USB devices. */
- HostUSBDeviceList mDevices;
- /** VBox status code of the last failure.
- * (Only used by start(), stop() and the child constructors.) */
- int mLastError;
-};
-
-
-#if defined(RT_OS_LINUX) || defined(RT_OS_L4)
-#include <stdio.h>
-
-/**
- * The Linux hosted USB Proxy Service.
- */
-class USBProxyServiceLinux : public USBProxyService
-{
-public:
- USBProxyServiceLinux (HostUSB *aHost, const char *aUsbfsRoot = "/proc/bus/usb");
- ~USBProxyServiceLinux();
-
- virtual int captureDevice (HostUSBDevice *aDevice);
- virtual int holdDevice (HostUSBDevice *aDevice);
- virtual int releaseDevice (HostUSBDevice *aDevice);
- virtual int resetDevice (HostUSBDevice *aDevice);
-
-protected:
- virtual int wait (unsigned aMillies);
- virtual int interruptWait (void);
- virtual PUSBDEVICE getDevices (void);
-
-private:
- /** File handle to the '/proc/bus/usb/devices' file. */
- RTFILE mFile;
- /** Stream for mFile. */
- FILE *mStream;
- /** Pipe used to interrupt wait(), the read end. */
- RTFILE mWakeupPipeR;
- /** Pipe used to interrupt wait(), the write end. */
- RTFILE mWakeupPipeW;
- /** The root of usbfs. */
- std::string mUsbfsRoot;
-};
-#endif /* RT_OS_LINUX */
-
-
-#ifdef RT_OS_WINDOWS
-/**
- * The Win32/Win64 hosted USB Proxy Service.
- */
-class USBProxyServiceWin32 : public USBProxyService
-{
-public:
- USBProxyServiceWin32 (HostUSB *aHost);
- ~USBProxyServiceWin32();
-
- virtual int captureDevice (HostUSBDevice *aDevice);
- virtual int holdDevice (HostUSBDevice *aDevice);
- virtual int releaseDevice (HostUSBDevice *aDevice);
- virtual int resetDevice (HostUSBDevice *aDevice);
-
-protected:
- virtual int wait (unsigned aMillies);
- virtual int interruptWait (void);
- virtual PUSBDEVICE getDevices (void);
-
-private:
-
- HANDLE hEventInterrupt;
-};
-#endif
-
-
-#endif /* !____H_USBPROXYSERVICE */
diff --git a/src/VBox/Frontends/VBoxBFE/USBProxyServiceLinux.cpp b/src/VBox/Frontends/VBoxBFE/USBProxyServiceLinux.cpp
deleted file mode 100644
index 042866713..000000000
--- a/src/VBox/Frontends/VBoxBFE/USBProxyServiceLinux.cpp
+++ /dev/null
@@ -1,1051 +0,0 @@
-/* $Id: USBProxyServiceLinux.cpp $ */
-/** @file
- * VBox frontends: Basic Frontend (BFE):
- * Implementation of USBProxyServiceLinux class
- *
- * WARNING: This file needs to be resynced and is currently disabled.
- */
-
-/*
- * Copyright (C) 2006-2007 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 "USBProxyService.h"
-#include "Logging.h"
-
-#include <VBox/usb.h>
-#include <VBox/err.h>
-
-#include <iprt/alloc.h>
-#include <iprt/ctype.h>
-#include <iprt/string.h>
-#include <iprt/assert.h>
-#include <iprt/file.h>
-#include <iprt/err.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <sys/statfs.h>
-#include <sys/poll.h>
-#include <unistd.h>
-#ifdef VBOX_WITH_LINUX_COMPILER_H
-# include <linux/compiler.h>
-#endif
-#include <linux/usbdevice_fs.h>
-
-
-
-/*******************************************************************************
-* Structures and Typedefs *
-*******************************************************************************/
-/** Suffix translation. */
-typedef struct USBSUFF
-{
- char szSuff[4];
- unsigned cchSuff;
- unsigned uMul;
- unsigned uDiv;
-} USBSUFF, *PUSBSUFF;
-typedef const USBSUFF *PCUSBSUFF;
-
-
-/*******************************************************************************
-* Global Variables *
-*******************************************************************************/
-/**
- * Suffixes for the endpoint polling interval.
- */
-static const USBSUFF s_aIntervalSuff[] =
-{
- { "ms", 2, 1, 0 },
- { "us", 2, 1, 1000 },
- { "ns", 2, 1, 1000000 },
- { "s", 1, 1000, 0 },
- { "", 0, 0, 0 } /* term */
-};
-
-
-/**
- * Initialize data members.
- */
-USBProxyServiceLinux::USBProxyServiceLinux (HostUSB *aHost, const char *aUsbfsRoot /* = "/proc/bus/usb" */)
- : USBProxyService (aHost), mFile (NIL_RTFILE), mStream (NULL), mWakeupPipeR (NIL_RTFILE),
- mWakeupPipeW (NIL_RTFILE), mUsbfsRoot (aUsbfsRoot)
-{
- LogFlowMember (("USBProxyServiceLinux::USBProxyServiceLinux: aHost=%p aUsbfsRoot=%p:{%s}\n", aHost, aUsbfsRoot, aUsbfsRoot));
-
- /*
- * Open the devices file.
- */
- int rc = VERR_NO_MEMORY;
- char *pszDevices;
- RTStrAPrintf (&pszDevices, "%s/devices", aUsbfsRoot);
- if (pszDevices)
- {
- rc = RTFileOpen (&mFile, pszDevices, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
- if (RT_SUCCESS (rc))
- {
- /*
- * Check that we're actually on the usbfs.
- */
- struct statfs StFS;
- if (!fstatfs (mFile, &StFS))
- {
- if (StFS.f_type == USBDEVICE_SUPER_MAGIC)
- {
- int pipes[2];
- if (!pipe (pipes))
- {
- mWakeupPipeR = pipes[0];
- mWakeupPipeW = pipes[1];
- mStream = fdopen (mFile, "r");
- if (mStream)
- {
- /*
- * Start the poller thread.
- */
- rc = start();
- if (RT_SUCCESS (rc))
- {
- RTStrFree (pszDevices);
- LogFlowMember (("USBProxyServiceLinux::USBProxyServiceLinux: returns successfully - mFile=%d mStream=%p mWakeupPipeR/W=%d/%d\n",
- mFile, mStream, mWakeupPipeR, mWakeupPipeW));
- return;
- }
-
- fclose (mStream);
- mStream = NULL;
- mFile = NIL_RTFILE;
- }
-
- RTFileClose (mWakeupPipeR);
- RTFileClose (mWakeupPipeW);
- mWakeupPipeW = mWakeupPipeR = NIL_RTFILE;
- }
- }
- else
- {
- Log (("USBProxyServiceLinux::USBProxyServiceLinux: StFS.f_type=%d expected=%d\n", StFS.f_type, USBDEVICE_SUPER_MAGIC));
- rc = VERR_INVALID_PARAMETER;
- }
- }
- else
- {
- rc = RTErrConvertFromErrno (errno);
- Log (("USBProxyServiceLinux::USBProxyServiceLinux: fstatfs failed, errno=%d\n", errno));
- }
- RTFileClose (mFile);
- mFile = NIL_RTFILE;
- }
- else
- {
-#ifndef DEBUG_fm3
- /* I'm currently using Linux with disabled USB support */
- AssertRC (rc);
-#endif
- Log (("USBProxyServiceLinux::USBProxyServiceLinux: RTFileOpen(,%s,,) -> %Rrc\n", pszDevices, rc));
- }
- RTStrFree (pszDevices);
- }
- else
- Log (("USBProxyServiceLinux::USBProxyServiceLinux: out of memory!\n"));
-
- mLastError = rc;
- LogFlowMember (("USBProxyServiceLinux::USBProxyServiceLinux: returns failure!!! (rc=%Rrc)\n", rc));
-}
-
-
-/**
- * Stop all service threads and free the device chain.
- */
-USBProxyServiceLinux::~USBProxyServiceLinux()
-{
- LogFlowMember (("USBProxyServiceLinux::~USBProxyServiceLinux:\n"));
-
- /*
- * Stop the service.
- */
- if (isActive())
- stop();
-
- /*
- * Free resources.
- */
- if (mStream)
- {
- fclose (mStream);
- mStream = NULL;
- mFile = NIL_RTFILE;
- }
- else if (mFile != NIL_RTFILE)
- {
- RTFileClose (mFile);
- mFile = NIL_RTFILE;
- }
-
- RTFileClose (mWakeupPipeR);
- RTFileClose (mWakeupPipeW);
- mWakeupPipeW = mWakeupPipeR = NIL_RTFILE;
-}
-
-
-int USBProxyServiceLinux::captureDevice (HostUSBDevice *aDevice)
-{
- /*
- * Don't think we need to do anything when the device is held...
- */
- return VINF_SUCCESS;
-}
-
-
-int USBProxyServiceLinux::holdDevice (HostUSBDevice *pDevice)
-{
- /*
- * This isn't really implemented, we can usually wrestle
- * any user when we need it... Anyway, I don't have anywhere to store
- * any info per device atm.
- */
- return VINF_SUCCESS;
-}
-
-
-int USBProxyServiceLinux::releaseDevice (HostUSBDevice *aDevice)
-{
- /*
- * We're not really holding it atm.
- */
- return VINF_SUCCESS;
-}
-
-
-int USBProxyServiceLinux::resetDevice (HostUSBDevice *aDevice)
-{
- /*
- * We don't dare reset anything, but the USB Proxy Device
- * will reset upon detach, so this should be ok.
- */
- return VINF_SUCCESS;
-}
-
-
-int USBProxyServiceLinux::wait (unsigned aMillies)
-{
- struct pollfd PollFds[2];
-
- memset(&PollFds, 0, sizeof(PollFds));
- PollFds[0].fd = mFile;
- PollFds[0].events = POLLIN;
- PollFds[1].fd = mWakeupPipeR;
- PollFds[1].events = POLLIN | POLLERR | POLLHUP;
-
- int rc = poll (&PollFds[0], 2, aMillies);
- if (rc == 0)
- return VERR_TIMEOUT;
- if (rc > 0)
- return VINF_SUCCESS;
- return RTErrConvertFromErrno (errno);
-}
-
-
-int USBProxyServiceLinux::interruptWait (void)
-{
- int rc = RTFileWrite (mWakeupPipeW, "Wakeup!", sizeof("Wakeup!") - 1, NULL);
- if (RT_SUCCESS (rc))
- fsync (mWakeupPipeW);
- return rc;
-}
-
-
-/**
- * "reads" the number suffix. It's more like validating it and
- * skipping the necessary number of chars.
- */
-static int usbReadSkipSuffix (char **ppszNext)
-{
- char *pszNext = *ppszNext;
- if (!RT_C_IS_SPACE (*pszNext) && *pszNext)
- {
- /* skip unit */
- if (pszNext[0] == 'm' && pszNext[1] == 's')
- pszNext += 2;
- else if (pszNext[0] == 'm' && pszNext[1] == 'A')
- pszNext += 2;
-
- /* skip parenthesis */
- if (*pszNext == '(')
- {
- pszNext = strchr (pszNext, ')');
- if (!pszNext++)
- {
- AssertMsgFailed (("*ppszNext=%s\n", *ppszNext));
- return VERR_PARSE_ERROR;
- }
- }
-
- /* blank or end of the line. */
- if (!RT_C_IS_SPACE (*pszNext) && *pszNext)
- {
- AssertMsgFailed (("pszNext=%s\n", pszNext));
- return VERR_PARSE_ERROR;
- }
-
- /* it's ok. */
- *ppszNext = pszNext;
- }
-
- return VINF_SUCCESS;
-}
-
-
-/**
- * Reads a USB number returning the number and the position of the next character to parse.
- */
-static int usbReadNum (const char *pszValue, unsigned uBase, uint32_t u32Mask, PCUSBSUFF paSuffs, void *pvNum, char **ppszNext)
-{
- /*
- * Initialize return value to zero and strip leading spaces.
- */
- switch (u32Mask)
- {
- case 0xff: *(uint8_t *)pvNum = 0; break;
- case 0xffff: *(uint16_t *)pvNum = 0; break;
- case 0xffffffff: *(uint32_t *)pvNum = 0; break;
- }
- pszValue = RTStrStripL (pszValue);
- if (*pszValue)
- {
- /*
- * Try convert the number.
- */
- char *pszNext;
- uint32_t u32 = 0;
- RTStrToUInt32Ex (pszValue, &pszNext, uBase, &u32);
- if (pszNext == pszValue)
- {
- AssertMsgFailed (("pszValue=%d\n", pszValue));
- return VERR_NO_DATA;
- }
-
- /*
- * Check the range.
- */
- if (u32 & ~u32Mask)
- {
- AssertMsgFailed (("pszValue=%d u32=%#x lMask=%#x\n", pszValue, u32, u32Mask));
- return VERR_OUT_OF_RANGE;
- }
-
- /*
- * Validate and skip stuff following the number.
- */
- if (paSuffs)
- {
- if (!RT_C_IS_SPACE (*pszNext) && *pszNext)
- {
- for (PCUSBSUFF pSuff = paSuffs; pSuff->szSuff[0]; pSuff++)
- {
- if ( !strncmp (pSuff->szSuff, pszNext, pSuff->cchSuff)
- && (!pszNext[pSuff->cchSuff] || RT_C_IS_SPACE (pszNext[pSuff->cchSuff])))
- {
- if (pSuff->uDiv)
- u32 /= pSuff->uDiv;
- else
- u32 *= pSuff->uMul;
- break;
- }
- }
- }
- }
- else
- {
- int rc = usbReadSkipSuffix (&pszNext);
- if (RT_FAILURE (rc))
- return rc;
- }
-
- *ppszNext = pszNext;
-
- /*
- * Set the value.
- */
- switch (u32Mask)
- {
- case 0xff: *(uint8_t *)pvNum = (uint8_t)u32; break;
- case 0xffff: *(uint16_t *)pvNum = (uint16_t)u32; break;
- case 0xffffffff: *(uint32_t *)pvNum = (uint32_t)u32; break;
- }
- }
- return VINF_SUCCESS;
-}
-
-static int usbRead8 (const char *pszValue, unsigned uBase, uint8_t *pu8, char **ppszNext)
-{
- return usbReadNum (pszValue, uBase, 0xff, NULL, pu8, ppszNext);
-}
-
-static int usbRead16 (const char *pszValue, unsigned uBase, uint16_t *pu16, char **ppszNext)
-{
- return usbReadNum (pszValue, uBase, 0xffff, NULL, pu16, ppszNext);
-}
-
-static int usbRead16Suff (const char *pszValue, unsigned uBase, PCUSBSUFF paSuffs, uint16_t *pu16, char **ppszNext)
-{
- return usbReadNum (pszValue, uBase, 0xffff, paSuffs, pu16, ppszNext);
-}
-
-/**
- * Reads a USB BCD number returning the number and the position of the next character to parse.
- * The returned number contains the integer part in the high byte and the decimal part in the low byte.
- */
-static int usbReadBCD (const char *pszValue, unsigned uBase, uint16_t *pu16, char **ppszNext)
-{
- /*
- * Initialize return value to zero and strip leading spaces.
- */
- *pu16 = 0;
- pszValue = RTStrStripL (pszValue);
- if (*pszValue)
- {
- /*
- * Try convert the number.
- */
- /* integer part */
- char *pszNext;
- uint32_t u32Int = 0;
- RTStrToUInt32Ex (pszValue, &pszNext, uBase, &u32Int);
- if (pszNext == pszValue)
- {
- AssertMsgFailed (("pszValue=%s\n", pszValue));
- return VERR_NO_DATA;
- }
- if (u32Int & ~0xff)
- {
- AssertMsgFailed (("pszValue=%s u32Int=%#x (int)\n", pszValue, u32Int));
- return VERR_OUT_OF_RANGE;
- }
-
- /* skip dot and read decimal part */
- if (*pszNext != '.')
- {
- AssertMsgFailed (("pszValue=%s pszNext=%s (int)\n", pszValue, pszNext));
- return VERR_PARSE_ERROR;
- }
- char *pszValue2 = RTStrStripL (pszNext + 1);
- uint32_t u32Dec = 0;
- RTStrToUInt32Ex (pszValue2, &pszNext, uBase, &u32Dec);
- if (pszNext == pszValue)
- {
- AssertMsgFailed (("pszValue=%s\n", pszValue));
- return VERR_NO_DATA;
- }
- if (u32Dec & ~0xff)
- {
- AssertMsgFailed (("pszValue=%s u32Dec=%#x\n", pszValue, u32Dec));
- return VERR_OUT_OF_RANGE;
- }
-
- /*
- * Validate and skip stuff following the number.
- */
- int rc = usbReadSkipSuffix (&pszNext);
- if (RT_FAILURE (rc))
- return rc;
- *ppszNext = pszNext;
-
- /*
- * Set the value.
- */
- *pu16 = (uint16_t)u32Int << 8 | (uint16_t)u32Dec;
- }
- return VINF_SUCCESS;
-}
-
-
-/**
- * Reads a string, i.e. allocates memory and copies it.
- *
- * We assume that a string is pure ASCII, if that's not the case
- * tell me how to figure out the codeset please.
- */
-static int usbReadStr (const char *pszValue, const char **ppsz)
-{
- if (*ppsz)
- RTStrFree ((char *)*ppsz);
- *ppsz = RTStrDup (pszValue);
- if (*ppsz)
- return VINF_SUCCESS;
- return VERR_NO_MEMORY;
-}
-
-
-/**
- * Skips the current property.
- */
-static char * usbReadSkip (const char *pszValue)
-{
- char *psz = strchr (pszValue, '=');
- if (psz)
- psz = strchr (psz + 1, '=');
- if (!psz)
- return strchr (pszValue, '\0');
- while (psz > pszValue && !RT_C_IS_SPACE (psz[-1]))
- psz--;
- Assert (psz > pszValue);
- return psz;
-}
-
-
-/**
- * Compare a prefix and returns pointer to the char following it if it matches.
- */
-static char *usbPrefix (char *psz, const char *pszPref, size_t cchPref)
-{
- if (strncmp (psz, pszPref, cchPref))
- return NULL;
- return psz + cchPref;
-}
-
-
-/**
- * Checks which state the device is in.
- */
-static USBDEVICESTATE usbDeterminState (PCUSBDEVICE pDevice)
-{
- if (!pDevice->idVendor)
- return USBDEVICESTATE_UNSUPPORTED;
-
- /*
- * We cannot distinguish between USED_BY_HOST_CAPTURABLE and
- * USED_BY_GUEST, HELD_BY_PROXY all that well and it shouldn't be
- * necessary either.
- */
- USBDEVICESTATE enmState = USBDEVICESTATE_UNUSED;
- for (int iCfg = pDevice->bNumConfigurations - 1; iCfg >= 0; iCfg--)
- for (int iIf = pDevice->paConfigurations[iCfg].bConfigurationValue - 1; iIf >= 0; iIf--)
- {
- const char *pszDriver = pDevice->paConfigurations[iCfg].paInterfaces[iIf].pszDriver;
- if (pszDriver)
- {
- if (!strcmp (pszDriver, "hub"))
- {
- enmState = USBDEVICESTATE_USED_BY_HOST;
- break;
- }
- enmState = USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
- }
- }
-
- return enmState;
-}
-
-
-PUSBDEVICE USBProxyServiceLinux::getDevices (void)
-{
- PUSBDEVICE pFirst = NULL;
- if (mStream)
- {
- PUSBDEVICE *ppNext = NULL;
- USBDEVICE Dev = {0};
- int cHits = 0;
- int iCfg = 0;
- PUSBCONFIG pCfg = NULL;
- PUSBINTERFACE pIf = NULL;
- int iEp = 0;
- PUSBENDPOINT pEp = NULL;
- char szLine[1024];
-
- rewind (mStream);
- int rc = VINF_SUCCESS;
- while ( RT_SUCCESS (rc)
- && fgets (szLine, sizeof (szLine), mStream))
- {
- char *psz;
- char *pszValue;
-
- /* validate and remove the trailing newline. */
- psz = strchr (szLine, '\0');
- if (psz[-1] != '\n' && !feof (mStream))
- {
- AssertMsgFailed (("Line too long. (cch=%d)\n", strlen (szLine)));
- continue;
- }
-
- /* strip */
- psz = RTStrStrip (szLine);
- if (!*psz)
- continue;
-
- /*
- * Interpret the line.
- * (Ordered by normal occurrence.)
- */
- char ch = psz[0];
- if (psz[1] != ':')
- continue;
- psz = RTStrStripL (psz + 3);
- #define PREFIX(str) ( (pszValue = usbPrefix (psz, str, sizeof (str) - 1)) != NULL )
- switch (ch)
- {
- /*
- * T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd
- * | | | | | | | | |__MaxChildren
- * | | | | | | | |__Device Speed in Mbps
- * | | | | | | |__DeviceNumber
- * | | | | | |__Count of devices at this level
- * | | | | |__Connector/Port on Parent for this device
- * | | | |__Parent DeviceNumber
- * | | |__Level in topology for this bus
- * | |__Bus number
- * |__Topology info tag
- */
- case 'T':
- /* add */
- AssertMsg (cHits >= 3 || cHits == 0, ("cHits=%d\n", cHits));
- if (cHits >= 3)
- {
- Dev.enmState = usbDeterminState (&Dev);
- PUSBDEVICE pDev = (PUSBDEVICE) RTMemAlloc (sizeof(*pDev));
- if (pDev)
- {
- *pDev = Dev;
- if (Dev.enmState != USBDEVICESTATE_UNSUPPORTED)
- {
- RTStrAPrintf((char **)&pDev->pszAddress, "%s/%03d/%03d", mUsbfsRoot.c_str(), pDev->bBus, pDev->bDevNum);
- if (pDev->pszAddress)
- {
- if (ppNext)
- *ppNext = pDev;
- else
- pFirst = pDev;
- ppNext = &pDev->pNext;
- }
- else
- {
- freeDevice (pDev);
- rc = VERR_NO_MEMORY;
- }
- }
- else
- freeDevice (pDev);
- memset (&Dev, 0, sizeof (Dev));
- }
- else
- rc = VERR_NO_MEMORY;
- }
-
- /* Reset device state */
- cHits = 1;
- iCfg = 0;
- pCfg = NULL;
- pIf = NULL;
- iEp = 0;
- pEp = NULL;
-
-
- /* parse the line. */
- while (*psz && RT_SUCCESS (rc))
- {
- if (PREFIX ("Bus="))
- rc = usbRead8 (pszValue, 10, &Dev.bBus, &psz);
- else if (PREFIX ("Lev="))
- rc = usbRead8 (pszValue, 10, &Dev.bLevel, &psz);
- else if (PREFIX ("Dev#="))
- rc = usbRead8 (pszValue, 10, &Dev.bDevNum, &psz);
- else if (PREFIX ("Prnt="))
- rc = usbRead8 (pszValue, 10, &Dev.bDevNumParent, &psz);
- else if (PREFIX ("Port="))
- rc = usbRead8 (pszValue, 10, &Dev.bPort, &psz);
- else if (PREFIX ("Cnt="))
- rc = usbRead8 (pszValue, 10, &Dev.bNumDevices, &psz);
- //else if (PREFIX ("Spd="))
- // rc = usbReadSpeed (pszValue, &Dev.cbSpeed, &psz);
- else if (PREFIX ("MxCh="))
- rc = usbRead8 (pszValue, 10, &Dev.bMaxChildren, &psz);
- else
- psz = usbReadSkip (psz);
- psz = RTStrStripL (psz);
- }
- break;
-
- /*
- * Bandwidth info:
- * B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd
- * | | | |__Number of isochronous requests
- * | | |__Number of interrupt requests
- * | |__Total Bandwidth allocated to this bus
- * |__Bandwidth info tag
- */
- case 'B':
- break;
-
- /*
- * D: Ver=x.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd
- * | | | | | | |__NumberConfigurations
- * | | | | | |__MaxPacketSize of Default Endpoint
- * | | | | |__DeviceProtocol
- * | | | |__DeviceSubClass
- * | | |__DeviceClass
- * | |__Device USB version
- * |__Device info tag #1
- */
- case 'D':
- while (*psz && RT_SUCCESS (rc))
- {
- if (PREFIX ("Ver="))
- rc = usbReadBCD (pszValue, 16, &Dev.bcdUSB, &psz);
- else if (PREFIX ("Cls="))
- rc = usbRead8 (pszValue, 16, &Dev.bDeviceClass, &psz);
- else if (PREFIX ("Sub="))
- rc = usbRead8 (pszValue, 16, &Dev.bDeviceSubClass, &psz);
- else if (PREFIX ("Prot="))
- rc = usbRead8 (pszValue, 16, &Dev.bDeviceProtocol, &psz);
- //else if (PREFIX ("MxPS="))
- // rc = usbRead16 (pszValue, 10, &Dev.wMaxPacketSize, &psz);
- else if (PREFIX ("#Cfgs="))
- rc = usbRead8 (pszValue, 10, &Dev.bNumConfigurations, &psz);
- else
- psz = usbReadSkip (psz);
- psz = RTStrStripL (psz);
- }
- cHits++;
- break;
-
- /*
- * P: Vendor=xxxx ProdID=xxxx Rev=xx.xx
- * | | | |__Product revision number
- * | | |__Product ID code
- * | |__Vendor ID code
- * |__Device info tag #2
- */
- case 'P':
- while (*psz && RT_SUCCESS (rc))
- {
- if (PREFIX ("Vendor="))
- rc = usbRead16 (pszValue, 16, &Dev.idVendor, &psz);
- else if (PREFIX ("ProdID="))
- rc = usbRead16 (pszValue, 16, &Dev.idProduct, &psz);
- else if (PREFIX ("Rev="))
- rc = usbReadBCD (pszValue, 16, &Dev.bcdDevice, &psz);
- else
- psz = usbReadSkip (psz);
- psz = RTStrStripL (psz);
- }
- cHits++;
- break;
-
- /*
- * String.
- */
- case 'S':
- if (PREFIX ("Manufacturer="))
- rc = usbReadStr (pszValue, &Dev.pszManufacturer);
- else if (PREFIX ("Product="))
- rc = usbReadStr (pszValue, &Dev.pszProduct);
- else if (PREFIX ("SerialNumber="))
- {
- rc = usbReadStr (pszValue, &Dev.pszSerialNumber);
- if (RT_SUCCESS (rc))
- Dev.u64SerialHash = calcSerialHash (pszValue);
- }
- break;
-
- /*
- * C:* #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA
- * | | | | | |__MaxPower in mA
- * | | | | |__Attributes
- * | | | |__ConfiguratioNumber
- * | | |__NumberOfInterfaces
- * | |__ "*" indicates the active configuration (others are " ")
- * |__Config info tag
- */
- case 'C':
- {
- USBCONFIG Cfg = {0};
- Cfg.fActive = psz[-2] == '*';
- while (*psz && RT_SUCCESS (rc))
- {
- if (PREFIX ("#Ifs="))
- rc = usbRead8 (pszValue, 10, &Cfg.bNumInterfaces, &psz);
- else if (PREFIX ("Cfg#="))
- rc = usbRead8 (pszValue, 10, &Cfg.bConfigurationValue, &psz);
- else if (PREFIX ("Atr="))
- rc = usbRead8 (pszValue, 16, &Cfg.bmAttributes, &psz);
- else if (PREFIX ("MxPwr="))
- rc = usbRead16 (pszValue, 10, &Cfg.u16MaxPower, &psz);
- else
- psz = usbReadSkip (psz);
- psz = RTStrStripL (psz);
- }
- if (RT_SUCCESS (rc))
- {
- if (iCfg < Dev.bNumConfigurations)
- {
- /* Add the config. */
- if (!Dev.paConfigurations)
- {
- Dev.paConfigurations = pCfg = (PUSBCONFIG) RTMemAllocZ (sizeof (Cfg) * Dev.bNumConfigurations);
- if (pCfg)
- {
- *pCfg = Cfg;
- iCfg = 1;
- }
- else
- rc = VERR_NO_MEMORY;
- }
- else
- {
- *++pCfg = Cfg;
- iCfg++;
- }
- }
- else
- {
- AssertMsgFailed (("iCfg=%d bNumConfigurations=%d\n", iCfg, Dev.bNumConfigurations));
- rc = VERR_INTERNAL_ERROR;
- }
- }
-
- /* new config, so, start anew with interfaces and endpoints. */
- pIf = NULL;
- iEp = 0;
- pEp = NULL;
- break;
- }
-
- /*
- * I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss
- * | | | | | | | |__Driver name
- * | | | | | | | or "(none)"
- * | | | | | | |__InterfaceProtocol
- * | | | | | |__InterfaceSubClass
- * | | | | |__InterfaceClass
- * | | | |__NumberOfEndpoints
- * | | |__AlternateSettingNumber
- * | |__InterfaceNumber
- * |__Interface info tag
- */
- case 'I':
- {
- USBINTERFACE If = {0};
- bool fIfAdopted = false;
- while (*psz && RT_SUCCESS (rc))
- {
- if (PREFIX ("If#="))
- rc = usbRead8 (pszValue, 10, &If.bInterfaceNumber, &psz);
- else if (PREFIX ("Alt="))
- rc = usbRead8 (pszValue, 10, &If.bAlternateSetting, &psz);
- else if (PREFIX ("#EPs="))
- rc = usbRead8 (pszValue, 10, &If.bNumEndpoints, &psz);
- else if (PREFIX ("Cls="))
- rc = usbRead8 (pszValue, 16, &If.bInterfaceClass, &psz);
- else if (PREFIX ("Sub="))
- rc = usbRead8 (pszValue, 16, &If.bInterfaceSubClass, &psz);
- else if (PREFIX ("Prot="))
- rc = usbRead8 (pszValue, 16, &If.bInterfaceProtocol, &psz);
- else if (PREFIX ("Driver="))
- {
- rc = usbReadStr (pszValue, &If.pszDriver);
- if ( If.pszDriver
- && ( !strcmp (If.pszDriver, "(none)")
- || !strcmp (If.pszDriver, "(no driver)")
- || !*If.pszDriver))
- {
- RTStrFree ((char *)If.pszDriver);
- If.pszDriver = NULL;
- }
- break;
- }
- else
- psz = usbReadSkip (psz);
- psz = RTStrStripL (psz);
- }
- if (RT_SUCCESS (rc))
- {
- if (pCfg && If.bInterfaceNumber < pCfg->bNumInterfaces)
- {
- /* Add the config. */
- if (!pCfg->paInterfaces)
- {
- pCfg->paInterfaces = pIf = (PUSBINTERFACE) RTMemAllocZ (sizeof (If) * pCfg->bNumInterfaces);
- if (pIf)
- {
- Assert (!If.bInterfaceNumber); Assert (!If.bAlternateSetting);
- *pIf = If;
- fIfAdopted = true;
- }
- else
- rc = VERR_NO_MEMORY;
- }
- else
- {
- /*
- * Alternate settings makes life *difficult*!
- * ASSUMES: ORDER ASC bInterfaceNumber, bAlternateSetting
- */
- pIf = &pCfg->paInterfaces[If.bInterfaceNumber];
- if (!If.bAlternateSetting)
- {
- freeInterfaceMembers (pIf, 1);
- *pIf = If;
- fIfAdopted = true;
- }
- else
- {
- PUSBINTERFACE paAlts = (PUSBINTERFACE) RTMemRealloc (pIf->paAlts, (pIf->cAlts + 1) * sizeof(*pIf));
- if (paAlts)
- {
- pIf->paAlts = paAlts;
- // don't do pIf = &paAlts[pIf->cAlts++]; as it will increment after the assignment
- unsigned cAlts = pIf->cAlts++;
- pIf = &paAlts[cAlts];
- *pIf = If;
- fIfAdopted = true;
- }
- else
- rc = VERR_NO_MEMORY;
- }
- }
- }
- else
- {
- AssertMsgFailed (("iCfg=%d bInterfaceNumber=%d bNumInterfaces=%d\n", iCfg, If.bInterfaceNumber, pCfg->bNumInterfaces));
- rc = VERR_INTERNAL_ERROR;
- }
- }
-
- if (!fIfAdopted)
- freeInterfaceMembers (&If, 1);
-
- /* start anew with endpoints. */
- iEp = 0;
- pEp = NULL;
- break;
- }
-
-
- /*
- * E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddms
- * | | | | |__Interval (max) between transfers
- * | | | |__EndpointMaxPacketSize
- * | | |__Attributes(EndpointType)
- * | |__EndpointAddress(I=In,O=Out)
- * |__Endpoint info tag
- */
- case 'E':
- {
- USBENDPOINT Ep = {0};
- while (*psz && RT_SUCCESS (rc))
- {
- if (PREFIX ("Ad="))
- rc = usbRead8 (pszValue, 16, &Ep.bEndpointAddress, &psz);
- else if (PREFIX ("Atr="))
- rc = usbRead8 (pszValue, 16, &Ep.bmAttributes, &psz);
- else if (PREFIX ("MxPS="))
- rc = usbRead16 (pszValue, 10, &Ep.wMaxPacketSize, &psz);
- else if (PREFIX ("Ivl="))
- rc = usbRead16Suff (pszValue, 10, &s_aIntervalSuff[0], &Ep.u16Interval, &psz);
- else
- psz = usbReadSkip (psz);
- psz = RTStrStripL (psz);
- }
- if (RT_SUCCESS (rc))
- {
- if (pIf && iEp < pIf->bNumEndpoints)
- {
- /* Add the config. */
- if (!pIf->paEndpoints)
- {
- pIf->paEndpoints = pEp = (PUSBENDPOINT) RTMemAllocZ (sizeof (Ep) * pIf->bNumEndpoints);
- if (pEp)
- {
- *pEp = Ep;
- iEp = 1;
- }
- else
- rc = VERR_NO_MEMORY;
- }
- else
- {
- *++pEp = Ep;
- iEp++;
- }
- }
- else
- {
- AssertMsgFailed (("iCfg=%d bInterfaceNumber=%d iEp=%d bNumInterfaces=%d\n", iCfg, pIf->bInterfaceNumber, iEp, pIf->bNumEndpoints));
- rc = VERR_INTERNAL_ERROR;
- }
- }
- break;
- }
-
- }
- #undef PREFIX
- } /* parse loop */
-
- /*
- * Add the current entry.
- */
- AssertMsg (cHits >= 3 || cHits == 0, ("cHits=%d\n", cHits));
- if (cHits >= 3)
- {
- Dev.enmState = usbDeterminState (&Dev);
- PUSBDEVICE pDev = (PUSBDEVICE) RTMemAlloc (sizeof(*pDev));
- if (pDev)
- {
- *pDev = Dev;
- if (Dev.enmState != USBDEVICESTATE_UNSUPPORTED)
- {
- RTStrAPrintf((char **)&pDev->pszAddress, "%s/%03d/%03d", mUsbfsRoot.c_str(), pDev->bBus, pDev->bDevNum);
- if (pDev->pszAddress)
- {
- if (ppNext)
- *ppNext = pDev;
- else
- pFirst = pDev;
- ppNext = &pDev->pNext;
- }
- else
- {
- rc = VERR_NO_MEMORY;
- freeDevice (pDev);
- }
- }
- else
- freeDevice (pDev);
- }
- else
- rc = VERR_NO_MEMORY;
- }
-
- /*
- * Success?
- */
- if (RT_FAILURE (rc))
- {
- LogFlow (("USBProxyServiceLinux::getDevices: rc=%Rrc\n", rc));
- while (pFirst)
- {
- PUSBDEVICE pFree = pFirst;
- pFirst = pFirst->pNext;
- freeDevice (pFree);
- }
- }
- }
- return pFirst;
-}
-
diff --git a/src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp b/src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp
index 65ca87f29..db53aa762 100644
--- a/src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp
+++ b/src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp
@@ -1,12 +1,11 @@
-/* $Id: VBoxBFE.cpp $ */
+/* $Id: VBoxBFE.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* Basic Frontend (BFE): VBoxBFE main routines.
*
* VBoxBFE is a limited frontend that sits directly on the Virtual Machine
* Manager (VMM) and does _not_ use COM to communicate.
- * On Linux and Windows, VBoxBFE is based on SDL; on L4 it's based on the
- * L4 console. Much of the code has been copied over from the other frontends
- * in VBox/Main/ and src/Frontends/VBoxSDL/.
+ * VBoxBFE is based on SDL. Much of the code has been copied over from the
+ * other frontends in VBox/Main/ and src/Frontends/VBoxSDL/.
*/
/*
@@ -38,9 +37,6 @@ using namespace com;
#include <VBox/param.h>
#include <VBox/vmm/pdm.h>
#include <VBox/version.h>
-#ifdef VBOXBFE_WITH_USB
-# include <VBox/vusb.h>
-#endif
#ifdef VBOX_WITH_HGCM
# include <VBox/shflsvc.h>
#endif
@@ -63,7 +59,7 @@ using namespace com;
#include <stdlib.h> /* putenv */
#include <errno.h>
-#if defined(RT_OS_LINUX) || defined(RT_OS_L4)
+#if defined(RT_OS_LINUX)
#include <fcntl.h>
#include <net/if.h>
#include <sys/ioctl.h>
@@ -78,25 +74,13 @@ using namespace com;
#include "StatusImpl.h"
#include "Framebuffer.h"
#include "MachineDebuggerImpl.h"
-#ifdef VBOXBFE_WITH_USB
-# include "HostUSBImpl.h"
-#endif
-#if defined(USE_SDL) && ! defined(RT_OS_L4)
+#if defined(USE_SDL)
#include "SDLConsole.h"
#include "SDLFramebuffer.h"
#endif
-#ifdef RT_OS_L4
-#include "L4Console.h"
-#include "L4Framebuffer.h"
-#include "L4IDLInterface.h"
-#endif
-#ifdef RT_OS_L4
-# include <l4/sys/ktrace.h>
-# include <l4/vboxserver/file.h>
-#endif
/*******************************************************************************
* Defined Constants And Macros *
@@ -129,20 +113,13 @@ Framebuffer *gFramebuffer = NULL;
MachineDebugger *gMachineDebugger = NULL;
VMStatus *gStatus = NULL;
Console *gConsole = NULL;
-#ifdef VBOXBFE_WITH_USB
-HostUSB *gHostUSB = NULL;
-#endif
VMSTATE machineState = VMSTATE_CREATING;
static PPDMLED mapFDLeds[2] = {0};
/** flag whether keyboard/mouse events are grabbed */
-#ifdef RT_OS_L4
-/** see <l4/input/macros.h> for key definitions */
-int gHostKey; /* not used */
-int gHostKeySym = KEY_RIGHTCTRL;
-#elif defined (DEBUG_dmik)
+#if defined (DEBUG_dmik)
// my mini kbd doesn't have RCTRL...
int gHostKey = KMOD_RSHIFT;
int gHostKeySym = SDLK_RSHIFT;
@@ -155,9 +132,6 @@ bool gfAllowFullscreenToggle = true;
static bool g_fIOAPIC = false;
static bool g_fACPI = true;
static bool g_fAudio = false;
-#ifdef VBOXBFE_WITH_USB
-static bool g_fUSB = false;
-#endif
static char *g_pszHdaFile = NULL;
static bool g_fHdaSpf = false;
static char *g_pszHdbFile = NULL;
@@ -369,17 +343,13 @@ static void show_usage()
" -[no]acpi Enable or disable ACPI (default: enabled)\n"
" -[no]ioapic Enable or disable the IO-APIC (default: disabled)\n"
" -audio Enable audio\n"
-#ifndef RT_OS_L4
" -natdev<1-N> [mac] Use NAT networking on network adapter <N>. Use hardware\n"
" address <mac> if specified.\n"
-#endif
" -hifdev<1-N> Use Host Interface Networking with host interface <int>\n"
" <int> [mac] on network adapter <N>. Use hardware address <mac> if\n"
" specified.\n"
-#ifndef RT_OS_L4
" -intnet<1-N> Attach network adapter <N> to internal network <net>. Use\n"
" <net> [mac] hardware address <mac> if specified.\n"
-#endif
#if 0
" -netsniff<1-N> Enable packet sniffer\n"
#endif
@@ -402,9 +372,6 @@ static void show_usage()
" -[no]patm Enable or disable PATM\n"
" -[no]csam Enable or disable CSAM\n"
#endif
-#ifdef RT_OS_L4
- " -env <var=value> Set the given environment variable to \"value\"\n"
-#endif
"\n");
}
@@ -419,9 +386,6 @@ extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char **envp)
uint32_t secureLabelPointSize = 12;
char *secureLabelFontFile = NULL;
#endif
-#ifdef RT_OS_L4
- uint32_t u32MaxVRAM;
-#endif
int rc = VINF_SUCCESS;
RTPrintf(VBOX_PRODUCT " Simple SDL GUI built %s %s\n", __DATE__, __TIME__);
@@ -543,10 +507,6 @@ extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char **envp)
g_fIOAPIC = false;
else if (strcmp(pszArg, "-audio") == 0)
g_fAudio = true;
-#ifdef VBOXBFE_WITH_USB
- else if (strcmp(pszArg, "-usb") == 0)
- g_fUSB = true;
-#endif
else if (strcmp(pszArg, "-hda") == 0)
{
if (++curArg >= argc)
@@ -599,18 +559,10 @@ extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char **envp)
if (!g_pszCdromFile)
return SyntaxError("The path to the specified cdrom, '%s', could not be resolved.\n", argv[curArg]);
}
-#ifdef RT_OS_L4
- /* This is leaving a lot of dead code in the L4 version of course,
- but I don't think that that is a major problem. We may even
- activate it sometime... */
- else if ( strncmp(pszArg, "-hifdev", 7) == 0
- || strncmp(pszArg, "-nonetd", 7) == 0)
-#else
else if ( strncmp(pszArg, "-natdev", 7) == 0
|| strncmp(pszArg, "-hifdev", 7) == 0
|| strncmp(pszArg, "-nonetd", 7) == 0
|| strncmp(pszArg, "-intnet", 7) == 0)
-#endif
{
int i = networkArg2Index(pszArg, 7);
if (i < 0)
@@ -762,10 +714,6 @@ extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char **envp)
else if (strcmp(pszArg, "-nocsam") == 0)
g_fCSAM = false;
#endif /* VBOXSDL_ADVANCED_OPTIONS */
-#ifdef RT_OS_L4
- else if (strcmp(pszArg, "-env") == 0)
- ++curArg;
-#endif /* RT_OS_L4 */
/* just show the help screen */
else
{
@@ -787,9 +735,6 @@ extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char **envp)
/* First console, then framebuffer!! */
gConsole = new SDLConsole();
gFramebuffer = new SDLFramebuffer();
-#elif defined(RT_OS_L4)
- gConsole = new L4Console();
- gFramebuffer = new L4Framebuffer();
#else
#error "todo"
#endif
@@ -815,10 +760,6 @@ extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char **envp)
return -1;
}
-#ifdef RT_OS_L4
- /* Start the external IDL interface */
- L4CtrlInit();
-#endif
/* loop until the powerup processing is done */
do
@@ -866,24 +807,6 @@ extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char **envp)
gConsole->updateTitlebar();
-#ifdef RT_OS_L4
- /* The L4 console provides (currently) a fixed resolution. */
- if (g_u32VRamSize >= gFramebuffer->getHostXres()
- * gFramebuffer->getHostYres()
- * (gDisplay->getBitsPerPixel() / 8))
- gDisplay->SetVideoModeHint(gFramebuffer->getHostXres(), gFramebuffer->getHostYres(), 0, 0);
-
- /* Limit the VRAM of the guest to the amount of memory we got actually
- * mapped from the L4 console. */
- u32MaxVRAM = (gFramebuffer->getHostYres() + 18) /* don't omit the status bar */
- * gFramebuffer->getHostXres()
- * (gFramebuffer->getHostBitsPerPixel() / 8);
- if (g_u32VRamSize > u32MaxVRAM)
- {
- RTPrintf("Limiting the video memory to %u bytes\n", u32MaxVRAM);
- g_u32VRamSize = u32MaxVRAM;
- }
-#endif
/*
* Main event loop
@@ -986,23 +909,6 @@ leave:
*/
int main(int argc, char **argv)
{
-# ifdef RT_OS_L4
-# ifndef L4API_l4v2onv4
- /* clear Fiasco kernel trace buffer */
- fiasco_tbuf_clear();
-# endif
- /* set the environment. Must be done before the runtime is
- initialised. Yes, it really must. */
- for (int i = 0; i < argc; i++)
- if (strcmp(argv[i], "-env") == 0)
- {
- if (++i >= argc)
- return SyntaxError("missing argument to -env (format: var=value)!\n");
- /* add it to the environment */
- if (putenv(argv[i]) != 0)
- return SyntaxError("Error setting environment string %s.\n", argv[i]);
- }
-# endif /* RT_OS_L4 */
/*
* Before we do *anything*, we initialize the runtime.
@@ -1240,17 +1146,6 @@ DECLCALLBACK(int) VMPowerUpThread(RTTHREAD Thread, void *pvUser)
}
#endif
-#ifdef VBOXBFE_WITH_USB
- /*
- * Capture USB devices.
- */
- if (g_fUSB)
- {
- gHostUSB = new HostUSB();
- gHostUSB->init(gpVM);
- }
-#endif /* VBOXBFE_WITH_USB */
-
/*
* Power on the VM (i.e. start executing).
*/
@@ -1610,18 +1505,6 @@ static DECLCALLBACK(int) vboxbfeConfigConstructor(PVM pVM, void *pvUser)
/* Boot menu */
rc = CFGMR3InsertInteger(pCfg, "ShowBootMenu", g_iBootMenu); UPDATE_RC();
-#ifdef RT_OS_L4
- /* XXX hard-coded */
- rc = CFGMR3InsertInteger(pCfg, "HeightReduction", 18); UPDATE_RC();
- rc = CFGMR3InsertInteger(pCfg, "CustomVideoModes", 1); UPDATE_RC();
- char szBuf[64];
- /* Tell the guest which is the ideal video mode to use */
- RTStrPrintf(szBuf, sizeof(szBuf), "%dx%dx%d",
- gFramebuffer->getHostXres(),
- gFramebuffer->getHostYres(),
- gFramebuffer->getHostBitsPerPixel());
- rc = CFGMR3InsertString(pCfg, "CustomVideoMode1", szBuf); UPDATE_RC();
-#endif
rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); UPDATE_RC();
rc = CFGMR3InsertString(pLunL0, "Driver", "MainDisplay"); UPDATE_RC();
@@ -1789,7 +1672,7 @@ static DECLCALLBACK(int) vboxbfeConfigConstructor(PVM pVM, void *pvUser)
else
#endif
{
-#if defined(RT_OS_LINUX) || defined(RT_OS_L4)
+#if defined(RT_OS_LINUX)
/*
* Create/Open the TAP the device.
*/
@@ -1819,7 +1702,7 @@ static DECLCALLBACK(int) vboxbfeConfigConstructor(PVM pVM, void *pvUser)
else
strcpy(IfReq.ifr_name, "tun%d");
IfReq.ifr_flags = IFF_TAP | IFF_NO_PI;
- rc = ioctl(tapFD, TUNSETIFF, &IfReq);
+ rc = ioctl(RTFileToNative(tapFD), TUNSETIFF, &IfReq);
if (rc)
{
int rc2 = RTErrConvertFromErrno(errno);
@@ -1828,7 +1711,7 @@ static DECLCALLBACK(int) vboxbfeConfigConstructor(PVM pVM, void *pvUser)
return rc2;
}
- rc = fcntl(tapFD, F_SETFL, O_NONBLOCK);
+ rc = fcntl(RTFileToNative(tapFD), F_SETFL, O_NONBLOCK);
if (rc)
{
int rc2 = RTErrConvertFromErrno(errno);
@@ -1838,7 +1721,7 @@ static DECLCALLBACK(int) vboxbfeConfigConstructor(PVM pVM, void *pvUser)
}
rc = CFGMR3InsertString(pCfg, "Device", g_aNetDevs[ulInstance].pszName); UPDATE_RC();
- rc = CFGMR3InsertInteger(pCfg, "FileHandle", (RTFILE)tapFD); UPDATE_RC();
+ rc = CFGMR3InsertInteger(pCfg, "FileHandle", (uintptr_t)tapFD); UPDATE_RC();
#elif defined(RT_OS_SOLARIS)
rc = CFGMR3InsertString(pCfg, "Device", g_aNetDevs[ulInstance].pszName); UPDATE_RC();
@@ -1928,32 +1811,11 @@ static DECLCALLBACK(int) vboxbfeConfigConstructor(PVM pVM, void *pvUser)
# else
rc = CFGMR3InsertString(pCfg, "AudioDriver", "solaudio"); UPDATE_RC();
# endif
-#elif defined(RT_OS_L4)
- rc = CFGMR3InsertString(pCfg, "AudioDriver", "oss"); UPDATE_RC();
#else /* portme */
rc = CFGMR3InsertString(pCfg, "AudioDriver", "none"); UPDATE_RC();
#endif /* !RT_OS_WINDOWS */
}
-#ifdef VBOXBFE_WITH_USB
- /*
- * The USB Controller.
- */
- if (g_fUSB)
- {
- rc = CFGMR3InsertNode(pDevices, "usb-ohci", &pDev); UPDATE_RC();
- rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATE_RC();
- rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATE_RC();
- rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATE_RC();
- rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 6); UPDATE_RC();
- rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); UPDATE_RC();
-
- rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); UPDATE_RC();
- rc = CFGMR3InsertString(pLunL0, "Driver", "VUSBRootHub"); UPDATE_RC();
- rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); UPDATE_RC();
- }
-#endif /* VBOXBFE_WITH_USB */
-
#undef UPDATE_RC
#undef UPDATE_RC
diff --git a/src/VBox/Frontends/VBoxBFE/VBoxBFE.h b/src/VBox/Frontends/VBoxBFE/VBoxBFE.h
index cdf8e0a29..37a2cb654 100644
--- a/src/VBox/Frontends/VBoxBFE/VBoxBFE.h
+++ b/src/VBox/Frontends/VBoxBFE/VBoxBFE.h
@@ -27,7 +27,7 @@
enum
{
NetworkAdapterCount = 4,
- MaxSharedFolders = 16,
+ MaxSharedFolders = 16
};
diff --git a/src/VBox/Frontends/VBoxBFE/VBoxBFEHardened.cpp b/src/VBox/Frontends/VBoxBFE/VBoxBFEHardened.cpp
index 62635e487..16646741c 100644
--- a/src/VBox/Frontends/VBoxBFE/VBoxBFEHardened.cpp
+++ b/src/VBox/Frontends/VBoxBFE/VBoxBFEHardened.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxBFEHardened.cpp $ */
+/* $Id: VBoxBFEHardened.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxSDL - Hardened main().
*/
diff --git a/src/VBox/Frontends/VBoxBFE/VMMDev.h b/src/VBox/Frontends/VBoxBFE/VMMDev.h
index 5be26a50a..4f705d809 100644
--- a/src/VBox/Frontends/VBoxBFE/VMMDev.h
+++ b/src/VBox/Frontends/VBoxBFE/VMMDev.h
@@ -1,4 +1,4 @@
-/* $Id: VMMDev.h $ */
+/* $Id: VMMDev.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBox frontends: Basic Frontend (BFE):
* Declaration of VMMDev: driver interface to VMM device
diff --git a/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp b/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp
index 1e17681aa..1f6e56d16 100644
--- a/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp
+++ b/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMMDevInterface.cpp $ */
+/* $Id: VMMDevInterface.cpp 36590 2011-04-06 15:35:26Z vboxsync $ */
/** @file
* VBox frontends: Basic Frontend (BFE):
* Implementation of VMMDev: driver interface to VMM device
@@ -47,9 +47,6 @@
# define VBOXSHAREDFOLDERS_DLL "VBoxSharedFolders"
#endif
-#ifdef RT_OS_L4
-#include <l4/util/util.h> /* for l4_sleep */
-#endif
/**
* VMMDev driver instance data.
*/
diff --git a/src/VBox/Frontends/VBoxBFE/VirtualBoxBase.h b/src/VBox/Frontends/VBoxBFE/VirtualBoxBase.h
index bcabb0bf8..bfb66cbc1 100644
--- a/src/VBox/Frontends/VBoxBFE/VirtualBoxBase.h
+++ b/src/VBox/Frontends/VBoxBFE/VirtualBoxBase.h
@@ -306,7 +306,7 @@ namespace stdx
delete (*it);
}
};
-};
+}
////////////////////////////////////////////////////////////////////////////////
@@ -518,9 +518,9 @@ public:
};
// sets the ready state of the object
- void setReady(bool isReady)
+ void setReady(bool ready)
{
- mReady = isReady;
+ mReady = ready;
}
// get the ready state of the object
bool isReady()
@@ -585,47 +585,47 @@ public:
}
}
- void attach (D *data) {
- AssertMsg (data, ("new data must not be NULL"));
- if (data && mData != data) {
+ void attach (D *pData) {
+ AssertMsg (pData, ("new data must not be NULL"));
+ if (pData && mData != pData) {
if (mData && !mIsShared)
delete mData;
- mData = data;
+ mData = pData;
mIsShared = false;
}
}
- void attach (Shareable &data) {
+ void attach (Shareable &Data) {
AssertMsg (
- data.mData == mData || !data.mIsShared,
+ Data.mData == mData || !Data.mIsShared,
("new data must not be shared")
);
- if (this != &data && !data.mIsShared) {
- attach (data.mData);
- data.mIsShared = true;
+ if (this != &Data && !Data.mIsShared) {
+ attach (Data.mData);
+ Data.mIsShared = true;
}
}
- void share (D *data) {
- AssertMsg (data, ("new data must not be NULL"));
- if (mData != data) {
+ void share (D *pData) {
+ AssertMsg (pData, ("new data must not be NULL"));
+ if (mData != pData) {
if (mData && !mIsShared)
delete mData;
- mData = data;
+ mData = pData;
mIsShared = true;
}
}
- void share (const Shareable &data) { share (data.mData); }
+ void share (const Shareable &Data) { share (Data.mData); }
- void attachCopy (const D *data) {
- AssertMsg (data, ("data to copy must not be NULL"));
- if (data)
- attach (new D (*data));
+ void attachCopy (const D *pData) {
+ AssertMsg (pData, ("data to copy must not be NULL"));
+ if (pData)
+ attach (new D (*pData));
}
- void attachCopy (const Shareable &data) {
- attachCopy (data.mData);
+ void attachCopy (const Shareable &Data) {
+ attachCopy (Data.mData);
}
virtual D *detach() {
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/Makefile.kup b/src/VBox/Frontends/VBoxBFE/testcase/Makefile.kup
index e69de29bb..e69de29bb 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/Makefile.kup
+++ b/src/VBox/Frontends/VBoxBFE/testcase/Makefile.kup
diff --git a/src/VBox/Frontends/VBoxBFE/testcase/tstMouseImpl.cpp b/src/VBox/Frontends/VBoxBFE/testcase/tstMouseImpl.cpp
new file mode 100644
index 000000000..3549fe077
--- /dev/null
+++ b/src/VBox/Frontends/VBoxBFE/testcase/tstMouseImpl.cpp
@@ -0,0 +1,387 @@
+/* $Id: tstMouseImpl.cpp 36162 2011-03-04 10:43:19Z vboxsync $ */
+/** @file
+ * Main unit test - Mouse class.
+ */
+
+/*
+ * 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 "MouseImpl.h"
+#include "VMMDev.h"
+#include "DisplayImpl.h"
+
+#include <VBox/vmm/cfgm.h>
+#include <VBox/vmm/pdmdrv.h>
+#include <VBox/VMMDev.h>
+#include <iprt/assert.h>
+#include <iprt/test.h>
+
+/******************************************************************************
+* Test infrastructure *
+******************************************************************************/
+
+class TestConsole : public Console
+{
+public:
+ TestConsole() {}
+ ~TestConsole() {}
+
+ virtual void updateTitlebar() {}
+ virtual void updateTitlebarProgress(const char *, int) {}
+
+ virtual void inputGrabStart() {}
+ virtual void inputGrabEnd() {}
+
+ virtual void mouseSendEvent(int) {}
+ virtual void onMousePointerShapeChange(bool, bool, uint32_t,
+ uint32_t, uint32_t,
+ uint32_t, void *) {}
+ virtual void progressInfo(PVM, unsigned, void *) {}
+
+ virtual CONEVENT eventWait()
+ {
+ AssertFailedReturn(CONEVENT_QUIT);
+ }
+ virtual void eventQuit() {}
+ virtual void resetCursor() {}
+ virtual void resetKeys(void) {}
+ virtual VMMDev *getVMMDev()
+ {
+ return &mVMMDev;
+ }
+ virtual Display *getDisplay()
+ {
+ return &mDisplay;
+ }
+
+private:
+ VMMDev mVMMDev;
+ Display mDisplay;
+};
+
+static int pdmdrvhlpAttach(PPDMDRVINS pDrvIns, uint32_t fFlags,
+ PPDMIBASE *ppBaseInterface)
+{
+ return VERR_PDM_NO_ATTACHED_DRIVER;
+}
+
+static struct PDMDRVHLPR3 pdmHlpR3 =
+{
+ PDM_DRVHLPR3_VERSION,
+ pdmdrvhlpAttach
+};
+
+static struct
+{
+ int32_t cx;
+ int32_t cy;
+} mouseEvent;
+
+static int mousePutEvent(PPDMIMOUSEPORT pInterface, int32_t iDeltaX,
+ int32_t iDeltaY, int32_t iDeltaZ, int32_t iDeltaW,
+ uint32_t fButtonStates)
+{
+ mouseEvent.cx = iDeltaX;
+ mouseEvent.cy = iDeltaY;
+ return VINF_SUCCESS;
+}
+
+static struct
+{
+ int32_t x;
+ int32_t y;
+} mouseEventAbs;
+
+static int mousePutEventAbs(PPDMIMOUSEPORT pInterface, uint32_t uX,
+ uint32_t uY, int32_t iDeltaZ, int32_t iDeltaW,
+ uint32_t fButtonStates)
+{
+ mouseEventAbs.x = uX;
+ mouseEventAbs.y = uY;
+ return VINF_SUCCESS;
+}
+
+static struct PDMIMOUSEPORT pdmiMousePort =
+{
+ mousePutEvent,
+ mousePutEventAbs
+};
+
+static void *pdmiBaseQuery(struct PDMIBASE *pInterface, const char *pszIID)
+{
+ return &pdmiMousePort;
+}
+
+static struct PDMIBASE pdmiBase =
+{
+ pdmiBaseQuery
+};
+
+static struct PDMDRVINS pdmdrvInsCore =
+{
+ PDM_DRVINS_VERSION,
+ 0,
+ NIL_RTRCPTR,
+ NIL_RTRCPTR,
+ NIL_RTR0PTR,
+ NIL_RTR0PTR,
+ &pdmHlpR3,
+ NULL,
+ NULL,
+ NULL,
+ &pdmiBase
+};
+
+static struct PDMDRVINS *ppdmdrvIns = NULL;
+
+PDMIVMMDEVPORT VMMDevPort;
+Mouse *pMouse;
+Console *pConsole;
+
+static struct
+{
+ int32_t x;
+ int32_t y;
+} absoluteMouse;
+
+static int setAbsoluteMouse(PPDMIVMMDEVPORT, int32_t x, int32_t y)
+{
+ absoluteMouse.x = x;
+ absoluteMouse.y = y;
+ return VINF_SUCCESS;
+}
+
+static int updateMouseCapabilities(PPDMIVMMDEVPORT, uint32_t, uint32_t)
+{
+ return VINF_SUCCESS;
+}
+
+PPDMIVMMDEVPORT VMMDev::getVMMDevPort(void)
+{
+ return &VMMDevPort;
+}
+
+VMMDev::VMMDev() {}
+
+VMMDev::~VMMDev() {}
+
+void Display::getFramebufferDimensions(int32_t *px1, int32_t *py1,
+ int32_t *px2, int32_t *py2)
+{
+ if (px1)
+ *px1 = -320;
+ if (py1)
+ *py1 = -240;
+ if (px2)
+ *px2 = 320;
+ if (py2)
+ *py2 = 240;
+}
+
+STDMETHODIMP Display::GetScreenResolution(ULONG aScreenId,
+ ULONG *aWidth,
+ ULONG *aHeight,
+ ULONG *aBitsPerPixel)
+{
+ if (aWidth)
+ *aWidth = 640;
+ if (aHeight)
+ *aHeight = 480;
+ if (aBitsPerPixel)
+ *aBitsPerPixel = 32;
+ return S_OK;
+}
+
+Display::Display() {}
+
+Display::~Display() {}
+
+DECLEXPORT(bool) CFGMR3AreValuesValid(PCFGMNODE, const char *)
+{
+ return true;
+}
+
+DECLEXPORT(int) CFGMR3QueryPtr(PCFGMNODE, const char *, void **pv)
+{
+ *pv = pMouse;
+ return VINF_SUCCESS;
+}
+
+/******************************************************************************
+* Main test code *
+******************************************************************************/
+
+static int setup(void)
+{
+ VMMDevPort.pfnSetAbsoluteMouse = setAbsoluteMouse;
+ VMMDevPort.pfnUpdateMouseCapabilities = updateMouseCapabilities;
+ pMouse = new Mouse;
+ Assert(SUCCEEDED(pMouse->FinalConstruct()));
+ pConsole = new TestConsole;
+ pMouse->init(pConsole);
+ ppdmdrvIns = (struct PDMDRVINS *) RTMemAllocZ( sizeof(struct PDMDRVINS)
+ + Mouse::DrvReg.cbInstance);
+ *ppdmdrvIns = pdmdrvInsCore;
+ Mouse::DrvReg.pfnConstruct(ppdmdrvIns, NULL, 0);
+ return VINF_SUCCESS;
+}
+
+static void teardown(void)
+{
+ delete pMouse;
+ delete pConsole;
+ RTMemFree(ppdmdrvIns);
+}
+
+static bool approxEq(int a, int b, int prec)
+{
+ return a - b < prec && b - a < prec;
+}
+
+/** @test testAbsToVMMDevNewProtocol */
+static void testAbsToVMMDevNewProtocol(RTTEST hTest)
+{
+ PPDMIBASE pBase;
+ PPDMIMOUSECONNECTOR pConnector;
+
+ RTTestSub(hTest, "Absolute event to VMMDev, new protocol");
+ pBase = &ppdmdrvIns->IBase;
+ pConnector = (PPDMIMOUSECONNECTOR)pBase->pfnQueryInterface(pBase,
+ PDMIMOUSECONNECTOR_IID);
+ pConnector->pfnReportModes(pConnector, true, false);
+ pMouse->onVMMDevGuestCapsChange( VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
+ | VMMDEV_MOUSE_NEW_PROTOCOL);
+ pMouse->PutMouseEventAbsolute(0, 0, 0, 0, 0);
+ RTTESTI_CHECK_MSG(approxEq(absoluteMouse.x, 0x8000, 200),
+ ("absoluteMouse.x=%d\n", absoluteMouse.x));
+ RTTESTI_CHECK_MSG(approxEq(absoluteMouse.y, 0x8000, 200),
+ ("absoluteMouse.y=%d\n", absoluteMouse.y));
+ pMouse->PutMouseEventAbsolute(-319, -239, 0, 0, 0);
+ RTTESTI_CHECK_MSG(approxEq(absoluteMouse.x, 0, 200),
+ ("absoluteMouse.x=%d\n", absoluteMouse.x));
+ RTTESTI_CHECK_MSG(approxEq(absoluteMouse.y, 0, 200),
+ ("absoluteMouse.y=%d\n", absoluteMouse.y));
+ pMouse->PutMouseEventAbsolute(320, 240, 0, 0, 0);
+ RTTESTI_CHECK_MSG(approxEq(absoluteMouse.x, 0xffff, 200),
+ ("absoluteMouse.x=%d\n", absoluteMouse.x));
+ RTTESTI_CHECK_MSG(approxEq(absoluteMouse.y, 0xffff, 200),
+ ("absoluteMouse.y=%d\n", absoluteMouse.y));
+ RTTestSubDone(hTest);
+}
+
+/** @test testAbsToVMMDevOldProtocol */
+static void testAbsToVMMDevOldProtocol(RTTEST hTest)
+{
+ PPDMIBASE pBase;
+ PPDMIMOUSECONNECTOR pConnector;
+
+ RTTestSub(hTest, "Absolute event to VMMDev, old protocol");
+ pBase = &ppdmdrvIns->IBase;
+ pConnector = (PPDMIMOUSECONNECTOR)pBase->pfnQueryInterface(pBase,
+ PDMIMOUSECONNECTOR_IID);
+ pConnector->pfnReportModes(pConnector, true, false);
+ pMouse->onVMMDevGuestCapsChange(VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE);
+ pMouse->PutMouseEventAbsolute(320, 240, 0, 0, 0);
+ RTTESTI_CHECK_MSG(approxEq(absoluteMouse.x, 0x8000, 200),
+ ("absoluteMouse.x=%d\n", absoluteMouse.x));
+ RTTESTI_CHECK_MSG(approxEq(absoluteMouse.y, 0x8000, 200),
+ ("absoluteMouse.y=%d\n", absoluteMouse.y));
+ pMouse->PutMouseEventAbsolute(0, 0, 0, 0, 0);
+ RTTESTI_CHECK_MSG(approxEq(absoluteMouse.x, 0, 200),
+ ("absoluteMouse.x=%d\n", absoluteMouse.x));
+ RTTESTI_CHECK_MSG(approxEq(absoluteMouse.y, 0, 200),
+ ("absoluteMouse.y=%d\n", absoluteMouse.y));
+ pMouse->PutMouseEventAbsolute(-319, -239, 0, 0, 0);
+ RTTESTI_CHECK_MSG(approxEq(absoluteMouse.x, -0x8000, 200),
+ ("absoluteMouse.x=%d\n", absoluteMouse.x));
+ RTTESTI_CHECK_MSG(approxEq(absoluteMouse.y, -0x8000, 200),
+ ("absoluteMouse.y=%d\n", absoluteMouse.y));
+ RTTestSubDone(hTest);
+}
+
+/** @test testAbsToAbsDev */
+static void testAbsToAbsDev(RTTEST hTest)
+{
+ PPDMIBASE pBase;
+ PPDMIMOUSECONNECTOR pConnector;
+
+ RTTestSub(hTest, "Absolute event to absolute device");
+ pBase = &ppdmdrvIns->IBase;
+ pConnector = (PPDMIMOUSECONNECTOR)pBase->pfnQueryInterface(pBase,
+ PDMIMOUSECONNECTOR_IID);
+ pConnector->pfnReportModes(pConnector, false, true);
+ pMouse->onVMMDevGuestCapsChange( VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
+ | VMMDEV_MOUSE_NEW_PROTOCOL);
+ pMouse->PutMouseEventAbsolute(0, 0, 0, 0, 0);
+ RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.x, 0x8000, 200),
+ ("mouseEventAbs.x=%d\n", mouseEventAbs.x));
+ RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.y, 0x8000, 200),
+ ("mouseEventAbs.y=%d\n", mouseEventAbs.y));
+ pMouse->PutMouseEventAbsolute(-319, -239, 0, 0, 0);
+ RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.x, 0, 200),
+ ("mouseEventAbs.x=%d\n", mouseEventAbs.x));
+ RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.y, 0, 200),
+ ("mouseEventAbs.y=%d\n", mouseEventAbs.y));
+ pMouse->PutMouseEventAbsolute(320, 240, 0, 0, 0);
+ RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.x, 0xffff, 200),
+ ("mouseEventAbs.x=%d\n", mouseEventAbs.x));
+ RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.y, 0xffff, 200),
+ ("mouseEventAbs.y=%d\n", mouseEventAbs.y));
+ mouseEventAbs.x = mouseEventAbs.y = 0xffff;
+ pMouse->PutMouseEventAbsolute(-640, -480, 0, 0, 0);
+ RTTESTI_CHECK_MSG(mouseEventAbs.x = 0xffff,
+ ("mouseEventAbs.x=%d\n", mouseEventAbs.x));
+ RTTESTI_CHECK_MSG(mouseEventAbs.y == 0xffff,
+ ("mouseEventAbs.y=%d\n", mouseEventAbs.y));
+ RTTestSubDone(hTest);
+}
+
+/** @todo generate this using the @test blocks above */
+typedef void (*PFNTEST)(RTTEST);
+static PFNTEST g_tests[] =
+{
+ testAbsToVMMDevNewProtocol,
+ testAbsToVMMDevOldProtocol,
+ testAbsToAbsDev,
+ NULL
+};
+
+int main(void)
+{
+ /*
+ * Init the runtime, test and say hello.
+ */
+ RTTEST hTest;
+ RTEXITCODE rcExit = RTTestInitAndCreate("tstMouseImpl", &hTest);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ RTTestBanner(hTest);
+
+ /*
+ * Run the tests.
+ */
+ for (unsigned i = 0; g_tests[i]; ++i)
+ {
+ AssertRC(setup());
+ g_tests[i](hTest);
+ teardown();
+ }
+
+ /*
+ * Summary
+ */
+ return RTTestSummaryAndDestroy(hTest);
+}
+
diff --git a/src/VBox/Frontends/VBoxBalloonCtrl/Makefile.kmk b/src/VBox/Frontends/VBoxBalloonCtrl/Makefile.kmk
index a5e3742e6..3321605fa 100644
--- a/src/VBox/Frontends/VBoxBalloonCtrl/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxBalloonCtrl/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 36693 2011-04-18 07:57:57Z vboxsync $
## @file
# VBoxBalloonCtrl - Memory balloon control.
#
diff --git a/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.cpp b/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.cpp
index c6fe22f3f..f1fe597a6 100644
--- a/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.cpp
+++ b/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxBalloonCtrl.cpp $ */
+/* $Id: VBoxBalloonCtrl.cpp 37103 2011-05-16 12:59:24Z vboxsync $ */
/** @file
* VBoxBalloonCtrl - VirtualBox Ballooning Control Service.
*/
@@ -189,6 +189,15 @@ class VirtualBoxEventListener
{
}
+ HRESULT init()
+ {
+ return S_OK;
+ }
+
+ void uninit()
+ {
+ }
+
STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent)
{
switch (aType)
@@ -472,10 +481,7 @@ static int machineAdd(const Bstr &strUuid)
com::SafeIfaceArray<IUnknown> metricObjects(1);
com::SafeIfaceArray<IPerformanceMetric> metricAffected;
- /* NOTE: the base metric for Guest/RAM/Usage is RAM/Usage up to
- * VirtualBox 4.0. Somewhat inconsistent, but changing may be
- * considered an API change since it can break existing API clients. */
- Bstr strMetricNames(L"RAM/Usage");
+ Bstr strMetricNames(L"Guest/RAM/Usage");
strMetricNames.cloneTo(&metricNames[0]);
m.machine.queryInterfaceTo(&metricObjects[0]);
@@ -998,12 +1004,16 @@ static RTEXITCODE balloonCtrlMain(HandlerArg *a)
CHECK_ERROR_BREAK(g_pVirtualBox, COMGETTER(EventSource)(g_pEventSource.asOutParam()));
CHECK_ERROR_BREAK(g_pVirtualBoxClient, COMGETTER(EventSource)(g_pEventSourceClient.asOutParam()));
+ ComObjPtr<VirtualBoxEventListenerImpl> vboxListenerImpl;
+ vboxListenerImpl.createObject();
+ vboxListenerImpl->init(new VirtualBoxEventListener());
+
com::SafeArray <VBoxEventType_T> eventTypes;
eventTypes.push_back(VBoxEventType_OnMachineRegistered);
eventTypes.push_back(VBoxEventType_OnMachineStateChanged);
eventTypes.push_back(VBoxEventType_OnVBoxSVCAvailabilityChanged); /* Processed by g_pEventSourceClient. */
- g_pVBoxEventListener = new VirtualBoxEventListenerImpl();
+ g_pVBoxEventListener = vboxListenerImpl;
CHECK_ERROR_BREAK(g_pEventSource, RegisterListener(g_pVBoxEventListener, ComSafeArrayAsInParam(eventTypes), true /* Active listener */));
CHECK_ERROR_BREAK(g_pEventSourceClient, RegisterListener(g_pVBoxEventListener, ComSafeArrayAsInParam(eventTypes), true /* Active listener */));
diff --git a/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.h b/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.h
index 64adeda60..174322bb3 100644
--- a/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.h
+++ b/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxBalloonCtrl.h $ */
+/* $Id: VBoxBalloonCtrl.h 36707 2011-04-18 12:17:33Z vboxsync $ */
/** @file
* VBoxBalloonCtrl - VirtualBox Ballooning Control Service.
*/
diff --git a/src/VBox/Frontends/VBoxFB/Makefile.kmk b/src/VBox/Frontends/VBoxFB/Makefile.kmk
index cc5d5d71d..b02d4dcea 100644
--- a/src/VBox/Frontends/VBoxFB/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxFB/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for VBoxFB.
#
diff --git a/src/VBox/Frontends/VBoxFB/VBoxFB.h b/src/VBox/Frontends/VBoxFB/VBoxFB.h
index ff8cf237e..553f5a073 100644
--- a/src/VBox/Frontends/VBoxFB/VBoxFB.h
+++ b/src/VBox/Frontends/VBoxFB/VBoxFB.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2006-2009 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;
@@ -19,9 +19,6 @@
#ifndef __H_VBOXFB
#define __H_VBOXFB
-// release logging
-#define LOG_ENABLED
-
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
diff --git a/src/VBox/Frontends/VBoxHeadless/FramebufferVNC.cpp b/src/VBox/Frontends/VBoxHeadless/FramebufferVNC.cpp
index bc211dbfe..1265d3d2c 100644
--- a/src/VBox/Frontends/VBoxHeadless/FramebufferVNC.cpp
+++ b/src/VBox/Frontends/VBoxHeadless/FramebufferVNC.cpp
@@ -1,4 +1,4 @@
-/* $Id: FramebufferVNC.cpp $ */
+/* $Id: FramebufferVNC.cpp 36694 2011-04-18 08:18:00Z vboxsync $ */
/** @file
* VBoxHeadless - VNC server implementation for VirtualBox.
*
diff --git a/src/VBox/Frontends/VBoxHeadless/FramebufferVNC.h b/src/VBox/Frontends/VBoxHeadless/FramebufferVNC.h
index c7e42cf23..93538d4f1 100644
--- a/src/VBox/Frontends/VBoxHeadless/FramebufferVNC.h
+++ b/src/VBox/Frontends/VBoxHeadless/FramebufferVNC.h
@@ -1,4 +1,4 @@
-/* $Id: FramebufferVNC.h $ */
+/* $Id: FramebufferVNC.h 31698 2010-08-16 15:00:05Z vboxsync $ */
/** @file
* VBox Remote Desktop Protocol - VNC server interface.
*/
diff --git a/src/VBox/Frontends/VBoxHeadless/Makefile.kmk b/src/VBox/Frontends/VBoxHeadless/Makefile.kmk
index a6a44175d..6c0b419f8 100644
--- a/src/VBox/Frontends/VBoxHeadless/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxHeadless/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 33590 2010-10-29 08:55:09Z vboxsync $
## @file
# Sub-Makefile for the headless frontend.
#
diff --git a/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp b/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
index 57bc5a7f2..0eb0c4c66 100644
--- a/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
+++ b/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxHeadless.cpp $ */
+/* $Id: VBoxHeadless.cpp 37473 2011-06-15 16:16:31Z vboxsync $ */
/** @file
* VBoxHeadless - The VirtualBox Headless frontend for running VMs on servers.
*/
@@ -101,6 +101,15 @@ public:
{
}
+ HRESULT init()
+ {
+ return S_OK;
+ }
+
+ void uninit()
+ {
+ }
+
STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent)
{
switch (aType)
@@ -147,6 +156,15 @@ public:
{
}
+ HRESULT init()
+ {
+ return S_OK;
+ }
+
+ void uninit()
+ {
+ }
+
STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent)
{
switch (aType)
@@ -267,6 +285,15 @@ public:
{
}
+ HRESULT init()
+ {
+ return S_OK;
+ }
+
+ void uninit()
+ {
+ }
+
STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent)
{
switch (aType)
@@ -517,7 +544,7 @@ static void parse_environ(unsigned long *pulFrameWidth, unsigned long *pulFrameH
}
#endif /* VBOX_FFMPEG defined */
-#ifdef RT_OS_WINDOWS
+#ifdef RT_OS_WINDOWS
// Required for ATL
static CComModule _Module;
#endif
@@ -550,12 +577,6 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
const char *pszFileNameParam = "VBox-%d.vob";
#endif /* VBOX_FFMPEG */
-
- /* Make sure that DISPLAY is unset, so that X11 bits do not get initialised
- * on X11-using OSes. */
- /** @todo this should really be taken care of in Main. */
- RTEnvUnset("DISPLAY");
-
LogFlow (("VBoxHeadless STARTED.\n"));
RTPrintf (VBOX_PRODUCT " Headless Interface " VBOX_VERSION_STRING "\n"
"(C) 2008-" VBOX_C_YEAR " " VBOX_VENDOR "\n"
@@ -781,9 +802,9 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
ComPtr<ISession> session;
ComPtr<IMachine> machine;
bool fSessionOpened = false;
- IEventListener *vboxClientListener = NULL;
- IEventListener *vboxListener = NULL;
- ConsoleEventListenerImpl *consoleListener = NULL;
+ ComPtr<IEventListener> vboxClientListener;
+ ComPtr<IEventListener> vboxListener;
+ ComObjPtr<ConsoleEventListenerImpl> consoleListener;
do
{
@@ -1019,7 +1040,10 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
{
ComPtr<IEventSource> pES;
CHECK_ERROR(pVirtualBoxClient, COMGETTER(EventSource)(pES.asOutParam()));
- vboxClientListener = new VirtualBoxClientEventListenerImpl();
+ ComObjPtr<VirtualBoxClientEventListenerImpl> listener;
+ listener.createObject();
+ listener->init(new VirtualBoxClientEventListener());
+ vboxClientListener = listener;
com::SafeArray<VBoxEventType_T> eventTypes;
eventTypes.push_back(VBoxEventType_OnVBoxSVCAvailabilityChanged);
CHECK_ERROR(pES, RegisterListener(vboxClientListener, ComSafeArrayAsInParam(eventTypes), true));
@@ -1029,7 +1053,8 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
{
ComPtr<IEventSource> es;
CHECK_ERROR(console, COMGETTER(EventSource)(es.asOutParam()));
- consoleListener = new ConsoleEventListenerImpl();
+ consoleListener.createObject();
+ consoleListener->init(new ConsoleEventListener());
com::SafeArray<VBoxEventType_T> eventTypes;
eventTypes.push_back(VBoxEventType_OnMouseCapabilityChanged);
eventTypes.push_back(VBoxEventType_OnStateChanged);
@@ -1132,6 +1157,9 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
}
}
+ /* Disable the host clipboard before powering up */
+ console->COMSETTER(UseHostClipboard)(false);
+
Log(("VBoxHeadless: Powering up the machine...\n"));
ComPtr <IProgress> progress;
@@ -1184,7 +1212,10 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
{
ComPtr<IEventSource> es;
CHECK_ERROR(virtualBox, COMGETTER(EventSource)(es.asOutParam()));
- vboxListener = new VirtualBoxEventListenerImpl();
+ ComObjPtr<VirtualBoxEventListenerImpl> listener;
+ listener.createObject();
+ listener->init(new VirtualBoxEventListener());
+ vboxListener = listener;
com::SafeArray<VBoxEventType_T> eventTypes;
eventTypes.push_back(VBoxEventType_OnGuestPropertyChanged);
CHECK_ERROR(es, RegisterListener(vboxListener, ComSafeArrayAsInParam(eventTypes), true));
@@ -1263,7 +1294,7 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
CHECK_ERROR(virtualBox, COMGETTER(EventSource)(es.asOutParam()));
if (!es.isNull())
CHECK_ERROR(es, UnregisterListener(vboxListener));
- vboxListener->Release();
+ vboxListener.setNull();
}
/* Console callback unregistration. */
@@ -1273,7 +1304,7 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
CHECK_ERROR(gConsole, COMGETTER(EventSource)(es.asOutParam()));
if (!es.isNull())
CHECK_ERROR(es, UnregisterListener(consoleListener));
- consoleListener->Release();
+ consoleListener.setNull();
}
/* VirtualBoxClient callback unregistration. */
@@ -1283,7 +1314,7 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
CHECK_ERROR(pVirtualBoxClient, COMGETTER(EventSource)(pES.asOutParam()));
if (!pES.isNull())
CHECK_ERROR(pES, UnregisterListener(vboxClientListener));
- vboxClientListener->Release();
+ vboxClientListener.setNull();
}
/* No more access to the 'console' object, which will be uninitialized by the next session->Close call. */
@@ -1304,7 +1335,7 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
virtualBox.setNull();
pVirtualBoxClient.setNull();
machine.setNull();
-
+
com::Shutdown();
LogFlow(("VBoxHeadless FINISHED.\n"));
diff --git a/src/VBox/Frontends/VBoxHeadless/VBoxHeadlessHardened.cpp b/src/VBox/Frontends/VBoxHeadless/VBoxHeadlessHardened.cpp
index abb18eea8..543f4a3c2 100644
--- a/src/VBox/Frontends/VBoxHeadless/VBoxHeadlessHardened.cpp
+++ b/src/VBox/Frontends/VBoxHeadless/VBoxHeadlessHardened.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxHeadlessHardened.cpp $ */
+/* $Id: VBoxHeadlessHardened.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxHeadless - Hardened main().
*/
diff --git a/src/VBox/Frontends/VBoxHeadless/VideoCapture/Makefile.kmk b/src/VBox/Frontends/VBoxHeadless/VideoCapture/Makefile.kmk
index 885e755b7..8a4e5f056 100644
--- a/src/VBox/Frontends/VBoxHeadless/VideoCapture/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxHeadless/VideoCapture/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the ffmpeg frame buffer module.
#
diff --git a/src/VBox/Frontends/VBoxHeadless/testcase/Makefile.kmk b/src/VBox/Frontends/VBoxHeadless/testcase/Makefile.kmk
index ed7ab74f1..e7c97b8cb 100644
--- a/src/VBox/Frontends/VBoxHeadless/testcase/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxHeadless/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the VRDP (headless RDP server) frontend testcase.
#
diff --git a/src/VBox/Frontends/VBoxManage/Makefile.kmk b/src/VBox/Frontends/VBoxManage/Makefile.kmk
index bcb9a66ca..5d294a943 100644
--- a/src/VBox/Frontends/VBoxManage/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxManage/Makefile.kmk
@@ -1,10 +1,10 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37402 2011-06-10 06:35:28Z vboxsync $
## @file
# Sub-Makefile for VBoxManage (the cli frontend).
#
#
-# Copyright (C) 2006-2007 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;
@@ -24,54 +24,54 @@ ifdef VBOX_ONLY_DOCS
VBoxManage_DEFS += VBOX_ONLY_DOCS
VBoxManage_SOURCES = \
VBoxManage.cpp \
- VBoxManageHelp.cpp \
- $(if $(VBOX_WITH_GUEST_PROPS),VBoxManageGuestProp.cpp) \
+ VBoxManageHelp.cpp \
+ $(if $(VBOX_WITH_GUEST_PROPS),VBoxManageGuestProp.cpp) \
$(if $(VBOX_WITH_GUEST_CONTROL),VBoxManageGuestCtrl.cpp)
VBoxManage_LIBS += $(LIB_RUNTIME)
else # !VBOX_ONLY_DOCS
VBoxManage_TEMPLATE = VBOXMAINCLIENTEXE
VBoxManage_DEFS.win = _WIN32_WINNT=0x0500
VBoxManage_SOURCES = \
- VBoxManage.cpp \
- VBoxInternalManage.cpp \
- VBoxManageControlVM.cpp \
- VBoxManageDebugVM.cpp \
- VBoxManageDHCPServer.cpp \
- VBoxManageDisk.cpp \
- $(if $(VBOX_WITH_GUEST_PROPS),VBoxManageGuestProp.cpp) \
+ VBoxManage.cpp \
+ VBoxInternalManage.cpp \
+ VBoxManageAppliance.cpp \
+ VBoxManageBandwidthControl.cpp \
+ VBoxManageControlVM.cpp \
+ VBoxManageDebugVM.cpp \
+ VBoxManageDHCPServer.cpp \
+ VBoxManageDisk.cpp \
$(if $(VBOX_WITH_GUEST_CONTROL),VBoxManageGuestCtrl.cpp) \
- VBoxManageHelp.cpp \
- VBoxManageHostonly.cpp \
- VBoxManageAppliance.cpp \
- VBoxManageInfo.cpp \
- VBoxManageList.cpp \
- VBoxManageMetrics.cpp \
- VBoxManageMisc.cpp \
- VBoxManageModifyVM.cpp \
- VBoxManageSnapshot.cpp \
- VBoxManageStorageController.cpp \
- VBoxManageUSB.cpp \
- VBoxManageBandwidthControl.cpp
+ $(if $(VBOX_WITH_GUEST_PROPS),VBoxManageGuestProp.cpp) \
+ VBoxManageHelp.cpp \
+ VBoxManageHostonly.cpp \
+ VBoxManageInfo.cpp \
+ VBoxManageList.cpp \
+ VBoxManageMetrics.cpp \
+ VBoxManageMisc.cpp \
+ VBoxManageModifyVM.cpp \
+ VBoxManageSnapshot.cpp \
+ VBoxManageStorageController.cpp \
+ VBoxManageUSB.cpp
endif # !VBOX_ONLY_DOCS
VBoxManage_DEFS += \
- $(if $(VBOX_WITH_AHCI), VBOX_WITH_AHCI) \
- $(if $(VBOX_WITH_ALSA), VBOX_WITH_ALSA) \
+ $(if $(VBOX_WITH_AHCI), VBOX_WITH_AHCI) \
+ $(if $(VBOX_WITH_ALSA), VBOX_WITH_ALSA) \
$(if $(VBOX_WITH_COPYTOGUEST),VBOX_WITH_COPYTOGUEST) \
- $(if $(VBOX_WITH_E1000),VBOX_WITH_E1000) \
- $(if $(VBOX_WITH_GUEST_CONTROL),VBOX_WITH_GUEST_CONTROL) \
- $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS) \
- $(if $(VBOX_WITH_HEADLESS), VBOX_WITH_HEADLESS) \
+ $(if $(VBOX_WITH_E1000),VBOX_WITH_E1000) \
+ $(if $(VBOX_WITH_GUEST_CONTROL),VBOX_WITH_GUEST_CONTROL) \
+ $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS) \
+ $(if $(VBOX_WITH_HEADLESS), VBOX_WITH_HEADLESS) \
$(if $(VBOX_WITH_HGCM), VBOX_WITH_HGCM) \
- $(if $(VBOX_WITH_HOSTNETIF_API), VBOX_WITH_HOSTNETIF_API) \
+ $(if $(VBOX_WITH_HOSTNETIF_API), VBOX_WITH_HOSTNETIF_API) \
$(if $(VBOX_WITH_NETFLT), VBOX_WITH_NETFLT) \
- $(if $(VBOX_WITH_PULSE),VBOX_WITH_PULSE) \
- $(if $(VBOX_WITH_SCSI), VBOX_WITH_SCSI) \
- $(if $(VBOX_WITH_SOLARIS_OSS), VBOX_WITH_SOLARIS_OSS) \
- $(if $(VBOX_WITH_VBOXSDL), VBOX_WITH_VBOXSDL) \
- $(if $(VBOX_WITH_VDE), VBOX_WITH_VDE) \
+ $(if $(VBOX_WITH_PULSE),VBOX_WITH_PULSE) \
+ $(if $(VBOX_WITH_SCSI), VBOX_WITH_SCSI) \
+ $(if $(VBOX_WITH_SOLARIS_OSS), VBOX_WITH_SOLARIS_OSS) \
+ $(if $(VBOX_WITH_VBOXSDL), VBOX_WITH_VBOXSDL) \
$(if $(VBOX_WITH_VIDEOHWACCEL), VBOX_WITH_VIDEOHWACCEL) \
- $(if $(VBOX_WITH_VIRTIO),VBOX_WITH_VIRTIO)
+ $(if $(VBOX_WITH_VIRTIO),VBOX_WITH_VIRTIO) \
+ $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH)
ifneq ($(KBUILD_TARGET),win)
# Workaround for buggy gcc-4.3 compilers, see
diff --git a/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp b/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp
index a48dad6f8..52adb6f10 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxInternalManage.cpp $ */
+/* $Id: VBoxInternalManage.cpp 37925 2011-07-13 15:31:10Z vboxsync $ */
/** @file
* VBoxManage - The 'internalcommands' command.
*
@@ -136,7 +136,7 @@ void printUsageInternal(USAGECATEGORY u64Cmd, PRTSTREAM pStrm)
"\n"
"Commands:\n"
"\n"
- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
"WARNING: This is a development tool and shall only be used to analyse\n"
" problems. It is completely unsupported and will change in\n"
" incompatible ways without warning.\n",
@@ -242,8 +242,13 @@ void printUsageInternal(USAGECATEGORY u64Cmd, PRTSTREAM pStrm)
? " passwordhash <passsword>\n"
" Generates a password hash.\n"
"\n"
- :
- ""
+ : "",
+ (u64Cmd & USAGE_GUESTSTATS)
+ ? " gueststats <vmname>|<uuid> [--interval <seconds>]\n"
+ " Obtains and prints internal guest statistics.\n"
+ " Sets the update interval if specified.\n"
+ "\n"
+ : ""
);
}
@@ -858,8 +863,8 @@ static int CmdListPartitions(int argc, char **argv, ComPtr<IVirtualBox> aVirtual
if (rawdisk.isEmpty())
return errorSyntax(USAGE_LISTPARTITIONS, "Mandatory parameter -rawdisk missing");
- RTFILE RawFile;
- int vrc = RTFileOpen(&RawFile, rawdisk.c_str(), RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+ RTFILE hRawFile;
+ int vrc = RTFileOpen(&hRawFile, rawdisk.c_str(), RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
if (RT_FAILURE(vrc))
{
RTMsgError("Cannot open the raw disk: %Rrc", vrc);
@@ -867,7 +872,7 @@ static int CmdListPartitions(int argc, char **argv, ComPtr<IVirtualBox> aVirtual
}
HOSTPARTITIONS partitions;
- vrc = partRead(RawFile, &partitions);
+ vrc = partRead(hRawFile, &partitions);
/* Don't bail out on errors, print the table and return the result code. */
RTPrintf("Number Type StartCHS EndCHS Size (MiB) Start (Sect)\n");
@@ -983,8 +988,8 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
#ifdef RT_OS_DARWIN
fRelative = true;
#endif /* RT_OS_DARWIN */
- RTFILE RawFile;
- int vrc = RTFileOpen(&RawFile, rawdisk.c_str(), RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+ RTFILE hRawFile;
+ int vrc = RTFileOpen(&hRawFile, rawdisk.c_str(), RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
if (RT_FAILURE(vrc))
{
RTMsgError("Cannot open the raw disk '%s': %Rrc", rawdisk.c_str(), vrc);
@@ -1002,7 +1007,7 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
*/
DISK_GEOMETRY DriveGeo;
DWORD cbDriveGeo;
- if (DeviceIoControl((HANDLE)RawFile,
+ if (DeviceIoControl((HANDLE)RTFileToNative(hRawFile),
IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
&DriveGeo, sizeof(DriveGeo), &cbDriveGeo, NULL))
{
@@ -1023,7 +1028,7 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
GET_LENGTH_INFORMATION DiskLenInfo;
DWORD junk;
- if (DeviceIoControl((HANDLE)RawFile,
+ if (DeviceIoControl((HANDLE)RTFileToNative(hRawFile),
IOCTL_DISK_GET_LENGTH_INFO, NULL, 0,
&DiskLenInfo, sizeof(DiskLenInfo), &junk, (LPOVERLAPPED)NULL))
{
@@ -1039,7 +1044,7 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
}
#elif defined(RT_OS_LINUX)
struct stat DevStat;
- if (!fstat(RawFile, &DevStat) && S_ISBLK(DevStat.st_mode))
+ if (!fstat(RTFileToNative(hRawFile), &DevStat) && S_ISBLK(DevStat.st_mode))
{
#ifdef BLKGETSIZE64
/* BLKGETSIZE64 is broken up to 2.4.17 and in many 2.5.x. In 2.6.0
@@ -1050,14 +1055,14 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
|| (strncmp(utsname.release, "2.", 2) == 0 && atoi(&utsname.release[2]) >= 6)))
{
uint64_t cbBlk;
- if (!ioctl(RawFile, BLKGETSIZE64, &cbBlk))
+ if (!ioctl(RTFileToNative(hRawFile), BLKGETSIZE64, &cbBlk))
cbSize = cbBlk;
}
#endif /* BLKGETSIZE64 */
if (!cbSize)
{
long cBlocks;
- if (!ioctl(RawFile, BLKGETSIZE, &cBlocks))
+ if (!ioctl(RTFileToNative(hRawFile), BLKGETSIZE, &cBlocks))
cbSize = (uint64_t)cBlocks << 9;
else
{
@@ -1075,13 +1080,13 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
}
#elif defined(RT_OS_DARWIN)
struct stat DevStat;
- if (!fstat(RawFile, &DevStat) && S_ISBLK(DevStat.st_mode))
+ if (!fstat(RTFileToNative(hRawFile), &DevStat) && S_ISBLK(DevStat.st_mode))
{
uint64_t cBlocks;
uint32_t cbBlock;
- if (!ioctl(RawFile, DKIOCGETBLOCKCOUNT, &cBlocks))
+ if (!ioctl(RTFileToNative(hRawFile), DKIOCGETBLOCKCOUNT, &cBlocks))
{
- if (!ioctl(RawFile, DKIOCGETBLOCKSIZE, &cbBlock))
+ if (!ioctl(RTFileToNative(hRawFile), DKIOCGETBLOCKSIZE, &cbBlock))
cbSize = cBlocks * cbBlock;
else
{
@@ -1105,11 +1110,11 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
}
#elif defined(RT_OS_SOLARIS)
struct stat DevStat;
- if (!fstat(RawFile, &DevStat) && ( S_ISBLK(DevStat.st_mode)
+ if (!fstat(RTFileToNative(hRawFile), &DevStat) && ( S_ISBLK(DevStat.st_mode)
|| S_ISCHR(DevStat.st_mode)))
{
struct dk_minfo mediainfo;
- if (!ioctl(RawFile, DKIOCGMEDIAINFO, &mediainfo))
+ if (!ioctl(RTFileToNative(hRawFile), DKIOCGMEDIAINFO, &mediainfo))
cbSize = mediainfo.dki_capacity * mediainfo.dki_lbsize;
else
{
@@ -1126,10 +1131,10 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
}
#elif defined(RT_OS_FREEBSD)
struct stat DevStat;
- if (!fstat(RawFile, &DevStat) && S_ISCHR(DevStat.st_mode))
+ if (!fstat(RTFileToNative(hRawFile), &DevStat) && S_ISCHR(DevStat.st_mode))
{
off_t cbMedia = 0;
- if (!ioctl(RawFile, DIOCGMEDIASIZE, &cbMedia))
+ if (!ioctl(RTFileToNative(hRawFile), DIOCGMEDIASIZE, &cbMedia))
{
cbSize = cbMedia;
}
@@ -1149,7 +1154,7 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
#else /* all unrecognized OSes */
/* Hopefully this works on all other hosts. If it doesn't, it'll just fail
* creating the VMDK, so no real harm done. */
- vrc = RTFileGetSize(RawFile, &cbSize);
+ vrc = RTFileGetSize(hRawFile, &cbSize);
if (RT_FAILURE(vrc))
{
RTMsgError("Cannot get the size of the raw disk '%s': %Rrc", rawdisk.c_str(), vrc);
@@ -1207,7 +1212,7 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
}
HOSTPARTITIONS partitions;
- vrc = partRead(RawFile, &partitions);
+ vrc = partRead(hRawFile, &partitions);
if (RT_FAILURE(vrc))
{
RTMsgError("Cannot read the partition information from '%s'", rawdisk.c_str());
@@ -1248,7 +1253,7 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
}
/** @todo the clipping below isn't 100% accurate, as it should
- * actually clip to the track size. However that's easier said
+ * actually clip to the track size. However, that's easier said
* than done as figuring out the track size is heuristics. In
* any case the clipping is adjusted later after sorting, to
* prevent overlapping data areas on the resulting image. */
@@ -1262,7 +1267,7 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
vrc = VERR_NO_MEMORY;
goto out;
}
- vrc = RTFileReadAt(RawFile, partitions.aPartitions[i].uPartDataStart * 512,
+ vrc = RTFileReadAt(hRawFile, partitions.aPartitions[i].uPartDataStart * 512,
pPartData, (size_t)pPartDesc->cbData, NULL);
if (RT_FAILURE(vrc))
{
@@ -1409,7 +1414,7 @@ static int CmdCreateRawVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
}
}
- RTFileClose(RawFile);
+ RTFileClose(hRawFile);
#ifdef DEBUG_klaus
RTPrintf("# start length startoffset partdataptr device\n");
@@ -1632,7 +1637,7 @@ static int CmdConvertToRaw(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBo
RTFILE outFile;
vrc = VINF_SUCCESS;
if (fWriteToStdOut)
- outFile = 1;
+ vrc = RTFileFromNative(&outFile, 1);
else
vrc = RTFileOpen(&outFile, dst.c_str(), RTFILE_O_WRITE | RTFILE_O_CREATE | RTFILE_O_DENY_ALL);
if (RT_FAILURE(vrc))
@@ -1922,11 +1927,11 @@ int CmdDebugLog(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<I
bool fEnablePresent = false;
bool fEnable = false;
bool fFlagsPresent = false;
- iprt::MiniString strFlags;
+ RTCString strFlags;
bool fGroupsPresent = false;
- iprt::MiniString strGroups;
+ RTCString strGroups;
bool fDestsPresent = false;
- iprt::MiniString strDests;
+ RTCString strDests;
static const RTGETOPTDEF s_aOptions[] =
{
@@ -2024,6 +2029,88 @@ int CmdGeneratePasswordHash(int argc, char **argv, ComPtr<IVirtualBox> aVirtualB
}
/**
+ * Print internal guest statistics or
+ * set internal guest statistics update interval if specified
+ */
+int CmdGuestStats(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ /* one parameter, guest name */
+ if (argc < 1)
+ return errorSyntax(USAGE_GUESTSTATS, "Missing VM name/UUID");
+
+ /*
+ * Parse the command.
+ */
+ ULONG aUpdateInterval = 0;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--interval", 'i', RTGETOPT_REQ_UINT32 }
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (ch)
+ {
+ case 'i':
+ aUpdateInterval = ValueUnion.u32;
+ break;
+
+ default:
+ return errorGetOpt(USAGE_GUESTSTATS , ch, &ValueUnion);
+ }
+ }
+
+ if (argc > 1 && aUpdateInterval == 0)
+ return errorSyntax(USAGE_GUESTSTATS, "Invalid update interval specified");
+
+ RTPrintf("argc=%d interval=%u\n", argc, aUpdateInterval);
+
+ ComPtr<IMachine> ptrMachine;
+ HRESULT rc;
+ CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[0]).raw(),
+ ptrMachine.asOutParam()), 1);
+
+ CHECK_ERROR_RET(ptrMachine, LockMachine(aSession, LockType_Shared), 1);
+
+ /*
+ * Get the guest interface.
+ */
+ ComPtr<IConsole> ptrConsole;
+ CHECK_ERROR_RET(aSession, COMGETTER(Console)(ptrConsole.asOutParam()), 1);
+
+ ComPtr<IGuest> ptrGuest;
+ CHECK_ERROR_RET(ptrConsole, COMGETTER(Guest)(ptrGuest.asOutParam()), 1);
+
+ if (aUpdateInterval)
+ CHECK_ERROR_RET(ptrGuest, COMSETTER(StatisticsUpdateInterval)(aUpdateInterval), 1);
+ else
+ {
+ ULONG mCpuUser, mCpuKernel, mCpuIdle;
+ ULONG mMemTotal, mMemFree, mMemBalloon, mMemShared, mMemCache, mPageTotal;
+ ULONG ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemSharedTotal;
+
+ CHECK_ERROR_RET(ptrGuest, InternalGetStatistics(&mCpuUser, &mCpuKernel, &mCpuIdle,
+ &mMemTotal, &mMemFree, &mMemBalloon, &mMemShared, &mMemCache,
+ &mPageTotal, &ulMemAllocTotal, &ulMemFreeTotal, &ulMemBalloonTotal, &ulMemSharedTotal), 1);
+ RTPrintf("mCpuUser=%u mCpuKernel=%u mCpuIdle=%u\n"
+ "mMemTotal=%u mMemFree=%u mMemBalloon=%u mMemShared=%u mMemCache=%u\n"
+ "mPageTotal=%u ulMemAllocTotal=%u ulMemFreeTotal=%u ulMemBalloonTotal=%u ulMemSharedTotal=%u\n",
+ mCpuUser, mCpuKernel, mCpuIdle,
+ mMemTotal, mMemFree, mMemBalloon, mMemShared, mMemCache,
+ mPageTotal, ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemSharedTotal);
+
+ }
+
+ return 0;
+}
+
+
+/**
* Wrapper for handling internal commands
*/
int handleInternalCommands(HandlerArg *a)
@@ -2064,6 +2151,8 @@ int handleInternalCommands(HandlerArg *a)
return CmdDebugLog(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
if (!strcmp(pszCmd, "passwordhash"))
return CmdGeneratePasswordHash(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
+ if (!strcmp(pszCmd, "gueststats"))
+ return CmdGuestStats(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
/* default: */
return errorSyntax(USAGE_ALL, "Invalid command '%s'", a->argv[0]);
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManage.cpp b/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
index 0bd3b1ee4..7c23bbf6d 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManage.cpp $ */
+/* $Id: VBoxManage.cpp 37172 2011-05-20 17:15:55Z vboxsync $ */
/** @file
* VBoxManage - VirtualBox's command-line interface.
*/
@@ -231,7 +231,7 @@ HRESULT showProgress(ComPtr<IProgress> progress)
#endif /* !VBOX_ONLY_DOCS */
-#ifdef RT_OS_WINDOWS
+#ifdef RT_OS_WINDOWS
// Required for ATL
static CComModule _Module;
#endif
@@ -405,6 +405,7 @@ int main(int argc, char *argv[])
{ "showvminfo", USAGE_SHOWVMINFO, handleShowVMInfo },
{ "registervm", USAGE_REGISTERVM, handleRegisterVM },
{ "unregistervm", USAGE_UNREGISTERVM, handleUnregisterVM },
+ { "clonevm", USAGE_CLONEVM, handleCloneVM },
{ "createhd", USAGE_CREATEHD, handleCreateHardDisk },
{ "createvdi", USAGE_CREATEHD, handleCreateHardDisk }, /* backward compatibility */
{ "modifyhd", USAGE_MODIFYHD, handleModifyHardDisk },
@@ -469,7 +470,19 @@ int main(int argc, char *argv[])
}
}
if (!s_commandHandlers[commandIndex].command)
- rcExit = errorSyntax(USAGE_ALL, "Invalid command '%s'", Utf8Str(argv[iCmd]).c_str());
+ {
+ /* Help topics. */
+ if (fShowHelp && !strcmp(argv[iCmd], "commands"))
+ {
+ RTPrintf("commands:\n");
+ for (unsigned i = 0; i < RT_ELEMENTS(s_commandHandlers) - 1; i++)
+ if ( i == 0 /* skip backwards compatibility entries */
+ || s_commandHandlers[i].help != s_commandHandlers[i - 1].help)
+ RTPrintf(" %s\n", s_commandHandlers[i].command);
+ }
+ else
+ rcExit = errorSyntax(USAGE_ALL, "Invalid command '%s'", Utf8Str(argv[iCmd]).c_str());
+ }
/* Although all handlers should always close the session if they open it,
* we do it here just in case if some of the handlers contains a bug --
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManage.h b/src/VBox/Frontends/VBoxManage/VBoxManage.h
index 6fd478c98..f557d92de 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManage.h
+++ b/src/VBox/Frontends/VBoxManage/VBoxManage.h
@@ -1,10 +1,10 @@
-/* $Id: VBoxManage.h $ */
+/* $Id: VBoxManage.h 37525 2011-06-17 10:09:21Z vboxsync $ */
/** @file
* VBoxManage - VirtualBox command-line interface, internal header file.
*/
/*
- * 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;
@@ -44,10 +44,11 @@
#define USAGE_UNREGISTERVM RT_BIT_64(3)
#define USAGE_CREATEVM RT_BIT_64(4)
#define USAGE_MODIFYVM RT_BIT_64(5)
-#define USAGE_STARTVM RT_BIT_64(6)
-#define USAGE_CONTROLVM RT_BIT_64(7)
-#define USAGE_DISCARDSTATE RT_BIT_64(8)
-#define USAGE_SNAPSHOT RT_BIT_64(9)
+#define USAGE_CLONEVM RT_BIT_64(6)
+#define USAGE_STARTVM RT_BIT_64(7)
+#define USAGE_CONTROLVM RT_BIT_64(8)
+#define USAGE_DISCARDSTATE RT_BIT_64(9)
+#define USAGE_SNAPSHOT RT_BIT_64(10)
#define USAGE_CLOSEMEDIUM RT_BIT_64(11)
#define USAGE_SHOWHDINFO RT_BIT_64(12)
#define USAGE_CREATEHD RT_BIT_64(13)
@@ -97,6 +98,7 @@
#define USAGE_PASSWORDHASH RT_BIT_64(54)
#define USAGE_EXTPACK RT_BIT_64(55)
#define USAGE_BANDWIDTHCONTROL RT_BIT_64(56)
+#define USAGE_GUESTSTATS RT_BIT_64(57)
#define USAGE_ALL (~(uint64_t)0)
/** @} */
@@ -162,6 +164,9 @@ int handleInternalCommands(HandlerArg *a);
/* VBoxManageControlVM.cpp */
int handleControlVM(HandlerArg *a);
+#ifndef VBOX_ONLY_DOCS
+unsigned int getMaxNics(IVirtualBox* vbox, IMachine* mach);
+#endif
/* VBoxManageModifyVM.cpp */
int handleModifyVM(HandlerArg *a);
@@ -193,7 +198,7 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
ComPtr<IMachine> machine,
VMINFO_DETAILS details = VMINFO_NONE,
ComPtr <IConsole> console = ComPtr<IConsole>());
-const char *stateToName(MachineState_T machineState, bool fShort);
+const char *machineStateToName(MachineState_T machineState, bool fShort);
/* VBoxManageList.cpp */
int handleList(HandlerArg *a);
@@ -205,6 +210,7 @@ int handleMetrics(HandlerArg *a);
int handleRegisterVM(HandlerArg *a);
int handleUnregisterVM(HandlerArg *a);
int handleCreateVM(HandlerArg *a);
+int handleCloneVM(HandlerArg *a);
int handleStartVM(HandlerArg *a);
int handleDiscardState(HandlerArg *a);
int handleAdoptState(HandlerArg *a);
@@ -220,7 +226,7 @@ HRESULT findMedium(HandlerArg *a, const char *pszFilenameOrUuid,
ComPtr<IMedium> &pMedium);
HRESULT findOrOpenMedium(HandlerArg *a, const char *pszFilenameOrUuid,
DeviceType_T enmDevType, ComPtr<IMedium> &pMedium,
- bool *pfWasUnknown);
+ bool fForceNewUuidOnOpen, bool *pfWasUnknown);
int handleCreateHardDisk(HandlerArg *a);
int handleModifyHardDisk(HandlerArg *a);
int handleCloneHardDisk(HandlerArg *a);
@@ -255,4 +261,3 @@ int handleBandwidthControl(HandlerArg *a);
#endif /* !VBOX_ONLY_DOCS */
#endif /* !___H_VBOXMANAGE */
-
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
index 1c2405719..d49d91fc4 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageAppliance.cpp $ */
+/* $Id: VBoxManageAppliance.cpp 37862 2011-07-11 10:09:29Z vboxsync $ */
/** @file
* VBoxManage - The appliance-related commands.
*/
@@ -76,6 +76,35 @@ static bool findArgValue(Utf8Str &strOut,
return false;
}
+static int parseImportOptions(const char *psz, com::SafeArray<ImportOptions_T> *options)
+{
+ int rc = VINF_SUCCESS;
+ while (psz && *psz && RT_SUCCESS(rc))
+ {
+ size_t len;
+ const char *pszComma = strchr(psz, ',');
+ if (pszComma)
+ len = pszComma - psz;
+ else
+ len = strlen(psz);
+ if (len > 0)
+ {
+ if (!RTStrNICmp(psz, "KeepAllMACs", len))
+ options->push_back(ImportOptions_KeepAllMACs);
+ else if (!RTStrNICmp(psz, "KeepNATMACs", len))
+ options->push_back(ImportOptions_KeepNATMACs);
+ else
+ rc = VERR_PARSE_ERROR;
+ }
+ if (pszComma)
+ psz += len + 1;
+ else
+ psz += len;
+ }
+
+ return rc;
+}
+
static const RTGETOPTDEF g_aImportApplianceOptions[] =
{
{ "--dry-run", 'n', RTGETOPT_REQ_NOTHING },
@@ -111,6 +140,7 @@ static const RTGETOPTDEF g_aImportApplianceOptions[] =
{ "--controller", 'C', RTGETOPT_REQ_STRING },
#endif
{ "--disk", 'D', RTGETOPT_REQ_STRING },
+ { "--options", 'O', RTGETOPT_REQ_STRING },
};
int handleImportAppliance(HandlerArg *arg)
@@ -119,6 +149,7 @@ int handleImportAppliance(HandlerArg *arg)
Utf8Str strOvfFilename;
bool fExecute = true; // if true, then we actually do the import
+ com::SafeArray<ImportOptions_T> options;
uint32_t ulCurVsys = (uint32_t)-1;
uint32_t ulCurUnit = (uint32_t)-1;
// for each --vsys X command, maintain a map of command line items
@@ -222,6 +253,11 @@ int handleImportAppliance(HandlerArg *arg)
mapArgsMapsPerVsys[ulCurVsys][Utf8StrFmt("disk%u", ulCurUnit)] = ValueUnion.psz;
break;
+ case 'O': // --options
+ if (RT_FAILURE(parseImportOptions(ValueUnion.psz, &options)))
+ return errorArgument("Invalid import options '%s'\n", ValueUnion.psz);
+ break;
+
case VINF_GETOPT_NOT_OPTION:
if (strOvfFilename.isEmpty())
strOvfFilename = ValueUnion.psz;
@@ -255,9 +291,9 @@ int handleImportAppliance(HandlerArg *arg)
CHECK_ERROR_BREAK(arg->virtualBox, CreateAppliance(pAppliance.asOutParam()));
char *pszAbsFilePath;
- if (strOvfFilename.startsWith("S3://", iprt::MiniString::CaseInsensitive) ||
- strOvfFilename.startsWith("SunCloud://", iprt::MiniString::CaseInsensitive) ||
- strOvfFilename.startsWith("webdav://", iprt::MiniString::CaseInsensitive))
+ if (strOvfFilename.startsWith("S3://", RTCString::CaseInsensitive) ||
+ strOvfFilename.startsWith("SunCloud://", RTCString::CaseInsensitive) ||
+ strOvfFilename.startsWith("webdav://", RTCString::CaseInsensitive))
pszAbsFilePath = RTStrDup(strOvfFilename.c_str());
else
pszAbsFilePath = RTPathAbsDup(strOvfFilename.c_str());
@@ -746,7 +782,7 @@ int handleImportAppliance(HandlerArg *arg)
// go!
ComPtr<IProgress> progress;
CHECK_ERROR_BREAK(pAppliance,
- ImportMachines(progress.asOutParam()));
+ ImportMachines(ComSafeArrayAsInParam(options), progress.asOutParam()));
rc = showProgress(progress);
@@ -927,9 +963,9 @@ int handleExportAppliance(HandlerArg *a)
CHECK_ERROR_BREAK(a->virtualBox, CreateAppliance(pAppliance.asOutParam()));
char *pszAbsFilePath = 0;
- if (strOutputFile.startsWith("S3://", iprt::MiniString::CaseInsensitive) ||
- strOutputFile.startsWith("SunCloud://", iprt::MiniString::CaseInsensitive) ||
- strOutputFile.startsWith("webdav://", iprt::MiniString::CaseInsensitive))
+ if (strOutputFile.startsWith("S3://", RTCString::CaseInsensitive) ||
+ strOutputFile.startsWith("SunCloud://", RTCString::CaseInsensitive) ||
+ strOutputFile.startsWith("webdav://", RTCString::CaseInsensitive))
pszAbsFilePath = RTStrDup(strOutputFile.c_str());
else
pszAbsFilePath = RTPathAbsDup(strOutputFile.c_str());
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp
index 363b8c8c5..a12174045 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageBandwidthControl.cpp $ */
+/* $Id: VBoxManageBandwidthControl.cpp 34587 2010-12-01 20:30:02Z vboxsync $ */
/** @file
* VBoxManage - The bandwidth control related commands.
*/
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp
index 45f0aa3c0..ceb1d7cf5 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageControlVM.cpp $ */
+/* $Id: VBoxManageControlVM.cpp 37202 2011-05-24 15:57:55Z vboxsync $ */
/** @file
* VBoxManage - Implementation of the controlvm command.
*/
@@ -64,6 +64,24 @@ static unsigned parseNum(const char *psz, unsigned cMaxNum, const char *name)
return 0;
}
+unsigned int getMaxNics(IVirtualBox* vbox, IMachine* mach)
+{
+ ComPtr <ISystemProperties> info;
+ ChipsetType_T aChipset;
+ ULONG NetworkAdapterCount = 0;
+ HRESULT rc;
+
+ do {
+ CHECK_ERROR_BREAK(vbox, COMGETTER(SystemProperties)(info.asOutParam()));
+ CHECK_ERROR_BREAK(mach, COMGETTER(ChipsetType)(&aChipset));
+ CHECK_ERROR_BREAK(info, GetMaxNetworkAdapters(aChipset, &NetworkAdapterCount));
+
+ return (unsigned int)NetworkAdapterCount;
+ } while (0);
+
+ return 0;
+}
+
int handleControlVM(HandlerArg *a)
{
@@ -173,7 +191,7 @@ int handleControlVM(HandlerArg *a)
if (machineState != MachineState_Paused)
{
RTMsgError("Machine in invalid state %d -- %s\n",
- machineState, stateToName(machineState, false));
+ machineState, machineStateToName(machineState, false));
break;
}
}
@@ -265,10 +283,7 @@ int handleControlVM(HandlerArg *a)
else if (!strncmp(a->argv[1], "setlinkstate", 12))
{
/* Get the number of network adapters */
- ULONG NetworkAdapterCount = 0;
- ComPtr <ISystemProperties> info;
- CHECK_ERROR_BREAK(a->virtualBox, COMGETTER(SystemProperties)(info.asOutParam()));
- CHECK_ERROR_BREAK(info, COMGETTER(NetworkAdapterCount)(&NetworkAdapterCount));
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, sessionMachine);
unsigned n = parseNum(&a->argv[1][12], NetworkAdapterCount, "NIC");
if (!n)
@@ -311,11 +326,7 @@ int handleControlVM(HandlerArg *a)
else if (!strncmp(a->argv[1], "nictracefile", 12))
{
/* Get the number of network adapters */
- ULONG NetworkAdapterCount = 0;
- ComPtr <ISystemProperties> info;
- CHECK_ERROR_BREAK(a->virtualBox, COMGETTER(SystemProperties)(info.asOutParam()));
- CHECK_ERROR_BREAK(info, COMGETTER(NetworkAdapterCount)(&NetworkAdapterCount));
-
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, sessionMachine);
unsigned n = parseNum(&a->argv[1][12], NetworkAdapterCount, "NIC");
if (!n)
{
@@ -350,16 +361,13 @@ int handleControlVM(HandlerArg *a)
}
}
else
- RTMsgError("The NIC %d is currently disabled and thus can't change its tracefile", n);
+ RTMsgError("The NIC %d is currently disabled and thus its tracefile can't be changed", n);
}
}
else if (!strncmp(a->argv[1], "nictrace", 8))
{
/* Get the number of network adapters */
- ULONG NetworkAdapterCount = 0;
- ComPtr <ISystemProperties> info;
- CHECK_ERROR_BREAK(a->virtualBox, COMGETTER(SystemProperties)(info.asOutParam()));
- CHECK_ERROR_BREAK(info, COMGETTER(NetworkAdapterCount)(&NetworkAdapterCount));
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, sessionMachine);
unsigned n = parseNum(&a->argv[1][8], NetworkAdapterCount, "NIC");
if (!n)
@@ -399,18 +407,15 @@ int handleControlVM(HandlerArg *a)
}
}
else
- RTMsgError("The NIC %d is currently disabled and thus can't change its trace flag", n);
+ RTMsgError("The NIC %d is currently disabled and thus its trace flag can't be changed", n);
}
}
else if( a->argc > 2
&& !strncmp(a->argv[1], "natpf", 5))
{
/* Get the number of network adapters */
- ULONG NetworkAdapterCount = 0;
- ComPtr <ISystemProperties> info;
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, sessionMachine);
ComPtr<INATEngine> engine;
- CHECK_ERROR_BREAK(a->virtualBox, COMGETTER(SystemProperties)(info.asOutParam()));
- CHECK_ERROR_BREAK(info, COMGETTER(NetworkAdapterCount)(&NetworkAdapterCount));
unsigned n = parseNum(&a->argv[1][5], NetworkAdapterCount, "NIC");
if (!n)
{
@@ -500,14 +505,68 @@ int handleControlVM(HandlerArg *a)
if (SUCCEEDED(rc))
CHECK_ERROR(sessionMachine, SaveSettings());
}
- else if (!strncmp(a->argv[1], "nic", 3))
+ else if (!strncmp(a->argv[1], "nicproperty", 11))
{
/* Get the number of network adapters */
- ULONG NetworkAdapterCount = 0;
- ComPtr <ISystemProperties> info;
- CHECK_ERROR_BREAK(a->virtualBox, COMGETTER(SystemProperties)(info.asOutParam()));
- CHECK_ERROR_BREAK(info, COMGETTER(NetworkAdapterCount)(&NetworkAdapterCount));
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox,sessionMachine) ;
+ unsigned n = parseNum(&a->argv[1][11], NetworkAdapterCount, "NIC");
+ if (!n)
+ {
+ rc = E_FAIL;
+ break;
+ }
+ if (a->argc <= 2)
+ {
+ errorArgument("Missing argument to '%s'", a->argv[1]);
+ rc = E_FAIL;
+ break;
+ }
+
+ /* get the corresponding network adapter */
+ ComPtr<INetworkAdapter> adapter;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
+ if (adapter)
+ {
+ BOOL fEnabled;
+ adapter->COMGETTER(Enabled)(&fEnabled);
+ if (fEnabled)
+ {
+ /* Parse 'name=value' */
+ char *pszProperty = RTStrDup(a->argv[2]);
+ if (pszProperty)
+ {
+ char *pDelimiter = strchr(pszProperty, '=');
+ if (pDelimiter)
+ {
+ *pDelimiter = '\0';
+ Bstr bstrName = pszProperty;
+ Bstr bstrValue = &pDelimiter[1];
+ CHECK_ERROR(adapter, SetProperty(bstrName.raw(), bstrValue.raw()));
+ }
+ else
+ {
+ errorArgument("Invalid nicproperty%d argument '%s'", n, a->argv[2]);
+ rc = E_FAIL;
+ }
+ RTStrFree(pszProperty);
+ }
+ else
+ {
+ RTStrmPrintf(g_pStdErr, "Error: Failed to allocate memory for nicproperty%d '%s'\n", n, a->argv[2]);
+ rc = E_FAIL;
+ }
+ if (FAILED(rc))
+ break;
+ }
+ else
+ RTMsgError("The NIC %d is currently disabled and thus its properties can't be changed", n);
+ }
+ }
+ else if (!strncmp(a->argv[1], "nic", 3))
+ {
+ /* Get the number of network adapters */
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox,sessionMachine) ;
unsigned n = parseNum(&a->argv[1][3], NetworkAdapterCount, "NIC");
if (!n)
{
@@ -533,14 +592,14 @@ int handleControlVM(HandlerArg *a)
if (!strcmp(a->argv[2], "null"))
{
CHECK_ERROR_RET(adapter, COMSETTER(Enabled)(TRUE), 1);
- CHECK_ERROR_RET(adapter, Detach(), 1);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_Null), 1);
}
else if (!strcmp(a->argv[2], "nat"))
{
CHECK_ERROR_RET(adapter, COMSETTER(Enabled)(TRUE), 1);
if (a->argc == 4)
CHECK_ERROR_RET(adapter, COMSETTER(NATNetwork)(Bstr(a->argv[3]).raw()), 1);
- CHECK_ERROR_RET(adapter, AttachToNAT(), 1);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_NAT), 1);
}
else if ( !strcmp(a->argv[2], "bridged")
|| !strcmp(a->argv[2], "hostif")) /* backward compatibility */
@@ -552,8 +611,8 @@ int handleControlVM(HandlerArg *a)
break;
}
CHECK_ERROR_RET(adapter, COMSETTER(Enabled)(TRUE), 1);
- CHECK_ERROR_RET(adapter, COMSETTER(HostInterface)(Bstr(a->argv[3]).raw()), 1);
- CHECK_ERROR_RET(adapter, AttachToBridgedInterface(), 1);
+ CHECK_ERROR_RET(adapter, COMSETTER(BridgedInterface)(Bstr(a->argv[3]).raw()), 1);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_Bridged), 1);
}
else if (!strcmp(a->argv[2], "intnet"))
{
@@ -565,7 +624,7 @@ int handleControlVM(HandlerArg *a)
}
CHECK_ERROR_RET(adapter, COMSETTER(Enabled)(TRUE), 1);
CHECK_ERROR_RET(adapter, COMSETTER(InternalNetwork)(Bstr(a->argv[3]).raw()), 1);
- CHECK_ERROR_RET(adapter, AttachToInternalNetwork(), 1);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_Internal), 1);
}
#if defined(VBOX_WITH_NETFLT)
else if (!strcmp(a->argv[2], "hostonly"))
@@ -577,10 +636,35 @@ int handleControlVM(HandlerArg *a)
break;
}
CHECK_ERROR_RET(adapter, COMSETTER(Enabled)(TRUE), 1);
- CHECK_ERROR_RET(adapter, COMSETTER(HostInterface)(Bstr(a->argv[3]).raw()), 1);
- CHECK_ERROR_RET(adapter, AttachToHostOnlyInterface(), 1);
+ CHECK_ERROR_RET(adapter, COMSETTER(HostOnlyInterface)(Bstr(a->argv[3]).raw()), 1);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_HostOnly), 1);
}
#endif
+ else if (!strcmp(a->argv[2], "generic"))
+ {
+ if (a->argc <= 3)
+ {
+ errorArgument("Missing argument to '%s'", a->argv[2]);
+ rc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_RET(adapter, COMSETTER(Enabled)(TRUE), 1);
+ CHECK_ERROR_RET(adapter, COMSETTER(GenericDriver)(Bstr(a->argv[3]).raw()), 1);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_Generic), 1);
+ }
+ /** @todo obsolete, remove eventually */
+ else if (!strcmp(a->argv[2], "vde"))
+ {
+ if (a->argc <= 3)
+ {
+ errorArgument("Missing argument to '%s'", a->argv[2]);
+ rc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_RET(adapter, COMSETTER(Enabled)(TRUE), 1);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_Generic), 1);
+ CHECK_ERROR_RET(adapter, SetProperty(Bstr("name").raw(), Bstr(a->argv[3]).raw()), 1);
+ }
else
{
errorArgument("Invalid type '%s' specfied for NIC %lu", Utf8Str(a->argv[2]).c_str(), n);
@@ -589,7 +673,7 @@ int handleControlVM(HandlerArg *a)
}
}
else
- RTMsgError("The NIC %d is currently disabled and thus can't change its attachment type", n);
+ RTMsgError("The NIC %d is currently disabled and thus its attachment type can't be changed", n);
}
}
else if ( !strcmp(a->argv[1], "vrde")
@@ -703,9 +787,8 @@ int handleControlVM(HandlerArg *a)
}
else
{
- errorArgument("Invalid --vrdeproperty argument '%s'", a->argv[2]);
+ errorArgument("Invalid vrdeproperty argument '%s'", a->argv[2]);
rc = E_FAIL;
- break;
}
RTStrFree(pszProperty);
}
@@ -1077,4 +1160,3 @@ int handleControlVM(HandlerArg *a)
return SUCCEEDED(rc) ? 0 : 1;
}
-
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp
index 68ef44fc3..958cd774a 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageDHCPServer.cpp $ */
+/* $Id: VBoxManageDHCPServer.cpp 33489 2010-10-27 10:31:41Z vboxsync $ */
/** @file
* VBoxManage - Implementation of dhcpserver command.
*/
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp
index 6b1e46305..1d8dd9fdb 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageDebugVM.cpp $ */
+/* $Id: VBoxManageDebugVM.cpp 35550 2011-01-13 18:08:54Z vboxsync $ */
/** @file
* VBoxManage - Implementation of the debugvm command.
*/
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
index 74e425969..5c6fce980 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxManageDisk.cpp $ */
+/* $Id: VBoxManageDisk.cpp 37525 2011-06-17 10:09:21Z vboxsync $ */
/** @file
* VBoxManage - The disk related commands.
*/
/*
- * 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;
@@ -180,7 +180,7 @@ HRESULT findMedium(HandlerArg *a, const char *pszFilenameOrUuid,
HRESULT findOrOpenMedium(HandlerArg *a, const char *pszFilenameOrUuid,
DeviceType_T enmDevType, ComPtr<IMedium> &pMedium,
- bool *pfWasUnknown)
+ bool fForceNewUuidOnOpen, bool *pfWasUnknown)
{
HRESULT rc;
bool fWasUnknown = false;
@@ -206,6 +206,7 @@ HRESULT findOrOpenMedium(HandlerArg *a, const char *pszFilenameOrUuid,
{
CHECK_ERROR(a->virtualBox, OpenMedium(Bstr(pszFilenameOrUuid).raw(),
enmDevType, AccessMode_ReadWrite,
+ fForceNewUuidOnOpen,
pMedium.asOutParam()));
if (SUCCEEDED(rc))
fWasUnknown = true;
@@ -335,9 +336,9 @@ int handleCreateHardDisk(HandlerArg *a)
if (!RTPathHaveExt(strName.c_str()))
{
Utf8Str strFormat(format);
- if (strFormat.compare("vmdk", iprt::MiniString::CaseInsensitive) == 0)
+ if (strFormat.compare("vmdk", RTCString::CaseInsensitive) == 0)
strName.append(".vmdk");
- else if (strFormat.compare("vhd", iprt::MiniString::CaseInsensitive) == 0)
+ else if (strFormat.compare("vhd", RTCString::CaseInsensitive) == 0)
strName.append(".vhd");
else
strName.append(".vdi");
@@ -475,7 +476,7 @@ int handleModifyHardDisk(HandlerArg *a)
rc = findMedium(a, FilenameOrUuid, DeviceType_HardDisk, false /* fSilent */, hardDisk);
else
rc = findOrOpenMedium(a, FilenameOrUuid, DeviceType_HardDisk,
- hardDisk, &unknown);
+ hardDisk, false /* fForceNewUuidOnOpen */, &unknown);
if (FAILED(rc))
return 1;
if (hardDisk.isNull())
@@ -629,7 +630,8 @@ int handleCloneHardDisk(HandlerArg *a)
bool fSrcUnknown = false;
bool fDstUnknown = false;
- rc = findOrOpenMedium(a, pszSrc, DeviceType_HardDisk, srcDisk, &fSrcUnknown);
+ rc = findOrOpenMedium(a, pszSrc, DeviceType_HardDisk, srcDisk,
+ false /* fForceNewUuidOnOpen */, &fSrcUnknown);
if (FAILED(rc))
return 1;
@@ -638,7 +640,8 @@ int handleCloneHardDisk(HandlerArg *a)
/* open/create destination hard disk */
if (fExisting)
{
- rc = findOrOpenMedium(a, pszDst, DeviceType_HardDisk, dstDisk, &fDstUnknown);
+ rc = findOrOpenMedium(a, pszDst, DeviceType_HardDisk, dstDisk,
+ false /* fForceNewUuidOnOpen */, &fDstUnknown);
if (FAILED(rc))
break;
@@ -924,7 +927,8 @@ int handleShowHardDiskInfo(HandlerArg *a)
ComPtr<IMedium> hardDisk;
bool unknown = false;
- rc = findOrOpenMedium(a, FilenameOrUuid, DeviceType_HardDisk, hardDisk, &unknown);
+ rc = findOrOpenMedium(a, FilenameOrUuid, DeviceType_HardDisk, hardDisk,
+ false /* fForceNewUuidOnOpen */, &unknown);
if (FAILED(rc))
return 1;
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
index c42129fba..96d5e00dc 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxManageGuestCtrl.cpp $ */
+/* $Id: VBoxManageGuestCtrl.cpp 37761 2011-07-04 12:22:02Z vboxsync $ */
/** @file
* VBoxManage - Implementation of guestcontrol command.
*/
/*
- * 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;
@@ -28,11 +28,11 @@
#include <VBox/com/array.h>
#include <VBox/com/ErrorInfo.h>
#include <VBox/com/errorprint.h>
-
#include <VBox/com/VirtualBox.h>
#include <VBox/com/EventQueue.h>
-#include <VBox/HostServices/GuestControlSvc.h> /* for PROC_STS_XXX */
+#include <VBox/err.h>
+#include <VBox/log.h>
#include <iprt/asm.h>
#include <iprt/dir.h>
@@ -43,6 +43,9 @@
#include <iprt/path.h>
#include <iprt/thread.h>
+#include <map>
+#include <vector>
+
#ifdef USE_XPCOM_QUEUE
# include <sys/select.h>
# include <errno.h>
@@ -65,42 +68,148 @@ using namespace com;
/** Set by the signal handler. */
static volatile bool g_fGuestCtrlCanceled = false;
+/**
+ * An entry for a source element, including an optional filter.
+ */
+typedef struct SOURCEFILEENTRY
+{
+ SOURCEFILEENTRY(const char *pszSource, const char *pszFilter)
+ : mSource(pszSource),
+ mFilter(pszFilter) {}
+ SOURCEFILEENTRY(const char *pszSource)
+ : mSource(pszSource)
+ {
+ if ( !RTFileExists(pszSource)
+ && !RTDirExists(pszSource))
+ {
+ /* No file and no directory -- maybe a filter? */
+ if (NULL != strpbrk(RTPathFilename(pszSource), "*?"))
+ {
+ /* Yep, get the actual filter part. */
+ mFilter = RTPathFilename(pszSource);
+ /* Remove the filter from actual sourcec directory name. */
+ RTPathStripFilename(mSource.mutableRaw());
+ mSource.jolt();
+ }
+ }
+ }
+ Utf8Str mSource;
+ Utf8Str mFilter;
+} SOURCEFILEENTRY, *PSOURCEFILEENTRY;
+typedef std::vector<SOURCEFILEENTRY> SOURCEVEC, *PSOURCEVEC;
+
+/**
+ * An entry for an element which needs to be copied to the guest.
+ */
+typedef struct DESTFILEENTRY
+{
+ DESTFILEENTRY(Utf8Str strFileName) : mFileName(strFileName) {}
+ Utf8Str mFileName;
+} DESTFILEENTRY, *PDESTFILEENTRY;
/*
- * Structure holding a directory entry.
+ * Map for holding destination entires, whereas the key is the destination
+ * directory and the mapped value is a vector holding all elements for this directoy.
*/
-typedef struct DIRECTORYENTRY
+typedef std::map< Utf8Str, std::vector<DESTFILEENTRY> > DESTDIRMAP, *PDESTDIRMAP;
+typedef std::map< Utf8Str, std::vector<DESTFILEENTRY> >::iterator DESTDIRMAPITER, *PDESTDIRMAPITER;
+
+/**
+ * Special exit codes for returning errors/information of a
+ * started guest process to the command line VBoxManage was started from.
+ * Useful for e.g. scripting.
+ *
+ * @note These are frozen as of 4.1.0.
+ */
+enum EXITCODEEXEC
{
- char *pszSourcePath;
- char *pszDestPath;
- RTLISTNODE Node;
-} DIRECTORYENTRY, *PDIRECTORYENTRY;
+ EXITCODEEXEC_SUCCESS = RTEXITCODE_SUCCESS,
+ /* Process exited normally but with an exit code <> 0. */
+ EXITCODEEXEC_CODE = 16,
+ EXITCODEEXEC_FAILED = 17,
+ EXITCODEEXEC_TERM_SIGNAL = 18,
+ EXITCODEEXEC_TERM_ABEND = 19,
+ EXITCODEEXEC_TIMEOUT = 20,
+ EXITCODEEXEC_DOWN = 21,
+ EXITCODEEXEC_CANCELED = 22
+};
+
+/**
+ * RTGetOpt-IDs for the guest execution control command line.
+ */
+enum GETOPTDEF_EXEC
+{
+ GETOPTDEF_EXEC_IGNOREORPHANEDPROCESSES = 1000,
+ GETOPTDEF_EXEC_NO_PROFILE,
+ GETOPTDEF_EXEC_OUTPUTFORMAT,
+ GETOPTDEF_EXEC_DOS2UNIX,
+ GETOPTDEF_EXEC_UNIX2DOS,
+ GETOPTDEF_EXEC_WAITFOREXIT,
+ GETOPTDEF_EXEC_WAITFORSTDOUT,
+ GETOPTDEF_EXEC_WAITFORSTDERR
+};
+
+enum GETOPTDEF_COPYFROM
+{
+ GETOPTDEF_COPYFROM_DRYRUN = 1000,
+ GETOPTDEF_COPYFROM_FOLLOW,
+ GETOPTDEF_COPYFROM_PASSWORD,
+ GETOPTDEF_COPYFROM_TARGETDIR,
+ GETOPTDEF_COPYFROM_USERNAME
+};
+
+enum GETOPTDEF_COPYTO
+{
+ GETOPTDEF_COPYTO_DRYRUN = 1000,
+ GETOPTDEF_COPYTO_FOLLOW,
+ GETOPTDEF_COPYTO_PASSWORD,
+ GETOPTDEF_COPYTO_TARGETDIR,
+ GETOPTDEF_COPYTO_USERNAME
+};
+
+enum OUTPUTTYPE
+{
+ OUTPUTTYPE_UNDEFINED = 0,
+ OUTPUTTYPE_DOS2UNIX = 10,
+ OUTPUTTYPE_UNIX2DOS = 20
+};
#endif /* VBOX_ONLY_DOCS */
void usageGuestControl(PRTSTREAM pStrm)
{
RTStrmPrintf(pStrm,
- "VBoxManage guestcontrol exec[ute] <vmname>|<uuid>\n"
- " <path to program>\n"
+ "VBoxManage guestcontrol <vmname>|<uuid>\n"
+ " exec[ute]\n"
+ " --image <path to program>\n"
" --username <name> --password <password>\n"
- " [--arguments \"<arguments>\"]\n"
+ " [--dos2unix]\n"
" [--environment \"<NAME>=<VALUE> [<NAME>=<VALUE>]\"]\n"
- " [--flags <flags>] [--timeout <msec>]\n"
- " [--verbose] [--wait-for exit,stdout,stderr||]\n"
+ " [--timeout <msec>] [--unix2dos] [--verbose]\n"
+ " [--wait-exit] [--wait-stdout] [--wait-stderr]\n"
+ //" [--output-format=<dos>|<unix>]\n"
+ " [--output-type=<binary>|<text>]\n"
+ " [-- [<argument1>] ... [<argumentN>]]\n"
/** @todo Add a "--" parameter (has to be last parameter) to directly execute
* stuff, e.g. "VBoxManage guestcontrol execute <VMName> --username <> ... -- /bin/rm -Rf /foo". */
"\n"
- " copyto|cp <vmname>|<uuid>\n"
+#if 0
+ " copyfrom\n"
+ " <source on guest> <destination on host>\n"
+ " --username <name> --password <password>\n"
+ " [--dryrun] [--follow] [--recursive] [--verbose]\n"
+ "\n"
+#endif
+ " copyto|cp\n"
" <source on host> <destination on guest>\n"
" --username <name> --password <password>\n"
" [--dryrun] [--follow] [--recursive] [--verbose]\n"
"\n"
- " createdir[ectory]|mkdir|md <vmname>|<uuid>\n"
+ " createdir[ectory]|mkdir|md\n"
" <directory to create on guest>\n"
" --username <name> --password <password>\n"
" [--parents] [--mode <mode>] [--verbose]\n"
"\n"
- " updateadditions <vmname>|<uuid>\n"
+ " updateadditions\n"
" [--source <guest additions .ISO>] [--verbose]\n"
"\n");
}
@@ -147,29 +256,68 @@ static void ctrlSignalHandlerUninstall()
* Translates a process status to a human readable
* string.
*/
-static const char *ctrlExecGetStatus(ULONG uStatus)
+static const char *ctrlExecProcessStatusToText(ExecuteProcessStatus_T enmStatus)
{
- switch (uStatus)
+ switch (enmStatus)
{
- case guestControl::PROC_STS_STARTED:
+ case ExecuteProcessStatus_Started:
return "started";
- case guestControl::PROC_STS_TEN:
+ case ExecuteProcessStatus_TerminatedNormally:
return "successfully terminated";
- case guestControl::PROC_STS_TES:
+ case ExecuteProcessStatus_TerminatedSignal:
return "terminated by signal";
- case guestControl::PROC_STS_TEA:
+ case ExecuteProcessStatus_TerminatedAbnormally:
return "abnormally aborted";
- case guestControl::PROC_STS_TOK:
+ case ExecuteProcessStatus_TimedOutKilled:
return "timed out";
- case guestControl::PROC_STS_TOA:
+ case ExecuteProcessStatus_TimedOutAbnormally:
return "timed out, hanging";
- case guestControl::PROC_STS_DWN:
+ case ExecuteProcessStatus_Down:
return "killed";
- case guestControl::PROC_STS_ERROR:
+ case ExecuteProcessStatus_Error:
return "error";
default:
- return "unknown";
+ break;
+ }
+ return "unknown";
+}
+
+static int ctrlExecProcessStatusToExitCode(ExecuteProcessStatus_T enmStatus, ULONG uExitCode)
+{
+ int rc = EXITCODEEXEC_SUCCESS;
+ switch (enmStatus)
+ {
+ case ExecuteProcessStatus_Started:
+ rc = EXITCODEEXEC_SUCCESS;
+ break;
+ case ExecuteProcessStatus_TerminatedNormally:
+ rc = !uExitCode ? EXITCODEEXEC_SUCCESS : EXITCODEEXEC_CODE;
+ break;
+ case ExecuteProcessStatus_TerminatedSignal:
+ rc = EXITCODEEXEC_TERM_SIGNAL;
+ break;
+ case ExecuteProcessStatus_TerminatedAbnormally:
+ rc = EXITCODEEXEC_TERM_ABEND;
+ break;
+ case ExecuteProcessStatus_TimedOutKilled:
+ rc = EXITCODEEXEC_TIMEOUT;
+ break;
+ case ExecuteProcessStatus_TimedOutAbnormally:
+ rc = EXITCODEEXEC_TIMEOUT;
+ break;
+ case ExecuteProcessStatus_Down:
+ /* Service/OS is stopping, process was killed, so
+ * not exactly an error of the started process ... */
+ rc = EXITCODEEXEC_DOWN;
+ break;
+ case ExecuteProcessStatus_Error:
+ rc = EXITCODEEXEC_FAILED;
+ break;
+ default:
+ AssertMsgFailed(("Unknown exit code (%u) from guest process returned!\n", enmStatus));
+ break;
}
+ return rc;
}
static int ctrlPrintError(com::ErrorInfo &errorInfo)
@@ -198,7 +346,6 @@ static int ctrlPrintError(IUnknown *pObj, const GUID &aIID)
return ctrlPrintError(ErrInfo);
}
-
static int ctrlPrintProgressError(ComPtr<IProgress> progress)
{
int rc;
@@ -227,14 +374,15 @@ static void ctrlUninitVM(HandlerArg *pArg)
}
/**
- * Initializes the VM, that is checks whether it's up and
- * running, if it can be locked (shared only) and returns a
- * valid IGuest pointer on success.
+ * Initializes the VM for IGuest operations.
+ *
+ * That is, checks whether it's up and running, if it can be locked (shared
+ * only) and returns a valid IGuest pointer on success.
*
* @return IPRT status code.
* @param pArg Our command line argument structure.
- * @param pszNameOrId The VM's name or UUID to use.
- * @param pGuest Pointer where to store the IGuest interface.
+ * @param pszNameOrId The VM's name or UUID.
+ * @param pGuest Where to return the IGuest interface pointer.
*/
static int ctrlInitVM(HandlerArg *pArg, const char *pszNameOrId, ComPtr<IGuest> *pGuest)
{
@@ -256,7 +404,7 @@ static int ctrlInitVM(HandlerArg *pArg, const char *pszNameOrId, ComPtr<IGuest>
if (machineState != MachineState_Running)
{
RTMsgError("Machine \"%s\" is not running (currently %s)!\n",
- pszNameOrId, stateToName(machineState, false));
+ pszNameOrId, machineStateToName(machineState, false));
return VERR_VM_INVALID_VM_STATE;
}
@@ -279,68 +427,66 @@ static int ctrlInitVM(HandlerArg *pArg, const char *pszNameOrId, ComPtr<IGuest>
return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
}
-static int handleCtrlExecProgram(HandlerArg *a)
+/* <Missing docuemntation> */
+static int handleCtrlExecProgram(ComPtr<IGuest> guest, HandlerArg *pArg)
{
+ AssertPtrReturn(pArg, VERR_INVALID_PARAMETER);
+
/*
- * Check the syntax. We can deduce the correct syntax from the number of
- * arguments.
+ * Parse arguments.
*/
- if (a->argc < 2) /* At least the command we want to execute in the guest should be present :-). */
+ if (pArg->argc < 2) /* At least the command we want to execute in the guest should be present :-). */
return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters");
static const RTGETOPTDEF s_aOptions[] =
{
- { "--arguments", 'a', RTGETOPT_REQ_STRING },
- { "--environment", 'e', RTGETOPT_REQ_STRING },
- { "--flags", 'f', RTGETOPT_REQ_STRING },
- { "--password", 'p', RTGETOPT_REQ_STRING },
- { "--timeout", 't', RTGETOPT_REQ_UINT32 },
- { "--username", 'u', RTGETOPT_REQ_STRING },
- { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
- { "--wait-for", 'w', RTGETOPT_REQ_STRING }
+ { "--dos2unix", GETOPTDEF_EXEC_DOS2UNIX, RTGETOPT_REQ_NOTHING },
+ { "--environment", 'e', RTGETOPT_REQ_STRING },
+ { "--flags", 'f', RTGETOPT_REQ_STRING },
+ { "--ignore-operhaned-processes", GETOPTDEF_EXEC_IGNOREORPHANEDPROCESSES, RTGETOPT_REQ_NOTHING },
+ { "--image", 'i', RTGETOPT_REQ_STRING },
+ { "--no-profile", GETOPTDEF_EXEC_NO_PROFILE, RTGETOPT_REQ_NOTHING },
+ { "--password", 'p', RTGETOPT_REQ_STRING },
+ { "--timeout", 't', RTGETOPT_REQ_UINT32 },
+ { "--unix2dos", GETOPTDEF_EXEC_UNIX2DOS, RTGETOPT_REQ_NOTHING },
+ { "--username", 'u', RTGETOPT_REQ_STRING },
+ { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
+ { "--wait-exit", GETOPTDEF_EXEC_WAITFOREXIT, RTGETOPT_REQ_NOTHING },
+ { "--wait-stdout", GETOPTDEF_EXEC_WAITFORSTDOUT, RTGETOPT_REQ_NOTHING },
+ { "--wait-stderr", GETOPTDEF_EXEC_WAITFORSTDERR, RTGETOPT_REQ_NOTHING }
};
- int ch;
- RTGETOPTUNION ValueUnion;
- RTGETOPTSTATE GetState;
- RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, pArg->argc, pArg->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
- Utf8Str Utf8Cmd;
- uint32_t uFlags = 0;
- /* Note: this uses IN_BSTR as it must be BSTR on COM and CBSTR on XPCOM */
+ Utf8Str Utf8Cmd;
+ uint32_t fExecFlags = ExecuteProcessFlag_None;
+ uint32_t fOutputFlags = ProcessOutputFlag_None;
com::SafeArray<IN_BSTR> args;
com::SafeArray<IN_BSTR> env;
- Utf8Str Utf8UserName;
- Utf8Str Utf8Password;
- uint32_t u32TimeoutMS = 0;
- bool fWaitForExit = false;
- bool fWaitForStdOut = false;
- bool fWaitForStdErr = false;
- bool fVerbose = false;
-
- int vrc = VINF_SUCCESS;
- bool fUsageOK = true;
+ Utf8Str Utf8UserName;
+ Utf8Str Utf8Password;
+ uint32_t cMsTimeout = 0;
+ OUTPUTTYPE eOutputType = OUTPUTTYPE_UNDEFINED;
+ bool fOutputBinary = false;
+ bool fWaitForExit = false;
+ bool fWaitForStdOut = false;
+ bool fVerbose = false;
+
+ int vrc = VINF_SUCCESS;
while ( (ch = RTGetOpt(&GetState, &ValueUnion))
&& RT_SUCCESS(vrc))
{
/* For options that require an argument, ValueUnion has received the value. */
switch (ch)
{
- case 'a': /* Arguments */
- {
- char **papszArg;
- int cArgs;
-
- vrc = RTGetOptArgvFromString(&papszArg, &cArgs, ValueUnion.psz, NULL);
- if (RT_SUCCESS(vrc))
- {
- for (int j = 0; j < cArgs; j++)
- args.push_back(Bstr(papszArg[j]).raw());
-
- RTGetOptArgvFree(papszArg);
- }
+ case GETOPTDEF_EXEC_DOS2UNIX:
+ if (eOutputType != OUTPUTTYPE_UNDEFINED)
+ return errorSyntax(USAGE_GUESTCONTROL, "More than one output type (dos2unix/unix2dos) specified!");
+ eOutputType = OUTPUTTYPE_DOS2UNIX;
break;
- }
case 'e': /* Environment */
{
@@ -348,33 +494,41 @@ static int handleCtrlExecProgram(HandlerArg *a)
int cArgs;
vrc = RTGetOptArgvFromString(&papszArg, &cArgs, ValueUnion.psz, NULL);
- if (RT_SUCCESS(vrc))
- {
- for (int j = 0; j < cArgs; j++)
- env.push_back(Bstr(papszArg[j]).raw());
+ if (RT_FAILURE(vrc))
+ return errorSyntax(USAGE_GUESTCONTROL, "Failed to parse environment value, rc=%Rrc", vrc);
+ for (int j = 0; j < cArgs; j++)
+ env.push_back(Bstr(papszArg[j]).raw());
- RTGetOptArgvFree(papszArg);
- }
+ RTGetOptArgvFree(papszArg);
break;
}
- case 'f': /* Flags */
- /** @todo Needs a bit better processing as soon as we have more flags. */
- /** @todo Add a hidden flag. */
- if (!RTStrICmp(ValueUnion.psz, "ignoreorphanedprocesses"))
- uFlags |= ExecuteProcessFlag_IgnoreOrphanedProcesses;
- else if (!RTStrICmp(ValueUnion.psz, "noprofile"))
- uFlags |= ExecuteProcessFlag_NoProfile;
- else
- fUsageOK = false;
+ case GETOPTDEF_EXEC_IGNOREORPHANEDPROCESSES:
+ fExecFlags |= ExecuteProcessFlag_IgnoreOrphanedProcesses;
+ break;
+
+ case GETOPTDEF_EXEC_NO_PROFILE:
+ fExecFlags |= ExecuteProcessFlag_NoProfile;
+ break;
+
+ case 'i':
+ Utf8Cmd = ValueUnion.psz;
break;
+ /** @todo Add a hidden flag. */
+
case 'p': /* Password */
Utf8Password = ValueUnion.psz;
break;
case 't': /* Timeout */
- u32TimeoutMS = ValueUnion.u32;
+ cMsTimeout = ValueUnion.u32;
+ break;
+
+ case GETOPTDEF_EXEC_UNIX2DOS:
+ if (eOutputType != OUTPUTTYPE_UNDEFINED)
+ return errorSyntax(USAGE_GUESTCONTROL, "More than one output type (dos2unix/unix2dos) specified!");
+ eOutputType = OUTPUTTYPE_UNIX2DOS;
break;
case 'u': /* User name */
@@ -385,30 +539,21 @@ static int handleCtrlExecProgram(HandlerArg *a)
fVerbose = true;
break;
- case 'w': /* Wait for ... */
- {
- if (!RTStrICmp(ValueUnion.psz, "exit"))
- fWaitForExit = true;
- else if (!RTStrICmp(ValueUnion.psz, "stdout"))
- {
- fWaitForExit = true;
- fWaitForStdOut = true;
- }
- else if (!RTStrICmp(ValueUnion.psz, "stderr"))
- {
- fWaitForExit = true;
- fWaitForStdErr = true;
- }
- else
- fUsageOK = false;
+ case GETOPTDEF_EXEC_WAITFOREXIT:
+ fWaitForExit = true;
+ break;
+
+ case GETOPTDEF_EXEC_WAITFORSTDOUT:
+ fWaitForExit = true;
+ fWaitForStdOut = true;
+ break;
+
+ case GETOPTDEF_EXEC_WAITFORSTDERR:
+ fWaitForExit = (fOutputFlags |= ProcessOutputFlag_StdErr) ? true : false;
break;
- }
case VINF_GETOPT_NOT_OPTION:
{
- if (!strlen(ValueUnion.psz))
- continue;
-
if (args.size() == 0 && Utf8Cmd.isEmpty())
Utf8Cmd = ValueUnion.psz;
else
@@ -421,275 +566,336 @@ static int handleCtrlExecProgram(HandlerArg *a)
}
}
- if (!fUsageOK)
- return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters");
-
if (Utf8Cmd.isEmpty())
- return errorSyntax(USAGE_GUESTCONTROL,
- "No command to execute specified!");
+ return errorSyntax(USAGE_GUESTCONTROL, "No command to execute specified!");
if (Utf8UserName.isEmpty())
- return errorSyntax(USAGE_GUESTCONTROL,
- "No user name specified!");
+ return errorSyntax(USAGE_GUESTCONTROL, "No user name specified!");
+ /*
+ * <missing comment indicating that we're done parsing args and started doing something else>
+ */
HRESULT rc = S_OK;
- ComPtr<IGuest> guest;
- vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest);
- if (RT_SUCCESS(vrc))
+ if (fVerbose)
{
- ComPtr<IProgress> progress;
- ULONG uPID = 0;
+ if (cMsTimeout == 0)
+ RTPrintf("Waiting for guest to start process ...\n");
+ else
+ RTPrintf("Waiting for guest to start process (within %ums)\n", cMsTimeout);
+ }
+
+ /* Get current time stamp to later calculate rest of timeout left. */
+ uint64_t u64StartMS = RTTimeMilliTS();
+
+ /* Execute the process. */
+ int rcProc = RTEXITCODE_FAILURE;
+ ComPtr<IProgress> progress;
+ ULONG uPID = 0;
+ rc = guest->ExecuteProcess(Bstr(Utf8Cmd).raw(),
+ fExecFlags,
+ ComSafeArrayAsInParam(args),
+ ComSafeArrayAsInParam(env),
+ Bstr(Utf8UserName).raw(),
+ Bstr(Utf8Password).raw(),
+ cMsTimeout,
+ &uPID,
+ progress.asOutParam());
+ if (FAILED(rc))
+ return ctrlPrintError(guest, COM_IIDOF(IGuest));
+ if (fVerbose)
+ RTPrintf("Process '%s' (PID: %u) started\n", Utf8Cmd.c_str(), uPID);
+ if (fWaitForExit)
+ {
if (fVerbose)
{
- if (u32TimeoutMS == 0)
- RTPrintf("Waiting for guest to start process ...\n");
- else
- RTPrintf("Waiting for guest to start process (within %ums)\n", u32TimeoutMS);
+ if (cMsTimeout) /* Wait with a certain timeout. */
+ {
+ /* Calculate timeout value left after process has been started. */
+ uint64_t u64Elapsed = RTTimeMilliTS() - u64StartMS;
+ /* Is timeout still bigger than current difference? */
+ if (cMsTimeout > u64Elapsed)
+ RTPrintf("Waiting for process to exit (%ums left) ...\n", cMsTimeout - u64Elapsed);
+ else
+ RTPrintf("No time left to wait for process!\n"); /** @todo a bit misleading ... */
+ }
+ else /* Wait forever. */
+ RTPrintf("Waiting for process to exit ...\n");
}
- /* Get current time stamp to later calculate rest of timeout left. */
- uint64_t u64StartMS = RTTimeMilliTS();
-
- /* Execute the process. */
- rc = guest->ExecuteProcess(Bstr(Utf8Cmd).raw(), uFlags,
- ComSafeArrayAsInParam(args),
- ComSafeArrayAsInParam(env),
- Bstr(Utf8UserName).raw(),
- Bstr(Utf8Password).raw(), u32TimeoutMS,
- &uPID, progress.asOutParam());
- if (FAILED(rc))
- vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
- else
+ /* Setup signal handling if cancelable. */
+ ASSERT(progress);
+ bool fCanceledAlready = false;
+ BOOL fCancelable;
+ HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable);
+ if (FAILED(hrc))
+ fCancelable = FALSE;
+ if (fCancelable)
+ ctrlSignalHandlerInstall();
+
+ /* Wait for process to exit ... */
+ BOOL fCompleted = FALSE;
+ BOOL fCanceled = FALSE;
+ while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted))))
{
- if (fVerbose)
- RTPrintf("Process '%s' (PID: %u) started\n", Utf8Cmd.c_str(), uPID);
- if (fWaitForExit)
+ SafeArray<BYTE> aOutputData;
+ ULONG cbOutputData = 0;
+
+ /*
+ * Some data left to output?
+ */
+ if (fOutputFlags || fWaitForStdOut)
{
- if (u32TimeoutMS) /* Wait with a certain timeout. */
+ /** @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))
{
- /* Calculate timeout value left after process has been started. */
- uint64_t u64Elapsed = RTTimeMilliTS() - u64StartMS;
- /* Is timeout still bigger than current difference? */
- if (u32TimeoutMS > u64Elapsed)
- {
- if (fVerbose)
- RTPrintf("Waiting for process to exit (%ums left) ...\n", u32TimeoutMS - u64Elapsed);
- }
- else
- {
- if (fVerbose)
- RTPrintf("No time left to wait for process!\n");
- }
+ vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
+ cbOutputData = 0;
}
- else if (fVerbose) /* Wait forever. */
- RTPrintf("Waiting for process to exit ...\n");
-
- /* Setup signal handling if cancelable. */
- ASSERT(progress);
- bool fCanceledAlready = false;
- BOOL fCancelable;
- HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable);
- if (FAILED(hrc))
- fCancelable = FALSE;
- if (fCancelable)
- ctrlSignalHandlerInstall();
-
- /* Wait for process to exit ... */
- BOOL fCompleted = FALSE;
- BOOL fCanceled = FALSE;
- while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted))))
+ else
{
- SafeArray<BYTE> aOutputData;
- ULONG cbOutputData = 0;
-
- /*
- * Some data left to output?
- */
- if ( fWaitForStdOut
- || fWaitForStdErr)
+ cbOutputData = aOutputData.size();
+ if (cbOutputData > 0)
{
- rc = guest->GetProcessOutput(uPID, 0 /* aFlags */,
- RT_MAX(0, u32TimeoutMS - (RTTimeMilliTS() - u64StartMS)) /* Timeout in ms */,
- _64K, ComSafeArrayAsOutParam(aOutputData));
- if (FAILED(rc))
+ /** @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 (eOutputType != OUTPUTTYPE_UNDEFINED)
{
- vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
- cbOutputData = 0;
- }
- else
- {
- cbOutputData = aOutputData.size();
- if (cbOutputData > 0)
+ /*
+ * 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++)
{
- /* aOutputData has a platform dependent line ending, 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')
{
- if (*s == '\r')
- {
- /* skip over CR, adjust destination */
- d--;
- cbOutputDataPrint--;
- }
- else if (s != d)
- *d = *s;
+ /* skip over CR, adjust destination */
+ d--;
+ cbOutputDataPrint--;
}
- RTStrmWrite(g_pStdOut, aOutputData.raw(), cbOutputDataPrint);
+ else if (s != d)
+ *d = *s;
}
+ RTStrmWrite(g_pStdOut, aOutputData.raw(), cbOutputDataPrint);
}
+ else /* Just dump all data as we got it ... */
+ RTStrmWrite(g_pStdOut, aOutputData.raw(), cbOutputData);
}
+ }
+ }
- /* No more output data left? */
- if (cbOutputData <= 0)
- {
- /* 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;
- }
+ /* No more output data left? */
+ if (cbOutputData <= 0)
+ {
+ /* 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;
+ }
- /* Process async cancelation */
- if (g_fGuestCtrlCanceled && !fCanceledAlready)
- {
- hrc = progress->Cancel();
- if (SUCCEEDED(hrc))
- fCanceledAlready = TRUE;
- else
- g_fGuestCtrlCanceled = false;
- }
+ /* Process async cancelation */
+ if (g_fGuestCtrlCanceled && !fCanceledAlready)
+ {
+ hrc = progress->Cancel();
+ if (SUCCEEDED(hrc))
+ fCanceledAlready = TRUE;
+ else
+ g_fGuestCtrlCanceled = false;
+ }
- /* Progress canceled by Main API? */
- if ( SUCCEEDED(progress->COMGETTER(Canceled(&fCanceled)))
- && fCanceled)
- {
- break;
- }
+ /* Progress canceled by Main API? */
+ if ( SUCCEEDED(progress->COMGETTER(Canceled(&fCanceled)))
+ && fCanceled)
+ break;
- /* Did we run out of time? */
- if ( u32TimeoutMS
- && RTTimeMilliTS() - u64StartMS > u32TimeoutMS)
- {
- progress->Cancel();
- break;
- }
- }
+ /* Did we run out of time? */
+ if ( cMsTimeout
+ && RTTimeMilliTS() - u64StartMS > cMsTimeout)
+ {
+ progress->Cancel();
+ break;
+ }
+ } /* while */
- /* Undo signal handling */
- if (fCancelable)
- ctrlSignalHandlerUninstall();
+ /* Undo signal handling */
+ if (fCancelable)
+ ctrlSignalHandlerUninstall();
- if (fCanceled)
- {
- if (fVerbose)
- RTPrintf("Process execution canceled!\n");
- }
- else if ( fCompleted
- && SUCCEEDED(rc))
- {
- LONG iRc;
- CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
- if (FAILED(iRc))
- {
- vrc = ctrlPrintProgressError(progress);
- }
- else if (fVerbose)
- {
- ULONG uRetStatus, uRetExitCode, uRetFlags;
- rc = guest->GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &uRetStatus);
- if (SUCCEEDED(rc))
- RTPrintf("Exit code=%u (Status=%u [%s], Flags=%u)\n", uRetExitCode, uRetStatus, ctrlExecGetStatus(uRetStatus), uRetFlags);
- }
- }
- else
- {
- if (fVerbose)
- RTPrintf("Process execution aborted!\n");
- }
+ /* Report status back to the user. */
+ if (fCanceled)
+ {
+ if (fVerbose)
+ RTPrintf("Process execution canceled!\n");
+ rcProc = EXITCODEEXEC_CANCELED;
+ }
+ else if ( fCompleted
+ && SUCCEEDED(rc)) /* The GetProcessOutput rc. */
+ {
+ LONG iRc;
+ CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
+ if (FAILED(iRc))
+ vrc = ctrlPrintProgressError(progress);
+ else
+ {
+ 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);
}
}
- ctrlUninitVM(a);
+ else
+ {
+ if (fVerbose)
+ RTPrintf("Process execution aborted!\n");
+ rcProc = EXITCODEEXEC_TERM_ABEND;
+ }
}
- if (RT_FAILURE(vrc))
- rc = VBOX_E_IPRT_ERROR;
- return SUCCEEDED(rc) ? 0 : 1;
+ if (RT_FAILURE(vrc) || FAILED(rc))
+ return RTEXITCODE_FAILURE;
+ return rcProc;
}
-/**
- * Appends a new file/directory entry to a given list.
- *
- * @return IPRT status code.
- * @param pszFileSource Full qualified source path of file to copy (optional).
- * @param pszFileDest Full qualified destination path (optional).
- * @param pList Copy list used for insertion.
- */
-static int ctrlDirectoryEntryAppend(const char *pszFileSource, const char *pszFileDest,
- PRTLISTNODE pList)
+/** @todo Clean up too long parameter list -> move guest specific stuff into own struct etc! */
+static int ctrlCopyDirectoryReadGuest(IGuest *pGuest,
+ const char *pszUsername, const char *pszPassword,
+ const char *pszRootDir, const char *pszSubDir,
+ const char *pszFilter, const char *pszDest,
+ uint32_t fFlags, uint32_t *pcObjects, DESTDIRMAP &dirMap)
{
- AssertPtrReturn(pList, VERR_INVALID_POINTER);
- AssertReturn(pszFileSource || pszFileDest, VERR_INVALID_PARAMETER);
-
- PDIRECTORYENTRY pNode = (PDIRECTORYENTRY)RTMemAlloc(sizeof(DIRECTORYENTRY));
- if (pNode == NULL)
- return VERR_NO_MEMORY;
+ AssertPtrReturn(pszRootDir, VERR_INVALID_POINTER);
+ /* Sub directory is optional. */
+ /* Filter directory is optional. */
+ AssertPtrReturn(pszDest, VERR_INVALID_POINTER);
+ AssertPtrReturn(pcObjects, VERR_INVALID_POINTER);
- pNode->pszSourcePath = NULL;
- pNode->pszDestPath = NULL;
+ /*
+ * Construct current path.
+ */
+ char szCurDir[RTPATH_MAX];
+ int rc = RTStrCopy(szCurDir, sizeof(szCurDir), pszRootDir);
+ if (RT_SUCCESS(rc) && pszSubDir != NULL)
+ rc = RTPathAppend(szCurDir, sizeof(szCurDir), pszSubDir);
- if (pszFileSource)
- {
- pNode->pszSourcePath = RTStrDup(pszFileSource);
- AssertPtrReturn(pNode->pszSourcePath, VERR_NO_MEMORY);
- }
- if (pszFileDest)
+ if (RT_SUCCESS(rc))
{
- pNode->pszDestPath = RTStrDup(pszFileDest);
- AssertPtrReturn(pNode->pszDestPath, VERR_NO_MEMORY);
- }
+ ULONG uDirHandle;
+ HRESULT hr = pGuest->DirectoryOpen(Bstr(szCurDir).raw(), Bstr(pszFilter).raw(), fFlags,
+ Bstr(pszUsername).raw(), Bstr(pszPassword).raw(), &uDirHandle);
+ if (FAILED(hr))
+ rc = ctrlPrintError(pGuest, COM_IIDOF(IGuest));
+ else
+ {
+ ComPtr <IGuestDirEntry> dirEntry;
+ while (SUCCEEDED(hr = pGuest->DirectoryRead(uDirHandle, dirEntry.asOutParam())))
+ {
+ GuestDirEntryType_T enmType;
+ dirEntry->COMGETTER(Type)(&enmType);
- pNode->Node.pPrev = NULL;
- pNode->Node.pNext = NULL;
- RTListAppend(pList, &pNode->Node);
- return VINF_SUCCESS;
-}
+ Bstr strName;
+ dirEntry->COMGETTER(Name)(strName.asOutParam());
-/**
- * Destroys a directory list.
- *
- * @param pList Pointer to list to destroy.
- */
-static void ctrlDirectoryListDestroy(PRTLISTNODE pList)
-{
- AssertPtr(pList);
+ switch (enmType)
+ {
+ case GuestDirEntryType_Directory:
+ {
+ /* Skip "." and ".." entries. */
+ if ( !strName.compare(Bstr("."))
+ || !strName.compare(Bstr("..")))
+ break;
- /* Destroy file list. */
- PDIRECTORYENTRY pNode = RTListGetFirst(pList, DIRECTORYENTRY, Node);
- while (pNode)
- {
- PDIRECTORYENTRY pNext = RTListNodeGetNext(&pNode->Node, DIRECTORYENTRY, Node);
- bool fLast = RTListNodeIsLast(pList, &pNode->Node);
+ const char *pszName = Utf8Str(strName).c_str();
+ if (fFlags & CopyFileFlag_Recursive)
+ {
+ char *pszNewSub = NULL;
+ if (pszSubDir)
+ RTStrAPrintf(&pszNewSub, "%s/%s", pszSubDir, pszName);
+ else
+ RTStrAPrintf(&pszNewSub, "%s", pszName);
- if (pNode->pszSourcePath)
- RTStrFree(pNode->pszSourcePath);
- if (pNode->pszDestPath)
- RTStrFree(pNode->pszDestPath);
- RTListNodeRemove(&pNode->Node);
- RTMemFree(pNode);
+ if (pszNewSub)
+ {
+ dirMap[pszNewSub];
- if (fLast)
- break;
+ rc = ctrlCopyDirectoryReadGuest(pGuest, pszUsername, pszPassword,
+ pszRootDir, pszNewSub,
+ pszFilter, pszDest,
+ fFlags, pcObjects, dirMap);
+ RTStrFree(pszNewSub);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ }
+ break;
+ }
+
+ case GuestDirEntryType_Symlink:
+ if ( (fFlags & CopyFileFlag_Recursive)
+ && (fFlags & CopyFileFlag_FollowLinks))
+ {
+ /* Fall through to next case is intentional. */
+ }
+ else
+ break;
- pNode = pNext;
+ case GuestDirEntryType_File:
+ {
+ const char *pszName = Utf8Str(strName).c_str();
+ if ( !pszFilter
+ || RTStrSimplePatternMatch(pszFilter, pszName))
+ {
+ dirMap[pszSubDir].push_back(DESTFILEENTRY(pszName));
+ *pcObjects += 1;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ hr = pGuest->DirectoryClose(uDirHandle);
+ if (FAILED(rc))
+ rc = ctrlPrintError(pGuest, COM_IIDOF(IGuest));
+ }
}
+ return rc;
}
-
/**
* Reads a specified directory (recursively) based on the copy flags
* and appends all matching entries to the supplied list.
@@ -701,41 +907,47 @@ static void ctrlDirectoryListDestroy(PRTLISTNODE pList)
* directory; needed for recursion.
* @param pszFilter Search filter (e.g. *.pdf).
* @param pszDest Destination directory.
- * @param uFlags Copy flags.
+ * @param fFlags Copy flags.
* @param pcObjects Where to store the overall objects to
* copy found.
- * @param pList Pointer to the object list to use.
+ * @param dirMap Reference to destination directory map to store found
+ * directories (primary key) + files (secondary key, vector).
*/
-static int ctrlCopyDirectoryRead(const char *pszRootDir, const char *pszSubDir,
- const char *pszFilter, const char *pszDest,
- uint32_t uFlags, uint32_t *pcObjects, PRTLISTNODE pList)
+static int ctrlCopyDirectoryReadHost(const char *pszRootDir, const char *pszSubDir,
+ const char *pszFilter, const char *pszDest,
+ uint32_t fFlags, uint32_t *pcObjects, DESTDIRMAP &dirMap)
{
AssertPtrReturn(pszRootDir, VERR_INVALID_POINTER);
/* Sub directory is optional. */
/* Filter directory is optional. */
AssertPtrReturn(pszDest, VERR_INVALID_POINTER);
AssertPtrReturn(pcObjects, VERR_INVALID_POINTER);
- AssertPtrReturn(pList, VERR_INVALID_POINTER);
-
- PRTDIR pDir = NULL;
- int rc = VINF_SUCCESS;
+ /*
+ * Construct current path.
+ */
char szCurDir[RTPATH_MAX];
- /* Construct current path. */
- if (RTStrPrintf(szCurDir, sizeof(szCurDir), pszRootDir))
- {
- if (pszSubDir != NULL)
- rc = RTPathAppend(szCurDir, sizeof(szCurDir), pszSubDir);
- }
- else
- rc = VERR_NO_MEMORY;
+ int rc = RTStrCopy(szCurDir, sizeof(szCurDir), pszRootDir);
+ if (RT_SUCCESS(rc) && pszSubDir != NULL)
+ rc = RTPathAppend(szCurDir, sizeof(szCurDir), pszSubDir);
+ /*
+ * Open directory without a filter - RTDirOpenFiltered unfortunately
+ * cannot handle sub directories so we have to do the filtering ourselves.
+ */
+ PRTDIR pDir = NULL;
if (RT_SUCCESS(rc))
{
- /* Open directory without a filter - RTDirOpenFiltered unfortunately
- * cannot handle sub directories so we have to do the filtering ourselves. */
rc = RTDirOpen(&pDir, szCurDir);
- for (;RT_SUCCESS(rc);)
+ if (RT_FAILURE(rc))
+ pDir = NULL;
+ }
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Enumerate the directory tree.
+ */
+ while (RT_SUCCESS(rc))
{
RTDIRENTRY DirEntry;
rc = RTDirRead(pDir, &DirEntry, NULL);
@@ -748,35 +960,38 @@ static int ctrlCopyDirectoryRead(const char *pszRootDir, const char *pszSubDir,
switch (DirEntry.enmType)
{
case RTDIRENTRYTYPE_DIRECTORY:
- /* Skip "." and ".." entrires. */
+ {
+ /* Skip "." and ".." entries. */
if ( !strcmp(DirEntry.szName, ".")
|| !strcmp(DirEntry.szName, ".."))
- {
break;
- }
- if (uFlags & CopyFileFlag_Recursive)
+
+ if (fFlags & CopyFileFlag_Recursive)
{
char *pszNewSub = NULL;
if (pszSubDir)
- RTStrAPrintf(&pszNewSub, "%s%s/", pszSubDir, DirEntry.szName);
+ RTStrAPrintf(&pszNewSub, "%s/%s", pszSubDir, DirEntry.szName);
else
- RTStrAPrintf(&pszNewSub, "%s/", DirEntry.szName);
+ RTStrAPrintf(&pszNewSub, "%s", DirEntry.szName);
if (pszNewSub)
{
- rc = ctrlCopyDirectoryRead(pszRootDir, pszNewSub,
- pszFilter, pszDest,
- uFlags, pcObjects, pList);
+ dirMap[pszNewSub];
+
+ rc = ctrlCopyDirectoryReadHost(pszRootDir, pszNewSub,
+ pszFilter, pszDest,
+ fFlags, pcObjects, dirMap);
RTStrFree(pszNewSub);
}
else
rc = VERR_NO_MEMORY;
}
break;
+ }
case RTDIRENTRYTYPE_SYMLINK:
- if ( (uFlags & CopyFileFlag_Recursive)
- && (uFlags & CopyFileFlag_FollowLinks))
+ if ( (fFlags & CopyFileFlag_Recursive)
+ && (fFlags & CopyFileFlag_FollowLinks))
{
/* Fall through to next case is intentional. */
}
@@ -785,44 +1000,14 @@ static int ctrlCopyDirectoryRead(const char *pszRootDir, const char *pszSubDir,
case RTDIRENTRYTYPE_FILE:
{
- bool fProcess = false;
- if (pszFilter && RTStrSimplePatternMatch(pszFilter, DirEntry.szName))
- fProcess = true;
- else if (!pszFilter)
- fProcess = true;
-
- if (fProcess)
+ if ( !pszFilter
+ || RTStrSimplePatternMatch(pszFilter, DirEntry.szName))
{
- char *pszFileSource = NULL;
- char *pszFileDest = NULL;
- if (RTStrAPrintf(&pszFileSource, "%s%s%s",
- pszRootDir, pszSubDir ? pszSubDir : "",
- DirEntry.szName) >= 0)
- {
- if (RTStrAPrintf(&pszFileDest, "%s%s%s",
- pszDest, pszSubDir ? pszSubDir : "",
- DirEntry.szName) <= 0)
- {
- rc = VERR_NO_MEMORY;
- }
- }
- else
- rc = VERR_NO_MEMORY;
-
- if (RT_SUCCESS(rc))
- {
- rc = ctrlDirectoryEntryAppend(pszFileSource, pszFileDest, pList);
- if (RT_SUCCESS(rc))
- *pcObjects = *pcObjects + 1;
- }
-
- if (pszFileSource)
- RTStrFree(pszFileSource);
- if (pszFileDest)
- RTStrFree(pszFileDest);
+ dirMap[pszSubDir].push_back(DESTFILEENTRY(Utf8Str(DirEntry.szName)));
+ *pcObjects += 1;
}
+ break;
}
- break;
default:
break;
@@ -830,143 +1015,142 @@ static int ctrlCopyDirectoryRead(const char *pszRootDir, const char *pszSubDir,
if (RT_FAILURE(rc))
break;
}
- }
- if (pDir)
RTDirClose(pDir);
+ }
return rc;
}
/**
- * Initializes the copy process and builds up an object list
- * with all required information to start the actual copy process.
+ * Constructs a destinations map from a source entry and a destination root.
*
* @return IPRT status code.
- * @param pszSource Source path on host to use.
- * @param pszDest Destination path on guest to use.
- * @param uFlags Copy flags.
- * @param pcObjects Where to store the count of objects to be copied.
- * @param pList Where to store the object list.
+ * @param fHostToGuest
+ * @param sourceEntry Reference to a specified source entry to use.
+ * @param fFlags Copy file flags. Needed for recursive directory parsing.
+ * @param pszDestRoot Pointer to destination root. This can be used to add one or
+ * more directories to the actual destination path.
+ * @param mapDest Reference to the destination map for storing the actual result.
+ * @param pcObjects Pointer to a total object (file) count to copy.
*/
-static int ctrlCopyInit(const char *pszSource, const char *pszDest, uint32_t uFlags,
- uint32_t *pcObjects, PRTLISTNODE pList)
+static int ctrlCopyConstructDestinationsForGuest(SOURCEFILEENTRY &sourceEntry, uint32_t fFlags,
+ const char *pszDestRoot, DESTDIRMAP &mapDest,
+ uint32_t *pcObjects)
{
- AssertPtrReturn(pszSource, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pszDest, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pcObjects, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pList, VERR_INVALID_PARAMETER);
+ int rc = VINF_SUCCESS;
+ const char *pszSource = sourceEntry.mSource.c_str();
+
+ if ( RTPathFilename(pszSource)
+ && RTFileExists(pszSource))
+ {
+ /* Source is a single file. */
+ char *pszFileName = RTPathFilename(pszSource);
+ mapDest[Utf8Str("")].push_back(DESTFILEENTRY(pszFileName));
+ *pcObjects += 1;
+ }
+ else
+ {
+ /* Source is either a directory or a filter (e.g. *.dll). */
+ rc = ctrlCopyDirectoryReadHost(pszSource,
+ NULL /* pszSubDir */,
+ sourceEntry.mFilter.isEmpty() ? NULL : sourceEntry.mFilter.c_str(),
+ pszDestRoot, fFlags, pcObjects, mapDest);
+ }
+ return rc;
+}
+
+static int ctrlCopyConstructDestinationsForHost(IGuest *pGuest,
+ const char *pszUsername, const char *pszPassword,
+ SOURCEFILEENTRY &sourceEntry, uint32_t fFlags,
+ const char *pszDestRoot, DESTDIRMAP &mapDest,
+ uint32_t *pcObjects)
+{
int rc = VINF_SUCCESS;
- char *pszSourceAbs = RTPathAbsDup(pszSource);
- if (pszSourceAbs)
+ const char *pszSource = sourceEntry.mSource.c_str();
+
+ BOOL fExists = FALSE;
+ HRESULT hr = pGuest->FileExists(Bstr(pszSource).raw(),
+ Bstr(pszUsername).raw(), Bstr(pszPassword).raw(), &fExists);
+ if (FAILED(rc))
+ rc = ctrlPrintError(pGuest, COM_IIDOF(IGuest));
+ else
{
- if ( RTPathFilename(pszSourceAbs)
- && RTFileExists(pszSourceAbs)) /* We have a single file ... */
+ if (fExists)
{
- char *pszDestAbs = RTStrDup(pszDest);
- if (pszDestAbs)
- {
- /* Do we have a trailing slash for the destination?
- * Then this is a directory ... */
- size_t cch = strlen(pszDestAbs);
- if ( cch > 1
- && ( RTPATH_IS_SLASH(pszDestAbs[cch - 1])
- || RTPATH_IS_SLASH(pszDestAbs[cch - 2])
- )
- )
- {
- rc = RTStrAAppend(&pszDestAbs, RTPathFilename(pszSourceAbs));
- }
- else
- {
- /* Since the desetination seems not to be a directory,
- * we assume that this is the absolute path to the destination
- * file -> nothing to do here ... */
- }
+ /* Source is a single file. */
+ char *pszFileName = RTPathFilename(pszSource);
+ mapDest[Utf8Str(pszDestRoot)].push_back(DESTFILEENTRY(pszFileName));
- if (RT_SUCCESS(rc))
- {
- RTListInit(pList);
- rc = ctrlDirectoryEntryAppend(pszSourceAbs, pszDestAbs, pList);
- *pcObjects = 1;
- }
- RTStrFree(pszDestAbs);
- }
- else
- rc = VERR_NO_MEMORY;
+ *pcObjects++;
}
- else /* ... or a directory. */
+ else
{
- /* Append trailing slash to absolute directory. */
- if (RTDirExists(pszSourceAbs))
- RTStrAAppend(&pszSourceAbs, RTPATH_SLASH_STR);
-
- /* Extract directory filter (e.g. "*.exe"). */
- char *pszFilter = RTPathFilename(pszSourceAbs);
- char *pszSourceAbsRoot = RTStrDup(pszSourceAbs);
- char *pszDestAbs = RTStrDup(pszDest);
- if ( pszSourceAbsRoot
- && pszDestAbs)
- {
- if (pszFilter)
- {
- RTPathStripFilename(pszSourceAbsRoot);
- rc = RTStrAAppend(&pszSourceAbsRoot, RTPATH_SLASH_STR);
- }
- else
- {
- /*
- * If we have more than one file to copy, make sure that we have
- * a trailing slash so that we can construct a full path name
- * (e.g. "foo.txt" -> "c:/foo/temp.txt") as destination.
- */
- size_t cch = strlen(pszSourceAbsRoot);
- if ( cch > 1
- && !RTPATH_IS_SLASH(pszSourceAbsRoot[cch - 1])
- && !RTPATH_IS_SLASH(pszSourceAbsRoot[cch - 2]))
- {
- rc = RTStrAAppend(&pszSourceAbsRoot, RTPATH_SLASH_STR);
- }
- }
+ /* Source is either a directory or a filter (e.g. *.dll). */
+ rc = ctrlCopyDirectoryReadGuest(pGuest, pszUsername, pszPassword,
+ pszSource, NULL /* pszSubDir */,
+ sourceEntry.mFilter.isEmpty() ? NULL : sourceEntry.mFilter.c_str(),
+ pszDestRoot, fFlags, pcObjects, mapDest);
+ }
+ }
+ return rc;
+}
- if (RT_SUCCESS(rc))
- {
- /*
- * Make sure we have a valid destination path. All we can do
- * here is to check whether we have a trailing slash -- the rest
- * (i.e. path creation, rights etc.) needs to be done inside the guest.
- */
- size_t cch = strlen(pszDestAbs);
- if ( cch > 1
- && !RTPATH_IS_SLASH(pszDestAbs[cch - 1])
- && !RTPATH_IS_SLASH(pszDestAbs[cch - 2]))
- {
- rc = RTStrAAppend(&pszDestAbs, RTPATH_SLASH_STR);
- }
- }
+/**
+ * Prepares the destination directory hirarchy on the guest side by creating the directories
+ * and sets the appropriate access rights.
+ *
+ * @return IPRT status code.
+ * @param pGuest IGuest interface pointer.
+ * @param fHostToGuest
+ * @param itDest Destination map iterator to process.
+ * @param pszDestRoot Destination root to use.
+ * @param pszUsername Username to use.
+ * @param pszPassword Password to use.
+ */
+static int ctrlCopyPrepareDestDirectory(IGuest *pGuest, bool fHostToGuest,
+ const char *pszDestRoot, const char *pszDestSub,
+ const char *pszUsername, const char *pszPassword)
+{
+ AssertPtrReturn(pGuest, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszDestRoot, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszDestSub, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszUsername, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
- if (RT_SUCCESS(rc))
- {
- RTListInit(pList);
- rc = ctrlCopyDirectoryRead(pszSourceAbsRoot, NULL /* Sub directory */,
- pszFilter, pszDestAbs,
- uFlags, pcObjects, pList);
- if (RT_SUCCESS(rc) && *pcObjects == 0)
- rc = VERR_NOT_FOUND;
- }
+ char *pszDestFinal = NULL;
+ int rc = VINF_SUCCESS;
- if (pszDestAbs)
- RTStrFree(pszDestAbs);
- if (pszSourceAbsRoot)
- RTStrFree(pszSourceAbsRoot);
- }
- else
- rc = VERR_NO_MEMORY;
+ /* Create root directory (= empty name) and skip the rest for
+ * this round. */
+ if (!strlen(pszDestSub))
+ {
+ pszDestFinal = RTStrDup(pszDestRoot);
+ if (!pszDestFinal)
+ rc = VERR_NO_MEMORY;
+ }
+ else /* Create sub-directories, also empty ones. */
+ {
+ if (!RTStrAPrintf(&pszDestFinal, "%s/%s", pszDestRoot, pszDestSub))
+ rc = VERR_NO_MEMORY;
+ }
+
+ if (RT_SUCCESS(rc) && pszDestFinal)
+ {
+ if (fHostToGuest) /* We want to create directories on the guest. */
+ {
+ HRESULT hrc = pGuest->DirectoryCreate(Bstr(pszDestFinal).raw(),
+ Bstr(pszUsername).raw(), Bstr(pszPassword).raw(),
+ 700, DirectoryCreateFlag_Parents);
+ if (FAILED(hrc))
+ rc = ctrlPrintError(pGuest, COM_IIDOF(IGuest));
+ }
+ else /* ... or on the host. */
+ {
+ rc = RTDirCreate(pszDestFinal, 700);
}
- RTStrFree(pszSourceAbs);
+ RTStrFree(pszDestFinal);
}
- else
- rc = VERR_NO_MEMORY;
return rc;
}
@@ -974,28 +1158,28 @@ static int ctrlCopyInit(const char *pszSource, const char *pszDest, uint32_t uFl
* Copys a file from host to the guest.
*
* @return IPRT status code.
- * @param pGuest IGuest interface pointer.
- * @param fVerbose Verbose flag.
- * @param pszSource Source path of existing host file to copy.
- * @param pszDest Destination path on guest to copy the file to.
- * @param pszUserName User name on guest to use for the copy operation.
- * @param pszPassword Password of user account.
- * @param uFlags Copy flags.
+ * @param pGuest IGuest interface pointer.
+ * @param pszSource Source path of existing host file to copy to the guest.
+ * @param pszDest Destination path on guest to copy the file to.
+ * @param pszUserName User name on guest to use for the copy operation.
+ * @param pszPassword Password of user account.
+ * @param fFlags Copy flags.
*/
-static int ctrlCopyFileToGuest(IGuest *pGuest, bool fVerbose, const char *pszSource, const char *pszDest,
+static int ctrlCopyFileToGuest(IGuest *pGuest, const char *pszSource, const char *pszDest,
const char *pszUserName, const char *pszPassword,
- uint32_t uFlags)
+ uint32_t fFlags)
{
- AssertPtrReturn(pszSource, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pszDest, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pszUserName, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pszPassword, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pGuest, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszSource, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszDest, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszUserName, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
int vrc = VINF_SUCCESS;
ComPtr<IProgress> progress;
HRESULT rc = pGuest->CopyToGuest(Bstr(pszSource).raw(), Bstr(pszDest).raw(),
Bstr(pszUserName).raw(), Bstr(pszPassword).raw(),
- uFlags, progress.asOutParam());
+ fFlags, progress.asOutParam());
if (FAILED(rc))
vrc = ctrlPrintError(pGuest, COM_IIDOF(IGuest));
else
@@ -1007,65 +1191,174 @@ static int ctrlCopyFileToGuest(IGuest *pGuest, bool fVerbose, const char *pszSou
return vrc;
}
-static int handleCtrlCopyTo(HandlerArg *a)
+/**
+ * Copys a file from guest to the host.
+ *
+ * @return IPRT status code.
+ * @param pGuest IGuest interface pointer.
+ * @param pszSource Source path of existing guest file to copy to the host.
+ * @param pszDest Destination path/file on host to copy the file to.
+ * @param pszUserName User name on guest to use for the copy operation.
+ * @param pszPassword Password of user account.
+ * @param fFlags Copy flags.
+ */
+static int ctrlCopyFileToHost(IGuest *pGuest, const char *pszSource, const char *pszDest,
+ const char *pszUserName, const char *pszPassword,
+ uint32_t fFlags)
{
+ AssertPtrReturn(pGuest, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszSource, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszDest, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszUserName, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
+
+ int vrc = VINF_SUCCESS;
+ ComPtr<IProgress> progress;
+ HRESULT rc = pGuest->CopyFromGuest(Bstr(pszSource).raw(), Bstr(pszDest).raw(),
+ Bstr(pszUserName).raw(), Bstr(pszPassword).raw(),
+ fFlags, progress.asOutParam());
+ if (FAILED(rc))
+ vrc = ctrlPrintError(pGuest, COM_IIDOF(IGuest));
+ else
+ {
+ rc = showProgress(progress);
+ if (FAILED(rc))
+ vrc = ctrlPrintProgressError(progress);
+ }
+ return vrc;
+}
+
+static int ctrlCopyToDestDirectory(IGuest *pGuest, bool fVerbose, bool fDryRun, bool fHostToGuest,
+ const char *pszSourceDir,
+ const char *pszDestRoot, const char *pszDestSub, const char *pszFileName,
+ uint32_t uFlags, const char *pszUsername, const char *pszPassword)
+{
+ AssertPtrReturn(pGuest, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszDestRoot, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszDestSub, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszFileName, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszSourceDir, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszUsername, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
+
+ int iLen;
+ char *pszSource;
+ if (!strlen(pszDestSub))
+ iLen = RTStrAPrintf(&pszSource, "%s/%s", pszSourceDir, pszFileName);
+ else
+ iLen = RTStrAPrintf(&pszSource, "%s/%s/%s",
+ pszSourceDir, pszDestSub, pszFileName);
+ if (!iLen)
+ return VERR_NO_MEMORY;
+
+ char *pszDest;
+ if (!strlen(pszDestSub))
+ iLen = RTStrAPrintf(&pszDest, "%s/%s", pszDestRoot, pszFileName);
+ else
+ iLen = RTStrAPrintf(&pszDest, "%s/%s/%s", pszDestRoot, pszDestSub,
+ pszFileName);
+ if (!iLen)
+ {
+ RTStrFree(pszSource);
+ return VERR_NO_MEMORY;
+ }
+
+ if (fVerbose)
+ RTPrintf("\"%s\" -> \"%s\"\n", pszSource, pszDest);
+
+ int rc = VINF_SUCCESS;
+
+ /* Finally copy the desired file (if no dry run selected). */
+ if (!fDryRun)
+ {
+ if (fHostToGuest)
+ rc = ctrlCopyFileToGuest(pGuest, pszSource, pszDest,
+ pszUsername, pszPassword, uFlags);
+ else
+ rc = ctrlCopyFileToHost(pGuest, pszSource, pszDest,
+ pszUsername, pszPassword, uFlags);
+ }
+ RTStrFree(pszSource);
+ RTStrFree(pszDest);
+
+ return rc;
+}
+
+static int handleCtrlCopyTo(ComPtr<IGuest> guest, HandlerArg *pArg,
+ bool fHostToGuest)
+{
+ AssertPtrReturn(pArg, VERR_INVALID_PARAMETER);
+
+ /** @todo r=bird: This command isn't very unix friendly in general. mkdir
+ * is much better (partly because it is much simpler of course). The main
+ * arguments against this is that (1) all but two options conflicts with
+ * what 'man cp' tells me on a GNU/Linux system, (2) wildchar matching is
+ * done windows CMD style (though not in a 100% compatible way), and (3)
+ * that only one source is allowed - efficiently sabotaging default
+ * wildcard expansion by a unix shell. The best solution here would be
+ * two different variant, one windowsy (xcopy) and one unixy (gnu cp). */
+
/*
- * Check the syntax. We can deduce the correct syntax from the number of
- * arguments.
+ * IGuest::CopyToGuest is kept as simple as possible to let the developer choose
+ * what and how to implement the file enumeration/recursive lookup, like VBoxManage
+ * does in here.
*/
- if (a->argc < 3) /* At least the source + destination should be present :-). */
- return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters");
static const RTGETOPTDEF s_aOptions[] =
{
- { "--dryrun", 'd', RTGETOPT_REQ_NOTHING },
- { "--follow", 'F', RTGETOPT_REQ_NOTHING },
- { "--password", 'p', RTGETOPT_REQ_STRING },
- { "--recursive", 'R', RTGETOPT_REQ_NOTHING },
- { "--username", 'u', RTGETOPT_REQ_STRING },
- { "--verbose", 'v', RTGETOPT_REQ_NOTHING }
+ { "--dryrun", GETOPTDEF_COPYTO_DRYRUN, RTGETOPT_REQ_NOTHING },
+ { "--follow", GETOPTDEF_COPYTO_FOLLOW, RTGETOPT_REQ_NOTHING },
+ { "--password", GETOPTDEF_COPYTO_PASSWORD, RTGETOPT_REQ_STRING },
+ { "--recursive", 'R', RTGETOPT_REQ_NOTHING },
+ { "--target-directory", GETOPTDEF_COPYTO_TARGETDIR, RTGETOPT_REQ_STRING },
+ { "--username", GETOPTDEF_COPYTO_USERNAME, RTGETOPT_REQ_STRING },
+ { "--verbose", 'v', RTGETOPT_REQ_NOTHING }
};
int ch;
RTGETOPTUNION ValueUnion;
RTGETOPTSTATE GetState;
- RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ RTGetOptInit(&GetState, pArg->argc, pArg->argv,
+ s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_OPTS_FIRST);
Utf8Str Utf8Source;
Utf8Str Utf8Dest;
Utf8Str Utf8UserName;
Utf8Str Utf8Password;
- uint32_t uFlags = CopyFileFlag_None;
+ uint32_t fFlags = CopyFileFlag_None;
bool fVerbose = false;
bool fCopyRecursive = false;
bool fDryRun = false;
+ SOURCEVEC vecSources;
+
int vrc = VINF_SUCCESS;
- uint32_t uNoOptionIdx = 0;
- bool fUsageOK = true;
- while ( (ch = RTGetOpt(&GetState, &ValueUnion))
- && RT_SUCCESS(vrc))
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)))
{
/* For options that require an argument, ValueUnion has received the value. */
switch (ch)
{
- case 'd': /* Dry run */
+ case GETOPTDEF_COPYTO_DRYRUN:
fDryRun = true;
break;
- case 'F': /* Follow symlinks */
- uFlags |= CopyFileFlag_FollowLinks;
+ case GETOPTDEF_COPYTO_FOLLOW:
+ fFlags |= CopyFileFlag_FollowLinks;
break;
- case 'p': /* Password */
+ case GETOPTDEF_COPYTO_PASSWORD:
Utf8Password = ValueUnion.psz;
break;
case 'R': /* Recursive processing */
- uFlags |= CopyFileFlag_Recursive;
+ fFlags |= CopyFileFlag_Recursive;
break;
- case 'u': /* User name */
+ case GETOPTDEF_COPYTO_TARGETDIR:
+ Utf8Dest = ValueUnion.psz;
+ break;
+
+ case GETOPTDEF_COPYTO_USERNAME:
Utf8UserName = ValueUnion.psz;
break;
@@ -1075,25 +1368,18 @@ static int handleCtrlCopyTo(HandlerArg *a)
case VINF_GETOPT_NOT_OPTION:
{
- /* Get the actual source + destination. */
- switch (uNoOptionIdx)
+ /* Last argument and no destination specified with
+ * --target-directory yet? Then use the current argument
+ * as destination. */
+ if ( pArg->argc == GetState.iNext
+ && Utf8Dest.isEmpty())
{
- case 0:
- Utf8Source = ValueUnion.psz;
- break;
-
- case 1:
- Utf8Dest = ValueUnion.psz;
- break;
-
- default:
- break;
+ Utf8Dest = ValueUnion.psz;
}
- uNoOptionIdx++;
- if (uNoOptionIdx == UINT32_MAX)
+ else
{
- RTMsgError("Too many files specified! Aborting.\n");
- vrc = VERR_TOO_MUCH_DATA;
+ /* Save the source directory. */
+ vecSources.push_back(SOURCEFILEENTRY(ValueUnion.psz));
}
break;
}
@@ -1103,12 +1389,9 @@ static int handleCtrlCopyTo(HandlerArg *a)
}
}
- if (!fUsageOK)
- return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters");
-
- if (Utf8Source.isEmpty())
+ if (!vecSources.size())
return errorSyntax(USAGE_GUESTCONTROL,
- "No source specified!");
+ "No source(s) specified!");
if (Utf8Dest.isEmpty())
return errorSyntax(USAGE_GUESTCONTROL,
@@ -1117,100 +1400,146 @@ static int handleCtrlCopyTo(HandlerArg *a)
if (Utf8UserName.isEmpty())
return errorSyntax(USAGE_GUESTCONTROL,
"No user name specified!");
- HRESULT rc = S_OK;
- ComPtr<IGuest> guest;
- vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest);
- if (RT_SUCCESS(vrc))
+
+ /*
+ * Done parsing arguments, do some more preparations.
+ */
+ if (fVerbose)
{
- if (fVerbose)
+ if (fHostToGuest)
+ RTPrintf("Copying from host to guest ...\n");
+ else
+ RTPrintf("Copying from guest to host ...\n");
+ if (fDryRun)
+ RTPrintf("Dry run - no files copied!\n");
+ }
+
+ /* Strip traling slash from destination path. */
+ RTPathStripTrailingSlash(Utf8Dest.mutableRaw());
+ Utf8Dest.jolt();
+
+ /*
+ * Here starts the actual fun!
+ */
+ for (unsigned long s = 0; s < vecSources.size(); s++)
+ {
+ char *pszSourceDir;
+ if (RTDirExists(vecSources[s].mSource.c_str()))
+ pszSourceDir = RTStrDup(vecSources[s].mSource.c_str());
+ else
{
- if (fDryRun)
- RTPrintf("Dry run - no files copied!\n");
- RTPrintf("Gathering file information ...\n");
+ pszSourceDir = RTStrDup(vecSources[s].mSource.c_str());
+ RTPathStripFilename(pszSourceDir);
}
- RTLISTNODE listToCopy;
- uint32_t cTotalObjects = 0;
- vrc = ctrlCopyInit(Utf8Source.c_str(), Utf8Dest.c_str(), uFlags,
- &cTotalObjects, &listToCopy);
+ uint32_t cObjects = 0;
+ DESTDIRMAP mapDest;
+ const char *pszDestRoot = Utf8Dest.c_str();
+
+ if (fHostToGuest)
+ vrc = ctrlCopyConstructDestinationsForGuest(vecSources[s], fFlags, pszDestRoot,
+ mapDest, &cObjects);
+ else
+ vrc = ctrlCopyConstructDestinationsForHost(guest, Utf8UserName.c_str(), Utf8Password.c_str(),
+ vecSources[s], fFlags, pszDestRoot,
+ mapDest, &cObjects);
if (RT_FAILURE(vrc))
{
- switch (vrc)
+ if ( fVerbose
+ && vrc == VERR_FILE_NOT_FOUND)
{
- case VERR_NOT_FOUND:
- RTMsgError("No files to copy found!\n");
- break;
-
- case VERR_FILE_NOT_FOUND:
- RTMsgError("Source path \"%s\" not found!\n", Utf8Source.c_str());
- break;
-
- default:
- RTMsgError("Failed to initialize, rc=%Rrc\n", vrc);
- break;
+ RTPrintf("Warning: Source \"%s\" does not exist, skipping!\n",
+ vecSources[s].mSource.c_str());
}
}
else
{
- PDIRECTORYENTRY pNode;
- if (RT_SUCCESS(vrc))
+ /*
+ * Prepare directory structure of each destination directory.
+ */
+ DESTDIRMAPITER itDest;
+ for (itDest = mapDest.begin(); itDest != mapDest.end(); itDest++)
{
if (fVerbose)
{
- if (fCopyRecursive)
- RTPrintf("Recursively copying \"%s\" to \"%s\" (%u file(s)) ...\n",
- Utf8Source.c_str(), Utf8Dest.c_str(), cTotalObjects);
+ const char *pszSubDir = itDest->first.c_str();
+ AssertPtr(pszSubDir);
+ if (!strlen(pszSubDir))
+ RTPrintf("Preparing directory \"%s\" ...\n", pszDestRoot);
else
- RTPrintf("Copying \"%s\" to \"%s\" (%u file(s)) ...\n",
- Utf8Source.c_str(), Utf8Dest.c_str(), cTotalObjects);
+ RTPrintf("Preparing directory \"%s/%s\" ...\n", pszDestRoot,
+ itDest->first.c_str());
}
+ if (!fDryRun)
+ vrc = ctrlCopyPrepareDestDirectory(guest, fHostToGuest,
+ pszDestRoot, itDest->first.c_str(),
+ Utf8UserName.c_str(), Utf8Password.c_str());
+ if (RT_FAILURE(vrc))
+ break;
+ }
+
+ if (RT_FAILURE(vrc))
+ break;
+
+ if (fVerbose)
+ {
+ if (!cObjects)
+ RTPrintf("Warning: Source \"%s\" has no (matching) files to copy, skipping!\n",
+ vecSources[s].mSource.c_str());
+ else
+ RTPrintf("Copying \"%s\" (%u files) ...\n",
+ vecSources[s].mSource.c_str(), cObjects);
+ }
- uint32_t uCurObject = 1;
- RTListForEach(&listToCopy, pNode, DIRECTORYENTRY, Node)
+ /*
+ * Copy files of each destination root directory to the guest.
+ */
+ for (itDest = mapDest.begin(); itDest != mapDest.end(); itDest++)
+ {
+ if (fVerbose && itDest->second.size())
{
- if (!fDryRun)
- {
- if (fVerbose)
- RTPrintf("Copying \"%s\" to \"%s\" (%u/%u) ...\n",
- pNode->pszSourcePath, pNode->pszDestPath, uCurObject, cTotalObjects);
- /* Finally copy the desired file (if no dry run selected). */
- if (!fDryRun)
- vrc = ctrlCopyFileToGuest(guest, fVerbose, pNode->pszSourcePath, pNode->pszDestPath,
- Utf8UserName.c_str(), Utf8Password.c_str(), uFlags);
- }
+ if (itDest->first.isEmpty())
+ RTPrintf("Copying %u files ...\n", itDest->second.size());
+ else
+ RTPrintf("Copying directory \"%s\" (%u files) ...\n",
+ itDest->first.c_str(), itDest->second.size());
+ }
+
+ for (unsigned long l = 0; l < itDest->second.size(); l++)
+ {
+ vrc = ctrlCopyToDestDirectory(guest, fVerbose, fDryRun, fHostToGuest,
+ pszSourceDir,
+ pszDestRoot, itDest->first.c_str() /* Sub directory */,
+ itDest->second[l].mFileName.c_str() /* Filename */,
+ fFlags, Utf8UserName.c_str(), Utf8Password.c_str());
if (RT_FAILURE(vrc))
break;
- uCurObject++;
}
- if (RT_SUCCESS(vrc) && fVerbose)
- RTPrintf("Copy operation successful!\n");
-
- Assert(cTotalObjects >= uCurObject - 1);
- if (cTotalObjects != uCurObject - 1)
- RTPrintf("Warning: %u elements instead of %ld were copied!\n",
- uCurObject - 1, cTotalObjects);
- else if (RT_SUCCESS(vrc) && fVerbose)
- RTPrintf("Copy operation successful!\n");
+
+ if (RT_FAILURE(vrc))
+ break;
}
- ctrlDirectoryListDestroy(&listToCopy);
+
+ if (RT_FAILURE(vrc))
+ break;
}
- ctrlUninitVM(a);
+
+ RTStrFree(pszSourceDir);
}
- if (RT_FAILURE(vrc))
- rc = VBOX_E_IPRT_ERROR;
- return SUCCEEDED(rc) ? 0 : 1;
+ return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
}
-static int handleCtrlCreateDirectory(HandlerArg *a)
+static int handleCtrlCreateDirectory(ComPtr<IGuest> guest, HandlerArg *pArg)
{
+ AssertPtrReturn(pArg, VERR_INVALID_PARAMETER);
+
/*
- * Check the syntax. We can deduce the correct syntax from the number of
- * arguments.
+ * Parse arguments.
+ *
+ * Note! No direct returns here, everyone must go thru the cleanup at the
+ * end of this function.
*/
- if (a->argc < 2) /* At least the directory we want to create should be present :-). */
- return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters");
-
static const RTGETOPTDEF s_aOptions[] =
{
{ "--mode", 'm', RTGETOPT_REQ_UINT32 },
@@ -1223,32 +1552,30 @@ static int handleCtrlCreateDirectory(HandlerArg *a)
int ch;
RTGETOPTUNION ValueUnion;
RTGETOPTSTATE GetState;
- RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ RTGetOptInit(&GetState, pArg->argc, pArg->argv,
+ s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_OPTS_FIRST);
Utf8Str Utf8UserName;
Utf8Str Utf8Password;
- uint32_t uFlags = CreateDirectoryFlag_None;
- uint32_t uMode = 0;
+ uint32_t fFlags = DirectoryCreateFlag_None;
+ uint32_t fDirMode = 0; /* Default mode. */
bool fVerbose = false;
- RTLISTNODE listDirs;
- uint32_t uNumDirs = 0;
- RTListInit(&listDirs);
+ DESTDIRMAP mapDirs;
- int vrc = VINF_SUCCESS;
- bool fUsageOK = true;
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
while ( (ch = RTGetOpt(&GetState, &ValueUnion))
- && RT_SUCCESS(vrc))
+ && rcExit == RTEXITCODE_SUCCESS)
{
/* For options that require an argument, ValueUnion has received the value. */
switch (ch)
{
case 'm': /* Mode */
- uMode = ValueUnion.u32;
+ fDirMode = ValueUnion.u32;
break;
case 'P': /* Create parents */
- uFlags |= CreateDirectoryFlag_Parents;
+ fFlags |= DirectoryCreateFlag_Parents;
break;
case 'p': /* Password */
@@ -1265,218 +1592,218 @@ static int handleCtrlCreateDirectory(HandlerArg *a)
case VINF_GETOPT_NOT_OPTION:
{
- vrc = ctrlDirectoryEntryAppend(NULL, /* No source given */
- ValueUnion.psz, /* Destination */
- &listDirs);
- if (RT_SUCCESS(vrc))
- {
- uNumDirs++;
- if (uNumDirs == UINT32_MAX)
- {
- RTMsgError("Too many directories specified! Aborting.\n");
- vrc = VERR_TOO_MUCH_DATA;
- }
- }
+ mapDirs[ValueUnion.psz]; /* Add destination directory to map. */
break;
}
default:
- return RTGetOptPrintError(ch, &ValueUnion);
+ rcExit = RTGetOptPrintError(ch, &ValueUnion);
+ break;
}
}
- if (!fUsageOK)
- return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters");
+ uint32_t cDirs = mapDirs.size();
+ if (rcExit == RTEXITCODE_SUCCESS && !cDirs)
+ rcExit = errorSyntax(USAGE_GUESTCONTROL, "No directory to create specified!");
- if (!uNumDirs)
- return errorSyntax(USAGE_GUESTCONTROL,
- "No directory to create specified!");
-
- if (Utf8UserName.isEmpty())
- return errorSyntax(USAGE_GUESTCONTROL,
- "No user name specified!");
+ if (rcExit == RTEXITCODE_SUCCESS && Utf8UserName.isEmpty())
+ rcExit = errorSyntax(USAGE_GUESTCONTROL, "No user name specified!");
- HRESULT rc = S_OK;
- ComPtr<IGuest> guest;
- vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest);
- if (RT_SUCCESS(vrc))
+ if (rcExit == RTEXITCODE_SUCCESS)
{
- if (fVerbose && uNumDirs > 1)
- RTPrintf("Creating %ld directories ...\n", uNumDirs);
-
- PDIRECTORYENTRY pNode;
- RTListForEach(&listDirs, pNode, DIRECTORYENTRY, Node)
+ /*
+ * Create the directories.
+ */
+ HRESULT hrc = S_OK;
+ if (fVerbose && cDirs)
+ RTPrintf("Creating %u directories ...\n", cDirs);
+
+ DESTDIRMAPITER it = mapDirs.begin();
+ while (it != mapDirs.end())
{
if (fVerbose)
- RTPrintf("Creating directory \"%s\" ...\n", pNode->pszDestPath);
+ RTPrintf("Creating directory \"%s\" ...\n", it->first.c_str());
- ComPtr<IProgress> progress;
- rc = guest->CreateDirectory(Bstr(pNode->pszDestPath).raw(),
- Bstr(Utf8UserName).raw(), Bstr(Utf8Password).raw(),
- uMode, uFlags, progress.asOutParam());
- if (FAILED(rc))
+ hrc = guest->DirectoryCreate(Bstr(it->first).raw(),
+ Bstr(Utf8UserName).raw(), Bstr(Utf8Password).raw(),
+ fDirMode, fFlags);
+ if (FAILED(hrc))
{
- vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
+ ctrlPrintError(guest, COM_IIDOF(IGuest)); /* Return code ignored, save original rc. */
break;
}
+
+ it++;
}
- ctrlUninitVM(a);
+
+ if (FAILED(hrc))
+ rcExit = RTEXITCODE_FAILURE;
}
- ctrlDirectoryListDestroy(&listDirs);
- if (RT_FAILURE(vrc))
- rc = VBOX_E_IPRT_ERROR;
- return SUCCEEDED(rc) ? 0 : 1;
+ return rcExit;
}
-static int handleCtrlUpdateAdditions(HandlerArg *a)
+static int handleCtrlUpdateAdditions(ComPtr<IGuest> guest, HandlerArg *pArg)
{
+ AssertPtrReturn(pArg, VERR_INVALID_PARAMETER);
+
/*
* Check the syntax. We can deduce the correct syntax from the number of
* arguments.
*/
- if (a->argc < 1) /* At least the VM name should be present :-). */
- return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters");
-
Utf8Str Utf8Source;
bool fVerbose = false;
-/** @todo r=bird: Use RTGetOpt here, no new code using strcmp-if-switching! */
- /* Iterate through all possible commands (if available). */
- bool usageOK = true;
- for (int i = 1; usageOK && i < a->argc; i++)
+ static const RTGETOPTDEF s_aOptions[] =
{
- if (!strcmp(a->argv[i], "--source"))
+ { "--source", 's', RTGETOPT_REQ_STRING },
+ { "--verbose", 'v', RTGETOPT_REQ_NOTHING }
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, pArg->argc, pArg->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
+
+ int vrc = VINF_SUCCESS;
+ while ( (ch = RTGetOpt(&GetState, &ValueUnion))
+ && RT_SUCCESS(vrc))
+ {
+ switch (ch)
{
- if (i + 1 >= a->argc)
- usageOK = false;
- else
- {
- Utf8Source = a->argv[i + 1];
- ++i;
- }
+ case 's':
+ Utf8Source = ValueUnion.psz;
+ break;
+
+ case 'v':
+ fVerbose = true;
+ break;
+
+ default:
+ return RTGetOptPrintError(ch, &ValueUnion);
}
- else if (!strcmp(a->argv[i], "--verbose"))
- fVerbose = true;
- else
- return errorSyntax(USAGE_GUESTCONTROL,
- "Invalid parameter '%s'", Utf8Str(a->argv[i]).c_str());
}
- if (!usageOK)
- return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters");
-
- HRESULT rc = S_OK;
- ComPtr<IGuest> guest;
- int vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest);
- if (RT_SUCCESS(vrc))
- {
- if (fVerbose)
- RTPrintf("Updating Guest Additions of machine \"%s\" ...\n", a->argv[0]);
+ if (fVerbose)
+ RTPrintf("Updating Guest Additions ...\n");
#ifdef DEBUG_andy
- if (Utf8Source.isEmpty())
- Utf8Source = "c:\\Downloads\\VBoxGuestAdditions-r67158.iso";
+ if (Utf8Source.isEmpty())
+ Utf8Source = "c:\\Downloads\\VBoxGuestAdditions-r67158.iso";
#endif
- /* Determine source if not set yet. */
- if (Utf8Source.isEmpty())
- {
- char strTemp[RTPATH_MAX];
- vrc = RTPathAppPrivateNoArch(strTemp, sizeof(strTemp));
- AssertRC(vrc);
- Utf8Str Utf8Src1 = Utf8Str(strTemp).append("/VBoxGuestAdditions.iso");
-
- vrc = RTPathExecDir(strTemp, sizeof(strTemp));
- AssertRC(vrc);
- Utf8Str Utf8Src2 = Utf8Str(strTemp).append("/additions/VBoxGuestAdditions.iso");
-
- /* Check the standard image locations */
- if (RTFileExists(Utf8Src1.c_str()))
- Utf8Source = Utf8Src1;
- else if (RTFileExists(Utf8Src2.c_str()))
- Utf8Source = Utf8Src2;
- else
- {
- RTMsgError("Source could not be determined! Please use --source to specify a valid source.\n");
- vrc = VERR_FILE_NOT_FOUND;
- }
- }
- else if (!RTFileExists(Utf8Source.c_str()))
+
+ /* Determine source if not set yet. */
+ if (Utf8Source.isEmpty())
+ {
+ char strTemp[RTPATH_MAX];
+ vrc = RTPathAppPrivateNoArch(strTemp, sizeof(strTemp));
+ AssertRC(vrc);
+ Utf8Str Utf8Src1 = Utf8Str(strTemp).append("/VBoxGuestAdditions.iso");
+
+ vrc = RTPathExecDir(strTemp, sizeof(strTemp));
+ AssertRC(vrc);
+ Utf8Str Utf8Src2 = Utf8Str(strTemp).append("/additions/VBoxGuestAdditions.iso");
+
+ /* Check the standard image locations */
+ if (RTFileExists(Utf8Src1.c_str()))
+ Utf8Source = Utf8Src1;
+ else if (RTFileExists(Utf8Src2.c_str()))
+ Utf8Source = Utf8Src2;
+ else
{
- RTMsgError("Source \"%s\" does not exist!\n", Utf8Source.c_str());
+ RTMsgError("Source could not be determined! Please use --source to specify a valid source.\n");
vrc = VERR_FILE_NOT_FOUND;
}
+ }
+ else if (!RTFileExists(Utf8Source.c_str()))
+ {
+ RTMsgError("Source \"%s\" does not exist!\n", Utf8Source.c_str());
+ vrc = VERR_FILE_NOT_FOUND;
+ }
- if (RT_SUCCESS(vrc))
- {
- if (fVerbose)
- RTPrintf("Using source: %s\n", Utf8Source.c_str());
+ if (RT_SUCCESS(vrc))
+ {
+ if (fVerbose)
+ RTPrintf("Using source: %s\n", Utf8Source.c_str());
- ComPtr<IProgress> progress;
- CHECK_ERROR(guest, UpdateGuestAdditions(Bstr(Utf8Source).raw(),
- /* Wait for whole update process to complete. */
- AdditionsUpdateFlag_None,
- progress.asOutParam()));
+ HRESULT rc = S_OK;
+ ComPtr<IProgress> progress;
+ CHECK_ERROR(guest, UpdateGuestAdditions(Bstr(Utf8Source).raw(),
+ /* Wait for whole update process to complete. */
+ AdditionsUpdateFlag_None,
+ progress.asOutParam()));
+ if (FAILED(rc))
+ vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
+ else
+ {
+ rc = showProgress(progress);
if (FAILED(rc))
- vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
- else
- {
- rc = showProgress(progress);
- if (FAILED(rc))
- vrc = ctrlPrintProgressError(progress);
- else if (fVerbose)
- RTPrintf("Guest Additions update successful.\n");
- }
+ vrc = ctrlPrintProgressError(progress);
+ else if (fVerbose)
+ RTPrintf("Guest Additions update successful.\n");
}
- ctrlUninitVM(a);
}
- if (RT_FAILURE(vrc))
- rc = VBOX_E_IPRT_ERROR;
- return SUCCEEDED(rc) ? 0 : 1;
+ return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
}
/**
* Access the guest control store.
*
- * @returns 0 on success, 1 on failure
+ * @returns program exit code.
* @note see the command line API description for parameters
*/
-int handleGuestControl(HandlerArg *a)
+int handleGuestControl(HandlerArg *pArg)
{
- HandlerArg arg = *a;
- arg.argc = a->argc - 1;
- arg.argv = a->argv + 1;
+ AssertPtrReturn(pArg, VERR_INVALID_PARAMETER);
- if (a->argc <= 0)
- return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters");
+ HandlerArg arg = *pArg;
+ arg.argc = pArg->argc - 2; /* Skip VM name and sub command. */
+ arg.argv = pArg->argv + 2; /* Same here. */
- /* switch (cmd) */
- if ( !RTStrICmp(a->argv[0], "exec")
- || !RTStrICmp(a->argv[0], "execute"))
- {
- return handleCtrlExecProgram(&arg);
- }
- else if ( !RTStrICmp(a->argv[0], "copyto")
- || !RTStrICmp(a->argv[0], "cp"))
- {
- return handleCtrlCopyTo(&arg);
- }
- else if ( !RTStrICmp(a->argv[0], "createdirectory")
- || !RTStrICmp(a->argv[0], "createdir")
- || !RTStrICmp(a->argv[0], "mkdir")
- || !RTStrICmp(a->argv[0], "md"))
- {
- return handleCtrlCreateDirectory(&arg);
- }
- else if ( !RTStrICmp(a->argv[0], "updateadditions")
- || !RTStrICmp(a->argv[0], "updateadds"))
+ ComPtr<IGuest> guest;
+ int vrc = ctrlInitVM(pArg, pArg->argv[0] /* VM Name */, &guest);
+ if (RT_SUCCESS(vrc))
{
- return handleCtrlUpdateAdditions(&arg);
- }
+ int rcExit;
+ if ( !strcmp(pArg->argv[1], "exec")
+ || !strcmp(pArg->argv[1], "execute"))
+ {
+ rcExit = handleCtrlExecProgram(guest, &arg);
+ }
+#if 0
+ else if (!strcmp(pArg->argv[1], "copyfrom"))
+ {
+ rcExit = handleCtrlCopyTo(guest, &arg,
+ false /* Guest to host */);
+ }
+#endif
+ else if ( !strcmp(pArg->argv[1], "copyto")
+ || !strcmp(pArg->argv[1], "cp"))
+ {
+ rcExit = handleCtrlCopyTo(guest, &arg,
+ true /* Host to guest */);
+ }
+ else if ( !strcmp(pArg->argv[1], "createdirectory")
+ || !strcmp(pArg->argv[1], "createdir")
+ || !strcmp(pArg->argv[1], "mkdir")
+ || !strcmp(pArg->argv[1], "md"))
+ {
+ rcExit = handleCtrlCreateDirectory(guest, &arg);
+ }
+ else if ( !strcmp(pArg->argv[1], "updateadditions")
+ || !strcmp(pArg->argv[1], "updateadds"))
+ {
+ rcExit = handleCtrlUpdateAdditions(guest, &arg);
+ }
+ else
+ rcExit = errorSyntax(USAGE_GUESTCONTROL, "No sub command specified!");
- /* default: */
- return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters");
+ ctrlUninitVM(pArg);
+ return rcExit;
+ }
+ return RTEXITCODE_FAILURE;
}
#endif /* !VBOX_ONLY_DOCS */
+
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp
index 6d985f72a..5933d3288 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageGuestProp.cpp $ */
+/* $Id: VBoxManageGuestProp.cpp 35951 2011-02-14 08:15:55Z vboxsync $ */
/** @file
* VBoxManage - Implementation of guestproperty command.
*/
@@ -372,6 +372,11 @@ int handleGuestProperty(HandlerArg *a)
arg.argc = a->argc - 1;
arg.argv = a->argv + 1;
+ /** @todo This command does not follow the syntax where the <uuid|vmname>
+ * comes between the command and subcommand. The commands controlvm,
+ * snapshot and debugvm puts it between.
+ */
+
if (a->argc == 0)
return errorSyntax(USAGE_GUESTPROPERTY, "Incorrect parameters");
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
index 4c9344919..e051dfe65 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxManageHelp.cpp $ */
+/* $Id: VBoxManageHelp.cpp 38055 2011-07-19 08:55:42Z vboxsync $ */
/** @file
* VBoxManage - help and other message output.
*/
/*
- * 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;
@@ -150,6 +150,11 @@ void printUsage(USAGECATEGORY u64Cmd, PRTSTREAM pStrm)
" [--pagefusion on|off]\n"
" [--vram <vramsize in MB>]\n"
" [--acpi on|off]\n"
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ " [--pciattach 03:04.0]\n"
+ " [--pciattach 03:04.0@02:01.0]\n"
+ " [--pcidetach 03:04.0]\n"
+#endif
" [--ioapic on|off]\n"
" [--pae on|off]\n"
" [--hpet on|off]\n"
@@ -188,10 +193,8 @@ void printUsage(USAGECATEGORY u64Cmd, PRTSTREAM pStrm)
#if defined(VBOX_WITH_NETFLT)
"|hostonly"
#endif
-#ifdef VBOX_WITH_VDE
"|\n"
- " vde"
-#endif
+ " generic"
"]\n"
" [--nictype<1-N> Am79C970A|Am79C973"
#ifdef VBOX_WITH_E1000
@@ -204,17 +207,18 @@ void printUsage(USAGECATEGORY u64Cmd, PRTSTREAM pStrm)
" [--cableconnected<1-N> on|off]\n"
" [--nictrace<1-N> on|off]\n"
" [--nictracefile<1-N> <filename>]\n"
+ " [--nicproperty<1-N> name=[value]]\n"
" [--nicspeed<1-N> <kbps>]\n"
" [--nicbootprio<1-N> <priority>]\n"
+ " [--nicpromisc<1-N> deny|allow-vms|allow-all]\n"
+ " [--nicbandwidthgroup<1-N> none|<name>]\n"
" [--bridgeadapter<1-N> none|<devicename>]\n"
#if defined(VBOX_WITH_NETFLT)
" [--hostonlyadapter<1-N> none|<devicename>]\n"
#endif
" [--intnet<1-N> <network name>]\n"
" [--natnet<1-N> <network>|default]\n"
-#ifdef VBOX_WITH_VDE
- " [--vdenet<1-N> <network>|default]\n"
-#endif
+ " [--nicgenericdrv<1-N> <driver>\n"
" [--natsettings<1-N> [<mtu>],[<socksnd>],\n"
" [<sockrcv>],[<tcpsnd>],\n"
" [<tcprcv>]]\n"
@@ -224,6 +228,7 @@ void printUsage(USAGECATEGORY u64Cmd, PRTSTREAM pStrm)
" [--nattftpprefix<1-N> <prefix>]\n"
" [--nattftpfile<1-N> <file>]\n"
" [--nattftpserver<1-N> <ip>]\n"
+ " [--natbindip<1-N> <ip>\n"
" [--natdnspassdomain<1-N> on|off]\n"
" [--natdnsproxy<1-N> on|off]\n"
" [--natdnshostresolver<1-N> on|off]\n"
@@ -325,9 +330,25 @@ void printUsage(USAGECATEGORY u64Cmd, PRTSTREAM pStrm)
"\n");
}
+ if (u64Cmd & USAGE_CLONEVM)
+ RTStrmPrintf(pStrm,
+ "VBoxManage clonevm <uuid>|<name>\n"
+ " [--snapshot <uuid>|<name>]\n"
+ " [--mode machine|all]\n"
+ " [--options link|keepallmacs|keepnatmacs|\n"
+ " keepdisknames]\n"
+ " [--name <name>]\n"
+ " [--basefolder <basefolder>]\n"
+ " [--uuid <uuid>]\n"
+ " [--register]\n"
+ "\n");
+
if (u64Cmd & USAGE_IMPORTAPPLIANCE)
RTStrmPrintf(pStrm,
- "VBoxManage import <ovf/ova> [--dry-run|-n] [more options]\n"
+ "VBoxManage import <ovf/ova>\n"
+ " [--dry-run|-n]\n"
+ " [--options keepallmacs|keepnatmacs]\n"
+ " [more options]\n"
" (run with -n to have options displayed\n"
" for a particular OVF)\n\n");
@@ -368,14 +389,16 @@ void printUsage(USAGECATEGORY u64Cmd, PRTSTREAM pStrm)
" keyboardputscancode <hex> [<hex> ...]|\n"
" setlinkstate<1-N> on|off |\n"
#if defined(VBOX_WITH_NETFLT)
- " nic<1-N> null|nat|bridged|intnet|hostonly\n"
+ " nic<1-N> null|nat|bridged|intnet|hostonly|generic"
+ "\n"
" [<devicename>] |\n"
-#else /* !RT_OS_LINUX && !RT_OS_DARWIN */
- " nic<1-N> null|nat|bridged|intnet\n"
+#else /* !VBOX_WITH_NETFLT */
+ " nic<1-N> null|nat|bridged|intnet|generic\n"
" [<devicename>] |\n"
-#endif /* !RT_OS_LINUX && !RT_OS_DARWIN */
+#endif /* !VBOX_WITH_NETFLT */
" nictrace<1-N> on|off\n"
" nictracefile<1-N> <filename>\n"
+ " nicproperty<1-N> name=[value]\n"
" natpf<1-N> [<rulename>],tcp|udp,[<hostip>],\n"
" <hostport>,[<guestip>],<guestport>\n"
" natpf<1-N> delete <rulename>\n"
@@ -435,20 +458,24 @@ void printUsage(USAGECATEGORY u64Cmd, PRTSTREAM pStrm)
RTStrmPrintf(pStrm,
"VBoxManage storageattach <uuid|vmname>\n"
" --storagectl <name>\n"
- " --port <number>\n"
- " --device <number>\n"
+ " [--port <number>]\n"
+ " [--device <number>]\n"
" [--type dvddrive|hdd|fdd]\n"
" [--medium none|emptydrive|\n"
" <uuid>|<filename>|host:<drive>|iscsi]\n"
" [--mtype normal|writethrough|immutable|shareable|\n"
" readonly|multiattach]\n"
" [--comment <text>]\n"
+ " [--setuuid <uuid>]\n"
+ " [--setparentuuid <uuid>]\n"
" [--passthrough on|off]\n"
+ " [--tempeject on|off]\n"
+ " [--nonrotational on|off]\n"
" [--bandwidthgroup <name>]\n"
" [--forceunmount]\n"
" [--server <name>|<ip>]\n"
" [--target <target>]\n"
- " [--port <port>]\n"
+ " [--tport <port>]\n"
" [--lun <lun>]\n"
" [--encodedlun <lun>]\n"
" [--username <username>]\n"
@@ -504,7 +531,7 @@ void printUsage(USAGECATEGORY u64Cmd, PRTSTREAM pStrm)
if (u64Cmd & USAGE_CLONEHD)
RTStrmPrintf(pStrm,
- "VBoxManage clonehd <uuid>|<filename> <outputfile>\n"
+ "VBoxManage clonehd <uuid>|<filename> <uuid>|<outputfile>\n"
" [--format VDI|VMDK|VHD|RAW|<other>]\n"
" [--variant Standard,Fixed,Split2G,Stream,ESX]\n"
" [--existing]\n"
@@ -683,7 +710,7 @@ void printUsage(USAGECATEGORY u64Cmd, PRTSTREAM pStrm)
if (u64Cmd & USAGE_EXTPACK)
{
RTStrmPrintf(pStrm,
- "VBoxManage extpack install <tarball> |\n"
+ "VBoxManage extpack install [--replace] <tarball> |\n"
" uninstall [--force] <name> |\n"
" cleanup\n"
"\n");
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageHostonly.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageHostonly.cpp
index 31b456507..7c417aba8 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageHostonly.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageHostonly.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageHostonly.cpp $ */
+/* $Id: VBoxManageHostonly.cpp 35330 2010-12-24 18:05:33Z vboxsync $ */
/** @file
* VBoxManage - Implementation of hostonlyif command.
*/
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
index 9c5580077..8a2159cde 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxManageInfo.cpp $ */
+/* $Id: VBoxManageInfo.cpp 37778 2011-07-05 12:10:49Z vboxsync $ */
/** @file
* VBoxManage - The 'showvminfo' command and helper routines.
*/
/*
- * 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;
@@ -29,6 +29,10 @@
#include <VBox/com/VirtualBox.h>
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+#include <VBox/pci.h>
+#endif
+
#include <VBox/log.h>
#include <iprt/stream.h>
#include <iprt/time.h>
@@ -110,8 +114,7 @@ static void makeTimeStr(char *s, int cb, int64_t millies)
t.u8Hour, t.u8Minute, t.u8Second);
}
-
-const char *stateToName(MachineState_T machineState, bool fShort)
+const char *machineStateToName(MachineState_T machineState, bool fShort)
{
switch (machineState)
{
@@ -156,8 +159,36 @@ const char *stateToName(MachineState_T machineState, bool fShort)
case MachineState_SettingUp:
return fShort ? "settingup" : "setting up";
default:
- return "unknown";
+ break;
+ }
+ return "unknown";
+}
+
+const char *facilityStateToName(AdditionsFacilityStatus_T faStatus, bool fShort)
+{
+ switch (faStatus)
+ {
+ case AdditionsFacilityStatus_Inactive:
+ return fShort ? "inactive" : "not active";
+ case AdditionsFacilityStatus_Paused:
+ return "paused";
+ case AdditionsFacilityStatus_PreInit:
+ return fShort ? "preinit" : "pre-initializing";
+ case AdditionsFacilityStatus_Init:
+ return fShort ? "init" : "initializing";
+ case AdditionsFacilityStatus_Active:
+ return fShort ? "active" : "active/running";
+ case AdditionsFacilityStatus_Terminating:
+ return "terminating";
+ case AdditionsFacilityStatus_Terminated:
+ return "terminated";
+ case AdditionsFacilityStatus_Failed:
+ return "failed";
+ case AdditionsFacilityStatus_Unknown:
+ default:
+ break;
}
+ return "unknown";
}
/* Disable global optimizations for MSC 8.0/64 to make it compile in reasonable
@@ -306,6 +337,13 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
else
RTPrintf("VRAM size: %uMB\n", vramSize);
+ ULONG cpuCap;
+ rc = machine->COMGETTER(CPUExecutionCap)(&cpuCap);
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("cpuexecutioncap=%u\n", cpuCap);
+ else
+ RTPrintf("CPU exec cap: %u%%\n", cpuCap);
+
BOOL fHpetEnabled;
machine->COMGETTER(HpetEnabled)(&fHpetEnabled);
if (details == VMINFO_MACHINEREADABLE)
@@ -568,7 +606,7 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
MachineState_T machineState;
rc = machine->COMGETTER(State)(&machineState);
- const char *pszState = stateToName(machineState, details == VMINFO_MACHINEREADABLE /*=fShort*/);
+ const char *pszState = machineStateToName(machineState, details == VMINFO_MACHINEREADABLE /*=fShort*/);
LONG64 stateSince;
machine->COMGETTER(LastStateChange)(&stateSince);
@@ -734,17 +772,26 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
{
for (ULONG k = 0; k < cDevices; ++ k)
{
+ ComPtr<IMediumAttachment> mediumAttach;
+ machine->GetMediumAttachment(storageCtlName.raw(),
+ i, k,
+ mediumAttach.asOutParam());
+ BOOL fIsEjected = FALSE;
+ BOOL fTempEject = FALSE;
+ DeviceType_T devType = DeviceType_Null;
+ if (mediumAttach)
+ {
+ mediumAttach->COMGETTER(TemporaryEject)(&fTempEject);
+ mediumAttach->COMGETTER(IsEjected)(&fIsEjected);
+ mediumAttach->COMGETTER(Type)(&devType);
+ }
rc = machine->GetMedium(storageCtlName.raw(), i, k,
medium.asOutParam());
if (SUCCEEDED(rc) && medium)
{
- BOOL fPassthrough;
- ComPtr<IMediumAttachment> mediumAttach;
+ BOOL fPassthrough = FALSE;
- rc = machine->GetMediumAttachment(storageCtlName.raw(),
- i, k,
- mediumAttach.asOutParam());
- if (SUCCEEDED(rc) && mediumAttach)
+ if (mediumAttach)
mediumAttach->COMGETTER(Passthrough)(&fPassthrough);
medium->COMGETTER(Location)(filePath.asOutParam());
@@ -759,6 +806,13 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
if (fPassthrough)
RTPrintf("\"%lS-dvdpassthrough\"=\"%s\"\n", storageCtlName.raw(),
fPassthrough ? "on" : "off");
+ if (devType == DeviceType_DVD)
+ {
+ RTPrintf("\"%lS-tempeject\"=\"%s\"\n", storageCtlName.raw(),
+ fTempEject ? "on" : "off");
+ RTPrintf("\"%lS-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
+ fIsEjected ? "on" : "off");
+ }
}
else
{
@@ -767,15 +821,31 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
Utf8Str(uuid).c_str());
if (fPassthrough)
RTPrintf(" (passthrough enabled)");
+ if (fTempEject)
+ RTPrintf(" (temp eject)");
+ if (fIsEjected)
+ RTPrintf(" (ejected)");
RTPrintf("\n");
}
}
else if (SUCCEEDED(rc))
{
if (details == VMINFO_MACHINEREADABLE)
+ {
RTPrintf("\"%lS-%d-%d\"=\"emptydrive\"\n", storageCtlName.raw(), i, k);
+ if (devType == DeviceType_DVD)
+ RTPrintf("\"%lS-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
+ fIsEjected ? "on" : "off");
+ }
else
- RTPrintf("%lS (%d, %d): Empty\n", storageCtlName.raw(), i, k);
+ {
+ RTPrintf("%lS (%d, %d): Empty", storageCtlName.raw(), i, k);
+ if (fTempEject)
+ RTPrintf(" (temp eject)");
+ if (fIsEjected)
+ RTPrintf(" (ejected)");
+ RTPrintf("\n");
+ }
}
else
{
@@ -787,10 +857,8 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
}
/* get the maximum amount of NICS */
- ComPtr<ISystemProperties> sysProps;
- virtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
- ULONG maxNICs = 0;
- sysProps->COMGETTER(NetworkAdapterCount)(&maxNICs);
+ ULONG maxNICs = getMaxNics(virtualBox, machine);
+
for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
{
ComPtr<INetworkAdapter> nic;
@@ -823,6 +891,7 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
else
strAttachment = "none";
break;
+
case NetworkAttachmentType_NAT:
{
Bstr strNetwork;
@@ -915,15 +984,16 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
else
{
strAttachment = "NAT";
- strNatSettings = Utf8StrFmt("NIC %d Settings: MTU: %d, Socket( send: %d, receive: %d), TCP Window( send:%d, receive: %d)\n",
+ strNatSettings = Utf8StrFmt("NIC %d Settings: MTU: %d, Socket (send: %d, receive: %d), TCP Window (send:%d, receive: %d)\n",
currentNIC + 1, mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64 , tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
}
break;
}
+
case NetworkAttachmentType_Bridged:
{
Bstr strBridgeAdp;
- nic->COMGETTER(HostInterface)(strBridgeAdp.asOutParam());
+ nic->COMGETTER(BridgedInterface)(strBridgeAdp.asOutParam());
if (details == VMINFO_MACHINEREADABLE)
{
RTPrintf("bridgeadapter%d=\"%lS\"\n", currentNIC + 1, strBridgeAdp.raw());
@@ -933,6 +1003,7 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
strAttachment = Utf8StrFmt("Bridged Interface '%lS'", strBridgeAdp.raw());
break;
}
+
case NetworkAttachmentType_Internal:
{
Bstr strNetwork;
@@ -946,11 +1017,11 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
strAttachment = Utf8StrFmt("Internal Network '%s'", Utf8Str(strNetwork).c_str());
break;
}
-#if defined(VBOX_WITH_NETFLT)
+
case NetworkAttachmentType_HostOnly:
{
Bstr strHostonlyAdp;
- nic->COMGETTER(HostInterface)(strHostonlyAdp.asOutParam());
+ nic->COMGETTER(HostOnlyInterface)(strHostonlyAdp.asOutParam());
if (details == VMINFO_MACHINEREADABLE)
{
RTPrintf("hostonlyadapter%d=\"%lS\"\n", currentNIC + 1, strHostonlyAdp.raw());
@@ -960,22 +1031,36 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
strAttachment = Utf8StrFmt("Host-only Interface '%lS'", strHostonlyAdp.raw());
break;
}
-#endif
-#ifdef VBOX_WITH_VDE
- case NetworkAttachmentType_VDE:
+ case NetworkAttachmentType_Generic:
{
- Bstr strVDEAdp;
- nic->COMGETTER(VDENetwork)(strVDEAdp.asOutParam());
+ Bstr strGenericDriver;
+ nic->COMGETTER(GenericDriver)(strGenericDriver.asOutParam());
if (details == VMINFO_MACHINEREADABLE)
{
- RTPrintf("vdenet%d=\"%lS\"\n", currentNIC + 1, strVDEAdp.raw());
- strAttachment = "VDE";
+ RTPrintf("generic%d=\"%lS\"\n", currentNIC + 1, strGenericDriver.raw());
+ strAttachment = "Generic";
}
else
- strAttachment = Utf8StrFmt("VDE Network '%lS'", strVDEAdp.raw());
+ {
+ strAttachment = Utf8StrFmt("Generic '%lS'", strGenericDriver.raw());
+
+ // show the generic properties
+ com::SafeArray<BSTR> aProperties;
+ com::SafeArray<BSTR> aValues;
+ rc = nic->GetProperties(NULL,
+ ComSafeArrayAsOutParam(aProperties),
+ ComSafeArrayAsOutParam(aValues));
+ if (SUCCEEDED(rc))
+ {
+ strAttachment += " { ";
+ for (unsigned i = 0; i < aProperties.size(); ++i)
+ strAttachment += Utf8StrFmt(!i ? "%lS='%lS'" : ", %lS='%lS'",
+ aProperties[i], aValues[i]);
+ strAttachment += " }";
+ }
+ }
break;
}
-#endif
default:
strAttachment = "unknown";
break;
@@ -985,6 +1070,18 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
BOOL fConnected;
nic->COMGETTER(CableConnected)(&fConnected);
+ /* promisc policy */
+ NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
+ CHECK_ERROR2_RET(nic, COMGETTER(PromiscModePolicy)(&enmPromiscModePolicy), hrcCheck);
+ const char *pszPromiscuousGuestPolicy;
+ switch (enmPromiscModePolicy)
+ {
+ case NetworkAdapterPromiscModePolicy_Deny: pszPromiscuousGuestPolicy = "deny"; break;
+ case NetworkAdapterPromiscModePolicy_AllowNetwork: pszPromiscuousGuestPolicy = "allow-vms"; break;
+ case NetworkAdapterPromiscModePolicy_AllowAll: pszPromiscuousGuestPolicy = "allow-all"; break;
+ default: AssertFailedReturn(VERR_INTERNAL_ERROR_4);
+ }
+
/* trace stuff */
BOOL fTraceEnabled;
nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
@@ -992,35 +1089,22 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
nic->COMGETTER(TraceFile)(traceFile.asOutParam());
/* NIC type */
- Utf8Str strNICType;
NetworkAdapterType_T NICType;
nic->COMGETTER(AdapterType)(&NICType);
- switch (NICType) {
- case NetworkAdapterType_Am79C970A:
- strNICType = "Am79C970A";
- break;
- case NetworkAdapterType_Am79C973:
- strNICType = "Am79C973";
- break;
+ const char *pszNICType;
+ switch (NICType)
+ {
+ case NetworkAdapterType_Am79C970A: pszNICType = "Am79C970A"; break;
+ case NetworkAdapterType_Am79C973: pszNICType = "Am79C973"; break;
#ifdef VBOX_WITH_E1000
- case NetworkAdapterType_I82540EM:
- strNICType = "82540EM";
- break;
- case NetworkAdapterType_I82543GC:
- strNICType = "82543GC";
- break;
- case NetworkAdapterType_I82545EM:
- strNICType = "82545EM";
- break;
+ case NetworkAdapterType_I82540EM: pszNICType = "82540EM"; break;
+ case NetworkAdapterType_I82543GC: pszNICType = "82543GC"; break;
+ case NetworkAdapterType_I82545EM: pszNICType = "82545EM"; break;
#endif
#ifdef VBOX_WITH_VIRTIO
- case NetworkAdapterType_Virtio:
- strNICType = "virtio";
- break;
-#endif /* VBOX_WITH_VIRTIO */
- default:
- strNICType = "unknown";
- break;
+ case NetworkAdapterType_Virtio: pszNICType = "virtio"; break;
+#endif
+ default: AssertFailed(); pszNICType = "unknown"; break;
}
/* reported line speed */
@@ -1038,14 +1122,15 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
RTPrintf("nic%d=\"%s\"\n", currentNIC + 1, strAttachment.c_str());
}
else
- RTPrintf("NIC %d: MAC: %lS, Attachment: %s, Cable connected: %s, Trace: %s (file: %lS), Type: %s, Reported speed: %d Mbps, Boot priority: %d\n",
+ RTPrintf("NIC %u: MAC: %lS, Attachment: %s, Cable connected: %s, Trace: %s (file: %lS), Type: %s, Reported speed: %d Mbps, Boot priority: %d, Promisc Policy: %s\n",
currentNIC + 1, strMACAddress.raw(), strAttachment.c_str(),
fConnected ? "on" : "off",
fTraceEnabled ? "on" : "off",
traceFile.isEmpty() ? Bstr("none").raw() : traceFile.raw(),
- strNICType.c_str(),
+ pszNICType,
ulLineSpeed / 1000,
- (int)ulBootPriority);
+ (int)ulBootPriority,
+ pszPromiscuousGuestPolicy);
if (strNatSettings.length())
RTPrintf(strNatSettings.c_str());
if (strNatForwardings.length())
@@ -1121,6 +1206,9 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
RTPrintf("Keyboard Device: %s\n", pszHid);
/* get the maximum amount of UARTs */
+ ComPtr<ISystemProperties> sysProps;
+ virtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
+
ULONG maxUARTs = 0;
sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
@@ -1770,6 +1858,46 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
}
} /* USB */
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ /* Host PCI passthrough devices */
+ {
+ SafeIfaceArray <IPciDeviceAttachment> assignments;
+ rc = machine->COMGETTER(PciDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
+ if (SUCCEEDED(rc))
+ {
+ if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
+ {
+ RTPrintf("\nAttached physical PCI devices:\n\n");
+ }
+
+ for (size_t index = 0; index < assignments.size(); ++index)
+ {
+ ComPtr<IPciDeviceAttachment> Assignment = assignments[index];
+ char szHostPciAddress[32], szGuestPciAddress[32];
+ LONG iHostPciAddress = -1, iGuestPciAddress = -1;
+ Bstr DevName;
+
+ Assignment->COMGETTER(Name)(DevName.asOutParam());
+ Assignment->COMGETTER(HostAddress)(&iHostPciAddress);
+ Assignment->COMGETTER(GuestAddress)(&iGuestPciAddress);
+ PciBusAddress().fromLong(iHostPciAddress).format(szHostPciAddress, sizeof(szHostPciAddress));
+ PciBusAddress().fromLong(iGuestPciAddress).format(szGuestPciAddress, sizeof(szGuestPciAddress));
+
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("AttachedHostPci=%s,%s\n", szHostPciAddress, szGuestPciAddress);
+ else
+ RTPrintf(" Host device %lS at %s attached as %s\n", DevName.raw(), szHostPciAddress, szGuestPciAddress);
+ }
+
+ if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
+ {
+ RTPrintf("\n");
+ }
+ }
+ }
+ /* Host PCI passthrough devices */
+#endif
+
/*
* Shared folders
*/
@@ -2003,6 +2131,16 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
if (details != VMINFO_MACHINEREADABLE)
RTPrintf("Guest:\n\n");
+ ULONG guestVal;
+ rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
+ if (SUCCEEDED(rc))
+ {
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
+ else
+ RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
+ }
+
if (console)
{
ComPtr<IGuest> guest;
@@ -2030,30 +2168,56 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
RTPrintf("Additions run level: %u\n", guestRunLevel);
}
- if (details == VMINFO_FULL)
+ rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
+ if ( SUCCEEDED(rc)
+ && !guestString.isEmpty())
+ {
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("GuestAdditionsVersion=\"%lS\"\n", guestString.raw());
+ else
+ RTPrintf("Additions version: %lS\n\n", guestString.raw());
+ }
+
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("\nGuest Facilities:\n\n");
+
+ /* Print information about known Guest Additions facilities: */
+ SafeIfaceArray <IAdditionsFacility> collFac;
+ CHECK_ERROR_RET(guest, COMGETTER(Facilities)(ComSafeArrayAsOutParam(collFac)), rc);
+ LONG64 lLastUpdatedMS;
+ char szLastUpdated[32];
+ AdditionsFacilityStatus_T curStatus;
+ for (size_t index = 0; index < collFac.size(); ++index)
{
- rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
- if ( SUCCEEDED(rc)
- && !guestString.isEmpty())
+ ComPtr<IAdditionsFacility> fac = collFac[index];
+ if (fac)
{
- if (details == VMINFO_MACHINEREADABLE)
- RTPrintf("GuestAdditionsVersion=\"%lS\"\n", guestString.raw());
+ CHECK_ERROR_RET(fac, COMGETTER(Name)(guestString.asOutParam()), rc);
+ if (!guestString.isEmpty())
+ {
+ CHECK_ERROR_RET(fac, COMGETTER(Status)(&curStatus), rc);
+ CHECK_ERROR_RET(fac, COMGETTER(LastUpdated)(&lLastUpdatedMS), rc);
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("GuestAdditionsFacility_%lS=%u,%lld\n",
+ guestString.raw(), curStatus, lLastUpdatedMS);
+ else
+ {
+ makeTimeStr(szLastUpdated, sizeof(szLastUpdated), lLastUpdatedMS);
+ RTPrintf("Facility \"%lS\": %s (last update: %s)\n",
+ guestString.raw(), facilityStateToName(curStatus, false /* No short naming */), szLastUpdated);
+ }
+ }
else
- RTPrintf("Additions version: %lS\n\n", guestString.raw());
+ AssertMsgFailed(("Facility with undefined name retrieved!\n"));
}
+ else
+ AssertMsgFailed(("Invalid facility returned!\n"));
}
+ if (!collFac.size() && details != VMINFO_MACHINEREADABLE)
+ RTPrintf("No active facilities.\n");
}
}
- ULONG guestVal;
- rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
- if (SUCCEEDED(rc))
- {
- if (details == VMINFO_MACHINEREADABLE)
- RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
- else
- RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
- }
if (details != VMINFO_MACHINEREADABLE)
RTPrintf("\n");
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageList.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageList.cpp
index 2f60a2248..9776711c6 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageList.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageList.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxManageList.cpp $ */
+/* $Id: VBoxManageList.cpp 37244 2011-05-30 08:28:07Z vboxsync $ */
/** @file
* VBoxManage - The 'list' command.
*/
/*
- * 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;
@@ -832,6 +832,9 @@ static HRESULT produceList(enum enmListType enmCommand, bool fOptLong, const Com
ULONG ulValue;
LONG64 i64Value;
+ rptrVirtualBox->COMGETTER(APIVersion)(str.asOutParam());
+ RTPrintf("API version: %ls\n", str.raw());
+
systemProperties->COMGETTER(MinGuestRAM)(&ulValue);
RTPrintf("Minimum guest RAM size: %u Megabytes\n", ulValue);
systemProperties->COMGETTER(MaxGuestRAM)(&ulValue);
@@ -846,14 +849,16 @@ static HRESULT produceList(enum enmListType enmCommand, bool fOptLong, const Com
RTPrintf("Maximum guest CPU count: %u\n", ulValue);
systemProperties->COMGETTER(InfoVDSize)(&i64Value);
RTPrintf("Virtual disk limit (info): %lld Bytes\n", i64Value);
- systemProperties->COMGETTER(NetworkAdapterCount)(&ulValue);
- RTPrintf("Maximum Network Adapter count: %u\n", ulValue);
systemProperties->COMGETTER(SerialPortCount)(&ulValue);
RTPrintf("Maximum Serial Port count: %u\n", ulValue);
systemProperties->COMGETTER(ParallelPortCount)(&ulValue);
RTPrintf("Maximum Parallel Port count: %u\n", ulValue);
systemProperties->COMGETTER(MaxBootPosition)(&ulValue);
RTPrintf("Maximum Boot Position: %u\n", ulValue);
+ systemProperties->GetMaxNetworkAdapters(ChipsetType_PIIX3, &ulValue);
+ RTPrintf("Maximum PIIX3 Network Adapter count: %u\n", ulValue);
+ systemProperties->GetMaxNetworkAdapters(ChipsetType_ICH9, &ulValue);
+ RTPrintf("Maximum ICH9 Network Adapter count: %u\n", ulValue);
systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_PIIX3, StorageBus_IDE, &ulValue);
RTPrintf("Maximum PIIX3 IDE Controllers: %u\n", ulValue);
systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_ICH9, StorageBus_IDE, &ulValue);
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp
index 69249f451..f35957ea6 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageMetrics.cpp $ */
+/* $Id: VBoxManageMetrics.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxManage - The 'metrics' command.
*/
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
index f999db8ec..3713bd318 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageMisc.cpp $ */
+/* $Id: VBoxManageMisc.cpp 38055 2011-07-19 08:55:42Z vboxsync $ */
/** @file
* VBoxManage - VirtualBox's command-line interface.
*/
@@ -149,36 +149,27 @@ int handleUnregisterVM(HandlerArg *a)
return errorSyntax(USAGE_UNREGISTERVM, "VM name required");
ComPtr<IMachine> machine;
- CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMName).raw(),
- machine.asOutParam()));
- if (machine)
+ CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(VMName).raw(),
+ machine.asOutParam()),
+ RTEXITCODE_FAILURE);
+ SafeIfaceArray<IMedium> aMedia;
+ CHECK_ERROR_RET(machine, Unregister(fDelete ? (CleanupMode_T)CleanupMode_DetachAllReturnHardDisksOnly : (CleanupMode_T)CleanupMode_DetachAllReturnNone,
+ ComSafeArrayAsOutParam(aMedia)),
+ RTEXITCODE_FAILURE);
+ if (fDelete)
{
- SafeIfaceArray<IMedium> aMedia;
- CleanupMode_T cleanupMode = CleanupMode_DetachAllReturnNone;
-#if !defined(RT_OS_WINDOWS) || !defined(RT_ARCH_AMD64)
- /* XXX currently disabled due to a bug in ComSafeArrayIn on 64-bit Windows hosts! */
- if (fDelete)
- cleanupMode = CleanupMode_DetachAllReturnHardDisksOnly;
-#endif
- CHECK_ERROR(machine, Unregister(cleanupMode,
- ComSafeArrayAsOutParam(aMedia)));
- if (SUCCEEDED(rc))
- {
-#if defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)
- /* XXX currently disabled due to a bug in ComSafeArrayIn on 64-bit Windows hosts! */
- RTPrintf("The ''--delete'' parameter is ignored on Windows/x64 to prevent a crash.\n"
- "This will be fixed in the next release.");
-#else
- if (fDelete)
- {
- ComPtr<IProgress> pProgress;
- CHECK_ERROR(machine, Delete(ComSafeArrayAsInParam(aMedia), pProgress.asOutParam()));
- CHECK_ERROR(pProgress, WaitForCompletion(-1));
- }
-#endif
+ ComPtr<IProgress> pProgress;
+ CHECK_ERROR_RET(machine, Delete(ComSafeArrayAsInParam(aMedia), pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ rc = showProgress(pProgress);
+ if (FAILED(rc))
+ {
+ com::ProgressErrorInfo ErrInfo(pProgress);
+ com::GluePrintErrorInfo(ErrInfo);
+ return RTEXITCODE_FAILURE;
}
}
- return SUCCEEDED(rc) ? 0 : 1;
+ return RTEXITCODE_SUCCESS;
}
int handleCreateVM(HandlerArg *a)
@@ -275,6 +266,200 @@ int handleCreateVM(HandlerArg *a)
return SUCCEEDED(rc) ? 0 : 1;
}
+static const RTGETOPTDEF g_aCloneVMOptions[] =
+{
+ { "--snapshot", 's', RTGETOPT_REQ_STRING },
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ { "--mode", 'm', RTGETOPT_REQ_STRING },
+ { "--options", 'o', RTGETOPT_REQ_STRING },
+ { "--register", 'r', RTGETOPT_REQ_NOTHING },
+ { "--basefolder", 'p', RTGETOPT_REQ_STRING },
+ { "--uuid", 'u', RTGETOPT_REQ_STRING },
+};
+
+static int parseCloneMode(const char *psz, CloneMode_T *pMode)
+{
+ if (!RTStrICmp(psz, "machine"))
+ *pMode = CloneMode_MachineState;
+// else if (!RTStrICmp(psz, "machineandchildren"))
+// *pMode = CloneMode_MachineAndChildStates;
+ else if (!RTStrICmp(psz, "all"))
+ *pMode = CloneMode_AllStates;
+ else
+ return VERR_PARSE_ERROR;
+
+ return VINF_SUCCESS;
+}
+
+static int parseCloneOptions(const char *psz, com::SafeArray<CloneOptions_T> *options)
+{
+ int rc = VINF_SUCCESS;
+ while (psz && *psz && RT_SUCCESS(rc))
+ {
+ size_t len;
+ const char *pszComma = strchr(psz, ',');
+ if (pszComma)
+ len = pszComma - psz;
+ else
+ len = strlen(psz);
+ if (len > 0)
+ {
+ if (!RTStrNICmp(psz, "KeepAllMACs", len))
+ options->push_back(CloneOptions_KeepAllMACs);
+ else if (!RTStrNICmp(psz, "KeepNATMACs", len))
+ options->push_back(CloneOptions_KeepNATMACs);
+ else if (!RTStrNICmp(psz, "KeepDiskNames", len))
+ options->push_back(CloneOptions_KeepDiskNames);
+ else if ( !RTStrNICmp(psz, "Link", len)
+ || !RTStrNICmp(psz, "Linked", len))
+ options->push_back(CloneOptions_Link);
+ else
+ rc = VERR_PARSE_ERROR;
+ }
+ if (pszComma)
+ psz += len + 1;
+ else
+ psz += len;
+ }
+
+ return rc;
+}
+
+int handleCloneVM(HandlerArg *a)
+{
+ HRESULT rc;
+ const char *pszSrcName = NULL;
+ const char *pszSnapshotName = NULL;
+ CloneMode_T mode = CloneMode_MachineState;
+ com::SafeArray<CloneOptions_T> options;
+ const char *pszTrgName = NULL;
+ const char *pszTrgBaseFolder = NULL;
+ bool fRegister = false;
+ Bstr bstrUuid;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aCloneVMOptions, RT_ELEMENTS(g_aCloneVMOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 's': // --snapshot
+ pszSnapshotName = ValueUnion.psz;
+ break;
+
+ case 'm': // --mode
+ if (RT_FAILURE(parseCloneMode(ValueUnion.psz, &mode)))
+ return errorArgument("Invalid clone mode '%s'\n", ValueUnion.psz);
+ break;
+
+ case 'o': // --options
+ if (RT_FAILURE(parseCloneOptions(ValueUnion.psz, &options)))
+ return errorArgument("Invalid clone options '%s'\n", ValueUnion.psz);
+ break;
+
+ case 'n': // --name
+ pszTrgName = ValueUnion.psz;
+ break;
+
+ case 'p': // --basefolder
+ pszTrgBaseFolder = ValueUnion.psz;
+ break;
+
+ case 'u': // --uuid
+ RTUUID trgUuid;
+ if (RT_FAILURE(RTUuidFromStr(&trgUuid, ValueUnion.psz)))
+ return errorArgument("Invalid UUID format %s\n", ValueUnion.psz);
+ else
+ bstrUuid = Guid(trgUuid).toUtf16().raw();
+ break;
+
+ case 'r': // --register
+ fRegister = true;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (!pszSrcName)
+ pszSrcName = ValueUnion.psz;
+ else
+ return errorSyntax(USAGE_CLONEVM, "Invalid parameter '%s'", ValueUnion.psz);
+ break;
+
+ default:
+ return errorGetOpt(USAGE_CLONEVM, c, &ValueUnion);
+ }
+ }
+
+ /* Check for required options */
+ if (!pszSrcName)
+ return errorSyntax(USAGE_CLONEVM, "VM name required");
+
+ /* Get the machine object */
+ ComPtr<IMachine> srcMachine;
+ CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(pszSrcName).raw(),
+ srcMachine.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ /* If a snapshot name/uuid was given, get the particular machine of this
+ * snapshot. */
+ if (pszSnapshotName)
+ {
+ ComPtr<ISnapshot> srcSnapshot;
+ CHECK_ERROR_RET(srcMachine, FindSnapshot(Bstr(pszSnapshotName).raw(),
+ srcSnapshot.asOutParam()),
+ RTEXITCODE_FAILURE);
+ CHECK_ERROR_RET(srcSnapshot, COMGETTER(Machine)(srcMachine.asOutParam()),
+ RTEXITCODE_FAILURE);
+ }
+
+ /* Default name necessary? */
+ if (!pszTrgName)
+ pszTrgName = RTStrAPrintf2("%s Clone", pszSrcName);
+
+ Bstr bstrSettingsFile;
+ CHECK_ERROR_RET(a->virtualBox,
+ ComposeMachineFilename(Bstr(pszTrgName).raw(),
+ Bstr(pszTrgBaseFolder).raw(),
+ bstrSettingsFile.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<IMachine> trgMachine;
+ CHECK_ERROR_RET(a->virtualBox, CreateMachine(bstrSettingsFile.raw(),
+ Bstr(pszTrgName).raw(),
+ NULL,
+ bstrUuid.raw(),
+ FALSE,
+ trgMachine.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ /* Start the cloning */
+ ComPtr<IProgress> progress;
+ CHECK_ERROR_RET(srcMachine, CloneTo(trgMachine,
+ mode,
+ ComSafeArrayAsInParam(options),
+ progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ rc = showProgress(progress);
+ if (FAILED(rc))
+ {
+ com::ProgressErrorInfo ErrInfo(progress);
+ com::GluePrintErrorInfo(ErrInfo);
+ return RTEXITCODE_FAILURE;
+ }
+
+ if (fRegister)
+ CHECK_ERROR_RET(a->virtualBox, RegisterMachine(trgMachine), RTEXITCODE_FAILURE);
+
+ Bstr bstrNewName;
+ CHECK_ERROR_RET(trgMachine, COMGETTER(Name)(bstrNewName.asOutParam()), RTEXITCODE_FAILURE);
+ RTPrintf("Machine has been successfully cloned as \"%lS\"\n", bstrNewName.raw());
+
+ return RTEXITCODE_SUCCESS;
+}
+
int handleStartVM(HandlerArg *a)
{
HRESULT rc;
@@ -439,6 +624,14 @@ int handleAdoptState(HandlerArg *a)
machine.asOutParam()));
if (machine)
{
+ char szStateFileAbs[RTPATH_MAX] = "";
+ int vrc = RTPathAbs(a->argv[1], szStateFileAbs, sizeof(szStateFileAbs));
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError("Cannot convert filename \"%s\" to absolute path", a->argv[0]);
+ return 1;
+ }
+
do
{
/* we have to open a session for this task */
@@ -447,7 +640,7 @@ int handleAdoptState(HandlerArg *a)
{
ComPtr<IConsole> console;
CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
- CHECK_ERROR_BREAK(console, AdoptSavedState(Bstr(a->argv[1]).raw()));
+ CHECK_ERROR_BREAK(console, AdoptSavedState(Bstr(szStateFileAbs).raw()));
} while (0);
CHECK_ERROR_BREAK(a->session, UnlockMachine());
} while (0);
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
index faa7bc8cc..e4250438f 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxManageModifyVM.cpp $ */
+/* $Id: VBoxManageModifyVM.cpp 37817 2011-07-07 13:02:40Z vboxsync $ */
/** @file
* VBoxManage - Implementation of modifyvm command.
*/
/*
- * 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;
@@ -100,18 +100,19 @@ enum
MODIFYVM_FLOPPY, // deprecated
MODIFYVM_NICTRACEFILE,
MODIFYVM_NICTRACE,
+ MODIFYVM_NICPROPERTY,
MODIFYVM_NICTYPE,
MODIFYVM_NICSPEED,
MODIFYVM_NICBOOTPRIO,
+ MODIFYVM_NICPROMISC,
+ MODIFYVM_NICBWGROUP,
MODIFYVM_NIC,
MODIFYVM_CABLECONNECTED,
MODIFYVM_BRIDGEADAPTER,
MODIFYVM_HOSTONLYADAPTER,
MODIFYVM_INTNET,
MODIFYVM_NATNET,
-#ifdef VBOX_WITH_VDE
- MODIFYVM_VDENET,
-#endif
+ MODIFYVM_GENERICDRV,
MODIFYVM_NATBINDIP,
MODIFYVM_NATSETTINGS,
MODIFYVM_NATPF,
@@ -168,6 +169,10 @@ enum
MODIFYVM_FAULT_TOLERANCE_PASSWORD,
MODIFYVM_FAULT_TOLERANCE_SYNC_INTERVAL,
MODIFYVM_CPU_EXECTUION_CAP,
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ MODIFYVM_ATTACH_PCI,
+ MODIFYVM_DETACH_PCI,
+#endif
MODIFYVM_CHIPSET
};
@@ -226,18 +231,19 @@ static const RTGETOPTDEF g_aModifyVMOptions[] =
{ "--floppy", MODIFYVM_FLOPPY, RTGETOPT_REQ_STRING },
{ "--nictracefile", MODIFYVM_NICTRACEFILE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
{ "--nictrace", MODIFYVM_NICTRACE, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX },
+ { "--nicproperty", MODIFYVM_NICPROPERTY, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
{ "--nictype", MODIFYVM_NICTYPE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
{ "--nicspeed", MODIFYVM_NICSPEED, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX },
{ "--nicbootprio", MODIFYVM_NICBOOTPRIO, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX },
+ { "--nicpromisc", MODIFYVM_NICPROMISC, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
+ { "--nicbandwidthgroup", MODIFYVM_NICBWGROUP, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
{ "--nic", MODIFYVM_NIC, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
{ "--cableconnected", MODIFYVM_CABLECONNECTED, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX },
{ "--bridgeadapter", MODIFYVM_BRIDGEADAPTER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
{ "--hostonlyadapter", MODIFYVM_HOSTONLYADAPTER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
{ "--intnet", MODIFYVM_INTNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
{ "--natnet", MODIFYVM_NATNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
-#ifdef VBOX_WITH_VDE
- { "--vdenet", MODIFYVM_VDENET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
-#endif
+ { "--nicgenericdrv", MODIFYVM_GENERICDRV, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
{ "--natbindip", MODIFYVM_NATBINDIP, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
{ "--natsettings", MODIFYVM_NATSETTINGS, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
{ "--natpf", MODIFYVM_NATPF, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
@@ -294,6 +300,10 @@ static const RTGETOPTDEF g_aModifyVMOptions[] =
{ "--faulttolerancepassword", MODIFYVM_FAULT_TOLERANCE_PASSWORD, RTGETOPT_REQ_STRING },
{ "--faulttolerancesyncinterval", MODIFYVM_FAULT_TOLERANCE_SYNC_INTERVAL, RTGETOPT_REQ_UINT32 },
{ "--chipset", MODIFYVM_CHIPSET, RTGETOPT_REQ_STRING },
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ { "--pciattach", MODIFYVM_ATTACH_PCI, RTGETOPT_REQ_STRING },
+ { "--pcidetach", MODIFYVM_DETACH_PCI, RTGETOPT_REQ_STRING },
+#endif
};
static void vrdeWarningDeprecatedOption(const char *pszOption)
@@ -301,6 +311,27 @@ static void vrdeWarningDeprecatedOption(const char *pszOption)
RTStrmPrintf(g_pStdErr, "Warning: '--vrdp%s' is deprecated. Use '--vrde%s'.\n", pszOption, pszOption);
}
+/** Parse PCI address in format 01:02.03 and convert it to the numeric representation. */
+static int32_t parsePci(const char* szPciAddr)
+{
+ char* pszNext = (char*)szPciAddr;
+ int rc;
+ uint8_t aVals[3] = {0, 0, 0};
+
+ rc = RTStrToUInt8Ex(pszNext, &pszNext, 16, &aVals[0]);
+ if (RT_FAILURE(rc) || pszNext == NULL || *pszNext != ':')
+ return -1;
+
+ rc = RTStrToUInt8Ex(pszNext+1, &pszNext, 16, &aVals[1]);
+ if (RT_FAILURE(rc) || pszNext == NULL || *pszNext != '.')
+ return -1;
+
+ rc = RTStrToUInt8Ex(pszNext+1, &pszNext, 16, &aVals[2]);
+ if (RT_FAILURE(rc) || pszNext == NULL)
+ return -1;
+
+ return (aVals[0] << 8) | (aVals[1] << 3) | (aVals[2] << 0);
+}
int handleModifyVM(HandlerArg *a)
{
@@ -317,13 +348,6 @@ int handleModifyVM(HandlerArg *a)
if (a->argc < 2)
return errorSyntax(USAGE_MODIFYVM, "Not enough parameters");
- /* Get the number of network adapters */
- ULONG NetworkAdapterCount = 0;
- {
- ComPtr <ISystemProperties> info;
- CHECK_ERROR_RET(a->virtualBox, COMGETTER(SystemProperties)(info.asOutParam()), 1);
- CHECK_ERROR_RET(info, COMGETTER(NetworkAdapterCount)(&NetworkAdapterCount), 1);
- }
ULONG SerialPortCount = 0;
{
ComPtr <ISystemProperties> info;
@@ -335,6 +359,10 @@ int handleModifyVM(HandlerArg *a)
CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
machine.asOutParam()), 1);
+
+ /* Get the number of network adapters */
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, machine);
+
/* open a session for the VM */
CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), 1);
@@ -683,7 +711,8 @@ int handleModifyVM(HandlerArg *a)
{
ComPtr<IMedium> hardDisk;
rc = findOrOpenMedium(a, ValueUnion.psz, DeviceType_HardDisk,
- hardDisk, NULL);
+ hardDisk, false /* fForceNewUuidOnOpen */,
+ NULL);
if (FAILED(rc))
break;
if (hardDisk)
@@ -778,7 +807,8 @@ int handleModifyVM(HandlerArg *a)
{
ComPtr<IMedium> hardDisk;
rc = findOrOpenMedium(a, ValueUnion.psz, DeviceType_HardDisk,
- hardDisk, NULL);
+ hardDisk, false /* fForceNewUuidOnOpen */,
+ NULL);
if (FAILED(rc))
break;
if (hardDisk)
@@ -905,7 +935,8 @@ int handleModifyVM(HandlerArg *a)
else
{
rc = findOrOpenMedium(a, ValueUnion.psz, DeviceType_DVD,
- dvdMedium, NULL);
+ dvdMedium, false /* fForceNewUuidOnOpen */,
+ NULL);
if (FAILED(rc))
break;
if (!dvdMedium)
@@ -968,7 +999,8 @@ int handleModifyVM(HandlerArg *a)
else
{
rc = findOrOpenMedium(a, ValueUnion.psz, DeviceType_Floppy,
- floppyMedium, NULL);
+ floppyMedium, false /* fForceNewUuidOnOpen */,
+ NULL);
if (FAILED(rc))
break;
if (!floppyMedium)
@@ -1007,6 +1039,43 @@ int handleModifyVM(HandlerArg *a)
break;
}
+ case MODIFYVM_NICPROPERTY:
+ {
+ ComPtr<INetworkAdapter> nic;
+
+ CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ if (nic)
+ {
+ /* Parse 'name=value' */
+ char *pszProperty = RTStrDup(ValueUnion.psz);
+ if (pszProperty)
+ {
+ char *pDelimiter = strchr(pszProperty, '=');
+ if (pDelimiter)
+ {
+ *pDelimiter = '\0';
+
+ Bstr bstrName = pszProperty;
+ Bstr bstrValue = &pDelimiter[1];
+ CHECK_ERROR(nic, SetProperty(bstrName.raw(), bstrValue.raw()));
+ }
+ else
+ {
+ errorArgument("Invalid --nicproperty%d argument '%s'", GetOptState.uIndex, ValueUnion.psz);
+ rc = E_FAIL;
+ }
+ RTStrFree(pszProperty);
+ }
+ else
+ {
+ RTStrmPrintf(g_pStdErr, "Error: Failed to allocate memory for --nicproperty%d '%s'\n", GetOptState.uIndex, ValueUnion.psz);
+ rc = E_FAIL;
+ }
+ }
+ break;
+ }
case MODIFYVM_NICTYPE:
{
ComPtr<INetworkAdapter> nic;
@@ -1084,6 +1153,61 @@ int handleModifyVM(HandlerArg *a)
break;
}
+ case MODIFYVM_NICPROMISC:
+ {
+ NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
+ if (!strcmp(ValueUnion.psz, "deny"))
+ enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_Deny;
+ else if ( !strcmp(ValueUnion.psz, "allow-vms")
+ || !strcmp(ValueUnion.psz, "allow-network"))
+ enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowNetwork;
+ else if (!strcmp(ValueUnion.psz, "allow-all"))
+ enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowAll;
+ else
+ {
+ errorArgument("Unknown promiscuous mode policy '%s'", ValueUnion.psz);
+ rc = E_INVALIDARG;
+ break;
+ }
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ CHECK_ERROR(nic, COMSETTER(PromiscModePolicy)(enmPromiscModePolicy));
+ break;
+ }
+
+ case MODIFYVM_NICBWGROUP:
+ {
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ /* Just remove the bandwidth group. */
+ CHECK_ERROR(nic, COMSETTER(BandwidthGroup)(NULL));
+ }
+ else
+ {
+ ComPtr<IBandwidthControl> bwCtrl;
+ ComPtr<IBandwidthGroup> bwGroup;
+
+ CHECK_ERROR(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
+
+ if (SUCCEEDED(rc))
+ {
+ CHECK_ERROR(bwCtrl, GetBandwidthGroup(Bstr(ValueUnion.psz).raw(), bwGroup.asOutParam()));
+ if (SUCCEEDED(rc))
+ {
+ CHECK_ERROR(nic, COMSETTER(BandwidthGroup)(bwGroup));
+ }
+ }
+ }
+ break;
+ }
+
case MODIFYVM_NIC:
{
ComPtr<INetworkAdapter> nic;
@@ -1098,40 +1222,36 @@ int handleModifyVM(HandlerArg *a)
else if (!strcmp(ValueUnion.psz, "null"))
{
CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
- CHECK_ERROR(nic, Detach());
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Null));
}
else if (!strcmp(ValueUnion.psz, "nat"))
{
CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
- CHECK_ERROR(nic, AttachToNAT());
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_NAT));
}
else if ( !strcmp(ValueUnion.psz, "bridged")
|| !strcmp(ValueUnion.psz, "hostif")) /* backward compatibility */
{
CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
- CHECK_ERROR(nic, AttachToBridgedInterface());
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Bridged));
}
else if (!strcmp(ValueUnion.psz, "intnet"))
{
CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
- CHECK_ERROR(nic, AttachToInternalNetwork());
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Internal));
}
-#if defined(VBOX_WITH_NETFLT)
else if (!strcmp(ValueUnion.psz, "hostonly"))
{
CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
- CHECK_ERROR(nic, AttachToHostOnlyInterface());
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_HostOnly));
}
-#endif
-#ifdef VBOX_WITH_VDE
- else if (!strcmp(ValueUnion.psz, "vde"))
+ else if (!strcmp(ValueUnion.psz, "generic"))
{
CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
- CHECK_ERROR(nic, AttachToVDE());
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Generic));
}
-#endif
else
{
errorArgument("Invalid type '%s' specfied for NIC %u", ValueUnion.psz, GetOptState.uIndex);
@@ -1152,67 +1272,73 @@ int handleModifyVM(HandlerArg *a)
}
case MODIFYVM_BRIDGEADAPTER:
- case MODIFYVM_HOSTONLYADAPTER:
{
ComPtr<INetworkAdapter> nic;
CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
ASSERT(nic);
- /** @todo NULL string deprecated */
/* remove it? */
if (!strcmp(ValueUnion.psz, "none"))
{
- CHECK_ERROR(nic, COMSETTER(HostInterface)(NULL));
+ CHECK_ERROR(nic, COMSETTER(BridgedInterface)(Bstr().raw()));
}
else
{
- CHECK_ERROR(nic, COMSETTER(HostInterface)(Bstr(ValueUnion.psz).raw()));
+ CHECK_ERROR(nic, COMSETTER(BridgedInterface)(Bstr(ValueUnion.psz).raw()));
}
break;
}
- case MODIFYVM_INTNET:
+ case MODIFYVM_HOSTONLYADAPTER:
{
ComPtr<INetworkAdapter> nic;
CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
ASSERT(nic);
- /** @todo NULL string deprecated */
/* remove it? */
if (!strcmp(ValueUnion.psz, "none"))
{
- CHECK_ERROR(nic, COMSETTER(InternalNetwork)(NULL));
+ CHECK_ERROR(nic, COMSETTER(HostOnlyInterface)(Bstr().raw()));
}
else
{
- CHECK_ERROR(nic, COMSETTER(InternalNetwork)(Bstr(ValueUnion.psz).raw()));
+ CHECK_ERROR(nic, COMSETTER(HostOnlyInterface)(Bstr(ValueUnion.psz).raw()));
}
break;
}
-#ifdef VBOX_WITH_VDE
- case MODIFYVM_VDENET:
+ case MODIFYVM_INTNET:
{
ComPtr<INetworkAdapter> nic;
CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
ASSERT(nic);
- /** @todo NULL string deprecated */
/* remove it? */
- if (!strcmp(ValueUnion.psz, "default"))
+ if (!strcmp(ValueUnion.psz, "none"))
{
- CHECK_ERROR(nic, COMSETTER(VDENetwork)(NULL));
+ CHECK_ERROR(nic, COMSETTER(InternalNetwork)(Bstr().raw()));
}
else
{
- CHECK_ERROR(nic, COMSETTER(VDENetwork)(Bstr(ValueUnion.psz).raw()));
+ CHECK_ERROR(nic, COMSETTER(InternalNetwork)(Bstr(ValueUnion.psz).raw()));
}
break;
}
-#endif
+
+ case MODIFYVM_GENERICDRV:
+ {
+ ComPtr<INetworkAdapter> nic;
+
+ CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ CHECK_ERROR(nic, COMSETTER(GenericDriver)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
case MODIFYVM_NATNET:
{
ComPtr<INetworkAdapter> nic;
@@ -1472,7 +1598,7 @@ int handleModifyVM(HandlerArg *a)
/* generate one? */
if (!strcmp(ValueUnion.psz, "auto"))
{
- CHECK_ERROR(nic, COMSETTER(MACAddress)(NULL));
+ CHECK_ERROR(nic, COMSETTER(MACAddress)(Bstr().raw()));
}
else
{
@@ -1796,7 +1922,7 @@ int handleModifyVM(HandlerArg *a)
CHECK_ERROR(vrdeServer, COMSETTER(VRDEExtPack)(bstr.raw()));
}
else
- CHECK_ERROR(vrdeServer, COMSETTER(VRDEExtPack)(NULL));
+ CHECK_ERROR(vrdeServer, COMSETTER(VRDEExtPack)(Bstr().raw()));
}
break;
}
@@ -1912,7 +2038,7 @@ int handleModifyVM(HandlerArg *a)
CHECK_ERROR(vrdeServer, COMSETTER(AuthLibrary)(bstr.raw()));
}
else
- CHECK_ERROR(vrdeServer, COMSETTER(AuthLibrary)(NULL));
+ CHECK_ERROR(vrdeServer, COMSETTER(AuthLibrary)(Bstr().raw()));
}
break;
}
@@ -2000,7 +2126,7 @@ int handleModifyVM(HandlerArg *a)
case MODIFYVM_SNAPSHOTFOLDER:
{
if (!strcmp(ValueUnion.psz, "default"))
- CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(NULL));
+ CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(Bstr().raw()));
else
CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(Bstr(ValueUnion.psz).raw()));
break;
@@ -2121,7 +2247,45 @@ int handleModifyVM(HandlerArg *a)
}
break;
}
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ case MODIFYVM_ATTACH_PCI:
+ {
+ const char* pAt = strchr(ValueUnion.psz, '@');
+ int32_t iHostAddr, iGuestAddr;
+
+ iHostAddr = parsePci(ValueUnion.psz);
+ iGuestAddr = pAt != NULL ? parsePci(pAt + 1) : iHostAddr;
+ if (iHostAddr == -1 || iGuestAddr == -1)
+ {
+ errorArgument("Invalid --pciattach argument '%s' (valid: 'HB:HD.HF@GB:GD.GF' or just 'HB:HD.HF')", ValueUnion.psz);
+ rc = E_FAIL;
+ }
+ else
+ {
+ CHECK_ERROR(machine, AttachHostPciDevice(iHostAddr, iGuestAddr, TRUE));
+ }
+
+ break;
+ }
+ case MODIFYVM_DETACH_PCI:
+ {
+ int32_t iHostAddr;
+
+ iHostAddr = parsePci(ValueUnion.psz);
+ if (iHostAddr == -1)
+ {
+ errorArgument("Invalid --pcidetach argument '%s' (valid: 'HB:HD.HF')", ValueUnion.psz);
+ rc = E_FAIL;
+ }
+ else
+ {
+ CHECK_ERROR(machine, DetachHostPciDevice(iHostAddr));
+ }
+
+ break;
+ }
+#endif
default:
{
errorGetOpt(USAGE_MODIFYVM, c, &ValueUnion);
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp
index dbb2e47cb..9bcbd79a4 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageSnapshot.cpp $ */
+/* $Id: VBoxManageSnapshot.cpp 33425 2010-10-25 14:30:43Z vboxsync $ */
/** @file
* VBoxManage - The 'snapshot' command.
*/
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp
index ea8f2ec5c..9032da276 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageStorageController.cpp $ */
+/* $Id: VBoxManageStorageController.cpp 37929 2011-07-13 18:34:49Z vboxsync $ */
/** @file
* VBoxManage - The storage controller related commands.
*/
@@ -51,13 +51,17 @@ static const RTGETOPTDEF g_aStorageAttachOptions[] =
{ "--medium", 'm', RTGETOPT_REQ_STRING },
{ "--mtype", 'M', RTGETOPT_REQ_STRING },
{ "--passthrough", 'h', RTGETOPT_REQ_STRING },
+ { "--tempeject", 'e', RTGETOPT_REQ_STRING },
+ { "--nonrotational", 'n', RTGETOPT_REQ_STRING },
{ "--bandwidthgroup", 'b', RTGETOPT_REQ_STRING },
{ "--forceunmount", 'f', RTGETOPT_REQ_NOTHING },
{ "--comment", 'C', RTGETOPT_REQ_STRING },
+ { "--setuuid", 'q', RTGETOPT_REQ_STRING },
+ { "--setparentuuid", 'Q', RTGETOPT_REQ_STRING },
// iSCSI options
{ "--server", 'S', RTGETOPT_REQ_STRING },
{ "--target", 'T', RTGETOPT_REQ_STRING },
- { "--port", 'P', RTGETOPT_REQ_STRING },
+ { "--tport", 'P', RTGETOPT_REQ_STRING },
{ "--lun", 'L', RTGETOPT_REQ_STRING },
{ "--encodedlun", 'E', RTGETOPT_REQ_STRING },
{ "--username", 'U', RTGETOPT_REQ_STRING },
@@ -73,13 +77,19 @@ int handleStorageAttach(HandlerArg *a)
ULONG device = ~0U;
bool fForceUnmount = false;
bool fSetMediumType = false;
+ bool fSetNewUuid = false;
+ bool fSetNewParentUuid = false;
MediumType_T mediumType = MediumType_Normal;
Bstr bstrComment;
const char *pszCtl = NULL;
DeviceType_T devTypeRequested = DeviceType_Null;
const char *pszMedium = NULL;
const char *pszPassThrough = NULL;
+ const char *pszTempEject = NULL;
+ const char *pszNonRotational = NULL;
const char *pszBandwidthGroup = NULL;
+ Bstr bstrNewUuid;
+ Bstr bstrNewParentUuid;
// iSCSI options
Bstr bstrServer;
Bstr bstrTarget;
@@ -160,6 +170,24 @@ int handleStorageAttach(HandlerArg *a)
break;
}
+ case 'e': // tempeject <on|off>
+ {
+ if (ValueUnion.psz)
+ pszTempEject = ValueUnion.psz;
+ else
+ rc = E_FAIL;
+ break;
+ }
+
+ case 'n': // nonrotational <on|off>
+ {
+ if (ValueUnion.psz)
+ pszNonRotational = ValueUnion.psz;
+ else
+ rc = E_FAIL;
+ break;
+ }
+
case 'b': // bandwidthgroup <name>
{
if (ValueUnion.psz)
@@ -180,7 +208,27 @@ int handleStorageAttach(HandlerArg *a)
bstrComment = ValueUnion.psz;
else
rc = E_FAIL;
- break;
+ break;
+
+ case 'q':
+ if (ValueUnion.psz)
+ {
+ bstrNewUuid = ValueUnion.psz;
+ fSetNewUuid = true;
+ }
+ else
+ rc = E_FAIL;
+ break;
+
+ case 'Q':
+ if (ValueUnion.psz)
+ {
+ bstrNewParentUuid = ValueUnion.psz;
+ fSetNewParentUuid = true;
+ }
+ else
+ rc = E_FAIL;
+ break;
case 'S': // --server
bstrServer = ValueUnion.psz;
@@ -190,7 +238,7 @@ int handleStorageAttach(HandlerArg *a)
bstrTarget = ValueUnion.psz;
break;
- case 'P': // --port
+ case 'P': // --tport
bstrPort = ValueUnion.psz;
break;
@@ -237,10 +285,6 @@ int handleStorageAttach(HandlerArg *a)
if (!pszCtl)
return errorSyntax(USAGE_STORAGEATTACH, "Storage controller name not specified");
- if (port == ~0U)
- return errorSyntax(USAGE_STORAGEATTACH, "Port not specified");
- if (device == ~0U)
- return errorSyntax(USAGE_STORAGEATTACH, "Device not specified");
/* get the virtualbox system properties */
CHECK_ERROR_RET(a->virtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()), 1);
@@ -256,13 +300,10 @@ int handleStorageAttach(HandlerArg *a)
try
{
bool fRunTime = (st == SessionType_Shared);
+
if (fRunTime)
{
- if (devTypeRequested == DeviceType_HardDisk)
- throw Utf8Str("Hard disk drives cannot be changed while the VM is running\n");
- else if (!RTStrICmp(pszMedium, "none"))
- throw Utf8Str("Drives cannot be removed while the VM is running\n");
- else if (pszPassThrough)
+ if (pszPassThrough)
throw Utf8Str("Drive passthrough state cannot be changed while the VM is running\n");
else if (pszBandwidthGroup)
throw Utf8Str("Bandwidth group cannot be changed while the VM is running\n");
@@ -274,6 +315,28 @@ int handleStorageAttach(HandlerArg *a)
if (FAILED(rc))
throw Utf8StrFmt("Could not find a controller named '%s'\n", pszCtl);
+ StorageBus_T storageBus = StorageBus_Null;
+ CHECK_ERROR_RET(storageCtl, COMGETTER(Bus)(&storageBus), 1);
+ ULONG maxPorts = 0;
+ CHECK_ERROR_RET(systemProperties, GetMaxPortCountForStorageBus(storageBus, &maxPorts), 1);
+ ULONG maxDevices = 0;
+ CHECK_ERROR_RET(systemProperties, GetMaxDevicesPerPortForStorageBus(storageBus, &maxDevices), 1);
+
+ if (port == ~0U)
+ {
+ if (maxPorts == 1)
+ port = 0;
+ else
+ return errorSyntax(USAGE_STORAGEATTACH, "Port not specified");
+ }
+ if (device == ~0U)
+ {
+ if (maxDevices == 1)
+ device = 0;
+ else
+ return errorSyntax(USAGE_STORAGEATTACH, "Device not specified");
+ }
+
/* for sata controller check if the port count is big enough
* to accommodate the current port which is being assigned
* else just increase the port count
@@ -332,13 +395,11 @@ int handleStorageAttach(HandlerArg *a)
}
else
{
- StorageBus_T storageBus = StorageBus_Null;
DeviceType_T deviceType = DeviceType_Null;
com::SafeArray <DeviceType_T> saDeviceTypes;
ULONG driveCheck = 0;
/* check if the device type is supported by the controller */
- CHECK_ERROR(storageCtl, COMGETTER(Bus)(&storageBus));
CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes)));
for (size_t i = 0; i < saDeviceTypes.size(); ++ i)
{
@@ -375,7 +436,7 @@ int handleStorageAttach(HandlerArg *a)
*/
if (ctlType == StorageControllerType_I82078) // floppy controller
devTypeRequested = DeviceType_Floppy;
- else if (pszMedium)
+ else
{
/*
* for SATA/SCSI/IDE it is hard to tell if it is a harddisk or
@@ -393,19 +454,23 @@ int handleStorageAttach(HandlerArg *a)
DeviceType_T deviceType;
mediumAttachment->COMGETTER(Type)(&deviceType);
- ComPtr<IMedium> pExistingMedium;
- rc = findMedium(a, pszMedium, deviceType, true /* fSilent */,
- pExistingMedium);
- if (SUCCEEDED(rc) && pExistingMedium)
+ if (pszMedium)
{
- if ( (deviceType == DeviceType_DVD)
- || (deviceType == DeviceType_HardDisk)
- )
- devTypeRequested = deviceType;
+ ComPtr<IMedium> pExistingMedium;
+ rc = findMedium(a, pszMedium, deviceType, true /* fSilent */,
+ pExistingMedium);
+ if (SUCCEEDED(rc) && pExistingMedium)
+ {
+ if ( (deviceType == DeviceType_DVD)
+ || (deviceType == DeviceType_HardDisk)
+ )
+ devTypeRequested = deviceType;
+ }
}
+ else
+ devTypeRequested = deviceType;
}
}
- /* for all other cases lets ask the user what type of drive it is */
}
if (devTypeRequested == DeviceType_Null) // still the initializer value?
@@ -413,10 +478,8 @@ int handleStorageAttach(HandlerArg *a)
/* check if the device type is supported by the controller */
{
- StorageBus_T storageBus = StorageBus_Null;
com::SafeArray <DeviceType_T> saDeviceTypes;
- CHECK_ERROR(storageCtl, COMGETTER(Bus)(&storageBus));
CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes)));
if (SUCCEEDED(rc))
{
@@ -538,14 +601,32 @@ int handleStorageAttach(HandlerArg *a)
}
else
{
- Bstr bstrMedium(pszMedium);
- if (bstrMedium.isEmpty())
- throw Utf8Str("Missing --medium argument");
-
- rc = findOrOpenMedium(a, pszMedium, devTypeRequested,
- pMedium2Mount, NULL);
- if (FAILED(rc) || !pMedium2Mount)
- throw Utf8StrFmt("Invalid UUID or filename \"%s\"", pszMedium);
+ if (!pszMedium)
+ {
+ ComPtr<IMediumAttachment> mediumAttachment;
+ rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device,
+ mediumAttachment.asOutParam());
+ if (FAILED(rc))
+ throw Utf8Str("Missing --medium argument");
+ }
+ else
+ {
+ Bstr bstrMedium(pszMedium);
+ rc = findOrOpenMedium(a, pszMedium, devTypeRequested,
+ pMedium2Mount, fSetNewUuid, NULL);
+ if (FAILED(rc) || !pMedium2Mount)
+ throw Utf8StrFmt("Invalid UUID or filename \"%s\"", pszMedium);
+ }
+ }
+
+ // set medium/parent medium UUID, if so desired
+ if (pMedium2Mount && (fSetNewUuid || fSetNewParentUuid))
+ {
+ CHECK_ERROR(pMedium2Mount, SetIDs(fSetNewUuid, bstrNewUuid.raw(),
+ fSetNewParentUuid, bstrNewParentUuid.raw()));
+ if (FAILED(rc))
+ throw Utf8Str("Failed to set the medium/parent medium UUID");
}
// set medium type, if so desired
@@ -561,26 +642,37 @@ int handleStorageAttach(HandlerArg *a)
CHECK_ERROR(pMedium2Mount, COMSETTER(Description)(bstrComment.raw()));
}
- switch (devTypeRequested)
+ if (pszMedium)
{
- case DeviceType_DVD:
- case DeviceType_Floppy:
+ switch (devTypeRequested)
{
- if (!fRunTime)
+ case DeviceType_DVD:
+ case DeviceType_Floppy:
{
- ComPtr<IMediumAttachment> mediumAttachment;
- // check if there is a dvd/floppy drive at the given location, if not attach one first
- rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(),
- port,
- device,
- mediumAttachment.asOutParam());
- if (SUCCEEDED(rc))
+ if (!fRunTime)
{
- DeviceType_T deviceType;
- mediumAttachment->COMGETTER(Type)(&deviceType);
- if (deviceType != devTypeRequested)
+ ComPtr<IMediumAttachment> mediumAttachment;
+ // check if there is a dvd/floppy drive at the given location, if not attach one first
+ rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(),
+ port,
+ device,
+ mediumAttachment.asOutParam());
+ if (SUCCEEDED(rc))
+ {
+ DeviceType_T deviceType;
+ mediumAttachment->COMGETTER(Type)(&deviceType);
+ if (deviceType != devTypeRequested)
+ {
+ machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
+ rc = machine->AttachDevice(Bstr(pszCtl).raw(),
+ port,
+ device,
+ devTypeRequested, // DeviceType_DVD or DeviceType_Floppy
+ NULL);
+ }
+ }
+ else
{
- machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
rc = machine->AttachDevice(Bstr(pszCtl).raw(),
port,
device,
@@ -588,41 +680,30 @@ int handleStorageAttach(HandlerArg *a)
NULL);
}
}
- else
+
+ if (pMedium2Mount)
{
- rc = machine->AttachDevice(Bstr(pszCtl).raw(),
- port,
- device,
- devTypeRequested, // DeviceType_DVD or DeviceType_Floppy
- NULL);
+ CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(),
+ port,
+ device,
+ pMedium2Mount,
+ fForceUnmount));
}
- }
+ } // end DeviceType_DVD or DeviceType_Floppy:
+ break;
- if (pMedium2Mount)
+ case DeviceType_HardDisk:
{
- CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(),
- port,
- device,
- pMedium2Mount,
- fForceUnmount));
+ // if there is anything attached at the given location, remove it
+ machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
+ CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(),
+ port,
+ device,
+ DeviceType_HardDisk,
+ pMedium2Mount));
}
- } // end DeviceType_DVD or DeviceType_Floppy:
- break;
-
- case DeviceType_HardDisk:
- {
- if (fRunTime)
- throw Utf8Str("Hard disk attachments cannot be changed while the VM is running");
-
- // if there is anything attached at the given location, remove it
- machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
- CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(),
- port,
- device,
- DeviceType_HardDisk,
- pMedium2Mount));
+ break;
}
- break;
}
}
@@ -652,6 +733,58 @@ int handleStorageAttach(HandlerArg *a)
throw Utf8StrFmt("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
}
+ if ( pszTempEject
+ && (SUCCEEDED(rc)))
+ {
+ ComPtr<IMediumAttachment> mattach;
+ CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device, mattach.asOutParam()));
+
+ if (SUCCEEDED(rc))
+ {
+ if (!RTStrICmp(pszTempEject, "on"))
+ {
+ CHECK_ERROR(machine, TemporaryEjectDevice(Bstr(pszCtl).raw(),
+ port, device, TRUE));
+ }
+ else if (!RTStrICmp(pszTempEject, "off"))
+ {
+ CHECK_ERROR(machine, TemporaryEjectDevice(Bstr(pszCtl).raw(),
+ port, device, FALSE));
+ }
+ else
+ throw Utf8StrFmt("Invalid --tempeject argument '%s'", pszTempEject);
+ }
+ else
+ throw Utf8StrFmt("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
+ }
+
+ if ( pszNonRotational
+ && (SUCCEEDED(rc)))
+ {
+ ComPtr<IMediumAttachment> mattach;
+ CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device, mattach.asOutParam()));
+
+ if (SUCCEEDED(rc))
+ {
+ if (!RTStrICmp(pszNonRotational, "on"))
+ {
+ CHECK_ERROR(machine, NonRotationalDevice(Bstr(pszCtl).raw(),
+ port, device, TRUE));
+ }
+ else if (!RTStrICmp(pszNonRotational, "off"))
+ {
+ CHECK_ERROR(machine, NonRotationalDevice(Bstr(pszCtl).raw(),
+ port, device, FALSE));
+ }
+ else
+ throw Utf8StrFmt("Invalid --nonrotational argument '%s'", pszNonRotational);
+ }
+ else
+ throw Utf8StrFmt("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
+ }
+
if ( pszBandwidthGroup
&& !fRunTime
&& SUCCEEDED(rc))
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp
index 91d987813..13f2e9d2b 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageUSB.cpp $ */
+/* $Id: VBoxManageUSB.cpp 33294 2010-10-21 10:45:26Z vboxsync $ */
/** @file
* VBoxManage - VirtualBox's command-line interface.
*/
diff --git a/src/VBox/Frontends/VBoxSDL/Helper.cpp b/src/VBox/Frontends/VBoxSDL/Helper.cpp
index 6b912dd74..a2f4e275b 100644
--- a/src/VBox/Frontends/VBoxSDL/Helper.cpp
+++ b/src/VBox/Frontends/VBoxSDL/Helper.cpp
@@ -127,7 +127,8 @@ int startXPCOMEventQueueThread(int eqFD)
if (RT_SUCCESS(rc))
{
RTTHREAD Thread;
- rc = RTThreadCreate(&Thread, xpcomEventThread, (void *)eqFD, 0, RTTHREADTYPE_MSG_PUMP, 0, "XPCOMEvent");
+ rc = RTThreadCreate(&Thread, xpcomEventThread, (void *)(intptr_t)eqFD,
+ 0, RTTHREADTYPE_MSG_PUMP, 0, "XPCOMEvent");
}
AssertRC(rc);
return rc;
diff --git a/src/VBox/Frontends/VBoxSDL/Makefile.kmk b/src/VBox/Frontends/VBoxSDL/Makefile.kmk
index 497297540..028a00d22 100644
--- a/src/VBox/Frontends/VBoxSDL/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxSDL/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37037 2011-05-11 12:53:40Z vboxsync $
## @file
# Sub-Makefile for VBoxSDL (a simple frontend based on SDL).
#
diff --git a/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp b/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
index b43502578..454c65ef3 100644
--- a/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
+++ b/src/VBox/Frontends/VBoxSDL/VBoxSDL.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;
@@ -244,6 +244,15 @@ public:
{
}
+ HRESULT init()
+ {
+ return S_OK;
+ }
+
+ void uninit()
+ {
+ }
+
STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent * aEvent)
{
switch (aType)
@@ -289,6 +298,15 @@ public:
{
}
+ HRESULT init()
+ {
+ return S_OK;
+ }
+
+ void uninit()
+ {
+ }
+
STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent * aEvent)
{
switch (aType)
@@ -349,6 +367,15 @@ public:
{
}
+ HRESULT init()
+ {
+ return S_OK;
+ }
+
+ void uninit()
+ {
+ }
+
STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent * aEvent)
{
// likely all this double copy is now excessive, and we can just use existing event object
@@ -689,7 +716,7 @@ void signal_handler_SIGINT(int sig)
#endif /* VBOXSDL_WITH_X11 */
-#ifdef RT_OS_WINDOWS
+#ifdef RT_OS_WINDOWS
// Required for ATL
static CComModule _Module;
#endif
@@ -777,9 +804,9 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
DeviceType_T bootDevice = DeviceType_Null;
uint32_t memorySize = 0;
uint32_t vramSize = 0;
- IEventListener *pVBoxClientListener = NULL;
- IEventListener *pVBoxListener = NULL;
- VBoxSDLConsoleEventListenerImpl *pConsoleListener = NULL;
+ ComPtr<IEventListener> pVBoxClientListener;
+ ComPtr<IEventListener> pVBoxListener;
+ ComObjPtr<VBoxSDLConsoleEventListenerImpl> pConsoleListener;
bool fFullscreen = false;
bool fResizable = true;
@@ -1431,7 +1458,8 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
/* we've not found the image */
RTPrintf("Adding hard disk '%s'...\n", hdaFile);
pVirtualBox->OpenMedium(bstrHdaFile.raw(), DeviceType_HardDisk,
- AccessMode_ReadWrite, pMedium.asOutParam());
+ AccessMode_ReadWrite, FALSE /* fForceNewUuid */,
+ pMedium.asOutParam());
}
/* do we have the right image now? */
if (pMedium)
@@ -1516,6 +1544,7 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
OpenMedium(bstrFdaFile.raw(),
DeviceType_Floppy,
AccessMode_ReadWrite,
+ FALSE /* fForceNewUuid */,
pMedium.asOutParam()));
}
}
@@ -1596,6 +1625,7 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
OpenMedium(bstrCdromFile.raw(),
DeviceType_DVD,
AccessMode_ReadWrite,
+ FALSE /* fForceNewUuid */,
pMedium.asOutParam()));
}
}
@@ -1839,7 +1869,10 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
// register listener for VirtualBoxClient events
ComPtr<IEventSource> pES;
CHECK_ERROR(pVirtualBoxClient, COMGETTER(EventSource)(pES.asOutParam()));
- pVBoxClientListener = new VBoxSDLClientEventListenerImpl();
+ ComObjPtr<VBoxSDLClientEventListenerImpl> listener;
+ listener.createObject();
+ listener->init(new VBoxSDLClientEventListener());
+ pVBoxClientListener = listener;
com::SafeArray<VBoxEventType_T> eventTypes;
eventTypes.push_back(VBoxEventType_OnVBoxSVCAvailabilityChanged);
CHECK_ERROR(pES, RegisterListener(pVBoxClientListener, ComSafeArrayAsInParam(eventTypes), true));
@@ -1849,7 +1882,10 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
// register listener for VirtualBox (server) events
ComPtr<IEventSource> pES;
CHECK_ERROR(pVirtualBox, COMGETTER(EventSource)(pES.asOutParam()));
- pVBoxListener = new VBoxSDLEventListenerImpl();
+ ComObjPtr<VBoxSDLEventListenerImpl> listener;
+ listener.createObject();
+ listener->init(new VBoxSDLEventListener());
+ pVBoxListener = listener;
com::SafeArray<VBoxEventType_T> eventTypes;
eventTypes.push_back(VBoxEventType_OnExtraDataChanged);
CHECK_ERROR(pES, RegisterListener(pVBoxListener, ComSafeArrayAsInParam(eventTypes), true));
@@ -1859,7 +1895,8 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
// register listener for Console events
ComPtr<IEventSource> pES;
CHECK_ERROR(gpConsole, COMGETTER(EventSource)(pES.asOutParam()));
- pConsoleListener = new VBoxSDLConsoleEventListenerImpl();
+ pConsoleListener.createObject();
+ pConsoleListener->init(new VBoxSDLConsoleEventListener());
com::SafeArray<VBoxEventType_T> eventTypes;
eventTypes.push_back(VBoxEventType_OnMousePointerShapeChanged);
eventTypes.push_back(VBoxEventType_OnMouseCapabilityChanged);
@@ -2731,8 +2768,7 @@ leave:
CHECK_ERROR(gpConsole, COMGETTER(EventSource)(pES.asOutParam()));
if (!pES.isNull())
CHECK_ERROR(pES, UnregisterListener(pConsoleListener));
- pConsoleListener->Release();
- pConsoleListener = NULL;
+ pConsoleListener.setNull();
}
/*
@@ -2831,8 +2867,7 @@ leave:
CHECK_ERROR(pVirtualBox, COMGETTER(EventSource)(pES.asOutParam()));
if (!pES.isNull())
CHECK_ERROR(pES, UnregisterListener(pVBoxListener));
- pVBoxListener->Release();
- pVBoxListener = NULL;
+ pVBoxListener.setNull();
}
/* VirtualBoxClient listener unregistration. */
@@ -2842,8 +2877,7 @@ leave:
CHECK_ERROR(pVirtualBoxClient, COMGETTER(EventSource)(pES.asOutParam()));
if (!pES.isNull())
CHECK_ERROR(pES, UnregisterListener(pVBoxClientListener));
- pVBoxClientListener->Release();
- pVBoxClientListener = NULL;
+ pVBoxClientListener.setNull();
}
LogFlow(("Releasing machine, session...\n"));
diff --git a/src/VBox/Frontends/VBoxSDL/VBoxSDLHardened.cpp b/src/VBox/Frontends/VBoxSDL/VBoxSDLHardened.cpp
index f2ae76400..45ea2aa8b 100644
--- a/src/VBox/Frontends/VBoxSDL/VBoxSDLHardened.cpp
+++ b/src/VBox/Frontends/VBoxSDL/VBoxSDLHardened.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxSDLHardened.cpp $ */
+/* $Id: VBoxSDLHardened.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxSDL - Hardened main().
*/
diff --git a/src/VBox/Frontends/VBoxSDL/VBoxSDLMain-darwin.m b/src/VBox/Frontends/VBoxSDL/VBoxSDLMain-darwin.m
index 6383e7c1a..6383e7c1a 100644..100755
--- a/src/VBox/Frontends/VBoxSDL/VBoxSDLMain-darwin.m
+++ b/src/VBox/Frontends/VBoxSDL/VBoxSDLMain-darwin.m
diff --git a/src/VBox/Frontends/VBoxSDL/VBoxSDLTest.cpp b/src/VBox/Frontends/VBoxSDL/VBoxSDLTest.cpp
index f4e503b57..8adb7822a 100644
--- a/src/VBox/Frontends/VBoxSDL/VBoxSDLTest.cpp
+++ b/src/VBox/Frontends/VBoxSDL/VBoxSDLTest.cpp
@@ -23,6 +23,7 @@
#include <iprt/assert.h>
#include <iprt/env.h>
+#include <iprt/initterm.h>
#include <iprt/stream.h>
#include <iprt/string.h>
#include <iprt/time.h>
@@ -69,6 +70,7 @@ int
main(int argc, char **argv)
{
int rc;
+ RTR3Init();
for (int i = 1; i < argc; i++)
{
diff --git a/src/VBox/Frontends/VBoxShell/Makefile.kmk b/src/VBox/Frontends/VBoxShell/Makefile.kmk
index 797906b60..5702fb21c 100644
--- a/src/VBox/Frontends/VBoxShell/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxShell/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 38003 2011-07-18 10:17:01Z vboxsync $
## @file
# Sub-Makefile for the shell frontend.
#
@@ -19,7 +19,7 @@ SUB_DEPTH = ../../../..
include $(KBUILD_PATH)/subheader.kmk
INSTALLS += VBoxShell
-VBoxShell_INST = $(INST_SDK)/bindings
+VBoxShell_INST = $(INST_SDK)/bindings/
VBoxShell_SOURCES = \
vboxshell.py=>glue/python/sample/vboxshell.py \
vboxinfo.vbs=>mscom/vbs/sample/vboxinfo.vbs \
diff --git a/src/VBox/Frontends/VBoxShell/vboxshell.py b/src/VBox/Frontends/VBoxShell/vboxshell.py
index f1a658341..e3d10dfa6 100755..100644
--- a/src/VBox/Frontends/VBoxShell/vboxshell.py
+++ b/src/VBox/Frontends/VBoxShell/vboxshell.py
@@ -51,7 +51,8 @@ term_colors = {
'blue':'\033[94m',
'green':'\033[92m',
'yellow':'\033[93m',
- 'magenta':'\033[35m'
+ 'magenta':'\033[35m',
+ 'cyan':'\033[36m'
}
def colored(string,color):
if not g_hascolors:
@@ -179,6 +180,7 @@ def progressBar(ctx,p,wait=1000):
return 1
except KeyboardInterrupt:
print "Interrupted."
+ ctx['interrupt'] = True
if p.cancelable:
print "Canceling task..."
p.cancel()
@@ -190,7 +192,7 @@ def printErr(ctx,e):
def reportError(ctx,progress):
ei = progress.errorInfo
if ei:
- print colored("Error in %s: %s" %(ei.component, ei.text), 'red')
+ print colored("Error in module '%s': %s" %(ei.component, ei.text), 'red')
def colCat(ctx,str):
return colored(str, 'magenta')
@@ -204,6 +206,12 @@ def colPath(ctx,p):
def colSize(ctx,m):
return colored(m, 'red')
+def colPci(ctx,vm):
+ return colored(vm, 'green')
+
+def colDev(ctx,vm):
+ return colored(vm, 'cyan')
+
def colSizeM(ctx,m):
return colored(str(m)+'M', 'red')
@@ -245,10 +253,7 @@ def startVm(ctx,mach,type):
printErr(ctx, e)
if g_verbose:
traceback.print_exc()
- # if session not opened, close doesn't make sense
session.unlockMachine()
- else:
- reportError(ctx,progress)
class CachedMach:
def __init__(self, mach):
@@ -481,6 +486,8 @@ def playbackDemo(ctx, console, file, dur):
mouse.putMouseEvent(int(mdict['x']), int(mdict['y']), int(mdict['z']), int(mdict['w']), int(mdict['b']))
# We need to catch all exceptions here, to close file
+ except KeyboardInterrupt:
+ ctx['interrupt'] = True
except:
traceback.print_exc()
pass
@@ -683,6 +690,8 @@ def cmdExistingVm(ctx,mach,cmd,args):
}
try:
ops[cmd]()
+ except KeyboardInterrupt:
+ ctx['interrupt'] = True
except Exception, e:
printErr(ctx,e)
if g_verbose:
@@ -808,7 +817,7 @@ class XPathNodeVM(XPathNode):
class XPathNodeHolderNIC(XPathNodeHolder):
def __init__(self, parent, mach):
XPathNodeHolder.__init__(self, parent, mach, 'nics', XPathNodeVM, 'nics')
- self.maxNic = self.getCtx()['vb'].systemProperties.networkAdapterCount
+ self.maxNic = self.getCtx()['vb'].systemProperties.getMaxNetworkAdapters(self.obj.chipsetType)
def enum(self):
children = []
for i in range(0, self.maxNic):
@@ -1106,6 +1115,7 @@ def execInGuest(ctx,console,args,env,user,passwd,tmo,inputPipe=None,outputPipe=N
except KeyboardInterrupt:
print "Interrupted."
+ ctx['interrupt'] = True
if progress.cancelable:
progress.cancel()
(reason, code, flags) = guest.getProcessStatus(pid)
@@ -1470,7 +1480,6 @@ def hostCmd(ctx, args):
print "VirtualBox version %s" %(colored(vb.version, 'blue'))
props = vb.systemProperties
print "Machines: %s" %(colPath(ctx,props.defaultMachineFolder))
- print "HDDs: %s" %(colPath(ctx,props.defaultHardDiskFolder))
#print "Global shared folders:"
#for ud in ctx['global'].getArray(vb, 'sharedFolders'):
@@ -1723,7 +1732,6 @@ def reloadExtCmd(ctx, args):
autoCompletion(commands, ctx)
return 0
-
def runScriptCmd(ctx, args):
if (len(args) != 2):
print "usage: runScript <script>"
@@ -1735,9 +1743,16 @@ def runScriptCmd(ctx, args):
return 0
try:
- for line in lf:
+ lines = lf.readlines()
+ ctx['scriptLine'] = 0
+ ctx['interrupt'] = False
+ while ctx['scriptLine'] < len(lines):
+ line = lines[ctx['scriptLine']]
+ ctx['scriptLine'] = ctx['scriptLine'] + 1
done = runCommand(ctx, line)
- if done != 0: break
+ if done != 0 or ctx['interrupt']:
+ break
+
except Exception,e:
printErr(ctx,e)
if g_verbose:
@@ -2602,9 +2617,9 @@ def natAlias(ctx, mach, nicnum, nat, args=[]):
else:
msg += ', '
if int(nat.aliasMode) & aliaskey:
- msg += '{0}: {1}'.format(aliasmode, 'on')
+ msg += '%d: %s' % (aliasmode, 'on')
else:
- msg += '{0}: {1}'.format(aliasmode, 'off')
+ msg += '%d: %s' % (aliasmode, 'off')
msg += ')'
return (0, [msg])
else:
@@ -2632,15 +2647,15 @@ def natSettings(ctx, mach, nicnum, nat, args):
if sockrcvbuf == 0: sockrcvbuf = 64
if tcpsndwnd == 0: tcpsndwnd = 64
if tcprcvwnd == 0: tcprcvwnd = 64
- msg = 'mtu:{0} socket(snd:{1}, rcv:{2}) tcpwnd(snd:{3}, rcv:{4})'.format(mtu, socksndbuf, sockrcvbuf, tcpsndwnd, tcprcvwnd);
+ msg = 'mtu:%s socket(snd:%s, rcv:%s) tcpwnd(snd:%s, rcv:%s)' % (mtu, socksndbuf, sockrcvbuf, tcpsndwnd, tcprcvwnd);
return (0, [msg])
else:
if args[1] < 16000:
- print 'invalid mtu value ({0} no in range [65 - 16000])'.format(args[1])
+ print 'invalid mtu value (%s not in range [65 - 16000])' % (args[1])
return (1, None)
for i in range(2, len(args)):
if not args[i].isdigit() or int(args[i]) < 8 or int(args[i]) > 1024:
- print 'invalid {0} parameter ({1} not in range [8-1024])'.format(i, args[i])
+ print 'invalid %s parameter (%i not in range [8-1024])' % (i, args[i])
return (1, None)
a = [args[1]]
if len(args) < 6:
@@ -2661,7 +2676,7 @@ def natDns(ctx, mach, nicnum, nat, args):
"""
yesno = {0: 'off', 1: 'on'}
if len(args) == 1:
- msg = 'passdomain:{0}, proxy:{1}, usehostresolver:{2}'.format(yesno[int(nat.dnsPassDomain)], yesno[int(nat.dnsProxy)], yesno[int(nat.dnsUseHostResolver)])
+ msg = 'passdomain:%s, proxy:%s, usehostresolver:%s' % (yesno[int(nat.dnsPassDomain)], yesno[int(nat.dnsProxy)], yesno[int(nat.dnsUseHostResolver)])
return (0, [msg])
else:
nat.dnsPassDomain = 'passdomain' in args
@@ -2681,19 +2696,19 @@ def natTftp(ctx, mach, nicnum, nat, args):
if server is None:
server = nat.network
if server is None:
- server = '10.0.{0}/24'.format(int(nicnum) + 2)
+ server = '10.0.%d/24' % (int(nicnum) + 2)
(server,mask) = server.split('/')
while server.count('.') != 3:
server += '.0'
(a,b,c,d) = server.split('.')
- server = '{0}.{1}.{2}.4'.format(a,b,c)
+ server = '%d.%d.%d.4' % (a,b,c)
prefix = nat.tftpPrefix
if prefix is None:
- prefix = '{0}/TFTP/'.format(ctx['vb'].homeFolder)
+ prefix = '%s/TFTP/' % (ctx['vb'].homeFolder)
bootfile = nat.tftpBootFile
if bootfile is None:
- bootfile = '{0}.pxe'.format(mach.name)
- msg = 'server:{0}, prefix:{1}, bootfile:{2}'.format(server, prefix, bootfile)
+ bootfile = '%s.pxe' % (mach.name)
+ msg = 'server:%s, prefix:%s, bootfile:%s' % (server, prefix, bootfile)
return (0, [msg])
else:
@@ -2725,7 +2740,7 @@ def natPortForwarding(ctx, mach, nicnum, nat, args):
pfs = ctx['global'].getArray(nat, 'redirects')
for pf in pfs:
(pfnme, pfp, pfhip, pfhp, pfgip, pfgp) = str(pf).split(',')
- msg.append('{0}: {1} {2}:{3} => {4}:{5}'.format(pfnme, proto[int(pfp)], pfhip, pfhp, pfgip, pfgp))
+ msg.append('%s: %s %s:%s => %s:%s' % (pfnme, proto[int(pfp)], pfhip, pfhp, pfgip, pfgp))
return (0, msg) # msg is array
else:
proto = {'udp': 0, 'tcp': 1}
@@ -2764,7 +2779,7 @@ def natNetwork(ctx, mach, nicnum, nat, args):
if nat.network is not None and len(str(nat.network)) != 0:
msg = '\'%s\'' % (nat.network)
else:
- msg = '10.0.{0}.0/24'.format(int(nicnum) + 2)
+ msg = '10.0.%d.0/24' % (int(nicnum) + 2)
return (0, [msg])
else:
(addr, mask) = args[1].split('/')
@@ -2804,8 +2819,8 @@ def natCmd(ctx, args):
if mach == None:
print "please specify vm"
return 0
- if len(args) < 3 or not args[2].isdigit() or int(args[2]) not in range(0, ctx['vb'].systemProperties.networkAdapterCount):
- print 'please specify adapter num {0} isn\'t in range [0-{1}]'.format(args[2], ctx['vb'].systemProperties.networkAdapterCount)
+ if len(args) < 3 or not args[2].isdigit() or int(args[2]) not in range(0, ctx['vb'].systemProperties.getMaxNetworkAdapters(mach.chipsetType)):
+ print 'please specify adapter num %d isn\'t in range [0-%d]' % (args[2], ctx['vb'].systemProperties.getMaxNetworkAdapters(mach.chipsetType))
return 0
nicnum = int(args[2])
cmdargs = []
@@ -2831,7 +2846,7 @@ def natCmd(ctx, args):
session.unlockMachine()
elif report is not None:
for r in report:
- msg ='{0} nic{1} {2}: {3}'.format(mach.name, nicnum, func, r)
+ msg ='%s nic%d %s: %s' % (mach.name, nicnum, func, r)
print msg
return 0
@@ -2866,7 +2881,7 @@ def nicLineSpeedSubCmd(ctx, vm, nicnum, adapter, args):
return (0, r)
else:
if not args[1].isdigit():
- print '%s isn\'t a number'.format(args[1])
+ print '%s isn\'t a number' % (args[1])
print (1, None)
adapter.lineSpeed = int(args[1])
return (0, None)
@@ -2903,16 +2918,17 @@ def nicTypeSubCmd(ctx, vm, nicnum, adapter, args):
def nicAttachmentSubCmd(ctx, vm, nicnum, adapter, args):
'''
- usage: nic <vm> <nicnum> attachment [Null|NAT|Bridged <interface>|Internal <name>|HostOnly <interface>]
+ usage: nic <vm> <nicnum> attachment [Null|NAT|Bridged <interface>|Internal <name>|HostOnly <interface>
'''
if len(args) == 1:
nicAttachmentType = {
ctx['global'].constants.NetworkAttachmentType_Null: ('Null', ''),
ctx['global'].constants.NetworkAttachmentType_NAT: ('NAT', ''),
- ctx['global'].constants.NetworkAttachmentType_Bridged: ('Bridged', adapter.hostInterface),
+ ctx['global'].constants.NetworkAttachmentType_Bridged: ('Bridged', adapter.bridgedInterface),
ctx['global'].constants.NetworkAttachmentType_Internal: ('Internal', adapter.internalNetwork),
- ctx['global'].constants.NetworkAttachmentType_HostOnly: ('HostOnly', adapter.hostInterface),
- #ctx['global'].constants.NetworkAttachmentType_VDE: ('VDE', adapter.VDENetwork)
+ ctx['global'].constants.NetworkAttachmentType_HostOnly: ('HostOnly', adapter.hostOnlyInterface),
+ # @todo show details of the generic network attachment type
+ ctx['global'].constants.NetworkAttachmentType_Generic: ('Generic', ''),
}
import types
if type(adapter.attachmentType) != types.IntType:
@@ -2920,42 +2936,43 @@ def nicAttachmentSubCmd(ctx, vm, nicnum, adapter, args):
else:
t = adapter.attachmentType
(r, p) = nicAttachmentType[t]
- return (0, 'attachment:{0}, name:{1}'.format(r, p))
+ return (0, 'attachment:%s, name:%s' % (r, p))
else:
nicAttachmentType = {
'Null': {
'v': lambda: len(args) == 2,
'p': lambda: 'do nothing',
- 'f': lambda: adapter.detach()},
+ 'f': lambda: ctx['global'].constants.NetworkAttachmentType_Null},
'NAT': {
'v': lambda: len(args) == 2,
'p': lambda: 'do nothing',
- 'f': lambda: adapter.attachToNAT()},
+ 'f': lambda: ctx['global'].constants.NetworkAttachmentType_NAT},
'Bridged': {
'v': lambda: len(args) == 3,
- 'p': lambda: adapter.__setattr__('hostInterface', args[2]),
- 'f': lambda: adapter.attachToBridgedInterface()},
+ 'p': lambda: adapter.__setattr__('bridgedInterface', args[2]),
+ 'f': lambda: ctx['global'].constants.NetworkAttachmentType_Bridged},
'Internal': {
'v': lambda: len(args) == 3,
'p': lambda: adapter.__setattr__('internalNetwork', args[2]),
- 'f': lambda: adapter.attachToInternalNetwork()},
+ 'f': lambda: ctx['global'].constants.NetworkAttachmentType_Internal},
'HostOnly': {
'v': lambda: len(args) == 2,
- 'p': lambda: adapter.__setattr__('hostInterface', args[2]),
- 'f': lambda: adapter.attachToHostOnlyInterface()},
- 'VDE': {
+ 'p': lambda: adapter.__setattr__('hostOnlyInterface', args[2]),
+ 'f': lambda: ctx['global'].constants.NetworkAttachmentType_HostOnly},
+ # @todo implement setting the properties of a generic attachment
+ 'Generic': {
'v': lambda: len(args) == 3,
- 'p': lambda: adapter.__setattr__('VDENetwork', args[2]),
- 'f': lambda: adapter.attachToVDE()}
+ 'p': lambda: 'do nothing',
+ 'f': lambda: ctx['global'].constants.NetworkAttachmentType_Generic}
}
if args[1] not in nicAttachmentType.keys():
- print '{0} not in acceptable values ({1})'.format(args[1], nicAttachmentType.keys())
+ print '%s not in acceptable values (%s)' % (args[1], nicAttachmentType.keys())
return (1, None)
if not nicAttachmentType[args[1]]['v']():
print nicAttachmentType.__doc__
return (1, None)
nicAttachmentType[args[1]]['p']()
- nicAttachmentType[args[1]]['f']()
+ adapter.attachmentType = nicAttachmentType[args[1]]['f']()
return (0, None)
def nicCmd(ctx, args):
@@ -2989,8 +3006,8 @@ def nicCmd(ctx, args):
return 0
if len(args) < 3 \
- or int(args[2]) not in range(0, ctx['vb'].systemProperties.networkAdapterCount):
- print 'please specify adapter num %d isn\'t in range [0-%d]'%(args[2], ctx['vb'].systemProperties.networkAdapterCount)
+ or int(args[2]) not in range(0, ctx['vb'].systemProperties.getMaxNetworkAdapters(vm.chipsetType)):
+ print 'please specify adapter num %d isn\'t in range [0-%d]'%(args[2], ctx['vb'].systemProperties.getMaxNetworkAdapters(vm.chipsetType))
return 0
nicnum = int(args[2])
cmdargs = args[3:]
@@ -3071,6 +3088,91 @@ def playbackDemoCmd(ctx, args):
cmdExistingVm(ctx, mach, 'guestlambda', [lambda ctx,mach,console,args: playbackDemo(ctx, console, filename, dur)])
return 0
+
+def pciAddr(ctx,addr):
+ str = "%02x:%02x.%d" %(addr >> 8, (addr & 0xff) >> 3, addr & 7)
+ return colPci(ctx, str)
+
+def lspci(ctx, console):
+ assigned = ctx['global'].getArray(console.machine, 'pciDeviceAssignments')
+ for a in assigned:
+ if a.isPhysicalDevice:
+ print "%s: assigned host device %s guest %s" %(colDev(ctx, a.name), pciAddr(ctx, a.hostAddress), pciAddr(ctx, a.guestAddress))
+
+ atts = ctx['global'].getArray(console, 'attachedPciDevices')
+ for a in atts:
+ if a.isPhysicalDevice:
+ print "%s: physical, guest %s, host %s" %(colDev(ctx, a.name), pciAddr(ctx, a.guestAddress), pciAddr(ctx, a.hostAddress))
+ else:
+ print "%s: virtual, guest %s" %(colDev(ctx, a.name), pciAddr(ctx, a.guestAddress))
+ return
+
+def parsePci(str):
+ pcire = re.compile(r'(?P<b>[0-9a-fA-F]+):(?P<d>[0-9a-fA-F]+)\.(?P<f>\d)')
+ m = pcire.search(str)
+ if m is None:
+ return -1
+ dict = m.groupdict()
+ return ((int(dict['b'], 16)) << 8) | ((int(dict['d'], 16)) << 3) | int(dict['f'])
+
+def lspciCmd(ctx, args):
+ if (len(args) < 2):
+ print "usage: lspci vm"
+ return 0
+ mach = argsToMach(ctx,args)
+ if mach == None:
+ return 0
+ cmdExistingVm(ctx, mach, 'guestlambda', [lambda ctx,mach,console,args: lspci(ctx, console)])
+ return 0
+
+def attachpciCmd(ctx, args):
+ if (len(args) < 3):
+ print "usage: attachpci vm hostpci <guestpci>"
+ return 0
+ mach = argsToMach(ctx,args)
+ if mach == None:
+ return 0
+ hostaddr = parsePci(args[2])
+ if hostaddr == -1:
+ print "invalid host PCI %s, accepted format 01:02.3 for bus 1, device 2, function 3" %(args[2])
+ return 0
+
+ if (len(args) > 3):
+ guestaddr = parsePci(args[3])
+ if guestaddr == -1:
+ print "invalid guest PCI %s, accepted format 01:02.3 for bus 1, device 2, function 3" %(args[3])
+ return 0
+ else:
+ guestaddr = hostaddr
+ cmdClosedVm(ctx, mach, lambda ctx,mach,a: mach.attachHostPciDevice(hostaddr, guestaddr, True))
+ return 0
+
+def detachpciCmd(ctx, args):
+ if (len(args) < 3):
+ print "usage: detachpci vm hostpci"
+ return 0
+ mach = argsToMach(ctx,args)
+ if mach == None:
+ return 0
+ hostaddr = parsePci(args[2])
+ if hostaddr == -1:
+ print "invalid host PCI %s, accepted format 01:02.3 for bus 1, device 2, function 3" %(args[2])
+ return 0
+
+ cmdClosedVm(ctx, mach, lambda ctx,mach,a: mach.detachHostPciDevice(hostaddr))
+ return 0
+
+def gotoCmd(ctx, args):
+ if (len(args) < 2):
+ print "usage: goto line"
+ return 0
+
+ line = int(args[1])
+
+ ctx['scriptLine'] = line
+
+ return 0
+
aliases = {'s':'start',
'i':'info',
'l':'list',
@@ -3152,11 +3254,15 @@ commands = {'help':['Prints help information', helpCmd, 0],
'snapshot':['VM snapshot manipulation, snapshot help for more info', snapshotCmd, 0],
'nat':['NAT (network address translation engine) manipulation, nat help for more info', natCmd, 0],
'nic' : ['Network adapter management', nicCmd, 0],
- 'prompt' : ['Control prompt', promptCmd, 0],
+ 'prompt' : ['Control shell prompt', promptCmd, 0],
'foreachvm' : ['Perform command for each VM', foreachvmCmd, 0],
'foreach' : ['Generic "for each" construction, using XPath-like notation: foreach //vms/vm[@OSTypeId=\'MacOS\'] "print obj.name"', foreachCmd, 0],
'recordDemo':['Record demo: recordDemo Win32 file.dmo 10', recordDemoCmd, 0],
- 'playbackDemo':['Playback demo: playbackDemo Win32 file.dmo 10', playbackDemoCmd, 0]
+ 'playbackDemo':['Playback demo: playbackDemo Win32 file.dmo 10', playbackDemoCmd, 0],
+ 'lspci': ['List PCI devices attached to the VM: lspci Win32', lspciCmd, 0],
+ 'attachpci': ['Attach host PCI device to the VM: attachpci Win32 01:00.0', attachpciCmd, 0],
+ 'detachpci': ['Detach host PCI device from the VM: detachpci Win32 01:00.0', detachpciCmd, 0],
+ 'goto': ['Go to line in script (script-only)', gotoCmd, 0]
}
def runCommandArgs(ctx, args):
@@ -3250,7 +3356,7 @@ def interpret(ctx):
home = getHomeFolder(ctx)
checkUserExtensions(ctx, commands, home)
- if platform.system() == 'Windows':
+ if platform.system() in ['Windows', 'Microsoft']:
global g_hascolors
g_hascolors = False
hist_file=os.path.join(home, ".vboxshellhistory")
@@ -3383,7 +3489,9 @@ def main(argv):
'progressBar': lambda p: progressBar(ctx,p),
'typeInGuest': typeInGuest,
'_machlist': None,
- 'prompt': g_prompt
+ 'prompt': g_prompt,
+ 'scriptLine': 0,
+ 'interrupt': False
}
interpret(ctx)
g_virtualBoxManager.deinit()
diff --git a/src/VBox/Frontends/VirtualBox/Makefile.kmk b/src/VBox/Frontends/VirtualBox/Makefile.kmk
index a2d0d4942..96c6a591a 100644
--- a/src/VBox/Frontends/VirtualBox/Makefile.kmk
+++ b/src/VBox/Frontends/VirtualBox/Makefile.kmk
@@ -1,10 +1,10 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 38002 2011-07-18 10:16:41Z vboxsync $
## @file
# Makefile for the VirtualBox Qt GUI.
#
#
-# 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;
@@ -128,6 +128,7 @@ VirtualBox_DEFS += \
$(if $(VBOX_WITH_E1000),VBOX_WITH_E1000) \
$(if $(VBOX_WITH_NETFLT)$(eq $(KBUILD_TARGET),freebsd),VBOX_WITH_NETFLT) \
$(if $(VBOX_WITH_VDE),VBOX_WITH_VDE) \
+ $(if $(VBOX_WITH_UDPTUNNEL),VBOX_WITH_UDPTUNNEL) \
$(if $(VBOX_WITH_EHCI),VBOX_WITH_EHCI) \
$(if $(VBOX_GUI_WITH_PIDFILE),VBOX_GUI_WITH_PIDFILE) \
$(if $(VBOX_GUI_WITH_KEYS_RESET_HANDLER),VBOX_GUI_WITH_KEYS_RESET_HANDLER) \
@@ -176,6 +177,7 @@ VBOX_GUI_INC_DIRS = \
./src/settings \
./src/settings/global \
./src/settings/machine \
+ ./src/wizards/clonevm \
./src/wizards/newvm \
./src/wizards/newhd \
./src/wizards/firstrun \
@@ -225,9 +227,14 @@ else
endif
endif
-if defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_GUI_USE_QGL)
- VirtualBox_LDFLAGS.win += /DelayLoad:QtOpenGLVBox4.dll /DelayLoad:OPENGL32.dll
-endif
+# delay loading causes VM process crashes due to the misbehave of the current QtOpenGLVBox4.dll we use
+# (i.e. it does not create the ogl context properly when loaded this way)
+#
+# @todo: investigate a better work-around and enable back delay loading since it is needed to avoid
+# crashes caused by buggy ogl drivers for the case 2D is not used (i.e. no ogl stuff loaded)
+#if defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_GUI_USE_QGL)
+# VirtualBox_LDFLAGS.win += /DelayLoad:QtOpenGLVBox4.dll /DelayLoad:OPENGL32.dll
+#endif
VirtualBox_LDFLAGS.darwin = \
-framework AppKit -framework Carbon \
@@ -259,6 +266,7 @@ VirtualBox_QT_MOCHDRS = \
src/VBoxAboutDlg.h \
src/VBoxGlobalSettings.h \
src/VBoxMediaManagerDlg.h \
+ src/UIMediumTypeChangeDialog.h \
src/VBoxSnapshotDetailsDlg.h \
src/VBoxTakeSnapshotDlg.h \
src/VBoxUpdateDlg.h \
@@ -304,6 +312,7 @@ VirtualBox_QT_MOCHDRS = \
src/settings/global/UIGlobalSettingsNetwork.h \
src/settings/global/UIGlobalSettingsNetworkDetails.h \
src/settings/global/UIGlobalSettingsExtension.h \
+ src/settings/global/UIGlobalSettingsProxy.h \
src/settings/machine/UIMachineSettingsGeneral.h \
src/settings/machine/UIMachineSettingsSystem.h \
src/settings/machine/UIMachineSettingsDisplay.h \
@@ -317,8 +326,9 @@ VirtualBox_QT_MOCHDRS = \
src/settings/machine/UIMachineSettingsUSBFilterDetails.h \
src/settings/machine/UIMachineSettingsSF.h \
src/settings/machine/UIMachineSettingsSFDetails.h \
+ src/wizards/clonevm/UICloneVMWizard.h \
src/wizards/newvm/UINewVMWzd.h \
- src/wizards/newhd/UINewHDWzd.h \
+ src/wizards/newhd/UINewHDWizard.h \
src/wizards/firstrun/UIFirstRunWzd.h \
src/wizards/exportappliance/UIExportApplianceWzd.h \
src/wizards/importappliance/UIImportApplianceWzd.h \
@@ -392,8 +402,8 @@ VirtualBox_QT_MOCSRCS = \
src/runtime/UIActionsPool.cpp \
src/runtime/UIIndicatorsPool.cpp \
src/runtime/UIMachine.cpp \
- src/runtime/UIMachineLogic.cpp \
- src/runtime/UIMachineMenuBar.cpp
+ src/runtime/UIMachineMenuBar.cpp \
+ src/wizards/newhd/UINewHDWizard.cpp
VirtualBox_QT_MOCSRCS.darwin += \
src/platform/darwin/UIWindowMenuManager.cpp
@@ -421,6 +431,7 @@ VirtualBox_SOURCES = \
src/VBoxGlobalSettings.cpp \
src/VBoxHelpActions.cpp \
src/VBoxMediaManagerDlg.cpp \
+ src/UIMediumTypeChangeDialog.cpp \
src/VBoxMedium.cpp \
src/VBoxSnapshotDetailsDlg.cpp \
src/VBoxTakeSnapshotDlg.cpp \
@@ -458,6 +469,7 @@ VirtualBox_SOURCES = \
src/extensions/QITreeWidget.cpp \
src/extensions/QIWidgetValidator.cpp \
src/extensions/QIWizard.cpp \
+ src/settings/UISettingsDefs.cpp \
src/settings/UISettingsDialog.cpp \
src/settings/UISettingsDialogSpecific.cpp \
src/settings/UISettingsPage.cpp \
@@ -469,6 +481,7 @@ VirtualBox_SOURCES = \
src/settings/global/UIGlobalSettingsNetwork.cpp \
src/settings/global/UIGlobalSettingsNetworkDetails.cpp \
src/settings/global/UIGlobalSettingsExtension.cpp \
+ src/settings/global/UIGlobalSettingsProxy.cpp \
src/settings/machine/UIMachineSettingsGeneral.cpp \
src/settings/machine/UIMachineSettingsSystem.cpp \
src/settings/machine/UIMachineSettingsDisplay.cpp \
@@ -482,8 +495,9 @@ VirtualBox_SOURCES = \
src/settings/machine/UIMachineSettingsUSBFilterDetails.cpp \
src/settings/machine/UIMachineSettingsSF.cpp \
src/settings/machine/UIMachineSettingsSFDetails.cpp \
+ src/wizards/clonevm/UICloneVMWizard.cpp \
src/wizards/newvm/UINewVMWzd.cpp \
- src/wizards/newhd/UINewHDWzd.cpp \
+ src/wizards/newhd/UINewHDWizard.cpp \
src/wizards/firstrun/UIFirstRunWzd.cpp \
src/wizards/exportappliance/UIExportApplianceWzd.cpp \
src/wizards/importappliance/UIImportApplianceWzd.cpp \
@@ -573,7 +587,8 @@ endif
VirtualBox_SOURCES.win += \
src/platform/win/VirtualBox.rc \
- src/platform/win/UIDesktopServices_win.cpp
+ src/platform/win/UIDesktopServices_win.cpp \
+ src/platform/win/VBoxUtils-win.cpp
VirtualBox_DEFS.darwin += VBOX_DARWIN_USE_NATIVE_CONTROLS
VirtualBox_SOURCES.darwin += \
@@ -857,7 +872,11 @@ VirtualBox.app_SOURCES = \
$(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-vbox.icns=>Resources/virtualbox-vbox.icns \
$(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-vbox-extpack.icns=>Resources/virtualbox-vbox-extpack.icns \
$(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-ovf.icns=>Resources/virtualbox-ovf.icns \
- $(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-ova.icns=>Resources/virtualbox-ova.icns
+ $(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-ova.icns=>Resources/virtualbox-ova.icns \
+ $(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-vdi.icns=>Resources/virtualbox-vdi.icns \
+ $(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-vmdk.icns=>Resources/virtualbox-vmdk.icns \
+ $(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-vhd.icns=>Resources/virtualbox-vhd.icns \
+ $(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-hdd.icns=>Resources/virtualbox-hdd.icns
$$(VirtualBox.app_0_OUTDIR)/Info.plist: $(PATH_SUB_CURRENT)/src/platform/darwin/Info.plist $(VBOX_VERSION_MK) | $$(@D)/
$(call MSG_GENERATE,VirtualBox.app,$<,$@)
@@ -902,7 +921,7 @@ vmstarter_LDFLAGS += -framework AppKit
vmstarter_INST = $(INST_BIN)vmstarter
INSTALLS += vmstarter.app
-vmstarter.app_INST = $(VirtualBox.app_INST)Resources/vmstarter.app/Contents
+vmstarter.app_INST = $(VirtualBox.app_INST)Resources/vmstarter.app/Contents/
vmstarter.app_MODE = 644
vmstarter.app_SOURCES = \
src/platform/darwin/vmstarter-PkgInfo=>PkgInfo \
diff --git a/src/VBox/Frontends/VirtualBox/VBoxUI.pro b/src/VBox/Frontends/VirtualBox/VBoxUI.pro
index 8f982d6f7..72de48e92 100644
--- a/src/VBox/Frontends/VirtualBox/VBoxUI.pro
+++ b/src/VBox/Frontends/VirtualBox/VBoxUI.pro
@@ -6,7 +6,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,6 +35,7 @@ FORMS = \
src/settings/global/UIGlobalSettingsNetwork.ui \
src/settings/global/UIGlobalSettingsNetworkDetails.ui \
src/settings/global/UIGlobalSettingsExtension.ui \
+ src/settings/global/UIGlobalSettingsProxy.ui \
src/settings/machine/UIMachineSettingsGeneral.ui \
src/settings/machine/UIMachineSettingsSystem.ui \
src/settings/machine/UIMachineSettingsDisplay.ui \
@@ -47,15 +48,18 @@ FORMS = \
src/settings/machine/UIMachineSettingsUSBFilterDetails.ui \
src/settings/machine/UIMachineSettingsSF.ui \
src/settings/machine/UIMachineSettingsSFDetails.ui \
+ src/wizards/clonevm/UICloneVMWizardPage1.ui \
+ src/wizards/clonevm/UICloneVMWizardPage2.ui \
src/wizards/newvm/UINewVMWzdPage1.ui \
src/wizards/newvm/UINewVMWzdPage2.ui \
src/wizards/newvm/UINewVMWzdPage3.ui \
src/wizards/newvm/UINewVMWzdPage4.ui \
src/wizards/newvm/UINewVMWzdPage5.ui \
- src/wizards/newhd/UINewHDWzdPage1.ui \
- src/wizards/newhd/UINewHDWzdPage2.ui \
- src/wizards/newhd/UINewHDWzdPage3.ui \
- src/wizards/newhd/UINewHDWzdPage4.ui \
+ src/wizards/newhd/UINewHDWizardPageWelcome.ui \
+ src/wizards/newhd/UINewHDWizardPageFormat.ui \
+ src/wizards/newhd/UINewHDWizardPageVariant.ui \
+ src/wizards/newhd/UINewHDWizardPageOptions.ui \
+ src/wizards/newhd/UINewHDWizardPageSummary.ui \
src/wizards/firstrun/UIFirstRunWzdPage1.ui \
src/wizards/firstrun/UIFirstRunWzdPage2.ui \
src/wizards/firstrun/UIFirstRunWzdPage3.ui \
diff --git a/src/VBox/Frontends/VirtualBox/VirtualBox1.qrc b/src/VBox/Frontends/VirtualBox/VirtualBox1.qrc
index 1faef26ad..d790f91f8 100644
--- a/src/VBox/Frontends/VirtualBox/VirtualBox1.qrc
+++ b/src/VBox/Frontends/VirtualBox/VirtualBox1.qrc
@@ -13,6 +13,8 @@
<file alias="vm_pause_disabled_32px.png">images/vm_pause_disabled_32px.png</file>
<file alias="vm_settings_32px.png">images/vm_settings_32px.png</file>
<file alias="vm_settings_disabled_32px.png">images/vm_settings_disabled_32px.png</file>
+ <file alias="vm_clone_16px.png">images/vm_clone_16px.png</file>
+ <file alias="vm_clone_disabled_16px.png">images/vm_clone_disabled_16px.png</file>
<file alias="vm_show_logs_32px.png">images/vm_show_logs_32px.png</file>
<file alias="vm_show_logs_disabled_32px.png">images/vm_show_logs_disabled_32px.png</file>
<file alias="vm_start_32px.png">images/vm_start_32px.png</file>
@@ -34,12 +36,14 @@
<file alias="online_snapshot_16px.png">images/online_snapshot_16px.png</file>
<file alias="machine_16px.png">images/machine_16px.png</file>
<file alias="machine_32px.png">images/machine_32px.png</file>
+ <file alias="machine_disabled_16px.png">images/machine_disabled_16px.png</file>
<file alias="machine_disabled_32px.png">images/machine_disabled_32px.png</file>
<file alias="help_16px.png">images/help_16px.png</file>
<file alias="help_button_normal_mac_22px.png">images/help_button_normal_mac_22px.png</file>
<file alias="help_button_pressed_mac_22px.png">images/help_button_pressed_mac_22px.png</file>
<file alias="site_16px.png">images/site_16px.png</file>
<file alias="site_32px.png">images/site_32px.png</file>
+ <file alias="site_disabled_16px.png">images/site_disabled_16px.png</file>
<file alias="site_disabled_32px.png">images/site_disabled_32px.png</file>
<file alias="register_16px.png">images/register_16px.png</file>
<file alias="register_32px.png">images/register_32px.png</file>
diff --git a/src/VBox/Frontends/VirtualBox/VirtualBox2.qrc b/src/VBox/Frontends/VirtualBox/VirtualBox2.qrc
index ca9dcc67f..abde5e020 100644
--- a/src/VBox/Frontends/VirtualBox/VirtualBox2.qrc
+++ b/src/VBox/Frontends/VirtualBox/VirtualBox2.qrc
@@ -26,8 +26,8 @@
<file alias="os_netware.png">images/os_netware.png</file>
<file alias="os_openbsd.png">images/os_openbsd.png</file>
<file alias="os_openbsd_64.png">images/os_openbsd_64.png</file>
- <file alias="os_opensolaris.png">images/os_opensolaris.png</file>
- <file alias="os_opensolaris_64.png">images/os_opensolaris_64.png</file>
+ <file alias="os_oraclesolaris.png">images/os_oraclesolaris.png</file>
+ <file alias="os_oraclesolaris_64.png">images/os_oraclesolaris_64.png</file>
<file alias="os_opensuse.png">images/os_opensuse.png</file>
<file alias="os_opensuse_64.png">images/os_opensuse_64.png</file>
<file alias="os_os2_other.png">images/os_os2_other.png</file>
@@ -160,6 +160,7 @@
<file alias="progress_snapshot_create_90px.png">images/progress_snapshot_create_90px.png</file>
<file alias="progress_snapshot_restore_90px.png">images/progress_snapshot_restore_90px.png</file>
<file alias="progress_snapshot_discard_90px.png">images/progress_snapshot_discard_90px.png</file>
+ <file alias="progress_clone_90px.png">images/progress_clone_90px.png</file>
<file alias="status_check_16px.png">images/status_check_16px.png</file>
<file alias="status_check_32px.png">images/status_check_32px.png</file>
<file alias="status_error_16px.png">images/status_error_16px.png</file>
@@ -176,5 +177,9 @@
<file alias="extension_pack_uninstall_disabled_16px.png">images/extension_pack_uninstall_disabled_16px.png</file>
<file alias="extension_pack_uninstall_32px.png">images/extension_pack_uninstall_32px.png</file>
<file alias="extension_pack_uninstall_disabled_32px.png">images/extension_pack_uninstall_disabled_32px.png</file>
+ <file alias="proxy_16px.png">images/proxy_16px.png</file>
+ <file alias="proxy_disabled_16px.png">images/proxy_disabled_16px.png</file>
+ <file alias="proxy_32px.png">images/proxy_32px.png</file>
+ <file alias="proxy_disabled_32px.png">images/proxy_disabled_32px.png</file>
</qresource>
</RCC>
diff --git a/src/VBox/Frontends/VirtualBox/VirtualBoxMac.qrc b/src/VBox/Frontends/VirtualBox/VirtualBoxMac.qrc
index 3714d115f..9e7335ddf 100644
--- a/src/VBox/Frontends/VirtualBox/VirtualBoxMac.qrc
+++ b/src/VBox/Frontends/VirtualBox/VirtualBoxMac.qrc
@@ -6,6 +6,7 @@
<file alias="vmw_new_user_bg.png">images/vmw_new_user_bg.png</file>
<file alias="vmw_ovf_import_bg.png">images/vmw_ovf_import_bg.png</file>
<file alias="vmw_ovf_export_bg.png">images/vmw_ovf_export_bg.png</file>
+ <file alias="vmw_clone_bg.png">images/vmw_clone_bg.png</file>
<file alias="monitor.png">images/monitor.png</file>
<file alias="monitor_glossy.png">images/monitor_glossy.png</file>
</qresource>
diff --git a/src/VBox/Frontends/VirtualBox/VirtualBoxOther.qrc b/src/VBox/Frontends/VirtualBox/VirtualBoxOther.qrc
index 13fd92c70..7d1d9221d 100644
--- a/src/VBox/Frontends/VirtualBox/VirtualBoxOther.qrc
+++ b/src/VBox/Frontends/VirtualBox/VirtualBoxOther.qrc
@@ -6,5 +6,6 @@
<file alias="vmw_first_run.png">images/vmw_first_run.png</file>
<file alias="vmw_ovf_export.png">images/vmw_ovf_export.png</file>
<file alias="vmw_ovf_import.png">images/vmw_ovf_import.png</file>
+ <file alias="vmw_clone.png">images/vmw_clone.png</file>
</qresource>
</RCC>
diff --git a/src/VBox/Frontends/VirtualBox/images/os_opensolaris.png b/src/VBox/Frontends/VirtualBox/images/os_opensolaris.png
deleted file mode 100644
index fd7af77e8..000000000
--- a/src/VBox/Frontends/VirtualBox/images/os_opensolaris.png
+++ /dev/null
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/images/os_opensolaris_64.png b/src/VBox/Frontends/VirtualBox/images/os_opensolaris_64.png
deleted file mode 100644
index 057581df8..000000000
--- a/src/VBox/Frontends/VirtualBox/images/os_opensolaris_64.png
+++ /dev/null
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/images/os_oraclesolaris.png b/src/VBox/Frontends/VirtualBox/images/os_oraclesolaris.png
new file mode 100644
index 000000000..c5e5df58e
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/images/os_oraclesolaris.png
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/images/os_oraclesolaris_64.png b/src/VBox/Frontends/VirtualBox/images/os_oraclesolaris_64.png
new file mode 100644
index 000000000..1cf06eaf0
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/images/os_oraclesolaris_64.png
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/images/progress_clone_90px.png b/src/VBox/Frontends/VirtualBox/images/progress_clone_90px.png
new file mode 100644
index 000000000..190f3c9e2
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/images/progress_clone_90px.png
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/images/proxy_16px.png b/src/VBox/Frontends/VirtualBox/images/proxy_16px.png
new file mode 100644
index 000000000..46b458661
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/images/proxy_16px.png
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/images/proxy_32px.png b/src/VBox/Frontends/VirtualBox/images/proxy_32px.png
new file mode 100644
index 000000000..f95598e0c
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/images/proxy_32px.png
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/images/proxy_disabled_16px.png b/src/VBox/Frontends/VirtualBox/images/proxy_disabled_16px.png
new file mode 100644
index 000000000..90ecd9e9a
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/images/proxy_disabled_16px.png
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/images/proxy_disabled_32px.png b/src/VBox/Frontends/VirtualBox/images/proxy_disabled_32px.png
new file mode 100644
index 000000000..bd5a15275
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/images/proxy_disabled_32px.png
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/images/vm_clone_16px.png b/src/VBox/Frontends/VirtualBox/images/vm_clone_16px.png
new file mode 100644
index 000000000..5fa77d4ac
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/images/vm_clone_16px.png
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/images/vm_clone_disabled_16px.png b/src/VBox/Frontends/VirtualBox/images/vm_clone_disabled_16px.png
new file mode 100644
index 000000000..673b2a6f9
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/images/vm_clone_disabled_16px.png
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/images/vmw_clone.png b/src/VBox/Frontends/VirtualBox/images/vmw_clone.png
new file mode 100644
index 000000000..79dcf6197
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/images/vmw_clone.png
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/images/vmw_clone_bg.png b/src/VBox/Frontends/VirtualBox/images/vmw_clone_bg.png
new file mode 100644
index 000000000..2872b1ce4
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/images/vmw_clone_bg.png
Binary files differ
diff --git a/src/VBox/Frontends/VirtualBox/nls/ApprovedLanguages.kmk b/src/VBox/Frontends/VirtualBox/nls/ApprovedLanguages.kmk
index 905238525..e4cadd809 100644
--- a/src/VBox/Frontends/VirtualBox/nls/ApprovedLanguages.kmk
+++ b/src/VBox/Frontends/VirtualBox/nls/ApprovedLanguages.kmk
@@ -1,4 +1,4 @@
-# $Id: ApprovedLanguages.kmk $
+# $Id: ApprovedLanguages.kmk 31132 2010-07-27 09:06:38Z vboxsync $
## @file
# ApprovedLanguages.kmk - List of approved GUI translations
#
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ar.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ar.ts
index 30836e251..7e51125f9 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ar.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ar.ts
@@ -432,11 +432,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -602,11 +683,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation type="unfinished"></translation>
@@ -730,6 +806,26 @@
<comment>details report</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -778,6 +874,10 @@
<source>Restore Defaults</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -925,6 +1025,10 @@
<source>Cancel</source>
<translation type="obsolete">إلغاء</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">إبدأ</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -998,41 +1102,6 @@
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished">لغة</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1431,6 +1500,57 @@
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1499,26 +1619,6 @@
<translation>يمين</translation>
</message>
<message>
- <source>Left Shift</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Right Shift</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Left Ctrl</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Right Ctrl</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Left Alt</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Right Alt</source>
<translation type="unfinished"></translation>
</message>
@@ -1665,6 +1765,10 @@
<source>Restore Defaults</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -1799,11 +1903,6 @@
<translation></translation>
</message>
<message>
- <source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
- <comment>Virtualization Stuff LED</comment>
- <translation></translation>
- </message>
- <message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation></translation>
@@ -1824,6 +1923,11 @@
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2002,7 +2106,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2092,6 +2200,10 @@
<source>Show At &amp;Top Of Screen</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2141,10 +2253,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>A&amp;dvanced</source>
<translation type="unfinished"></translation>
</message>
@@ -2180,6 +2288,42 @@
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsParallel</name>
@@ -2499,10 +2643,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
@@ -2738,6 +2878,60 @@
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -2911,6 +3105,32 @@
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3036,7 +3256,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -3150,6 +3370,21 @@
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3195,7 +3430,7 @@
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation type="unfinished"></translation>
@@ -3216,80 +3451,121 @@
<source>Cancel</source>
<translation type="obsolete">إلغاء</translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage1</name>
<message>
- <source>Welcome to the Create New Virtual Disk Wizard!</source>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <source>Create</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage2</name>
<message>
- <source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
+ <source>Copy Virtual Disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Storage Type</source>
+ <source>Copy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Dynamically expanding storage</source>
+ <source>Welcome to the virtual disk copying wizard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Fixed-size storage</source>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hard Disk Storage Type</source>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage3</name>
<message>
- <source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Location</source>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Size</source>
+ <source>Welcome to the virtual disk creation wizard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Virtual Disk Location and Size</source>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Select a file for the new hard disk image file</source>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hard disk images (*.vdi)</source>
+ <source>Virtual disk file type</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage4</name>
<message>
- <source>You are going to create a new virtual hard disk with the following parameters:</source>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select a file for the new hard disk image file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3297,11 +3573,28 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>%1 B</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Type</source>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
<comment>summary</comment>
<translation type="unfinished"></translation>
</message>
@@ -3315,8 +3608,40 @@
<comment>summary</comment>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
<message>
- <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
+ <source>Choose a virtual hard disk file...</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -3335,6 +3660,10 @@
<source>Cancel</source>
<translation type="obsolete">إلغاء</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -3542,6 +3871,96 @@
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation type="unfinished">لغة</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -3656,81 +4075,6 @@
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -3932,6 +4276,14 @@
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -4859,11 +5211,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Adapter %1</source>
- <comment>network</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Checking...</source>
<comment>medium</comment>
<translation type="unfinished"></translation>
@@ -5132,21 +5479,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>SAS</source>
<comment>StorageBus</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation type="unfinished"></translation>
@@ -5336,6 +5673,61 @@
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -5552,18 +5944,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Location</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Type (Format)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Attached to</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Checking accessibility</source>
<translation type="unfinished"></translation>
</message>
@@ -5629,34 +6009,59 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: Virtual Disk</comment>
+ <source>CD/DVD-ROM disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: CD/DVD Image</comment>
+ <source>hard disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: Floppy Image</comment>
+ <source>floppy disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>CD/DVD-ROM disk</source>
+ <source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hard disk</source>
+ <source>Type:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>floppy disk</source>
+ <source>Location:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>All %1 images (%2)</source>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -5680,13 +6085,6 @@
</message>
</context>
<context>
- <name>VBoxNetworkDialog</name>
- <message>
- <source>Network Adapters</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxOSTypeSelectorWidget</name>
<message>
<source>Operating &amp;System:</source>
@@ -5762,10 +6160,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Failed to access the USB subsystem.</source>
<translation type="unfinished"></translation>
</message>
@@ -6333,10 +6727,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restore</source>
<translation type="unfinished"></translation>
</message>
@@ -6668,15 +7058,75 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -6694,10 +7144,6 @@
<context>
<name>VBoxSFDialog</name>
<message>
- <source>Shared Folders</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>OK</source>
<translation type="obsolete">مواÙÙ‚</translation>
</message>
@@ -6801,11 +7247,11 @@
</message>
<message>
<source>D&amp;iscard</source>
- <translation>إ&amp;لغاء</translation>
+ <translation type="obsolete">إ&amp;لغاء</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">إلغاء</translation>
+ <translation type="unfinished">إلغاء</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -7040,6 +7486,18 @@
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSharedFoldersSettings</name>
@@ -7274,6 +7732,14 @@
<source> (%1 ago)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_bg.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_bg.ts
index 090ca552f..30d123bb5 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_bg.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_bg.ts
@@ -513,12 +513,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>Ин&amp;Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° ÑеÑиÑта</translation>
+ <translation type="obsolete">Ин&amp;Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° ÑеÑиÑта</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>ПозволÑване на &amp;Отдалечен работен плот</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">&amp;ÐаÑтройки...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -684,7 +769,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE мрежа, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE мрежа, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -810,6 +895,26 @@
<comment>details report</comment>
<translation>ОпиÑание</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -984,6 +1089,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">&amp;Име на хоÑта:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1315,6 +1424,10 @@ p, li { white-space: pre-wrap; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot;
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;Ðко по-горното е вÑрно, натиÑнете бутона &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;.&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1388,41 +1501,6 @@ p, li { white-space: pre-wrap; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot;
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>ОÑновни</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Въвеждане</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>ОбновÑване</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Език</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Мрежа</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>РазширениÑ</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1859,6 +1937,57 @@ p, li { white-space: pre-wrap; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot;
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1928,23 +2057,23 @@ p, li { white-space: pre-wrap; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot;
</message>
<message>
<source>Left Shift</source>
- <translation>ЛÑв Shift</translation>
+ <translation type="obsolete">ЛÑв Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>ДеÑен Shift</translation>
+ <translation type="obsolete">ДеÑен Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>ЛÑв Ctrl</translation>
+ <translation type="obsolete">ЛÑв Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>ДеÑен Ctrl</translation>
+ <translation type="obsolete">ДеÑен Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>ЛÑв Alt</translation>
+ <translation type="obsolete">ЛÑв Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2155,6 +2284,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;ВнаÑÑне &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2299,7 +2432,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Показва ÑтатуÑа на хардуерните виртуализационни функции, които Ñе използват от тази виртуална машина:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Показва ÑтатуÑа на хардуерните виртуализационни функции, които Ñе използват от тази виртуална машина:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2322,6 +2455,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;ОтдалечениÑÑ‚ работен плот Ñлуша на порт %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2521,7 +2659,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Имате позволено 3D уÑкорение за операционна ÑиÑтема, коÑто използва WDDM видео драйвер. За макÑимална производителноÑÑ‚ задайте виртуалната VRAM да бъде поне &lt;b&gt;%1&lt;/b&gt;.</translation>
+ <translation type="obsolete">Имате позволено 3D уÑкорение за операционна ÑиÑтема, коÑто използва WDDM видео драйвер. За макÑимална производителноÑÑ‚ задайте виртуалната VRAM да бъде поне &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">Имате позволено 2D видео уÑкорение. Тъй като 2D видео уÑкорението Ñе поддържа Ñамо за виртуални машини Ñ Windows, тази Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ‰Ðµ бъде забранена.</translation>
</message>
</context>
<context>
@@ -2750,6 +2896,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Показване &amp;отгоре на екрана</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">Избрали Ñте 64-битова виртуална ОС за тази ВМ. Тъй като виртуалната машина изиÑква хардуерно уÑкорение (VT-x/AMD-V), тази Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ‰Ðµ бъде включена автоматично.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2804,7 +2954,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Избира името на Ð¼Ñ€ÐµÐ¶Ð¾Ð²Ð¸Ñ Ð°Ð´Ð°Ð¿Ñ‚ÐµÑ€, ако типът на прикачването е еквивалентен на &lt;b&gt;МоÑтов адаптер&lt;/b&gt; или &lt;b&gt;Само-хоÑÑ‚ адаптер&lt;/b&gt;, и името на вътрешната мрежа, ако типът на прикачването е еквивалентен на &lt;b&gt;Вътрешна мрежа&lt;/b&gt;.</translation>
+ <translation type="obsolete">Избира името на Ð¼Ñ€ÐµÐ¶Ð¾Ð²Ð¸Ñ Ð°Ð´Ð°Ð¿Ñ‚ÐµÑ€, ако типът на прикачването е еквивалентен на &lt;b&gt;МоÑтов адаптер&lt;/b&gt; или &lt;b&gt;Само-хоÑÑ‚ адаптер&lt;/b&gt;, и името на вътрешната мрежа, ако типът на прикачването е еквивалентен на &lt;b&gt;Вътрешна мрежа&lt;/b&gt;.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -2842,6 +2992,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>&amp;ПренаÑочване на портове</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3289,7 +3475,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>ÐÑма избран твърд диÑк за &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">ÐÑма избран твърд диÑк за &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3563,6 +3749,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation>Изберете файл Ñ Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»ÐµÐ½ флопи диÑк...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">поддържа Ñе Ñамо един</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">поддържат Ñе до %1</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">текущо използвате повече контролери за Ñъхранение, отколкото чипÑетът %1 поддържа. МолÑ, променете типа на чипÑета от Ñтраницата Ñ Ð½Ð°Ñтройки СиÑтема или намалете Ð±Ñ€Ð¾Ñ Ð½Ð° Ñледните контролери за Ñъхранение от Ñтраницата Ñ Ð½Ð°Ñтройки Съхранение: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3753,6 +3993,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>избрали Ñте чипÑет тип ICH9 за тази ВМ. Той нÑма да работи коректно, докато IO-APIC Ñъщо е позволен. Това ще бъде променено автоматично, когато потвърдите наÑтройките на ВМ Ñ Ð½Ð°Ñ‚Ð¸Ñкането на бутона Добре.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3879,7 +4145,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>USB 2.0 текущо е позволено за тази виртуална машина. Това изиÑква да бъде инÑталиран &lt;b&gt;%1&lt;/b&gt;. МолÑ, инÑталирайте пакета Ñ Ñ€Ð°Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð¾Ñ‚ Ñайта на VirtualBox. След това ще можете да позволите отново USB 2.0. Междувременно тази наÑтройка ще бъде забранена, оÑвен ако не откажете тази промÑна в наÑтройките.</translation>
+ <translation type="obsolete">USB 2.0 текущо е позволено за тази виртуална машина. Това изиÑква да бъде инÑталиран &lt;b&gt;%1&lt;/b&gt;. МолÑ, инÑталирайте пакета Ñ Ñ€Ð°Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð¾Ñ‚ Ñайта на VirtualBox. След това ще можете да позволите отново USB 2.0. Междувременно тази наÑтройка ще бъде забранена, оÑвен ако не откажете тази промÑна в наÑтройките.</translation>
+ </message>
+ <message>
+ <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>
</context>
<context>
@@ -3992,6 +4262,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4037,7 +4322,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Създаване на нов виртуален диÑк</translation>
@@ -4052,7 +4337,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Обобщение</translation>
+ <translation type="unfinished">Обобщение</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4064,7 +4349,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Изберете файл за новото изображение на твърд диÑк</translation>
+ <translation type="unfinished">Изберете файл за новото изображение на твърд диÑк</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -4086,12 +4371,12 @@ p, li { white-space: pre-wrap; }
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">МеÑтоположение</translation>
+ <translation type="unfinished">МеÑтоположение</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Размер</translation>
+ <translation type="unfinished">Размер</translation>
</message>
<message>
<source>Bytes</source>
@@ -4150,108 +4435,280 @@ p, li { white-space: pre-wrap; }
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Ðко наÑтройките по-горе Ñа правилни, натиÑнете бутона &lt;b&gt;Край&lt;/b&gt;. След като го натиÑнете, ще започне Ñъздаване на Ð½Ð¾Ð²Ð¸Ñ Ñ‚Ð²ÑŠÑ€Ð´ диÑк.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 Б)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 Б</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;МеÑтоположение</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Размер</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Добре дошли в помощника за Ñъздаване на нов виртуален диÑк!</translation>
+ <translation type="obsolete">Добре дошли в помощника за Ñъздаване на нов виртуален диÑк!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Този помощник ще ви помогне да Ñъздадете нов виртуален твърд диÑк за вашата виртуална машина.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Този помощник ще ви помогне да Ñъздадете нов виртуален твърд диÑк за вашата виртуална машина.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished">Изберете файл Ñ Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»ÐµÐ½ твърд диÑк...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Изберете тип на паметта на Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»Ð½Ð¸Ñ Ð´Ð¸Ñк, който ще бъде Ñъздаден.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Динамично преоразмерÑващата Ñе памет&lt;/b&gt; първоначално заема много малка чаÑÑ‚ от проÑтранÑтвото на Ð²Ð°ÑˆÐ¸Ñ Ñ„Ð¸Ð·Ð¸Ñ‡ÐµÑки твърд диÑк. Ð¢Ñ Ñ‰Ðµ Ñе Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡Ð½Ð¾ (макÑимално до Ð·Ð°Ð´Ð°Ð´ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€) Ñпоред изиÑканото диÑково проÑтранÑтво от виртуалната ОС.&lt;/p&gt;&lt;p&gt;&lt;b&gt;ФикÑираниÑÑ‚ размер на паметта&lt;/b&gt; не Ñе променÑ. Ð¢Ñ Ñе разполага във файл Ñ Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð·Ð¸Ñ‚ÐµÐ»Ð½Ð¾ ÑÑŠÑ‰Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€, какъвто е размерът на Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»Ð½Ð¸Ñ Ñ‚Ð²ÑŠÑ€Ð´ диÑк. Създаването на памет Ñ Ñ„Ð¸ÐºÑиран размер може да отнеме доÑта време, в завиÑимоÑÑ‚ от Ð·Ð°Ð´Ð°Ð´ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€ и възможноÑтите за Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° физичеÑÐºÐ¸Ñ Ñ‚Ð²ÑŠÑ€Ð´ диÑк.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Изберете тип на паметта на Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»Ð½Ð¸Ñ Ð´Ð¸Ñк, който ще бъде Ñъздаден.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Динамично преоразмерÑващата Ñе памет&lt;/b&gt; първоначално заема много малка чаÑÑ‚ от проÑтранÑтвото на Ð²Ð°ÑˆÐ¸Ñ Ñ„Ð¸Ð·Ð¸Ñ‡ÐµÑки твърд диÑк. Ð¢Ñ Ñ‰Ðµ Ñе Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡Ð½Ð¾ (макÑимално до Ð·Ð°Ð´Ð°Ð´ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€) Ñпоред изиÑканото диÑково проÑтранÑтво от виртуалната ОС.&lt;/p&gt;&lt;p&gt;&lt;b&gt;ФикÑираниÑÑ‚ размер на паметта&lt;/b&gt; не Ñе променÑ. Ð¢Ñ Ñе разполага във файл Ñ Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð·Ð¸Ñ‚ÐµÐ»Ð½Ð¾ ÑÑŠÑ‰Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€, какъвто е размерът на Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»Ð½Ð¸Ñ Ñ‚Ð²ÑŠÑ€Ð´ диÑк. Създаването на памет Ñ Ñ„Ð¸ÐºÑиран размер може да отнеме доÑта време, в завиÑимоÑÑ‚ от Ð·Ð°Ð´Ð°Ð´ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€ и възможноÑтите за Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° физичеÑÐºÐ¸Ñ Ñ‚Ð²ÑŠÑ€Ð´ диÑк.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Тип на паметта</translation>
+ <translation type="obsolete">Тип на паметта</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>&amp;Динамично преоразмерÑваща Ñе памет</translation>
+ <translation type="obsolete">&amp;Динамично преоразмерÑваща Ñе памет</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>&amp;ФикÑиран размер на паметта</translation>
+ <translation type="obsolete">&amp;ФикÑиран размер на паметта</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Тип на паметта на Ñ‚Ð²ÑŠÑ€Ð´Ð¸Ñ Ð´Ð¸Ñк</translation>
+ <translation type="obsolete">Тип на паметта на Ñ‚Ð²ÑŠÑ€Ð´Ð¸Ñ Ð´Ð¸Ñк</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;ÐатиÑнете бутона &lt;b&gt;Избор&lt;/b&gt;, за да изберете меÑтоположение на файла, в който ще Ñе ÑъхранÑват данните на Ñ‚Ð²ÑŠÑ€Ð´Ð¸Ñ Ð´Ð¸Ñк, или въведете име на файла в полето за въвеждане.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;ÐатиÑнете бутона &lt;b&gt;Избор&lt;/b&gt;, за да изберете меÑтоположение на файла, в който ще Ñе ÑъхранÑват данните на Ñ‚Ð²ÑŠÑ€Ð´Ð¸Ñ Ð´Ð¸Ñк, или въведете име на файла в полето за въвеждане.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;МеÑтоположение</translation>
+ <translation type="obsolete">&amp;МеÑтоположение</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Изберете размера на Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»Ð½Ð¸Ñ Ñ‚Ð²ÑŠÑ€Ð´ диÑк в мегабайти. Този размер ще бъде Ñъобщен на виртуалната ОС като макÑимален размер на този твърд диÑк.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Изберете размера на Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»Ð½Ð¸Ñ Ñ‚Ð²ÑŠÑ€Ð´ диÑк в мегабайти. Този размер ще бъде Ñъобщен на виртуалната ОС като макÑимален размер на този твърд диÑк.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Размер</translation>
+ <translation type="obsolete">&amp;Размер</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>МеÑтоположение и размер на Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»Ð½Ð¸Ñ Ð´Ð¸Ñк</translation>
+ <translation type="obsolete">МеÑтоположение и размер на Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»Ð½Ð¸Ñ Ð´Ð¸Ñк</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Изберете файл за новото изображение на твърд диÑк</translation>
+ <translation type="obsolete">Изберете файл за новото изображение на твърд диÑк</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð½Ð° твърд диÑк (*.vdi)</translation>
+ <translation type="obsolete">Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð½Ð° твърд диÑк (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 Б)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 Б)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>ПредÑтои да Ñъздадете нов виртуален твърд диÑк ÑÑŠÑ Ñледните параметри:</translation>
+ <translation type="obsolete">ПредÑтои да Ñъздадете нов виртуален твърд диÑк ÑÑŠÑ Ñледните параметри:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Обобщение</translation>
+ <translation type="obsolete">Обобщение</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 Б</translation>
+ <translation type="obsolete">%1 Б</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Тип</translation>
+ <translation type="obsolete">Тип</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>МеÑтоположение</translation>
+ <translation type="obsolete">МеÑтоположение</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Размер</translation>
+ <translation type="obsolete">Размер</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Ðко наÑтройките по-горе Ñа правилни, натиÑнете бутона &lt;b&gt;%1&lt;/b&gt;. След като го натиÑнете, ще започне Ñъздаване на Ð½Ð¾Ð²Ð¸Ñ Ñ‚Ð²ÑŠÑ€Ð´ диÑк.</translation>
+ <translation type="obsolete">Ðко наÑтройките по-горе Ñа правилни, натиÑнете бутона &lt;b&gt;%1&lt;/b&gt;. След като го натиÑнете, ще започне Ñъздаване на Ð½Ð¾Ð²Ð¸Ñ Ñ‚Ð²ÑŠÑ€Ð´ диÑк.</translation>
</message>
</context>
<context>
@@ -4381,6 +4838,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">&amp;Използване на ÑъщеÑтвуващ твърд диÑк</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4666,6 +5127,120 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>ОÑновни</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Въвеждане</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>ОбновÑване</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Език</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Мрежа</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>РазширениÑ</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>ОÑновни</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>СиÑтема</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Възпроизвеждане</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Съхранение</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Звук</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Мрежа</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Портове</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Серийни портове</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Паралелни портове</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Споделени папки</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">Избрали Ñте 64-битова виртуална ОС за тази ВМ. Тъй като виртуалната машина изиÑква хардуерно уÑкорение (VT-x/AMD-V), тази Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ‰Ðµ бъде включена автоматично.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">Имате позволено 2D видео уÑкорение. Тъй като 2D видео уÑкорението Ñе поддържа Ñамо за виртуални машини Ñ Windows, тази Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ‰Ðµ бъде забранена.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">позволили Ñте USB HID (Human Interface Device). Това нÑма да работи, докато не позволите и USB емулациÑта. Това ще бъде променено автоматично, когато потвърдите наÑтройките на ВМ Ñ Ð½Ð°Ñ‚Ð¸Ñкане на бутона Добре.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">поддържа Ñе Ñамо един</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">поддържат Ñе до %1</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">текущо използвате повече контролери за Ñъхранение, отколкото чипÑетът %1 поддържа. МолÑ, променете типа на чипÑета от Ñтраницата Ñ Ð½Ð°Ñтройки СиÑтема или намалете Ð±Ñ€Ð¾Ñ Ð½Ð° Ñледните контролери за Ñъхранение от Ñтраницата Ñ Ð½Ð°Ñтройки Съхранение: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -4804,81 +5379,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>ОÑновни</translation>
- </message>
- <message>
- <source>System</source>
- <translation>СиÑтема</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Възпроизвеждане</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Съхранение</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Звук</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Мрежа</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Портове</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Серийни портове</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Паралелни портове</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Споделени папки</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>Избрали Ñте 64-битова виртуална ОС за тази ВМ. Тъй като виртуалната машина изиÑква хардуерно уÑкорение (VT-x/AMD-V), тази Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ‰Ðµ бъде включена автоматично.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>Имате позволено 2D видео уÑкорение. Тъй като 2D видео уÑкорението Ñе поддържа Ñамо за виртуални машини Ñ Windows, тази Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ‰Ðµ бъде забранена.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>позволили Ñте USB HID (Human Interface Device). Това нÑма да работи, докато не позволите и USB емулациÑта. Това ще бъде променено автоматично, когато потвърдите наÑтройките на ВМ Ñ Ð½Ð°Ñ‚Ð¸Ñкане на бутона Добре.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>поддържа Ñе Ñамо един</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>поддържат Ñе до %1</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>текущо използвате повече контролери за Ñъхранение, отколкото чипÑетът %1 поддържа. МолÑ, променете типа на чипÑета от Ñтраницата Ñ Ð½Ð°Ñтройки СиÑтема или намалете Ð±Ñ€Ð¾Ñ Ð½Ð° Ñледните контролери за Ñъхранение от Ñтраницата Ñ Ð½Ð°Ñтройки Съхранение: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5013,6 +5513,14 @@ p, li { white-space: pre-wrap; }
<source>Hard Disk Controller (SAS)</source>
<translation>Контролер на твърд диÑк (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -6418,7 +6926,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Ðдаптер %1</translation>
+ <translation type="obsolete">Ðдаптер %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -6860,7 +7368,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE мрежа, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE мрежа, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -6870,7 +7378,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>VDE адаптер</translation>
+ <translation type="obsolete">VDE адаптер</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -7067,6 +7575,61 @@ p, li { white-space: pre-wrap; }
<comment>DiskType</comment>
<translation>Мулти закачане</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Ðдаптер %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7229,15 +7792,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Location</source>
- <translation>МеÑтоположение</translation>
+ <translation type="obsolete">МеÑтоположение</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Тип (Формат)</translation>
+ <translation type="obsolete">Тип (Формат)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Закачен към</translation>
+ <translation type="obsolete">Закачен към</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -7319,17 +7882,17 @@ p, li { white-space: pre-wrap; }
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Закачен към</translation>
+ <translation type="obsolete">Закачен към</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Закачен към</translation>
+ <translation type="obsolete">Закачен към</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Закачен към</translation>
+ <translation type="obsolete">Закачен към</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -7347,6 +7910,46 @@ p, li { white-space: pre-wrap; }
<source>All %1 images (%2)</source>
<translation>Ð’Ñички %1 Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Тип:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">МеÑтоположение:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -7371,7 +7974,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Мрежови адаптери</translation>
+ <translation type="obsolete">Мрежови адаптери</translation>
</message>
</context>
<context>
@@ -8056,7 +8659,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Ðе може да Ñе доÑтъпи USB на реалната ÑиÑтема, защото нито е Ñ USB файлова ÑиÑтема (usbfs), нито DBus и hal уÑлугите Ñа доÑтъпни в момента. Ðко иÑкате да използвате реални USB уÑтройÑтва във виртуалните ÑиÑтеми, трÑбва да поправите това и да реÑтартирате VirtualBox.</translation>
+ <translation type="obsolete">Ðе може да Ñе доÑтъпи USB на реалната ÑиÑтема, защото нито е Ñ USB файлова ÑиÑтема (usbfs), нито DBus и hal уÑлугите Ñа доÑтъпни в момента. Ðко иÑкате да използвате реални USB уÑтройÑтва във виртуалните ÑиÑтеми, трÑбва да поправите това и да реÑтартирате VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -8173,7 +8776,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Сигурни ли Ñте, че иÑкате да възÑтановите Ñнимката &lt;b&gt;%1&lt;/b&gt;? По този начин ще загубите наÑтоÑщото ÑÑŠÑтоÑние на машината, което не може да бъде възÑтановено.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Сигурни ли Ñте, че иÑкате да възÑтановите Ñнимката &lt;b&gt;%1&lt;/b&gt;? По този начин ще загубите наÑтоÑщото ÑÑŠÑтоÑние на машината, което не може да бъде възÑтановено.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -8472,7 +9075,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">СъжалÑвам, възникна нÑкакъв оÑновен проблем.</translation>
+ <translation type="unfinished">СъжалÑвам, възникна нÑкакъв оÑновен проблем.</translation>
</message>
<message>
<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>
@@ -8561,7 +9164,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>Изтриването на вÑички файлове, принадлежащи към виртуалната машина, текущо е забранено за Windows/x64, за да Ñе предотврати Ñрив. Това ще бъде поправено в Ñледващата верÑиÑ.</translation>
+ <translation type="obsolete">Изтриването на вÑички файлове, принадлежащи към виртуалната машина, текущо е забранено за Windows/x64, за да Ñе предотврати Ñрив. Това ще бъде поправено в Ñледващата верÑиÑ.</translation>
</message>
<message>
<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>
@@ -8569,7 +9172,71 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>&lt;p&gt;USB 2.0 текущо е позволено за тази виртуална машина. Това изиÑква да бъде инÑталиран &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;МолÑ, инÑталирайте пакета Ñ Ñ€Ð°Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð¾Ñ‚ Ñайта на VirtualBox. След това ще можете да позволите отново USB 2.0. Междувременно тази наÑтройка ще бъде забранена, оÑвен ако не откажете тази промÑна в наÑтройките.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;USB 2.0 текущо е позволено за тази виртуална машина. Това изиÑква да бъде инÑталиран &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;МолÑ, инÑталирайте пакета Ñ Ñ€Ð°Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð¾Ñ‚ Ñайта на VirtualBox. След това ще можете да позволите отново USB 2.0. Междувременно тази наÑтройка ще бъде забранена, оÑвен ако не откажете тази промÑна в наÑтройките.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -8683,7 +9350,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Споделени папки</translation>
+ <translation type="obsolete">Споделени папки</translation>
</message>
</context>
<context>
@@ -8754,7 +9421,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>D&amp;iscard</source>
- <translation>&amp;ИзчиÑтване</translation>
+ <translation type="obsolete">&amp;ИзчиÑтване</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -8956,6 +9623,22 @@ p, li { white-space: pre-wrap; }
<source>Show Statusbar</source>
<translation>Показване на ÑÑ‚Ð°Ñ‚ÑƒÑ Ð»ÐµÐ½Ñ‚Ð°</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished">ИзчиÑтване</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -9181,6 +9864,14 @@ p, li { white-space: pre-wrap; }
<source> (%1 ago)</source>
<translation> (преди %1)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts
index 26dcd3c25..eeb202ea2 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts
@@ -569,12 +569,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>I&amp;nformació de la sessió</translation>
+ <translation type="obsolete">I&amp;nformació de la sessió</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>Activa la pantalla r&amp;emota</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">Paràmetre&amp;s...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -740,7 +825,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Xarxa VDE, &apos;%1&apos;</translation>
+ <translation type="obsolete">Xarxa VDE, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -866,6 +951,26 @@
<comment>details report</comment>
<translation>Descripció</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -1074,6 +1179,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">&amp;Nom de l&apos;amfitrió:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1412,6 +1521,10 @@ p, li { white-space: pre-wrap; }
<source>Cancel</source>
<translation type="obsolete">Cancel·la</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">Inicia</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1485,41 +1598,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>General</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Entrada</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Actualització</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Llengua</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Xarxa</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Extensions</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1961,6 +2039,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -2030,23 +2159,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Tecla de majúscules esquerra</translation>
+ <translation type="obsolete">Tecla de majúscules esquerra</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Tecla de majúscules dreta</translation>
+ <translation type="obsolete">Tecla de majúscules dreta</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Control esquerra</translation>
+ <translation type="obsolete">Control esquerra</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Control dreta</translation>
+ <translation type="obsolete">Control dreta</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Alt esquerra</translation>
+ <translation type="obsolete">Alt esquerra</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2263,6 +2392,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importa &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2407,7 +2540,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Indica l&apos;estat de les característiques de virtualització de maquinari que fa servir aquesta màquina virtual:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Indica l&apos;estat de les característiques de virtualització de maquinari que fa servir aquesta màquina virtual:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2430,6 +2563,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;El servidor d&apos;escriptori remot està escoltant al port %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2629,7 +2767,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Teniu l&apos;acceleració 3D activada per a una operació del sistema que fa servir el mòdul de vídeo WDDM. Per a un rendiment màxim, establiu la memòria VRAM del client com a mínim a &lt;b&gt;%1&lt;/b&gt;.</translation>
+ <translation type="obsolete">Teniu l&apos;acceleració 3D activada per a una operació del sistema que fa servir el mòdul de vídeo WDDM. Per a un rendiment màxim, establiu la memòria VRAM del client com a mínim a &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2874,6 +3020,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Mostra a la par&amp;t de dalt de la pantalla</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2983,7 +3133,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Selecciona el nom de l&apos;adaptador de xarxa si el tipus d&apos;adjunció és equivalent a &lt;b&gt;Adaptador en pont&lt;/b&gt; o &lt;b&gt;Adaptador de només l&apos;amfitrió&lt;/b&gt; i el nom de la xarxa interna si el tipus d&apos;adjunció és equivalent a &lt;b&gt;Xarxa interna&lt;/b&gt;.</translation>
+ <translation type="obsolete">Selecciona el nom de l&apos;adaptador de xarxa si el tipus d&apos;adjunció és equivalent a &lt;b&gt;Adaptador en pont&lt;/b&gt; o &lt;b&gt;Adaptador de només l&apos;amfitrió&lt;/b&gt; i el nom de la xarxa interna si el tipus d&apos;adjunció és equivalent a &lt;b&gt;Xarxa interna&lt;/b&gt;.</translation>
</message>
<message>
<source>Open extended settings dialog for current attachment type.</source>
@@ -3081,6 +3231,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>Reenviament de &amp;ports</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3615,7 +3801,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>No hi ha cap disc dur seleccionat per a &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">No hi ha cap disc dur seleccionat per a &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3889,6 +4075,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation>Selecciona un fitxer de disquet virtual...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">com a mínim una suportada</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">fins %1 suportades</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">actualment esteu fent servir més controlador d&apos;emmagatzematge que els xips %1 suporten. Canvieu el tipus de xip a la pàgina de paràmetres del sistema o reduïu el nombre dels següents controladors d&apos;emmagatzematge a la pàgina de paràmetres d&apos;emmagatzematge: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -4079,6 +4319,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>he assignat un tipus de xip ICH9 a aquesta màquina virtual. No funcionarà correctament a menys que la característica IO-APIC estigui habilitada. Això es farà automàticament quan accepteu els paràmetres de la màquina virtual en prémer el botó «D&apos;acord».</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -4205,7 +4471,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>L&apos;USB 2.0 es troba activat per a aquesta màquina virtual. Tot i així, això requereix la instal·lació de &lt;b&gt;%1&lt;/b&gt;. Instal·leu el paquet d&apos;extensions des del lloc web de baixades del VirtualBox. Una vegada fet això, haureu de tornar a activar l&apos;USB 2.0. Mentrestant es desactivarà a no ser que cancel·leu els canvis dels paràmetres actuals.</translation>
+ <translation type="obsolete">L&apos;USB 2.0 es troba activat per a aquesta màquina virtual. Tot i així, això requereix la instal·lació de &lt;b&gt;%1&lt;/b&gt;. Instal·leu el paquet d&apos;extensions des del lloc web de baixades del VirtualBox. Una vegada fet això, haureu de tornar a activar l&apos;USB 2.0. Mentrestant es desactivarà a no ser que cancel·leu els canvis dels paràmetres actuals.</translation>
+ </message>
+ <message>
+ <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>
</context>
<context>
@@ -4318,6 +4588,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4363,7 +4648,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Crea un disc virtual nou</translation>
@@ -4452,7 +4737,7 @@ al sistema operatiu client com a mida del disc dur.&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Resum</translation>
+ <translation type="unfinished">Resum</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4468,7 +4753,7 @@ al sistema operatiu client com a mida del disc dur.&lt;/p&gt;</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Seleccioneu un fitxer per al fitxer d&apos;imatge del disc dur nou</translation>
+ <translation type="unfinished">Seleccioneu un fitxer per al fitxer d&apos;imatge del disc dur nou</translation>
</message>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;
@@ -4527,12 +4812,12 @@ l&apos;eficiència d&apos;escriptura del disc dur físic.&lt;/p&gt;</translation
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Ubicació</translation>
+ <translation type="unfinished">Ubicació</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Mida</translation>
+ <translation type="unfinished">Mida</translation>
</message>
<message>
<source>Bytes</source>
@@ -4591,108 +4876,280 @@ l&apos;eficiència d&apos;escriptura del disc dur físic.&lt;/p&gt;</translation
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Si el que hi ha més amunt és correcte premeu el botó &lt;b&gt;Finalitza&lt;/b&gt;. Quan el premeu, es crearà una imatge de disc dur nova.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;Ubicació</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Mida</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Benvingut a l&apos;auxiliar per a la creació d&apos;un disc virtual nou!</translation>
+ <translation type="obsolete">Benvingut a l&apos;auxiliar per a la creació d&apos;un disc virtual nou!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Aquest auxiliar us ajudarà a crear una disc dur virtual nou per a la màquina virtual.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Aquest auxiliar us ajudarà a crear una disc dur virtual nou per a la màquina virtual.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished">Selecciona un fitxer de disc dur virtual...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Seleccioneu el tipus de disc dur virtual que voleu crear.&lt;p&gt;&lt;/p&gt;Un &lt;b&gt;emmagatzematge d&apos;expansió dinàmica&lt;/b&gt; ocupa inicialment una quantiat molt petita d&apos;espai al disc dur físic. Creixerà dinàmicament (fins a la mida especificada) conforme el Sistema Amfitrió consumeixi espai. Un &lt;b&gt;emmagatzematge de mida fixa&lt;/b&gt; no creix. S&apos;emmagatzema en un fitxer de mida aproximadament la que s&apos;indica per al disc dur virtual. La creació d&apos;un emmagatzematge de mida fixa triga un temps segons la mida del mateix i de l&apos;eficiència d&apos;escriptura del disc dur físic.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Seleccioneu el tipus de disc dur virtual que voleu crear.&lt;p&gt;&lt;/p&gt;Un &lt;b&gt;emmagatzematge d&apos;expansió dinàmica&lt;/b&gt; ocupa inicialment una quantiat molt petita d&apos;espai al disc dur físic. Creixerà dinàmicament (fins a la mida especificada) conforme el Sistema Amfitrió consumeixi espai. Un &lt;b&gt;emmagatzematge de mida fixa&lt;/b&gt; no creix. S&apos;emmagatzema en un fitxer de mida aproximadament la que s&apos;indica per al disc dur virtual. La creació d&apos;un emmagatzematge de mida fixa triga un temps segons la mida del mateix i de l&apos;eficiència d&apos;escriptura del disc dur físic.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Tipus d&apos;emmagatzematge</translation>
+ <translation type="obsolete">Tipus d&apos;emmagatzematge</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>Emmagatzematge que s&apos;expandeix &amp;dinàmicament</translation>
+ <translation type="obsolete">Emmagatzematge que s&apos;expandeix &amp;dinàmicament</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>Emmagatzematge de mida &amp;fixa</translation>
+ <translation type="obsolete">Emmagatzematge de mida &amp;fixa</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Tipus d&apos;emmagatzematge per al disc dur</translation>
+ <translation type="obsolete">Tipus d&apos;emmagatzematge per al disc dur</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Premeu el botó &lt;b&gt;Selecciona&lt;/b&gt; per seleccionar el lloc i el nom del fitxer on emmagatzemar les dades del disc dur o escriviu el nom del fitxer en el camp d&apos;entrada.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Premeu el botó &lt;b&gt;Selecciona&lt;/b&gt; per seleccionar el lloc i el nom del fitxer on emmagatzemar les dades del disc dur o escriviu el nom del fitxer en el camp d&apos;entrada.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;Ubicació</translation>
+ <translation type="obsolete">&amp;Ubicació</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Seleccioneu la mida del disc dur virtual en megabytes. Aquesta serà la mida que s&apos;informarà al sistema operatiu client com a mida del disc dur.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Seleccioneu la mida del disc dur virtual en megabytes. Aquesta serà la mida que s&apos;informarà al sistema operatiu client com a mida del disc dur.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Mida</translation>
+ <translation type="obsolete">&amp;Mida</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Ubicació i mida del disc virtual</translation>
+ <translation type="obsolete">Ubicació i mida del disc virtual</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Seleccioneu un fitxer per al fitxer d&apos;imatge del disc dur nou</translation>
+ <translation type="obsolete">Seleccioneu un fitxer per al fitxer d&apos;imatge del disc dur nou</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Imatges de disc dur (*.vdi)</translation>
+ <translation type="obsolete">Imatges de disc dur (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Ara creareu un disc dur virtual amb els paràmetres següents:</translation>
+ <translation type="obsolete">Ara creareu un disc dur virtual amb els paràmetres següents:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Resum</translation>
+ <translation type="obsolete">Resum</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Tipus</translation>
+ <translation type="obsolete">Tipus</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Ubicació</translation>
+ <translation type="obsolete">Ubicació</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Mida</translation>
+ <translation type="obsolete">Mida</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Si els paràmetres que hi ha a continuació son correctes, premeu el botó &lt;b&gt;%1&lt;/b&gt;. Un cop l&apos;hàgiu pres, es crearà un disc dur nou.</translation>
+ <translation type="obsolete">Si els paràmetres que hi ha a continuació son correctes, premeu el botó &lt;b&gt;%1&lt;/b&gt;. Un cop l&apos;hàgiu pres, es crearà un disc dur nou.</translation>
</message>
</context>
<context>
@@ -4936,6 +5393,10 @@ pas i connectar discos durs més endavant, fent servir el diàleg de configuraci
<source>Boot Hard &amp;Disk (Primary Master)</source>
<translation type="obsolete">D&amp;isc dur d&apos;arrencada (primari mestre)</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -5221,6 +5682,120 @@ pas i connectar discos durs més endavant, fent servir el diàleg de configuraci
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Entrada</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Actualització</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Llengua</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Xarxa</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Extensions</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>Sistema</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Pantalla</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Emmagatzematge</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Àudio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Xarxa</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Ports</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Ports en sèrie</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Ports paral·lels</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Carpetes compartides</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">heu seleccionat un tipus de sistema client de 64 bits per a aquesta màquina virtual. Amb aquests tipus de clients es requereix maquinari de virtualització (VT-x/AMD-V), aquesta característica s&apos;activarà automàticament.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">l&apos;acceleració 2D està activada. Atès que l&apos;acceleració 2D només està suportada per clients Windows, es desactivarà aquesta característica.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">heu habilitat un USB HID (dispositiu d&apos;interfície humana). Això no funcionarà a menys que l&apos;emulació USB també estigui habilitada. Això es farà automàticament quan accepteu els paràmetres de la màquina virtual en prémer el botó «D&apos;acord».</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">com a mínim una suportada</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">fins %1 suportades</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">actualment esteu fent servir més controlador d&apos;emmagatzematge que els xips %1 suporten. Canvieu el tipus de xip a la pàgina de paràmetres del sistema o reduïu el nombre dels següents controladors d&apos;emmagatzematge a la pàgina de paràmetres d&apos;emmagatzematge: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -5359,81 +5934,6 @@ pas i connectar discos durs més endavant, fent servir el diàleg de configuraci
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>General</translation>
- </message>
- <message>
- <source>System</source>
- <translation>Sistema</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Pantalla</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Emmagatzematge</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Àudio</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Xarxa</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Ports</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Ports en sèrie</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Ports paral·lels</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Carpetes compartides</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>heu seleccionat un tipus de sistema client de 64 bits per a aquesta màquina virtual. Amb aquests tipus de clients es requereix maquinari de virtualització (VT-x/AMD-V), aquesta característica s&apos;activarà automàticament.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>l&apos;acceleració 2D està activada. Atès que l&apos;acceleració 2D només està suportada per clients Windows, es desactivarà aquesta característica.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>heu habilitat un USB HID (dispositiu d&apos;interfície humana). Això no funcionarà a menys que l&apos;emulació USB també estigui habilitada. Això es farà automàticament quan accepteu els paràmetres de la màquina virtual en prémer el botó «D&apos;acord».</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>com a mínim una suportada</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>fins %1 suportades</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>actualment esteu fent servir més controlador d&apos;emmagatzematge que els xips %1 suporten. Canvieu el tipus de xip a la pàgina de paràmetres del sistema o reduïu el nombre dels següents controladors d&apos;emmagatzematge a la pàgina de paràmetres d&apos;emmagatzematge: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5669,6 +6169,14 @@ Versió %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation>Mòdul de disc dur (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -7687,7 +8195,7 @@ Versió %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Adaptador %1</translation>
+ <translation type="obsolete">Adaptador %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -8055,7 +8563,7 @@ Versió %1</translation>
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Xarxa VDE, &apos;%1&apos;</translation>
+ <translation type="obsolete">Xarxa VDE, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -8065,7 +8573,7 @@ Versió %1</translation>
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>Adaptador VDE</translation>
+ <translation type="obsolete">Adaptador VDE</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -8262,6 +8770,61 @@ Versió %1</translation>
<comment>DiskType</comment>
<translation>Adjunció múltiple</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Adaptador %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -8964,15 +9527,15 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>Location</source>
- <translation>Ubicació</translation>
+ <translation type="obsolete">Ubicació</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Tipus (Format)</translation>
+ <translation type="obsolete">Tipus (Format)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Connectat a</translation>
+ <translation type="obsolete">Connectat a</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -9054,17 +9617,17 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Connectat a</translation>
+ <translation type="obsolete">Connectat a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Connectat a</translation>
+ <translation type="obsolete">Connectat a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Connectat a</translation>
+ <translation type="obsolete">Connectat a</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -9082,6 +9645,46 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
<source>All %1 images (%2)</source>
<translation>Totes les imatges %1 (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Tipus:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Ubicació:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -9141,7 +9744,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Adaptadors de xarxa</translation>
+ <translation type="obsolete">Adaptadors de xarxa</translation>
</message>
</context>
<context>
@@ -9854,7 +10457,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>No es pot accedir a l&apos;USB al sistema amfitrió perquè ni el servei de sistema de fitxers USB (usbfs) ni el DBus s&apos;hi troben disponibles. Si voleu fer servir els dispositius USB de l&apos;amfitrió a dins dels sistemes clients, heu de solucionar això i tornar a iniciar el VirtualBox.</translation>
+ <translation type="obsolete">No es pot accedir a l&apos;USB al sistema amfitrió perquè ni el servei de sistema de fitxers USB (usbfs) ni el DBus s&apos;hi troben disponibles. Si voleu fer servir els dispositius USB de l&apos;amfitrió a dins dels sistemes clients, heu de solucionar això i tornar a iniciar el VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -10117,7 +10720,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Segur que voleu restaurar la captura &lt;b&gt;%1&lt;/b&gt;? Això suposarà perdre l&apos;estat actual de la màquina i no podrà ser recuperat.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Segur que voleu restaurar la captura &lt;b&gt;%1&lt;/b&gt;? Això suposarà perdre l&apos;estat actual de la màquina i no podrà ser recuperat.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -10417,7 +11020,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">S&apos;han produït alguns errors genèrics.</translation>
+ <translation type="unfinished">S&apos;han produït alguns errors genèrics.</translation>
</message>
<message>
<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>
@@ -10506,7 +11109,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>L&apos;eliminació de tots els fitxers que pertanyen a la màquina virtual es troba actualment inhabilitada en sistemes Windows/x64 per evitar fallades. Això s&apos;arreglarà en la propera versió.</translation>
+ <translation type="obsolete">L&apos;eliminació de tots els fitxers que pertanyen a la màquina virtual es troba actualment inhabilitada en sistemes Windows/x64 per evitar fallades. Això s&apos;arreglarà en la propera versió.</translation>
</message>
<message>
<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>
@@ -10514,7 +11117,71 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<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>&lt;p&gt;L&apos;USB 2.0 es troba activat per a aquesta màquina virtual. Tot i així, es requereix la instal·lació de &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Instal·leu el paquet d&apos;extensions des del lloc web de baixades del VirtualBox. Una vegada fet això, podreu tornar a activar l&apos;USB 2.0. Mentrestant es desactivarà a no ser que cancel·leu els canvis dels paràmetres actuals.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;L&apos;USB 2.0 es troba activat per a aquesta màquina virtual. Tot i així, es requereix la instal·lació de &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Instal·leu el paquet d&apos;extensions des del lloc web de baixades del VirtualBox. Una vegada fet això, podreu tornar a activar l&apos;USB 2.0. Mentrestant es desactivarà a no ser que cancel·leu els canvis dels paràmetres actuals.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -10660,7 +11327,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>Shared Folders</source>
- <translation>Carpetes compartides</translation>
+ <translation type="obsolete">Carpetes compartides</translation>
</message>
</context>
<context>
@@ -10758,11 +11425,11 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Descarta</translation>
+ <translation type="unfinished">Descarta</translation>
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Descar&amp;ta</translation>
+ <translation type="obsolete">Descar&amp;ta</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -11069,6 +11736,18 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
<source>Show Statusbar</source>
<translation>Mostra la barra d&apos;estat</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -11471,6 +12150,14 @@ per accedir a ella des d&apos;un sistema Linux. Aquesta característica requerei
<source> (%1 ago)</source>
<translation> (fa %1)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca_VA.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca_VA.ts
index 2bbca0b23..ac5fa7596 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca_VA.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca_VA.ts
@@ -569,12 +569,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>I&amp;nformació de la sessió</translation>
+ <translation type="obsolete">I&amp;nformació de la sessió</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>Activa la pantalla r&amp;emota</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">Paràmetre&amp;s...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -740,7 +825,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Xarxa VDE, &apos;%1&apos;</translation>
+ <translation type="obsolete">Xarxa VDE, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -866,6 +951,26 @@
<comment>details report</comment>
<translation>Descripció</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -933,7 +1038,7 @@
<name>UIDownloaderUserManual</name>
<message>
<source>Select folder to save User Manual to</source>
- <translation>Seleccioneu la carpeta on s'alçarà el manual de l&apos;usuari</translation>
+ <translation>Seleccioneu la carpeta on s&apos;alçarà el manual de l&apos;usuari</translation>
</message>
</context>
<context>
@@ -1074,6 +1179,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">&amp;Nom de l&apos;amfitrió:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1412,6 +1521,10 @@ p, li { white-space: pre-wrap; }
<source>Cancel</source>
<translation type="obsolete">Cancel·la</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">Inicia</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1485,41 +1598,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>General</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Entrada</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Actualització</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Llengua</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Xarxa</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Extensions</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1961,6 +2039,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -2030,23 +2159,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Tecla de majúscules esquerra</translation>
+ <translation type="obsolete">Tecla de majúscules esquerra</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Tecla de majúscules dreta</translation>
+ <translation type="obsolete">Tecla de majúscules dreta</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Control esquerra</translation>
+ <translation type="obsolete">Control esquerra</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Control dreta</translation>
+ <translation type="obsolete">Control dreta</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Alt esquerra</translation>
+ <translation type="obsolete">Alt esquerra</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2263,6 +2392,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importa &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2407,7 +2540,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Indica l&apos;estat de les característiques de virtualització de maquinari que fa servir esta màquina virtual:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Indica l&apos;estat de les característiques de virtualització de maquinari que fa servir esta màquina virtual:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2430,6 +2563,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;El servidor d&apos;escriptori remot està escoltant al port %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2494,7 +2632,7 @@ p, li { white-space: pre-wrap; }
<name>UIMachineSettingsAudio</name>
<message>
<source>When checked, a virtual PCI audio card will be plugged into the virtual machine and will communicate with the host audio system using the specified driver.</source>
- <translation>Quan estiga marcat, la tarjeta de so PCI virtual es connectarà a dins de la màquina virtual, la qual farà servir un controlador específic per comunicar-s'amb la tarjeta de so de l&apos;amfitrió.</translation>
+ <translation>Quan estiga marcat, la tarjeta de so PCI virtual es connectarà a dins de la màquina virtual, la qual farà servir un controlador específic per comunicar-s&apos;amb la tarjeta de so de l&apos;amfitrió.</translation>
</message>
<message>
<source>Enable &amp;Audio</source>
@@ -2506,7 +2644,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Controls the audio output driver. The &lt;b&gt;Null Audio Driver&lt;/b&gt; makes the guest see an audio card, however every access to it will be ignored.</source>
- <translation>Gestiona el controlador d'eixida de so. El &lt;b&gt;controlador d&apos;àudio Nul&lt;/b&gt; fa que el client veja una tarjeta de so, però l&apos;accés a ella s&apos;ignorarà.</translation>
+ <translation>Gestiona el controlador d&apos;eixida de so. El &lt;b&gt;controlador d&apos;àudio Nul&lt;/b&gt; fa que el client veja una tarjeta de so, però l&apos;accés a ella s&apos;ignorarà.</translation>
</message>
<message>
<source>Audio &amp;Controller:</source>
@@ -2561,7 +2699,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>When checked, the VM will act as a Remote Desktop Protocol (RDP) server, allowing remote clients to connect and operate the VM (when it is running) using a standard RDP client.</source>
- <translation>Quan estiga marcat, la màquina virtual actuarà com un servidor RDP (protocol d&apos;escriptori remot), de forma que es permetrà a clients remots connectar-s'i operar amb la màquina virtual (quan estiga en execució) fent servir un client estàndard RDP.</translation>
+ <translation>Quan estiga marcat, la màquina virtual actuarà com un servidor RDP (protocol d&apos;escriptori remot), de forma que es permetrà a clients remots connectar-s&apos;i operar amb la màquina virtual (quan estiga en execució) fent servir un client estàndard RDP.</translation>
</message>
<message>
<source>&amp;Enable Server</source>
@@ -2629,7 +2767,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Teniu l&apos;acceleració 3D activada per a una operació del sistema que fa servir el mòdul de vídeo WDDM. Per a un rendiment màxim, establiu la memòria VRAM del client com a mínim a &lt;b&gt;%1&lt;/b&gt;.</translation>
+ <translation type="obsolete">Teniu l&apos;acceleració 3D activada per a una operació del sistema que fa servir el mòdul de vídeo WDDM. Per a un rendiment màxim, establiu la memòria VRAM del client com a mínim a &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2652,7 +2798,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Displays the path where snapshots of this virtual machine will be stored. Be aware that snapshots can take quite a lot of disk space.</source>
- <translation>Mostra el camí on les captures d&apos;esta màquina virtual s'alçaran. Tingueu en compte que les captures poden ocupar prou quantitat d&apos;espai al disc dur.</translation>
+ <translation>Mostra el camí on les captures d&apos;esta màquina virtual s&apos;alçaran. Tingueu en compte que les captures poden ocupar prou quantitat d&apos;espai al disc dur.</translation>
</message>
<message>
<source>&amp;Basic</source>
@@ -2816,7 +2962,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>If checked, any change to mounted CD/DVD or Floppy media performed during machine execution will be saved in the settings file in order to preserve the configuration of mounted media between runs.</source>
- <translation>Si està marcat, qualsevol canvi al CD/DVD o disquet muntat s'alçarà al fitxer de configuració per tal de preservar la configuració dels suports muntats entre cada execució de la màquina virtual.</translation>
+ <translation>Si està marcat, qualsevol canvi al CD/DVD o disquet muntat s&apos;alçarà al fitxer de configuració per tal de preservar la configuració dels suports muntats entre cada execució de la màquina virtual.</translation>
</message>
<message>
<source>&amp;Remember Mounted Media</source>
@@ -2868,12 +3014,16 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>If checked, show the Mini ToolBar at the top of the screen, rather than in its default position at the bottom of the screen.</source>
- <translation>Si està marcat, mostra una barra d&apos;eines petita a la part de dalt de la pantalla en lloc d'a la posició per defecte a la part de sota.</translation>
+ <translation>Si està marcat, mostra una barra d&apos;eines petita a la part de dalt de la pantalla en lloc d&apos;a la posició per defecte a la part de sota.</translation>
</message>
<message>
<source>Show At &amp;Top Of Screen</source>
<translation>Mostra a la par&amp;t de dalt de la pantalla</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2983,7 +3133,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Selecciona el nom de l&apos;adaptador de xarxa si el tipus d&apos;adjunció és equivalent a &lt;b&gt;Adaptador en pont&lt;/b&gt; o &lt;b&gt;Adaptador de només l&apos;amfitrió&lt;/b&gt; i el nom de la xarxa interna si el tipus d&apos;adjunció és equivalent a &lt;b&gt;Xarxa interna&lt;/b&gt;.</translation>
+ <translation type="obsolete">Selecciona el nom de l&apos;adaptador de xarxa si el tipus d&apos;adjunció és equivalent a &lt;b&gt;Adaptador en pont&lt;/b&gt; o &lt;b&gt;Adaptador de només l&apos;amfitrió&lt;/b&gt; i el nom de la xarxa interna si el tipus d&apos;adjunció és equivalent a &lt;b&gt;Xarxa interna&lt;/b&gt;.</translation>
</message>
<message>
<source>Open extended settings dialog for current attachment type.</source>
@@ -3081,6 +3231,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>Reenviament de &amp;ports</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3579,7 +3765,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>If checked, shows the differencing hard disks that are attached to slots rather than their base hard disks (shown for indirect attachments) and allows explicit attaching of differencing hard disks. Check this only if you need a complex hard disk setup.</source>
- <translation type="obsolete">Si està marcat, mostrarà de forma diferenciada els discos durs connectats a les ranures en lloc d'als discos durs base (mostrat en cas d&apos;adjuncions indirectes), a més permetrà connectar altres discos durs explícitament. Marqueu això només si necessiteu una configuració complexa del disc dur.</translation>
+ <translation type="obsolete">Si està marcat, mostrarà de forma diferenciada els discos durs connectats a les ranures en lloc d&apos;als discos durs base (mostrat en cas d&apos;adjuncions indirectes), a més permetrà connectar altres discos durs explícitament. Marqueu això només si necessiteu una configuració complexa del disc dur.</translation>
</message>
<message>
<source>&amp;Show Differencing Hard Disks</source>
@@ -3615,7 +3801,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>No hi ha cap disc dur seleccionat per a &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">No hi ha cap disc dur seleccionat per a &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3889,6 +4075,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation>Selecciona un fitxer de disquet virtual...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">com a mínim una suportada</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">fins %1 suportades</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">actualment esteu fent servir més controlador d&apos;emmagatzematge que els xips %1 suporten. Canvieu el tipus de xip a la pàgina de paràmetres del sistema o reduïu el nombre dels següents controladors d&apos;emmagatzematge a la pàgina de paràmetres d&apos;emmagatzematge: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -4079,6 +4319,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>he assignat un tipus de xip ICH9 a esta màquina virtual. No funcionarà correctament a menys que la característica IO-APIC estiga habilitada. Això es farà automàticament quan accepteu els paràmetres de la màquina virtual en prémer el botó «D&apos;acord».</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -4205,7 +4471,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>L&apos;USB 2.0 es troba activat per a esta màquina virtual. Tot i així, això requereix la instal·lació de &lt;b&gt;%1&lt;/b&gt;. Instal·leu el paquet d&apos;extensions des del lloc web de baixades del VirtualBox. Una vegada fet això, haureu de tornar a activar l&apos;USB 2.0. Mentrestant es desactivarà a no ser que cancel·leu els canvis dels paràmetres actuals.</translation>
+ <translation type="obsolete">L&apos;USB 2.0 es troba activat per a esta màquina virtual. Tot i així, això requereix la instal·lació de &lt;b&gt;%1&lt;/b&gt;. Instal·leu el paquet d&apos;extensions des del lloc web de baixades del VirtualBox. Una vegada fet això, haureu de tornar a activar l&apos;USB 2.0. Mentrestant es desactivarà a no ser que cancel·leu els canvis dels paràmetres actuals.</translation>
+ </message>
+ <message>
+ <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>
</context>
<context>
@@ -4318,6 +4588,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4363,7 +4648,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Crea un disc virtual nou</translation>
@@ -4452,7 +4737,7 @@ al sistema operatiu client com a mida del disc dur.&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Resum</translation>
+ <translation type="unfinished">Resum</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4468,7 +4753,7 @@ al sistema operatiu client com a mida del disc dur.&lt;/p&gt;</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Seleccioneu un fitxer per al fitxer d&apos;imatge del disc dur nou</translation>
+ <translation type="unfinished">Seleccioneu un fitxer per al fitxer d&apos;imatge del disc dur nou</translation>
</message>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;
@@ -4527,12 +4812,12 @@ l&apos;eficiència d&apos;escriptura del disc dur físic.&lt;/p&gt;</translation
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Ubicació</translation>
+ <translation type="unfinished">Ubicació</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Mida</translation>
+ <translation type="unfinished">Mida</translation>
</message>
<message>
<source>Bytes</source>
@@ -4591,108 +4876,280 @@ l&apos;eficiència d&apos;escriptura del disc dur físic.&lt;/p&gt;</translation
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Si el que hi ha més amunt és correcte premeu el botó &lt;b&gt;Finalitza&lt;/b&gt;. Quan el premeu, es crearà una imatge de disc dur nova.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;Ubicació</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Mida</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Benvingut a l&apos;auxiliar per a la creació d&apos;un disc virtual nou!</translation>
+ <translation type="obsolete">Benvingut a l&apos;auxiliar per a la creació d&apos;un disc virtual nou!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Este auxiliar vos ajudarà a crear una disc dur virtual nou per a la màquina virtual.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Este auxiliar vos ajudarà a crear una disc dur virtual nou per a la màquina virtual.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished">Selecciona un fitxer de disc dur virtual...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Seleccioneu el tipus de disc dur virtual que voleu crear.&lt;p&gt;&lt;/p&gt;Un &lt;b&gt;emmagatzematge d&apos;expansió dinàmica&lt;/b&gt; ocupa inicialment una quantiat molt petita d&apos;espai al disc dur físic. Creixerà dinàmicament (fins a la mida especificada) conforme el Sistema Amfitrió consumisca espai. Un &lt;b&gt;emmagatzematge de mida fixa&lt;/b&gt; no creix. S&apos;emmagatzema en un fitxer de mida aproximadament la que s&apos;indica per al disc dur virtual. La creació d&apos;un emmagatzematge de mida fixa triga un temps segons la mida del mateix i de l&apos;eficiència d&apos;escriptura del disc dur físic.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Seleccioneu el tipus de disc dur virtual que voleu crear.&lt;p&gt;&lt;/p&gt;Un &lt;b&gt;emmagatzematge d&apos;expansió dinàmica&lt;/b&gt; ocupa inicialment una quantiat molt petita d&apos;espai al disc dur físic. Creixerà dinàmicament (fins a la mida especificada) conforme el Sistema Amfitrió consumisca espai. Un &lt;b&gt;emmagatzematge de mida fixa&lt;/b&gt; no creix. S&apos;emmagatzema en un fitxer de mida aproximadament la que s&apos;indica per al disc dur virtual. La creació d&apos;un emmagatzematge de mida fixa triga un temps segons la mida del mateix i de l&apos;eficiència d&apos;escriptura del disc dur físic.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Tipus d&apos;emmagatzematge</translation>
+ <translation type="obsolete">Tipus d&apos;emmagatzematge</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>Emmagatzematge que s&apos;expandeix &amp;dinàmicament</translation>
+ <translation type="obsolete">Emmagatzematge que s&apos;expandeix &amp;dinàmicament</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>Emmagatzematge de mida &amp;fixa</translation>
+ <translation type="obsolete">Emmagatzematge de mida &amp;fixa</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Tipus d&apos;emmagatzematge per al disc dur</translation>
+ <translation type="obsolete">Tipus d&apos;emmagatzematge per al disc dur</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Premeu el botó &lt;b&gt;Selecciona&lt;/b&gt; per seleccionar el lloc i el nom del fitxer on emmagatzemar les dades del disc dur o escriviu el nom del fitxer en el camp d&apos;entrada.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Premeu el botó &lt;b&gt;Selecciona&lt;/b&gt; per seleccionar el lloc i el nom del fitxer on emmagatzemar les dades del disc dur o escriviu el nom del fitxer en el camp d&apos;entrada.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;Ubicació</translation>
+ <translation type="obsolete">&amp;Ubicació</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Seleccioneu la mida del disc dur virtual en megabytes. Esta serà la mida que s&apos;informarà al sistema operatiu client com a mida del disc dur.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Seleccioneu la mida del disc dur virtual en megabytes. Esta serà la mida que s&apos;informarà al sistema operatiu client com a mida del disc dur.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Mida</translation>
+ <translation type="obsolete">&amp;Mida</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Ubicació i mida del disc virtual</translation>
+ <translation type="obsolete">Ubicació i mida del disc virtual</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Seleccioneu un fitxer per al fitxer d&apos;imatge del disc dur nou</translation>
+ <translation type="obsolete">Seleccioneu un fitxer per al fitxer d&apos;imatge del disc dur nou</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Imatges de disc dur (*.vdi)</translation>
+ <translation type="obsolete">Imatges de disc dur (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Ara creareu un disc dur virtual amb els paràmetres següents:</translation>
+ <translation type="obsolete">Ara creareu un disc dur virtual amb els paràmetres següents:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Resum</translation>
+ <translation type="obsolete">Resum</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Tipus</translation>
+ <translation type="obsolete">Tipus</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Ubicació</translation>
+ <translation type="obsolete">Ubicació</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Mida</translation>
+ <translation type="obsolete">Mida</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Si els paràmetres que hi ha a continuació son correctes, premeu el botó &lt;b&gt;%1&lt;/b&gt;. Un cop l&apos;hàgeu pres, es crearà un disc dur nou.</translation>
+ <translation type="obsolete">Si els paràmetres que hi ha a continuació son correctes, premeu el botó &lt;b&gt;%1&lt;/b&gt;. Un cop l&apos;hàgeu pres, es crearà un disc dur nou.</translation>
</message>
</context>
<context>
@@ -4936,6 +5393,10 @@ pas i connectar discos durs més avant, fent servir el diàleg de configuració
<source>Boot Hard &amp;Disk (Primary Master)</source>
<translation type="obsolete">D&amp;isc dur d&apos;arrencada (primari mestre)</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -5221,6 +5682,120 @@ pas i connectar discos durs més avant, fent servir el diàleg de configuració
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Entrada</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Actualització</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Llengua</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Xarxa</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Extensions</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>Sistema</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Pantalla</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Emmagatzematge</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Àudio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Xarxa</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Ports</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Ports en sèrie</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Ports paral·lels</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Carpetes compartides</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">heu seleccionat un tipus de sistema client de 64 bits per a esta màquina virtual. Amb estos tipus de clients es requereix maquinari de virtualització (VT-x/AMD-V), esta característica s&apos;activarà automàticament.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">l&apos;acceleració 2D està activada. Atès que l&apos;acceleració 2D només està suportada per clients Windows, es desactivarà esta característica.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">heu habilitat un USB HID (dispositiu d&apos;interfície humana). Això no funcionarà a menys que l&apos;emulació USB també estiga habilitada. Això es farà automàticament quan accepteu els paràmetres de la màquina virtual en prémer el botó «D&apos;acord».</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">com a mínim una suportada</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">fins %1 suportades</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">actualment esteu fent servir més controlador d&apos;emmagatzematge que els xips %1 suporten. Canvieu el tipus de xip a la pàgina de paràmetres del sistema o reduïu el nombre dels següents controladors d&apos;emmagatzematge a la pàgina de paràmetres d&apos;emmagatzematge: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -5232,7 +5807,7 @@ pas i connectar discos durs més avant, fent servir el diàleg de configuració
</message>
<message>
<source>&lt;p&gt;Saves the current execution state of the virtual machine to the physical hard disk of the host PC.&lt;/p&gt;&lt;p&gt;Next time this machine is started, it will be restored from the saved state and continue execution from the same place you saved it at, which will let you continue your work immediately.&lt;/p&gt;&lt;p&gt;Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Alça l&apos;estat d&apos;execució actual de la màquina virtual al disc dur físic de l&apos;ordinador amfitrió.&lt;/p&gt;&lt;p&gt;La propera vegada que s&apos;inicià esta màquina, es restaurarà des de l&apos;estat alçat i continuarà l&apos;execució des del mateix lloc en què l&apos;heu alçat, cosa que permetrà continuar immediatament amb el vostre treball.&lt;/p&gt;&lt;p&gt;Tingueu en compte que l&apos;operació d'alçar l&apos;estat de la màquina pot prendre molt de temps, depenent del tipus de sistema operatiu client i la quantitat de memòria assignada a la màquina virtual.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Alça l&apos;estat d&apos;execució actual de la màquina virtual al disc dur físic de l&apos;ordinador amfitrió.&lt;/p&gt;&lt;p&gt;La propera vegada que s&apos;inicià esta màquina, es restaurarà des de l&apos;estat alçat i continuarà l&apos;execució des del mateix lloc en què l&apos;heu alçat, cosa que permetrà continuar immediatament amb el vostre treball.&lt;/p&gt;&lt;p&gt;Tingueu en compte que l&apos;operació d&apos;alçar l&apos;estat de la màquina pot prendre molt de temps, depenent del tipus de sistema operatiu client i la quantitat de memòria assignada a la màquina virtual.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Save the machine state</source>
@@ -5240,7 +5815,7 @@ pas i connectar discos durs més avant, fent servir el diàleg de configuració
</message>
<message>
<source>&lt;p&gt;Sends the ACPI Power Button press event to the virtual machine.&lt;/p&gt;&lt;p&gt;Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.&lt;/p&gt;&lt;p&gt;If the machine doesn&apos;t respond to this action then the guest operating system may be misconfigured or doesn&apos;t understand ACPI Power Button events at all. In this case you should select the &lt;b&gt;Power off the machine&lt;/b&gt; action to stop virtual machine execution.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Envia a la màquina virtual l&apos;esdeveniment de prémer el botó ACPI Power.&lt;/p&gt;&lt;p&gt;Normalment, el sistema operatiu client que s&apos;està executant a dins de la màquina virtual detectarà este esdeveniment i realitzarà un procediment de tancament net. Esta és una manera recomanada de tancar la màquina virtual perquè totes les aplicacions que s&apos;estan executant en ella tindran la possibilitat d'alçar les seues dades i estat.&lt;/p&gt;&lt;p&gt;Si la màquina no respon a esta acció potser el sistema operatiu client pot estar mal configurat o no entén els events del botó ACPI Power. En este cas, seleccioneu l&apos;acció &lt;b&gt;Atura la màquina&lt;/b&gt; per aturar l&apos;execució de la màquina virtual.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Envia a la màquina virtual l&apos;esdeveniment de prémer el botó ACPI Power.&lt;/p&gt;&lt;p&gt;Normalment, el sistema operatiu client que s&apos;està executant a dins de la màquina virtual detectarà este esdeveniment i realitzarà un procediment de tancament net. Esta és una manera recomanada de tancar la màquina virtual perquè totes les aplicacions que s&apos;estan executant en ella tindran la possibilitat d&apos;alçar les seues dades i estat.&lt;/p&gt;&lt;p&gt;Si la màquina no respon a esta acció potser el sistema operatiu client pot estar mal configurat o no entén els events del botó ACPI Power. En este cas, seleccioneu l&apos;acció &lt;b&gt;Atura la màquina&lt;/b&gt; per aturar l&apos;execució de la màquina virtual.&lt;/p&gt;</translation>
</message>
<message>
<source>S&amp;end the shutdown signal</source>
@@ -5359,81 +5934,6 @@ pas i connectar discos durs més avant, fent servir el diàleg de configuració
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>General</translation>
- </message>
- <message>
- <source>System</source>
- <translation>Sistema</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Pantalla</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Emmagatzematge</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Àudio</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Xarxa</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Ports</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Ports en sèrie</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Ports paral·lels</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Carpetes compartides</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>heu seleccionat un tipus de sistema client de 64 bits per a esta màquina virtual. Amb estos tipus de clients es requereix maquinari de virtualització (VT-x/AMD-V), esta característica s&apos;activarà automàticament.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>l&apos;acceleració 2D està activada. Atès que l&apos;acceleració 2D només està suportada per clients Windows, es desactivarà esta característica.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>heu habilitat un USB HID (dispositiu d&apos;interfície humana). Això no funcionarà a menys que l&apos;emulació USB també estiga habilitada. Això es farà automàticament quan accepteu els paràmetres de la màquina virtual en prémer el botó «D&apos;acord».</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>com a mínim una suportada</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>fins %1 suportades</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>actualment esteu fent servir més controlador d&apos;emmagatzematge que els xips %1 suporten. Canvieu el tipus de xip a la pàgina de paràmetres del sistema o reduïu el nombre dels següents controladors d&apos;emmagatzematge a la pàgina de paràmetres d&apos;emmagatzematge: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5669,6 +6169,14 @@ Versió %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation>Mòdul de disc dur (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -5718,7 +6226,7 @@ Versió %1</translation>
&lt;p&gt;Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;Alça l&apos;estat d&apos;execució actual de la màquina virtual al disc dur físic de l&apos;ordinador d&apos;amfitrió.&lt;/p&gt;
&lt;p&gt;La propera vegada que s&apos;engegue esta màquina, es restaurarà des de l&apos;estat alçat i continuarà l&apos;execució des del mateix lloc en què l&apos;heu alçat, cosa que vos permetrà continuar immediatament amb el vostre treball.&lt;/p&gt;
-&lt;p&gt;Tingueu en compte que l&apos;operació d'alçar l&apos;estat de la màquina pot prendre molt de temps, depenent del tipus de sistema operatiu client i la quantitat de memòria assignada a la màquina virtual.&lt;/p&gt;</translation>
+&lt;p&gt;Tingueu en compte que l&apos;operació d&apos;alçar l&apos;estat de la màquina pot prendre molt de temps, depenent del tipus de sistema operatiu client i la quantitat de memòria assignada a la màquina virtual.&lt;/p&gt;</translation>
</message>
<message>
<source>S&amp;end the shutdown signal</source>
@@ -5729,7 +6237,7 @@ Versió %1</translation>
&lt;p&gt;Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.&lt;/p&gt;
&lt;p&gt;If the machine doesn&apos;t respond to this action then the guest operating system may be misconfigured or doesn&apos;t understand ACPI Power Button events at all. In this case you should select the &lt;b&gt;Power off the machine&lt;/b&gt; action to stop virtual machine execution.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;Envia a la màquina virtual l&apos;esdeveniment de prémer el botó ACPI Power.&lt;/p&gt;
-&lt;p&gt;Normalment, el sistema operatiu client que s&apos;està executant a dins de la màquina virtual detectarà este esdeveniment i realitzarà un procediment de tancament net. Esta és una manera recomanada de tancar la màquina virtual perquè totes les aplicacions que s&apos;estan executant en ella tindran la possibilitat d'alçar les seues dades i estat.&lt;/p&gt;
+&lt;p&gt;Normalment, el sistema operatiu client que s&apos;està executant a dins de la màquina virtual detectarà este esdeveniment i realitzarà un procediment de tancament net. Esta és una manera recomanada de tancar la màquina virtual perquè totes les aplicacions que s&apos;estan executant en ella tindran la possibilitat d&apos;alçar les seues dades i estat.&lt;/p&gt;
&lt;p&gt;Si la màquina no respon a esta acció potser el sistema operatiu client pot estar mal configurat o no entén els events del botó ACPI Power. En este cas, seleccioneu l&apos;acció &lt;b&gt;Atura la màquina&lt;/b&gt; per aturar l&apos;execució de la màquina virtual.&lt;/p&gt;</translation>
</message>
<message>
@@ -5744,11 +6252,11 @@ Versió %1</translation>
</message>
<message>
<source>&lt;p&gt;Saves the current execution state of the virtual machine to the physical hard disk of the host PC.&lt;/p&gt;&lt;p&gt;Next time this machine is started, it will be restored from the saved state and continue execution from the same place you saved it at, which will let you continue your work immediately.&lt;/p&gt;&lt;p&gt;Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.&lt;/p&gt;</source>
- <translation type="obsolete">&lt;p&gt;Alça l&apos;estat d&apos;execució actual de la màquina virtual al disc dur físic de l&apos;ordinador amfitrió.&lt;/p&gt;&lt;p&gt;La propera vegada que s&apos;inicià esta màquina, es restaurarà des de l&apos;estat alçat i continuarà l&apos;execució des del mateix lloc en què l&apos;heu alçat, cosa que permetrà continuar immediatament amb el vostre treball.&lt;/p&gt;&lt;p&gt;Tingueu en compte que l&apos;operació d'alçar l&apos;estat de la màquina pot prendre molt de temps, depenent del tipus de sistema operatiu client i la quantitat de memòria assignada a la màquina virtual.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Alça l&apos;estat d&apos;execució actual de la màquina virtual al disc dur físic de l&apos;ordinador amfitrió.&lt;/p&gt;&lt;p&gt;La propera vegada que s&apos;inicià esta màquina, es restaurarà des de l&apos;estat alçat i continuarà l&apos;execució des del mateix lloc en què l&apos;heu alçat, cosa que permetrà continuar immediatament amb el vostre treball.&lt;/p&gt;&lt;p&gt;Tingueu en compte que l&apos;operació d&apos;alçar l&apos;estat de la màquina pot prendre molt de temps, depenent del tipus de sistema operatiu client i la quantitat de memòria assignada a la màquina virtual.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Sends the ACPI Power Button press event to the virtual machine.&lt;/p&gt;&lt;p&gt;Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.&lt;/p&gt;&lt;p&gt;If the machine doesn&apos;t respond to this action then the guest operating system may be misconfigured or doesn&apos;t understand ACPI Power Button events at all. In this case you should select the &lt;b&gt;Power off the machine&lt;/b&gt; action to stop virtual machine execution.&lt;/p&gt;</source>
- <translation type="obsolete">&lt;p&gt;Envia a la màquina virtual l&apos;esdeveniment de prémer el botó ACPI Power.&lt;/p&gt;&lt;p&gt;Normalment, el sistema operatiu client que s&apos;està executant a dins de la màquina virtual detectarà este esdeveniment i realitzarà un procediment de tancament net. Esta és una manera recomanada de tancar la màquina virtual perquè totes les aplicacions que s&apos;estan executant en ella tindran la possibilitat d'alçar les seues dades i estat.&lt;/p&gt;&lt;p&gt;Si la màquina no respon a esta acció potser el sistema operatiu client pot estar mal configurat o no entén els events del botó ACPI Power. En este cas, seleccioneu l&apos;acció &lt;b&gt;Atura la màquina&lt;/b&gt; per aturar l&apos;execució de la màquina virtual.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Envia a la màquina virtual l&apos;esdeveniment de prémer el botó ACPI Power.&lt;/p&gt;&lt;p&gt;Normalment, el sistema operatiu client que s&apos;està executant a dins de la màquina virtual detectarà este esdeveniment i realitzarà un procediment de tancament net. Esta és una manera recomanada de tancar la màquina virtual perquè totes les aplicacions que s&apos;estan executant en ella tindran la possibilitat d&apos;alçar les seues dades i estat.&lt;/p&gt;&lt;p&gt;Si la màquina no respon a esta acció potser el sistema operatiu client pot estar mal configurat o no entén els events del botó ACPI Power. En este cas, seleccioneu l&apos;acció &lt;b&gt;Atura la màquina&lt;/b&gt; per aturar l&apos;execució de la màquina virtual.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Turns off the virtual machine.&lt;/p&gt;&lt;p&gt;Note that this action will stop machine execution immediately so that the guest operating system running inside it will not be able to perform a clean shutdown procedure which may result in &lt;i&gt;data loss&lt;/i&gt; inside the virtual machine. Selecting this action is recommended only if the virtual machine does not respond to the &lt;b&gt;Send the shutdown signal&lt;/b&gt; action.&lt;/p&gt;</source>
@@ -7687,7 +8195,7 @@ Versió %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Adaptador %1</translation>
+ <translation type="obsolete">Adaptador %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -8055,7 +8563,7 @@ Versió %1</translation>
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Xarxa VDE, &apos;%1&apos;</translation>
+ <translation type="obsolete">Xarxa VDE, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -8065,7 +8573,7 @@ Versió %1</translation>
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>Adaptador VDE</translation>
+ <translation type="obsolete">Adaptador VDE</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -8262,6 +8770,61 @@ Versió %1</translation>
<comment>DiskType</comment>
<translation>Adjunció múltiple</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Adaptador %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -8964,15 +9527,15 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>Location</source>
- <translation>Ubicació</translation>
+ <translation type="obsolete">Ubicació</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Tipus (Format)</translation>
+ <translation type="obsolete">Tipus (Format)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Connectat a</translation>
+ <translation type="obsolete">Connectat a</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -9054,17 +9617,17 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Connectat a</translation>
+ <translation type="obsolete">Connectat a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Connectat a</translation>
+ <translation type="obsolete">Connectat a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Connectat a</translation>
+ <translation type="obsolete">Connectat a</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -9082,6 +9645,46 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
<source>All %1 images (%2)</source>
<translation>Totes les imatges %1 (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Tipus:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Ubicació:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -9141,7 +9744,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Adaptadors de xarxa</translation>
+ <translation type="obsolete">Adaptadors de xarxa</translation>
</message>
</context>
<context>
@@ -9500,7 +10103,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<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 type="obsolete">&lt;p&gt;La Màquina Virtual ha informat que el sistema client suporta &lt;b&gt;integració del punter del ratolí&lt;/b&gt;. Això significa que no necessiteu &lt;i&gt;capturar&lt;/i&gt; el punter del ratolí per poder fer-lo servir al sistema client -- totes les accions que executeu quan el punter del ratolí estiga a sobre de la Màquina virtual s&apos;enviaran directament al sistema client. Si es captura el ratolí, automàticament es tornarà al mode normal.&lt;/p&gt;&lt;p&gt;La icona del ratolí a la barra d&apos;estat es mostrarà com&amp;nbsp;&lt;img src=mouse_seamless_16px.png/&gt;&amp;nbsp;per informar-vos que la integració del punter està suportada pel sistema client que està actiu.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Nota&lt;/b&gt;: Algunes aplicacions poden comportar-s'incorrectament treballant en el mode d&apos;integració del ratolí. Sempre podeu inhabilitar-ho a la sessió actual (o habilitar-ho) seleccionat l&apos;opció corresponent a la barra de menú.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;La Màquina Virtual ha informat que el sistema client suporta &lt;b&gt;integració del punter del ratolí&lt;/b&gt;. Això significa que no necessiteu &lt;i&gt;capturar&lt;/i&gt; el punter del ratolí per poder fer-lo servir al sistema client -- totes les accions que executeu quan el punter del ratolí estiga a sobre de la Màquina virtual s&apos;enviaran directament al sistema client. Si es captura el ratolí, automàticament es tornarà al mode normal.&lt;/p&gt;&lt;p&gt;La icona del ratolí a la barra d&apos;estat es mostrarà com&amp;nbsp;&lt;img src=mouse_seamless_16px.png/&gt;&amp;nbsp;per informar-vos que la integració del punter està suportada pel sistema client que està actiu.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Nota&lt;/b&gt;: Algunes aplicacions poden comportar-s&apos;incorrectament treballant en el mode d&apos;integració del ratolí. Sempre podeu inhabilitar-ho a la sessió actual (o habilitar-ho) seleccionat l&apos;opció corresponent a la barra de menú.&lt;/p&gt;</translation>
</message>
<message>
<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>
@@ -9679,7 +10282,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>&lt;p&gt;The following VirtualBox settings files have been automatically converted to the new settings file format version &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;However, the results of the conversion were not saved back to disk yet. Please press:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Save&lt;/b&gt; to save all auto-converted files now (it will not be possible to use these settings files with an older version of VirtualBox in the future);&lt;/li&gt;&lt;li&gt;&lt;b&gt;Backup&lt;/b&gt; to create backup copies of the settings files in the old format before saving them in the new format;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Cancel&lt;/b&gt; to not save the auto-converted settings files now.&lt;li&gt;&lt;/ul&gt;&lt;p&gt;Note that if you select &lt;b&gt;Cancel&lt;/b&gt;, the auto-converted settings files will be implicitly saved in the new format anyway once you change a setting or start a virtual machine, but &lt;b&gt;no&lt;/b&gt; backup copies will be created in this case.&lt;/p&gt;</source>
- <translation type="obsolete">&lt;p&gt;Els següents fitxers de paràmetres del VirtualBox s&apos;han convertit automàticament al nou format &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Tot i així, els resultats de la conversió encara no s&apos;han alçat al disc. Premeu:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Alça&lt;/b&gt; per alçar ara els fitxers auto-convertits (ja no serà possible fer servir estos paràmetres amb una versió anterior del VirtualBox);&lt;/li&gt;&lt;li&gt;&lt;b&gt;Còpia de seguretat&lt;/b&gt; per crear una còpia de seguretat dels fitxers de paràmetres en el format antic abans d'alçar-los en el nou format;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Cancel·la&lt;/b&gt; per no alçar ara els fitxers de paràmetres auto-convertits.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Tingueu en compte que si seleccioneu &lt;b&gt;Cancel·la&lt;/b&gt;, els fitxers de paràmetres auto-convertits s'alçaran implícitament en el nou format tot i que una vegada que canvieu algun paràmetre o inicieu una màquina virtual, en canvi en este cas &lt;b&gt;no&lt;/b&gt; es faran còpies de seguretat.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Els següents fitxers de paràmetres del VirtualBox s&apos;han convertit automàticament al nou format &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Tot i així, els resultats de la conversió encara no s&apos;han alçat al disc. Premeu:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Alça&lt;/b&gt; per alçar ara els fitxers auto-convertits (ja no serà possible fer servir estos paràmetres amb una versió anterior del VirtualBox);&lt;/li&gt;&lt;li&gt;&lt;b&gt;Còpia de seguretat&lt;/b&gt; per crear una còpia de seguretat dels fitxers de paràmetres en el format antic abans d&apos;alçar-los en el nou format;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Cancel·la&lt;/b&gt; per no alçar ara els fitxers de paràmetres auto-convertits.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Tingueu en compte que si seleccioneu &lt;b&gt;Cancel·la&lt;/b&gt;, els fitxers de paràmetres auto-convertits s&apos;alçaran implícitament en el nou format tot i que una vegada que canvieu algun paràmetre o inicieu una màquina virtual, en canvi en este cas &lt;b&gt;no&lt;/b&gt; es faran còpies de seguretat.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Save</source>
@@ -9769,7 +10372,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<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;La Màquina Virtual ha informat que el sistema client suporta &lt;b&gt;integració del punter&lt;/b&gt;. Això significa que no necessiteu &lt;i&gt;capturar&lt;/i&gt; el punter per poder fer-lo servir al sistema client -- totes les accions que executeu quan el punter estiga a sobre de la Màquina virtual s&apos;enviaran directament al sistema client. Si es captura el punter, automàticament es tornarà al mode normal.&lt;/p&gt;&lt;p&gt;La icona del punter a la barra d&apos;estat es mostrarà com&amp;nbsp;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;per informar-vos que la integració del punter està suportada pel sistema client que està actiu.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Nota&lt;/b&gt;: Algunes aplicacions poden comportar-s'incorrectament treballant en el mode d&apos;integració del punter. Sempre podeu inhabilitar-ho a la sessió actual (o habilitar-ho) seleccionat l&apos;opció corresponent a la barra de menú.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;La Màquina Virtual ha informat que el sistema client suporta &lt;b&gt;integració del punter&lt;/b&gt;. Això significa que no necessiteu &lt;i&gt;capturar&lt;/i&gt; el punter per poder fer-lo servir al sistema client -- totes les accions que executeu quan el punter estiga a sobre de la Màquina virtual s&apos;enviaran directament al sistema client. Si es captura el punter, automàticament es tornarà al mode normal.&lt;/p&gt;&lt;p&gt;La icona del punter a la barra d&apos;estat es mostrarà com&amp;nbsp;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;per informar-vos que la integració del punter està suportada pel sistema client que està actiu.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Nota&lt;/b&gt;: Algunes aplicacions poden comportar-s&apos;incorrectament treballant en el mode d&apos;integració del punter. Sempre podeu inhabilitar-ho a la sessió actual (o habilitar-ho) seleccionat l&apos;opció corresponent a la barra de menú.&lt;/p&gt;</translation>
</message>
<message>
<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;. 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>
@@ -9854,7 +10457,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>No es pot accedir a l&apos;USB al sistema amfitrió perquè ni el servei de sistema de fitxers USB (usbfs) ni el DBus s&apos;hi troben disponibles. Si voleu fer servir els dispositius USB de l&apos;amfitrió a dins dels sistemes clients, heu de solucionar això i tornar a iniciar el VirtualBox.</translation>
+ <translation type="obsolete">No es pot accedir a l&apos;USB al sistema amfitrió perquè ni el servei de sistema de fitxers USB (usbfs) ni el DBus s&apos;hi troben disponibles. Si voleu fer servir els dispositius USB de l&apos;amfitrió a dins dels sistemes clients, heu de solucionar això i tornar a iniciar el VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -10025,7 +10628,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>&lt;p&gt;The following VirtualBox settings files have been automatically converted to the new settings file format version &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;However, the results of the conversion were not saved back to disk yet. Please press:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Backup&lt;/b&gt; to create backup copies of the settings files in the old format before saving them in the new format;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Overwrite&lt;/b&gt; to save all auto-converted files without creating backup copies (it will not be possible to use these settings files with an older version of VirtualBox afterwards);&lt;/li&gt;%2&lt;/ul&gt;&lt;p&gt;It is recommended to always select &lt;b&gt;Backup&lt;/b&gt; because in this case it will be possible to go back to the previous version of VirtualBox (if necessary) without losing your current settings. See the VirtualBox Manual for more information about downgrading.&lt;/p&gt;</source>
- <translation type="obsolete">&lt;p&gt;Els següents fitxers de paràmetres del VirtualBox s&apos;han convertit automàticament al nou format &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Tot i així, els resultats de la conversió encara no s&apos;han alçat al disc. Premeu:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Alça&lt;/b&gt; per alçar ara els fitxers auto-convertits (ja no serà possible fer servir estos paràmetres amb una versió anterior del VirtualBox);&lt;/li&gt;&lt;li&gt;&lt;b&gt;Còpia de seguretat&lt;/b&gt; per crear una còpia de seguretat dels fitxers de paràmetres en el format antic abans d'alçar-los en el nou format;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Sobreescriu&lt;/b&gt; per alçar tots els fitxers auto-convertitts sense crear còpies de seguretat;&lt;/li&gt;%2&lt;/ul&gt;&lt;p&gt;Es recomana seleccionar en tot moment &lt;b&gt;Còpia de seguretat&lt;/b&gt; perquè sempre serà possible tornar a l&apos;estat anterior sense perdre els paràmetres de configuració actuals. Mireu el manual del VirtualBox per a més informació sobre desactualització.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Els següents fitxers de paràmetres del VirtualBox s&apos;han convertit automàticament al nou format &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Tot i així, els resultats de la conversió encara no s&apos;han alçat al disc. Premeu:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Alça&lt;/b&gt; per alçar ara els fitxers auto-convertits (ja no serà possible fer servir estos paràmetres amb una versió anterior del VirtualBox);&lt;/li&gt;&lt;li&gt;&lt;b&gt;Còpia de seguretat&lt;/b&gt; per crear una còpia de seguretat dels fitxers de paràmetres en el format antic abans d&apos;alçar-los en el nou format;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Sobreescriu&lt;/b&gt; per alçar tots els fitxers auto-convertitts sense crear còpies de seguretat;&lt;/li&gt;%2&lt;/ul&gt;&lt;p&gt;Es recomana seleccionar en tot moment &lt;b&gt;Còpia de seguretat&lt;/b&gt; perquè sempre serà possible tornar a l&apos;estat anterior sense perdre els paràmetres de configuració actuals. Mireu el manual del VirtualBox per a més informació sobre desactualització.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;li&gt;&lt;b&gt;Exit&lt;/b&gt; to terminate VirtualBox without saving the results of the conversion to disk.&lt;/li&gt;</source>
@@ -10117,7 +10720,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Segur que voleu restaurar la captura &lt;b&gt;%1&lt;/b&gt;? Això suposarà perdre l&apos;estat actual de la màquina i no podrà ser recuperat.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Segur que voleu restaurar la captura &lt;b&gt;%1&lt;/b&gt;? Això suposarà perdre l&apos;estat actual de la màquina i no podrà ser recuperat.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -10417,7 +11020,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">S&apos;han produït alguns errors genèrics.</translation>
+ <translation type="unfinished">S&apos;han produït alguns errors genèrics.</translation>
</message>
<message>
<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>
@@ -10506,7 +11109,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>L&apos;eliminació de tots els fitxers que pertanyen a la màquina virtual es troba actualment inhabilitada en sistemes Windows/x64 per evitar fallades. Això s&apos;arreglarà en la propera versió.</translation>
+ <translation type="obsolete">L&apos;eliminació de tots els fitxers que pertanyen a la màquina virtual es troba actualment inhabilitada en sistemes Windows/x64 per evitar fallades. Això s&apos;arreglarà en la propera versió.</translation>
</message>
<message>
<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>
@@ -10514,7 +11117,71 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<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>&lt;p&gt;L&apos;USB 2.0 es troba activat per a esta màquina virtual. Tot i així, es requereix la instal·lació de &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Instal·leu el paquet d&apos;extensions des del lloc web de baixades del VirtualBox. Una vegada fet això, podreu tornar a activar l&apos;USB 2.0. Mentrestant es desactivarà a no ser que cancel·leu els canvis dels paràmetres actuals.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;L&apos;USB 2.0 es troba activat per a esta màquina virtual. Tot i així, es requereix la instal·lació de &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Instal·leu el paquet d&apos;extensions des del lloc web de baixades del VirtualBox. Una vegada fet això, podreu tornar a activar l&apos;USB 2.0. Mentrestant es desactivarà a no ser que cancel·leu els canvis dels paràmetres actuals.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -10593,7 +11260,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>&lt;p&gt;Please fill out this registration form to let vos know that you use VirtualBox and, optionally, to keep you informed about VirtualBox news and updates.&lt;/p&gt;&lt;p&gt;Please use Latin characters only to fill in the fields below. Sun Microsystems will use this information only to gather product usage statistics and to send you VirtualBox newsletters. In particular, Sun Microsystems will never pass your data to third parties. Detailed information about how we use your personal data can be found in the &lt;b&gt;Privacy Policy&lt;/b&gt; section of the VirtualBox Manual or on the &lt;a href=http://www.virtualbox.org/wiki/PrivacyPolicy&gt;Privacy Policy&lt;/a&gt; page of the VirtualBox web-site.&lt;/p&gt;</source>
- <translation type="obsolete">&lt;p&gt;Ompliu este formulari de registre per permetre&apos;ns conèixer que feu servir el VirtualBox i, opcionalment, mantindre-vos informat sobre novetats i actualitzacions del VirtualBox.&lt;/p&gt;&lt;p&gt;Feu servir caràcters llatins per omplir els camps següents. Tingueu en compte que Sun Microsystems farà servir esta informació només per a usos estadístics i per enviar-vos notícies sobre el VirtualBox. Sun Microsystems mai compartirà les vostres dades amb terceres parts. Més informació detallada sobre l&apos;ús de les vostres dades personals poden trobar-s'a la secció de &lt;b&gt;Política de privacitat&lt;/b&gt; al manual de VirtualBox o al&lt;a href=http://www.virtualbox.org/wiki/PrivacyPolicy&gt;Privacy Policy&lt;/a&gt; lloc web del VirtualBox.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Ompliu este formulari de registre per permetre&apos;ns conèixer que feu servir el VirtualBox i, opcionalment, mantindre-vos informat sobre novetats i actualitzacions del VirtualBox.&lt;/p&gt;&lt;p&gt;Feu servir caràcters llatins per omplir els camps següents. Tingueu en compte que Sun Microsystems farà servir esta informació només per a usos estadístics i per enviar-vos notícies sobre el VirtualBox. Sun Microsystems mai compartirà les vostres dades amb terceres parts. Més informació detallada sobre l&apos;ús de les vostres dades personals poden trobar-s&apos;a la secció de &lt;b&gt;Política de privacitat&lt;/b&gt; al manual de VirtualBox o al&lt;a href=http://www.virtualbox.org/wiki/PrivacyPolicy&gt;Privacy Policy&lt;/a&gt; lloc web del VirtualBox.&lt;/p&gt;</translation>
</message>
<message>
<source>I &amp;already have a Sun Online account:</source>
@@ -10660,7 +11327,7 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>Shared Folders</source>
- <translation>Carpetes compartides</translation>
+ <translation type="obsolete">Carpetes compartides</translation>
</message>
</context>
<context>
@@ -10758,11 +11425,11 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Descarta</translation>
+ <translation type="unfinished">Descarta</translation>
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Descar&amp;ta</translation>
+ <translation type="obsolete">Descar&amp;ta</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -11069,12 +11736,24 @@ un disc dur per connectar a la ranura remarcada actualment.&lt;/a&gt;</translati
<source>Show Statusbar</source>
<translation>Mostra la barra d&apos;estat</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
<message>
<source>&lt;i&gt;Select a settings category from the list on the left-hand side and move the mouse over a settings item to get more information&lt;/i&gt;.</source>
- <translation type="obsolete">&lt;i&gt;Seleccioneu una categoria de paràmetres en la llista de l&apos;esquerra i deplaceu el punter sobre un element de la dreta per obtindre'n més informació&lt;/i&gt;.</translation>
+ <translation type="obsolete">&lt;i&gt;Seleccioneu una categoria de paràmetres en la llista de l&apos;esquerra i deplaceu el punter sobre un element de la dreta per obtindre&apos;n més informació&lt;/i&gt;.</translation>
</message>
<message>
<source>On the &lt;b&gt;%1&lt;/b&gt; page, %2</source>
@@ -11471,6 +12150,14 @@ per accedir a ella des d&apos;un sistema Linux. Esta característica requereix G
<source> (%1 ago)</source>
<translation> (fa %1)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
@@ -12613,7 +13300,7 @@ o a ambdòs (&lt;i&gt;Qualsevol&lt;/i&gt;).&lt;/qt&gt;</translation>
</message>
<message>
<source>Displays the path where snapshots of this virtual machine will be stored. Be aware that snapshots can take quite a lot of disk space.</source>
- <translation type="obsolete">Mostra la ruta on les captures d&apos;esta màquina virtual s'alçaran. Tingueu en compte que les captures poden ocupar prou quantitat d&apos;espai al disc dur.</translation>
+ <translation type="obsolete">Mostra la ruta on les captures d&apos;esta màquina virtual s&apos;alçaran. Tingueu en compte que les captures poden ocupar prou quantitat d&apos;espai al disc dur.</translation>
</message>
<message>
<source>Displays the virtual hard disk to attach to this IDE slot and allows to quickly select a different hard disk.</source>
@@ -12709,7 +13396,7 @@ o a ambdòs (&lt;i&gt;Qualsevol&lt;/i&gt;).&lt;/qt&gt;</translation>
</message>
<message>
<source>If checked, any change to mounted CD/DVD or Floppy media performed during machine execution will be saved in the settings file in order to preserve the configuration of mounted media between runs.</source>
- <translation type="obsolete">Si està marcat, qualsevol canvi al CD/DVD o disquet muntat s'alçarà al fitxer de configuració per tal de preservar la configuració dels suports muntats entre cada execució de la màquina virtual.</translation>
+ <translation type="obsolete">Si està marcat, qualsevol canvi al CD/DVD o disquet muntat s&apos;alçarà al fitxer de configuració per tal de preservar la configuració dels suports muntats entre cada execució de la màquina virtual.</translation>
</message>
<message>
<source>&amp;Image File</source>
@@ -12893,7 +13580,7 @@ o a ambdòs (&lt;i&gt;Qualsevol&lt;/i&gt;).&lt;/qt&gt;</translation>
<message>
<source>&lt;qt&gt;Controls the audio output driver. The &lt;b&gt;Null Audio Driver&lt;/b&gt;
makes the guest see an audio card, however every access to it will be ignored.&lt;/qt&gt;</source>
- <translation type="obsolete">&lt;qt&gt;Gestiona el controlador d'eixida de so. El &lt;b&gt;controlador d&apos;àudio Nul&lt;/b&gt;
+ <translation type="obsolete">&lt;qt&gt;Gestiona el controlador d&apos;eixida de so. El &lt;b&gt;controlador d&apos;àudio Nul&lt;/b&gt;
fa que el client veja una tarjeta de so, però l&apos;accés a ella s&apos;ignorarà.&lt;/qt&gt;</translation>
</message>
<message>
@@ -13052,7 +13739,7 @@ esta característica després d&apos;haver instal·lat un Windows al sistema ope
</message>
<message>
<source>When checked, a virtual PCI audio card will be plugged into the virtual machine and will communicate with the host audio system using the specified driver.</source>
- <translation type="obsolete">Quan estiga marcat, la tarjeta de so PCI virtual es connectarà a dins de la màquina virtual, la qual farà servir un controlador específic per comunicar-s'amb la tarjeta de so de l&apos;amfitrió.</translation>
+ <translation type="obsolete">Quan estiga marcat, la tarjeta de so PCI virtual es connectarà a dins de la màquina virtual, la qual farà servir un controlador específic per comunicar-s&apos;amb la tarjeta de so de l&apos;amfitrió.</translation>
</message>
<message>
<source>When checked, the VM will act as a Remote Desktop Protocol (RDP) server, allowing remote clients to connect and operate the VM (when it is running) using a standard RDP client.</source>
@@ -13408,7 +14095,7 @@ al sistema amfitrió.&lt;/qt&gt;</translation>
<name>VBoxVMSettingsVRDP</name>
<message>
<source>When checked, the VM will act as a Remote Desktop Protocol (RDP) server, allowing remote clients to connect and operate the VM (when it is running) using a standard RDP client.</source>
- <translation type="obsolete">Quan estiga marcat, la màquina virtual actuarà com un servidor protocol d&apos;escriptori remot (RDP), permetent als clients remots connectar-s'a la màquina virtual (quan estiga executant-se) fent servir l&apos;estàndard client RDP.</translation>
+ <translation type="obsolete">Quan estiga marcat, la màquina virtual actuarà com un servidor protocol d&apos;escriptori remot (RDP), permetent als clients remots connectar-s&apos;a la màquina virtual (quan estiga executant-se) fent servir l&apos;estàndard client RDP.</translation>
</message>
<message>
<source>&amp;Enable VRDP Server</source>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_cs.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_cs.ts
index 1cb809d89..81522cda4 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_cs.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_cs.ts
@@ -520,12 +520,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>&amp;Informace o sezení</translation>
+ <translation type="obsolete">&amp;Informace o sezení</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>Povolit v&amp;zdálený server</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">Nas&amp;tavení...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -691,7 +776,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE síť, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE síť, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -817,6 +902,26 @@
<comment>details report</comment>
<translation>Popis</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -1028,6 +1133,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">&amp;Název poÄítaÄe:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1362,6 +1471,10 @@ p, li { white-space: pre-wrap; }
<source>Cancel</source>
<translation type="obsolete">Zrušit</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">Spustit</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1435,41 +1548,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Obecné</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Vstup</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Aktualizace</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Jazyk</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Síť</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Rozšíření</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1910,6 +1988,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1979,23 +2108,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Levý Shift</translation>
+ <translation type="obsolete">Levý Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Pravý Shift</translation>
+ <translation type="obsolete">Pravý Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Levý Ctrl</translation>
+ <translation type="obsolete">Levý Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Pravý Ctrl</translation>
+ <translation type="obsolete">Pravý Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Levý Alt</translation>
+ <translation type="obsolete">Levý Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2100,6 +2229,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importovat &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2244,7 +2377,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Indikuje stav virtualizaÄních rozšíření použitých tímto virtuálním poÄítaÄem:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Indikuje stav virtualizaÄních rozšíření použitých tímto virtuálním poÄítaÄem:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2267,6 +2400,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;Vzdálená plocha serveru poslouchá na portu %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2466,7 +2604,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Pro systém, který používá WDDM ovladaÄ máte povolenu 3D akceleraci. Pro maximální výkon nastavte velikost VRAM pro hosta na minimální hodnotu &lt;b&gt;%1&lt;/b&gt;.</translation>
+ <translation type="obsolete">Pro systém, který používá WDDM ovladaÄ máte povolenu 3D akceleraci. Pro maximální výkon nastavte velikost VRAM pro hosta na minimální hodnotu &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">máte povolenu 2D akceleraci videa. Protože tato akcelerace je podporována pouze na virtuálních poÄítaÄích s Windows, bude tato vlastnost zákázána.</translation>
</message>
</context>
<context>
@@ -2711,6 +2857,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Zobrazit na&amp;hoře na obrazovce</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">zvolili jste 64bitový OS pro tento virtuální poÄítaÄ. Protože je nutná podpora hardwarové virtualizace (VT-x/AMD-V), byla tato volba automaticky nastavena.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2820,7 +2970,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Zvolte název síťového rozhraní pokud je připojení typu &lt;b&gt;Síťový most&lt;/b&gt; nebo &lt;b&gt;Síť pouze s hostitelem&lt;/b&gt; a název vnitřní sítě pokud je typ připojení &lt;b&gt;Vnitřní síť&lt;/b&gt;.</translation>
+ <translation type="obsolete">Zvolte název síťového rozhraní pokud je připojení typu &lt;b&gt;Síťový most&lt;/b&gt; nebo &lt;b&gt;Síť pouze s hostitelem&lt;/b&gt; a název vnitřní sítě pokud je typ připojení &lt;b&gt;Vnitřní síť&lt;/b&gt;.</translation>
</message>
<message>
<source>Open extended settings dialog for current attachment type.</source>
@@ -2918,6 +3068,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>&amp;Předávání portů</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3452,7 +3638,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Pro &lt;i&gt;%1&lt;/i&gt; nebyl vybrán žádný pevný disk.</translation>
+ <translation type="obsolete">Pro &lt;i&gt;%1&lt;/i&gt; nebyl vybrán žádný pevný disk.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3726,6 +3912,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">minimálně jedna podporovaná</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">až %1 podporovaných</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">používáte nyní více Å™adiÄů než Äipová sada %1 podporuje. Změňte prosím typ Äipové sady na záložce Nastavení systému nebo zmenÅ¡ete následující poÄet Å™adiÄů na záložce Nastavení Å™adiÄe: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3916,6 +4156,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>pÅ™iÅ™adili jste tomuto poÄítaÄi Äipovou sadu ICH9. Ta nebude správnÄ› fungovat dokud nebude také povolena volba &apos;IO-APIC&apos;. To se aktivuje automaticky pokud akceptujete nastavení virtuálního poÄítaÄe pomocí tlaÄítka OK.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished">povolili jste USB HID zařízení. To nebude pracovat pokud nebude také povolena emulace USB. Ta se automaticky aktivuje jakmile akceptujete nastavení virtuálního poÄítaÄe stisknutím tlaÄítka OK.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -4041,7 +4307,7 @@ p, li { white-space: pre-wrap; }
<translation>&lt;nobr&gt;Stav: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -4155,6 +4421,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4200,7 +4481,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Vytvořit nový virtuální disk</translation>
@@ -4289,7 +4570,7 @@ jako velikost virtuálního pevného disku.&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Shrnutí</translation>
+ <translation type="unfinished">Shrnutí</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4305,7 +4586,7 @@ jako velikost virtuálního pevného disku.&lt;/p&gt;</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Vyberte soubor pro nový obraz pevného disku</translation>
+ <translation type="unfinished">Vyberte soubor pro nový obraz pevného disku</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk image for your virtual machine.&lt;/p&gt;&lt;p&gt;Use the &lt;b&gt;Next&lt;/b&gt; button to go to the next page of the wizard and the &lt;b&gt;Back&lt;/b&gt; button to return to the previous page.&lt;/p&gt;</source>
@@ -4347,12 +4628,12 @@ jako velikost virtuálního pevného disku.&lt;/p&gt;</translation>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Umístění</translation>
+ <translation type="unfinished">Umístění</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Velikost</translation>
+ <translation type="unfinished">Velikost</translation>
</message>
<message>
<source>Bytes</source>
@@ -4411,108 +4692,280 @@ jako velikost virtuálního pevného disku.&lt;/p&gt;</translation>
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Pokud jsou výše uvedené údaje v pořádku, stisknÄ›te tlaÄítko &lt;b&gt;DokonÄit&lt;/b&gt;. Po jeho stisknutí bude vytvoÅ™en nový obraz pevného disku.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;Umístění</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">V&amp;elikost</translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Vítejte v průvodci vytvoření nového virtuálního disku!</translation>
+ <translation type="obsolete">Vítejte v průvodci vytvoření nového virtuálního disku!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Tento průvodce vám pomůže vytvoÅ™it nový virtuální disk pro virtuální poÄítaÄ.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Tento průvodce vám pomůže vytvoÅ™it nový virtuální disk pro virtuální poÄítaÄ.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Vyberte typ virtuálního pevného disku, který chcete vytvoÅ™it.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Dynamicky zvÄ›tÅ¡ující se obraz&lt;/b&gt; na zaÄátku obsadí velmi málo místa na vaÅ¡em fyzickém disku. Bude se dynamicky zvÄ›tÅ¡ovat (až do dané velikosti) tak, jak bude hostovaný OS zabírat místo na disku&lt;/p&gt;&lt;p&gt;&lt;b&gt;Obraz o pevnÄ› dané velikosti&lt;/b&gt; se nezvÄ›tÅ¡uje. Je uložen v souboru o pÅ™ibližnÄ› stejné velikosti jako velikost virtuálního pevného disku. VytvoÅ™ení obrazu o pevné velikosti může trvat déle v závislosti na velikosti vytvářeného disku a rychlosti zápisu fyzického pevného disku.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Vyberte typ virtuálního pevného disku, který chcete vytvoÅ™it.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Dynamicky zvÄ›tÅ¡ující se obraz&lt;/b&gt; na zaÄátku obsadí velmi málo místa na vaÅ¡em fyzickém disku. Bude se dynamicky zvÄ›tÅ¡ovat (až do dané velikosti) tak, jak bude hostovaný OS zabírat místo na disku&lt;/p&gt;&lt;p&gt;&lt;b&gt;Obraz o pevnÄ› dané velikosti&lt;/b&gt; se nezvÄ›tÅ¡uje. Je uložen v souboru o pÅ™ibližnÄ› stejné velikosti jako velikost virtuálního pevného disku. VytvoÅ™ení obrazu o pevné velikosti může trvat déle v závislosti na velikosti vytvářeného disku a rychlosti zápisu fyzického pevného disku.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Typ uložení</translation>
+ <translation type="obsolete">Typ uložení</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>&amp;Dynamicky se zvětšující obraz</translation>
+ <translation type="obsolete">&amp;Dynamicky se zvětšující obraz</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>&amp;Obraz o pevně dané velikosti</translation>
+ <translation type="obsolete">&amp;Obraz o pevně dané velikosti</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Typ obrazu virtuálního disku</translation>
+ <translation type="obsolete">Typ obrazu virtuálního disku</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;StisknÄ›te tlaÄítko &lt;b&gt;Vybrat&lt;/b&gt; pro výbÄ›r umístÄ›ní a názvu souboru pro uložení obrazu virtuálního disku nebo napiÅ¡te do políÄka název souboru.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;StisknÄ›te tlaÄítko &lt;b&gt;Vybrat&lt;/b&gt; pro výbÄ›r umístÄ›ní a názvu souboru pro uložení obrazu virtuálního disku nebo napiÅ¡te do políÄka název souboru.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;Umístění</translation>
+ <translation type="obsolete">&amp;Umístění</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Nastavte velikost virtuálního pevného disku v megabajtech. Velikost bude nahlášena hostovanému OS jako maximální velikost pevného disku.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Nastavte velikost virtuálního pevného disku v megabajtech. Velikost bude nahlášena hostovanému OS jako maximální velikost pevného disku.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>V&amp;elikost</translation>
+ <translation type="obsolete">V&amp;elikost</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Umístění a velikost virtuálního disku</translation>
+ <translation type="obsolete">Umístění a velikost virtuálního disku</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Vyberte soubor pro nový obraz pevného disku</translation>
+ <translation type="obsolete">Vyberte soubor pro nový obraz pevného disku</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Obrazy pevných disků (*.vdi)</translation>
+ <translation type="obsolete">Obrazy pevných disků (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Chystáte se vytvořit nový virtuální pevný disk s následujícími parametry:</translation>
+ <translation type="obsolete">Chystáte se vytvořit nový virtuální pevný disk s následujícími parametry:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Shrnutí</translation>
+ <translation type="obsolete">Shrnutí</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Typ</translation>
+ <translation type="obsolete">Typ</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Umístění</translation>
+ <translation type="obsolete">Umístění</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Velikost</translation>
+ <translation type="obsolete">Velikost</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Pokud jsou výše uvedené údaje v pořádku, stisknÄ›te tlaÄítko &lt;b&gt;%1&lt;/b&gt;. Po stisknutí bude vytvoÅ™en nový obraz pevného disku.</translation>
+ <translation type="obsolete">Pokud jsou výše uvedené údaje v pořádku, stisknÄ›te tlaÄítko &lt;b&gt;%1&lt;/b&gt;. Po stisknutí bude vytvoÅ™en nový obraz pevného disku.</translation>
</message>
</context>
<context>
@@ -4731,6 +5184,10 @@ krok a připojit pevné disky později použitím dialogu Nastavení VM.&lt;/p&g
<source>Boot Hard &amp;Disk (Primary Master)</source>
<translation type="obsolete">&amp;Bootovací pevný disk (primární master)</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -5016,6 +5473,120 @@ krok a připojit pevné disky později použitím dialogu Nastavení VM.&lt;/p&g
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Obecné</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Vstup</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Aktualizace</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Jazyk</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Síť</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Rozšíření</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Obecné</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>Systém</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Obrazovka</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Úložiště</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Zvuk</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Síť</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Porty</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Sériové porty</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Paralelní porty</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Sdílené složky</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">zvolili jste 64bitový OS pro tento virtuální poÄítaÄ. Protože je nutná podpora hardwarové virtualizace (VT-x/AMD-V), byla tato volba automaticky nastavena.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">máte povolenu 2D akceleraci videa. Protože tato akcelerace je podporována pouze na virtuálních poÄítaÄích s Windows, bude tato vlastnost zákázána.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">povolili jste USB HID zařízení. To nebude pracovat pokud nebude také povolena emulace USB. Ta se automaticky aktivuje jakmile akceptujete nastavení virtuálního poÄítaÄe stisknutím tlaÄítka OK.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">minimálně jedna podporovaná</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">až %1 podporovaných</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">používáte nyní více Å™adiÄů než Äipová sada %1 podporuje. Změňte prosím typ Äipové sady na záložce Nastavení systému nebo zmenÅ¡ete následující poÄet Å™adiÄů na záložce Nastavení Å™adiÄe: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -5154,81 +5725,6 @@ krok a připojit pevné disky později použitím dialogu Nastavení VM.&lt;/p&g
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Obecné</translation>
- </message>
- <message>
- <source>System</source>
- <translation>Systém</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Obrazovka</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Úložiště</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Zvuk</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Síť</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Porty</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Sériové porty</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Paralelní porty</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Sdílené složky</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>zvolili jste 64bitový OS pro tento virtuální poÄítaÄ. Protože je nutná podpora hardwarové virtualizace (VT-x/AMD-V), byla tato volba automaticky nastavena.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>máte povolenu 2D akceleraci videa. Protože tato akcelerace je podporována pouze na virtuálních poÄítaÄích s Windows, bude tato vlastnost zákázána.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>povolili jste USB HID zařízení. To nebude pracovat pokud nebude také povolena emulace USB. Ta se automaticky aktivuje jakmile akceptujete nastavení virtuálního poÄítaÄe stisknutím tlaÄítka OK.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>minimálně jedna podporovaná</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>až %1 podporovaných</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>používáte nyní více Å™adiÄů než Äipová sada %1 podporuje. Změňte prosím typ Äipové sady na záložce Nastavení systému nebo zmenÅ¡ete následující poÄet Å™adiÄů na záložce Nastavení Å™adiÄe: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5448,6 +5944,14 @@ Verze %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation>ŘadiÄ disku SAS</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -7463,7 +7967,7 @@ Verze %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Karta %1</translation>
+ <translation type="obsolete">Karta %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -7818,7 +8322,7 @@ Verze %1</translation>
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE síť, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE síť, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -7828,7 +8332,7 @@ Verze %1</translation>
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>VDE adaptér</translation>
+ <translation type="obsolete">VDE adaptér</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -8025,6 +8529,61 @@ Verze %1</translation>
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Karta %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -8454,15 +9013,15 @@ na výchozí jazyk systému.&lt;/qt&gt;
</message>
<message>
<source>Location</source>
- <translation>Umístění</translation>
+ <translation type="obsolete">Umístění</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Typ (formát)</translation>
+ <translation type="obsolete">Typ (formát)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Připojeno k</translation>
+ <translation type="obsolete">Připojeno k</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -8544,17 +9103,17 @@ na výchozí jazyk systému.&lt;/qt&gt;
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Připojen k</translation>
+ <translation type="obsolete">Připojen k</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Připojen k</translation>
+ <translation type="obsolete">Připojen k</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Připojen k</translation>
+ <translation type="obsolete">Připojen k</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -8572,6 +9131,46 @@ na výchozí jazyk systému.&lt;/qt&gt;
<source>All %1 images (%2)</source>
<translation>Všechny obrazy -%1 (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Typ:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Umístění:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -8631,7 +9230,7 @@ na výchozí jazyk systému.&lt;/qt&gt;
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Síťové karty</translation>
+ <translation type="obsolete">Síťové karty</translation>
</message>
</context>
<context>
@@ -9379,7 +9978,7 @@ na výchozí jazyk systému.&lt;/qt&gt;
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Nelze použít USB na hostovaném systému i přesto, protože není dostupný USB souborový systém (usbfs) nebo nejsou dostupné služby DBus a hal. Pokud chcete používat USB zařízené v hostovaném systému, musíte to opravit a restartovat VirtualBox.</translation>
+ <translation type="obsolete">Nelze použít USB na hostovaném systému i přesto, protože není dostupný USB souborový systém (usbfs) nebo nejsou dostupné služby DBus a hal. Pokud chcete používat USB zařízené v hostovaném systému, musíte to opravit a restartovat VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -9614,7 +10213,7 @@ na výchozí jazyk systému.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Opravdu chcete obnovit snímek &lt;b&gt;%1&lt;/b&gt;? Tím pÅ™ijdete o aktuální stav poÄítaÄe, který už potom nelze obnovit.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Opravdu chcete obnovit snímek &lt;b&gt;%1&lt;/b&gt;? Tím pÅ™ijdete o aktuální stav poÄítaÄe, který už potom nelze obnovit.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -9906,7 +10505,7 @@ na výchozí jazyk systému.&lt;/qt&gt;
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">Omlouváme se, vyskytla se obecná chyba.</translation>
+ <translation type="unfinished">Omlouváme se, vyskytla se obecná chyba.</translation>
</message>
<message>
<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>
@@ -9994,15 +10593,71 @@ na výchozí jazyk systému.&lt;/qt&gt;
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -10133,7 +10788,7 @@ na výchozí jazyk systému.&lt;/qt&gt;
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Sdílené složky</translation>
+ <translation type="obsolete">Sdílené složky</translation>
</message>
<message>
<source>Cancel</source>
@@ -10228,11 +10883,11 @@ na výchozí jazyk systému.&lt;/qt&gt;
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Zruš&amp;it</translation>
+ <translation type="obsolete">Zruš&amp;it</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Zrušit</translation>
+ <translation type="unfinished">Zrušit</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -10494,6 +11149,18 @@ na výchozí jazyk systému.&lt;/qt&gt;
<source>Show Statusbar</source>
<translation>Zobrazit stavovou lištu</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -10856,6 +11523,14 @@ pro přístup z Linuxových OS. Tato funkce vyžaduje Přídavky pro hosta.&lt;/
<source> (%1 ago)</source>
<translation> (před %1)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_da.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_da.ts
index 77a30c360..d5b66bab8 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_da.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_da.ts
@@ -524,12 +524,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>Sessionsi&amp;nformation</translation>
+ <translation type="obsolete">Sessionsi&amp;nformation</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>Tillad fj&amp;ernskærm</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">Op&amp;sætning...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -695,7 +780,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE netværk, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE netværk, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -821,6 +906,26 @@
<comment>details report</comment>
<translation>Beskrivelse</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -997,6 +1102,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">Værtsnavn:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1334,6 +1443,10 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;Tryk på knappen &lt;b&gt;Færdig&lt;/b&gt;, hvis ovenstående er korrekt. Når du trykker, vil det valgte medie midlertidigt blive monteret i den virtuelle maskine, som derefter vil starte op.&lt;/p&gt;&lt;p&gt;Bemærk at når du lukker den virtuelle maskine, vil det angivne medie automatisk blive afmonteret og opstartsenheden vil igen være den første harddisk.&lt;/p&gt;&lt;p&gt;Afhængig af dit installationsprogram kan det være nødvendigt manuelt at afmontere mediet efter installationsprogrammet har genstartet den virtuelle maskine for at undgå at installationsprogrammet starter forfra. Du kan gøre dette ved at vælge &lt;b&gt;Afmontér...&lt;/b&gt; i menuen &lt;b&gt;Enheder&lt;/b&gt;.&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1407,42 +1520,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Generelt</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Input</translation>
- </message>
- <message>
- <source>Update</source>
- <translatorcomment>Verb or noun?</translatorcomment>
- <translation>Opdateringer</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Sprog</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Netværk</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Udvidelser</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1879,6 +1956,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1948,23 +2076,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Venstre Shift</translation>
+ <translation type="obsolete">Venstre Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Højre Shift</translation>
+ <translation type="obsolete">Højre Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Venstre Ctrl</translation>
+ <translation type="obsolete">Venstre Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Højre Ctrl</translation>
+ <translation type="obsolete">Højre Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Venstre Alt</translation>
+ <translation type="obsolete">Venstre Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2183,6 +2311,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importer &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2327,7 +2459,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Viser om værtsmaskinens funktioner til hardware-virtualisering bruges af den virtuelle maskine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Viser om værtsmaskinens funktioner til hardware-virtualisering bruges af den virtuelle maskine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2350,6 +2482,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;Fjernskærm-serveren lytter på port %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2549,7 +2686,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Du har slået 3D-acceleration til i et operativsystem, der bruger WDDM-skærmdriveren. Sæt gæstens grafikhukommelse til mindst &lt;b&gt;%1&lt;/b&gt; for maksimal ydelse.</translation>
+ <translation type="obsolete">Du har slået 3D-acceleration til i et operativsystem, der bruger WDDM-skærmdriveren. Sæt gæstens grafikhukommelse til mindst &lt;b&gt;%1&lt;/b&gt; for maksimal ydelse.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">du har 2D-videoacceleration aktiveret. 2D-videoacceleration understøttes kun, når gæsteoperativsystemet er Windows og deaktiveres derfor.</translation>
</message>
</context>
<context>
@@ -2627,6 +2772,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Vis i &amp;toppen af skærm</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">Du har valgt et 64-bit gæsteoperativsystem til denne VM. Da denne type gæst kræver hardware-virtualisering (VT-x/AMD-V) er dette automatisk blevet slået til.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2681,7 +2830,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Angiver navnet på netværkskortet, hvis tilslutningstypen er &lt;b&gt;Netværksbro&lt;/b&gt; eller &lt;b&gt;Værtsbegrænset netværk&lt;/b&gt; eller navnet på det interne netværk hvis tilslutningstypen er &lt;b&gt;Internt netværk&lt;/b&gt;</translation>
+ <translation type="obsolete">Angiver navnet på netværkskortet, hvis tilslutningstypen er &lt;b&gt;Netværksbro&lt;/b&gt; eller &lt;b&gt;Værtsbegrænset netværk&lt;/b&gt; eller navnet på det interne netværk hvis tilslutningstypen er &lt;b&gt;Internt netværk&lt;/b&gt;</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -2719,6 +2868,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>&amp;Port-viderestilling</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3162,7 +3347,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Ingen harddisk er valgt for &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">Ingen harddisk er valgt for &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3437,6 +3622,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation>Vælg en virtuel diskette-fil...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">højst én understøttet</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">Op til %1 understøttet</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">du bruger netop nu flere lager-styreenheder end et %1 chipset understøtter. Tilpas chipset-typen under System-indstillinger eller formindsk antallet af de følgende lager-styreenheder under Lager-indstillinger: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3627,6 +3866,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>du har valgt et ICH9-chipset i denne VM. Det vil ikke virke korrekt, medmindre IO-APIC aktiveres. Det vil ske automatisk, når du godkender VM-indstillingerne ved at trykke på OK.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished">du har tilsluttet en USB HID (Human Interface Device). Den vil ikke virke medmindre USB emulering er aktiveret. Dette vil ske automatisk når du accepterer VM-indstillingerne ved at trykke OK.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3753,7 +4018,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>USB 2.0 er pt aktiveret i denne virtuelle maskine. Dette kræver at &lt;b&gt;%1&lt;/b&gt; installeres - denne kan hentes fra VirtualBox&apos; hjemmeside. Derefter kan du reaktivere USB 2.0. USB 2.0 vil blive deaktiveret, medmindre du annullerer de nuværende ændringer.</translation>
+ <translation type="obsolete">USB 2.0 er pt aktiveret i denne virtuelle maskine. Dette kræver at &lt;b&gt;%1&lt;/b&gt; installeres - denne kan hentes fra VirtualBox&apos; hjemmeside. Derefter kan du reaktivere USB 2.0. USB 2.0 vil blive deaktiveret, medmindre du annullerer de nuværende ændringer.</translation>
+ </message>
+ <message>
+ <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>
</context>
<context>
@@ -3867,6 +4136,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3912,7 +4196,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Opret ny virtuel disk</translation>
@@ -3927,7 +4211,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Oversigt</translation>
+ <translation type="unfinished">Oversigt</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -3939,7 +4223,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Vælg et filnavn til det nye harddisk-aftryk</translation>
+ <translation type="unfinished">Vælg et filnavn til det nye harddisk-aftryk</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -3961,12 +4245,12 @@ p, li { white-space: pre-wrap; }
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Placering</translation>
+ <translation type="unfinished">Placering</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Størrelse</translation>
+ <translation type="unfinished">Størrelse</translation>
</message>
<message>
<source>Bytes</source>
@@ -4025,108 +4309,280 @@ p, li { white-space: pre-wrap; }
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Hvis indstillingerne er som du ønsker, så klik på &lt;b&gt;Færdig&lt;/b&gt; for at oprette din nye harddisk.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">P&amp;lacering</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Størrelse</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Denne guide hjælper dig med at oprette en ny virtuel disk!</translation>
+ <translation type="obsolete">Denne guide hjælper dig med at oprette en ny virtuel disk!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Denne guide hjælper dig med at oprette en ny virtuel disk til din virtuelle maskine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Denne guide hjælper dig med at oprette en ny virtuel disk til din virtuelle maskine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished">Vælg en virtuel harddisk-fil...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Vælg en allokeringsstrategi for din virtuelle harddisk.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Dynamisk udvidelse&lt;/b&gt; optager kun lidt plads i starten, men vokser dynamisk op til den angivne størrelse i takt med at gæsteoperativsystemet allokerer plads.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Fast størrelse&lt;/b&gt; vokser aldrig. Pladsen allokeres på forhånd i en fil af samme størrelse som den virtuelle harddisk. Oprettelsen af denne type harddisk kan tage lang tid afhængig af den valgte størrelse og skrivehastigheden på din fysiske harddisk.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Vælg en allokeringsstrategi for din virtuelle harddisk.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Dynamisk udvidelse&lt;/b&gt; optager kun lidt plads i starten, men vokser dynamisk op til den angivne størrelse i takt med at gæsteoperativsystemet allokerer plads.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Fast størrelse&lt;/b&gt; vokser aldrig. Pladsen allokeres på forhånd i en fil af samme størrelse som den virtuelle harddisk. Oprettelsen af denne type harddisk kan tage lang tid afhængig af den valgte størrelse og skrivehastigheden på din fysiske harddisk.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Allokeringsstrategi</translation>
+ <translation type="obsolete">Allokeringsstrategi</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>&amp;Dynamisk udvidelse</translation>
+ <translation type="obsolete">&amp;Dynamisk udvidelse</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>&amp;Fast størrelse</translation>
+ <translation type="obsolete">&amp;Fast størrelse</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Allokeringsstrategi</translation>
+ <translation type="obsolete">Allokeringsstrategi</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Klik på &lt;b&gt;Vælg&lt;/b&gt; for at vælge placeringen af filen, som harddisken gemmes i eller indtast et filnavn i feltet.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Klik på &lt;b&gt;Vælg&lt;/b&gt; for at vælge placeringen af filen, som harddisken gemmes i eller indtast et filnavn i feltet.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>P&amp;lacering</translation>
+ <translation type="obsolete">P&amp;lacering</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Angiv størrelsen af den virtuelle harddisk i megabytes. Gæsteoperativsystemet vil se denne værdi som harddiskens maksimale størrelse.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Angiv størrelsen af den virtuelle harddisk i megabytes. Gæsteoperativsystemet vil se denne værdi som harddiskens maksimale størrelse.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Størrelse</translation>
+ <translation type="obsolete">&amp;Størrelse</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Placering og størrelse af virtuel disk</translation>
+ <translation type="obsolete">Placering og størrelse af virtuel disk</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Vælg et filnavn til det nye harddisk-aftryk</translation>
+ <translation type="obsolete">Vælg et filnavn til det nye harddisk-aftryk</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Harddisk-aftryk (*.vdi)</translation>
+ <translation type="obsolete">Harddisk-aftryk (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Du er ved at oprette en ny virtuel harddisk med følgende egenskaber:</translation>
+ <translation type="obsolete">Du er ved at oprette en ny virtuel harddisk med følgende egenskaber:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Oversigt</translation>
+ <translation type="obsolete">Oversigt</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Type</translation>
+ <translation type="obsolete">Type</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Placering</translation>
+ <translation type="obsolete">Placering</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Størrelse</translation>
+ <translation type="obsolete">Størrelse</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Tryk &lt;b&gt;%1&lt;/b&gt;, hvis ovenstående indstillinger er korrekte. Når du trykker vil den nye harddisk blive oprettet.</translation>
+ <translation type="obsolete">Tryk &lt;b&gt;%1&lt;/b&gt;, hvis ovenstående indstillinger er korrekte. Når du trykker vil den nye harddisk blive oprettet.</translation>
</message>
</context>
<context>
@@ -4256,6 +4712,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">Br&amp;ug eksisterende harddisk</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4541,6 +5001,122 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Generelt</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Input</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translatorcomment>Verb or noun?</translatorcomment>
+ <translation>Opdateringer</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Sprog</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Netværk</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Udvidelser</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Generelt</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>System</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Skærm</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Lagerenheder</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Lydkort</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Netværk</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Porte</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Serielle porte</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Parallelporte</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Delte mapper</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">Du har valgt et 64-bit gæsteoperativsystem til denne VM. Da denne type gæst kræver hardware-virtualisering (VT-x/AMD-V) er dette automatisk blevet slået til.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">du har 2D-videoacceleration aktiveret. 2D-videoacceleration understøttes kun, når gæsteoperativsystemet er Windows og deaktiveres derfor.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">du har tilsluttet en USB HID (Human Interface Device). Den vil ikke virke medmindre USB emulering er aktiveret. Dette vil ske automatisk når du accepterer VM-indstillingerne ved at trykke OK.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translatorcomment>en hvad?</translatorcomment>
+ <translation type="obsolete">højst én understøttet</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">Op til %1 understøttet</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">du bruger netop nu flere lager-styreenheder end et %1 chipset understøtter. Tilpas chipset-typen under System-indstillinger eller formindsk antallet af de følgende lager-styreenheder under Lager-indstillinger: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -4679,82 +5255,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Generelt</translation>
- </message>
- <message>
- <source>System</source>
- <translation>System</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Skærm</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Lagerenheder</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Lydkort</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Netværk</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Porte</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Serielle porte</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Parallelporte</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Delte mapper</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>Du har valgt et 64-bit gæsteoperativsystem til denne VM. Da denne type gæst kræver hardware-virtualisering (VT-x/AMD-V) er dette automatisk blevet slået til.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>du har 2D-videoacceleration aktiveret. 2D-videoacceleration understøttes kun, når gæsteoperativsystemet er Windows og deaktiveres derfor.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>du har tilsluttet en USB HID (Human Interface Device). Den vil ikke virke medmindre USB emulering er aktiveret. Dette vil ske automatisk når du accepterer VM-indstillingerne ved at trykke OK.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translatorcomment>en hvad?</translatorcomment>
- <translation>højst én understøttet</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>Op til %1 understøttet</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>du bruger netop nu flere lager-styreenheder end et %1 chipset understøtter. Tilpas chipset-typen under System-indstillinger eller formindsk antallet af de følgende lager-styreenheder under Lager-indstillinger: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -4889,6 +5389,14 @@ p, li { white-space: pre-wrap; }
<source>Hard Disk Controller (SAS)</source>
<translation>Harddiskenhed (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -6264,7 +6772,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Netværkskort %1</translation>
+ <translation type="obsolete">Netværkskort %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -6706,7 +7214,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE netværk, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE netværk, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -6716,7 +7224,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>VDE-adapter</translation>
+ <translation type="obsolete">VDE-adapter</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -6909,6 +7417,61 @@ p, li { white-space: pre-wrap; }
<comment>DiskType</comment>
<translation>Multi-forbundet</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Netværkskort %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7071,15 +7634,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Location</source>
- <translation>Placering</translation>
+ <translation type="obsolete">Placering</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Type (Format)</translation>
+ <translation type="obsolete">Type (Format)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Monteret på</translation>
+ <translation type="obsolete">Monteret på</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -7161,17 +7724,17 @@ p, li { white-space: pre-wrap; }
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Monteret på</translation>
+ <translation type="obsolete">Monteret på</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Monteret på</translation>
+ <translation type="obsolete">Monteret på</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Monteret på</translation>
+ <translation type="obsolete">Monteret på</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -7189,6 +7752,46 @@ p, li { white-space: pre-wrap; }
<source>All %1 images (%2)</source>
<translation>Alle %1 aftryk (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Type:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Placering:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -7213,7 +7816,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Netværkskort</translation>
+ <translation type="obsolete">Netværkskort</translation>
</message>
</context>
<context>
@@ -7887,7 +8490,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Kan ikke tilgå USB på værtssystemet, da hverken USB filsystemet (usbfs) eller DBus/HAL-tjenester er tilgængelige. Hvis du vil bruge USB-enheder fra værten i dine virtuelle maskiner skal du først løse problemet og så genstarte VirtualBox.</translation>
+ <translation type="obsolete">Kan ikke tilgå USB på værtssystemet, da hverken USB filsystemet (usbfs) eller DBus/HAL-tjenester er tilgængelige. Hvis du vil bruge USB-enheder fra værten i dine virtuelle maskiner skal du først løse problemet og så genstarte VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -8005,7 +8608,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Er du sikker på at du vil genindlæse øjebliksbilledet &lt;b&gt;%1&lt;/b&gt;? Gør du det, kan du ikke længere genskabe maskinens nuværende tilstand.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Er du sikker på at du vil genindlæse øjebliksbilledet &lt;b&gt;%1&lt;/b&gt;? Gør du det, kan du ikke længere genskabe maskinens nuværende tilstand.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -8305,7 +8908,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Sorry, some generic error happens.</source>
<translatorcomment>Huh?</translatorcomment>
- <translation type="obsolete">Beklager, der skete en fejl.</translation>
+ <translation type="unfinished">Beklager, der skete en fejl.</translation>
</message>
<message>
<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>
@@ -8394,7 +8997,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>Sletning af samtlige filer, der tilhører VM&apos;en er pt deaktiveret på Windows/x64 for at forhindre nedbrud. Problemet vil blive løst i næste version.</translation>
+ <translation type="obsolete">Sletning af samtlige filer, der tilhører VM&apos;en er pt deaktiveret på Windows/x64 for at forhindre nedbrud. Problemet vil blive løst i næste version.</translation>
</message>
<message>
<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>
@@ -8402,7 +9005,71 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>&lt;p&gt;USB 2.0 er pt aktiveret i denne virtuelle maskine. Dette kræver at &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; installeres.&lt;/p&gt;&lt;p&gt;Denne kan hentes fra VirtualBox&apos; hjemmeside. Derefter kan du reaktivere USB 2.0. USB 2.0 vil blive deaktiveret, medmindre du annullerer de nuværende ændringer.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;USB 2.0 er pt aktiveret i denne virtuelle maskine. Dette kræver at &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; installeres.&lt;/p&gt;&lt;p&gt;Denne kan hentes fra VirtualBox&apos; hjemmeside. Derefter kan du reaktivere USB 2.0. USB 2.0 vil blive deaktiveret, medmindre du annullerer de nuværende ændringer.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -8492,7 +9159,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Delte mapper</translation>
+ <translation type="obsolete">Delte mapper</translation>
</message>
</context>
<context>
@@ -8563,7 +9230,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Drop</translation>
+ <translation type="obsolete">Drop</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -8765,6 +9432,22 @@ p, li { white-space: pre-wrap; }
<source>Show Statusbar</source>
<translation>Vis statusbar</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -8992,6 +9675,14 @@ p, li { white-space: pre-wrap; }
<source> (%1 ago)</source>
<translation> (%1 siden)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_de.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_de.ts
index 84b806439..4f23ff538 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_de.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_de.ts
@@ -337,7 +337,7 @@
</message>
<message>
<source>Dock Icon</source>
- <translation></translation>
+ <translation>Dock-Icon</translation>
</message>
<message>
<source>Show Monitor Preview</source>
@@ -385,13 +385,94 @@
<translation>Automatische Anpassung der &amp;Gastanzeige</translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
- <translation>Session-&amp;Informationen</translation>
- </message>
- <message>
<source>Enable R&amp;emote Display</source>
<translation>&amp;Fernsteuerung aktivieren</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation>Änd&amp;ern...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation>Einstellungen der virtuellen Maschine ändern</translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation>Session-I&amp;nformationen...</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation>Virtuelle Maschine klonen</translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation>Klonen</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Dieser Assistent hilft Ihnen bei der Erstellung eines Klones (einer exakten Kopie) einer virtuellen Maschine.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Bitte wählen Sie einen Namen für die neue virtuelle Maschine:&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation>Klone-Assistent</translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation>%1-Klon</translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>Falls ausgewählt, wird allen aktivierten Netzwerkkarten eine neue MAC-Adresse zugewiesen.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>&amp;Zuweisen neuer MAC-Adressen für alle Netzwerkkarten</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation>Aktueller Zustand</translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation>Aktueller und alle nachfolgenden Zustände</translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation>Alle Zustände</translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation>Auswahl der Zustände</translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation>Bitte wählen Sie, welche Zustände der virtuellen Maschine geklont werden sollen.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation>Falls Sie &lt;b&gt;Aktueller Zustand&lt;/b&gt; wählen, wird nur der aktuelle Zustand der virtuellen Maschine geklont.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation>Falls Sie &lt;b&gt;Aktueller und alle nachfolgenden Zustände&lt;/b&gt; auswählen, werden der aktuelle Zustand und alle Zustände, die in nachfolgenden Sicherheitspunkten gespeichert sind, kopiert.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation>Falls Sie &lt;b&gt;Alle Zustände&lt;/b&gt; wählen, werden wirklich alle Zustände geklont.</translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -540,11 +621,6 @@
<translation>Host-only Adapter, &apos;%1&apos;</translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation>VDE-Netzwerk, &apos;%1&apos;</translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation>Adapter %1</translation>
@@ -683,6 +759,26 @@
<comment>details report (VRDE Server)</comment>
<translation>deaktiviert</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation>&amp;CPU-Begrenzung</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>Generischer Treiber, &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation>Generischer Treiber, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -719,6 +815,10 @@
<source>Restore Defaults</source>
<translation>Standardeinstellungen</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation>Exportieren</translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -854,6 +954,10 @@
<source>First Run Wizard</source>
<translation>Startassistent</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation>Starten</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -927,41 +1031,6 @@
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Allgemein</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Eingabe</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Update</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Sprache</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Netzwerk</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Zusatzpakete</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation></translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1360,6 +1429,57 @@
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation>Durch Aktivieren dieser Einstellung benutzt VirtualBox einen HTTP-Proxy für Aufgaben wie beispielsweise den Test auf neue VirtualBox-Versionen oder das Herunterladen der Gasterweiterungen.</translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation>Proxy &amp;aktivieren</translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation>Ho&amp;st:</translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation>Ändert den Proxy-Host.</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation>Ändert den Proxy-Port.</translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation>Durch Aktivierung dieser Einstellung wird Proxy-Authentifierzierung verwendet.</translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation>&amp;Benutze Authentisierung</translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation>Benutzer&amp;name:</translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation>Ändert den Benutzernamen für die Authentisierung.</translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation>&amp;Passwort:</translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation>Ändert das Passwort für die Authentisierung.</translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1432,26 +1552,6 @@
<translation>Rechts</translation>
</message>
<message>
- <source>Left Shift</source>
- <translation>Umsch Links</translation>
- </message>
- <message>
- <source>Right Shift</source>
- <translation>Umsch Rechts</translation>
- </message>
- <message>
- <source>Left Ctrl</source>
- <translation>Strg Links</translation>
- </message>
- <message>
- <source>Right Ctrl</source>
- <translation>Strg Rechts</translation>
- </message>
- <message>
- <source>Left Alt</source>
- <translation>Alt Links</translation>
- </message>
- <message>
<source>Right Alt</source>
<translation>Alt Rechts</translation>
</message>
@@ -1481,7 +1581,27 @@
</message>
<message>
<source>None</source>
- <translation>keine</translation>
+ <translation>Keine</translation>
+ </message>
+ <message>
+ <source>Left Shift</source>
+ <translation type="obsolete">Shift Links</translation>
+ </message>
+ <message>
+ <source>Right Shift</source>
+ <translation type="obsolete">Shift Rechts</translation>
+ </message>
+ <message>
+ <source>Left Ctrl</source>
+ <translation type="obsolete">Strg Links</translation>
+ </message>
+ <message>
+ <source>Right Ctrl</source>
+ <translation type="obsolete">Strg Rechts</translation>
+ </message>
+ <message>
+ <source>Left Alt</source>
+ <translation type="obsolete">Alt Links</translation>
</message>
</context>
<context>
@@ -1494,6 +1614,10 @@
<source>Restore Defaults</source>
<translation>Standardeinstellungen</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation>Importieren</translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -1628,11 +1752,6 @@
<translation>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;Keine gemeinsamen Ordner&lt;/b&gt;&lt;/nobr&gt;</translation>
</message>
<message>
- <source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
- <comment>Virtualization Stuff LED</comment>
- <translation>Zeigt an, ob diese virtuelle Maschine Hardware-Virtualisierung benutzt:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
- </message>
- <message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</translation>
@@ -1653,6 +1772,11 @@
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;Der Server für die Fernsteuerung lauscht an Port %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation>Zeigt an, ob diese virtuelle Maschine Hardware-Virtualisierung benutzt:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -1827,8 +1951,12 @@
<translation>&amp;Gleichzeitige Verbindungen erlauben</translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Sie haben die 3D-Unterstützung für ein Betriebssystem aktiviert, welches den WDDM-Videotreiber benutzt. Setzen Sie die Größe des Grafikspeichers auf mindestens &lt;b&gt;%1&lt;/b&gt; um eine optimale Performance zu erreichen.</translation>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>haben Sie die 3D-Unterstützung für ein Betriebssystem aktiviert, welches den WDDM-Videotreiber benutzt. Setzen Sie die Größe des Grafikspeichers auf mindestens &lt;b&gt;%1&lt;/b&gt; um eine optimale Performance zu erreichen.</translation>
+ </message>
+ <message>
+ <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>
</context>
<context>
@@ -1905,6 +2033,10 @@
<source>If checked, show the Mini ToolBar at the top of the screen, rather than in its default position at the bottom of the screen.</source>
<translation>Zeigt die Mini-Toolbar am oberen Rand des Bildschirms wenn ausgewählt, sonst am unteren Rand.</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation>haben Sie ein 64-Bit-Gastbestriebssystem ausgewählt. Da solche Gäste Hardwarevirtualisierung benötigen (VT-x/AMD-V), wird diese VM-Einstellung automatisch aktiviert.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -1918,7 +2050,7 @@
</message>
<message>
<source>no host-only network adapter is selected</source>
- <translation></translation>
+ <translation>haben Sie keinen Host-Only-Netzwerkadapter ausgewählt</translation>
</message>
<message>
<source>Not selected</source>
@@ -1950,10 +2082,6 @@
<translation>&amp;Name:</translation>
</message>
<message>
- <source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Wählt den Namen des Netzwerkadapters für eine &lt;b&gt;Netzwerkbrücke&lt;/b&gt; oder für einen &lt;b&gt;Host-Only-Adapter&lt;/b&gt; bzw. den Namen eines internen Netzwerkes, falls die Einstellung &lt;b&gt;Internes Netzwerk&lt;/b&gt; gewählt wurde.</translation>
- </message>
- <message>
<source>Adapter &amp;Type:</source>
<translation>Adapter&amp;typ:</translation>
</message>
@@ -1993,6 +2121,42 @@
<source>&amp;Port Forwarding</source>
<translation>&amp;Port-Weiterleitung</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation>&amp;Promiscuous-Modus:</translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation>Legt fest, wie der promiscuous-Modus des Netzwerkadapters behandelt werden soll, wenn dieser an ein internes Netzwerk, an ein Host-Only-Netzwerk oder an eine Brücke angeschlossen ist.</translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation>Konfiguration:</translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation>Geben Sie hier Konfigurationseinstellungen für den generischen Treiber an. Diese Einstellungen müssen in der Form &lt;b&gt;Name=Wert&lt;/b&gt; angegeben werden. Die möglichen Einstellungen richten sich nach dem Treiber. Benutzen Sie &lt;b&gt;Shift-Enter&lt;/b&gt;, um einen neuen Eintrag hinzuzufügen.</translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation>haben Sie keinen generischen Treiber ausgewählt</translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation>Bezeichnet den Netzwerkadapter auf dem Host, mit dem diese virtuelle Netzwerkkarte verbunden ist.</translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation>Spezifizieren Sie den Namen des internen Netzwerkes, an den die Netzwerkkarte angeschlossen werden soll. Sie können ein neues internes Netzwerk durch Angabe eines Namens erzeugen, der von keiner anderen Netzwerkkarte dieser oder anderer virtueller Maschinen benutzt wird.</translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation>Bezeichnet den virtuellen Netzwerkadapter auf dem Host, mit dem diese Netzwerkkarte verbunden ist. Host-only-Adapter können in den globalen Netzwerk-Einstellungen hinzugefügt und entfernt werden.</translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation>Wählt den Treiber für die Netzwerkkarte aus.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsParallel</name>
@@ -2312,10 +2476,6 @@
<translation>&lt;nobr&gt;Diskettenlaufwerk hinzufügen&lt;/nobr&gt;</translation>
</message>
<message>
- <source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Keine Festplatte für &lt;i&gt;%1&lt;/i&gt; ausgewählt.</translation>
- </message>
- <message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
<translation>&lt;i&gt;%1&lt;/i&gt; benutzt ein Medium, das bereits an &lt;i&gt;%2&lt;/i&gt; angeschlossen ist.</translation>
</message>
@@ -2409,7 +2569,7 @@
</message>
<message>
<source>Information</source>
- <translation>Information</translation>
+ <translation>Informationen</translation>
</message>
<message>
<source>The Storage Tree can contain several controllers of different types. This machine currently has no controllers.</source>
@@ -2449,11 +2609,11 @@
</message>
<message>
<source>Virtual Size:</source>
- <translation>Virtuelle Größe:</translation>
+ <translation>virtuelle Größe:</translation>
</message>
<message>
<source>Actual Size:</source>
- <translation>Wirkliche Größe:</translation>
+ <translation>tatsächliche Größe:</translation>
</message>
<message>
<source>Size:</source>
@@ -2461,7 +2621,7 @@
</message>
<message>
<source>Location:</source>
- <translation>Ort:</translation>
+ <translation>abgespeichert wo:</translation>
</message>
<message>
<source>Type (Format):</source>
@@ -2469,7 +2629,7 @@
</message>
<message>
<source>Attached To:</source>
- <translation>Angeschlossen an:</translation>
+ <translation>angeschlossen an:</translation>
</message>
<message>
<source>Add SAS Controller</source>
@@ -2551,6 +2711,60 @@
<source>Choose a virtual floppy disk file...</source>
<translation>Datei für virtuelle Diskette auswählen...</translation>
</message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>haben Sie keinen Namen für den Controller auf der Position &lt;b&gt;%1&lt;/b&gt; angegeben.</translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation>ist für den Controller auf der Position &lt;b&gt;%1&lt;/b&gt; ein Name angegeben, der bereits von dem Controller an Position &lt;b&gt;%2&lt;/b&gt; benutzt wird.</translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation>haben Sie keine Platte für &lt;i&gt;%1&lt;/i&gt; ausgewählt.</translation>
+ </message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation>Unterdrückt das Auswerfen des Mediums durch den Gast.</translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation>&amp;Live-CD/DVD</translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation>Markiert das Medium als nicht rotierbaren Speicher (SSD).</translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation>&amp;SSD-Laufwerk</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation>höchstens einer unterstützt</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation>bis zu %1 unterstützt</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation>werden momentan mehr Controller benutzt als ein %1-Chipsatz unterstützt. Bitte ändern Sie den Typ des Chipsatzes auf der Seite Systemeinstellungen oder entfernen Sie Controller aus der folgenden Liste: %2.</translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation>abgespeichert wie:</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation>&amp;Anzahl Ports:</translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation>Setzt die Anzahl der Anschlüsse des SATA-Controllers. Dieser Wert kann nicht kleiner sein als der letzte benutzte Port plus 1.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -2724,6 +2938,32 @@
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>haben Sie die ICH9-Chipsatzemulation für diese VM gewählt. Diese Emulation setzt einen aktivierten IO-APIC voraus. Diese Änderung wird automatisch vorgenommen, falls Sie die Einstellungen akzeptieren.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation>&amp;CPU-Begrenzung:</translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation>Begrenzt die jeder virtuellen CPU zur Verfügung stehenden Zeit. Jede virtuelle CPU darf nicht länger als dieser Prozentsatz der verfügbaren Zeit auf einer physischen CPU laufen. Durch Setzen dieses Wertes auf 100% wird diese Begrenzung aufgehoben. Wird dieser Wert zu tief gewählt, kann sich dies negativ auf das Zeitverhalten der VM auswirken.</translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation>haben Sie die CPU-Ausführungsbegrenzung auf einen sehr niedrigen Wert gesetzt. Dadurch wird die virtuelle Maschine wahrscheinlich spürebar schlechter reagieren.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation>haben Sie ein USB HID (Human Interface Device) aktiviert. Dieses benötigt die USB-Emulation. Wenn Sie die Einstellungen bestätigen, wird die USB-Emulation für diese VM aktiviert.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -2849,8 +3089,8 @@
<translation>&lt;nobr&gt;Zustand: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <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>wurde die USB-2.0-Unterstützung aktiviert. Dies erfordert allerdings die Installation des &lt;b&gt;%1&lt;/b&gt;. Sie finden dieses Zusatzpaket auf der offiziellen Webseite von VirtualBox. Ohne dieses Paket wird diese Einstellung deaktiviert, sobald Sie die Einstellungen der VM abspeichern.</translation>
+ <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>Für diese virtuelle Maschine ist USB-2.0-Unterstützung aktiviert. Dafür wird aber das &lt;b&gt;%1&lt;/b&gt; benötigt. Bitte installieren Sie das Zusatzpaket von der VirtualBox-Webseite. Danach können Sie USB-2.0 wieder aktivieren. In der Zwischenzeit wird diese Einstellung deaktiviert, wenn Sie die Einstellungen bestätigen.</translation>
</message>
</context>
<context>
@@ -2963,6 +3203,21 @@
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation>Mediumattribute ändern</translation>
+ </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;Sie möchten die Attribute der virtuellen Festplatte &lt;b&gt;%1&lt;/b&gt; ändern.&lt;/p&gt;&lt;p&gt;Bitte wählen Sie einen der folgenden Medientypen und bestätigen dann mit &lt;b&gt;%2&lt;/b&gt; um fortzufahren oder verwerfen die Änderung mit &lt;b&gt;%3&lt;/b&gt;.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation>Mediumtyp ändern:</translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3008,104 +3263,125 @@
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation>%1_Kopie</translation>
+ </message>
<message>
<source>Create New Virtual Disk</source>
<translation>Neue virtuelle Festplatte erstellen</translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage1</name>
<message>
- <source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Erstellen einer virtuellen Festplatte</translation>
+ <source>Copy Virtual Disk</source>
+ <translation>Virtuelle Festplatte kopieren</translation>
</message>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Dieser Assistent wird Ihnen helfen, eine neue virtuelle Festplatte für Ihre virtuelle Maschine zu erstellen.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation>Virtuelle Platte kopieren</translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage2</name>
<message>
- <source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Wählen Sie den Typ der virtuellen Festplatte.&lt;/p&gt;&lt;p&gt;Ein &lt;b&gt;dynamisch expandierendes Medium&lt;/b&gt; belegt bei der Erzeugung nur sehr wenig Platz auf der physischen Festplatte. Es wächst in dem Maße dynamisch (bis zur vorher festgelegten Größe), wie das Gastsystem Blöcke auf der virtuellen Platte beschreibt.&lt;/p&gt;&lt;p&gt;Ein &lt;b&gt;Medium fester Größe&lt;/b&gt; wächst nicht zur Laufzeit, sondern wird sofort mit der endgültigen Größe erzeugt. Das Erstellen eines Mediums fester Größe kann in Abhängigkeit von der Größe und der Schreibrate der Festplatte sehr lange (Minuten) dauern.&lt;/p&gt;</translation>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation></translation>
</message>
<message>
- <source>Storage Type</source>
- <translation>Datenspeichertyp</translation>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation></translation>
</message>
<message>
- <source>&amp;Dynamically expanding storage</source>
- <translation>&amp;Dynamisch wachsendes Medium</translation>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation></translation>
</message>
<message>
- <source>&amp;Fixed-size storage</source>
- <translation>Medium &amp;fester Größe</translation>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation>Erstellen einer virtuellen Festplatte</translation>
</message>
<message>
- <source>Hard Disk Storage Type</source>
- <translation>Typ der Festplatte</translation>
+ <source>Virtual disk file type</source>
+ <translation>Dateityp der virtuellen Platte</translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage3</name>
<message>
- <source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Klicken Sie auf &lt;b&gt;Auswählen&lt;/b&gt;, um den Speicherort der Daten auf der Festplatte auszuwählen oder tippen Sie den Namen in das Eingabefeld.&lt;/p&gt;</translation>
+ <source>Virtual disk storage details</source>
+ <translation>Art der virtuellen Platte</translation>
</message>
<message>
- <source>&amp;Location</source>
- <translation>&amp;Ort</translation>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Eine &lt;b&gt;dynamisch allozierte&lt;/b&gt; Datei einer virtuellen Platte belegt nur dann Platz auf der physischen Platte des Hosts, wenn der Gast Daten schreibt. Einmal belegter Platz wird nicht automatisch freigegeben.&lt;/p&gt;</translation>
</message>
<message>
- <source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Wählen Sie die Größe der virtuellen Festplatte in Megabyte. Diese Größe wird dem Gastsystem als Größe der virtuellen Festplatte übermittelt.&lt;/p&gt;</translation>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Das Erzeugen einer Datei &lt;b&gt;fester Größe&lt;/b&gt; dauert auf manchen Systemen länger aber bietet eine etwas bessere Performance.&lt;/p&gt;</translation>
</message>
<message>
- <source>&amp;Size</source>
- <translation>&amp;Größe</translation>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation>&lt;p&gt;Die virtuelle Platte kann ebenfalls auf mehrere Dateien mit einer maximalen Größe von 2 GB aufgeteilt werden. Dies ist sinnvoll, wenn die virtuelle Maschine auf einem USB-Gerät oder auf älteren Systemen gespeichert werden soll, die keine größeren Dateien unterstützen.</translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation>&amp;dynamisch alloziert</translation>
</message>
<message>
- <source>Virtual Disk Location and Size</source>
+ <source>&amp;Fixed size</source>
+ <translation>&amp;feste Größe</translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation>&amp;Aufteilen in Dateien mit weniger als 2GB</translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
<translation>Lage und Größe der virtuellen Festplatte</translation>
</message>
<message>
- <source>Select a file for the new hard disk image file</source>
- <translation>Wählen Sie eine Datei für ein neues Plattenabbild aus</translation>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation>Legt die Größe der virtuellen Platte in Megabyte fest. Diese Größenangabe wird an den Gast als die Größe der virtuellen Platte übermittelt.</translation>
</message>
<message>
- <source>Hard disk images (*.vdi)</source>
- <translation>Plattenabbilder (*.vdi)</translation>
+ <source>Virtual disk file location</source>
+ <translation>Ort der virtuellen Datei</translation>
</message>
<message>
- <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation></translation>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation>Wählen Sie &lt;b&gt;Auswählen&lt;/b&gt; um den Ort der Datei festzulegen oder bestimmen Sie direkt einen Dateinamen.</translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage4</name>
<message>
- <source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Sie möchten eine neue virtuelle Festplatte mit den folgenden Parametern erstellen:</translation>
+ <source>Select a file for the new hard disk image file</source>
+ <translation>Wählen Sie eine Datei für ein neues Plattenabbild aus</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation></translation>
</message>
<message>
<source>Summary</source>
<translation>Zusammenfassung</translation>
</message>
<message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation>Es wird eine neue virtuelle Platte mit den folgenden Parametern erstellt:</translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation>Es wird eine Kopie der virtuellen Festplatte mit den folgenden Parametern erstellt:</translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation>Falls diese Einstellungen richtig sind, betätigen Sie bitte &lt;b&gt;%1&lt;/b&gt;. Dann wird die neue virtuelle Festplatte erzeugt.</translation>
+ </message>
+ <message>
<source>%1 B</source>
<translation></translation>
</message>
<message>
- <source>Type</source>
+ <source>File type</source>
<comment>summary</comment>
- <translation>Typ</translation>
+ <translation>Dateityp</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Ort</translation>
+ <translation>abgespeichert wo</translation>
</message>
<message>
<source>Size</source>
@@ -3113,8 +3389,77 @@
<translation>Größe</translation>
</message>
<message>
- <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Klicken Sie auf &lt;b&gt;%1&lt;/b&gt;, wenn alle oben angegebenen Einstellungen richtig sind. Damit wird eine neue virtuelle Festplatte erstellt.</translation>
+ <source>Create</source>
+ <translation>Erzeugen</translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation>Kopieren</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Dieser Assistent unterstützt Sie bei der Erzeugung einer Kopie einer virtuellen Platte.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation>Bitte wählen Sie eine virtuelle Festplatte zum Kopieren aus. Diese können Sie entweder aus der Liste oder mit Hilfe des Icons neben der Liste mittels Dateidialog auswählen.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Dieser Assistent unterstützt Sie bei der Erzeugung einer neuen virtuellen Festplatte.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Bitte wählen Sie den Typ der neuen virtuelle Festplatte. Falls Sie diese nicht mit anderer Virtualisierungssoftware verwenden, können Sie diese Einstellung unverändert lassen.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation>Bitte wählen Sie den Dateityp für die neue virtuelle Festplatte. Falls Sie diese nicht mit andere Virtualisierungssoftware verwenden, können Sie diese Einstellung unverändert lassen.</translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation>Bitte wählen Sie, ob die neue virtuelle Festplatte erst nach und nach zur Laufzeit alloziert werden soll oder ob die Platte jetzt sofort vollständig alloziert werden soll.</translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation>abgespeichert wie</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation>Dateityp</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation>&amp;Ort</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation>&amp;Größe</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation>Art der Abspeicherung</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation>Zu kopierende Festplatte</translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation>Datei für virtuelle Festplatte auswählen...</translation>
</message>
</context>
<context>
@@ -3123,6 +3468,10 @@
<source>Create New Virtual Machine</source>
<translation>Neue virtuelle Maschine erstellen</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation>Erzeugen</translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -3330,6 +3679,96 @@
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Allgemein</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Eingabe</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Update</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Sprache</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Netzwerk</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Zusatzpakete</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation>Proxy</translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Allgemein</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>System</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Anzeige</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Massenspeicher</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Audio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Netzwerk</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Ports</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Serielle Schnittstellen</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Parallel-Ports</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Gemeinsame Ordner</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -3436,81 +3875,6 @@
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Allgemein</translation>
- </message>
- <message>
- <source>System</source>
- <translation>System</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Anzeige</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Massenspeicher</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Audio</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Netzwerk</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Ports</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Serielle Schnittstellen</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Parallel-Ports</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Gemeinsame Ordner</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation></translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>haben Sie ein 64-Bit-Gastbestriebssystem ausgewählt. Da solche Gäste Hardwarevirtualisierung benötigen (VT-x/AMD-V), wird diese VM-Einstellung automatisch aktiviert.</translation>
- </message>
- <message>
- <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 have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>haben Sie ein USB HID (Human Interface Device) aktiviert. Dieses benötigt die USB-Emulation. Wenn Sie die Einstellungen bestätigen, wird die USB-Emulation für diese VM aktiviert.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>höchstens einer unterstützt</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>bis zu %1 unterstützt</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>werden momentan mehr Controller benutzt als ein %1-Chipsatz unterstützt. Bitte ändern Sie den Typ des Chipsatzes auf der Seite Systemeinstellungen oder entfernen Sie Controller aus der folgenden Liste: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -3597,7 +3961,7 @@
</message>
<message>
<source>Network Adapter</source>
- <translation>Netzwerk-Adapter</translation>
+ <translation>Netzwerkadapter</translation>
</message>
<message>
<source>USB Controller</source>
@@ -3631,6 +3995,14 @@
<source>Hard Disk Controller (SAS)</source>
<translation>Festplatten-Controller SAS</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>Falls ausgewählt, wird allen aktivierten Netzwerkkarten eine neue MAC-Adresse zugewiesen.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>&amp;Zuweisen neuer MAC-Adressen für alle Netzwerkkarten</translation>
+ </message>
</context>
<context>
<name>VBoxEmptyFileSelector</name>
@@ -4287,11 +4659,6 @@
<translation>&lt;nobr&gt;Zustand: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <source>Adapter %1</source>
- <comment>network</comment>
- <translation>Adapter %1</translation>
- </message>
- <message>
<source>Checking...</source>
<comment>medium</comment>
<translation>Überprüfen...</translation>
@@ -4599,6 +4966,48 @@
<comment>medium</comment>
<translation>Diese Basisfestplatte ist indirekt über die folgenden Differenzfestplatten eingebunden:</translation>
</message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation>
+ <numerusform>%n Jahr</numerusform>
+ <numerusform>%n Jahre</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n month(s)</source>
+ <translation>
+ <numerusform>%n Monat</numerusform>
+ <numerusform>%n Monate</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation>
+ <numerusform>%n Tag</numerusform>
+ <numerusform>%n Tage</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation>
+ <numerusform>%n Stunde</numerusform>
+ <numerusform>%n Stunden</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n minute(s)</source>
+ <translation>
+ <numerusform>%n Minute</numerusform>
+ <numerusform>%n Minuten</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n second(s)</source>
+ <translation>
+ <numerusform>%n Sekunde</numerusform>
+ <numerusform>%n Sekunden</numerusform>
+ </translation>
+ </message>
<message>
<source>(CD/DVD)</source>
<translation>(CD/DVD)</translation>
@@ -4609,21 +5018,11 @@
<translation>Bildschirme</translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation>VDE-Netzwerk, &apos;%1&apos;</translation>
- </message>
- <message>
<source>SAS</source>
<comment>StorageBus</comment>
<translation>SAS</translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation></translation>
@@ -4798,47 +5197,60 @@
<source>and</source>
<translation>und</translation>
</message>
- <message numerus="yes">
- <source>%n year(s)</source>
- <translation>
- <numerusform>%n Jahr</numerusform>
- <numerusform>%n Jahre</numerusform>
- </translation>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>verweigern (deny)</translation>
</message>
- <message numerus="yes">
- <source>%n month(s)</source>
- <translation>
- <numerusform>%n Monat</numerusform>
- <numerusform>%n Monate</numerusform>
- </translation>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>erlauben für alle VMs</translation>
</message>
- <message numerus="yes">
- <source>%n day(s)</source>
- <translation>
- <numerusform>%n Tag</numerusform>
- <numerusform>%n Tage</numerusform>
- </translation>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>erlauben für allen VMs und den Host</translation>
</message>
- <message numerus="yes">
- <source>%n hour(s)</source>
- <translation>
- <numerusform>%n Stunde</numerusform>
- <numerusform>%n Stunden</numerusform>
- </translation>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation>dynamisch belegt</translation>
</message>
- <message numerus="yes">
- <source>%n minute(s)</source>
- <translation>
- <numerusform>%n Minute</numerusform>
- <numerusform>%n Minuten</numerusform>
- </translation>
+ <message>
+ <source>Fixed size storage</source>
+ <translation>feste Größe</translation>
</message>
- <message numerus="yes">
- <source>%n second(s)</source>
- <translation>
- <numerusform>%n Sekunde</numerusform>
- <numerusform>%n Sekunden</numerusform>
- </translation>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation>dynamisch belegt mit Dateien kleiner als 2GB</translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation>Dateien mit fester Größe kleiner als 2GB</translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation>CPU-Bremse</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>Generisch, &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation>Generischer Treiber</translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation>Adapter %1</translation>
</message>
</context>
<context>
@@ -4871,7 +5283,7 @@
<name>VBoxLicenseViewer</name>
<message>
<source>VirtualBox License</source>
- <translation></translation>
+ <translation>VirtualBox-Lizenz</translation>
</message>
<message>
<source>I &amp;Agree</source>
@@ -4972,25 +5384,13 @@
</message>
<message>
<source>Release the selected medium by detaching it from the machines</source>
- <translation>Hebt die Verbindung des ausgewählten Medium an alle virtuellen Maschinen auf</translation>
+ <translation>Löst die Bindung des ausgewählten Medium an alle virtuellen Maschinen</translation>
</message>
<message>
<source>Refresh the media list</source>
<translation>Aktualisiert die Medienliste</translation>
</message>
<message>
- <source>Location</source>
- <translation>Ort</translation>
- </message>
- <message>
- <source>Type (Format)</source>
- <translation>Type (Format)</translation>
- </message>
- <message>
- <source>Attached to</source>
- <translation>angeschlossen an</translation>
- </message>
- <message>
<source>Checking accessibility</source>
<translation>Überprüfe Zugriffsrecht</translation>
</message>
@@ -5056,21 +5456,6 @@
<translation>&amp;Diskettenabbilder</translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: Virtual Disk</comment>
- <translation>angeschlossen an</translation>
- </message>
- <message>
- <source>Attached to</source>
- <comment>VMM: CD/DVD Image</comment>
- <translation>angeschlossen an</translation>
- </message>
- <message>
- <source>Attached to</source>
- <comment>VMM: Floppy Image</comment>
- <translation>angeschlossen an</translation>
- </message>
- <message>
<source>CD/DVD-ROM disk</source>
<translation>CD/DVD-ROM</translation>
</message>
@@ -5086,6 +5471,46 @@
<source>All %1 images (%2)</source>
<translation>Alle %1-Abbilder (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation>Typ:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation>Ort:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation>Format:</translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation>Art der Abspeicherung:</translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation>Angeschlossen an:</translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation>&amp;Kopieren...</translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation>Erstellt eine Kopie des Medium</translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation>&amp;Ändern...</translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation>Ändert die Attribute des ausgewählten Mediums</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Schließen</translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -5107,13 +5532,6 @@
</message>
</context>
<context>
- <name>VBoxNetworkDialog</name>
- <message>
- <source>Network Adapters</source>
- <translation>Netzwerkadapter</translation>
- </message>
-</context>
-<context>
<name>VBoxOSTypeSelectorWidget</name>
<message>
<source>Operating &amp;System:</source>
@@ -5258,7 +5676,7 @@
</message>
<message>
<source>&lt;p&gt;Deleting this host-only network will remove the host-only interface this network is based on. Do you want to remove the (host-only network) interface &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;?&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; this interface may be in use by one or more virtual network adapters belonging to one of your VMs. After it is removed, these adapters will no longer be usable until you correct their settings by either choosing a different interface name or a different adapter attachment type.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Möchten Sie wirklich dieses Host-only Netzinterface &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt; löschen?&lt;/p&gt;&lt;p&gt;&lt;b&gt;Beachten Sie:&lt;/b&gt; Dieses Interface wird möglicherweise von mehreren virtuellen Netzadaptern benutzt. Nach dem Löschen sind diese Adapter nicht mehr benutzbar bis Sie die Einstellungen dieser virtuellen Maschinen angepasst haben.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Möchten Sie wirklich dieses Host-only Netzinterface &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt; löschen?&lt;/p&gt;&lt;p&gt;&lt;b&gt;Beachten Sie:&lt;/b&gt; Dieses Interface wird möglicherweise von mehreren virtuellen Netzwerkadaptern benutzt. Nach dem Löschen sind diese Adapter nicht mehr benutzbar bis Sie die Einstellungen dieser virtuellen Maschinen angepasst haben.&lt;/p&gt;</translation>
</message>
<message>
<source>Failed to remove the host network interface &lt;b&gt;%1&lt;/b&gt;.</source>
@@ -5642,10 +6060,6 @@
<translation>&lt;p&gt;Ein schwerwiegender Fehler ist aufgetreten, und die Ausführung der virtuellen Maschine wurde unterbrochen.&lt;/p&gt;&lt;p&gt;Zusätzliche Informationen zu diesem Fehler suchen Sie bitte in der Community-Sektion auf &lt;a href=http://www.virtualbox.org&gt;http://www.virtualbox.org&lt;/a&gt; bzw. handeln Sie gemäß Ihres Supportvertrages. Bitte geben Sie die Logdatei &lt;tt&gt;VBox.log&lt;/tt&gt;, den Screenshot &lt;tt&gt;VBox.png&lt;/tt&gt;, den Sie im Verzeichnis &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt; finden können, sowie eine Beschreibung der Maßnahmen, die zu diesem Fehler führten, weiter. Sie können diese Dateien auch durch Auswahl von &lt;b&gt;Zeige Log...&lt;/b&gt; im Menü &lt;b&gt;Maschine&lt;/b&gt; des Hauptfensters finden.&lt;/p&gt;&lt;p&gt;Wählen Sie &lt;b&gt;OK&lt;/b&gt;, wenn Sie die virtuelle Maschine ausschalten wollen. Wählen Sie &lt;b&gt;Ignorieren&lt;/b&gt;, wenn Sie diese für Debugging offen lassen wollen. Zum Debuggen sind spezielle Kenntnisse und Tools notwendig, so dass die empfohlene Aktion hier &lt;b&gt;OK&lt;/b&gt; ist.&lt;/p&gt;</translation>
</message>
<message>
- <source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation type="obsolete">Der Zugriff auf USB-Geräte des Hosts ist nicht möglich, weil weder das USB-Dateisystem (usbfs) mit den entsprechenden Rechten gemountet ist, noch der DBus / Hal-Service verfügbar ist. Falls Sie USB-Geräte des Hosts innerhalb von Gästen nutzen wollen, müssen Sie dieses Problem beheben und VirtualBox neu starten.</translation>
- </message>
- <message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
<translation>Sie versuchen den Gast mittels ACPI-Signal zu beenden. Dies ist nicht möglich, weil der Gast momentan das ACPI-Subsystem nicht benutzt.</translation>
</message>
@@ -5726,10 +6140,6 @@
<translation>Sie verwenden eine EXPERIMENTELLE Version von VirtualBox. Diese Version ist nicht für den produktiven Einsatz gedacht.</translation>
</message>
<message>
- <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Möchten Sie wirklich zum Sicherungspunkt &lt;b&gt;%1&lt;/b&gt; zurückkehren? Dadurch wird der aktuelle Zustand der virtuellen Maschine unwiderruflich verworfen.&lt;/p&gt;</translation>
- </message>
- <message>
<source>Restore</source>
<translation>Zurückkehren</translation>
</message>
@@ -6057,47 +6467,76 @@
<translation>&amp;Neu installieren</translation>
</message>
<message>
- <source>&lt;p&gt;Cannot create the machine folder:&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Please check you have the permissions required to do so.&lt;/p&gt;</source>
- <translation type="obsolete">&lt;p&gt;Der Ordner für die virtuelle Maschine kann nicht angelegt werden:&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Bitte überprüfen Sie die Zugriffsrechte.&lt;/p&gt;</translation>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Sie möchten zum Sicherungspunkt &lt;b&gt;%1&lt;/b&gt; zurückkehren.&lt;/p&gt;&lt;p&gt;Sie können gleichzeitig durch Auswahl der Checkbox einen Sicherungspunkt für den aktuellen Zustand anlegen, anderenfalls geht der aktuelle Zustand unwiderruflich verloren. Möchten Sie fortfahren?&lt;/p&gt;</translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation type="unfinished"></translation>
+ <source>Create a snapshot of the current machine state</source>
+ <translation>Erzeugt einen Sicherungspunkt der aktuellen virtuellen Maschine</translation>
</message>
<message>
- <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>&lt;p&gt;Für diese VM wurde USB-2.0-Unterstützung aktiviert. Dies erfordert allerdings die Installation des &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Sie finden dieses Zusatzpaket auf der offiziellen Webseite von VirtualBox. Nach der Installation können Sie die USB-2.0-Unterstützung aktivieren. Ohne dieses Paket wird diese Einstellung deaktiviert, sobald Sie die Einstellungen der VM abspeichern.&lt;/p&gt;</translation>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Möchten Sie wirklich zum Sicherungspunkt &lt;b&gt;%1&lt;/b&gt; zurückkehren?&lt;/p&gt;</translation>
</message>
<message>
<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;Das Verzeichnis für die virtuellen Maschinen &lt;b&gt;%1&lt;/b&gt; kann im Verzeichnis &lt;nobr&gt;&lt;b&gt;%2&lt;/nobr&gt; nicht erzeugt werden. &lt;/p&gt;&lt;p&gt;Bitte stellen Sie sicher, dass das übergeordnete Verzeichnis vorhanden und schreibbar ist.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Das Maschinen-Verzeichnis &lt;b&gt;%1&lt;/b&gt; konnte nicht im Verzeichnis &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt; erzeugt werden.&lt;/p&gt;&lt;p&gt;Bitte überprüfen Sie, ob das übergeordnete Verzeichnis vorhanden ist und ob Sie geeignete Zugriffsrechte zum Erzeugen des Maschinen-Verzeichnisses haben.&lt;/p&gt;</translation>
</message>
<message>
<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>Der USB-Proxy-Dienst konnte nicht gestarted werden. Dieser Dienst ist möglicherweise nicht auf diesem Computer installiert</translation>
+ <translation>Der USB-Proxy-Dienst konnte nicht gestarted werden. Dieser Dienst ist möglicherweise nicht auf diesem Computer installiert.</translation>
</message>
<message>
<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>VirtualBox kann nicht auf USB-Geräte zugreifen. Dieses Problem kann dadurch gelöst werden, indem der aktuelle Nutzer Mitglied der Gruppe &apos;vboxusers&apos; wird. In der Dokumentation finden Sie eine genauere Erklärung</translation>
+ <translation>VirtualBox kann nicht auf USB-Geräte zugreifen. Dieses Problem kann dadurch gelöst werden, indem der aktuelle Nutzer Mitglied der Gruppe &apos;vboxusers&apos; wird. In der Dokumentation finden Sie eine genauere Erklärung.</translation>
</message>
<message>
<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>VirtualBox kann nicht auf USB-Geräte zugreifen. Dieses Problem wird gelöst, wenn der aktuelle Nutzer auf die Dateien und Order des USB-Dateisystems (usbfs) zugreifen kann. In der Dokumentation finden Sie eine genauere Erklärung</translation>
+ <translation>VirtualBox kann nicht auf USB-Geräte zugreifen. Dieses Problem wird gelöst, wenn der aktuelle Nutzer auf die Dateien und Order des USB-Dateisystems (usbfs) zugreifen kann. In der Dokumentation finden Sie eine genauere Erklärung.</translation>
</message>
<message>
<source>The USB Proxy Service has not yet been ported to this host</source>
- <translation>Der USB-Proxy-Dienst wurde nicht auf diesen Host portiert</translation>
+ <translation>Der USB-Proxy-Dienst wurde nicht auf diesen Host portiert.</translation>
</message>
<message>
<source>Could not load the Host USB Proxy service</source>
- <translation>Der USB-Proxy-Dienst konnte nicht gestartet werden</translation>
+ <translation>Der USB-Proxy-Dienst konnte nicht gestartet werden.</translation>
</message>
-</context>
-<context>
- <name>VBoxSFDialog</name>
<message>
- <source>Shared Folders</source>
- <translation>Gemeinsame Ordner</translation>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>Die virtuelle Maschine &lt;b&gt;%1&lt;/b&gt; kann nicht registriert werden.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Die Einstellungen der Maschine wurden in der Zwischenzeit verändert und im Dialog wurden ebenfalls Änderungen vorgenommen.&lt;/p&gt;&lt;p&gt;Möchten Sie die Einstellungen neu laden oder möchten Sie die geänderten Einstellungen behalten?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation>Einstellungen neu laden</translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation>Änderungen beibehalten</translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>Die virtuelle Maschine &lt;b&gt;%1&lt;/b&gt; konnte nicht geklont werden.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Der Mediumtyp konnte nicht von &lt;b&gt;%1&lt;/b&gt; nach &lt;b&gt;%2&lt;/b&gt; geändert werden.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation>Ein generischer Fehler ist aufgetreten.</translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation>Der Zustand der virtuellen Maschine hat sich in der Zwischenzeit geändert. Durch Bestätigen werden nur die zur Laufzeit änderbaren Einstellungen abgespeichert. Alle anderen Änderungen gehen verloren.</translation>
+ </message>
+ <message>
+ <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>&lt;p&gt;Für diese virtuelle Maschine ist USB-2.0-Unterstützung aktiviert. Dafür wird aber das &lt;b&gt;%1&lt;/b&gt; benötigt. Bitte installieren Sie das Zusatzpaket von der VirtualBox-Webseite. Danach können Sie USB-2.0 wieder aktivieren. In der Zwischenzeit wird diese Einstellung deaktiviert, wenn Sie die Einstellungen bestätigen.&lt;/p&gt;</translation>
</message>
</context>
<context>
@@ -6151,10 +6590,6 @@
<translation>Einstellungen der ausgewählten virtuellen Maschine ändern</translation>
</message>
<message>
- <source>D&amp;iscard</source>
- <translation>&amp;Verwerfen</translation>
- </message>
- <message>
<source>Discard the saved state of the selected virtual machine</source>
<translation>Verwirft den gesicherten Zustand der ausgewählten virtuellen Maschine</translation>
</message>
@@ -6330,6 +6765,22 @@
<comment>Note: main window title which is pretended by the product name.</comment>
<translation>Manager</translation>
</message>
+ <message>
+ <source>Discard</source>
+ <translation>Verwerfen</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation>&amp;Verwerfen</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>Die ausgewählte virtuelle Maschine klonen</translation>
+ </message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation>&amp;Klonen...</translation>
+ </message>
</context>
<context>
<name>VBoxSnapshotDetailsDlg</name>
@@ -6456,6 +6907,14 @@
<source> (%1 ago)</source>
<translation> (vor %1)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation>&amp;Klonen...</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>Die ausgewählte virtuelle Maschine klonen</translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_el.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_el.ts
index 12f028088..776cefbd0 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_el.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_el.ts
@@ -385,11 +385,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -555,11 +636,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation type="unfinished"></translation>
@@ -683,6 +759,26 @@
<comment>details report</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -719,6 +815,10 @@
<source>Restore Defaults</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -854,6 +954,10 @@
<source>First Run Wizard</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -927,41 +1031,6 @@
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1360,6 +1429,57 @@
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1428,26 +1548,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Left Shift</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Right Shift</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Left Ctrl</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Right Ctrl</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Left Alt</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Right Alt</source>
<translation type="unfinished"></translation>
</message>
@@ -1494,6 +1594,10 @@
<source>Restore Defaults</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -1628,11 +1732,6 @@
<translation></translation>
</message>
<message>
- <source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
- <comment>Virtualization Stuff LED</comment>
- <translation></translation>
- </message>
- <message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation></translation>
@@ -1653,6 +1752,11 @@
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -1827,7 +1931,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1905,6 +2013,10 @@
<source>Show At &amp;Top Of Screen</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -1954,10 +2066,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>A&amp;dvanced</source>
<translation type="unfinished"></translation>
</message>
@@ -1993,6 +2101,42 @@
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsParallel</name>
@@ -2312,10 +2456,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
@@ -2551,6 +2691,60 @@
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -2724,6 +2918,32 @@
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -2849,7 +3069,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -2963,6 +3183,21 @@
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3008,85 +3243,126 @@
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage1</name>
<message>
- <source>Welcome to the Create New Virtual Disk Wizard!</source>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <source>Create</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage2</name>
<message>
- <source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
+ <source>Copy Virtual Disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Storage Type</source>
+ <source>Copy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Dynamically expanding storage</source>
+ <source>Welcome to the virtual disk copying wizard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Fixed-size storage</source>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hard Disk Storage Type</source>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage3</name>
<message>
- <source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Location</source>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Size</source>
+ <source>Welcome to the virtual disk creation wizard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Virtual Disk Location and Size</source>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Select a file for the new hard disk image file</source>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hard disk images (*.vdi)</source>
+ <source>Virtual disk file type</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage4</name>
<message>
- <source>You are going to create a new virtual hard disk with the following parameters:</source>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select a file for the new hard disk image file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3094,11 +3370,28 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>%1 B</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Type</source>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
<comment>summary</comment>
<translation type="unfinished"></translation>
</message>
@@ -3112,8 +3405,40 @@
<comment>summary</comment>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
<message>
- <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -3123,6 +3448,10 @@
<source>Create New Virtual Machine</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -3330,183 +3659,198 @@
</message>
</context>
<context>
- <name>UIVMCloseDialog</name>
+ <name>UISettingsDialogGlobal</name>
<message>
- <source>Close Virtual Machine</source>
+ <source>General</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You want to:</source>
+ <source>Input</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Saves the current execution state of the virtual machine to the physical hard disk of the host PC.&lt;/p&gt;&lt;p&gt;Next time this machine is started, it will be restored from the saved state and continue execution from the same place you saved it at, which will let you continue your work immediately.&lt;/p&gt;&lt;p&gt;Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.&lt;/p&gt;</source>
+ <source>Update</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Save the machine state</source>
+ <source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Sends the ACPI Power Button press event to the virtual machine.&lt;/p&gt;&lt;p&gt;Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.&lt;/p&gt;&lt;p&gt;If the machine doesn&apos;t respond to this action then the guest operating system may be misconfigured or doesn&apos;t understand ACPI Power Button events at all. In this case you should select the &lt;b&gt;Power off the machine&lt;/b&gt; action to stop virtual machine execution.&lt;/p&gt;</source>
+ <source>USB</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>S&amp;end the shutdown signal</source>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Turns off the virtual machine.&lt;/p&gt;&lt;p&gt;Note that this action will stop machine execution immediately so that the guest operating system running inside it will not be able to perform a clean shutdown procedure which may result in &lt;i&gt;data loss&lt;/i&gt; inside the virtual machine. Selecting this action is recommended only if the virtual machine does not respond to the &lt;b&gt;Send the shutdown signal&lt;/b&gt; action.&lt;/p&gt;</source>
+ <source>Extensions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Power off the machine</source>
+ <source>VirtualBox - %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Restore the machine state stored in the current snapshot</source>
+ <source>Proxy</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
<message>
- <source>&lt;p&gt;When checked, the machine will be returned to the state stored in the current snapshot after it is turned off. This is useful if you are sure that you want to discard the results of your last sessions and start again at that snapshot.&lt;/p&gt;</source>
+ <source>General</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Restore current snapshot &apos;%1&apos;</source>
+ <source>System</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UIVMDesktop</name>
<message>
- <source>&amp;Details</source>
+ <source>Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Snapshots</source>
+ <source>Storage</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UIVMListView</name>
<message>
- <source>Inaccessible</source>
+ <source>Audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;nobr&gt;%1&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;%2 since %3&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Session %4&lt;/nobr&gt;</source>
- <comment>VM tooltip (name, last state change, session state)</comment>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;Inaccessible since %2&lt;/nobr&gt;</source>
- <comment>Inaccessible VM tooltip (name, last state change)</comment>
+ <source>Ports</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UIVMPreviewWindow</name>
<message>
- <source>Update Disabled</source>
+ <source>Serial Ports</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Every 0.5 s</source>
+ <source>Parallel Ports</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Every 1 s</source>
+ <source>USB</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Every 2 s</source>
+ <source>Shared Folders</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Every 5 s</source>
+ <source>%1 - %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UIVMCloseDialog</name>
<message>
- <source>Every 10 s</source>
+ <source>Close Virtual Machine</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No Preview</source>
+ <source>You want to:</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UIVMSettingsDlg</name>
<message>
- <source>General</source>
+ <source>&lt;p&gt;Saves the current execution state of the virtual machine to the physical hard disk of the host PC.&lt;/p&gt;&lt;p&gt;Next time this machine is started, it will be restored from the saved state and continue execution from the same place you saved it at, which will let you continue your work immediately.&lt;/p&gt;&lt;p&gt;Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>System</source>
+ <source>&amp;Save the machine state</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Display</source>
+ <source>&lt;p&gt;Sends the ACPI Power Button press event to the virtual machine.&lt;/p&gt;&lt;p&gt;Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.&lt;/p&gt;&lt;p&gt;If the machine doesn&apos;t respond to this action then the guest operating system may be misconfigured or doesn&apos;t understand ACPI Power Button events at all. In this case you should select the &lt;b&gt;Power off the machine&lt;/b&gt; action to stop virtual machine execution.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Storage</source>
+ <source>S&amp;end the shutdown signal</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Audio</source>
+ <source>&lt;p&gt;Turns off the virtual machine.&lt;/p&gt;&lt;p&gt;Note that this action will stop machine execution immediately so that the guest operating system running inside it will not be able to perform a clean shutdown procedure which may result in &lt;i&gt;data loss&lt;/i&gt; inside the virtual machine. Selecting this action is recommended only if the virtual machine does not respond to the &lt;b&gt;Send the shutdown signal&lt;/b&gt; action.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network</source>
+ <source>&amp;Power off the machine</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Ports</source>
+ <source>Restore the machine state stored in the current snapshot</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Serial Ports</source>
+ <source>&lt;p&gt;When checked, the machine will be returned to the state stored in the current snapshot after it is turned off. This is useful if you are sure that you want to discard the results of your last sessions and start again at that snapshot.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Parallel Ports</source>
+ <source>&amp;Restore current snapshot &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UIVMDesktop</name>
<message>
- <source>USB</source>
+ <source>&amp;Details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Shared Folders</source>
+ <source>&amp;Snapshots</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UIVMListView</name>
<message>
- <source>%1 - %2</source>
+ <source>Inaccessible</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <source>&lt;nobr&gt;%1&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;%2 since %3&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Session %4&lt;/nobr&gt;</source>
+ <comment>VM tooltip (name, last state change, session state)</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;Inaccessible since %2&lt;/nobr&gt;</source>
+ <comment>Inaccessible VM tooltip (name, last state change)</comment>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UIVMPreviewWindow</name>
<message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <source>Update Disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>at most one supported</source>
+ <source>Every 0.5 s</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>up to %1 supported</source>
+ <source>Every 1 s</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <source>Every 2 s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Every 5 s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Every 10 s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No Preview</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -3631,6 +3975,14 @@
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxEmptyFileSelector</name>
@@ -4327,11 +4679,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Adapter %1</source>
- <comment>network</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Checking...</source>
<comment>medium</comment>
<translation type="unfinished"></translation>
@@ -4636,21 +4983,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>SAS</source>
<comment>StorageBus</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation type="unfinished"></translation>
@@ -4840,6 +5177,61 @@
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -4979,18 +5371,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Location</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Type (Format)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Attached to</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Checking accessibility</source>
<translation type="unfinished"></translation>
</message>
@@ -5056,34 +5436,59 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: Virtual Disk</comment>
+ <source>CD/DVD-ROM disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: CD/DVD Image</comment>
+ <source>hard disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: Floppy Image</comment>
+ <source>floppy disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>CD/DVD-ROM disk</source>
+ <source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hard disk</source>
+ <source>Type:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>floppy disk</source>
+ <source>Location:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>All %1 images (%2)</source>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -5107,13 +5512,6 @@
</message>
</context>
<context>
- <name>VBoxNetworkDialog</name>
- <message>
- <source>Network Adapters</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxOSTypeSelectorWidget</name>
<message>
<source>Operating &amp;System:</source>
@@ -5189,10 +5587,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Failed to access the USB subsystem.</source>
<translation type="unfinished"></translation>
</message>
@@ -5726,10 +6120,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restore</source>
<translation type="unfinished"></translation>
</message>
@@ -6057,22 +6447,75 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>VBoxSFDialog</name>
<message>
- <source>Shared Folders</source>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -6143,10 +6586,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>D&amp;iscard</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Discard the saved state of the selected virtual machine</source>
<translation type="unfinished"></translation>
</message>
@@ -6306,6 +6745,22 @@
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSnapshotDetailsDlg</name>
@@ -6432,6 +6887,14 @@
<source> (%1 ago)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_es.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_es.ts
index f2eff218b..481265bfe 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_es.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_es.ts
@@ -307,11 +307,11 @@
</message>
<message>
<source>Auto-resize &amp;Guest Display</source>
- <translation>Au&amp;toredimensionar pantalla del huésped</translation>
+ <translation>Au&amp;toredimensionar pantalla del invitado</translation>
</message>
<message>
<source>Automatically resize the guest display when the window is resized (requires Guest Additions)</source>
- <translation>Redimensiona la pantalla del huésped cuando se redimensiona la ventana (requiere instalar las «Guest Additions»)</translation>
+ <translation>Redimensiona la pantalla del invitado cuando se redimensiona la ventana (requiere instalar las «Guest Additions»)</translation>
</message>
<message>
<source>&amp;Adjust Window Size</source>
@@ -319,7 +319,7 @@
</message>
<message>
<source>Adjust window size and position to best fit the guest display</source>
- <translation>Ajustar el tamaño y posición de la ventana al tamaño de la pantalla del huésped</translation>
+ <translation>Ajustar el tamaño y posición de la ventana al tamaño de la pantalla del invitado</translation>
</message>
<message>
<source>Disable &amp;Mouse Integration</source>
@@ -580,12 +580,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>&amp;Información de sesión</translation>
+ <translation type="obsolete">&amp;Información de sesión</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>Habilitar escritorio &amp;remoto</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation>&amp;Configuración...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation>Administrar la configuración de la máquina virtual</translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation>I&amp;nformación de sesión...</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation>Clonar máquina virtual</translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation>Clonar</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Este asistente le ayudará a crear un clón de su máquina virtual.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Seleccione un nuevo nombre para la máquina virtual:&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>Seleccionado, una nueva dirección MAC única se asignará a todas las tarjetas de red configuradas.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>&amp;Reinicializar la dirección MAC de todas las tarjetas de red</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation>Bienvenido al asistente de clonación de máquina virtual</translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation>%1 clonar</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation>Estado de máquina actual</translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation>Máquina actual y estados hijos</translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation>Todos los estados</translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation>Clonando configuración</translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation>Seleccione que partes de la máquina virtual deberían ser clonados.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation>Si selecciona &lt;b&gt;Estado de máquina actual&lt;/b&gt;, solo el estado actual de la máquina virtual será clonado.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation>Si selecciona &lt;b&gt;Máquina actual y estados hijos&lt;/b&gt;, el estado actual de la máquina virtual y cualquier estado de las instantáneas hijas serán clonados.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation>Si selecciona &lt;b&gt;Todos los estados&lt;/b&gt;, el estado actual de la máquina virtual y todas las instantáneas serán clonados.</translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -751,7 +836,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Red VDE , «%1»</translation>
+ <translation type="obsolete">Red VDE , «%1»</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -877,6 +962,26 @@
<comment>details report</comment>
<translation>Descripción</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation>Ejecución Cap</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation>&lt;nobr&gt;%1%&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>Controlador genérico, «%1»</translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation>Controlador genérico, «%1» {&amp;nbsp;%2&amp;nbsp;}</translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -1085,6 +1190,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">Nombre de &amp;máquina:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation>Exportar</translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1440,6 +1549,10 @@ p, li { white-space: pre-wrap; }
<source>Cancel</source>
<translation type="obsolete">Cancelar</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation>Iniciar</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1513,41 +1626,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>General</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Entrada</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Actualizar</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Idioma</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Red</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Extensiones</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1988,6 +2066,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation>Seleccionado, VirtualBox usará la configuración proporcionada para tareas como descargar las «Guest Additions» de la red o comprobar las actualizaciones.</translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation>&amp;Habilitar proxy</translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation>&amp;Máquina:</translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation>Cambia la máquina del proxy.</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Puerto:</translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation>Cambia el puerto del proxy.</translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation>Seleccionado, la autenticación proporcionada será usarda con el servidor proxy.</translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation>&amp;Usar autenticación</translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation>Nombre de &amp;usuario:</translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation>Cambia el nombre de usuario usado para la autenticación.</translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation>&amp;Contraseña:</translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation>Cambia la contraseña usada para la autenticación.</translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -2057,23 +2186,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Mayús Izquierdo</translation>
+ <translation type="obsolete">Mayús Izquierdo</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Mayús Derecho</translation>
+ <translation type="obsolete">Mayús Derecho</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Ctrl Izquierdo</translation>
+ <translation type="obsolete">Ctrl Izquierdo</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Ctrl Derecho</translation>
+ <translation type="obsolete">Ctrl Derecho</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Alt Izquierdo</translation>
+ <translation type="obsolete">Alt Izquierdo</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2290,6 +2419,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importar &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation>Importar</translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2434,7 +2567,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Indica el estado de las características del hardware de virtualización usadas por esta máquina virtual: &lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Indica el estado de las características del hardware de virtualización usadas por esta máquina virtual: &lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2443,11 +2576,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Indicates whether the host mouse pointer is captured by the guest OS:&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_disabled_16px.png/&gt;&amp;nbsp;&amp;nbsp;pointer is not captured&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_16px.png/&gt;&amp;nbsp;&amp;nbsp;pointer is captured&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;mouse integration (MI) is On&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;MI is Off, pointer is captured&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_uncaptured_16px.png/&gt;&amp;nbsp;&amp;nbsp;MI is Off, pointer is not captured&lt;/nobr&gt;&lt;br&gt;Note that the mouse integration feature requires Guest Additions to be installed in the guest OS.</source>
- <translation>Indica si el puntero del ratón es capturado por el SO huésped:&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_disabled_16px.png/&gt;&amp;nbsp;&amp;nbsp;puntero no es capturado&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_16px.png/&gt;&amp;nbsp;&amp;nbsp;puntero es capturado&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;Int. del ratón habilitada&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;Int. ratón deshabilitada, el ratón es capturado&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_uncaptured_16px.png/&gt;&amp;nbsp;&amp;nbsp;Int. ratón deshabilitada, el ratón no es capturado&lt;/nobr&gt;&lt;br&gt; La integración del ratón requiere instalar las «Guest Additions» en el SO huésped.</translation>
+ <translation>Indica si el puntero del ratón es capturado por el SO invitado:&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_disabled_16px.png/&gt;&amp;nbsp;&amp;nbsp;puntero no es capturado&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_16px.png/&gt;&amp;nbsp;&amp;nbsp;puntero es capturado&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;Int. del ratón habilitada&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;Int. ratón deshabilitada, el ratón es capturado&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_uncaptured_16px.png/&gt;&amp;nbsp;&amp;nbsp;Int. ratón deshabilitada, el ratón no es capturado&lt;/nobr&gt;&lt;br&gt; La integración del ratón requiere instalar las «Guest Additions» en el SO invitado.</translation>
</message>
<message>
<source>Indicates whether the keyboard is captured by the guest OS (&lt;img src=:/hostkey_captured_16px.png/&gt;) or not (&lt;img src=:/hostkey_16px.png/&gt;).</source>
- <translation>Indica si el teclado está capturado por el SO huésped (&lt;img src=:/hostkey_captured_16px.png/&gt;) o no (&lt;img src=:/hostkey_16px.png/&gt;).</translation>
+ <translation>Indica si el teclado está capturado por el SO invitado (&lt;img src=:/hostkey_captured_16px.png/&gt;) o no (&lt;img src=:/hostkey_16px.png/&gt;).</translation>
</message>
<message>
<source>Indicates whether the Remote Desktop Server is enabled (&lt;img src=:/vrdp_16px.png/&gt;) or not (&lt;img src=:/vrdp_disabled_16px.png/&gt;).</source>
@@ -2457,6 +2590,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;El servidor de escritorio remoto está escuchando en el puerto %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation>Indica el estado de diferentes características usadas por esta máquina virtual:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2533,7 +2671,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Controls the audio output driver. The &lt;b&gt;Null Audio Driver&lt;/b&gt; makes the guest see an audio card, however every access to it will be ignored.</source>
- <translation>Controla el controlador de salida de audio. El &lt;b&gt;Controlador de audio nulo&lt;/b&gt; hace que el huésped vea una tarjeta de sonido, sin embargo, los accesos a ésta serán ignorados.</translation>
+ <translation>Controla el controlador de salida de audio. El &lt;b&gt;Controlador de audio nulo&lt;/b&gt; hace que el invitado vea una tarjeta de sonido, sin embargo, los accesos a ésta serán ignorados.</translation>
</message>
<message>
<source>Audio &amp;Controller:</source>
@@ -2616,7 +2754,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Specifies the timeout for guest authentication, in milliseconds.</source>
- <translation>Especifica el tiempo de espera para la autenticación del cliente (en milisegundos).</translation>
+ <translation>Especifica el tiempo de espera para la autenticación del invitado (en milisegundos).</translation>
</message>
<message>
<source>you have assigned less than &lt;b&gt;%1&lt;/b&gt; of video memory which is the minimum amount required for HD Video to be played efficiently.</source>
@@ -2656,7 +2794,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Tiene la aceleración 3D habilitada para un sistema operativo que usa el controlador de vídeo WDDM. Para un rendimiento máximo asigne una VRAM para el invitado de al menos &lt;b&gt;%1&lt;/b&gt;.</translation>
+ <translation type="obsolete">Tiene la aceleración 3D habilitada para un sistema operativo que usa el controlador de vídeo WDDM. Para un rendimiento máximo asigne una VRAM para el invitado de al menos &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>tiene la aceleración 3D habilitada para un sistema operativo que usa el controlador WDDM. Para un máximo rendimiento establezca la VRAM del invitado a almenos &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation>tiene la acelaración de vídeo 2D habilitada. Como la aceleración de vídeo solo está soportada para invitados Windows, esta característica será deshabilitada.</translation>
</message>
</context>
<context>
@@ -2759,7 +2905,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects which clipboard data will be copied between the guest and the host OS. This feature requires Guest Additions to be installed in the guest OS.</source>
- <translation>Define el modo de compartición del portapapeles entre el SO anfitrión y el huésped. Tenga en cuenta que esta opción requiere instalar las «Guest Additions» en el SO huésped.</translation>
+ <translation>Define el modo de compartición del portapapeles entre el SO anfitrión y el invitado. Tenga en cuenta que esta opción requiere instalar las «Guest Additions» en el SO invitado.</translation>
</message>
<message>
<source>Defines the type of the virtual IDE controller. Depending on this value, VirtualBox will provide different virtual IDE hardware devices to the guest OS.</source>
@@ -2775,7 +2921,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Displays the description of the virtual machine. The description field is useful for commenting on configuration details of the installed guest OS.</source>
- <translation>Muestra la descripción de la máquina virtual. El campo de descripción es útil para comentar los detalles de configuración del SO huésped instalado.</translation>
+ <translation>Muestra la descripción de la máquina virtual. El campo de descripción es útil para comentar los detalles de configuración del SO invitado instalado.</translation>
</message>
<message>
<source>If checked, any change to mounted CD/DVD or Floppy media performed during machine execution will be saved in the settings file in order to preserve the configuration of mounted media between runs.</source>
@@ -2809,6 +2955,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Mostrar en la parte &amp;superior de la pantalla</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation>ha seleccionado un tipo de SO invitado de 64-bit para esta MV. Como estos invitados requieren hardware de virtualización (VT-x/AMD-V), esta característica se activará automáticamente.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2881,7 +3031,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Selecciona el nombre del adaptador de red si el tipo de conexión es &lt;b&gt;Adaptador Puente&lt;/b&gt; o &lt;b&gt;Adaptador Solo-Anfitrión&lt;/b&gt; o el nombre de la red interna si el tipo de conexión es &lt;b&gt;Red Interna&lt;/b&gt;.</translation>
+ <translation type="obsolete">Selecciona el nombre del adaptador de red si el tipo de conexión es &lt;b&gt;Adaptador Puente&lt;/b&gt; o &lt;b&gt;Adaptador Solo-Anfitrión&lt;/b&gt; o el nombre de la red interna si el tipo de conexión es &lt;b&gt;Red Interna&lt;/b&gt;.</translation>
</message>
<message>
<source>Displays the name of the internal network selected for this adapter.</source>
@@ -2955,6 +3105,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>&amp;Reenvío de puertos</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation>Modo &amp;promiscuo:</translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation>Seleciona la política de modo promiscuo para el adaptador de red cuando está conectado a una red interna, solo red anfitrión o un puente.</translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation>Propiedades genéricas:</translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation>Introduzca cualquier preferencia de configuración aquí para la conexión del controlador de red que usará. Esta configuración deberá ser de la forma &lt;b&gt;nombre=valor&lt;/b&gt; y dependerán del controlador. Use &lt;b&gt;shift-enter&lt;/b&gt; para añadir una nueva entrada.</translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation>no hay driver genérico seleccionado</translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation>Selecciona el adaptador de red en el sistema anfitrión que enruta el tŕafico desde y a esta tarjeta de red.</translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation>Introduzca el nombre de la red interna a la que esta tarjeta red será conetada. Puede crear una nueva red interna eligiendo un nombre que no esté siendo usado por ninguna otra tarjeta de red en esta máquina virtual u otras.</translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation>Selecciona el adaptador virtual de red en el sistema anfitrión que enruta el tŕafico desde y a esta tarjeta de red. Puede crear o eliminar adaptadores usando la configuración global de red en la ventana de administracion de máquina virtual.</translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation>Selecciona el controlador a ser usado con esta tarjeta de red.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3140,7 +3326,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Lists all shared folders accessible to this machine. Use &apos;net use x: \\vboxsvr\share&apos; to access a shared folder named &lt;i&gt;share&lt;/i&gt; from a DOS-like OS, or &apos;mount -t vboxsf share mount_point&apos; to access it from a Linux OS. This feature requires Guest Additions.</source>
- <translation>Lista todas las carpetas compartidas accesibles por esta máquina. Use &apos;net use x: \\vboxsvr\share&apos; para acceder a una carpeta compartida llamada &lt;i&gt;share&lt;/i&gt; desde un SO similar a DOS o &apos;mount -t vboxsf share mount_point&apos; para acceder desde un SO Linux. Esta característica requiere las «Guest Additions».</translation>
+ <translation>Lista todas las carpetas compartidas accesibles por esta máquina. Use «net use x: \\vboxsvr\share» para acceder a una carpeta compartida llamada &lt;i&gt;share&lt;/i&gt; desde un SO similar a DOS o «mount -t vboxsf share mount_point» para acceder desde un SO Linux. Esta característica requiere las «Guest Additions».</translation>
</message>
<message>
<source>Name</source>
@@ -3207,11 +3393,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Displays the name of the shared folder (as it will be seen by the guest OS).</source>
- <translation>Muestra el nombre de la carpeta compartida (como será vista en el SO huésped).</translation>
+ <translation>Muestra el nombre de la carpeta compartida (como será vista en el SO invitado).</translation>
</message>
<message>
<source>When checked, the guest OS will not be able to write to the specified shared folder.</source>
- <translation>Seleccionado, el SO huésped no podrá escribir en la carpeta compartida especificada.</translation>
+ <translation>Seleccionado, el SO invitado no podrá escribir en la carpeta compartida especificada.</translation>
</message>
<message>
<source>&amp;Read-only</source>
@@ -3279,7 +3465,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Controls the working mode of this serial port. If you select &lt;b&gt;Disconnected&lt;/b&gt;, the guest OS will detect the serial port but will not be able to operate it.</source>
- <translation>Controla el modo de trabajo del puerto serie. Si selecciona &lt;b&gt;Desconectado&lt;/b&gt;, el SO huésped detectará el puerto serie pero no podrá trabajar con él.</translation>
+ <translation>Controla el modo de trabajo del puerto serie. Si selecciona &lt;b&gt;Desconectado&lt;/b&gt;, el SO invitado detectará el puerto serie pero no podrá trabajar con él.</translation>
</message>
<message>
<source>If checked, the pipe specified in the &lt;b&gt;Port Path&lt;/b&gt; field will be created by the virtual machine when it starts. Otherwise, the virtual machine will assume that the pipe exists and try to use it.</source>
@@ -3413,7 +3599,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>No hay disco duro seleccionado para &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">No hay disco duro seleccionado para &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3569,7 +3755,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>When checked, allows the guest to send ATAPI commands directly to the host-drive which makes it possible to use CD/DVD writers connected to the host inside the VM. Note that writing audio CD inside the VM is not yet supported.</source>
- <translation>Seleccinado, permite que sistema huésped envíe comandos ATAPI directamente al unidad real. Ésto a su vez posibilita el uso de grabadoras de CD/DVD reales desde el sistema huésped. Tenga en cuenta que grabar CD de audio todavía no está soportado.</translation>
+ <translation>Seleccinado, permite que sistema invitado envíe comandos ATAPI directamente al unidad real. Esto a su vez posibilita el uso de grabadoras de CD/DVD reales desde el sistema invitado. Tenga en cuenta que grabar CD de audio todavía no está soportado.</translation>
</message>
<message>
<source>&amp;Passthrough</source>
@@ -3687,6 +3873,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation>Seleccionar un archivo de disquete virtual...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation>Seleccionado, suprime el desmontaje del medio cuando el SO invitado lo extrae.</translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation>CD/DVD &amp;vivo</translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation>Seleccionado, marca el medio como almacenamiento no rotacional (SSD).</translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation>Disco duro de estado &amp;sólido</translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation>Detalles:</translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>no se ha especificado un nombre para el controlador en la posición &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation>el controlador en la posición &lt;b&gt;%1&lt;/b&gt; usa el nombre que ya está siendo usado por el controlador en la posición &lt;b&gt;%2&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation>no hay disco duro seleccionado para &lt;i&gt;%1&lt;/i&gt;.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation>soportado como mucho uno</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation>hasta %1 soportados</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation>está usando más controladores de almacenamiento de los que un chipset %1 soporta. Cambie el tipo de chipset en la página de la configuración del sistema o reduzca el número de los siguientes controladores de almacenamiento en la página de la configuración de almacenamiento: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3782,7 +4022,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>When checked, the virtual machine will support the Input Output APIC (IO APIC), which may slightly decrease performance. &lt;b&gt;Note:&lt;/b&gt; don&apos;t disable this feature after having installed a Windows guest operating system!</source>
- <translation>Seleccionado, la máquina virtual soportará Input Output APIC (IO APIC), que puede disminuir ligeramente el rendimiento de la MV. &lt;b&gt;Nota:&lt;/b&gt; no deshabilite esta característica despues de haber instalado un sistema operativo huésped Windows!</translation>
+ <translation>Seleccionado, la máquina virtual soportará Input Output APIC (IO APIC), que puede disminuir ligeramente el rendimiento de la MV. &lt;b&gt;Nota:&lt;/b&gt; no deshabilite esta característica después de haber instalado un sistema operativo invitado Windows!</translation>
</message>
<message>
<source>Enable &amp;IO APIC</source>
@@ -3877,6 +4117,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>tiene asignado el tipo de chipset ICH9 para esta máquina virtual. No funcionará adecuadamente a menos que la característica IO APIC este también habilitada. Esto se hará automáticamente cuando acepte las preferencias de la MV presionando el botón Aceptar.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation>&amp;Límite ejecución:</translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation>Limita la cantidad de tiempo que cada CPU virtual está permitida a ejecutarse. Cada CPU virtual será perimitida usarse hasta este porcentaje de tiempo de procesamiento disponible en una CPU física. El límite de ejecución puede ser deshabilitada estableciendolo a 100%. Estableciendo un límite demasiado bajo puede hacer que la máquina tenga una respuesta lenta.</translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation>ha establecido el límite de ejecución a un valor bajo. Esto puede hacer que la máquina tenga una respuesta lenta.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation>Ha habilitado un USB HID (Human Interface Device). Esto no funcionará a menos que la emulación USB esté también habilitada. Esto se hará autmáticamente cuando acepte la configuración presionando el botón Aceptar.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation>&lt;qt&gt;%1%&lt;/qt&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation>&lt;qt&gt;%1%&lt;/qt&gt;</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -4003,7 +4269,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>USB 2.0 está habilitado para esta máquina virtual. Sin embargo esto requiere que &lt;b&gt;%1&lt;/b&gt; esté instalado. Instale el Paquete de Extensiones desde el sitio de descargas de VirtualBox. Después de esto podrá rehabilitar USB 2.0. Por el momento será deshabilitado a menos que cancele los cambios de preferencias actuales.</translation>
+ <translation type="obsolete">USB 2.0 está habilitado para esta máquina virtual. Sin embargo esto requiere que &lt;b&gt;%1&lt;/b&gt; esté instalado. Instale el Paquete de Extensiones desde el sitio de descargas de VirtualBox. Después de esto podrá rehabilitar USB 2.0. Por el momento será deshabilitado a menos que cancele los cambios de preferencias actuales.</translation>
+ </message>
+ <message>
+ <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>USB 2.0 está actualmente habilitado para esta máquina virtual, esto requiere que &lt;b&gt;%1&lt;/b&gt; esté instalado. Instale el paquete de extensiones desde el sitio de descargas de VirtualBox. Después de esto podrá rehabilitar USB 2.0. Será deshabilitado mientras tanto a menos que cancele los cambios de configuración actuales.</translation>
</message>
</context>
<context>
@@ -4116,6 +4386,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation>Modificar atributos del medio</translation>
+ </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;Está apunto de cambiar los atributos del disco virtual localizados en &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Seleccione uno de los siguiente tipos de medios y presione &lt;b&gt;%2&lt;/b&gt; para proceder o &lt;b&gt;%3&lt;/b&gt; en caso contrario.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation>Selecione un tipo de medio:</translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4161,7 +4446,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Crear nuevo disco virtual</translation>
@@ -4257,7 +4542,7 @@ as the size of the virtual hard disk.&lt;/p&gt;</source>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Resumen</translation>
+ <translation>Resumen</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4273,7 +4558,7 @@ as the size of the virtual hard disk.&lt;/p&gt;</source>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Seleccione un archivo para la nueva imagen de disco duro</translation>
+ <translation>Seleccione un archivo para la nueva imagen de disco duro</translation>
</message>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;
@@ -4331,12 +4616,12 @@ dependiendo del tamaño de la imagen y el rendimiento de su disco duro.&lt;/p&gt
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Localización</translation>
+ <translation>Localización</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Tamaño</translation>
+ <translation>Tamaño</translation>
</message>
<message>
<source>Bytes</source>
@@ -4395,108 +4680,280 @@ dependiendo del tamaño de la imagen y el rendimiento de su disco duro.&lt;/p&gt
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Si la configuración anterior es correcta presione el botón &lt;b&gt;Terminar&lt;/b&gt;. Una vez presionado un nuevo disco virtual será creado.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation>%1 copiado</translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation>Crear</translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation>Copiar disco virtual</translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation>Copiar</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation>Bienvenido al asistente de copiado de disco virtual</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Este asistente le ayudará a copiar un disco virtual.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation>Selecicone el disco virtual que quiere copiar. Puede seleccionar uno de la lista o usar el icono de carpeta junto a la lista para seleccionar un archivo de disco virtual.</translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation>&amp;VDI (VirtualBox Disk Image)</translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation>V&amp;MDK (Virtual Machine Disk)</translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation>V&amp;HD (Virtual Hard Disk)</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation>Bienvenido al asistente de creación de disco virtual</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Este asistente le ayudará a crear un disco virtual para su máquina virtual.&lt;/p</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Selecione el tipo de archivo que quiere usar para el nuevo disco virtual. Si no necesita usarlo con otro software de virtualización puede dejar esta configuración sin cambiar.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation>Tipo de archivo de disco virtual</translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation>Seleccione el tipo de archivo que quiere usar para el nuevo disco virtual. Si no necesita usarlo con otro software de virtualización puede dejar esta configuración sin cambiar.</translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation>Detalles de almecenamiento de disco virtual</translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation>Seleccione si el archivo del disco virtual debería ser reservado según sea usado o si debería reservase completamente en la creación.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Un archivo de disco virtual &lt;b&gt;reservado dinámcamente&lt;/b&gt; solo usa espacio en su disco duro físico según se llena, sin embargo no se reducirá de nuevo automáticamente cuando el espacio en él sea liberado.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Un archivo de disco virtual de &lt;b&gt;tamaño fijo&lt;/b&gt; puede tomar más tiempo en crearse en algunos sistemas pero a menudo es más rápido al usarlo.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation>&lt;p&gt;También puede seleccionar &lt;b&gt;dividir&lt;/b&gt; el disco virtual en varios archivos de hasta dos gigabytes cada uno. Principalmente esto es útil si desea almacenar la máquina virtual en dispositivos USB extraíbles o en sistemas antiguos, algunos de los cuales no pueden manejar archivos muy grandes.</translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation>Reservado &amp;dinámcamente</translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation>Tamaño &amp;fijo</translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation>Dividir en &amp;archivos de menos de 2 GB</translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation>Localización y tamaño del archivo de disco virtual</translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation>Seleccione el tamaño del disco virtual en megabytes. Este tamaño será informado al SO invitado como el tamaño máximo de este disco virtual.</translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation>Localización del archivo del disco virtual</translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation>Presione el botón &lt;b&gt;Seleccionar&lt;/b&gt; para seleccionar la localización de un archivo para almacenar los datos del disco virtual o escriba una nombre de archivo en el campo de entrada.</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation>Va a crear un nuevo disco virtual con los siguientes parámetros:</translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation>Va a crear un de disco virtual copiado con los siguientes parámetros:</translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation>Si la configuración de arriba es correcta, presione el botón &lt;b&gt;%1&lt;/b&gt;. Presionándolo el archivo de disco virtual será creado.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation>Tipo de archivo</translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation>Detalles</translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation>Tipo de archivo</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation>&amp;Localización</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation>&amp;Tamaño</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation>Detalles de almacenamiento</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>¡Bienvenido al asistente para la creación de un nuevo disco virtual!</translation>
+ <translation type="obsolete">¡Bienvenido al asistente para la creación de un nuevo disco virtual!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Este asistente le ayudará a crear un nuevo disco duro para la máquina virtual.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Este asistente le ayudará a crear un nuevo disco duro para la máquina virtual.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation>Disco virtual a copiar</translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation>Seleccione un archivo de disco duro virtual...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Seleccione el tipo de imagen de disco duro virtual que desee crear.&lt;/p&gt;&lt;p&gt;Una &lt;b&gt;imagen de expansión dinámica&lt;/b&gt; inicialmente ocupa un pequeño espacio de su disco duro físico. Crecerá dinámicamente (hasta el tamaño espeficicado) a medida que el sistema huésped vaya utilizando el espacio del disco.&lt;/p&gt;&lt;p&gt;Una &lt;b&gt;imagen de tamaño fijo&lt;/b&gt; no crece. Es almacenada en un archivo aproximandamente del mismo tamaño que el disco virtual. La creación del un disco de tamaño fijo puede demorarse dependiendo del tamaño de la imagen y el rendimiento de su disco duro.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Seleccione el tipo de imagen de disco duro virtual que desee crear.&lt;/p&gt;&lt;p&gt;Una &lt;b&gt;imagen de expansión dinámica&lt;/b&gt; inicialmente ocupa un pequeño espacio de su disco duro físico. Crecerá dinámicamente (hasta el tamaño espeficicado) a medida que el sistema huésped vaya utilizando el espacio del disco.&lt;/p&gt;&lt;p&gt;Una &lt;b&gt;imagen de tamaño fijo&lt;/b&gt; no crece. Es almacenada en un archivo aproximandamente del mismo tamaño que el disco virtual. La creación del un disco de tamaño fijo puede demorarse dependiendo del tamaño de la imagen y el rendimiento de su disco duro.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Tipo de almacenamiento</translation>
+ <translation type="obsolete">Tipo de almacenamiento</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>Almacenamiento de expansión &amp;dinámica</translation>
+ <translation type="obsolete">Almacenamiento de expansión &amp;dinámica</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>Almacenamiento de tamaño &amp;fijo</translation>
+ <translation type="obsolete">Almacenamiento de tamaño &amp;fijo</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Tipo de almacenamiento de disco duro</translation>
+ <translation type="obsolete">Tipo de almacenamiento de disco duro</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Presione &lt;b&gt;Seleccionar&lt;/b&gt; para elegir la localización y nombre del archivo para almacenar los datos del disco virtual. Alternativamente puede ingresar el nombre del archivo en el campo de entrada.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Presione &lt;b&gt;Seleccionar&lt;/b&gt; para elegir la localización y nombre del archivo para almacenar los datos del disco virtual. Alternativamente puede ingresar el nombre del archivo en el campo de entrada.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;Localización</translation>
+ <translation type="obsolete">&amp;Localización</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Seleccione el tamaño de la imagen de disco virtual en megabytes. Este será el tamaño de disco que será reportado al SO huésped.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Seleccione el tamaño de la imagen de disco virtual en megabytes. Este será el tamaño de disco que será reportado al SO huésped.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Tamaño</translation>
+ <translation type="obsolete">&amp;Tamaño</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Tamaño y localizacion del disco virtual</translation>
+ <translation type="obsolete">Tamaño y localizacion del disco virtual</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Seleccione un archivo para la nueva imagen de disco duro</translation>
+ <translation type="obsolete">Seleccione un archivo para la nueva imagen de disco duro</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Imágenes de disco duro (*.vdi)</translation>
+ <translation type="obsolete">Imágenes de disco duro (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Se creará una nueva imagen de disco virtual con los siguientes parámetros:</translation>
+ <translation type="obsolete">Se creará una nueva imagen de disco virtual con los siguientes parámetros:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Resumen</translation>
+ <translation type="obsolete">Resumen</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Tipo</translation>
+ <translation type="obsolete">Tipo</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Localización</translation>
+ <translation type="obsolete">Localización</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Tamaño</translation>
+ <translation type="obsolete">Tamaño</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Si la configuración de arriba es correcta, presione el botón &lt;b&gt;%1&lt;/b&gt;. Una vez presionado, se creará un nuevo disco duro.</translation>
+ <translation type="obsolete">Si la configuración de arriba es correcta, presione el botón &lt;b&gt;%1&lt;/b&gt;. Una vez presionado, se creará un nuevo disco duro.</translation>
</message>
</context>
<context>
@@ -4733,6 +5190,10 @@ este paso y luego conectar los Discos Duros desde el diálogo de Configuración
<source>Boot Hard &amp;Disk (Primary Master)</source>
<translation type="obsolete">&amp;Disco duro de arranque (Primario maestro)</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation>Crear</translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4749,7 +5210,7 @@ este paso y luego conectar los Discos Duros desde el diálogo de Configuración
<name>UINewVMWzdPage2</name>
<message>
<source>&lt;p&gt;Enter a name for the new virtual machine and select the type of the guest operating system you plan to install onto the virtual machine.&lt;/p&gt;&lt;p&gt;The name of the virtual machine usually indicates its software and hardware configuration. It will be used by all VirtualBox components to identify your virtual machine.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Ingrese el nombre de la nueva máquina virtual y seleccione el tipo de sistema operativo huésped que planea instalar.&lt;/p&gt;&lt;p&gt;El nombre de la máquina virtual normalmente indica su configuración de software y hardware. Será usado para identificar la máquina virtual creada en los productos de VirtualBox.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Ingrese el nombre de la nueva máquina virtual y seleccione el tipo de sistema operativo invitado que planea instalar.&lt;/p&gt;&lt;p&gt;El nombre de la máquina virtual normalmente indica su configuración de software y hardware. Será usado para identificar la máquina virtual creada en los productos de VirtualBox.&lt;/p&gt;</translation>
</message>
<message>
<source>N&amp;ame</source>
@@ -5018,6 +5479,120 @@ este paso y luego conectar los Discos Duros desde el diálogo de Configuración
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Entrada</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Actualizar</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Idioma</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Red</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Extensiones</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation>Proxy</translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>Sistema</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Pantalla</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Almacenamiento</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Audio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Red</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Puertos</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Puertos serie</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Puertos paralelos</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Carpetas compartidas</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">ha seleccionado un tipo de SO invitado de 64-bit para esta MV. Como estos huéspedes requieren hardware de virtualización (VT-x/AMD-V), esta característica se activará automáticamente.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">tiene habilitada la aceleración de vídeo 2D. Como la aceleración de vídeo 2D solo es soportada para invitados Windows, esta característica será inhabilitada.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">Ha habilitado un USB HID (Human Interface Device). Esto no funcionará a menos que la emulación USB esté también habilitada. Esto se hará autmáticamente cuando acepte la configuración presionando el botón Aceptar.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">soportado como mucho uno</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">hasta %1 soportados</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">está usando más controladores de almacenamiento de los que un chipset %1 soporta. Cambie el tipo de chipset en la página de la configuración del sistema o reduzca el número de los siguientes controladores de almacenamiento en la página de la configuración de almacenamiento: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -5029,7 +5604,7 @@ este paso y luego conectar los Discos Duros desde el diálogo de Configuración
</message>
<message>
<source>&lt;p&gt;Saves the current execution state of the virtual machine to the physical hard disk of the host PC.&lt;/p&gt;&lt;p&gt;Next time this machine is started, it will be restored from the saved state and continue execution from the same place you saved it at, which will let you continue your work immediately.&lt;/p&gt;&lt;p&gt;Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Guarda el estado actual de ejecución de la máquina virtual al disco duro físico del PC anfitrión.&lt;/p&gt;&lt;p&gt;La próxima vez que la máquina sea iniciada, será restuarada al estado guardado y continuará la ejecución en el mismo punto donde la guardó. Lo que le permitirá continuar con su trabajo inmediatamente.&lt;/p&gt;&lt;p&gt;Tenga en cuenta que guardar el estádo de la máquina puede tomar bastante tiempo, dependiendo el tipo de sistema operativo huésped y la cantidad de memoria que se le asignó a la máquina virtual.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Guarda el estado actual de ejecución de la máquina virtual al disco duro físico del PC anfitrión.&lt;/p&gt;&lt;p&gt;La próxima vez que la máquina sea iniciada, será restuarada al estado guardado y continuará la ejecución en el mismo punto donde la guardó. Lo que le permitirá continuar con su trabajo inmediatamente.&lt;/p&gt;&lt;p&gt;Tenga en cuenta que guardar el estádo de la máquina puede tomar bastante tiempo, dependiendo el tipo de sistema operativo invitado y la cantidad de memoria que se le asignó a la máquina virtual.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Save the machine state</source>
@@ -5037,7 +5612,7 @@ este paso y luego conectar los Discos Duros desde el diálogo de Configuración
</message>
<message>
<source>&lt;p&gt;Sends the ACPI Power Button press event to the virtual machine.&lt;/p&gt;&lt;p&gt;Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.&lt;/p&gt;&lt;p&gt;If the machine doesn&apos;t respond to this action then the guest operating system may be misconfigured or doesn&apos;t understand ACPI Power Button events at all. In this case you should select the &lt;b&gt;Power off the machine&lt;/b&gt; action to stop virtual machine execution.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Envía el evento ACPI Boton de Energía presionado a la máquina virtual.&lt;/p&gt;&lt;p&gt;Normalmente el sistema operativo huésped detectará esta señal y efectuará un procedimiento de apagado limpio. Esta es la manera recomendada de apagar la máquina virtual, ya que las aplicaciones corriendo dentro de la máquina virtual tendrán la oportunidad de guardar sus datos y estado.&lt;/p&gt;&lt;p&gt;Si la máquina no responde a esta acción puede que esté mal configurado o no soporte eventos ACPI de apagado. En este caso conviene apagar el sistema desde la máquina y luego seleccionar &lt;b&gt;Apagar la máquina&lt;/b&gt; para parar la ejecución de la máquina virtual.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Envía el evento ACPI Boton de Energía presionado a la máquina virtual.&lt;/p&gt;&lt;p&gt;Normalmente el sistema operativo invitado detectará esta señal y efectuará un procedimiento de apagado limpio. Esta es la manera recomendada de apagar la máquina virtual, ya que las aplicaciones corriendo dentro de la máquina virtual tendrán la oportunidad de guardar sus datos y estado.&lt;/p&gt;&lt;p&gt;Si la máquina no responde a esta acción puede que esté mal configurado o no soporte eventos ACPI de apagado. En este caso conviene apagar el sistema desde la máquina y luego seleccionar &lt;b&gt;Apagar la máquina&lt;/b&gt; para parar la ejecución de la máquina virtual.&lt;/p&gt;</translation>
</message>
<message>
<source>S&amp;end the shutdown signal</source>
@@ -5045,7 +5620,7 @@ este paso y luego conectar los Discos Duros desde el diálogo de Configuración
</message>
<message>
<source>&lt;p&gt;Turns off the virtual machine.&lt;/p&gt;&lt;p&gt;Note that this action will stop machine execution immediately so that the guest operating system running inside it will not be able to perform a clean shutdown procedure which may result in &lt;i&gt;data loss&lt;/i&gt; inside the virtual machine. Selecting this action is recommended only if the virtual machine does not respond to the &lt;b&gt;Send the shutdown signal&lt;/b&gt; action.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Apaga la máquina virtual.&lt;/p&gt;&lt;p&gt;Tenga en cuenta que está acción parará la ejecución de la máquina virtual inmediatamente. Esto puede ocasionar que el sistema operativo huésped no pueda efectuar un apagado limpio y haya &lt;i&gt;pérdida de datos&lt;/i&gt; dentro de la máquina virtual. Sólo se recomienda usar esta opción cuando la máquina virtual no respode a la acción &lt;b&gt;Enviar señal de apagado&lt;/b&gt;.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Apaga la máquina virtual.&lt;/p&gt;&lt;p&gt;Tenga en cuenta que está acción parará la ejecución de la máquina virtual inmediatamente. Esto puede ocasionar que el sistema operativo invitado no pueda efectuar un apagado limpio y haya &lt;i&gt;pérdida de datos&lt;/i&gt; dentro de la máquina virtual. Sólo se recomienda usar esta opción cuando la máquina virtual no respode a la acción &lt;b&gt;Enviar señal de apagado&lt;/b&gt;.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Power off the machine</source>
@@ -5156,81 +5731,6 @@ este paso y luego conectar los Discos Duros desde el diálogo de Configuración
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>General</translation>
- </message>
- <message>
- <source>System</source>
- <translation>Sistema</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Pantalla</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Almacenamiento</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Audio</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Red</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Puertos</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Puertos serie</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Puertos paralelos</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Carpetas compartidas</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>ha seleccionado un tipo de SO invitado de 64-bit para esta MV. Como estos huéspedes requieren hardware de virtualización (VT-x/AMD-V), esta característica se activará automáticamente.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>tiene habilitada la aceleración de vídeo 2D. Como la aceleración de vídeo 2D solo es soportada para invitados Windows, esta característica será inhabilitada.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>Ha habilitado un USB HID (Human Interface Device). Esto no funcionará a menos que la emulación USB esté también habilitada. Esto se hará autmáticamente cuando acepte la configuración presionando el botón Aceptar.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>soportado como mucho uno</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>hasta %1 soportados</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>está usando más controladores de almacenamiento de los que un chipset %1 soporta. Cambie el tipo de chipset en la página de la configuración del sistema o reduzca el número de los siguientes controladores de almacenamiento en la página de la configuración de almacenamiento: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5402,7 +5902,7 @@ Versión %1</translation>
</message>
<message>
<source>Guest OS Type</source>
- <translation>Tipo de SO huésped</translation>
+ <translation>Tipo de SO invitado</translation>
</message>
<message>
<source>CPU</source>
@@ -5482,6 +5982,14 @@ Versión %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation>Controlador de disco duro (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>Seleccionado, una nueva dirección MAC será asignada a todas las tarjetas de red configuradas.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>&amp;Reinicializar la dirección MAC de todas las tarjetas de red</translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -7301,12 +7809,12 @@ Versión %1</translation>
<message>
<source>Host To Guest</source>
<comment>ClipboardType</comment>
- <translation>Anfitrión a huésped</translation>
+ <translation>Anfitrión a invitado</translation>
</message>
<message>
<source>Guest To Host</source>
<comment>ClipboardType</comment>
- <translation>Huésped a anfitrión</translation>
+ <translation>Invitado a anfitrión</translation>
</message>
<message>
<source>Bidirectional</source>
@@ -7639,7 +8147,7 @@ Versión %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Adaptador %1</translation>
+ <translation type="obsolete">Adaptador %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -8001,7 +8509,7 @@ Versión %1</translation>
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Red VDE , «%1»</translation>
+ <translation type="obsolete">Red VDE , «%1»</translation>
</message>
<message>
<source>SAS</source>
@@ -8011,7 +8519,7 @@ Versión %1</translation>
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>Adaptador VDE</translation>
+ <translation type="obsolete">Adaptador VDE</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -8162,7 +8670,7 @@ Versión %1</translation>
<message>
<source>Guest</source>
<comment>AuthType</comment>
- <translation>Huésped</translation>
+ <translation>Invitado</translation>
</message>
<message>
<source>Intel HD Audio</source>
@@ -8208,6 +8716,61 @@ Versión %1</translation>
<comment>DiskType</comment>
<translation>Multiconexión</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation>Almacenamiento resevado dinámicamente</translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation>Almacenamiento de tamaño fijo</translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation>Dividir el almacenamiento reservado dinámicamente en archivos de menos de 2GB</translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation>Dividir el almacenamiento de tamaño fijo en archivos de menos de 2GB</translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation>Límite de ejecución</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation>&lt;nobr&gt;%1%&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>Genérico, «%1»</translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation>Controlador genérico</translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>Denegar</translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>Permitir MVs</translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>Permitir todo</translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation>Adaptador %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -8929,15 +9492,15 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<source>Location</source>
- <translation>Localización</translation>
+ <translation type="obsolete">Localización</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Tipo (Formato)</translation>
+ <translation type="obsolete">Tipo (Formato)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Conectado a</translation>
+ <translation type="obsolete">Conectado a</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -9019,17 +9582,17 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Conectado a</translation>
+ <translation type="obsolete">Conectado a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Conectado a</translation>
+ <translation type="obsolete">Conectado a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Conectado a</translation>
+ <translation type="obsolete">Conectado a</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -9047,6 +9610,46 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
<source>All %1 images (%2)</source>
<translation>Todas las imágenes %1 (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation>Tipo:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation>Localización:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation>Formato:</translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation>Detalles de almacenamiento:</translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation>Conectado a:</translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation>&amp;Copiar...</translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation>&amp;Modificar...</translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation>Copiar un medio existente</translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation>Modificar los atributos del medio seleccionado</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>Cerra&amp;r</translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -9106,7 +9709,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Adaptadores de red</translation>
+ <translation type="obsolete">Adaptadores de red</translation>
</message>
</context>
<context>
@@ -9125,7 +9728,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<source>Displays the operating system type that you plan to install into this virtual machine (called a guest operating system).</source>
- <translation>Muestra el tipo de sistema operativo que planea instalar en esta máquina virtual (llamado sistema operativo huésped).</translation>
+ <translation>Muestra el tipo de sistema operativo que planea instalar en esta máquina virtual (llamado sistema operativo invitado).</translation>
</message>
<message>
<source>&amp;Version:</source>
@@ -9270,7 +9873,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;Are you sure you want to discard the saved state of the virtual machine &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;This operation is equivalent to resetting or powering off the machine without doing a proper shutdown of the guest OS.&lt;/p&gt;</source>
- <translation>&lt;p&gt;¿Está seguro de que desea descartar el estado guardado de la máquina virtual &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Esta operación es equivalente a reiniciar o apagar la máquina sin hacerlo desde el SO huésped apropiadamente.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;¿Está seguro de que desea descartar el estado guardado de la máquina virtual &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Esta operación es equivalente a reiniciar o apagar la máquina sin hacerlo desde el SO invitado apropiadamente.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Releasing this media image will detach it from the following virtual machine(s): &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Continue?&lt;/p&gt;</source>
@@ -9370,7 +9973,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<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;La máquina virtual informa que el SO huésped no soporta &lt;b&gt;integración del ratón&lt;/b&gt; en el modo de vídeo actual. Se necesita capturar el ratón (haciendo clic sobre la pantalla de la máquina virtual o presionando la tecla anfitrión) para poder usarlo dentro de SO huésped.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;La máquina virtual informa que el SO invitado no soporta &lt;b&gt;integración del ratón&lt;/b&gt; en el modo de vídeo actual. Se necesita capturar el ratón (haciendo clic sobre la pantalla de la máquina virtual o presionando la tecla anfitrión) para poder usarlo dentro de SO invitado.&lt;/p&gt;</translation>
</message>
<message>
<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>
@@ -9512,7 +10115,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<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;Fallo al eliminar la carpeta compartida &lt;b&gt;%1&lt;/b&gt; (apuntando a &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;) de la máquina virtual &lt;b&gt;%3&lt;/b&gt;. &lt;/p&gt;&lt;p&gt;Cierre todos los programas en el SO huésped que puedan estar usando este carpeta compartida y vuelva a intentarlo.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Fallo al eliminar la carpeta compartida &lt;b&gt;%1&lt;/b&gt; (apuntando a &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;) de la máquina virtual &lt;b&gt;%3&lt;/b&gt;. &lt;/p&gt;&lt;p&gt;Cierre todos los programas en el SO invitado que puedan estar usando este carpeta compartida y vuelva a intentarlo.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Could not find the VirtualBox Guest Additions CD image file &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt; or &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;Do you wish to download this CD image from the Internet?&lt;/p&gt;</source>
@@ -9540,7 +10143,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<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;La pantalla de la máquina virtual está optimizada para trabajar en modo de color &lt;b&gt;%1&amp;nbsp;bit&lt;/b&gt;. Sin embargo, el modo del pantalla de la máquina virtual está configurada como &lt;b&gt;%2&amp;nbsp;bit&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Abra el diálogo de las propiedades de pantalla en el SO huésped y seleccione un modo de color de &lt;b&gt;%3&amp;nbsp;bit&lt;/b&gt;, si esta disponible, para obtener el mejor rendimiento posible en el subsistema de vídeo virtual.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Nota&lt;/b&gt;: Algunos sistemas operativos, como OS/2, pueden en realidad estar trabajando en modo 32&amp;nbsp;bit pero informarlo como 24&amp;nbsp;bit (16 millones de colores). Puede tratar de seleccionar una calidad de color diferente para ver si este mensaje desaparece o simplemente deshabilitar este mensaje ahora si está seguro que el modo de color (%4&amp;nbsp;bit) no está disponible en el SO huésped.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;La pantalla de la máquina virtual está optimizada para trabajar en modo de color &lt;b&gt;%1&amp;nbsp;bit&lt;/b&gt;. Sin embargo, el modo del pantalla de la máquina virtual está configurada como &lt;b&gt;%2&amp;nbsp;bit&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Abra el diálogo de las propiedades de pantalla en el SO invitado y seleccione un modo de color de &lt;b&gt;%3&amp;nbsp;bit&lt;/b&gt;, si esta disponible, para obtener el mejor rendimiento posible en el subsistema de vídeo virtual.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Nota&lt;/b&gt;: Algunos sistemas operativos, como OS/2, pueden en realidad estar trabajando en modo 32&amp;nbsp;bit pero informarlo como 24&amp;nbsp;bit (16 millones de colores). Puede tratar de seleccionar una calidad de color diferente para ver si este mensaje desaparece o simplemente deshabilitar este mensaje ahora si está seguro que el modo de color (%4&amp;nbsp;bit) no está disponible en el SO invitado.&lt;/p&gt;</translation>
</message>
<message>
<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 VirualBox 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>
@@ -9549,7 +10152,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<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;No hay conectado ningún disco duro a la nueva máquina virtual. La máquina no podrá arrancar a menos que se conecte un disco duro con un sistema operativo huésped o algún otro medio arrancable. Esto se puede hacer desde el díalogo de configuración o desde el asistente de primera ejecución de VirtualBox.&lt;/p&gt;&lt;p&gt;¿Desea continuar?&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;No hay conectado ningún disco duro a la nueva máquina virtual. La máquina no podrá arrancar a menos que se conecte un disco duro con un sistema operativo invitado o algún otro medio arrancable. Esto se puede hacer desde el díalogo de configuración o desde el asistente de primera ejecución de VirtualBox.&lt;/p&gt;&lt;p&gt;¿Desea continuar?&lt;/p&gt;</translation>
</message>
<message>
<source>Failed to find license files in &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;.</source>
@@ -9723,11 +10326,11 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;Could not enter seamless mode due to insufficient guest video memory.&lt;/p&gt;&lt;p&gt;You should configure the virtual machine to have at least &lt;b&gt;%1&lt;/b&gt; of video memory.&lt;/p&gt;</source>
- <translation>&lt;p&gt;No se pudo activar el modo fluído debido a que no hay suficiente memoria de vídeo huésped.&lt;/p&gt;&lt;p&gt;Se debe configurar la máquina virtual con al menos &lt;b&gt;%1&lt;/b&gt; de memoria de vídeo.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;No se pudo activar el modo fluído debido a que no hay suficiente memoria de vídeo de invitado.&lt;/p&gt;&lt;p&gt;Se debe configurar la máquina virtual con al menos &lt;b&gt;%1&lt;/b&gt; de memoria de vídeo.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Could not switch the guest display to fullscreen mode due to insufficient guest video memory.&lt;/p&gt;&lt;p&gt;You should configure the virtual machine to have at least &lt;b&gt;%1&lt;/b&gt; of video memory.&lt;/p&gt;&lt;p&gt;Press &lt;b&gt;Ignore&lt;/b&gt; to switch to fullscreen mode anyway or press &lt;b&gt;Cancel&lt;/b&gt; to cancel the operation.&lt;/p&gt;</source>
- <translation>&lt;p&gt;No se pudo activar el modo pantalla completa debido que no hay suficiente memoria de vídeo huésped.&lt;/p&gt;&lt;p&gt;Se debe configurar la máquina virtual con al menos &lt;b&gt;%1&lt;/b&gt; de memoria de vídeo.&lt;/p&gt;&lt;p&gt;Presione &lt;b&gt;Ignorar&lt;/b&gt; para cambiar a modo pantalla completa de todos modos, o presione &lt;b&gt;Cancelar&lt;/b&gt; para cancelar la operación.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;No se pudo activar el modo pantalla completa debido que no hay suficiente memoria de vídeo de invitado.&lt;/p&gt;&lt;p&gt;Se debe configurar la máquina virtual con al menos &lt;b&gt;%1&lt;/b&gt; de memoria de vídeo.&lt;/p&gt;&lt;p&gt;Presione &lt;b&gt;Ignorar&lt;/b&gt; para cambiar a modo pantalla completa de todos modos, o presione &lt;b&gt;Cancelar&lt;/b&gt; para cancelar la operación.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Deleting this host-only network will remove the host-only interface this network is based on. Do you want to remove the (host-only network) interface &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;?&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; this interface may be in use by one or more virtual network adapters belonging to one of your VMs. After it is removed, these adapters will no longer be usable until you correct their settings by either choosing a different interface name or a different adapter attachment type.&lt;/p&gt;</source>
@@ -9739,7 +10342,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<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;Ha hecho &lt;b&gt;clic con el ratón&lt;/b&gt; dentro de la pantalla de la máquina virtual o ha presionado la &lt;b&gt;tecla anfitrión&lt;/b&gt;. Esto causará que la máquina virtual &lt;b&gt;capture&lt;/b&gt; el puntero del ratón (sólo si la integración del puntero del ratón no está soportada por el SO huésped) y el teclado del anfitrión, lo que hará que no estén disponibles para otras aplicaciones ejecutándose en la máquina anfitrión.&lt;/p&gt;&lt;p&gt;Puede presionar la &lt;b&gt;tecla anfitrión&lt;/b&gt; en cualquier momento para &lt;b&gt;liberar&lt;/b&gt; el teclado y el ratón (si están capturados) y devolverlos al modo de funcionamiento normal. La tecla anfitrión actualmente asignada se muestra en la barra de estado en la parte inferior de la ventana de la máquina virtual, al lado del icono&amp;nbsp;&lt;img src=:/hostkey_16px.png/&gt;. Este icono, junto con el icono del ratón situado al lado, indica el estado de captura actual del teclado y ratón.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Ha hecho &lt;b&gt;clic con el ratón&lt;/b&gt; dentro de la pantalla de la máquina virtual o ha presionado la &lt;b&gt;tecla anfitrión&lt;/b&gt;. Esto causará que la máquina virtual &lt;b&gt;capture&lt;/b&gt; el puntero del ratón (sólo si la integración del puntero del ratón no está soportada por el SO invitado) y el teclado del anfitrión, lo que hará que no estén disponibles para otras aplicaciones ejecutándose en la máquina anfitrión.&lt;/p&gt;&lt;p&gt;Puede presionar la &lt;b&gt;tecla anfitrión&lt;/b&gt; en cualquier momento para &lt;b&gt;liberar&lt;/b&gt; el teclado y el ratón (si están capturados) y devolverlos al modo de funcionamiento normal. La tecla anfitrión actualmente asignada se muestra en la barra de estado en la parte inferior de la ventana de la máquina virtual, al lado del icono&amp;nbsp;&lt;img src=:/hostkey_16px.png/&gt;. Este icono, junto con el icono del ratón situado al lado, indica el estado de captura actual del teclado y ratón.&lt;/p&gt;</translation>
</message>
<message>
<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>
@@ -9747,7 +10350,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<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;La máquina virtual informa que el SO huésped soporta &lt;b&gt;integración del ratón&lt;/b&gt;. Esto significa que no necesita &lt;i&gt;capturar&lt;/i&gt; el puntero del ratón para poder usarlo en su SO huésped -- todas las acciones del ratón que realice cuando el puntero del ratón esté sobre la pantalla de la máquina virtual son enviadas directamente al SO huésped. Si el ratón está actualmente capturado, se liberará automáticamente.&lt;/p&gt;&lt;p&gt;El icono del ratón en la barra de estado aparecerá como&amp;nbsp;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;para informarle que la integración del puntero del ratón está soportada por el SO huésped y está actualmente habilitada.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Nota&lt;/b&gt;: Algunas aplicaciones pueden funcionar incorrectamente en el modo de integración del puntero del ratón. Siempre puede desactivarlo para la sesión actual (y habilitarlo de nuevo) seleccionado la correspondiente acción de la barra de menú.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;La máquina virtual informa que el SO invitado soporta &lt;b&gt;integración del ratón&lt;/b&gt;. Esto significa que no necesita &lt;i&gt;capturar&lt;/i&gt; el puntero del ratón para poder usarlo en su SO invitado -- todas las acciones del ratón que realice cuando el puntero del ratón esté sobre la pantalla de la máquina virtual son enviadas directamente al SO invitado. Si el ratón está actualmente capturado, se liberará automáticamente.&lt;/p&gt;&lt;p&gt;El icono del ratón en la barra de estado aparecerá como&amp;nbsp;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;para informarle que la integración del puntero del ratón está soportada por el SO invitado y está actualmente habilitada.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Nota&lt;/b&gt;: Algunas aplicaciones pueden funcionar incorrectamente en el modo de integración del puntero del ratón. Siempre puede desactivarlo para la sesión actual (y habilitarlo de nuevo) seleccionado la correspondiente acción de la barra de menú.&lt;/p&gt;</translation>
</message>
<message>
<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;. 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>
@@ -9807,7 +10410,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</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 type="unfinished">&lt;p&gt;¡Hay una nueva versión de VirtualBox! La versión &lt;b&gt;%1&lt;/b&gt; se encuentra disponible en &lt;a href=&quot;http://www.virtualbox.org/&quot;&gt;virtualbox.org&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Puede descargar dicha versión directamente desde el siguiente enlace:&lt;/p&gt;&lt;p&gt;&lt;a href=%2&gt;%3&lt;/a&gt;&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;¡Hay una nueva versión de VirtualBox! La versión &lt;b&gt;%1&lt;/b&gt; se encuentra disponible en &lt;a href=&quot;http://www.virtualbox.org/&quot;&gt;virtualbox.org&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Puede descargar dicha versión directamente desde el siguiente enlace:&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>
@@ -9831,15 +10434,15 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>No se pudo acceder al USB en el sistema anfitrión. Esto puede ser porque el sistema de archivos USB (usbfs) ni DBus ni los servicios hal se encuentran disponibles. Para utilizar dispositivos USB en los sistemas huésped, debe corregir esto y reiniciar VirtualBox.</translation>
+ <translation type="obsolete">No se pudo acceder al USB en el sistema anfitrión. Esto puede ser porque el sistema de archivos USB (usbfs) ni DBus ni los servicios hal se encuentran disponibles. Para utilizar dispositivos USB en los sistemas huésped, debe corregir esto y reiniciar VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
- <translation>Está intentando apagar la máquina huésped con el botón de energía ACPI. Esto no es posible porque el sistema huésped no está utilizando el subsistema ACPI.</translation>
+ <translation>Está intentando apagar la máquina invitado con el botón de energía ACPI. Esto no es posible porque el sistema invitado no está utilizando el subsistema ACPI.</translation>
</message>
<message>
<source>&lt;p&gt;VT-x/AMD-V hardware acceleration has been enabled, but is not operational. Your 64-bit guest will fail to detect a 64-bit CPU and will not be able to boot.&lt;/p&gt;&lt;p&gt;Please ensure that you have enabled VT-x/AMD-V properly in the BIOS of your host computer.&lt;/p&gt;</source>
- <translation>&lt;p&gt;La aceleración VT-x/AMD-V ha sido habilitada, pero no es funcional. Su sistema huésped de 64-bit fallára al detectar una CPU de 64-bit y no podrá arrancar.&lt;/p&gt;&lt;b&gt;Compruebe que VT-x/AMD-V están habilitadas en la BIOS de su computadora anfitrión.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;La aceleración VT-x/AMD-V ha sido habilitada, pero no es funcional. Su sistema invitado de 64-bit fallára al detectar una CPU de 64-bit y no podrá arrancar.&lt;/p&gt;&lt;b&gt;Compruebe que VT-x/AMD-V están habilitadas en la BIOS de su computadora anfitrión.&lt;/p&gt;</translation>
</message>
<message>
<source>Close VM</source>
@@ -10030,7 +10633,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;VT-x/AMD-V hardware acceleration has been enabled, but is not operational. Certain guests (e.g. OS/2 and QNX) require this feature.&lt;/p&gt;&lt;p&gt;Please ensure that you have enabled VT-x/AMD-V properly in the BIOS of your host computer.&lt;/p&gt;</source>
- <translation>&lt;p&gt;La aceleración hardware VT-x/AMD-V ha sido habilitada, pero no es operacional. Ciertos huéspedes (pe. OS/2 y QNX) requieren esta característica.&lt;/p&gt;&lt;p&gt;Asegúrese de que ha habilitado VT-x/AMD-V apropiadamente en la BIOS de su computadora anfitrión.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;La aceleración hardware VT-x/AMD-V ha sido habilitada, pero no es operacional. Ciertos invitados (por ejemplo, OS/2 y QNX) requieren esta característica.&lt;/p&gt;&lt;p&gt;Asegúrese de que ha habilitado VT-x/AMD-V apropiadamente en la BIOS de su computadora anfitrión.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Invalid e-mail address or password specified.&lt;/p&gt;</source>
@@ -10058,7 +10661,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;¿Está seguro que desea restaurar la instantánea &lt;b&gt;%1&lt;/b&gt;? Esto causa que se pierda el estado actual de la máquina, el cual no podrá ser recuperado.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;¿Está seguro que desea restaurar la instantánea &lt;b&gt;%1&lt;/b&gt;? Esto causa que se pierda el estado actual de la máquina, el cual no podrá ser recuperado.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -10194,11 +10797,11 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;VT-x/AMD-V hardware acceleration is not available on your system. Your 64-bit guest will fail to detect a 64-bit CPU and will not be able to boot.</source>
- <translation>&lt;p&gt;La aceleración por hardware VT-x/AMD-V no se encuentra en su sistema. Por lo tanto el sistema huésped de 64 bits no podrá detectar una CPU de 64 bits y no podrá iniciarse.</translation>
+ <translation>&lt;p&gt;La aceleración por hardware VT-x/AMD-V no se encuentra en su sistema. Por lo tanto el sistema invitado de 64 bits no podrá detectar una CPU de 64 bits y no podrá iniciarse.</translation>
</message>
<message>
<source>&lt;p&gt;VT-x/AMD-V hardware acceleration is not available on your system. Certain guests (e.g. OS/2 and QNX) require this feature and will fail to boot without it.&lt;/p&gt;</source>
- <translation>&lt;p&gt;La aceleración por hardware VT-x/AMD-V no se encuentra en su sistema. Algunos sistemas huésped (por ejemplo: OS/2 o QNX) requieren esta funcionalidad y no podrán iniciar sin ella.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;La aceleración por hardware VT-x/AMD-V no se encuentra en su sistema. Algunos sistemas invitados (por ejemplo, OS/2 o QNX) requieren esta funcionalidad y no podrán iniciar sin ella.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Deleting the snapshot %1 will temporarily need more disk space. In the worst case the size of image %2 will grow by %3, however on this filesystem there is only %4 free.&lt;/p&gt;&lt;p&gt;Running out of disk space during the merge operation can result in corruption of the image and the VM configuration, i.e. loss of the VM and its data.&lt;/p&gt;&lt;p&gt;You may continue with deleting the snapshot at your own risk.&lt;/p&gt;</source>
@@ -10206,19 +10809,19 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;Could not change the guest screen to this host screen due to insufficient guest video memory.&lt;/p&gt;&lt;p&gt;You should configure the virtual machine to have at least &lt;b&gt;%1&lt;/b&gt; of video memory.&lt;/p&gt;</source>
- <translation>&lt;p&gt;No se pudo cambiar la pantalla huésped a esta pantalla anfitrión debido a la memoria de vídeo insuficiente en el huésped.&lt;/p&gt;&lt;p&gt;Debería configurar la máquina virtual con al menos &lt;b&gt;%1&lt;/b&gt; de memoria de vídeo.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;No se pudo cambiar la pantalla invitado a esta pantalla anfitrión debido a la memoria de vídeo insuficiente del invitado.&lt;/p&gt;&lt;p&gt;Debería configurar la máquina virtual con al menos &lt;b&gt;%1&lt;/b&gt; de memoria de vídeo.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Could not change the guest screen to this host screen due to insufficient guest video memory.&lt;/p&gt;&lt;p&gt;You should configure the virtual machine to have at least &lt;b&gt;%1&lt;/b&gt; of video memory.&lt;/p&gt;&lt;p&gt;Press &lt;b&gt;Ignore&lt;/b&gt; to switch the screen anyway or press &lt;b&gt;Cancel&lt;/b&gt; to cancel the operation.&lt;/p&gt;</source>
- <translation>&lt;p&gt;No se pudo cambiar la pantalla huésped a esta pantalla anfitrión debido a la insuficiente memoria de vídeo en el huésped.&lt;/p&gt;&lt;p&gt;Debería configurar la máquina virtual con al menos &lt;b&gt;%1&lt;/b&gt; de memoria de vídeo.&lt;/p&gt;&lt;p&gt;Presione &lt;b&gt;Ignorar&lt;/b&gt; para cambiarla de cualquier modo, o &lt;b&gt;Cancelar&lt;/b&gt; para cancelar la operación .&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;No se pudo cambiar la pantalla invitado a esta pantalla anfitrión debido a la insuficiente memoria de vídeo del invitado.&lt;/p&gt;&lt;p&gt;Debería configurar la máquina virtual con al menos &lt;b&gt;%1&lt;/b&gt; de memoria de vídeo.&lt;/p&gt;&lt;p&gt;Presione &lt;b&gt;Ignorar&lt;/b&gt; para cambiarla de cualquier modo, o &lt;b&gt;Cancelar&lt;/b&gt; para cancelar la operación .&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Can not switch the guest display to fullscreen mode. You have more virtual screens configured than physical screens are attached to your host.&lt;/p&gt;&lt;p&gt;Please either lower the virtual screens in your VM configuration or attach additional screens to your host.&lt;/p&gt;</source>
- <translation>&lt;p&gt;No se puede cambiar la pantalla huésped a modo pantalla completa. Hay configuradas más pantallas virtuales que pantallas físicas conectadas al anfitrión.&lt;/p&gt;&lt;p&gt;Reduzca el número de pantallas virtuales en la configuración de la MV o conecte más pantallas físicas al sistema anfitrión.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;No se puede cambiar la pantalla invitado a modo pantalla completa. Hay configuradas más pantallas virtuales que pantallas físicas conectadas al anfitrión.&lt;/p&gt;&lt;p&gt;Reduzca el número de pantallas virtuales en la configuración de la MV o conecte más pantallas físicas al sistema anfitrión.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Can not switch the guest display to seamless mode. You have more virtual screens configured than physical screens are attached to your host.&lt;/p&gt;&lt;p&gt;Please either lower the virtual screens in your VM configuration or attach additional screens to your host.&lt;/p&gt;</source>
- <translation>&lt;p&gt;No se puede cambiar la pantalla huésped a modo fluído. Hay configuradas más pantallas virtuales que pantallas físicas conectadas al anfitrión.&lt;/p&gt;&lt;p&gt;Reduzca el número de pantallas virtuales en la configuración de la MV o conecte más pantallas físicas al sistema anfitrión.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;No se puede cambiar la pantalla invitado a modo fluído. Hay configuradas más pantallas virtuales que pantallas físicas conectadas al anfitrión.&lt;/p&gt;&lt;p&gt;Reduzca el número de pantallas virtuales en la configuración de la MV o conecte más pantallas físicas al sistema anfitrión.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Could not find the VirtualBox User Manual &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;Do you wish to download this file from the Internet?&lt;/p&gt;</source>
@@ -10322,7 +10925,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message numerus="yes">
<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>
+ <translation type="unfinished">
<numerusform>&lt;p&gt;La máquina virtual &lt;b&gt;%1&lt;/b&gt; está actualmente en un estado guardado.&lt;/p&gt;&lt;p&gt;Si continua el estado de ejecución de la máquina exportada será descartado. Note que la máquina existente no se cambia.&lt;/p&gt;</numerusform>
<numerusform>&lt;p&gt;Las máquinas virtuales &lt;b&gt;%1&lt;/b&gt; están actualmente en un estado guardado.&lt;/p&gt;&lt;p&gt;Si continua el estado de ejecución de las máquinas exportadas será descartado. Note que las máquinas existentes no se cambian.&lt;/p&gt;</numerusform>
</translation>
@@ -10357,7 +10960,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">Lo sentimos, ha sucedido un error genérico.</translation>
+ <translation>Lo sentimos, ha sucedido un error genérico.</translation>
</message>
<message>
<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>
@@ -10446,7 +11049,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>La eliminación de todos los archivos pertenecientes a la MV está actualmente deshabilitado en Windows/x64 para prevenir un fallo. Esto será corregido en la siguiente versión.</translation>
+ <translation type="obsolete">La eliminación de todos los archivos pertenecientes a la MV está actualmente deshabilitado en Windows/x64 para prevenir un fallo. Esto será corregido en la siguiente versión.</translation>
</message>
<message>
<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>
@@ -10454,7 +11057,71 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<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>&lt;p&gt;USB 2.0 está habilitado para esta máquina virtual. Sin embargo esto requiere que &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; esté instalado.&lt;/p&gt;&lt;p&gt;Instale el Paquete de Extensiones desde el sitio de descargas de VirtualBox. Después de esto podrá rehabilitar USB 2.0. Por el momento será deshabilitado a menos que cancele los cambios de preferencias actuales.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;USB 2.0 está habilitado para esta máquina virtual. Sin embargo esto requiere que &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; esté instalado.&lt;/p&gt;&lt;p&gt;Instale el Paquete de Extensiones desde el sitio de descargas de VirtualBox. Después de esto podrá rehabilitar USB 2.0. Por el momento será deshabilitado a menos que cancele los cambios de preferencias actuales.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>Fallo al registrar la máquina virtual &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;La configuración de la máquina fue cambiada mientras estaba editándola. Tiene cambios sin guardar.&lt;/p&gt;&lt;p&gt;¿Quiere recargar la configuración cambiada o quiere mantener sus propios cambios?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation>Recargar configuración</translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation>Mantener cambios</translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation>El estado de la máquina virtual que está editando ha cambiado. Solo la configuración que era editable en tiempo de ejecución será guardada cuando presione Aceptar. Todos los demás cambios se perderán.</translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>Fallo al clonar la máquina virtual &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Está apunto de restaurar la instantánea &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Puede crear una instantánea del estado actual de la máquina virtual primero marcando la caja de abajo; si no hace esto el estado actual se perderá de forma definitiva. ¿Quiere continuar?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation>Crear una instantánea del estado actual de la máquina</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;¿Quire restaurar la instantánea &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Error cambiando el tipo de medio de &lt;b&gt;%1&lt;/b&gt; a &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <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>&lt;p&gt;USB 2.0 está actualmente habilitado para esta máquina virtual. Sin embargo, esto requiere que &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; esté instalado.&lt;/p&gt;&lt;p&gt;Instale el paquete de extensiones desde el sitio de descargas de VirtualBox. Después podrá rehabilitar USB 2.0. Será deshabilitado mientras tanto a menos que cancele la configuración actual.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <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>No se puede cargar el servicio Host USB Proxy (VERR_FILE_NOT_FOUND). El servicio podría no estar instalado en la máquina anfitrión</translation>
+ </message>
+ <message>
+ <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>VirtualBox no tiene permisos para acceder a los dispositivos USB. Puede cambiar esto añadiendo su usuario al grupo «vboxusers». Mire el manual de usuario para una explicación más detallada</translation>
+ </message>
+ <message>
+ <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>VirtualBox no tiene permisos para acceder a los dispositivos USB. Puede cambiar esto permitiendo a su usuario acceder al directorio y archivos «usbfs». Mire el manual de usuario para una explicación más detallada</translation>
+ </message>
+ <message>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation>El servicio USB Proxy no ha sido portado todavía a este anfitrión</translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation>No se puede cargar el servicio Host USB Proxy</translation>
</message>
</context>
<context>
@@ -10580,7 +11247,7 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Carpetas compartidas</translation>
+ <translation type="obsolete">Carpetas compartidas</translation>
</message>
<message>
<source>OK</source>
@@ -10711,11 +11378,11 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
</message>
<message>
<source>D&amp;iscard</source>
- <translation>&amp;Descartar</translation>
+ <translation type="obsolete">&amp;Descartar</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Descartar</translation>
+ <translation>Descartar</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -11009,6 +11676,18 @@ volver al idioma por omisión del sistema.&lt;/qt&gt;
<source>Show Statusbar</source>
<translation>Mostrar barra de estado</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation>Cl&amp;onar...</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>Clonar la máquina virtual seleccionada</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation>&amp;Descartar el estado guardado</translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -11465,6 +12144,14 @@ Esta funcionalidad requiere &quot;Guest Additions&quot; instalado.&lt;/qt&gt;</t
<source> (%1 ago)</source>
<translation> (hace %1)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation>&amp;Clonar...</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>Clonar la máquina virtual seleccionada</translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
@@ -11936,7 +12623,7 @@ cualquier valor.&lt;/qt&gt;</translation>
</message>
<message>
<source>Guest OS Type</source>
- <translation>Tipo de SO huésped</translation>
+ <translation>Tipo de SO invitado</translation>
</message>
<message>
<source>Hard Disk Statistics</source>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_eu.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_eu.ts
index 4f7034c51..8bfe1f628 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_eu.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_eu.ts
@@ -479,11 +479,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">&amp;Ezarpenak...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -649,11 +730,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation type="unfinished">%1 Moldagailua</translation>
@@ -777,6 +853,26 @@
<comment>details report</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -873,6 +969,10 @@
<source>Restore Defaults</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1124,6 +1224,10 @@
<source>Cancel</source>
<translation type="obsolete">Utzi</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">Abiarazi</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1197,41 +1301,6 @@
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Orokorra</translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished"> Hizkuntza </translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Sarea</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1634,6 +1703,57 @@
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1703,23 +1823,23 @@
</message>
<message>
<source>Left Shift</source>
- <translation>Esker Shift</translation>
+ <translation type="obsolete">Esker Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Eskuin Shift</translation>
+ <translation type="obsolete">Eskuin Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Ezker Ktrl</translation>
+ <translation type="obsolete">Ezker Ktrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Eskuin Ktrl</translation>
+ <translation type="obsolete">Eskuin Ktrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Ezker Alt</translation>
+ <translation type="obsolete">Ezker Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -1868,6 +1988,10 @@
<source>Restore Defaults</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2006,11 +2130,6 @@
<translation type="obsolete">&lt;hr&gt;VRDP Zerbitzaria %1 atakan entzuten ari da</translation>
</message>
<message>
- <source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
- <comment>Virtualization Stuff LED</comment>
- <translation></translation>
- </message>
- <message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation></translation>
@@ -2031,6 +2150,11 @@
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2209,7 +2333,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2355,6 +2483,10 @@
<source>Show At &amp;Top Of Screen</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2422,10 +2554,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Generates a new random MAC address.</source>
<translation type="unfinished">Ausazko MAC berri bat sortzen du.</translation>
</message>
@@ -2493,6 +2621,42 @@
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -2831,10 +2995,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
@@ -3070,6 +3230,60 @@
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3243,6 +3457,32 @@
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3368,7 +3608,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -3482,6 +3722,21 @@
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3527,7 +3782,7 @@
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Disko Birtual Berria Sortu</translation>
@@ -3625,7 +3880,7 @@ disko gogor birtual tamaina bezala&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Laburpena</translation>
+ <translation type="unfinished">Laburpena</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -3641,17 +3896,17 @@ disko gogor birtual tamaina bezala&lt;/p&gt;</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Hautatu fitxategi bat disko gogor berriaren irudi fitxategiarentzat</translation>
+ <translation type="unfinished">Hautatu fitxategi bat disko gogor berriaren irudi fitxategiarentzat</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Kokalekuak</translation>
+ <translation type="unfinished">Kokalekuak</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Tamaina</translation>
+ <translation type="unfinished">Tamaina</translation>
</message>
<message>
<source>Cancel</source>
@@ -3661,111 +3916,226 @@ disko gogor birtual tamaina bezala&lt;/p&gt;</translation>
<source>Storage Type</source>
<translation type="obsolete">Biltegiratze Mota</translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage1</name>
<message>
- <source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation type="unfinished">Ongietorri Disko Gogor Birtual Berriak Sortzeko Morroira!</translation>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <source>Create</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage2</name>
<message>
- <source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
+ <source>Copy Virtual Disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Storage Type</source>
- <translation type="unfinished">Biltegiratze Mota</translation>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Dynamically expanding storage</source>
+ <source>Welcome to the virtual disk copying wizard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Fixed-size storage</source>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hard Disk Storage Type</source>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage3</name>
<message>
- <source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Location</source>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Size</source>
+ <source>Welcome to the virtual disk creation wizard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Virtual Disk Location and Size</source>
- <translation type="unfinished">Disko Birtual Kokapen eta Tamaina</translation>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Select a file for the new hard disk image file</source>
- <translation type="unfinished">Hautatu fitxategi bat disko gogor berriaren irudi fitxategiarentzat</translation>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Hard disk images (*.vdi)</source>
- <translation type="unfinished">Disko gogor irudiak (*.vdi)</translation>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage4</name>
<message>
- <source>You are going to create a new virtual hard disk with the following parameters:</source>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary</source>
- <translation type="unfinished">Laburpena</translation>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>%1 B</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Type</source>
+ <source>File type</source>
<comment>summary</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Location</source>
+ <source>Details</source>
<comment>summary</comment>
- <translation type="unfinished">Kokalekuak</translation>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
<message>
- <source>Size</source>
- <comment>summary</comment>
- <translation type="unfinished">Tamaina</translation>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
+ <message>
+ <source>Welcome to the Create New Virtual Disk Wizard!</source>
+ <translation type="obsolete">Ongietorri Disko Gogor Birtual Berriak Sortzeko Morroira!</translation>
</message>
<message>
- <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
+ <name>UINewHDWzdPage2</name>
+ <message>
+ <source>Storage Type</source>
+ <translation type="obsolete">Biltegiratze Mota</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWzdPage3</name>
+ <message>
+ <source>Virtual Disk Location and Size</source>
+ <translation type="obsolete">Disko Birtual Kokapen eta Tamaina</translation>
+ </message>
+ <message>
+ <source>Select a file for the new hard disk image file</source>
+ <translation type="obsolete">Hautatu fitxategi bat disko gogor berriaren irudi fitxategiarentzat</translation>
+ </message>
+ <message>
+ <source>Hard disk images (*.vdi)</source>
+ <translation type="obsolete">Disko gogor irudiak (*.vdi)</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWzdPage4</name>
+ <message>
+ <source>Summary</source>
+ <translation type="obsolete">Laburpena</translation>
+ </message>
+ <message>
+ <source>Location</source>
+ <comment>summary</comment>
+ <translation type="obsolete">Kokalekuak</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <comment>summary</comment>
+ <translation type="obsolete">Tamaina</translation>
+ </message>
+</context>
+<context>
<name>UINewVMWzd</name>
<message>
<source>Create New Virtual Machine</source>
@@ -3951,6 +4321,10 @@ gogorrak erantsi ditzakezu.&lt;/p&gt;</translation>
<source>Cancel</source>
<translation type="obsolete">Utzi</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4172,6 +4546,96 @@ gogorrak erantsi ditzakezu.&lt;/p&gt;</translation>
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Orokorra</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation type="unfinished"> Hizkuntza </translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Sarea</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Orokorra</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished">Audioa</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Sarea</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation type="unfinished">Serie Atakak</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation type="unfinished">Partekatutako Karpetak</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -4310,81 +4774,6 @@ gogorrak erantsi ditzakezu.&lt;/p&gt;</translation>
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Orokorra</translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished">Audioa</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Sarea</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished">Serie Atakak</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished">Partekatutako Karpetak</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -4598,6 +4987,14 @@ gogorrak erantsi ditzakezu.&lt;/p&gt;</translation>
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -6292,7 +6689,7 @@ gogorrak erantsi ditzakezu.&lt;/p&gt;</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation type="unfinished">%1 Moldagailua</translation>
+ <translation type="obsolete">%1 Moldagailua</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Attached to:&amp;nbsp;&amp;nbsp;%1&lt;/nobr&gt;</source>
@@ -6603,21 +7000,11 @@ gogorrak erantsi ditzakezu.&lt;/p&gt;</translation>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>SAS</source>
<comment>StorageBus</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation type="unfinished"></translation>
@@ -6807,6 +7194,61 @@ gogorrak erantsi ditzakezu.&lt;/p&gt;</translation>
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">%1 Moldagailua</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7321,15 +7763,11 @@ sistemako lehenetsiriko hizkuntza berrezartzeko.&lt;/qt&gt;
</message>
<message>
<source>Location</source>
- <translation type="unfinished">Kokalekuak</translation>
- </message>
- <message>
- <source>Type (Format)</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Kokalekuak</translation>
</message>
<message>
<source>Attached to</source>
- <translation type="unfinished">Honi erantsia</translation>
+ <translation type="obsolete">Honi erantsia</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -7407,17 +7845,17 @@ sistemako lehenetsiriko hizkuntza berrezartzeko.&lt;/qt&gt;
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation type="unfinished">Honi erantsia</translation>
+ <translation type="obsolete">Honi erantsia</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation type="unfinished">Honi erantsia</translation>
+ <translation type="obsolete">Honi erantsia</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation type="unfinished">Honi erantsia</translation>
+ <translation type="obsolete">Honi erantsia</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -7435,6 +7873,46 @@ sistemako lehenetsiriko hizkuntza berrezartzeko.&lt;/qt&gt;
<source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -7483,13 +7961,6 @@ sistemako lehenetsiriko hizkuntza berrezartzeko.&lt;/qt&gt;
</message>
</context>
<context>
- <name>VBoxNetworkDialog</name>
- <message>
- <source>Network Adapters</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxOSTypeSelectorWidget</name>
<message>
<source>Operating &amp;System:</source>
@@ -8140,10 +8611,6 @@ sistemako lehenetsiriko hizkuntza berrezartzeko.&lt;/qt&gt;
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
<translation type="unfinished"></translation>
</message>
@@ -8308,10 +8775,6 @@ sistemako lehenetsiriko hizkuntza berrezartzeko.&lt;/qt&gt;
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restore</source>
<translation type="unfinished"></translation>
</message>
@@ -8648,15 +9111,75 @@ sistemako lehenetsiriko hizkuntza berrezartzeko.&lt;/qt&gt;
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -8675,7 +9198,7 @@ sistemako lehenetsiriko hizkuntza berrezartzeko.&lt;/qt&gt;
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Partekatutako Karpetak</translation>
+ <translation type="obsolete">Partekatutako Karpetak</translation>
</message>
<message>
<source>Cancel</source>
@@ -8802,11 +9325,11 @@ sistemako lehenetsiriko hizkuntza berrezartzeko.&lt;/qt&gt;
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Ba&amp;ztertu</translation>
+ <translation type="obsolete">Ba&amp;ztertu</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Baztertu</translation>
+ <translation type="unfinished">Baztertu</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -9072,6 +9595,18 @@ sistemako lehenetsiriko hizkuntza berrezartzeko.&lt;/qt&gt;
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -9403,6 +9938,14 @@ Linux SE batetatik atzitzeko. Ezaugarri honek Bezero Gehigarriak behar ditu.&lt;
<source> (%1 ago)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fi.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fi.ts
index 73d90fd5c..4d46cbe30 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fi.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fi.ts
@@ -500,11 +500,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">&amp;Asetukset...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -670,11 +751,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation type="unfinished">Sovitin %1</translation>
@@ -798,6 +874,26 @@
<comment>details report</comment>
<translation type="unfinished">Kuvaus</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -920,6 +1016,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Export &gt;</source>
<translation type="obsolete">&amp;Vie &gt;</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1198,6 +1298,10 @@ p, li { white-space: pre-wrap; }
<source>Cancel</source>
<translation type="obsolete">Peru</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">Käynnistä</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1271,41 +1375,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Yleiset</translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished">Syöte</translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished">Päivitä</translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished">Kieli</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Verkko</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished">VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1730,6 +1799,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1799,23 +1919,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Vasen vaihtonäppäin</translation>
+ <translation type="obsolete">Vasen vaihtonäppäin</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Oikea vaihtonäppäin</translation>
+ <translation type="obsolete">Oikea vaihtonäppäin</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Vasen Ctrl</translation>
+ <translation type="obsolete">Vasen Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Oikea Ctrl</translation>
+ <translation type="obsolete">Oikea Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Vasen Alt</translation>
+ <translation type="obsolete">Vasen Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2032,6 +2152,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Tuo &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2174,11 +2298,6 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">&lt;hr&gt;VRDP-palvelin kuuntelee porttissa %1</translation>
</message>
<message>
- <source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
- <comment>Virtualization Stuff LED</comment>
- <translation></translation>
- </message>
- <message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation></translation>
@@ -2199,6 +2318,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2381,7 +2505,11 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2619,6 +2747,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2723,10 +2855,6 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished">&amp;Nimi:</translation>
</message>
<message>
- <source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Open extended settings dialog for current attachment type.</source>
<translation type="obsolete">Avaa tämänhetkisen liitostavan lisäasetukset.</translation>
</message>
@@ -2822,6 +2950,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3339,10 +3503,6 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
@@ -3578,6 +3738,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3755,6 +3969,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3880,7 +4120,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished">&lt;nobr&gt;Tila: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -3994,6 +4234,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4039,7 +4294,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Luo uusi virtuaalilevy</translation>
@@ -4112,7 +4367,7 @@ levykuvan sijainnin ja nimen, tai kirjoita tiedostonimi tekstikenttään.&lt;/p&
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Yhteenveto</translation>
+ <translation type="unfinished">Yhteenveto</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4124,7 +4379,7 @@ levykuvan sijainnin ja nimen, tai kirjoita tiedostonimi tekstikenttään.&lt;/p&
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Valitse uuden kiintolevyn levykuvan tiedosto</translation>
+ <translation type="unfinished">Valitse uuden kiintolevyn levykuvan tiedosto</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -4146,12 +4401,12 @@ levykuvan sijainnin ja nimen, tai kirjoita tiedostonimi tekstikenttään.&lt;/p&
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Sijainti</translation>
+ <translation type="unfinished">Sijainti</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Koko</translation>
+ <translation type="unfinished">Koko</translation>
</message>
<message>
<source>Bytes</source>
@@ -4210,15 +4465,183 @@ levykuvan sijainnin ja nimen, tai kirjoita tiedostonimi tekstikenttään.&lt;/p&
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Jos ylläolevat asetukset ovat oikein, paina &lt;b&gt;Viimeistele&lt;/b&gt;-painiketta. Uusi kiintolevy luodaan kun olet tämän jälkeen.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;Sijainti</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Koko</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation type="unfinished">Tervetuloa uuden virtuaalilevyn ohjattuun luomiseen!</translation>
+ <translation type="obsolete">Tervetuloa uuden virtuaalilevyn ohjattuun luomiseen!</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <source>Choose a virtual hard disk file...</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -4226,92 +4649,80 @@ levykuvan sijainnin ja nimen, tai kirjoita tiedostonimi tekstikenttään.&lt;/p&
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Valitse luotavan virtuaalikiintolevyn tyyppi.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Dynaamisesti kasvava levykuva&lt;/b&gt; käyttää aluksi hyvin vähän isännän levytilaa. Se kasvaa tarpeen mukaan annettuun kokoon saakka, kun asiakasvirtuaalikone käyttää levytilaa.&lt;/p&gt;&lt;p&gt;Kiinteäkokoinen levykuva&lt;/p&gt; ei kasva. Se tallennetaan tiedostoon, jonka koko on lähes sama kuin virtuaalisen kiintolevyn. Kiinteäkokoisen kiintolevyn luonti voi kestää pitkään, riippuen levykuvan koosta ja isäntäkoneen kiintolevyjen kirjoitusnopeudesta.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Valitse luotavan virtuaalikiintolevyn tyyppi.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Dynaamisesti kasvava levykuva&lt;/b&gt; käyttää aluksi hyvin vähän isännän levytilaa. Se kasvaa tarpeen mukaan annettuun kokoon saakka, kun asiakasvirtuaalikone käyttää levytilaa.&lt;/p&gt;&lt;p&gt;Kiinteäkokoinen levykuva&lt;/p&gt; ei kasva. Se tallennetaan tiedostoon, jonka koko on lähes sama kuin virtuaalisen kiintolevyn. Kiinteäkokoisen kiintolevyn luonti voi kestää pitkään, riippuen levykuvan koosta ja isäntäkoneen kiintolevyjen kirjoitusnopeudesta.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation type="unfinished">Tallennustyyppi</translation>
+ <translation type="obsolete">Tallennustyyppi</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation type="unfinished">&amp;Dynaamisesti kasvava levykuva</translation>
+ <translation type="obsolete">&amp;Dynaamisesti kasvava levykuva</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation type="unfinished">&amp;Kiinteäkokoinen levykuva</translation>
+ <translation type="obsolete">&amp;Kiinteäkokoinen levykuva</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation type="unfinished">Kiintolevyn tallennustyyppi</translation>
+ <translation type="obsolete">Kiintolevyn tallennustyyppi</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Napista &lt;b&gt;Valitse&lt;/b&gt; voit valita kiintolevyn tietojen tallennukseen käytetyn tiedoston sijainnin. Voit myös syöttää tiedostonimen kenttään.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Napista &lt;b&gt;Valitse&lt;/b&gt; voit valita kiintolevyn tietojen tallennukseen käytetyn tiedoston sijainnin. Voit myös syöttää tiedostonimen kenttään.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation type="unfinished">&amp;Sijainti</translation>
+ <translation type="obsolete">&amp;Sijainti</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Valitse virtuaalisen kiintolevyn koko megatavuina. Tämä koko näytetään asiakaskäyttöjärjestelmälle kiintolevyn kokona.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Valitse virtuaalisen kiintolevyn koko megatavuina. Tämä koko näytetään asiakaskäyttöjärjestelmälle kiintolevyn kokona.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation type="unfinished">&amp;Koko</translation>
+ <translation type="obsolete">&amp;Koko</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation type="unfinished">Virtuaalilevyn sijainti ja koko</translation>
+ <translation type="obsolete">Virtuaalilevyn sijainti ja koko</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="unfinished">Valitse uuden kiintolevyn levykuvan tiedosto</translation>
+ <translation type="obsolete">Valitse uuden kiintolevyn levykuvan tiedosto</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation type="unfinished">Kiintolevyjen levykuvat (*.vdi)</translation>
- </message>
- <message>
- <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Kiintolevyjen levykuvat (*.vdi)</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation type="unfinished">Olet luomassa uutta virtuaalista kiintolevyä seuraavilla asetuksilla:</translation>
+ <translation type="obsolete">Olet luomassa uutta virtuaalista kiintolevyä seuraavilla asetuksilla:</translation>
</message>
<message>
<source>Summary</source>
- <translation type="unfinished">Yhteenveto</translation>
- </message>
- <message>
- <source>%1 B</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Yhteenveto</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation type="unfinished">Tyyppi</translation>
+ <translation type="obsolete">Tyyppi</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="unfinished">Sijainti</translation>
+ <translation type="obsolete">Sijainti</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="unfinished">Koko</translation>
- </message>
- <message>
- <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Koko</translation>
</message>
</context>
<context>
@@ -4503,6 +4914,10 @@ Kaikki VirtualBoxin komponentit käyttävät sitä koneen tunnistukseen.&lt;/p&g
<source>Boot Hard &amp;Disk (Primary Master)</source>
<translation type="obsolete">Käynnistys&amp;kiintolevy (ensisijainen isäntä)</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4732,6 +5147,96 @@ Kaikki VirtualBoxin komponentit käyttävät sitä koneen tunnistukseen.&lt;/p&g
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Yleiset</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation type="unfinished">Syöte</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished">Päivitä</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation type="unfinished">Kieli</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Verkko</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation type="unfinished">VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Yleiset</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation type="unfinished">Levykuvat</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished">Ääni</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Verkko</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation type="unfinished">Portit</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation type="unfinished">Sarjaportit</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation type="unfinished">Rinnakkaisportit</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation type="unfinished">Jaetut kansiot</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished">%1 - %2</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -4870,81 +5375,6 @@ Kaikki VirtualBoxin komponentit käyttävät sitä koneen tunnistukseen.&lt;/p&g
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Yleiset</translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished">Levykuvat</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished">Ääni</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Verkko</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished">Portit</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished">Sarjaportit</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished">Rinnakkaisportit</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished">Jaetut kansiot</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished">%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5163,6 +5593,14 @@ Version %1</source>
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -6968,7 +7406,7 @@ Version %1</source>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Sovitin %1</translation>
+ <translation type="obsolete">Sovitin %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -7318,21 +7756,11 @@ Version %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>SAS</source>
<comment>StorageBus</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation type="unfinished"></translation>
@@ -7522,6 +7950,61 @@ Version %1</source>
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Sovitin %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7991,15 +8474,15 @@ Version %1</source>
</message>
<message>
<source>Location</source>
- <translation>Sijainti</translation>
+ <translation type="obsolete">Sijainti</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Tyyppi (muoto)</translation>
+ <translation type="obsolete">Tyyppi (muoto)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Liitetty kohteeseen</translation>
+ <translation type="obsolete">Liitetty kohteeseen</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -8081,17 +8564,17 @@ Version %1</source>
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation type="unfinished">Liitetty kohteeseen</translation>
+ <translation type="obsolete">Liitetty kohteeseen</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation type="unfinished">Liitetty kohteeseen</translation>
+ <translation type="obsolete">Liitetty kohteeseen</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation type="unfinished">Liitetty kohteeseen</translation>
+ <translation type="obsolete">Liitetty kohteeseen</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -8109,6 +8592,46 @@ Version %1</source>
<source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -8165,13 +8688,6 @@ Version %1</source>
</message>
</context>
<context>
- <name>VBoxNetworkDialog</name>
- <message>
- <source>Network Adapters</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxOSTypeSelectorWidget</name>
<message>
<source>Operating &amp;System:</source>
@@ -8260,7 +8776,7 @@ Version %1</source>
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Isäntäjärjestelmän USB-laitteisiin ei päästä käsiksi, koska USB-tiedostojärjestelmä (usbfs) tai DBUS -ja HAL-palvelut eivät ole käytettävissä. Jos haluat käyttää isäntäkoneen USB-laitteita virtuaalikoneista, sinun täytyy korjata tämä ongelma ja käynnistää VirtualBox uudestaan.</translation>
+ <translation type="obsolete">Isäntäjärjestelmän USB-laitteisiin ei päästä käsiksi, koska USB-tiedostojärjestelmä (usbfs) tai DBUS -ja HAL-palvelut eivät ole käytettävissä. Jos haluat käyttää isäntäkoneen USB-laitteita virtuaalikoneista, sinun täytyy korjata tämä ongelma ja käynnistää VirtualBox uudestaan.</translation>
</message>
<message>
<source>Failed to access the USB subsystem.</source>
@@ -9019,10 +9535,6 @@ Version %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restore</source>
<translation type="unfinished"></translation>
</message>
@@ -9365,15 +9877,75 @@ Version %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
- <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -9432,7 +10004,7 @@ Version %1</source>
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Jaetut kansiot</translation>
+ <translation type="obsolete">Jaetut kansiot</translation>
</message>
<message>
<source>OK</source>
@@ -9563,11 +10135,11 @@ Version %1</source>
</message>
<message>
<source>D&amp;iscard</source>
- <translation>H&amp;ylkää</translation>
+ <translation type="obsolete">H&amp;ylkää</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Hylkää</translation>
+ <translation type="unfinished">Hylkää</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -9837,6 +10409,18 @@ Version %1</source>
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -10207,6 +10791,14 @@ to access it from a Linux OS. This feature requires Guest Additions.&lt;/qt&gt;<
<source> (%1 ago)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fr.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fr.ts
index 76243dee8..5501c975b 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fr.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fr.ts
@@ -467,12 +467,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>Fenêtre &amp;Session</translation>
+ <translation type="obsolete">Fenêtre &amp;Session</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>&amp;Activer bureau à distance</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">&amp;Configuration...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -638,7 +723,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Réseau VDE, &apos;%1&apos; </translation>
+ <translation type="obsolete">Réseau VDE, &apos;%1&apos; </translation>
</message>
<message>
<source>Adapter %1</source>
@@ -764,6 +849,26 @@
<comment>details report</comment>
<translation>Description</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -800,6 +905,10 @@
<source>Restore Defaults</source>
<translation>Valeurs par défaut</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1009,6 +1118,10 @@
<source>First Run Wizard</source>
<translation>Assistant au premier lancement</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1083,41 +1196,6 @@
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Général</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Entrée</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Mise à jour</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Langue</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Réseau</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Extensions</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1546,6 +1624,57 @@
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1615,23 +1744,23 @@
</message>
<message>
<source>Left Shift</source>
- <translation>Maj gauche</translation>
+ <translation type="obsolete">Maj gauche</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Maj droite</translation>
+ <translation type="obsolete">Maj droite</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Ctrl gauche</translation>
+ <translation type="obsolete">Ctrl gauche</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Ctrl droite</translation>
+ <translation type="obsolete">Ctrl droite</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Alt gauche</translation>
+ <translation type="obsolete">Alt gauche</translation>
</message>
<message>
<source>Right Alt</source>
@@ -1797,6 +1926,10 @@
<source>Restore Defaults</source>
<translation>Valeurs par défaut</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -1941,7 +2074,7 @@
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Indique le statut des fonctionnalités de virtualisation du processeur hôte : &lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1 :&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3 :&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Indique le statut des fonctionnalités de virtualisation du processeur hôte : &lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1 :&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3 :&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -1964,6 +2097,11 @@
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;Le serveur du bureau à distance écoute sur le port %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2160,7 +2298,15 @@
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Vous avez activé l&apos;accélération 3D pour un système.invité qui utilise l&apos;architecture vidéo de Windows Vista. Pour une performance optimale vous devrez affecter au moins &lt;b&gt;%1&lt;/b&gt; de mémoire vidéo à la machine virtuelle.</translation>
+ <translation type="obsolete">Vous avez activé l&apos;accélération 3D pour un système.invité qui utilise l&apos;architecture vidéo de Windows Vista. Pour une performance optimale vous devrez affecter au moins &lt;b&gt;%1&lt;/b&gt; de mémoire vidéo à la machine virtuelle.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">vous avez activé l&apos;accélération vidéo 2D. Comme l&apos;accélération 2D n&apos;est supportée que pour des invités Windows, elle sera désactivée.</translation>
</message>
</context>
<context>
@@ -2237,6 +2383,10 @@
<source>If checked, show the Mini ToolBar at the top of the screen, rather than in its default position at the bottom of the screen.</source>
<translation>Si cette case est cochée la barre d&apos;outils compacte sera affichée en haut de l&apos;écran, plutôt qu&apos;en bas comme par défaut.</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">vous avez choisi un système de type 64 bit pour cette machine virtuelle. Comme la virtualisation matérielle de l&apos;hôte (VT-x/AMD-V) est nécessaire pour un tel invité, elle sera automatiquement activée.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2299,7 +2449,7 @@
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Choisit le nom de l&apos;interface réseau pour le mode &lt;b&gt;accès par pont&lt;/b&gt; ou le mode &lt;b&gt;réseau privé hôte&lt;/b&gt; et le nom du réseau interne pour le mode d&apos;accès &lt;b&gt;réseau interne&lt;/b&gt;.</translation>
+ <translation type="obsolete">Choisit le nom de l&apos;interface réseau pour le mode &lt;b&gt;accès par pont&lt;/b&gt; ou le mode &lt;b&gt;réseau privé hôte&lt;/b&gt; et le nom du réseau interne pour le mode d&apos;accès &lt;b&gt;réseau interne&lt;/b&gt;.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -2325,6 +2475,42 @@
<source>&amp;Port Forwarding</source>
<translation>Redirection de &amp;ports</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsParallel</name>
@@ -2654,7 +2840,7 @@
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Aucun disque dur n&apos;est affecté à &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">Aucun disque dur n&apos;est affecté à &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -2928,6 +3114,60 @@
<source>Choose a virtual floppy disk file...</source>
<translation>Choisissez un fichier de disquette virtuel...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">au plus un seul supporté</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">justqu&apos;à %1 supporté</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">Vou utilisez plus de contrôleurs de stockage qu&apos;un chipset %1 ne supporte. Veuillez changer le type du chipset sur la page Système des paramètres de la machine ou bien reduire en nombre les contrôleurs de stockage suivants sur la page Stockage: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3101,6 +3341,32 @@
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>Vous avez affecté un chipset de type ICH9 à cette machine. Ceci nécessite l&apos;activation d&apos;un contrôleur APIC, qui sera activée automatiquement en cliquant sur OK pour accepter les.paramètres actuels.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished">vous avez activé un périphérique USB HID (clavier, souris ou tablette). Celui-ci ne pourra fonctionner que si l&apos;émulation USB est aussi activée donc elle le sera automatiquement lorsque vous cliquerez sur OK.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3228,7 +3494,11 @@
</message>
<message>
<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>USB 2.0 est active pour cette machine virtuelle, mais ceci nécessite que l&apos;extension &lt;b&gt;%1&lt;/b&gt; soit installée. Veuillez installer l&apos;extension à partir du site de téléchargement VirtualBox. Vous pourrez alors réactiver USB 2.0. En attendant, la fonctionnalité sera désactivée si vous n&apos;annulez pas les changements actuels.</translation>
+ <translation type="obsolete">USB 2.0 est active pour cette machine virtuelle, mais ceci nécessite que l&apos;extension &lt;b&gt;%1&lt;/b&gt; soit installée. Veuillez installer l&apos;extension à partir du site de téléchargement VirtualBox. Vous pourrez alors réactiver USB 2.0. En attendant, la fonctionnalité sera désactivée si vous n&apos;annulez pas les changements actuels.</translation>
+ </message>
+ <message>
+ <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>
</context>
<context>
@@ -3341,6 +3611,21 @@
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3386,44 +3671,234 @@
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Créer un nouveau disque virtuel</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select a file for the new hard disk image file</source>
+ <translation type="unfinished">Choisissez un emplacement pour le nouvelle disque dur virtuel</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 octets)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished">Récapitulatif</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 octets</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Location</source>
+ <comment>summary</comment>
+ <translation type="unfinished">Emplacement </translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">Emp&amp;lacement</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Taille</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Bienvenue dans l&apos;assistant de création de disque virtuel !</translation>
+ <translation type="obsolete">Bienvenue dans l&apos;assistant de création de disque virtuel !</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Cet assistant vous aidera à créer un nouveau disque dur virtuel pour votre machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Cet assistant vous aidera à créer un nouveau disque dur virtuel pour votre machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished">Choisissez un fichier de disque dur virtuel...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Choisissez le type de disque virtuel que vous voulez créer.&lt;/p&gt;&lt;p&gt;Au début un &lt;b&gt;fichier disque de taille variable&lt;/b&gt; prend peu de place sur votre vrai disque dur. L&apos;espace occupé augmentera en fonction des besoins du système d&apos;exploitation invité, jusqu&apos;à la taille limite spécifiée.&lt;/p&gt;&lt;p&gt;Un &lt;b&gt;fichier disque de taille fixe&lt;/b&gt; occupe un espace constant. La taille du fichier correspond approximativement à l&apos;espace du disque virtuel. La création d&apos;un fichier disque de taille fixe peut prendre un certain temps, qui dépend de la taille choisie et des performances en écriture de votre vrai disque dur.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Choisissez le type de disque virtuel que vous voulez créer.&lt;/p&gt;&lt;p&gt;Au début un &lt;b&gt;fichier disque de taille variable&lt;/b&gt; prend peu de place sur votre vrai disque dur. L&apos;espace occupé augmentera en fonction des besoins du système d&apos;exploitation invité, jusqu&apos;à la taille limite spécifiée.&lt;/p&gt;&lt;p&gt;Un &lt;b&gt;fichier disque de taille fixe&lt;/b&gt; occupe un espace constant. La taille du fichier correspond approximativement à l&apos;espace du disque virtuel. La création d&apos;un fichier disque de taille fixe peut prendre un certain temps, qui dépend de la taille choisie et des performances en écriture de votre vrai disque dur.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Type de disque virtuel</translation>
+ <translation type="obsolete">Type de disque virtuel</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>Fichier de taille &amp;variable</translation>
+ <translation type="obsolete">Fichier de taille &amp;variable</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>Fichier de taille &amp;fixe</translation>
+ <translation type="obsolete">Fichier de taille &amp;fixe</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Type de disque dur virtuel</translation>
+ <translation type="obsolete">Type de disque dur virtuel</translation>
</message>
</context>
<context>
@@ -3431,71 +3906,71 @@
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
<translatorcomment>There&apos;s only an icon on the so-called &quot;Select&quot; Button !</translatorcomment>
- <translation>&lt;p&gt;Entrez le chemin du fichier qui contiendra les données du disque dur ou cliquez sur le bouton pour choisir son emplacement.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Entrez le chemin du fichier qui contiendra les données du disque dur ou cliquez sur le bouton pour choisir son emplacement.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>Emp&amp;lacement</translation>
+ <translation type="obsolete">Emp&amp;lacement</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
<translatorcomment>Shouldn&apos;t it be &quot;Select the *maximum* size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the *actual* size of this hard disk.&quot; ?
And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the best unit.</translatorcomment>
- <translation>&lt;p&gt;Choisissez la taille maximale du disque dur virtuel. Le système d&apos;exploitation invité verra cette taille comme taille maximale de ce disque dur.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Choisissez la taille maximale du disque dur virtuel. Le système d&apos;exploitation invité verra cette taille comme taille maximale de ce disque dur.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Taille</translation>
+ <translation type="obsolete">&amp;Taille</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Emplacement et taille du disque virtuel</translation>
+ <translation type="obsolete">Emplacement et taille du disque virtuel</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Choisissez un emplacement pour le nouvelle disque dur virtuel</translation>
+ <translation type="obsolete">Choisissez un emplacement pour le nouvelle disque dur virtuel</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Disque dur virtuel (*.vdi)</translation>
+ <translation type="obsolete">Disque dur virtuel (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 octets)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 octets)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Vous êtes sur le point de créer un disque dur virtuel avec les paramètres suivants :</translation>
+ <translation type="obsolete">Vous êtes sur le point de créer un disque dur virtuel avec les paramètres suivants :</translation>
</message>
<message>
<source>Summary</source>
- <translation>Récapitulatif</translation>
+ <translation type="obsolete">Récapitulatif</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 octets</translation>
+ <translation type="obsolete">%1 octets</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Type </translation>
+ <translation type="obsolete">Type </translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Emplacement </translation>
+ <translation type="obsolete">Emplacement </translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Taille </translation>
+ <translation type="obsolete">Taille </translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Si ces paramètres vous conviennent cliquez sur &lt;b&gt;%1&lt;/b&gt; pour créer le nouveau disque dur.</translation>
+ <translation type="obsolete">Si ces paramètres vous conviennent cliquez sur &lt;b&gt;%1&lt;/b&gt; pour créer le nouveau disque dur.</translation>
</message>
</context>
<context>
@@ -3504,6 +3979,10 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<source>Create New Virtual Machine</source>
<translation>Créer une nouvelle machine virtuelle</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -3730,6 +4209,120 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Général</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Entrée</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Mise à jour</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Langue</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Réseau</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Extensions</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Général</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>Système</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Affichage</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Stockage</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Son</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Réseau</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Ports</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Ports séries</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Ports parallèle</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Dossiers partagés</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">vous avez choisi un système de type 64 bit pour cette machine virtuelle. Comme la virtualisation matérielle de l&apos;hôte (VT-x/AMD-V) est nécessaire pour un tel invité, elle sera automatiquement activée.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">vous avez activé l&apos;accélération vidéo 2D. Comme l&apos;accélération 2D n&apos;est supportée que pour des invités Windows, elle sera désactivée.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">vous avez activé un périphérique USB HID (clavier, souris ou tablette). Celui-ci ne pourra fonctionner que si l&apos;émulation USB est aussi activée donc elle le sera automatiquement lorsque vous cliquerez sur OK.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">au plus un seul supporté</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">justqu&apos;à %1 supporté</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">Vou utilisez plus de contrôleurs de stockage qu&apos;un chipset %1 ne supporte. Veuillez changer le type du chipset sur la page Système des paramètres de la machine ou bien reduire en nombre les contrôleurs de stockage suivants sur la page Stockage: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -3868,81 +4461,6 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Général</translation>
- </message>
- <message>
- <source>System</source>
- <translation>Système</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Affichage</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Stockage</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Son</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Réseau</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Ports</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Ports séries</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Ports parallèle</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Dossiers partagés</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>vous avez choisi un système de type 64 bit pour cette machine virtuelle. Comme la virtualisation matérielle de l&apos;hôte (VT-x/AMD-V) est nécessaire pour un tel invité, elle sera automatiquement activée.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>vous avez activé l&apos;accélération vidéo 2D. Comme l&apos;accélération 2D n&apos;est supportée que pour des invités Windows, elle sera désactivée.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>vous avez activé un périphérique USB HID (clavier, souris ou tablette). Celui-ci ne pourra fonctionner que si l&apos;émulation USB est aussi activée donc elle le sera automatiquement lorsque vous cliquerez sur OK.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>au plus un seul supporté</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>justqu&apos;à %1 supporté</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>Vou utilisez plus de contrôleurs de stockage qu&apos;un chipset %1 ne supporte. Veuillez changer le type du chipset sur la page Système des paramètres de la machine ou bien reduire en nombre les contrôleurs de stockage suivants sur la page Stockage: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -4069,6 +4587,14 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<source>Hard Disk Controller (SAS)</source>
<translation>Contrôleur disque dur SAS</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -4824,7 +5350,7 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Carte %1</translation>
+ <translation type="obsolete">Carte %1</translation>
</message>
<message>
<source>Checking...</source>
@@ -5231,7 +5757,7 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Réseau VDE, &apos;%1&apos; </translation>
+ <translation type="obsolete">Réseau VDE, &apos;%1&apos; </translation>
</message>
<message>
<source>SAS</source>
@@ -5241,7 +5767,7 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>Réseau VDE</translation>
+ <translation type="obsolete">Réseau VDE</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -5438,6 +5964,61 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<comment>DiskType</comment>
<translation>Attachements multiples</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -5589,16 +6170,16 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
</message>
<message>
<source>Location</source>
- <translation>Emplacement </translation>
+ <translation type="obsolete">Emplacement </translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Type (Format) </translation>
+ <translation type="obsolete">Type (Format) </translation>
</message>
<message>
<source>Attached to</source>
<translatorcomment>For the next three we have no choice because there is only one translation for &quot;not connected&quot;.</translatorcomment>
- <translation>Connecté à&amp;nbsp;</translation>
+ <translation type="obsolete">Connecté à&amp;nbsp;</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -5681,19 +6262,19 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
<translatorcomment>Followed by a colon.</translatorcomment>
- <translation>Connecté à&amp;nbsp;</translation>
+ <translation type="obsolete">Connecté à&amp;nbsp;</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
<translatorcomment>Followed by a colon.</translatorcomment>
- <translation>Connecté à&amp;nbsp;</translation>
+ <translation type="obsolete">Connecté à&amp;nbsp;</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
<translatorcomment>Followed by a colon.</translatorcomment>
- <translation>Connecté à&amp;nbsp;</translation>
+ <translation type="obsolete">Connecté à&amp;nbsp;</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -5711,6 +6292,46 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<source>All %1 images (%2)</source>
<translation>Tous les fichiers %1 virtuels (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Type :</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Emplacement :</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -5735,7 +6356,7 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Cartes réseau</translation>
+ <translation type="obsolete">Cartes réseau</translation>
</message>
</context>
<context>
@@ -6310,7 +6931,7 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Impossible d&apos;accéder à l&apos;USB de l&apos;hôte car ni le système de fichiers USB (usbfs) ni les services DBus et hal ne sont disponibles actuellement. Si vous voulez utiliser des périphériques USB de l&apos;hôte dans les systèmes virtuels corrigez ceci et redémarrez VirtualBox.</translation>
+ <translation type="obsolete">Impossible d&apos;accéder à l&apos;USB de l&apos;hôte car ni le système de fichiers USB (usbfs) ni les services DBus et hal ne sont disponibles actuellement. Si vous voulez utiliser des périphériques USB de l&apos;hôte dans les systèmes virtuels corrigez ceci et redémarrez VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -6444,7 +7065,7 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Êtes-vous sûr de vouloir restaurer l&apos;instantané &lt;b&gt;%1&lt;/b&gt;&amp;nbsp;? Vous perdrez définitivement l&apos;état actuel de votre machine.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Êtes-vous sûr de vouloir restaurer l&apos;instantané &lt;b&gt;%1&lt;/b&gt;&amp;nbsp;? Vous perdrez définitivement l&apos;état actuel de votre machine.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -6722,7 +7343,7 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">Une erreur non-identifiée s&apos;est produite.</translation>
+ <translation type="unfinished">Une erreur non-identifiée s&apos;est produite.</translation>
</message>
<message>
<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>
@@ -6811,7 +7432,7 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>La suppression de tous les fichiers d&apos;une machine virtuelle n&apos;est pas actuellement possible sur les systèmes Windows 64bits. Ceci sera rectifié dans la version suivante.</translation>
+ <translation type="obsolete">La suppression de tous les fichiers d&apos;une machine virtuelle n&apos;est pas actuellement possible sur les systèmes Windows 64bits. Ceci sera rectifié dans la version suivante.</translation>
</message>
<message>
<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>
@@ -6819,7 +7440,7 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
</message>
<message>
<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>&lt;p&gt;USB 2.0 est active pour cette machine virtuelle, mais ceci nécessite que l&apos;extension &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; soit installée.&lt;/p&gt;&lt;p&gt;Veuillez installer l&apos;extension à partir du site de téléchargement VirtualBox. Vous pourrez alors réactiver USB 2.0. En attendant, la fonctionnalité sera désactivée si vous n&apos;annulez pas les changements actuels.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;USB 2.0 est active pour cette machine virtuelle, mais ceci nécessite que l&apos;extension &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; soit installée.&lt;/p&gt;&lt;p&gt;Veuillez installer l&apos;extension à partir du site de téléchargement VirtualBox. Vous pourrez alors réactiver USB 2.0. En attendant, la fonctionnalité sera désactivée si vous n&apos;annulez pas les changements actuels.&lt;/p&gt;</translation>
</message>
<message>
<source>Could not load the Host USB Proxy Service (VERR_FILE_NOT_FOUND). The service might not be installed on the host computer</source>
@@ -6841,12 +7462,56 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<source>Could not load the Host USB Proxy service</source>
<translation>Le service de relais de périphériques USB n&apos;a pas pû être activé</translation>
</message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
</context>
<context>
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Dossiers partagés</translation>
+ <translation type="obsolete">Dossiers partagés</translation>
</message>
</context>
<context>
@@ -6918,7 +7583,7 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
</message>
<message>
<source>D&amp;iscard</source>
- <translation>&amp;Oublier</translation>
+ <translation type="obsolete">&amp;Oublier</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -7112,6 +7777,22 @@ 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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished">Oublier</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -7264,6 +7945,14 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<source> (%1 ago)</source>
<translation> (il y a %1)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_gl_ES.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_gl_ES.ts
index 8d513ee30..0755791a5 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_gl_ES.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_gl_ES.ts
@@ -471,11 +471,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">Configuración&amp;s...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -641,11 +722,6 @@
<translation type="unfinished">Adaptador exclusivo do anfitrión, &apos;%1&apos;</translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation type="unfinished">Adaptador %1</translation>
@@ -769,6 +845,26 @@
<comment>details report</comment>
<translation type="unfinished">Descrición</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -945,6 +1041,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">Nome do e&amp;quipo:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1276,6 +1376,10 @@ p, li { white-space: pre-wrap; }
<source>Cancel</source>
<translation type="obsolete">Cancelar</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1349,41 +1453,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Xeral</translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished">Entrada</translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished">Actualizar</translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished">Idioma</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Rede</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished">VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1808,6 +1877,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1877,23 +1997,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Maiúsculas da esquerda</translation>
+ <translation type="obsolete">Maiúsculas da esquerda</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Maiúsculas da dereita</translation>
+ <translation type="obsolete">Maiúsculas da dereita</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Ctrl da esquerda</translation>
+ <translation type="obsolete">Ctrl da esquerda</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Ctrl da dereita </translation>
+ <translation type="obsolete">Ctrl da dereita </translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Alt da esquerda</translation>
+ <translation type="obsolete">Alt da esquerda</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2110,6 +2230,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importar &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2254,7 +2378,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Indica o estado dos recursos do hardware virtualizado en uso por esta máquina virtual:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Indica o estado dos recursos do hardware virtualizado en uso por esta máquina virtual:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2277,6 +2401,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2459,7 +2588,11 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2537,6 +2670,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">seleccionou un sistema operativo convidado de tipo 64-bit para esta máquina virtual. Tales convidados requiren hardware de virtualización (VT-x/AMD-V) co que esta característica activarase automaticamente.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2591,7 +2728,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Selecciona o nome do adaptador de rede se o tipo anexado é equivalente a &lt;b&gt;Adaptador ponte&lt;/b&gt; ou &lt;b&gt;Adaptador exclusivo do anfitrión&lt;/b&gt; e o nome da rede interna se o tipo anexado é equivalente a &lt;b&gt;Rede interna&lt;/b&gt;.</translation>
+ <translation type="obsolete">Selecciona o nome do adaptador de rede se o tipo anexado é equivalente a &lt;b&gt;Adaptador ponte&lt;/b&gt; ou &lt;b&gt;Adaptador exclusivo do anfitrión&lt;/b&gt; e o nome da rede interna se o tipo anexado é equivalente a &lt;b&gt;Rede interna&lt;/b&gt;.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -2629,6 +2766,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3067,10 +3240,6 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
@@ -3306,6 +3475,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3496,6 +3719,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3621,7 +3870,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished">&lt;nobr&gt;Estado: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -3735,6 +3984,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3780,7 +4044,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Crear novo disco virtual</translation>
@@ -3795,7 +4059,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Resumo</translation>
+ <translation type="unfinished">Resumo</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -3807,7 +4071,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Selecciona un ficheiro para a nova imaxe de disco ríxido</translation>
+ <translation type="unfinished">Selecciona un ficheiro para a nova imaxe de disco ríxido</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -3829,12 +4093,12 @@ p, li { white-space: pre-wrap; }
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Localización</translation>
+ <translation type="unfinished">Localización</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Tamaño</translation>
+ <translation type="unfinished">Tamaño</translation>
</message>
<message>
<source>Bytes</source>
@@ -3893,15 +4157,183 @@ p, li { white-space: pre-wrap; }
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Se os axustes anteriores son correctos, prema no botón &lt;b&gt;Finalizar&lt;/b&gt;. Unha vez que prema nel, crearase un novo disco ríxido.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;Localización</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Tamaño</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation type="unfinished">Benvida ao asistente para crear novos discos virtuais!</translation>
+ <translation type="obsolete">Benvida ao asistente para crear novos discos virtuais!</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <source>Choose a virtual hard disk file...</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -3909,92 +4341,80 @@ p, li { white-space: pre-wrap; }
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Seleccione o tipo de disco ríxido virtual que desexa crear.&lt;/p&gt;&lt;p&gt;Un &lt;b&gt;almacenamento de expansión dinámica&lt;/b&gt; inicialmente ocupa unha pequena cantidade de espazo no seu disco ríxido. Este espazo en disco aumentará dinamicamente (ata o tamaño especificado) segundo o vaia necesitando o sistema operativo convidado.&lt;/p&gt;&lt;p&gt;Un &lt;b&gt;almacenamento de tamaño fixo&lt;/b&gt; non aumenta. Almacénase nun ficheiro no que aproximadamente o seu tamaño é igual co do disco ríxido virtual. A creación dun disco de tamaño fixo pode demorarse dependendo do tamaño de almacenamento e a velocidade de escritura do seu disco ríxido.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Seleccione o tipo de disco ríxido virtual que desexa crear.&lt;/p&gt;&lt;p&gt;Un &lt;b&gt;almacenamento de expansión dinámica&lt;/b&gt; inicialmente ocupa unha pequena cantidade de espazo no seu disco ríxido. Este espazo en disco aumentará dinamicamente (ata o tamaño especificado) segundo o vaia necesitando o sistema operativo convidado.&lt;/p&gt;&lt;p&gt;Un &lt;b&gt;almacenamento de tamaño fixo&lt;/b&gt; non aumenta. Almacénase nun ficheiro no que aproximadamente o seu tamaño é igual co do disco ríxido virtual. A creación dun disco de tamaño fixo pode demorarse dependendo do tamaño de almacenamento e a velocidade de escritura do seu disco ríxido.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation type="unfinished">Tipo de almacenamento</translation>
+ <translation type="obsolete">Tipo de almacenamento</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation type="unfinished">Almacenamento de expansión &amp;dinámica</translation>
+ <translation type="obsolete">Almacenamento de expansión &amp;dinámica</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation type="unfinished">Almacenamento de tamaño &amp;fixo</translation>
+ <translation type="obsolete">Almacenamento de tamaño &amp;fixo</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation type="unfinished">Tipo de almacenamento no disco ríxido</translation>
+ <translation type="obsolete">Tipo de almacenamento no disco ríxido</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Prema no botón &lt;b&gt;Seleccionar&lt;/b&gt; para escoller a localización dun ficheiro onde almacenar os datos do disco ríxido ou introduza un nome de ficheiro no campo de entrada.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Prema no botón &lt;b&gt;Seleccionar&lt;/b&gt; para escoller a localización dun ficheiro onde almacenar os datos do disco ríxido ou introduza un nome de ficheiro no campo de entrada.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation type="unfinished">&amp;Localización</translation>
+ <translation type="obsolete">&amp;Localización</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Seleccione o tamaño do disco ríxido virtual en megabytes. Este tamaño comunicaráselle ao sistema operativo convidado como o tamaño máximo do seu disco ríxido.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Seleccione o tamaño do disco ríxido virtual en megabytes. Este tamaño comunicaráselle ao sistema operativo convidado como o tamaño máximo do seu disco ríxido.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation type="unfinished">&amp;Tamaño</translation>
+ <translation type="obsolete">&amp;Tamaño</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation type="unfinished">Tamaño e localización do disco virtual</translation>
+ <translation type="obsolete">Tamaño e localización do disco virtual</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="unfinished">Selecciona un ficheiro para a nova imaxe de disco ríxido</translation>
+ <translation type="obsolete">Selecciona un ficheiro para a nova imaxe de disco ríxido</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation type="unfinished">Imaxes de disco ríxido (*.vdi)</translation>
- </message>
- <message>
- <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Imaxes de disco ríxido (*.vdi)</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation type="unfinished">Vaise crear un novo disco ríxido virtual cos seguintes parámetros:</translation>
+ <translation type="obsolete">Vaise crear un novo disco ríxido virtual cos seguintes parámetros:</translation>
</message>
<message>
<source>Summary</source>
- <translation type="unfinished">Resumo</translation>
- </message>
- <message>
- <source>%1 B</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Resumo</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation type="unfinished">Tipo</translation>
+ <translation type="obsolete">Tipo</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="unfinished">Localización</translation>
+ <translation type="obsolete">Localización</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="unfinished">Tamaño</translation>
- </message>
- <message>
- <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Tamaño</translation>
</message>
</context>
<context>
@@ -4124,6 +4544,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">Empregar &amp;un disco ríxido existente</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4357,6 +4781,100 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Xeral</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation type="unfinished">Entrada</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished">Actualizar</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation type="unfinished">Idioma</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Rede</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation type="unfinished">VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Xeral</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation type="unfinished">Sistema</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation type="unfinished">Pantalla</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation type="unfinished">Almacenamento</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished">Audio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Rede</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation type="unfinished">Portos</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation type="unfinished">Portos serie</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation type="unfinished">Portos paralelos</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation type="unfinished">Cartafoles compartidos</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished">%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">seleccionou un sistema operativo convidado de tipo 64-bit para esta máquina virtual. Tales convidados requiren hardware de virtualización (VT-x/AMD-V) co que esta característica activarase automaticamente.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -4495,81 +5013,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Xeral</translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished">Sistema</translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished">Pantalla</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished">Almacenamento</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished">Audio</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Rede</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished">Portos</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished">Portos serie</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished">Portos paralelos</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished">Cartafoles compartidos</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished">%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished">seleccionou un sistema operativo convidado de tipo 64-bit para esta máquina virtual. Tales convidados requiren hardware de virtualización (VT-x/AMD-V) co que esta característica activarase automaticamente.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -4704,6 +5147,14 @@ p, li { white-space: pre-wrap; }
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -5926,7 +6377,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Adaptador %1</translation>
+ <translation type="obsolete">Adaptador %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -6366,21 +6817,11 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>SAS</source>
<comment>StorageBus</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation type="unfinished"></translation>
@@ -6570,6 +7011,61 @@ p, li { white-space: pre-wrap; }
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Adaptador %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -6732,15 +7228,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Location</source>
- <translation>Localización</translation>
+ <translation type="obsolete">Localización</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Tipo (Formato)</translation>
+ <translation type="obsolete">Tipo (Formato)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Conectado a</translation>
+ <translation type="obsolete">Conectado a</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -6822,17 +7318,17 @@ p, li { white-space: pre-wrap; }
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation type="unfinished">Conectado a</translation>
+ <translation type="obsolete">Conectado a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation type="unfinished">Conectado a</translation>
+ <translation type="obsolete">Conectado a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation type="unfinished">Conectado a</translation>
+ <translation type="obsolete">Conectado a</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -6850,6 +7346,46 @@ p, li { white-space: pre-wrap; }
<source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -6871,13 +7407,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>VBoxNetworkDialog</name>
- <message>
- <source>Network Adapters</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxOSTypeSelectorWidget</name>
<message>
<source>Operating &amp;System:</source>
@@ -7547,7 +8076,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Non foi posíbel acceder ao USB no sistema anfitrión, porque nin o sistema de ficheiros USB (usbfs), nin o DBUS, nin os servizos da capa de abstracción de hardware (HAL) están dispoñíbeis actualmente. Se desexa empregar os dispositivos USB do anfitrión dentro dos sistemas convidados debe corrixir isto e reiniciar VirtualBox.</translation>
+ <translation type="obsolete">Non foi posíbel acceder ao USB no sistema anfitrión, porque nin o sistema de ficheiros USB (usbfs), nin o DBUS, nin os servizos da capa de abstracción de hardware (HAL) están dispoñíbeis actualmente. Se desexa empregar os dispositivos USB do anfitrión dentro dos sistemas convidados debe corrixir isto e reiniciar VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -7663,10 +8192,6 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restore</source>
<translation type="unfinished"></translation>
</message>
@@ -8009,15 +8534,75 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -8108,7 +8693,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Cartafoles compartidos</translation>
+ <translation type="obsolete">Cartafoles compartidos</translation>
</message>
</context>
<context>
@@ -8179,7 +8764,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Rexe&amp;itar</translation>
+ <translation type="obsolete">Rexe&amp;itar</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -8381,6 +8966,22 @@ p, li { white-space: pre-wrap; }
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished">Descartar</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -8578,6 +9179,14 @@ p, li { white-space: pre-wrap; }
<source> (%1 ago)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_hu.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_hu.ts
index b3f5f9676..9f000cda7 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_hu.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_hu.ts
@@ -570,12 +570,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>Mu&amp;nkamenet információk</translation>
+ <translation type="obsolete">Mu&amp;nkamenet információk</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>Távoli képernyő &amp;engedélyezése</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation>Konfigurálá&amp;s...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation>Virtuális gépek konfigurálásainak kezelése</translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation>Mu&amp;nkamenet információk...</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation>Virtuális gép klónozása</translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation>Klónozás</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Ez a varázsló segít egy új klón virtuális gép létrehozásában.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Válassz egy nevet az új virtuális gépnek:&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>Ha engedélyezett, új egyedi MAC cím lesz minden beállított hálózati kártyához rendelve.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>MAC címek új&amp;ra-inicializálása a hálózati kártyákhoz</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation>Üdvözöl a virtuális gép klónozó varázsló</translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation>%1 Klónozás</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation>Aktuális gép állapota</translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation>Aktuális gép és gyermekei állapota</translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation>Minden állapot</translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation>Klónozási konfiguráció</translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation>Válaszd ki, hogy a virtuális gép melyik részét kell klónozni.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation>Ha az &lt;b&gt;Aktuális gép állapot&lt;/b&gt;át választod, csak a virtuális gép aktuális állapota lesz klónozva.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation>Ha az &lt;b&gt;Aktuális gép és gyermekei állapot&lt;/b&gt;át választod, a virtuális gép aktuális állapota és a gyermekek pillanatképeinek minden állapota klónozva lesz.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation>Ha a &lt;b&gt;Minden állapot&lt;/b&gt;ot választod, az aktuális virtuális gép és minden piialantkép klónozva lesz.</translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -741,7 +826,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE hálózat, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE hálózat, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -867,6 +952,26 @@
<comment>details report</comment>
<translation>Leírás</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation>Végrehajtási csúcs</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation>&lt;nobr&gt;%1%&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>Ãltalános meghajtó, &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation>Ãltalános meghajtó, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -1077,6 +1182,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">&amp;Gépnév:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation>Exportálás</translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1424,12 +1533,16 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;Ha a fentiek megfelelőek, nyomd meg a &lt;b&gt;Befejezés&lt;/b&gt; gombot. Ha megnyomtad, a kiválasztott média ideiglenesen felcsatolódik a virtuális gépre és a gép el fogja indítani.&lt;/p&gt;&lt;p&gt;Ne feledd, hogy mikor bezárod a virtuális gépet, a megadott média automatikusan le fog választódni és az első merevlemezről fog indulni a gép.&lt;/p&gt;&lt;p&gt;A telepítőprogram típusától függgően, talán neked kell kézzel leválasztani (kiadni) a médiát, miután a telepítő újraindította a virtuális gépet, hogy megelőzd a telepítési folyamat újbóli elindulását. Ezt megteheted a megfelelő &lt;b&gt;Lecsatolás...&lt;/b&gt; művelet használatával az &lt;b&gt;Eszközök&lt;/b&gt; menüben.&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation>Start</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
<message>
<source>Welcome to the First Run Wizard!</source>
- <translation>Az Első indítás varázsló üdvözöl!</translation>
+ <translation>Üdvözöl az első indítás varázsló!</translation>
</message>
<message>
<source>&lt;p&gt;You have started a newly created virtual machine for the first time. This wizard will help you to perform the steps necessary for installing an operating system of your choice onto this virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
@@ -1497,41 +1610,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Ãltalános</translation>
- </message>
- <message>
- <source>Input</source>
- <translation> Bevitel</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Frissítés</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Nyelv</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Hálózat</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Kiterjesztők</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1976,6 +2054,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation>Ha engedélyezed, a VirtualBox az olyan feladatokhoz, mint az Integrációs szolgáltatások letöltése vagy a frissítések ellenőrzése, a proxy szerver beállításait fogja használni.</translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation>&amp;Proxy használata</translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation>Ga&amp;zda:</translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation>A proxy gazda módosítása.</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation>A proxy port módosítása.</translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation>Ha engedélyezed, hitelesítés szükséges a proxy szerver használatához.</translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation>&amp;Hitelesítés használata</translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation>Felhasználó&amp;név:</translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation>A hitelesítéshez használt felhasználónév módosítása.</translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation>&amp;Jelszó:</translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation>A hitelesítéshez használt jelszó módosítása.</translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -2045,23 +2174,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Bal Shift</translation>
+ <translation type="obsolete">Bal Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Jobb Shift</translation>
+ <translation type="obsolete">Jobb Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Bal Ctrl</translation>
+ <translation type="obsolete">Bal Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Jobb Ctrl</translation>
+ <translation type="obsolete">Jobb Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Bal Alt</translation>
+ <translation type="obsolete">Bal Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2262,6 +2391,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importálás &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation>Importálás</translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2406,7 +2539,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Jelzi a hardvervirtualizáció állapotát ezen a virtuális gépen: &lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Jelzi a hardvervirtualizáció állapotát ezen a virtuális gépen: &lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2429,6 +2562,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;A Távoli asztal szerver a következő porton figyel: %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation>Megmutatja a virtuális gépen használt szolgáltatások közötti különbséget:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2629,7 +2767,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>A WDDM videó drivert használó operációs rendszereden be van kapcsolva a 3D gyorsítás. A maximális teljesítmény eléréséhez a vendég VRAM méretét legalább &lt;b&gt;%1&lt;/b&gt; értékre állítsd be.</translation>
+ <translation type="obsolete">A WDDM videó drivert használó operációs rendszereden be van kapcsolva a 3D gyorsítás. A maximális teljesítmény eléréséhez a vendég VRAM méretét legalább &lt;b&gt;%1&lt;/b&gt; értékre állítsd be.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>a WDDM videó drivert használó operációs rendszereden be van kapcsolva a 3D gyorsítás. A maximális teljesítmény eléréséhez a vendég VRAM méretét legalább &lt;b&gt;%1&lt;/b&gt; értékre állítsd be.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation>engedélyezted a 2D gyorsítást. Mivel ez a lehetőség jelenleg csak Windows-os vendéggépeken érhető el, ezért most letiltásra kerül.</translation>
</message>
</context>
<context>
@@ -2851,6 +2997,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Legyen a képernyő &amp;tetején</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation>egy 64 bites vendégrendszert választottál ehhez a géphez. Ezek a rendszerek igényik a hardvervirtualizációt (VT-x/AMD-V), így ez a tulajdonság automatikusan engedélyezve lesz.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2995,7 +3145,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>A hálózati kártya nevét lehet itt beállítani, ha a csatolás típusa &lt;b&gt;Bridge-elt kártya&lt;/b&gt; vagy &lt;b&gt;Host-only kártya&lt;/b&gt;, és a belső hálózat nevét, ha a csatolás típusa &lt;b&gt;Belső hálózat&lt;/b&gt;.</translation>
+ <translation type="obsolete">A hálózati kártya nevét lehet itt beállítani, ha a csatolás típusa &lt;b&gt;Bridge-elt kártya&lt;/b&gt; vagy &lt;b&gt;Host-only kártya&lt;/b&gt;, és a belső hálózat nevét, ha a csatolás típusa &lt;b&gt;Belső hálózat&lt;/b&gt;.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -3021,6 +3171,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>&amp;Port továbbítása</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation>&amp;Kevert mód:</translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation>Válaszd ki a hálózati kártya kevert módú házirendjét, ha belső-, host only vagy bridge-elt hálózatra csatlakozol.</translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation>Ãltalános tulajdonságok:</translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation>Adj meg itt bármilyen konfigurációs beállítást a használandó hálózati driverhez. A beállításokat &lt;b&gt;név=érték&lt;/b&gt; formátumban kellene megadni és a drivertől fognak függni. Új bejegyzés hozzáadásához használd a &lt;b&gt;shift-enter&lt;/b&gt; kombinációt.</translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation>nincs általános driver telepítve</translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation>Válassz egy hálózati kártyát a gazda rendszerről, melyen keresztül ez a hálózati kártya fog kommunikálni.</translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation>Add meg a belső hálózat nevét, amelyhez ez a hálózati kártya csatlakozni fog. Létrehozhatsz új belső hálózatot egy olyan név választásával, melyet egyik hálózati kártya sem használ ezen, vagy másik virtuális gépen.</translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation>Válassz egy hálózati kártyát a gazda rendszerről, melyen keresztül ez a hálózati kártya fog kommunikálni. Létrehozhatsz vagy törölhetsz kártyákat a virtuális gép kezelése ablakon belül a globális hálózati beállítások használatával.</translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation>Válaszd ki az ehhez a hálózati kártyához használandó drivert.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3487,7 +3673,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Nincs merevlemez kiválasztva a(z) &lt;i&gt;%1&lt;/i&gt; géphez.</translation>
+ <translation type="obsolete">Nincs merevlemez kiválasztva a(z) &lt;i&gt;%1&lt;/i&gt; géphez.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3763,6 +3949,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation>Virtuális floppy választása...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation>Ha engedélyezed, elnyomja a médium lecsatolását, mikor a vendég rendszer kiadja azt.</translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation>&amp;Live CD/DVD</translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation>Ha engedélyezed, a médium mozgó alkatrészek nélküli tárolóként (SSD) lesz jelölve.</translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation>&amp;Solid-state drive (SSD)</translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation>Részletek:</translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>nincs név adva a vezérlőhöz ezen a helyen: &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation>&lt;b&gt;%1&lt;/b&gt; helyen levő vezérlő olyan nevet használ, amit már használ egy vezérlő ezen a helyen: &lt;b&gt;%2&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation>&lt;i&gt;%1&lt;/i&gt; számára nincs merevlemez kiválasztva.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation>legfeljebb egy támogatott</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation>legfeljebb %1 támogatott</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation>jelenleg több vezérlőt használsz, mint amit a lapkakészlet támogat: %1. Válassz másik lapkakészlet-típust a beállítások Rendszer lapján, vagy csökkentsd a vezérlők számát a beállítások Tároló lapján: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation>&amp;Port érték:</translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation>Válaszd ki a Tárolófán jelenleg kiválasztott SATA tárolási vezérlőjének Port értékét. Ez az érték nem lehet kisebb, mint a maximálisan használt portok száma + 1.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3953,6 +4193,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>az ICH9 lapkakészlet típust választottad a virtuális géphez. Csak akkor fog helyesen működni, ha az IO APIC is be van kapcsolva. Ez automatikusan meg fog történni, mikor az OK gomb megnyomásával elfogadod a beállításokat.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation>Végr&amp;ehajtási csúcs:</translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation>Korlátozza a virtuális processzor futási idejének értékét. Minden virtuális processzor maximálisan ennyi százalékát használhatja egy fizikai processzor elérhető feldolgozási idejéből. A végrehajtási csúcs a 100%-ra állítással kikapcsolható. A túl alacsonyra állított csúcstól a gép lassabban válaszolhat.</translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation>a processzor végrehajtási csúcsát túl acsonyra állítottad. Ez lassíthatja a virtuális gépet.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation>engedélyezted a USB HID-et (Human Interface Device). Addig nem fog működni, amíg az USB emuláció be van kapcsolva. Ez automatikusan meg fog történni, ha elfogadod a virtuális gép beállításait az OK gomb megnyomásával.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation>&lt;qt&gt;%1%&lt;/qt&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation>&lt;qt&gt;%1%&lt;/qt&gt;</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -4079,6 +4345,10 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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="obsolete">Az USB 2.0 jelenleg be van kapcsolva a virtuális gépen. Azonban ehhez a következőnek telepítve kell lennie: &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;A VirtualBox oldaláról letöltve telepítsd fel a Kiterjesztő csomagot. Ezután újra be engedélyezni tudod az USB 2.0-t. Addig ki lesz kapcsolva, hacsak meg nem szakítod a beállítások módosítását.</translation>
+ </message>
+ <message>
+ <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>Az USB 2.0 jelenleg be van kapcsolva a virtuális gépen. Azonban ehhez a következőnek telepítve kell lennie: &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;A VirtualBox oldaláról letöltve telepítsd fel a Kiterjesztő csomagot. Ezután újra be engedélyezni tudod az USB 2.0-t. Addig ki lesz kapcsolva, hacsak meg nem szakítod a beállítások módosítását.</translation>
</message>
</context>
@@ -4192,6 +4462,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation>Médium atttribútimainak módosítása</translation>
+ </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;Módosítani akarod a virtuális lemez attribútumát, ami itt van: &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Válassz egyet a következő típusok közül, majd &lt;b&gt;%2&lt;/b&gt; gomb a folytatáshoz. Egyébként &lt;b&gt;%3&lt;/b&gt;.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation>Válassz médium típust:</translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4237,7 +4522,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Új virtuális lemez készítése</translation>
@@ -4331,7 +4616,7 @@ lemezből&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Összegzés</translation>
+ <translation>Összegzés</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4347,7 +4632,7 @@ lemezből&lt;/p&gt;</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Válaszd ki az új merevlemezkép fájlját</translation>
+ <translation>Válaszd ki az új merevlemezkép fájlját</translation>
</message>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;
@@ -4401,12 +4686,12 @@ a rámásolt adatok függvényében növekszik az általa elfoglalt hely - míg
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Hely</translation>
+ <translation>Hely</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Méret</translation>
+ <translation>Méret</translation>
</message>
<message>
<source>Bytes</source>
@@ -4465,108 +4750,280 @@ a rámásolt adatok függvényében növekszik az általa elfoglalt hely - míg
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Ha a fenti beállítások megfelelőek, nyomd meg a &lt;b&gt;Befejezés&lt;/b&gt; gombot. Ha megnyomtad, az új merevlemez azonnal létrejön.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation>%1_másolat</translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation>Létrehozás</translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation>Virtuális lemez másolása</translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation>Másolás</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation>Üdvözöl a virtuális lemez másoló varázsló</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Ez a varázsló segít a virtuális lemez másolásában.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation>Válaszd ki a virtuális lemezt, amelyiket másolni szeretnél, ha még nincs kiválasztva. válaszhatsz másikat is alistából vagy a mappa ikonnal kiválaszthatsz egy virtuális lemezfájlt.</translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation>&amp;VDI (VirtualBox lemezkép)</translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation>V&amp;MDK (Virtuális gép lemez)</translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation>V&amp;HD (Virtuális merevlemez)</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation>Üdvözöl a virtuális lemez létrehozó varázsló</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Ez a varázsló segít egy új virtuális lemez elkészítésében a virtuális géphez.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Válassz egy fájltípust, amit az új virtuális lemezhez szeretnél használni. Ha nem szeretnéd másik virtualizációs szoftverhez használni, nem kell a beállításokat módosítanod.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation>Virtuális lemez fájtípusa</translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation>Válassz egy fájltípust, amit az új virtuális lemezhez szeretnél használni. Ha nem szeretnéd másik virtualizációs szoftverhez használni, nem kell a beállításokat módosítanod.</translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation>Virtuális lemez tároló részletei</translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation>Válaszd ki, hogy az új virtuális lemez mérete folyamatosan növekedjen vagy lefoglalja-e a teljes területét.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;A &lt;b&gt;dinamikus növekvő&lt;/b&gt; virtuális lemezfájl a benne levő adatokhoz mérten foglal helyet, bár a felszabaduló hellyel nem fog automatikusan csökkeni a mérete.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;A &lt;b&gt;fix méretű&lt;/b&gt; virtuális lemezfájl létrehozása egyes rendszereken lassú lehet, de gyakran gyorsabb a használata.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation>&lt;p&gt;&lt;b&gt;Feldarabol&lt;/b&gt;hatod a virtuális lemezeket, maximum 2GB-os fájlokra. Leginkább akkor hasznos, ha a virtuális gépet USB eszközön vagy régi fájlrendszeren tárolod, melyek nem tudják a nagy fájlokat kezelni.</translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation>&amp;Dinamikusan növekvő</translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation>&amp;Fix méretű</translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation>2GB-nál ki&amp;sebb fájlokba darabolás</translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation>Virtuális lemezfájl helye és mérete</translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation>Add meg a virtuális lemez méretét megabájtban. Ezt a méretet fogják a virtuális gépek látni a lemezből.</translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation>Virtuális lemezfájl helye</translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation>Nyomd meg a &lt;b&gt;Választ&lt;/b&gt; gombot a virtuális merevlemez elhelyezkedésének megadásához, vagy gépeld be a fájl nevét a mezőbe.</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation>A virtuális merevlemez az alábbi paraméterekkel lesz létrehozva:</translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation>A virtuális merevlemez másolata az alábbi paraméterekkel lesz létrehozva:</translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation>Ha a fenti beállítások megfelelőek, nyomd meg a &lt;b&gt;%1&lt;/b&gt; gombot. Ha megnyomtad, az új lemezkép azonnal létrejön.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation>Fájltípus</translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation>Részletek</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation>Fájltípus</translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation>He&amp;ly</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation>&amp;Méret</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation>Tároló részletei</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Üdvözöl az Új Virtuális lemez varázsló!</translation>
+ <translation type="obsolete">Üdvözöl az Új Virtuális lemez varázsló!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Ez a varázsló segít egy új virtuális merevlemez elkészítésében.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Ez a varázsló segít egy új virtuális merevlemez elkészítésében.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation>Másolandó virtuális lemez</translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation>Virtuális merevlemez választása...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Válaszd ki az elkészítendő virtuális merevlemez típusát.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dinamikusan növekvő&lt;/b&gt; kezdetben egy kis fájlt hoz létre a lemezen, mely később a vendég rendszer igényei szerint növekszik (a beállított méretig). A &lt;b&gt;fix méretű&lt;/b&gt; nem növekszik. Ez egy nagyjából akkora fájl lesz, amekkora méretet itt megadtál a virtuális merevlemez méreteként. A fix méretű virtuális merevlemez elkészítése egy kis időt vehet igénybe, függően az itt megadott mérettől és a valódi merevlemez írási sebességétől.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Válaszd ki az elkészítendő virtuális merevlemez típusát.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dinamikusan növekvő&lt;/b&gt; kezdetben egy kis fájlt hoz létre a lemezen, mely később a vendég rendszer igényei szerint növekszik (a beállított méretig). A &lt;b&gt;fix méretű&lt;/b&gt; nem növekszik. Ez egy nagyjából akkora fájl lesz, amekkora méretet itt megadtál a virtuális merevlemez méreteként. A fix méretű virtuális merevlemez elkészítése egy kis időt vehet igénybe, függően az itt megadott mérettől és a valódi merevlemez írási sebességétől.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Tároló típusa</translation>
+ <translation type="obsolete">Tároló típusa</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>&amp;Dinamikusan növekvő tároló</translation>
+ <translation type="obsolete">&amp;Dinamikusan növekvő tároló</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>&amp;Fix méretű tároló</translation>
+ <translation type="obsolete">&amp;Fix méretű tároló</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Merevlemez típusa</translation>
+ <translation type="obsolete">Merevlemez típusa</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Nyomd meg a &lt;b&gt;Kiválaszt&lt;/b&gt; gombot a virtuális merevlemez elhelyezkedésének megadásához, vagy gépeld be a fájl nevét a mezőbe.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Nyomd meg a &lt;b&gt;Kiválaszt&lt;/b&gt; gombot a virtuális merevlemez elhelyezkedésének megadásához, vagy gépeld be a fájl nevét a mezőbe.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>He&amp;ly</translation>
+ <translation type="obsolete">He&amp;ly</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Add meg a virtuális lemez méretét megabájtban. Ezt a méretet fogják a virtuális gépek látni a lemezből.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Add meg a virtuális lemez méretét megabájtban. Ezt a méretet fogják a virtuális gépek látni a lemezből.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Méret</translation>
+ <translation type="obsolete">&amp;Méret</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Virtuális lemez helye és mérete</translation>
+ <translation type="obsolete">Virtuális lemez helye és mérete</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Válaszd ki az új merevlemezkép fájlját</translation>
+ <translation type="obsolete">Válaszd ki az új merevlemezkép fájlját</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Merevlemez képfájlok (*.vdi)</translation>
+ <translation type="obsolete">Merevlemez képfájlok (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>A virtuális merevlemez az alábbi paraméterekkel lesz létrehozva:</translation>
+ <translation type="obsolete">A virtuális merevlemez az alábbi paraméterekkel lesz létrehozva:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Összegzés</translation>
+ <translation type="obsolete">Összegzés</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Típus</translation>
+ <translation type="obsolete">Típus</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Hely</translation>
+ <translation type="obsolete">Hely</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Méret</translation>
+ <translation type="obsolete">Méret</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Ha az alábbi beállítások megfelelők, kattints a &lt;b&gt;%1&lt;/b&gt; gombra. Ha megnyomtad, az új lemezkép azonnal elkészül.</translation>
+ <translation type="obsolete">Ha az alábbi beállítások megfelelők, kattints a &lt;b&gt;%1&lt;/b&gt; gombra. Ha megnyomtad, az új lemezkép azonnal elkészül.</translation>
</message>
</context>
<context>
@@ -4803,6 +5260,10 @@ esetleg a &lt;b&gt;Létező&lt;/b&gt; gombbal a Virtuális lemezkezelőből.&lt;
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">Létező merevlemez &amp;haználata</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation>Létrehoz</translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -5036,6 +5497,120 @@ esetleg a &lt;b&gt;Létező&lt;/b&gt; gombbal a Virtuális lemezkezelőből.&lt;
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Ãltalános</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation> Bevitel</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Frissítés</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Nyelv</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Hálózat</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Kiterjesztők</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation>Proxy</translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Ãltalános</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>Rendszer</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Képernyő</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Tároló</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Audió</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Hálózat</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Portok</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Soros portok</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Párhuzamos portok</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Megosztott mappák</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">egy 64 bites vendégrendszert választottál ehhez a géphez. Ezek a rendszerek igénylik a hardvervirtualizációt (VT-x/AMD-V), így ez a tulajdonság automatikusan engedélyezve lesz.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">engedélyezted a 2D gyorsítást. Mivel ez a lehetőség jelenleg csak Windows-os vendéggépeken érhető el, ezért most letiltásra került.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">engedélyezted a USB HID-et (Human Interface Device). Addig nem fog működni, amíg az USB emuláció be van kapcsolva. Ez automatikusan meg fog történni, ha elfogadod a virtuális gép beállításait az OK gomb megnyomásával.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">legfeljebb egy támogatott</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">legfeljebb %1 támogatott</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">jelenleg több vezérlőt használsz, mint amit a(z) %1 lapkakészlet támogat. Válassz másik lapkakészlet-típust a beállítások Rendszer lapján vagy csökkentsd a vezérlők számát a beállítások Tároló lapján: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -5174,81 +5749,6 @@ esetleg a &lt;b&gt;Létező&lt;/b&gt; gombbal a Virtuális lemezkezelőből.&lt;
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Ãltalános</translation>
- </message>
- <message>
- <source>System</source>
- <translation>Rendszer</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Képernyő</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Tároló</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Audió</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Hálózat</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Portok</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Soros portok</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Párhuzamos portok</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Megosztott mappák</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>egy 64 bites vendégrendszert választottál ehhez a géphez. Ezek a rendszerek igénylik a hardvervirtualizációt (VT-x/AMD-V), így ez a tulajdonság automatikusan engedélyezve lesz.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>engedélyezted a 2D gyorsítást. Mivel ez a lehetőség jelenleg csak Windows-os vendéggépeken érhető el, ezért most letiltásra került.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>engedélyezted a USB HID-et (Human Interface Device). Addig nem fog működni, amíg az USB emuláció be van kapcsolva. Ez automatikusan meg fog történni, ha elfogadod a virtuális gép beállításait az OK gomb megnyomásával.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>legfeljebb egy támogatott</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>legfeljebb %1 támogatott</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>jelenleg több vezérlőt használsz, mint amit a(z) %1 lapkakészlet támogat. Válassz másik lapkakészlet-típust a beállítások Rendszer lapján vagy csökkentsd a vezérlők számát a beállítások Tároló lapján: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5480,6 +5980,14 @@ Verzió %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation>Merevlemez vezérlő (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>Ha engedélyezett, új egyedi MAC cím lesz minden hálózati kártyához rendelve.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>MAC címek új&amp;ra-inicializálása a hálózati kártyákhoz</translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -7467,7 +7975,7 @@ Verzió %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>%1. eszköz</translation>
+ <translation type="obsolete">%1. eszköz</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -7910,7 +8418,7 @@ Verzió %1</translation>
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE hálózat, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE hálózat, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -7920,7 +8428,7 @@ Verzió %1</translation>
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>VDE adapter</translation>
+ <translation type="obsolete">VDE adapter</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -8117,6 +8625,61 @@ Verzió %1</translation>
<comment>DiskType</comment>
<translation>Többszörös csatolás</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation>Dinamikusan növekvő tároló</translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation>Fix méretű tároló</translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation>A dinamikusan növekvő tároló 2GB-nál kisebb fájlokra darabolása</translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation>A fix méretű tároló 2GB-nál kisebb fájlokra darabolása</translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation>Végrehajtási csúcs</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation>&lt;nobr&gt;%1%&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>Ãltalános, &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation>Ãltalános driver</translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>Tiltott</translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>Virtuális gépeknek</translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>Mindenkinek</translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation>Kártya %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -8625,15 +9188,15 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>Location</source>
- <translation>Hely</translation>
+ <translation type="obsolete">Hely</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Típus (formátum)</translation>
+ <translation type="obsolete">Típus (formátum)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Ide csatlakoztatva</translation>
+ <translation type="obsolete">Ide csatlakoztatva</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -8715,17 +9278,17 @@ to the system default language.&lt;/qt&gt;
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Ide csatlakoztatva</translation>
+ <translation type="obsolete">Ide csatlakoztatva</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Ide csatlakoztatva</translation>
+ <translation type="obsolete">Ide csatlakoztatva</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Ide csatlakoztatva</translation>
+ <translation type="obsolete">Ide csatlakoztatva</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -8743,6 +9306,46 @@ to the system default language.&lt;/qt&gt;
<source>All %1 images (%2)</source>
<translation>Minden %1 képfájl (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation>Típus:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation>Hely:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation>Formátum:</translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation>Tároló részletei:</translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation>Csatlakoztatva:</translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation>Má&amp;solás...</translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation>&amp;Módosítás...</translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation>Létező médium másolása</translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation>A kiválasztott médium attribútumainak módosítása</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>Be&amp;zárás</translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -8802,7 +9405,7 @@ to the system default language.&lt;/qt&gt;
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Hálózati kártyák</translation>
+ <translation type="obsolete">Hálózati kártyák</translation>
</message>
</context>
<context>
@@ -9524,7 +10127,7 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Nem lehet használni az USB-t a gazda rendszerben, mert sem az USB fájlrendszer (usbfs), sem a DBus/Hal szolgáltatások nem elérhetők. Ha szeretnél USB eszközt használni a gazda gép rendszeréből, ennek a problémának a javítása szükséges. Ha végeztél, indítsd újra a VirtualBox-ot.</translation>
+ <translation type="obsolete">Nem lehet használni az USB-t a gazda rendszerben, mert sem az USB fájlrendszer (usbfs), sem a DBus/Hal szolgáltatások nem elérhetők. Ha szeretnél USB eszközt használni a gazda gép rendszeréből, ennek a problémának a javítása szükséges. Ha végeztél, indítsd újra a VirtualBox-ot.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -9645,7 +10248,7 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Biztos, hogy vissza akarod tölteni ezt a pillanatképet: &lt;b&gt;%1&lt;/b&gt;? Ez a gép jelenlegi állapotának végleges elvesztését okozhatja.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Biztos, hogy vissza akarod tölteni ezt a pillanatképet: &lt;b&gt;%1&lt;/b&gt;? Ez a gép jelenlegi állapotának végleges elvesztését okozhatja.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -9943,7 +10546,7 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">Sajnálom, véletlen hiba lépett fel.</translation>
+ <translation>Sajnálom, véletlen hiba lépett fel.</translation>
</message>
<message>
<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>
@@ -10032,7 +10635,7 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>A virtuális géphez tartozó fájlok fájlok törlése jelenleg le van tiltva Windows/x64 rendszeren az összeomlás elkerülése miatt. Ez a következő kiadásban kerül javításra.</translation>
+ <translation type="obsolete">A virtuális géphez tartozó fájlok fájlok törlése jelenleg le van tiltva Windows/x64 rendszeren az összeomlás elkerülése miatt. Ez a következő kiadásban kerül javításra.</translation>
</message>
<message>
<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>
@@ -10040,7 +10643,71 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<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>&lt;p&gt;Az USB 2.0 jelenleg be van kapcsolva a virtuális gépen. Azonban ehhez a következőnek telepítve kell lennie: &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;A VirtualBox oldaláról letöltve telepítsd fel a Kiterjesztő csomagot. Ezután újra be engedélyezni tudod az USB 2.0-t. Addig ki lesz kapcsolva, hacsak meg nem szakítod a beállítások módosítását.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Az USB 2.0 jelenleg be van kapcsolva a virtuális gépen. Azonban ehhez a következőnek telepítve kell lennie: &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;A VirtualBox oldaláról letöltve telepítsd fel a Kiterjesztő csomagot. Ezután újra be engedélyezni tudod az USB 2.0-t. Addig ki lesz kapcsolva, hacsak meg nem szakítod a beállítások módosítását.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>A virtuális gép regisztrálása sikertelen: &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;A gép beállításai megváltoztak az utolsó módosításuk óta.&lt;/p&gt;&lt;p&gt;Szeretnéd visszatölteni a megváltozott beállításokat vagy meghagyod a jelenlegieket?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation>Beállítások visszatöltése</translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation>Módosítások megtartása</translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation>A jelenleg szerkesztett virtuális gép állapota megváltozott. Csak a futáskor szerkesztett beállítások lesznek mentve az OK gomb megnyomásakor. Minden egyéb módosítás elveszik.</translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>A virtuális gép klónozása sikertelen: &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Vissza akarod állítani a pillanatképet: &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;készíthetsz pillanatképet a virtuális gép jelenlegi állapotáról a lenti jelölőnégyzettel; ha nem teszed meg, a jelenlegi állapot végleg elveszik. Folytatni akarod?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation>Pillanatkép készítése az aktuális gép állapotáról</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Biztos vissza akarod állítani a pillanatképet: &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Hiba a médium &lt;b&gt;%1&lt;/b&gt; típusáról &lt;b&gt;%2&lt;/b&gt; típusra történő váltáskor.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <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>&lt;p&gt;Az USB 2.0 jelenleg be van kapcsolva a virtuális gépen. Azonban ehhez a következőnek telepítve kell lennie: &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;A VirtualBox oldaláról letöltve telepítsd fel a Kiterjesztő csomagot. Ezután újra engedélyezni tudod az USB 2.0-t. Addig ki lesz kapcsolva, hacsak meg nem szakítod a beállítások módosítását.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <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>Nem tölthetÅ‘ be a gazda USB Proxy szolgáltatás (FÃJL_NEM_TALÃHATÓ). A szolgáltatás talán nincs telepítve a gazda számítógépre</translation>
+ </message>
+ <message>
+ <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>A VirtualBox jelenleg nem férhet hozzá az USB eszközökhöz. Ezen változtathatsz, ha a felhasználód hozzáadod a &apos;vboxusers&apos; csoporthoz. Részletes magyarázatért nézd meg a Felhasználói kézikönyvet</translation>
+ </message>
+ <message>
+ <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>A VirtualBox jelenleg nem férhet hozzá az USB eszközökhöz. Ezen változtathatsz, ha engedélyezed a felhasználódnak az &apos;usbfs&apos; mappa és fájlok elérését. Részletes magyarázatért nézd meg a Felhasználói kézikönyvet</translation>
+ </message>
+ <message>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation>Az USB proxy szolgáltatás még nem lett portolva erre a gazda rendszerre</translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation>A gazda USB szolgáltatás nem tölthető be</translation>
</message>
</context>
<context>
@@ -10174,7 +10841,7 @@ to the system default language.&lt;/qt&gt;
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Megosztott mappák</translation>
+ <translation type="obsolete">Megosztott mappák</translation>
</message>
<message>
<source>OK</source>
@@ -10305,11 +10972,11 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Eldo&amp;bás</translation>
+ <translation type="obsolete">Eldo&amp;bás</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Eldobás</translation>
+ <translation>Eldobás</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -10461,7 +11128,7 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>&lt;h3&gt;Welcome to VirtualBox!&lt;/h3&gt;&lt;p&gt;The left part of this window is a list of all virtual machines on your computer. The list is empty now because you haven&apos;t created any virtual machines yet.&lt;img src=:/welcome.png align=right/&gt;&lt;/p&gt;&lt;p&gt;In order to create a new virtual machine, press the &lt;b&gt;New&lt;/b&gt; button in the main tool bar located at the top of the window.&lt;/p&gt;&lt;p&gt;You can press the &lt;b&gt;%1&lt;/b&gt; key to get instant help, or visit &lt;a href=http://www.virtualbox.org&gt;www.virtualbox.org&lt;/a&gt; for the latest information and news.&lt;/p&gt;</source>
- <translation>&lt;h3&gt;A VirtualBox üdvözöl!&lt;/h3&gt;&lt;p&gt;Az ablak bal oldali részében a virtuális gépeid listáját látod. Ez jelenleg üres, hiszen most indítod ezt a programot először.&lt;img src=welcome.png align=right/&gt;&lt;/p&gt;&lt;p&gt;Új virtuális gép létrehozásához kattints az &lt;b&gt;Új&lt;/b&gt; gombra az eszköztáron.&lt;/p&gt;&lt;p&gt;Az &lt;b&gt;%1&lt;/b&gt; billentyű megnyomásával azonnali segítséget kérhetsz, vagy látogass el a &lt;a href=http://www.virtualbox.org&gt;www.virtualbox.org&lt;/a&gt; címre a legfrissebb információkért és hírekért.&lt;/p&gt;</translation>
+ <translation>&lt;h3&gt;Üdvözöl a VirtualBox!&lt;/h3&gt;&lt;p&gt;Az ablak bal oldali részében a virtuális gépeid listáját látod. Ez jelenleg üres, hiszen most indítod ezt a programot először.&lt;img src=welcome.png align=right/&gt;&lt;/p&gt;&lt;p&gt;Új virtuális gép létrehozásához kattints az &lt;b&gt;Új&lt;/b&gt; gombra az eszköztáron.&lt;/p&gt;&lt;p&gt;Az &lt;b&gt;%1&lt;/b&gt; billentyű megnyomásával azonnali segítséget kérhetsz, vagy látogass el a &lt;a href=http://www.virtualbox.org&gt;www.virtualbox.org&lt;/a&gt; címre a legfrissebb információkért és hírekért.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Virtual Media Manager...</source>
@@ -10583,6 +11250,18 @@ to the system default language.&lt;/qt&gt;
<source>Show Statusbar</source>
<translation>Ãllapotsor mutatása</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation>K&amp;lónozás...</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>A kiválasztott virtuális gép klónozása</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation>Mentett állapot eldobá&amp;sa</translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -10986,6 +11665,14 @@ parancsot Linux-alapú OS-ekből. Integrációs szolgáltatások szükségesek h
<source> (%1 ago)</source>
<translation> (%1)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation>&amp;Klónozás...</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>A kiválasztott virtuális gép klónozása</translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_id.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_id.ts
index 5d964f3ff..003f48490 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_id.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_id.ts
@@ -504,11 +504,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">&amp;Setting...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -674,11 +755,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation type="unfinished">Adapter %1</translation>
@@ -802,6 +878,26 @@
<comment>details report</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -886,6 +982,10 @@
<source>Restore Defaults</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1121,6 +1221,10 @@
<source>Cancel</source>
<translation type="obsolete">Batal</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">Mulai</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1194,41 +1298,6 @@
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Garis Besar</translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished">Bahasa</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Jaringan</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1631,6 +1700,57 @@
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1700,23 +1820,23 @@
</message>
<message>
<source>Left Shift</source>
- <translation>Shift Kiri</translation>
+ <translation type="obsolete">Shift Kiri</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Shift Kanan</translation>
+ <translation type="obsolete">Shift Kanan</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Ctrl Kiri</translation>
+ <translation type="obsolete">Ctrl Kiri</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Ctrl Kanan</translation>
+ <translation type="obsolete">Ctrl Kanan</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Alt Kiri</translation>
+ <translation type="obsolete">Alt Kiri</translation>
</message>
<message>
<source>Right Alt</source>
@@ -1885,6 +2005,10 @@
<source>Restore Defaults</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2023,11 +2147,6 @@
<translation type="obsolete">&lt;hr&gt;VRDP Server mendengarkan pada port %1</translation>
</message>
<message>
- <source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
- <comment>Virtualization Stuff LED</comment>
- <translation></translation>
- </message>
- <message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation></translation>
@@ -2048,6 +2167,11 @@
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2226,7 +2350,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2376,6 +2504,10 @@
<source>Show At &amp;Top Of Screen</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2491,10 +2623,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>A&amp;dvanced</source>
<translation type="unfinished"></translation>
</message>
@@ -2518,6 +2646,42 @@
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -2907,10 +3071,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
@@ -3146,6 +3306,60 @@
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3319,6 +3533,32 @@
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3444,7 +3684,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -3558,6 +3798,21 @@
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3603,7 +3858,7 @@
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Ciptakan Disk Virtual Baru</translation>
@@ -3692,7 +3947,7 @@ sebagai ukuran hard disk virtual.&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Risalah</translation>
+ <translation type="unfinished">Risalah</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -3708,7 +3963,7 @@ sebagai ukuran hard disk virtual.&lt;/p&gt;</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Pilih sebuah file untuk file image hard disk baru</translation>
+ <translation type="unfinished">Pilih sebuah file untuk file image hard disk baru</translation>
</message>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;
@@ -3729,12 +3984,12 @@ bergantung pada ukuran image dan performa tulis harddisk anda.&lt;/p&gt;</transl
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Lokasi</translation>
+ <translation type="unfinished">Lokasi</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Ukuran</translation>
+ <translation type="unfinished">Ukuran</translation>
</message>
<message>
<source>Cancel</source>
@@ -3744,111 +3999,226 @@ bergantung pada ukuran image dan performa tulis harddisk anda.&lt;/p&gt;</transl
<source>Storage Type</source>
<translation type="obsolete">Tipe Storage</translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage1</name>
<message>
- <source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation type="unfinished">Selamat Datang di Wizard untuk Menciptakan Disk Virtual Baru!</translation>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <source>Create</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage2</name>
<message>
- <source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
+ <source>Copy Virtual Disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Storage Type</source>
- <translation type="unfinished">Tipe Storage</translation>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Dynamically expanding storage</source>
+ <source>Welcome to the virtual disk copying wizard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Fixed-size storage</source>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hard Disk Storage Type</source>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage3</name>
<message>
- <source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Location</source>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Size</source>
+ <source>Welcome to the virtual disk creation wizard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Virtual Disk Location and Size</source>
- <translation type="unfinished">Lokasi dan Ukuran Disk Virtual</translation>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Select a file for the new hard disk image file</source>
- <translation type="unfinished">Pilih sebuah file untuk file image hard disk baru</translation>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Hard disk images (*.vdi)</source>
- <translation type="unfinished">Image hard disk (*.vdi)</translation>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage4</name>
<message>
- <source>You are going to create a new virtual hard disk with the following parameters:</source>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary</source>
- <translation type="unfinished">Risalah</translation>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>%1 B</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Type</source>
+ <source>File type</source>
<comment>summary</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Location</source>
+ <source>Details</source>
<comment>summary</comment>
- <translation type="unfinished">Lokasi</translation>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
<message>
- <source>Size</source>
- <comment>summary</comment>
- <translation type="unfinished">Ukuran</translation>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
<message>
- <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
+ <source>Storage details</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
+ <name>UINewHDWizardPageWelcome</name>
+ <message>
+ <source>Welcome to the Create New Virtual Disk Wizard!</source>
+ <translation type="obsolete">Selamat Datang di Wizard untuk Menciptakan Disk Virtual Baru!</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWzdPage2</name>
+ <message>
+ <source>Storage Type</source>
+ <translation type="obsolete">Tipe Storage</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWzdPage3</name>
+ <message>
+ <source>Virtual Disk Location and Size</source>
+ <translation type="obsolete">Lokasi dan Ukuran Disk Virtual</translation>
+ </message>
+ <message>
+ <source>Select a file for the new hard disk image file</source>
+ <translation type="obsolete">Pilih sebuah file untuk file image hard disk baru</translation>
+ </message>
+ <message>
+ <source>Hard disk images (*.vdi)</source>
+ <translation type="obsolete">Image hard disk (*.vdi)</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWzdPage4</name>
+ <message>
+ <source>Summary</source>
+ <translation type="obsolete">Risalah</translation>
+ </message>
+ <message>
+ <source>Location</source>
+ <comment>summary</comment>
+ <translation type="obsolete">Lokasi</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <comment>summary</comment>
+ <translation type="obsolete">Ukuran</translation>
+ </message>
+</context>
+<context>
<name>UINewVMWzd</name>
<message>
<source>Create New Virtual Machine</source>
@@ -4035,6 +4405,10 @@ langkah ini dan memasang hard disk pada waktu lain menggunakan dialog Setting Me
<source>Cancel</source>
<translation type="obsolete">Batal</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4256,6 +4630,96 @@ langkah ini dan memasang hard disk pada waktu lain menggunakan dialog Setting Me
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Garis Besar</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation type="unfinished">Bahasa</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Jaringan</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Garis Besar</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished">Suara</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Jaringan</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation type="unfinished">Port Serial</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation type="unfinished">Port Paralel</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation type="unfinished">Folder yang di Share</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -4394,81 +4858,6 @@ langkah ini dan memasang hard disk pada waktu lain menggunakan dialog Setting Me
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Garis Besar</translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished">Suara</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Jaringan</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished">Port Serial</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished">Port Paralel</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished">Folder yang di Share</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -4700,6 +5089,14 @@ Versi %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -6365,7 +6762,7 @@ Versi %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation type="unfinished">Adapter %1</translation>
+ <translation type="obsolete">Adapter %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Attached to:&amp;nbsp;&amp;nbsp;%1&lt;/nobr&gt;</source>
@@ -6756,21 +7153,11 @@ Versi %1</translation>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>SAS</source>
<comment>StorageBus</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation type="unfinished"></translation>
@@ -6960,6 +7347,61 @@ Versi %1</translation>
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Adapter %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7679,15 +8121,11 @@ ke nilai awal bahasa sistem.&lt;/qt&gt;
</message>
<message>
<source>Location</source>
- <translation type="unfinished">Lokasi</translation>
- </message>
- <message>
- <source>Type (Format)</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Lokasi</translation>
</message>
<message>
<source>Attached to</source>
- <translation type="unfinished">Terpasang pada</translation>
+ <translation type="obsolete">Terpasang pada</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -7765,17 +8203,17 @@ ke nilai awal bahasa sistem.&lt;/qt&gt;
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation type="unfinished">Terpasang pada</translation>
+ <translation type="obsolete">Terpasang pada</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation type="unfinished">Terpasang pada</translation>
+ <translation type="obsolete">Terpasang pada</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation type="unfinished">Terpasang pada</translation>
+ <translation type="obsolete">Terpasang pada</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -7793,6 +8231,46 @@ ke nilai awal bahasa sistem.&lt;/qt&gt;
<source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -7841,13 +8319,6 @@ ke nilai awal bahasa sistem.&lt;/qt&gt;
</message>
</context>
<context>
- <name>VBoxNetworkDialog</name>
- <message>
- <source>Network Adapters</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxOSTypeSelectorWidget</name>
<message>
<source>Operating &amp;System:</source>
@@ -8635,10 +9106,6 @@ ke nilai awal bahasa sistem.&lt;/qt&gt;
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
<translation type="unfinished"></translation>
</message>
@@ -8739,10 +9206,6 @@ ke nilai awal bahasa sistem.&lt;/qt&gt;
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restore</source>
<translation type="unfinished"></translation>
</message>
@@ -9084,15 +9547,75 @@ ke nilai awal bahasa sistem.&lt;/qt&gt;
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -9167,7 +9690,7 @@ ke nilai awal bahasa sistem.&lt;/qt&gt;
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Folder yang di Share</translation>
+ <translation type="obsolete">Folder yang di Share</translation>
</message>
<message>
<source>Cancel</source>
@@ -9294,11 +9817,11 @@ ke nilai awal bahasa sistem.&lt;/qt&gt;
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Aba&amp;ikan</translation>
+ <translation type="obsolete">Aba&amp;ikan</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Abaikan</translation>
+ <translation type="unfinished">Abaikan</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -9584,6 +10107,18 @@ ke nilai awal bahasa sistem.&lt;/qt&gt;
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -9939,6 +10474,14 @@ untuk mengaksesnya dari sebuah SIstem Operasi Linux. Fitur ini membutuhkan Guest
<source> (%1 ago)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts
index a7b46b3ce..557e0c243 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts
@@ -569,12 +569,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>I&amp;nformazioni di sessione</translation>
+ <translation type="obsolete">I&amp;nformazioni di sessione</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>Abilita sch&amp;ermo remoto</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation>Impo&amp;stazioni...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation>Gestisci le impostazioni della macchina virtuale</translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation>I&amp;nformazioni di sessione...</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation>Clona una macchina virtuale</translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation>Clona</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Questa procedura ti aiuterà a creare un clone della macchina virtuale.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Scegli un nome per la nuova macchina virtuale:&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>Se marcata, sarà assegnato un indirizzo MAC nuovo e unico a tutte le schede di rete configurate.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>Inizializza nuovamente l&apos;indi&amp;rizzo MAC di tutte le schede di rete</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation>Benvenuti nella procedura guidata di clonazione di una macchina virtuale</translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation>Clone di %1</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation>Stato corrente della macchina</translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation>Lo stato corrente della macchina e di tutti i figli</translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation>Tutti gli stati</translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation>Configurazione clonazione</translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation>Scegli quali parti della macchina virtuale saranno clonate.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation>Se selezioni &lt;b&gt;Stato corrente della macchina&lt;/b&gt;, sarà clonato solo lo stato corrente della macchina virtuale.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation>Se selezioni &lt;b&gt;Stato corrente della macchina e di tutti i figli&lt;/b&gt;, saranno clonati sia lo stato corrente della macchina virtuale che quello delle istantanee collegate.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation>Se selezioni &lt;b&gt;Tutti gli stati&lt;/b&gt;, saranno clonati sia lo stato corrente della macchina che quello di tutte le istantanee.</translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -740,7 +825,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Rete VDE. &apos;%1&apos;</translation>
+ <translation type="obsolete">Rete VDE. &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -866,6 +951,26 @@
<comment>details report</comment>
<translation>Descrizione</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation>Execution Cap</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation>&lt;nobr&gt;%1%&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>Driver generico, &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation>Driver generico, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -1066,6 +1171,10 @@
<source>&amp;Hostname:</source>
<translation type="obsolete">Nome &amp;host:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation>Esporta</translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1417,6 +1526,10 @@ p, li { white-space: pre-wrap; }
<source>Cancel</source>
<translation type="obsolete">Annulla</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation>Avvia</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1490,41 +1603,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Generale</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Inserimento</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Aggiornamento</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Lingua</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Rete</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Estensioni</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1646,7 +1724,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>When checked, the keyboard is automatically captured every time the VM window is activated. When the keyboard is captured, all keystrokes (including system ones like Alt-Tab) are directed to the VM.</source>
- <translation>Se selezionato, la tastiera è acquisita automaticamente ogni volta che la finestra della MV è attivata. Una volta che la tastiera è acquisita, tutte le combinazioni di tasti (incluse quelle di sistema come Alt-Tab) sono dirette alla MV.</translation>
+ <translation>Se marcata, la tastiera è acquisita automaticamente ogni volta che la finestra della MV è attivata. Una volta che la tastiera è acquisita, tutte le combinazioni di tasti (incluse quelle di sistema come Alt-Tab) sono dirette alla MV.</translation>
</message>
<message>
<source>&amp;Auto Capture Keyboard</source>
@@ -1965,6 +2043,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation>Se marcata, VirtualBox utilizzerà le impostazioni del proxy fornite per attività come lo scaricamento delle Guest Additions dalla rete o il controllo degli aggiornamenti.</translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation>A&amp;bilita il proxy</translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation>Ho&amp;st:</translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation>Cambia l&apos;host del proxy.</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Porta:</translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation>Cambia la porta del proxy.</translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation>Se marcata, l&apos;autenticazione fornita sarà utilizzata per il server proxy.</translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation>&amp;Utilizza l&apos;autenticazione</translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation>&amp;Nome utente:</translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation>Cambia il nome utente utilizzato per l&apos;autenticazione.</translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation>Pass&amp;word:</translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation>Cambia la password utilizzata per l&apos;autenticazione.</translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -2034,23 +2163,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Shift sinistro</translation>
+ <translation type="obsolete">Shift sinistro</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Shift destro</translation>
+ <translation type="obsolete">Shift destro</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Ctrl sinistro</translation>
+ <translation type="obsolete">Ctrl sinistro</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Ctrl destro</translation>
+ <translation type="obsolete">Ctrl destro</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Alt sinistro</translation>
+ <translation type="obsolete">Alt sinistro</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2267,6 +2396,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importa &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation>Importa</translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2411,7 +2544,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Indica lo stato delle funzionalità di virtualizzazione hardware utilizzate da questa macchina virtuale:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Indica lo stato delle funzionalità di virtualizzazione hardware utilizzate da questa macchina virtuale:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2434,6 +2567,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;Il server di desktop remoto è in ascolto sulla porta %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation>Indica lo stato di diverse funzionalità utilizzate dalla macchina virtuale:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2629,7 +2767,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Hai abilitato l&apos;accelerazione 3D per un sistema operativo che utilizza il driver video WDDM. Per massimizzare le prestazioni imposta la VRAM del Guest almeno a &lt;b&gt;%1&lt;/b&gt;.</translation>
+ <translation type="obsolete">Hai abilitato l&apos;accelerazione 3D per un sistema operativo che utilizza il driver video WDDM. Per massimizzare le prestazioni imposta la VRAM del Guest almeno a &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>hai l&apos;accelerazione 3D abilitata per un sistema operativo che utilizza il driver video WDDM. Per ottenere il massimo delle prestazioni, imposta la VRAM del guest almeno a &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation>hai l&apos;accelerazione video 2D abilitata. Poiché l&apos;accelerazione 2D è supportata dai soli guest Windows, questa funzionalità sarà disabilitata.</translation>
</message>
</context>
<context>
@@ -2870,6 +3016,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Most&amp;ra nella parte alta dello schermo</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation>hai selezionato un SO guest a 64 bit per questa MV. Poiché questo tipo di guest richiede la virtualizzazione hardware (VT-x/AMD-V), questa funzionalità sarà abilitata automaticamente.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -3051,7 +3201,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Seleziona il nome della scheda di rete se il tipo di collegamento è &lt;b&gt;Scheda con bridge&lt;/b&gt; o &lt;b&gt;Scheda solo host&lt;/b&gt; e il nome della rete interna se il tipo di collegamento è uguale a &lt;b&gt;Rete interna&lt;/b&gt;.</translation>
+ <translation type="obsolete">Seleziona il nome della scheda di rete se il tipo di collegamento è &lt;b&gt;Scheda con bridge&lt;/b&gt; o &lt;b&gt;Scheda solo host&lt;/b&gt; e il nome della rete interna se il tipo di collegamento è uguale a &lt;b&gt;Rete interna&lt;/b&gt;.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -3077,6 +3227,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>Inoltro delle &amp;porte</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation>Modalità &amp;promiscua:</translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation>Seleziona la modalità promiscua della scheda di rete quando è collegata a una rete interna, solo host o bridge.</translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation>Proprietà generali:</translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation>Inserisci qui ogni impostazione di configurazione del driver del collegamentoJ di rete che utilizzerai. Le impostazioni dovrebbero essere nella forma &lt;b&gt;nome=valore&lt;/b&gt; e dipenderanno dal driver. Utilizza &lt;b&gt;maiusc-invio&lt;/b&gt; per aggiungere una nuova voce.</translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation>non è selezionato alcun driver generico</translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation>Seleziona la scheda di rete sul sistema host sulla quale transiterà il traffico verso e da questa scheda di rete.</translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation>Inserisci il nome della rete interna alla quale questa scheda di rete sarà collegata. Puoi creare una nuova rete interna scegliendo un nome che non è utilizzato da un&apos;altra scheda di rete in questa macchina virtuale o in altre.</translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation>Seleziona la scheda di rete virtuale sul sistema host attraverso la quale il traffico verso e da questa scheda di rete transiterà. Puoi creare e rimuovere le schede utilizzando le impostazioni di rete generali nella finestra del gestore della macchina virtuale.</translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation>Seleziona il driver da utilizzare per questa scheda di rete.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3607,7 +3793,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Nessun disco fisso selezionato per &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">Nessun disco fisso selezionato per &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3881,6 +4067,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation>Scegli un file di disco floppy virtuale...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation>Se marcata, impedisce lo smontaggio del supporto quando il sistema operativo guest lo rimuove.</translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation>&amp;Live CD/DVD</translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation>Se marcata, segna il supporto come archiviazione senza rotazione (SSD).</translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation>Di&amp;sco a stato solido</translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation>Dettagli:</translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>nessun nome specificato per il controller nella posizione &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation>il controller nella posizione &lt;b&gt;%1&lt;/b&gt; utilizza il nome già assegnato al controller nella posizione &lt;b&gt;%2&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation>nessun disco fisso selezionato per &lt;i&gt;%1&lt;/i&gt;.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation>al massimo uno supportato</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation>fino a %1 supportati</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation>stai attualmente utilizzando più controller di archiviazione di quanti un chipset %1 supporti. Cambia il tipo di chipset nella pagina delle impostazioni Sistema o riduci il numero dei seguenti controller di archiviazione nella pagina delle impostazioni Archiviazione: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation>Numero &amp;porte:</translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation>Seleziona il numero delle porte del controller di archiviazione SATA selezionato nell&apos;albero di archiviazione. Questo valore non può essere minore del numero di porte utilizzato + 1.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3902,11 +4142,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>you have assigned more than one virtual CPU to this VM. This will not work unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>c&apos;è più di una CPU virtuale assegnate a questa MV, che richiede che anche la funzionalità IO-APIC sia abilitata, altrimenti SMP non funzionerà, perciò questa funzionalità sarà abilitata automaticamente quando accetterai le impostazioni della MV premendo il pulsante OK.</translation>
+ <translation>c&apos;è più di una CPU virtuale assegnata a questa MV, che richiede che anche la funzionalità IO-APIC sia abilitata. Questa funzionalità sarà abilitata automaticamente quando accetterai le impostazioni della MV, premendo il pulsante OK.</translation>
</message>
<message>
<source>you have assigned more than one virtual CPU to this VM. This will not work unless hardware virtualization (VT-x/AMD-V) is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>c&apos;è più di una CPU virtuale assegnate a questa MV, che richiede che anche la funzionalità di virtualizzazione (VT-x/AMD-V) sia abilitata, altrimenti SMP non funzionerà, perciò questa funzionalità sarà abilitata automaticamente quando accetterai le impostazioni della MV premendo il pulsante OK.</translation>
+ <translation>c&apos;è più di una CPU virtuale assegnata a questa MV. Ciò richiede che anche la virtualizzazione hardware (VT-x/AMD-V) sia abilitata. Questa funzionalità sarà abilitata automaticamente quando accetterai le impostazioni della MV, premendo il pulsante OK.</translation>
</message>
<message>
<source>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</source>
@@ -4071,6 +4311,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>hai assegnato il tipo di chipset ICH9 a questa macchina virtuale. Funzionerà correttamente solo se anche la funzionalità IO-APIC è abilitata. Ciò avverrà automaticamente quando accetti le impostazioni della MV, premendo il pulsante OK.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation>&amp;Execution Cap:</translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation>Limita la quantità di tempo destinata all&apos;esecuzione di ogni CPU virtuale. Ogni CPU virtual potrà utlizzare fino a questa percentuale del tempo di elaborazione disponibile in una CPU fisica. Execution cap può essere disabilitato impostandolo al 100%. L&apos;impostazione di un limite troppo basso può rendere lenta la risposta della macchina.</translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation>hai impostato un valore basso di execution cap del processore. Ciò potrebbe rendere lenta la risposta della macchina.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation>hai abilitato un HID (Human Interface Device) USB. Non funzionerà a meno che non sia abilitata anche l&apos;emulazione USB. Ciò avverrà automaticamente quando accetti le impostazioni della MV, premendo il pulsante OK.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation>&lt;qt&gt;%1%&lt;/qt&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation>&lt;qt&gt;%1%&lt;/qt&gt;</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -4197,7 +4463,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>USB 2.0 è attualmente abilitato per questa macchina virtuale. In ogni caso, ciò richiede che &lt;b&gt;%1&lt;/b&gt; sia installato. Installa l&apos;Extension Pack dal sito di VirtualBox. Una volta installato, sarà possibile ri-abilitare USB 2.0. Nel frattempo sarà disabilitato a meno che annulli le modifiche correnti alle impostazioni.</translation>
+ <translation type="obsolete">USB 2.0 è attualmente abilitato per questa macchina virtuale. In ogni caso, ciò richiede che &lt;b&gt;%1&lt;/b&gt; sia installato. Installa l&apos;Extension Pack dal sito di VirtualBox. Una volta installato, sarà possibile ri-abilitare USB 2.0. Nel frattempo sarà disabilitato a meno che annulli le modifiche correnti alle impostazioni.</translation>
+ </message>
+ <message>
+ <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>USB 2.0 è attualmente abilitato per questa macchina virtuale. In ogni caso, ciò richiede che &lt;b&gt;%1&lt;/b&gt; sia installato. Installa l&apos;Extension Pack dal sito di VirtualBox. Dopo potrai riabilitare l&apos;USB 2.0. Nel frattempo, sarà disabilitato a meno che tu non annulli le modifiche correnti.</translation>
</message>
</context>
<context>
@@ -4310,6 +4580,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation>Modifica gli attributi del supporto</translation>
+ </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;Stai per cambiare gli attributi del disco virtuale posizionato in &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Scegli uno dei seguenti tipi di supporto e premi &lt;b&gt;%2&lt;/b&gt; per procedere o &lt;b&gt;%3&lt;/b&gt; altrimenti.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation>Scegli il tipo di supporto:</translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4355,7 +4640,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Crea un nuovo disco virtuale</translation>
@@ -4453,7 +4738,7 @@ come dimensione dell&apos;hard disk virtuale.&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Riassunto</translation>
+ <translation>Riepilogo</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4469,7 +4754,7 @@ come dimensione dell&apos;hard disk virtuale.&lt;/p&gt;</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Seleziona un file per la nuova immagine di disco fisso</translation>
+ <translation>Seleziona un file per la nuova immagine di disco fisso</translation>
</message>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;
@@ -4508,12 +4793,12 @@ alla velocità di scrittura del tuo disco rigido.&lt;/p&gt;</translation>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Posizione</translation>
+ <translation>Posizione</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Dimensione</translation>
+ <translation>Dimensione</translation>
</message>
<message>
<source>Bytes</source>
@@ -4572,108 +4857,276 @@ alla velocità di scrittura del tuo disco rigido.&lt;/p&gt;</translation>
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Se le precedenti impostazioni sono corrette, premi il pulsante &lt;b&gt;Fine&lt;/b&gt;. Una volta premuto, sarà creato un nuovo disco fisso.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation>%1_copia</translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation>Crea</translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation>Copia disco virtuale</translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation>Copia</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation>Benvenuti nella procedura guidata di copia di un disco virtuale</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Questa procedurà ti aiuterà a copiare un disco virtuale.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation>Seleziona il disco virtuale che desideri copiare se non è ancora selezionato. Puoi sceglierne uno dall&apos;elenco o utilizzare l&apos;icona della cartella accanto all&apos;elenco per selezionare il file di disco virtuale.</translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation>&amp;VDI (VirtualBox Disk Image)</translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation>V&amp;MDK (Virtual Machine Disk)</translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation>V&amp;HD (Virtual Hard Disk)</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation>Benvenuti nella procedura guidata di creazione di un nuovo disco virtuale</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Questa procedura ti aiuterà a creare un nuovo disco fisso per la macchina virtuale.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Scegli il tipo del file che desideri utilizzare per il nuovo disco virtuale. Se non pensi di utilizzarlo con altri programmi di virtualizzazione, puoi lasciare inalterata questa opzione.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation>Tipo di file del disco virtuale</translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation>Scegli il tipo del file che desideri utilizzare per il nuovo disco virtuale. Se non pensi di utilizzarlo con altri programmi di virtualizzazione, puoi lasciare inalterata questa impostazione.</translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation>Dettagli di archiviazione del disco virtuale</translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation>Scegli se il file del nuovo disco virtuale deve essere allocato al momento del suo utilizzo o se deve essere allocato completamente in fase di creazione.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Un disco virtuale &lt;b&gt;allocato dinamicamente&lt;/b&gt; utilizzerà solo lo spazio del disco fisico che si riempe, ma non si ridurrà automaticamente se lo spazio viene liberato.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Un file di disco virtuale a &lt;b&gt;dimensione fissa&lt;/b&gt; richiede normalmente più tempo per la creazione, ma è più veloce nell&apos;utilizzo.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation>&lt;p&gt;Puoi scegliere anche di &lt;b&gt;dividere&lt;/b&gt; il disco virtuale in diversi file, ognuno della dimensione massima di due gygabyte. È utile principalmente se desideri archiviare la macchina virtuale su dispositivi USB o sistemi datati, alcuni dei quali non sono in grado di gestire file molto grandi.</translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation>Allocato &amp;dinamicamente</translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation>Dimensione &amp;fissa</translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation>Dividi in file di dimen&amp;sione inferiore a 2GB</translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation>Posizione e dimensione del file del disco virtuale</translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation>Seleziona la dimensione del disco virtuale in megabyte. Tale dimensione sarà presentata al sistema operativo guest come dimensione massima del disco virtuale.</translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation>Posizione del file del disco virtuale</translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation>Premi il pulsante &lt;b&gt;Seleziona&lt;/b&gt; per selezionare la posizione di un file dove archiviare i dati del disco virtuale o digita un nome file nel campo di inserimento.</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation>Stai per creare un nuovo disco virtuale con i seguenti parametri:</translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation>Stai per creare la copia di un disco virtuale con i seguenti parametri:</translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation>Se le impostazioni precedenti sono corrette, premi il pulsante &lt;b&gt;%1&lt;/b&gt;. Una volta premuto, il file del disco virtuale sarà creato.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation>Tipo di file</translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation>Dettagli</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation>Tipo di file</translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation>&amp;Posizione</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation>Dimen&amp;sione</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation>Dettagli di archiviazione</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Benvenuti nella procedura di creazione di un nuovo disco virtuale!</translation>
+ <translation type="obsolete">Benvenuti nella procedura di creazione di un nuovo disco virtuale!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Questa procedura guidata ti aiuterà a creare un nuovo disco fisso per la macchina virtuale.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Questa procedura guidata ti aiuterà a creare un nuovo disco fisso per la macchina virtuale.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation>Disco virtuale da copiare</translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation>Scegli un file di disco fisso virtuale...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Seleziona il tipo di disco fisso virtuale che vuoi creare.&lt;/p&gt;&lt;p&gt;Un&apos;unità di &lt;b&gt;archiviazione a espansione dinamica&lt;/b&gt; occupa inizialmente una quantità molto piccola di spazio sul disco fisico, che crescerà in modo dinamico (fino alla dimensione specificata) in base alla richiesta di spazio su disco del sistema guest.&lt;/p&gt;&lt;p&gt;Un&apos;unità di &lt;b&gt;archiviazione a dimensione fissa&lt;/b&gt; non cresce. Sarà conservata in un file con dimensioni molto vicine a quelle del disco fisso virtuale. La creazione di un&apos;unità di archiviazione a dimensione fissa potrebbe richiedere molto tempo, a seconda della dimensione scelta e delle prestazioni in scrittura del disco fisso fisico.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Seleziona il tipo di disco fisso virtuale che vuoi creare.&lt;/p&gt;&lt;p&gt;Un&apos;unità di &lt;b&gt;archiviazione a espansione dinamica&lt;/b&gt; occupa inizialmente una quantità molto piccola di spazio sul disco fisico, che crescerà in modo dinamico (fino alla dimensione specificata) in base alla richiesta di spazio su disco del sistema guest.&lt;/p&gt;&lt;p&gt;Un&apos;unità di &lt;b&gt;archiviazione a dimensione fissa&lt;/b&gt; non cresce. Sarà conservata in un file con dimensioni molto vicine a quelle del disco fisso virtuale. La creazione di un&apos;unità di archiviazione a dimensione fissa potrebbe richiedere molto tempo, a seconda della dimensione scelta e delle prestazioni in scrittura del disco fisso fisico.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Tipo di archiviazione</translation>
+ <translation type="obsolete">Tipo di archiviazione</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>Archiviazione a espansione &amp;dinamica</translation>
+ <translation type="obsolete">Archiviazione a espansione &amp;dinamica</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>Archiviazione a dimensione &amp;fissa</translation>
+ <translation type="obsolete">Archiviazione a dimensione &amp;fissa</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Tipo di archiviazione disco fisso</translation>
+ <translation type="obsolete">Tipo di archiviazione disco fisso</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Premi il pulsante &lt;b&gt;Seleziona&lt;/b&gt; per selezionare la posizione di un file per memorizzare i dati del disco fisso o digita un nome file nel campo di inserimento.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Premi il pulsante &lt;b&gt;Seleziona&lt;/b&gt; per selezionare la posizione di un file per memorizzare i dati del disco fisso o digita un nome file nel campo di inserimento.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;Posizione</translation>
+ <translation type="obsolete">&amp;Posizione</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Seleziona la dimensione del disco fisso virtuale in megabyte. Questa dimensione sarà riportata nel sistema Guest come dimensione massima del disco fisso.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Seleziona la dimensione del disco fisso virtuale in megabyte. Questa dimensione sarà riportata nel sistema Guest come dimensione massima del disco fisso.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Dimensione</translation>
+ <translation type="obsolete">&amp;Dimensione</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Posizione e dimensione del disco virtuale</translation>
+ <translation type="obsolete">Posizione e dimensione del disco virtuale</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Seleziona un file per la nuova immagine di disco fisso</translation>
+ <translation type="obsolete">Seleziona un file per la nuova immagine di disco fisso</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Immagini disco fisso (*.vdi)</translation>
+ <translation type="obsolete">Immagini disco fisso (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Stai per creare un nuovo disco fisso virtuale con i seguenti parametri:</translation>
+ <translation type="obsolete">Stai per creare un nuovo disco fisso virtuale con i seguenti parametri:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Riepilogo</translation>
- </message>
- <message>
- <source>%1 B</source>
- <translation></translation>
+ <translation type="obsolete">Riepilogo</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Tipo</translation>
+ <translation type="obsolete">Tipo</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Posizione</translation>
+ <translation type="obsolete">Posizione</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Dimensione</translation>
+ <translation type="obsolete">Dimensione</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Se le precedenti impostazioni sono corrette, premi il pulsante &lt;b&gt;%1&lt;/b&gt;. Una volta premuto, sarà creato un nuovo disco fisso.</translation>
+ <translation type="obsolete">Se le precedenti impostazioni sono corrette, premi il pulsante &lt;b&gt;%1&lt;/b&gt;. Una volta premuto, sarà creato un nuovo disco fisso.</translation>
</message>
</context>
<context>
@@ -4913,6 +5366,10 @@ questo passo e collegare hard disk più tardi tramite Impostazioni della MV.&lt;
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">&amp;Usa un disco fisso esistente</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation>Crea</translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -5188,6 +5645,120 @@ questo passo e collegare hard disk più tardi tramite Impostazioni della MV.&lt;
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Generale</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Inserimento</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Aggiornamento</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Lingua</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rete</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Estensioni</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation>Proxy</translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Generale</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>Sistema</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Schermo</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Archiviazione</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Audio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rete</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Porte</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Porte seriali</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Porte parallele</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Cartelle condivise</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">hai selezionato un sistema operativo guest a 64 bit per questa MV. Poiché questo tipo di guest richiede la virtualizzazione hardware (VT-x/AMD-V), questa funzionalità sarà abilitata automaticamente.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">hai l&apos;accelerazione video 2D abilitata. Poiché l&apos;accelerazione 2D è supportata dai soli guest Windows, questa funzionalità sarà disabilitata.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">hai abilitato un HID USB (dispositivo di interfaccia umana). Non funzionerà se l&apos;emulazione USB non è abilitata. Ciò avviene automaticamente quando accetti le impostazione della MV, premendo il pulsante OK.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">al massimo uno supportato</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">fino a %1 supportati</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">stai attualmente utilizzando più controller di archiviazione di quanti un chipset %1 supporti. Cambia il tipo di chipset nella pagina delle impostazioni Sistema o riduci il numero dei seguenti controller di archiviazione nella pagina delle impostazioni Archiviazione: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -5326,81 +5897,6 @@ questo passo e collegare hard disk più tardi tramite Impostazioni della MV.&lt;
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Generale</translation>
- </message>
- <message>
- <source>System</source>
- <translation>Sistema</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Schermo</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Archiviazione</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Audio</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Rete</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Porte</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Porte seriali</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Porte parallele</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Cartelle condivise</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>hai selezionato un sistema operativo guest a 64 bit per questa MV. Poiché questo tipo di guest richiede la virtualizzazione hardware (VT-x/AMD-V), questa funzionalità sarà abilitata automaticamente.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>hai l&apos;accelerazione video 2D abilitata. Poiché l&apos;accelerazione 2D è supportata dai soli guest Windows, questa funzionalità sarà disabilitata.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>hai abilitato un HID USB (dispositivo di interfaccia umana). Non funzionerà se l&apos;emulazione USB non è abilitata. Ciò avviene automaticamente quando accetti le impostazione della MV, premendo il pulsante OK.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>al massimo uno supportato</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>fino a %1 supportati</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>stai attualmente utilizzando più controller di archiviazione di quanti un chipset %1 supporti. Cambia il tipo di chipset nella pagina delle impostazioni Sistema o riduci il numero dei seguenti controller di archiviazione nella pagina delle impostazioni Archiviazione: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5626,6 +6122,14 @@ Versione %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation>Controller del disco fisso (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>Se marcata, un indirizzo MAC nuovo e unico sarà assegnato a tutte le schede di rete configurate.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>Inizializza nuovamente l&apos;indi&amp;rizzo MAC di tutte le schede di rete</translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -7629,7 +8133,7 @@ Versione %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Scheda %1</translation>
+ <translation type="obsolete">Scheda %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -8091,7 +8595,7 @@ Versione %1</translation>
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Rete VDE. &apos;%1&apos;</translation>
+ <translation type="obsolete">Rete VDE. &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -8101,7 +8605,7 @@ Versione %1</translation>
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>Scheda VDE</translation>
+ <translation type="obsolete">Scheda VDE</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -8298,6 +8802,61 @@ Versione %1</translation>
<comment>DiskType</comment>
<translation>Collegamento multiplo</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation>Archiviazione allocata dinamicamente</translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation>Archiviazione a dimensione fissa</translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation>Archiviazione allocata dinamicamente divisa in file di dimensione inferiore a 2GB</translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation>Archiviazione a dimensione fissa divisa in file di dimensione inferiore a 2GB</translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation>Execution Cap</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation>&lt;nobr&gt;%1%&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>Generico, &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation>Driver generico</translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>Nega</translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>Permetti MV</translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>Permetti tutto</translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation>Scheda %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -8955,7 +9514,7 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
</message>
<message>
<source>Perform case sensitive search (when checked)</source>
- <translation>Abilita la ricerca confrontando maiuscole e minuscole</translation>
+ <translation>Abilita la ricerca confrontando maiuscole e minuscole (se marcata)</translation>
</message>
<message>
<source>String not found</source>
@@ -9029,15 +9588,15 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
</message>
<message>
<source>Location</source>
- <translation>Posizione</translation>
+ <translation type="obsolete">Posizione</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Tipo (Formato)</translation>
+ <translation type="obsolete">Tipo (Formato)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Connesso a</translation>
+ <translation type="obsolete">Connesso a</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -9119,17 +9678,17 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Collegato a</translation>
+ <translation type="obsolete">Collegato a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Collegata a</translation>
+ <translation type="obsolete">Collegata a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Collegata a</translation>
+ <translation type="obsolete">Collegata a</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -9147,6 +9706,46 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
<source>All %1 images (%2)</source>
<translation>Tutte le %1 immagini (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation>Tipo:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation>Posizione:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation>Formato:</translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation>Dettagli di archiviazione:</translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation>Collegato a:</translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation>&amp;Copia...</translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation>&amp;Modifica...</translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation>Copia un supporto esistente</translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation>Modifica gli attributi del supporto selezionato</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>C&amp;hiudi</translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -9206,7 +9805,7 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Schede di rete</translation>
+ <translation type="obsolete">Schede di rete</translation>
</message>
</context>
<context>
@@ -10065,7 +10664,7 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Impossibile accedere all&apos;USB del sistema host, poiché né il file system USB (usbfs) né i servizi hal e DBus sono attualmente disponibili. Se desideri utilizzare dispositivi USB nei sistemi guest, devi apportare le dovute modifiche e riavviare VirtualBox.</translation>
+ <translation type="obsolete">Impossibile accedere all&apos;USB del sistema host, poiché né il file system USB (usbfs) né i servizi hal e DBus sono attualmente disponibili. Se desideri utilizzare dispositivi USB nei sistemi guest, devi apportare le dovute modifiche e riavviare VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -10186,7 +10785,7 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Sei sicuro di voler ripristinare l&apos;istantanea &lt;b&gt;%1&lt;/b&gt;? Ciò causerà la perdita dello stato attuale della macchina, che non può essere ripristinato.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Sei sicuro di voler ripristinare l&apos;istantanea &lt;b&gt;%1&lt;/b&gt;? Ciò causerà la perdita dello stato attuale della macchina, che non può essere ripristinato.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -10481,7 +11080,7 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">Spiacenti, si sono verificati alcuni errori generici.</translation>
+ <translation>Spiacenti, si sono verificati alcuni errori generici.</translation>
</message>
<message>
<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>
@@ -10570,7 +11169,7 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>L&apos;eliminazione di tutti i file che appartengono alla MV è attualmente disabilitata su Windows/x64 per evitare una chiusura inattesa. Il problema sarà corretto nella prossima versione.</translation>
+ <translation type="obsolete">L&apos;eliminazione di tutti i file che appartengono alla MV è attualmente disabilitata su Windows/x64 per evitare una chiusura inattesa. Il problema sarà corretto nella prossima versione.</translation>
</message>
<message>
<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>
@@ -10578,7 +11177,71 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
</message>
<message>
<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>&lt;p&gt;USB 2.0 è attualmente abilitato per questa macchina virtuale. In ogni caso, ciò richiede che &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; sia installato. Installa l&apos;Extension Pack dal sito di VirtualBox. Una volta installato, sarà possibile ri-abilitare USB 2.0. Nel frattempo sarà disabilitato a meno che annulli le modifiche correnti alle impostazioni.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;USB 2.0 è attualmente abilitato per questa macchina virtuale. In ogni caso, ciò richiede che &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; sia installato. Installa l&apos;Extension Pack dal sito di VirtualBox. Una volta installato, sarà possibile ri-abilitare USB 2.0. Nel frattempo sarà disabilitato a meno che annulli le modifiche correnti alle impostazioni.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>La registrazione della macchina virtuale &lt;b&gt;%1&lt;/b&gt; non è riuscita.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Le impostazioni della macchina sono cambiate mentre le stavi modificando. Attualmente, ci sono modifiche non salvate.&lt;/p&gt;&lt;p&gt;Vuoi ricaricare le impostazioni modificate o mantenere le modifiche?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation>Ricarica le impostazioni</translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation>Mantieni le modifiche</translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation>Lo stato della macchina virtuale che hai appena modificato è cambiato. Solo le impostazioni che sono modificabili in esecuzione sono salvate quando premi OK. Tutte le modifiche alle altre impostazioni saranno perse.</translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>La clonazione della macchina virtuale &lt;b&gt;%1&lt;/b&gt; non è riuscita.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Stai per ripristinare l&apos;istantanea &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Puoi creare subito un&apos;istantanea dello stato corrente della macchina marcando la casella seguente; se non lo fai, lo stato corrente della macchina sarà perso definitivamente. Desideri procedere?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation>Crea un&apos;istantanea dello stato corrente della macchina</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Sei sicuro di voler ripristinare l&apos;istantanea &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Errore durante il cambiamento del tipo di supporto da &lt;b&gt;%1&lt;/b&gt; a &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <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>&lt;p&gt;USB 2.0 è attualmente abilitato per questa macchina virtuale. In ogni caso, ciò richiede che &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; sia installato.&lt;/p&gt;&lt;p&gt;Installa l&apos;Extension Pack dal sito di VirtualBox. Dopo potrai riabilitare l&apos;USB 2.0. Nel frattempo, sarà disabilitato a meno che tu non annulli le modifiche correnti.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <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>Impossibile caricare il servizio Host USB Proxy (VERR_FILE_NOT_FOUND). Il servizio potrebbe non essere installato sul computer host</translation>
+ </message>
+ <message>
+ <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>Attualmente VirtualBox non ha il permesso di accedere ai dispositivi USB. Puoi cambiare questa situazione aggiungendo il tuo utente al gruppo &apos;vboxusers&apos;. Vedi il manuale utente per una spiegazione più dettagliata</translation>
+ </message>
+ <message>
+ <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>Attualmente VirtualBox non ha il permesso di accedere ai dispositivi USB. Puoi cambiare questa situazione consentendo al tuo utente di accedere ai file e alla cartella &apos;usbfs&apos;. Vedi il manuale utente per una spiegazione più dettagliata</translation>
+ </message>
+ <message>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation>Il servizio USB Proxy non è stato ancora portato su questo host</translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation>Impossibile caricare il servizio Host USB Proxy</translation>
</message>
</context>
<context>
@@ -10712,7 +11375,7 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Cartelle condivise</translation>
+ <translation type="obsolete">Cartelle condivise</translation>
</message>
<message>
<source>OK</source>
@@ -10843,11 +11506,11 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Scar&amp;ta</translation>
+ <translation type="obsolete">Scar&amp;ta</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Scarta</translation>
+ <translation>Scarta</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -11135,6 +11798,18 @@ la lingua a quella predefinita di sistema.&lt;/qt&gt;
<source>Show Statusbar</source>
<translation>Mostra la barra di stato</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation>Cl&amp;ona...</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>Clona la macchina virtuale selezionata</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation>Scarta l&amp;o stato salvato</translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -11595,6 +12270,14 @@ per accedervi da un sistema Linux. Questa funzionalità richiede Guest Additions
<source> (%1 ago)</source>
<translation> (%1 fa)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation>&amp;Clona...</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>Clona la macchina virtuale selezionata</translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ja.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ja.ts
index e5f068723..f5bad1f14 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ja.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ja.ts
@@ -1,34 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS><TS version="1.1" language="ja">
-<defaultcodec></defaultcodec>
+<!DOCTYPE TS>
+<TS version="2.0" language="ja">
<context>
<name>@@@</name>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2784"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2803"/>
<source>English</source>
<comment>Native language name</comment>
<translation>日本語</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2795"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2814"/>
<source>--</source>
<comment>Native language country name (empty if this language is for all countries)</comment>
<translation></translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2808"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2827"/>
<source>English</source>
<comment>Language name, in English</comment>
<translation>Japanese</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2819"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2838"/>
<source>--</source>
<comment>Language country name, in English (empty if native country name is empty)</comment>
<translation></translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2832"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2851"/>
<source>Oracle Corporation</source>
<comment>Comma-separated list of translators</comment>
<translation>Toshimitsu Tanaka</translation>
@@ -37,17 +37,14 @@
<context>
<name>AttachmentsModel</name>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2832"/>
<source>Double-click to add a new attachment</source>
<translation type="obsolete">ãƒ€ãƒ–ãƒ«ã‚¯ãƒªãƒƒã‚¯ã§æ–°è¦ã®å‰²ã‚Šå½“ã¦ã‚’追加</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2832"/>
<source>Hard Disk</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2832"/>
<source>Slot</source>
<translation type="obsolete">スロット</translation>
</message>
@@ -55,22 +52,18 @@
<context>
<name>BootItemsList</name>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2832"/>
<source>Move Up (Ctrl-Up)</source>
<translation type="obsolete">上ã«ç§»å‹•(Ctrl-Up)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2832"/>
<source>Move Down (Ctrl-Down)</source>
<translation type="obsolete">下ã«ç§»å‹•(Ctrl-Down)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2832"/>
<source>Moves the selected boot device up.</source>
<translation type="obsolete">é¸æŠžã—ãŸèµ·å‹•デãƒã‚¤ã‚¹ã‚’上ã«ç§»å‹•ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2832"/>
<source>Moves the selected boot device down.</source>
<translation type="obsolete">é¸æŠžã—ãŸèµ·å‹•デãƒã‚¤ã‚¹ã‚’下ã«ç§»å‹•ã—ã¾ã™ã€‚</translation>
</message>
@@ -78,7 +71,6 @@
<context>
<name>BootItemsTable</name>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2832"/>
<source>Defines the boot device order. Use the checkboxes on the left to enable or disable individual boot devices. Move items up and down to change the device order.</source>
<translation type="obsolete">起動デãƒã‚¤ã‚¹ã®å„ªå…ˆé †åºã‚’指定ã—ã¾ã™ã€‚ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã‚’使ã„å„デãƒã‚¤ã‚¹ã‚’有効ã¾ãŸã¯ç„¡åйã«ã§ãã¾ã™ã€‚項目を上ã¾ãŸã¯ä¸‹ã«ç§»å‹•ã—ã¦ãƒ‡ãƒã‚¤ã‚¹ã®é †åºã‚’変更ã—ã¦ãã ã•ã„。</translation>
</message>
@@ -86,17 +78,14 @@
<context>
<name>HDItemsModel</name>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2832"/>
<source>Double-click to add a new attachment</source>
<translation type="obsolete">ãƒ€ãƒ–ãƒ«ã‚¯ãƒªãƒƒã‚¯ã§æ–°è¦ã®å‰²ã‚Šå½“ã¦ã‚’追加</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2832"/>
<source>Hard Disk</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2832"/>
<source>Slot</source>
<translation type="obsolete">スロット</translation>
</message>
@@ -104,22 +93,22 @@
<context>
<name>QApplication</name>
<message>
- <location filename="../src/main.cpp" line="450"/>
+ <location filename="../src/main.cpp" line="437"/>
<source>Executable &lt;b&gt;%1&lt;/b&gt; requires Qt %2.x, found Qt %3.</source>
<translation>実行ファイル &lt;b&gt;%1&lt;/b&gt; ã¯Qt %2.x ãŒå¿…è¦ã§ã™ã€‚Qt %3 ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/main.cpp" line="455"/>
+ <location filename="../src/main.cpp" line="442"/>
<source>Incompatible Qt Library Error</source>
<translation>äº’æ›æ€§ã®ãªã„Qtライブラリエラー</translation>
</message>
<message>
- <location filename="../src/main.cpp" line="678"/>
+ <location filename="../src/main.cpp" line="690"/>
<source>VirtualBox - Error In %1</source>
<translation>VirtualBox - %1 ã®ã‚¨ãƒ©ãƒ¼</translation>
</message>
<message>
- <location filename="../src/main.cpp" line="683"/>
+ <location filename="../src/main.cpp" line="695"/>
<source>&lt;html&gt;&lt;b&gt;%1 (rc=%2)&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;</source>
<translation>&lt;html&gt;&lt;b&gt;%1 (rc=%2)&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;</translation>
</message>
@@ -129,7 +118,6 @@
<translation>VirtualBoxã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/main.cpp" line="105"/>
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.&lt;br/&gt;&lt;br/&gt;There are known problems with Linux 2.6.29. If you are running such a kernel, please edit /usr/src/vboxdrv-*/Makefile and enable &lt;i&gt;VBOX_USE_INSERT_PAGE = 1&lt;/i&gt;. After that, re-compile 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.</source>
<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>
@@ -144,22 +132,22 @@
<translation>カーãƒãƒ« ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ãŒæ­£ã—ãロードã•れãŸã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/main.cpp" line="605"/>
+ <location filename="../src/main.cpp" line="617"/>
<source>VirtualBox - Runtime Error</source>
<translation>VirtualBox - ランタイムエラー</translation>
</message>
<message>
- <location filename="../src/main.cpp" line="611"/>
+ <location filename="../src/main.cpp" line="623"/>
<source>&lt;b&gt;Cannot access the kernel driver!&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;</source>
<translation>&lt;b&gt;カーãƒãƒ«ãƒ‰ãƒ©ã‚¤ãƒã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ï¼&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;</translation>
</message>
<message>
- <location filename="../src/main.cpp" line="635"/>
+ <location filename="../src/main.cpp" line="647"/>
<source>Unknown error %2 during initialization of the Runtime</source>
<translation>ランタイムã®åˆæœŸåŒ–中ã«äºˆæœŸã—ãªã„エラー(%2)</translation>
</message>
<message>
- <location filename="../src/main.cpp" line="625"/>
+ <location filename="../src/main.cpp" line="637"/>
<source>Kernel driver not accessible</source>
<translation>カーãƒãƒ«ãƒ‰ãƒ©ã‚¤ãƒã«ã‚¢ã‚¯ã‚»ã‚¹ã§ããªã„</translation>
</message>
@@ -200,7 +188,8 @@
<translation>ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/extensions/QIFileDialog.cpp" line="699"/>
+ <location filename="../src/extensions/QIFileDialog.cpp" line="454"/>
+ <location filename="../src/extensions/QIFileDialog.cpp" line="701"/>
<source>Select a file</source>
<translation>ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž</translation>
</message>
@@ -208,7 +197,6 @@
<context>
<name>QIHelpButton</name>
<message>
- <location filename="../src/extensions/QIFileDialog.cpp" line="699"/>
<source>&amp;Help</source>
<translation type="obsolete">ヘルプ(&amp;H)</translation>
</message>
@@ -237,7 +225,6 @@
<context>
<name>QILabelPrivate</name>
<message>
- <location filename="../src/extensions/QILabel.cpp" line="201"/>
<source>&amp;Copy</source>
<translation type="obsolete">コピー(&amp;C)</translation>
</message>
@@ -283,7 +270,6 @@
<context>
<name>QIRichLabel</name>
<message>
- <location filename="../src/extensions/QIMessageBox.cpp" line="392"/>
<source>Copy to clipboard</source>
<translation type="obsolete">クリップボードã«ã‚³ãƒ”ー</translation>
</message>
@@ -329,395 +315,473 @@
<translation>仮想マシン(&amp;M)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="221"/>
<source>&amp;Fullscreen Mode</source>
<translation type="obsolete">フルスクリーンモード(&amp;F)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="221"/>
<source>Switch to fullscreen mode</source>
<translation type="obsolete">フルスクリーンモードã«åˆ‡ã‚Šæ›¿ãˆã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="221"/>
<source>Seam&amp;less Mode</source>
<translation type="obsolete">シームレスモード(&amp;L)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="221"/>
<source>Switch to seamless desktop integration mode</source>
<translation type="obsolete">シームレスモードã«åˆ‡ã‚Šæ›¿ãˆã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="312"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="575"/>
<source>Auto-resize &amp;Guest Display</source>
<translation>ゲストOSã®ç”»é¢ã‚’自動リサイズ(&amp;G)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="312"/>
<source>Enter &amp;Fullscreen Mode</source>
<translation type="obsolete">フルスクリーンモードã«ã™ã‚‹(&amp;F)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="312"/>
<source>Exit &amp;Fullscreen Mode</source>
<translation type="obsolete">フルスクリーンモードを終了(&amp;F)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="312"/>
<source>Switch to normal mode</source>
<translation type="obsolete">標準モードã«åˆ‡ã‚Šæ›ãˆã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="312"/>
<source>Enter Seam&amp;less Mode</source>
<translation type="obsolete">シームレスモードã«ã™ã‚‹(&amp;L)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="312"/>
<source>Exit Seam&amp;less Mode</source>
<translation type="obsolete">シームレスモードを終了(&amp;L)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="312"/>
<source>Enable &amp;Guest Display Auto-resize</source>
<translation type="obsolete">ゲストOSç”»é¢ã®è‡ªå‹•リサイズを有効化(&amp;G)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="313"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="576"/>
<source>Automatically resize the guest display when the window is resized (requires Guest Additions)</source>
<translation>ウィンドウをリサイズã—ãŸã¨ãã€ã‚²ã‚¹ãƒˆOSç”»é¢ã‚’自動的ã«ãƒªã‚µã‚¤ã‚ºã™ã‚‹(Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="313"/>
<source>Disable &amp;Guest Display Auto-resize</source>
<translation type="obsolete">ゲストOSç”»é¢ã®è‡ªå‹•リサイズを無効化(&amp;G)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="313"/>
<source>Disable automatic resize of the guest display when the window is resized</source>
<translation type="obsolete">ゲストOSç”»é¢ã®è‡ªå‹•リサイズを無効ã«ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="334"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="597"/>
<source>&amp;Adjust Window Size</source>
<translation>ウィンドウã®ã‚µã‚¤ã‚ºã‚’調整(&amp;A)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="335"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="598"/>
<source>Adjust window size and position to best fit the guest display</source>
<translation>ゲストOSç”»é¢ã«åˆã‚ã›ã¦ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã®ã‚µã‚¤ã‚ºã¨ä½ç½®ã‚’調整ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="376"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="328"/>
<source>Disable &amp;Mouse Integration</source>
<translation>マウス統åˆã‚’無効化(&amp;M)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="377"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="242"/>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">設定(&amp;S)...</translation>
+ </message>
+ <message>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="243"/>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="286"/>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="329"/>
<source>Temporarily disable host mouse pointer integration</source>
<translation>一時的ã«ãƒ›ã‚¹ãƒˆ マウスãƒã‚¤ãƒ³ã‚¿ã®çµ±åˆæ©Ÿèƒ½ã‚’無効化</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="377"/>
<source>Enable &amp;Mouse Integration</source>
<translation type="obsolete">マウス統åˆã‚’有効化(&amp;M)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="377"/>
<source>Enable temporarily disabled host mouse pointer integration</source>
<translation type="obsolete">一時的ã«ç„¡åŠ¹åŒ–ã—ãŸãƒ›ã‚¹ãƒˆ マウスãƒã‚¤ãƒ³ã‚¿ã®çµ±åˆæ©Ÿèƒ½ã‚’有効化</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="398"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="350"/>
<source>&amp;Insert Ctrl-Alt-Del</source>
<translation>Ctrl-Alt-Delã‚’é€ä¿¡(&amp;I)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="399"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="351"/>
<source>Send the Ctrl-Alt-Del sequence to the virtual machine</source>
<translation>仮想マシンã«Ctrl-Alt-Delシーケンスをé€ä¿¡ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="421"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="373"/>
<source>&amp;Insert Ctrl-Alt-Backspace</source>
<translation>Ctrl-Alt-Backspaceã‚’é€ä¿¡(&amp;I)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="422"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="374"/>
<source>Send the Ctrl-Alt-Backspace sequence to the virtual machine</source>
<translation>仮想マシンã«Ctrl-Alt-Backspaceシーケンスをé€ä¿¡ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="444"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="264"/>
<source>Take &amp;Snapshot...</source>
<translation>スナップショット作æˆ(&amp;S)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="445"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="265"/>
<source>Take a snapshot of the virtual machine</source>
<translation>仮想マシンã®ã‚¹ãƒŠãƒƒãƒ—ショットを作æˆã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="445"/>
<source>Session I&amp;nformation Dialog</source>
<translation type="obsolete">セッション情報ダイアログ(&amp;N)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="467"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="287"/>
<source>Show Session Information Dialog</source>
<translation>セッション情報ダイアログを表示</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="488"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="396"/>
<source>&amp;Pause</source>
<translation>ä¸€æ™‚åœæ­¢(&amp;P)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="489"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="397"/>
<source>Suspend the execution of the virtual machine</source>
<translation>仮想マシンã®å®Ÿè¡Œã‚’ä¸€æ™‚åœæ­¢ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="489"/>
<source>R&amp;esume</source>
<translation type="obsolete">å†é–‹(&amp;E)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="489"/>
<source>Resume the execution of the virtual machine</source>
<translation type="obsolete">仮想マシンã®å®Ÿè¡Œã‚’å†é–‹ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="243"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="506"/>
<source>Switch to &amp;Fullscreen</source>
<translation>フルスクリーンモードã«åˆ‡ã‚Šæ›¿ãˆã‚‹(&amp;F)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="244"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="507"/>
<source>Switch between normal and fullscreen mode</source>
<translation>標準ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãƒ¢ãƒ¼ãƒ‰ã¨ãƒ•ルスクリーンモードを切りæ›ãˆã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="266"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="529"/>
<source>Switch to Seam&amp;less Mode</source>
<translation>シームレスモードã«åˆ‡ã‚Šæ›ãˆã‚‹(&amp;L)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="267"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="530"/>
<source>Switch between normal and seamless desktop integration mode</source>
<translation>標準ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãƒ¢ãƒ¼ãƒ‰ã¨ã‚·ãƒ¼ãƒ ãƒ¬ã‚¹ãƒ¢ãƒ¼ãƒ‰ã‚’切りæ›ãˆã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="289"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="552"/>
<source>Switch to &amp;Scale Mode</source>
<translation>スケールモードã«åˆ‡ã‚Šæ›ãˆã‚‹(&amp;S)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="290"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="553"/>
<source>Switch between normal and scale mode</source>
<translation>標準ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãƒ¢ãƒ¼ãƒ‰ã¨ã‚¹ã‚±ãƒ¼ãƒ«ãƒ¢ãƒ¼ãƒ‰ã‚’切りæ›ãˆã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="466"/>
<source>Session I&amp;nformation</source>
- <translation>セッション情報(&amp;N)</translation>
+ <translation type="obsolete">セッション情報(&amp;N)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="510"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="418"/>
<source>&amp;Reset</source>
<translation>リセット(&amp;R)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="511"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="419"/>
<source>Reset the virtual machine</source>
<translation>仮想マシンをリセットã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="532"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="440"/>
<source>ACPI Sh&amp;utdown</source>
<translation>ACPI シャットダウン(&amp;U)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="532"/>
<source>ACPI S&amp;hutdown</source>
<translation type="obsolete">ACPI シャットダウン(&amp;H)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="533"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="441"/>
<source>Send the ACPI Power Button press event to the virtual machine</source>
<translation>仮想マシンã«é›»æºãƒœã‚¿ãƒ³ オフã®ACPIイベントをé€ä¿¡ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="555"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="463"/>
<source>&amp;Close...</source>
<translation>é–‰ã˜ã‚‹(&amp;C)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="556"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="464"/>
<source>Close the virtual machine</source>
<translation>仮想マシンを閉ã˜ã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="576"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="484"/>
<source>&amp;View</source>
<translation>ビュー(&amp;V)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="596"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="618"/>
<source>&amp;Devices</source>
<translation>デãƒã‚¤ã‚¹(&amp;D)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="617"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="639"/>
<source>&amp;CD/DVD Devices</source>
<translation>CD/DVD デãƒã‚¤ã‚¹(&amp;C)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="638"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="660"/>
<source>&amp;Floppy Devices</source>
<translation>フロッピー デãƒã‚¤ã‚¹(&amp;F)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="660"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="682"/>
<source>&amp;USB Devices</source>
<translation>USB デãƒã‚¤ã‚¹(&amp;U)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="700"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="722"/>
<source>&amp;Network Adapters...</source>
<translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタ(&amp;N)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="701"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="723"/>
<source>Change the settings of network adapters</source>
<translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタã®è¨­å®šå¤‰æ›´</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="741"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="763"/>
<source>&amp;Shared Folders...</source>
<translation>共有フォルダ(&amp;S)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="742"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="764"/>
<source>Create or modify shared folders</source>
<translation>共有フォルダ設定ダイアログを開ã</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="764"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="786"/>
<source>Enable R&amp;emote Display</source>
<translation>リモートディスプレイを有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="764"/>
<source>&amp;Enable Remote Display</source>
<translation type="obsolete">リモートディスプレイを有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="765"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="787"/>
<source>Enable remote desktop (RDP) connections to this machine</source>
<translation>ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã¸ã®ãƒªãƒ¢ãƒ¼ãƒˆãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—(RDP)接続を有効化</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="765"/>
<source>&amp;Disable Remote Display</source>
<translation type="obsolete">リモートディスプレイを無効化(&amp;D)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="765"/>
<source>Disable remote desktop (RDP) connections to this machine</source>
<translation type="obsolete">ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã¸ã®ãƒªãƒ¢ãƒ¼ãƒˆãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—(RDP)接続を無効化</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="868"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="890"/>
<source>Enable &amp;Logging...</source>
<comment>debug action</comment>
<translation>ログ出力を有効化(&amp;L)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="868"/>
<source>Disable &amp;Logging...</source>
<comment>debug action</comment>
<translation type="obsolete">ログ出力を無効化(&amp;L)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="868"/>
<source>&amp;Remote Display</source>
<translation type="obsolete">リモートディスプレイ(&amp;R)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="868"/>
<source>Enable or disable remote desktop (RDP) connections to this machine</source>
<translation type="obsolete">ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã¸ã®ãƒªãƒ¢ãƒ¼ãƒˆãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—(RDP)接続を有効化ã¾ãŸã¯ç„¡åŠ¹åŒ–</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="786"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="808"/>
<source>&amp;Install Guest Additions...</source>
<translation>Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«(&amp;I)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="787"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="809"/>
<source>Mount the Guest Additions installation image</source>
<translation>Guest Additions インストールイメージをマウントã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="808"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="830"/>
<source>De&amp;bug</source>
<translation>デãƒãƒƒã‚°(&amp;B)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="828"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="850"/>
<source>&amp;Statistics...</source>
<comment>debug action</comment>
<translation>統計(&amp;S)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="848"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="870"/>
<source>&amp;Command Line...</source>
<comment>debug action</comment>
<translation>コマンドライン(&amp;C)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="848"/>
<source>&amp;Logging...</source>
<comment>debug action</comment>
<translation type="obsolete">ログå–å¾—(&amp;L)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="889"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="911"/>
<source>&amp;Help</source>
<translation>ヘルプ(&amp;H)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="1066"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="1088"/>
<source>Dock Icon</source>
<translation>ドック アイコン</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="1086"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="1108"/>
<source>Show Monitor Preview</source>
<translation>ディスプレイã®ãƒ—レビューを表示</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="1106"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="1128"/>
<source>Show Application Icon</source>
<translation>アプリケーション アイコンを表示</translation>
</message>
</context>
<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizard.cpp" line="66"/>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizard.cpp" line="68"/>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizardPage1.ui" line="36"/>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizardPage1.ui" line="46"/>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizardPage1.ui" line="59"/>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizardPage1.ui" line="62"/>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizard.cpp" line="151"/>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizard.cpp" line="163"/>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizardPage2.ui" line="46"/>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizardPage2.ui" line="56"/>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizardPage2.ui" line="63"/>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizard.cpp" line="210"/>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizard.cpp" line="212"/>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizard.cpp" line="213"/>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizard.cpp" line="214"/>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/clonevm/UICloneVMWizard.cpp" line="215"/>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIDescriptionPagePrivate</name>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1292"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="1318"/>
<source>No description. Press the Edit button below to add it.</source>
<translation>説明ãŒã‚りã¾ã›ã‚“。[編集]ボタンをクリックã—ã¦è¿½åŠ ã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1294"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="1320"/>
<source>Edit</source>
<translation>編集</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1296"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="1322"/>
<source>Edit (Ctrl+E)</source>
<translation>編集(Ctrl+E)</translation>
</message>
@@ -725,329 +789,354 @@
<context>
<name>UIDetailsPagePrivate</name>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="473"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="567"/>
<source>Name</source>
<comment>details report</comment>
<translation>åå‰</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="475"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="569"/>
<source>OS Type</source>
<comment>details report</comment>
<translation>OSタイプ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="494"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="588"/>
<source>Base Memory</source>
<comment>details report</comment>
<translation>メインメモリ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="577"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="589"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="677"/>
<source>&lt;nobr&gt;%1 MB&lt;/nobr&gt;</source>
<comment>details report</comment>
<translation>&lt;nobr&gt;%1 MB&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="500"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="594"/>
<source>Processors</source>
<comment>details report</comment>
<translation>プロセッサ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="501"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="595"/>
<source>&lt;nobr&gt;%1&lt;/nobr&gt;</source>
<comment>details report</comment>
<translation>&lt;nobr&gt;%1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="516"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="600"/>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="601"/>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="616"/>
<source>Boot Order</source>
<comment>details report</comment>
<translation>èµ·å‹•é †åº</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="524"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="624"/>
<source>ACPI</source>
<comment>details report</comment>
<translation>ACPI</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="528"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="628"/>
<source>IO APIC</source>
<comment>details report</comment>
<translation>IO APIC</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="531"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="631"/>
<source>BIOS</source>
<comment>details report</comment>
<translation>BIOS</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="540"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="640"/>
<source>VT-x/AMD-V</source>
<comment>details report</comment>
<translation>VT-x/AMD-V</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="544"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="644"/>
<source>Nested Paging</source>
<comment>details report</comment>
<translation>ãƒã‚¹ãƒ†ãƒƒãƒ‰ãƒšãƒ¼ã‚¸ãƒ³ã‚°</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="549"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="649"/>
<source>PAE/NX</source>
<comment>details report</comment>
<translation>PAE/NX</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="597"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="652"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="697"/>
<source>Acceleration</source>
<comment>details report</comment>
<translation>アクセラレーション</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="576"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="676"/>
<source>Video Memory</source>
<comment>details report</comment>
<translation>ビデオメモリ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="584"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="684"/>
<source>Screens</source>
<comment>details report</comment>
<translation>スクリーン</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="591"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="691"/>
<source>2D Video</source>
<comment>details report</comment>
<translation>2D ビデオ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="594"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="694"/>
<source>3D</source>
<comment>details report</comment>
<translation>3D</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="605"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="705"/>
<source>Remote Desktop Server Port</source>
<comment>details report (VRDE Server)</comment>
<translation>リモートデスクトップ サーãƒãƒ¼ ãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="609"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="709"/>
<source>Remote Desktop Server</source>
<comment>details report (VRDE Server)</comment>
<translation>リモートデスクトップ サーãƒãƒ¼</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="610"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="710"/>
<source>Disabled</source>
<comment>details report (VRDE Server)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="648"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="748"/>
<source>(CD/DVD)</source>
<translation>(CD/DVD)</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="679"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="779"/>
<source>Not Attached</source>
<comment>details report (Storage)</comment>
<translation>未割り当ã¦</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="702"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="802"/>
<source>Host Driver</source>
<comment>details report (audio)</comment>
<translation>ホスト ドライãƒ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="705"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="805"/>
<source>Controller</source>
<comment>details report (audio)</comment>
<translation>コントローラ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="709"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="809"/>
<source>Disabled</source>
<comment>details report (audio)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="741"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="841"/>
<source>Bridged adapter, %1</source>
<comment>details report (network)</comment>
<translation>ブリッジ アダプタ, &apos;%1&apos;</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="744"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="844"/>
<source>Internal network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
<translation>内部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯, &apos;%1&apos;</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="747"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="847"/>
<source>Host-only adapter, &apos;%1&apos;</source>
<comment>details report (network)</comment>
<translation>ホストオンリー アダプタ, &apos;%1&apos;</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="751"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="853"/>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="854"/>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯, &apos;%1&apos;</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="758"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="861"/>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation>アダプタ %1</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="766"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="869"/>
<source>Disabled</source>
<comment>details report (network)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="805"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="908"/>
<source>Port %1</source>
<comment>details report (serial ports)</comment>
<translation>ãƒãƒ¼ãƒˆ %1</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="813"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="916"/>
<source>Disabled</source>
<comment>details report (serial ports)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="846"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="949"/>
<source>Port %1</source>
<comment>details report (parallel ports)</comment>
<translation>ãƒãƒ¼ãƒˆ %1</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="854"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="957"/>
<source>Disabled</source>
<comment>details report (parallel ports)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="891"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="994"/>
<source>Device Filters</source>
<comment>details report (USB)</comment>
<translation>デãƒã‚¤ã‚¹ フィルタ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="892"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="995"/>
<source>%1 (%2 active)</source>
<comment>details report (USB)</comment>
<translation>%1 (%2 アクティブ)</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="897"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="1000"/>
<source>Disabled</source>
<comment>details report (USB)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="926"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="1029"/>
<source>Shared Folders</source>
<comment>details report (shared folders)</comment>
<translation>共有フォルダ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="931"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="1034"/>
<source>None</source>
<comment>details report (shared folders)</comment>
<translation>ãªã—</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="955"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="1058"/>
<source>None</source>
<comment>details report (description)</comment>
<translation>ãªã—</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1080"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="471"/>
<source>The selected virtual machine is &lt;i&gt;inaccessible&lt;/i&gt;. Please inspect the error message shown below and press the &lt;b&gt;Refresh&lt;/b&gt; button if you want to repeat the accessibility check:</source>
<translation>é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã«&lt;i&gt;アクセスã§ãã¾ã›ã‚“&lt;/i&gt;。アクセスå¯å¦ã‚’å†ç¢ºèªã™ã‚‹ã«ã¯ä»¥ä¸‹ã«ç¤ºã•れãŸã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’調査ã—ã¦&lt;b&gt;[æœ€æ–°ã®æƒ…å ±ã«æ›´æ–°]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„:</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1095"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="486"/>
<source>General</source>
<comment>details report</comment>
<translation>一般</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1101"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="492"/>
<source>System</source>
<comment>details report</comment>
<translation>システム</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1107"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="498"/>
<source>Preview</source>
<comment>details report</comment>
<translation>プレビュー</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1113"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="504"/>
<source>Display</source>
<comment>details report</comment>
<translation>ディスプレイ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1119"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="510"/>
<source>Storage</source>
<comment>details report</comment>
<translation>ストレージ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1125"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="516"/>
<source>Audio</source>
<comment>details report</comment>
<translation>オーディオ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1131"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="522"/>
<source>Network</source>
<comment>details report</comment>
<translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1137"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="528"/>
<source>Serial Ports</source>
<comment>details report</comment>
<translation>シリアルãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1144"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="535"/>
<source>Parallel Ports</source>
<comment>details report</comment>
<translation>パラレルãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1151"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="542"/>
<source>USB</source>
<comment>details report</comment>
<translation>USB</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1157"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="548"/>
<source>Shared Folders</source>
<comment>details report</comment>
<translation>共有フォルダ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1163"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="554"/>
<source>Description</source>
<comment>details report</comment>
<translation>説明</translation>
@@ -1056,47 +1145,39 @@
<context>
<name>UIDownloader</name>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1163"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1163"/>
<source>Downloading the VirtualBox Guest Additions CD image from &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;...&lt;/nobr&gt;</source>
<translation type="obsolete">VirtualBox Guest Additions CDイメージを&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰...&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1163"/>
<source>Cancel the VirtualBox Guest Additions CD image download</source>
<translation type="obsolete">VirtualBox Guest Additions CDイメージã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã‚’キャンセル</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1163"/>
<source>Could not locate the file on the server (response: %1).</source>
<translation type="obsolete">サーãƒãƒ¼ä¸Šã«ãƒ•ァイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ(応答: %1)。</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1163"/>
<source>&lt;p&gt;Failed to save the downloaded file as &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;.&lt;/nobr&gt;&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;ダウンロードã—ãŸãƒ•ァイル(&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;)ã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1163"/>
<source>Select folder to save Guest Additions image to</source>
<translation type="obsolete">Guest Additionsイメージをä¿å­˜ã™ã‚‹ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1163"/>
<source>Connection timed out.</source>
<translation type="obsolete">接続ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã«ãªã‚Šã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1163"/>
<source>The download process has been cancelled by the user.</source>
<translation type="obsolete">ダウンロード処ç†ãŒãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã‚ˆã£ã¦ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/UIDownloader.cpp" line="235"/>
+ <location filename="../src/widgets/UIDownloader.cpp" line="262"/>
<source>The download process has been canceled by the user.</source>
<translation>ダウンロード処ç†ãŒãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã‚ˆã£ã¦ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸã€‚</translation>
</message>
@@ -1104,17 +1185,14 @@
<context>
<name>UIDownloaderAdditions</name>
<message>
- <location filename="../src/widgets/UIDownloader.cpp" line="235"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/widgets/UIDownloader.cpp" line="235"/>
<source>Downloading the VirtualBox Guest Additions CD image from &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;...&lt;/nobr&gt;</source>
<translation type="obsolete">VirtualBox Guest Additions CDイメージを&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰...&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/UIDownloader.cpp" line="235"/>
<source>Cancel the VirtualBox Guest Additions CD image download</source>
<translation type="obsolete">VirtualBox Guest Additions CDイメージã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã‚’キャンセル</translation>
</message>
@@ -1140,22 +1218,18 @@
<context>
<name>UIExportApplianceWzd</name>
<message>
- <location filename="../src/widgets/UIDownloaderUserManual.cpp" line="151"/>
<source>Select a file to export into</source>
<translation type="obsolete">エクスãƒãƒ¼ãƒˆã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/widgets/UIDownloaderUserManual.cpp" line="151"/>
<source>Open Virtualization Format (%1)</source>
<translation type="obsolete">仮想フォーマット(%1)ã‚’é–‹ã</translation>
</message>
<message>
- <location filename="../src/widgets/UIDownloaderUserManual.cpp" line="151"/>
<source>Appliance</source>
<translation type="obsolete">仮想アプライアンス</translation>
</message>
<message>
- <location filename="../src/widgets/UIDownloaderUserManual.cpp" line="151"/>
<source>Exporting Appliance ...</source>
<translation type="obsolete">仮想アプライアンスã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ...</translation>
</message>
@@ -1165,12 +1239,15 @@
<translation>仮想アプライアンス エクスãƒãƒ¼ãƒˆ ウィザード</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="92"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="96"/>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Welcome to the Appliance Export Wizard!</source>
<translation type="obsolete">よã†ã“ã仮想アプライアンス エクスãƒãƒ¼ãƒˆ ウィザードã¸ï¼</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="92"/>
<source>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
@@ -1181,27 +1258,22 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;p, li { white-space: pre-wrap; }&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ã€ä»®æƒ³ã‚¢ãƒ—ライアンスをエクスãƒãƒ¼ãƒˆã™ã‚‹æ‰‹é †ã‚’案内ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã®æ¬¡ã®ãƒšãƒ¼ã‚¸ã«é€²ã‚€ã«ã¯&lt;span style=&quot; font-weight:600;&quot;&gt;[次ã¸]&lt;/span&gt;ボタンをã€å‰ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã‚‹ã«ã¯&lt;span style=&quot; font-weight:600;&quot;&gt;[戻る]&lt;/span&gt;ボタンを使用ã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;エクスãƒãƒ¼ãƒˆã™ã‚‹ä»®æƒ³ãƒžã‚·ãƒ³ã‚’é¸æŠžã—ã¦ãã ã•ã„。 1ã¤ä»¥ä¸Šã®ä»®æƒ³ãƒžã‚·ãƒ³ã‚’é¸æŠžã§ãã¾ã™ã€‚ エクスãƒãƒ¼ãƒˆã™ã‚‹å‰ã«ã€ãれらã®ä»®æƒ³ãƒžã‚·ãƒ³ã‚’オフã«ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="92"/>
<source>&lt; &amp;Back</source>
<translation type="obsolete">&lt; 戻る(&amp;B)</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="92"/>
<source>&amp;Next &gt;</source>
<translation type="obsolete">次ã¸(&amp;N) &gt;</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="92"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="92"/>
<source>Appliance Export Settings</source>
<translation type="obsolete">仮想アプライアンスã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆè¨­å®š</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="92"/>
<source>Here you can change additional configuration values of the selected virtual machines. You can modify most of the properties shown by double-clicking on the items.</source>
<translation type="obsolete">é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®æ§‹æˆã‚’変更ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚項目をダブルクリックã—ã¦è¡¨ç¤ºã•れã¦ã„るプロパティを変更ã§ãã¾ã™ã€‚</translation>
</message>
@@ -1211,92 +1283,74 @@ p, li { white-space: pre-wrap; }
<translation>ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã«æˆ»ã™</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>Please specify a filename into which the appliance information will be written. Currently VirtualBox supports the Open Virtualization Format (OVF).</source>
<translation type="obsolete">ä»®æƒ³ã‚¢ãƒ—ãƒ©ã‚¤ã‚¢ãƒ³ã‚¹æƒ…å ±ãŒæ›¸ã‹ã‚ŒãŸãƒ•ァイルåを指定ã—ã¦ãã ã•ã„。 VirtualBoxã¯Open Virtualization Format(OVF)をサãƒãƒ¼ãƒˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>&amp;Export &gt;</source>
<translation type="obsolete">エクスãƒãƒ¼ãƒˆ(&amp;E) &gt;</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>Write in legacy OVF 0.9 format for compatibility with other virtualization products.</source>
<translation type="obsolete">ä»–ã®ä»®æƒ³åŒ–製å“ã¨ã®äº’æ›æ€§ã®ãŸã‚ã€å¤ã„OVF0.9å½¢å¼ã§æ›¸ãè¾¼ã¿ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>&amp;Write legacy OVF 0.9</source>
<translation type="obsolete">OVF 0.9å½¢å¼ã§æ›¸ãè¾¼ã¿(&amp;W)</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>Please choose a filename to export the OVF to.</source>
<translation type="obsolete">エクスãƒãƒ¼ãƒˆã™ã‚‹ãƒ•ァイルåã‚’é¸æŠžã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>Please complete the additional fields like the username, password and the bucket, and provide a filename for the OVF target.</source>
<translation type="obsolete">ユーザåã€ãƒ‘スワードãŠã‚ˆã³ãƒã‚±ãƒƒãƒˆåãªã©ã®è¿½åŠ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ã™ã¹ã¦æŒ‡å®šã—ã¦ãã ã•ã„。最後ã«OVFターゲットã®ãƒ•ァイルåを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>Please complete the additional fields like the username, password, hostname and the bucket, and provide a filename for the OVF target.</source>
<translation type="obsolete">ユーザåã€ãƒ‘スワードã€ãƒ›ã‚¹ãƒˆåãŠã‚ˆã³ãƒã‚±ãƒƒãƒˆåãªã©ã®è¿½åŠ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ã™ã¹ã¦æŒ‡å®šã—ã¦ãã ã•ã„。最後ã«OVFターゲットã®ãƒ•ァイルåを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>Checking files ...</source>
<translation type="obsolete">ファイルを確èªä¸­...</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>Removing files ...</source>
<translation type="obsolete">ファイルを除去中...</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>Please specify the target for the OVF export. You can choose between a local file system export, uploading the OVF to the Sun Cloud service or an S3 storage server.</source>
<translation type="obsolete">OVFã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã®ãŸã‚ã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚’指定ã—ã¦ãã ã•ã„。 ローカル ファイルシステムã¸ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã‹ã€OVFã®ã‚¢ãƒƒãƒ—ロード(Sun Cloudã¾ãŸã¯S3 ストレージ サーãƒãƒ¼)ã‚’é¸æŠžã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>&amp;Local Filesystem </source>
<translation type="obsolete">ローカル ファイルシステム(&amp;L)</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>Sun &amp;Cloud</source>
<translation type="obsolete">Sun Cloud(&amp;C)</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>&amp;Simple Storage System (S3)</source>
<translation type="obsolete">Simple Storage System (S3)(&amp;S)</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>&amp;Username:</source>
<translation type="obsolete">ユーザーå(&amp;U):</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>&amp;Password:</source>
<translation type="obsolete">パスワード(&amp;P):</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>&amp;File:</source>
<translation type="obsolete">ファイル(&amp;F):</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>&amp;Bucket:</source>
<translation type="obsolete">ãƒã‚±ãƒƒãƒˆå(&amp;B):</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="95"/>
<source>&amp;Hostname:</source>
<translation type="obsolete">ホストå(&amp;H):</translation>
</message>
@@ -1304,12 +1358,12 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIExportApplianceWzdPage1</name>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="130"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="131"/>
<source>Welcome to the Appliance Export Wizard!</source>
<translation>よã†ã“ã仮想アプライアンス エクスãƒãƒ¼ãƒˆ ウィザードã¸ï¼</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="132"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="133"/>
<source>&lt;p&gt;This wizard will guide you through the process of exporting an appliance.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;Please select the virtual machines that should be added to the appliance. You can select more than one. Please note that these machines have to be turned off before they can be exported.&lt;/p&gt;</source>
<translation>&lt;p&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ã€ä»®æƒ³ã‚¢ãƒ—ライアンスをエクスãƒãƒ¼ãƒˆã™ã‚‹æ‰‹é †ã‚’案内ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;エクスãƒãƒ¼ãƒˆã™ã‚‹ä»®æƒ³ãƒžã‚·ãƒ³ã‚’é¸æŠžã—ã¦ãã ã•ã„。 1ã¤ä»¥ä¸Šã®ä»®æƒ³ãƒžã‚·ãƒ³ã‚’é¸æŠžã§ãã¾ã™ã€‚ エクスãƒãƒ¼ãƒˆã™ã‚‹å‰ã«ã€ãれらã®ä»®æƒ³ãƒžã‚·ãƒ³ã‚’オフã«ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。&lt;/p&gt;</translation>
</message>
@@ -1317,12 +1371,11 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIExportApplianceWzdPage2</name>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="132"/>
<source>Here you can change additional configuration values of the selected virtual machines. You can modify most of the properties shown by double-clicking on the items.</source>
<translation type="obsolete">é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®æ§‹æˆã‚’変更ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚項目をダブルクリックã—ã¦è¡¨ç¤ºã•れã¦ã„るプロパティを変更ã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="285"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="286"/>
<source>Appliance Export Settings</source>
<translation>仮想アプライアンスã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆè¨­å®š</translation>
</message>
@@ -1350,62 +1403,58 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIExportApplianceWzdPage3</name>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzdPage2.ui" line="63"/>
<source>Please specify the target for the OVF export. You can choose between a local file system export, uploading the OVF to the Sun Cloud service or an S3 storage server.</source>
<translation type="obsolete">OVFã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã®ãŸã‚ã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚’指定ã—ã¦ãã ã•ã„。 ローカル ファイルシステムã¸ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã‹ã€OVFã®ã‚¢ãƒƒãƒ—ロード(Sun Cloud サービスã¾ãŸã¯S3 ストレージ サーãƒãƒ¼)ã‚’é¸æŠžã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzdPage2.ui" line="63"/>
<source>&amp;Local Filesystem </source>
<translation type="obsolete">ローカル ファイルシステム(&amp;L)</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzdPage2.ui" line="63"/>
<source>Sun &amp;Cloud</source>
<translation type="obsolete">Sun Cloud(&amp;C)</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzdPage2.ui" line="63"/>
<source>&amp;Simple Storage System (S3)</source>
<translation type="obsolete">Simple Storage System (S3)(&amp;S)</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="353"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="354"/>
<source>Appliance Export Settings</source>
<translation>仮想アプライアンスã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆè¨­å®š</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="356"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="357"/>
<source>Appliance</source>
<translation>仮想アプライアンス</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="359"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="360"/>
<source>Select a file to export into</source>
<translation>エクスãƒãƒ¼ãƒˆã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="360"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="361"/>
<source>Open Virtualization Format Archive (%1)</source>
<translation>Open Virtualization Format Archive (%1)</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="360"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="361"/>
<source>Open Virtualization Format (%1)</source>
<translation>Open Virtualization Format (%1)</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="374"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="375"/>
<source>Please choose a filename to export the OVF/OVA to. If you use an &lt;i&gt;ova&lt;/i&gt; file name extension, then all the files will be combined into one Open Virtualization Format Archive. If you use an &lt;i&gt;ovf&lt;/i&gt; extension, several files will be written separately. Other extensions are not allowed.</source>
<translation>エクスãƒãƒ¼ãƒˆã™ã‚‹OVF/OVAファイルã®åå‰ã‚’é¸æŠžã—ã¦ãã ã•ã„。拡張å­&lt;i&gt;ova&lt;/i&gt;ã‚’é¸æŠžã™ã‚‹ã¨ã™ã¹ã¦ã®ãƒ•ァイルã¯Open Virtualization Format Archiveå½¢å¼ã«çµåˆã•れã¾ã™ã€‚æ‹¡å¼µå­&lt;i&gt;ovf&lt;/i&gt;ã‚’é¸æŠžã™ã‚‹ã¨è¤‡æ•°ã®ãƒ•ァイルã«ä¿å­˜ã•れã¾ã™ã€‚ä»–ã®æ‹¡å¼µå­ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="397"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="398"/>
<source>Please complete the additional fields like the username, password and the bucket, and provide a filename for the OVF target.</source>
<translation>ユーザåã€ãƒ‘スワードãŠã‚ˆã³ãƒã‚±ãƒƒãƒˆåãªã©ã®è¿½åŠ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ã™ã¹ã¦æŒ‡å®šã—ã¦ãã ã•ã„。最後ã«OVFターゲットã®ãƒ•ァイルåを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="415"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="416"/>
<source>Please complete the additional fields like the username, password, hostname and the bucket, and provide a filename for the OVF target.</source>
<translation>ユーザåã€ãƒ‘スワードã€ãƒ›ã‚¹ãƒˆåãŠã‚ˆã³ãƒã‚±ãƒƒãƒˆåãªã©ã®è¿½åŠ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ã™ã¹ã¦æŒ‡å®šã—ã¦ãã ã•ã„。最後ã«OVFターゲットã®ãƒ•ァイルåを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。</translation>
</message>
@@ -1458,87 +1507,74 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIExportApplianceWzdPage4</name>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzdPage3.ui" line="144"/>
<source>&amp;Username:</source>
<translation type="obsolete">ユーザーå(&amp;U):</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzdPage3.ui" line="144"/>
<source>&amp;Password:</source>
<translation type="obsolete">パスワード(&amp;P):</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzdPage3.ui" line="144"/>
<source>&amp;Hostname:</source>
<translation type="obsolete">ホストå(&amp;H):</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzdPage3.ui" line="144"/>
<source>&amp;Bucket:</source>
<translation type="obsolete">ãƒã‚±ãƒƒãƒˆå(&amp;B):</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzdPage3.ui" line="144"/>
<source>&amp;File:</source>
<translation type="obsolete">ファイル(&amp;F):</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzdPage3.ui" line="144"/>
<source>Write in legacy OVF 0.9 format for compatibility with other virtualization products.</source>
<translation type="obsolete">ä»–ã®ä»®æƒ³åŒ–製å“ã¨ã®äº’æ›æ€§ã®ãŸã‚ã€OVF 0.9å½¢å¼ã§æ›¸ãè¾¼ã¿ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzdPage3.ui" line="144"/>
<source>&amp;Write legacy OVF 0.9</source>
<translation type="obsolete">OVF 0.9å½¢å¼ã§æ›¸ãè¾¼ã¿(&amp;W)</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="500"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="501"/>
<source>Appliance Export Settings</source>
<translation>仮想アプライアンスã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆè¨­å®š</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="500"/>
<source>Appliance</source>
<translation type="obsolete">仮想アプライアンス</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="500"/>
<source>Select a file to export into</source>
<translation type="obsolete">エクスãƒãƒ¼ãƒˆã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="500"/>
<source>Open Virtualization Format (%1)</source>
<translation type="obsolete">仮想フォーマット(%1)ã‚’é–‹ã</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="500"/>
<source>Please choose a filename to export the OVF to.</source>
<translation type="obsolete">エクスãƒãƒ¼ãƒˆã™ã‚‹ãƒ•ァイルåã‚’é¸æŠžã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="500"/>
<source>Please complete the additional fields like the username, password and the bucket, and provide a filename for the OVF target.</source>
<translation type="obsolete">ユーザåã€ãƒ‘スワードãŠã‚ˆã³ãƒã‚±ãƒƒãƒˆåãªã©ã®è¿½åŠ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ã™ã¹ã¦æŒ‡å®šã—ã¦ãã ã•ã„。最後ã«OVFターゲットã®ãƒ•ァイルåを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="500"/>
<source>Please complete the additional fields like the username, password, hostname and the bucket, and provide a filename for the OVF target.</source>
<translation type="obsolete">ユーザåã€ãƒ‘スワードã€ãƒ›ã‚¹ãƒˆåãŠã‚ˆã³ãƒã‚±ãƒƒãƒˆåãªã©ã®è¿½åŠ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ã™ã¹ã¦æŒ‡å®šã—ã¦ãã ã•ã„。最後ã«OVFターゲットã®ãƒ•ァイルåを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="602"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="603"/>
<source>Checking files ...</source>
<translation>ファイルを確èªä¸­...</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="623"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="624"/>
<source>Removing files ...</source>
<translation>ファイルを除去中...</translation>
</message>
<message>
- <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="659"/>
+ <location filename="../src/wizards/exportappliance/UIExportApplianceWzd.cpp" line="660"/>
<source>Exporting Appliance ...</source>
<translation>仮想アプライアンスã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ...</translation>
</message>
@@ -1556,138 +1592,116 @@ p, li { white-space: pre-wrap; }
<translation>åˆå›žèµ·å‹•ウィザード</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
+ <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="101"/>
+ <source>Start</source>
+ <translation type="unfinished">èµ·å‹•</translation>
+ </message>
+ <message>
<source>&lt;p&gt;You have started a newly created virtual machine for the first time. This wizard will help you to perform the steps necessary for installing an operating system of your choice onto this virtual machine.&lt;/p&gt;&lt;p&gt;Use the &lt;b&gt;Next&lt;/b&gt; button to go to the next page of the wizard and the &lt;b&gt;Back&lt;/b&gt; button to return to the previous page. You can also press &lt;b&gt;Cancel&lt;/b&gt; if you want to cancel the execution of this wizard.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;æ–°ãŸã«ä½œæˆã•れãŸä»®æƒ³ãƒžã‚·ãƒ³ãŒåˆã‚ã¦èµ·å‹•ã•れã¾ã—ãŸã€‚ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ã€ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã«é¸æŠžã—ãŸã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã‚’インストールã™ã‚‹ãŸã‚ã«å¿…è¦ãªä½œæ¥­ã‚’手助ã‘ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã®æ¬¡ã®ãƒšãƒ¼ã‚¸ã«é€²ã‚€ã«ã¯&lt;b&gt;[次ã¸]&lt;/b&gt;ボタンをã€å‰ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã‚‹ã«ã¯&lt;b&gt;[戻る]&lt;/b&gt;ボタンを使用ã—ã¦ãã ã•ã„。ウィザードã®å®Ÿè¡Œã‚’中止ã—ãŸã„å ´åˆã¯&lt;b&gt;[キャンセル]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>Welcome to the First Run Wizard!</source>
<translation type="obsolete">よã†ã“ãåˆå›žèµ·å‹•ウィザードã¸ï¼</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&lt;p&gt;Select the type of media you would like to use for installation.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;インストールã«ä½¿ç”¨ã—ãŸã„メディアã®ç¨®åˆ¥ã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>Media Type</source>
<translation type="obsolete">メディア種別</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&amp;CD/DVD-ROM Device</source>
<translation type="obsolete">CD/DVD-ROMデãƒã‚¤ã‚¹(&amp;C)</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&amp;Floppy Device</source>
<translation type="obsolete">フロッピー デãƒã‚¤ã‚¹(&amp;F)</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&lt;p&gt;Select the media which contains the setup program of the operating system you want to install. This media must be bootable, otherwise the setup program will not be able to start.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;インストールã™ã‚‹ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã®ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ— プログラムをå«ã‚€ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’é¸æŠžã—ã¦ãã ã•ã„。ã“ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã¯èµ·å‹•å¯èƒ½ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。ãã†ã§ãªã‘れã°ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ— プログラムã¯èµ·å‹•ã§ãã¾ã›ã‚“。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>Media Source</source>
<translation type="obsolete">メディア ソース</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&amp;Host Drive</source>
<translation type="obsolete">ホスト デãƒã‚¤ã‚¹(&amp;H)</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&amp;Image File</source>
<translation type="obsolete">イメージファイル(&amp;I)</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>VDM</source>
<translation type="obsolete">VDM</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>Select Installation Media</source>
<translation type="obsolete">ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&lt;p&gt;You have selected the following media to boot from:&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;以下ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã‹ã‚‰ã®èµ·å‹•ã‚’é¸æŠžã—ã¾ã—ãŸ:&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;上記ã®è¨­å®šãŒæ­£ã—ã‘れã°ã€&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;ã®å‹•ä½œã‚’é¸æŠžã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>Summary</source>
<translation type="obsolete">概è¦</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>CD/DVD-ROM Device</source>
<translation type="obsolete">CD/DVD-ROMデãƒã‚¤ã‚¹</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>Floppy Device</source>
<translation type="obsolete">フロッピー デãƒã‚¤ã‚¹</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>Host Drive %1</source>
<translation type="obsolete">ホスト ドライブ %1</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&lt;table&gt;&lt;tr&gt;&lt;td&gt;Type:&lt;/td&gt;&lt;td&gt;%1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Source:&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</source>
<translation type="obsolete">&lt;table&gt;&lt;tr&gt;&lt;td&gt;タイプ:&lt;/td&gt;&lt;td&gt;%1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ソース:&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&lt;p&gt;You have started a newly created virtual machine for the first time. This wizard will help you to perform the steps necessary for booting an operating system of your choice on the virtual machine.&lt;/p&gt;&lt;p&gt;Note that you will not be able to install an operating system into this virtual machine right now because you did not attach any hard disk to it. If this is not what you want, you can cancel the execution of this wizard, select &lt;b&gt;Settings&lt;/b&gt; from the &lt;b&gt;Machine&lt;/b&gt; menu of the main VirtualBox window to access the settings dialog of this machine and change the hard disk configuration.&lt;/p&gt;&lt;p&gt;Use the &lt;b&gt;Next&lt;/b&gt; button to go to the next page of the wizard and the &lt;b&gt;Back&lt;/b&gt; button to return to the previous page. You can also press &lt;b&gt;Cancel&lt;/b&gt; if you want to cancel the execution of this wizard.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;æ–°ãŸã«ä½œæˆã•れãŸä»®æƒ³ãƒžã‚·ãƒ³ãŒåˆã‚ã¦èµ·å‹•ã•れã¾ã—ãŸã€‚ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã«é¸æŠžã—ãŸã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã‚’インストールã™ã‚‹ãŸã‚ã«å¿…è¦ãªä½œæ¥­ã‚’手助ã‘ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;注:ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ãªã„ãŸã‚ã€ç¾åœ¨ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã‚’ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã®å®Ÿè¡Œã‚’中止ã—ã€VirtualBoxメインウィンドウã®&lt;b&gt;[仮想マシン]&lt;/b&gt;メニューã‹ã‚‰&lt;b&gt;[設定]&lt;/b&gt;ã‚’é¸ã³ã€ä»®æƒ³ãƒžã‚·ãƒ³ã®è¨­å®šãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯æ§‹æˆã‚’変更ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã®æ¬¡ã®ãƒšãƒ¼ã‚¸ã«é€²ã‚€ã«ã¯&lt;b&gt;[次ã¸]&lt;/b&gt;ボタンをã€å‰ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã‚‹ã«ã¯&lt;b&gt;[戻る]&lt;/b&gt;ボタンを使用ã—ã¦ãã ã•ã„。ウィザードã®å®Ÿè¡Œã‚’中止ã—ãŸã„å ´åˆã¯&lt;b&gt;[キャンセル]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&lt;p&gt;Select the type of media you would like to use for booting an operating system.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;オペレーティングシステムã®èµ·å‹•ã«ä½¿ç”¨ã—ãŸã„メディアã®ã‚¿ã‚¤ãƒ—ã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&lt;p&gt;Select the media that contains the operating system you want to work with. This media must be bootable, otherwise the operating system will not be able to start.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;使用ã—ãŸã„オペレーティングシステムをå«ã‚€ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’é¸æŠžã—ã¦ãã ã•ã„。 ã“ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã¯èµ·å‹•å¯èƒ½ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。ãã†ã§ãªã‘れã°ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã¯èµ·å‹•ã§ãã¾ã›ã‚“。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&lt;p&gt;You have selected the following media to boot an operating system from:&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;オペレーティングシステムã®ä»¥ä¸‹ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã‹ã‚‰ã®èµ·å‹•ã‚’é¸æŠžã—ã¾ã—ãŸ::&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be mounted on the virtual machine and the machine will start execution.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;上記ã®è¨­å®šãŒæ­£ã—ã‘れã°ã€&lt;b&gt;[終了]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。 é¸æŠžã•れãŸãƒ¡ãƒ‡ã‚£ã‚¢ã¯ä»®æƒ³ãƒžã‚·ãƒ³ã«å–り付ã‘られã€ä»®æƒ³ãƒžã‚·ãƒ³ã¯å®Ÿè¡Œã‚’é–‹å§‹ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&lt; &amp;Back</source>
<translation type="obsolete">&lt; 戻る(&amp;B)</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&amp;Next &gt;</source>
<translation type="obsolete">次ã¸(&amp;N) &gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Arial&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
@@ -1697,24 +1711,20 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;p, li { white-space: pre-wrap; }&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Arial&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;上記ã®è¨­å®šãŒæ­£ã—ã‘れã°ã€[&lt;span style=&quot; font-weight:600;&quot;&gt;完了&lt;/span&gt;]ボタンをクリックã—ã¦ãã ã•ã„。 é¸æŠžã•れãŸãƒ¡ãƒ‡ã‚£ã‚¢ãŒä»®æƒ³ãƒžã‚·ãƒ³ã«ä¸€æ™‚çš„ã«ãƒžã‚¦ãƒ³ãƒˆã•れã€ä»®æƒ³ãƒžã‚·ãƒ³ãŒèµ·å‹•ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;仮想マシンを終了ã™ã‚‹ã¨ã€æŒ‡å®šã•れãŸãƒ¡ãƒ‡ã‚£ã‚¢ã¯è‡ªå‹•çš„ã«ãƒžã‚¦ãƒ³ãƒˆè§£é™¤ã•れã€èµ·å‹•デãƒã‚¤ã‚¹ã¯æœ€åˆã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã«è¨­å®šã•れã¾ã™ã€‚&lt;/p&gt;&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;セットアッププログラムã®ç¨®é¡žã«ã‚ˆã£ã¦ã¯ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ—ロセスãŒå†åº¦å®Ÿè¡Œã•れãªã„よã†ã«ã€ä»®æƒ³ãƒžã‚·ãƒ³ã®å†èµ·å‹•後ã«ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’手動ã§ãƒžã‚¦ãƒ³ãƒˆè§£é™¤(å–り出ã—)ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ã“れã¯&lt;span style=&quot; font-weight:600;&quot;&gt;[デãƒã‚¤ã‚¹]&lt;/span&gt;メニューã‹ã‚‰å¯¾å¿œã™ã‚‹&lt;span style=&quot; font-weight:600;&quot;&gt;[〜ã®ãƒžã‚¦ãƒ³ãƒˆè§£é™¤]&lt;/span&gt;ã®å‹•ä½œã‚’é¸æŠžã™ã‚‹ã“ã¨ã§è¡Œãˆã¾ã™ã€‚&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>&amp;Finish</source>
<translation type="obsolete">完了(&amp;F)</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>Type</source>
<comment>summary</comment>
<translation type="obsolete">タイプ</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>Source</source>
<comment>summary</comment>
<translation type="obsolete">ソース</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="99"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
@@ -1722,17 +1732,17 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIFirstRunWzdPage1</name>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="126"/>
+ <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="128"/>
<source>Welcome to the First Run Wizard!</source>
<translation>よã†ã“ãåˆå›žèµ·å‹•ウィザードã¸ï¼</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="128"/>
+ <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="130"/>
<source>&lt;p&gt;You have started a newly created virtual machine for the first time. This wizard will help you to perform the steps necessary for installing an operating system of your choice onto this virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
<translation>&lt;p&gt;æ–°è¦ä½œæˆã•れãŸä»®æƒ³ãƒžã‚·ãƒ³ãŒåˆã‚ã¦èµ·å‹•ã•れã¾ã—ãŸã€‚ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ã€ä»®æƒ³ãƒžã‚·ãƒ³ã«ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã‚’インストールã™ã‚‹ãŸã‚ã«å¿…è¦ãªä½œæ¥­ã‚’手助ã‘ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="134"/>
+ <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="136"/>
<source>&lt;p&gt;You have started a newly created virtual machine for the first time. This wizard will help you to perform the steps necessary for booting an operating system of your choice on the virtual machine.&lt;/p&gt;&lt;p&gt;Note that you will not be able to install an operating system into this virtual machine right now because you did not attach any hard disk to it. If this is not what you want, you can cancel the execution of this wizard, select &lt;b&gt;Settings&lt;/b&gt; from the &lt;b&gt;Machine&lt;/b&gt; menu of the main VirtualBox window to access the settings dialog of this machine and change the hard disk configuration.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
<translation>&lt;p&gt;æ–°è¦ä½œæˆã•れãŸä»®æƒ³ãƒžã‚·ãƒ³ãŒåˆã‚ã¦èµ·å‹•ã•れã¾ã—ãŸã€‚ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ã€ä»®æƒ³ãƒžã‚·ãƒ³ã‚’èµ·å‹•ã™ã‚‹ãŸã‚ã«å¿…è¦ãªä½œæ¥­ã‚’手助ã‘ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;注:ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ãªã„ãŸã‚ã€ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã«ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã‚’インストールã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã®å®Ÿè¡Œã‚’中止ã—ã¦ã€VirtualBox メインウィンドウã®&lt;b&gt;[仮想マシン]&lt;/b&gt;メニューã‹ã‚‰&lt;b&gt;[設定]&lt;/b&gt;ã‚’é¸ã‚“ã§è¨­å®šãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã€ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯æ§‹æˆã‚’変更ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
@@ -1755,7 +1765,7 @@ p, li { white-space: pre-wrap; }
<translation>メディア ソース</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="195"/>
+ <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="197"/>
<source>Select Installation Media</source>
<translation>ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’é¸æŠž</translation>
</message>
@@ -1783,72 +1793,29 @@ p, li { white-space: pre-wrap; }
<translation>&lt;p&gt;上記ã®è¨­å®šãŒæ­£ã—ã‘れã°ã€&lt;b&gt;[終了]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。 é¸æŠžã•れãŸãƒ¡ãƒ‡ã‚£ã‚¢ã¯ä»®æƒ³ãƒžã‚·ãƒ³ã«å–り付ã‘られã€ä»®æƒ³ãƒžã‚·ãƒ³ã¯å®Ÿè¡Œã‚’é–‹å§‹ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="269"/>
+ <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="271"/>
<source>Summary</source>
<translation>概è¦</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="274"/>
+ <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="276"/>
<source>CD/DVD-ROM Device</source>
<translation>CD/DVD-ROMデãƒã‚¤ã‚¹</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="282"/>
+ <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="284"/>
<source>Type</source>
<comment>summary</comment>
<translation>タイプ</translation>
</message>
<message>
- <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="283"/>
+ <location filename="../src/wizards/firstrun/UIFirstRunWzd.cpp" line="285"/>
<source>Source</source>
<comment>summary</comment>
<translation>ソース</translation>
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="440"/>
- <source>General</source>
- <translation>一般</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="443"/>
- <source>Input</source>
- <translation>入力</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="446"/>
- <source>Update</source>
- <translation>アップデート</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="449"/>
- <source>Language</source>
- <translation>言語</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="452"/>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="455"/>
- <source>Network</source>
- <translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="458"/>
- <source>Extensions</source>
- <translation>機能拡張</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="469"/>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<location filename="../src/settings/global/UIGlobalSettingsExtension.ui" line="48"/>
@@ -1876,6 +1843,7 @@ 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"/>
<source>Extensions</source>
<translation>機能拡張</translation>
@@ -1904,7 +1872,6 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIGlobalSettingsGeneral</name>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="321"/>
<source>Displays the path to the default VDI folder. This folder is used, if not explicitly specified otherwise, when adding existing or creating new virtual hard disks.</source>
<translation type="obsolete">デフォルトã®VDIフォルダã®ãƒ‘スを表示ã—ã¾ã™ã€‚æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ä½œæˆæ™‚ã«ä¿å­˜å…ˆã‚’æ˜Žç¤ºçš„ã«æŒ‡å®šã—ãªã„å ´åˆã€ã“ã®ãƒ•ォルダãŒä½¿ç”¨ã•れã¾ã™ã€‚</translation>
</message>
@@ -1919,7 +1886,6 @@ p, li { white-space: pre-wrap; }
<translation>リモートディスプレイ(VRDP)クライアントã«èªè¨¼ã‚’æä¾›ã™ã‚‹ãƒ©ã‚¤ãƒ–ラリã®ãƒ‘スを表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsGeneral.cpp" line="151"/>
<source>Default &amp;Hard Disk Folder:</source>
<translation type="obsolete">デフォルト ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ フォルダ(&amp;H):</translation>
</message>
@@ -1944,7 +1910,6 @@ p, li { white-space: pre-wrap; }
<translation>ホストã®ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚»ãƒ¼ãƒãƒ¼ã‚’無効化(&amp;S)</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsGeneral.ui" line="151"/>
<source>Displays the path to the default hard disk folder. This folder is used, if not explicitly specified otherwise, when adding existing or creating new virtual hard disks.</source>
<translation type="obsolete">デフォルトã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ フォルダã®ãƒ‘スを表示ã—ã¾ã™ã€‚既存ディスクを追加ã™ã‚‹ã‹ã€ã¾ãŸã¯æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ä½œæˆæ™‚ã«ä¿å­˜å…ˆã‚’æ˜Žç¤ºçš„ã«æŒ‡å®šã—ãªã„å ´åˆã€ã“ã®ãƒ•ォルダãŒä½¿ç”¨ã•れã¾ã™ã€‚</translation>
</message>
@@ -1959,12 +1924,10 @@ p, li { white-space: pre-wrap; }
<translation>システムトレイアイコンを表示(&amp;S)</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsGeneral.ui" line="108"/>
<source>When checked, the Dock Icon will reflect the VM window content in realtime.</source>
<translation type="obsolete">仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’ドックアイコンã«ãƒªã‚¢ãƒ«ã‚¿ã‚¤ãƒ ã§ãƒ—レビューã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsGeneral.ui" line="108"/>
<source>&amp;Dock Icon Realtime Preview</source>
<translation type="obsolete">ドックアイコンã®ãƒªã‚¢ãƒ«ã‚¿ã‚¤ãƒ ãƒ—レビュー(&amp;D)</translation>
</message>
@@ -1997,12 +1960,10 @@ p, li { white-space: pre-wrap; }
<translation>仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã§ãƒ›ã‚¹ãƒˆã‚­ãƒ¼ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã‚­ãƒ¼ã‚³ãƒ³ãƒ“ãƒãƒ¼ã‚·ãƒ§ãƒ³ã‚’リセットã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsInput.ui" line="77"/>
<source>Reset Host Key</source>
<translation type="obsolete">ホストキーã®ãƒªã‚»ãƒƒãƒˆ</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsInput.ui" line="77"/>
<source>Resets the key used as a Host Key in the VM window.</source>
<translation type="obsolete">仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã§ãƒ›ã‚¹ãƒˆã‚­ãƒ¼ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã‚­ãƒ¼ã‚’リセットã—ã¾ã™ã€‚</translation>
</message>
@@ -2020,6 +1981,7 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIGlobalSettingsLanguage</name>
<message>
+ <location filename="../src/settings/global/UIGlobalSettingsLanguage.cpp" line="88"/>
<location filename="../src/settings/global/UIGlobalSettingsLanguage.cpp" line="89"/>
<source> (built-in)</source>
<comment>Language</comment>
@@ -2087,7 +2049,6 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIGlobalSettingsNetwork</name>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsLanguage.cpp" line="358"/>
<source>%1 network</source>
<comment>&lt;adapter name&gt; network</comment>
<translation type="obsolete">%1 ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
@@ -2150,6 +2111,8 @@ p, li { white-space: pre-wrap; }
<translation>IPv4 アドレス</translation>
</message>
<message>
+ <location filename="../src/settings/global/UIGlobalSettingsNetwork.cpp" line="138"/>
+ <location filename="../src/settings/global/UIGlobalSettingsNetwork.cpp" line="149"/>
<location filename="../src/settings/global/UIGlobalSettingsNetwork.cpp" line="170"/>
<source>Not set</source>
<comment>address</comment>
@@ -2161,6 +2124,7 @@ p, li { white-space: pre-wrap; }
<translation>IPv4 ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ マスク</translation>
</message>
<message>
+ <location filename="../src/settings/global/UIGlobalSettingsNetwork.cpp" line="142"/>
<location filename="../src/settings/global/UIGlobalSettingsNetwork.cpp" line="174"/>
<source>Not set</source>
<comment>mask</comment>
@@ -2215,6 +2179,7 @@ p, li { white-space: pre-wrap; }
<translation>下é™</translation>
</message>
<message>
+ <location filename="../src/settings/global/UIGlobalSettingsNetwork.cpp" line="178"/>
<location filename="../src/settings/global/UIGlobalSettingsNetwork.cpp" line="182"/>
<source>Not set</source>
<comment>bound</comment>
@@ -2241,17 +2206,16 @@ p, li { white-space: pre-wrap; }
<translation>ホストオンリー ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’編集(&amp;E)</translation>
</message>
<message>
+ <location filename="../src/settings/global/UIGlobalSettingsNetwork.cpp" line="420"/>
<location filename="../src/settings/global/UIGlobalSettingsNetwork.cpp" line="473"/>
<source>Networking</source>
<translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsNetwork.cpp" line="473"/>
<source>New Host-Only Interface</source>
<translation type="obsolete">æ–°è¦ãƒ›ã‚¹ãƒˆ インターフェース</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsNetwork.cpp" line="473"/>
<source>Performing</source>
<comment>creating/removing host-only network</comment>
<translation type="obsolete">動作</translation>
@@ -2391,6 +2355,69 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <location filename="../src/settings/global/UIGlobalSettingsProxy.ui" line="48"/>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/global/UIGlobalSettingsProxy.ui" line="51"/>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/global/UIGlobalSettingsProxy.ui" line="82"/>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/global/UIGlobalSettingsProxy.ui" line="95"/>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/global/UIGlobalSettingsProxy.ui" line="102"/>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/global/UIGlobalSettingsProxy.ui" line="115"/>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/global/UIGlobalSettingsProxy.ui" line="124"/>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/global/UIGlobalSettingsProxy.ui" line="127"/>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/global/UIGlobalSettingsProxy.ui" line="153"/>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/global/UIGlobalSettingsProxy.ui" line="166"/>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/global/UIGlobalSettingsProxy.ui" line="173"/>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/global/UIGlobalSettingsProxy.ui" line="186"/>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<location filename="../src/settings/global/UIGlobalSettingsUpdate.ui" line="48"/>
@@ -2465,38 +2492,38 @@ p, li { white-space: pre-wrap; }
<name>UIHotKeyEditor</name>
<message>
<location filename="../src/widgets/UIHotKeyEditor.cpp" line="127"/>
+ <location filename="../src/widgets/UIHotKeyEditor.cpp" line="248"/>
+ <location filename="../src/widgets/UIHotKeyEditor.cpp" line="250"/>
+ <location filename="../src/widgets/UIHotKeyEditor.cpp" line="252"/>
<source>Left </source>
<translation>å·¦</translation>
</message>
<message>
<location filename="../src/widgets/UIHotKeyEditor.cpp" line="133"/>
+ <location filename="../src/widgets/UIHotKeyEditor.cpp" line="249"/>
+ <location filename="../src/widgets/UIHotKeyEditor.cpp" line="251"/>
<source>Right </source>
<translation>å³</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="248"/>
<source>Left Shift</source>
- <translation>å·¦ Shift</translation>
+ <translation type="obsolete">å·¦ Shift</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="249"/>
<source>Right Shift</source>
- <translation>å³ Shift</translation>
+ <translation type="obsolete">å³ Shift</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="250"/>
<source>Left Ctrl</source>
- <translation>å·¦ Ctrl</translation>
+ <translation type="obsolete">å·¦ Ctrl</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="251"/>
<source>Right Ctrl</source>
- <translation>å³ Ctrl</translation>
+ <translation type="obsolete">å³ Ctrl</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="252"/>
<source>Left Alt</source>
- <translation>å·¦ Alt</translation>
+ <translation type="obsolete">å·¦ Alt</translation>
</message>
<message>
<location filename="../src/widgets/UIHotKeyEditor.cpp" line="253"/>
@@ -2534,157 +2561,130 @@ p, li { white-space: pre-wrap; }
<translation>Scroll Lock</translation>
</message>
<message>
+ <location filename="../src/widgets/UIHotKeyEditor.cpp" line="276"/>
<location filename="../src/widgets/UIHotKeyEditor.cpp" line="617"/>
<source>None</source>
<translation>ãªã—</translation>
</message>
<message>
+ <location filename="../src/widgets/UIHotKeyEditor.cpp" line="101"/>
<location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>&lt;key_%1&gt;</source>
<translation>&lt;キー %1&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>Pause</source>
<translation type="obsolete">Pause</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>Print Screen</source>
<translation type="obsolete">Print Screen</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F1</source>
<translation type="obsolete">F1</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F2</source>
<translation type="obsolete">F2</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F3</source>
<translation type="obsolete">F3</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F4</source>
<translation type="obsolete">F4</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F5</source>
<translation type="obsolete">F5</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F6</source>
<translation type="obsolete">F6</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F7</source>
<translation type="obsolete">F7</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F8</source>
<translation type="obsolete">F8</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F9</source>
<translation type="obsolete">F9</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F10</source>
<translation type="obsolete">F10</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F11</source>
<translation type="obsolete">F11</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F12</source>
<translation type="obsolete">F12</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F13</source>
<translation type="obsolete">F13</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F14</source>
<translation type="obsolete">F14</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F15</source>
<translation type="obsolete">F15</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F16</source>
<translation type="obsolete">F16</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F17</source>
<translation type="obsolete">F17</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F18</source>
<translation type="obsolete">F18</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F19</source>
<translation type="obsolete">F19</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F20</source>
<translation type="obsolete">F20</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F21</source>
<translation type="obsolete">F21</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F22</source>
<translation type="obsolete">F22</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F23</source>
<translation type="obsolete">F23</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>F24</source>
<translation type="obsolete">F24</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>Num Lock</source>
<translation type="obsolete">Num Lock</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>Forward</source>
<translation type="obsolete">Forward</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>Back</source>
<translation type="obsolete">Back</translation>
</message>
@@ -2692,12 +2692,10 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIImportApplianceWzd</name>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>Select an appliance to import</source>
<translation type="obsolete">インãƒãƒ¼ãƒˆã™ã‚‹ä»®æƒ³ã‚¢ãƒ—ãƒ©ã‚¤ã‚¢ãƒ³ã‚¹ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/widgets/UIHotKeyEditor.cpp" line="115"/>
<source>Open Virtualization Format (%1)</source>
<translation type="obsolete">Open Virtualization Format (%1)</translation>
</message>
@@ -2707,12 +2705,15 @@ p, li { white-space: pre-wrap; }
<translation>仮想アプライアンス インãƒãƒ¼ãƒˆ ウィザード</translation>
</message>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="154"/>
+ <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="158"/>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Welcome to the Appliance Import Wizard!</source>
<translation type="obsolete">よã†ã“ã仮想アプライアンス インãƒãƒ¼ãƒˆ ウィザードã¸ï¼</translation>
</message>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="154"/>
<source>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
@@ -2723,27 +2724,22 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;p, li { white-space: pre-wrap; }&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ã€ä»®æƒ³ã‚¢ãƒ—ライアンスをインãƒãƒ¼ãƒˆã™ã‚‹æ‰‹é †ã‚’案内ã—ã¾ã™ã€‚ &lt;/p&gt;&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã®æ¬¡ã®ãƒšãƒ¼ã‚¸ã«é€²ã‚€ã«ã¯&lt;span style=&quot; font-weight:600;&quot;&gt;[次ã¸]&lt;/span&gt;ボタンをã€å‰ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã‚‹ã«ã¯&lt;span style=&quot; font-weight:600;&quot;&gt;[戻る]&lt;/span&gt;ボタンを使用ã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;インãƒãƒ¼ãƒˆã™ã‚‹ã«ã¯ã€æœ€åˆã«ä»®æƒ³ã‚¢ãƒ—ãƒ©ã‚¤ã‚¢ãƒ³ã‚¹æƒ…å ±ãŒæ›¸ã‹ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。 VirtualBoxã¯Open Virtualization Format(OVF)をサãƒãƒ¼ãƒˆã—ã¾ã™ã€‚ç¶šã„ã¦ã€ä»¥ä¸‹ã‹ã‚‰ã‚¤ãƒ³ãƒãƒ¼ãƒˆã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="154"/>
<source>&lt; &amp;Back</source>
<translation type="obsolete">&lt; 戻る(&amp;B)</translation>
</message>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="154"/>
<source>&amp;Next &gt;</source>
<translation type="obsolete">次ã¸(&amp;N) &gt;</translation>
</message>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="154"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="154"/>
<source>Appliance Import Settings</source>
<translation type="obsolete">仮想アプライアンスã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆè¨­å®š</translation>
</message>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="154"/>
<source>These are the virtual machines contained in the appliance and the suggested settings of the imported VirtualBox machines. You can change many of the properties shown by double-clicking on the items and disable others using the check boxes below.</source>
<translation type="obsolete">VirtualBoxã¸ã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã®ãŸã‚ã«ä»®æƒ³ã‚¢ãƒ—ライアンス情報ã§è¨˜è¼‰ã•れãŸä»®æƒ³ãƒžã‚·ãƒ³æ§‹æˆã§ã™ã€‚項目をダブルクリックã™ã‚‹ã¨ã€è¡¨ç¤ºã•れã¦ã„るプロパティã®å¤§éƒ¨åˆ†ã‚’変更ã§ãã¾ã™ã€‚ã¾ãŸã€ä»¥ä¸‹ã®ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã‚’使用ã—ã¦ä»–ã®ãƒ—ロパティを無効化ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚</translation>
</message>
@@ -2753,7 +2749,6 @@ p, li { white-space: pre-wrap; }
<translation>ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã«æˆ»ã™</translation>
</message>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="157"/>
<source>&amp;Import &gt;</source>
<translation type="obsolete">インãƒãƒ¼ãƒˆ(&amp;I) &gt;</translation>
</message>
@@ -2761,22 +2756,22 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIImportApplianceWzdPage1</name>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="184"/>
+ <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="185"/>
<source>Select an appliance to import</source>
<translation>インãƒãƒ¼ãƒˆã™ã‚‹ä»®æƒ³ã‚¢ãƒ—ãƒ©ã‚¤ã‚¢ãƒ³ã‚¹ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="185"/>
+ <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="186"/>
<source>Open Virtualization Format (%1)</source>
<translation>Open Virtualization Format (%1)</translation>
</message>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="188"/>
+ <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="189"/>
<source>Welcome to the Appliance Import Wizard!</source>
<translation>よã†ã“ã仮想アプライアンス インãƒãƒ¼ãƒˆ ウィザードã¸ï¼</translation>
</message>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="190"/>
+ <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="191"/>
<source>&lt;p&gt;This wizard will guide you through importing an appliance.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;VirtualBox currently supports importing appliances saved in the Open Virtualization Format (OVF). To continue, select the file to import below:&lt;/p&gt;</source>
<translation>&lt;p&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ã€ä»®æƒ³ã‚¢ãƒ—ライアンスをインãƒãƒ¼ãƒˆã™ã‚‹æ‰‹é †ã‚’案内ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;VirtualBoxã¯Open Virtualization Format(OVF)å½¢å¼ã§ä¿å­˜ã•れãŸã‚¢ãƒ—ライアンスã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã‚’サãƒãƒ¼ãƒˆã—ã¾ã™ã€‚インãƒãƒ¼ãƒˆã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ç¶šè¡Œã—ã¦ãã ã•ã„:&lt;/p&gt;</translation>
</message>
@@ -2789,7 +2784,7 @@ p, li { white-space: pre-wrap; }
<translation>VirtualBoxã¸ã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã®ãŸã‚ã«ä»®æƒ³ã‚¢ãƒ—ライアンス情報ã§è¨˜è¼‰ã•れãŸä»®æƒ³ãƒžã‚·ãƒ³æ§‹æˆã§ã™ã€‚項目をダブルクリックã—ã¦è¡¨ç¤ºã•れã¦ã„るプロパティを変更ã§ãã¾ã™ã€‚ã¾ãŸã¯ã€ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã‚’使用ã—ã¦ãƒ—ロパティを無効化ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="249"/>
+ <location filename="../src/wizards/importappliance/UIImportApplianceWzd.cpp" line="250"/>
<source>Appliance Import Settings</source>
<translation>仮想アプライアンスã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆè¨­å®š</translation>
</message>
@@ -2928,34 +2923,37 @@ p, li { white-space: pre-wrap; }
<translation>&lt;hr&gt;リモートデスクトップサーãƒãƒ¼ã¯ãƒãƒ¼ãƒˆ %1 ã‚’å¾…ã¡å—ã‘ã—ã¦ã„ã¾ã™</translation>
</message>
<message>
- <location filename="../src/runtime/UIIndicatorsPool.cpp" line="516"/>
+ <location filename="../src/runtime/UIIndicatorsPool.cpp" line="570"/>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Indicates whether the Remote Display (VRDP Server) is enabled (&lt;img src=:/vrdp_16px.png/&gt;) or not (&lt;img src=:/vrdp_disabled_16px.png/&gt;).</source>
<translation type="obsolete">リモートディスプレイ(VRDPサーãƒãƒ¼)æ©Ÿèƒ½ãŒæœ‰åйãªã¨ã(&lt;img src=:/vrdp_16px.png/&gt;) ã‚’ã€ç„¡åйãªã¨ã (&lt;img src=:/vrdp_disabled_16px.png/&gt;)を表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/runtime/UIIndicatorsPool.cpp" line="516"/>
<source>&lt;hr&gt;The VRDP Server is listening on port %1</source>
<translation type="obsolete">&lt;hr&gt;VRDPサーãƒãƒ¼ã¯ãƒãƒ¼ãƒˆ %1 ã‚’å¾…ã¡å—ã‘ã—ã¦ã„ã¾ã™</translation>
</message>
<message>
- <location filename="../src/runtime/UIIndicatorsPool.cpp" line="568"/>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>仮想マシンã§ä½¿ç”¨ã•ã‚Œã‚‹ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½ã®çŠ¶æ…‹ã‚’è¡¨ç¤º:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">仮想マシンã§ä½¿ç”¨ã•ã‚Œã‚‹ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½ã®çŠ¶æ…‹ã‚’è¡¨ç¤º:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/runtime/UIIndicatorsPool.cpp" line="578"/>
+ <location filename="../src/runtime/UIIndicatorsPool.cpp" line="583"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/runtime/UIIndicatorsPool.cpp" line="612"/>
+ <location filename="../src/runtime/UIIndicatorsPool.cpp" line="617"/>
<source>Indicates whether the host mouse pointer is captured by the guest OS:&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_disabled_16px.png/&gt;&amp;nbsp;&amp;nbsp;pointer is not captured&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_16px.png/&gt;&amp;nbsp;&amp;nbsp;pointer is captured&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;mouse integration (MI) is On&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;MI is Off, pointer is captured&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_uncaptured_16px.png/&gt;&amp;nbsp;&amp;nbsp;MI is Off, pointer is not captured&lt;/nobr&gt;&lt;br&gt;Note that the mouse integration feature requires Guest Additions to be installed in the guest OS.</source>
<translation>ホスト マウスãƒã‚¤ãƒ³ã‚¿ã®ã‚­ãƒ£ãƒ—ãƒãƒ£çŠ¶æ…‹ã‚’è¡¨ç¤º:&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_disabled_16px.png/&gt;&amp;nbsp;&amp;nbsp;キャプãƒãƒ£ã•れã¦ã„ã¾ã›ã‚“&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_16px.png/&gt;&amp;nbsp;&amp;nbsp;キャプãƒãƒ£ã•れã¦ã„ã¾ã™&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;マウス統åˆã¯æœ‰åйã§ã™&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;マウス統åˆã¯ç„¡åйã€ã‚­ãƒ£ãƒ—ãƒãƒ£ã•れã¦ã„ã¾ã™&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_uncaptured_16px.png/&gt;&amp;nbsp;&amp;nbsp;マウス統åˆã¯ç„¡åйã€ã‚­ãƒ£ãƒ—ãƒãƒ£ã•れã¦ã„ã¾ã›ã‚“&lt;/nobr&gt;&lt;br&gt; æ³¨ï¼šãƒžã‚¦ã‚¹çµ±åˆæ©Ÿèƒ½ã®åˆ©ç”¨ã«ã¯ã‚²ã‚¹ãƒˆOSã« Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/runtime/UIIndicatorsPool.cpp" line="663"/>
+ <location filename="../src/runtime/UIIndicatorsPool.cpp" line="668"/>
<source>Indicates whether the keyboard is captured by the guest OS (&lt;img src=:/hostkey_captured_16px.png/&gt;) or not (&lt;img src=:/hostkey_16px.png/&gt;).</source>
<translation>キーボードãŒã‚²ã‚¹ãƒˆOSã«ã‚­ãƒ£ãƒ—ãƒãƒ£ã•れã¦ã„ã‚‹ã¨ã(&lt;img src=:/hostkey_captured_16px.png/&gt;ã‚’ã€ç„¡åйãªã¨ã(&lt;img src=:/hostkey_16px.png/&gt;)を表示ã—ã¾ã™ã€‚</translation>
</message>
@@ -2963,7 +2961,6 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineLogic</name>
<message>
- <location filename="../src/runtime/UIIndicatorsPool.cpp" line="663"/>
<source>VirtualBox OSE</source>
<translation type="obsolete">VirtualBox OSE</translation>
</message>
@@ -2973,62 +2970,58 @@ p, li { white-space: pre-wrap; }
<translation>試験的ビルド %1r%2 - %3</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="414"/>
+ <location filename="../src/runtime/UIMachineLogic.cpp" line="265"/>
<source>Preview Monitor %1</source>
<translation>プレビュー ディスプレイ %1</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1008"/>
+ <location filename="../src/runtime/UIMachineLogic.cpp" line="864"/>
<source>Snapshot %1</source>
<translation>スナップショット %1</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1008"/>
<source>More CD/DVD Images...</source>
<translation type="obsolete">CD/DVD イメージã®è¿½åŠ ...</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1008"/>
<source>Unmount CD/DVD Device</source>
<translation type="obsolete">CD/DVD デãƒã‚¤ã‚¹ã®ãƒžã‚¦ãƒ³ãƒˆè§£é™¤</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1008"/>
<source>More Floppy Images...</source>
<translation type="obsolete">フロッピー イメージã®è¿½åŠ ...</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1008"/>
<source>Unmount Floppy Device</source>
<translation type="obsolete">フロッピー デãƒã‚¤ã‚¹ã®ãƒžã‚¦ãƒ³ãƒˆè§£é™¤</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1282"/>
+ <location filename="../src/runtime/UIMachineLogic.cpp" line="1166"/>
<source>No CD/DVD Devices Attached</source>
<translation>CD/DVD デãƒã‚¤ã‚¹ 未割り当ã¦</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1283"/>
+ <location filename="../src/runtime/UIMachineLogic.cpp" line="1167"/>
<source>No CD/DVD devices attached to that VM</source>
<translation>CD/DVD デãƒã‚¤ã‚¹ 未割り当ã¦</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1286"/>
+ <location filename="../src/runtime/UIMachineLogic.cpp" line="1170"/>
<source>No Floppy Devices Attached</source>
<translation>フロッピー デãƒã‚¤ã‚¹ 未割り当ã¦</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1287"/>
+ <location filename="../src/runtime/UIMachineLogic.cpp" line="1171"/>
<source>No floppy devices attached to that VM</source>
<translation>フロッピー デãƒã‚¤ã‚¹ 未割り当ã¦</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1458"/>
+ <location filename="../src/runtime/UIMachineLogic.cpp" line="1342"/>
<source>No USB Devices Connected</source>
<translation>USB デãƒã‚¤ã‚¹ 未接続</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1460"/>
+ <location filename="../src/runtime/UIMachineLogic.cpp" line="1344"/>
<source>No supported devices connected to the host PC</source>
<translation>ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã«æŽ¥ç¶šã•れãŸãƒ‡ãƒã‚¤ã‚¹ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“</translation>
</message>
@@ -3069,22 +3062,34 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsDisplay</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="279"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="335"/>
<source>you have assigned less than &lt;b&gt;%1&lt;/b&gt; of video memory which is the minimum amount required to switch the virtual machine to fullscreen or seamless mode.</source>
<translation>仮想マシンをフルスクリーンã¾ãŸã¯ã‚·ãƒ¼ãƒ ãƒ¬ã‚¹ãƒ¢ãƒ¼ãƒ‰ã«åˆ‡ã‚Šæ›ãˆã‚‹ãŸã‚ã«å¿…è¦ãªå€¤(%1)より少ãªã„ビデオメモリãŒä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="307"/>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>WDDMドライãƒã‚’使用ã™ã‚‹ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã§3Dã‚¢ã‚¯ã‚»ãƒ©ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒæœ‰åŠ¹åŒ–ã•れã¾ã—ãŸã€‚性能å‘上ã®ãŸã‚&lt;b&gt;%1&lt;/b&gt;以上ã®ãƒ“デオメモリを指定ã—ã¦ãã ã•ã„。</translation>
+ <translation type="obsolete">WDDMドライãƒã‚’使用ã™ã‚‹ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã§3Dã‚¢ã‚¯ã‚»ãƒ©ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒæœ‰åŠ¹åŒ–ã•れã¾ã—ãŸã€‚性能å‘上ã®ãŸã‚&lt;b&gt;%1&lt;/b&gt;以上ã®ãƒ“デオメモリを指定ã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="415"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="365"/>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="380"/>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">2D ビデオ ã‚¢ã‚¯ã‚»ãƒ©ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒæœ‰åŠ¹åŒ–ã•れã¾ã—ãŸã€‚2D ビデオ アクセラレーションã¯Windowsゲストã§ã®ã¿ã‚µãƒãƒ¼ãƒˆã•れるãŸã‚ã€æœ¬æ©Ÿèƒ½ã¯ç„¡åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="418"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="419"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="491"/>
<source>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</source>
<translation>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="350"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="420"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="421"/>
<source>&lt;qt&gt;%1&lt;/qt&gt;</source>
<translation>&lt;qt&gt;%1&lt;/qt&gt;</translation>
</message>
@@ -3099,112 +3104,114 @@ p, li { white-space: pre-wrap; }
<translation>ビデオメモリ(&amp;M):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="130"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="70"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="127"/>
<source>Controls the amount of video memory provided to the virtual machine.</source>
<translation>仮想マシンã«å‰²ã‚Šå½“ã¦ã‚‹ãƒ“デオメモリã®ã‚µã‚¤ã‚ºã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="143"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="140"/>
<source>MB</source>
<translation>MB</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="152"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="149"/>
<source>Mo&amp;nitor Count:</source>
<translation>ディスプレイ数(&amp;N):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="236"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="167"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="233"/>
<source>Controls the amount of virtual monitors provided to the virtual machine.</source>
<translation>仮想マシンã«å‰²ã‚Šå½“ã¦ã‚‹ä»®æƒ³ãƒ‡ã‚£ã‚¹ãƒ—ãƒ¬ã‚¤ã®æ•°ã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="435"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="245"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="432"/>
<source>Extended Features:</source>
<translation>拡張機能:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="264"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="261"/>
<source>When checked, the virtual machine will be given access to the 3D graphics capabilities available on the host.</source>
<translation>仮想マシンã¯ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã®3Dグラフィックス機能を利用ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="267"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="264"/>
<source>Enable &amp;3D Acceleration</source>
<translation>3Dアクセラレーションを有効化(&amp;3)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="307"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="304"/>
<source>&amp;Remote Display</source>
<translation>リモートディスプレイ(&amp;R)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="328"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="325"/>
<source>When checked, the VM will act as a Remote Desktop Protocol (RDP) server, allowing remote clients to connect and operate the VM (when it is running) using a standard RDP client.</source>
<translation>仮想マシンã®ãƒªãƒ¢ãƒ¼ãƒˆãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—プロトコル(RDP)ã‚µãƒ¼ãƒæ©Ÿèƒ½ã‚’有効ã«ã—ã¾ã™ã€‚ãƒªãƒ¢ãƒ¼ãƒˆã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆãŒæ¨™æº–çš„ãªRDPクライアントを使用ã—ã¦å®Ÿè¡Œä¸­ã®ä»®æƒ³ãƒžã‚·ãƒ³ã«æŽ¥ç¶šã—ã€æ“作ã™ã‚‹ã“ã¨ã‚’å¯èƒ½ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="331"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="328"/>
<source>&amp;Enable Server</source>
<translation>サーãƒãƒ¼ã‚’有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="369"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="366"/>
<source>Server &amp;Port:</source>
<translation>サーãƒãƒ¼ã®ãƒãƒ¼ãƒˆç•ªå·(&amp;P):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="451"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="448"/>
<source>Specifies whether multiple simultaneous connections to the VM are permitted.</source>
<translation>仮想マシンã¸ã®è¤‡æ•°ã®åŒæ™‚接続を許å¯ã™ã‚‹ã‹ã©ã†ã‹ã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="454"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="451"/>
<source>&amp;Allow Multiple Connections</source>
<translation>è¤‡æ•°ã®æŽ¥ç¶šã‚’è¨±å¯(&amp;A)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="454"/>
<source>Displays the VRDP Server port number. You may specify &lt;tt&gt;0&lt;/tt&gt; (zero) to reset the port to the default value.</source>
<translation type="obsolete">VRDPサーãƒãƒ¼ã®ãƒãƒ¼ãƒˆç•ªå·ã‚’表示ã—ã¾ã™ã€‚ãƒãƒ¼ãƒˆã‚’デフォルト値ã«ãƒªã‚»ãƒƒãƒˆã™ã‚‹ã«ã¯&lt;tt&gt;0&lt;/tt&gt;(ゼロ)を指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="389"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="386"/>
<source>Authentication &amp;Method:</source>
<translation>èªè¨¼æ–¹å¼(&amp;M):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="408"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="405"/>
<source>Defines the VRDP authentication method.</source>
<translation>VRDPã®èªè¨¼æ–¹å¼ã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="415"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="412"/>
<source>Authentication &amp;Timeout:</source>
<translation>èªè¨¼ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆå€¤(&amp;T):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="428"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="425"/>
<source>Specifies the timeout for guest authentication, in milliseconds.</source>
<translation>ゲストèªè¨¼ã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆå€¤ã‚’ミリ秒å˜ä½ã§æŒ‡å®šã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="291"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.cpp" line="348"/>
<source>you have assigned less than &lt;b&gt;%1&lt;/b&gt; of video memory which is the minimum amount required for HD Video to be played efficiently.</source>
<translation>HD Videoを効率よãå†ç”Ÿã™ã‚‹ãŸã‚ã«å¿…è¦ãªå€¤(%1)より少ãªã„ビデオメモリãŒä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="280"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="277"/>
<source>When checked, the virtual machine will be given access to the Video Acceleration capabilities available on the host.</source>
<translation>仮想マシンã¯ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã®ãƒ“デオ アクセラレーション機能を利用ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="283"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="280"/>
<source>Enable &amp;2D Video Acceleration</source>
<translation>2Dビデオ アクセラレーションを有効化(&amp;2)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="382"/>
+ <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="379"/>
<source>The VRDP Server port number. You may specify &lt;tt&gt;0&lt;/tt&gt; (zero), to select port 3389, the standard port for RDP.</source>
<translation>VRDPサーãƒãƒ¼ã®ãƒãƒ¼ãƒˆç•ªå·ã§ã™ã€‚RDP標準ã®ãƒãƒ¼ãƒˆç•ªå·(3389)ã‚’é¸æŠžã™ã‚‹ãŸã‚ã«&lt;tt&gt;0&lt;/tt&gt;(ゼロ)を指定ã§ãã¾ã™ã€‚</translation>
</message>
@@ -3212,12 +3219,16 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsGeneral</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsDisplay.ui" line="382"/>
<source>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</source>
<translation type="obsolete">&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.cpp" line="184"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.cpp" line="205"/>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">64ビットã®ã‚²ã‚¹ãƒˆOSタイプãŒé¸æŠžã•れã¾ã—ãŸã€‚ゲストOSãŒä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½(VT-x/AMD-V)ã‚’å¿…è¦ã¨ã™ã‚‹ã¨ãã€ã“ã®æ©Ÿèƒ½ã¯è‡ªå‹•çš„ã«æœ‰åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.cpp" line="235"/>
<source>Displays the path where snapshots of this virtual machine will be stored. Be aware that snapshots can take quite a lot of disk space.</source>
<translation>ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®ã‚¹ãƒŠãƒƒãƒ—ショットã®ä¿å­˜å…ˆãƒ‘スを表示ã—ã¾ã™ã€‚注:スナップショットã¯å¤šãã®ãƒ‡ã‚£ã‚¹ã‚¯å®¹é‡ã‚’消費ã—ã¾ã™ã€‚</translation>
</message>
@@ -3227,7 +3238,6 @@ p, li { white-space: pre-wrap; }
<translation>基本(&amp;B)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="33"/>
<source>Identification</source>
<translation type="obsolete">詳細</translation>
</message>
@@ -3242,272 +3252,232 @@ p, li { white-space: pre-wrap; }
<translation>仮想マシンã®åå‰ã‚’表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="61"/>
<source>OS &amp;Type:</source>
<translation type="obsolete">OSタイプ(&amp;T):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="61"/>
<source>Displays the operating system type that you plan to install into this virtual machine (called a guest operating system).</source>
<translation type="obsolete">仮想マシンã§å®Ÿè¡Œã™ã‚‹OS(ゲストOSã¨å‘¼ã³ã¾ã™)ã®ã‚¿ã‚¤ãƒ—を表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="61"/>
<source>Base &amp;Memory Size</source>
<translation type="obsolete">メインメモリã®ã‚µã‚¤ã‚º(&amp;M)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="61"/>
<source>Controls the amount of memory provided to the virtual machine. If you assign too much, the machine might not start.</source>
<translation type="obsolete">仮想マシンã«å‰²ã‚Šå½“ã¦ã‚‹ãƒ¡ã‚¤ãƒ³ãƒ¡ãƒ¢ãƒªã®ã‚µã‚¤ã‚ºã‚’指定ã—ã¾ã™ã€‚割り当ã¦é‡ãŒå¤šã™ãŽã‚‹ã¨ä»®æƒ³ãƒžã‚·ãƒ³ã¯èµ·å‹•ã—ãªã„ã‹ã‚‚ã—れã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="61"/>
<source>&lt;</source>
<translation type="obsolete">&lt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="61"/>
<source>&gt;</source>
<translation type="obsolete">&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="61"/>
<source>MB</source>
<translation type="obsolete">MB</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="61"/>
<source>&amp;Video Memory Size</source>
<translation type="obsolete">ビデオメモリã®ã‚µã‚¤ã‚º(&amp;V)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="61"/>
<source>Controls the amount of video memory provided to the virtual machine.</source>
<translation type="obsolete">仮想マシンã«å‰²ã‚Šå½“ã¦ã‚‹ãƒ“デオメモリã®ã‚µã‚¤ã‚ºã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="85"/>
<source>&amp;Advanced</source>
<translation>高度(&amp;A)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>Boo&amp;t Order:</source>
<translation type="obsolete">èµ·å‹•é †åº(&amp;T):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>Defines the boot device order. Use the checkboxes on the left to enable or disable individual boot devices. Move items up and down to change the device order.</source>
<translation type="obsolete">起動デãƒã‚¤ã‚¹ã®å„ªå…ˆé †åºã‚’指定ã—ã¾ã™ã€‚ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã‚’使ã„å„デãƒã‚¤ã‚¹ã‚’有効ã¾ãŸã¯ç„¡åйã«ã§ãã¾ã™ã€‚項目を上ã¾ãŸã¯ä¸‹ã«ç§»å‹•ã—ã¦ãƒ‡ãƒã‚¤ã‚¹ã®é †åºã‚’変更ã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>[device]</source>
<translation type="obsolete">[デãƒã‚¤ã‚¹]</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>Move Up (Ctrl-Up)</source>
<translation type="obsolete">上ã«ç§»å‹•(Ctrl-Up)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>Moves the selected boot device up.</source>
<translation type="obsolete">é¸æŠžã—ãŸèµ·å‹•デãƒã‚¤ã‚¹ã‚’上ã«ç§»å‹•ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>Move Down (Ctrl-Down)</source>
<translation type="obsolete">下ã«ç§»å‹•(Ctrl-Down)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>Moves the selected boot device down.</source>
<translation type="obsolete">é¸æŠžã—ãŸèµ·å‹•デãƒã‚¤ã‚¹ã‚’下ã«ç§»å‹•ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>Extended Features:</source>
<translation type="obsolete">拡張機能:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>When checked, the virtual machine will support the Advanced Configuration and Power Management Interface (ACPI). &lt;b&gt;Note:&lt;/b&gt; don&apos;t disable this feature after having installed a Windows guest operating system!</source>
<translation type="obsolete">仮想マシンã§ACPI(Advanced Configuration and Power Management Interface)サãƒãƒ¼ãƒˆã‚’有効ã«ã—ã¾ã™ã€‚&lt;b&gt;注:&lt;/b&gt; Windows ゲストOSをインストールã—ãŸå¾Œã§æœ¬æ©Ÿèƒ½ã‚’無効ã«ã—ãªã„ã§ãã ã•ã„ï¼</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>Enable A&amp;CPI</source>
<translation type="obsolete">ACPIを有効化(&amp;C)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>When checked, the virtual machine will support the Input Output APIC (IO APIC), which may slightly decrease performance. &lt;b&gt;Note:&lt;/b&gt; don&apos;t disable this feature after having installed a Windows guest operating system!</source>
<translation type="obsolete">仮想マシンã§IO APIC(Input Output APIC)サãƒãƒ¼ãƒˆã‚’有効ã«ã—ã¾ã™ã€‚ã“れã¯ä»®æƒ³ãƒžã‚·ãƒ³ã®æ€§èƒ½ã‚’ã‚ãšã‹ã«ä½Žä¸‹ã•ã›ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。&lt;b&gt;注:&lt;/b&gt;Windows ゲストOSをインストールã—ãŸå¾Œã§æœ¬æ©Ÿèƒ½ã‚’無効ã«ã—ãªã„ã§ãã ã•ã„ï¼</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>Enable IO A&amp;PIC</source>
<translation type="obsolete">IO APICを有効化(&amp;P)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>When checked, the virtual machine will try to make use of the host CPU&apos;s hardware virtualization extensions such as Intel VT-x and AMD-V.</source>
<translation type="obsolete">仮想マシンã§ãƒ›ã‚¹ãƒˆCPUã®ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½(Intel VT-xã¾ãŸã¯AMD-V)を有効ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>Enable &amp;VT-x/AMD-V</source>
<translation type="obsolete">VT-x/AMD-Vを有効化(&amp;V)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>When checked, the Physical Address Extension (PAE) feature of the host CPU will be exposed to the virtual machine.</source>
<translation type="obsolete">仮想マシンã§ãƒ›ã‚¹ãƒˆCPUã®PAE(物ç†ã‚¢ãƒ‰ãƒ¬ã‚¹æ‹¡å¼µæ©Ÿèƒ½)を有効ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="88"/>
<source>Enable PA&amp;E/NX</source>
<translation type="obsolete">PAE/NXを有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="126"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="123"/>
<source>&amp;Shared Clipboard:</source>
<translation>クリップボードã®å…±æœ‰(&amp;S):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="145"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="142"/>
<source>Selects which clipboard data will be copied between the guest and the host OS. This feature requires Guest Additions to be installed in the guest OS.</source>
<translation>ゲストOSã¨ãƒ›ã‚¹ãƒˆOSã®é–“ã§ã‚¯ãƒªãƒƒãƒ—ボードを共有ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã‚’定義ã—ã¾ã™ã€‚注:本機能ã®åˆ©ç”¨ã«ã¯ã‚²ã‚¹ãƒˆOSã« Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="145"/>
<source>Defines the type of the virtual IDE controller. Depending on this value, VirtualBox will provide different virtual IDE hardware devices to the guest OS.</source>
<translation type="obsolete">仮想IDE コントローラã®ã‚¿ã‚¤ãƒ—を定義ã—ã¾ã™ã€‚ã“ã®å€¤ã«ã‚ˆã‚Šã€VirtualBoxã¯ç•°ãªã£ãŸä»®æƒ³IDEãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ デãƒã‚¤ã‚¹ã‚’ゲストOSã«æä¾›ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="145"/>
<source>&amp;IDE Controller Type:</source>
<translation type="obsolete">IDE コントローラ タイプ(&amp;I):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="103"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="100"/>
<source>S&amp;napshot Folder:</source>
<translation>スナップショットã®ä¿å­˜å…ˆ(&amp;N):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="259"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="256"/>
<source>&amp;Description</source>
<translation>説明(&amp;D)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="268"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="265"/>
<source>Displays the description of the virtual machine. The description field is useful for commenting on configuration details of the installed guest OS.</source>
<translation>仮想マシンã®èª¬æ˜Žã‚’表示ã—ã¾ã™ã€‚ã“れインストールã•れãŸã‚²ã‚¹ãƒˆOSã®è©³ç´°ãªæ§‹æˆã«é–¢ã™ã‚‹æ³¨é‡ˆã¨ã—ã¦å½¹ç«‹ã¡ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="268"/>
<source>&amp;Other</source>
<translation type="obsolete">ãã®ä»–(&amp;O)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="178"/>
<source>If checked, any change to mounted CD/DVD or Floppy media performed during machine execution will be saved in the settings file in order to preserve the configuration of mounted media between runs.</source>
<translation>仮想マシン実行中ã«å¤‰æ›´ã—ãŸCD/DVDã¾ãŸã¯ãƒ•ãƒ­ãƒƒãƒ”ãƒ¼ãƒ¡ãƒ‡ã‚£ã‚¢ã®æ§‹æˆã‚’設定ファイルã«ä¿å­˜ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>&amp;Remember Mounted Media</source>
<translation type="obsolete">マウントã—ãŸãƒ¡ãƒ‡ã‚£ã‚¢ã‚’記録(&amp;R)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>Runtime:</source>
<translation type="obsolete">実行時:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>you have assigned more than &lt;b&gt;75%&lt;/b&gt; of your computer&apos;s memory (&lt;b&gt;%1&lt;/b&gt;) to the virtual machine. Not enough memory is left for your host operating system. Please select a smaller amount.</source>
<translation type="obsolete">実メモリ(&lt;b&gt;%1&lt;/b)ã®&lt;b&gt;75%&lt;/b&gt;ã‚’è¶…ãˆã‚‹ãƒ¡ãƒ¢ãƒªãŒä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚ ホストOSãŒå分ãªãƒ¡ãƒ¢ãƒªã‚’使用ã§ãã¾ã›ã‚“。割り当ã¦ãƒ¡ãƒ¢ãƒªã‚’減らã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>you have assigned more than &lt;b&gt;50%&lt;/b&gt; of your computer&apos;s memory (&lt;b&gt;%1&lt;/b&gt;) to the virtual machine. There might not be enough memory left for your host operating system. Continue at your own risk.</source>
<translation type="obsolete">実メモリ(&lt;b&gt;%1&lt;/b)ã®&lt;b&gt;50%&lt;/b&gt;ã‚’è¶…ãˆã‚‹ãƒ¡ãƒ¢ãƒªãŒä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚ ホストOSãŒå分ãªãƒ¡ãƒ¢ãƒªã‚’使用ã§ãã¾ã›ã‚“。割り当ã¦ãƒ¡ãƒ¢ãƒªã‚’減らã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>you have assigned less than &lt;b&gt;%1&lt;/b&gt; of video memory which is the minimum amount required to switch the virtual machine to fullscreen or seamless mode.</source>
<translation type="obsolete">仮想マシンをフルスクリーンã¾ãŸã¯ã‚·ãƒ¼ãƒ ãƒ¬ã‚¹ãƒ¢ãƒ¼ãƒ‰ã«åˆ‡ã‚Šæ›ãˆã‚‹ãŸã‚ã«å¿…è¦ãªå€¤(%1)より少ãªã„ビデオメモリãŒä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>When checked, the virtual machine will be given access to the 3D graphics capabilities available on the host.</source>
<translation type="obsolete">仮想マシンã¯ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã®3Dグラフィックス機能を利用ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>Enable &amp;3D Acceleration</source>
<translation type="obsolete">3Dアクセラレーションを有効化(&amp;3)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>you have assigned more than &lt;b&gt;%1%&lt;/b&gt; of your computer&apos;s memory (&lt;b&gt;%2&lt;/b&gt;) to the virtual machine. Not enough memory is left for your host operating system. Please select a smaller amount.</source>
<translation type="obsolete">実メモリ(&lt;b&gt;%2&lt;/b)ã®&lt;b&gt;%1%&lt;/b&gt;ã‚’è¶…ãˆã‚‹ãƒ¡ãƒ¢ãƒªãŒä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚ ホストOSãŒå分ãªãƒ¡ãƒ¢ãƒªã‚’使用ã§ãã¾ã›ã‚“。割り当ã¦ãƒ¡ãƒ¢ãƒªã‚’減らã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>you have assigned more than &lt;b&gt;%1%&lt;/b&gt; of your computer&apos;s memory (&lt;b&gt;%2&lt;/b&gt;) to the virtual machine. There might not be enough memory left for your host operating system. Continue at your own risk.</source>
<translation type="obsolete">実メモリ(&lt;b&gt;%2&lt;/b)ã®&lt;b&gt;%1%&lt;/b&gt;ã‚’è¶…ãˆã‚‹ãƒ¡ãƒ¢ãƒªãŒä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚ ホストOSã«å分ãªãƒ¡ãƒ¢ãƒªãŒæ®‹ã•れã¦ã„ã¾ã›ã‚“。自己ã®è²¬ä»»ã§ç¶šè¡Œã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>there is a 64 bits guest OS type assigned for this VM, which requires virtualization feature (VT-x/AMD-V) to be enabled too, else your guest will fail to detect a 64 bits CPU and will not be able to boot, so this feature will be enabled automatically when you&apos;ll accept VM Settings by pressing OK button.</source>
<translation type="obsolete">64ビット ゲストOSタイプを指定ã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã¯ã€ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½(VT-x/AMD-V)を有効化ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ãã†ã§ãªã‘れã°ã‚²ã‚¹ãƒˆOSã¯64ビットCPUを検出ã§ããšã€èµ·å‹•ã§ãã¾ã›ã‚“。ã“ã®ãŸã‚[OK]ボタンを押ã—ã¦ä»®æƒ³ãƒžã‚·ãƒ³è¨­å®šã‚’ä¿å­˜ã™ã‚‹ã¨ãã€ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½ã‚’è‡ªå‹•çš„ã«æœ‰åŠ¹åŒ–ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>When checked, the virtual machine will try to make use of the nested paging extension of Intel VT-x and AMD-V.</source>
<translation type="obsolete">仮想マシンã§ãƒ›ã‚¹ãƒˆCPUã®ãƒã‚¹ãƒ†ãƒƒãƒ‰ãƒšãƒ¼ã‚¸ãƒ³ã‚°(Intel VT-xã¾ãŸã¯AMD-V)を有効ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>Enable Nested Pa&amp;ging</source>
<translation type="obsolete">ãƒã‚¹ãƒ†ãƒƒãƒ‰ãƒšãƒ¼ã‚¸ãƒ³ã‚°ã‚’有効化(&amp;G)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="165"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="162"/>
<source>Removable Media:</source>
<translation>リムーãƒãƒ–ル メディア:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="184"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="181"/>
<source>&amp;Remember Runtime Changes</source>
<translation>実行時ã«å¤‰æ›´ã—ãŸãƒ¡ãƒ‡ã‚£ã‚¢ã‚’記録(&amp;R)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="194"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="191"/>
<source>Mini ToolBar:</source>
<translation>ミニ ツールãƒãƒ¼:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="210"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="207"/>
<source>If checked, show the Mini ToolBar in Fullscreen and Seamless modes.</source>
<translation>フルスクリーンモードã¾ãŸã¯ã‚·ãƒ¼ãƒ ãƒ¬ã‚¹ãƒ¢ãƒ¼ãƒ‰æ™‚ã«ãƒŸãƒ‹ ツールãƒãƒ¼ã‚’表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="213"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="210"/>
<source>Show In &amp;Fullscreen/Seamless</source>
<translation>フルスクリーン/シームレスモード時ã«è¡¨ç¤º(&amp;F)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="229"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="226"/>
<source>If checked, show the Mini ToolBar at the top of the screen, rather than in its default position at the bottom of the screen.</source>
<translation>ミニ ツールãƒãƒ¼ã‚’ç”»é¢ã®ä¸Šéƒ¨ã«è¡¨ç¤ºã—ã¾ã™ã€‚デフォルトã®è¨­å®šã§ã¯ç”»é¢ã®ä¸‹éƒ¨ã«è¡¨ç¤ºã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="232"/>
+ <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="229"/>
<source>Show At &amp;Top Of Screen</source>
<translation>ç”»é¢ã®ä¸Šéƒ¨ã«è¡¨ç¤º(&amp;T)</translation>
</message>
@@ -3515,12 +3485,10 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsNetwork</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="232"/>
<source>Select TAP setup application</source>
<translation type="obsolete">TAPè¨­å®šã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsGeneral.ui" line="232"/>
<source>Select TAP terminate application</source>
<translation type="obsolete">TAPçµ‚äº†ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’é¸æŠž</translation>
</message>
@@ -3535,235 +3503,254 @@ p, li { white-space: pre-wrap; }
<translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタを有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="32"/>
<source>A&amp;dapter Type:</source>
<translation type="obsolete">アダプタ タイプ(&amp;D):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="165"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="159"/>
<source>Selects the type of the virtual network adapter. Depending on this value, VirtualBox will provide different network hardware to the virtual machine.</source>
<translation>仮想ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¢ãƒ€ãƒ—ã‚¿ã®ã‚¿ã‚¤ãƒ—ã‚’é¸æŠžã—ã¾ã™ã€‚ ã“ã®å€¤ã«ã‚ˆã‚Šã€VirtualBoxã¯ç•°ãªã£ãŸãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã‚’ä»®æƒ³ãƒžã‚·ãƒ³ã«æä¾›ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="64"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="61"/>
<source>&amp;Attached to:</source>
<translation>割り当ã¦(&amp;A):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="83"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="80"/>
<source>Controls how this virtual adapter is attached to the real network of the Host OS.</source>
<translation>仮想アダプタをホストOSã®å®Ÿéš›ã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã«å‰²ã‚Šå½“ã¦ã‚‹æ–¹å¼ã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="83"/>
<source>&amp;Network Name:</source>
<translation type="obsolete">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯å(&amp;N):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="83"/>
<source>Displays the name of the internal network selected for this adapter.</source>
<translation type="obsolete">ã“ã®ã‚¢ãƒ€ãƒ—タ用ã«é¸æŠžã—ãŸå†…部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯åを表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="83"/>
<source>&amp;MAC Address:</source>
<translation type="obsolete">MACアドレス(&amp;M):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="191"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="211"/>
<source>Displays the MAC address of this adapter. It contains exactly 12 characters chosen from {0-9,A-F}. Note that the second character must be an even digit.</source>
<translation>ã“ã®ã‚¢ãƒ€ãƒ—ã‚¿ã®MACアドレスを表示ã—ã¾ã™ã€‚MACアドレスã¯{0-9,A-F}ã‹ã‚‰é¸æŠžã•れãŸ12æ–‡å­—ã§æ§‹æˆã•れã¾ã™ã€‚注:2ç•ªç›®ã®æ–‡å­—ã¯å¶æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="198"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="218"/>
<source>Generates a new random MAC address.</source>
<translation>MACアドレスをランダムã«ç”Ÿæˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="198"/>
<source>&amp;Generate</source>
<translation type="obsolete">生æˆ(&amp;G)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="249"/>
<source>Indicates whether the virtual network cable is plugged in on machine startup or not.</source>
<translation>仮想マシンã®èµ·å‹•時ã«ä»®æƒ³ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚±ãƒ¼ãƒ–ãƒ«ãŒæŽ¥ç¶šã•れるã‹ã©ã†ã‹ã‚’示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Ca&amp;ble Connected</source>
<translation type="obsolete">接続(&amp;B)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>&amp;Interface Name:</source>
<translation type="obsolete">インターフェースå(&amp;I):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Displays the TAP interface name.</source>
<translation type="obsolete">TAPインターフェースåを表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>&amp;Setup Application:</source>
<translation type="obsolete">設定アプリケーション(&amp;S):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Displays the command executed to set up the TAP interface.</source>
<translation type="obsolete">TAPインターフェース設定時ã«å®Ÿè¡Œã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã‚’表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Selects the setup application.</source>
<translation type="obsolete">è¨­å®šã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’é¸æŠžã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>&amp;Terminate Application:</source>
<translation type="obsolete">終了アプリケーション(&amp;T):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Displays the command executed to terminate the TAP interface.</source>
<translation type="obsolete">TAPインターフェース終了時ã«å®Ÿè¡Œã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã‚’表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Selects the terminate application.</source>
<translation type="obsolete">çµ‚äº†ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’é¸æŠžã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Host Interface Settings</source>
<translation type="obsolete">ホスト インターフェースã®è¨­å®š</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Adapter</source>
<comment>network</comment>
<translation type="obsolete">アダプタ</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Not selected</source>
<comment>adapter</comment>
<translation type="obsolete">æœªé¸æŠž</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Network</source>
<comment>internal</comment>
<translation type="obsolete">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Not selected</source>
<comment>network</comment>
<translation type="obsolete">æœªé¸æŠž</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>MAC Address</source>
<translation type="obsolete">MACアドレス</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Not selected</source>
<comment>address</comment>
<translation type="obsolete">æœªé¸æŠž</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Cable</source>
<translation type="obsolete">ケーブル</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Connected</source>
<comment>cable</comment>
<translation type="obsolete">接続</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="212"/>
<source>Not connected</source>
<comment>cable</comment>
<translation type="obsolete">未接続</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="146"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="140"/>
<source>Adapter &amp;Type:</source>
<translation>アダプタ タイプ(&amp;T):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="146"/>
<source>Open extended settings dialog for current attachment type.</source>
<translation type="obsolete">ç¾åœ¨ã®å‰²ã‚Šå½“ã¦ã‚¿ã‚¤ãƒ—ã®ãŸã‚ã®æ‹¡å¼µè¨­å®šãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‹ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="195"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="175"/>
<source>no bridged network adapter is selected</source>
<translation>ブリッジ ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ ã‚¢ãƒ€ãƒ—ã‚¿ãŒæœªé¸æŠž</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="202"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="184"/>
<source>no internal network name is specified</source>
<translation>内部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯åãŒæœªæŒ‡å®š</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="209"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="193"/>
<source>no host-only network adapter is selected</source>
<translation>ホストオンリー ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ ã‚¢ãƒ€ãƒ—ã‚¿ãŒæœªé¸æŠž</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="368"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="202"/>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="362"/>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="369"/>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="378"/>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="387"/>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="640"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="642"/>
<source>Not selected</source>
<comment>network adapter name</comment>
<translation>æœªé¸æŠž</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="368"/>
<source>Open additional options dialog for current attachment type.</source>
<translation type="obsolete">ç¾åœ¨ã®å‰²ã‚Šå½“ã¦ã‚¿ã‚¤ãƒ—ã®ãŸã‚ã®è¿½åŠ ã‚ªãƒ—ã‚·ãƒ§ãƒ³ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‹ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="90"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="87"/>
<source>&amp;Name:</source>
<translation>åå‰(&amp;N):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="109"/>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>&lt;b&gt;ブリッジ アダプタ&lt;/b&gt;ã¾ãŸã¯&lt;b&gt;ホストオンリー アダプタ&lt;/b&gt;を割り当ã¦ãŸå ´åˆã¯ä½¿ç”¨ã™ã‚‹ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタã®åå‰ã‚’é¸æŠžã—ã¾ã™ã€‚&lt;b&gt;内部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯&lt;/b&gt;を割り当ã¦ãŸå ´åˆã¯å†…部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã®åå‰ã‚’指定ã—ã¾ã™ã€‚</translation>
+ <translation type="obsolete">&lt;b&gt;ブリッジ アダプタ&lt;/b&gt;ã¾ãŸã¯&lt;b&gt;ホストオンリー アダプタ&lt;/b&gt;を割り当ã¦ãŸå ´åˆã¯ä½¿ç”¨ã™ã‚‹ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタã®åå‰ã‚’é¸æŠžã—ã¾ã™ã€‚&lt;b&gt;内部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯&lt;/b&gt;を割り当ã¦ãŸå ´åˆã¯å†…部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã®åå‰ã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="134"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="128"/>
<source>A&amp;dvanced</source>
<translation>高度(&amp;D)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="137"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="131"/>
<source>Shows or hides additional network adapter options.</source>
<translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタã®é«˜åº¦ãªã‚ªãƒ—ションã®è¡¨ç¤º/éžè¡¨ç¤ºã‚’切り替ãˆã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="172"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="166"/>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="185"/>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="192"/>
<source>&amp;Mac Address:</source>
<translation>MACアドレス(&amp;M):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="215"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="232"/>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="242"/>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="252"/>
<source>&amp;Cable connected</source>
<translation>ケーブル接続(&amp;C)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="222"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="259"/>
<source>Opens dialog to manage port forwarding rules.</source>
<translation>ãƒãƒ¼ãƒˆãƒ•ォワーディングã®ãƒ«ãƒ¼ãƒ«ã‚’設定ã™ã‚‹ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‹ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="262"/>
<source>&amp;Port Forwarding</source>
<translation>ãƒãƒ¼ãƒˆãƒ•ォワーディング</translation>
</message>
@@ -3771,112 +3758,90 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsNetworkDetails</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>no bridged network adapter is selected</source>
<translation type="obsolete">ブリッジ ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ ã‚¢ãƒ€ãƒ—ã‚¿ãŒæœªé¸æŠž</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>no internal network name is specified</source>
<translation type="obsolete">内部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯åãŒæœªæŒ‡å®š</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>no host-only adapter is selected</source>
<translation type="obsolete">ホストオンリー ã‚¢ãƒ€ãƒ—ã‚¿ãŒæœªé¸æŠž</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Basic Details</source>
<translation type="obsolete">詳細情報</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Bridged Network Details</source>
<translation type="obsolete">ブリッジ ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯è©³ç´°</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Internal Network Details</source>
<translation type="obsolete">内部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯è©³ç´°</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Host-only Network Details</source>
<translation type="obsolete">ホストオンリー ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯è©³ç´°</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Not selected</source>
<translation type="obsolete">æœªé¸æŠž</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Host Settings</source>
<translation type="obsolete">ホスト設定</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>&amp;Bridged Network Adapter:</source>
<translation type="obsolete">ブリッジ ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタ(&amp;B):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Displays the name of the host network adapter selected for bridged networking.</source>
<translation type="obsolete">ブリッジ ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ç”¨ã«é¸æŠžã—ãŸãƒ›ã‚¹ãƒˆ ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¢ãƒ€ãƒ—ã‚¿åを表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Internal &amp;Network:</source>
<translation type="obsolete">内部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯(&amp;N):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Displays the name of the internal network selected for this adapter.</source>
<translation type="obsolete">ã“ã®ã‚¢ãƒ€ãƒ—タ用ã«é¸æŠžã—ãŸå†…部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯åを表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Host-only &amp;Network Adapter:</source>
<translation type="obsolete">ホストオンリー ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¢ãƒ€ãƒ—ã‚¿(&amp;N):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Displays the name of the VirtualBox network adapter selected for host-only networking.</source>
<translation type="obsolete">ホストオンリー ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ç”¨ã«é¸æŠžã—ãŸVirtualBox ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¢ãƒ€ãƒ—ã‚¿åを表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Guest Settings</source>
<translation type="obsolete">ゲスト設定</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Guest &amp;MAC Address:</source>
<translation type="obsolete">ゲストMACアドレス:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Displays the MAC address of this adapter. It contains exactly 12 characters chosen from {0-9,A-F}. Note that the second character must be an even digit.</source>
<translation type="obsolete">ã“ã®ã‚¢ãƒ€ãƒ—ã‚¿ã®MACアドレスを表示ã—ã¾ã™ã€‚MACアドレスã¯{0-9,A-F}ã‹ã‚‰é¸æŠžã•れãŸ12æ–‡å­—ã§æ§‹æˆã•れã¾ã™ã€‚注:2ç•ªç›®ã®æ–‡å­—ã¯å¶æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Generates a new random MAC address.</source>
<translation type="obsolete">MACアドレスをランダムã«ç”Ÿæˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>&amp;Cable connected</source>
<translation type="obsolete">ケーブル接続(&amp;C)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Indicates whether the virtual network cable is plugged in on machine startup or not.</source>
<translation type="obsolete">仮想マシンã®èµ·å‹•時ã«ä»®æƒ³ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚±ãƒ¼ãƒ–ルを接続ã™ã‚‹ã‹ã©ã†ã‹ã‚’示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Additional Options</source>
<translation type="obsolete">追加オプション</translation>
</message>
@@ -3884,12 +3849,10 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsNetworkPage</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>No host network interface is selected</source>
<translation type="obsolete">ホスト インターフェースãŒé¸æŠžã•れã¦ã„ãªã„</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.ui" line="225"/>
<source>Internal network name is not set</source>
<translation type="obsolete">内部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯åãŒè¨­å®šã•れã¦ã„ãªã„</translation>
</message>
@@ -3897,7 +3860,7 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsParallel</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsParallel.cpp" line="110"/>
+ <location filename="../src/settings/machine/UIMachineSettingsParallel.cpp" line="136"/>
<source>Port %1</source>
<comment>parallel ports</comment>
<translation>ãƒãƒ¼ãƒˆ %1</translation>
@@ -3928,7 +3891,6 @@ p, li { white-space: pre-wrap; }
<translation>IRQ(&amp;I):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsParallel.ui" line="93"/>
<source>Displays the IRQ number of this parallel port. Valid values are integer numbers in range from &lt;tt&gt;0&lt;/tt&gt; to &lt;tt&gt;255&lt;/tt&gt;. Values greater than &lt;tt&gt;15&lt;/tt&gt; may only be used if the &lt;b&gt;IO APIC&lt;/b&gt; is enabled for this virtual machine.</source>
<translation type="obsolete">ã“ã®ãƒ‘ラレルãƒãƒ¼ãƒˆã®IRQ番å·ã‚’表示ã—ã¾ã™ã€‚有効値ã¯&lt;tt&gt;0&lt;/tt&gt;ã‹ã‚‰&lt;tt&gt;255&lt;/tt&gt;ã¾ã§ã®ç¯„å›²ã®æ•´æ•°ã§ã™ã€‚&lt;tt&gt;15&lt;/tt&gt;以上ã®å€¤ã¯ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã§&lt;b&gt;IO APIC&lt;/b&gt;ãŒæœ‰åйãªã¨ã使用ã•れã¾ã™ã€‚</translation>
</message>
@@ -3938,7 +3900,6 @@ p, li { white-space: pre-wrap; }
<translation>I/Oãƒãƒ¼ãƒˆ(&amp;R):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsParallel.ui" line="116"/>
<source>Displays the base I/O port address of this parallel port. This should be a whole number between &lt;tt&gt;0&lt;/tt&gt; and &lt;tt&gt;0xFFFF&lt;/tt&gt;.</source>
<translation type="obsolete">ã“ã®ãƒ‘ラレルãƒãƒ¼ãƒˆã®ãƒ™ãƒ¼ã‚¹I/Oãƒãƒ¼ãƒˆã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’表示ã—ã¾ã™ã€‚ 有効値ã¯&lt;tt&gt;0&lt;/tt&gt;ã‹ã‚‰&lt;tt&gt;0xFFFF&lt;/tt&gt;ã®ç¯„å›²ã®æ•´æ•°ã§ã™ã€‚</translation>
</message>
@@ -3966,17 +3927,17 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsParallelPage</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsParallel.cpp" line="295"/>
+ <location filename="../src/settings/machine/UIMachineSettingsParallel.cpp" line="351"/>
<source>Duplicate port number selected </source>
<translation>é¸æŠžã—ãŸãƒãƒ¼ãƒˆç•ªå·ã¯ã™ã§ã«ä½¿ç”¨ã•れã¦ã„ã‚‹</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsParallel.cpp" line="311"/>
+ <location filename="../src/settings/machine/UIMachineSettingsParallel.cpp" line="367"/>
<source>Port path not specified </source>
<translation>ãƒãƒ¼ãƒˆ ãƒ‘ã‚¹ãŒæŒ‡å®šã•れã¦ã„ãªã„</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsParallel.cpp" line="312"/>
+ <location filename="../src/settings/machine/UIMachineSettingsParallel.cpp" line="368"/>
<source>Duplicate port path entered </source>
<translation>指定ã—ãŸãƒãƒ¼ãƒˆ パスã¯ã™ã§ã«ä½¿ç”¨ã•れã¦ã„ã‚‹</translation>
</message>
@@ -4022,37 +3983,34 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsSF</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsPortForwardingDlg.cpp" line="676"/>
<source>&amp;Add New Shared Folder</source>
<translation type="obsolete">æ–°è¦å…±æœ‰ãƒ•ォルダを追加(&amp;A)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsPortForwardingDlg.cpp" line="676"/>
<source>&amp;Edit Selected Shared Folder</source>
<translation type="obsolete">é¸æŠžã—ãŸå…±æœ‰ãƒ•ォルダを編集(&amp;E)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsPortForwardingDlg.cpp" line="676"/>
<source>&amp;Remove Selected Shared Folder</source>
<translation type="obsolete">é¸æŠžã—ãŸå…±æœ‰ãƒ•ォルダを除去(&amp;R)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="459"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="416"/>
<source>Adds a new shared folder definition.</source>
<translation>æ–°è¦å…±æœ‰ãƒ•ォルダを追加ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="460"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="417"/>
<source>Edits the selected shared folder definition.</source>
<translation>é¸æŠžã—ãŸå…±æœ‰ãƒ•ォルダã®è¨­å®šã‚’編集ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="461"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="418"/>
<source>Removes the selected shared folder definition.</source>
<translation>é¸æŠžã—ãŸå…±æœ‰ãƒ•ォルダã®è¨­å®šã‚’除去ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="465"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="422"/>
<source>Yes</source>
<translation>ã¯ã„</translation>
</message>
@@ -4067,12 +4025,12 @@ p, li { white-space: pre-wrap; }
<translation>一時的ãªå…±æœ‰ãƒ•ォルダ</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="463"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="420"/>
<source>Full</source>
<translation>完全</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="464"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="421"/>
<source>Read-only</source>
<translation>読ã¿è¾¼ã¿å°‚用</translation>
</message>
@@ -4102,22 +4060,21 @@ p, li { white-space: pre-wrap; }
<translation>アクセス権</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSF.ui" line="84"/>
<source> Global Folders</source>
<translation type="obsolete">グローãƒãƒ«ãƒ•ォルダ</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="448"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="405"/>
<source>&amp;Add Shared Folder</source>
<translation>共有フォルダを追加(&amp;A)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="449"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="406"/>
<source>&amp;Edit Shared Folder</source>
<translation>共有フォルダを編集(&amp;E)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="450"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSF.cpp" line="407"/>
<source>&amp;Remove Shared Folder</source>
<translation>共有フォルダを除去(&amp;R)</translation>
</message>
@@ -4193,7 +4150,7 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsSerial</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="123"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="153"/>
<source>Port %1</source>
<comment>serial ports</comment>
<translation>ãƒãƒ¼ãƒˆ %1</translation>
@@ -4224,7 +4181,6 @@ p, li { white-space: pre-wrap; }
<translation>IRQ(&amp;I):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.ui" line="93"/>
<source>Displays the IRQ number of this serial port. Valid values are integer numbers in range from &lt;tt&gt;0&lt;/tt&gt; to &lt;tt&gt;255&lt;/tt&gt;. Values greater than &lt;tt&gt;15&lt;/tt&gt; may only be used if the &lt;b&gt;IO APIC&lt;/b&gt; is enabled for this virtual machine.</source>
<translation type="obsolete">ã“ã®ã‚·ãƒªã‚¢ãƒ«ãƒãƒ¼ãƒˆã®IRQ番å·ã‚’表示ã—ã¾ã™ã€‚有効値ã¯&lt;tt&gt;0&lt;/tt&gt;ã‹ã‚‰&lt;tt&gt;255&lt;/tt&gt;ã¾ã§ã®ç¯„å›²ã®æ•´æ•°ã§ã™ã€‚&lt;tt&gt;15&lt;/tt&gt;以上ã®å€¤ã¯ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã§&lt;b&gt;IO APIC&lt;/b&gt;ãŒæœ‰åйãªã¨ã使用ã•れã¾ã™ã€‚</translation>
</message>
@@ -4234,7 +4190,6 @@ p, li { white-space: pre-wrap; }
<translation>I/Oãƒãƒ¼ãƒˆ(&amp;R):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.ui" line="116"/>
<source>Displays the base I/O port address of this serial port. This should be a whole number between &lt;tt&gt;0&lt;/tt&gt; and &lt;tt&gt;0xFFFF&lt;/tt&gt;.</source>
<translation type="obsolete">ã“ã®ã‚·ãƒªã‚¢ãƒ«ãƒãƒ¼ãƒˆã®ãƒ™ãƒ¼ã‚¹I/Oãƒãƒ¼ãƒˆã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’表示ã—ã¾ã™ã€‚ 有効値ã¯&lt;tt&gt;0&lt;/tt&gt;ã‹ã‚‰&lt;tt&gt;0xFFFF&lt;/tt&gt;ã®ç¯„å›²ã®æ•´æ•°ã§ã™ã€‚</translation>
</message>
@@ -4259,7 +4214,6 @@ p, li { white-space: pre-wrap; }
<translation>パイプ作æˆ(&amp;C)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.ui" line="175"/>
<source>Port &amp;Path:</source>
<translation type="obsolete">ãƒãƒ¼ãƒˆ パス(&amp;P):</translation>
</message>
@@ -4287,17 +4241,17 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsSerialPage</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="350"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="395"/>
<source>Duplicate port number selected </source>
<translation>é¸æŠžã—ãŸãƒãƒ¼ãƒˆç•ªå·ã¯ã™ã§ã«ä½¿ç”¨ã•れã¦ã„ã‚‹</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="372"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="417"/>
<source>Port path not specified </source>
<translation>ãƒãƒ¼ãƒˆ ãƒ‘ã‚¹ãŒæŒ‡å®šã•れã¦ã„ãªã„</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="418"/>
<source>Duplicate port path entered </source>
<translation>指定ã—ãŸãƒãƒ¼ãƒˆ パスã¯ã™ã§ã«ä½¿ç”¨ã•れã¦ã„ã‚‹</translation>
</message>
@@ -4305,327 +4259,347 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsStorage</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;</source>
<translation type="obsolete"> &lt;i&gt;%1&lt;/i&gt;ã®ãŸã‚ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒé¸æŠžã•れã¦ã„ãªã„</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>&lt;i&gt;%1&lt;/i&gt; uses the hard disk that is already attached to &lt;i&gt;%2&lt;/i&gt;</source>
<translation type="obsolete">&lt;i&gt;%1&lt;/i&gt;ã¯ã™ã§ã«&lt;i&gt;%2&lt;/i&gt;ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã‚‹</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>&amp;Add Attachment</source>
<translation type="obsolete">割り当ã¦ã‚’追加ã™ã‚‹(&amp;A)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>&amp;Remove Attachment</source>
<translation type="obsolete">割り当ã¦ã‚’除去ã™ã‚‹(&amp;R)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>&amp;Select Hard Disk</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’é¸æŠžã™ã‚‹(&amp;S)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>Adds a new hard disk attachment.</source>
<translation type="obsolete">æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®å‰²ã‚Šå½“ã¦ã‚’追加ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>Removes the highlighted hard disk attachment.</source>
<translation type="obsolete">ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®å‰²ã‚Šå½“ã¦ã‚’除去ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>Invokes the Virtual Disk Manager to select a hard disk to attach to the currently highlighted slot.</source>
<translation type="obsolete">仮想ディスクマãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•ã—ã€ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’ç¾åœ¨ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸã‚¹ãƒ­ãƒƒãƒˆã«å‰²ã‚Šå½“ã¦ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>When checked, enables the virtual SATA controller of this machine. Note that you cannot attach hard disks to SATA ports when the virtual SATA controller is disabled.</source>
<translation type="obsolete">仮想SATA コントローラを有効ã«ã—ã¾ã™ã€‚注:仮想SATA コントローラãŒç„¡åйãªå ´åˆã€SATAãƒãƒ¼ãƒˆã«ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’割り当ã¦ã§ãã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>&amp;Enable SATA Controller</source>
<translation type="obsolete">SATA コントローラを有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>&amp;Attachments</source>
<translation type="obsolete">割り当ã¦(&amp;A)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>Lists all hard disks attached to this machine. Use a mouse click or the &lt;tt&gt;Space&lt;/tt&gt; key on the highlighted item to activate the drop-down list and choose the desired value. Use the context menu or buttons to the right to add or remove hard disk attachments.</source>
<translation type="obsolete">ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸã™ã¹ã¦ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’リスト表示ã—ã¾ã™ã€‚ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸé …目をマウスクリックã™ã‚‹ã‹ã€&lt;tt&gt;[スペース]&lt;/tt&gt;キーを使用ã—ã¦ã€ãƒ‰ãƒ­ãƒƒãƒ—ダウンリストã‹ã‚‰ä½¿ç”¨ã™ã‚‹ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’é¸æŠžã—ã¦ãã ã•ã„。コンテキストメニューã‹å³ã®ãƒœã‚¿ãƒ³ã‚’使ã£ã¦ã€ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®å‰²ã‚Šå½“ã¦ã®è¿½åŠ ã¾ãŸã¯é™¤åŽ»ãŒè¡Œãˆã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>Invokes the Virtual Media Manager to select a hard disk to attach to the currently highlighted slot.</source>
<translation type="obsolete">仮想メディアマãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•ã—ã€ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’ç¾åœ¨ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸã‚¹ãƒ­ãƒƒãƒˆã«å‰²ã‚Šå½“ã¦ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>If checked, shows the differencing hard disks that are attached to slots rather than their base hard disks (shown for indirect attachments) and allows explicit attaching of differencing hard disks. Check this only if you need a complex hard disk setup.</source>
<translation type="obsolete">実際ã®ãƒ™ãƒ¼ã‚¹ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ä»£ã‚りã«ã‚¹ãƒ­ãƒƒãƒˆã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸå·®åˆ†ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’表示ã—ã¾ã™(間接的ãªå‰²ã‚Šå½“ã¦æ™‚)。 高度ãªãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯è¨­å®šãŒå¿…è¦ãªå ´åˆã®ã¿ã€ã‚ªãƒ³ã«ã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>&amp;Show Differencing Hard Disks</source>
<translation type="obsolete">差分ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’表示(&amp;S)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>When checked, enables an additional virtual controller (either SATA or SCSI) of this machine.</source>
<translation type="obsolete">ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®è¿½åŠ ã®ä»®æƒ³ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©(SATAã¾ãŸã¯SCSI)を有効ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>&amp;Enable Additional Controller</source>
<translation type="obsolete">追加ã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã‚’有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>IDE &amp;Controller Type</source>
<translation type="obsolete">IDE コントローラ タイプ(&amp;C)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSerial.cpp" line="373"/>
<source>Defines the type of the virtual IDE controller. Depending on this value, VirtualBox will provide different virtual IDE hardware devices to the guest OS.</source>
<translation type="obsolete">仮想IDE コントローラã®ã‚¿ã‚¤ãƒ—を定義ã—ã¾ã™ã€‚ã“ã®å€¤ã«ã‚ˆã‚Šã€VirtualBoxã¯ç•°ãªã£ãŸä»®æƒ³IDEãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ デãƒã‚¤ã‚¹ã‚’ゲストOSã«æä¾›ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="524"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="543"/>
<source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Bus:&amp;nbsp;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Type:&amp;nbsp;&amp;nbsp;%3&lt;/nobr&gt;</source>
<translation>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;ãƒã‚¹:&amp;nbsp;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;タイプ:&amp;nbsp;&amp;nbsp;%3&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="683"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="730"/>
<source>Host Drive</source>
<translation>ホスト ドライブ</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="683"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="730"/>
<source>Image</source>
<translation>イメージ</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="849"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="897"/>
<source>&lt;nobr&gt;Expand/Collapse&amp;nbsp;Item&lt;/nobr&gt;</source>
<translation>&lt;nobr&gt;項目を展開ã™ã‚‹/折り畳む&amp;nbsp;&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="852"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="900"/>
<source>&lt;nobr&gt;Add&amp;nbsp;Hard&amp;nbsp;Disk&lt;/nobr&gt;</source>
<translation>&lt;nobr&gt;ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯&amp;nbsp;ã®è¿½åŠ &lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="855"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="903"/>
<source>&lt;nobr&gt;Add&amp;nbsp;CD/DVD&amp;nbsp;Device&lt;/nobr&gt;</source>
<translation>&lt;nobr&gt;CD/DVD&amp;nbsp;デãƒã‚¤ã‚¹&amp;nbsp;ã®è¿½åŠ &lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="858"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="906"/>
<source>&lt;nobr&gt;Add&amp;nbsp;Floppy&amp;nbsp;Device&lt;/nobr&gt;</source>
<translation>&lt;nobr&gt;フロッピー&amp;nbsp;デãƒã‚¤ã‚¹&amp;nbsp;ã®è¿½åŠ &lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="1973"/>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation> &lt;i&gt;%1&lt;/i&gt;ã®ãŸã‚ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒé¸æŠžã•れã¦ã„ã¾ã›ã‚“。</translation>
+ <translation type="obsolete"> &lt;i&gt;%1&lt;/i&gt;ã®ãŸã‚ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒé¸æŠžã•れã¦ã„ã¾ã›ã‚“。</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2104"/>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="1979"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2110"/>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2127"/>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2133"/>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
<translation>&lt;i&gt;%1&lt;/i&gt;ãŒä½¿ç”¨ã™ã‚‹ãƒ¡ãƒ‡ã‚£ã‚¢ã¯ã™ã§ã«&lt;i&gt;%2&lt;/i&gt;ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="1999"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2152"/>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">1個ã ã‘サãƒãƒ¼ãƒˆ</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2153"/>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">%1個ã¾ã§ã‚µãƒãƒ¼ãƒˆ</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2159"/>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">%1ãƒãƒƒãƒ—セットãŒã‚µãƒãƒ¼ãƒˆã™ã‚‹ã‚ˆã‚Šå¤šãã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã‚’指定ã—ã¦ã„ã¾ã™ã€‚ システムページã§ãƒãƒƒãƒ—セットã®ç¨®é¡žã‚’変更ã™ã‚‹ã‹ã€ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒšãƒ¼ã‚¸ã§æ¬¡ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã®æ•°ã‚’減らã—ã¦ãã ã•ã„: %2。</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2180"/>
<source>Add Controller</source>
<translation>コントローラを追加</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2000"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2181"/>
<source>Add IDE Controller</source>
<translation>IDE コントローラを追加</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2001"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2182"/>
<source>Add SATA Controller</source>
<translation>SATA コントローラを追加</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2002"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2183"/>
<source>Add SCSI Controller</source>
<translation>SCSI コントローラを追加</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2003"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2184"/>
<source>Add SAS Controller</source>
<translation>SAS コントローラを追加</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2004"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2185"/>
<source>Add Floppy Controller</source>
<translation>フロッピー コントローラを追加</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2005"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2186"/>
<source>Remove Controller</source>
<translation>コントローラを除去</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2006"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2187"/>
<source>Add Attachment</source>
<translation>割り当ã¦ã®è¿½åŠ </translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2007"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2188"/>
<source>Add Hard Disk</source>
<translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’追加</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2008"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2189"/>
<source>Add CD/DVD Device</source>
<translation>CD/DVD デãƒã‚¤ã‚¹ã‚’追加</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2009"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2190"/>
<source>Add Floppy Device</source>
<translation>フロッピー デãƒã‚¤ã‚¹ã‚’追加</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2010"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2191"/>
<source>Remove Attachment</source>
<translation>割り当ã¦ã‚’除去</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2012"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2193"/>
<source>Adds a new controller to the end of the Storage Tree.</source>
<translation>æ–°ã—ã„コントローラをストレージ ãƒ„ãƒªãƒ¼ã®æœ€å¾Œã«è¿½åŠ ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2013"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2194"/>
<source>Removes the controller highlighted in the Storage Tree.</source>
<translation>ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ ツリーã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã‚’除去ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2014"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2195"/>
<source>Adds a new attachment to the Storage Tree using currently selected controller as parent.</source>
<translation>ç¾åœ¨é¸æŠžã•れã¦ã„るコントローラを親ã¨ã—ã¦æ–°ãŸãªå‰²ã‚Šå½“ã¦ã‚’ストレージ ツリーã«è¿½åŠ ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2016"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2197"/>
<source>Removes the attachment highlighted in the Storage Tree.</source>
<translation>ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ ツリーã®å‰²ã‚Šå½“ã¦ã‚’除去ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="912"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2293"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="906"/>
<source>IDE Controller</source>
<translation>IDE コントローラ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="920"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2298"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="914"/>
<source>SATA Controller</source>
<translation>SATA コントローラ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="928"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2303"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="922"/>
<source>SCSI Controller</source>
<translation>SCSI コントローラ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="936"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2308"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="930"/>
<source>Floppy Controller</source>
<translation>フロッピー コントローラ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="944"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2313"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="938"/>
<source>SAS Controller</source>
<translation>SAS コントローラ</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2276"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2463"/>
<source>Hard &amp;Disk:</source>
<translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯(&amp;D):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2278"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2465"/>
<source>Choose or create a virtual hard disk file. The virtual machine will see the data in the file as the contents of the virtual hard disk.</source>
<translation>仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã¾ãŸã¯ä½œæˆã—ã¾ã™ã€‚仮想マシンã¯ãƒ•ァイルã®ãƒ‡ãƒ¼ã‚¿ã‚’仮想的ãªãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®å†…容ã¨è¦‹ãªã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2280"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2467"/>
<source>Set up the virtual hard disk</source>
<translation>仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®è¨­å®š</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2283"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2470"/>
<source>CD/DVD &amp;Drive:</source>
<translation>CD/DVDドライブ(&amp;D):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2285"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2472"/>
<source>Choose a virtual CD/DVD disk or a physical drive to use with the virtual drive. The virtual machine will see a disk inserted into the drive with the data in the file or on the disk in the physical drive as its contents.</source>
<translation>仮想CD/DVDãƒ‡ã‚£ã‚¹ã‚¯ã‚’é¸æŠžã™ã‚‹ã‹ã€ç‰©ç†ãƒ‰ãƒ©ã‚¤ãƒ–を仮想ドライブã«å‰²ã‚Šå½“ã¦ã¾ã™ã€‚仮想マシンã¯ãƒ•ァイルã®ãƒ‡ãƒ¼ã‚¿ã¾ãŸã¯ç‰©ç†çš„ãªãƒ‰ãƒ©ã‚¤ãƒ–ã®å†…容ãŒä»®æƒ³ãƒ‰ãƒ©ã‚¤ãƒ–ã«æŒ¿å…¥ã•れã¦ã„ã‚‹ã¨è¦‹ãªã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2288"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2475"/>
<source>Set up the virtual CD/DVD drive</source>
<translation>仮想CD/DVDドライブã®è¨­å®š</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2291"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2478"/>
<source>Floppy &amp;Drive:</source>
<translation>フロッピー ドライブ(&amp;D):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2293"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2480"/>
<source>Choose a virtual floppy disk or a physical drive to use with the virtual drive. The virtual machine will see a disk inserted into the drive with the data in the file or on the disk in the physical drive as its contents.</source>
<translation>ä»®æƒ³ãƒ•ãƒ­ãƒƒãƒ”ãƒ¼ãƒ‡ã‚£ã‚¹ã‚¯ã‚’é¸æŠžã™ã‚‹ã‹ã€ç‰©ç†ãƒ‰ãƒ©ã‚¤ãƒ–を仮想ドライブã«å‰²ã‚Šå½“ã¦ã¾ã™ã€‚仮想マシンã¯ãƒ•ァイルã®ãƒ‡ãƒ¼ã‚¿ã¾ãŸã¯ç‰©ç†çš„ãªãƒ‰ãƒ©ã‚¤ãƒ–ã®å†…容ãŒä»®æƒ³ãƒ‰ãƒ©ã‚¤ãƒ–ã«æŒ¿å…¥ã•れã¦ã„ã‚‹ã¨è¦‹ãªã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2296"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2483"/>
<source>Set up the virtual floppy drive</source>
<translation>仮想フロッピードライブã®è¨­å®š</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2401"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2610"/>
<source>Create a new hard disk...</source>
<translation>æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ä½œæˆ...</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2406"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2615"/>
<source>Choose a virtual hard disk file...</source>
<translation>仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãƒ•ァイルã®é¸æŠž...</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1256"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2623"/>
+ <location filename="../src/runtime/UIMachineLogic.cpp" line="1140"/>
<source>Choose a virtual CD/DVD disk file...</source>
<translation>仮想CD/DVDディスクファイルã®é¸æŠž...</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1263"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2630"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2647"/>
+ <location filename="../src/runtime/UIMachineLogic.cpp" line="1141"/>
+ <location filename="../src/runtime/UIMachineLogic.cpp" line="1147"/>
<source>Remove disk from virtual drive</source>
<translation>仮想ドライブã‹ã‚‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’除去</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1262"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2640"/>
+ <location filename="../src/runtime/UIMachineLogic.cpp" line="1146"/>
<source>Choose a virtual floppy disk file...</source>
<translation>仮想フロッピーディスクファイルã®é¸æŠž...</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1262"/>
<source>&amp;CD/DVD Device:</source>
<translation type="obsolete">CD/DVD デãƒã‚¤ã‚¹(&amp;C):</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="1262"/>
<source>&amp;Floppy Device:</source>
<translation type="obsolete">フロッピー デãƒã‚¤ã‚¹(&amp;F):</translation>
</message>
@@ -4640,7 +4614,8 @@ p, li { white-space: pre-wrap; }
<translation>ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®ã™ã¹ã¦ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ コントローラã¨ä»®æƒ³ã‚¤ãƒ¡ãƒ¼ã‚¸ã€å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸãƒ›ã‚¹ãƒˆ デãƒã‚¤ã‚¹ã‚’å«ã¿ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="328"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="115"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="386"/>
<source>Information</source>
<translation>情報</translation>
</message>
@@ -4650,7 +4625,8 @@ p, li { white-space: pre-wrap; }
<translation>ストレージ ツリーã¯ç•°ãªã£ãŸç¨®é¡žã®è¤‡æ•°ã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã‚’å«ã‚€ã“ã¨ãŒã§ãã¾ã™ã€‚ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã«ã¯ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ãŒã‚りã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="253"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="161"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="279"/>
<source>Attributes</source>
<translation>属性</translation>
</message>
@@ -4676,96 +4652,124 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="214"/>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="227"/>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="240"/>
<source>Allows to use host I/O caching capabilities.</source>
<translation>ホストã®I/O キャッシュ機能を使用ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="217"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="243"/>
<source>Use host I/O cache</source>
<translation>ホストã®I/O キャッシュを使ã†</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="217"/>
<source>S&amp;lot:</source>
<translation type="obsolete">スロット(&amp;L):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="287"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="313"/>
<source>Selects the slot on the storage controller used by this attachment. The available slots depend on the type of the controller and other attachments on it.</source>
<translation>ã“ã®å‰²ã‚Šå½“ã¦ã§ä½¿ç”¨ã™ã‚‹ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ コントローラã®ã‚¹ãƒ­ãƒƒãƒˆã‚’é¸æŠžã—ã¾ã™ã€‚利用ã§ãるスロットã¯ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã®ã‚¿ã‚¤ãƒ—ã¨ã€ãれを利用ã™ã‚‹ä»–ã®å‰²ã‚Šå½“ã¦ã«ä¾å­˜ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="287"/>
<source>Selects the virtual disk image or the host drive used by this attachment.</source>
<translation type="obsolete">ã“ã®å‰²ã‚Šå½“ã¦ã§ä½¿ç”¨ã™ã‚‹ä»®æƒ³ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã¾ãŸã¯ãƒ›ã‚¹ãƒˆ デãƒã‚¤ã‚¹ã‚’é¸æŠžã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="287"/>
<source>Opens the Virtual Media Manager to select a virtual image for this attachment.</source>
<translation type="obsolete">é¸æŠžã—ãŸã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ァイルを割り当ã¦ã‚‹ãŸã‚ã€ä»®æƒ³ãƒ¡ãƒ‡ã‚£ã‚¢ãƒžãƒãƒ¼ã‚¸ãƒ£ã‚’é–‹ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="287"/>
<source>Open Virtual Media Manager</source>
<translation type="obsolete">仮想メディアマãƒãƒ¼ã‚¸ãƒ£ã‚’é–‹ã</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="287"/>
<source>D&amp;ifferencing Disks</source>
<translation type="obsolete">差分ディスク(&amp;I)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="318"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="344"/>
<source>When checked, allows the guest to send ATAPI commands directly to the host-drive which makes it possible to use CD/DVD writers connected to the host inside the VM. Note that writing audio CD inside the VM is not yet supported.</source>
<translation>仮想マシン内ã§ãƒ›ã‚¹ãƒˆã«æŽ¥ç¶šã•れãŸCD/DVDライターを使用å¯èƒ½ã«ã™ã‚‹ãŸã‚ã€ATAPIコマンドを直接ホスト デãƒã‚¤ã‚¹ã«é€ä¿¡ã—ã¾ã™ã€‚ 注:仮想マシン内ã§ã‚ªãƒ¼ãƒ‡ã‚£ã‚ªCDã®æ›¸ãè¾¼ã¿ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="321"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="347"/>
<source>&amp;Passthrough</source>
<translation>パススルー(&amp;P)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="355"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="360"/>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="363"/>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="376"/>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="379"/>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="413"/>
<source>Type:</source>
<translation>タイプ:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="375"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="433"/>
<source>Virtual Size:</source>
<translation>仮想的ãªã‚µã‚¤ã‚º:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="395"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="453"/>
<source>Actual Size:</source>
<translation>実際ã®ã‚µã‚¤ã‚º:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="415"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="473"/>
<source>Size:</source>
<translation>サイズ:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="435"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="493"/>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="513"/>
<source>Location:</source>
<translation>場所:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="335"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="393"/>
<source>Type (Format):</source>
<translation>タイプ(å½¢å¼):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="455"/>
+ <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="533"/>
<source>Attached To:</source>
<translation>割り当ã¦:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="455"/>
<source>Storage Controller</source>
<translation type="obsolete">ストレージ コントローラ</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsStorage.ui" line="455"/>
<source>Storage Controller 1</source>
<translation type="obsolete">ストレージ コントローラ 1</translation>
</message>
@@ -4773,53 +4777,75 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsSystem</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="331"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="392"/>
<source>you have assigned more than &lt;b&gt;%1%&lt;/b&gt; of your computer&apos;s memory (&lt;b&gt;%2&lt;/b&gt;) to the virtual machine. Not enough memory is left for your host operating system. Please select a smaller amount.</source>
<translation>実メモリ(&lt;b&gt;%2&lt;/b)ã®&lt;b&gt;%1ï¼…&lt;/b&gt;ã‚’è¶…ãˆã‚‹ãƒ¡ãƒ¢ãƒªãŒä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚ ホストOSãŒå分ãªãƒ¡ãƒ¢ãƒªã‚’使用ã§ãã¾ã›ã‚“。割り当ã¦ãƒ¡ãƒ¢ãƒªã‚’減らã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="341"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="402"/>
<source>you have assigned more than &lt;b&gt;%1%&lt;/b&gt; of your computer&apos;s memory (&lt;b&gt;%2&lt;/b&gt;) to the virtual machine. There might not be enough memory left for your host operating system. Continue at your own risk.</source>
<translation>実メモリ(&lt;b&gt;%2&lt;/b)ã®&lt;b&gt;%1ï¼…&lt;/b&gt;ã‚’è¶…ãˆã‚‹ãƒ¡ãƒ¢ãƒªãŒä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚ ホストOSã«å分ãªãƒ¡ãƒ¢ãƒªãŒæ®‹ã•れã¦ã„ã¾ã›ã‚“。自己ã®è²¬ä»»ã§ç¶šè¡Œã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="354"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="415"/>
<source>for performance reasons, the number of virtual CPUs attached to the virtual machine may not be more than twice the number of physical CPUs on the host (&lt;b&gt;%1&lt;/b&gt;). Please reduce the number of virtual CPUs.</source>
<translation>性能上ã®ç†ç”±ã‹ã‚‰ã€ä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‹CPUæ•°ã¯ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã®ç‰©ç†CPUæ•°(&lt;b&gt;%1&lt;/b&gt;)ã®2å€ã‚’è¶…ãˆã¦ã¯ãªã‚Šã¾ã›ã‚“。仮想CPUã®æ•°ã‚’減らã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="363"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="424"/>
<source>you have assigned more virtual CPUs to the virtual machine than the number of physical CPUs on your host system (&lt;b&gt;%1&lt;/b&gt;). This is likely to degrade the performance of your virtual machine. Please consider reducing the number of virtual CPUs.</source>
<translation>ホストマシンã®ç‰©ç†CPUæ•° (&lt;b&gt;%1&lt;/b&gt;)より多ã„CPUãŒä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚ã“れã¯ä»®æƒ³ãƒžã‚·ãƒ³ã®æ€§èƒ½ã‚’低下ã•ã›ã¾ã™ã€‚仮想CPUã®æ•°ã‚’減らã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="375"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="436"/>
<source>you have assigned more than one virtual CPU to this VM. This will not work unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>2個以上ã®CPUãŒä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚IO APICãŒç„¡åйãªå ´åˆã€ã“れã¯å‹•作ã—ã¾ã›ã‚“。[OK]ボタンを押ã™ã¨è‡ªå‹•çš„ã«IO APICãŒæœ‰åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="386"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="447"/>
<source>you have assigned more than one virtual CPU to this VM. This will not work unless hardware virtualization (VT-x/AMD-V) is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>2個以上ã®CPUãŒä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½(VT-x/AMD-V)ãŒç„¡åйãªå ´åˆã€ã“れã¯å‹•作ã—ã¾ã›ã‚“。[OK]ボタンを押ã™ã¨è‡ªå‹•çš„ã«ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½ãŒæœ‰åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="397"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="458"/>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="466"/>
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>ICH9ãƒãƒƒãƒ—セットãŒé¸æŠžã•れã¾ã—ãŸã€‚ IO-APICãŒç„¡åйãªå ´åˆã€ã“れã¯å‹•作ã—ã¾ã›ã‚“。[OK]ボタンを押ã™ã¨è‡ªå‹•çš„ã«IO-APICãŒæœ‰åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="444"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="477"/>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished">USB HID(Human Interface Device)を有効化ã—ã¾ã—ãŸã€‚ ã“れã¯ã€USBエミュレーションを有効化ã—ãªã„ã¨å‹•作ã—ã¾ã›ã‚“。USBエミュレーションã¯&lt;b&gt;[OK]&lt;/b&gt;ボタンを押ã™ã¨è‡ªå‹•çš„ã«æœ‰åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="525"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="526"/>
<source>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</source>
<translation>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="447"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="529"/>
<source>&lt;qt&gt;%1&amp;nbsp;CPU&lt;/qt&gt;</source>
<comment>%1 is 1 for now</comment>
<translation>&lt;qt&gt;%1&amp;nbsp;CPU&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="447"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="533"/>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="534"/>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;qt&gt;%1&amp;nbsp;CPUs&lt;/qt&gt;</source>
<comment>%1 is 32 for now</comment>
<translation type="obsolete">&lt;qt&gt;%1&amp;nbsp;CPUs&lt;/qt&gt;</translation>
@@ -4835,6 +4861,7 @@ p, li { white-space: pre-wrap; }
<translation>メインメモリ(&amp;M):</translation>
</message>
<message>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="64"/>
<location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="130"/>
<source>Controls the amount of memory provided to the virtual machine. If you assign too much, the machine might not start.</source>
<translation>仮想マシンã«å‰²ã‚Šå½“ã¦ã‚‹ãƒ¡ã‚¤ãƒ³ãƒ¡ãƒ¢ãƒªã®ã‚µã‚¤ã‚ºã‚’指定ã—ã¾ã™ã€‚割り当ã¦é‡ãŒå¤šã™ãŽã‚‹ã¨ä»®æƒ³ãƒžã‚·ãƒ³ã¯èµ·å‹•ã—ãªã„ã‹ã‚‚ã—れã¾ã›ã‚“。</translation>
@@ -4885,11 +4912,23 @@ p, li { white-space: pre-wrap; }
<translation>絶対座標指定ã®ãƒ‡ãƒã‚¤ã‚¹ã‚’有効化(&amp;A)</translation>
</message>
<message>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="463"/>
<location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="536"/>
<source>Controls the number of virtual CPUs in the virtual machine. You need hardware virtualization support on your host system to use more than one virtual CPU.</source>
<translation>仮想マシンã«å‰²ã‚Šå½“ã¦ã‚‹CPUã®æ•°ã‚’指定ã—ã¾ã™ã€‚複数ã®ä»®æƒ³CPUを使用ã™ã‚‹ã«ã¯ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã®ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½ãŒå¿…è¦ã§ã™ã€‚</translation>
</message>
<message>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="549"/>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="567"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="640"/>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="214"/>
<source>Move Up (Ctrl-Up)</source>
<translation>上ã«ç§»å‹•(Ctrl-Up)</translation>
@@ -4900,17 +4939,16 @@ p, li { white-space: pre-wrap; }
<translation>é¸æŠžã—ãŸèµ·å‹•デãƒã‚¤ã‚¹ã‚’上ã«ç§»å‹•ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="543"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="345"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="647"/>
<source>Extended Features:</source>
<translation>拡張機能:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="543"/>
<source>When checked, the virtual machine will support the Advanced Configuration and Power Management Interface (ACPI). &lt;b&gt;Note:&lt;/b&gt; don&apos;t disable this feature after having installed a Windows guest operating system!</source>
<translation type="obsolete">仮想マシンã§ACPI(Advanced Configuration and Power Management Interface)サãƒãƒ¼ãƒˆã‚’有効ã«ã—ã¾ã™ã€‚&lt;b&gt;注:&lt;/b&gt; Windows ゲストOSをインストールã—ãŸå¾Œã§æœ¬æ©Ÿèƒ½ã‚’無効ã«ã—ãªã„ã§ãã ã•ã„ï¼</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="543"/>
<source>Enable &amp;ACPI</source>
<translation type="obsolete">ACPIを有効化(&amp;A)</translation>
</message>
@@ -4945,52 +4983,51 @@ p, li { white-space: pre-wrap; }
<translation>プロセッサ数(&amp;P):</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="445"/>
<source>Controls the number of virtual CPUs in the virtual machine.</source>
<translation type="obsolete">仮想マシンã«å‰²ã‚Šå½“ã¦ã‚‹CPUã®æ•°ã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="559"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="663"/>
<source>When checked, the Physical Address Extension (PAE) feature of the host CPU will be exposed to the virtual machine.</source>
<translation>仮想マシンã§ãƒ›ã‚¹ãƒˆCPUã®PAE(物ç†ã‚¢ãƒ‰ãƒ¬ã‚¹æ‹¡å¼µæ©Ÿèƒ½)を有効ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="562"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="666"/>
<source>Enable PA&amp;E/NX</source>
<translation>PAE/NXを有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="583"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="687"/>
<source>Acce&amp;leration</source>
<translation>アクセラレーション(&amp;L)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="589"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="693"/>
<source>Hardware Virtualization:</source>
<translation>ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½:</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="602"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="706"/>
<source>When checked, the virtual machine will try to make use of the host CPU&apos;s hardware virtualization extensions such as Intel VT-x and AMD-V.</source>
<translation>仮想マシンã§ãƒ›ã‚¹ãƒˆCPUã®ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½(Intel VT-xã¾ãŸã¯AMD-V)を有効ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="605"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="709"/>
<source>Enable &amp;VT-x/AMD-V</source>
<translation>VT-x/AMD-Vを有効化(&amp;V)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="621"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="725"/>
<source>When checked, the virtual machine will try to make use of the nested paging extension of Intel VT-x and AMD-V.</source>
<translation>仮想マシンã§ãƒ›ã‚¹ãƒˆCPUã®ãƒã‚¹ãƒ†ãƒƒãƒ‰ãƒšãƒ¼ã‚¸ãƒ³ã‚°(Intel VT-x/EPTã¾ãŸã¯AMD-V/RVI)を有効ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="624"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.ui" line="728"/>
<source>Enable Nested Pa&amp;ging</source>
<translation>ãƒã‚¹ãƒ†ãƒƒãƒ‰ãƒšãƒ¼ã‚¸ãƒ³ã‚°ã‚’有効化(&amp;G)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="448"/>
+ <location filename="../src/settings/machine/UIMachineSettingsSystem.cpp" line="530"/>
<source>&lt;qt&gt;%1&amp;nbsp;CPUs&lt;/qt&gt;</source>
<comment>%1 is host cpu count * 2 for now</comment>
<translation>&lt;qt&gt;%1&amp;nbsp;CPUs&lt;/qt&gt;</translation>
@@ -5009,120 +5046,124 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineSettingsUSB</name>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="394"/>
<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>ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã§USB 2.0を有効化ã™ã‚‹ã«ã¯&lt;b&gt;%1&lt;/b&gt;ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚VirtualBoxã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã‚µã‚¤ãƒˆã‹ã‚‰æ©Ÿèƒ½æ‹¡å¼µãƒ‘ッケージをダウンロードã—ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。機能拡張パッケージをインストールã™ã‚‹ã¨ã€USB 2.0を有効化ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ç¾åœ¨ã®è¨­å®šã‚’キャンセルã—ãªã„å ´åˆã€USB 2.0ã¯ç„¡åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
+ <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="418"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="473"/>
+ <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="497"/>
<source>&amp;Add Empty Filter</source>
<translation>空ã®ãƒ•ィルタを追加(&amp;A)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="419"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="498"/>
<source>A&amp;dd Filter From Device</source>
<translation>デãƒã‚¤ã‚¹ã‹ã‚‰ãƒ•ィルタを追加ã™ã‚‹(&amp;D)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="420"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="499"/>
<source>&amp;Edit Filter</source>
<translation>フィルタを編集ã™ã‚‹(&amp;E)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="421"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="500"/>
<source>&amp;Remove Filter</source>
<translation>フィルタを除去ã™ã‚‹(&amp;R)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="422"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="501"/>
<source>&amp;Move Filter Up</source>
<translation>フィルタを上ã«ç§»å‹•ã™ã‚‹(&amp;M)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="423"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="502"/>
<source>M&amp;ove Filter Down</source>
<translation>フィルタを下ã«ç§»å‹•(&amp;O)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="438"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="517"/>
<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="442"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="521"/>
<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="445"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="524"/>
<source>Edits the selected USB filter.</source>
<translation>é¸æŠžã—ãŸUSBフィルタを編集ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="446"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="525"/>
<source>Removes the selected USB filter.</source>
<translation>é¸æŠžã—ãŸUSBフィルタを除去ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="447"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="526"/>
<source>Moves the selected USB filter up.</source>
<translation>é¸æŠžã—ãŸUSBフィルタを上ã«ç§»å‹•ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="448"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="527"/>
<source>Moves the selected USB filter down.</source>
<translation>é¸æŠžã—ãŸUSBフィルタを下ã«ç§»å‹•ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="450"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="529"/>
<source>New Filter %1</source>
<comment>usb</comment>
<translation>æ–°è¦ãƒ•ィルタ %1</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="796"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="884"/>
<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="800"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="888"/>
<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="804"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="892"/>
<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="808"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="896"/>
<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="812"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="900"/>
<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="816"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="904"/>
<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="820"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="908"/>
<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="825"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="913"/>
<source>&lt;nobr&gt;State: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
<translation>&lt;nobr&gt;状態: %1&lt;/nobr&gt;</translation>
@@ -5292,12 +5333,30 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineWindowNormal</name>
<message>
- <location filename="../src/runtime/normal/UIMachineWindowNormal.cpp" line="273"/>
+ <location filename="../src/runtime/normal/UIMachineWindowNormal.cpp" line="296"/>
<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>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <location filename="../src/UIMediumTypeChangeDialog.cpp" line="111"/>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/UIMediumTypeChangeDialog.cpp" line="114"/>
+ <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 type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/UIMediumTypeChangeDialog.cpp" line="122"/>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<location filename="../src/widgets/UIDownloaderAdditions.h" line="46"/>
@@ -5341,25 +5400,24 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMultiScreenLayout</name>
<message>
- <location filename="../src/runtime/UIMultiScreenLayout.cpp" line="58"/>
+ <location filename="../src/runtime/UIMultiScreenLayout.cpp" line="65"/>
<source>Virtual Screen %1</source>
<translation>仮想スクリーン %1</translation>
</message>
<message>
- <location filename="../src/runtime/UIMultiScreenLayout.cpp" line="65"/>
+ <location filename="../src/runtime/UIMultiScreenLayout.cpp" line="72"/>
<source>Use Host Screen %1</source>
<translation>ホスト スクリーン %1 を使ã†</translation>
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="235"/>
<source>Create New Virtual Disk</source>
<translation>æ–°è¦ä»®æƒ³ãƒ‡ã‚£ã‚¹ã‚¯ã®ä½œæˆ</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk image for your virtual machine.&lt;/p&gt;
&lt;p&gt;Use the &lt;b&gt;Next&lt;/b&gt; button to go to the next page of the wizard
and the &lt;b&gt;Back&lt;/b&gt; button to return to the previous page.&lt;/p&gt;</source>
@@ -5367,102 +5425,85 @@ and the &lt;b&gt;Back&lt;/b&gt; button to return to the previous page.&lt;/p&gt;
&lt;p&gt;ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã®æ¬¡ã®ãƒšãƒ¼ã‚¸ã«é€²ã‚€ã«ã¯&lt;b&gt;[次ã¸]&lt;/b&gt;ボタンをã€å‰ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã‚‹ã«ã¯&lt;b&gt;[戻る]&lt;/b&gt;ボタンを使用ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
<translation type="obsolete">よã†ã“ãæ–°è¦ä»®æƒ³ãƒ‡ã‚£ã‚¹ã‚¯ä½œæˆã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¸ï¼</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>Image Type</source>
<translation type="obsolete">イメージã®ã‚¿ã‚¤ãƒ—</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&amp;Dynamically expanding image</source>
<translation type="obsolete">å¯å¤‰ã‚µã‚¤ã‚ºã®ã‚¤ãƒ¡ãƒ¼ã‚¸(&amp;D)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&amp;Fixed-size image</source>
<translation type="obsolete">固定サイズã®ã‚¤ãƒ¡ãƒ¼ã‚¸(&amp;F)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>Virtual Disk Image Type</source>
<translation type="obsolete">仮想ディスクイメージã®ã‚¿ã‚¤ãƒ—</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location and name of the file
to store the virtual hard disk image or type a file name in the entry field.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;&lt;b&gt;[é¸æŠž]&lt;/b&gt;ボタンをクリックã—ã€ãƒ•ァイルã®å ´æ‰€ã¨åå‰ã‚’é¸æŠžã—ã¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’ä¿å­˜ã™ã‚‹ã‹ã€å…¥åŠ›ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«ãƒ•ァイルåを入力ã—ã¦ãã ã•ㄠ。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&amp;Image File Name</source>
<translation type="obsolete">イメージファイルå(&amp;I)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>Select</source>
<translation type="obsolete">é¸æŠž</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;p&gt;Select the size of the virtual hard disk image in megabytes. This size will be reported to the Guest OS
as the size of the virtual hard disk.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚µã‚¤ã‚ºã‚’é¸æŠžã—ã¦ãã ã•ã„。
ã“ã®ã‚µã‚¤ã‚ºã¯ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚µã‚¤ã‚ºã¨ã—ã¦ã‚²ã‚¹ãƒˆOSã«å ±å‘Šã•れã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>Image &amp;Size</source>
<translation type="obsolete">イメージã®ã‚µã‚¤ã‚º(&amp;S)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>Virtual Disk Location and Size</source>
<translation type="obsolete">仮想ディスクã®å ´æ‰€ã¨ã‚µã‚¤ã‚º</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>You are going to create a new virtual hard disk image with the following parameters:</source>
<translation type="obsolete">æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã¯ä»¥ä¸‹ã®è¨­å®šã§ä½œæˆã•れã¾ã™:</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button.
Once you press it, a new hard disk image will be created.
</source>
<translation type="obsolete">上記ã®è¨­å®šãŒæ­£ã—ã‘れã°ã€&lt;b&gt;[完了]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。 æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ãŒä½œæˆã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="935"/>
<source>Summary</source>
- <translation type="obsolete">概è¦</translation>
+ <translation type="unfinished">概è¦</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
<translation type="obsolete">&lt;nobr&gt;%1 ãƒã‚¤ãƒˆ&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;table&gt;&lt;tr&gt;&lt;td&gt;Type:&lt;/td&gt;&lt;td&gt;%1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Location:&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Size:&lt;/td&gt;&lt;td&gt;%3&amp;nbsp;(%4&amp;nbsp;Bytes)&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</source>
<translation type="obsolete">&lt;table&gt;&lt;tr&gt;&lt;td&gt;タイプ:&lt;/td&gt;&lt;td&gt;%1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;場所:&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;サイズ:&lt;/td&gt;&lt;td&gt;%3&amp;nbsp;(%4&amp;nbsp;ãƒã‚¤ãƒˆ)&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>Hard disk images (*.vdi)</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸(*.vdi)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="783"/>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„</translation>
+ <translation type="unfinished">æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;
&lt;p&gt;A &lt;b&gt;dynamically expanding image&lt;/b&gt; initially occupies a very small amount
of space on your physical hard disk. It will grow dynamically (up to
@@ -5477,258 +5518,426 @@ time depending on the image size and the write performance of your harddisk.&lt;
固定サイズã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã®ä½œæˆã¯ã€ã‚¤ãƒ¡ãƒ¼ã‚¸ã®ã‚µã‚¤ã‚ºã¨ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®æ›¸ãè¾¼ã¿æ€§èƒ½ã«ä¾å­˜ã—ã¦é•·ã„時間ãŒã‹ã‹ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk image for your virtual machine.&lt;/p&gt;&lt;p&gt;Use the &lt;b&gt;Next&lt;/b&gt; button to go to the next page of the wizard and the &lt;b&gt;Back&lt;/b&gt; button to return to the previous page.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ä»®æƒ³ãƒžã‚·ãƒ³ç”¨ã®æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ä½œæˆã‚’手助ã‘ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã®æ¬¡ã®ãƒšãƒ¼ã‚¸ã«é€²ã‚€ã«ã¯&lt;b&gt;[次ã¸]&lt;/b&gt;ボタンをã€å‰ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã‚‹ã«ã¯&lt;b&gt;[戻る]&lt;/b&gt;ボタンを使用ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt; &amp;Back</source>
<translation type="obsolete">&lt; 戻る(&amp;B)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&amp;Next &gt;</source>
<translation type="obsolete">次ã¸(&amp;N) &gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding image&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size image&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size image may take a long time depending on the image size and the write performance of your harddisk.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;作æˆã™ã‚‹ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã®ã‚¿ã‚¤ãƒ—ã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p&gt;&lt;b&gt;å¯å¤‰ã‚µã‚¤ã‚ºã®ã‚¤ãƒ¡ãƒ¼ã‚¸&lt;/b&gt;ã¯ã€æœ€åˆã«ç‰©ç†çš„ãªãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã®ã”ãå°ã•ãªå®¹é‡ã—ã‹ä½¿ç”¨ã—ã¾ã›ã‚“。ゲストOSãŒè¦æ±‚ã™ã‚‹ãƒ‡ã‚£ã‚¹ã‚¯å®¹é‡ã«å¿œã˜ã¦ã‚µã‚¤ã‚ºãŒå‹•çš„ã«å¢—加(指定ã•れãŸã‚µã‚¤ã‚ºã¾ã§)ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;&lt;b&gt;固定サイズã®ã‚¤ãƒ¡ãƒ¼ã‚¸&lt;/b&gt;ã®å®¹é‡ã¯å¢—加ã—ã¾ã›ã‚“。仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚µã‚¤ã‚ºã¨ã»ã¼åŒã˜ã‚µã‚¤ã‚ºã®ãƒ•ァイルã«ä¿å­˜ã•れã¾ã™ã€‚固定サイズã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã®ä½œæˆã¯ã€ã‚¤ãƒ¡ãƒ¼ã‚¸ã®ã‚µã‚¤ã‚ºã¨ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®æ›¸ãè¾¼ã¿æ€§èƒ½ã«ä¾å­˜ã—ã¦é•·ã„時間ãŒã‹ã‹ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location and name of the file to store the virtual hard disk image or type a file name in the entry field.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;&lt;b&gt;[é¸æŠž]&lt;/b&gt;ボタンをクリックã—ã€ãƒ•ァイルã®å ´æ‰€ã¨åå‰ã‚’é¸æŠžã—ã¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’ä¿å­˜ã™ã‚‹ã‹ã€å…¥åŠ›ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«ãƒ•ァイルåを入力ã—ã¦ãã ã•ㄠ。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;p&gt;Select the size of the virtual hard disk image in megabytes. This size will be reported to the Guest OS as the size of the virtual hard disk.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚µã‚¤ã‚ºã‚’é¸æŠžã—ã¦ãã ã•ã„。ã“ã®ã‚µã‚¤ã‚ºã¯ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚µã‚¤ã‚ºã¨ã—ã¦ã‚²ã‚¹ãƒˆOSã«å ±å‘Šã•れã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk image will be created.</source>
<translation type="obsolete">上記ã®è¨­å®šãŒæ­£ã—ã‘れã°ã€&lt;b&gt;[完了]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。 æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ãŒä½œæˆã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&amp;Finish</source>
<translation type="obsolete">完了(&amp;F)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>Type</source>
<comment>summary</comment>
<translation type="obsolete">タイプ</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="236"/>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="239"/>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="240"/>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="299"/>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="300"/>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="306"/>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="369"/>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="371"/>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="373"/>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="402"/>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="403"/>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="405"/>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="409"/>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="410"/>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="532"/>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="533"/>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="539"/>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="542"/>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="544"/>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="550"/>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="551"/>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="552"/>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="649"/>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="650"/>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="653"/>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="659"/>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="909"/>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="939"/>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="942"/>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="947"/>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="958"/>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="967"/>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="968"/>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="969"/>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">場所</translation>
+ <translation type="unfinished">場所</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="970"/>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">サイズ</translation>
+ <translation type="unfinished">サイズ</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>Bytes</source>
<comment>summary</comment>
<translation type="obsolete">ãƒã‚¤ãƒˆ</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;Use the &lt;b&gt;Next&lt;/b&gt; button to go to the next page of the wizard and the &lt;b&gt;Back&lt;/b&gt; button to return to the previous page.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ä»®æƒ³ãƒžã‚·ãƒ³ç”¨ã®æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ä½œæˆã‚’手助ã‘ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã®æ¬¡ã®ãƒšãƒ¼ã‚¸ã«é€²ã‚€ã«ã¯&lt;b&gt;[次ã¸]&lt;/b&gt;ボタンをã€å‰ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã‚‹ã«ã¯&lt;b&gt;[戻る]&lt;/b&gt;ボタンを使用ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>Hard Disk Storage Type</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ ストレージ タイプ</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;作æˆã™ã‚‹ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚¿ã‚¤ãƒ—ã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p&gt;&lt;b&gt;å¯å¤‰ã‚µã‚¤ã‚ºã®ã‚¤ãƒ¡ãƒ¼ã‚¸&lt;/b&gt;ã¯ã€æœ€åˆã«ç‰©ç†çš„ãªãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã®ã”ãå°ã•ãªå®¹é‡ã—ã‹ä½¿ç”¨ã—ã¾ã›ã‚“。ゲストOSãŒè¦æ±‚ã™ã‚‹ãƒ‡ã‚£ã‚¹ã‚¯å®¹é‡ã«å¿œã˜ã¦ã‚µã‚¤ã‚ºãŒå‹•çš„ã«å¢—加(指定ã•れãŸã‚µã‚¤ã‚ºã¾ã§)ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;&lt;b&gt;固定サイズã®ã‚¤ãƒ¡ãƒ¼ã‚¸&lt;/b&gt;ã®å®¹é‡ã¯å¢—加ã—ã¾ã›ã‚“。仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚µã‚¤ã‚ºã¨ã»ã¼åŒã˜ã‚µã‚¤ã‚ºã®ãƒ•ァイルã«ä¿å­˜ã•れã¾ã™ã€‚固定サイズã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã®ä½œæˆã¯ã€ã‚¤ãƒ¡ãƒ¼ã‚¸ã®ã‚µã‚¤ã‚ºã¨ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®æ›¸ãè¾¼ã¿æ€§èƒ½ã«ä¾å­˜ã—ã¦é•·ã„時間ãŒã‹ã‹ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>Storage Type</source>
<translation type="obsolete">ストレージ タイプ</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&amp;Dynamically expanding storage</source>
<translation type="obsolete">å¯å¤‰ã‚µã‚¤ã‚ºã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸(&amp;D)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&amp;Fixed-size storage</source>
<translation type="obsolete">固定サイズã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸(&amp;F)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;&lt;b&gt;[é¸æŠž]&lt;/b&gt;ボタンをクリックã—ã€ãƒ•ァイルã®å ´æ‰€ã‚’é¸æŠžã—ã¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãƒ‡ãƒ¼ã‚¿ã‚’ä¿å­˜ã™ã‚‹ã‹ã€å…¥åŠ›ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«ãƒ•ァイルåを入力ã—ã¦ãã ã•ㄠ。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&amp;Location</source>
<translation type="obsolete">場所(&amp;L)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚µã‚¤ã‚ºã‚’メガãƒã‚¤ãƒˆå˜ä½ã§é¸æŠžã—ã¦ãã ã•ã„。ã“ã®ã‚µã‚¤ã‚ºã¯ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®æœ€å¤§ã‚µã‚¤ã‚ºã¨ã—ã¦ã‚²ã‚¹ãƒˆOSã«å ±å‘Šã•れã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>&amp;Size</source>
<translation type="obsolete">サイズ(&amp;S)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
<translation type="obsolete">æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã¯ä»¥ä¸‹ã®è¨­å®šã§ä½œæˆã•れã¾ã™:</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="98"/>
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">上記ã®è¨­å®šãŒæ­£ã—ã‘れã°ã€&lt;b&gt;[完了]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。 æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒä½œæˆã•れã¾ã™ã€‚</translation>
</message>
+ <message>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="1067"/>
+ <location filename="../src/wizards/newhd/UINewHDWizard.cpp" line="687"/>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizardPageFormat.ui" line="46"/>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizardPageOptions.ui" line="46"/>
+ <source>&amp;Location</source>
+ <translation type="unfinished">場所(&amp;L)</translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizardPageOptions.ui" line="72"/>
+ <source>&amp;Size</source>
+ <translation type="unfinished">サイズ(&amp;S)</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizardPageVariant.ui" line="46"/>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageWelcome</name>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="113"/>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>よã†ã“ãæ–°è¦ä»®æƒ³ãƒ‡ã‚£ã‚¹ã‚¯ä½œæˆã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¸ï¼</translation>
+ <translation type="obsolete">よã†ã“ãæ–°è¦ä»®æƒ³ãƒ‡ã‚£ã‚¹ã‚¯ä½œæˆã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¸ï¼</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="116"/>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ä»®æƒ³ãƒžã‚·ãƒ³ç”¨ã®æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ä½œæˆã‚’手助ã‘ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ä»®æƒ³ãƒžã‚·ãƒ³ç”¨ã®æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ä½œæˆã‚’手助ã‘ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizardPageWelcome.ui" line="46"/>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/wizards/newhd/UINewHDWizardPageWelcome.ui" line="58"/>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzdPage2.ui" line="39"/>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;作æˆã™ã‚‹ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚¿ã‚¤ãƒ—ã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p&gt;&lt;b&gt;å¯å¤‰ã‚µã‚¤ã‚ºã®ã‚¤ãƒ¡ãƒ¼ã‚¸&lt;/b&gt;ã¯ã€æœ€åˆã«ç‰©ç†çš„ãªãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã®ã”ãå°ã•ãªå®¹é‡ã—ã‹ä½¿ç”¨ã—ã¾ã›ã‚“。ゲストOSãŒè¦æ±‚ã™ã‚‹ãƒ‡ã‚£ã‚¹ã‚¯å®¹é‡ã«å¿œã˜ã¦ã‚µã‚¤ã‚ºãŒå‹•çš„ã«å¢—加(指定ã•れãŸã‚µã‚¤ã‚ºã¾ã§)ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;&lt;b&gt;固定サイズã®ã‚¤ãƒ¡ãƒ¼ã‚¸&lt;/b&gt;ã®å®¹é‡ã¯å¢—加ã—ã¾ã›ã‚“。仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚µã‚¤ã‚ºã¨ã»ã¼åŒã˜ã‚µã‚¤ã‚ºã®ãƒ•ァイルã«ä¿å­˜ã•れã¾ã™ã€‚固定サイズã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã®ä½œæˆã¯ã€ã‚¤ãƒ¡ãƒ¼ã‚¸ã®ã‚µã‚¤ã‚ºã¨ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®æ›¸ãè¾¼ã¿æ€§èƒ½ã«ä¾å­˜ã—ã¦é•·ã„時間ãŒã‹ã‹ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;作æˆã™ã‚‹ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚¿ã‚¤ãƒ—ã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p&gt;&lt;b&gt;å¯å¤‰ã‚µã‚¤ã‚ºã®ã‚¤ãƒ¡ãƒ¼ã‚¸&lt;/b&gt;ã¯ã€æœ€åˆã«ç‰©ç†çš„ãªãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã®ã”ãå°ã•ãªå®¹é‡ã—ã‹ä½¿ç”¨ã—ã¾ã›ã‚“。ゲストOSãŒè¦æ±‚ã™ã‚‹ãƒ‡ã‚£ã‚¹ã‚¯å®¹é‡ã«å¿œã˜ã¦ã‚µã‚¤ã‚ºãŒå‹•çš„ã«å¢—加(指定ã•れãŸã‚µã‚¤ã‚ºã¾ã§)ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;&lt;b&gt;固定サイズã®ã‚¤ãƒ¡ãƒ¼ã‚¸&lt;/b&gt;ã®å®¹é‡ã¯å¢—加ã—ã¾ã›ã‚“。仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚µã‚¤ã‚ºã¨ã»ã¼åŒã˜ã‚µã‚¤ã‚ºã®ãƒ•ァイルã«ä¿å­˜ã•れã¾ã™ã€‚固定サイズã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã®ä½œæˆã¯ã€ã‚¤ãƒ¡ãƒ¼ã‚¸ã®ã‚µã‚¤ã‚ºã¨ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®æ›¸ãè¾¼ã¿æ€§èƒ½ã«ä¾å­˜ã—ã¦é•·ã„時間ãŒã‹ã‹ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzdPage2.ui" line="49"/>
<source>Storage Type</source>
- <translation>ストレージ タイプ</translation>
+ <translation type="obsolete">ストレージ タイプ</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzdPage2.ui" line="55"/>
<source>&amp;Dynamically expanding storage</source>
- <translation>å¯å¤‰ã‚µã‚¤ã‚ºã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸(&amp;D)</translation>
+ <translation type="obsolete">å¯å¤‰ã‚µã‚¤ã‚ºã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸(&amp;D)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzdPage2.ui" line="62"/>
<source>&amp;Fixed-size storage</source>
- <translation>固定サイズã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸(&amp;F)</translation>
+ <translation type="obsolete">固定サイズã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸(&amp;F)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="149"/>
<source>Hard Disk Storage Type</source>
- <translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ ストレージ タイプ</translation>
+ <translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ ストレージ タイプ</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzdPage3.ui" line="39"/>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;&lt;b&gt;[é¸æŠž]&lt;/b&gt;ボタンをクリックã—ã€ãƒ•ァイルã®å ´æ‰€ã‚’é¸æŠžã—ã¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãƒ‡ãƒ¼ã‚¿ã‚’ä¿å­˜ã™ã‚‹ã‹ã€å…¥åŠ›ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«ãƒ•ァイルåを入力ã—ã¦ãã ã•ㄠ。&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;&lt;b&gt;[é¸æŠž]&lt;/b&gt;ボタンをクリックã—ã€ãƒ•ァイルã®å ´æ‰€ã‚’é¸æŠžã—ã¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãƒ‡ãƒ¼ã‚¿ã‚’ä¿å­˜ã™ã‚‹ã‹ã€å…¥åŠ›ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«ãƒ•ァイルåを入力ã—ã¦ãã ã•ㄠ。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzdPage3.ui" line="49"/>
<source>&amp;Location</source>
- <translation>場所(&amp;L)</translation>
+ <translation type="obsolete">場所(&amp;L)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzdPage3.ui" line="68"/>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚µã‚¤ã‚ºã‚’é¸æŠžã—ã¦ãã ã•ã„。ã“ã®ã‚µã‚¤ã‚ºã¯ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®æœ€å¤§ã‚µã‚¤ã‚ºã¨ã—ã¦ã‚²ã‚¹ãƒˆOSã«å ±å‘Šã•れã¾ã™ã€‚&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚µã‚¤ã‚ºã‚’é¸æŠžã—ã¦ãã ã•ã„。ã“ã®ã‚µã‚¤ã‚ºã¯ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®æœ€å¤§ã‚µã‚¤ã‚ºã¨ã—ã¦ã‚²ã‚¹ãƒˆOSã«å ±å‘Šã•れã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzdPage3.ui" line="78"/>
<source>&amp;Size</source>
- <translation>サイズ(&amp;S)</translation>
+ <translation type="obsolete">サイズ(&amp;S)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="252"/>
<source>Virtual Disk Location and Size</source>
- <translation>仮想ディスクã®å ´æ‰€ã¨ã‚µã‚¤ã‚º</translation>
+ <translation type="obsolete">仮想ディスクã®å ´æ‰€ã¨ã‚µã‚¤ã‚º</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="329"/>
<source>Select a file for the new hard disk image file</source>
- <translation>æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„</translation>
+ <translation type="obsolete">æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="330"/>
<source>Hard disk images (*.vdi)</source>
- <translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸(*.vdi)</translation>
+ <translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸(*.vdi)</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="418"/>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzdPage4.ui" line="39"/>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã¯ä»¥ä¸‹ã®è¨­å®šã§ä½œæˆã•れã¾ã™:</translation>
+ <translation type="obsolete">æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã¯ä»¥ä¸‹ã®è¨­å®šã§ä½œæˆã•れã¾ã™:</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="446"/>
<source>Summary</source>
- <translation>概è¦</translation>
+ <translation type="obsolete">概è¦</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="454"/>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="462"/>
<source>Type</source>
<comment>summary</comment>
- <translation>タイプ</translation>
+ <translation type="obsolete">タイプ</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="463"/>
<source>Location</source>
<comment>summary</comment>
- <translation>場所</translation>
+ <translation type="obsolete">場所</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="464"/>
<source>Size</source>
<comment>summary</comment>
- <translation>サイズ</translation>
+ <translation type="obsolete">サイズ</translation>
</message>
<message>
- <location filename="../src/wizards/newhd/UINewHDWzd.cpp" line="471"/>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>上記ã®è¨­å®šãŒæ­£ã—ã‘れã°ã€&lt;b&gt;[%1]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。 æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ãŒä½œæˆã•れã¾ã™ã€‚</translation>
+ <translation type="obsolete">上記ã®è¨­å®šãŒæ­£ã—ã‘れã°ã€&lt;b&gt;[%1]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。 æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ãŒä½œæˆã•れã¾ã™ã€‚</translation>
</message>
</context>
<context>
@@ -5739,7 +5948,11 @@ time depending on the image size and the write performance of your harddisk.&lt;
<translation>æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã®ä½œæˆ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="170"/>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<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;Use the &lt;b&gt;Next&lt;/b&gt; button to go the next page of the wizard
@@ -5748,12 +5961,10 @@ and the &lt;b&gt;Back&lt;/b&gt; button to return to the previous page.&lt;/p&gt;
&lt;p&gt;ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã®æ¬¡ã®ãƒšãƒ¼ã‚¸ã«é€²ã‚€ã«ã¯&lt;b&gt;[次ã¸]&lt;/b&gt;ボタンをã€å‰ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã‚‹ã«ã¯&lt;b&gt;[戻る]&lt;/b&gt;ボタンを使用ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>Welcome to the New Virtual Machine Wizard!</source>
<translation type="obsolete">よã†ã“ãæ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ä½œæˆã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¸ï¼</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt;p&gt;Enter a name for the new virtual machine and select the type of the guest operating
system you plan to install onto the virtual machine.&lt;/p&gt;
&lt;p&gt;The name of the virtual machine usually indicates its software and hardware configuration.
@@ -5762,57 +5973,46 @@ It will be used by all VirtualBox components to identify your virtual machine.&l
&lt;p&gt;通常ã€ä»®æƒ³ãƒžã‚·ãƒ³ã®åå‰ã¯ã‚½ãƒ•トウェアã¨ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢æ§‹æˆã‚’示ã—ã¾ã™ã€‚VirtualBoxã¯ä½œæˆã•れãŸä»®æƒ³ãƒžã‚·ãƒ³ã‚’特定ã™ã‚‹ãŸã‚ã«ã“ã®åå‰ã‚’使用ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>N&amp;ame</source>
<translation type="obsolete">åå‰(&amp;N)</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>OS &amp;Type</source>
<translation type="obsolete">OSタイプ(&amp;T)</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>VM Name and OS Type</source>
<translation type="obsolete">仮想マシンåã¨OSタイプ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt;p&gt;Select the amount of base memory (RAM) in megabytes to be allocated to the virtual machine.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想マシンã«å‰²ã‚Šå½“ã¦ã‚‹ãƒ¡ã‚¤ãƒ³ãƒ¡ãƒ¢ãƒª(RAM)ã®ã‚µã‚¤ã‚ºã‚’メガãƒã‚¤ãƒˆå˜ä½ã§é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>Base &amp;Memory Size</source>
<translation type="obsolete">メインメモリã®ã‚µã‚¤ã‚º(&amp;M)</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt;</source>
<translation type="obsolete">&lt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>=</source>
<translation type="obsolete">=</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&gt;</source>
<translation type="obsolete">&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>MB</source>
<translation type="obsolete">MB</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>Memory</source>
<translation type="obsolete">メモリ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt;p&gt;Select a hard disk image to be used
as the boot hard disk of the virtual machine. You can either create a new hard
disk using the &lt;b&gt;New&lt;/b&gt; button or select an existing hard disk
@@ -5826,27 +6026,22 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
&lt;p&gt;より高度ãªãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯è¨­å®šãŒå¿…è¦ã§ã‚れã°ã€ã“ã®ã‚¹ãƒ†ãƒƒãƒ—をスキップã—ã€å¾Œã§ä»®æƒ³ãƒžã‚·ãƒ³è¨­å®šãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’使用ã—ã¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’割り当ã¦ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>B&amp;oot Hard Disk (Primary Master)</source>
<translation type="obsolete">起動ディスク (プライマリ マスター) (&amp;O)</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>N&amp;ew...</source>
<translation type="obsolete">æ–°è¦(&amp;E)...</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>E&amp;xisting...</source>
<translation type="obsolete">é¸æŠž(&amp;X)...</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>Virtual Hard Disk</source>
<translation type="obsolete">仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>
&lt;p&gt;
You are going to create a new virtual machine
@@ -5856,7 +6051,6 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<translation type="obsolete"> &lt;p&gt;æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã¯ä»¥ä¸‹ã®è¨­å®šã§ä½œæˆã•れã¾ã™: &lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>
&lt;p&gt;
If the above is correct press the &lt;b&gt;Finish&lt;/b&gt; button.
@@ -5872,127 +6066,103 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
&lt;p&gt;注:メインウィンドウã®ãƒ„ールãƒãƒ¼ã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹&lt;b&gt;[設定]&lt;/b&gt;ダイアログを使用ã—ã¦ä½œæˆã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®ã™ã¹ã¦ã®ã™ã¹ã¦ã®è¨­å®šã‚’ã„ã¤ã§ã‚‚変更ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>Summary</source>
<translation type="obsolete">概è¦</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</source>
<translation type="obsolete">&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt;tr&gt;&lt;td&gt;Name:&lt;/td&gt;&lt;td&gt;%1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;OS Type:&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Base Memory:&lt;/td&gt;&lt;td&gt;%3&amp;nbsp;MB&lt;/td&gt;&lt;/tr&gt;</source>
<translation type="obsolete">&lt;tr&gt;&lt;td&gt;åå‰:&lt;/td&gt;&lt;td&gt;%1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;OSタイプ:&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;メインメモリ:&lt;/td&gt;&lt;td&gt;%3&amp;nbsp;MB&lt;/td&gt;&lt;/tr&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt;tr&gt;&lt;td&gt;Boot Hard Disk:&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;/tr&gt;</source>
<translation type="obsolete">&lt;tr&gt;&lt;td&gt;起動ディスク:&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;/tr&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>The recommended base memory size is &lt;b&gt;%1&lt;/b&gt; MB.</source>
<translation type="obsolete">推奨ã•れるメインメモリã®ã‚µã‚¤ã‚ºã¯&lt;b&gt;%1&lt;/b&gt;MBã§ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>The recommended size of the boot hard disk is &lt;b&gt;%1&lt;/b&gt; MB.</source>
<translation type="obsolete">推奨ã•れる起動ディスクã®ã‚µã‚¤ã‚ºã¯&lt;b&gt;%1&lt;/b&gt;MBã§ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<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;Use the &lt;b&gt;Next&lt;/b&gt; button to go the next page of the wizard and the &lt;b&gt;Back&lt;/b&gt; button to return to the previous page.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯VirtualBoxç”¨ã®æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã‚’作æˆã™ã‚‹ãŸã‚ã«å¿…è¦ãªã‚¹ãƒ†ãƒƒãƒ—を案内ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã®æ¬¡ã®ãƒšãƒ¼ã‚¸ã«é€²ã‚€ã«ã¯&lt;b&gt;[次ã¸]&lt;/b&gt;ボタンをã€å‰ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã‚‹ã«ã¯&lt;b&gt;[戻る]&lt;/b&gt;ボタンを使用ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt; &amp;Back</source>
<translation type="obsolete">&lt; 戻る(&amp;B)</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&amp;Next &gt;</source>
<translation type="obsolete">次ã¸(&amp;N) &gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt;p&gt;Enter a name for the new virtual machine and select the type of the guest operating system you plan to install onto the virtual machine.&lt;/p&gt;&lt;p&gt;The name of the virtual machine usually indicates its software and hardware configuration. It will be used by all VirtualBox components to identify your virtual machine.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã®åå‰ã‚’入力ã—ã€ä»®æƒ³ãƒžã‚·ãƒ³ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ãŸã„ゲストOSã®ã‚¿ã‚¤ãƒ—ã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p&gt;通常ã€ä»®æƒ³ãƒžã‚·ãƒ³ã®åå‰ã¯ã‚½ãƒ•トウェアã¨ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢æ§‹æˆã‚’示ã—ã¾ã™ã€‚VirtualBoxã¯ä½œæˆã•れãŸä»®æƒ³ãƒžã‚·ãƒ³ã‚’特定ã™ã‚‹ãŸã‚ã«ã“ã®åå‰ã‚’使用ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt;p&gt;Select a hard disk image to be used as the boot hard disk of the virtual machine. You can either create a new hard disk using the &lt;b&gt;New&lt;/b&gt; button or select an existing hard disk image from the drop-down list or by pressing the &lt;b&gt;Existing&lt;/b&gt; button (to invoke the Virtual Disk Manager dialog).&lt;/p&gt;&lt;p&gt;If you need a more complicated hard disk setup, you can also skip this step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想マシンã§èµ·å‹•ディスクã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’é¸æŠžã—ã¾ã™ã€‚&lt;b&gt;[æ–°è¦]&lt;/b&gt;ボタンをクリックã—ã¦æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’作æˆã™ã‚‹ã‹ã€ãƒ‰ãƒ­ãƒƒãƒ—ダウンリストã¾ãŸã¯&lt;b&gt;[é¸æŠž]&lt;/b&gt;ボタンをクリック(仮想ディスクマãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•ã—ã¾ã™)ã—ã¦æ—¢å­˜ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’é¸æŠžã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;より高度ãªãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯è¨­å®šãŒå¿…è¦ã§ã‚れã°ã€ã“ã®ã‚¹ãƒ†ãƒƒãƒ—をスキップã—ã€å¾Œã§ä»®æƒ³ãƒžã‚·ãƒ³è¨­å®šãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’使用ã—ã¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’割り当ã¦ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt;p&gt;You are going to create a new virtual machine with the following parameters:&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã¯ä»¥ä¸‹ã®è¨­å®šã§ä½œæˆã•れã¾ã™:&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt;p&gt;If the above is correct press the &lt;b&gt;Finish&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 type="obsolete">&lt;p&gt;上記ã®è¨­å®šãŒæ­£ã—ã‘れã°ã€&lt;b&gt;[完了]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。新è¦ä»®æƒ³ãƒžã‚·ãƒ³ãŒä½œæˆã•れã¾ã™ã€‚ &lt;/p&gt;&lt;p&gt;注:メインウィンドウã®ãƒ„ールãƒãƒ¼ã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹&lt;b&gt;[設定]&lt;/b&gt;ダイアログを使用ã—ã¦ä½œæˆã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®ã™ã¹ã¦ã®ã™ã¹ã¦ã®è¨­å®šã‚’ã„ã¤ã§ã‚‚変更ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&amp;Finish</source>
<translation type="obsolete">完了(&amp;F)</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>MB</source>
<comment>megabytes</comment>
<translation type="obsolete">MB</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>Name</source>
<comment>summary</comment>
<translation type="obsolete">åå‰</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>OS Type</source>
<comment>summary</comment>
<translation type="obsolete">OSタイプ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>Base Memory</source>
<comment>summary</comment>
<translation type="obsolete">メインメモリ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>Boot Hard Disk</source>
<comment>summary</comment>
<translation type="obsolete">èµ·å‹• ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&lt;p&gt;Select a hard disk image to be used as the boot hard disk of the virtual machine. You can either create a new hard disk using the &lt;b&gt;New&lt;/b&gt; button or select an existing hard disk image from the drop-down list or by pressing the &lt;b&gt;Existing&lt;/b&gt; button (to invoke the Virtual Media Manager dialog).&lt;/p&gt;&lt;p&gt;If you need a more complicated hard disk setup, you can also skip this step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想マシンã§èµ·å‹•ディスクã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’é¸æŠžã—ã¾ã™ã€‚&lt;b&gt;[æ–°è¦]&lt;/b&gt;ボタンをクリックã—ã¦æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’作æˆã™ã‚‹ã‹ã€ãƒ‰ãƒ­ãƒƒãƒ—ダウンリストã¾ãŸã¯&lt;b&gt;[é¸æŠž]&lt;/b&gt;ボタンをクリック(仮想メディアマãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•)ã—ã¦æ—¢å­˜ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’é¸æŠžã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;より高度ãªãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯è¨­å®šãŒå¿…è¦ã§ã‚れã°ã€ã“ã®ã‚¹ãƒ†ãƒƒãƒ—をスキップã—ã€å¾Œã§ä»®æƒ³ãƒžã‚·ãƒ³è¨­å®šãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’使用ã—ã¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’割り当ã¦ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>Boot Hard &amp;Disk (Primary Master)</source>
<translation type="obsolete">起動ディスク (プライマリ マスター) (&amp;D)</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&amp;Create new hard disk</source>
<translation type="obsolete">æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ä½œæˆ(&amp;C)</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="168"/>
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">既存ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’使用(&amp;U)</translation>
</message>
@@ -6000,12 +6170,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="183"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="185"/>
<source>Welcome to the New Virtual Machine Wizard!</source>
<translation>よã†ã“ãæ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ä½œæˆã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¸ï¼</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="185"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="187"/>
<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>
@@ -6028,7 +6198,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="243"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="245"/>
<source>VM Name and OS Type</source>
<translation>仮想マシンåã¨OSタイプ</translation>
</message>
@@ -6051,17 +6221,16 @@ 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="349"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="351"/>
<source>Memory</source>
<translation>メモリ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="354"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="356"/>
<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>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="354"/>
<source>MB</source>
<comment>size suffix MBytes=1024 KBytes</comment>
<translation type="obsolete">MB</translation>
@@ -6070,12 +6239,10 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<context>
<name>UINewVMWzdPage4</name>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="354"/>
<source>&lt;p&gt;Select a hard disk image to be used as the boot hard disk of the virtual machine. You can either create a new hard disk using the &lt;b&gt;New&lt;/b&gt; button or select an existing hard disk image from the drop-down list or by pressing the &lt;b&gt;Existing&lt;/b&gt; button (to invoke the Virtual Media Manager dialog).&lt;/p&gt;&lt;p&gt;If you need a more complicated hard disk setup, you can also skip this step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想マシンã§èµ·å‹•ディスクã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’é¸æŠžã—ã¾ã™ã€‚&lt;b&gt;[æ–°è¦]&lt;/b&gt;ボタンをクリックã—ã¦æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’作æˆã™ã‚‹ã‹ã€ãƒ‰ãƒ­ãƒƒãƒ—ダウンリストã¾ãŸã¯&lt;b&gt;[é¸æŠž]&lt;/b&gt;ボタンをクリック(仮想メディアマãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•)ã—ã¦æ—¢å­˜ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’é¸æŠžã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;より高度ãªãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯è¨­å®šãŒå¿…è¦ã§ã‚れã°ã€ã“ã®ã‚¹ãƒ†ãƒƒãƒ—をスキップã—ã€å¾Œã§ä»®æƒ³ãƒžã‚·ãƒ³è¨­å®šãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’使用ã—ã¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’割り当ã¦ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="354"/>
<source>Boot Hard &amp;Disk (Primary Master)</source>
<translation type="obsolete">起動ディスク (プライマリ マスター) (&amp;D)</translation>
</message>
@@ -6105,17 +6272,16 @@ 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="443"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="445"/>
<source>Virtual Hard Disk</source>
<translation>仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="448"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="450"/>
<source>The recommended size of the boot hard disk is &lt;b&gt;%1&lt;/b&gt;.</source>
<translation>推奨ã•れる起動ディスクã®ã‚µã‚¤ã‚ºã¯&lt;b&gt;%1&lt;/b&gt;ã§ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="448"/>
<source>The recommended size of the boot hard disk is &lt;b&gt;%1&lt;/b&gt; MB.</source>
<translation type="obsolete">推奨ã•れる起動ディスクã®ã‚µã‚¤ã‚ºã¯&lt;b&gt;%1&lt;/b&gt;MBã§ã™ã€‚</translation>
</message>
@@ -6128,42 +6294,41 @@ 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="647"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="646"/>
<source>Summary</source>
<translation>概è¦</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="663"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="662"/>
<source>Name</source>
<comment>summary</comment>
<translation>åå‰</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="664"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="663"/>
<source>OS Type</source>
<comment>summary</comment>
<translation>OSタイプ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="665"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="664"/>
<source>Base Memory</source>
<comment>summary</comment>
<translation>メインメモリ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="665"/>
<source>MB</source>
<comment>size suffix MBytes=1024KBytes</comment>
<translation type="obsolete">MB</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="675"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="674"/>
<source>Boot Hard Disk</source>
<comment>summary</comment>
<translation>èµ·å‹• ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="682"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="681"/>
<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>
@@ -6209,72 +6374,58 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<translation>キャンセル(&amp;C)</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>Time remaining: %1</source>
<translation type="obsolete">残り時間: %1</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>%1 days, %2 hours remaining</source>
<translation type="obsolete">残り時間 %1日㨠%2時間</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>%1 days, %2 minutes remaining</source>
<translation type="obsolete">残り時間 %1日㨠%2分</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>%1 days remaining</source>
<translation type="obsolete">残り時間 %1日</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>1 day, %1 hours remaining</source>
<translation type="obsolete">残り時間 1日㨠%1時間</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>1 day, %1 minutes remaining</source>
<translation type="obsolete">残り時間 1日㨠%1分</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>1 day remaining</source>
<translation type="obsolete">残り時間 1日</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>%1 hours, %2 minutes remaining</source>
<translation type="obsolete">残り時間 %1時間㨠%2分</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>1 hour, %1 minutes remaining</source>
<translation type="obsolete">残り時間 1時間㨠%1分</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>1 hour remaining</source>
<translation type="obsolete">残り時間 1時間</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>%1 minutes remaining</source>
<translation type="obsolete">残り時間 %1分</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>1 minute, %2 seconds remaining</source>
<translation type="obsolete">残り時間 1分㨠%2秒</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>1 minute remaining</source>
<translation type="obsolete">残り時間 1分</translation>
</message>
<message>
- <location filename="../src/widgets/UIProgressDialog.cpp" line="136"/>
<source>%1 seconds remaining</source>
<translation type="obsolete">残り時間 %1秒</translation>
</message>
@@ -6309,7 +6460,7 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<context>
<name>UISession</name>
<message>
- <location filename="../src/runtime/UISession.cpp" line="393"/>
+ <location filename="../src/runtime/UISession.cpp" line="446"/>
<source>Install</source>
<translation>インストール</translation>
</message>
@@ -6322,27 +6473,162 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<translation>&lt;i&gt;å·¦å´ã®ãƒªã‚¹ãƒˆã‹ã‚‰è¨­å®šã®ã‚«ãƒ†ã‚´ãƒªã‚’é¸æŠžã—ã€è¨­å®šé …目をマウスオーãƒãƒ¼ã—ã¦è©³ç´°ãªæƒ…報をå‚ç…§ã—ã¦ãã ã•ã„。&lt;/i&gt;</translation>
</message>
<message>
- <location filename="../src/settings/UISettingsDialog.cpp" line="158"/>
+ <location filename="../src/settings/UISettingsDialog.cpp" line="184"/>
<source>On the &lt;b&gt;%1&lt;/b&gt; page, %2</source>
<translation>&lt;b&gt;%1&lt;/b&gt;ページ,%2</translation>
</message>
<message>
- <location filename="../src/settings/UISettingsDialog.cpp" line="204"/>
+ <location filename="../src/settings/UISettingsDialog.cpp" line="300"/>
<source>Invalid settings detected</source>
<translation>無効ãªè¨­å®šãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ</translation>
</message>
<message>
- <location filename="../src/settings/UISettingsDialog.cpp" line="205"/>
+ <location filename="../src/settings/UISettingsDialog.cpp" line="301"/>
<source>Non-optimal settings detected</source>
<translation>最é©åŒ–ã•れã¦ã„ãªã„設定ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ</translation>
</message>
<message>
- <location filename="../src/settings/UISettingsDialog.cpp" line="233"/>
+ <location filename="../src/settings/UISettingsDialog.cpp" line="344"/>
<source>Settings</source>
<translation>設定</translation>
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="479"/>
+ <source>General</source>
+ <translation>一般</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="482"/>
+ <source>Input</source>
+ <translation>入力</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="485"/>
+ <source>Update</source>
+ <translation>アップデート</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="488"/>
+ <source>Language</source>
+ <translation>言語</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="491"/>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="494"/>
+ <source>Network</source>
+ <translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="497"/>
+ <source>Extensions</source>
+ <translation>機能拡張</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="500"/>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="508"/>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="874"/>
+ <source>General</source>
+ <translation>一般</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="877"/>
+ <source>System</source>
+ <translation>システム</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="880"/>
+ <source>Display</source>
+ <translation>ディスプレイ</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="883"/>
+ <source>Storage</source>
+ <translation>ストレージ</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="886"/>
+ <source>Audio</source>
+ <translation>オーディオ</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="889"/>
+ <source>Network</source>
+ <translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="892"/>
+ <source>Ports</source>
+ <translation>ãƒãƒ¼ãƒˆ</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="895"/>
+ <source>Serial Ports</source>
+ <translation>シリアルãƒãƒ¼ãƒˆ</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="898"/>
+ <source>Parallel Ports</source>
+ <translation>パラレルãƒãƒ¼ãƒˆ</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="901"/>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="904"/>
+ <source>Shared Folders</source>
+ <translation>共有フォルダ</translation>
+ </message>
+ <message>
+ <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="916"/>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">64ビットã®ã‚²ã‚¹ãƒˆOSタイプãŒé¸æŠžã•れã¾ã—ãŸã€‚ゲストOSãŒä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½(VT-x/AMD-V)ã‚’å¿…è¦ã¨ã™ã‚‹ã¨ãã€ã“ã®æ©Ÿèƒ½ã¯è‡ªå‹•çš„ã«æœ‰åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">2D ビデオ ã‚¢ã‚¯ã‚»ãƒ©ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒæœ‰åŠ¹åŒ–ã•れã¾ã—ãŸã€‚2D ビデオ アクセラレーションã¯Windowsゲストã§ã®ã¿ã‚µãƒãƒ¼ãƒˆã•れるãŸã‚ã€æœ¬æ©Ÿèƒ½ã¯ç„¡åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">USB HID(Human Interface Device)を有効化ã—ã¾ã—ãŸã€‚ ã“れã¯ã€USBエミュレーションを有効化ã—ãªã„ã¨å‹•作ã—ã¾ã›ã‚“。USBエミュレーションã¯&lt;b&gt;[OK]&lt;/b&gt;ボタンを押ã™ã¨è‡ªå‹•çš„ã«æœ‰åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">1個ã ã‘サãƒãƒ¼ãƒˆ</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">%1個ã¾ã§ã‚µãƒãƒ¼ãƒˆ</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">%1ãƒãƒƒãƒ—セットãŒã‚µãƒãƒ¼ãƒˆã™ã‚‹ã‚ˆã‚Šå¤šãã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã‚’指定ã—ã¦ã„ã¾ã™ã€‚ システムページã§ãƒãƒƒãƒ—セットã®ç¨®é¡žã‚’変更ã™ã‚‹ã‹ã€ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒšãƒ¼ã‚¸ã§æ¬¡ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã®æ•°ã‚’減らã—ã¦ãã ã•ã„: %2。</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<location filename="../src/runtime/UIVMCloseDialog.ui" line="26"/>
@@ -6403,12 +6689,12 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<context>
<name>UIVMDesktop</name>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1405"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="1431"/>
<source>&amp;Details</source>
<translation>詳細(&amp;D)</translation>
</message>
<message>
- <location filename="../src/selector/UIVMDesktop.cpp" line="1429"/>
+ <location filename="../src/selector/UIVMDesktop.cpp" line="1455"/>
<source>&amp;Snapshots</source>
<translation>スナップショット(&amp;S)</translation>
</message>
@@ -6416,6 +6702,7 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<context>
<name>UIVMListView</name>
<message>
+ <location filename="../src/selector/UIVMItem.cpp" line="154"/>
<location filename="../src/selector/UIVMItem.cpp" line="160"/>
<source>Inaccessible</source>
<translation>アクセスã§ãã¾ã›ã‚“</translation>
@@ -6433,42 +6720,34 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<translation>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;%2ã‹ã‚‰ã®çŠ¶æ…‹ アクセスã§ãã¾ã›ã‚“&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/selector/UIVMItem.cpp" line="188"/>
<source>S&amp;how</source>
<translation type="obsolete">表示(&amp;H)</translation>
</message>
<message>
- <location filename="../src/selector/UIVMItem.cpp" line="188"/>
<source>Switch to the window of the selected virtual machine</source>
<translation type="obsolete">é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã«åˆ‡ã‚Šæ›¿ãˆ</translation>
</message>
<message>
- <location filename="../src/selector/UIVMItem.cpp" line="188"/>
<source>S&amp;tart</source>
<translation type="obsolete">èµ·å‹•(&amp;T)</translation>
</message>
<message>
- <location filename="../src/selector/UIVMItem.cpp" line="188"/>
<source>Start the selected virtual machine</source>
<translation type="obsolete">é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã‚’èµ·å‹•</translation>
</message>
<message>
- <location filename="../src/selector/UIVMItem.cpp" line="188"/>
<source>R&amp;esume</source>
<translation type="obsolete">å†é–‹(&amp;E)</translation>
</message>
<message>
- <location filename="../src/selector/UIVMItem.cpp" line="188"/>
<source>Resume the execution of the virtual machine</source>
<translation type="obsolete">仮想マシンã®å®Ÿè¡Œã‚’å†é–‹ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/selector/UIVMItem.cpp" line="188"/>
<source>&amp;Pause</source>
<translation type="obsolete">ä¸€æ™‚åœæ­¢(&amp;P)</translation>
</message>
<message>
- <location filename="../src/selector/UIVMItem.cpp" line="188"/>
<source>Suspend the execution of the virtual machine</source>
<translation type="obsolete">仮想マシンã®å®Ÿè¡Œã‚’ä¸€æ™‚åœæ­¢ã™ã‚‹</translation>
</message>
@@ -6512,99 +6791,6 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="781"/>
- <source>General</source>
- <translation>一般</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="784"/>
- <source>System</source>
- <translation>システム</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="787"/>
- <source>Display</source>
- <translation>ディスプレイ</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="790"/>
- <source>Storage</source>
- <translation>ストレージ</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="793"/>
- <source>Audio</source>
- <translation>オーディオ</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="796"/>
- <source>Network</source>
- <translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="801"/>
- <source>Ports</source>
- <translation>ãƒãƒ¼ãƒˆ</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="804"/>
- <source>Serial Ports</source>
- <translation>シリアルãƒãƒ¼ãƒˆ</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="809"/>
- <source>Parallel Ports</source>
- <translation>パラレルãƒãƒ¼ãƒˆ</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="814"/>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="817"/>
- <source>Shared Folders</source>
- <translation>共有フォルダ</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="839"/>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="860"/>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>64ビットã®ã‚²ã‚¹ãƒˆOSタイプãŒé¸æŠžã•れã¾ã—ãŸã€‚ゲストOSãŒä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½(VT-x/AMD-V)ã‚’å¿…è¦ã¨ã™ã‚‹ã¨ãã€ã“ã®æ©Ÿèƒ½ã¯è‡ªå‹•çš„ã«æœ‰åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="888"/>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>2D ビデオ ã‚¢ã‚¯ã‚»ãƒ©ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒæœ‰åŠ¹åŒ–ã•れã¾ã—ãŸã€‚2D ビデオ アクセラレーションã¯Windowsゲストã§ã®ã¿ã‚µãƒãƒ¼ãƒˆã•れるãŸã‚ã€æœ¬æ©Ÿèƒ½ã¯ç„¡åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="908"/>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>USB HID(Human Interface Device)を有効化ã—ã¾ã—ãŸã€‚ ã“れã¯ã€USBエミュレーションを有効化ã—ãªã„ã¨å‹•作ã—ã¾ã›ã‚“。USBエミュレーションã¯&lt;b&gt;[OK]&lt;/b&gt;ボタンを押ã™ã¨è‡ªå‹•çš„ã«æœ‰åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="941"/>
- <source>at most one supported</source>
- <translation>1個ã ã‘サãƒãƒ¼ãƒˆ</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="942"/>
- <source>up to %1 supported</source>
- <translation>%1個ã¾ã§ã‚µãƒãƒ¼ãƒˆ</translation>
- </message>
- <message>
- <location filename="../src/settings/UISettingsDialogSpecific.cpp" line="948"/>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>%1ãƒãƒƒãƒ—セットãŒã‚µãƒãƒ¼ãƒˆã™ã‚‹ã‚ˆã‚Šå¤šãã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã‚’指定ã—ã¦ã„ã¾ã™ã€‚ システムページã§ãƒãƒƒãƒ—セットã®ç¨®é¡žã‚’変更ã™ã‚‹ã‹ã€ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒšãƒ¼ã‚¸ã§æ¬¡ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã®æ•°ã‚’減らã—ã¦ãã ã•ã„: %2。</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<location filename="../src/VBoxAboutDlg.cpp" line="104"/>
@@ -6612,13 +6798,11 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<translation>VirtualBox ã«ã¤ã„ã¦</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="104"/>
<source>&lt;qt&gt;VirtualBox Graphical User Interface Version %1&lt;br&gt;
%2&lt;/qt&gt;</source>
<translation type="obsolete">&lt;qt&gt;VirtualBox グラフィカルユーザーインターフェース ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %1&lt;br&gt;%2&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="104"/>
<source>&lt;qt&gt;VirtualBox Graphical User Interface Version %1&lt;br&gt;%2&lt;/qt&gt;</source>
<translation type="obsolete">&lt;qt&gt;VirtualBox グラフィカルユーザーインターフェース ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %1&lt;br&gt;%2&lt;/qt&gt;</translation>
</message>
@@ -6636,12 +6820,10 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<context>
<name>VBoxAboutNonOSEDlg</name>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>VirtualBox - About</source>
<translation type="obsolete">VirtualBox ã«ã¤ã„ã¦</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>VirtualBox Graphical User Interface
Version %1</source>
<translation type="obsolete">VirtualBox グラフィカルユーザーインターフェース ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %1</translation>
@@ -6650,27 +6832,22 @@ Version %1</source>
<context>
<name>VBoxAddNIDialog</name>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Add Host Interface</source>
<translation type="obsolete">ホスト インターフェースã®è¿½åŠ </translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Interface Name</source>
<translation type="obsolete">インターフェースå</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Descriptive name of the new network interface</source>
<translation type="obsolete">æ–°è¦ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ インターフェースå</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>&amp;OK</source>
<translation type="obsolete">OK(&amp;O)</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
@@ -6678,67 +6855,54 @@ Version %1</source>
<context>
<name>VBoxAddSFDialog</name>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Add Share</source>
<translation type="obsolete">共有フォルダã®è¿½åŠ </translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Edit Share</source>
<translation type="obsolete">設定ã®ç·¨é›†</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Select a folder to share</source>
<translation type="obsolete">é¸æŠžã—ãŸãƒ•ォルダを共有</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Folder Path</source>
<translation type="obsolete">フォルダã®ãƒ‘ス</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Folder Name</source>
<translation type="obsolete">フォルダå</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Displays the path to an existing folder on the host PC.</source>
<translation type="obsolete">ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ä¸Šã®æ—¢å­˜ã®ãƒ•ォルダã®ãƒ‘スを表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Displays the name of the shared folder (as it will be seen by the guest OS).</source>
<translation type="obsolete">ゲストOSã§ä½¿ç”¨ã•れる共有フォルダåを表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Opens the dialog to select a folder.</source>
<translation type="obsolete">ãƒ•ã‚©ãƒ«ãƒ€é¸æŠžãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‹ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>&amp;OK</source>
<translation type="obsolete">OK(&amp;O)</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>&amp;Make Permanent</source>
<translation type="obsolete">永続化ã™ã‚‹(&amp;M)</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>&amp;Read-only</source>
<translation type="obsolete">読ã¿è¾¼ã¿å°‚用(&amp;R)</translation>
</message>
<message>
- <location filename="../src/VBoxAboutDlg.cpp" line="109"/>
<source>When checked, the guest OS will not be able to write to the specified shared folder.</source>
<translation type="obsolete">ゲストOSã‹ã‚‰æŒ‡å®šã•れãŸå…±æœ‰ãƒ•ォルダã¸ã®æ›¸ãè¾¼ã¿ã‚’ç¦æ­¢ã—ã¾ã™ã€‚</translation>
</message>
@@ -6781,6 +6945,7 @@ Version %1</source>
<translation>ãƒãƒ¼ã‚¸ãƒ§ãƒ³</translation>
</message>
<message>
+ <location filename="../src/widgets/VBoxApplianceEditorWgt.cpp" line="200"/>
<location filename="../src/widgets/VBoxApplianceEditorWgt.cpp" line="851"/>
<source>Description</source>
<translation>説明</translation>
@@ -6861,13 +7026,11 @@ Version %1</source>
<translation>䏿˜Žãªãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢é …ç›®</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.cpp" line="215"/>
<source>MB</source>
<comment>size suffix MBytes=1024 KBytes</comment>
<translation type="obsolete">MB</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.cpp" line="215"/>
<source>MB</source>
<translation type="obsolete">MB</translation>
</message>
@@ -6877,7 +7040,6 @@ Version %1</source>
<translation>&lt;b&gt;å…ƒã®å€¤:&lt;/b&gt; %1</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.cpp" line="249"/>
<source>MB</source>
<comment>size suffix MBytes=1024KBytes</comment>
<translation type="obsolete">MB</translation>
@@ -6888,7 +7050,17 @@ Version %1</source>
<translation>æ§‹æˆ</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
+ <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="43"/>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="46"/>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="65"/>
<source>Warnings:</source>
<translation>警告:</translation>
</message>
@@ -6896,57 +7068,46 @@ Version %1</source>
<context>
<name>VBoxCloseVMDlg</name>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Close Virtual Machine</source>
<translation type="obsolete">仮想マシンを閉ã˜ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>You want to:</source>
<translation type="obsolete">æ“ä½œã‚’é¸æŠž:</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Save the machine state</source>
<translation type="obsolete">仮想マシンã®çŠ¶æ…‹ã‚’ä¿å­˜(&amp;S)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Power off the machine</source>
<translation type="obsolete">仮想マシンã®é›»æºã‚ªãƒ•(&amp;P)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Revert to the current snapshot</source>
<translation type="obsolete">最新ã®ã‚¹ãƒŠãƒƒãƒ—ショットã®çŠ¶æ…‹ã«æˆ»ã™(&amp;R)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Revert the machine state to the state stored in the current snapshot</source>
<translation type="obsolete">仮想マシンã®çŠ¶æ…‹ã‚’æœ€æ–°ã®ã‚¹ãƒŠãƒƒãƒ—ショットã«ä¿å­˜ã•れã¦ã„ã‚‹çŠ¶æ…‹ã«æˆ»ã™</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Help</source>
<translation type="obsolete">ヘルプ</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>F1</source>
<translation type="obsolete">F1</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;OK</source>
<translation type="obsolete">OK(&amp;O)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p&gt;Saves the current execution state of the virtual machine to the physical hard disk of the host PC.&lt;/p&gt;
&lt;p&gt;Next time this machine is started, it will be restored from the saved state and continue execution from the same place you saved it at, which will let you continue your work immediately.&lt;/p&gt;
&lt;p&gt;Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.&lt;/p&gt;</source>
@@ -6956,12 +7117,10 @@ Version %1</source>
&lt;p&gt;注:ゲストOSã®ç¨®åˆ¥ã¨ä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ãŸãƒ¡ãƒ¢ãƒªé‡ã«ã‚ˆã£ã¦ã¯ã€ä»®æƒ³ãƒžã‚·ãƒ³ã®çŠ¶æ…‹ã®ä¿å­˜ã«é•·ã„時間を必è¦ã¨ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>S&amp;end the shutdown signal</source>
<translation type="obsolete">シャットダウン シグナルé€ä¿¡(&amp;E)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p&gt;Sends the ACPI Power Button press event to the virtual machine.&lt;/p&gt;
&lt;p&gt;Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.&lt;/p&gt;
&lt;p&gt;If the machine doesn&apos;t respond to this action then the guest operating system may be misconfigured or doesn&apos;t understand ACPI Power Button events at all. In this case you should select the &lt;b&gt;Power off the machine&lt;/b&gt; action to stop virtual machine execution.&lt;/p&gt;</source>
@@ -6970,39 +7129,32 @@ Version %1</source>
&lt;p&gt;仮想マシンãŒã“ã®å‹•作ã«å応ã—ãªã„ãªã‚‰ã°ã€ã‚²ã‚¹ãƒˆOSã®æ§‹æˆã«èª¤ã‚ŠãŒã‚ã‚‹ã‹ã€é›»æºãƒœã‚¿ãƒ³ オフã®ACPIイベントã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。ã“ã®å ´åˆã€ä»®æƒ³ãƒžã‚·ãƒ³ã®å®Ÿè¡Œã‚’åœæ­¢ã™ã‚‹ã«ã¯&lt;b&gt;[仮想マシンã®é›»æºã‚ªãƒ•]&lt;/b&gt;ã‚’é¸æŠžã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p&gt;Turns off the virtual machine.&lt;/p&gt;
&lt;p&gt;Note that this action will stop machine execution immediately so that the guest operating system running inside it will not be able to perform a clean shutdown procedure which may result in &lt;i&gt;data loss&lt;/i&gt; inside the virtual machine. Selecting this action is recommended only if the virtual machine does not respond to the &lt;b&gt;Send the shutdown signal&lt;/b&gt; action.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想マシンã®é›»æºã‚’切りã¾ã™ã€‚&lt;/p&gt;
&lt;p&gt;注:ã“ã®å‹•作ã¯ã€ã‚²ã‚¹ãƒˆOSã‚’æ­£ã—ã終了ã™ã‚‹ã“ã¨ãªãã€ç›´ã¡ã«ä»®æƒ³ãƒžã‚·ãƒ³ã®å®Ÿè¡Œã‚’åœæ­¢ã—ã¾ã™ã€‚仮想マシン内ã®&lt;i&gt;ãƒ‡ãƒ¼ã‚¿ã®æå¤±&lt;/i&gt;ã‚’æ‹›ãã‹ã‚‚ã—れã¾ã›ã‚“。ã“ã®å‹•作ã¯ã€ä»®æƒ³ãƒžã‚·ãƒ³ãŒ&lt;b&gt;[シャットダウン シグナルé€ä¿¡]&lt;/b&gt;ã«å応ã—ãªã„å ´åˆã®ã¿é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p&gt;When checked, the machine will be returned to the state stored in the current snapshot after it is turned off. This is useful if you are sure that you want to discard the results of your last sessions and start again at that snapshot.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想マシンをオフã«ã—ãŸå¾Œã€ç¾åœ¨ã®ã‚¹ãƒŠãƒƒãƒ—ショットã«ä¿å­˜ã•れãŸçŠ¶æ…‹ã«å¾©å…ƒã—ã¾ã™ã€‚ã“れã¯ç›´å‰ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®çŠ¶æ…‹ã‚’ç ´æ£„ã—ã€å·®ç¾åœ¨ã®ã‚¹ãƒŠãƒƒãƒ—ショットã®çŠ¶æ…‹ã«æˆ»ã‚ŠãŸã„å ´åˆã«å½¹ç«‹ã¡ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p&gt;Saves the current execution state of the virtual machine to the physical hard disk of the host PC.&lt;/p&gt;&lt;p&gt;Next time this machine is started, it will be restored from the saved state and continue execution from the same place you saved it at, which will let you continue your work immediately.&lt;/p&gt;&lt;p&gt;Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;ç¾åœ¨å®Ÿè¡Œä¸­ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®çŠ¶æ…‹ã‚’ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã®ç‰©ç†ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã«ä¿å­˜ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®æ¬¡å›žã®èµ·å‹•時ã€ã™ãã«ä½œæ¥­ã‚’å†é–‹ã§ãるよã†ã«ä»®æƒ³ãƒžã‚·ãƒ³ã¯ä¿å­˜ã—ãŸçŠ¶æ…‹ã‚’å¾©å…ƒã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;注:ゲストOSã®ç¨®åˆ¥ã¨ä»®æƒ³ãƒžã‚·ãƒ³ã«å‰²ã‚Šå½“ã¦ãŸãƒ¡ãƒ¢ãƒªé‡ã«ã‚ˆã£ã¦ã¯ã€ä»®æƒ³ãƒžã‚·ãƒ³ã®çŠ¶æ…‹ã®ä¿å­˜ã«é•·ã„時間を必è¦ã¨ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p&gt;Sends the ACPI Power Button press event to the virtual machine.&lt;/p&gt;&lt;p&gt;Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.&lt;/p&gt;&lt;p&gt;If the machine doesn&apos;t respond to this action then the guest operating system may be misconfigured or doesn&apos;t understand ACPI Power Button events at all. In this case you should select the &lt;b&gt;Power off the machine&lt;/b&gt; action to stop virtual machine execution.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想マシンã«é›»æºãƒœã‚¿ãƒ³ オフã®ACPIイベントをé€ä¿¡ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;通常ã€ä»®æƒ³ãƒžã‚·ãƒ³å†…ã§å‹•作ã™ã‚‹ã‚²ã‚¹ãƒˆOSã¯ã€ã“ã®ã‚¤ãƒ™ãƒ³ãƒˆã‚’検出ã—ã¦æ­£ã—ã„終了処ç†ã‚’実行ã—ã¾ã™ã€‚ゲストOSã§å‹•作ã™ã‚‹ã™ã¹ã¦ã®ã‚¢ãƒ—リケーションãŒãƒ‡ãƒ¼ã‚¿ã¨çŠ¶æ…‹ã‚’ä¿å­˜ã™ã‚‹ã“ã¨ãŒã§ãã‚‹ã®ã§ã€ä»®æƒ³ãƒžã‚·ãƒ³ã®é›»æºã‚’切るãŠå‹§ã‚ã®æ–¹æ³•ã§ã™ã€‚&lt;/p&gt;&lt;p&gt;仮想マシンãŒã“ã®å‹•作ã«å応ã—ãªã„ãªã‚‰ã°ã€ã‚²ã‚¹ãƒˆOSã®æ§‹æˆã«èª¤ã‚ŠãŒã‚ã‚‹ã‹ã€é›»æºãƒœã‚¿ãƒ³ オフã®ACPIイベントã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。ã“ã®å ´åˆã€ä»®æƒ³ãƒžã‚·ãƒ³ã®å®Ÿè¡Œã‚’åœæ­¢ã™ã‚‹ã«ã¯&lt;b&gt;[仮想マシンã®é›»æºã‚ªãƒ•]&lt;/b&gt;ã‚’é¸æŠžã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p&gt;Turns off the virtual machine.&lt;/p&gt;&lt;p&gt;Note that this action will stop machine execution immediately so that the guest operating system running inside it will not be able to perform a clean shutdown procedure which may result in &lt;i&gt;data loss&lt;/i&gt; inside the virtual machine. Selecting this action is recommended only if the virtual machine does not respond to the &lt;b&gt;Send the shutdown signal&lt;/b&gt; action.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想マシンã®é›»æºã‚’切りã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;注:ã“ã®å‹•作ã¯ã€ã‚²ã‚¹ãƒˆOSã‚’æ­£ã—ã終了ã™ã‚‹ã“ã¨ãªãã€ç›´ã¡ã«ä»®æƒ³ãƒžã‚·ãƒ³ã®å®Ÿè¡Œã‚’åœæ­¢ã—ã¾ã™ã€‚仮想マシン内ã®&lt;i&gt;ãƒ‡ãƒ¼ã‚¿ã®æå¤±&lt;/i&gt;ã‚’æ‹›ãã‹ã‚‚ã—れã¾ã›ã‚“。ã“ã®å‹•作ã¯ã€ä»®æƒ³ãƒžã‚·ãƒ³ãŒ&lt;b&gt;[シャットダウン シグナルé€ä¿¡]&lt;/b&gt;ã«å応ã—ãªã„å ´åˆã®ã¿é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Restore the machine state stored in the current snapshot</source>
<translation type="obsolete">ç¾åœ¨ã®ã‚¹ãƒŠãƒƒãƒ—ショットã®çŠ¶æ…‹ã«ãƒžã‚·ãƒ³ã‚’復元ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Restore current snapshot &apos;%1&apos;</source>
<translation type="obsolete">ç¾åœ¨ã®ã‚¹ãƒŠãƒƒãƒ—ショット &apos;%1&apos; ã«å¾©å…ƒ(&amp;R)</translation>
</message>
@@ -7010,749 +7162,608 @@ Version %1</source>
<context>
<name>VBoxConsoleWnd</name>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>VirtualBox OSE</source>
<translation type="obsolete">VirtualBox OSE</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Fullscreen Mode</source>
<translation type="obsolete">フルスクリーンモード(&amp;F)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Switch to fullscreen mode</source>
<translation type="obsolete">フルスクリーンモードã«åˆ‡ã‚Šæ›¿ãˆã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Mouse Integration</source>
<comment>enable/disable...</comment>
<translation type="obsolete">マウス統åˆ</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Auto-resize Guest Display</source>
<comment>enable/disable...</comment>
<translation type="obsolete">ゲストOSã®ç”»é¢ã‚’自動的ã«ãƒªã‚µã‚¤ã‚ºã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Auto-resize &amp;Guest Display</source>
<translation type="obsolete">ゲストOSã®ç”»é¢ã‚’自動リサイズ(&amp;G)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Automatically resize the guest display when the window is resized (requires Guest Additions)</source>
<translation type="obsolete">ウィンドウをリサイズã—ãŸã¨ãã€ã‚²ã‚¹ãƒˆOSã®ç”»é¢ã‚’自動的ã«ãƒªã‚µã‚¤ã‚ºã™ã‚‹(Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Adjust Window Size</source>
<translation type="obsolete">ウィンドウã®ã‚µã‚¤ã‚ºã‚’調整(&amp;A)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Adjust window size and position to best fit the guest display</source>
<translation type="obsolete">ゲストOSã®ç”»é¢ã«åˆã‚ã›ã¦ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã®ã‚µã‚¤ã‚ºã¨ä½ç½®ã‚’調整ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Insert Ctrl-Alt-Del</source>
<translation type="obsolete">Ctrl-Alt-Delã‚’é€ä¿¡(&amp;I)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Send the Ctrl-Alt-Del sequence to the virtual machine</source>
<translation type="obsolete">仮想マシンã«Ctrl-Alt-Delシーケンスをé€ä¿¡ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Insert Ctrl-Alt-Backspace</source>
<translation type="obsolete">Ctrl-Alt-Backspaceã‚’é€ä¿¡(&amp;I)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Send the Ctrl-Alt-Backspace sequence to the virtual machine</source>
<translation type="obsolete">仮想マシンã«Ctrl-Alt-Backspaceシーケンスをé€ä¿¡ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Reset</source>
<translation type="obsolete">リセット(&amp;R)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Reset the virtual machine</source>
<translation type="obsolete">仮想マシンをリセットã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>ACPI S&amp;hutdown</source>
<translation type="obsolete">ACPI シャットダウン(&amp;H)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Send the ACPI Power Button press event to the virtual machine</source>
<translation type="obsolete">仮想マシンã«é›»æºãƒœã‚¿ãƒ³ オフã®ACPIイベントをé€ä¿¡ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Close...</source>
<translation type="obsolete">é–‰ã˜ã‚‹(&amp;C)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Close the virtual machine</source>
<translation type="obsolete">仮想マシンを閉ã˜ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Take &amp;Snapshot...</source>
<translation type="obsolete">スナップショット作æˆ(&amp;S)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Take a snapshot of the virtual machine</source>
<translation type="obsolete">仮想マシンã®ã‚¹ãƒŠãƒƒãƒ—ショットを作æˆã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Floppy Image...</source>
<translation type="obsolete">フロッピーイメージ(&amp;F)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Mount a floppy image file</source>
<translation type="obsolete">フロッピーイメージファイルをマウントã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Unmount F&amp;loppy</source>
<translation type="obsolete">フロッピーã®ãƒžã‚¦ãƒ³ãƒˆè§£é™¤(&amp;L)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Unmount the currently mounted floppy media</source>
<translation type="obsolete">マウント中ã®ãƒ•ロッピーメディアをマウント解除ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;CD/DVD-ROM Image...</source>
<translation type="obsolete">CD/DVD-ROMイメージ(&amp;C)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Mount a CD/DVD-ROM image file</source>
<translation type="obsolete">CD/DVD-ROMイメージファイルをマウントã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Unmount C&amp;D/DVD-ROM</source>
<translation type="obsolete">CD/DVD-ROMã®ãƒžã‚¦ãƒ³ãƒˆè§£é™¤(&amp;D)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Unmount the currently mounted CD/DVD-ROM media</source>
<translation type="obsolete">マウント中ã®CD/DVDメディアをマウント解除ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Remote Desktop (RDP) Server</source>
<comment>enable/disable...</comment>
<translation type="obsolete">リモートデスクトップ(RDP)サーãƒãƒ¼</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Remote Dis&amp;play</source>
<translation type="obsolete">リモートディスプレイ(&amp;P)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Enable or disable remote desktop (RDP) connections to this machine</source>
<translation type="obsolete">ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã¸ã®ãƒªãƒ¢ãƒ¼ãƒˆãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—(RDP)接続を有効化ã¾ãŸã¯ç„¡åŠ¹åŒ–</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Shared Folders...</source>
<translation type="obsolete">共有フォルダ(&amp;S)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Create or modify shared folders</source>
<translation type="obsolete">共有フォルダ設定ダイアログを開ã</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Install Guest Additions...</source>
<translation type="obsolete">Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«(&amp;I)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Mount the Guest Additions installation image</source>
<translation type="obsolete">Guest Additions インストールイメージをマウントã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;VirtualBox Web Site...</source>
<translation type="obsolete">VirtualBox Webサイト(&amp;V)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Open the browser and go to the VirtualBox product web site</source>
<translation type="obsolete">Webブラウザã§VirtualBox製å“ã®Webサイトを開ã</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;About VirtualBox...</source>
<translation type="obsolete">VirtualBox ã«ã¤ã„ã¦(&amp;A)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Show a dialog with product information</source>
<translation type="obsolete">è£½å“æƒ…報ダイアログを表示ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Reset All Warnings</source>
<translation type="obsolete">ã™ã¹ã¦ã®è­¦å‘Šã‚’リセット(&amp;R)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Go back to showing all suppressed warnings and messages</source>
<translation type="obsolete">ã™ã¹ã¦ã®æŠ‘æ­¢ã•れãŸè­¦å‘Šã¨ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’å†åº¦è¡¨ç¤ºã•ã›ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Mount &amp;Floppy</source>
<translation type="obsolete">フロッピーã®ãƒžã‚¦ãƒ³ãƒˆ(&amp;F)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Mount &amp;CD/DVD-ROM</source>
<translation type="obsolete">CD/DVD-ROMã®ãƒžã‚¦ãƒ³ãƒˆ(&amp;C)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;USB Devices</source>
<translation type="obsolete">USB デãƒã‚¤ã‚¹(&amp;U)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Devices</source>
<translation type="obsolete">デãƒã‚¤ã‚¹(&amp;D)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>De&amp;bug</source>
<translation type="obsolete">デãƒãƒƒã‚°(&amp;B)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Help</source>
<translation type="obsolete">ヘルプ(&amp;H)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Indicates whether the guest display auto-resize function is On (&lt;img src=auto_resize_on_16px.png/&gt;) or Off (&lt;img src=auto_resize_off_16px.png/&gt;). Note that this function requires Guest Additions to be installed in the guest OS.</source>
<translation type="obsolete">ゲストOSã®ç”»é¢ã®è‡ªå‹•ãƒªã‚µã‚¤ã‚ºæ©Ÿèƒ½ãŒæœ‰åйãªã¨ã(&lt;img src=auto_resize_on_16px.png/&gt;)ã‚’ã€ç„¡åйãªã¨ã(&lt;img src=auto_resize_off_16px.png/&gt;)を表示ã—ã¾ã™ã€‚注:本機能ã®åˆ©ç”¨ã«ã¯ã‚²ã‚¹ãƒˆOSã« Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚
</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Indicates whether the host mouse pointer is captured by the guest OS:&lt;br&gt;&lt;nobr&gt;&lt;img src=mouse_disabled_16px.png/&gt;&amp;nbsp;&amp;nbsp;pointer is not captured&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=mouse_16px.png/&gt;&amp;nbsp;&amp;nbsp;pointer is captured&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=mouse_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;mouse integration (MI) is On&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=mouse_can_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;MI is Off, pointer is captured&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=mouse_can_seamless_uncaptured_16px.png/&gt;&amp;nbsp;&amp;nbsp;MI is Off, pointer is not captured&lt;/nobr&gt;&lt;br&gt;Note that the mouse integration feature requires Guest Additions to be installed in the guest OS.</source>
<translation type="obsolete">ホスト マウスãƒã‚¤ãƒ³ã‚¿ã®ã‚­ãƒ£ãƒ—ãƒãƒ£çŠ¶æ…‹ã‚’è¡¨ç¤º:&lt;br&gt;&lt;nobr&gt;&lt;img src=mouse_disabled_16px.png/&gt;&amp;nbsp;&amp;nbsp;キャプãƒãƒ£ã•れã¦ã„ã¾ã›ã‚“&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=mouse_16px.png/&gt;&amp;nbsp;&amp;nbsp;キャプãƒãƒ£ã•れã¦ã„ã¾ã™&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=mouse_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;マウス統åˆã¯æœ‰åйã§ã™&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=mouse_can_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;マウス統åˆã¯ç„¡åйã€ã‚­ãƒ£ãƒ—ãƒãƒ£ã•れã¦ã„ã¾ã™&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=mouse_can_seamless_uncaptured_16px.png/&gt;&amp;nbsp;&amp;nbsp;マウス統åˆã¯ç„¡åйã€ã‚­ãƒ£ãƒ—ãƒãƒ£ã•れã¦ã„ã¾ã›ã‚“&lt;/nobr&gt;&lt;br&gt; æ³¨ï¼šãƒžã‚¦ã‚¹çµ±åˆæ©Ÿèƒ½ã®åˆ©ç”¨ã«ã¯ã‚²ã‚¹ãƒˆOSã« Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚
</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Shows the currently assigned Host key.&lt;br&gt;This key, when pressed alone, toggles the 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 type="obsolete">ç¾åœ¨å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„るホストキーを表示ã—ã¾ã™ã€‚&lt;br&gt;ホストキーをå˜ç‹¬ã§æŠ¼ã™ã¨ã€ã‚­ãƒ¼ãƒœãƒ¼ãƒˆã¨ãƒžã‚¦ã‚¹ã®åˆ¶å¾¡ãŒåˆ‡ã‚Šæ›¿ã‚りã¾ã™ã€‚ã¾ãŸã€ä»–ã®ã‚­ãƒ¼ã¨åˆã‚ã›ã¦ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ ã‚·ãƒ§ãƒ¼ãƒˆã‚«ãƒƒãƒˆã®æ“作ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;hr&gt;The VRDP Server is listening on port %1</source>
<translation type="obsolete">&lt;hr&gt;VRDPサーãƒãƒ¼ã¯ãƒãƒ¼ãƒˆ %1 ã‚’å¾…ã¡å—ã‘ã—ã¦ã„ã¾ã™</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Pause</source>
<translation type="obsolete">ä¸€æ™‚åœæ­¢(&amp;P)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Suspend the execution of the virtual machine</source>
<translation type="obsolete">仮想マシンã®å®Ÿè¡Œã‚’ä¸€æ™‚åœæ­¢ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>R&amp;esume</source>
<translation type="obsolete">å†é–‹(&amp;E)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Resume the execution of the virtual machine</source>
<translation type="obsolete">仮想マシンã®å®Ÿè¡Œã‚’å†é–‹ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Disable &amp;Mouse Integration</source>
<translation type="obsolete">マウス統åˆã‚’無効化(&amp;M)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Temporarily disable host mouse pointer integration</source>
<translation type="obsolete">一時的ã«ãƒ›ã‚¹ãƒˆ マウスãƒã‚¤ãƒ³ã‚¿ã®çµ±åˆæ©Ÿèƒ½ã‚’無効化</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Enable &amp;Mouse Integration</source>
<translation type="obsolete">マウス統åˆã‚’有効化(&amp;M)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Enable temporarily disabled host mouse pointer integration</source>
<translation type="obsolete">一時的ã«ç„¡åŠ¹åŒ–ã—ãŸãƒ›ã‚¹ãƒˆ マウスãƒã‚¤ãƒ³ã‚¿ã®çµ±åˆæ©Ÿèƒ½ã‚’有効化</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Snapshot %1</source>
<translation type="obsolete">スナップショット %1</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Host Drive </source>
<translation type="obsolete">ホスト ドライブ</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Machine</source>
<translation type="obsolete">仮想マシン(&amp;M)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Network Adapters</source>
<translation type="obsolete">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタ(&amp;N)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Adapter %1</source>
<comment>network</comment>
<translation type="obsolete">アダプタ %1</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Mount the selected physical drive of the host PC</source>
<comment>Floppy tip</comment>
<translation type="obsolete">é¸æŠžã•れãŸãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã®ç‰©ç†ãƒ‰ãƒ©ã‚¤ãƒ–をマウントã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Mount the selected physical drive of the host PC</source>
<comment>CD/DVD tip</comment>
<translation type="obsolete">é¸æŠžã•れãŸãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã®ç‰©ç†ãƒ‰ãƒ©ã‚¤ãƒ–をマウントã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Disconnect the cable from the selected virtual network adapter</source>
<translation type="obsolete">é¸æŠžã•れãŸä»®æƒ³ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタã‹ã‚‰ã‚±ãƒ¼ãƒ–ルを切断ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Connect the cable to the selected virtual network adapter</source>
<translation type="obsolete">é¸æŠžã•れãŸä»®æƒ³ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタã«ã‚±ãƒ¼ãƒ–ルを接続ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Seam&amp;less Mode</source>
<translation type="obsolete">シームレスモード(&amp;L)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Switch to seamless desktop integration mode</source>
<translation type="obsolete">シームレスモードã«åˆ‡ã‚Šæ›¿ãˆã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Indicates whether the keyboard is captured by the guest OS (&lt;img src=hostkey_captured_16px.png/&gt;) or not (&lt;img src=hostkey_16px.png/&gt;).</source>
<translation type="obsolete">キーボードãŒã‚²ã‚¹ãƒˆOSã«ã‚­ãƒ£ãƒ—ãƒãƒ£ã•れã¦ã„ã‚‹ã¨ã(&lt;img src=hostkey_captured_16px.png/&gt;)ã‚’ã€ç„¡åйãªã¨ã(&lt;img src=hostkey_16px.png/&gt;)を表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;qt&gt;&lt;nobr&gt;Indicates the activity of the floppy media:&lt;/nobr&gt;%1&lt;/qt&gt;</source>
<comment>Floppy tooltip</comment>
<translation type="obsolete">&lt;qt&gt;&lt;nobr&gt;フロッピーメディアã®çŠ¶æ…‹ã‚’è¡¨ç¤º:&lt;/nobr&gt;%1&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;Host Drive&lt;/b&gt;: %1&lt;/nobr&gt;</source>
<comment>Floppy tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;ホスト ドライブ&lt;/b&gt;: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;Image&lt;/b&gt;: %1&lt;/nobr&gt;</source>
<comment>Floppy tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;イメージ&lt;/b&gt;: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;No media mounted&lt;/b&gt;&lt;/nobr&gt;</source>
<comment>Floppy tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;メディアãŒãƒžã‚¦ãƒ³ãƒˆã•れã¦ã„ãªã„&lt;/b&gt;&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;qt&gt;&lt;nobr&gt;Indicates the activity of the CD/DVD-ROM media:&lt;/nobr&gt;%1&lt;/qt&gt;</source>
<comment>DVD-ROM tooltip</comment>
<translation type="obsolete">&lt;qt&gt;&lt;nobr&gt;CD/DVD-ROMメディアã®çŠ¶æ…‹ã‚’è¡¨ç¤º:&lt;/nobr&gt;%1&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;Host Drive&lt;/b&gt;: %1&lt;/nobr&gt;</source>
<comment>DVD-ROM tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;ホスト ドライブ&lt;/b&gt;: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;Image&lt;/b&gt;: %1&lt;/nobr&gt;</source>
<comment>DVD-ROM tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;イメージ&lt;/b&gt;: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;No media mounted&lt;/b&gt;&lt;/nobr&gt;</source>
<comment>DVD-ROM tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;メディアãŒãƒžã‚¦ãƒ³ãƒˆã•れã¦ã„ãªã„&lt;/b&gt;&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;qt&gt;&lt;nobr&gt;Indicates activity on the the virtual hard disks:&lt;/nobr&gt;%1&lt;/qt&gt;</source>
<comment>HDD tooltip</comment>
<translation type="obsolete">&lt;qt&gt;&lt;nobr&gt;仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®çŠ¶æ…‹ã‚’è¡¨ç¤º:&lt;/nobr&gt;%1&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;No hard disks attached&lt;/b&gt;&lt;/nobr&gt;</source>
<comment>HDD tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ãªã„&lt;/b&gt;&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;qt&gt;&lt;nobr&gt;Indicates the activity of the network interfaces:&lt;/nobr&gt;%1&lt;/qt&gt;</source>
<comment>Network adapters tooltip</comment>
<translation type="obsolete">&lt;qt&gt;&lt;nobr&gt;ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ インターフェースã®çŠ¶æ…‹ã‚’è¡¨ç¤º:&lt;/nobr&gt;%1&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;Adapter %1 (%2)&lt;/b&gt;: cable %3&lt;/nobr&gt;</source>
<comment>Network adapters tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;アダプタ %1 (%2)&lt;/b&gt;:ケーブル %3&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>connected</source>
<comment>Network adapters tooltip</comment>
<translation type="obsolete">接続</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>disconnected</source>
<comment>Network adapters tooltip</comment>
<translation type="obsolete">切断</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;All network adapters are disabled&lt;/b&gt;&lt;/nobr&gt;</source>
<comment>Network adapters tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;ã™ã¹ã¦ã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタãŒç„¡åй&lt;/b&gt;&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;qt&gt;&lt;nobr&gt;Indicates the activity of the attached USB devices:&lt;/nobr&gt;%1&lt;/qt&gt;</source>
<comment>USB device tooltip</comment>
<translation type="obsolete">&lt;qt&gt;&lt;nobr&gt;USB デãƒã‚¤ã‚¹ã®çŠ¶æ…‹ã‚’è¡¨ç¤º:&lt;/nobr&gt;%1&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;No USB devices attached&lt;/b&gt;&lt;/nobr&gt;</source>
<comment>USB device tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;USB デãƒã‚¤ã‚¹ãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ãªã„&lt;/b&gt;&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;USB Controller is disabled&lt;/b&gt;&lt;/nobr&gt;</source>
<comment>USB device tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;USB コントローラãŒç„¡åй&lt;/b&gt;&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Indicates whether the Remote Display (VRDP Server) is enabled (&lt;img src=vrdp_16px.png/&gt;) or not (&lt;img src=vrdp_disabled_16px.png/&gt;).</source>
<translation type="obsolete">リモートディスプレイ(VRDPサーãƒ)æ©Ÿèƒ½ãŒæœ‰åйãªã¨ã(&lt;img src=vrdp_16px.png/&gt;) ã‚’ã€ç„¡åйãªã¨ã (&lt;img src=vrdp_disabled_16px.png/&gt;)を表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;qt&gt;&lt;nobr&gt;Indicates the activity of the machineof the machine&apos;sapos;s shared folders: shared folders:&lt;/nobr&gt;%1&lt;/qt&gt;</source>
<comment>Shared folders tooltip</comment>
<translation type="obsolete">&lt;qt&gt;&lt;nobr&gt;共有フォルダã®çŠ¶æ…‹ã‚’è¡¨ç¤º:&lt;/nobr&gt;%1&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;No shared folders&lt;/b&gt;&lt;/nobr&gt;</source>
<comment>Shared folders tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;共有フォルダãªã—&lt;/b&gt;&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Contents...</source>
<translation type="obsolete">ヘルプを表示(&amp;C)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Show the online help contents</source>
<translation type="obsolete">オンラインヘルプを表示</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>R&amp;egister VirtualBox...</source>
<translation type="obsolete">VirtualBox を登録(&amp;E)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Open VirtualBox registration form</source>
<translation type="obsolete">VirtualBox 登録フォームを開ã</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Session I&amp;nformation Dialog</source>
<translation type="obsolete">セッション情報ダイアログ(&amp;N)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Show Session Information Dialog</source>
<translation type="obsolete">セッション情報ダイアログを表示</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Statistics...</source>
<comment>debug action</comment>
<translation type="obsolete">統計(&amp;S)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Command Line...</source>
<comment>debug action</comment>
<translation type="obsolete">コマンドライン(&amp;C)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Logging...</source>
<comment>debug action</comment>
<translation type="obsolete">ログå–å¾—(&amp;L)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Indicates whether the guest display auto-resize function is On (&lt;img src=:/auto_resize_on_16px.png/&gt;) or Off (&lt;img src=:/auto_resize_off_16px.png/&gt;). Note that this function requires Guest Additions to be installed in the guest OS.</source>
<translation type="obsolete">ゲストOSã®ç”»é¢ã®è‡ªå‹•ãƒªã‚µã‚¤ã‚ºæ©Ÿèƒ½ãŒæœ‰åйãªã¨ã(&lt;img src=:/auto_resize_on_16px.png/&gt;)ã‚’ã€ç„¡åйãªã¨ã(&lt;img src=:/auto_resize_off_16px.png/&gt;)を表示ã—ã¾ã™ã€‚注:本機能ã®åˆ©ç”¨ã«ã¯ã‚²ã‚¹ãƒˆOSã« Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Indicates whether the host mouse pointer is captured by the guest OS:&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_disabled_16px.png/&gt;&amp;nbsp;&amp;nbsp;pointer is not captured&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_16px.png/&gt;&amp;nbsp;&amp;nbsp;pointer is captured&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;mouse integration (MI) is On&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;MI is Off, pointer is captured&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_uncaptured_16px.png/&gt;&amp;nbsp;&amp;nbsp;MI is Off, pointer is not captured&lt;/nobr&gt;&lt;br&gt;Note that the mouse integration feature requires Guest Additions to be installed in the guest OS.</source>
<translation type="obsolete">ホスト マウスãƒã‚¤ãƒ³ã‚¿ã®ã‚­ãƒ£ãƒ—ãƒãƒ£çŠ¶æ…‹ã‚’è¡¨ç¤º:&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_disabled_16px.png/&gt;&amp;nbsp;&amp;nbsp;キャプãƒãƒ£ã•れã¦ã„ã¾ã›ã‚“&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_16px.png/&gt;&amp;nbsp;&amp;nbsp;キャプãƒãƒ£ã•れã¦ã„ã¾ã™&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;マウス統åˆã¯æœ‰åйã§ã™&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_16px.png/&gt;&amp;nbsp;&amp;nbsp;マウス統åˆã¯ç„¡åйã€ã‚­ãƒ£ãƒ—ãƒãƒ£ã•れã¦ã„ã¾ã™&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;img src=:/mouse_can_seamless_uncaptured_16px.png/&gt;&amp;nbsp;&amp;nbsp;マウス統åˆã¯ç„¡åйã€ã‚­ãƒ£ãƒ—ãƒãƒ£ã•れã¦ã„ã¾ã›ã‚“&lt;/nobr&gt;&lt;br&gt; æ³¨ï¼šãƒžã‚¦ã‚¹çµ±åˆæ©Ÿèƒ½ã®åˆ©ç”¨ã«ã¯ã‚²ã‚¹ãƒˆOSã« Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Indicates whether the keyboard is captured by the guest OS (&lt;img src=:/hostkey_captured_16px.png/&gt;) or not (&lt;img src=:/hostkey_16px.png/&gt;).</source>
<translation type="obsolete">キーボードãŒã‚²ã‚¹ãƒˆOSã«ã‚­ãƒ£ãƒ—ãƒãƒ£ã•れã¦ã„ã‚‹ã¨ã(&lt;img src=:/hostkey_captured_16px.png/&gt;ã‚’ã€ç„¡åйãªã¨ã(&lt;img src=:/hostkey_16px.png/&gt;)を表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Indicates whether the Remote Display (VRDP Server) is enabled (&lt;img src=:/vrdp_16px.png/&gt;) or not (&lt;img src=:/vrdp_disabled_16px.png/&gt;).</source>
<translation type="obsolete">リモートディスプレイ(VRDPサーãƒãƒ¼)æ©Ÿèƒ½ãŒæœ‰åйãªã¨ã(&lt;img src=:/vrdp_16px.png/&gt;) ã‚’ã€ç„¡åйãªã¨ã (&lt;img src=:/vrdp_disabled_16px.png/&gt;)を表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<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 type="obsolete">ç¾åœ¨å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„るホストキーを表示ã—ã¾ã™ã€‚&lt;br&gt;ホストキーをå˜ç‹¬ã§æŠ¼ã™ã¨ã€ã‚­ãƒ¼ãƒœãƒ¼ãƒˆã¨ãƒžã‚¦ã‚¹ã®åˆ¶å¾¡ãŒåˆ‡ã‚Šæ›¿ã‚りã¾ã™ã€‚ã¾ãŸã€ä»–ã®ã‚­ãƒ¼ã¨åˆã‚ã›ã¦ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ ã‚·ãƒ§ãƒ¼ãƒˆã‚«ãƒƒãƒˆã®æ“作ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Sun VirtualBox</source>
<translation type="obsolete">Sun VirtualBox</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation type="obsolete">仮想マシンã§ä½¿ç”¨ã•ã‚Œã‚‹ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½ã®çŠ¶æ…‹ã‚’è¡¨ç¤º:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source> EXPERIMENTAL build %1r%2 - %3</source>
<translation type="obsolete">試験的ビルド %1r%2 - %3</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;CD/DVD Devices</source>
<translation type="obsolete">CD/DVD デãƒã‚¤ã‚¹(&amp;C)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Floppy Devices</source>
<translation type="obsolete">フロッピー デãƒã‚¤ã‚¹(&amp;F)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Network Adapters...</source>
<translation type="obsolete">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタ(&amp;N)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Change the settings of network adapters</source>
<translation type="obsolete">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタã®è¨­å®šå¤‰æ›´</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Remote Display</source>
<translation type="obsolete">リモートディスプレイ(&amp;R)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Dock Icon</source>
<translation type="obsolete">ドック アイコン</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Show Application Icon</source>
<translation type="obsolete">アプリケーション アイコンを表示</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Show Monitor Preview</source>
<translation type="obsolete">ディスプレイã®ãƒ—レビューを表示</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>More CD/DVD Images...</source>
<translation type="obsolete">CD/DVD イメージã®è¿½åŠ ...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Unmount CD/DVD Device</source>
<translation type="obsolete">CD/DVD デãƒã‚¤ã‚¹ã®ãƒžã‚¦ãƒ³ãƒˆè§£é™¤</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>More Floppy Images...</source>
<translation type="obsolete">フロッピー イメージã®è¿½åŠ ...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Unmount Floppy Device</source>
<translation type="obsolete">フロッピー デãƒã‚¤ã‚¹ã®ãƒžã‚¦ãƒ³ãƒˆè§£é™¤</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>No CD/DVD Devices Attached</source>
<translation type="obsolete">CD/DVD デãƒã‚¤ã‚¹ 未割り当ã¦</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>No Floppy Devices Attached</source>
<translation type="obsolete">フロッピー デãƒã‚¤ã‚¹ 未割り当ã¦</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p style=&apos;white-space:pre&apos;&gt;&lt;nobr&gt;Indicates the activity of the virtual hard disks:&lt;/nobr&gt;%1&lt;/p&gt;</source>
<comment>HDD tooltip</comment>
<translation type="obsolete">&lt;p style=&apos;white-space:pre&apos;&gt;&lt;nobr&gt;アクティブãªä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’表示:&lt;/nobr&gt;%1&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p style=&apos;white-space:pre&apos;&gt;&lt;nobr&gt;Indicates the activity of the CD/DVD devices:&lt;/nobr&gt;%1&lt;/p&gt;</source>
<comment>CD/DVD tooltip</comment>
<translation type="obsolete">&lt;p style=&apos;white-space:pre&apos;&gt;&lt;nobr&gt;アクティブãªCD/DVD デãƒã‚¤ã‚¹ã‚’表示:&lt;/nobr&gt;%1&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;No CD/DVD devices attached&lt;/b&gt;&lt;/nobr&gt;</source>
<comment>CD/DVD tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;CD/DVD デãƒã‚¤ã‚¹ãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ãªã„&lt;/b&gt;&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p style=&apos;white-space:pre&apos;&gt;&lt;nobr&gt;Indicates the activity of the floppy devices:&lt;/nobr&gt;%1&lt;/p&gt;</source>
<comment>FD tooltip</comment>
<translation type="obsolete">&lt;p style=&apos;white-space:pre&apos;&gt;&lt;nobr&gt;アクティブãªãƒ•ロッピー デãƒã‚¤ã‚¹ã‚’表示:&lt;/nobr&gt;%1&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;No floppy devices attached&lt;/b&gt;&lt;/nobr&gt;</source>
<comment>FD tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;フロッピー デãƒã‚¤ã‚¹ãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ãªã„&lt;/b&gt;&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p style=&apos;white-space:pre&apos;&gt;&lt;nobr&gt;Indicates the activity of the network interfaces:&lt;/nobr&gt;%1&lt;/p&gt;</source>
<comment>Network adapters tooltip</comment>
<translation type="obsolete">&lt;p style=&apos;white-space:pre&apos;&gt;&lt;nobr&gt;アクティブãªãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ デãƒã‚¤ã‚¹ã‚’表示:&lt;/nobr&gt;%1&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;Adapter %1 (%2)&lt;/b&gt;: %3 cable %4&lt;/nobr&gt;</source>
<comment>Network adapters tooltip</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;&lt;b&gt;アダプタ %1 (%2)&lt;/b&gt;:%3 ケーブル %4&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p style=&apos;white-space:pre&apos;&gt;&lt;nobr&gt;Indicates the activity of the attached USB devices:&lt;/nobr&gt;%1&lt;/p&gt;</source>
<comment>USB device tooltip</comment>
<translation type="obsolete">&lt;p style=&apos;white-space:pre&apos;&gt;&lt;nobr&gt;アクティブãªUSB デãƒã‚¤ã‚¹ã‚’表示:&lt;/nobr&gt;%1&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;p style=&apos;white-space:pre&apos;&gt;&lt;nobr&gt;Indicates the activity of the machine&apos;s shared folders:&lt;/nobr&gt;%1&lt;/p&gt;</source>
<comment>Shared folders tooltip</comment>
<translation type="obsolete">&lt;p style=&apos;white-space:pre&apos;&gt;&lt;nobr&gt;アクティブãªå…±æœ‰ãƒ•ォルダを表示:&lt;/nobr&gt;%1&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>ACPI Sh&amp;utdown</source>
<translation type="obsolete">ACPI シャットダウン(&amp;U)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;View</source>
<translation type="obsolete">ビュー(&amp;V)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Preview Monitor %1</source>
<translation type="obsolete">プレビュー ディスプレイ %1</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>No CD/DVD devices attached to that VM</source>
<translation type="obsolete">CD/DVD デãƒã‚¤ã‚¹ 未割り当ã¦</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>No floppy devices attached to that VM</source>
<translation type="obsolete">フロッピー デãƒã‚¤ã‚¹ 未割り当ã¦</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>No USB Devices Connected</source>
<translation type="obsolete">USB デãƒã‚¤ã‚¹ 未接続</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>No supported devices connected to the host PC</source>
<translation type="obsolete">ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã«æŽ¥ç¶šã•れãŸãƒ‡ãƒã‚¤ã‚¹ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“</translation>
</message>
@@ -7760,358 +7771,289 @@ Version %1</source>
<context>
<name>VBoxDiskImageManagerDlg</name>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Name</source>
<translation type="obsolete">åå‰</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Virtual Size</source>
<translation type="obsolete">仮想的ãªã‚µã‚¤ã‚º</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Actual Size</source>
<translation type="obsolete">実際ã®ã‚µã‚¤ã‚º</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Size</source>
<translation type="obsolete">サイズ</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Virtual Disk Manager</source>
<translation type="obsolete">仮想ディスクマãƒãƒ¼ã‚¸ãƒ£</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Hard Disks</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯(&amp;H)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;CD/DVD Images</source>
<translation type="obsolete">CD/DVDイメージ(&amp;C)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Floppy Images</source>
<translation type="obsolete">フロッピーイメージ(&amp;F)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Help</source>
<translation type="obsolete">ヘルプ</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>F1</source>
<translation type="obsolete">F1</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Invoke dialog&apos;s help</source>
<translation type="obsolete">ダイアログã®ãƒ˜ãƒ«ãƒ—を表示</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;OK</source>
<translation type="obsolete">OK(&amp;O)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Accept dialog</source>
<translation type="obsolete">ダイアログã«åŒæ„</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Cancel dialog</source>
<translation type="obsolete">ダイアログをキャンセル</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>--</source>
<comment>no info</comment>
<translation type="obsolete">--</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;New...</source>
<translation type="obsolete">æ–°è¦(&amp;N)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Add...</source>
<translation type="obsolete">追加(&amp;A)...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>R&amp;emove</source>
<translation type="obsolete">除去(&amp;E)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Re&amp;lease</source>
<translation type="obsolete">解放(&amp;L)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Re&amp;fresh</source>
<translation type="obsolete">æœ€æ–°ã®æƒ…å ±ã«æ›´æ–°(&amp;F)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>New</source>
<translation type="obsolete">æ–°è¦</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Add</source>
<translation type="obsolete">追加</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Remove</source>
<translation type="obsolete">除去</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Release</source>
<translation type="obsolete">解放</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Refresh</source>
<translation type="obsolete">æœ€æ–°ã®æƒ…å ±ã«æ›´æ–°</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Ctrl+N</source>
<translation type="obsolete">Ctrl+N</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Ctrl+A</source>
<translation type="obsolete">Ctrl+A</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Ctrl+D</source>
<translation type="obsolete">Ctrl+D</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Ctrl+L</source>
<translation type="obsolete">Ctrl+L</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Ctrl+R</source>
<translation type="obsolete">Ctrl+R</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Actions</source>
<translation type="obsolete">動作</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Location</source>
<translation type="obsolete">場所</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Disk Type</source>
<translation type="obsolete">ディスク タイプ</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Storage Type</source>
<translation type="obsolete">ストレージ タイプ</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Attached to</source>
<translation type="obsolete">割り当ã¦</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Snapshot</source>
<translation type="obsolete">スナップショット</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Checking accessibility</source>
<translation type="obsolete">アクセスå¯å¦ã‚’確èª</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;Checking accessibility...</source>
<comment>HDD</comment>
<translation type="obsolete">&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;アクセスå¯å¦ã‚’確èªä¸­...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Disk type:&amp;nbsp;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Storage type:&amp;nbsp;&amp;nbsp;%3&lt;/nobr&gt;</source>
<translation type="obsolete">&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;ディスク タイプ:&amp;nbsp;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;ストレージ タイプ:&amp;nbsp;&amp;nbsp;%3&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;Attached to:&amp;nbsp;&amp;nbsp;%1&lt;/nobr&gt;</source>
<comment>HDD</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;割り当ã¦:&amp;nbsp;&amp;nbsp;%1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;Snapshot:&amp;nbsp;&amp;nbsp;%5&lt;/nobr&gt;</source>
<comment>HDD</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;スナップショット:&amp;nbsp;&amp;nbsp;%5&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;Error checking media accessibility</source>
<comment>HDD</comment>
<translation type="obsolete">&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;メディアã®ã‚¢ã‚¯ã‚»ã‚¹å¯å¦ç¢ºèªã§ã‚¨ãƒ©ãƒ¼</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;%2</source>
<comment>HDD</comment>
<translation type="obsolete">&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;%2</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;Checking accessibility...</source>
<comment>CD/DVD/Floppy</comment>
<translation type="obsolete">&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;アクセスå¯å¦ã‚’確èªä¸­...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;</source>
<comment>CD/DVD/Floppy</comment>
<translation type="obsolete">&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;br&gt;&lt;nobr&gt;Attached to:&amp;nbsp;&amp;nbsp;%1&lt;/nobr&gt;</source>
<comment>CD/DVD/Floppy</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;割り当ã¦:&amp;nbsp;&amp;nbsp;%1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;Error checking media accessibility</source>
<comment>CD/DVD/Floppy</comment>
<translation type="obsolete">&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;メディアã®ã‚¢ã‚¯ã‚»ã‚¹å¯å¦ç¢ºèªã§ã‚¨ãƒ©ãƒ¼</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;%2</source>
<translation type="obsolete">&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;%2</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>The image file is not accessible</source>
<comment>CD/DVD/Floppy</comment>
<translation type="obsolete">イメージファイルã«ã‚¢ã‚¯ã‚»ã‚¹ã§ããªã„</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&amp;Select</source>
<translation type="obsolete">é¸æŠž(&amp;S)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>All hard disk images (*.vdi; *.vmdk);;Virtual Disk images (*.vdi);;VMDK images (*.vmdk);;All files (*)</source>
<translation type="obsolete">ã™ã¹ã¦ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ァイル(*.vdi; *.vmdk);;仮想ディスクイメージ(*.vdi);;VMDKイメージ(*.vmdk);;ã™ã¹ã¦ã®ãƒ•ァイル (*)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Select a hard disk image file</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Select a CD/DVD-ROM disk image file</source>
<translation type="obsolete">CD/DVD-ROMãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Select a floppy disk image file</source>
<translation type="obsolete">ãƒ•ãƒ­ãƒƒãƒ”ãƒ¼ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Create a new virtual hard disk</source>
<translation type="obsolete">æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ä½œæˆ</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Add (register) an existing image file</source>
<translation type="obsolete">既存ã®ãƒ¡ãƒ‡ã‚£ã‚¢ ファイルを追加(登録)ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Remove (unregister) the selected media</source>
<translation type="obsolete">é¸æŠžã—ãŸãƒ¡ãƒ‡ã‚£ã‚¢ã‚’å–り除ã(登録解除)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Release the selected media by detaching it from the machine</source>
<translation type="obsolete">é¸æŠžã—ãŸãƒ¡ãƒ‡ã‚£ã‚¢ã‚’仮想マシンã‹ã‚‰å‰²ã‚Šå½“ã¦è§£é™¤ã—ã¦è§£æ”¾ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Refresh the media list</source>
<translation type="obsolete">ãƒ¡ãƒ‡ã‚£ã‚¢ãƒªã‚¹ãƒˆã‚’æœ€æ–°ã®æƒ…å ±ã«æ›´æ–°</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>CD/DVD-ROM images (*.iso);;All files (*)</source>
<translation type="obsolete">CD/DVD-ROMイメージ(*.iso);;ã™ã¹ã¦ã®ãƒ•ァイル(*)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Floppy images (*.img);;All files (*)</source>
<translation type="obsolete">フロッピーイメージ(*.img);;ã™ã¹ã¦ã®ãƒ•ァイル(*)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>All hard disk images (*.vdi *.vmdk *.vhd);;Virtual Disk images (*.vdi);;VMDK images (*.vmdk);;VHD images (*.vhd);;All files (*)</source>
<translation type="obsolete">ã™ã¹ã¦ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ァイル(*.vdi *.vmdk *.vhd);;仮想ディスクイメージ(*.vdi);;VMDKイメージ(*.vmdk);;VHDイメージ(*.vhd);;ã™ã¹ã¦ã®ãƒ•ァイル (*)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>Hard &amp;Disks</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯(&amp;D)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;Location:&lt;/nobr&gt;</source>
<translation type="obsolete">&lt;nobr&gt;場所:&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;Disk Type:&lt;/nobr&gt;</source>
<translation type="obsolete">&lt;nobr&gt;ディスク タイプ:&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;&amp;nbsp;&amp;nbsp;Storage Type:&lt;/nobr&gt;</source>
<translation type="obsolete">&lt;nobr&gt;&amp;nbsp;&amp;nbsp;ストレージ タイプ:&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;Attached to:&lt;/nobr&gt;</source>
<translation type="obsolete">&lt;nobr&gt;割り当ã¦å…ˆ:&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxApplianceEditorWgt.ui" line="58"/>
<source>&lt;nobr&gt;&amp;nbsp;&amp;nbsp;Snapshot:&lt;/nobr&gt;</source>
<translation type="obsolete">&lt;nobr&gt;&amp;nbsp;&amp;nbsp;スナップショット:&lt;/nobr&gt;</translation>
</message>
@@ -8195,37 +8137,30 @@ Version %1</source>
<context>
<name>VBoxGLSettingsDlg</name>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>General</source>
<translation type="obsolete">一般</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>Input</source>
<translation type="obsolete">入力</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>Update</source>
<translation type="obsolete">アップデート</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>Language</source>
<translation type="obsolete">言語</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>USB</source>
<translation type="obsolete">USB</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>VirtualBox - %1</source>
<translation type="obsolete">VirtualBox - %1</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>Network</source>
<translation type="obsolete">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
</message>
@@ -8233,32 +8168,26 @@ Version %1</source>
<context>
<name>VBoxGLSettingsInput</name>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>Host &amp;Key:</source>
<translation type="obsolete">ホストキー(&amp;K):</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>Displays the key used as a Host Key in the VM window. Activate the entry field and press a new Host Key. Note that alphanumeric, cursor movement and editing keys cannot be used.</source>
<translation type="obsolete">仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã§ãƒ›ã‚¹ãƒˆã‚­ãƒ¼ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã‚­ãƒ¼ã‚’表示ã—ã¾ã™ã€‚変更ã™ã‚‹ã«ã¯å…¥åŠ›ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã«ã—ã¦æ–°ã—ã„ホストキーを押ã—ã¦ãã ã•ã„。注:英数字ã€ã‚«ãƒ¼ã‚½ãƒ«ã‚­ãƒ¼ã€ç·¨é›†ã‚­ãƒ¼ã¯ãƒ›ã‚¹ãƒˆã‚­ãƒ¼ã¨ã—ã¦ä½¿ç”¨ã§ãã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>Reset Host Key</source>
<translation type="obsolete">ホストキーã®ãƒªã‚»ãƒƒãƒˆ</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>Resets the key used as a Host Key in the VM window.</source>
<translation type="obsolete">仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã§ãƒ›ã‚¹ãƒˆã‚­ãƒ¼ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã‚­ãƒ¼ã‚’リセットã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>When checked, the keyboard is automatically captured every time the VM window is activated. When the keyboard is captured, all keystrokes (including system ones like Alt-Tab) are directed to the VM.</source>
<translation type="obsolete">仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã®ã¨ãã€ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã‚’自動的ã«ã‚­ãƒ£ãƒ—ãƒãƒ£ã—ã¾ã™ã€‚キーボードãŒã‚­ãƒ£ãƒ—ãƒãƒ£ã•れるã¨ã€ã™ã¹ã¦ã®ã‚­ãƒ¼ã‚¹ãƒˆãƒ­ãƒ¼ã‚¯(Alt-Tabãªã©ã‚’å«ã‚€)ãŒä»®æƒ³ãƒžã‚·ãƒ³ã«é€ã‚‰ã‚Œã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>&amp;Auto Capture Keyboard</source>
<translation type="obsolete">キーボードã®è‡ªå‹•キャプãƒãƒ£(&amp;A)</translation>
</message>
@@ -8266,1640 +8195,1675 @@ Version %1</source>
<context>
<name>VBoxGlobal</name>
<message>
- <location filename="../src/widgets/VBoxFilePathSelectorWidget.cpp" line="509"/>
<source>Differencing</source>
<comment>hard disk</comment>
<translation type="obsolete">差分</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1420"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1438"/>
<source>Unknown device %1:%2</source>
<comment>USB device details</comment>
<translation>䏿˜Žãªãƒ‡ãƒã‚¤ã‚¹ %1:%2</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1445"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1463"/>
<source>&lt;nobr&gt;Vendor ID: %1&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Product ID: %2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Revision: %3&lt;/nobr&gt;</source>
<comment>USB device tooltip</comment>
<translation>&lt;nobr&gt;ベンダID: %1&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;プロダクトID: %2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;リビジョン: %3&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1454"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1472"/>
<source>&lt;br&gt;&lt;nobr&gt;Serial No. %1&lt;/nobr&gt;</source>
<comment>USB device tooltip</comment>
<translation>&lt;br&gt;&lt;nobr&gt;シリアルNo. %1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1461"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1479"/>
<source>&lt;br&gt;&lt;nobr&gt;State: %1&lt;/nobr&gt;</source>
<comment>USB device tooltip</comment>
<translation>&lt;br&gt;&lt;nobr&gt;状態: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1556"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1574"/>
<source>Name</source>
<comment>details report</comment>
<translation>åå‰</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1558"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1576"/>
<source>OS Type</source>
<comment>details report</comment>
<translation>OSタイプ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1628"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1646"/>
<source>Base Memory</source>
<comment>details report</comment>
<translation>メインメモリ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1628"/>
<source>&lt;nobr&gt;%3 MB&lt;/nobr&gt;</source>
<comment>details report</comment>
<translation type="obsolete">&lt;nobr&gt;%3 MB&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1565"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1583"/>
<source>General</source>
<comment>details report</comment>
<translation>一般</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1661"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1682"/>
<source>Video Memory</source>
<comment>details report</comment>
<translation>ビデオメモリ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1661"/>
<source>&lt;nobr&gt;%4 MB&lt;/nobr&gt;</source>
<comment>details report</comment>
<translation type="obsolete">&lt;nobr&gt;%4 MB&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1634"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1655"/>
<source>Boot Order</source>
<comment>details report</comment>
<translation>èµ·å‹•é †åº</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1636"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1657"/>
<source>ACPI</source>
<comment>details report</comment>
<translation>ACPI</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1637"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1658"/>
<source>IO APIC</source>
<comment>details report</comment>
<translation>IO APIC</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1637"/>
<source>Not Attached</source>
<comment>details report (HDDs)</comment>
<translation type="obsolete">割り当ã¦ã‚‰ã‚Œã¦ã„ã¾ã›ã‚“</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1637"/>
<source>Hard Disks</source>
<comment>details report</comment>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1596"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1614"/>
<source>Enabled</source>
<comment>details report (ACPI)</comment>
<translation>有効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1597"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1615"/>
<source>Disabled</source>
<comment>details report (ACPI)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1601"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1619"/>
<source>Enabled</source>
<comment>details report (IO APIC)</comment>
<translation>有効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1602"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1620"/>
<source>Disabled</source>
<comment>details report (IO APIC)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1602"/>
<source>Not mounted</source>
<comment>details report (floppy)</comment>
<translation type="obsolete">マウントã•れã¦ã„ã¾ã›ã‚“</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1602"/>
<source>Image</source>
<comment>details report (floppy)</comment>
<translation type="obsolete">イメージ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1602"/>
<source>Host Drive</source>
<comment>details report (floppy)</comment>
<translation type="obsolete">ホスト ドライブ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1602"/>
<source>Floppy</source>
<comment>details report</comment>
<translation type="obsolete">フロッピー</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1602"/>
<source>Not mounted</source>
<comment>details report (DVD)</comment>
<translation type="obsolete">マウントã•れã¦ã„ã¾ã›ã‚“</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1602"/>
<source>Image</source>
<comment>details report (DVD)</comment>
<translation type="obsolete">イメージ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1602"/>
<source>Host Drive</source>
<comment>details report (DVD)</comment>
<translation type="obsolete">ホスト ドライブ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1602"/>
<source>CD/DVD-ROM</source>
<comment>details report</comment>
<translation type="obsolete">CD/DVD-ROM</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1802"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1823"/>
<source>Disabled</source>
<comment>details report (audio)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1808"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1829"/>
<source>Audio</source>
<comment>details report</comment>
<translation>オーディオ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1847"/>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="653"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1866"/>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation>アダプタ %1</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1856"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1875"/>
<source>Disabled</source>
<comment>details report (network)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1864"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1883"/>
<source>Network</source>
<comment>details report</comment>
<translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1971"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1990"/>
<source>Device Filters</source>
<comment>details report (USB)</comment>
<translation>デãƒã‚¤ã‚¹ フィルタ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1972"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1991"/>
<source>%1 (%2 active)</source>
<comment>details report (USB)</comment>
<translation>%1 (%2 アクティブ)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1977"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1996"/>
<source>Disabled</source>
<comment>details report (USB)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1977"/>
<source>VRDP Server Port</source>
<comment>details report (VRDP)</comment>
<translation type="obsolete">VRDPサーãƒãƒ¼ ãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1977"/>
<source>%1</source>
<comment>details report (VRDP)</comment>
<translation type="obsolete">%1</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1977"/>
<source>Disabled</source>
<comment>details report (VRDP)</comment>
<translation type="obsolete">無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1977"/>
<source>Remote Display</source>
<comment>details report</comment>
<translation type="obsolete">リモートディスプレイ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1977"/>
<source>Opening URLs is not implemented yet.</source>
<translation type="obsolete">&quot;URLã‚’é–‹ã&quot;ã¯ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2842"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2861"/>
<source>Powered Off</source>
<comment>MachineState</comment>
<translation>é›»æºã‚ªãƒ•</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2843"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2862"/>
<source>Saved</source>
<comment>MachineState</comment>
<translation>ä¿å­˜</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2845"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2864"/>
<source>Aborted</source>
<comment>MachineState</comment>
<translation>中断</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2846"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2865"/>
<source>Running</source>
<comment>MachineState</comment>
<translation>実行中</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2847"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2866"/>
<source>Paused</source>
<comment>MachineState</comment>
<translation>ä¸€æ™‚åœæ­¢</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2851"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2870"/>
<source>Starting</source>
<comment>MachineState</comment>
<translation>起動中</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2852"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2871"/>
<source>Stopping</source>
<comment>MachineState</comment>
<translation>åœæ­¢ä¸­</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2853"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2872"/>
<source>Saving</source>
<comment>MachineState</comment>
<translation>ä¿å­˜ä¸­</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2854"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2873"/>
<source>Restoring</source>
<comment>MachineState</comment>
<translation>復元中</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2854"/>
<source>Discarding</source>
<comment>MachineState</comment>
<translation type="obsolete">破棄中</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2854"/>
<source>Closed</source>
<comment>SessionState</comment>
<translation type="obsolete">クローズド</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2854"/>
<source>Open</source>
<comment>SessionState</comment>
<translation type="obsolete">オープン</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2866"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2885"/>
<source>Spawning</source>
<comment>SessionState</comment>
<translation>生æˆä¸­</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2866"/>
<source>Closing</source>
<comment>SessionState</comment>
<translation type="obsolete">閉鎖中</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2869"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2888"/>
<source>None</source>
<comment>DeviceType</comment>
<translation>ãªã—</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2870"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2889"/>
<source>Floppy</source>
<comment>DeviceType</comment>
<translation>フロッピー</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2871"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2890"/>
<source>CD/DVD-ROM</source>
<comment>DeviceType</comment>
<translation>CD/DVD-ROM</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2872"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2891"/>
<source>Hard Disk</source>
<comment>DeviceType</comment>
<translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2873"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2892"/>
<source>Network</source>
<comment>DeviceType</comment>
<translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2900"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2919"/>
<source>Normal</source>
<comment>DiskType</comment>
<translation>標準</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2901"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2920"/>
<source>Immutable</source>
<comment>DiskType</comment>
<translation>変更ä¸å¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2902"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2921"/>
<source>Writethrough</source>
<comment>DiskType</comment>
<translation>ライトスルー</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2902"/>
<source>Virtual Disk Image</source>
<comment>DiskStorageType</comment>
<translation type="obsolete">仮想ディスクイメージ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2902"/>
<source>iSCSI</source>
<comment>DiskStorageType</comment>
<translation type="obsolete">iSCSI</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2902"/>
<source>VMDK Image</source>
<comment>DiskStorageType</comment>
<translation type="obsolete">VMDKイメージ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2902"/>
<source>Null</source>
<comment>VRDPAuthType</comment>
<translation type="obsolete">Null</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2902"/>
<source>External</source>
<comment>VRDPAuthType</comment>
<translation type="obsolete">外部</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2902"/>
<source>Guest</source>
<comment>VRDPAuthType</comment>
<translation type="obsolete">ゲスト</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2918"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2937"/>
<source>Ignore</source>
<comment>USBFilterActionType</comment>
<translation>無視</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2920"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2939"/>
<source>Hold</source>
<comment>USBFilterActionType</comment>
<translation>ä¿æŒ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2923"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2942"/>
<source>Null Audio Driver</source>
<comment>AudioDriverType</comment>
<translation>Null Audio Driver</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2925"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2944"/>
<source>Windows Multimedia</source>
<comment>AudioDriverType</comment>
<translation>Windows マルãƒãƒ¡ãƒ‡ã‚£ã‚¢</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2929"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2948"/>
<source>OSS Audio Driver</source>
<comment>AudioDriverType</comment>
<translation>OSS オーディオ ドライãƒ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2931"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2950"/>
<source>ALSA Audio Driver</source>
<comment>AudioDriverType</comment>
<translation>ALSA オーディオ ドライãƒ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2933"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2952"/>
<source>Windows DirectSound</source>
<comment>AudioDriverType</comment>
<translation>Windows DirectSound</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2935"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2954"/>
<source>CoreAudio</source>
<comment>AudioDriverType</comment>
<translation>CoreAudio</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2962"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2981"/>
<source>Not attached</source>
<comment>NetworkAttachmentType</comment>
<translation>未割り当ã¦</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2964"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2983"/>
<source>NAT</source>
<comment>NetworkAttachmentType</comment>
<translation>NAT</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2964"/>
<source>Host Interface</source>
<comment>NetworkAttachmentType</comment>
<translation type="obsolete">ホスト インターフェース</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2968"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2987"/>
<source>Internal Network</source>
<comment>NetworkAttachmentType</comment>
<translation>内部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3005"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2991"/>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2994"/>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2996"/>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2998"/>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3029"/>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation>LsiLogic SAS</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3008"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3032"/>
<source>Not supported</source>
<comment>USBDeviceState</comment>
<translation>未サãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3010"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3034"/>
<source>Unavailable</source>
<comment>USBDeviceState</comment>
<translation>利用ä¸å¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3012"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3036"/>
<source>Busy</source>
<comment>USBDeviceState</comment>
<translation>ビジー</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3014"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3038"/>
<source>Available</source>
<comment>USBDeviceState</comment>
<translation>利用å¯èƒ½</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3016"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3040"/>
<source>Held</source>
<comment>USBDeviceState</comment>
<translation>ä¿æŒ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3018"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3042"/>
<source>Captured</source>
<comment>USBDeviceState</comment>
<translation>キャプãƒãƒ£</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3018"/>
<source>&lt;i&gt;Checking...&lt;/i&gt;</source>
<comment>hard disk</comment>
<translation type="obsolete">&lt;i&gt;確èªä¸­...&lt;/i&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3018"/>
<source>&lt;i&gt;Inaccessible&lt;/i&gt;</source>
<comment>hard disk</comment>
<translation type="obsolete">&lt;i&gt;アクセスä¸å¯&lt;/i&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2982"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3006"/>
<source>Disabled</source>
<comment>ClipboardType</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2984"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3008"/>
<source>Host To Guest</source>
<comment>ClipboardType</comment>
<translation>ホストOSã‹ã‚‰ã‚²ã‚¹ãƒˆOSã¸</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2986"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3010"/>
<source>Guest To Host</source>
<comment>ClipboardType</comment>
<translation>ゲストOSã‹ã‚‰ãƒ›ã‚¹ãƒˆOSã¸</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2988"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3012"/>
<source>Bidirectional</source>
<comment>ClipboardType</comment>
<translation>åŒæ–¹å‘</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2988"/>
<source>Select a directory</source>
<translation type="obsolete">ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2988"/>
<source>Select a file</source>
<translation type="obsolete">ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1892"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1911"/>
<source>Port %1</source>
<comment>details report (serial ports)</comment>
<translation>ãƒãƒ¼ãƒˆ %1</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1901"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1920"/>
<source>Disabled</source>
<comment>details report (serial ports)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1909"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1928"/>
<source>Serial Ports</source>
<comment>details report</comment>
<translation>シリアルãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1983"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2002"/>
<source>USB</source>
<comment>details report</comment>
<translation>USB</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1996"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2015"/>
<source>Shared Folders</source>
<comment>details report (shared folders)</comment>
<translation>共有フォルダ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1996"/>
<source>%1</source>
<comment>details report (shadef folders)</comment>
<translation type="obsolete">%1</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2001"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2020"/>
<source>None</source>
<comment>details report (shared folders)</comment>
<translation>ãªã—</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2007"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2026"/>
<source>Shared Folders</source>
<comment>details report</comment>
<translation>共有フォルダ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2007"/>
<source>Stuck</source>
<comment>MachineState</comment>
<translation type="obsolete">スタック</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2912"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2931"/>
<source>Disconnected</source>
<comment>PortMode</comment>
<translation>切断</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2913"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2932"/>
<source>Host Pipe</source>
<comment>PortMode</comment>
<translation>ホストã«ãƒ‘イプ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2914"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2933"/>
<source>Host Device</source>
<comment>PortMode</comment>
<translation>ホスト デãƒã‚¤ã‚¹</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3021"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3045"/>
<source>PIIX3</source>
<comment>ChipsetType</comment>
<translation>PIIX3</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3023"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3047"/>
<source>ICH9</source>
<comment>ChipsetType</comment>
<translation>ICH9</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3025"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3049"/>
<source>User-defined</source>
<comment>serial port</comment>
<translation>ユーザー定義</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3025"/>
<source>Custom Hard Disk</source>
<comment>DiskStorageType</comment>
<translation type="obsolete">カスタム ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/runtime/UIIndicatorsPool.cpp" line="573"/>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="492"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1664"/>
+ <location filename="../src/runtime/UIIndicatorsPool.cpp" line="577"/>
<source>VT-x/AMD-V</source>
<comment>details report</comment>
<translation>VT-x/AMD-V</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1638"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1659"/>
<source>PAE/NX</source>
<comment>details report</comment>
<translation>PAE/NX</translation>
</message>
<message>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="464"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1632"/>
<location filename="../src/runtime/UIIndicatorsPool.cpp" line="560"/>
<source>Enabled</source>
<comment>details report (VT-x/AMD-V)</comment>
<translation>有効</translation>
</message>
<message>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="465"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1633"/>
<location filename="../src/runtime/UIIndicatorsPool.cpp" line="561"/>
<source>Disabled</source>
<comment>details report (VT-x/AMD-V)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1699"/>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="496"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1720"/>
<source>Remote Desktop Server Port</source>
<comment>details report (VRDE Server)</comment>
<translation>リモートデスクトップ サーãƒãƒ¼ ãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1606"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1624"/>
<source>Enabled</source>
<comment>details report (PAE/NX)</comment>
<translation>有効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1607"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1625"/>
<source>Disabled</source>
<comment>details report (PAE/NX)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1795"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1652"/>
+ <location filename="../src/runtime/UIIndicatorsPool.cpp" line="579"/>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1653"/>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1816"/>
<source>Host Driver</source>
<comment>details report (audio)</comment>
<translation>ホスト ドライãƒ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1798"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1819"/>
<source>Controller</source>
<comment>details report (audio)</comment>
<translation>コントローラ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1930"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1860"/>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1949"/>
<source>Port %1</source>
<comment>details report (parallel ports)</comment>
<translation>ãƒãƒ¼ãƒˆ %1</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1939"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1958"/>
<source>Disabled</source>
<comment>details report (parallel ports)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1948"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1967"/>
<source>Parallel Ports</source>
<comment>details report</comment>
<translation>パラレルãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2874"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2893"/>
<source>USB</source>
<comment>DeviceType</comment>
<translation>USB</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2875"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2894"/>
<source>Shared Folder</source>
<comment>DeviceType</comment>
<translation>共有フォルダ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2877"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2896"/>
<source>IDE</source>
<comment>StorageBus</comment>
<translation>IDE</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2878"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2897"/>
<source>SATA</source>
<comment>StorageBus</comment>
<translation>SATA</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2883"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2902"/>
<source>Primary</source>
<comment>StorageBusChannel</comment>
<translation>プライマリ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2884"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2903"/>
<source>Secondary</source>
<comment>StorageBusChannel</comment>
<translation>セカンダリ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2887"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2906"/>
<source>Master</source>
<comment>StorageBusDevice</comment>
<translation>マスター</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2888"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2907"/>
<source>Slave</source>
<comment>StorageBusDevice</comment>
<translation>スレーブ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2885"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2904"/>
<source>Port %1</source>
<comment>StorageBusChannel</comment>
<translation>ãƒãƒ¼ãƒˆ %1</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2885"/>
<source>VHD Image</source>
<comment>DiskStorageType</comment>
<translation type="obsolete">VHDイメージ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2927"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2946"/>
<source>Solaris Audio</source>
<comment>AudioDriverType</comment>
<translation>Solaris オーディオ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2937"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2956"/>
<source>PulseAudio</source>
<comment>AudioDriverType</comment>
<translation>PulseAudio</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2940"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2959"/>
<source>ICH AC97</source>
<comment>AudioControllerType</comment>
<translation>ICH AC97</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2942"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2961"/>
<source>SoundBlaster 16</source>
<comment>AudioControllerType</comment>
<translation>SoundBlaster 16</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2947"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2966"/>
<source>PCnet-PCI II (Am79C970A)</source>
<comment>NetworkAdapterType</comment>
<translation>PCnet-PCI II (Am79C970A)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2949"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2968"/>
<source>PCnet-FAST III (Am79C973)</source>
<comment>NetworkAdapterType</comment>
<translation>PCnet-FAST III (Am79C973)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2951"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2970"/>
<source>Intel PRO/1000 MT Desktop (82540EM)</source>
<comment>NetworkAdapterType</comment>
<translation>Intel PRO/1000 MT Desktop (82540EM)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2951"/>
<source>PIIX3</source>
<comment>IDEControllerType</comment>
<translation type="obsolete">PIIX3</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2951"/>
<source>PIIX4</source>
<comment>IDEControllerType</comment>
<translation type="obsolete">PIIX4</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2953"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2972"/>
<source>Intel PRO/1000 T Server (82543GC)</source>
<comment>NetworkAdapterType</comment>
<translation>Intel PRO/1000 T Server (82543GC)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1477"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1495"/>
<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/globals/VBoxGlobal.cpp" line="1482"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1500"/>
<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/globals/VBoxGlobal.cpp" line="1487"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1505"/>
<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/globals/VBoxGlobal.cpp" line="1492"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1510"/>
<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/globals/VBoxGlobal.cpp" line="1497"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1515"/>
<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/globals/VBoxGlobal.cpp" line="1502"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1520"/>
<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/globals/VBoxGlobal.cpp" line="1507"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1525"/>
<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/globals/VBoxGlobal.cpp" line="1514"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1532"/>
<source>&lt;nobr&gt;State: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
<translation>&lt;nobr&gt;状態: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1514"/>
<source>host interface, %1</source>
<comment>details report (network)</comment>
<translation type="obsolete">ホスト インターフェース, %1</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1514"/>
<source>internal network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
<translation type="obsolete">内部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯, &apos;%1&apos;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="239"/>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>アダプタ %1</translation>
+ <translation type="obsolete">アダプタ %1</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="239"/>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
<comment>hard disk</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;タイプ&amp;nbsp;(å½¢å¼):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="239"/>
<source>&lt;br&gt;&lt;nobr&gt;Attached to:&amp;nbsp;&amp;nbsp;%1&lt;/nobr&gt;</source>
<comment>medium</comment>
<translation type="obsolete">&lt;br&gt;&lt;nobr&gt;割り当ã¦:&amp;nbsp;&amp;nbsp;%1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="239"/>
<source>&lt;i&gt;Not&amp;nbsp;Attached&lt;/i&gt;</source>
<comment>medium</comment>
<translation type="obsolete">&lt;i&gt;未割り当ã¦&lt;/i&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="239"/>
<source>&lt;br&gt;&lt;i&gt;Checking accessibility...&lt;/i&gt;</source>
<comment>medium</comment>
<translation type="obsolete">&lt;br&gt;&lt;i&gt;アクセスå¯å¦ã‚’確èªä¸­...&lt;/i&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="239"/>
<source>&lt;hr&gt;Failed to check media accessibility.&lt;br&gt;%1.</source>
<comment>medium</comment>
<translation type="obsolete">&lt;hr&gt;メディアã®ã‚¢ã‚¯ã‚»ã‚¹å¯å¦ã®ç¢ºèªã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;br&gt;%1.</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="239"/>
<source>&lt;hr&gt;&lt;img src=%1/&gt;&amp;nbsp;Attaching this hard disk will be performed indirectly using a newly created differencing hard disk.</source>
<comment>medium</comment>
<translation type="obsolete">&lt;hr&gt;&lt;img src=%1/&gt;&amp;nbsp;ã“ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®å‰²ã‚Šå½“ã¦ã¯ã€æ–°è¦ä½œæˆã•れãŸå·®åˆ†ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ä½¿ç”¨ã«ã‚ˆã‚Šã€é–“接的ã«å®Ÿè¡Œã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="443"/>
+ <location filename="../src/VBoxMedium.cpp" line="446"/>
<source>Checking...</source>
<comment>medium</comment>
<translation>確èªä¸­...</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="447"/>
+ <location filename="../src/VBoxMedium.cpp" line="450"/>
<source>Inaccessible</source>
<comment>medium</comment>
<translation>アクセスã§ãã¾ã›ã‚“</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="447"/>
<source>&lt;hr&gt;Some of the media in this hard disk chain are inaccessible. Please use the Virtual Media Manager in &lt;b&gt;Show Differencing Hard Disks&lt;/b&gt; mode to inspect these media.</source>
<translation type="obsolete">&lt;hr&gt;ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ ãƒã‚§ãƒ¼ãƒ³ä¸­ã®ã„ãã¤ã‹ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。仮想メディアマãƒãƒ¼ã‚¸ãƒ£ã®&lt;b&gt;[別ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’表示ã™ã‚‹]&lt;/b&gt;を使用ã—ã¦ã€ã“れらã®ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’確èªã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="447"/>
<source>%1&lt;hr&gt;This base hard disk is indirectly attached using the following differencing hard disk:&lt;br&gt;%2%3</source>
<translation type="obsolete">%1&lt;hr&gt;ã“ã®ãƒ™ãƒ¼ã‚¹ ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã¯ä»¥ä¸‹ã®å·®åˆ†ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’使用ã—ã¦é–“接的ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã™:&lt;br&gt;%2%3</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1680"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1701"/>
<source>3D Acceleration</source>
<comment>details report</comment>
<translation>3Dアクセラレーション</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1676"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1697"/>
<source>Enabled</source>
<comment>details report (3D Acceleration)</comment>
<translation>有効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1677"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1698"/>
<source>Disabled</source>
<comment>details report (3D Acceleration)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2861"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2880"/>
<source>Setting Up</source>
<comment>MachineState</comment>
<translation>セットアップ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2906"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2925"/>
<source>Differencing</source>
<comment>DiskType</comment>
<translation>差分</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1644"/>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="493"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1665"/>
<source>Nested Paging</source>
<comment>details report</comment>
<translation>ãƒã‚¹ãƒ†ãƒƒãƒ‰ãƒšãƒ¼ã‚¸ãƒ³ã‚°</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1619"/>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="467"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1637"/>
<source>Enabled</source>
<comment>details report (Nested Paging)</comment>
<translation>有効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1620"/>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="468"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1638"/>
<source>Disabled</source>
<comment>details report (Nested Paging)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1620"/>
<source>Bridged network, %1</source>
<comment>details report (network)</comment>
<translation type="obsolete">ブリッジ ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯, &apos;%1&apos;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1833"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1854"/>
<source>Internal network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
<translation>内部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯, &apos;%1&apos;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1833"/>
<source>Host-only network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
<translation type="obsolete">ホストオンリー ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯, &apos;%1&apos;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2879"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2898"/>
<source>SCSI</source>
<comment>StorageBus</comment>
<translation>SCSI</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2879"/>
<source>Bridged Network</source>
<comment>NetworkAttachmentType</comment>
<translation type="obsolete">ブリッジ ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2879"/>
<source>Host-only Network</source>
<comment>NetworkAttachmentType</comment>
<translation type="obsolete">ホストオンリー ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2991"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3015"/>
<source>PIIX3</source>
<comment>StorageControllerType</comment>
<translation>PIIX3</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2993"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3017"/>
<source>PIIX4</source>
<comment>StorageControllerType</comment>
<translation>PIIX4</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2995"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3019"/>
<source>ICH6</source>
<comment>StorageControllerType</comment>
<translation>ICH6</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2997"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3021"/>
<source>AHCI</source>
<comment>StorageControllerType</comment>
<translation>AHCI</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2999"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3023"/>
<source>Lsilogic</source>
<comment>StorageControllerType</comment>
<translation>Lsilogic</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3001"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3025"/>
<source>BusLogic</source>
<comment>StorageControllerType</comment>
<translation>BusLogic</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1830"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1851"/>
<source>Bridged adapter, %1</source>
<comment>details report (network)</comment>
<translation>ブリッジ アダプタ, &apos;%1&apos;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1836"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1857"/>
<source>Host-only adapter, &apos;%1&apos;</source>
<comment>details report (network)</comment>
<translation>ホストオンリー アダプタ, &apos;%1&apos;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2955"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2974"/>
<source>Intel PRO/1000 MT Server (82545EM)</source>
<comment>NetworkAdapterType</comment>
<translation>Intel PRO/1000 MT Server (82545EM)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2966"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2985"/>
<source>Bridged Adapter</source>
<comment>NetworkAttachmentType</comment>
<translation>ブリッジ アダプタ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2970"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2989"/>
<source>Host-only Adapter</source>
<comment>NetworkAttachmentType</comment>
<translation>ホストオンリー アダプタ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1662"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1647"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1683"/>
<source>&lt;nobr&gt;%1 MB&lt;/nobr&gt;</source>
<comment>details report</comment>
<translation>&lt;nobr&gt;%1 MB&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/runtime/UIIndicatorsPool.cpp" line="579"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1649"/>
+ <location filename="../src/runtime/UIIndicatorsPool.cpp" line="584"/>
<source>Processor(s)</source>
<comment>details report</comment>
<translation>プロセッサ数</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1632"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1650"/>
<source>&lt;nobr&gt;%1&lt;/nobr&gt;</source>
<comment>details report</comment>
<translation>&lt;nobr&gt;%1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1650"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1671"/>
<source>System</source>
<comment>details report</comment>
<translation>システム</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1650"/>
<source>Remote Display Server Port</source>
<comment>details report (VRDP Server)</comment>
<translation type="obsolete">リモートディスプレイ サーãƒãƒ¼ ãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1650"/>
<source>Remote Display Server</source>
<comment>details report (VRDP Server)</comment>
<translation type="obsolete">リモートディスプレイ サーãƒãƒ¼</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1650"/>
<source>Disabled</source>
<comment>details report (VRDP Server)</comment>
<translation type="obsolete">無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1712"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1733"/>
<source>Display</source>
<comment>details report</comment>
<translation>ディスプレイ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2915"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2934"/>
<source>Raw File</source>
<comment>PortMode</comment>
<translation>Rawファイル</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1685"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1706"/>
<source>Enabled</source>
<comment>details report (2D Video Acceleration)</comment>
<translation>有効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1411"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1246"/>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1248"/>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1250"/>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1252"/>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1429"/>
<source>Unknown device</source>
<comment>USB device details</comment>
<translation></translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1670"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1691"/>
<source>Screens</source>
<comment>details report</comment>
<translation>スクリーン</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1686"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1707"/>
<source>Disabled</source>
<comment>details report (2D Video Acceleration)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1689"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1710"/>
<source>2D Video Acceleration</source>
<comment>details report</comment>
<translation>2Dビデオ アクセラレーション</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1703"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1724"/>
<source>Remote Desktop Server</source>
<comment>details report (VRDE Server)</comment>
<translation>リモートデスクトップ サーãƒãƒ¼</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1704"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1725"/>
<source>Disabled</source>
<comment>details report (VRDE Server)</comment>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1743"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1764"/>
<source>(CD/DVD)</source>
<translation>(CD/DVD)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1775"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1796"/>
<source>Not Attached</source>
<comment>details report (Storage)</comment>
<translation>未割り当ã¦</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1783"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="1804"/>
<source>Storage</source>
<comment>details report</comment>
<translation>ストレージ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="1840"/>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯, &apos;%1&apos;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2648"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2667"/>
<source>Choose a virtual hard disk file</source>
<translation>仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãƒ•ァイルã®é¸æŠž</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2649"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2668"/>
<source>hard disk</source>
<translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2660"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2679"/>
<source>Choose a virtual CD/DVD disk file</source>
<translation>仮想CD/DVDディスクファイルã®é¸æŠž</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2661"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2680"/>
<source>CD/DVD-ROM disk</source>
<translation>CD/DVD-ROMディスク</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2672"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2691"/>
<source>Choose a virtual floppy disk file</source>
<translation>仮想フロッピーディスクファイルã®é¸æŠž</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2673"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2692"/>
<source>floppy disk</source>
<translation>フロッピーディスク</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2698"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2717"/>
<source>All %1 images (%2)</source>
<translation>ã™ã¹ã¦ã®%1イメージ(%2)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2699"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2718"/>
<source>All files (*)</source>
<translation>ã™ã¹ã¦ã®ãƒ•ァイル(*)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2844"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2863"/>
<source>Teleported</source>
<comment>MachineState</comment>
<translation>テレãƒãƒ¼ãƒ†ãƒ¼ã‚·ãƒ§ãƒ³</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2848"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2867"/>
<source>Guru Meditation</source>
<comment>MachineState</comment>
<translation>瞑想中(システムエラー)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2856"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2868"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2875"/>
<source>Teleporting</source>
<comment>MachineState</comment>
<translation>テレãƒãƒ¼ãƒ†ãƒ¼ã‚·ãƒ§ãƒ³ä¸­</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2850"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2869"/>
<source>Taking Live Snapshot</source>
<comment>MachineState</comment>
<translation>スナップショットã®ä½œæˆä¸­</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2855"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2874"/>
<source>Teleporting Paused VM</source>
<comment>MachineState</comment>
<translation>仮想マシンã®ãƒ†ãƒ¬ãƒãƒ¼ãƒ†ãƒ¼ã‚·ãƒ§ãƒ³ã‚’中断</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2857"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2876"/>
<source>Restoring Snapshot</source>
<comment>MachineState</comment>
<translation>スナップショットã«å¾©å…ƒä¸­</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2860"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2877"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2878"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2879"/>
<source>Deleting Snapshot</source>
<comment>MachineState</comment>
<translation>スナップショットを削除中</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2862"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2881"/>
<source>Fault Tolerant Syncing</source>
<comment>MachineState</comment>
<translation>フォールトトレラントã®åŒæœŸä¸­</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2864"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2883"/>
<source>Unlocked</source>
<comment>SessionState</comment>
<translation>アンロック</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2865"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2884"/>
<source>Locked</source>
<comment>SessionState</comment>
<translation>ロック</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2867"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2886"/>
<source>Unlocking</source>
<comment>SessionState</comment>
<translation>アンロック中</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2880"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2899"/>
<source>Floppy</source>
<comment>StorageBus</comment>
<translation>フロッピー</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2881"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2900"/>
<source>SAS</source>
<comment>StorageBus</comment>
<translation>SAS</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2889"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2908"/>
<source>Device %1</source>
<comment>StorageBusDevice</comment>
<translation>デãƒã‚¤ã‚¹ %1</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2891"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2910"/>
<source>IDE Primary Master</source>
<comment>New Storage UI : Slot Name</comment>
<translation>IDE プライマリ マスター</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2892"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2911"/>
<source>IDE Primary Slave</source>
<comment>New Storage UI : Slot Name</comment>
<translation>IDE プライマリ スレーブ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2893"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2912"/>
<source>IDE Secondary Master</source>
<comment>New Storage UI : Slot Name</comment>
<translation>IDE セカンダリ マスター</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2894"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2913"/>
<source>IDE Secondary Slave</source>
<comment>New Storage UI : Slot Name</comment>
<translation>IDE セカンダリ スレーブ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2895"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2914"/>
<source>SATA Port %1</source>
<comment>New Storage UI : Slot Name</comment>
<translation>SATA ãƒãƒ¼ãƒˆ %1</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2896"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2915"/>
<source>SCSI Port %1</source>
<comment>New Storage UI : Slot Name</comment>
<translation>SCSI ãƒãƒ¼ãƒˆ %1</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2897"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2916"/>
<source>SAS Port %1</source>
<comment>New Storage UI : Slot Name</comment>
<translation>SAS ãƒãƒ¼ãƒˆ %1</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2898"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2917"/>
<source>Floppy Device %1</source>
<comment>New Storage UI : Slot Name</comment>
<translation>フロッピー デãƒã‚¤ã‚¹ %1</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2903"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2922"/>
<source>Shareable</source>
<comment>DiskType</comment>
<translation>共有å¯èƒ½</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2904"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2923"/>
<source>Readonly</source>
<comment>DiskType</comment>
<translation>読ã¿è¾¼ã¿å°‚用</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2905"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2924"/>
<source>Multi-attach</source>
<comment>DiskType</comment>
<translation>複数割り当ã¦</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2908"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2927"/>
<source>Null</source>
<comment>AuthType</comment>
<translation>Null</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2909"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2928"/>
<source>External</source>
<comment>AuthType</comment>
<translation>外部</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2910"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2929"/>
<source>Guest</source>
<comment>AuthType</comment>
<translation>ゲスト</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2944"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2963"/>
<source>Intel HD Audio</source>
<comment>AudioControllerType</comment>
<translation>Intel HD オーディオ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2958"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="2977"/>
<source>Paravirtualized Network (virtio-net)</source>
<comment>NetworkAdapterType</comment>
<translation>準仮想化ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ (virtio-net)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2973"/>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>VDE アダプタ</translation>
+ <translation type="obsolete">VDE アダプタ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2977"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3001"/>
<source>UDP</source>
<comment>NATProtocolType</comment>
<translation>UDP</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="2979"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3003"/>
<source>TCP</source>
<comment>NATProtocolType</comment>
<translation>TCP</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3003"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3027"/>
<source>I82078</source>
<comment>StorageControllerType</comment>
<translation>I82078</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3625"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3649"/>
<source>and</source>
<translation>and</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3625"/>
<source>^(?:(?:(\d+)(?:\s?(B|KB|MB|GB|TB|PB))?)|(?:(\d*)%1(\d{1,2})(?:\s?(KB|MB|GB|TB|PB))))$</source>
<comment>regexp for matching ####[.##] B|KB|MB|GB|TB|PB, %1=decimal point</comment>
<translation type="obsolete">^(?:(?:(\d+)(?:\s?(B|KB|MB|GB|TB|PB))?)|(?:(\d*)%1(\d{1,2})(?:\s?(KB|MB|GB|TB|PB))))$</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3713"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3626"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3677"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3737"/>
<source>B</source>
<comment>size suffix Bytes</comment>
<translation>B</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3714"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3627"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3679"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3738"/>
<source>KB</source>
<comment>size suffix KBytes=1024 Bytes</comment>
<translation>KB</translation>
</message>
<message>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3628"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3681"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3739"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="359"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="360"/>
+ <location filename="../src/widgets/VBoxApplianceEditorWgt.cpp" line="236"/>
<location filename="../src/widgets/VBoxApplianceEditorWgt.cpp" line="427"/>
<source>MB</source>
<comment>size suffix MBytes=1024 KBytes</comment>
<translation>MB</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3716"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3629"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3683"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3740"/>
<source>GB</source>
<comment>size suffix GBytes=1024 MBytes</comment>
<translation>GB</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3717"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3630"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3685"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3741"/>
<source>TB</source>
<comment>size suffix TBytes=1024 GBytes</comment>
<translation>TB</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="3718"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3631"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3687"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="3742"/>
<source>PB</source>
<comment>size suffix PBytes=1024 TBytes</comment>
<translation>PB</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="120"/>
+ <location filename="../src/VBoxMedium.cpp" line="122"/>
<source>Empty</source>
<comment>medium</comment>
<translation>空</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="124"/>
+ <location filename="../src/VBoxMedium.cpp" line="126"/>
<source>Host Drive &apos;%1&apos;</source>
<comment>medium</comment>
<translation>ホスト ドライブ &apos;%1&apos;</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="126"/>
+ <location filename="../src/VBoxMedium.cpp" line="128"/>
<source>Host Drive %1 (%2)</source>
<comment>medium</comment>
<translation>ホスト ドライブ %1 (%2)</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="245"/>
+ <location filename="../src/VBoxMedium.cpp" line="248"/>
<source>&lt;p style=white-space:pre&gt;Type (Format): %1 (%2)&lt;/p&gt;</source>
<comment>medium</comment>
<translation>&lt;p style=white-space:pre&gt;タイプ (å½¢å¼): %1 (%2)&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="249"/>
+ <location filename="../src/VBoxMedium.cpp" line="252"/>
<source>&lt;p&gt;Attached to: %1&lt;/p&gt;</source>
<comment>image</comment>
<translation>&lt;p&gt;割り当ã¦: %1&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="250"/>
+ <location filename="../src/VBoxMedium.cpp" line="253"/>
<source>&lt;i&gt;Not Attached&lt;/i&gt;</source>
<comment>image</comment>
<translation>&lt;i&gt;未割り当ã¦&lt;/i&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="256"/>
+ <location filename="../src/VBoxMedium.cpp" line="259"/>
<source>&lt;i&gt;Checking accessibility...&lt;/i&gt;</source>
<comment>medium</comment>
<translation>&lt;i&gt;アクセスå¯å¦ã‚’確èªä¸­...&lt;/i&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="269"/>
+ <location filename="../src/VBoxMedium.cpp" line="272"/>
<source>Failed to check media accessibility.</source>
<comment>medium</comment>
<translation>メディアã®ã‚¢ã‚¯ã‚»ã‚¹å¯å¦ã®ç¢ºèªã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="314"/>
+ <location filename="../src/VBoxMedium.cpp" line="317"/>
<source>&lt;b&gt;No medium selected&lt;/b&gt;</source>
<comment>medium</comment>
<translation>&lt;b&gt;メディア æœªé¸æŠž&lt;/b&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="315"/>
+ <location filename="../src/VBoxMedium.cpp" line="318"/>
<source>You can also change this while the machine is running.</source>
<translation>仮想マシンã®å‹•作中ã€ã“れを変更ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="316"/>
+ <location filename="../src/VBoxMedium.cpp" line="319"/>
<source>&lt;b&gt;No media available&lt;/b&gt;</source>
<comment>medium</comment>
<translation>&lt;b&gt;メディア 利用ä¸å¯&lt;/b&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="317"/>
+ <location filename="../src/VBoxMedium.cpp" line="320"/>
<source>You can create media images using the virtual media manager.</source>
<translation>仮想メディアマãƒãƒ¼ã‚¸ãƒ£ã‚’使ã£ã¦ãƒ¡ãƒ‡ã‚£ã‚¢ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’作æˆã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="327"/>
+ <location filename="../src/VBoxMedium.cpp" line="330"/>
<source>Attaching this hard disk will be performed indirectly using a newly created differencing hard disk.</source>
<comment>medium</comment>
<translation>ã“ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®å‰²ã‚Šå½“ã¦ã¯ã€æ–°è¦ä½œæˆã•れãŸå·®åˆ†ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ä½¿ç”¨ã«ã‚ˆã‚Šã€é–“接的ã«å®Ÿè¡Œã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="482"/>
+ <location filename="../src/VBoxMedium.cpp" line="485"/>
<source>Some of the media in this hard disk chain are inaccessible. Please use the Virtual Media Manager in &lt;b&gt;Show Differencing Hard Disks&lt;/b&gt; mode to inspect these media.</source>
<comment>medium</comment>
<translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ ãƒã‚§ãƒ¼ãƒ³ä¸­ã®ã„ãã¤ã‹ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。仮想メディアマãƒãƒ¼ã‚¸ãƒ£ã®&lt;b&gt;[差分ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’表示]&lt;/b&gt;を使用ã—ã¦ã€ã“れらã®ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’確èªã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/VBoxMedium.cpp" line="499"/>
+ <location filename="../src/VBoxMedium.cpp" line="502"/>
<source>This base hard disk is indirectly attached using the following differencing hard disk:</source>
<comment>medium</comment>
<translation>ã“ã®ãƒ™ãƒ¼ã‚¹ ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã¯ä»¥ä¸‹ã®å·®åˆ†ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’使用ã—ã¦é–“接的ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã™:</translation>
@@ -9959,36 +9923,40 @@ Version %1</source>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/runtime/UIIndicatorsPool.cpp" line="574"/>
+ <location filename="../src/runtime/UIIndicatorsPool.cpp" line="578"/>
<source>Nested Paging</source>
<translation>ãƒã‚¹ãƒ†ãƒƒãƒ‰ãƒšãƒ¼ã‚¸ãƒ³ã‚°</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="665"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="664"/>
<source>MB</source>
<comment>size suffix MBytes=1024KBytes</comment>
<translation>MB</translation>
</message>
+ <message>
+ <location filename="../src/settings/machine/UIMachineSettingsNetwork.cpp" line="234"/>
+ <source>Adapter %1</source>
+ <translation type="unfinished">アダプタ %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="665"/>
<source>&apos;%1 (0x%2)&apos; is an invalid host key code.</source>
<translation type="obsolete">&apos;%1 (0x%2)&apos;ã¯ç„¡åйãªãƒ›ã‚¹ãƒˆã‚­ãƒ¼ã®ã‚³ãƒ¼ãƒ‰ã§ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="128"/>
+ <location filename="../src/VBoxGlobalSettings.cpp" line="132"/>
<source>&apos;%1&apos; is an invalid host-combination code-sequence.</source>
<translation>&apos;%1&apos;ã¯ç„¡åйãªãƒ›ã‚¹ãƒˆã‚­ãƒ¼ã®çµ„ã¿åˆã‚ã›ã§ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="261"/>
+ <location filename="../src/VBoxGlobalSettings.cpp" line="265"/>
<source>The value &apos;%1&apos; of the key &apos;%2&apos; doesn&apos;t match the regexp constraint &apos;%3&apos;.</source>
<translation>&apos;%2&apos;キーã®å€¤&apos;%1&apos;ã¯æ­£è¦è¡¨ç¾ã®è¦å‰‡&apos;%3&apos;ã«é©åˆã—ã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
+ <location filename="../src/VBoxGlobalSettings.cpp" line="256"/>
<source>Cannot delete the key &apos;%1&apos;.</source>
<translation>&apos;%1&apos;キーを削除ã§ãã¾ã›ã‚“。</translation>
</message>
@@ -9996,231 +9964,186 @@ Version %1</source>
<context>
<name>VBoxGlobalSettingsDlg</name>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Category</source>
<translation type="obsolete">カテゴリ</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>[id]</source>
<translation type="obsolete">[id]</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>[link]</source>
<translation type="obsolete">[link]</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>[name]</source>
<translation type="obsolete">[name]</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&lt;i&gt;Select a settings category from the list on the left-hand side and move the mouse over a settings item to get more information&lt;i&gt;.</source>
<translation type="obsolete">&lt;i&gt;å·¦å´ã®ãƒªã‚¹ãƒˆã‹ã‚‰è¨­å®šã®ã‚«ãƒ†ã‚´ãƒªã‚’é¸æŠžã—ã€è¨­å®šé …目をマウスオーãƒãƒ¼ã—ã¦è©³ç´°ãªæƒ…報をå‚ç…§ã—ã¦ãã ã•ã„&lt;i&gt;。</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source> General </source>
<translation type="obsolete">一般</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>0</source>
<translation type="obsolete">0</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source> Input </source>
<translation type="obsolete">入力</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>1</source>
<translation type="obsolete">1</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source> USB </source>
<translation type="obsolete"> USB </translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>2</source>
<translation type="obsolete">2</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Default &amp;Folders</source>
<translation type="obsolete">デフォルト フォルダ(&amp;F)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Machines</source>
<translation type="obsolete">仮想マシン</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>VDI files</source>
<translation type="obsolete">VDIファイル</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Select</source>
<translation type="obsolete">é¸æŠž</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Keyboard</source>
<translation type="obsolete">キーボード(&amp;K)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Host Key</source>
<translation type="obsolete">ホストキー(&amp;H)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Auto capture keyboard</source>
<translation type="obsolete">キーボードã®è‡ªå‹•キャプãƒãƒ£(&amp;A)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;USB Device Filters</source>
<translation type="obsolete">USB デãƒã‚¤ã‚¹ フィルタ(&amp;U)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Ins</source>
<translation type="obsolete">Ins</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Alt+Ins</source>
<translation type="obsolete">Alt+Ins</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Del</source>
<translation type="obsolete">Del</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Ctrl+Up</source>
<translation type="obsolete">Ctrl+Up</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Ctrl+Down</source>
<translation type="obsolete">Ctrl+Down</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Help</source>
<translation type="obsolete">ヘルプ</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>F1</source>
<translation type="obsolete">F1</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Displays the dialog help.</source>
<translation type="obsolete">ダイアログã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Invalid settings detected</source>
<translation type="obsolete">無効ãªè¨­å®šãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;OK</source>
<translation type="obsolete">OK(&amp;O)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Accepts (saves) changes and closes the dialog.</source>
<translation type="obsolete">変更をä¿å­˜ã—ã¦ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‰ã˜ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Cancels changes and closes the dialog.</source>
<translation type="obsolete">変更を破棄ã—ã¦ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‰ã˜ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>VirtualBox Preferences</source>
<translation type="obsolete">VirtualBox 環境設定</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Displays the key used as a Host Key in the VM window. Activate the entry field and press a new Host Key. Note that alphanumeric, cursor movement and editing keys cannot be used.</source>
<translation type="obsolete">仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã§ãƒ›ã‚¹ãƒˆã‚­ãƒ¼ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã‚­ãƒ¼ã‚’表示ã—ã¾ã™ã€‚変更ã™ã‚‹ã«ã¯å…¥åŠ›ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã«ã—ã¦æ–°ã—ã„ホストキーを押ã—ã¦ãã ã•ã„。注:英数字ã€ã‚«ãƒ¼ã‚½ãƒ«ã‚­ãƒ¼ã€ç·¨é›†ã‚­ãƒ¼ã¯ãƒ›ã‚¹ãƒˆã‚­ãƒ¼ã¨ã—ã¦ä½¿ç”¨ã§ãã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>New Filter %1</source>
<comment>usb</comment>
<translation type="obsolete">æ–°è¦ãƒ•ィルタ %1</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Language</source>
<translation type="obsolete">言語</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source> Language </source>
<translation type="obsolete">言語</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>3</source>
<translation type="obsolete">3</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Interface Language</source>
<translation type="obsolete">インターフェース言語(&amp;I)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Author(s):</source>
<translation type="obsolete">作者:</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Language:</source>
<translation type="obsolete">言語:</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source> (built-in)</source>
<comment>Language</comment>
<translation type="obsolete">(内蔵)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&lt;unavailable&gt;</source>
<comment>Language</comment>
<translation type="obsolete">&lt;利用ä¸å¯&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&lt;unknown&gt;</source>
<comment>Author(s)</comment>
<translation type="obsolete">&lt;䏿˜Ž&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>
&lt;qt&gt;Lists all available user interface languages. The effective language is
written in &lt;b&gt;bold&lt;/b&gt;. Select &lt;i&gt;Default&lt;/i&gt; to reset
@@ -10230,83 +10153,67 @@ to the system default language.&lt;/qt&gt;
システムã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆè¨€èªžã«æˆ»ã™ã«ã¯&lt;i&gt;デフォルト&lt;/i&gt;ã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Default</source>
<comment>Language</comment>
<translation type="obsolete">デフォルト</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Displays the path to the default VDI folder. This folder is used, if not explicitly specified otherwise, when adding existing or creating new virtual hard disks.</source>
<translation type="obsolete">デフォルトã®VDIフォルダã®ãƒ‘スを表示ã—ã¾ã™ã€‚æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ä½œæˆæ™‚ã«ä¿å­˜å…ˆã‚’æ˜Žç¤ºçš„ã«æŒ‡å®šã—ãªã„å ´åˆã€ã“ã®ãƒ•ォルダãŒä½¿ç”¨ã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Resets the virtual machine folder path to the default value. The actual default path will be displayed after accepting the changes and opening this dialog again.</source>
<translation type="obsolete">仮想マシン フォルダã®ãƒ‘ã‚¹ã‚’ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã«æˆ»ã—ã¾ã™ã€‚変更後ã€å†åº¦ã“ã®ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‹ãã¨ãƒ‡ãƒ•ォルトã®ãƒ‘スãŒè¡¨ç¤ºã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Resets the VDI folder path to the default value. The actual default path will be displayed after accepting the changes and opening this dialog again.</source>
<translation type="obsolete">VDIフォルダã®ãƒ‘ã‚¹ã‚’ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã«æˆ»ã—ã¾ã™ã€‚変更後ã€å†åº¦ã“ã®ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‹ãã¨ãƒ‡ãƒ•ォルト パスãŒè¡¨ç¤ºã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Displays the path to the default virtual machine folder. This folder is used, if not explicitly specified otherwise, when creating new virtual machines.</source>
<translation type="obsolete">デフォルトã®ä»®æƒ³ãƒžã‚·ãƒ³ フォルダã®ãƒ‘スを表示ã—ã¾ã™ã€‚æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã®ä½œæˆæ™‚ã«ä¿å­˜å…ˆã‚’æ˜Žç¤ºçš„ã«æŒ‡å®šã—ãªã„å ´åˆã€ã“ã®ãƒ•ォルダãŒä½¿ç”¨ã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Opens a dialog to select the default VDI folder.</source>
<translation type="obsolete">ダイアログを開ã„ã¦ãƒ‡ãƒ•ォルトã®VDIãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠžã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Opens a dialog to select the default virtual machine folder.</source>
<translation type="obsolete">ダイアログを開ã„ã¦ãƒ‡ãƒ•ォルトã®ä»®æƒ³ãƒžã‚·ãƒ³ ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠžã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>When checked, the keyboard is automatically captured every time the VM window is activated. When the keyboard is captured, all keystrokes (including system ones like Alt-Tab) are directed to the VM.</source>
<translation type="obsolete">仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã®ã¨ãã€ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã‚’自動的ã«ã‚­ãƒ£ãƒ—ãƒãƒ£ã—ã¾ã™ã€‚キーボードãŒã‚­ãƒ£ãƒ—ãƒãƒ£ã•れるã¨ã€ã™ã¹ã¦ã®ã‚­ãƒ¼ã‚¹ãƒˆãƒ­ãƒ¼ã‚¯(Alt-Tabãªã©ã‚’å«ã‚€)ãŒä»®æƒ³ãƒžã‚·ãƒ³ã«é€ã‚‰ã‚Œã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>V&amp;RDP Authentication Library</source>
<translation type="obsolete">VRDPèªè¨¼ãƒ©ã‚¤ãƒ–ラリ(&amp;R)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Displays the path to the library that provides authentication for Remote Display (VRDP) clients.</source>
<translation type="obsolete">リモートディスプレイ(VRDP)クライアントã«èªè¨¼ã‚’æä¾›ã™ã‚‹ãƒ©ã‚¤ãƒ–ラリã®ãƒ‘スを表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Opens a dialog to select the VRDP authentication library file.</source>
<translation type="obsolete">VRDPèªè¨¼ãƒ©ã‚¤ãƒ–ラリ ファイルã®é¸æŠžãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‹ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Resets the authentication library file to the default value. The actual default library file will be displayed after accepting the changes and opening this dialog again.</source>
<translation type="obsolete">èªè¨¼ãƒ©ã‚¤ãƒ–ラリ ファイルã®å€¤ã‚’デフォルト値ã«ãƒªã‚»ãƒƒãƒˆã—ã¾ã™ã€‚変更をé©ç”¨ã—ã€å†åº¦ã“ã®ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‹ãã¨ç¾åœ¨ã®èªè¨¼ãƒ©ã‚¤ãƒ–ラリ ファイルãŒè¡¨ç¤ºã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Extended Features</source>
<translation type="obsolete">拡張機能(&amp;E)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Enable &amp;VT-x/AMD-V</source>
<translation type="obsolete">VT-x/AMD-Vを有効化(&amp;V)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Defines whether virtual machines should try to make use of the host CPU&apos;s hardware virtualization extensions such as Intel VT-x and AMD-V by default or not.</source>
<translation type="obsolete">仮想マシンãŒãƒ›ã‚¹ãƒˆCPUã®Intel VT-xã‚„AMD-Vãªã©ã®ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½ã‚’デフォルトã§ä½¿ç”¨ã™ã‚‹ã‹ã©ã†ã‹ã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>
&lt;qt&gt;Lists all global USB
filters. The checkbox to the left
@@ -10321,17 +10228,14 @@ to the system default language.&lt;/qt&gt;
USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹å³å´ã®ãƒœã‚¿ãƒ³ã‚’使用ã—ã¦ãã ã•ã„。&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Add Empty Filter</source>
<translation type="obsolete">空ã®ãƒ•ィルタを追加</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Add Empty Filter</source>
<translation type="obsolete">空ã®ãƒ•ィルタを追加(&amp;A)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>
&lt;qt&gt;Adds a new USB filter with all fields initially set to
empty strings. Note that such a filter will match any attached USB
@@ -10340,17 +10244,14 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<translation type="obsolete">&lt;qt&gt;ã™ã¹ã¦ã®ãƒ•ィールドãŒç©ºã®æ–°è¦USBフィルタを追加ã—ã¾ã™ã€‚注:ã“ã®ãƒ•ィルタã¯ã™ã¹ã¦ã®æŽ¥ç¶šã•れãŸUSB デãƒã‚¤ã‚¹ã«é©åˆã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Add Filter From Device</source>
<translation type="obsolete">デãƒã‚¤ã‚¹ã‹ã‚‰ãƒ•ィルタを追加</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>A&amp;dd Filter From Device</source>
<translation type="obsolete">デãƒã‚¤ã‚¹ã‹ã‚‰ãƒ•ィルタを追加ã™ã‚‹(&amp;D)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&lt;qt&gt;Adds a new USB filter with all fields set to the
values of the selected USB device attached to the host
PC.&lt;/qt&gt;
@@ -10358,51 +10259,42 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<translation type="obsolete">&lt;qt&gt;é¸æŠžã—ãŸãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã®USB デãƒã‚¤ã‚¹ã®å€¤ã‚’ã™ã¹ã¦ã®ãƒ•ィールドã«è¨­å®šã—ãŸæ–°è¦USBフィルタを追加ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Remove Filter</source>
<translation type="obsolete">フィルタを除去</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Remove Filter</source>
<translation type="obsolete">フィルタを除去ã™ã‚‹(&amp;R)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>
&lt;qt&gt;Removes the highlighted USB filter.&lt;/qt&gt;
</source>
<translation type="obsolete">&lt;qt&gt;ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸãƒ•ィルタを除去ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Move Filter Up</source>
<translation type="obsolete">フィルタを上ã«ç§»å‹•</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Move Filter Up</source>
<translation type="obsolete">フィルタを上ã«ç§»å‹•ã™ã‚‹(&amp;M)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>
&lt;qt&gt;Moves the highlighted USB filter up.&lt;/qt&gt;
</source>
<translation type="obsolete">&lt;qt&gt;ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸãƒ•ィルタを上ã«ç§»å‹•ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Move Filter Down</source>
<translation type="obsolete">フィルタを下ã«ç§»å‹•</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>M&amp;ove Filter Down</source>
<translation type="obsolete">フィルタを下ã«ç§»å‹•(&amp;O)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>
&lt;qt&gt;Moves the highlighted USB filter down.&lt;/qt&gt;
</source>
@@ -10412,32 +10304,26 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxHardDiskSettings</name>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Slot</source>
<translation type="obsolete">スロット</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Hard Disk</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>VBoxHardDiskSettings</source>
<translation type="obsolete">VBoxHardDiskSettings</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Hard Disks</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯(&amp;H)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Enable SATA Controller</source>
<translation type="obsolete">SATA コントローラを有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>
&lt;qt&gt;When checked, enables the virtual SATA
controller of this machine. Note that you cannot
@@ -10447,12 +10333,10 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<translation type="obsolete">&lt;qt&gt;ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®ä»®æƒ³SATA コントローラを有効ã«ã—ã¾ã™ã€‚注:仮想コントローラãŒç„¡åйãªã¨ãã€ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’SATAãƒãƒ¼ãƒˆã«å–り付ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Hard Disks &amp;Attachments</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®å‰²ã‚Šå½“ã¦(&amp;A)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>
&lt;qt&gt;Lists all hard disks attached to
this machine. Use a mouse double-click or the
@@ -10469,66 +10353,54 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Add Attachment</source>
<translation type="obsolete">割り当ã¦ã®è¿½åŠ </translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Add Attachment</source>
<translation type="obsolete">割り当ã¦ã‚’追加ã™ã‚‹(&amp;A)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Ins</source>
<translation type="obsolete">Ins</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>
&lt;qt&gt;Adds a new hard disk attachment.&lt;/qt&gt;
</source>
<translation type="obsolete">&lt;qt&gt;æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®å‰²ã‚Šå½“ã¦ã‚’追加ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Remove Attachment</source>
<translation type="obsolete">割り当ã¦ã‚’除去</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Remove Attachment</source>
<translation type="obsolete">割り当ã¦ã‚’除去ã™ã‚‹(&amp;R)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Delete</source>
<translation type="obsolete">削除</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>
&lt;qt&gt;Removes the highlighted hard disk attachment.&lt;/qt&gt;
</source>
<translation type="obsolete">&lt;qt&gt;ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®å‰²ã‚Šå½“ã¦ã‚’除去ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Select Hard Disk</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Select Hard Disk</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’é¸æŠžã™ã‚‹(&amp;S)</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Ctrl+Space</source>
<translation type="obsolete">Ctrl+スペース</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>
&lt;qt&gt;Invokes the Virtual Disk Manager to select a hard disk
to attach to the currently highlighted slot.&lt;/qt&gt;
@@ -10536,17 +10408,14 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<translation type="obsolete">&lt;qt&gt;仮想ディスクマãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•ã—ã€ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’ç¾åœ¨ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸã‚¹ãƒ­ãƒƒãƒˆã«å‰²ã‚Šå½“ã¦ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&lt;i&gt;%1&lt;/i&gt; uses the hard disk that is already attached to &lt;i&gt;%2&lt;/i&gt;</source>
<translation type="obsolete">&lt;i&gt;%1&lt;/i&gt;ã¯ã™ã§ã«&lt;i&gt;%2&lt;/i&gt;ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã‚‹</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>Double-click to add a new attachment</source>
<translation type="obsolete">ãƒ€ãƒ–ãƒ«ã‚¯ãƒªãƒƒã‚¯ã§æ–°è¦ã®å‰²ã‚Šå½“ã¦ã‚’追加</translation>
</message>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;</source>
<translation type="obsolete"> &lt;i&gt;%1&lt;/i&gt;ã®ãŸã‚ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒé¸æŠžã•れã¦ã„ãªã„</translation>
</message>
@@ -10554,7 +10423,6 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxHelpButton</name>
<message>
- <location filename="../src/VBoxGlobalSettings.cpp" line="252"/>
<source>&amp;Help</source>
<translation type="obsolete">ヘルプ(&amp;H)</translation>
</message>
@@ -10562,12 +10430,12 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxImportApplianceWgt</name>
<message>
- <location filename="../src/widgets/VBoxImportApplianceWgt.cpp" line="141"/>
+ <location filename="../src/widgets/VBoxImportApplianceWgt.cpp" line="146"/>
<source>Importing Appliance ...</source>
<translation>仮想アプライアンスã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ...</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxImportApplianceWgt.cpp" line="64"/>
+ <location filename="../src/widgets/VBoxImportApplianceWgt.cpp" line="66"/>
<source>Reading Appliance ...</source>
<translation>仮想アプライアンスã®èª­ã¿è¾¼ã¿...</translation>
</message>
@@ -10654,22 +10522,18 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxMediaComboBox</name>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="432"/>
<source>&lt;no hard disk&gt;</source>
<translation type="obsolete">&lt;ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãªã—&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="432"/>
<source>No hard disk</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãªã—</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="432"/>
<source>No media available. Use the Virtual Media Manager to add media of the corresponding type.</source>
<translation type="obsolete">利用å¯èƒ½ãªãƒ¡ãƒ‡ã‚£ã‚¢ãŒã‚りã¾ã›ã‚“。 仮想メディアマãƒãƒ¼ã‚¸ãƒ£ã‚’使用ã—ã¦ã€å¯¾å¿œã™ã‚‹ã‚¿ã‚¤ãƒ—ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’追加ã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="432"/>
<source>&lt;no media&gt;</source>
<translation type="obsolete">&lt;メディアãªã—&gt;</translation>
</message>
@@ -10677,147 +10541,166 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxMediaManagerDlg</name>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="587"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="608"/>
<source>&amp;Actions</source>
<translation>動作(&amp;A)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="589"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="610"/>
<source>&amp;New...</source>
<translation>æ–°è¦(&amp;N)...</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="590"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="611"/>
<source>&amp;Add...</source>
<translation>追加(&amp;A)...</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="591"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="612"/>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="613"/>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="614"/>
<source>R&amp;emove</source>
<translation>除去(&amp;E)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="592"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="615"/>
<source>Re&amp;lease</source>
<translation>解放(&amp;L)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="593"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="616"/>
<source>Re&amp;fresh</source>
<translation>æœ€æ–°ã®æƒ…å ±ã«æ›´æ–°(&amp;F)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="601"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="626"/>
<source>Create a new virtual hard disk</source>
<translation>æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ä½œæˆ</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="602"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="627"/>
<source>Add an existing medium</source>
<translation>既存ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’追加</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="603"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="628"/>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="629"/>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="630"/>
<source>Remove the selected medium</source>
<translation>é¸æŠžã—ãŸãƒ¡ãƒ‡ã‚£ã‚¢ã‚’除去</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="604"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="631"/>
<source>Release the selected medium by detaching it from the machines</source>
<translation>é¸æŠžã—ãŸãƒ¡ãƒ‡ã‚£ã‚¢ã‚’仮想マシンã‹ã‚‰å‰²ã‚Šå½“ã¦è§£é™¤ã—ã¦è§£æ”¾ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="605"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="632"/>
<source>Refresh the media list</source>
<translation>ãƒ¡ãƒ‡ã‚£ã‚¢ãƒªã‚¹ãƒˆã‚’æœ€æ–°ã®æƒ…å ±ã«æ›´æ–°</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="994"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="664"/>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="1014"/>
<source>CD/DVD-ROM disk</source>
<translation>CD/DVD-ROMディスク</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="1001"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="1021"/>
<source>hard disk</source>
<translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="625"/>
<source>Location</source>
- <translation>場所</translation>
+ <translation type="obsolete">場所</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="619"/>
<source>Type (Format)</source>
- <translation>タイプ(å½¢å¼)</translation>
+ <translation type="obsolete">タイプ(å½¢å¼)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.ui" line="314"/>
<source>Attached to</source>
- <translation>割り当ã¦</translation>
+ <translation type="obsolete">割り当ã¦</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="628"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="649"/>
<source>Checking accessibility</source>
<translation>アクセスå¯å¦ã‚’確èª</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="644"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="664"/>
<source>&amp;Select</source>
<translation>é¸æŠž(&amp;S)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="644"/>
<source>All hard disk images (%1)</source>
<translation type="obsolete">ã™ã¹ã¦ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸(%1)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="1026"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="1046"/>
<source>All files (*)</source>
<translation>ã™ã¹ã¦ã®ãƒ•ァイル(*)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="1000"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="1020"/>
<source>Select a hard disk image file</source>
<translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="1000"/>
<source>CD/DVD-ROM images (*.iso);;All files (*)</source>
<translation type="obsolete">CD/DVD-ROMイメージ(*.iso);;ã™ã¹ã¦ã®ãƒ•ァイル(*)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="993"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="1013"/>
<source>Select a CD/DVD-ROM disk image file</source>
<translation>CD/DVD-ROMãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="993"/>
<source>Floppy images (*.img);;All files (*)</source>
<translation type="obsolete">フロッピーイメージ(*.img);;ã™ã¹ã¦ã®ãƒ•ァイル(*)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="1007"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="1027"/>
<source>Select a floppy disk image file</source>
<translation>ãƒ•ãƒ­ãƒƒãƒ”ãƒ¼ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="1008"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="1028"/>
<source>floppy disk</source>
<translation>フロッピーディスク</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="1025"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="1045"/>
<source>All %1 images (%2)</source>
<translation>ã™ã¹ã¦ã®%1イメージ(%2)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="1410"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="1463"/>
<source>&lt;i&gt;Not&amp;nbsp;Attached&lt;/i&gt;</source>
<translation>&lt;i&gt;未割り当ã¦&lt;/i&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="1854"/>
+ <location filename="../src/VBoxMediaManagerDlg.cpp" line="1926"/>
<source>--</source>
<comment>no info</comment>
<translation>--</translation>
@@ -10833,7 +10716,9 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯(&amp;D)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.ui" line="266"/>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="68"/>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="212"/>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="300"/>
<source>Name</source>
<translation>åå‰</translation>
</message>
@@ -10848,37 +10733,64 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<translation>実際ã®ã‚µã‚¤ã‚º</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.ui" line="156"/>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="101"/>
+ <source>Type:</source>
+ <translation type="unfinished">タイプ:</translation>
+ </message>
+ <message>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="118"/>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="240"/>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="331"/>
+ <source>Location:</source>
+ <translation type="unfinished">場所:</translation>
+ </message>
+ <message>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="135"/>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="152"/>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="169"/>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="257"/>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="348"/>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="190"/>
<source>&amp;CD/DVD Images</source>
<translation>CD/DVDイメージ(&amp;C)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.ui" line="271"/>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="217"/>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="305"/>
<source>Size</source>
<translation>サイズ</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.ui" line="244"/>
+ <location filename="../src/VBoxMediaManagerDlg.ui" line="278"/>
<source>&amp;Floppy Images</source>
<translation>フロッピーイメージ(&amp;F)</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="620"/>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>割り当ã¦</translation>
+ <translation type="obsolete">割り当ã¦</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="623"/>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>割り当ã¦</translation>
+ <translation type="obsolete">割り当ã¦</translation>
</message>
<message>
- <location filename="../src/VBoxMediaManagerDlg.cpp" line="626"/>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>割り当ã¦</translation>
+ <translation type="obsolete">割り当ã¦</translation>
</message>
</context>
<context>
@@ -10907,42 +10819,34 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxNIList</name>
<message>
- <location filename="../src/widgets/VBoxMiniToolBar.cpp" line="116"/>
<source>VirtualBox Host Interface %1</source>
<translation type="obsolete">VirtualBox ホスト インターフェース %1</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxMiniToolBar.cpp" line="116"/>
<source>&lt;p&gt;Do you want to remove the selected host network interface &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;?&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; This interface may be in use by one or more network adapters of this or another VM. After it is removed, these adapters will no longer work until you correct their settings by either choosing a different interface name or a different adapter attachment type.&lt;/p&gt;</source>
<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/widgets/VBoxMiniToolBar.cpp" line="116"/>
<source>Host &amp;Interfaces</source>
<translation type="obsolete">ホスト インターフェース(&amp;I)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxMiniToolBar.cpp" line="116"/>
<source>Lists all available host interfaces.</source>
<translation type="obsolete">利用å¯èƒ½ãªãƒ›ã‚¹ãƒˆ インターフェースをリスト表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxMiniToolBar.cpp" line="116"/>
<source>A&amp;dd New Host Interface</source>
<translation type="obsolete">æ–°è¦ãƒ›ã‚¹ãƒˆ インターフェースã®è¿½åŠ (&amp;D)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxMiniToolBar.cpp" line="116"/>
<source>&amp;Remove Selected Host Interface</source>
<translation type="obsolete">é¸æŠžã—ãŸãƒ›ã‚¹ãƒˆ インターフェースã®é™¤åŽ»(&amp;R)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxMiniToolBar.cpp" line="116"/>
<source>Adds a new host interface.</source>
<translation type="obsolete">æ–°è¦ãƒ›ã‚¹ãƒˆ インターフェースを追加ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxMiniToolBar.cpp" line="116"/>
<source>Removes the selected host interface.</source>
<translation type="obsolete">é¸æŠžã—ãŸãƒ›ã‚¹ãƒˆ インターフェースを除去ã—ã¾ã™ã€‚</translation>
</message>
@@ -10950,9 +10854,8 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxNetworkDialog</name>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="148"/>
<source>Network Adapters</source>
- <translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタ</translation>
+ <translation type="obsolete">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタ</translation>
</message>
</context>
<context>
@@ -10968,7 +10871,6 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<translation>仮想マシンã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹OSã®ç¨®é¡žã‚’表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxOSTypeSelectorWidget.cpp" line="155"/>
<source>V&amp;ersion:</source>
<translation type="obsolete">ãƒãƒ¼ã‚¸ãƒ§ãƒ³(&amp;E):</translation>
</message>
@@ -10987,30 +10889,35 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<name>VBoxProblemReporter</name>
<message>
<location filename="../src/globals/VBoxProblemReporter.cpp" line="172"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="280"/>
<source>VirtualBox - Information</source>
<comment>msg box title</comment>
<translation>VirtualBox - 情報</translation>
</message>
<message>
<location filename="../src/globals/VBoxProblemReporter.cpp" line="176"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="284"/>
<source>VirtualBox - Question</source>
<comment>msg box title</comment>
<translation>VirtualBox - 質å•</translation>
</message>
<message>
<location filename="../src/globals/VBoxProblemReporter.cpp" line="180"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="288"/>
<source>VirtualBox - Warning</source>
<comment>msg box title</comment>
<translation>VirtualBox - 警告</translation>
</message>
<message>
<location filename="../src/globals/VBoxProblemReporter.cpp" line="184"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="292"/>
<source>VirtualBox - Error</source>
<comment>msg box title</comment>
<translation>VirtualBox - エラー</translation>
</message>
<message>
<location filename="../src/globals/VBoxProblemReporter.cpp" line="188"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="296"/>
<source>VirtualBox - Critical Error</source>
<comment>msg box title</comment>
<translation>VirtualBox - é‡å¤§ãªã‚¨ãƒ©ãƒ¼</translation>
@@ -11022,638 +10929,636 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<translation>次回ã‹ã‚‰ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã—ãªã„</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="397"/>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>クラッシュを防ããŸã‚ã€Windows/x64ã§ã¯ä»®æƒ³ãƒžã‚·ãƒ³ã«å«ã¾ã‚Œã‚‹ã™ã¹ã¦ã®ãƒ•ァイルã®å‰Šé™¤ã¯ç¾åœ¨ã§ãã¾ã›ã‚“。ã“ã‚Œã¯æ¬¡å›žã®ãƒªãƒªãƒ¼ã‚¹ã§ä¿®æ­£ã•れã¾ã™ã€‚</translation>
+ <translation type="obsolete">クラッシュを防ããŸã‚ã€Windows/x64ã§ã¯ä»®æƒ³ãƒžã‚·ãƒ³ã«å«ã¾ã‚Œã‚‹ã™ã¹ã¦ã®ãƒ•ァイルã®å‰Šé™¤ã¯ç¾åœ¨ã§ãã¾ã›ã‚“。ã“ã‚Œã¯æ¬¡å›žã®ãƒªãƒªãƒ¼ã‚¹ã§ä¿®æ­£ã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="442"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="535"/>
<source>Failed to open &lt;tt&gt;%1&lt;/tt&gt;. Make sure your desktop environment can properly handle URLs of this type.</source>
<translation>&lt;tt&gt;%1&lt;/tt&gt;ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚デスクトップ環境ãŒé©åˆ‡ã«URLを扱ãˆã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="476"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="569"/>
<source>&lt;p&gt;Failed to initialize COM or to find the VirtualBox COM server. Most likely, the VirtualBox server is not running or failed to start.&lt;/p&gt;&lt;p&gt;The application will now terminate.&lt;/p&gt;</source>
<translation>&lt;p&gt;COMã®åˆæœŸåŒ–ã«å¤±æ•—ã—ãŸã‹ã€ã¾ãŸã¯VirtualBox COMサーãƒãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚VirtualBoxサーãƒãŒèµ·å‹•ã—ã¦ã„ãªã„ã‹ã€ã¾ãŸã¯èµ·å‹•ã«å¤±æ•—ã—ã¦ã„ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;アプリケーションを終了ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="486"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="579"/>
<source>&lt;p&gt;Failed to create the VirtualBox COM object.&lt;/p&gt;&lt;p&gt;The application will now terminate.&lt;/p&gt;</source>
<translation>&lt;p&gt;VirtualBox COMオブジェクトã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;/p&gt;&lt;p&gt;アプリケーションを終了ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="522"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="615"/>
<source>Failed to set global VirtualBox properties.</source>
<translation>グローãƒãƒ«ãªVirtualBoxã®ãƒ—ロパティã®è¨­å®šã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="552"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="629"/>
<source>Failed to access the USB subsystem.</source>
<translation>USBサブシステムã®ã‚¢ã‚¯ã‚»ã‚¹ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="563"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="640"/>
<source>Failed to create a new virtual machine.</source>
<translation>æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="575"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="652"/>
<source>Failed to create a new virtual machine &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/VBoxProblemReporter.cpp" line="585"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="662"/>
<source>Failed to open virtual machine located in %1.</source>
<translation>仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="594"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="673"/>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="682"/>
<source>Failed to add virtual machine &lt;b&gt;%1&lt;/b&gt; located in &lt;i&gt;%2&lt;/i&gt; because its already present.</source>
<translation>仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;(&lt;i&gt;&quot;%2&quot;&lt;/i&gt;)ã®è¿½åŠ ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="604"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="692"/>
<source>Failed to apply the settings to the virtual machine &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/VBoxProblemReporter.cpp" line="665"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="736"/>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="740"/>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="740"/>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="751"/>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="764"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="778"/>
<source>Failed to start the virtual machine &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/VBoxProblemReporter.cpp" line="677"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="790"/>
<source>Failed to pause the execution of the virtual machine &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/VBoxProblemReporter.cpp" line="688"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="801"/>
<source>Failed to resume the execution of the virtual machine &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/VBoxProblemReporter.cpp" line="725"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="824"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="838"/>
<source>Failed to save the state of the virtual machine &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/VBoxProblemReporter.cpp" line="751"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="850"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="865"/>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="877"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="891"/>
<source>Failed to create a snapshot of the virtual machine &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/VBoxProblemReporter.cpp" line="775"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="903"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="915"/>
<source>Failed to stop the virtual machine &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/VBoxProblemReporter.cpp" line="787"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="927"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="935"/>
<source>Failed to remove the virtual machine &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/VBoxProblemReporter.cpp" line="797"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="945"/>
<source>Failed to discard the saved state of the virtual machine &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/VBoxProblemReporter.cpp" line="797"/>
<source>Failed to discard the snapshot &lt;b&gt;%1&lt;/b&gt; of the virtual machine &lt;b&gt;%2&lt;/b&gt;.</source>
<translation type="obsolete">仮想マシン&lt;b&gt;&quot;%2&quot;&lt;/b&gt;ã®ã‚¹ãƒŠãƒƒãƒ—ショット &lt;b&gt;%1&lt;/b&gt; ã®ç ´æ£„ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="797"/>
<source>Failed to discard the current state of the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="obsolete">仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®æœ€æ–°ã®çŠ¶æ…‹ã®ç ´æ£„ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="797"/>
<source>Failed to discard the current snapshot and the current state of the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="obsolete">仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®æœ€æ–°ã®ã‚¹ãƒŠãƒƒãƒ—ショットã¨çŠ¶æ…‹ã®ç ´æ£„ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="942"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1099"/>
<source>There is no virtual machine named &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/VBoxProblemReporter.cpp" line="942"/>
<source>&lt;p&gt;Are you sure you want to permanently delete the virtual machine &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;This operation cannot be undone.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;を削除ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;&lt;p&gt;ã“ã®æ“作ã¯å…ƒã«æˆ»ã›ã¾ã›ã‚“。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="942"/>
<source>&lt;p&gt;Are you sure you want to unregister the inaccessible virtual machine &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;You will not be able to register it again from GUI.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;アクセスã§ããªã„仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ç™»éŒ²ã‚’解除ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;&lt;p&gt;GUIã‹ã‚‰ãれを登録ã—ç›´ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“。&lt;/p&gt;
</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1087"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1244"/>
<source>&lt;p&gt;Are you sure you want to discard the saved state of the virtual machine &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;This operation is equivalent to resetting or powering off the machine without doing a proper shutdown of the guest OS.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ä¿å­˜ã•れãŸçŠ¶æ…‹ã‚’ç ´æ£„ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;&lt;p&gt;ã“ã®æ“作ã¯ã‚²ã‚¹ãƒˆOSã‚’é©åˆ‡ã«ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã›ãšã«ãƒªã‚»ãƒƒãƒˆã¾ãŸã¯é›»æºã‚’オフã«ã™ã‚‹ã“ã¨ã¨åŒç­‰ã§ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1087"/>
<source>&lt;p&gt;Releasing this media image will detach it from the following virtual machine(s): &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Continue?&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;ã“ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’解放ã™ã‚‹ã¨ã€ä»¥ä¸‹ã®ä»®æƒ³ãƒžã‚·ãƒ³ã§ã®å‰²ã‚Šå½“ã¦ãŒè§£é™¤ã•れã¾ã™:&lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;続行ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1087"/>
<source>&lt;p&gt;The image file &lt;b&gt;%1&lt;/b&gt; already exists. You cannot create a new virtual hard disk that uses this file, because it can be already used by another virtual hard disk.&lt;/p&gt;&lt;p&gt;Please specify a different image file name.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;イメージファイル&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚ä»–ã®ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã§ã“ã®åå‰ãŒä½¿ç”¨ã•れã¦ã„ã‚‹ãŸã‚ã€æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’作æˆã§ãã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;別ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ァイルåを指定ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1087"/>
<source>Failed to delete the virtual hard disk image &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="obsolete">仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1087"/>
<source>&lt;p&gt;Do you want to remove (unregister) the virtual hard disk &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;?&lt;/nobr&gt;&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯&lt;nobr&gt;&lt;b&gt;&quot;%1&quot;&lt;/b&gt;を除去(登録解除)ã—ã¾ã™ã‹ï¼Ÿ&lt;/nobr&gt;&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1087"/>
<source>Failed to create the virtual hard disk image &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;.&lt;/nobr&gt;</source>
<translation type="obsolete">仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸&lt;nobr&gt;&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1087"/>
<source>hard disk</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1087"/>
<source>CD/DVD image</source>
<translation type="obsolete">CD/DVDイメージ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1087"/>
<source>floppy image</source>
<translation type="obsolete">フロッピーイメージ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1087"/>
<source>Failed to register the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;.</source>
<translation type="obsolete">%1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;ã®ç™»éŒ²ã«å¤±æ•—ã—ã¾ã—ãŸã€‚
</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1087"/>
<source>Failed to unregister the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;.</source>
<translation type="obsolete">%1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;ã®ç™»éŒ²è§£é™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1366"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1531"/>
<source>Failed to create a new session.</source>
<translation>æ–°è¦ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1384"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1549"/>
<source>Failed to open a session for the virtual machine &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/VBoxProblemReporter.cpp" line="1384"/>
<source>Failed to determine the accessibility state of the media &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;. Some of the registered media may become inaccessible.</source>
<translation type="obsolete">メディア&lt;nobr&gt;&lt;b&gt;&quot;%1&quot;&lt;/b&gt;&lt;/nobr&gt;ã®ã‚¢ã‚¯ã‚»ã‚¹å¯å¦çŠ¶æ…‹ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚登録ã•れãŸãƒ¡ãƒ‡ã‚£ã‚¢ã®ã„ãã¤ã‹ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ããªã„ã‹ã‚‚ã—れã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1384"/>
<source>Failed to create the host network interface &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="obsolete">ホスト ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ インターフェース&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2677"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2849"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2857"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1436"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1589"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1601"/>
<source>Failed to attach the USB device &lt;b&gt;%1&lt;/b&gt; to the virtual machine &lt;b&gt;%2&lt;/b&gt;.</source>
<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/VBoxProblemReporter.cpp" line="1462"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1615"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1627"/>
<source>Failed to detach the USB device &lt;b&gt;%1&lt;/b&gt; from the virtual machine &lt;b&gt;%2&lt;/b&gt;.</source>
<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/VBoxProblemReporter.cpp" line="2743"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2897"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2923"/>
<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/VBoxProblemReporter.cpp" line="2730"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2910"/>
<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/VBoxProblemReporter.cpp" line="2730"/>
<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 type="obsolete">&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/VBoxProblemReporter.cpp" line="2730"/>
<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 type="obsolete">&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;アイコンã§è¡¨ç¤ºã•れã¾ã™ã€‚ã“ã®ã‚¢ã‚¤ã‚³ãƒ³ã¯ãƒžã‚¦ã‚¹ã‚¢ã‚¤ã‚³ãƒ³ã¨å…±ã«ç¾åœ¨ã®ã‚­ãƒ¼ãƒœâˆ’ドã¨ãƒžã‚¦ã‚¹ã®ã‚­ãƒ£ãƒ—ãƒãƒ£çŠ¶æ…‹ã‚’è¡¨ç¤ºã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2730"/>
<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 type="obsolete">&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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1773"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1938"/>
<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/VBoxProblemReporter.cpp" line="1793"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1958"/>
<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/VBoxProblemReporter.cpp" line="2014"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2179"/>
<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/VBoxProblemReporter.cpp" line="2141"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2306"/>
<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/VBoxProblemReporter.cpp" line="2169"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2334"/>
<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/VBoxProblemReporter.cpp" line="2182"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2347"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2182"/>
<source>You are about to remove the Extension Pack &lt;b&gt;%1&lt;/b&gt;. Are you sure you want to do that?</source>
<translation type="obsolete">機能拡張パッケージ&lt;b&gt;&quot;%1&quot;&lt;/b&gt;を除去ã—ã¾ã™ã€‚本当ã«é™¤åŽ»ã—ã¾ã™ã‹ï¼Ÿ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2273"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2438"/>
<source>&amp;Remove</source>
<translation>除去(&amp;R)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2286"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2451"/>
<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/VBoxProblemReporter.cpp" line="2293"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2458"/>
<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/VBoxProblemReporter.cpp" line="2322"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2487"/>
<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/VBoxProblemReporter.cpp" line="2328"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2493"/>
<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/VBoxProblemReporter.cpp" line="2334"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2499"/>
<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/VBoxProblemReporter.cpp" line="2351"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2516"/>
<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/VBoxProblemReporter.cpp" line="2353"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2518"/>
<source>Severity: </source>
<comment>runtime error info</comment>
<translation>é‡è¦åº¦:</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2364"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2529"/>
<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/VBoxProblemReporter.cpp" line="2376"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2541"/>
<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/VBoxProblemReporter.cpp" line="2385"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2550"/>
<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/VBoxProblemReporter.cpp" line="2385"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2732"/>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">申ã—訳ã‚りã¾ã›ã‚“ã€‚ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚</translation>
+ <translation type="unfinished">申ã—訳ã‚りã¾ã›ã‚“ã€‚ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2691"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2871"/>
<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/VBoxProblemReporter.cpp" line="2697"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2877"/>
<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/VBoxProblemReporter.cpp" line="2703"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2883"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2803"/>
<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>&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>
+ <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/VBoxProblemReporter.cpp" line="2896"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="3093"/>
<source>Result&amp;nbsp;Code: </source>
<comment>error info</comment>
<translation>終了コード&amp;nbsp;: </translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2902"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="3099"/>
<source>Component: </source>
<comment>error info</comment>
<translation>コンãƒãƒ¼ãƒãƒ³ãƒˆ: </translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2910"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="3107"/>
<source>Interface: </source>
<comment>error info</comment>
<translation>インターフェース: </translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2919"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="3116"/>
<source>Callee: </source>
<comment>error info</comment>
<translation>呼ã³å‡ºã—å…ˆ: </translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2927"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="3124"/>
<source>Callee&amp;nbsp;RC: </source>
<comment>error info</comment>
<translation>呼ã³å‡ºã—å…ˆ&amp;nbsp;RC: </translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="451"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="544"/>
<source>&lt;p&gt;Could not find a language file for the language &lt;b&gt;%1&lt;/b&gt; in the directory &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;The language will be temporarily reset to the system default language. Please go to the &lt;b&gt;Preferences&lt;/b&gt; dialog which you can open from the &lt;b&gt;File&lt;/b&gt; menu of the main VirtualBox window, and select one of the existing languages on the &lt;b&gt;Language&lt;/b&gt; page.&lt;/p&gt;</source>
<translation>&lt;p&gt;言語ファイル&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ãŒ&lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt;ディレクトリ中ã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;言語ã¯ä¸€æ™‚çš„ã«ã‚·ã‚¹ãƒ†ãƒ ã®ãƒ‡ãƒ•ォルト言語ã«è¨­å®šã•れã¾ã™ã€‚VirtualBoxメインウィンドウã®&lt;b&gt;[ファイル]&lt;/b&gt;メニューã‹ã‚‰&lt;b&gt;[環境設定]&lt;/b&gt;ダイアログを開ãã€&lt;b&gt;[言語]&lt;/b&gt;ページã§è¡¨ç¤ºã•れã¦ã„ã‚‹è¨€èªžã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="464"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="557"/>
<source>&lt;p&gt;Could not load the language file &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;. &lt;p&gt;The language will be temporarily reset to English (built-in). Please go to the &lt;b&gt;Preferences&lt;/b&gt; dialog which you can open from the &lt;b&gt;File&lt;/b&gt; menu of the main VirtualBox window, and select one of the existing languages on the &lt;b&gt;Language&lt;/b&gt; page.&lt;/p&gt;</source>
<translation>&lt;p&gt;言語ファイル&lt;b&gt;&lt;nobr&gt;&quot;%1&quot;&lt;/nobr&gt;&lt;/b&gt;ãŒèª­ã¿è¾¼ã‚ã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;言語ã¯ä¸€æ™‚çš„ã«English(内蔵)ã«è¨­å®šã•れã¾ã™ã€‚VirtualBoxメインウィンドウã®&lt;b&gt;[ファイル]&lt;/b&gt;メニューã‹ã‚‰&lt;b&gt;[環境設定]&lt;/b&gt;ダイアログを開ãã€&lt;b&gt;[言語]&lt;/b&gt;ページã§è¡¨ç¤ºã•れã¦ã„ã‚‹è¨€èªžã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="464"/>
<source>&lt;p&gt;The VirtualBox Guest Additions installed in the Guest OS are too old: the installed version is %1, the expected version is %2. Some features that require Guest Additions (mouse integration, guest display auto-resize) will most likely stop working properly.&lt;/p&gt;&lt;p&gt;Please update the Guest Additions to the current version by choosing &lt;b&gt;Install Guest Additions&lt;/b&gt; from the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;ゲストOSã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れãŸVirtualBox Guest Additionsã¯å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã™:インストールã•れãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯%1ã§ã™ã€‚期待ã•れるãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯%2ã§ã™ã€‚Guest Additionsã‚’å¿…è¦ã¨ã™ã‚‹ã„ãã¤ã‹ã®æ©Ÿèƒ½(マウス統åˆã€ç”»é¢ã®ãƒªã‚µã‚¤ã‚º)ã¯å‹•作ã—ãªã„ã‹ã‚‚ã—れã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;&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/VBoxProblemReporter.cpp" line="464"/>
<source>&lt;p&gt;The VirtualBox Guest Additions installed in the Guest OS are outdated: the installed version is %1, the expected version is %2. Some features that require Guest Additions (mouse integration, guest display auto-resize) may not work as expected.&lt;/p&gt;&lt;p&gt;It is recommended to update the Guest Additions to the current version by choosing &lt;b&gt;Install Guest Additions&lt;/b&gt; from the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;ゲストOSã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れãŸVirtualBox Guest Additionsã¯å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã™:インストールã•れãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯%1ã§ã™ã€‚期待ã•れるãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯%2ã§ã™ã€‚Guest Additionsã‚’å¿…è¦ã¨ã™ã‚‹ã„ãã¤ã‹ã®æ©Ÿèƒ½(マウス統åˆã€ç”»é¢ã®ãƒªã‚µã‚¤ã‚º)ã¯å‹•作ã—ãªã„ã‹ã‚‚ã—れã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;&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/VBoxProblemReporter.cpp" line="464"/>
<source>&lt;p&gt;The VirtualBox Guest Additions installed in the Guest OS are too recent for this version of VirtualBox: the installed version is %1, the expected version is %2.&lt;/p&gt;&lt;p&gt;Using a newer version of Additions with an older version of VirtualBox is not supported. Please install the current version of the Guest Additions by choosing &lt;b&gt;Install Guest Additions&lt;/b&gt; from the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;ゲストOSã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れãŸVirtualBox Guest Additionsã¯ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®VirtualBoxより新ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã™:インストールã•れãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯%1ã§ã™ã€‚期待ã•れるãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯%2ã§ã™ã€‚&lt;/p&gt;&lt;p&gt;æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®Guest Additionsã®å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®VirtualBoxã§ã®ä½¿ç”¨ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“。&lt;p&gt;&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/VBoxProblemReporter.cpp" line="464"/>
<source>Failed to change the snapshot folder path of the virtual machine &lt;b&gt;%1&lt;b&gt; to &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;.</source>
<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/VBoxProblemReporter.cpp" line="2756"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2936"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1488"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1653"/>
<source>&lt;p&gt;Could not find the VirtualBox Guest Additions CD image file &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt; or &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;Do you wish to download this CD image from the Internet?&lt;/p&gt;</source>
<translation>&lt;p&gt;VirtualBox Guest Additions CDイメージファイル&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;ã¾ãŸã¯&lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;インターãƒãƒƒãƒˆã‹ã‚‰CDイメージをダウンロードã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1502"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1667"/>
<source>&lt;p&gt;Failed to download the VirtualBox Guest Additions CD image from &lt;nobr&gt;&lt;a href=&quot;%1&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;nobr&gt;&lt;a href=&quot;%1&quot;&gt;%2&lt;/a&gt;ã‹ã‚‰VirtualBox Guest Additions CDイメージをダウンロードã§ãã¾ã›ã‚“。&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1521"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1686"/>
<source>&lt;p&gt;Are you sure you want to download the VirtualBox Guest Additions CD image from &lt;nobr&gt;&lt;a href=&quot;%1&quot;&gt;%2&lt;/a&gt;&lt;/nobr&gt; (size %3 bytes)?&lt;/p&gt;</source>
<translation>&lt;p&gt;VirtualBox Guest Additions CDイメージを&lt;nobr&gt;&lt;a href=&quot;%1&quot;&gt;%2&lt;/a&gt;&lt;/nobr&gt; (サイズ %3ãƒã‚¤ãƒˆ)ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1533"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1698"/>
<source>&lt;p&gt;The VirtualBox Guest Additions CD image has been successfully downloaded from &lt;nobr&gt;&lt;a href=&quot;%1&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 register this CD image and mount it on the virtual CD/DVD drive?&lt;/p&gt;</source>
<translation>&lt;p&gt;VirtualBox Guest Additions CDイメージを&lt;nobr&gt;&lt;a href=&quot;%1&quot;&gt;%2&lt;/a&gt;&lt;/nobr&gt;ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ã€&lt;nobr&gt;&lt;b&gt;%3&lt;/b&gt;ã«ä¿å­˜ã—ã¾ã—ãŸã€‚&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;CDイメージを登録ã—ã€ä»®æƒ³CD/DVDドライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1533"/>
<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;. Note that the &lt;i&gt;Host&lt;/i&gt; key is currently defined as &lt;b&gt;%1&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 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/VBoxProblemReporter.cpp" line="1533"/>
<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;. Note that the &lt;i&gt;Host&lt;/i&gt; key is currently defined as &lt;b&gt;%1&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 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/VBoxProblemReporter.cpp" line="2780"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2960"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2780"/>
<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 VirualBox 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 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/VBoxProblemReporter.cpp" line="1998"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2163"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="422"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="515"/>
<source>Failed to find license files in &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;.</source>
<translation>&lt;nobr&gt;&lt;b&gt;&quot;%1&quot;&lt;/b&gt;&lt;/nobr&gt;ã«ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ãƒ•ァイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="433"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="526"/>
<source>Failed to open the license file &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;. Check file permissions.</source>
<translation>ライセンスファイル&lt;nobr&gt;&lt;b&gt;&quot;%1&quot;&lt;/b&gt;&lt;/nobr&gt;ãŒé–‹ã‘ã¾ã›ã‚“。ファイルã®ãƒ‘ーミッションを確èªã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="699"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="812"/>
<source>Failed to send the ACPI Power Button press event to the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
<translation>仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã¸ã®é›»æºãƒœã‚¿ãƒ³ オフã®ACPIイベントé€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="699"/>
<source>&lt;p&gt;Failed to connect to the VirtualBox online registration service.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;VirtualBox オンライン登録サービスã¸ã®æŽ¥ç¶šã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1616"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1781"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1616"/>
<source>&lt;p&gt;Failed to register the VirtualBox product&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;VirtualBox ã®è£½å“登録ã«å¤±æ•—ã—ã¾ã—ãŸ&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1616"/>
<source>&lt;p&gt;Failed to save the global VirtualBox settings to &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;グローãƒãƒ«ãªVirtualBox設定ã®&lt;b&gt;&lt;nobr&gt;&quot;%1&quot;&lt;/nobr&gt;&lt;/b&gt;ã¸ã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="498"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="591"/>
<source>&lt;p&gt;Failed to load the global GUI configuration from &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;The application will now terminate.&lt;/p&gt;</source>
<translation>&lt;p&gt;グローãƒãƒ«ãªGUIæ§‹æˆã®&lt;b&gt;&lt;nobr&gt;&quot;%1&quot;&lt;/nobr&gt;&lt;/b&gt;ã‹ã‚‰ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;/p&gt;
&lt;p&gt;アプリケーションを終了ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="512"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="605"/>
<source>&lt;p&gt;Failed to save the global GUI configuration to &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;The application will now terminate.&lt;/p&gt;</source>
<translation>&lt;p&gt;グローãƒãƒ«ãªGUIæ§‹æˆã®&lt;b&gt;&lt;nobr&gt;&quot;%1&quot;&lt;/nobr&gt;&lt;/b&gt;ã¸ã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;/p&gt;
&lt;p&gt;アプリケーションを終了ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="617"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="705"/>
<source>Failed to save the settings of the virtual machine &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt;.</source>
<translation>仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®è¨­å®šã®&lt;b&gt;&lt;nobr&gt;&quot;%2&quot;&lt;/nobr&gt;&lt;/b&gt;ã¸ã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="639"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="727"/>
<source>Failed to load the settings of the virtual machine &lt;b&gt;%1&lt;/b&gt; from &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt;.</source>
<translation>仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®è¨­å®šã®&lt;b&gt;&lt;nobr&gt;&quot;%2â€&lt;/nobr&gt;&lt;/b&gt;ã‹ã‚‰ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="639"/>
<source>Delete</source>
<comment>machine</comment>
<translation type="obsolete">削除</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="639"/>
<source>Unregister</source>
<comment>machine</comment>
<translation type="obsolete">登録解除</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1094"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1251"/>
<source>Discard</source>
<comment>saved state</comment>
<translation>破棄</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1094"/>
<source>Continue</source>
<comment>detach image</comment>
<translation type="obsolete">ç¶šã‘ã‚‹</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1094"/>
<source>&lt;p&gt;Do you want to delete this hard disk&apos;s image file &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;?&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;If you select &lt;b&gt;Delete&lt;/b&gt; then the image file will be permanently deleted after unregistering the hard disk. This operation cannot be undone.&lt;/p&gt;&lt;p&gt;If you select &lt;b&gt;Unregister&lt;/b&gt; then the virtual hard disk will be unregistered and removed from the collection, but the image file will be left on your physical disk.&lt;/p&gt;</source>
<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;ã‚’é¸æŠžã™ã‚‹ã¨ã€ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ァイルã¯ãƒªã‚¹ãƒˆã‹ã‚‰å–り除ã‹ã‚ŒãŸå¾Œã€æ°¸ä¹…ã«å‰Šé™¤ã•れã¾ã™ã€‚ã“ã®æ“作ã¯å…ƒã«æˆ»ã›ã¾ã›ã‚“。&lt;/p&gt;
&lt;p&gt;&lt;b&gt;[登録解除]&lt;/b&gt;ã‚’é¸æŠžã™ã‚‹ã¨ã€ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã¯ãƒªã‚¹ãƒˆã‹ã‚‰å–り除ã‹ã‚Œã¾ã™ãŒã€ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ァイルã¯ç‰©ç†ãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã«æ®‹ã•れã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1094"/>
<source>Delete</source>
<comment>hard disk</comment>
<translation type="obsolete">削除</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1094"/>
<source>Unregister</source>
<comment>hard disk</comment>
<translation type="obsolete">登録解除</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1094"/>
<source>&lt;p&gt;There are hard disks attached to SATA ports of this virtual machine. If you disable the SATA controller, all these hard disks will be automatically detached.&lt;/p&gt;&lt;p&gt;Are you sure that you want to disable the SATA controller?&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®SATAãƒãƒ¼ãƒˆã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒã‚りã¾ã™ã€‚SATA コントローラを無効ã«ã™ã‚‹ã¨ã€ãれらã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã¯è‡ªå‹•çš„ã«å‰²ã‚Šå½“ã¦è§£é™¤ã•れã¾ã™ã€‚&lt;/p&gt;
&lt;p&gt;SATA コントローラを無効ã«ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1094"/>
<source>Disable</source>
<comment>hard disk</comment>
<translation type="obsolete">無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1094"/>
<source>Failed to attach a hard disk image with UUID %1 to device slot %2 on channel %3 of the %4 bus of the machine &lt;b&gt;%5&lt;/b&gt;.</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸(UUID %1)ã®ã€ä»®æƒ³ãƒžã‚·ãƒ³&lt;b&gt;&quot;%5&quot;&lt;/b&gt;ã®ãƒã‚¹ %4 ã®ãƒãƒ£ãƒ³ãƒãƒ« %3 ã®ãƒ‡ãƒã‚¤ã‚¹ã‚¹ãƒ­ãƒƒãƒˆ %2 ã¸ã®å‰²ã‚Šå½“ã¦ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1094"/>
<source>Failed to detach a hard disk image from device slot %1 on channel %2 of the %3 bus of the machine &lt;b&gt;%4&lt;/b&gt;.</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã®ã€ä»®æƒ³ãƒžã‚·ãƒ³&lt;b&gt;&quot;%4&quot;&lt;/b&gt;ã®ãƒã‚¹ %3 ã®ãƒãƒ£ãƒ³ãƒãƒ« %2 ã®ãƒ‡ãƒã‚¤ã‚¹ã‚¹ãƒ­ãƒƒãƒˆ %1 ã‹ã‚‰ã®å‰²ã‚Šå½“ã¦è§£é™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1563"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1691"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1717"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1728"/>
<source>Download</source>
<comment>additions</comment>
<translation>ダウンロード</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1541"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1706"/>
<source>Mount</source>
<comment>additions</comment>
<translation>マウント</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1718"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1850"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1883"/>
<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/VBoxProblemReporter.cpp" line="1692"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1857"/>
<source>Capture</source>
<comment>do input capture</comment>
<translation>キャプãƒãƒ£</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1692"/>
<source>&lt;p&gt;One or more of the registered 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 Disk 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 type="obsolete">&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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1819"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1984"/>
<source>Check</source>
<comment>inaccessible media message box</comment>
<translation>確èª</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1819"/>
<source>&lt;p&gt;The following VirtualBox settings files have been automatically converted to the new settings file format version &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;However, the results of the conversion were not saved back to disk yet. Please press:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Save&lt;/b&gt; to save all auto-converted files now (it will not be possible to use these settings files with an older version of VirtualBox in the future);&lt;/li&gt;&lt;li&gt;&lt;b&gt;Backup&lt;/b&gt; to create backup copies of the settings files in the old format before saving them in the new format;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Cancel&lt;/b&gt; to not save the auto-converted settings files now.&lt;li&gt;&lt;/ul&gt;&lt;p&gt;Note that if you select &lt;b&gt;Cancel&lt;/b&gt;, the auto-converted settings files will be implicitly saved in the new format anyway once you change a setting or start a virtual machine, but &lt;b&gt;no&lt;/b&gt; backup copies will be created in this case.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;次ã®VirtualBox設定ファイルã¯è‡ªå‹•çš„ã«ãƒãƒ¼ã‚¸ãƒ§ãƒ³ &lt;b&gt;%1&lt;/b&gt; ã®æ–°ã—ã„設定ファイル形å¼ã«å¤‰æ›ã•れã¾ã—ãŸã€‚&lt;/p&gt;
&lt;p&gt;ã—ã‹ã—ãªãŒã‚‰ã€å¤‰æ›å¾Œã®ãƒ•ァイルã¯ã¾ã ãƒ‡ã‚£ã‚¹ã‚¯ã«ä¿å­˜ã•れã¦ã„ã¾ã›ã‚“。ボタンをクリックã—ã¦ãã ã•ã„:&lt;/p&gt;
@@ -11663,957 +11568,994 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
&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/VBoxProblemReporter.cpp" line="1819"/>
<source>&amp;Save</source>
<comment>warnAboutAutoConvertedSettings message box</comment>
<translation type="obsolete">ä¿å­˜(&amp;S)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1819"/>
<source>&amp;Backup</source>
<comment>warnAboutAutoConvertedSettings message box</comment>
<translation type="obsolete">ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—(&amp;B)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1819"/>
<source>Cancel</source>
<comment>warnAboutAutoConvertedSettings message box</comment>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1890"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2055"/>
<source>Switch</source>
<comment>fullscreen</comment>
<translation>切り替ãˆ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1910"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2075"/>
<source>Switch</source>
<comment>seamless</comment>
<translation>切り替ãˆ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1975"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2140"/>
<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/VBoxProblemReporter.cpp" line="1979"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2144"/>
<source>Reset</source>
<comment>machine</comment>
<translation>リセット</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2007"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2172"/>
<source>Continue</source>
<comment>no hard disk attached</comment>
<translation>ç¶šã‘ã‚‹</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2008"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2173"/>
<source>Go Back</source>
<comment>no hard disk attached</comment>
<translation>戻る</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2008"/>
<source>Failed to copy file &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; to &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; (%3).</source>
<translation type="obsolete">ファイル&lt;b&gt;&lt;nobr&gt;&quot;%1&quot;&lt;/nobr&gt;&lt;/b&gt;ã®&lt;b&gt;&lt;nobr&gt;&quot;%2&quot;&lt;/nobr&gt;&lt;/b&gt;ã¸ã®ã‚³ãƒ”ーã«å¤±æ•—ã—ã¾ã—ãŸ(%3)。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2008"/>
<source>&lt;p&gt;There are no unused hard disks available for the newly created attachment.&lt;/p&gt;&lt;p&gt;Press the &lt;b&gt;Create&lt;/b&gt; button to start the &lt;i&gt;New Virtual Disk&lt;/i&gt; wizard and create a new hard disk, or press the &lt;b&gt;Select&lt;/b&gt; if you wish to open the &lt;i&gt;Virtual Disk Manager&lt;/i&gt;.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;æ–°è¦ã®å‰²ã‚Šå½“ã¦ã«åˆ©ç”¨ã§ãる未使用ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒã‚りã¾ã›ã‚“。&lt;/p&gt;
&lt;p&gt;&lt;b&gt;[作æˆ]&lt;/b&gt;ボタンをクリックã—ã€&lt;i&gt;æ–°è¦ä»®æƒ³ãƒ‡ã‚£ã‚¹ã‚¯ä½œæˆã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰&lt;/i&gt;ã‚’èµ·å‹•ã—ã¦æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’作æˆã™ã‚‹ã‹ã€&lt;b&gt;[é¸æŠž]&lt;/b&gt;ボタンをクリックã—ã¦ã€&lt;i&gt;仮想ディスクマãƒãƒ¼ã‚¸ãƒ£&lt;/i&gt;ã‚’é–‹ãã€å‹•ä½œã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2008"/>
<source>&amp;Create</source>
<comment>hard disk</comment>
<translation type="obsolete">作æˆ(&amp;C)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2008"/>
<source>Select</source>
<comment>hard disk</comment>
<translation type="obsolete">é¸æŠž</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="954"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1111"/>
<source>&lt;p&gt;Could not enter seamless mode due to insufficient guest video memory.&lt;/p&gt;&lt;p&gt;You should configure the virtual machine to have at least &lt;b&gt;%1&lt;/b&gt; of video memory.&lt;/p&gt;</source>
<translation>&lt;p&gt;ゲストOSã®ãƒ“デオメモリä¸è¶³ã®ãŸã‚ã€ã‚·ãƒ¼ãƒ ãƒ¬ã‚¹ãƒ¢ãƒ¼ãƒ‰ã«åˆ‡ã‚Šæ›¿ãˆã§ãã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;仮想マシンã®è¨­å®šã§ãƒ“デオメモリを &lt;b&gt;%1&lt;/b&gt;以上ã«è¨­å®šã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="967"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1124"/>
<source>&lt;p&gt;Could not switch the guest display to fullscreen mode due to insufficient guest video memory.&lt;/p&gt;&lt;p&gt;You should configure the virtual machine to have at least &lt;b&gt;%1&lt;/b&gt; of video memory.&lt;/p&gt;&lt;p&gt;Press &lt;b&gt;Ignore&lt;/b&gt; to switch to fullscreen mode anyway or press &lt;b&gt;Cancel&lt;/b&gt; to cancel the operation.&lt;/p&gt;</source>
<translation>&lt;p&gt;ゲストOSã®ãƒ“デオメモリä¸è¶³ã®ãŸã‚ã€ã‚²ã‚¹ãƒˆç”»é¢ã‚’フルスクリーンモードã«åˆ‡ã‚Šæ›¿ãˆã§ãã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;仮想マシンã®è¨­å®šã§ãƒ“デオメモリを &lt;b&gt;%1&lt;/b&gt;以上ã«è¨­å®šã—ã¦ãã ã•ã„。&lt;/p&gt;&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/VBoxProblemReporter.cpp" line="967"/>
<source>&lt;p&gt;Unable to obtain the new version information due to the following network error:&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/p&gt;</source>
<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/VBoxProblemReporter.cpp" line="1658"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1823"/>
<source>You are already running the most recent version of VirtualBox.</source>
<translation>最新ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®VirtualBoxãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã™ã€‚ 後ã§ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç¢ºèªã‚’行ã£ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1670"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1835"/>
<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/VBoxProblemReporter.cpp" line="1703"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1868"/>
<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/VBoxProblemReporter.cpp" line="1749"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1914"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1749"/>
<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;. 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 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/VBoxProblemReporter.cpp" line="1749"/>
<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;. 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 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/runtime/UIActionsPool.cpp" line="911"/>
+ <location filename="../src/VBoxHelpActions.cpp" line="108"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="933"/>
<source>&amp;Contents...</source>
<translation>ヘルプを表示(&amp;C)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="912"/>
+ <location filename="../src/VBoxHelpActions.cpp" line="110"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="934"/>
<source>Show the online help contents</source>
<translation>オンラインヘルプを表示</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="933"/>
+ <location filename="../src/VBoxHelpActions.cpp" line="113"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="955"/>
<source>&amp;VirtualBox Web Site...</source>
<translation>VirtualBox Webサイト(&amp;V)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="934"/>
+ <location filename="../src/VBoxHelpActions.cpp" line="115"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="956"/>
<source>Open the browser and go to the VirtualBox product web site</source>
<translation>Webブラウザã§VirtualBox製å“ã®Webサイトを開ã</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="955"/>
+ <location filename="../src/VBoxHelpActions.cpp" line="118"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="977"/>
<source>&amp;Reset All Warnings</source>
<translation>ã™ã¹ã¦ã®è­¦å‘Šã‚’リセット(&amp;R)</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="956"/>
+ <location filename="../src/VBoxHelpActions.cpp" line="120"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="978"/>
<source>Go back to showing all suppressed warnings and messages</source>
<translation>ã™ã¹ã¦ã®æŠ‘æ­¢ã•れãŸè­¦å‘Šã¨ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’å†åº¦è¡¨ç¤ºã•ã›ã‚‹</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="980"/>
+ <location filename="../src/VBoxHelpActions.cpp" line="124"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="1002"/>
<source>R&amp;egister VirtualBox...</source>
<translation>VirtualBox を登録(&amp;E)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="981"/>
+ <location filename="../src/VBoxHelpActions.cpp" line="126"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="1003"/>
<source>Open VirtualBox registration form</source>
<translation>VirtualBox 登録フォームを開ã</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="1004"/>
+ <location filename="../src/VBoxHelpActions.cpp" line="130"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="1026"/>
<source>C&amp;heck for Updates...</source>
<translation>アップデートを確èª(&amp;H)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="1005"/>
+ <location filename="../src/VBoxHelpActions.cpp" line="132"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="1027"/>
<source>Check for a new VirtualBox version</source>
<translation>VirtualBoxã®æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’確èª</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="1027"/>
+ <location filename="../src/VBoxHelpActions.cpp" line="135"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="1049"/>
<source>&amp;About VirtualBox...</source>
<translation>VirtualBox ã«ã¤ã„ã¦(&amp;A)...</translation>
</message>
<message>
- <location filename="../src/runtime/UIActionsPool.cpp" line="1028"/>
+ <location filename="../src/VBoxHelpActions.cpp" line="137"/>
+ <location filename="../src/runtime/UIActionsPool.cpp" line="1050"/>
<source>Show a dialog with product information</source>
<translation>è£½å“æƒ…報ダイアログを表示</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1640"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1805"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1104"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1269"/>
<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>
<translation>&lt;p&gt;&quot;%1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;&quot;を解放ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;&lt;p&gt;以下ã®ä»®æƒ³ãƒžã‚·ãƒ³ã‹ã‚‰è§£æ”¾ã•れã¾ã™: &lt;b&gt;%3&lt;/b&gt;&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1047"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1204"/>
<source>&lt;p&gt;You are about to remove the virtual machine &lt;b&gt;%1&lt;/b&gt; from the machine list.&lt;/p&gt;&lt;p&gt;Would you like to delete the files containing the virtual machine from your hard disk as well?&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;をリストã‹ã‚‰é™¤åŽ»ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;仮想マシンを構æˆã™ã‚‹ãƒ•ァイルをãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‹ã‚‰å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1050"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1207"/>
<source>&lt;p&gt;You are about to remove the virtual machine &lt;b&gt;%1&lt;/b&gt; from the machine list.&lt;/p&gt;&lt;p&gt;Would you like to delete the files containing the virtual machine from your hard disk as well? Doing this will also remove the files containing the machine&apos;s virtual hard disks if they are not in use by another machine.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;をリストã‹ã‚‰é™¤åŽ»ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;仮想マシンを構æˆã™ã‚‹ãƒ•ァイルをãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‹ã‚‰å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿä»–ã®ä»®æƒ³ãƒžã‚·ãƒ³ã§ä½¿ç”¨ã•れã¦ã„ãªã„仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã¯å‰Šé™¤ã•れã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1062"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1219"/>
<source>Delete all files</source>
<translation>ã™ã¹ã¦ã®ãƒ•ァイルを削除</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1063"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1220"/>
<source>Remove only</source>
<translation>除去ã®ã¿</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1070"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1227"/>
<source>You are about to remove the inaccessible virtual machine &lt;b&gt;%1&lt;/b&gt; from the machine list. Do you wish to proceed?</source>
<translation>アクセスã§ããªã„仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;をリストã‹ã‚‰é™¤åŽ»ã—ã¾ã™ã€‚続行ã—ã¾ã™ã‹ï¼Ÿ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1080"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1237"/>
<source>Remove</source>
<translation>除去</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1112"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1277"/>
<source>Release</source>
<comment>detach medium</comment>
<translation>解放</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1121"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1286"/>
<source>&lt;p&gt;Are you sure you want to remove the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt; from the list of known media?&lt;/p&gt;</source>
<translation>&lt;p&gt;メディアã®ãƒªã‚¹ãƒˆã‹ã‚‰&quot;%1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;&quot;を除去ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1131"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1296"/>
<source>Note that as this hard disk is inaccessible its storage unit cannot be deleted right now.</source>
<translation>注:ã“ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ããªã„ãŸã‚ã€ç¾åœ¨ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ 装置を削除ã§ãã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1135"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1300"/>
<source>The next dialog will let you choose whether you also want to delete the storage unit of this hard disk or keep it for later usage.</source>
<translation>次ã®ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã§ã€ã“ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸è£…置を削除ã™ã‚‹ã‹ã€å¾Œã§ä½¿ç”¨ã™ã‚‹ãŸã‚ä¿æŒã™ã‚‹ã‹ã‚’é¸æŠžã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1135"/>
<source>&lt;p&gt;Note that the storage unit of this medium will not be deleted and that it will be possible to add it to the list later again.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;注:ã“ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸è£…ç½®ã¯å‰Šé™¤ã•れã¾ã›ã‚“。後ã§ãƒªã‚¹ãƒˆã«å†åº¦è¿½åŠ ã™ã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1146"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1311"/>
<source>Remove</source>
<comment>medium</comment>
<translation>除去</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1153"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1318"/>
<source>&lt;p&gt;The hard disk storage unit at location &lt;b&gt;%1&lt;/b&gt; already exists. You cannot create a new virtual hard disk that uses this location because it can be already used by another virtual hard disk.&lt;/p&gt;&lt;p&gt;Please specify a different location.&lt;/p&gt;</source>
<translation>&lt;p&gt;ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ ストレージ装置ã®å ´æ‰€ &lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚別ã®ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒä½¿ç”¨ã—ã¦ã„ã‚‹ãŸã‚ã€ã“ã®å ´æ‰€ã«æ–°è¦ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’作æˆã§ãã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;別ã®å ´æ‰€ã‚’指定ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1165"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1330"/>
<source>&lt;p&gt;Do you want to delete the storage unit of the hard disk &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;?&lt;/p&gt;&lt;p&gt;If you select &lt;b&gt;Delete&lt;/b&gt; then the specified storage unit will be permanently deleted. This operation &lt;b&gt;cannot be undone&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;If you select &lt;b&gt;Keep&lt;/b&gt; then the hard disk will be only removed from the list of known hard disks, but the storage unit will be left untouched which makes it possible to add this hard disk to the list later again.&lt;/p&gt;</source>
<translation>&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;ã‚’é¸æŠžã™ã‚‹ã¨ã€æŒ‡å®šã•れãŸã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸è£…ç½®ã¯æ°¸ä¹…ã«å‰Šé™¤ã•れã¾ã™ã€‚ã“ã®æ“作ã¯&lt;b&gt;å…ƒã«æˆ»ã›ã¾ã›ã‚“&lt;/b&gt;。&lt;/p&gt;&lt;p&gt;&lt;b&gt;[ä¿æŒ]&lt;/b&gt;ã‚’é¸æŠžã™ã‚‹ã¨ã€ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã¯ãƒªã‚¹ãƒˆã‹ã‚‰å–り除ã‹ã‚Œã¾ã™ãŒã€ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸è£…ç½®ã¯å¾Œã§ãƒªã‚¹ãƒˆã«å†åº¦è¿½åŠ ã§ãるよã†ã«ã€ãã®ã¾ã¾ç½®ã‹ã‚Œã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1179"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1344"/>
<source>Delete</source>
<comment>hard disk storage</comment>
<translation>削除</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1180"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1345"/>
<source>Keep</source>
<comment>hard disk storage</comment>
<translation>ä¿æŒ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1191"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1356"/>
<source>Failed to delete the storage unit of the hard disk &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/VBoxProblemReporter.cpp" line="1191"/>
<source>&lt;p&gt;There are no unused hard disks available for the newly created attachment.&lt;/p&gt;&lt;p&gt;Press the &lt;b&gt;Create&lt;/b&gt; button to start the &lt;i&gt;New Virtual Disk&lt;/i&gt; wizard and create a new hard disk, or press the &lt;b&gt;Select&lt;/b&gt; if you wish to open the &lt;i&gt;Virtual Media Manager&lt;/i&gt;.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;æ–°è¦ã®å‰²ã‚Šå½“ã¦ã«åˆ©ç”¨ã§ãる未使用ã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒã‚りã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;&lt;b&gt;[作æˆ]&lt;/b&gt;ボタンをクリックã—ã€&lt;i&gt;æ–°è¦ä»®æƒ³ãƒ‡ã‚£ã‚¹ã‚¯ä½œæˆã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰&lt;/i&gt;ã‚’èµ·å‹•ã—ã¦æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’作æˆã™ã‚‹ã‹ã€&lt;b&gt;[é¸æŠž]&lt;/b&gt;ボタンをクリックã—ã¦ã€&lt;i&gt;仮想メディアマãƒãƒ¼ã‚¸ãƒ£&lt;/i&gt;ã‚’é–‹ãã€å‹•ä½œã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1260"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1425"/>
<source>Failed to create the hard disk storage &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;.&lt;/nobr&gt;</source>
<translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ ストレージ&lt;nobr&gt;&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1260"/>
<source>Failed to attach the hard disk &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt; to slot &lt;i&gt;%2&lt;/i&gt; of the machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯&lt;nobr&gt;&lt;b&gt;&quot;%1&quot;&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/VBoxProblemReporter.cpp" line="1260"/>
<source>Failed to detach the hard disk &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt; from slot &lt;i&gt;%2&lt;/i&gt; of the machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯&lt;nobr&gt;&lt;b&gt;&quot;%1&quot;&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/VBoxProblemReporter.cpp" line="1260"/>
<source>Failed to mount the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt; on the machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation type="obsolete">&quot;%1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;&quot;ã®ã€ä»®æƒ³ãƒžã‚·ãƒ³&lt;b&gt;&quot;%3&quot;&lt;/b&gt;ã¸ã®ãƒžã‚¦ãƒ³ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1260"/>
<source>Failed to unmount the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt; from the machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation type="obsolete">&quot;%1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;&quot;ã®ã€ä»®æƒ³ãƒžã‚·ãƒ³&lt;b&gt;&quot;%3&quot;&lt;/b&gt;ã‹ã‚‰ã®ãƒžã‚¦ãƒ³ãƒˆè§£é™¤ã«å¤±æ•—ã—ã‹ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1341"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1506"/>
<source>Failed to open the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;.</source>
<translation>&quot;%1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;&quot;ã®ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1353"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1518"/>
<source>Failed to close the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;.</source>
<translation>&quot;%1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;&quot;ã®ã‚¯ãƒ­ãƒ¼ã‚ºã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1394"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1559"/>
<source>Failed to determine the accessibility state of the medium &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;.</source>
<translation>メディア&lt;nobr&gt;&lt;b&gt;&quot;%1&quot;&lt;/b&gt;&lt;/nobr&gt;ã®ã‚¢ã‚¯ã‚»ã‚¹å¯å¦çŠ¶æ…‹ã®å–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1604"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1769"/>
<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/VBoxProblemReporter.cpp" line="1650"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1815"/>
<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/VBoxProblemReporter.cpp" line="1808"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1973"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1808"/>
<source>&lt;p&gt;Your existing VirtualBox settings files were 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;More&lt;/b&gt; if you want to get more information about what files were converted and access additional actions.&lt;/p&gt;&lt;p&gt;Press &lt;b&gt;Exit&lt;/b&gt; to terminate the VirtualBox application without saving the results of the conversion to disk.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;既存ã®VirtualBox設定ファイルã¯å¤ã„å½¢å¼ã‹ã‚‰VirtualBoxã®æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«å¿…è¦ãªå½¢å¼ã«è‡ªå‹•変æ›ã•れã¾ã—ãŸã€‚&lt;/p&gt;&lt;p&gt;ã™ãã«VirtualBoxã‚’èµ·å‹•ã™ã‚‹ã«ã¯&lt;b&gt;[OK]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。変æ›ã•れãŸè¨­å®šãƒ•ァイルã«ã¤ã„ã¦ã€è©³ã—ã„æƒ…報を得ãŸã„å ´åˆã¯&lt;b&gt;[詳細]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p&gt;&lt;b&gt;[終了]&lt;/b&gt;ボタンをクリックã™ã‚‹ã¨ã€å¤‰æ›çµæžœã‚’ディスクã«ä¿å­˜ã™ã‚‹ã“ã¨ãªãã€VirtualBoxアプリケーションを終了ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1808"/>
<source>&amp;More</source>
<comment>warnAboutAutoConvertedSettings message box</comment>
<translation type="obsolete">詳細(&amp;M)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1808"/>
<source>E&amp;xit</source>
<comment>warnAboutAutoConvertedSettings message box</comment>
<translation type="obsolete">終了(&amp;X)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1808"/>
<source>&lt;p&gt;The following VirtualBox settings files have been automatically converted to the new settings file format version &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;However, the results of the conversion were not saved back to disk yet. Please press:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Backup&lt;/b&gt; to create backup copies of the settings files in the old format before saving them in the new format;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Overwrite&lt;/b&gt; to save all auto-converted files without creating backup copies (it will not be possible to use these settings files with an older version of VirtualBox afterwards);&lt;/li&gt;%2&lt;/ul&gt;&lt;p&gt;It is recommended to always select &lt;b&gt;Backup&lt;/b&gt; because in this case it will be possible to go back to the previous version of VirtualBox (if necessary) without losing your current settings. See the VirtualBox Manual for more information about downgrading.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;次ã®VirtualBox設定ファイルã¯è‡ªå‹•çš„ã«ãƒãƒ¼ã‚¸ãƒ§ãƒ³ &lt;b&gt;&quot;%1&quot;&lt;/b&gt; ã®æ–°ã—ã„設定ファイル形å¼ã«å¤‰æ›ã•れã¾ã—ãŸã€‚&lt;/p&gt;&lt;p&gt;ã—ã‹ã—ãªãŒã‚‰ã€å¤‰æ›å¾Œã®ãƒ•ァイルã¯ã¾ã ãƒ‡ã‚£ã‚¹ã‚¯ã«ä¿å­˜ã•れã¦ã„ã¾ã›ã‚“。ボタンをクリックã—ã¦ãã ã•ã„:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;[ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—]&lt;/b&gt;: æ–°ã—ã„å½¢å¼ã§è¨­å®šãƒ•ァイルをä¿å­˜ã™ã‚‹å‰ã«ã€å¤ã„å½¢å¼ã§è¨­å®šãƒ•ァイルã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—コピーを作æˆã—ã¾ã™ã€‚&lt;/li&gt;&lt;li&gt;&lt;b&gt;[上書ã]&lt;/b&gt;:ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—コピーを作æˆã›ãšã«ã€ã™ã¹ã¦ã®å¤‰æ›æ¸ˆã¿ãƒ•ァイルをä¿å­˜ã—ã¾ã™ã€‚(æ—§ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®VirtualBoxã§ã“れらã®è¨­å®šãƒ•ァイルã¯ä½¿ç”¨ã§ãã¾ã›ã‚“)&lt;/li&gt;%2&lt;/ul&gt;&lt;p&gt;(å¿…è¦ãªã‚‰ã°) æ—§ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®VirtualBoxã«ç¾åœ¨ã®è¨­å®šã‚’失ã†ã“ã¨ãªã戻るã“ã¨ãŒã§ãã‚‹ã®ã§ã€&lt;b&gt;[ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—]&lt;/b&gt; ã‚’é¸æŠžã™ã‚‹ã“ã¨ã‚’推奨ã—ã¾ã™ã€‚ダウングレードã«é–¢ã™ã‚‹è©³ç´°ã¯VirtualBoxマニュアルをå‚ç…§ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1808"/>
<source>&lt;li&gt;&lt;b&gt;Exit&lt;/b&gt; to terminate VirtualBox without saving the results of the conversion to disk.&lt;/li&gt;</source>
<translation type="obsolete">&lt;li&gt;&lt;b&gt;[終了]&lt;/b&gt;:変æ›çµæžœã‚’ディスクã«ä¿å­˜ã›ãšã«VirtualBoxを終了ã—ã¾ã™ã€‚&lt;/li&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1808"/>
<source>O&amp;verwrite</source>
<comment>warnAboutAutoConvertedSettings message box</comment>
<translation type="obsolete">上書ã(&amp;V)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1942"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2107"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1942"/>
<source>hard disk</source>
<comment>failed to close ...</comment>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1942"/>
<source>CD/DVD image</source>
<comment>failed to close ...</comment>
<translation type="obsolete">CD/DVDイメージ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1942"/>
<source>floppy image</source>
<comment>failed to close ...</comment>
<translation type="obsolete">フロッピーイメージ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1942"/>
<source>A file named &lt;b&gt;%1&lt;/b&gt; already exists. Are you sure you want to replace it?&lt;br /&gt;&lt;br /&gt;The file already exists in &quot;%2&quot;. Replacing it will overwrite its contents.</source>
<translation type="obsolete">ファイルå&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã¯ã™ã§ã«ä½¿ã‚れã¦ã„ã¾ã™ã€‚ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ç½®ãæ›ãˆã¾ã™ã‹ï¼Ÿ&lt;br /&gt;&lt;br /&gt;ファイルã¯&quot;%2&quot;ã«å­˜åœ¨ã—ã¾ã™ã€‚ファイルã®å†…容ã¯ä¸Šæ›¸ãã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="335"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="436"/>
<source>The following files already exist:&lt;br /&gt;&lt;br /&gt;%1&lt;br /&gt;&lt;br /&gt;Are you sure you want to replace them? Replacing them will overwrite their contents.</source>
<translation>以下ã®ãƒ•ァイルã¯ã™ã§ã«å­˜åœ¨ã—ã¦ã„ã¾ã™:&lt;br /&gt;&lt;br /&gt;%1&lt;br /&gt;&lt;br /&gt;ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ç½®ãæ›ãˆã¾ã™ã‹ï¼Ÿãƒ•ァイルã®å†…容ã¯ä¸Šæ›¸ãã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="335"/>
<source>Failed to remove the file &lt;b&gt;%1&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Please try to remove the file yourself and try again.</source>
<translation type="obsolete">&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®é™¤åŽ»ã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;br /&gt;&lt;br /&gt;手作業ã§ãƒ•ァイルをå–り除ãã€å†å®Ÿè¡Œã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="405"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="498"/>
<source>You are running a prerelease version of VirtualBox. This version is not suitable for production use.</source>
<translation>ã“れã¯VirtualBoxã®ãƒ—レリリースãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã™ã€‚ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯å®Ÿå‹™ä½œæ¥­ã«ã¯é©ã—ã¦ã„ã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="541"/>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>USBファイルシステム(usbfs)ã‚‚DBusã¨halサービスも利用ã§ããªã„ãŸã‚ã€ãƒ›ã‚¹ãƒˆã‚·ã‚¹ãƒ†ãƒ ã§USBã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ ゲストOSã§ãƒ›ã‚¹ãƒˆUSB デãƒã‚¤ã‚¹ã‚’使用ã™ã‚‹ã«ã¯ã€ã“れを修正ã—ã¦VirtualBoxã‚’å†èµ·å‹•ã—ã¦ãã ã•ã„。</translation>
+ <translation type="obsolete">USBファイルシステム(usbfs)ã‚‚DBusã¨halサービスも利用ã§ããªã„ãŸã‚ã€ãƒ›ã‚¹ãƒˆã‚·ã‚¹ãƒ†ãƒ ã§USBã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ ゲストOSã§ãƒ›ã‚¹ãƒˆUSB デãƒã‚¤ã‚¹ã‚’使用ã™ã‚‹ã«ã¯ã€ã“れを修正ã—ã¦VirtualBoxã‚’å†èµ·å‹•ã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="805"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="953"/>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
<translation>é›»æºãƒœã‚¿ãƒ³ オフã®ACPIイベントã§ã‚²ã‚¹ãƒˆOSをシャットダウンã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ゲストOSãŒACPIサブシステムを使用ã—ãªã„ãŸã‚シャットダウンã§ãã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="814"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="962"/>
<source>&lt;p&gt;VT-x/AMD-V hardware acceleration has been enabled, but is not operational. Your 64-bit guest will fail to detect a 64-bit CPU and will not be able to boot.&lt;/p&gt;&lt;p&gt;Please ensure that you have enabled VT-x/AMD-V properly in the BIOS of your host computer.&lt;/p&gt;</source>
<translation>&lt;p&gt;ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½(VT-x/AMD-V)を有効化ã§ãã¾ã›ã‚“。64ビット ゲストOSã¯64ビットCPUを検出ã§ããšã€èµ·å‹•ã§ãã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;ホストマシンã®BIOS設定ã§VT-x/AMD-Vを有効化ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="847"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="968"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="975"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="988"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="995"/>
<source>Close VM</source>
<translation>仮想マシンを閉ã˜ã‚‹</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2086"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="968"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="975"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="988"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="995"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2251"/>
<source>Continue</source>
<translation>ç¶šã‘ã‚‹</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2086"/>
<source>&lt;p&gt;Are you sure you wish to delete the selected snapshot and saved state?&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;é¸æŠžã•れãŸã‚¹ãƒŠãƒƒãƒ—ショットã¨ä¿å­˜ã•れãŸçŠ¶æ…‹ã‚’å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2086"/>
<source>Discard</source>
<translation type="obsolete">破棄</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2086"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1010"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1015"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1027"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1046"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2251"/>
<source>Cancel</source>
<translation>キャンセル</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2086"/>
<source>&lt;p&gt;There are hard disks attached to ports of the additional controller. If you disable the additional controller, all these hard disks will be automatically detached.&lt;/p&gt;&lt;p&gt;Are you sure you want to disable the additional controller?&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;追加ã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã®ãƒãƒ¼ãƒˆã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒã‚りã¾ã™ã€‚追加ã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã‚’無効ã«ã™ã‚‹ã¨ã€ãれらã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã¯è‡ªå‹•çš„ã«å‰²ã‚Šå½“ã¦è§£é™¤ã•れã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;追加ã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã‚’無効ã«ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2086"/>
<source>&lt;p&gt;There are hard disks attached to ports of the additional controller. If you change the additional controller, all these hard disks will be automatically detached.&lt;/p&gt;&lt;p&gt;Are you sure you want to change the additional controller?&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;追加ã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã®ãƒãƒ¼ãƒˆã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒã‚りã¾ã™ã€‚追加ã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã‚’変更ã™ã‚‹ã¨ã€ãれらã®ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã¯è‡ªå‹•çš„ã«å‰²ã‚Šå½“ã¦è§£é™¤ã•れã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;追加ã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã‚’変更ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2086"/>
<source>Change</source>
<comment>hard disk</comment>
<translation type="obsolete">変更</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2086"/>
<source>&lt;p&gt;Do you want to remove the selected host network interface &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;?&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; This interface may be in use by one or more network adapters of this or another VM. After it is removed, these adapters will no longer work until you correct their settings by either choosing a different interface name or a different adapter attachment type.&lt;/p&gt;</source>
<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/VBoxProblemReporter.cpp" line="2662"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2835"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2842"/>
<source>Failed to create the host-only network interface.</source>
<translation>ホストオンリー ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ インターフェースã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1840"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2005"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1141"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1002"/>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1006"/>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1012"/>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1257"/>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1306"/>
<source>&lt;p&gt;Note that the storage unit of this medium will not be deleted and that it will be possible to use it later again.&lt;/p&gt;</source>
<translation>&lt;p&gt;注:ã“ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã®è¨˜æ†¶è£…ç½®ã¯å‰Šé™¤ã•れã¾ã›ã‚“。å†åº¦åˆ©ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1202"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1367"/>
<source>&lt;p&gt;You are about to add a virtual hard disk to controller &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Would you like to create a new, empty file to hold the disk contents or select an existing one?&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’コントローラ&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã«è¿½åŠ ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;空ã®ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’æ–°è¦ä½œæˆã—ã¾ã™ã‹ï¼Ÿæ—¢å­˜ã®ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚’é¸æŠžã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1209"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1374"/>
<source>Create &amp;new disk</source>
<comment>add attachment routine</comment>
<translation>æ–°è¦ãƒ‡ã‚£ã‚¹ã‚¯ã®ä½œæˆ(&amp;N)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1210"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1375"/>
<source>&amp;Choose existing disk</source>
<comment>add attachment routine</comment>
<translation>既存ã®ãƒ‡ã‚£ã‚¹ã‚¯ã‚’é¸æŠž(&amp;C)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1217"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1382"/>
<source>&lt;p&gt;You are about to add a new CD/DVD drive to controller &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Would you like to choose a virtual CD/DVD disk to put in the drive or to leave it empty for now?&lt;/p&gt;</source>
<translation>&lt;p&gt;CD/DVDドライブをコントローラ&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã«è¿½åŠ ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;仮想CD/DVDディスクをドライブã«å‰²ã‚Šå½“ã¦ã¾ã™ã‹ï¼Ÿç©ºã®ãƒ‰ãƒ©ã‚¤ãƒ–ã ã‘割り当ã¦ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1241"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1390"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1406"/>
<source>&amp;Choose disk</source>
<comment>add attachment routine</comment>
<translation>ãƒ‡ã‚£ã‚¹ã‚¯ã‚’é¸æŠž(&amp;C)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1242"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1391"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1407"/>
<source>Leave &amp;empty</source>
<comment>add attachment routine</comment>
<translation>空ã®ãƒ‰ãƒ©ã‚¤ãƒ–(&amp;E)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1233"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1398"/>
<source>&lt;p&gt;You are about to add a new floppy drive to controller &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Would you like to choose a virtual floppy disk to put in the drive or to leave it empty for now?&lt;/p&gt;</source>
<translation>&lt;p&gt;フロッピードライブをコントローラ&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã«è¿½åŠ ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;仮想フロッピーディスクをドライブã«å‰²ã‚Šå½“ã¦ã¾ã™ã‹ï¼Ÿç©ºã®ãƒ‰ãƒ©ã‚¤ãƒ–ã ã‘割り当ã¦ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1276"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1441"/>
<source>Failed to detach the hard disk (&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;) from 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/VBoxProblemReporter.cpp" line="1282"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1447"/>
<source>Failed to detach the CD/DVD device (&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;) from 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/VBoxProblemReporter.cpp" line="1288"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1453"/>
<source>Failed to detach the floppy device (&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;) from 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/VBoxProblemReporter.cpp" line="1288"/>
<source>&lt;p&gt;The VirtualBox Guest Additions do not appear to be available on this virtual machine, and shared folders cannot be used without them. To use shared folders inside the virtual machine, please install the Guest Additions if they are not installed, or re-install them if they are not working correctly, by selecting &lt;b&gt;Install Guest Additions&lt;/b&gt; from the &lt;b&gt;Machine&lt;/b&gt; menu. If they are installed but the machine is not yet fully started then shared folders will be available once it is.&lt;/p&gt;</source>
<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/VBoxProblemReporter.cpp" line="2025"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2190"/>
<source>Failed to open appliance.</source>
<translation>仮想アプライアンスã®ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2041"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2206"/>
<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/VBoxProblemReporter.cpp" line="2053"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2218"/>
<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/VBoxProblemReporter.cpp" line="2080"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2245"/>
<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/VBoxProblemReporter.cpp" line="2095"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2260"/>
<source>Failed to create appliance.</source>
<translation>仮想アプライアンスã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2120"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2268"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2285"/>
<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/VBoxProblemReporter.cpp" line="2115"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2280"/>
<source>Failed to create an appliance.</source>
<translation>仮想アプライアンスã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2131"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2296"/>
<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>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1404"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1569"/>
<source>&lt;p&gt;Deleting this host-only network will remove the host-only interface this network is based on. Do you want to remove the (host-only network) interface &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;?&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; this interface may be in use by one or more virtual network adapters belonging to one of your VMs. After it is removed, these adapters will no longer be usable until you correct their settings by either choosing a different interface name or a different adapter attachment type.&lt;/p&gt;</source>
<translation>&lt;p&gt;ã“ã®ã‚¤ãƒ³ã‚¿ãƒ•ェースを削除ã™ã‚‹ã¨ã€ã“ã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェースãŒåŸºã¥ã„ã¦ã„るホストオンリー ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ インタフェースãŒå‰Šé™¤ã•れã¾ã™ã€‚ホストオンリー ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ インタフェース&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;を削除ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;&lt;p&gt;&lt;b&gt;注:&lt;/b&gt;ã“ã®ã‚¤ãƒ³ã‚¿ãƒ•ェースã¯ä»–ã®ä»®æƒ³ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタã§ä½¿ç”¨ã—ã¦ã„ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。削除ã—ãŸå ´åˆã€ãれらã®ã‚¢ãƒ€ãƒ—ã‚¿ã¯ã€ä»–ã®ã‚¤ãƒ³ã‚¿ãƒ•ェースåã‚’é¸ã¶ã‹ã€åˆ¥ã®ã‚¢ãƒ€ãƒ—ã‚¿ タイプをé¸ã‚“ã§è¨­å®šã‚’変更ã™ã‚‹ã¾ã§ä½¿ç”¨ã§ãã¾ã›ã‚“。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="326"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="427"/>
<source>A file named &lt;b&gt;%1&lt;/b&gt; already exists. Are you sure you want to replace it?&lt;br /&gt;&lt;br /&gt;Replacing it will overwrite its contents.</source>
<translation>ファイルå&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã¯ã™ã§ã«ä½¿ã‚れã¦ã„ã¾ã™ã€‚ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ç½®ãæ›ãˆã¾ã™ã‹ï¼Ÿ&lt;br /&gt;&lt;br /&gt;ファイルã®å†…容ã¯ä¸Šæ›¸ãã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="834"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="982"/>
<source>&lt;p&gt;VT-x/AMD-V hardware acceleration has been enabled, but is not operational. Certain guests (e.g. OS/2 and QNX) require this feature.&lt;/p&gt;&lt;p&gt;Please ensure that you have enabled VT-x/AMD-V properly in the BIOS of your host computer.&lt;/p&gt;</source>
<translation>&lt;p&gt;ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½(VT-x/AMD-V)ãŒæœ‰åŠ¹åŒ–ã•れã¾ã—ãŸãŒä½¿ç”¨ã§ãã¾ã›ã‚“。ã„ãã¤ã‹ã®ã‚²ã‚¹ãƒˆOS(OS/2ã‚„QNXãªã©))ã¯æœ¬æ©Ÿèƒ½ã‚’å¿…è¦ã¨ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;ホストマシンã®BIOS設定ã§VT-x/AMD-Vを有効化ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1472"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1637"/>
<source>&lt;p&gt;The VirtualBox Guest Additions do not appear to be available on this virtual machine, and shared folders cannot be used without them. To use shared folders inside the virtual machine, please install the Guest Additions if they are not installed, or re-install them if they are not working correctly, by selecting &lt;b&gt;Install Guest Additions&lt;/b&gt; from the &lt;b&gt;Devices&lt;/b&gt; menu. If they are installed but the machine is not yet fully started then shared folders will be available once it is.&lt;/p&gt;</source>
<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/VBoxProblemReporter.cpp" line="1627"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1792"/>
<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/VBoxProblemReporter.cpp" line="1630"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1795"/>
<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/VBoxProblemReporter.cpp" line="2063"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2228"/>
<source>Failed to check files.</source>
<translation>ファイルã®ç¢ºèªã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2073"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2238"/>
<source>Failed to remove file.</source>
<translation>ファイルã®é™¤å޻䏭ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="385"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="486"/>
<source>You seem to have the USBFS filesystem mounted at /sys/bus/usb/drivers. We strongly recommend that you change this, as it is a severe mis-configuration of your system which could cause USB devices to fail in unexpected ways.</source>
<translation>USBFS ファイルシステムを/sys/bus/usb/driversã«ãƒžã‚¦ãƒ³ãƒˆã—ã¦ã„ã¾ã™ã€‚ã“れを変更ã™ã‚‹ã“ã¨ã‚’å¼·ãå‹§ã‚ã¾ã™ã€‚誤ã£ãŸã‚·ã‚¹ãƒ†ãƒ æ§‹æˆã«ã‚ˆã‚ŠUSB デãƒã‚¤ã‚¹ã®ä½¿ç”¨ã«å¤±æ•—ã™ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="413"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="506"/>
<source>You are running an EXPERIMENTAL build of VirtualBox. This version is not suitable for production use.</source>
<translation>ã“れã¯VirtualBoxã®è©¦é¨“的ビルドã§ã™ã€‚ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯å®Ÿå‹™ä½œæ¥­ã«ã¯é©ã—ã¦ã„ã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="823"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="971"/>
<source>&lt;p&gt;VT-x/AMD-V hardware acceleration is not available on your system. Your 64-bit guest will fail to detect a 64-bit CPU and will not be able to boot.</source>
<translation>&lt;p&gt;ホストマシンã®ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½(VT-x/AMD-V)ãŒä½¿ç”¨ã§ãã¾ã›ã‚“。64ビット ゲストOSã¯64ビットCPUを検出ã§ããšã€èµ·å‹•ã§ãã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="843"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="991"/>
<source>&lt;p&gt;VT-x/AMD-V hardware acceleration is not available on your system. Certain guests (e.g. OS/2 and QNX) require this feature and will fail to boot without it.&lt;/p&gt;</source>
<translation>&lt;p&gt;ホストマシンã®ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½(VT-x/AMD-V)ãŒä½¿ç”¨ã§ãã¾ã›ã‚“。本機能を必è¦ã¨ã™ã‚‹ã„ãã¤ã‹ã®ã‚²ã‚¹ãƒˆOS(OS/2ã‚„QNXãªã©)ã¯èµ·å‹•ã§ãã¾ã›ã‚“。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="853"/>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;スナップショット&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã«å¾©å…ƒã—ã¾ã™ã‹ï¼Ÿç¾åœ¨ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®çŠ¶æ…‹ã¯å¤±ã‚れã€ãれを回復ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;スナップショット&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã«å¾©å…ƒã—ã¾ã™ã‹ï¼Ÿç¾åœ¨ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®çŠ¶æ…‹ã¯å¤±ã‚れã€ãれを回復ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="858"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1010"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1015"/>
<source>Restore</source>
<translation>復元</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="864"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1021"/>
<source>&lt;p&gt;Deleting the snapshot will cause the state information saved in it to be lost, and disk data spread over several image files that VirtualBox has created together with the snapshot will be merged into one file. This can be a lengthy process, and the information in the snapshot cannot be recovered.&lt;/p&gt;&lt;/p&gt;Are you sure you want to delete the selected snapshot &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;&quot;%1&quot;&lt;/b&gt;を削除ã—ã¾ã™ã‹ï¼Ÿã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="889"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1027"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1046"/>
<source>Delete</source>
<translation>削除</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="879"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1036"/>
<source>&lt;p&gt;Deleting the snapshot %1 will temporarily need more disk space. In the worst case the size of image %2 will grow by %3, however on this filesystem there is only %4 free.&lt;/p&gt;&lt;p&gt;Running out of disk space during the merge operation can result in corruption of the image and the VM configuration, i.e. loss of the VM and its data.&lt;/p&gt;&lt;p&gt;You may continue with deleting the snapshot at your own risk.&lt;/p&gt;</source>
<translation>&lt;p&gt;スナップショット %1ã®å‰Šé™¤ã«ã¯å¤šãã®ãƒ‡ã‚£ã‚¹ã‚¯å®¹é‡ã‚’å¿…è¦ã¨ã—ã¾ã™ã€‚ディスクイメージファイル %2ã®ã‚µã‚¤ã‚ºã¯æœ€å¤§ã§%3ã¾ã§å¢—加ã—ã¾ã™ã€‚ã—ã‹ã—ã€ãƒ‡ã‚£ã‚¹ã‚¯ã®ç©ºã容é‡ã¯%4ã—ã‹ã‚りã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;マージ作業中ã«ãƒ‡ã‚£ã‚¹ã‚¯å®¹é‡ãŒä¸è¶³ã™ã‚‹ã¨ã€ä»®æƒ³ãƒžã‚·ãƒ³ã®ãƒ‡ãƒ¼ã‚¿ã‚’失ã†å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;スナップショットã®å‰Šé™¤ã‚’自己責任ã§ç¶šè¡Œã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="908"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1053"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1065"/>
<source>Failed to restore the snapshot &lt;b&gt;%1&lt;/b&gt; of the virtual machine &lt;b&gt;%2&lt;/b&gt;.</source>
<translation>仮想マシン&lt;b&gt;&quot;%2&quot;&lt;/b&gt;ã®ã‚¹ãƒŠãƒƒãƒ—ショット&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã¸ã®å¾©å…ƒã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="930"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1075"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1087"/>
<source>Failed to delete the snapshot &lt;b&gt;%1&lt;/b&gt; of the virtual machine &lt;b&gt;%2&lt;/b&gt;.</source>
<translation>仮想マシン&lt;b&gt;&quot;%2&quot;&lt;/b&gt;ã®ã‚¹ãƒŠãƒƒãƒ—ショット&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="982"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1139"/>
<source>&lt;p&gt;Could not change the guest screen to this host screen due to insufficient guest video memory.&lt;/p&gt;&lt;p&gt;You should configure the virtual machine to have at least &lt;b&gt;%1&lt;/b&gt; of video memory.&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/VBoxProblemReporter.cpp" line="992"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1149"/>
<source>&lt;p&gt;Could not change the guest screen to this host screen due to insufficient guest video memory.&lt;/p&gt;&lt;p&gt;You should configure the virtual machine to have at least &lt;b&gt;%1&lt;/b&gt; of video memory.&lt;/p&gt;&lt;p&gt;Press &lt;b&gt;Ignore&lt;/b&gt; to switch the screen anyway or press &lt;b&gt;Cancel&lt;/b&gt; to cancel the operation.&lt;/p&gt;</source>
<translation>&lt;p&gt;ビデオメモリä¸è¶³ã®ãŸã‚ã€ã‚²ã‚¹ãƒˆ スクリーンをã“ã®ãƒ›ã‚¹ãƒˆ スクリーンã«å¤‰æ›´ã§ãã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;ä»®æƒ³ãƒžã‚·ãƒ³ã®æ§‹æˆã§&lt;b&gt;%1&lt;/b&gt;以上ã®ãƒ“デオメモリを指定ã—ã¦ãã ã•ã„。&lt;/p&gt;&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/VBoxProblemReporter.cpp" line="1007"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1164"/>
<source>&lt;p&gt;Can not switch the guest display to fullscreen mode. You have more virtual screens configured than physical screens are attached to your host.&lt;/p&gt;&lt;p&gt;Please either lower the virtual screens in your VM configuration or attach additional screens to your host.&lt;/p&gt;</source>
<translation>&lt;p&gt;ゲスト ディスプレイをフルスクリーンモードã«å¤‰æ›´ã§ãã¾ã›ã‚“ã€‚ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã«æŽ¥ç¶šã•れã¦ã„る実ディスプレイよりも多ãã®ä»®æƒ³ãƒ‡ã‚£ã‚¹ãƒ—レイãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;ä»®æƒ³ãƒ‡ã‚£ã‚¹ãƒ—ãƒ¬ã‚¤ã®æ•°ã‚’減らã™ã‹ã€ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã«ãƒ‡ã‚£ã‚¹ãƒ—レイを追加ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1019"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1176"/>
<source>&lt;p&gt;Can not switch the guest display to seamless mode. You have more virtual screens configured than physical screens are attached to your host.&lt;/p&gt;&lt;p&gt;Please either lower the virtual screens in your VM configuration or attach additional screens to your host.&lt;/p&gt;</source>
<translation>&lt;p&gt;ゲスト ディスプレイをシームレスモードã«å¤‰æ›´ã§ãã¾ã›ã‚“ã€‚ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã«æŽ¥ç¶šã•れã¦ã„る実ディスプレイよりも多ãã®ä»®æƒ³ãƒ‡ã‚£ã‚¹ãƒ—レイãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;ä»®æƒ³ãƒ‡ã‚£ã‚¹ãƒ—ãƒ¬ã‚¤ã®æ•°ã‚’減らã™ã‹ã€ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã«ãƒ‡ã‚£ã‚¹ãƒ—レイを追加ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1019"/>
<source>&lt;p&gt;There are no unused media available for the newly created attachment.&lt;/p&gt;&lt;p&gt;Press the &lt;b&gt;Create&lt;/b&gt; button to start the &lt;i&gt;New Virtual Disk&lt;/i&gt; wizard and create a new medium, or press the &lt;b&gt;Select&lt;/b&gt; if you wish to open the &lt;i&gt;Virtual Media Manager&lt;/i&gt;.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;æ–°è¦ã®å‰²ã‚Šå½“ã¦ã«åˆ©ç”¨ã§ãる未使用ã®ãƒ¡ãƒ‡ã‚£ã‚¢ãŒã‚りã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;&lt;b&gt;[作æˆ]&lt;/b&gt;ボタンをクリックã—ã€&lt;i&gt;æ–°è¦ä»®æƒ³ãƒ‡ã‚£ã‚¹ã‚¯ä½œæˆã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰&lt;/i&gt;ã‚’èµ·å‹•ã—ã¦æ–°è¦ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’作æˆã™ã‚‹ã‹ã€&lt;b&gt;[é¸æŠž]&lt;/b&gt;ボタンをクリックã—ã¦ã€&lt;i&gt;仮想メディアマãƒãƒ¼ã‚¸ãƒ£&lt;/i&gt;ã‚’é–‹ã„ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1019"/>
<source>&amp;Create</source>
<comment>medium</comment>
<translation type="obsolete">作æˆ(&amp;C)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1019"/>
<source>&amp;Select</source>
<comment>medium</comment>
<translation type="obsolete">é¸æŠž(&amp;S)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1019"/>
<source>&lt;p&gt;There are no unused media available for the newly created attachment.&lt;/p&gt;&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; if you wish to open the &lt;i&gt;Virtual Media Manager&lt;/i&gt;.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;æ–°è¦ã®å‰²ã‚Šå½“ã¦ã«åˆ©ç”¨ã§ãる未使用ã®ãƒ¡ãƒ‡ã‚£ã‚¢ãŒã‚りã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;&lt;b&gt;[é¸æŠž]&lt;/b&gt;ボタンをクリックã—ã¦ã€&lt;i&gt;仮想メディアマãƒãƒ¼ã‚¸ãƒ£&lt;/i&gt;ã‚’é–‹ã„ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1248"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1413"/>
<source>&lt;p&gt;Are you sure you want to delete the CD/DVD-ROM device?&lt;/p&gt;&lt;p&gt;You will not be able to mount any CDs or ISO images or install the Guest Additions without it!&lt;/p&gt;</source>
<translation>&lt;p&gt;CD/DVD-ROM デãƒã‚¤ã‚¹ã‚’削除ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;&lt;p&gt;デãƒã‚¤ã‚¹ãŒãªã„å ´åˆã€CD/DVDメディアやISOイメージファイルã®ãƒžã‚¦ãƒ³ãƒˆãŠã‚ˆã³Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã¯ã§ãã¾ã›ã‚“ï¼&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1252"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1417"/>
<source>&amp;Remove</source>
<comment>medium</comment>
<translation>除去(&amp;R)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1252"/>
<source>Failed to attach the %1 to slot &lt;i&gt;%2&lt;/i&gt; of the machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation type="obsolete">&quot;%1&quot;ã®ä»®æƒ³ãƒžã‚·ãƒ³&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/VBoxProblemReporter.cpp" line="1252"/>
<source>Failed to detach the %1 from slot &lt;i&gt;%2&lt;/i&gt; of the machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation type="obsolete">&quot;%1&quot;ã®ä»®æƒ³ãƒžã‚·ãƒ³&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/VBoxProblemReporter.cpp" line="1306"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1471"/>
<source>Unable to mount the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt; on the machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation>%1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;を仮想マシン&lt;b&gt;&quot;%3&quot;&lt;/b&gt;ã«ãƒžã‚¦ãƒ³ãƒˆã§ãã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1307"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1472"/>
<source> Would you like to force mounting of this medium?</source>
<translation>メディアを強制マウントã—ã¾ã™ã‹ï¼Ÿ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1311"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1476"/>
<source>Unable to unmount the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt; from the machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation>%1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;を仮想マシン&lt;b&gt;&quot;%3&quot;&lt;/b&gt;ã‹ã‚‰ãƒžã‚¦ãƒ³ãƒˆè§£é™¤ã§ãã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1312"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1477"/>
<source> Would you like to force unmounting of this medium?</source>
<translation>メディアを強制マウント解除ã—ã¾ã™ã‹ï¼Ÿ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1322"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1487"/>
<source>Force Unmount</source>
<translation>強制マウント解除</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1322"/>
<source>Failed to eject the disk from the virtual drive. The drive may be locked by the guest operating system. Please check this and try again.</source>
<translation type="obsolete">仮想ドライブã®ãƒ‡ã‚£ã‚¹ã‚¯ã®å–り出ã—ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã“ã®ãƒ‰ãƒ©ã‚¤ãƒ–ã¯ã‚²ã‚¹ãƒˆOSã«ã‚ˆã£ã¦ãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™ã€‚確èªå¾Œã€å†å®Ÿè¡Œã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1510"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1675"/>
<source>&lt;p&gt;Could not insert the VirtualBox Guest Additions installer CD image into the virtual machine &lt;b&gt;%1&lt;/b&gt;, as the machine has no CD/DVD-ROM drives. Please add a drive using the storage page of the virtual machine settings dialog.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ãŒCD/DVD-ROMドライブをæŒãŸãªã„ãŸã‚ã€VirtualBox Guest Additionsã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«CDイメージを仮想マシンã«ã‚¤ãƒ³ã‚µãƒ¼ãƒˆã§ãã¾ã›ã‚“。 仮想マシン設定ダイアログã®[ストレージ]ページã§ãƒ‰ãƒ©ã‚¤ãƒ–を追加ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1547"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1712"/>
<source>&lt;p&gt;Could not find the VirtualBox User Manual &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;Do you wish to download this file from the Internet?&lt;/p&gt;</source>
<translation>&lt;p&gt;VirtualBox ユーザーマニュアル &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;ユーザーマニュアルをダウンロードã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1558"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1723"/>
<source>&lt;p&gt;Are you sure you want to download the VirtualBox User Manual from &lt;nobr&gt;&lt;a href=&quot;%1&quot;&gt;%2&lt;/a&gt;&lt;/nobr&gt; (size %3 bytes)?&lt;/p&gt;</source>
<translation>&lt;p&gt;VirtualBox ユーザーマニュアルを&lt;nobr&gt;&lt;a href=&quot;%1&quot;&gt;%2&lt;/a&gt;&lt;/nobr&gt; (サイズ %3ãƒã‚¤ãƒˆ)ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1569"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1734"/>
<source>&lt;p&gt;Failed to download the VirtualBox User Manual from &lt;nobr&gt;&lt;a href=&quot;%1&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;nobr&gt;&lt;a href=&quot;%1&quot;&gt;%2&lt;/a&gt;ã‹ã‚‰VirtualBox ユーザーマニュアルをダウンロードã§ãã¾ã›ã‚“。&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1577"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1742"/>
<source>&lt;p&gt;The VirtualBox User Manual has been successfully downloaded from &lt;nobr&gt;&lt;a href=&quot;%1&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;</source>
<translation>&lt;p&gt;VirtualBox ユーザーマニュアルを&lt;nobr&gt;&lt;a href=&quot;%1&quot;&gt;%2&lt;/a&gt;&lt;/nobr&gt;ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ã€&lt;nobr&gt;&lt;b&gt;%3&lt;/b&gt;&lt;/nobr&gt;ã«ä¿å­˜ã—ã¾ã—ãŸã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1587"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="1752"/>
<source>&lt;p&gt;The VirtualBox User Manual has been successfully downloaded from &lt;nobr&gt;&lt;a href=&quot;%1&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>&lt;p&gt;VirtualBox ユーザーマニュアルを&lt;nobr&gt;&lt;a href=&quot;%1&quot;&gt;%2&lt;/a&gt;&lt;/nobr&gt;ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ã¾ã—ãŸãŒã€&lt;nobr&gt;&lt;b&gt;%3&lt;/b&gt;&lt;/nobr&gt;ã«ä¿å­˜ã§ãã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;ä»–ã®ä¿å­˜å ´æ‰€ã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1869"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2016"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2034"/>
<source>E&amp;xit</source>
<comment>warnAboutSettingsAutoConversion message box</comment>
<translation>終了(&amp;X)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1857"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2022"/>
<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/VBoxProblemReporter.cpp" line="1882"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2047"/>
<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/VBoxProblemReporter.cpp" line="1902"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2067"/>
<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/VBoxProblemReporter.cpp" line="1922"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2087"/>
<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/VBoxProblemReporter.cpp" line="1930"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2095"/>
<source>Switch</source>
<comment>scale</comment>
<translation>切り替ãˆ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="1986"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2151"/>
<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/VBoxProblemReporter.cpp" line="2157"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2314"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2322"/>
<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/VBoxProblemReporter.cpp" line="2191"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2356"/>
<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/VBoxProblemReporter.cpp" line="2202"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2367"/>
<source>&amp;Install</source>
<translation>インストール(&amp;I)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2212"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2377"/>
<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/VBoxProblemReporter.cpp" line="2225"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2390"/>
<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/VBoxProblemReporter.cpp" line="2235"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2400"/>
<source>&amp;Upgrade</source>
<translation>アップグレード(&amp;U)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2239"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2404"/>
<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/VBoxProblemReporter.cpp" line="2249"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2414"/>
<source>&amp;Downgrade</source>
<translation>ダウングレード(&amp;D)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2253"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2418"/>
<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/VBoxProblemReporter.cpp" line="2262"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2427"/>
<source>&amp;Reinstall</source>
<translation>å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«(&amp;R)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2270"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2435"/>
<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/VBoxProblemReporter.cpp" line="2280"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2445"/>
<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/VBoxProblemReporter.cpp" line="2401"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2566"/>
<source>hard disk</source>
<comment>failed to mount ...</comment>
<translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2403"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2568"/>
<source>CD/DVD</source>
<comment>failed to mount ... host-drive</comment>
<translation>CD/DVD</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2405"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2570"/>
<source>CD/DVD image</source>
<comment>failed to mount ...</comment>
<translation>CD/DVD イメージ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2407"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2572"/>
<source>floppy</source>
<comment>failed to mount ... host-drive</comment>
<translation>フロッピー</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2574"/>
<source>floppy image</source>
<comment>failed to mount ...</comment>
<translation>フロッピー イメージ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="2983"/>
+ <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/VBoxProblemReporter.cpp" line="3039"/>
+ <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/VBoxProblemReporter.cpp" line="3040"/>
+ <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/VBoxProblemReporter.cpp" line="3041"/>
+ <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/VBoxProblemReporter.cpp" line="3042"/>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/VBoxProblemReporter.cpp" line="3043"/>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>hard disk</source>
<comment>failed to attach ...</comment>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>CD/DVD device</source>
<comment>failed to attach ...</comment>
<translation type="obsolete">CD/DVD デãƒã‚¤ã‚¹</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>floppy device</source>
<comment>failed to close ...</comment>
<translation type="obsolete">フロッピー デãƒã‚¤ã‚¹</translation>
@@ -12622,147 +12564,118 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxRegistrationDlg</name>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>VirtualBox Registration Dialog</source>
<translation type="obsolete">VirtualBox 登録ダイアログ</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>&amp;Name</source>
<translation type="obsolete">åå‰(&amp;N)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>Enter your full name using Latin characters.</source>
<translation type="obsolete">フルãƒãƒ¼ãƒ ã‚’英字ã§å…¥åŠ›ã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>&amp;E-mail</source>
<translation type="obsolete">メールアドレス(&amp;E)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>Enter your e-mail address. Please use a valid address here.</source>
<translation type="obsolete">メールアドレスを入力ã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>&amp;Please do not use this information to contact me</source>
<translation type="obsolete">情報メールä¸è¦(&amp;P)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>Welcome to the VirtualBox Registration Form!</source>
<translation type="obsolete">よã†ã“ã VirtualBox 登録フォームã¸ï¼</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>&amp;Confirm</source>
<translation type="obsolete">確èª(&amp;C)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>Connection timed out.</source>
<translation type="obsolete">接続ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã«ãªã‚Šã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>Could not locate the registration form on the server (response: %1).</source>
<translation type="obsolete">サーãƒãƒ¼ä¸Šã«ç™»éŒ²ãƒ•ォームãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ(応答: %1)。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>Could not perform connection handshake.</source>
<translation type="obsolete">接続を確立ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>&lt;p&gt;Please fill out this registration form to let us know that you use VirtualBox and, optionally, to keep you informed about VirtualBox news and updates.&lt;/p&gt;&lt;p&gt;Enter your full name using Latin characters and your e-mail address to the fields below. Sun Microsystems will use this information only to gather product usage statistics and to send you VirtualBox newsletters. In particular, Sun Microsystems will never pass your data to third parties. Detailed information about how we use your personal data can be found in the &lt;b&gt;Privacy Policy&lt;/b&gt; section of the VirtualBox Manual or on the &lt;a href=http://www.virtualbox.org/wiki/PrivacyPolicy&gt;Privacy Policy&lt;/a&gt; page of the VirtualBox web-site.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;登録フォームã«å…¥åŠ›ã—ã€ã‚ãªãŸãŒ VirtualBox を使用ã—ã¦ã„ã‚‹ã“ã¨ã‚’我々ã«çŸ¥ã‚‰ã›ã¦ãã ã•ã„。VirtualBox ã®ãƒ‹ãƒ¥ãƒ¼ã‚¹ã¨æ›´æ–°æƒ…報をãŠçŸ¥ã‚‰ã›ã—ã¾ã™(ä»»æ„)。&lt;/p&gt;&lt;p&gt;フルãƒãƒ¼ãƒ (英字)ã¨ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’下ã®ãƒ•ィールドã«å…¥åŠ›ã—ã¦ãã ã•ã„。注:Sun Microsystems ã¯ã€ã“ã®æƒ…報を製å“使用ã®çµ±è¨ˆã‚’åŽé›†ã—ã€VirtualBox ニュースレターをé€ä¿¡ã™ã‚‹ãŸã‚ã ã‘ã«ä½¿ç”¨ã—ã¾ã™ã€‚Sun Microsystems ãŒå€‹äººæƒ…å ±ã‚’ç¬¬ä¸‰è€…ã«æ¸¡ã™ã“ã¨ã¯ã‚りã¾ã›ã‚“ã€‚å€‹äººæƒ…å ±ã®æ‰±ã„ã«é–¢ã™ã‚‹è©³ç´°æƒ…å ±ã¯ã€VirtualBox マニュアルã®&quot;&lt;b&gt;Privacy Policy&lt;/b&gt;&quot; セクションã¾ãŸã¯ VirtualBox webサイトã®&quot;&lt;a href=http://www.virtualbox.org/wiki/PrivacyPolicy&gt;Privacy Policy&lt;/a&gt;&quot;ページをå‚ç…§ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>Check this box if you do not want to receive mail from Sun Microsystems at the e-mail address specified above.</source>
<translation type="obsolete">Sun Microsystems ã‹ã‚‰ã®æƒ…報メールをå—ã‘å–りãŸããªã„å ´åˆã€ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã‚’オンã«ã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>C&amp;onfirm</source>
<translation type="obsolete">確èª(&amp;O)</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>Select Country/Territory</source>
<translation type="obsolete">国/åœ°åŸŸã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>&lt;p&gt;Please fill out this registration form to let us know that you use VirtualBox and, optionally, to keep you informed about VirtualBox news and updates.&lt;/p&gt;&lt;p&gt;Please use Latin characters only to fill in the fields below. Sun Microsystems will use this information only to gather product usage statistics and to send you VirtualBox newsletters. In particular, Sun Microsystems will never pass your data to third parties. Detailed information about how we use your personal data can be found in the &lt;b&gt;Privacy Policy&lt;/b&gt; section of the VirtualBox Manual or on the &lt;a href=http://www.virtualbox.org/wiki/PrivacyPolicy&gt;Privacy Policy&lt;/a&gt; page of the VirtualBox web-site.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;登録フォームã«å…¥åŠ›ã—ã€ã‚ãªãŸãŒ VirtualBox を使用ã—ã¦ã„ã‚‹ã“ã¨ã‚’我々ã«çŸ¥ã‚‰ã›ã¦ãã ã•ã„。VirtualBox ã®ãƒ‹ãƒ¥ãƒ¼ã‚¹ã¨æ›´æ–°æƒ…報をãŠçŸ¥ã‚‰ã›ã—ã¾ã™(ä»»æ„)。&lt;/p&gt;&lt;p&gt;フルãƒãƒ¼ãƒ (英字)ã¨ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’下ã®ãƒ•ィールドã«å…¥åŠ›ã—ã¦ãã ã•ã„。注:Sun Microsystems ã¯ã€ã“ã®æƒ…報を製å“使用ã®çµ±è¨ˆã‚’åŽé›†ã—ã€VirtualBox ニュースレターをé€ä¿¡ã™ã‚‹ãŸã‚ã ã‘ã«ä½¿ç”¨ã—ã¾ã™ã€‚Sun Microsystems ãŒå€‹äººæƒ…å ±ã‚’ç¬¬ä¸‰è€…ã«æ¸¡ã™ã“ã¨ã¯ã‚りã¾ã›ã‚“ã€‚å€‹äººæƒ…å ±ã®æ‰±ã„ã«é–¢ã™ã‚‹è©³ç´°æƒ…å ±ã¯ã€VirtualBox マニュアルã®&quot;&lt;b&gt;Privacy Policy&lt;/b&gt;&quot; セクションã¾ãŸã¯ VirtualBox webサイトã®&quot;&lt;a href=http://www.virtualbox.org/wiki/PrivacyPolicy&gt;Privacy Policy&lt;/a&gt;&quot;ページをå‚ç…§ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>I &amp;already have a Sun Online account:</source>
<translation type="obsolete">Sun オンライン アカウントã«ç™»éŒ²æ¸ˆã¿ã§ã™(&amp;H):</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>&amp;E-mail:</source>
<translation type="obsolete">メールアドレス:</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>&amp;Password:</source>
<translation type="obsolete">パスワード:</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>I &amp;would like to create a new Sun Online account:</source>
<translation type="obsolete">Sun オンライン アカウントを作æˆã—ã¦ç™»éŒ²ã—ã¾ã™(&amp;W):</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>&amp;First Name:</source>
<translation type="obsolete">åå‰(&amp;F):</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>&amp;Last Name:</source>
<translation type="obsolete">å§“(&amp;L):</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>&amp;Company:</source>
<translation type="obsolete">会社(&amp;C):</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>Co&amp;untry:</source>
<translation type="obsolete">国/地域(&amp;U):</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>E-&amp;mail:</source>
<translation type="obsolete">メールアドレス(&amp;M):</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>P&amp;assword:</source>
<translation type="obsolete">パスワード(&amp;A):</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>Co&amp;nfirm Password:</source>
<translation type="obsolete">パスワード確èª(&amp;N):</translation>
</message>
<message>
- <location filename="../src/globals/VBoxProblemReporter.cpp" line="2409"/>
<source>&amp;Register</source>
<translation type="obsolete">登録(R)</translation>
</message>
@@ -12770,22 +12683,18 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxSFDialog</name>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="221"/>
<source>Shared Folders</source>
- <translation>共有フォルダ</translation>
+ <translation type="obsolete">共有フォルダ</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="221"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="221"/>
<source>Help</source>
<translation type="obsolete">ヘルプ</translation>
</message>
<message>
- <location filename="../src/runtime/UIMachineLogic.cpp" line="221"/>
<source>&amp;OK</source>
<translation type="obsolete">OK(&amp;O)</translation>
</message>
@@ -12811,482 +12720,459 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxSelectorWnd</name>
<message>
- <location filename="../src/VBoxSnapshotDetailsDlg.cpp" line="242"/>
<source>VirtualBox OSE</source>
<translation type="obsolete">VirtualBox OSE</translation>
</message>
<message>
- <location filename="../src/VBoxSnapshotDetailsDlg.cpp" line="242"/>
<source>&amp;Details</source>
<translation type="obsolete">詳細(&amp;D)</translation>
</message>
<message>
- <location filename="../src/VBoxSnapshotDetailsDlg.cpp" line="242"/>
<source>Virtual &amp;Disk Manager...</source>
<translation type="obsolete">仮想ディスクマãƒãƒ¼ã‚¸ãƒ£(&amp;D)...</translation>
</message>
<message>
- <location filename="../src/VBoxSnapshotDetailsDlg.cpp" line="242"/>
<source>Ctrl+D</source>
<translation type="obsolete">Ctrl+D</translation>
</message>
<message>
- <location filename="../src/VBoxSnapshotDetailsDlg.cpp" line="242"/>
<source>Display the Virtual Disk Manager dialog</source>
<translation type="obsolete">仮想ディスクマãƒãƒ¼ã‚¸ãƒ£ ダイアログを表示</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1217"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1216"/>
<source>&amp;Preferences...</source>
<comment>global settings</comment>
<translation>環境設定(&amp;P)...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1217"/>
<source>Ctrl+G</source>
<translation type="obsolete">Ctrl+G</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1219"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1218"/>
<source>Display the global settings dialog</source>
<translation>環境設定ダイアログを表示</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1221"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1220"/>
<source>E&amp;xit</source>
<translation>終了(&amp;X)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1221"/>
<source>Ctrl+Q</source>
<translation type="obsolete">Ctrl+Q</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1223"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1222"/>
<source>Close application</source>
<translation>アプリケーションを閉ã˜ã‚‹</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1225"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1224"/>
<source>&amp;New...</source>
<translation>æ–°è¦(&amp;N)...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1225"/>
<source>New</source>
<translation type="obsolete">æ–°è¦</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1225"/>
<source>Ctrl+N</source>
<translation type="obsolete">Ctrl+N</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1227"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1226"/>
<source>Create a new virtual machine</source>
<translation>æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã®ä½œæˆ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1235"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1234"/>
<source>&amp;Settings...</source>
<translation>設定(&amp;S)...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1235"/>
<source>Settings</source>
<translation type="obsolete">設定</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1235"/>
<source>Ctrl+S</source>
<translation type="obsolete">Ctrl+S</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1237"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1236"/>
<source>Configure the selected virtual machine</source>
<translation>é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã‚’設定</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1237"/>
<source>&amp;Delete</source>
<translation type="obsolete">削除(&amp;D)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1237"/>
<source>Delete</source>
<translation type="obsolete">削除</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1237"/>
<source>Delete the selected virtual machine</source>
<translation type="obsolete">é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã‚’削除</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1247"/>
<source>D&amp;iscard</source>
- <translation>破棄(&amp;I)</translation>
+ <translation type="obsolete">破棄(&amp;I)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1247"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1250"/>
<source>Discard</source>
- <translation type="obsolete">破棄</translation>
+ <translation type="unfinished">破棄</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1250"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1254"/>
<source>Discard the saved state of the selected virtual machine</source>
<translation>é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã‚’破棄</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1250"/>
<source>&amp;Refresh</source>
<translation type="obsolete">æœ€æ–°ã®æƒ…å ±ã«æ›´æ–°(&amp;R)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1250"/>
<source>Refresh</source>
<translation type="obsolete">æœ€æ–°ã®æƒ…å ±ã«æ›´æ–°</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1250"/>
<source>Ctrl+R</source>
<translation type="obsolete">Ctrl+R</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1261"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1265"/>
<source>Refresh the accessibility state of the selected virtual machine</source>
<translation>é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®ã‚¢ã‚¯ã‚»ã‚¹å¯å¦çŠ¶æ…‹ã‚’æœ€æ–°ã®æƒ…å ±ã«æ›´æ–°ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1261"/>
<source>&amp;Contents...</source>
<translation type="obsolete">ヘルプを表示(&amp;C)...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1261"/>
<source>F1</source>
<translation type="obsolete">F1</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1261"/>
<source>Show the online help contents</source>
<translation type="obsolete">オンラインヘルプを表示</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1261"/>
<source>&amp;VirtualBox Web Site...</source>
<translation type="obsolete">VirtualBox Webサイト(&amp;V)...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1261"/>
<source>Open the browser and go to the VirtualBox product web site</source>
<translation type="obsolete">Webブラウザã§VirtualBox製å“ã®Webサイトを開ã</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1261"/>
<source>&amp;About VirtualBox...</source>
<translation type="obsolete">VirtualBox ã«ã¤ã„ã¦(&amp;A)...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1261"/>
<source>Show a dialog with product information</source>
<translation type="obsolete">è£½å“æƒ…報ダイアログを表示</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1261"/>
<source>&amp;Reset All Warnings</source>
<translation type="obsolete">ã™ã¹ã¦ã®è­¦å‘Šã‚’リセット(&amp;R)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1261"/>
<source>Go back to showing all suppressed warnings and messages</source>
<translation type="obsolete">ã™ã¹ã¦ã®æŠ‘æ­¢ã•れãŸè­¦å‘Šã¨ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’å†åº¦è¡¨ç¤ºã•ã›ã‚‹</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1261"/>
<source>&amp;File</source>
<translation type="obsolete">ファイル(&amp;F)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1296"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1300"/>
<source>&amp;Help</source>
<translation>ヘルプ(&amp;H)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1296"/>
<source>&amp;Snapshots</source>
<translation type="obsolete">スナップショット(&amp;S)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1296"/>
<source>D&amp;escription</source>
<translation type="obsolete">説明(&amp;E)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1296"/>
<source>D&amp;escription *</source>
<translation type="obsolete">説明(&amp;E) *</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1381"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1386"/>
<source>S&amp;how</source>
<translation>表示(&amp;H)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1381"/>
<source>Show</source>
<translation type="obsolete">表示</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1393"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1398"/>
<source>Switch to the window of the selected virtual machine</source>
<translation>é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã«åˆ‡ã‚Šæ›¿ãˆ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1482"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1368"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1488"/>
<source>S&amp;tart</source>
<translation>èµ·å‹•(&amp;T)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1482"/>
<source>Start</source>
<translation type="obsolete">èµ·å‹•</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1484"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1380"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1490"/>
<source>Start the selected virtual machine</source>
<translation>é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã‚’èµ·å‹•</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1484"/>
<source>&lt;h3&gt;Welcome to VirtualBox!&lt;/h3&gt;&lt;p&gt;The left part of this window is a list of all virtual machines on your computer. The list is empty now because you haven&apos;t created any virtual machines yet.&lt;img src=welcome.png align=right/&gt;&lt;/p&gt;&lt;p&gt;In order to create a new virtual machine, press the &lt;b&gt;New&lt;/b&gt; button in the main tool bar located at the top of the window.&lt;/p&gt;&lt;p&gt;You can press the &lt;b&gt;%1&lt;/b&gt; key to get instant help, or visit &lt;a href=http://www.virtualbox.org&gt;www.virtualbox.org&lt;/a&gt; for the latest information and news.&lt;/p&gt;</source>
<translation type="obsolete">&lt;h3&gt;よã†ã“ãVirtualBoxã¸ï¼&lt;/h3&gt;&lt;p&gt;ã“ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã®å·¦å´ã«ã‚³ãƒ³ãƒ”ュータ上ã®ã™ã¹ã¦ã®ä»®æƒ³ãƒžã‚·ãƒ³ãŒãƒªã‚¹ãƒˆè¡¨ç¤ºã•れã¾ã™ã€‚ã¾ã ä»®æƒ³ãƒžã‚·ãƒ³ãŒä½œæˆã•れã¦ã„ãªã„ãŸã‚ã€ãƒªã‚¹ãƒˆã¯ç©ºã§ã™ã€‚&lt;img src=welcome.png align=right/&gt;&lt;/p&gt;&lt;p&gt;æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã‚’作æˆã™ã‚‹ã«ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ä¸Šéƒ¨ã«ã‚るメインツールãƒãƒ¼ã®&lt;b&gt;[æ–°è¦]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;キーã§ãƒ˜ãƒ«ãƒ—を表示ã§ãã¾ã™ã€‚ã¾ãŸã¯æœ€æ–°ã®æƒ…å ±ã¨ãƒ‹ãƒ¥ãƒ¼ã‚¹ã‚’å–å¾—ã™ã‚‹ãŸã‚ &lt;a href=http://www.virtualbox.org&gt;www.virtualbox.org&lt;/a&gt; を訪å•ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1295"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1299"/>
<source>&amp;Machine</source>
<translation>仮想マシン(&amp;M)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1263"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1267"/>
<source>Show &amp;Log...</source>
<translation>ログをå‚ç…§(&amp;L)...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1263"/>
<source>Show Log...</source>
<translation type="obsolete">ログをå‚ç…§...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1263"/>
<source>Ctrl+L</source>
<translation type="obsolete">Ctrl+L</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1267"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1271"/>
<source>Show the log files of the selected virtual machine</source>
<translation>é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®ãƒ­ã‚°ãƒ•ァイルをå‚ç…§ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1267"/>
<source>R&amp;egister VirtualBox...</source>
<translation type="obsolete">VirtualBox を登録(&amp;E)...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1267"/>
<source>Open VirtualBox registration form</source>
<translation type="obsolete">VirtualBox 登録フォームを開ã</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1267"/>
<source>R&amp;esume</source>
<translation type="obsolete">å†é–‹(&amp;E)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1267"/>
<source>Resume</source>
<translation type="obsolete">å†é–‹</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1267"/>
<source>Ctrl+P</source>
<translation type="obsolete">Ctrl+P</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1405"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1410"/>
<source>Resume the execution of the virtual machine</source>
<translation>仮想マシンã®å®Ÿè¡Œã‚’å†é–‹ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1254"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>&amp;Pause</source>
<translation>ä¸€æ™‚åœæ­¢(&amp;P)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1254"/>
<source>Pause</source>
<translation type="obsolete">ä¸€æ™‚åœæ­¢</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1414"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1260"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1419"/>
<source>Suspend the execution of the virtual machine</source>
<translation>仮想マシンã®å®Ÿè¡Œã‚’ä¸€æ™‚åœæ­¢ã™ã‚‹</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1270"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1274"/>
<source>Show in Finder</source>
<translation>Finderã«è¡¨ç¤º</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1271"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1275"/>
<source>Show the VirtualBox Machine Definition file in Finder.</source>
<translation>仮想マシン定義ファイルをFinderã«è¡¨ç¤ºã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1272"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1276"/>
<source>Create Alias on Desktop</source>
<translation>エイリアスをデスクトップã«ä½œæˆ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1273"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1277"/>
<source>Creates an Alias file to the VirtualBox Machine Definition file on your Desktop.</source>
<translation>仮想マシン定義ファイルã®ã‚¨ã‚¤ãƒªã‚¢ã‚¹ã‚’デスクトップã«ä½œæˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1275"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1279"/>
<source>Show in Explorer</source>
<translation>エクスプローラーã«è¡¨ç¤º</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1276"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1280"/>
<source>Show the VirtualBox Machine Definition file in Explorer.</source>
<translation>仮想マシン定義ファイルをエクスプローラーã«è¡¨ç¤ºã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1282"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1281"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1286"/>
<source>Create Shortcut on Desktop</source>
<translation>ショートカットをデスクトップã«ä½œæˆ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1283"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1282"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1287"/>
<source>Creates an Shortcut file to the VirtualBox Machine Definition file on your Desktop.</source>
<translation>仮想マシン定義ファイルã®ã‚·ãƒ§ãƒ¼ãƒˆã‚«ãƒƒãƒˆã‚’デスクトップã«ä½œæˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1280"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1284"/>
<source>Show in File Manager</source>
<translation>ファイルマãƒãƒ¼ã‚¸ãƒ£ã«è¡¨ç¤º</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1281"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1285"/>
<source>Show the VirtualBox Machine Definition file in the File Manager</source>
<translation>仮想マシン定義ファイルをファイルマãƒãƒ¼ã‚¸ãƒ£ã«è¡¨ç¤ºã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1291"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1295"/>
<source>&amp;File</source>
<comment>Mac OS X version</comment>
<translation>ファイル(&amp;F)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1293"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1297"/>
<source>&amp;File</source>
<comment>Non Mac OS X version</comment>
<translation>ファイル(&amp;F)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1454"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1459"/>
<source>&lt;h3&gt;Welcome to VirtualBox!&lt;/h3&gt;&lt;p&gt;The left part of this window is a list of all virtual machines on your computer. The list is empty now because you haven&apos;t created any virtual machines yet.&lt;img src=:/welcome.png align=right/&gt;&lt;/p&gt;&lt;p&gt;In order to create a new virtual machine, press the &lt;b&gt;New&lt;/b&gt; button in the main tool bar located at the top of the window.&lt;/p&gt;&lt;p&gt;You can press the &lt;b&gt;%1&lt;/b&gt; key to get instant help, or visit &lt;a href=http://www.virtualbox.org&gt;www.virtualbox.org&lt;/a&gt; for the latest information and news.&lt;/p&gt;</source>
<translation>&lt;h3&gt;よã†ã“ãVirtualBoxã¸ï¼&lt;/h3&gt;&lt;p&gt;ã“ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã®å·¦å´ã«ã‚³ãƒ³ãƒ”ュータ上ã®ã™ã¹ã¦ã®ä»®æƒ³ãƒžã‚·ãƒ³ãŒãƒªã‚¹ãƒˆè¡¨ç¤ºã•れã¾ã™ã€‚ã¾ã ä»®æƒ³ãƒžã‚·ãƒ³ãŒä½œæˆã•れã¦ã„ãªã„ãŸã‚ã€ãƒªã‚¹ãƒˆã¯ç©ºã§ã™ã€‚&lt;img src=:/welcome.png align=right/&gt;&lt;/p&gt;&lt;p&gt;æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã‚’作æˆã™ã‚‹ã«ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ä¸Šéƒ¨ã«ã‚るメインツールãƒãƒ¼ã®&lt;b&gt;[æ–°è¦]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;キーã§ãƒ˜ãƒ«ãƒ—を表示ã§ãã¾ã™ã€‚ã¾ãŸã¯æœ€æ–°ã®æƒ…å ±ã¨ãƒ‹ãƒ¥ãƒ¼ã‚¹ã‚’å–å¾—ã™ã‚‹ãŸã‚ &lt;a href=http://www.virtualbox.org&gt;www.virtualbox.org&lt;/a&gt; を訪å•ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1671"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1677"/>
<source>Show Toolbar</source>
<translation>ツールãƒãƒ¼ã‚’表示</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1675"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1681"/>
<source>Show Statusbar</source>
<translation>ステータスãƒãƒ¼ã‚’表示</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1205"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1204"/>
<source>&amp;Virtual Media Manager...</source>
<translation>仮想メディアマãƒãƒ¼ã‚¸ãƒ£(&amp;V)...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="652"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="661"/>
<source>Select a virtual machine file</source>
<translation>ä»®æƒ³ãƒžã‚·ãƒ³ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="656"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="665"/>
<source>Virtual machine files (%1)</source>
<translation>仮想マシンファイル(%1)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1190"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1189"/>
<source>Manager</source>
<comment>Note: main window title which is pretended by the product name.</comment>
<translation>マãƒãƒ¼ã‚¸ãƒ£ãƒ¼</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1207"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1206"/>
<source>Display the Virtual Media Manager dialog</source>
<translation>仮想メディアマãƒãƒ¼ã‚¸ãƒ£ ダイアログを表示</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1231"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1230"/>
<source>&amp;Add...</source>
<translation>追加(&amp;A)...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1233"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1232"/>
<source>Add an existing virtual machine</source>
<translation>既存ã®ä»®æƒ³ãƒžã‚·ãƒ³ã‚’追加</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1241"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1240"/>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1242"/>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1244"/>
<source>&amp;Remove</source>
<translation>除去(&amp;R)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1243"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1246"/>
<source>Remove the selected virtual machine</source>
<translation>é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã‚’除去</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1264"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1251"/>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1268"/>
<source>Log</source>
<comment>icon text</comment>
<translation>ログ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1264"/>
<source>Sun VirtualBox</source>
<translation type="obsolete">Sun VirtualBox</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1209"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1208"/>
<source>&amp;Import Appliance...</source>
<translation>仮想アプライアンスã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ(&amp;I)...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1211"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1210"/>
<source>Import an appliance into VirtualBox</source>
<translation>仮想アプライアンスをVirtualBoxã«ã‚¤ãƒ³ãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1213"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1212"/>
<source>&amp;Export Appliance...</source>
<translation>仮想アプライアンスã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ(&amp;E)...</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1215"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1214"/>
<source>Export one or more VirtualBox virtual machines as an appliance</source>
<translation>VirtualBoxã®ä»®æƒ³ãƒžã‚·ãƒ³ã‚’仮想アプライアンスã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
+ <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1262"/>
<source>Re&amp;fresh</source>
<translation>æœ€æ–°ã®æƒ…å ±ã«æ›´æ–°(&amp;F)</translation>
</message>
@@ -13294,27 +13180,22 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxSettingsDialog</name>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>&lt;i&gt;Select a settings category from the list on the left-hand side and move the mouse over a settings item to get more information&lt;/i&gt;.</source>
<translation type="obsolete">&lt;i&gt;å·¦å´ã®ãƒªã‚¹ãƒˆã‹ã‚‰è¨­å®šã®ã‚«ãƒ†ã‚´ãƒªã‚’é¸æŠžã—ã€è¨­å®šé …目をマウスオーãƒãƒ¼ã—ã¦è©³ç´°ãªæƒ…報をå‚ç…§ã—ã¦ãã ã•ã„&lt;i&gt;。</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Invalid settings detected</source>
<translation type="obsolete">無効ãªè¨­å®šãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Settings</source>
<translation type="obsolete">設定</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Non-optimal settings detected</source>
<translation type="obsolete">最é©åŒ–ã•れã¦ã„ãªã„設定ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>On the &lt;b&gt;%1&lt;/b&gt; page, %2</source>
<translation type="obsolete">&lt;b&gt;%1&lt;/b&gt;ページ:%2</translation>
</message>
@@ -13322,22 +13203,18 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxSharedFoldersSettings</name>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Name</source>
<translation type="obsolete">åå‰</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Path</source>
<translation type="obsolete">パス</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Shared &amp;Folders</source>
<translation type="obsolete">共有フォルダ(&amp;F)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>&lt;qt&gt;Lists all shared folders accessible to this machine.
Use
&lt;tt&gt;net use x: \\vboxsvr\share&lt;/tt&gt;
@@ -13350,78 +13227,63 @@ DOS系ゲストOSã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å ´åˆã¯ &lt;tt&gt;net use x:¥¥vboxs
本機能を使用ã™ã‚‹ã«ã¯ Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Adds a new shared folder definition.</source>
<translation type="obsolete">æ–°è¦å…±æœ‰ãƒ•ォルダを追加ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Removes the selected shared folder definition.</source>
<translation type="obsolete">é¸æŠžã—ãŸå…±æœ‰ãƒ•ォルダã®è¨­å®šã‚’削除ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source> Machine Folders</source>
<translation type="obsolete">共有フォルダ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source> Transient Folders</source>
<translation type="obsolete">一時的ãªå…±æœ‰ãƒ•ォルダ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Edits the selected shared folder definition.</source>
<translation type="obsolete">é¸æŠžã—ãŸå…±æœ‰ãƒ•ォルダã®è¨­å®šã‚’編集ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>VBoxSharedFoldersSettings</source>
<comment>don&apos;t translate</comment>
<translation type="obsolete">VBoxSharedFoldersSettings</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Ins</source>
<translation type="obsolete">Ins</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Add a new shared folder (Ins)</source>
<translation type="obsolete">æ–°è¦å…±æœ‰ãƒ•ォルダを追加(Ins)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Del</source>
<translation type="obsolete">Del</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Remove the selected shared folder (Del)</source>
<translation type="obsolete">é¸æŠžã—ãŸå…±æœ‰ãƒ•ォルダを削除(Del)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Access</source>
<translation type="obsolete">アクセス権</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Ctrl+Space</source>
<translation type="obsolete">Ctrl+スペース</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Edit the selected shared folder (Ctrl+Space)</source>
<translation type="obsolete">é¸æŠžã—ãŸå…±æœ‰ãƒ•ォルダã®è¨­å®šã‚’編集(Ctrl+スペース)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Full</source>
<translation type="obsolete">完全</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Read-only</source>
<translation type="obsolete">読ã¿è¾¼ã¿å°‚用</translation>
</message>
@@ -13429,47 +13291,38 @@ DOS系ゲストOSã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å ´åˆã¯ &lt;tt&gt;net use x:¥¥vboxs
<context>
<name>VBoxSnapshotDetailsDlg</name>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>VBoxSnapshotDetailsDlg</source>
<translation type="obsolete">VBoxSnapshotDetailsDlg</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source> Snapshot Details </source>
<translation type="obsolete">スナップショット詳細</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>&amp;Name</source>
<translation type="obsolete">åå‰(&amp;N)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>&amp;Description</source>
<translation type="obsolete">説明(&amp;D)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>&amp;Machine Details</source>
<translation type="obsolete">仮想マシン詳細(&amp;M)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Help</source>
<translation type="obsolete">ヘルプ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>F1</source>
<translation type="obsolete">F1</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>&amp;OK</source>
<translation type="obsolete">OK(&amp;O)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSelectorWnd.cpp" line="1258"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
@@ -13479,7 +13332,6 @@ DOS系ゲストOSã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å ´åˆã¯ &lt;tt&gt;net use x:¥¥vboxs
<translation>%1 (%2)ã®è©³ç´°</translation>
</message>
<message>
- <location filename="../src/VBoxSnapshotDetailsDlg.cpp" line="130"/>
<source>Snapshot Details</source>
<translation type="obsolete">スナップショット詳細</translation>
</message>
@@ -13512,7 +13364,6 @@ DOS系ゲストOSã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å ´åˆã¯ &lt;tt&gt;net use x:¥¥vboxs
<context>
<name>VBoxSnapshotsWgt</name>
<message>
- <location filename="../src/VBoxSnapshotDetailsDlg.ui" line="120"/>
<source>[snapshot]</source>
<translation type="obsolete">[snapshot]</translation>
</message>
@@ -13522,233 +13373,224 @@ DOS系ゲストOSã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å ´åˆã¯ &lt;tt&gt;net use x:¥¥vboxs
<translation>VBoxSnapshotsWgt</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.ui" line="26"/>
<source>snapshotActionGroup</source>
<translation type="obsolete">snapshotActionGroup</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.ui" line="26"/>
<source>Discard Snapshot</source>
<translation type="obsolete">スナップショットを破棄</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.ui" line="26"/>
<source>&amp;Discard Snapshot</source>
<translation type="obsolete">スナップショットを破棄(&amp;D)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.ui" line="26"/>
<source>Ctrl+Shift+D</source>
<translation type="obsolete">Ctrl+Shift+D</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.ui" line="26"/>
<source>curStateActionGroup</source>
<translation type="obsolete">curStateActionGroup</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.ui" line="26"/>
<source>Take Snapshot</source>
<translation type="obsolete">スナップショット作æˆ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="739"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="452"/>
<source>Take &amp;Snapshot</source>
<translation>スナップショット作æˆ(&amp;S)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="739"/>
<source>Discard Current Snapshot and State</source>
<translation type="obsolete">最新ã®ã‚¹ãƒŠãƒƒãƒ—ショットã¨çŠ¶æ…‹ã‚’ç ´æ£„</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="739"/>
<source>D&amp;iscard Current Snapshot and State</source>
<translation type="obsolete">最新ã®ã‚¹ãƒŠãƒƒãƒ—ショットã¨çŠ¶æ…‹ã‚’ç ´æ£„(&amp;I)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="739"/>
<source>Show Details</source>
<translation type="obsolete">詳細を表示</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="738"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="451"/>
<source>S&amp;how Details</source>
<translation>詳細を表示(&amp;H)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="148"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="151"/>
<source>Current State (changed)</source>
<comment>Current State (Modified)</comment>
<translation>最新ã®çŠ¶æ…‹(変更)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="149"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="152"/>
<source>Current State</source>
<comment>Current State (Unmodified)</comment>
<translation>最新ã®çŠ¶æ…‹</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="151"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="154"/>
<source>The current state differs from the state stored in the current snapshot</source>
<translation>最新ã®çŠ¶æ…‹ã¯æœ€æ–°ã®ã‚¹ãƒŠãƒƒãƒ—ショットã«ä¿å­˜ã•れã¦ã„る状態ã¨ç•°ãªã‚Šã¾ã™</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="153"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="156"/>
<source>The current state is identical to the state stored in the current snapshot</source>
<translation>最新ã®çŠ¶æ…‹ã¯æœ€æ–°ã®ã‚¹ãƒŠãƒƒãƒ—ショットã«ä¿å­˜ã•れã¦ã„る状態ã¨åŒã˜ã§ã™</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="217"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="205"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="210"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="215"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="220"/>
<source> (%1 ago)</source>
<translation>(%1å‰)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="257"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="260"/>
<source> (current, </source>
<comment>Snapshot details</comment>
<translation>(最新,</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="260"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="263"/>
<source>online)</source>
<comment>Snapshot details</comment>
<translation>オンライン)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="261"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="264"/>
<source>offline)</source>
<comment>Snapshot details</comment>
<translation>オフライン)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="264"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="267"/>
<source>Taken at %1</source>
<comment>Snapshot (time)</comment>
<translation>ä½œæˆæ™‚刻 %1</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="266"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="269"/>
<source>Taken on %1</source>
<comment>Snapshot (date + time)</comment>
<translation>ä½œæˆæ—¥æ™‚ %1</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="270"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="273"/>
<source>%1 since %2</source>
<comment>Current State (time or date + time)</comment>
<translation>%2ã‹ã‚‰ã®çŠ¶æ…‹ %1</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="627"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="453"/>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="460"/>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="779"/>
<source>Snapshot %1</source>
<translation>スナップショット %1</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="627"/>
<source>Discard the selected snapshot of the virtual machine</source>
<translation type="obsolete">é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®ã‚¹ãƒŠãƒƒãƒ—ショットを破棄</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="627"/>
<source>Ctrl+Shift+S</source>
<translation type="obsolete">Ctrl+Shift+S</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="744"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="459"/>
<source>Take a snapshot of the current virtual machine state</source>
<translation>ç¾åœ¨ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®çŠ¶æ…‹ã®ã‚¹ãƒŠãƒƒãƒ—ショットを作æˆ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="744"/>
<source>Revert to Current Snapshot</source>
<translation type="obsolete">最新ã®ã‚¹ãƒŠãƒƒãƒ—ショットã®çŠ¶æ…‹ã«æˆ»ã™</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="744"/>
<source>&amp;Revert to Current Snapshot</source>
<translation type="obsolete">最新ã®ã‚¹ãƒŠãƒƒãƒ—ショットã®çŠ¶æ…‹ã«æˆ»ã™(&amp;R)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="744"/>
<source>Ctrl+Shift+R</source>
<translation type="obsolete">Ctrl+Shift+R</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="744"/>
<source>Restore the virtual machine state from the state stored in the current snapshot</source>
<translation type="obsolete">仮想マシンã®çŠ¶æ…‹ã‚’æœ€æ–°ã®ã‚¹ãƒŠãƒƒãƒ—ショットã«ä¿å­˜ã•れãŸçŠ¶æ…‹ã«å¾©å…ƒ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="744"/>
<source>Ctrl+Shift+B</source>
<translation type="obsolete">Ctrl+Shift+B</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="744"/>
<source>Discard the current snapshot and revert the machine to the state it had before the snapshot was taken</source>
<translation type="obsolete">最新ã®ã‚¹ãƒŠãƒƒãƒ—ショットを破棄ã—ã€ã‚¹ãƒŠãƒƒãƒ—ショットを作æˆã™ã‚‹å‰ã®çŠ¶æ…‹ã«æˆ»ã™</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="743"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="458"/>
<source>Show the details of the selected snapshot</source>
<translation>é¸æŠžã—ãŸã‚¹ãƒŠãƒƒãƒ—ショットã®è©³ç´°ã‚’表示</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="743"/>
<source>Ctrl+Space</source>
<translation type="obsolete">Ctrl+スペース</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="197"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="200"/>
<source> (%1)</source>
<translation> (%1)</translation>
</message>
<message numerus="yes">
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="197"/>
<source> (%n day(s) ago)</source>
<translation type="obsolete">
<numerusform> (%n æ—¥å‰)</numerusform>
</translation>
</message>
<message numerus="yes">
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="197"/>
<source> (%n hour(s) ago)</source>
<translation type="obsolete">
<numerusform> (%n 時間å‰)</numerusform>
</translation>
</message>
<message numerus="yes">
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="197"/>
<source> (%n minute(s) ago)</source>
<translation type="obsolete">
<numerusform> (%n 分å‰)</numerusform>
</translation>
</message>
<message numerus="yes">
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="197"/>
<source> (%n second(s) ago)</source>
<translation type="obsolete">
<numerusform> (%n ç§’å‰)</numerusform>
</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="736"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="449"/>
<source>&amp;Restore Snapshot</source>
<translation>スナップショットã«å¾©å…ƒ(&amp;R)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="737"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="450"/>
<source>&amp;Delete Snapshot</source>
<translation>スナップショットを削除(&amp;D)</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="741"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="456"/>
<source>Restore the selected snapshot of the virtual machine</source>
<translation>é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®ã‚¹ãƒŠãƒƒãƒ—ショットã«å¾©å…ƒ</translation>
</message>
<message>
- <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="742"/>
+ <location filename="../src/selector/VBoxSnapshotsWgt.cpp" line="457"/>
<source>Delete the selected snapshot of the virtual machine</source>
<translation>é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®ã‚¹ãƒŠãƒƒãƒ—ショットを削除</translation>
</message>
@@ -13756,17 +13598,16 @@ DOS系ゲストOSã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å ´åˆã¯ &lt;tt&gt;net use x:¥¥vboxs
<context>
<name>VBoxSwitchMenu</name>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="5504"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="5507"/>
<source>Disable</source>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="5504"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="5507"/>
<source>Enable</source>
<translation>有効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="5504"/>
<source>%1 %2</source>
<translation type="obsolete">%1 %2</translation>
</message>
@@ -13789,22 +13630,18 @@ DOS系ゲストOSã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å ´åˆã¯ &lt;tt&gt;net use x:¥¥vboxs
<translation>スナップショットã®èª¬æ˜Ž(&amp;D)</translation>
</message>
<message>
- <location filename="../src/VBoxTakeSnapshotDlg.ui" line="84"/>
<source>Help</source>
<translation type="obsolete">ヘルプ</translation>
</message>
<message>
- <location filename="../src/VBoxTakeSnapshotDlg.ui" line="84"/>
<source>F1</source>
<translation type="obsolete">F1</translation>
</message>
<message>
- <location filename="../src/VBoxTakeSnapshotDlg.ui" line="84"/>
<source>&amp;OK</source>
<translation type="obsolete">OK(&amp;O)</translation>
</message>
<message>
- <location filename="../src/VBoxTakeSnapshotDlg.ui" line="84"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
@@ -13847,27 +13684,22 @@ DOS系ゲストOSã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å ´åˆã¯ &lt;tt&gt;net use x:¥¥vboxs
<context>
<name>VBoxTrayIcon</name>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>Show Selector Window</source>
<translation type="obsolete">é¸æŠžã•れãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’表示</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>Show the selector window assigned to this menu</source>
<translation type="obsolete">ã“ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’表示</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>Hide Tray Icon</source>
<translation type="obsolete">トレイアイコンを隠ã™</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>Remove this icon from the system tray</source>
<translation type="obsolete">ã“ã®ã‚¢ã‚¤ã‚³ãƒ³ã‚’システムトレイã‹ã‚‰å–り除ã</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&amp;Other Machines...</source>
<comment>tray menu</comment>
<translation type="obsolete">ä»–ã®ä»®æƒ³ãƒžã‚·ãƒ³(&amp;O)...</translation>
@@ -13876,86 +13708,70 @@ DOS系ゲストOSã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å ´åˆã¯ &lt;tt&gt;net use x:¥¥vboxs
<context>
<name>VBoxUSBFilterSettings</name>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>VBoxUSBFilterSettings</source>
<comment>don&apos;t translate</comment>
<translation type="obsolete">VBoxUSBFilterSettings</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&amp;Name</source>
<translation type="obsolete">åå‰(&amp;N)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>Displays the filter name.</source>
<translation type="obsolete">フィルタåを表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&amp;Manufacturer</source>
<translation type="obsolete">メーカー(&amp;M)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>Pro&amp;duct</source>
<translation type="obsolete">製å“å(&amp;D)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&amp;Serial No.</source>
<translation type="obsolete">シリアル No.(&amp;S)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>R&amp;emote</source>
<translation type="obsolete">リモート(&amp;E)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&amp;Action</source>
<translation type="obsolete">動作(&amp;A)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&amp;Vendor ID</source>
<translation type="obsolete">ベンダーID(&amp;V)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&amp;Product ID</source>
<translation type="obsolete">プロダクトID(&amp;P)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&amp;Revision</source>
<translation type="obsolete">リビジョン(&amp;R)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>Por&amp;t</source>
<translation type="obsolete">ãƒãƒ¼ãƒˆ(&amp;T)</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>Any</source>
<comment>remote</comment>
<translation type="obsolete">ä»»æ„</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>Yes</source>
<comment>remote</comment>
<translation type="obsolete">ã¯ã„</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>No</source>
<comment>remote</comment>
<translation type="obsolete">ã„ã„ãˆ</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&lt;qt&gt;Defines the manufacturer filter as an
&lt;i&gt;exact match&lt;/i&gt; string. An empty string will match any
value.&lt;/qt&gt;</source>
@@ -13963,7 +13779,6 @@ value.&lt;/qt&gt;</source>
ç©ºã®æ–‡å­—列ã¯ã™ã¹ã¦ã®å€¤ã¨ä¸€è‡´ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&lt;qt&gt;Defines the product name filter as an
&lt;i&gt;exact match&lt;/i&gt; string. An empty string will match any
value.&lt;/qt&gt;</source>
@@ -13971,7 +13786,6 @@ value.&lt;/qt&gt;</source>
ç©ºã®æ–‡å­—列ã¯ã™ã¹ã¦ã®å€¤ã¨ä¸€è‡´ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&lt;qt&gt;Defines the serial number filter as an
&lt;i&gt;exact match&lt;/i&gt; string. An empty string will match any
value.&lt;/qt&gt;</source>
@@ -13979,7 +13793,6 @@ value.&lt;/qt&gt;</source>
ç©ºã®æ–‡å­—列ã¯ã™ã¹ã¦ã®å€¤ã¨ä¸€è‡´ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&lt;qt&gt;Defines whether this filter applies
to USB devices attached locally to the host computer (&lt;i&gt;No&lt;/i&gt;),
to a VRDP client&apos;s computer (&lt;i&gt;Yes&lt;/i&gt;),
@@ -13989,7 +13802,6 @@ or both (&lt;i&gt;Any&lt;/i&gt;).&lt;/qt&gt;</source>
両方((&lt;i&gt;ä»»æ„&lt;/i&gt;))。&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&lt;qt&gt;Defines an action performed by the host
computer when a matching device is attached: give it up to the host OS
(&lt;i&gt;Ignore&lt;/i&gt;) or grab it for later usage by virtual machines
@@ -13998,7 +13810,6 @@ computer when a matching device is attached: give it up to the host OS
ホストOSã«è­²ã‚‹(&lt;i&gt;無視&lt;/i&gt;) ã€ä»®æƒ³ãƒžã‚·ãƒ³ã§ä½¿ç”¨ã™ã‚‹ãŸã‚ã«æ•æ‰(&lt;i&gt;ä¿æŒ&lt;/i&gt;)。&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&lt;qt&gt;Defines the vendor ID filter. The
&lt;i&gt;exact match&lt;/i&gt; string format is &lt;tt&gt;XXXX&lt;/tt&gt; where
&lt;tt&gt;X&lt;/tt&gt; is a hexadecimal digit. An empty string will match any
@@ -14008,7 +13819,6 @@ value.&lt;/qt&gt;</source>
ç©ºã®æ–‡å­—列ã¯ã™ã¹ã¦ã®å€¤ã¨ä¸€è‡´ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&lt;qt&gt;Defines the product ID filter. The
&lt;i&gt;exact match&lt;/i&gt; string format is &lt;tt&gt;XXXX&lt;/tt&gt; where
&lt;tt&gt;X&lt;/tt&gt; is a hexadecimal digit. An empty string will match any
@@ -14018,7 +13828,6 @@ value.&lt;/qt&gt;</source>
ç©ºã®æ–‡å­—列ã¯ã™ã¹ã¦ã®å€¤ã¨ä¸€è‡´ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&lt;qt&gt;Defines the revision number filter. The
&lt;i&gt;exact match&lt;/i&gt; string format is &lt;tt&gt;IIFF&lt;/tt&gt; where
&lt;tt&gt;I&lt;/tt&gt; is a decimal digit of the integer part and &lt;tt&gt;F&lt;/tt&gt;
@@ -14030,7 +13839,6 @@ value.&lt;/qt&gt;</source>
ç©ºã®æ–‡å­—列ã¯ã™ã¹ã¦ã®å€¤ã¨ä¸€è‡´ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/widgets/VBoxLineTextEdit.cpp" line="81"/>
<source>&lt;qt&gt;Defines the host USB port filter as an
&lt;i&gt;exact match&lt;/i&gt; string. An empty string will match any
value.&lt;/qt&gt;</source>
@@ -14041,13 +13849,13 @@ value.&lt;/qt&gt;</source>
<context>
<name>VBoxUSBMenu</name>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="5434"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="5437"/>
<source>&lt;no devices available&gt;</source>
<comment>USB devices</comment>
<translation>&lt;利用ã§ãるデãƒã‚¤ã‚¹ãŒã‚りã¾ã›ã‚“&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="5436"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="5439"/>
<source>No supported devices connected to the host PC</source>
<comment>USB device tooltip</comment>
<translation>ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã«æŽ¥ç¶šã•れãŸãƒ‡ãƒã‚¤ã‚¹ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“</translation>
@@ -14056,124 +13864,121 @@ value.&lt;/qt&gt;</source>
<context>
<name>VBoxUpdateDlg</name>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="79"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="193"/>
<source>1 day</source>
<translation>1æ—¥</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="80"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="194"/>
<source>2 days</source>
<translation>2æ—¥</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="81"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="195"/>
<source>3 days</source>
<translation>3æ—¥</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="82"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="196"/>
<source>4 days</source>
<translation>4æ—¥</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="83"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="197"/>
<source>5 days</source>
<translation>5æ—¥</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="84"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="198"/>
<source>6 days</source>
<translation>6æ—¥</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="87"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="201"/>
<source>1 week</source>
<translation>1週間</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="88"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="202"/>
<source>2 weeks</source>
<translation>2週間</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="89"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="203"/>
<source>3 weeks</source>
<translation>3週間</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="92"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="206"/>
<source>1 month</source>
<translation>1月</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="141"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="255"/>
<source>Never</source>
<translation>確èªã—ãªã„</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="141"/>
<source>Connection timed out.</source>
<translation type="obsolete">接続ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã«ãªã‚Šã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="141"/>
<source>Could not locate the latest version list on the server (response: %1).</source>
<translation type="obsolete">サーãƒãƒ¼ä¸Šã«æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ(応答: %1)。</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="291"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="416"/>
<source>Chec&amp;k</source>
<translation>確èª(&amp;K)</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="295"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="420"/>
<source>&amp;Close</source>
<translation>é–‰ã˜ã‚‹(&amp;C)</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="288"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="413"/>
<source>VirtualBox Update Wizard</source>
<translation>VirtualBox アップデート ウィザード</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="290"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="415"/>
<source>Check for Updates</source>
<translation>アップデートを確èª</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="290"/>
<source>&lt;p&gt;This wizard will connect to the VirtualBox web-site and check if a newer version of VirtualBox is available.&lt;/p&gt;
&lt;p&gt;Use the &lt;b&gt;Check&lt;/b&gt; button to check for a new version now or the &lt;b&gt;Cancel&lt;/b&gt; button if you do not want to perform this check.&lt;/p&gt;
&lt;p&gt;You can run this wizard at any time by choosing &lt;b&gt;Check for Updates...&lt;/b&gt; from the &lt;b&gt;Help&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ã€VirtualBox Webã‚µã‚¤ãƒˆã«æŽ¥ç¶šã—ã¦ã€VirtualBoxã®æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã‹ã©ã†ã‹ç¢ºèªã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;&lt;b&gt;[確èª]&lt;/b&gt;ボタンをクリックã—ã¦æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’今ã™ã確èªã—ã¦ãã ã•ã„。確èªã—ãªã„å ´åˆã¯&lt;b&gt;[キャンセル]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯&lt;b&gt;[ヘルプ]&lt;/b&gt;メニューã‹ã‚‰&lt;b&gt;[アップデートを確èª...]&lt;/b&gt;ã‚’é¸ã¶ã“ã¨ã§ã€ã„ã¤ã§ã‚‚実行ã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="292"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="417"/>
<source>Cancel</source>
<translation>キャンセル</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="294"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="419"/>
<source>Summary</source>
<translation>概è¦</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="306"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="431"/>
<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>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="312"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="437"/>
<source>&lt;p&gt;Unable to obtain the new version information due to the following network 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/VBoxUpdateDlg.cpp" line="315"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="440"/>
<source>You are already running the most recent version of VirtualBox.</source>
<translation>最新ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®VirtualBoxãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã™ã€‚ 後ã§ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç¢ºèªã‚’行ã£ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="297"/>
+ <location filename="../src/VBoxUpdateDlg.cpp" line="422"/>
<source>&lt;p&gt;This wizard will connect to the VirtualBox web-site and check if a newer version of VirtualBox is available.&lt;/p&gt;&lt;p&gt;Use the &lt;b&gt;Check&lt;/b&gt; button to check for a new version now or the &lt;b&gt;Cancel&lt;/b&gt; button if you do not want to perform this check.&lt;/p&gt;&lt;p&gt;You can run this wizard at any time by choosing &lt;b&gt;Check for Updates...&lt;/b&gt; from the &lt;b&gt;Help&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation>&lt;p&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ã€VirtualBox Webã‚µã‚¤ãƒˆã«æŽ¥ç¶šã—ã¦ã€VirtualBoxã®æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã‹ã©ã†ã‹ç¢ºèªã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;&lt;b&gt;[確èª]&lt;/b&gt;ボタンをクリックã—ã¦æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’今ã™ã確èªã—ã¦ãã ã•ã„。確èªã—ãªã„å ´åˆã¯&lt;b&gt;[キャンセル]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯&lt;b&gt;[ヘルプ]&lt;/b&gt;メニューã‹ã‚‰&lt;b&gt;[アップデートを確èª...]&lt;/b&gt;ã‚’é¸ã¶ã“ã¨ã§ã€ã„ã¤ã§ã‚‚実行ã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
@@ -14181,22 +13986,18 @@ value.&lt;/qt&gt;</source>
<context>
<name>VBoxVMDescriptionPage</name>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="297"/>
<source>No description. Press the Edit button below to add it.</source>
<translation type="obsolete">説明ãŒã‚りã¾ã›ã‚“。[編集]ボタンをクリックã—ã¦è¿½åŠ ã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="297"/>
<source>Edit</source>
<translation type="obsolete">編集</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="297"/>
<source>Edit (Ctrl+E)</source>
<translation type="obsolete">編集(Ctrl+E)</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="297"/>
<source>Ctrl+E</source>
<translation type="obsolete">Ctrl+E</translation>
</message>
@@ -14204,7 +14005,6 @@ value.&lt;/qt&gt;</source>
<context>
<name>VBoxVMDetailsView</name>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="297"/>
<source>The selected virtual machine is &lt;i&gt;inaccessible&lt;/i&gt;. Please inspect the error message shown below and press the &lt;b&gt;Refresh&lt;/b&gt; button if you want to repeat the accessibility check:</source>
<translation type="obsolete">é¸æŠžã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。アクセスå¯å¦ã‚’å†ç¢ºèªã™ã‚‹ã«ã¯ä»¥ä¸‹ã«ç¤ºã•れãŸã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’調査ã—ã¦&lt;b&gt;[æœ€æ–°ã®æƒ…å ±ã«æ›´æ–°]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„:</translation>
</message>
@@ -14212,12 +14012,10 @@ value.&lt;/qt&gt;</source>
<context>
<name>VBoxVMInformationDlg</name>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="297"/>
<source>Session Information Dialog</source>
<translation type="obsolete">セッション情報ダイアログ</translation>
</message>
<message>
- <location filename="../src/VBoxUpdateDlg.cpp" line="297"/>
<source>&amp;Close</source>
<translation type="obsolete">é–‰ã˜ã‚‹(&amp;C)</translation>
</message>
@@ -14227,16 +14025,19 @@ value.&lt;/qt&gt;</source>
<translation>%1 - セッション情報</translation>
</message>
<message>
+ <location filename="../src/VBoxVMInformationDlg.ui" line="37"/>
<location filename="../src/VBoxVMInformationDlg.cpp" line="163"/>
<source>&amp;Details</source>
<translation>詳細(&amp;D)</translation>
</message>
<message>
+ <location filename="../src/VBoxVMInformationDlg.ui" line="72"/>
<location filename="../src/VBoxVMInformationDlg.cpp" line="164"/>
<source>&amp;Runtime</source>
<translation>ランタイム(&amp;R)</translation>
</message>
<message>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="187"/>
<location filename="../src/VBoxVMInformationDlg.cpp" line="224"/>
<source>DMA Transfers</source>
<translation>DMA 転é€</translation>
@@ -14247,11 +14048,15 @@ value.&lt;/qt&gt;</source>
<translation>PIO 転é€</translation>
</message>
<message>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="191"/>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="226"/>
<location filename="../src/VBoxVMInformationDlg.cpp" line="253"/>
<source>Data Read</source>
<translation>データ読ã¿è¾¼ã¿</translation>
</message>
<message>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="193"/>
+ <location filename="../src/VBoxVMInformationDlg.cpp" line="228"/>
<location filename="../src/VBoxVMInformationDlg.cpp" line="255"/>
<source>Data Written</source>
<translation>データ書ãè¾¼ã¿</translation>
@@ -14283,17 +14088,14 @@ value.&lt;/qt&gt;</source>
<translation>ç”»é¢è§£åƒåº¦</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="491"/>
<source>CD/DVD-ROM Statistics</source>
<translation type="obsolete">CD/DVD-ROM 統計</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="491"/>
<source>Network Adapter Statistics</source>
<translation type="obsolete">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタ統計</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="491"/>
<source>Version %1.%2</source>
<comment>guest additions</comment>
<translation type="obsolete">ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %1.%2</translation>
@@ -14321,12 +14123,10 @@ value.&lt;/qt&gt;</source>
<translation>ゲストOSã®ã‚¿ã‚¤ãƒ—</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="495"/>
<source>Hard Disk Statistics</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯çµ±è¨ˆ</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="495"/>
<source>No Hard Disks</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãªã—</translation>
</message>
@@ -14336,35 +14136,29 @@ value.&lt;/qt&gt;</source>
<translation>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタãªã—</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="602"/>
<source>Enabled</source>
<comment>nested paging</comment>
<translation type="obsolete">有効</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="602"/>
<source>Disabled</source>
<comment>nested paging</comment>
<translation type="obsolete">無効</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="602"/>
<source>Nested Paging</source>
<comment>details report</comment>
<translation type="obsolete">ãƒã‚¹ãƒ†ãƒƒãƒ‰ãƒšãƒ¼ã‚¸ãƒ³ã‚°</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="602"/>
<source>Nested Paging</source>
<translation type="obsolete">ãƒã‚¹ãƒ†ãƒƒãƒ‰ãƒšãƒ¼ã‚¸ãƒ³ã‚°</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="602"/>
<source>Enabled</source>
<translation type="obsolete">有効</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="602"/>
<source>Disabled</source>
<translation type="obsolete">無効</translation>
</message>
@@ -14374,7 +14168,6 @@ value.&lt;/qt&gt;</source>
<translation>VBoxVMInformationDlg</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.ui" line="26"/>
<source>Not Available</source>
<comment>details report (VRDP server port)</comment>
<translation type="obsolete">利用ä¸å¯</translation>
@@ -14398,19 +14191,16 @@ value.&lt;/qt&gt;</source>
<context>
<name>VBoxVMListBox</name>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="586"/>
<source>&lt;nobr&gt;%1&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;%2 since %3&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Session %4&lt;/nobr&gt;</source>
<comment>VM tooltip (name, last state change, session state)</comment>
<translation type="obsolete">&lt;nobr&gt;%1&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;%3ã‹ã‚‰ã®çŠ¶æ…‹ %2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;セッション %4&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="586"/>
<source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;Inaccessible since %2&lt;/nobr&gt;</source>
<comment>Inaccessible VM tooltip (name, last state change)</comment>
<translation type="obsolete">&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;%2ã‹ã‚‰ã®çŠ¶æ…‹ アクセスã§ãã¾ã›ã‚“&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMInformationDlg.cpp" line="586"/>
<source>Inaccessible</source>
<translation type="obsolete">アクセスã§ãã¾ã›ã‚“</translation>
</message>
@@ -14448,12 +14238,10 @@ value.&lt;/qt&gt;</source>
<translation>åå‰ã‚’ã¤ã‘ã¦VirtualBox ログをä¿å­˜</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="247"/>
<source>Help</source>
<translation type="obsolete">ヘルプ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="247"/>
<source>F1</source>
<translation type="obsolete">F1</translation>
</message>
@@ -14471,147 +14259,118 @@ value.&lt;/qt&gt;</source>
<context>
<name>VBoxVMNetworkSettings</name>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>VBoxVMNetworkSettings</source>
<translation type="obsolete">VBoxVMNetworkSettings</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Enable Network Adapter</source>
<translation type="obsolete">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アダプタを有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Attached to</source>
<translation type="obsolete">割り当ã¦(&amp;A)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;MAC Address</source>
<translation type="obsolete">MACアドレス(&amp;M)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Generate</source>
<translation type="obsolete">生æˆ(&amp;G)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Generates a new random MAC address.</source>
<translation type="obsolete">MACアドレスをランダムã«ç”Ÿæˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Ca&amp;ble Connected</source>
<translation type="obsolete">接続(&amp;B)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Host Interface Settings</source>
<translation type="obsolete">ホスト インターフェースã®è¨­å®š</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Interface Name</source>
<translation type="obsolete">インターフェースå(&amp;I)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;File Descriptor</source>
<translation type="obsolete">ファイル識別å­(&amp;F)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Setup Application</source>
<translation type="obsolete">設定アプリケーション(&amp;S)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Select</source>
<translation type="obsolete">é¸æŠž</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Terminate Application</source>
<translation type="obsolete">終了アプリケーション(&amp;T)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Select TAP setup application</source>
<translation type="obsolete">TAPè¨­å®šã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Select TAP terminate application</source>
<translation type="obsolete">TAPçµ‚äº†ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, plugs this virtual network adapter into the virtual machine.</source>
<translation type="obsolete">仮想ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ ã‚¢ãƒ€ãƒ—ã‚¿ã‚’ä»®æƒ³ãƒžã‚·ãƒ³ã«æŽ¥ç¶šã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Controls how this virtual adapter is attached to the real network of the Host OS.</source>
<translation type="obsolete">仮想アダプタをホストOSã®å®Ÿéš›ã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã«å‰²ã‚Šå½“ã¦ã‚‹æ–¹å¼ã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Indicates whether the virtual network cable is plugged in on machine startup or not.</source>
<translation type="obsolete">仮想マシンã®èµ·å‹•時ã«ä»®æƒ³ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚±ãƒ¼ãƒ–ãƒ«ãŒæŽ¥ç¶šã•れるã‹ã©ã†ã‹ã‚’示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the name of the host interface selected for this adapter.</source>
<translation type="obsolete">ã“ã®ã‚¢ãƒ€ãƒ—タ用ã«é¸æŠžã—ãŸãƒ›ã‚¹ãƒˆ インターフェースåを表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the TAP interface name.</source>
<translation type="obsolete">TAPインターフェースåを表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the command executed to set up the TAP interface.</source>
<translation type="obsolete">TAPインターフェース設定時ã«å®Ÿè¡Œã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã‚’表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Selects the setup application.</source>
<translation type="obsolete">è¨­å®šã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’é¸æŠžã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the command executed to terminate the TAP interface.</source>
<translation type="obsolete">TAPインターフェース終了時ã«å®Ÿè¡Œã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã‚’表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Selects the terminate application.</source>
<translation type="obsolete">çµ‚äº†ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’é¸æŠžã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the MAC address of this adapter. It contains exactly 12 characters chosen from {0-9,A-F}. Note that the second character must be an even digit.</source>
<translation type="obsolete">ã“ã®ã‚¢ãƒ€ãƒ—ã‚¿ã®MACアドレスを表示ã—ã¾ã™ã€‚MACアドレスã¯{0-9,A-F}ã‹ã‚‰é¸æŠžã•れãŸ12æ–‡å­—ã§æ§‹æˆã•れã¾ã™ã€‚注:2ç•ªç›®ã®æ–‡å­—ã¯å¶æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Network Name</source>
<translation type="obsolete">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯å(&amp;N)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Adapter &amp;Type</source>
<translation type="obsolete">アダプタ タイプ(&amp;T)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Selects the type of the virtual network adapter. Depending on this value, VirtualBox will provide different network hardware to the virtual machine.</source>
<translation type="obsolete">仮想ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¢ãƒ€ãƒ—ã‚¿ã®ã‚¿ã‚¤ãƒ—ã‚’é¸æŠžã—ã¾ã™ã€‚ ã“ã®å€¤ã«ã‚ˆã‚Šã€VirtualBoxã¯ç•°ãªã£ãŸãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã‚’ä»®æƒ³ãƒžã‚·ãƒ³ã«æä¾›ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the name of the internal network selected for this adapter.</source>
<translation type="obsolete">ã“ã®ã‚¢ãƒ€ãƒ—タ用ã«é¸æŠžã—ãŸå†…部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯åを表示ã—ã¾ã™ã€‚</translation>
</message>
@@ -14619,57 +14378,46 @@ value.&lt;/qt&gt;</source>
<context>
<name>VBoxVMParallelPortSettings</name>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>VBoxVMParallelPortSettings</source>
<translation type="obsolete">VBoxVMParallelPortSettings</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Enable Parallel Port</source>
<translation type="obsolete">パラレルãƒãƒ¼ãƒˆã‚’有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, enables the given parallel port of the virtual machine.</source>
<translation type="obsolete">仮想マシンã®ãƒ‘ラレルãƒãƒ¼ãƒˆã‚’有効ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Port &amp;Number</source>
<translation type="obsolete">ãƒãƒ¼ãƒˆç•ªå·(&amp;N)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the parallel port number. You can choose one of the standard parallel ports or select &lt;b&gt;User-defined&lt;/b&gt; and specify port parameters manually.</source>
<translation type="obsolete">パラレルãƒãƒ¼ãƒˆç•ªå·ã‚’表示ã—ã¾ã™ã€‚ 標準ã®ãƒ‘ラレルãƒãƒ¼ãƒˆã‹&lt;b&gt;[ユーザー定義]&lt;/b&gt;ã‚’é¸æŠžã—ã€æ‰‹å‹•ã§ãƒãƒ¼ãƒˆãƒ‘ラメタを指定ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;IRQ</source>
<translation type="obsolete">IRQ(&amp;I)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the IRQ number of this parallel port. Valid values are integer numbers in range from &lt;tt&gt;0&lt;/tt&gt; to &lt;tt&gt;255&lt;/tt&gt;. Values greater than &lt;tt&gt;15&lt;/tt&gt; may only be used if the &lt;b&gt;IO APIC&lt;/b&gt; is enabled for this virtual machine.</source>
<translation type="obsolete">ã“ã®ãƒ‘ラレルãƒãƒ¼ãƒˆã®IRQ番å·ã‚’表示ã—ã¾ã™ã€‚有効値ã¯&lt;tt&gt;0&lt;/tt&gt;ã‹ã‚‰&lt;tt&gt;255&lt;/tt&gt;ã¾ã§ã®ç¯„å›²ã®æ•´æ•°ã§ã™ã€‚&lt;tt&gt;15&lt;/tt&gt;以上ã®å€¤ã¯ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã§&lt;b&gt;IO APIC&lt;/b&gt;ãŒæœ‰åйãªã¨ã使用ã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>I/O Po&amp;rt</source>
<translation type="obsolete">I/Oãƒãƒ¼ãƒˆ(&amp;R)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the base I/O port address of this parallel port. This should be a whole number between &lt;tt&gt;0&lt;/tt&gt; and &lt;tt&gt;0xFFFF&lt;/tt&gt;.</source>
<translation type="obsolete">ã“ã®ãƒ‘ラレルãƒãƒ¼ãƒˆã®ãƒ™ãƒ¼ã‚¹I/Oãƒãƒ¼ãƒˆã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’表示ã—ã¾ã™ã€‚ 有効値ã¯&lt;tt&gt;0&lt;/tt&gt;ã‹ã‚‰&lt;tt&gt;0xFFFF&lt;/tt&gt;ã®ç¯„å›²ã®æ•´æ•°ã§ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Port &amp;Path</source>
<translation type="obsolete">ãƒãƒ¼ãƒˆ パス(&amp;P)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the host parallel device name.</source>
<translation type="obsolete">ホストã®ãƒ‘ラレル デãƒã‚¤ã‚¹åを表示ã—ã¾ã™ã€‚</translation>
</message>
@@ -14677,77 +14425,62 @@ value.&lt;/qt&gt;</source>
<context>
<name>VBoxVMSerialPortSettings</name>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>VBoxVMSerialPortSettings</source>
<translation type="obsolete">VBoxVMSerialPortSettings</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Enable Serial Port</source>
<translation type="obsolete">シリアルãƒãƒ¼ãƒˆã‚’有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, enables the given serial port of the virtual machine.</source>
<translation type="obsolete">仮想マシンã®ã‚·ãƒªã‚¢ãƒ«ãƒãƒ¼ãƒˆã‚’有効ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Port &amp;Number</source>
<translation type="obsolete">ãƒãƒ¼ãƒˆç•ªå·(&amp;N)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the serial port number. You can choose one of the standard serial ports or select &lt;b&gt;User-defined&lt;/b&gt; and specify port parameters manually.</source>
<translation type="obsolete">シリアルãƒãƒ¼ãƒˆç•ªå·ã‚’表示ã—ã¾ã™ã€‚ 標準ã®ã‚·ãƒªã‚¢ãƒ«ãƒãƒ¼ãƒˆã‹&lt;b&gt;[ユーザー定義]&lt;/b&gt;ã‚’é¸æŠžã—ã€æ‰‹å‹•ã§ãƒãƒ¼ãƒˆãƒ‘ラメタを指定ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;IRQ</source>
<translation type="obsolete">IRQ(&amp;I)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the IRQ number of this serial port. Valid values are integer numbers in range from &lt;tt&gt;0&lt;/tt&gt; to &lt;tt&gt;255&lt;/tt&gt;. Values greater than &lt;tt&gt;15&lt;/tt&gt; may only be used if the &lt;b&gt;IO APIC&lt;/b&gt; is enabled for this virtual machine.</source>
<translation type="obsolete">ã“ã®ã‚·ãƒªã‚¢ãƒ«ãƒãƒ¼ãƒˆã®IRQ番å·ã‚’表示ã—ã¾ã™ã€‚有効値ã¯&lt;tt&gt;0&lt;/tt&gt;ã‹ã‚‰&lt;tt&gt;255&lt;/tt&gt;ã¾ã§ã®ç¯„å›²ã®æ•´æ•°ã§ã™ã€‚&lt;tt&gt;15&lt;/tt&gt;以上ã®å€¤ã¯ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã§&lt;b&gt;IO APIC&lt;/b&gt;ãŒæœ‰åйãªã¨ã使用ã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>I/O Po&amp;rt</source>
<translation type="obsolete">I/Oãƒãƒ¼ãƒˆ(&amp;R)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the base I/O port address of this serial port. This should be a whole number between &lt;tt&gt;0&lt;/tt&gt; and &lt;tt&gt;0xFFFF&lt;/tt&gt;.</source>
<translation type="obsolete">ã“ã®ã‚·ãƒªã‚¢ãƒ«ãƒãƒ¼ãƒˆã®ãƒ™ãƒ¼ã‚¹I/Oãƒãƒ¼ãƒˆã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’表示ã—ã¾ã™ã€‚ 有効値ã¯&lt;tt&gt;0&lt;/tt&gt;ã‹ã‚‰&lt;tt&gt;0xFFFF&lt;/tt&gt;ã®ç¯„å›²ã®æ•´æ•°ã§ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Port &amp;Mode</source>
<translation type="obsolete">ãƒãƒ¼ãƒˆ モード(&amp;M)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Controls the working mode of this serial port. If you select &lt;b&gt;Disconnected&lt;/b&gt;, the guest OS will detect the serial port but will not be able to operate it.</source>
<translation type="obsolete">ã“ã®ã‚·ãƒªã‚¢ãƒ«ãƒãƒ¼ãƒˆã®å‹•作モードを指定ã—ã¾ã™ã€‚ &lt;b&gt;[切断]&lt;/b&gt;ã‚’é¸æŠžã™ã‚‹ã¨ã€ã‚²ã‚¹ãƒˆOSã¯ã‚·ãƒªã‚¢ãƒ«ãƒãƒ¼ãƒˆã‚’検出ã—ã¾ã™ãŒã€ãれをæ“作ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Create Pipe</source>
<translation type="obsolete">パイプ作æˆ(&amp;C)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>If checked, the pipe specified in the &lt;b&gt;Port Path&lt;/b&gt; field will be created by the virtual machine when it starts. Otherwise, the virtual machine will assume that the pipe exists and try to use it.</source>
<translation type="obsolete">仮想マシンã®èµ·å‹•時㫠&lt;b&gt;[ãƒãƒ¼ãƒˆ パス]&lt;/b&gt;ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã§æŒ‡å®šã•れãŸãƒ‘イプãŒä½œæˆã•れã¾ã™ã€‚オフã®å ´åˆã€ä»®æƒ³ãƒžã‚·ãƒ³ã¯æ—¢å­˜ã®ãƒ‘イプを使用ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Port &amp;Path</source>
<translation type="obsolete">ãƒãƒ¼ãƒˆ パス(&amp;P)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the path to the serial port&apos;s pipe on the host when the port is working in &lt;b&gt;Host Pipe&lt;/b&gt; mode, or the host serial device name when the port is working in &lt;b&gt;Host Device&lt;/b&gt; mode.</source>
<translation type="obsolete">ãƒãƒ¼ãƒˆãŒ&lt;b&gt;[ホスト パイプ]&lt;/b&gt;モードã§å‹•作ã—ã¦ã„ã‚‹ã¨ãã€ã‚·ãƒªã‚¢ãƒ«ãƒãƒ¼ãƒˆã®ãƒ‘イプã®ãƒ‘スを表示ã—ã¾ã™ã€‚ãƒãƒ¼ãƒˆãŒ&lt;b&gt;[ホスト デãƒã‚¤ã‚¹]&lt;/b&gt;モードã§å‹•作ã—ã¦ã„ã‚‹ã¨ãã€ãƒ›ã‚¹ãƒˆ シリアル デãƒã‚¤ã‚¹åを表示ã—ã¾ã™ã€‚</translation>
</message>
@@ -14755,72 +14488,58 @@ value.&lt;/qt&gt;</source>
<context>
<name>VBoxVMSettingsCD</name>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Host CD/DVD drive is not selected</source>
<translation type="obsolete">ホスト CD/DVDドライブãŒé¸æŠžã•れã¦ã„ãªã„</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>CD/DVD image file is not selected</source>
<translation type="obsolete">CD/DVDイメージファイルãŒé¸æŠžã•れã¦ã„ãªã„</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, mounts the specified media to the CD/DVD drive of the virtual machine. Note that the CD/DVD drive is always connected to the Secondary Master IDE controller of the machine.</source>
<translation type="obsolete">指定ã—ãŸãƒ¡ãƒ‡ã‚£ã‚¢ã‚’仮想マシンã®CD/DVDドライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚注:CD/DVDドライブã¯å¸¸ã«ä»®æƒ³ãƒžã‚·ãƒ³ã®ã‚»ã‚«ãƒ³ãƒ€ãƒªIDE コントローラã®ãƒžã‚¹ã‚¿ãƒ¼ã‚¹ãƒ­ãƒƒãƒˆã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Mount CD/DVD Drive</source>
<translation type="obsolete">CD/DVD ドライブã®ãƒžã‚¦ãƒ³ãƒˆ(&amp;M)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Mounts the specified CD/DVD drive to the virtual CD/DVD drive.</source>
<translation type="obsolete">指定ã—ãŸCD/DVDドライブを仮想CD/DVDドライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Host CD/DVD &amp;Drive</source>
<translation type="obsolete">ホスト CD/DVDドライブ(&amp;D)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Lists host CD/DVD drives available to mount to the virtual machine.</source>
<translation type="obsolete">仮想マシンã«ãƒžã‚¦ãƒ³ãƒˆã™ã‚‹ãŸã‚ã«åˆ©ç”¨å¯èƒ½ãªãƒ›ã‚¹ãƒˆã®CD/DVDドライブをリスト表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, allows the guest to send ATAPI commands directly to the host drive which makes it possible to use CD/DVD writers connected to the host inside the VM. Note that writing audio CD inside the VM is not yet supported.</source>
<translation type="obsolete">ãƒ›ã‚¹ãƒˆã«æŽ¥ç¶šã•れãŸCD/DVDライターを使用å¯èƒ½ã«ã™ã‚‹ãŸã‚ã€ã‚²ã‚¹ãƒˆOSã®ATAPIコマンドを直接ホスト ドライブã«é€ã‚Šã¾ã™ã€‚注:仮想マシンã‹ã‚‰éŸ³æ¥½CDã¸ã®æ›¸ãè¾¼ã¿ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Enable &amp;Passthrough</source>
<translation type="obsolete">パススルーを有効化(&amp;P)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Mounts the specified CD/DVD image to the virtual CD/DVD drive.</source>
<translation type="obsolete">指定ã—ãŸCD/DVDイメージを仮想CD/DVDドライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;ISO Image File</source>
<translation type="obsolete">ISO イメージファイル(&amp;I)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the image file to mount to the virtual CD/DVD drive and allows to quickly select a different image.</source>
<translation type="obsolete">仮想CD/DVDドライブã«ãƒžã‚¦ãƒ³ãƒˆã•れãŸã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ァイルを表示ã—ã¾ã™ã€‚ã¾ãŸã€ä»–ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’ç´ æ—©ãé¸æŠžã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Invokes the Virtual Disk Manager to select a CD/DVD image to mount.</source>
<translation type="obsolete">仮想ディスクマãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•ã—ã€é¸æŠžã—ãŸCD/DVDイメージをマウントã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Invokes the Virtual Media Manager to select a CD/DVD image to mount.</source>
<translation type="obsolete">仮想メディアマãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•ã—ã€é¸æŠžã—ãŸCD/DVDイメージをマウントã—ã¾ã™ã€‚</translation>
</message>
@@ -14828,701 +14547,563 @@ value.&lt;/qt&gt;</source>
<context>
<name>VBoxVMSettingsDlg</name>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Category</source>
<translation type="obsolete">カテゴリ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>[id]</source>
<translation type="obsolete">[id]</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>[link]</source>
<translation type="obsolete">[link]</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>[name]</source>
<translation type="obsolete">[name]</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>VBoxVMSettingsDlg</source>
<translation type="obsolete">VBoxVMSettingsDlg</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&lt;i&gt;Select a settings category from the list on the left-hand side and move the mouse over a settings item to get more information&lt;i&gt;.</source>
<translation type="obsolete">&lt;i&gt;å·¦å´ã®ãƒªã‚¹ãƒˆã‹ã‚‰è¨­å®šã®ã‚«ãƒ†ã‚´ãƒªã‚’é¸æŠžã—ã€è¨­å®šé …目をマウスオーãƒãƒ¼ã—ã¦è©³ç´°ãªæƒ…報をå‚ç…§ã—ã¦ãã ã•ã„&lt;i&gt;。</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source> General </source>
<translation type="obsolete">一般</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source> Hard Disks </source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source> Floppy </source>
<translation type="obsolete">フロッピー</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source> CD/DVD-ROM </source>
<translation type="obsolete">CD/DVD-ROM</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source> Audio </source>
<translation type="obsolete">オーディオ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source> Network </source>
<translation type="obsolete">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source> USB </source>
<translation type="obsolete"> USB </translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source> Remote Display </source>
<translation type="obsolete">リモートディスプレイ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source> Shared Folders </source>
<translation type="obsolete">共有フォルダ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Identification</source>
<translation type="obsolete">ID(&amp;I)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Name</source>
<translation type="obsolete">åå‰(&amp;N)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the name of the virtual machine.</source>
<translation type="obsolete">仮想マシンã®åå‰ã‚’表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>OS &amp;Type</source>
<translation type="obsolete">OSタイプ(&amp;T)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Base &amp;Memory Size</source>
<translation type="obsolete">メインメモリã®ã‚µã‚¤ã‚º(&amp;M)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Controls the amount of memory provided to the virtual machine. If you assign too much, the machine might not start.</source>
<translation type="obsolete">仮想マシンã«å‰²ã‚Šå½“ã¦ã‚‹ãƒ¡ã‚¤ãƒ³ãƒ¡ãƒ¢ãƒªã®ã‚µã‚¤ã‚ºã‚’指定ã—ã¾ã™ã€‚割り当ã¦é‡ãŒå¤šã™ãŽã‚‹ã¨ä»®æƒ³ãƒžã‚·ãƒ³ã¯èµ·å‹•ã—ãªã„ã‹ã‚‚ã—れã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&lt;</source>
<translation type="obsolete">&lt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>=</source>
<translation type="obsolete">=</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&gt;</source>
<translation type="obsolete">&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>MB</source>
<translation type="obsolete">MB</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Video Memory Size</source>
<translation type="obsolete">ビデオメモリã®ã‚µã‚¤ã‚º(&amp;V)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Controls the amount of video memory provided to the virtual machine.</source>
<translation type="obsolete">仮想マシンã«å‰²ã‚Šå½“ã¦ã‚‹ãƒ“デオメモリã®ã‚µã‚¤ã‚ºã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Basic</source>
<translation type="obsolete">基本(&amp;B)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Select</source>
<translation type="obsolete">é¸æŠž</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Selects the snapshot folder path.</source>
<translation type="obsolete">スナップショットã®ä¿å­˜å…ˆãƒ•ォルダã®ãƒ‘ã‚¹ã‚’é¸æŠžã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Reset</source>
<translation type="obsolete">リセット</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Extended Features</source>
<translation type="obsolete">拡張機能</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Enable A&amp;CPI</source>
<translation type="obsolete">ACPIを有効化(&amp;C)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Enable IO A&amp;PIC</source>
<translation type="obsolete">IO APICを有効化(&amp;P)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Boo&amp;t Order</source>
<translation type="obsolete">èµ·å‹•é †åº(&amp;T)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Advanced</source>
<translation type="obsolete">高度(&amp;A)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Description</source>
<translation type="obsolete">コメント(&amp;D)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Mount Floppy Drive</source>
<translation type="obsolete">フロッピードライブã®ãƒžã‚¦ãƒ³ãƒˆ(&amp;M)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Host Floppy &amp;Drive</source>
<translation type="obsolete">ホスト フロッピードライブ(&amp;D)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Mounts the specified host Floppy drive to the virtual Floppy drive.</source>
<translation type="obsolete">指定ã—ãŸãƒ›ã‚¹ãƒˆ フロッピードライブを仮想フロッピードライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Image File</source>
<translation type="obsolete">イメージファイル(&amp;I)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Mounts the specified Floppy image to the virtual Floppy drive.</source>
<translation type="obsolete">指定ã—ãŸãƒ•ロッピーイメージを仮想フロッピードライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Mount CD/DVD Drive</source>
<translation type="obsolete">CD/DVD ドライブã®ãƒžã‚¦ãƒ³ãƒˆ(&amp;M)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Host CD/DVD &amp;Drive</source>
<translation type="obsolete">ホスト CD/DVDドライブ(&amp;D)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Mounts the specified CD/DVD drive to the virtual CD/DVD drive.</source>
<translation type="obsolete">指定ã—ãŸCD/DVDドライブを仮想CD/DVDドライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;ISO Image File</source>
<translation type="obsolete">ISO イメージファイル(&amp;I)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Mounts the specified CD/DVD image to the virtual CD/DVD drive.</source>
<translation type="obsolete">指定ã—ãŸCD/DVDイメージを仮想CD/DVDドライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Enable Audio</source>
<translation type="obsolete">オーディオを有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Host Audio &amp;Driver</source>
<translation type="obsolete">ホスト オーディオ ドライãƒ(&amp;D)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Enable &amp;USB Controller</source>
<translation type="obsolete">USB コントローラを有効化(&amp;U)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>USB Device &amp;Filters</source>
<translation type="obsolete">USB デãƒã‚¤ã‚¹ フィルタ(&amp;F)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Ins</source>
<translation type="obsolete">Ins</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Alt+Ins</source>
<translation type="obsolete">Alt+Ins</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Del</source>
<translation type="obsolete">Del</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Ctrl+Up</source>
<translation type="obsolete">Ctrl+Up</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Ctrl+Down</source>
<translation type="obsolete">Ctrl+Down</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Enable VRDP Server</source>
<translation type="obsolete">VRDPサーãƒã‚’有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Defines the VRDP authentication method.</source>
<translation type="obsolete">VRDPã®èªè¨¼æ–¹å¼ã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Specifies the timeout for guest authentication, in milliseconds.</source>
<translation type="obsolete">ゲストèªè¨¼ã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆå€¤ã‚’ミリ秒å˜ä½ã§æŒ‡å®šã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Help</source>
<translation type="obsolete">ヘルプ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>F1</source>
<translation type="obsolete">F1</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the dialog help.</source>
<translation type="obsolete">ダイアログã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Invalid settings detected</source>
<translation type="obsolete">無効ãªè¨­å®šãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;OK</source>
<translation type="obsolete">OK(&amp;O)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Accepts (saves) changes and closes the dialog.</source>
<translation type="obsolete">変更をä¿å­˜ã—ã¦ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‰ã˜ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Cancel</source>
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Cancels changes and closes the dialog.</source>
<translation type="obsolete">変更を破棄ã—ã¦ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‰ã˜ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, mounts the specified media to the CD/DVD drive of the virtual machine. Note that the CD/DVD drive is always connected to the Secondary Master IDE controller of the machine.</source>
<translation type="obsolete">指定ã—ãŸãƒ¡ãƒ‡ã‚£ã‚¢ã‚’仮想マシンã®CD/DVDドライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚注:CD/DVDドライブã¯å¸¸ã«ä»®æƒ³ãƒžã‚·ãƒ³ã®ã‚»ã‚«ãƒ³ãƒ€ãƒªIDE コントローラã®ãƒžã‚¹ã‚¿ãƒ¼ã‚¹ãƒ­ãƒƒãƒˆã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the image file to mount to the virtual CD/DVD drive and allows to quickly select a different image.</source>
<translation type="obsolete">仮想CD/DVDドライブã«ãƒžã‚¦ãƒ³ãƒˆã•れãŸã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ァイルを表示ã—ã¾ã™ã€‚ã¾ãŸã€ä»–ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’ç´ æ—©ãé¸æŠžã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, mounts the specified media to the Floppy drive of the virtual machine.</source>
<translation type="obsolete">指定ã—ãŸãƒ¡ãƒ‡ã‚£ã‚¢ã‚’仮想マシンã®ãƒ•ロッピードライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the image file to mount to the virtual Floppy drive and allows to quickly select a different image.</source>
<translation type="obsolete">仮想フロッピードライブã«ãƒžã‚¦ãƒ³ãƒˆã•れãŸã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ァイルを表示ã—ã¾ã™ã€‚ã¾ãŸã€ä»–ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’ç´ æ—©ãé¸æŠžã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, a virtual PCI audio card will be plugged into the virtual machine and will communicate with the host audio system using the specified driver.</source>
<translation type="obsolete">指定ã•れãŸãƒ‰ãƒ©ã‚¤ãƒã‚’使用ã—ã¦ãƒ›ã‚¹ãƒˆã®ã‚ªãƒ¼ãƒ‡ã‚£ã‚ªã‚«ãƒ¼ãƒ‰ã¨é€šä¿¡ã™ã‚‹ä»®æƒ³PCIã‚ªãƒ¼ãƒ‡ã‚£ã‚ªã‚«ãƒ¼ãƒ‰ã‚’ä»®æƒ³ãƒžã‚·ãƒ³ã«æŽ¥ç¶šã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, the VM will act as a Remote Desktop Protocol (RDP) server, allowing remote clients to connect and operate the VM (when it is running) using a standard RDP client.</source>
<translation type="obsolete">仮想マシンã®ãƒªãƒ¢ãƒ¼ãƒˆãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—プロトコル(RDP)ã‚µãƒ¼ãƒæ©Ÿèƒ½ã‚’有効ã«ã—ã¾ã™ã€‚ãƒªãƒ¢ãƒ¼ãƒˆã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆãŒæ¨™æº–çš„ãªRDPクライアントを使用ã—ã¦å®Ÿè¡Œä¸­ã®ä»®æƒ³ãƒžã‚·ãƒ³ã«æŽ¥ç¶šã—ã€æ“作ã™ã‚‹ã“ã¨ã‚’å¯èƒ½ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</source>
<translation type="obsolete">&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&lt;not attached&gt;</source>
<comment>hard disk</comment>
<translation type="obsolete">&lt;割り当ã¦ã‚‰ã‚Œã¦ã„ã¾ã›ã‚“&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source> - Settings</source>
<translation type="obsolete">- 設定</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>New Filter %1</source>
<comment>usb</comment>
<translation type="obsolete">æ–°è¦ãƒ•ィルタ %1</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Shared Clipboard</source>
<translation type="obsolete">クリップボードã®å…±æœ‰(&amp;S)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>S&amp;napshot Folder</source>
<translation type="obsolete">スナップショットã®ä¿å­˜å…ˆ(&amp;N)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the operating system type that you plan to install into this virtual machine (called a guest operating system).</source>
<translation type="obsolete">仮想マシンã§å®Ÿè¡Œã™ã‚‹OS(ゲストOSã¨å‘¼ã³ã¾ã™)ã®ã‚¿ã‚¤ãƒ—を表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&lt;qt&gt;When checked, the virtual machine will support
the Advanced Configuration and Power Management Interface (ACPI). &lt;b&gt;Note:&lt;/b&gt; don&apos;t disable
this feature after having installed a Windows guest operating system!&lt;/qt&gt;</source>
<translation type="obsolete">&lt;qt&gt;仮想マシンã§ACPI(Advanced Configuration and Power Management Interface)サãƒãƒ¼ãƒˆã‚’有効ã«ã—ã¾ã™ã€‚&lt;b&gt;注:&lt;/b&gt; Windows ゲストOSをインストールã—ãŸå¾Œã§æœ¬æ©Ÿèƒ½ã‚’無効ã«ã—ãªã„ã§ãã ã•ã„ï¼&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&lt;qt&gt;When checked, the virtual machine will support
the Input Output APIC (IO APIC), which may slightly decrease performance. &lt;b&gt;Note:&lt;/b&gt; don&apos;t disable
this feature after having installed a Windows guest operating system!&lt;/qt&gt;</source>
<translation type="obsolete">&lt;qt&gt;仮想マシンã§IO APIC(Input Output APIC)サãƒãƒ¼ãƒˆã‚’有効ã«ã—ã¾ã™ã€‚ã“れã¯ä»®æƒ³ãƒžã‚·ãƒ³ã®æ€§èƒ½ã‚’ã‚ãšã‹ã«ä½Žä¸‹ã•ã›ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。&lt;b&gt;注:&lt;/b&gt;Windows ゲストOSをインストールã—ãŸå¾Œã§æœ¬æ©Ÿèƒ½ã‚’無効ã«ã—ãªã„ã§ãã ã•ã„ï¼&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Selects which clipboard data will be copied between the guest and the host OS. This feature requires Guest Additions to be installed in the guest OS.</source>
<translation type="obsolete">ゲストOSã¨ãƒ›ã‚¹ãƒˆOSã®é–“ã§ã‚¯ãƒªãƒƒãƒ—ボードを共有ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã‚’定義ã—ã¾ã™ã€‚注:本機能ã®åˆ©ç”¨ã«ã¯ã‚²ã‚¹ãƒˆOSã« Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the path where snapshots of this virtual machine will be stored. Be aware that snapshots can take quite a lot of disk space.</source>
<translation type="obsolete">ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®ã‚¹ãƒŠãƒƒãƒ—ショットã®ä¿å­˜å…ˆãƒ‘スを表示ã—ã¾ã™ã€‚注:スナップショットã¯å¤šãã®ãƒ‡ã‚£ã‚¹ã‚¯å®¹é‡ã‚’消費ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Resets the snapshot folder path to the default value. The actual default path will be displayed after accepting the changes and opening this dialog again.</source>
<translation type="obsolete">スナップショットã®ä¿å­˜å…ˆãƒ•ォルダã®ãƒ‘ã‚¹ã‚’ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã«æˆ»ã—ã¾ã™ã€‚変更後ã€å†åº¦ã“ã®ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‹ãã¨ãƒ‡ãƒ•ォルトã®ãƒ‘スãŒè¡¨ç¤ºã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the description of the virtual machine. The description field is useful for commenting on configuration details of the installed guest OS.</source>
<translation type="obsolete">仮想マシンã®ã‚³ãƒ¡ãƒ³ãƒˆã‚’表示ã—ã¾ã™ã€‚コメントã¯ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れãŸã‚²ã‚¹ãƒˆOSã®è©³ç´°ãªæ§‹æˆã«é–¢ã™ã‚‹æ³¨é‡ˆã¨ã—ã¦å½¹ç«‹ã¡ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Lists host Floppy drives available to mount to the virtual machine.</source>
<translation type="obsolete">仮想マシンã«ãƒžã‚¦ãƒ³ãƒˆã™ã‚‹ãŸã‚ã«åˆ©ç”¨å¯èƒ½ãªãƒ›ã‚¹ãƒˆ フロッピードライブをリスト表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Invokes the Virtual Disk Manager to select a Floppy image to mount.</source>
<translation type="obsolete">仮想ディスクマãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•ã—ã€é¸æŠžã—ãŸãƒ•ロッピーイメージをマウントã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Lists host CD/DVD drives available to mount to the virtual machine.</source>
<translation type="obsolete">仮想マシンã«ãƒžã‚¦ãƒ³ãƒˆã™ã‚‹ãŸã‚ã«åˆ©ç”¨å¯èƒ½ãªãƒ›ã‚¹ãƒˆã®CD/DVDドライブをリスト表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Invokes the Virtual Disk Manager to select a CD/DVD image to mount.</source>
<translation type="obsolete">仮想ディスクマãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•ã—ã€é¸æŠžã—ãŸCD/DVDイメージをマウントã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&lt;qt&gt;Controls the audio output driver. The &lt;b&gt;Null Audio Driver&lt;/b&gt;
makes the guest see an audio card, however every access to it will be ignored.&lt;/qt&gt;</source>
<translation type="obsolete">&lt;qt&gt;オーディオ出力ドライãƒã‚’é¸æŠžã—ã¾ã™ã€‚&lt;b&gt;Null Audio Driver&lt;/b&gt;ã¯ã‚²ã‚¹ãƒˆOSã‹ã‚‰ã‚ªãƒ¼ãƒ‡ã‚£ã‚ªã‚«ãƒ¼ãƒ‰ã¨ã—ã¦èªè­˜ã•れã¾ã™ãŒã€ãƒ‡ãƒã‚¤ã‚¹ã¸ã®ã™ã¹ã¦ã®ã‚¢ã‚¯ã‚»ã‚¹ã¯ç„¡è¦–ã•れã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, enables the virtual USB controller of this machine.</source>
<translation type="obsolete">ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®ä»®æƒ³USB コントローラを有効ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Adapter %1</source>
<comment>network</comment>
<translation type="obsolete">アダプタ %1</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Host &amp;Interfaces</source>
<translation type="obsolete">ホスト インターフェース(&amp;I)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Lists all available host interfaces.</source>
<translation type="obsolete">利用å¯èƒ½ãªãƒ›ã‚¹ãƒˆ インターフェースをリスト表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Adds a new host interface.</source>
<translation type="obsolete">æ–°è¦ãƒ›ã‚¹ãƒˆ インターフェースを追加ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Removes the selected host interface.</source>
<translation type="obsolete">é¸æŠžã—ãŸãƒ›ã‚¹ãƒˆ インターフェースを除去ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&lt;No suitable interfaces&gt;</source>
<translation type="obsolete">&lt;é©åˆ‡ãªã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェースãŒã‚りã¾ã›ã‚“&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Add</source>
<translation type="obsolete">追加</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Remove</source>
<translation type="obsolete">除去</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>VirtualBox Host Interface %1</source>
<translation type="obsolete">VirtualBox ホスト インターフェース %1</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&lt;p&gt;Do you want to remove the selected host network interface &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;?&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; This interface may be in use by one or more network adapters of this or another VM. After it is removed, these adapters will no longer work until you correct their settings by either choosing a different interface name or a different adapter attachment type.&lt;/p&gt;</source>
<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/VBoxVMLogViewer.cpp" line="278"/>
<source> Serial Ports </source>
<translation type="obsolete">シリアルãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>#serialPorts</source>
<translation type="obsolete">#serialPorts</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Enable &amp;VT-x/AMD-V</source>
<translation type="obsolete">VT-x/AMD-Vを有効化(&amp;V)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, the virtual machine will try to make use of the host CPU&apos;s hardware virtualization extensions such as Intel VT-x and AMD-V. The grayed checkbox state means that this setting is determined by the value of the global setting.</source>
<translation type="obsolete">仮想マシンã¯Intel VT-x/AMD-Vã®ã‚ˆã†ãªãƒ›ã‚¹ãƒˆCPUã®ä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½ã‚’使用ã—ã¾ã™ã€‚ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ãŒã‚°ãƒ¬ã‚¤ã®ã¨ãã¯ã‚°ãƒ­ãƒ¼ãƒãƒ«è¨­å®šã®æŒ‡å®šå€¤ãŒä½¿ç”¨ã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Other &amp;Settings</source>
<translation type="obsolete">ãã®ä»–ã®è¨­å®š(&amp;S)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Remember Media Mounted at Runtime</source>
<translation type="obsolete">実行中ã«ãƒžã‚¦ãƒ³ãƒˆã—ãŸãƒ¡ãƒ‡ã‚£ã‚¢ã‚’記録(&amp;R)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>If checked, any change to mounted CD/DVD or Floppy media performed during machine execution will be saved in the settings file in order to preserve the configuration of mounted media between runs.</source>
<translation type="obsolete">仮想マシン実行中ã«å¤‰æ›´ã—ãŸCD/DVDã¾ãŸã¯ãƒ•ãƒ­ãƒƒãƒ”ãƒ¼ãƒ¡ãƒ‡ã‚£ã‚¢ã®æ§‹æˆã‚’設定ファイルã«ä¿å­˜ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>O&amp;ther</source>
<translation type="obsolete">ãã®ä»–(&amp;T)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Enable Passthrough</source>
<translation type="obsolete">パススルーを有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, allows the guest to send ATAPI commands directly to the host drive which makes it possible to use CD/DVD writers connected to the host inside the VM. Note that writing audio CD inside the VM is not yet supported.</source>
<translation type="obsolete">ãƒ›ã‚¹ãƒˆã«æŽ¥ç¶šã•れãŸCD/DVDライターを使用å¯èƒ½ã«ã™ã‚‹ãŸã‚ã€ã‚²ã‚¹ãƒˆOSã®ATAPIコマンドを直接ホスト ドライブã«é€ã‚Šã¾ã™ã€‚注:仮想マシンã‹ã‚‰éŸ³æ¥½CDã¸ã®æ›¸ãè¾¼ã¿ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Server Port </source>
<translation type="obsolete">サーãƒãƒ¼ã®ãƒãƒ¼ãƒˆç•ªå·</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Authentication &amp;Method </source>
<translation type="obsolete">èªè¨¼æ–¹æ³•(&amp;M)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Authentication &amp;Timeout </source>
<translation type="obsolete">èªè¨¼ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆå€¤(&amp;T)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&lt;qt&gt;Displays the VRDP Server port number. You may specify &lt;tt&gt;0&lt;/tt&gt; (zero) to reset the port to the default value.&lt;/qt&gt;</source>
<translation type="obsolete">&lt;qt&gt;VRDPサームãƒãƒ¼ãƒˆç•ªå·ã‚’表示ã—ã¾ã™ã€‚ãƒãƒ¼ãƒˆã‚’デフォルト値ã«ãƒªã‚»ãƒƒãƒˆã™ã‚‹ã«ã¯&lt;tt&gt;0&lt;/tt&gt;(ゼロ)を指定ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>CD/DVD image file is not selected</source>
<translation type="obsolete">CD/DVDイメージファイルãŒé¸æŠžã•れã¦ã„ãªã„</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Floppy image file is not selected</source>
<translation type="obsolete">フロッピーイメージファイルãŒé¸æŠžã•れã¦ã„ãªã„</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Incorrect host network interface is selected</source>
<translation type="obsolete">é¸æŠžã—ãŸãƒ›ã‚¹ãƒˆ ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ インターフェースãŒä¸æ­£</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Duplicate port number selected </source>
<translation type="obsolete">é¸æŠžã—ãŸãƒãƒ¼ãƒˆç•ªå·ã¯ã™ã§ã«ä½¿ç”¨ã•れã¦ã„ã‚‹</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Duplicate port path entered </source>
<translation type="obsolete">指定ã—ãŸãƒãƒ¼ãƒˆ パスã¯ã™ã§ã«ä½¿ç”¨ã•れã¦ã„ã‚‹</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>%1 on the &lt;b&gt;%2&lt;/b&gt; page.</source>
<translation type="obsolete">&lt;b&gt;%2&lt;/b&gt;ページã®%1。</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Port %1</source>
<comment>serial ports</comment>
<translation type="obsolete">ãƒãƒ¼ãƒˆ %1</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>00</source>
<translation type="obsolete">00</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>01</source>
<translation type="obsolete">01</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>02</source>
<translation type="obsolete">02</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>03</source>
<translation type="obsolete">03</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>04</source>
<translation type="obsolete">04</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>05</source>
<translation type="obsolete">05</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>08</source>
<translation type="obsolete">08</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>10</source>
<translation type="obsolete">10</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>09</source>
<translation type="obsolete">09</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>06</source>
<translation type="obsolete">06</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source> Parallel Ports </source>
<translation type="obsolete">パラレルãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>07</source>
<translation type="obsolete">07</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>#parallelPorts</source>
<translation type="obsolete">#parallelPorts</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Enable PA&amp;E/NX</source>
<translation type="obsolete">PAE/NXを有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&lt;qt&gt;When
checked, the Physical
Address Extension
@@ -15534,37 +15115,30 @@ makes the guest see an audio card, however every access to it will be ignored.&l
<translation type="obsolete">&lt;qt&gt;ホストCPUã®ç‰©ç†ã‚¢ãƒ‰ãƒ¬ã‚¹æ‹¡å¼µæ©Ÿèƒ½(PAE)ã‚’ä»®æƒ³ãƒžã‚·ãƒ³ã§æœ‰åйã«ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;IDE Controller Type</source>
<translation type="obsolete">IDE コントローラ タイプ(&amp;I)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Defines the type of the virtual IDE controller. Depending on this value, VirtualBox will provide different virtual IDE hardware devices to the guest OS.</source>
<translation type="obsolete">仮想IDE コントローラã®ã‚¿ã‚¤ãƒ—を定義ã—ã¾ã™ã€‚ã“ã®å€¤ã«ã‚ˆã‚Šã€VirtualBoxã¯ç•°ãªã£ãŸä»®æƒ³IDEãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ デãƒã‚¤ã‚¹ã‚’ゲストOSã«æä¾›ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Audio &amp;Controller</source>
<translation type="obsolete">オーディオ コントローラ(&amp;C)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Selects the type of the virtual sound card. Depending on this value, VirtualBox will provide different audio hardware to the virtual machine.</source>
<translation type="obsolete">仮想サウンドカードã®ã‚¿ã‚¤ãƒ—ã‚’é¸æŠžã—ã¾ã™ã€‚ ã“ã®å€¤ã«ã‚ˆã‚Šã€VirtualBoxã¯ç•°ãªã£ãŸã‚ªãƒ¼ãƒ‡ã‚£ã‚ª ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã‚’ä»®æƒ³ãƒžã‚·ãƒ³ã«æä¾›ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Enable USB &amp;2.0 Controller</source>
<translation type="obsolete">USB 2.0 コントローラを有効化(&amp;2)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, enables the virtual USB EHCI controller of this machine. The USB EHCI controller provides USB 2.0 support.</source>
<translation type="obsolete">仮想マシンã®ä»®æƒ³USB EHCI コントローラを有効ã«ã—ã¾ã™ã€‚USB EHCI コントローラã¯USB 2.0 サãƒãƒ¼ãƒˆã‚’æä¾›ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>
&lt;qt&gt;Lists all USB filters of
this machine. The checkbox to the
@@ -15579,17 +15153,14 @@ makes the guest see an audio card, however every access to it will be ignored.&l
USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹å³å´ã®ãƒœã‚¿ãƒ³ã‚’使用ã—ã¦ãã ã•ã„。&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Add Empty Filter</source>
<translation type="obsolete">空ã®ãƒ•ィルタを追加</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Add Empty Filter</source>
<translation type="obsolete">空ã®ãƒ•ィルタを追加ã™ã‚‹(&amp;A)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>
&lt;qt&gt;Adds a new USB filter with all fields initially set to
empty strings. Note that such a filter will match any attached USB
@@ -15598,17 +15169,14 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<translation type="obsolete">&lt;qt&gt;ã™ã¹ã¦ã®ãƒ•ィールドãŒç©ºã®æ–°è¦USBフィルタを追加ã—ã¾ã™ã€‚注:ã“ã®ãƒ•ィルタã¯ã™ã¹ã¦ã®æŽ¥ç¶šã•れãŸUSB デãƒã‚¤ã‚¹ã«é©åˆã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Add Filter From Device</source>
<translation type="obsolete">デãƒã‚¤ã‚¹ã‹ã‚‰ãƒ•ィルタを追加</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>A&amp;dd Filter From Device</source>
<translation type="obsolete">デãƒã‚¤ã‚¹ã‹ã‚‰ãƒ•ィルタを追加ã™ã‚‹(&amp;D)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&lt;qt&gt;Adds a new USB filter with all fields set to the
values of the selected USB device attached to the host
PC.&lt;/qt&gt;
@@ -15616,179 +15184,145 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<translation type="obsolete">&lt;qt&gt;é¸æŠžã—ãŸãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã®USB デãƒã‚¤ã‚¹ã®å€¤ã‚’ã™ã¹ã¦ã®ãƒ•ィールドã«è¨­å®šã—ãŸæ–°è¦USBフィルタを追加ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Remove Filter</source>
<translation type="obsolete">フィルタを除去</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Remove Filter</source>
<translation type="obsolete">フィルタを除去ã™ã‚‹(&amp;R)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>
&lt;qt&gt;Removes the highlighted USB filter.&lt;/qt&gt;
</source>
<translation type="obsolete">&lt;qt&gt;ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸUSBフィルタを除去ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Move Filter Up</source>
<translation type="obsolete">フィルタを上ã«ç§»å‹•</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Move Filter Up</source>
<translation type="obsolete">フィルタを上ã«ç§»å‹•ã™ã‚‹(&amp;M)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>
&lt;qt&gt;Moves the highlighted USB filter up.&lt;/qt&gt;
</source>
<translation type="obsolete">&lt;qt&gt;ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸUSBフィルタを上ã«ç§»å‹•ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Move Filter Down</source>
<translation type="obsolete">フィルタを下ã«ç§»å‹•</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>M&amp;ove Filter Down</source>
<translation type="obsolete">フィルタを下ã«ç§»å‹•(&amp;O)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>
&lt;qt&gt;Moves the highlighted USB filter down.&lt;/qt&gt;
</source>
<translation type="obsolete">&lt;qt&gt;ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡¨ç¤ºã•れãŸUSBフィルタを下ã«ç§»å‹•ã—ã¾ã™ã€‚&lt;/qt&gt;</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Internal network name is not set</source>
<translation type="obsolete">内部ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯åãŒè¨­å®šã•れã¦ã„ãªã„</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Port path not specified </source>
<translation type="obsolete">ãƒãƒ¼ãƒˆ ãƒ‘ã‚¹ãŒæŒ‡å®šã•れã¦ã„ãªã„</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Port %1</source>
<comment>parallel ports</comment>
<translation type="obsolete">ãƒãƒ¼ãƒˆ %1</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>USBActionGroup</source>
<translation type="obsolete">USBActionGroup</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>General</source>
<translation type="obsolete">一般</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Storage</source>
<translation type="obsolete">ストレージ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Hard Disks</source>
<translation type="obsolete">ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>CD/DVD-ROM</source>
<translation type="obsolete">CD/DVD-ROM</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Floppy</source>
<translation type="obsolete">フロッピー</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Audio</source>
<translation type="obsolete">オーディオ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Network</source>
<translation type="obsolete">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Ports</source>
<translation type="obsolete">ãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Serial Ports</source>
<translation type="obsolete">シリアルãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Parallel Ports</source>
<translation type="obsolete">パラレルãƒãƒ¼ãƒˆ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>USB</source>
<translation type="obsolete">USB</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Shared Folders</source>
<translation type="obsolete">共有フォルダ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="obsolete">USB HID(Human Interface Device)を有効化ã—ã¾ã—ãŸã€‚ ã“れã¯ã€USBエミュレーションを有効化ã—ãªã„ã¨å‹•作ã—ã¾ã›ã‚“。USBエミュレーションã¯&lt;b&gt;[OK]&lt;/b&gt;ボタンを押ã™ã¨è‡ªå‹•çš„ã«æœ‰åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Remote Display</source>
<translation type="obsolete">リモートディスプレイ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>%1 - %2</source>
<translation type="obsolete">%1 - %2</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>On the &lt;b&gt;%1&lt;/b&gt; page, %2</source>
<translation type="obsolete">&lt;b&gt;%1&lt;/b&gt;ページã®%2</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>System</source>
<translation type="obsolete">システム</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Display</source>
<translation type="obsolete">ディスプレイ</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
<translation type="obsolete">64ビットã®ã‚²ã‚¹ãƒˆOSタイプãŒé¸æŠžã•れã¾ã—ãŸã€‚ゲストOSãŒä»®æƒ³åŒ–æ”¯æ´æ©Ÿèƒ½(VT-x/AMD-V)ã‚’å¿…è¦ã¨ã™ã‚‹ã¨ãã€ã“ã®æ©Ÿèƒ½ã¯è‡ªå‹•çš„ã«æœ‰åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>you have selected a 64-bit guest OS type for this VM. VirtualBox does not currently support more than one virtual CPU for 64-bit guests executed on 32-bit hosts.</source>
<translation type="obsolete">64ビットã®ã‚²ã‚¹ãƒˆOSタイプãŒé¸æŠžã•れã¾ã—ãŸã€‚VirtualBoxã¯ç¾åœ¨32ビットã®ãƒ›ã‚¹ãƒˆOS上ã§å®Ÿè¡Œã•れる64ビットã®ã‚²ã‚¹ãƒˆOSã§2ã¤ä»¥ä¸Šã®ä»®æƒ³CPUをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
<translation type="obsolete">2D ビデオ ã‚¢ã‚¯ã‚»ãƒ©ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒæœ‰åŠ¹åŒ–ã•れã¾ã—ãŸã€‚2D ビデオ アクセラレーションã¯Windowsゲストã§ã®ã¿ã‚µãƒãƒ¼ãƒˆã•れるãŸã‚ã€æœ¬æ©Ÿèƒ½ã¯ç„¡åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
</message>
@@ -15796,62 +15330,50 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxVMSettingsFD</name>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Host floppy drive is not selected</source>
<translation type="obsolete">ホスト フロッピードライブãŒé¸æŠžã•れã¦ã„ãªã„</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Floppy image file is not selected</source>
<translation type="obsolete">フロッピーイメージファイルãŒé¸æŠžã•れã¦ã„ãªã„</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, mounts the specified media to the Floppy drive of the virtual machine.</source>
<translation type="obsolete">指定ã—ãŸãƒ¡ãƒ‡ã‚£ã‚¢ã‚’仮想マシンã®ãƒ•ロッピードライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Mount Floppy Drive</source>
<translation type="obsolete">フロッピードライブã®ãƒžã‚¦ãƒ³ãƒˆ(&amp;M)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Mounts the specified host Floppy drive to the virtual Floppy drive.</source>
<translation type="obsolete">指定ã—ãŸãƒ›ã‚¹ãƒˆ フロッピードライブを仮想フロッピードライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Host Floppy &amp;Drive</source>
<translation type="obsolete">ホスト フロッピードライブ(&amp;D)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Lists host Floppy drives available to mount to the virtual machine.</source>
<translation type="obsolete">仮想マシンã«ãƒžã‚¦ãƒ³ãƒˆã™ã‚‹ãŸã‚ã«åˆ©ç”¨å¯èƒ½ãªãƒ›ã‚¹ãƒˆ フロッピードライブをリスト表示ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Mounts the specified Floppy image to the virtual Floppy drive.</source>
<translation type="obsolete">指定ã—ãŸãƒ•ロッピーイメージを仮想フロッピードライブã«ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Image File</source>
<translation type="obsolete">イメージファイル(&amp;I)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the image file to mount to the virtual Floppy drive and allows to quickly select a different image.</source>
<translation type="obsolete">仮想フロッピードライブã«ãƒžã‚¦ãƒ³ãƒˆã•れãŸã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ァイルを表示ã—ã¾ã™ã€‚ã¾ãŸã€ä»–ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’ç´ æ—©ãé¸æŠžã§ãã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Invokes the Virtual Disk Manager to select a Floppy image to mount.</source>
<translation type="obsolete">仮想ディスクマãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•ã—ã€é¸æŠžã—ãŸãƒ•ロッピーイメージをマウントã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Invokes the Virtual Media Manager to select a Floppy image to mount.</source>
<translation type="obsolete">仮想メディアマãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•ã—ã€é¸æŠžã—ãŸãƒ•ロッピーイメージをマウントã—ã¾ã™ã€‚</translation>
</message>
@@ -15859,42 +15381,34 @@ USBフィルタを追加ã¾ãŸã¯é™¤åŽ»ã™ã‚‹ã«ã¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ
<context>
<name>VBoxVMSettingsVRDP</name>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>When checked, the VM will act as a Remote Desktop Protocol (RDP) server, allowing remote clients to connect and operate the VM (when it is running) using a standard RDP client.</source>
<translation type="obsolete">仮想マシンã®ãƒªãƒ¢ãƒ¼ãƒˆãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—プロトコル(RDP)サーãƒãƒ¼æ©Ÿèƒ½ã‚’有効ã«ã—ã¾ã™ã€‚ãƒªãƒ¢ãƒ¼ãƒˆã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆãŒæ¨™æº–çš„ãªRDPクライアントを使用ã—ã¦å®Ÿè¡Œä¸­ã®ä»®æƒ³ãƒžã‚·ãƒ³ã«æŽ¥ç¶šã—ã€æ“作ã™ã‚‹ã“ã¨ã‚’å¯èƒ½ã«ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>&amp;Enable VRDP Server</source>
<translation type="obsolete">VRDPサーãƒãƒ¼ã‚’有効化(&amp;E)</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Server &amp;Port:</source>
<translation type="obsolete">サーãƒãƒ¼ã®ãƒãƒ¼ãƒˆç•ªå·(&amp;P):</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Displays the VRDP Server port number. You may specify &lt;tt&gt;0&lt;/tt&gt; (zero) to reset the port to the default value.</source>
<translation type="obsolete">VRDPサーãƒãƒ¼ã®ãƒãƒ¼ãƒˆç•ªå·ã‚’表示ã—ã¾ã™ã€‚ãƒãƒ¼ãƒˆã‚’デフォルト値ã«ãƒªã‚»ãƒƒãƒˆã™ã‚‹ã«ã¯&lt;tt&gt;0&lt;/tt&gt;(ゼロ)を指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Authentication &amp;Method:</source>
<translation type="obsolete">èªè¨¼æ–¹å¼(&amp;M):</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Defines the VRDP authentication method.</source>
<translation type="obsolete">VRDPã®èªè¨¼æ–¹å¼ã‚’指定ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Authentication &amp;Timeout:</source>
<translation type="obsolete">èªè¨¼ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆå€¤(&amp;T):</translation>
</message>
<message>
- <location filename="../src/VBoxVMLogViewer.cpp" line="278"/>
<source>Specifies the timeout for guest authentication, in milliseconds.</source>
<translation type="obsolete">ゲストèªè¨¼ã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆå€¤ã‚’ミリ秒å˜ä½ã§æŒ‡å®šã—ã¾ã™ã€‚</translation>
</message>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_km_KH.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_km_KH.ts
index a41b6691b..b95ec8047 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_km_KH.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_km_KH.ts
@@ -430,11 +430,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">ការ​កំណážáŸ‹...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -600,11 +681,6 @@
<translation type="unfinished">​អាដាប់​ទáŸážšâ€‹â€‹ ម៉ាស៊ីន​​-​ážáŸ‚​មួយ &apos;%1&apos;​</translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation type="unfinished">អាដាប់ទáŸážš %1</translation>
@@ -728,6 +804,26 @@
<comment>details report</comment>
<translation type="unfinished">សáŸáž…​ក្ážáž¸â€‹áž–ិណណ៌នា​</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -904,6 +1000,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Export &gt;</source>
<translation type="obsolete">នាំ​ចáŸáž‰&gt;</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1209,6 +1309,10 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;​​ចុច​ ប្រ​សិន​បើ​ážáž¶áž„លើ​​ážáŸ’រឹម​ážáŸ’រូវ​ &lt;b&gt;​បញ្ចប់​​&lt;/b&gt; ប៊ូážáž»áž„​ ។​ លើ​ទី​មួយ​ដែល​អ្នក​ចុច​វា​Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1282,41 +1386,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">ទូទៅ</translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished">បញ្ចូល</translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished">ធ្វើ​ឲ្យ​ទាន់សមáŸáž™</translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished">ភាសា</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">បណ្ដាញ</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished">VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1830,6 +1899,57 @@ creating/removing host-only network</comment>
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1899,23 +2019,23 @@ creating/removing host-only network</comment>
</message>
<message>
<source>Left Shift</source>
- <translation>ប្ដូរ(Shift) ឆ្វáŸáž„</translation>
+ <translation type="obsolete">ប្ដូរ(Shift) ឆ្វáŸáž„</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>ប្ដូរ(Shift) ស្ដាំ</translation>
+ <translation type="obsolete">ប្ដូរ(Shift) ស្ដាំ</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>បញ្ជា (Ctrl) ឆ្វáŸáž„</translation>
+ <translation type="obsolete">បញ្ជា (Ctrl) ឆ្វáŸáž„</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>បញ្ជា(Ctrl) ស្ដាំ</translation>
+ <translation type="obsolete">បញ្ជា(Ctrl) ស្ដាំ</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>ជំនួស​(Alt) ឆ្វáŸáž„</translation>
+ <translation type="obsolete">ជំនួស​(Alt) ឆ្វáŸáž„</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2132,6 +2252,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">នាំ​ចូល​​&gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2276,7 +2400,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>បង្ហាញážáž¶ ​ស្ážáž¶áž“​ភាព​របស់​លក្ážážŽáŸˆáž–ិសáŸážŸâ€‹áž“ិម្មិážâ€‹áž•្នែក​រឹង​ážáŸ’រូ​វបាន​ប្រើ​ដោយ​ម៉ាស៊ីន​និម្មិážâ€‹áž“áŸáŸ‡Â áŸ–​&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">បង្ហាញážáž¶ ​ស្ážáž¶áž“​ភាព​របស់​លក្ážážŽáŸˆáž–ិសáŸážŸâ€‹áž“ិម្មិážâ€‹áž•្នែក​រឹង​ážáŸ’រូ​វបាន​ប្រើ​ដោយ​ម៉ាស៊ីន​និម្មិážâ€‹áž“áŸáŸ‡Â áŸ–​&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2299,6 +2423,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2493,9 +2622,13 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">អ្នកបាន​បើក​បង្កើនល្បឿន​​វី​ដáŸáž¢áž¼â€‹â€‹áž‘្វáŸâ€‹â€‹áž˜áž¶ážáŸ’រ​ ។ បង្កើនល្បឿន​វីដáŸáž¢áž¼â€‹â€‹áž‘្វáŸâ€‹áž˜áž¶ážáŸ’រ​​ážáŸ’រូវ​បាន​គាំ​ទ្រ​សម្រាប់​​​ម៉ាស៊ីន​វីនដូ​ážáŸ‚​ប៉ុ​ណ្ណោះ​ លក្ážážŽáŸˆâ€‹áž–ិសáŸážŸáž“áŸáŸ‡â€‹â€‹áž“ឹង​​មិន​ážáŸ’រូវ​បាន​អនុញ្ញាážâ€‹ ។​</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsGeneral</name>
@@ -2571,6 +2704,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>បង្ហាញ​កំពូល​​អáŸáž€áŸ’រង់​</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">អ្នក​បាន​​ជ្រើស​ប្រ​ភáŸáž‘​ប្រ​ពáŸáž“្ធ​ប្រ​ážáž·áž”ážáŸ’ážáž·â€‹â€‹áž€áž¶ážšâ€‹áž˜áŸ‰áž¶ážŸáŸŠáž¸áž“​ភ្ញៀវ​ ៦៤​-​ប៊ីážâ€‹ សម្រាប់​​ VM áž“áŸáŸ‡â€‹ ។ ជាក់​ស្ážáŸ‚ង​ ដូច​ម៉ាស៊ីន​ភ្ញៀវ​ទាមទារ​ážáž¶ážŸážšáž¹áž„​ (VT-x/AMD-V) លក្ážážŽáŸˆâ€‹áž–ិសáŸážŸâ€‹áž“áŸáŸ‡â€‹áž“ឹង​ážáŸ’រូវ​បាន​បើក​ដោយ​ស្វáŸáž™â€‹áž”្រ​វážáŸ’ážáž·â€‹ ។</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2631,7 +2768,7 @@ network adapter name</comment>
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>ជ្រើស​ឈ្មោះ​អាដាប់ទáŸážšâ€‹áž”ណ្ដាញ​សម្រាប់ &lt;b&gt;អាដាប់ទáŸážšâ€‹áž”្រ៊ីដ្យ&lt;/b&gt; ឬ &lt;b&gt;អាដាប់ទáŸážšáž˜áŸ‰áž¶ážŸáŸŠáž¸áž“&lt;/b&gt; ការ​ភ្ជាប់ និង​ឈ្មោះ​​របស់​បណ្ដាញ ការ​ភ្ជាប់&lt;b&gt;បណ្ដាញ​ážáž¶áž„​ក្នុង&lt;/b&gt; ។</translation>
+ <translation type="obsolete">ជ្រើស​ឈ្មោះ​អាដាប់ទáŸážšâ€‹áž”ណ្ដាញ​សម្រាប់ &lt;b&gt;អាដាប់ទáŸážšâ€‹áž”្រ៊ីដ្យ&lt;/b&gt; ឬ &lt;b&gt;អាដាប់ទáŸážšáž˜áŸ‰áž¶ážŸáŸŠáž¸áž“&lt;/b&gt; ការ​ភ្ជាប់ និង​ឈ្មោះ​​របស់​បណ្ដាញ ការ​ភ្ជាប់&lt;b&gt;បណ្ដាញ​ážáž¶áž„​ក្នុង&lt;/b&gt; ។</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -2666,6 +2803,42 @@ network adapter name</comment>
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsParallel</name>
@@ -2994,7 +3167,7 @@ network adapter name</comment>
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>មិន​មាន​ážáž¶ážŸâ€‹ážšáž¹áž„​​ážáŸ’រូវ​បាន​ជ្រើស​​សម្រាប់&lt;i&gt;%1&lt;/i&gt; នោះ​ទáŸÂ áŸ”</translation>
+ <translation type="obsolete">មិន​មាន​ážáž¶ážŸâ€‹ážšáž¹áž„​​ážáŸ’រូវ​បាន​ជ្រើស​​សម្រាប់&lt;i&gt;%1&lt;/i&gt; នោះ​ទáŸÂ áŸ”</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3260,6 +3433,60 @@ network adapter name</comment>
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3451,6 +3678,32 @@ network adapter name</comment>
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3576,7 +3829,7 @@ network adapter name</comment>
<translation type="unfinished">&lt;nobr&gt;ស្ážáž¶áž“ភាព ៖ %1&lt;/nobr&gt;</translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -3690,6 +3943,21 @@ network adapter name</comment>
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3735,7 +4003,7 @@ network adapter name</comment>
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>បង្កើážâ€‹ážáž¶ážŸâ€‹áž“ិម្មិážâ€‹ážáŸ’មី</translation>
@@ -3750,7 +4018,7 @@ network adapter name</comment>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">សáŸáž…ក្ដី​សង្ážáŸáž”</translation>
+ <translation type="unfinished">សáŸáž…ក្ដី​សង្ážáŸáž”</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -3762,7 +4030,7 @@ network adapter name</comment>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">ជ្រើស​ឯកសារ​សម្រាប់​ឯកសារ​រូបភាព​ážáž¶ážŸâ€‹ážšáž¹áž„</translation>
+ <translation type="unfinished">ជ្រើស​ឯកសារ​សម្រាប់​ឯកសារ​រូបភាព​ážáž¶ážŸâ€‹ážšáž¹áž„</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -3784,12 +4052,12 @@ network adapter name</comment>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">ទីážáž¶áŸ†áž„</translation>
+ <translation type="unfinished">ទីážáž¶áŸ†áž„</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">ទំហំ</translation>
+ <translation type="unfinished">ទំហំ</translation>
</message>
<message>
<source>Bytes</source>
@@ -3848,15 +4116,183 @@ network adapter name</comment>
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">ប្រសិនបើ​កា​រកំណážáŸ‹â€‹ážáž¶áž„​លើ​ážáŸ’រឹមážáŸ’រូវ ចុច​ប៊ូážáž»áž„ &lt;b&gt;បញ្ចប់&lt;/b&gt; ។ នៅពáŸáž›â€‹áž¢áŸ’នក​ចុចវា ážáž¶ážŸážšáž¹áž„​ážáŸ’មី​នឹង​ážáŸ’រូវ​បានបង្កើážâ€‹áž¡áž¾áž„ ។</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">ទីážáž¶áŸ†áž„</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">ទំហំ</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation type="unfinished">សូម​ស្វាគមនáŸâ€‹áž˜áž€â€‹áž€áž¶áž“់​​អ្នក​ជំនួយការ​បង្កើážâ€‹ážáž¶ážŸâ€‹áž“ិម្មិ​ážážáŸ’មី !</translation>
+ <translation type="obsolete">សូម​ស្វាគមនáŸâ€‹áž˜áž€â€‹áž€áž¶áž“់​​អ្នក​ជំនួយការ​បង្កើážâ€‹ážáž¶ážŸâ€‹áž“ិម្មិ​ážážáŸ’មី !</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <source>Choose a virtual hard disk file...</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -3864,92 +4300,76 @@ network adapter name</comment>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;ជ្រើស​ប្រភáŸáž‘​ážáž¶ážŸážšáž¹áž„​និម្មិážâ€‹ážŠáŸ‚ល​អ្នក​ចង់​បង្កើážÂ áŸ”&lt;/p&gt;&lt;p&gt; &lt;b&gt;កា​រផ្ទុក​ពង្រីក​ជា​ážáž¶áž˜ážœáž“្áž&lt;/b&gt; ដំបូង​គ្រប់គ្រង​រាល់​ទំហំ​ážáž¼áž…ៗ​របស់ចន្លោះ​នៅ​ក្នុង​ážáž¶ážŸážšáž¹áž„​ហ្វីស៊ីážáž›â€‹ážšáž”ស់​អ្នក ។ វា​នឹង​ពង្រីក​ដោយ​ážáž¶áž˜ážœáž“្ហ(ដល់​ទំហំ​ដែល​បាន​បញ្ជាក់) ជា​ការ​អះអាង​ប្រពáŸáž“្ធ​ប្រážáž·áž”ážáŸ’ážáž·áž€áž¶ážšâ€‹ážšáž”ស់​ម៉ាស៊ីន​ភ្ញៀវ ។&lt;/p&gt;&lt;p&gt; &lt;b&gt;កា​រផ្ទុក​ទំហំážáŸážš&lt;/b&gt; មិន​រីកចំរើន​ទáŸÂ áŸ” វា​ážáŸ’រូ​វបាន​ផ្ទុក​នៅ​ក្នុង​ឯកសារ​របស់​ទំហំ​​ប្រហែល​ ជា​ទំហំ​របស់​ážáž¶ážŸážšáž¹áž„​និម្មិážÂ áŸ” ការ​បង្កើážâ€‹áž€áž¶ážšâ€‹áž•្ទុក​ទំហំážáŸážš អាច​ចំណាយ​ពáŸáž›â€‹áž™áž¼ážšâ€‹ ដោយអាស្រáŸáž™â€‹áž›áž¾â€‹áž‘ំហំ​ផ្ទុក និង​សរសáŸážšâ€‹áž€áž¶ážšâ€‹áž¢áž“ុវážáŸ’ážâ€‹áž“ៃ​ážáž¶ážŸážšáž¹áž„​របស់​អ្នក ។&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;ជ្រើស​ប្រភáŸáž‘​ážáž¶ážŸážšáž¹áž„​និម្មិážâ€‹ážŠáŸ‚ល​អ្នក​ចង់​បង្កើážÂ áŸ”&lt;/p&gt;&lt;p&gt; &lt;b&gt;កា​រផ្ទុក​ពង្រីក​ជា​ážáž¶áž˜ážœáž“្áž&lt;/b&gt; ដំបូង​គ្រប់គ្រង​រាល់​ទំហំ​ážáž¼áž…ៗ​របស់ចន្លោះ​នៅ​ក្នុង​ážáž¶ážŸážšáž¹áž„​ហ្វីស៊ីážáž›â€‹ážšáž”ស់​អ្នក ។ វា​នឹង​ពង្រីក​ដោយ​ážáž¶áž˜ážœáž“្ហ(ដល់​ទំហំ​ដែល​បាន​បញ្ជាក់) ជា​ការ​អះអាង​ប្រពáŸáž“្ធ​ប្រážáž·áž”ážáŸ’ážáž·áž€áž¶ážšâ€‹ážšáž”ស់​ម៉ាស៊ីន​ភ្ញៀវ ។&lt;/p&gt;&lt;p&gt; &lt;b&gt;កា​រផ្ទុក​ទំហំážáŸážš&lt;/b&gt; មិន​រីកចំរើន​ទáŸÂ áŸ” វា​ážáŸ’រូ​វបាន​ផ្ទុក​នៅ​ក្នុង​ឯកសារ​របស់​ទំហំ​​ប្រហែល​ ជា​ទំហំ​របស់​ážáž¶ážŸážšáž¹áž„​និម្មិážÂ áŸ” ការ​បង្កើážâ€‹áž€áž¶ážšâ€‹áž•្ទុក​ទំហំážáŸážš អាច​ចំណាយ​ពáŸáž›â€‹áž™áž¼ážšâ€‹ ដោយអាស្រáŸáž™â€‹áž›áž¾â€‹áž‘ំហំ​ផ្ទុក និង​សរសáŸážšâ€‹áž€áž¶ážšâ€‹áž¢áž“ុវážáŸ’ážâ€‹áž“ៃ​ážáž¶ážŸážšáž¹áž„​របស់​អ្នក ។&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation type="unfinished">ប្រភáŸáž‘​ផ្ទុក</translation>
+ <translation type="obsolete">ប្រភáŸáž‘​ផ្ទុក</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation type="unfinished">ពង្រីក​ការ​ផ្ទុក​ážáž¶áž˜ážœáž“្áž</translation>
+ <translation type="obsolete">ពង្រីក​ការ​ផ្ទុក​ážáž¶áž˜ážœáž“្áž</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation type="unfinished">កា​រ​ផ្ទុក​ទំហំážáŸážš</translation>
+ <translation type="obsolete">កា​រ​ផ្ទុក​ទំហំážáŸážš</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation type="unfinished">ប្រភáŸáž‘​ផ្ទុក​របស់​ážáž¶ážŸážšáž¹áž„</translation>
+ <translation type="obsolete">ប្រភáŸáž‘​ផ្ទុក​របស់​ážáž¶ážŸážšáž¹áž„</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;ចុច​ប៊ូážáž»áž„ &lt;b&gt;ជ្រើស&lt;/b&gt; ដើម្បី​ជ្រើស​ទីážáž¶áŸ†áž„​របស់​ឯកសារ​ដើម្បី​ផ្ទុក​ážáž¶ážŸážšáž¹áž„ ឬ​ប្រភáŸáž‘​ឈ្មោះ​ឯកសារ​នៅ​ក្នុង​វាល​ធាážáž»Â áŸ”&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;ចុច​ប៊ូážáž»áž„ &lt;b&gt;ជ្រើស&lt;/b&gt; ដើម្បី​ជ្រើស​ទីážáž¶áŸ†áž„​របស់​ឯកសារ​ដើម្បី​ផ្ទុក​ážáž¶ážŸážšáž¹áž„ ឬ​ប្រភáŸáž‘​ឈ្មោះ​ឯកសារ​នៅ​ក្នុង​វាល​ធាážáž»Â áŸ”&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation type="unfinished">ទីážáž¶áŸ†áž„</translation>
+ <translation type="obsolete">ទីážáž¶áŸ†áž„</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;ជ្រើស​ទំហំ​ážáž¶ážŸážšáž¹áž„​និម្មិážâ€‹áž‚áž·ážâ€‹áž‡áž¶áž˜áŸáž€áž¶áž”ៃ ។ ទំហំ​នáŸáŸ‡â€‹áž“ឹង​ážáŸ’រូវ​បាន​រាយការណáŸâ€‹áž‘ៅ​កាន់​ប្រពáŸáž“្ធ​ប្រážáž·áž”ážáŸ’ážáž·áž€áž¶ážšâ€‹ážšáž”ស់​ម៉ាស៊ីន​ភ្ញៀវ​ážáž¶áž˜â€‹áž‘ំហំ​អážáž·áž”រមា​របស់​ážáž¶ážŸážšáž¹áž„​នáŸáŸ‡Â áŸ”&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;ជ្រើស​ទំហំ​ážáž¶ážŸážšáž¹áž„​និម្មិážâ€‹áž‚áž·ážâ€‹áž‡áž¶áž˜áŸáž€áž¶áž”ៃ ។ ទំហំ​នáŸáŸ‡â€‹áž“ឹង​ážáŸ’រូវ​បាន​រាយការណáŸâ€‹áž‘ៅ​កាន់​ប្រពáŸáž“្ធ​ប្រážáž·áž”ážáŸ’ážáž·áž€áž¶ážšâ€‹ážšáž”ស់​ម៉ាស៊ីន​ភ្ញៀវ​ážáž¶áž˜â€‹áž‘ំហំ​អážáž·áž”រមា​របស់​ážáž¶ážŸážšáž¹áž„​នáŸáŸ‡Â áŸ”&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation type="unfinished">ទំហំ</translation>
+ <translation type="obsolete">ទំហំ</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation type="unfinished">ទីážáž¶áŸ†áž„ និង​ទំហំ​ážáž¶ážŸâ€‹áž“ិម្មិáž</translation>
+ <translation type="obsolete">ទីážáž¶áŸ†áž„ និង​ទំហំ​ážáž¶ážŸâ€‹áž“ិម្មិáž</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="unfinished">ជ្រើស​ឯកសារ​សម្រាប់​ឯកសារ​រូបភាព​ážáž¶ážŸâ€‹ážšáž¹áž„</translation>
+ <translation type="obsolete">ជ្រើស​ឯកសារ​សម្រាប់​ឯកសារ​រូបភាព​ážáž¶ážŸâ€‹ážšáž¹áž„</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation type="unfinished">រូបភាព​ážáž¶ážŸážšáž¹áž„ (*.vdi)</translation>
- </message>
- <message>
- <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">រូបភាព​ážáž¶ážŸážšáž¹áž„ (*.vdi)</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation type="unfinished">អ្នកនឹង​បង្កើážâ€‹ážáž¶ážŸážšáž¹áž„​និម្មិážâ€‹ážáŸ’មី​ដោយ​មាន​ប៉ារ៉ាម៉ែážáŸ’រ​ដូច​ážáž¶áž„ក្រោម ៖</translation>
- </message>
- <message>
- <source>Summary</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>%1 B</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">អ្នកនឹង​បង្កើážâ€‹ážáž¶ážŸážšáž¹áž„​និម្មិážâ€‹ážáŸ’មី​ដោយ​មាន​ប៉ារ៉ាម៉ែážáŸ’រ​ដូច​ážáž¶áž„ក្រោម ៖</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation type="unfinished">ប្រភáŸáž‘</translation>
+ <translation type="obsolete">ប្រភáŸáž‘</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="unfinished">ទីážáž¶áŸ†áž„</translation>
+ <translation type="obsolete">ទីážáž¶áŸ†áž„</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="unfinished">ទំហំ</translation>
- </message>
- <message>
- <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">ទំហំ</translation>
</message>
</context>
<context>
@@ -4079,6 +4499,10 @@ network adapter name</comment>
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">ប្រើ​ážáž¶ážŸâ€‹ážšáž¹áž„​ដែល​មាន​ស្រាប់​</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4328,6 +4752,104 @@ You may wish to translate this more like &quot;Time remaining: %1&quot;</comment
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">ទូទៅ</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation type="unfinished">បញ្ចូល</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished">ធ្វើ​ឲ្យ​ទាន់សមáŸáž™</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation type="unfinished">ភាសា</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">បណ្ដាញ</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation type="unfinished">VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">ទូទៅ</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation type="unfinished">ប្រពáŸáž“្ធ</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation type="unfinished">បង្ហាញ​</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished">អូឌីយ៉ូ</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">បណ្ដាញ</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation type="unfinished">ច្រក</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished">%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">អ្នក​បាន​​ជ្រើស​ប្រ​ភáŸáž‘​ប្រ​ពáŸáž“្ធ​ប្រ​ážáž·áž”ážáŸ’ážáž·â€‹â€‹áž€áž¶ážšâ€‹áž˜áŸ‰áž¶ážŸáŸŠáž¸áž“​ភ្ញៀវ​ ៦៤​-​ប៊ីážâ€‹ សម្រាប់​​ VM áž“áŸáŸ‡â€‹ ។ ជាក់​ស្ážáŸ‚ង​ ដូច​ម៉ាស៊ីន​ភ្ញៀវ​ទាមទារ​ážáž¶ážŸážšáž¹áž„​ (VT-x/AMD-V) លក្ážážŽáŸˆâ€‹áž–ិសáŸážŸâ€‹áž“áŸáŸ‡â€‹áž“ឹង​ážáŸ’រូវ​បាន​បើក​ដោយ​ស្វáŸáž™â€‹áž”្រ​វážáŸ’ážáž·â€‹ ។</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">អ្នកបាន​បើក​បង្កើនល្បឿន​​វី​ដáŸáž¢áž¼â€‹â€‹áž‘្វáŸâ€‹â€‹áž˜áž¶ážáŸ’រ​ ។ បង្កើនល្បឿន​វីដáŸáž¢áž¼â€‹â€‹áž‘្វáŸâ€‹áž˜áž¶ážáŸ’រ​​ážáŸ’រូវ​បាន​គាំ​ទ្រ​សម្រាប់​​​ម៉ាស៊ីន​វីនដូ​ážáŸ‚​ប៉ុ​ណ្ណោះ​ លក្ážážŽáŸˆâ€‹áž–ិសáŸážŸáž“áŸáŸ‡â€‹â€‹áž“ឹង​​មិន​ážáŸ’រូវ​បាន​អនុញ្ញាážâ€‹ ។​</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -4466,81 +4988,6 @@ You may wish to translate this more like &quot;Time remaining: %1&quot;</comment
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">ទូទៅ</translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished">ប្រពáŸáž“្ធ</translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished">បង្ហាញ​</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished">អូឌីយ៉ូ</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">បណ្ដាញ</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished">ច្រក</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished">%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished">អ្នក​បាន​​ជ្រើស​ប្រ​ភáŸáž‘​ប្រ​ពáŸáž“្ធ​ប្រ​ážáž·áž”ážáŸ’ážáž·â€‹â€‹áž€áž¶ážšâ€‹áž˜áŸ‰áž¶ážŸáŸŠáž¸áž“​ភ្ញៀវ​ ៦៤​-​ប៊ីážâ€‹ សម្រាប់​​ VM áž“áŸáŸ‡â€‹ ។ ជាក់​ស្ážáŸ‚ង​ ដូច​ម៉ាស៊ីន​ភ្ញៀវ​ទាមទារ​ážáž¶ážŸážšáž¹áž„​ (VT-x/AMD-V) លក្ážážŽáŸˆâ€‹áž–ិសáŸážŸâ€‹áž“áŸáŸ‡â€‹áž“ឹង​ážáŸ’រូវ​បាន​បើក​ដោយ​ស្វáŸáž™â€‹áž”្រ​វážáŸ’ážáž·â€‹ ។</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished">អ្នកបាន​បើក​បង្កើនល្បឿន​​វី​ដáŸáž¢áž¼â€‹â€‹áž‘្វáŸâ€‹â€‹áž˜áž¶ážáŸ’រ​ ។ បង្កើនល្បឿន​វីដáŸáž¢áž¼â€‹â€‹áž‘្វáŸâ€‹áž˜áž¶ážáŸ’រ​​ážáŸ’រូវ​បាន​គាំ​ទ្រ​សម្រាប់​​​ម៉ាស៊ីន​វីនដូ​ážáŸ‚​ប៉ុ​ណ្ណោះ​ លក្ážážŽáŸˆâ€‹áž–ិសáŸážŸáž“áŸáŸ‡â€‹â€‹áž“ឹង​​មិន​ážáŸ’រូវ​បាន​អនុញ្ញាážâ€‹ ។​</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -4675,6 +5122,14 @@ You may wish to translate this more like &quot;Time remaining: %1&quot;</comment
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -5862,7 +6317,7 @@ Virtualization Stuff LED</comment>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>អាដាប់ទáŸážš %1</translation>
+ <translation type="obsolete">អាដាប់ទáŸážš %1</translation>
</message>
<message>
<source>Checking...</source>
@@ -6661,11 +7116,6 @@ medium</comment>
<translation type="unfinished">​អាដាប់​ទáŸážšâ€‹â€‹ ម៉ាស៊ីន​​-​ážáŸ‚​មួយ &apos;%1&apos;​</translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Teleported</source>
<comment>MachineState</comment>
<translation type="unfinished">បញ្ជួន​</translation>
@@ -6781,11 +7231,6 @@ medium</comment>
<translation type="unfinished">អាដាប់​ទáŸážšâ€‹â€‹áž˜áŸ‰áž¶ážŸáŸŠáž¸áž“​​-​ážáŸ‚​មួយ​</translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>PIIX3</source>
<comment>StorageControllerType</comment>
<translation type="unfinished">PIIX3</translation>
@@ -7010,6 +7455,61 @@ medium</comment>
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">អាដាប់ទáŸážš %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7161,15 +7661,15 @@ medium</comment>
</message>
<message>
<source>Location</source>
- <translation>ទីážáž¶áŸ†áž„</translation>
+ <translation type="obsolete">ទីážáž¶áŸ†áž„</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>ប្រភáŸáž‘ (ទ្រង់ទ្រាយ)</translation>
+ <translation type="obsolete">ប្រភáŸáž‘ (ទ្រង់ទ្រាយ)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>បាន​ភ្ជាប់​ទៅកាន់</translation>
+ <translation type="obsolete">បាន​ភ្ជាប់​ទៅកាន់</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -7276,34 +7776,59 @@ VMM: Floppy Image</comment>
<translation type="obsolete">បាន​ភ្ជាប់​ទៅកាន់</translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: Virtual Disk</comment>
+ <source>CD/DVD-ROM disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: CD/DVD Image</comment>
+ <source>hard disk</source>
+ <translation type="unfinished">ážáž¶ážŸážšáž¹áž„</translation>
+ </message>
+ <message>
+ <source>floppy disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: Floppy Image</comment>
+ <source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>CD/DVD-ROM disk</source>
+ <source>Type:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hard disk</source>
- <translation type="unfinished">ážáž¶ážŸážšáž¹áž„</translation>
+ <source>Location:</source>
+ <translation type="unfinished">ទី​ážáž¶áŸ†áž„​ ៖</translation>
</message>
<message>
- <source>floppy disk</source>
+ <source>Format:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>All %1 images (%2)</source>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -7330,7 +7855,7 @@ VMM: Floppy Image</comment>
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>អាដាប់​ទáŸážšâ€‹áž”ណ្ážáž¶áž‰</translation>
+ <translation type="obsolete">អាដាប់​ទáŸážšâ€‹áž”ណ្ážáž¶áž‰</translation>
</message>
</context>
<context>
@@ -7927,7 +8452,7 @@ VMM: Floppy Image</comment>
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>មិនអាច​ដំណើរការ​ USB ក្នុង​ប្រពáŸáž“្ធ​របស់​ម៉ាស៊ីនបាន​ទ០ពីព្រោះប្រពáŸáž“្ធ​ឯកសារ USB (usbfs) ឬ DBus និង​សáŸážœáž¶ hal បច្ចុប្បន្ននáŸáŸ‡áž¢áž¶áž…​ប្រើ​បាន ។ ប្រសិនបើ​អ្នក​ចង់​ប្រើ​ឧបករណáŸâ€‹ USB របស់​ម៉ាស៊ីន អ្នក​ážáŸ’រូវ​ážáŸ‚​កែវា ហើយ​ចាប់ផ្ដើម VirtualBox ឡើង​វិញ ។</translation>
+ <translation type="obsolete">មិនអាច​ដំណើរការ​ USB ក្នុង​ប្រពáŸáž“្ធ​របស់​ម៉ាស៊ីនបាន​ទ០ពីព្រោះប្រពáŸáž“្ធ​ឯកសារ USB (usbfs) ឬ DBus និង​សáŸážœáž¶ hal បច្ចុប្បន្ននáŸáŸ‡áž¢áž¶áž…​ប្រើ​បាន ។ ប្រសិនបើ​អ្នក​ចង់​ប្រើ​ឧបករណáŸâ€‹ USB របស់​ម៉ាស៊ីន អ្នក​ážáŸ’រូវ​ážáŸ‚​កែវា ហើយ​ចាប់ផ្ដើម VirtualBox ឡើង​វិញ ។</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -7951,7 +8476,7 @@ VMM: Floppy Image</comment>
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;ážáž¾â€‹áž¢áŸ’នក​ប្រាក​ដ​ជា​ចង់​ស្ដារ​រូបážážâ€‹ &lt;b&gt;%1&lt;/b&gt;ឬ ? វា​នឹង​ធ្វើ​ឲ្យ​អ្នក​បាážáŸ‹áž”ង់​ស្ážáž¶áž“ភាព​ម៉ាស៊ីន​បច្ចុប្បន្ន​របស់​អ្នក ដែល​មិនអាច​សង្គ្រោះ​បាន​ទáŸÂ áŸ”&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;ážáž¾â€‹áž¢áŸ’នក​ប្រាក​ដ​ជា​ចង់​ស្ដារ​រូបážážâ€‹ &lt;b&gt;%1&lt;/b&gt;ឬ ? វា​នឹង​ធ្វើ​ឲ្យ​អ្នក​បាážáŸ‹áž”ង់​ស្ážáž¶áž“ភាព​ម៉ាស៊ីន​បច្ចុប្បន្ន​របស់​អ្នក ដែល​មិនអាច​សង្គ្រោះ​បាន​ទáŸÂ áŸ”&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -8524,15 +9049,75 @@ medium</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -8623,7 +9208,7 @@ medium</comment>
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>ážážâ€‹ážŠáŸ‚ល​បាន​ចែករំលែក</translation>
+ <translation type="obsolete">ážážâ€‹ážŠáŸ‚ល​បាន​ចែករំលែក</translation>
</message>
</context>
<context>
@@ -8694,7 +9279,7 @@ medium</comment>
</message>
<message>
<source>D&amp;iscard</source>
- <translation>បោះបង់</translation>
+ <translation type="obsolete">បោះបង់</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -8896,6 +9481,22 @@ medium</comment>
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished">បោះបង់</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -9045,6 +9646,14 @@ medium</comment>
<source> (%1 ago)</source>
<translation> (%1 កន្លង​ទៅ)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ko.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ko.ts
index a66b145ca..c9364d2f4 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ko.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ko.ts
@@ -472,12 +472,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>세션 정보(&amp;N)</translation>
+ <translation type="obsolete">세션 정보(&amp;N)</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>ì›ê²© ë””ìŠ¤í”Œë ˆì´ ì‚¬ìš©í•˜ê¸°(&amp;E)</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation>설정(&amp;S)...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation>ê°€ìƒ ë¨¸ì‹  ì„¤ì •ì„ ê´€ë¦¬í•©ë‹ˆë‹¤</translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation>세션 정보(&amp;N)...</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation>ê°€ìƒ ë¨¸ì‹ ì„ ë³µì œí•©ë‹ˆë‹¤</translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation>복제</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;ì´ ë§ˆë²•ì‚¬ëŠ” ê°€ìƒ ë¨¸ì‹ ì„ ë³µì œí•˜ëŠ” ê³¼ì •ì„ ë„와 ì¤ë‹ˆë‹¤.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation>&lt;p&gt;새 ê°€ìƒ ë¨¸ì‹ ì˜ ì´ë¦„ì„ ì§€ì •í•˜ì‹­ì‹œì˜¤:&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>ì„ íƒí•˜ë©´ 모든 ì„¤ì •ëœ ë„¤íŠ¸ì›Œí¬ ì¹´ë“œì— ìƒˆë¡œìš´ 고유 MAC 주소를 할당합니다.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>모든 ë„¤íŠ¸ì›Œí¬ ì¹´ë“œì˜ MAC 주소 초기화(&amp;R)</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation>ê°€ìƒ ë¨¸ì‹  복제 ë§ˆë²•ì‚¬ì— ì˜¤ì‹  ê²ƒì„ í™˜ì˜í•©ë‹ˆë‹¤</translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation>%1 복제</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation>현재 머신 ìƒíƒœ</translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation>현재 머신 ë° ëª¨ë“  머신 ìƒíƒœ</translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation>모든 ìƒíƒœ</translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation>복제 설정</translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation>ê°€ìƒ ë¨¸ì‹ ì˜ ë³µì œí•  ë¶€ë¶„ì„ ì„ íƒí•˜ì‹­ì‹œì˜¤.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation>&lt;b&gt;현재 머신 ìƒíƒœ&lt;/b&gt;를 ì„ íƒí•˜ë©´ ê°€ìƒ ë¨¸ì‹ ì˜ í˜„ìž¬ ìƒíƒœë§Œ 복제ë©ë‹ˆë‹¤.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation>&lt;b&gt;현재 머신 ë° ëª¨ë“  ìžì‹ ìƒíƒœ&lt;/b&gt;를 ì„ íƒí•˜ë©´ 현재 ê°€ìƒ ë¨¸ì‹ ì˜ ìƒíƒœì™€ 모든 ìžì‹ ìƒíƒœ ìŠ¤ëƒ…ìƒ·ì„ ë³µì œí•©ë‹ˆë‹¤.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation>&lt;b&gt;모든 ìƒíƒœ&lt;/b&gt;를 ì„ íƒí•˜ë©´ 현재 머신 ìƒíƒœì™€ 모든 ìŠ¤ëƒ…ìƒ·ì„ ë³µì œí•©ë‹ˆë‹¤.</translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -643,7 +728,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE 네트워í¬, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE 네트워í¬, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -769,6 +854,26 @@
<comment>details report</comment>
<translation>설명</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation>실행 제한</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>ì¼ë°˜ 드ë¼ì´ë²„, &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation>ì¼ë°˜ 드ë¼ì´ë²„, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -949,6 +1054,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">호스트 ì´ë¦„(&amp;H):</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation>내보내기</translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1280,6 +1389,10 @@ p, li { white-space: pre-wrap; }
<source>Cancel</source>
<translation type="obsolete">취소</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation>시작</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1353,41 +1466,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>ì¼ë°˜</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>ìž…ë ¥</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>ì—…ë°ì´íЏ</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>언어</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>네트워í¬</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>확장</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1824,6 +1902,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation>ì„ íƒí•˜ë©´ VirtualBox 게스트 확장 다운로드 ë° ì—…ë°ì´íЏ í™•ì¸ ë“± 네트워í¬ë¥¼ 사용하는 ìž‘ì—…ì— ì•„ëž˜ 프ë¡ì‹œë¥¼ 사용합니다.</translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation>프ë¡ì‹œ 사용하기(&amp;E)</translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation>호스트(&amp;S):</translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation>프ë¡ì‹œ 호스트를 변경합니다.</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>í¬íЏ(&amp;P):</translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation>프ë¡ì‹œ í¬íŠ¸ë¥¼ 변경합니다.</translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation>ì„ íƒí•˜ë©´ 프ë¡ì‹œ ì„œë²„ì— ì§€ì •í•œ ì¸ì¦ 정보로 ì¸ì¦í•©ë‹ˆë‹¤.</translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation>ì¸ì¦ 사용하기(&amp;U)</translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation>ì‚¬ìš©ìž ì´ë¦„(&amp;N):</translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation>ì¸ì¦ì— 사용할 ì‚¬ìš©ìž ì´ë¦„ì„ ì„¤ì •í•©ë‹ˆë‹¤.</translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation>암호(&amp;W):</translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation>ì¸ì¦ì— 사용할 암호를 설정합니다.</translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1893,23 +2022,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>왼쪽 Shift</translation>
+ <translation type="obsolete">왼쪽 Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>오른쪽 Shift</translation>
+ <translation type="obsolete">오른쪽 Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>왼쪽 Ctrl</translation>
+ <translation type="obsolete">왼쪽 Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>오른쪽 Ctrl</translation>
+ <translation type="obsolete">오른쪽 Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>왼쪽 Alt</translation>
+ <translation type="obsolete">왼쪽 Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -1917,11 +2046,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left WinKey</source>
- <translation>왼쪽 ìœˆë„ í‚¤</translation>
+ <translation>왼쪽 Win 키</translation>
</message>
<message>
<source>Right WinKey</source>
- <translation>오른쪽 ìœˆë„ í‚¤</translation>
+ <translation>오른쪽 Win 키</translation>
</message>
<message>
<source>Menu key</source>
@@ -2126,6 +2255,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">가져오기(&amp;I) &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation>가져오기</translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2270,7 +2403,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>ì´ ê°€ìƒ ë¨¸ì‹ ì—서 사용하는 하드웨어 ê°€ìƒí™” ê¸°ëŠ¥ì˜ ìƒíƒœë¥¼ 표시합니다:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">ì´ ê°€ìƒ ë¨¸ì‹ ì—서 사용하는 하드웨어 ê°€ìƒí™” ê¸°ëŠ¥ì˜ ìƒíƒœë¥¼ 표시합니다:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2293,6 +2426,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;ì›ê²© ë°ìФí¬í†± 서버가 í¬íЏ %1ì—서 듣는 중</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation>ì´ ê°€ìƒ ë¨¸ì‹ ì˜ ì—¬ëŸ¬ 기능 ìƒíƒœë¥¼ 표시합니다:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2492,7 +2630,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>WDDM 비디오 드ë¼ì´ë²„를 사용하는 게스트 ìš´ì˜ ì²´ì œì˜ 3ì°¨ì› ê°€ì†ì„ 활성화하였습니다. 최대 ì„±ëŠ¥ì„ ìœ„í•˜ì—¬ 게스트 비디오 메모리를 최소 &lt;b&gt;%1&lt;/b&gt; ì´ìƒìœ¼ë¡œ 설정하십시오.</translation>
+ <translation type="obsolete">WDDM 비디오 드ë¼ì´ë²„를 사용하는 게스트 ìš´ì˜ ì²´ì œì˜ 3ì°¨ì› ê°€ì†ì„ 활성화하였습니다. 최대 ì„±ëŠ¥ì„ ìœ„í•˜ì—¬ 게스트 비디오 메모리를 최소 &lt;b&gt;%1&lt;/b&gt; ì´ìƒìœ¼ë¡œ 설정하십시오.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>WDDM 비디오 드ë¼ì´ë²„를 사용하는 ìš´ì˜ ì²´ì œì˜ 3ì°¨ì› ê°€ì†ì„ 활성화하였습니다. 최대 ì„±ëŠ¥ì„ ìœ„í•˜ì—¬ 게스트 비디오 메모리를 최소 &lt;b&gt;%1&lt;/b&gt; ì´ìƒìœ¼ë¡œ 설정하십시오.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation>2ì°¨ì› ê°€ì†ì„ ì„ íƒí•˜ì˜€ìŠµë‹ˆë‹¤. 2ì°¨ì› ë¹„ë””ì˜¤ ê°€ì†ì€ Windows 게스트만 ì§€ì›í•˜ë¯€ë¡œ ì´ ê¸°ëŠ¥ì€ ë¹„í™œì„±í™”ë  ê²ƒìž…ë‹ˆë‹¤.</translation>
</message>
</context>
<context>
@@ -2721,6 +2867,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>화면 ìœ„ì— ë³´ì´ê¸°(&amp;T)</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation>ì´ ê°€ìƒ ë¨¸ì‹ ì— 64비트 게스트 ìš´ì˜ì²´ì œë¥¼ 사용하려면 하드웨어 ê°€ìƒí™”(VT-x/AMD-V)ê°€ 필요하므로, ì´ ê¸°ëŠ¥ì€ ìžë™ìœ¼ë¡œ 활성화ë©ë‹ˆë‹¤.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2822,7 +2972,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>ì—°ê²° 종류가 &lt;b&gt;브리지 어댑터&lt;/b&gt; ë° &lt;b&gt;호스트 ì „ìš© 어댑터&lt;/b&gt;ì¸ ê²½ìš° 해당하는 어댑터를 ì„ íƒí•˜ì‹œê³ , &lt;b&gt;ë‚´ë¶€ 네트워í¬&lt;/b&gt;ì¸ ê²½ìš° ë‚´ë¶€ 네트워í¬ì˜ ì´ë¦„ì„ ìž…ë ¥í•˜ì‹­ì‹œì˜¤.</translation>
+ <translation type="obsolete">ì—°ê²° 종류가 &lt;b&gt;브리지 어댑터&lt;/b&gt; ë° &lt;b&gt;호스트 ì „ìš© 어댑터&lt;/b&gt;ì¸ ê²½ìš° 해당하는 어댑터를 ì„ íƒí•˜ì‹œê³ , &lt;b&gt;ë‚´ë¶€ 네트워í¬&lt;/b&gt;ì¸ ê²½ìš° ë‚´ë¶€ 네트워í¬ì˜ ì´ë¦„ì„ ìž…ë ¥í•˜ì‹­ì‹œì˜¤.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -2860,6 +3010,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>í¬íЏ í¬ì›Œë”©(&amp;P)</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation>무작위 모드(&amp;P):</translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation>ë‚´ë¶€ 네트워í¬, 호스트 ì „ìš© 네트워í¬, ë¸Œë¦¬ì§€ì— ì—°ê²°ë˜ì—ˆì„ 때 ë„¤íŠ¸ì›Œí¬ ì–´ëŒ‘í„°ì˜ ë¬´ìž‘ìœ„ 모드를 ì„ íƒí•©ë‹ˆë‹¤.</translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation>ì¼ë°˜ ì†ì„±:</translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation>사용할 ë„¤íŠ¸ì›Œí¬ ë“œë¼ì´ë²„ì˜ ì„¤ì • ì‚¬í•­ì„ ìž…ë ¥í•˜ì‹­ì‹œì˜¤. 설정 ì‚¬í•­ì€ ë“œë¼ì´ë²„마다 다르며 &lt;b&gt;ì´ë¦„=ê°’&lt;/b&gt; 형ì‹ì„ 가집니다. 새 í•­ëª©ì„ ìž…ë ¥í•˜ë ¤ë©´ &lt;b&gt;Shift+Enter&lt;/b&gt; 키를 누르십시오.</translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation>ì¼ë°˜ 드ë¼ì´ë²„ê°€ ì„ íƒë˜ì§€ 않았ìŒ</translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation>ì´ ë„¤íŠ¸ì›Œí¬ ì¹´ë“œì˜ íŠ¸ëž˜í”½ì„ ë‹´ë‹¹í•  호스트 ì‹œìŠ¤í…œì˜ ë„¤íŠ¸ì›Œí¬ ì–´ëŒ‘í„°ë¥¼ ì„ íƒí•˜ì‹­ì‹œì˜¤.</translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation>ì´ ë„¤íŠ¸ì›Œí¬ ì¹´ë“œë¥¼ ì—°ê²°í•  ë‚´ë¶€ 네트워í¬ì˜ ì´ë¦„ì„ ìž…ë ¥í•˜ì‹­ì‹œì˜¤. ì´ ê°€ìƒ ë¨¸ì‹ ì´ë‚˜ 다른 ê°€ìƒ ë¨¸ì‹ ì— ì‚¬ìš©ë˜ì§€ 않는 ì´ë¦„ì„ ìž…ë ¥í•˜ë©´ 새 ë‚´ë¶€ 네트워í¬ë¥¼ 만들 수 있습니다.</translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation>ì´ ë„¤íŠ¸ì›Œí¬ ì¹´ë“œì˜ íŠ¸ëž˜í”½ì„ ë‹´ë‹¹í•  호스트 ì‹œìŠ¤í…œì˜ ê°€ìƒ ë„¤íŠ¸ì›Œí¬ ì–´ëŒ‘í„°ë¥¼ ì„ íƒí•˜ì‹­ì‹œì˜¤. ê°€ìƒ ë¨¸ì‹  ê´€ë¦¬ìž ì°½ì˜ ì „ì—­ ë„¤íŠ¸ì›Œí¬ ì„¤ì •ì—서 어댑터를 추가하거나 삭제할 수 있습니다.</translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation>ì´ ë„¤íŠ¸ì›Œí¬ ì¹´ë“œì— ì‚¬ìš©í•  드ë¼ì´ë²„를 ì„ íƒí•˜ì‹­ì‹œì˜¤.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3371,7 +3557,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>&lt;i&gt;%1&lt;/i&gt;ì˜ í•˜ë“œë””ìŠ¤í¬ê°€ ì„ íƒë˜ì§€ 않았습니다.</translation>
+ <translation type="obsolete">&lt;i&gt;%1&lt;/i&gt;ì˜ í•˜ë“œë””ìŠ¤í¬ê°€ ì„ íƒë˜ì§€ 않았습니다.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3645,6 +3831,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation>ê°€ìƒ í”Œë¡œí”¼ ë””ìŠ¤í¬ íŒŒì¼ ì„ íƒ...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation>ì„ íƒí•˜ë©´ 게스트 ìš´ì˜ ì²´ì œì—서 미디어를 꺼낼 때 마운트를 해제하지 않습니다.</translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation>ë¼ì´ë¸Œ CD/DVD(&amp;L)</translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation>ì„ íƒí•˜ë©´ ì´ ë¯¸ë””ì–´ë¥¼ SSD로 표시합니다.</translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation>SSD(&amp;S)</translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation>ì •ë³´:</translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>위치 &lt;b&gt;%1&lt;/b&gt;ì— ìžˆëŠ” ì»¨íŠ¸ë¡¤ëŸ¬ì˜ ì´ë¦„ì´ ì§€ì •ë˜ì§€ 않았습니다.</translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation>위치 &lt;b&gt;%1&lt;/b&gt;ì— ìžˆëŠ” ì»¨íŠ¸ë¡¤ëŸ¬ì˜ ì´ë¦„ì´ ìœ„ì¹˜ &lt;b&gt;%2&lt;/b&gt;ì— ìžˆëŠ” 컨트롤러ì—서 사용 중입니다.</translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation>&lt;i&gt;%1&lt;/i&gt;ì˜ í•˜ë“œë””ìŠ¤í¬ê°€ ì„ íƒë˜ì§€ 않았습니다.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation>최대 1개만 ì§€ì›í•¨</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation>최대 %1개까지 ì§€ì›í•¨</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation>%1 ì¹©ì…‹ì´ ì§€ì›í•˜ëŠ” 갯수 ì´ìƒì˜ 저장소 컨트롤러를 사용하고 있습니다. 시스템 설정 페ì´ì§€ì—서 칩셋 종류를 바꾸거나 저장소 설정 페ì´ì§€ì˜ ë‹¤ìŒ ì €ìž¥ì†Œ ì»¨íŠ¸ë¡¤ëŸ¬ì˜ ê°¯ìˆ˜ë¥¼ 줄ì´ì‹­ì‹œì˜¤: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3740,7 +3980,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>When checked, the virtual machine will support the Input Output APIC (IO APIC), which may slightly decrease performance. &lt;b&gt;Note:&lt;/b&gt; don&apos;t disable this feature after having installed a Windows guest operating system!</source>
- <translation>ì„ íƒí•˜ë©´ ê°€ìƒ ë¨¸ì‹ ì—서 IO APIC를 사용합니다. ì´ ê²½ìš° ê°€ìƒ ë¨¸ì‹ ì˜ ì„±ëŠ¥ì´ ì €í•˜ë  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. &lt;b&gt;주ì˜:&lt;/b&gt; 게스트 ìš´ì˜ì²´ì œë¡œ 윈ë„를 설치한 í›„ì— ì´ ê¸°ëŠ¥ì„ ë„ì§€ 마십시오!</translation>
+ <translation>ì„ íƒí•˜ë©´ ê°€ìƒ ë¨¸ì‹ ì—서 IO APIC를 사용합니다. ì´ ê²½ìš° ê°€ìƒ ë¨¸ì‹ ì˜ ì„±ëŠ¥ì´ ì €í•˜ë  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. &lt;b&gt;주ì˜:&lt;/b&gt; 게스트 ìš´ì˜ì²´ì œë¡œ Windows를 설치한 í›„ì— ì´ ê¸°ëŠ¥ì„ ë„ì§€ 마십시오!</translation>
</message>
<message>
<source>Enable &amp;IO APIC</source>
@@ -3835,6 +4075,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>ì´ ê°€ìƒ ë¨¸ì‹ ì— ICH9 ì¹©ì…‹ì„ ì‚¬ìš©í•˜ê¸°ë¡œ ì„ íƒí•˜ì˜€ìŠµë‹ˆë‹¤. IO APIC ê¸°ëŠ¥ì„ í™œì„±í™”í•˜ì§€ 않으면 ìž‘ë™í•˜ì§€ ì•Šì„ ê²ƒìž…ë‹ˆë‹¤. í™•ì¸ ë‹¨ì¶”ë¥¼ 누르면 ê°€ìƒ ë¨¸ì‹  설정ì—서 IO APIC를 켤 것입니다.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation>실행 제한(&amp;E):</translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation>ê°€ìƒ CPUê°€ ì‹¤í–‰ë  ìˆ˜ 있는 ì‹œê°„ì„ ì œí•œí•©ë‹ˆë‹¤. ê°ê° ê°€ìƒ ë¨¸ì‹ ì€ ì‹¤ì œ ë¬¼ë¦¬ì  CPUì˜ ë‹¤ìŒ ë°±ë¶„ìœ¨ ì´ìƒìœ¼ë¡œ 프로세싱 ì‹œê°„ì„ ì‚¬ìš©í•  수 없습니다. 실행 제한 ì„¤ì •ì„ ë¹„í™œì„±í™”í•˜ë ¤ë©´ 100%로 설정하십시오. 실행 제한 ë¹„ìœ¨ì„ ë„ˆë¬´ 낮게 잡으면 ê°€ìƒ ë¨¸ì‹ ì´ ëŠë¦¬ê²Œ ìž‘ë™í•  수 있습니다.</translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation>실행 ì œí•œì„ ë„ˆë¬´ 낮게 설정하였습니다. ê°€ìƒ ë¨¸ì‹ ì´ ëŠë¦¬ê²Œ ìž‘ë™í•  수 있습니다.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation>USB HID를 활성화했습니다. USB ì—뮬레ì´ì…˜ì´ 활성화ë˜ì–´ì•¼ 하므로, ê°€ìƒ ë¨¸ì‹  ì„¤ì •ì„ ì €ìž¥í•  때 ìžë™ìœ¼ë¡œ 활성화ë©ë‹ˆë‹¤.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation>&lt;qt&gt;%1%&lt;/qt&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation>&lt;qt&gt;%1%&lt;/qt&gt;</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3961,6 +4227,10 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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="obsolete">현재 ê°€ìƒ ë¨¸ì‹ ì—서 USB 2.0ì„ ì‚¬ìš©í•  수 있으나, &lt;b&gt;%1&lt;/b&gt;ì„(를) 설치해야 합니다. VirtualBox 다운로드 사ì´íЏì—서 확장 기능 패키지를 설치하면 USB 2.0ì„ ì‚¬ìš©í•  수 있습니다. ì´ëŒ€ë¡œ 변경 ì‚¬í•­ì„ ì €ìž¥í•˜ë©´ 확장 기능 패키지를 설치하기 전까지 USB 2.0ì„ ì‚¬ìš©í•  수 없습니다.</translation>
+ </message>
+ <message>
+ <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>현재 ê°€ìƒ ë¨¸ì‹ ì—서 USB 2.0ì„ ì‚¬ìš©í•  수 있으나, &lt;b&gt;%1&lt;/b&gt;ì„(를) 설치해야 합니다. VirtualBox 다운로드 사ì´íЏì—서 확장 기능 패키지를 설치하면 USB 2.0ì„ ì‚¬ìš©í•  수 있습니다. ì´ëŒ€ë¡œ 변경 ì‚¬í•­ì„ ì €ìž¥í•˜ë©´ 확장 기능 패키지를 설치하기 전까지 USB 2.0ì„ ì‚¬ìš©í•  수 없습니다.</translation>
</message>
</context>
@@ -4074,6 +4344,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation>미디어 ì†ì„± 수정</translation>
+ </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;&lt;b&gt;%1&lt;/b&gt;ì˜ ê°€ìƒ ë””ìŠ¤í¬ ì†ì„±ì„ 수정할 것입니다.&lt;/p&gt;&lt;p&gt;미디어 종류 중 하나를 ì„ íƒí•˜ì‹œê³ , ê³„ì† ì§„í–‰í•˜ë ¤ë©´ &lt;b&gt;%2&lt;/b&gt;, 취소하려면 &lt;b&gt;%3&lt;/b&gt;ì„(를) 누르십시오.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation>미디어 종류 ì„ íƒ:</translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4119,7 +4404,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>새 ê°€ìƒ ë””ìŠ¤í¬ ë§Œë“¤ê¸°</translation>
@@ -4134,7 +4419,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">요약</translation>
+ <translation>요약</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4146,7 +4431,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">새 í•˜ë“œë””ìŠ¤í¬ ì´ë¯¸ì§€ 파ì¼ì„ ì„ íƒí•˜ì‹­ì‹œì˜¤</translation>
+ <translation>새 í•˜ë“œë””ìŠ¤í¬ ì´ë¯¸ì§€ 파ì¼ì„ ì„ íƒí•˜ì‹­ì‹œì˜¤</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -4168,12 +4453,12 @@ p, li { white-space: pre-wrap; }
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">위치</translation>
+ <translation>위치</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">í¬ê¸°</translation>
+ <translation>í¬ê¸°</translation>
</message>
<message>
<source>Bytes</source>
@@ -4232,108 +4517,280 @@ p, li { white-space: pre-wrap; }
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">만약 위 ì„¤ì •ì´ ì˜¬ë°”ë¥´ë‹¤ë©´ &lt;b&gt;마침&lt;/b&gt; 단추를 누르십시오. 완료 단추를 누르면 새 ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ê°€ ìƒì„±ë©ë‹ˆë‹¤. </translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation>사본_%1</translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation>만들기</translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation>ê°€ìƒ ë””ìŠ¤í¬ ë³µì‚¬</translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation>복사</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation>ê°€ìƒ ë””ìŠ¤í¬ ë³µì‚¬ ë§ˆë²•ì‚¬ì— ì˜¤ì‹  ê²ƒì„ í™˜ì˜í•©ë‹ˆë‹¤</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;ì´ ë§ˆë²•ì‚¬ëŠ” ê°€ìƒ ë””ìŠ¤í¬ ë³µì‚¬ë¥¼ ë„와 ì¤ë‹ˆë‹¤.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation>복사할 ê°€ìƒ ë””ìŠ¤í¬ë¥¼ ì„ íƒí•˜ì‹­ì‹œì˜¤. 목ë¡ì—서 ì„ íƒí•˜ê±°ë‚˜ ëª©ë¡ ì˜†ì˜ í´ë” ì•„ì´ì½˜ì„ 눌러서 복사할 ë””ìŠ¤í¬ íŒŒì¼ì„ 지정할 수 있습니다.</translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation>VDI (VirtualBox ë””ìŠ¤í¬ ì´ë¯¸ì§€)(&amp;V)</translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation>VMDK (ê°€ìƒ ë¨¸ì‹  디스í¬)(&amp;M)</translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation>VHD (ê°€ìƒ í•˜ë“œ 디스í¬)(&amp;H)</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation>ê°€ìƒ ë””ìŠ¤í¬ ìƒì„± ë§ˆë²•ì‚¬ì— ì˜¤ì‹  ê²ƒì„ í™˜ì˜í•©ë‹ˆë‹¤</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;ì´ ë§ˆë²•ì‚¬ëŠ” ê°€ìƒ ë¨¸ì‹ ì— ì‚¬ìš©í•  새 ê°€ìƒ ë””ìŠ¤í¬ë¥¼ 만드는 ê²ƒì„ ë„와 ì¤ë‹ˆë‹¤.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;새 ê°€ìƒ ë””ìŠ¤í¬ íŒŒì¼ í˜•ì‹ì„ ì„ íƒí•˜ì‹­ì‹œì˜¤. 다른 ê°€ìƒí™” 소프트웨어ì—서 디스í¬ë¥¼ 사용하지 않으려면 ì„ íƒì„ 변경하지 ì•Šì•„ë„ ë©ë‹ˆë‹¤.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation>ê°€ìƒ ë””ìŠ¤í¬ íŒŒì¼ í˜•ì‹</translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation>새 ê°€ìƒ ë””ìŠ¤í¬ íŒŒì¼ í˜•ì‹ì„ ì„ íƒí•˜ì‹­ì‹œì˜¤. 다른 ê°€ìƒí™” 소프트웨어ì—서 디스í¬ë¥¼ 사용하지 않으려면 ì„ íƒì„ 변경하지 ì•Šì•„ë„ ë©ë‹ˆë‹¤.</translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation>ê°€ìƒ ë””ìŠ¤í¬ ì €ìž¥ì†Œ 설정</translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation>ê°€ìƒ ë””ìŠ¤í¬ íŒŒì¼ì„ 사용할 때 확장할 ì§€, 미리 지정한 í¬ê¸°ë¡œ 만들지 ì„ íƒí•˜ì‹­ì‹œì˜¤.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;&lt;b&gt;ë™ì  할당&lt;/b&gt; ê°€ìƒ ë””ìŠ¤í¬ëŠ” ê°€ìƒ ë””ìŠ¤í¬ë¥¼ 사용할 때 íŒŒì¼ í¬ê¸°ê°€ 커지지만, ì‚¬ìš©ëŸ‰ì´ ì¤„ì–´ë“¤ì–´ë„ ìž‘ì•„ì§€ì§€ëŠ” 않습니다.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;&lt;b&gt;ê³ ì • í¬ê¸°&lt;/b&gt; ê°€ìƒ ë””ìŠ¤í¬ëŠ” 만드는 ë° ë” ì˜¤ëž˜ 걸리지만 사용할 때 ë” ë¹ ë¦…ë‹ˆë‹¤.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation>&lt;p&gt;ê°€ìƒ ë””ìŠ¤í¬ë¥¼ 2GB íŒŒì¼ ì—¬ëŸ¬ 개로 &lt;b&gt;ë¶„í• &lt;/b&gt;í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. í° íŒŒì¼ì„ 처리할 수 없는 시스템ì´ë‚˜ ì´ë™ì‹ ë””ìŠ¤í¬ ë“±ì— ê°€ìƒ ë¨¸ì‹ ì„ ì €ìž¥í•  때 유용합니다.</translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation>ë™ì  할당(&amp;D)</translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation>ê³ ì • í¬ê¸°(&amp;F)</translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation>2GB 단위로 분할하기(&amp;S)</translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation>ê°€ìƒ ë””ìŠ¤í¬ íŒŒì¼ ìœ„ì¹˜ì™€ í¬ê¸°</translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation>ê°€ìƒ ë””ìŠ¤í¬ì˜ í¬ê¸°ë¥¼ 메가바ì´íЏ 단위로 지정하십시오. ì´ í¬ê¸°ëŠ” 게스트 ìš´ì˜ì²´ì œì— ê°€ìƒ ë””ìŠ¤í¬ì˜ í¬ê¸°ë¡œ 보여집니다.</translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation>ê°€ìƒ ë””ìŠ¤í¬ íŒŒì¼ ìœ„ì¹˜</translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation>&lt;b&gt;ì„ íƒ&lt;/b&gt; 단추를 눌러서 ê°€ìƒ ë””ìŠ¤í¬ ë°ì´í„°ë¥¼ 저장할 경로와 íŒŒì¼ ì´ë¦„ì„ ì§€ì •í•˜ê±°ë‚˜ íŒŒì¼ ì´ë¦„ì„ ì§ì ‘ 입력하십시오.</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation>&lt;nobr&gt;%1 (%2 ë°”ì´íЏ)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation>ë‹¤ìŒ ì„¤ì •ì„ ì‚¬ìš©í•˜ì—¬ 새 ê°€ìƒ ë””ìŠ¤í¬ë¥¼ 만듭니다:</translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation>ë‹¤ìŒ ì„¤ì •ì„ ì‚¬ìš©í•˜ì—¬ ë³µì œëœ ê°€ìƒ ë””ìŠ¤í¬ë¥¼ 만듭니다:</translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation>위 ì„¤ì •ì´ ì˜¬ë°”ë¥´ë‹¤ë©´ &lt;b&gt;%1&lt;/b&gt; 단추를 누르십시오. ì´ ë‹¨ì¶”ë¥¼ 누르면 새 ê°€ìƒ ë””ìŠ¤í¬ê°€ ìƒì„±ë©ë‹ˆë‹¤.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 ë°”ì´íЏ</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation>íŒŒì¼ í˜•ì‹</translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation>ì •ë³´</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation>íŒŒì¼ í˜•ì‹</translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation>위치(&amp;L)</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation>í¬ê¸°(&amp;S)</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation>저장소 정보</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>새 ê°€ìƒ ë””ìŠ¤í¬ ìƒì„± ë§ˆë²•ì‚¬ì— ì˜¤ì‹  ê²ƒì„ í™˜ì˜í•©ë‹ˆë‹¤!</translation>
+ <translation type="obsolete">새 ê°€ìƒ ë””ìŠ¤í¬ ìƒì„± ë§ˆë²•ì‚¬ì— ì˜¤ì‹  ê²ƒì„ í™˜ì˜í•©ë‹ˆë‹¤!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;ì´ ë§ˆë²•ì‚¬ëŠ” ê°€ìƒ ë¨¸ì‹ ì— ìƒˆë¡œìš´ 하드디스í¬ë¥¼ 만드는 ê³¼ì •ì„ ë„와ì¤ë‹ˆë‹¤.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;ì´ ë§ˆë²•ì‚¬ëŠ” ê°€ìƒ ë¨¸ì‹ ì— ìƒˆë¡œìš´ 하드디스í¬ë¥¼ 만드는 ê³¼ì •ì„ ë„와ì¤ë‹ˆë‹¤.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation>복사할 ê°€ìƒ ë””ìŠ¤í¬</translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation>ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ íŒŒì¼ ì„ íƒ...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;ë§Œë“¤ê³ ìž í•˜ëŠ” ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ ì´ë¯¸ì§€ì˜ 종류를 ì„ íƒí•˜ì‹­ì‹œì˜¤.&lt;/p&gt;&lt;p&gt;&lt;b&gt;ë™ì  확장 저장소&lt;/b&gt;는 ì²˜ìŒ ë§Œë“¤ì—ˆì„ ë•Œ 아주 ìž‘ì€ ê³µê°„ë§Œ 차지합니다. 게스트 ìš´ì˜ì²´ì œì—서 ë””ìŠ¤í¬ ê³µê°„ì„ ì‚¬ìš©í•˜ë©´ ë””ìŠ¤í¬ ì´ë¯¸ì§€ 파ì¼ì€ ì—¬ê¸°ì— ì§€ì •í•œ í¬ê¸°ê¹Œì§€ 커집니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;ê³ ì • í¬ê¸° 저장소&lt;/b&gt;ì˜ í¬ê¸°ëŠ” 변하지 않습니다. ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ì™€ ê±°ì˜ ê°™ì€ í¬ê¸°ì˜ ì´ë¯¸ì§€ 파ì¼ì— 저장ë©ë‹ˆë‹¤. 하드디스í¬ì˜ 쓰기 성능과 저장소 í¬ê¸°ì— ë”°ë¼ì„œ ìƒì„± ì‹œê°„ì´ ë‹¬ë¼ì§ˆ 수 있습니다.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;ë§Œë“¤ê³ ìž í•˜ëŠ” ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ ì´ë¯¸ì§€ì˜ 종류를 ì„ íƒí•˜ì‹­ì‹œì˜¤.&lt;/p&gt;&lt;p&gt;&lt;b&gt;ë™ì  확장 저장소&lt;/b&gt;는 ì²˜ìŒ ë§Œë“¤ì—ˆì„ ë•Œ 아주 ìž‘ì€ ê³µê°„ë§Œ 차지합니다. 게스트 ìš´ì˜ì²´ì œì—서 ë””ìŠ¤í¬ ê³µê°„ì„ ì‚¬ìš©í•˜ë©´ ë””ìŠ¤í¬ ì´ë¯¸ì§€ 파ì¼ì€ ì—¬ê¸°ì— ì§€ì •í•œ í¬ê¸°ê¹Œì§€ 커집니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;ê³ ì • í¬ê¸° 저장소&lt;/b&gt;ì˜ í¬ê¸°ëŠ” 변하지 않습니다. ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ì™€ ê±°ì˜ ê°™ì€ í¬ê¸°ì˜ ì´ë¯¸ì§€ 파ì¼ì— 저장ë©ë‹ˆë‹¤. 하드디스í¬ì˜ 쓰기 성능과 저장소 í¬ê¸°ì— ë”°ë¼ì„œ ìƒì„± ì‹œê°„ì´ ë‹¬ë¼ì§ˆ 수 있습니다.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>저장소 종류</translation>
+ <translation type="obsolete">저장소 종류</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>ë™ì  확장 저장소(&amp;D)</translation>
+ <translation type="obsolete">ë™ì  확장 저장소(&amp;D)</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>ê³ ì • í¬ê¸° 저장소(&amp;F)</translation>
+ <translation type="obsolete">ê³ ì • í¬ê¸° 저장소(&amp;F)</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>í•˜ë“œë””ìŠ¤í¬ ì €ìž¥ì†Œ 종류</translation>
+ <translation type="obsolete">í•˜ë“œë””ìŠ¤í¬ ì €ìž¥ì†Œ 종류</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;&lt;b&gt;ì„ íƒ&lt;/b&gt; 단추를 눌러서 í•˜ë“œë””ìŠ¤í¬ ë°ì´í„°ë¥¼ 저장할 경로와 íŒŒì¼ ì´ë¦„ì„ ì§€ì •í•˜ê±°ë‚˜ íŒŒì¼ ì´ë¦„ì„ ì§ì ‘ 입력하십시오.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;&lt;b&gt;ì„ íƒ&lt;/b&gt; 단추를 눌러서 í•˜ë“œë””ìŠ¤í¬ ë°ì´í„°ë¥¼ 저장할 경로와 íŒŒì¼ ì´ë¦„ì„ ì§€ì •í•˜ê±°ë‚˜ íŒŒì¼ ì´ë¦„ì„ ì§ì ‘ 입력하십시오.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>위치(&amp;L)</translation>
+ <translation type="obsolete">위치(&amp;L)</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ì˜ í¬ê¸°ë¥¼ 메가바ì´íЏ 단위로 지정하십시오. ì´ í¬ê¸°ëŠ” 게스트 ìš´ì˜ì²´ì œê°€ ì¸ì‹í•˜ëŠ” ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ì˜ í¬ê¸°ìž…니다.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ì˜ í¬ê¸°ë¥¼ 메가바ì´íЏ 단위로 지정하십시오. ì´ í¬ê¸°ëŠ” 게스트 ìš´ì˜ì²´ì œê°€ ì¸ì‹í•˜ëŠ” ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ì˜ í¬ê¸°ìž…니다.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>í¬ê¸°(&amp;S)</translation>
+ <translation type="obsolete">í¬ê¸°(&amp;S)</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>ê°€ìƒ ë””ìŠ¤í¬ ìœ„ì¹˜ì™€ í¬ê¸°</translation>
+ <translation type="obsolete">ê°€ìƒ ë””ìŠ¤í¬ ìœ„ì¹˜ì™€ í¬ê¸°</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>새 í•˜ë“œë””ìŠ¤í¬ ì´ë¯¸ì§€ 파ì¼ì„ ì„ íƒí•˜ì‹­ì‹œì˜¤</translation>
+ <translation type="obsolete">새 í•˜ë“œë””ìŠ¤í¬ ì´ë¯¸ì§€ 파ì¼ì„ ì„ íƒí•˜ì‹­ì‹œì˜¤</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>í•˜ë“œë””ìŠ¤í¬ ì´ë¯¸ì§€ (*.vdi)</translation>
+ <translation type="obsolete">í•˜ë“œë””ìŠ¤í¬ ì´ë¯¸ì§€ (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 ë°”ì´íЏ)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 ë°”ì´íЏ)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>ë‹¤ìŒ ì„¤ì •ì„ ì‚¬ìš©í•˜ì—¬ 새 ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ë¥¼ 만듭니다:</translation>
+ <translation type="obsolete">ë‹¤ìŒ ì„¤ì •ì„ ì‚¬ìš©í•˜ì—¬ 새 ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ë¥¼ 만듭니다:</translation>
</message>
<message>
<source>Summary</source>
- <translation>요약</translation>
+ <translation type="obsolete">요약</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 ë°”ì´íЏ</translation>
+ <translation type="obsolete">%1 ë°”ì´íЏ</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>종류</translation>
+ <translation type="obsolete">종류</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>위치</translation>
+ <translation type="obsolete">위치</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>í¬ê¸°</translation>
+ <translation type="obsolete">í¬ê¸°</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>만약 위 ì„¤ì •ì´ ì˜¬ë°”ë¥´ë‹¤ë©´ &lt;b&gt;%1&lt;/b&gt; 단추를 누르십시오. 단추를 누르면 새 ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ê°€ ìƒì„±ë©ë‹ˆë‹¤. </translation>
+ <translation type="obsolete">만약 위 ì„¤ì •ì´ ì˜¬ë°”ë¥´ë‹¤ë©´ &lt;b&gt;%1&lt;/b&gt; 단추를 누르십시오. 단추를 누르면 새 ê°€ìƒ í•˜ë“œë””ìŠ¤í¬ê°€ ìƒì„±ë©ë‹ˆë‹¤. </translation>
</message>
</context>
<context>
@@ -4463,6 +4920,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">기존 하드 ë””ìŠ¤í¬ ì‚¬ìš©í•˜ê¸°(&amp;U)</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation>만들기</translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4696,6 +5157,120 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>ì¼ë°˜</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>ìž…ë ¥</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>ì—…ë°ì´íЏ</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>언어</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>네트워í¬</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>확장</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation>프ë¡ì‹œ</translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>ì¼ë°˜</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>시스템</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>디스플레ì´</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>저장소</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>오디오</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>네트워í¬</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>í¬íЏ</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>ì§ë ¬ í¬íЏ</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>병렬 í¬íЏ</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>공유 í´ë”</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">ì´ ê°€ìƒ ë¨¸ì‹ ì— 64비트 게스트 ìš´ì˜ì²´ì œë¥¼ 사용하려면 하드웨어 ê°€ìƒí™”(VT-x/AMD-V)ê°€ 필요하므로, ì´ ê¸°ëŠ¥ì€ ìžë™ìœ¼ë¡œ 활성화ë©ë‹ˆë‹¤.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">2ì°¨ì› ê°€ì†ì„ ì„ íƒí•˜ì˜€ìŠµë‹ˆë‹¤. 2ì°¨ì› ë¹„ë””ì˜¤ ê°€ì†ì€ ìœˆë„ ê²ŒìŠ¤íŠ¸ë§Œ ì§€ì›í•˜ë¯€ë¡œ ì´ ê¸°ëŠ¥ì€ ë¹„í™œì„±í™”ë  ê²ƒìž…ë‹ˆë‹¤.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">USB HID를 활성화했습니다. USB ì—뮬레ì´ì…˜ì´ 활성화ë˜ì–´ì•¼ 하므로, ê°€ìƒ ë¨¸ì‹  ì„¤ì •ì„ ì €ìž¥í•  때 ìžë™ìœ¼ë¡œ 활성화ë©ë‹ˆë‹¤.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">최대 1개만 ì§€ì›í•¨</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">최대 %1개까지 ì§€ì›í•¨</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">%1 ì¹©ì…‹ì´ ì§€ì›í•˜ëŠ” 개수 ì´ìƒì˜ 저장소 컨트롤러를 사용하고 있습니다. 시스템 설정 페ì´ì§€ì—서 칩셋 종류를 바꾸거나 저장소 설정 페ì´ì§€ì˜ ë‹¤ìŒ ì €ìž¥ì†Œ ì»¨íŠ¸ë¡¤ëŸ¬ì˜ ê°œìˆ˜ë¥¼ 줄ì´ì‹­ì‹œì˜¤: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -4834,81 +5409,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>ì¼ë°˜</translation>
- </message>
- <message>
- <source>System</source>
- <translation>시스템</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>디스플레ì´</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>저장소</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>오디오</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>네트워í¬</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>í¬íЏ</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>ì§ë ¬ í¬íЏ</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>병렬 í¬íЏ</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>공유 í´ë”</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>ì´ ê°€ìƒ ë¨¸ì‹ ì— 64비트 게스트 ìš´ì˜ì²´ì œë¥¼ 사용하려면 하드웨어 ê°€ìƒí™”(VT-x/AMD-V)ê°€ 필요하므로, ì´ ê¸°ëŠ¥ì€ ìžë™ìœ¼ë¡œ 활성화ë©ë‹ˆë‹¤.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>2ì°¨ì› ê°€ì†ì„ ì„ íƒí•˜ì˜€ìŠµë‹ˆë‹¤. 2ì°¨ì› ë¹„ë””ì˜¤ ê°€ì†ì€ ìœˆë„ ê²ŒìŠ¤íŠ¸ë§Œ ì§€ì›í•˜ë¯€ë¡œ ì´ ê¸°ëŠ¥ì€ ë¹„í™œì„±í™”ë  ê²ƒìž…ë‹ˆë‹¤.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>USB HID를 활성화했습니다. USB ì—뮬레ì´ì…˜ì´ 활성화ë˜ì–´ì•¼ 하므로, ê°€ìƒ ë¨¸ì‹  ì„¤ì •ì„ ì €ìž¥í•  때 ìžë™ìœ¼ë¡œ 활성화ë©ë‹ˆë‹¤.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>최대 1개만 ì§€ì›í•¨</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>최대 %1개까지 ì§€ì›í•¨</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>%1 ì¹©ì…‹ì´ ì§€ì›í•˜ëŠ” 개수 ì´ìƒì˜ 저장소 컨트롤러를 사용하고 있습니다. 시스템 설정 페ì´ì§€ì—서 칩셋 종류를 바꾸거나 저장소 설정 페ì´ì§€ì˜ ë‹¤ìŒ ì €ìž¥ì†Œ ì»¨íŠ¸ë¡¤ëŸ¬ì˜ ê°œìˆ˜ë¥¼ 줄ì´ì‹­ì‹œì˜¤: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5066,6 +5566,14 @@ p, li { white-space: pre-wrap; }
<source>Hard Disk Controller (SAS)</source>
<translation>하드 ë””ìŠ¤í¬ ì»¨íŠ¸ë¡¤ëŸ¬ (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>ì„ íƒí•˜ë©´ 모든 ì„¤ì •ëœ ë„¤íŠ¸ì›Œí¬ ì¹´ë“œì— ìƒˆ 고유 MAC 주소를 할당합니다.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>모든 ë„¤íŠ¸ì›Œí¬ ì¹´ë“œì˜ MAC 주소 초기화(&amp;R)</translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -6129,7 +6637,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Windows Multimedia</source>
<comment>AudioDriverType</comment>
- <translation>ìœˆë„ ë©€í‹°ë¯¸ë””ì–´</translation>
+ <translation>Windows 멀티미디어</translation>
</message>
<message>
<source>OSS Audio Driver</source>
@@ -6144,7 +6652,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Windows DirectSound</source>
<comment>AudioDriverType</comment>
- <translation>ìœˆë„ DirectSound</translation>
+ <translation>Windows DirectSound</translation>
</message>
<message>
<source>CoreAudio</source>
@@ -6467,7 +6975,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>어댑터 %1</translation>
+ <translation type="obsolete">어댑터 %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -6923,7 +7431,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE 네트워í¬, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE 네트워í¬, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -6933,7 +7441,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>VDE 어댑터</translation>
+ <translation type="obsolete">VDE 어댑터</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -7130,6 +7638,61 @@ p, li { white-space: pre-wrap; }
<comment>DiskType</comment>
<translation>다중 연결 가능</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation>ë™ì  확장 저장소</translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation>ê³ ì • í¬ê¸° 저장소</translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation>2GB 단위로 나뉘어 있는 ë™ì  할당 저장소</translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation>2GB 단위로 나뉘어 있는 ê³ ì • í¬ê¸° 저장소</translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation>실행 제한</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation>&lt;nobr&gt;%1%&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>ì¼ë°˜, &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation>ì¼ë°˜ 드ë¼ì´ë²„</translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>ê±°ë¶€</translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>ê°€ìƒ ë¨¸ì‹ ì— í—ˆìš©</translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>ëª¨ë‘ í—ˆìš©</translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation>어댑터 %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7292,15 +7855,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Location</source>
- <translation>위치</translation>
+ <translation type="obsolete">위치</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>종류 (형ì‹)</translation>
+ <translation type="obsolete">종류 (형ì‹)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>다ìŒì— ì—°ê²°ë¨</translation>
+ <translation type="obsolete">다ìŒì— ì—°ê²°ë¨</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -7382,17 +7945,17 @@ p, li { white-space: pre-wrap; }
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>다ìŒì— ì—°ê²°ë¨</translation>
+ <translation type="obsolete">다ìŒì— ì—°ê²°ë¨</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>다ìŒì— ì—°ê²°ë¨</translation>
+ <translation type="obsolete">다ìŒì— ì—°ê²°ë¨</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>다ìŒì— ì—°ê²°ë¨</translation>
+ <translation type="obsolete">다ìŒì— ì—°ê²°ë¨</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -7410,6 +7973,46 @@ p, li { white-space: pre-wrap; }
<source>All %1 images (%2)</source>
<translation>모든 %1 ì´ë¯¸ì§€ (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation>종류:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation>위치:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation>형ì‹:</translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation>저장소 정보:</translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation>다ìŒì— ì—°ê²°ë¨:</translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation>복사(&amp;C)...</translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation>수정(&amp;M)...</translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation>존재하는 미디어 복사</translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation>ì„ íƒí•œ 미디어 ì†ì„± 수정</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>닫기(&amp;L)</translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -7434,7 +8037,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>ë„¤íŠ¸ì›Œí¬ ì–´ëŒ‘í„°</translation>
+ <translation type="obsolete">ë„¤íŠ¸ì›Œí¬ ì–´ëŒ‘í„°</translation>
</message>
</context>
<context>
@@ -8119,7 +8722,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>호스트 ì‹œìŠ¤í…œì˜ USBì— ì ‘ê·¼í•  수 없습니다. 게스트 시스템ì—서 USB를 사용하려면 USB íŒŒì¼ ì‹œìŠ¤í…œ(usbfs), D-Bus/HAL 서비스 둘 중 하나를 활성화한 ë‹¤ìŒ VirtualBox를 다시 시작하십시오.</translation>
+ <translation type="obsolete">호스트 ì‹œìŠ¤í…œì˜ USBì— ì ‘ê·¼í•  수 없습니다. 게스트 시스템ì—서 USB를 사용하려면 USB íŒŒì¼ ì‹œìŠ¤í…œ(usbfs), D-Bus/HAL 서비스 둘 중 하나를 활성화한 ë‹¤ìŒ VirtualBox를 다시 시작하십시오.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -8240,7 +8843,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;스냅샷 &lt;b&gt;%1&lt;/b&gt;(으)로 ë˜ëŒë¦¬ì‹œê² ìŠµë‹ˆê¹Œ? 현재 ê°€ìƒ ë¨¸ì‹  ìƒíƒœê°€ ì‚­ì œë˜ë©°, 복구할 수 없습니다.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;스냅샷 &lt;b&gt;%1&lt;/b&gt;(으)로 ë˜ëŒë¦¬ì‹œê² ìŠµë‹ˆê¹Œ? 현재 ê°€ìƒ ë¨¸ì‹  ìƒíƒœê°€ ì‚­ì œë˜ë©°, 복구할 수 없습니다.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -8538,7 +9141,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">ì¼ë°˜ 오류가 ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤.</translation>
+ <translation>ì¼ë°˜ 오류가 ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤.</translation>
</message>
<message>
<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>
@@ -8627,7 +9230,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>ì¶©ëŒì„ 방지하기 위하여 64비트 윈ë„ì—서는 ê°€ìƒ ë¨¸ì‹ ì— ì†í•´ 있는 모든 파ì¼ì„ 삭제할 수 없습니다. ê³§ 수정하겠습니다.</translation>
+ <translation type="obsolete">ì¶©ëŒì„ 방지하기 위하여 64비트 윈ë„ì—서는 ê°€ìƒ ë¨¸ì‹ ì— ì†í•´ 있는 모든 파ì¼ì„ 삭제할 수 없습니다. ê³§ 수정하겠습니다.</translation>
</message>
<message>
<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>
@@ -8635,8 +9238,72 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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="obsolete">&lt;p&gt;현재 ê°€ìƒ ë¨¸ì‹ ì—서 USB 2.0ì„ ì‚¬ìš©í•  수 있으나, &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;ì„(를) 설치해야 합니다.&lt;/p&gt;&lt;p&gt;VirtualBox 다운로드 사ì´íЏì—서 확장 기능 패키지를 설치하면 USB 2.0ì„ ì‚¬ìš©í•  수 있습니다. ì´ëŒ€ë¡œ 변경 ì‚¬í•­ì„ ì €ìž¥í•˜ë©´ 확장 기능 패키지를 설치하기 전까지 USB 2.0ì„ ì‚¬ìš©í•  수 없습니다.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>ê°€ìƒ ë¨¸ì‹  &lt;b&gt;%1&lt;/b&gt;ì„(를) 등ë¡í•  수 없습니다.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;머신 ì„¤ì •ì„ íŽ¸ì§‘í•˜ëŠ” 중 변경ë˜ì—ˆìŠµë‹ˆë‹¤. 현재 저장ë˜ì§€ ì•Šì€ ë³€ê²½ ì‚¬í•­ì´ ìžˆìŠµë‹ˆë‹¤.&lt;/p&gt;&lt;p&gt;변경 ì‚¬í•­ì„ ë‹¤ì‹œ 불러오거나, 현재 저장ë˜ì§€ ì•Šì€ ë³€ê²½ ì‚¬í•­ì„ ìœ ì§€í•˜ì‹œê² ìŠµë‹ˆê¹Œ?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation>설정 새로 고침</translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation>변경 사항 유지</translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation>편집 ì¤‘ì¸ ê°€ìƒ ë¨¸ì‹ ì˜ ìƒíƒœê°€ 변경ë˜ì—ˆìŠµë‹ˆë‹¤. í™•ì¸ ë‹¨ì¶”ë¥¼ 누르면 실행 중 변경 가능한 설정만 저장ë˜ë©° 모든 다른 ì„¤ì •ì€ ì €ìž¥ë˜ì§€ 않습니다.</translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>ê°€ìƒ ë¨¸ì‹  &lt;b&gt;%1&lt;/b&gt;ì„(를) 복제하는 ë° ì‹¤íŒ¨í•˜ì˜€ìŠµë‹ˆë‹¤.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;스냅샷 &lt;b&gt;%1&lt;/b&gt;ì„(를) ë³µì›í•˜ë ¤ê³  합니다.&lt;/p&gt;&lt;p&gt;아래 ìƒìžë¥¼ ì„ íƒí•˜ë©´ ê°€ìƒ ë¨¸ì‹ ì˜ í˜„ìž¬ ìƒíƒœë¥¼ 스냅샷으로 저장할 수 있습니다. 현재 ìƒíƒœë¥¼ 저장하지 않으면 ë³µì›í•  수 없습니다. ê³„ì† ì§„í–‰í•˜ì‹œê² ìŠµë‹ˆê¹Œ?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation>현재 ê°€ìƒ ë¨¸ì‹  ìƒíƒœ 스냅샷 만들기</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;스냅샷 &lt;b&gt;%1&lt;/b&gt;ì„(를) ë³µì›í•˜ì‹œê² ìŠµë‹ˆê¹Œ?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;미디어 종류를 &lt;b&gt;%1&lt;/b&gt;ì—서 &lt;b&gt;%2&lt;/b&gt;(으)로 변경하는 ë° ì‹¤íŒ¨í•˜ì˜€ìŠµë‹ˆë‹¤.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <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>&lt;p&gt;현재 ê°€ìƒ ë¨¸ì‹ ì—서 USB 2.0ì„ ì‚¬ìš©í•  수 있으나, &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;ì„(를) 설치해야 합니다.&lt;/p&gt;&lt;p&gt;VirtualBox 다운로드 사ì´íЏì—서 확장 기능 패키지를 설치하면 USB 2.0ì„ ì‚¬ìš©í•  수 있습니다. ì´ëŒ€ë¡œ 변경 ì‚¬í•­ì„ ì €ìž¥í•˜ë©´ 확장 기능 패키지를 설치하기 전까지 USB 2.0ì„ ì‚¬ìš©í•  수 없습니다.&lt;/p&gt;</translation>
</message>
+ <message>
+ <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>호스트 USB 프ë¡ì‹œ 서비스를 불러올 수 없습니다(VERR_FILE_NOT_FOUND). 호스트 ì»´í“¨í„°ì— ì„œë¹„ìŠ¤ê°€ 설치ë˜ì–´ 있지 ì•Šì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤</translation>
+ </message>
+ <message>
+ <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>VirtualBoxì—서 USB ìž¥ì¹˜ì— ì ‘ê·¼í•  수 없습니다. 현재 사용ìžë¥¼ &apos;vboxusers&apos; ê·¸ë£¹ì— ì¶”ê°€í•˜ì‹­ì‹œì˜¤. ë” ìžì„¸í•œ ì„¤ëª…ì€ ì‚¬ìš©ìž ì„¤ëª…ì„œë¥¼ 참고하십시오</translation>
+ </message>
+ <message>
+ <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>VirtualBoxì—서 USB ìž¥ì¹˜ì— ì ‘ê·¼í•  수 없습니다. 현재 사용ìžê°€ &apos;usbfs&apos; í´ë” ë° íŒŒì¼ì— 접근할 수 있ë„ë¡ í•˜ì‹­ì‹œì˜¤. ë” ìžì„¸í•œ ì„¤ëª…ì€ ì‚¬ìš©ìž ì„¤ëª…ì„œë¥¼ 참고하십시오</translation>
+ </message>
+ <message>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation>USB 프ë¡ì‹œ 서비스를 현재 호스트ì—서 사용할 수 없습니다</translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation>호스트 USB 프ë¡ì‹œ 서비스를 불러올 수 ì—†ìŒ</translation>
+ </message>
</context>
<context>
<name>VBoxRegistrationDlg</name>
@@ -8749,7 +9416,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>공유 í´ë”</translation>
+ <translation type="obsolete">공유 í´ë”</translation>
</message>
</context>
<context>
@@ -8820,7 +9487,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>D&amp;iscard</source>
- <translation>삭제(&amp;I)</translation>
+ <translation type="obsolete">삭제(&amp;I)</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -9022,6 +9689,22 @@ p, li { white-space: pre-wrap; }
<source>Show Statusbar</source>
<translation>ìƒíƒœ 표시줄 ë³´ì´ê¸°</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation>복제(&amp;O)...</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>ì„ íƒí•œ ê°€ìƒ ë¨¸ì‹ ì„ ë³µì œí•©ë‹ˆë‹¤</translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation>삭제</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation>ì €ìž¥ëœ ìƒíƒœ ì‚­ì œ(&amp;I)</translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -9219,6 +9902,14 @@ p, li { white-space: pre-wrap; }
<source> (%1 ago)</source>
<translation> (%1 지남)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation>복제(&amp;C)...</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>ì„ íƒí•œ ê°€ìƒ ë¨¸ì‹ ì„ ë³µì œí•©ë‹ˆë‹¤</translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts
index 469f2b4eb..2b10504e6 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts
@@ -481,7 +481,7 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>Sesijos in&amp;formacija</translation>
+ <translation type="obsolete">Sesijos in&amp;formacija</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
@@ -497,6 +497,91 @@
<comment>debug action</comment>
<translation>&amp;KomandinÄ— eilutÄ—...</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">Nuo&amp;statos...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -662,7 +747,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE tinklas, „%1“</translation>
+ <translation type="obsolete">VDE tinklas, „%1“</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -788,6 +873,26 @@
<comment>details report</comment>
<translation>Aprašas</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -824,6 +929,10 @@
<source>Restore Defaults</source>
<translation>Atkurti pirmines reiškmes</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1019,6 +1128,10 @@
<source>First Run Wizard</source>
<translation>Pirmojo paleidimo vediklis</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1104,41 +1217,6 @@
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Bendra</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Įvestis</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Atnaujinimas</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Kalba</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Tinklas</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Papildiniai</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1545,6 +1623,57 @@
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1614,23 +1743,23 @@
</message>
<message>
<source>Left Shift</source>
- <translation>Kairysis Lyg2</translation>
+ <translation type="obsolete">Kairysis Lyg2</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Dešinysis Lyg2</translation>
+ <translation type="obsolete">Dešinysis Lyg2</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Kairysis Vald</translation>
+ <translation type="obsolete">Kairysis Vald</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Dešinysis Vald</translation>
+ <translation type="obsolete">Dešinysis Vald</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Kairysis Alt</translation>
+ <translation type="obsolete">Kairysis Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -1795,6 +1924,10 @@
<source>Restore Defaults</source>
<translation>Atkurti pirmines reiškmes</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2039,13 +2172,18 @@
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Rodo virtualizavimo procesoriaus būseną: &lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1 :&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3 :&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Rodo virtualizavimo procesoriaus būseną: &lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1 :&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3 :&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1 :&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2233,7 +2371,7 @@
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Ä®galinote 3D spartinimÄ… operacinei sistemai, kuri naudoja WDDM vaizdo tvarkyklÄ™. DidžiausiÄ… naÅ¡umÄ… pasieksite, jei vaizdo laisvosios prieigos atminÄiai paskirsite bent &lt;b&gt;%1&lt;/b&gt;. </translation>
+ <translation type="obsolete">Ä®galinote 3D spartinimÄ… operacinei sistemai, kuri naudoja WDDM vaizdo tvarkyklÄ™. DidžiausiÄ… naÅ¡umÄ… pasieksite, jei vaizdo laisvosios prieigos atminÄiai paskirsite bent &lt;b&gt;%1&lt;/b&gt;. </translation>
</message>
<message>
<source>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</source>
@@ -2243,6 +2381,14 @@
<source>&lt;qt&gt;%1&lt;/qt&gt;</source>
<translation>&lt;qt&gt;%1&lt;/qt&gt;</translation>
</message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">įgalinote 2D vaizdo spartinimÄ…. Kadangi 2D vaizdo spartinimas palaikomas tik Windows sveÄiui, pastaroji savybÄ— bus uždrausta.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsGeneral</name>
@@ -2318,6 +2464,10 @@
<source>Displays the path where snapshots of this virtual machine will be stored. Be aware that snapshots can take quite a lot of disk space.</source>
<translation>Rodo kelią, kur bus saugomos šios virtualios mašinos momentinių būvių kopijos. Atminkite, kad būvių kopijos gali užimti daug vietos.</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">pasirinkote 64 bitų sveÄio OS Å¡ioje maÅ¡inoje. Kadangi toks sveÄias reikalauja virtualizacijÄ… palaikanÄio procesoriaus (VT-x/AMD-V), pastaroji parinktis bus įgalinta automatiÅ¡kai.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2343,7 +2493,7 @@
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Parenka &lt;b&gt;tinklų tilto&lt;/b&gt; plokštę ar &lt;b&gt;plokštę prisijungimui tik prie pagrindinio kompiuterio&lt;/b&gt; arba &lt;b&gt;vidinio tinklo&lt;/b&gt; vardą.</translation>
+ <translation type="obsolete">Parenka &lt;b&gt;tinklų tilto&lt;/b&gt; plokštę ar &lt;b&gt;plokštę prisijungimui tik prie pagrindinio kompiuterio&lt;/b&gt; arba &lt;b&gt;vidinio tinklo&lt;/b&gt; vardą.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -2406,6 +2556,42 @@
<comment>network adapter name</comment>
<translation>Nepasirinkta</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsParallel</name>
@@ -2818,7 +3004,7 @@
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Neparinktas joks standusis diskas &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">Neparinktas joks standusis diskas &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -2964,6 +3150,60 @@
<source>Choose a virtual floppy disk file...</source>
<translation>Pasirinkti virtualaus diskelio rinkmenÄ…....</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">palaikoma ne daugiau kaip vienas</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">palaikoma ne daugiau kaip %1</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">naudojate daugiau laikmenų valdiklių nei palaiko %1 lustų rinkinys. TodÄ—l arba pakeiskite lustų rinkinio tipÄ… sistemos nuostatose, arba sumažinkite laikmenų valdiklių skaiÄių laikmenų nuostatose: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3137,6 +3377,32 @@
<comment>%1 is host cpu count * 2 for now</comment>
<translation>&lt;qt&gt;%1&amp;nbsp;procesoriai&lt;/qt&gt;</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished">įgalinote USB HID (žmogaus sąsajos įtaisą). Jis neveiks tol, kol neįgalinsite USB emuliacijos. Todėl pastaroji bus įgalinta automatiškai po to, kai patvirtinsite VM nuostatas mygtuku „Gerai“.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3263,7 +3529,11 @@
</message>
<message>
<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>Å ioje virtualioje maÅ¡inoje įgalintas USB 2.0. TaÄiau tam turi įdiegtas &lt;b&gt;%1&lt;/b&gt;. Ä®diegike papildinių paketÄ…, kurį rasite VirtualBox svetainÄ—je. Tuomet vÄ—l galÄ—site įgalite USB 2.0. Iki tol Å¡i funkcija bus uždrausta, nebent atsisakysite dabartinių nuostatų pakeitimų.</translation>
+ <translation type="obsolete">Å ioje virtualioje maÅ¡inoje įgalintas USB 2.0. TaÄiau tam turi įdiegtas &lt;b&gt;%1&lt;/b&gt;. Ä®diegike papildinių paketÄ…, kurį rasite VirtualBox svetainÄ—je. Tuomet vÄ—l galÄ—site įgalite USB 2.0. Iki tol Å¡i funkcija bus uždrausta, nebent atsisakysite dabartinių nuostatų pakeitimų.</translation>
+ </message>
+ <message>
+ <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>
</context>
<context>
@@ -3376,6 +3646,21 @@
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3421,94 +3706,284 @@
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Sukurti naują virtualų diską</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select a file for the new hard disk image file</source>
+ <translation type="unfinished">Pasirinkite rinkmeną naujo standžiojo disko atvaizdžiui</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished">Santrauka</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Location</source>
+ <comment>summary</comment>
+ <translation type="unfinished">Vieta</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <comment>summary</comment>
+ <translation type="unfinished">Dydis</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;Vieta</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Dydis</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Jus sveikina naujo virtulaus disko kūrimo vediklis!</translation>
+ <translation type="obsolete">Jus sveikina naujo virtulaus disko kūrimo vediklis!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Šis vediklis padės sukurti naują virtualų standųjį diską virtualiai mašinai.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Šis vediklis padės sukurti naują virtualų standųjį diską virtualiai mašinai.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished">Pasirinkti virtualaus standžiojo disko rinkmeną...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Pasirinkite norimo sukurti virtualaus standžiojo disko tipÄ….&lt;/p&gt;&lt;p&gt;&lt;b&gt;DinamiÅ¡ko dydžio disko atvaizdas&lt;/b&gt; iÅ¡ pradžių užima ypaÄ mažai vietos fiziniame JÅ«sų kompiuteryje. Jis didÄ—ja dinamiÅ¡kai (iki tam tikro nurodyto dydžio) pagal sveÄio operacinÄ—s sistemos disko poreikius.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Pastovaus dydžio disko atvaizdis&lt;/b&gt; yra nekintamo dydžio. Jo rinkmena užima maždaug tiek vietos, kiek virtualus standusis diskas. Priklausomai nuo pasirinkto dydžio ir jÅ«sų kompiuterio raÅ¡ymo greiÄio, pastovaus dydžio disko kÅ«rimas gali užtrukti ilgai.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Pasirinkite norimo sukurti virtualaus standžiojo disko tipÄ….&lt;/p&gt;&lt;p&gt;&lt;b&gt;DinamiÅ¡ko dydžio disko atvaizdas&lt;/b&gt; iÅ¡ pradžių užima ypaÄ mažai vietos fiziniame JÅ«sų kompiuteryje. Jis didÄ—ja dinamiÅ¡kai (iki tam tikro nurodyto dydžio) pagal sveÄio operacinÄ—s sistemos disko poreikius.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Pastovaus dydžio disko atvaizdis&lt;/b&gt; yra nekintamo dydžio. Jo rinkmena užima maždaug tiek vietos, kiek virtualus standusis diskas. Priklausomai nuo pasirinkto dydžio ir jÅ«sų kompiuterio raÅ¡ymo greiÄio, pastovaus dydžio disko kÅ«rimas gali užtrukti ilgai.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Kaupiklio tipas</translation>
+ <translation type="obsolete">Kaupiklio tipas</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>&amp;Dinamiško dydžio disko atvaizdis</translation>
+ <translation type="obsolete">&amp;Dinamiško dydžio disko atvaizdis</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>&amp;Pastovaus dydžio disko atvaizdis</translation>
+ <translation type="obsolete">&amp;Pastovaus dydžio disko atvaizdis</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Standžiojo disko kaupiklio tipas</translation>
+ <translation type="obsolete">Standžiojo disko kaupiklio tipas</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Norėdami nurodyti rinkmenos, kurioje bus laikomi virtualaus standžiojo disko duomenys, vietą, spauskite &lt;b&gt;Pasirinkti&lt;/b&gt; arba įveskite rinkmenos pavadinimą laukelyje.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Norėdami nurodyti rinkmenos, kurioje bus laikomi virtualaus standžiojo disko duomenys, vietą, spauskite &lt;b&gt;Pasirinkti&lt;/b&gt; arba įveskite rinkmenos pavadinimą laukelyje.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;Vieta</translation>
+ <translation type="obsolete">&amp;Vieta</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Nurodykite virtualaus standžiojo disko dydį megabaitais. Å is dydis sveÄio operacinÄ—je sistemoje bus rodomas kaip didžiausias standžiojo disko dydis.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Nurodykite virtualaus standžiojo disko dydį megabaitais. Å is dydis sveÄio operacinÄ—je sistemoje bus rodomas kaip didžiausias standžiojo disko dydis.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Dydis</translation>
+ <translation type="obsolete">&amp;Dydis</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Virtualaus disko vieta ir dydis</translation>
+ <translation type="obsolete">Virtualaus disko vieta ir dydis</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Pasirinkite rinkmeną naujo standžiojo disko atvaizdžiui</translation>
+ <translation type="obsolete">Pasirinkite rinkmeną naujo standžiojo disko atvaizdžiui</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Standžiųjų diskų atvaizdžiai (*.vdi)</translation>
+ <translation type="obsolete">Standžiųjų diskų atvaizdžiai (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Netrukus pradėsime kurti naują virtualų standųjį diską tokiomis savybėmis:</translation>
+ <translation type="obsolete">Netrukus pradėsime kurti naują virtualų standųjį diską tokiomis savybėmis:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Santrauka</translation>
+ <translation type="obsolete">Santrauka</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
@@ -3530,22 +4005,22 @@
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Jei aukÅ¡Äiau esanÄios nuostatos tinkamos, spauskite mygtukÄ… &lt;b&gt;%1&lt;/b&gt;. Tuomet bus sukurtas naujas standusis diskas.</translation>
+ <translation type="obsolete">Jei aukÅ¡Äiau esanÄios nuostatos tinkamos, spauskite mygtukÄ… &lt;b&gt;%1&lt;/b&gt;. Tuomet bus sukurtas naujas standusis diskas.</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Tipas</translation>
+ <translation type="obsolete">Tipas</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Vieta</translation>
+ <translation type="obsolete">Vieta</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Dydis</translation>
+ <translation type="obsolete">Dydis</translation>
</message>
</context>
<context>
@@ -3554,6 +4029,10 @@
<source>Create New Virtual Machine</source>
<translation>Sukurti naują virtualią mašiną</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -3805,6 +4284,120 @@
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Bendra</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Įvestis</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Atnaujinimas</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Kalba</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Tinklas</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Papildiniai</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Bendra</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>Sistema</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Ekranas</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Atminties įtaisas</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Garsas</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Tinklas</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Prievadai</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Nuoseklieji prievadai</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Lygiagretieji prievadai</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Bendrieji aplankai</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">pasirinkote 64 bitų sveÄio OS Å¡ioje maÅ¡inoje. Kadangi toks sveÄias reikalauja virtualizacijÄ… palaikanÄio procesoriaus (VT-x/AMD-V), pastaroji parinktis bus įgalinta automatiÅ¡kai.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">įgalinote 2D vaizdo spartinimÄ…. Kadangi 2D vaizdo spartinimas palaikomas tik Windows sveÄiui, pastaroji savybÄ— bus uždrausta.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">įgalinote USB HID (žmogaus sąsajos įtaisą). Jis neveiks tol, kol neįgalinsite USB emuliacijos. Todėl pastaroji bus įgalinta automatiškai po to, kai patvirtinsite VM nuostatas mygtuku „Gerai“.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">palaikoma ne daugiau kaip vienas</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">palaikoma ne daugiau kaip %1</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">naudojate daugiau laikmenų valdiklių nei palaiko %1 lustų rinkinys. TodÄ—l arba pakeiskite lustų rinkinio tipÄ… sistemos nuostatose, arba sumažinkite laikmenų valdiklių skaiÄių laikmenų nuostatose: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -3955,81 +4548,6 @@
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Bendra</translation>
- </message>
- <message>
- <source>System</source>
- <translation>Sistema</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Ekranas</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Atminties įtaisas</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Garsas</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Tinklas</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Prievadai</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Nuoseklieji prievadai</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Lygiagretieji prievadai</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Bendrieji aplankai</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>pasirinkote 64 bitų sveÄio OS Å¡ioje maÅ¡inoje. Kadangi toks sveÄias reikalauja virtualizacijÄ… palaikanÄio procesoriaus (VT-x/AMD-V), pastaroji parinktis bus įgalinta automatiÅ¡kai.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>įgalinote 2D vaizdo spartinimÄ…. Kadangi 2D vaizdo spartinimas palaikomas tik Windows sveÄiui, pastaroji savybÄ— bus uždrausta.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>įgalinote USB HID (žmogaus sąsajos įtaisą). Jis neveiks tol, kol neįgalinsite USB emuliacijos. Todėl pastaroji bus įgalinta automatiškai po to, kai patvirtinsite VM nuostatas mygtuku „Gerai“.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>palaikoma ne daugiau kaip vienas</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>palaikoma ne daugiau kaip %1</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>naudojate daugiau laikmenų valdiklių nei palaiko %1 lustų rinkinys. TodÄ—l arba pakeiskite lustų rinkinio tipÄ… sistemos nuostatose, arba sumažinkite laikmenų valdiklių skaiÄių laikmenų nuostatose: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -4156,6 +4674,14 @@
<source>Hard Disk Controller (SAS)</source>
<translation>Standžiojo disko valdiklis (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -5888,7 +6414,7 @@ IPv6.</translation>
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE tinklas, „%1“</translation>
+ <translation type="obsolete">VDE tinklas, „%1“</translation>
</message>
<message>
<source>SAS</source>
@@ -5898,7 +6424,7 @@ IPv6.</translation>
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>VDE plokštė</translation>
+ <translation type="obsolete">VDE plokštė</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -6876,7 +7402,7 @@ IPv6.</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>%1 plokštė</translation>
+ <translation type="obsolete">%1 plokštė</translation>
</message>
<message>
<source>MB</source>
@@ -6903,6 +7429,61 @@ IPv6.</translation>
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">%1 plokštė</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7054,15 +7635,15 @@ IPv6.</translation>
</message>
<message>
<source>Location</source>
- <translation>Vieta</translation>
+ <translation type="obsolete">Vieta</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Tipas (formatas) </translation>
+ <translation type="obsolete">Tipas (formatas) </translation>
</message>
<message>
<source>Attached to</source>
- <translation>Susietas su </translation>
+ <translation type="obsolete">Susietas su </translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -7163,17 +7744,17 @@ IPv6.</translation>
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Susietas su </translation>
+ <translation type="obsolete">Susietas su </translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Susietas su </translation>
+ <translation type="obsolete">Susietas su </translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Susietas su </translation>
+ <translation type="obsolete">Susietas su </translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -7196,6 +7777,46 @@ IPv6.</translation>
<comment>no info</comment>
<translation>--</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Tipas:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Vieta:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -7220,7 +7841,7 @@ IPv6.</translation>
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Tinklo plokštės</translation>
+ <translation type="obsolete">Tinklo plokštės</translation>
</message>
</context>
<context>
@@ -7833,7 +8454,7 @@ IPv6.</translation>
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Nepavyksta pasiekti pagrindinio kompiuteryje esanÄių USB įtaisų, nes neprieinama nei USB rinkmenų sistema (usbfs), nei DBus su hal paslaugomis. Jei sveÄio sistemoje norite naudoti pagrindinio kompiuterio USB įtaisus, privalote paÅ¡alinti trÅ«kumus ir iÅ¡ naujo paleisti VirtualBox.</translation>
+ <translation type="obsolete">Nepavyksta pasiekti pagrindinio kompiuteryje esanÄių USB įtaisų, nes neprieinama nei USB rinkmenų sistema (usbfs), nei DBus su hal paslaugomis. Jei sveÄio sistemoje norite naudoti pagrindinio kompiuterio USB įtaisus, privalote paÅ¡alinti trÅ«kumus ir iÅ¡ naujo paleisti VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -7943,7 +8564,7 @@ IPv6.</translation>
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Tikrai atkurti momentinę kopiją &lt;b&gt;%1&lt;/b&gt;? Tokiu atveju negrįžtamai prarasite dabartinę savo mašinos būseną.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Tikrai atkurti momentinę kopiją &lt;b&gt;%1&lt;/b&gt;? Tokiu atveju negrįžtamai prarasite dabartinę savo mašinos būseną.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -8318,6 +8939,8 @@ IPv6.</translation>
<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>
@@ -8400,7 +9023,7 @@ IPv6.</translation>
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">Atleiskite, būna daugybinių klaidų.</translation>
+ <translation type="unfinished">Atleiskite, būna daugybinių klaidų.</translation>
</message>
<message>
<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>
@@ -8504,7 +9127,7 @@ IPv6.</translation>
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>Visų virtuliai maÅ¡inai rinkmenų paÅ¡alinimas uždraustas Windows/x64 sistemoje tam, kad bÅ«tų iÅ¡vengta strigio. Tai bus iÅ¡taisyta sekanÄiame leidime.</translation>
+ <translation type="obsolete">Visų virtuliai maÅ¡inai rinkmenų paÅ¡alinimas uždraustas Windows/x64 sistemoje tam, kad bÅ«tų iÅ¡vengta strigio. Tai bus iÅ¡taisyta sekanÄiame leidime.</translation>
</message>
<message>
<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>
@@ -8512,7 +9135,71 @@ IPv6.</translation>
</message>
<message>
<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>&lt;p&gt;Å ioje virtualioje maÅ¡inoje įgalintas USB 2.0. TaÄiau tam turi įdiegtas &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;. &lt;nobr&gt;Ä®diegike papildinių paketÄ…, kurį rasite VirtualBox svetainÄ—je. Tuomet vÄ—l galÄ—site įgalite USB 2.0. Iki tol Å¡i funkcija bus uždrausta, nebent atsisakysite dabartinių nuostatų pakeitimų.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Å ioje virtualioje maÅ¡inoje įgalintas USB 2.0. TaÄiau tam turi įdiegtas &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;. &lt;nobr&gt;Ä®diegike papildinių paketÄ…, kurį rasite VirtualBox svetainÄ—je. Tuomet vÄ—l galÄ—site įgalite USB 2.0. Iki tol Å¡i funkcija bus uždrausta, nebent atsisakysite dabartinių nuostatų pakeitimų.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -8550,7 +9237,7 @@ IPv6.</translation>
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Bendrieji aplankai</translation>
+ <translation type="obsolete">Bendrieji aplankai</translation>
</message>
</context>
<context>
@@ -8622,7 +9309,7 @@ IPv6.</translation>
</message>
<message>
<source>D&amp;iscard</source>
- <translation>At&amp;mesti</translation>
+ <translation type="obsolete">At&amp;mesti</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -8839,6 +9526,22 @@ IPv6.</translation>
<source>Show Statusbar</source>
<translation>Rodyti būsenos juostą</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished">Atmesti</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -9037,6 +9740,14 @@ konkreÄių nuostatų, matysite paaiÅ¡kinimus&lt;i&gt;.</translation>
<comment>Current State (time or date + time)</comment>
<translation>%1 nuo %2</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts
index 3a3f95e83..77828c461 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts
@@ -517,12 +517,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>Sessie i&amp;nformatie</translation>
+ <translation type="obsolete">Sessie i&amp;nformatie</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>Activeer b&amp;eeldscherm op afstand</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">In&amp;stellingen...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -688,7 +773,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE netwerk, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE netwerk, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -814,6 +899,26 @@
<comment>details report</comment>
<translation>Omschrijving</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -990,6 +1095,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">&amp;Hostnaam:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1325,6 +1434,10 @@ p, li {white-space: pre-wrap; }
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;Is het bovenstaande correct, druk dan op de knop &lt;b&gt;Klaar&lt;/b&gt;. Zodra u die indrukt, wordt de geselecteerde media, tijdelijk, gekoppeld aan de virtuele machine en zal uitgevoerd worden.&lt;/p&gt;&lt;p&gt;Let op, sluit u de virtuele machine, dan wordt de geselecteerde media automatisch ontkoppeld en het opstarten zal vanaf de eerste harde schij plaatsvinden.&lt;/p&gt;&lt;p&gt;Afhankelijk van het soort setup programma kan het zijn dat u zelf de media moet ontkoppelen (uitwerpen) nadat het setup programma de virtuele machine opnieuw heeft gestart. Om te voorkomen dat het installatie proces opnieuw begint kunt u de overeenkomstige &lt;b&gt;Ontkoppel...&lt;/b&gt; actie selecteren in het menu &lt;b&gt;Apparaten&lt;/b&gt;.&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1398,41 +1511,6 @@ p, li {white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Algemeen</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Invoer</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Bijwerken</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Taal</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Netwerk</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Extenties</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1870,6 +1948,57 @@ p, li {white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1939,23 +2068,23 @@ p, li {white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Linker Shift</translation>
+ <translation type="obsolete">Linker Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Rechter Shift</translation>
+ <translation type="obsolete">Rechter Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Linker Ctrl</translation>
+ <translation type="obsolete">Linker Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Rechter Ctrl</translation>
+ <translation type="obsolete">Rechter Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Linker Alt</translation>
+ <translation type="obsolete">Linker Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2175,6 +2304,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importeren &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2319,7 +2452,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Geeft de status van de hardware virtualisatie functies weer die gebruikt worden door de virtuele machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Geeft de status van de hardware virtualisatie functies weer die gebruikt worden door de virtuele machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2342,6 +2475,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;De werkplek op afstand luisterd op poort %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2541,7 +2679,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>U heeft 3D acceleratie geactiveerd voor een besturingssysteem die een WDDM video driver gebruikt. Voor een maximale performance zet het gast VRAM op tenminste &lt;b&gt;%1&lt;/b&gt;.</translation>
+ <translation type="obsolete">U heeft 3D acceleratie geactiveerd voor een besturingssysteem die een WDDM video driver gebruikt. Voor een maximale performance zet het gast VRAM op tenminste &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">U hebt 2D video versnelling geactiveerd. Omdat 2D video versnelling alleen door Windows wordt ondersteund, wordt deze mogelijkheid gedeactiveerd.</translation>
</message>
</context>
<context>
@@ -2618,6 +2764,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Geef &amp;bovenin het scherm weer</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">U heeft een 64-Bit gastbesturingssysteem, voor deze VM, geselecteerd. Daarom is hardware virtualisering (VT-x/AMD-V) vereist voor de gast, deze optie wordt automatische geactiveerd.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2668,7 +2818,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Selecteert de naam van de netwerk adapter als het soort bijlage gelijk is aan de &lt;b&gt;bridge adapter&lt;/b&gt; of een &lt;b&gt;host-only adapter&lt;/b&gt; en de naam van het interne netwerk als de soort bijlage gelijk is aan het &lt;b&gt;interne netwerk&lt;/b&gt;.</translation>
+ <translation type="obsolete">Selecteert de naam van de netwerk adapter als het soort bijlage gelijk is aan de &lt;b&gt;bridge adapter&lt;/b&gt; of een &lt;b&gt;host-only adapter&lt;/b&gt; en de naam van het interne netwerk als de soort bijlage gelijk is aan het &lt;b&gt;interne netwerk&lt;/b&gt;.</translation>
</message>
<message>
<source>Adapter &amp;Type:</source>
@@ -2710,6 +2860,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>&amp;Poort doorverwijzing</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3153,7 +3339,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Geen harde schijf geselecteerd voor &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">Geen harde schijf geselecteerd voor &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3428,6 +3614,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation>Kies een virtueel diskette bestand...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">Op zijn minst één ondersteund</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">tot %1 ondersteund</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">u gebruikt nu meer opslagcontrolers dan een %1 chipset ondersteund. Wijzig aub het type chipset bij de pagina met systeeminstellingen of verminder het volgende aantal opslagcontrolers bij de pagina met opslaginstellingen: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3618,6 +3858,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>u heeft een ICH9 chipset type toegekend aan deze VM. Deze zal niet goed werken tenzij de IO-APIC optie is geactiveerd. Dit wordt automatisch uitgevoerd als u de VM instellingen accpeteerd door op OK te klikken.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished">U hebt een USB HID (Human Interface Device) geactiveerd. Deze zal niet werken zolang de USB emulatie niet is geactiveerd. Dit wordt automatisch gedaan als u de VM instellingen accepteerd door op de Ok knop te klikken.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3744,7 +4010,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>USB 2.0 is momenteel geactiveerd voor deze virtuele machine. Maar dit vereist installatie van &lt;b&gt;%1&lt;/b&gt;. Installeer het uitbreidingspakket beschikbaar op de VirtualBox download site. Hierna ben u instaat om de USB 2.0 opnieuw te activeren. In de tussentijn blijft deze inactief tenzij u de huidige instelling wijzigd.</translation>
+ <translation type="obsolete">USB 2.0 is momenteel geactiveerd voor deze virtuele machine. Maar dit vereist installatie van &lt;b&gt;%1&lt;/b&gt;. Installeer het uitbreidingspakket beschikbaar op de VirtualBox download site. Hierna ben u instaat om de USB 2.0 opnieuw te activeren. In de tussentijn blijft deze inactief tenzij u de huidige instelling wijzigd.</translation>
+ </message>
+ <message>
+ <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>
</context>
<context>
@@ -3857,6 +4127,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3902,7 +4187,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Maak een nieuwe virtuele schijf</translation>
@@ -3917,7 +4202,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Samenvatting</translation>
+ <translation type="unfinished">Samenvatting</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -3929,7 +4214,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Selecteer een bestand voor de nieuwe harde schijf image</translation>
+ <translation type="unfinished">Selecteer een bestand voor de nieuwe harde schijf image</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -3951,12 +4236,12 @@ p, li { white-space: pre-wrap; }
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Locatie</translation>
+ <translation type="unfinished">Locatie</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Omvang</translation>
+ <translation type="unfinished">Omvang</translation>
</message>
<message>
<source>Bytes</source>
@@ -4015,108 +4300,280 @@ p, li { white-space: pre-wrap; }
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Zijn de bovenstaande instellingen correct? Druk dan op de knop &lt;b&gt;Klaar&lt;/b&gt;. Zodra u op de knop drukt wordt de nieuwe harde schijf aan gemaakt.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;Locatie</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Omvang</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Welkom bij de assistent voor het aanmaken van een nieuwe virtuele schijf!</translation>
+ <translation type="obsolete">Welkom bij de assistent voor het aanmaken van een nieuwe virtuele schijf!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Deze assistent help u bij het aanmaken van een nieuwe virtuele harde schijf voor uw virtuale machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Deze assistent help u bij het aanmaken van een nieuwe virtuele harde schijf voor uw virtuale machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished">kies een virtueel harde schijf bestand...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Selecteer het soort opslag voor de harde schijf die wilt aanmaken.&lt;/p&gt;&lt;p&gt;Een &lt;b&gt;dynamisch uit te breiden opslag&lt;/b&gt; neemt in het begin een kleine hoeveelheid ruimte van uw fysieke harde schijf in beslag. Maar zal dynamisch groeien (tot aan de vastgestelde grote) zodra het gast besturingssysteem ruimte nodig heeft.&lt;/p&gt;&lt;p&gt;Een &lt;b&gt;opslag met een vaste omvang&lt;/b&gt; groeit niet. Deze is opgeslagen in een bestand met ongeveer dezelfde grote als de virtuele harde schijf. Het aanmaken van een opslag met vaste omvang kan lang duren, dit hangt af van de omvang van de opslag en de schrijfsnelheid van uw fysieke harde schijf.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Selecteer het soort opslag voor de harde schijf die wilt aanmaken.&lt;/p&gt;&lt;p&gt;Een &lt;b&gt;dynamisch uit te breiden opslag&lt;/b&gt; neemt in het begin een kleine hoeveelheid ruimte van uw fysieke harde schijf in beslag. Maar zal dynamisch groeien (tot aan de vastgestelde grote) zodra het gast besturingssysteem ruimte nodig heeft.&lt;/p&gt;&lt;p&gt;Een &lt;b&gt;opslag met een vaste omvang&lt;/b&gt; groeit niet. Deze is opgeslagen in een bestand met ongeveer dezelfde grote als de virtuele harde schijf. Het aanmaken van een opslag met vaste omvang kan lang duren, dit hangt af van de omvang van de opslag en de schrijfsnelheid van uw fysieke harde schijf.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Soort opslag</translation>
+ <translation type="obsolete">Soort opslag</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>&amp;Dynamisch uit te breiden opslag</translation>
+ <translation type="obsolete">&amp;Dynamisch uit te breiden opslag</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>&amp;Opslag met een vaste omvang</translation>
+ <translation type="obsolete">&amp;Opslag met een vaste omvang</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Soort opslag voor de harde schijf</translation>
+ <translation type="obsolete">Soort opslag voor de harde schijf</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Druk op de knop &lt;b&gt;Selecteer&lt;/b&gt;, om de locatie van een bestand te selecteren waarin de harde schijf gegevens worden opgeslagen of typ een bestandsnaam in het invoerveld.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Druk op de knop &lt;b&gt;Selecteer&lt;/b&gt;, om de locatie van een bestand te selecteren waarin de harde schijf gegevens worden opgeslagen of typ een bestandsnaam in het invoerveld.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;Locatie</translation>
+ <translation type="obsolete">&amp;Locatie</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Selecteer de omvang van de virtuele harde schijf in megabytes. Deze omvang wordt gerapporteerd aan het gast besturingssysteem als de maximale omvang van deze harde schijf.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Selecteer de omvang van de virtuele harde schijf in megabytes. Deze omvang wordt gerapporteerd aan het gast besturingssysteem als de maximale omvang van deze harde schijf.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Omvang</translation>
+ <translation type="obsolete">&amp;Omvang</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Locatie en omvang van de vrituele schijf</translation>
+ <translation type="obsolete">Locatie en omvang van de vrituele schijf</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Selecteer een bestand voor de nieuwe harde schijf image</translation>
+ <translation type="obsolete">Selecteer een bestand voor de nieuwe harde schijf image</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Harde schijf image (*.vdi)</translation>
+ <translation type="obsolete">Harde schijf image (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>U staat op het punt een nieuwe virtuele harde schijf aan te maken met de onderstaande parameters:</translation>
+ <translation type="obsolete">U staat op het punt een nieuwe virtuele harde schijf aan te maken met de onderstaande parameters:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Samenvatting</translation>
+ <translation type="obsolete">Samenvatting</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Soort</translation>
+ <translation type="obsolete">Soort</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Locatie</translation>
+ <translation type="obsolete">Locatie</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Omvang</translation>
+ <translation type="obsolete">Omvang</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Druk op de &lt;b&gt;%1&lt;/b&gt; knop als de bovenstaande instellingen juist zijn. Zodra u de knop indrukt wordt de nieuwe harde schijf aangemaakt.</translation>
+ <translation type="obsolete">Druk op de &lt;b&gt;%1&lt;/b&gt; knop als de bovenstaande instellingen juist zijn. Zodra u de knop indrukt wordt de nieuwe harde schijf aangemaakt.</translation>
</message>
</context>
<context>
@@ -4237,6 +4694,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">&amp;Gebruikt een bestaande harde schijf</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4522,6 +4983,120 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Algemeen</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Invoer</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Bijwerken</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Taal</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Netwerk</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Extenties</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Algemeen</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>Systeem</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Beeldscherm</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Opslag</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Audio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Netwerk</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Poorten</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Seriële poorten</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Parallelle porten</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Gedeelde mappen</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">U heeft een 64-Bit gastbesturingssysteem, voor deze VM, geselecteerd. Daarom is hardware virtualisering (VT-x/AMD-V) vereist voor de gast, deze optie wordt automatische geactiveerd.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">U hebt 2D video versnelling geactiveerd. Omdat 2D video versnelling alleen door Windows wordt ondersteund, wordt deze mogelijkheid gedeactiveerd.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">U hebt een USB HID (Human Interface Device) geactiveerd. Deze zal niet werken zolang de USB emulatie niet is geactiveerd. Dit wordt automatisch gedaan als u de VM instellingen accepteerd door op de Ok knop te klikken.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">Op zijn minst één ondersteund</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">tot %1 ondersteund</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">u gebruikt nu meer opslagcontrolers dan een %1 chipset ondersteund. Wijzig aub het type chipset bij de pagina met systeeminstellingen of verminder het volgende aantal opslagcontrolers bij de pagina met opslaginstellingen: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -4661,81 +5236,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Algemeen</translation>
- </message>
- <message>
- <source>System</source>
- <translation>Systeem</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Beeldscherm</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Opslag</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Audio</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Netwerk</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Poorten</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Seriële poorten</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Parallelle porten</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Gedeelde mappen</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>U heeft een 64-Bit gastbesturingssysteem, voor deze VM, geselecteerd. Daarom is hardware virtualisering (VT-x/AMD-V) vereist voor de gast, deze optie wordt automatische geactiveerd.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>U hebt 2D video versnelling geactiveerd. Omdat 2D video versnelling alleen door Windows wordt ondersteund, wordt deze mogelijkheid gedeactiveerd.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>U hebt een USB HID (Human Interface Device) geactiveerd. Deze zal niet werken zolang de USB emulatie niet is geactiveerd. Dit wordt automatisch gedaan als u de VM instellingen accepteerd door op de Ok knop te klikken.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>Op zijn minst één ondersteund</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>tot %1 ondersteund</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>u gebruikt nu meer opslagcontrolers dan een %1 chipset ondersteund. Wijzig aub het type chipset bij de pagina met systeeminstellingen of verminder het volgende aantal opslagcontrolers bij de pagina met opslaginstellingen: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -4871,6 +5371,14 @@ p, li { white-space: pre-wrap; }
<source>Hard Disk Controller (SAS)</source>
<translation>Harde schijf controller (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -6258,7 +6766,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Adapter %1</translation>
+ <translation type="obsolete">Adapter %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -6683,7 +7191,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE netwerk, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE netwerk, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -6693,7 +7201,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>VDE adapter</translation>
+ <translation type="obsolete">VDE adapter</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -6890,6 +7398,61 @@ p, li { white-space: pre-wrap; }
<comment>DiskType</comment>
<translation>Meerdere aangesloten</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Adapter %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7052,15 +7615,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Location</source>
- <translation>Locatie</translation>
+ <translation type="obsolete">Locatie</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Soort (formaat)</translation>
+ <translation type="obsolete">Soort (formaat)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Aangesloten aan</translation>
+ <translation type="obsolete">Aangesloten aan</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -7142,17 +7705,17 @@ p, li { white-space: pre-wrap; }
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Aangesloten aan</translation>
+ <translation type="obsolete">Aangesloten aan</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Aangesloten aan</translation>
+ <translation type="obsolete">Aangesloten aan</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Aangesloten aan</translation>
+ <translation type="obsolete">Aangesloten aan</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -7170,6 +7733,46 @@ p, li { white-space: pre-wrap; }
<source>All %1 images (%2)</source>
<translation>Alle %1 images (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Type:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Locatie:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -7194,7 +7797,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Netwerk adapters</translation>
+ <translation type="obsolete">Netwerk adapters</translation>
</message>
</context>
<context>
@@ -7885,7 +8488,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Het is niet mogelijk om de USB op het gastheer systeem te benaderen omdat nog het USB bestandssysteem (usbfs) nog de DBus en HAL services nu beschikbaar zijn. Wilt u het met USB op het gast systeem werken moet eea corrigeren en VirtuaBox herstarten.</translation>
+ <translation type="obsolete">Het is niet mogelijk om de USB op het gastheer systeem te benaderen omdat nog het USB bestandssysteem (usbfs) nog de DBus en HAL services nu beschikbaar zijn. Wilt u het met USB op het gast systeem werken moet eea corrigeren en VirtuaBox herstarten.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -7986,7 +8589,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Bent u er zeker van dat u de momentopname &lt;b&gt;%1&lt;/b&gt; wilt terugzetten? Hierdoor verliest u de huidige status van de machine en dit is niet te herstellen.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Bent u er zeker van dat u de momentopname &lt;b&gt;%1&lt;/b&gt; wilt terugzetten? Hierdoor verliest u de huidige status van de machine en dit is niet te herstellen.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -8285,7 +8888,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">Excusses een algemene fout is opgetreden.</translation>
+ <translation type="unfinished">Excusses een algemene fout is opgetreden.</translation>
</message>
<message>
<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>
@@ -8374,7 +8977,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>Verwijderen van alle bestanden die bij de VM horen is nu inactief op Windows/x64 om een crash te voorkomen. Dit wordt in de volgende versie opgelost.</translation>
+ <translation type="obsolete">Verwijderen van alle bestanden die bij de VM horen is nu inactief op Windows/x64 om een crash te voorkomen. Dit wordt in de volgende versie opgelost.</translation>
</message>
<message>
<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>
@@ -8382,7 +8985,71 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>&lt;p&gt;USB 2.0 is momenteel geactiveerd voor deze virtuele machine. Maar dit vereist installatie van &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Installeer het uitbreidingspakket beschikbaar op de VirtualBox download site. Hierna ben u instaat om de USB 2.0 opnieuw te activeren. In de tussentijn blijft deze inactief tenzij u de huidige instelling wijzigd.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;USB 2.0 is momenteel geactiveerd voor deze virtuele machine. Maar dit vereist installatie van &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Installeer het uitbreidingspakket beschikbaar op de VirtualBox download site. Hierna ben u instaat om de USB 2.0 opnieuw te activeren. In de tussentijn blijft deze inactief tenzij u de huidige instelling wijzigd.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -8473,7 +9140,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Gedeelde mappen</translation>
+ <translation type="obsolete">Gedeelde mappen</translation>
</message>
</context>
<context>
@@ -8546,7 +9213,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>D&amp;iscard</source>
- <translation>&amp;Verwerpen</translation>
+ <translation type="obsolete">&amp;Verwerpen</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -8748,6 +9415,22 @@ p, li { white-space: pre-wrap; }
<source>Show Statusbar</source>
<translation>Geeft de statusbalk weer</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -8977,6 +9660,14 @@ p, li { white-space: pre-wrap; }
<source> (%1 ago)</source>
<translation> (%1 geleden)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pl.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pl.ts
index bc0f7ceef..8f4d5604d 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pl.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pl.ts
@@ -568,11 +568,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">U&amp;stawienia...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -740,7 +821,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation type="unfinished">Sieć VDE, &apos;%1&apos;</translation>
+ <translation type="obsolete">Sieć VDE, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -866,6 +947,26 @@
<comment>details report</comment>
<translation type="unfinished">Opis</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -1086,6 +1187,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">Nazwa h&amp;osta:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1442,6 +1547,10 @@ p, li { white-space: pre-wrap; }
<source>Cancel</source>
<translation type="obsolete">Anuluj</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">Uruchom</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1515,41 +1624,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Ogólne</translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished">Wejście</translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished">Aktualizacje</translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished">Język</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Sieć</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished">VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1986,6 +2060,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -2055,23 +2180,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Lewy Shift</translation>
+ <translation type="obsolete">Lewy Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Prawy Shift</translation>
+ <translation type="obsolete">Prawy Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Lewy Ctrl</translation>
+ <translation type="obsolete">Lewy Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Prawy Ctrl</translation>
+ <translation type="obsolete">Prawy Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Lewy Alt</translation>
+ <translation type="obsolete">Lewy Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2288,6 +2413,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importuj &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2432,7 +2561,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Wskazuje status funkcji wirtualzacji sprzętowej używanych przez maszynę wirtualną:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Wskazuje status funkcji wirtualzacji sprzętowej używanych przez maszynę wirtualną:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2455,6 +2584,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2653,9 +2787,13 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">włączona jest akceleracja wideo 2D. Ponieważ akceleracja wideo 2D wspierana jest jedynie dla systemów gospodarza typu Windows, funkcja ta zostanie wyłączona.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsGeneral</name>
@@ -2887,6 +3025,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Pokaż u &amp;góry ekranu</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">wybrano 64-bitowy system operacyjny dla tej maszyny wirtualnej. Ponieważ tego typu goszczone systemy wymagają wsparcia dla sprzętowej wirtualizacji (VT-x/AMD-V), funkcja ta zostanie włączona automatycznie.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -3040,7 +3182,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Pozwala wybrać nazwę karty sieciowej dla połączenia &lt;b&gt;mostkowanego&lt;/b&gt; lub &lt;b&gt;izolowanego&lt;/b&gt; oraz nazwę dla połączenia &lt;b&gt;sieci wewnętrznej&lt;/b&gt;.</translation>
+ <translation type="obsolete">Pozwala wybrać nazwę karty sieciowej dla połączenia &lt;b&gt;mostkowanego&lt;/b&gt; lub &lt;b&gt;izolowanego&lt;/b&gt; oraz nazwę dla połączenia &lt;b&gt;sieci wewnętrznej&lt;/b&gt;.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -3066,6 +3208,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3580,7 +3758,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Nie wybrano dysku twardego dla &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">Nie wybrano dysku twardego dla &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3854,6 +4032,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -4035,6 +4267,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished">włączony jest USB HID (Human Interface Device). Nie będzie to działać, chyba że włączona będzie również emulacja USB. Zostanie to wykonane automatycznie po zatwierdzeniu ustawień maszyny wirtualnej przyciskiem OK.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -4160,7 +4418,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished">&lt;nobr&gt;Stan: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -4274,6 +4532,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4319,7 +4592,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Tworzenie nowego dysku wirtualnego</translation>
@@ -4416,7 +4689,7 @@ operacyjnemu jako rozmiar wirtualnego dysku twardego.&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Podsumowanie</translation>
+ <translation type="unfinished">Podsumowanie</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4432,7 +4705,7 @@ operacyjnemu jako rozmiar wirtualnego dysku twardego.&lt;/p&gt;</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Umożliwia wskazanie pliku dla obrazu nowego wirtualnego dysku twardego</translation>
+ <translation type="unfinished">Umożliwia wskazanie pliku dla obrazu nowego wirtualnego dysku twardego</translation>
</message>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;
@@ -4485,12 +4758,12 @@ oraz wydajności zapisu dysku twardego w komputerze.&lt;/p&gt;</translation>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Ścieżka</translation>
+ <translation type="unfinished">Ścieżka</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Rozmiar</translation>
+ <translation type="unfinished">Rozmiar</translation>
</message>
<message>
<source>Bytes</source>
@@ -4549,108 +4822,280 @@ oraz wydajności zapisu dysku twardego w komputerze.&lt;/p&gt;</translation>
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Jeśli powyższe ustawienia są prawidłowe, proszę wcisnąć przycisk &lt;b&gt;Zakończ&lt;/b&gt;. Po naciśnięciu zostanie utworzony nowy obraz dysku twardego.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">Ś&amp;cieżka</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Rozmiar</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Asystent tworzenia nowego dysku wirtualnego</translation>
+ <translation type="obsolete">Asystent tworzenia nowego dysku wirtualnego</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Ten asystent pomaga utworzyć nowy wirtualny dysk twardy dla maszyny wirtualnej.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Ten asystent pomaga utworzyć nowy wirtualny dysk twardy dla maszyny wirtualnej.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Proszę wybrać typ obrazu wirtualnego dysku twardego, jaki ma zostać utworzony.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Dynamicznie rozszerzany obraz&lt;/b&gt; początkowo zajmuje bardzo niewielką ilość miejsca na fizycznym dysku. Będzie on jednak rósł dynamicznie (aż do wybranego rozmiaru) wraz z zajmowaniem przez goszczony system operacyjny coraz większej przestrzeni dysku.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Obraz o stałym rozmiarze&lt;/b&gt; nie rośnie. Jest on od razu zapisywany w pliku o rozmiarze w przybliżeniu takim samym, jak wybrany rozmiar dysku wirtualnego. Tworzenie obrazu o stałym rozmiarze może zająć wiele czasu, zależnie od rozmiaru obrazu oraz wydajności zapisu dysku twardego w komputerze.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Proszę wybrać typ obrazu wirtualnego dysku twardego, jaki ma zostać utworzony.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Dynamicznie rozszerzany obraz&lt;/b&gt; początkowo zajmuje bardzo niewielką ilość miejsca na fizycznym dysku. Będzie on jednak rósł dynamicznie (aż do wybranego rozmiaru) wraz z zajmowaniem przez goszczony system operacyjny coraz większej przestrzeni dysku.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Obraz o stałym rozmiarze&lt;/b&gt; nie rośnie. Jest on od razu zapisywany w pliku o rozmiarze w przybliżeniu takim samym, jak wybrany rozmiar dysku wirtualnego. Tworzenie obrazu o stałym rozmiarze może zająć wiele czasu, zależnie od rozmiaru obrazu oraz wydajności zapisu dysku twardego w komputerze.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Typ obrazu</translation>
+ <translation type="obsolete">Typ obrazu</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>D&amp;ynamicznie rozszerzany obraz</translation>
+ <translation type="obsolete">D&amp;ynamicznie rozszerzany obraz</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>Obraz o &amp;stałym rozmiarze</translation>
+ <translation type="obsolete">Obraz o &amp;stałym rozmiarze</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Typ obrazu dysku twardego</translation>
+ <translation type="obsolete">Typ obrazu dysku twardego</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Proszę wcisnąć przycisk &lt;b&gt;Wybierz&lt;/b&gt;, aby wybrać lokalizację oraz nazwę pliku z obrazem dysku wirtualnego, można też wprowadzić nazwę pliku bezpośrednio w polu poniżej.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Proszę wcisnąć przycisk &lt;b&gt;Wybierz&lt;/b&gt;, aby wybrać lokalizację oraz nazwę pliku z obrazem dysku wirtualnego, można też wprowadzić nazwę pliku bezpośrednio w polu poniżej.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>Ś&amp;cieżka</translation>
+ <translation type="obsolete">Ś&amp;cieżka</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Proszę wskazać rozmiar wirtualnego dysku twardego w megabajtach. Będzie on zgłoszony goszczonemu systemowi operacyjnemu jako maksymalny rozmiar tego dysku twardego.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Proszę wskazać rozmiar wirtualnego dysku twardego w megabajtach. Będzie on zgłoszony goszczonemu systemowi operacyjnemu jako maksymalny rozmiar tego dysku twardego.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Rozmiar</translation>
+ <translation type="obsolete">&amp;Rozmiar</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Ścieżka i rozmiar dysku wirtualnego</translation>
+ <translation type="obsolete">Ścieżka i rozmiar dysku wirtualnego</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Wskaż plik dla obrazu nowego wirtualnego dysku twardego</translation>
+ <translation type="obsolete">Wskaż plik dla obrazu nowego wirtualnego dysku twardego</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Obrazy dysków twardych (*.vdi)</translation>
+ <translation type="obsolete">Obrazy dysków twardych (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Zostanie utworzony nowy wirtualny dysk twardy o następujących parametrach:</translation>
+ <translation type="obsolete">Zostanie utworzony nowy wirtualny dysk twardy o następujących parametrach:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Podsumowanie</translation>
+ <translation type="obsolete">Podsumowanie</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Typ</translation>
+ <translation type="obsolete">Typ</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Ścieżka</translation>
+ <translation type="obsolete">Ścieżka</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Rozmiar</translation>
+ <translation type="obsolete">Rozmiar</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Jeśli powyższe ustawienia są prawidłowe, proszę wcisnąć przycisk &lt;b&gt;%1&lt;/b&gt;. Po naciśnięciu zostanie utworzony nowy obraz dysku twardego.</translation>
+ <translation type="obsolete">Jeśli powyższe ustawienia są prawidłowe, proszę wcisnąć przycisk &lt;b&gt;%1&lt;/b&gt;. Po naciśnięciu zostanie utworzony nowy obraz dysku twardego.</translation>
</message>
</context>
<context>
@@ -4886,6 +5331,10 @@ Będzie ona używana przez wszystkie moduły VirtualBox, aby móc rozróżnić t
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">&amp;Użyj istniejącego dysku twardego</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -5115,6 +5564,108 @@ Będzie ona używana przez wszystkie moduły VirtualBox, aby móc rozróżnić t
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Ogólne</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation type="unfinished">Wejście</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished">Aktualizacje</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation type="unfinished">Język</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Sieć</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation type="unfinished">VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Ogólne</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation type="unfinished">System</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation type="unfinished">Ekran</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation type="unfinished">Nośniki</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished">Dźwięk</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Sieć</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation type="unfinished">Porty</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation type="unfinished">Porty szeregowe</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation type="unfinished">Porty równoległe</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation type="unfinished">Współdzielone katalogi</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished">%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">wybrano 64-bitowy system operacyjny dla tej maszyny wirtualnej. Ponieważ tego typu goszczone systemy wymagają wsparcia dla sprzętowej wirtualizacji (VT-x/AMD-V), funkcja ta zostanie włączona automatycznie.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">włączona jest akceleracja wideo 2D. Ponieważ akceleracja wideo 2D wspierana jest jedynie dla systemów gospodarza typu Windows, funkcja ta zostanie wyłączona.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">włączony jest USB HID (Human Interface Device). Nie będzie to działać, chyba że włączona będzie również emulacja USB. Zostanie to wykonane automatycznie po zatwierdzeniu ustawień maszyny wirtualnej przyciskiem OK.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -5253,81 +5804,6 @@ Będzie ona używana przez wszystkie moduły VirtualBox, aby móc rozróżnić t
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Ogólne</translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished">System</translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished">Ekran</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished">Nośniki</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished">Dźwięk</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Sieć</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished">Porty</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished">Porty szeregowe</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished">Porty równoległe</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished">Współdzielone katalogi</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished">%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished">wybrano 64-bitowy system operacyjny dla tej maszyny wirtualnej. Ponieważ tego typu goszczone systemy wymagają wsparcia dla sprzętowej wirtualizacji (VT-x/AMD-V), funkcja ta zostanie włączona automatycznie.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished">włączona jest akceleracja wideo 2D. Ponieważ akceleracja wideo 2D wspierana jest jedynie dla systemów gospodarza typu Windows, funkcja ta zostanie wyłączona.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished">włączony jest USB HID (Human Interface Device). Nie będzie to działać, chyba że włączona będzie również emulacja USB. Zostanie to wykonane automatycznie po zatwierdzeniu ustawień maszyny wirtualnej przyciskiem OK.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5563,6 +6039,14 @@ Wersja %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation>Kontroler dysków SAS</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -7549,7 +8033,7 @@ Wersja %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Karta %1</translation>
+ <translation type="obsolete">Karta %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -8017,7 +8501,7 @@ Wersja %1</translation>
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Sieć VDE, &apos;%1&apos;</translation>
+ <translation type="obsolete">Sieć VDE, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -8027,7 +8511,7 @@ Wersja %1</translation>
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>Karta sieciowa VDE</translation>
+ <translation type="obsolete">Karta sieciowa VDE</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -8224,6 +8708,61 @@ Wersja %1</translation>
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Karta %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -8897,15 +9436,15 @@ języka ustawiony jako domyślny dla systemu.&lt;/qt&gt;
</message>
<message>
<source>Location</source>
- <translation>Ścieżka</translation>
+ <translation type="obsolete">Ścieżka</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Typ (format)</translation>
+ <translation type="obsolete">Typ (format)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Podłączony do</translation>
+ <translation type="obsolete">Podłączony do</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -8987,17 +9526,17 @@ języka ustawiony jako domyślny dla systemu.&lt;/qt&gt;
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Podłączony do</translation>
+ <translation type="obsolete">Podłączony do</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Podłączona do</translation>
+ <translation type="obsolete">Podłączona do</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Podłączona do</translation>
+ <translation type="obsolete">Podłączona do</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -9015,6 +9554,46 @@ języka ustawiony jako domyślny dla systemu.&lt;/qt&gt;
<source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Ścieżka:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -9062,7 +9641,7 @@ języka ustawiony jako domyślny dla systemu.&lt;/qt&gt;
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Karty sieciowe</translation>
+ <translation type="obsolete">Karty sieciowe</translation>
</message>
</context>
<context>
@@ -9920,7 +10499,7 @@ języka ustawiony jako domyślny dla systemu.&lt;/qt&gt;
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Nie udało się uzyskać dostępu do USB w systemie operacyjnym gospodarza, ponieważ system plików USB (usbfs) jak również usługi DBus i hal nie są aktualnie dostępne. Jeśli potrzebne jest użycie urządzeń USB wewnątrz goszczonych systemów, należy to naprawić i uruchomić ponownie VirtualBox.</translation>
+ <translation type="obsolete">Nie udało się uzyskać dostępu do USB w systemie operacyjnym gospodarza, ponieważ system plików USB (usbfs) jak również usługi DBus i hal nie są aktualnie dostępne. Jeśli potrzebne jest użycie urządzeń USB wewnątrz goszczonych systemów, należy to naprawić i uruchomić ponownie VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -10041,7 +10620,7 @@ języka ustawiony jako domyślny dla systemu.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Przywrócić migawkę systemu &lt;b&gt;%1&lt;/b&gt;? Spowoduje to utratę aktualnego stanu maszyny, którego nie będzie już można odzyskać.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Przywrócić migawkę systemu &lt;b&gt;%1&lt;/b&gt;? Spowoduje to utratę aktualnego stanu maszyny, którego nie będzie już można odzyskać.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -10417,15 +10996,75 @@ języka ustawiony jako domyślny dla systemu.&lt;/qt&gt;
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -10560,7 +11199,7 @@ języka ustawiony jako domyślny dla systemu.&lt;/qt&gt;
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Współdzielone katalogi</translation>
+ <translation type="obsolete">Współdzielone katalogi</translation>
</message>
<message>
<source>Cancel</source>
@@ -10663,11 +11302,11 @@ języka ustawiony jako domyślny dla systemu.&lt;/qt&gt;
</message>
<message>
<source>D&amp;iscard</source>
- <translation>O&amp;drzuć</translation>
+ <translation type="obsolete">O&amp;drzuć</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Odrzuć</translation>
+ <translation type="unfinished">Odrzuć</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -10945,6 +11584,18 @@ języka ustawiony jako domyślny dla systemu.&lt;/qt&gt;
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -11309,6 +11960,14 @@ Uwaga: funkcja ta wymaga zainstalowania Dodatków (Guest Additions).&lt;/qt&gt;<
<source> (%1 ago)</source>
<translation> (%1 temu)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt.ts
index 8a1e4d9f6..10810d876 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt.ts
@@ -109,61 +109,61 @@
</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>
+ <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>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
- <translation type="unfinished"></translation>
+ <translation>Certifique-se que o módulo kernel foi carregado com sucesso.</translation>
</message>
<message>
<source>VirtualBox - Runtime Error</source>
- <translation type="unfinished"></translation>
+ <translation>VirtualBox - Erro de Execução</translation>
</message>
<message>
<source>&lt;b&gt;Cannot access the kernel driver!&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;b&gt;Não é possível aceder ao controlador kernel!&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;</translation>
</message>
<message>
<source>Unknown error %2 during initialization of the Runtime</source>
- <translation type="unfinished"></translation>
+ <translation>Erro desconhecido %2 durante a instalação do ambiente de execução (Runtime)</translation>
</message>
<message>
<source>Kernel driver not accessible</source>
- <translation type="unfinished"></translation>
+ <translation>O controlador kernel não está acessível</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>
+ <translation>Os módulos kernel do VirtualBox não correspondem a esta versão do VirtualBox. A instalação do VirtualBox aparentemente falhou. Por favor tente desinstalar completamente e reinstalar o VirtualBox.</translation>
</message>
<message>
<source>The VirtualBox kernel modules do not match this version of VirtualBox. The installation of VirtualBox was apparently not successful. 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;may correct this. Make sure that you do not mix the OSE version and the PUEL version of VirtualBox.</source>
- <translation type="unfinished"></translation>
+ <translation>Os módulos kernel do VirtualBox não correspondem a esta versão do VirtualBox. A instalação do VirtualBox aparentemente falhou. Pode corrigir isto ao executar &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;. Certifique-se que não mistura as versões OSE e a versão PUEL do VirtualBox.</translation>
</message>
<message>
<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>
+ <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>
</context>
<context>
<name>QIArrowSplitter</name>
<message>
<source>&amp;Back</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Anterior</translation>
</message>
<message>
<source>&amp;Next</source>
- <translation type="unfinished">&amp;Próximo</translation>
+ <translation>&amp;Próximo</translation>
</message>
</context>
<context>
<name>QIFileDialog</name>
<message>
<source>Select a directory</source>
- <translation type="unfinished">Seleccione um directório</translation>
+ <translation>Seleccione um directório</translation>
</message>
<message>
<source>Select a file</source>
- <translation type="unfinished">Seleccione um ficheiro</translation>
+ <translation>Seleccione um ficheiro</translation>
</message>
</context>
<context>
@@ -188,7 +188,7 @@
<name>QILabel</name>
<message>
<source>&amp;Copy</source>
- <translation type="unfinished">&amp;Copiar</translation>
+ <translation>&amp;Copiar</translation>
</message>
</context>
<context>
@@ -222,11 +222,11 @@
</message>
<message>
<source>&amp;Details</source>
- <translation type="unfinished">&amp;Detalhes</translation>
+ <translation>&amp;Detalhes</translation>
</message>
<message>
<source>&amp;Details (%1 of %2)</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Detalhes (%1 of %2)</translation>
</message>
</context>
<context>
@@ -261,7 +261,7 @@
<name>QIWizardPage</name>
<message>
<source>Use the &lt;b&gt;%1&lt;/b&gt; button to go to the next page of the wizard and the &lt;b&gt;%2&lt;/b&gt; button to return to the previous page. You can also press &lt;b&gt;%3&lt;/b&gt; if you want to cancel the execution of this wizard.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>Use o botão &lt;b&gt;%1&lt;/b&gt; para ir para a próxima página do assistente e use o botão &lt;b&gt;%2&lt;/b&gt; para regressar à página anterior. Pode também premir &lt;b&gt;%3&lt;/b&gt; se deseja cancelar a execução deste assistente.&lt;/p&gt;</translation>
</message>
</context>
<context>
@@ -288,7 +288,7 @@
</message>
<message>
<source>Auto-resize &amp;Guest Display</source>
- <translation type="unfinished">Auto-redimensionar Ecrã &amp;Convidado</translation>
+ <translation>Auto-redimensionar Ecrã &amp;Convidado</translation>
</message>
<message>
<source>Automatically resize the guest display when the window is resized (requires Guest Additions)</source>
@@ -320,11 +320,11 @@
</message>
<message>
<source>&amp;Insert Ctrl-Alt-Del</source>
- <translation>&amp;Inserir Ctrl-Alt-Del</translation>
+ <translation>&amp;Inserir Ctrl-Alt-Apagar</translation>
</message>
<message>
<source>Send the Ctrl-Alt-Del sequence to the virtual machine</source>
- <translation>Envia o comando Ctrl-Alt-Del para a máquina virtual</translation>
+ <translation>Envia o comando Ctrl-Alt-Apagar para a máquina virtual</translation>
</message>
<message>
<source>&amp;Insert Ctrl-Alt-Backspace</source>
@@ -376,7 +376,7 @@
</message>
<message>
<source>ACPI Sh&amp;utdown</source>
- <translation></translation>
+ <translation>&amp;Desligar ACPI</translation>
</message>
<message>
<source>ACPI S&amp;hutdown</source>
@@ -396,7 +396,7 @@
</message>
<message>
<source>&amp;View</source>
- <translation></translation>
+ <translation>&amp;ver</translation>
</message>
<message>
<source>&amp;Devices</source>
@@ -404,11 +404,11 @@
</message>
<message>
<source>&amp;CD/DVD Devices</source>
- <translation></translation>
+ <translation>Dispositivos &amp;CD/DVD</translation>
</message>
<message>
<source>&amp;Floppy Devices</source>
- <translation></translation>
+ <translation>Dispositivos de Dis&amp;quete</translation>
</message>
<message>
<source>&amp;USB Devices</source>
@@ -416,11 +416,11 @@
</message>
<message>
<source>&amp;Network Adapters...</source>
- <translation></translation>
+ <translation>&amp;Adaptadores de Rede...</translation>
</message>
<message>
<source>Change the settings of network adapters</source>
- <translation></translation>
+ <translation>Muda as definições dos adaptadores de rede</translation>
</message>
<message>
<source>&amp;Shared Folders...</source>
@@ -428,7 +428,7 @@
</message>
<message>
<source>Create or modify shared folders</source>
- <translation>Abre o diálogo de pastas partilhadas</translation>
+ <translation>Cria ou modificas as pastas partilhadas</translation>
</message>
<message>
<source>Enable or disable remote desktop (RDP) connections to this machine</source>
@@ -458,59 +458,144 @@
</message>
<message>
<source>&amp;Help</source>
- <translation></translation>
+ <translation>&amp;Ajuda</translation>
</message>
<message>
<source>Dock Icon</source>
- <translation></translation>
+ <translation>Icon da Barra de Tarefas</translation>
</message>
<message>
<source>Show Monitor Preview</source>
- <translation></translation>
+ <translation>Mostrar Previsão do Monitor</translation>
</message>
<message>
<source>Show Application Icon</source>
- <translation></translation>
+ <translation>Mostrar Ãcone da Aplicação</translation>
</message>
<message>
<source>Enable remote desktop (RDP) connections to this machine</source>
- <translation type="unfinished"></translation>
+ <translation>Activar conexões remotas (RDP) ao ecrã para esta máquina</translation>
</message>
<message>
<source>Enable &amp;Logging...</source>
<comment>debug action</comment>
- <translation type="unfinished"></translation>
+ <translation>Activar &amp;Registo...</translation>
</message>
<message>
<source>Switch to &amp;Fullscreen</source>
- <translation type="unfinished"></translation>
+ <translation>Mudar para &amp;Ecrã Completo</translation>
</message>
<message>
<source>Switch between normal and fullscreen mode</source>
- <translation type="unfinished"></translation>
+ <translation>Mudar entre modo normal e modo ecrã completo</translation>
</message>
<message>
<source>Switch to Seam&amp;less Mode</source>
- <translation type="unfinished"></translation>
+ <translation>Mudar para Modo In&amp;tegrado</translation>
</message>
<message>
<source>Switch between normal and seamless desktop integration mode</source>
- <translation type="unfinished"></translation>
+ <translation>Mudar entre modo normal e modo integrado de ecrã transparente</translation>
</message>
<message>
<source>Switch to &amp;Scale Mode</source>
- <translation type="unfinished"></translation>
+ <translation>Mudar para Modo E&amp;scala</translation>
</message>
<message>
<source>Switch between normal and scale mode</source>
- <translation type="unfinished"></translation>
+ <translation>Mudar entre modo normal e modo escala</translation>
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">I&amp;nformação da Sessão</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
+ <translation>Activar Ecrã R&amp;emoto</translation>
+ </message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">Definiçõe&amp;s...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -518,15 +603,15 @@
<name>UIDescriptionPagePrivate</name>
<message>
<source>No description. Press the Edit button below to add it.</source>
- <translation type="unfinished">Sem descrição. Prima o botão Editar para adicionar uma.</translation>
+ <translation>Sem descrição. Prima o botão Editar para adicionar uma.</translation>
</message>
<message>
<source>Edit</source>
- <translation type="unfinished">Editar</translation>
+ <translation>Editar</translation>
</message>
<message>
<source>Edit (Ctrl+E)</source>
- <translation type="unfinished">Editar (Ctrl+E)</translation>
+ <translation>Editar (Ctrl+E)</translation>
</message>
</context>
<context>
@@ -534,274 +619,294 @@
<message>
<source>Name</source>
<comment>details report</comment>
- <translation type="unfinished">Nome</translation>
+ <translation>Nome</translation>
</message>
<message>
<source>OS Type</source>
<comment>details report</comment>
- <translation type="unfinished">Tipo de Sistema Operativo</translation>
+ <translation>Tipo de Sistema Operativo</translation>
</message>
<message>
<source>Base Memory</source>
<comment>details report</comment>
- <translation type="unfinished">Memória Principal</translation>
+ <translation>Memória Base</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 MB&lt;/nobr&gt;</source>
<comment>details report</comment>
- <translation type="unfinished">&lt;nobr&gt;%4 MB&lt;/nobr&gt; {1 ?}</translation>
+ <translation>&lt;nobr&gt;%1 MB&lt;/nobr&gt;</translation>
</message>
<message>
<source>Processors</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Processadores</translation>
</message>
<message>
<source>&lt;nobr&gt;%1&lt;/nobr&gt;</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;%1&lt;/nobr&gt;</translation>
</message>
<message>
<source>Boot Order</source>
<comment>details report</comment>
- <translation type="unfinished">Ordem de Arranque</translation>
+ <translation>Ordem de Arranque</translation>
</message>
<message>
<source>ACPI</source>
<comment>details report</comment>
- <translation type="unfinished">ACPI</translation>
+ <translation>ACPI</translation>
</message>
<message>
<source>IO APIC</source>
<comment>details report</comment>
- <translation type="unfinished">IO APIC</translation>
+ <translation>IO APIC</translation>
</message>
<message>
<source>BIOS</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>BIOS</translation>
</message>
<message>
<source>VT-x/AMD-V</source>
<comment>details report</comment>
- <translation type="unfinished">VT-x/AMD-V</translation>
+ <translation>VT-x/AMD-V</translation>
</message>
<message>
<source>Nested Paging</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Paginação Aninhada</translation>
</message>
<message>
<source>PAE/NX</source>
<comment>details report</comment>
- <translation type="unfinished">PAE/NX</translation>
+ <translation>PAE/NX</translation>
</message>
<message>
<source>Acceleration</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Aceleração</translation>
</message>
<message>
<source>Video Memory</source>
<comment>details report</comment>
- <translation type="unfinished">Memória Gráfica</translation>
+ <translation>Memória Gráfica</translation>
</message>
<message>
<source>Screens</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Ecrãs</translation>
</message>
<message>
<source>2D Video</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Vídeo 2D</translation>
</message>
<message>
<source>3D</source>
<comment>details report</comment>
- <translation type="unfinished">3D</translation>
+ <translation>3D</translation>
</message>
<message>
<source>Remote Desktop Server Port</source>
<comment>details report (VRDE Server)</comment>
- <translation type="unfinished"></translation>
+ <translation>Porta do Servidor de Ecrã Remoto</translation>
</message>
<message>
<source>Remote Desktop Server</source>
<comment>details report (VRDE Server)</comment>
- <translation type="unfinished"></translation>
+ <translation>Servidor de Ecrã Remoto</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (VRDE Server)</comment>
- <translation type="unfinished">Desactivado</translation>
+ <translation>Desactivado</translation>
</message>
<message>
<source>(CD/DVD)</source>
- <translation type="unfinished"></translation>
+ <translation>(CD/DVD)</translation>
</message>
<message>
<source>Not Attached</source>
<comment>details report (Storage)</comment>
- <translation type="unfinished">Não Conectado</translation>
+ <translation>Não Ligado</translation>
</message>
<message>
<source>Host Driver</source>
<comment>details report (audio)</comment>
- <translation type="unfinished">Controlador do Dispositivo</translation>
+ <translation>Dispositivo Hospedeiro</translation>
</message>
<message>
<source>Controller</source>
<comment>details report (audio)</comment>
- <translation type="unfinished">Controlador</translation>
+ <translation>Controlador</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (audio)</comment>
- <translation type="unfinished">Desactivado</translation>
+ <translation>Desactivado</translation>
</message>
<message>
<source>Bridged adapter, %1</source>
<comment>details report (network)</comment>
- <translation type="unfinished"></translation>
+ <translation>Adaptador em ponte (bridged), %1</translation>
</message>
<message>
<source>Internal network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation type="unfinished"></translation>
+ <translation>Rede interna, &apos;%1&apos;</translation>
</message>
<message>
<source>Host-only adapter, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation type="unfinished"></translation>
+ <translation>Adaptador do hospedeiro-apenas, &apos;%1&apos;</translation>
</message>
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Rede VDE, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
- <translation type="unfinished">Adaptador %1</translation>
+ <translation>Adaptador %1</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (network)</comment>
- <translation type="unfinished">Desactivado</translation>
+ <translation>Desactivado</translation>
</message>
<message>
<source>Port %1</source>
<comment>details report (serial ports)</comment>
- <translation type="unfinished">Porta %1</translation>
+ <translation>Porta %1</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (serial ports)</comment>
- <translation type="unfinished">Desactivado</translation>
+ <translation>Desactivado</translation>
</message>
<message>
<source>Port %1</source>
<comment>details report (parallel ports)</comment>
- <translation type="unfinished">Porta %1</translation>
+ <translation>Porta %1</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (parallel ports)</comment>
- <translation type="unfinished">Desactivado</translation>
+ <translation>Desactivado</translation>
</message>
<message>
<source>Device Filters</source>
<comment>details report (USB)</comment>
- <translation type="unfinished">Filtros de Dispositivo</translation>
+ <translation>Filtros do Dispositivo</translation>
</message>
<message>
<source>%1 (%2 active)</source>
<comment>details report (USB)</comment>
- <translation type="unfinished">%1 (%2 activos)</translation>
+ <translation>%1 (%2 activos)</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (USB)</comment>
- <translation type="unfinished">Desactivado</translation>
+ <translation>Desactivado</translation>
</message>
<message>
<source>Shared Folders</source>
<comment>details report (shared folders)</comment>
- <translation type="unfinished">Pastas Partilhadas</translation>
+ <translation>Pastas Partilhadas</translation>
</message>
<message>
<source>None</source>
<comment>details report (shared folders)</comment>
- <translation type="unfinished">Nenhum</translation>
+ <translation>Nenhum</translation>
</message>
<message>
<source>None</source>
<comment>details report (description)</comment>
- <translation type="unfinished">Nenhum</translation>
+ <translation>Nenhum</translation>
</message>
<message>
<source>The selected virtual machine is &lt;i&gt;inaccessible&lt;/i&gt;. Please inspect the error message shown below and press the &lt;b&gt;Refresh&lt;/b&gt; button if you want to repeat the accessibility check:</source>
- <translation type="unfinished">A máquina virtual seleccionada está &lt;i&gt;inacessível&lt;/i&gt;. Verifique a mensagem de erro mostrada abaixo e prima o botão &lt;b&gt;Actualizar&lt;/b&gt; se desejar repetir o teste de acessibilidade:</translation>
+ <translation>A máquina virtual seleccionada está &lt;i&gt;inacessível&lt;/i&gt;. Verifique a mensagem de erro mostrada abaixo e prima o botão &lt;b&gt;Actualizar&lt;/b&gt; se desejar repetir o teste de acessibilidade:</translation>
</message>
<message>
<source>General</source>
<comment>details report</comment>
- <translation type="unfinished">Geral</translation>
+ <translation>Geral</translation>
</message>
<message>
<source>System</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Sistema</translation>
</message>
<message>
<source>Preview</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Prever</translation>
</message>
<message>
<source>Display</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Mostrar</translation>
</message>
<message>
<source>Storage</source>
<comment>details report</comment>
- <translation type="unfinished">Armazenamento</translation>
+ <translation>Armazenamento</translation>
</message>
<message>
<source>Audio</source>
<comment>details report</comment>
- <translation type="unfinished">Ãudio</translation>
+ <translation>Ãudio</translation>
</message>
<message>
<source>Network</source>
<comment>details report</comment>
- <translation type="unfinished">Rede</translation>
+ <translation>Rede</translation>
</message>
<message>
<source>Serial Ports</source>
<comment>details report</comment>
- <translation type="unfinished">Portas Série</translation>
+ <translation>Portas Série</translation>
</message>
<message>
<source>Parallel Ports</source>
<comment>details report</comment>
- <translation type="unfinished">Portas Paralelas</translation>
+ <translation>Portas Paralelas</translation>
</message>
<message>
<source>USB</source>
<comment>details report</comment>
- <translation type="unfinished">USB</translation>
+ <translation>USB</translation>
</message>
<message>
<source>Shared Folders</source>
<comment>details report</comment>
- <translation type="unfinished">Pastas Partilhadas</translation>
+ <translation>Pastas Partilhadas</translation>
</message>
<message>
<source>Description</source>
<comment>details report</comment>
+ <translation>Descrição</translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
<translation type="unfinished"></translation>
</message>
</context>
@@ -853,7 +958,7 @@
</message>
<message>
<source>The download process has been canceled by the user.</source>
- <translation type="unfinished"></translation>
+ <translation>O processo de transferência foi cancelado pelo utilizador.</translation>
</message>
</context>
<context>
@@ -883,14 +988,14 @@
<name>UIDownloaderUserManual</name>
<message>
<source>Select folder to save User Manual to</source>
- <translation type="unfinished"></translation>
+ <translation>Seleccione a pasta para gravar o Manual de Utilizador</translation>
</message>
</context>
<context>
<name>UIExportApplianceWzd</name>
<message>
<source>Appliance Export Wizard</source>
- <translation type="unfinished"></translation>
+ <translation>Assistente de Exportação de Aplicação</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -906,6 +1011,10 @@
</message>
<message>
<source>Restore Defaults</source>
+ <translation>Restaurar Predefinições</translation>
+ </message>
+ <message>
+ <source>Export</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -913,128 +1022,128 @@
<name>UIExportApplianceWzdPage1</name>
<message>
<source>Welcome to the Appliance Export Wizard!</source>
- <translation type="unfinished"></translation>
+ <translation>Bem-vindo ao Assistente de Exportação de Aplicação!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will guide you through the process of exporting an appliance.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;Please select the virtual machines that should be added to the appliance. You can select more than one. Please note that these machines have to be turned off before they can be exported.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Este assistente irá guiá-lo através do processo de exportar uma aplicação.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;Por favor seleccione as máquinas virtuais que devem ser adicionadas à aplicação. Pode seleccionar mais que uma. Por favor note que estas máquinas têm que ser desligadas antes de sere exportadas.&lt;/p&gt;</translation>
</message>
</context>
<context>
<name>UIExportApplianceWzdPage2</name>
<message>
<source>Appliance Export Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Definições de Exportação de Aplicação</translation>
</message>
<message>
<source>Please specify the target for the OVF export. You can choose between a local file system export, uploading the OVF to the Sun Cloud service or an S3 storage server.</source>
- <translation type="unfinished"></translation>
+ <translation>Por favor especifique o alvo da exportação OVF. Pode escolher entre uma expotação de sistema de ficheiros local, a enviar o OVF para o serviço &apos;Sun Cloud&apos; ou um servidor de armazenamento S3.</translation>
</message>
<message>
<source>&amp;Local Filesystem </source>
- <translation type="unfinished"></translation>
+ <translation>Sistema de Ficheiros &amp;Local</translation>
</message>
<message>
<source>Sun &amp;Cloud</source>
- <translation type="unfinished"></translation>
+ <translation>&apos;Sun &amp;Cloud&apos;</translation>
</message>
<message>
<source>&amp;Simple Storage System (S3)</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Sistema de Armazenamento Simples (S3)</translation>
</message>
</context>
<context>
<name>UIExportApplianceWzdPage3</name>
<message>
<source>Appliance Export Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Definições de Exportação de Aplicação</translation>
</message>
<message>
<source>&amp;Username:</source>
- <translation type="unfinished"></translation>
+ <translation>Nome de &amp;Utilizador:</translation>
</message>
<message>
<source>&amp;Password:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Senha:</translation>
</message>
<message>
<source>&amp;Hostname:</source>
- <translation type="unfinished"></translation>
+ <translation>Nome da &amp;Máquina:</translation>
</message>
<message>
<source>&amp;Bucket:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Caixote:</translation>
</message>
<message>
<source>&amp;File:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Ficheiro:</translation>
</message>
<message>
<source>Write in legacy OVF 0.9 format for compatibility with other virtualization products.</source>
- <translation type="unfinished"></translation>
+ <translation>Escrever no formato legado OVF para compatibilidade com outros produtos de virtualização.</translation>
</message>
<message>
<source>&amp;Write legacy OVF 0.9</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Escrever legado OVF 0.9</translation>
</message>
<message>
<source>Create a Manifest file for automatic data integrity checks on import.</source>
- <translation type="unfinished"></translation>
+ <translation>Criar um ficheiro de Manifesto para verificações automática da integridade dos dados ao importar.</translation>
</message>
<message>
<source>Write &amp;Manifest file</source>
- <translation type="unfinished"></translation>
+ <translation>Escrever Ficheiro de &amp;Manifesto</translation>
</message>
<message>
<source>Appliance</source>
- <translation type="unfinished"></translation>
+ <translation>Aplicação</translation>
</message>
<message>
<source>Select a file to export into</source>
- <translation type="unfinished"></translation>
+ <translation>Seleccione um ficheiro para exportar</translation>
</message>
<message>
<source>Open Virtualization Format Archive (%1)</source>
- <translation type="unfinished"></translation>
+ <translation>Arquivo de Formato de Virtualização Aberto (%1)</translation>
</message>
<message>
<source>Open Virtualization Format (%1)</source>
- <translation type="unfinished"></translation>
+ <translation>Formato de Virtualização Aberto (%1)</translation>
</message>
<message>
<source>Please choose a filename to export the OVF/OVA to. If you use an &lt;i&gt;ova&lt;/i&gt; file name extension, then all the files will be combined into one Open Virtualization Format Archive. If you use an &lt;i&gt;ovf&lt;/i&gt; extension, several files will be written separately. Other extensions are not allowed.</source>
- <translation type="unfinished"></translation>
+ <translation>Por favor escolha um nome de ficheiro para exportar o OVF/OVA. Se poder usar uma extensão de nome de ficheiro &lt;i&gt;ova&lt;/i&gt;, então todos os ficheiros serão combinados num Arquivo de Formato de Virtualização Aberto. Se usar uma extensão &lt;i&gt;ovf&lt;/i&gt;, vários ficheiros serão escritos separadamente. Não é permitida outra extensão.</translation>
</message>
<message>
<source>Please complete the additional fields like the username, password and the bucket, and provide a filename for the OVF target.</source>
- <translation type="unfinished"></translation>
+ <translation>Por favor complete os campos adicionais como o nome de utilizador, senha e do caixote, e forneça um nome de ficheiro para o destino OVF.</translation>
</message>
<message>
<source>Please complete the additional fields like the username, password, hostname and the bucket, and provide a filename for the OVF target.</source>
- <translation type="unfinished"></translation>
+ <translation>Por favor complete os campos adicionais como o nome de utilizador, senha, nome da máquina e do caixote, e forneça um nome de ficheiro para o destino OVF.</translation>
</message>
</context>
<context>
<name>UIExportApplianceWzdPage4</name>
<message>
<source>Appliance Export Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Definições de EXportação da Aplicação</translation>
</message>
<message>
<source>Checking files ...</source>
- <translation type="unfinished"></translation>
+ <translation>A verificar ficheiros...</translation>
</message>
<message>
<source>Removing files ...</source>
- <translation type="unfinished"></translation>
+ <translation>A remover ficheiros...</translation>
</message>
<message>
<source>Exporting Appliance ...</source>
- <translation type="unfinished"></translation>
+ <translation>A exportar aplicação...</translation>
</message>
<message>
<source>Here you can change additional configuration values of the selected virtual machines. You can modify most of the properties shown by double-clicking on the items.</source>
- <translation type="unfinished"></translation>
+ <translation>Aqui pode mudar os valores de configuraão adicionais das máquinas virtuais seleccionadas. Pode modificar a maioria das propriedades mostradas ao fazer duplo clique nos itens.</translation>
</message>
</context>
<context>
@@ -1165,154 +1274,123 @@
<source>Cancel</source>
<translation type="obsolete">Cancelar</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">Iniciar</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
<message>
<source>Welcome to the First Run Wizard!</source>
- <translation type="unfinished">Bem-vindo ao Assistente de Primeira Execução!</translation>
+ <translation>Bem-vindo ao Assistente de Primeira Execução!</translation>
</message>
<message>
<source>&lt;p&gt;You have started a newly created virtual machine for the first time. This wizard will help you to perform the steps necessary for installing an operating system of your choice onto this virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Iniciou uma nova máquina virtual pela primeira vez. Este assistente irá ajudá-lo a executar alguns passos necessários para instalar um sistema operativo da sua escolha nesta máquina virtual.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;You have started a newly created virtual machine for the first time. This wizard will help you to perform the steps necessary for booting an operating system of your choice on the virtual machine.&lt;/p&gt;&lt;p&gt;Note that you will not be able to install an operating system into this virtual machine right now because you did not attach any hard disk to it. If this is not what you want, you can cancel the execution of this wizard, select &lt;b&gt;Settings&lt;/b&gt; from the &lt;b&gt;Machine&lt;/b&gt; menu of the main VirtualBox window to access the settings dialog of this machine and change the hard disk configuration.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Iniciou uma nova máquina virtual pela primeira vez. Este assistente irá ajudá-lo a executar alguns passos necessários para arrancar um sistema operativo da sua escolha nesta máquina virtual.&lt;/p&gt;&lt;p&gt;Note que agora não poderá instalar um sistema operativo nesta máquina virtual porque não ligou qualquer disco rígido a esta. Se não é isto que deseja, pode cancelar a execução deste assistente, seleccionar &lt;b&gt;Definições&lt;/b&gt; do menu principal &lt;b&gt;Máquina&lt;/b&gt; da janela do VirtualBox para aceder ao dialogo de definições desta máquina e mudar a configuração do disco rígido.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
</context>
<context>
<name>UIFirstRunWzdPage2</name>
<message>
<source>&lt;p&gt;Select the media which contains the setup program of the operating system you want to install. This media must be bootable, otherwise the setup program will not be able to start.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Seleccione o dispositivo que contém o programa de instalação do sistema operativo que deseja instalar. Este dispositivo deve poder arrancar a máquina virtual, caso contrário o programa de instalação não poderá iniciar.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Seleccione a média que contém o programa de instalação do sistema operativo que deseja instalar. Esta média deve poder arrancar a máquina virtual, caso contrário o programa de instalação não poderá iniciar.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Select the media that contains the operating system you want to work with. This media must be bootable, otherwise the operating system will not be able to start.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Seleccione o dispositivo que contém o sistema operativo com o qual deseja trabalhar. Tem que poder arrancar com este dispositivo, caso contrário o sistema operativo não poderá iniciar.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Seleccione a média que contém o sistema operativo com o qual deseja trabalhar. Tem que poder arrancar com esta média, caso contrário o sistema operativo não poderá iniciar.&lt;/p&gt;</translation>
</message>
<message>
<source>Media Source</source>
- <translation type="unfinished">Dispositivo de Origem</translation>
+ <translation>Média Fonte</translation>
</message>
<message>
<source>Select Installation Media</source>
- <translation type="unfinished">Seleccione o Dispositivo de Instalação</translation>
+ <translation>Seleccionar Média de Instalação</translation>
</message>
</context>
<context>
<name>UIFirstRunWzdPage3</name>
<message>
<source>&lt;p&gt;You have selected the following media to boot from:&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Seleccionou iniciar o sistema a partir do seguinte dispositivo:&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Seleccionou iniciar o sistema a partir da seguinte média:&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;You have selected the following media to boot an operating system from:&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Seleccionou o seguinte dispositivo para arrancar o sistema operativo:&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Seleccionou a seguinte média para arrancar o sistema operativo:&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Se as informações acima estiverem correctas, prima o botão &lt;b&gt;Finalizar&lt;/b&gt;. Assim que o premir, o dispositivo seleccionado será temporariamente montado na máquina virtual e a máquina iniciará a sua execução.&lt;/p&gt;&lt;p&gt;Note que quando fechar a máquina virtual, o dispositivo especificado será automaticamente desmontado e o dispositivo de arranque será redefinido como o primeiro disco rígido.&lt;/p&gt;&lt;p&gt;Dependendo do tipo do programa de instalação, poderá ser necessário desmontar (ejectar) manualmente o dispositivo após o reinício do PC no final da instalação, para evitar que o processo de instalação seja iniciado novamente. Pode fazer isto seleccionando a acção correspondente &lt;b&gt;Desmontar...&lt;/b&gt; no menu &lt;b&gt;Dispositivos&lt;/b&gt;.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Se as informações acima estiverem correctas, prima o botão &lt;b&gt;Finalizar&lt;/b&gt;. Assim que o premir, a média seleccionada será temporariamente montada na máquina virtual e a máquina iniciará a sua execução.&lt;/p&gt;&lt;p&gt;Note que quando fechar a máquina virtual, a média especificada será automaticamente desmontada e o dispositivo de arranque será redefinido como o primeiro disco rígido.&lt;/p&gt;&lt;p&gt;Dependendo do tipo do programa de instalação, poderá ser necessário desmontar (ejectar) manualmente o dispositivo após o reinício do PC no final da instalação, para evitar que o processo de instalação seja iniciado novamente. Pode fazer isto seleccionando a acção correspondente &lt;b&gt;Desmontar...&lt;/b&gt; no menu &lt;b&gt;Dispositivos&lt;/b&gt;.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be mounted on the virtual machine and the machine will start execution.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Se as informações acima estiverem correctas, prima o botão &lt;b&gt;Finalizar&lt;/b&gt;. Assim que o tiver prmeido, o dispositivo seleccionado será montado na máquina virtual e a execução da máquina será iniciada.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Se as informações acima estiverem correctas, prima o botão &lt;b&gt;Finalizar&lt;/b&gt;. Assim que o tiver prmeido, a média seleccionada será montada na máquina virtual e a execução da máquina será iniciada.&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="unfinished"></translation>
+ <translation>Sumário</translation>
</message>
<message>
<source>CD/DVD-ROM Device</source>
- <translation type="unfinished">Dispositivo de CD/DVD-ROM</translation>
+ <translation>Dispositivo de CD/DVD-ROM</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation type="unfinished">Tipo</translation>
+ <translation>Tipo</translation>
</message>
<message>
<source>Source</source>
<comment>summary</comment>
- <translation type="unfinished">Fonte</translation>
- </message>
-</context>
-<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Geral</translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished">Entrada</translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished">Actualizar</translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished">Idioma</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Rede</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished"></translation>
+ <translation>Fonte</translation>
</message>
</context>
<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
- <translation type="unfinished"></translation>
+ <translation>Pacotes &amp;Extensão:</translation>
</message>
<message>
<source>Lists all installed packages.</source>
- <translation type="unfinished"></translation>
+ <translation>Lista todos os pacotes instalados.</translation>
</message>
<message>
<source>Active</source>
- <translation type="unfinished"></translation>
+ <translation>Activo</translation>
</message>
<message>
<source>Name</source>
- <translation type="unfinished">Nome</translation>
+ <translation>Nome</translation>
</message>
<message>
<source>Version</source>
- <translation type="unfinished"></translation>
+ <translation>Versão</translation>
</message>
<message>
<source>Add package</source>
- <translation type="unfinished"></translation>
+ <translation>Adicionar pacote</translation>
</message>
<message>
<source>Remove package</source>
- <translation type="unfinished"></translation>
+ <translation>Remover pacote</translation>
</message>
<message>
<source>Select an extension package file</source>
- <translation type="unfinished"></translation>
+ <translation>Seleccione um ficheiro de pacote de extensão</translation>
</message>
<message>
<source>Extension package files (%1)</source>
- <translation type="unfinished"></translation>
+ <translation>Ficheiros de pacote de extensão (%1)</translation>
</message>
<message>
<source>Extensions</source>
- <translation type="unfinished"></translation>
+ <translation>Extensões</translation>
</message>
</context>
<context>
@@ -1347,50 +1425,50 @@
</message>
<message>
<source>When checked, the application will provide an icon with the context menu in the system tray.</source>
- <translation type="unfinished">Quando seleccionada, a aplicação apresentará um ícone com menu de contexto no ... do sistema.</translation>
+ <translation>Quando seleccionada, a aplicação apresentará um ícone com o menu de contexto no barra de tarefas do sistema.</translation>
</message>
<message>
<source>&amp;Show System Tray Icon</source>
- <translation type="unfinished">Apre&amp;sentar o ícone do </translation>
+ <translation>Mo&amp;strar Ãcone da Barra de Tarefas</translation>
</message>
<message>
<source>&amp;Auto show Dock and Menubar in fullscreen</source>
- <translation type="unfinished"></translation>
+ <translation>Mostrar &amp;Automaticamente Ãcone da Barra de Tarefas e Menu no ecrã completo</translation>
</message>
<message>
<source>When checked, the host screen saver will be disabled whenever a virtual machine is running.</source>
- <translation type="unfinished"></translation>
+ <translation>Quando activada, o protector de ecrã do hospedeiro será desactivado quando estiver a correr uma máquina virtual.</translation>
</message>
<message>
<source>Disable Host &amp;ScreenSaver</source>
- <translation type="unfinished"></translation>
+ <translation>Desactivar &amp;Protector de Ecrã do Hospedeiro</translation>
</message>
</context>
<context>
<name>UIGlobalSettingsInput</name>
<message>
<source>Host &amp;Key:</source>
- <translation type="unfinished">Tecla do &amp;Hospedeiro:</translation>
+ <translation>Chave do &amp;Hospedeiro:</translation>
</message>
<message>
<source>Displays the key used as a Host Key in the VM window. Activate the entry field and press a new Host Key. Note that alphanumeric, cursor movement and editing keys cannot be used.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra a chave usada como Chave de Hospedeiro na janela do VM. Active o campo de entrada e prima uma nova Chave de Hospedeiro. Note que não pode usar valores alfanuméricos, mover o cursor e editar chaves.</translation>
</message>
<message>
<source>When checked, the keyboard is automatically captured every time the VM window is activated. When the keyboard is captured, all keystrokes (including system ones like Alt-Tab) are directed to the VM.</source>
- <translation type="unfinished"></translation>
+ <translation>Quando seleccionada, o teclado é capturado automaticamente sempre que a janela do VM é activada. Quando o teclado é capturado, todas os toques nas teclas (incluindo como as do sistema Alt-Tab) são direccionados para o VM.</translation>
</message>
<message>
<source>&amp;Auto Capture Keyboard</source>
- <translation type="unfinished">&amp;Auto Capturar Teclado</translation>
+ <translation>&amp;Auto Capturar Teclado</translation>
</message>
<message>
<source>Reset host combination</source>
- <translation type="unfinished"></translation>
+ <translation>Restaurar combinação do hospedeiro</translation>
</message>
<message>
<source>Resets the key combination used as the host combination in the VM window.</source>
- <translation type="unfinished"></translation>
+ <translation>Restaura a combinação da chave usada como combinação de hospedeiro na janela do VM.</translation>
</message>
</context>
<context>
@@ -1452,233 +1530,284 @@
<name>UIGlobalSettingsNetwork</name>
<message>
<source>host IPv4 address of &lt;b&gt;%1&lt;/b&gt; is wrong</source>
- <translation type="unfinished"></translation>
+ <translation>O endereço IPv4 do hospedeiro de &lt;b&gt;%1&lt;/b&gt; está errado</translation>
</message>
<message>
<source>host IPv4 network mask of &lt;b&gt;%1&lt;/b&gt; is wrong</source>
- <translation type="unfinished"></translation>
+ <translation>A máscara de rede IPv4 do hospedeiro de &lt;b&gt;%1&lt;/b&gt; está errada</translation>
</message>
<message>
<source>host IPv6 address of &lt;b&gt;%1&lt;/b&gt; is wrong</source>
- <translation type="unfinished"></translation>
+ <translation>O endereço IPv6 do hospedeiro de &lt;b&gt;%1&lt;/b&gt; está errado</translation>
</message>
<message>
<source>DHCP server address of &lt;b&gt;%1&lt;/b&gt; is wrong</source>
- <translation type="unfinished"></translation>
+ <translation>O endereço do servidor DHCP de &lt;b&gt;%1&lt;/b&gt; está errado</translation>
</message>
<message>
<source>DHCP server network mask of &lt;b&gt;%1&lt;/b&gt; is wrong</source>
- <translation type="unfinished"></translation>
+ <translation>A máscara da rede do servidor DHCP de &lt;b&gt;%1&lt;/b&gt; está errada</translation>
</message>
<message>
<source>DHCP lower address bound of &lt;b&gt;%1&lt;/b&gt; is wrong</source>
- <translation type="unfinished"></translation>
+ <translation>O limite inferior do endereço DHCP de &lt;b&gt;%1&lt;/b&gt; está errado</translation>
</message>
<message>
<source>DHCP upper address bound of &lt;b&gt;%1&lt;/b&gt; is wrong</source>
- <translation type="unfinished"></translation>
+ <translation>O limite superior do endereço DHCP de &lt;b&gt;%1&lt;/b&gt; está errado</translation>
</message>
<message>
<source>Adapter</source>
- <translation type="unfinished">Adaptador</translation>
+ <translation>Adaptador</translation>
</message>
<message>
<source>Automatically configured</source>
<comment>interface</comment>
- <translation type="unfinished"></translation>
+ <translation>Configurado automaticamente</translation>
</message>
<message>
<source>Manually configured</source>
<comment>interface</comment>
- <translation type="unfinished"></translation>
+ <translation>Configurado manualmente</translation>
</message>
<message>
<source>IPv4 Address</source>
- <translation type="unfinished"></translation>
+ <translation>Endereço IPv4</translation>
</message>
<message>
<source>Not set</source>
<comment>address</comment>
- <translation type="unfinished"></translation>
+ <translation>Não definido</translation>
</message>
<message>
<source>IPv4 Network Mask</source>
- <translation type="unfinished"></translation>
+ <translation>Máscara de Rede IPv4</translation>
</message>
<message>
<source>Not set</source>
<comment>mask</comment>
- <translation type="unfinished"></translation>
+ <translation>Não definido</translation>
</message>
<message>
<source>IPv6 Address</source>
- <translation type="unfinished"></translation>
+ <translation>Endereço IPv6</translation>
</message>
<message>
<source>IPv6 Network Mask Length</source>
- <translation type="unfinished"></translation>
+ <translation>Comprimento da Máscara de Rede IPv6</translation>
</message>
<message>
<source>Not set</source>
<comment>length</comment>
- <translation type="unfinished"></translation>
+ <translation>Não definido</translation>
</message>
<message>
<source>DHCP Server</source>
- <translation type="unfinished"></translation>
+ <translation>Servidor DHCP</translation>
</message>
<message>
<source>Enabled</source>
<comment>server</comment>
- <translation type="unfinished">Activado</translation>
+ <translation>Activado</translation>
</message>
<message>
<source>Disabled</source>
<comment>server</comment>
- <translation type="unfinished">Desactivado</translation>
+ <translation>Desactivado</translation>
</message>
<message>
<source>Address</source>
- <translation type="unfinished"></translation>
+ <translation>Endereço</translation>
</message>
<message>
<source>Network Mask</source>
- <translation type="unfinished"></translation>
+ <translation>Máscara de Rede</translation>
</message>
<message>
<source>Lower Bound</source>
- <translation type="unfinished"></translation>
+ <translation>Limite Inferior</translation>
</message>
<message>
<source>Not set</source>
<comment>bound</comment>
- <translation type="unfinished"></translation>
+ <translation>Não definido</translation>
</message>
<message>
<source>Upper Bound</source>
- <translation type="unfinished"></translation>
+ <translation>Limite Superior</translation>
</message>
<message>
<source>&amp;Add host-only network</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Adicionar rede de apenas para o hospedeiro</translation>
</message>
<message>
<source>&amp;Remove host-only network</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Remover rede apenas para o hospedeiro</translation>
</message>
<message>
<source>&amp;Edit host-only network</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Editar rede apenas para o hospedeiro</translation>
</message>
<message>
<source>&amp;Host-only Networks:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Redes apenas do hospedeiro:</translation>
</message>
<message>
<source>Lists all available host-only networks.</source>
- <translation type="unfinished"></translation>
+ <translation>Lista todas as redes disponíveis apenas do hospedeiro.</translation>
</message>
<message>
<source>Name</source>
- <translation type="unfinished">Nome</translation>
+ <translation>Nome</translation>
</message>
<message>
<source>Networking</source>
- <translation type="unfinished"></translation>
+ <translation>Rede</translation>
</message>
</context>
<context>
<name>UIGlobalSettingsNetworkDetails</name>
<message>
<source>Host-only Network Details</source>
- <translation type="unfinished"></translation>
+ <translation>Detalhes da Rede Apenas do Hospedeiro</translation>
</message>
<message>
<source>&amp;Adapter</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Adaptador</translation>
</message>
<message>
<source>Manual &amp;Configuration</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Configuração Manual</translation>
</message>
<message>
<source>Use manual configuration for this host-only network adapter.</source>
- <translation type="unfinished"></translation>
+ <translation>Use a configuração manual para o adaptador de rede apenas deste hospedeiro.</translation>
</message>
<message>
<source>&amp;IPv4 Address:</source>
- <translation type="unfinished"></translation>
+ <translation>Endereço &amp;IPv4:</translation>
</message>
<message>
<source>Displays the host IPv4 address for this adapter.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra o endereço IPv4 do hospedeiro para este adaptador.</translation>
</message>
<message>
<source>IPv4 Network &amp;Mask:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Máscara de Rede IPv4:</translation>
</message>
<message>
<source>Displays the host IPv4 network mask for this adapter.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra a máscara de rede IPv4 do hospedeiro para este adaptador.</translation>
</message>
<message>
<source>I&amp;Pv6 Address:</source>
- <translation type="unfinished"></translation>
+ <translation>Endereço I&amp;Pv6:</translation>
</message>
<message>
<source>Displays the host IPv6 address for this adapter if IPv6 is supported.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra o endereço IPv6 do hospedeiro para este adaptador se o IPv6 for suportado.</translation>
</message>
<message>
<source>IPv6 Network Mask &amp;Length:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Comprimento da Máscara de Rede IPv6:</translation>
</message>
<message>
<source>Displays the host IPv6 network mask prefix length for this adapter if IPv6 is supported.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra o comprimento da máscara de rede IPv6 do hospedeiro para este adaptador se o IPv6 for suportado.</translation>
</message>
<message>
<source>&amp;DHCP Server</source>
- <translation type="unfinished"></translation>
+ <translation>Servidor &amp;DHCP</translation>
</message>
<message>
<source>&amp;Enable Server</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Activar Servidor</translation>
</message>
<message>
<source>Indicates whether the DHCP Server is enabled on machine startup or not.</source>
- <translation type="unfinished"></translation>
+ <translation>Indica se o servidor DHCP está activado no arranque da máquina.</translation>
</message>
<message>
<source>Server Add&amp;ress:</source>
- <translation type="unfinished"></translation>
+ <translation>Ende&amp;reço do Servidor:</translation>
</message>
<message>
<source>Displays the address of the DHCP server servicing the network associated with this host-only adapter.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra o endereço do servidor DHCP que serve a rede associada com este adaptador apenas do hospedeiro.</translation>
</message>
<message>
<source>Server &amp;Mask:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Máscara do Servidor:</translation>
</message>
<message>
<source>Displays the network mask of the DHCP server servicing the network associated with this host-only adapter.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra a máscara de rede do servidor DHCP que serve a rede associada com este adaptador apenas do hospedeiro.</translation>
</message>
<message>
<source>&amp;Lower Address Bound:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Limite Inferior do Endereço:</translation>
</message>
<message>
<source>Displays the lower address bound offered by the DHCP server servicing the network associated with this host-only adapter.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra o limite inferior do endereço oferecido pelo servidor DHCP que serve a rede associada com este adaptador apenas do hospedeiro.</translation>
</message>
<message>
<source>&amp;Upper Address Bound:</source>
- <translation type="unfinished"></translation>
+ <translation>Limite &amp;Superior do Endereço:</translation>
</message>
<message>
<source>Displays the upper address bound offered by the DHCP server servicing the network associated with this host-only adapter.</source>
+ <translation>Mostra o limite superior do endereço oferecido pelo servidor DHCP que serve a rede associada com este adaptador apenas do hospedeiro.</translation>
+ </message>
+</context>
+<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1706,38 +1835,38 @@
</message>
<message>
<source>Check for:</source>
- <translation type="unfinished"></translation>
+ <translation>Verificar:</translation>
</message>
<message>
<source>&lt;p&gt;Choose this if you only wish to be notified about stable updates to VirtualBox.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Escolha esta se deseja apenas ser notificado acerca de actualizações estáveis para o VirtualBox.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Stable release versions</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Lançamento de versões estáveis</translation>
</message>
<message>
<source>&lt;p&gt;Choose this if you wish to be notified about all new VirtualBox releases.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Escolha esta se deseja apenas ser notificado acerca de todos os lançamentos novos do VirtualBox.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;All new releases</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Todos os novos lançamentos</translation>
</message>
<message>
<source>&lt;p&gt;Choose this to be notified about all new VirtualBox releases and pre-release versions of VirtualBox.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Escolha esta se deseja apenas ser notificado acerca de todos os lançamentos novos e versões de pré-lançamento do VirtualBox.&lt;/p&gt;</translation>
</message>
<message>
<source>All new releases and &amp;pre-releases</source>
- <translation type="unfinished"></translation>
+ <translation>Todos os novos lançamentos e &amp;pré-lançamentos</translation>
</message>
</context>
<context>
<name>UIHelpButton</name>
<message>
<source>&amp;Help</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Ajuda</translation>
</message>
</context>
<context>
@@ -1752,23 +1881,23 @@
</message>
<message>
<source>Left Shift</source>
- <translation>Shift Esquerdo</translation>
+ <translation type="obsolete">Shift Esquerdo</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Shift Direito</translation>
+ <translation type="obsolete">Shift Direito</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Ctrl Esquerdo</translation>
+ <translation type="obsolete">Ctrl Esquerdo</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Ctrl Direito</translation>
+ <translation type="obsolete">Ctrl Direito</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Alt Esquerdo</translation>
+ <translation type="obsolete">Alt Esquerdo</translation>
</message>
<message>
<source>Right Alt</source>
@@ -1920,14 +2049,14 @@
</message>
<message>
<source>None</source>
- <translation type="unfinished">Nenhum</translation>
+ <translation>Nenhum</translation>
</message>
</context>
<context>
<name>UIImportApplianceWzd</name>
<message>
<source>Appliance Import Wizard</source>
- <translation type="unfinished"></translation>
+ <translation>Assistente de Importação de Aplicação</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -1943,6 +2072,10 @@
</message>
<message>
<source>Restore Defaults</source>
+ <translation>Restaurar Predefinições</translation>
+ </message>
+ <message>
+ <source>Import</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1950,65 +2083,66 @@
<name>UIImportApplianceWzdPage1</name>
<message>
<source>Select an appliance to import</source>
- <translation type="unfinished"></translation>
+ <translation>Seleccione uma aplicação para importar</translation>
</message>
<message>
<source>Open Virtualization Format (%1)</source>
- <translation type="unfinished"></translation>
+ <translation>Abrir Formato de Virtualização (%1)</translation>
</message>
<message>
<source>Welcome to the Appliance Import Wizard!</source>
- <translation type="unfinished"></translation>
+ <translation>Bem-vindo ao Assistente de Importação de Aplicação!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will guide you through importing an appliance.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;VirtualBox currently supports importing appliances saved in the Open Virtualization Format (OVF). To continue, select the file to import below:&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Este assistente irá guiá-lo pela importação de uma aplicação.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;O VirtualBox actualmente suporta a importação de aplicações gravada em Abrir Formato de Virtualização (OVF). Para continuar seleccione o ficheiro para importar em baixo:&lt;/p&gt;</translation>
</message>
</context>
<context>
<name>UIImportApplianceWzdPage2</name>
<message>
<source>These are the virtual machines contained in the appliance and the suggested settings of the imported VirtualBox machines. You can change many of the properties shown by double-clicking on the items and disable others using the check boxes below.</source>
- <translation type="unfinished"></translation>
+ <translation>Estas são as máquinas virtuais contidas na aplicação e as definições sugeridas das máquinas VirtualBox importadas. Pode mudar muita das propriedades mostradas ao fazer um cuplo clique nos itens e desactivando outros usando as caixas em baixo.</translation>
</message>
<message>
<source>Appliance Import Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Definições de Importação da Aplicação</translation>
</message>
</context>
<context>
<name>UIImportLicenseViewer</name>
<message>
<source>&lt;b&gt;The virtual system &quot;%1&quot; requires that you agree to the terms and conditions of the software license agreement shown below.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Click &lt;b&gt;Agree&lt;/b&gt; to continue or click &lt;b&gt;Disagree&lt;/b&gt; to cancel the import.</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;b&gt;O sistema virtual &quot;%1&quot; requer que concorde com os termos e condições do acordo da licença do programa mostrado em baixo.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Clique em &lt;b&gt;Concordo&lt;/b&gt; para continuar ou clique em &lt;b&gt;Discordo&lt;/b&gt; para cancelar a importação.</translation>
</message>
<message>
<source>Software License Agreement</source>
- <translation type="unfinished"></translation>
+ <translation>Acordo da Licença do Programa</translation>
</message>
<message>
<source>&amp;Disagree</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Discordo</translation>
</message>
<message>
<source>&amp;Agree</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Concordo</translation>
</message>
<message>
<source>&amp;Print...</source>
- <translation type="unfinished"></translation>
+ <translatorcomment>Im&amp;primir...</translatorcomment>
+ <translation></translation>
</message>
<message>
<source>&amp;Save...</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Gravar...</translation>
</message>
<message>
<source>Text (*.txt)</source>
- <translation type="unfinished"></translation>
+ <translation>Texto (*.txt)</translation>
</message>
<message>
<source>Save license to file...</source>
- <translation type="unfinished"></translation>
+ <translation>Gravar licença para o ficheiro...</translation>
</message>
</context>
<context>
@@ -2087,11 +2221,6 @@
<translation type="obsolete">&lt;hr&gt;O Servidor VRDP está a escutar na porta %1</translation>
</message>
<message>
- <source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
- <comment>Virtualization Stuff LED</comment>
- <translation></translation>
- </message>
- <message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation></translation>
@@ -2106,10 +2235,15 @@
</message>
<message>
<source>Indicates whether the Remote Desktop Server is enabled (&lt;img src=:/vrdp_16px.png/&gt;) or not (&lt;img src=:/vrdp_disabled_16px.png/&gt;).</source>
- <translation type="unfinished"></translation>
+ <translation>Indica se o Servidor de Ecrã Remoto está activado (&lt;img src=:/vrdp_16px.png/&gt;) ou não (&lt;img src=:/vrdp_disabled_16px.png/&gt;).</translation>
</message>
<message>
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
+ <translation>&lt;hr&gt;O Servidor de Ecrã Remoto está a escutar na porta %1</translation>
+ </message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2168,11 +2302,11 @@
</message>
<message>
<source>Host Audio &amp;Driver:</source>
- <translation>&amp;Controlador Audio do Hospedeiro:</translation>
+ <translation>&amp;Controlador Ãudio do Hospedeiro:</translation>
</message>
<message>
<source>Controls the audio output driver. The &lt;b&gt;Null Audio Driver&lt;/b&gt; makes the guest see an audio card, however every access to it will be ignored.</source>
- <translation>Controla o controlador da saída de audio. O &lt;b&gt;Controlador de Audio Nulo&lt;/b&gt; permite que o convidado identifique uma placa de som, no entanto qualquer acesso será ignorado.</translation>
+ <translation>Controla o controlador da saída áudio. O &lt;b&gt;Controlador Ãudio Nulo&lt;/b&gt; permite que o convidado identifique uma placa de som, no entanto qualquer acesso será ignorado.</translation>
</message>
<message>
<source>Audio &amp;Controller:</source>
@@ -2180,119 +2314,127 @@
</message>
<message>
<source>Selects the type of the virtual sound card. Depending on this value, VirtualBox will provide different audio hardware to the virtual machine.</source>
- <translation type="unfinished">Selecciona o tipo da placa de som virtual. Dependendo deste valor, o VirtualBox irá disponibilizar tipo de áudio diferente para a máquina virtual.</translation>
+ <translation>Selecciona o tipo da placa de som virtual. Dependendo deste valor, o VirtualBox fornecerá um tipo de áudio diferente para a máquina virtual.</translation>
</message>
</context>
<context>
<name>UIMachineSettingsDisplay</name>
<message>
<source>you have assigned less than &lt;b&gt;%1&lt;/b&gt; of video memory which is the minimum amount required to switch the virtual machine to fullscreen or seamless mode.</source>
- <translation type="unfinished"></translation>
+ <translation>atribui menos de &lt;b&gt;%1&lt;/b&gt; de memória gráfica que é a quantidade mínima requerida para mudar a máquina virtual para modo de ecrã completo ou modo integrado.</translation>
</message>
<message>
<source>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</source>
- <translation type="unfinished">&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</translation>
+ <translation>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</translation>
</message>
<message>
<source>&amp;Video</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Gráfica</translation>
</message>
<message>
<source>Video &amp;Memory:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Memória Gráfica:</translation>
</message>
<message>
<source>Controls the amount of video memory provided to the virtual machine.</source>
- <translation type="unfinished">Controla a quantidade de memória gráfica alocada para a máquina virtual.</translation>
+ <translation>Controla a quantidade de memória gráfica alocada para a máquina virtual.</translation>
</message>
<message>
<source>MB</source>
- <translation type="unfinished">MB</translation>
+ <translation>MB</translation>
</message>
<message>
<source>Extended Features:</source>
- <translation type="unfinished">Caraterísticas Extendidas:</translation>
+ <translation>Caraterísticas Extendidas:</translation>
</message>
<message>
<source>When checked, the virtual machine will be given access to the 3D graphics capabilities available on the host.</source>
- <translation type="unfinished">Quando seleccionado, a máquina virtual terá acesso à capacidade gráfica 3D disponível no hospedeiro.</translation>
+ <translation>Quando seleccionado, a máquina virtual terá acesso à capacidade gráfica 3D disponível no hospedeiro.</translation>
</message>
<message>
<source>Enable &amp;3D Acceleration</source>
- <translation type="unfinished">Activar Aceleração &amp;3D</translation>
+ <translation>Activar Aceleração &amp;3D</translation>
</message>
<message>
<source>&amp;Remote Display</source>
- <translation type="unfinished"></translation>
+ <translation>Ecrã &amp;Remoto</translation>
</message>
<message>
<source>When checked, the VM will act as a Remote Desktop Protocol (RDP) server, allowing remote clients to connect and operate the VM (when it is running) using a standard RDP client.</source>
- <translation type="unfinished">Quando seleccionado, a MV irá agir como um servidor de Protocolo de Ecrã Remoto (RDP), permitindo a clientes remotos conectarem-se e operarem a MV (quando está a correr) usando um cliente RDP padrão.</translation>
+ <translation>Quando seleccionado, a MV agirá como um servidor de Protocolo de Ecrã Remoto (RDP), permitindo aos clientes remotos conectarem-se e operarem a MV (quando está a correr) usando um cliente RDP padrão.</translation>
</message>
<message>
<source>&amp;Enable Server</source>
- <translation type="unfinished"></translation>
+ <translation>Activar S&amp;ervidor</translation>
</message>
<message>
<source>Server &amp;Port:</source>
- <translation type="unfinished">Porta do &amp;Servidor:</translation>
+ <translation>Porta do &amp;Servidor:</translation>
</message>
<message>
<source>Authentication &amp;Method:</source>
- <translation type="unfinished">&amp;Método de Autenticação:</translation>
+ <translation>&amp;Método de Autenticação:</translation>
</message>
<message>
<source>Defines the VRDP authentication method.</source>
- <translation type="unfinished">Define o método de autenticação VRDP.</translation>
+ <translation>Define o método de autenticação VRDP.</translation>
</message>
<message>
<source>Authentication &amp;Timeout:</source>
- <translation type="unfinished">In&amp;tervalo de Tempo para Autenticação:</translation>
+ <translation>&amp;Tempo de Autenticação:</translation>
</message>
<message>
<source>Specifies the timeout for guest authentication, in milliseconds.</source>
- <translation type="unfinished">Especifica o intervalo de tempo para a autenticação do convidado, em milisegundos.</translation>
+ <translation>Especifica o intervalo de tempo para a autenticação do convidado, em milisegundos.</translation>
</message>
<message>
<source>you have assigned less than &lt;b&gt;%1&lt;/b&gt; of video memory which is the minimum amount required for HD Video to be played efficiently.</source>
- <translation type="unfinished"></translation>
+ <translation>atribui menos de &lt;b&gt;%1&lt;/b&gt; de memória gráfica que é a quantidade mínima requerida para a o Vídeo HD sejam reproduzido eficientemente.</translation>
</message>
<message>
<source>When checked, the virtual machine will be given access to the Video Acceleration capabilities available on the host.</source>
- <translation type="unfinished"></translation>
+ <translation>Quando seleccionado, a memória virtual da máquina terá acesso às capacidades de Aceleração Gráfica disponíveos no hospedeiro.</translation>
</message>
<message>
<source>Enable &amp;2D Video Acceleration</source>
- <translation type="unfinished"></translation>
+ <translation>Activar Aceleração Gráfica &amp;2D</translation>
</message>
<message>
<source>The VRDP Server port number. You may specify &lt;tt&gt;0&lt;/tt&gt; (zero), to select port 3389, the standard port for RDP.</source>
- <translation type="unfinished"></translation>
+ <translation>O número da porta do Servidor VRDP. Pode especificar &lt;tt&gt;0&lt;/tt&gt; (zero), para seleccionar a porta 3389, a porta padrão para o RDP.</translation>
</message>
<message>
<source>Mo&amp;nitor Count:</source>
- <translation type="unfinished"></translation>
+ <translation>Número de Mo&amp;nitores:</translation>
</message>
<message>
<source>Controls the amount of virtual monitors provided to the virtual machine.</source>
- <translation type="unfinished"></translation>
+ <translation>Controla a quantidade de monitores virtuais fornecida pela máquina virtual.</translation>
</message>
<message>
<source>&lt;qt&gt;%1&lt;/qt&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;qt&gt;%1&lt;/qt&gt;</translation>
</message>
<message>
<source>Specifies whether multiple simultaneous connections to the VM are permitted.</source>
- <translation type="unfinished"></translation>
+ <translation>Especifica se são permitidas várias conexões simultâneas para a VM.</translation>
</message>
<message>
<source>&amp;Allow Multiple Connections</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Permitir Várias Conexões </translation>
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="obsolete">Tem a Aceleração 3D activada para um sistema operativo que usa o controlador gráfico WDDM. PAra um desempenho máximo defina a VRAM do convidado para pelo menos &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">tem a Aceleração 2D activada. Como a Acceleraão Vídeo 2D é suportada apenas para convidados Windows, esta opção será desactivada.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsGeneral</name>
@@ -2302,7 +2444,7 @@
</message>
<message>
<source>Displays the path where snapshots of this virtual machine will be stored. Be aware that snapshots can take quite a lot of disk space.</source>
- <translation type="unfinished">Mostra a localização onde as capturas desta máquina virtual serão armazenadas. Note que estas capturas podem ocupar bastante espaço em disco.</translation>
+ <translation>Mostra a localização onde as capturas desta máquina virtual serão armazenadas. Note que estas capturas podem ocupar bastante espaço em disco.</translation>
</message>
<message>
<source>&amp;Basic</source>
@@ -2438,7 +2580,7 @@
</message>
<message>
<source>S&amp;napshot Folder:</source>
- <translation>Pasta de S&amp;napshots:</translation>
+ <translation>Pasta de &amp;Capturas:</translation>
</message>
<message>
<source>&amp;Description</source>
@@ -2482,31 +2624,35 @@
</message>
<message>
<source>Removable Media:</source>
- <translation type="unfinished"></translation>
+ <translation>Média Removível:</translation>
</message>
<message>
<source>&amp;Remember Runtime Changes</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Lembrar Mudanças do Ambiente de Execução</translation>
</message>
<message>
<source>Mini ToolBar:</source>
- <translation type="unfinished"></translation>
+ <translation>Mini Barra de Ferramentas:</translation>
</message>
<message>
<source>If checked, show the Mini ToolBar in Fullscreen and Seamless modes.</source>
- <translation type="unfinished"></translation>
+ <translation>Se seleccionado, mostra a Mini Barra de Ferramentas em modo Ecrã Completo ou Integrado.</translation>
</message>
<message>
<source>Show In &amp;Fullscreen/Seamless</source>
- <translation type="unfinished"></translation>
+ <translation>Mostrar em &amp;Ecrã Completo/Integrado</translation>
</message>
<message>
<source>If checked, show the Mini ToolBar at the top of the screen, rather than in its default position at the bottom of the screen.</source>
- <translation type="unfinished"></translation>
+ <translation>Se seleccionado, mostra a Mini Barra de Ferramentas no topo do ecrã, em vez da sua posição predefinida no fundo do ecrã.</translation>
</message>
<message>
<source>Show At &amp;Top Of Screen</source>
- <translation type="unfinished"></translation>
+ <translation>Mostrar no &amp;Topo do Ecrã</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">seleccionou um SO convidado 64 bit para esta MV. Como tal os convidados requerem virtualização de material (VT-x/AMD-V), esta opção será activada automaticamente.</translation>
</message>
</context>
<context>
@@ -2557,11 +2703,11 @@
</message>
<message>
<source>Displays the MAC address of this adapter. It contains exactly 12 characters chosen from {0-9,A-F}. Note that the second character must be an even digit.</source>
- <translation type="unfinished">Apresenta o endereço MAC deste dispositivo. Contém exactamente 12 caracteres de {0-9,A-F}. O segundo caracter tem de ser um dígito ímpar.</translation>
+ <translation>Mostra o endereço MAC deste dispositivo. Contém exactamente 12 caracteres de {0-9,A-F}. Note que o segundo caracter tem de ser um dígito ímpar.</translation>
</message>
<message>
<source>Generates a new random MAC address.</source>
- <translation type="unfinished">Gera um novo endereço MAC aleatório.</translation>
+ <translation>Gera um novo endereço MAC aleatório.</translation>
</message>
<message>
<source>&amp;Generate</source>
@@ -2569,7 +2715,7 @@
</message>
<message>
<source>Indicates whether the virtual network cable is plugged in on machine startup or not.</source>
- <translation type="unfinished">Indica se o cabo de rede virtual está ligado no arranque da máquina virtual ou não.</translation>
+ <translation>Indica se o cabo de rede virtual está ligado no arranque da máquina virtual ou não.</translation>
</message>
<message>
<source>Ca&amp;ble Connected</source>
@@ -2623,55 +2769,91 @@
</message>
<message>
<source>Adapter &amp;Type:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Tipo de Adaptador:</translation>
</message>
<message>
<source>no bridged network adapter is selected</source>
- <translation type="unfinished"></translation>
+ <translation>não está seleccionado nenhum adaptador de rede em ponte (bridged)</translation>
</message>
<message>
<source>no internal network name is specified</source>
- <translation type="unfinished"></translation>
+ <translation>não está seleccionado nenhum nome de rede interno</translation>
</message>
<message>
<source>no host-only network adapter is selected</source>
- <translation type="unfinished"></translation>
+ <translation>não está seleccionado nenhum adaptador de rede apenas para hospedeiro</translation>
</message>
<message>
<source>Not selected</source>
<comment>network adapter name</comment>
- <translation type="unfinished"></translation>
+ <translation>Não seleccionado</translation>
</message>
<message>
<source>&amp;Name:</source>
- <translation type="unfinished">&amp;Nome:</translation>
+ <translation>&amp;Nome:</translation>
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Selecciona o nome do adaptador de rede para o &lt;b&gt;Adaptador em Ponte (bridged)&lt;/b&gt; ou &lt;b&gt;Adaptador Apenas para Hospedeiro&lt;/b&gt; ligados e o nome da rede &lt;b&gt;Rede Interna&lt;/b&gt; ligada.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
- <translation type="unfinished"></translation>
+ <translation>Avança&amp;do</translation>
</message>
<message>
<source>Shows or hides additional network adapter options.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra ou esconde as opções dos adaptadores de rede adicionais.</translation>
</message>
<message>
<source>&amp;Mac Address:</source>
- <translation type="unfinished"></translation>
+ <translation>Endereço &amp;Mac:</translation>
</message>
<message>
<source>&amp;Cable connected</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Cabo conectado</translation>
</message>
<message>
<source>Opens dialog to manage port forwarding rules.</source>
- <translation type="unfinished"></translation>
+ <translation>Abre o dialogo para gerir as regras de encaminhamento de portas (port forwarding).</translation>
</message>
<message>
<source>&amp;Port Forwarding</source>
+ <translation>&amp;Encaminhamento de &amp;Porta</translation>
+ </message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2750,15 +2932,15 @@
</message>
<message>
<source>Displays the host parallel device name.</source>
- <translation>Mostra o nome do dispositivo paralelo da máquina.</translation>
+ <translation>Mostra o nome do dispositivo paralelo do hospedeiro.</translation>
</message>
<message>
<source>Displays the IRQ number of this parallel port. This should be a whole number between &lt;tt&gt;0&lt;/tt&gt; and &lt;tt&gt;255&lt;/tt&gt;. Values greater than &lt;tt&gt;15&lt;/tt&gt; may only be used if the &lt;b&gt;IO APIC&lt;/b&gt; setting is enabled for this virtual machine.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra o número IRQ desta porta paralela. Isto deve ser um número inteiro &lt;tt&gt;0&lt;/tt&gt; e &lt;tt&gt;255&lt;/tt&gt;. Os valores maiores que &lt;tt&gt;15&lt;/tt&gt; podem apenas ser usados se a opção &lt;b&gt;IO APIC&lt;/b&gt; estiver activada para esta máquina virtual.</translation>
</message>
<message>
<source>Displays the base I/O port address of this parallel port. Valid values are integer numbers in range from &lt;tt&gt;0&lt;/tt&gt; to &lt;tt&gt;0xFFFF&lt;/tt&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra o endereço de porta de E/S base desta porta paralela. Os valores válidos são são números inteiros no intervalo de &lt;tt&gt;0&lt;/tt&gt; até &lt;tt&gt;0xFFFF&lt;/tt&gt;.</translation>
</message>
</context>
<context>
@@ -2780,31 +2962,31 @@
<name>UIMachineSettingsPortForwardingDlg</name>
<message>
<source>Port Forwarding Rules</source>
- <translation type="unfinished"></translation>
+ <translation>Regras de Encaminhamento de Portas</translation>
</message>
<message>
<source>This table contains a list of port forwarding rules.</source>
- <translation type="unfinished"></translation>
+ <translation>Esta tabela contém uma lista de regras de encaminhamento de portas.</translation>
</message>
<message>
<source>Insert new rule</source>
- <translation type="unfinished"></translation>
+ <translation>Inserir nova regra</translation>
</message>
<message>
<source>Copy selected rule</source>
- <translation type="unfinished"></translation>
+ <translation>Copiar regra seleccionada</translation>
</message>
<message>
<source>Delete selected rule</source>
- <translation type="unfinished"></translation>
+ <translation>Apagar regra seleccionada</translation>
</message>
<message>
<source>This button adds new port forwarding rule.</source>
- <translation type="unfinished"></translation>
+ <translation>Este botão adiciona uma nova regra de encaminhamento de portas.</translation>
</message>
<message>
<source>This button deletes selected port forwarding rule.</source>
- <translation type="unfinished"></translation>
+ <translation>Este botão apaga a regra de encaminhamento de portas seleccionada.</translation>
</message>
</context>
<context>
@@ -2851,7 +3033,7 @@
</message>
<message>
<source>Lists all shared folders accessible to this machine. Use &apos;net use x: \\vboxsvr\share&apos; to access a shared folder named &lt;i&gt;share&lt;/i&gt; from a DOS-like OS, or &apos;mount -t vboxsf share mount_point&apos; to access it from a Linux OS. This feature requires Guest Additions.</source>
- <translation type="unfinished"></translation>
+ <translation>Lista todas as pastas partilhadas nesta máquina. Use &apos;net use x: \\vboxsvr\partilha&apos; para aceder à pasta partilhada chamada &lt;i&gt;partilha&lt;/i&gt; num SO do tipo DOS, ou &apos;mount -t vboxsf partilha ponto_de_montagem&apos; para aceder à pasta num SO Linux. Esta opção requer as Adições de Convidado.</translation>
</message>
<message>
<source>Name</source>
@@ -2867,27 +3049,27 @@
</message>
<message>
<source>&amp;Add Shared Folder</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Adicionar Pasta PArtilhada</translation>
</message>
<message>
<source>&amp;Edit Shared Folder</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Editar Pasta Partilhada</translation>
</message>
<message>
<source>&amp;Remove Shared Folder</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Remover Pasta Partilhada</translation>
</message>
<message>
<source>&amp;Folders List</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Lista de Pastas</translation>
</message>
<message>
<source>Auto-Mount</source>
- <translation type="unfinished"></translation>
+ <translation>Auto-Montar</translation>
</message>
<message>
<source>Yes</source>
- <translation type="unfinished">Sim</translation>
+ <translation>Sim</translation>
</message>
</context>
<context>
@@ -2930,15 +3112,15 @@
</message>
<message>
<source>When checked, the guest OS will try to automatically mount the shared folder on startup.</source>
- <translation type="unfinished"></translation>
+ <translation>Quando seleccionado, o SO convidado tentará automaticamente montar a pasta partilhada no arranque.</translation>
</message>
<message>
<source>&amp;Auto-mount</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Auto-montar</translation>
</message>
<message>
<source>If checked, this shared folder will be permanent.</source>
- <translation type="unfinished"></translation>
+ <translation>Se seleccionado, esta pasta partilhada será permanente.</translation>
</message>
</context>
<context>
@@ -3006,15 +3188,15 @@
</message>
<message>
<source>Port/File &amp;Path:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Localização da Porta/Ficheiro:</translation>
</message>
<message>
<source>Displays the IRQ number of this serial port. This should be a whole number between &lt;tt&gt;0&lt;/tt&gt; and &lt;tt&gt;255&lt;/tt&gt;. Values greater than &lt;tt&gt;15&lt;/tt&gt; may only be used if the &lt;b&gt;IO APIC&lt;/b&gt; setting is enabled for this virtual machine.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra o número IRQ desta porta em série. Isto deve ser um número inteiro entre &lt;tt&gt;0&lt;/tt&gt; and &lt;tt&gt;255&lt;/tt&gt;. Os valores maiores que &lt;tt&gt;15&lt;/tt&gt; podem apenas ser usados se a opção &lt;b&gt;IO APIC&lt;/b&gt; estiver activada para esta máquina virtual.</translation>
</message>
<message>
<source>Displays the base I/O port address of this serial port. Valid values are integer numbers in range from &lt;tt&gt;0&lt;/tt&gt; to &lt;tt&gt;0xFFFF&lt;/tt&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra o endereço da porta de E/S base desta porta em série. Os valores válidos são n+umeros inteiros no intervalo de &lt;tt&gt;0&lt;/tt&gt; até &lt;tt&gt;0xFFFF&lt;/tt&gt;.</translation>
</message>
</context>
<context>
@@ -3084,147 +3266,147 @@
</message>
<message>
<source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Bus:&amp;nbsp;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Type:&amp;nbsp;&amp;nbsp;%3&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Janela:&amp;nbsp;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Tipo:&amp;nbsp;&amp;nbsp;%3&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Expand/Collapse&amp;nbsp;Item&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;Expandir/Colapsar&amp;nbsp;Item&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Add&amp;nbsp;Hard&amp;nbsp;Disk&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;Adicionar&amp;nbsp;Disco&amp;nbsp;Rígido&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Add&amp;nbsp;CD/DVD&amp;nbsp;Device&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;Adicionar&amp;nbsp;Dispositivo&amp;nbsp;CD/DVD&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Add&amp;nbsp;Floppy&amp;nbsp;Device&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;Adicionar&amp;nbsp;Dispositivo&amp;nbsp;Disquete&lt;/nobr&gt;</translation>
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Nenhum disco rígido seleccionado para &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>Add Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Adicionar Controlador</translation>
</message>
<message>
<source>Add IDE Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Adicionar Controlador IDE</translation>
</message>
<message>
<source>Add SATA Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Adicionar Controlador SATA</translation>
</message>
<message>
<source>Add SCSI Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Adicionar Controlador SCSI</translation>
</message>
<message>
<source>Add Floppy Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Adicionar Controlador de Disquete</translation>
</message>
<message>
<source>Remove Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Remover Controlador</translation>
</message>
<message>
<source>Add Attachment</source>
- <translation type="unfinished">Adicionar Ligação</translation>
+ <translation>Adicionar Ligação</translation>
</message>
<message>
<source>Add Hard Disk</source>
- <translation type="unfinished"></translation>
+ <translation>Adicionar Disco Rígido</translation>
</message>
<message>
<source>Add CD/DVD Device</source>
- <translation type="unfinished"></translation>
+ <translation>Adicionar Dispositivo CD/DVD</translation>
</message>
<message>
<source>Add Floppy Device</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>Remove Attachment</source>
- <translation type="unfinished">Remover Ligação</translation>
+ <translation>Remover Ligação</translation>
</message>
<message>
<source>Adds a new controller to the end of the Storage Tree.</source>
- <translation type="unfinished"></translation>
+ <translation>Adiciona um novo controlador ao fim da Ãrvoe de Armazenamento.</translation>
</message>
<message>
<source>Removes the controller highlighted in the Storage Tree.</source>
- <translation type="unfinished"></translation>
+ <translation>Remove o controlador destacado na Ãrvore de Armazenamento.</translation>
</message>
<message>
<source>Adds a new attachment to the Storage Tree using currently selected controller as parent.</source>
- <translation type="unfinished"></translation>
+ <translation>Adiciona uma nova ligação à Ãrvore de Armazenamento usando o controlador seleccionado actual como principal.</translation>
</message>
<message>
<source>Removes the attachment highlighted in the Storage Tree.</source>
- <translation type="unfinished"></translation>
+ <translation>Remove a ligação destacada na Ãrvore de Armazenamento.</translation>
</message>
<message>
<source>IDE Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Controlador IDE</translation>
</message>
<message>
<source>SATA Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Controlador SATA</translation>
</message>
<message>
<source>SCSI Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Controlador SCSI</translation>
</message>
<message>
<source>Floppy Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Controlador de Disquete</translation>
</message>
<message>
<source>Hard &amp;Disk:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Disco Rígido:</translation>
</message>
<message>
<source>&amp;Storage Tree</source>
- <translation type="unfinished"></translation>
+ <translation>Ãrvore de Arma&amp;zenamento</translation>
</message>
<message>
<source>Contains all storage controllers for this machine and the virtual images and host drives attached to them.</source>
- <translation type="unfinished"></translation>
+ <translation>Contém todos os controladores de armazenamento para esta máquina e as imagens virtuais e dispositivos de hospedeito ligados a estes.</translation>
</message>
<message>
<source>Information</source>
- <translation type="unfinished"></translation>
+ <translation>Informação</translation>
</message>
<message>
<source>The Storage Tree can contain several controllers of different types. This machine currently has no controllers.</source>
- <translation type="unfinished"></translation>
+ <translation>A Ãrvore de Armazenamento pode conter vários controladores de diferentes tipos. Esta máquina actualmente não tem controladores.</translation>
</message>
<message>
<source>Attributes</source>
- <translation type="unfinished"></translation>
+ <translation>Atributos</translation>
</message>
<message>
<source>&amp;Name:</source>
- <translation type="unfinished">&amp;Nome:</translation>
+ <translation>&amp;Nome:</translation>
</message>
<message>
<source>Changes the name of the storage controller currently selected in the Storage Tree.</source>
- <translation type="unfinished"></translation>
+ <translation>Muda o nome do controladores de armazenamento actualmente seleccionado na Ãrvore de Armazenamento.</translation>
</message>
<message>
<source>&amp;Type:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Tipo:</translation>
</message>
<message>
<source>Selects the sub-type of the storage controller currently selected in the Storage Tree.</source>
- <translation type="unfinished"></translation>
+ <translation>Selecciona o sub-tipo de controlador de armazenamento seleccionado actualmente na Ãrvore de Armazenamento.</translation>
</message>
<message>
<source>Selects the slot on the storage controller used by this attachment. The available slots depend on the type of the controller and other attachments on it.</source>
@@ -3240,55 +3422,55 @@
</message>
<message>
<source>Virtual Size:</source>
- <translation type="unfinished"></translation>
+ <translation>Tamanho Virtual:</translation>
</message>
<message>
<source>Actual Size:</source>
- <translation type="unfinished"></translation>
+ <translation>Tamanho Actual:</translation>
</message>
<message>
<source>Size:</source>
- <translation type="unfinished"></translation>
+ <translation>Tamanho:</translation>
</message>
<message>
<source>Location:</source>
- <translation type="unfinished"></translation>
+ <translation>Localização:</translation>
</message>
<message>
<source>Type (Format):</source>
- <translation type="unfinished"></translation>
+ <translation>Tipo (Formato):</translation>
</message>
<message>
<source>Attached To:</source>
- <translation type="unfinished"></translation>
+ <translation>Ligado a:</translation>
</message>
<message>
<source>Allows to use host I/O caching capabilities.</source>
- <translation type="unfinished"></translation>
+ <translation>Permite usar as capacidades de caixa de E/S do hospedeiro.</translation>
</message>
<message>
<source>Use host I/O cache</source>
- <translation type="unfinished"></translation>
+ <translation>Usar caixa de E/S do hospedeiro</translation>
</message>
<message>
<source>Add SAS Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Adicionar Controlador SAS</translation>
</message>
<message>
<source>SAS Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Controlador SAS</translation>
</message>
<message>
<source>Type:</source>
- <translation type="unfinished"></translation>
+ <translation>Tipo:</translation>
</message>
<message>
<source>Host Drive</source>
- <translation type="unfinished">Dispositivo do Hospedeiro</translation>
+ <translation>Dispositivo do Hospedeiro</translation>
</message>
<message>
<source>Image</source>
- <translation type="unfinished">Imagem</translation>
+ <translation>Imagem</translation>
</message>
<message>
<source>Choose or create a virtual hard disk file. The virtual machine will see the data in the file as the contents of the virtual hard disk.</source>
@@ -3296,50 +3478,104 @@
</message>
<message>
<source>Set up the virtual hard disk</source>
- <translation type="unfinished"></translation>
+ <translation>Definir o disco rígido virtual</translation>
</message>
<message>
<source>CD/DVD &amp;Drive:</source>
- <translation type="unfinished"></translation>
+ <translation>Uni&amp;dade CD/DVD:</translation>
</message>
<message>
<source>Choose a virtual CD/DVD disk or a physical drive to use with the virtual drive. The virtual machine will see a disk inserted into the drive with the data in the file or on the disk in the physical drive as its contents.</source>
- <translation type="unfinished"></translation>
+ <translation>Escolha um CD/DVD virtual ou uma unidade física para usar com o dispositivo virtual. A máquina virtual procurará um disco inserido no dispositivo com os dados no ficheiro ou num disco na unidade física assim como os seus conteúdos.</translation>
</message>
<message>
<source>Set up the virtual CD/DVD drive</source>
- <translation type="unfinished"></translation>
+ <translation>Definir o dispositivo CD/DVD virtual</translation>
</message>
<message>
<source>Floppy &amp;Drive:</source>
- <translation type="unfinished"></translation>
+ <translation>Unidade &amp;Disquete:</translation>
</message>
<message>
<source>Choose a virtual floppy disk or a physical drive to use with the virtual drive. The virtual machine will see a disk inserted into the drive with the data in the file or on the disk in the physical drive as its contents.</source>
- <translation type="unfinished"></translation>
+ <translation>Escolha uma disquete virtual ou uma unidade física para usar com o dispositivo virtual. A máquina virtual procurará um disco inserido no dispositivo com dados no ficheiro ou um disco na unidade física assim como os seus conteúdos.</translation>
</message>
<message>
<source>Set up the virtual floppy drive</source>
- <translation type="unfinished"></translation>
+ <translation>Definir o dispositivo de disquete virtual</translation>
</message>
<message>
<source>Create a new hard disk...</source>
- <translation type="unfinished"></translation>
+ <translation>Criar um novo disco rígido...</translation>
</message>
<message>
<source>Choose a virtual hard disk file...</source>
- <translation type="unfinished"></translation>
+ <translation>Escolher um ficheiro de disco rígido virtual...</translation>
</message>
<message>
<source>Choose a virtual CD/DVD disk file...</source>
- <translation type="unfinished"></translation>
+ <translation>Escolher um ficheiro de CD/DVD virtual...</translation>
</message>
<message>
<source>Remove disk from virtual drive</source>
- <translation type="unfinished"></translation>
+ <translation>Remover disco de dispositivo virtual</translation>
</message>
<message>
<source>Choose a virtual floppy disk file...</source>
+ <translation>Escolher um ficheiro de disquete virtual...</translation>
+ </message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">até no máximo um suportado</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">até %1 suportado</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">está actualmente a usar mais controladores de armazenamento do que o &apos;chipset&apos; %1 suporta. Por favor mude o tipo de &apos;chipset&apos; na página de definições do sistema ou reduza o número de controladores de armazenamento na página de definições de Armazenamento: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -3371,56 +3607,56 @@
</message>
<message>
<source>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</source>
- <translation type="unfinished">&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</translation>
+ <translation>&lt;qt&gt;%1&amp;nbsp;MB&lt;/qt&gt;</translation>
</message>
<message>
<source>&lt;qt&gt;%1&amp;nbsp;CPU&lt;/qt&gt;</source>
<comment>%1 is 1 for now</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;qt&gt;%1&amp;nbsp;CPU&lt;/qt&gt;</translation>
</message>
<message>
<source>&amp;Motherboard</source>
- <translation type="unfinished"></translation>
+ <translation>Placa &amp;Mãe</translation>
</message>
<message>
<source>Base &amp;Memory:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Memória Base:</translation>
</message>
<message>
<source>Controls the amount of memory provided to the virtual machine. If you assign too much, the machine might not start.</source>
- <translation type="unfinished">Controla a quantidade de memória disponibilizada para a máquina virtual. Se alocar demasiada memória, a máquina virtual poderá não iniciar.</translation>
+ <translation>Controla a quantidade de memória disponibilizada para a máquina virtual. Se alocar demasiada memória, a máquina virtual poderá não iniciar.</translation>
</message>
<message>
<source>MB</source>
- <translation type="unfinished">MB</translation>
+ <translation>MB</translation>
</message>
<message>
<source>&amp;Boot Order:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Ordem de Arranque:</translation>
</message>
<message>
<source>Defines the boot device order. Use the checkboxes on the left to enable or disable individual boot devices. Move items up and down to change the device order.</source>
- <translation type="unfinished">Define a ordem de arranque dos dispositivos. Use as caixas do lado esquerdo para activar ou desactivar os dispositivos de arranque individualmente. Mova os itens para cima ou para biaxo para alterar a ordem de arranque.</translation>
+ <translation>Define a ordem de arranque dos dispositivos. Use as caixas do lado esquerdo para activar ou desactivar os dispositivos de arranque individualmente. Mova os itens para cima ou para biaxo para alterar a ordem de arranque.</translation>
</message>
<message>
<source>Move Down (Ctrl-Down)</source>
- <translation type="unfinished">Mover para Baixo (Ctrl-Seta para Baixo)</translation>
+ <translation>Mover para Baixo (Ctrl-Seta para Baixo)</translation>
</message>
<message>
<source>Moves the selected boot device down.</source>
- <translation type="unfinished">Move o dispositivo de arranque seleccionado para baixo.</translation>
+ <translation>Move o dispositivo de arranque seleccionado para baixo.</translation>
</message>
<message>
<source>Move Up (Ctrl-Up)</source>
- <translation type="unfinished">Mover para Cima (Ctrl-Seta para Cima)</translation>
+ <translation>Mover para Cima (Ctrl-Seta para Cima)</translation>
</message>
<message>
<source>Moves the selected boot device up.</source>
- <translation type="unfinished">Move o dispositivo de arranque seleccionado para cima.</translation>
+ <translation>Move o dispositivo de arranque seleccionado para cima.</translation>
</message>
<message>
<source>Extended Features:</source>
- <translation type="unfinished">Caraterísticas Extendidas:</translation>
+ <translation>Caraterísticas Extendidas:</translation>
</message>
<message>
<source>When checked, the virtual machine will support the Advanced Configuration and Power Management Interface (ACPI). &lt;b&gt;Note:&lt;/b&gt; don&apos;t disable this feature after having installed a Windows guest operating system!</source>
@@ -3428,43 +3664,43 @@
</message>
<message>
<source>When checked, the virtual machine will support the Input Output APIC (IO APIC), which may slightly decrease performance. &lt;b&gt;Note:&lt;/b&gt; don&apos;t disable this feature after having installed a Windows guest operating system!</source>
- <translation type="unfinished">Quando seleccionado, a máquina virtual suportará &quot;Input Output APIC&quot; (IO APIC), o que poderá reduzir ligeiramente a performance da Máquina Virtual. &lt;b&gt;Atenção:&lt;/b&gt; não desactivar esta opção depois de instalar um sistema operativo convidado Windows!</translation>
+ <translation>Quando seleccionado, a máquina virtual suportará &quot;Input Output APIC&quot; (IO APIC), o que poderá reduzir ligeiramente o desempenho da Máquina Virtual. &lt;b&gt;Atenção:&lt;/b&gt; não desactive esta opção depois de instalar um sistema operativo convidado Windows!</translation>
</message>
<message>
<source>Enable &amp;IO APIC</source>
- <translation type="unfinished"></translation>
+ <translation>Activar &amp;IO APIC</translation>
</message>
<message>
<source>&amp;Processor</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Processador</translation>
</message>
<message>
<source>&amp;Processor(s):</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Processador(es):</translation>
</message>
<message>
<source>When checked, the Physical Address Extension (PAE) feature of the host CPU will be exposed to the virtual machine.</source>
- <translation type="unfinished">Quando seleccionado, a opção &quot;Physical Address Extension&quot; (PAE) do CPU Hospedeiro será disponibilizada à máquina virtual.</translation>
+ <translation>Quando seleccionado, a opção &quot;Physical Address Extension&quot; (PAE) do CPU Hospedeiro será disponibilizada para a máquina virtual.</translation>
</message>
<message>
<source>Enable PA&amp;E/NX</source>
- <translation type="unfinished">Activar PA&amp;E/NX</translation>
+ <translation>Activar PA&amp;E/NX</translation>
</message>
<message>
<source>Acce&amp;leration</source>
- <translation type="unfinished"></translation>
+ <translation>Ace&amp;laração</translation>
</message>
<message>
<source>Hardware Virtualization:</source>
- <translation type="unfinished"></translation>
+ <translation>Virtualização de Material:</translation>
</message>
<message>
<source>When checked, the virtual machine will try to make use of the host CPU&apos;s hardware virtualization extensions such as Intel VT-x and AMD-V.</source>
- <translation type="unfinished">Quando seleccionado, a máquina virtual tentará utilizar extensões de suporta a virtualização do CPU do PC Hospedeiro, tais como a Intel VT-x e AMD-V.</translation>
+ <translation>Quando seleccionado, a máquina virtual tentará utilizar extensões de virtualização do CPU do hospedeiro, tais como a Intel VT-x e AMD-V.</translation>
</message>
<message>
<source>Enable &amp;VT-x/AMD-V</source>
- <translation type="unfinished">Activar &amp;VT-x/AMD-V</translation>
+ <translation>Activar &amp;VT-x/AMD-V</translation>
</message>
<message>
<source>When checked, the virtual machine will try to make use of the nested paging extension of Intel VT-x and AMD-V.</source>
@@ -3509,7 +3745,7 @@
</message>
<message>
<source>&amp;Chipset:</source>
- <translation type="unfinished"></translation>
+ <translation>&apos;&amp;Chipset&apos;:</translation>
</message>
<message>
<source>Defines chipset type used in this VM.</source>
@@ -3519,6 +3755,32 @@
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished">activou um HID (Human Interface Device) USB. Isto não funcionará a não ser que a emulação USB esteja também activada. Isto será feito automaticamente quando aceitar as definições MV ao premir o butão OK.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3548,11 +3810,11 @@
</message>
<message>
<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 type="unfinished"></translation>
+ <translation>Adiciona um filtro USB com todos os campos inicialmente definidos para vazios. Note que tal filtro corresponderá a qualquer dispositivo USB ligado.</translation>
</message>
<message>
<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 type="unfinished"></translation>
+ <translation>Adiciona um filtro USB com todos os campos definidos para os valores do dispositivo USB seleccionado ligado ao PC hospedeiro.</translation>
</message>
<message>
<source>Edits the selected USB filter.</source>
@@ -3597,7 +3859,7 @@
</message>
<message>
<source>Lists all USB filters of this machine. The checkbox to the left defines whether the particular filter is enabled or not. Use the context menu or buttons to the right to add or remove USB filters.</source>
- <translation type="unfinished"></translation>
+ <translation>Lista todos os filtros USB desta máquina. A caixa de verificação à esquerda define se um filtro em particular está activado ou não. Use o menu de contexto ou os botões à direita para adicionar ou remover filtros USB.</translation>
</message>
<message>
<source>[filter]</source>
@@ -3606,45 +3868,49 @@
<message>
<source>&lt;nobr&gt;Vendor ID: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;ID do Fabricante: %1&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Product ID: %2&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;ID do Produto: %2&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Revision: %3&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;Revisão: %3&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Product: %4&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished">&lt;nobr&gt;Produto: %4&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt;Produto: %4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Manufacturer: %5&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished">&lt;nobr&gt;Fabricante: %5&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt;Fabricante: %5&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Serial No.: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished">&lt;nobr&gt;Número de série: %1&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt;Número de Série: %1&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Port: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;Porta: %1&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;State: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;Estado: %1&lt;/nobr&gt;</translation>
</message>
<message>
<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="obsolete">O USB 2.0 está actualmente activado para esta máquina virtual. No entanto isto requer que o &lt;b&gt;%1&lt;/b&gt; seja instalado. Por favor instale o Pacote de Extensão do sítio de transferências do VirtualBox. Depois poderá re-activar o USB 2.0. Será desactivado entretanto a não ser que cancele as alterações das definições actuais.</translation>
+ </message>
+ <message>
+ <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>
</context>
@@ -3758,52 +4024,67 @@
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
- <translation type="unfinished">Cancelar</translation>
+ <translation>Cancelar</translation>
</message>
<message>
<source>Cancel the VirtualBox Guest Additions CD image download</source>
- <translation type="unfinished"></translation>
+ <translation>Cancela a transferência da imagem de CD das Adições de Convidado VirtualBox</translation>
</message>
<message>
<source>Downloading the VirtualBox Guest Additions CD image from &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;...&lt;/nobr&gt;</source>
- <translation type="unfinished">A transferir a imagem de CD das Adições de Convidado VirtualBox de &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;...&lt;/nobr&gt;</translation>
+ <translation>A transferir a imagem de CD das Adições de Convidado VirtualBox de &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;...&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UIMiniProcessWidgetUserManual</name>
<message>
<source>Cancel</source>
- <translation type="unfinished">Cancelar</translation>
+ <translation>Cancelar</translation>
</message>
<message>
<source>Cancel the VirtualBox User Manual download</source>
- <translation type="unfinished"></translation>
+ <translation>Cancela a transferência do Manual de Utilizador VirtualBox</translation>
</message>
<message>
<source>Downloading the VirtualBox User Manual</source>
- <translation type="unfinished"></translation>
+ <translation>A transferir o Manual de Utilizador VirtualBox</translation>
</message>
<message>
<source>Downloading the VirtualBox User Manual &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;...&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>A transferir o Manual de Utilizador VirtualBox &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;...&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UIMultiScreenLayout</name>
<message>
<source>Virtual Screen %1</source>
- <translation type="unfinished"></translation>
+ <translation>Ecrã Virtual %1</translation>
</message>
<message>
<source>Use Host Screen %1</source>
- <translation type="unfinished"></translation>
+ <translation>Usar Ecrã Hospedeiro %1</translation>
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Criar Novo Disco Virtual</translation>
@@ -3892,7 +4173,7 @@ sistema operativo Convidado com o tamanho do disco rígido virtual.&lt;/p&gt;</t
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Sumário</translation>
+ <translation type="unfinished">Sumário</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -3908,7 +4189,7 @@ sistema operativo Convidado com o tamanho do disco rígido virtual.&lt;/p&gt;</t
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Seleccione um ficheiro para a nova imagem de disco rígido</translation>
+ <translation type="unfinished">Seleccione um ficheiro para a nova imagem de disco rígido</translation>
</message>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;
@@ -3946,12 +4227,12 @@ demorar algum tempo dependendo do tamanho da imagem e do desempenho do seu disco
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Localização</translation>
+ <translation type="unfinished">Localização</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Tamanho</translation>
+ <translation type="unfinished">Tamanho</translation>
</message>
<message>
<source>Cancel</source>
@@ -3989,108 +4270,276 @@ demorar algum tempo dependendo do tamanho da imagem e do desempenho do seu disco
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Se a configuração anterior estiver correcta, pressione o botão &lt;b&gt;Terminar&lt;/b&gt;. Assim que o pressionar, um novo disco será criado.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
<message>
- <source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation type="unfinished">Bem-vindo ao Assistente de Criação de Discos Rígidos Virtuais!</translation>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;Localização</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Tamanho</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>UINewHDWzdPage2</name>
+ <name>UINewHDWizardPageWelcome</name>
<message>
- <source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
+ <source>Welcome to the Create New Virtual Disk Wizard!</source>
+ <translation type="obsolete">Bem-vindo ao Assistente de Criação de Discos Rígidos Virtuais!</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <translation type="obsolete">&lt;p&gt;Este assistente irá ajudá-lo a criar um novo disco rígido virtual para a sua máquina virtual.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWzdPage2</name>
+ <message>
<source>Storage Type</source>
- <translation type="unfinished">Tipo de Armazenamento</translation>
+ <translation type="obsolete">Tipo de Armazenamento</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation type="unfinished">Armazenamento expandido &amp;dinâmicamente</translation>
+ <translation type="obsolete">Armazenamento expandido &amp;dinâmicamente</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation type="unfinished">Armazenamento de tamanho &amp;Fixo</translation>
+ <translation type="obsolete">Armazenamento de tamanho &amp;Fixo</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation type="unfinished">Tipo de Armazenamento do Disco Rígido Virtual</translation>
+ <translation type="obsolete">Tipo de Armazenamento do Disco Rígido</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">&lt;p&gt;Prima o botão &lt;b&gt;Seleccionar&lt;/b&gt; para seleccionar a localização de um ficheiro para armazenar os dados do disco rígido ou digite um nome no campo de entrada.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation type="unfinished">&amp;Localização</translation>
+ <translation type="obsolete">&amp;Localização</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">&lt;p&gt;Seleccione o tamanho do disco rígido virtual em megabytes. Este tamanho será reportadoo para o SO Convidado como o tamanho máximo deste disco rígido.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation type="unfinished">&amp;Tamanho</translation>
+ <translation type="obsolete">&amp;Tamanho</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation type="unfinished">Localização do Disco Virtual e Tamanho</translation>
+ <translation type="obsolete">Localização do Disco Virtual e Tamanho</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="unfinished">Seleccione um ficheiro para a nova imagem de disco rígido</translation>
+ <translation type="obsolete">Seleccione um ficheiro para a nova imagem de disco rígido</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation type="unfinished">Imagens de disco rígido (*.vdi)</translation>
+ <translation type="obsolete">Imagens de disco rígido (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation type="unfinished">Está prestes a criar um novo disco rígido virtual com as seguintes características:</translation>
+ <translation type="obsolete">Está prestes a criar um novo disco rígido virtual com as seguintes características:</translation>
</message>
<message>
<source>Summary</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Sumário</translation>
</message>
<message>
<source>%1 B</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation type="unfinished">Tipo</translation>
+ <translation type="obsolete">Tipo</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="unfinished">Localização</translation>
+ <translation type="obsolete">Localização</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="unfinished">Tamanho</translation>
+ <translation type="obsolete">Tamanho</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Se as definições em cima estiverem correctas, prima o botão &lt;b&gt;%1&lt;/b&gt;. Assim que o tiver premido, será criado um novo disco rígido.</translation>
</message>
</context>
<context>
@@ -4294,16 +4743,20 @@ diálogo de Configurações da MV.&lt;/p&gt;</translation>
<source>Cancel</source>
<translation type="obsolete">Cancelar</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
<message>
<source>Welcome to the New Virtual Machine Wizard!</source>
- <translation type="unfinished">Bem-vindo ao Assistente de Criação de Máquina Virtual!</translation>
+ <translation>Bem-vindo ao Assistente de Criação de Máquina Virtual!</translation>
</message>
<message>
<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 type="unfinished"></translation>
+ <translation>&lt;p&gt;Este assistente irá guiá-lo através dos passos necessários para criar uma nova máquina virtual para o VirtualBox.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
</context>
<context>
@@ -4314,38 +4767,38 @@ diálogo de Configurações da MV.&lt;/p&gt;</translation>
</message>
<message>
<source>N&amp;ame</source>
- <translation type="unfinished">N&amp;ome</translation>
+ <translation>N&amp;ome</translation>
</message>
<message>
<source>OS &amp;Type</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Tipo de SO</translation>
</message>
<message>
<source>VM Name and OS Type</source>
- <translation type="unfinished">Nome da MV e Tipo de Sistema Operativo</translation>
+ <translation>Nome da MV e Tipo de SO</translation>
</message>
</context>
<context>
<name>UINewVMWzdPage3</name>
<message>
<source>&lt;p&gt;Select the amount of base memory (RAM) in megabytes to be allocated to the virtual machine.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Seleccione a quantidade de memória (RAM) em megabytes a ser alocada para a máquina virtual.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Seleccione a quantidade de memória (RAM) em megabytes para ser alocada para a máquina virtual.&lt;/p&gt;</translation>
</message>
<message>
<source>Base &amp;Memory Size</source>
- <translation type="unfinished"></translation>
+ <translation>Tamanho da &amp;Memória Base</translation>
</message>
<message>
<source>MB</source>
- <translation type="unfinished">MB</translation>
+ <translation>MB</translation>
</message>
<message>
<source>Memory</source>
- <translation type="unfinished">Memória</translation>
+ <translation>Memória</translation>
</message>
<message>
<source>The recommended base memory size is &lt;b&gt;%1&lt;/b&gt; MB.</source>
- <translation type="unfinished">O tamanho recomendado para memória principal é de &lt;b&gt;%1&lt;/b&gt; MB.</translation>
+ <translation>O tamanho recomendado para memória base é &lt;b&gt;%1&lt;/b&gt; MB.</translation>
</message>
<message>
<source>MB</source>
@@ -4357,15 +4810,15 @@ diálogo de Configurações da MV.&lt;/p&gt;</translation>
<name>UINewVMWzdPage4</name>
<message>
<source>&amp;Create new hard disk</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Criar novo disco rígido</translation>
</message>
<message>
<source>&amp;Use existing hard disk</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Usar disco rígido existente</translation>
</message>
<message>
<source>Virtual Hard Disk</source>
- <translation type="unfinished">Disco Rígido Virtual</translation>
+ <translation>Disco Rígido Virtual</translation>
</message>
<message>
<source>The recommended size of the boot hard disk is &lt;b&gt;%1&lt;/b&gt; MB.</source>
@@ -4373,45 +4826,45 @@ diálogo de Configurações da MV.&lt;/p&gt;</translation>
</message>
<message>
<source>Boot Hard &amp;Disk</source>
- <translation type="unfinished"></translation>
+ <translation>Arrancar &amp;Disco Rígido</translation>
</message>
<message>
<source>&lt;p&gt;Select a virtual hard disk to be used as the boot hard disk of the virtual machine. You can either create a new hard disk or select an existing one from the drop-down list or by pressing corresponding button (to invoke file-open window).&lt;/p&gt;&lt;p&gt;If you need a more complicated hard disk setup, you can also skip this step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Selecciona um disco rígido virtual para ser usado como o disco rígido de arranque da máquina virtual. Pod criar um novo disco rígido ou seleccionar um existente da lista ou premindo o botão correspondente (para invocar a janela de ficheiro aberto).&lt;/p&gt;&lt;p&gt;Se precisar de uma definição de disco rígido mais complicada, pode também saltar este passo e ligar discos rígidos mais tarde usando o diálogo de Definições da MV.&lt;/p&gt;</translation>
</message>
<message>
<source>Choose a virtual hard disk file...</source>
- <translation type="unfinished"></translation>
+ <translation>Escolha um ficheiro de disco rígido virtual...</translation>
</message>
<message>
<source>The recommended size of the boot hard disk is &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>O tamanho recomendado do disco rígido de arranque é &lt;b&gt;%1&lt;/b&gt;.</translation>
</message>
</context>
<context>
<name>UINewVMWzdPage5</name>
<message>
<source>&lt;p&gt;You are going to create a new virtual machine with the following parameters:&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Está prestes a criar uma nova máquina virtual com os seguintes parâmetros:&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="unfinished"></translation>
+ <translation>Sumário</translation>
</message>
<message>
<source>Name</source>
<comment>summary</comment>
- <translation type="unfinished">Nome</translation>
+ <translation>Nome</translation>
</message>
<message>
<source>OS Type</source>
<comment>summary</comment>
- <translation type="unfinished">Tipo de Sistema Operativo</translation>
+ <translation>Tipo de SO</translation>
</message>
<message>
<source>Base Memory</source>
<comment>summary</comment>
- <translation type="unfinished">Memória Principal</translation>
+ <translation>Memória Base</translation>
</message>
<message>
<source>MB</source>
@@ -4421,155 +4874,269 @@ diálogo de Configurações da MV.&lt;/p&gt;</translation>
<message>
<source>Boot Hard Disk</source>
<comment>summary</comment>
- <translation type="unfinished"></translation>
+ <translation>Arrancar Disco Rígido</translation>
</message>
<message>
<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 type="unfinished"></translation>
+ <translation>&lt;p&gt;Se o que está em cima estiver correcto prima o botão &lt;b&gt;%1&lt;/b&gt;. Assim que o tiver premido, será criada uma nova máquina virtual. &lt;/p&gt;&lt;p&gt;Note que pode alterar todas estas definições da máquina virtual criada em qualquer altura usando o diálogo &lt;b&gt;Definições&lt;/b&gt; acessível através do menu da janela principal.&lt;/p&gt;</translation>
</message>
</context>
<context>
<name>UIPortForwardingModel</name>
<message>
<source>Name</source>
- <translation type="unfinished">Nome</translation>
+ <translation>Nome</translation>
</message>
<message>
<source>Protocol</source>
- <translation type="unfinished"></translation>
+ <translation>Protocolo</translation>
</message>
<message>
<source>Host IP</source>
- <translation type="unfinished"></translation>
+ <translation>IP do Hospedeiro</translation>
</message>
<message>
<source>Host Port</source>
- <translation type="unfinished"></translation>
+ <translation>Porta do Hospedeiro</translation>
</message>
<message>
<source>Guest IP</source>
- <translation type="unfinished"></translation>
+ <translation>IP do Convidado</translation>
</message>
<message>
<source>Guest Port</source>
- <translation type="unfinished"></translation>
+ <translation>Porta do Convidado</translation>
</message>
</context>
<context>
<name>UIProgressDialog</name>
<message>
<source>A few seconds remaining</source>
- <translation type="unfinished"></translation>
+ <translation>Faltam alguns segundos</translation>
</message>
<message>
<source>Canceling...</source>
- <translation type="unfinished"></translation>
+ <translation>A cancelar...</translation>
</message>
<message>
<source>&amp;Cancel</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Cancelar</translation>
</message>
<message>
<source>Cancel the current operation</source>
- <translation type="unfinished"></translation>
+ <translation>Cancela a operação actual</translation>
</message>
<message>
<source>%1, %2 remaining</source>
<comment>You may wish to translate this more like &quot;Time remaining: %1, %2&quot;</comment>
- <translation type="unfinished"></translation>
+ <translation>%1, %2 em falta</translation>
</message>
<message>
<source>%1 remaining</source>
<comment>You may wish to translate this more like &quot;Time remaining: %1&quot;</comment>
- <translation type="unfinished"></translation>
+ <translation>%1 em falta</translation>
</message>
</context>
<context>
<name>UISession</name>
<message>
<source>Install</source>
- <translation type="unfinished"></translation>
+ <translation>Instalar</translation>
</message>
</context>
<context>
<name>UISettingsDialog</name>
<message>
<source>&lt;i&gt;Select a settings category from the list on the left-hand side and move the mouse over a settings item to get more information.&lt;/i&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;i&gt;Seleccione uma categoria de definições da lista do lado esquerdo e mova o rato sobre um item de definições para obter mais informação.&lt;/i&gt;</translation>
</message>
<message>
<source>On the &lt;b&gt;%1&lt;/b&gt; page, %2</source>
- <translation type="unfinished">Na página &lt;b&gt;%1&lt;/b&gt;, &lt;b&gt;%2&lt;/b&gt;</translation>
+ <translation>Na página &lt;b&gt;%1&lt;/b&gt;, %2</translation>
</message>
<message>
<source>Invalid settings detected</source>
- <translation type="unfinished"></translation>
+ <translation>Definições inválidas detectadas</translation>
</message>
<message>
<source>Non-optimal settings detected</source>
- <translation type="unfinished">Configuração não-óptima foi detectada</translation>
+ <translation>Definições não-óptimizadas detectadas</translation>
</message>
<message>
<source>Settings</source>
- <translation type="unfinished">Configurações</translation>
+ <translation>Definições</translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Geral</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Entrada</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Actualizar</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Língua</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rede</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Extensões</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Geral</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>Sistema</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Ecrã</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Armazenamento</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Ãudio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rede</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Portas</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Portas Série</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Portas Paralelas</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Pastas Partilhadas</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">seleccionou um SO convidado 64 bit para esta MV. Como tal os convidados requerem virtualização de material (VT-x/AMD-V), esta opção será activada automaticamente.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">tem a Aceleração 2D activada. Como a Acceleraão Vídeo 2D é suportada apenas para convidados Windows, esta opção será desactivada.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">activou um HID (Human Interface Device) USB. Isto não funcionará a não ser que a emulação USB esteja também activada. Isto será feito automaticamente quando aceitar as definições MV ao premir o butão OK.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">até no máximo um suportado</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">até %1 suportado</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">está actualmente a usar mais controladores de armazenamento do que o &apos;chipset&apos; %1 suporta. Por favor mude o tipo de &apos;chipset&apos; na página de definições do sistema ou reduza o número de controladores de armazenamento na página de definições de Armazenamento: %2.</translation>
</message>
</context>
<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
- <translation type="unfinished">Fechar Máquina Virtual</translation>
+ <translation>Fechar Máquina Virtual</translation>
</message>
<message>
<source>You want to:</source>
- <translation type="unfinished">Deseja:</translation>
+ <translation>Deseja:</translation>
</message>
<message>
<source>&lt;p&gt;Saves the current execution state of the virtual machine to the physical hard disk of the host PC.&lt;/p&gt;&lt;p&gt;Next time this machine is started, it will be restored from the saved state and continue execution from the same place you saved it at, which will let you continue your work immediately.&lt;/p&gt;&lt;p&gt;Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Salvar o estado de execução actual da máquina virtual para o disco rígido físico do PC hospedeiro. &lt;/p&gt;&lt;p&gt;Na próxima vez que a máquina virtual for executada, será restaurada a partir do estado salvado e continuará a execução do mesmo sítio em que foi salva, o que permitirá continuar o seu trabalho imediatamente.&lt;/p&gt;&lt;p&gt;Note que salvar o estado da máquina poderá demorar algum tempo, dependente do tipo do sistema operativa convidado e da quantidade de memória disponibilizada à máquina virtual.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Grava o estado de execução actual da máquina virtual para o disco rígido físico do PC hospedeiro. &lt;/p&gt;&lt;p&gt;Na próxima vez que a máquina virtual for executada, será restaurada a partir do estado gravado e continuará a execução do mesmo sítio em que foi gravada, o que permitirá continuar o seu trabalho imediatamente.&lt;/p&gt;&lt;p&gt;Note que gravar o estado da máquina poderá demorar algum tempo, dependente do tipo do sistema operativo convidado e da quantidade de memória disponibilizada à máquina virtual.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Save the machine state</source>
- <translation type="unfinished">Gravar o e&amp;stado da máquina</translation>
+ <translation>Gravar o e&amp;stado da máquina</translation>
</message>
<message>
<source>&lt;p&gt;Sends the ACPI Power Button press event to the virtual machine.&lt;/p&gt;&lt;p&gt;Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.&lt;/p&gt;&lt;p&gt;If the machine doesn&apos;t respond to this action then the guest operating system may be misconfigured or doesn&apos;t understand ACPI Power Button events at all. In this case you should select the &lt;b&gt;Power off the machine&lt;/b&gt; action to stop virtual machine execution.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Envia o evento ACPI de pressionar o butão de alimentação para a máquina virtual.&lt;/p&gt;&lt;p&gt;Normalmente, o sistema operativo convidado em funcionamento na máquina virtual detectará este evento e realizará o processo de desligar a máquina virtual de uma forma limpa. Esta é a forma recomendada de desligar a máquina virtual porque todas as aplicação a funcionar no seu interior terão a oportunidade de salvar os seus dados.&lt;/p&gt;&lt;p&gt;Se a máquina não responder a esta acção então o sistema operativo poderá estar malconfigurado ou não reconhecer os eventos ACPI. Neste caso deve seleccionar &lt;b&gt;Desligar a máquina&lt;/b&gt; para parar o funcionamento da máquina virutal.</translation>
+ <translation>&lt;p&gt;Envia o evento ACPI de pressionar o botão de alimentação para a máquina virtual.&lt;/p&gt;&lt;p&gt;Normalmente, o sistema operativo convidado a correr na máquina virtual detectará este evento e realizará o processo de desligar a máquina virtual de uma forma limpa. Esta é a forma recomendada de desligar a máquina virtual porque todas as aplicação a funcionar no seu interior terão a oportunidade de salvar os seus dados.&lt;/p&gt;&lt;p&gt;Se a máquina não responder a esta acção então o sistema operativo poderá estar malconfigurado ou não reconhecer os eventos ACPI. Neste caso deve seleccionar &lt;b&gt;Desligar a máquina&lt;/b&gt; para parar o funcionamento da máquina virutal.&lt;/p&gt;</translation>
</message>
<message>
<source>S&amp;end the shutdown signal</source>
- <translation type="unfinished">&amp;Enviar pedido para desligar</translation>
+ <translation>&amp;Enviar pedido para desligar</translation>
</message>
<message>
<source>&lt;p&gt;Turns off the virtual machine.&lt;/p&gt;&lt;p&gt;Note that this action will stop machine execution immediately so that the guest operating system running inside it will not be able to perform a clean shutdown procedure which may result in &lt;i&gt;data loss&lt;/i&gt; inside the virtual machine. Selecting this action is recommended only if the virtual machine does not respond to the &lt;b&gt;Send the shutdown signal&lt;/b&gt; action.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Desliga a máquina virtual.&lt;/p&gt;&lt;p&gt;Note-se que esta acção parará a execução da máquina virtual imediatamente, de tal forma que, o sistema operativo convidado não terá oportunidade de se desligar de uma forma limpa, o que poderá resultar em &lt;i&gt;perdas de dados&lt;/i&gt; dentro da máquina virtual. Seleccionar esta acção é apenas recomendável se a máquina virtual não responder à acção de enviar &lt;b&gt;Desligar máquina virtual&lt;/b&gt;.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Desliga a máquina virtual.&lt;/p&gt;&lt;p&gt;Note-se que esta acção parará a execução da máquina virtual imediatamente, de tal forma que, o sistema operativo convidado não terá oportunidade de se desligar de uma forma limpa, o que poderá resultar em &lt;i&gt;perdas de dados&lt;/i&gt; dentro da máquina virtual. Seleccionar esta acção é apenas recomendável se a máquina virtual não responder à acção de enviar &lt;b&gt;Desligar máquina virtual&lt;/b&gt;.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Power off the machine</source>
- <translation type="unfinished">&amp;Desligar a máquina</translation>
+ <translation>&amp;Desliga a máquina</translation>
</message>
<message>
<source>Restore the machine state stored in the current snapshot</source>
- <translation type="unfinished"></translation>
+ <translation>Restaura o estado da máquina guardado na captura actual</translation>
</message>
<message>
<source>&lt;p&gt;When checked, the machine will be returned to the state stored in the current snapshot after it is turned off. This is useful if you are sure that you want to discard the results of your last sessions and start again at that snapshot.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Quando seleccionado, a estado da máquina virtual será restaurado a partir do estado armazenado na captura actual logo após ter sido desligado. Isto é útil se tem a certeza que deseja descartar os resultados da sua última sessão e voltar à captura actual.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Quando seleccionado, a estado da máquina virtual será restaurado a partir do estado armazenado na captura actual logo após ter sido desligado. Isto é útil se tem a certeza que deseja descartar os resultados da sua última sessão e voltar à captura actual.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Restore current snapshot &apos;%1&apos;</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Restaurar captura actual &apos;%1&apos;</translation>
</message>
</context>
<context>
<name>UIVMDesktop</name>
<message>
<source>&amp;Details</source>
- <translation type="unfinished">&amp;Detalhes</translation>
+ <translation>&amp;Detalhes</translation>
</message>
<message>
<source>&amp;Snapshots</source>
- <translation type="unfinished">&amp;Capturas</translation>
+ <translation>&amp;Capturas</translation>
</message>
</context>
<context>
@@ -4625,106 +5192,31 @@ diálogo de Configurações da MV.&lt;/p&gt;</translation>
<name>UIVMPreviewWindow</name>
<message>
<source>Update Disabled</source>
- <translation type="unfinished"></translation>
+ <translation>Actualização Desactivada</translation>
</message>
<message>
<source>Every 0.5 s</source>
- <translation type="unfinished"></translation>
+ <translation>A todos os 0.5 s</translation>
</message>
<message>
<source>Every 1 s</source>
- <translation type="unfinished"></translation>
+ <translation>A todos os 1 s</translation>
</message>
<message>
<source>Every 2 s</source>
- <translation type="unfinished"></translation>
+ <translation>A todos os 2 s</translation>
</message>
<message>
<source>Every 5 s</source>
- <translation type="unfinished"></translation>
+ <translation>A todos os 5 s</translation>
</message>
<message>
<source>Every 10 s</source>
- <translation type="unfinished"></translation>
+ <translation>A todos os 10 s</translation>
</message>
<message>
<source>No Preview</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Geral</translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished">Armazenamento</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished">Ãudio</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Rede</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished">Portos</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished">Portas Série</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished">Portas Paralelas</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished">Pastas Partilhadas</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished">%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
+ <translation>Nenhuma Previsão</translation>
</message>
</context>
<context>
@@ -4847,91 +5339,91 @@ Versão %1</translation>
<name>VBoxApplianceEditorWgt</name>
<message>
<source>Virtual System %1</source>
- <translation type="unfinished"></translation>
+ <translation>Sistema Virtual %1</translation>
</message>
<message>
<source>Name</source>
- <translation type="unfinished">Nome</translation>
+ <translation>Nome</translation>
</message>
<message>
<source>Product</source>
- <translation type="unfinished"></translation>
+ <translation>Produto</translation>
</message>
<message>
<source>Product-URL</source>
- <translation type="unfinished"></translation>
+ <translation>URL do Produto</translation>
</message>
<message>
<source>Vendor</source>
- <translation type="unfinished"></translation>
+ <translation>Fabricante</translation>
</message>
<message>
<source>Vendor-URL</source>
- <translation type="unfinished"></translation>
+ <translation>URL do Fabricante</translation>
</message>
<message>
<source>Version</source>
- <translation type="unfinished"></translation>
+ <translation>Versão</translation>
</message>
<message>
<source>Description</source>
- <translation type="unfinished"></translation>
+ <translation>Descrição</translation>
</message>
<message>
<source>License</source>
- <translation type="unfinished"></translation>
+ <translation>Licença</translation>
</message>
<message>
<source>Guest OS Type</source>
- <translation type="unfinished">Tipo de Sistema Operativo Convidado</translation>
+ <translation>Tipo de SO Convidado</translation>
</message>
<message>
<source>CPU</source>
- <translation type="unfinished"></translation>
+ <translation>CPU</translation>
</message>
<message>
<source>RAM</source>
- <translation type="unfinished"></translation>
+ <translation>RAM</translation>
</message>
<message>
<source>Hard Disk Controller (IDE)</source>
- <translation type="unfinished"></translation>
+ <translation>Controlador do Disco Rígido (IDE)</translation>
</message>
<message>
<source>Hard Disk Controller (SATA)</source>
- <translation type="unfinished"></translation>
+ <translation>Controlador do Disco Rígido (SATA)</translation>
</message>
<message>
<source>Hard Disk Controller (SCSI)</source>
- <translation type="unfinished"></translation>
+ <translation>Controlador do Disco Rígido (SCSI)</translation>
</message>
<message>
<source>DVD</source>
- <translation type="unfinished"></translation>
+ <translation>DVD</translation>
</message>
<message>
<source>Floppy</source>
- <translation type="unfinished">Disquete</translation>
+ <translation>Disquete</translation>
</message>
<message>
<source>Network Adapter</source>
- <translation type="unfinished"></translation>
+ <translation>Adaptador de Rede</translation>
</message>
<message>
<source>USB Controller</source>
- <translation type="unfinished">Controladora USB</translation>
+ <translation>Controladora USB</translation>
</message>
<message>
<source>Sound Card</source>
- <translation type="unfinished"></translation>
+ <translation>Placa de Som</translation>
</message>
<message>
<source>Virtual Disk Image</source>
- <translation type="unfinished">Imagem de Disco Virtual</translation>
+ <translation>Imagem de Disco Virtual</translation>
</message>
<message>
<source>Unknown Hardware Item</source>
- <translation type="unfinished"></translation>
+ <translation>Item de Material Desconhecido</translation>
</message>
<message>
<source>MB</source>
@@ -4939,15 +5431,15 @@ Versão %1</translation>
</message>
<message>
<source>&lt;b&gt;Original Value:&lt;/b&gt; %1</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;b&gt;Valor Original:&lt;/b&gt; %1</translation>
</message>
<message>
<source>Configuration</source>
- <translation type="unfinished"></translation>
+ <translation>Configuração</translation>
</message>
<message>
<source>Warnings:</source>
- <translation type="unfinished"></translation>
+ <translation>Avisos:</translation>
</message>
<message>
<source>MB</source>
@@ -4961,6 +5453,14 @@ Versão %1</translation>
</message>
<message>
<source>Hard Disk Controller (SAS)</source>
+ <translation>Controlador do Disco Rígido (SAS)</translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -4976,7 +5476,7 @@ Versão %1</translation>
</message>
<message>
<source>&amp;Save the machine state</source>
- <translation type="obsolete">Gravar o e&amp;stado da máquina</translation>
+ <translation type="obsolete">Grava o e&amp;stado da máquina</translation>
</message>
<message>
<source>&amp;Power off the machine</source>
@@ -5896,46 +6396,46 @@ Versão %1</translation>
<name>VBoxEmptyFileSelector</name>
<message>
<source>&amp;Choose...</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Escolher...</translation>
</message>
</context>
<context>
<name>VBoxFilePathSelectorWidget</name>
<message>
<source>&lt;reset to default&gt;</source>
- <translation type="unfinished">&lt;reinicializar para normal&gt;</translation>
+ <translation>&lt;restaurar para predefinido&gt;</translation>
</message>
<message>
<source>The actual default path value will be displayed after accepting the changes and opening this dialog again.</source>
- <translation type="unfinished">O caminho por defeito actual será apresentado depois de aceitar as alterações e abrir este diálogo novamente.</translation>
+ <translation>O caminho predefinido actual será apresentado após aceitar as alterações e abrir este diálogo novamente.</translation>
</message>
<message>
<source>&lt;not selected&gt;</source>
- <translation type="unfinished">&lt;não seleccionado&gt;</translation>
+ <translation>&lt;não seleccionado&gt;</translation>
</message>
<message>
<source>Please use the &lt;b&gt;Other...&lt;/b&gt; item from the drop-down list to select a path.</source>
- <translation type="unfinished">Por favor use &lt;b&gt;Outro...&lt;/b&gt; item da lista para seleccionar o caminho desejado.</translation>
+ <translation>Por favor use &lt;b&gt;Outro...&lt;/b&gt; item da lista para seleccionar um caminho.</translation>
</message>
<message>
<source>Other...</source>
- <translation type="unfinished">Outro...</translation>
+ <translation>Outro...</translation>
</message>
<message>
<source>Reset</source>
- <translation type="unfinished">Reinicializar</translation>
+ <translation>Restaurar</translation>
</message>
<message>
<source>Opens a dialog to select a different folder.</source>
- <translation type="unfinished">Abre um diálogo para seleccionar uma pasta diferente.</translation>
+ <translation>Abre um diálogo para seleccionar uma pasta diferente.</translation>
</message>
<message>
<source>Resets the folder path to the default value.</source>
- <translation type="unfinished">Reinicializa o caminho para a pasta para o valor por defeito.</translation>
+ <translation>Restaura o caminho da pasta para o valor predefinido.</translation>
</message>
<message>
<source>Opens a dialog to select a different file.</source>
- <translation type="unfinished">Abre o diálogo para seleccionar um ficheiro diferente.</translation>
+ <translation>Abre um diálogo para seleccionar um ficheiro diferente.</translation>
</message>
<message>
<source>Resets the file path to the default value.</source>
@@ -6742,17 +7242,17 @@ Versão %1</translation>
<message>
<source>&lt;nobr&gt;Vendor ID: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;ID do Fabricante: %1&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Product ID: %2&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;ID do Produto: %2&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Revision: %3&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;Revisão: %3&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Product: %4&lt;/nobr&gt;</source>
@@ -6772,12 +7272,12 @@ Versão %1</translation>
<message>
<source>&lt;nobr&gt;Port: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;Porta: %1&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;State: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;Estado: %1&lt;/nobr&gt;</translation>
</message>
<message>
<source>host interface, %1</source>
@@ -6792,7 +7292,7 @@ Versão %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation type="unfinished">Adaptador %1</translation>
+ <translation type="obsolete">Adaptador %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -6827,7 +7327,7 @@ Versão %1</translation>
<message>
<source>Inaccessible</source>
<comment>medium</comment>
- <translation type="unfinished">Inacessível</translation>
+ <translation>Inacessível</translation>
</message>
<message>
<source>3D Acceleration</source>
@@ -6852,107 +7352,107 @@ Versão %1</translation>
<message>
<source>Differencing</source>
<comment>DiskType</comment>
- <translation type="unfinished">Diferença</translation>
+ <translation>Diferenciação</translation>
</message>
<message>
<source>Nested Paging</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Página Aninhada</translation>
</message>
<message>
<source>Enabled</source>
<comment>details report (Nested Paging)</comment>
- <translation type="unfinished">Activado</translation>
+ <translation>Activado</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (Nested Paging)</comment>
- <translation type="unfinished">Desactivado</translation>
+ <translation>Desactivado</translation>
</message>
<message>
<source>Internal network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation type="unfinished"></translation>
+ <translation>Rede Interna, &apos;%1&apos;</translation>
</message>
<message>
<source>SCSI</source>
<comment>StorageBus</comment>
- <translation type="unfinished"></translation>
+ <translation>SCSI</translation>
</message>
<message>
<source>PIIX3</source>
<comment>StorageControllerType</comment>
- <translation type="unfinished">PIIX3</translation>
+ <translation>PIIX3</translation>
</message>
<message>
<source>PIIX4</source>
<comment>StorageControllerType</comment>
- <translation type="unfinished">PIIX4</translation>
+ <translation>PIIX4</translation>
</message>
<message>
<source>ICH6</source>
<comment>StorageControllerType</comment>
- <translation type="unfinished"></translation>
+ <translation>ICH6</translation>
</message>
<message>
<source>AHCI</source>
<comment>StorageControllerType</comment>
- <translation type="unfinished"></translation>
+ <translation>AHCI</translation>
</message>
<message>
<source>Lsilogic</source>
<comment>StorageControllerType</comment>
- <translation type="unfinished"></translation>
+ <translation>Lsilogic</translation>
</message>
<message>
<source>BusLogic</source>
<comment>StorageControllerType</comment>
- <translation type="unfinished"></translation>
+ <translation>BusLogic</translation>
</message>
<message>
<source>Bridged adapter, %1</source>
<comment>details report (network)</comment>
- <translation type="unfinished"></translation>
+ <translation>Adaptador &apos;bridged&apos;, %1</translation>
</message>
<message>
<source>Host-only adapter, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation type="unfinished"></translation>
+ <translation>Adaptador apenas do hospedeiro, &apos;%1&apos;</translation>
</message>
<message>
<source>Intel PRO/1000 MT Server (82545EM)</source>
<comment>NetworkAdapterType</comment>
- <translation type="unfinished"></translation>
+ <translation>Servidor PRO/1000 MT Intel (82545EM)</translation>
</message>
<message>
<source>Bridged Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
+ <translation>Adaptador &apos;Bridged&apos;</translation>
</message>
<message>
<source>Host-only Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
+ <translation>Adaptador Apenas do Hospedeiro</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 MB&lt;/nobr&gt;</source>
<comment>details report</comment>
- <translation type="unfinished">&lt;nobr&gt;%4 MB&lt;/nobr&gt; {1 ?}</translation>
+ <translation>&lt;nobr&gt;%1 MB&lt;/nobr&gt;</translation>
</message>
<message>
<source>Processor(s)</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Processador(es)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1&lt;/nobr&gt;</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;nobr&gt;%1&lt;/nobr&gt;</translation>
</message>
<message>
<source>System</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Sistema</translation>
</message>
<message>
<source>Disabled</source>
@@ -6962,457 +7462,512 @@ Versão %1</translation>
<message>
<source>Display</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Ecrã</translation>
</message>
<message>
<source>Raw File</source>
<comment>PortMode</comment>
- <translation type="unfinished"></translation>
+ <translation>Ficheiro puro</translation>
</message>
<message>
<source>Enabled</source>
<comment>details report (2D Video Acceleration)</comment>
- <translation type="unfinished">Activado</translation>
+ <translation>Activado</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (2D Video Acceleration)</comment>
- <translation type="unfinished">Desactivado</translation>
+ <translation>Desactivado</translation>
</message>
<message>
<source>2D Video Acceleration</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Aceleração de Vídeo 2D</translation>
</message>
<message>
<source>Not Attached</source>
<comment>details report (Storage)</comment>
- <translation type="unfinished">Não Conectado</translation>
+ <translation>Não Ligado</translation>
</message>
<message>
<source>Storage</source>
<comment>details report</comment>
- <translation type="unfinished">Armazenamento</translation>
+ <translation>Armazenamento</translation>
</message>
<message>
<source>Teleported</source>
<comment>MachineState</comment>
- <translation type="unfinished"></translation>
+ <translation>Teleportado</translation>
</message>
<message>
<source>Guru Meditation</source>
<comment>MachineState</comment>
- <translation type="unfinished"></translation>
+ <translation>Meditação Guru</translation>
</message>
<message>
<source>Teleporting</source>
<comment>MachineState</comment>
- <translation type="unfinished"></translation>
+ <translation>Teleportação</translation>
</message>
<message>
<source>Taking Live Snapshot</source>
<comment>MachineState</comment>
- <translation type="unfinished"></translation>
+ <translation>Tirar Captura ao Vivo</translation>
</message>
<message>
<source>Teleporting Paused VM</source>
<comment>MachineState</comment>
- <translation type="unfinished"></translation>
+ <translation>A teleportar VM pausada</translation>
</message>
<message>
<source>Restoring Snapshot</source>
<comment>MachineState</comment>
- <translation type="unfinished"></translation>
+ <translation>A restaurar captura</translation>
</message>
<message>
<source>Deleting Snapshot</source>
<comment>MachineState</comment>
- <translation type="unfinished"></translation>
+ <translation>A apagar captura</translation>
</message>
<message>
<source>Floppy</source>
<comment>StorageBus</comment>
- <translation type="unfinished">Disquete</translation>
+ <translation>Disquete</translation>
</message>
<message>
<source>Device %1</source>
<comment>StorageBusDevice</comment>
- <translation type="unfinished"></translation>
+ <translation>Dsipositivo %1</translation>
</message>
<message>
<source>IDE Primary Master</source>
<comment>New Storage UI : Slot Name</comment>
- <translation type="unfinished"></translation>
+ <translation>IDE &apos;Master&apos; Principal</translation>
</message>
<message>
<source>IDE Primary Slave</source>
<comment>New Storage UI : Slot Name</comment>
- <translation type="unfinished"></translation>
+ <translation>IDE &apos;Slave&apos; Principal</translation>
</message>
<message>
<source>IDE Secondary Master</source>
<comment>New Storage UI : Slot Name</comment>
- <translation type="unfinished"></translation>
+ <translation>IDE &apos;Master&apos; Secundário</translation>
</message>
<message>
<source>IDE Secondary Slave</source>
<comment>New Storage UI : Slot Name</comment>
- <translation type="unfinished"></translation>
+ <translation>IDE &apos;Slave&apos; Secundário</translation>
</message>
<message>
<source>SATA Port %1</source>
<comment>New Storage UI : Slot Name</comment>
- <translation type="unfinished"></translation>
+ <translation>Porta SATA %1</translation>
</message>
<message>
<source>SCSI Port %1</source>
<comment>New Storage UI : Slot Name</comment>
- <translation type="unfinished"></translation>
+ <translation>Porta SCSI %1</translation>
</message>
<message>
<source>Floppy Device %1</source>
<comment>New Storage UI : Slot Name</comment>
- <translation type="unfinished"></translation>
+ <translation>Dispositivo de Disquete %1</translation>
</message>
<message>
<source>Paravirtualized Network (virtio-net)</source>
<comment>NetworkAdapterType</comment>
- <translation type="unfinished"></translation>
+ <translation>Rede Paravirtualizada (virtio-net)</translation>
</message>
<message>
<source>I82078</source>
<comment>StorageControllerType</comment>
- <translation type="unfinished"></translation>
+ <translation>I82078</translation>
</message>
<message>
<source>Empty</source>
<comment>medium</comment>
- <translation type="unfinished"></translation>
+ <translation>Vazio</translation>
</message>
<message>
<source>Host Drive &apos;%1&apos;</source>
<comment>medium</comment>
- <translation type="unfinished"></translation>
+ <translation>Unidade do Hospedeiro &apos;%1&apos;</translation>
</message>
<message>
<source>Host Drive %1 (%2)</source>
<comment>medium</comment>
- <translation type="unfinished"></translation>
+ <translation>Unidade do Hospedeiro %1 (%2)</translation>
</message>
<message>
<source>&lt;p style=white-space:pre&gt;Type (Format): %1 (%2)&lt;/p&gt;</source>
<comment>medium</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;p style=white-space:pre&gt;Tipo (Formato): %1 (%2)&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Attached to: %1&lt;/p&gt;</source>
<comment>image</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Ligado a: %1&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;i&gt;Not Attached&lt;/i&gt;</source>
<comment>image</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;i&gt;Não Ligado&lt;/i&gt;</translation>
</message>
<message>
<source>&lt;i&gt;Checking accessibility...&lt;/i&gt;</source>
<comment>medium</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;i&gt;A verificar acessibilidade...&lt;/i&gt;</translation>
</message>
<message>
<source>Failed to check media accessibility.</source>
<comment>medium</comment>
- <translation type="unfinished"></translation>
+ <translation>Falha ao verificar a acessibilidade da média.</translation>
</message>
<message>
<source>&lt;b&gt;No medium selected&lt;/b&gt;</source>
<comment>medium</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;b&gt;Nenhuma média seleccionada&lt;/b&gt;</translation>
</message>
<message>
<source>You can also change this while the machine is running.</source>
- <translation type="unfinished"></translation>
+ <translation>Pode também mudar isto enquanto a máquina está a correr.</translation>
</message>
<message>
<source>&lt;b&gt;No media available&lt;/b&gt;</source>
<comment>medium</comment>
- <translation type="unfinished"></translation>
+ <translation>&lt;b&gt;Nenhuma média disponível&lt;/b&gt;</translation>
</message>
<message>
<source>You can create media images using the virtual media manager.</source>
- <translation type="unfinished"></translation>
+ <translation>Pode criar imagens de médias usando o gestor de médias virtual.</translation>
</message>
<message>
<source>Attaching this hard disk will be performed indirectly using a newly created differencing hard disk.</source>
<comment>medium</comment>
- <translation type="unfinished"></translation>
+ <translation>A ligação deste disco será executada indirectamente usando um disco rígido de diferenciação recém criado.</translation>
</message>
<message>
<source>Some of the media in this hard disk chain are inaccessible. Please use the Virtual Media Manager in &lt;b&gt;Show Differencing Hard Disks&lt;/b&gt; mode to inspect these media.</source>
<comment>medium</comment>
- <translation type="unfinished"></translation>
+ <translation>Algumas das médias neste disco rígido estão inacessiveis. Por favor use o Gestor de Médias Virtual no modo &lt;b&gt;Mostrar Discos Rígidos de Diferenciação&lt;/b&gt; para inspecionar esta média.</translation>
</message>
<message>
<source>This base hard disk is indirectly attached using the following differencing hard disk:</source>
<comment>medium</comment>
- <translation type="unfinished"></translation>
+ <translation>Este disco rígido base está ligado indirectamente usando o seguinte disco rígido de diferenciação:</translation>
</message>
<message numerus="yes">
<source>%n year(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%n ano(s)</numerusform>
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%n month(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%n mês(es)</numerusform>
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%n day(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%n dia(s)</numerusform>
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%n hour(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%n hora(s)</numerusform>
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%n minute(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%n minuto(s)</numerusform>
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%n second(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%n segundo(s)</numerusform>
<numerusform></numerusform>
</translation>
</message>
<message>
<source>(CD/DVD)</source>
- <translation type="unfinished"></translation>
+ <translation>(CD/DVD)</translation>
</message>
<message>
<source>Screens</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Ecrãs</translation>
</message>
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Rede VDE, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
<comment>StorageBus</comment>
- <translation type="unfinished"></translation>
+ <translation>SAS</translation>
</message>
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Adaptador VDE</translation>
</message>
<message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
- <translation type="unfinished"></translation>
+ <translation>SAS LsiLogic</translation>
</message>
<message>
<source>B</source>
<comment>size suffix Bytes</comment>
- <translation type="unfinished"></translation>
+ <translation>B</translation>
</message>
<message>
<source>KB</source>
<comment>size suffix KBytes=1024 Bytes</comment>
- <translation type="unfinished"></translation>
+ <translation>KB</translation>
</message>
<message>
<source>MB</source>
<comment>size suffix MBytes=1024 KBytes</comment>
- <translation type="unfinished">MB</translation>
+ <translation>MB</translation>
</message>
<message>
<source>GB</source>
<comment>size suffix GBytes=1024 MBytes</comment>
- <translation type="unfinished"></translation>
+ <translation>GB</translation>
</message>
<message>
<source>TB</source>
<comment>size suffix TBytes=1024 GBytes</comment>
- <translation type="unfinished"></translation>
+ <translation>TB</translation>
</message>
<message>
<source>PB</source>
<comment>size suffix PBytes=1024 TBytes</comment>
- <translation type="unfinished"></translation>
+ <translation>PB</translation>
</message>
<message>
<source>Enabled</source>
<comment>nested paging</comment>
- <translation type="unfinished">Activado</translation>
+ <translation>Activado</translation>
</message>
<message>
<source>Disabled</source>
<comment>nested paging</comment>
- <translation type="unfinished">Desactivado</translation>
+ <translation>Desactivado</translation>
</message>
<message>
<source>Nested Paging</source>
- <translation type="unfinished"></translation>
+ <translation>Página Aninhada</translation>
</message>
<message>
<source>Shareable</source>
<comment>DiskType</comment>
- <translation type="unfinished"></translation>
+ <translation>Partilhável</translation>
</message>
<message>
<source>Unknown device</source>
<comment>USB device details</comment>
- <translation type="unfinished"></translation>
+ <translation>Dispositivo desconhecido</translation>
</message>
<message>
<source>SAS Port %1</source>
<comment>New Storage UI : Slot Name</comment>
- <translation type="unfinished"></translation>
+ <translation>Porta SAS %1</translation>
</message>
<message>
<source>Remote Desktop Server Port</source>
<comment>details report (VRDE Server)</comment>
- <translation type="unfinished"></translation>
+ <translation>Porta do Servidor de Ecrã Remoto</translation>
</message>
<message>
<source>Remote Desktop Server</source>
<comment>details report (VRDE Server)</comment>
- <translation type="unfinished"></translation>
+ <translation>Servidor de Ecrã Remoto</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (VRDE Server)</comment>
- <translation type="unfinished">Desactivado</translation>
+ <translation>Desactivado</translation>
</message>
<message>
<source>Choose a virtual hard disk file</source>
- <translation type="unfinished"></translation>
+ <translation>Escolha um ficheiro do disco rígido virtual</translation>
</message>
<message>
<source>hard disk</source>
- <translation type="unfinished">disco rígido</translation>
+ <translation>disco rígido</translation>
</message>
<message>
<source>Choose a virtual CD/DVD disk file</source>
- <translation type="unfinished"></translation>
+ <translation>Escolha um ficheiro CD/DVD virtual</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
- <translation type="unfinished"></translation>
+ <translation>CD/DVD-ROM</translation>
</message>
<message>
<source>Choose a virtual floppy disk file</source>
- <translation type="unfinished"></translation>
+ <translation>Escolha o ficheiro da disquete virtual</translation>
</message>
<message>
<source>floppy disk</source>
- <translation type="unfinished"></translation>
+ <translation>disquete</translation>
</message>
<message>
<source>All %1 images (%2)</source>
- <translation type="unfinished"></translation>
+ <translation>Todas as %1 images (%2)</translation>
</message>
<message>
<source>All files (*)</source>
- <translation type="unfinished">Todos os ficheiros (*)</translation>
+ <translation>Todos os ficheiros (*)</translation>
</message>
<message>
<source>Fault Tolerant Syncing</source>
<comment>MachineState</comment>
- <translation type="unfinished"></translation>
+ <translation>Falha de Sincronização Tolerante</translation>
</message>
<message>
<source>Unlocked</source>
<comment>SessionState</comment>
- <translation type="unfinished"></translation>
+ <translation>Destrancado</translation>
</message>
<message>
<source>Locked</source>
<comment>SessionState</comment>
- <translation type="unfinished"></translation>
+ <translation>Trancado</translation>
</message>
<message>
<source>Unlocking</source>
<comment>SessionState</comment>
- <translation type="unfinished"></translation>
+ <translation>A destrancar</translation>
</message>
<message>
<source>Null</source>
<comment>AuthType</comment>
- <translation type="unfinished">Nula</translation>
+ <translation>Nulo</translation>
</message>
<message>
<source>External</source>
<comment>AuthType</comment>
- <translation type="unfinished">Externo</translation>
+ <translation>Externo</translation>
</message>
<message>
<source>Guest</source>
<comment>AuthType</comment>
- <translation type="unfinished">Convidado</translation>
+ <translation>Convidado</translation>
</message>
<message>
<source>Intel HD Audio</source>
<comment>AudioControllerType</comment>
- <translation type="unfinished"></translation>
+ <translation>Ãudo HD Intel</translation>
</message>
<message>
<source>UDP</source>
<comment>NATProtocolType</comment>
- <translation type="unfinished"></translation>
+ <translation>UDP</translation>
</message>
<message>
<source>TCP</source>
<comment>NATProtocolType</comment>
- <translation type="unfinished"></translation>
+ <translation>TCP</translation>
</message>
<message>
<source>PIIX3</source>
<comment>ChipsetType</comment>
- <translation type="unfinished">PIIX3</translation>
+ <translation>PIIX3</translation>
</message>
<message>
<source>ICH9</source>
<comment>ChipsetType</comment>
- <translation type="unfinished"></translation>
+ <translation>ICH9</translation>
</message>
<message>
<source>and</source>
- <translation type="unfinished"></translation>
+ <translation>e</translation>
</message>
<message>
<source>MB</source>
<comment>size suffix MBytes=1024KBytes</comment>
- <translation type="unfinished">MB</translation>
+ <translation>MB</translation>
</message>
<message>
<source>Readonly</source>
<comment>DiskType</comment>
- <translation type="unfinished"></translation>
+ <translation>Leitura-apenas</translation>
</message>
<message>
<source>Multi-attach</source>
<comment>DiskType</comment>
+ <translation>Multi-ligações</translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Adaptador %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7430,7 +7985,7 @@ Versão %1</translation>
</message>
<message>
<source>&apos;%1&apos; is an invalid host-combination code-sequence.</source>
- <translation type="unfinished"></translation>
+ <translation>&apos;%1&apos; é uma sequência inválida de código de combinação com o hospedeiro.</translation>
</message>
</context>
<context>
@@ -7800,7 +8355,7 @@ corresponder a qualquer dispositivo USB ligado.&lt;/qt&gt;
</source>
<translation type="obsolete">&lt;qt&gt;Adiciona um novo filtro USB com todos os campos
definidos para os valores do dispositivo USB seleccionado
-ligado à máquina.&lt;/qt&gt;
+ligado ao PC hospedeiro.&lt;/qt&gt;
</translation>
</message>
<message>
@@ -7982,11 +8537,11 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<name>VBoxImportApplianceWgt</name>
<message>
<source>Importing Appliance ...</source>
- <translation type="unfinished"></translation>
+ <translation>A importar aplicação...</translation>
</message>
<message>
<source>Reading Appliance ...</source>
- <translation type="unfinished"></translation>
+ <translation>A ler aplicação...</translation>
</message>
</context>
<context>
@@ -8008,7 +8563,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<name>VBoxLineTextEdit</name>
<message>
<source>&amp;Edit</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Editar</translation>
</message>
</context>
<context>
@@ -8105,31 +8660,31 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>Add an existing medium</source>
- <translation>Adicionar um dispositvo existente</translation>
+ <translation>Adiciona uma média existente</translation>
</message>
<message>
<source>Remove the selected medium</source>
- <translation type="unfinished">Remover o dispositivo seleccionado</translation>
+ <translation>Remover a média seleccionada</translation>
</message>
<message>
<source>Release the selected medium by detaching it from the machines</source>
- <translation type="unfinished">Libertar o dispositivo seleccionado desassociando-o das máquinas virtuais</translation>
+ <translation>Liberta a média seleccionada ao desligar-se das máquinas virtuais</translation>
</message>
<message>
<source>Refresh the media list</source>
- <translation type="unfinished">Actualiza a lista de dispositivos</translation>
+ <translation>Refresca a lista de médias</translation>
</message>
<message>
<source>Location</source>
- <translation>Localização</translation>
+ <translation type="obsolete">Localização</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Tipo (Formato)</translation>
+ <translation type="obsolete">Tipo (Formato)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Ligado a</translation>
+ <translation type="obsolete">Ligado a</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -8169,7 +8724,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>&lt;i&gt;Not&amp;nbsp;Attached&lt;/i&gt;</source>
- <translation type="unfinished">&lt;i&gt;Não&amp;nbsp;Conectado&lt;/i&gt;</translation>
+ <translation>&lt;i&gt;Não&amp;nbsp;Ligado&lt;/i&gt;</translation>
</message>
<message>
<source>--</source>
@@ -8211,32 +8766,72 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation type="unfinished">Ligado a</translation>
+ <translation type="obsolete">Ligado a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation type="unfinished">Ligado a</translation>
+ <translation type="obsolete">Ligado a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation type="unfinished">Ligado a</translation>
+ <translation type="obsolete">Ligado a</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
- <translation type="unfinished"></translation>
+ <translation>CD/DVD-ROM</translation>
</message>
<message>
<source>hard disk</source>
- <translation type="unfinished">disco rígido</translation>
+ <translation>disco rígido</translation>
</message>
<message>
<source>floppy disk</source>
- <translation type="unfinished"></translation>
+ <translation>disquete</translation>
</message>
<message>
<source>All %1 images (%2)</source>
+ <translation>Tosas as %1 imagens (%2)</translation>
+ </message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Tipo:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Localização:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -8244,19 +8839,19 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<name>VBoxMiniToolBar</name>
<message>
<source>Always show the toolbar</source>
- <translation type="unfinished"></translation>
+ <translation>Mostrar sempre na barra de ferramentas</translation>
</message>
<message>
<source>Exit Full Screen or Seamless Mode</source>
- <translation type="unfinished"></translation>
+ <translation>Sair do Ecrã Completo ou do Modo Integrado</translation>
</message>
<message>
<source>Close VM</source>
- <translation type="unfinished"></translation>
+ <translation>Fechar VM</translation>
</message>
<message>
<source>Minimize Window</source>
- <translation type="unfinished"></translation>
+ <translation>Minimizar Janela</translation>
</message>
</context>
<context>
@@ -8294,7 +8889,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Adaptadores de Rede</translation>
</message>
</context>
<context>
@@ -8317,7 +8912,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>&amp;Version:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Versão:</translation>
</message>
</context>
<context>
@@ -8619,7 +9214,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<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;A execução da máquina virtual pode correr para uma condiºão de erro como descrito em baixo. Pode ignorar esta mensagem, mas recomendamos que tome uma acção para garantir que o erro descrito não ocorra.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;A execução da máquina virtual pode correr para uma condição de erro como descrito em baixo. Sugerimos que tome uma acção apropriada para evitar o erro.&lt;/p&gt;</translation>
</message>
<message>
<source>Result&amp;nbsp;Code: </source>
@@ -8914,7 +9509,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>You are already running the most recent version of VirtualBox.</source>
- <translation type="unfinished">Já tem instalada a última versão do VirtualBox. Por favor tente novamente mais tarde.</translation>
+ <translation>Já está a correr a versão mais recente do VirtualBox.</translation>
</message>
<message>
<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>
@@ -8942,7 +9537,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>Show the online help contents</source>
- <translation type="unfinished">Apresentar o conteúdo da ajuda disponível na Internet</translation>
+ <translation>Mostrar o conteúdo da ajuda em-linha</translation>
</message>
<message>
<source>&amp;VirtualBox Web Site...</source>
@@ -8950,15 +9545,15 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>Open the browser and go to the VirtualBox product web site</source>
- <translation type="unfinished"></translation>
+ <translation>Abra o navegador e vá até ao sítio &apos;web&apos; do produto VirtualBox</translation>
</message>
<message>
<source>&amp;Reset All Warnings</source>
- <translation type="unfinished">&amp;Apagar Todos os Avisos</translation>
+ <translation>&amp;Restaurar Todos os Avisos</translation>
</message>
<message>
<source>Go back to showing all suppressed warnings and messages</source>
- <translation type="unfinished">Faz com que todas as mensagens suprimidas sejam apresentadas novamente</translation>
+ <translation>Faz com que todas as mensagens suprimidas sejam apresentadas novamente</translation>
</message>
<message>
<source>R&amp;egister VirtualBox...</source>
@@ -8999,7 +9594,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;Are you sure you want to remove the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt; from the list of known media?&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Tem a certeza de que deseja remover %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt; da lista de dispositivos conhecidos?&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Tem a certeza de que deseja remover %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt; da lista de médias conhecidas?&lt;/p&gt;</translation>
</message>
<message>
<source>Note that as this hard disk is inaccessible its storage unit cannot be deleted right now.</source>
@@ -9054,15 +9649,15 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>Failed to open the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>Falha ao abrir %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;.</translation>
</message>
<message>
<source>Failed to close the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>Falha ao fechar %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;.</translation>
</message>
<message>
<source>Failed to determine the accessibility state of the medium &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>Falha ao determinar o estado de acessibilidade da média &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;.</translation>
</message>
<message>
<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>
@@ -9119,10 +9714,6 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
<translation type="unfinished"></translation>
</message>
@@ -9132,11 +9723,11 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>Close VM</source>
- <translation type="unfinished"></translation>
+ <translation>Fechar VM</translation>
</message>
<message>
<source>Continue</source>
- <translation type="unfinished">Continuar</translation>
+ <translation>Continuar</translation>
</message>
<message>
<source>Discard</source>
@@ -9144,11 +9735,11 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>Cancel</source>
- <translation type="unfinished">Cancelar</translation>
+ <translation>Cancelar</translation>
</message>
<message>
<source>Failed to create the host-only network interface.</source>
- <translation type="unfinished"></translation>
+ <translation>Falha ao criar o interface de rede apenas do hospedeiro.</translation>
</message>
<message>
<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>
@@ -9219,12 +9810,8 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restore</source>
- <translation type="unfinished"></translation>
+ <translation>Restarar</translation>
</message>
<message>
<source>&lt;p&gt;Deleting the snapshot will cause the state information saved in it to be lost, and disk data spread over several image files that VirtualBox has created together with the snapshot will be merged into one file. This can be a lengthy process, and the information in the snapshot cannot be recovered.&lt;/p&gt;&lt;/p&gt;Are you sure you want to delete the selected snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
@@ -9232,7 +9819,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>Delete</source>
- <translation type="unfinished">Apagar</translation>
+ <translation>Apagar</translation>
</message>
<message>
<source>Failed to restore the snapshot &lt;b&gt;%1&lt;/b&gt; of the virtual machine &lt;b&gt;%2&lt;/b&gt;.</source>
@@ -9270,7 +9857,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>Force Unmount</source>
- <translation type="unfinished"></translation>
+ <translation>Forçar Desmontagem</translation>
</message>
<message>
<source>&lt;p&gt;Could not insert the VirtualBox Guest Additions installer CD image into the virtual machine &lt;b&gt;%1&lt;/b&gt;, as the machine has no CD/DVD-ROM drives. Please add a drive using the storage page of the virtual machine settings dialog.&lt;/p&gt;</source>
@@ -9279,7 +9866,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<message>
<source>E&amp;xit</source>
<comment>warnAboutSettingsAutoConversion message box</comment>
- <translation type="unfinished">&amp;Sair</translation>
+ <translation>&amp;Sair</translation>
</message>
<message>
<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>
@@ -9288,27 +9875,27 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<message>
<source>hard disk</source>
<comment>failed to mount ...</comment>
- <translation type="unfinished">disco rígido</translation>
+ <translation>disco rígido</translation>
</message>
<message>
<source>CD/DVD</source>
<comment>failed to mount ... host-drive</comment>
- <translation type="unfinished"></translation>
+ <translation>CD/DVD</translation>
</message>
<message>
<source>CD/DVD image</source>
<comment>failed to mount ...</comment>
- <translation type="unfinished">imagem de CD/DVD</translation>
+ <translation>imagem de CD/DVD</translation>
</message>
<message>
<source>floppy</source>
<comment>failed to mount ... host-drive</comment>
- <translation type="unfinished"></translation>
+ <translation>disquete</translation>
</message>
<message>
<source>floppy image</source>
<comment>failed to mount ...</comment>
- <translation type="unfinished">imagem de disquete</translation>
+ <translation>imagem de disquete</translation>
</message>
<message>
<source>hard disk</source>
@@ -9322,7 +9909,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<message>
<source>&amp;Remove</source>
<comment>medium</comment>
- <translation type="unfinished"></translation>
+ <translation>&amp;Remover</translation>
</message>
<message>
<source>&lt;p&gt;VT-x/AMD-V hardware acceleration is not available on your system. Your 64-bit guest will fail to detect a 64-bit CPU and will not be able to boot.</source>
@@ -9390,11 +9977,11 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>Delete all files</source>
- <translation type="unfinished"></translation>
+ <translation>Apagar todos os ficheiros</translation>
</message>
<message>
<source>Remove only</source>
- <translation type="unfinished"></translation>
+ <translation>Remover apenas</translation>
</message>
<message>
<source>You are about to remove the inaccessible virtual machine &lt;b&gt;%1&lt;/b&gt; from the machine list. Do you wish to proceed?</source>
@@ -9402,7 +9989,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>Remove</source>
- <translation type="unfinished">Remover</translation>
+ <translation>Remover</translation>
</message>
<message>
<source>&lt;p&gt;You are about to add a virtual hard disk to controller &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Would you like to create a new, empty file to hold the disk contents or select an existing one?&lt;/p&gt;</source>
@@ -9411,12 +9998,12 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<message>
<source>Create &amp;new disk</source>
<comment>add attachment routine</comment>
- <translation type="unfinished"></translation>
+ <translation>Criar &amp;novo disco</translation>
</message>
<message>
<source>&amp;Choose existing disk</source>
<comment>add attachment routine</comment>
- <translation type="unfinished"></translation>
+ <translation>Es&amp;colher disco existente</translation>
</message>
<message>
<source>&lt;p&gt;You are about to add a new CD/DVD drive to controller &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Would you like to choose a virtual CD/DVD disk to put in the drive or to leave it empty for now?&lt;/p&gt;</source>
@@ -9425,12 +10012,12 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<message>
<source>&amp;Choose disk</source>
<comment>add attachment routine</comment>
- <translation type="unfinished"></translation>
+ <translation>Es&amp;colher disco</translation>
</message>
<message>
<source>Leave &amp;empty</source>
<comment>add attachment routine</comment>
- <translation type="unfinished"></translation>
+ <translation>Deixar &amp;vazio</translation>
</message>
<message>
<source>&lt;p&gt;You are about to add a new floppy drive to controller &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Would you like to choose a virtual floppy disk to put in the drive or to leave it empty for now?&lt;/p&gt;</source>
@@ -9469,7 +10056,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>&amp;Remove</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Remover</translation>
</message>
<message>
<source>The current port forwarding rules are not valid. None of the host or guest port values may be set to zero.</source>
@@ -9514,7 +10101,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<message>
<source>Switch</source>
<comment>scale</comment>
- <translation type="unfinished">Mudar</translation>
+ <translation>Mudar</translation>
</message>
<message>
<source>Failed to open the Extension Pack &lt;b&gt;%1&lt;/b&gt;.</source>
@@ -9526,7 +10113,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>&amp;Install</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Instalar</translation>
</message>
<message>
<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>
@@ -9538,7 +10125,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>&amp;Upgrade</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Actualizar</translation>
</message>
<message>
<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>
@@ -9554,7 +10141,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>&amp;Reinstall</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Reinstalar</translation>
</message>
<message>
<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>
@@ -9565,15 +10152,75 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -9652,7 +10299,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Pastas Partilhadas</translation>
+ <translation type="obsolete">Pastas Partilhadas</translation>
</message>
<message>
<source>OK</source>
@@ -9675,15 +10322,15 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<name>VBoxScreenshotViewer</name>
<message>
<source>Screenshot of %1 (%2)</source>
- <translation type="unfinished"></translation>
+ <translation>Protector de Ecrã de %1 (%2)</translation>
</message>
<message>
<source>Click to view non-scaled screenshot.</source>
- <translation type="unfinished"></translation>
+ <translation>Clique para ver o protector de ecrã não escalado.</translation>
</message>
<message>
<source>Click to view scaled screenshot.</source>
- <translation type="unfinished"></translation>
+ <translation>Clique para ver o protector de ecrã escalado.</translation>
</message>
</context>
<context>
@@ -9783,11 +10430,11 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>D&amp;iscard</source>
- <translation>&amp;Descartar</translation>
+ <translation type="obsolete">&amp;Descartar</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Descartar</translation>
+ <translation type="unfinished">Descartar</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -9951,7 +10598,7 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
</message>
<message>
<source>&lt;h3&gt;Welcome to VirtualBox!&lt;/h3&gt;&lt;p&gt;The left part of this window is a list of all virtual machines on your computer. The list is empty now because you haven&apos;t created any virtual machines yet.&lt;img src=:/welcome.png align=right/&gt;&lt;/p&gt;&lt;p&gt;In order to create a new virtual machine, press the &lt;b&gt;New&lt;/b&gt; button in the main tool bar located at the top of the window.&lt;/p&gt;&lt;p&gt;You can press the &lt;b&gt;%1&lt;/b&gt; key to get instant help, or visit &lt;a href=http://www.virtualbox.org&gt;www.virtualbox.org&lt;/a&gt; for the latest information and news.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;h3&gt;Bem-vindo ao VirtualBox!&lt;/h3&gt;&lt;p&gt;A parte esquerda desta janela é uma lista de todas as máquinas virtuais no seu computador. A lista está vazia agora porque ainda não criou qualquer máquina virtual.&lt;img src=:/welcome.png align=right/&gt;&lt;/p&gt;&lt;p&gt;Para poder criar uma nova máquina virtual, prima o botão &lt;b&gt;Nova&lt;/b&gt; na barra de ferramentas no topo da janela.&lt;/p&gt;&lt;p&gt;Pode premir a tecla &lt;b&gt;%1&lt;/b&gt; para obter ajuda instântanea, ou visite &lt;a href=http://www.virtualbox.org&gt;www.virtualbox.org&lt;/a&gt; para ver as últimas informações e noticias.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Virtual Media Manager...</source>
@@ -9964,113 +10611,125 @@ para ligar ao encaixe actualmente destacado.&lt;/qt&gt;
<message>
<source>Log</source>
<comment>icon text</comment>
- <translation type="unfinished"></translation>
+ <translation>Registo</translation>
</message>
<message>
<source>&amp;Import Appliance...</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;importar Aplicação...</translation>
</message>
<message>
<source>Import an appliance into VirtualBox</source>
- <translation type="unfinished"></translation>
+ <translation>Importar uma aplicaão para o VirtualBox</translation>
</message>
<message>
<source>&amp;Export Appliance...</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Exportar Aplicação...</translation>
</message>
<message>
<source>Export one or more VirtualBox virtual machines as an appliance</source>
- <translation type="unfinished"></translation>
+ <translation>Exporta uma ou mais máquinas virtuais VirtualBox como aplicação</translation>
</message>
<message>
<source>Re&amp;fresh</source>
- <translation type="unfinished">Actuali&amp;zar</translation>
+ <translation>Re&amp;frescar</translation>
</message>
<message>
<source>&amp;File</source>
<comment>Mac OS X version</comment>
- <translation type="unfinished">&amp;Ficheiro</translation>
+ <translation>&amp;Ficheiro</translation>
</message>
<message>
<source>&amp;File</source>
<comment>Non Mac OS X version</comment>
- <translation type="unfinished">&amp;Ficheiro</translation>
+ <translation>&amp;Ficheiro</translation>
</message>
<message>
<source>Select a virtual machine file</source>
- <translation type="unfinished"></translation>
+ <translation>Seleccione um ficheiro de muina virtual</translation>
</message>
<message>
<source>Virtual machine files (%1)</source>
- <translation type="unfinished"></translation>
+ <translation>Ficheiros de máquina virtual (%1)</translation>
</message>
<message>
<source>Manager</source>
<comment>Note: main window title which is pretended by the product name.</comment>
- <translation type="unfinished"></translation>
+ <translation>Gestor</translation>
</message>
<message>
<source>&amp;Add...</source>
- <translation type="unfinished">&amp;Adicionar...</translation>
+ <translation>&amp;Adicionar...</translation>
</message>
<message>
<source>Add an existing virtual machine</source>
- <translation type="unfinished"></translation>
+ <translation>Adiciona uma máquina virtual existente</translation>
</message>
<message>
<source>&amp;Remove</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Remover</translation>
</message>
<message>
<source>Remove the selected virtual machine</source>
- <translation type="unfinished"></translation>
+ <translation>Remove uma máquina virtual seleccionada</translation>
</message>
<message>
<source>Show in Finder</source>
- <translation type="unfinished"></translation>
+ <translation>Mostrar no Pesquisador</translation>
</message>
<message>
<source>Show the VirtualBox Machine Definition file in Finder.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra o ficheiro de Definição da Máquina Virtual no Pesquisador.</translation>
</message>
<message>
<source>Create Alias on Desktop</source>
- <translation type="unfinished"></translation>
+ <translation>Criar Alias no Ecrã</translation>
</message>
<message>
<source>Creates an Alias file to the VirtualBox Machine Definition file on your Desktop.</source>
- <translation type="unfinished"></translation>
+ <translation>Cria um ficheiro de Alias para o ficheiro de Definição da Máquina VirtualBox no seu Ecrã.</translation>
</message>
<message>
<source>Show in Explorer</source>
- <translation type="unfinished"></translation>
+ <translation>Mostrar no Explorador</translation>
</message>
<message>
<source>Show the VirtualBox Machine Definition file in Explorer.</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra o ficheiro da Definição de Máquina VirtualBox no Explorador.</translation>
</message>
<message>
<source>Create Shortcut on Desktop</source>
- <translation type="unfinished"></translation>
+ <translation>Criar Atalho no Ecrã</translation>
</message>
<message>
<source>Creates an Shortcut file to the VirtualBox Machine Definition file on your Desktop.</source>
- <translation type="unfinished"></translation>
+ <translation>Cria um ficheiro de Atalho para o ficheiro da Definião de Máquina VirtualBox no seu Ecrã.</translation>
</message>
<message>
<source>Show in File Manager</source>
- <translation type="unfinished"></translation>
+ <translation>Mostrar no Gestor de Ficheiros</translation>
</message>
<message>
<source>Show the VirtualBox Machine Definition file in the File Manager</source>
- <translation type="unfinished"></translation>
+ <translation>Mostra o ficheiro da Definição de Máquina Virtual no Gestor de Ficheiros</translation>
</message>
<message>
<source>Show Toolbar</source>
- <translation type="unfinished"></translation>
+ <translation>Mostrar Barra de Ferramentas</translation>
</message>
<message>
<source>Show Statusbar</source>
+ <translation>Mostrar Barra de Estado</translation>
+ </message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -10276,23 +10935,23 @@ para a aceder de um SO Linux. Este recurso requer a instalação das Adições d
</message>
<message>
<source>Click to enlarge the screenshot.</source>
- <translation type="unfinished"></translation>
+ <translation>Clique para alargar a captura.</translation>
</message>
<message>
<source>&amp;Name:</source>
- <translation type="unfinished">&amp;Nome:</translation>
+ <translation>&amp;Nome:</translation>
</message>
<message>
<source>Taken:</source>
- <translation type="unfinished"></translation>
+ <translation>Criada:</translation>
</message>
<message>
<source>&amp;Description:</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Descrição:</translation>
</message>
<message>
<source>D&amp;etails:</source>
- <translation type="unfinished"></translation>
+ <translation>D&amp;etalhes:</translation>
</message>
</context>
<context>
@@ -10331,7 +10990,7 @@ para a aceder de um SO Linux. Este recurso requer a instalação das Adições d
</message>
<message>
<source>Take &amp;Snapshot</source>
- <translation type="unfinished">&amp;Criar Captura</translation>
+ <translation>&amp;Criar Captura</translation>
</message>
<message>
<source>Ctrl+Alt+S</source>
@@ -10399,7 +11058,7 @@ para a aceder de um SO Linux. Este recurso requer a instalação das Adições d
<message>
<source>online)</source>
<comment>Snapshot details</comment>
- <translation>em-linha)</translation>
+ <translation>ligado)</translation>
</message>
<message>
<source>offline)</source>
@@ -10435,7 +11094,7 @@ para a aceder de um SO Linux. Este recurso requer a instalação das Adições d
</message>
<message>
<source>Take a snapshot of the current virtual machine state</source>
- <translation type="unfinished">Cria uma captura do estado actual da máquina virtual actual</translation>
+ <translation>Cria uma captura do estado actual da máquina virtual actual</translation>
</message>
<message>
<source>Revert to Current Snapshot</source>
@@ -10463,7 +11122,7 @@ para a aceder de um SO Linux. Este recurso requer a instalação das Adições d
</message>
<message>
<source>Show the details of the selected snapshot</source>
- <translation type="unfinished">Mostra detalhes sobre o snapshot seleccionado</translation>
+ <translation>Mostra os detalhes da captura seleccionada</translation>
</message>
<message>
<source>Ctrl+Space</source>
@@ -10471,26 +11130,34 @@ para a aceder de um SO Linux. Este recurso requer a instalação das Adições d
</message>
<message>
<source> (%1)</source>
- <translation type="unfinished"></translation>
+ <translation> (%1)</translation>
</message>
<message>
<source>&amp;Restore Snapshot</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Restaurar Captura</translation>
</message>
<message>
<source>&amp;Delete Snapshot</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Apagar Captura</translation>
</message>
<message>
<source>Restore the selected snapshot of the virtual machine</source>
- <translation type="unfinished"></translation>
+ <translation>Restaura a captura seleccionada da máquina virtual</translation>
</message>
<message>
<source>Delete the selected snapshot of the virtual machine</source>
- <translation type="unfinished"></translation>
+ <translation>Apaga a captura seleccionada da máquina virtual</translation>
</message>
<message>
<source> (%1 ago)</source>
+ <translation> (%1 atrás)</translation>
+ </message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -10513,15 +11180,15 @@ para a aceder de um SO Linux. Este recurso requer a instalação das Adições d
<name>VBoxTakeSnapshotDlg</name>
<message>
<source>Take Snapshot of Virtual Machine</source>
- <translation type="unfinished">Criar Captura da Máquina Virtual</translation>
+ <translation>Criar Captura da Máquina Virtual</translation>
</message>
<message>
<source>Snapshot &amp;Name</source>
- <translation type="unfinished">&amp;Nome da Captura</translation>
+ <translation>&amp;Nome da Captura</translation>
</message>
<message>
<source>Snapshot &amp;Description</source>
- <translation type="unfinished">&amp;Descrição da Captura</translation>
+ <translation>&amp;Descrição da Captura</translation>
</message>
<message>
<source>Help</source>
@@ -10541,9 +11208,9 @@ para a aceder de um SO Linux. Este recurso requer a instalação das Adições d
</message>
<message numerus="yes">
<source>Warning: You are taking a snapshot of a running machine which has %n immutable image(s) attached to it. As long as you are working from this snapshot the immutable image(s) will not be reset to avoid loss of data.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>Aviso: Está prestes a criar uma captura de uma máquina a correr que tem %n imagem imutável ligada a ela. Desde que continue a trabalhar a partir desta captura a imagem imutável não será restaurada para evitar a perda de dados.</numerusform>
+ <numerusform>Aviso: Está prestes a criar uma captura de uma máquina a correr que tem %n imagens imutáveis anexadas ligadas a ela. Desde que continue a trabalhar a partir desta captura as imagens imutáveis não serão restauradas para evitar a perda de dados.</numerusform>
</translation>
</message>
</context>
@@ -10551,23 +11218,23 @@ para a aceder de um SO Linux. Este recurso requer a instalação das Adições d
<name>VBoxTextEditor</name>
<message>
<source>Edit text</source>
- <translation type="unfinished"></translation>
+ <translation>Editar texto</translation>
</message>
<message>
<source>&amp;Replace...</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Substituir...</translation>
</message>
<message>
<source>Replaces the current text with the content of a file.</source>
- <translation type="unfinished"></translation>
+ <translation>Substitui o testo actual com o conteúdo de um ficheiro.</translation>
</message>
<message>
<source>Text (*.txt);;All (*.*)</source>
- <translation type="unfinished"></translation>
+ <translation>Texto (*.txt);;All (*.*)</translation>
</message>
<message>
<source>Select a file to open...</source>
- <translation type="unfinished"></translation>
+ <translation>Seleccione um ficheiro para abrir...</translation>
</message>
</context>
<context>
@@ -10806,15 +11473,15 @@ corresponder a qualquer valor.&lt;/qt&gt;</translation>
</message>
<message>
<source>Chec&amp;k</source>
- <translation type="unfinished">&amp;Verificar</translation>
+ <translation>&amp;Verificar</translation>
</message>
<message>
<source>&amp;Close</source>
- <translation type="unfinished">&amp;Fechar</translation>
+ <translation>&amp;Fechar</translation>
</message>
<message>
<source>VirtualBox Update Wizard</source>
- <translation type="unfinished"></translation>
+ <translation>Assitente de Actualização VirtualBox</translation>
</message>
<message>
<source>Check for Updates</source>
@@ -10826,7 +11493,7 @@ corresponder a qualquer valor.&lt;/qt&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="unfinished">Resumo</translation>
+ <translation>Resumo</translation>
</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>
@@ -10834,7 +11501,7 @@ corresponder a qualquer valor.&lt;/qt&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Unable to obtain the new version information due to the following network error:&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Incapaz de obter informação acerca de novas versões devido ao seguinte erro de rede:&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Não é possível obter informação acerca da nova versões devido ao seguinte erro da rede:&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/p&gt;</translation>
</message>
<message>
<source>You are already running the most recent version of VirtualBox.</source>
@@ -10842,7 +11509,7 @@ corresponder a qualquer valor.&lt;/qt&gt;</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will connect to the VirtualBox web-site and check if a newer version of VirtualBox is available.&lt;/p&gt;&lt;p&gt;Use the &lt;b&gt;Check&lt;/b&gt; button to check for a new version now or the &lt;b&gt;Cancel&lt;/b&gt; button if you do not want to perform this check.&lt;/p&gt;&lt;p&gt;You can run this wizard at any time by choosing &lt;b&gt;Check for Updates...&lt;/b&gt; from the &lt;b&gt;Help&lt;/b&gt; menu.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Este assistente conectará ao sítio &apos;web&apos; VirtualBox e verifica se está disponível uma nova versão.&lt;/p&gt;&lt;p&gt;Use o botão &lt;b&gt;Verificar&lt;/b&gt; para verificar agora acerca de uma nova versão ou o botão &lt;b&gt;Cancelar&lt;/b&gt; se não deseja executar esta verificação.&lt;/p&gt;&lt;p&gt;Pode correr este assistente em qualquer altura ao escolher &lt;b&gt;Verificar Actualizações...&lt;/b&gt; no menu &lt;b&gt;Ajuda&lt;/b&gt;</translation>
</message>
</context>
<context>
@@ -10997,7 +11664,7 @@ corresponder a qualquer valor.&lt;/qt&gt;</translation>
<message>
<source>Not Detected</source>
<comment>guest additions</comment>
- <translation type="unfinished">Não Detectadas</translation>
+ <translation>Não Detectadas</translation>
</message>
<message>
<source>Not Detected</source>
@@ -11010,7 +11677,7 @@ corresponder a qualquer valor.&lt;/qt&gt;</translation>
</message>
<message>
<source>Guest OS Type</source>
- <translation type="unfinished">Tipo de Sistema Operativo Convidado</translation>
+ <translation>Tipo de SO Convidado</translation>
</message>
<message>
<source>Hard Disk Statistics</source>
@@ -11036,24 +11703,24 @@ corresponder a qualquer valor.&lt;/qt&gt;</translation>
</message>
<message>
<source>VBoxVMInformationDlg</source>
- <translation type="unfinished"></translation>
+ <translation>VBoxVMInformationDlg</translation>
</message>
<message>
<source>Storage Statistics</source>
- <translation type="unfinished"></translation>
+ <translation>Estatísticas de Armazenamento</translation>
</message>
<message>
<source>No Storage Devices</source>
- <translation type="unfinished"></translation>
+ <translation>Sem Dispositivos de Armazenamento</translation>
</message>
<message>
<source>Network Statistics</source>
- <translation type="unfinished"></translation>
+ <translation>Estatísticas da Rede</translation>
</message>
<message>
<source>Not Available</source>
<comment>details report (VRDE server port)</comment>
- <translation type="unfinished"></translation>
+ <translation>Não Disponível</translation>
</message>
</context>
<context>
@@ -11315,7 +11982,7 @@ corresponder a qualquer valor.&lt;/qt&gt;</translation>
</message>
<message>
<source>Displays the host parallel device name.</source>
- <translation type="obsolete">Mostra o nome do dispositivo paralelo da máquina.</translation>
+ <translation type="obsolete">Mostra o nome do dispositivo paralelo do hospedeiro.</translation>
</message>
</context>
<context>
@@ -11346,7 +12013,7 @@ corresponder a qualquer valor.&lt;/qt&gt;</translation>
</message>
<message>
<source>Displays the IRQ number of this serial port. Valid values are integer numbers in range from &lt;tt&gt;0&lt;/tt&gt; to &lt;tt&gt;255&lt;/tt&gt;. Values greater than &lt;tt&gt;15&lt;/tt&gt; may only be used if the &lt;b&gt;IO APIC&lt;/b&gt; is enabled for this virtual machine.</source>
- <translation type="obsolete">Mostra o número IRQ associado a esta porta série. Os valores válidos são números inteiros de &lt;tt&gt;0&lt;/tt&gt; a &lt;tt&gt;255&lt;/tt&gt;. Valores maiores que &lt;tt&gt;15&lt;/tt&gt; só poderão ser usados se a opção &lt;b&gt;IO APIC&lt;/b&gt; estiver activada para esta máquina.</translation>
+ <translation type="obsolete">Mostra o número IRQ associado a esta porta série. Os valores válidos são números inteiros de &lt;tt&gt;0&lt;/tt&gt; a &lt;tt&gt;255&lt;/tt&gt;. Valores maiores que &lt;tt&gt;15&lt;/tt&gt; só poderão ser usados se a opção &lt;b&gt;IO APIC&lt;/b&gt; estiver activada para esta máquina virtual.</translation>
</message>
<message>
<source>I/O Po&amp;rt</source>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt_BR.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt_BR.ts
index be0eb9e80..b88df5269 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt_BR.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt_BR.ts
@@ -1,4 +1,6 @@
-<!DOCTYPE TS><TS>
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
<context>
<name>@@@</name>
<message>
@@ -567,12 +569,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>I&amp;nformações sobre a Sessão</translation>
+ <translation type="obsolete">I&amp;nformações sobre a Sessão</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>Habilitar T&amp;ela Remota</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">Configuraçõe&amp;s...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -738,7 +825,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Rede VDE, &apos;%1&apos;</translation>
+ <translation type="obsolete">Rede VDE, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -864,6 +951,26 @@
<comment>details report</comment>
<translation>Descrição</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -1084,6 +1191,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">Nome do Servidor (&amp;H):</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1443,6 +1554,10 @@ p, li { white-space: pre-wrap; }
<source>Cancel</source>
<translation type="obsolete">Cancelar</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">Iniciar</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1516,41 +1631,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Geral</translation>
- </message>
- <message>
- <source>Input</source>
- <translation> Entrada </translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Atualizar</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Idioma</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Rede</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Extensões</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1991,6 +2071,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -2060,23 +2191,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Shift Esquerdo</translation>
+ <translation type="obsolete">Shift Esquerdo</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Shift Direito</translation>
+ <translation type="obsolete">Shift Direito</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Ctrl Esquerdo</translation>
+ <translation type="obsolete">Ctrl Esquerdo</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Ctrl Direito</translation>
+ <translation type="obsolete">Ctrl Direito</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Alt Esquerdo</translation>
+ <translation type="obsolete">Alt Esquerdo</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2293,6 +2424,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importar &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2437,7 +2572,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Indica o status dos recursos de virtualização de hardware utilizados por esta máquina virtual:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Indica o status dos recursos de virtualização de hardware utilizados por esta máquina virtual:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2460,6 +2595,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;O Servidor VRDP está ouvindo na porta %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2659,7 +2799,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Você habilitou a Aceleração 3D para um sistema operacional que utiliza um driver de vídeo WDDM. Para melhor performance, defina a memória de vídeo do sistema convidado para pelo menos &lt;b&gt;%1&lt;/b&gt;.</translation>
+ <translation type="obsolete">Você habilitou a Aceleração 3D para um sistema operacional que utiliza um driver de vídeo WDDM. Para melhor performance, defina a memória de vídeo do sistema convidado para pelo menos &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">você possui a Aceleração de Vídeo 2D habilitada. Como a Aceleração de Vídeo 2D somente é suportada em sistemas convidados Windows, este recurso será desabilitado.</translation>
</message>
</context>
<context>
@@ -2904,6 +3052,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Exibir No &amp;Topo da Tela</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">você selecionou um tipo de sistema operacional convidado de 64 bits para esta VM. Como tais sistemas convidados exigem virtualização de hardware (VT-x/AMD-V), este recurso será habilitado automaticamente.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -3085,7 +3237,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Seleciona o nome da placa de rede se o tipo de conexão for equivalente a &lt;b&gt;Placa de Rede em Modo Bridge&lt;/b&gt; ou &lt;b&gt;Placa de Rede Exclusiva de Hospedeiro&lt;/b&gt; ou o nome da rede interna caso o tipo de conexão seja equivalente a &lt;b&gt;Rede Interna&lt;/b&gt;.</translation>
+ <translation type="obsolete">Seleciona o nome da placa de rede se o tipo de conexão for equivalente a &lt;b&gt;Placa de Rede em Modo Bridge&lt;/b&gt; ou &lt;b&gt;Placa de Rede Exclusiva de Hospedeiro&lt;/b&gt; ou o nome da rede interna caso o tipo de conexão seja equivalente a &lt;b&gt;Rede Interna&lt;/b&gt;.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -3111,6 +3263,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>Redirecionamento de &amp;Portas</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3645,7 +3833,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Nenhum disco rígido foi selecionado para &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">Nenhum disco rígido foi selecionado para &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3919,6 +4107,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation>Selecione um arquivo de imagem de disquete...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">no máximo um é suportado</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">até %1 são suportados</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">você está utilizando mais controladoras de armazenamento que o chipset %1 suporta. Altere o tipo de chipset na página de Configurações do Sistema ou reduza a quantidade das seguintes controladoras de armazenamento na página de Configurações de Armazenamento: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -4109,6 +4351,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>você associou o tipo de chipset ICH9 a esta VM. Ele não funcionará corretamente a menos que o recurso de IO APIC também esteja habilitado. Isto será feito automaticamente assim que pressionar o botão OK.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished">você habilitou um dispositivo do tipo USB HID (Human Interface Device). Isto não irá funcionar corretamente a menos que a emulação USB também esteja habilitada. Isto será feito automaticamente quando você pressionar o botão OK.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -4235,7 +4503,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>USB 2.0 está habilitado para esta máquina virtual, mas para esta funcionalidade é necessário instalar &lt;b&gt;%1&lt;/b&gt;. Instale o Pacote de Extensão a partir do site do VirtualBox. Após instalar este componente, você poderá habilitar novamente o suporte a USB 2.0. Por enquanto, o suporte a USB 2.0 será desligado, a menos que você cancele as mudanças atuais.</translation>
+ <translation type="obsolete">USB 2.0 está habilitado para esta máquina virtual, mas para esta funcionalidade é necessário instalar &lt;b&gt;%1&lt;/b&gt;. Instale o Pacote de Extensão a partir do site do VirtualBox. Após instalar este componente, você poderá habilitar novamente o suporte a USB 2.0. Por enquanto, o suporte a USB 2.0 será desligado, a menos que você cancele as mudanças atuais.</translation>
+ </message>
+ <message>
+ <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>
</context>
<context>
@@ -4348,6 +4620,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4393,7 +4680,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Criar Novo Disco Virtual</translation>
@@ -4490,7 +4777,7 @@ sistema operacional Convidado com o tamanho do disco rígido virtual.&lt;/p&gt;<
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Sumário</translation>
+ <translation type="unfinished">Sumário</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4506,7 +4793,7 @@ sistema operacional Convidado com o tamanho do disco rígido virtual.&lt;/p&gt;<
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Selecione um arquivo para a nova imagem de disco rígido</translation>
+ <translation type="unfinished">Selecione um arquivo para a nova imagem de disco rígido</translation>
</message>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;
@@ -4564,12 +4851,12 @@ demorar bastante tempo, dependendo do tamanho escolhido e da velocidade de seu d
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Localização</translation>
+ <translation type="unfinished">Localização</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Tamanho</translation>
+ <translation type="unfinished">Tamanho</translation>
</message>
<message>
<source>Bytes</source>
@@ -4628,108 +4915,280 @@ demorar bastante tempo, dependendo do tamanho escolhido e da velocidade de seu d
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Se as configurações acima estiverem corretas, pressione o botão &lt;b&gt;Finalizar&lt;/b&gt;. Assim que pressioná-lo, um novo disco rígido será criado.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;Localização</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">Tamanho (&amp;S)</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Bem-Vindo ao Assistente de Criação de Novo Disco Virtual!</translation>
+ <translation type="obsolete">Bem-Vindo ao Assistente de Criação de Novo Disco Virtual!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Este assistente irá ajudá-lo a criar um novo disco rígido virtual para a sua máquina virtual.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Este assistente irá ajudá-lo a criar um novo disco rígido virtual para a sua máquina virtual.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished">Selecione um arquivo de disco rígido virtual...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Selecione o tipo de imagem de disco virtual que você deseja criar.&lt;/p&gt;&lt;p&gt;O &lt;b&gt;armazenamento dinamicamente expansível&lt;/b&gt; ocupa inicialmente um espaço bem pequeno no seu disco rígido físico e irá crescer dinamicamente (até o tamanho especificado) à medida em que o sistema operacional Convidado exigir mais espaço.&lt;/p&gt;&lt;p&gt;O &lt;b&gt;armazenamento de tamanho fixo&lt;/b&gt; não cresce. Ele é armazenado em um arquivo com o tamanho definido para o disco rígido virtual. A criação de um armazenamento de tamanho fixo pode demorar bastante tempo, dependendo do tamanho escolhido e da velocidade de seu disco rígido físico.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Selecione o tipo de imagem de disco virtual que você deseja criar.&lt;/p&gt;&lt;p&gt;O &lt;b&gt;armazenamento dinamicamente expansível&lt;/b&gt; ocupa inicialmente um espaço bem pequeno no seu disco rígido físico e irá crescer dinamicamente (até o tamanho especificado) à medida em que o sistema operacional Convidado exigir mais espaço.&lt;/p&gt;&lt;p&gt;O &lt;b&gt;armazenamento de tamanho fixo&lt;/b&gt; não cresce. Ele é armazenado em um arquivo com o tamanho definido para o disco rígido virtual. A criação de um armazenamento de tamanho fixo pode demorar bastante tempo, dependendo do tamanho escolhido e da velocidade de seu disco rígido físico.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Tipo de Armazenamento</translation>
+ <translation type="obsolete">Tipo de Armazenamento</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>Armazenamento &amp;dinamicamente expansível</translation>
+ <translation type="obsolete">Armazenamento &amp;dinamicamente expansível</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>Armazenamento de tamanho &amp;fixo</translation>
+ <translation type="obsolete">Armazenamento de tamanho &amp;fixo</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Tipo de Armazenamento do Disco Rígido</translation>
+ <translation type="obsolete">Tipo de Armazenamento do Disco Rígido</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Pressione o botão &lt;b&gt;Selecionar&lt;/b&gt; para selecionar a localização e o nome do arquivo que irá armazenar os dados do disco rígido virtual ou digite um nome de arquivo no campo de entrada.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Pressione o botão &lt;b&gt;Selecionar&lt;/b&gt; para selecionar a localização e o nome do arquivo que irá armazenar os dados do disco rígido virtual ou digite um nome de arquivo no campo de entrada.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;Localização</translation>
+ <translation type="obsolete">&amp;Localização</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Selecione o tamanho do disco rígido virtual em megabytes. Este tamanho irá aparecer para o sistema operacional Convidado como o tamanho máximo deste disco rígido.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Selecione o tamanho do disco rígido virtual em megabytes. Este tamanho irá aparecer para o sistema operacional Convidado como o tamanho máximo deste disco rígido.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>Tamanho (&amp;S)</translation>
+ <translation type="obsolete">Tamanho (&amp;S)</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Localização do Disco Virtual e Tamanho</translation>
+ <translation type="obsolete">Localização do Disco Virtual e Tamanho</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Selecione um arquivo para a nova imagem de disco rígido</translation>
+ <translation type="obsolete">Selecione um arquivo para a nova imagem de disco rígido</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Imagens de disco rígido (*.vdi)</translation>
+ <translation type="obsolete">Imagens de disco rígido (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Você irá criar um novo disco rígido virtual com os seguintes parâmetros:</translation>
+ <translation type="obsolete">Você irá criar um novo disco rígido virtual com os seguintes parâmetros:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Sumário</translation>
+ <translation type="obsolete">Sumário</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Tipo</translation>
+ <translation type="obsolete">Tipo</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Localização</translation>
+ <translation type="obsolete">Localização</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Tamanho</translation>
+ <translation type="obsolete">Tamanho</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Se as configurações acima estiverem corretas, pressione o botão &lt;b&gt;%1&lt;/b&gt;. Assim que pressioná-lo, um novo disco rígido será criado.</translation>
+ <translation type="obsolete">Se as configurações acima estiverem corretas, pressione o botão &lt;b&gt;%1&lt;/b&gt;. Assim que pressioná-lo, um novo disco rígido será criado.</translation>
</message>
</context>
<context>
@@ -4975,6 +5434,10 @@ utilizando o diálogo de Configurações da MV.&lt;/p&gt;</translation>
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">&amp;Utilizar disco rígido existente</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -5260,6 +5723,120 @@ utilizando o diálogo de Configurações da MV.&lt;/p&gt;</translation>
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Geral</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation> Entrada </translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Atualizar</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Idioma</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rede</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Extensões</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Geral</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>Sistema</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Monitor</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Armazenamento</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Ãudio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rede</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Portas</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Portas Seriais</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Portas Paralelas</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Pastas Compartilhadas</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">você selecionou um tipo de sistema operacional convidado de 64 bits para esta VM. Como tais sistemas convidados exigem virtualização de hardware (VT-x/AMD-V), este recurso será habilitado automaticamente.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">você possui a Aceleração de Vídeo 2D habilitada. Como a Aceleração de Vídeo 2D somente é suportada em sistemas convidados Windows, este recurso será desabilitado.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">você habilitou um dispositivo do tipo USB HID (Human Interface Device). Isto não irá funcionar corretamente a menos que a emulação USB também esteja habilitada. Isto será feito automaticamente quando você pressionar o botão OK.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">no máximo um é suportado</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">até %1 são suportados</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">você está utilizando mais controladoras de armazenamento que o chipset %1 suporta. Altere o tipo de chipset na página de Configurações do Sistema ou reduza a quantidade das seguintes controladoras de armazenamento na página de Configurações de Armazenamento: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -5398,81 +5975,6 @@ utilizando o diálogo de Configurações da MV.&lt;/p&gt;</translation>
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Geral</translation>
- </message>
- <message>
- <source>System</source>
- <translation>Sistema</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Monitor</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Armazenamento</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Ãudio</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Rede</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Portas</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Portas Seriais</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Portas Paralelas</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Pastas Compartilhadas</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>você selecionou um tipo de sistema operacional convidado de 64 bits para esta VM. Como tais sistemas convidados exigem virtualização de hardware (VT-x/AMD-V), este recurso será habilitado automaticamente.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>você possui a Aceleração de Vídeo 2D habilitada. Como a Aceleração de Vídeo 2D somente é suportada em sistemas convidados Windows, este recurso será desabilitado.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>você habilitou um dispositivo do tipo USB HID (Human Interface Device). Isto não irá funcionar corretamente a menos que a emulação USB também esteja habilitada. Isto será feito automaticamente quando você pressionar o botão OK.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>no máximo um é suportado</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>até %1 são suportados</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>você está utilizando mais controladoras de armazenamento que o chipset %1 suporta. Altere o tipo de chipset na página de Configurações do Sistema ou reduza a quantidade das seguintes controladoras de armazenamento na página de Configurações de Armazenamento: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5712,6 +6214,14 @@ Versão %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation>Controladora de Disco Rígido (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -7760,7 +8270,7 @@ Versão %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Adaptador %1</translation>
+ <translation type="obsolete">Adaptador %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -8168,34 +8678,46 @@ Versão %1</translation>
<comment>medium</comment>
<translation>Este disco rígido de base está indiretamente conectado através do seguinte disco rígido diferencial:</translation>
</message>
- <message>
+ <message numerus="yes">
<source>%n year(s)</source>
- <translation>%n anos
+ <translation type="unfinished">
+ <numerusform>%n anos
+ </numerusform>
</translation>
</message>
- <message>
+ <message numerus="yes">
<source>%n month(s)</source>
- <translation>%n meses
+ <translation type="unfinished">
+ <numerusform>%n meses
+ </numerusform>
</translation>
</message>
- <message>
+ <message numerus="yes">
<source>%n day(s)</source>
- <translation>%n dias
+ <translation type="unfinished">
+ <numerusform>%n dias
+ </numerusform>
</translation>
</message>
- <message>
+ <message numerus="yes">
<source>%n hour(s)</source>
- <translation>%n horas
+ <translation type="unfinished">
+ <numerusform>%n horas
+ </numerusform>
</translation>
</message>
- <message>
+ <message numerus="yes">
<source>%n minute(s)</source>
- <translation>%n minuto(s)
+ <translation type="unfinished">
+ <numerusform>%n minuto(s)
+ </numerusform>
</translation>
</message>
- <message>
+ <message numerus="yes">
<source>%n second(s)</source>
- <translation>%n segundos
+ <translation type="unfinished">
+ <numerusform>%n segundos
+ </numerusform>
</translation>
</message>
<message>
@@ -8210,7 +8732,7 @@ Versão %1</translation>
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Rede VDE, &apos;%1&apos;</translation>
+ <translation type="obsolete">Rede VDE, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -8220,7 +8742,7 @@ Versão %1</translation>
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>Controladora VDE</translation>
+ <translation type="obsolete">Controladora VDE</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -8417,6 +8939,61 @@ Versão %1</translation>
<comment>DiskType</comment>
<translation>Múltiplas Conexões</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Adaptador %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -9149,15 +9726,15 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>Location</source>
- <translation>Localização</translation>
+ <translation type="obsolete">Localização</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Tipo (Formatação)</translation>
+ <translation type="obsolete">Tipo (Formatação)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Conectado a</translation>
+ <translation type="obsolete">Conectado a</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -9239,17 +9816,17 @@ to the system default language.&lt;/qt&gt;
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Conectado a</translation>
+ <translation type="obsolete">Conectado a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Conectado a</translation>
+ <translation type="obsolete">Conectado a</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Conectado a</translation>
+ <translation type="obsolete">Conectado a</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -9267,6 +9844,46 @@ to the system default language.&lt;/qt&gt;
<source>All %1 images (%2)</source>
<translation>Todas as imagens de %1 (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Tipo:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Localização:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -9326,7 +9943,7 @@ to the system default language.&lt;/qt&gt;
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Adaptadores de Rede</translation>
+ <translation type="obsolete">Adaptadores de Rede</translation>
</message>
</context>
<context>
@@ -10188,7 +10805,7 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Não foi possível acessar a USB no sistema hospedeiro, pois nem o sistema de arquivos USB (usbfs) nem os serviços DBus e hal estão disponíveis. Se você deseja utilizar dispositivos USB dentre de sistemas convidados, corrija as configurações e reinicie o VirtualBox.</translation>
+ <translation type="obsolete">Não foi possível acessar a USB no sistema hospedeiro, pois nem o sistema de arquivos USB (usbfs) nem os serviços DBus e hal estão disponíveis. Se você deseja utilizar dispositivos USB dentre de sistemas convidados, corrija as configurações e reinicie o VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -10309,7 +10926,7 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Você tem certeza de que deseja restaurar o snapshot &lt;b&gt;%1&lt;/b&gt;? Isto fará com que você perca o estado atual da máquina, que não poderá ser recuperado.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Você tem certeza de que deseja restaurar o snapshot &lt;b&gt;%1&lt;/b&gt;? Isto fará com que você perca o estado atual da máquina, que não poderá ser recuperado.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -10571,9 +11188,11 @@ to the system default language.&lt;/qt&gt;
<source>&lt;p&gt;The VirtualBox Guest Additions do not appear to be available on this virtual machine, and shared folders cannot be used without them. To use shared folders inside the virtual machine, please install the Guest Additions if they are not installed, or re-install them if they are not working correctly, by selecting &lt;b&gt;Install Guest Additions&lt;/b&gt; from the &lt;b&gt;Machine&lt;/b&gt; menu. If they are installed but the machine is not yet fully started then shared folders will be available once it is.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;Os Adicionais para Convidado não estão disponíveis nesta máquina virtual, e portanto não é possível utilizar o recurso de pastas compartilhadas. Para utilizar pastas compartilhadas dentro da máquina virtual, instale os Adicionais para Convidado, ou instale-os novamente caso não estejam funcionando corretamente. Para fazer isto, selecione a opção &lt;b&gt;Instalar Adicionais para Convidado&lt;/b&gt; no menu &lt;b&gt;Máquina&lt;/b&gt;. Caso já esteja instalado mas a máquina esteja em processo de inicialização, aguarde até que esteja totalmente ativa e a opção de pastas compartilhadas estará disponível.&lt;/p&gt;</translation>
</message>
- <message>
+ <message numerus="yes">
<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>&lt;p&gt;As máquinas virtuais &lt;b&gt;%1&lt;/b&gt; possuem estado de execução salvo. &lt;/p&gt;&lt;p&gt;Se você continuar, o estado atual de execução destas máquinas será descartado. As máquinas existentes não serão afetadas.&lt;/p&gt;
+ <translation type="unfinished">
+ <numerusform>&lt;p&gt;As máquinas virtuais &lt;b&gt;%1&lt;/b&gt; possuem estado de execução salvo. &lt;/p&gt;&lt;p&gt;Se você continuar, o estado atual de execução destas máquinas será descartado. As máquinas existentes não serão afetadas.&lt;/p&gt;
+ </numerusform>
</translation>
</message>
<message>
@@ -10606,7 +11225,7 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">Desculpe, aconteceu um erro genérico (sério!).</translation>
+ <translation type="unfinished">Desculpe, aconteceu um erro genérico (sério!).</translation>
</message>
<message>
<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>
@@ -10699,7 +11318,71 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<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>&lt;p&gt;USB 2.0 está habilitado para esta máquina virtual, mas para esta funcionalidade é necessário instalar &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt; Instale o Pacote de Extensão a partir do site do VirtualBox. Após instalar este componente, você poderá habilitar novamente o suporte a USB 2.0. Por enquanto, o suporte a USB 2.0 será desligado, a menos que você cancele as mudanças atuais.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;USB 2.0 está habilitado para esta máquina virtual, mas para esta funcionalidade é necessário instalar &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt; Instale o Pacote de Extensão a partir do site do VirtualBox. Após instalar este componente, você poderá habilitar novamente o suporte a USB 2.0. Por enquanto, o suporte a USB 2.0 será desligado, a menos que você cancele as mudanças atuais.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -10833,7 +11516,7 @@ to the system default language.&lt;/qt&gt;
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Pastas Compartilhadas</translation>
+ <translation type="obsolete">Pastas Compartilhadas</translation>
</message>
<message>
<source>OK</source>
@@ -10964,11 +11647,11 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Descartar (&amp;I)</translation>
+ <translation type="obsolete">Descartar (&amp;I)</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Descartar</translation>
+ <translation type="unfinished">Descartar</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -11258,6 +11941,18 @@ to the system default language.&lt;/qt&gt;
<source>Show Statusbar</source>
<translation>Exibir Barra de Status</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -11698,6 +12393,14 @@ para acessá-lo de um sistema operacional Linux. Este recurso requer a instalaç
<source> (%1 ago)</source>
<translation> (%1 atrás)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
@@ -11748,9 +12451,11 @@ para acessá-lo de um sistema operacional Linux. Este recurso requer a instalaç
<source>Cancel</source>
<translation type="obsolete">Cancelar</translation>
</message>
- <message>
+ <message numerus="yes">
<source>Warning: You are taking a snapshot of a running machine which has %n immutable image(s) attached to it. As long as you are working from this snapshot the immutable image(s) will not be reset to avoid loss of data.</source>
- <translation>Aviso: Você está criando um snapshot de uma máquina em execução que possui %n imagens imutáveis associadas a ela. Enquanto você estiver trabalhando a partir deste snapshot, as imagens imutáveis não serão reestabelecidas para evitar perda de dados.
+ <translation type="unfinished">
+ <numerusform>Aviso: Você está criando um snapshot de uma máquina em execução que possui %n imagens imutáveis associadas a ela. Enquanto você estiver trabalhando a partir deste snapshot, as imagens imutáveis não serão reestabelecidas para evitar perda de dados.
+ </numerusform>
</translation>
</message>
</context>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ro.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ro.ts
index 1c8f3a4d4..695d38e28 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ro.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ro.ts
@@ -526,11 +526,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">&amp;Setări...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -696,11 +777,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation type="unfinished"></translation>
@@ -824,6 +900,26 @@
<comment>details report</comment>
<translation type="unfinished">Descriere</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -1008,6 +1104,10 @@
<source>&amp;Hostname:</source>
<translation type="obsolete">&amp;Nume de gazdă:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1353,6 +1453,10 @@
<source>Cancel</source>
<translation type="obsolete">Renunță</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">Start</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1426,41 +1530,6 @@
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished">Intrare </translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished">Actualizare</translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished">Limbă</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Rețea</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished">VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1902,6 +1971,57 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1971,23 +2091,23 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
</message>
<message>
<source>Left Shift</source>
- <translation>Shift stânga</translation>
+ <translation type="obsolete">Shift stânga</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Shift dreapta</translation>
+ <translation type="obsolete">Shift dreapta</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Ctrl stânga</translation>
+ <translation type="obsolete">Ctrl stânga</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Ctrl dreapta</translation>
+ <translation type="obsolete">Ctrl dreapta</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Alt stânga</translation>
+ <translation type="obsolete">Alt stânga</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2176,6 +2296,10 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importă &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2320,7 +2444,7 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Indică statusul funcțiilor de virtualizare hardware folosite de această mașină virtuală: &lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Indică statusul funcțiilor de virtualizare hardware folosite de această mașină virtuală: &lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2343,6 +2467,11 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2525,7 +2654,11 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2751,6 +2884,10 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
<source>Show At &amp;Top Of Screen</source>
<translation>Poziționează &amp;sus</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2894,10 +3031,6 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
<translation>&amp;Nume:</translation>
</message>
<message>
- <source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>A&amp;dvanced</source>
<translation>A&amp;vansat</translation>
</message>
@@ -2921,6 +3054,42 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3378,10 +3547,6 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
@@ -3641,6 +3806,60 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3827,6 +4046,32 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3952,7 +4197,7 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
<translation type="unfinished">&lt;nobr&gt;Stare %1&lt;/nobr&gt;</translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -4070,6 +4315,21 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4115,7 +4375,7 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Creează disc fix virtual nou</translation>
@@ -4207,7 +4467,7 @@ O dată apăsat, o nouă imagine de disc hard va fi creată.
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Rezumat</translation>
+ <translation type="unfinished">Rezumat</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4223,7 +4483,7 @@ O dată apăsat, o nouă imagine de disc hard va fi creată.
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Selectați un fișier pentru noua imagine de disc fix</translation>
+ <translation type="unfinished">Selectați un fișier pentru noua imagine de disc fix</translation>
</message>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;
@@ -4284,12 +4544,12 @@ time depending on the image size and the write performance of your harddisk.&lt;
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Amplasare</translation>
+ <translation type="unfinished">Amplasare</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Dimensiune</translation>
+ <translation type="unfinished">Dimensiune</translation>
</message>
<message>
<source>Bytes</source>
@@ -4348,109 +4608,281 @@ time depending on the image size and the write performance of your harddisk.&lt;
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Dacă setările de mai sus sunt corecte, apăsați butonul &lt;b&gt;Finalizare&lt;/b&gt;. O dată apăsat, o nouă imagine de disc fix va fi creată.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">Amp&amp;lasare</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">Dimen&amp;siune</translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Bun venit la asistentul Creează disc virtual nou!</translation>
+ <translation type="obsolete">Bun venit la asistentul Creează disc virtual nou!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Acest asistent vă va ghida în procesul de creare a unui nou disc dur virtual pentru mașina dvs virtuală.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Acest asistent vă va ghida în procesul de creare a unui nou disc dur virtual pentru mașina dvs virtuală.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Selectați tipul de imagine virtuală de disc fix pe care doriți să o creați.&lt;/p&gt;&lt;p&gt;O &lt;b&gt;imagine expandabilă dinamic&lt;/b&gt; ocupă inițial un spațiu foarte mic pe discul fix fizic. Va crește dinamic (până la dimensiunre specificată), pe măsură ce SO musafir face uz de spațiul de pe disc. &lt;/p&gt;&lt;p&gt;O &lt;b&gt;imagine de dimensiune fixă&lt;/b&gt; nu crește. Este salvată într-un fișier de aproximativ aceeași dimensiune cu discul fix virtual. Crearea unei imagini de dimensiune fixă poate dura destul de mult în funcție de dimensiunea imaginii și de viteza de scriere a discului dvs.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Selectați tipul de imagine virtuală de disc fix pe care doriți să o creați.&lt;/p&gt;&lt;p&gt;O &lt;b&gt;imagine expandabilă dinamic&lt;/b&gt; ocupă inițial un spațiu foarte mic pe discul fix fizic. Va crește dinamic (până la dimensiunre specificată), pe măsură ce SO musafir face uz de spațiul de pe disc. &lt;/p&gt;&lt;p&gt;O &lt;b&gt;imagine de dimensiune fixă&lt;/b&gt; nu crește. Este salvată într-un fișier de aproximativ aceeași dimensiune cu discul fix virtual. Crearea unei imagini de dimensiune fixă poate dura destul de mult în funcție de dimensiunea imaginii și de viteza de scriere a discului dvs.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>TIp stocare</translation>
+ <translation type="obsolete">TIp stocare</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>Imagine expandabilă &amp;dinamic</translation>
+ <translation type="obsolete">Imagine expandabilă &amp;dinamic</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>Imagine de dimensiune &amp;fixă</translation>
+ <translation type="obsolete">Imagine de dimensiune &amp;fixă</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Tip stocare disc fix</translation>
+ <translation type="obsolete">Tip stocare disc fix</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Apăsați butonul &lt;b&gt;Selectează&lt;/b&gt; pentru a selecta amplasarea imaginii discului fix virtual sau tastați un nume de fișier în câmpul de intrare.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Apăsați butonul &lt;b&gt;Selectează&lt;/b&gt; pentru a selecta amplasarea imaginii discului fix virtual sau tastați un nume de fișier în câmpul de intrare.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>Amp&amp;lasare</translation>
+ <translation type="obsolete">Amp&amp;lasare</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Selectați dimensiunea imaginii discului fix virtual (în megaocteți). Această dimensiune va fi raportată SO musafir ca dimensiunea discului fix virtual.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Selectați dimensiunea imaginii discului fix virtual (în megaocteți). Această dimensiune va fi raportată SO musafir ca dimensiunea discului fix virtual.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>Dimen&amp;siune</translation>
+ <translation type="obsolete">Dimen&amp;siune</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Amplasare disc virtual și dimensiune</translation>
+ <translation type="obsolete">Amplasare disc virtual și dimensiune</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Selectați un fișier pentru noua imagine de disc fix</translation>
+ <translation type="obsolete">Selectați un fișier pentru noua imagine de disc fix</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Imagini disc dur (*.vdi)</translation>
+ <translation type="obsolete">Imagini disc dur (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
<translatorcomment>hmm</translatorcomment>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Veți crea o nouă imagine virtuală de disc dur cu următorii parametrii:</translation>
+ <translation type="obsolete">Veți crea o nouă imagine virtuală de disc dur cu următorii parametrii:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Rezumat</translation>
+ <translation type="obsolete">Rezumat</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Tip</translation>
+ <translation type="obsolete">Tip</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Amplasare</translation>
+ <translation type="obsolete">Amplasare</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Dimensiune</translation>
+ <translation type="obsolete">Dimensiune</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Dacă setările de mai sus sunt corecte, apăsați butonul &lt;b&gt;Finalizare&lt;/b&gt;. Odată apăsat, o nouă imagine de disc dur va fi creată.</translation>
+ <translation type="obsolete">Dacă setările de mai sus sunt corecte, apăsați butonul &lt;b&gt;Finalizare&lt;/b&gt;. Odată apăsat, o nouă imagine de disc dur va fi creată.</translation>
</message>
</context>
<context>
@@ -4703,6 +5135,10 @@ din listă apăsând butonul &lt;b&gt;Existent&lt;/b&gt; (pentru a invoca dialog
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">F&amp;olosește disc dur existent</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4932,6 +5368,96 @@ din listă apăsând butonul &lt;b&gt;Existent&lt;/b&gt; (pentru a invoca dialog
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation type="unfinished">Intrare </translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished">Actualizare</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation type="unfinished">Limbă</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Rețea</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation type="unfinished">VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation type="unfinished">Sistem</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation type="unfinished">Afișare</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation type="unfinished">Stocare</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished">Sunet</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Rețea</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation type="unfinished">Porturi</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation type="unfinished">Porturi seriale</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation type="unfinished">Porturi paralele</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation type="unfinished">Directoare partajate</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished">%1 - %2</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -5082,81 +5608,6 @@ din listă apăsând butonul &lt;b&gt;Existent&lt;/b&gt; (pentru a invoca dialog
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished">Sistem</translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished">Afișare</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished">Stocare</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished">Sunet</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Rețea</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished">Porturi</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished">Porturi seriale</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished">Porturi paralele</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished">Directoare partajate</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished">%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5408,6 +5859,14 @@ Versiunea %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -7443,7 +7902,7 @@ Versiunea %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Placă de rețea %1</translation>
+ <translation type="obsolete">Placă de rețea %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -7867,21 +8326,11 @@ Versiunea %1</translation>
<translation>Ecrane</translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>SAS</source>
<comment>StorageBus</comment>
<translation>SATA</translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation type="unfinished"></translation>
@@ -8071,6 +8520,61 @@ Versiunea %1</translation>
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -8830,15 +9334,15 @@ Folosiți meniul contextual sau butaonele din dreapta pentru a adâuga sau șter
</message>
<message>
<source>Location</source>
- <translation>Amplasare</translation>
+ <translation type="obsolete">Amplasare</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Tip (Format)</translation>
+ <translation type="obsolete">Tip (Format)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Conectat la</translation>
+ <translation type="obsolete">Conectat la</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -8920,17 +9424,17 @@ Folosiți meniul contextual sau butaonele din dreapta pentru a adâuga sau șter
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Conectat la</translation>
+ <translation type="obsolete">Conectat la</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Conectată la</translation>
+ <translation type="obsolete">Conectată la</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Conectată la</translation>
+ <translation type="obsolete">Conectată la</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -8948,6 +9452,46 @@ Folosiți meniul contextual sau butaonele din dreapta pentru a adâuga sau șter
<source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Amplasare:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -9007,7 +9551,7 @@ Folosiți meniul contextual sau butaonele din dreapta pentru a adâuga sau șter
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Plăci de rețea</translation>
+ <translation type="obsolete">Plăci de rețea</translation>
</message>
</context>
<context>
@@ -9838,10 +10382,6 @@ Folosiți meniul contextual sau butaonele din dreapta pentru a adâuga sau șter
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
<translation type="unfinished"></translation>
</message>
@@ -9955,10 +10495,6 @@ Folosiți meniul contextual sau butaonele din dreapta pentru a adâuga sau șter
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restore</source>
<translation>Restabilește</translation>
</message>
@@ -10312,15 +10848,75 @@ Folosiți meniul contextual sau butaonele din dreapta pentru a adâuga sau șter
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
- <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -10447,7 +11043,7 @@ Folosiți meniul contextual sau butaonele din dreapta pentru a adâuga sau șter
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Directoare partajate</translation>
+ <translation type="obsolete">Directoare partajate</translation>
</message>
<message>
<source>OK</source>
@@ -10578,11 +11174,11 @@ Folosiți meniul contextual sau butaonele din dreapta pentru a adâuga sau șter
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Anu&amp;lează starea salvată</translation>
+ <translation type="obsolete">Anu&amp;lează starea salvată</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Renunță</translation>
+ <translation type="unfinished">Renunță</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -10884,6 +11480,18 @@ Folosiți meniul contextual sau butaonele din dreapta pentru a adâuga sau șter
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -11312,6 +11920,14 @@ pentru a-l accesa dintr-un SO Linux. Această funcție necesită Guest Additions
<source> (%1 ago)</source>
<translation> (acum %1)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ru.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ru.ts
index f96d1cd94..2ad165635 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ru.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ru.ts
@@ -517,12 +517,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>&amp;Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ ÑеÑÑии</translation>
+ <translation type="obsolete">&amp;Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ ÑеÑÑии</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>Удалённый &amp;диÑплей</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation>&amp;СвойÑтва...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation>ÐаÑтроить виртуальную машину</translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation>&amp;Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ ÑеÑÑии...</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation>Копировать виртуальную машину</translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation>Копировать</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Данный маÑтер поможет Вам Ñоздать копию Вашей виртуальной машины.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation>&lt;p&gt;ПожалуйÑта, выберите Ð¸Ð¼Ñ Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð¹ виртуальной машины:&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>ЕÑли галочка Ñтоит, вÑем Ñетевым адаптерам новой машины будут назначены новые уникальные MAC адреÑа.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>&amp;Сгенерировать новые MAC адреÑа Ð´Ð»Ñ Ð²Ñех Ñетевых адаптеров</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation>МаÑтер ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»ÑŒÐ½Ð¾Ð¹ машины</translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation>ÐšÐ¾Ð¿Ð¸Ñ %1</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation>Только ÑоÑтоÑние машины</translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation>СоÑтоÑние машины и вÑех дочерних Ñнимков</translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation>СоÑтоÑние машины и вÑех Ñнимков</translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation>ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ</translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation>ПожалуйÑта уточните, какие чаÑти виртуальной машины должны быть Ñкопированы.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation>ЕÑли Ð’Ñ‹ выберите &lt;b&gt;Только ÑоÑтоÑние машины&lt;/b&gt;, будет Ñкопировано лишь текущее ÑоÑтоÑние машины.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation>ЕÑли Ð’Ñ‹ выберите &lt;b&gt;СоÑтоÑние машины и вÑех дочерних Ñнимков&lt;/b&gt;, будут Ñкопированы текущее ÑоÑтоÑние машины и ÑоÑтоÑÐ½Ð¸Ñ Ñ‚ÐµÑ… Ñнимков, которые ÑвлÑÑŽÑ‚ÑÑ Ð´Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ð¼Ð¸ Ð´Ð»Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ³Ð¾ ÑоÑтоÑÐ½Ð¸Ñ Ð¼Ð°ÑˆÐ¸Ð½Ñ‹.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation>ЕÑли Ð’Ñ‹ выберите &lt;b&gt;СоÑтоÑние машины и вÑех Ñнимков&lt;/b&gt;, будут Ñкопированы текущее ÑоÑтоÑние машины и ÑоÑтоÑÐ½Ð¸Ñ Ð²Ñех Ñнимков.</translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -688,7 +773,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE-Ñеть, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE-Ñеть, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -814,6 +899,26 @@
<comment>details report</comment>
<translation>ОпиÑание</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation>Предел загрузки ЦПУ</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation>&lt;nobr&gt;%1%&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>УниверÑальный драйвер, &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation>УниверÑальный драйвер, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -994,6 +1099,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">Ð˜Ð¼Ñ Ñ…&amp;оÑта:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation>ЭкÑпорт</translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1324,6 +1433,10 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;ЕÑли вышеÑказанное верно, нажмите кнопку &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;.&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation>Продолжить</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1397,41 +1510,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Общие</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Ввод</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>ОбновлениÑ</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Язык</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Сеть</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Плагины</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1868,6 +1946,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation>ЕÑли Ñтоит галочка, VirtualBox будет иÑпользовать данные наÑтройки Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ð¿Ñ€Ð¾ÐºÑи-Ñервером в целÑÑ… загрузки гоÑтевых дополнений и проверки обновлений.</translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation>&amp;ИÑпользовать прокÑи-Ñервер</translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation>Ð&amp;Ð´Ñ€ÐµÑ Ð¿Ñ€Ð¾ÐºÑи-Ñервера:</translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation>Задаёт Ð°Ð´Ñ€ÐµÑ Ð¿Ñ€Ð¾ÐºÑи-Ñервера.</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Порт:</translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation>Задаёт порт прокÑи-Ñервера.</translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation>ЕÑли Ñтоит галочка, VirtualBox будет иÑпользовать данные наÑтройки аутентификации Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ð¿Ñ€Ð¾ÐºÑи-Ñервером.</translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation>И&amp;Ñпользовать аутентификацию</translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation>Им&amp;Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ:</translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation>Задаёт Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ на прокÑи-Ñервере.</translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation>Па&amp;роль:</translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation>Задаёт пароль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ на прокÑи-Ñервере.</translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1937,23 +2066,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Левый Shift</translation>
+ <translation type="obsolete">Левый Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Правый Shift</translation>
+ <translation type="obsolete">Правый Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Левый Ctrl</translation>
+ <translation type="obsolete">Левый Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Правый Ctrl</translation>
+ <translation type="obsolete">Правый Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Левый Alt</translation>
+ <translation type="obsolete">Левый Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2150,6 +2279,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Импорт &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation>Импорт</translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2294,7 +2427,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Показывает ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¾Ð¿Ñ†Ð¸Ð¹ аппаратной виртуализации иÑпользуемых виртуальной машиной:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Показывает ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¾Ð¿Ñ†Ð¸Ð¹ аппаратной виртуализации иÑпользуемых виртуальной машиной:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2317,6 +2450,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;VRDP-Ñервер ожидает Ñоединений на порту %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation>Отображает ÑÑ‚Ð°Ñ‚ÑƒÑ Ñ€Ð°Ð·Ð½Ð¾Ð¾Ð±Ñ€Ð°Ð·Ð½Ñ‹Ñ… опций, иÑпользуемых виртуальной машиной:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2516,8 +2654,16 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="obsolete">Ð’Ñ‹ решили иÑпользовать 3D-уÑкорение Ð´Ð»Ñ Ð³Ð¾Ñтевой ОС, иÑпользующей WDDM видео-драйвер. Ð”Ð»Ñ Ð´Ð¾ÑÑ‚Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð¼Ð°ÐºÑимальной производительноÑти задайте количеÑтво видео-памÑти гоÑтевой ОС минимум в &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
<translation>Ð’Ñ‹ решили иÑпользовать 3D-уÑкорение Ð´Ð»Ñ Ð³Ð¾Ñтевой ОС, иÑпользующей WDDM видео-драйвер. Ð”Ð»Ñ Ð´Ð¾ÑÑ‚Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð¼Ð°ÐºÑимальной производительноÑти задайте количеÑтво видео-памÑти гоÑтевой ОС минимум в &lt;b&gt;%1&lt;/b&gt;.</translation>
</message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation>Ð´Ð»Ñ Ñтой машины выбрана Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ 2D-уÑÐºÐ¾Ñ€ÐµÐ½Ð¸Ñ Ð²Ð¸Ð´ÐµÐ¾. ПоÑкольку Ð´Ð°Ð½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÑ‚ÑÑ Ð»Ð¸ÑˆÑŒ клаÑÑом гоÑтевых ÑиÑтем Windows, она будет отключена.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsGeneral</name>
@@ -2749,6 +2895,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>&amp;РаÑположить Ñверху Ñкрана</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation>Ð´Ð»Ñ Ñтой машины выбран 64-битный тип гоÑтевой ОС. Ð’ ÑвÑзи Ñ Ñ‚ÐµÐ¼, что такие гоÑтевые ОС требуют активации функций аппаратной виртуализации (VT-x/AMD-V), Ñти функции будут включены автоматичеÑки.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2905,15 +3055,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>no bridged network adapter is selected</source>
- <translation>не выбран адаптер Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ Ñетевому моÑту</translation>
+ <translation>не выбран адаптер Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ Ñетевому моÑту.</translation>
</message>
<message>
<source>no internal network name is specified</source>
- <translation>не указано Ð¸Ð¼Ñ Ð²Ð½ÑƒÑ‚Ñ€ÐµÐ½Ð½ÐµÐ¹ Ñети</translation>
+ <translation>не указано Ð¸Ð¼Ñ Ð²Ð½ÑƒÑ‚Ñ€ÐµÐ½Ð½ÐµÐ¹ Ñети.</translation>
</message>
<message>
<source>no host-only network adapter is selected</source>
- <translation>не выбран виртуальный Ñетевой адаптер хоÑта</translation>
+ <translation>не выбран виртуальный Ñетевой адаптер хоÑта.</translation>
</message>
<message>
<source>Not selected</source>
@@ -2930,7 +3080,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>ПозволÑет выбрать Ð¸Ð¼Ñ Ñетевого адаптера, еÑли тип Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ - &lt;b&gt;Сетевой моÑÑ‚&lt;/b&gt; или &lt;b&gt;Виртуальный адаптер хоÑта&lt;/b&gt;, либо Ð¸Ð¼Ñ Ð²Ð½ÑƒÑ‚Ñ€ÐµÐ½Ð½ÐµÐ¹ Ñети, еÑли тип Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ - &lt;b&gt;ВнутреннÑÑ Ñеть&lt;/b&gt;.</translation>
+ <translation type="obsolete">ПозволÑет выбрать Ð¸Ð¼Ñ Ñетевого адаптера, еÑли тип Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ - &lt;b&gt;Сетевой моÑÑ‚&lt;/b&gt; или &lt;b&gt;Виртуальный адаптер хоÑта&lt;/b&gt;, либо Ð¸Ð¼Ñ Ð²Ð½ÑƒÑ‚Ñ€ÐµÐ½Ð½ÐµÐ¹ Ñети, еÑли тип Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ - &lt;b&gt;ВнутреннÑÑ Ñеть&lt;/b&gt;.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -2956,6 +3106,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>&amp;ÐŸÑ€Ð¾Ð±Ñ€Ð¾Ñ Ð¿Ð¾Ñ€Ñ‚Ð¾Ð²</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation>&amp;Ðеразборчивый режим:</translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation>Задаёт политику &quot;неразборчивого&quot; режима данного виртуального Ñетевого адаптера, еÑли он подключен к внутренней Ñети, виртуальному Ñетевому адаптеру хоÑта или Ñетевому моÑту.</translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation>Параметры драйвера:</translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation>ЗдеÑÑŒ Ð’Ñ‹ можете задать необходимые параметры Ñетевого драйвера. Параметры должны быть заданы в форме &lt;b&gt;имÑ=значение&lt;/b&gt; и завиÑÑÑ‚ от Ñамого драйвера. ИÑпользуйте &lt;b&gt;shift-enter&lt;/b&gt; Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð° на новую Ñтроку.</translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation>не выбран универÑальный драйвер.</translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation>Задаёт Ñетевой адаптер хоÑта, через который пойдёт трафик данного виртуального Ñетевого адаптера.</translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation>Задаёт Ð¸Ð¼Ñ Ð²Ð½ÑƒÑ‚Ñ€ÐµÐ½Ð½ÐµÐ¹ Ñети, к которой будет подключен данный виртуальный Ñетевой адаптер. Ð’Ñ‹ можете Ñоздать новую внутреннюю Ñеть, выбрав имÑ, которое не иÑпользуетÑÑ Ð¸Ð½Ñ‹Ð¼Ð¸ виртуальными Ñетевыми адаптерами данной и других машин.</translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation>Задаёт виртуальный Ñетевой адаптер хоÑта, через который пойдёт трафик данного виртуального Ñетевого адаптера. Ð’Ñ‹ можете добавлÑть и удалÑть виртуальные Ñетевые адаптеры хоÑта, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¾ÐºÐ½Ð¾ глобальных ÑвойÑтв менеджера виртуальных машин.</translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation>Задаёт Ð¸Ð¼Ñ ÑƒÐ½Ð¸Ð²ÐµÑ€Ñального Ñетевого драйвера, который будет иÑпользоватьÑÑ Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ виртуального Ñетевого адаптера.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3486,7 +3672,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Ðе выбран жёÑткий диÑк Ð´Ð»Ñ &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">Ðе выбран жёÑткий диÑк Ð´Ð»Ñ &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3760,6 +3946,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation>Выбрать образ гибкого диÑка...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation>ЕÑли Ñтоит галочка, VirtualBox будет подавлÑть демонтирование образа в ÑлучаÑÑ… Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ ÐµÐ³Ð¾ Ñо Ñтороны гоÑтевой ÑиÑтемы.</translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation>&amp;Живой CD/DVD</translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation>ЕÑли Ñтоит галочка, VirtualBox будет Ñчитать данное уÑтройÑтво твердотельным накопителем (SSD).</translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation>&amp;Твердотельный накопитель</translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation>Детали:</translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>не указано Ð¸Ð¼Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»Ð»ÐµÑ€Ð° на позиции &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation>контроллер на позиции &lt;b&gt;%1&lt;/b&gt; иÑпользует имÑ, иÑпользуемое контроллером на позиции &lt;b&gt;%2&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation>не выбран жёÑткий диÑк Ð´Ð»Ñ &lt;i&gt;%1&lt;/i&gt;.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation>поддерживаетÑÑ Ð¼Ð°ÐºÑимум один</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation>поддерживаетÑÑ Ð²Ð¿Ð»Ð¾Ñ‚ÑŒ до %1</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation>Ð’ данный момент больше контроллеров ноÑителей информации, чем поддерживаетÑÑ Ñ‡Ð¸Ð¿Ñетом %1. ПожалуйÑта, измените тип чипÑета на Ñтранице &apos;СиÑтема&apos; или уменьшите количеÑтво Ñледующих контроллеров на Ñтранице &apos;ÐоÑители&apos;: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation>&amp;Порты:</translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation>Задаёт количеÑтво портов контроллера ноÑителей информации типа SATA, выбранного в данный момент в дереве ноÑителей информации. Это значение не может быть меньше, чем макÑимальный номер иÑпользованного порта + 1.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3950,6 +4190,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>Ð’Ñ‹ задали тип чипÑета ICH9 Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ машины. Машина не Ñможет функционировать еÑли Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ IO-APIC будет отключена, поÑтому Ð´Ð°Ð½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ включена автоматичеÑки при закрытии диалога наÑтроек.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation>Предел &amp;загрузки ЦПУ:</translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation>Ограничивает количеÑтво времени, отведённого каждому виртуальному процеÑÑору. Каждому виртуальному процеÑÑору будет отведено вплоть до указанного количеÑтва времени работы реального процеÑÑора (в процентах). Это ограничение ÑнимаетÑÑ Ð¿ÑƒÑ‚Ñ‘Ð¼ уÑтановки данного атрибута в значение, равное 100%. УÑтановка данного атрибута в Ñлишком малое значение может привеÑти к очень медленной работе виртуальной машины.</translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation>Ð’Ñ‹ уÑтановили предел загрузки ЦПУ в Ñлишком малое значение, что может привеÑти к очень медленной работе виртуальной машины.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation>Ð’Ñ‹ включили поддержку USB HID (уÑтройÑтва пользовательÑкого интерфейÑа). Ð”Ð°Ð½Ð½Ð°Ñ Ð¾Ð¿Ñ†Ð¸Ñ Ð½Ðµ работает без активированной USB ÑмулÑции, поÑтому USB ÑмулÑÑ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ активирована в момент ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð½Ð°Ñтроек виртуальной машины при закрытии данного диалога.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation>&lt;qt&gt;%1%&lt;/qt&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation>&lt;qt&gt;%1%&lt;/qt&gt;</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -4076,6 +4342,10 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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="obsolete">в наÑтоÑщий момент, поддержка USB 2.0 активна Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ виртуальной машины. Однако, Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы она работала верно, необходимо уÑтановить плагин &lt;b&gt;%1&lt;/b&gt;. ПожалуйÑта, уÑтановите плагин, предварительно загрузив его Ñ Ñайта поддержки VirtualBox. ПоÑле Ñтого Ð’Ñ‹ Ñможете повторно активировать поддержку USB 2.0. До уÑтановки плагина поддержка USB 2.0 будет автоматичеÑки отключатьÑÑ Ð¿Ð¾ принÑтии наÑтроек данной машины.</translation>
+ </message>
+ <message>
+ <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>в наÑтоÑщий момент, поддержка USB 2.0 активна Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ виртуальной машины. Однако, Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы она работала верно, необходимо уÑтановить плагин &lt;b&gt;%1&lt;/b&gt;. ПожалуйÑта, уÑтановите плагин, предварительно загрузив его Ñ Ñайта поддержки VirtualBox. ПоÑле Ñтого Ð’Ñ‹ Ñможете повторно активировать поддержку USB 2.0. До уÑтановки плагина поддержка USB 2.0 будет автоматичеÑки отключатьÑÑ Ð¿Ð¾ принÑтии наÑтроек данной машины.</translation>
</message>
</context>
@@ -4189,6 +4459,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation>Изменить атрибуты ноÑителÑ</translation>
+ </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;Ð’Ñ‹ ÑобираетеÑÑŒ изменить атрибуты виртуального ноÑителÑ, раÑположенного по адреÑу &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;ПожалуйÑта, выберите один из Ñледующих типов ноÑÐ¸Ñ‚ÐµÐ»Ñ Ð¸ нажмите &lt;b&gt;%2&lt;/b&gt; чтобы продолжить или &lt;b&gt;%3&lt;/b&gt; в противном Ñлучае.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation>Выберите тип ноÑителÑ:</translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4234,10 +4519,10 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
- <translation>Создать новый виртуальный жёÑткий диÑк</translation>
+ <translation>Создать новый виртуальный диÑк</translation>
</message>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
@@ -4249,7 +4534,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Итог</translation>
+ <translation>Итог</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4261,7 +4546,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Выберите файл Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð·Ð° нового жеÑткого диÑка</translation>
+ <translation>Выберите Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° Ð´Ð»Ñ Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ виртуального диÑка</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -4283,12 +4568,12 @@ p, li { white-space: pre-wrap; }
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">РаÑположение</translation>
+ <translation>РаÑположение</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Размер</translation>
+ <translation>Размер</translation>
</message>
<message>
<source>Bytes</source>
@@ -4347,108 +4632,280 @@ p, li { white-space: pre-wrap; }
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">ЕÑли Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ð°Ñ Ð²Ñ‹ÑˆÐµ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð²ÐµÑ€Ð½Ð°, нажмите кнопку &lt;b&gt;Готово&lt;/b&gt;. ПоÑле Ñтого будет Ñоздан новый жеÑткий диÑк.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation>%1_копиÑ</translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation>Создать</translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation>Копировать виртуальный диÑк</translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation>Копировать</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation>МаÑтер ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ диÑка</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Данный маÑтер поможет Вам Ñоздать копию Вашего виртуального диÑка.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation>ПожалуйÑта, выберите виртуальный диÑк, который Ð’Ñ‹ желаете Ñкопировать, еÑли он ещё не выбран. Ð’Ñ‹ можете выбрать его из ÑпиÑка или нажать на кнопку Ñ Ð¸ÐºÐ¾Ð½ÐºÐ¾Ð¹ папки Ñправа от ÑпиÑка и выбрать файл виртуального диÑка в открывшемÑÑ Ð´Ð¸Ð°Ð»Ð¾Ð³Ðµ.</translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation>&amp;VDI (VirtualBox Disk Image)</translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation>V&amp;MDK (Virtual Machine Disk)</translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation>V&amp;HD (Virtual Hard Disk)</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation>МаÑтер ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ виртуального диÑка</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Данный маÑтер поможет Вам Ñоздать новый виртуальный диÑк Ð´Ð»Ñ Ð’Ð°ÑˆÐµÐ¹ виртуальной машины.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;ПожалуйÑта, выберите тип файла, который Ð’Ñ‹ хотите иÑпользовать при Ñоздании нового виртуального диÑка. ЕÑли у Ð’Ð°Ñ Ð½ÐµÑ‚ необходимоÑти иÑпользовать данный виртуальный диÑк Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼Ð¸ продуктами программной виртуализации, Ð’Ñ‹ можете оÑтавить данный параметр как еÑть.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation>Тип файла виртуального диÑка</translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation>ПожалуйÑта, выберите тип файла, который Ð’Ñ‹ хотите иÑпользовать при Ñоздании нового виртуального диÑка. ЕÑли у Ð’Ð°Ñ Ð½ÐµÑ‚ необходимоÑти иÑпользовать данный виртуальный диÑк Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼Ð¸ продуктами программной виртуализации, Ð’Ñ‹ можете оÑтавить данный параметр как еÑть.</translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation>Дополнительные атрибуты виртуального диÑка</translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation>ПожалуйÑта уточните, должен ли новый виртуальный диÑк подÑтраивать Ñвой размер под размер Ñвоего Ñодержимого или быть Ñоздан Ñразу заданного размера.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Файл &lt;b&gt;динамичеÑкого&lt;/b&gt; виртуального диÑка будет занимать необходимое меÑто на Вашем физичеÑком ноÑителе информации лишь по мере заполнениÑ, однако учтите, что он не Ñможет уменьшитьÑÑ Ð² размере еÑли меÑто, занÑтое его Ñодержимым, оÑвободитÑÑ.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Файл &lt;b&gt;фикÑированного&lt;/b&gt; виртуального диÑка может потребовать больше времени при Ñоздании на некоторых файловых ÑиÑтемах, однако, обычно, он быÑтрее в иÑпользовании.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation>&lt;p&gt;Ð’Ñ‹ можете также &lt;b&gt;разделить&lt;/b&gt; виртуальный диÑк на неÑколько файлов размером до 2Ñ… ГБ. Это может пригодитьÑÑ ÐµÑли Ð’Ñ‹ планируете хранить виртуальные ноÑители на Ñъёмных USB ноÑителÑÑ… или Ñтарых файловых ÑиÑтемах, некоторые из которых не поддерживают Ñлишком большие файлы.</translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation>&amp;ДинамичеÑкий виртуальный диÑк</translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation>&amp;ФикÑированный виртуальный диÑк</translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation>&amp;Разделить на файлы размером до 2х ГБ</translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation>РаÑположение и размер виртуального диÑка</translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation>Выберите размер виртуального диÑка в мегабайтах. Указанный размер будет фигурировать в гоÑтевой ОС в качеÑтве размера данного виртуального диÑка.</translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation>РаÑположение виртуального диÑка</translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation>Ðажмите кнопку &lt;b&gt;Выбрать&lt;/b&gt; Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° раÑположениÑ/имени файла виртуального диÑка или введите Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° в поле ввода.</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation>&lt;nobr&gt;%1 (%2 Б)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation>Ð’Ñ‹ ÑобираетеÑÑŒ Ñоздать новый виртуальный диÑк Ñо Ñледующими параметрами:</translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation>Ð’Ñ‹ ÑобираетеÑÑŒ Ñоздать копию виртуального диÑка Ñо Ñледующими параметрами:</translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation>ЕÑли Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ð°Ñ Ð²Ñ‹ÑˆÐµ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð²ÐµÑ€Ð½Ð°, нажмите кнопку &lt;b&gt;%1&lt;/b&gt;. ПоÑле Ñтого будет Ñоздан новый виртуальный диÑк.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 Б</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation>Тип файла</translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation>Дополнительно</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation>Тип файла</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation>&amp;РаÑположение</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation>Р&amp;азмер</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation>Дополнительные атрибуты</translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>МаÑтер ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ виртуального жёÑткого диÑка</translation>
+ <translation type="obsolete">МаÑтер ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ виртуального жёÑткого диÑка</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Данный маÑтер поможет Вам оÑущеÑтвить Ñоздание нового виртуального жёÑткого диÑка Ð´Ð»Ñ Ð’Ð°ÑˆÐµÐ¹ виртуальной машины.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Данный маÑтер поможет Вам оÑущеÑтвить Ñоздание нового виртуального жёÑткого диÑка Ð´Ð»Ñ Ð’Ð°ÑˆÐµÐ¹ виртуальной машины.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation>ИÑточник копированиÑ</translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation>Выбрать файл виртуального диÑка...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Выберите тип образа виртуального жёÑткого диÑка, который Ð’Ñ‹ хотите Ñоздать.&lt;/p&gt;&lt;p&gt;&lt;b&gt;ДинамичеÑки раÑширÑющийÑÑ Ð¾Ð±Ñ€Ð°Ð·&lt;/b&gt; первоначально занимает очень мало меÑта на физичеÑком жёÑтком диÑке. Он будет динамичеÑки раÑти (до заданного размера) по мере того, как гоÑÑ‚ÐµÐ²Ð°Ñ ÐžÐ¡ иÑпользует диÑковое проÑтранÑтво.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Образ фикÑированного размера&lt;/b&gt; не увеличиваетÑÑ. Он хранитÑÑ Ð² файле примерно того же размера, что и размер виртуального жёÑткого диÑка. Создание жёÑткого диÑка фикÑированного размера может занÑть длительное времÑ, в завиÑимоÑти от размера образа и производительноÑти физичеÑкого диÑка.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Выберите тип образа виртуального жёÑткого диÑка, который Ð’Ñ‹ хотите Ñоздать.&lt;/p&gt;&lt;p&gt;&lt;b&gt;ДинамичеÑки раÑширÑющийÑÑ Ð¾Ð±Ñ€Ð°Ð·&lt;/b&gt; первоначально занимает очень мало меÑта на физичеÑком жёÑтком диÑке. Он будет динамичеÑки раÑти (до заданного размера) по мере того, как гоÑÑ‚ÐµÐ²Ð°Ñ ÐžÐ¡ иÑпользует диÑковое проÑтранÑтво.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Образ фикÑированного размера&lt;/b&gt; не увеличиваетÑÑ. Он хранитÑÑ Ð² файле примерно того же размера, что и размер виртуального жёÑткого диÑка. Создание жёÑткого диÑка фикÑированного размера может занÑть длительное времÑ, в завиÑимоÑти от размера образа и производительноÑти физичеÑкого диÑка.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Тип образа виртуального жёÑткого диÑка</translation>
+ <translation type="obsolete">Тип образа виртуального жёÑткого диÑка</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>Д&amp;инамичеÑки раÑширÑющийÑÑ Ð¾Ð±Ñ€Ð°Ð·</translation>
+ <translation type="obsolete">Д&amp;инамичеÑки раÑширÑющийÑÑ Ð¾Ð±Ñ€Ð°Ð·</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>Образ &amp;фикÑированного размера</translation>
+ <translation type="obsolete">Образ &amp;фикÑированного размера</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Тип образа виртуального жёÑткого диÑка</translation>
+ <translation type="obsolete">Тип образа виртуального жёÑткого диÑка</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Ðажмите кнопку &lt;b&gt;Выбрать&lt;/b&gt; Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° раÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ имени файла виртуального жёÑткого диÑка или введите Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° в поле ввода.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Ðажмите кнопку &lt;b&gt;Выбрать&lt;/b&gt; Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° раÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ имени файла виртуального жёÑткого диÑка или введите Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° в поле ввода.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;РаÑположение</translation>
+ <translation type="obsolete">&amp;РаÑположение</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Выберите размер виртуального жёÑткого диÑка в мегабайтах. Указанный размер будет фигурировать в гоÑтевой ОС в качеÑтве размера данного жёÑткого диÑка.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Выберите размер виртуального жёÑткого диÑка в мегабайтах. Указанный размер будет фигурировать в гоÑтевой ОС в качеÑтве размера данного жёÑткого диÑка.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>Р&amp;азмер</translation>
+ <translation type="obsolete">Р&amp;азмер</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>МеÑтоположение и размер виртуального жёÑткого диÑка</translation>
+ <translation type="obsolete">МеÑтоположение и размер виртуального жёÑткого диÑка</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Выберите файл Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð·Ð° нового жёÑткого диÑка</translation>
+ <translation type="obsolete">Выберите файл Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð·Ð° нового жёÑткого диÑка</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Образы жёÑтких диÑков (*.vdi)</translation>
+ <translation type="obsolete">Образы жёÑтких диÑков (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 Б)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 Б)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Ð’Ñ‹ ÑобираетеÑÑŒ Ñоздать виртуальный жёÑткий диÑк Ñо Ñледующими параметрами:</translation>
+ <translation type="obsolete">Ð’Ñ‹ ÑобираетеÑÑŒ Ñоздать виртуальный жёÑткий диÑк Ñо Ñледующими параметрами:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Итог</translation>
+ <translation type="obsolete">Итог</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 Б</translation>
+ <translation type="obsolete">%1 Б</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Тип</translation>
+ <translation type="obsolete">Тип</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>РаÑположение</translation>
+ <translation type="obsolete">РаÑположение</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Размер</translation>
+ <translation type="obsolete">Размер</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>ЕÑли Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ð°Ñ Ð²Ñ‹ÑˆÐµ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð²ÐµÑ€Ð½Ð°, нажмите кнопку &lt;b&gt;%1&lt;/b&gt;. ПоÑле Ñтого будет Ñоздан новый жёÑткий диÑк.</translation>
+ <translation type="obsolete">ЕÑли Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ð°Ñ Ð²Ñ‹ÑˆÐµ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð²ÐµÑ€Ð½Ð°, нажмите кнопку &lt;b&gt;%1&lt;/b&gt;. ПоÑле Ñтого будет Ñоздан новый жёÑткий диÑк.</translation>
</message>
</context>
<context>
@@ -4586,6 +5043,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">&amp;ИÑпользовать ÑущеÑтвующий жёÑткий диÑк</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4867,6 +5328,120 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Общие</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Ввод</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>ОбновлениÑ</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Язык</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Сеть</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Плагины</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation>ПрокÑи</translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Общие</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>СиÑтема</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>ДиÑплей</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>ÐоÑители</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Ðудио</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Сеть</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Порты</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>COM-порты</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>LPT-порты</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Общие папки</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">Ð´Ð»Ñ Ñтой машины выбран 64-битный тип гоÑтевой ОС. Ð’ ÑвÑзи Ñ Ñ‚ÐµÐ¼, что такие гоÑтевые ОС требуют активации функций аппаратной виртуализации (VT-x/AMD-V), Ñти функции будут включены автоматичеÑки.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">Ð´Ð»Ñ Ñтой машины выбрана Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ 2D-уÑÐºÐ¾Ñ€ÐµÐ½Ð¸Ñ Ð²Ð¸Ð´ÐµÐ¾. ПоÑкольку Ð´Ð°Ð½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÑ‚ÑÑ Ð»Ð¸ÑˆÑŒ клаÑÑом гоÑтевых ÑиÑтем Windows, она будет отключена.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">Ð’Ñ‹ включили поддержку USB HID (уÑтройÑтва пользовательÑкого интерфейÑа). Ð”Ð°Ð½Ð½Ð°Ñ Ð¾Ð¿Ñ†Ð¸Ñ Ð½Ðµ работает без активированной USB ÑмулÑции, поÑтому USB ÑмулÑÑ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ активирована в момент ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð½Ð°Ñтроек виртуальной машины при закрытии данного диалога.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">поддерживаетÑÑ Ð¼Ð°ÐºÑимум один</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">поддерживаетÑÑ Ð²Ð¿Ð»Ð¾Ñ‚ÑŒ до %1</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">Ð’ данный момент больше контроллеров ноÑителей информации, чем поддерживаетÑÑ Ñ‡Ð¸Ð¿Ñетом %1. ПожалуйÑта, измените тип чипÑета на Ñтранице &apos;СиÑтема&apos; или уменьшите количеÑтво Ñледующих контроллеров на Ñтранице &apos;ÐоÑители&apos;: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -5005,81 +5580,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Общие</translation>
- </message>
- <message>
- <source>System</source>
- <translation>СиÑтема</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>ДиÑплей</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>ÐоÑители</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Ðудио</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Сеть</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Порты</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>COM-порты</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>LPT-порты</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Общие папки</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>Ð´Ð»Ñ Ñтой машины выбран 64-битный тип гоÑтевой ОС. Ð’ ÑвÑзи Ñ Ñ‚ÐµÐ¼, что такие гоÑтевые ОС требуют активации функций аппаратной виртуализации (VT-x/AMD-V), Ñти функции будут включены автоматичеÑки.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>Ð´Ð»Ñ Ñтой машины выбрана Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ 2D-уÑÐºÐ¾Ñ€ÐµÐ½Ð¸Ñ Ð²Ð¸Ð´ÐµÐ¾. ПоÑкольку Ð´Ð°Ð½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÑ‚ÑÑ Ð»Ð¸ÑˆÑŒ клаÑÑом гоÑтевых ÑиÑтем Windows, она будет отключена.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>Ð’Ñ‹ включили поддержку USB HID (уÑтройÑтва пользовательÑкого интерфейÑа). Ð”Ð°Ð½Ð½Ð°Ñ Ð¾Ð¿Ñ†Ð¸Ñ Ð½Ðµ работает без активированной USB ÑмулÑции, поÑтому USB ÑмулÑÑ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ активирована в момент ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð½Ð°Ñтроек виртуальной машины при закрытии данного диалога.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>поддерживаетÑÑ Ð¼Ð°ÐºÑимум один</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>поддерживаетÑÑ Ð²Ð¿Ð»Ð¾Ñ‚ÑŒ до %1</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>Ð’ данный момент больше контроллеров ноÑителей информации, чем поддерживаетÑÑ Ñ‡Ð¸Ð¿Ñетом %1. ПожалуйÑта, измените тип чипÑета на Ñтранице &apos;СиÑтема&apos; или уменьшите количеÑтво Ñледующих контроллеров на Ñтранице &apos;ÐоÑители&apos;: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5237,6 +5737,14 @@ p, li { white-space: pre-wrap; }
<source>Hard Disk Controller (SAS)</source>
<translation>SAS-контроллер жёÑткого диÑка</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>ЕÑли галочка Ñтоит, вÑем Ñетевым адаптерам машины будут назначены новые уникальные MAC адреÑа.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>&amp;Сгенерировать новые MAC адреÑа Ð´Ð»Ñ Ð²Ñех Ñетевых адаптеров</translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -6671,7 +7179,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Ðдаптер %1</translation>
+ <translation type="obsolete">Ðдаптер %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -7139,7 +7647,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE-Ñеть, &apos;%1&apos;</translation>
+ <translation type="obsolete">VDE-Ñеть, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -7149,7 +7657,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>VDE-Ðдаптер</translation>
+ <translation type="obsolete">VDE-Ðдаптер</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -7346,6 +7854,61 @@ p, li { white-space: pre-wrap; }
<comment>DiskType</comment>
<translation>МножеÑтвенное подключение</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation>ДинамичеÑки раÑширÑющийÑÑ Ð¾Ð±Ñ€Ð°Ð·</translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation>Образ фикÑированного размера</translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation>ДинамичеÑки раÑширÑющийÑÑ Ð¾Ð±Ñ€Ð°Ð·, разделённый на файлы менее 2Ñ… ГБ</translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation>Образ фикÑированного размера, разделённый на файлы менее 2Ñ… ГБ</translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation>Предел загрузки ЦПУ</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation>&lt;nobr&gt;%1%&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>УниверÑальный драйвер, &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation>УниверÑальный драйвер</translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>Запретить</translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>Разрешить ВМ</translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation>Разрешить вÑÑ‘</translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation>Ðдаптер %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7508,15 +8071,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Location</source>
- <translation>РаÑположение</translation>
+ <translation type="obsolete">РаÑположение</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Тип (Формат)</translation>
+ <translation type="obsolete">Тип (Формат)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>ПодÑоединен к</translation>
+ <translation type="obsolete">ПодÑоединен к</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -7569,7 +8132,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Hard &amp;Disks</source>
- <translation>&amp;ЖеÑткие диÑки</translation>
+ <translation>&amp;ЖёÑткие диÑки</translation>
</message>
<message>
<source>Name</source>
@@ -7585,7 +8148,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&amp;CD/DVD Images</source>
- <translation>О&amp;бразы CD/DVD</translation>
+ <translation>&amp;ОптичеÑкие диÑки</translation>
</message>
<message>
<source>Size</source>
@@ -7593,22 +8156,22 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&amp;Floppy Images</source>
- <translation>Об&amp;разы диÑкет</translation>
+ <translation>&amp;Гибкие диÑки</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>ПодÑоединён к</translation>
+ <translation type="obsolete">ПодÑоединён к</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>ПодÑоединён к</translation>
+ <translation type="obsolete">ПодÑоединён к</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>ПодÑоединён к</translation>
+ <translation type="obsolete">ПодÑоединён к</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -7626,6 +8189,46 @@ p, li { white-space: pre-wrap; }
<source>All %1 images (%2)</source>
<translation>Ð’Ñе образы %1 (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation>Тип:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation>РаÑположение:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation>Формат:</translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation>Дополнительно:</translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation>ПодÑоединён к:</translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation>&amp;Копировать...</translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation>&amp;Изменить...</translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation>Копировать ÑущеÑтвующий виртуальный ноÑитель</translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation>Изменить атрибуты выбранного виртуального ноÑителÑ</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Закрыть</translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -7685,7 +8288,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Сетевые адаптеры</translation>
+ <translation type="obsolete">Сетевые адаптеры</translation>
</message>
</context>
<context>
@@ -8378,7 +8981,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Ðе удаётÑÑ Ð¿Ð¾Ð»ÑƒÑ‡Ð¸Ñ‚ÑŒ доÑтуп к USB в оÑновной операционной ÑиÑтеме поÑкольку ни Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð°Ñ ÑиÑтема USB (usbfs), ни ÑервиÑÑ‹ (DBus и hal) не доÑтупны в данный момент. ЕÑли Ð’Ñ‹ хотите иÑпользовать USB уÑтройÑтва оÑновной операционной ÑиÑтемы в гоÑтевой, Вам необходимо иÑправить данную проблему и перезапуÑтить VirtualBox.</translation>
+ <translation type="obsolete">Ðе удаётÑÑ Ð¿Ð¾Ð»ÑƒÑ‡Ð¸Ñ‚ÑŒ доÑтуп к USB в оÑновной операционной ÑиÑтеме поÑкольку ни Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð°Ñ ÑиÑтема USB (usbfs), ни ÑервиÑÑ‹ (DBus и hal) не доÑтупны в данный момент. ЕÑли Ð’Ñ‹ хотите иÑпользовать USB уÑтройÑтва оÑновной операционной ÑиÑтемы в гоÑтевой, Вам необходимо иÑправить данную проблему и перезапуÑтить VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -8499,7 +9102,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Ð’Ñ‹ уверены, что хотите воÑÑтановить Ñнимок &lt;b&gt;%1&lt;/b&gt;? Это приведёт к потере текущего ÑоÑтоÑÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ машины, которое не может быть воÑÑтановлено в дальнейшем.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Ð’Ñ‹ уверены, что хотите воÑÑтановить Ñнимок &lt;b&gt;%1&lt;/b&gt;? Это приведёт к потере текущего ÑоÑтоÑÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ машины, которое не может быть воÑÑтановлено в дальнейшем.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -8791,7 +9394,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">Сожалеем, произошло что-то в корне невероÑтное...</translation>
+ <translation>Сожалеем, произошло что-то в корне невероÑтное...</translation>
</message>
<message>
<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>
@@ -8880,7 +9483,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>Удаление файлов, принадлежащих виртуальной машине, в данный запрещено Ð´Ð»Ñ ÐžÐ¡ Windows/x64 (во избежание ÑÐ±Ð¾Ñ Ñамой ОС). Ð”Ð°Ð½Ð½Ð°Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° будет иÑправлена в будущем релизе.</translation>
+ <translation type="obsolete">Удаление файлов, принадлежащих виртуальной машине, в данный запрещено Ð´Ð»Ñ ÐžÐ¡ Windows/x64 (во избежание ÑÐ±Ð¾Ñ Ñамой ОС). Ð”Ð°Ð½Ð½Ð°Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° будет иÑправлена в будущем релизе.</translation>
</message>
<message>
<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>
@@ -8888,27 +9491,71 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>&lt;p&gt;Ð’ наÑтоÑщий момент, поддержка USB 2.0 включена Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ виртуальной машины. Однако, Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы она работала верно, необходимо уÑтановить плагин &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;ПожалуйÑта, уÑтановите плагин, предварительно загрузив его Ñ Ñайта поддержки VirtualBox. ПоÑле Ñтого Ð’Ñ‹ Ñможете повторно активировать поддержку USB 2.0. До уÑтановки плагина поддержка USB 2.0 будет автоматичеÑки отключатьÑÑ Ð¿Ð¾ принÑтии наÑтроек данной машины.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Ð’ наÑтоÑщий момент, поддержка USB 2.0 включена Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ виртуальной машины. Однако, Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы она работала верно, необходимо уÑтановить плагин &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;ПожалуйÑта, уÑтановите плагин, предварительно загрузив его Ñ Ñайта поддержки VirtualBox. ПоÑле Ñтого Ð’Ñ‹ Ñможете повторно активировать поддержку USB 2.0. До уÑтановки плагина поддержка USB 2.0 будет автоматичеÑки отключатьÑÑ Ð¿Ð¾ принÑтии наÑтроек данной машины.&lt;/p&gt;</translation>
</message>
<message>
<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">Ðе удалоÑÑŒ загрузить USB Proxy Ñлужбу хоÑта (VERR_FILE_NOT_FOUND). Возможно, Ð´Ð°Ð½Ð½Ð°Ñ Ñлужба не уÑтановлена на данном компьютере</translation>
+ <translation>Ðе удалоÑÑŒ загрузить USB Proxy Ñлужбу хоÑта (VERR_FILE_NOT_FOUND). Возможно, Ð´Ð°Ð½Ð½Ð°Ñ Ñлужба не уÑтановлена на данном компьютере</translation>
</message>
<message>
<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">Ð’ данный момент VirtualBox не может иÑпользовать уÑтройÑтва USB. Ð’Ñ‹ можете иÑправить данную проблему, добавив текущего Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð² группу &apos;vboxusers&apos;. Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÐµÐµ детальных объÑÑнений Ñледуйте указаниÑм руководÑтва пользователÑ</translation>
+ <translation>Ð’ данный момент VirtualBox не может иÑпользовать уÑтройÑтва USB. Ð’Ñ‹ можете иÑправить данную проблему, добавив текущего Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð² группу &apos;vboxusers&apos;. Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÐµÐµ детальных объÑÑнений Ñледуйте указаниÑм руководÑтва пользователÑ</translation>
</message>
<message>
<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">Ð’ данный момент VirtualBox не может иÑпользовать уÑтройÑтва USB. Ð’Ñ‹ можете иÑправить данную проблему, открыв текущему пользователю доÑтуп к файлам и папкам &apos;usbfs&apos;. Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÐµÐµ детальных объÑÑнений Ñледуйте указаниÑм руководÑтва пользователÑ</translation>
+ <translation>Ð’ данный момент VirtualBox не может иÑпользовать уÑтройÑтва USB. Ð’Ñ‹ можете иÑправить данную проблему, открыв текущему пользователю доÑтуп к файлам и папкам &apos;usbfs&apos;. Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÐµÐµ детальных объÑÑнений Ñледуйте указаниÑм руководÑтва пользователÑ</translation>
</message>
<message>
<source>The USB Proxy Service has not yet been ported to this host</source>
- <translation type="unfinished">Служба USB Proxy ещё не была портирована на данный хоÑÑ‚</translation>
+ <translation>Служба USB Proxy ещё не была портирована на данный хоÑÑ‚</translation>
</message>
<message>
<source>Could not load the Host USB Proxy service</source>
- <translation type="unfinished">Ðе удалоÑÑŒ загрузить USB Proxy Ñлужбу хоÑта</translation>
+ <translation>Ðе удалоÑÑŒ загрузить USB Proxy Ñлужбу хоÑта</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>Ðе удалоÑÑŒ зарегиÑтрировать виртуальную машину &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;ÐаÑтройки машины были изменены извне. У Ð’Ð°Ñ Ð² данный момент имеютÑÑ Ð½ÐµÑохранённые изменениÑ.&lt;/p&gt;&lt;p&gt;Желаете загрузить новые наÑтройки или оÑтавить Ñвои изменениÑ?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation>Загрузить новые</translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation>ОÑтавить Ñвои</translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation>СоÑтоÑние машины, наÑтройки которой Ð’Ñ‹ в данный момент изменÑете, было изменено извне. Ð’ Ñлучае Ð½Ð°Ð¶Ð°Ñ‚Ð¸Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ OK будут Ñохранены лишь те наÑтройки, которые могут быть изменены во Ð²Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ машины. Ð’Ñе Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… наÑтроек будут утерÑны.</translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>Ðе удалоÑÑŒ Ñкопировать виртуальную машину &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Ð’Ñ‹ ÑобираетеÑÑŒ воÑÑтановить Ñнимок &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Перед Ñтим Ð’Ñ‹ можете Ñоздать Ñнимок текущего ÑоÑтоÑÐ½Ð¸Ñ Ð¼Ð°ÑˆÐ¸Ð½Ñ‹, поÑтавив галочку внизу, по желанию; еÑли Ð’Ñ‹ Ñтого не Ñделаете, текущее ÑоÑтоÑние будет утерÑно навÑегда. Хотите ли продолжить?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation>Создать Ñнимок текущего ÑоÑтоÑÐ½Ð¸Ñ Ð¼Ð°ÑˆÐ¸Ð½Ñ‹</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Ð’Ñ‹ уверены, что хотите воÑÑтановить Ñнимок &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Ðе удалоÑÑŒ Ñменить тип ноÑÐ¸Ñ‚ÐµÐ»Ñ Ñ &lt;b&gt;&apos;%1&apos;&lt;/b&gt; на &lt;b&gt;&apos;%2&apos;&lt;/b&gt;.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <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>&lt;p&gt;Ð’ наÑтоÑщий момент, поддержка USB 2.0 включена Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ виртуальной машины. Однако, Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы она работала верно, необходимо уÑтановить плагин &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;ПожалуйÑта, уÑтановите плагин, предварительно загрузив его Ñ Ñайта поддержки VirtualBox. ПоÑле Ñтого Ð’Ñ‹ Ñможете повторно активировать поддержку USB 2.0. До уÑтановки плагина поддержка USB 2.0 будет автоматичеÑки отключатьÑÑ Ð¿Ð¾ принÑтии наÑтроек данной машины.&lt;/p&gt;</translation>
</message>
</context>
<context>
@@ -9022,7 +9669,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Общие папки</translation>
+ <translation type="obsolete">Общие папки</translation>
</message>
</context>
<context>
@@ -9053,7 +9700,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>&amp;Preferences...</source>
<comment>global settings</comment>
- <translation>&amp;ÐаÑтройки...</translation>
+ <translation>&amp;СвойÑтва...</translation>
</message>
<message>
<source>Display the global settings dialog</source>
@@ -9093,7 +9740,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Сб&amp;роÑить</translation>
+ <translation type="obsolete">Сб&amp;роÑить</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -9165,7 +9812,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&amp;Pause</source>
- <translation>Па&amp;уза</translation>
+ <translation>&amp;Пауза</translation>
</message>
<message>
<source>Suspend the execution of the virtual machine</source>
@@ -9299,6 +9946,22 @@ p, li { white-space: pre-wrap; }
<source>Show Statusbar</source>
<translation>Показать Ñтроку ÑтатуÑа</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation>&amp;Копировать...</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>Копировать выбранную виртуальную машину</translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation>СброÑить</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation>С&amp;броÑить Ñохранённое ÑоÑтоÑние</translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -9520,6 +10183,14 @@ p, li { white-space: pre-wrap; }
<source> (%1 ago)</source>
<translation> (%1 назад)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation>&amp;Копировать...</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>Копировать выбранную виртуальную машину</translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sk.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sk.ts
index f425aba3b..9238f8d12 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sk.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sk.ts
@@ -511,11 +511,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">&amp;Nastavenia...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -681,11 +762,6 @@
<translation type="unfinished">Karta pre sieť iba medzi hostiteľom a hosťom, &apos;%1&apos;</translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation type="unfinished">Adaptér %1</translation>
@@ -809,6 +885,26 @@
<comment>details report</comment>
<translation type="unfinished">Popis</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -969,6 +1065,10 @@
<source>&amp;Hostname:</source>
<translation type="obsolete">&amp;Hostiteľ:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1290,6 +1390,10 @@
<source>Cancel</source>
<translation type="obsolete">Zrušiť</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">Spustiť</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1363,41 +1467,6 @@
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Všeobecné</translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished">Vstup</translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished">Aktualizácia</translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished">Jazyk</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Sieť</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished">VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1826,6 +1895,57 @@
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1895,23 +2015,23 @@
</message>
<message>
<source>Left Shift</source>
- <translation>ľavý shift</translation>
+ <translation type="obsolete">ľavý shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>pravý shift</translation>
+ <translation type="obsolete">pravý shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>ľavý ctrl</translation>
+ <translation type="obsolete">ľavý ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>pravý ctrl</translation>
+ <translation type="obsolete">pravý ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>ľavý alt</translation>
+ <translation type="obsolete">ľavý alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2096,6 +2216,10 @@
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importovať &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2238,11 +2362,6 @@
<translation type="obsolete">&lt;hr&gt;VRDP server poÄúva na porte %1</translation>
</message>
<message>
- <source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
- <comment>Virtualization Stuff LED</comment>
- <translation></translation>
- </message>
- <message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation></translation>
@@ -2263,6 +2382,11 @@
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2457,9 +2581,13 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">povolili ste 2D akceleráciu videa. Pretože 2D akcelerácia videa je podporovaná iba pre hosťovské systémy s Windows, táto vlastnosť bude vypnutá.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsGeneral</name>
@@ -2607,6 +2735,10 @@
<source>Show At &amp;Top Of Screen</source>
<translation>Z&amp;obraziť na vrchu obrazovky</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2718,10 +2850,6 @@
<translation type="unfinished">&amp;Názov:</translation>
</message>
<message>
- <source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>A&amp;dvanced</source>
<translation type="unfinished"></translation>
</message>
@@ -2749,6 +2877,42 @@
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3106,10 +3270,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
@@ -3357,6 +3517,60 @@
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3538,6 +3752,32 @@
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3663,7 +3903,7 @@
<translation type="unfinished">&lt;nobr&gt;Stav: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -3777,6 +4017,21 @@
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3822,7 +4077,7 @@
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Vytvoriť nový virtuálny disk</translation>
@@ -3919,7 +4174,7 @@ ako veľkosť virtuálneho pevného disku.&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Zhrnutie</translation>
+ <translation type="unfinished">Zhrnutie</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -3935,7 +4190,7 @@ ako veľkosť virtuálneho pevného disku.&lt;/p&gt;</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Vyberte súbor pre obraz nového pevného disku</translation>
+ <translation type="unfinished">Vyberte súbor pre obraz nového pevného disku</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -3957,12 +4212,12 @@ ako veľkosť virtuálneho pevného disku.&lt;/p&gt;</translation>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Umiestnenie</translation>
+ <translation type="unfinished">Umiestnenie</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Veľkosť</translation>
+ <translation type="unfinished">Veľkosť</translation>
</message>
<message>
<source>Bytes</source>
@@ -4021,108 +4276,280 @@ ako veľkosť virtuálneho pevného disku.&lt;/p&gt;</translation>
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Ak sú vyššie uvedené nastavenia správne, stlaÄte tlaÄidlo &lt;b&gt;DokonÄiÅ¥&lt;/b&gt;. Po jeho stlaÄení bude vytvorený nový pevný disk.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;Umiestnenie</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Veľkosť</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Vitajte v sprievodcovi vytvorením nového virtuálneho disku!</translation>
+ <translation type="obsolete">Vitajte v sprievodcovi vytvorením nového virtuálneho disku!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Tento sprievodca vám pomôže vytvoriť nový virtuálny disk pre virtuálny stroj&gt;.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Tento sprievodca vám pomôže vytvoriť nový virtuálny disk pre virtuálny stroj&gt;.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Vyberte typ virtuálneho pevného disku, ktorý chcete vytvoriÅ¥.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Dynamicky sa zväÄÅ¡ujúce úložisko&lt;/b&gt; najprv zaberá veľmi málo miesta na fyzickom pevnom disku. Potom dynamicky rastie (až do definovanej veľkosti) podľa toho, koľko miesta si OS hosÅ¥a nárokuje.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Úložisko s fixnou veľkosÅ¥ou&lt;/b&gt; nerastie. Je uložené v súbore o približne rovnakej veľkosti ako virtuálny pevný disk. Vytvorenie úložiska s pevnou veľkosÅ¥ou môže trvaÅ¥ dlhší Äas v závislosti od jeho veľkosti a výkonu vášho disku pri zápise.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Vyberte typ virtuálneho pevného disku, ktorý chcete vytvoriÅ¥.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Dynamicky sa zväÄÅ¡ujúce úložisko&lt;/b&gt; najprv zaberá veľmi málo miesta na fyzickom pevnom disku. Potom dynamicky rastie (až do definovanej veľkosti) podľa toho, koľko miesta si OS hosÅ¥a nárokuje.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Úložisko s fixnou veľkosÅ¥ou&lt;/b&gt; nerastie. Je uložené v súbore o približne rovnakej veľkosti ako virtuálny pevný disk. Vytvorenie úložiska s pevnou veľkosÅ¥ou môže trvaÅ¥ dlhší Äas v závislosti od jeho veľkosti a výkonu vášho disku pri zápise.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Typ úložiska</translation>
+ <translation type="obsolete">Typ úložiska</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>&amp;Dynamicky sa zväÄÅ¡ujúce úložisko</translation>
+ <translation type="obsolete">&amp;Dynamicky sa zväÄÅ¡ujúce úložisko</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>Ú&amp;ložisko s fixnou veľkosťou</translation>
+ <translation type="obsolete">Ú&amp;ložisko s fixnou veľkosťou</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Typ úložiska pevného disku</translation>
+ <translation type="obsolete">Typ úložiska pevného disku</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;StlaÄte tlaÄidlo &lt;b&gt;Výber&lt;/b&gt; a vyberte umiestnenie súboru, ktoré bude slúžiÅ¥ na ukladanie dát pevného disku alebo napíšte jeho meno do vstupného poľa.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;StlaÄte tlaÄidlo &lt;b&gt;Výber&lt;/b&gt; a vyberte umiestnenie súboru, ktoré bude slúžiÅ¥ na ukladanie dát pevného disku alebo napíšte jeho meno do vstupného poľa.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;Umiestnenie</translation>
+ <translation type="obsolete">&amp;Umiestnenie</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Vyberte veľkosť virtuálneho pevného disku v megabajtoch. Túto veľkosť bude vidieť OS hosťa ako maximálnu veľkosť pevného disku.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Vyberte veľkosť virtuálneho pevného disku v megabajtoch. Túto veľkosť bude vidieť OS hosťa ako maximálnu veľkosť pevného disku.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Veľkosť</translation>
+ <translation type="obsolete">&amp;Veľkosť</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Umiestnenie a veľkosť virtuálneho disku</translation>
+ <translation type="obsolete">Umiestnenie a veľkosť virtuálneho disku</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Vyberte súbor pre obraz nového pevného disku</translation>
+ <translation type="obsolete">Vyberte súbor pre obraz nového pevného disku</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Obrazy pevných diskov (*.vdi)</translation>
+ <translation type="obsolete">Obrazy pevných diskov (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Chystáte sa vytvoriť nový virtuálny pevný disk s nasledujúcimi parametrami:</translation>
+ <translation type="obsolete">Chystáte sa vytvoriť nový virtuálny pevný disk s nasledujúcimi parametrami:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Zhrnutie</translation>
+ <translation type="obsolete">Zhrnutie</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Typ</translation>
+ <translation type="obsolete">Typ</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Umiestnenie</translation>
+ <translation type="obsolete">Umiestnenie</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Veľkosť</translation>
+ <translation type="obsolete">Veľkosť</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Ak sú vyššie uvedené udaje v poriadku, stlaÄte tlaÄidlo &lt;b&gt;%1&lt;/b&gt;. Po jeho stlaÄení bude vytvorený nový obraz pevného disku.</translation>
+ <translation type="obsolete">Ak sú vyššie uvedené udaje v poriadku, stlaÄte tlaÄidlo &lt;b&gt;%1&lt;/b&gt;. Po jeho stlaÄení bude vytvorený nový obraz pevného disku.</translation>
</message>
</context>
<context>
@@ -4361,6 +4788,10 @@ preskoÄiÅ¥ a pripojiÅ¥ pevné disky neskôr pomocou dialógu Nastavenia virtuá
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">&amp;Použiť existujúci pevný disk</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4590,6 +5021,100 @@ preskoÄiÅ¥ a pripojiÅ¥ pevné disky neskôr pomocou dialógu Nastavenia virtuá
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Všeobecné</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation type="unfinished">Vstup</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished">Aktualizácia</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation type="unfinished">Jazyk</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Sieť</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation type="unfinished">VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Všeobecné</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation type="unfinished">Systém</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation type="unfinished">Displej</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation type="unfinished">Úložisko</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished">Audio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Sieť</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation type="unfinished">Porty</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation type="unfinished">Sériové porty</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation type="unfinished">Paralelné porty</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation type="unfinished">Zdieľané prieÄinky</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished">%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">povolili ste 2D akceleráciu videa. Pretože 2D akcelerácia videa je podporovaná iba pre hosťovské systémy s Windows, táto vlastnosť bude vypnutá.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -4728,81 +5253,6 @@ preskoÄiÅ¥ a pripojiÅ¥ pevné disky neskôr pomocou dialógu Nastavenia virtuá
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Všeobecné</translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished">Systém</translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished">Displej</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished">Úložisko</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished">Audio</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Sieť</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished">Porty</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished">Sériové porty</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished">Paralelné porty</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished">Zdieľané prieÄinky</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished">%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished">povolili ste 2D akceleráciu videa. Pretože 2D akcelerácia videa je podporovaná iba pre hosťovské systémy s Windows, táto vlastnosť bude vypnutá.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5034,6 +5484,14 @@ verzia %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -6859,7 +7317,7 @@ verzia %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Adaptér %1</translation>
+ <translation type="obsolete">Adaptér %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -7305,21 +7763,11 @@ verzia %1</translation>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>SAS</source>
<comment>StorageBus</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation type="unfinished"></translation>
@@ -7509,6 +7957,61 @@ verzia %1</translation>
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Adaptér %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -8094,15 +8597,15 @@ je zobrazený &lt;b&gt;tuÄným&lt;/b&gt; písmom. Voľbou &lt;i&gt;Å tandardný
</message>
<message>
<source>Location</source>
- <translation>Umiestnenie</translation>
+ <translation type="obsolete">Umiestnenie</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Typ (Formát)</translation>
+ <translation type="obsolete">Typ (Formát)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Pripojený k</translation>
+ <translation type="obsolete">Pripojený k</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -8184,17 +8687,17 @@ je zobrazený &lt;b&gt;tuÄným&lt;/b&gt; písmom. Voľbou &lt;i&gt;Å tandardný
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Pripojený k</translation>
+ <translation type="obsolete">Pripojený k</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Pripojený k</translation>
+ <translation type="obsolete">Pripojený k</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Pripojený k</translation>
+ <translation type="obsolete">Pripojený k</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -8212,6 +8715,46 @@ je zobrazený &lt;b&gt;tuÄným&lt;/b&gt; písmom. Voľbou &lt;i&gt;Å tandardný
<source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Umiestnenie:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -8271,7 +8814,7 @@ je zobrazený &lt;b&gt;tuÄným&lt;/b&gt; písmom. Voľbou &lt;i&gt;Å tandardný
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Sieťové adaptéry</translation>
+ <translation type="obsolete">Sieťové adaptéry</translation>
</message>
</context>
<context>
@@ -8956,10 +9499,6 @@ je zobrazený &lt;b&gt;tuÄným&lt;/b&gt; písmom. Voľbou &lt;i&gt;Å tandardný
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
<translation type="unfinished"></translation>
</message>
@@ -9065,10 +9604,6 @@ je zobrazený &lt;b&gt;tuÄným&lt;/b&gt; písmom. Voľbou &lt;i&gt;Å tandardný
<translation>Používate TESTOVACIE zostavenie VirtualBoxu. Táto verzia nie je vhodná pre nasadenie v produkcii.</translation>
</message>
<message>
- <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restore</source>
<translation>Obnoviť</translation>
</message>
@@ -9422,15 +9957,75 @@ je zobrazený &lt;b&gt;tuÄným&lt;/b&gt; písmom. Voľbou &lt;i&gt;Å tandardný
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -9521,7 +10116,7 @@ je zobrazený &lt;b&gt;tuÄným&lt;/b&gt; písmom. Voľbou &lt;i&gt;Å tandardný
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Zdieľané prieÄinky</translation>
+ <translation type="obsolete">Zdieľané prieÄinky</translation>
</message>
<message>
<source>Cancel</source>
@@ -9648,11 +10243,11 @@ je zobrazený &lt;b&gt;tuÄným&lt;/b&gt; písmom. Voľbou &lt;i&gt;Å tandardný
</message>
<message>
<source>D&amp;iscard</source>
- <translation>&amp;Zahodiť</translation>
+ <translation type="obsolete">&amp;Zahodiť</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Zahodiť</translation>
+ <translation type="unfinished">Zahodiť</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -9938,6 +10533,18 @@ je zobrazený &lt;b&gt;tuÄným&lt;/b&gt; písmom. Voľbou &lt;i&gt;Å tandardný
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -10311,6 +10918,14 @@ je zobrazený &lt;b&gt;tuÄným&lt;/b&gt; písmom. Voľbou &lt;i&gt;Å tandardný
<source> (%1 ago)</source>
<translation> (pred %1)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sr.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sr.ts
index cb6d9bd56..d24255b50 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sr.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sr.ts
@@ -217,7 +217,7 @@
<name>QIWizardPage</name>
<message>
<source>Use the &lt;b&gt;%1&lt;/b&gt; button to go to the next page of the wizard and the &lt;b&gt;%2&lt;/b&gt; button to return to the previous page. You can also press &lt;b&gt;%3&lt;/b&gt; if you want to cancel the execution of this wizard.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>КориÑти дугме &lt;b&gt;%1&lt;/b&gt; за даљи лиÑÑ‚ аÑиÑтента и &lt;b&gt;%2&lt;/b&gt; дугме да би Ñе вратили назад. Можете иÑто ÑтиÑнути &lt;b&gt;%3&lt;/b&gt; ако желите да поништите аÑиÑтент.&lt;/p&gt;</translation>
</message>
</context>
<context>
@@ -244,7 +244,7 @@
</message>
<message>
<source>Auto-resize &amp;Guest Display</source>
- <translation type="unfinished">Ðуто-величина диÑплеја гоÑта</translation>
+ <translation>Ðуто-величина диÑплеја гоÑта</translation>
</message>
<message>
<source>Automatically resize the guest display when the window is resized (requires Guest Additions)</source>
@@ -292,7 +292,7 @@
</message>
<message>
<source>Take &amp;Snapshot...</source>
- <translation>Узми &amp;Снимак</translation>
+ <translation>Узми Снимак...</translation>
</message>
<message>
<source>Take a snapshot of the virtual machine</source>
@@ -431,59 +431,140 @@
</message>
<message>
<source>Enable remote desktop (RDP) connections to this machine</source>
- <translation type="unfinished"></translation>
+ <translation>Упали удаљене веже (RDP) на овој машини</translation>
</message>
<message>
<source>Enable &amp;Logging...</source>
<comment>debug action</comment>
- <translation type="unfinished"></translation>
+ <translation>Упали извештај...</translation>
</message>
<message>
<source>Switch to &amp;Fullscreen</source>
- <translation type="unfinished"></translation>
+ <translation>Пређи на Пун Екран</translation>
</message>
<message>
<source>Switch between normal and fullscreen mode</source>
- <translation type="unfinished"></translation>
+ <translation>Пребаци нормални/пун екран</translation>
</message>
<message>
<source>Switch to Seam&amp;less Mode</source>
- <translation type="unfinished"></translation>
+ <translation>Пређи интегриÑан мод</translation>
</message>
<message>
<source>Switch between normal and seamless desktop integration mode</source>
- <translation type="unfinished"></translation>
+ <translation>Пребаци нормални/нтегриÑан мод</translation>
</message>
<message>
<source>Switch to &amp;Scale Mode</source>
- <translation type="unfinished"></translation>
+ <translation>Пређи на зумиран мод</translation>
</message>
<message>
<source>Switch between normal and scale mode</source>
- <translation type="unfinished"></translation>
+ <translation>Пребаци нормални/зумиран мод</translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
- <translation type="unfinished"></translation>
+ <source>Enable R&amp;emote Display</source>
+ <translation>Упали удаљен диÑплеј</translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
- <translation type="unfinished"></translation>
+ <source>&amp;Settings...</source>
+ <translation>Параметри...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation>Уреди подешавања машине</translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation>Информација ÑеÑије...</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation>Клонирај машину</translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation>Клонирај</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;ÐÑиÑтент Вам помаже у креирање клона Ваше виртуалне машине.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Одабрати име за нову машину:&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation>Када одабрано, јединÑтвена MAC адреÑа ће бити поÑтављена за Ñве мрежне каре.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation>Иницијализација MAC адреÑе за ве мређне карте</translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation>Добродошли у аÑиÑтенту виртуале машине</translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation>%1 клон</translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation>Ðктуелни ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð°ÑˆÐ¸Ð½Ðµ</translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation>Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð°ÐºÑ‚ÑƒÐµÐ»Ð½Ðµ машине и деце</translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation>Сви ÑтатуÑи</translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation>Подешавање клонирања</translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation>Одаберите шта треба да Ñе клонира.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation>Ðко одаберете &lt;b&gt;Ðктуелни ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð°ÑˆÐ¸Ð½Ðµ&lt;/b&gt;, Ñамо ће актуелни ÑÑ‚Ð°Ñ‚ÑƒÑ Ð´Ð° буде клониран.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation>Ðко одаберете &lt;b&gt;Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð°ÐºÑ‚ÑƒÐµÐ»Ð½Ðµ машине и деце&lt;/b&gt; клонирано је актуелни ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð°ÑˆÐ¸Ð½Ðµ и ÑÑ‚Ð°Ñ‚ÑƒÑ Ñнимака деце.</translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation>Ðко одаберете &lt;b&gt;Сви ÑтатуÑи&lt;/b&gt;,актуелна машина и Ñве Ñлике Ñу клониране.</translation>
</message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
<message>
<source>No description. Press the Edit button below to add it.</source>
- <translation type="unfinished">Ðема опиÑа. СтиÑнути „Уреди“ да Ñе дода једно.</translation>
+ <translation>Ðема опиÑа. СтиÑнути „Уреди“ да Ñе дода једно.</translation>
</message>
<message>
<source>Edit</source>
- <translation type="unfinished">Уреди</translation>
+ <translation>Уреди</translation>
</message>
<message>
<source>Edit (Ctrl+E)</source>
- <translation type="unfinished">Уреди (Ctrl+E)</translation>
+ <translation>Уреди (Ctrl+E)</translation>
</message>
</context>
<context>
@@ -491,275 +572,290 @@
<message>
<source>Name</source>
<comment>details report</comment>
- <translation type="unfinished">Име</translation>
+ <translation>Име</translation>
</message>
<message>
<source>OS Type</source>
<comment>details report</comment>
- <translation type="unfinished">Тип ОЅ-а</translation>
+ <translation>Тип ОЅ-а</translation>
</message>
<message>
<source>Base Memory</source>
<comment>details report</comment>
- <translation type="unfinished">ОÑновна меморија</translation>
+ <translation>ОÑновна меморија</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 MB&lt;/nobr&gt;</source>
<comment>details report</comment>
- <translation type="unfinished">&lt;nobr&gt;%1 МБ&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt;%1 МБ&lt;/nobr&gt;</translation>
</message>
<message>
<source>Processors</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>ПроцеÑори</translation>
</message>
<message>
<source>&lt;nobr&gt;%1&lt;/nobr&gt;</source>
<comment>details report</comment>
- <translation type="unfinished">&lt;nobr&gt;%1&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt;%1&lt;/nobr&gt;</translation>
</message>
<message>
<source>Boot Order</source>
<comment>details report</comment>
- <translation type="unfinished">Ред бута</translation>
+ <translation>Ред бута</translation>
</message>
<message>
<source>ACPI</source>
<comment>details report</comment>
- <translation type="unfinished">ACPI</translation>
+ <translation>ACPI</translation>
</message>
<message>
<source>IO APIC</source>
<comment>details report</comment>
- <translation type="unfinished">IO APIC</translation>
+ <translation>IO APIC</translation>
</message>
<message>
<source>BIOS</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>BIOS</translation>
</message>
<message>
<source>VT-x/AMD-V</source>
<comment>details report</comment>
- <translation type="unfinished">VT-x/AMD-V</translation>
+ <translation>VT-x/AMD-V</translation>
</message>
<message>
<source>Nested Paging</source>
<comment>details report</comment>
- <translation type="unfinished">Подметнуто запиÑивање</translation>
+ <translation>Подметнуто запиÑивање</translation>
</message>
<message>
<source>PAE/NX</source>
<comment>details report</comment>
- <translation type="unfinished">PAE/NX</translation>
+ <translation>PAE/NX</translation>
</message>
<message>
<source>Acceleration</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Убрзање</translation>
</message>
<message>
<source>Video Memory</source>
<comment>details report</comment>
- <translation type="unfinished">Видео меморија</translation>
+ <translation>Видео меморија</translation>
</message>
<message>
<source>Screens</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Екрани</translation>
</message>
<message>
<source>2D Video</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>2D видео</translation>
</message>
<message>
<source>3D</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>3D</translation>
</message>
<message>
<source>Remote Desktop Server Port</source>
<comment>details report (VRDE Server)</comment>
- <translation type="unfinished"></translation>
+ <translation>Порт Ñервера удаљеног бироа</translation>
</message>
<message>
<source>Remote Desktop Server</source>
<comment>details report (VRDE Server)</comment>
- <translation type="unfinished"></translation>
+ <translation>Сервер удаљеног бироа</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (VRDE Server)</comment>
- <translation type="unfinished"></translation>
+ <translation>Онемогућено</translation>
</message>
<message>
<source>(CD/DVD)</source>
- <translation type="unfinished">(CD/DVD)</translation>
+ <translation>(CD/DVD)</translation>
</message>
<message>
<source>Not Attached</source>
<comment>details report (Storage)</comment>
- <translation type="unfinished">Ðије привезано</translation>
+ <translation>Ðије привезано</translation>
</message>
<message>
<source>Host Driver</source>
<comment>details report (audio)</comment>
- <translation type="unfinished">ХоÑÑ‚ драјвер</translation>
+ <translation>ХоÑÑ‚ драјвер</translation>
</message>
<message>
<source>Controller</source>
<comment>details report (audio)</comment>
- <translation type="unfinished">Контролер</translation>
+ <translation>Контролер</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (audio)</comment>
- <translation type="unfinished"></translation>
+ <translation>Онемогућено</translation>
</message>
<message>
<source>Bridged adapter, %1</source>
<comment>details report (network)</comment>
- <translation type="unfinished">МоÑÑ‚ адаптер, %1</translation>
+ <translation>МоÑÑ‚ адаптер, %1</translation>
</message>
<message>
<source>Internal network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation type="unfinished">Интерна мрежа, %1</translation>
+ <translation>Интерна мрежа, %1</translation>
</message>
<message>
<source>Host-only adapter, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation type="unfinished">Само хоÑÑ‚ адаптер, &apos;%1&apos;</translation>
- </message>
- <message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
+ <translation>Само хоÑÑ‚ адаптер, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
- <translation type="unfinished">Ðдаптер %1</translation>
+ <translation>Ðдаптер %1</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (network)</comment>
- <translation type="unfinished"></translation>
+ <translation>Онемогућено</translation>
</message>
<message>
<source>Port %1</source>
<comment>details report (serial ports)</comment>
- <translation type="unfinished">Порт %1</translation>
+ <translation>Порт %1</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (serial ports)</comment>
- <translation type="unfinished"></translation>
+ <translation>Онемогућено</translation>
</message>
<message>
<source>Port %1</source>
<comment>details report (parallel ports)</comment>
- <translation type="unfinished">Порт %1</translation>
+ <translation>Порт %1</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (parallel ports)</comment>
- <translation type="unfinished"></translation>
+ <translation>Онемогућено</translation>
</message>
<message>
<source>Device Filters</source>
<comment>details report (USB)</comment>
- <translation type="unfinished">Филтери уређаја</translation>
+ <translation>Филтери уређаја</translation>
</message>
<message>
<source>%1 (%2 active)</source>
<comment>details report (USB)</comment>
- <translation type="unfinished">%1 (%2 активно)</translation>
+ <translation>%1 (%2 активно)</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (USB)</comment>
- <translation type="unfinished"></translation>
+ <translation>Онемогућено</translation>
</message>
<message>
<source>Shared Folders</source>
<comment>details report (shared folders)</comment>
- <translation type="unfinished">Дељене фаÑцикле</translation>
+ <translation>Дељене фаÑцикле</translation>
</message>
<message>
<source>None</source>
<comment>details report (shared folders)</comment>
- <translation type="unfinished">Ðишта</translation>
+ <translation>Ðишта</translation>
</message>
<message>
<source>None</source>
<comment>details report (description)</comment>
- <translation type="unfinished">Ðишта</translation>
+ <translation>Ðишта</translation>
</message>
<message>
<source>The selected virtual machine is &lt;i&gt;inaccessible&lt;/i&gt;. Please inspect the error message shown below and press the &lt;b&gt;Refresh&lt;/b&gt; button if you want to repeat the accessibility check:</source>
- <translation type="unfinished">Одабрана машина &lt;i&gt;није доÑтупна&lt;/i&gt;. Проверити поруку показану иÑпод и ÑтиÑнути &lt;b&gt;ОÑвежи&lt;/b&gt; ако желите да поновити проверу приÑтупа:</translation>
+ <translation>Одабрана машина &lt;i&gt;није доÑтупна&lt;/i&gt;. Проверити поруку показану иÑпод и ÑтиÑнути &lt;b&gt;ОÑвежи&lt;/b&gt; ако желите да поновите проверу приÑтупа:</translation>
</message>
<message>
<source>General</source>
<comment>details report</comment>
- <translation type="unfinished">Опште</translation>
+ <translation>Опште</translation>
</message>
<message>
<source>System</source>
<comment>details report</comment>
- <translation type="unfinished">СиÑтем</translation>
+ <translation>СиÑтем</translation>
</message>
<message>
<source>Preview</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation>Преглед</translation>
</message>
<message>
<source>Display</source>
<comment>details report</comment>
- <translation type="unfinished">ДиÑплеј</translation>
+ <translation>ДиÑплеј</translation>
</message>
<message>
<source>Storage</source>
<comment>details report</comment>
- <translation type="unfinished">Стовариште</translation>
+ <translation>Стовариште</translation>
</message>
<message>
<source>Audio</source>
<comment>details report</comment>
- <translation type="unfinished">Ðудио</translation>
+ <translation>Ðудио</translation>
</message>
<message>
<source>Network</source>
<comment>details report</comment>
- <translation type="unfinished">Мрежа</translation>
+ <translation>Мрежа</translation>
</message>
<message>
<source>Serial Ports</source>
<comment>details report</comment>
- <translation type="unfinished">СеријÑки портови</translation>
+ <translation>СеријÑки портови</translation>
</message>
<message>
<source>Parallel Ports</source>
<comment>details report</comment>
- <translation type="unfinished">Паралелни портови</translation>
+ <translation>Паралелни портови</translation>
</message>
<message>
<source>USB</source>
<comment>details report</comment>
- <translation type="unfinished">USB</translation>
+ <translation>УСБ</translation>
</message>
<message>
<source>Shared Folders</source>
<comment>details report</comment>
- <translation type="unfinished">Дељене фаÑцикле</translation>
+ <translation>Дељене фаÑцикле</translation>
</message>
<message>
<source>Description</source>
<comment>details report</comment>
- <translation type="unfinished">ОпиÑ</translation>
+ <translation>ОпиÑ</translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation>&lt;nobr&gt;%1%&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation>Општи драјвер, &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation>Општи драјвер, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</translation>
</message>
</context>
<context>
@@ -770,7 +866,7 @@
</message>
<message>
<source>The download process has been canceled by the user.</source>
- <translation type="unfinished"></translation>
+ <translation>КориÑник је зауÑтавио преузимање.</translation>
</message>
</context>
<context>
@@ -800,7 +896,7 @@
<name>UIDownloaderUserManual</name>
<message>
<source>Select folder to save User Manual to</source>
- <translation type="unfinished"></translation>
+ <translation>Одабрати фаÑциклу где да Ñе Ñачува приручник</translation>
</message>
</context>
<context>
@@ -935,16 +1031,20 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">ХоÑÑ‚ име:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation>Извоз</translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
<message>
<source>Welcome to the Appliance Export Wizard!</source>
- <translation type="unfinished">Добродошли у помоћнику извоза ÑредÑтва!</translation>
+ <translation>Добродошли у помоћнику извоза ÑредÑтва!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will guide you through the process of exporting an appliance.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;Please select the virtual machines that should be added to the appliance. You can select more than one. Please note that these machines have to be turned off before they can be exported.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Овај аÑиÑтент Вам помаже за извоз ÑредÑтва.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;Одаберите машину која треба да Ñе дода у ÑредÑтву. Можете да одаберете више. Машине требају да буду угашене пре него што Ñе извезу.&lt;/p&gt;</translation>
</message>
</context>
<context>
@@ -955,23 +1055,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Appliance Export Settings</source>
- <translation type="unfinished">Параметри извоза ÑаÑтава</translation>
+ <translation>Параметри извоза ÑаÑтава</translation>
</message>
<message>
<source>Please specify the target for the OVF export. You can choose between a local file system export, uploading the OVF to the Sun Cloud service or an S3 storage server.</source>
- <translation type="unfinished">Унети циљ OVF извоза. можете изабрати између локални извоз, Ñлање на OVF „Sun Cloud“ ÑÐµÑ€Ð²Ð¸Ñ Ð¸Ð»Ð¸ на S3 Ñтоварни Ñервер.</translation>
+ <translation>Унети циљ OVF извоза. Можете изабрати између локални извоз, Ñлање на OVF „Sun Cloud“ ÑÐµÑ€Ð²Ð¸Ñ Ð¸Ð»Ð¸ на S3 Ñтоварни Ñервер.</translation>
</message>
<message>
<source>&amp;Local Filesystem </source>
- <translation type="unfinished">Локално</translation>
+ <translation>Локално</translation>
</message>
<message>
<source>Sun &amp;Cloud</source>
- <translation type="unfinished">Sun Cloud</translation>
+ <translation>Sun Cloud</translation>
</message>
<message>
<source>&amp;Simple Storage System (S3)</source>
- <translation type="unfinished">Simple Storage System (S3)</translation>
+ <translation>Simple Storage System (S3)</translation>
</message>
</context>
<context>
@@ -994,71 +1094,71 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Appliance Export Settings</source>
- <translation type="unfinished">Параметри извоза ÑаÑтава</translation>
+ <translation>Параметри извоза ÑаÑтава</translation>
</message>
<message>
<source>&amp;Username:</source>
- <translation type="unfinished">Име:</translation>
+ <translation>Име:</translation>
</message>
<message>
<source>&amp;Password:</source>
- <translation type="unfinished">Лозинка:</translation>
+ <translation>Лозинка:</translation>
</message>
<message>
<source>&amp;Hostname:</source>
- <translation type="unfinished">ХоÑÑ‚ име:</translation>
+ <translation>ХоÑÑ‚ име:</translation>
</message>
<message>
<source>&amp;Bucket:</source>
- <translation type="unfinished">Bucket:</translation>
+ <translation>Кофа:</translation>
</message>
<message>
<source>&amp;File:</source>
- <translation type="unfinished">Датотека:</translation>
+ <translation>Датотека:</translation>
</message>
<message>
<source>Write in legacy OVF 0.9 format for compatibility with other virtualization products.</source>
- <translation type="unfinished">ПиÑати у OVF 0.9 формат за компатибилноÑÑ‚ Ñа другим програмима виртуализације.</translation>
+ <translation>ПиÑати у OVF 0.9 формат за компатибилноÑÑ‚ Ñа другим програмима виртуализације.</translation>
</message>
<message>
<source>&amp;Write legacy OVF 0.9</source>
- <translation type="unfinished">ПиÑати OVF 0.9</translation>
+ <translation>ПиÑати OVF 0.9</translation>
</message>
<message>
<source>Create a Manifest file for automatic data integrity checks on import.</source>
- <translation type="unfinished"></translation>
+ <translation>Креирати „Manifest“ датотеку за аутоматÑку проверу интегритета на увоз.</translation>
</message>
<message>
<source>Write &amp;Manifest file</source>
- <translation type="unfinished"></translation>
+ <translation>Пиши „Manifest“ датотеку</translation>
</message>
<message>
<source>Appliance</source>
- <translation type="unfinished">СредÑтва</translation>
+ <translation>СредÑтва</translation>
</message>
<message>
<source>Select a file to export into</source>
- <translation type="unfinished">Одабрати датотеку за извоз</translation>
+ <translation>Одабрати датотеку за извоз</translation>
</message>
<message>
<source>Open Virtualization Format Archive (%1)</source>
- <translation type="unfinished"></translation>
+ <translation>Open Virtualization Format Archive (%1)</translation>
</message>
<message>
<source>Open Virtualization Format (%1)</source>
- <translation type="unfinished"></translation>
+ <translation>Open Virtualization Format (%1)</translation>
</message>
<message>
<source>Please choose a filename to export the OVF/OVA to. If you use an &lt;i&gt;ova&lt;/i&gt; file name extension, then all the files will be combined into one Open Virtualization Format Archive. If you use an &lt;i&gt;ovf&lt;/i&gt; extension, several files will be written separately. Other extensions are not allowed.</source>
- <translation type="unfinished"></translation>
+ <translation>Одаберите име за извоз у OVF/OVA. Ðко кориÑтите &lt;i&gt;ova&lt;/i&gt; ектензију, онда ће Ñве датотеке да буду комбиноване у једну „Open Virtualization Format“ архиву. Ðко кориÑтите &lt;i&gt;ovf&lt;/i&gt; ектензију, имаћете више датотека. Друге екÑтензије ниÑу дозвољене.</translation>
</message>
<message>
<source>Please complete the additional fields like the username, password and the bucket, and provide a filename for the OVF target.</source>
- <translation type="unfinished">Попунити додатна поља као име, лозинка и букет, и унеÑите датотеку за OVF циљ.</translation>
+ <translation>Попунити додатна поља као име, лозинка и букет, и унеÑите име за OVF циљ.</translation>
</message>
<message>
<source>Please complete the additional fields like the username, password, hostname and the bucket, and provide a filename for the OVF target.</source>
- <translation type="unfinished">Попунити додатна поља као име, лозинка, хоÑÑ‚ име и букет, и унеÑите датотеку за OVF циљ.</translation>
+ <translation>Попунити додатна поља као име, лозинка, име хоÑта и букет, и унеÑите име за OVF циљ.</translation>
</message>
</context>
<context>
@@ -1093,7 +1193,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Appliance Export Settings</source>
- <translation type="unfinished">Параметри извоза ÑаÑтава</translation>
+ <translation>Параметри извоза ÑаÑтава</translation>
</message>
<message>
<source>Appliance</source>
@@ -1117,19 +1217,19 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Checking files ...</source>
- <translation type="unfinished">Провера датотека...</translation>
+ <translation>Провера датотека...</translation>
</message>
<message>
<source>Removing files ...</source>
- <translation type="unfinished">Уклон датотека...</translation>
+ <translation>Уклон датотека...</translation>
</message>
<message>
<source>Exporting Appliance ...</source>
- <translation type="unfinished">Извоз ÑредÑтва...</translation>
+ <translation>Извоз ÑредÑтва...</translation>
</message>
<message>
<source>Here you can change additional configuration values of the selected virtual machines. You can modify most of the properties shown by double-clicking on the items.</source>
- <translation type="unfinished">Овде можете да промените додатне вредноÑти виртуелних машина. Можете променити цечину поÑтавке преко дуплог-клика.</translation>
+ <translation>Овде можете да промените додатне вредноÑти виртуелних машина. Можете променити вечину поÑтавке преко дуплог-клика.</translation>
</message>
</context>
<context>
@@ -1266,154 +1366,123 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;Ðко је ово коректно, ÑтиÑнути &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; .&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation>Почетак</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
<message>
<source>Welcome to the First Run Wizard!</source>
- <translation type="unfinished">Добродошли у аÑиÑтенту првог покретања!</translation>
+ <translation>Добродошли у аÑиÑтенту првог покретања!</translation>
</message>
<message>
<source>&lt;p&gt;You have started a newly created virtual machine for the first time. This wizard will help you to perform the steps necessary for installing an operating system of your choice onto this virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Први пут Ñте покренули нову креирану машину. Овај аÑиÑтент ће Вам помоћи да инÑталирате ÑиÑтем који Ñте изабрали у овој машину.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;You have started a newly created virtual machine for the first time. This wizard will help you to perform the steps necessary for booting an operating system of your choice on the virtual machine.&lt;/p&gt;&lt;p&gt;Note that you will not be able to install an operating system into this virtual machine right now because you did not attach any hard disk to it. If this is not what you want, you can cancel the execution of this wizard, select &lt;b&gt;Settings&lt;/b&gt; from the &lt;b&gt;Machine&lt;/b&gt; menu of the main VirtualBox window to access the settings dialog of this machine and change the hard disk configuration.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Први пут Ñте покренули нову креирану машину. Овај аÑиÑтент ће Вам помоћи да инÑталирате ÑиÑтем који Ñте изабрали у овој машину.&lt;/p&gt;&lt;p&gt;Ðећете моћи да инÑталирате ÑиÑтем одмах пошто ниÑте прикачили хард диÑк. Ðко није то што желите, можете да поништите аÑиÑтент, одабрати &lt;b&gt;Подешавања&lt;/b&gt; Ñа менија &lt;b&gt;Машина&lt;/b&gt; тако да приÑтупите подешавањима машине и да промените конфигурацију хард диÑка.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
</context>
<context>
<name>UIFirstRunWzdPage2</name>
<message>
<source>&lt;p&gt;Select the media which contains the setup program of the operating system you want to install. This media must be bootable, otherwise the setup program will not be able to start.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Одабрати медиј који Ñадржи ÑиÑтем који желите да инÑталирате. Медиј треба да буде бут, инаће програм неће моћи да Ñе покрене.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Одабрати медиј који Ñадржи ÑиÑтем који желите да инÑталирате. Медиј треба да буде бут, инаће програм неће моћи да Ñе покрене.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Select the media that contains the operating system you want to work with. This media must be bootable, otherwise the operating system will not be able to start.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Одабрати медиј који Ñадржи ÑиÑтем Ñа којим желите да радите. Медиј мора да буде бут, или ÑиÑтем неће моћи да Ñтартује.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Одабрати медиј који Ñадржи ÑиÑтем Ñа којим желите да радите. Медиј мора да буде бут, или ÑиÑтем неће моћи да Ñтартује.&lt;/p&gt;</translation>
</message>
<message>
<source>Media Source</source>
- <translation type="unfinished">Изворни медиј</translation>
+ <translation>Изворни медиј</translation>
</message>
<message>
<source>Select Installation Media</source>
- <translation type="unfinished">Одабрати медиј инÑталације</translation>
+ <translation>Одабрати медиј инÑталације</translation>
</message>
</context>
<context>
<name>UIFirstRunWzdPage3</name>
<message>
<source>&lt;p&gt;You have selected the following media to boot from:&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Одабрали Ñте овај медиј за бут:&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Одабрали Ñте овај медиј за бут:&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;You have selected the following media to boot an operating system from:&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Одабрали Ñте овај медиј за подизање ÑиÑтема:&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Одабрали Ñте овај медиј за подизање ÑиÑтема:&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Ðко је ово коректно, ÑтиÑнути &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; .&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Ðко је ово коректно, ÑтиÑнути &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; .&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be mounted on the virtual machine and the machine will start execution.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Ðко је ово коректно, ÑтиÑнути &lt;b&gt;Заврши&lt;/b&gt;. ПоÑле ÑтиÑкања, одабран медиј ће бити монтиран на виртуелну машину и машина ће покренути рад.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Ðко је ово коректно, ÑтиÑнути &lt;b&gt;Заврши&lt;/b&gt;. ПоÑле ÑтиÑкања, одабран медиј ће бити монтиран на виртуелну машину и машина ће покренути рад.&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="unfinished">Резиме</translation>
+ <translation>Резиме</translation>
</message>
<message>
<source>CD/DVD-ROM Device</source>
- <translation type="unfinished">CD/DVD-ROM уређај</translation>
+ <translation>CD/DVD-ROM уређај</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation type="unfinished">Тип</translation>
+ <translation>Тип</translation>
</message>
<message>
<source>Source</source>
<comment>summary</comment>
- <translation type="unfinished">Извор</translation>
- </message>
-</context>
-<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Опште</translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished">УноÑ</translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished">Ðжурирање</translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished">Језик</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Мрежа</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished">VirtualBox - %1</translation>
+ <translation>Извор</translation>
</message>
</context>
<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
- <translation type="unfinished"></translation>
+ <translation>Пакети проширење:</translation>
</message>
<message>
<source>Lists all installed packages.</source>
- <translation type="unfinished"></translation>
+ <translation>СпиÑак инÑталираних проширења.</translation>
</message>
<message>
<source>Active</source>
- <translation type="unfinished"></translation>
+ <translation>Ðктивно</translation>
</message>
<message>
<source>Name</source>
- <translation type="unfinished">Име</translation>
+ <translation>Име</translation>
</message>
<message>
<source>Version</source>
- <translation type="unfinished">Верзија</translation>
+ <translation>Верзија</translation>
</message>
<message>
<source>Add package</source>
- <translation type="unfinished"></translation>
+ <translation>Додај пакет</translation>
</message>
<message>
<source>Remove package</source>
- <translation type="unfinished"></translation>
+ <translation>Уклони пакет</translation>
</message>
<message>
<source>Select an extension package file</source>
- <translation type="unfinished"></translation>
+ <translation>Одабрати пакет проширења</translation>
</message>
<message>
<source>Extension package files (%1)</source>
- <translation type="unfinished"></translation>
+ <translation>Пакет проширења (%1)</translation>
</message>
<message>
<source>Extensions</source>
- <translation type="unfinished"></translation>
+ <translation>Проширења</translation>
</message>
</context>
<context>
@@ -1464,38 +1533,38 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>When checked, the host screen saver will be disabled whenever a virtual machine is running.</source>
- <translation type="unfinished"></translation>
+ <translation>Ðко унето, Ñкрин Ñејвер хоÑта ће бити угашен ако виртуална машина ради.</translation>
</message>
<message>
<source>Disable Host &amp;ScreenSaver</source>
- <translation type="unfinished"></translation>
+ <translation>УгаÑи Ñкрин Ñејвер хоÑта</translation>
</message>
</context>
<context>
<name>UIGlobalSettingsInput</name>
<message>
<source>Host &amp;Key:</source>
- <translation type="unfinished">ХоÑÑ‚ кључ:</translation>
+ <translation>ХоÑÑ‚ кључ:</translation>
</message>
<message>
<source>Displays the key used as a Host Key in the VM window. Activate the entry field and press a new Host Key. Note that alphanumeric, cursor movement and editing keys cannot be used.</source>
- <translation type="unfinished">Показује таÑтер коришћен као ХоÑÑ‚ таÑтер у VM прозору. Ðктивирати поље и ÑтиÑнути нови хоÑÑ‚ таÑтер. Ðлфанумерично, покрете курÑора и таÑтери уређивања не могу да Ñе кориÑте.</translation>
+ <translation>Показује таÑтер коришћен као ХоÑÑ‚ таÑтер у VM прозору. Ðктивирати поље и ÑтиÑнути нови хоÑÑ‚ таÑтер. Ðлфанумерично, покрете курÑора и таÑтери уређивања не могу да Ñе кориÑте.</translation>
</message>
<message>
<source>When checked, the keyboard is automatically captured every time the VM window is activated. When the keyboard is captured, all keystrokes (including system ones like Alt-Tab) are directed to the VM.</source>
- <translation type="unfinished">Ðко унето, таÑтатура је хвачена на Ñвако активирање прозора машине. Сваки ÑƒÐ½Ð¾Ñ Ð¸Ð· таÑтатуре (као и ÑиÑтемÑке Alt-Tab) Ñу преуÑмерене виртуелној машини.</translation>
+ <translation>Ðко унето, таÑтатура је хвачена на Ñвако активирање прозора машине. Сваки ÑƒÐ½Ð¾Ñ Ð¸Ð· таÑтатуре (као и ÑиÑтемÑке Alt-Tab) Ñу преуÑмерене виртуелној машини.</translation>
</message>
<message>
<source>&amp;Auto Capture Keyboard</source>
- <translation type="unfinished">Ðуто-интегриÑање таÑтатуре</translation>
+ <translation>Ðуто-интегриÑање таÑтатуре</translation>
</message>
<message>
<source>Reset host combination</source>
- <translation type="unfinished"></translation>
+ <translation>РеÑетуј комбинацију хоÑта</translation>
</message>
<message>
<source>Resets the key combination used as the host combination in the VM window.</source>
- <translation type="unfinished"></translation>
+ <translation>РеÑетуј комбинацију за хоÑÑ‚ у прозору машине.</translation>
</message>
</context>
<context>
@@ -1699,7 +1768,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Networking</source>
- <translation type="unfinished"></translation>
+ <translation>Мрежање</translation>
</message>
</context>
<context>
@@ -1718,7 +1787,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Use manual configuration for this host-only network adapter.</source>
- <translation>КориÑти ручну конфигурацију</translation>
+ <translation>КориÑти ручну конфигурацију за овог хоÑта Ñамо мрежни адаптер.</translation>
</message>
<message>
<source>&amp;IPv4 Address:</source>
@@ -1798,6 +1867,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation>Када одабрано, VirtualBox ће кориÑтити поÑтаке прокÑија за, на пример, преузимање ГоÑта додатка или провере ажурирања.</translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation>Упали прокÑи</translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation>ХоÑÑ‚:</translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation>Промени прокÑи хоÑта.</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>Порт:</translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation>Промени порт хоÑта.</translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation>Када одабрано, поÑтављена аутентификација ће бити коришћена за прокÑи.</translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation>Употреби аутентификацију</translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation>КориÑник:</translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation>Име за аутентификацију.</translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation>Лозинка:</translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation>Лозинка за аутентификацију.</translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1852,7 +1972,7 @@ p, li { white-space: pre-wrap; }
<name>UIHelpButton</name>
<message>
<source>&amp;Help</source>
- <translation type="unfinished">&amp;Помоћ</translation>
+ <translation>Помоћ</translation>
</message>
</context>
<context>
@@ -1867,23 +1987,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Леви шифт</translation>
+ <translation type="obsolete">Леви шифт</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>ДеÑни шифт</translation>
+ <translation type="obsolete">ДеÑни шифт</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Леви Ctrl</translation>
+ <translation type="obsolete">Леви Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>ДеÑни Ctrl</translation>
+ <translation type="obsolete">ДеÑни Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Леви Alt</translation>
+ <translation type="obsolete">Леви Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -1931,7 +2051,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>None</source>
- <translation type="unfinished">Ðишта</translation>
+ <translation>Ðишта</translation>
</message>
</context>
<context>
@@ -2001,35 +2121,39 @@ p, li { white-space: pre-wrap; }
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;VirtualBox currently supports importing appliances saved in the Open Virtualization Format (OVF). To continue, select the file to import below:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="obsolete">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;p, li { white-space: pre-wrap; }&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;ÐÑиÑтент вам помаже у увозу ÑредÑтва. &lt;/p&gt;&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;КориÑтити &lt;span style=&quot; font-weight:600;&quot;&gt;Даље&lt;/span&gt; за Ñледећи лиÑÑ‚ и &lt;span style=&quot; font-weight:600;&quot;&gt;Ðазад&lt;/span&gt; за предходни лиÑÑ‚.&lt;/p&gt;&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;VirtualBox актуелно подржава увоз ÑредÑтва из Open Virtualization Format (OVF). За наÑтавак, одабрати датотеку за увоз:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation>Увоз</translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
<message>
<source>Select an appliance to import</source>
- <translation type="unfinished">Одабрати ÑредÑтво за увоз</translation>
+ <translation>Одабрати ÑредÑтво за увоз</translation>
</message>
<message>
<source>Open Virtualization Format (%1)</source>
- <translation type="unfinished"></translation>
+ <translation>Отвори Virtualization Format (%1)</translation>
</message>
<message>
<source>Welcome to the Appliance Import Wizard!</source>
- <translation type="unfinished">Добродошли у аÑиÑтенту увоза ÑредÑтва!</translation>
+ <translation>Добродошли у аÑиÑтенту увоза ÑредÑтва!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will guide you through importing an appliance.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;VirtualBox currently supports importing appliances saved in the Open Virtualization Format (OVF). To continue, select the file to import below:&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;ÐÑиÑтент Ð’Ð°Ñ Ð¿Ñ€Ð°Ñ‚Ð¸ кроз увоз ÑредÑтва.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;VirtualBox подржава увоз ÑредÑтва Ñачувана у Open Virtualization формату (OVF). За наÑтавак, одаберите датотеку за увоз:&lt;/p&gt;</translation>
</message>
</context>
<context>
<name>UIImportApplianceWzdPage2</name>
<message>
<source>These are the virtual machines contained in the appliance and the suggested settings of the imported VirtualBox machines. You can change many of the properties shown by double-clicking on the items and disable others using the check boxes below.</source>
- <translation type="unfinished">Ово Ñу виртуелне машине које Ñу у поÑтавке VirtualBox машине. Можете променити пуно поÑтавке Ñа дуплим-кликом на елементе и да онемогучите друге Ñа кутијицом.</translation>
+ <translation>Ово Ñу виртуелне машине које Ñу у поÑтавке VirtualBox машине. Можете променити пуно поÑтавке Ñа дуплим-кликом на елементе и да онемогучите друге Ñа кутијицом.</translation>
</message>
<message>
<source>Appliance Import Settings</source>
- <translation type="unfinished">Параметри увоза ÑредÑтва</translation>
+ <translation>Параметри увоза ÑредÑтва</translation>
</message>
</context>
<context>
@@ -2145,7 +2269,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Показује ÑÑ‚Ð°Ñ‚ÑƒÑ Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ˜Ðµ ове машине:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Показује ÑÑ‚Ð°Ñ‚ÑƒÑ Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ˜Ðµ ове машине:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2162,11 +2286,16 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Indicates whether the Remote Desktop Server is enabled (&lt;img src=:/vrdp_16px.png/&gt;) or not (&lt;img src=:/vrdp_disabled_16px.png/&gt;).</source>
- <translation type="unfinished"></translation>
+ <translation>Показује да ли је Ñервер удаљеног бирао упаљен (&lt;img src=:/vrdp_16px.png/&gt;) или не (&lt;img src=:/vrdp_disabled_16px.png/&gt;).</translation>
</message>
<message>
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;hr&gt;Сервер удаљеног бироа Ñлуша порт %1</translation>
+ </message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation>Индикатори ÑпоÑобноÑти коришћени Ñа Ñтране машине:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</translation>
</message>
</context>
<context>
@@ -2248,7 +2377,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Audio &amp;Controller:</source>
- <translation>Ðудио контролер</translation>
+ <translation>Ðудио контролер:</translation>
</message>
<message>
<source>Selects the type of the virtual sound card. Depending on this value, VirtualBox will provide different audio hardware to the virtual machine.</source>
@@ -2347,27 +2476,31 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Mo&amp;nitor Count:</source>
- <translation type="unfinished"></translation>
+ <translation>Број монитора:</translation>
</message>
<message>
<source>Controls the amount of virtual monitors provided to the virtual machine.</source>
- <translation type="unfinished"></translation>
+ <translation>Контролише број виртуелних монитора дате на машину.</translation>
</message>
<message>
<source>&lt;qt&gt;%1&lt;/qt&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;qt&gt;%1&lt;/qt&gt;</translation>
</message>
<message>
<source>Specifies whether multiple simultaneous connections to the VM are permitted.</source>
- <translation type="unfinished"></translation>
+ <translation>Одређује да ли Ñу могуће више иÑтовремене везе на машини.</translation>
</message>
<message>
<source>&amp;Allow Multiple Connections</source>
- <translation type="unfinished"></translation>
+ <translation>Дозволи више везе</translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation type="unfinished"></translation>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation>имате 3D убрзавање упаљено за рад који кориÑти WDDM драјвер. За макÑималну перформанÑу поÑтавите VRAM гиÑта на макар &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation>имате 2D видео убрзавање упаљено. Пошто је 2D видео убрзавање је подршана Ñамо Ñа тране Windows гоÑта, опција ће бити онемогућена.</translation>
</message>
</context>
<context>
@@ -2600,6 +2733,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Покажи на врх екрана</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation>одабрали Ñте 64-битни ОС. Пошто је гоÑту потребно хардверÑка виртуализација (VT-x/AMD-V), ова ÑпоÑобноÑÑ‚ ће бити омоигучена.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2739,7 +2876,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>одабрати име мређног адаптера за &lt;b&gt;МоÑтни адаптер&lt;/b&gt; или &lt;b&gt;Само-хоÑÑ‚ адаптер&lt;/b&gt; и име мреже &lt;b&gt;интерна мрежа&lt;/b&gt;.</translation>
+ <translation type="obsolete">одабрати име мређног адаптера за &lt;b&gt;МоÑтни адаптер&lt;/b&gt; или &lt;b&gt;Само-хоÑÑ‚ адаптер&lt;/b&gt; и име мреже &lt;b&gt;интерна мрежа&lt;/b&gt;.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -2751,7 +2888,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&amp;Mac Address:</source>
- <translation>Mac адреÑа</translation>
+ <translation>Mac адреÑа:</translation>
</message>
<message>
<source>&amp;Cable connected</source>
@@ -2759,10 +2896,46 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Opens dialog to manage port forwarding rules.</source>
- <translation type="unfinished"></translation>
+ <translation>Отвара дијалог за уређивање проÑлеђивање порта.</translation>
</message>
<message>
<source>&amp;Port Forwarding</source>
+ <translation>ПроÑлеђивање порта</translation>
+ </message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2883,31 +3056,31 @@ p, li { white-space: pre-wrap; }
<name>UIMachineSettingsPortForwardingDlg</name>
<message>
<source>Port Forwarding Rules</source>
- <translation type="unfinished"></translation>
+ <translation>ПроÑлеђивање порта</translation>
</message>
<message>
<source>This table contains a list of port forwarding rules.</source>
- <translation type="unfinished"></translation>
+ <translation>Табела Ñадржи ÑпиÑак правила проÑлеђивања порта.</translation>
</message>
<message>
<source>Insert new rule</source>
- <translation type="unfinished"></translation>
+ <translation>Убаци ново правило</translation>
</message>
<message>
<source>Copy selected rule</source>
- <translation type="unfinished"></translation>
+ <translation>Копирај одабрано правило</translation>
</message>
<message>
<source>Delete selected rule</source>
- <translation type="unfinished"></translation>
+ <translation>Избриши одабрано правило</translation>
</message>
<message>
<source>This button adds new port forwarding rule.</source>
- <translation type="unfinished"></translation>
+ <translation>Дугме додаје ново правило проÑлеђивања порта.</translation>
</message>
<message>
<source>This button deletes selected port forwarding rule.</source>
- <translation type="unfinished"></translation>
+ <translation>Дугме брише одабрано правило проÑлеђивања порта.</translation>
</message>
</context>
<context>
@@ -2990,11 +3163,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Auto-Mount</source>
- <translation type="unfinished"></translation>
+ <translation>Ðуто-монтирај</translation>
</message>
<message>
<source>Yes</source>
- <translation type="unfinished">Да</translation>
+ <translation>Да</translation>
</message>
</context>
<context>
@@ -3037,15 +3210,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>When checked, the guest OS will try to automatically mount the shared folder on startup.</source>
- <translation type="unfinished"></translation>
+ <translation>Када унето, гоÑÑ‚ ће пробати да аутоматÑко монтира на покретање дељену фаÑциклу.</translation>
</message>
<message>
<source>&amp;Auto-mount</source>
- <translation type="unfinished"></translation>
+ <translation>Ðуто-онтирај</translation>
</message>
<message>
<source>If checked, this shared folder will be permanent.</source>
- <translation type="unfinished"></translation>
+ <translation>Ðко унето, дељена фаÑцикла ће бити трајна.</translation>
</message>
</context>
<context>
@@ -3235,7 +3408,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Хард диÑк није одабран за &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">Хард диÑк није одабран за &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3319,7 +3492,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Hard &amp;Disk:</source>
- <translation>Хард диÑк</translation>
+ <translation>Хард диÑк:</translation>
</message>
<message>
<source>&amp;CD/DVD Device:</source>
@@ -3343,7 +3516,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>The Storage Tree can contain several controllers of different types. This machine currently has no controllers.</source>
- <translation>Дрво може да Ñадржи више контролера различитих типа. Ðктуелно машина нема контролера</translation>
+ <translation>Дрво може да Ñадржи више контролера различитих типа. Ðктуелно машина нема контролера.</translation>
</message>
<message>
<source>Attributes</source>
@@ -3359,7 +3532,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&amp;Type:</source>
- <translation>Тип</translation>
+ <translation>Тип:</translation>
</message>
<message>
<source>Selects the sub-type of the storage controller currently selected in the Storage Tree.</source>
@@ -3395,7 +3568,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&amp;Passthrough</source>
- <translation type="unfinished"></translation>
+ <translation>Прођи кроз</translation>
</message>
<message>
<source>Virtual Size:</source>
@@ -3423,43 +3596,43 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Allows to use host I/O caching capabilities.</source>
- <translation type="unfinished"></translation>
+ <translation>Дозволи да Ñе кориÑти I/O могућноÑÑ‚ кеширања хоÑта.</translation>
</message>
<message>
<source>Use host I/O cache</source>
- <translation type="unfinished"></translation>
+ <translation>КориÑти I/O кеш хоÑта</translation>
</message>
<message>
<source>Add SAS Controller</source>
- <translation type="unfinished"></translation>
+ <translation>Додај SAS контролер</translation>
</message>
<message>
<source>SAS Controller</source>
- <translation type="unfinished"></translation>
+ <translation>SAS контролер</translation>
</message>
<message>
<source>Type:</source>
- <translation type="unfinished"></translation>
+ <translation>Тип:</translation>
</message>
<message>
<source>Host Drive</source>
- <translation type="unfinished">Драјв хоÑта</translation>
+ <translation>Драјв хоÑта</translation>
</message>
<message>
<source>Image</source>
- <translation type="unfinished">Слика</translation>
+ <translation>Слика</translation>
</message>
<message>
<source>Choose or create a virtual hard disk file. The virtual machine will see the data in the file as the contents of the virtual hard disk.</source>
- <translation type="unfinished"></translation>
+ <translation>Одабрати или креирати виртуелни хард диÑк. Машине ће видети податке датотеке као Ñадржај виртуелног хард диÑка.</translation>
</message>
<message>
<source>Set up the virtual hard disk</source>
- <translation type="unfinished"></translation>
+ <translation>ПодеÑи виртуални хард диÑк</translation>
</message>
<message>
<source>CD/DVD &amp;Drive:</source>
- <translation type="unfinished"></translation>
+ <translation>CD/DVD драјв:</translation>
</message>
<message>
<source>Choose a virtual CD/DVD disk or a physical drive to use with the virtual drive. The virtual machine will see a disk inserted into the drive with the data in the file or on the disk in the physical drive as its contents.</source>
@@ -3467,11 +3640,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Set up the virtual CD/DVD drive</source>
- <translation type="unfinished"></translation>
+ <translation>ПодеÑи виртуелни CD/DVD драјв</translation>
</message>
<message>
<source>Floppy &amp;Drive:</source>
- <translation type="unfinished"></translation>
+ <translation>Флопи:</translation>
</message>
<message>
<source>Choose a virtual floppy disk or a physical drive to use with the virtual drive. The virtual machine will see a disk inserted into the drive with the data in the file or on the disk in the physical drive as its contents.</source>
@@ -3479,26 +3652,80 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Set up the virtual floppy drive</source>
- <translation type="unfinished"></translation>
+ <translation>ПодеÑи флопи драјв</translation>
</message>
<message>
<source>Create a new hard disk...</source>
- <translation type="unfinished"></translation>
+ <translation>Креирај нов хард диÑк...</translation>
</message>
<message>
<source>Choose a virtual hard disk file...</source>
- <translation type="unfinished"></translation>
+ <translation>Одабрати виртуелну хард диÑк...</translation>
</message>
<message>
<source>Choose a virtual CD/DVD disk file...</source>
- <translation type="unfinished"></translation>
+ <translation>Одабрати виртуелни CD/DVD диÑк...</translation>
</message>
<message>
<source>Remove disk from virtual drive</source>
- <translation type="unfinished"></translation>
+ <translation>Уклони диÑк Ñа виртуелног драјва</translation>
</message>
<message>
<source>Choose a virtual floppy disk file...</source>
+ <translation>Одабрати виртуални флопи диÑк...</translation>
+ </message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -3665,7 +3892,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Hardware clock in &amp;UTC time</source>
- <translation type="unfinished"></translation>
+ <translation>ХардверÑки Ñат у UTC времену</translation>
</message>
<message>
<source>Controls the number of virtual CPUs in the virtual machine. You need hardware virtualization support on your host system to use more than one virtual CPU.</source>
@@ -3681,16 +3908,42 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&amp;Chipset:</source>
- <translation type="unfinished"></translation>
+ <translation>ЧипÑет:</translation>
</message>
<message>
<source>Defines chipset type used in this VM.</source>
- <translation type="unfinished"></translation>
+ <translation>Дефиниши тип чипÑета за машину.</translation>
</message>
<message>
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation>&lt;qt&gt;%1%&lt;/qt&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation>&lt;qt&gt;%1%&lt;/qt&gt;</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3778,45 +4031,45 @@ p, li { white-space: pre-wrap; }
<message>
<source>&lt;nobr&gt;Vendor ID: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished">&lt;nobr&gt; Продавач: %1&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt; Продавач: %1&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Product ID: %2&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished">&lt;nobr&gt;Производ: %2&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt;Производ: %2&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Revision: %3&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished">&lt;nobr&gt;Ревизија: %3&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt;Ревизија: %3&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Product: %4&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished">&lt;nobr&gt;Производ: %4&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt;Производ: %4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Manufacturer: %5&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished">&lt;nobr&gt;Произвођач: %5&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt;Произвођач: %5&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Serial No.: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished">&lt;nobr&gt;Серијал: %1&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt;Серијал: %1&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;Port: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished">&lt;nobr&gt;Порт: %1&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt;Порт: %1&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;nobr&gt;State: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
- <translation type="unfinished">&lt;nobr&gt;СтатуÑ: %1&lt;/nobr&gt;</translation>
+ <translation>&lt;nobr&gt;СтатуÑ: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -3930,52 +4183,67 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
- <translation type="unfinished">Поништи</translation>
+ <translation>Поништи</translation>
</message>
<message>
<source>Cancel the VirtualBox Guest Additions CD image download</source>
- <translation type="unfinished">Поништи преузимање VirtualBox &apos;додатка гоÑта&apos;</translation>
+ <translation>Поништи преузимање VirtualBox „додатка гоÑта“</translation>
</message>
<message>
<source>Downloading the VirtualBox Guest Additions CD image from &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;...&lt;/nobr&gt;</source>
- <translation type="unfinished">Преузимање VirtualBox &apos;додатка гоÑта&apos; Ñа &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;...&lt;/nobr&gt;</translation>
+ <translation>Преузимање VirtualBox „додатка гоÑта“&apos; &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;...&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UIMiniProcessWidgetUserManual</name>
<message>
<source>Cancel</source>
- <translation type="unfinished">Поништи</translation>
+ <translation>Поништи</translation>
</message>
<message>
<source>Cancel the VirtualBox User Manual download</source>
- <translation type="unfinished"></translation>
+ <translation>Поништи преузимање приручника</translation>
</message>
<message>
<source>Downloading the VirtualBox User Manual</source>
- <translation type="unfinished"></translation>
+ <translation>Преузимање приручника</translation>
</message>
<message>
<source>Downloading the VirtualBox User Manual &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;...&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>Преузимање приручника &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;...&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UIMultiScreenLayout</name>
<message>
<source>Virtual Screen %1</source>
- <translation type="unfinished"></translation>
+ <translation>Виртуални екран %1</translation>
</message>
<message>
<source>Use Host Screen %1</source>
- <translation type="unfinished"></translation>
+ <translation>КориÑти хоÑÑ‚ екран %1</translation>
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Креирај нови виртуелни диÑк</translation>
@@ -3990,7 +4258,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Резиме</translation>
+ <translation type="unfinished">Резиме</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4002,7 +4270,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Одабрати Ñлику за нову хард диÑк</translation>
+ <translation type="unfinished">Одабрати Ñлику за нову хард диÑк</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -4024,12 +4292,12 @@ p, li { white-space: pre-wrap; }
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Смештај</translation>
+ <translation type="unfinished">Смештај</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Величина</translation>
+ <translation type="unfinished">Величина</translation>
</message>
<message>
<source>Bytes</source>
@@ -4088,15 +4356,183 @@ p, li { white-space: pre-wrap; }
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Ðко Ñу ови параметри добри, ÑтиÑнути &lt;b&gt;Заврши&lt;/b&gt;. ПоÑле ÑтиÑкања, нови диÑк ће бити креиран.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">Смештај</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">Величина</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation type="unfinished">Добродошли у аÑиÑтенту креирања новог виртуелног диÑка!</translation>
+ <translation type="obsolete">Добродошли у аÑиÑтенту креирања новог виртуелног диÑка!</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <source>Choose a virtual hard disk file...</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -4104,92 +4540,80 @@ p, li { white-space: pre-wrap; }
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Одабрати тип хард дидка који желите да креирате.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Динамична Ñлика&lt;/b&gt; прво заузима мали проÑтор на ваш хард диÑк. Повечаваће Ñе динамично (до унете вредноÑти) док гоÑÑ‚ тражи проÑтор.&lt;/p&gt;&lt;p&gt;&lt;b&gt;ФикÑна Ñлика&lt;/b&gt; не повечава Ñе. Стављено је у датотеци од прилике иÑте величине као виртуелног хард диÑка.Креација фикÑне Ñлике може да потраје у завиÑноÑти величине Ñлике и перформанÑа хард диÑка.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Одабрати тип хард дидка који желите да креирате.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Динамична Ñлика&lt;/b&gt; прво заузима мали проÑтор на ваш хард диÑк. Повечаваће Ñе динамично (до унете вредноÑти) док гоÑÑ‚ тражи проÑтор.&lt;/p&gt;&lt;p&gt;&lt;b&gt;ФикÑна Ñлика&lt;/b&gt; не повечава Ñе. Стављено је у датотеци од прилике иÑте величине као виртуелног хард диÑка.Креација фикÑне Ñлике може да потраје у завиÑноÑти величине Ñлике и перформанÑа хард диÑка.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation type="unfinished">Тип Ñтоваришта</translation>
+ <translation type="obsolete">Тип Ñтоваришта</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation type="unfinished">Динамичан</translation>
+ <translation type="obsolete">Динамичан</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation type="unfinished">ФикÑна величина</translation>
+ <translation type="obsolete">ФикÑна величина</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation type="unfinished">Тип хард диÑка</translation>
+ <translation type="obsolete">Тип хард диÑка</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;СтиÑнути &lt;b&gt;Одабери&lt;/b&gt; за одабирање Ñмештаја датотеке за Ñачувавање хард диÑка или унети име датотеке у поље.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;СтиÑнути &lt;b&gt;Одабери&lt;/b&gt; за одабирање Ñмештаја датотеке за Ñачувавање хард диÑка или унети име датотеке у поље.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation type="unfinished">Смештај</translation>
+ <translation type="obsolete">Смештај</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Одабрати величину виртуелног диÑка у мегабајтима. Клијент ће видети ту величину као макÑималну величину хард диÑка.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Одабрати величину виртуелног диÑка у мегабајтима. Клијент ће видети ту величину као макÑималну величину хард диÑка.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation type="unfinished">Величина</translation>
+ <translation type="obsolete">Величина</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation type="unfinished">Смештај и величина виртуелног диÑка</translation>
+ <translation type="obsolete">Смештај и величина виртуелног диÑка</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="unfinished">Одабрати Ñлику за нову хард диÑк</translation>
+ <translation type="obsolete">Одабрати Ñлику за нову хард диÑк</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation type="unfinished">хард диÑк Ñлике (*.vdi)</translation>
- </message>
- <message>
- <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Хард диÑк Ñлике (*.vdi)</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation type="unfinished">Креирате нов диÑк Ñа овим параметрима:</translation>
+ <translation type="obsolete">Креирате нов диÑк Ñа овим параметрима:</translation>
</message>
<message>
<source>Summary</source>
- <translation type="unfinished">Резиме</translation>
- </message>
- <message>
- <source>%1 B</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Резиме</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation type="unfinished">Тип</translation>
+ <translation type="obsolete">Тип</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="unfinished">Смештај</translation>
+ <translation type="obsolete">Смештај</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="unfinished">Величина</translation>
- </message>
- <message>
- <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Величина</translation>
</message>
</context>
<context>
@@ -4327,58 +4751,62 @@ p, li { white-space: pre-wrap; }
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">КориÑти поÑтојећи хард диÑк</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
<message>
<source>Welcome to the New Virtual Machine Wizard!</source>
- <translation type="unfinished">Добродошли у аÑиÑтенту нове виртуелне машине!</translation>
+ <translation>Добродошли у аÑиÑтенту нове виртуелне машине!</translation>
</message>
<message>
<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 type="unfinished"></translation>
+ <translation>&lt;p&gt;ÐÑиÑтент Вам помаже да креирате нову виртуалну машинуза VirtualBox.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
</context>
<context>
<name>UINewVMWzdPage2</name>
<message>
<source>&lt;p&gt;Enter a name for the new virtual machine and select the type of the guest operating system you plan to install onto the virtual machine.&lt;/p&gt;&lt;p&gt;The name of the virtual machine usually indicates its software and hardware configuration. It will be used by all VirtualBox components to identify your virtual machine.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Унети име за нову виртуелну машину и одабрати тип ОС-а гоÑта који планирате да инÑталирате.&lt;/p&gt;&lt;p&gt;Ðормално име виртуелне машине показује конфигурацију Ñофтвера и хардвера. То ће бити коришћено Ñвим компонентима VirtualBox-а за идентификацију ваше виртуелне машине.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Унети име за нову виртуелну машину и одабрати тип ОС-а гоÑта који планирате да инÑталирате.&lt;/p&gt;&lt;p&gt;Ðормално име виртуелне машине показује конфигурацију Ñофтвера и хардвера. То ће бити коришћено Ñвим компонентима VirtualBox-а за идентификацију ваше виртуелне машине.&lt;/p&gt;</translation>
</message>
<message>
<source>N&amp;ame</source>
- <translation type="unfinished">&amp;Име</translation>
+ <translation>&amp;Име</translation>
</message>
<message>
<source>OS &amp;Type</source>
- <translation type="unfinished">&amp;Тип ОС-а</translation>
+ <translation>&amp;Тип ОС-а</translation>
</message>
<message>
<source>VM Name and OS Type</source>
- <translation type="unfinished">Име и тип ОС-а</translation>
+ <translation>Име и тип ОС-а</translation>
</message>
</context>
<context>
<name>UINewVMWzdPage3</name>
<message>
<source>&lt;p&gt;Select the amount of base memory (RAM) in megabytes to be allocated to the virtual machine.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Одабрати оÑновну меморију (RAM) у мегабајтима за виртуелну машину.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Одабрати оÑновну меморију (RAM) у мегабајтима за виртуелну машину.&lt;/p&gt;</translation>
</message>
<message>
<source>Base &amp;Memory Size</source>
- <translation type="unfinished">&amp;Базна меморија</translation>
+ <translation>ОÑновна меморија</translation>
</message>
<message>
<source>MB</source>
- <translation type="unfinished">МБ</translation>
+ <translation>МБ</translation>
</message>
<message>
<source>Memory</source>
- <translation type="unfinished">Меморија</translation>
+ <translation>Меморија</translation>
</message>
<message>
<source>The recommended base memory size is &lt;b&gt;%1&lt;/b&gt; MB.</source>
- <translation type="unfinished">Препоручена оÑновна меморија је &lt;b&gt;%1&lt;/b&gt; МБ.</translation>
+ <translation>Препоручена оÑновна меморија је &lt;b&gt;%1&lt;/b&gt; МБ.</translation>
</message>
<message>
<source>MB</source>
@@ -4398,15 +4826,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&amp;Create new hard disk</source>
- <translation type="unfinished">Креирај нов хард диÑк</translation>
+ <translation>Креирај нов хард диÑк</translation>
</message>
<message>
<source>&amp;Use existing hard disk</source>
- <translation type="unfinished">КориÑти поÑтојећи хард диÑк</translation>
+ <translation>КориÑти поÑтојећи хард диÑк</translation>
</message>
<message>
<source>Virtual Hard Disk</source>
- <translation type="unfinished">Виртуелни хард диÑк</translation>
+ <translation>Виртуелни хард диÑк</translation>
</message>
<message>
<source>The recommended size of the boot hard disk is &lt;b&gt;%1&lt;/b&gt; MB.</source>
@@ -4414,7 +4842,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Boot Hard &amp;Disk</source>
- <translation type="unfinished"></translation>
+ <translation>ДиÑк бута харда</translation>
</message>
<message>
<source>&lt;p&gt;Select a virtual hard disk to be used as the boot hard disk of the virtual machine. You can either create a new hard disk or select an existing one from the drop-down list or by pressing corresponding button (to invoke file-open window).&lt;/p&gt;&lt;p&gt;If you need a more complicated hard disk setup, you can also skip this step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source>
@@ -4422,37 +4850,37 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Choose a virtual hard disk file...</source>
- <translation type="unfinished"></translation>
+ <translation>Одабрати виртуелни хард диÑк...</translation>
</message>
<message>
<source>The recommended size of the boot hard disk is &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>Препоручена величина диÑка бута је &lt;b&gt;%1&lt;/b&gt;.</translation>
</message>
</context>
<context>
<name>UINewVMWzdPage5</name>
<message>
<source>&lt;p&gt;You are going to create a new virtual machine with the following parameters:&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Креирате нов диÑк Ñа овим параметрима:&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Креирате нов диÑк Ñа овим параметрима:&lt;/p&gt;</translation>
</message>
<message>
<source>Summary</source>
- <translation type="unfinished">Резиме</translation>
+ <translation>Резиме</translation>
</message>
<message>
<source>Name</source>
<comment>summary</comment>
- <translation type="unfinished">Име</translation>
+ <translation>Име</translation>
</message>
<message>
<source>OS Type</source>
<comment>summary</comment>
- <translation type="unfinished">Тип ОЅ-а</translation>
+ <translation>Тип ОЅ-а</translation>
</message>
<message>
<source>Base Memory</source>
<comment>summary</comment>
- <translation type="unfinished">ОÑновна меморија</translation>
+ <translation>ОÑновна меморија</translation>
</message>
<message>
<source>MB</source>
@@ -4462,7 +4890,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Boot Hard Disk</source>
<comment>summary</comment>
- <translation type="unfinished">Хард диÑк бута</translation>
+ <translation>Хард диÑк бута</translation>
</message>
<message>
<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>
@@ -4473,27 +4901,27 @@ p, li { white-space: pre-wrap; }
<name>UIPortForwardingModel</name>
<message>
<source>Name</source>
- <translation type="unfinished">Име</translation>
+ <translation>Име</translation>
</message>
<message>
<source>Protocol</source>
- <translation type="unfinished"></translation>
+ <translation>Протокол</translation>
</message>
<message>
<source>Host IP</source>
- <translation type="unfinished"></translation>
+ <translation>ИП хоÑта</translation>
</message>
<message>
<source>Host Port</source>
- <translation type="unfinished"></translation>
+ <translation>Порт хоÑта</translation>
</message>
<message>
<source>Guest IP</source>
- <translation type="unfinished"></translation>
+ <translation>ИП гоÑта</translation>
</message>
<message>
<source>Guest Port</source>
- <translation type="unfinished"></translation>
+ <translation>Порт гоÑта</translation>
</message>
</context>
<context>
@@ -4585,88 +5013,186 @@ p, li { white-space: pre-wrap; }
<name>UISession</name>
<message>
<source>Install</source>
- <translation type="unfinished"></translation>
+ <translation>ИнÑталирај</translation>
</message>
</context>
<context>
<name>UISettingsDialog</name>
<message>
<source>&lt;i&gt;Select a settings category from the list on the left-hand side and move the mouse over a settings item to get more information.&lt;/i&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;i&gt;Одабрати категорију Ñа леве Ñтране, и померати миш преко поÑтавке да би добили више информације.&lt;/i&gt;</translation>
</message>
<message>
<source>On the &lt;b&gt;%1&lt;/b&gt; page, %2</source>
- <translation type="unfinished">Ðа &lt;b&gt;%1&lt;/b&gt; лиÑÑ‚, %2</translation>
+ <translation>Ðа &lt;b&gt;%1&lt;/b&gt; лиÑÑ‚, %2</translation>
</message>
<message>
<source>Invalid settings detected</source>
- <translation type="unfinished">Ðађени погрешни параметри</translation>
+ <translation>Ðађени погрешни параметри</translation>
</message>
<message>
<source>Non-optimal settings detected</source>
- <translation type="unfinished">Ðажени не оптимални параметри</translation>
+ <translation>Ðађени не оптимални параметри</translation>
</message>
<message>
<source>Settings</source>
- <translation type="unfinished">Параметри</translation>
+ <translation>Параметри</translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Опште</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation type="unfinished">УноÑ</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished">Ðжурирање</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation type="unfinished">Језик</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Мрежа</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation type="unfinished">Проширења</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation type="unfinished">VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Опште</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation type="unfinished">СиÑтем</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation type="unfinished">ДиÑплеј</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation type="unfinished">Стовариште</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished">Ðудио</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Мрежа</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation type="unfinished">Портови</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation type="unfinished">СеријÑки портови</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation type="unfinished">Паралелни портови</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation type="unfinished">Дељене фаÑцикле</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished">%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">одабрали Ñте 64-битни ОС. Пошто је гоÑту потребно хардверÑка виртуализација (VT-x/AMD-V), ова ÑпоÑобноÑÑ‚ ће бити омоигучена.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">имате 2D видео убрзавање упаљено. Пошто је 2D видео убрзавање је подршана Ñамо Ñа тране Windows гоÑта, опција ће бити онемогућена.</translation>
</message>
</context>
<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
- <translation type="unfinished">Затвори виртуелну машину</translation>
+ <translation>Затвори виртуелну машину</translation>
</message>
<message>
<source>You want to:</source>
- <translation type="unfinished">Желите да:</translation>
+ <translation>Желите да:</translation>
</message>
<message>
<source>&lt;p&gt;Saves the current execution state of the virtual machine to the physical hard disk of the host PC.&lt;/p&gt;&lt;p&gt;Next time this machine is started, it will be restored from the saved state and continue execution from the same place you saved it at, which will let you continue your work immediately.&lt;/p&gt;&lt;p&gt;Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Сачувава ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð°Ð¸Ð½Ðµ на хард диÑку хоÑта.&lt;/p&gt;&lt;p&gt;Ðа Ñледеће покретање ове машине, биће врачена Ñа Ñачуваног ÑтатуÑа и наÑтавиће одакле је Ñачувано, што вам омогучаа да одмах наÑтавите ваш рад.&lt;/p&gt;&lt;p&gt;Сачувавање машине може да потраје, у завиÑноÑти хоÑÑ‚ ÑиÑтема и меморије виртуелне машине.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Сачувава ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð°Ð¸Ð½Ðµ на хард диÑку хоÑта.&lt;/p&gt;&lt;p&gt;Ðа Ñледеће покретање ове машине, биће врачена Ñа Ñачуваног ÑтатуÑа и наÑтавиће одакле је Ñачувано, што вам омогучаа да одмах наÑтавите ваш рад.&lt;/p&gt;&lt;p&gt;Сачувавање машине може да потраје, у завиÑноÑти хоÑÑ‚ ÑиÑтема и меморије виртуелне машине.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Save the machine state</source>
- <translation type="unfinished">&amp;Сачувај ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð°ÑˆÐ¸Ð½Ðµ</translation>
+ <translation>Сачувај ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð°ÑˆÐ¸Ð½Ðµ</translation>
</message>
<message>
<source>&lt;p&gt;Sends the ACPI Power Button press event to the virtual machine.&lt;/p&gt;&lt;p&gt;Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.&lt;/p&gt;&lt;p&gt;If the machine doesn&apos;t respond to this action then the guest operating system may be misconfigured or doesn&apos;t understand ACPI Power Button events at all. In this case you should select the &lt;b&gt;Power off the machine&lt;/b&gt; action to stop virtual machine execution.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Шаље ÑтиÑкање ACPI дугмета гашења машини.&lt;/p&gt;&lt;p&gt;Ðормално, гоÑÑ‚ ÑиÑтем из виртуелне машине ће видети догађај и добро Ñе угаÑити. То је препоручен наћин за гашење машине, пошто Ñви програми имају могућноÑÑ‚ да Ñачувају податке и ÑтатуÑ.&lt;/p&gt;&lt;p&gt;Ðко машина не одговара на ову акцију, онда гоÑÑ‚ није добро подешен или не разуме тај ACPI догађај. У том Ñлучају, тебате да одаберете акцију &lt;b&gt;УгаÑи машину&lt;/b&gt;.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Шаље ÑтиÑкање ACPI дугмета гашења машини.&lt;/p&gt;&lt;p&gt;Ðормално, гоÑÑ‚ ÑиÑтем из виртуелне машине ће видети догађај и добро Ñе угаÑити. То је препоручен наћин за гашење машине, пошто Ñви програми имају могућноÑÑ‚ да Ñачувају податке и ÑтатуÑ.&lt;/p&gt;&lt;p&gt;Ðко машина не одговара на ову акцију, онда гоÑÑ‚ није добро подешен или не разуме тај ACPI догађај. У том Ñлучају, тебате да одаберете акцију &lt;b&gt;УгаÑи машину&lt;/b&gt;.&lt;/p&gt;</translation>
</message>
<message>
<source>S&amp;end the shutdown signal</source>
- <translation type="unfinished">По&amp;шаљи Ñигнал гашења</translation>
+ <translation>Пошаљи Ñигнал гашења</translation>
</message>
<message>
<source>&lt;p&gt;Turns off the virtual machine.&lt;/p&gt;&lt;p&gt;Note that this action will stop machine execution immediately so that the guest operating system running inside it will not be able to perform a clean shutdown procedure which may result in &lt;i&gt;data loss&lt;/i&gt; inside the virtual machine. Selecting this action is recommended only if the virtual machine does not respond to the &lt;b&gt;Send the shutdown signal&lt;/b&gt; action.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;ГаÑи виртуелну машину.&lt;/p&gt;&lt;p&gt;То ће одмах зауÑтавити рад машине тако да гоÑÑ‚ ÑиÑтем на може да Ñе лепо угаÑи што може довеÑти до &lt;i&gt;губљења података&lt;/i&gt; унутар виртуелне машине. Ова акција је препоручена Ñамо ако машина не одговара на акцију &lt;b&gt;Пошаљи Ñигнал гашења&lt;/b&gt;.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;ГаÑи виртуелну машину.&lt;/p&gt;&lt;p&gt;То ће одмах зауÑтавити рад машине тако да гоÑÑ‚ ÑиÑтем на може да Ñе лепо угаÑи што може довеÑти до &lt;i&gt;губљења података&lt;/i&gt; унутар виртуелне машине. Ова акција је препоручена Ñамо ако машина не одговара на акцију &lt;b&gt;Пошаљи Ñигнал гашења&lt;/b&gt;.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Power off the machine</source>
- <translation type="unfinished">&amp;УгаÑи машину</translation>
+ <translation>УгаÑи машину</translation>
</message>
<message>
<source>Restore the machine state stored in the current snapshot</source>
- <translation type="unfinished">Врача ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð°ÑˆÐ¸Ð½Ðµ из актуелне Ñлике</translation>
+ <translation>Врача ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð°ÑˆÐ¸Ð½Ðµ из актуелне Ñлике</translation>
</message>
<message>
<source>&lt;p&gt;When checked, the machine will be returned to the state stored in the current snapshot after it is turned off. This is useful if you are sure that you want to discard the results of your last sessions and start again at that snapshot.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Ðко унето, ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð°ÑˆÐ¸Ð½Ðµ ће бити врачен као из Ñлике одмах поÑле гашења. КориÑно ако Ñте Ñигурни да одбаците промене задње ÑеÑије и да Ñе вратите на актуелни Ñнимак.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Ðко унето, ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð°ÑˆÐ¸Ð½Ðµ ће бити врачен као из Ñлике одмах поÑле гашења. КориÑно ако Ñте Ñигурни да одбаците промене задње ÑеÑије и да Ñе вратите на актуелни Ñнимак.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Restore current snapshot &apos;%1&apos;</source>
- <translation type="unfinished">Врати актуелну Ñлику &apos;%1&apos;</translation>
+ <translation>Врати актуелну Ñлику &apos;%1&apos;</translation>
</message>
</context>
<context>
<name>UIVMDesktop</name>
<message>
<source>&amp;Details</source>
- <translation type="unfinished"></translation>
+ <translation>Детаљи</translation>
</message>
<message>
<source>&amp;Snapshots</source>
- <translation type="unfinished">&amp;Снимци</translation>
+ <translation>Снимци</translation>
</message>
</context>
<context>
@@ -4722,27 +5248,27 @@ p, li { white-space: pre-wrap; }
<name>UIVMPreviewWindow</name>
<message>
<source>Update Disabled</source>
- <translation type="unfinished"></translation>
+ <translation>Ðжурирање угашено</translation>
</message>
<message>
<source>Every 0.5 s</source>
- <translation type="unfinished"></translation>
+ <translation>Свака 0.5 Ñ</translation>
</message>
<message>
<source>Every 1 s</source>
- <translation type="unfinished"></translation>
+ <translation>Сваки Ñекунд</translation>
</message>
<message>
<source>Every 2 s</source>
- <translation type="unfinished"></translation>
+ <translation>Свака 2 Ñ</translation>
</message>
<message>
<source>Every 5 s</source>
- <translation type="unfinished"></translation>
+ <translation>Сваке 5 Ñ</translation>
</message>
<message>
<source>Every 10 s</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Сваке 5 Ñ {10 ?}</translation>
</message>
<message>
<source>No Preview</source>
@@ -4750,81 +5276,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Опште</translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished">СиÑтем</translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished">ДиÑплеј</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished">Стовариште</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished">Ðудио</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">Мрежа</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished">Портови</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished">СеријÑки портови</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished">Паралелни портови</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished">Дељене фаÑцикле</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished">%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished">одабрали Ñте 64-битни ОС. Пошто је гоÑту потребно хардверÑка виртуализација (VT-x/AMD-V), ова ÑпоÑобноÑÑ‚ ће бити омоигучена.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished">имате 2D видео убрзавање упаљено. Пошто је 2D видео убрзавање је подршана Ñамо Ñа тране Windows гоÑта, опција ће бити онемогућена.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -4982,6 +5433,14 @@ p, li { white-space: pre-wrap; }
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished">Када одабрано, јединÑтвена MAC адреÑа ће бити поÑтављена за Ñве мрежне каре.</translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished">Иницијализација MAC адреÑе за ве мређне карте</translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -6377,7 +6836,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Ðдаптер %1</translation>
+ <translation type="obsolete">Ðдаптер %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -6820,12 +7279,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Screens</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
+ <translation>Екрани</translation>
</message>
<message>
<source>SAS</source>
@@ -6833,120 +7287,115 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
- <translation type="unfinished"></translation>
+ <translation>LsiLogic SAS</translation>
</message>
<message>
<source>B</source>
<comment>size suffix Bytes</comment>
- <translation type="unfinished"></translation>
+ <translation>Б</translation>
</message>
<message>
<source>KB</source>
<comment>size suffix KBytes=1024 Bytes</comment>
- <translation type="unfinished"></translation>
+ <translation>КБ</translation>
</message>
<message>
<source>MB</source>
<comment>size suffix MBytes=1024 KBytes</comment>
- <translation type="unfinished">МБ</translation>
+ <translation>МБ</translation>
</message>
<message>
<source>GB</source>
<comment>size suffix GBytes=1024 MBytes</comment>
- <translation type="unfinished"></translation>
+ <translation>ГБ</translation>
</message>
<message>
<source>TB</source>
<comment>size suffix TBytes=1024 GBytes</comment>
- <translation type="unfinished"></translation>
+ <translation>ТБ</translation>
</message>
<message>
<source>PB</source>
<comment>size suffix PBytes=1024 TBytes</comment>
- <translation type="unfinished"></translation>
+ <translation>ПБ</translation>
</message>
<message>
<source>Enabled</source>
<comment>nested paging</comment>
- <translation type="unfinished"></translation>
+ <translation>Упаљено</translation>
</message>
<message>
<source>Disabled</source>
<comment>nested paging</comment>
- <translation type="unfinished"></translation>
+ <translation>Онемогућено</translation>
</message>
<message>
<source>Nested Paging</source>
- <translation type="unfinished">Подметнуто запиÑивање</translation>
+ <translation>Подметнуто запиÑивање</translation>
</message>
<message>
<source>Shareable</source>
<comment>DiskType</comment>
- <translation type="unfinished"></translation>
+ <translation>Дељиво</translation>
</message>
<message>
<source>Unknown device</source>
<comment>USB device details</comment>
- <translation type="unfinished"></translation>
+ <translation>Ðепознат уређај</translation>
</message>
<message>
<source>SAS Port %1</source>
<comment>New Storage UI : Slot Name</comment>
- <translation type="unfinished"></translation>
+ <translation>SAS порт %1</translation>
</message>
<message>
<source>Remote Desktop Server Port</source>
<comment>details report (VRDE Server)</comment>
- <translation type="unfinished"></translation>
+ <translation>Порт Ñервера удаљеног бироа</translation>
</message>
<message>
<source>Remote Desktop Server</source>
<comment>details report (VRDE Server)</comment>
- <translation type="unfinished"></translation>
+ <translation>Сервер удаљеног бироа</translation>
</message>
<message>
<source>Disabled</source>
<comment>details report (VRDE Server)</comment>
- <translation type="unfinished"></translation>
+ <translation>Онемогућено</translation>
</message>
<message>
<source>Choose a virtual hard disk file</source>
- <translation type="unfinished"></translation>
+ <translation>Одабрати виртуелну хард диÑк</translation>
</message>
<message>
<source>hard disk</source>
- <translation type="unfinished">хард диÑк</translation>
+ <translation>хард диÑк</translation>
</message>
<message>
<source>Choose a virtual CD/DVD disk file</source>
- <translation type="unfinished"></translation>
+ <translation>Одабрати виртуелни CD/DVD диÑк</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
- <translation type="unfinished"></translation>
+ <translation>CD/DVD-ROM диÑк</translation>
</message>
<message>
<source>Choose a virtual floppy disk file</source>
- <translation type="unfinished"></translation>
+ <translation>Одабрати виртуални флопи диÑк</translation>
</message>
<message>
<source>floppy disk</source>
- <translation type="unfinished"></translation>
+ <translation>Флопи уређај</translation>
</message>
<message>
<source>All %1 images (%2)</source>
- <translation type="unfinished"></translation>
+ <translation>Све %1 Ñлике (%2)</translation>
</message>
<message>
<source>All files (*)</source>
- <translation type="unfinished">Све датотеке (*)</translation>
+ <translation>Све датотеке (*)</translation>
</message>
<message>
<source>Fault Tolerant Syncing</source>
@@ -6956,77 +7405,132 @@ p, li { white-space: pre-wrap; }
<message>
<source>Unlocked</source>
<comment>SessionState</comment>
- <translation type="unfinished"></translation>
+ <translation>Деблокирано</translation>
</message>
<message>
<source>Locked</source>
<comment>SessionState</comment>
- <translation type="unfinished"></translation>
+ <translation>Блокирано</translation>
</message>
<message>
<source>Unlocking</source>
<comment>SessionState</comment>
- <translation type="unfinished"></translation>
+ <translation>Деблокирање</translation>
</message>
<message>
<source>Null</source>
<comment>AuthType</comment>
- <translation type="unfinished">Празно</translation>
+ <translation>Празно</translation>
</message>
<message>
<source>External</source>
<comment>AuthType</comment>
- <translation type="unfinished">Спољно</translation>
+ <translation>Спољно</translation>
</message>
<message>
<source>Guest</source>
<comment>AuthType</comment>
- <translation type="unfinished">ГоÑÑ‚</translation>
+ <translation>ГоÑÑ‚</translation>
</message>
<message>
<source>Intel HD Audio</source>
<comment>AudioControllerType</comment>
- <translation type="unfinished"></translation>
+ <translation>Intel HD аудио</translation>
</message>
<message>
<source>UDP</source>
<comment>NATProtocolType</comment>
- <translation type="unfinished"></translation>
+ <translation>UDP</translation>
</message>
<message>
<source>TCP</source>
<comment>NATProtocolType</comment>
- <translation type="unfinished"></translation>
+ <translation>TCP</translation>
</message>
<message>
<source>PIIX3</source>
<comment>ChipsetType</comment>
- <translation type="unfinished">PIIX3</translation>
+ <translation>PIIX3</translation>
</message>
<message>
<source>ICH9</source>
<comment>ChipsetType</comment>
- <translation type="unfinished">ICH9</translation>
+ <translation>ICH9</translation>
</message>
<message>
<source>and</source>
- <translation type="unfinished"></translation>
+ <translation>и</translation>
</message>
<message>
<source>MB</source>
<comment>size suffix MBytes=1024KBytes</comment>
- <translation type="unfinished">МБ</translation>
+ <translation>МБ</translation>
</message>
<message>
<source>Readonly</source>
<comment>DiskType</comment>
- <translation type="unfinished"></translation>
+ <translation>СамоЧитљиво</translation>
</message>
<message>
<source>Multi-attach</source>
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished">&lt;nobr&gt;%1%&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Ðдаптер %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7044,7 +7548,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&apos;%1&apos; is an invalid host-combination code-sequence.</source>
- <translation type="unfinished"></translation>
+ <translation>&apos;%1&apos; није добра хоÑÑ‚ комбинација.</translation>
</message>
</context>
<context>
@@ -7189,15 +7693,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Location</source>
- <translation>Смештај</translation>
+ <translation type="obsolete">Смештај</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Тип (Формат)</translation>
+ <translation type="obsolete">Тип (Формат)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Привезан на</translation>
+ <translation type="obsolete">Привезан на</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -7279,32 +7783,72 @@ p, li { white-space: pre-wrap; }
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Привезано на</translation>
+ <translation type="obsolete">Привезано на</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Привезано на</translation>
+ <translation type="obsolete">Привезано на</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Привезано на</translation>
+ <translation type="obsolete">Привезано на</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
- <translation type="unfinished"></translation>
+ <translation>CD/DVD-ROM диÑк</translation>
</message>
<message>
<source>hard disk</source>
- <translation type="unfinished">хард диÑк</translation>
+ <translation>хард диÑк</translation>
</message>
<message>
<source>floppy disk</source>
- <translation type="unfinished"></translation>
+ <translation>флопи диÑк</translation>
</message>
<message>
<source>All %1 images (%2)</source>
+ <translation type="unfinished">Све %1 Ñлике (%2)</translation>
+ </message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Тип:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Смештај:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -7324,7 +7868,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Minimize Window</source>
- <translation type="unfinished"></translation>
+ <translation>Умањи прозор</translation>
</message>
</context>
<context>
@@ -7366,7 +7910,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Мрежни адаптери</translation>
+ <translation type="obsolete">Мрежни адаптери</translation>
</message>
</context>
<context>
@@ -8060,7 +8604,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Ðе можете да приÑтупите USB на хоÑту, пошто ни USB ÑиÑтем (usbfs) ни DBus ниÑу доÑтупни. Ðко желите да кориÑтите USB уређаје, требате да то поправите и да поново покренете VirtualBox.</translation>
+ <translation type="obsolete">Ðе можете да приÑтупите USB на хоÑту, пошто ни USB ÑиÑтем (usbfs) ни DBus ниÑу доÑтупни. Ðко желите да кориÑтите USB уређаје, требате да то поправите и да поново покренете VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -8181,7 +8725,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Сигурно вратити Ñлику &lt;b&gt;%1&lt;/b&gt;? То доводо до губљења актуелног ÑтатуÑа машине, што не може да Ñе поврати.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Сигурно вратити Ñлику &lt;b&gt;%1&lt;/b&gt;? То доводо до губљења актуелног ÑтатуÑа машине, што не може да Ñе поврати.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -8369,11 +8913,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Failed to add virtual machine &lt;b&gt;%1&lt;/b&gt; located in &lt;i&gt;%2&lt;/i&gt; because its already present.</source>
- <translation type="unfinished"></translation>
+ <translation>ÐеуÑпешно додавање машине &lt;b&gt;%1&lt;/b&gt; из &lt;i&gt;%2&lt;/i&gt; пошто је већ приÑутна.</translation>
</message>
<message>
<source>&lt;p&gt;You are about to remove the virtual machine &lt;b&gt;%1&lt;/b&gt; from the machine list.&lt;/p&gt;&lt;p&gt;Would you like to delete the files containing the virtual machine from your hard disk as well?&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;p&gt;Спремате Ñе да уклоните машину &lt;b&gt;%1&lt;/b&gt; Ñа ÑпиÑка.&lt;/p&gt;&lt;p&gt;Да ли желите иÑто да обришете Ñа хард диÑка датотеку која Ñадржава виртуалну машину?&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;You are about to remove the virtual machine &lt;b&gt;%1&lt;/b&gt; from the machine list.&lt;/p&gt;&lt;p&gt;Would you like to delete the files containing the virtual machine from your hard disk as well? Doing this will also remove the files containing the machine&apos;s virtual hard disks if they are not in use by another machine.&lt;/p&gt;</source>
@@ -8385,15 +8929,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Remove only</source>
- <translation type="unfinished"></translation>
+ <translation>Уклони Ñамо</translation>
</message>
<message>
<source>You are about to remove the inaccessible virtual machine &lt;b&gt;%1&lt;/b&gt; from the machine list. Do you wish to proceed?</source>
- <translation type="unfinished"></translation>
+ <translation>Спремате Ñе да уклоните недоÑтупно машину &lt;b&gt;%1&lt;/b&gt; Ñа ÑпиÑка. Да ли да Ñе наÑтави?</translation>
</message>
<message>
<source>Remove</source>
- <translation type="unfinished">Скини</translation>
+ <translation>Скини</translation>
</message>
<message>
<source>&lt;p&gt;You are about to add a virtual hard disk to controller &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Would you like to create a new, empty file to hold the disk contents or select an existing one?&lt;/p&gt;</source>
@@ -8402,12 +8946,12 @@ p, li { white-space: pre-wrap; }
<message>
<source>Create &amp;new disk</source>
<comment>add attachment routine</comment>
- <translation type="unfinished"></translation>
+ <translation>Креирај нов диÑк</translation>
</message>
<message>
<source>&amp;Choose existing disk</source>
<comment>add attachment routine</comment>
- <translation type="unfinished"></translation>
+ <translation>Одабери поÑтојећи диÑк</translation>
</message>
<message>
<source>&lt;p&gt;You are about to add a new CD/DVD drive to controller &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Would you like to choose a virtual CD/DVD disk to put in the drive or to leave it empty for now?&lt;/p&gt;</source>
@@ -8416,12 +8960,12 @@ p, li { white-space: pre-wrap; }
<message>
<source>&amp;Choose disk</source>
<comment>add attachment routine</comment>
- <translation type="unfinished"></translation>
+ <translation>Одабери диÑк</translation>
</message>
<message>
<source>Leave &amp;empty</source>
<comment>add attachment routine</comment>
- <translation type="unfinished"></translation>
+ <translation>ОÑтави празно</translation>
</message>
<message>
<source>&lt;p&gt;You are about to add a new floppy drive to controller &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Would you like to choose a virtual floppy disk to put in the drive or to leave it empty for now?&lt;/p&gt;</source>
@@ -8429,15 +8973,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Failed to detach the hard disk (&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;) from the slot &lt;i&gt;%2&lt;/i&gt; of the machine &lt;b&gt;%3&lt;/b&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>ÐеуÑпешан одвој хард диÑка (&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;) Ñа Ñлота &lt;i&gt;%2&lt;/i&gt; од машине &lt;b&gt;%3&lt;/b&gt;.</translation>
</message>
<message>
<source>Failed to detach the CD/DVD device (&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;) from the slot &lt;i&gt;%2&lt;/i&gt; of the machine &lt;b&gt;%3&lt;/b&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>ÐеуÑпешан одвој CD/DVD уређаја (&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;) Ñа Ñлота &lt;i&gt;%2&lt;/i&gt; од машине &lt;b&gt;%3&lt;/b&gt;.</translation>
</message>
<message>
<source>Failed to detach the floppy device (&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;) from the slot &lt;i&gt;%2&lt;/i&gt; of the machine &lt;b&gt;%3&lt;/b&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>ÐеуÑпешан одвој флопи уређаја (&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;) Ñа Ñлота &lt;i&gt;%2&lt;/i&gt; од машине &lt;b&gt;%3&lt;/b&gt;.</translation>
</message>
<message numerus="yes">
<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>
@@ -8449,19 +8993,19 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Failed to update Guest Additions. The Guest Additions installation image will be mounted to provide a manual installation.</source>
- <translation type="unfinished"></translation>
+ <translation>Погрешно ажурирање „дадаци гоÑта“. Слика „додатка гоÑта“ ће бити монтирана тако да можете да урадите ручну инÑталацију.</translation>
</message>
<message>
<source>Failed to install the Extension Pack &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>Погрешна инÑталација пакета &lt;b&gt;%1&lt;/b&gt;.</translation>
</message>
<message>
<source>Failed to uninstall the Extension Pack &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>Погрешна деинÑталација пакет &lt;b&gt;%1&lt;/b&gt;.</translation>
</message>
<message>
<source>&amp;Remove</source>
- <translation type="unfinished">Уклони</translation>
+ <translation>Уклони</translation>
</message>
<message>
<source>The current port forwarding rules are not valid. None of the host or guest port values may be set to zero.</source>
@@ -8506,11 +9050,11 @@ p, li { white-space: pre-wrap; }
<message>
<source>Switch</source>
<comment>scale</comment>
- <translation type="unfinished">Пребаци</translation>
+ <translation>Пребаци</translation>
</message>
<message>
<source>Failed to open the Extension Pack &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation type="unfinished"></translation>
+ <translation>Погрешно отварање пакета &lt;b&gt;%1&lt;/b&gt;.</translation>
</message>
<message>
<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>
@@ -8518,7 +9062,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&amp;Install</source>
- <translation type="unfinished"></translation>
+ <translation>ИнÑталирај</translation>
</message>
<message>
<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>
@@ -8530,7 +9074,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&amp;Upgrade</source>
- <translation type="unfinished"></translation>
+ <translation>Ðжурирај</translation>
</message>
<message>
<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>
@@ -8538,7 +9082,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&amp;Downgrade</source>
- <translation type="unfinished"></translation>
+ <translation>Понижи</translation>
</message>
<message>
<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>
@@ -8546,26 +9090,86 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&amp;Reinstall</source>
- <translation type="unfinished"></translation>
+ <translation>Поново инÑталирај</translation>
</message>
<message>
<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 type="unfinished"></translation>
+ <translation>&lt;p&gt;Спремате Ñе да уклоните пакет &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Сигруно да Ñе наÑтави?&lt;/p&gt;</translation>
</message>
<message>
<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>
+ <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 type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
- <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -8680,7 +9284,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Дељене фаÑцикле</translation>
+ <translation type="obsolete">Дељене фаÑцикле</translation>
</message>
</context>
<context>
@@ -8691,11 +9295,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Click to view non-scaled screenshot.</source>
- <translation>Кликнути за преглед без зума Ñлике</translation>
+ <translation>Кликнути за преглед без зума Ñлике.</translation>
</message>
<message>
<source>Click to view scaled screenshot.</source>
- <translation>Кликнути за преглед Ñлике Ñа зумом</translation>
+ <translation>Кликнути за преглед Ñлике Ñа зумом.</translation>
</message>
</context>
<context>
@@ -8751,7 +9355,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>D&amp;iscard</source>
- <translation>О&amp;дбаци</translation>
+ <translation type="obsolete">О&amp;дбаци</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -8873,90 +9477,106 @@ p, li { white-space: pre-wrap; }
<message>
<source>&amp;File</source>
<comment>Mac OS X version</comment>
- <translation type="unfinished">&amp;Датотека</translation>
+ <translation>Датотека</translation>
</message>
<message>
<source>&amp;File</source>
<comment>Non Mac OS X version</comment>
- <translation type="unfinished">&amp;Датотека</translation>
+ <translation>Датотека</translation>
</message>
<message>
<source>Select a virtual machine file</source>
- <translation type="unfinished"></translation>
+ <translation>Одабрати машину</translation>
</message>
<message>
<source>Virtual machine files (%1)</source>
- <translation type="unfinished"></translation>
+ <translation>Машина (%1)</translation>
</message>
<message>
<source>Manager</source>
<comment>Note: main window title which is pretended by the product name.</comment>
- <translation type="unfinished"></translation>
+ <translation>Уреди</translation>
</message>
<message>
<source>&amp;Add...</source>
- <translation type="unfinished">&amp;Додај...</translation>
+ <translation>Додај...</translation>
</message>
<message>
<source>Add an existing virtual machine</source>
- <translation type="unfinished"></translation>
+ <translation>Додај поÑтојећу машину</translation>
</message>
<message>
<source>&amp;Remove</source>
- <translation type="unfinished">Уклони</translation>
+ <translation>Уклони</translation>
</message>
<message>
<source>Remove the selected virtual machine</source>
- <translation type="unfinished"></translation>
+ <translation>Уклони машину</translation>
</message>
<message>
<source>Show in Finder</source>
- <translation type="unfinished"></translation>
+ <translation>Покажи у налазач</translation>
</message>
<message>
<source>Show the VirtualBox Machine Definition file in Finder.</source>
- <translation type="unfinished"></translation>
+ <translation>Покажи Ð¾Ð¿Ð¸Ñ Ð¼Ð°ÑˆÐ¸Ð½Ñƒ у налазач.</translation>
</message>
<message>
<source>Create Alias on Desktop</source>
- <translation type="unfinished"></translation>
+ <translation>Креирај „звани“ на декÑтопу</translation>
</message>
<message>
<source>Creates an Alias file to the VirtualBox Machine Definition file on your Desktop.</source>
- <translation type="unfinished"></translation>
+ <translation>Креирај „звану датотеку“ машине на деÑктопу.</translation>
</message>
<message>
<source>Show in Explorer</source>
- <translation type="unfinished"></translation>
+ <translation>Прикажи у Explorer</translation>
</message>
<message>
<source>Show the VirtualBox Machine Definition file in Explorer.</source>
- <translation type="unfinished"></translation>
+ <translation>Покажи Ð¾Ð¿Ð¸Ñ Ð¼Ð°ÑˆÐ¸Ð½Ðµ у Explorer.</translation>
</message>
<message>
<source>Create Shortcut on Desktop</source>
- <translation type="unfinished"></translation>
+ <translation>Креирај пречицу на деÑктопу</translation>
</message>
<message>
<source>Creates an Shortcut file to the VirtualBox Machine Definition file on your Desktop.</source>
- <translation type="unfinished"></translation>
+ <translation>Креирај пречицу од опиÑа машине на деÑктопу.</translation>
</message>
<message>
<source>Show in File Manager</source>
- <translation type="unfinished"></translation>
+ <translation>Прикажи у Менаџер датотеке</translation>
</message>
<message>
<source>Show the VirtualBox Machine Definition file in the File Manager</source>
- <translation type="unfinished"></translation>
+ <translation>Прикажи Ð¾Ð¿Ð¸Ñ Ð¼Ð°ÑˆÐ¸Ð½Ðµ у Менаџеру датотеке</translation>
</message>
<message>
<source>Show Toolbar</source>
- <translation type="unfinished"></translation>
+ <translation>Прикажи траку</translation>
</message>
<message>
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished">Одбаци</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -9009,7 +9629,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Click to enlarge the screenshot.</source>
- <translation>Кликнути за увеличавање Ñлике</translation>
+ <translation>Кликнути за увеличавање Ñлике.</translation>
</message>
<message>
<source>&amp;Name:</source>
@@ -9017,15 +9637,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Taken:</source>
- <translation>Узето</translation>
+ <translation>Узето:</translation>
</message>
<message>
<source>&amp;Description:</source>
- <translation>ОпиÑ</translation>
+ <translation>ОпиÑ:</translation>
</message>
<message>
<source>D&amp;etails:</source>
- <translation>Детаљи</translation>
+ <translation>Детаљи:</translation>
</message>
</context>
<context>
@@ -9154,6 +9774,14 @@ p, li { white-space: pre-wrap; }
<source> (%1 ago)</source>
<translation> (пре %1)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sv.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sv.ts
index 20d2d647c..c8a441a15 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sv.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sv.ts
@@ -291,7 +291,7 @@
</message>
<message>
<source>&amp;Insert Ctrl-Alt-Del</source>
- <translation>&amp;Infoga Ctrl-Alt-Del</translation>
+ <translation>In&amp;foga Ctrl-Alt-Del</translation>
</message>
<message>
<source>Send the Ctrl-Alt-Del sequence to the virtual machine</source>
@@ -347,7 +347,7 @@
</message>
<message>
<source>ACPI Sh&amp;utdown</source>
- <translation></translation>
+ <translation>ACPI Stäng a&amp;v</translation>
</message>
<message>
<source>ACPI S&amp;hutdown</source>
@@ -536,12 +536,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>Sessionsi&amp;nformation</translation>
+ <translation type="obsolete">Sessionsi&amp;nformation</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>Aktivera f&amp;järrskärm</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">&amp;Inställningar...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -707,7 +792,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE-nätverk, &quot;%1&quot;</translation>
+ <translation type="obsolete">VDE-nätverk, &quot;%1&quot;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -833,6 +918,26 @@
<comment>details report</comment>
<translation>Beskrivning</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -1041,6 +1146,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Hostname:</source>
<translation type="obsolete">&amp;Värdnamn:</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1376,6 +1485,10 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;Om ovanstående är korrekt så kan du trycka på knappen &lt;b&gt;Färdigställ&lt;/b&gt;. När du har tryckt på den så kommer valt media att temporärt monteras på den virtuella maskinen och maskinen kommer att starta körningen.&lt;/p&gt;&lt;p&gt;Observera att när du stänger den virtuella maskinen så kommer valt media att automatiskt avmonteras och uppstartsenheten kommer att ställas tillbaka till den första hårddisken.&lt;/p&gt;&lt;p&gt;Beroende på typ av konfigurationsprogram så kan du behöva att manuellt avmontera (mata ut) detta media efter att konfigurationsprogrammet startar om den virtuella maskinen för att förhindra att installationsprocessen startar en gång till. Du kan göra detta genom att välja den motsvarande &lt;b&gt;Avmontera...&lt;/b&gt;-åtgärden i menyn &lt;b&gt;Enheter&lt;/b&gt;.&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1449,41 +1562,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Allmänt</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Inmatning</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Uppdatering</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Språk</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Nätverk</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>Tillägg</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1523,7 +1601,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Extensions</source>
- <translation type="unfinished">Tillägg</translation>
+ <translation>Tillägg</translation>
</message>
</context>
<context>
@@ -1613,11 +1691,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Reset host combination</source>
- <translation type="unfinished"></translation>
+ <translation>Återställ värdkombination</translation>
</message>
<message>
<source>Resets the key combination used as the host combination in the VM window.</source>
- <translation type="unfinished"></translation>
+ <translation>Återställer tangentkombinationen som används som värdkombinationen i värdmaskinfönstret.</translation>
</message>
</context>
<context>
@@ -1825,7 +1903,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Networking</source>
- <translation type="unfinished"></translation>
+ <translation>Nätverk</translation>
</message>
</context>
<context>
@@ -1924,6 +2002,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1993,23 +2122,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Vänster skift</translation>
+ <translation type="obsolete">Vänster skift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Höger skift</translation>
+ <translation type="obsolete">Höger skift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Vänster Ctrl</translation>
+ <translation type="obsolete">Vänster Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Höger Ctrl</translation>
+ <translation type="obsolete">Höger Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Vänster Alt</translation>
+ <translation type="obsolete">Vänster Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2161,7 +2290,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>None</source>
- <translation type="unfinished"></translation>
+ <translation>Ingen</translation>
</message>
</context>
<context>
@@ -2226,6 +2355,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Importera &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2370,7 +2503,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>Indikerar status för funktioner för maskinvirtualisering som används av denna virtuella maskin:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">Indikerar status för funktioner för maskinvirtualisering som används av denna virtuella maskin:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2393,6 +2526,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;Fjärrskrivbordsservern lyssnar på port %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2592,7 +2730,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Du har 3D-acceleration aktiverat för ett operativsystem som använder grafikdrivrutinen WDDM. För maximal prestanda bör gästens VRAM ställas in till minst &lt;b&gt;%1&lt;/b&gt;.</translation>
+ <translation type="obsolete">Du har 3D-acceleration aktiverat för ett operativsystem som använder grafikdrivrutinen WDDM. För maximal prestanda bör gästens VRAM ställas in till minst &lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">du har 2D-grafikacceleration aktiverat. Eftersom 2D-grafikacceleration endast stöds för Windows-gäster så kommer denna funktion att inaktiveras.</translation>
</message>
</context>
<context>
@@ -2837,6 +2983,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Visa övers&amp;t på skärmen</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">du har valt en 64-bitars operativsystemstyp för denna virtuella maskin. Eftersom sådana gästoperativsystem kräver maskinvirtualisering (VT-x/AMD-V) så kommer denna funktion att vara automatiskt aktiverad.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -3018,7 +3168,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Väljer namnet för nätverkskortet om anslutningstypen är den samma som &lt;b&gt;Bryggat nätkort&lt;/b&gt; eller &lt;b&gt;Endast värd-kort&lt;/b&gt; och namnet på det interna nätverket om anslutningstypen är den samma som &lt;b&gt;Internt nätverk&lt;/b&gt;.</translation>
+ <translation type="obsolete">Väljer namnet för nätverkskortet om anslutningstypen är den samma som &lt;b&gt;Bryggat nätkort&lt;/b&gt; eller &lt;b&gt;Endast värd-kort&lt;/b&gt; och namnet på det interna nätverket om anslutningstypen är den samma som &lt;b&gt;Internt nätverk&lt;/b&gt;.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -3044,6 +3194,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>Omdirigering av &amp;portar</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3590,7 +3776,7 @@ serial ports</comment>
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Ingen hårddisk har valts för &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">Ingen hårddisk har valts för &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3864,6 +4050,60 @@ serial ports</comment>
<source>Choose a virtual floppy disk file...</source>
<translation>Välj en virtuell diskettfil...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">minst en stöds</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">upp till %1 stöds</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">du använder för närvarande fler lagringsstyrkort än vad ett %1-chipset har stöd för. Ändra typ av chipset i systeminställningarna eller minska antalet av följande lagringsstyrkort i lagringsinställningarna: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -4054,6 +4294,32 @@ serial ports</comment>
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>du har tilldelat chipset-typen ICH9 till denna virtuella maskin. Den kommer inte att fungera korrekt såvida inte IO-APIC-funktionen även aktiveras. Detta kommer att göras automatiskt när du accepterar inställningarna för den virtuella maskinen genom att trycka på OK-knappen.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished">du har aktiverat en USB HID (Human Interface Device). Detta kommer inte att fungera såvida inte USB-emulering även aktiveras. Detta sker automatiskt när du accepterar inställningarna för virtuella maskinen genom att trycka på OK-knappen.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -4180,6 +4446,10 @@ serial ports</comment>
</message>
<message>
<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="obsolete">USB 2.0 är för närvarande aktiverat för denna virtuella maskin. Dock kräver detta att &lt;b&gt;%1&lt;/b&gt; installeras. Installera Extension Pack (tilläggspaket) från VirtualBox webbplats. Efter det kommer du att kunna återaktivera USB 2.0. Det kommer att vara inaktiverat under tiden såvida inte du avbryter de aktuella inställningsändringarna.</translation>
+ </message>
+ <message>
+ <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>
</context>
@@ -4293,6 +4563,21 @@ serial ports</comment>
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4338,7 +4623,7 @@ serial ports</comment>
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Skapa ny virtuell disk</translation>
@@ -4381,7 +4666,7 @@ serial ports</comment>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Sammandrag</translation>
+ <translation type="unfinished">Sammandrag</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4393,7 +4678,7 @@ serial ports</comment>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Välj en fil för den nya hårddiskavbildningsfilen</translation>
+ <translation type="unfinished">Välj en fil för den nya hårddiskavbildningsfilen</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk image for your virtual machine.&lt;/p&gt;&lt;p&gt;Use the &lt;b&gt;Next&lt;/b&gt; button to go to the next page of the wizard and the &lt;b&gt;Back&lt;/b&gt; button to return to the previous page.&lt;/p&gt;</source>
@@ -4435,12 +4720,12 @@ serial ports</comment>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Plats</translation>
+ <translation type="unfinished">Plats</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Storlek</translation>
+ <translation type="unfinished">Storlek</translation>
</message>
<message>
<source>Bytes</source>
@@ -4499,108 +4784,280 @@ serial ports</comment>
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Tryck på knappen &lt;b&gt;Färdigställ&lt;/b&gt; om ovanstående inställningar är korrekt. Den nya hårddisken kommer att skapas när du har tryckt på denna knapp.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;Plats</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Storlek</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>Välkommen till guiden för att skapa ny virtuell disk!</translation>
+ <translation type="obsolete">Välkommen till guiden för att skapa ny virtuell disk!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Denna guide hjälper dig att skapa en ny virtuell hårddisk för din virtuella maskin.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Denna guide hjälper dig att skapa en ny virtuell hårddisk för din virtuella maskin.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished">Välj en virtuell hårddiskfil...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Välj den typ av virtuell hårddisk som du vill skapa.&lt;/p&gt;&lt;p&gt;En &lt;b&gt;dynamiskt växande lagring&lt;/b&gt; tar initialt upp en mycket liten mängd utrymme på din fysiska hårddisk. Den kommer att växa dynamiskt (upp till angiven storlek) allt eftersom gästoperativsystemet behöver diskutrymme.&lt;/p&gt;&lt;p&gt;En &lt;b&gt;lagring med fast storlek&lt;/b&gt; växer inte. Den lagras i en fil av ungefär samma storlek som den virtuella hårddisken. Skapandet av en lagringsplats med fast storlek kan ta lång tid beroende på lagringsstorleken och skrivprestandan för din hårddisk.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Välj den typ av virtuell hårddisk som du vill skapa.&lt;/p&gt;&lt;p&gt;En &lt;b&gt;dynamiskt växande lagring&lt;/b&gt; tar initialt upp en mycket liten mängd utrymme på din fysiska hårddisk. Den kommer att växa dynamiskt (upp till angiven storlek) allt eftersom gästoperativsystemet behöver diskutrymme.&lt;/p&gt;&lt;p&gt;En &lt;b&gt;lagring med fast storlek&lt;/b&gt; växer inte. Den lagras i en fil av ungefär samma storlek som den virtuella hårddisken. Skapandet av en lagringsplats med fast storlek kan ta lång tid beroende på lagringsstorleken och skrivprestandan för din hårddisk.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Lagringstyp</translation>
+ <translation type="obsolete">Lagringstyp</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>&amp;Dynamiskt växande lagring</translation>
+ <translation type="obsolete">&amp;Dynamiskt växande lagring</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>Lagring med &amp;fast storlek</translation>
+ <translation type="obsolete">Lagring med &amp;fast storlek</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Lagringstyp för hårddisk</translation>
+ <translation type="obsolete">Lagringstyp för hårddisk</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Tryck på knappen &lt;b&gt;Välj&lt;/b&gt; för att välja platsen för en fil att lagra hårddiskens data till eller ange ett filnamn i inmatningsfältet.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Tryck på knappen &lt;b&gt;Välj&lt;/b&gt; för att välja platsen för en fil att lagra hårddiskens data till eller ange ett filnamn i inmatningsfältet.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;Plats</translation>
+ <translation type="obsolete">&amp;Plats</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Välj storleken för den virtuella hårddisken i megabyte. Denna storlek kommer att rapporteras till gästoperativsystemet som den maximala storleken för denna hårddisk.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Välj storleken för den virtuella hårddisken i megabyte. Denna storlek kommer att rapporteras till gästoperativsystemet som den maximala storleken för denna hårddisk.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Storlek</translation>
+ <translation type="obsolete">&amp;Storlek</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>Plats och storlek för virtuell disk</translation>
+ <translation type="obsolete">Plats och storlek för virtuell disk</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Välj en fil för den nya hårddiskavbildningsfilen</translation>
+ <translation type="obsolete">Välj en fil för den nya hårddiskavbildningsfilen</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>HÃ¥rddiskavbildningar (*.vdi)</translation>
+ <translation type="obsolete">HÃ¥rddiskavbildningar (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Du är på väg att skapa en ny virtuell hårddisk med följande parametrar:</translation>
+ <translation type="obsolete">Du är på väg att skapa en ny virtuell hårddisk med följande parametrar:</translation>
</message>
<message>
<source>Summary</source>
- <translation>Sammandrag</translation>
+ <translation type="obsolete">Sammandrag</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Typ</translation>
+ <translation type="obsolete">Typ</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>Plats</translation>
+ <translation type="obsolete">Plats</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Storlek</translation>
+ <translation type="obsolete">Storlek</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Tryck på &lt;b&gt;%1&lt;/b&gt;-knappen om ovanstående inställningar är korrekta. När du har tryckt på den kommer en ny hårddisk att skapas.</translation>
+ <translation type="obsolete">Tryck på &lt;b&gt;%1&lt;/b&gt;-knappen om ovanstående inställningar är korrekta. När du har tryckt på den kommer en ny hårddisk att skapas.</translation>
</message>
</context>
<context>
@@ -4746,6 +5203,10 @@ serial ports</comment>
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">&amp;Använd befintlig hårddisk</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -5031,6 +5492,120 @@ serial ports</comment>
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Allmänt</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Inmatning</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Uppdatering</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Språk</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Nätverk</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>Tillägg</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Allmänt</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>System</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Skärm</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Lagring</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Ljud</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Nätverk</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Portar</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>Serieportar</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Parallellportar</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Delade mappar</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">du har valt en 64-bitars operativsystemstyp för denna virtuella maskin. Eftersom sådana gästoperativsystem kräver maskinvirtualisering (VT-x/AMD-V) så kommer denna funktion att vara automatiskt aktiverad.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">du har 2D-grafikacceleration aktiverat. Eftersom 2D-grafikacceleration endast stöds för Windows-gäster så kommer denna funktion att inaktiveras.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">du har aktiverat en USB HID (Human Interface Device). Detta kommer inte att fungera såvida inte USB-emulering även aktiveras. Detta sker automatiskt när du accepterar inställningarna för virtuella maskinen genom att trycka på OK-knappen.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">minst en stöds</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">upp till %1 stöds</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">du använder för närvarande fler lagringsstyrkort än vad ett %1-chipset har stöd för. Ändra typ av chipset i systeminställningarna eller minska antalet av följande lagringsstyrkort i lagringsinställningarna: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -5169,81 +5744,6 @@ serial ports</comment>
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Allmänt</translation>
- </message>
- <message>
- <source>System</source>
- <translation>System</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Skärm</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Lagring</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Ljud</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Nätverk</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Portar</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>Serieportar</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Parallellportar</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Delade mappar</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>du har valt en 64-bitars operativsystemstyp för denna virtuella maskin. Eftersom sådana gästoperativsystem kräver maskinvirtualisering (VT-x/AMD-V) så kommer denna funktion att vara automatiskt aktiverad.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>du har 2D-grafikacceleration aktiverat. Eftersom 2D-grafikacceleration endast stöds för Windows-gäster så kommer denna funktion att inaktiveras.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>du har aktiverat en USB HID (Human Interface Device). Detta kommer inte att fungera såvida inte USB-emulering även aktiveras. Detta sker automatiskt när du accepterar inställningarna för virtuella maskinen genom att trycka på OK-knappen.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>minst en stöds</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>upp till %1 stöds</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>du använder för närvarande fler lagringsstyrkort än vad ett %1-chipset har stöd för. Ändra typ av chipset i systeminställningarna eller minska antalet av följande lagringsstyrkort i lagringsinställningarna: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5418,6 +5918,14 @@ Version %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation>HÃ¥rddiskstyrkort (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -7059,7 +7567,7 @@ Version %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Adapter %1</translation>
+ <translation type="obsolete">Adapter %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -7521,7 +8029,7 @@ Version %1</translation>
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE-nätverk, &quot;%1&quot;</translation>
+ <translation type="obsolete">VDE-nätverk, &quot;%1&quot;</translation>
</message>
<message>
<source>SAS</source>
@@ -7531,7 +8039,7 @@ Version %1</translation>
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>VDE-adapter</translation>
+ <translation type="obsolete">VDE-adapter</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -7728,6 +8236,61 @@ Version %1</translation>
<comment>DiskType</comment>
<translation>Multi-attach</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Adapter %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7745,7 +8308,7 @@ Version %1</translation>
</message>
<message>
<source>&apos;%1&apos; is an invalid host-combination code-sequence.</source>
- <translation type="unfinished"></translation>
+ <translation>&quot;%1&quot; är en ogiltig kodsekvens för värdkombination.</translation>
</message>
</context>
<context>
@@ -7898,15 +8461,15 @@ Version %1</translation>
</message>
<message>
<source>Location</source>
- <translation>Plats</translation>
+ <translation type="obsolete">Plats</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Typ (Format)</translation>
+ <translation type="obsolete">Typ (Format)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Ansluten till</translation>
+ <translation type="obsolete">Ansluten till</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -7988,17 +8551,17 @@ Version %1</translation>
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Ansluten till</translation>
+ <translation type="obsolete">Ansluten till</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Ansluten till</translation>
+ <translation type="obsolete">Ansluten till</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Ansluten till</translation>
+ <translation type="obsolete">Ansluten till</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -8016,6 +8579,46 @@ Version %1</translation>
<source>All %1 images (%2)</source>
<translation>Alla %1-avbildningar (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Typ:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">Plats:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -8075,7 +8678,7 @@ Version %1</translation>
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Nätverkskort</translation>
+ <translation type="obsolete">Nätverkskort</translation>
</message>
</context>
<context>
@@ -8591,7 +9194,7 @@ Version %1</translation>
<message>
<source>Reset</source>
<comment>machine</comment>
- <translation>Återställ</translation>
+ <translation>Starta om</translation>
</message>
<message>
<source>Continue</source>
@@ -8873,7 +9476,7 @@ Version %1</translation>
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Kunde inte komma åt USB på värdsystemet därför att varken USB-filsystemet (usbfs) eller DBus och hal-tjänster är tillgängliga för tillfället. Om du önskar att använda värdens USB-enheter inne i gästsystem så måste du rätta till detta och starta om VirtualBox.</translation>
+ <translation type="obsolete">Kunde inte komma åt USB på värdsystemet därför att varken USB-filsystemet (usbfs) eller DBus och hal-tjänster är tillgängliga för tillfället. Om du önskar att använda värdens USB-enheter inne i gästsystem så måste du rätta till detta och starta om VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -8994,7 +9597,7 @@ Version %1</translation>
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Är du säker på att du vill återställa ögonblicksbilden &lt;b&gt;%1&lt;/b&gt;? Detta kommer att orsaka att du förlorar ditt aktuella maskintillstånd, vilket inte kan återställas.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Är du säker på att du vill återställa ögonblicksbilden &lt;b&gt;%1&lt;/b&gt;? Detta kommer att orsaka att du förlorar ditt aktuella maskintillstånd, vilket inte kan återställas.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -9285,7 +9888,7 @@ Version %1</translation>
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">Beklagar, ett allmänt fel inträffade.</translation>
+ <translation type="unfinished">Beklagar, ett allmänt fel inträffade.</translation>
</message>
<message>
<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>
@@ -9374,14 +9977,78 @@ Version %1</translation>
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Borttagning av alla filer som tillhör värdmaskinen är för närvarande inaktiverat på Windows/x64 för att förhindra en krasch. Detta kommer att korrigeras i nästa utgåva.</translation>
</message>
<message>
<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 type="unfinished"></translation>
+ <translation>&lt;p&gt;Kan inte skapa maskinmappen &lt;b&gt;%1&lt;/b&gt; i föräldramappen &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;Kontrollera att föräldern verkligen finns och att du har behörighet att skapa maskinmappen.&lt;/p&gt;</translation>
</message>
<message>
<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="obsolete">&lt;p&gt;USB 2.0 är för närvarande aktiverat för denna virtuella maskin. Dock kräver detta att &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; installeras.&lt;/p&gt;&lt;p&gt;Installera Extension Pack (tilläggspaket) från VirtualBox webbplats. Efter det kommer du att kunna återaktivera USB 2.0. Det kommer att vara inaktiverat under tiden såvida inte du avbryter de aktuella inställningsändringarna.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -9504,7 +10171,7 @@ Version %1</translation>
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Delade mappar</translation>
+ <translation type="obsolete">Delade mappar</translation>
</message>
</context>
<context>
@@ -9583,7 +10250,7 @@ Version %1</translation>
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Fö&amp;rkasta</translation>
+ <translation type="obsolete">Fö&amp;rkasta</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -9789,6 +10456,22 @@ Version %1</translation>
<source>Show Statusbar</source>
<translation>Visa statusrad</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished">Förkasta</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -10022,6 +10705,14 @@ Version %1</translation>
<source> (%1 ago)</source>
<translation> (%1 sedan)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_tr.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_tr.ts
index 1da537537..17ee3b1c2 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_tr.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_tr.ts
@@ -511,11 +511,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">A&amp;yarlar...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -681,11 +762,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation type="unfinished">Bağdaştırıcı %1</translation>
@@ -809,6 +885,26 @@
<comment>details report</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -897,6 +993,10 @@
<source>Restore Defaults</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1154,6 +1254,10 @@
<source>Cancel</source>
<translation type="obsolete">İptal</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">BaÅŸlat</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1227,41 +1331,6 @@
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Genel</translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished"> Girdi </translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished">Güncelle</translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished">Dil</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB </translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">AÄŸ</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished">VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1672,6 +1741,57 @@
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1741,23 +1861,23 @@
</message>
<message>
<source>Left Shift</source>
- <translation>Sol Shift</translation>
+ <translation type="obsolete">Sol Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>SaÄŸ Shift</translation>
+ <translation type="obsolete">SaÄŸ Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Sol Ctrl</translation>
+ <translation type="obsolete">Sol Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>SaÄŸ Ctrl</translation>
+ <translation type="obsolete">SaÄŸ Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Sol Alt</translation>
+ <translation type="obsolete">Sol Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -1930,6 +2050,10 @@
<source>Restore Defaults</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2072,11 +2196,6 @@
<translation type="obsolete">&lt;hr&gt;VRDP Sunusu %1 portundan dinleniyor</translation>
</message>
<message>
- <source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
- <comment>Virtualization Stuff LED</comment>
- <translation></translation>
- </message>
- <message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation></translation>
@@ -2097,6 +2216,11 @@
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2279,7 +2403,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2465,6 +2593,10 @@
<source>Show At &amp;Top Of Screen</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2600,10 +2732,6 @@
<translation type="unfinished">&amp;İsim:</translation>
</message>
<message>
- <source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>A&amp;dvanced</source>
<translation type="unfinished"></translation>
</message>
@@ -2627,6 +2755,42 @@
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3028,10 +3192,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
@@ -3267,6 +3427,60 @@
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3440,6 +3654,32 @@
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3565,7 +3805,7 @@
<translation type="unfinished">&lt;nobr&gt;Durum: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -3679,6 +3919,21 @@
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3724,7 +3979,7 @@
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Yeni Sanal Disk OluÅŸtur</translation>
@@ -3809,7 +4064,7 @@ sanal sabit disk boyutu olarak rapor edilecektir.&lt;/p&gt; </translation>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">Özet</translation>
+ <translation type="unfinished">Özet</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -3825,7 +4080,7 @@ sanal sabit disk boyutu olarak rapor edilecektir.&lt;/p&gt; </translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Yeni sabit disk kalıbı dosyası için, bir dosya seçin</translation>
+ <translation type="unfinished">Yeni sabit disk kalıbı dosyası için, bir dosya seçin</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -3847,12 +4102,12 @@ sanal sabit disk boyutu olarak rapor edilecektir.&lt;/p&gt; </translation>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">Konum</translation>
+ <translation type="unfinished">Konum</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Boyut</translation>
+ <translation type="unfinished">Boyut</translation>
</message>
<message>
<source>Bytes</source>
@@ -3907,108 +4162,260 @@ sanal sabit disk boyutu olarak rapor edilecektir.&lt;/p&gt; </translation>
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Eğer aşağıdaki ayarlar doğruysa &lt;b&gt;Bitir&lt;/b&gt; düğmesine basın. Bitir düğmesine bastığınızda, yeni bir sabit disk kalıbı oluşturulacaktır.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
<message>
- <source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation type="unfinished">Sanal Disk Oluşturma Sihirbazına Hoşgeldiniz!</translation>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;Konum</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Boyut</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>UINewHDWzdPage2</name>
+ <name>UINewHDWizardPageWelcome</name>
+ <message>
+ <source>Welcome to the Create New Virtual Disk Wizard!</source>
+ <translation type="obsolete">Sanal Disk Oluşturma Sihirbazına Hoşgeldiniz!</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
<message>
- <source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
+ <source>Choose a virtual hard disk file...</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UINewHDWzdPage2</name>
<message>
<source>Storage Type</source>
- <translation type="unfinished">Depolama Tipi</translation>
+ <translation type="obsolete">Depolama Tipi</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation type="unfinished">&amp;Dinamik olarak genişleyen kalıp</translation>
+ <translation type="obsolete">&amp;Dinamik olarak genişleyen kalıp</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation type="unfinished">&amp;Sabit boyutlu depolama</translation>
+ <translation type="obsolete">&amp;Sabit boyutlu depolama</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation type="unfinished">Sabit Disk Depolama Tipi</translation>
+ <translation type="obsolete">Sabit Disk Depolama Tipi</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;&lt;b&gt;Seç&lt;/b&gt; simgesine basarak sanal sabit disk kalıbının saklanacağı konumu ve oluşturulacak dosyanın adını seçebilirsiniz ya da aşağıdaki alanına bir dosya ismi yazabilirsiniz.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;&lt;b&gt;Seç&lt;/b&gt; simgesine basarak sanal sabit disk kalıbının saklanacağı konumu ve oluşturulacak dosyanın adını seçebilirsiniz ya da aşağıdaki alanına bir dosya ismi yazabilirsiniz.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation type="unfinished">&amp;Konum</translation>
+ <translation type="obsolete">&amp;Konum</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;Sanal sabit disk kalıbının boyutunu megabayt cinsinden seçin. Bu boyut, misafir işletim sistemine sanal sabit disk boyutu olarak rapor edilecektir.&lt;/p&gt; </translation>
+ <translation type="obsolete">&lt;p&gt;Sanal sabit disk kalıbının boyutunu megabayt cinsinden seçin. Bu boyut, misafir işletim sistemine sanal sabit disk boyutu olarak rapor edilecektir.&lt;/p&gt; </translation>
</message>
<message>
<source>&amp;Size</source>
- <translation type="unfinished">&amp;Boyut</translation>
+ <translation type="obsolete">&amp;Boyut</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation type="unfinished">Sanal Disk Konumu ve Boyutu</translation>
+ <translation type="obsolete">Sanal Disk Konumu ve Boyutu</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="unfinished">Yeni sabit disk kalıbı dosyası için, bir dosya seçin</translation>
+ <translation type="obsolete">Yeni sabit disk kalıbı dosyası için, bir dosya seçin</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation type="unfinished">Sabit disk kalıpları (*.vdi)</translation>
- </message>
- <message>
- <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Sabit disk kalıpları (*.vdi)</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation type="unfinished">Aşağıdaki ayarlara göre yeni bir sanal sabit disk kalıbı oluşturacaksınız:</translation>
+ <translation type="obsolete">Aşağıdaki ayarlara göre yeni bir sanal sabit disk kalıbı oluşturacaksınız:</translation>
</message>
<message>
<source>Summary</source>
- <translation type="unfinished">Özet</translation>
- </message>
- <message>
- <source>%1 B</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Özet</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation type="unfinished">Tip</translation>
+ <translation type="obsolete">Tip</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="unfinished">Konum</translation>
+ <translation type="obsolete">Konum</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="unfinished">Boyut</translation>
- </message>
- <message>
- <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Boyut</translation>
</message>
</context>
<context>
@@ -4231,6 +4638,10 @@ bu basamağı atlayarak sabit diskleri Sanal Makine Ayarları penceresinden ekle
<source>Boot Hard &amp;Disk (Primary Master)</source>
<translation type="obsolete">&amp;Başlangıç (Boot) Sabit Diski (Primary Master)</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4460,6 +4871,96 @@ bu basamağı atlayarak sabit diskleri Sanal Makine Ayarları penceresinden ekle
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Genel</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation type="unfinished"> Girdi </translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished">Güncelle</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation type="unfinished">Dil</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB </translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">AÄŸ</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation type="unfinished">VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Genel</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation type="unfinished">Depolama</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished">Ses</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">AÄŸ</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation type="unfinished">Portlar</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation type="unfinished">Seri Portlar </translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation type="unfinished">Paralel Portlar </translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished">USB </translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation type="unfinished">Paylaşılan Dizinler</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished">%1 %2</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -4598,81 +5099,6 @@ bu basamağı atlayarak sabit diskleri Sanal Makine Ayarları penceresinden ekle
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">Genel</translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished">Depolama</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished">Ses</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">AÄŸ</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished">Portlar</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished">Seri Portlar </translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished">Paralel Portlar </translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished">USB </translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished">Paylaşılan Dizinler</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished">%1 %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -4903,6 +5329,14 @@ Version %1</source>
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -6630,7 +7064,7 @@ Version %1</source>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Bağdaştırıcı %1</translation>
+ <translation type="obsolete">Bağdaştırıcı %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -7041,21 +7475,11 @@ Version %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>SAS</source>
<comment>StorageBus</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation type="unfinished"></translation>
@@ -7245,6 +7669,61 @@ Version %1</source>
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Bağdaştırıcı %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7912,15 +8391,15 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>Location</source>
- <translation>Konum</translation>
+ <translation type="obsolete">Konum</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Tip (Biçim)</translation>
+ <translation type="obsolete">Tip (Biçim)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Åžuraya eklendi</translation>
+ <translation type="obsolete">Åžuraya eklendi</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -8002,17 +8481,17 @@ to the system default language.&lt;/qt&gt;
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation type="unfinished">Åžuraya eklendi</translation>
+ <translation type="obsolete">Åžuraya eklendi</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation type="unfinished">Åžuraya eklendi</translation>
+ <translation type="obsolete">Åžuraya eklendi</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation type="unfinished">Åžuraya eklendi</translation>
+ <translation type="obsolete">Åžuraya eklendi</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -8030,6 +8509,46 @@ to the system default language.&lt;/qt&gt;
<source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -8086,13 +8605,6 @@ to the system default language.&lt;/qt&gt;
</message>
</context>
<context>
- <name>VBoxNetworkDialog</name>
- <message>
- <source>Network Adapters</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxOSTypeSelectorWidget</name>
<message>
<source>Operating &amp;System:</source>
@@ -8850,10 +9362,6 @@ Bu Sanal Makinenin fare işaretçinizi ve klavyenizi &lt;b&gt;yakalamasına&lt;/
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
<translation type="unfinished"></translation>
</message>
@@ -8954,10 +9462,6 @@ Bu Sanal Makinenin fare işaretçinizi ve klavyenizi &lt;b&gt;yakalamasına&lt;/
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restore</source>
<translation type="unfinished"></translation>
</message>
@@ -9299,15 +9803,75 @@ Bu Sanal Makinenin fare işaretçinizi ve klavyenizi &lt;b&gt;yakalamasına&lt;/
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -9386,7 +9950,7 @@ Bu Sanal Makinenin fare işaretçinizi ve klavyenizi &lt;b&gt;yakalamasına&lt;/
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Paylaşılan Dizinler</translation>
+ <translation type="obsolete">Paylaşılan Dizinler</translation>
</message>
<message>
<source>Cancel</source>
@@ -9513,11 +10077,11 @@ Bu Sanal Makinenin fare işaretçinizi ve klavyenizi &lt;b&gt;yakalamasına&lt;/
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Va&amp;zgeç</translation>
+ <translation type="obsolete">Va&amp;zgeç</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">Vazgeç</translation>
+ <translation type="unfinished">Vazgeç</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -9803,6 +10367,18 @@ Bu Sanal Makinenin fare işaretçinizi ve klavyenizi &lt;b&gt;yakalamasına&lt;/
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -10173,6 +10749,14 @@ Bu özellik Misafir Eklentilerinin yüklü olmasını gerektirir.&lt;/qt&gt;</tr
<source> (%1 ago)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_uk.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_uk.ts
index 3dcd38971..e80cc4894 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_uk.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_uk.ts
@@ -509,12 +509,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>&amp;Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ ÑеанÑ</translation>
+ <translation type="obsolete">&amp;Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ ÑеанÑ</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>Увімкнути віддалений &amp;екран</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">&amp;ÐалаштуваннÑ...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -680,7 +765,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Мережа VDE, &apos;%1&apos;</translation>
+ <translation type="obsolete">Мережа VDE, &apos;%1&apos;</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -806,6 +891,26 @@
<comment>details report</comment>
<translation>ОпиÑ</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -982,6 +1087,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Export &gt;</source>
<translation type="obsolete">&amp;ЕкÑпорт &gt;</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1312,6 +1421,10 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;If the above is correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.&lt;/p&gt;&lt;p&gt;Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.&lt;/p&gt;&lt;p&gt;Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding &lt;b&gt;Unmount...&lt;/b&gt; action in the &lt;b&gt;Devices&lt;/b&gt; menu.&lt;/p&gt;</source>
<translation type="obsolete">&lt;p&gt;Якщо вищевказане правильне, натиÑніть кнопку &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;.&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1385,41 +1498,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Загальне</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>Ввід</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>ОновленнÑ</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>Мова</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Мережа</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>РозширеннÑ</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox — %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1856,6 +1934,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1925,23 +2054,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Лівий Shift</translation>
+ <translation type="obsolete">Лівий Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Правий Shift</translation>
+ <translation type="obsolete">Правий Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Лівий Ctrl</translation>
+ <translation type="obsolete">Лівий Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Правий Ctrl</translation>
+ <translation type="obsolete">Правий Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Лівий Alt</translation>
+ <translation type="obsolete">Лівий Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2158,6 +2287,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">&amp;Імпорт &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2302,7 +2435,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>ОпиÑує Ñтан влаÑтивоÑтей віртулазації приÑтроїв, Ñкі викориÑтовуютьÑÑ Ð²Ñ–Ñ€Ñ‚ÑƒÐ°Ð»ÑŒÐ½Ð¾ÑŽ машиною:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">ОпиÑує Ñтан влаÑтивоÑтей віртулазації приÑтроїв, Ñкі викориÑтовуютьÑÑ Ð²Ñ–Ñ€Ñ‚ÑƒÐ°Ð»ÑŒÐ½Ð¾ÑŽ машиною:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2325,6 +2458,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;Сервер віддаленої Ñтільниці очікуєтьÑÑ Ð½Ð° порті %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2524,7 +2662,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>Ви увімкнули проÑторове приÑÐºÐ¾Ñ€ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ð¹Ð½Ð¾Ñ— ÑиÑтеми, Ñка викориÑтовує відеодрайвер WDDM. Ð”Ð»Ñ Ð½Ð°Ð¹Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ð¸Ð²Ð½Ñ–ÑˆÐ¾Ñ— роботи ввімкніть хоча би гоÑтьову VRAM&lt;b&gt;%1&lt;/b&gt;.</translation>
+ <translation type="obsolete">Ви увімкнули проÑторове приÑÐºÐ¾Ñ€ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ð¹Ð½Ð¾Ñ— ÑиÑтеми, Ñка викориÑтовує відеодрайвер WDDM. Ð”Ð»Ñ Ð½Ð°Ð¹Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ð¸Ð²Ð½Ñ–ÑˆÐ¾Ñ— роботи ввімкніть хоча би гоÑтьову VRAM&lt;b&gt;%1&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2741,6 +2887,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>Показувати &amp;зверху екрана</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -2879,7 +3029,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>Вибирає назву мережевого адаптера, Ñкщо тип під&apos;Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ€Ñ–Ð²Ð½Ð¾Ñильний до &lt;b&gt;проміжного адаптера&lt;/b&gt; або &lt;b&gt;лише головного адаптера&lt;/b&gt; Ñ– назву внутрішньої мережі, Ñкщо тип під&apos;Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ€Ñ–Ð²Ð½Ð¾Ñильний до &lt;b&gt;внутрішньої мережі&lt;/b&gt;.</translation>
+ <translation type="obsolete">Вибирає назву мережевого адаптера, Ñкщо тип під&apos;Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ€Ñ–Ð²Ð½Ð¾Ñильний до &lt;b&gt;проміжного адаптера&lt;/b&gt; або &lt;b&gt;лише головного адаптера&lt;/b&gt; Ñ– назву внутрішньої мережі, Ñкщо тип під&apos;Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ€Ñ–Ð²Ð½Ð¾Ñильний до &lt;b&gt;внутрішньої мережі&lt;/b&gt;.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -2905,6 +3055,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation>&amp;ПереадреÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ€Ñ‚Ñƒ</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3371,7 +3557,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>Ðе вибрано жорÑткий диÑк Ð´Ð»Ñ &lt;i&gt;%1&lt;/i&gt;.</translation>
+ <translation type="obsolete">Ðе вибрано жорÑткий диÑк Ð´Ð»Ñ &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3645,6 +3831,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation>Вибрати файл віртуальної диÑкети…</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">щонайбільше один підтримуєтьÑÑ</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">до %1 підтримуєтьÑÑ</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">ви тепер викориÑтовуєте більше пам&apos;Ñті контролерів, аніж підтримуєтьÑÑ â€” %1. Будь лаÑка, змініть тип ÐºÐ¾Ð¼Ð¿Ð»ÐµÐºÑ Ð¼Ñ–ÐºÑ€Ð¾Ñхем на Ñторінці налаштувань ÑиÑтеми або або збільште кількіÑть кількіÑть пам&apos;Ñті таких контролерів на Ñторінці налаштувань пам&apos;Ñті: %2.</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -3835,6 +4075,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>ви вказали тип комплекту мікроÑхем ICH9 Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— віртуальної машини. Це не буде працювати Ñк Ñлід, допоки IO-APIC увімкнуто. Це буде автоматично здійÑнено, коли ви дозволите Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ñ€Ñ‚ÑƒÐ°Ð»ÑŒÐ½Ð¾Ñ— машини, натиÑнувши кнопку Гаразд.</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished">ви маєте USB HID (людÑький Ñ–Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¿Ñ€Ð¸Ñтрою) увімкнутим. Це не буде працювати, Ñкщо вимкнено ÐµÐ¼ÑƒÐ»ÑŽÐ²Ð°Ð½Ð½Ñ USB. Воно буде ввімкнуто автоматично, Ñкщо ви даÑте згоду на це в налаштуваннÑÑ… віртуальної машини.</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -3961,7 +4227,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>USB 2.0 уже ввімкнено Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— віртуальної машини. Однак потрібно вÑтановити &lt;b&gt;%1&lt;/b&gt;. Будь лаÑка, вÑтановіть пакунок розширень із Ñайту звантажень VirtualBox. ПіÑÐ»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ зможете перезапуÑтити USB 2.0. Це буде вимкнено протÑгом ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¼Ñ–Ð½ поточних налаштувань.</translation>
+ <translation type="obsolete">USB 2.0 уже ввімкнено Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— віртуальної машини. Однак потрібно вÑтановити &lt;b&gt;%1&lt;/b&gt;. Будь лаÑка, вÑтановіть пакунок розширень із Ñайту звантажень VirtualBox. ПіÑÐ»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ зможете перезапуÑтити USB 2.0. Це буде вимкнено протÑгом ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¼Ñ–Ð½ поточних налаштувань.</translation>
+ </message>
+ <message>
+ <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>
</context>
<context>
@@ -4074,6 +4344,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4119,7 +4404,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>Створити новий віртуальний диÑк</translation>
@@ -4134,7 +4419,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">ПідÑумок</translation>
+ <translation type="unfinished">ПідÑумок</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4146,7 +4431,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">Виберіть файл Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ образу жорÑткого диÑка</translation>
+ <translation type="unfinished">Виберіть файл Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ образу жорÑткого диÑка</translation>
</message>
<message>
<source>&lt; &amp;Back</source>
@@ -4168,12 +4453,12 @@ p, li { white-space: pre-wrap; }
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">ÐдреÑа</translation>
+ <translation type="unfinished">ÐдреÑа</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">Розмір</translation>
+ <translation type="unfinished">Розмір</translation>
</message>
<message>
<source>Bytes</source>
@@ -4232,108 +4517,280 @@ p, li { white-space: pre-wrap; }
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">Якщо вищевказані Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ–, натиÑніть кнопку &lt;b&gt;Закінчити&lt;/b&gt;. ПіÑÐ»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ буде Ñтворений новий жорÑткий диÑк.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 Б)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 Б</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">&amp;ÐдреÑа</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">&amp;Розмір</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>ЛаÑкаво проÑимо до майÑтра ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ віртуального диÑка!</translation>
+ <translation type="obsolete">ЛаÑкаво проÑимо до майÑтра ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ віртуального диÑка!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;Цей майÑтер допоможе вам Ñтворити новий віртуальний жорÑткий диÑк Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ñ— віртуальної машини.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Цей майÑтер допоможе вам Ñтворити новий віртуальний жорÑткий диÑк Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ñ— віртуальної машини.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Виберіть тип віртуального жорÑткого диÑка, Ñкий ви бажаєте Ñтворити.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Динамічно розширна пам&apos;Ñть&lt;/b&gt; початково займає дуже малу величину міÑÑ†Ñ Ð½Ð° фізичному жорÑткому диÑку. Розмір буде динамічно зроÑтати (до вказаного розміру) до тих пір, поки гоÑтьова операційна ÑиÑтема може викориÑтовувати диÑковий проÑтір.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Ðезмінної розмірноÑті пам&apos;Ñть&lt;/b&gt; не збільшуєтьÑÑ. Він зберігаєтьÑÑ Ñƒ файлі приблизно такого ж розміру, Ñк розмір віртуального жорÑткого диÑка. Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½ÐµÐ·Ð¼Ñ–Ð½Ð½Ð¾Ñ— розмірноÑті пам&apos;Ñті може забрати багато чаÑу, Ñкий залежить від розміру пам&apos;Ñті та швидкодії вашого жорÑткого диÑка.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Виберіть тип віртуального жорÑткого диÑка, Ñкий ви бажаєте Ñтворити.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Динамічно розширна пам&apos;Ñть&lt;/b&gt; початково займає дуже малу величину міÑÑ†Ñ Ð½Ð° фізичному жорÑткому диÑку. Розмір буде динамічно зроÑтати (до вказаного розміру) до тих пір, поки гоÑтьова операційна ÑиÑтема може викориÑтовувати диÑковий проÑтір.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Ðезмінної розмірноÑті пам&apos;Ñть&lt;/b&gt; не збільшуєтьÑÑ. Він зберігаєтьÑÑ Ñƒ файлі приблизно такого ж розміру, Ñк розмір віртуального жорÑткого диÑка. Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½ÐµÐ·Ð¼Ñ–Ð½Ð½Ð¾Ñ— розмірноÑті пам&apos;Ñті може забрати багато чаÑу, Ñкий залежить від розміру пам&apos;Ñті та швидкодії вашого жорÑткого диÑка.&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>Тип пам&apos;Ñті</translation>
+ <translation type="obsolete">Тип пам&apos;Ñті</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>Д&amp;инамічно розширна пам&apos;Ñть</translation>
+ <translation type="obsolete">Д&amp;инамічно розширна пам&apos;Ñть</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>Ð&amp;езмінної розмірноÑті пам&apos;Ñть</translation>
+ <translation type="obsolete">Ð&amp;езмінної розмірноÑті пам&apos;Ñть</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>Тип пам&apos;Ñті жорÑткого диÑка</translation>
+ <translation type="obsolete">Тип пам&apos;Ñті жорÑткого диÑка</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;ÐатиÑніть кнопку &lt;b&gt;Вибрати&lt;/b&gt;, щоб вибрати адреÑу файла Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… віртуального жорÑткого диÑка або введіть назву файла у поле вводу.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;ÐатиÑніть кнопку &lt;b&gt;Вибрати&lt;/b&gt;, щоб вибрати адреÑу файла Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… віртуального жорÑткого диÑка або введіть назву файла у поле вводу.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>&amp;ÐдреÑа</translation>
+ <translation type="obsolete">&amp;ÐдреÑа</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Виберіть розмір віртуального жорÑткого диÑка у мегабайтах. Цей розмір буде вказаний гоÑтьовій операційній ÑиÑтемі Ñк макÑимальний розмір жорÑткого диÑка.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Виберіть розмір віртуального жорÑткого диÑка у мегабайтах. Цей розмір буде вказаний гоÑтьовій операційній ÑиÑтемі Ñк макÑимальний розмір жорÑткого диÑка.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>&amp;Розмір</translation>
+ <translation type="obsolete">&amp;Розмір</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>ÐдреÑа Ñ– розмір віртуального диÑка</translation>
+ <translation type="obsolete">ÐдреÑа Ñ– розмір віртуального диÑка</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>Виберіть файл Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ образу жорÑткого диÑка</translation>
+ <translation type="obsolete">Виберіть файл Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ образу жорÑткого диÑка</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>Образ жорÑткого диÑка (*.vdi)</translation>
+ <translation type="obsolete">Образ жорÑткого диÑка (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 Б)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 Б)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>Ви збираєтеÑÑŒ Ñтворити новий віртуальний жорÑткий диÑк з такими параметрами:</translation>
+ <translation type="obsolete">Ви збираєтеÑÑŒ Ñтворити новий віртуальний жорÑткий диÑк з такими параметрами:</translation>
</message>
<message>
<source>Summary</source>
- <translation>ПідÑумок</translation>
+ <translation type="obsolete">ПідÑумок</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 Б</translation>
+ <translation type="obsolete">%1 Б</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>Тип</translation>
+ <translation type="obsolete">Тип</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>ÐдреÑа</translation>
+ <translation type="obsolete">ÐдреÑа</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>Розмір</translation>
+ <translation type="obsolete">Розмір</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>Якщо Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ñ‰Ðµ коректні, натиÑніть &lt;b&gt;%1&lt;/b&gt;. Як тільки ви натиÑнете це, новий жорÑткий диÑк буде Ñтворено.</translation>
+ <translation type="obsolete">Якщо Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ñ‰Ðµ коректні, натиÑніть &lt;b&gt;%1&lt;/b&gt;. Як тільки ви натиÑнете це, новий жорÑткий диÑк буде Ñтворено.</translation>
</message>
</context>
<context>
@@ -4471,6 +4928,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">&amp;ВикориÑтовувати наÑвний жорÑткий диÑк</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -4756,6 +5217,120 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>Загальне</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>Ввід</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>ОновленнÑ</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Мова</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Мережа</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>РозширеннÑ</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox — %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>Загальне</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>СиÑтема</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Екран</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>Пам&apos;Ñть</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Ðудіо</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Мережа</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>Порти</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>ПоÑлідовні порти</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>Паралельні порти</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>Спільні теки</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 — %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">ви вибрали 64-ох бітну гоÑтьову операційну ÑиÑтему Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— віртуальної машини. Потрібна відповідна апаратна Ð²Ñ–Ñ€Ñ‚ÑƒÐ°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ (VT-x/AMD-V), цю можливіÑть буде автоматично ввімкнено.</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">ви маєте приÑÐºÐ¾Ñ€ÐµÐ½Ð½Ñ Ð´Ð²Ð¾Ð²Ð¸Ð¼Ñ–Ñ€Ð½Ð¾Ð³Ð¾ відео увімкнутим. ОÑкільки приÑÐºÐ¾Ñ€ÐµÐ½Ð½Ñ Ð´Ð²Ð¾Ð²Ð¸Ð¼Ñ–Ñ€Ð½Ð¾Ð³Ð¾ відео підтримуєтьÑÑ Ð»Ð¸ÑˆÐµ Ð´Ð»Ñ Ð³Ð¾Ñтьових Windows, цю влаÑтивіÑть вимкнено.</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">ви маєте USB HID (людÑький Ñ–Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¿Ñ€Ð¸Ñтрою) увімкнутим. Це не буде працювати, Ñкщо вимкнено ÐµÐ¼ÑƒÐ»ÑŽÐ²Ð°Ð½Ð½Ñ USB. Воно буде ввімкнуто автоматично, Ñкщо ви даÑте згоду на це в налаштуваннÑÑ… віртуальної машини.</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">щонайбільше один підтримуєтьÑÑ</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">до %1 підтримуєтьÑÑ</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">ви тепер викориÑтовуєте більше пам&apos;Ñті контролерів, аніж підтримуєтьÑÑ â€” %1. Будь лаÑка, змініть тип ÐºÐ¾Ð¼Ð¿Ð»ÐµÐºÑ Ð¼Ñ–ÐºÑ€Ð¾Ñхем на Ñторінці налаштувань ÑиÑтеми або або збільште кількіÑть кількіÑть пам&apos;Ñті таких контролерів на Ñторінці налаштувань пам&apos;Ñті: %2.</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -4894,81 +5469,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>Загальне</translation>
- </message>
- <message>
- <source>System</source>
- <translation>СиÑтема</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>Екран</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>Пам&apos;Ñть</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>Ðудіо</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>Мережа</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>Порти</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>ПоÑлідовні порти</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>Паралельні порти</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>Спільні теки</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 — %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>ви вибрали 64-ох бітну гоÑтьову операційну ÑиÑтему Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— віртуальної машини. Потрібна відповідна апаратна Ð²Ñ–Ñ€Ñ‚ÑƒÐ°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ (VT-x/AMD-V), цю можливіÑть буде автоматично ввімкнено.</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>ви маєте приÑÐºÐ¾Ñ€ÐµÐ½Ð½Ñ Ð´Ð²Ð¾Ð²Ð¸Ð¼Ñ–Ñ€Ð½Ð¾Ð³Ð¾ відео увімкнутим. ОÑкільки приÑÐºÐ¾Ñ€ÐµÐ½Ð½Ñ Ð´Ð²Ð¾Ð²Ð¸Ð¼Ñ–Ñ€Ð½Ð¾Ð³Ð¾ відео підтримуєтьÑÑ Ð»Ð¸ÑˆÐµ Ð´Ð»Ñ Ð³Ð¾Ñтьових Windows, цю влаÑтивіÑть вимкнено.</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>ви маєте USB HID (людÑький Ñ–Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¿Ñ€Ð¸Ñтрою) увімкнутим. Це не буде працювати, Ñкщо вимкнено ÐµÐ¼ÑƒÐ»ÑŽÐ²Ð°Ð½Ð½Ñ USB. Воно буде ввімкнуто автоматично, Ñкщо ви даÑте згоду на це в налаштуваннÑÑ… віртуальної машини.</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>щонайбільше один підтримуєтьÑÑ</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>до %1 підтримуєтьÑÑ</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>ви тепер викориÑтовуєте більше пам&apos;Ñті контролерів, аніж підтримуєтьÑÑ â€” %1. Будь лаÑка, змініть тип ÐºÐ¾Ð¼Ð¿Ð»ÐµÐºÑ Ð¼Ñ–ÐºÑ€Ð¾Ñхем на Ñторінці налаштувань ÑиÑтеми або або збільште кількіÑть кількіÑть пам&apos;Ñті таких контролерів на Ñторінці налаштувань пам&apos;Ñті: %2.</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5126,6 +5626,14 @@ p, li { white-space: pre-wrap; }
<source>Hard Disk Controller (SAS)</source>
<translation>Контролер жорÑткого диÑка (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -6529,7 +7037,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>Ðдаптер %1</translation>
+ <translation type="obsolete">Ðдаптер %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -6977,7 +7485,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>Мережа VDE, &apos;%1&apos;</translation>
+ <translation type="obsolete">Мережа VDE, &apos;%1&apos;</translation>
</message>
<message>
<source>SAS</source>
@@ -6987,7 +7495,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>Ðдаптер VDE</translation>
+ <translation type="obsolete">Ðдаптер VDE</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -7184,6 +7692,61 @@ p, li { white-space: pre-wrap; }
<comment>DiskType</comment>
<translation>Кілька під&apos;єднань</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">Ðдаптер %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -7346,15 +7909,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Location</source>
- <translation>ÐдреÑа</translation>
+ <translation type="obsolete">ÐдреÑа</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>Тип (Формат)</translation>
+ <translation type="obsolete">Тип (Формат)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>Під&apos;єднати до</translation>
+ <translation type="obsolete">Під&apos;єднати до</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -7436,17 +7999,17 @@ p, li { white-space: pre-wrap; }
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>Під&apos;єднано до</translation>
+ <translation type="obsolete">Під&apos;єднано до</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>Під&apos;єднано до</translation>
+ <translation type="obsolete">Під&apos;єднано до</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>Під&apos;єднано до</translation>
+ <translation type="obsolete">Під&apos;єднано до</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -7464,6 +8027,46 @@ p, li { white-space: pre-wrap; }
<source>All %1 images (%2)</source>
<translation>УÑÑ– образи %1 (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">Тип:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">ÐдреÑа:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -7523,7 +8126,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>Мережеві адаптери</translation>
+ <translation type="obsolete">Мережеві адаптери</translation>
</message>
</context>
<context>
@@ -8216,7 +8819,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>Ðема доÑтупу до USB на головній операційній ÑиÑтемі, бо ані файлова ÑиÑтема USB (usbfs), ані DBus Ñ– Ñлужби hal зараз недоÑтупні. Якщо ви бажаєте викориÑтовувати головний приÑтрій USB вÑередині гоÑтьової операційної ÑиÑтеми, вам потрібно виправити це Ñ– перезавантажити VirtualBox.</translation>
+ <translation type="obsolete">Ðема доÑтупу до USB на головній операційній ÑиÑтемі, бо ані файлова ÑиÑтема USB (usbfs), ані DBus Ñ– Ñлужби hal зараз недоÑтупні. Якщо ви бажаєте викориÑтовувати головний приÑтрій USB вÑередині гоÑтьової операційної ÑиÑтеми, вам потрібно виправити це Ñ– перезавантажити VirtualBox.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -8329,7 +8932,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Ви впевнені, що бажаєте відновити зріз &lt;b&gt;%1&lt;/b&gt;? Це Ñпричинить втрату поточного Ñтану машини, Ñкий буде неможливо відновити.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Ви впевнені, що бажаєте відновити зріз &lt;b&gt;%1&lt;/b&gt;? Це Ñпричинить втрату поточного Ñтану машини, Ñкий буде неможливо відновити.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -8633,7 +9236,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Sorry, some generic error happens.</source>
- <translation type="obsolete">Вибачте, трапилаÑÑŒ деÑка випадкова помилка.</translation>
+ <translation type="unfinished">Вибачте, трапилаÑÑŒ деÑка випадкова помилка.</translation>
</message>
<message>
<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>
@@ -8649,7 +9252,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>Ð’Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ð²ÑÑ–Ñ… файлів, Ñкі належать віртуальній машині, наразі вимкнено Ð´Ð»Ñ Windows/x64 Ð·Ð°Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð±Ñ–Ð³Ð°Ð½Ð½Ñ ÐºÑ€Ð°Ñ…Ñ–Ð². Це буде виправлено в наÑтупному випуÑку.</translation>
+ <translation type="obsolete">Ð’Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ð²ÑÑ–Ñ… файлів, Ñкі належать віртуальній машині, наразі вимкнено Ð´Ð»Ñ Windows/x64 Ð·Ð°Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð±Ñ–Ð³Ð°Ð½Ð½Ñ ÐºÑ€Ð°Ñ…Ñ–Ð². Це буде виправлено в наÑтупному випуÑку.</translation>
</message>
<message>
<source>&lt;p&gt;Note that the storage unit of this medium will not be deleted and that it will be possible to use it later again.&lt;/p&gt;</source>
@@ -8730,7 +9333,71 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<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>&lt;p&gt;USB 2.0 наразі ввімкнено Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— віртуальної машини. Однак потрібно вÑтановити &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Будь лаÑка, вÑтановіть пакунок доповнень з Ñайту звантажень VirtualBox. ПіÑÐ»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ зможете перезапуÑтити USB 2.0. Це буде вимкнено протÑгом ÑкаÑуваннÑм змін поточних налаштувань.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;USB 2.0 наразі ввімкнено Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— віртуальної машини. Однак потрібно вÑтановити &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Будь лаÑка, вÑтановіть пакунок доповнень з Ñайту звантажень VirtualBox. ПіÑÐ»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ зможете перезапуÑтити USB 2.0. Це буде вимкнено протÑгом ÑкаÑуваннÑм змін поточних налаштувань.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -8844,7 +9511,7 @@ p, li { white-space: pre-wrap; }
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>Спільні теки</translation>
+ <translation type="obsolete">Спільні теки</translation>
</message>
</context>
<context>
@@ -8915,7 +9582,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>D&amp;iscard</source>
- <translation>Ві&amp;дкинути</translation>
+ <translation type="obsolete">Ві&amp;дкинути</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -9129,6 +9796,22 @@ p, li { white-space: pre-wrap; }
<source>Show Statusbar</source>
<translation>Показувати Ñмужку Ñтану</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished">Відкинути</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -9358,6 +10041,14 @@ p, li { white-space: pre-wrap; }
<source> (%1 ago)</source>
<translation> (%1 тому)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_xx_YY.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_xx_YY.ts
index 7bfa8847e..dac3ad2ae 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_xx_YY.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_xx_YY.ts
@@ -385,11 +385,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -555,11 +636,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation type="unfinished"></translation>
@@ -683,6 +759,26 @@
<comment>details report</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -719,6 +815,10 @@
<source>Restore Defaults</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -854,6 +954,10 @@
<source>First Run Wizard</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -927,41 +1031,6 @@
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1360,6 +1429,57 @@
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1428,26 +1548,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Left Shift</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Right Shift</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Left Ctrl</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Right Ctrl</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Left Alt</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Right Alt</source>
<translation type="unfinished"></translation>
</message>
@@ -1494,6 +1594,10 @@
<source>Restore Defaults</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -1628,11 +1732,6 @@
<translation></translation>
</message>
<message>
- <source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
- <comment>Virtualization Stuff LED</comment>
- <translation></translation>
- </message>
- <message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
<translation></translation>
@@ -1653,6 +1752,11 @@
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -1827,7 +1931,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1905,6 +2013,10 @@
<source>Show At &amp;Top Of Screen</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -1954,10 +2066,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>A&amp;dvanced</source>
<translation type="unfinished"></translation>
</message>
@@ -1993,6 +2101,42 @@
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsParallel</name>
@@ -2312,10 +2456,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
@@ -2551,6 +2691,60 @@
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -2724,6 +2918,32 @@
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -2849,7 +3069,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -2963,6 +3183,21 @@
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3008,85 +3243,126 @@
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage1</name>
<message>
- <source>Welcome to the Create New Virtual Disk Wizard!</source>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <source>Create</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage2</name>
<message>
- <source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
+ <source>Copy Virtual Disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Storage Type</source>
+ <source>Copy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Dynamically expanding storage</source>
+ <source>Welcome to the virtual disk copying wizard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Fixed-size storage</source>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hard Disk Storage Type</source>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage3</name>
<message>
- <source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Location</source>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Size</source>
+ <source>Welcome to the virtual disk creation wizard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Virtual Disk Location and Size</source>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Select a file for the new hard disk image file</source>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hard disk images (*.vdi)</source>
+ <source>Virtual disk file type</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UINewHDWzdPage4</name>
<message>
- <source>You are going to create a new virtual hard disk with the following parameters:</source>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select a file for the new hard disk image file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3094,11 +3370,28 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>%1 B</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Type</source>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
<comment>summary</comment>
<translation type="unfinished"></translation>
</message>
@@ -3112,8 +3405,40 @@
<comment>summary</comment>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
<message>
- <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -3123,6 +3448,10 @@
<source>Create New Virtual Machine</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -3330,183 +3659,198 @@
</message>
</context>
<context>
- <name>UIVMCloseDialog</name>
+ <name>UISettingsDialogGlobal</name>
<message>
- <source>Close Virtual Machine</source>
+ <source>General</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You want to:</source>
+ <source>Input</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Saves the current execution state of the virtual machine to the physical hard disk of the host PC.&lt;/p&gt;&lt;p&gt;Next time this machine is started, it will be restored from the saved state and continue execution from the same place you saved it at, which will let you continue your work immediately.&lt;/p&gt;&lt;p&gt;Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.&lt;/p&gt;</source>
+ <source>Update</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Save the machine state</source>
+ <source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Sends the ACPI Power Button press event to the virtual machine.&lt;/p&gt;&lt;p&gt;Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.&lt;/p&gt;&lt;p&gt;If the machine doesn&apos;t respond to this action then the guest operating system may be misconfigured or doesn&apos;t understand ACPI Power Button events at all. In this case you should select the &lt;b&gt;Power off the machine&lt;/b&gt; action to stop virtual machine execution.&lt;/p&gt;</source>
+ <source>USB</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>S&amp;end the shutdown signal</source>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Turns off the virtual machine.&lt;/p&gt;&lt;p&gt;Note that this action will stop machine execution immediately so that the guest operating system running inside it will not be able to perform a clean shutdown procedure which may result in &lt;i&gt;data loss&lt;/i&gt; inside the virtual machine. Selecting this action is recommended only if the virtual machine does not respond to the &lt;b&gt;Send the shutdown signal&lt;/b&gt; action.&lt;/p&gt;</source>
+ <source>Extensions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Power off the machine</source>
+ <source>VirtualBox - %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Restore the machine state stored in the current snapshot</source>
+ <source>Proxy</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
<message>
- <source>&lt;p&gt;When checked, the machine will be returned to the state stored in the current snapshot after it is turned off. This is useful if you are sure that you want to discard the results of your last sessions and start again at that snapshot.&lt;/p&gt;</source>
+ <source>General</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Restore current snapshot &apos;%1&apos;</source>
+ <source>System</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UIVMDesktop</name>
<message>
- <source>&amp;Details</source>
+ <source>Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Snapshots</source>
+ <source>Storage</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UIVMListView</name>
<message>
- <source>Inaccessible</source>
+ <source>Audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;nobr&gt;%1&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;%2 since %3&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Session %4&lt;/nobr&gt;</source>
- <comment>VM tooltip (name, last state change, session state)</comment>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;Inaccessible since %2&lt;/nobr&gt;</source>
- <comment>Inaccessible VM tooltip (name, last state change)</comment>
+ <source>Ports</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UIVMPreviewWindow</name>
<message>
- <source>Update Disabled</source>
+ <source>Serial Ports</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Every 0.5 s</source>
+ <source>Parallel Ports</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Every 1 s</source>
+ <source>USB</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Every 2 s</source>
+ <source>Shared Folders</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Every 5 s</source>
+ <source>%1 - %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UIVMCloseDialog</name>
<message>
- <source>Every 10 s</source>
+ <source>Close Virtual Machine</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No Preview</source>
+ <source>You want to:</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>UIVMSettingsDlg</name>
<message>
- <source>General</source>
+ <source>&lt;p&gt;Saves the current execution state of the virtual machine to the physical hard disk of the host PC.&lt;/p&gt;&lt;p&gt;Next time this machine is started, it will be restored from the saved state and continue execution from the same place you saved it at, which will let you continue your work immediately.&lt;/p&gt;&lt;p&gt;Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>System</source>
+ <source>&amp;Save the machine state</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Display</source>
+ <source>&lt;p&gt;Sends the ACPI Power Button press event to the virtual machine.&lt;/p&gt;&lt;p&gt;Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.&lt;/p&gt;&lt;p&gt;If the machine doesn&apos;t respond to this action then the guest operating system may be misconfigured or doesn&apos;t understand ACPI Power Button events at all. In this case you should select the &lt;b&gt;Power off the machine&lt;/b&gt; action to stop virtual machine execution.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Storage</source>
+ <source>S&amp;end the shutdown signal</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Audio</source>
+ <source>&lt;p&gt;Turns off the virtual machine.&lt;/p&gt;&lt;p&gt;Note that this action will stop machine execution immediately so that the guest operating system running inside it will not be able to perform a clean shutdown procedure which may result in &lt;i&gt;data loss&lt;/i&gt; inside the virtual machine. Selecting this action is recommended only if the virtual machine does not respond to the &lt;b&gt;Send the shutdown signal&lt;/b&gt; action.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network</source>
+ <source>&amp;Power off the machine</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Ports</source>
+ <source>Restore the machine state stored in the current snapshot</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Serial Ports</source>
+ <source>&lt;p&gt;When checked, the machine will be returned to the state stored in the current snapshot after it is turned off. This is useful if you are sure that you want to discard the results of your last sessions and start again at that snapshot.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Parallel Ports</source>
+ <source>&amp;Restore current snapshot &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UIVMDesktop</name>
<message>
- <source>USB</source>
+ <source>&amp;Details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Shared Folders</source>
+ <source>&amp;Snapshots</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UIVMListView</name>
<message>
- <source>%1 - %2</source>
+ <source>Inaccessible</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <source>&lt;nobr&gt;%1&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;%2 since %3&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;Session %4&lt;/nobr&gt;</source>
+ <comment>VM tooltip (name, last state change, session state)</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <source>&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;br&gt;&lt;/nobr&gt;&lt;nobr&gt;Inaccessible since %2&lt;/nobr&gt;</source>
+ <comment>Inaccessible VM tooltip (name, last state change)</comment>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UIVMPreviewWindow</name>
<message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <source>Update Disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>at most one supported</source>
+ <source>Every 0.5 s</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>up to %1 supported</source>
+ <source>Every 1 s</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <source>Every 2 s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Every 5 s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Every 10 s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No Preview</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -3631,6 +3975,14 @@
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxEmptyFileSelector</name>
@@ -4247,11 +4599,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Adapter %1</source>
- <comment>network</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Checking...</source>
<comment>medium</comment>
<translation type="unfinished"></translation>
@@ -4630,21 +4977,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>SAS</source>
<comment>StorageBus</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation type="unfinished"></translation>
@@ -4834,6 +5171,61 @@
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -4973,18 +5365,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Location</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Type (Format)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Attached to</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Checking accessibility</source>
<translation type="unfinished"></translation>
</message>
@@ -5050,34 +5430,59 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: Virtual Disk</comment>
+ <source>CD/DVD-ROM disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: CD/DVD Image</comment>
+ <source>hard disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Attached to</source>
- <comment>VMM: Floppy Image</comment>
+ <source>floppy disk</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>CD/DVD-ROM disk</source>
+ <source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hard disk</source>
+ <source>Type:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>floppy disk</source>
+ <source>Location:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>All %1 images (%2)</source>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -5101,13 +5506,6 @@
</message>
</context>
<context>
- <name>VBoxNetworkDialog</name>
- <message>
- <source>Network Adapters</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxOSTypeSelectorWidget</name>
<message>
<source>Operating &amp;System:</source>
@@ -5624,10 +6022,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
<translation type="unfinished"></translation>
</message>
@@ -5720,10 +6114,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restore</source>
<translation type="unfinished"></translation>
</message>
@@ -6050,22 +6440,75 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>VBoxSFDialog</name>
<message>
- <source>Shared Folders</source>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -6120,10 +6563,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>D&amp;iscard</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Discard the saved state of the selected virtual machine</source>
<translation type="unfinished"></translation>
</message>
@@ -6299,6 +6738,22 @@
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSnapshotDetailsDlg</name>
@@ -6425,6 +6880,14 @@
<source> (%1 ago)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_CN.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_CN.ts
index 9456b4e60..26152fd40 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_CN.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_CN.ts
@@ -526,11 +526,92 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Session I&amp;nformation</source>
+ <source>Enable R&amp;emote Display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable R&amp;emote Display</source>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">设置(&amp;S)...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -696,11 +777,6 @@
<translation type="unfinished">Host-only 网络, &apos;%1&apos;</translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Adapter %1</source>
<comment>details report (network)</comment>
<translation type="unfinished"></translation>
@@ -824,6 +900,26 @@
<comment>details report</comment>
<translation type="unfinished">æè¿°</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -1054,6 +1150,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Write legacy OVF 0.9</source>
<translation type="obsolete">用传统的 OVF 0.9 æ ¼å¼ä¿å­˜(&amp;W)</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -1405,6 +1505,10 @@ p, li { white-space: pre-wrap; }
<source>Cancel</source>
<translation type="obsolete">å–æ¶ˆ</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">å¯åЍ</translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -1478,41 +1582,6 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">常规</translation>
- </message>
- <message>
- <source>Input</source>
- <translation type="unfinished">热键</translation>
- </message>
- <message>
- <source>Update</source>
- <translation type="unfinished">æ›´æ–°</translation>
- </message>
- <message>
- <source>Language</source>
- <translation type="unfinished">语言</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">网络</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation type="unfinished">VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1941,6 +2010,57 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -2010,23 +2130,23 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Left Shift</source>
- <translation>Left Shift</translation>
+ <translation type="obsolete">Left Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>Right Shift</translation>
+ <translation type="obsolete">Right Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>Left Ctrl</translation>
+ <translation type="obsolete">Left Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>Right Ctrl</translation>
+ <translation type="obsolete">Right Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>Left Alt</translation>
+ <translation type="obsolete">Left Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -2231,6 +2351,10 @@ p, li { white-space: pre-wrap; }
<source>&amp;Import &gt;</source>
<translation type="obsolete">导入(&amp;I) &gt;</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -2375,7 +2499,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>指示该虚拟电脑所用硬件虚拟指令的当å‰çжæ€:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">指示该虚拟电脑所用硬件虚拟指令的当å‰çжæ€:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -2398,6 +2522,11 @@ p, li { white-space: pre-wrap; }
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -2596,9 +2725,13 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">您已å¯ç”¨äº†2D视频加速。但该功能目å‰åªèƒ½ç”¨äºŽè™šæ‹Ÿç”µè„‘内的windows系统,因此该特性将被ç¦ç”¨ã€‚</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsGeneral</name>
@@ -2842,6 +2975,10 @@ p, li { white-space: pre-wrap; }
<source>Show At &amp;Top Of Screen</source>
<translation>在å±å¹•顶部显示</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">您已ç»ä¸ºè¯¥è™šæ‹Ÿç”µè„‘选择了一个64ä½çš„æ“ä½œç³»ç»Ÿã€‚è¯¥æ“作系统需è¦ç¡¬ä»¶è™šæ‹ŸæŒ‡ä»¤ (VT-x/AMD-V) çš„æ”¯æŒæ–¹èƒ½è¿è¡Œï¼Œå› æ­¤è¯¥ç‰¹æ€§å°†è¢«è‡ªåЍå¯ç”¨ã€‚</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -3023,7 +3160,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>为 &lt;b&gt;Bridged Adapter&lt;/b&gt; å’Œ &lt;b&gt;Host-only Adapter&lt;/b&gt; 选择一个其所è¦è¿žæŽ¥çš„网络界é¢ï¼Œä»¥åŠä¸º &lt;b&gt;Internal Network&lt;/b&gt; 指定一个界é¢åç§°.</translation>
+ <translation type="obsolete">为 &lt;b&gt;Bridged Adapter&lt;/b&gt; å’Œ &lt;b&gt;Host-only Adapter&lt;/b&gt; 选择一个其所è¦è¿žæŽ¥çš„网络界é¢ï¼Œä»¥åŠä¸º &lt;b&gt;Internal Network&lt;/b&gt; 指定一个界é¢åç§°.</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -3049,6 +3186,42 @@ p, li { white-space: pre-wrap; }
<source>&amp;Port Forwarding</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetworkDetails</name>
@@ -3575,7 +3748,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>没有为 &lt;i&gt;%1&lt;/i&gt; 指定虚拟硬盘。</translation>
+ <translation type="obsolete">没有为 &lt;i&gt;%1&lt;/i&gt; 指定虚拟硬盘。</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -3841,6 +4014,60 @@ p, li { white-space: pre-wrap; }
<source>Choose a virtual floppy disk file...</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -4022,6 +4249,32 @@ p, li { white-space: pre-wrap; }
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -4147,7 +4400,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished">&lt;nobr&gt;State: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <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>
+ <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>
</context>
@@ -4261,6 +4514,21 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -4306,7 +4574,7 @@ p, li { white-space: pre-wrap; }
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>创建新的虚拟硬盘</translation>
@@ -4398,7 +4666,7 @@ as the size of the virtual hard disk.&lt;/p&gt;</source>
</message>
<message>
<source>Summary</source>
- <translation type="obsolete">摘è¦</translation>
+ <translation type="unfinished">摘è¦</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 Bytes&lt;/nobr&gt;</source>
@@ -4414,7 +4682,7 @@ as the size of the virtual hard disk.&lt;/p&gt;</source>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="obsolete">选择一个文件作为新的虚拟硬盘</translation>
+ <translation type="unfinished">选择一个文件作为新的虚拟硬盘</translation>
</message>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk image you want to create.&lt;/p&gt;
@@ -4468,12 +4736,12 @@ time depending on the image size and the write performance of your harddisk.&lt;
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="obsolete">ä½ç½®</translation>
+ <translation type="unfinished">ä½ç½®</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="obsolete">大å°</translation>
+ <translation type="unfinished">大å°</translation>
</message>
<message>
<source>Bytes</source>
@@ -4532,108 +4800,260 @@ time depending on the image size and the write performance of your harddisk.&lt;
<source>If the above settings are correct, press the &lt;b&gt;Finish&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
<translation type="obsolete">如果上é¢çš„设置正确,å•击&lt;b&gt;完æˆ&lt;/b&gt; 按钮,一个新的虚拟硬盘将会被建立.</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
<message>
- <source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation type="unfinished">欢迎使用新建虚拟硬盘å‘导!</translation>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
<message>
- <source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+ <source>&amp;Location</source>
+ <translation type="unfinished">ä½ç½®(&amp;L)</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">大å°(&amp;S)</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>UINewHDWzdPage2</name>
+ <name>UINewHDWizardPageWelcome</name>
<message>
- <source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;é€‰æ‹©ä½ è¦æ–°å»ºçš„虚拟硬盘类型.&lt;/p&gt;&lt;p&gt;其中 &lt;b&gt;åŠ¨æ€æ‰©å±•&lt;/b&gt; 类型最åˆåªéœ€å ç”¨éžå¸¸å°çš„物ç†ç¡¬ç›˜ç©ºé—´ã€‚ç„¶åŽä¸æ–­å¢žåŠ (æœ€å¤§åˆ°å½“å‰æŒ‡å®šçš„大å°)ï¼Œå…·ä½“å¤§å°æ ¹æ®è™šæ‹Ÿç”µè„‘的实际需求动æ€åˆ†é…。&lt;/p&gt;&lt;p&gt;其中 &lt;b&gt;固定大å°&lt;/b&gt; ç±»åž‹ä¸€æ—¦å»ºç«‹å°±éœ€åˆ†é…æŒ‡å®šå¤§å°çš„物ç†ç£ç›˜ç©ºé—´ç»™è¯¥è™šæ‹Ÿç¡¬ç›˜ä½¿ç”¨ï¼Œæ€§èƒ½ä¸Šæœ‰ä¸€å®šä¼˜åŠ¿ã€‚å»ºç«‹è¿™ç§ç±»åž‹çš„虚拟硬盘需花费较多的时间.&lt;/p&gt;</translation>
+ <source>Welcome to the Create New Virtual Disk Wizard!</source>
+ <translation type="obsolete">欢迎使用新建虚拟硬盘å‘导!</translation>
</message>
<message>
- <source>Storage Type</source>
+ <source>Virtual disk to copy</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWzdPage2</name>
+ <message>
+ <source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
+ <translation type="obsolete">&lt;p&gt;é€‰æ‹©ä½ è¦æ–°å»ºçš„虚拟硬盘类型.&lt;/p&gt;&lt;p&gt;其中 &lt;b&gt;åŠ¨æ€æ‰©å±•&lt;/b&gt; 类型最åˆåªéœ€å ç”¨éžå¸¸å°çš„物ç†ç¡¬ç›˜ç©ºé—´ã€‚ç„¶åŽä¸æ–­å¢žåŠ (æœ€å¤§åˆ°å½“å‰æŒ‡å®šçš„大å°)ï¼Œå…·ä½“å¤§å°æ ¹æ®è™šæ‹Ÿç”µè„‘的实际需求动æ€åˆ†é…。&lt;/p&gt;&lt;p&gt;其中 &lt;b&gt;固定大å°&lt;/b&gt; ç±»åž‹ä¸€æ—¦å»ºç«‹å°±éœ€åˆ†é…æŒ‡å®šå¤§å°çš„物ç†ç£ç›˜ç©ºé—´ç»™è¯¥è™šæ‹Ÿç¡¬ç›˜ä½¿ç”¨ï¼Œæ€§èƒ½ä¸Šæœ‰ä¸€å®šä¼˜åŠ¿ã€‚å»ºç«‹è¿™ç§ç±»åž‹çš„虚拟硬盘需花费较多的时间.&lt;/p&gt;</translation>
+ </message>
+ <message>
<source>&amp;Dynamically expanding storage</source>
- <translation type="unfinished">åŠ¨æ€æ‰©å±•(&amp;D)</translation>
+ <translation type="obsolete">åŠ¨æ€æ‰©å±•(&amp;D)</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation type="unfinished">固定大å°(&amp;F)</translation>
+ <translation type="obsolete">固定大å°(&amp;F)</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation type="unfinished">虚拟硬盘类型</translation>
+ <translation type="obsolete">虚拟硬盘类型</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;å•击&lt;b&gt;选择&lt;/b&gt;æŒ‰é’®ç”¨æ¥æŒ‡å®šä¿å­˜è™šæ‹Ÿç¡¬ç›˜çš„æ–‡ä»¶ååŠå…¶ä½ç½®ï¼Œæˆ–者也å¯ç›´æŽ¥åœ¨è¾“入框中输入.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;å•击&lt;b&gt;选择&lt;/b&gt;æŒ‰é’®ç”¨æ¥æŒ‡å®šä¿å­˜è™šæ‹Ÿç¡¬ç›˜çš„æ–‡ä»¶ååŠå…¶ä½ç½®ï¼Œæˆ–者也å¯ç›´æŽ¥åœ¨è¾“入框中输入.&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation type="unfinished">ä½ç½®(&amp;L)</translation>
+ <translation type="obsolete">ä½ç½®(&amp;L)</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;p&gt;以兆(M)为å•使Œ‡å®šè¦æ–°å»ºçš„虚拟硬盘大å°. &lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;以兆(M)为å•使Œ‡å®šè¦æ–°å»ºçš„虚拟硬盘大å°. &lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation type="unfinished">大å°(&amp;S)</translation>
+ <translation type="obsolete">大å°(&amp;S)</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation type="unfinished">虚拟硬盘所在ä½ç½®å’Œç©ºé—´å¤§å°</translation>
+ <translation type="obsolete">虚拟硬盘所在ä½ç½®å’Œç©ºé—´å¤§å°</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation type="unfinished">选择一个文件作为新的虚拟硬盘</translation>
+ <translation type="obsolete">选择一个文件作为新的虚拟硬盘</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation type="unfinished">虚拟硬盘文件 (*.vdi)</translation>
- </message>
- <message>
- <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">虚拟硬盘文件 (*.vdi)</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation type="unfinished">现在将根æ®ä¸‹é¢æ‰€åˆ—傿•°åˆ›å»ºä¸€ä¸ªæ–°çš„虚拟硬盘:</translation>
+ <translation type="obsolete">现在将根æ®ä¸‹é¢æ‰€åˆ—傿•°åˆ›å»ºä¸€ä¸ªæ–°çš„虚拟硬盘:</translation>
</message>
<message>
<source>Summary</source>
- <translation type="unfinished">摘è¦</translation>
- </message>
- <message>
- <source>%1 B</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">摘è¦</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation type="unfinished">类型</translation>
+ <translation type="obsolete">类型</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation type="unfinished">ä½ç½®</translation>
+ <translation type="obsolete">ä½ç½®</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation type="unfinished">大å°</translation>
- </message>
- <message>
- <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">大å°</translation>
</message>
</context>
<context>
@@ -4859,6 +5279,10 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<source>&amp;Use existing hard disk</source>
<translation type="obsolete">使用现有的虚拟硬盘(&amp;U)</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -5088,6 +5512,104 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">常规</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation type="unfinished">热键</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished">æ›´æ–°</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation type="unfinished">语言</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">网络</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation type="unfinished">VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">常规</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation type="unfinished">系统</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation type="unfinished">显示</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished">声音</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">网络</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation type="unfinished">端å£</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation type="unfinished">串å£</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation type="unfinished">å¹¶å£</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation type="unfinished">æ•°æ®ç©ºé—´</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished">%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">您已ç»ä¸ºè¯¥è™šæ‹Ÿç”µè„‘选择了一个64ä½çš„æ“ä½œç³»ç»Ÿã€‚è¯¥æ“作系统需è¦ç¡¬ä»¶è™šæ‹ŸæŒ‡ä»¤ (VT-x/AMD-V) çš„æ”¯æŒæ–¹èƒ½è¿è¡Œï¼Œå› æ­¤è¯¥ç‰¹æ€§å°†è¢«è‡ªåЍå¯ç”¨ã€‚</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">您已å¯ç”¨äº†2D视频加速。但该功能目å‰åªèƒ½ç”¨äºŽè™šæ‹Ÿç”µè„‘内的windows系统,因此该特性将被ç¦ç”¨ã€‚</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -5226,81 +5748,6 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation type="unfinished">常规</translation>
- </message>
- <message>
- <source>System</source>
- <translation type="unfinished">系统</translation>
- </message>
- <message>
- <source>Display</source>
- <translation type="unfinished">显示</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Audio</source>
- <translation type="unfinished">声音</translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished">网络</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation type="unfinished">端å£</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation type="unfinished">串å£</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation type="unfinished">å¹¶å£</translation>
- </message>
- <message>
- <source>USB</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation type="unfinished">æ•°æ®ç©ºé—´</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation type="unfinished">%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation type="unfinished">您已ç»ä¸ºè¯¥è™šæ‹Ÿç”µè„‘选择了一个64ä½çš„æ“ä½œç³»ç»Ÿã€‚è¯¥æ“作系统需è¦ç¡¬ä»¶è™šæ‹ŸæŒ‡ä»¤ (VT-x/AMD-V) çš„æ”¯æŒæ–¹èƒ½è¿è¡Œï¼Œå› æ­¤è¯¥ç‰¹æ€§å°†è¢«è‡ªåЍå¯ç”¨ã€‚</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation type="unfinished">您已å¯ç”¨äº†2D视频加速。但该功能目å‰åªèƒ½ç”¨äºŽè™šæ‹Ÿç”µè„‘内的windows系统,因此该特性将被ç¦ç”¨ã€‚</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -5552,6 +5999,14 @@ Version %1</translation>
<source>Hard Disk Controller (SAS)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxCloseVMDlg</name>
@@ -7523,7 +7978,7 @@ Version %1</translation>
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>网络连接 %1</translation>
+ <translation type="obsolete">网络连接 %1</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;Type&amp;nbsp;(Format):&amp;nbsp;&amp;nbsp;%2&amp;nbsp;(%3)&lt;/nobr&gt;</source>
@@ -7977,21 +8432,11 @@ Version %1</translation>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE network, &apos;%1&apos;</source>
- <comment>details report (network)</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>SAS</source>
<comment>StorageBus</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <source>VDE Adapter</source>
- <comment>NetworkAttachmentType</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>LsiLogic SAS</source>
<comment>StorageControllerType</comment>
<translation type="unfinished"></translation>
@@ -8181,6 +8626,61 @@ Version %1</translation>
<comment>DiskType</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -8927,15 +9427,15 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>Location</source>
- <translation>ä½ç½®</translation>
+ <translation type="obsolete">ä½ç½®</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>类型 (æ ¼å¼)</translation>
+ <translation type="obsolete">类型 (æ ¼å¼)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>分é…到</translation>
+ <translation type="obsolete">分é…到</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -9017,17 +9517,17 @@ to the system default language.&lt;/qt&gt;
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>分é…到</translation>
+ <translation type="obsolete">分é…到</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>分é…到</translation>
+ <translation type="obsolete">分é…到</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>分é…到</translation>
+ <translation type="obsolete">分é…到</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -9045,6 +9545,46 @@ to the system default language.&lt;/qt&gt;
<source>All %1 images (%2)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">ä½ç½®:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -9104,7 +9644,7 @@ to the system default language.&lt;/qt&gt;
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>网络连接</translation>
+ <translation type="obsolete">网络连接</translation>
</message>
</context>
<context>
@@ -9966,7 +10506,7 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>无法访问电脑上的USB设备,因为当å‰ä¸ç®¡æ˜¯USB文件系统(usbfs)或Dbuså’ŒhalæœåŠ¡éƒ½æ— æ³•ä½¿ç”¨ã€‚å¦‚æžœæ‚¨æƒ³åœ¨è™šæ‹Ÿç”µè„‘å†…ä½¿ç”¨USB设备,则必须先修å¤å®ƒä»¬ï¼Œç„¶åŽå†é‡å¯æœ¬ç¨‹åº.</translation>
+ <translation type="obsolete">无法访问电脑上的USB设备,因为当å‰ä¸ç®¡æ˜¯USB文件系统(usbfs)或Dbuså’ŒhalæœåŠ¡éƒ½æ— æ³•ä½¿ç”¨ã€‚å¦‚æžœæ‚¨æƒ³åœ¨è™šæ‹Ÿç”µè„‘å†…ä½¿ç”¨USB设备,则必须先修å¤å®ƒä»¬ï¼Œç„¶åŽå†é‡å¯æœ¬ç¨‹åº.</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -10091,7 +10631,7 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;您确定è¦å°†è™šæ‹Ÿç”µè„‘æ¢å¤åˆ°ç”Ÿæˆå¤‡ä»½ &lt;b&gt;%1&lt;/b&gt; 时的状æ€? 这将导致从最近一次备份到现在虚拟电脑内的所有å˜åŒ–都被完全清空(存放在数æ®ç©ºé—´çš„内容除外), 请注æ„:该æ“作一旦执行就无法撤销.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;您确定è¦å°†è™šæ‹Ÿç”µè„‘æ¢å¤åˆ°ç”Ÿæˆå¤‡ä»½ &lt;b&gt;%1&lt;/b&gt; 时的状æ€? 这将导致从最近一次备份到现在虚拟电脑内的所有å˜åŒ–都被完全清空(存放在数æ®ç©ºé—´çš„内容除外), 请注æ„:该æ“作一旦执行就无法撤销.&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -10465,15 +11005,75 @@ to the system default language.&lt;/qt&gt;
<translation type="unfinished"></translation>
</message>
<message>
- <source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
+ <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 type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <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>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -10600,7 +11200,7 @@ to the system default language.&lt;/qt&gt;
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>æ•°æ®ç©ºé—´</translation>
+ <translation type="obsolete">æ•°æ®ç©ºé—´</translation>
</message>
<message>
<source>OK</source>
@@ -10731,11 +11331,11 @@ to the system default language.&lt;/qt&gt;
</message>
<message>
<source>D&amp;iscard</source>
- <translation>清除(&amp;i)</translation>
+ <translation type="obsolete">清除(&amp;i)</translation>
</message>
<message>
<source>Discard</source>
- <translation type="obsolete">清除</translation>
+ <translation type="unfinished">清除</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -11037,6 +11637,18 @@ to the system default language.&lt;/qt&gt;
<source>Show Statusbar</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -11448,6 +12060,14 @@ to access it from a Linux OS. This feature requires Guest Additions.&lt;/qt&gt;<
<source> (%1 ago)</source>
<translation> (%1 之å‰)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_TW.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_TW.ts
index 07c7cfb7b..7bb9848ae 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_TW.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_TW.ts
@@ -386,12 +386,97 @@
</message>
<message>
<source>Session I&amp;nformation</source>
- <translation>工作階段資訊(&amp;N)</translation>
+ <translation type="obsolete">工作階段資訊(&amp;N)</translation>
</message>
<message>
<source>Enable R&amp;emote Display</source>
<translation>啟用é ç«¯é¡¯ç¤º(&amp;E)</translation>
</message>
+ <message>
+ <source>&amp;Settings...</source>
+ <translation type="unfinished">設定值(&amp;S)...</translation>
+ </message>
+ <message>
+ <source>Manage the virtual machine settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Session I&amp;nformation...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizard</name>
+ <message>
+ <source>Clone a virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage1</name>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual machine clone wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UICloneVMWizardPage2</name>
+ <message>
+ <source>Current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Current machine and all child states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All states</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cloning Configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose which parts of the virtual machine should be cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine state&lt;/b&gt;, only the current state of the virtual machine is cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;Current machine and all child states&lt;/b&gt; the current state of the virtual machine and any states of child snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you select &lt;b&gt;All states&lt;/b&gt;, the current machine state and all snapshots are cloned.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDescriptionPagePrivate</name>
@@ -557,7 +642,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE 網路, 「%1ã€</translation>
+ <translation type="obsolete">VDE 網路, 「%1ã€</translation>
</message>
<message>
<source>Adapter %1</source>
@@ -683,6 +768,26 @@
<comment>details report</comment>
<translation>æè¿°</translation>
</message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic driver, &apos;%1&apos; {&amp;nbsp;%2&amp;nbsp;}</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIDownloader</name>
@@ -719,6 +824,10 @@
<source>Restore Defaults</source>
<translation>還原é è¨­å€¼</translation>
</message>
+ <message>
+ <source>Export</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIExportApplianceWzdPage1</name>
@@ -854,6 +963,10 @@
<source>First Run Wizard</source>
<translation>首次執行精éˆ</translation>
</message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIFirstRunWzdPage1</name>
@@ -927,41 +1040,6 @@
</message>
</context>
<context>
- <name>UIGLSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>一般</translation>
- </message>
- <message>
- <source>Input</source>
- <translation>輸入</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>æ›´æ–°</translation>
- </message>
- <message>
- <source>Language</source>
- <translation>語言</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>網路</translation>
- </message>
- <message>
- <source>Extensions</source>
- <translation>æ“´å……</translation>
- </message>
- <message>
- <source>VirtualBox - %1</source>
- <translation>VirtualBox - %1</translation>
- </message>
-</context>
-<context>
<name>UIGlobalSettingsExtension</name>
<message>
<source>&amp;Extension Packages:</source>
@@ -1360,6 +1438,57 @@
</message>
</context>
<context>
+ <name>UIGlobalSettingsProxy</name>
+ <message>
+ <source>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Enable proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ho&amp;st:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy host.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the proxy port.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked the authentication supplied will be used with the proxy server.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Use authentication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>User &amp;name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the user name used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pass&amp;word:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changes the password used for authentication.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIGlobalSettingsUpdate</name>
<message>
<source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source>
@@ -1429,23 +1558,23 @@
</message>
<message>
<source>Left Shift</source>
- <translation>å·¦å´ Shift</translation>
+ <translation type="obsolete">å·¦å´ Shift</translation>
</message>
<message>
<source>Right Shift</source>
- <translation>å³å´ Shift</translation>
+ <translation type="obsolete">å³å´ Shift</translation>
</message>
<message>
<source>Left Ctrl</source>
- <translation>å·¦å´ Ctrl</translation>
+ <translation type="obsolete">å·¦å´ Ctrl</translation>
</message>
<message>
<source>Right Ctrl</source>
- <translation>å³å´ Ctrl</translation>
+ <translation type="obsolete">å³å´ Ctrl</translation>
</message>
<message>
<source>Left Alt</source>
- <translation>å·¦å´ Alt</translation>
+ <translation type="obsolete">å·¦å´ Alt</translation>
</message>
<message>
<source>Right Alt</source>
@@ -1494,6 +1623,10 @@
<source>Restore Defaults</source>
<translation>還原é è¨­å€¼</translation>
</message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIImportApplianceWzdPage1</name>
@@ -1630,7 +1763,7 @@
<message>
<source>Indicates the status of the hardware virtualization features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</source>
<comment>Virtualization Stuff LED</comment>
- <translation>指示這部虛擬機器使用的硬體虛擬化功能之狀態:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
+ <translation type="obsolete">指示這部虛擬機器使用的硬體虛擬化功能之狀態:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;</translation>
</message>
<message>
<source>&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;</source>
@@ -1653,6 +1786,11 @@
<source>&lt;hr&gt;The Remote Desktop Server is listening on port %1</source>
<translation>&lt;hr&gt;é ç«¯æ¡Œé¢ä¼ºæœå™¨æ­£åœ¨ç›£è½é€£æŽ¥åŸ  %1</translation>
</message>
+ <message>
+ <source>Indicates the status of different features used by this virtual machine:&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1:&lt;/b&gt;&amp;nbsp;%2&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%3:&lt;/b&gt;&amp;nbsp;%4&lt;/nobr&gt;&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%5:&lt;/b&gt;&amp;nbsp;%6%&lt;/nobr&gt;</source>
+ <comment>Virtualization Stuff LED</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineLogic</name>
@@ -1828,7 +1966,15 @@
</message>
<message>
<source>You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
- <translation>您已啟用作業系統的 3D 加速,其使用 WDDM 視訊驅動程å¼ã€‚ 為了最大效能,設定客體 VRAM 至少 &lt;b&gt;%1&lt;/b&gt;。</translation>
+ <translation type="obsolete">您已啟用作業系統的 3D 加速,其使用 WDDM 視訊驅動程å¼ã€‚ 為了最大效能,設定客體 VRAM 至少 &lt;b&gt;%1&lt;/b&gt;。</translation>
+ </message>
+ <message>
+ <source>you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. For maximal performance set the guest VRAM to at least &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="unfinished">您已啟用 2D 視訊加速。 由於 2D è¦–è¨ŠåŠ é€Ÿåªæ”¯æ´ Windows 客體,這個功能將åœç”¨ã€‚</translation>
</message>
</context>
<context>
@@ -1905,6 +2051,10 @@
<source>Show At &amp;Top Of Screen</source>
<translation>顯示在螢幕上方(&amp;T)</translation>
</message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="unfinished">您已é‡å°é€™éƒ¨ VM é¸å– 64 ä½å…ƒçš„客體作業系統類型。 如此的客體需è¦ç¡¬é«”虛擬化 (VT-x/AMD-V),這個功能將會自動啟用。</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsNetwork</name>
@@ -1955,7 +2105,7 @@
</message>
<message>
<source>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</source>
- <translation>é¸å–&lt;b&gt;橋接介é¢å¡&lt;/b&gt;或&lt;b&gt;「僅é™ä¸»æ©Ÿã€ä»‹é¢å¡&lt;/b&gt;附加的網路å¡å稱與&lt;b&gt;內部網路&lt;/b&gt;附加的網路å稱。</translation>
+ <translation type="obsolete">é¸å–&lt;b&gt;橋接介é¢å¡&lt;/b&gt;或&lt;b&gt;「僅é™ä¸»æ©Ÿã€ä»‹é¢å¡&lt;/b&gt;附加的網路å¡å稱與&lt;b&gt;內部網路&lt;/b&gt;附加的網路å稱。</translation>
</message>
<message>
<source>A&amp;dvanced</source>
@@ -1993,6 +2143,42 @@
<source>&amp;Port Forwarding</source>
<translation>連接埠轉é€(&amp;P)</translation>
</message>
+ <message>
+ <source>&amp;Promiscuous Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Properties:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no generic driver is selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the network adapter on the host system that traffic to and from this network card will go through.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter the name of the internal network that this network card will be connected to. You can create a new internal network by choosing a name which is not used by any other network cards in this virtual machine or others.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the virtual network adapter on the host system that traffic to and from this network card will go through. You can create and remove adapters using the global network settings in the virtual machine manager window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the driver to be used with this network card.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsParallel</name>
@@ -2313,7 +2499,7 @@
</message>
<message>
<source>No hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
- <translation>未é¸å– &lt;i&gt;%1&lt;/i&gt; 的硬碟。</translation>
+ <translation type="obsolete">未é¸å– &lt;i&gt;%1&lt;/i&gt; 的硬碟。</translation>
</message>
<message>
<source>&lt;i&gt;%1&lt;/i&gt; uses a medium that is already attached to &lt;i&gt;%2&lt;/i&gt;.</source>
@@ -2551,6 +2737,60 @@
<source>Choose a virtual floppy disk file...</source>
<translation>鏿“‡è™›æ“¬è»Ÿç¢Ÿæª”案...</translation>
</message>
+ <message>
+ <source>When checked, it suppresses unmounting the medium when the guest OS ejects it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Live CD/DVD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When checked, this marks the medium as non-rotational storage (SSD).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Solid-state drive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no name specified for controller at position &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>controller at position &lt;b&gt;%1&lt;/b&gt; uses the name that is already used by controller at position &lt;b&gt;%2&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>no hard disk is selected for &lt;i&gt;%1&lt;/i&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <comment>controller</comment>
+ <translation type="unfinished">æœ€å¤šæ”¯æ´ 1 個</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <comment>controllers</comment>
+ <translation type="unfinished">æœ€å¤šæ”¯æ´ %1 個</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="unfinished">您目å‰ä½¿ç”¨è¶…éŽ %1 晶片組所支æ´çš„存放控制器。 請在系統設定é ä¸­è®Šæ›´æ™¶ç‰‡çµ„類型或在存放設定é ä¸­æ¸›å°‘以下存放控制器的數é‡: %2。</translation>
+ </message>
+ <message>
+ <source>&amp;Port Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can&apos;t be less than the maximum used port number + 1.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsSystem</name>
@@ -2724,6 +2964,32 @@
<source>you have assigned ICH9 chipset type to this VM. It will not work properly unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
<translation>您已指派 ICH9 晶片組類型到此 VM。 除éžåŒæ™‚啟用 IO-APIC 功能å¦å‰‡å°‡ä¸æœƒå‹•作。 當您按下 [確定] æŒ‰éˆ•æŽ¥å— VM 設定值將會自動完æˆã€‚</translation>
</message>
+ <message>
+ <source>&amp;Execution Cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have set the processor execution cap to a low value. This can make the machine feel slow to respond.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="unfinished">您已啟用 USB HID (人性化介é¢è£ç½®)。 除éžåŒæ™‚啟用 USB 模擬å¦å‰‡é€™å°‡ä¸æœƒå‹•作。 當您按下 [確定] æŒ‰éˆ•æŽ¥å— VM 設定值時這將會自動完æˆã€‚</translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Min CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;qt&gt;%1%&lt;/qt&gt;</source>
+ <comment>Max CPU execution cap in %</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsUSB</name>
@@ -2850,7 +3116,11 @@
</message>
<message>
<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>USB 2.0 ç›®å‰åœ¨é€™éƒ¨è™›æ“¬æ©Ÿå™¨å•Ÿç”¨ã€‚ 然而這需è¦å®‰è£ &lt;b&gt;%1&lt;/b&gt;。 請從 VirtualBox ä¸‹è¼‰ç¶²ç«™å®‰è£æ“´å……包。 在此之後您將å¯ä»¥é‡æ–°å®‰è£ USB 2.0。 é™¤éžæ‚¨å–消目å‰è¨­å®šè®Šæ›´ï¼Œå¦å‰‡å°‡åœ¨æ­¤æœŸé–“åœç”¨ã€‚</translation>
+ <translation type="obsolete">USB 2.0 ç›®å‰åœ¨é€™éƒ¨è™›æ“¬æ©Ÿå™¨å•Ÿç”¨ã€‚ 然而這需è¦å®‰è£ &lt;b&gt;%1&lt;/b&gt;。 請從 VirtualBox ä¸‹è¼‰ç¶²ç«™å®‰è£æ“´å……包。 在此之後您將å¯ä»¥é‡æ–°å®‰è£ USB 2.0。 é™¤éžæ‚¨å–消目å‰è¨­å®šè®Šæ›´ï¼Œå¦å‰‡å°‡åœ¨æ­¤æœŸé–“åœç”¨ã€‚</translation>
+ </message>
+ <message>
+ <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>
</context>
<context>
@@ -2963,6 +3233,21 @@
</message>
</context>
<context>
+ <name>UIMediumTypeChangeDialog</name>
+ <message>
+ <source>Modify medium attributes</source>
+ <translation type="unfinished"></translation>
+ </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 type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose medium type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>UIMiniProcessWidgetAdditions</name>
<message>
<source>Cancel</source>
@@ -3008,113 +3293,303 @@
</message>
</context>
<context>
- <name>UINewHDWzd</name>
+ <name>UINewHDWizard</name>
<message>
<source>Create New Virtual Disk</source>
<translation>新建虛擬ç£ç¢Ÿ</translation>
</message>
+ <message>
+ <source>%1_copy</source>
+ <comment>copied virtual disk name</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy Virtual Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk copying wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to copy a virtual disk.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select the virtual disk which you would like to copy if it is not already selected. You can either choose one from the list or use the folder icon beside the list to select a virtual disk file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;VDI (VirtualBox Disk Image)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;MDK (Virtual Machine Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;HD (Virtual Hard Disk)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Welcome to the virtual disk creation wizard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This wizard will help you to create a new virtual disk for your virtual machine.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose the type of file that you would like to use for the new virtual disk. If you do not need to use it with other virtualization software you can leave this setting unchanged.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;dynamically allocated&lt;/b&gt; virtual disk file will only use space on your physical hard disk as it fills up, although it will not shrink again automatically when space on it is freed.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;A &lt;b&gt;fixed size&lt;/b&gt; virtual disk file may take longer to create on some systems but is often faster to use.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You can also choose to &lt;b&gt;split&lt;/b&gt; the virtual disk into several files of up to two gigabytes each. This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, some of which cannot handle very large files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Dynamically allocated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Fixed size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location and size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Virtual disk file location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the virtual disk data or type a file name in the entry field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select a file for the new hard disk image file</source>
+ <translation type="unfinished">é¸å–æ–°ç¡¬ç¢Ÿæ˜ åƒæª”的檔案</translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
+ <translation type="unfinished">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished">摘è¦</translation>
+ </message>
+ <message>
+ <source>You are going to create a new virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You are going to create a copied virtual disk with the following parameters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it the new virtual disk file will be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation type="unfinished">%1 B</translation>
+ </message>
+ <message>
+ <source>File type</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Details</source>
+ <comment>summary</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Location</source>
+ <comment>summary</comment>
+ <translation type="unfinished">ä½ç½®</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <comment>summary</comment>
+ <translation type="unfinished">大å°</translation>
+ </message>
</context>
<context>
- <name>UINewHDWzdPage1</name>
+ <name>UINewHDWizardPageFormat</name>
+ <message>
+ <source>File type</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageOptions</name>
+ <message>
+ <source>&amp;Location</source>
+ <translation type="unfinished">ä½ç½®(&amp;L)</translation>
+ </message>
+ <message>
+ <source>&amp;Size</source>
+ <translation type="unfinished">大å°(&amp;S)</translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageVariant</name>
+ <message>
+ <source>Storage details</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UINewHDWizardPageWelcome</name>
<message>
<source>Welcome to the Create New Virtual Disk Wizard!</source>
- <translation>歡迎使用新建虛擬ç£ç¢Ÿç²¾éˆ!</translation>
+ <translation type="obsolete">歡迎使用新建虛擬ç£ç¢Ÿç²¾éˆ!</translation>
</message>
<message>
<source>&lt;p&gt;This wizard will help you to create a new virtual hard disk for your virtual machine.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
- <translation>&lt;p&gt;這個精éˆå°‡å”助您新建一個虛擬機器的虛擬ç£ç¢Ÿã€‚&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;這個精éˆå°‡å”助您新建一個虛擬機器的虛擬ç£ç¢Ÿã€‚&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Virtual disk to copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Choose a virtual hard disk file...</source>
+ <translation type="unfinished">鏿“‡è™›æ“¬ç¡¬ç¢Ÿæª”案...</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage2</name>
<message>
<source>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;é¸å–您想è¦å»ºç«‹çš„虛擬硬碟類型。&lt;/p&gt;&lt;p&gt;&lt;b&gt;動態延伸存放&lt;/b&gt;最åˆåœ¨æ‚¨çš„實體硬碟佔有éžå¸¸å°çš„空間é‡ã€‚ 它將會動態æˆé•· (最大到指定的大å°) 作為客體作業系統的索å–ç£ç¢Ÿç©ºé–“。&lt;/p&gt;&lt;p&gt;&lt;b&gt;固定大å°å­˜æ”¾&lt;/b&gt;䏿œƒæˆé•·ã€‚ 它存放在一個約與虛擬硬碟大å°ç›¸åŒçš„æª”案中。 建立一個固定大å°å­˜æ”¾æ™‚å¯èƒ½éœ€è¦å¾ˆé•·çš„æ™‚é–“ï¼Œå–æ±ºæ–¼å­˜æ”¾å¤§å°å’Œæ‚¨ç¡¬ç¢Ÿçš„寫入效能。&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;é¸å–您想è¦å»ºç«‹çš„虛擬硬碟類型。&lt;/p&gt;&lt;p&gt;&lt;b&gt;動態延伸存放&lt;/b&gt;最åˆåœ¨æ‚¨çš„實體硬碟佔有éžå¸¸å°çš„空間é‡ã€‚ 它將會動態æˆé•· (最大到指定的大å°) 作為客體作業系統的索å–ç£ç¢Ÿç©ºé–“。&lt;/p&gt;&lt;p&gt;&lt;b&gt;固定大å°å­˜æ”¾&lt;/b&gt;䏿œƒæˆé•·ã€‚ 它存放在一個約與虛擬硬碟大å°ç›¸åŒçš„æª”案中。 建立一個固定大å°å­˜æ”¾æ™‚å¯èƒ½éœ€è¦å¾ˆé•·çš„æ™‚é–“ï¼Œå–æ±ºæ–¼å­˜æ”¾å¤§å°å’Œæ‚¨ç¡¬ç¢Ÿçš„寫入效能。&lt;/p&gt;</translation>
</message>
<message>
<source>Storage Type</source>
- <translation>存放類型</translation>
+ <translation type="obsolete">存放類型</translation>
</message>
<message>
<source>&amp;Dynamically expanding storage</source>
- <translation>動態延伸存放(&amp;D)</translation>
+ <translation type="obsolete">動態延伸存放(&amp;D)</translation>
</message>
<message>
<source>&amp;Fixed-size storage</source>
- <translation>固定大å°å­˜æ”¾(&amp;F)</translation>
+ <translation type="obsolete">固定大å°å­˜æ”¾(&amp;F)</translation>
</message>
<message>
<source>Hard Disk Storage Type</source>
- <translation>硬碟存放類型</translation>
+ <translation type="obsolete">硬碟存放類型</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage3</name>
<message>
<source>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</source>
- <translation>&lt;p&gt;按下 [&lt;b&gt;é¸å–&lt;/b&gt;] 按鈕以é¸å–存放硬碟資料的檔案ä½ç½®æˆ–在項目欄ä½è¼¸å…¥æª”案å稱。&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;按下 [&lt;b&gt;é¸å–&lt;/b&gt;] 按鈕以é¸å–存放硬碟資料的檔案ä½ç½®æˆ–在項目欄ä½è¼¸å…¥æª”案å稱。&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Location</source>
- <translation>ä½ç½®(&amp;L)</translation>
+ <translation type="obsolete">ä½ç½®(&amp;L)</translation>
</message>
<message>
<source>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</source>
- <translation>&lt;p&gt;é¸å–虛擬硬碟的大å°ï¼Œä»¥ MB 為單ä½ã€‚ 這個大å°å°‡åœ¨å®¢é«”作業系統中作為這個硬碟的最大容é‡ã€‚&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;é¸å–虛擬硬碟的大å°ï¼Œä»¥ MB 為單ä½ã€‚ 這個大å°å°‡åœ¨å®¢é«”作業系統中作為這個硬碟的最大容é‡ã€‚&lt;/p&gt;</translation>
</message>
<message>
<source>&amp;Size</source>
- <translation>大å°(&amp;S)</translation>
+ <translation type="obsolete">大å°(&amp;S)</translation>
</message>
<message>
<source>Virtual Disk Location and Size</source>
- <translation>虛擬ç£ç¢Ÿå¤§å°å’Œä½ç½®</translation>
+ <translation type="obsolete">虛擬ç£ç¢Ÿå¤§å°å’Œä½ç½®</translation>
</message>
<message>
<source>Select a file for the new hard disk image file</source>
- <translation>é¸å–æ–°ç¡¬ç¢Ÿæ˜ åƒæª”的檔案</translation>
+ <translation type="obsolete">é¸å–æ–°ç¡¬ç¢Ÿæ˜ åƒæª”的檔案</translation>
</message>
<message>
<source>Hard disk images (*.vdi)</source>
- <translation>ç¡¬ç¢Ÿæ˜ åƒ (*.vdi)</translation>
+ <translation type="obsolete">ç¡¬ç¢Ÿæ˜ åƒ (*.vdi)</translation>
</message>
<message>
<source>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</source>
- <translation>&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
+ <translation type="obsolete">&lt;nobr&gt;%1 (%2 B)&lt;/nobr&gt;</translation>
</message>
</context>
<context>
<name>UINewHDWzdPage4</name>
<message>
<source>You are going to create a new virtual hard disk with the following parameters:</source>
- <translation>您å³å°‡ä½¿ç”¨ä»¥ä¸‹åƒæ•¸å»ºç«‹æ–°çš„虛擬硬碟:</translation>
+ <translation type="obsolete">您å³å°‡ä½¿ç”¨ä»¥ä¸‹åƒæ•¸å»ºç«‹æ–°çš„虛擬硬碟:</translation>
</message>
<message>
<source>Summary</source>
- <translation>摘è¦</translation>
+ <translation type="obsolete">摘è¦</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 B</translation>
+ <translation type="obsolete">%1 B</translation>
</message>
<message>
<source>Type</source>
<comment>summary</comment>
- <translation>類型</translation>
+ <translation type="obsolete">類型</translation>
</message>
<message>
<source>Location</source>
<comment>summary</comment>
- <translation>ä½ç½®</translation>
+ <translation type="obsolete">ä½ç½®</translation>
</message>
<message>
<source>Size</source>
<comment>summary</comment>
- <translation>大å°</translation>
+ <translation type="obsolete">大å°</translation>
</message>
<message>
<source>If the above settings are correct, press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new hard disk will be created.</source>
- <translation>如果以上設定正確,請按下 [&lt;b&gt;%1&lt;/b&gt;] 按鈕。 一旦按下,將會建立一個新的硬碟。</translation>
+ <translation type="obsolete">如果以上設定正確,請按下 [&lt;b&gt;%1&lt;/b&gt;] 按鈕。 一旦按下,將會建立一個新的硬碟。</translation>
</message>
</context>
<context>
@@ -3123,6 +3598,10 @@
<source>Create New Virtual Machine</source>
<translation>新建虛擬機器精éˆ</translation>
</message>
+ <message>
+ <source>Create</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UINewVMWzdPage1</name>
@@ -3330,6 +3809,120 @@
</message>
</context>
<context>
+ <name>UISettingsDialogGlobal</name>
+ <message>
+ <source>General</source>
+ <translation>一般</translation>
+ </message>
+ <message>
+ <source>Input</source>
+ <translation>輸入</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>æ›´æ–°</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>語言</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>網路</translation>
+ </message>
+ <message>
+ <source>Extensions</source>
+ <translation>æ“´å……</translation>
+ </message>
+ <message>
+ <source>VirtualBox - %1</source>
+ <translation>VirtualBox - %1</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UISettingsDialogMachine</name>
+ <message>
+ <source>General</source>
+ <translation>一般</translation>
+ </message>
+ <message>
+ <source>System</source>
+ <translation>系統</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>顯示</translation>
+ </message>
+ <message>
+ <source>Storage</source>
+ <translation>存放è£ç½®</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>音效</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>網路</translation>
+ </message>
+ <message>
+ <source>Ports</source>
+ <translation>連接埠</translation>
+ </message>
+ <message>
+ <source>Serial Ports</source>
+ <translation>åºåˆ—埠</translation>
+ </message>
+ <message>
+ <source>Parallel Ports</source>
+ <translation>串列埠</translation>
+ </message>
+ <message>
+ <source>USB</source>
+ <translation>USB</translation>
+ </message>
+ <message>
+ <source>Shared Folders</source>
+ <translation>共用資料夾</translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation>%1 - %2</translation>
+ </message>
+ <message>
+ <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
+ <translation type="obsolete">您已é‡å°é€™éƒ¨ VM é¸å– 64 ä½å…ƒçš„客體作業系統類型。 如此的客體需è¦ç¡¬é«”虛擬化 (VT-x/AMD-V),這個功能將會自動啟用。</translation>
+ </message>
+ <message>
+ <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
+ <translation type="obsolete">您已啟用 2D 視訊加速。 由於 2D è¦–è¨ŠåŠ é€Ÿåªæ”¯æ´ Windows 客體,這個功能將åœç”¨ã€‚</translation>
+ </message>
+ <message>
+ <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
+ <translation type="obsolete">您已啟用 USB HID (人性化介é¢è£ç½®)。 除éžåŒæ™‚啟用 USB 模擬å¦å‰‡é€™å°‡ä¸æœƒå‹•作。 當您按下 [確定] æŒ‰éˆ•æŽ¥å— VM 設定值時這將會自動完æˆã€‚</translation>
+ </message>
+ <message>
+ <source>at most one supported</source>
+ <translation type="obsolete">æœ€å¤šæ”¯æ´ 1 個</translation>
+ </message>
+ <message>
+ <source>up to %1 supported</source>
+ <translation type="obsolete">æœ€å¤šæ”¯æ´ %1 個</translation>
+ </message>
+ <message>
+ <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
+ <translation type="obsolete">您目å‰ä½¿ç”¨è¶…éŽ %1 晶片組所支æ´çš„存放控制器。 請在系統設定é ä¸­è®Šæ›´æ™¶ç‰‡çµ„類型或在存放設定é ä¸­æ¸›å°‘以下存放控制器的數é‡: %2。</translation>
+ </message>
+</context>
+<context>
<name>UIVMCloseDialog</name>
<message>
<source>Close Virtual Machine</source>
@@ -3436,81 +4029,6 @@
</message>
</context>
<context>
- <name>UIVMSettingsDlg</name>
- <message>
- <source>General</source>
- <translation>一般</translation>
- </message>
- <message>
- <source>System</source>
- <translation>系統</translation>
- </message>
- <message>
- <source>Display</source>
- <translation>顯示</translation>
- </message>
- <message>
- <source>Storage</source>
- <translation>存放è£ç½®</translation>
- </message>
- <message>
- <source>Audio</source>
- <translation>音效</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>網路</translation>
- </message>
- <message>
- <source>Ports</source>
- <translation>連接埠</translation>
- </message>
- <message>
- <source>Serial Ports</source>
- <translation>åºåˆ—埠</translation>
- </message>
- <message>
- <source>Parallel Ports</source>
- <translation>串列埠</translation>
- </message>
- <message>
- <source>USB</source>
- <translation>USB</translation>
- </message>
- <message>
- <source>Shared Folders</source>
- <translation>共用資料夾</translation>
- </message>
- <message>
- <source>%1 - %2</source>
- <translation>%1 - %2</translation>
- </message>
- <message>
- <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source>
- <translation>您已é‡å°é€™éƒ¨ VM é¸å– 64 ä½å…ƒçš„客體作業系統類型。 如此的客體需è¦ç¡¬é«”虛擬化 (VT-x/AMD-V),這個功能將會自動啟用。</translation>
- </message>
- <message>
- <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
- <translation>您已啟用 2D 視訊加速。 由於 2D è¦–è¨ŠåŠ é€Ÿåªæ”¯æ´ Windows 客體,這個功能將åœç”¨ã€‚</translation>
- </message>
- <message>
- <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source>
- <translation>您已啟用 USB HID (人性化介é¢è£ç½®)。 除éžåŒæ™‚啟用 USB 模擬å¦å‰‡é€™å°‡ä¸æœƒå‹•作。 當您按下 [確定] æŒ‰éˆ•æŽ¥å— VM 設定值時這將會自動完æˆã€‚</translation>
- </message>
- <message>
- <source>at most one supported</source>
- <translation>æœ€å¤šæ”¯æ´ 1 個</translation>
- </message>
- <message>
- <source>up to %1 supported</source>
- <translation>æœ€å¤šæ”¯æ´ %1 個</translation>
- </message>
- <message>
- <source>you are currently using more storage controllers than a %1 chipset supports. Please change the chipset type on the System settings page or reduce the number of the following storage controllers on the Storage settings page: %2.</source>
- <translation>您目å‰ä½¿ç”¨è¶…éŽ %1 晶片組所支æ´çš„存放控制器。 請在系統設定é ä¸­è®Šæ›´æ™¶ç‰‡çµ„類型或在存放設定é ä¸­æ¸›å°‘以下存放控制器的數é‡: %2。</translation>
- </message>
-</context>
-<context>
<name>VBoxAboutDlg</name>
<message>
<source>VirtualBox - About</source>
@@ -3631,6 +4149,14 @@
<source>Hard Disk Controller (SAS)</source>
<translation>硬碟控制器 (SAS)</translation>
</message>
+ <message>
+ <source>When checked a new unique MAC address will assigned to all configured network cards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Reinitialize the MAC address of all network cards</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxEmptyFileSelector</name>
@@ -4249,7 +4775,7 @@
<message>
<source>Adapter %1</source>
<comment>network</comment>
- <translation>介é¢å¡ %1</translation>
+ <translation type="obsolete">介é¢å¡ %1</translation>
</message>
<message>
<source>Checking...</source>
@@ -4632,7 +5158,7 @@
<message>
<source>VDE network, &apos;%1&apos;</source>
<comment>details report (network)</comment>
- <translation>VDE 網路, 「%1ã€</translation>
+ <translation type="obsolete">VDE 網路, 「%1ã€</translation>
</message>
<message>
<source>SAS</source>
@@ -4642,7 +5168,7 @@
<message>
<source>VDE Adapter</source>
<comment>NetworkAttachmentType</comment>
- <translation>VDE 介é¢å¡</translation>
+ <translation type="obsolete">VDE 介é¢å¡</translation>
</message>
<message>
<source>LsiLogic SAS</source>
@@ -4834,6 +5360,61 @@
<comment>DiskType</comment>
<translation>多é‡é™„加</translation>
</message>
+ <message>
+ <source>Dynamically allocated storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Dynamically allocated storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fixed size storage split into files of less than 2GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Execution Cap</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
+ <comment>details report</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic, &apos;%1&apos;</source>
+ <comment>details report (network)</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Driver</source>
+ <comment>NetworkAttachmentType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow VMs</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow All</source>
+ <comment>NetworkAdapterPromiscModePolicyType</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Adapter %1</source>
+ <translation type="unfinished">介é¢å¡ %1</translation>
+ </message>
</context>
<context>
<name>VBoxGlobalSettings</name>
@@ -4974,15 +5555,15 @@
</message>
<message>
<source>Location</source>
- <translation>ä½ç½®</translation>
+ <translation type="obsolete">ä½ç½®</translation>
</message>
<message>
<source>Type (Format)</source>
- <translation>類型 (æ ¼å¼)</translation>
+ <translation type="obsolete">類型 (æ ¼å¼)</translation>
</message>
<message>
<source>Attached to</source>
- <translation>附加到</translation>
+ <translation type="obsolete">附加到</translation>
</message>
<message>
<source>Checking accessibility</source>
@@ -5052,17 +5633,17 @@
<message>
<source>Attached to</source>
<comment>VMM: Virtual Disk</comment>
- <translation>附加到</translation>
+ <translation type="obsolete">附加到</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: CD/DVD Image</comment>
- <translation>附加到</translation>
+ <translation type="obsolete">附加到</translation>
</message>
<message>
<source>Attached to</source>
<comment>VMM: Floppy Image</comment>
- <translation>附加到</translation>
+ <translation type="obsolete">附加到</translation>
</message>
<message>
<source>CD/DVD-ROM disk</source>
@@ -5080,6 +5661,46 @@
<source>All %1 images (%2)</source>
<translation>所有 %1 æ˜ åƒ (%2)</translation>
</message>
+ <message>
+ <source>Type:</source>
+ <translation type="unfinished">類型:</translation>
+ </message>
+ <message>
+ <source>Location:</source>
+ <translation type="unfinished">ä½ç½®:</translation>
+ </message>
+ <message>
+ <source>Format:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Storage details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attached to:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Modify...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy an existing medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Modify the attributes of the selected medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxMiniToolBar</name>
@@ -5104,7 +5725,7 @@
<name>VBoxNetworkDialog</name>
<message>
<source>Network Adapters</source>
- <translation>網路å¡</translation>
+ <translation type="obsolete">網路å¡</translation>
</message>
</context>
<context>
@@ -5625,7 +6246,7 @@
</message>
<message>
<source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source>
- <translation>無法存å–主機系統上的 USB ,因為 USB 檔案系統 (usbfs) 或 DBus å’Œ hal æœå‹™ç›®å‰ä¸å¯ç”¨ã€‚ 如果您è¦åœ¨å®¢é«”系統內使用主機 USB è£ç½®ï¼Œæ‚¨å¿…é ˆä¿®æ­£æ­¤ä¸¦é‡æ–°å•Ÿå‹• VirtualBox。</translation>
+ <translation type="obsolete">無法存å–主機系統上的 USB ,因為 USB 檔案系統 (usbfs) 或 DBus å’Œ hal æœå‹™ç›®å‰ä¸å¯ç”¨ã€‚ 如果您è¦åœ¨å®¢é«”系統內使用主機 USB è£ç½®ï¼Œæ‚¨å¿…é ˆä¿®æ­£æ­¤ä¸¦é‡æ–°å•Ÿå‹• VirtualBox。</translation>
</message>
<message>
<source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source>
@@ -5721,7 +6342,7 @@
</message>
<message>
<source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;? This will cause you to lose your current machine state, which cannot be recovered.&lt;/p&gt;</source>
- <translation>&lt;p&gt;您確定è¦é‚„原快照 &lt;b&gt;%1&lt;/b&gt; å—Ž? 這將導致您目å‰çš„æ©Ÿå™¨å¿«ç…§éºå¤±è€Œç„¡æ³•復原。&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;您確定è¦é‚„原快照 &lt;b&gt;%1&lt;/b&gt; å—Ž? 這將導致您目å‰çš„æ©Ÿå™¨å¿«ç…§éºå¤±è€Œç„¡æ³•復原。&lt;/p&gt;</translation>
</message>
<message>
<source>Restore</source>
@@ -6051,7 +6672,7 @@
</message>
<message>
<source>Deletion of all files belonging to the VM is currently disabled on Windows/x64 to prevent a crash. That will be fixed in the next release.</source>
- <translation>刪除所有ä¾è³´ VM 的檔案目å‰å·²åœ¨ Windows/x64 åœç”¨ä»¥é˜²æ­¢ç•¶æ©Ÿã€‚ 其將在下次發佈時修復。</translation>
+ <translation type="obsolete">刪除所有ä¾è³´ VM 的檔案目å‰å·²åœ¨ Windows/x64 åœç”¨ä»¥é˜²æ­¢ç•¶æ©Ÿã€‚ 其將在下次發佈時修復。</translation>
</message>
<message>
<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>
@@ -6059,14 +6680,82 @@
</message>
<message>
<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>&lt;p&gt;USB 2.0 ç›®å‰åœ¨é€™éƒ¨è™›æ“¬æ©Ÿå™¨å•Ÿç”¨ã€‚ 然而這需è¦å®‰è£ &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;。&lt;/p&gt;&lt;p&gt;請從 VirtualBox ä¸‹è¼‰ç¶²ç«™å®‰è£æ“´å……包。 在此之後您將å¯ä»¥é‡æ–°å®‰è£ USB 2.0。 é™¤éžæ‚¨å–消目å‰è¨­å®šè®Šæ›´ï¼Œå¦å‰‡å°‡åœ¨æ­¤æœŸé–“åœç”¨ã€‚&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;USB 2.0 ç›®å‰åœ¨é€™éƒ¨è™›æ“¬æ©Ÿå™¨å•Ÿç”¨ã€‚ 然而這需è¦å®‰è£ &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;。&lt;/p&gt;&lt;p&gt;請從 VirtualBox ä¸‹è¼‰ç¶²ç«™å®‰è£æ“´å……包。 在此之後您將å¯ä»¥é‡æ–°å®‰è£ USB 2.0。 é™¤éžæ‚¨å–消目å‰è¨­å®šè®Šæ›´ï¼Œå¦å‰‡å°‡åœ¨æ­¤æœŸé–“åœç”¨ã€‚&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <source>Failed to register the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;The machine settings were changed while you were editing them. You currently have unsaved setting changes.&lt;/p&gt;&lt;p&gt;Would you like to reload the changed settings or to keep your own changes?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reload settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Keep changes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The state of the virtual machine you currently edit has changed. Only settings which are editable at runtime are saved when you press OK. All changes to other settings will be lost.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to clone the virtual machine &lt;b&gt;%1&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;You are about to restore snapshot &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;You can create a snapshot of the current state of the virtual machine first by checking the box below; if you do not do this the current state will be permanently lost. Do you wish to proceed?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a snapshot of the current machine state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Are you sure you want to restore snapshot &lt;b&gt;%1&lt;/b&gt;?&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;Error changing medium type from &lt;b&gt;%1&lt;/b&gt; to &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sorry, some generic error happens.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <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>
+ <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>
+ <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>
+ <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>
+ <source>The USB Proxy Service has not yet been ported to this host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Could not load the Host USB Proxy service</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>VBoxSFDialog</name>
<message>
<source>Shared Folders</source>
- <translation>共用資料夾</translation>
+ <translation type="obsolete">共用資料夾</translation>
</message>
</context>
<context>
@@ -6121,7 +6810,7 @@
</message>
<message>
<source>D&amp;iscard</source>
- <translation>æ¨æ£„(&amp;I)</translation>
+ <translation type="obsolete">æ¨æ£„(&amp;I)</translation>
</message>
<message>
<source>Discard the saved state of the selected virtual machine</source>
@@ -6299,6 +6988,22 @@
<source>Show Statusbar</source>
<translation>顯示狀態列</translation>
</message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation type="unfinished">æ¨æ£„</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSnapshotDetailsDlg</name>
@@ -6425,6 +7130,14 @@
<source> (%1 ago)</source>
<translation>(%1 之å‰)</translation>
</message>
+ <message>
+ <source>&amp;Clone...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>VBoxSwitchMenu</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/qt_sv.ts b/src/VBox/Frontends/VirtualBox/nls/qt_sv.ts
index c86dbc5ec..8f2a4bf3c 100644
--- a/src/VBox/Frontends/VirtualBox/nls/qt_sv.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/qt_sv.ts
@@ -2,21 +2,57 @@
<!DOCTYPE TS>
<TS version="2.0" language="sv">
<context>
+ <name>AudioOutput</name>
+ <message>
+ <source>&lt;html&gt;The audio playback device &lt;b&gt;%1&lt;/b&gt; does not work.&lt;br/&gt;Falling back to &lt;b&gt;%2&lt;/b&gt;.&lt;/html&gt;</source>
+ <translation type="obsolete">&lt;html&gt;Ljuduppspelningsenheten &lt;b&gt;%1&lt;/b&gt; fungerar inte.&lt;br/&gt;Faller tillbaka på &lt;b&gt;%2&lt;/b&gt;.&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;Switching to the audio playback device &lt;b&gt;%1&lt;/b&gt;&lt;br/&gt;which just became available and has higher preference.&lt;/html&gt;</source>
+ <translation type="obsolete">&lt;html&gt;Växlar till ljuduppspelningensenheten &lt;b&gt;%1&lt;/b&gt;&lt;br/&gt;som precis blev tillgänglig och har företräde.&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Revert back to device &apos;%1&apos;</source>
+ <translation type="obsolete">Återgå till enhet \&quot;%1\&quot;</translation>
+ </message>
+</context>
+<context>
+ <name>CloseButton</name>
+ <message>
+ <location filename="../src/gui/widgets/qtabbar.cpp" line="+2319"/>
+ <source>Close Tab</source>
+ <translation>Stäng flik</translation>
+ </message>
+</context>
+<context>
+ <name>FakeReply</name>
+ <message>
+ <location filename="../src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp" line="+2279"/>
+ <source>Fake error !</source>
+ <translation>LÃ¥tsasfel!</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Invalid URL</source>
+ <translation>Ogiltig webbadress</translation>
+ </message>
+</context>
+<context>
<name>MAC_APPLICATION_MENU</name>
<message>
- <location filename="../src/gui/kernel/qapplication.cpp" line="+2316"/>
+ <location filename="../src/gui/kernel/qapplication.cpp" line="+2407"/>
<source>Services</source>
<translation>Tjänster</translation>
</message>
<message>
<location line="+1"/>
<source>Hide %1</source>
- <translation>Göm %1</translation>
+ <translation>Dölj %1</translation>
</message>
<message>
<location line="+1"/>
<source>Hide Others</source>
- <translation>Göm övriga</translation>
+ <translation>Dölj övriga</translation>
</message>
<message>
<location line="+1"/>
@@ -26,7 +62,7 @@
<message>
<location line="+1"/>
<source>Preferences...</source>
- <translation>Inställningar…</translation>
+ <translation>Inställningar...</translation>
</message>
<message>
<location line="+1"/>
@@ -40,59 +76,88 @@
</message>
</context>
<context>
- <name>AudioOutput</name>
- <message>
- <source>&lt;html&gt;The audio playback device &lt;b&gt;%1&lt;/b&gt; does not work.&lt;br/&gt;Falling back to &lt;b&gt;%2&lt;/b&gt;.&lt;/html&gt;</source>
- <translation>&lt;html&gt;Ljuduppspelningsenheten &lt;b&gt;%1&lt;/b&gt; fungerar inte.&lt;br/&gt;Faller tillbaka på &lt;b&gt;%2&lt;/b&gt;.&lt;/html&gt;</translation>
- </message>
+ <name>MainWindow</name>
<message>
- <source>&lt;html&gt;Switching to the audio playback device &lt;b&gt;%1&lt;/b&gt;&lt;br/&gt;which just became available and has higher preference.&lt;/html&gt;</source>
- <translation>&lt;html&gt;Växlar till ljuduppspelningsenheten &lt;b&gt;%1&lt;/b&gt;&lt;br/&gt;som precis blev tillgänglig och har högre prioritet.&lt;/html&gt;</translation>
+ <source>Print</source>
+ <translation type="obsolete">Skriv ut</translation>
</message>
<message>
- <source>Revert back to device &apos;%1&apos;</source>
- <translation>Återgå tillbaka till enheten &apos;%1&apos;</translation>
+ <source>Location:</source>
+ <translation type="obsolete">Plats:</translation>
</message>
</context>
<context>
<name>Phonon::</name>
<message>
+ <location filename="../src/3rdparty/phonon/phonon/phononnamespace.cpp" line="+55"/>
<source>Notifications</source>
<translation>Notifieringar</translation>
</message>
<message>
+ <location line="+2"/>
<source>Music</source>
<translation>Musik</translation>
</message>
<message>
+ <location line="+2"/>
<source>Video</source>
<translation>Video</translation>
</message>
<message>
+ <location line="+2"/>
<source>Communication</source>
<translation>Kommunikation</translation>
</message>
<message>
+ <location line="+2"/>
<source>Games</source>
<translation>Spel</translation>
</message>
<message>
+ <location line="+2"/>
<source>Accessibility</source>
- <translation>Hjälpmedel</translation>
+ <translation>Tillgänglighet</translation>
+ </message>
+</context>
+<context>
+ <name>Phonon::AudioOutput</name>
+ <message>
+ <location filename="../src/3rdparty/phonon/phonon/audiooutput.cpp" line="+444"/>
+ <location line="+34"/>
+ <source>&lt;html&gt;The audio playback device &lt;b&gt;%1&lt;/b&gt; does not work.&lt;br/&gt;Falling back to &lt;b&gt;%2&lt;/b&gt;.&lt;/html&gt;</source>
+ <translation>&lt;html&gt;Ljuduppspelningsenheten &lt;b&gt;%1&lt;/b&gt; fungerar inte.&lt;br/&gt;Återgår till &lt;b&gt;%2&lt;/b&gt;.&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location line="-21"/>
+ <source>&lt;html&gt;Switching to the audio playback device &lt;b&gt;%1&lt;/b&gt;&lt;br/&gt;which just became available and has higher preference.&lt;/html&gt;</source>
+ <translation>&lt;html&gt;Växlar till ljuduppspelningsenheten &lt;b&gt;%1&lt;/b&gt;&lt;br/&gt;som precis blev tillgänglig och har företräde.&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <location line="+14"/>
+ <source>Revert back to device &apos;%1&apos;</source>
+ <translation>Återgå till enhet &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <location line="-3"/>
+ <source>&lt;html&gt;Switching to the audio playback device &lt;b&gt;%1&lt;/b&gt;&lt;br/&gt;which has higher preference or is specifically configured for this stream.&lt;/html&gt;</source>
+ <translation>&lt;html&gt;Växlar till ljuduppspelningsenheten &lt;b&gt;%1&lt;/b&gt;&lt;br/&gt;som har företräde eller är specifikt inställd för den här strömmen.&lt;/html&gt;</translation>
</message>
</context>
<context>
<name>Phonon::Gstreamer::Backend</name>
<message>
+ <location filename="../src/3rdparty/phonon/gstreamer/backend.cpp" line="+188"/>
<source>Warning: You do not seem to have the package gstreamer0.10-plugins-good installed.
Some video features have been disabled.</source>
- <translation>Varning: Du verkar inte ha paketet gstreamer0.10-plugins-good installerat.
+ <translation>Varning: Det verkar inte som om du har paketet gstreamer0.10-plugins-good installerat.
Vissa videofunktioner har inaktiverats.</translation>
</message>
<message>
+ <location line="+5"/>
<source>Warning: You do not seem to have the base GStreamer plugins installed.
All audio and video support has been disabled</source>
- <translation>Varning: Du verkar inte ha grundläggande GStreamer-insticksmoduler installerade.
+ <translation>Varning: Det verkar inte som om du har de grundläggande GStreamer-insticksmodulerna installerade.
Allt stöd för ljud och video har inaktiverats</translation>
</message>
</context>
@@ -103,57 +168,484 @@
Check your Gstreamer installation and make sure you
have libgstreamer-plugins-base installed.</source>
- <translation>Kan inte starta uppspelning.
+ <translation type="obsolete">Kan inte starta uppspelningen.
Kontrollera din Gstreamer-installation och försäkra dig om
att du har libgstreamer-plugins-base installerat.</translation>
</message>
- <message numerus="yes">
+ <message>
+ <location filename="../src/3rdparty/phonon/gstreamer/mediaobject.cpp" line="+93"/>
+ <source>Cannot start playback.
+
+Check your GStreamer installation and make sure you
+have libgstreamer-plugins-base installed.</source>
+ <translation>Kan inte starta uppspelningen.
+
+Kontrollera din Gstreamer-installation och försäkra dig om
+att du har libgstreamer-plugins-base installerat.</translation>
+ </message>
+ <message>
+ <location line="+129"/>
+ <source>Missing codec helper script assistant.</source>
+ <translation>Saknar hjälpskriptguide för kodek.</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Plugin codec installation failed for codec: %0</source>
+ <translation>Installering av insticksprogram för avkodning misslyckades för: %0</translation>
+ </message>
+ <message>
+ <location line="+11"/>
<source>A required codec is missing. You need to install the following codec(s) to play this content: %0</source>
- <translation>
- <numerusform>En nödvändig kodek saknas. Du behöver installera följande kodek(ar) för att spela upp detta innehåll: %0</numerusform>
- <numerusform></numerusform>
- </translation>
+ <translation>En nödvändig kodek saknas. Du behöver installera följande kodek(ar) för att spela upp detta innehåll: %0</translation>
</message>
<message>
+ <location line="+730"/>
+ <location line="+6"/>
+ <location line="+13"/>
+ <location line="+24"/>
+ <location line="+6"/>
+ <location line="+18"/>
+ <location line="+434"/>
+ <location line="+24"/>
<source>Could not open media source.</source>
- <translation>Kunde inte öppna mediakällan.</translation>
+ <translation>Kunde inte öppna mediakälla.</translation>
</message>
<message>
+ <location line="-514"/>
<source>Invalid source type.</source>
<translation>Ogiltig källtyp.</translation>
</message>
<message>
+ <location line="+488"/>
<source>Could not locate media source.</source>
- <translation>Kunde inte hitta mediakällan.</translation>
+ <translation>Kunde inte hitta mediakälla.</translation>
</message>
<message>
+ <location line="+10"/>
<source>Could not open audio device. The device is already in use.</source>
- <translation>Kunde inte öppna ljudenheten. Enheten används redan.</translation>
+ <translation>Kunde inte öppna ljudenhet. Enheten används redan.</translation>
</message>
<message>
+ <location line="+13"/>
<source>Could not decode media source.</source>
- <translation>Kunde inte avkoda mediakällan.</translation>
+ <translation>Kunde inte avkoda mediakälla.</translation>
+ </message>
+</context>
+<context>
+ <name>Phonon::MMF</name>
+ <message>
+ <location filename="../src/3rdparty/phonon/mmf/audiooutput.cpp" line="+106"/>
+ <source>Audio Output</source>
+ <translation>Ljuduppspelning</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>The audio output device</source>
+ <translation>Ljudutenheten</translation>
+ </message>
+ <message>
+ <location filename="../src/3rdparty/phonon/mmf/utils.cpp" line="+89"/>
+ <source>No error</source>
+ <translation>Inget fel</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Not found</source>
+ <translation>Hittades inte</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Out of memory</source>
+ <translation>Slut på minne</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Not supported</source>
+ <translation>Stöds inte</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Overflow</source>
+ <translation>För mycket data</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Underflow</source>
+ <translation>För lite data</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Already exists</source>
+ <translation>Finns redan</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Path not found</source>
+ <translation>Sökväg hittades inte</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>In use</source>
+ <translation>Används</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Not ready</source>
+ <translation>Inte klar</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Access denied</source>
+ <translation>Ã…tkomst nekades</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Could not connect</source>
+ <translation>Kunde inte ansluta</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Disconnected</source>
+ <translation>Nerkopplad</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Permission denied</source>
+ <translation>Ã…tkomst nekad</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Insufficient bandwidth</source>
+ <translation>Otillräcklig bandbredd</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Network unavailable</source>
+ <translation>Nätverk inte tillgängligt</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Network communication error</source>
+ <translation>Kommunikationsfel i nätverket</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Streaming not supported</source>
+ <translation>Strömmande media stöds inte</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Server alert</source>
+ <translation>Servervarning</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Invalid protocol</source>
+ <translation>Ogiltigt protokoll</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Invalid URL</source>
+ <translation>Ogiltig webbadress</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Multicast error</source>
+ <translation>Multicastfel</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Proxy server error</source>
+ <translation>Proxyserverfel</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Proxy server not supported</source>
+ <translation>Proxyserver stöds inte</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Audio output error</source>
+ <translation>Fel vid ljuduppspelning</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Video output error</source>
+ <translation>Fel vid videouppspelning</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Decoder error</source>
+ <translation>Avkodningsfel</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Audio or video components could not be played</source>
+ <translation>Ljud- eller videokomponent kunde inte spelas</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>DRM error</source>
+ <translation>Fel i digital upphovsrättshantering (DRM)</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Unknown error (%1)</source>
+ <translation>Okänt fel (%1)</translation>
+ </message>
+</context>
+<context>
+ <name>Phonon::MMF::AbstractMediaPlayer</name>
+ <message>
+ <location filename="../src/3rdparty/phonon/mmf/abstractmediaplayer.cpp" line="+82"/>
+ <source>Not ready to play</source>
+ <translation>Inte klar att spela</translation>
+ </message>
+ <message>
+ <location line="+170"/>
+ <location line="+11"/>
+ <location line="+346"/>
+ <location line="+21"/>
+ <source>Error opening file</source>
+ <translation>Fel när filen skulle öppnas</translation>
+ </message>
+ <message>
+ <location line="-347"/>
+ <source>Error opening URL</source>
+ <translation>Fel när webbadressen skulle öppnas</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>Error opening resource</source>
+ <translation>Fel när resurs skulle öppnas</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Error opening source: resource not opened</source>
+ <translation>Fel när källa skulle öppnas: Resursen öppnades inte</translation>
+ </message>
+ <message>
+ <location line="+92"/>
+ <source>Setting volume failed</source>
+ <translation>Ställa in volym misslyckades</translation>
+ </message>
+ <message>
+ <location line="+61"/>
+ <source>Loading clip failed</source>
+ <translation>Ladda klipp misslyckades</translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Playback complete</source>
+ <translation>Uppspelning färdig</translation>
+ </message>
+ <message>
+ <location line="+157"/>
+ <source>Download error</source>
+ <translation>Nedladdningsfel</translation>
+ </message>
+</context>
+<context>
+ <name>Phonon::MMF::AbstractVideoPlayer</name>
+ <message>
+ <location filename="../src/3rdparty/phonon/mmf/abstractvideoplayer.cpp" line="+111"/>
+ <source>Pause failed</source>
+ <translation>Paus misslyckades</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Seek failed</source>
+ <translation>Sökning misslyckades</translation>
+ </message>
+ <message>
+ <location line="+67"/>
+ <source>Getting position failed</source>
+ <translation>Hämta position misslyckades</translation>
+ </message>
+ <message>
+ <location line="+70"/>
+ <source>Opening clip failed</source>
+ <translation>Öppna klipp misslyckades</translation>
+ </message>
+</context>
+<context>
+ <name>Phonon::MMF::AudioEqualizer</name>
+ <message>
+ <location filename="../src/3rdparty/phonon/mmf/audioequalizer.cpp" line="+92"/>
+ <source>%1 Hz</source>
+ <translation>%1 Hz</translation>
+ </message>
+</context>
+<context>
+ <name>Phonon::MMF::AudioPlayer</name>
+ <message>
+ <location filename="../src/3rdparty/phonon/mmf/audioplayer.cpp" line="+187"/>
+ <source>Getting position failed</source>
+ <translation>Hämta position misslyckades</translation>
+ </message>
+</context>
+<context>
+ <name>Phonon::MMF::DsaVideoPlayer</name>
+ <message>
+ <location filename="../src/3rdparty/phonon/mmf/videoplayer_dsa.cpp" line="+241"/>
+ <location line="+15"/>
+ <location line="+8"/>
+ <location line="+22"/>
+ <location line="+22"/>
+ <source>Video display error</source>
+ <translation>Videovisningsfel</translation>
+ </message>
+</context>
+<context>
+ <name>Phonon::MMF::EffectFactory</name>
+ <message>
+ <location filename="../src/3rdparty/phonon/mmf/effectfactory.cpp" line="+181"/>
+ <source>Enabled</source>
+ <translation>Aktiverad</translation>
+ </message>
+</context>
+<context>
+ <name>Phonon::MMF::EnvironmentalReverb</name>
+ <message>
+ <location filename="../src/3rdparty/phonon/mmf/environmentalreverb.cpp" line="+146"/>
+ <source>Decay HF ratio (%)</source>
+ <extracomment>DecayHFRatio: Ratio of high-frequency decay time to the value specified by DecayTime.</extracomment>
+ <translation>HF-avklingningsförhållande (%)</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Decay time (ms)</source>
+ <extracomment>DecayTime: Time over which reverberation is diminished.</extracomment>
+ <translation>Avklingningstid (ms)</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Density (%)</source>
+ <extracomment>Density Delay between first and subsequent reflections. Note that the S60 platform documentation does not make clear the distinction between this value and the Diffusion value.</extracomment>
+ <translation>Täthet (%)</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Diffusion (%)</source>
+ <extracomment>Diffusion: Delay between first and subsequent reflections. Note that the S60 platform documentation does not make clear the distinction between this value and the Density value.</extracomment>
+ <translation>Diffusion (%)</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Reflections delay (ms)</source>
+ <extracomment>ReflectionsDelay: Amount of delay between the arrival the direct path from the source and the arrival of the first reflection.</extracomment>
+ <translation>Reflektionsfördröjning (ms)</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Reflections level (mB)</source>
+ <extracomment>ReflectionsLevel: Amplitude of reflections. This value is corrected by the RoomLevel to give the final reflection amplitude.</extracomment>
+ <translation>Reflektionsnivå (mB)</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Reverb delay (ms)</source>
+ <extracomment>ReverbDelay: Amount of time between arrival of the first reflection and start of the late reverberation.</extracomment>
+ <translation>Ekofördröjning (ms)</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Reverb level (mB)</source>
+ <extracomment>ReverbLevel Amplitude of reverberations. This value is corrected by the RoomLevel to give the final reverberation amplitude.</extracomment>
+ <translation>Ekonivå (mB)</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Room HF level</source>
+ <extracomment>RoomHFLevel: Amplitude of low-pass filter used to attenuate the high frequency component of reflected sound.</extracomment>
+ <translation>HF-rumsnivå</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Room level (mB)</source>
+ <extracomment>RoomLevel: Master volume control for all reflected sound.</extracomment>
+ <translation>Rumsnivå (mB)</translation>
+ </message>
+</context>
+<context>
+ <name>Phonon::MMF::MediaObject</name>
+ <message>
+ <location filename="../src/3rdparty/phonon/mmf/mediaobject.cpp" line="+321"/>
+ <location line="+18"/>
+ <source>Error opening source: type not supported</source>
+ <translation>Fel när källa skulle öppnas: Typen stöds inte</translation>
+ </message>
+ <message>
+ <location line="-7"/>
+ <source>Error opening source: resource is compressed</source>
+ <translation>Fel när källa skulle öppnas: Resursen är komprimerad</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Error opening source: resource not valid</source>
+ <translation>Fel när källa skulle öppnas: Resursen är inte giltig</translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>Error opening source: media type could not be determined</source>
+ <translation>Fel när källa skulle öppnas: Medietyp kunde inte bestämmas</translation>
+ </message>
+ <message>
+ <location line="+158"/>
+ <source>Failed to set requested IAP</source>
+ <translation>Misslyckades ställa in begärd IAP</translation>
+ </message>
+</context>
+<context>
+ <name>Phonon::MMF::StereoWidening</name>
+ <message>
+ <location filename="../src/3rdparty/phonon/mmf/stereowidening.cpp" line="+79"/>
+ <source>Level (%)</source>
+ <translation>Nivå (%)</translation>
+ </message>
+</context>
+<context>
+ <name>Phonon::MMF::SurfaceVideoPlayer</name>
+ <message>
+ <location filename="../src/3rdparty/phonon/mmf/videoplayer_surface.cpp" line="+139"/>
+ <location line="+26"/>
+ <source>Video display error</source>
+ <translation>Videovisningsfel</translation>
</message>
</context>
<context>
<name>Phonon::VolumeSlider</name>
<message>
+ <location filename="../src/3rdparty/phonon/phonon/volumeslider.cpp" line="+42"/>
+ <location line="+18"/>
+ <location line="+129"/>
+ <location line="+15"/>
<source>Volume: %1%</source>
<translation>Volym: %1%</translation>
</message>
<message>
+ <location line="-159"/>
+ <location line="+18"/>
+ <location line="+54"/>
<source>Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1%</source>
- <translation>Använd denna draglist för att justera volymen. Längst till vänster är 0% och till höger är %1%</translation>
+ <translation>Använd denna draglist för att justera volymen. Längst till vänster är 0% och längst till höger är %1%</translation>
+ </message>
+ <message>
+ <location line="+67"/>
+ <source>Muted</source>
+ <translation>Tyst</translation>
</message>
</context>
<context>
<name>Q3Accel</name>
<message>
+ <location filename="../src/qt3support/other/q3accel.cpp" line="+481"/>
<source>%1, %2 not defined</source>
<translation>%1, %2 är inte definierad</translation>
</message>
<message>
+ <location line="+36"/>
<source>Ambiguous %1 not handled</source>
<translation>Tvetydigt %1 hanteras inte</translation>
</message>
@@ -161,22 +653,27 @@ att du har libgstreamer-plugins-base installerat.</translation>
<context>
<name>Q3DataTable</name>
<message>
+ <location filename="../src/qt3support/sql/q3datatable.cpp" line="+285"/>
<source>True</source>
<translation>Sant</translation>
</message>
<message>
+ <location line="+1"/>
<source>False</source>
<translation>Falskt</translation>
</message>
<message>
+ <location line="+505"/>
<source>Insert</source>
<translation>Infoga</translation>
</message>
<message>
+ <location line="+1"/>
<source>Update</source>
<translation>Uppdatera</translation>
</message>
<message>
+ <location line="+1"/>
<source>Delete</source>
<translation>Ta bort</translation>
</message>
@@ -184,238 +681,313 @@ att du har libgstreamer-plugins-base installerat.</translation>
<context>
<name>Q3FileDialog</name>
<message>
+ <location filename="../src/qt3support/dialogs/q3filedialog.cpp" line="+834"/>
<source>Copy or Move a File</source>
<translation>Kopiera eller ta bort en fil</translation>
</message>
<message>
+ <location line="+8"/>
<source>Read: %1</source>
<translation>Läs: %1</translation>
</message>
<message>
+ <location line="+6"/>
+ <location line="+30"/>
<source>Write: %1</source>
<translation>Skriv: %1</translation>
</message>
<message>
+ <location line="-22"/>
+ <location line="+1579"/>
<source>Cancel</source>
<translation>Avbryt</translation>
</message>
<message>
+ <location line="-157"/>
+ <location line="+49"/>
+ <location line="+2149"/>
+ <location filename="../src/qt3support/dialogs/q3filedialog_mac.cpp" line="+133"/>
<source>All Files (*)</source>
<translation>Alla filer (*)</translation>
</message>
<message>
+ <location line="-2085"/>
<source>Name</source>
<translation>Namn</translation>
</message>
<message>
+ <location line="+1"/>
<source>Size</source>
<translation>Storlek</translation>
</message>
<message>
+ <location line="+2"/>
<source>Type</source>
<translation>Typ</translation>
</message>
<message>
+ <location line="+1"/>
<source>Date</source>
<translation>Datum</translation>
</message>
<message>
+ <location line="+1"/>
<source>Attributes</source>
<translation>Attribut</translation>
</message>
<message>
+ <location line="+35"/>
+ <location line="+2027"/>
<source>&amp;OK</source>
<translation>&amp;OK</translation>
</message>
<message>
+ <location line="-1987"/>
<source>Look &amp;in:</source>
<translation>Leta &amp;i:</translation>
</message>
<message>
+ <location line="+1"/>
+ <location line="+1977"/>
+ <location line="+16"/>
<source>File &amp;name:</source>
<translation>Fil&amp;namn:</translation>
</message>
<message>
+ <location line="-1992"/>
<source>File &amp;type:</source>
<translation>Fil&amp;typ:</translation>
</message>
<message>
+ <location line="+7"/>
<source>Back</source>
<translation>Tillbaka</translation>
</message>
<message>
+ <location line="+7"/>
<source>One directory up</source>
<translation>En katalog uppåt</translation>
</message>
<message>
+ <location line="+9"/>
<source>Create New Folder</source>
<translation>Skapa ny mapp</translation>
</message>
<message>
+ <location line="+18"/>
<source>List View</source>
<translation>Listvy</translation>
</message>
<message>
+ <location line="+8"/>
<source>Detail View</source>
<translation>Detaljvy</translation>
</message>
<message>
+ <location line="+9"/>
<source>Preview File Info</source>
<translation>Förhandsgranska filinformation</translation>
</message>
<message>
+ <location line="+19"/>
<source>Preview File Contents</source>
<translation>Förhandsgranska filinnehåll</translation>
</message>
<message>
+ <location line="+88"/>
<source>Read-write</source>
<translation>Läs-skriv</translation>
</message>
<message>
+ <location line="+1"/>
<source>Read-only</source>
<translation>Skrivskyddad</translation>
</message>
<message>
+ <location line="+1"/>
<source>Write-only</source>
<translation>Lässkyddad</translation>
</message>
<message>
+ <location line="+1"/>
<source>Inaccessible</source>
<translation>Otillgänglig</translation>
</message>
<message>
+ <location line="+2"/>
<source>Symlink to File</source>
<translation>Symbolisk länk till fil</translation>
</message>
<message>
+ <location line="+1"/>
<source>Symlink to Directory</source>
<translation>Symbolisk länk till katalog</translation>
</message>
<message>
+ <location line="+1"/>
<source>Symlink to Special</source>
<translation>Symbolisk länk till special</translation>
</message>
<message>
+ <location line="+1"/>
<source>File</source>
<translation>Fil</translation>
</message>
<message>
+ <location line="+1"/>
<source>Dir</source>
<translation>Katalog</translation>
</message>
<message>
+ <location line="+1"/>
<source>Special</source>
<translation>Special</translation>
</message>
<message>
+ <location line="+704"/>
+ <location line="+1999"/>
+ <location filename="../src/qt3support/dialogs/q3filedialog_win.cpp" line="+209"/>
<source>Open</source>
<translation>Öppna</translation>
</message>
<message>
+ <location line="-1889"/>
+ <location filename="../src/qt3support/dialogs/q3filedialog_win.cpp" line="+71"/>
<source>Save As</source>
<translation>Spara som</translation>
</message>
<message>
+ <location line="+642"/>
+ <location line="+5"/>
+ <location line="+355"/>
<source>&amp;Open</source>
<translation>&amp;Öppna</translation>
</message>
<message>
+ <location line="-357"/>
+ <location line="+341"/>
<source>&amp;Save</source>
<translation>&amp;Spara</translation>
</message>
<message>
+ <location line="-334"/>
<source>&amp;Rename</source>
<translation>&amp;Byt namn</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Delete</source>
<translation>&amp;Ta bort</translation>
</message>
<message>
+ <location line="+20"/>
<source>R&amp;eload</source>
<translation>Uppdat&amp;era</translation>
</message>
<message>
+ <location line="+4"/>
<source>Sort by &amp;Name</source>
<translation>Sortera efter &amp;namn</translation>
</message>
<message>
+ <location line="+2"/>
<source>Sort by &amp;Size</source>
<translation>Sortera efter &amp;storlek</translation>
</message>
<message>
+ <location line="+1"/>
<source>Sort by &amp;Date</source>
<translation>Sortera efter &amp;datum</translation>
</message>
<message>
+ <location line="+2"/>
<source>&amp;Unsorted</source>
<translation>&amp;Osorterad</translation>
</message>
<message>
+ <location line="+15"/>
<source>Sort</source>
<translation>Sortera</translation>
</message>
<message>
+ <location line="+4"/>
<source>Show &amp;hidden files</source>
<translation>Visa &amp;dolda filer</translation>
</message>
<message>
+ <location line="+31"/>
<source>the file</source>
<translation>filen</translation>
</message>
<message>
+ <location line="+2"/>
<source>the directory</source>
<translation>katalogen</translation>
</message>
<message>
+ <location line="+2"/>
<source>the symlink</source>
<translation>symboliska länken</translation>
</message>
<message>
+ <location line="+3"/>
<source>Delete %1</source>
<translation>Ta bort %1</translation>
</message>
<message>
+ <location line="+1"/>
<source>&lt;qt&gt;Are you sure you wish to delete %1 &quot;%2&quot;?&lt;/qt&gt;</source>
<translation>&lt;qt&gt;Är du säker på att du vill ta bort %1 &quot;%2&quot;?&lt;/qt&gt;</translation>
</message>
<message>
+ <location line="+2"/>
<source>&amp;Yes</source>
<translation>&amp;Ja</translation>
</message>
<message>
+ <location line="+0"/>
<source>&amp;No</source>
<translation>&amp;Nej</translation>
</message>
<message>
+ <location line="+36"/>
<source>New Folder 1</source>
<translation>Ny mapp 1</translation>
</message>
<message>
+ <location line="+5"/>
<source>New Folder</source>
<translation>Ny mapp</translation>
</message>
<message>
+ <location line="+5"/>
<source>New Folder %1</source>
<translation>Ny mapp %1</translation>
</message>
<message>
+ <location line="+98"/>
<source>Find Directory</source>
<translation>Hitta katalog</translation>
</message>
<message>
+ <location line="+5"/>
+ <location line="+108"/>
<source>Directories</source>
<translation>Kataloger</translation>
</message>
<message>
+ <location line="-2"/>
<source>Directory:</source>
<translation>Katalog:</translation>
</message>
<message>
+ <location line="+40"/>
+ <location line="+1009"/>
<source>Error</source>
<translation>Fel</translation>
</message>
<message>
+ <location line="-1008"/>
<source>%1
File not found.
Check path and filename.</source>
@@ -423,28 +995,48 @@ Check path and filename.</source>
Filen hittades inte.
Kontrollera sökväg och filnamn.</translation>
</message>
+ <message>
+ <location filename="../src/qt3support/dialogs/q3filedialog_win.cpp" line="-191"/>
+ <source>All Files (*.*)</source>
+ <translation>Alla filer (*.*)</translation>
+ </message>
+ <message>
+ <location line="+264"/>
+ <source>Open </source>
+ <translation>Öppna</translation>
+ </message>
+ <message>
+ <location line="+107"/>
+ <source>Select a Directory</source>
+ <translation>Välj en katalog</translation>
+ </message>
</context>
<context>
<name>Q3LocalFs</name>
<message>
+ <location filename="../src/qt3support/network/q3localfs.cpp" line="+130"/>
+ <location line="+10"/>
<source>Could not read directory
%1</source>
<translation>Kunde inte läsa katalogen
%1</translation>
</message>
<message>
+ <location line="+45"/>
<source>Could not create directory
%1</source>
<translation>Kunde inte skapa katalogen
%1</translation>
</message>
<message>
+ <location line="+34"/>
<source>Could not remove file or directory
%1</source>
<translation>Kunde inte ta bort filen eller katalogen
%1</translation>
</message>
<message>
+ <location line="+27"/>
<source>Could not rename
%1
to
@@ -455,12 +1047,14 @@ till
%2</translation>
</message>
<message>
+ <location line="+25"/>
<source>Could not open
%1</source>
<translation>Kunde inte öppna
%1</translation>
</message>
<message>
+ <location line="+68"/>
<source>Could not write
%1</source>
<translation>Kunde inte skriva till
@@ -470,10 +1064,12 @@ till
<context>
<name>Q3MainWindow</name>
<message>
+ <location filename="../src/qt3support/widgets/q3mainwindow.cpp" line="+2051"/>
<source>Line up</source>
<translation>Rada upp</translation>
</message>
<message>
+ <location line="+2"/>
<source>Customize...</source>
<translation>Anpassa...</translation>
</message>
@@ -481,6 +1077,7 @@ till
<context>
<name>Q3NetworkProtocol</name>
<message>
+ <location filename="../src/qt3support/network/q3networkprotocol.cpp" line="+854"/>
<source>Operation stopped by the user</source>
<translation>Åtgärden stoppades av användaren</translation>
</message>
@@ -488,6 +1085,8 @@ till
<context>
<name>Q3ProgressDialog</name>
<message>
+ <location filename="../src/qt3support/dialogs/q3progressdialog.cpp" line="+224"/>
+ <location line="+61"/>
<source>Cancel</source>
<translation>Avbryt</translation>
</message>
@@ -495,22 +1094,28 @@ till
<context>
<name>Q3TabDialog</name>
<message>
+ <location filename="../src/qt3support/dialogs/q3tabdialog.cpp" line="+190"/>
+ <location line="+824"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
+ <location line="-366"/>
<source>Apply</source>
<translation>Verkställ</translation>
</message>
<message>
+ <location line="+43"/>
<source>Help</source>
<translation>Hjälp</translation>
</message>
<message>
+ <location line="+45"/>
<source>Defaults</source>
<translation>Standardvärden</translation>
</message>
<message>
+ <location line="+50"/>
<source>Cancel</source>
<translation>Avbryt</translation>
</message>
@@ -518,30 +1123,38 @@ till
<context>
<name>Q3TextEdit</name>
<message>
+ <location filename="../src/qt3support/text/q3textedit.cpp" line="+5429"/>
<source>&amp;Undo</source>
<translation>&amp;Ã…ngra</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Redo</source>
<translation>&amp;Gör om</translation>
</message>
<message>
+ <location line="+5"/>
<source>Cu&amp;t</source>
<translation>Klipp u&amp;t</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Copy</source>
<translation>&amp;Kopiera</translation>
</message>
<message>
+ <location line="+2"/>
<source>&amp;Paste</source>
<translation>Klistra &amp;in</translation>
</message>
<message>
+ <location line="+3"/>
<source>Clear</source>
<translation>Töm</translation>
</message>
<message>
+ <location line="+4"/>
+ <location line="+2"/>
<source>Select All</source>
<translation>Markera alla</translation>
</message>
@@ -549,54 +1162,71 @@ till
<context>
<name>Q3TitleBar</name>
<message>
+ <location filename="../src/plugins/accessible/compat/q3complexwidgets.cpp" line="+246"/>
<source>System</source>
<translation>System</translation>
</message>
<message>
+ <location line="+3"/>
<source>Restore up</source>
<translation>Återställ uppåt</translation>
</message>
<message>
+ <location line="+1"/>
<source>Minimize</source>
<translation>Minimera</translation>
</message>
<message>
+ <location line="+3"/>
<source>Restore down</source>
<translation>Återställ nedåt</translation>
</message>
<message>
+ <location line="+1"/>
<source>Maximize</source>
<translation>Maximera</translation>
</message>
<message>
+ <location line="+2"/>
<source>Close</source>
<translation>Stäng</translation>
</message>
<message>
+ <location line="+18"/>
<source>Contains commands to manipulate the window</source>
<translation>Innehåller kommandon för att manipulera fönstret</translation>
</message>
<message>
+ <location line="+3"/>
+ <source>Puts a minimized window back to normal</source>
+ <translation>Återställer ett minimerat fönster till normalt</translation>
+ </message>
+ <message>
<source>Puts a minimized back to normal</source>
- <translation>Återställer ett minimerat till normalt</translation>
+ <translation type="obsolete">Återställer ett minimerat till normalt</translation>
</message>
<message>
+ <location line="+1"/>
<source>Moves the window out of the way</source>
<translation>Flyttar fönstret ur vägen</translation>
</message>
<message>
+ <location line="+3"/>
<source>Puts a maximized window back to normal</source>
<translation>Återställer ett maximerat fönster tillbaka till normalt</translation>
</message>
<message>
+ <location line="+1"/>
<source>Makes the window full screen</source>
<translation>Gör fönstret till helskärm</translation>
</message>
<message>
+ <location line="+2"/>
<source>Closes the window</source>
<translation>Stänger fönstret</translation>
</message>
<message>
+ <location line="+2"/>
<source>Displays the name of the window and contains controls to manipulate it</source>
<translation>Visar namnet på fönstret och innehåller kontroller för att manipulera det</translation>
</message>
@@ -604,6 +1234,7 @@ till
<context>
<name>Q3ToolBar</name>
<message>
+ <location filename="../src/qt3support/widgets/q3toolbar.cpp" line="+692"/>
<source>More...</source>
<translation>Mer...</translation>
</message>
@@ -611,38 +1242,51 @@ till
<context>
<name>Q3UrlOperator</name>
<message>
+ <location filename="../src/qt3support/network/q3urloperator.cpp" line="+386"/>
+ <location line="+260"/>
+ <location line="+4"/>
<source>The protocol `%1&apos; is not supported</source>
- <translation>Protokollet \&quot;%1\&quot; stöds inte</translation>
+ <translation>Protokollet &quot;%&quot; stöds inte</translation>
</message>
<message>
+ <location line="-260"/>
<source>The protocol `%1&apos; does not support listing directories</source>
<translation>Protokollet \&quot;%1\&quot; har inte stöd för att lista kataloger</translation>
</message>
<message>
+ <location line="+3"/>
<source>The protocol `%1&apos; does not support creating new directories</source>
<translation>Protokollet \&quot;%1\&quot; har inte stöd för att skapa nya kataloger</translation>
</message>
<message>
+ <location line="+3"/>
<source>The protocol `%1&apos; does not support removing files or directories</source>
<translation>Protokollet \&quot;%1\&quot; har inte stöd för att ta bort filer eller kataloger</translation>
</message>
<message>
+ <location line="+3"/>
<source>The protocol `%1&apos; does not support renaming files or directories</source>
<translation>Protokollet \&quot;%1\&quot; har inte stöd för att byta namn på filer eller kataloger</translation>
</message>
<message>
+ <location line="+3"/>
<source>The protocol `%1&apos; does not support getting files</source>
<translation>Protokollet \&quot;%1\&quot; har inte stöd för att hämta filer</translation>
</message>
<message>
+ <location line="+3"/>
<source>The protocol `%1&apos; does not support putting files</source>
<translation>Protokollet \&quot;%1\&quot; har inte stöd för att lämna filer</translation>
</message>
<message>
+ <location line="+243"/>
+ <location line="+4"/>
<source>The protocol `%1&apos; does not support copying or moving files or directories</source>
<translation>Protokollet \&quot;%1\&quot; har inte stöd för att kopiera eller flytta filer eller kataloger</translation>
</message>
<message>
+ <location line="+237"/>
+ <location line="+1"/>
<source>(unknown)</source>
<translation>(okänt)</translation>
</message>
@@ -650,22 +1294,27 @@ till
<context>
<name>Q3Wizard</name>
<message>
+ <location filename="../src/qt3support/dialogs/q3wizard.cpp" line="+177"/>
<source>&amp;Cancel</source>
<translation>&amp;Avbryt</translation>
</message>
<message>
+ <location line="+1"/>
<source>&lt; &amp;Back</source>
<translation>&lt; Till&amp;baka</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Next &gt;</source>
<translation>&amp;Nästa &gt;</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Finish</source>
- <translation>&amp;Färdig</translation>
+ <translation>&amp;Färdigställ</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Help</source>
<translation>&amp;Hjälp</translation>
</message>
@@ -673,72 +1322,141 @@ till
<context>
<name>QAbstractSocket</name>
<message>
+ <location filename="../src/network/socket/qabstractsocket.cpp" line="+549"/>
+ <location line="+839"/>
+ <location line="+220"/>
+ <source>Operation on socket is not supported</source>
+ <translation>Uttagsåtgärden stöds inte</translation>
+ </message>
+ <message>
+ <location line="-692"/>
+ <location filename="../src/network/socket/qhttpsocketengine.cpp" line="+629"/>
+ <location filename="../src/network/socket/qsocks5socketengine.cpp" line="+661"/>
+ <location line="+26"/>
<source>Host not found</source>
<translation>Värden hittades inte</translation>
</message>
<message>
+ <location line="+50"/>
+ <location filename="../src/network/socket/qhttpsocketengine.cpp" line="+3"/>
+ <location filename="../src/network/socket/qsocks5socketengine.cpp" line="+4"/>
<source>Connection refused</source>
<translation>Anslutningen nekades</translation>
</message>
<message>
+ <location line="+142"/>
+ <source>Connection timed out</source>
+ <translation>Tidsgränsen för anslutning överstegs</translation>
+ </message>
+ <message>
+ <location filename="../src/network/access/qhttpnetworkconnection.cpp" line="+647"/>
+ <location filename="../src/network/socket/qabstractsocket.cpp" line="+703"/>
<source>Socket operation timed out</source>
<translation>Tidsgräns för uttagsåtgärd överstegs</translation>
</message>
<message>
+ <location filename="../src/network/socket/qabstractsocket.cpp" line="+380"/>
<source>Socket is not connected</source>
<translation>Uttaget är inte anslutet</translation>
</message>
+ <message>
+ <location filename="../src/network/socket/qsocks5socketengine.cpp" line="-8"/>
+ <source>Network unreachable</source>
+ <translation>Nätverket är inte nåbart</translation>
+ </message>
</context>
<context>
<name>QAbstractSpinBox</name>
<message>
+ <location filename="../src/gui/widgets/qabstractspinbox.cpp" line="+1263"/>
<source>&amp;Step up</source>
<translation>&amp;Stega uppåt</translation>
</message>
<message>
+ <location line="+2"/>
<source>Step &amp;down</source>
<translation>Stega &amp;nedåt</translation>
</message>
<message>
+ <location line="-8"/>
<source>&amp;Select All</source>
<translation>&amp;Markera allt</translation>
</message>
</context>
<context>
+ <name>QAccessibleButton</name>
+ <message>
+ <location filename="../src/plugins/accessible/widgets/simplewidgets.cpp" line="+250"/>
+ <source>Press</source>
+ <translation>Tryck</translation>
+ </message>
+</context>
+<context>
<name>QApplication</name>
<message>
+ <location filename="../src/gui/accessible/qaccessibleobject.cpp" line="+376"/>
<source>Activate</source>
<translation>Aktivera</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qmessagebox.h" line="+354"/>
<source>Executable &apos;%1&apos; requires Qt %2, found Qt %3.</source>
<translation>Binären \&quot;%1\&quot; kräver Qt %2, hittade Qt %3.</translation>
</message>
<message>
+ <location line="+2"/>
<source>Incompatible Qt Library Error</source>
<translation>Inkompatibelt Qt-biblioteksfel</translation>
</message>
<message>
+ <location filename="../src/gui/kernel/qapplication.cpp" line="-13"/>
<source>QT_LAYOUT_DIRECTION</source>
<comment>Translate this string to the string &apos;LTR&apos; in left-to-right languages or to &apos;RTL&apos; in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout.</comment>
<translation>LTR</translation>
</message>
<message>
+ <location filename="../src/gui/accessible/qaccessibleobject.cpp" line="+2"/>
<source>Activates the program&apos;s main window</source>
<translation>Aktiverar programmets huvudfönster</translation>
</message>
</context>
<context>
+ <name>QAxSelect</name>
+ <message>
+ <location filename="../src/activeqt/container/qaxselect.ui"/>
+ <source>Select ActiveX Control</source>
+ <translation>Välj ActiveX Control</translation>
+ </message>
+ <message>
+ <location/>
+ <source>OK</source>
+ <translation>OK</translation>
+ </message>
+ <message>
+ <location/>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Avbryt</translation>
+ </message>
+ <message>
+ <location/>
+ <source>COM &amp;Object:</source>
+ <translation>COM-&amp;objekt:</translation>
+ </message>
+</context>
+<context>
<name>QCheckBox</name>
<message>
+ <location filename="../src/plugins/accessible/widgets/simplewidgets.cpp" line="-136"/>
<source>Uncheck</source>
<translation>Avkryssa</translation>
</message>
<message>
+ <location line="+3"/>
<source>Check</source>
<translation>Kryssa</translation>
</message>
<message>
+ <location line="+1"/>
<source>Toggle</source>
<translation>Växla</translation>
</message>
@@ -746,65 +1464,85 @@ till
<context>
<name>QColorDialog</name>
<message>
+ <location filename="../src/gui/dialogs/qcolordialog.cpp" line="+1378"/>
<source>Hu&amp;e:</source>
<translation>Nya&amp;ns:</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Sat:</source>
<translation>&amp;Mättnad:</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Val:</source>
<translation>&amp;Ljushet:</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Red:</source>
<translation>&amp;Röd:</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Green:</source>
<translation>&amp;Grön:</translation>
</message>
<message>
+ <location line="+1"/>
<source>Bl&amp;ue:</source>
<translation>Bl&amp;Ã¥:</translation>
</message>
<message>
+ <location line="+1"/>
<source>A&amp;lpha channel:</source>
<translation>Alfa&amp;kanal:</translation>
</message>
<message>
+ <location line="+101"/>
+ <source>Select Color</source>
+ <translation>Välj färg</translation>
+ </message>
+ <message>
+ <location line="+183"/>
<source>&amp;Basic colors</source>
<translation>&amp;Basfärger</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Custom colors</source>
<translation>&amp;Anpassade färger</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Add to Custom Colors</source>
<translation>&amp;Lägg till i anpassade färger</translation>
</message>
<message>
<source>Select color</source>
- <translation>Välj färg</translation>
+ <translation type="obsolete">Välj färg</translation>
</message>
</context>
<context>
<name>QComboBox</name>
<message>
+ <location filename="../src/plugins/accessible/widgets/complexwidgets.cpp" line="+1776"/>
+ <location line="+65"/>
<source>Open</source>
<translation>Öppna</translation>
</message>
<message>
+ <location filename="../src/gui/itemviews/qitemeditorfactory.cpp" line="+556"/>
<source>False</source>
<translation>Falskt</translation>
</message>
<message>
+ <location line="+1"/>
<source>True</source>
<translation>Sant</translation>
</message>
<message>
+ <location filename="../src/plugins/accessible/widgets/complexwidgets.cpp" line="+0"/>
<source>Close</source>
<translation>Stäng</translation>
</message>
@@ -812,11 +1550,13 @@ till
<context>
<name>QCoreApplication</name>
<message>
+ <location filename="../src/corelib/kernel/qsystemsemaphore_symbian.cpp" line="+78"/>
<source>%1: permission denied</source>
<comment>QSystemSemaphore</comment>
- <translation>%1: åtkomst nekas</translation>
+ <translation>%1: åtkomst nekad</translation>
</message>
<message>
+ <location line="-13"/>
<source>%1: already exists</source>
<comment>QSystemSemaphore</comment>
<translation>%1: finns redan</translation>
@@ -824,29 +1564,40 @@ till
<message>
<source>%1: doesn&apos;t exists</source>
<comment>QSystemSemaphore</comment>
+ <translation type="obsolete">%1: finns inte</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>%1: does not exist</source>
+ <comment>QSystemSemaphore</comment>
<translation>%1: finns inte</translation>
</message>
<message>
+ <location line="+5"/>
<source>%1: out of resources</source>
<comment>QSystemSemaphore</comment>
<translation>%1: slut på resurser</translation>
</message>
<message>
+ <location line="+8"/>
<source>%1: unknown error %2</source>
<comment>QSystemSemaphore</comment>
<translation>%1: okänt fel %2</translation>
</message>
<message>
+ <location filename="../src/corelib/kernel/qsystemsemaphore_unix.cpp" line="+119"/>
<source>%1: key is empty</source>
<comment>QSystemSemaphore</comment>
<translation>%1: nyckeln är tom</translation>
</message>
<message>
+ <location line="+12"/>
<source>%1: unable to make key</source>
<comment>QSystemSemaphore</comment>
<translation>%1: kunde inte skapa nyckel</translation>
</message>
<message>
+ <location line="+9"/>
<source>%1: ftok failed</source>
<comment>QSystemSemaphore</comment>
<translation>%1: ftok misslyckades</translation>
@@ -855,18 +1606,22 @@ till
<context>
<name>QDB2Driver</name>
<message>
+ <location filename="../src/sql/drivers/db2/qsql_db2.cpp" line="+1253"/>
<source>Unable to connect</source>
<translation>Kunde inte ansluta</translation>
</message>
<message>
+ <location line="+298"/>
<source>Unable to commit transaction</source>
<translation>Kunde inte verkställa transaktion</translation>
</message>
<message>
+ <location line="+17"/>
<source>Unable to rollback transaction</source>
<translation>Kunde inte rulla tillbaka transaktion</translation>
</message>
<message>
+ <location line="+15"/>
<source>Unable to set autocommit</source>
<translation>Kunde inte ställa in automatisk verkställning</translation>
</message>
@@ -874,26 +1629,33 @@ till
<context>
<name>QDB2Result</name>
<message>
+ <location line="-1030"/>
+ <location line="+240"/>
<source>Unable to execute statement</source>
<translation>Kunde inte köra frågesats</translation>
</message>
<message>
+ <location line="-203"/>
<source>Unable to prepare statement</source>
<translation>Kunde inte förbereda frågesats</translation>
</message>
<message>
+ <location line="+193"/>
<source>Unable to bind variable</source>
<translation>Kunde inte binda variabel</translation>
</message>
<message>
+ <location line="+89"/>
<source>Unable to fetch record %1</source>
<translation>Kunde inte hämta posten %1</translation>
</message>
<message>
+ <location line="+19"/>
<source>Unable to fetch next</source>
<translation>Kunde inte hämta nästa</translation>
</message>
<message>
+ <location line="+21"/>
<source>Unable to fetch first</source>
<translation>Kunde inte hämta första</translation>
</message>
@@ -901,33 +1663,1224 @@ till
<context>
<name>QDateTimeEdit</name>
<message>
+ <location filename="../src/gui/widgets/qdatetimeedit.cpp" line="+2274"/>
<source>AM</source>
<translation>AM</translation>
</message>
<message>
+ <location line="+0"/>
<source>am</source>
<translation>am</translation>
</message>
<message>
+ <location line="+2"/>
<source>PM</source>
<translation>PM</translation>
</message>
<message>
+ <location line="+0"/>
<source>pm</source>
<translation>pm</translation>
</message>
</context>
<context>
+ <name>QDeclarativeAbstractAnimation</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativeanimation.cpp" line="+172"/>
+ <source>Cannot animate non-existent property &quot;%1&quot;</source>
+ <translation>Kan inte animera en icke-existerande egenskap &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Cannot animate read-only property &quot;%1&quot;</source>
+ <translation>Kan inte animera en skrivskyddad egenskap &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativeutilmodule.cpp" line="+123"/>
+ <location line="+45"/>
+ <source>Animation is an abstract class</source>
+ <translation>Animation är en abstrakt klass</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeAnchorAnimation</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativeanimation.cpp" line="+2686"/>
+ <source>Cannot set a duration of &lt; 0</source>
+ <translation>Kan inte ställa in en varaktighet mindre än 0</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeAnchors</name>
+ <message>
+ <location filename="../src/declarative/graphicsitems/qdeclarativeanchors.cpp" line="+198"/>
+ <source>Possible anchor loop detected on fill.</source>
+ <translation>Möjlig förankringssnurra detekterad vid ifyllnad.</translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Possible anchor loop detected on centerIn.</source>
+ <translation>Möjlig förankringssnurra detekterad för centerIn.</translation>
+ </message>
+ <message>
+ <location line="+208"/>
+ <location line="+34"/>
+ <location line="+646"/>
+ <location line="+37"/>
+ <source>Cannot anchor to an item that isn&apos;t a parent or sibling.</source>
+ <translation>Kan inte ankra till ett objekt som inte är överliggande eller på samma nivå.</translation>
+ </message>
+ <message>
+ <location line="-570"/>
+ <source>Possible anchor loop detected on vertical anchor.</source>
+ <translation>Möjlig förankringssnurra detekterad för vertikal förankring.</translation>
+ </message>
+ <message>
+ <location line="+95"/>
+ <source>Possible anchor loop detected on horizontal anchor.</source>
+ <translation>Möjlig förankringssnurra detekterad för horisontell förankring.</translation>
+ </message>
+ <message>
+ <location line="+422"/>
+ <source>Cannot specify left, right, and hcenter anchors.</source>
+ <translation>Kan inte ange vänster-, höger- eller horisontell centralförankring.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <location line="+37"/>
+ <source>Cannot anchor to a null item.</source>
+ <translation>Kan inte förankra till ett objekt som är null.</translation>
+ </message>
+ <message>
+ <location line="-34"/>
+ <source>Cannot anchor a horizontal edge to a vertical edge.</source>
+ <translation>Kan inte förankra en horisontell kant till en vertikal kant.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <location line="+37"/>
+ <source>Cannot anchor item to self.</source>
+ <translation>Kan inte förankra objekt till sig själv.</translation>
+ </message>
+ <message>
+ <location line="-25"/>
+ <source>Cannot specify top, bottom, and vcenter anchors.</source>
+ <translation>Kan inte ange över-, under- eller vertikal centralförankring.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Baseline anchor cannot be used in conjunction with top, bottom, or vcenter anchors.</source>
+ <translation>Baslinjeförankring kan inte användas tillsammans med över-, under- eller vertikal centralförankring.</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Cannot anchor a vertical edge to a horizontal edge.</source>
+ <translation>Kan inte förankra en vertikal kant till en horisontell kant.</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeAnimatedImage</name>
+ <message>
+ <location filename="../src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp" line="+103"/>
+ <location line="+103"/>
+ <source>Qt was built without support for QMovie</source>
+ <translation>Qt byggdes utan stöd för QMovie</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeApplication</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativeutilmodule.cpp" line="-89"/>
+ <source>Application is an abstract class</source>
+ <translation>Application är en abstrakt klass</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeBehavior</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativebehavior.cpp" line="+126"/>
+ <source>Cannot change the animation assigned to a Behavior.</source>
+ <translation>Kan inte ändra animeringen tilldelad till Behavior.</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeBinding</name>
+ <message>
+ <location filename="../src/declarative/qml/qdeclarativebinding.cpp" line="+456"/>
+ <source>Binding loop detected for property &quot;%1&quot;</source>
+ <translation>Bindningssnurra detekterades för egenskap &quot;%1&quot;</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeCompiledBindings</name>
+ <message>
+ <location filename="../src/declarative/qml/qdeclarativecompiledbindings.cpp" line="+380"/>
+ <source>Binding loop detected for property &quot;%1&quot;</source>
+ <translation>Bindningssnurra detekterades för egenskap &quot;%1&quot;</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeCompiler</name>
+ <message>
+ <location filename="../src/declarative/qml/qdeclarativecompiler.cpp" line="+185"/>
+ <location line="+1662"/>
+ <location line="+205"/>
+ <location line="+81"/>
+ <location line="+75"/>
+ <location line="+582"/>
+ <source>Invalid property assignment: &quot;%1&quot; is a read-only property</source>
+ <translation>Ogiltig egenskapstilldelning: &quot;%1&quot; är en skrivskyddad egenskap</translation>
+ </message>
+ <message>
+ <location line="-2596"/>
+ <source>Invalid property assignment: unknown enumeration</source>
+ <translation>Ogiltig egenskapstilldelning: okänt uppräkningsvärde</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Invalid property assignment: string expected</source>
+ <translation>Ogiltig egenskapstilldelning: sträng förväntades</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Invalid property assignment: url expected</source>
+ <translation>Ogiltig egenskapstilldelning: webbadress förväntades</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Invalid property assignment: unsigned int expected</source>
+ <translation>Ogiltig egenskapstilldelning: heltal utan tecken förväntades</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Invalid property assignment: int expected</source>
+ <translation>Ogiltig egenskapstilldelning: heltal förväntades</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <location line="+3"/>
+ <source>Invalid property assignment: number expected</source>
+ <translation>Ogiltig egenskapstilldelning: tal förväntades</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Invalid property assignment: color expected</source>
+ <translation>Ogiltig egenskapstilldelning: färg förväntades</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Invalid property assignment: date expected</source>
+ <translation>Ogiltig egenskapstilldelning: datum förväntades</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Invalid property assignment: time expected</source>
+ <translation>Ogiltig egenskapstilldelning: tid förväntades</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Invalid property assignment: datetime expected</source>
+ <translation>Ogiltig egenskapstilldelning: datum och tid förväntades</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Invalid property assignment: point expected</source>
+ <translation>Ogiltig egenskapstilldelning: punkt förväntades</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Invalid property assignment: size expected</source>
+ <translation>Ogiltig egenskapstilldelning: storlek förväntades</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Invalid property assignment: rect expected</source>
+ <translation>Ogiltig egenskapstilldelning: rektangel förväntades</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Invalid property assignment: boolean expected</source>
+ <translation>Ogiltig egenskapstilldelning: Boolean förväntades</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Invalid property assignment: 3D vector expected</source>
+ <translation>Ogiltig egenskapstilldelning: tredimensionell vektor förväntades</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Invalid property assignment: unsupported type &quot;%1&quot;</source>
+ <translation>Ogiltig egenskapstilldelning: typen &quot;%1&quot; stöds inte</translation>
+ </message>
+ <message>
+ <location line="+282"/>
+ <source>Element is not creatable.</source>
+ <translation>Elementet går inte att skapa.</translation>
+ </message>
+ <message>
+ <location line="+644"/>
+ <source>Component elements may not contain properties other than id</source>
+ <translation>Komponentelement får inte innehålla andra egenskaper än ID</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Invalid component id specification</source>
+ <translation>Ogiltig specifikation av komponent-ID</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <location line="+515"/>
+ <source>id is not unique</source>
+ <translation>ID-värdet är inte unikt</translation>
+ </message>
+ <message>
+ <location line="-505"/>
+ <source>Invalid component body specification</source>
+ <translation>Ogiltig specifikation av component body</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Component objects cannot declare new properties.</source>
+ <translation>Komponentobjekt kan inte deklarera nya egenskaper.</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Component objects cannot declare new signals.</source>
+ <translation>Komponentobjekt kan inte deklarera nya signaler.</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Component objects cannot declare new functions.</source>
+ <translation>Komponentobjekt kan inte deklarera nya funktioner.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Cannot create empty component specification</source>
+ <translation>Kan inte skapa tom komponentspecifikation</translation>
+ </message>
+ <message>
+ <location line="+88"/>
+ <location line="+121"/>
+ <source>&quot;%1.%2&quot; is not available in %3 %4.%5.</source>
+ <translation>&quot;%1.%2&quot; är inte tillgänglig i %3 %4.%5.</translation>
+ </message>
+ <message>
+ <location line="-119"/>
+ <location line="+121"/>
+ <source>&quot;%1.%2&quot; is not available due to component versioning.</source>
+ <translation>&quot;%1.%2&quot; är inte tillgänglig på grund av komponentversion.</translation>
+ </message>
+ <message>
+ <location line="-110"/>
+ <source>Incorrectly specified signal assignment</source>
+ <translation>Felaktigt angiven signaltilldelning</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>Cannot assign a value to a signal (expecting a script to be run)</source>
+ <translation>Kan inte tilldela ett värde till en signal (förväntar att ett skript ska köras)</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Empty signal assignment</source>
+ <translation>Tom signaltilldelning</translation>
+ </message>
+ <message>
+ <location line="+38"/>
+ <source>Empty property assignment</source>
+ <translation>Tom egenskapstilldelning</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>Attached properties cannot be used here</source>
+ <translation>Anslutna egenskaper kan inte användas här</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <location line="+128"/>
+ <source>Non-existent attached object</source>
+ <translation>Anslutet objekt existerar inte</translation>
+ </message>
+ <message>
+ <location line="-124"/>
+ <location line="+127"/>
+ <source>Invalid attached object assignment</source>
+ <translation>Ogiltig tilldelning av anslutet objekt</translation>
+ </message>
+ <message>
+ <location line="-48"/>
+ <source>Cannot assign to non-existent default property</source>
+ <translation>Kan inte tilldela en standardegenskap som inte finns</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <location line="+356"/>
+ <location line="+3"/>
+ <source>Cannot assign to non-existent property &quot;%1&quot;</source>
+ <translation>Kan inte tilldela till egenskapen &quot;%1 &quot; som inte finns</translation>
+ </message>
+ <message>
+ <location line="-329"/>
+ <source>Invalid use of namespace</source>
+ <translation>Ogiltig användning av namnrymd</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Not an attached property name</source>
+ <translation>Inte ett namn på en ansluten egenskap</translation>
+ </message>
+ <message>
+ <location line="+182"/>
+ <source>Invalid use of id property</source>
+ <translation>Ogiltig användning av id-egenskap</translation>
+ </message>
+ <message>
+ <location line="+87"/>
+ <location line="+2"/>
+ <source>Property has already been assigned a value</source>
+ <translation>Egenskapen har redan tilldelats ett värde</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <location line="+7"/>
+ <source>Invalid grouped property access</source>
+ <translation>Ogiltig grupperad egenskapsåtkomst</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Cannot assign a value directly to a grouped property</source>
+ <translation>Kan inte tilldela ett värde direkt till en grupperad egenskap</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Invalid property use</source>
+ <translation>Ogiltig användning av egenskap</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Property assignment expected</source>
+ <translation>Egenskapstilldelning förväntades</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Single property assignment expected</source>
+ <translation>Enstaka egenskapstilldelning förväntades</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Unexpected object assignment</source>
+ <translation>Oväntad objekttilldelning</translation>
+ </message>
+ <message>
+ <location line="+65"/>
+ <source>Cannot assign object to list</source>
+ <translation>Kan inte tilldela objekt till lista</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Can only assign one binding to lists</source>
+ <translation>Kan bara tilldela en bindning till listor</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Cannot assign primitives to lists</source>
+ <translation>Kan inte tilldela primitiver till listor</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Cannot assign multiple values to a script property</source>
+ <translation>Kan inte tilldela flera värden till en skriptegenskap</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Invalid property assignment: script expected</source>
+ <translation>Ogiltig egenskapstilldelning: skript förväntades</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Cannot assign multiple values to a singular property</source>
+ <translation>Kan inte tilldela flera värden till en enskild egenskap</translation>
+ </message>
+ <message>
+ <location line="+93"/>
+ <source>Cannot assign object to property</source>
+ <translation>Kan inte tilldela objekt till egenskap</translation>
+ </message>
+ <message>
+ <location line="+50"/>
+ <source>&quot;%1&quot; cannot operate on &quot;%2&quot;</source>
+ <translation>&quot;%1&quot; kan inte användas för &quot;%2&quot;</translation>
+ </message>
+ <message>
+ <location line="+164"/>
+ <source>Duplicate default property</source>
+ <translation>Duplicerad fördefinierad egenskap</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Duplicate property name</source>
+ <translation>Duplicerat egenskapsnamn</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Property names cannot begin with an upper case letter</source>
+ <translation>Egenskapsnamn kan inte börja med en stor bokstav</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Illegal property name</source>
+ <translation>Ogiltigt egenskapsnamn</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Duplicate signal name</source>
+ <translation>Duplicerat signalnamn</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Signal names cannot begin with an upper case letter</source>
+ <translation>Signalnamn kan inte börja med en stor bokstav</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Illegal signal name</source>
+ <translation>Ogiltigt signalnamn</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Duplicate method name</source>
+ <translation>Duplicerat metodnamn</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Method names cannot begin with an upper case letter</source>
+ <translation>Metodnamn kan inte börja med en stor bokstav</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Illegal method name</source>
+ <translation>Felaktigt metodnamn</translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>Property value set multiple times</source>
+ <translation>Egenskapsvärde angivet flera gånger</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Invalid property nesting</source>
+ <translation>Ogiltig nästling av egenskaper</translation>
+ </message>
+ <message>
+ <location line="+52"/>
+ <source>Cannot override FINAL property</source>
+ <translation>Kan inte överskrida egenskapen FINAL</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Invalid property type</source>
+ <translation>Ogiltig egenskapstyp</translation>
+ </message>
+ <message>
+ <location line="+177"/>
+ <source>Invalid empty ID</source>
+ <translation>Ogiltigt tomt ID</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>IDs cannot start with an uppercase letter</source>
+ <translation>Inget ID får börja med en stor bokstav</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>IDs must start with a letter or underscore</source>
+ <translation>Alla ID måste börja med en bokstav eller ett understreck</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>IDs must contain only letters, numbers, and underscores</source>
+ <translation>ID får bara innehålla bokstäver, siffror och understreck</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>ID illegally masks global JavaScript property</source>
+ <translation>ID maskerar felaktigt global Javascript-egenskap</translation>
+ </message>
+ <message>
+ <location line="+31"/>
+ <location line="+9"/>
+ <source>No property alias location</source>
+ <translation>Ingen aliasplats för egenskap</translation>
+ </message>
+ <message>
+ <location line="-4"/>
+ <location line="+25"/>
+ <location line="+7"/>
+ <location line="+7"/>
+ <location line="+6"/>
+ <source>Invalid alias location</source>
+ <translation>Ogiltig aliasplats</translation>
+ </message>
+ <message>
+ <location line="-36"/>
+ <source>Invalid alias reference. An alias reference must be specified as &lt;id&gt;, &lt;id&gt;.&lt;property&gt; or &lt;id&gt;.&lt;value property&gt;.&lt;property&gt;</source>
+ <translation>Ogiltig aliasreferens En aliasreferens måste anges som &lt;id&gt;, &lt;id&gt;.&lt;property&gt; eller &lt;id&gt;.&lt;value property&gt;.&lt;property&gt;</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Invalid alias reference. Unable to find id &quot;%1&quot;</source>
+ <translation>Ogiltig aliasreferens. Kan inte hitta id &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Alias property exceeds alias bounds</source>
+ <translation>Aliasegenskap överskrider aliasgränser</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeComponent</name>
+ <message>
+ <location filename="../src/declarative/qml/qdeclarativecomponent.cpp" line="+531"/>
+ <source>Invalid empty URL</source>
+ <translation>Ogiltig tom webbadress</translation>
+ </message>
+ <message>
+ <location line="+148"/>
+ <source>createObject: value is not an object</source>
+ <translation>createObject: värdet är inte ett objekt</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeConnections</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativeconnections.cpp" line="+205"/>
+ <location line="+64"/>
+ <source>Cannot assign to non-existent property &quot;%1&quot;</source>
+ <translation>Kan inte tilldela till egenskapen &quot;%1&quot; som inte finns</translation>
+ </message>
+ <message>
+ <location line="-54"/>
+ <source>Connections: nested objects not allowed</source>
+ <translation>Connections: nästlade objekt tillåts inte</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Connections: syntax error</source>
+ <translation>Connections: syntaxfel</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Connections: script expected</source>
+ <translation>Connections: skript förväntades</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeEngine</name>
+ <message>
+ <location filename="../src/declarative/qml/qdeclarativesqldatabase.cpp" line="+211"/>
+ <source>executeSql called outside transaction()</source>
+ <translation>executeSql anropad utanför transaction()</translation>
+ </message>
+ <message>
+ <location line="+58"/>
+ <source>Read-only Transaction</source>
+ <translation>Skrivskyddad transaktion</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>Version mismatch: expected %1, found %2</source>
+ <translation>Version matchar inte: förväntade %1, hittade %2</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>SQL transaction failed</source>
+ <translation>SQL-transaktion misslyckades</translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>transaction: missing callback</source>
+ <translation>transaction: saknar återanrop</translation>
+ </message>
+ <message>
+ <location line="+59"/>
+ <location line="+15"/>
+ <source>SQL: database version mismatch</source>
+ <translation>SQL: databasversion matchar inte</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeFlipable</name>
+ <message>
+ <location filename="../src/declarative/graphicsitems/qdeclarativeflipable.cpp" line="+138"/>
+ <source>front is a write-once property</source>
+ <translation>front är en egenskap som kan skrivas en gång</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>back is a write-once property</source>
+ <translation>back är en egenskap som kan skrivas en gång</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeImportDatabase</name>
+ <message>
+ <location filename="../src/declarative/qml/qdeclarativeimport.cpp" line="+360"/>
+ <source>cannot load module &quot;%1&quot;: File name case mismatch for &quot;%2&quot;</source>
+ <translation>kan inte ladda modul &quot;%1&quot;: Filnamnets stora och små bokstäver stämmer inte för &quot;%2&quot;</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>module &quot;%1&quot; definition &quot;%2&quot; not readable</source>
+ <translation>modul &quot;%1&quot; definition &quot;%2&quot; är inte läsbar</translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>plugin cannot be loaded for module &quot;%1&quot;: %2</source>
+ <translation>insticksprogram kan inte laddas för modulen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>module &quot;%1&quot; plugin &quot;%2&quot; not found</source>
+ <translation>modul &quot;%1&quot; insticksprogram &quot;%2&quot; hittades inte</translation>
+ </message>
+ <message>
+ <location line="+133"/>
+ <location line="+68"/>
+ <source>module &quot;%1&quot; version %2.%3 is not installed</source>
+ <translation>modul &quot;%1&quot; version %2.%3 är inte installerad</translation>
+ </message>
+ <message>
+ <location line="-66"/>
+ <source>module &quot;%1&quot; is not installed</source>
+ <translation>modul &quot;%1&quot; är inte installerad</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <location line="+20"/>
+ <source>&quot;%1&quot;: no such directory</source>
+ <translation>&quot;%1&quot;: ingen sådan katalog</translation>
+ </message>
+ <message>
+ <location line="-2"/>
+ <source>import &quot;%1&quot; has no qmldir and no namespace</source>
+ <translation>import &quot;%1&quot; har inget qmldir och ingen namnrymd</translation>
+ </message>
+ <message>
+ <location line="+58"/>
+ <source>- %1 is not a namespace</source>
+ <translation>- %1 är inte en namnrymd</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>- nested namespaces not allowed</source>
+ <translation>- nästlade namnrymder tillåts inte</translation>
+ </message>
+ <message>
+ <location line="+47"/>
+ <location line="+4"/>
+ <source>local directory</source>
+ <translation>lokal katalog</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>is ambiguous. Found in %1 and in %2</source>
+ <translation>är tvetydig. Hittades i %1 och i %2</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>is ambiguous. Found in %1 in version %2.%3 and %4.%5</source>
+ <translation>är tvetydig. Hittades i %1 i version %2.%3 och %4.%5</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>is instantiated recursively</source>
+ <translation>instantieras rekursivt</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>is not a type</source>
+ <translation>är inte en typ</translation>
+ </message>
+ <message>
+ <location line="+324"/>
+ <source>File name case mismatch for &quot;%2&quot;</source>
+ <translation>Filnamnets stora och små bokstäver stämmer inte för &quot;%2&quot;</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeKeyNavigationAttached</name>
+ <message>
+ <location filename="../src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp" line="-31"/>
+ <location line="+83"/>
+ <source>KeyNavigation is only available via attached properties</source>
+ <translation>Nyckelnavigering är bara tillgänglig via anslutna egenskaper</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeKeysAttached</name>
+ <message>
+ <location line="-82"/>
+ <location line="+83"/>
+ <source>Keys is only available via attached properties</source>
+ <translation>Nycklar är bara tillgängliga via anslutna egenskaper</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeLayoutMirroringAttached</name>
+ <message>
+ <location filename="../src/declarative/graphicsitems/qdeclarativeitem.cpp" line="+795"/>
+ <source>LayoutDirection attached property only works with Items</source>
+ <translation>LayoutDirection ansluten egenskap fungerar bara med objekt</translation>
+ </message>
+ <message>
+ <location filename="../src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp" line="-58"/>
+ <source>LayoutMirroring is only available via attached properties</source>
+ <translation>LayoutMirroring är bara tillgänglig via anslutna egenskaper</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeListModel</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativelistmodel.cpp" line="+392"/>
+ <source>remove: index %1 out of range</source>
+ <translation>remove: index %1 utanför intervall</translation>
+ </message>
+ <message>
+ <location line="+33"/>
+ <source>insert: value is not an object</source>
+ <translation>insert: värdet är inte ett objekt</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>insert: index %1 out of range</source>
+ <translation>insert: index %1 utanför intervall</translation>
+ </message>
+ <message>
+ <location line="+30"/>
+ <source>move: out of range</source>
+ <translation>move: utanför intervall</translation>
+ </message>
+ <message>
+ <location line="+40"/>
+ <source>append: value is not an object</source>
+ <translation>append: värdet är inte ett objekt</translation>
+ </message>
+ <message>
+ <location line="+71"/>
+ <source>set: value is not an object</source>
+ <translation>set: värdet är inte ett objekt</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <location line="+38"/>
+ <source>set: index %1 out of range</source>
+ <translation>set: index %1 utanför intervall</translation>
+ </message>
+ <message>
+ <location line="+37"/>
+ <location line="+17"/>
+ <source>ListElement: cannot contain nested elements</source>
+ <translation>ListElement: kan inte innehålla nästlade element</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>ListElement: cannot use reserved &quot;id&quot; property</source>
+ <translation>ListElement: kan inte använda reserverad egenskap &quot;id&quot;</translation>
+ </message>
+ <message>
+ <location line="+53"/>
+ <source>ListElement: cannot use script for property value</source>
+ <translation>ListElement: kan inte använda skript för egenskapsvärde</translation>
+ </message>
+ <message>
+ <location line="+31"/>
+ <source>ListModel: undefined property &apos;%1&apos;</source>
+ <translation>ListModel: odefinierad egenskap &apos;%1&apos;</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeLoader</name>
+ <message>
+ <location filename="../src/declarative/graphicsitems/qdeclarativeloader.cpp" line="+407"/>
+ <source>Loader does not support loading non-visual elements.</source>
+ <translation>Laddaren stöder inte att ladda icke-visuella element.</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeParentAnimation</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativeanimation.cpp" line="-166"/>
+ <source>Unable to preserve appearance under complex transform</source>
+ <translation>Kan inte bevara utseende med komplex transform</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <location line="+7"/>
+ <source>Unable to preserve appearance under non-uniform scale</source>
+ <translation>Kan inte bevara utseende med icke likformig skala</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Unable to preserve appearance under scale of 0</source>
+ <translation>Kan inte bevara utseende med skala 0</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeParentChange</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativestateoperations.cpp" line="+103"/>
+ <source>Unable to preserve appearance under complex transform</source>
+ <translation>Kan inte bevara utseende med komplex transform</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <location line="+7"/>
+ <source>Unable to preserve appearance under non-uniform scale</source>
+ <translation>Kan inte bevara utseende med icke likformig skala</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Unable to preserve appearance under scale of 0</source>
+ <translation>Kan inte bevara utseende med skala 0</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeParser</name>
+ <message>
+ <location filename="../src/declarative/qml/parser/qdeclarativejslexer.cpp" line="+545"/>
+ <location line="+123"/>
+ <location line="+54"/>
+ <source>Illegal unicode escape sequence</source>
+ <translation>Ogiltig Unicode escape-sekvens</translation>
+ </message>
+ <message>
+ <location line="-140"/>
+ <source>Illegal character</source>
+ <translation>Ogiltigt tecken</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Unclosed string at end of line</source>
+ <translation>Oavslutad sträng vid radslut</translation>
+ </message>
+ <message>
+ <source>Illegal escape squence</source>
+ <translation type="obsolete">Ogiltig escape-sekvens</translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>Illegal escape sequence</source>
+ <translation>Ogiltig escape-sekvens</translation>
+ </message>
+ <message>
+ <location line="+72"/>
+ <source>Unclosed comment at end of file</source>
+ <translation>Oavslutad kommentar vid filslut</translation>
+ </message>
+ <message>
+ <location line="+102"/>
+ <source>Illegal syntax for exponential number</source>
+ <translation>Ogiltig syntax för exponentialtal</translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>Identifier cannot start with numeric literal</source>
+ <translation>Identifierare kan inte inledas med numeriskt tecken</translation>
+ </message>
+ <message>
+ <location line="+338"/>
+ <source>Unterminated regular expression literal</source>
+ <translation>Oavslutad literal i reguljärt uttryck</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Invalid regular expression flag &apos;%0&apos;</source>
+ <translation>Ogiltig reguljärt uttrycksflagga &apos;%0&apos;</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <location line="+22"/>
+ <source>Unterminated regular expression backslash sequence</source>
+ <translation>Oavslutad bakstreck-sekvens i reguljärt uttryck</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Unterminated regular expression class</source>
+ <translation>Oavslutad reguljär uttrycksklass</translation>
+ </message>
+ <message>
+ <location filename="../src/declarative/qml/parser/qdeclarativejsparser.cpp" line="+1828"/>
+ <location line="+67"/>
+ <source>Syntax error</source>
+ <translation>Syntaxfel</translation>
+ </message>
+ <message>
+ <location line="-65"/>
+ <source>Unexpected token `%1&apos;</source>
+ <translation>Oväntad symbol `%1&apos;</translation>
+ </message>
+ <message>
+ <location line="+28"/>
+ <location line="+24"/>
+ <source>Expected token `%1&apos;</source>
+ <translation>Förväntad symbol `%1&apos;</translation>
+ </message>
+ <message>
+ <location filename="../src/declarative/qml/qdeclarativescriptparser.cpp" line="+254"/>
+ <location line="+429"/>
+ <location line="+59"/>
+ <source>Property value set multiple times</source>
+ <translation>Egenskapsvärde angivet flera gånger</translation>
+ </message>
+ <message>
+ <location line="-477"/>
+ <source>Expected type name</source>
+ <translation>Förväntade typnamn</translation>
+ </message>
+ <message>
+ <location line="+134"/>
+ <source>Invalid import qualifier ID</source>
+ <translation>Ogiltig identifierare för importkvalificering</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Reserved name &quot;Qt&quot; cannot be used as an qualifier</source>
+ <translation>Reserverat namn &quot;Qt&quot; kan inte användas som kvalificering</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Script import qualifiers must be unique.</source>
+ <translation>Kvalificering av skriptimport måste vara unik.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Script import requires a qualifier</source>
+ <translation>Skriptimport kräver en kvalificering</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Library import requires a version</source>
+ <translation>Biblioteksimport kräver en version</translation>
+ </message>
+ <message>
+ <location line="+59"/>
+ <source>Expected parameter type</source>
+ <translation>Förväntade parametertyp</translation>
+ </message>
+ <message>
+ <location line="+42"/>
+ <source>Invalid property type modifier</source>
+ <translation>Ogiltig modifierare av egenskapstyp</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Unexpected property type modifier</source>
+ <translation>Oväntad modifierare av egenskapstyp</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Expected property type</source>
+ <translation>Förväntade egenskapstyp</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Readonly not yet supported</source>
+ <translation>Skrivskydd stöds inte ännu</translation>
+ </message>
+ <message>
+ <location line="+218"/>
+ <source>JavaScript declaration outside Script element</source>
+ <translation>Javascript-deklaration utanför Script-element</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativePauseAnimation</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativeanimation.cpp" line="-2111"/>
+ <source>Cannot set a duration of &lt; 0</source>
+ <translation>Kan inte ställa in varaktighet mindre än 0</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativePixmap</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativepixmapcache.cpp" line="+310"/>
+ <source>Error decoding: %1: %2</source>
+ <translation>Fel vid avkodning: %1: %2</translation>
+ </message>
+ <message>
+ <location line="+151"/>
+ <location line="+343"/>
+ <source>Failed to get image from provider: %1</source>
+ <translation>Misslyckades hämta bild från leverantör: %1</translation>
+ </message>
+ <message>
+ <location line="-324"/>
+ <location line="+342"/>
+ <source>Cannot open: %1</source>
+ <translation>Kan inte öppna: %1</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativePropertyAnimation</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativeanimation.cpp" line="+1234"/>
+ <source>Cannot set a duration of &lt; 0</source>
+ <translation>Kan inte ställa in varaktighet mindre än 0</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativePropertyChanges</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativepropertychanges.cpp" line="+254"/>
+ <source>PropertyChanges does not support creating state-specific objects.</source>
+ <translation>PropertyChanges stöder inte att skapa tillståndsspecifika objekt.</translation>
+ </message>
+ <message>
+ <location line="+168"/>
+ <source>Cannot assign to non-existent property &quot;%1&quot;</source>
+ <translation>Kan inte tilldela till egenskapen &quot;%1&quot; som inte finns</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Cannot assign to read-only property &quot;%1&quot;</source>
+ <translation>Kan inte tilldela till skrivskyddad egenskap &quot;%1&quot;</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeTextInput</name>
+ <message>
+ <location filename="../src/declarative/graphicsitems/qdeclarativetextinput.cpp" line="+949"/>
+ <location line="+8"/>
+ <source>Could not load cursor delegate</source>
+ <translation>Kunde inte ladda markörrepresentant</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Could not instantiate cursor delegate</source>
+ <translation>Kunde inte initiera markörrepresentant</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeTypeLoader</name>
+ <message>
+ <location filename="../src/declarative/qml/qdeclarativetypeloader.cpp" line="+799"/>
+ <source>Script %1 unavailable</source>
+ <translation>Skriptet %1 är inte tillgängligt</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Type %1 unavailable</source>
+ <translation>Typen %1 inte tillgänglig</translation>
+ </message>
+ <message>
+ <location line="+176"/>
+ <source>Namespace %1 cannot be used as a type</source>
+ <translation>Namnrymd %1 kan inte användas som en typ</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>%1 %2</source>
+ <translation>%1 %2</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeVME</name>
+ <message>
+ <location filename="../src/declarative/qml/qdeclarativevme.cpp" line="+192"/>
+ <source>Unable to create object of type %1</source>
+ <translation>Kan inte skapa objekt av typen %1</translation>
+ </message>
+ <message>
+ <location line="+396"/>
+ <source>Cannot assign value %1 to property %2</source>
+ <translation>Kan inte tilldela värdet %1 till egenskapen %2</translation>
+ </message>
+ <message>
+ <location line="+22"/>
+ <source>Cannot assign object type %1 with no default method</source>
+ <translation>Kan inte tilldela objekttyp %1 utan fördefinierad metod</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Cannot connect mismatched signal/slot %1 %vs. %2</source>
+ <translation>Kan inte ansluta signal %1 och slot %2 som inte matchar</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Cannot assign an object to signal property %1</source>
+ <translation>Kan inte tilldela ett objekt till signalegenskap %1</translation>
+ </message>
+ <message>
+ <location line="+154"/>
+ <source>Cannot assign object to list</source>
+ <translation>Kan inte tilldela objekt till lista</translation>
+ </message>
+ <message>
+ <location line="+41"/>
+ <source>Cannot assign object to interface property</source>
+ <translation>Kan inte tilldela objekt till egenskap i interface</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Unable to create attached object</source>
+ <translation>Kan inte skapa anslutet objekt</translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Cannot set properties on %1 as it is null</source>
+ <translation>Kan inte ställa in egenskaper för %1 eftersom den är null</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeVisualDataModel</name>
+ <message>
+ <location filename="../src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp" line="+1098"/>
+ <source>Delegate component must be Item type.</source>
+ <translation>Representantkomponent måste vara objekttyp.</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeXmlListModel</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativeutilmodule.cpp" line="+32"/>
+ <location line="+2"/>
+ <location line="+47"/>
+ <location line="+2"/>
+ <source>Qt was built without support for xmlpatterns</source>
+ <translation>Qt byggdes utan stöd för xmlpatterns</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeXmlListModelRole</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativexmllistmodel_p.h" line="+174"/>
+ <source>An XmlRole query must not start with &apos;/&apos;</source>
+ <translation>En förfrågan till en XmlRole får inte börja med &apos;/&apos;</translation>
+ </message>
+</context>
+<context>
+ <name>QDeclarativeXmlRoleList</name>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativexmllistmodel.cpp" line="+727"/>
+ <source>An XmlListModel query must start with &apos;/&apos; or &quot;//&quot;</source>
+ <translation>En förfrågan till en XmlListModel måste börja med &apos;/&apos; eller &quot;//&quot;</translation>
+ </message>
+</context>
+<context>
<name>QDial</name>
<message>
+ <location filename="../src/plugins/accessible/widgets/rangecontrols.cpp" line="+951"/>
<source>QDial</source>
<translation>QDial</translation>
</message>
<message>
+ <location line="+2"/>
<source>SpeedoMeter</source>
<translation>Hastighetsmätare</translation>
</message>
<message>
+ <location line="+2"/>
<source>SliderHandle</source>
<translation>Draglisthandtag</translation>
</message>
@@ -935,10 +2888,12 @@ till
<context>
<name>QDialog</name>
<message>
+ <location filename="../src/gui/dialogs/qdialog.cpp" line="+651"/>
<source>What&apos;s This?</source>
<translation>Vad är det här?</translation>
</message>
<message>
+ <location line="-127"/>
<source>Done</source>
<translation>Färdig</translation>
</message>
@@ -946,86 +2901,124 @@ till
<context>
<name>QDialogButtonBox</name>
<message>
+ <location filename="../src/gui/dialogs/qmessagebox.cpp" line="+1910"/>
+ <location line="+446"/>
+ <location filename="../src/gui/widgets/qdialogbuttonbox.cpp" line="+649"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
+ <location filename="../src/gui/widgets/qdialogbuttonbox.cpp" line="+3"/>
<source>Save</source>
<translation>Spara</translation>
</message>
<message>
+ <location line="+0"/>
+ <source>&amp;Save</source>
+ <translation>&amp;Spara</translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Open</source>
<translation>Öppna</translation>
</message>
<message>
+ <location line="+3"/>
<source>Cancel</source>
<translation>Avbryt</translation>
</message>
<message>
+ <location line="+0"/>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Avbryt</translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Close</source>
<translation>Stäng</translation>
</message>
<message>
+ <location line="+0"/>
+ <source>&amp;Close</source>
+ <translation>Stän&amp;g</translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Apply</source>
<translation>Verkställ</translation>
</message>
<message>
+ <location line="+3"/>
<source>Reset</source>
<translation>Återställ</translation>
</message>
<message>
+ <location line="+3"/>
<source>Help</source>
<translation>Hjälp</translation>
</message>
<message>
+ <location line="+4"/>
<source>Don&apos;t Save</source>
<translation>Spara inte</translation>
</message>
<message>
+ <location line="+4"/>
<source>Discard</source>
<translation>Förkasta</translation>
</message>
<message>
+ <location line="+3"/>
<source>&amp;Yes</source>
<translation>&amp;Ja</translation>
</message>
<message>
+ <location line="+3"/>
<source>Yes to &amp;All</source>
<translation>Ja till &amp;alla</translation>
</message>
<message>
+ <location line="+3"/>
<source>&amp;No</source>
<translation>&amp;Nej</translation>
</message>
<message>
+ <location line="+3"/>
<source>N&amp;o to All</source>
<translation>N&amp;ej till alla</translation>
</message>
<message>
+ <location line="+3"/>
<source>Save All</source>
<translation>Spara alla</translation>
</message>
<message>
+ <location line="+3"/>
<source>Abort</source>
<translation>Avbryt</translation>
</message>
<message>
+ <location line="+3"/>
<source>Retry</source>
<translation>Försök igen</translation>
</message>
<message>
+ <location line="+3"/>
<source>Ignore</source>
<translation>Ignorera</translation>
</message>
<message>
+ <location line="+3"/>
<source>Restore Defaults</source>
<translation>Återställ standardvärden</translation>
</message>
<message>
+ <location line="-29"/>
<source>Close without Saving</source>
<translation>Stäng utan att spara</translation>
</message>
<message>
+ <location line="-27"/>
<source>&amp;OK</source>
<translation>&amp;OK</translation>
</message>
@@ -1033,24 +3026,29 @@ till
<context>
<name>QDirModel</name>
<message>
+ <location filename="../src/gui/itemviews/qdirmodel.cpp" line="+438"/>
<source>Name</source>
<translation>Namn</translation>
</message>
<message>
+ <location line="+1"/>
<source>Size</source>
<translation>Storlek</translation>
</message>
<message>
+ <location line="+3"/>
<source>Kind</source>
<comment>Match OS X Finder</comment>
<translation>Sort</translation>
</message>
<message>
+ <location line="+2"/>
<source>Type</source>
<comment>All other platforms</comment>
<translation>Typ</translation>
</message>
<message>
+ <location line="+6"/>
<source>Date Modified</source>
<translation>Ändringsdatum</translation>
</message>
@@ -1058,25 +3056,30 @@ till
<context>
<name>QDockWidget</name>
<message>
+ <location filename="../src/plugins/accessible/widgets/qaccessiblewidgets.cpp" line="+1239"/>
<source>Close</source>
<translation>Stäng</translation>
</message>
<message>
+ <location line="+2"/>
<source>Dock</source>
<translation>Docka</translation>
</message>
<message>
+ <location line="+1"/>
<source>Float</source>
- <translation>Flyta</translation>
+ <translation>Flyt</translation>
</message>
</context>
<context>
<name>QDoubleSpinBox</name>
<message>
+ <location filename="../src/plugins/accessible/widgets/rangecontrols.cpp" line="-537"/>
<source>More</source>
<translation>Mer</translation>
</message>
<message>
+ <location line="+2"/>
<source>Less</source>
<translation>Mindre</translation>
</message>
@@ -1084,55 +3087,110 @@ till
<context>
<name>QErrorMessage</name>
<message>
+ <location filename="../src/gui/dialogs/qerrormessage.cpp" line="+208"/>
<source>Debug Message:</source>
<translation>Felsökningsmeddelande:</translation>
</message>
<message>
+ <location line="+3"/>
<source>Warning:</source>
<translation>Varning:</translation>
</message>
<message>
+ <location line="+3"/>
<source>Fatal Error:</source>
<translation>Ödesdigert fel:</translation>
</message>
<message>
+ <location line="+200"/>
<source>&amp;Show this message again</source>
<translation>&amp;Visa detta meddelande igen</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;OK</source>
<translation>&amp;OK</translation>
</message>
</context>
<context>
+ <name>QFile</name>
+ <message>
+ <location filename="../src/corelib/io/qfile.cpp" line="+703"/>
+ <location line="+155"/>
+ <source>Destination file exists</source>
+ <translation>MÃ¥lfilen finns</translation>
+ </message>
+ <message>
+ <location line="-140"/>
+ <source>Will not rename sequential file using block copy</source>
+ <translation>Kommer inte att byta namn på sekvensiell fil med användning av blockkopiering</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Cannot remove source file</source>
+ <translation>Kan inte ta bort källfil</translation>
+ </message>
+ <message>
+ <location line="+130"/>
+ <source>Cannot open %1 for input</source>
+ <translation>Kan inte öppna %1 för inmatning</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Cannot open for output</source>
+ <translation>Kan inte öppna för utmatning</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Failure to write block</source>
+ <translation>Misslyckades skriva block</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Cannot create %1 for output</source>
+ <translation>Kan inte skapa %1 för utmatning</translation>
+ </message>
+</context>
+<context>
<name>QFileDialog</name>
<message>
+ <location filename="../src/gui/dialogs/qfiledialog.cpp" line="+557"/>
+ <location line="+481"/>
<source>All Files (*)</source>
<translation>Alla filer (*)</translation>
</message>
<message>
+ <location line="+216"/>
<source>Directories</source>
<translation>Kataloger</translation>
</message>
<message>
+ <location line="-3"/>
+ <location line="+55"/>
+ <location line="+1582"/>
<source>&amp;Open</source>
<translation>&amp;Öppna</translation>
</message>
<message>
+ <location line="-1637"/>
+ <location line="+55"/>
<source>&amp;Save</source>
<translation>&amp;Spara</translation>
</message>
<message>
+ <location line="-766"/>
<source>Open</source>
<translation>Öppna</translation>
</message>
<message>
+ <location line="+1587"/>
<source>%1 already exists.
Do you want to replace it?</source>
<translation>%1 finns redan.
Vill du ersätta den?</translation>
</message>
<message>
+ <location line="+20"/>
<source>%1
File not found.
Please verify the correct file name was given.</source>
@@ -1141,46 +3199,64 @@ Filen hittades inte.
Kontrollera att det korrekta filnamnet angavs.</translation>
</message>
<message>
+ <location filename="../src/gui/itemviews/qdirmodel.cpp" line="+402"/>
<source>My Computer</source>
<translation>Min dator</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qfiledialog.cpp" line="-1576"/>
<source>&amp;Rename</source>
<translation>&amp;Byt namn</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Delete</source>
<translation>&amp;Ta bort</translation>
</message>
<message>
+ <location line="+1"/>
<source>Show &amp;hidden files</source>
<translation>Visa &amp;dolda filer</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qfiledialog.ui"/>
+ <location filename="../src/gui/dialogs/qfiledialog_embedded.ui"/>
<source>Back</source>
<translation>Tillbaka</translation>
</message>
<message>
+ <location/>
+ <location filename="../src/gui/dialogs/qfiledialog_embedded.ui"/>
<source>Parent Directory</source>
<translation>Föräldrakatalog</translation>
</message>
<message>
+ <location/>
+ <location filename="../src/gui/dialogs/qfiledialog_embedded.ui"/>
<source>List View</source>
<translation>Listvy</translation>
</message>
<message>
+ <location/>
+ <location filename="../src/gui/dialogs/qfiledialog_embedded.ui"/>
<source>Detail View</source>
<translation>Detaljerad vy</translation>
</message>
<message>
+ <location/>
+ <location filename="../src/gui/dialogs/qfiledialog_embedded.ui"/>
<source>Files of type:</source>
<translation>Filer av typen:</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qfiledialog.cpp" line="+6"/>
+ <location line="+679"/>
<source>Directory:</source>
<translation>Katalog:</translation>
</message>
<message>
+ <location line="+835"/>
+ <location line="+862"/>
<source>%1
Directory not found.
Please verify the correct directory name was given.</source>
@@ -1189,339 +3265,514 @@ Katalogen hittades inte.
Kontrollera att det korrekta katalognamnet angavs.</translation>
</message>
<message>
+ <location line="-218"/>
<source>&apos;%1&apos; is write protected.
Do you want to delete it anyway?</source>
<translation>\&quot;%1\&quot; är skrivskyddad.
Vill du ta bort den ändå?</translation>
</message>
<message>
+ <location line="+5"/>
<source>Are sure you want to delete &apos;%1&apos;?</source>
<translation>Är du säker på att du vill ta bort \&quot;%1\&quot;?</translation>
</message>
<message>
+ <location line="+15"/>
<source>Could not delete directory.</source>
<translation>Kunde inte ta bort katalogen.</translation>
</message>
<message>
+ <location line="+404"/>
+ <source>Recent Places</source>
+ <translation>Senaste platser</translation>
+ </message>
+ <message>
+ <location filename="../src/gui/dialogs/qfiledialog_win.cpp" line="+148"/>
+ <source>All Files (*.*)</source>
+ <translation>Alla filer (*.*)</translation>
+ </message>
+ <message>
+ <location filename="../src/gui/dialogs/qfiledialog.cpp" line="-2619"/>
<source>Save As</source>
<translation>Spara som</translation>
</message>
<message>
+ <location filename="../src/gui/itemviews/qfileiconprovider.cpp" line="+475"/>
<source>Drive</source>
<translation>Enhet</translation>
</message>
<message>
+ <location line="+3"/>
+ <location line="+1"/>
<source>File</source>
<translation>Fil</translation>
</message>
<message>
+ <location line="+5"/>
+ <source>File Folder</source>
+ <comment>Match Windows Explorer</comment>
+ <translation>Filmapp</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Folder</source>
+ <comment>All other platforms</comment>
+ <translation>Mapp</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Alias</source>
+ <comment>Mac OS X Finder</comment>
+ <translation>Alias</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Shortcut</source>
+ <comment>All other platforms</comment>
+ <translation>Genväg</translation>
+ </message>
+ <message>
+ <location line="+7"/>
<source>Unknown</source>
<translation>Okänt</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qfiledialog.cpp" line="-4"/>
+ <location filename="../src/gui/dialogs/qfiledialog_symbian.cpp" line="+192"/>
<source>Find Directory</source>
<translation>Hitta katalog</translation>
</message>
<message>
+ <location line="+29"/>
<source>Show </source>
- <translation>Visa</translation>
+ <translation>Visa </translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qfiledialog.ui"/>
+ <location filename="../src/gui/dialogs/qfiledialog_embedded.ui"/>
<source>Forward</source>
<translation>Framåt</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qfiledialog.cpp" line="+2042"/>
<source>New Folder</source>
<translation>Ny mapp</translation>
</message>
<message>
+ <location line="-2035"/>
<source>&amp;New Folder</source>
<translation>&amp;Ny mapp</translation>
</message>
<message>
+ <location line="+687"/>
+ <location line="+43"/>
<source>&amp;Choose</source>
<translation>&amp;Välj</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qsidebar.cpp" line="+442"/>
<source>Remove</source>
<translation>Ta bort</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qfiledialog.cpp" line="-723"/>
+ <location line="+683"/>
<source>File &amp;name:</source>
<translation>Fil&amp;namn:</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qfiledialog.ui"/>
+ <location filename="../src/gui/dialogs/qfiledialog_embedded.ui"/>
<source>Look in:</source>
<translation>Leta i:</translation>
</message>
<message>
+ <location/>
+ <location filename="../src/gui/dialogs/qfiledialog_embedded.ui"/>
<source>Create New Folder</source>
<translation>Skapa ny mapp</translation>
</message>
+ <message>
+ <location/>
+ <source>Go back</source>
+ <translation>Tillbaka</translation>
+ </message>
+ <message>
+ <location/>
+ <source>Go forward</source>
+ <translation>Framåt</translation>
+ </message>
+ <message>
+ <location/>
+ <source>Go to the parent directory</source>
+ <translation>Gå till överliggande mapp</translation>
+ </message>
+ <message>
+ <location/>
+ <source>Create a New Folder</source>
+ <translation>Skapa en ny mapp</translation>
+ </message>
+ <message>
+ <location/>
+ <source>Change to list view mode</source>
+ <translation>Byt till listvy</translation>
+ </message>
+ <message>
+ <location/>
+ <source>Change to detail view mode</source>
+ <translation>Byt till detaljerad vy</translation>
+ </message>
</context>
<context>
<name>QFileSystemModel</name>
<message>
+ <location filename="../src/gui/dialogs/qfilesystemmodel.cpp" line="+763"/>
+ <location filename="../src/gui/itemviews/qdirmodel.cpp" line="+482"/>
<source>%1 TB</source>
<translation>%1 TB</translation>
</message>
<message>
+ <location line="+2"/>
+ <location filename="../src/gui/itemviews/qdirmodel.cpp" line="+2"/>
<source>%1 GB</source>
<translation>%1 GB</translation>
</message>
<message>
+ <location line="+2"/>
+ <location filename="../src/gui/itemviews/qdirmodel.cpp" line="+2"/>
<source>%1 MB</source>
<translation>%1 MB</translation>
</message>
<message>
+ <location line="+2"/>
+ <location filename="../src/gui/itemviews/qdirmodel.cpp" line="+2"/>
<source>%1 KB</source>
<translation>%1 KB</translation>
</message>
<message>
+ <location line="+1"/>
<source>%1 bytes</source>
<translation>%1 byte</translation>
</message>
<message>
+ <location line="+89"/>
<source>Invalid filename</source>
<translation>Ogiltigt filnamn</translation>
</message>
<message>
+ <location line="+1"/>
<source>&lt;b&gt;The name &quot;%1&quot; can not be used.&lt;/b&gt;&lt;p&gt;Try using another name, with fewer characters or no punctuations marks.</source>
- <translation>&lt;b&gt;Namnet \&quot;%1&quot; kan inte användas.&lt;/b&gt;&lt;p&gt;Prova med ett annat namn med mindre antal tecken eller inga skiljetecken.</translation>
+ <translation>&lt;b&gt;Namnet &quot;%1&quot; kan inte användas.&lt;/b&gt;&lt;p&gt;Försök med ett annat namn, mindre antal tecken eller utan skiljetecken.</translation>
</message>
<message>
+ <location line="+64"/>
<source>Name</source>
<translation>Namn</translation>
</message>
<message>
+ <location line="+2"/>
<source>Size</source>
<translation>Storlek</translation>
</message>
<message>
+ <location line="+4"/>
<source>Kind</source>
<comment>Match OS X Finder</comment>
<translation>Sort</translation>
</message>
<message>
+ <location line="+2"/>
<source>Type</source>
<comment>All other platforms</comment>
<translation>Typ</translation>
</message>
<message>
+ <location line="+7"/>
<source>Date Modified</source>
<translation>Ändringsdatum</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qfilesystemmodel_p.h" line="+261"/>
<source>My Computer</source>
<translation>Min dator</translation>
</message>
<message>
+ <location line="+2"/>
<source>Computer</source>
<translation>Dator</translation>
</message>
+ <message>
+ <location filename="../src/gui/itemviews/qdirmodel.cpp" line="+1"/>
+ <source>%1 byte(s)</source>
+ <translation>%1 byte</translation>
+ </message>
</context>
<context>
<name>QFontDatabase</name>
<message>
+ <location filename="../src/gui/text/qfontdatabase.cpp" line="+102"/>
+ <location line="+1349"/>
<source>Normal</source>
<translation>Normal</translation>
</message>
<message>
+ <location line="-1346"/>
+ <location line="+12"/>
+ <location line="+1322"/>
<source>Bold</source>
<translation>Fet</translation>
</message>
<message>
+ <location line="-1331"/>
+ <location line="+1333"/>
<source>Demi Bold</source>
<translation>Halvfet</translation>
</message>
<message>
+ <location line="-1330"/>
+ <location line="+18"/>
+ <location line="+1308"/>
<source>Black</source>
<translation>Svart</translation>
</message>
<message>
+ <location line="-1318"/>
<source>Demi</source>
<translation>Halv</translation>
</message>
<message>
+ <location line="+6"/>
+ <location line="+1318"/>
<source>Light</source>
<translation>Ljus</translation>
</message>
<message>
+ <location line="-1172"/>
+ <location line="+1175"/>
<source>Italic</source>
<translation>Kursiv</translation>
</message>
<message>
+ <location line="-1172"/>
+ <location line="+1174"/>
<source>Oblique</source>
<translation>Oblik</translation>
</message>
<message>
+ <location line="+704"/>
<source>Any</source>
- <translation>Valfri</translation>
+ <translation>Alla</translation>
</message>
<message>
+ <location line="+3"/>
<source>Latin</source>
<translation>Latinska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Greek</source>
<translation>Grekiska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Cyrillic</source>
<translation>Kyrilliska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Armenian</source>
<translation>Armeniska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Hebrew</source>
<translation>Hebreiska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Arabic</source>
<translation>Arabiska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Syriac</source>
- <translation>Syriska</translation>
+ <translation>Syrianska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Thaana</source>
<translation>Thaana</translation>
</message>
<message>
+ <location line="+3"/>
<source>Devanagari</source>
<translation>Devanagari</translation>
</message>
<message>
+ <location line="+3"/>
<source>Bengali</source>
- <translation>Bengali</translation>
+ <translation>Bengaliska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Gurmukhi</source>
<translation>Gurmukhi</translation>
</message>
<message>
+ <location line="+3"/>
<source>Gujarati</source>
<translation>Gujarati</translation>
</message>
<message>
+ <location line="+3"/>
<source>Oriya</source>
<translation>Oriya</translation>
</message>
<message>
+ <location line="+3"/>
<source>Tamil</source>
- <translation>Tamil</translation>
+ <translation>Tamilska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Telugu</source>
<translation>Telugu</translation>
</message>
<message>
+ <location line="+3"/>
<source>Kannada</source>
<translation>Kannada</translation>
</message>
<message>
+ <location line="+3"/>
<source>Malayalam</source>
<translation>Malayalam</translation>
</message>
<message>
+ <location line="+3"/>
<source>Sinhala</source>
<translation>Sinhala</translation>
</message>
<message>
+ <location line="+3"/>
<source>Thai</source>
- <translation>Thai</translation>
+ <translation>Thailändska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Lao</source>
- <translation>Lao</translation>
+ <translation>Laotiska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Tibetan</source>
<translation>Tibetanska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Myanmar</source>
<translation>Myanmar</translation>
</message>
<message>
+ <location line="+3"/>
<source>Georgian</source>
<translation>Georgiska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Khmer</source>
- <translation>Khmer</translation>
+ <translation>Khmeriska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Simplified Chinese</source>
- <translation>Förenklad kinesiska</translation>
+ <translation>Kinesiska (förenklad)</translation>
</message>
<message>
+ <location line="+3"/>
<source>Traditional Chinese</source>
- <translation>Traditionell kinesiska</translation>
+ <translation>Kinesiska (traditionell)</translation>
</message>
<message>
+ <location line="+3"/>
<source>Japanese</source>
<translation>Japanska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Korean</source>
<translation>Koreanska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Vietnamese</source>
<translation>Vietnamesiska</translation>
</message>
<message>
+ <location line="+3"/>
<source>Symbol</source>
<translation>Symbol</translation>
</message>
<message>
+ <location line="+3"/>
<source>Ogham</source>
<translation>Ogham</translation>
</message>
<message>
+ <location line="+3"/>
<source>Runic</source>
<translation>Runskrift</translation>
</message>
+ <message>
+ <location line="+3"/>
+ <source>N&apos;Ko</source>
+ <translation>N&apos;Ko</translation>
+ </message>
</context>
<context>
<name>QFontDialog</name>
<message>
+ <location filename="../src/gui/dialogs/qfontdialog.cpp" line="+768"/>
<source>&amp;Font</source>
<translation>&amp;Typsnitt</translation>
</message>
<message>
+ <location line="+1"/>
<source>Font st&amp;yle</source>
<translation>T&amp;ypsnittsstil</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Size</source>
<translation>&amp;Storlek</translation>
</message>
<message>
+ <location line="+4"/>
<source>Effects</source>
<translation>Effekter</translation>
</message>
<message>
+ <location line="+2"/>
<source>Stri&amp;keout</source>
<translation>Genomstru&amp;ken</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Underline</source>
<translation>&amp;Understruken</translation>
</message>
<message>
+ <location line="+1"/>
<source>Sample</source>
<translation>Test</translation>
</message>
<message>
+ <location line="+1"/>
<source>Wr&amp;iting System</source>
<translation>Skr&amp;ivsystem</translation>
</message>
<message>
+ <location line="-596"/>
<source>Select Font</source>
<translation>Välj typsnitt</translation>
</message>
@@ -1529,100 +3780,145 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QFtp</name>
<message>
+ <location filename="../src/network/access/qftp.cpp" line="+828"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+683"/>
<source>Not connected</source>
<translation>Inte ansluten</translation>
</message>
<message>
+ <location line="+68"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+65"/>
<source>Host %1 not found</source>
<translation>Värden %1 hittades inte</translation>
</message>
<message>
+ <location line="+4"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+4"/>
<source>Connection refused to host %1</source>
<translation>Anslutningen till värden %1 vägrades</translation>
</message>
<message>
+ <location line="+4"/>
+ <source>Connection timed out to host %1</source>
+ <translation>Tidsgräns gick ut vid anslutning till värden %1</translation>
+ </message>
+ <message>
+ <location line="+104"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+102"/>
+ <location line="+1451"/>
<source>Connected to host %1</source>
<translation>Ansluten till värden %1</translation>
</message>
<message>
+ <location line="+219"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="-1290"/>
<source>Connection refused for data connection</source>
<translation>Anslutning vägrades för dataanslutning</translation>
</message>
<message>
+ <location line="+178"/>
+ <location line="+29"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+195"/>
+ <location line="+728"/>
<source>Unknown error</source>
<translation>Okänt fel</translation>
</message>
<message>
+ <location line="+897"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+77"/>
<source>Connecting to host failed:
%1</source>
<translation>Anslutning till värden misslyckades:
%1</translation>
</message>
<message>
+ <location line="+4"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+3"/>
<source>Login failed:
%1</source>
<translation>Inloggning misslyckades:
%1</translation>
</message>
<message>
+ <location line="+4"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+3"/>
<source>Listing directory failed:
%1</source>
<translation>Listning av katalogen misslyckades:
%1</translation>
</message>
<message>
+ <location line="+4"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+3"/>
<source>Changing directory failed:
%1</source>
<translation>Byte av katalog misslyckades:
%1</translation>
</message>
<message>
+ <location line="+4"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+3"/>
<source>Downloading file failed:
%1</source>
<translation>Nedladdningen av filen misslyckades:
%1</translation>
</message>
<message>
+ <location line="+4"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+3"/>
<source>Uploading file failed:
%1</source>
<translation>Uppladdningen av filen misslyckades:
%1</translation>
</message>
<message>
+ <location line="+4"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+3"/>
<source>Removing file failed:
%1</source>
<translation>Borttagning av filen misslyckades:
%1</translation>
</message>
<message>
+ <location line="+4"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+3"/>
<source>Creating directory failed:
%1</source>
<translation>Skapandet av katalogen misslyckades:
%1</translation>
</message>
<message>
+ <location line="+4"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+3"/>
<source>Removing directory failed:
%1</source>
<translation>Borttagning av katalogen misslyckades:
%1</translation>
</message>
<message>
+ <location line="+28"/>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="+25"/>
+ <location line="+250"/>
<source>Connection closed</source>
<translation>Anslutningen stängd</translation>
</message>
<message>
+ <location filename="../src/qt3support/network/q3ftp.cpp" line="-11"/>
<source>Host %1 found</source>
<translation>Värden %1 hittades</translation>
</message>
<message>
+ <location line="+4"/>
<source>Connection to %1 closed</source>
<translation>Anslutningen till %1 stängdes</translation>
</message>
<message>
+ <location line="+3"/>
<source>Host found</source>
<translation>Värden hittades</translation>
</message>
<message>
+ <location line="+2"/>
<source>Connected to host</source>
<translation>Ansluten till värden</translation>
</message>
@@ -1630,21 +3926,50 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QHostInfo</name>
<message>
+ <location filename="../src/network/kernel/qhostinfo_p.h" line="+103"/>
<source>Unknown error</source>
<translation>Okänt fel</translation>
</message>
+ <message>
+ <location filename="../src/network/kernel/qhostinfo.cpp" line="+171"/>
+ <source>No host name given</source>
+ <translation>Inget värdnamn angivet</translation>
+ </message>
</context>
<context>
<name>QHostInfoAgent</name>
<message>
+ <location filename="../src/network/kernel/qhostinfo_unix.cpp" line="+277"/>
+ <location line="+32"/>
+ <location filename="../src/network/kernel/qhostinfo_win.cpp" line="+215"/>
+ <location line="+27"/>
<source>Host not found</source>
<translation>Värden hittades inte</translation>
</message>
<message>
+ <location line="-45"/>
+ <location line="+39"/>
+ <location filename="../src/network/kernel/qhostinfo_win.cpp" line="-34"/>
+ <location line="+29"/>
<source>Unknown address type</source>
<translation>Okänd adresstyp</translation>
</message>
<message>
+ <location line="-105"/>
+ <location filename="../src/network/kernel/qhostinfo_win.cpp" line="-59"/>
+ <source>No host name given</source>
+ <translation>Inget värdnamn angivet</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <location filename="../src/network/kernel/qhostinfo_win.cpp" line="+0"/>
+ <source>Invalid hostname</source>
+ <translation>Ogiltigt värdnamn</translation>
+ </message>
+ <message>
+ <location line="+114"/>
+ <location filename="../src/network/kernel/qhostinfo_win.cpp" line="+40"/>
+ <location line="+27"/>
<source>Unknown error</source>
<translation>Okänt fel</translation>
</message>
@@ -1652,102 +3977,153 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QHttp</name>
<message>
+ <location filename="../src/network/access/qhttp.cpp" line="+370"/>
+ <source>HTTPS connection requested but SSL support not compiled in</source>
+ <translation>HTTPS-anslutning begärd men SSL-stöd inte inkompilerat</translation>
+ </message>
+ <message>
+ <location line="+1212"/>
+ <location line="+820"/>
+ <location filename="../src/qt3support/network/q3http.cpp" line="+1159"/>
+ <location line="+567"/>
<source>Unknown error</source>
<translation>Okänt fel</translation>
</message>
<message>
+ <location line="-568"/>
+ <location filename="../src/qt3support/network/q3http.cpp" line="-370"/>
<source>Request aborted</source>
<translation>Begäran avbröts</translation>
</message>
<message>
+ <location line="+579"/>
+ <location filename="../src/qt3support/network/q3http.cpp" line="+381"/>
<source>No server set to connect to</source>
<translation>Ingen server inställd att ansluta till</translation>
</message>
<message>
+ <location line="+164"/>
+ <location filename="../src/qt3support/network/q3http.cpp" line="+56"/>
<source>Wrong content length</source>
<translation>Fel innehållslängd</translation>
</message>
<message>
+ <location line="+4"/>
+ <location filename="../src/qt3support/network/q3http.cpp" line="+4"/>
<source>Server closed connection unexpectedly</source>
<translation>Servern stängde oväntat anslutningen</translation>
</message>
<message>
+ <location line="+383"/>
+ <source>Error writing response to device</source>
+ <translation>Fel vid skrivning av svar till enhet</translation>
+ </message>
+ <message>
+ <location filename="../src/network/access/qhttpnetworkconnection.cpp" line="-6"/>
+ <location filename="../src/qt3support/network/q3http.cpp" line="+38"/>
<source>Connection refused</source>
<translation>Anslutningen nekades</translation>
</message>
<message>
+ <location filename="../src/network/access/qhttp.cpp" line="-325"/>
+ <location filename="../src/network/access/qhttpnetworkconnection.cpp" line="-4"/>
+ <location filename="../src/qt3support/network/q3http.cpp" line="+3"/>
<source>Host %1 not found</source>
<translation>Värden %1 hittades inte</translation>
</message>
<message>
+ <location line="+20"/>
+ <location filename="../src/qt3support/network/q3http.cpp" line="+3"/>
<source>HTTP request failed</source>
<translation>HTTP-begäran misslyckades</translation>
</message>
<message>
+ <location line="+94"/>
+ <location filename="../src/qt3support/network/q3http.cpp" line="+69"/>
<source>Invalid HTTP response header</source>
<translation>Ogiltig HTTP-svarshuvud</translation>
</message>
<message>
+ <location line="+28"/>
+ <source>Unknown authentication method</source>
+ <translation>Värden kräver autentisering</translation>
+ </message>
+ <message>
+ <location line="+97"/>
+ <location line="+48"/>
+ <location filename="../src/qt3support/network/q3http.cpp" line="+40"/>
+ <location line="+47"/>
<source>Invalid HTTP chunked body</source>
<translation>Ogiltig HTTP chunked body</translation>
</message>
<message>
+ <location filename="../src/qt3support/network/q3http.cpp" line="+294"/>
<source>Host %1 found</source>
<translation>Värden %1 hittades</translation>
</message>
<message>
+ <location line="+3"/>
<source>Connected to host %1</source>
<translation>Ansluten till värden %1</translation>
</message>
<message>
+ <location line="+3"/>
<source>Connection to %1 closed</source>
<translation>Anslutningen till %1 stängdes</translation>
</message>
<message>
+ <location line="+8"/>
<source>Host found</source>
<translation>Värden hittades</translation>
</message>
<message>
+ <location line="+3"/>
<source>Connected to host</source>
<translation>Ansluten till värd</translation>
</message>
<message>
+ <location filename="../src/network/access/qhttpnetworkconnection.cpp" line="+7"/>
+ <location filename="../src/qt3support/network/q3http.cpp" line="+3"/>
<source>Connection closed</source>
<translation>Anslutningen stängd</translation>
</message>
<message>
+ <location filename="../src/network/access/qhttp.cpp" line="-135"/>
<source>Proxy authentication required</source>
<translation>Proxyautentisering krävs</translation>
</message>
<message>
+ <location line="+4"/>
<source>Authentication required</source>
<translation>Autentisering krävs</translation>
</message>
<message>
- <source>HTTPS connection requested but SSL support not compiled in</source>
- <translation>HTTPS-anslutning begärdes men SSL-stöd är inte inkompilerat</translation>
- </message>
- <message>
+ <location line="-159"/>
<source>Connection refused (or timed out)</source>
- <translation>Anslutningen nekades (eller översteg tidsgränsen)</translation>
+ <translation>Anslutningen nekades (eller översteg tidsgräns)</translation>
</message>
<message>
+ <location filename="../src/network/access/qhttpnetworkconnection.cpp" line="+6"/>
<source>Proxy requires authentication</source>
- <translation>Proxyservern kräver autentisering</translation>
+ <translation>Proxy kräver autentisering</translation>
</message>
<message>
+ <location line="+3"/>
<source>Host requires authentication</source>
<translation>Värden kräver autentisering</translation>
</message>
<message>
+ <location line="+3"/>
<source>Data corrupted</source>
- <translation type="unfinished"></translation>
+ <translation>Data skadat</translation>
</message>
<message>
+ <location line="+3"/>
<source>Unknown protocol specified</source>
<translation>Okänt protokoll angivet</translation>
</message>
<message>
+ <location line="+3"/>
<source>SSL handshake failed</source>
<translation>SSL-handskakning misslyckades</translation>
</message>
@@ -1755,25 +4131,70 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QHttpSocketEngine</name>
<message>
+ <location filename="../src/network/socket/qhttpsocketengine.cpp" line="-89"/>
+ <source>Did not receive HTTP response from proxy</source>
+ <translation>Tog inte emot HTTP-svar från proxy</translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>Error parsing authentication request from proxy</source>
+ <translation>Fel vid tolkning av behörighetsbegäran från proxy</translation>
+ </message>
+ <message>
+ <location line="+31"/>
<source>Authentication required</source>
<translation>Autentisering krävs</translation>
</message>
+ <message>
+ <location line="+27"/>
+ <source>Proxy denied connection</source>
+ <translation>Anslutning till proxy vägrades</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Error communicating with HTTP proxy</source>
+ <translation>Fel vid kommunikation med HTTP-proxy</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Proxy server not found</source>
+ <translation>Proxy-server hittades inte</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Proxy connection refused</source>
+ <translation>Anslutning till proxy vägrades</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Proxy server connection timed out</source>
+ <translation>Anslutningen till proxy överskred tidsgräns</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Proxy connection closed prematurely</source>
+ <translation>Anslutning till proxy stängdes i förtid</translation>
+ </message>
</context>
<context>
<name>QIBaseDriver</name>
<message>
+ <location filename="../src/sql/drivers/ibase/qsql_ibase.cpp" line="+1491"/>
<source>Error opening database</source>
<translation>Fel vid öppning av databas</translation>
</message>
<message>
+ <location line="+54"/>
<source>Could not start transaction</source>
<translation>Kunde inte starta transaktion</translation>
</message>
<message>
+ <location line="+13"/>
<source>Unable to commit transaction</source>
<translation>Kunde inte verkställa transaktion</translation>
</message>
<message>
+ <location line="+13"/>
<source>Unable to rollback transaction</source>
<translation>Kunde inte rulla tillbaka transaktion</translation>
</message>
@@ -1781,70 +4202,89 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QIBaseResult</name>
<message>
+ <location line="-1149"/>
<source>Unable to create BLOB</source>
<translation>Kunde inte skapa BLOB</translation>
</message>
<message>
+ <location line="+6"/>
<source>Unable to write BLOB</source>
<translation>Kunde inte skriva BLOB</translation>
</message>
<message>
+ <location line="+14"/>
<source>Unable to open BLOB</source>
<translation>Kunde inte öppna BLOB</translation>
</message>
<message>
+ <location line="+16"/>
<source>Unable to read BLOB</source>
<translation>Kunde inte läsa BLOB</translation>
</message>
<message>
+ <location line="+125"/>
+ <location line="+187"/>
<source>Could not find array</source>
<translation>Kunde inte hitta kedja</translation>
</message>
<message>
+ <location line="-155"/>
<source>Could not get array data</source>
<translation>Kunde inte få kedjedata</translation>
</message>
<message>
+ <location line="+210"/>
<source>Could not get query info</source>
<translation>Kunde inte gå frågesatsinformation</translation>
</message>
<message>
+ <location line="+20"/>
<source>Could not start transaction</source>
<translation>Kunde inte starta transaktion</translation>
</message>
<message>
+ <location line="+19"/>
<source>Unable to commit transaction</source>
<translation>Kunde inte verkställa transaktion</translation>
</message>
<message>
+ <location line="+42"/>
<source>Could not allocate statement</source>
<translation>Kunde inte allokera frågesats</translation>
</message>
<message>
+ <location line="+5"/>
<source>Could not prepare statement</source>
<translation>Kunde inte förbereda frågesats</translation>
</message>
<message>
+ <location line="+5"/>
+ <location line="+11"/>
<source>Could not describe input statement</source>
<translation>Kunde inte beskriva inmatningsfrågesats</translation>
</message>
<message>
+ <location line="+14"/>
<source>Could not describe statement</source>
<translation>Kunde inte beskriva frågesats</translation>
</message>
<message>
+ <location line="+115"/>
<source>Unable to close statement</source>
<translation>Kunde inte stänga frågesats</translation>
</message>
<message>
+ <location line="+8"/>
<source>Unable to execute query</source>
<translation>Kunde inte köra frågesats</translation>
</message>
<message>
+ <location line="+46"/>
<source>Could not fetch next item</source>
<translation>Kunde inte hämta nästa post</translation>
</message>
<message>
+ <location line="+197"/>
<source>Could not get statement info</source>
<translation>Kunde inte få frågesatsinformation</translation>
</message>
@@ -1852,22 +4292,27 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QIODevice</name>
<message>
+ <location filename="../src/corelib/global/qglobal.cpp" line="+2131"/>
<source>Permission denied</source>
<translation>Ã…tkomst nekad</translation>
</message>
<message>
+ <location line="+3"/>
<source>Too many open files</source>
<translation>För många öppna filer</translation>
</message>
<message>
+ <location line="+3"/>
<source>No such file or directory</source>
<translation>Ingen sådan fil eller katalog</translation>
</message>
<message>
+ <location line="+3"/>
<source>No space left on device</source>
<translation>Inget ledigt utrymme på enheten</translation>
</message>
<message>
+ <location filename="../src/corelib/io/qiodevice.cpp" line="+1621"/>
<source>Unknown error</source>
<translation>Okänt fel</translation>
</message>
@@ -1875,100 +4320,156 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QInputContext</name>
<message>
+ <location filename="../src/gui/inputmethod/qinputcontextfactory.cpp" line="+301"/>
<source>XIM</source>
<translation>XIM</translation>
</message>
<message>
+ <location line="+4"/>
+ <source>FEP</source>
+ <translation>FEP</translation>
+ </message>
+ <message>
+ <location line="+23"/>
<source>XIM input method</source>
<translation>XIM-inmatningsmetod</translation>
</message>
<message>
+ <location line="+4"/>
<source>Windows input method</source>
<translation>Windows-inmatningsmetod</translation>
</message>
<message>
+ <location line="+4"/>
<source>Mac OS X input method</source>
<translation>Mac OS X-inmatningsmetod</translation>
</message>
+ <message>
+ <location line="+4"/>
+ <source>S60 FEP input method</source>
+ <translation>S60 FEP-inmatningsmetod</translation>
+ </message>
+</context>
+<context>
+ <name>QInputDialog</name>
+ <message>
+ <location filename="../src/gui/dialogs/qinputdialog.cpp" line="+223"/>
+ <source>Enter a value:</source>
+ <translation>Ange ett värde:</translation>
+ </message>
</context>
<context>
<name>QLibrary</name>
<message>
<source>QLibrary::load_sys: Cannot load %1 (%2)</source>
- <translation>QLibrary::load_sys: Kan inte läsa in %1 (%2)</translation>
+ <translation type="obsolete">QLibrary::load_sys: Kan inte läsa in %1 (%2)</translation>
</message>
<message>
<source>QLibrary::unload_sys: Cannot unload %1 (%2)</source>
- <translation>QLibrary::unload_sys: Kan inte läsa ur %1 (%2)</translation>
+ <translation type="obsolete">QLibrary::unload_sys: Kan inte läsa ur %1 (%2)</translation>
</message>
<message>
<source>QLibrary::resolve_sys: Symbol &quot;%1&quot; undefined in %2 (%3)</source>
- <translation>QLibrary::resolve_sys: Symbolen &quot;%1&quot; är inte definierad i %2 (%3)</translation>
+ <translation type="obsolete">QLibrary::resolve_sys: Symbolen &quot;%1&quot; är inte definierad i %2 (%3)</translation>
</message>
<message>
<source>Could not mmap &apos;%1&apos;: %2</source>
- <translation>Kunde inte mmap \&quot;%1\&quot;: %2</translation>
+ <translation type="obsolete">Kunde inte mmap \&quot;%1\&quot;: %2</translation>
</message>
<message>
+ <location filename="../src/corelib/plugin/qlibrary.cpp" line="+378"/>
<source>Plugin verification data mismatch in &apos;%1&apos;</source>
- <translation>Dataverifiering av insticksmodul misslyckades i \&quot;%1\&quot;</translation>
+ <translation>Dataverifieringsfel av insticksmodul i \&quot;%1\&quot;</translation>
</message>
<message>
<source>Could not unmap &apos;%1&apos;: %2</source>
- <translation>Kunde inte unmap \&quot;%1\&quot;: %2</translation>
+ <translation type="obsolete">Kunde inte unmap \&quot;%1\&quot;: %2</translation>
</message>
<message>
+ <location line="+215"/>
+ <location line="+138"/>
+ <location filename="../src/corelib/plugin/qpluginloader.cpp" line="+343"/>
<source>The shared library was not found.</source>
<translation>Det delade biblioteket hittades inte.</translation>
</message>
<message>
+ <location line="+2"/>
<source>The file &apos;%1&apos; is not a valid Qt plugin.</source>
- <translation>Filen \&quot;%1\&quot; är inte en giltig insticksmodul för Qt.</translation>
+ <translation>Filen \&quot;%1\&quot; är inte ett giltig Qt-insticksprogram.</translation>
</message>
<message>
+ <location line="+15"/>
<source>The plugin &apos;%1&apos; uses incompatible Qt library. (%2.%3.%4) [%5]</source>
- <translation>Insticksmodulen \&quot;%1\&quot; använder ett inkompatibelt Qt-bibliotek. (%2.%3.%4) [%5]</translation>
+ <translation>Insticksprogrammet \&quot;%1\&quot; använder ett inkompatibelt Qt-bibliotek. (%2.%3.%4) [%5]</translation>
</message>
<message>
+ <location line="+23"/>
<source>The plugin &apos;%1&apos; uses incompatible Qt library. Expected build key &quot;%2&quot;, got &quot;%3&quot;</source>
- <translation>Insticksmodulen \&quot;%1\&quot; använder ett inkompatibelt Qt-bibliotek. Förväntade byggnyckel \&quot;%2&quot;, fick &quot;%3&quot;</translation>
+ <translation>Insticksmodulen \&quot;%1\&quot; använder ett inkompatibelt Qt-bibliotek. Förväntad byggnyckel &quot;%2&quot;, fick &quot;%3&quot;</translation>
</message>
<message>
+ <location line="+8"/>
<source>The plugin &apos;%1&apos; uses incompatible Qt library. (Cannot mix debug and release libraries.)</source>
- <translation>Insticksmodulen \&quot;%1\&quot; använder ett inkompatibelt Qt-bibliotek. (Kan inte blanda bibliotek för \&quot;debug\&quot; och \&quot;release\&quot;.)</translation>
+ <translation>Insticksmodulen \&quot;%1\&quot; använder ett inkompatibelt Qt-bibliotek. (Kan inte blanda bibliotek för debug och release.)</translation>
</message>
<message>
+ <location line="+357"/>
<source>Unknown error</source>
<translation>Okänt fel</translation>
</message>
+ <message>
+ <location filename="../src/corelib/plugin/qlibrary_unix.cpp" line="+236"/>
+ <location filename="../src/corelib/plugin/qlibrary_win.cpp" line="+87"/>
+ <source>Cannot load library %1: %2</source>
+ <translation>Kan inte ladda biblioteket %1: %2</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <location filename="../src/corelib/plugin/qlibrary_win.cpp" line="+22"/>
+ <source>Cannot unload library %1: %2</source>
+ <translation>Kan inte ladda ur biblioteket %1: %2</translation>
+ </message>
+ <message>
+ <location line="+34"/>
+ <location filename="../src/corelib/plugin/qlibrary_win.cpp" line="+15"/>
+ <source>Cannot resolve symbol &quot;%1&quot; in %2: %3</source>
+ <translation>Kan inte upplösa symbolen &quot;%1&quot; i %2: %3</translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
<message>
+ <location filename="../src/gui/widgets/qlineedit.cpp" line="+2087"/>
<source>&amp;Undo</source>
<translation>&amp;Ã…ngra</translation>
</message>
<message>
+ <location line="+4"/>
<source>&amp;Redo</source>
<translation>&amp;Gör om</translation>
</message>
<message>
+ <location line="+9"/>
<source>Cu&amp;t</source>
<translation>Klipp &amp;ut</translation>
</message>
<message>
+ <location line="+6"/>
<source>&amp;Copy</source>
<translation>&amp;Kopiera</translation>
</message>
<message>
+ <location line="+6"/>
<source>&amp;Paste</source>
<translation>Klistra &amp;in</translation>
</message>
<message>
+ <location line="+7"/>
<source>Delete</source>
<translation>Ta bort</translation>
</message>
<message>
+ <location line="+8"/>
<source>Select All</source>
<translation>Markera alla</translation>
</message>
@@ -1976,18 +4477,23 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QLocalServer</name>
<message>
+ <location filename="../src/network/socket/qlocalserver.cpp" line="+224"/>
+ <location filename="../src/network/socket/qlocalserver_unix.cpp" line="+246"/>
<source>%1: Name error</source>
<translation>%1: Namnfel</translation>
</message>
<message>
+ <location filename="../src/network/socket/qlocalserver_unix.cpp" line="-8"/>
<source>%1: Permission denied</source>
- <translation>%1: Ã…tkomst nekas</translation>
+ <translation>%1: Ã…terkomst nekad</translation>
</message>
<message>
+ <location line="+12"/>
<source>%1: Address in use</source>
<translation>%1: Adressen används redan</translation>
</message>
<message>
+ <location line="+5"/>
<source>%1: Unknown error %2</source>
<translation>%1: Okänt fel %2</translation>
</message>
@@ -1995,42 +4501,70 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QLocalSocket</name>
<message>
+ <location filename="../src/network/socket/qlocalsocket_tcp.cpp" line="+132"/>
+ <location filename="../src/network/socket/qlocalsocket_unix.cpp" line="+139"/>
<source>%1: Connection refused</source>
- <translation>%1: Anslutning nekades</translation>
+ <translation>%1: Anslutning nekad</translation>
</message>
<message>
+ <location line="+3"/>
+ <location filename="../src/network/socket/qlocalsocket_unix.cpp" line="+3"/>
<source>%1: Remote closed</source>
- <translation></translation>
+ <translation>%1: Fjärrvärden stängde</translation>
</message>
<message>
+ <location line="+3"/>
+ <location filename="../src/network/socket/qlocalsocket_unix.cpp" line="+3"/>
+ <location filename="../src/network/socket/qlocalsocket_win.cpp" line="+79"/>
+ <location line="+59"/>
<source>%1: Invalid name</source>
<translation>%1: Ogiltigt namn</translation>
</message>
<message>
+ <location line="+3"/>
+ <location filename="../src/network/socket/qlocalsocket_unix.cpp" line="+3"/>
<source>%1: Socket access error</source>
- <translation type="unfinished"></translation>
+ <translation>%1: Uttagsåtkomstfel</translation>
</message>
<message>
+ <location line="+3"/>
+ <location filename="../src/network/socket/qlocalsocket_unix.cpp" line="+3"/>
<source>%1: Socket resource error</source>
- <translation type="unfinished"></translation>
+ <translation>%1: Resursfel i uttag</translation>
</message>
<message>
+ <location line="+3"/>
+ <location filename="../src/network/socket/qlocalsocket_unix.cpp" line="+3"/>
<source>%1: Socket operation timed out</source>
- <translation type="unfinished"></translation>
+ <translation>%1: Uttagsåtgärd översteg tidsgränsen</translation>
</message>
<message>
+ <location line="+3"/>
+ <location filename="../src/network/socket/qlocalsocket_unix.cpp" line="+3"/>
<source>%1: Datagram too large</source>
- <translation type="unfinished"></translation>
+ <translation>%1: Datagram för stort</translation>
</message>
<message>
+ <location line="+3"/>
+ <location filename="../src/network/socket/qlocalsocket_unix.cpp" line="+3"/>
+ <location filename="../src/network/socket/qlocalsocket_win.cpp" line="-64"/>
<source>%1: Connection error</source>
<translation>%1: Anslutningsfel</translation>
</message>
<message>
+ <location line="+3"/>
+ <location filename="../src/network/socket/qlocalsocket_unix.cpp" line="+3"/>
<source>%1: The socket operation is not supported</source>
- <translation type="unfinished"></translation>
+ <translation>%1: Uttagsåtgärden stöds inte</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>%1: Unknown error</source>
+ <translation>%1: Okänt fel</translation>
</message>
<message>
+ <location filename="../src/network/socket/qlocalsocket_unix.cpp" line="+4"/>
+ <location filename="../src/network/socket/qlocalsocket_win.cpp" line="+10"/>
<source>%1: Unknown error %2</source>
<translation>%1: Okänt fel %2</translation>
</message>
@@ -2038,22 +4572,27 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QMYSQLDriver</name>
<message>
+ <location filename="../src/sql/drivers/mysql/qsql_mysql.cpp" line="+1287"/>
<source>Unable to open database &apos;</source>
<translation>Kunde inte öppna databasen \&quot;</translation>
</message>
<message>
+ <location line="+11"/>
<source>Unable to connect</source>
<translation>Kunde inte ansluta</translation>
</message>
<message>
+ <location line="+150"/>
<source>Unable to begin transaction</source>
<translation>Kunde inte påbörja transaktion</translation>
</message>
<message>
+ <location line="+17"/>
<source>Unable to commit transaction</source>
<translation>Kunde inte verkställa transaktion</translation>
</message>
<message>
+ <location line="+17"/>
<source>Unable to rollback transaction</source>
<translation>Kunde inte rulla tillbaka transaktion</translation>
</message>
@@ -2061,46 +4600,60 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QMYSQLResult</name>
<message>
+ <location line="-977"/>
+ <location line="+31"/>
<source>Unable to fetch data</source>
<translation>Kunde inte hämta data</translation>
</message>
<message>
+ <location line="+161"/>
<source>Unable to execute query</source>
<translation>Kunde inte köra frågesats</translation>
</message>
<message>
+ <location line="+6"/>
<source>Unable to store result</source>
<translation>Kunde inte lagra resultat</translation>
</message>
<message>
+ <location line="+191"/>
+ <location line="+8"/>
<source>Unable to prepare statement</source>
<translation>Kunde inte förbereda frågesats</translation>
</message>
<message>
+ <location line="+37"/>
<source>Unable to reset statement</source>
<translation>Kunde inte återställa frågesats</translation>
</message>
<message>
+ <location line="+86"/>
<source>Unable to bind value</source>
<translation>Kunde inte binda värde</translation>
</message>
<message>
+ <location line="+11"/>
<source>Unable to execute statement</source>
<translation>Kunde inte köra frågesats</translation>
</message>
<message>
+ <location line="+14"/>
+ <location line="+21"/>
<source>Unable to bind outvalues</source>
<translation>Kunde inte binda utvärden</translation>
</message>
<message>
+ <location line="-12"/>
<source>Unable to store statement results</source>
<translation>Kunde inte lagra resultat från frågesats</translation>
</message>
<message>
+ <location line="-253"/>
<source>Unable to execute next query</source>
<translation>Kunde inte köra nästa frågesats</translation>
</message>
<message>
+ <location line="+10"/>
<source>Unable to store next result</source>
<translation>Kunde inte lagra nästa resultat</translation>
</message>
@@ -2108,6 +4661,7 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QMdiArea</name>
<message>
+ <location filename="../src/gui/widgets/qmdiarea.cpp" line="+290"/>
<source>(Untitled)</source>
<translation>(Namnlös)</translation>
</message>
@@ -2115,74 +4669,92 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QMdiSubWindow</name>
<message>
+ <location filename="../src/gui/widgets/qmdisubwindow.cpp" line="+280"/>
<source>%1 - [%2]</source>
<translation>%1 - [%2]</translation>
</message>
<message>
+ <location line="+72"/>
<source>Close</source>
<translation>Stäng</translation>
</message>
<message>
+ <location line="-18"/>
<source>Minimize</source>
<translation>Minimera</translation>
</message>
<message>
+ <location line="+13"/>
<source>Restore Down</source>
<translation>Återställ nedåt</translation>
</message>
<message>
+ <location line="+707"/>
<source>&amp;Restore</source>
<translation>Åte&amp;rställ</translation>
</message>
<message>
+ <location line="+3"/>
<source>&amp;Move</source>
<translation>&amp;Flytta</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Size</source>
<translation>&amp;Storlek</translation>
</message>
<message>
+ <location line="+1"/>
<source>Mi&amp;nimize</source>
<translation>Mi&amp;nimera</translation>
</message>
<message>
+ <location line="+2"/>
<source>Ma&amp;ximize</source>
<translation>Ma&amp;ximera</translation>
</message>
<message>
+ <location line="+2"/>
<source>Stay on &amp;Top</source>
- <translation>Placera övers&amp;t</translation>
+ <translation>Alltid övers&amp;t</translation>
</message>
<message>
+ <location line="+3"/>
<source>&amp;Close</source>
<translation>&amp;Stäng</translation>
</message>
<message>
+ <location line="-787"/>
<source>- [%1]</source>
<translation>- [%1]</translation>
</message>
<message>
+ <location line="+58"/>
<source>Maximize</source>
<translation>Maximera</translation>
</message>
<message>
+ <location line="+3"/>
<source>Unshade</source>
- <translation>Rulla ned</translation>
+ <translation>Avskugga</translation>
</message>
<message>
+ <location line="+3"/>
<source>Shade</source>
- <translation>Rulla upp</translation>
+ <translation>Skugga</translation>
</message>
<message>
+ <location line="+6"/>
<source>Restore</source>
<translation>Återställ</translation>
</message>
<message>
+ <location line="+6"/>
<source>Help</source>
<translation>Hjälp</translation>
</message>
<message>
+ <location line="+3"/>
<source>Menu</source>
<translation>Meny</translation>
</message>
@@ -2190,56 +4762,138 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QMenu</name>
<message>
+ <location filename="../src/plugins/accessible/widgets/qaccessiblemenu.cpp" line="+157"/>
+ <location line="+225"/>
<source>Close</source>
<translation>Stäng</translation>
</message>
<message>
+ <location line="-224"/>
+ <location line="+225"/>
<source>Open</source>
<translation>Öppna</translation>
</message>
<message>
+ <location line="-223"/>
+ <location line="+225"/>
+ <location line="+51"/>
<source>Execute</source>
<translation>Kör</translation>
</message>
</context>
<context>
+ <name>QMenuBar</name>
+ <message>
+ <source>About</source>
+ <translation type="obsolete">Om</translation>
+ </message>
+ <message>
+ <source>Config</source>
+ <translation type="obsolete">Konfiguration</translation>
+ </message>
+ <message>
+ <source>Preference</source>
+ <translation type="obsolete">Inställning</translation>
+ </message>
+ <message>
+ <source>Options</source>
+ <translation type="obsolete">Alternativ</translation>
+ </message>
+ <message>
+ <source>Setting</source>
+ <translation type="obsolete">Inställning</translation>
+ </message>
+ <message>
+ <source>Setup</source>
+ <translation type="obsolete">Konfiguration</translation>
+ </message>
+ <message>
+ <source>Quit</source>
+ <translation type="obsolete">Avsluta</translation>
+ </message>
+ <message>
+ <source>Exit</source>
+ <translation type="obsolete">Avsluta</translation>
+ </message>
+ <message>
+ <source>About %1</source>
+ <translation type="obsolete">Om %1</translation>
+ </message>
+ <message>
+ <source>About Qt</source>
+ <translation type="obsolete">Om Qt</translation>
+ </message>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Inställningar</translation>
+ </message>
+ <message>
+ <source>Quit %1</source>
+ <translation type="obsolete">Avsluta %1</translation>
+ </message>
+ <message>
+ <location filename="../src/gui/widgets/qmenu_symbian.cpp" line="+456"/>
+ <source>Actions</source>
+ <translation>Åtgärder</translation>
+ </message>
+</context>
+<context>
<name>QMessageBox</name>
<message>
+ <location filename="../src/gui/dialogs/qmessagebox.cpp" line="-1090"/>
<source>Help</source>
<translation>Hjälp</translation>
</message>
<message>
+ <location line="-846"/>
+ <location line="+845"/>
+ <location filename="../src/gui/dialogs/qmessagebox.h" line="-52"/>
+ <location line="+8"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
+ <location line="+469"/>
+ <source>&lt;h3&gt;About Qt&lt;/h3&gt;&lt;p&gt;This program uses Qt version %1.&lt;/p&gt;</source>
+ <translation>&lt;h3&gt;Om Qt&lt;/h3&gt;&lt;p&gt;Programmet använder Qt version %1.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>&lt;p&gt;Qt is a C++ toolkit for cross-platform application development.&lt;/p&gt;&lt;p&gt;Qt provides single-source portability across MS&amp;nbsp;Windows, Mac&amp;nbsp;OS&amp;nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.&lt;/p&gt;&lt;p&gt;Qt is available under three different licensing options designed to accommodate the needs of our various users.&lt;/p&gt;&lt;p&gt;Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.&lt;/p&gt;&lt;p&gt;Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.&lt;/p&gt;&lt;p&gt;Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.&lt;/p&gt;&lt;p&gt;Please see &lt;a href=&quot;http://qt.nokia.com/products/licensing&quot;&gt;qt.nokia.com/products/licensing&lt;/a&gt; for an overview of Qt licensing.&lt;/p&gt;&lt;p&gt;Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).&lt;/p&gt;&lt;p&gt;Qt is a Nokia product. See &lt;a href=&quot;http://qt.nokia.com/&quot;&gt;qt.nokia.com&lt;/a&gt; for more information.&lt;/p&gt;</source>
+ <translation>&lt;p&gt;Qt är ett C++-programbibliotek för programutveckling på flera plattformar.&lt;/p&gt;&lt;p&gt;Qt gör det möjligt att använda samma källkod för MS&amp;nbsp;Windows, Mac&amp;nbsp;OS&amp;nbsp;X, Linux, och alla större kommersiella Unix-versioner. Qt finns också tillgängligt för inbäddade enheter som Qt for Embedded Linux och Qt for Windows CE.&lt;/p&gt;&lt;p&gt;Qt är tillgängligt med tre olika licensalternativ skapade för att uppfylla behoven hos våra olika användare.&lt;/p&gt;&lt;p&gt;Qt licensierat enligt vårt kommersiella licensavtal är lämpligt för utveckling av privat eller kommersiell programvara, där man inte vill dela någon källkod med tredje part eller på annat sätt inte kan uppfylla villkoren i GNU LGPL version 2.1 eller GNU GPL version 3.0.&lt;/p&gt;&lt;p&gt;Qt licensierat enligt GNU LGPL version 2.1 är lämpligt för utveckling av Qt-program (privata eller med öppen källkod) under förutsättning att man kan uppfylla villkoren och kraven i GNU LGPL version 2.1.&lt;/p&gt;&lt;p&gt;Qt licensierat enligt GNU General Public License version 3.0 är lämpligt för utveckling av Qt-program där man vill använda sådana program i kombination med programvara som lyder under villkoren i GNU GPL version 3.0 eller där man i övrigt är beredd att uppfylla villkoren i GNU GPL version 3.0.&lt;/p&gt;&lt;p&gt;Se &lt;a href=&quot;http://qt.nokia.com/products/licensing&quot;&gt;qt.nokia.com/products/licensing&lt;/a&gt; för en översikt av Qt licensiering.&lt;/p&gt;&lt;p&gt;Copyright © 2010 Nokia Corporation och/eller dess dotterbolag.&lt;/p&gt;&lt;p&gt;Qt är en produkt från Nokia. Se &lt;a href=&quot;http://qt.nokia.com/&quot;&gt;qt.nokia.com&lt;/a&gt; för mer information.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <location line="+31"/>
<source>About Qt</source>
<translation>Om Qt</translation>
</message>
<message>
<source>&lt;p&gt;This program uses Qt version %1.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Detta program använder Qt version %1.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Detta program använder Qt version %1.&lt;/p&gt;</translation>
</message>
<message>
+ <location line="-1631"/>
<source>Show Details...</source>
<translation>Visa detaljer...</translation>
</message>
<message>
+ <location line="+0"/>
<source>Hide Details...</source>
<translation>Dölj detaljer...</translation>
</message>
<message>
<source>&lt;p&gt;This program uses Qt Open Source Edition version %1.&lt;/p&gt;&lt;p&gt;Qt Open Source Edition is intended for the development of Open Source applications. You need a commercial Qt license for development of proprietary (closed source) applications.&lt;/p&gt;&lt;p&gt;Please see &lt;a href=&quot;http://www.trolltech.com/company/model/&quot;&gt;www.trolltech.com/company/model/&lt;/a&gt; for an overview of Qt licensing.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Detta program använder Qt Open Source Edition version %1.&lt;/p&gt;&lt;p&gt;Qt Open Source Edition är tänkt för utveckling av program med öppen källkod. Du behöver en kommersiell Qt-licens för utveckling av proprietära (stängd källkod) program.&lt;/p&gt;&lt;p&gt;Se &lt;a href=&quot;http://www.trolltech.com/company/model/&quot;&gt;www.trolltech.com/company/model/&lt;/a&gt; för information om licensiering av Qt.&lt;/p&gt;</translation>
+ <translation type="obsolete">&lt;p&gt;Detta program använder Qt Open Source Edition version %1.&lt;/p&gt;&lt;p&gt;Qt Open Source Edition är ämnad för utvecklingen av öppen källkodsprogram. En kommersiell Qt-licens behövs vid utveckling av äganderättsskyddade program (sluten källkod).&lt;/p&gt;&lt;p&gt;Se &lt;a href=&quot;http://www.trolltech.com/company/model/&quot;&gt;www.trolltech.com/company/model/&lt;/a&gt; för en översikt för Qt-licensiering.&lt;/p&gt;</translation>
</message>
<message>
- <source>&lt;h3&gt;About Qt&lt;/h3&gt;%1&lt;p&gt;Qt is a C++ toolkit for cross-platform application development.&lt;/p&gt;&lt;p&gt;Qt provides single-source portability across MS&amp;nbsp;Windows, Mac&amp;nbsp;OS&amp;nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.&lt;/p&gt;&lt;p&gt;Qt is a Nokia product. See &lt;a href=&quot;http://www.trolltech.com/qt/&quot;&gt;www.trolltech.com/qt/&lt;/a&gt; for more information.&lt;/p&gt;</source>
- <translation>&lt;h3&gt;Om Qt&lt;/h3&gt;%1&lt;p&gt;Qt är ett C++-verktygssamling för utveckling av krossplattformsprogram.&lt;/p&gt;&lt;p&gt;Qt tillhandahåller portabilitet för samma källkod mellan MS&amp;nbsp;Windows, Mac&amp;nbsp;OS&amp;nbsp;X, Linux och alla andra stora kommersiella Unix-varianter. Qt finns också tillgängligt för inbäddade enheter som Qt for Embedded Linux och Qt for Windows CE.&lt;/p&gt;&lt;p&gt;Qt är en produkt från Nokia. Se &lt;a href=&quot;http://www.trolltech.com/qt/&quot;&gt;www.trolltech.com/qt/&lt;/a&gt; för mer information.&lt;/p&gt;</translation>
+ <source>&lt;h3&gt;About Qt&lt;/h3&gt;%1&lt;p&gt;Qt is a C++ toolkit for cross-platform application development.&lt;/p&gt;&lt;p&gt;Qt provides single-source portability across MS&amp;nbsp;Windows, Mac&amp;nbsp;OS&amp;nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt Embedded.&lt;/p&gt;&lt;p&gt;Qt is a Trolltech product. See &lt;a href=&quot;http://www.trolltech.com/qt/&quot;&gt;www.trolltech.com/qt/&lt;/a&gt; for more information.&lt;/p&gt;</source>
+ <translation type="obsolete">&lt;h3&gt;Om Qt&lt;/h3&gt;%1&lt;p&gt;Qt är ett C++-ramverk för plattformsoberoende programutveckling.&lt;/p&gt;&lt;p&gt;Qt tillhandahåller portabilitet för källkod mellan MS&amp;nbsp;Windows, Mac&amp;nbsp;OS&amp;nbsp;X, Linux samt alla större kommersiella Unix-varianter. Qt finns också tillgängligt för inbäddade enheter som Qt Embedded.&lt;/p&gt;&lt;p&gt;Qt är en produkt från Trolltech. Se &lt;a href=&quot;http://www.trolltech.com/qt/&quot;&gt;www.trolltech.com/qt/&lt;/a&gt; för mer information.&lt;/p&gt;</translation>
</message>
</context>
<context>
<name>QMultiInputContext</name>
<message>
+ <location filename="../src/plugins/inputmethods/imsw-multi/qmultiinputcontext.cpp" line="+88"/>
<source>Select IM</source>
<translation>Välj inmatningsmetod</translation>
</message>
@@ -2247,10 +4901,12 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QMultiInputContextPlugin</name>
<message>
+ <location filename="../src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.cpp" line="+95"/>
<source>Multiple input method switcher</source>
<translation>Växlare för flera inmatningsmetoder</translation>
</message>
<message>
+ <location line="+7"/>
<source>Multiple input method switcher that uses the context menu of the text widgets</source>
<translation>Växlare för flera inmatningsmetoder som använder sammanhangsmenyn för textwidgar</translation>
</message>
@@ -2258,129 +4914,202 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QNativeSocketEngine</name>
<message>
+ <location filename="../src/network/socket/qnativesocketengine.cpp" line="+209"/>
<source>The remote host closed the connection</source>
<translation>Fjärrvärden stängde anslutningen</translation>
</message>
<message>
+ <location line="+3"/>
<source>Network operation timed out</source>
<translation>Tidsgräns för nätverksåtgärd överstegs</translation>
</message>
<message>
+ <location line="+3"/>
<source>Out of resources</source>
<translation>Slut på resurser</translation>
</message>
<message>
+ <location line="+3"/>
<source>Unsupported socket operation</source>
<translation>Uttagsåtgärden stöds inte</translation>
</message>
<message>
+ <location line="+3"/>
<source>Protocol type not supported</source>
<translation>Protokolltypen stöds inte</translation>
</message>
<message>
+ <location line="+3"/>
<source>Invalid socket descriptor</source>
<translation>Ogiltig uttagsbeskrivare</translation>
</message>
<message>
+ <location line="+6"/>
<source>Network unreachable</source>
<translation>Nätverket är inte nåbart</translation>
</message>
<message>
+ <location line="+3"/>
<source>Permission denied</source>
<translation>Ã…tkomst nekad</translation>
</message>
<message>
+ <location line="+3"/>
<source>Connection timed out</source>
<translation>Tidsgränsen för anslutning överstegs</translation>
</message>
<message>
+ <location line="+3"/>
<source>Connection refused</source>
<translation>Anslutningen vägrades</translation>
</message>
<message>
+ <location line="+3"/>
<source>The bound address is already in use</source>
<translation>Bindningsadress används redan</translation>
</message>
<message>
+ <location line="+3"/>
<source>The address is not available</source>
<translation>Adressen är inte tillgänglig</translation>
</message>
<message>
+ <location line="+3"/>
<source>The address is protected</source>
<translation>Adressen är skyddad</translation>
</message>
<message>
+ <location line="+6"/>
<source>Unable to send a message</source>
<translation>Kunde inte skicka ett meddelande</translation>
</message>
<message>
+ <location line="+3"/>
<source>Unable to receive a message</source>
<translation>Kunde inte ta emot ett meddelande</translation>
</message>
<message>
+ <location line="+3"/>
<source>Unable to write</source>
<translation>Kunde inte skriva</translation>
</message>
<message>
+ <location line="+3"/>
<source>Network error</source>
<translation>Nätverksfel</translation>
</message>
<message>
+ <location line="+3"/>
<source>Another socket is already listening on the same port</source>
<translation>Ett annat uttag lyssnar redan på samma port</translation>
</message>
<message>
+ <location line="-66"/>
<source>Unable to initialize non-blocking socket</source>
<translation>Kunde inte initiera icke-blockerande uttag</translation>
</message>
<message>
+ <location line="+3"/>
<source>Unable to initialize broadcast socket</source>
<translation>Kunde inte initiera uttag för broadcast</translation>
</message>
<message>
+ <location line="+3"/>
<source>Attempt to use IPv6 socket on a platform with no IPv6 support</source>
<translation>Försök att använda IPv6-uttag på en plattform som saknar IPv6-stöd</translation>
</message>
<message>
+ <location line="+21"/>
<source>Host unreachable</source>
<translation>Värden är inte nåbar</translation>
</message>
<message>
+ <location line="+24"/>
<source>Datagram was too large to send</source>
<translation>Datagram för för stor för att skicka</translation>
</message>
<message>
+ <location line="+18"/>
<source>Operation on non-socket</source>
<translation>Åtgärd på icke-uttag</translation>
</message>
<message>
+ <location line="+6"/>
<source>Unknown error</source>
<translation>Okänt fel</translation>
</message>
<message>
+ <location line="-3"/>
<source>The proxy type is invalid for this operation</source>
<translation>Proxytypen är ogiltig för denna åtgärd</translation>
</message>
</context>
<context>
+ <name>QNetworkAccessCacheBackend</name>
+ <message>
+ <location filename="../src/network/access/qnetworkaccesscachebackend.cpp" line="+66"/>
+ <source>Error opening %1</source>
+ <translation>Fel när %1 skulle öppnas</translation>
+ </message>
+</context>
+<context>
+ <name>QNetworkAccessDataBackend</name>
+ <message>
+ <location filename="../src/network/access/qnetworkaccessdatabackend.cpp" line="+76"/>
+ <source>Operation not supported on %1</source>
+ <translation>Åtgärden stöds inte på %1</translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>Invalid URI: %1</source>
+ <translation>Ogiltig URI: %1</translation>
+ </message>
+</context>
+<context>
+ <name>QNetworkAccessDebugPipeBackend</name>
+ <message>
+ <location filename="../src/network/access/qnetworkaccessdebugpipebackend.cpp" line="+195"/>
+ <source>Write error writing to %1: %2</source>
+ <translation>Skrivfel vid skrivning till %1: %2</translation>
+ </message>
+ <message>
+ <location line="+60"/>
+ <source>Socket error on %1: %2</source>
+ <translation>Uttagsfel på %1: %2</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Remote host closed the connection prematurely on %1</source>
+ <translation>Fjärrvärden stängde anslutningen i förtid på %1</translation>
+ </message>
+</context>
+<context>
<name>QNetworkAccessFileBackend</name>
<message>
+ <location filename="../src/network/access/qfilenetworkreply.cpp" line="+85"/>
+ <location filename="../src/network/access/qnetworkaccessfilebackend.cpp" line="+100"/>
<source>Request for opening non-local file %1</source>
- <translation type="unfinished"></translation>
+ <translation>Begäran om öppning av icke-lokala filen %1</translation>
</message>
<message>
+ <location line="+36"/>
+ <location filename="../src/network/access/qnetworkaccessfilebackend.cpp" line="+45"/>
<source>Error opening %1: %2</source>
- <translation>Fel vid öppning av %1: %2</translation>
+ <translation>Fel vid öppnade av %1: %2</translation>
</message>
<message>
+ <location filename="../src/network/access/qnetworkaccessfilebackend.cpp" line="+38"/>
<source>Write error writing to %1: %2</source>
<translation>Skrivfel vid skrivning till %1: %2</translation>
</message>
<message>
+ <location filename="../src/network/access/qfilenetworkreply.cpp" line="-13"/>
+ <location filename="../src/network/access/qnetworkaccessfilebackend.cpp" line="+42"/>
<source>Cannot open %1: Path is a directory</source>
<translation>Kan inte öppna %1: Sökvägen är en katalog</translation>
</message>
<message>
+ <location filename="../src/network/access/qnetworkaccessfilebackend.cpp" line="+21"/>
<source>Read error reading from %1: %2</source>
<translation>Läsfel vid läsning från %1: %2</translation>
</message>
@@ -2388,60 +5117,162 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QNetworkAccessFtpBackend</name>
<message>
+ <location filename="../src/network/access/qnetworkaccessftpbackend.cpp" line="+131"/>
+ <source>No suitable proxy found</source>
+ <translation>Någon lämplig proxy hittades inte</translation>
+ </message>
+ <message>
+ <location line="+14"/>
<source>Cannot open %1: is a directory</source>
<translation>Kan inte öppna %1: är en katalog</translation>
</message>
<message>
+ <location line="+95"/>
<source>Logging in to %1 failed: authentication required</source>
<translation>Inloggning mot %1 misslyckades: autentisering krävs</translation>
</message>
<message>
+ <location line="+39"/>
<source>Error while downloading %1: %2</source>
<translation>Fel vid hämtning av %1: %2</translation>
</message>
<message>
+ <location line="+2"/>
<source>Error while uploading %1: %2</source>
<translation>Fel vid sändning av %1: %2</translation>
</message>
</context>
<context>
+ <name>QNetworkAccessHttpBackend</name>
+ <message>
+ <location filename="../src/network/access/qnetworkaccesshttpbackend.cpp" line="+647"/>
+ <location line="+5"/>
+ <source>No suitable proxy found</source>
+ <translation>Någon lämplig proxy hittades inte</translation>
+ </message>
+</context>
+<context>
+ <name>QNetworkAccessManager</name>
+ <message>
+ <location filename="../src/network/access/qnetworkreplyimpl.cpp" line="+966"/>
+ <source>Network access is disabled.</source>
+ <translation>Nätverksåtkomst är inaktiverad.</translation>
+ </message>
+</context>
+<context>
<name>QNetworkReply</name>
<message>
+ <location filename="../src/network/access/qnetworkaccesshttpbackend.cpp" line="+90"/>
<source>Error downloading %1 - server replied: %2</source>
<translation>Fel vid hämtning av %1 - servern svarade: %2</translation>
</message>
<message>
+ <location filename="../src/network/access/qnetworkreplyimpl.cpp" line="-884"/>
<source>Protocol &quot;%1&quot; is unknown</source>
<translation>Protokollet &quot;%1&quot; är okänt</translation>
</message>
+ <message>
+ <location line="+196"/>
+ <source>Network session error.</source>
+ <translation>Nätverkssessionsfel.</translation>
+ </message>
+ <message>
+ <location line="+372"/>
+ <source>Temporary network failure.</source>
+ <translation>Tillfälligt nätverksfel.</translation>
+ </message>
</context>
<context>
<name>QNetworkReplyImpl</name>
<message>
+ <location line="+120"/>
+ <location line="+28"/>
<source>Operation canceled</source>
<translation>Åtgärden avbröts</translation>
</message>
</context>
<context>
+ <name>QNetworkSession</name>
+ <message>
+ <location filename="../src/network/bearer/qnetworksession.cpp" line="+453"/>
+ <source>Invalid configuration.</source>
+ <translation>Ogiltig inställning.</translation>
+ </message>
+</context>
+<context>
+ <name>QNetworkSessionPrivateImpl</name>
+ <message>
+ <location filename="../src/plugins/bearer/icd/qnetworksession_impl.cpp" line="+1024"/>
+ <source>Roaming error</source>
+ <translation>Roaming-fel</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Session aborted by user or system</source>
+ <translation>Session avbruten av användaren eller systemet</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <location filename="../src/plugins/bearer/qnetworksession_impl.cpp" line="+278"/>
+ <location filename="../src/plugins/bearer/symbian/qnetworksession_impl.cpp" line="+312"/>
+ <source>The specified configuration cannot be used.</source>
+ <translation>Den angivna inställningen kan inte användas.</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Unidentified Error</source>
+ <translation>Oidentifierat fel</translation>
+ </message>
+ <message>
+ <location filename="../src/plugins/bearer/qnetworksession_impl.cpp" line="-6"/>
+ <location filename="../src/plugins/bearer/symbian/qnetworksession_impl.cpp" line="-6"/>
+ <source>Unknown session error.</source>
+ <translation>Okänt sessionsfel.</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <location filename="../src/plugins/bearer/symbian/qnetworksession_impl.cpp" line="+2"/>
+ <source>The session was aborted by the user or system.</source>
+ <translation>Sessionen avbröts av användaren eller systemet.</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <location filename="../src/plugins/bearer/symbian/qnetworksession_impl.cpp" line="+2"/>
+ <source>The requested operation is not supported by the system.</source>
+ <translation>Den begärda åtgärden stöds inte av systemet.</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <location filename="../src/plugins/bearer/symbian/qnetworksession_impl.cpp" line="+4"/>
+ <source>Roaming was aborted or is not possible.</source>
+ <translation>Roaming avbruten eller inte möjlig.</translation>
+ </message>
+</context>
+<context>
<name>QOCIDriver</name>
<message>
+ <location filename="../src/sql/drivers/oci/qsql_oci.cpp" line="+2225"/>
<source>Unable to logon</source>
<translation>Kunde inte logga in</translation>
</message>
<message>
+ <location line="-144"/>
<source>Unable to initialize</source>
<comment>QOCIDriver</comment>
<translation>Kunde inte initiera</translation>
</message>
<message>
+ <location line="+215"/>
<source>Unable to begin transaction</source>
<translation>Kunde inte påbörja transaktion</translation>
</message>
<message>
+ <location line="+19"/>
<source>Unable to commit transaction</source>
<translation>Kunde inte verkställa transaktion</translation>
</message>
<message>
+ <location line="+19"/>
<source>Unable to rollback transaction</source>
<translation>Kunde inte rulla tillbaka transaktion</translation>
</message>
@@ -2449,34 +5280,48 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QOCIResult</name>
<message>
+ <location line="-1020"/>
+ <location line="+194"/>
+ <location line="+15"/>
<source>Unable to bind column for batch execute</source>
<translation>Kunde inte binda kolumn för satskörning</translation>
</message>
<message>
+ <location line="+15"/>
<source>Unable to execute batch statement</source>
<translation>Kunde inte köra satsfråga</translation>
</message>
<message>
+ <location line="+319"/>
<source>Unable to goto next</source>
<translation>Kunde inte gå till nästa</translation>
</message>
<message>
+ <location line="+59"/>
<source>Unable to alloc statement</source>
<translation>Kunde inte allokera frågesats</translation>
</message>
<message>
+ <location line="+15"/>
<source>Unable to prepare statement</source>
<translation>Kunde inte förbereda frågesats</translation>
</message>
<message>
+ <location line="+26"/>
+ <source>Unable to get statement type</source>
+ <translation>Kan inte hämta satstyp</translation>
+ </message>
+ <message>
+ <location line="+20"/>
<source>Unable to bind value</source>
<translation>Kunde inte binda värde</translation>
</message>
<message>
<source>Unable to execute select statement</source>
- <translation>Kunde inte köra \&quot;select\&quot;-frågesats</translation>
+ <translation type="obsolete">Kunde inte köra \&quot;select\&quot;-frågesats</translation>
</message>
<message>
+ <location line="+19"/>
<source>Unable to execute statement</source>
<translation>Kunde inte köra frågesats</translation>
</message>
@@ -2484,26 +5329,36 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QODBCDriver</name>
<message>
+ <location filename="../src/sql/drivers/odbc/qsql_odbc.cpp" line="+1888"/>
<source>Unable to connect</source>
<translation>Kunde inte ansluta</translation>
</message>
<message>
<source>Unable to connect - Driver doesn&apos;t support all needed functionality</source>
- <translation>Kunde inte ansluta - Drivrutinen har inte stöd för all nödvändig funktionalitet</translation>
+ <translation type="obsolete">Kunde inte ansluta - Drivrutinen har inte stöd för all nödvändig funktionalitet</translation>
</message>
<message>
+ <location line="+6"/>
+ <source>Unable to connect - Driver doesn&apos;t support all functionality required</source>
+ <translation>Kan inte ansluta: Drivrutinen stöder inte alla funktioner som krävs</translation>
+ </message>
+ <message>
+ <location line="+263"/>
<source>Unable to disable autocommit</source>
<translation>Kunde inte inaktivera automatisk verkställning</translation>
</message>
<message>
+ <location line="+17"/>
<source>Unable to commit transaction</source>
<translation>Kunde inte verkställa transaktion</translation>
</message>
<message>
+ <location line="+17"/>
<source>Unable to rollback transaction</source>
<translation>Kunde inte rulla tillbaka transaktion</translation>
</message>
<message>
+ <location line="+15"/>
<source>Unable to enable autocommit</source>
<translation>Kunde inte aktivera automatisk verkställning</translation>
</message>
@@ -2511,38 +5366,51 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QODBCResult</name>
<message>
+ <location line="-1253"/>
+ <location line="+351"/>
<source>QODBCResult::reset: Unable to set &apos;SQL_CURSOR_STATIC&apos; as statement attribute. Please check your ODBC driver configuration</source>
<translation>QODBCResult::reset: Kunde inte ställa in \&quot;SQL_CURSOR_STATIC\&quot; som frågesatsattribut. Kontrollera konfigurationen för din ODBC-drivrutin</translation>
</message>
<message>
+ <location line="-334"/>
+ <location line="+627"/>
<source>Unable to execute statement</source>
<translation>Kunde inte köra frågesats</translation>
</message>
<message>
+ <location line="-546"/>
<source>Unable to fetch next</source>
<translation>Kunde inte hämta nästa</translation>
</message>
<message>
+ <location line="+271"/>
<source>Unable to prepare statement</source>
<translation>Kunde inte förbereda frågesats</translation>
</message>
<message>
+ <location line="+267"/>
<source>Unable to bind variable</source>
<translation>Kunde inte binda variabel</translation>
</message>
<message>
+ <location filename="../src/sql/drivers/db2/qsql_db2.cpp" line="+189"/>
+ <location filename="../src/sql/drivers/odbc/qsql_odbc.cpp" line="-466"/>
+ <location line="+578"/>
<source>Unable to fetch last</source>
- <translation>Kunde inte hämta senaste</translation>
+ <translation>Kunde inte hämta sista</translation>
</message>
<message>
+ <location filename="../src/sql/drivers/odbc/qsql_odbc.cpp" line="-672"/>
<source>Unable to fetch</source>
<translation>Kunde inte hämta</translation>
</message>
<message>
+ <location line="+44"/>
<source>Unable to fetch first</source>
<translation>Kunde inte hämta första</translation>
</message>
<message>
+ <location line="+19"/>
<source>Unable to fetch previous</source>
<translation>Kunde inte hämta föregående</translation>
</message>
@@ -2550,41 +5418,64 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QObject</name>
<message>
+ <source>Home</source>
+ <translation type="obsolete">Hem</translation>
+ </message>
+ <message>
<source>Operation not supported on %1</source>
- <translation>Åtgärden stöds inte på %1</translation>
+ <translation type="obsolete">Åtgärden stöds inte på %1</translation>
</message>
<message>
<source>Invalid URI: %1</source>
- <translation>Ogiltig URI: %1</translation>
+ <translation type="obsolete">Ogiltig URI: %1</translation>
</message>
<message>
<source>Write error writing to %1: %2</source>
- <translation>Skrivfel vid skrivning till %1: %2</translation>
+ <translation type="obsolete">Skrivfel vid skrivning till %1: %2</translation>
</message>
<message>
<source>Read error reading from %1: %2</source>
- <translation>Läsfel vid läsning från %1: %2</translation>
+ <translation type="obsolete">Läsfel vid läsning från %1: %2</translation>
</message>
<message>
<source>Socket error on %1: %2</source>
- <translation>Uttagsfel på %1: %2</translation>
+ <translation type="obsolete">Uttagsfel på %1: %2</translation>
</message>
<message>
<source>Remote host closed the connection prematurely on %1</source>
- <translation>Fjärrvärden stängde anslutningen i förtid på %1</translation>
+ <translation type="obsolete">Fjärrvärden stängde anslutningen i förtid på %1</translation>
</message>
<message>
<source>Protocol error: packet of size 0 received</source>
- <translation>Protokollfel: paket med storlek 0 togs emot</translation>
+ <translation type="obsolete">Protokollfel: paket med storlek 0 togs emot</translation>
+ </message>
+ <message>
+ <location filename="../src/3rdparty/phonon/phonon/pulsesupport.cpp" line="+162"/>
+ <location line="+11"/>
+ <source>PulseAudio Sound Server</source>
+ <translation>PulseAudio ljudserver</translation>
+ </message>
+ <message>
+ <location filename="../src/declarative/util/qdeclarativexmllistmodel.cpp" line="-249"/>
+ <source>&quot;%1&quot; duplicates a previous role name and will be disabled.</source>
+ <translation>&quot;%1&quot; duplicerar ett tidigare rollnamn och kommer att inaktiveras.</translation>
+ </message>
+ <message>
+ <location line="+531"/>
+ <location line="+4"/>
+ <source>invalid query: &quot;%1&quot;</source>
+ <translation>ogiltig förfrågan: &quot;%1&quot;</translation>
</message>
</context>
<context>
<name>QPPDOptionsModel</name>
<message>
+ <location filename="../src/gui/dialogs/qprintdialog_unix.cpp" line="+1238"/>
<source>Name</source>
<translation>Namn</translation>
</message>
<message>
+ <location line="+2"/>
<source>Value</source>
<translation>Värde</translation>
</message>
@@ -2592,37 +5483,45 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QPSQLDriver</name>
<message>
+ <location filename="../src/sql/drivers/psql/qsql_psql.cpp" line="+819"/>
<source>Unable to connect</source>
<translation>Kunde inte ansluta</translation>
</message>
<message>
+ <location line="+49"/>
<source>Could not begin transaction</source>
<translation>Kunde inte påbörja transaktion</translation>
</message>
<message>
+ <location line="+33"/>
<source>Could not commit transaction</source>
<translation>Kunde inte verkställa transaktion</translation>
</message>
<message>
+ <location line="+16"/>
<source>Could not rollback transaction</source>
<translation>Kunde inte rulla tillbaka transaktion</translation>
</message>
<message>
+ <location line="+386"/>
<source>Unable to subscribe</source>
- <translation type="unfinished"></translation>
+ <translation>Kunde inte prenumerera</translation>
</message>
<message>
+ <location line="+32"/>
<source>Unable to unsubscribe</source>
- <translation type="unfinished"></translation>
+ <translation>Kunde inte avsluta prenumeration</translation>
</message>
</context>
<context>
<name>QPSQLResult</name>
<message>
+ <location line="-1138"/>
<source>Unable to create query</source>
<translation>Kunde inte skapa fråga</translation>
</message>
<message>
+ <location line="+372"/>
<source>Unable to prepare statement</source>
<translation>Kunde inte förbereda frågesats</translation>
</message>
@@ -2630,93 +5529,115 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QPageSetupWidget</name>
<message>
+ <location filename="../src/gui/dialogs/qpagesetupdialog_unix.cpp" line="+304"/>
<source>Centimeters (cm)</source>
<translation>Centimeter (cm)</translation>
</message>
<message>
+ <location line="+0"/>
<source>Millimeters (mm)</source>
<translation>Millimeter (mm)</translation>
</message>
<message>
+ <location line="+0"/>
<source>Inches (in)</source>
<translation>Tum (in)</translation>
</message>
<message>
+ <location line="+0"/>
<source>Points (pt)</source>
<translation>Punkter (pt)</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qpagesetupwidget.ui"/>
<source>Form</source>
<translation>Format</translation>
</message>
<message>
+ <location/>
<source>Paper</source>
<translation>Papper</translation>
</message>
<message>
+ <location/>
<source>Page size:</source>
<translation>Sidstorlek:</translation>
</message>
<message>
+ <location/>
<source>Width:</source>
<translation>Bredd:</translation>
</message>
<message>
+ <location/>
<source>Height:</source>
<translation>Höjd:</translation>
</message>
<message>
+ <location/>
<source>Paper source:</source>
<translation>Papperskälla:</translation>
</message>
<message>
+ <location/>
<source>Orientation</source>
<translation>Orientering</translation>
</message>
<message>
+ <location/>
<source>Portrait</source>
<translation>Stående</translation>
</message>
<message>
+ <location/>
<source>Landscape</source>
<translation>Liggande</translation>
</message>
<message>
+ <location/>
<source>Reverse landscape</source>
<translation>Omvänt liggande</translation>
</message>
<message>
+ <location/>
<source>Reverse portrait</source>
- <translation>Omvänt stående</translation>
+ <translation>Omvänt porträtt</translation>
</message>
<message>
+ <location/>
<source>Margins</source>
<translation>Marginaler</translation>
</message>
<message>
+ <location/>
<source>top margin</source>
- <translation>övre marginal</translation>
+ <translation>övermarginal</translation>
</message>
<message>
+ <location/>
<source>left margin</source>
- <translation>vänstermarginal</translation>
+ <translation>Vänstermarginal</translation>
</message>
<message>
+ <location/>
<source>right margin</source>
<translation>högermarginal</translation>
</message>
<message>
+ <location/>
<source>bottom margin</source>
- <translation>nedre marginal</translation>
+ <translation>nedermarginal</translation>
</message>
</context>
<context>
<name>QPluginLoader</name>
<message>
+ <location filename="../src/corelib/plugin/qpluginloader.cpp" line="-89"/>
<source>The plugin was not loaded.</source>
- <translation>Insticksmodulen lästes inte in.</translation>
+ <translation>Insticksprogrammet lästes inte in.</translation>
</message>
<message>
+ <location line="+113"/>
<source>Unknown error</source>
<translation>Okänt fel</translation>
</message>
@@ -2724,278 +5645,560 @@ Vill du ta bort den ändå?</translation>
<context>
<name>QPrintDialog</name>
<message>
+ <location filename="../src/gui/painting/qprinterinfo_unix.cpp" line="+110"/>
<source>locally connected</source>
<translation>lokalt ansluten</translation>
</message>
<message>
+ <location line="+23"/>
+ <location line="+225"/>
<source>Aliases: %1</source>
<translation>Alias: %1</translation>
</message>
<message>
+ <location line="+225"/>
+ <location line="+199"/>
<source>unknown</source>
<translation>okänt</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qprintdialog_qws.cpp" line="+333"/>
+ <source>A0 (841 x 1189 mm)</source>
+ <translation>A0 (841 x 1189 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>A1 (594 x 841 mm)</source>
+ <translation>A1 (594 x 841 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>A2 (420 x 594 mm)</source>
+ <translation>A2 (420 x 594 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>A3 (297 x 420 mm)</source>
+ <translation>A3 (297 x 420 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>A4 (210 x 297 mm, 8.26 x 11.7 inches)</source>
+ <translation>A4 (210 x 297 mm, 8.26 x 11.7 tum)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>A5 (148 x 210 mm)</source>
+ <translation>A5 (148 x 210 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>A6 (105 x 148 mm)</source>
+ <translation>A6 (105 x 148 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>A7 (74 x 105 mm)</source>
+ <translation>A7 (74 x 105 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>A8 (52 x 74 mm)</source>
+ <translation>A8 (52 x 74 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>A9 (37 x 52 mm)</source>
+ <translation>A9 (37 x 52 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>B0 (1000 x 1414 mm)</source>
+ <translation>B0 (1000 x 1414 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>B1 (707 x 1000 mm)</source>
+ <translation>B1 (707 x 1000 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>B2 (500 x 707 mm)</source>
+ <translation>B2 (500 x 707 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>B3 (353 x 500 mm)</source>
+ <translation>B3 (353 x 500 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>B4 (250 x 353 mm)</source>
+ <translation>B4 (250 x 353 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>B5 (176 x 250 mm, 6.93 x 9.84 inches)</source>
+ <translation>B5 (176 x 250 mm, 6.93 x 9.84 tum)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>B6 (125 x 176 mm)</source>
+ <translation>B6 (125 x 176 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>B7 (88 x 125 mm)</source>
+ <translation>B7 (88 x 125 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>B8 (62 x 88 mm)</source>
+ <translation>B8 (62 x 88 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>B9 (44 x 62 mm)</source>
+ <translation>B9 (44 x 62 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>B10 (31 x 44 mm)</source>
+ <translation>B10 (31 x 44 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>C5E (163 x 229 mm)</source>
+ <translation>C5E (163 x 229 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>DLE (110 x 220 mm)</source>
+ <translation>DLE (110 x 220 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Executive (7.5 x 10 inches, 191 x 254 mm)</source>
+ <translation>Executive (7.5 x 10 tum, 191 x 254 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Folio (210 x 330 mm)</source>
+ <translation>Folio (210 x 330 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Ledger (432 x 279 mm)</source>
+ <translation>Ledger (432 x 279 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Legal (8.5 x 14 inches, 216 x 356 mm)</source>
+ <translation>Legal (8.5 x 14 tum, 216 x 356 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Letter (8.5 x 11 inches, 216 x 279 mm)</source>
+ <translation>Letter (8.5 x 11 tum, 216 x 279 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Tabloid (279 x 432 mm)</source>
+ <translation>Tabloid (279 x 432 mm)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>US Common #10 Envelope (105 x 241 mm)</source>
+ <translation>US Common #10 Envelope (105 x 241 mm)</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>Print current page</source>
+ <translation>Skriv ut aktuell sida</translation>
+ </message>
+ <message>
+ <location filename="../src/gui/dialogs/qprintdialog_win.cpp" line="+272"/>
+ <source>OK</source>
+ <translation>OK</translation>
+ </message>
+ <message>
+ <location filename="../src/gui/dialogs/qabstractprintdialog.cpp" line="+116"/>
+ <location line="+13"/>
+ <location filename="../src/gui/dialogs/qprintdialog_win.cpp" line="-2"/>
+ <source>Print</source>
+ <translation>Skriv ut</translation>
+ </message>
+ <message>
+ <location filename="../src/gui/dialogs/qprintdialog_unix.cpp" line="-392"/>
<source>Print To File ...</source>
<translation>Skriv ut till fil ...</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qprintdialog_qws.cpp" line="-1"/>
+ <source>Print range</source>
+ <translation>Skriv ut intervall</translation>
+ </message>
+ <message>
+ <location line="-2"/>
+ <source>Print all</source>
+ <translation>Skriv ut alla</translation>
+ </message>
+ <message>
+ <location filename="../src/gui/dialogs/qprintdialog_unix.cpp" line="+82"/>
<source>File %1 is not writable.
Please choose a different file name.</source>
<translation>Filen %1 är inte skrivbar.
Välj ett annat filnamn.</translation>
</message>
<message>
+ <location line="+4"/>
<source>%1 already exists.
Do you want to overwrite it?</source>
<translation>%1 finns redan.
Vill du skriva över den?</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qprintdialog_qws.cpp" line="-231"/>
+ <source>File exists</source>
+ <translation>Filen finns redan</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>&lt;qt&gt;Do you want to overwrite it?&lt;/qt&gt;</source>
+ <translation>&lt;qt&gt;Vill du skriva över den?&lt;/qt&gt;</translation>
+ </message>
+ <message>
+ <location line="+231"/>
+ <source>Print selection</source>
+ <translation>Utskriftsval</translation>
+ </message>
+ <message>
+ <location filename="../src/gui/dialogs/qprintdialog_unix.cpp" line="-8"/>
<source>%1 is a directory.
Please choose a different file name.</source>
<translation>%1 är en katalog.
Välj ett annat filnamn.</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qpagesetupdialog_unix.cpp" line="-232"/>
<source>A0</source>
<translation>A0</translation>
</message>
<message>
+ <location line="+1"/>
<source>A1</source>
<translation>A1</translation>
</message>
<message>
+ <location line="+1"/>
<source>A2</source>
<translation>A2</translation>
</message>
<message>
+ <location line="+1"/>
<source>A3</source>
<translation>A3</translation>
</message>
<message>
+ <location line="+1"/>
<source>A4</source>
<translation>A4</translation>
</message>
<message>
+ <location line="+1"/>
<source>A5</source>
<translation>A5</translation>
</message>
<message>
+ <location line="+1"/>
<source>A6</source>
<translation>A6</translation>
</message>
<message>
+ <location line="+1"/>
<source>A7</source>
<translation>A7</translation>
</message>
<message>
+ <location line="+1"/>
<source>A8</source>
<translation>A8</translation>
</message>
<message>
+ <location line="+1"/>
<source>A9</source>
<translation>A9</translation>
</message>
<message>
+ <location line="+1"/>
<source>B0</source>
<translation>B0</translation>
</message>
<message>
+ <location line="+1"/>
<source>B1</source>
<translation>B1</translation>
</message>
<message>
+ <location line="+1"/>
<source>B2</source>
<translation>B2</translation>
</message>
<message>
+ <location line="+1"/>
<source>B3</source>
<translation>B3</translation>
</message>
<message>
+ <location line="+1"/>
<source>B4</source>
<translation>B4</translation>
</message>
<message>
+ <location line="+1"/>
<source>B5</source>
<translation>B5</translation>
</message>
<message>
+ <location line="+1"/>
<source>B6</source>
<translation>B6</translation>
</message>
<message>
+ <location line="+1"/>
<source>B7</source>
<translation>B7</translation>
</message>
<message>
+ <location line="+1"/>
<source>B8</source>
<translation>B8</translation>
</message>
<message>
+ <location line="+1"/>
<source>B9</source>
<translation>B9</translation>
</message>
<message>
+ <location line="+1"/>
<source>B10</source>
<translation>B10</translation>
</message>
<message>
+ <location line="+1"/>
<source>C5E</source>
<translation>C5E</translation>
</message>
<message>
+ <location line="+1"/>
<source>DLE</source>
<translation>DLE</translation>
</message>
<message>
+ <location line="+1"/>
<source>Executive</source>
<translation>Executive</translation>
</message>
<message>
+ <location line="+1"/>
<source>Folio</source>
- <translation>Folio</translation>
+ <translation>Folie</translation>
</message>
<message>
+ <location line="+1"/>
<source>Ledger</source>
<translation>Ledger</translation>
</message>
<message>
+ <location line="+1"/>
<source>Legal</source>
<translation>Legal</translation>
</message>
<message>
+ <location line="+1"/>
<source>Letter</source>
- <translation>Letter</translation>
+ <translation>Brev</translation>
</message>
<message>
+ <location line="+1"/>
<source>Tabloid</source>
- <translation>Tabloid</translation>
+ <translation>Tablå</translation>
</message>
<message>
+ <location line="+1"/>
<source>US Common #10 Envelope</source>
<translation>US Common #10 Envelope</translation>
</message>
<message>
+ <location line="+1"/>
<source>Custom</source>
- <translation>Anpassad</translation>
+ <translation>Anpassat</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qprintdialog_unix.cpp" line="-530"/>
+ <location line="+68"/>
<source>&amp;Options &gt;&gt;</source>
<translation>A&amp;lternativ &gt;&gt;</translation>
</message>
<message>
+ <location line="-63"/>
<source>&amp;Print</source>
<translation>Skriv &amp;ut</translation>
</message>
<message>
+ <location line="+67"/>
<source>&amp;Options &lt;&lt;</source>
<translation>A&amp;lternativ &lt;&lt;</translation>
</message>
<message>
+ <location line="+260"/>
<source>Print to File (PDF)</source>
<translation>Skriv ut till fil (PDF)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Print to File (Postscript)</source>
<translation>Skriv ut till fil (Postscript)</translation>
</message>
<message>
+ <location line="+47"/>
<source>Local file</source>
<translation>Lokal fil</translation>
</message>
<message>
+ <location line="+1"/>
<source>Write %1 file</source>
<translation>Skriv %1-fil</translation>
</message>
+ <message>
+ <location filename="../src/gui/dialogs/qprintdialog_win.cpp" line="+1"/>
+ <source>The &apos;From&apos; value cannot be greater than the &apos;To&apos; value.</source>
+ <translation>Värdet för \&quot;From\&quot; får inte vara större än värdet för \&quot;To\&quot;.</translation>
+ </message>
</context>
<context>
<name>QPrintPreviewDialog</name>
<message>
+ <location filename="../src/gui/dialogs/qabstractpagesetupdialog.cpp" line="+68"/>
+ <location line="+12"/>
<source>Page Setup</source>
- <translation>Sidinställningar</translation>
+ <translation>Sidkonfiguration</translation>
</message>
<message>
+ <location filename="../src/gui/dialogs/qprintpreviewdialog.cpp" line="+249"/>
+ <source>%1%</source>
+ <translation>%1 %</translation>
+ </message>
+ <message>
+ <location line="+84"/>
<source>Print Preview</source>
- <translation>Förhandsgranska</translation>
+ <translation>Förhandsvisning</translation>
</message>
<message>
+ <location line="+30"/>
<source>Next page</source>
<translation>Nästa sida</translation>
</message>
<message>
+ <location line="+1"/>
<source>Previous page</source>
<translation>Föregående sida</translation>
</message>
<message>
+ <location line="+1"/>
<source>First page</source>
<translation>Första sidan</translation>
</message>
<message>
+ <location line="+1"/>
<source>Last page</source>
<translation>Sista sidan</translation>
</message>
<message>
+ <location line="+9"/>
<source>Fit width</source>
<translation>Anpassa efter bredd</translation>
</message>
<message>
+ <location line="+1"/>
<source>Fit page</source>
- <translation>Anpassa efter sida</translation>
+ <translation>Anpassa till sida</translation>
</message>
<message>
+ <location line="+11"/>
<source>Zoom in</source>
<translation>Zooma in</translation>
</message>
<message>
+ <location line="+1"/>
<source>Zoom out</source>
<translation>Zooma ut</translation>
</message>
<message>
+ <location line="+6"/>
<source>Portrait</source>
<translation>Stående</translation>
</message>
<message>
+ <location line="+1"/>
<source>Landscape</source>
<translation>Liggande</translation>
</message>
<message>
+ <location line="+10"/>
<source>Show single page</source>
<translation>Visa en sida</translation>
</message>
<message>
+ <location line="+1"/>
<source>Show facing pages</source>
- <translation>Visa motsatta sidor</translation>
+ <translation>Visa dubbelsidig layout</translation>
</message>
<message>
+ <location line="+1"/>
<source>Show overview of all pages</source>
- <translation>Visa översikt över alla sidor</translation>
+ <translation>Visa översikt för alla sidor</translation>
</message>
<message>
+ <location line="+15"/>
<source>Print</source>
<translation>Skriv ut</translation>
</message>
<message>
+ <location line="+1"/>
<source>Page setup</source>
- <translation>Sidinställningar</translation>
+ <translation>Sidkonfiguration</translation>
</message>
<message>
+ <location line="+6"/>
<source>Close</source>
<translation>Stäng</translation>
</message>
+ <message>
+ <location line="+148"/>
+ <source>Export to PDF</source>
+ <translation>Exportera till PDF</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Export to PostScript</source>
+ <translation>Exportera till Postscript</translation>
+ </message>
</context>
<context>
<name>QPrintPropertiesWidget</name>
<message>
+ <location filename="../src/gui/dialogs/qprintpropertieswidget.ui"/>
<source>Form</source>
<translation>Format</translation>
</message>
<message>
+ <location/>
<source>Page</source>
<translation>Sida</translation>
</message>
<message>
+ <location/>
<source>Advanced</source>
<translation>Avancerat</translation>
</message>
@@ -3003,124 +6206,221 @@ Välj ett annat filnamn.</translation>
<context>
<name>QPrintSettingsOutput</name>
<message>
+ <location filename="../src/gui/dialogs/qprintsettingsoutput.ui"/>
<source>Form</source>
<translation>Format</translation>
</message>
<message>
+ <location/>
<source>Copies</source>
<translation>Kopior</translation>
</message>
<message>
+ <location/>
<source>Print range</source>
- <translation>Skriv ut intervall</translation>
+ <translation>Utskriftsintervall</translation>
</message>
<message>
+ <location/>
<source>Print all</source>
<translation>Skriv ut alla</translation>
</message>
<message>
+ <location/>
<source>Pages from</source>
<translation>Sidor från</translation>
</message>
<message>
+ <location/>
<source>to</source>
<translation>till</translation>
</message>
<message>
+ <location/>
<source>Selection</source>
<translation>Val</translation>
</message>
<message>
+ <location/>
<source>Output Settings</source>
<translation>Utmatningsinställningar</translation>
</message>
<message>
+ <location/>
<source>Copies:</source>
<translation>Kopior:</translation>
</message>
<message>
+ <location/>
<source>Collate</source>
<translation>Sortera</translation>
</message>
<message>
+ <location/>
<source>Reverse</source>
<translation>Omvänt</translation>
</message>
<message>
+ <location/>
<source>Options</source>
<translation>Alternativ</translation>
</message>
<message>
+ <location/>
<source>Color Mode</source>
<translation>Färgläge</translation>
</message>
<message>
+ <location/>
<source>Color</source>
<translation>Färg</translation>
</message>
<message>
+ <location/>
<source>Grayscale</source>
<translation>Gråskala</translation>
</message>
<message>
+ <location/>
<source>Duplex Printing</source>
<translation>Dubbelsidig utskrift</translation>
</message>
<message>
+ <location/>
<source>None</source>
<translation>Ingen</translation>
</message>
<message>
+ <location/>
<source>Long side</source>
<translation>LÃ¥ngsida</translation>
</message>
<message>
+ <location/>
<source>Short side</source>
<translation>Kortsida</translation>
</message>
+ <message>
+ <location/>
+ <source>Current Page</source>
+ <translation>Aktuell sida</translation>
+ </message>
</context>
<context>
<name>QPrintWidget</name>
<message>
+ <location filename="../src/gui/dialogs/qprintwidget.ui"/>
<source>Form</source>
<translation>Format</translation>
</message>
<message>
+ <location/>
<source>Printer</source>
<translation>Skrivare</translation>
</message>
<message>
+ <location/>
<source>&amp;Name:</source>
<translation>&amp;Namn:</translation>
</message>
<message>
+ <location/>
<source>P&amp;roperties</source>
<translation>E&amp;genskaper</translation>
</message>
<message>
+ <location/>
<source>Location:</source>
<translation>Plats:</translation>
</message>
<message>
+ <location/>
<source>Preview</source>
- <translation>Förhandsgranska</translation>
+ <translation>Förhandsvisa</translation>
</message>
<message>
+ <location/>
<source>Type:</source>
<translation>Typ:</translation>
</message>
<message>
+ <location/>
<source>Output &amp;file:</source>
- <translation>Utmatnings&amp;fil:</translation>
+ <translation>Ut&amp;fil:</translation>
</message>
<message>
+ <location/>
<source>...</source>
<translation>...</translation>
</message>
</context>
<context>
+ <name>QProcess</name>
+ <message>
+ <location filename="../src/corelib/io/qprocess.cpp" line="+866"/>
+ <location line="+52"/>
+ <location filename="../src/corelib/io/qprocess_win.cpp" line="+578"/>
+ <location line="+50"/>
+ <source>Error reading from process</source>
+ <translation>Läsfel vid läsning från process</translation>
+ </message>
+ <message>
+ <location line="+47"/>
+ <location line="+870"/>
+ <location filename="../src/corelib/io/qprocess_win.cpp" line="+140"/>
+ <source>Error writing to process</source>
+ <translation>Skrivfel vid skrivning till process</translation>
+ </message>
+ <message>
+ <location line="-800"/>
+ <source>Process crashed</source>
+ <translation>Processen kraschade</translation>
+ </message>
+ <message>
+ <location line="+1002"/>
+ <source>No program defined</source>
+ <translation>Inget program definierat</translation>
+ </message>
+ <message>
+ <location filename="../src/corelib/io/qprocess_unix.cpp" line="+406"/>
+ <location filename="../src/corelib/io/qprocess_win.cpp" line="-631"/>
+ <source>Could not open input redirection for reading</source>
+ <translation>Kunde inte omdirigerad inmatning för läsning</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <location filename="../src/corelib/io/qprocess_win.cpp" line="+20"/>
+ <source>Could not open output redirection for writing</source>
+ <translation>Kunde inte omdirigerad utmatning för skrivning</translation>
+ </message>
+ <message>
+ <location line="+239"/>
+ <source>Resource error (fork failure): %1</source>
+ <translation>Resursfel (fork misslyckades): %1</translation>
+ </message>
+ <message>
+ <location line="+258"/>
+ <location line="+52"/>
+ <location line="+74"/>
+ <location line="+66"/>
+ <location filename="../src/corelib/io/qprocess_win.cpp" line="+411"/>
+ <location line="+50"/>
+ <location line="+75"/>
+ <location line="+42"/>
+ <location line="+54"/>
+ <source>Process operation timed out</source>
+ <translation>Processåtgärd överskred tidsgräns</translation>
+ </message>
+ <message>
+ <location filename="../src/corelib/io/qprocess_win.cpp" line="-381"/>
+ <source>Process failed to start: %1</source>
+ <translation>Processen misslyckades starta: %1</translation>
+ </message>
+</context>
+<context>
<name>QProgressDialog</name>
<message>
+ <location filename="../src/gui/dialogs/qprogressdialog.cpp" line="+203"/>
<source>Cancel</source>
<translation>Avbryt</translation>
</message>
@@ -3128,6 +6428,7 @@ Välj ett annat filnamn.</translation>
<context>
<name>QPushButton</name>
<message>
+ <location filename="../src/plugins/accessible/widgets/simplewidgets.cpp" line="-8"/>
<source>Open</source>
<translation>Öppna</translation>
</message>
@@ -3135,6 +6436,7 @@ Välj ett annat filnamn.</translation>
<context>
<name>QRadioButton</name>
<message>
+ <location line="+12"/>
<source>Check</source>
<translation>Kryssa</translation>
</message>
@@ -3142,68 +6444,101 @@ Välj ett annat filnamn.</translation>
<context>
<name>QRegExp</name>
<message>
+ <location filename="../src/corelib/tools/qregexp.cpp" line="+65"/>
<source>no error occurred</source>
<translation>inga fel inträffade</translation>
</message>
<message>
+ <location line="+1"/>
<source>disabled feature used</source>
<translation>inaktiverad funktion används</translation>
</message>
<message>
+ <location line="+1"/>
<source>bad char class syntax</source>
<translation>felaktig teckenklasssyntax</translation>
</message>
<message>
+ <location line="+1"/>
<source>bad lookahead syntax</source>
<translation>felaktig seframåtsyntax</translation>
</message>
<message>
+ <location line="+1"/>
<source>bad repetition syntax</source>
<translation>felaktig upprepningssyntax</translation>
</message>
<message>
+ <location line="+1"/>
<source>invalid octal value</source>
<translation>ogiltigt oktalt värde</translation>
</message>
<message>
+ <location line="+1"/>
<source>missing left delim</source>
<translation>saknar vänster avgränsare</translation>
</message>
<message>
+ <location line="+1"/>
<source>unexpected end</source>
<translation>oväntat slut</translation>
</message>
<message>
+ <location line="+1"/>
<source>met internal limit</source>
<translation>nådde intern gräns</translation>
</message>
+ <message>
+ <location line="+1"/>
+ <source>invalid interval</source>
+ <translation>ogiltigt intervall</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>invalid category</source>
+ <translation>ogiltig kategori</translation>
+ </message>
</context>
<context>
<name>QSQLite2Driver</name>
<message>
<source>Error to open database</source>
+ <translation type="obsolete">Fel vid öppning av databas</translation>
+ </message>
+ <message>
+ <location filename="../src/sql/drivers/sqlite2/qsql_sqlite2.cpp" line="+399"/>
+ <source>Error opening database</source>
<translation>Fel vid öppning av databas</translation>
</message>
<message>
+ <location line="+41"/>
<source>Unable to begin transaction</source>
<translation>Kunde inte påbörja transaktion</translation>
</message>
<message>
+ <location line="+17"/>
<source>Unable to commit transaction</source>
<translation>Kunde inte verkställa transaktion</translation>
</message>
<message>
- <source>Unable to rollback Transaction</source>
+ <location line="+17"/>
+ <source>Unable to rollback transaction</source>
<translation>Kunde inte rulla tillbaka transaktion</translation>
</message>
+ <message>
+ <source>Unable to rollback Transaction</source>
+ <translation type="obsolete">Kunde inte rulla tillbaka transaktion</translation>
+ </message>
</context>
<context>
<name>QSQLite2Result</name>
<message>
+ <location line="-326"/>
<source>Unable to fetch results</source>
<translation>Kunde inte hämta resultat</translation>
</message>
<message>
+ <location line="+150"/>
<source>Unable to execute statement</source>
<translation>Kunde inte köra frågesats</translation>
</message>
@@ -3211,22 +6546,27 @@ Välj ett annat filnamn.</translation>
<context>
<name>QSQLiteDriver</name>
<message>
+ <location filename="../src/sql/drivers/sqlite/qsql_sqlite.cpp" line="+539"/>
<source>Error opening database</source>
<translation>Fel vid öppning av databas</translation>
</message>
<message>
+ <location line="+11"/>
<source>Error closing database</source>
<translation>Fel vid stängning av databas</translation>
</message>
<message>
+ <location line="+20"/>
<source>Unable to begin transaction</source>
<translation>Kunde inte påbörja transaktion</translation>
</message>
<message>
+ <location line="+15"/>
<source>Unable to commit transaction</source>
<translation>Kunde inte verkställa transaktion</translation>
</message>
<message>
+ <location line="+15"/>
<source>Unable to rollback transaction</source>
<translation>Kunde inte rulla tillbaka transaktion</translation>
</message>
@@ -3234,93 +6574,457 @@ Välj ett annat filnamn.</translation>
<context>
<name>QSQLiteResult</name>
<message>
+ <location line="-396"/>
+ <location line="+63"/>
+ <location line="+8"/>
<source>Unable to fetch row</source>
<translation>Kunde inte hämta rad</translation>
</message>
<message>
+ <location line="+59"/>
<source>Unable to execute statement</source>
<translation>Kunde inte köra frågesats</translation>
</message>
<message>
+ <location line="+20"/>
<source>Unable to reset statement</source>
<translation>Kunde inte återställa frågesats</translation>
</message>
<message>
+ <location line="+45"/>
<source>Unable to bind parameters</source>
<translation>Kunde inte binda parametrar</translation>
</message>
<message>
+ <location line="+7"/>
<source>Parameter count mismatch</source>
<translation>Parameterantal stämmer inte</translation>
</message>
<message>
+ <location line="-201"/>
<source>No query</source>
<translation>Ingen frågesats</translation>
</message>
</context>
<context>
+ <name>QScriptBreakpointsModel</name>
+ <message>
+ <location filename="../src/scripttools/debugging/qscriptbreakpointsmodel.cpp" line="+455"/>
+ <source>ID</source>
+ <translation>Id</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Location</source>
+ <translation>Plats</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Condition</source>
+ <translation>Villkor</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Ignore-count</source>
+ <translation>Ignorerat antal</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Single-shot</source>
+ <translation>Engångs</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Hit-count</source>
+ <translation>Träffantal</translation>
+ </message>
+</context>
+<context>
+ <name>QScriptBreakpointsWidget</name>
+ <message>
+ <location filename="../src/scripttools/debugging/qscriptbreakpointswidget.cpp" line="+298"/>
+ <source>New</source>
+ <translation>Ny</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Delete</source>
+ <translation>Ta bort</translation>
+ </message>
+</context>
+<context>
+ <name>QScriptDebugger</name>
+ <message>
+ <location filename="../src/scripttools/debugging/qscriptdebugger.cpp" line="+885"/>
+ <location line="+1013"/>
+ <source>Go to Line</source>
+ <translation>GÃ¥ till rad</translation>
+ </message>
+ <message>
+ <location line="-1012"/>
+ <source>Line:</source>
+ <translation>Rad:</translation>
+ </message>
+ <message>
+ <location line="+791"/>
+ <source>Interrupt</source>
+ <translation>Avbrott</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Shift+F5</source>
+ <translation>Skift+F5</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Continue</source>
+ <translation>Fortsätt</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>F5</source>
+ <translation>F5</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Step Into</source>
+ <translation>Stega in i</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>F11</source>
+ <translation>F11</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Step Over</source>
+ <translation>Stega förbi</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>F10</source>
+ <translation>F10</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Step Out</source>
+ <translation>Stega ut ur</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Shift+F11</source>
+ <translation>Skift+F11</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Run to Cursor</source>
+ <translation>Kör till markören</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Ctrl+F10</source>
+ <translation>Ctrl+F10</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Run to New Script</source>
+ <translation>Kör till nytt skript</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Toggle Breakpoint</source>
+ <translation>Växla brytpunkt</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>F9</source>
+ <translation>F9</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Clear Debug Output</source>
+ <translation>Rensa felsökningsutmatning</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Clear Error Log</source>
+ <translation>Rensa fellogg</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Clear Console</source>
+ <translation>Rensa konsol</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>&amp;Find in Script...</source>
+ <translation>&amp;Sök i skript...</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Ctrl+F</source>
+ <translation>Ctrl+F</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Find &amp;Next</source>
+ <translation>Sök &amp;nästa</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>F3</source>
+ <translation>F3</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Find &amp;Previous</source>
+ <translation>Sök &amp;föregående</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Shift+F3</source>
+ <translation>Skift+F3</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Ctrl+G</source>
+ <translation>Ctrl+G</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Debug</source>
+ <translation>Felsök</translation>
+ </message>
+</context>
+<context>
+ <name>QScriptDebuggerCodeFinderWidget</name>
+ <message>
+ <location filename="../src/scripttools/debugging/qscriptdebuggercodefinderwidget.cpp" line="+141"/>
+ <source>Close</source>
+ <translation>Stäng</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Previous</source>
+ <translation>Föregående</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Next</source>
+ <translation>Nästa</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Case Sensitive</source>
+ <translation>Skiftlägeskänslig</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Whole words</source>
+ <translation>Hela ord</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>&lt;img src=&quot;:/qt/scripttools/debugging/images/wrap.png&quot;&gt;&amp;nbsp;Search wrapped</source>
+ <translation>&lt;img src=&quot;:/qt/scripttools/debugging/images/wrap.png&quot;&gt;&amp;nbsp;Sökning omstartad</translation>
+ </message>
+</context>
+<context>
+ <name>QScriptDebuggerLocalsModel</name>
+ <message>
+ <location filename="../src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp" line="+897"/>
+ <source>Name</source>
+ <translation>Namn</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Value</source>
+ <translation>Värde</translation>
+ </message>
+</context>
+<context>
+ <name>QScriptDebuggerStackModel</name>
+ <message>
+ <location filename="../src/scripttools/debugging/qscriptdebuggerstackmodel.cpp" line="+161"/>
+ <source>Level</source>
+ <translation>Nivå</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Name</source>
+ <translation>Namn</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Location</source>
+ <translation>Plats</translation>
+ </message>
+</context>
+<context>
+ <name>QScriptEdit</name>
+ <message>
+ <location filename="../src/scripttools/debugging/qscriptedit.cpp" line="+411"/>
+ <source>Toggle Breakpoint</source>
+ <translation>Växla brytpunkt</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Disable Breakpoint</source>
+ <translation>Inaktivera brytpunkt</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Enable Breakpoint</source>
+ <translation>Aktivera brytpunkt</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Breakpoint Condition:</source>
+ <translation>Brytpunktsvillkor:</translation>
+ </message>
+</context>
+<context>
+ <name>QScriptEngineDebugger</name>
+ <message>
+ <location filename="../src/scripttools/debugging/qscriptenginedebugger.cpp" line="+523"/>
+ <source>Loaded Scripts</source>
+ <translation>Laddade skript</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Breakpoints</source>
+ <translation>Brytpunkter</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Stack</source>
+ <translation>Stack</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Locals</source>
+ <translation>Lokala</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Console</source>
+ <translation>Konsol</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Debug Output</source>
+ <translation>Felsökningsutmatning</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Error Log</source>
+ <translation>Fellogg</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>Search</source>
+ <translation>Sök</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>View</source>
+ <translation>Visa</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Qt Script Debugger</source>
+ <translation>Qt-skriptfelsökare</translation>
+ </message>
+</context>
+<context>
+ <name>QScriptNewBreakpointWidget</name>
+ <message>
+ <location filename="../src/scripttools/debugging/qscriptbreakpointswidget.cpp" line="-223"/>
+ <source>Close</source>
+ <translation>Stäng</translation>
+ </message>
+</context>
+<context>
<name>QScrollBar</name>
<message>
+ <location filename="../src/gui/widgets/qscrollbar.cpp" line="+453"/>
<source>Scroll here</source>
<translation>Rulla här</translation>
</message>
<message>
+ <location line="+2"/>
<source>Left edge</source>
<translation>Vänsterkant</translation>
</message>
<message>
+ <location line="+0"/>
<source>Top</source>
<translation>Överkant</translation>
</message>
<message>
+ <location line="+1"/>
<source>Right edge</source>
<translation>Högerkant</translation>
</message>
<message>
+ <location line="+0"/>
<source>Bottom</source>
<translation>Nederkant</translation>
</message>
<message>
+ <location line="+2"/>
<source>Page left</source>
<translation>Sida vänster</translation>
</message>
<message>
+ <location line="+0"/>
+ <location filename="../src/plugins/accessible/widgets/rangecontrols.cpp" line="+143"/>
<source>Page up</source>
<translation>Sida uppåt</translation>
</message>
<message>
+ <location line="+1"/>
<source>Page right</source>
<translation>Sida höger</translation>
</message>
<message>
+ <location line="+0"/>
+ <location filename="../src/plugins/accessible/widgets/rangecontrols.cpp" line="+4"/>
<source>Page down</source>
<translation>Sida nedåt</translation>
</message>
<message>
+ <location line="+2"/>
<source>Scroll left</source>
<translation>Rulla vänster</translation>
</message>
<message>
+ <location line="+0"/>
<source>Scroll up</source>
<translation>Rulla uppåt</translation>
</message>
<message>
+ <location line="+1"/>
<source>Scroll right</source>
<translation>Rulla höger</translation>
</message>
<message>
+ <location line="+0"/>
<source>Scroll down</source>
<translation>Rulla nedåt</translation>
</message>
<message>
+ <location filename="../src/plugins/accessible/widgets/rangecontrols.cpp" line="-6"/>
<source>Line up</source>
<translation>Rada upp</translation>
</message>
<message>
+ <location line="+4"/>
<source>Position</source>
<translation>Position</translation>
</message>
<message>
+ <location line="+4"/>
<source>Line down</source>
<translation>Rad nedåt</translation>
</message>
@@ -3328,433 +7032,1223 @@ Välj ett annat filnamn.</translation>
<context>
<name>QSharedMemory</name>
<message>
+ <location filename="../src/corelib/kernel/qsharedmemory.cpp" line="+223"/>
<source>%1: unable to set key on lock</source>
- <translation type="unfinished"></translation>
+ <translation>%1: kunde inte ställa in nyckel på lås</translation>
</message>
<message>
+ <location line="+81"/>
<source>%1: create size is less then 0</source>
- <translation type="unfinished"></translation>
+ <translation>%1: skapad storlek är mindre än 0</translation>
</message>
<message>
+ <location line="+164"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_p.h" line="+155"/>
<source>%1: unable to lock</source>
<translation>%1: kunde inte låsa</translation>
</message>
<message>
+ <location line="+22"/>
<source>%1: unable to unlock</source>
<translation>%1: kunde inte låsa upp</translation>
</message>
<message>
+ <location filename="../src/corelib/kernel/qsharedmemory_symbian.cpp" line="+83"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_unix.cpp" line="+81"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_win.cpp" line="+87"/>
<source>%1: permission denied</source>
- <translation>%1: åtkomst nekas</translation>
+ <translation>%1: behörighet nekas</translation>
</message>
<message>
+ <location line="-16"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_unix.cpp" line="+4"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_win.cpp" line="-22"/>
<source>%1: already exists</source>
<translation>%1: finns redan</translation>
</message>
<message>
+ <location line="+4"/>
<source>%1: doesn&apos;t exists</source>
<translation>%1: finns inte</translation>
</message>
<message>
+ <location line="+8"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_unix.cpp" line="+10"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_win.cpp" line="+18"/>
<source>%1: out of resources</source>
<translation>%1: slut på resurser</translation>
</message>
<message>
+ <location line="+7"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_unix.cpp" line="+4"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_win.cpp" line="+7"/>
<source>%1: unknown error %2</source>
<translation>%1: okänt fel %2</translation>
</message>
<message>
+ <location filename="../src/corelib/kernel/qsharedmemory_unix.cpp" line="+21"/>
<source>%1: key is empty</source>
<translation>%1: nyckeln är tom</translation>
</message>
<message>
<source>%1: unix key file doesn&apos;t exists</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">%1: unix-nyckelfil finns inte</translation>
</message>
<message>
+ <location line="+15"/>
<source>%1: ftok failed</source>
<translation>%1: ftok misslyckades</translation>
</message>
<message>
+ <location filename="../src/corelib/kernel/qsharedmemory_symbian.cpp" line="+56"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_unix.cpp" line="+51"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_win.cpp" line="+15"/>
<source>%1: unable to make key</source>
- <translation type="unfinished"></translation>
+ <translation>%1: kunde inte skapa nyckel</translation>
</message>
<message>
+ <location filename="../src/corelib/kernel/qsharedmemory_unix.cpp" line="-97"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_win.cpp" line="-31"/>
+ <source>%1: doesn&apos;t exist</source>
+ <translation>%1: finns inte</translation>
+ </message>
+ <message>
+ <location line="+39"/>
+ <source>%1: UNIX key file doesn&apos;t exist</source>
+ <translation>%1: UNIX nyckelfil finns inte</translation>
+ </message>
+ <message>
+ <location line="+78"/>
<source>%1: system-imposed size restrictions</source>
- <translation type="unfinished"></translation>
+ <translation>%1: systeminställda storleksbegränsningar</translation>
</message>
<message>
+ <location line="+50"/>
<source>%1: not attached</source>
- <translation>%1: inte ansluten</translation>
+ <translation>%1: inte bifogad</translation>
+ </message>
+ <message>
+ <location filename="../src/corelib/kernel/qsharedmemory_symbian.cpp" line="-67"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_win.cpp" line="+4"/>
+ <source>%1: invalid size</source>
+ <translation>%1: ogiltig storlek</translation>
+ </message>
+ <message>
+ <location line="+40"/>
+ <location filename="../src/corelib/kernel/qsharedmemory_win.cpp" line="+63"/>
+ <source>%1: key error</source>
+ <translation>%1: nyckelfel</translation>
+ </message>
+ <message>
+ <location filename="../src/corelib/kernel/qsharedmemory_win.cpp" line="+32"/>
+ <source>%1: size query failed</source>
+ <translation>%1: storleksbegäran misslyckades</translation>
</message>
</context>
<context>
<name>QShortcut</name>
<message>
+ <location filename="../src/gui/kernel/qkeysequence.cpp" line="+396"/>
<source>Space</source>
+ <extracomment>This and all following &quot;incomprehensible&quot; strings in QShortcut context are key names. Please use the localized names appearing on actual keyboards or whatever is commonly used.</extracomment>
<translation>Mellanslag</translation>
</message>
<message>
+ <location line="+1"/>
<source>Esc</source>
<translation>Esc</translation>
</message>
<message>
+ <location line="+1"/>
<source>Tab</source>
<translation>Tab</translation>
</message>
<message>
+ <location line="+1"/>
<source>Backtab</source>
<translation>Backtab</translation>
</message>
<message>
+ <location line="+1"/>
<source>Backspace</source>
<translation>Backsteg</translation>
</message>
<message>
+ <location line="+1"/>
<source>Return</source>
<translation>Return</translation>
</message>
<message>
+ <location line="+1"/>
<source>Enter</source>
<translation>Enter</translation>
</message>
<message>
+ <location line="+1"/>
<source>Ins</source>
<translation>Ins</translation>
</message>
<message>
+ <location line="+1"/>
<source>Del</source>
<translation>Del</translation>
</message>
<message>
+ <location line="+1"/>
<source>Pause</source>
<translation>Pause</translation>
</message>
<message>
+ <location line="+1"/>
<source>Print</source>
<translation>Print</translation>
</message>
<message>
+ <location line="+1"/>
<source>SysReq</source>
<translation>SysReq</translation>
</message>
<message>
+ <location line="+1"/>
<source>Home</source>
<translation>Home</translation>
</message>
<message>
+ <location line="+1"/>
<source>End</source>
<translation>End</translation>
</message>
<message>
+ <location line="+1"/>
<source>Left</source>
<translation>Vänster</translation>
</message>
<message>
+ <location line="+1"/>
<source>Up</source>
<translation>Upp</translation>
</message>
<message>
+ <location line="+1"/>
<source>Right</source>
<translation>Höger</translation>
</message>
<message>
+ <location line="+1"/>
<source>Down</source>
<translation>Ned</translation>
</message>
<message>
+ <location line="+1"/>
<source>PgUp</source>
<translation>PgUp</translation>
</message>
<message>
+ <location line="+1"/>
<source>PgDown</source>
<translation>PgDown</translation>
</message>
<message>
+ <location line="+1"/>
<source>CapsLock</source>
<translation>CapsLock</translation>
</message>
<message>
+ <location line="+1"/>
<source>NumLock</source>
<translation>NumLock</translation>
</message>
<message>
+ <location line="+1"/>
<source>ScrollLock</source>
<translation>ScrollLock</translation>
</message>
<message>
+ <location line="+1"/>
<source>Menu</source>
<translation>Meny</translation>
</message>
<message>
+ <location line="+1"/>
<source>Help</source>
<translation>Hjälp</translation>
</message>
<message>
+ <location line="+5"/>
<source>Back</source>
<translation>Bakåt</translation>
</message>
<message>
+ <location line="+1"/>
<source>Forward</source>
<translation>Framåt</translation>
</message>
<message>
+ <location line="+1"/>
<source>Stop</source>
<translation>Stoppa</translation>
</message>
<message>
+ <location line="+1"/>
<source>Refresh</source>
<translation>Uppdatera</translation>
</message>
<message>
+ <location line="+1"/>
<source>Volume Down</source>
<translation>Sänk volym</translation>
</message>
<message>
+ <location line="+1"/>
<source>Volume Mute</source>
<translation>Volym tyst</translation>
</message>
<message>
+ <location line="+1"/>
<source>Volume Up</source>
<translation>Höj volym</translation>
</message>
<message>
+ <location line="+1"/>
<source>Bass Boost</source>
<translation>Förstärk bas</translation>
</message>
<message>
+ <location line="+1"/>
<source>Bass Up</source>
<translation>Höj bas</translation>
</message>
<message>
+ <location line="+1"/>
<source>Bass Down</source>
<translation>Sänk bas</translation>
</message>
<message>
+ <location line="+1"/>
<source>Treble Up</source>
<translation>Höj diskant</translation>
</message>
<message>
+ <location line="+1"/>
<source>Treble Down</source>
<translation>Sänk diskant</translation>
</message>
<message>
+ <location line="+1"/>
<source>Media Play</source>
<translation>Media spela upp</translation>
</message>
<message>
+ <location line="+1"/>
<source>Media Stop</source>
<translation>Media stopp</translation>
</message>
<message>
+ <location line="+1"/>
<source>Media Previous</source>
<translation>Media föregående</translation>
</message>
<message>
+ <location line="+1"/>
<source>Media Next</source>
<translation>Media nästa</translation>
</message>
<message>
+ <location line="+1"/>
<source>Media Record</source>
<translation>Media spela in</translation>
</message>
<message>
+ <location line="+2"/>
+ <source>Media Pause</source>
+ <extracomment>Media player pause button</extracomment>
+ <translation>Media paus</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Toggle Media Play/Pause</source>
+ <extracomment>Media player button to toggle between playing and paused</extracomment>
+ <translation>Växla media mellan spela och paus</translation>
+ </message>
+ <message>
+ <location line="+2"/>
<source>Favorites</source>
<translation>Favoriter</translation>
</message>
<message>
+ <location line="+1"/>
<source>Search</source>
<translation>Sök</translation>
</message>
<message>
+ <location line="+1"/>
<source>Standby</source>
<translation>Avvakta</translation>
</message>
<message>
+ <location line="+1"/>
<source>Open URL</source>
<translation>Öppna url</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch Mail</source>
<translation>Starta e-post</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch Media</source>
<translation>Starta media</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (0)</source>
<translation>Starta (0)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (1)</source>
<translation>Starta (1)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (2)</source>
<translation>Starta (2)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (3)</source>
<translation>Starta (3)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (4)</source>
<translation>Starta (4)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (5)</source>
<translation>Starta (5)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (6)</source>
<translation>Starta (6)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (7)</source>
<translation>Starta (7)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (8)</source>
<translation>Starta (8)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (9)</source>
<translation>Starta (9)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (A)</source>
<translation>Starta (A)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (B)</source>
<translation>Starta (B)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (C)</source>
<translation>Starta (C)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (D)</source>
<translation>Starta (D)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (E)</source>
<translation>Starta (E)</translation>
</message>
<message>
+ <location line="+1"/>
<source>Launch (F)</source>
<translation>Starta (F)</translation>
</message>
<message>
+ <location line="+1"/>
+ <source>Monitor Brightness Up</source>
+ <translation>Öka bildskärmens ljusstyrka</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Monitor Brightness Down</source>
+ <translation>Minska bildskärmens ljusstyrka</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Keyboard Light On/Off</source>
+ <translation>Tangentbordsljus på/av</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Keyboard Brightness Up</source>
+ <translation>Öka tangentbordets ljusstyrka</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Keyboard Brightness Down</source>
+ <translation>Minska tangentbordets ljusstyrka</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Power Off</source>
+ <translation>Stäng av</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Wake Up</source>
+ <translation>Väck</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Eject</source>
+ <translation>Mata ut</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Screensaver</source>
+ <translation>Skärmsläckare</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>WWW</source>
+ <translation>WWW</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Sleep</source>
+ <translation>Sov</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>LightBulb</source>
+ <translation>Glödlampa</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Shop</source>
+ <translation>Handla</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>History</source>
+ <translation>Historik</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Add Favorite</source>
+ <translation>Lägg till favorit</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hot Links</source>
+ <translation>Aktuella länkar</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Adjust Brightness</source>
+ <translation>Justera ljusstyrka</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Finance</source>
+ <translation>Ekonomi</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Community</source>
+ <translation>Gemenskap</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Audio Rewind</source>
+ <translation>Spola tillbaka ljud</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Back Forward</source>
+ <translation>Bakåt framåt</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Application Left</source>
+ <translation>Program vänster</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Application Right</source>
+ <translation>Program höger</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Book</source>
+ <translation>Bok</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>CD</source>
+ <translation>Cd</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Calculator</source>
+ <translation>Miniräknare</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Clear</source>
+ <translation>Töm</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Clear Grab</source>
+ <translation>Släpp fokus</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Close</source>
+ <translation>Stäng</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy</source>
+ <translation>Kopiera</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Cut</source>
+ <translation>Klipp ut</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Display</source>
+ <translation>Skärm</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>DOS</source>
+ <translation>DOS</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Documents</source>
+ <translation>Dokument</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Spreadsheet</source>
+ <translation>Kalkylblad</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Browser</source>
+ <translation>Webbläsare</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Game</source>
+ <translation>Spel</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Go</source>
+ <translation>GÃ¥</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>iTouch</source>
+ <translation>iTouch</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Logoff</source>
+ <translation>Logga ut</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Market</source>
+ <translation>Marknad</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Meeting</source>
+ <translation>Möte</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Keyboard Menu</source>
+ <translation>Tangentbordsmeny</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Menu PB</source>
+ <translation>Menyknapp</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>My Sites</source>
+ <translation>Mina platser</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>News</source>
+ <translation>Nyheter</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Home Office</source>
+ <translation>Hemmakontor</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Option</source>
+ <translation>Alternativ</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Paste</source>
+ <translation>Klistra in</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Phone</source>
+ <translation>Telefon</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Reply</source>
+ <translation>Svara</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Reload</source>
+ <translation>Läs om</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Rotate Windows</source>
+ <translation>Rotera fönster</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Rotation PB</source>
+ <translation>Rotationsknapp</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Rotation KB</source>
+ <translation>Rotationstangent</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Save</source>
+ <translation>Spara</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Send</source>
+ <translation>Skicka</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Spellchecker</source>
+ <translation>Stavningskontroll</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Split Screen</source>
+ <translation>Dela skärm</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Support</source>
+ <translation>Support</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Task Panel</source>
+ <translation>Aktivitetsruta</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Terminal</source>
+ <translation>Terminal</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Tools</source>
+ <translation>Verktyg</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Travel</source>
+ <translation>Resor</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Video</source>
+ <translation>Video</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Word Processor</source>
+ <translation>Ordbehandlare</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>XFer</source>
+ <translation>Överför</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Zoom In</source>
+ <translation>Zooma in</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Zoom Out</source>
+ <translation>Zooma ut</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Away</source>
+ <translation>Frånvaro</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Messenger</source>
+ <translation>Meddelanden</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>WebCam</source>
+ <translation>Webbkamera</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Mail Forward</source>
+ <translation>Vidarebefordra brev</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Pictures</source>
+ <translation>Bilder</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Music</source>
+ <translation>Musik</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Battery</source>
+ <translation>Batteri</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Bluetooth</source>
+ <translation>Blåtand</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Wireless</source>
+ <translation>Trådlös</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Ultra Wide Band</source>
+ <translation>Ultrabredband</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Audio Forward</source>
+ <translation>Spola fram ljud</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Audio Repeat</source>
+ <translation>Upprepa ljud</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Audio Random Play</source>
+ <translation>Spela ljud slumpmässigt</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Subtitle</source>
+ <translation>Textning</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Audio Cycle Track</source>
+ <translation>Upprepa ljudspår</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Time</source>
+ <translation>Tid</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>View</source>
+ <translation>Visa</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Top Menu</source>
+ <translation>Menyrad</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Suspend</source>
+ <translation>Viloläge</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hibernate</source>
+ <translation>Dvala</translation>
+ </message>
+ <message>
+ <location line="+4"/>
<source>Print Screen</source>
<translation>Print Screen</translation>
</message>
<message>
+ <location line="+1"/>
<source>Page Up</source>
<translation>Page Up</translation>
</message>
<message>
+ <location line="+1"/>
<source>Page Down</source>
<translation>Page Down</translation>
</message>
<message>
+ <location line="+1"/>
<source>Caps Lock</source>
<translation>Caps Lock</translation>
</message>
<message>
+ <location line="+1"/>
<source>Num Lock</source>
<translation>Num Lock</translation>
</message>
<message>
+ <location line="+1"/>
<source>Number Lock</source>
<translation>Number Lock</translation>
</message>
<message>
+ <location line="+1"/>
<source>Scroll Lock</source>
<translation>Scroll Lock</translation>
</message>
<message>
+ <location line="+1"/>
<source>Insert</source>
<translation>Insert</translation>
</message>
<message>
+ <location line="+1"/>
<source>Delete</source>
<translation>Delete</translation>
</message>
<message>
+ <location line="+1"/>
<source>Escape</source>
<translation>Escape</translation>
</message>
<message>
+ <location line="+1"/>
<source>System Request</source>
<translation>System Request</translation>
</message>
<message>
+ <location line="-18"/>
+ <location line="+22"/>
<source>Select</source>
<translation>Välj</translation>
</message>
<message>
+ <location line="+1"/>
<source>Yes</source>
<translation>Ja</translation>
</message>
<message>
+ <location line="+1"/>
<source>No</source>
<translation>Nej</translation>
</message>
<message>
+ <location line="+4"/>
<source>Context1</source>
<translation>Sammanhang1</translation>
</message>
<message>
+ <location line="+1"/>
<source>Context2</source>
<translation>Sammanhang2</translation>
</message>
<message>
+ <location line="+1"/>
<source>Context3</source>
<translation>Sammanhang3</translation>
</message>
<message>
+ <location line="+1"/>
<source>Context4</source>
<translation>Sammanhang4</translation>
</message>
<message>
+ <location line="+2"/>
<source>Call</source>
+ <extracomment>Button to start a call (note: a separate button is used to end the call)</extracomment>
<translation>Ring upp</translation>
</message>
<message>
+ <location line="+2"/>
<source>Hangup</source>
+ <extracomment>Button to end a call (note: a separate button is used to start the call)</extracomment>
<translation>Lägg på</translation>
</message>
<message>
+ <location line="+2"/>
+ <source>Toggle Call/Hangup</source>
+ <extracomment>Button that will hang up if we&apos;re in call, or make a call if we&apos;re not.</extracomment>
+ <translation>Ring upp eller lägg på</translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Flip</source>
<translation>Vänd</translation>
</message>
<message>
+ <location line="+2"/>
+ <source>Voice Dial</source>
+ <extracomment>Button to trigger voice dialing</extracomment>
+ <translation>Röstuppringning</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Last Number Redial</source>
+ <extracomment>Button to redial the last number called</extracomment>
+ <translation>Ring upp senaste nummer igen</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Camera Shutter</source>
+ <extracomment>Button to trigger the camera shutter (take a picture)</extracomment>
+ <translation>Kameraslutare</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Camera Focus</source>
+ <extracomment>Button to focus the camera</extracomment>
+ <translation>Kamerafokusering</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Kanji</source>
+ <translation>Kanji</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Muhenkan</source>
+ <translation>Muhenkan</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Henkan</source>
+ <translation>Henkan</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Romaji</source>
+ <translation>Romaji</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hiragana</source>
+ <translation>Hiragana</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Katakana</source>
+ <translation>Katakana</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hiragana Katakana</source>
+ <translation>Hiragana Katakana</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Zenkaku</source>
+ <translation>Zenkaku</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hankaku</source>
+ <translation>Hankaku</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Zenkaku Hankaku</source>
+ <translation>Zenkaku Hankaku</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Touroku</source>
+ <translation>Touroku</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Massyo</source>
+ <translation>Massyo</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Kana Lock</source>
+ <translation>Kana lås</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Kana Shift</source>
+ <translation>Kana skift</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Eisu Shift</source>
+ <translation>Eisu skift</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Eisu toggle</source>
+ <translation>Eisu växling</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Code input</source>
+ <translation>Kodinmatning</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Multiple Candidate</source>
+ <translation>Flera kandidater</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Previous Candidate</source>
+ <translation>Föregående kandidat</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Hangul</source>
+ <translation>Hangul</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hangul Start</source>
+ <translation>Hangul start</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hangul End</source>
+ <translation>Hangul slut</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hangul Hanja</source>
+ <translation>Hangul Hanja</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hangul Jamo</source>
+ <translation>Hangul Jamo</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hangul Romaja</source>
+ <translation>Hangul Romaja</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hangul Jeonja</source>
+ <translation>Hangul Jeonja</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hangul Banja</source>
+ <translation>Hangul Banja</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hangul PreHanja</source>
+ <translation>Hangul pre-Hanja</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hangul PostHanja</source>
+ <translation>Hangul post-Hanja</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Hangul Special</source>
+ <translation>Hangul special</translation>
+ </message>
+ <message>
+ <location line="+602"/>
+ <location line="+135"/>
<source>Ctrl</source>
<translation>Ctrl</translation>
</message>
<message>
+ <location line="-134"/>
+ <location line="+138"/>
<source>Shift</source>
<translation>Shift</translation>
</message>
<message>
+ <location line="-137"/>
+ <location line="+135"/>
<source>Alt</source>
<translation>Alt</translation>
</message>
<message>
+ <location line="-134"/>
+ <location line="+130"/>
<source>Meta</source>
<translation>Meta</translation>
</message>
<message>
+ <location line="-40"/>
<source>+</source>
<translation>+</translation>
</message>
<message>
+ <location line="+61"/>
<source>F%1</source>
<translation>F%1</translation>
</message>
<message>
+ <location line="-946"/>
<source>Home Page</source>
<translation>Hemsida</translation>
</message>
@@ -3762,22 +8256,27 @@ Välj ett annat filnamn.</translation>
<context>
<name>QSlider</name>
<message>
+ <location filename="../src/plugins/accessible/widgets/rangecontrols.cpp" line="+151"/>
<source>Page left</source>
<translation>Sida vänster</translation>
</message>
<message>
+ <location line="+0"/>
<source>Page up</source>
<translation>Sida uppåt</translation>
</message>
<message>
+ <location line="+2"/>
<source>Position</source>
<translation>Position</translation>
</message>
<message>
+ <location line="+3"/>
<source>Page right</source>
<translation>Sida höger</translation>
</message>
<message>
+ <location line="+0"/>
<source>Page down</source>
<translation>Sida nedåt</translation>
</message>
@@ -3786,20 +8285,121 @@ Välj ett annat filnamn.</translation>
<name>QSocks5SocketEngine</name>
<message>
<source>Socks5 timeout error connecting to socks server</source>
- <translation>Tidsgräns för Socks5 överstigen vid anslutningen till socks-server</translation>
+ <translation type="obsolete">Tidsgräns för Socks5 överstigen vid anslutningen till socks-server</translation>
+ </message>
+ <message>
+ <location filename="../src/network/socket/qsocks5socketengine.cpp" line="-67"/>
+ <source>Connection to proxy refused</source>
+ <translation>Anslutning till proxy vägrades</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Connection to proxy closed prematurely</source>
+ <translation>Anslutning till proxy stängdes i förtid</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Proxy host not found</source>
+ <translation>Proxy-värddator hittades inte</translation>
</message>
<message>
+ <location line="+5"/>
+ <source>Connection to proxy timed out</source>
+ <translation>Anslutningen till proxy överskred tidsgräns</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Proxy authentication failed</source>
+ <translation>Behörighetskontroll med proxy misslyckades</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Proxy authentication failed: %1</source>
+ <translation>Behörighetskontroll med proxy misslyckades: %1</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>SOCKS version 5 protocol error</source>
+ <translation>SOCKS version 5 protokollfel</translation>
+ </message>
+ <message>
+ <location line="+19"/>
+ <source>General SOCKSv5 server failure</source>
+ <translation>Allmänt SOCKS v5 serverfel</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Connection not allowed by SOCKSv5 server</source>
+ <translation>Anslutning inte tillåten av SOCKS v5 server</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>TTL expired</source>
+ <translation>TTL utgången</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>SOCKSv5 command not supported</source>
+ <translation>SOCKS v5-kommando stöds inte</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Address type not supported</source>
+ <translation>Adresstypen stöds inte</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Unknown SOCKSv5 proxy error code 0x%1</source>
+ <translation>Okänd SOCKS v5 proxyfelkod 0x%1</translation>
+ </message>
+ <message>
+ <location line="+689"/>
<source>Network operation timed out</source>
<translation>Tidsgräns för nätverksåtgärd överstegs</translation>
</message>
</context>
<context>
+ <name>QSoftKeyManager</name>
+ <message>
+ <location filename="../src/gui/kernel/qsoftkeymanager.cpp" line="+63"/>
+ <source>Ok</source>
+ <translation>Ok</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select</source>
+ <translation>Välj</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Done</source>
+ <translation>Klar</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Options</source>
+ <translation>Alternativ</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Cancel</source>
+ <translation>Avbryt</translation>
+ </message>
+ <message>
+ <location filename="../src/gui/kernel/qsoftkeymanager_s60.cpp" line="+321"/>
+ <source>Exit</source>
+ <translation>Avsluta</translation>
+ </message>
+</context>
+<context>
<name>QSpinBox</name>
<message>
+ <location filename="../src/plugins/accessible/widgets/rangecontrols.cpp" line="-574"/>
<source>More</source>
<translation>Mer</translation>
</message>
<message>
+ <location line="+2"/>
<source>Less</source>
<translation>Mindre</translation>
</message>
@@ -3807,42 +8407,56 @@ Välj ett annat filnamn.</translation>
<context>
<name>QSql</name>
<message>
+ <location filename="../src/qt3support/sql/q3sqlmanager_p.cpp" line="+890"/>
<source>Delete</source>
<translation>Ta bort</translation>
</message>
<message>
+ <location line="+1"/>
<source>Delete this record?</source>
<translation>Ta bort denna post?</translation>
</message>
<message>
+ <location line="+1"/>
+ <location line="+16"/>
+ <location line="+36"/>
<source>Yes</source>
<translation>Ja</translation>
</message>
<message>
+ <location line="-51"/>
+ <location line="+16"/>
+ <location line="+36"/>
<source>No</source>
<translation>Nej</translation>
</message>
<message>
+ <location line="-44"/>
<source>Insert</source>
<translation>Infoga</translation>
</message>
<message>
+ <location line="+2"/>
<source>Update</source>
<translation>Uppdatera</translation>
</message>
<message>
+ <location line="+4"/>
<source>Save edits?</source>
<translation>Spara redigeringar?</translation>
</message>
<message>
+ <location line="+3"/>
<source>Cancel</source>
<translation>Avbryt</translation>
</message>
<message>
+ <location line="+32"/>
<source>Confirm</source>
<translation>Bekräfta</translation>
</message>
<message>
+ <location line="+1"/>
<source>Cancel your edits?</source>
<translation>Avbryt dina redigeringar?</translation>
</message>
@@ -3850,57 +8464,249 @@ Välj ett annat filnamn.</translation>
<context>
<name>QSslSocket</name>
<message>
+ <location filename="../src/network/ssl/qsslsocket_openssl.cpp" line="+921"/>
<source>Unable to write data: %1</source>
<translation>Kunde inte skriva data: %1</translation>
</message>
<message>
+ <location line="+63"/>
+ <source>Unable to decrypt data: %1</source>
+ <translation>Kan inte avkoda data: %1</translation>
+ </message>
+ <message>
+ <location line="+78"/>
+ <location line="+10"/>
<source>Error while reading: %1</source>
<translation>Fel vid läsning: %1</translation>
</message>
<message>
+ <location line="+95"/>
<source>Error during SSL handshake: %1</source>
- <translation>Fel vid SSL-handskakning: %1</translation>
+ <translation>Fel under SSL-handskakning: %1</translation>
</message>
<message>
+ <location line="-894"/>
<source>Error creating SSL context (%1)</source>
<translation>Fel vid skapande av SSL-kontext (%1)</translation>
</message>
<message>
+ <location line="+25"/>
<source>Invalid or empty cipher list (%1)</source>
<translation>Ogiltig eller tom chifferlista (%1)</translation>
</message>
<message>
+ <location line="+57"/>
+ <source>Private key does not certify public key, %1</source>
+ <translation>Den privata nyckeln certifierar inte den öppna nyckeln, %1</translation>
+ </message>
+ <message>
+ <location line="+20"/>
<source>Error creating SSL session, %1</source>
<translation>Fel vid skapande av SSL-session, %1</translation>
</message>
<message>
+ <location line="+15"/>
<source>Error creating SSL session: %1</source>
<translation>Fel vid skapande av SSL-session: %1</translation>
</message>
<message>
+ <location line="-64"/>
<source>Cannot provide a certificate with no key, %1</source>
<translation>Kan inte tillhandahålla ett certifikat utan nyckel, %1</translation>
</message>
<message>
+ <location line="+7"/>
<source>Error loading local certificate, %1</source>
<translation>Fel vid inläsning av lokalt certifikat, %1</translation>
</message>
<message>
+ <location line="+15"/>
<source>Error loading private key, %1</source>
<translation>Fel vid inläsning av privat nyckel, %1</translation>
</message>
<message>
<source>Private key does not certificate public key, %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Privat nyckel certifierar inte publik nyckel, %1</translation>
+ </message>
+ <message>
+ <location filename="../src/network/ssl/qsslerror.cpp" line="+213"/>
+ <source>No error</source>
+ <translation>Inget fel</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The issuer certificate could not be found</source>
+ <translation>Utgivarens certifikat hittades inte</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The certificate signature could not be decrypted</source>
+ <translation>Certifikatets signatur kunde inte avkodas</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The public key in the certificate could not be read</source>
+ <translation>Den öppna nyckeln i certifikatet kunde inte läsas</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The signature of the certificate is invalid</source>
+ <translation>Certifikatets signatur är ogiltig</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The certificate is not yet valid</source>
+ <translation>Certifikatet är inte giltigt ännu</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The certificate has expired</source>
+ <translation>Certifikatet har gått ut</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The certificate&apos;s notBefore field contains an invalid time</source>
+ <translation>Fältet notBefore i certifikatet innehåller en ogiltig tid</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The certificate&apos;s notAfter field contains an invalid time</source>
+ <translation>Fältet notAfter i certifikatet innehåller en ogiltig tid</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The certificate is self-signed, and untrusted</source>
+ <translation>Certifikatet är självsignerat, och inte pålitligt</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The root certificate of the certificate chain is self-signed, and untrusted</source>
+ <translation>Rotcertifikatet i certifikatkedjan är självsignerat, och inte pålitligt</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The issuer certificate of a locally looked up certificate could not be found</source>
+ <translation>Utfärdarens certifikat för ett lokalt uppslaget certifikat kunde inte hittas</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>No certificates could be verified</source>
+ <translation>Inga certifikat kunde verifieras</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>One of the CA certificates is invalid</source>
+ <translation>Ett av certifikatutfärdarens certifikat är ogiltigt</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The basicConstraints path length parameter has been exceeded</source>
+ <translation>Längden hos sökvägsparametern basicConstraints har överskridits</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The supplied certificate is unsuitable for this purpose</source>
+ <translation>Det angivna certifikatet är olämpligt för det här ändamålet</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The root CA certificate is not trusted for this purpose</source>
+ <translation>Rotcertifikatetutfärdarens certifikat är inte pålitligt för det här ändamålet</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The root CA certificate is marked to reject the specified purpose</source>
+ <translation>Certifikatutfärdarens certifikat är markerat att avslå det angivna ändamålet</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate</source>
+ <translation>Det aktuella föreslagna utfärdarens certifikat avslogs eftersom dess ämnesnamn inte motsvarade utfärdarens namn i det aktuella certifikatet</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate</source>
+ <translation>Det aktuella föreslagna utfärdarens certifikat avslogs eftersom dess utfärdarnamn och serienummer fanns, men inte motsvarade behörighetsnyckelns identifierare i det aktuella certifikatet</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>The peer did not present any certificate</source>
+ <translation>Motparten uppvisade inte något certifikat</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The host name did not match any of the valid hosts for this certificate</source>
+ <translation>Värddatornamnet stämmer inte med några av de giltiga värddatorerna i det här certifikatet</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Unknown error</source>
+ <translation>Okänt fel</translation>
+ </message>
+</context>
+<context>
+ <name>QStateMachine</name>
+ <message>
+ <location filename="../src/corelib/statemachine/qstatemachine.cpp" line="+1028"/>
+ <source>Missing initial state in compound state &apos;%1&apos;</source>
+ <translation>Saknar initialtillstånd i sammansatt tillstånd &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Missing default state in history state &apos;%1&apos;</source>
+ <translation>Saknar standardtillstånd i historiktillstånd &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>No common ancestor for targets and source of transition from state &apos;%1&apos;</source>
+ <translation>Inget gemensamt ursprung för mål och källa för övergång från tillstånd &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Unknown error</source>
+ <translation>Okänt fel</translation>
+ </message>
+</context>
+<context>
+ <name>QSystemSemaphore</name>
+ <message>
+ <location filename="../src/corelib/kernel/qsystemsemaphore_unix.cpp" line="-41"/>
+ <location filename="../src/corelib/kernel/qsystemsemaphore_win.cpp" line="+66"/>
+ <source>%1: out of resources</source>
+ <translation>%1: slut på resurser</translation>
+ </message>
+ <message>
+ <location line="-13"/>
+ <location filename="../src/corelib/kernel/qsystemsemaphore_win.cpp" line="+4"/>
+ <source>%1: permission denied</source>
+ <translation>%1: behörighet nekas</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>%1: already exists</source>
+ <translation>%1: finns redan</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>%1: does not exist</source>
+ <translation>%1: finns inte</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <location filename="../src/corelib/kernel/qsystemsemaphore_win.cpp" line="+3"/>
+ <source>%1: unknown error %2</source>
+ <translation>%1: okänt fel %2</translation>
</message>
</context>
<context>
<name>QTDSDriver</name>
<message>
+ <location filename="../src/sql/drivers/tds/qsql_tds.cpp" line="+595"/>
<source>Unable to open connection</source>
<translation>Kunde inte öppna anslutning</translation>
</message>
<message>
+ <location line="+5"/>
<source>Unable to use database</source>
<translation>Kunde inte använda databasen</translation>
</message>
@@ -3908,56 +8714,78 @@ Välj ett annat filnamn.</translation>
<context>
<name>QTabBar</name>
<message>
+ <location filename="../src/plugins/accessible/widgets/complexwidgets.cpp" line="-330"/>
<source>Scroll Left</source>
<translation>Rulla vänster</translation>
</message>
<message>
+ <location line="+0"/>
<source>Scroll Right</source>
<translation>Rulla höger</translation>
</message>
</context>
<context>
+ <name>QTcpServer</name>
+ <message>
+ <location filename="../src/network/socket/qtcpserver.cpp" line="+292"/>
+ <source>Operation on socket is not supported</source>
+ <translation>Åtgärden för uttaget stöds inte</translation>
+ </message>
+</context>
+<context>
<name>QTextControl</name>
<message>
+ <location filename="../src/gui/text/qtextcontrol.cpp" line="+2098"/>
<source>&amp;Undo</source>
<translation>&amp;Ã…ngra</translation>
</message>
<message>
+ <location line="+2"/>
<source>&amp;Redo</source>
<translation>&amp;Gör om</translation>
</message>
<message>
+ <location line="+4"/>
<source>Cu&amp;t</source>
<translation>Klipp u&amp;t</translation>
</message>
<message>
+ <location line="+5"/>
<source>&amp;Copy</source>
<translation>&amp;Kopiera</translation>
</message>
<message>
+ <location line="+7"/>
<source>Copy &amp;Link Location</source>
<translation>Kopiera &amp;länkplats</translation>
</message>
<message>
+ <location line="+6"/>
<source>&amp;Paste</source>
<translation>Klistra &amp;in</translation>
</message>
<message>
+ <location line="+3"/>
<source>Delete</source>
<translation>Ta bort</translation>
</message>
<message>
+ <location line="+7"/>
<source>Select All</source>
- <translation>Markera allt</translation>
+ <translation>Markera alla</translation>
</message>
</context>
<context>
<name>QToolButton</name>
<message>
+ <location filename="../src/plugins/accessible/widgets/simplewidgets.cpp" line="+310"/>
+ <location line="+6"/>
<source>Press</source>
<translation>Tryck</translation>
</message>
<message>
+ <location line="-4"/>
+ <location line="+8"/>
<source>Open</source>
<translation>Öppna</translation>
</message>
@@ -3965,6 +8793,7 @@ Välj ett annat filnamn.</translation>
<context>
<name>QUdpSocket</name>
<message>
+ <location filename="../src/network/socket/qudpsocket.cpp" line="+189"/>
<source>This platform does not support IPv6</source>
<translation>Denna plattform saknar stöd för IPv6</translation>
</message>
@@ -3972,10 +8801,12 @@ Välj ett annat filnamn.</translation>
<context>
<name>QUndoGroup</name>
<message>
+ <location filename="../src/gui/util/qundogroup.cpp" line="+385"/>
<source>Undo</source>
<translation>Ã…ngra</translation>
</message>
<message>
+ <location line="+28"/>
<source>Redo</source>
<translation>Gör om</translation>
</message>
@@ -3983,6 +8814,7 @@ Välj ett annat filnamn.</translation>
<context>
<name>QUndoModel</name>
<message>
+ <location filename="../src/gui/util/qundoview.cpp" line="+101"/>
<source>&lt;empty&gt;</source>
<translation>&lt;tom&gt;</translation>
</message>
@@ -3990,10 +8822,12 @@ Välj ett annat filnamn.</translation>
<context>
<name>QUndoStack</name>
<message>
+ <location filename="../src/gui/util/qundostack.cpp" line="+832"/>
<source>Undo</source>
<translation>Ã…ngra</translation>
</message>
<message>
+ <location line="+27"/>
<source>Redo</source>
<translation>Gör om</translation>
</message>
@@ -4001,46 +8835,57 @@ Välj ett annat filnamn.</translation>
<context>
<name>QUnicodeControlCharacterMenu</name>
<message>
+ <location filename="../src/gui/text/qtextcontrol.cpp" line="+924"/>
<source>LRM Left-to-right mark</source>
<translation>U+200E</translation>
</message>
<message>
+ <location line="+1"/>
<source>RLM Right-to-left mark</source>
<translation>U+200F</translation>
</message>
<message>
+ <location line="+1"/>
<source>ZWJ Zero width joiner</source>
<translation>U+200D</translation>
</message>
<message>
+ <location line="+1"/>
<source>ZWNJ Zero width non-joiner</source>
<translation>U+200C</translation>
</message>
<message>
+ <location line="+1"/>
<source>ZWSP Zero width space</source>
<translation>U+200B</translation>
</message>
<message>
+ <location line="+1"/>
<source>LRE Start of left-to-right embedding</source>
<translation>U+202A</translation>
</message>
<message>
+ <location line="+1"/>
<source>RLE Start of right-to-left embedding</source>
<translation>U+202B</translation>
</message>
<message>
+ <location line="+1"/>
<source>LRO Start of left-to-right override</source>
<translation>U+202D</translation>
</message>
<message>
+ <location line="+1"/>
<source>RLO Start of right-to-left override</source>
<translation>U+202E</translation>
</message>
<message>
+ <location line="+1"/>
<source>PDF Pop directional formatting</source>
<translation>U+202C</translation>
</message>
<message>
+ <location line="+6"/>
<source>Insert Unicode control character</source>
<translation>Infoga unicode-kontrolltecken</translation>
</message>
@@ -4048,26 +8893,36 @@ Välj ett annat filnamn.</translation>
<context>
<name>QWebFrame</name>
<message>
+ <location filename="../src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp" line="+756"/>
<source>Request cancelled</source>
<translation>Begäran avbröts</translation>
</message>
<message>
+ <location line="+19"/>
<source>Request blocked</source>
- <translation>Begäran blockerad</translation>
+ <translation>Begäran blockeras</translation>
</message>
<message>
+ <location line="+7"/>
<source>Cannot show URL</source>
- <translation>Kan inte visa URL:en</translation>
+ <translation>Kan inte visa URL</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Frame load interrupted by policy change</source>
+ <translation>Raminläsning avbröts av policyändring</translation>
</message>
<message>
<source>Frame load interruped by policy change</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Raminläsning avbröts av policyändring</translation>
</message>
<message>
+ <location line="+6"/>
<source>Cannot show mimetype</source>
- <translation>Kan inte visa mime-typen</translation>
+ <translation>Kan inte visa mime-typ</translation>
</message>
<message>
+ <location line="+6"/>
<source>File does not exist</source>
<translation>Filen finns inte</translation>
</message>
@@ -4075,257 +8930,896 @@ Välj ett annat filnamn.</translation>
<context>
<name>QWebPage</name>
<message>
+ <location filename="../src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp" line="+355"/>
+ <source>Redirection limit reached</source>
+ <translation>Omdirigeringsgräns uppnådd</translation>
+ </message>
+ <message>
+ <location line="+121"/>
<source>Bad HTTP request</source>
<translation>Felaktig HTTP-begäran</translation>
</message>
<message>
+ <location filename="../src/3rdparty/webkit/WebCore/platform/qt/Localizations.cpp" line="+44"/>
<source>Submit</source>
<comment>default label for Submit buttons in forms on web pages</comment>
<translation>Skicka</translation>
</message>
<message>
+ <location line="+5"/>
<source>Submit</source>
<comment>Submit (input element) alt text for &lt;input&gt; elements with no alt, title, or value</comment>
<translation>Skicka</translation>
</message>
<message>
<source>Reset</source>
- <comment>default label for Reset buttons in forms on web pages</comment>
- <translation>Återställ</translation>
+ <comment>
+default label for Reset buttons in forms on web pages</comment>
+ <translation type="obsolete">Återställ</translation>
</message>
<message>
+ <location line="+16"/>
<source>This is a searchable index. Enter search keywords: </source>
<comment>text that appears at the start of nearly-obsolete web pages in the form of a &apos;searchable index&apos;</comment>
<translation>Detta är ett sökbart index. Ange sökord: </translation>
</message>
<message>
+ <location line="+5"/>
<source>Choose File</source>
<comment>title for file button used in HTML forms</comment>
<translation>Välj fil</translation>
</message>
<message>
+ <location line="+5"/>
<source>No file selected</source>
<comment>text to display in file button used in HTML forms when no file is selected</comment>
<translation>Ingen fil vald</translation>
</message>
<message>
+ <location line="+5"/>
<source>Open in New Window</source>
<comment>Open in New Window context menu item</comment>
<translation>Öppna i nytt fönster</translation>
</message>
<message>
+ <location line="+5"/>
<source>Save Link...</source>
<comment>Download Linked File context menu item</comment>
<translation>Spara länk...</translation>
</message>
<message>
+ <location line="+5"/>
<source>Copy Link</source>
<comment>Copy Link context menu item</comment>
<translation>Kopiera länk</translation>
</message>
<message>
+ <location line="+5"/>
<source>Open Image</source>
<comment>Open Image in New Window context menu item</comment>
<translation>Öppna bild</translation>
</message>
<message>
+ <location line="+5"/>
<source>Save Image</source>
<comment>Download Image context menu item</comment>
<translation>Spara bild</translation>
</message>
<message>
+ <location line="+5"/>
<source>Copy Image</source>
<comment>Copy Link context menu item</comment>
<translation>Kopiera bild</translation>
</message>
<message>
+ <location line="+5"/>
<source>Open Frame</source>
<comment>Open Frame in New Window context menu item</comment>
<translation>Öppna ram</translation>
</message>
<message>
+ <location line="+5"/>
<source>Copy</source>
<comment>Copy context menu item</comment>
<translation>Kopiera</translation>
</message>
<message>
+ <location line="+5"/>
<source>Go Back</source>
<comment>Back context menu item</comment>
<translation>Gå bakåt</translation>
</message>
<message>
+ <location line="+5"/>
<source>Go Forward</source>
<comment>Forward context menu item</comment>
<translation>Gå framåt</translation>
</message>
<message>
<source>Stop</source>
+ <comment>
+Stop context menu item</comment>
+ <translation type="obsolete">Stoppa</translation>
+ </message>
+ <message>
+ <location line="-71"/>
+ <source>Reset</source>
+ <comment>default label for Reset buttons in forms on web pages</comment>
+ <translation>Återställ</translation>
+ </message>
+ <message>
+ <location line="+76"/>
+ <source>Stop</source>
<comment>Stop context menu item</comment>
<translation>Stoppa</translation>
</message>
<message>
+ <location line="+5"/>
<source>Reload</source>
<comment>Reload context menu item</comment>
- <translation>Uppdatera</translation>
+ <translation>Läs om</translation>
</message>
<message>
+ <location line="+5"/>
<source>Cut</source>
<comment>Cut context menu item</comment>
<translation>Klipp ut</translation>
</message>
<message>
+ <location line="+5"/>
<source>Paste</source>
<comment>Paste context menu item</comment>
<translation>Klistra in</translation>
</message>
<message>
+ <location line="+5"/>
<source>No Guesses Found</source>
<comment>No Guesses Found context menu item</comment>
<translation>Inga gissningar hittades</translation>
</message>
<message>
+ <location line="+5"/>
<source>Ignore</source>
<comment>Ignore Spelling context menu item</comment>
<translation>Ignorera</translation>
</message>
<message>
+ <location line="+5"/>
<source>Add To Dictionary</source>
<comment>Learn Spelling context menu item</comment>
- <translation>Lägg till i ordlista</translation>
+ <translation>Lägg till i ordbok</translation>
</message>
<message>
+ <location line="+5"/>
<source>Search The Web</source>
<comment>Search The Web context menu item</comment>
- <translation>Sök på webben</translation>
+ <translation>Sök på nätet</translation>
</message>
<message>
+ <location line="+5"/>
<source>Look Up In Dictionary</source>
<comment>Look Up in Dictionary context menu item</comment>
- <translation>Slå upp i ordlista</translation>
+ <translation>Slå upp i ordbok</translation>
</message>
<message>
+ <location line="+5"/>
<source>Open Link</source>
<comment>Open Link context menu item</comment>
<translation>Öppna länk</translation>
</message>
<message>
+ <location line="+5"/>
<source>Ignore</source>
<comment>Ignore Grammar context menu item</comment>
<translation>Ignorera</translation>
</message>
<message>
+ <location line="+5"/>
<source>Spelling</source>
<comment>Spelling and Grammar context sub-menu item</comment>
<translation>Stavning</translation>
</message>
<message>
+ <location line="+5"/>
<source>Show Spelling and Grammar</source>
<comment>menu item title</comment>
- <translation>Visa stavning och grammatik</translation>
+ <translation>Visa Stavning och grammatik</translation>
</message>
<message>
+ <location line="+1"/>
<source>Hide Spelling and Grammar</source>
<comment>menu item title</comment>
- <translation>Dölj stavning och grammatik</translation>
+ <translation>Dölj Stavning och grammatik</translation>
</message>
<message>
+ <location line="+5"/>
<source>Check Spelling</source>
<comment>Check spelling context menu item</comment>
<translation>Kontrollera stavning</translation>
</message>
<message>
+ <location line="+5"/>
<source>Check Spelling While Typing</source>
<comment>Check spelling while typing context menu item</comment>
- <translation>Kontrollera stavning vid inmatning</translation>
+ <translation>Kontrollera stavning automatiskt</translation>
</message>
<message>
+ <location line="+5"/>
<source>Check Grammar With Spelling</source>
<comment>Check grammar with spelling context menu item</comment>
- <translation>Kontrollera grammatik vid inmatning</translation>
+ <translation>Kontrollera grammatik med stavning</translation>
</message>
<message>
+ <location line="+5"/>
<source>Fonts</source>
<comment>Font context sub-menu item</comment>
<translation>Typsnitt</translation>
</message>
<message>
+ <location line="+5"/>
<source>Bold</source>
<comment>Bold context menu item</comment>
<translation>Fet</translation>
</message>
<message>
+ <location line="+5"/>
<source>Italic</source>
<comment>Italic context menu item</comment>
<translation>Kursiv</translation>
</message>
<message>
+ <location line="+5"/>
<source>Underline</source>
<comment>Underline context menu item</comment>
<translation>Understruken</translation>
</message>
<message>
+ <location line="+5"/>
<source>Outline</source>
<comment>Outline context menu item</comment>
<translation>Kontur</translation>
</message>
<message>
+ <location line="+5"/>
<source>Direction</source>
<comment>Writing direction context sub-menu item</comment>
<translation>Riktning</translation>
</message>
<message>
+ <location line="+5"/>
+ <source>Text Direction</source>
+ <comment>Text direction context sub-menu item</comment>
+ <translation>Textriktning</translation>
+ </message>
+ <message>
+ <location line="+5"/>
<source>Default</source>
<comment>Default writing direction context menu item</comment>
<translation>Standard</translation>
</message>
<message>
- <source>LTR</source>
+ <location line="+5"/>
+ <source>Left to Right</source>
<comment>Left to Right context menu item</comment>
<translation>Vänster till höger</translation>
</message>
<message>
- <source>RTL</source>
+ <location line="+5"/>
+ <source>Right to Left</source>
<comment>Right to Left context menu item</comment>
<translation>Höger till vänster</translation>
</message>
<message>
+ <location line="+100"/>
+ <source>Missing Plug-in</source>
+ <comment>Label text to be used when a plug-in is missing</comment>
+ <translation>Saknar insticksprogram</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Unknown</source>
+ <comment>Unknown filesize FTP directory listing item</comment>
+ <translation>Okänd</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Loading...</source>
+ <comment>Media controller status message when the media is loading</comment>
+ <translation>Laddar...</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Live Broadcast</source>
+ <comment>Media controller status message when watching a live broadcast</comment>
+ <translation>Direktsändning</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Audio Element</source>
+ <comment>Media controller element</comment>
+ <translation>Ljudkomponent</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Video Element</source>
+ <comment>Media controller element</comment>
+ <translation>Videokomponent</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Mute Button</source>
+ <comment>Media controller element</comment>
+ <translation>Tystknapp</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Unmute Button</source>
+ <comment>Media controller element</comment>
+ <translation>Ljudåterställningsknapp</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Play Button</source>
+ <comment>Media controller element</comment>
+ <translation>Uppspelningsknapp</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Pause Button</source>
+ <comment>Media controller element</comment>
+ <translation>Pausknapp</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Slider</source>
+ <comment>Media controller element</comment>
+ <translation>Skjutreglage</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Slider Thumb</source>
+ <comment>Media controller element</comment>
+ <translation>Skjutreglageknapp</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Rewind Button</source>
+ <comment>Media controller element</comment>
+ <translation>Bakåtspolningsknapp</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Return to Real-time Button</source>
+ <comment>Media controller element</comment>
+ <translation>Återgång till realtid-knapp</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Elapsed Time</source>
+ <comment>Media controller element</comment>
+ <translation>Förfluten tid</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Remaining Time</source>
+ <comment>Media controller element</comment>
+ <translation>Återstående tid</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Status Display</source>
+ <comment>Media controller element</comment>
+ <translation>Statusfönster</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Fullscreen Button</source>
+ <comment>Media controller element</comment>
+ <translation>Fullskärmsknapp</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Seek Forward Button</source>
+ <comment>Media controller element</comment>
+ <translation>Sök framåt-knapp</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Seek Back Button</source>
+ <comment>Media controller element</comment>
+ <translation>Sök bakåt-knapp</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Audio element playback controls and status display</source>
+ <comment>Media controller element</comment>
+ <translation>Ljudkomponentens uppspelningskontroller och statusvisning</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Video element playback controls and status display</source>
+ <comment>Media controller element</comment>
+ <translation>Videokomponentens uppspelningskontroller och statusvisning</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Mute audio tracks</source>
+ <comment>Media controller element</comment>
+ <translation>Tysta ljudspår</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Unmute audio tracks</source>
+ <comment>Media controller element</comment>
+ <translation>Återställ volym för ljudspår</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Begin playback</source>
+ <comment>Media controller element</comment>
+ <translation>Börja uppspelning</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Pause playback</source>
+ <comment>Media controller element</comment>
+ <translation>Paus i uppspelning</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Movie time scrubber</source>
+ <comment>Media controller element</comment>
+ <translation>Filmtidsrensning</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Movie time scrubber thumb</source>
+ <comment>Media controller element</comment>
+ <translation>Filmtidsrensningsknapp</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Rewind movie</source>
+ <comment>Media controller element</comment>
+ <translation>Spola tillbaka film</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Return streaming movie to real-time</source>
+ <comment>Media controller element</comment>
+ <translation>Återställ strömmande film till realtid</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Current movie time</source>
+ <comment>Media controller element</comment>
+ <translation>Aktuell filmtid</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Remaining movie time</source>
+ <comment>Media controller element</comment>
+ <translation>Återstående filmtid</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Current movie status</source>
+ <comment>Media controller element</comment>
+ <translation>Aktuell filmstatus</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Play movie in full-screen mode</source>
+ <comment>Media controller element</comment>
+ <translation>Spela film i fullskärmsläge</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Seek quickly back</source>
+ <comment>Media controller element</comment>
+ <translation>Sök snabbt bakåt</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Seek quickly forward</source>
+ <comment>Media controller element</comment>
+ <translation>Sök snabbt framåt</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Indefinite time</source>
+ <comment>Media time description</comment>
+ <translation>Odefinierad tid</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>%1 days %2 hours %3 minutes %4 seconds</source>
+ <comment>Media time description</comment>
+ <translation>%1 dagar %2 timmar %3 minuter %4 sekunder</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>%1 hours %2 minutes %3 seconds</source>
+ <comment>Media time description</comment>
+ <translation>%1 timmar %2 minuter %3 sekunder</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>%1 minutes %2 seconds</source>
+ <comment>Media time description</comment>
+ <translation>%1 minuter %2 sekunder</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>%1 seconds</source>
+ <comment>Media time description</comment>
+ <translation>%1 sekunder</translation>
+ </message>
+ <message>
+ <source>LTR</source>
+ <comment>Left to Right context menu item</comment>
+ <translation type="obsolete">VTH</translation>
+ </message>
+ <message>
+ <source>RTL</source>
+ <comment>Right to Left context menu item</comment>
+ <translation type="obsolete">HTV</translation>
+ </message>
+ <message>
+ <location line="-225"/>
<source>Inspect</source>
<comment>Inspect Element context menu item</comment>
<translation>Inspektera</translation>
</message>
<message>
+ <location line="+5"/>
<source>No recent searches</source>
<comment>Label for only item in menu that appears when clicking on the search field image, when no searches have been performed</comment>
<translation>Inga tidigare sökningar</translation>
</message>
<message>
+ <location line="+5"/>
<source>Recent searches</source>
<comment>label for first item in the menu that appears when clicking on the search field image, used as embedded menu title</comment>
<translation>Tidigare sökningar</translation>
</message>
<message>
+ <location line="+5"/>
<source>Clear recent searches</source>
<comment>menu item in Recent Searches menu that empties menu&apos;s contents</comment>
<translation>Töm tidigare sökningar</translation>
</message>
<message>
<source>Unknown</source>
- <comment>Unknown filesize FTP directory listing item</comment>
- <translation>Okänt</translation>
+ <comment>
+Unknown filesize FTP directory listing item</comment>
+ <translation type="obsolete">Okänt</translation>
</message>
<message>
+ <location line="+95"/>
<source>%1 (%2x%3 pixels)</source>
<comment>Title string for images</comment>
<translation>%1 (%2x%3 bildpunkter)</translation>
</message>
<message>
+ <location filename="../src/3rdparty/webkit/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp" line="+256"/>
<source>Web Inspector - %2</source>
- <translation>Webbinspekterare - %2</translation>
+ <translation>Webbinspektör - %2</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../src/3rdparty/webkit/WebCore/platform/qt/FileChooserQt.cpp" line="+45"/>
+ <source>%n file(s)</source>
+ <comment>number of chosen file</comment>
+ <translation>
+ <numerusform>%n fil</numerusform>
+ <numerusform>%n filer</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../src/3rdparty/webkit/WebCore/platform/qt/ScrollbarQt.cpp" line="+58"/>
+ <source>Scroll here</source>
+ <translation>Rulla här</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Left edge</source>
+ <translation>Vänsterkant</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Top</source>
+ <translation>Överkant</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Right edge</source>
+ <translation>Högerkant</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Bottom</source>
+ <translation>Nederkant</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Page left</source>
+ <translation>Sida vänster</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Page up</source>
+ <translation>Sida uppåt</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Page right</source>
+ <translation>Sida höger</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Page down</source>
+ <translation>Sida nedåt</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Scroll left</source>
+ <translation>Rulla vänster</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Scroll up</source>
+ <translation>Rulla uppåt</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Scroll right</source>
+ <translation>Rulla höger</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Scroll down</source>
+ <translation>Rulla nedåt</translation>
+ </message>
+ <message>
+ <location filename="../src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp" line="+2088"/>
+ <source>JavaScript Alert - %1</source>
+ <translation>Javascript-larm - %1</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>JavaScript Confirm - %1</source>
+ <translation>Javascript-bekräftelse - %1</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>JavaScript Prompt - %1</source>
+ <translation>Javascript-fråga - %1</translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>JavaScript Problem - %1</source>
+ <translation>Javascript-problem - %1</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>The script on this page appears to have a problem. Do you want to stop the script?</source>
+ <translation>Skriptet på sidan verkar ha problem. Vill du stoppa skriptet?</translation>
+ </message>
+ <message>
+ <location line="+395"/>
+ <source>Move the cursor to the next character</source>
+ <translation>Flytta markören till nästa tecken</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Move the cursor to the previous character</source>
+ <translation>Flytta markören till föregående tecken</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Move the cursor to the next word</source>
+ <translation>Flytta markören till nästa ord</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Move the cursor to the previous word</source>
+ <translation>Flytta markören till föregående ord</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Move the cursor to the next line</source>
+ <translation>Flytta markören till nästa rad</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Move the cursor to the previous line</source>
+ <translation>Flytta markören till föregående rad</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Move the cursor to the start of the line</source>
+ <translation>Flytta markören till radens början</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Move the cursor to the end of the line</source>
+ <translation>Flytta markören till radens slut</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Move the cursor to the start of the block</source>
+ <translation>Flytta markören till blockets början</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Move the cursor to the end of the block</source>
+ <translation>Flytta markören till blockets slut</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Move the cursor to the start of the document</source>
+ <translation>Flytta markören till dokumentets början</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Move the cursor to the end of the document</source>
+ <translation>Flytta markören till dokumentets slut</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select all</source>
+ <translation>Markera alla</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select to the next character</source>
+ <translation>Markera till nästa tecken</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select to the previous character</source>
+ <translation>Markera till föregående tecken</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select to the next word</source>
+ <translation>Markera till nästa ord</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select to the previous word</source>
+ <translation>Markera till föregående ord</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select to the next line</source>
+ <translation>Markera till nästa rad</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select to the previous line</source>
+ <translation>Markera till föregående rad</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select to the start of the line</source>
+ <translation>Markera till radens början</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select to the end of the line</source>
+ <translation>Markera till radens slut</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select to the start of the block</source>
+ <translation>Markera till blockets början</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select to the end of the block</source>
+ <translation>Markera till blockets slut</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select to the start of the document</source>
+ <translation>Markera till dokumentets början</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Select to the end of the document</source>
+ <translation>Markera till dokumentets slut</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Delete to the start of the word</source>
+ <translation>Ta bort till ordets början</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Delete to the end of the word</source>
+ <translation>Ta bort till ordets slut</translation>
+ </message>
+ <message>
+ <location line="+33"/>
+ <source>Insert a new paragraph</source>
+ <translation>Infoga ett nytt stycke</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Insert a new line</source>
+ <translation>Infoga en ny rad</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Paste and Match Style</source>
+ <translation>Klistra in och matcha stil</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Remove formatting</source>
+ <translation>Ta bort formatering</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Strikethrough</source>
+ <translation>Överstrykning</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Subscript</source>
+ <translation>Nedsänkt</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Superscript</source>
+ <translation>Upphöjt</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Insert Bulleted List</source>
+ <translation>Infoga punktlista</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Insert Numbered List</source>
+ <translation>Infoga numrerad lista</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Indent</source>
+ <translation>Indentera</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Outdent</source>
+ <translation>Ta bort indentering</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Center</source>
+ <translation>Centrera</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Justify</source>
+ <translation>Anpassa</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Align Left</source>
+ <translation>Vänsterjustera</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Align Right</source>
+ <translation>Högerjustera</translation>
</message>
</context>
<context>
<name>QWhatsThisAction</name>
<message>
+ <location filename="../src/gui/kernel/qwhatsthis.cpp" line="+527"/>
<source>What&apos;s This?</source>
<translation>Vad är det här?</translation>
</message>
@@ -4333,6 +9827,7 @@ Välj ett annat filnamn.</translation>
<context>
<name>QWidget</name>
<message>
+ <location filename="../src/gui/kernel/qwidget.cpp" line="+5974"/>
<source>*</source>
<translation>*</translation>
</message>
@@ -4340,50 +9835,61 @@ Välj ett annat filnamn.</translation>
<context>
<name>QWizard</name>
<message>
+ <location filename="../src/gui/dialogs/qwizard.cpp" line="+689"/>
<source>Go Back</source>
- <translation>GÃ¥ tillbaka</translation>
+ <translation>Gå bakåt</translation>
</message>
<message>
+ <location line="+3"/>
<source>Continue</source>
<translation>Fortsätt</translation>
</message>
<message>
+ <location line="+5"/>
<source>Commit</source>
<translation>Verkställ</translation>
</message>
<message>
+ <location line="+2"/>
<source>Done</source>
<translation>Färdig</translation>
</message>
<message>
<source>Quit</source>
- <translation>Avsluta</translation>
+ <translation type="obsolete">Avsluta</translation>
</message>
<message>
+ <location line="+4"/>
<source>Help</source>
<translation>Hjälp</translation>
</message>
<message>
+ <location line="-14"/>
<source>&lt; &amp;Back</source>
<translation>&lt; Till&amp;baka</translation>
</message>
<message>
+ <location line="+10"/>
<source>&amp;Finish</source>
<translation>&amp;Färdigställ</translation>
</message>
<message>
+ <location line="+2"/>
<source>Cancel</source>
<translation>Avbryt</translation>
</message>
<message>
+ <location line="+2"/>
<source>&amp;Help</source>
<translation>&amp;Hjälp</translation>
</message>
<message>
+ <location line="-8"/>
<source>&amp;Next</source>
<translation>&amp;Nästa</translation>
</message>
<message>
+ <location line="+0"/>
<source>&amp;Next &gt;</source>
<translation>&amp;Nästa &gt;</translation>
</message>
@@ -4391,54 +9897,69 @@ Välj ett annat filnamn.</translation>
<context>
<name>QWorkspace</name>
<message>
+ <location filename="../src/gui/widgets/qworkspace.cpp" line="+1089"/>
<source>&amp;Restore</source>
<translation>Åte&amp;rställ</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Move</source>
<translation>&amp;Flytta</translation>
</message>
<message>
+ <location line="+1"/>
<source>&amp;Size</source>
<translation>&amp;Storlek</translation>
</message>
<message>
+ <location line="+2"/>
<source>Mi&amp;nimize</source>
<translation>Mi&amp;nimera</translation>
</message>
<message>
+ <location line="+2"/>
<source>Ma&amp;ximize</source>
<translation>Ma&amp;ximera</translation>
</message>
<message>
+ <location line="+2"/>
<source>&amp;Close</source>
<translation>&amp;Stäng</translation>
</message>
<message>
+ <location line="+6"/>
<source>Stay on &amp;Top</source>
<translation>Stanna kvar övers&amp;t</translation>
</message>
<message>
+ <location line="+3"/>
+ <location line="+1059"/>
<source>Sh&amp;ade</source>
<translation>Skugg&amp;a</translation>
</message>
<message>
+ <location line="-278"/>
+ <location line="+60"/>
<source>%1 - [%2]</source>
<translation>%1 - [%2]</translation>
</message>
<message>
+ <location line="-1832"/>
<source>Minimize</source>
<translation>Minimera</translation>
</message>
<message>
+ <location line="+2"/>
<source>Restore Down</source>
<translation>Återställ nedåt</translation>
</message>
<message>
+ <location line="-4"/>
<source>Close</source>
<translation>Stäng</translation>
</message>
<message>
+ <location line="+2048"/>
<source>&amp;Unshade</source>
<translation>A&amp;vskugga</translation>
</message>
@@ -4446,237 +9967,330 @@ Välj ett annat filnamn.</translation>
<context>
<name>QXml</name>
<message>
+ <location filename="../src/xml/sax/qxml.cpp" line="+58"/>
<source>no error occurred</source>
<translation>inga fel inträffade</translation>
</message>
<message>
+ <location line="+1"/>
<source>error triggered by consumer</source>
<translation>fel utlöstes av konsument</translation>
</message>
<message>
+ <location line="+1"/>
<source>unexpected end of file</source>
<translation>oväntat slut på filen</translation>
</message>
<message>
+ <location line="+1"/>
<source>more than one document type definition</source>
<translation>fler än en dokumenttypsdefinition</translation>
</message>
<message>
+ <location line="+1"/>
<source>error occurred while parsing element</source>
<translation>fel inträffade vid tolkning av element</translation>
</message>
<message>
+ <location line="+1"/>
<source>tag mismatch</source>
<translation>tagg stämmer inte</translation>
</message>
<message>
+ <location line="+1"/>
<source>error occurred while parsing content</source>
<translation>fel inträffade vid tolkning av innehåll</translation>
</message>
<message>
+ <location line="+1"/>
<source>unexpected character</source>
<translation>oväntat tecken</translation>
</message>
<message>
+ <location line="+1"/>
<source>invalid name for processing instruction</source>
<translation>ogiltigt namn för behandlingsinstruktion</translation>
</message>
<message>
+ <location line="+1"/>
<source>version expected while reading the XML declaration</source>
<translation>version förväntades vid läsning av XML-deklareringen</translation>
</message>
<message>
+ <location line="+1"/>
<source>wrong value for standalone declaration</source>
<translation>fel värde för fristående deklarering</translation>
</message>
<message>
+ <location line="+1"/>
<source>encoding declaration or standalone declaration expected while reading the XML declaration</source>
<translation>kodningsdeklarering eller fristående deklarering förväntades vid läsning av XML-deklareringen</translation>
</message>
<message>
+ <location line="+1"/>
<source>standalone declaration expected while reading the XML declaration</source>
<translation>fristående deklarering förväntades vid läsning av XML-deklarering</translation>
</message>
<message>
+ <location line="+1"/>
<source>error occurred while parsing document type definition</source>
<translation>fel inträffade vid tolkning av dokumenttypsdefinition</translation>
</message>
<message>
+ <location line="+1"/>
<source>letter is expected</source>
<translation>bokstav förväntades</translation>
</message>
<message>
+ <location line="+1"/>
<source>error occurred while parsing comment</source>
<translation>fel inträffade vid tolkning av kommentar</translation>
</message>
<message>
+ <location line="+1"/>
<source>error occurred while parsing reference</source>
<translation>fel inträffade vid tolkning av referens</translation>
</message>
<message>
+ <location line="+1"/>
<source>internal general entity reference not allowed in DTD</source>
<translation>intern allmän entitetsreferens tillåts inte i DTD</translation>
</message>
<message>
+ <location line="+1"/>
<source>external parsed general entity reference not allowed in attribute value</source>
<translation>extern tolkad allmän entitetsreferens tillåts inte i attributvärde</translation>
</message>
<message>
+ <location line="+1"/>
<source>external parsed general entity reference not allowed in DTD</source>
<translation>extern tolkad allmän entitetsreferens tillåts inte i DTD</translation>
</message>
<message>
+ <location line="+1"/>
<source>unparsed entity reference in wrong context</source>
<translation>otolkad entitetsreferens i fel sammanhang</translation>
</message>
<message>
+ <location line="+1"/>
<source>recursive entities</source>
<translation>rekursiva entiteter</translation>
</message>
<message>
+ <location line="+1"/>
<source>error in the text declaration of an external entity</source>
<translation>fel i textdeklareringen av en extern entitet</translation>
</message>
</context>
<context>
+ <name>QXmlPatternistCLI</name>
+ <message>
+ <location filename="../src/xmlpatterns/api/qcoloringmessagehandler.cpp" line="+87"/>
+ <source>Warning in %1, at line %2, column %3: %4</source>
+ <translation>Varning i %1, på rad %2, kolumn %3: %4</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Warning in %1: %2</source>
+ <translation>Varning i %1: %2</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Unknown location</source>
+ <translation>Okänt plats</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Error %1 in %2, at line %3, column %4: %5</source>
+ <translation>Fel %1 i %2 på rad %3, kolumn %4: %5</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Error %1 in %2: %3</source>
+ <translation>Fel %1 i %2: %3</translation>
+ </message>
+</context>
+<context>
<name>QXmlStream</name>
<message>
+ <location filename="../src/corelib/xml/qxmlstream.cpp" line="+611"/>
+ <location filename="../src/corelib/xml/qxmlstream_p.h" line="+1770"/>
<source>Extra content at end of document.</source>
- <translation>Extra innehåll vid dokumentets slut.</translation>
+ <translation>Extra innehåll vid dokumentslutet.</translation>
</message>
<message>
+ <location line="+271"/>
<source>Invalid entity value.</source>
- <translation>Ogiltigt värde för entitet.</translation>
+ <translation>Ogiltigt entitetsvärde.</translation>
</message>
<message>
+ <location line="+109"/>
<source>Invalid XML character.</source>
<translation>Ogiltigt XML-tecken.</translation>
</message>
<message>
+ <location line="+259"/>
<source>Sequence &apos;]]&gt;&apos; not allowed in content.</source>
<translation>Sekvensen \&quot;]]&gt;\&quot; tillåts inte i innehåll.</translation>
</message>
<message>
+ <location line="+309"/>
<source>Namespace prefix &apos;%1&apos; not declared</source>
- <translation>Namnrymdsprefixet \&quot;%1\&quot; är inte deklarerat</translation>
+ <translation>Namnrymdsprefixet \&quot;%1\&quot; inte deklarerat</translation>
</message>
<message>
+ <location line="+78"/>
<source>Attribute redefined.</source>
<translation>Attributet omdefinierat.</translation>
</message>
<message>
+ <location line="+115"/>
<source>Unexpected character &apos;%1&apos; in public id literal.</source>
<translation>Oväntat tecken \&quot;%1\&quot; i publik id-literal.</translation>
</message>
<message>
+ <location line="+28"/>
<source>Invalid XML version string.</source>
<translation>Ogiltig XML-versionssträng.</translation>
</message>
<message>
+ <location line="+2"/>
<source>Unsupported XML version.</source>
<translation>XML-versionen stöds inte.</translation>
</message>
<message>
+ <location line="+23"/>
<source>%1 is an invalid encoding name.</source>
- <translation>%1 är ett ogiltigt kodningsnamn.</translation>
+ <translation>%1 är ett ogiltigt teckenkodningsnamn.</translation>
</message>
<message>
+ <location line="+7"/>
<source>Encoding %1 is unsupported</source>
- <translation>Kodningen %1 stöds inte</translation>
+ <translation>Teckenkodningen %1 stöds inte</translation>
</message>
<message>
+ <location line="+16"/>
<source>Standalone accepts only yes or no.</source>
- <translation>Standalone accepterar endast yes eller no.</translation>
+ <translation>Standalone tillåter endast yes eller no.</translation>
</message>
<message>
+ <location line="+2"/>
<source>Invalid attribute in XML declaration.</source>
<translation>Ogiltigt attribut i XML-deklaration.</translation>
</message>
<message>
+ <location line="+16"/>
<source>Premature end of document.</source>
- <translation>För tidigt slut på dokumentet.</translation>
+ <translation>För tidigt dokumentslut.</translation>
</message>
<message>
+ <location line="+2"/>
<source>Invalid document.</source>
<translation>Ogiltigt dokument.</translation>
</message>
<message>
+ <location line="+40"/>
<source>Expected </source>
<translation>Förväntade </translation>
</message>
<message>
+ <location line="+11"/>
<source>, but got &apos;</source>
<translation>, men fick &apos;</translation>
</message>
<message>
+ <location line="+4"/>
<source>Unexpected &apos;</source>
<translation>Oväntat &apos;</translation>
</message>
<message>
+ <location line="+225"/>
<source>Expected character data.</source>
<translation>Förväntade teckendata.</translation>
</message>
<message>
+ <location filename="../src/corelib/xml/qxmlstream_p.h" line="-995"/>
<source>Recursive entity detected.</source>
<translation>Rekursiv entitet upptäcktes.</translation>
</message>
<message>
+ <location line="+516"/>
<source>Start tag expected.</source>
- <translation>Starttagg förväntades.</translation>
+ <translation>Start-tagg förväntades.</translation>
</message>
<message>
+ <location line="+222"/>
<source>XML declaration not at start of document.</source>
<translation>XML-deklaration inte i början av dokument.</translation>
</message>
<message>
+ <location line="-31"/>
<source>NDATA in parameter entity declaration.</source>
- <translation>NDATA i deklaration av parameterentitet.</translation>
+ <translation>NDATA i parameterentitetdeklaration.</translation>
</message>
<message>
+ <location line="+34"/>
<source>%1 is an invalid processing instruction name.</source>
- <translation>%1 är ett ogiltigt namn för processinstruktion.</translation>
+ <translation>%1 är ett ogiltigt namn på en processinstruktion.</translation>
</message>
<message>
+ <location line="+11"/>
<source>Invalid processing instruction name.</source>
- <translation>Ogiltigt namn för processinstruktion.</translation>
+ <translation>Ogiltigt namn på processinstruktion.</translation>
</message>
<message>
+ <location filename="../src/corelib/xml/qxmlstream.cpp" line="-536"/>
+ <location line="+12"/>
+ <location filename="../src/corelib/xml/qxmlstream_p.h" line="+164"/>
+ <location line="+53"/>
<source>Illegal namespace declaration.</source>
- <translation>Ogiltigt deklaration av namnrymd.</translation>
+ <translation>Otillåten namnrymdsdeklaration.</translation>
</message>
<message>
+ <location filename="../src/corelib/xml/qxmlstream_p.h" line="+15"/>
<source>Invalid XML name.</source>
<translation>Ogiltigt XML-namn.</translation>
</message>
<message>
+ <location line="+23"/>
<source>Opening and ending tag mismatch.</source>
- <translation>Öppning- och slut-tagg stämmer inte.</translation>
+ <translation>Taggar för början och slut stämmer inte.</translation>
</message>
<message>
+ <location line="+18"/>
<source>Reference to unparsed entity &apos;%1&apos;.</source>
- <translation>Referens till otolkade entiteten \&quot;%1\&quot;.</translation>
+ <translation>Referens till otolkad entitet \&quot;%1\&quot;.</translation>
</message>
<message>
+ <location line="-13"/>
+ <location line="+61"/>
+ <location line="+40"/>
<source>Entity &apos;%1&apos; not declared.</source>
- <translation>Entiteten \&quot;%1\&quot; är inte deklarerad.</translation>
+ <translation>Entitet \&quot;%1\&quot; inte deklarerad.</translation>
</message>
<message>
+ <location line="-26"/>
<source>Reference to external entity &apos;%1&apos; in attribute value.</source>
- <translation>Referens till externa entiteten \&quot;%1\&quot; i attributvärde.</translation>
+ <translation>Referens till extern entitet \&quot;%1\&quot; i attributvärde.</translation>
</message>
<message>
+ <location line="+40"/>
<source>Invalid character reference.</source>
<translation>Ogiltig teckenreferens.</translation>
</message>
<message>
+ <location filename="../src/corelib/xml/qxmlstream.cpp" line="-75"/>
+ <location filename="../src/corelib/xml/qxmlstream_p.h" line="-823"/>
<source>Encountered incorrectly encoded content.</source>
<translation>Påträffade felaktigt kodat innehåll.</translation>
</message>
<message>
+ <location line="+274"/>
<source>The standalone pseudo attribute must appear after the encoding.</source>
- <translation>Pseudoattributet standalone måste finnas efter kodningen.</translation>
+ <translation>Pseudoattributet standalone måste finnas efter teckenkodningen.</translation>
</message>
<message>
+ <location filename="../src/corelib/xml/qxmlstream_p.h" line="+562"/>
<source>%1 is an invalid PUBLIC identifier.</source>
<translation>%1 är en ogiltig PUBLIC-identifierare.</translation>
</message>
@@ -4685,651 +10299,2474 @@ Välj ett annat filnamn.</translation>
<name>QtXmlPatterns</name>
<message>
<source>An %1-attribute with value %2 has already been declared.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Ett %1-attribut med värdet %2 har redan deklarerats.</translation>
</message>
<message>
<source>An %1-attribute must have a valid %2 as value, which %3 isn&apos;t.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Ett %1-attribut måste ha en giltig %2 som värde, som %3 inte är.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/api/qiodevicedelegate.cpp" line="+84"/>
<source>Network timeout.</source>
- <translation type="unfinished"></translation>
+ <translation>Nätverkstidsgräns överskreds.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/api/qxmlserializer.cpp" line="+320"/>
<source>Element %1 can&apos;t be serialized because it appears outside the document element.</source>
- <translation type="unfinished"></translation>
+ <translation>Elementet %1 kan inte serialiseras därför att det finns utanför dokumentelementet.</translation>
</message>
<message>
+ <location line="+60"/>
<source>Attribute %1 can&apos;t be serialized because it appears at the top level.</source>
- <translation type="unfinished"></translation>
+ <translation>Egenskapen %1 kan inte serialiseras eftersom den uppträder på toppnivå.</translation>
</message>
<message>
+ <source>Attribute element %1 can&apos;t be serialized because it appears at the top level.</source>
+ <translation type="obsolete">Attributelementet %1 kan inte serialiseras därför att det finns i översta nivån.</translation>
+ </message>
+ <message>
+ <location filename="../src/xmlpatterns/data/qabstractdatetime.cpp" line="+80"/>
<source>Year %1 is invalid because it begins with %2.</source>
- <translation type="unfinished"></translation>
+ <translation>Året %1 är ogiltigt eftersom det börjar med %2.</translation>
</message>
<message>
+ <location line="+19"/>
<source>Day %1 is outside the range %2..%3.</source>
- <translation type="unfinished"></translation>
+ <translation>Dagen %1 är utanför intervallet %2..%3.</translation>
</message>
<message>
+ <location line="+7"/>
<source>Month %1 is outside the range %2..%3.</source>
- <translation type="unfinished"></translation>
+ <translation>Månaden %1 är utanför intervallet %2..%3.</translation>
</message>
<message>
+ <location line="+10"/>
<source>Overflow: Can&apos;t represent date %1.</source>
- <translation type="unfinished"></translation>
+ <translation>Överflode: Kan inte representera datumet %1.</translation>
</message>
<message>
+ <location line="+9"/>
<source>Day %1 is invalid for month %2.</source>
- <translation type="unfinished"></translation>
+ <translation>Dagen %1 är ogiltig för månaden %2.</translation>
</message>
<message>
+ <location line="+49"/>
<source>Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; </source>
- <translation type="unfinished"></translation>
+ <translation>Tiden 24:%1:%2.%3 är ogiltig. Timmen är 24 men minuter, sekunder och millisekunder är inte alla 0; </translation>
</message>
<message>
+ <location line="+13"/>
<source>Time %1:%2:%3.%4 is invalid.</source>
- <translation type="unfinished"></translation>
+ <translation>Tiden %1:%2:%3.%4 är ogiltig.</translation>
</message>
<message>
+ <location line="+115"/>
<source>Overflow: Date can&apos;t be represented.</source>
- <translation type="unfinished"></translation>
+ <translation>Överflöde: Datumet kan inte representeras.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/data/qabstractduration.cpp" line="+99"/>
+ <location line="+15"/>
<source>At least one component must be present.</source>
- <translation type="unfinished"></translation>
+ <translation>Åtminstone en komponent måste finnas.</translation>
</message>
<message>
+ <location line="-7"/>
<source>At least one time component must appear after the %1-delimiter.</source>
- <translation type="unfinished"></translation>
+ <translation>Åtminstone en tidskomponent måste finnas efter %1-avgränsaren.</translation>
</message>
<message>
<source>No operand in an integer division, %1, can be %2.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Ingen operand i en heltalsdivision, %1, kan vara %2.</translation>
</message>
<message>
<source>The first operand in an integer division, %1, cannot be infinity (%2).</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Första operanden i en heltalsdivision, %1, kan inte vara oändlig (%2).</translation>
</message>
<message>
<source>The second operand in a division, %1, cannot be zero (%2).</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Andra operanden i en division, %1, kan inte vara noll (%2).</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/data/qanyuri_p.h" line="+132"/>
<source>%1 is not a valid value of type %2.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är inte ett giltigt värde för typen %2.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/data/qatomiccasters_p.h" line="+223"/>
<source>When casting to %1 from %2, the source value cannot be %3.</source>
- <translation type="unfinished"></translation>
+ <translation>Vid typkonvertering till %1 från %2 kan inte källvärdet vara %3.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/data/qatomicmathematicians.cpp" line="+65"/>
<source>Integer division (%1) by zero (%2) is undefined.</source>
- <translation type="unfinished"></translation>
+ <translation>Heltalsdivision (%1) med noll (%2) är odefinierad.</translation>
</message>
<message>
+ <location line="+7"/>
<source>Division (%1) by zero (%2) is undefined.</source>
- <translation type="unfinished"></translation>
+ <translation>Division (%1) med noll (%2) är odefinierad.</translation>
</message>
<message>
+ <location line="+7"/>
<source>Modulus division (%1) by zero (%2) is undefined.</source>
- <translation type="unfinished"></translation>
+ <translation>Modulusdividering (%1) med noll (%2) är odefinierad.</translation>
</message>
<message>
+ <location line="+122"/>
+ <location line="+32"/>
<source>Dividing a value of type %1 by %2 (not-a-number) is not allowed.</source>
- <translation type="unfinished"></translation>
+ <translation>Dividering av ett värde av typen %1 med %2 (inte ett tal) tillåts inte.</translation>
</message>
<message>
+ <location line="-20"/>
<source>Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed.</source>
- <translation type="unfinished"></translation>
+ <translation>Dividering av ett värde av typen %1 med %2 eller %3 (plus eller minus noll) tillåts inte.</translation>
</message>
<message>
+ <location line="+32"/>
<source>Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed.</source>
- <translation type="unfinished"></translation>
+ <translation>Multiplicering av ett värde av typen %1 med %2 eller %3 (plus eller minus oändligt) tillåts inte.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/data/qatomicvalue.cpp" line="+79"/>
<source>A value of type %1 cannot have an Effective Boolean Value.</source>
- <translation type="unfinished"></translation>
+ <translation>Ett värde av typen %1 kan inte ha ett effektivt booleskt värde.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/data/qboolean.cpp" line="+78"/>
<source>Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values.</source>
- <translation type="unfinished"></translation>
+ <translation>Effektivt booleskt värde kan inte beräknas för en sekvens som innehåller två eller flera odelbara värden.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/data/qderivedinteger_p.h" line="+402"/>
<source>Value %1 of type %2 exceeds maximum (%3).</source>
- <translation type="unfinished"></translation>
+ <translation>Värdet %1 av typen %2 överstiger maximum (%3).</translation>
</message>
<message>
+ <location line="+9"/>
<source>Value %1 of type %2 is below minimum (%3).</source>
- <translation type="unfinished"></translation>
+ <translation>Värdet %1 av typen %2 är under minimum (%3).</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/data/qhexbinary.cpp" line="+91"/>
<source>A value of type %1 must contain an even number of digits. The value %2 does not.</source>
- <translation type="unfinished"></translation>
+ <translation>Ett värde av typen %1 måste innehålla ett jämnt antal siffror. Värdet %2 gör inte det.</translation>
</message>
<message>
+ <location line="+19"/>
<source>%1 is not valid as a value of type %2.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är inte giltig som ett värde av typen %2.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/expr/qarithmeticexpression.cpp" line="+207"/>
<source>Operator %1 cannot be used on type %2.</source>
- <translation type="unfinished"></translation>
+ <translation>Operatorn %1 kan inte användas på typen %2.</translation>
</message>
<message>
+ <location line="+17"/>
<source>Operator %1 cannot be used on atomic values of type %2 and %3.</source>
- <translation type="unfinished"></translation>
+ <translation>Operatorn %1 kan inte användas på odelbara värden av typen %2 och %3.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/expr/qattributenamevalidator.cpp" line="+66"/>
<source>The namespace URI in the name for a computed attribute cannot be %1.</source>
- <translation type="unfinished"></translation>
+ <translation>Namnrymds-URI:n i namnet för ett beräknat attribut kan inte vara %1.</translation>
</message>
<message>
+ <location line="+9"/>
<source>The name for a computed attribute cannot have the namespace URI %1 with the local name %2.</source>
- <translation type="unfinished"></translation>
+ <translation>Namnet för ett beräknat attribut kan inte ha namnrymds-URI:n %1 med lokala namnet %2.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/expr/qcastas.cpp" line="+88"/>
<source>Type error in cast, expected %1, received %2.</source>
- <translation type="unfinished"></translation>
+ <translation>Typfel i typkonvertering, förväntade %1, fick %2.</translation>
</message>
<message>
+ <location line="+29"/>
<source>When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed.</source>
- <translation type="unfinished"></translation>
+ <translation>När typkonvertering görs till %1 eller typer härledda från den, måste källvärde vara av samma typ, eller så måste den vara en strängliteral. Typen %2 är inte tillåten.</translation>
</message>
<message>
<source>No casting is possible with %1 as the target type.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Ingen typkonvertering är möjlig med %1 som måltypen.</translation>
</message>
<message>
<source>It is not possible to cast from %1 to %2.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Det är inte möjligt att typkonvertera från %1 till %2.</translation>
</message>
<message>
<source>Casting to %1 is not possible because it is an abstract type, and can therefore never be instantiated.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Typkonvertering till %1 är inte möjlig därför att det är en abstrakt typ och kan därför aldrig exemplifieras.</translation>
</message>
<message>
<source>It&apos;s not possible to cast the value %1 of type %2 to %3</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Det är inte möjligt att typkonvertera värdet %1 av typen %2 till %3</translation>
</message>
<message>
<source>Failure when casting from %1 to %2: %3</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Typkonvertering från %1 till %2 misslyckades: %3</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/expr/qcommentconstructor.cpp" line="+67"/>
<source>A comment cannot contain %1</source>
- <translation type="unfinished"></translation>
+ <translation>En kommentar får inte innehålla %1</translation>
</message>
<message>
+ <location line="+6"/>
<source>A comment cannot end with a %1.</source>
- <translation type="unfinished"></translation>
+ <translation>En kommentar får inte sluta med ett %1.</translation>
</message>
<message>
<source>No comparisons can be done involving the type %1.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Inga jämförelser kan göras som infattar typen %1.</translation>
</message>
<message>
<source>Operator %1 is not available between atomic values of type %2 and %3.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Operatorn %1 är inte tillgänglig mellan odelbara värden av typen %2 och %3.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/expr/qdocumentcontentvalidator.cpp" line="+86"/>
<source>An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place.</source>
- <translation type="unfinished"></translation>
+ <translation>En attributnod kan inte vara ett barn till en dokumentnod. Därför är attributet %1 felplacerat.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/expr/qexpressionfactory.cpp" line="+162"/>
<source>A library module cannot be evaluated directly. It must be imported from a main module.</source>
- <translation type="unfinished"></translation>
+ <translation>En biblioteksmodul kan inte evalueras direkt. Den måste importeras från en huvudmodul.</translation>
+ </message>
+ <message>
+ <location line="+40"/>
+ <source>No template by name %1 exists.</source>
+ <translation>NÃ¥gon mall med namnet %1 finns inte.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/expr/qgenericpredicate.cpp" line="+106"/>
<source>A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type.</source>
- <translation type="unfinished"></translation>
+ <translation>Ett värde av typen %1 kan inte vara ett predikat. Ett predikat måste ha antingen ett numeriskt värde eller en effektivt booleskt värde-typ.</translation>
</message>
<message>
+ <location line="+32"/>
<source>A positional predicate must evaluate to a single numeric value.</source>
- <translation type="unfinished"></translation>
+ <translation>Ett positionellt predikat måste evalueras till ett enstaka numeriskt värde.</translation>
</message>
<message>
<source>The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, is %2 invalid.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Målnamnet i en processinstruktion kan inte vara %1 i någon kombination av gemener och versaler. Därför är %2 ogiltig.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/expr/qncnameconstructor_p.h" line="+113"/>
+ <source>The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, %2 is invalid.</source>
+ <translation>Målnamnet i en processinstruktion kan inte vara %1 i någon kombination av gemener och versaler. Därför är %2 ogiltig.</translation>
+ </message>
+ <message>
+ <location line="+24"/>
<source>%1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är inte ett giltigt målnamn i en processinstruktion. Den måste vara ett %2-värde, t.ex. %3.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/expr/qpath.cpp" line="+109"/>
<source>The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two.</source>
- <translation type="unfinished"></translation>
+ <translation>Sista steget i en sökvägen måste innehålla antingen noder eller odelbara värden. Det kan inte vara en blandning mellan de två.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp" line="+84"/>
<source>The data of a processing instruction cannot contain the string %1</source>
- <translation type="unfinished"></translation>
+ <translation>Datat för en processinstruktion får inte innehålla strängen %1</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/expr/qqnameconstructor.cpp" line="+82"/>
<source>No namespace binding exists for the prefix %1</source>
- <translation type="unfinished"></translation>
+ <translation>Ingen namnrymdsbindning finns för prefixet %1</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/expr/qqnameconstructor_p.h" line="+156"/>
<source>No namespace binding exists for the prefix %1 in %2</source>
- <translation type="unfinished"></translation>
+ <translation>Ingen namnrymdsbindning finns för prefixet %1 i %2</translation>
</message>
<message>
+ <location line="+12"/>
+ <location filename="../src/xmlpatterns/functions/qqnamefns.cpp" line="+69"/>
<source>%1 is an invalid %2</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är en ogiltig %2</translation>
</message>
<message numerus="yes">
+ <location filename="../src/xmlpatterns/functions/qabstractfunctionfactory.cpp" line="+77"/>
<source>%1 takes at most %n argument(s). %2 is therefore invalid.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%1 tar som mest %n argument. %2 är därför ogiltig.</numerusform>
+ <numerusform>%1 tar som mest %n argument. %2 är därför ogiltig.</numerusform>
</translation>
</message>
<message numerus="yes">
+ <location line="+11"/>
<source>%1 requires at least %n argument(s). %2 is therefore invalid.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%1 kräver minst %n argument. %2 är därför ogiltig.</numerusform>
+ <numerusform>%1 kräver minst %n argument. %2 är därför ogiltig.</numerusform>
</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/functions/qaggregatefns.cpp" line="+120"/>
<source>The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration.</source>
- <translation type="unfinished"></translation>
+ <translation>Först argumentet till %1 kan inte vara av typen %2. Det måste vara en numerisk typ, xs:yearMonthDuration eller xs:dayTimeDuration.</translation>
</message>
<message>
+ <location line="+74"/>
<source>The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5.</source>
- <translation type="unfinished"></translation>
+ <translation>Första argumentet till %1 kan inte vara av typen %2. Det måste vara av typen %3, %4 eller %5.</translation>
</message>
<message>
+ <location line="+91"/>
<source>The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5.</source>
- <translation type="unfinished"></translation>
+ <translation>Andra argumentet till %1 kan inte vara av typen %2. Det måste vara av typen %3, %4 eller %5.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/functions/qassemblestringfns.cpp" line="+88"/>
<source>%1 is not a valid XML 1.0 character.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är inte ett giltigt XML 1.0-tecken.</translation>
</message>
<message>
<source>The first argument to %1 cannot be of type %2.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Första argumentet till %1 kan inte vara av typen %2.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/functions/qdatetimefn.cpp" line="+86"/>
<source>If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same.</source>
- <translation type="unfinished"></translation>
+ <translation>Om båda värden har zonpositioner så måste de ha samma zonposition. %1 och %2 är inte samma.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/functions/qerrorfn.cpp" line="+61"/>
<source>%1 was called.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 anropades.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/functions/qpatternmatchingfns.cpp" line="+94"/>
<source>%1 must be followed by %2 or %3, not at the end of the replacement string.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 måste följas av %2 eller %3, inte i slutet av ersättningssträngen.</translation>
</message>
<message>
+ <location line="+39"/>
<source>In the replacement string, %1 must be followed by at least one digit when not escaped.</source>
- <translation type="unfinished"></translation>
+ <translation>I ersättningssträngen måste %1 följas av minst en siffra när den inte inleds med escape-tecken.</translation>
</message>
<message>
+ <location line="+26"/>
<source>In the replacement string, %1 can only be used to escape itself or %2, not %3</source>
- <translation type="unfinished"></translation>
+ <translation>I ersättningssträngen kan %1 endast användas för att undanta (escape) sig själv eller %2, inte %3</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/functions/qpatternplatform.cpp" line="+92"/>
<source>%1 matches newline characters</source>
- <translation type="unfinished"></translation>
+ <translation>%1 matchar nyradstecken</translation>
</message>
<message>
+ <location line="+4"/>
<source>%1 and %2 match the start and end of a line.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 och %2 matchar början och slutet av en rad.</translation>
</message>
<message>
+ <location line="+6"/>
<source>Matches are case insensitive</source>
- <translation type="unfinished"></translation>
+ <translation>Matchningar är skiftlägesokänsliga</translation>
</message>
<message>
+ <location line="+4"/>
<source>Whitespace characters are removed, except when they appear in character classes</source>
- <translation type="unfinished"></translation>
+ <translation>Icke-utskrivbara tecken tas bort, förutom när de finns i teckenklasser</translation>
</message>
<message>
+ <location line="+100"/>
<source>%1 is an invalid regular expression pattern: %2</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är ett ogiltigt reguljärt uttrycksmönster: %2</translation>
</message>
<message>
+ <location line="+30"/>
<source>%1 is an invalid flag for regular expressions. Valid flags are:</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är en ogiltig flagga för reguljära uttryck. Giltiga flaggor är:</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/functions/qqnamefns.cpp" line="+17"/>
<source>If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified.</source>
- <translation type="unfinished"></translation>
+ <translation>Om första argumentet är den tomma sekvensen eller en noll-längdssträng (ingen namnrymd) kan ett prefix inte anges. Prefixet %1 angavs.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/functions/qsequencefns.cpp" line="+346"/>
<source>It will not be possible to retrieve %1.</source>
- <translation type="unfinished"></translation>
+ <translation>Det var inte möjligt att hämta %1.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/functions/qcontextnodechecker.cpp" line="+54"/>
<source>The root node of the second argument to function %1 must be a document node. %2 is not a document node.</source>
- <translation type="unfinished"></translation>
+ <translation>Rotnoden för det andra argumentet till funktionen %1 måste vara en dokumentnod. %2 är inte en dokumentnod.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/functions/qsequencegeneratingfns.cpp" line="+266"/>
<source>The default collection is undefined</source>
- <translation type="unfinished"></translation>
+ <translation>Standardsamlingen är inte definierad</translation>
</message>
<message>
+ <location line="+13"/>
<source>%1 cannot be retrieved</source>
- <translation type="unfinished"></translation>
+ <translation>%1 kan inte hämtas</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/functions/qstringvaluefns.cpp" line="+252"/>
<source>The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization).</source>
- <translation type="unfinished"></translation>
+ <translation>Normaliseringsformatet %1 stöds inte. De format som stöds är %2, %3, %4 och %5, samt none, alltså den tomma strängen (ingen normalisering).</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/functions/qtimezonefns.cpp" line="+87"/>
<source>A zone offset must be in the range %1..%2 inclusive. %3 is out of range.</source>
- <translation type="unfinished"></translation>
+ <translation>En zonposition måste vara inom intervallet %1..%2 inklusive. %3 är utanför intervallet.</translation>
</message>
<message>
+ <location line="+12"/>
<source>%1 is not a whole number of minutes.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är inte en helt antal minuter.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/janitors/qcardinalityverifier.cpp" line="+58"/>
<source>Required cardinality is %1; got cardinality %2.</source>
- <translation type="unfinished"></translation>
+ <translation>Nödvändig cardinality är %1; fick cardinality %2.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/janitors/qitemverifier.cpp" line="+67"/>
<source>The item %1 did not match the required type %2.</source>
- <translation type="unfinished"></translation>
+ <translation>Objektet %1 matchade inte den nödvändiga typen %2.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/parser/qquerytransformparser.cpp" line="+352"/>
+ <location line="+7323"/>
<source>%1 is an unknown schema type.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är en okänd schematyp.</translation>
</message>
<message>
+ <location line="-7041"/>
<source>Only one %1 declaration can occur in the query prolog.</source>
- <translation type="unfinished"></translation>
+ <translation>Endast en %1-deklaration kan ske i frågesatsprologen.</translation>
</message>
<message>
+ <location line="+188"/>
<source>The initialization of variable %1 depends on itself</source>
- <translation type="unfinished"></translation>
+ <translation>Initiering av variabeln %1 är beroende av sig själv</translation>
</message>
<message>
<source>No variable by name %1 exists</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Ingen variabel med namnet %1 finns</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/parser/qparsercontext.cpp" line="+93"/>
<source>The variable %1 is unused</source>
- <translation type="unfinished"></translation>
+ <translation>Variablen %1 är oanvänd</translation>
+ </message>
+ <message>
+ <location filename="../src/xmlpatterns/parser/qquerytransformparser.cpp" line="-527"/>
+ <source>W3C XML Schema identity constraint selector</source>
+ <translation>W3C XML Schema identitetsbegränsningsväljare</translation>
</message>
<message>
+ <location line="+3"/>
+ <source>W3C XML Schema identity constraint field</source>
+ <translation>W3C XML Schema identitetsbegränsningsfält</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>A construct was encountered which is disallowed in the current language(%1).</source>
+ <translation>En skapelse påträffades som inte är tillåten i nuvarande språk (%1).</translation>
+ </message>
+ <message>
+ <location line="+119"/>
+ <source>A template with name %1 has already been declared.</source>
+ <translation>En mall med namnet %1 har redan deklarerats.</translation>
+ </message>
+ <message>
+ <location line="+464"/>
+ <source>No variable with name %1 exists</source>
+ <translation>Ingen variabel med namnet %1 finns</translation>
+ </message>
+ <message>
+ <location line="+2841"/>
<source>Version %1 is not supported. The supported XQuery version is 1.0.</source>
- <translation type="unfinished"></translation>
+ <translation>Version %1 stöds inte. Version som stöds är XQuery 1.0.</translation>
</message>
<message>
+ <location line="+16"/>
<source>The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2.</source>
- <translation type="unfinished"></translation>
+ <translation>Teckenkodningen %1 är ogiltig. Den får endast innehålla latinska tecken och utskrivbara tecken samt måste matcha det reguljära uttrycket %2.</translation>
</message>
<message>
+ <location line="+55"/>
<source>No function with signature %1 is available</source>
- <translation type="unfinished"></translation>
+ <translation>Ingen funktion med signaturen %1 finns tillgänglig</translation>
</message>
<message>
+ <location line="+72"/>
+ <location line="+10"/>
<source>A default namespace declaration must occur before function, variable, and option declarations.</source>
- <translation type="unfinished"></translation>
+ <translation>En standardnamnrymdsdeklaration måste ske innan deklarationer av function, variable och option.</translation>
</message>
<message>
+ <location line="+10"/>
<source>Namespace declarations must occur before function, variable, and option declarations.</source>
- <translation type="unfinished"></translation>
+ <translation>Namnrymdsdeklarationer måste ske innan deklarationer av function, variable och option.</translation>
</message>
<message>
+ <location line="+11"/>
<source>Module imports must occur before function, variable, and option declarations.</source>
- <translation type="unfinished"></translation>
+ <translation>Modulimporter måste ske innan deklarationer av function, variable och option.</translation>
</message>
<message>
+ <location line="+102"/>
+ <source>The keyword %1 cannot occur with any other mode name.</source>
+ <translation>Nyckelordet %1 kan inte förekomma med något annat lägesnamn.</translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>The value of attribute %1 must be of type %2, which %3 isn&apos;t.</source>
+ <translation>Värdet av egenskapen %1 måste ha typen %2, vilket %3 inte har.</translation>
+ </message>
+ <message>
+ <location line="+69"/>
<source>It is not possible to redeclare prefix %1.</source>
- <translation type="unfinished"></translation>
+ <translation>Det är inte möjligt att deklarera om prefixet %1.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>The prefix %1 cannot be bound. By default, it is already bound to the namespace %2.</source>
+ <translation>Prefixet %1 kan inte bindas. Normalt är det redan bundet till namnrymden %2.</translation>
+ </message>
+ <message>
+ <location line="+312"/>
+ <source>A variable with name %1 has already been declared.</source>
+ <translation>En variabel med namnet %1 har redan deklarerats.</translation>
+ </message>
+ <message>
+ <location line="+39"/>
+ <source>No value is available for the external variable with name %1.</source>
+ <translation>Något värde är inte tillgängligt för den externa variabeln med namnet %1.</translation>
+ </message>
+ <message>
+ <location line="+96"/>
+ <source>A stylesheet function must have a prefixed name.</source>
+ <translation>En funktion i en stilmall måste ha ett namn med prefix.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this)</source>
+ <translation>Namnrymden för en användardefinierad funktion kan inte vara tom (försök med det fördefinierade prefixet %1, som finns för dessa fall)</translation>
+ </message>
+ <message>
+ <location line="+115"/>
+ <source>An argument with name %1 has already been declared. Every argument name must be unique.</source>
+ <translation>Ett argument med namnet %1 har redan deklarerats. Varje argumentnamn måste vara unikt.</translation>
+ </message>
+ <message>
+ <location line="+179"/>
+ <source>When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal.</source>
+ <translation>När funktionen %1 används för att matcha inne i ett mönster, måste argumentet vara en variabelreferens eller en stränglitteral.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching.</source>
+ <translation>I ett XSL-T mönster måste första argumentet till funktionen %1 vara en stränglitteral, vid användning för matchning.</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching.</source>
+ <translation>I ett XSL-T mönster måste första argumentet till funktionen %1 vara en litteral eller variabelreferens, vid användning för matchning.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>In an XSL-T pattern, function %1 cannot have a third argument.</source>
+ <translation>I ett XSL-T mönster kan inte funktionen %1 ha ett tredje argument.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching.</source>
+ <translation>I ett XSL-T mönster kan bara funktionerna %1 och %2, inte %3, användas för matchning.</translation>
+ </message>
+ <message>
+ <location line="+63"/>
+ <source>In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can.</source>
+ <translation>I ett XSL-T mönster kan inte axeln %1 användas, utan bara axlarna %2 eller %3.</translation>
+ </message>
+ <message>
+ <location line="+126"/>
+ <source>%1 is an invalid template mode name.</source>
+ <translation>%1 är ett ogiltigt lägesnamn för mallen.</translation>
+ </message>
+ <message>
+ <location line="+1593"/>
+ <source>No function with name %1 is available.</source>
+ <translation>Någon funktion med namnet %1 är inte tillgänglig.</translation>
+ </message>
+ <message>
+ <location line="+250"/>
+ <source>An attribute with name %1 has already appeared on this element.</source>
+ <translation>En egenskap med namnet %1 har redan funnits för den här komponenten.</translation>
+ </message>
+ <message>
+ <location line="+614"/>
+ <source>%1 is not a valid name for a processing-instruction.</source>
+ <translation>%1 är inte ett giltigt namn för en behandlingsinstruktion.</translation>
</message>
<message>
<source>Only the prefix %1 can be declared to bind the namespace %2. By default, it is already bound to the prefix %1.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Endast prefixet %1 kan deklareras för att binda namnrymden %2. Den är som standard redan bunden till prefixet %1.</translation>
</message>
<message>
+ <location line="-3428"/>
<source>Prefix %1 is already declared in the prolog.</source>
- <translation type="unfinished"></translation>
+ <translation>Prefixet %1 är redan deklarerat i prologen.</translation>
</message>
<message>
+ <location line="+95"/>
<source>The name of an option must have a prefix. There is no default namespace for options.</source>
- <translation type="unfinished"></translation>
+ <translation>Namnet för option måste ha ett prefix. Det finns inga standardnamnrymder för dessa.</translation>
</message>
<message>
+ <location line="+171"/>
<source>The Schema Import feature is not supported, and therefore %1 declarations cannot occur.</source>
- <translation type="unfinished"></translation>
+ <translation>Funktionen Schema Import stöds inte och därför kan inte deklarationen %1 ske.</translation>
</message>
<message>
+ <location line="+13"/>
<source>The target namespace of a %1 cannot be empty.</source>
- <translation type="unfinished"></translation>
+ <translation>Målnamnrymden för en %1 får inte vara tom.</translation>
</message>
<message>
+ <location line="+8"/>
<source>The module import feature is not supported</source>
- <translation type="unfinished"></translation>
+ <translation>Funktionen för modulimport stöds inte</translation>
</message>
<message>
<source>A variable by name %1 has already been declared in the prolog.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">En variabel med namnet %1 har redan deklarerats i prologen.</translation>
</message>
<message>
<source>No value is available for the external variable by name %1.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Inget värde är tillgängligt för den externa variabeln med namnet %1.</translation>
</message>
<message>
- <source>The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this)</source>
- <translation type="unfinished"></translation>
+ <source>The namespace for a user defined function cannot be empty(try the predefined prefix %1 which exists for cases like this)</source>
+ <translation type="obsolete">Namnrymden för en användardefinierad funktion får inte vara tom(prova det fördefinierade prefixet %1 som finns för dessa situationer)</translation>
</message>
<message>
+ <location line="+166"/>
<source>The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases.</source>
- <translation type="unfinished"></translation>
+ <translation>Namnrymden %1 är reserverad; därför kan inte användardefinierade funktioner använda den. Prova det fördefinierade prefixet %2 som finns för dessa situationer.</translation>
</message>
<message>
+ <location line="+12"/>
<source>The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2</source>
- <translation type="unfinished"></translation>
+ <translation>Namnrymden för en användardefinierad funktion i en biblioteksmodul måste motsvara modulens namnrymd. Med andra ord, den måste vara %1 istället för %2</translation>
</message>
<message>
+ <location line="+34"/>
<source>A function already exists with the signature %1.</source>
- <translation type="unfinished"></translation>
+ <translation>En funktion med signaturen %1 finns redan.</translation>
</message>
<message>
+ <location line="+23"/>
<source>No external functions are supported. All supported functions can be used directly, without first declaring them as external</source>
- <translation type="unfinished"></translation>
+ <translation>Inga externa funktioner stöds. Alla funktioner som stöds kan användas direkt utan att först deklarera dem som externa</translation>
</message>
<message>
<source>An argument by name %1 has already been declared. Every argument name must be unique.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Ett argument med namnet %1 har redan deklarerats. Varje argumentnamn måste vara unikt.</translation>
</message>
<message>
+ <location line="+493"/>
<source>The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide.</source>
- <translation type="unfinished"></translation>
+ <translation>Namnet på en variabelbindning i ett for-uttryck måste skilja sig från den positionella variabeln. Därav kolliderar de två variablerna %1.</translation>
</message>
<message>
+ <location line="+778"/>
<source>The Schema Validation Feature is not supported. Hence, %1-expressions may not be used.</source>
- <translation type="unfinished"></translation>
+ <translation>Funktionen Schema Validation Feature stöds inte. Därav kan inte %1-uttryck användas.</translation>
</message>
<message>
+ <location line="+40"/>
<source>None of the pragma expressions are supported. Therefore, a fallback expression must be present</source>
- <translation type="unfinished"></translation>
+ <translation>Inga av pragma-uttrycken stöds. Därfär måste ett uttryck att falla tillbaka på finnas</translation>
+ </message>
+ <message>
+ <location line="+269"/>
+ <source>Each name of a template parameter must be unique; %1 is duplicated.</source>
+ <translation>Varje namn i en mallparameter måste vara unikt. %1 är duplicerat.</translation>
</message>
<message>
+ <location line="+129"/>
<source>The %1-axis is unsupported in XQuery</source>
- <translation type="unfinished"></translation>
+ <translation>%1-axeln stöds inte i XQuery</translation>
</message>
<message>
+ <location line="-5902"/>
<source>%1 is not a valid numeric literal.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är inte en giltig numerisk literal.</translation>
</message>
<message>
<source>No function by name %1 is available.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Ingen funktion med namnet %1 finns tillgänglig.</translation>
</message>
<message>
+ <location line="+6337"/>
<source>The namespace URI cannot be the empty string when binding to a prefix, %1.</source>
- <translation type="unfinished"></translation>
+ <translation>Namnrymds-URI:n får inte vara den tomma strängen vid bindning till ett prefix, %1.</translation>
</message>
<message>
+ <location line="+7"/>
<source>%1 is an invalid namespace URI.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är en ogiltig namnrymds-URI.</translation>
</message>
<message>
+ <location line="+6"/>
<source>It is not possible to bind to the prefix %1</source>
- <translation type="unfinished"></translation>
+ <translation>Det är inte möjligt att binda till prefixet %1</translation>
</message>
<message>
+ <location line="+7"/>
<source>Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared).</source>
- <translation type="unfinished"></translation>
+ <translation>Namnrymden %1 kan endast bindas till %2 (och den är, oavsett, fördeklarerad).</translation>
</message>
<message>
+ <location line="+8"/>
<source>Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared).</source>
- <translation type="unfinished"></translation>
+ <translation>Prefixet %1 kan endast bindas till %2 (och det är, oavsett, fördeklarerat).</translation>
</message>
<message>
+ <location line="+15"/>
<source>Two namespace declaration attributes have the same name: %1.</source>
- <translation type="unfinished"></translation>
+ <translation>Två attribut för namnrymdsdeklaration har samma namn: %1.</translation>
</message>
<message>
+ <location line="+89"/>
<source>The namespace URI must be a constant and cannot use enclosed expressions.</source>
- <translation type="unfinished"></translation>
+ <translation>Namnrymds-URI:n måste vara en constant och kan inte använda bifogade uttryck.</translation>
</message>
<message>
<source>An attribute by name %1 has already appeared on this element.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Ett attribut med namnet %1 har redan angivits i detta element.</translation>
</message>
<message>
+ <location line="+77"/>
<source>A direct element constructor is not well-formed. %1 is ended with %2.</source>
- <translation type="unfinished"></translation>
+ <translation>En direkt element constructor är inte korrekt formulerad. %1 slutar med %2.</translation>
</message>
<message>
+ <location line="+458"/>
<source>The name %1 does not refer to any schema type.</source>
- <translation type="unfinished"></translation>
+ <translation>Namnet %1 refererar inte till någon schematyp.</translation>
</message>
<message>
+ <location line="+10"/>
<source>%1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är en komplex typ. Typkonvertering till komplexa typer är inte möjlig. Dock fungerar typkonverteringar till odelbara typer såsom %2.</translation>
</message>
<message>
+ <location line="+9"/>
<source>%1 is not an atomic type. Casting is only possible to atomic types.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är inte en odelbar typ. Typkonvertering är endast möjlig för odelbara typer.</translation>
</message>
<message>
<source>%1 is not a valid name for a processing-instruction. Therefore this name test will never match.</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">%1 är inte ett giltigt namn för en processing-instruction. Därför kommer detta namntest aldrig att matcha.</translation>
</message>
<message>
+ <location line="+145"/>
+ <location line="+71"/>
<source>%1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 är inte i in-scope attributdeklarationerna. Observera att schemaimportfunktionen inte stöds.</translation>
</message>
<message>
+ <location line="+48"/>
<source>The name of an extension expression must be in a namespace.</source>
- <translation type="unfinished"></translation>
+ <translation>Namnet på ett utökningsuttryck måste finnas i en namnrymd.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/type/qcardinality.cpp" line="+55"/>
<source>empty</source>
<translation>tom</translation>
</message>
<message>
+ <location line="+2"/>
<source>zero or one</source>
<translation>noll eller en</translation>
</message>
<message>
+ <location line="+2"/>
<source>exactly one</source>
<translation>exakt en</translation>
</message>
<message>
+ <location line="+2"/>
<source>one or more</source>
- <translation>en eller mer</translation>
+ <translation>en eller mera</translation>
</message>
<message>
+ <location line="+2"/>
<source>zero or more</source>
- <translation>noll eller mer</translation>
+ <translation>noll eller mera</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/type/qtypechecker.cpp" line="+63"/>
<source>Required type is %1, but %2 was found.</source>
- <translation type="unfinished"></translation>
+ <translation>Nödvändig typ är %1 men %2 hittades.</translation>
</message>
<message>
+ <location line="+44"/>
<source>Promoting %1 to %2 may cause loss of precision.</source>
- <translation type="unfinished"></translation>
+ <translation>Promotering av %1 till %2 kan innebära minskad precision.</translation>
</message>
<message>
+ <location line="+49"/>
<source>The focus is undefined.</source>
- <translation type="unfinished"></translation>
+ <translation>Fokus är odefinierad.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/utils/qoutputvalidator.cpp" line="+86"/>
<source>It&apos;s not possible to add attributes after any other kind of node.</source>
- <translation type="unfinished"></translation>
+ <translation>Det är inte möjligt att lägga till attribut efter någon annan sorts nod.</translation>
</message>
<message>
+ <location line="+7"/>
<source>An attribute by name %1 has already been created.</source>
- <translation type="unfinished"></translation>
+ <translation>Ett attribut med namnet %1 har redan skapats.</translation>
</message>
<message>
+ <location filename="../src/xmlpatterns/utils/qxpathhelper_p.h" line="+120"/>
<source>Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported.</source>
- <translation type="unfinished"></translation>
+ <translation>Endast Unicode Codepoint Collation stöds(%1). %2 stöds inte.</translation>
</message>
-</context>
-<context>
- <name>VolumeSlider</name>
<message>
- <source>Muted</source>
- <translation>Tyst</translation>
+ <location filename="../src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp" line="+344"/>
+ <source>%1 is an unsupported encoding.</source>
+ <translation>%1 är en ogiltig kodning.</translation>
</message>
<message>
- <source>Volume: %1%</source>
- <translation>Volym: %1%</translation>
+ <location line="+16"/>
+ <source>%1 contains octets which are disallowed in the requested encoding %2.</source>
+ <translation>%1 innehåller oktetter som inte godkänns i den begärda kodningen %2.</translation>
</message>
-</context>
-<context>
- <name>WebCore::PlatformScrollbar</name>
<message>
- <source>Scroll here</source>
- <translation>Rulla här</translation>
+ <location line="+18"/>
+ <source>The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character.</source>
+ <translation>Kodvärdet %1, som förekommer i %2 med kodningen %3, är ett ogiltigt XML-tecken.</translation>
</message>
<message>
- <source>Left edge</source>
- <translation>Vänsterkant</translation>
+ <location filename="../src/xmlpatterns/expr/qapplytemplate.cpp" line="+119"/>
+ <source>Ambiguous rule match.</source>
+ <translation>Tvetydig regelträff.</translation>
</message>
<message>
- <source>Top</source>
- <translation>Överkant</translation>
+ <location filename="../src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp" line="+69"/>
+ <source>In a namespace constructor, the value for a namespace cannot be an empty string.</source>
+ <translation>I en namnrymdskonstruktor kan inte namnrymdens värde vara en tom sträng.</translation>
</message>
<message>
- <source>Right edge</source>
- <translation>Högerkant</translation>
+ <location line="+11"/>
+ <source>The prefix must be a valid %1, which %2 is not.</source>
+ <translation>Prefixet måste vara giltig %1, vilket %2 inte är.</translation>
</message>
<message>
- <source>Bottom</source>
- <translation>Nederkant</translation>
+ <location line="+14"/>
+ <source>The prefix %1 cannot be bound.</source>
+ <translation>Prefixet %1 kan inte bindas.</translation>
</message>
<message>
- <source>Page left</source>
- <translation>Sida vänster</translation>
+ <location line="+10"/>
+ <source>Only the prefix %1 can be bound to %2 and vice versa.</source>
+ <translation>Bara prefixet %1 kan bindas till %2 och tvärtom.</translation>
</message>
<message>
- <source>Page up</source>
- <translation>Sida uppåt</translation>
+ <location filename="../src/xmlpatterns/expr/qtemplate.cpp" line="+74"/>
+ <source>The parameter %1 is passed, but no corresponding %2 exists.</source>
+ <translation>Parametern %1 skickades, men motsvarande %2 finns inte.</translation>
</message>
<message>
- <source>Page right</source>
- <translation>Sida höger</translation>
+ <location line="+71"/>
+ <source>The parameter %1 is required, but no corresponding %2 is supplied.</source>
+ <translation>Parametern %1 krävs, men motsvarande %2 tillhandahålls inte.</translation>
</message>
<message>
- <source>Page down</source>
- <translation>Sida nedåt</translation>
+ <location filename="../src/xmlpatterns/functions/qunparsedtextfn.cpp" line="+65"/>
+ <source>The URI cannot have a fragment</source>
+ <translation>Webbadressen kan inte innehålla ett fragment</translation>
</message>
<message>
- <source>Scroll left</source>
- <translation>Rulla vänster</translation>
+ <location filename="../src/xmlpatterns/parser/qxslttokenizer.cpp" line="+519"/>
+ <source>Element %1 is not allowed at this location.</source>
+ <translation>Komponenten %1 är inte tillåten på den här platsen.</translation>
</message>
<message>
- <source>Scroll up</source>
- <translation>Rulla uppåt</translation>
+ <location line="+9"/>
+ <source>Text nodes are not allowed at this location.</source>
+ <translation>Textnoder är inte tillåtna på den här platsen.</translation>
</message>
<message>
- <source>Scroll right</source>
- <translation>Rulla höger</translation>
+ <location line="+20"/>
+ <source>Parse error: %1</source>
+ <translation>Tolkningsfel: %1</translation>
</message>
<message>
- <source>Scroll down</source>
- <translation>Rulla nedåt</translation>
+ <location line="+62"/>
+ <source>The value of the XSL-T version attribute must be a value of type %1, which %2 isn&apos;t.</source>
+ <translation>Värdet av XSL-T versionsegenskapen måste vara ett värde av typen %1, vilket %2 inte är.</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>Running an XSL-T 1.0 stylesheet with a 2.0 processor.</source>
+ <translation>Kör en XSL-T 1.0 stilmall med en 2.0 behandlingsenhet.</translation>
+ </message>
+ <message>
+ <location line="+108"/>
+ <source>Unknown XSL-T attribute %1.</source>
+ <translation>Okänd XSL-T egenskap %1.</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Attribute %1 and %2 are mutually exclusive.</source>
+ <translation>Egenskaperna %1 och %2 är ömsesidigt uteslutande.</translation>
+ </message>
+ <message>
+ <location line="+166"/>
+ <source>In a simplified stylesheet module, attribute %1 must be present.</source>
+ <translation>I en förenklad stilmallsmodul måste egenskapen %1 ingå.</translation>
+ </message>
+ <message>
+ <location line="+72"/>
+ <source>If element %1 has no attribute %2, it cannot have attribute %3 or %4.</source>
+ <translation>Om komponenten %1 inte har egenskapen %2, kan den inte ha egenskapen %3 eller %4.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Element %1 must have at least one of the attributes %2 or %3.</source>
+ <translation>Komponenten %1 måste ha minst en av egenskaperna %2 eller %3.</translation>
+ </message>
+ <message>
+ <location line="+28"/>
+ <source>At least one mode must be specified in the %1-attribute on element %2.</source>
+ <translation>Åtminstone ett läge måste anges i egenskapen %1 i komponenten %2.</translation>
+ </message>
+ <message>
+ <location line="+123"/>
+ <source>Element %1 must come last.</source>
+ <translation>Komponenten %1 måste komma sist.</translation>
+ </message>
+ <message>
+ <location line="+24"/>
+ <source>At least one %1-element must occur before %2.</source>
+ <translation>Åtminstone en %1-komponent måste förekomma innan %2.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Only one %1-element can appear.</source>
+ <translation>Bara en %1-komponent kan förekomma.</translation>
+ </message>
+ <message>
+ <location line="+31"/>
+ <source>At least one %1-element must occur inside %2.</source>
+ <translation>Åtminstone en %1-komponent måste förekomma inne i %2.</translation>
+ </message>
+ <message>
+ <location line="+58"/>
+ <source>When attribute %1 is present on %2, a sequence constructor cannot be used.</source>
+ <translation>När egenskapen %1 är närvarande i %2, kan inte en sekvenskonstruktor användas.</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Element %1 must have either a %2-attribute or a sequence constructor.</source>
+ <translation>Komponenten %1 måste antingen ha en %2-egenskap eller en sekvenskonstruktor.</translation>
+ </message>
+ <message>
+ <location line="+125"/>
+ <source>When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor.</source>
+ <translation>När en parameter krävs, kan inte ett förvalt värde tillhandahållas via en %1-egenskap eller en sekvenskonstruktor.</translation>
+ </message>
+ <message>
+ <location line="+270"/>
+ <source>Element %1 cannot have children.</source>
+ <translation>Komponenten %1 kan inte ha några underliggande objekt.</translation>
+ </message>
+ <message>
+ <location line="+434"/>
+ <source>Element %1 cannot have a sequence constructor.</source>
+ <translation>Komponenten %1 kan inte ha en sekvenskonstruktor.</translation>
+ </message>
+ <message>
+ <location line="+86"/>
+ <location line="+9"/>
+ <source>The attribute %1 cannot appear on %2, when it is a child of %3.</source>
+ <translation>Egenskapen %1 kan inte finnas i %2, när den är underliggande till %3.</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>A parameter in a function cannot be declared to be a tunnel.</source>
+ <translation>En parameter i en funktion kan inte deklareras att vara en tunnel.</translation>
+ </message>
+ <message>
+ <location line="+149"/>
+ <source>This processor is not Schema-aware and therefore %1 cannot be used.</source>
+ <translation>Behandlingsenheten känner inte till Schema, och därför kan inte %1 användas.</translation>
+ </message>
+ <message>
+ <location line="+57"/>
+ <source>Top level stylesheet elements must be in a non-null namespace, which %1 isn&apos;t.</source>
+ <translation>Komponenter på stilmallens toppnivå får inte vara i namnrymden null, vilket %1 är.</translation>
+ </message>
+ <message>
+ <location line="+48"/>
+ <source>The value for attribute %1 on element %2 must either be %3 or %4, not %5.</source>
+ <translation>Värdet på egenskapen %1 i komponenten %2 måste antingen vara %3 eller %4, inte %5.</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>Attribute %1 cannot have the value %2.</source>
+ <translation>Egenskapen %1 kan inte ha värdet %2.</translation>
+ </message>
+ <message>
+ <location line="+58"/>
+ <source>The attribute %1 can only appear on the first %2 element.</source>
+ <translation>Egenskapen %1 kan bara förekomma i den första %2-komponenten.</translation>
+ </message>
+ <message>
+ <location line="+99"/>
+ <source>At least one %1 element must appear as child of %2.</source>
+ <translation>Åtminstone en %1-komponent måste finnas som underliggande komponent till %2.</translation>
+ </message>
+ <message>
+ <location filename="../src/xmlpatterns/schema/qxsdparticlechecker.cpp" line="+165"/>
+ <source>Empty particle cannot be derived from non-empty particle.</source>
+ <translation>Tom partikel kan inte härledas från icke-tom partikel.</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Derived particle is missing element %1.</source>
+ <translation>Härledd partikel saknar komponenten %1.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Derived element %1 is missing value constraint as defined in base particle.</source>
+ <translation>Härledd komponent %1 saknar värdebegränsning som definierad i baspartikeln.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Derived element %1 has weaker value constraint than base particle.</source>
+ <translation>Härledd komponent %1 har svagare värdebegränsning än baspartikeln.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Fixed value constraint of element %1 differs from value constraint in base particle.</source>
+ <translation>Fast värdebegränsning i komponenten %1 skiljer sig från värdebegränsning i baspartikeln.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Derived element %1 cannot be nillable as base element is not nillable.</source>
+ <translation>Härledd komponent %1 kan inte tilldelas noll, eftersom baskomponenten inte kan det.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Block constraints of derived element %1 must not be more weaker than in the base element.</source>
+ <translation>Blockbegränsning för härledd komponent %1 får inte vara mycket svagare än i baskomponenten.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Simple type of derived element %1 cannot be validly derived from base element.</source>
+ <translation>Enkel typ av härledd komponent %1 kan inte giltigt härledas från baskomponent.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Complex type of derived element %1 cannot be validly derived from base element.</source>
+ <translation>Komplex typ av härledd komponent %1 kan inte giltigt härledas från baskomponent.</translation>
+ </message>
+ <message>
+ <location line="+24"/>
+ <source>Element %1 is missing in derived particle.</source>
+ <translation>Komponenten %1 saknas i härledd partikel.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Element %1 does not match namespace constraint of wildcard in base particle.</source>
+ <translation>Komponenten %1 motsvarar inte namnrymdsbegränsning för jokertecken i baspartikel.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Wildcard in derived particle is not a valid subset of wildcard in base particle.</source>
+ <translation>Jokertecken i härledd partikel är inte en giltig delmängd av jokertecknen i baspartikeln.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>processContent of wildcard in derived particle is weaker than wildcard in base particle.</source>
+ <translation>Processinnehåll i jokertecken för härledd partikel är svagare än jokertecken i baspartikeln.</translation>
+ </message>
+ <message>
+ <location line="+270"/>
+ <source>Derived particle allows content that is not allowed in the base particle.</source>
+ <translation>Härledd partikel tillåter innehåll som inte tillåts i baspartikeln.</translation>
+ </message>
+ <message>
+ <location filename="../src/xmlpatterns/schema/qxsdschemachecker.cpp" line="+227"/>
+ <source>%1 has inheritance loop in its base type %2.</source>
+ <translation>%1 har ett cirkulärt arv i dess bastyp %2.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <location line="+24"/>
+ <source>Circular inheritance of base type %1.</source>
+ <translation>Cirkulärt arv för bastyp %1.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Circular inheritance of union %1.</source>
+ <translation>Cirkulärt arv av union %1.</translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>%1 is not allowed to derive from %2 by restriction as the latter defines it as final.</source>
+ <translation>%1 tillåts inte härleda från %2 med begränsning, eftersom den senare definierar den som slutgiltig.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>%1 is not allowed to derive from %2 by extension as the latter defines it as final.</source>
+ <translation>%1 tillåts inte härleda från %2 med begränsning, eftersom den senare definierar den som slutgiltig.</translation>
+ </message>
+ <message>
+ <location line="+31"/>
+ <source>Base type of simple type %1 cannot be complex type %2.</source>
+ <translation>Bastyp av enkel typ %1 kan inte vara en komplex typ %2.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Simple type %1 cannot have direct base type %2.</source>
+ <translation>Enkel typ %1 kan inte ha direkt bastyp %2.</translation>
+ </message>
+ <message>
+ <location line="+33"/>
+ <location line="+9"/>
+ <source>Simple type %1 is not allowed to have base type %2.</source>
+ <translation>Enkel typ %1 tillåts inte ha bastyp %2.</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>Simple type %1 can only have simple atomic type as base type.</source>
+ <translation>Enkel typ %1 kan bara ha enkel atomär typ som bastyp.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Simple type %1 cannot derive from %2 as the latter defines restriction as final.</source>
+ <translation>Enkel typ %1 kan inte härleda från %2 eftersom den senare definierar begränsning som slutgiltig.</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <location line="+484"/>
+ <source>Variety of item type of %1 must be either atomic or union.</source>
+ <translation>Variation av objekttyp för %1 måste antingen vara atomär eller union.</translation>
+ </message>
+ <message>
+ <location line="-474"/>
+ <location line="+483"/>
+ <source>Variety of member types of %1 must be atomic.</source>
+ <translation>Variation av medlemstyper för %1 måste vara atomära.</translation>
+ </message>
+ <message>
+ <location line="-470"/>
+ <location line="+451"/>
+ <source>%1 is not allowed to derive from %2 by list as the latter defines it as final.</source>
+ <translation>%1 tillåts inte härleda från %2 med lista, eftersom den senare definierar den som slutgiltig.</translation>
+ </message>
+ <message>
+ <location line="-431"/>
+ <source>Simple type %1 is only allowed to have %2 facet.</source>
+ <translation>Enkel typ %1 tillåts bara ha aspekten %2.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Base type of simple type %1 must have variety of type list.</source>
+ <translation>Bastyp av enkel typ %1 måste ha variation av typ lista.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Base type of simple type %1 has defined derivation by restriction as final.</source>
+ <translation>Bastyp av enkel typ %1 har definierat härledning med begränsning som slutgiltig.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Item type of base type does not match item type of %1.</source>
+ <translation>Objekttyp av bastyp motsvarar inte objekttyp av %1.</translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <location line="+93"/>
+ <source>Simple type %1 contains not allowed facet type %2.</source>
+ <translation>Enkel typ %1 innehåller aspekttyp %2 som inte tillåts.</translation>
+ </message>
+ <message>
+ <location line="-72"/>
+ <location line="+413"/>
+ <source>%1 is not allowed to derive from %2 by union as the latter defines it as final.</source>
+ <translation>%1 tillåts inte härleda från %2 med union, eftersom den senare definierar den som slutgiltig.</translation>
+ </message>
+ <message>
+ <location line="-404"/>
+ <source>%1 is not allowed to have any facets.</source>
+ <translation>%1 tillåts inte ha några aspekter.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Base type %1 of simple type %2 must have variety of union.</source>
+ <translation>Bastyp %1 av enkel typ %2 måste ha variationen union.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute.</source>
+ <translation>Bastyp %1 av enkel typ %2 tillåts inte ha begränsning i egenskap %3.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Member type %1 cannot be derived from member type %2 of %3&apos;s base type %4.</source>
+ <translation>Medlemstypen %1 kan inte härledas från medlemstypen %2 av bastypen %4 för %3.</translation>
+ </message>
+ <message>
+ <location line="+65"/>
+ <source>Derivation method of %1 must be extension because the base type %2 is a simple type.</source>
+ <translation>Härledningsmetod för %1 måste vara utökning, eftersom bastypen %2 är en enkel typ.</translation>
+ </message>
+ <message>
+ <location line="+30"/>
+ <source>Complex type %1 has duplicated element %2 in its content model.</source>
+ <translation>Komplex typ %1 har duplicerade komponenten %2 i sin innehållsmodell.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Complex type %1 has non-deterministic content.</source>
+ <translation>Komplex typ %1 har icke-deterministiskt innehåll.</translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3.</source>
+ <translation>Egenskapen för den komplexa typen %1 är inte en giltig utökning av egenskaperna för bastypen %2: %3.</translation>
+ </message>
+ <message>
+ <location line="+37"/>
+ <source>Content model of complex type %1 is not a valid extension of content model of %2.</source>
+ <translation>Innehållsmodellen för komplex typ %1 är inte en giltig utökning av innehållsmodellen för %2.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Complex type %1 must have simple content.</source>
+ <translation>Komplex typ %1 måste ha enkelt innehåll.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Complex type %1 must have the same simple type as its base class %2.</source>
+ <translation>Komplex typ %1 måste ha samma enkla typ som dess basklass %2.</translation>
+ </message>
+ <message>
+ <location line="+67"/>
+ <source>Complex type %1 cannot be derived from base type %2%3.</source>
+ <translation>Komplex typ %1 kan inte härledas från bastyp %2%3.</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3.</source>
+ <translation>Egenskaper för komplex typ %1 är inte en giltig begränsning från egenskaper för bastypen %2: %3.</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Complex type %1 with simple content cannot be derived from complex base type %2.</source>
+ <translation>Komplex typ %1 med enkelt innehåll kan inte härledas från komplex bastyp %2.</translation>
+ </message>
+ <message>
+ <location line="+35"/>
+ <source>Item type of simple type %1 cannot be a complex type.</source>
+ <translation>Objekttyp av enkel typ %1 kan inte vara en komplex typ.</translation>
+ </message>
+ <message>
+ <location line="+44"/>
+ <source>Member type of simple type %1 cannot be a complex type.</source>
+ <translation>Medlemstyp av enkel typ %1 kan inte vara en komplex typ.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>%1 is not allowed to have a member type with the same name as itself.</source>
+ <translation>%1 tillåts inte ha en medlemstyp av samma namn som den själv.</translation>
+ </message>
+ <message>
+ <location line="+83"/>
+ <location line="+29"/>
+ <location line="+34"/>
+ <source>%1 facet collides with %2 facet.</source>
+ <translation>Aspekt %1 kolliderar med aspekt %2.</translation>
+ </message>
+ <message>
+ <location line="-20"/>
+ <source>%1 facet must have the same value as %2 facet of base type.</source>
+ <translation>Aspekt %1 måste ha samma värde som aspekt %2 av bastypen.</translation>
+ </message>
+ <message>
+ <location line="+37"/>
+ <source>%1 facet must be equal or greater than %2 facet of base type.</source>
+ <translation>Aspekt %1 måste vara större än eller lika med aspekt %2 av bastypen.</translation>
+ </message>
+ <message>
+ <location line="+19"/>
+ <location line="+125"/>
+ <location line="+55"/>
+ <location line="+12"/>
+ <location line="+91"/>
+ <location line="+58"/>
+ <location line="+34"/>
+ <location line="+35"/>
+ <source>%1 facet must be less than or equal to %2 facet of base type.</source>
+ <translation>Aspekt %1 måste vara mindre än eller lika med aspekt %2 av bastypen.</translation>
+ </message>
+ <message>
+ <location line="-389"/>
+ <source>%1 facet contains invalid regular expression</source>
+ <translation>Aspekt %1 innehåller ogiltigt reguljärt uttryck</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Unknown notation %1 used in %2 facet.</source>
+ <translation>Okänd notation %1 använd i aspekten %2.</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>%1 facet contains invalid value %2: %3.</source>
+ <translation>Aspekten %1 innehåller ogiltigt värde %2: %3.</translation>
+ </message>
+ <message>
+ <location line="+22"/>
+ <source>%1 facet cannot be %2 or %3 if %4 facet of base type is %5.</source>
+ <translation>Aspekten %1 kan inte vara %2 eller %3 om aspekten %4 av bastypen är %5.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>%1 facet cannot be %2 if %3 facet of base type is %4.</source>
+ <translation>Aspekten %1 kan inte vara %2 om aspekten %3 av bastypen är %4.</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <location line="+55"/>
+ <location line="+230"/>
+ <source>%1 facet must be less than or equal to %2 facet.</source>
+ <translation>Aspekten %1 måste vara mindre än eller lika med aspekten %2.</translation>
+ </message>
+ <message>
+ <location line="-257"/>
+ <location line="+134"/>
+ <location line="+82"/>
+ <source>%1 facet must be less than %2 facet of base type.</source>
+ <translation>Aspekten %1 måste vara mindre än bastypens aspekt %2.</translation>
+ </message>
+ <message>
+ <location line="-201"/>
+ <location line="+79"/>
+ <source>%1 facet and %2 facet cannot appear together.</source>
+ <translation>Aspekten %1 och aspekten %2 kan inte uppträda tillsammans.</translation>
+ </message>
+ <message>
+ <location line="-27"/>
+ <location line="+12"/>
+ <location line="+113"/>
+ <source>%1 facet must be greater than %2 facet of base type.</source>
+ <translation>Aspekten %1 måste vara större än bastypens aspekt %2.</translation>
+ </message>
+ <message>
+ <location line="-86"/>
+ <location line="+58"/>
+ <source>%1 facet must be less than %2 facet.</source>
+ <translation>Aspekten %1 måste vara mindre än aspekten %2.</translation>
+ </message>
+ <message>
+ <location line="-42"/>
+ <location line="+58"/>
+ <source>%1 facet must be greater than or equal to %2 facet of base type.</source>
+ <translation>Aspekten %1 måste vara större än eller lika med bastypens aspekt %2.</translation>
+ </message>
+ <message>
+ <location line="+113"/>
+ <source>Simple type contains not allowed facet %1.</source>
+ <translation>Enkel typ innehåller aspekten %1 som inte är tillåten.</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>%1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list.</source>
+ <translation>Aspekterna %1, %2, %3, %4, %5 och %6 är inte tillåtna vid härledning från lista.</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Only %1 and %2 facets are allowed when derived by union.</source>
+ <translation>Bara aspekterna %1 och %2 är tillåtna vid härledning från union.</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <location line="+16"/>
+ <source>%1 contains %2 facet with invalid data: %3.</source>
+ <translation>%1 innehåller aspekten %2 med ogiltig data: %3.</translation>
+ </message>
+ <message>
+ <location line="+24"/>
+ <source>Attribute group %1 contains attribute %2 twice.</source>
+ <translation>Egenskapsgruppen %1 innehåller egenskapen %2 två gånger.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Attribute group %1 contains two different attributes that both have types derived from %2.</source>
+ <translation>Egenskapsgruppen %1 innehåller två olika egenskaper som båda har typer härledda från %2.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3.</source>
+ <translation>Egenskapsgruppen %1 innehåller egenskapen %2 som har en värdebegränsning men en typ som ärver från %3.</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Complex type %1 contains attribute %2 twice.</source>
+ <translation>Komplex typ %1 innehåller egenskapen %2 två gånger.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Complex type %1 contains two different attributes that both have types derived from %2.</source>
+ <translation>Komplex typ %1 innehåller två olika egenskaper som båda har typer härledda från %2.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3.</source>
+ <translation>Komplex typ %1 innehåller egenskapen %2 som har en värdebegränsning men en typ som ärver från %3.</translation>
+ </message>
+ <message>
+ <location line="+43"/>
+ <source>Element %1 is not allowed to have a value constraint if its base type is complex.</source>
+ <translation>Komponenten %1 tillåts inte ha en värdebegränsning om dess bastyp är komplex.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Element %1 is not allowed to have a value constraint if its type is derived from %2.</source>
+ <translation>Komponenten %1 tillåts inte ha en värdebegränsning om dess typ är härledd från %2.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <location line="+11"/>
+ <source>Value constraint of element %1 is not of elements type: %2.</source>
+ <translation>Värdebegränsning för komponenten %1 har inte komponentens typ: %2.</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Element %1 is not allowed to have substitution group affiliation as it is no global element.</source>
+ <translation>Komponenten %1 tillåts inte ha tillhörighet som ersättningsgrupp eftersom den inte är en global komponent.</translation>
+ </message>
+ <message>
+ <location line="+28"/>
+ <source>Type of element %1 cannot be derived from type of substitution group affiliation.</source>
+ <translation>Typ för komponenten %1 kan inte härledas från typ för ersättningsgruppens tillhörighet.</translation>
+ </message>
+ <message>
+ <location line="+41"/>
+ <source>Value constraint of attribute %1 is not of attributes type: %2.</source>
+ <translation>Värdebegränsning för egenskapen %1 har inte egenskapens typ: %2.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Attribute %1 has value constraint but has type derived from %2.</source>
+ <translation>Egenskapen %1 har en värdebegränsning men har en typ härledd från %2.</translation>
+ </message>
+ <message>
+ <location line="+56"/>
+ <source>%1 attribute in derived complex type must be %2 like in base type.</source>
+ <translation>Egenskapen %1 i härledd komplex typ måste vara %2 som i bastypen.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Attribute %1 in derived complex type must have %2 value constraint like in base type.</source>
+ <translation>Egenskapen %1 i härledd komplex typ måste ha värdebegränsningen %2 som i bastypen.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Attribute %1 in derived complex type must have the same %2 value constraint like in base type.</source>
+ <translation>Egenskapen %1 i härledd komplex typ måste ha samma värdebegränsning %2 som i bastypen.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Attribute %1 in derived complex type must have %2 value constraint.</source>
+ <translation>Egenskapen %1 i härledd komplex typ måste ha värdebegränsningen %2.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>processContent of base wildcard must be weaker than derived wildcard.</source>
+ <translation>Processinnehåll i basjokertecken måste vara svagare än härledda jokertecken.</translation>
+ </message>
+ <message>
+ <location line="+39"/>
+ <location line="+15"/>
+ <source>Element %1 exists twice with different types.</source>
+ <translation>Komponenten %1 finns två gånger med olika typer.</translation>
+ </message>
+ <message>
+ <location line="+28"/>
+ <source>Particle contains non-deterministic wildcards.</source>
+ <translation>Partikel innehåller icke-deterministiska jokertecken.</translation>
+ </message>
+ <message>
+ <location filename="../src/xmlpatterns/schema/qxsdschemahelper.cpp" line="+691"/>
+ <location line="+63"/>
+ <source>Base attribute %1 is required but derived attribute is not.</source>
+ <translation>Basegenskap %1 krävs men härledd egenskap gör inte det.</translation>
+ </message>
+ <message>
+ <location line="-57"/>
+ <source>Type of derived attribute %1 cannot be validly derived from type of base attribute.</source>
+ <translation>Typ av härledd egenskap %1 kan inte giltigt härledas från typen hos basegenskapen.</translation>
+ </message>
+ <message>
+ <location line="+28"/>
+ <source>Value constraint of derived attribute %1 does not match value constraint of base attribute.</source>
+ <translation>Värdebegränsning för härledd egenskap %1 motsvarar inte värdebegränsning för basegenskapen.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Derived attribute %1 does not exist in the base definition.</source>
+ <translation>Härledd egenskap %1 finns inte i basdefinitionen.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Derived attribute %1 does not match the wildcard in the base definition.</source>
+ <translation>Härledd egenskap %1 motsvarar inte jokertecknen i basdefinitionen.</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Base attribute %1 is required but missing in derived definition.</source>
+ <translation>Basegenskap %1 krävs, men saknas i härledd definition.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Derived definition contains an %1 element that does not exists in the base definition</source>
+ <translation>Härledd definition innehåller komponenten %1 som inte finns i basdefinitionen</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Derived wildcard is not a subset of the base wildcard.</source>
+ <translation>Härledda jokertecken är inte en delmängd av basjokertecken.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>%1 of derived wildcard is not a valid restriction of %2 of base wildcard</source>
+ <translation>%1 i härledda jokertecken är inte en giltig begränsning för %2 i basjokertecken</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Attribute %1 from base type is missing in derived type.</source>
+ <translation>Egenskapen %1 från bastypen saknas i härledd typ.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Type of derived attribute %1 differs from type of base attribute.</source>
+ <translation>Typ för härledd egenskap %1 skiljer sig från basegenskapens typ.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Base definition contains an %1 element that is missing in the derived definition</source>
+ <translation>Basdefinitionen innehåller komponenten %1 som saknas i den härledda definitionen</translation>
+ </message>
+ <message>
+ <location filename="../src/xmlpatterns/schema/qxsdschemaparser.cpp" line="+170"/>
+ <source>Can not process unknown element %1, expected elements are: %2.</source>
+ <translation>Kan inte behandla okänd komponent %1, förväntade komponenter är: %2.</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Element %1 is not allowed in this scope, possible elements are: %2.</source>
+ <translation>Komponenten %1 är inte tillåten i det här synliga området, möjliga komponenter är: %2.</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Child element is missing in that scope, possible child elements are: %1.</source>
+ <translation>Underliggande komponent saknas i det synliga området, möjliga underliggande komponenter är: %1.</translation>
+ </message>
+ <message>
+ <location line="+143"/>
+ <source>Document is not a XML schema.</source>
+ <translation>Dokumentet är inte XML-schema.</translation>
+ </message>
+ <message>
+ <location line="+22"/>
+ <source>%1 attribute of %2 element contains invalid content: {%3} is not a value of type %4.</source>
+ <translation>Egenskapen %1 i komponenten %2 har ogiltigt innehåll: {%3} är inte ett värde av typen %4.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>%1 attribute of %2 element contains invalid content: {%3}.</source>
+ <translation>Egenskapen %1 i komponenten %2 har ogiltigt innehåll: {%3}.</translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema.</source>
+ <translation>Målnamnrymden %1 av inkluderat schema skiljer sig från målnamnrymden %2 som definieras av schemat som inkluderar det.</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <location line="+11"/>
+ <source>Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema.</source>
+ <translation>Målnamnrymden %1 av importerat schema skiljer sig från målnamnrymden %2 som definieras av schemat som importerar det.</translation>
+ </message>
+ <message>
+ <location line="+243"/>
+ <source>%1 element is not allowed to have the same %2 attribute value as the target namespace %3.</source>
+ <translation>Komponenten %1 tillåts inte ha samma egenskapsvärde %2 som målnamnrymden %3.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>%1 element without %2 attribute is not allowed inside schema without target namespace.</source>
+ <translation>Komponenten %1 utan egenskapen %2 tillåts inte inne i schema utan målnamnrymd.</translation>
+ </message>
+ <message>
+ <location line="+851"/>
+ <location line="+158"/>
+ <source>%1 element is not allowed inside %2 element if %3 attribute is present.</source>
+ <translation>Komponenten %1 tillåts inte inne i komponenten %2 om egenskapen %3 är närvarande.</translation>
+ </message>
+ <message>
+ <location line="-97"/>
+ <location line="+119"/>
+ <location line="+92"/>
+ <source>%1 element has neither %2 attribute nor %3 child element.</source>
+ <translation>Komponenten %1 har varken egenskapen %2 eller den underliggande komponenten %3.</translation>
+ </message>
+ <message>
+ <location line="+835"/>
+ <location line="+1474"/>
+ <location line="+232"/>
+ <location line="+7"/>
+ <location line="+260"/>
+ <location line="+17"/>
+ <location line="+258"/>
+ <location line="+6"/>
+ <location line="+17"/>
+ <location line="+6"/>
+ <location line="+17"/>
+ <location line="+11"/>
+ <location line="+11"/>
+ <location line="+11"/>
+ <source>%1 element with %2 child element must not have a %3 attribute.</source>
+ <translation>Komponenten %1 med den underliggande komponenten %2 får inte ha egenskapen %3.</translation>
+ </message>
+ <message>
+ <location line="-1325"/>
+ <source>%1 attribute of %2 element must be %3 or %4.</source>
+ <translation>Egenskapen %1 i komponenten %2 måste vara %3 eller %4.</translation>
+ </message>
+ <message>
+ <location line="+36"/>
+ <source>%1 attribute of %2 element must have a value of %3.</source>
+ <translation>Egenskapen %1 i komponenten %2 måste ha värdet %3.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <location line="+34"/>
+ <source>%1 attribute of %2 element must have a value of %3 or %4.</source>
+ <translation>Egenskapen %1 i komponenten %2 måste ha värdet %3 eller %4.</translation>
+ </message>
+ <message>
+ <location line="+319"/>
+ <location line="+129"/>
+ <location line="+9"/>
+ <location line="+7"/>
+ <location line="+7"/>
+ <location line="+327"/>
+ <location line="+203"/>
+ <location line="+6"/>
+ <location line="+6"/>
+ <location line="+6"/>
+ <location line="+6"/>
+ <location line="+6"/>
+ <location line="+6"/>
+ <location line="+77"/>
+ <source>%1 element must not have %2 and %3 attribute together.</source>
+ <translation>Komponenten %1 får inte ha egenskaperna %2 och %3 tillsammans.</translation>
+ </message>
+ <message>
+ <location line="-768"/>
+ <location line="+222"/>
+ <source>Content of %1 attribute of %2 element must not be from namespace %3.</source>
+ <translation>Innehållet i egenskapen %1 för komponenten %2 får inte komma från namnrymden %3.</translation>
+ </message>
+ <message>
+ <location line="-215"/>
+ <location line="+222"/>
+ <source>%1 attribute of %2 element must not be %3.</source>
+ <translation>Egenskapen %1 i komponenten %2 får inte vara %3.</translation>
+ </message>
+ <message>
+ <location line="-64"/>
+ <source>%1 attribute of %2 element must have the value %3 because the %4 attribute is set.</source>
+ <translation>Egenskapen %1 i komponenten %2 måste ha värdet %3, eftersom egenskapen %4 är tilldelad.</translation>
+ </message>
+ <message>
+ <location line="+187"/>
+ <source>Specifying use=&apos;prohibited&apos; inside an attribute group has no effect.</source>
+ <translation>Att ange use=&apos;prohibited&apos; inne i en egenskapsgrupp får ingen effekt.</translation>
+ </message>
+ <message>
+ <location line="+353"/>
+ <source>%1 element must have either %2 or %3 attribute.</source>
+ <translation>Komponenten %1 måste antingen ha egenskapen %2 eller %3.</translation>
+ </message>
+ <message>
+ <location line="+554"/>
+ <source>%1 element must have either %2 attribute or %3 or %4 as child element.</source>
+ <translation>Komponenten %1 måste antingen ha egenskapen %2 eller underliggande komponenten %3 eller %4.</translation>
+ </message>
+ <message>
+ <location line="+55"/>
+ <source>%1 element requires either %2 or %3 attribute.</source>
+ <translation>Komponenten %1 kräver antingen egenskapen %2 eller %3.</translation>
+ </message>
+ <message>
+ <location line="+19"/>
+ <source>Text or entity references not allowed inside %1 element</source>
+ <translation>Text eller objektreferenser tillåts inte inne i komponenten %1</translation>
+ </message>
+ <message>
+ <location line="+41"/>
+ <location line="+112"/>
+ <source>%1 attribute of %2 element must contain %3, %4 or a list of URIs.</source>
+ <translation>Egenskapen %1 i komponenten %2 måste innehålla %3, %4 eller en lista med webbadresser.</translation>
+ </message>
+ <message>
+ <location line="+126"/>
+ <source>%1 element is not allowed in this context.</source>
+ <translation>Komponenten %1 är inte tillåten i det här sammanhanget.</translation>
+ </message>
+ <message>
+ <location line="+53"/>
+ <source>%1 attribute of %2 element has larger value than %3 attribute.</source>
+ <translation>Egenskapen %1 i komponenten %2 har ett större värde än egenskapen %3.</translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>Prefix of qualified name %1 is not defined.</source>
+ <translation>Prefix av kvalificerat namn %1 är inte definierat.</translation>
+ </message>
+ <message>
+ <location line="+65"/>
+ <location line="+61"/>
+ <source>%1 attribute of %2 element must either contain %3 or the other values.</source>
+ <translation>Egenskapen %1 i komponenten %2 måste antingen innehålla %3 eller övriga värden.</translation>
+ </message>
+ <message>
+ <location line="+131"/>
+ <source>Component with ID %1 has been defined previously.</source>
+ <translation>Komponent med ID %1 har definierats tidigare.</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Element %1 already defined.</source>
+ <translation>Komponent %1 redan definierad.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Attribute %1 already defined.</source>
+ <translation>Egenskap %1 redan definierad.</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Type %1 already defined.</source>
+ <translation>Typ %1 redan definierad.</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Attribute group %1 already defined.</source>
+ <translation>Egenskapsgrupp %1 redan definierad.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Element group %1 already defined.</source>
+ <translation>Komponentgrupp %1 redan definierad.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Notation %1 already defined.</source>
+ <translation>Notation %1 redan definierad.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Identity constraint %1 already defined.</source>
+ <translation>Identitetsbegränsning %1 redan definierad.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Duplicated facets in simple type %1.</source>
+ <translation>Duplicerade aspekter i enkel typ %1.</translation>
+ </message>
+ <message>
+ <location filename="../src/xmlpatterns/schema/qxsdschemaresolver.cpp" line="+354"/>
+ <source>%1 references unknown %2 or %3 element %4.</source>
+ <translation>%1 refererar till okänd %2 eller %3 komponent %4.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>%1 references identity constraint %2 that is no %3 or %4 element.</source>
+ <translation>%1 refererar till identitetsbegränsning %2 som inte är en %3 eller %4 komponent.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>%1 has a different number of fields from the identity constraint %2 that it references.</source>
+ <translation>%1 har ett annat antal fält än identitetsbegränsningen %2 som den refererar till.</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Base type %1 of %2 element cannot be resolved.</source>
+ <translation>Bastypen %1 av komponenten %2 kan inte lösas upp.</translation>
+ </message>
+ <message>
+ <location line="+84"/>
+ <source>Item type %1 of %2 element cannot be resolved.</source>
+ <translation>Objekttypen %1 av komponenten %2 kan inte lösas upp.</translation>
+ </message>
+ <message>
+ <location line="+31"/>
+ <source>Member type %1 of %2 element cannot be resolved.</source>
+ <translation>Medlemstypen %1 av komponenten %2 kan inte lösas upp.</translation>
+ </message>
+ <message>
+ <location line="+28"/>
+ <location line="+415"/>
+ <location line="+30"/>
+ <source>Type %1 of %2 element cannot be resolved.</source>
+ <translation>Bastypen %1 av komponenten %2 kan inte lösas upp.</translation>
+ </message>
+ <message>
+ <location line="-423"/>
+ <source>Base type %1 of complex type cannot be resolved.</source>
+ <translation>Bastypen %1 av komplex typ kan inte lösas upp.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>%1 cannot have complex base type that has a %2.</source>
+ <translation>%1 kan inte ha komplex bastyp som har en %2.</translation>
+ </message>
+ <message>
+ <location line="+286"/>
+ <source>Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type.</source>
+ <translation>Innehållsmodellen för den komplexa typen %1 innehåller %2 komponenter, så den kan inte härledas med utökning från en icke-tom typ.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model.</source>
+ <translation>Komplex typ %1 kan inte härledas med utökning från %2, eftersom den senare innehåller %3 komponenter i sin innehållsmodell.</translation>
+ </message>
+ <message>
+ <location line="+101"/>
+ <source>Type of %1 element must be a simple type, %2 is not.</source>
+ <translation>Typ för komponenten %1 måste vara en enkel typ, %2 är inte det.</translation>
+ </message>
+ <message>
+ <location line="+62"/>
+ <source>Substitution group %1 of %2 element cannot be resolved.</source>
+ <translation>Ersättningsgrupp %1 av komponenten %2 kan inte lösas upp.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Substitution group %1 has circular definition.</source>
+ <translation>Ersättningsgrupp %1 har en cirkulär definition.</translation>
+ </message>
+ <message>
+ <location line="+120"/>
+ <location line="+7"/>
+ <source>Duplicated element names %1 in %2 element.</source>
+ <translation>Duplicerade komponentnamn %1 i komponent %2.</translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <location line="+52"/>
+ <location line="+71"/>
+ <location line="+28"/>
+ <source>Reference %1 of %2 element cannot be resolved.</source>
+ <translation>Referens %1 av komponent %2 kan inte lösas upp.</translation>
+ </message>
+ <message>
+ <location line="-138"/>
+ <source>Circular group reference for %1.</source>
+ <translation>Cirkulär gruppreferens för %1.</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>%1 element is not allowed in this scope</source>
+ <translation>Komponenten %1 är inte tillåten i det här synliga området</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>%1 element cannot have %2 attribute with value other than %3.</source>
+ <translation>Komponenten %1 kan inte ha egenskapen %2 med ett värde skilt från %3.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>%1 element cannot have %2 attribute with value other than %3 or %4.</source>
+ <translation>Komponenten %1 kan inte ha egenskapen %2 med ett värde skilt från %3 eller %4.</translation>
+ </message>
+ <message>
+ <location line="+91"/>
+ <source>%1 or %2 attribute of reference %3 does not match with the attribute declaration %4.</source>
+ <translation>Egenskapen %1 eller %2 av referensen %3 motsvarar inte egenskapsdeklarationen %4.</translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>Attribute group %1 has circular reference.</source>
+ <translation>Egenskapsgruppen %1 har cirkulär referens.</translation>
+ </message>
+ <message>
+ <location line="+131"/>
+ <source>%1 attribute in %2 must have %3 use like in base type %4.</source>
+ <translation>Egenskapen %1 i %2 måste ha %3 användning som i bastypen %4.</translation>
+ </message>
+ <message>
+ <location line="+52"/>
+ <source>Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2.</source>
+ <translation>Egenskapens jokertecken för %1 är inte en giltig begränsning av egenskapens jokertecken för bastypen %2.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>%1 has attribute wildcard but its base type %2 has not.</source>
+ <translation>%1 har ett egenskapsjokertecken men dess bastyp %2 har det inte.</translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible.</source>
+ <translation>En union av egenskapsjokertecken med typ %1 och egenskapsjokertecken av dess bastyp %2 går inte att uttrycka.</translation>
+ </message>
+ <message>
+ <location line="+48"/>
+ <source>Enumeration facet contains invalid content: {%1} is not a value of type %2.</source>
+ <translation>Uppräkningsaspekt har ogiltigt innehåll: {%1} är inte ett värde av typen %2.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Namespace prefix of qualified name %1 is not defined.</source>
+ <translation>Namnrymdens prefix för det kvalificerade namnet %1 är inte definierat.</translation>
+ </message>
+ <message>
+ <location line="+51"/>
+ <location line="+18"/>
+ <source>%1 element %2 is not a valid restriction of the %3 element it redefines: %4.</source>
+ <translation>%1 komponent %2 är inte en giltig begränsning av komponenten %3 som den definierar om: %4.</translation>
+ </message>
+ <message>
+ <location filename="../src/xmlpatterns/schema/qxsdtypechecker.cpp" line="+234"/>
+ <location line="+7"/>
+ <location line="+21"/>
+ <source>%1 is not valid according to %2.</source>
+ <translation>%1 är inte giltig enligt %2.</translation>
+ </message>
+ <message>
+ <location line="+167"/>
+ <source>String content does not match the length facet.</source>
+ <translation>Stränginnehåll motsvarar inte längdaspekten.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>String content does not match the minLength facet.</source>
+ <translation>Stränginnehåll motsvarar inte aspekten minLength.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>String content does not match the maxLength facet.</source>
+ <translation>Stränginnehåll motsvarar inte aspekten maxLength.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>String content does not match pattern facet.</source>
+ <translation>Stränginnehåll motsvarar inte mönsteraspekt.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>String content is not listed in the enumeration facet.</source>
+ <translation>Stränginnehåll listas inte i uppräkningsaspekten.</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Signed integer content does not match the maxInclusive facet.</source>
+ <translation>Innehåll i heltal med tecken motsvarar inte aspekten maxInclusive.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Signed integer content does not match the maxExclusive facet.</source>
+ <translation>Innehåll i heltal med tecken motsvarar inte aspekten maxExclusive.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Signed integer content does not match the minInclusive facet.</source>
+ <translation>Innehåll i heltal med tecken motsvarar inte aspekten minInclusive.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Signed integer content does not match the minExclusive facet.</source>
+ <translation>Innehåll i heltal med tecken motsvarar inte aspekten minExclusive.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Signed integer content is not listed in the enumeration facet.</source>
+ <translation>Innehåll i heltal med tecken listas inte i uppräkningsaspekten.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Signed integer content does not match pattern facet.</source>
+ <translation>Innehåll i heltal med tecken motsvarar inte mönsteraspekt.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Signed integer content does not match in the totalDigits facet.</source>
+ <translation>Innehåll i heltal med tecken motsvarar inte aspekten totalDigits.</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Unsigned integer content does not match the maxInclusive facet.</source>
+ <translation>Innehåll i heltal utan tecken motsvarar inte aspekten maxInclusive.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Unsigned integer content does not match the maxExclusive facet.</source>
+ <translation>Innehåll i heltal utan tecken motsvarar inte aspekten maxExclusive.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Unsigned integer content does not match the minInclusive facet.</source>
+ <translation>Innehåll i heltal utan tecken motsvarar inte aspekten minInclusive.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Unsigned integer content does not match the minExclusive facet.</source>
+ <translation>Innehåll i heltal utan tecken motsvarar inte aspekten minExclusive.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Unsigned integer content is not listed in the enumeration facet.</source>
+ <translation>Innehåll i heltal utan tecken listas inte i uppräkningsaspekten.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Unsigned integer content does not match pattern facet.</source>
+ <translation>Innehåll i heltal utan tecken motsvarar inte mönsteraspekt.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Unsigned integer content does not match in the totalDigits facet.</source>
+ <translation>Innehåll i heltal utan tecken motsvarar inte aspekten totalDigits.</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Double content does not match the maxInclusive facet.</source>
+ <translation>Innehåll i flyttal med dubbel precision motsvarar inte aspekten maxInclusive.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Double content does not match the maxExclusive facet.</source>
+ <translation>Innehåll i flyttal med dubbel precision motsvarar inte aspekten maxExclusive.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Double content does not match the minInclusive facet.</source>
+ <translation>Innehåll i flyttal med dubbel precision motsvarar inte aspekten minInclusive.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Double content does not match the minExclusive facet.</source>
+ <translation>Innehåll i flyttal med dubbel precision motsvarar inte aspekten minExclusive.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Double content is not listed in the enumeration facet.</source>
+ <translation>Innehåll i flyttal med dubbel precision listas inte i uppräkningsaspekten.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Double content does not match pattern facet.</source>
+ <translation>Innehåll i flyttal med dubbel precision motsvarar inte mönsteraspekt.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Decimal content does not match in the fractionDigits facet.</source>
+ <translation>Decimalt innehåll motsvarar inte i aspekten fractionDigits.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Decimal content does not match in the totalDigits facet.</source>
+ <translation>Decimalt innehåll motsvarar inte i aspekten totalDigits.</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Date time content does not match the maxInclusive facet.</source>
+ <translation>Datum- och tidinnehåll motsvarar inte aspekten maxInclusive.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Date time content does not match the maxExclusive facet.</source>
+ <translation>Datum- och tidinnehåll motsvarar inte aspekten maxExclusive.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Date time content does not match the minInclusive facet.</source>
+ <translation>Datum- och tidinnehåll motsvarar inte aspekten minInclusive.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Date time content does not match the minExclusive facet.</source>
+ <translation>Datum- och tidinnehåll motsvarar inte aspekten minExclusive.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Date time content is not listed in the enumeration facet.</source>
+ <translation>Datum- och tidinnehåll listas inte i uppräkningsaspekten.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Date time content does not match pattern facet.</source>
+ <translation>Datum- och tidinnehåll motsvarar inte mönsteraspekt.</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Duration content does not match the maxInclusive facet.</source>
+ <translation>Tidslängdens innehåll motsvarar inte aspekten maxInclusive.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Duration content does not match the maxExclusive facet.</source>
+ <translation>Tidslängdens innehåll motsvarar inte aspekten maxExclusive.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Duration content does not match the minInclusive facet.</source>
+ <translation>Tidslängdens innehåll motsvarar inte aspekten minInclusive.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Duration content does not match the minExclusive facet.</source>
+ <translation>Tidslängdens innehåll motsvarar inte aspekten minExclusive.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Duration content is not listed in the enumeration facet.</source>
+ <translation>Tidslängdens innehåll listas inte i uppräkningsaspekten.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Duration content does not match pattern facet.</source>
+ <translation>Tidslängdens innehåll motsvarar inte mönsteraspekt.</translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Boolean content does not match pattern facet.</source>
+ <translation>Booleskt innehåll motsvarar inte mönsteraspekt.</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Binary content does not match the length facet.</source>
+ <translation>Binärt innehåll motsvarar inte längdaspekten.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Binary content does not match the minLength facet.</source>
+ <translation>Binärt innehåll motsvarar inte aspekten minLength.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Binary content does not match the maxLength facet.</source>
+ <translation>Binärt innehåll motsvarar inte aspekten maxLength.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Binary content is not listed in the enumeration facet.</source>
+ <translation>Binärt innehåll listas inte i uppräkningsaspekten.</translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Invalid QName content: %1.</source>
+ <translation>Ogiltigt innehåll i QName: %1.</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>QName content is not listed in the enumeration facet.</source>
+ <translation>Innehåll i QName listas inte i uppräkningsaspekten.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>QName content does not match pattern facet.</source>
+ <translation>Innehåll i QName motsvarar inte mönsteraspekt.</translation>
+ </message>
+ <message>
+ <location line="+36"/>
+ <source>Notation content is not listed in the enumeration facet.</source>
+ <translation>Notationsinnehåll listas inte i uppräkningsaspekten.</translation>
+ </message>
+ <message>
+ <location line="+19"/>
+ <source>List content does not match length facet.</source>
+ <translation>Listinnehåll motsvarar inte längdaspekten.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>List content does not match minLength facet.</source>
+ <translation>Listinnehåll motsvarar inte aspekten minLength.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>List content does not match maxLength facet.</source>
+ <translation>Listinnehåll motsvarar inte aspekten maxLength.</translation>
+ </message>
+ <message>
+ <location line="+90"/>
+ <source>List content is not listed in the enumeration facet.</source>
+ <translation>Listinnehåll listas inte i uppräkningsaspekten.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>List content does not match pattern facet.</source>
+ <translation>Listinnehåll motsvarar inte mönsteraspekt.</translation>
+ </message>
+ <message>
+ <location line="+39"/>
+ <source>Union content is not listed in the enumeration facet.</source>
+ <translation>Innehåll i union listas inte i uppräkningsaspekten.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Union content does not match pattern facet.</source>
+ <translation>Innehåll i union motsvarar inte mönsteraspekt.</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Data of type %1 are not allowed to be empty.</source>
+ <translation>Data av typen %1 tillåts inte vara tomt.</translation>
+ </message>
+ <message>
+ <location filename="../src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp" line="+160"/>
+ <source>Element %1 is missing child element.</source>
+ <translation>Komponenten %1 saknar underliggande komponent.</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>There is one IDREF value with no corresponding ID: %1.</source>
+ <translation>Det finns ett IDREF värde utan motsvarande ID: %1.</translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Loaded schema file is invalid.</source>
+ <translation>Laddad schema-fil är ogiltig.</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>%1 contains invalid data.</source>
+ <translation>%1 innehåller ogiltig data.</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>xsi:schemaLocation namespace %1 has already appeared earlier in the instance document.</source>
+ <translation>xsi:schemaLocation namnrymd %1 har redan funnits tidigare i instansdokumentet.</translation>
+ </message>
+ <message>
+ <location line="+22"/>
+ <source>xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute.</source>
+ <translation>xsi:noNamespaceSchemaLocation kan inte finnas efter den första komponenten eller egenskapen som inte är en namnrymd.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>No schema defined for validation.</source>
+ <translation>Inget schema definierat för validering.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>No definition for element %1 available.</source>
+ <translation>Ingen definition av komponent %1 tillgänglig.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <location line="+49"/>
+ <location line="+142"/>
+ <source>Specified type %1 is not known to the schema.</source>
+ <translation>Angiven typ %1 är inte känd av schemat.</translation>
+ </message>
+ <message>
+ <location line="-176"/>
+ <source>Element %1 is not defined in this scope.</source>
+ <translation>Komponenten %1 är inte definierade i det här synliga området.</translation>
+ </message>
+ <message>
+ <location line="+43"/>
+ <source>Declaration for element %1 does not exist.</source>
+ <translation>Deklaration för komponenten %1 finns inte.</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>Element %1 contains invalid content.</source>
+ <translation>Komponenten %1 har ogiltigt innehåll.</translation>
+ </message>
+ <message>
+ <location line="+73"/>
+ <source>Element %1 is declared as abstract.</source>
+ <translation>Komponenten %1 är deklarerad som abstrakt.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Element %1 is not nillable.</source>
+ <translation>Komponenten %1 kan inte tilldelas noll.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Attribute %1 contains invalid data: %2</source>
+ <translation>Egenskapen %1 innehåller ogiltig data: %2</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Element contains content although it is nillable.</source>
+ <translation>Komponenten har innehåll trots att den kan tilldelas noll.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Fixed value constraint not allowed if element is nillable.</source>
+ <translation>Fast värdebegränsning ej tillåten om komponenten kan tilldelas noll.</translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Specified type %1 is not validly substitutable with element type %2.</source>
+ <translation>Angiven typ %1 kan inte ersättas av komponenttypen %2 med giltigt resultat.</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Complex type %1 is not allowed to be abstract.</source>
+ <translation>Komplex typ %1 tillåts inte vara abstrakt.</translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>Element %1 contains not allowed attributes.</source>
+ <translation>Komponenten %1 innehåller egenskaper som inte tillåts.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <location line="+97"/>
+ <source>Element %1 contains not allowed child element.</source>
+ <translation>Komponenten %1 innehåller en underliggande komponent som inte tillåts.</translation>
+ </message>
+ <message>
+ <location line="-76"/>
+ <location line="+93"/>
+ <source>Content of element %1 does not match its type definition: %2.</source>
+ <translation>Innehållet i komponenten %1 motsvarar inte dess typdefinition: %2.</translation>
+ </message>
+ <message>
+ <location line="-85"/>
+ <location line="+92"/>
+ <location line="+41"/>
+ <source>Content of element %1 does not match defined value constraint.</source>
+ <translation>Innehållet i komponenten %1 motsvarar inte definierad värdebegränsning.</translation>
+ </message>
+ <message>
+ <location line="-73"/>
+ <source>Element %1 contains not allowed child content.</source>
+ <translation>Komponenten %1 innehåller underliggande komponentinnehåll som inte tillåts.</translation>
+ </message>
+ <message>
+ <location line="+41"/>
+ <source>Element %1 contains not allowed text content.</source>
+ <translation>Komponenten %1 innehåller textinnehåll som inte tillåts.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Element %1 cannot contain other elements, as it has a fixed content.</source>
+ <translation>Komponenten %1 kan inte innehålla andra komponenter, eftersom den har ett fast innehåll.</translation>
+ </message>
+ <message>
+ <location line="+43"/>
+ <source>Element %1 is missing required attribute %2.</source>
+ <translation>Komponenten %1 saknar nödvändig egenskap %2.</translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Attribute %1 does not match the attribute wildcard.</source>
+ <translation>Egenskapen %1 motsvarar inte egenskapens jokertecken.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Declaration for attribute %1 does not exist.</source>
+ <translation>Deklaration av egenskapen %1 finns inte.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Element %1 contains two attributes of type %2.</source>
+ <translation>Komponenten %1 innehåller två egenskaper av typ %2.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Attribute %1 contains invalid content.</source>
+ <translation>Egenskapen %1 har ogiltigt innehåll.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Element %1 contains unknown attribute %2.</source>
+ <translation>Komponenten %1 innehåller okänd egenskap %2.</translation>
+ </message>
+ <message>
+ <location line="+40"/>
+ <location line="+46"/>
+ <source>Content of attribute %1 does not match its type definition: %2.</source>
+ <translation>Innehållet i egenskapen %1 motsvarar inte dess typdefinition: %2.</translation>
+ </message>
+ <message>
+ <location line="-38"/>
+ <location line="+46"/>
+ <source>Content of attribute %1 does not match defined value constraint.</source>
+ <translation>Innehållet i komponenten %1 motsvarar inte definierad värdebegränsning.</translation>
+ </message>
+ <message>
+ <location line="+88"/>
+ <source>Non-unique value found for constraint %1.</source>
+ <translation>Icke-unikt värde hittades för begränsning %1.</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>Key constraint %1 contains absent fields.</source>
+ <translation>Nyckelbegränsningen %1 innehåller saknade fält.</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Key constraint %1 contains references nillable element %2.</source>
+ <translation>Nyckelbegränsningen %1 innehåller referenser till komponenten %2 som kan tilldelas noll.</translation>
+ </message>
+ <message>
+ <location line="+40"/>
+ <source>No referenced value found for key reference %1.</source>
+ <translation>Inget referensvärde hittades för nyckelreferens %1.</translation>
+ </message>
+ <message>
+ <location line="+64"/>
+ <source>More than one value found for field %1.</source>
+ <translation>Mer än ett värde hittades för fältet %1.</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>Field %1 has no simple type.</source>
+ <translation>Fältet %1 har ingen enkel typ.</translation>
+ </message>
+ <message>
+ <location line="+73"/>
+ <source>ID value &apos;%1&apos; is not unique.</source>
+ <translation>ID-värdet &apos;%1&apos; är inte unikt.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>&apos;%1&apos; attribute contains invalid QName content: %2.</source>
+ <translation>Egenskapen &apos;%1&apos; innehåller ogiltigt QName innehåll: %2.</translation>
+ </message>
+</context>
+<context>
+ <name>VolumeSlider</name>
+ <message>
+ <source>Muted</source>
+ <translation type="obsolete">Tyst</translation>
+ </message>
+ <message>
+ <source>Volume: %1%</source>
+ <translation type="obsolete">Volym: %1%</translation>
</message>
</context>
</TS>
diff --git a/src/VBox/Frontends/VirtualBox/src/UIMediumTypeChangeDialog.cpp b/src/VBox/Frontends/VirtualBox/src/UIMediumTypeChangeDialog.cpp
new file mode 100644
index 000000000..ac356e41c
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/UIMediumTypeChangeDialog.cpp
@@ -0,0 +1,187 @@
+/* $Id: UIMediumTypeChangeDialog.cpp 37895 2011-07-12 12:48:15Z vboxsync $ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMediumTypeChangeDialog class implementation
+ */
+
+/*
+ * 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.
+ */
+
+/* Global includes: */
+#include <QVBoxLayout>
+#include <QGroupBox>
+#include <QRadioButton>
+#include <QPushButton>
+
+/* Local includes: */
+#include "UIMediumTypeChangeDialog.h"
+#include "VBoxGlobal.h"
+#include "VBoxProblemReporter.h"
+#include "QILabel.h"
+#include "QIDialogButtonBox.h"
+
+/* Constructor: */
+UIMediumTypeChangeDialog::UIMediumTypeChangeDialog(QWidget *pParent, const QString &strMediumId)
+ : QIWithRetranslateUI<QIDialog>(pParent)
+{
+#ifdef Q_WS_MAC
+ setWindowFlags(Qt::Sheet);
+#else /* Q_WS_MAC */
+ /* Enable size-grip: */
+ setSizeGripEnabled(true);
+#endif /* Q_WS_MAC */
+
+ /* Search for corresponding medium: */
+ m_medium = vboxGlobal().findMedium(strMediumId).medium();
+ m_oldMediumType = m_medium.GetType();
+ m_newMediumType = m_oldMediumType;
+
+ /* Create main layout: */
+ QVBoxLayout *pMainLayout = new QVBoxLayout(this);
+
+ /* Create description label: */
+ m_pLabel = new QILabel(this);
+ m_pLabel->setWordWrap(true);
+ m_pLabel->useSizeHintForWidth(450);
+ m_pLabel->updateGeometry();
+ pMainLayout->addWidget(m_pLabel);
+
+ /* Create group-box: */
+ m_pGroupBox = new QGroupBox(this);
+ pMainLayout->addWidget(m_pGroupBox);
+
+ /* Create button-box: */
+ m_pButtonBox = new QIDialogButtonBox(this);
+ m_pButtonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ m_pButtonBox->button(QDialogButtonBox::Ok)->setDefault(true);
+ connect(m_pButtonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(sltAccept()));
+ connect(m_pButtonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(sltReject()));
+ pMainLayout->addWidget(m_pButtonBox);
+
+ /* Finally, add a stretch: */
+ pMainLayout->addStretch();
+
+ /* Create radio-buttons: */
+ createMediumTypeButtons();
+
+ /* Retranslate: */
+ retranslateUi();
+
+ /* Resize: */
+ resize(minimumSizeHint());
+}
+
+/* Accept finisher: */
+void UIMediumTypeChangeDialog::sltAccept()
+{
+ /* Try to assign new medium type: */
+ m_medium.SetType(m_newMediumType);
+ /* Check for result: */
+ if (!m_medium.isOk())
+ {
+ /* Show error message: */
+ vboxProblem().cannotChangeMediumType(this, m_medium, m_oldMediumType, m_newMediumType);
+ return;
+ }
+ /* Accept dialog with parent class method: */
+ QIWithRetranslateUI<QIDialog>::accept();
+}
+
+/* Reject finisher: */
+void UIMediumTypeChangeDialog::sltReject()
+{
+ /* Reject dialog with parent class method: */
+ QIWithRetranslateUI<QIDialog>::reject();
+}
+
+/* Translation stuff: */
+void UIMediumTypeChangeDialog::retranslateUi()
+{
+ /* Translate window title: */
+ setWindowTitle(tr("Modify medium attributes"));
+
+ /* Translate description: */
+ m_pLabel->setText(tr("<p>You are about to change the attributes of the virtual disk located in <b>%1</b>.</p>"
+ "<p>Please choose one of the following medium types and press <b>%2</b> "
+ "to proceed or <b>%3</b> otherwise.</p>")
+ .arg(m_medium.GetLocation())
+ .arg(VBoxGlobal::removeAccelMark(m_pButtonBox->button(QDialogButtonBox::Ok)->text()))
+ .arg(VBoxGlobal::removeAccelMark(m_pButtonBox->button(QDialogButtonBox::Cancel)->text())));
+
+ /* Translate group-box: */
+ m_pGroupBox->setTitle(tr("Choose medium type:"));
+
+ /* Translate radio-buttons: */
+ QList<QRadioButton*> buttons = findChildren<QRadioButton*>();
+ for (int i = 0; i < buttons.size(); ++i)
+ buttons[i]->setText(vboxGlobal().toString(buttons[i]->property("mediumType").value<KMediumType>()));
+}
+
+void UIMediumTypeChangeDialog::sltValidate()
+{
+ /* Search for the checked button: */
+ QRadioButton *pCheckedButton = 0;
+ QList<QRadioButton*> buttons = findChildren<QRadioButton*>();
+ for (int i = 0; i < buttons.size(); ++i)
+ {
+ if (buttons[i]->isChecked())
+ {
+ pCheckedButton = buttons[i];
+ break;
+ }
+ }
+ /* Determine chosen type: */
+ m_newMediumType = pCheckedButton->property("mediumType").value<KMediumType>();
+ /* Enable/disable OK button depending on chosen type,
+ * for now only the previous type is restricted, others are free to choose: */
+ m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(m_oldMediumType != m_newMediumType);
+}
+
+/* Create medium-type radio-buttons: */
+void UIMediumTypeChangeDialog::createMediumTypeButtons()
+{
+ /* Register required meta-type: */
+ qRegisterMetaType<KMediumType>();
+ /* Create group-box layout: */
+ m_pGroupBoxLayout = new QVBoxLayout(m_pGroupBox);
+ /* Populate radio-buttons: */
+ createMediumTypeButton(KMediumType_Normal);
+ createMediumTypeButton(KMediumType_Immutable);
+ createMediumTypeButton(KMediumType_Writethrough);
+ createMediumTypeButton(KMediumType_Shareable);
+ createMediumTypeButton(KMediumType_MultiAttach);
+ /* Make sure button reflecting previoius type is checked: */
+ QList<QRadioButton*> buttons = findChildren<QRadioButton*>();
+ for (int i = 0; i < buttons.size(); ++i)
+ {
+ if (buttons[i]->property("mediumType").value<KMediumType>() == m_oldMediumType)
+ {
+ buttons[i]->setChecked(true);
+ buttons[i]->setFocus();
+ break;
+ }
+ }
+ /* Revalidate finally: */
+ sltValidate();
+}
+
+/* Create radio-button for the passed medium-type: */
+void UIMediumTypeChangeDialog::createMediumTypeButton(KMediumType mediumType)
+{
+ /* Create corresponding radio-button: */
+ QRadioButton *pRadioButton = new QRadioButton(m_pGroupBox);
+ connect(pRadioButton, SIGNAL(clicked()), this, SLOT(sltValidate()));
+ pRadioButton->setProperty("mediumType", QVariant::fromValue(mediumType));
+ m_pGroupBoxLayout->addWidget(pRadioButton);
+}
+
diff --git a/src/VBox/Frontends/VirtualBox/src/UIMediumTypeChangeDialog.h b/src/VBox/Frontends/VirtualBox/src/UIMediumTypeChangeDialog.h
new file mode 100644
index 000000000..41e216c6f
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/UIMediumTypeChangeDialog.h
@@ -0,0 +1,76 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMediumTypeChangeDialog class declaration
+ */
+
+/*
+ * 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 __UIMediumTypeChangeDialog_h__
+#define __UIMediumTypeChangeDialog_h__
+
+/* Local includes: */
+#include "QIDialog.h"
+#include "QIWithRetranslateUI.h"
+#include "COMDefs.h"
+
+/* Forward declarations: */
+class QVBoxLayout;
+class QILabel;
+class QGroupBox;
+class QRadioButton;
+class QIDialogButtonBox;
+
+/* Dialog providing user with possibility to change medium type: */
+class UIMediumTypeChangeDialog : public QIWithRetranslateUI<QIDialog>
+{
+ Q_OBJECT;
+
+public:
+
+ /* Constructor: */
+ UIMediumTypeChangeDialog(QWidget *pParent, const QString &strMediumId);
+
+protected:
+
+ /* Translation stuff: */
+ void retranslateUi();
+
+protected slots:
+
+ /* Finisher(s): */
+ void sltAccept();
+ void sltReject();
+
+ /* Validation stuff: */
+ void sltValidate();
+
+private:
+
+ /* Various helping stuff: */
+ void createMediumTypeButtons();
+ void createMediumTypeButton(KMediumType mediumType);
+
+ /* Widgets: */
+ QILabel *m_pLabel;
+ QGroupBox *m_pGroupBox;
+ QVBoxLayout *m_pGroupBoxLayout;
+ QIDialogButtonBox *m_pButtonBox;
+
+ /* Variables: */
+ CMedium m_medium;
+ KMediumType m_oldMediumType;
+ KMediumType m_newMediumType;
+};
+
+#endif // __UIMediumTypeChangeDialog_h__
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxAboutDlg.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxAboutDlg.cpp
index 6a4c75943..d1a9c7915 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxAboutDlg.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxAboutDlg.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxAboutDlg.cpp $ */
+/* $Id: VBoxAboutDlg.cpp 37762 2011-07-04 12:55:46Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -33,7 +33,7 @@
#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
VBoxAboutDlg::VBoxAboutDlg(QWidget *pParent, const QString &strVersion)
- : QIWithRetranslateUI2<QIDialog>(pParent, Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
+ : QIWithRetranslateUI2<QIDialog>(pParent, Qt::CustomizeWindowHint | Qt::WindowTitleHint)
, m_strVersion(strVersion)
{
/* Delete dialog on close: */
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp
index 0dd0ac7f1..244a72223 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxFBOverlay.cpp $ */
+/* $Id: VBoxFBOverlay.cpp 37495 2011-06-16 13:32:37Z vboxsync $ */
/** @file
* VBoxFBOverlay implementation
*/
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp
index 793e3854e..d449a70b9 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxFBQGL.cpp $ */
+/* $Id: VBoxFBQGL.cpp 29794 2010-05-25 16:06:59Z vboxsync $ */
/** @file
* VBoxFBQGL Opengl-based FrameBuffer implementation
*/
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxGLSupportInfo.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxGLSupportInfo.cpp
index 67d603d5b..fcded7777 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxGLSupportInfo.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxGLSupportInfo.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGLSupportInfo.cpp $ */
+/* $Id: VBoxGLSupportInfo.cpp 36386 2011-03-24 06:51:19Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxGlobalSettings.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxGlobalSettings.cpp
index 0d4b29b64..0c661da47 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxGlobalSettings.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxGlobalSettings.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGlobalSettings.cpp $ */
+/* $Id: VBoxGlobalSettings.cpp 37544 2011-06-17 13:54:47Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -53,6 +53,7 @@ VBoxGlobalSettingsData::VBoxGlobalSettingsData()
languageId = QString::null;
maxGuestRes = "auto";
remapScancodes = QString::null;
+ proxySettings = QString::null;
trayIconEnabled = false;
presentationModeEnabled = false;
hostScreenSaverDisabled = false;
@@ -66,6 +67,7 @@ VBoxGlobalSettingsData::VBoxGlobalSettingsData (const VBoxGlobalSettingsData &th
languageId = that.languageId;
maxGuestRes = that.maxGuestRes;
remapScancodes = that.remapScancodes;
+ proxySettings = that.proxySettings;
trayIconEnabled = that.trayIconEnabled;
presentationModeEnabled = that.presentationModeEnabled;
hostScreenSaverDisabled = that.hostScreenSaverDisabled;
@@ -84,6 +86,7 @@ bool VBoxGlobalSettingsData::operator== (const VBoxGlobalSettingsData &that) con
languageId == that.languageId &&
maxGuestRes == that.maxGuestRes &&
remapScancodes == that.remapScancodes &&
+ proxySettings == that.proxySettings &&
trayIconEnabled == that.trayIconEnabled &&
presentationModeEnabled == that.presentationModeEnabled &&
hostScreenSaverDisabled == that.hostScreenSaverDisabled
@@ -114,6 +117,7 @@ gPropertyMap[] =
{ "GUI/LanguageID", "languageId", gVBoxLangIDRegExp, true },
{ "GUI/MaxGuestResolution", "maxGuestRes", "\\d*[1-9]\\d*,\\d*[1-9]\\d*|any|auto", true },
{ "GUI/RemapScancodes", "remapScancodes", "(\\d+=\\d+,)*\\d+=\\d+", true },
+ { "GUI/ProxySettings", "proxySettings", "[\\s\\S]*", true },
{ "GUI/TrayIcon/Enabled", "trayIconEnabled", "true|false", true },
#ifdef Q_WS_MAC
{ VBoxDefs::GUI_PresentationModeEnabled, "presentationModeEnabled", "true|false", true },
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxGlobalSettings.h b/src/VBox/Frontends/VirtualBox/src/VBoxGlobalSettings.h
index a6deb8e54..288c2a8bb 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxGlobalSettings.h
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxGlobalSettings.h
@@ -43,6 +43,7 @@ private:
QString languageId;
QString maxGuestRes;
QString remapScancodes;
+ QString proxySettings;
bool trayIconEnabled;
bool presentationModeEnabled;
bool hostScreenSaverDisabled;
@@ -61,6 +62,7 @@ class VBoxGlobalSettings : public QObject, public CIShared <VBoxGlobalSettingsDa
Q_PROPERTY (QString languageId READ languageId WRITE setLanguageId)
Q_PROPERTY (QString maxGuestRes READ maxGuestRes WRITE setMaxGuestRes)
Q_PROPERTY (QString remapScancodes READ remapScancodes WRITE setRemapScancodes)
+ Q_PROPERTY (QString proxySettings READ proxySettings WRITE setProxySettings)
Q_PROPERTY (bool trayIconEnabled READ trayIconEnabled WRITE setTrayIconEnabled)
Q_PROPERTY (bool presentationModeEnabled READ presentationModeEnabled WRITE setPresentationModeEnabled)
Q_PROPERTY (bool hostScreenSaverDisabled READ hostScreenSaverDisabled WRITE setHostScreenSaverDisabled)
@@ -113,6 +115,11 @@ public:
mData()->remapScancodes = aRemapScancodes;
}
+ QString proxySettings() const { return data()->proxySettings; }
+ void setProxySettings (const QString &aProxySettings)
+ {
+ mData()->proxySettings = aProxySettings;
+ }
bool trayIconEnabled() const { return data()->trayIconEnabled; }
void setTrayIconEnabled (bool enabled)
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxHelpActions.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxHelpActions.cpp
index ae224ddd1..760ba74d7 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxHelpActions.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxHelpActions.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxHelpActions.cpp $ */
+/* $Id: VBoxHelpActions.cpp 35634 2011-01-19 16:13:31Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxLicenseViewer.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxLicenseViewer.cpp
index a9346dca0..dc8d7289b 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxLicenseViewer.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxLicenseViewer.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxLicenseViewer.cpp $ */
+/* $Id: VBoxLicenseViewer.cpp 35103 2010-12-14 16:33:26Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.cpp
index 04f4a77af..224b28f5d 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxMediaManagerDlg.cpp $ */
+/* $Id: VBoxMediaManagerDlg.cpp 37904 2011-07-12 15:16:23Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,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;
@@ -36,13 +36,14 @@
/* Local includes */
#include "VBoxGlobal.h"
#include "VBoxMediaManagerDlg.h"
-#include "UINewHDWzd.h"
+#include "UINewHDWizard.h"
#include "VBoxProblemReporter.h"
#include "UIToolBar.h"
#include "QIFileDialog.h"
#include "QILabel.h"
#include "UIIconPool.h"
#include "UIVirtualBoxEventHandler.h"
+#include "UIMediumTypeChangeDialog.h"
#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
#ifdef Q_WS_MAC
@@ -108,6 +109,8 @@ public:
QString hardDiskFormat() const { return mMedium.hardDiskFormat (!mManager->showDiffs()); }
QString hardDiskType() const { return mMedium.hardDiskType (!mManager->showDiffs()); }
+ QString details() const { return mMedium.storageDetails(); }
+
QString usage() const { return mMedium.usage (!mManager->showDiffs()); }
QString toolTip() const { return mMedium.toolTip (!mManager->showDiffs(), mManager->inAttachMode()); }
@@ -286,12 +289,16 @@ VBoxMediaManagerDlg::VBoxMediaManagerDlg (QWidget *aParent /* = 0 */, Qt::Window
mNewAction = new QAction (this);
mAddAction = new QAction (this);
+ mCopyAction = new QAction (this);
+ mModifyAction = new QAction (this);
mRemoveAction = new QAction (this);
mReleaseAction = new QAction (this);
mRefreshAction = new QAction (this);
connect (mNewAction, SIGNAL (triggered()), this, SLOT (doNewMedium()));
connect (mAddAction, SIGNAL (triggered()), this, SLOT (doAddMedium()));
+ connect (mCopyAction, SIGNAL (triggered()), this, SLOT (doCopyMedium()));
+ connect (mModifyAction, SIGNAL (triggered()), this, SLOT (doModifyMedium()));
connect (mRemoveAction, SIGNAL (triggered()), this, SLOT (doRemoveMedium()));
connect (mReleaseAction, SIGNAL (triggered()), this, SLOT (doReleaseMedium()));
connect (mRefreshAction, SIGNAL (triggered()), this, SLOT (refreshAll()));
@@ -304,6 +311,14 @@ VBoxMediaManagerDlg::VBoxMediaManagerDlg (QWidget *aParent /* = 0 */, Qt::Window
QSize (22, 22), QSize (16, 16),
":/hd_add_22px.png", ":/hd_add_16px.png",
":/hd_add_disabled_22px.png", ":/hd_add_disabled_16px.png"));
+ mCopyAction->setIcon(UIIconPool::iconSetFull (
+ QSize (22, 22), QSize (16, 16),
+ ":/hd_add_22px.png", ":/hd_add_16px.png",
+ ":/hd_add_disabled_22px.png", ":/hd_add_disabled_16px.png"));
+ mModifyAction->setIcon(UIIconPool::iconSetFull (
+ QSize (22, 22), QSize (16, 16),
+ ":/hd_new_22px.png", ":/hd_new_16px.png",
+ ":/hd_new_disabled_22px.png", ":/hd_new_disabled_16px.png"));
mRemoveAction->setIcon(UIIconPool::iconSetFull (
QSize (22, 22), QSize (16, 16),
":/hd_remove_22px.png", ":/hd_remove_16px.png",
@@ -317,6 +332,8 @@ VBoxMediaManagerDlg::VBoxMediaManagerDlg (QWidget *aParent /* = 0 */, Qt::Window
":/refresh_22px.png", ":/refresh_16px.png",
":/refresh_disabled_22px.png", ":/refresh_disabled_16px.png"));
+ mActionsContextMenu->addAction (mCopyAction);
+ mActionsContextMenu->addAction (mModifyAction);
mActionsContextMenu->addAction (mRemoveAction);
mActionsContextMenu->addAction (mReleaseAction);
@@ -345,6 +362,8 @@ VBoxMediaManagerDlg::VBoxMediaManagerDlg (QWidget *aParent /* = 0 */, Qt::Window
// mToolBar->addAction (mNewAction);
// mToolBar->addAction (mAddAction);
+ mToolBar->addAction (mCopyAction);
+ mToolBar->addAction (mModifyAction);
// mToolBar->addSeparator();
mToolBar->addAction (mRemoveAction);
mToolBar->addAction (mReleaseAction);
@@ -355,6 +374,8 @@ VBoxMediaManagerDlg::VBoxMediaManagerDlg (QWidget *aParent /* = 0 */, Qt::Window
mActionsMenu = menuBar()->addMenu (QString::null);
// mActionsMenu->addAction (mNewAction);
// mActionsMenu->addAction (mAddAction);
+ mActionsMenu->addAction (mCopyAction);
+ mActionsMenu->addAction (mModifyAction);
// mActionsMenu->addSeparator();
mActionsMenu->addAction (mRemoveAction);
mActionsMenu->addAction (mReleaseAction);
@@ -588,18 +609,24 @@ void VBoxMediaManagerDlg::retranslateUi()
mNewAction->setText (tr ("&New..."));
mAddAction->setText (tr ("&Add..."));
+ mCopyAction->setText (tr ("&Copy..."));
+ mModifyAction->setText (tr ("&Modify..."));
mRemoveAction->setText (tr ("R&emove"));
mReleaseAction->setText (tr ("Re&lease"));
mRefreshAction->setText (tr ("Re&fresh"));
mNewAction->setShortcut (QKeySequence (QKeySequence::New));
mAddAction->setShortcut (QKeySequence ("Ins"));
+ mCopyAction->setShortcut (QKeySequence ("Ctrl+C"));
+ mModifyAction->setShortcut (QKeySequence ("Ctrl+Space"));
mRemoveAction->setShortcut (QKeySequence (QKeySequence::Delete));
mReleaseAction->setShortcut (QKeySequence ("Ctrl+L"));
mRefreshAction->setShortcut (QKeySequence (QKeySequence::Refresh));
mNewAction->setStatusTip (tr ("Create a new virtual hard disk"));
mAddAction->setStatusTip (tr ("Add an existing medium"));
+ mCopyAction->setStatusTip (tr ("Copy an existing medium"));
+ mModifyAction->setStatusTip (tr ("Modify the attributes of the selected medium"));
mRemoveAction->setStatusTip (tr ("Remove the selected medium"));
mReleaseAction->setStatusTip (tr ("Release the selected medium by detaching it from the machines"));
mRefreshAction->setStatusTip (tr ("Refresh the media list"));
@@ -608,6 +635,10 @@ void VBoxMediaManagerDlg::retranslateUi()
QString (" (%1)").arg (mNewAction->shortcut().toString()));
mAddAction->setToolTip (mAddAction->text().remove ('&') +
QString (" (%1)").arg (mAddAction->shortcut().toString()));
+ mCopyAction->setToolTip (mCopyAction->text().remove ('&') +
+ QString (" (%1)").arg (mCopyAction->shortcut().toString()));
+ mModifyAction->setToolTip (mModifyAction->text().remove ('&') +
+ QString (" (%1)").arg (mModifyAction->shortcut().toString()));
mRemoveAction->setToolTip (mRemoveAction->text().remove ('&') +
QString (" (%1)").arg (mRemoveAction->shortcut().toString()));
mReleaseAction->setToolTip (mReleaseAction->text().remove ('&') +
@@ -615,16 +646,6 @@ void VBoxMediaManagerDlg::retranslateUi()
mRefreshAction->setToolTip (mRefreshAction->text().remove ('&') +
QString (" (%1)").arg (mRefreshAction->shortcut().toString()));
- mLbHD1->setText (QString ("<nobr>%1:</nobr>").arg (tr ("Location")));
- mLbHD2->setText (QString ("<nobr>%1:</nobr>").arg (tr ("Type (Format)")));
- mLbHD3->setText (QString ("<nobr>%1:</nobr>").arg (tr ("Attached to", "VMM: Virtual Disk")));
-
- mLbCD1->setText (QString ("<nobr>%1:</nobr>").arg (tr ("Location")));
- mLbCD2->setText (QString ("<nobr>%1:</nobr>").arg (tr ("Attached to", "VMM: CD/DVD Image")));
-
- mLbFD1->setText (QString ("<nobr>%1:</nobr>").arg (tr ("Location")));
- mLbFD2->setText (QString ("<nobr>%1:</nobr>").arg (tr ("Attached to", "VMM: Floppy Image")));
-
mProgressBar->setText (tr ("Checking accessibility"));
#ifdef Q_WS_MAC
/* Make sure that the widgets aren't jumping around while the progress bar get visible. */
@@ -640,8 +661,7 @@ void VBoxMediaManagerDlg::retranslateUi()
mToolBar->updateLayout();
#endif /* QT_MAC_USE_COCOA */
- if (mDoSelect)
- mButtonBox->button (QDialogButtonBox::Ok)->setText (tr ("&Select"));
+ mButtonBox->button(QDialogButtonBox::Ok)->setText(mDoSelect ? tr("&Select") : tr("C&lose"));
if (mTwHD->model()->rowCount() || mTwCD->model()->rowCount() || mTwFD->model()->rowCount())
refreshAll();
@@ -951,7 +971,7 @@ void VBoxMediaManagerDlg::doNewMedium()
{
AssertReturnVoid (currentTreeWidgetType() == VBoxDefs::MediumType_HardDisk);
- UINewHDWzd dlg (this);
+ UINewHDWizard dlg (this);
if (dlg.exec() == QDialog::Accepted)
{
@@ -1036,6 +1056,32 @@ void VBoxMediaManagerDlg::doAddMedium()
}
}
+void VBoxMediaManagerDlg::doCopyMedium()
+{
+ /* Get current tree: */
+ QTreeWidget *pTree = currentTreeWidget();
+ /* Get current item of current tree: */
+ MediaItem *pItem = toMediaItem(pTree->currentItem());
+
+ UINewHDWizard wizard(this /* parent dialog */,
+ UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(pItem->text(0)).baseName()) /* default name */,
+ QFileInfo(pItem->location()).absolutePath() /* default path */,
+ 0 /* default size, not important for copying */,
+ pItem->medium().medium() /* base medium for copying */);
+ wizard.exec();
+}
+
+void VBoxMediaManagerDlg::doModifyMedium()
+{
+ MediaItem *pMediumItem = toMediaItem(currentTreeWidget()->currentItem());
+ UIMediumTypeChangeDialog dlg(this, pMediumItem->id());
+ if (dlg.exec() == QDialog::Accepted)
+ {
+ pMediumItem->refreshAll();
+ m_pTypePane->setText(pMediumItem->hardDiskType());
+ }
+}
+
void VBoxMediaManagerDlg::doRemoveMedium()
{
QTreeWidget *tree = currentTreeWidget();
@@ -1390,11 +1436,17 @@ void VBoxMediaManagerDlg::processCurrentChanged (QTreeWidgetItem *aItem,
/* New and Add are now enabled even when enumerating since it should be safe */
bool newEnabled = currentTreeWidgetType() == VBoxDefs::MediumType_HardDisk;
bool addEnabled = true;
+ bool copyEnabled = currentTreeWidgetType() == VBoxDefs::MediumType_HardDisk &&
+ notInEnum && item && checkMediumFor (item, Action_Copy);
+ bool modifyEnabled = currentTreeWidgetType() == VBoxDefs::MediumType_HardDisk &&
+ notInEnum && item && checkMediumFor (item, Action_Modify);
bool removeEnabled = notInEnum && item && checkMediumFor (item, Action_Remove);
bool releaseEnabled = item && checkMediumFor (item, Action_Release);
mNewAction->setEnabled (newEnabled);
mAddAction->setEnabled (addEnabled);
+ mCopyAction->setEnabled (copyEnabled);
+ mModifyAction->setEnabled (modifyEnabled);
mRemoveAction->setEnabled (removeEnabled);
mReleaseAction->setEnabled (releaseEnabled);
@@ -1406,16 +1458,18 @@ void VBoxMediaManagerDlg::processCurrentChanged (QTreeWidgetItem *aItem,
if (item)
{
+ QString details = item->details();
QString usage = item->usage().isNull() ?
formatPaneText (tr ("<i>Not&nbsp;Attached</i>"), false) :
formatPaneText (item->usage());
if (item->treeWidget() == mTwHD)
{
- mIpHD1->setText (formatPaneText (item->location(), true, "end"));
- mIpHD2->setText (formatPaneText (QString ("%1 (%2)").arg (item->hardDiskType())
- .arg (item->hardDiskFormat()), false));
- mIpHD3->setText (usage);
+ m_pTypePane->setText(item->hardDiskType());
+ m_pLocationPane->setText(formatPaneText(item->location(), true, "end"));
+ m_pFormatPane->setText(item->hardDiskFormat());
+ m_pDetailsPane->setText(details);
+ m_pUsagePane->setText(usage);
}
else if (item->treeWidget() == mTwCD)
{
@@ -1440,8 +1494,16 @@ void VBoxMediaManagerDlg::processDoubleClick (QTreeWidgetItem * /* aItem */, int
{
QTreeWidget *tree = currentTreeWidget();
- if (mDoSelect && selectedItem (tree) && mButtonBox->button (QDialogButtonBox::Ok)->isEnabled())
- accept();
+ if (mDoSelect)
+ {
+ if (selectedItem (tree) && mButtonBox->button (QDialogButtonBox::Ok)->isEnabled())
+ accept();
+ }
+ else
+ {
+ if (currentTreeWidgetType() == VBoxDefs::MediumType_HardDisk)
+ doModifyMedium();
+ }
}
void VBoxMediaManagerDlg::showContextMenu (const QPoint &aPos)
@@ -1532,7 +1594,7 @@ void VBoxMediaManagerDlg::addMediumToList(const QString &aLocation, VBoxDefs::Me
AssertMsgFailedReturnVoid (("Invalid aType %d\n", aType));
}
- CMedium med = mVBox.OpenMedium(aLocation, devType, KAccessMode_ReadWrite);
+ CMedium med = mVBox.OpenMedium(aLocation, devType, KAccessMode_ReadWrite, false /* fForceNewUuid */);
if (mVBox.isOk())
medium = VBoxMedium(CMedium(med), aType, KMediumState_Created);
@@ -1712,6 +1774,16 @@ bool VBoxMediaManagerDlg::checkMediumFor (MediaItem *aItem, Action aAction)
}
return true;
}
+ case Action_Copy:
+ {
+ /* False for children: */
+ return !aItem->medium().parent();
+ }
+ case Action_Modify:
+ {
+ /* False for children: */
+ return !aItem->medium().parent();
+ }
case Action_Remove:
{
/* Removable if not attached to anything */
@@ -1783,7 +1855,7 @@ void VBoxMediaManagerDlg::addDndUrls (const QList <QUrl> &aUrls)
void VBoxMediaManagerDlg::clearInfoPanes()
{
- mIpHD1->clear(); mIpHD2->clear(); mIpHD3->clear();
+ m_pTypePane->clear(); m_pLocationPane->clear(); m_pFormatPane->clear(); m_pDetailsPane->clear(); m_pUsagePane->clear();
mIpCD1->clear(); mIpCD2->clear();
mIpFD1->clear(); mIpFD2->clear();
}
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.h b/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.h
index 9937d6855..bb2db5801 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.h
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.h
@@ -39,7 +39,7 @@ class VBoxMediaManagerDlg : public QIWithRetranslateUI2<QIMainDialog>,
enum TabIndex { HDTab = 0, CDTab, FDTab };
enum ItemAction { ItemAction_Added, ItemAction_Updated, ItemAction_Removed };
- enum Action { Action_Select, Action_Edit, Action_Remove, Action_Release };
+ enum Action { Action_Select, Action_Edit, Action_Copy, Action_Modify, Action_Remove, Action_Release };
public:
@@ -84,6 +84,8 @@ private slots:
void doNewMedium();
void doAddMedium();
+ void doCopyMedium();
+ void doModifyMedium();
void doRemoveMedium();
void doReleaseMedium();
@@ -154,6 +156,8 @@ private:
UIToolBar *mToolBar;
QAction *mNewAction;
QAction *mAddAction;
+ QAction *mCopyAction;
+ QAction *mModifyAction;
QAction *mRemoveAction;
QAction *mReleaseAction;
QAction *mRefreshAction;
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.ui b/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.ui
index 1dd88b862..219cd4d76 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.ui
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.ui
@@ -96,16 +96,16 @@
<number>5</number>
</property>
<item row="0" column="0" >
- <widget class="QLabel" name="mLbHD1" >
+ <widget class="QLabel" name="m_pTypeLabel" >
<property name="text" >
- <string>Location</string>
+ <string>Type:</string>
</property>
</widget>
</item>
<item row="0" column="1" >
- <widget class="QILabel" name="mIpHD1" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+ <widget class="QILabel" name="m_pTypePane">
+ <property name="sizePolicy">
+ <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -113,14 +113,14 @@
</widget>
</item>
<item row="1" column="0" >
- <widget class="QLabel" name="mLbHD2" >
+ <widget class="QLabel" name="m_pLocationLabel" >
<property name="text" >
- <string>Type (Format)</string>
+ <string>Location:</string>
</property>
</widget>
</item>
<item row="1" column="1" >
- <widget class="QILabel" name="mIpHD2" >
+ <widget class="QILabel" name="m_pLocationPane" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
@@ -130,14 +130,48 @@
</widget>
</item>
<item row="2" column="0" >
- <widget class="QLabel" name="mLbHD3" >
+ <widget class="QLabel" name="m_pFormatLabel" >
<property name="text" >
- <string>Attached to</string>
+ <string>Format:</string>
</property>
</widget>
</item>
<item row="2" column="1" >
- <widget class="QILabel" name="mIpHD3" >
+ <widget class="QILabel" name="m_pFormatPane" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="m_pDetailsLabel" >
+ <property name="text" >
+ <string>Storage details:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QILabel" name="m_pDetailsPane" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="m_pUsageLabel" >
+ <property name="text" >
+ <string>Attached to:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QILabel" name="m_pUsagePane" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
@@ -203,7 +237,7 @@
<item row="0" column="0" >
<widget class="QLabel" name="mLbCD1" >
<property name="text" >
- <string>Location</string>
+ <string>Location:</string>
</property>
</widget>
</item>
@@ -220,7 +254,7 @@
<item row="1" column="0" >
<widget class="QLabel" name="mLbCD2" >
<property name="text" >
- <string>Attached to</string>
+ <string>Attached to:</string>
</property>
</widget>
</item>
@@ -294,7 +328,7 @@
<item row="0" column="0" >
<widget class="QLabel" name="mLbFD1" >
<property name="text" >
- <string>Location</string>
+ <string>Location:</string>
</property>
</widget>
</item>
@@ -311,7 +345,7 @@
<item row="1" column="0" >
<widget class="QLabel" name="mLbFD2" >
<property name="text" >
- <string>Attached to</string>
+ <string>Attached to:</string>
</property>
</widget>
</item>
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxMedium.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxMedium.cpp
index 2e091538e..abd8a1405 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxMedium.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxMedium.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxMedium.cpp $ */
+/* $Id: VBoxMedium.cpp 37374 2011-06-08 10:08:19Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -50,6 +50,8 @@ VBoxMedium& VBoxMedium::operator= (const VBoxMedium &aOther)
mHardDiskFormat = aOther.hardDiskFormat();
mHardDiskType = aOther.hardDiskType();
+ mStorageDetails = aOther.storageDetails();
+
mUsage = aOther.usage();
mToolTip = aOther.tip();
@@ -132,6 +134,7 @@ void VBoxMedium::refresh()
{
mHardDiskFormat = mMedium.GetFormat();
mHardDiskType = vboxGlobal().mediumTypeString (mMedium);
+ mStorageDetails = vboxGlobal().toString((KMediumVariant)mMedium.GetVariant());
mIsReadOnly = mMedium.GetReadOnly();
/* Adjust the parent if its possible */
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxMedium.h b/src/VBox/Frontends/VirtualBox/src/VBoxMedium.h
index 4d28b78c0..2169f0603 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxMedium.h
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxMedium.h
@@ -166,6 +166,8 @@ public:
QString hardDiskFormat (bool aNoDiffs = false) const { return aNoDiffs ? root().mHardDiskFormat : mHardDiskFormat; }
QString hardDiskType (bool aNoDiffs = false) const { return aNoDiffs ? root().mHardDiskType : mHardDiskType; }
+ QString storageDetails() const { return mStorageDetails; }
+
QString usage (bool aNoDiffs = false) const { return aNoDiffs ? root().mUsage : mUsage; }
QString tip() const { return mToolTip; }
@@ -252,6 +254,8 @@ private:
QString mHardDiskFormat;
QString mHardDiskType;
+ QString mStorageDetails;
+
QString mUsage;
QString mToolTip;
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxSnapshotDetailsDlg.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxSnapshotDetailsDlg.cpp
index b36edebdd..9d8a16422 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxSnapshotDetailsDlg.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxSnapshotDetailsDlg.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxSnapshotDetailsDlg.cpp $ */
+/* $Id: VBoxSnapshotDetailsDlg.cpp 35710 2011-01-25 13:14:13Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxTakeSnapshotDlg.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxTakeSnapshotDlg.cpp
index 0267ab442..8037eb3ae 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxTakeSnapshotDlg.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxTakeSnapshotDlg.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxTakeSnapshotDlg.cpp $ */
+/* $Id: VBoxTakeSnapshotDlg.cpp 31319 2010-08-02 16:41:47Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxUpdateDlg.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxUpdateDlg.cpp
index de6c69d6c..4f9453588 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxUpdateDlg.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxUpdateDlg.cpp
@@ -5,7 +5,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;
@@ -27,6 +27,7 @@
#include "VBoxProblemReporter.h"
#include "VBoxUpdateDlg.h"
#include "UIIconPool.h"
+#include "VBoxUtils.h"
#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
/* VBoxVersion stuff */
@@ -243,7 +244,7 @@ VBoxUpdateDlg::VBoxUpdateDlg (VBoxUpdateDlg **aSelf, bool aForceRun, QWidget *aP
: QIWithRetranslateUI <QDialog> (aParent)
, mSelf (aSelf)
, mUrl ("http://update.virtualbox.org/query.php")
- , mHttp (new QIHttp (this, mUrl.host()))
+ , mHttp (new QIHttp (this))
, mForceRun (aForceRun)
{
/* Store external pointer to this dialog. */
@@ -256,6 +257,17 @@ VBoxUpdateDlg::VBoxUpdateDlg (VBoxUpdateDlg **aSelf, bool aForceRun, QWidget *aP
setWindowIcon(UIIconPool::iconSetFull(QSize (32, 32), QSize (16, 16),
":/refresh_32px.png", ":/refresh_16px.png"));
+ /* Setup HTTP proxy: */
+ UIProxyManager proxyManager(vboxGlobal().settings().proxySettings());
+ if (proxyManager.proxyEnabled())
+ {
+ mHttp->setProxy(proxyManager.proxyHost(), proxyManager.proxyPort().toInt(),
+ proxyManager.authEnabled() ? proxyManager.authLogin() : QString(),
+ proxyManager.authEnabled() ? proxyManager.authPassword() : QString());
+ }
+ /* Set HTTP host: */
+ mHttp->setHost(mUrl.host());
+
/* Setup other connections */
connect (mBtnCheck, SIGNAL (clicked()), this, SLOT (search()));
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxVMInformationDlg.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxVMInformationDlg.cpp
index 8202715a9..80c249bb3 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxVMInformationDlg.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxVMInformationDlg.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxVMInformationDlg.cpp $ */
+/* $Id: VBoxVMInformationDlg.cpp 35761 2011-01-28 13:19:26Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -273,7 +273,7 @@ void VBoxVMInformationDlg::retranslateUi()
}
/* Network statistics: */
- ulong count = vboxGlobal().virtualBox().GetSystemProperties().GetNetworkAdapterCount();
+ ulong count = vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3);
for (ulong i = 0; i < count; ++ i)
{
CNetworkAdapter na = machine.GetNetworkAdapter (i);
@@ -586,7 +586,7 @@ void VBoxVMInformationDlg::refreshStatistics()
result += hdrRow.arg (":/nw_16px.png").arg (tr ("Network Statistics"));
/* Network Adapters list */
- ulong count = vboxGlobal().virtualBox().GetSystemProperties().GetNetworkAdapterCount();
+ ulong count = vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3);
for (ulong slot = 0; slot < count; ++ slot)
{
if (m.GetNetworkAdapter (slot).GetEnabled())
@@ -689,4 +689,3 @@ QString VBoxVMInformationDlg::composeArticle (const QString &aBelongsTo, int aSp
return result;
}
-
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxVMLogViewer.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxVMLogViewer.cpp
index 569b65c08..199a4df0b 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxVMLogViewer.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxVMLogViewer.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxVMLogViewer.cpp $ */
+/* $Id: VBoxVMLogViewer.cpp 30356 2010-06-22 08:42:22Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIAdvancedSlider.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIAdvancedSlider.cpp
index 5a69aeac6..d4f9bee6b 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIAdvancedSlider.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIAdvancedSlider.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIAdvancedSlider.cpp $ */
+/* $Id: QIAdvancedSlider.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIArrowButtonPress.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIArrowButtonPress.cpp
index 773adb8c6..987ad299d 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIArrowButtonPress.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIArrowButtonPress.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIArrowButtonPress.cpp $ */
+/* $Id: QIArrowButtonPress.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIArrowButtonSwitch.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIArrowButtonSwitch.cpp
index 062cefb99..4075a22ee 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIArrowButtonSwitch.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIArrowButtonSwitch.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIArrowButtonSwitch.cpp $ */
+/* $Id: QIArrowButtonSwitch.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIArrowSplitter.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIArrowSplitter.cpp
index b55758ff9..64bf62196 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIArrowSplitter.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIArrowSplitter.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIArrowSplitter.cpp $ */
+/* $Id: QIArrowSplitter.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIDialog.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIDialog.cpp
index 46f10cb1c..527bda80d 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIDialog.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIDialog.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIDialog.cpp $ */
+/* $Id: QIDialog.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIDialogButtonBox.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIDialogButtonBox.cpp
index 84cfca887..b372a1283 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIDialogButtonBox.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIDialogButtonBox.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIDialogButtonBox.cpp $ */
+/* $Id: QIDialogButtonBox.cpp 30356 2010-06-22 08:42:22Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIFileDialog.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIFileDialog.cpp
index 98bd738ef..ace6753bd 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIFileDialog.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIFileDialog.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIFileDialog.cpp $ */
+/* $Id: QIFileDialog.cpp 37629 2011-06-24 12:46:48Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -367,9 +367,10 @@ QString QIFileDialog::getExistingDirectory (const QString &aDir,
QFileDialog::Options o;
# if defined (Q_WS_X11)
/** @todo see http://bugs.kde.org/show_bug.cgi?id=210904, make it conditional
- * when this bug is fixed (xtracker 5167) */
- if (vboxGlobal().isKWinManaged())
- o |= QFileDialog::DontUseNativeDialog;
+ * when this bug is fixed (xtracker 5167).
+ * Apparently not necessary anymore (xtracker 5748)! */
+// if (vboxGlobal().isKWinManaged())
+// o |= QFileDialog::DontUseNativeDialog;
# endif
if (aDirOnly)
o |= QFileDialog::ShowDirsOnly;
@@ -581,9 +582,10 @@ QString QIFileDialog::getSaveFileName (const QString &aStartWith,
QFileDialog::Options o;
# if defined (Q_WS_X11)
/** @todo see http://bugs.kde.org/show_bug.cgi?id=210904, make it conditional
- * when this bug is fixed (xtracker 5167) */
- if (vboxGlobal().isKWinManaged())
- o |= QFileDialog::DontUseNativeDialog;
+ * when this bug is fixed (xtracker 5167)
+ * Apparently not necessary anymore (xtracker 5748)! */
+// if (vboxGlobal().isKWinManaged())
+// o |= QFileDialog::DontUseNativeDialog;
# endif
if (!aResolveSymlinks)
o |= QFileDialog::DontResolveSymlinks;
@@ -831,9 +833,10 @@ QStringList QIFileDialog::getOpenFileNames (const QString &aStartWith,
o |= QFileDialog::DontResolveSymlinks;
# if defined (Q_WS_X11)
/** @todo see http://bugs.kde.org/show_bug.cgi?id=210904, make it conditional
- * when this bug is fixed (xtracker 5167) */
- if (vboxGlobal().isKWinManaged())
- o |= QFileDialog::DontUseNativeDialog;
+ * when this bug is fixed (xtracker 5167)
+ * Apparently not necessary anymore (xtracker 5748)! */
+// if (vboxGlobal().isKWinManaged())
+// o |= QFileDialog::DontUseNativeDialog;
# endif
if (aSingleFile)
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIHttp.h b/src/VBox/Frontends/VirtualBox/src/extensions/QIHttp.h
index 4ca045fb7..6b5cfb357 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIHttp.h
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIHttp.h
@@ -5,7 +5,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;
@@ -56,8 +56,8 @@ public:
MovedTemporarilyError /* Corresponds to 302 == moved temporarily response */
};
- QIHttp (QObject *aParent, const QString &aHostName, quint16 aPort = 80)
- : QHttp (aHostName, aPort, aParent)
+ QIHttp (QObject *aParent)
+ : QHttp (aParent)
, mStatusCode (0)
, mErrorCode (NoError)
{
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QILabel.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QILabel.cpp
index 3898d7d63..4e51505e5 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QILabel.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QILabel.cpp
@@ -1,4 +1,4 @@
-/* $Id: QILabel.cpp $ */
+/* $Id: QILabel.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QILabelSeparator.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QILabelSeparator.cpp
index a0ebcfb7f..2f1fc1de9 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QILabelSeparator.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QILabelSeparator.cpp
@@ -1,4 +1,4 @@
-/* $Id: QILabelSeparator.cpp $ */
+/* $Id: QILabelSeparator.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QILineEdit.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QILineEdit.cpp
index 42eaf8e20..fc5c311c2 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QILineEdit.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QILineEdit.cpp
@@ -1,4 +1,4 @@
-/* $Id: QILineEdit.cpp $ */
+/* $Id: QILineEdit.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIListView.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIListView.cpp
index 54ff879f1..6e4023e25 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIListView.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIListView.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIListView.cpp $ */
+/* $Id: QIListView.cpp 34064 2010-11-15 11:12:37Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIMainDialog.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIMainDialog.cpp
index 8f8355028..c1b5ead58 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIMainDialog.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIMainDialog.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIMainDialog.cpp $ */
+/* $Id: QIMainDialog.cpp 35131 2010-12-15 13:19:00Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.cpp
index e1bb1888d..ce5b108ae 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIMessageBox.cpp $ */
+/* $Id: QIMessageBox.cpp 31319 2010-08-02 16:41:47Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.h b/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.h
index bd8057d57..28f72be54 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.h
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.h
@@ -69,7 +69,9 @@ public:
ButtonMask = 0xFF,
Default = 0x100, Escape = 0x200,
- FlagMask = 0x300
+ FlagMask = 0x300,
+
+ OptionChosen = 0x400
};
QIMessageBox (const QString &aCaption, const QString &aText,
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIRichToolButton.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIRichToolButton.cpp
index fe776077d..5f41fd837 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIRichToolButton.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIRichToolButton.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIRichToolButton.cpp $ */
+/* $Id: QIRichToolButton.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QISplitter.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QISplitter.cpp
index 4ebdf9b29..9af79a277 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QISplitter.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QISplitter.cpp
@@ -1,4 +1,4 @@
-/* $Id: QISplitter.cpp $ */
+/* $Id: QISplitter.cpp 30868 2010-07-16 09:42:12Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIStateIndicator.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIStateIndicator.cpp
index 5cbb21073..15ea3531b 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIStateIndicator.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIStateIndicator.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIStateIndicator.cpp $ */
+/* $Id: QIStateIndicator.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIStatusBar.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIStatusBar.cpp
index 6aa7bde06..42cea93de 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIStatusBar.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIStatusBar.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIStatusBar.cpp $ */
+/* $Id: QIStatusBar.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QITableView.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QITableView.cpp
index 964cf5d1f..fb51a5b79 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QITableView.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QITableView.cpp
@@ -1,4 +1,4 @@
-/* $Id: QITableView.cpp $ */
+/* $Id: QITableView.cpp 31533 2010-08-10 13:08:56Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QITreeView.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QITreeView.cpp
index 7c42e72bf..2ab67624b 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QITreeView.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QITreeView.cpp
@@ -1,4 +1,4 @@
-/* $Id: QITreeView.cpp $ */
+/* $Id: QITreeView.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QITreeWidget.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QITreeWidget.cpp
index e03966a78..af057d911 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QITreeWidget.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QITreeWidget.cpp
@@ -1,4 +1,4 @@
-/* $Id: QITreeWidget.cpp $ */
+/* $Id: QITreeWidget.cpp 37610 2011-06-23 12:26:14Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIWidgetValidator.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIWidgetValidator.cpp
index 012c4aa75..e8d54ec65 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIWidgetValidator.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIWidgetValidator.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIWidgetValidator.cpp $ */
+/* $Id: QIWidgetValidator.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIWizard.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIWizard.cpp
index d2bfaa7f0..85ebfeade 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIWizard.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIWizard.cpp
@@ -1,4 +1,4 @@
-/* $Id: QIWizard.cpp $ */
+/* $Id: QIWizard.cpp 35234 2010-12-20 09:40:31Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.cpp b/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.cpp
index ea16aa07a..3543defcf 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.cpp
@@ -1,4 +1,4 @@
-/* $Id: COMDefs.cpp $ */
+/* $Id: COMDefs.cpp 37015 2011-05-09 14:11:00Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -21,6 +21,7 @@
#if !defined (VBOX_WITH_XPCOM)
+
#else /* !defined (VBOX_WITH_XPCOM) */
/* Qt includes */
@@ -86,16 +87,11 @@ private:
/**
* Initializes COM/XPCOM.
*/
-HRESULT COMBase::InitializeCOM()
+HRESULT COMBase::InitializeCOM(bool fGui)
{
LogFlowFuncEnter();
- /* Note: On Win32, Qt somehow calls CoInitialize[Ex]() during creation of
- * the QApplication instance (didn't explore deeply why it does so) with
- * different flags which is incompatible with our multithreaded
- * apartment. com::Initialize() will properly care of this situation. */
-
- HRESULT rc = com::Initialize();
+ HRESULT rc = com::Initialize(fGui);
#if defined (VBOX_WITH_XPCOM)
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h b/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h
index b8fd65170..88fa30c58 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h
+++ b/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h
@@ -202,7 +202,7 @@ class COMBase
{
public:
- static HRESULT InitializeCOM();
+ static HRESULT InitializeCOM(bool fGui);
static HRESULT CleanupCOM();
/**
@@ -354,7 +354,7 @@ public:
protected:
/* no arbitrary instance creations */
- COMBase() : mRC (S_OK) {};
+ COMBase() : mRC (S_OK) {}
#if defined (VBOX_WITH_XPCOM)
static XPCOMEventQSocketListener *sSocketListener;
@@ -632,44 +632,61 @@ public:
// constructors & destructor
- CInterface() : mIface (NULL) {}
+ CInterface()
+ {
+ clear();
+ }
- CInterface (const CInterface &that) : B (that), mIface (that.mIface)
+ CInterface (const CInterface &that) : B (that)
{
- addref (mIface);
+ clear();
+ mIface = that.mIface;
+ addref(ptr());
}
- CInterface (I *aIface) : mIface (aIface) { addref (mIface); }
+ CInterface (I *aIface)
+ {
+ clear();
+ setPtr (aIface);
+ addref (aIface);
+ }
- virtual ~CInterface() { release (mIface); }
+ virtual ~CInterface()
+ {
+ detach();
+#ifdef DEBUG
+ mDead = true;
+#endif
+ }
// utility methods
-
void createInstance (const CLSID &aClsId)
{
- AssertMsg (!mIface, ("Instance is already non-NULL\n"));
- if (!mIface)
+ AssertMsg (ptr() == NULL, ("Instance is already non-NULL\n"));
+ if (ptr() == NULL)
{
+ I* pObj = NULL;
#if !defined (VBOX_WITH_XPCOM)
-
B::mRC = CoCreateInstance (aClsId, NULL, CLSCTX_ALL,
- _ATL_IIDOF (I), (void **) &mIface);
-
-#else /* !defined (VBOX_WITH_XPCOM) */
-
+ _ATL_IIDOF (I), (void **) &pObj);
+#else
nsCOMPtr <nsIComponentManager> manager;
B::mRC = NS_GetComponentManager (getter_AddRefs (manager));
if (SUCCEEDED (B::mRC))
B::mRC = manager->CreateInstance (aClsId, nsnull, NS_GET_IID (I),
- (void **) &mIface);
+ (void **) &pObj);
+#endif
-#endif /* !defined (VBOX_WITH_XPCOM) */
+ if (SUCCEEDED (B::mRC))
+ setPtr(pObj);
+ else
+ setPtr(NULL);
/* fetch error info, but don't assert if it's missing -- many other
* reasons can lead to an error (w/o providing error info), not only
* the instance initialization code (that should always provide it) */
B::fetchErrorInfo (NULL, NULL);
- }
+ }
}
/**
@@ -679,18 +696,23 @@ public:
template <class OI>
void attach (OI *aIface)
{
+#ifdef DEBUG
+ Assert(!mDead);
+#endif
/* be aware of self assignment */
+ I* amIface = ptr();
addref (aIface);
- release (mIface);
+ release (amIface);
if (aIface)
{
- mIface = NULL;
- B::mRC = aIface->QueryInterface (COM_IIDOF (I), (void **) &mIface);
+ amIface = NULL;
+ B::mRC = aIface->QueryInterface (COM_IIDOF (I), (void **) &amIface);
release (aIface);
+ setPtr(amIface);
}
else
{
- mIface = NULL;
+ setPtr(NULL);
B::mRC = S_OK;
}
};
@@ -698,18 +720,34 @@ public:
/** Specialization of attach() for our own interface I. Never fails. */
void attach (I *aIface)
{
+#ifdef DEBUG
+ Assert(!mDead);
+#endif
/* be aware of self assignment */
addref (aIface);
- release (mIface);
- mIface = aIface;
+ release (ptr());
+ setPtr(aIface);
B::mRC = S_OK;
};
/** Detaches from the underlying interface pointer. */
- void detach() { release (mIface); mIface = NULL; }
+ void detach()
+ {
+#ifdef DEBUG
+ Assert(!mDead);
+#endif
+ release (ptr());
+ setPtr(NULL);
+ }
/** Returns @c true if not attached to any interface pointer. */
- bool isNull() const { return mIface == NULL; }
+ bool isNull() const
+ {
+#ifdef DEBUG
+ Assert(!mDead);
+#endif
+ return mIface == NULL;
+ }
/**
* Returns @c true if the result code represents success (with or without
@@ -732,7 +770,7 @@ public:
CInterface &operator= (const CInterface &that)
{
- attach (that.mIface);
+ attach (that.ptr());
B::operator= (that);
return *this;
}
@@ -747,18 +785,44 @@ public:
* Returns the raw interface pointer. Not intended to be used for anything
* else but in generated wrappers and for debugging. You've been warned.
*/
- I *raw() const { return mIface; }
+ I *raw() const
+ {
+ return ptr();
+ }
- bool operator== (const CInterface &that) const { return mIface == that.mIface; }
- bool operator!= (const CInterface &that) const { return mIface != that.mIface; }
+ bool operator== (const CInterface &that) const { return ptr() == that.ptr(); }
+ bool operator!= (const CInterface &that) const { return ptr() != that.ptr(); }
-/**
- * @todo: rethink if we'll ever need 'protected' back, removed to allow mIface access in rather
- * nontrivial inheritance situations, see 'friend wrappers' code in COMWrappers.xsl
- */
-//protected:
+ I* ptr() const
+ {
+#ifdef DEBUG
+ Assert(!mDead);
+#endif
+
+ return mIface;
+ }
- mutable I *mIface;
+ void setPtr(I* aObj) const
+ {
+#ifdef DEBUG
+ Assert(!mDead);
+#endif
+ mIface = aObj;
+ }
+
+private:
+#ifdef DEBUG
+ bool mDead;
+#endif
+ mutable I * mIface;
+
+ void clear()
+ {
+ mIface = NULL;
+#ifdef DEBUG
+ mDead = false;
+#endif
+ }
};
/////////////////////////////////////////////////////////////////////////////
@@ -775,7 +839,7 @@ public:
template <class OI, class OB>
explicit CUnknown (const CInterface <OI, OB> &that)
{
- attach (that.mIface);
+ attach (that.ptr());
if (SUCCEEDED (mRC))
{
/* preserve old error info if any */
@@ -801,7 +865,7 @@ public:
template <class OI, class OB>
CUnknown &operator= (const CInterface <OI, OB> &that)
{
- attach (that.mIface);
+ attach (that.ptr());
if (SUCCEEDED (mRC))
{
/* preserve old error info if any */
@@ -832,9 +896,6 @@ public:
Base::operator= (aIface);
return *this;
}
-
- /* @internal Used in generated wrappers. Never use directly. */
- IUnknown *&rawRef() { return mIface; };
};
/////////////////////////////////////////////////////////////////////////////
@@ -848,6 +909,7 @@ Q_DECLARE_METATYPE(CHost);
Q_DECLARE_METATYPE(CMachine);
Q_DECLARE_METATYPE(CConsole);
Q_DECLARE_METATYPE(CHostNetworkInterface);
+Q_DECLARE_METATYPE(CMediumFormat);
/** @} */
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/COMWrappers.xsl b/src/VBox/Frontends/VirtualBox/src/globals/COMWrappers.xsl
index 87ed37886..95258158d 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/COMWrappers.xsl
+++ b/src/VBox/Frontends/VirtualBox/src/globals/COMWrappers.xsl
@@ -950,7 +950,7 @@
<xsl:if test="$define">
<xsl:text>&#x0A;{&#x0A;</xsl:text>
<!-- iface assertion -->
- <xsl:text> AssertReturnVoid(mIface);&#x0A;</xsl:text>
+ <xsl:text> AssertReturnVoid(ptr());&#x0A;</xsl:text>
<!-- method call -->
<xsl:call-template name="composeMethodCall">
<xsl:with-param name="isSetter" select="'yes'"/>
@@ -989,7 +989,7 @@
<xsl:apply-templates select="$return/@type" mode="initializer"/>
<xsl:text>;&#x0A;</xsl:text>
<!-- iface assertion -->
- <xsl:text> AssertReturn(mIface, a</xsl:text>
+ <xsl:text> AssertReturn(ptr(), a</xsl:text>
<xsl:call-template name="capitalize">
<xsl:with-param name="str" select="$return/@name"/>
</xsl:call-template>
@@ -1096,7 +1096,7 @@
</xsl:when>
</xsl:choose>
<!-- start the call -->
- <xsl:text> mRC = mIface-></xsl:text>
+ <xsl:text> mRC = ptr()-></xsl:text>
<xsl:choose>
<!-- attribute method call -->
<xsl:when test="name()='attribute'">
@@ -1136,6 +1136,11 @@
</xsl:when>
</xsl:choose>
<xsl:text>);&#x0A;</xsl:text>
+
+ <xsl:text>#ifdef RT_OS_WINDOWS&#x0A;</xsl:text>
+ <xsl:text> Assert(mRC != RPC_E_WRONG_THREAD);&#x0A;</xsl:text>
+ <xsl:text>#endif&#x0A;</xsl:text>
+
<!-- apply 'post-call' hooks -->
<xsl:choose>
<xsl:when test="name()='attribute'">
@@ -1200,7 +1205,7 @@
<xsl:otherwise>
<xsl:if test="$supports='strict' or $supports='yes'">
<xsl:text> if (RT_UNLIKELY(mRC != S_OK))&#x0A; {&#x0A;</xsl:text>
- <xsl:text> fetchErrorInfo(mIface, &amp;COM_IIDOF(Base::Iface));&#x0A;</xsl:text>
+ <xsl:text> fetchErrorInfo(ptr(), &amp;COM_IIDOF(Base::Iface));&#x0A;</xsl:text>
<xsl:if test="$supports='strict'">
<xsl:text> AssertMsg(errInfo.isFullAvailable(), </xsl:text>
<xsl:text>("for RC=0x%08X\n", mRC));&#x0A;</xsl:text>
@@ -1293,28 +1298,10 @@
<xsl:call-template name="capitalize">
<xsl:with-param name="str" select="@name"/>
</xsl:call-template>
- <xsl:choose>
- <xsl:when test="@type='$unknown'">
- <xsl:text>.raw()</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>.mIface</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
+ <xsl:text>.ptr()</xsl:text>
</xsl:when>
<xsl:when test="$isOut">
- <xsl:text>&amp;a</xsl:text>
- <xsl:call-template name="capitalize">
- <xsl:with-param name="str" select="@name"/>
- </xsl:call-template>
- <xsl:choose>
- <xsl:when test="@type='$unknown'">
- <xsl:text>.rawRef()</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>.mIface</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
+ <xsl:value-of select="concat('&amp;', @name, 'Ptr')"/>
</xsl:when>
</xsl:choose>
</xsl:when>
@@ -1782,6 +1769,11 @@
(ancestor::library/if[@target=$self_target]/enum[@name=current()/@type])
)"/>
+ <xsl:variable name="is_out" select="(
+ (name()='attribute' and not($isSetter)) or
+ (name()='param' and (@dir='out' or @dir='return'))
+ )"/>
+
<xsl:choose>
<xsl:when test="$when='pre-call'">
<xsl:choose>
@@ -1837,13 +1829,24 @@
<xsl:text>);&#x0A;</xsl:text>
</xsl:if>
</xsl:when>
+ <xsl:when test="$is_out and ($is_iface or (@type='$unknown'))">
+ <xsl:text> </xsl:text>
+ <xsl:choose>
+ <xsl:when test="@type='$unknown'">
+ <xsl:text>IUnknown</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@type"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:value-of select="concat('* ',@name,'Ptr = NULL;&#10;')"/>
+ </xsl:when>
</xsl:choose>
</xsl:when>
<xsl:when test="$when='post-call'">
<xsl:choose>
<xsl:when test="@safearray='yes'">
- <xsl:if test="(name()='attribute' and not($isSetter)) or
- (name()='param' and (@dir='out' or @dir='return'))">
+ <xsl:if test="$is_out">
<!-- convert SafeArray to QVector -->
<xsl:choose>
<!-- interface types need special treatment here -->
@@ -1863,6 +1866,13 @@
<xsl:text>);&#x0A;</xsl:text>
</xsl:if>
</xsl:when>
+ <xsl:when test="$is_out and ($is_iface or (@type='$unknown'))">
+ <xsl:text> a</xsl:text>
+ <xsl:call-template name="capitalize">
+ <xsl:with-param name="str" select="@name"/>
+ </xsl:call-template>
+ <xsl:value-of select="concat('.setPtr(',@name,'Ptr);&#10;')"/>
+ </xsl:when>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.cpp b/src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.cpp
index 68e41528c..936d27425 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIExtraDataEventHandler.cpp $ */
+/* $Id: UIExtraDataEventHandler.cpp 35722 2011-01-26 16:37:16Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -251,7 +251,9 @@ UIExtraDataEventHandler::UIExtraDataEventHandler()
{
// RTPrintf("Self add: %RTthrd\n", RTThreadSelf());
const CVirtualBox &vbox = vboxGlobal().virtualBox();
- UIMainEventListenerImpl *pListener = new UIMainEventListenerImpl(this);
+ ComObjPtr<UIMainEventListenerImpl> pListener;
+ pListener.createObject();
+ pListener->init(new UIMainEventListener(), this);
m_mainEventListener = CEventListener(pListener);
QVector<KVBoxEventType> events;
events
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/UIIconPool.cpp b/src/VBox/Frontends/VirtualBox/src/globals/UIIconPool.cpp
index 7caaf05d5..1ce6a6bf8 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/UIIconPool.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/UIIconPool.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIIconPool.cpp $ */
+/* $Id: UIIconPool.cpp 30206 2010-06-15 15:41:05Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/UIImageTools.cpp b/src/VBox/Frontends/VirtualBox/src/globals/UIImageTools.cpp
index 5a94870b5..fa4e996f1 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/UIImageTools.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/UIImageTools.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIImageTools.cpp $ */
+/* $Id: UIImageTools.cpp 35424 2011-01-07 13:05:41Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.cpp b/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.cpp
index 24c7d58ed..90e27ec8a 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMainEventListener.cpp $ */
+/* $Id: UIMainEventListener.cpp 37712 2011-06-30 14:11:14Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -24,8 +24,7 @@
//#include <iprt/thread.h>
//#include <iprt/stream.h>
-UIMainEventListener::UIMainEventListener(QObject * /* pParent */)
-// : QObject(pParent) /* Todo: Not sure if pParent should delete this. Especially on Win there is ref counting implemented. */
+UIMainEventListener::UIMainEventListener()
: QObject()
{
/* For queued events we have to extra register our enums/interface classes
@@ -41,6 +40,14 @@ UIMainEventListener::UIMainEventListener(QObject * /* pParent */)
qRegisterMetaType<CVirtualBoxErrorInfo>("CVirtualBoxErrorInfo");
}
+HRESULT UIMainEventListener::init(QObject * /* pParent */)
+{
+ return S_OK;
+}
+
+void UIMainEventListener::uninit()
+{
+}
/**
* @todo: instead of double wrapping of events into signals maybe it
@@ -49,7 +56,7 @@ UIMainEventListener::UIMainEventListener(QObject * /* pParent */)
STDMETHODIMP UIMainEventListener::HandleEvent(VBoxEventType_T /* type */, IEvent *pEvent)
{
CEvent event(pEvent);
-// RTPrintf("Event received: %d (%RTthrd)\n", event.GetType(), RTThreadSelf());
+ // printf("Event received: %d\n", event.GetType());
switch(event.GetType())
{
/*
@@ -163,9 +170,13 @@ STDMETHODIMP UIMainEventListener::HandleEvent(VBoxEventType_T /* type */, IEvent
}
/* Not used *
case KVBoxEventType_OnCPUChange:
- case KVBoxEventType_OnVRDEServerChange:
- case KVBoxEventType_OnVRDEServerInfoChange:
*/
+ case KVBoxEventType_OnVRDEServerChanged:
+ case KVBoxEventType_OnVRDEServerInfoChanged:
+ {
+ emit sigVRDEChange();
+ break;
+ }
case KVBoxEventType_OnUSBControllerChanged:
{
emit sigUSBControllerChange();
@@ -179,7 +190,6 @@ STDMETHODIMP UIMainEventListener::HandleEvent(VBoxEventType_T /* type */, IEvent
}
case KVBoxEventType_OnSharedFolderChanged:
{
- CSharedFolderChangedEvent es(pEvent);
emit sigSharedFolderChange();
break;
}
@@ -209,6 +219,11 @@ STDMETHODIMP UIMainEventListener::HandleEvent(VBoxEventType_T /* type */, IEvent
es.SetWinId(winId);
break;
}
+ case KVBoxEventType_OnCPUExecutionCapChanged:
+ {
+ emit sigCPUExecutionCapChange();
+ break;
+ }
default: break;
}
return S_OK;
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.h b/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.h
index 7a1672e6f..5a2ea5e86 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.h
+++ b/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.h
@@ -42,7 +42,11 @@ class UIMainEventListener: public QObject
Q_OBJECT;
public:
- UIMainEventListener(QObject *pParent);
+ UIMainEventListener();
+
+
+ HRESULT init(QObject *pParent);
+ void uninit();
STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *pEvent);
@@ -63,12 +67,14 @@ signals:
void sigAdditionsChange();
void sigNetworkAdapterChange(CNetworkAdapter adapter);
void sigMediumChange(CMediumAttachment attachment);
+ void sigVRDEChange();
void sigUSBControllerChange();
void sigUSBDeviceStateChange(CUSBDevice device, bool fAttached, CVirtualBoxErrorInfo error);
void sigSharedFolderChange();
void sigRuntimeError(bool fFatal, QString strId, QString strMessage);
void sigCanShowWindow(bool &fVeto, QString &strReason); /* use Qt::DirectConnection */
void sigShowWindow(LONG64 &winId); /* use Qt::DirectConnection */
+ void sigCPUExecutionCapChange();
};
/* Wrap the IListener interface around our implementation class. */
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.cpp b/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.cpp
index 13609c3b8..134ccb80f 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxDefs.cpp $ */
+/* $Id: VBoxDefs.cpp 35897 2011-02-08 13:25:30Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.h b/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.h
index fcb95e748..8c9932814 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.h
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2006-2009 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;
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
index 201139f0d..7bbc39cc9 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGlobal.cpp $ */
+/* $Id: VBoxGlobal.cpp 37838 2011-07-08 11:27:16Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -6,7 +6,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;
@@ -1238,6 +1238,24 @@ StorageSlot VBoxGlobal::toStorageSlot (const QString &aSlot) const
return result;
}
+QString VBoxGlobal::toString(KMediumVariant mediumVariant) const
+{
+ switch (mediumVariant)
+ {
+ case KMediumVariant_Standard:
+ return tr("Dynamically allocated storage");
+ case (KMediumVariant)(KMediumVariant_Standard | KMediumVariant_Fixed):
+ return tr("Fixed size storage");
+ case (KMediumVariant)(KMediumVariant_Standard | KMediumVariant_VmdkSplit2G):
+ return tr("Dynamically allocated storage split into files of less than 2GB");
+ case (KMediumVariant)(KMediumVariant_Standard | KMediumVariant_Fixed | KMediumVariant_VmdkSplit2G):
+ return tr("Fixed size storage split into files of less than 2GB");
+ default:
+ break;
+ }
+ return QString();
+}
+
/**
* Returns the list of all device types (VirtualBox::DeviceType COM enum).
*/
@@ -1631,6 +1649,9 @@ QString VBoxGlobal::detailsReport (const CMachine &aMachine, bool aWithLinks)
+ QString (sSectionItemTpl2).arg (tr ("Processor(s)", "details report"),
tr ("<nobr>%1</nobr>", "details report"))
.arg (aMachine.GetCPUCount())
+ + QString (sSectionItemTpl2).arg (tr ("Execution Cap", "details report"),
+ tr ("<nobr>%1%</nobr>", "details report"))
+ .arg (aMachine.GetCPUExecutionCap())
+ QString (sSectionItemTpl2).arg (tr ("Boot Order", "details report"), bootOrder)
#ifdef VBOX_WITH_FULL_DETAILS_REPORT
+ QString (sSectionItemTpl2).arg (tr ("ACPI", "details report"), acpi)
@@ -1813,7 +1834,7 @@ QString VBoxGlobal::detailsReport (const CMachine &aMachine, bool aWithLinks)
{
QString item;
- ulong count = mVBox.GetSystemProperties().GetNetworkAdapterCount();
+ ulong count = mVBox.GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3);
int rows = 2; /* including section header and footer */
for (ulong slot = 0; slot < count; slot ++)
{
@@ -1828,18 +1849,16 @@ QString VBoxGlobal::detailsReport (const CMachine &aMachine, bool aWithLinks)
* this name instead */
if (type == KNetworkAttachmentType_Bridged)
attType = attType.arg (tr ("Bridged adapter, %1",
- "details report (network)").arg (adapter.GetHostInterface()));
+ "details report (network)").arg (adapter.GetBridgedInterface()));
else if (type == KNetworkAttachmentType_Internal)
attType = attType.arg (tr ("Internal network, '%1'",
"details report (network)").arg (adapter.GetInternalNetwork()));
else if (type == KNetworkAttachmentType_HostOnly)
attType = attType.arg (tr ("Host-only adapter, '%1'",
- "details report (network)").arg (adapter.GetHostInterface()));
-#ifdef VBOX_WITH_VDE
- else if (type == KNetworkAttachmentType_VDE)
- attType = attType.arg (tr ("VDE network, '%1'",
- "details report (network)").arg (adapter.GetVDENetwork()));
-#endif
+ "details report (network)").arg (adapter.GetHostOnlyInterface()));
+ else if (type == KNetworkAttachmentType_Generic)
+ attType = attType.arg (tr ("Generic, '%1'",
+ "details report (network)").arg (adapter.GetGenericDriver()));
else
attType = attType.arg (vboxGlobal().toString (type));
@@ -2389,7 +2408,7 @@ void VBoxGlobal::startEnumeratingMedia()
virtual void run()
{
LogFlow (("MediaEnumThread started.\n"));
- COMBase::InitializeCOM();
+ COMBase::InitializeCOM(false);
CVirtualBox mVBox = vboxGlobal().virtualBox();
QObject *self = &vboxGlobal();
@@ -2737,7 +2756,7 @@ QString VBoxGlobal::openMedium(VBoxDefs::MediumType mediumType, QString strMediu
vbox.SetExtraData(strRecentListKey, recentMediumList.join(";"));
/* Open corresponding medium: */
- CMedium comMedium = vbox.OpenMedium(strMediumLocation, mediumTypeToGlobal(mediumType), KAccessMode_ReadWrite);
+ CMedium comMedium = vbox.OpenMedium(strMediumLocation, mediumTypeToGlobal(mediumType), KAccessMode_ReadWrite, false);
if (vbox.isOk())
{
@@ -2968,10 +2987,15 @@ void VBoxGlobal::retranslateUi()
tr ("Internal Network", "NetworkAttachmentType");
mNetworkAttachmentTypes [KNetworkAttachmentType_HostOnly] =
tr ("Host-only Adapter", "NetworkAttachmentType");
-#ifdef VBOX_WITH_VDE
- mNetworkAttachmentTypes [KNetworkAttachmentType_VDE] =
- tr ("VDE Adapter", "NetworkAttachmentType");
-#endif
+ mNetworkAttachmentTypes [KNetworkAttachmentType_Generic] =
+ tr ("Generic Driver", "NetworkAttachmentType");
+
+ mNetworkAdapterPromiscModePolicyTypes [KNetworkAdapterPromiscModePolicy_Deny] =
+ tr ("Deny", "NetworkAdapterPromiscModePolicyType");
+ mNetworkAdapterPromiscModePolicyTypes [KNetworkAdapterPromiscModePolicy_AllowNetwork] =
+ tr ("Allow VMs", "NetworkAdapterPromiscModePolicyType");
+ mNetworkAdapterPromiscModePolicyTypes [KNetworkAdapterPromiscModePolicy_AllowAll] =
+ tr ("Allow All", "NetworkAdapterPromiscModePolicyType");
mNATProtocolTypes [KNATProtocol_UDP] =
tr ("UDP", "NATProtocolType");
@@ -3797,27 +3821,12 @@ QString VBoxGlobal::formatSize (quint64 aSize, uint aDecimal /* = 2 */,
return QString ("%1 %2").arg (number).arg (Suffixes [suffix]);
}
-/* static */
-bool VBoxGlobal::shouldWarnAboutToLowVRAM(const CMachine *pMachine /* = 0 */)
-{
- static QStringList osList = QStringList()
- << "Other" << "DOS" << "Netware" << "L4" << "QNX" << "JRockitVE";
-
- bool fResult = true;
- if ( pMachine
- && !pMachine->isNull()
- && osList.contains(pMachine->GetOSTypeId()))
- fResult = false;
-
- return fResult;
-}
-
/**
* Returns the required video memory in bytes for the current desktop
* resolution at maximum possible screen depth in bpp.
*/
/* static */
-quint64 VBoxGlobal::requiredVideoMemory (CMachine *aMachine /* = 0 */, int cMonitors /* = 1 */)
+quint64 VBoxGlobal::requiredVideoMemory(const QString &strGuestOSTypeId, int cMonitors /* = 1 */)
{
QSize desktopRes = QApplication::desktop()->screenGeometry().size();
QDesktopWidget *pDW = QApplication::desktop();
@@ -3855,23 +3864,19 @@ quint64 VBoxGlobal::requiredVideoMemory (CMachine *aMachine /* = 0 */, int cMoni
quint64 needMBytes = needBits % (8 * _1M) ? needBits / (8 * _1M) + 1 :
needBits / (8 * _1M) /* convert to megabytes */;
- if (aMachine && !aMachine->isNull())
+ if (strGuestOSTypeId.startsWith("Windows"))
{
- QString typeId = aMachine->GetOSTypeId();
- if (typeId.startsWith("Windows"))
- {
- /* Windows guests need offscreen VRAM too for graphics acceleration features. */
+ /* Windows guests need offscreen VRAM too for graphics acceleration features: */
#ifdef VBOX_WITH_CRHGSMI
- if (typeId == "WindowsVista" || typeId == "Windows7")
- {
- /* wddm mode, there are two surfaces for each screen: shadow & primary */
- needMBytes *= 3;
- }
- else
-#endif
- {
- needMBytes *= 2;
- }
+ if (isWddmCompatibleOsType(strGuestOSTypeId))
+ {
+ /* wddm mode, there are two surfaces for each screen: shadow & primary */
+ needMBytes *= 3;
+ }
+ else
+#endif /* VBOX_WITH_CRHGSMI */
+ {
+ needMBytes *= 2;
}
}
@@ -4426,14 +4431,20 @@ quint64 VBoxGlobal::required2DOffscreenVideoMemory()
#ifdef VBOX_WITH_CRHGSMI
/* static */
-quint64 VBoxGlobal::required3DWddmOffscreenVideoMemory(CMachine *aMachine /* = 0 */, int cMonitors /* = 1 */)
+quint64 VBoxGlobal::required3DWddmOffscreenVideoMemory(const QString &strGuestOSTypeId, int cMonitors /* = 1 */)
{
cMonitors = RT_MAX(cMonitors, 1);
- quint64 cbSize = VBoxGlobal::requiredVideoMemory(aMachine, 1); /* why not cMonitors? */
+ quint64 cbSize = VBoxGlobal::requiredVideoMemory(strGuestOSTypeId, 1); /* why not cMonitors? */
cbSize += 64 * _1M;
return cbSize;
}
-#endif
+
+/* static */
+bool VBoxGlobal::isWddmCompatibleOsType(const QString &strGuestOSTypeId)
+{
+ return strGuestOSTypeId.startsWith("WindowsVista") || strGuestOSTypeId.startsWith("Windows7") || strGuestOSTypeId.startsWith("Windows2008");
+}
+#endif /* VBOX_WITH_CRHGSMI */
#ifdef Q_WS_MAC
bool VBoxGlobal::isSheetWindowsAllowed(QWidget *pParent) const
@@ -4784,16 +4795,12 @@ void VBoxGlobal::init()
mVerString += " [DEBUG]";
#endif
-#ifdef Q_WS_WIN
- /* COM for the main thread is initialized in main() */
-#else
- HRESULT rc = COMBase::InitializeCOM();
+ HRESULT rc = COMBase::InitializeCOM(true);
if (FAILED (rc))
{
vboxProblem().cannotInitCOM (rc);
return;
}
-#endif
mVBox.createInstance (CLSID_VirtualBox);
if (!mVBox.isOk())
@@ -4935,8 +4942,8 @@ void VBoxGlobal::init()
{"NetBSD_64", ":/os_netbsd_64.png"},
{"Solaris", ":/os_solaris.png"},
{"Solaris_64", ":/os_solaris_64.png"},
- {"OpenSolaris", ":/os_opensolaris.png"},
- {"OpenSolaris_64", ":/os_opensolaris_64.png"},
+ {"OpenSolaris", ":/os_oraclesolaris.png"},
+ {"OpenSolaris_64", ":/os_oraclesolaris_64.png"},
{"QNX", ":/os_qnx.png"},
{"MacOS", ":/os_macosx.png"},
{"MacOS_64", ":/os_macosx_64.png"},
@@ -5271,11 +5278,7 @@ void VBoxGlobal::cleanup()
* before uninitializing the COM subsystem. */
QApplication::removePostedEvents (this);
-#ifdef Q_WS_WIN
- /* COM for the main thread is shutdown in main() */
-#else
COMBase::CleanupCOM();
-#endif
mValid = false;
}
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
index 386d442c4..254cc733e 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
@@ -5,7 +5,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;
@@ -314,6 +314,9 @@ public:
AssertMsg (!mDiskTypes.value (t).isNull(), ("No text for %d", t));
return mDiskTypes.value (t);
}
+ QString differencingMediumTypeName() const { return mDiskTypes_Differencing; }
+
+ QString toString(KMediumVariant mediumVariant) const;
/**
* Similar to toString (KMediumType), but returns 'Differencing' for
@@ -481,6 +484,21 @@ public:
return KNetworkAttachmentType (it.key());
}
+ QString toString (KNetworkAdapterPromiscModePolicy t) const
+ {
+ AssertMsg (!mNetworkAdapterPromiscModePolicyTypes.value (t).isNull(), ("No text for %d", t));
+ return mNetworkAdapterPromiscModePolicyTypes.value (t);
+ }
+
+ KNetworkAdapterPromiscModePolicy toNetworkAdapterPromiscModePolicyType (const QString &s) const
+ {
+ QULongStringHash::const_iterator it =
+ qFind (mNetworkAdapterPromiscModePolicyTypes.begin(), mNetworkAdapterPromiscModePolicyTypes.end(), s);
+ AssertMsg (it != mNetworkAdapterPromiscModePolicyTypes.end(), ("No value for {%s}",
+ s.toLatin1().constData()));
+ return KNetworkAdapterPromiscModePolicy (it.key());
+ }
+
QString toString (KNATProtocol t) const
{
AssertMsg (!mNATProtocolTypes.value (t).isNull(), ("No text for %d", t));
@@ -620,7 +638,6 @@ public:
/* public static stuff */
- static bool shouldWarnAboutToLowVRAM(const CMachine *pMachine = 0);
static bool isDOSType (const QString &aOSTypeId);
static QString languageId();
@@ -647,7 +664,7 @@ public:
static QString formatSize (quint64 aSize, uint aDecimal = 2,
VBoxDefs::FormatSize aMode = VBoxDefs::FormatSize_Round);
- static quint64 requiredVideoMemory (CMachine *aMachine = 0, int cMonitors = 1);
+ static quint64 requiredVideoMemory(const QString &strGuestOSTypeId, int cMonitors = 1);
static QString locationForHTML (const QString &aFileName);
@@ -699,8 +716,9 @@ public:
#endif
#ifdef VBOX_WITH_CRHGSMI
- static quint64 required3DWddmOffscreenVideoMemory(CMachine *aMachine = 0, int cMonitors = 1);
-#endif
+ static bool isWddmCompatibleOsType(const QString &strGuestOSTypeId);
+ static quint64 required3DWddmOffscreenVideoMemory(const QString &strGuestOSTypeId, int cMonitors = 1);
+#endif /* VBOX_WITH_CRHGSMI */
#ifdef Q_WS_MAC
bool isSheetWindowsAllowed(QWidget *pParent) const;
@@ -853,6 +871,7 @@ private:
QULongStringHash mAudioControllerTypes;
QULongStringHash mNetworkAdapterTypes;
QULongStringHash mNetworkAttachmentTypes;
+ QULongStringHash mNetworkAdapterPromiscModePolicyTypes;
QULongStringHash mNATProtocolTypes;
QULongStringHash mClipboardTypes;
QULongStringHash mStorageControllerTypes;
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.cpp b/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.cpp
index 001345e4d..c6ac4b271 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxProblemReporter.cpp $ */
+/* $Id: VBoxProblemReporter.cpp 37916 2011-07-13 12:46:11Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -253,6 +253,107 @@ int VBoxProblemReporter::message (QWidget *aParent, Type aType, const QString &a
* text (QString::null is assumed).
*/
+int VBoxProblemReporter::messageWithOption(QWidget *pParent,
+ Type type,
+ const QString &strMessage,
+ const QString &strOptionText,
+ bool fDefaultOptionValue /* = true */,
+ const QString &strDetails /* = QString::null */,
+ int iButton1 /* = 0 */,
+ int iButton2 /* = 0 */,
+ int iButton3 /* = 0 */,
+ const QString &strButtonName1 /* = QString::null */,
+ const QString &strButtonName2 /* = QString::null */,
+ const QString &strButtonName3 /* = QString::null */) const
+{
+ /* If no buttons are set, using single 'OK' button: */
+ if (iButton1 == 0 && iButton2 == 0 && iButton3 == 0)
+ iButton1 = QIMessageBox::Ok | QIMessageBox::Default;
+
+ /* Assign corresponding title and icon: */
+ QString strTitle;
+ QIMessageBox::Icon icon;
+ switch (type)
+ {
+ default:
+ case Info:
+ strTitle = tr("VirtualBox - Information", "msg box title");
+ icon = QIMessageBox::Information;
+ break;
+ case Question:
+ strTitle = tr("VirtualBox - Question", "msg box title");
+ icon = QIMessageBox::Question;
+ break;
+ case Warning:
+ strTitle = tr("VirtualBox - Warning", "msg box title");
+ icon = QIMessageBox::Warning;
+ break;
+ case Error:
+ strTitle = tr("VirtualBox - Error", "msg box title");
+ icon = QIMessageBox::Critical;
+ break;
+ case Critical:
+ strTitle = tr("VirtualBox - Critical Error", "msg box title");
+ icon = QIMessageBox::Critical;
+ break;
+ case GuruMeditation:
+ strTitle = "VirtualBox - Guru Meditation"; /* don't translate this */
+ icon = QIMessageBox::GuruMeditation;
+ break;
+ }
+
+ /* Create message-box: */
+ if (QPointer<QIMessageBox> pBox = new QIMessageBox(strTitle, strMessage, icon,
+ iButton1, iButton2, iButton3, pParent))
+ {
+ /* Append the list of all warnings with current: */
+ m_warnings << pBox;
+
+ /* Setup message-box connections: */
+ connect(this, SIGNAL(sigToCloseAllWarnings()), pBox, SLOT(deleteLater()));
+
+ /* Assign other text values: */
+ if (!strOptionText.isNull())
+ {
+ pBox->setFlagText(strOptionText);
+ pBox->setFlagChecked(fDefaultOptionValue);
+ }
+ if (!strButtonName1.isNull())
+ pBox->setButtonText(0, strButtonName1);
+ if (!strButtonName2.isNull())
+ pBox->setButtonText(1, strButtonName2);
+ if (!strButtonName3.isNull())
+ pBox->setButtonText(2, strButtonName3);
+ if (!strDetails.isEmpty())
+ pBox->setDetailsText(strDetails);
+
+ /* Show the message box: */
+ int iResultCode = pBox->exec();
+
+ /* Its possible what message-box will be deleted during some event-processing procedure,
+ * in that case pBox will be null right after pBox->exec() returns from it's event-pool,
+ * so we have to check this too: */
+ if (pBox)
+ {
+ /* Cleanup the list of all warnings from current: */
+ if (m_warnings.contains(pBox))
+ m_warnings.removeAll(pBox);
+
+ /* Check if option was chosen: */
+ if (pBox->isFlagChecked())
+ iResultCode |= QIMessageBox::OptionChosen;
+
+ /* Destroy message-box: */
+ if (pBox)
+ delete pBox;
+
+ /* Return final result: */
+ return iResultCode;
+ }
+ }
+ return 0;
+}
+
/**
* Shows a modal progress dialog using a CProgress object passed as an
* argument to track the progress.
@@ -390,14 +491,6 @@ void VBoxProblemReporter::checkForMountedWrongUSB() const
#endif
}
-void VBoxProblemReporter::showWin64Warning()
-{
- message
- (0, Warning,
- tr ("Deletion of all files belonging to the VM is currently disabled on "
- "Windows/x64 to prevent a crash. That will be fixed in the next release."));
-}
-
void VBoxProblemReporter::showBETAWarning()
{
message
@@ -571,6 +664,17 @@ void VBoxProblemReporter::cannotOpenMachine(QWidget *pParent, const QString &str
formatErrorInfo(vbox));
}
+void VBoxProblemReporter::cannotRegisterMachine(const CVirtualBox &vbox,
+ const CMachine &machine,
+ QWidget *pParent)
+{
+ message(pParent ? pParent : mainWindowShown(),
+ Error,
+ tr("Failed to register the virtual machine <b>%1</b>.")
+ .arg(machine.GetName()),
+ formatErrorInfo(vbox));
+}
+
void VBoxProblemReporter::cannotReregisterMachine(QWidget *pParent, const QString &strMachinePath, const QString &strMachineName)
{
message(pParent ? pParent : mainWindowShown(),
@@ -626,6 +730,31 @@ void VBoxProblemReporter::cannotLoadMachineSettings (const CMachine &machine,
formatErrorInfo (res));
}
+bool VBoxProblemReporter::confirmedSettingsReloading(QWidget *pParent)
+{
+ int rc = message(pParent, Question,
+ tr("<p>The machine settings were changed while you were editing them. "
+ "You currently have unsaved setting changes.</p>"
+ "<p>Would you like to reload the changed settings or to keep your own changes?</p>"), 0,
+ QIMessageBox::Yes, QIMessageBox::No | QIMessageBox::Default | QIMessageBox::Escape, 0,
+ tr("Reload settings"), tr("Keep changes"), 0);
+ return rc == QIMessageBox::Yes;
+}
+
+void VBoxProblemReporter::warnAboutStateChange(QWidget *pParent)
+{
+ if (isAlreadyShown("warnAboutStateChange"))
+ return;
+ setShownStatus("warnAboutStateChange");
+
+ message(pParent ? pParent : mainWindowShown(), Warning,
+ tr("The state of the virtual machine you currently edit has changed. "
+ "Only settings which are editable at runtime are saved when you press OK. "
+ "All changes to other settings will be lost."));
+
+ clearShownStatus("warnAboutStateChange");
+}
+
void VBoxProblemReporter::cannotStartMachine (const CConsole &console)
{
/* preserve the current error info before calling the object again */
@@ -712,6 +841,33 @@ void VBoxProblemReporter::cannotSaveMachineState (const CProgress &progress)
);
}
+void VBoxProblemReporter::cannotCreateClone(const CMachine &machine,
+ QWidget *pParent /* = 0 */)
+{
+ message(
+ pParent ? pParent : mainWindowShown(),
+ Error,
+ tr ("Failed to clone the virtual machine <b>%1</b>.")
+ .arg(machine.GetName()),
+ formatErrorInfo(machine)
+ );
+}
+
+void VBoxProblemReporter::cannotCreateClone(const CMachine &machine,
+ const CProgress &progress,
+ QWidget *pParent /* = 0 */)
+{
+ AssertWrapperOk(progress);
+
+ message(
+ pParent ? pParent : mainWindowShown(),
+ Error,
+ tr ("Failed to clone the virtual machine <b>%1</b>.")
+ .arg(machine.GetName()),
+ formatErrorInfo(progress.GetErrorInfo())
+ );
+}
+
void VBoxProblemReporter::cannotTakeSnapshot (const CConsole &console)
{
/* preserve the current error info before calling the object again */
@@ -839,15 +995,24 @@ bool VBoxProblemReporter::warnAboutVirtNotEnabledGuestRequired(bool fHWVirtExSup
tr ("Close VM"), tr ("Continue"));
}
-bool VBoxProblemReporter::askAboutSnapshotRestoring (const QString &aSnapshotName)
+int VBoxProblemReporter::askAboutSnapshotRestoring(const QString &strSnapshotName, bool fAlsoCreateNewSnapshot)
{
- return messageOkCancel (mainWindowShown(), Question,
- tr ("<p>Are you sure you want to restore snapshot <b>%1</b>? "
- "This will cause you to lose your current machine state, which cannot be recovered.</p>")
- .arg (aSnapshotName),
- /* Do NOT allow this message to be disabled! */
- NULL /* aAutoConfirmId */,
- tr ("Restore"), tr ("Cancel"));
+ return fAlsoCreateNewSnapshot ?
+ messageWithOption(mainWindowShown(), Question,
+ tr("<p>You are about to restore snapshot <b>%1</b>.</p>"
+ "<p>You can create a snapshot of the current state of the virtual machine first by checking the box below; "
+ "if you do not do this the current state will be permanently lost. Do you wish to proceed?</p>")
+ .arg(strSnapshotName),
+ tr("Create a snapshot of the current machine state"),
+ true /* choose option by default */,
+ QString::null /* details */,
+ QIMessageBox::Ok, QIMessageBox::Cancel, 0 /* 3rd button */,
+ tr("Restore"), tr("Cancel"), QString::null /* 3rd button text */) :
+ message(mainWindowShown(), Question,
+ tr("<p>Are you sure you want to restore snapshot <b>%1</b>?</p>").arg(strSnapshotName),
+ 0 /* auto-confirmation token */,
+ QIMessageBox::Ok, QIMessageBox::Cancel, 0 /* 3rd button */,
+ tr("Restore"), tr("Cancel"), QString::null /* 3rd button text */);
}
bool VBoxProblemReporter::askAboutSnapshotDeleting (const QString &aSnapshotName)
@@ -1086,6 +1251,14 @@ bool VBoxProblemReporter::confirmDiscardSavedState (const CMachine &machine)
tr ("Discard", "saved state"));
}
+void VBoxProblemReporter::cannotChangeMediumType(QWidget *pParent, const CMedium &medium, KMediumType oldMediumType, KMediumType newMediumType)
+{
+ message(pParent ? pParent : mainWindowShown(), Error,
+ tr("<p>Error changing medium type from <b>%1</b> to <b>%2</b>.</p>")
+ .arg(vboxGlobal().toString(oldMediumType)).arg(vboxGlobal().toString(newMediumType)),
+ formatErrorInfo(medium));
+}
+
bool VBoxProblemReporter::confirmReleaseMedium (QWidget *aParent,
const VBoxMedium &aMedium,
const QString &aUsage)
@@ -2548,6 +2721,21 @@ void VBoxProblemReporter::remindAboutWrongColorDepth(ulong uRealBPP, ulong uWant
emit sigRemindAboutWrongColorDepth(uRealBPP, uWantedBPP);
}
+void VBoxProblemReporter::showGenericError(COMBaseWithEI *object, QWidget *pParent /* = 0 */)
+{
+ if ( !object
+ || object->lastRC() == S_OK)
+ return;
+
+ message(pParent ? pParent : mainWindowShown(),
+ Error,
+ tr("Sorry, some generic error happens."),
+ formatErrorInfo(*object));
+}
+
+// Public slots
+/////////////////////////////////////////////////////////////////////////////
+
void VBoxProblemReporter::remindAboutUnsupportedUSB2(const QString &strExtPackName, QWidget *pParent)
{
emit sigRemindAboutUnsupportedUSB2(strExtPackName, pParent);
@@ -2793,7 +2981,7 @@ void VBoxProblemReporter::sltRemindAboutUnsupportedUSB2(const QString &strExtPac
message(pParent ? pParent : mainMachineWindowShown(), Warning,
tr("<p>USB 2.0 is currently enabled for this virtual machine. "
- "However this requires the <b><nobr>%1</nobr></b> to be installed.</p>"
+ "However, this requires the <b><nobr>%1</nobr></b> to be installed.</p>"
"<p>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.</p>")
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.h b/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.h
index 8876017b3..12c2e1c39 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.h
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.h
@@ -137,6 +137,19 @@ public:
aAutoConfirmId, aOkText, aCancelText);
}
+ int messageWithOption(QWidget *pParent,
+ Type type,
+ const QString &strMessage,
+ const QString &strOptionText,
+ bool fDefaultOptionValue = true,
+ const QString &strDetails = QString::null,
+ int iButton1 = 0,
+ int iButton2 = 0,
+ int iButton3 = 0,
+ const QString &strButtonName1 = QString::null,
+ const QString &strButtonName2 = QString::null,
+ const QString &strButtonName3 = QString::null) const;
+
bool showModalProgressDialog(CProgress &progress, const QString &strTitle,
const QString &strImage = "", QWidget *pParent = 0,
bool fSheetOnDarwin = false, int cMinDuration = 2000);
@@ -151,7 +164,6 @@ public:
void checkForMountedWrongUSB() const;
- void showWin64Warning();
void showBETAWarning();
void showBEBWarning();
@@ -180,8 +192,8 @@ public:
QWidget *parent = 0);
void cannotOpenMachine(QWidget *pParent, const QString &strMachinePath, const CVirtualBox &vbox);
+ void cannotRegisterMachine(const CVirtualBox &vbox, const CMachine &machine, QWidget *pParent);
void cannotReregisterMachine(QWidget *pParent, const QString &strMachinePath, const QString &strMachineName);
-
void cannotApplyMachineSettings (const CMachine &machine, const COMResult &res);
void cannotSaveMachineSettings (const CMachine &machine,
QWidget *parent = 0);
@@ -189,6 +201,9 @@ public:
bool strict = true,
QWidget *parent = 0);
+ bool confirmedSettingsReloading(QWidget *pParent);
+ void warnAboutStateChange(QWidget *pParent);
+
void cannotStartMachine (const CConsole &console);
void cannotStartMachine (const CProgress &progress);
void cannotPauseMachine (const CConsole &console);
@@ -196,6 +211,8 @@ public:
void cannotACPIShutdownMachine (const CConsole &console);
void cannotSaveMachineState (const CConsole &console);
void cannotSaveMachineState (const CProgress &progress);
+ void cannotCreateClone(const CMachine &machine, QWidget *pParent = 0);
+ void cannotCreateClone(const CMachine &machine, const CProgress &progress, QWidget *pParent = 0);
void cannotTakeSnapshot (const CConsole &console);
void cannotTakeSnapshot (const CProgress &progress);
void cannotStopMachine (const CConsole &console);
@@ -209,7 +226,7 @@ public:
bool warnAboutVirtNotEnabled64BitsGuest(bool fHWVirtExSupported);
bool warnAboutVirtNotEnabledGuestRequired(bool fHWVirtExSupported);
- bool askAboutSnapshotRestoring (const QString &aSnapshotName);
+ int askAboutSnapshotRestoring (const QString &aSnapshotName, bool fAlsoCreateNewSnapshot);
bool askAboutSnapshotDeleting (const QString &aSnapshotName);
bool askAboutSnapshotDeletingFreeSpace (const QString &aSnapshotName,
const QString &aTargetImageName,
@@ -234,6 +251,8 @@ public:
int confirmMachineDeletion(const CMachine &machine);
bool confirmDiscardSavedState (const CMachine &machine);
+ void cannotChangeMediumType(QWidget *pParent, const CMedium &medium, KMediumType oldMediumType, KMediumType newMediumType);
+
bool confirmReleaseMedium (QWidget *aParent, const VBoxMedium &aMedium,
const QString &aUsage);
@@ -383,6 +402,8 @@ public:
return formatErrorInfo (aRC.errorInfo(), aRC.rc());
}
+ void showGenericError(COMBaseWithEI *object, QWidget *pParent = 0);
+
/* Stuff supporting interthreading: */
void cannotCreateHostInterface(const CHost &host, QWidget *pParent = 0);
void cannotCreateHostInterface(const CProgress &progress, QWidget *pParent = 0);
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxUtils.h b/src/VBox/Frontends/VirtualBox/src/globals/VBoxUtils.h
index 857cae878..f4b99586f 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxUtils.h
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxUtils.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2006-2008 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;
@@ -122,6 +122,78 @@ public:
}
};
+class UIProxyManager
+{
+public:
+
+ UIProxyManager(const QString &strProxySettings = QString())
+ : m_fProxyEnabled(false), m_fAuthEnabled(false)
+ {
+ /* Parse settings: */
+ if (!strProxySettings.isEmpty())
+ {
+ QStringList proxySettings = strProxySettings.split(",");
+ if (proxySettings.size() > 0)
+ m_fProxyEnabled = proxySettings[0] == "proxyEnabled";
+ if (proxySettings.size() > 1)
+ m_strProxyHost = proxySettings[1];
+ if (proxySettings.size() > 2)
+ m_strProxyPort = proxySettings[2];
+ if (proxySettings.size() > 3)
+ m_fAuthEnabled = proxySettings[3] == "authEnabled";
+ if (proxySettings.size() > 4)
+ m_strAuthLogin = proxySettings[4];
+ if (proxySettings.size() > 5)
+ m_strAuthPassword = proxySettings[5];
+ }
+ }
+
+ QString toString() const
+ {
+ /* Serialize settings: */
+ QString strResult;
+ if (m_fProxyEnabled || !m_strProxyHost.isEmpty() || !m_strProxyPort.isEmpty() ||
+ m_fAuthEnabled || !m_strAuthLogin.isEmpty() || !m_strAuthPassword.isEmpty())
+ {
+ QStringList proxySettings;
+ proxySettings << QString(m_fProxyEnabled ? "proxyEnabled" : "proxyDisabled");
+ proxySettings << m_strProxyHost;
+ proxySettings << m_strProxyPort;
+ proxySettings << QString(m_fAuthEnabled ? "authEnabled" : "authDisabled");
+ proxySettings << m_strAuthLogin;
+ proxySettings << m_strAuthPassword;
+ strResult = proxySettings.join(",");
+ }
+ return strResult;
+ }
+
+ /* Proxy attribute getters: */
+ bool proxyEnabled() const { return m_fProxyEnabled; }
+ const QString& proxyHost() const { return m_strProxyHost; }
+ const QString& proxyPort() const { return m_strProxyPort; }
+ bool authEnabled() const { return m_fAuthEnabled; }
+ const QString& authLogin() const { return m_strAuthLogin; }
+ const QString& authPassword() const { return m_strAuthPassword; }
+
+ /* Proxy attribute setters: */
+ void setProxyEnabled(bool fProxyEnabled) { m_fProxyEnabled = fProxyEnabled; }
+ void setProxyHost(const QString &strProxyHost) { m_strProxyHost = strProxyHost; }
+ void setProxyPort(const QString &strProxyPort) { m_strProxyPort = strProxyPort; }
+ void setAuthEnabled(bool fAuthEnabled) { m_fAuthEnabled = fAuthEnabled; }
+ void setAuthLogin(const QString &strAuthLogin) { m_strAuthLogin = strAuthLogin; }
+ void setAuthPassword(const QString &strAuthPassword) { m_strAuthPassword = strAuthPassword; }
+
+private:
+
+ /* Proxy attribute variables: */
+ bool m_fProxyEnabled;
+ QString m_strProxyHost;
+ QString m_strProxyPort;
+ bool m_fAuthEnabled;
+ QString m_strAuthLogin;
+ QString m_strAuthPassword;
+};
+
#ifdef Q_WS_MAC
# include "VBoxUtils-darwin.h"
#endif /* Q_WS_MAC */
diff --git a/src/VBox/Frontends/VirtualBox/src/hardenedmain.cpp b/src/VBox/Frontends/VirtualBox/src/hardenedmain.cpp
index a36825f96..b7468f1d8 100644
--- a/src/VBox/Frontends/VirtualBox/src/hardenedmain.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/hardenedmain.cpp
@@ -1,4 +1,4 @@
-/* $Id: hardenedmain.cpp $ */
+/* $Id: hardenedmain.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VirtualBox - Hardened main().
*/
diff --git a/src/VBox/Frontends/VirtualBox/src/main.cpp b/src/VBox/Frontends/VirtualBox/src/main.cpp
index fb0978bd9..cac9381ad 100644
--- a/src/VBox/Frontends/VirtualBox/src/main.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/main.cpp
@@ -1,4 +1,4 @@
-/* $Id: main.cpp $ */
+/* $Id: main.cpp 35652 2011-01-20 14:16:38Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -260,7 +260,7 @@ static void showHelp()
" --rmode %-18s select different render mode (default is %s)\n"
" --no-startvm-errormsgbox do not show a message box for VM start errors\n"
# ifdef VBOX_GUI_WITH_PIDFILE
- " --pidfile file create a pidfile file when a VM is up and running\n"
+ " --pidfile <file> create a pidfile file when a VM is up and running\n"
# endif
# ifdef VBOX_WITH_DEBUGGER_GUI
" --dbg enable the GUI debug menu\n"
@@ -290,19 +290,6 @@ extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char ** /*envp*/)
ShutUpAppKit();
# endif
-#ifdef Q_WS_WIN
- /* Initialize COM early, before QApplication calls OleInitialize(), to
- * make sure we enter the multi threaded apartment instead of a single
- * threaded one. Note that this will make some non-threadsafe system
- * services that use OLE and require STA (such as Drag&Drop) not work
- * anymore, however it's still better because otherwise VBox will not work
- * on some Windows XP systems at all since it requires MTA (we cannot
- * leave STA by calling CoUninitialize() and re-enter MTA on those systems
- * for some unknown reason), see also src/VBox/Main/glue/initterm.cpp. */
- /// @todo find a proper solution that satisfies both OLE and VBox
- HRESULT hrc = COMBase::InitializeCOM();
-#endif
-
for (int i=0; i<argc; i++)
if ( !strcmp(argv[i], "-h")
|| !strcmp(argv[i], "-?")
@@ -463,15 +450,6 @@ extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char ** /*envp*/)
do
{
-#ifdef Q_WS_WIN
- /* Check for the COM error after we've initialized Qt */
- if (FAILED (hrc))
- {
- vboxProblem().cannotInitCOM (hrc);
- break;
- }
-#endif
-
if (!vboxGlobal().isValid())
break;
@@ -554,12 +532,6 @@ extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char ** /*envp*/)
while (0);
}
-#ifdef Q_WS_WIN
- /* See COMBase::initializeCOM() above */
- if (SUCCEEDED (hrc))
- COMBase::CleanupCOM();
-#endif
-
LogFlowFunc (("rc=%d\n", rc));
LogFlowFuncLeave();
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/CocoaEventHelper.mm b/src/VBox/Frontends/VirtualBox/src/platform/darwin/CocoaEventHelper.mm
index 9b86ac3e6..b79ba32c1 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/CocoaEventHelper.mm
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/CocoaEventHelper.mm
@@ -1,4 +1,4 @@
-/* $Id: CocoaEventHelper.mm $ */
+/* $Id: CocoaEventHelper.mm 30122 2010-06-09 13:50:26Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp b/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp
index b802d1c85..0cf8d2814 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp
@@ -1,4 +1,4 @@
-/* $Id: DarwinKeyboard.cpp $ */
+/* $Id: DarwinKeyboard.cpp 35873 2011-02-07 14:10:08Z vboxsync $ */
/** @file
* Common GUI Library - Darwin Keyboard routines.
*
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/DockIconPreview.h b/src/VBox/Frontends/VirtualBox/src/platform/darwin/DockIconPreview.h
index c4ffaef4f..8a4f86abc 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/DockIconPreview.h
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/DockIconPreview.h
@@ -1,4 +1,4 @@
-/* $Id: DockIconPreview.h $ */
+/* $Id: DockIconPreview.h 29812 2010-05-26 11:46:22Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/Info.plist b/src/VBox/Frontends/VirtualBox/src/platform/darwin/Info.plist
index c0ba0d24a..8e5872601 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/Info.plist
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/Info.plist
@@ -35,6 +35,30 @@
<key>CFBundleTypeRole</key> <string>Viewer</string>
<key>CFBundleTypeIconFile</key> <string>virtualbox-ova</string>
</dict>
+ <dict>
+ <key>CFBundleTypeName</key> <string>Virtual Disk Image</string>
+ <key>CFBundleTypeExtensions</key> <array><string>vdi</string></array>
+ <key>CFBundleTypeRole</key> <string>None</string>
+ <key>CFBundleTypeIconFile</key> <string>virtualbox-vdi</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeName</key> <string>Virtual Machine Disk Format</string>
+ <key>CFBundleTypeExtensions</key> <array><string>vmdk</string></array>
+ <key>CFBundleTypeRole</key> <string>None</string>
+ <key>CFBundleTypeIconFile</key> <string>virtualbox-vmdk</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeName</key> <string>Virtual Hard Disk</string>
+ <key>CFBundleTypeExtensions</key> <array><string>vhd</string></array>
+ <key>CFBundleTypeRole</key> <string>None</string>
+ <key>CFBundleTypeIconFile</key> <string>virtualbox-vhd</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeName</key> <string>Virtual Hard Disk</string>
+ <key>CFBundleTypeExtensions</key> <array><string>hdd</string></array>
+ <key>CFBundleTypeRole</key> <string>None</string>
+ <key>CFBundleTypeIconFile</key> <string>virtualbox-hdd</string>
+ </dict>
</array>
</dict>
</plist>
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIAbstractDockIconPreview.cpp b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIAbstractDockIconPreview.cpp
index f2391f87f..fe6c17fc7 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIAbstractDockIconPreview.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIAbstractDockIconPreview.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIAbstractDockIconPreview.cpp $ */
+/* $Id: UIAbstractDockIconPreview.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Qt GUI - Realtime Dock Icon Preview
*/
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIAbstractDockIconPreview.h b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIAbstractDockIconPreview.h
index 8c4c46fd2..ec6c4b262 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIAbstractDockIconPreview.h
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIAbstractDockIconPreview.h
@@ -1,4 +1,4 @@
-/* $Id: UIAbstractDockIconPreview.h $ */
+/* $Id: UIAbstractDockIconPreview.h 29823 2010-05-26 14:49:27Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.mm b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.mm
index c45147102..96d9dbd9d 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.mm
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.mm
@@ -1,4 +1,4 @@
-/* $Id: UICocoaApplication.mm $ */
+/* $Id: UICocoaApplication.mm 30154 2010-06-10 16:28:15Z vboxsync $ */
/** @file
* UICocoaApplication - C++ interface to NSApplication for handling -sendEvent.
*/
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaDockIconPreview.h b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaDockIconPreview.h
index 7bfe2d76a..c20088f9f 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaDockIconPreview.h
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaDockIconPreview.h
@@ -1,4 +1,4 @@
-/* $Id: UICocoaDockIconPreview.h $ */
+/* $Id: UICocoaDockIconPreview.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaDockIconPreview.mm b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaDockIconPreview.mm
index 152e5d1df..95fdd9ecf 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaDockIconPreview.mm
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaDockIconPreview.mm
@@ -1,4 +1,4 @@
-/* $Id: UICocoaDockIconPreview.mm $ */
+/* $Id: UICocoaDockIconPreview.mm 30151 2010-06-10 16:12:33Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaSpecialControls.mm b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaSpecialControls.mm
index 165a46967..ebedcd24e 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaSpecialControls.mm
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaSpecialControls.mm
@@ -1,4 +1,4 @@
-/* $Id: UICocoaSpecialControls.mm $ */
+/* $Id: UICocoaSpecialControls.mm 37115 2011-05-16 22:44:58Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -44,7 +44,9 @@
{
UICocoaButton *mRealTarget;
}
--(id)initWithObject:(UICocoaButton*)object;
+/* The next method used to be called initWithObject, but Xcode 4.1 preview 5
+ cannot cope with that for some reason. Hope this doesn't break anything... */
+-(id)initWithObjectAndLionTrouble:(UICocoaButton*)object;
-(IBAction)clicked:(id)sender;
@end
@@ -82,7 +84,7 @@
* Implementation of the private interfaces
*/
@implementation UIButtonTargetPrivate
--(id)initWithObject:(UICocoaButton*)object
+-(id)initWithObjectAndLionTrouble:(UICocoaButton*)object
{
self = [super init];
@@ -292,7 +294,7 @@ UICocoaButton::UICocoaButton(CocoaButtonType aType, QWidget *pParent /* = 0 */)
}
}
- UIButtonTargetPrivate *bt = [[UIButtonTargetPrivate alloc] initWithObject:this];
+ UIButtonTargetPrivate *bt = [[UIButtonTargetPrivate alloc] initWithObjectAndLionTrouble:this];
[m_pNativeRef setTarget:bt];
[m_pNativeRef setAction:@selector(clicked:)];
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIDesktopServices_darwin.cpp b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIDesktopServices_darwin.cpp
index 75041bd20..4ab55aaa2 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIDesktopServices_darwin.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIDesktopServices_darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIDesktopServices_darwin.cpp $ */
+/* $Id: UIDesktopServices_darwin.cpp 34411 2010-11-26 16:57:30Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIDesktopServices_darwin_cocoa.mm b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIDesktopServices_darwin_cocoa.mm
index 213aafd3b..bc0502c42 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIDesktopServices_darwin_cocoa.mm
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIDesktopServices_darwin_cocoa.mm
@@ -1,4 +1,4 @@
-/* $Id: UIDesktopServices_darwin_cocoa.mm $ */
+/* $Id: UIDesktopServices_darwin_cocoa.mm 34411 2010-11-26 16:57:30Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIWindowMenuManager.cpp b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIWindowMenuManager.cpp
index 1bd88925c..6acc1f3ad 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIWindowMenuManager.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIWindowMenuManager.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIWindowMenuManager.cpp $ */
+/* $Id: UIWindowMenuManager.cpp 34401 2010-11-26 16:37:51Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxIChatTheaterWrapper.h b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxIChatTheaterWrapper.h
index 235bc0a29..d1e86f996 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxIChatTheaterWrapper.h
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxIChatTheaterWrapper.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxIChatTheaterWrapper.h $ */
+/* $Id: VBoxIChatTheaterWrapper.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Qt GUI - iChat Theater cocoa wrapper.
*/
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxIChatTheaterWrapper.m b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxIChatTheaterWrapper.m
index 1fd2792e8..d5f5de91a 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxIChatTheaterWrapper.m
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxIChatTheaterWrapper.m
@@ -1,4 +1,4 @@
-/* $Id: VBoxIChatTheaterWrapper.m $ */
+/* $Id: VBoxIChatTheaterWrapper.m 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Qt GUI - iChat Theater cocoa wrapper.
*/
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin-cocoa.mm b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin-cocoa.mm
index cf4195177..5fbd7d54a 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin-cocoa.mm
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin-cocoa.mm
@@ -1,4 +1,4 @@
-/* $Id: VBoxUtils-darwin-cocoa.mm $ */
+/* $Id: VBoxUtils-darwin-cocoa.mm 35870 2011-02-07 13:18:02Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.cpp b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.cpp
index 4bec56f38..030a73e96 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxUtils-darwin.cpp $ */
+/* $Id: VBoxUtils-darwin.cpp 36534 2011-04-04 15:00:49Z vboxsync $ */
/** @file
* Qt GUI - Utility Classes and Functions specific to Darwin.
*/
@@ -20,6 +20,7 @@
#include "UICocoaApplication.h"
#include <iprt/mem.h>
+#include <iprt/assert.h>
#include <QMainWindow>
#include <QApplication>
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/tstDarwinKeyboard.cpp b/src/VBox/Frontends/VirtualBox/src/platform/darwin/tstDarwinKeyboard.cpp
index 929de5335..84a4ae4ab 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/tstDarwinKeyboard.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/tstDarwinKeyboard.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstDarwinKeyboard.cpp $ */
+/* $Id: tstDarwinKeyboard.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Common GUI Library - Testcase - Darwin Keyboard routines.
*
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/vmstarter.mm b/src/VBox/Frontends/VirtualBox/src/platform/darwin/vmstarter.mm
index f755566af..23bb6e0be 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/vmstarter.mm
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/vmstarter.mm
@@ -1,4 +1,4 @@
-/* $Id: vmstarter.mm $ */
+/* $Id: vmstarter.mm 34275 2010-11-23 11:08:52Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/os2/VBoxHlp.asm b/src/VBox/Frontends/VirtualBox/src/platform/os2/VBoxHlp.asm
index f82fac0b6..40739aa46 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/os2/VBoxHlp.asm
+++ b/src/VBox/Frontends/VirtualBox/src/platform/os2/VBoxHlp.asm
@@ -1,4 +1,4 @@
-; $Id: VBoxHlp.asm $
+; $Id: VBoxHlp.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
;
; VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/os2/VBoxHlp.cpp b/src/VBox/Frontends/VirtualBox/src/platform/os2/VBoxHlp.cpp
index 87244dc56..989a7606c 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/os2/VBoxHlp.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/os2/VBoxHlp.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxHlp.cpp $ */
+/* $Id: VBoxHlp.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox frontends: Qt GUI ("VirtualBox"):
* Implementation of OS/2-specific helpers that require to reside in a DLL
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/win/UIDesktopServices_win.cpp b/src/VBox/Frontends/VirtualBox/src/platform/win/UIDesktopServices_win.cpp
index 7f14234ef..a5f67ef7f 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/win/UIDesktopServices_win.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/win/UIDesktopServices_win.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIDesktopServices_win.cpp $ */
+/* $Id: UIDesktopServices_win.cpp 34415 2010-11-26 17:09:29Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/win/VBoxUtils-win.cpp b/src/VBox/Frontends/VirtualBox/src/platform/win/VBoxUtils-win.cpp
new file mode 100644
index 000000000..fc980a52c
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/platform/win/VBoxUtils-win.cpp
@@ -0,0 +1,79 @@
+/* $Id: VBoxUtils-win.cpp 35940 2011-02-11 11:58:32Z vboxsync $ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * Utility classes and functions for handling Win specific tasks
+ */
+
+/*
+ * 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.
+ */
+
+/* Includes: */
+#include "VBoxUtils-win.h"
+
+/* Namespace for native window sub-system functions: */
+namespace NativeWindowSubsystem
+{
+ /* Enumerates visible always-on-top (top-most) windows: */
+ BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam);
+ /* Contain visible top-most-window rectangles: */
+ QList<QRect> topMostRects;
+}
+
+/* Enumerates visible always-on-top (top-most) windows: */
+BOOL CALLBACK NativeWindowSubsystem::EnumWindowsProc(HWND hWnd, LPARAM /* lParam */)
+{
+ /* Ignore NULL HWNDs: */
+ if (!hWnd)
+ return TRUE;
+
+ /* Ignore hidden windows: */
+ if (!IsWindowVisible(hWnd))
+ return TRUE;
+
+ /* Get window style: */
+ LONG uStyle = GetWindowLong(hWnd, GWL_STYLE);
+ /* Ignore minimized windows: */
+ if (uStyle & WS_MINIMIZE)
+ return TRUE;
+
+ /* Get extended window style: */
+ LONG uExtendedStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
+ /* Ignore non-top-most windows: */
+ if (!(uExtendedStyle & WS_EX_TOPMOST))
+ return TRUE;
+
+ /* Get that window rectangle: */
+ RECT rect;
+ GetWindowRect(hWnd, &rect);
+ topMostRects << QRect(QPoint(rect.left, rect.top), QPoint(rect.right - 1, rect.bottom - 1));
+
+ /* Proceed to the next window: */
+ return TRUE;
+}
+
+/* Returns area covered by visible always-on-top (top-most) windows: */
+const QRegion NativeWindowSubsystem::areaCoveredByTopMostWindows()
+{
+ /* Prepare the top-most region: */
+ QRegion topMostRegion;
+ /* Initialize the list of the top-most rectangles: */
+ topMostRects.clear();
+ /* Populate the list of top-most rectangles: */
+ EnumWindows((WNDENUMPROC)EnumWindowsProc, 0);
+ /* Update the top-most region with top-most rectangles: */
+ for (int iRectIndex = 0; iRectIndex < topMostRects.size(); ++iRectIndex)
+ topMostRegion += topMostRects[iRectIndex];
+ /* Return top-most region: */
+ return topMostRegion;
+}
+
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/win/VBoxUtils-win.h b/src/VBox/Frontends/VirtualBox/src/platform/win/VBoxUtils-win.h
new file mode 100644
index 000000000..d82660fdc
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/platform/win/VBoxUtils-win.h
@@ -0,0 +1,36 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * Declarations of utility classes and functions for handling Win specific tasks
+ */
+
+/*
+ * 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 __VBoxUtils_WIN_h__
+#define __VBoxUtils_WIN_h__
+
+/* Qt includes: */
+#include <QRegion>
+
+/* Platform includes: */
+#include "Windows.h"
+
+/* Namespace for native window sub-system functions: */
+namespace NativeWindowSubsystem
+{
+ /* Returns area covered by visible always-on-top (top-most) windows: */
+ const QRegion areaCoveredByTopMostWindows();
+}
+
+#endif /* __VBoxUtils_WIN_h__ */
+
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc b/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc
index 64ac53857..87ea3ba74 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc
+++ b/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc
@@ -1,4 +1,4 @@
-/* $Id: VirtualBox.rc $ */
+/* $Id: VirtualBox.rc 34384 2010-11-25 16:23:57Z vboxsync $ */
/** @file
* Windows resource file for VirtualBox.exe.
*/
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/x11/UIDesktopServices_x11.cpp b/src/VBox/Frontends/VirtualBox/src/platform/x11/UIDesktopServices_x11.cpp
index 6aa8200d3..e4fd8dcab 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/x11/UIDesktopServices_x11.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/x11/UIDesktopServices_x11.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIDesktopServices_x11.cpp $ */
+/* $Id: UIDesktopServices_x11.cpp 34886 2010-12-09 14:06:02Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/x11/VBoxX11Helper.cpp b/src/VBox/Frontends/VirtualBox/src/platform/x11/VBoxX11Helper.cpp
index 45b2e5c85..9d70cb657 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/x11/VBoxX11Helper.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/x11/VBoxX11Helper.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxX11Helper.cpp $ */
+/* $Id: VBoxX11Helper.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/x11/XKeyboard-new.cpp b/src/VBox/Frontends/VirtualBox/src/platform/x11/XKeyboard-new.cpp
index cb9728efb..980ada621 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/x11/XKeyboard-new.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/x11/XKeyboard-new.cpp
@@ -1,4 +1,4 @@
-/* $Id: XKeyboard-new.cpp $ */
+/* $Id: XKeyboard-new.cpp 36335 2011-03-21 21:58:58Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/precomp.h b/src/VBox/Frontends/VirtualBox/src/precomp.h
index d6a0c6326..b0f962d6d 100644
--- a/src/VBox/Frontends/VirtualBox/src/precomp.h
+++ b/src/VBox/Frontends/VirtualBox/src/precomp.h
@@ -1,4 +1,4 @@
-/* $Id: precomp.h $*/
+/* $Id: precomp.h 35347 2010-12-27 16:25:58Z vboxsync $*/
/** @file
* Header used if VBOX_WITH_PRECOMPILED_HEADERS is active.
*/
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.cpp
index 503f2d6cb..8cb1b390f 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIActionsPool.cpp $ */
+/* $Id: UIActionsPool.cpp 36357 2011-03-23 09:36:05Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -222,16 +222,15 @@ protected:
}
};
-class ToggleFullscreenModeAction : public UIToggleAction
+class ShowSettingsDialogAction : public UISimpleAction
{
Q_OBJECT;
public:
- ToggleFullscreenModeAction(QObject *pParent)
- : UIToggleAction(pParent,
- ":/fullscreen_on_16px.png", ":/fullscreen_16px.png",
- ":/fullscreen_on_disabled_16px.png", ":/fullscreen_disabled_16px.png")
+ ShowSettingsDialogAction(QObject *pParent)
+ : UISimpleAction(pParent,
+ ":/settings_16px.png", ":/settings_dis_16px.png")
{
retranslateUi();
}
@@ -240,21 +239,20 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Switch to &Fullscreen"), gMS->shortcut(UIMachineShortcuts::FullscreenModeShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Switch between normal and fullscreen mode"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Settings..."), gMS->shortcut(UIMachineShortcuts::SettingsDialogShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Manage the virtual machine settings"));
}
};
-class ToggleSeamlessModeAction : public UIToggleAction
+class PerformTakeSnapshotAction : public UISimpleAction
{
Q_OBJECT;
public:
- ToggleSeamlessModeAction(QObject *pParent)
- : UIToggleAction(pParent,
- ":/seamless_on_16px.png", ":/seamless_16px.png",
- ":/seamless_on_disabled_16px.png", ":/seamless_disabled_16px.png")
+ PerformTakeSnapshotAction(QObject *pParent)
+ : UISimpleAction(pParent,
+ ":/take_snapshot_16px.png", ":/take_snapshot_dis_16px.png")
{
retranslateUi();
}
@@ -263,21 +261,20 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Switch to Seam&less Mode"), gMS->shortcut(UIMachineShortcuts::SeamlessModeShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Switch between normal and seamless desktop integration mode"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Take &Snapshot..."), gMS->shortcut(UIMachineShortcuts::TakeSnapshotShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Take a snapshot of the virtual machine"));
}
};
-class ToggleScaleModeAction : public UIToggleAction
+class ShowInformationDialogAction : public UISimpleAction
{
Q_OBJECT;
public:
- ToggleScaleModeAction(QObject *pParent)
- : UIToggleAction(pParent,
- ":/scale_on_16px.png", ":/scale_16px.png",
- ":/scale_on_disabled_16px.png", ":/scale_disabled_16px.png")
+ ShowInformationDialogAction(QObject *pParent)
+ : UISimpleAction(pParent,
+ ":/session_info_16px.png", ":/session_info_disabled_16px.png")
{
retranslateUi();
}
@@ -286,21 +283,40 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Switch to &Scale Mode"), gMS->shortcut(UIMachineShortcuts::ScaleModeShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Switch between normal and scale mode"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Session I&nformation..."), gMS->shortcut(UIMachineShortcuts::InformationDialogShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Show Session Information Dialog"));
}
};
-class ToggleGuestAutoresizeAction : public UIToggleAction
+class MenuMouseIntegrationAction : public UIMenuAction
{
Q_OBJECT;
public:
- ToggleGuestAutoresizeAction(QObject *pParent)
+ MenuMouseIntegrationAction(QObject *pParent)
+ : UIMenuAction(pParent)
+ {
+ retranslateUi();
+ }
+
+protected:
+
+ void retranslateUi()
+ {
+ }
+};
+
+class ToggleMouseIntegrationAction : public UIToggleAction
+{
+ Q_OBJECT;
+
+public:
+
+ ToggleMouseIntegrationAction(QObject *pParent)
: UIToggleAction(pParent,
- ":/auto_resize_on_on_16px.png", ":/auto_resize_on_16px.png",
- ":/auto_resize_on_on_disabled_16px.png", ":/auto_resize_on_disabled_16px.png")
+ ":/mouse_can_seamless_on_16px.png", ":/mouse_can_seamless_16px.png",
+ ":/mouse_can_seamless_on_disabled_16px.png", ":/mouse_can_seamless_disabled_16px.png")
{
retranslateUi();
}
@@ -309,20 +325,20 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Auto-resize &Guest Display"), gMS->shortcut(UIMachineShortcuts::GuestAutoresizeShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Automatically resize the guest display when the window is resized (requires Guest Additions)"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Disable &Mouse Integration"), gMS->shortcut(UIMachineShortcuts::MouseIntegrationShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Temporarily disable host mouse pointer integration"));
}
};
-class PerformWindowAdjustAction : public UISimpleAction
+class PerformTypeCADAction : public UISimpleAction
{
Q_OBJECT;
public:
- PerformWindowAdjustAction(QObject *pParent)
+ PerformTypeCADAction(QObject *pParent)
: UISimpleAction(pParent,
- ":/adjust_win_size_16px.png", ":/adjust_win_size_disabled_16px.png")
+ ":/hostkey_16px.png", ":/hostkey_disabled_16px.png")
{
retranslateUi();
}
@@ -331,19 +347,21 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Adjust Window Size"), gMS->shortcut(UIMachineShortcuts::WindowAdjustShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Adjust window size and position to best fit the guest display"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Insert Ctrl-Alt-Del"), gMS->shortcut(UIMachineShortcuts::TypeCADShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Send the Ctrl-Alt-Del sequence to the virtual machine"));
}
};
-class MenuMouseIntegrationAction : public UIMenuAction
+#ifdef Q_WS_X11
+class PerformTypeCABSAction : public UISimpleAction
{
Q_OBJECT;
public:
- MenuMouseIntegrationAction(QObject *pParent)
- : UIMenuAction(pParent)
+ PerformTypeCABSAction(QObject *pParent)
+ : UISimpleAction(pParent,
+ ":/hostkey_16px.png", ":/hostkey_disabled_16px.png")
{
retranslateUi();
}
@@ -352,19 +370,21 @@ protected:
void retranslateUi()
{
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Insert Ctrl-Alt-Backspace"), gMS->shortcut(UIMachineShortcuts::TypeCABSShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Send the Ctrl-Alt-Backspace sequence to the virtual machine"));
}
};
+#endif
-class ToggleMouseIntegrationAction : public UIToggleAction
+class TogglePauseAction : public UIToggleAction
{
Q_OBJECT;
public:
- ToggleMouseIntegrationAction(QObject *pParent)
+ TogglePauseAction(QObject *pParent)
: UIToggleAction(pParent,
- ":/mouse_can_seamless_on_16px.png", ":/mouse_can_seamless_16px.png",
- ":/mouse_can_seamless_on_disabled_16px.png", ":/mouse_can_seamless_disabled_16px.png")
+ ":/pause_16px.png", ":/pause_disabled_16px.png")
{
retranslateUi();
}
@@ -373,20 +393,20 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Disable &Mouse Integration"), gMS->shortcut(UIMachineShortcuts::MouseIntegrationShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Temporarily disable host mouse pointer integration"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Pause"), gMS->shortcut(UIMachineShortcuts::PauseShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Suspend the execution of the virtual machine"));
}
};
-class PerformTypeCADAction : public UISimpleAction
+class PerformResetAction : public UISimpleAction
{
Q_OBJECT;
public:
- PerformTypeCADAction(QObject *pParent)
+ PerformResetAction(QObject *pParent)
: UISimpleAction(pParent,
- ":/hostkey_16px.png", ":/hostkey_disabled_16px.png")
+ ":/reset_16px.png", ":/reset_disabled_16px.png")
{
retranslateUi();
}
@@ -395,21 +415,20 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Insert Ctrl-Alt-Del"), gMS->shortcut(UIMachineShortcuts::TypeCADShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Send the Ctrl-Alt-Del sequence to the virtual machine"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Reset"), gMS->shortcut(UIMachineShortcuts::ResetShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Reset the virtual machine"));
}
};
-#ifdef Q_WS_X11
-class PerformTypeCABSAction : public UISimpleAction
+class PerformShutdownAction : public UISimpleAction
{
Q_OBJECT;
public:
- PerformTypeCABSAction(QObject *pParent)
+ PerformShutdownAction(QObject *pParent)
: UISimpleAction(pParent,
- ":/hostkey_16px.png", ":/hostkey_disabled_16px.png")
+ ":/acpi_16px.png", ":/acpi_disabled_16px.png")
{
retranslateUi();
}
@@ -418,22 +437,22 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Insert Ctrl-Alt-Backspace"), gMS->shortcut(UIMachineShortcuts::TypeCABSShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Send the Ctrl-Alt-Backspace sequence to the virtual machine"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "ACPI Sh&utdown"), gMS->shortcut(UIMachineShortcuts::ShutdownShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Send the ACPI Power Button press event to the virtual machine"));
}
};
-#endif
-class PerformTakeSnapshotAction : public UISimpleAction
+class PerformCloseAction : public UISimpleAction
{
Q_OBJECT;
public:
- PerformTakeSnapshotAction(QObject *pParent)
+ PerformCloseAction(QObject *pParent)
: UISimpleAction(pParent,
- ":/take_snapshot_16px.png", ":/take_snapshot_dis_16px.png")
+ ":/exit_16px.png")
{
+ setMenuRole(QAction::QuitRole);
retranslateUi();
}
@@ -441,20 +460,19 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Take &Snapshot..."), gMS->shortcut(UIMachineShortcuts::TakeSnapshotShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Take a snapshot of the virtual machine"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Close..."), gMS->shortcut(UIMachineShortcuts::CloseShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Close the virtual machine"));
}
};
-class ShowInformationDialogAction : public UISimpleAction
+class MenuViewAction : public UIMenuAction
{
Q_OBJECT;
public:
- ShowInformationDialogAction(QObject *pParent)
- : UISimpleAction(pParent,
- ":/session_info_16px.png", ":/session_info_disabled_16px.png")
+ MenuViewAction(QObject *pParent)
+ : UIMenuAction(pParent)
{
retranslateUi();
}
@@ -463,20 +481,20 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Session I&nformation"), gMS->shortcut(UIMachineShortcuts::InformationDialogShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Show Session Information Dialog"));
+ menu()->setTitle(QApplication::translate("UIActionsPool", "&View"));
}
};
-class TogglePauseAction : public UIToggleAction
+class ToggleFullscreenModeAction : public UIToggleAction
{
Q_OBJECT;
public:
- TogglePauseAction(QObject *pParent)
+ ToggleFullscreenModeAction(QObject *pParent)
: UIToggleAction(pParent,
- ":/pause_16px.png", ":/pause_disabled_16px.png")
+ ":/fullscreen_on_16px.png", ":/fullscreen_16px.png",
+ ":/fullscreen_on_disabled_16px.png", ":/fullscreen_disabled_16px.png")
{
retranslateUi();
}
@@ -485,20 +503,21 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Pause"), gMS->shortcut(UIMachineShortcuts::PauseShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Suspend the execution of the virtual machine"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Switch to &Fullscreen"), gMS->shortcut(UIMachineShortcuts::FullscreenModeShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Switch between normal and fullscreen mode"));
}
};
-class PerformResetAction : public UISimpleAction
+class ToggleSeamlessModeAction : public UIToggleAction
{
Q_OBJECT;
public:
- PerformResetAction(QObject *pParent)
- : UISimpleAction(pParent,
- ":/reset_16px.png", ":/reset_disabled_16px.png")
+ ToggleSeamlessModeAction(QObject *pParent)
+ : UIToggleAction(pParent,
+ ":/seamless_on_16px.png", ":/seamless_16px.png",
+ ":/seamless_on_disabled_16px.png", ":/seamless_disabled_16px.png")
{
retranslateUi();
}
@@ -507,20 +526,21 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Reset"), gMS->shortcut(UIMachineShortcuts::ResetShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Reset the virtual machine"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Switch to Seam&less Mode"), gMS->shortcut(UIMachineShortcuts::SeamlessModeShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Switch between normal and seamless desktop integration mode"));
}
};
-class PerformShutdownAction : public UISimpleAction
+class ToggleScaleModeAction : public UIToggleAction
{
Q_OBJECT;
public:
- PerformShutdownAction(QObject *pParent)
- : UISimpleAction(pParent,
- ":/acpi_16px.png", ":/acpi_disabled_16px.png")
+ ToggleScaleModeAction(QObject *pParent)
+ : UIToggleAction(pParent,
+ ":/scale_on_16px.png", ":/scale_16px.png",
+ ":/scale_on_disabled_16px.png", ":/scale_disabled_16px.png")
{
retranslateUi();
}
@@ -529,22 +549,22 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "ACPI Sh&utdown"), gMS->shortcut(UIMachineShortcuts::ShutdownShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Send the ACPI Power Button press event to the virtual machine"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Switch to &Scale Mode"), gMS->shortcut(UIMachineShortcuts::ScaleModeShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Switch between normal and scale mode"));
}
};
-class PerformCloseAction : public UISimpleAction
+class ToggleGuestAutoresizeAction : public UIToggleAction
{
Q_OBJECT;
public:
- PerformCloseAction(QObject *pParent)
- : UISimpleAction(pParent,
- ":/exit_16px.png")
+ ToggleGuestAutoresizeAction(QObject *pParent)
+ : UIToggleAction(pParent,
+ ":/auto_resize_on_on_16px.png", ":/auto_resize_on_16px.png",
+ ":/auto_resize_on_on_disabled_16px.png", ":/auto_resize_on_disabled_16px.png")
{
- setMenuRole(QAction::QuitRole);
retranslateUi();
}
@@ -552,19 +572,20 @@ protected:
void retranslateUi()
{
- setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Close..."), gMS->shortcut(UIMachineShortcuts::CloseShortcut)));
- setStatusTip(QApplication::translate("UIActionsPool", "Close the virtual machine"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "Auto-resize &Guest Display"), gMS->shortcut(UIMachineShortcuts::GuestAutoresizeShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Automatically resize the guest display when the window is resized (requires Guest Additions)"));
}
};
-class MenuViewAction : public UIMenuAction
+class PerformWindowAdjustAction : public UISimpleAction
{
Q_OBJECT;
public:
- MenuViewAction(QObject *pParent)
- : UIMenuAction(pParent)
+ PerformWindowAdjustAction(QObject *pParent)
+ : UISimpleAction(pParent,
+ ":/adjust_win_size_16px.png", ":/adjust_win_size_disabled_16px.png")
{
retranslateUi();
}
@@ -573,7 +594,8 @@ protected:
void retranslateUi()
{
- menu()->setTitle(QApplication::translate("UIActionsPool", "&View"));
+ setText(vboxGlobal().insertKeyToActionText(QApplication::translate("UIActionsPool", "&Adjust Window Size"), gMS->shortcut(UIMachineShortcuts::WindowAdjustShortcut)));
+ setStatusTip(QApplication::translate("UIActionsPool", "Adjust window size and position to best fit the guest display"));
}
};
@@ -1113,23 +1135,26 @@ UIActionsPool::UIActionsPool(QObject *pParent)
, m_actionsPool(UIActionIndex_End, 0)
{
/* "Machine" menu actions: */
- m_actionsPool[UIActionIndex_Toggle_Fullscreen] = new ToggleFullscreenModeAction(this);
- m_actionsPool[UIActionIndex_Toggle_Seamless] = new ToggleSeamlessModeAction(this);
- m_actionsPool[UIActionIndex_Toggle_Scale] = new ToggleScaleModeAction(this);
- m_actionsPool[UIActionIndex_Toggle_GuestAutoresize] = new ToggleGuestAutoresizeAction(this);
- m_actionsPool[UIActionIndex_Simple_AdjustWindow] = new PerformWindowAdjustAction(this);
+ m_actionsPool[UIActionIndex_Simple_SettingsDialog] = new ShowSettingsDialogAction(this);
+ m_actionsPool[UIActionIndex_Simple_TakeSnapshot] = new PerformTakeSnapshotAction(this);
+ m_actionsPool[UIActionIndex_Simple_InformationDialog] = new ShowInformationDialogAction(this);
m_actionsPool[UIActionIndex_Toggle_MouseIntegration] = new ToggleMouseIntegrationAction(this);
m_actionsPool[UIActionIndex_Simple_TypeCAD] = new PerformTypeCADAction(this);
#ifdef Q_WS_X11
m_actionsPool[UIActionIndex_Simple_TypeCABS] = new PerformTypeCABSAction(this);
#endif
- m_actionsPool[UIActionIndex_Simple_TakeSnapshot] = new PerformTakeSnapshotAction(this);
- m_actionsPool[UIActionIndex_Simple_InformationDialog] = new ShowInformationDialogAction(this);
m_actionsPool[UIActionIndex_Toggle_Pause] = new TogglePauseAction(this);
m_actionsPool[UIActionIndex_Simple_Reset] = new PerformResetAction(this);
m_actionsPool[UIActionIndex_Simple_Shutdown] = new PerformShutdownAction(this);
m_actionsPool[UIActionIndex_Simple_Close] = new PerformCloseAction(this);
+ /* "View" menu actions: */
+ m_actionsPool[UIActionIndex_Toggle_Fullscreen] = new ToggleFullscreenModeAction(this);
+ m_actionsPool[UIActionIndex_Toggle_Seamless] = new ToggleSeamlessModeAction(this);
+ m_actionsPool[UIActionIndex_Toggle_Scale] = new ToggleScaleModeAction(this);
+ m_actionsPool[UIActionIndex_Toggle_GuestAutoresize] = new ToggleGuestAutoresizeAction(this);
+ m_actionsPool[UIActionIndex_Simple_AdjustWindow] = new PerformWindowAdjustAction(this);
+
/* "Devices" menu actions: */
m_actionsPool[UIActionIndex_Simple_NetworkAdaptersDialog] = new ShowNetworkAdaptersDialogAction(this);
m_actionsPool[UIActionIndex_Simple_SharedFoldersDialog] = new ShowSharedFoldersDialogAction(this);
@@ -1225,13 +1250,14 @@ void UIActionsPool::createMenus()
if (m_actionsPool[UIActionIndex_Menu_Machine])
delete m_actionsPool[UIActionIndex_Menu_Machine];
m_actionsPool[UIActionIndex_Menu_Machine] = new MenuMachineAction(this);
- if (m_actionsPool[UIActionIndex_Menu_View])
- delete m_actionsPool[UIActionIndex_Menu_View];
- m_actionsPool[UIActionIndex_Menu_View] = new MenuViewAction(this);
if (m_actionsPool[UIActionIndex_Menu_MouseIntegration])
delete m_actionsPool[UIActionIndex_Menu_MouseIntegration];
m_actionsPool[UIActionIndex_Menu_MouseIntegration] = new MenuMouseIntegrationAction(this);
+ if (m_actionsPool[UIActionIndex_Menu_View])
+ delete m_actionsPool[UIActionIndex_Menu_View];
+ m_actionsPool[UIActionIndex_Menu_View] = new MenuViewAction(this);
+
if (m_actionsPool[UIActionIndex_Menu_Devices])
delete m_actionsPool[UIActionIndex_Menu_Devices];
m_actionsPool[UIActionIndex_Menu_Devices] = new MenuDevicesAction(this);
@@ -1247,7 +1273,6 @@ void UIActionsPool::createMenus()
if (m_actionsPool[UIActionIndex_Menu_NetworkAdapters])
delete m_actionsPool[UIActionIndex_Menu_NetworkAdapters];
m_actionsPool[UIActionIndex_Menu_NetworkAdapters] = new MenuNetworkAdaptersAction(this);
-
if (m_actionsPool[UIActionIndex_Menu_SharedFolders])
delete m_actionsPool[UIActionIndex_Menu_SharedFolders];
m_actionsPool[UIActionIndex_Menu_SharedFolders] = new MenuSharedFoldersAction(this);
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.h
index a7a9d065b..3e8220f9d 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.h
@@ -51,19 +51,15 @@ enum UIActionIndex
{
/* "Machine" menu actions: */
UIActionIndex_Menu_Machine,
- UIActionIndex_Toggle_Fullscreen,
- UIActionIndex_Toggle_Seamless,
- UIActionIndex_Toggle_Scale,
- UIActionIndex_Toggle_GuestAutoresize,
- UIActionIndex_Simple_AdjustWindow,
+ UIActionIndex_Simple_SettingsDialog,
+ UIActionIndex_Simple_TakeSnapshot,
+ UIActionIndex_Simple_InformationDialog,
UIActionIndex_Menu_MouseIntegration,
UIActionIndex_Toggle_MouseIntegration,
UIActionIndex_Simple_TypeCAD,
#ifdef Q_WS_X11
UIActionIndex_Simple_TypeCABS,
#endif
- UIActionIndex_Simple_TakeSnapshot,
- UIActionIndex_Simple_InformationDialog,
UIActionIndex_Toggle_Pause,
UIActionIndex_Simple_Reset,
UIActionIndex_Simple_Shutdown,
@@ -71,6 +67,11 @@ enum UIActionIndex
/* "View" menu actions: */
UIActionIndex_Menu_View,
+ UIActionIndex_Toggle_Fullscreen,
+ UIActionIndex_Toggle_Seamless,
+ UIActionIndex_Toggle_Scale,
+ UIActionIndex_Toggle_GuestAutoresize,
+ UIActionIndex_Simple_AdjustWindow,
/* "Devices" menu actions: */
UIActionIndex_Menu_Devices,
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIConsoleEventHandler.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIConsoleEventHandler.cpp
index 1caae96b1..b444f6d28 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIConsoleEventHandler.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIConsoleEventHandler.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIConsoleEventHandler.cpp $ */
+/* $Id: UIConsoleEventHandler.cpp 37712 2011-06-30 14:11:14Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -58,7 +58,9 @@ UIConsoleEventHandler::UIConsoleEventHandler(UISession *pSession)
Assert(pSession);
// RTPrintf("Self add: %RTthrd\n", RTThreadSelf());
- UIMainEventListenerImpl *pListener = new UIMainEventListenerImpl(this);
+ ComObjPtr<UIMainEventListenerImpl> pListener;
+ pListener.createObject();
+ pListener->init(new UIMainEventListener(), this);
m_mainEventListener = CEventListener(pListener);
QVector<KVBoxEventType> events;
events
@@ -69,12 +71,15 @@ UIConsoleEventHandler::UIConsoleEventHandler(UISession *pSession)
<< KVBoxEventType_OnAdditionsStateChanged
<< KVBoxEventType_OnNetworkAdapterChanged
<< KVBoxEventType_OnMediumChanged
+ << KVBoxEventType_OnVRDEServerChanged
+ << KVBoxEventType_OnVRDEServerInfoChanged
<< KVBoxEventType_OnUSBControllerChanged
<< KVBoxEventType_OnUSBDeviceStateChanged
<< KVBoxEventType_OnSharedFolderChanged
<< KVBoxEventType_OnRuntimeError
<< KVBoxEventType_OnCanShowWindow
- << KVBoxEventType_OnShowWindow;
+ << KVBoxEventType_OnShowWindow
+ << KVBoxEventType_OnCPUExecutionCapChanged;
const CConsole &console = m_pSession->session().GetConsole();
console.GetEventSource().RegisterListener(m_mainEventListener, events, TRUE);
@@ -108,6 +113,10 @@ UIConsoleEventHandler::UIConsoleEventHandler(UISession *pSession)
this, SIGNAL(sigMediumChange(CMediumAttachment)),
Qt::QueuedConnection);
+ connect(pListener->getWrapped(), SIGNAL(sigVRDEChange()),
+ this, SIGNAL(sigVRDEChange()),
+ Qt::QueuedConnection);
+
connect(pListener->getWrapped(), SIGNAL(sigUSBControllerChange()),
this, SIGNAL(sigUSBControllerChange()),
Qt::QueuedConnection);
@@ -135,6 +144,10 @@ UIConsoleEventHandler::UIConsoleEventHandler(UISession *pSession)
connect(pListener->getWrapped(), SIGNAL(sigShowWindow(LONG64&)),
this, SLOT(sltShowWindow(LONG64&)),
Qt::DirectConnection);
+
+ connect(pListener->getWrapped(), SIGNAL(sigCPUExecutionCapChange()),
+ this, SIGNAL(sigCPUExecutionCapChange()),
+ Qt::QueuedConnection);
}
UIConsoleEventHandler::~UIConsoleEventHandler()
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIConsoleEventHandler.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIConsoleEventHandler.h
index 644a50e10..8e56e0430 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIConsoleEventHandler.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIConsoleEventHandler.h
@@ -41,6 +41,7 @@ signals:
void sigAdditionsChange();
void sigNetworkAdapterChange(CNetworkAdapter adapter);
void sigMediumChange(CMediumAttachment attachment);
+ void sigVRDEChange();
void sigUSBControllerChange();
void sigUSBDeviceStateChange(CUSBDevice device, bool fAttached, CVirtualBoxErrorInfo error);
void sigSharedFolderChange();
@@ -48,6 +49,7 @@ signals:
#ifdef RT_OS_DARWIN
void sigShowWindow();
#endif /* RT_OS_DARWIN */
+ void sigCPUExecutionCapChange();
private slots:
void sltCanShowWindow(bool &fVeto, QString &strReason);
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
index 5e78b4f32..48b3aebea 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIFrameBuffer.cpp $ */
+/* $Id: UIFrameBuffer.cpp 31698 2010-08-16 15:00:05Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferDirectDraw.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferDirectDraw.cpp
index 650cb5bfd..bb9384752 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferDirectDraw.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferDirectDraw.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIFrameBufferDirectDraw.cpp $ */
+/* $Id: UIFrameBufferDirectDraw.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQGL.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQGL.cpp
index ecc38973e..c5e43f903 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQGL.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQGL.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIFrameBufferQGL.cpp $ */
+/* $Id: UIFrameBufferQGL.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxFBQGL Opengl-based FrameBuffer implementation
*/
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.cpp
index 70feca1ed..cd8b2c0a9 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIFrameBufferQImage.cpp $ */
+/* $Id: UIFrameBufferQImage.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -66,6 +66,7 @@ void UIFrameBufferQImage::paintEvent(QPaintEvent *pEvent)
/* Scaled image by default is empty: */
QImage scaledImage;
+
/* If scaled-factor is set and current image is NOT null: */
if (m_scaledSize.isValid() && !m_img.isNull())
{
@@ -92,6 +93,7 @@ void UIFrameBufferQImage::paintEvent(QPaintEvent *pEvent)
QPainter painter(m_pMachineView->viewport());
+
if ((ulong)r.width() < m_width * 2 / 3)
{
/* This method is faster for narrow updates */
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQuartz2D.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQuartz2D.cpp
index fafad2c9f..e77c2ee3f 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQuartz2D.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQuartz2D.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIFrameBufferQuartz2D.cpp $ */
+/* $Id: UIFrameBufferQuartz2D.cpp 37063 2011-05-13 10:21:28Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferSDL.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferSDL.cpp
index 8b035679b..86ce55066 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferSDL.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferSDL.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIFrameBufferSDL.cpp $ */
+/* $Id: UIFrameBufferSDL.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.cpp
index 450e7effe..78892c180 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIIndicatorsPool.cpp $ */
+/* $Id: UIIndicatorsPool.cpp 37753 2011-07-04 10:09:18Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -269,7 +269,7 @@ public:
const CMachine &machine = m_session.GetMachine();
QString strFullData;
- ulong uMaxCount = vboxGlobal().virtualBox().GetSystemProperties().GetNetworkAdapterCount();
+ ulong uMaxCount = vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3);
QString strToolTip = QApplication::translate("UIIndicatorsPool",
"<p style='white-space:pre'><nobr>Indicates the activity of the "
@@ -565,13 +565,18 @@ public:
VBoxGlobal::tr("Enabled", "nested paging") :
VBoxGlobal::tr("Disabled", "nested paging");
- QString tip(QApplication::translate("UIIndicatorsPool", "Indicates the status of the hardware virtualization "
- "features used by this virtual machine:"
- "<br><nobr><b>%1:</b>&nbsp;%2</nobr>"
- "<br><nobr><b>%3:</b>&nbsp;%4</nobr>",
- "Virtualization Stuff LED")
- .arg(VBoxGlobal::tr("VT-x/AMD-V", "details report"), virtualization)
- .arg(VBoxGlobal::tr("Nested Paging"), nestedPaging));
+ QString strCPUExecCap = QString::number(console.GetMachine().GetCPUExecutionCap());
+
+ QString tip(QApplication::translate("UIIndicatorsPool",
+ "Indicates the status of different "
+ "features used by this virtual machine:"
+ "<br><nobr><b>%1:</b>&nbsp;%2</nobr>"
+ "<br><nobr><b>%3:</b>&nbsp;%4</nobr>"
+ "<br><nobr><b>%5:</b>&nbsp;%6%</nobr>",
+ "Virtualization Stuff LED")
+ .arg(VBoxGlobal::tr("VT-x/AMD-V", "details report"), virtualization)
+ .arg(VBoxGlobal::tr("Nested Paging"), nestedPaging)
+ .arg(VBoxGlobal::tr("Execution Cap", "details report"), strCPUExecCap));
int cpuCount = console.GetMachine().GetCPUCount();
if (cpuCount > 1)
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp
index b71fa383a..8406d1cbf 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIKeyboardHandler.cpp $ */
+/* $Id: UIKeyboardHandler.cpp 37716 2011-06-30 16:34:13Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -484,7 +484,7 @@ bool UIKeyboardHandler::x11EventFilter(XEvent *pEvent, ulong uScreenId)
case XFocusOut:
case XFocusIn:
{
- if (uisession()->isRunning())
+ if (isSessionRunning())
{
if (VBoxGlobal::qtRTVersion() < ((4 << 16) | (5 << 8) | 0))
{
@@ -493,8 +493,8 @@ bool UIKeyboardHandler::x11EventFilter(XEvent *pEvent, ulong uScreenId)
/* Capture keyboard by chosen view number: */
captureKeyboard(uScreenId);
/* Reset the single-time disable capture flag: */
- if (uisession()->isAutoCaptureDisabled())
- uisession()->setAutoCaptureDisabled(false);
+ if (isAutoCaptureDisabled())
+ setAutoCaptureDisabled(false);
}
else
{
@@ -607,19 +607,19 @@ void UIKeyboardHandler::sltMachineStateChanged()
QList<ulong> theListOfViewIds = m_views.keys();
for (int i = 0; i < theListOfViewIds.size(); ++i)
{
- if (m_views[theListOfViewIds[i]]->hasFocus())
+ if (viewHasFocus(theListOfViewIds[i]))
{
/* Capture keyboard: */
#ifdef Q_WS_WIN
- if (!uisession()->isAutoCaptureDisabled() && m_globalSettings.autoCapture() &&
+ if (!isAutoCaptureDisabled() && autoCaptureSetGlobally() &&
GetAncestor(m_views[theListOfViewIds[i]]->winId(), GA_ROOT) == GetForegroundWindow())
#else /* Q_WS_WIN */
- if (!uisession()->isAutoCaptureDisabled() && m_globalSettings.autoCapture())
+ if (!isAutoCaptureDisabled() && autoCaptureSetGlobally())
#endif /* !Q_WS_WIN */
captureKeyboard(theListOfViewIds[i]);
/* Reset the single-time disable capture flag: */
- if (uisession()->isAutoCaptureDisabled())
- uisession()->setAutoCaptureDisabled(false);
+ if (isAutoCaptureDisabled())
+ setAutoCaptureDisabled(false);
break;
}
}
@@ -826,24 +826,24 @@ bool UIKeyboardHandler::eventFilter(QObject *pWatchedObject, QEvent *pEvent)
switch (pEvent->type())
{
case QEvent::FocusIn:
- if (uisession()->isRunning())
+ if (isSessionRunning())
{
/* Capture keyboard: */
#ifdef Q_WS_WIN
- if (!uisession()->isAutoCaptureDisabled() && m_globalSettings.autoCapture() &&
+ if (!isAutoCaptureDisabled() && autoCaptureSetGlobally() &&
GetAncestor(pWatchedView->winId(), GA_ROOT) == GetForegroundWindow())
#else /* Q_WS_WIN */
- if (!uisession()->isAutoCaptureDisabled() && m_globalSettings.autoCapture())
+ if (!isAutoCaptureDisabled() && autoCaptureSetGlobally())
#endif /* !Q_WS_WIN */
captureKeyboard(uScreenId);
/* Reset the single-time disable capture flag: */
- if (uisession()->isAutoCaptureDisabled())
- uisession()->setAutoCaptureDisabled(false);
+ if (isAutoCaptureDisabled())
+ setAutoCaptureDisabled(false);
}
break;
case QEvent::FocusOut:
/* Release keyboard: */
- if (uisession()->isRunning())
+ if (isSessionRunning())
releaseKeyboard();
/* And all pressed keys: */
releaseAllPressedKeys(true);
@@ -1109,6 +1109,203 @@ bool UIKeyboardHandler::darwinKeyboardEvent(const void *pvCocoaEvent, EventRef i
#endif
+/**
+ * If the user has just completed a control-alt-del combination then handle
+ * that.
+ * @returns true if handling should stop here, false otherwise
+ */
+bool UIKeyboardHandler::keyEventCADHandled(uint8_t uScan)
+{
+ /* Check if it's C-A-D and GUI/PassCAD is not true: */
+ if (!m_fPassCAD &&
+ uScan == 0x53 /* Del */ &&
+ ((m_pressedKeys[0x38] & IsKeyPressed) /* Alt */ ||
+ (m_pressedKeys[0x38] & IsExtKeyPressed)) &&
+ ((m_pressedKeys[0x1d] & IsKeyPressed) /* Ctrl */ ||
+ (m_pressedKeys[0x1d] & IsExtKeyPressed)))
+ {
+ /* Use the C-A-D combination as a last resort to get the keyboard and mouse back
+ * to the host when the user forgets the Host Key. Note that it's always possible
+ * to send C-A-D to the guest using the Host+Del combination: */
+ if (isSessionRunning() && m_fIsKeyboardCaptured)
+ {
+ releaseKeyboard();
+ if (!uisession()->isMouseSupportsAbsolute() || !uisession()->isMouseIntegrated())
+ machineLogic()->mouseHandler()->releaseMouse();
+ }
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Handle a non-special (C-A-D, pause, print) key press or release
+ * @returns true if handling should stop here, false otherwise
+ */
+bool UIKeyboardHandler::keyEventHandleNormal(int iKey, uint8_t uScan, int fFlags, LONG *pCodes, uint *puCodesCount)
+{
+ /* Get host-combo key list: */
+ QSet<int> allHostComboKeys = UIHotKeyCombination::toKeyCodeList(m_globalSettings.hostCombo()).toSet();
+ /* Get the type of key - simple or extended: */
+ uint8_t uWhatPressed = fFlags & KeyExtended ? IsExtKeyPressed : IsKeyPressed;
+
+ /* If some key was pressed or some previously pressed key was released =>
+ * we are updating the list of pressed keys and preparing scancodes: */
+ if ((fFlags & KeyPressed) || (m_pressedKeys[uScan] & uWhatPressed))
+ {
+ /* Check if the guest has the same view on the modifier keys
+ * (NumLock, CapsLock, ScrollLock) as the X server.
+ * If not, send KeyPress events to synchronize the state: */
+ if (fFlags & KeyPressed)
+ fixModifierState(pCodes, puCodesCount);
+
+ /* Prepend 'extended' scancode if needed: */
+ if (fFlags & KeyExtended)
+ pCodes[(*puCodesCount)++] = 0xE0;
+
+ /* Process key-press: */
+ if (fFlags & KeyPressed)
+ {
+ /* Append scancode: */
+ pCodes[(*puCodesCount)++] = uScan;
+ m_pressedKeys[uScan] |= uWhatPressed;
+ }
+ /* Process key-release if that key was pressed before: */
+ else if (m_pressedKeys[uScan] & uWhatPressed)
+ {
+ /* Append scancode: */
+ pCodes[(*puCodesCount)++] = uScan | 0x80;
+ m_pressedKeys[uScan] &= ~uWhatPressed;
+ }
+
+ /* Update keyboard-captured flag: */
+ if (m_fIsKeyboardCaptured)
+ m_pressedKeys[uScan] |= IsKbdCaptured;
+ else
+ m_pressedKeys[uScan] &= ~IsKbdCaptured;
+ }
+ /* Ignore key-release if that key was NOT pressed before,
+ * but only if thats not one of the host-combination keys: */
+ else if (!allHostComboKeys.contains(iKey))
+ return true;
+ return false;
+}
+
+/**
+ * Check whether the key pressed results in a host key combination being
+ * handled.
+ * @returns true if a combination was handled, false otherwise
+ * @param pfResult where to store the result of the handling
+ */
+bool UIKeyboardHandler::keyEventHostComboHandled(int iKey, wchar_t *pUniKey, bool isHostComboStateChanged, bool *pfResult)
+{
+ if (isHostComboStateChanged)
+ {
+ if (!m_bIsHostComboPressed)
+ {
+ m_bIsHostComboPressed = true;
+ m_bIsHostComboAlone = true;
+ m_bIsHostComboProcessed = false;
+ if (isSessionRunning())
+ saveKeyStates();
+ }
+ }
+ else
+ {
+ if (m_bIsHostComboPressed)
+ {
+ if (m_bIsHostComboAlone)
+ {
+ m_bIsHostComboAlone = false;
+ m_bIsHostComboProcessed = true;
+ /* Process Host+<key> shortcuts.
+ * Currently, <key> is limited to alphanumeric chars.
+ * Other Host+<key> combinations are handled in Qt event(): */
+ *pfResult = processHotKey(iKey, pUniKey);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/**
+ * Handle a key event that releases the host key combination
+ */
+void UIKeyboardHandler::keyEventHandleHostComboRelease(ulong uScreenId)
+{
+ if (m_bIsHostComboPressed)
+ {
+ m_bIsHostComboPressed = false;
+ /* Capturing/releasing keyboard/mouse if necessary: */
+ if (m_bIsHostComboAlone && !m_bIsHostComboProcessed)
+ {
+ if (isSessionRunning())
+ {
+ bool ok = true;
+ if (!m_fIsKeyboardCaptured)
+ {
+ /* Temporarily disable auto-capture that will take place after
+ * this dialog is dismissed because the capture state is to be
+ * defined by the dialog result itself: */
+ setAutoCaptureDisabled(true);
+ bool fIsAutoConfirmed = false;
+ ok = vboxProblem().confirmInputCapture(&fIsAutoConfirmed);
+ if (fIsAutoConfirmed)
+ setAutoCaptureDisabled(false);
+ /* Otherwise, the disable flag will be reset in the next
+ * machine-view's focus-in event (since may happen asynchronously
+ * on some platforms, after we return from this code): */
+ }
+ if (ok)
+ {
+ if (m_fIsKeyboardCaptured)
+ releaseKeyboard();
+ else
+ captureKeyboard(uScreenId);
+ if (!uisession()->isMouseSupportsAbsolute() || !uisession()->isMouseIntegrated())
+ {
+#ifdef Q_WS_X11
+ /* Make sure that pending FocusOut events from the
+ * previous message box are handled, otherwise the
+ * mouse is immediately ungrabbed: */
+ qApp->processEvents();
+#endif /* Q_WS_X11 */
+ if (m_fIsKeyboardCaptured)
+ machineLogic()->mouseHandler()->captureMouse(uScreenId);
+ else
+ machineLogic()->mouseHandler()->releaseMouse();
+ }
+ }
+ }
+ }
+ if (isSessionRunning())
+ sendChangedKeyStates();
+ }
+}
+
+void UIKeyboardHandler::keyEventReleaseHostComboKeys(CKeyboard keyboard)
+{
+ /* We have to make guest to release pressed keys from the host-combination: */
+ QList<uint8_t> hostComboScans = m_pressedHostComboKeys.values();
+ for (int i = 0 ; i < hostComboScans.size(); ++i)
+ {
+ uint8_t uScan = hostComboScans[i];
+ if (m_pressedKeys[uScan] & IsKeyPressed)
+ {
+ keyboard.PutScancode(uScan | 0x80);
+ }
+ else if (m_pressedKeys[uScan] & IsExtKeyPressed)
+ {
+ QVector<LONG> scancodes(2);
+ scancodes[0] = 0xE0;
+ scancodes[1] = uScan | 0x80;
+ keyboard.PutScancodes(scancodes);
+ }
+ m_pressedKeys[uScan] = 0;
+ }
+}
+
bool UIKeyboardHandler::keyEvent(int iKey, uint8_t uScan, int fFlags, ulong uScreenId, wchar_t *pUniKey /* = 0 */)
{
/* Get host-combo key list: */
@@ -1144,25 +1341,8 @@ bool UIKeyboardHandler::keyEvent(int iKey, uint8_t uScan, int fFlags, ulong uScr
}
#endif /* Q_WS_WIN */
- /* Check if it's C-A-D and GUI/PassCAD is not true: */
- if (!m_fPassCAD &&
- uScan == 0x53 /* Del */ &&
- ((m_pressedKeys[0x38] & IsKeyPressed) /* Alt */ ||
- (m_pressedKeys[0x38] & IsExtKeyPressed)) &&
- ((m_pressedKeys[0x1d] & IsKeyPressed) /* Ctrl */ ||
- (m_pressedKeys[0x1d] & IsExtKeyPressed)))
- {
- /* Use the C-A-D combination as a last resort to get the keyboard and mouse back
- * to the host when the user forgets the Host Key. Note that it's always possible
- * to send C-A-D to the guest using the Host+Del combination: */
- if (uisession()->isRunning() && m_fIsKeyboardCaptured)
- {
- releaseKeyboard();
- if (!uisession()->isMouseSupportsAbsolute() || !uisession()->isMouseIntegrated())
- machineLogic()->mouseHandler()->releaseMouse();
- }
+ if (keyEventCADHandled(uScan))
return true;
- }
/* Preparing the press/release scan-codes array for sending to the guest:
* 1. if host-combo is NOT pressed, taking into account currently pressed key too,
@@ -1209,135 +1389,21 @@ bool UIKeyboardHandler::keyEvent(int iKey, uint8_t uScan, int fFlags, ulong uScr
}
/* Common flags handling: */
else
- {
- /* Get the type of key - simple or extended: */
- uint8_t uWhatPressed = fFlags & KeyExtended ? IsExtKeyPressed : IsKeyPressed;
-
- /* If some key was pressed or some previously pressed key was released =>
- * we are updating the list of pressed keys and preparing scancodes: */
- if ((fFlags & KeyPressed) || (m_pressedKeys[uScan] & uWhatPressed))
- {
- /* Check if the guest has the same view on the modifier keys
- * (NumLock, CapsLock, ScrollLock) as the X server.
- * If not, send KeyPress events to synchronize the state: */
- if (fFlags & KeyPressed)
- fixModifierState(pCodes, &uCodesCount);
-
- /* Prepend 'extended' scancode if needed: */
- if (fFlags & KeyExtended)
- pCodes[uCodesCount++] = 0xE0;
-
- /* Process key-press: */
- if (fFlags & KeyPressed)
- {
- /* Append scancode: */
- pCodes[uCodesCount++] = uScan;
- m_pressedKeys[uScan] |= uWhatPressed;
- }
- /* Process key-release if that key was pressed before: */
- else if (m_pressedKeys[uScan] & uWhatPressed)
- {
- /* Append scancode: */
- pCodes[uCodesCount++] = uScan | 0x80;
- m_pressedKeys[uScan] &= ~uWhatPressed;
- }
-
- /* Update keyboard-captured flag: */
- if (m_fIsKeyboardCaptured)
- m_pressedKeys[uScan] |= IsKbdCaptured;
- else
- m_pressedKeys[uScan] &= ~IsKbdCaptured;
- }
- /* Ignore key-release if that key was NOT pressed before,
- * but only if thats not one of the host-combination keys: */
- else if (!allHostComboKeys.contains(iKey))
+ if (keyEventHandleNormal(iKey, uScan, fFlags, pCodes, &uCodesCount))
return true;
- }
}
/* Process the host-combo funtionality: */
if (fFlags & KeyPressed)
{
- if (isHostComboStateChanged)
- {
- if (!m_bIsHostComboPressed)
- {
- m_bIsHostComboPressed = true;
- m_bIsHostComboAlone = true;
- m_bIsHostComboProcessed = false;
- if (uisession()->isRunning())
- saveKeyStates();
- }
- }
- else
- {
- if (m_bIsHostComboPressed)
- {
- if (m_bIsHostComboAlone)
- {
- m_bIsHostComboAlone = false;
- m_bIsHostComboProcessed = true;
- /* Process Host+<key> shortcuts.
- * Currently, <key> is limited to alphanumeric chars.
- * Other Host+<key> combinations are handled in Qt event(): */
- return processHotKey(iKey, pUniKey);
- }
- }
- }
+ bool fResult;
+ if (keyEventHostComboHandled(iKey, pUniKey, isHostComboStateChanged, &fResult))
+ return fResult;
}
else
{
if (isHostComboStateChanged)
- {
- if (m_bIsHostComboPressed)
- {
- m_bIsHostComboPressed = false;
- /* Capturing/releasing keyboard/mouse if necessary: */
- if (m_bIsHostComboAlone && !m_bIsHostComboProcessed)
- {
- if (uisession()->isRunning())
- {
- bool ok = true;
- if (!m_fIsKeyboardCaptured)
- {
- /* Temporarily disable auto-capture that will take place after
- * this dialog is dismissed because the capture state is to be
- * defined by the dialog result itself: */
- uisession()->setAutoCaptureDisabled(true);
- bool fIsAutoConfirmed = false;
- ok = vboxProblem().confirmInputCapture(&fIsAutoConfirmed);
- if (fIsAutoConfirmed)
- uisession()->setAutoCaptureDisabled(false);
- /* Otherwise, the disable flag will be reset in the next
- * machine-view's focus-in event (since may happen asynchronously
- * on some platforms, after we return from this code): */
- }
- if (ok)
- {
- if (m_fIsKeyboardCaptured)
- releaseKeyboard();
- else
- captureKeyboard(uScreenId);
- if (!uisession()->isMouseSupportsAbsolute() || !uisession()->isMouseIntegrated())
- {
-#ifdef Q_WS_X11
- /* Make sure that pending FocusOut events from the
- * previous message box are handled, otherwise the
- * mouse is immediately ungrabbed: */
- qApp->processEvents();
-#endif /* Q_WS_X11 */
- if (m_fIsKeyboardCaptured)
- machineLogic()->mouseHandler()->captureMouse(uScreenId);
- else
- machineLogic()->mouseHandler()->releaseMouse();
- }
- }
- }
- }
- if (uisession()->isRunning())
- sendChangedKeyStates();
- }
- }
+ keyEventHandleHostComboRelease(uScreenId);
else
{
if (m_bIsHostComboPressed)
@@ -1366,24 +1432,7 @@ bool UIKeyboardHandler::keyEvent(int iKey, uint8_t uScan, int fFlags, ulong uScr
/* If full host-key sequence was just finalized: */
if (isHostComboStateChanged && m_bIsHostComboPressed)
{
- /* We have to make guest to release pressed keys from the host-combination: */
- QList<uint8_t> hostComboScans = m_pressedHostComboKeys.values();
- for (int i = 0 ; i < hostComboScans.size(); ++i)
- {
- uint8_t uScan = hostComboScans[i];
- if (m_pressedKeys[uScan] & IsKeyPressed)
- {
- keyboard.PutScancode(uScan | 0x80);
- }
- else if (m_pressedKeys[uScan] & IsExtKeyPressed)
- {
- QVector<LONG> scancodes(2);
- scancodes[0] = 0xE0;
- scancodes[1] = uScan | 0x80;
- keyboard.PutScancodes(scancodes);
- }
- m_pressedKeys[uScan] = 0;
- }
+ keyEventReleaseHostComboKeys(keyboard);
}
}
@@ -1563,6 +1612,31 @@ void UIKeyboardHandler::sendChangedKeyStates()
}
}
+bool UIKeyboardHandler::isAutoCaptureDisabled()
+{
+ return uisession()->isAutoCaptureDisabled();
+}
+
+void UIKeyboardHandler::setAutoCaptureDisabled(bool fIsAutoCaptureDisabled)
+{
+ uisession()->setAutoCaptureDisabled(fIsAutoCaptureDisabled);
+}
+
+bool UIKeyboardHandler::autoCaptureSetGlobally()
+{
+ return m_globalSettings.autoCapture();
+}
+
+bool UIKeyboardHandler::viewHasFocus(ulong uScreenId)
+{
+ return m_views[uScreenId]->hasFocus();
+}
+
+bool UIKeyboardHandler::isSessionRunning()
+{
+ return uisession()->isRunning();
+}
+
UIMachineWindow* UIKeyboardHandler::isItListenedWindow(QObject *pWatchedObject) const
{
UIMachineWindow *pResultWindow = 0;
@@ -1596,4 +1670,3 @@ UIMachineView* UIKeyboardHandler::isItListenedView(QObject *pWatchedObject) cons
}
return pResultView;
}
-
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.h
index 53fddf542..bf42d4c3d 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.h
@@ -123,6 +123,11 @@ protected:
static bool darwinEventHandlerProc(const void *pvCocoaEvent, const void *pvCarbonEvent, void *pvUser);
#endif
+ bool keyEventCADHandled(uint8_t uScan);
+ bool keyEventHandleNormal(int iKey, uint8_t uScan, int fFlags, LONG *pCodes, uint *puCodesCount);
+ bool keyEventHostComboHandled(int iKey, wchar_t *pUniKey, bool isHostComboStateChanged, bool *pfResult);
+ void keyEventHandleHostComboRelease(ulong uScreenId);
+ void keyEventReleaseHostComboKeys(CKeyboard keyboard);
/* Separate function to handle most of existing keyboard-events: */
bool keyEvent(int iKey, uint8_t uScan, int fFlags, ulong uScreenId, wchar_t *pUniKey = 0);
bool processHotKey(int iHotKey, wchar_t *pUniKey);
@@ -131,6 +136,11 @@ protected:
void fixModifierState(LONG *piCodes, uint *puCount);
void saveKeyStates();
void sendChangedKeyStates();
+ bool isAutoCaptureDisabled();
+ void setAutoCaptureDisabled(bool fIsAutoCaptureDisabled);
+ bool autoCaptureSetGlobally();
+ bool viewHasFocus(ulong uScreenId);
+ bool isSessionRunning();
UIMachineWindow* isItListenedWindow(QObject *pWatchedObject) const;
UIMachineView* isItListenedView(QObject *pWatchedObject) const;
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp
index 4f1ba425f..ba388344f 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachine.cpp $ */
+/* $Id: UIMachine.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
index 7f411de19..3db5eb948 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineLogic.cpp $ */
+/* $Id: UIMachineLogic.cpp 37992 2011-07-18 09:39:03Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -6,7 +6,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;
@@ -37,8 +37,7 @@
#include "VBoxProblemReporter.h"
#include "VBoxTakeSnapshotDlg.h"
#include "VBoxVMInformationDlg.h"
-#include "UIMachineSettingsNetwork.h"
-#include "UIMachineSettingsSF.h"
+#include "UISettingsDialogSpecific.h"
#ifdef Q_WS_MAC
# include "DockIconPreview.h"
# include "UIExtraDataEventHandler.h"
@@ -102,154 +101,6 @@ struct USBTarget
};
Q_DECLARE_METATYPE(USBTarget);
-class UINetworkAdaptersDialog : public QIWithRetranslateUI<QDialog>
-{
- Q_OBJECT;
-
-public:
-
- UINetworkAdaptersDialog(QWidget *pParent, CSession &session)
- : QIWithRetranslateUI<QDialog>(pParent)
- , m_pSettings(0)
- , m_session(session)
- {
- /* Setup Dialog's options */
- setModal(true);
- setWindowIcon(QIcon(":/nw_16px.png"));
- setSizeGripEnabled(true);
-
- /* Setup main dialog's layout */
- QVBoxLayout *pMainLayout = new QVBoxLayout(this);
- VBoxGlobal::setLayoutMargin(pMainLayout, 10);
- pMainLayout->setSpacing(10);
-
- /* Setup settings layout */
- m_pSettings = new UIMachineSettingsNetworkPage(true);
- m_pSettings->setOrderAfter(this);
- VBoxGlobal::setLayoutMargin(m_pSettings->layout(), 0);
- m_pSettings->loadDirectlyFrom(m_session.GetMachine());
- pMainLayout->addWidget(m_pSettings);
-
- /* Setup button's layout */
- QIDialogButtonBox *pButtonBox = new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help);
-
- connect(pButtonBox, SIGNAL(helpRequested()), &vboxProblem(), SLOT(showHelpHelpDialog()));
- connect(pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
- connect(pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
- pMainLayout->addWidget(pButtonBox);
-
- retranslateUi();
- }
-
-protected:
-
- void retranslateUi()
- {
- setWindowTitle(QApplication::translate("VBoxNetworkDialog", "Network Adapters"));
- }
-
-protected slots:
-
- virtual void accept()
- {
- CMachine machine = m_session.GetMachine();
- m_pSettings->saveDirectlyTo(machine);
- machine.SaveSettings();
- if (!machine.isOk())
- vboxProblem().cannotSaveMachineSettings(machine);
- QDialog::accept();
- }
-
-protected:
-
- void showEvent(QShowEvent *pEvent)
- {
- resize(450, 300);
- VBoxGlobal::centerWidget(this, parentWidget());
- setMinimumWidth(400);
- QDialog::showEvent(pEvent);
- }
-
-private:
-
- UIMachineSettingsNetworkPage *m_pSettings;
- CSession &m_session;
-};
-
-class UISharedFoldersDialog : public QIWithRetranslateUI<QDialog>
-{
- Q_OBJECT;
-
-public:
-
- UISharedFoldersDialog(QWidget *pParent, CSession &session)
- : QIWithRetranslateUI<QDialog>(pParent)
- , m_pSettings(0)
- , m_session(session)
- {
- /* Setup Dialog's options */
- setModal(true);
- setWindowIcon(QIcon(":/select_file_16px.png"));
- setSizeGripEnabled(true);
-
- /* Setup main dialog's layout */
- QVBoxLayout *pMainLayout = new QVBoxLayout(this);
- VBoxGlobal::setLayoutMargin(pMainLayout, 10);
- pMainLayout->setSpacing(10);
-
- /* Setup settings layout */
- m_pSettings = new UIMachineSettingsSF;
- VBoxGlobal::setLayoutMargin(m_pSettings->layout(), 0);
- m_pSettings->loadDirectlyFrom(m_session.GetConsole());
- pMainLayout->addWidget(m_pSettings);
-
- /* Setup button's layout */
- QIDialogButtonBox *pButtonBox = new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help);
-
- connect(pButtonBox, SIGNAL(helpRequested()), &vboxProblem(), SLOT(showHelpHelpDialog()));
- connect(pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
- connect(pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
- pMainLayout->addWidget(pButtonBox);
-
- retranslateUi();
- }
-
-protected:
-
- void retranslateUi()
- {
- setWindowTitle(QApplication::translate("VBoxSFDialog", "Shared Folders"));
- }
-
-protected slots:
-
- virtual void accept()
- {
- CMachine machine = m_session.GetMachine();
- CConsole console = m_session.GetConsole();
- m_pSettings->saveDirectlyTo(console);
- machine.SaveSettings();
- if (!machine.isOk())
- vboxProblem().cannotSaveMachineSettings(machine);
- QDialog::accept();
- }
-
-protected:
-
- void showEvent (QShowEvent *aEvent)
- {
- resize(450, 300);
- VBoxGlobal::centerWidget(this, parentWidget());
- setMinimumWidth(400);
- QDialog::showEvent(aEvent);
- }
-
-private:
-
- UIMachineSettingsSF *m_pSettings;
- CSession &m_session;
-};
-
UIMachineLogic* UIMachineLogic::create(QObject *pParent,
UISession *pSession,
UIActionsPool *pActionsPool,
@@ -473,10 +324,12 @@ void UIMachineLogic::prepareSessionConnections()
void UIMachineLogic::prepareActionConnections()
{
/* "Machine" actions connections: */
- connect(actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize), SIGNAL(toggled(bool)),
- this, SLOT(sltToggleGuestAutoresize(bool)));
- connect(actionsPool()->action(UIActionIndex_Simple_AdjustWindow), SIGNAL(triggered()),
- this, SLOT(sltAdjustWindow()));
+ connect(actionsPool()->action(UIActionIndex_Simple_SettingsDialog), SIGNAL(triggered()),
+ this, SLOT(sltOpenVMSettingsDialog()));
+ connect(actionsPool()->action(UIActionIndex_Simple_TakeSnapshot), SIGNAL(triggered()),
+ this, SLOT(sltTakeSnapshot()));
+ connect(actionsPool()->action(UIActionIndex_Simple_InformationDialog), SIGNAL(triggered()),
+ this, SLOT(sltShowInformationDialog()));
connect(actionsPool()->action(UIActionIndex_Toggle_MouseIntegration), SIGNAL(toggled(bool)),
this, SLOT(sltToggleMouseIntegration(bool)));
connect(actionsPool()->action(UIActionIndex_Simple_TypeCAD), SIGNAL(triggered()),
@@ -485,10 +338,6 @@ void UIMachineLogic::prepareActionConnections()
connect(actionsPool()->action(UIActionIndex_Simple_TypeCABS), SIGNAL(triggered()),
this, SLOT(sltTypeCABS()));
#endif
- connect(actionsPool()->action(UIActionIndex_Simple_TakeSnapshot), SIGNAL(triggered()),
- this, SLOT(sltTakeSnapshot()));
- connect(actionsPool()->action(UIActionIndex_Simple_InformationDialog), SIGNAL(triggered()),
- this, SLOT(sltShowInformationDialog()));
connect(actionsPool()->action(UIActionIndex_Toggle_Pause), SIGNAL(toggled(bool)),
this, SLOT(sltPause(bool)));
connect(actionsPool()->action(UIActionIndex_Simple_Reset), SIGNAL(triggered()),
@@ -498,6 +347,12 @@ void UIMachineLogic::prepareActionConnections()
connect(actionsPool()->action(UIActionIndex_Simple_Close), SIGNAL(triggered()),
this, SLOT(sltClose()));
+ /* "View" actions connections: */
+ connect(actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize), SIGNAL(toggled(bool)),
+ this, SLOT(sltToggleGuestAutoresize(bool)));
+ connect(actionsPool()->action(UIActionIndex_Simple_AdjustWindow), SIGNAL(triggered()),
+ this, SLOT(sltAdjustWindow()));
+
/* "Devices" actions connections: */
connect(actionsPool()->action(UIActionIndex_Menu_OpticalDevices)->menu(), SIGNAL(aboutToShow()),
this, SLOT(sltPrepareStorageMenu()));
@@ -549,23 +404,24 @@ void UIMachineLogic::prepareActionGroups()
m_pRunningOrPausedActions->setExclusive(false);
/* Move actions into running actions group: */
- m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Toggle_Fullscreen));
- m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Toggle_Seamless));
- m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Toggle_Scale));
- m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize));
- m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Simple_AdjustWindow));
m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Simple_TypeCAD));
#ifdef Q_WS_X11
m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Simple_TypeCABS));
#endif
m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Simple_Reset));
m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Simple_Shutdown));
+ m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Toggle_Fullscreen));
+ m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Toggle_Seamless));
+ m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Toggle_Scale));
+ m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize));
+ m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Simple_AdjustWindow));
/* Move actions into running-n-paused actions group: */
- m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Menu_MouseIntegration));
- m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Toggle_MouseIntegration));
+ m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Simple_SettingsDialog));
m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Simple_TakeSnapshot));
m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Simple_InformationDialog));
+ m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Menu_MouseIntegration));
+ m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Toggle_MouseIntegration));
m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Toggle_Pause));
m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Menu_OpticalDevices));
m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Menu_FloppyDevices));
@@ -1089,6 +945,34 @@ void UIMachineLogic::sltClose()
defaultMachineWindow()->sltTryClose();
}
+void UIMachineLogic::sltOpenVMSettingsDialog(const QString &strCategory /* = QString() */)
+{
+ /* Do not process if window(s) missed! */
+ if (!isMachineWindowsCreated())
+ return;
+
+ /* Create and execute current VM settings dialog: */
+ UISettingsDialogMachine dlg(defaultMachineWindow()->machineWindow(),
+ session().GetMachine().GetId(), strCategory, QString());
+ dlg.execute();
+}
+
+void UIMachineLogic::sltOpenNetworkAdaptersDialog()
+{
+ /* Open VM settings : Network page: */
+ sltOpenVMSettingsDialog("#network");
+}
+
+void UIMachineLogic::sltOpenSharedFoldersDialog()
+{
+ /* Do not process if additions are not loaded! */
+ if (!uisession()->isGuestAdditionsActive())
+ vboxProblem().remindAboutGuestAdditionsAreNotActive(defaultMachineWindow()->machineWindow());
+
+ /* Open VM settings : Shared folders page: */
+ sltOpenVMSettingsDialog("#sfolders");
+}
+
void UIMachineLogic::sltPrepareStorageMenu()
{
/* Get the sender() menu: */
@@ -1326,6 +1210,12 @@ void UIMachineLogic::sltMountStorageMedium()
if (attachment != currentAttachment && !medium.isNull() && !medium.GetHostDrive())
usedImages << medium.GetId();
}
+ /* To that moment application focus already returned to machine-view,
+ * so the keyboard already captured too.
+ * We should clear application focus from machine-view now
+ * to let file-open dialog get it. That way the keyboard will be released too: */
+ if (QApplication::focusWidget())
+ QApplication::focusWidget()->clearFocus();
/* Call for file-open window: */
QString strMachineFolder(QFileInfo(machine.GetSettingsFilePath()).absolutePath());
QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(target.type, defaultMachineWindow()->machineWindow(),
@@ -1513,30 +1403,6 @@ void UIMachineLogic::sltAttachUSBDevice()
}
}
-void UIMachineLogic::sltOpenNetworkAdaptersDialog()
-{
- /* Do not process if window(s) missed! */
- if (!isMachineWindowsCreated())
- return;
-
- /* Show network settings dialog: */
- UINetworkAdaptersDialog dlg(defaultMachineWindow()->machineWindow(), session());
- dlg.exec();
-}
-
-void UIMachineLogic::sltOpenSharedFoldersDialog()
-{
- /* Do not process if window(s) missed! */
- if (!isMachineWindowsCreated())
- return;
-
- /* Show shared folders settings dialog: */
- UISharedFoldersDialog dlg(defaultMachineWindow()->machineWindow(), session());
- if (!uisession()->isGuestAdditionsActive())
- vboxProblem().remindAboutGuestAdditionsAreNotActive(defaultMachineWindow()->machineWindow());
- dlg.exec();
-}
-
void UIMachineLogic::sltSwitchVrde(bool fOn)
{
/* Enable VRDE server if possible: */
@@ -1778,5 +1644,3 @@ void UIMachineLogic::dbgAdjustRelativePos()
}
#endif
-#include "UIMachineLogic.moc"
-
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h
index f864b2db9..eb8508115 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h
@@ -5,7 +5,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;
@@ -168,13 +168,14 @@ private slots:
void sltClose();
/* "Device" menu functionality */
+ void sltOpenVMSettingsDialog(const QString &strCategory = QString());
+ void sltOpenNetworkAdaptersDialog();
+ void sltOpenSharedFoldersDialog();
void sltPrepareStorageMenu();
void sltMountStorageMedium();
void sltMountRecentStorageMedium();
void sltPrepareUSBMenu();
void sltAttachUSBDevice();
- void sltOpenNetworkAdaptersDialog();
- void sltOpenSharedFoldersDialog();
void sltSwitchVrde(bool fOn);
void sltInstallGuestAdditions();
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.cpp
index bd13ad55a..86a158c9b 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineMenuBar.cpp $ */
+/* $Id: UIMachineMenuBar.cpp 36364 2011-03-23 11:35:44Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -143,6 +143,7 @@ QList<QMenu*> UIMachineMenuBar::prepareSubMenus(UIActionsPool *pActionsPool, UIM
if (fOptions & UIMainMenuType_View)
{
QMenu *pMenuView = pActionsPool->action(UIActionIndex_Menu_View)->menu();
+ prepareMenuView(pMenuView, pActionsPool);
preparedSubMenus << pMenuView;
}
@@ -188,11 +189,9 @@ void UIMachineMenuBar::prepareMenuMachine(QMenu *pMenu, UIActionsPool *pActionsP
return;
/* Machine submenu: */
- pMenu->addAction(pActionsPool->action(UIActionIndex_Toggle_Fullscreen));
- pMenu->addAction(pActionsPool->action(UIActionIndex_Toggle_Seamless));
- pMenu->addAction(pActionsPool->action(UIActionIndex_Toggle_Scale));
- pMenu->addAction(pActionsPool->action(UIActionIndex_Toggle_GuestAutoresize));
- pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_AdjustWindow));
+ pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_SettingsDialog));
+ pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_TakeSnapshot));
+ pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_InformationDialog));
pMenu->addSeparator();
pMenu->addAction(pActionsPool->action(UIActionIndex_Toggle_MouseIntegration));
pMenu->addSeparator();
@@ -201,10 +200,6 @@ void UIMachineMenuBar::prepareMenuMachine(QMenu *pMenu, UIActionsPool *pActionsP
pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_TypeCABS));
#endif
pMenu->addSeparator();
- pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_TakeSnapshot));
- pMenu->addSeparator();
- pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_InformationDialog));
- pMenu->addSeparator();
pMenu->addAction(pActionsPool->action(UIActionIndex_Toggle_Pause));
pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_Reset));
pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_Shutdown));
@@ -214,6 +209,21 @@ void UIMachineMenuBar::prepareMenuMachine(QMenu *pMenu, UIActionsPool *pActionsP
pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_Close));
}
+void UIMachineMenuBar::prepareMenuView(QMenu *pMenu, UIActionsPool *pActionsPool)
+{
+ /* Do not prepare if ready: */
+ if (!pMenu->isEmpty())
+ return;
+
+ /* View submenu: */
+ pMenu->addAction(pActionsPool->action(UIActionIndex_Toggle_Fullscreen));
+ pMenu->addAction(pActionsPool->action(UIActionIndex_Toggle_Seamless));
+ pMenu->addAction(pActionsPool->action(UIActionIndex_Toggle_Scale));
+ pMenu->addSeparator();
+ pMenu->addAction(pActionsPool->action(UIActionIndex_Toggle_GuestAutoresize));
+ pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_AdjustWindow));
+}
+
void UIMachineMenuBar::prepareMenuDevices(QMenu *pMenu, UIActionsPool *pActionsPool)
{
/* Do not prepare if ready: */
@@ -226,7 +236,6 @@ void UIMachineMenuBar::prepareMenuDevices(QMenu *pMenu, UIActionsPool *pActionsP
pMenu->addMenu(pActionsPool->action(UIActionIndex_Menu_USBDevices)->menu());
pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_NetworkAdaptersDialog));
pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_SharedFoldersDialog));
- pMenu->addSeparator();
pMenu->addAction(pActionsPool->action(UIActionIndex_Toggle_VRDEServer));
pMenu->addSeparator();
pMenu->addAction(pActionsPool->action(UIActionIndex_Simple_InstallGuestTools));
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.h
index 4a810082b..21e920a56 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.h
@@ -44,6 +44,7 @@ protected:
QList<QMenu*> prepareSubMenus(UIActionsPool *pActionsPool, UIMainMenuType fOptions = UIMainMenuType_All);
void prepareMenuMachine(QMenu *pMenu, UIActionsPool *pActionsPool);
+ void prepareMenuView(QMenu *pMenu, UIActionsPool *pActionsPool);
void prepareMenuDevices(QMenu *pMenu, UIActionsPool *pActionsPool);
#ifdef VBOX_WITH_DEBUGGER_GUI
void prepareMenuDebug(QMenu *pMenu, UIActionsPool *pActionsPool);
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineShortcuts.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineShortcuts.cpp
index 459d0be81..ea96cb204 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineShortcuts.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineShortcuts.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineShortcuts.cpp $ */
+/* $Id: UIMachineShortcuts.cpp 36357 2011-03-23 09:36:05Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -25,16 +25,12 @@ template <> UIMachineShortcuts* UIShortcuts<UIMachineShortcuts>::m_pInstance = 0
UIMachineShortcuts::UIMachineShortcuts()
{
/* Defaults */
- m_Shortcuts[FullscreenModeShortcut] = UIKeySequence("FullscreenMode", "F");
- m_Shortcuts[SeamlessModeShortcut] = UIKeySequence("SeamlessMode", "L");
- m_Shortcuts[ScaleModeShortcut] = UIKeySequence("ScaleMode", "C");
- m_Shortcuts[GuestAutoresizeShortcut] = UIKeySequence("GuestAutoresize", "G");
- m_Shortcuts[WindowAdjustShortcut] = UIKeySequence("WindowAdjust", "A");
+ m_Shortcuts[SettingsDialogShortcut] = UIKeySequence("SettingsDialog", "S");
+ m_Shortcuts[TakeSnapshotShortcut] = UIKeySequence("TakeSnapshot", "T");
+ m_Shortcuts[InformationDialogShortcut] = UIKeySequence("InformationDialog", "N");
m_Shortcuts[MouseIntegrationShortcut] = UIKeySequence("MouseIntegration" , "I");
m_Shortcuts[TypeCADShortcut] = UIKeySequence("TypeCAD", "Del");
m_Shortcuts[TypeCABSShortcut] = UIKeySequence("TypeCABS", "Backspace");
- m_Shortcuts[TakeSnapshotShortcut] = UIKeySequence("TakeSnapshot", "S");
- m_Shortcuts[InformationDialogShortcut] = UIKeySequence("InformationDialog", "N");
m_Shortcuts[PauseShortcut] = UIKeySequence("Pause", "P");
m_Shortcuts[ResetShortcut] = UIKeySequence("Reset", "R");
#ifdef Q_WS_MAC
@@ -43,6 +39,11 @@ UIMachineShortcuts::UIMachineShortcuts()
m_Shortcuts[ShutdownShortcut] = UIKeySequence("Shutdown", "H");
#endif /* Q_WS_MAC */
m_Shortcuts[CloseShortcut] = UIKeySequence("Close", "Q");
+ m_Shortcuts[FullscreenModeShortcut] = UIKeySequence("FullscreenMode", "F");
+ m_Shortcuts[SeamlessModeShortcut] = UIKeySequence("SeamlessMode", "L");
+ m_Shortcuts[ScaleModeShortcut] = UIKeySequence("ScaleMode", "C");
+ m_Shortcuts[GuestAutoresizeShortcut] = UIKeySequence("GuestAutoresize", "G");
+ m_Shortcuts[WindowAdjustShortcut] = UIKeySequence("WindowAdjust", "A");
m_Shortcuts[NetworkAdaptersDialogShortcut] = UIKeySequence("NetworkAdaptersDialog");
m_Shortcuts[SharedFoldersDialogShortcut] = UIKeySequence("SharedFoldersDialog");
m_Shortcuts[VRDPServerShortcut] = UIKeySequence("VRDPServer");
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineShortcuts.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineShortcuts.h
index 8258ecb39..8a6fd96d0 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineShortcuts.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineShortcuts.h
@@ -27,20 +27,21 @@ class UIMachineShortcuts: public UIShortcuts<UIMachineShortcuts>
public:
enum MachineShortcutType
{
- FullscreenModeShortcut,
- SeamlessModeShortcut,
- ScaleModeShortcut,
- GuestAutoresizeShortcut,
- WindowAdjustShortcut,
+ SettingsDialogShortcut,
+ TakeSnapshotShortcut,
+ InformationDialogShortcut,
MouseIntegrationShortcut,
TypeCADShortcut,
TypeCABSShortcut,
- TakeSnapshotShortcut,
- InformationDialogShortcut,
PauseShortcut,
ResetShortcut,
ShutdownShortcut,
CloseShortcut,
+ FullscreenModeShortcut,
+ SeamlessModeShortcut,
+ ScaleModeShortcut,
+ GuestAutoresizeShortcut,
+ WindowAdjustShortcut,
NetworkAdaptersDialogShortcut,
SharedFoldersDialogShortcut,
VRDPServerShortcut,
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
index f009fa142..12c7fcb17 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineView.cpp $ */
+/* $Id: UIMachineView.cpp 35247 2010-12-20 14:19:48Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp
index e72c70f99..6d9112420 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineWindow.cpp $ */
+/* $Id: UIMachineWindow.cpp 36127 2011-03-01 21:08:09Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp
index c0ea8aa4f..1efad8108 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMouseHandler.cpp $ */
+/* $Id: UIMouseHandler.cpp 36374 2011-03-23 16:37:03Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -32,6 +32,10 @@
#include "UIMachineView.h"
#include "UIFrameBuffer.h"
+#ifdef Q_WS_WIN
+# include "VBoxUtils-win.h"
+#endif /* Q_WS_WIN */
+
#ifdef Q_WS_X11
# include <X11/XKBlib.h>
# ifdef KeyPress
@@ -700,14 +704,11 @@ bool UIMouseHandler::mouseEvent(int iEventType, ulong uScreenId,
#ifdef Q_WS_WIN
/* Bringing mouse to the opposite side to simulate the endless moving: */
- /* Acquiring visible viewport rectangle in local coordinates: */
- QRect viewportRectangle = m_viewports[uScreenId]->visibleRegion().boundingRect();
+ /* Get visible-viewport-rectangle in global coordinates: */
+ QRect viewportRectangle = m_mouseCursorClippingRect;
+ /* Get top-left point of full-viewport-rectangle in global coordinates: */
QPoint viewportRectangleGlobalPos = m_views[uScreenId]->mapToGlobal(m_viewports[uScreenId]->pos());
- /* Shift viewport rectangle to global position to bound by available geometry: */
- viewportRectangle.translate(viewportRectangleGlobalPos);
- /* Acquiring viewport rectangle cropped by available geometry: */
- viewportRectangle = viewportRectangle.intersected(QApplication::desktop()->availableGeometry());
- /* Shift remaining viewport rectangle to local position as relative position is in local coordinates: */
+ /* Shift visible-viewport-rectangle to local position because relative position is in local coordinates: */
viewportRectangle.translate(-viewportRectangleGlobalPos);
/* Get boundaries: */
@@ -881,13 +882,35 @@ void UIMouseHandler::updateMouseCursorClipping()
if (uisession()->isMouseCaptured())
{
- /* Acquiring visible viewport rectangle: */
+ /* Get full-viewport-rectangle in local coordinates: */
QRect viewportRectangle = m_viewports[m_iMouseCaptureViewIndex]->visibleRegion().boundingRect();
+ /* Get top-left point of full-viewport-rectangle in global coordinates: */
QPoint viewportRectangleGlobalPos = m_views[m_iMouseCaptureViewIndex]->mapToGlobal(m_viewports[m_iMouseCaptureViewIndex]->pos());
+ /* Get full-viewport-rectangle in global coordinates: */
viewportRectangle.translate(viewportRectangleGlobalPos);
+ /* Trim full-viewport-rectangle by available geometry: */
viewportRectangle = viewportRectangle.intersected(QApplication::desktop()->availableGeometry());
+ /* Trim partial-viewport-rectangle by top-most windows: */
+ QRegion viewportRegion(viewportRectangle);
+ QRegion topMostRegion(NativeWindowSubsystem::areaCoveredByTopMostWindows());
+ viewportRegion -= topMostRegion;
+ /* Check if partial-viewport-region consists of 1 rectangle: */
+ if (viewportRegion.rectCount() > 1)
+ {
+ /* Choose the largest rectangle: */
+ QVector<QRect> rects = viewportRegion.rects();
+ QRect largestRect;
+ for (int i = 0; i < rects.size(); ++i)
+ largestRect = largestRect.width() * largestRect.height() < rects[i].width() * rects[i].height() ? rects[i] : largestRect;
+ /* Assign the partial-viewport-region to the largest rect: */
+ viewportRegion = largestRect;
+ }
+ /* Assign the partial-viewport-rectangle to the partial-viewport-region: */
+ viewportRectangle = viewportRegion.boundingRect();
+ /* Assign the visible-viewport-rectangle to the partial-viewport-rectangle: */
+ m_mouseCursorClippingRect = viewportRectangle;
/* Prepare clipping area: */
- RECT rect = { viewportRectangle.left() + 1, viewportRectangle.top() + 1, viewportRectangle.right(), viewportRectangle.bottom() };
+ RECT rect = { m_mouseCursorClippingRect.left() + 1, m_mouseCursorClippingRect.top() + 1, m_mouseCursorClippingRect.right(), m_mouseCursorClippingRect.bottom() };
::ClipCursor(&rect);
}
else
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.h
index e1da9bde0..2b56c6c59 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.h
@@ -23,6 +23,7 @@
#include <QObject>
#include <QPoint>
#include <QMap>
+#include <QRect>
/* Local includes */
#include "UIMachineDefs.h"
@@ -109,6 +110,7 @@ protected:
/* This method is actually required only because under win-host
* we do not really grab the mouse in case of capturing it: */
void updateMouseCursorClipping();
+ QRect m_mouseCursorClippingRect;
#endif /* Q_WS_WIN */
/* Machine logic parent: */
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.cpp
index 3f5c9330c..2515db965 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMultiScreenLayout.cpp $ */
+/* $Id: UIMultiScreenLayout.cpp 36083 2011-02-25 12:33:58Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -48,25 +48,33 @@ UIMultiScreenLayout::UIMultiScreenLayout(UIMachineLogic *pMachineLogic)
UIMultiScreenLayout::~UIMultiScreenLayout()
{
delete m_pScreenMap;
+ while (!m_screenMenuList.isEmpty())
+ {
+ delete m_screenMenuList.first();
+ m_screenMenuList.removeFirst();
+ }
}
void UIMultiScreenLayout::initialize(QMenu *pMenu)
{
- pMenu->clear();
- for (int i = 0; i < m_cGuestScreens; ++i)
+ if (m_cHostScreens > 1)
{
- QMenu *pScreenMenu = pMenu->addMenu(tr("Virtual Screen %1").arg(i + 1));
- QActionGroup *pScreenGroup = new QActionGroup(pScreenMenu);
- pScreenGroup->setExclusive(true);
- connect(pScreenGroup, SIGNAL(triggered(QAction*)),
- this, SLOT(sltScreenLayoutChanged(QAction*)));
- for (int a = 0; a < m_cHostScreens; ++a)
+ pMenu->addSeparator();
+ for (int i = 0; i < m_cGuestScreens; ++i)
{
- QAction *pAction = pScreenGroup->addAction(tr("Use Host Screen %1").arg(a + 1));
- pAction->setCheckable(true);
- pAction->setData(RT_MAKE_U32(i, a));
+ m_screenMenuList << pMenu->addMenu(tr("Virtual Screen %1").arg(i + 1));
+ m_screenMenuList.last()->menuAction()->setData(true);
+ QActionGroup *pScreenGroup = new QActionGroup(m_screenMenuList.last());
+ pScreenGroup->setExclusive(true);
+ connect(pScreenGroup, SIGNAL(triggered(QAction*)), this, SLOT(sltScreenLayoutChanged(QAction*)));
+ for (int a = 0; a < m_cHostScreens; ++a)
+ {
+ QAction *pAction = pScreenGroup->addAction(tr("Use Host Screen %1").arg(a + 1));
+ pAction->setCheckable(true);
+ pAction->setData(RT_MAKE_U32(i, a));
+ }
+ m_screenMenuList.last()->addActions(pScreenGroup->actions());
}
- pScreenMenu->addActions(pScreenGroup->actions());
}
}
@@ -83,8 +91,7 @@ void UIMultiScreenLayout::update()
QDesktopWidget *pDW = QApplication::desktop();
for (int i = 0; i < m_cGuestScreens; ++i)
{
- /* If the user ever selected a combination in the view menu, we have
- * the following entry: */
+ /* If the user ever selected a combination in the view menu, we have the following entry: */
QString strTest = machine.GetExtraData(QString("%1%2").arg(VBoxDefs::GUI_VirtualScreenToHostScreen).arg(i));
bool fOk;
int cScreen = strTest.toInt(&fOk);
@@ -126,16 +133,25 @@ void UIMultiScreenLayout::update()
availableScreens.removeOne(cScreen);
}
- QList<QAction*> actions = m_pMachineLogic->actionsPool()->action(UIActionIndex_Menu_View)->menu()->actions();
- for (int i = 0; i < m_pScreenMap->size(); ++i)
+ /* Get the list of all view-menu actions: */
+ QList<QAction*> viewMenuActions = m_pMachineLogic->actionsPool()->action(UIActionIndex_Menu_View)->menu()->actions();
+ /* Get the list of all view related actions: */
+ QList<QAction*> viewActions;
+ for (int i = 0; i < viewMenuActions.size(); ++i)
{
- int hostScreen = m_pScreenMap->value(i);
- QList<QAction*> actions1 = actions.at(i)->menu()->actions();
- for (int w = 0; w < actions1.size(); ++w)
+ if (viewMenuActions[i]->data().toBool())
+ viewActions << viewMenuActions[i];
+ }
+ /* Mark currently chosen action: */
+ for (int i = 0; i < viewActions.size(); ++i)
+ {
+ int iHostScreen = m_pScreenMap->value(i);
+ QList<QAction*> screenActions = viewActions.at(i)->menu()->actions();
+ for (int w = 0; w < screenActions.size(); ++w)
{
- QAction *pTmpAction = actions1.at(w);
+ QAction *pTmpAction = screenActions.at(w);
pTmpAction->blockSignals(true);
- pTmpAction->setChecked(RT_HIWORD(pTmpAction->data().toInt()) == hostScreen);
+ pTmpAction->setChecked(RT_HIWORD(pTmpAction->data().toInt()) == iHostScreen);
pTmpAction->blockSignals(false);
}
}
@@ -221,20 +237,26 @@ void UIMultiScreenLayout::sltScreenLayoutChanged(QAction *pAction)
m_pScreenMap = pTmpMap;
}
- /* Update the menu items. Even if we can't switch we have to revert the
- * menu items. */
- QList<QAction*> actions = m_pMachineLogic->actionsPool()->action(UIActionIndex_Menu_View)->menu()->actions();
- /* Update the settings. */
- for (int i = 0; i < m_cGuestScreens; ++i)
+ /* Get the list of all view-menu actions: */
+ QList<QAction*> viewMenuActions = m_pMachineLogic->actionsPool()->action(UIActionIndex_Menu_View)->menu()->actions();
+ /* Get the list of all view related actions: */
+ QList<QAction*> viewActions;
+ for (int i = 0; i < viewMenuActions.size(); ++i)
{
- int hostScreen = m_pScreenMap->value(i);
- machine.SetExtraData(QString("%1%2").arg(VBoxDefs::GUI_VirtualScreenToHostScreen).arg(i), QString::number(hostScreen));
- QList<QAction*> actions1 = actions.at(i)->menu()->actions();
- for (int w = 0; w < actions1.size(); ++w)
+ if (viewMenuActions[i]->data().toBool())
+ viewActions << viewMenuActions[i];
+ }
+ /* Update the menu items. Even if we can't switch we have to revert the menu items. */
+ for (int i = 0; i < viewActions.size(); ++i)
+ {
+ int iHostScreen = m_pScreenMap->value(i);
+ machine.SetExtraData(QString("%1%2").arg(VBoxDefs::GUI_VirtualScreenToHostScreen).arg(i), QString::number(iHostScreen));
+ QList<QAction*> screenActions = viewActions.at(i)->menu()->actions();
+ for (int w = 0; w < screenActions.size(); ++w)
{
- QAction *pTmpAction = actions1.at(w);
+ QAction *pTmpAction = screenActions.at(w);
pTmpAction->blockSignals(true);
- pTmpAction->setChecked(RT_HIWORD(pTmpAction->data().toInt()) == hostScreen);
+ pTmpAction->setChecked(RT_HIWORD(pTmpAction->data().toInt()) == iHostScreen);
pTmpAction->blockSignals(false);
}
}
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.h
index e549631ac..c841e23b9 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.h
@@ -62,6 +62,7 @@ private:
int m_cHostScreens;
QMap<int, int> *m_pScreenMap;
+ QList<QMenu*> m_screenMenuList;
};
#endif /* __UIMultiScreenLayout_h__ */
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
index f38052031..5d74af06d 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
@@ -1,4 +1,4 @@
-/* $Id: UISession.cpp $ */
+/* $Id: UISession.cpp 37712 2011-06-30 14:11:14Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 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;
@@ -109,6 +109,9 @@ UISession::UISession(UIMachine *pMachine, CSession &sessionReference)
connect(gConsoleEvents, SIGNAL(sigAdditionsChange()),
this, SLOT(sltAdditionsChange()));
+ connect(gConsoleEvents, SIGNAL(sigVRDEChange()),
+ this, SLOT(sltVRDEChange()));
+
connect(gConsoleEvents, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)),
this, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)));
@@ -133,6 +136,9 @@ UISession::UISession(UIMachine *pMachine, CSession &sessionReference)
Qt::QueuedConnection);
#endif /* Q_WS_MAC */
+ connect(gConsoleEvents, SIGNAL(sigCPUExecutionCapChange()),
+ this, SIGNAL(sigCPUExecutionCapChange()));
+
/* Prepare main menu: */
prepareMenuPool();
@@ -422,7 +428,7 @@ void UISession::sltInstallGuestAdditionsFrom(const QString &strSource)
CMedium image = vbox.FindMedium(strSource, KDeviceType_DVD);
if (image.isNull())
{
- image = vbox.OpenMedium(strSource, KDeviceType_DVD, KAccessMode_ReadWrite);
+ image = vbox.OpenMedium(strSource, KDeviceType_DVD, KAccessMode_ReadWrite, false /* fForceNewUuid */);
if (vbox.isOk())
strUuid = image.GetId();
}
@@ -602,6 +608,22 @@ void UISession::sltStateChange(KMachineState state)
}
}
+void UISession::sltVRDEChange()
+{
+ /* Get machine: */
+ const CMachine &machine = session().GetMachine();
+ /* Get VRDE server: */
+ const CVRDEServer &server = machine.GetVRDEServer();
+ bool fIsVRDEServerAvailable = !server.isNull();
+ /* Show/Hide VRDE action depending on VRDE server availability status: */
+ uimachine()->actionsPool()->action(UIActionIndex_Toggle_VRDEServer)->setVisible(fIsVRDEServerAvailable);
+ /* Check/Uncheck VRDE action depending on VRDE server activity status: */
+ if (fIsVRDEServerAvailable)
+ uimachine()->actionsPool()->action(UIActionIndex_Toggle_VRDEServer)->setChecked(server.GetEnabled());
+ /* Notify listeners about VRDE change: */
+ emit sigVRDEChange();
+}
+
void UISession::sltAdditionsChange()
{
/* Get our guest: */
@@ -609,9 +631,11 @@ void UISession::sltAdditionsChange()
/* Variable flags: */
ULONG ulGuestAdditionsRunLevel = guest.GetAdditionsRunLevel();
- bool fIsGuestSupportsGraphics = guest.GetSupportsGraphics();
- bool fIsGuestSupportsSeamless = guest.GetSupportsSeamless();
-
+ LONG64 lLastUpdatedIgnored;
+ bool fIsGuestSupportsGraphics = guest.GetFacilityStatus(KAdditionsFacilityType_Graphics, lLastUpdatedIgnored)
+ == KAdditionsFacilityStatus_Active;
+ bool fIsGuestSupportsSeamless = guest.GetFacilityStatus(KAdditionsFacilityType_Seamless, lLastUpdatedIgnored)
+ == KAdditionsFacilityStatus_Active;
/* Check if something had changed: */
if (m_ulGuestAdditionsRunLevel != ulGuestAdditionsRunLevel ||
m_fIsGuestSupportsGraphics != fIsGuestSupportsGraphics ||
@@ -964,22 +988,10 @@ void UISession::reinitMenuPool()
pFloppyDevicesMenu->setVisible(iDevicesCountFD);
}
- /* VRDE stuff: */
- {
- /* Get VRDE server: */
- CVRDEServer server = machine.GetVRDEServer();
- bool fIsVRDEServerAvailable = !server.isNull();
- /* Show/Hide VRDE action depending on VRDE server availability status: */
- uimachine()->actionsPool()->action(UIActionIndex_Toggle_VRDEServer)->setVisible(fIsVRDEServerAvailable);
- /* Check/Uncheck VRDE action depending on VRDE server activity status: */
- if (fIsVRDEServerAvailable)
- uimachine()->actionsPool()->action(UIActionIndex_Toggle_VRDEServer)->setChecked(server.GetEnabled());
- }
-
/* Network stuff: */
{
bool fAtLeastOneAdapterActive = false;
- ULONG uSlots = vboxGlobal().virtualBox().GetSystemProperties().GetNetworkAdapterCount();
+ ULONG uSlots = vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3);
for (ULONG uSlot = 0; uSlot < uSlots; ++uSlot)
{
const CNetworkAdapter &adapter = machine.GetNetworkAdapter(uSlot);
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h
index 66df05193..0645eeed1 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h
@@ -167,6 +167,7 @@ signals:
void sigAdditionsStateChange();
void sigNetworkAdapterChange(const CNetworkAdapter &networkAdapter);
void sigMediumChange(const CMediumAttachment &mediumAttachment);
+ void sigVRDEChange();
void sigUSBControllerChange();
void sigUSBDeviceStateChange(const CUSBDevice &device, bool bIsAttached, const CVirtualBoxErrorInfo &error);
void sigSharedFolderChange();
@@ -174,6 +175,7 @@ signals:
#ifdef RT_OS_DARWIN
void sigShowWindows();
#endif /* RT_OS_DARWIN */
+ void sigCPUExecutionCapChange();
/* Session signals: */
void sigMachineStarted();
@@ -193,6 +195,7 @@ private slots:
void sltKeyboardLedsChangeEvent(bool fNumLock, bool fCapsLock, bool fScrollLock);
void sltStateChange(KMachineState state);
void sltAdditionsChange();
+ void sltVRDEChange();
private:
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIVMCloseDialog.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIVMCloseDialog.cpp
index c4bc5d5fc..8604c9715 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIVMCloseDialog.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIVMCloseDialog.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIVMCloseDialog.cpp $ */
+/* $Id: UIVMCloseDialog.cpp 32483 2010-09-14 13:45:07Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIKeyboardHandlerFullscreen.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIKeyboardHandlerFullscreen.cpp
index d21199c6e..66e4db31d 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIKeyboardHandlerFullscreen.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIKeyboardHandlerFullscreen.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIKeyboardHandlerFullscreen.cpp $ */
+/* $Id: UIKeyboardHandlerFullscreen.cpp 35752 2011-01-28 10:57:53Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp
index f0a41800f..a1f613d04 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineLogicFullscreen.cpp $ */
+/* $Id: UIMachineLogicFullscreen.cpp 30936 2010-07-20 16:59:35Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.cpp
index 1d9bac393..93b4919cf 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineViewFullscreen.cpp $ */
+/* $Id: UIMachineViewFullscreen.cpp 32174 2010-09-01 12:52:17Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp
index 84ea7adab..f84a9190e 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineWindowFullscreen.cpp $ */
+/* $Id: UIMachineWindowFullscreen.cpp 36083 2011-02-25 12:33:58Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -165,14 +165,10 @@ void UIMachineWindowFullscreen::closeEvent(QCloseEvent *pEvent)
void UIMachineWindowFullscreen::prepareMenu()
{
- UIMainMenuType fMenus = UIMainMenuType_All;
- /* Remove the view menu in the case there is one screen only. */
- if (QApplication::desktop()->numScreens() == 1)
- fMenus = UIMainMenuType(fMenus ^ UIMainMenuType_View);
#ifdef Q_WS_MAC
- setMenuBar(uisession()->newMenuBar(fMenus));
+ setMenuBar(uisession()->newMenuBar());
#endif /* Q_WS_MAC */
- m_pMainMenu = uisession()->newMenu(fMenus);
+ m_pMainMenu = uisession()->newMenu();
}
void UIMachineWindowFullscreen::prepareMiniToolBar()
@@ -192,10 +188,7 @@ void UIMachineWindowFullscreen::prepareMiniToolBar()
true, fIsAutoHide);
m_pMiniToolBar->updateDisplay(true, true);
QList<QMenu*> menus;
- UIMainMenuType fMenu = UIMainMenuType(UIMainMenuType_Machine | UIMainMenuType_Devices);
- if (QApplication::desktop()->numScreens() > 1)
- fMenu = UIMainMenuType(fMenu | UIMainMenuType_View);
- QList<QAction*> actions = uisession()->newMenu(fMenu)->actions();
+ QList<QAction*> actions = uisession()->newMenu()->actions();
for (int i=0; i < actions.size(); ++i)
menus << actions.at(i)->menu();
*m_pMiniToolBar << menus;
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIKeyboardHandlerNormal.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIKeyboardHandlerNormal.cpp
index 782417d88..3796e4055 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIKeyboardHandlerNormal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIKeyboardHandlerNormal.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIKeyboardHandlerNormal.cpp $ */
+/* $Id: UIKeyboardHandlerNormal.cpp 35752 2011-01-28 10:57:53Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp
index d7f55f524..2c3931525 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineLogicNormal.cpp $ */
+/* $Id: UIMachineLogicNormal.cpp 30936 2010-07-20 16:59:35Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp
index b210fd4a9..6bfc29cec 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineViewNormal.cpp $ */
+/* $Id: UIMachineViewNormal.cpp 37148 2011-05-19 09:19:53Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp
index 37ab0d960..c0ed06740 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineWindowNormal.cpp $ */
+/* $Id: UIMachineWindowNormal.cpp 37712 2011-06-30 14:11:14Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -157,6 +157,11 @@ void UIMachineWindowNormal::sltSharedFolderChange()
updateAppearanceOf(UIVisualElement_SharedFolderStuff);
}
+void UIMachineWindowNormal::sltCPUExecutionCapChange()
+{
+ updateAppearanceOf(UIVisualElement_VirtualizationStuff);
+}
+
void UIMachineWindowNormal::sltTryClose()
{
UIMachineWindow::sltTryClose();
@@ -371,12 +376,16 @@ void UIMachineWindowNormal::prepareConsoleConnections()
/* Shared folder change updater: */
connect(machineLogic()->uisession(), SIGNAL(sigSharedFolderChange()),
this, SLOT(sltSharedFolderChange()));
+
+ /* CPU execution cap change updater: */
+ connect(machineLogic()->uisession(), SIGNAL(sigCPUExecutionCapChange()),
+ this, SLOT(sltCPUExecutionCapChange()));
+
}
void UIMachineWindowNormal::prepareMenu()
{
- /* No view menu in normal mode */
- setMenuBar(uisession()->newMenuBar(UIMainMenuType(UIMainMenuType_All ^ UIMainMenuType_View)));
+ setMenuBar(uisession()->newMenuBar());
}
void UIMachineWindowNormal::prepareStatusBar()
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h
index 767c13d0d..39be14cdf 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h
@@ -51,6 +51,7 @@ private slots:
void sltUSBDeviceStateChange();
void sltNetworkAdapterChange();
void sltSharedFolderChange();
+ void sltCPUExecutionCapChange();
/* LED connections: */
void sltUpdateIndicators();
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIKeyboardHandlerScale.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIKeyboardHandlerScale.cpp
index 3b6290221..4356e604d 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIKeyboardHandlerScale.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIKeyboardHandlerScale.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIKeyboardHandlerScale.cpp $ */
+/* $Id: UIKeyboardHandlerScale.cpp 35752 2011-01-28 10:57:53Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineLogicScale.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineLogicScale.cpp
index 181d1ef99..9f43c2b3f 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineLogicScale.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineLogicScale.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineLogicScale.cpp $ */
+/* $Id: UIMachineLogicScale.cpp 34984 2010-12-13 10:29:58Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineViewScale.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineViewScale.cpp
index 460f6fc06..5dc242f2a 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineViewScale.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineViewScale.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineViewScale.cpp $ */
+/* $Id: UIMachineViewScale.cpp 33595 2010-10-29 10:35:00Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp
index 700bc9e98..4dedbaa3a 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineWindowScale.cpp $ */
+/* $Id: UIMachineWindowScale.cpp 36083 2011-02-25 12:33:58Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -229,12 +229,10 @@ void UIMachineWindowScale::closeEvent(QCloseEvent *pEvent)
void UIMachineWindowScale::prepareMenu()
{
- UIMainMenuType fMenus = UIMainMenuType(UIMainMenuType_All ^ UIMainMenuType_View);
#ifdef Q_WS_MAC
- setMenuBar(uisession()->newMenuBar(fMenus));
+ setMenuBar(uisession()->newMenuBar());
#endif /* Q_WS_MAC */
- /* No view menu in normal mode: */
- m_pMainMenu = uisession()->newMenu(fMenus);
+ m_pMainMenu = uisession()->newMenu();
}
void UIMachineWindowScale::prepareMachineViewContainer()
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIKeyboardHandlerSeamless.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIKeyboardHandlerSeamless.cpp
index 46bfd7e02..c5228ca38 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIKeyboardHandlerSeamless.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIKeyboardHandlerSeamless.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIKeyboardHandlerSeamless.cpp $ */
+/* $Id: UIKeyboardHandlerSeamless.cpp 35752 2011-01-28 10:57:53Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp
index 17e242835..e577cf1bd 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineLogicSeamless.cpp $ */
+/* $Id: UIMachineLogicSeamless.cpp 30936 2010-07-20 16:59:35Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp
index 529a33772..7e732253c 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineViewSeamless.cpp $ */
+/* $Id: UIMachineViewSeamless.cpp 32174 2010-09-01 12:52:17Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp
index 344c6f6e9..5c7755768 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineWindowSeamless.cpp $ */
+/* $Id: UIMachineWindowSeamless.cpp 36083 2011-02-25 12:33:58Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -214,14 +214,10 @@ void UIMachineWindowSeamless::prepareSeamless()
void UIMachineWindowSeamless::prepareMenu()
{
- UIMainMenuType fMenus = UIMainMenuType_All;
- /* Remove the view menu in the case there is one screen only. */
- if (QApplication::desktop()->numScreens() == 1)
- fMenus = UIMainMenuType(fMenus ^ UIMainMenuType_View);
#ifdef Q_WS_MAC
- setMenuBar(uisession()->newMenuBar(fMenus));
+ setMenuBar(uisession()->newMenuBar());
#endif /* Q_WS_MAC */
- m_pMainMenu = uisession()->newMenu(fMenus);
+ m_pMainMenu = uisession()->newMenu();
}
#ifndef Q_WS_MAC
@@ -243,10 +239,7 @@ void UIMachineWindowSeamless::prepareMiniToolBar()
m_pMiniToolBar->setSeamlessMode(true);
m_pMiniToolBar->updateDisplay(true, true);
QList<QMenu*> menus;
- UIMainMenuType fMenu = UIMainMenuType(UIMainMenuType_Machine | UIMainMenuType_Devices);
- if (QApplication::desktop()->numScreens() > 1)
- fMenu = UIMainMenuType(fMenu | UIMainMenuType_View);
- QList<QAction*> actions = uisession()->newMenu(fMenu)->actions();
+ QList<QAction*> actions = uisession()->newMenu()->actions();
for (int i=0; i < actions.size(); ++i)
menus << actions.at(i)->menu();
*m_pMiniToolBar << menus;
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.cpp b/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.cpp
index f01729fb3..fda5c78ad 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.cpp
@@ -1,4 +1,4 @@
-/* $Id: UISelectorShortcuts.cpp $ */
+/* $Id: UISelectorShortcuts.cpp 37878 2011-07-11 16:15:02Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -33,6 +33,7 @@ UISelectorShortcuts::UISelectorShortcuts()
m_Shortcuts[NewVMShortcut] = UIKeySequence("NewVM", "Ctrl+N");
m_Shortcuts[AddVMShortcut] = UIKeySequence("AddVM", "Ctrl+A");
m_Shortcuts[SettingsVMShortcut] = UIKeySequence("SettingsVM", "Ctrl+S");
+ m_Shortcuts[CloneVMShortcut] = UIKeySequence("CloneVM", "Ctrl+O");
m_Shortcuts[RemoveVMShortcut] = UIKeySequence("RemoveVM", "Ctrl+R");
m_Shortcuts[StartVMShortcut] = UIKeySequence("StartVM");
m_Shortcuts[DiscardVMShortcut] = UIKeySequence("DiscardVM", "Ctrl+J");
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.h b/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.h
index 799b8201f..88d410559 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.h
+++ b/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.h
@@ -35,6 +35,7 @@ public:
NewVMShortcut,
AddVMShortcut,
SettingsVMShortcut,
+ CloneVMShortcut,
RemoveVMShortcut,
StartVMShortcut,
DiscardVMShortcut,
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp b/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp
index a934a8c9f..8eb12e9dc 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIVMDesktop.cpp $ */
+/* $Id: UIVMDesktop.cpp 37755 2011-07-04 10:21:00Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -6,7 +6,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;
@@ -126,6 +126,7 @@ public:
m_pErrText->setText(aText);
setCurrentIndex(indexOf(m_pErrBox));
}
+
signals:
void linkClicked(const QString &aURL);
@@ -163,6 +164,8 @@ private:
void createTextPage();
void createErrPage();
+ static QString summarizeGenericProperties(const CNetworkAdapter &adapter);
+
/* Private member vars */
CVirtualBox m_vbox;
CMachine m_machine;
@@ -462,6 +465,97 @@ UIDetailsPagePrivate::~UIDetailsPagePrivate()
boxes);
}
+void UIDetailsPagePrivate::retranslateUi()
+{
+ if (m_pErrLabel)
+ m_pErrLabel->setText(tr(
+ "The selected virtual machine is <i>inaccessible</i>. Please "
+ "inspect the error message shown below and press the "
+ "<b>Refresh</b> button if you want to repeat the accessibility "
+ "check:"));
+
+ if (mRefreshAction && mRefreshButton)
+ {
+ mRefreshButton->setText(mRefreshAction->text());
+ mRefreshButton->setIcon(mRefreshAction->icon());
+ mRefreshButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ }
+
+ /* General */
+ {
+ m_secBoxes.value(GeneralSec)->setTitle(tr("General", "details report"));
+ m_actions.value(GeneralSec)->setText(m_secBoxes.value(GeneralSec)->title());
+ }
+
+ /* System */
+ {
+ m_secBoxes.value(SystemSec)->setTitle(tr("System", "details report"));
+ m_actions.value(SystemSec)->setText(m_secBoxes.value(SystemSec)->title());
+ }
+
+ /* Preview */
+ {
+ m_secBoxes.value(PreviewSec)->setTitle(tr("Preview", "details report"));
+ m_actions.value(PreviewSec)->setText(m_secBoxes.value(PreviewSec)->title());
+ }
+
+ /* Display */
+ {
+ m_secBoxes.value(DisplaySec)->setTitle(tr("Display", "details report"));
+ m_actions.value(DisplaySec)->setText(m_secBoxes.value(DisplaySec)->title());
+ }
+
+ /* Storage */
+ {
+ m_secBoxes.value(StorageSec)->setTitle(tr("Storage", "details report"));
+ m_actions.value(StorageSec)->setText(m_secBoxes.value(StorageSec)->title());
+ }
+
+ /* Audio */
+ {
+ m_secBoxes.value(AudioSec)->setTitle(tr("Audio", "details report"));
+ m_actions.value(AudioSec)->setText(m_secBoxes.value(AudioSec)->title());
+ }
+
+ /* Network */
+ {
+ m_secBoxes.value(NetworkSec)->setTitle(tr("Network", "details report"));
+ m_actions.value(NetworkSec)->setText(m_secBoxes.value(NetworkSec)->title());
+ }
+
+ /* Serial Ports */
+ {
+ m_secBoxes.value(SerialPortsSec)->setTitle(tr("Serial Ports", "details report"));
+ m_actions.value(SerialPortsSec)->setText(m_secBoxes.value(SerialPortsSec)->title());
+ }
+
+#ifdef VBOX_WITH_PARALLEL_PORTS
+ /* Parallel Ports */
+ {
+ m_secBoxes.value(ParallelPortsSec)->setTitle(tr("Parallel Ports", "details report"));
+ m_actions.value(ParallelPortsSec)->setText(m_secBoxes.value(ParallelPortsSec)->title());
+ }
+#endif /* VBOX_WITH_PARALLEL_PORTS */
+
+ /* USB */
+ {
+ m_secBoxes.value(USBSec)->setTitle(tr("USB", "details report"));
+ m_actions.value(USBSec)->setText(m_secBoxes.value(USBSec)->title());
+ }
+
+ /* Shared Folders */
+ {
+ m_secBoxes.value(SharedFoldersSec)->setTitle(tr("Shared Folders", "details report"));
+ m_actions.value(SharedFoldersSec)->setText(m_secBoxes.value(SharedFoldersSec)->title());
+ }
+
+ /* Description */
+ {
+ m_secBoxes.value(DescriptionSec)->setTitle(tr("Description", "details report"));
+ m_actions.value(DescriptionSec)->setText(m_secBoxes.value(DescriptionSec)->title());
+ }
+}
+
void UIDetailsPagePrivate::sltUpdateGeneral()
{
m_secBoxes.value(GeneralSec)->setTitleLinkEnabled(m_fChangeable);
@@ -501,6 +595,12 @@ void UIDetailsPagePrivate::sltUpdateSystem()
tr("<nobr>%1</nobr>", "details report"))
.arg(cCPU);
+ int iCPUExecCap = m_machine.GetCPUExecutionCap();
+ if (iCPUExecCap < 100)
+ item += sSectionItemTpl2.arg(tr("Execution Cap", "details report"),
+ tr("<nobr>%1%</nobr>", "details report"))
+ .arg(iCPUExecCap);
+
/* Boot order */
QStringList bootOrder;
for (ulong i = 1; i <= m_vbox.GetSystemProperties().GetMaxBootPosition(); ++i)
@@ -725,7 +825,7 @@ void UIDetailsPagePrivate::sltUpdateNetwork()
{
QString item;
- ulong count = m_vbox.GetSystemProperties().GetNetworkAdapterCount();
+ ulong count = m_vbox.GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3);
for (ulong slot = 0; slot < count; slot ++)
{
const CNetworkAdapter &adapter = m_machine.GetNetworkAdapter(slot);
@@ -739,18 +839,21 @@ void UIDetailsPagePrivate::sltUpdateNetwork()
* this name instead */
if (type == KNetworkAttachmentType_Bridged)
attType = attType.arg(tr("Bridged adapter, %1",
- "details report (network)").arg(adapter.GetHostInterface()));
+ "details report (network)").arg(adapter.GetBridgedInterface()));
else if (type == KNetworkAttachmentType_Internal)
attType = attType.arg(tr("Internal network, '%1'",
"details report (network)").arg(adapter.GetInternalNetwork()));
else if (type == KNetworkAttachmentType_HostOnly)
attType = attType.arg(tr("Host-only adapter, '%1'",
- "details report (network)").arg(adapter.GetHostInterface()));
-#ifdef VBOX_WITH_VDE
- else if (type == KNetworkAttachmentType_VDE)
- attType = attType.arg(tr("VDE network, '%1'",
- "details report (network)").arg(adapter.GetVDENetwork()));
-#endif
+ "details report (network)").arg(adapter.GetHostOnlyInterface()));
+ else if (type == KNetworkAttachmentType_Generic)
+ {
+ QString strGenericDriverProperties(summarizeGenericProperties(adapter));
+ attType = strGenericDriverProperties.isNull() ?
+ attType.arg(tr("Generic driver, '%1'", "details report (network)").arg(adapter.GetGenericDriver())) :
+ attType.arg(tr("Generic driver, '%1' {&nbsp;%2&nbsp;}", "details report (network)")
+ .arg(adapter.GetGenericDriver(), strGenericDriverProperties));
+ }
else
attType = attType.arg(vboxGlobal().toString(type));
@@ -981,14 +1084,9 @@ void UIDetailsPagePrivate::sltContextMenuRequested(const QPoint &pos)
void UIDetailsPagePrivate::setMachine(const CMachine& machine)
{
m_machine = machine;
- if (m_machine.isNull())
- m_fChangeable = false;
- else
- {
- KMachineState state = m_machine.GetState();
- bool running = m_machine.GetSessionState() != KSessionState_Unlocked;
- m_fChangeable = !running && state != KMachineState_Saved;
- }
+ m_fChangeable = m_machine.isNull() ? false :
+ m_machine.GetState() != KMachineState_Stuck &&
+ m_machine.GetState() != KMachineState_Saved /* for now! */;
sltUpdateGeneral();
sltUpdateSystem();
@@ -1074,95 +1172,23 @@ void UIDetailsPagePrivate::createErrPage()
retranslateUi();
}
-void UIDetailsPagePrivate::retranslateUi()
+/**
+ * Return a text summary of the properties of a generic network adapter
+ */
+/* static */
+QString UIDetailsPagePrivate::summarizeGenericProperties(const CNetworkAdapter &adapter)
{
- if (m_pErrLabel)
- m_pErrLabel->setText(tr(
- "The selected virtual machine is <i>inaccessible</i>. Please "
- "inspect the error message shown below and press the "
- "<b>Refresh</b> button if you want to repeat the accessibility "
- "check:"));
-
- if (mRefreshAction && mRefreshButton)
- {
- mRefreshButton->setText(mRefreshAction->text());
- mRefreshButton->setIcon(mRefreshAction->icon());
- mRefreshButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
- }
-
- /* General */
- {
- m_secBoxes.value(GeneralSec)->setTitle(tr("General", "details report"));
- m_actions.value(GeneralSec)->setText(m_secBoxes.value(GeneralSec)->title());
- }
-
- /* System */
- {
- m_secBoxes.value(SystemSec)->setTitle(tr("System", "details report"));
- m_actions.value(SystemSec)->setText(m_secBoxes.value(SystemSec)->title());
- }
-
- /* Preview */
- {
- m_secBoxes.value(PreviewSec)->setTitle(tr("Preview", "details report"));
- m_actions.value(PreviewSec)->setText(m_secBoxes.value(PreviewSec)->title());
- }
-
- /* Display */
- {
- m_secBoxes.value(DisplaySec)->setTitle(tr("Display", "details report"));
- m_actions.value(DisplaySec)->setText(m_secBoxes.value(DisplaySec)->title());
- }
-
- /* Storage */
+ QVector<QString> names;
+ QVector<QString> props;
+ props = adapter.GetProperties(QString(), names);
+ QString strResult;
+ for (int i = 0; i < names.size(); ++i)
{
- m_secBoxes.value(StorageSec)->setTitle(tr("Storage", "details report"));
- m_actions.value(StorageSec)->setText(m_secBoxes.value(StorageSec)->title());
- }
-
- /* Audio */
- {
- m_secBoxes.value(AudioSec)->setTitle(tr("Audio", "details report"));
- m_actions.value(AudioSec)->setText(m_secBoxes.value(AudioSec)->title());
- }
-
- /* Network */
- {
- m_secBoxes.value(NetworkSec)->setTitle(tr("Network", "details report"));
- m_actions.value(NetworkSec)->setText(m_secBoxes.value(NetworkSec)->title());
- }
-
- /* Serial Ports */
- {
- m_secBoxes.value(SerialPortsSec)->setTitle(tr("Serial Ports", "details report"));
- m_actions.value(SerialPortsSec)->setText(m_secBoxes.value(SerialPortsSec)->title());
- }
-
-#ifdef VBOX_WITH_PARALLEL_PORTS
- /* Parallel Ports */
- {
- m_secBoxes.value(ParallelPortsSec)->setTitle(tr("Parallel Ports", "details report"));
- m_actions.value(ParallelPortsSec)->setText(m_secBoxes.value(ParallelPortsSec)->title());
- }
-#endif /* VBOX_WITH_PARALLEL_PORTS */
-
- /* USB */
- {
- m_secBoxes.value(USBSec)->setTitle(tr("USB", "details report"));
- m_actions.value(USBSec)->setText(m_secBoxes.value(USBSec)->title());
- }
-
- /* Shared Folders */
- {
- m_secBoxes.value(SharedFoldersSec)->setTitle(tr("Shared Folders", "details report"));
- m_actions.value(SharedFoldersSec)->setText(m_secBoxes.value(SharedFoldersSec)->title());
- }
-
- /* Description */
- {
- m_secBoxes.value(DescriptionSec)->setTitle(tr("Description", "details report"));
- m_actions.value(DescriptionSec)->setText(m_secBoxes.value(DescriptionSec)->title());
+ strResult += names[i] + "=" + props[i];
+ if (i < names.size() - 1)
+ strResult += ", ";
}
+ return strResult;
}
/**
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/UIVMItem.cpp b/src/VBox/Frontends/VirtualBox/src/selector/UIVMItem.cpp
index 64b9fa69d..239dcbf6f 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/UIVMItem.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/UIVMItem.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIVMItem.cpp $ */
+/* $Id: UIVMItem.cpp 34065 2010-11-15 11:34:50Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/UIVMListView.cpp b/src/VBox/Frontends/VirtualBox/src/selector/UIVMListView.cpp
index 2cdb60c67..192ad6beb 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/UIVMListView.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/UIVMListView.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIVMListView.cpp $ */
+/* $Id: UIVMListView.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -598,7 +598,7 @@ QPixmap UIVMListView::dragPixmap(const QModelIndex &index) const
p.setPen(Qt::white);
p.setFont(font());
p.drawText(QRect(margin, margin + osTypeSize.height() + space, s.width() - 2 * margin, nameSize.height()), Qt::AlignCenter, name);
- /* Transparent icons are not supported on all platforms. */
+ /* Transparent icons are not supported on all platforms. */
#if defined(Q_WS_MAC) || defined(Q_WS_WIN)
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.fillRect(image.rect(), QColor(0, 0, 0, 177));
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/UIVMPreviewWindow.cpp b/src/VBox/Frontends/VirtualBox/src/selector/UIVMPreviewWindow.cpp
index de9f554d1..4c7774f0e 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/UIVMPreviewWindow.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/UIVMPreviewWindow.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIVMPreviewWindow.cpp $ */
+/* $Id: UIVMPreviewWindow.cpp 35798 2011-01-31 18:09:28Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/UIVirtualBoxEventHandler.cpp b/src/VBox/Frontends/VirtualBox/src/selector/UIVirtualBoxEventHandler.cpp
index c3a5e6ffb..f284021a5 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/UIVirtualBoxEventHandler.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/UIVirtualBoxEventHandler.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIVirtualBoxEventHandler.cpp $ */
+/* $Id: UIVirtualBoxEventHandler.cpp 35722 2011-01-26 16:37:16Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -51,7 +51,9 @@ UIVirtualBoxEventHandler::UIVirtualBoxEventHandler()
{
// RTPrintf("Self add: %RTthrd\n", RTThreadSelf());
const CVirtualBox &vbox = vboxGlobal().virtualBox();
- UIMainEventListenerImpl *pListener = new UIMainEventListenerImpl(this);
+ ComObjPtr<UIMainEventListenerImpl> pListener;
+ pListener.createObject();
+ pListener->init(new UIMainEventListener(), this);
m_mainEventListener = CEventListener(pListener);
QVector<KVBoxEventType> events;
events
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp
index e240da2eb..56b33b55a 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp
@@ -5,7 +5,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;
@@ -25,6 +25,7 @@
#include "UIExportApplianceWzd.h"
#include "UIIconPool.h"
#include "UIImportApplianceWzd.h"
+#include "UICloneVMWizard.h"
#include "UINewVMWzd.h"
#include "UIVMDesktop.h"
#include "UIVMListView.h"
@@ -140,6 +141,9 @@ VBoxSelectorWnd(VBoxSelectorWnd **aSelf, QWidget* aParent,
QSize(32, 32), QSize(16, 16),
":/vm_settings_32px.png", ":/settings_16px.png",
":/vm_settings_disabled_32px.png", ":/settings_dis_16px.png"));
+ mVmCloneAction = new QAction(this);
+ mVmCloneAction->setIcon(UIIconPool::iconSet(
+ ":/vm_clone_16px.png", ":/vm_clone_disabled_16px.png"));
mVmDeleteAction = new QAction(this);
mVmDeleteAction->setIcon(UIIconPool::iconSetFull(
QSize(32, 32), QSize(16, 16),
@@ -287,6 +291,7 @@ VBoxSelectorWnd(VBoxSelectorWnd **aSelf, QWidget* aParent,
mVMMenu->addAction(mVmNewAction);
mVMMenu->addAction(mVmAddAction);
mVMMenu->addAction(mVmConfigAction);
+ mVMMenu->addAction(mVmCloneAction);
mVMMenu->addAction(mVmDeleteAction);
mVMMenu->addSeparator();
mVMMenu->addAction(mVmStartAction);
@@ -305,6 +310,7 @@ VBoxSelectorWnd(VBoxSelectorWnd **aSelf, QWidget* aParent,
mVMCtxtMenu = new QMenu(this);
mVMCtxtMenu->addAction(mVmConfigAction);
+ mVMCtxtMenu->addAction(mVmCloneAction);
mVMCtxtMenu->addAction(mVmDeleteAction);
mVMCtxtMenu->addSeparator();
mVMCtxtMenu->addAction(mVmStartAction);
@@ -434,6 +440,7 @@ VBoxSelectorWnd(VBoxSelectorWnd **aSelf, QWidget* aParent,
connect(mVmAddAction, SIGNAL(triggered()), this, SLOT(vmAdd()));
connect(mVmConfigAction, SIGNAL(triggered()), this, SLOT(vmSettings()));
+ connect(mVmCloneAction, SIGNAL(triggered()), this, SLOT(vmClone()));
connect(mVmDeleteAction, SIGNAL(triggered()), this, SLOT(vmDelete()));
connect(mVmStartAction, SIGNAL(triggered()), this, SLOT(vmStart()));
connect(mVmDiscardAction, SIGNAL(triggered()), this, SLOT(vmDiscard()));
@@ -591,16 +598,18 @@ void VBoxSelectorWnd::fileExportAppliance()
void VBoxSelectorWnd::fileSettings()
{
- VBoxGlobalSettings settings = vboxGlobal().settings();
- CSystemProperties props = vboxGlobal().virtualBox().GetSystemProperties();
-
- UISettingsDialog *dlg = new UIGLSettingsDlg(this);
- dlg->getFrom();
+ /* Check that we do NOT handling that already: */
+ if (mFileSettingsAction->data().toBool())
+ return;
+ /* Remember that we handling that already: */
+ mFileSettingsAction->setData(true);
- if (dlg->exec() == QDialog::Accepted)
- dlg->putBackTo();
+ /* Create and execute global settings dialog: */
+ UISettingsDialogGlobal dlg(this);
+ dlg.execute();
- delete dlg;
+ /* Remember that we do NOT handling that already: */
+ mFileSettingsAction->setData(false);
}
void VBoxSelectorWnd::fileExit()
@@ -696,22 +705,30 @@ void VBoxSelectorWnd::vmAdd(const QString &strFile /* = "" */)
/**
* Opens the VM settings dialog.
*/
-void VBoxSelectorWnd::vmSettings(const QString &aCategory /* = QString::null */,
- const QString &aControl /* = QString::null */,
- const QString &aUuid /* = QString::null */)
+void VBoxSelectorWnd::vmSettings(const QString &strCategoryRef /* = QString::null */,
+ const QString &strControlRef /* = QString::null */,
+ const QString &strMachineId /* = QString::null */)
{
- if (!aCategory.isEmpty() && aCategory [0] != '#')
+ /* Check that we do NOT handling that already: */
+ if (mVmConfigAction->data().toBool())
+ return;
+ /* Remember that we handling that already: */
+ mVmConfigAction->setData(true);
+
+ /* Process href from VM details / description: */
+ if (!strCategoryRef.isEmpty() && strCategoryRef[0] != '#')
{
- /* Assume it's a href from the Details HTML */
- vboxGlobal().openURL(aCategory);
+ vboxGlobal().openURL(strCategoryRef);
return;
}
- QString strCategory = aCategory;
- QString strControl = aControl;
- /* Maybe the control is coded into the URL by %% */
- if (aControl == QString::null)
+
+ /* Get category and control: */
+ QString strCategory = strCategoryRef;
+ QString strControl = strControlRef;
+ /* Check if control is coded into the URL by %%: */
+ if (strControl.isEmpty())
{
- QStringList parts = aCategory.split("%%");
+ QStringList parts = strCategory.split("%%");
if (parts.size() == 2)
{
strCategory = parts.at(0);
@@ -719,44 +736,31 @@ void VBoxSelectorWnd::vmSettings(const QString &aCategory /* = QString::null */,
}
}
- UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
- mVMModel->itemById(aUuid);
-
- AssertMsgReturnVoid(item, ("Item must be always selected here"));
-
- // open a direct session to modify VM settings
- QString id = item->id();
- CSession session = vboxGlobal().openSession(id);
- if (session.isNull())
- return;
-
- CMachine m = session.GetMachine();
- AssertMsgReturn(!m.isNull(), ("Machine must not be null"), (void) 0);
-
- /* Don't show the inaccessible warning if the user open the vm settings. */
+ /* Don't show the inaccessible warning if the user tries to open VM settings: */
mDoneInaccessibleWarningOnce = true;
- UISettingsDialog *dlg = new UIVMSettingsDlg(this, m, strCategory, strControl);
- dlg->getFrom();
+ /* Get corresponding VM item: */
+ UIVMItem *pItem = strMachineId.isNull() ? mVMListView->selectedItem() : mVMModel->itemById(strMachineId);
+ AssertMsgReturnVoid(pItem, ("Item must be always selected here!\n"));
- if (dlg->exec() == QDialog::Accepted)
- {
- QString oldName = m.GetName();
- dlg->putBackTo();
+ /* Create and execute corresponding VM settings dialog: */
+ UISettingsDialogMachine dlg(this, pItem->id(), strCategory, strControl);
+ dlg.execute();
- m.SaveSettings();
- if (!m.isOk())
- vboxProblem().cannotSaveMachineSettings(m);
+ /* Remember that we do NOT handling that already: */
+ mVmConfigAction->setData(false);
+}
- /* To check use the result in future
- * vboxProblem().cannotApplyMachineSettings(m, res); */
- }
+void VBoxSelectorWnd::vmClone(const QString &aUuid /* = QString::null */)
+{
+ UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() : mVMModel->itemById(aUuid);
- delete dlg;
+ AssertMsgReturnVoid(item, ("Item must be always selected here"));
- mVMListView->setFocus();
+ CMachine machine = item->machine();
- session.UnlockMachine();
+ UICloneVMWizard wzd(this, machine, false);
+ wzd.exec();
}
void VBoxSelectorWnd::vmDelete(const QString &aUuid /* = QString::null */)
@@ -769,10 +773,6 @@ void VBoxSelectorWnd::vmDelete(const QString &aUuid /* = QString::null */)
int rc = vboxProblem().confirmMachineDeletion(machine);
if (rc != QIMessageBox::Cancel)
{
-#if defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)
- /* XXX currently disabled due to a bug in ComSafeArrayIn on 64-bit Windows hosts! */
- vboxProblem().showWin64Warning();
-#else
if (rc == QIMessageBox::Yes)
{
/* Unregister and cleanup machine's data & hard-disks: */
@@ -792,7 +792,6 @@ void VBoxSelectorWnd::vmDelete(const QString &aUuid /* = QString::null */)
vboxProblem().cannotDeleteMachine(machine);
}
else
-#endif
{
/* Just unregister machine: */
machine.Unregister(KCleanupMode_DetachAllReturnNone);
@@ -1238,13 +1237,18 @@ void VBoxSelectorWnd::retranslateUi()
mVmConfigAction->setToolTip(mVmConfigAction->text().remove('&').remove('.') +
(mVmConfigAction->shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(mVmConfigAction->shortcut().toString())));
+ mVmCloneAction->setText(tr("Cl&one..."));
+ mVmCloneAction->setShortcut(gSS->keySequence(UISelectorShortcuts::CloneVMShortcut));
+ mVmCloneAction->setStatusTip(tr("Clone the selected virtual machine"));
+
mVmDeleteAction->setText(tr("&Remove"));
mVmDeleteAction->setShortcut(gSS->keySequence(UISelectorShortcuts::RemoveVMShortcut));
mVmDeleteAction->setStatusTip(tr("Remove the selected virtual machine"));
/* Note: mVmStartAction text is set up in vmListViewCurrentChanged() */
- mVmDiscardAction->setText(tr("D&iscard"));
+ mVmDiscardAction->setIconText(tr("Discard"));
+ mVmDiscardAction->setText(tr("D&iscard Saved State"));
mVmDiscardAction->setShortcut(gSS->keySequence(UISelectorShortcuts::DiscardVMShortcut));
mVmDiscardAction->setStatusTip(
tr("Discard the saved state of the selected virtual machine"));
@@ -1332,7 +1336,7 @@ void VBoxSelectorWnd::vmListViewCurrentChanged(bool aRefreshDetails,
KMachineState state = item->machineState();
bool running = item->sessionState() != KSessionState_Unlocked;
- bool modifyEnabled = !running && state != KMachineState_Saved;
+ bool modifyEnabled = state != KMachineState_Stuck && state != KMachineState_Saved /* for now! */;
if ( aRefreshDetails
|| aRefreshDescription)
@@ -1344,6 +1348,7 @@ void VBoxSelectorWnd::vmListViewCurrentChanged(bool aRefreshDetails,
/* enable/disable modify actions */
mVmConfigAction->setEnabled(modifyEnabled);
+ mVmCloneAction->setEnabled(!running);
mVmDeleteAction->setEnabled(!running);
mVmDiscardAction->setEnabled(state == KMachineState_Saved && !running);
mVmPauseAction->setEnabled( state == KMachineState_Running
@@ -1474,6 +1479,7 @@ void VBoxSelectorWnd::vmListViewCurrentChanged(bool aRefreshDetails,
/* disable modify actions */
mVmConfigAction->setEnabled(false);
+ mVmCloneAction->setEnabled(false);
mVmDeleteAction->setEnabled(item != NULL);
mVmDiscardAction->setEnabled(false);
mVmPauseAction->setEnabled(false);
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.h b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.h
index fb76cc186..1265c722e 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.h
+++ b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.h
@@ -70,6 +70,7 @@ public slots:
void vmNew();
void vmAdd(const QString &strFile = "");
void vmSettings(const QString &aCategory = QString::null, const QString &aControl = QString::null, const QString & = QString::null);
+ void vmClone(const QString & = QString::null);
void vmDelete(const QString & = QString::null);
void vmStart(const QString & = QString::null);
void vmDiscard(const QString & = QString::null);
@@ -94,6 +95,7 @@ public slots:
const QAction *vmNewAction() const { return mVmNewAction; }
const QAction *vmAddAction() const { return mVmAddAction; }
const QAction *vmConfigAction() const { return mVmConfigAction; }
+ const QAction *vmCloneAction() const { return mVmCloneAction; }
const QAction *vmDeleteAction() const { return mVmDeleteAction; }
const QAction *vmStartAction() const { return mVmStartAction; }
const QAction *vmDiscardAction() const { return mVmDiscardAction; }
@@ -164,6 +166,7 @@ private:
QAction *mVmNewAction;
QAction *mVmAddAction;
QAction *mVmConfigAction;
+ QAction *mVmCloneAction;
QAction *mVmDeleteAction;
QAction *mVmStartAction;
QAction *mVmDiscardAction;
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp
index 16db2155d..d205c09c6 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxSnapshotsWgt.cpp $ */
+/* $Id: VBoxSnapshotsWgt.cpp 37588 2011-06-22 12:38:09Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -26,8 +26,10 @@
#include "VBoxSnapshotDetailsDlg.h"
#include "VBoxSnapshotsWgt.h"
#include "VBoxTakeSnapshotDlg.h"
+#include "UICloneVMWizard.h"
#include "UIToolBar.h"
#include "UIVirtualBoxEventHandler.h"
+#include "UISelectorShortcuts.h"
/* Global includes */
#include <QDateTime>
@@ -135,6 +137,7 @@ public:
adjustText();
}
+ CMachine machine() const { return mMachine; }
CSnapshot snapshot() const { return mSnapshot; }
QString snapshotId() const { return mId; }
@@ -329,6 +332,7 @@ VBoxSnapshotsWgt::VBoxSnapshotsWgt (QWidget *aParent)
, mDeleteSnapshotAction (new QAction (mSnapshotActionGroup))
, mShowSnapshotDetailsAction (new QAction (mSnapshotActionGroup))
, mTakeSnapshotAction (new QAction (mCurStateActionGroup))
+ , mCloneSnapshotAction(new QAction(mCurStateActionGroup))
{
/* Apply UI decorations */
Ui::VBoxSnapshotsWgt::setupUi (this);
@@ -359,6 +363,8 @@ VBoxSnapshotsWgt::VBoxSnapshotsWgt (QWidget *aParent)
toolBar->addAction (mRestoreSnapshotAction);
toolBar->addAction (mDeleteSnapshotAction);
toolBar->addSeparator();
+ toolBar->addAction(mCloneSnapshotAction);
+ toolBar->addSeparator();
toolBar->addAction (mShowSnapshotDetailsAction);
((QVBoxLayout*)layout())->insertWidget (0, toolBar);
@@ -380,11 +386,14 @@ VBoxSnapshotsWgt::VBoxSnapshotsWgt (QWidget *aParent)
QSize (22, 22), QSize (16, 16),
":/take_snapshot_22px.png", ":/take_snapshot_16px.png",
":/take_snapshot_dis_22px.png", ":/take_snapshot_dis_16px.png"));
+ mCloneSnapshotAction->setIcon(UIIconPool::iconSet(
+ ":/vm_clone_16px.png", ":/vm_clone_disabled_16px.png"));
mRestoreSnapshotAction->setShortcut (QString ("Ctrl+Shift+R"));
mDeleteSnapshotAction->setShortcut (QString ("Ctrl+Shift+D"));
mShowSnapshotDetailsAction->setShortcut (QString ("Ctrl+Space"));
mTakeSnapshotAction->setShortcut (QString ("Ctrl+Shift+S"));
+ mCloneSnapshotAction->setShortcut(QString ("Ctrl+Shift+C"));
mAgeUpdateTimer.setSingleShot (true);
@@ -396,10 +405,11 @@ VBoxSnapshotsWgt::VBoxSnapshotsWgt (QWidget *aParent)
connect (mTreeWidget, SIGNAL (itemChanged (QTreeWidgetItem*, int)),
this, SLOT (onItemChanged (QTreeWidgetItem*)));
- connect (mRestoreSnapshotAction, SIGNAL (triggered()), this, SLOT (restoreSnapshot()));
- connect (mDeleteSnapshotAction, SIGNAL (triggered()), this, SLOT (deleteSnapshot()));
- connect (mShowSnapshotDetailsAction, SIGNAL (triggered()), this, SLOT (showSnapshotDetails()));
- connect (mTakeSnapshotAction, SIGNAL (triggered()), this, SLOT (takeSnapshot()));
+ connect (mTakeSnapshotAction, SIGNAL (triggered()), this, SLOT (sltTakeSnapshot()));
+ connect (mRestoreSnapshotAction, SIGNAL (triggered()), this, SLOT (sltRestoreSnapshot()));
+ connect (mDeleteSnapshotAction, SIGNAL (triggered()), this, SLOT (sltDeleteSnapshot()));
+ connect (mShowSnapshotDetailsAction, SIGNAL (triggered()), this, SLOT (sltShowSnapshotDetails()));
+ connect (mCloneSnapshotAction, SIGNAL(triggered()), this, SLOT(sltCloneSnapshot()));
connect (gVBoxEvents, SIGNAL(sigMachineDataChange(QString)),
this, SLOT(machineDataChanged(QString)));
@@ -431,6 +441,35 @@ void VBoxSnapshotsWgt::setMachine (const CMachine &aMachine)
refreshAll();
}
+void VBoxSnapshotsWgt::retranslateUi()
+{
+ /* Translate uic generated strings */
+ Ui::VBoxSnapshotsWgt::retranslateUi (this);
+
+ mRestoreSnapshotAction->setText (tr ("&Restore Snapshot"));
+ mDeleteSnapshotAction->setText (tr ("&Delete Snapshot"));
+ mShowSnapshotDetailsAction->setText (tr ("S&how Details"));
+ mTakeSnapshotAction->setText (tr ("Take &Snapshot"));
+ mCloneSnapshotAction->setText(tr("&Clone..."));
+
+
+ mRestoreSnapshotAction->setStatusTip (tr ("Restore the selected snapshot of the virtual machine"));
+ mDeleteSnapshotAction->setStatusTip (tr ("Delete the selected snapshot of the virtual machine"));
+ mShowSnapshotDetailsAction->setStatusTip (tr ("Show the details of the selected snapshot"));
+ mTakeSnapshotAction->setStatusTip (tr ("Take a snapshot of the current virtual machine state"));
+ mCloneSnapshotAction->setStatusTip(tr("Clone the selected virtual machine"));
+
+ mRestoreSnapshotAction->setToolTip (mRestoreSnapshotAction->text().remove ('&').remove ('.') +
+ QString (" (%1)").arg (mRestoreSnapshotAction->shortcut().toString()));
+ mDeleteSnapshotAction->setToolTip (mDeleteSnapshotAction->text().remove ('&').remove ('.') +
+ QString (" (%1)").arg (mDeleteSnapshotAction->shortcut().toString()));
+ mShowSnapshotDetailsAction->setToolTip (mShowSnapshotDetailsAction->text().remove ('&').remove ('.') +
+ QString (" (%1)").arg (mShowSnapshotDetailsAction->shortcut().toString()));
+ mTakeSnapshotAction->setToolTip (mTakeSnapshotAction->text().remove ('&').remove ('.') +
+ QString (" (%1)").arg (mTakeSnapshotAction->shortcut().toString()));
+ mCloneSnapshotAction->setToolTip(mCloneSnapshotAction->text().remove('&').remove('.') +
+ QString(" (%1)").arg(mCloneSnapshotAction->shortcut().toString()));
+}
void VBoxSnapshotsWgt::onCurrentChanged (QTreeWidgetItem *aItem)
{
@@ -473,6 +512,9 @@ void VBoxSnapshotsWgt::onCurrentChanged (QTreeWidgetItem *aItem)
mTakeSnapshotAction->setEnabled ( ( canTakeDeleteSnapshot
&& mCurSnapshotItem && item && item->isCurrentStateItem())
|| (item && !mCurSnapshotItem));
+
+ /* Enable/disable cloning snapshots */
+ mCloneSnapshotAction->setEnabled(!busy && item);
}
void VBoxSnapshotsWgt::onContextMenuRequested (const QPoint &aPoint)
@@ -489,10 +531,16 @@ void VBoxSnapshotsWgt::onContextMenuRequested (const QPoint &aPoint)
menu.addAction (mRestoreSnapshotAction);
menu.addAction (mDeleteSnapshotAction);
menu.addSeparator();
+ menu.addAction(mCloneSnapshotAction);
+ menu.addSeparator();
menu.addAction (mShowSnapshotDetailsAction);
}
else
+ {
menu.addAction (mTakeSnapshotAction);
+ menu.addSeparator();
+ menu.addAction(mCloneSnapshotAction);
+ }
menu.exec (mTreeWidget->viewport()->mapToGlobal (aPoint));
}
@@ -512,42 +560,61 @@ void VBoxSnapshotsWgt::onItemChanged (QTreeWidgetItem *aItem)
}
}
-void VBoxSnapshotsWgt::restoreSnapshot()
+void VBoxSnapshotsWgt::sltTakeSnapshot()
{
- SnapshotWgtItem *item = !mTreeWidget->currentItem() ? 0 :
- static_cast <SnapshotWgtItem*> (mTreeWidget->currentItem());
- AssertReturn (item, (void) 0);
-
- QString snapId = item->snapshotId();
- AssertReturn (!snapId.isNull(), (void) 0);
- CSnapshot snapshot = mMachine.FindSnapshot(snapId);
+ takeSnapshot();
+}
- if (!vboxProblem().askAboutSnapshotRestoring (snapshot.GetName()))
- return;
+void VBoxSnapshotsWgt::sltRestoreSnapshot()
+{
+ /* Get currently chosen item: */
+ SnapshotWgtItem *pItem = mTreeWidget->currentItem() ? static_cast<SnapshotWgtItem*>(mTreeWidget->currentItem()) : 0;
+ AssertReturn(pItem, (void)0);
+ /* Detemine snapshot id: */
+ QString strSnapshotId = pItem->snapshotId();
+ AssertReturn(!strSnapshotId.isNull(), (void)0);
+ /* Get currently desired snapshot: */
+ CSnapshot snapshot = mMachine.FindSnapshot(strSnapshotId);
+
+ /* Ask the user if he really wants to restore the snapshot: */
+ int iResultCode = vboxProblem().askAboutSnapshotRestoring(snapshot.GetName(), mMachine.GetCurrentStateModified());
+
+ /* If user confirmed other snapshot restoring: */
+ if (iResultCode & QIMessageBox::Ok)
+ {
+ /* If user also confirmed new snapshot creation: */
+ if (iResultCode & QIMessageBox::OptionChosen)
+ {
+ /* Take snapshot of changed current state: */
+ mTreeWidget->setCurrentItem(curStateItem());
+ if (!takeSnapshot())
+ return;
+ }
- /* Open a direct session (this call will handle all errors) */
- CSession session = vboxGlobal().openSession (mMachineId);
- if (session.isNull())
- return;
+ /* Open a direct session (this call will handle all errors): */
+ CSession session = vboxGlobal().openSession(mMachineId);
+ if (session.isNull())
+ return;
- CConsole console = session.GetConsole();
- CProgress progress = console.RestoreSnapshot (snapshot);
- if (console.isOk())
- {
- /* Show the progress dialog */
- vboxProblem().showModalProgressDialog (progress, mMachine.GetName(), ":/progress_snapshot_restore_90px.png",
- vboxProblem().mainWindowShown(), true);
+ /* Restore chosen snapshot: */
+ CConsole console = session.GetConsole();
+ CProgress progress = console.RestoreSnapshot(snapshot);
+ if (console.isOk())
+ {
+ vboxProblem().showModalProgressDialog(progress, mMachine.GetName(), ":/progress_snapshot_restore_90px.png",
+ vboxProblem().mainWindowShown(), true);
+ if (progress.GetResultCode() != 0)
+ vboxProblem().cannotRestoreSnapshot(progress, snapshot.GetName());
+ }
+ else
+ vboxProblem().cannotRestoreSnapshot(progress, snapshot.GetName());
- if (progress.GetResultCode() != 0)
- vboxProblem().cannotRestoreSnapshot (progress, snapshot.GetName());
+ /* Unlock machine finally: */
+ session.UnlockMachine();
}
- else
- vboxProblem().cannotRestoreSnapshot (progress, snapshot.GetName());
-
- session.UnlockMachine();
}
-void VBoxSnapshotsWgt::deleteSnapshot()
+void VBoxSnapshotsWgt::sltDeleteSnapshot()
{
SnapshotWgtItem *item = !mTreeWidget->currentItem() ? 0 :
static_cast <SnapshotWgtItem*> (mTreeWidget->currentItem());
@@ -593,7 +660,7 @@ void VBoxSnapshotsWgt::deleteSnapshot()
session.UnlockMachine();
}
-void VBoxSnapshotsWgt::showSnapshotDetails()
+void VBoxSnapshotsWgt::sltShowSnapshotDetails()
{
SnapshotWgtItem *item = !mTreeWidget->currentItem() ? 0 :
static_cast <SnapshotWgtItem*> (mTreeWidget->currentItem());
@@ -611,61 +678,30 @@ void VBoxSnapshotsWgt::showSnapshotDetails()
dlg.putBackToSnapshot();
}
-void VBoxSnapshotsWgt::takeSnapshot()
+void VBoxSnapshotsWgt::sltCloneSnapshot()
{
SnapshotWgtItem *item = !mTreeWidget->currentItem() ? 0 :
static_cast <SnapshotWgtItem*> (mTreeWidget->currentItem());
AssertReturn (item, (void) 0);
- VBoxTakeSnapshotDlg dlg (this, mMachine);
-
- QString typeId = mMachine.GetOSTypeId();
- dlg.mLbIcon->setPixmap (vboxGlobal().vmGuestOSTypeIcon (typeId));
-
- /* Search for the max available filter index */
- int maxSnapShotIndex = 0;
- QString snapShotName = tr ("Snapshot %1");
- QRegExp regExp (QString ("^") + snapShotName.arg ("([0-9]+)") + QString ("$"));
- QTreeWidgetItemIterator iterator (mTreeWidget);
- while (*iterator)
+ CMachine machine;
+ bool fShowChildsOption = false;
+ if (item->isCurrentStateItem())
+ machine = item->machine();
+ else
{
- QString snapShot = static_cast <SnapshotWgtItem*> (*iterator)->text (0);
- int pos = regExp.indexIn (snapShot);
- if (pos != -1)
- maxSnapShotIndex = regExp.cap (1).toInt() > maxSnapShotIndex ?
- regExp.cap (1).toInt() : maxSnapShotIndex;
- ++ iterator;
+ const CSnapshot &snap = item->snapshot();
+ AssertReturn(!snap.isNull(), (void)0);
+ machine = snap.GetMachine();
+ if (snap.GetChildrenCount() > 0)
+ fShowChildsOption = true;
}
- dlg.mLeName->setText (snapShotName.arg (maxSnapShotIndex + 1));
-
- if (dlg.exec() == QDialog::Accepted)
- {
- /* Open a direct session (this call will handle all errors) */
- bool busy = mSessionState != KSessionState_Unlocked;
- CSession session = vboxGlobal().openSession (mMachineId, busy /* aExisting */);
- if (session.isNull())
- return;
+ AssertReturn(!machine.isNull(), (void)0);
- CConsole console = session.GetConsole();
- CProgress progress = console.TakeSnapshot (dlg.mLeName->text().trimmed(),
- dlg.mTeDescription->toPlainText());
- if (console.isOk())
- {
- /* Show the progress dialog */
- vboxProblem().showModalProgressDialog (progress, mMachine.GetName(), ":/progress_snapshot_create_90px.png",
- vboxProblem().mainWindowShown(), true);
-
- if (progress.GetResultCode() != 0)
- vboxProblem().cannotTakeSnapshot (progress);
- }
- else
- vboxProblem().cannotTakeSnapshot (console);
-
- session.UnlockMachine();
- }
+ UICloneVMWizard wzd(this, machine, fShowChildsOption);
+ wzd.exec();
}
-
void VBoxSnapshotsWgt::machineDataChanged(QString strId)
{
SnapshotEditBlocker guardBlock (mEditProtector);
@@ -728,29 +764,60 @@ void VBoxSnapshotsWgt::updateSnapshotsAge()
mAgeUpdateTimer.start();
}
-void VBoxSnapshotsWgt::retranslateUi()
+bool VBoxSnapshotsWgt::takeSnapshot()
{
- /* Translate uic generated strings */
- Ui::VBoxSnapshotsWgt::retranslateUi (this);
+ /* Get currently chosen item: */
+ SnapshotWgtItem *pItem = mTreeWidget->currentItem() ? static_cast <SnapshotWgtItem*>(mTreeWidget->currentItem()) : 0;
+ AssertReturn(pItem, (bool)0);
+
+ /* Create 'take new snapshot' dialog: */
+ VBoxTakeSnapshotDlg dlg(this, mMachine);
+ dlg.mLbIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(mMachine.GetOSTypeId()));
+
+ /* Search for the max available filter index: */
+ int iMaxSnapShotIndex = 0;
+ QString snapShotName = tr("Snapshot %1");
+ QRegExp regExp(QString("^") + snapShotName.arg("([0-9]+)") + QString("$"));
+ QTreeWidgetItemIterator iterator(mTreeWidget);
+ while (*iterator)
+ {
+ QString snapShot = static_cast<SnapshotWgtItem*>(*iterator)->text(0);
+ int pos = regExp.indexIn(snapShot);
+ if (pos != -1)
+ iMaxSnapShotIndex = regExp.cap(1).toInt() > iMaxSnapShotIndex ? regExp.cap(1).toInt() : iMaxSnapShotIndex;
+ ++iterator;
+ }
+ dlg.mLeName->setText(snapShotName.arg(iMaxSnapShotIndex + 1));
- mRestoreSnapshotAction->setText (tr ("&Restore Snapshot"));
- mDeleteSnapshotAction->setText (tr ("&Delete Snapshot"));
- mShowSnapshotDetailsAction->setText (tr ("S&how Details"));
- mTakeSnapshotAction->setText (tr ("Take &Snapshot"));
+ /* Show 'take new snapshot' dialog: */
+ if (dlg.exec() == QDialog::Accepted)
+ {
+ /* Open a direct session (this call will handle all errors): */
+ bool busy = mSessionState != KSessionState_Unlocked;
+ CSession session = vboxGlobal().openSession(mMachineId, busy /* aExisting */);
+ if (session.isNull())
+ return false;
- mRestoreSnapshotAction->setStatusTip (tr ("Restore the selected snapshot of the virtual machine"));
- mDeleteSnapshotAction->setStatusTip (tr ("Delete the selected snapshot of the virtual machine"));
- mShowSnapshotDetailsAction->setStatusTip (tr ("Show the details of the selected snapshot"));
- mTakeSnapshotAction->setStatusTip (tr ("Take a snapshot of the current virtual machine state"));
+ /* Take new snapshot: */
+ CConsole console = session.GetConsole();
+ CProgress progress = console.TakeSnapshot(dlg.mLeName->text().trimmed(), dlg.mTeDescription->toPlainText());
+ if (console.isOk())
+ {
+ /* Show the progress dialog */
+ vboxProblem().showModalProgressDialog(progress, mMachine.GetName(), ":/progress_snapshot_create_90px.png",
+ vboxProblem().mainWindowShown(), true);
+ if (progress.GetResultCode() != 0)
+ vboxProblem().cannotTakeSnapshot(progress);
+ }
+ else
+ vboxProblem().cannotTakeSnapshot(console);
- mRestoreSnapshotAction->setToolTip (mRestoreSnapshotAction->text().remove ('&').remove ('.') +
- QString (" (%1)").arg (mRestoreSnapshotAction->shortcut().toString()));
- mDeleteSnapshotAction->setToolTip (mDeleteSnapshotAction->text().remove ('&').remove ('.') +
- QString (" (%1)").arg (mDeleteSnapshotAction->shortcut().toString()));
- mShowSnapshotDetailsAction->setToolTip (mShowSnapshotDetailsAction->text().remove ('&').remove ('.') +
- QString (" (%1)").arg (mShowSnapshotDetailsAction->shortcut().toString()));
- mTakeSnapshotAction->setToolTip (mTakeSnapshotAction->text().remove ('&').remove ('.') +
- QString (" (%1)").arg (mTakeSnapshotAction->shortcut().toString()));
+ /* Unlock machine finally: */
+ session.UnlockMachine();
+
+ return true;
+ }
+ return false;
}
void VBoxSnapshotsWgt::refreshAll()
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.h b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.h
index 3a8917bd6..563ff7db1 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.h
+++ b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.h
@@ -56,15 +56,19 @@ protected:
private slots:
+ /* Snapshot tree slots: */
void onCurrentChanged (QTreeWidgetItem *aItem = 0);
void onContextMenuRequested (const QPoint &aPoint);
void onItemChanged (QTreeWidgetItem *aItem);
- void restoreSnapshot();
- void deleteSnapshot();
- void showSnapshotDetails();
- void takeSnapshot();
+ /* Snapshot functionality slots: */
+ void sltTakeSnapshot();
+ void sltRestoreSnapshot();
+ void sltDeleteSnapshot();
+ void sltShowSnapshotDetails();
+ void sltCloneSnapshot();
+ /* Main API event handlers: */
void machineDataChanged(QString strId);
void machineStateChanged(QString strId, KMachineState state);
void sessionStateChanged(QString strId, KSessionState state);
@@ -73,6 +77,12 @@ private slots:
private:
+ /* Snapshot private functions: */
+ bool takeSnapshot();
+ //bool restoreSnapshot();
+ //bool deleteSnapshot();
+ //bool showSnapshotDetails();
+
void refreshAll();
SnapshotWgtItem* findItem (const QString &aSnapshotId);
SnapshotWgtItem* curStateItem();
@@ -92,6 +102,7 @@ private:
QAction *mDeleteSnapshotAction;
QAction *mShowSnapshotDetailsAction;
QAction *mTakeSnapshotAction;
+ QAction *mCloneSnapshotAction;
QTimer mAgeUpdateTimer;
};
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDefs.cpp b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDefs.cpp
new file mode 100644
index 000000000..953d9ebdf
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDefs.cpp
@@ -0,0 +1,49 @@
+/* $Id: UISettingsDefs.cpp 36589 2011-04-06 15:24:00Z vboxsync $ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UISettingsDefs implementation
+ */
+
+/*
+ * 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.
+ */
+
+/* VBox includes: */
+#include "UISettingsDefs.h"
+
+/* Using declarations: */
+using namespace UISettingsDefs;
+
+/* Machine state => Settings dialog type converter: */
+SettingsDialogType UISettingsDefs::machineStateToSettingsDialogType(KMachineState machineState)
+{
+ SettingsDialogType result = SettingsDialogType_Wrong;
+ switch (machineState)
+ {
+ case KMachineState_PoweredOff:
+ case KMachineState_Teleported:
+ case KMachineState_Aborted:
+ result = SettingsDialogType_Offline;
+ break;
+ case KMachineState_Saved:
+ result = SettingsDialogType_Saved;
+ break;
+ case KMachineState_Running:
+ case KMachineState_Paused:
+ result = SettingsDialogType_Online;
+ break;
+ default:
+ break;
+ }
+ return result;
+}
+
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDefs.h b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDefs.h
new file mode 100644
index 000000000..de8b76054
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDefs.h
@@ -0,0 +1,167 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * Header with definitions and functions related to settings dialog
+ */
+
+/*
+ * 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 __UISettingsDefs_h__
+#define __UISettingsDefs_h__
+
+/* Qt includes: */
+#include <QPair>
+#include <QMap>
+
+/* VBox includes: */
+#include "COMDefs.h"
+
+/* Settings dialog namespace: */
+namespace UISettingsDefs
+{
+ /* Settings dialog types: */
+ enum SettingsDialogType
+ {
+ SettingsDialogType_Wrong,
+ SettingsDialogType_Offline,
+ SettingsDialogType_Saved,
+ SettingsDialogType_Online
+ };
+
+ /* Machine state => Settings dialog type converter: */
+ SettingsDialogType machineStateToSettingsDialogType(KMachineState machineState);
+}
+
+/* Template to operate settings cache item: */
+template <class CacheData> class UISettingsCache
+{
+public:
+
+ /* Creates empty cache item: */
+ UISettingsCache() { m_value = qMakePair(CacheData(), CacheData()); }
+
+ /* Returns the NON-modifiable REFERENCE to the initial cached data: */
+ const CacheData& base() const { return m_value.first; }
+ /* Returns the NON-modifiable REFERENCE to the current cached data: */
+ const CacheData& data() const { return m_value.second; }
+
+ /* We assume that old cache item was removed if
+ * initial data was set but current data was NOT set.
+ * Returns 'true' if that cache item was removed: */
+ virtual bool wasRemoved() const { return base() != CacheData() && data() == CacheData(); }
+
+ /* We assume that new cache item was created if
+ * initial data was NOT set but current data was set.
+ * Returns 'true' if that cache item was created: */
+ virtual bool wasCreated() const { return base() == CacheData() && data() != CacheData(); }
+
+ /* We assume that old cache item was updated if
+ * current and initial data were both set and not equal to each other.
+ * Returns 'true' if that cache item was updated: */
+ virtual bool wasUpdated() const { return base() != CacheData() && data() != CacheData() && data() != base(); }
+
+ /* We assume that old cache item was actually changed if
+ * 1. this item was removed or
+ * 2. this item was created or
+ * 3. this item was updated.
+ * Returns 'true' if that cache item was actually changed: */
+ virtual bool wasChanged() const { return wasRemoved() || wasCreated() || wasUpdated(); }
+
+ /* Set initial cache item data: */
+ void cacheInitialData(const CacheData &initialData) { m_value.first = initialData; }
+ /* Set current cache item data: */
+ void cacheCurrentData(const CacheData &currentData) { m_value.second = currentData; }
+
+ /* Reset the initial and the current data to be both empty: */
+ void clear() { m_value.first = CacheData(); m_value.second = CacheData(); }
+
+private:
+
+ /* Data: */
+ QPair<CacheData, CacheData> m_value;
+};
+
+/* Template to operate settings cache item with children: */
+template <class ParentCacheData, class ChildCacheData> class UISettingsCachePool : public UISettingsCache<ParentCacheData>
+{
+public:
+
+ /* Typedefs: */
+ typedef QMap<QString, ChildCacheData> UISettingsCacheChildMap;
+ typedef QMapIterator<QString, ChildCacheData> UISettingsCacheChildIterator;
+
+ /* Creates empty cache item: */
+ UISettingsCachePool() : UISettingsCache<ParentCacheData>() {}
+
+ /* Returns the modifiable REFERENCE to the particular child cached data.
+ * If child with such key or index is NOT present,
+ * both those methods will create the new one to return: */
+ ChildCacheData& child(const QString &strChildKey) { return m_children[strChildKey]; }
+ ChildCacheData& child(int iIndex) { return child(indexToKey(iIndex)); }
+
+ /* Returns the NON-modifiable COPY to the particular child cached data.
+ * If child with such key or index is NOT present,
+ * both those methods will create the new one to return: */
+ const ChildCacheData child(const QString &strChildKey) const { return m_children[strChildKey]; }
+ const ChildCacheData child(int iIndex) const { return child(indexToKey(iIndex)); }
+
+ /* Children count: */
+ int childCount() const { return m_children.size(); }
+
+ /* We assume that old cache item was updated if
+ * current and initial data were both set and not equal to each other.
+ * Takes into account all the children.
+ * Returns 'true' if that cache item was updated: */
+ bool wasUpdated() const
+ {
+ /* First of all, cache item is considered to be updated if parent data was updated: */
+ bool fWasUpdated = UISettingsCache<ParentCacheData>::wasUpdated();
+ /* If parent data was NOT updated but also was NOT created or removed too (e.j. was NOT changed at all),
+ * we have to check children too: */
+ if (!fWasUpdated && !UISettingsCache<ParentCacheData>::wasRemoved() && !UISettingsCache<ParentCacheData>::wasCreated())
+ {
+ for (int iChildIndex = 0; !fWasUpdated && iChildIndex < childCount(); ++iChildIndex)
+ if (child(iChildIndex).wasChanged())
+ fWasUpdated = true;
+ }
+ return fWasUpdated;
+ }
+
+ /* Reset the initial and the current data to be both empty.
+ * Removes all the children: */
+ void clear()
+ {
+ UISettingsCache<ParentCacheData>::clear();
+ m_children.clear();
+ }
+
+private:
+
+ QString indexToKey(int iIndex) const
+ {
+ UISettingsCacheChildIterator childIterator(m_children);
+ for (int iChildIndex = 0; childIterator.hasNext(); ++iChildIndex)
+ {
+ childIterator.next();
+ if (iChildIndex == iIndex)
+ return childIterator.key();
+ }
+ return QString("%1").arg(iIndex, 8 /* up to 8 digits */, 10 /* base */, QChar('0') /* filler */);
+ }
+
+ /* Children: */
+ UISettingsCacheChildMap m_children;
+};
+
+#endif /* __UISettingsDefs_h__ */
+
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.cpp b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.cpp
index c5032c97b..7c97f8784 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.cpp
@@ -1,4 +1,4 @@
-/* $Id: UISettingsDialog.cpp $ */
+/* $Id: UISettingsDialog.cpp 37615 2011-06-23 14:37:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -6,7 +6,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;
@@ -18,6 +18,7 @@
*/
/* Global includes */
+#include <QProgressBar>
#include <QPushButton>
#include <QStackedWidget>
#include <QTimer>
@@ -41,16 +42,22 @@
#endif /* Q_WS_MAC */
/* Settings Dialog Constructor: */
-UISettingsDialog::UISettingsDialog(QWidget *pParent /* = 0 */)
+UISettingsDialog::UISettingsDialog(QWidget *pParent)
/* Parent class: */
: QIWithRetranslateUI<QIMainDialog>(pParent)
/* Protected variables: */
, m_pSelector(0)
, m_pStack(0)
/* Common variables: */
+ , m_dialogType(SettingsDialogType_Wrong)
, m_fPolished(false)
- /* Loading stuff: */
- , m_fProcessed(false)
+ /* Loading/saving stuff: */
+ , m_fLoaded(false)
+ , m_fSaved(false)
+ /* Status bar stuff: */
+ , m_pStatusBar(new QStackedWidget(this))
+ /* Process bar stuff: */
+ , m_pProcessBar(new QProgressBar(this))
/* Error/Warning stuff: */
, m_fValid(true)
, m_fSilent(true)
@@ -102,8 +109,15 @@ UISettingsDialog::UISettingsDialog(QWidget *pParent /* = 0 */)
pStackLayout->setContentsMargins(0, 0, 0, 0);
pStackLayout->addWidget(m_pStack);
+ /* Status bar: */
+ m_pStatusBar->addWidget(new QWidget);
+ m_pButtonBox->addExtraWidget(m_pStatusBar);
+
+ /* Setup process bar stuff: */
+ m_pStatusBar->addWidget(m_pProcessBar);
+
/* Setup error & warning stuff: */
- m_pButtonBox->addExtraWidget(m_pWarningPane);
+ m_pStatusBar->addWidget(m_pWarningPane);
m_errorIcon = UIIconPool::defaultIcon(UIIconPool::MessageBoxCriticalIcon, this).pixmap(16, 16);
m_warningIcon = UIIconPool::defaultIcon(UIIconPool::MessageBoxWarningIcon, this).pixmap(16, 16);
@@ -136,6 +150,19 @@ UISettingsDialog::~UISettingsDialog()
delete m_pSelector;
}
+void UISettingsDialog::execute()
+{
+ /* Load data: */
+ loadData();
+
+ /* Execute dialog and wait for completion: */
+ if (exec() != QDialog::Accepted)
+ return;
+
+ /* Save data: */
+ saveData();
+}
+
void UISettingsDialog::sltRevalidate(QIWidgetValidator *pValidator)
{
/* Get related settings page: */
@@ -146,13 +173,12 @@ void UISettingsDialog::sltRevalidate(QIWidgetValidator *pValidator)
QString strWarning;
QString strTitle = m_pSelector->itemTextByPage(pSettingsPage);
+ /* Recorrelate page with others before revalidation: */
+ recorrelate(pSettingsPage);
+
/* Revalidate the page: */
bool fValid = pSettingsPage->revalidate(strWarning, strTitle);
- /* If revalidation is fully passed - recorrelate the pages: */
- if (fValid && strWarning.isEmpty())
- fValid = recorrelate(pSettingsPage, strWarning);
-
/* Compose a message: */
strWarning = strWarning.isEmpty() ? QString() :
tr("On the <b>%1</b> page, %2").arg(strTitle, strWarning);
@@ -190,9 +216,42 @@ void UISettingsDialog::sltCategoryChanged(int cId)
#endif /* VBOX_GUI_WITH_TOOLBAR_SETTINGS */
}
-void UISettingsDialog::sltMarkProcessed()
+void UISettingsDialog::sltMarkLoaded()
+{
+ m_fLoaded = true;
+}
+
+void UISettingsDialog::sltMarkSaved()
+{
+ m_fSaved = true;
+}
+
+void UISettingsDialog::sltHandleProcessStarted()
+{
+ m_pProcessBar->setValue(0);
+ m_pStatusBar->setCurrentWidget(m_pProcessBar);
+}
+
+void UISettingsDialog::sltHandlePageProcessed()
+{
+ m_pProcessBar->setValue(m_pProcessBar->value() + 1);
+ if (m_pProcessBar->value() == m_pProcessBar->maximum())
+ {
+ if (!m_fValid || !m_fSilent)
+ m_pStatusBar->setCurrentWidget(m_pWarningPane);
+ else
+ m_pStatusBar->setCurrentIndex(0);
+ }
+}
+
+void UISettingsDialog::loadData()
{
- m_fProcessed = true;
+ m_fLoaded = false;
+}
+
+void UISettingsDialog::saveData()
+{
+ m_fSaved = false;
}
void UISettingsDialog::retranslateUi()
@@ -230,6 +289,16 @@ void UISettingsDialog::retranslateUi()
}
}
+void UISettingsDialog::setDialogType(SettingsDialogType settingsDialogType)
+{
+ m_dialogType = settingsDialogType;
+ for (int iWidgetNumber = 0; iWidgetNumber < m_pStack->count(); ++iWidgetNumber)
+ {
+ UISettingsPage *pPage = static_cast<UISettingsPage*>(m_pStack->widget(iWidgetNumber));
+ pPage->setDialogType(dialogType());
+ }
+}
+
QString UISettingsDialog::titleExtension() const
{
#ifdef VBOX_GUI_WITH_TOOLBAR_SETTINGS
@@ -248,7 +317,7 @@ void UISettingsDialog::setError(const QString &strError)
* otherwise it can change its size to undefined: */
if (m_fPolished)
{
- if (!m_strErrorString.isEmpty())
+ if (!m_strErrorString.isEmpty() && m_pStatusBar->currentWidget() == m_pWarningPane)
m_pLbWhatsThis->setText(m_strErrorString);
else
sltUpdateWhatsThis(true /* got focus? */);
@@ -264,7 +333,7 @@ void UISettingsDialog::setWarning(const QString &strWarning)
* otherwise it can change its size to undefined: */
if (m_fPolished)
{
- if (!m_strWarningString.isEmpty())
+ if (!m_strWarningString.isEmpty() && m_pStatusBar->currentWidget() == m_pWarningPane)
m_pLbWhatsThis->setText(m_strWarningString);
else
sltUpdateWhatsThis(true /* got focus? */);
@@ -298,16 +367,14 @@ void UISettingsDialog::addItem(const QString &strBigIcon,
#else /* Q_WS_MAC */
m_pages[cId] = m_pStack->addWidget(pPage);
#endif /* !Q_WS_MAC */
+ /* Update process bar: */
+ m_pProcessBar->setMinimum(0);
+ m_pProcessBar->setMaximum(m_pStack->count());
}
if (pSettingsPage)
assignValidator(pSettingsPage);
}
-bool UISettingsDialog::recorrelate(QWidget * /* pPage */, QString & /* strWarning */)
-{
- return true;
-}
-
void UISettingsDialog::sltHandleValidityChanged(const QIWidgetValidator * /* pValidator */)
{
/* Get validators list: */
@@ -337,13 +404,16 @@ void UISettingsDialog::sltHandleValidityChanged(const QIWidgetValidator * /* pVa
setError(strError);
m_fValid = fNewValid;
+ m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(m_fValid);
m_pWarningPane->setWarningPixmap(m_errorIcon);
m_pWarningPane->setWarningText(m_strErrorHint);
#ifdef Q_WS_MAC
m_pWarningPane->setToolTip(m_strErrorString);
#endif /* Q_WS_MAC */
- m_pWarningPane->setVisible(!m_fValid);
- m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(m_fValid);
+ if (m_fValid && m_pStatusBar->currentWidget() == m_pWarningPane)
+ m_pStatusBar->setCurrentIndex(0);
+ else if (!m_fValid && m_pStatusBar->currentIndex() == 0)
+ m_pStatusBar->setCurrentWidget(m_pWarningPane);
if (!m_fValid)
return;
@@ -378,7 +448,10 @@ void UISettingsDialog::sltHandleValidityChanged(const QIWidgetValidator * /* pVa
#ifdef Q_WS_MAC
m_pWarningPane->setToolTip(m_strWarningString);
#endif /* Q_WS_MAC */
- m_pWarningPane->setVisible(!m_fSilent);
+ if (m_fSilent && m_pStatusBar->currentWidget() == m_pWarningPane)
+ m_pStatusBar->setCurrentIndex(0);
+ else if (!m_fSilent && m_pStatusBar->currentIndex() == 0)
+ m_pStatusBar->setCurrentWidget(m_pWarningPane);
}
}
@@ -411,10 +484,13 @@ void UISettingsDialog::sltUpdateWhatsThis(bool fGotFocus /* = false */)
}
#ifndef Q_WS_MAC
- if (strWhatsThisText.isEmpty() && !m_strErrorString.isEmpty())
- strWhatsThisText = m_strErrorString;
- else if (strWhatsThisText.isEmpty() && !m_strWarningString.isEmpty())
- strWhatsThisText = m_strWarningString;
+ if (m_pStatusBar->currentWidget() == m_pWarningPane)
+ {
+ if (strWhatsThisText.isEmpty() && !m_strErrorString.isEmpty())
+ strWhatsThisText = m_strErrorString;
+ else if (strWhatsThisText.isEmpty() && !m_strWarningString.isEmpty())
+ strWhatsThisText = m_strWarningString;
+ }
if (strWhatsThisText.isEmpty())
strWhatsThisText = whatsThis();
m_pLbWhatsThis->setText(strWhatsThisText);
@@ -426,7 +502,7 @@ void UISettingsDialog::sltUpdateWhatsThis(bool fGotFocus /* = false */)
void UISettingsDialog::reject()
{
- if (m_fProcessed)
+ if (m_fLoaded)
QIMainDialog::reject();
}
@@ -529,7 +605,7 @@ void UISettingsDialog::showEvent(QShowEvent *pEvent)
void UISettingsDialog::closeEvent(QCloseEvent *pEvent)
{
- if (m_fProcessed)
+ if (m_fLoaded)
QIMainDialog::closeEvent(pEvent);
else
pEvent->ignore();
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.h b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.h
index 6f674ba5c..c2858fadf 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.h
@@ -5,7 +5,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;
@@ -19,19 +19,24 @@
#ifndef __UISettingsDialog_h__
#define __UISettingsDialog_h__
-/* Local includes */
+/* VBox includes: */
#include "QIMainDialog.h"
#include "QIWithRetranslateUI.h"
#include "UISettingsDialog.gen.h"
+#include "UISettingsDefs.h"
-/* Forward declarations */
+/* Forward declarations: */
class QIWidgetValidator;
+class QProgressBar;
class QStackedWidget;
class QTimer;
class VBoxWarningPane;
class VBoxSettingsSelector;
class UISettingsPage;
+/* Using declarations: */
+using namespace UISettingsDefs;
+
/* Base dialog class for both Global & VM settings which encapsulates most of their similar functionalities */
class UISettingsDialog : public QIWithRetranslateUI<QIMainDialog>, public Ui::UISettingsDialog
{
@@ -40,12 +45,11 @@ class UISettingsDialog : public QIWithRetranslateUI<QIMainDialog>, public Ui::UI
public:
/* Settings Dialog Constructor/Destructor: */
- UISettingsDialog(QWidget *pParent = 0);
+ UISettingsDialog(QWidget *pParent);
~UISettingsDialog();
- /* Save/Load interface: */
- virtual void getFrom() = 0;
- virtual void putBackTo() = 0;
+ /* Execute API: */
+ void execute();
protected slots:
@@ -55,14 +59,27 @@ protected slots:
/* Category-change slot: */
virtual void sltCategoryChanged(int cId);
- /* Mark dialog as processed: */
- virtual void sltMarkProcessed();
+ /* Mark dialog as loaded: */
+ virtual void sltMarkLoaded();
+ /* Mark dialog as saved: */
+ virtual void sltMarkSaved();
+
+ /* Handlers for process bar: */
+ void sltHandleProcessStarted();
+ void sltHandlePageProcessed();
protected:
+ /* Save/load API: */
+ virtual void loadData();
+ virtual void saveData();
+
/* UI translator: */
virtual void retranslateUi();
+ /* Dialog type: */
+ SettingsDialogType dialogType() { return m_dialogType; }
+ void setDialogType(SettingsDialogType settingsDialogType);
/* Dialog title: */
virtual QString title() const = 0;
/* Dialog title extension: */
@@ -78,8 +95,8 @@ protected:
int cId, const QString &strLink,
UISettingsPage* pSettingsPage = 0, int iParentId = -1);
- /* Correlation handler: */
- virtual bool recorrelate(QWidget *pPage, QString &strWarning);
+ /* Settings page correlator: */
+ virtual void recorrelate(UISettingsPage *pSettingsPage) { Q_UNUSED(pSettingsPage); }
/* Protected variables: */
VBoxSettingsSelector *m_pSelector;
@@ -106,10 +123,20 @@ private:
void assignValidator(UISettingsPage *pPage);
/* Global Flags: */
+ SettingsDialogType m_dialogType;
bool m_fPolished;
+ /* Loading/saving stuff: */
+ bool m_fLoaded;
+ bool m_fSaved;
+
+ /* Status bar widget: */
+ QStackedWidget *m_pStatusBar;
+
+ /* Process bar widget: */
+ QProgressBar *m_pProcessBar;
+
/* Error & Warning stuff: */
- bool m_fProcessed;
bool m_fValid;
bool m_fSilent;
QString m_strErrorHint;
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp
index 5bd98ced4..be95e2c5a 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp
@@ -1,4 +1,4 @@
-/* $Id: UISettingsDialogSpecific.cpp $ */
+/* $Id: UISettingsDialogSpecific.cpp 37901 2011-07-12 13:46:36Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -6,7 +6,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;
@@ -26,10 +26,12 @@
/* Local includes */
#include "UISettingsDialogSpecific.h"
+#include "UISettingsDefs.h"
#include "VBoxGlobal.h"
#include "VBoxProblemReporter.h"
#include "QIWidgetValidator.h"
#include "VBoxSettingsSelector.h"
+#include "UIVirtualBoxEventHandler.h"
#include "UIGlobalSettingsGeneral.h"
#include "UIGlobalSettingsInput.h"
@@ -37,6 +39,7 @@
#include "UIGlobalSettingsLanguage.h"
#include "UIGlobalSettingsNetwork.h"
#include "UIGlobalSettingsExtension.h"
+#include "UIGlobalSettingsProxy.h"
#include "UIMachineSettingsGeneral.h"
#include "UIMachineSettingsSystem.h"
@@ -84,10 +87,13 @@ public:
, m_iPageIdWeAreWaitingFor(-1)
, m_iIdOfHighPriorityPage(-1)
{
- /* Connecting thread signals: */
+ /* Connecting this signals: */
connect(this, SIGNAL(sigNotifyAboutPageProcessed(int)), this, SLOT(sltHandleProcessedPage(int)), Qt::QueuedConnection);
connect(this, SIGNAL(sigNotifyAboutPagesProcessed()), this, SLOT(sltHandleProcessedPages()), Qt::QueuedConnection);
connect(this, SIGNAL(finished()), this, SLOT(sltDestroySerializer()), Qt::QueuedConnection);
+ /* Connecting parent signals: */
+ connect(this, SIGNAL(sigNotifyAboutProcessStarted()), parent(), SLOT(sltHandleProcessStarted()), Qt::QueuedConnection);
+ connect(this, SIGNAL(sigNotifyAboutPageProcessed(int)), parent(), SLOT(sltHandlePageProcessed()), Qt::QueuedConnection);
/* Set instance: */
m_pInstance = this;
@@ -151,6 +157,9 @@ public:
signals:
+ /* Signal to notify main GUI thread about process has been started: */
+ void sigNotifyAboutProcessStarted();
+
/* Signal to notify main GUI thread about some page was processed: */
void sigNotifyAboutPageProcessed(int iPageId);
@@ -161,6 +170,8 @@ public slots:
void start(Priority priority = InheritPriority)
{
+ /* Notify listeners a bout we are starting: */
+ emit sigNotifyAboutProcessStarted();
/* If serializer saves settings: */
if (m_direction == UISettingsSerializeDirection_Save)
{
@@ -233,6 +244,11 @@ protected:
/* Settings processor: */
void run()
{
+ /* Mark all the pages initially as NOT processed: */
+ QList<UISettingsPage*> pageList = m_pages.values();
+ for (int iPageNumber = 0; iPageNumber < pageList.size(); ++iPageNumber)
+ pageList[iPageNumber]->setProcessed(false);
+
/* Iterate over the all left settings pages: */
UISettingsPageMap pages(m_pages);
while (!pages.empty())
@@ -287,7 +303,7 @@ protected:
UISettingsSerializer* UISettingsSerializer::m_pInstance = 0;
-UIGLSettingsDlg::UIGLSettingsDlg(QWidget *pParent)
+UISettingsDialogGlobal::UISettingsDialogGlobal(QWidget *pParent)
: UISettingsDialog(pParent)
{
/* Window icon: */
@@ -295,86 +311,97 @@ UIGLSettingsDlg::UIGLSettingsDlg(QWidget *pParent)
setWindowIcon(QIcon(":/global_settings_16px.png"));
#endif /* !Q_WS_MAC */
+ /* Assign default dialog type: */
+ setDialogType(SettingsDialogType_Offline);
+
/* Creating settings pages: */
- for (int i = GLSettingsPage_General; i < GLSettingsPage_MAX; ++i)
+ for (int iPageIndex = GLSettingsPage_General; iPageIndex < GLSettingsPage_MAX; ++iPageIndex)
{
- if (isAvailable(i))
+ if (isPageAvailable(iPageIndex))
{
- switch (i)
+ UISettingsPage *pSettingsPage = 0;
+ switch (iPageIndex)
{
/* General page: */
case GLSettingsPage_General:
{
- UISettingsPage *pSettingsPage = new UIGlobalSettingsGeneral;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIGlobalSettingsGeneral;
addItem(":/machine_32px.png", ":/machine_disabled_32px.png",
":/machine_16px.png", ":/machine_disabled_16px.png",
- i, "#general", pSettingsPage);
+ iPageIndex, "#general", pSettingsPage);
break;
}
/* Input page: */
case GLSettingsPage_Input:
{
- UISettingsPage *pSettingsPage = new UIGlobalSettingsInput;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIGlobalSettingsInput;
addItem(":/hostkey_32px.png", ":/hostkey_disabled_32px.png",
":/hostkey_16px.png", ":/hostkey_disabled_16px.png",
- i, "#input", pSettingsPage);
+ iPageIndex, "#input", pSettingsPage);
break;
}
/* Update page: */
case GLSettingsPage_Update:
{
- UISettingsPage *pSettingsPage = new UIGlobalSettingsUpdate;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIGlobalSettingsUpdate;
addItem(":/refresh_32px.png", ":/refresh_disabled_32px.png",
":/refresh_16px.png", ":/refresh_disabled_16px.png",
- i, "#update", pSettingsPage);
+ iPageIndex, "#update", pSettingsPage);
break;
}
/* Language page: */
case GLSettingsPage_Language:
{
- UISettingsPage *pSettingsPage = new UIGlobalSettingsLanguage;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIGlobalSettingsLanguage;
addItem(":/site_32px.png", ":/site_disabled_32px.png",
":/site_16px.png", ":/site_disabled_16px.png",
- i, "#language", pSettingsPage);
+ iPageIndex, "#language", pSettingsPage);
break;
}
/* USB page: */
case GLSettingsPage_USB:
{
- UISettingsPage *pSettingsPage = new UIMachineSettingsUSB(UISettingsPageType_Global);
- pSettingsPage->setId(i);
+ pSettingsPage = new UIMachineSettingsUSB(UISettingsPageType_Global);
addItem(":/usb_32px.png", ":/usb_disabled_32px.png",
":/usb_16px.png", ":/usb_disabled_16px.png",
- i, "#usb", pSettingsPage);
+ iPageIndex, "#usb", pSettingsPage);
break;
}
/* Network page: */
case GLSettingsPage_Network:
{
- UISettingsPage *pSettingsPage = new UIGlobalSettingsNetwork;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIGlobalSettingsNetwork;
addItem(":/nw_32px.png", ":/nw_disabled_32px.png",
":/nw_16px.png", ":/nw_disabled_16px.png",
- i, "#language", pSettingsPage);
+ iPageIndex, "#language", pSettingsPage);
break;
}
/* Extension page: */
case GLSettingsPage_Extension:
{
- UISettingsPage *pSettingsPage = new UIGlobalSettingsExtension;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIGlobalSettingsExtension;
addItem(":/extension_pack_32px.png", ":/extension_pack_disabled_32px.png",
":/extension_pack_16px.png", ":/extension_pack_disabled_16px.png",
- i, "#extension", pSettingsPage);
+ iPageIndex, "#extension", pSettingsPage);
+ break;
+ }
+ /* Proxy page: */
+ case GLSettingsPage_Proxy:
+ {
+ pSettingsPage = new UIGlobalSettingsProxy;
+ addItem(":/proxy_32px.png", ":/proxy_disabled_32px.png",
+ ":/proxy_16px.png", ":/proxy_disabled_16px.png",
+ iPageIndex, "#proxy", pSettingsPage);
break;
}
default:
break;
}
+ if (pSettingsPage)
+ {
+ pSettingsPage->setDialogType(dialogType());
+ pSettingsPage->setId(iPageIndex);
+ }
}
}
@@ -385,15 +412,18 @@ UIGLSettingsDlg::UIGLSettingsDlg(QWidget *pParent)
m_pSelector->selectById(0);
}
-void UIGLSettingsDlg::getFrom()
+void UISettingsDialogGlobal::loadData()
{
+ /* Call for base-class: */
+ UISettingsDialog::loadData();
+
/* Prepare global data: */
qRegisterMetaType<UISettingsDataGlobal>();
UISettingsDataGlobal data(vboxGlobal().virtualBox().GetSystemProperties(), vboxGlobal().settings());
/* Create global settings loader,
* it will load global settings & delete itself in the appropriate time: */
UISettingsSerializer *pGlobalSettingsLoader = new UISettingsSerializer(this, QVariant::fromValue(data), UISettingsSerializeDirection_Load);
- connect(pGlobalSettingsLoader, SIGNAL(destroyed(QObject*)), this, SLOT(sltMarkProcessed()));
+ connect(pGlobalSettingsLoader, SIGNAL(destroyed(QObject*)), this, SLOT(sltMarkLoaded()));
/* Set pages to be loaded: */
pGlobalSettingsLoader->setPageList(m_pSelector->settingPages());
/* Start loader: */
@@ -402,8 +432,11 @@ void UIGLSettingsDlg::getFrom()
pGlobalSettingsLoader->waitForPageToBeProcessed(m_pSelector->currentId());
}
-void UIGLSettingsDlg::putBackTo()
+void UISettingsDialogGlobal::saveData()
{
+ /* Call for base-class: */
+ UISettingsDialog::saveData();
+
/* Get properties and settings: */
CSystemProperties properties = vboxGlobal().virtualBox().GetSystemProperties();
VBoxGlobalSettings settings = vboxGlobal().settings();
@@ -429,9 +462,12 @@ void UIGLSettingsDlg::putBackTo()
/* Else save the new settings if they were changed: */
else if (!(newSettings == settings))
vboxGlobal().setSettings(newSettings);
+
+ /* Mark page processed: */
+ sltMarkSaved();
}
-void UIGLSettingsDlg::retranslateUi()
+void UISettingsDialogGlobal::retranslateUi()
{
/* Base-class UI translation: */
UISettingsDialog::retranslateUi();
@@ -460,21 +496,24 @@ void UIGLSettingsDlg::retranslateUi()
/* Extension page: */
m_pSelector->setItemText(GLSettingsPage_Extension, tr("Extensions"));
+ /* Proxy page: */
+ m_pSelector->setItemText(GLSettingsPage_Proxy, tr("Proxy"));
+
/* Translate the selector: */
m_pSelector->polish();
}
-QString UIGLSettingsDlg::title() const
+QString UISettingsDialogGlobal::title() const
{
return tr("VirtualBox - %1").arg(titleExtension());
}
-bool UIGLSettingsDlg::isAvailable(int id)
+bool UISettingsDialogGlobal::isPageAvailable(int iPageId)
{
/* Show the host error message for particular group if present.
* We don't use the generic cannotLoadGlobalConfig()
* call here because we want this message to be suppressible: */
- switch (id)
+ switch (iPageId)
{
case GLSettingsPage_USB:
{
@@ -507,12 +546,10 @@ bool UIGLSettingsDlg::isAvailable(int id)
return true;
}
-UIVMSettingsDlg::UIVMSettingsDlg(QWidget *pParent,
- const CMachine &machine,
- const QString &strCategory,
- const QString &strControl)
+UISettingsDialogMachine::UISettingsDialogMachine(QWidget *pParent, const QString &strMachineId,
+ const QString &strCategory, const QString &strControl)
: UISettingsDialog(pParent)
- , m_machine(machine)
+ , m_strMachineId(strMachineId)
, m_fAllowResetFirstRunFlag(false)
, m_fResetFirstRunFlag(false)
{
@@ -524,73 +561,74 @@ UIVMSettingsDlg::UIVMSettingsDlg(QWidget *pParent,
/* Allow to reset first-run flag just when medium enumeration was finished: */
connect(&vboxGlobal(), SIGNAL(mediumEnumFinished(const VBoxMediaList &)), this, SLOT(sltAllowResetFirstRunFlag()));
+ /* Get corresponding machine (required to determine dialog type and page availability): */
+ m_machine = vboxGlobal().virtualBox().FindMachine(m_strMachineId);
+ AssertMsg(!m_machine.isNull(), ("Can't find corresponding machine!\n"));
+ /* Assign current dialog type: */
+ setDialogType(machineStateToSettingsDialogType(m_machine.GetState()));
+
/* Creating settings pages: */
- for (int i = VMSettingsPage_General; i < VMSettingsPage_MAX; ++i)
+ for (int iPageIndex = VMSettingsPage_General; iPageIndex < VMSettingsPage_MAX; ++iPageIndex)
{
- if (isAvailable(i))
+ if (isPageAvailable(iPageIndex))
{
- switch (i)
+ UISettingsPage *pSettingsPage = 0;
+ switch (iPageIndex)
{
/* General page: */
case VMSettingsPage_General:
{
- UISettingsPage *pSettingsPage = new UIMachineSettingsGeneral;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIMachineSettingsGeneral;
addItem(":/machine_32px.png", ":/machine_disabled_32px.png",
":/machine_16px.png", ":/machine_disabled_16px.png",
- i, "#general", pSettingsPage);
+ iPageIndex, "#general", pSettingsPage);
break;
}
/* System page: */
case VMSettingsPage_System:
{
- UISettingsPage *pSettingsPage = new UIMachineSettingsSystem;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIMachineSettingsSystem;
connect(pSettingsPage, SIGNAL(tableChanged()), this, SLOT(sltResetFirstRunFlag()));
addItem(":/chipset_32px.png", ":/chipset_disabled_32px.png",
":/chipset_16px.png", ":/chipset_disabled_16px.png",
- i, "#system", pSettingsPage);
+ iPageIndex, "#system", pSettingsPage);
break;
}
/* Display page: */
case VMSettingsPage_Display:
{
- UISettingsPage *pSettingsPage = new UIMachineSettingsDisplay;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIMachineSettingsDisplay;
addItem(":/vrdp_32px.png", ":/vrdp_disabled_32px.png",
":/vrdp_16px.png", ":/vrdp_disabled_16px.png",
- i, "#display", pSettingsPage);
+ iPageIndex, "#display", pSettingsPage);
break;
}
/* Storage page: */
case VMSettingsPage_Storage:
{
- UISettingsPage *pSettingsPage = new UIMachineSettingsStorage;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIMachineSettingsStorage;
connect(pSettingsPage, SIGNAL(storageChanged()), this, SLOT(sltResetFirstRunFlag()));
addItem(":/hd_32px.png", ":/hd_disabled_32px.png",
":/attachment_16px.png", ":/attachment_disabled_16px.png",
- i, "#storage", pSettingsPage);
+ iPageIndex, "#storage", pSettingsPage);
break;
}
/* Audio page: */
case VMSettingsPage_Audio:
{
- UISettingsPage *pSettingsPage = new UIMachineSettingsAudio;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIMachineSettingsAudio;
addItem(":/sound_32px.png", ":/sound_disabled_32px.png",
":/sound_16px.png", ":/sound_disabled_16px.png",
- i, "#audio", pSettingsPage);
+ iPageIndex, "#audio", pSettingsPage);
break;
}
/* Network page: */
case VMSettingsPage_Network:
{
- UISettingsPage *pSettingsPage = new UIMachineSettingsNetworkPage;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIMachineSettingsNetworkPage;
addItem(":/nw_32px.png", ":/nw_disabled_32px.png",
":/nw_16px.png", ":/nw_disabled_16px.png",
- i, "#network", pSettingsPage);
+ iPageIndex, "#network", pSettingsPage);
break;
}
/* Ports page: */
@@ -598,59 +636,60 @@ UIVMSettingsDlg::UIVMSettingsDlg(QWidget *pParent,
{
addItem(":/serial_port_32px.png", ":/serial_port_disabled_32px.png",
":/serial_port_16px.png", ":/serial_port_disabled_16px.png",
- i, "#ports");
+ iPageIndex, "#ports");
break;
}
/* Serial page: */
case VMSettingsPage_Serial:
{
- UISettingsPage *pSettingsPage = new UIMachineSettingsSerialPage;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIMachineSettingsSerialPage;
addItem(":/serial_port_32px.png", ":/serial_port_disabled_32px.png",
":/serial_port_16px.png", ":/serial_port_disabled_16px.png",
- i, "#serialPorts", pSettingsPage, VMSettingsPage_Ports);
+ iPageIndex, "#serialPorts", pSettingsPage, VMSettingsPage_Ports);
break;
}
/* Parallel page: */
case VMSettingsPage_Parallel:
{
- UISettingsPage *pSettingsPage = new UIMachineSettingsParallelPage;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIMachineSettingsParallelPage;
addItem(":/parallel_port_32px.png", ":/parallel_port_disabled_32px.png",
":/parallel_port_16px.png", ":/parallel_port_disabled_16px.png",
- i, "#parallelPorts", pSettingsPage, VMSettingsPage_Ports);
+ iPageIndex, "#parallelPorts", pSettingsPage, VMSettingsPage_Ports);
break;
}
/* USB page: */
case VMSettingsPage_USB:
{
- UISettingsPage *pSettingsPage = new UIMachineSettingsUSB(UISettingsPageType_Machine);
- pSettingsPage->setId(i);
+ pSettingsPage = new UIMachineSettingsUSB(UISettingsPageType_Machine);
addItem(":/usb_32px.png", ":/usb_disabled_32px.png",
":/usb_16px.png", ":/usb_disabled_16px.png",
- i, "#usb", pSettingsPage, VMSettingsPage_Ports);
+ iPageIndex, "#usb", pSettingsPage, VMSettingsPage_Ports);
break;
}
/* Shared Folders page: */
case VMSettingsPage_SF:
{
- UISettingsPage *pSettingsPage = new UIMachineSettingsSF;
- pSettingsPage->setId(i);
+ pSettingsPage = new UIMachineSettingsSF;
addItem(":/shared_folder_32px.png", ":/shared_folder_disabled_32px.png",
":/shared_folder_16px.png", ":/shared_folder_disabled_16px.png",
- i, "#sfolders", pSettingsPage);
+ iPageIndex, "#sfolders", pSettingsPage);
break;
}
default:
break;
}
+ if (pSettingsPage)
+ {
+ pSettingsPage->setDialogType(dialogType());
+ pSettingsPage->setId(iPageIndex);
+ }
}
}
/* Retranslate UI: */
retranslateUi();
- /* Setup Settings Dialog: */
+ /* Setup settings dialog: */
if (!strCategory.isNull())
{
m_pSelector->selectByLink(strCategory);
@@ -684,15 +723,36 @@ UIVMSettingsDlg::UIVMSettingsDlg(QWidget *pParent,
m_pSelector->selectById(0);
}
-void UIVMSettingsDlg::getFrom()
+void UISettingsDialogMachine::loadData()
{
+ /* Check that session is NOT created: */
+ if (!m_session.isNull())
+ return;
+
+ /* Call for base-class: */
+ UISettingsDialog::loadData();
+
+ /* Disconnect global VBox events from this dialog: */
+ gVBoxEvents->disconnect(this);
+
+ /* Prepare session: */
+ m_session = dialogType() == SettingsDialogType_Wrong ? CSession() : vboxGlobal().openSession(m_strMachineId, true /* shared */);
+ /* Check that session was created: */
+ if (m_session.isNull())
+ return;
+
+ /* Get machine from session: */
+ m_machine = m_session.GetMachine();
+ /* Get console from session: */
+ m_console = dialogType() == SettingsDialogType_Offline ? CConsole() : m_session.GetConsole();
+
/* Prepare machine data: */
qRegisterMetaType<UISettingsDataMachine>();
- UISettingsDataMachine data(m_machine);
+ UISettingsDataMachine data(m_machine, m_console);
/* Create machine settings loader,
* it will load machine settings & delete itself in the appropriate time: */
UISettingsSerializer *pMachineSettingsLoader = new UISettingsSerializer(this, QVariant::fromValue(data), UISettingsSerializeDirection_Load);
- connect(pMachineSettingsLoader, SIGNAL(destroyed(QObject*)), this, SLOT(sltMarkProcessed()));
+ connect(pMachineSettingsLoader, SIGNAL(destroyed(QObject*)), this, SLOT(sltMarkLoaded()));
connect(pMachineSettingsLoader, SIGNAL(sigNotifyAboutPagesProcessed()), this, SLOT(sltSetFirstRunFlag()));
/* Set pages to be loaded: */
pMachineSettingsLoader->setPageList(m_pSelector->settingPages());
@@ -704,11 +764,33 @@ void UIVMSettingsDlg::getFrom()
pMachineSettingsLoader->waitForPageToBeProcessed(m_pSelector->currentId());
}
-void UIVMSettingsDlg::putBackTo()
+void UISettingsDialogMachine::saveData()
{
+ /* Check that session is NOT created: */
+ if (!m_session.isNull())
+ return;
+
+ /* Call for base-class: */
+ UISettingsDialog::saveData();
+
+ /* Disconnect global VBox events from this dialog: */
+ gVBoxEvents->disconnect(this);
+
+ /* Prepare session: */
+ bool fSessionShared = dialogType() != SettingsDialogType_Offline;
+ m_session = dialogType() == SettingsDialogType_Wrong ? CSession() : vboxGlobal().openSession(m_strMachineId, fSessionShared);
+ /* Check that session was created: */
+ if (m_session.isNull())
+ return;
+
+ /* Get machine from session: */
+ m_machine = m_session.GetMachine();
+ /* Get console from session: */
+ m_console = dialogType() == SettingsDialogType_Offline ? CConsole() : m_session.GetConsole();
+
/* Prepare machine data: */
qRegisterMetaType<UISettingsDataMachine>();
- UISettingsDataMachine data(m_machine);
+ UISettingsDataMachine data(m_machine, m_console);
/* Create machine settings saver,
* it will save machine settings & delete itself in the appropriate time: */
UISettingsSerializer *pMachineSettingsSaver = new UISettingsSerializer(this, QVariant::fromValue(data), UISettingsSerializeDirection_Save);
@@ -756,16 +838,20 @@ void UIVMSettingsDlg::putBackTo()
* the boot order or disk configuration were changed: */
if (m_fResetFirstRunFlag)
m_machine.SetExtraData(VBoxDefs::GUI_FirstRun, QString::null);
+
+ /* Save settings finally: */
+ m_machine.SaveSettings();
}
- /* If machine is NOT ok => show error message: */
- else
- {
- /* Show final error message: */
+
+ /* If machine is NOT ok => show the error message: */
+ if (!m_machine.isOk())
vboxProblem().cannotSaveMachineSettings(m_machine);
- }
+
+ /* Mark page processed: */
+ sltMarkSaved();
}
-void UIVMSettingsDlg::retranslateUi()
+void UISettingsDialogMachine::retranslateUi()
{
/* We have to make sure that the Network, Serial & Parallel pages are retranslated
* before they are revalidated. Cause: They do string comparing within
@@ -821,132 +907,139 @@ void UIVMSettingsDlg::retranslateUi()
m_pSelector->polish();
}
-QString UIVMSettingsDlg::title() const
+QString UISettingsDialogMachine::title() const
{
QString strDialogTitle;
- if (!m_machine.isNull())
- strDialogTitle = tr("%1 - %2").arg(m_machine.GetName()).arg(titleExtension());
+ /* Get corresponding machine (required to compose dialog title): */
+ const CMachine &machine = vboxGlobal().virtualBox().FindMachine(m_strMachineId);
+ if (!machine.isNull())
+ strDialogTitle = tr("%1 - %2").arg(machine.GetName()).arg(titleExtension());
return strDialogTitle;
}
-bool UIVMSettingsDlg::recorrelate(QWidget *pPage, QString &strWarning)
+void UISettingsDialogMachine::recorrelate(UISettingsPage *pSettingsPage)
{
- /* This method performs correlation option check
- * between different pages of VM Settings dialog: */
-
- if (pPage == m_pSelector->idToPage(VMSettingsPage_General))
+ switch (pSettingsPage->id())
{
- /* Get General & System pages: */
- UIMachineSettingsGeneral *pGeneralPage =
- qobject_cast<UIMachineSettingsGeneral*>(m_pSelector->idToPage(VMSettingsPage_General));
- UIMachineSettingsSystem *pSystemPage =
- qobject_cast<UIMachineSettingsSystem*>(m_pSelector->idToPage(VMSettingsPage_System));
-
- /* Guest OS type & VT-x/AMD-V option correlation test: */
- if (pGeneralPage && pSystemPage &&
- pGeneralPage->is64BitOSTypeSelected() && !pSystemPage->isHWVirtExEnabled())
+ case VMSettingsPage_General:
{
- strWarning = tr(
- "you have selected a 64-bit guest OS type for this VM. As such guests "
- "require hardware virtualization (VT-x/AMD-V), this feature will be enabled "
- "automatically.");
- return true;
+ UIMachineSettingsGeneral *pGeneralPage = qobject_cast<UIMachineSettingsGeneral*>(pSettingsPage);
+ UIMachineSettingsSystem *pSystemPage = qobject_cast<UIMachineSettingsSystem*>(m_pSelector->idToPage(VMSettingsPage_System));
+ if (pGeneralPage && pSystemPage)
+ pGeneralPage->setHWVirtExEnabled(pSystemPage->isHWVirtExEnabled());
+ break;
}
- }
-
-#if defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_WITH_CRHGSMI)
- /* 2D Video Acceleration is available for Windows guests only: */
- if (pPage == m_pSelector->idToPage(VMSettingsPage_Display))
- {
- /* Get General & Display pages: */
- UIMachineSettingsGeneral *pGeneralPage =
- qobject_cast<UIMachineSettingsGeneral*>(m_pSelector->idToPage(VMSettingsPage_General));
- UIMachineSettingsDisplay *pDisplayPage =
- qobject_cast<UIMachineSettingsDisplay*>(m_pSelector->idToPage(VMSettingsPage_Display));
-#ifdef VBOX_WITH_CRHGSMI
- if (pGeneralPage && pDisplayPage)
+ case VMSettingsPage_Display:
{
- bool bWddmSupported = pGeneralPage->isWddmSupportedForOSType();
- pDisplayPage->setWddmMode(bWddmSupported);
+ UIMachineSettingsDisplay *pDisplayPage = qobject_cast<UIMachineSettingsDisplay*>(pSettingsPage);
+ UIMachineSettingsGeneral *pGeneralPage = qobject_cast<UIMachineSettingsGeneral*>(m_pSelector->idToPage(VMSettingsPage_General));
+ if (pDisplayPage && pGeneralPage)
+ pDisplayPage->setGuestOSType(pGeneralPage->guestOSType());
+ break;
}
-#endif
-#ifdef VBOX_WITH_VIDEOHWACCEL
- if (pGeneralPage && pDisplayPage &&
- pDisplayPage->isAcceleration2DVideoSelected() && !pGeneralPage->isWindowsOSTypeSelected())
+ case VMSettingsPage_System:
{
- strWarning = tr(
- "you have 2D Video Acceleration enabled. As 2D Video Acceleration "
- "is supported for Windows guests only, this feature will be disabled.");
- return true;
+ UIMachineSettingsSystem *pSystemPage = qobject_cast<UIMachineSettingsSystem*>(pSettingsPage);
+ UIMachineSettingsUSB *pUsbPage = qobject_cast<UIMachineSettingsUSB*>(m_pSelector->idToPage(VMSettingsPage_USB));
+ if (pSystemPage && pUsbPage)
+ pSystemPage->setOHCIEnabled(pUsbPage->isOHCIEnabled());
+ break;
}
-#endif
+ case VMSettingsPage_Storage:
+ {
+ UIMachineSettingsStorage *pStoragePage = qobject_cast<UIMachineSettingsStorage*>(pSettingsPage);
+ UIMachineSettingsSystem *pSystemPage = qobject_cast<UIMachineSettingsSystem*>(m_pSelector->idToPage(VMSettingsPage_System));
+ if (pStoragePage && pSystemPage)
+ pStoragePage->setChipsetType(pSystemPage->chipsetType());
+ break;
+ }
+ default:
+ break;
}
-#endif /* VBOX_WITH_VIDEOHWACCEL */
+}
+
+void UISettingsDialogMachine::sltMarkLoaded()
+{
+ /* Call for base-class: */
+ UISettingsDialog::sltMarkLoaded();
- if (pPage == m_pSelector->idToPage(VMSettingsPage_System))
+ /* Unlock the session if exists: */
+ if (!m_session.isNull())
{
- /* Get System & USB pages: */
- UIMachineSettingsSystem *pSystemPage =
- qobject_cast<UIMachineSettingsSystem*>(m_pSelector->idToPage(VMSettingsPage_System));
- UIMachineSettingsUSB *pUsbPage =
- qobject_cast<UIMachineSettingsUSB*>(m_pSelector->idToPage(VMSettingsPage_USB));
- if (pSystemPage && pUsbPage &&
- pSystemPage->isHIDEnabled() && !pUsbPage->isOHCIEnabled())
- {
- strWarning = tr(
- "you have enabled a USB HID (Human Interface Device). "
- "This will not work unless USB emulation is also enabled. "
- "This will be done automatically when you accept the VM Settings "
- "by pressing the OK button.");
- return true;
- }
+ m_session.UnlockMachine();
+ m_session = CSession();
+ m_machine = CMachine();
+ m_console = CConsole();
}
- if (pPage == m_pSelector->idToPage(VMSettingsPage_Storage))
+ /* Make sure settings dialog will be updated on machine state/data changes: */
+ connect(gVBoxEvents, SIGNAL(sigMachineStateChange(QString, KMachineState)),
+ this, SLOT(sltMachineStateChanged(QString, KMachineState)));
+ connect(gVBoxEvents, SIGNAL(sigMachineDataChange(QString)),
+ this, SLOT(sltMachineDataChanged(QString)));
+}
+
+void UISettingsDialogMachine::sltMarkSaved()
+{
+ /* Call for base-class: */
+ UISettingsDialog::sltMarkSaved();
+
+ /* Unlock the session if exists: */
+ if (!m_session.isNull())
{
- /* Get System & Storage pages: */
- UIMachineSettingsSystem *pSystemPage =
- qobject_cast<UIMachineSettingsSystem*>(m_pSelector->idToPage(VMSettingsPage_System));
- UIMachineSettingsStorage *pStoragePage =
- qobject_cast<UIMachineSettingsStorage*>(m_pSelector->idToPage(VMSettingsPage_Storage));
- if (pSystemPage && pStoragePage)
- {
- /* Update chiset type for the Storage settings page: */
- if (pStoragePage->chipsetType() != pSystemPage->chipsetType())
- pStoragePage->setChipsetType(pSystemPage->chipsetType());
- /* Check for excessive controllers on Storage page controllers list: */
- QStringList excessiveList;
- QMap<KStorageBus, int> currentType = pStoragePage->currentControllerTypes();
- QMap<KStorageBus, int> maximumType = pStoragePage->maximumControllerTypes();
- for (int iStorageBusType = KStorageBus_IDE; iStorageBusType <= KStorageBus_SAS; ++iStorageBusType)
- {
- if (currentType[(KStorageBus)iStorageBusType] > maximumType[(KStorageBus)iStorageBusType])
- {
- QString strExcessiveRecord = QString("%1 (%2)");
- strExcessiveRecord = strExcessiveRecord.arg(QString("<b>%1</b>").arg(vboxGlobal().toString((KStorageBus)iStorageBusType)));
- strExcessiveRecord = strExcessiveRecord.arg(maximumType[(KStorageBus)iStorageBusType] == 1 ?
- tr("at most one supported") :
- tr("up to %1 supported").arg(maximumType[(KStorageBus)iStorageBusType]));
- excessiveList << strExcessiveRecord;
- }
- }
- if (!excessiveList.isEmpty())
- {
- strWarning = tr(
- "you are currently using more storage controllers than a %1 chipset supports. "
- "Please change the chipset type on the System settings page or reduce the number "
- "of the following storage controllers on the Storage settings page: %2.")
- .arg(vboxGlobal().toString(pStoragePage->chipsetType()))
- .arg(excessiveList.join(", "));
- return false;
- }
- }
+ m_session.UnlockMachine();
+ m_session = CSession();
+ m_machine = CMachine();
+ m_console = CConsole();
}
+}
- return true;
+void UISettingsDialogMachine::sltMachineStateChanged(QString strMachineId, KMachineState machineState)
+{
+ /* Ignore if thats NOT our VM: */
+ if (strMachineId != m_strMachineId)
+ return;
+
+ /* Ignore if state was NOT actually changed: */
+ if (m_machineState == machineState)
+ return;
+
+ /* Update current machine state: */
+ m_machineState = machineState;
+
+ /* Get new dialog type: */
+ SettingsDialogType newDialogType = machineStateToSettingsDialogType(m_machineState);
+
+ /* Ignore if dialog type was NOT actually changed: */
+ if (dialogType() == newDialogType)
+ return;
+
+ /* Should we show a warning about leaving 'offline' state? */
+ bool fShouldWe = dialogType() == SettingsDialogType_Offline;
+
+ /* Update current dialog type: */
+ setDialogType(newDialogType);
+
+ /* Show a warning about leaving 'offline' state if we should: */
+ if (isSettingsChanged() && fShouldWe)
+ vboxProblem().warnAboutStateChange(this);
+}
+
+void UISettingsDialogMachine::sltMachineDataChanged(QString strMachineId)
+{
+ /* Ignore if thats NOT our VM: */
+ if (strMachineId != m_strMachineId)
+ return;
+
+ /* Check if user had changed something and warn him about he will loose settings on reloading: */
+ if (isSettingsChanged() && !vboxProblem().confirmedSettingsReloading(this))
+ return;
+
+ /* Reload data: */
+ loadData();
}
-void UIVMSettingsDlg::sltCategoryChanged(int cId)
+void UISettingsDialogMachine::sltCategoryChanged(int cId)
{
if (UISettingsSerializer::instance())
UISettingsSerializer::instance()->raisePriorityOfPage(cId);
@@ -954,23 +1047,23 @@ void UIVMSettingsDlg::sltCategoryChanged(int cId)
UISettingsDialog::sltCategoryChanged(cId);
}
-void UIVMSettingsDlg::sltAllowResetFirstRunFlag()
+void UISettingsDialogMachine::sltAllowResetFirstRunFlag()
{
m_fAllowResetFirstRunFlag = true;
}
-void UIVMSettingsDlg::sltSetFirstRunFlag()
+void UISettingsDialogMachine::sltSetFirstRunFlag()
{
m_fResetFirstRunFlag = false;
}
-void UIVMSettingsDlg::sltResetFirstRunFlag()
+void UISettingsDialogMachine::sltResetFirstRunFlag()
{
if (m_fAllowResetFirstRunFlag)
m_fResetFirstRunFlag = true;
}
-bool UIVMSettingsDlg::isAvailable(int id)
+bool UISettingsDialogMachine::isPageAvailable(int iPageId)
{
if (m_machine.isNull())
return false;
@@ -978,19 +1071,19 @@ bool UIVMSettingsDlg::isAvailable(int id)
/* Show the machine error message for particular group if present.
* We don't use the generic cannotLoadMachineSettings()
* call here because we want this message to be suppressible. */
- switch (id)
+ switch (iPageId)
{
case VMSettingsPage_Serial:
{
/* Depends on ports availability: */
- if (!isAvailable(VMSettingsPage_Ports))
+ if (!isPageAvailable(VMSettingsPage_Ports))
return false;
break;
}
case VMSettingsPage_Parallel:
{
/* Depends on ports availability: */
- if (!isAvailable(VMSettingsPage_Ports))
+ if (!isPageAvailable(VMSettingsPage_Ports))
return false;
/* But for now this page is always disabled: */
return false;
@@ -998,7 +1091,7 @@ bool UIVMSettingsDlg::isAvailable(int id)
case VMSettingsPage_USB:
{
/* Depends on ports availability: */
- if (!isAvailable(VMSettingsPage_Ports))
+ if (!isPageAvailable(VMSettingsPage_Ports))
return false;
/* Get the USB controller object: */
CUSBController controller = m_machine.GetUSBController();
@@ -1016,5 +1109,18 @@ bool UIVMSettingsDlg::isAvailable(int id)
return true;
}
+bool UISettingsDialogMachine::isSettingsChanged()
+{
+ bool fIsSettingsChanged = false;
+ for (int iWidgetNumber = 0; iWidgetNumber < m_pStack->count() && !fIsSettingsChanged; ++iWidgetNumber)
+ {
+ UISettingsPage *pPage = static_cast<UISettingsPage*>(m_pStack->widget(iWidgetNumber));
+ pPage->putToCache();
+ if (pPage->changed())
+ fIsSettingsChanged = true;
+ }
+ return fIsSettingsChanged;
+}
+
# include "UISettingsDialogSpecific.moc"
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.h b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.h
index 2c4efce41..c44e8650a 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.h
@@ -5,7 +5,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;
@@ -24,7 +24,7 @@
#include "UISettingsDialog.h"
/* Dialog which encapsulate all the specific functionalities of the Global Settings */
-class UIGLSettingsDlg : public UISettingsDialog
+class UISettingsDialogGlobal : public UISettingsDialog
{
Q_OBJECT;
@@ -39,15 +39,16 @@ public:
GLSettingsPage_USB,
GLSettingsPage_Network,
GLSettingsPage_Extension,
+ GLSettingsPage_Proxy,
GLSettingsPage_MAX
};
- UIGLSettingsDlg(QWidget *pParent);
+ UISettingsDialogGlobal(QWidget *pParent);
protected:
- void getFrom();
- void putBackTo();
+ void loadData();
+ void saveData();
void retranslateUi();
@@ -55,11 +56,11 @@ protected:
private:
- bool isAvailable(int id);
+ bool isPageAvailable(int iPageId);
};
/* Dialog which encapsulate all the specific functionalities of the Virtual Machine Settings */
-class UIVMSettingsDlg : public UISettingsDialog
+class UISettingsDialogMachine : public UISettingsDialog
{
Q_OBJECT;
@@ -81,22 +82,26 @@ public:
VMSettingsPage_MAX
};
- UIVMSettingsDlg(QWidget *pParent, const CMachine &machine,
- const QString &strCategory, const QString &strControl);
+ UISettingsDialogMachine(QWidget *pParent, const QString &strMachineId,
+ const QString &strCategory, const QString &strControl);
protected:
- void getFrom();
- void putBackTo();
+ void loadData();
+ void saveData();
void retranslateUi();
QString title() const;
- bool recorrelate(QWidget *pPage, QString &strWarning);
+ void recorrelate(UISettingsPage *pSettingsPage);
private slots:
+ void sltMarkLoaded();
+ void sltMarkSaved();
+ void sltMachineStateChanged(QString strMachineId, KMachineState machineState);
+ void sltMachineDataChanged(QString strMachineId);
void sltCategoryChanged(int cId);
void sltAllowResetFirstRunFlag();
void sltSetFirstRunFlag();
@@ -104,9 +109,16 @@ private slots:
private:
- bool isAvailable(int id);
+ bool isPageAvailable(int iPageId);
+ bool isSettingsChanged();
+ QString m_strMachineId;
+ KMachineState m_machineState;
+
+ CSession m_session;
CMachine m_machine;
+ CConsole m_console;
+
bool m_fAllowResetFirstRunFlag;
bool m_fResetFirstRunFlag;
};
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.cpp b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.cpp
index 3efa83fd6..7864714f6 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.cpp
@@ -1,4 +1,4 @@
-/* $Id: UISettingsPage.cpp $ */
+/* $Id: UISettingsPage.cpp 36594 2011-04-06 16:22:58Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,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;
@@ -20,72 +20,10 @@
/* Local includes */
#include "UISettingsPage.h"
-/* Returns settings page type: */
-UISettingsPageType UISettingsPage::type() const
-{
- return m_type;
-}
-
-/* Validation stuff: */
-void UISettingsPage::setValidator(QIWidgetValidator *pValidator)
-{
- Q_UNUSED(pValidator);
-}
-
-/* Validation stuff: */
-bool UISettingsPage::revalidate(QString &strWarningText, QString &strTitle)
-{
- Q_UNUSED(strWarningText);
- Q_UNUSED(strTitle);
- return true;
-}
-
-/* Navigation stuff: */
-void UISettingsPage::setOrderAfter(QWidget *pWidget)
-{
- m_pFirstWidget = pWidget;
-}
-
-/* Page 'ID' stuff: */
-int UISettingsPage::id() const
-{
- return m_cId;
-}
-
-/* Page 'ID' stuff: */
-void UISettingsPage::setId(int cId)
-{
- m_cId = cId;
-}
-
-/* Page 'processed' stuff: */
-bool UISettingsPage::processed() const
-{
- return m_fProcessed;
-}
-
-/* Page 'processed' stuff: */
-void UISettingsPage::setProcessed(bool fProcessed)
-{
- m_fProcessed = fProcessed;
-}
-
-/* Page 'failed' stuff: */
-bool UISettingsPage::failed() const
-{
- return m_fFailed;
-}
-
-/* Page 'failed' stuff: */
-void UISettingsPage::setFailed(bool fFailed)
-{
- m_fFailed = fFailed;
-}
-
/* Settings page constructor, hidden: */
-UISettingsPage::UISettingsPage(UISettingsPageType type, QWidget *pParent)
- : QIWithRetranslateUI<QWidget>(pParent)
- , m_type(type)
+UISettingsPage::UISettingsPage(UISettingsPageType pageType)
+ : m_pageType(pageType)
+ , m_dialogType(SettingsDialogType_Wrong)
, m_cId(-1)
, m_fProcessed(false)
, m_fFailed(false)
@@ -93,6 +31,12 @@ UISettingsPage::UISettingsPage(UISettingsPageType type, QWidget *pParent)
{
}
+/* Global settings page constructor, hidden: */
+UISettingsPageGlobal::UISettingsPageGlobal()
+ : UISettingsPage(UISettingsPageType_Global)
+{
+}
+
/* Fetch data to m_properties & m_settings: */
void UISettingsPageGlobal::fetchData(const QVariant &data)
{
@@ -106,27 +50,22 @@ void UISettingsPageGlobal::uploadData(QVariant &data) const
data = QVariant::fromValue(UISettingsDataGlobal(m_properties, m_settings));
}
-/* Global settings page constructor, hidden: */
-UISettingsPageGlobal::UISettingsPageGlobal(QWidget *pParent)
- : UISettingsPage(UISettingsPageType_Global, pParent)
+/* Machine settings page constructor, hidden: */
+UISettingsPageMachine::UISettingsPageMachine()
+ : UISettingsPage(UISettingsPageType_Machine)
{
}
-/* Fetch data to m_machine: */
+/* Fetch data to m_machine & m_console: */
void UISettingsPageMachine::fetchData(const QVariant &data)
{
m_machine = data.value<UISettingsDataMachine>().m_machine;
+ m_console = data.value<UISettingsDataMachine>().m_console;
}
-/* Upload m_machine to data: */
+/* Upload m_machine & m_console to data: */
void UISettingsPageMachine::uploadData(QVariant &data) const
{
- data = QVariant::fromValue(UISettingsDataMachine(m_machine));
-}
-
-/* Machine settings page constructor, hidden: */
-UISettingsPageMachine::UISettingsPageMachine(QWidget *pParent)
- : UISettingsPage(UISettingsPageType_Machine, pParent)
-{
+ data = QVariant::fromValue(UISettingsDataMachine(m_machine, m_console));
}
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.h b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.h
index 3f64998c3..854138017 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.h
@@ -5,7 +5,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;
@@ -19,17 +19,22 @@
#ifndef __UISettingsPage_h__
#define __UISettingsPage_h__
-/* Global includes */
+/* Qt includes */
#include <QWidget>
#include <QVariant>
-/* Local includes */
+/* Other includes */
#include "QIWithRetranslateUI.h"
#include "COMDefs.h"
+#include "UISettingsDefs.h"
#include "VBoxGlobalSettings.h"
/* Forward declarations */
class QIWidgetValidator;
+class QShowEvent;
+
+/* Using declarations: */
+using namespace UISettingsDefs;
/* Settings page types: */
enum UISettingsPageType
@@ -53,9 +58,10 @@ Q_DECLARE_METATYPE(UISettingsDataGlobal);
struct UISettingsDataMachine
{
UISettingsDataMachine() {}
- UISettingsDataMachine(const CMachine &machine)
- : m_machine(machine) {}
+ UISettingsDataMachine(const CMachine &machine, const CConsole &console)
+ : m_machine(machine), m_console(console) {}
CMachine m_machine;
+ CConsole m_console;
};
Q_DECLARE_METATYPE(UISettingsDataMachine);
@@ -80,35 +86,53 @@ public:
* this task COULD be performed in other than GUI thread: */
virtual void saveFromCacheTo(QVariant &data) = 0;
- /* Returns settings page type: */
- virtual UISettingsPageType type() const;
-
/* Validation stuff: */
- virtual void setValidator(QIWidgetValidator *pValidator);
- virtual bool revalidate(QString &strWarningText, QString &strTitle);
+ virtual void setValidator(QIWidgetValidator* /* pValidator */) {}
+ virtual bool revalidate(QString& /* strWarningText */, QString& /* strTitle */) { return true; }
/* Navigation stuff: */
- virtual void setOrderAfter(QWidget *pWidget);
+ QWidget* firstWidget() const { return m_pFirstWidget; }
+ virtual void setOrderAfter(QWidget *pWidget) { m_pFirstWidget = pWidget; }
+
+ /* Settings page type stuff: */
+ UISettingsPageType pageType() const { return m_pageType; }
+
+ /* Settings dialog type stuff: */
+ SettingsDialogType dialogType() const { return m_dialogType; }
+ virtual void setDialogType(SettingsDialogType settingsDialogType) { m_dialogType = settingsDialogType; polishPage(); }
+ bool isMachineOffline() const { return dialogType() == SettingsDialogType_Offline; }
+ bool isMachineSaved() const { return dialogType() == SettingsDialogType_Saved; }
+ bool isMachineOnline() const { return dialogType() == SettingsDialogType_Online; }
+ bool isMachineInValidMode() const { return isMachineOffline() || isMachineSaved() || isMachineOnline(); }
+
+ /* Page changed: */
+ virtual bool changed() const = 0;
/* Page 'ID' stuff: */
- int id() const;
- void setId(int cId);
+ int id() const { return m_cId; }
+ void setId(int cId) { m_cId = cId; }
/* Page 'processed' stuff: */
- bool processed() const;
- void setProcessed(bool fProcessed);
+ bool processed() const { return m_fProcessed; }
+ void setProcessed(bool fProcessed) { m_fProcessed = fProcessed; }
/* Page 'failed' stuff: */
- bool failed() const;
- void setFailed(bool fFailed);
+ bool failed() const { return m_fFailed; }
+ void setFailed(bool fFailed) { m_fFailed = fFailed; }
+
+ /* Virtual function to polish page content: */
+ virtual void polishPage() {}
protected:
/* Settings page constructor, hidden: */
- UISettingsPage(UISettingsPageType type, QWidget *pParent = 0);
+ UISettingsPage(UISettingsPageType type);
+
+private:
- /* Variables: */
- UISettingsPageType m_type;
+ /* Private variables: */
+ UISettingsPageType m_pageType;
+ SettingsDialogType m_dialogType;
int m_cId;
bool m_fProcessed;
bool m_fFailed;
@@ -122,14 +146,17 @@ class UISettingsPageGlobal : public UISettingsPage
protected:
+ /* Global settings page constructor, hidden: */
+ UISettingsPageGlobal();
+
/* Fetch data to m_properties & m_settings: */
void fetchData(const QVariant &data);
/* Upload m_properties & m_settings to data: */
void uploadData(QVariant &data) const;
- /* Global settings page constructor, hidden: */
- UISettingsPageGlobal(QWidget *pParent = 0);
+ /* Page changed: */
+ bool changed() const { return false; }
/* Global data source: */
CSystemProperties m_properties;
@@ -143,17 +170,18 @@ class UISettingsPageMachine : public UISettingsPage
protected:
+ /* Machine settings page constructor, hidden: */
+ UISettingsPageMachine();
+
/* Fetch data to m_machine: */
void fetchData(const QVariant &data);
/* Upload m_machine to data: */
void uploadData(QVariant &data) const;
- /* Machine settings page constructor, hidden: */
- UISettingsPageMachine(QWidget *pParent = 0);
-
/* Machine data source: */
CMachine m_machine;
+ CConsole m_console;
};
#endif // __UISettingsPage_h__
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/VBoxSettingsSelector.cpp b/src/VBox/Frontends/VirtualBox/src/settings/VBoxSettingsSelector.cpp
index ed11fcae5..63892d7c4 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/VBoxSettingsSelector.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/VBoxSettingsSelector.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxSettingsSelector.cpp $ */
+/* $Id: VBoxSettingsSelector.cpp 37610 2011-06-23 12:26:14Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp
index f5ce0fada..6b05fea2b 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIGlobalSettingsExtension.cpp $ */
+/* $Id: UIGlobalSettingsExtension.cpp 35279 2010-12-21 16:44:39Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsGeneral.cpp b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsGeneral.cpp
index 100621cbd..b2ca9c691 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsGeneral.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsGeneral.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIGlobalSettingsGeneral.cpp $ */
+/* $Id: UIGlobalSettingsGeneral.cpp 33926 2010-11-10 09:02:39Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsInput.cpp b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsInput.cpp
index 280628dea..e0d890de4 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsInput.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsInput.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIGlobalSettingsInput.cpp $ */
+/* $Id: UIGlobalSettingsInput.cpp 35862 2011-02-07 08:57:38Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsLanguage.cpp b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsLanguage.cpp
index 378cb37d8..afb4ee14b 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsLanguage.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsLanguage.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIGlobalSettingsLanguage.cpp $ */
+/* $Id: UIGlobalSettingsLanguage.cpp 35522 2011-01-13 13:06:44Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetwork.cpp b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetwork.cpp
index f0b53db34..e0372cfd3 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetwork.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetwork.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIGlobalSettingsNetwork.cpp $ */
+/* $Id: UIGlobalSettingsNetwork.cpp 35748 2011-01-28 07:15:04Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetworkDetails.cpp b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetworkDetails.cpp
index 75bd79265..5a6cfd831 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetworkDetails.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetworkDetails.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIGlobalSettingsNetworkDetails.cpp $ */
+/* $Id: UIGlobalSettingsNetworkDetails.cpp 34162 2010-11-18 12:04:47Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsProxy.cpp b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsProxy.cpp
new file mode 100644
index 000000000..13cd07cfb
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsProxy.cpp
@@ -0,0 +1,166 @@
+/* $Id: UIGlobalSettingsProxy.cpp 37548 2011-06-20 06:19:31Z vboxsync $ */
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * UIGlobalSettingsProxy class implementation
+ */
+
+/*
+ * 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.
+ */
+
+/* Global includes */
+#include <QRegExpValidator>
+
+/* Local includes */
+#include "QIWidgetValidator.h"
+#include "UIGlobalSettingsProxy.h"
+#include "VBoxUtils.h"
+
+/* General page constructor: */
+UIGlobalSettingsProxy::UIGlobalSettingsProxy()
+ : m_pValidator(0)
+{
+ /* Apply UI decorations: */
+ Ui::UIGlobalSettingsProxy::setupUi(this);
+
+ /* Setup widgets: */
+ m_pPortEditor->setFixedWidthByText(QString().fill('0', 6));
+ m_pHostEditor->setValidator(new QRegExpValidator(QRegExp("\\S+"), m_pHostEditor));
+ m_pPortEditor->setValidator(new QRegExpValidator(QRegExp("\\d+"), m_pPortEditor));
+ m_pLoginEditor->setValidator(new QRegExpValidator(QRegExp("\\S+"), m_pLoginEditor));
+ m_pPasswordEditor->setValidator(new QRegExpValidator(QRegExp("\\S+"), m_pPasswordEditor));
+
+ /* Setup connections: */
+ connect(m_pProxyCheckbox, SIGNAL(stateChanged(int)), this, SLOT(sltProxyToggled()));
+ connect(m_pAuthCheckbox, SIGNAL(stateChanged(int)), this, SLOT(sltAuthToggled()));
+
+ /* Apply language settings: */
+ retranslateUi();
+}
+
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void UIGlobalSettingsProxy::loadToCacheFrom(QVariant &data)
+{
+ /* Fetch data to properties & settings: */
+ UISettingsPageGlobal::fetchData(data);
+
+ /* Load to cache: */
+ UIProxyManager proxyManager(m_settings.proxySettings());
+ m_cache.m_fProxyEnabled = proxyManager.proxyEnabled();
+ m_cache.m_strProxyHost = proxyManager.proxyHost();
+ m_cache.m_strProxyPort = proxyManager.proxyPort();
+ m_cache.m_fAuthEnabled = proxyManager.authEnabled();
+ m_cache.m_strAuthLogin = proxyManager.authLogin();
+ m_cache.m_strAuthPassword = proxyManager.authPassword();
+
+ /* Upload properties & settings to data: */
+ UISettingsPageGlobal::uploadData(data);
+}
+
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void UIGlobalSettingsProxy::getFromCache()
+{
+ /* Fetch from cache: */
+ m_pProxyCheckbox->setChecked(m_cache.m_fProxyEnabled);
+ m_pHostEditor->setText(m_cache.m_strProxyHost);
+ m_pPortEditor->setText(m_cache.m_strProxyPort);
+ m_pAuthCheckbox->setChecked(m_cache.m_fAuthEnabled);
+ m_pLoginEditor->setText(m_cache.m_strAuthLogin);
+ m_pPasswordEditor->setText(m_cache.m_strAuthPassword);
+ sltProxyToggled();
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void UIGlobalSettingsProxy::putToCache()
+{
+ /* Upload to cache: */
+ m_cache.m_fProxyEnabled = m_pProxyCheckbox->isChecked();
+ m_cache.m_strProxyHost = m_pHostEditor->text();
+ m_cache.m_strProxyPort = m_pPortEditor->text();
+ m_cache.m_fAuthEnabled = m_pAuthCheckbox->isChecked();
+ m_cache.m_strAuthLogin = m_pLoginEditor->text();
+ m_cache.m_strAuthPassword = m_pPasswordEditor->text();
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void UIGlobalSettingsProxy::saveFromCacheTo(QVariant &data)
+{
+ /* Fetch data to properties & settings: */
+ UISettingsPageGlobal::fetchData(data);
+
+ UIProxyManager proxyManager;
+ proxyManager.setProxyEnabled(m_cache.m_fProxyEnabled);
+ proxyManager.setProxyHost(m_cache.m_strProxyHost);
+ proxyManager.setProxyPort(m_cache.m_strProxyPort);
+ proxyManager.setAuthEnabled(m_cache.m_fAuthEnabled);
+ proxyManager.setAuthLogin(m_cache.m_strAuthLogin);
+ proxyManager.setAuthPassword(m_cache.m_strAuthPassword);
+ m_settings.setProxySettings(proxyManager.toString());
+
+ /* Upload properties & settings to data: */
+ UISettingsPageGlobal::uploadData(data);
+}
+
+/* Validation stuff: */
+void UIGlobalSettingsProxy::setValidator(QIWidgetValidator *pValidator)
+{
+ m_pValidator = pValidator;
+}
+
+/* Navigation stuff: */
+void UIGlobalSettingsProxy::setOrderAfter(QWidget *pWidget)
+{
+ setTabOrder(pWidget, m_pProxyCheckbox);
+ setTabOrder(m_pProxyCheckbox, m_pHostEditor);
+ setTabOrder(m_pHostEditor, m_pPortEditor);
+ setTabOrder(m_pPortEditor, m_pAuthCheckbox);
+ setTabOrder(m_pAuthCheckbox, m_pLoginEditor);
+ setTabOrder(m_pLoginEditor, m_pPasswordEditor);
+}
+
+/* Translation stuff: */
+void UIGlobalSettingsProxy::retranslateUi()
+{
+ /* Translate uic generated strings: */
+ Ui::UIGlobalSettingsProxy::retranslateUi(this);
+}
+
+void UIGlobalSettingsProxy::sltProxyToggled()
+{
+ /* Update widgets availability: */
+ m_pHostLabel->setEnabled(m_pProxyCheckbox->isChecked());
+ m_pHostEditor->setEnabled(m_pProxyCheckbox->isChecked());
+ m_pPortLabel->setEnabled(m_pProxyCheckbox->isChecked());
+ m_pPortEditor->setEnabled(m_pProxyCheckbox->isChecked());
+ m_pAuthCheckbox->setEnabled(m_pProxyCheckbox->isChecked());
+
+ /* Update auth widgets also: */
+ sltAuthToggled();
+}
+
+void UIGlobalSettingsProxy::sltAuthToggled()
+{
+ /* Update widgets availability: */
+ m_pLoginLabel->setEnabled(m_pProxyCheckbox->isChecked() && m_pAuthCheckbox->isChecked());
+ m_pLoginEditor->setEnabled(m_pProxyCheckbox->isChecked() && m_pAuthCheckbox->isChecked());
+ m_pPasswordLabel->setEnabled(m_pProxyCheckbox->isChecked() && m_pAuthCheckbox->isChecked());
+ m_pPasswordEditor->setEnabled(m_pProxyCheckbox->isChecked() && m_pAuthCheckbox->isChecked());
+
+ /* Revalidate if possible: */
+ if (m_pValidator)
+ m_pValidator->revalidate();
+}
+
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsProxy.h b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsProxy.h
new file mode 100644
index 000000000..3b45f4b93
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsProxy.h
@@ -0,0 +1,88 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * UIGlobalSettingsProxy class declaration
+ */
+
+/*
+ * 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 __UIGlobalSettingsProxy_h__
+#define __UIGlobalSettingsProxy_h__
+
+/* Local includes */
+#include "UISettingsPage.h"
+#include "UIGlobalSettingsProxy.gen.h"
+
+/* Global settings / Proxy page / Cache: */
+struct UISettingsCacheGlobalProxy
+{
+ UISettingsCacheGlobalProxy() : m_fProxyEnabled(false), m_fAuthEnabled(false) {}
+ bool m_fProxyEnabled;
+ QString m_strProxyHost;
+ QString m_strProxyPort;
+ bool m_fAuthEnabled;
+ QString m_strAuthLogin;
+ QString m_strAuthPassword;
+};
+
+/* Global settings / Proxy page: */
+class UIGlobalSettingsProxy : public UISettingsPageGlobal, public Ui::UIGlobalSettingsProxy
+{
+ Q_OBJECT;
+
+public:
+
+ /* Constructor: */
+ UIGlobalSettingsProxy();
+
+protected:
+
+ /* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+ void loadToCacheFrom(QVariant &data);
+ /* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+ void getFromCache();
+
+ /* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+ void putToCache();
+ /* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+ void saveFromCacheTo(QVariant &data);
+
+ /* Validation stuff: */
+ void setValidator(QIWidgetValidator *pValidator);
+
+ /* Navigation stuff: */
+ void setOrderAfter(QWidget *pWidget);
+
+ /* Translation stuff: */
+ void retranslateUi();
+
+private slots:
+
+ void sltProxyToggled();
+ void sltAuthToggled();
+
+private:
+
+ /* Validator: */
+ QIWidgetValidator *m_pValidator;
+
+ /* Cache: */
+ UISettingsCacheGlobalProxy m_cache;
+};
+
+#endif // __UIGlobalSettingsProxy_h__
+
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsProxy.ui b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsProxy.ui
new file mode 100644
index 000000000..de14bc550
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsProxy.ui
@@ -0,0 +1,214 @@
+<ui version="4.0">
+ <comment>
+ VBox frontends: Qt4 GUI ("VirtualBox"):
+
+ 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.
+ </comment>
+ <class>UIGlobalSettingsProxy</class>
+ <widget class="QWidget" name="UIGlobalSettingsProxy">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>300</width>
+ <height>150</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="1" colspan="4">
+ <widget class="QCheckBox" name="m_pProxyCheckbox">
+ <property name="whatsThis">
+ <string>When checked, VirtualBox will use the proxy settings supplied for tasks like downloading Guest Additions from the network or checking for updates.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Enable proxy</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="2" colspan="3">
+ <layout class="QHBoxLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="m_pHostLabel">
+ <property name="text">
+ <string>Ho&amp;st:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>m_pHostEditor</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QILineEdit" name="m_pHostEditor">
+ <property name="whatsThis">
+ <string>Changes the proxy host.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="m_pPortLabel">
+ <property name="text">
+ <string>&amp;Port:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>m_pPortEditor</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QILineEdit" name="m_pPortEditor">
+ <property name="whatsThis">
+ <string>Changes the proxy port.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="2" colspan="3">
+ <widget class="QCheckBox" name="m_pAuthCheckbox">
+ <property name="whatsThis">
+ <string>When checked the authentication supplied will be used with the proxy server.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Use authentication</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2" rowspan="2">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="3">
+ <widget class="QLabel" name="m_pLoginLabel">
+ <property name="text">
+ <string>User &amp;name:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>m_pLoginEditor</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="4">
+ <widget class="QILineEdit" name="m_pLoginEditor">
+ <property name="whatsThis">
+ <string>Changes the user name used for authentication.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3">
+ <widget class="QLabel" name="m_pPasswordLabel">
+ <property name="text">
+ <string>Pass&amp;word:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>m_pPasswordEditor</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="4">
+ <widget class="QILineEdit" name="m_pPasswordEditor">
+ <property name="whatsThis">
+ <string>Changes the password used for authentication.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1" colspan="4">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QILineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>QILineEdit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsUpdate.cpp b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsUpdate.cpp
index b3d74537e..a9acc3c26 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsUpdate.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsUpdate.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIGlobalSettingsUpdate.cpp $ */
+/* $Id: UIGlobalSettingsUpdate.cpp 34166 2010-11-18 12:36:43Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsAudio.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsAudio.cpp
index d92508248..d0c9ca7be 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsAudio.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsAudio.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsAudio.cpp $ */
+/* $Id: UIMachineSettingsAudio.cpp 37126 2011-05-17 13:56:50Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,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,11 +35,24 @@ void UIMachineSettingsAudio::loadToCacheFrom(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Fill internal variables with corresponding values: */
- const CAudioAdapter &audio = m_machine.GetAudioAdapter();
- m_cache.m_fAudioEnabled = audio.GetEnabled();
- m_cache.m_audioDriverType = audio.GetAudioDriver();
- m_cache.m_audioControllerType = audio.GetAudioController();
+ /* Clear cache initially: */
+ m_cache.clear();
+
+ /* Prepare audio data: */
+ UIDataSettingsMachineAudio audioData;
+
+ /* Check if adapter is valid: */
+ const CAudioAdapter &adapter = m_machine.GetAudioAdapter();
+ if (!adapter.isNull())
+ {
+ /* Gather audio data: */
+ audioData.m_fAudioEnabled = adapter.GetEnabled();
+ audioData.m_audioDriverType = adapter.GetAudioDriver();
+ audioData.m_audioControllerType = adapter.GetAudioController();
+ }
+
+ /* Cache audio data: */
+ m_cache.cacheInitialData(audioData);
/* Upload machine to data: */
UISettingsPageMachine::uploadData(data);
@@ -49,20 +62,32 @@ void UIMachineSettingsAudio::loadToCacheFrom(QVariant &data)
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsAudio::getFromCache()
{
- /* Apply internal variables data to QWidget(s): */
- mGbAudio->setChecked(m_cache.m_fAudioEnabled);
- mCbAudioDriver->setCurrentIndex(mCbAudioDriver->findText(vboxGlobal().toString(m_cache.m_audioDriverType)));
- mCbAudioController->setCurrentIndex(mCbAudioController->findText(vboxGlobal().toString(m_cache.m_audioControllerType)));
+ /* Get audio data from cache: */
+ const UIDataSettingsMachineAudio &audioData = m_cache.base();
+
+ /* Load audio data to page: */
+ mGbAudio->setChecked(audioData.m_fAudioEnabled);
+ mCbAudioDriver->setCurrentIndex(mCbAudioDriver->findText(vboxGlobal().toString(audioData.m_audioDriverType)));
+ mCbAudioController->setCurrentIndex(mCbAudioController->findText(vboxGlobal().toString(audioData.m_audioControllerType)));
+
+ /* Polish page finally: */
+ polishPage();
}
/* Save data from corresponding widgets to cache,
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsAudio::putToCache()
{
- /* Gather internal variables data from QWidget(s): */
- m_cache.m_fAudioEnabled = mGbAudio->isChecked();
- m_cache.m_audioDriverType = vboxGlobal().toAudioDriverType(mCbAudioDriver->currentText());
- m_cache.m_audioControllerType = vboxGlobal().toAudioControllerType(mCbAudioController->currentText());
+ /* Prepare audio data: */
+ UIDataSettingsMachineAudio audioData = m_cache.base();
+
+ /* Gather audio data: */
+ audioData.m_fAudioEnabled = mGbAudio->isChecked();
+ audioData.m_audioDriverType = vboxGlobal().toAudioDriverType(mCbAudioDriver->currentText());
+ audioData.m_audioControllerType = vboxGlobal().toAudioControllerType(mCbAudioController->currentText());
+
+ /* Cache audio data: */
+ m_cache.cacheCurrentData(audioData);
}
/* Save data from cache to corresponding external object(s),
@@ -72,11 +97,25 @@ void UIMachineSettingsAudio::saveFromCacheTo(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Gather corresponding values from internal variables: */
- CAudioAdapter audio = m_machine.GetAudioAdapter();
- audio.SetEnabled(m_cache.m_fAudioEnabled);
- audio.SetAudioDriver(m_cache.m_audioDriverType);
- audio.SetAudioController(m_cache.m_audioControllerType);
+ /* Check if audio data was changed: */
+ if (m_cache.wasChanged())
+ {
+ /* Check if adapter still valid: */
+ CAudioAdapter adapter = m_machine.GetAudioAdapter();
+ if (!adapter.isNull())
+ {
+ /* Get audio data from cache: */
+ const UIDataSettingsMachineAudio &audioData = m_cache.data();
+
+ /* Store audio data: */
+ if (isMachineOffline())
+ {
+ adapter.SetEnabled(audioData.m_fAudioEnabled);
+ adapter.SetAudioDriver(audioData.m_audioDriverType);
+ adapter.SetAudioController(audioData.m_audioControllerType);
+ }
+ }
+ }
/* Upload machine to data: */
UISettingsPageMachine::uploadData(data);
@@ -149,3 +188,12 @@ void UIMachineSettingsAudio::prepareComboboxes()
mCbAudioController->setCurrentIndex (currentController);
}
+void UIMachineSettingsAudio::polishPage()
+{
+ mGbAudio->setEnabled(isMachineOffline());
+ mLbAudioDriver->setEnabled(isMachineOffline());
+ mCbAudioDriver->setEnabled(isMachineOffline());
+ mLbAudioController->setEnabled(isMachineOffline());
+ mCbAudioController->setEnabled(isMachineOffline());
+}
+
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsAudio.h b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsAudio.h
index b25ccede2..a73d45526 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsAudio.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsAudio.h
@@ -5,7 +5,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;
@@ -23,13 +23,30 @@
#include "UIMachineSettingsAudio.gen.h"
#include "COMDefs.h"
-/* Machine settings / Audio page / Cache: */
-struct UISettingsCacheMachineAudio
+/* Machine settings / Audio page / Data: */
+struct UIDataSettingsMachineAudio
{
+ /* Default constructor: */
+ UIDataSettingsMachineAudio()
+ : m_fAudioEnabled(false)
+ , m_audioDriverType(KAudioDriverType_Null)
+ , m_audioControllerType(KAudioControllerType_AC97) {}
+ /* Functions: */
+ bool equal(const UIDataSettingsMachineAudio &other) const
+ {
+ return (m_fAudioEnabled == other.m_fAudioEnabled) &&
+ (m_audioDriverType == other.m_audioDriverType) &&
+ (m_audioControllerType == other.m_audioControllerType);
+ }
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineAudio &other) const { return equal(other); }
+ bool operator!=(const UIDataSettingsMachineAudio &other) const { return !equal(other); }
+ /* Variables: */
bool m_fAudioEnabled;
KAudioDriverType m_audioDriverType;
KAudioControllerType m_audioControllerType;
};
+typedef UISettingsCache<UIDataSettingsMachineAudio> UICacheSettingsMachineAudio;
/* Machine settings / Audio page: */
class UIMachineSettingsAudio : public UISettingsPageMachine,
@@ -57,6 +74,9 @@ protected:
* this task COULD be performed in other than GUI thread: */
void saveFromCacheTo(QVariant &data);
+ /* Page changed: */
+ bool changed() const { return m_cache.wasChanged(); }
+
void setOrderAfter (QWidget *aWidget);
void retranslateUi();
@@ -65,8 +85,10 @@ private:
void prepareComboboxes();
+ void polishPage();
+
/* Cache: */
- UISettingsCacheMachineAudio m_cache;
+ UICacheSettingsMachineAudio m_cache;
};
#endif // __UIMachineSettingsAudio_h__
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp
index 500056480..7ce815a03 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsDisplay.cpp $ */
+/* $Id: UIMachineSettingsDisplay.cpp 37735 2011-07-02 13:24:54Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -50,9 +50,12 @@ UIMachineSettingsDisplay::UIMachineSettingsDisplay()
, m_maxVRAM(0)
, m_maxVRAMVisible(0)
, m_initialVRAM(0)
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ , m_f2DVideoAccelerationSupported(false)
+#endif /* VBOX_WITH_VIDEOHWACCEL */
#ifdef VBOX_WITH_CRHGSMI
- , m_bWddmMode(false)
-#endif
+ , m_fWddmModeSupported(false)
+#endif /* VBOX_WITH_CRHGSMI */
{
/* Apply UI decorations */
Ui::UIMachineSettingsDisplay::setupUi (this);
@@ -93,10 +96,7 @@ UIMachineSettingsDisplay::UIMachineSettingsDisplay()
mSlMemory->setMinimum ((m_minVRAM / mSlMemory->pageStep()) * mSlMemory->pageStep());
mSlMemory->setMaximum (m_maxVRAMVisible);
mSlMemory->setSnappingEnabled (true);
- quint64 needMBytes = VBoxGlobal::requiredVideoMemory (&m_machine) / _1M;
mSlMemory->setErrorHint (0, 1);
- mSlMemory->setWarningHint (1, needMBytes);
- mSlMemory->setOptimalHint (needMBytes, m_maxVRAMVisible);
mSlMonitors->setMinimum (MinMonitors);
mSlMonitors->setMaximum (MaxMonitors);
mSlMonitors->setErrorHint (0, MinMonitors);
@@ -119,31 +119,40 @@ UIMachineSettingsDisplay::UIMachineSettingsDisplay()
mCb2DVideo->setVisible (false);
#endif
-#ifdef VBOX_WITH_CRHGSMI
- m_bWddmMode = false;
-#endif
-
/* Applying language settings */
retranslateUi();
}
-#ifdef VBOX_WITH_VIDEOHWACCEL
-bool UIMachineSettingsDisplay::isAcceleration2DVideoSelected() const
+void UIMachineSettingsDisplay::setGuestOSType(CGuestOSType guestOSType)
{
- return mCb2DVideo->isChecked();
-}
-#endif
+ /* Check if guest os type changed: */
+ if (m_guestOSType == guestOSType)
+ return;
+ /* Remember new guest os type: */
+ m_guestOSType = guestOSType;
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ /* Check if 2D video acceleration supported by the guest OS type: */
+ QString strguestOSTypeFamily = m_guestOSType.GetFamilyId();
+ m_f2DVideoAccelerationSupported = strguestOSTypeFamily == "Windows";
+#endif /* VBOX_WITH_VIDEOHWACCEL */
#ifdef VBOX_WITH_CRHGSMI
-void UIMachineSettingsDisplay::setWddmMode(bool bWddm)
-{
- if (bWddm == m_bWddmMode)
- return;
+ /* Check if WDDM mode supported by the guest OS type: */
+ QString strguestOSTypeId = m_guestOSType.GetId();
+ m_fWddmModeSupported = VBoxGlobal::isWddmCompatibleOsType(strguestOSTypeId);
+#endif /* VBOX_WITH_CRHGSMI */
- m_bWddmMode = bWddm;
+ /* Recheck video RAM requirement: */
checkVRAMRequirements();
}
-#endif
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+bool UIMachineSettingsDisplay::isAcceleration2DVideoSelected() const
+{
+ return mCb2DVideo->isChecked();
+}
+#endif /* VBOX_WITH_VIDEOHWACCEL */
/* Load data to cashe from corresponding external object(s),
* this task COULD be performed in other than GUI thread: */
@@ -152,23 +161,36 @@ void UIMachineSettingsDisplay::loadToCacheFrom(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Fill internal variables with corresponding values: */
- m_cache.m_iCurrentVRAM = m_machine.GetVRAMSize();
- m_cache.m_cMonitorCount = m_machine.GetMonitorCount();
- m_cache.m_f3dAccelerationEnabled = m_machine.GetAccelerate3DEnabled();
+ /* Clear cache initially: */
+ m_cache.clear();
+
+ /* Prepare display data: */
+ UIDataSettingsMachineDisplay displayData;
+
+ /* Gather display data: */
+ displayData.m_iCurrentVRAM = m_machine.GetVRAMSize();
+ displayData.m_cMonitorCount = m_machine.GetMonitorCount();
+ displayData.m_f3dAccelerationEnabled = m_machine.GetAccelerate3DEnabled();
#ifdef VBOX_WITH_VIDEOHWACCEL
- m_cache.m_f2dAccelerationEnabled = m_machine.GetAccelerate2DVideoEnabled();
-#endif
+ displayData.m_f2dAccelerationEnabled = m_machine.GetAccelerate2DVideoEnabled();
+#endif /* VBOX_WITH_VIDEOHWACCEL */
+ /* Check if VRDE server is valid: */
CVRDEServer vrdeServer = m_machine.GetVRDEServer();
- m_cache.m_fVRDEServerSupported = !vrdeServer.isNull();
- m_cache.m_fVRDEServerEnabled = m_cache.m_fVRDEServerSupported && vrdeServer.GetEnabled();
- m_cache.m_strVRDEPort = vrdeServer.GetVRDEProperty("TCP/Ports");
- m_cache.m_iVRDEAuthType = vrdeServer.GetAuthType();
- m_cache.m_uVRDETimeout = vrdeServer.GetAuthTimeout();
- m_cache.m_fMultipleConnectionsAllowed = vrdeServer.GetAllowMultiConnection();
+ displayData.m_fVRDEServerSupported = !vrdeServer.isNull();
+ if (!vrdeServer.isNull())
+ {
+ displayData.m_fVRDEServerEnabled = vrdeServer.GetEnabled();
+ displayData.m_strVRDEPort = vrdeServer.GetVRDEProperty("TCP/Ports");
+ displayData.m_VRDEAuthType = vrdeServer.GetAuthType();
+ displayData.m_uVRDETimeout = vrdeServer.GetAuthTimeout();
+ displayData.m_fMultipleConnectionsAllowed = vrdeServer.GetAllowMultiConnection();
+ }
- /* Other variables: */
- m_initialVRAM = RT_MIN(m_cache.m_iCurrentVRAM, m_maxVRAM);
+ /* Initialize other variables: */
+ m_initialVRAM = RT_MIN(displayData.m_iCurrentVRAM, m_maxVRAM);
+
+ /* Cache display data: */
+ m_cache.cacheInitialData(displayData);
/* Upload machine to data: */
UISettingsPageMachine::uploadData(data);
@@ -178,50 +200,59 @@ void UIMachineSettingsDisplay::loadToCacheFrom(QVariant &data)
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsDisplay::getFromCache()
{
- /* Apply internal variables data to QWidget(s): */
- mSlMonitors->setValue(m_cache.m_cMonitorCount);
- mCb3D->setEnabled(vboxGlobal().virtualBox().GetHost().GetAcceleration3DAvailable());
- mCb3D->setChecked(m_cache.m_f3dAccelerationEnabled);
+ /* Get display data from cache: */
+ const UIDataSettingsMachineDisplay &displayData = m_cache.base();
+
+ /* Load display data to page: */
+ mSlMonitors->setValue(displayData.m_cMonitorCount);
+ mCb3D->setChecked(displayData.m_f3dAccelerationEnabled);
#ifdef VBOX_WITH_VIDEOHWACCEL
- mCb2DVideo->setEnabled(VBoxGlobal::isAcceleration2DVideoAvailable());
- mCb2DVideo->setChecked(m_cache.m_f2dAccelerationEnabled);
-#endif
+ mCb2DVideo->setChecked(displayData.m_f2dAccelerationEnabled);
+#endif /* VBOX_WITH_VIDEOHWACCEL */
checkVRAMRequirements();
- mSlMemory->setValue(m_cache.m_iCurrentVRAM);
- if (m_cache.m_fVRDEServerSupported)
+ mSlMemory->setValue(displayData.m_iCurrentVRAM);
+ if (displayData.m_fVRDEServerSupported)
{
- mCbVRDE->setChecked(m_cache.m_fVRDEServerEnabled);
- mLeVRDEPort->setText(m_cache.m_strVRDEPort);
- mCbVRDEMethod->setCurrentIndex(mCbVRDEMethod->findText(vboxGlobal().toString(m_cache.m_iVRDEAuthType)));
- mLeVRDETimeout->setText(QString::number(m_cache.m_uVRDETimeout));
- mCbMultipleConn->setChecked(m_cache.m_fMultipleConnectionsAllowed);
+ mCbVRDE->setChecked(displayData.m_fVRDEServerEnabled);
+ mLeVRDEPort->setText(displayData.m_strVRDEPort);
+ mCbVRDEMethod->setCurrentIndex(mCbVRDEMethod->findText(vboxGlobal().toString(displayData.m_VRDEAuthType)));
+ mLeVRDETimeout->setText(QString::number(displayData.m_uVRDETimeout));
+ mCbMultipleConn->setChecked(displayData.m_fMultipleConnectionsAllowed);
}
- else
- mTwDisplay->removeTab(1);
+
+ /* Polish page finally: */
+ polishPage();
/* Revalidate if possible: */
- if (mValidator) mValidator->revalidate();
+ if (mValidator)
+ mValidator->revalidate();
}
/* Save data from corresponding widgets to cache,
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsDisplay::putToCache()
{
- /* Gather internal variables data from QWidget(s): */
- m_cache.m_iCurrentVRAM = mSlMemory->value();
- m_cache.m_cMonitorCount = mSlMonitors->value();
- m_cache.m_f3dAccelerationEnabled = mCb3D->isChecked();
+ /* Prepare audio data: */
+ UIDataSettingsMachineDisplay displayData = m_cache.base();
+
+ /* Gather display data: */
+ displayData.m_iCurrentVRAM = mSlMemory->value();
+ displayData.m_cMonitorCount = mSlMonitors->value();
+ displayData.m_f3dAccelerationEnabled = mCb3D->isChecked();
#ifdef VBOX_WITH_VIDEOHWACCEL
- m_cache.m_f2dAccelerationEnabled = mCb2DVideo->isChecked();
-#endif
- if (m_cache.m_fVRDEServerSupported)
+ displayData.m_f2dAccelerationEnabled = mCb2DVideo->isChecked();
+#endif /* VBOX_WITH_VIDEOHWACCEL */
+ if (displayData.m_fVRDEServerSupported)
{
- m_cache.m_fVRDEServerEnabled = mCbVRDE->isChecked();
- m_cache.m_strVRDEPort = mLeVRDEPort->text();
- m_cache.m_iVRDEAuthType = vboxGlobal().toAuthType(mCbVRDEMethod->currentText());
- m_cache.m_uVRDETimeout = mLeVRDETimeout->text().toULong();
- m_cache.m_fMultipleConnectionsAllowed = mCbMultipleConn->isChecked();
+ displayData.m_fVRDEServerEnabled = mCbVRDE->isChecked();
+ displayData.m_strVRDEPort = mLeVRDEPort->text();
+ displayData.m_VRDEAuthType = vboxGlobal().toAuthType(mCbVRDEMethod->currentText());
+ displayData.m_uVRDETimeout = mLeVRDETimeout->text().toULong();
+ displayData.m_fMultipleConnectionsAllowed = mCbMultipleConn->isChecked();
}
+
+ /* Cache display data: */
+ m_cache.cacheCurrentData(displayData);
}
/* Save data from cache to corresponding external object(s),
@@ -231,21 +262,40 @@ void UIMachineSettingsDisplay::saveFromCacheTo(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Gather corresponding values from internal variables: */
- m_machine.SetVRAMSize(m_cache.m_iCurrentVRAM);
- m_machine.SetMonitorCount(m_cache.m_cMonitorCount);
- m_machine.SetAccelerate3DEnabled(m_cache.m_f3dAccelerationEnabled);
-#ifdef VBOX_WITH_VIDEOHWACCEL
- m_machine.SetAccelerate2DVideoEnabled(m_cache.m_f2dAccelerationEnabled);
-#endif
- CVRDEServer vrdeServer = m_machine.GetVRDEServer();
- if (!vrdeServer.isNull())
+ /* Check if display data was changed: */
+ if (m_cache.wasChanged())
{
- vrdeServer.SetEnabled(m_cache.m_fVRDEServerEnabled);
- vrdeServer.SetVRDEProperty("TCP/Ports", m_cache.m_strVRDEPort);
- vrdeServer.SetAuthType(m_cache.m_iVRDEAuthType);
- vrdeServer.SetAuthTimeout(m_cache.m_uVRDETimeout);
- vrdeServer.SetAllowMultiConnection(m_cache.m_fMultipleConnectionsAllowed);
+ /* Get display data from cache: */
+ const UIDataSettingsMachineDisplay &displayData = m_cache.data();
+
+ /* Store display data: */
+ if (isMachineOffline())
+ {
+ /* Video tab: */
+ m_machine.SetVRAMSize(displayData.m_iCurrentVRAM);
+ m_machine.SetMonitorCount(displayData.m_cMonitorCount);
+ m_machine.SetAccelerate3DEnabled(displayData.m_f3dAccelerationEnabled);
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ m_machine.SetAccelerate2DVideoEnabled(displayData.m_f2dAccelerationEnabled);
+#endif /* VBOX_WITH_VIDEOHWACCEL */
+ }
+ /* Check if VRDE server still valid: */
+ CVRDEServer vrdeServer = m_machine.GetVRDEServer();
+ if (!vrdeServer.isNull())
+ {
+ /* Store VRDE data: */
+ if (isMachineInValidMode())
+ {
+ vrdeServer.SetEnabled(displayData.m_fVRDEServerEnabled);
+ vrdeServer.SetVRDEProperty("TCP/Ports", displayData.m_strVRDEPort);
+ vrdeServer.SetAuthType(displayData.m_VRDEAuthType);
+ vrdeServer.SetAuthTimeout(displayData.m_uVRDETimeout);
+ }
+ if (isMachineOffline() || isMachineSaved())
+ {
+ vrdeServer.SetAllowMultiConnection(displayData.m_fMultipleConnectionsAllowed);
+ }
+ }
}
/* Upload machine to data: */
@@ -269,49 +319,70 @@ void UIMachineSettingsDisplay::setValidator (QIWidgetValidator *aVal)
mValidator, SLOT (revalidate()));
}
-bool UIMachineSettingsDisplay::revalidate (QString &aWarning, QString & /* aTitle */)
+bool UIMachineSettingsDisplay::revalidate(QString &strWarning, QString & /* strTitle */)
{
- /* Video RAM amount test */
- quint64 needBytes = VBoxGlobal::requiredVideoMemory (&m_machine, mSlMonitors->value());
- if ( vboxGlobal().shouldWarnAboutToLowVRAM(&m_machine)
- && (quint64)mSlMemory->value() * _1M < needBytes)
+ /* Check if video RAM requirement changed first: */
+ checkVRAMRequirements();
+
+ /* Video RAM amount test: */
+ if (shouldWeWarnAboutLowVideoMemory() && !m_guestOSType.isNull())
{
- aWarning = tr (
- "you have assigned less than <b>%1</b> of video memory which is "
- "the minimum amount required to switch the virtual machine to "
- "fullscreen or seamless mode.")
- .arg (vboxGlobal().formatSize (needBytes, 0, VBoxDefs::FormatSize_RoundUp));
- }
+ quint64 uNeedBytes = VBoxGlobal::requiredVideoMemory(m_guestOSType.GetId(), mSlMonitors->value());
+
+ /* Basic video RAM amount test: */
+ if ((quint64)mSlMemory->value() * _1M < uNeedBytes)
+ {
+ strWarning = tr("you have assigned less than <b>%1</b> of video memory which is "
+ "the minimum amount required to switch the virtual machine to "
+ "fullscreen or seamless mode.")
+ .arg(vboxGlobal().formatSize(uNeedBytes, 0, VBoxDefs::FormatSize_RoundUp));
+ return true;
+ }
#ifdef VBOX_WITH_VIDEOHWACCEL
- else if (mCb2DVideo->isChecked())
- {
- needBytes += VBoxGlobal::required2DOffscreenVideoMemory();
- if ((quint64) mSlMemory->value() * _1M < needBytes)
+ /* 2D acceleration video RAM amount test: */
+ if (mCb2DVideo->isChecked() && m_f2DVideoAccelerationSupported)
{
- aWarning = tr (
- "you have assigned less than <b>%1</b> of video memory which is "
- "the minimum amount required for HD Video to be played efficiently.")
- .arg (vboxGlobal().formatSize (needBytes, 0, VBoxDefs::FormatSize_RoundUp));
+ uNeedBytes += VBoxGlobal::required2DOffscreenVideoMemory();
+ if ((quint64)mSlMemory->value() * _1M < uNeedBytes)
+ {
+ strWarning = tr("you have assigned less than <b>%1</b> of video memory which is "
+ "the minimum amount required for HD Video to be played efficiently.")
+ .arg(vboxGlobal().formatSize(uNeedBytes, 0, VBoxDefs::FormatSize_RoundUp));
+ return true;
+ }
}
- }
-#endif
-#ifdef VBOX_WITH_CRHGSMI
- else if (false) // m_bWddmMode && mCb3D->isChecked())
- {
- int cVal = mSlMonitors->value();
- needBytes += VBoxGlobal::required3DWddmOffscreenVideoMemory(&m_machine, cVal);
- needBytes = RT_MAX(needBytes, 128 * _1M);
- needBytes = RT_MIN(needBytes, 256 * _1M);
- if ((quint64) mSlMemory->value() * _1M < needBytes)
+#endif /* VBOX_WITH_VIDEOHWACCEL */
+#if 0
+# ifdef VBOX_WITH_CRHGSMI
+ if (mCb3D->isChecked() && m_fWddmModeSupported)
{
- aWarning = tr(
- "You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. "
- "For maximal performance set the guest VRAM to at least <b>%1</b>."
- ).arg (vboxGlobal().formatSize (needBytes, 0, VBoxDefs::FormatSize_RoundUp));
+ int cMonitorsCount = mSlMonitors->value();
+ uNeedBytes += VBoxGlobal::required3DWddmOffscreenVideoMemory(m_guestOSType.GetId(), cMonitorsCount);
+ uNeedBytes = RT_MAX(uNeedBytes, 128 * _1M);
+ uNeedBytes = RT_MIN(uNeedBytes, 256 * _1M);
+ if ((quint64)mSlMemory->value() * _1M < uNeedBytes)
+ {
+ strWarning = tr("you have 3D Acceleration enabled for a operation system which uses the WDDM video driver. "
+ "For maximal performance set the guest VRAM to at least <b>%1</b>.")
+ .arg(vboxGlobal().formatSize(uNeedBytes, 0, VBoxDefs::FormatSize_RoundUp));
+ return true;
+ }
}
+# endif /* VBOX_WITH_CRHGSMI */
+#endif /* 0 */
}
-#endif
- checkVRAMRequirements();
+
+ /* Check mode availability: */
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ /* 2D video acceleration is available for Windows guests only: */
+ if (mCb2DVideo->isChecked() && !m_f2DVideoAccelerationSupported)
+ {
+ strWarning = tr("you have 2D Video Acceleration enabled. As 2D Video Acceleration "
+ "is supported for Windows guests only, this feature will be disabled.");
+ return true;
+ }
+#endif /* VBOX_WITH_VIDEOHWACCEL */
+
return true;
}
@@ -380,39 +451,91 @@ void UIMachineSettingsDisplay::textChangedMonitors (const QString &aText)
void UIMachineSettingsDisplay::checkVRAMRequirements()
{
- int cVal = mSlMonitors->value();
- /* The memory requirements have changed too. */
- quint64 needMBytes = VBoxGlobal::requiredVideoMemory (&m_machine, cVal) / _1M;
- /* Limit the maximum memory to save careless users from setting useless big values */
+ if (m_guestOSType.isNull())
+ return;
+
+ /* Get monitors count and base video memory requirements: */
+ int cMonitorsCount = mSlMonitors->value();
+ quint64 uNeedMBytes = VBoxGlobal::requiredVideoMemory(m_guestOSType.GetId(), cMonitorsCount) / _1M;
+
+ /* Initial values: */
+ m_maxVRAMVisible = cMonitorsCount * 32;
+ if (m_maxVRAMVisible < 128)
+ m_maxVRAMVisible = 128;
+ if (m_maxVRAMVisible < m_initialVRAM)
+ m_maxVRAMVisible = m_initialVRAM;
+
#ifdef VBOX_WITH_VIDEOHWACCEL
- if (mCb2DVideo->isChecked())
+ if (mCb2DVideo->isChecked() && m_f2DVideoAccelerationSupported)
{
- needMBytes += VBoxGlobal::required2DOffscreenVideoMemory() / _1M;
+ uNeedMBytes += VBoxGlobal::required2DOffscreenVideoMemory() / _1M;
}
-#endif
-#if 0 // def VBOX_WITH_CRHGSMI
- if (m_bWddmMode && mCb3D->isChecked())
+#endif /* VBOX_WITH_VIDEOHWACCEL */
+#ifdef VBOX_WITH_CRHGSMI
+ if (mCb3D->isChecked() && m_fWddmModeSupported)
{
- needMBytes += VBoxGlobal::required3DWddmOffscreenVideoMemory(&m_machine, cVal) / _1M;
- needMBytes = RT_MAX(needMBytes, 128);
- needMBytes = RT_MIN(needMBytes, 256);
+# if 0
+ uNeedMBytes += VBoxGlobal::required3DWddmOffscreenVideoMemory(m_guestOSType.GetId(), cMonitorsCount) / _1M;
+ uNeedMBytes = RT_MAX(uNeedMBytes, 128);
+ uNeedMBytes = RT_MIN(uNeedMBytes, 256);
+# endif
m_maxVRAMVisible = 256;
}
- else
-#endif
- {
- m_maxVRAMVisible = cVal * 32;
- if (m_maxVRAMVisible < 128)
- m_maxVRAMVisible = 128;
- if (m_maxVRAMVisible < m_initialVRAM)
- m_maxVRAMVisible = m_initialVRAM;
- }
- mSlMemory->setWarningHint (1, needMBytes);
- mSlMemory->setPageStep (calcPageStep (m_maxVRAMVisible));
- mSlMemory->setMaximum (m_maxVRAMVisible);
- mSlMemory->setOptimalHint (needMBytes, m_maxVRAMVisible);
- mLeMemory->setValidator (new QIntValidator (m_minVRAM, m_maxVRAMVisible, this));
- mLbMemoryMax->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (m_maxVRAMVisible));
- /* ... or just call retranslateUi()? */
+#endif /* VBOX_WITH_CRHGSMI */
+
+ mSlMemory->setWarningHint(1, uNeedMBytes);
+ mSlMemory->setPageStep(calcPageStep(m_maxVRAMVisible));
+ mSlMemory->setMaximum(m_maxVRAMVisible);
+ mSlMemory->setOptimalHint(uNeedMBytes, m_maxVRAMVisible);
+ mLeMemory->setValidator(new QIntValidator(m_minVRAM, m_maxVRAMVisible, this));
+ mLbMemoryMax->setText(tr("<qt>%1&nbsp;MB</qt>").arg(m_maxVRAMVisible));
+}
+
+bool UIMachineSettingsDisplay::shouldWeWarnAboutLowVideoMemory()
+{
+ bool fResult = true;
+
+ QStringList excludingOSList = QStringList()
+ << "Other" << "DOS" << "Netware" << "L4" << "QNX" << "JRockitVE";
+ if (excludingOSList.contains(m_guestOSType.GetId()))
+ fResult = false;
+
+ return fResult;
+}
+
+void UIMachineSettingsDisplay::polishPage()
+{
+ /* Get system data from cache: */
+ const UIDataSettingsMachineDisplay &displayData = m_cache.base();
+
+ /* Video tab: */
+ mLbMemory->setEnabled(isMachineOffline());
+ mLbMemoryMin->setEnabled(isMachineOffline());
+ mLbMemoryMax->setEnabled(isMachineOffline());
+ mLbMemoryUnit->setEnabled(isMachineOffline());
+ mSlMemory->setEnabled(isMachineOffline());
+ mLeMemory->setEnabled(isMachineOffline());
+ mLbMonitors->setEnabled(isMachineOffline());
+ mLbMonitorsMin->setEnabled(isMachineOffline());
+ mLbMonitorsMax->setEnabled(isMachineOffline());
+ mLbMonitorsUnit->setEnabled(isMachineOffline());
+ mSlMonitors->setEnabled(isMachineOffline());
+ mLeMonitors->setEnabled(isMachineOffline());
+ mLbOptions->setEnabled(isMachineOffline());
+ mCb3D->setEnabled(isMachineOffline() && vboxGlobal().virtualBox().GetHost().GetAcceleration3DAvailable());
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ mCb2DVideo->setEnabled(isMachineOffline() && VBoxGlobal::isAcceleration2DVideoAvailable());
+#endif /* VBOX_WITH_VIDEOHWACCEL */
+ /* VRDE tab: */
+ mTwDisplay->setTabEnabled(1, displayData.m_fVRDEServerSupported);
+ mCbVRDE->setEnabled(isMachineInValidMode());
+ mLbVRDPPort->setEnabled(isMachineInValidMode());
+ mLeVRDEPort->setEnabled(isMachineInValidMode());
+ mLbVRDPMethod->setEnabled(isMachineInValidMode());
+ mCbVRDEMethod->setEnabled(isMachineInValidMode());
+ mLbVRDPTimeout->setEnabled(isMachineInValidMode());
+ mLeVRDETimeout->setEnabled(isMachineInValidMode());
+ mLbOptions2->setEnabled(isMachineOffline() || isMachineSaved());
+ mCbMultipleConn->setEnabled(isMachineOffline() || isMachineSaved());
}
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.h b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.h
index fa2fb93f5..b7fcf1e54 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -23,20 +23,57 @@
#include "UISettingsPage.h"
#include "UIMachineSettingsDisplay.gen.h"
-/* Machine settings / Display page / Cache: */
-struct UISettingsCacheMachineDisplay
+/* Machine settings / Display page / Data: */
+struct UIDataSettingsMachineDisplay
{
+ /* Default constructor: */
+ UIDataSettingsMachineDisplay()
+ : m_iCurrentVRAM(0)
+ , m_cMonitorCount(0)
+ , m_f3dAccelerationEnabled(false)
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ , m_f2dAccelerationEnabled(false)
+#endif /* VBOX_WITH_VIDEOHWACCEL */
+ , m_fVRDEServerSupported(false)
+ , m_fVRDEServerEnabled(false)
+ , m_strVRDEPort(QString())
+ , m_VRDEAuthType(KAuthType_Null)
+ , m_uVRDETimeout(0)
+ , m_fMultipleConnectionsAllowed(false) {}
+ /* Functions: */
+ bool equal(const UIDataSettingsMachineDisplay &other) const
+ {
+ return (m_iCurrentVRAM == other.m_iCurrentVRAM) &&
+ (m_cMonitorCount == other.m_cMonitorCount) &&
+ (m_f3dAccelerationEnabled == other.m_f3dAccelerationEnabled) &&
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ (m_f2dAccelerationEnabled == other.m_f2dAccelerationEnabled) &&
+#endif /* VBOX_WITH_VIDEOHWACCEL */
+ (m_fVRDEServerSupported == other.m_fVRDEServerSupported) &&
+ (m_fVRDEServerEnabled == other.m_fVRDEServerEnabled) &&
+ (m_strVRDEPort == other.m_strVRDEPort) &&
+ (m_VRDEAuthType == other.m_VRDEAuthType) &&
+ (m_uVRDETimeout == other.m_uVRDETimeout) &&
+ (m_fMultipleConnectionsAllowed == other.m_fMultipleConnectionsAllowed);
+ }
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineDisplay &other) const { return equal(other); }
+ bool operator!=(const UIDataSettingsMachineDisplay &other) const { return !equal(other); }
+ /* Variables: */
int m_iCurrentVRAM;
int m_cMonitorCount;
bool m_f3dAccelerationEnabled;
+#ifdef VBOX_WITH_VIDEOHWACCEL
bool m_f2dAccelerationEnabled;
+#endif /* VBOX_WITH_VIDEOHWACCEL */
bool m_fVRDEServerSupported;
bool m_fVRDEServerEnabled;
QString m_strVRDEPort;
- KAuthType m_iVRDEAuthType;
+ KAuthType m_VRDEAuthType;
ulong m_uVRDETimeout;
bool m_fMultipleConnectionsAllowed;
};
+typedef UISettingsCache<UIDataSettingsMachineDisplay> UICacheSettingsMachineDisplay;
/* Machine settings / Display page: */
class UIMachineSettingsDisplay : public UISettingsPageMachine,
@@ -48,13 +85,11 @@ public:
UIMachineSettingsDisplay();
+ void setGuestOSType(CGuestOSType guestOSType);
+
#ifdef VBOX_WITH_VIDEOHWACCEL
bool isAcceleration2DVideoSelected() const;
-#endif
-
-#ifdef VBOX_WITH_CRHGSMI
- void setWddmMode(bool bWddm);
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
protected:
@@ -72,6 +107,9 @@ protected:
* this task COULD be performed in other than GUI thread: */
void saveFromCacheTo(QVariant &data);
+ /* Page changed: */
+ bool changed() const { return m_cache.wasChanged(); }
+
void setValidator (QIWidgetValidator *aVal);
bool revalidate (QString &aWarning, QString &aTitle);
@@ -89,9 +127,14 @@ private slots:
private:
void checkVRAMRequirements();
+ bool shouldWeWarnAboutLowVideoMemory();
+
+ void polishPage();
QIWidgetValidator *mValidator;
+ /* Guest OS type id: */
+ CGuestOSType m_guestOSType;
/* System minimum lower limit of VRAM (MiB). */
int m_minVRAM;
/* System maximum limit of VRAM (MiB). */
@@ -101,13 +144,17 @@ private:
int m_maxVRAMVisible;
/* Initial VRAM value when the dialog is opened. */
int m_initialVRAM;
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ /* Specifies whether the guest OS supports 2D video-acceleration: */
+ bool m_f2DVideoAccelerationSupported;
+#endif /* VBOX_WITH_VIDEOHWACCEL */
#ifdef VBOX_WITH_CRHGSMI
- /* Specifies whether the guest os is wddm-capable: */
- bool m_bWddmMode;
-#endif
+ /* Specifies whether the guest OS supports WDDM: */
+ bool m_fWddmModeSupported;
+#endif /* VBOX_WITH_CRHGSMI */
/* Cache: */
- UISettingsCacheMachineDisplay m_cache;
+ UICacheSettingsMachineDisplay m_cache;
};
#endif // __UIMachineSettingsDisplay_h__
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.ui b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.ui
index 6a77ef637..8d1cd1484 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.ui
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.ui
@@ -121,9 +121,6 @@
</item>
<item row="0" column="2">
<layout class="QHBoxLayout" name="mLtMemorySize">
- <property name="spacing">
- <number>4</number>
- </property>
<item>
<widget class="QILineEdit" name="mLeMemory">
<property name="whatsThis">
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp
index 681111464..c779e3b32 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsGeneral.cpp $ */
+/* $Id: UIMachineSettingsGeneral.cpp 37168 2011-05-20 16:56:46Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,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;
@@ -26,6 +26,7 @@
UIMachineSettingsGeneral::UIMachineSettingsGeneral()
: mValidator(0)
+ , m_fHWVirtExEnabled(false)
{
/* Apply UI decorations */
Ui::UIMachineSettingsGeneral::setupUi (this);
@@ -47,6 +48,16 @@ UIMachineSettingsGeneral::UIMachineSettingsGeneral()
retranslateUi();
}
+CGuestOSType UIMachineSettingsGeneral::guestOSType() const
+{
+ return mOSTypeSelector->type();
+}
+
+void UIMachineSettingsGeneral::setHWVirtExEnabled(bool fEnabled)
+{
+ m_fHWVirtExEnabled = fEnabled;
+}
+
bool UIMachineSettingsGeneral::is64BitOSTypeSelected() const
{
return mOSTypeSelector->type().GetIs64Bit();
@@ -57,15 +68,7 @@ bool UIMachineSettingsGeneral::isWindowsOSTypeSelected() const
{
return mOSTypeSelector->type().GetFamilyId() == "Windows";
}
-#endif
-
-#ifdef VBOX_WITH_CRHGSMI
-bool UIMachineSettingsGeneral::isWddmSupportedForOSType() const
-{
- const QString &strOsId = mOSTypeSelector->type().GetId();
- return strOsId == "WindowsVista" || strOsId == "Windows7";
-}
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
/* Load data to cashe from corresponding external object(s),
* this task COULD be performed in other than GUI thread: */
@@ -74,19 +77,28 @@ void UIMachineSettingsGeneral::loadToCacheFrom(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Fill internal variables with corresponding values: */
- m_cache.m_strName = m_machine.GetName();
- m_cache.m_strGuestOsTypeId = m_machine.GetOSTypeId();
+ /* Clear cache initially: */
+ m_cache.clear();
+
+ /* Prepare general data: */
+ UIDataSettingsMachineGeneral generalData;
+
+ /* Gather general data: */
+ generalData.m_strName = m_machine.GetName();
+ generalData.m_strGuestOsTypeId = m_machine.GetOSTypeId();
QString strSaveMountedAtRuntime = m_machine.GetExtraData(VBoxDefs::GUI_SaveMountedAtRuntime);
- m_cache.m_fSaveMountedAtRuntime = strSaveMountedAtRuntime != "no";
+ generalData.m_fSaveMountedAtRuntime = strSaveMountedAtRuntime != "no";
QString strShowMiniToolBar = m_machine.GetExtraData(VBoxDefs::GUI_ShowMiniToolBar);
- m_cache.m_fShowMiniToolBar = strShowMiniToolBar != "no";
+ generalData.m_fShowMiniToolBar = strShowMiniToolBar != "no";
QString strMiniToolBarAlignment = m_machine.GetExtraData(VBoxDefs::GUI_MiniToolBarAlignment);
- m_cache.m_fMiniToolBarAtTop = strMiniToolBarAlignment == "top";
- m_cache.m_strSnapshotsFolder = m_machine.GetSnapshotFolder();
- m_cache.m_strSnapshotsHomeDir = QFileInfo(m_machine.GetSettingsFilePath()).absolutePath();
- m_cache.m_clipboardMode = m_machine.GetClipboardMode();
- m_cache.m_strDescription = m_machine.GetDescription();
+ generalData.m_fMiniToolBarAtTop = strMiniToolBarAlignment == "top";
+ generalData.m_strSnapshotsFolder = m_machine.GetSnapshotFolder();
+ generalData.m_strSnapshotsHomeDir = QFileInfo(m_machine.GetSettingsFilePath()).absolutePath();
+ generalData.m_clipboardMode = m_machine.GetClipboardMode();
+ generalData.m_strDescription = m_machine.GetDescription();
+
+ /* Cache general data: */
+ m_cache.cacheInitialData(generalData);
/* Upload machine to data: */
UISettingsPageMachine::uploadData(data);
@@ -96,36 +108,48 @@ void UIMachineSettingsGeneral::loadToCacheFrom(QVariant &data)
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsGeneral::getFromCache()
{
- /* Apply internal variables data to QWidget(s): */
- mLeName->setText(m_cache.m_strName);
- mOSTypeSelector->setType(vboxGlobal().vmGuestOSType(m_cache.m_strGuestOsTypeId));
- mCbSaveMounted->setChecked(m_cache.m_fSaveMountedAtRuntime);
- mCbShowToolBar->setChecked(m_cache.m_fShowMiniToolBar);
- mCbToolBarAlignment->setChecked(m_cache.m_fMiniToolBarAtTop);
- mCbToolBarAlignment->setEnabled(mCbShowToolBar->isChecked());
- mPsSnapshot->setPath(m_cache.m_strSnapshotsFolder);
- mPsSnapshot->setHomeDir(m_cache.m_strSnapshotsHomeDir);
- mCbClipboard->setCurrentIndex(m_cache.m_clipboardMode);
- mTeDescription->setPlainText(m_cache.m_strDescription);
+ /* Get general data from cache: */
+ const UIDataSettingsMachineGeneral &generalData = m_cache.base();
+
+ /* Load general data to page: */
+ mLeName->setText(generalData.m_strName);
+ mOSTypeSelector->setType(vboxGlobal().vmGuestOSType(generalData.m_strGuestOsTypeId));
+ mCbSaveMounted->setChecked(generalData.m_fSaveMountedAtRuntime);
+ mCbShowToolBar->setChecked(generalData.m_fShowMiniToolBar);
+ mCbToolBarAlignment->setChecked(generalData.m_fMiniToolBarAtTop);
+ mPsSnapshot->setPath(generalData.m_strSnapshotsFolder);
+ mPsSnapshot->setHomeDir(generalData.m_strSnapshotsHomeDir);
+ mCbClipboard->setCurrentIndex(generalData.m_clipboardMode);
+ mTeDescription->setPlainText(generalData.m_strDescription);
+
+ /* Polish page finally: */
+ polishPage();
/* Revalidate if possible: */
- if (mValidator) mValidator->revalidate();
+ if (mValidator)
+ mValidator->revalidate();
}
/* Save data from corresponding widgets to cache,
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsGeneral::putToCache()
{
- /* Gather internal variables data from QWidget(s): */
- m_cache.m_strName = mLeName->text();
- m_cache.m_strGuestOsTypeId = mOSTypeSelector->type().GetId();
- m_cache.m_fSaveMountedAtRuntime = mCbSaveMounted->isChecked();
- m_cache.m_fShowMiniToolBar = mCbShowToolBar->isChecked();
- m_cache.m_fMiniToolBarAtTop = mCbToolBarAlignment->isChecked();
- m_cache.m_strSnapshotsFolder = mPsSnapshot->path();
- m_cache.m_clipboardMode = (KClipboardMode)mCbClipboard->currentIndex();
- m_cache.m_strDescription = mTeDescription->toPlainText().isEmpty() ?
- QString::null : mTeDescription->toPlainText();
+ /* Prepare general data: */
+ UIDataSettingsMachineGeneral generalData = m_cache.base();
+
+ /* Gather general data: */
+ generalData.m_strName = mLeName->text();
+ generalData.m_strGuestOsTypeId = mOSTypeSelector->type().GetId();
+ generalData.m_fSaveMountedAtRuntime = mCbSaveMounted->isChecked();
+ generalData.m_fShowMiniToolBar = mCbShowToolBar->isChecked();
+ generalData.m_fMiniToolBarAtTop = mCbToolBarAlignment->isChecked();
+ generalData.m_strSnapshotsFolder = mPsSnapshot->path();
+ generalData.m_clipboardMode = (KClipboardMode)mCbClipboard->currentIndex();
+ generalData.m_strDescription = mTeDescription->toPlainText().isEmpty() ?
+ QString::null : mTeDescription->toPlainText();
+
+ /* Cache general data: */
+ m_cache.cacheCurrentData(generalData);
}
/* Save data from cache to corresponding external object(s),
@@ -135,17 +159,35 @@ void UIMachineSettingsGeneral::saveFromCacheTo(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Gather corresponding values from internal variables: */
- m_machine.SetOSTypeId(m_cache.m_strGuestOsTypeId);
- m_machine.SetExtraData(VBoxDefs::GUI_SaveMountedAtRuntime, m_cache.m_fSaveMountedAtRuntime ? "yes" : "no");
- m_machine.SetExtraData(VBoxDefs::GUI_ShowMiniToolBar, m_cache.m_fShowMiniToolBar ? "yes" : "no");
- m_machine.SetExtraData(VBoxDefs::GUI_MiniToolBarAlignment, m_cache.m_fMiniToolBarAtTop ? "top" : "bottom");
- m_machine.SetSnapshotFolder(m_cache.m_strSnapshotsFolder);
- m_machine.SetClipboardMode(m_cache.m_clipboardMode);
- m_machine.SetDescription(m_cache.m_strDescription);
- /* Must be last as otherwise its VM rename magic can collide with other
- * settings in the config, especially with the snapshot folder. */
- m_machine.SetName(m_cache.m_strName);
+ /* Check if general data was changed: */
+ if (m_cache.wasChanged())
+ {
+ /* Get general data from cache: */
+ const UIDataSettingsMachineGeneral &generalData = m_cache.data();
+
+ /* Store general data: */
+ if (isMachineInValidMode())
+ {
+ /* Advanced tab: */
+ m_machine.SetClipboardMode(generalData.m_clipboardMode);
+ m_machine.SetExtraData(VBoxDefs::GUI_SaveMountedAtRuntime, generalData.m_fSaveMountedAtRuntime ? "yes" : "no");
+ m_machine.SetExtraData(VBoxDefs::GUI_ShowMiniToolBar, generalData.m_fShowMiniToolBar ? "yes" : "no");
+ m_machine.SetExtraData(VBoxDefs::GUI_MiniToolBarAlignment, generalData.m_fMiniToolBarAtTop ? "top" : "bottom");
+ /* Description tab: */
+ m_machine.SetDescription(generalData.m_strDescription);
+ }
+ if (isMachineOffline())
+ {
+ /* Basic tab: */
+ m_machine.SetOSTypeId(generalData.m_strGuestOsTypeId);
+ /* Advanced tab: */
+ m_machine.SetSnapshotFolder(generalData.m_strSnapshotsFolder);
+ /* Basic (again) tab: */
+ /* VM name must be last as otherwise its VM rename magic can collide with other settings in the config,
+ * especially with the snapshot folder: */
+ m_machine.SetName(generalData.m_strName);
+ }
+ }
/* Upload machine to data: */
UISettingsPageMachine::uploadData(data);
@@ -157,6 +199,15 @@ void UIMachineSettingsGeneral::setValidator (QIWidgetValidator *aVal)
connect (mOSTypeSelector, SIGNAL (osTypeChanged()), mValidator, SLOT (revalidate()));
}
+bool UIMachineSettingsGeneral::revalidate(QString &strWarning, QString& /* strTitle */)
+{
+ if (is64BitOSTypeSelected() && !m_fHWVirtExEnabled)
+ strWarning = tr("you have selected a 64-bit guest OS type for this VM. As such guests "
+ "require hardware virtualization (VT-x/AMD-V), this feature will be enabled "
+ "automatically.");
+ return true;
+}
+
void UIMachineSettingsGeneral::setOrderAfter (QWidget *aWidget)
{
/* Basic tab-order */
@@ -193,3 +244,21 @@ void UIMachineSettingsGeneral::retranslateUi()
mCbClipboard->setItemText (3, vboxGlobal().toString (KClipboardMode_Bidirectional));
}
+void UIMachineSettingsGeneral::polishPage()
+{
+ /* Basic tab: */
+ mLbName->setEnabled(isMachineOffline());
+ mLeName->setEnabled(isMachineOffline());
+ mOSTypeSelector->setEnabled(isMachineOffline());
+ /* Advanced tab: */
+ mLbSnapshot->setEnabled(isMachineOffline());
+ mPsSnapshot->setEnabled(isMachineOffline());
+ mLbClipboard->setEnabled(isMachineInValidMode());
+ mCbClipboard->setEnabled(isMachineInValidMode());
+ mLbMedia->setEnabled(isMachineInValidMode());
+ mCbSaveMounted->setEnabled(isMachineInValidMode());
+ mLbToolBar->setEnabled(isMachineInValidMode());
+ mCbShowToolBar->setEnabled(isMachineInValidMode());
+ mCbToolBarAlignment->setEnabled(isMachineInValidMode() && mCbShowToolBar->isChecked());
+}
+
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.h b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.h
index dd6e85955..65dbe11b9 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.h
@@ -5,7 +5,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;
@@ -23,9 +23,37 @@
#include "UIMachineSettingsGeneral.gen.h"
#include "COMDefs.h"
-/* Machine settings / General page / Cache: */
-struct UISettingsCacheMachineGeneral
+/* Machine settings / General page / Data: */
+struct UIDataSettingsMachineGeneral
{
+ /* Default constructor: */
+ UIDataSettingsMachineGeneral()
+ : m_strName(QString())
+ , m_strGuestOsTypeId(QString())
+ , m_fSaveMountedAtRuntime(false)
+ , m_fShowMiniToolBar(false)
+ , m_fMiniToolBarAtTop(false)
+ , m_strSnapshotsFolder(QString())
+ , m_strSnapshotsHomeDir(QString())
+ , m_clipboardMode(KClipboardMode_Disabled)
+ , m_strDescription(QString()) {}
+ /* Functions: */
+ bool equal(const UIDataSettingsMachineGeneral &other) const
+ {
+ return (m_strName == other.m_strName) &&
+ (m_strGuestOsTypeId == other.m_strGuestOsTypeId) &&
+ (m_fSaveMountedAtRuntime == other.m_fSaveMountedAtRuntime) &&
+ (m_fShowMiniToolBar == other.m_fShowMiniToolBar) &&
+ (m_fMiniToolBarAtTop == other.m_fMiniToolBarAtTop) &&
+ (m_strSnapshotsFolder == other.m_strSnapshotsFolder) &&
+ (m_strSnapshotsHomeDir == other.m_strSnapshotsHomeDir) &&
+ (m_clipboardMode == other.m_clipboardMode) &&
+ (m_strDescription == other.m_strDescription);
+ }
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineGeneral &other) const { return equal(other); }
+ bool operator!=(const UIDataSettingsMachineGeneral &other) const { return !equal(other); }
+ /* Variables: */
QString m_strName;
QString m_strGuestOsTypeId;
bool m_fSaveMountedAtRuntime;
@@ -36,6 +64,7 @@ struct UISettingsCacheMachineGeneral
KClipboardMode m_clipboardMode;
QString m_strDescription;
};
+typedef UISettingsCache<UIDataSettingsMachineGeneral> UICacheSettingsMachineGeneral;
/* Machine settings / General page: */
class UIMachineSettingsGeneral : public UISettingsPageMachine,
@@ -47,15 +76,12 @@ public:
UIMachineSettingsGeneral();
+ CGuestOSType guestOSType() const;
+ void setHWVirtExEnabled(bool fEnabled);
bool is64BitOSTypeSelected() const;
-
#ifdef VBOX_WITH_VIDEOHWACCEL
bool isWindowsOSTypeSelected() const;
-#endif
-
-#ifdef VBOX_WITH_CRHGSMI
- bool isWddmSupportedForOSType() const;
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
protected:
@@ -66,6 +92,9 @@ protected:
* this task SHOULD be performed in GUI thread only: */
void getFromCache();
+ /* Page changed: */
+ bool changed() const { return m_cache.wasChanged(); }
+
/* Save data from corresponding widgets to cache,
* this task SHOULD be performed in GUI thread only: */
void putToCache();
@@ -74,6 +103,7 @@ protected:
void saveFromCacheTo(QVariant &data);
void setValidator (QIWidgetValidator *aVal);
+ bool revalidate(QString &strWarning, QString &strTitle);
void setOrderAfter (QWidget *aWidget);
@@ -81,10 +111,13 @@ protected:
private:
+ void polishPage();
+
QIWidgetValidator *mValidator;
+ bool m_fHWVirtExEnabled;
/* Cache: */
- UISettingsCacheMachineGeneral m_cache;
+ UICacheSettingsMachineGeneral m_cache;
};
#endif // __UIMachineSettingsGeneral_h__
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp
index 5348259f8..cf858fae9 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsNetwork.cpp $ */
+/* $Id: UIMachineSettingsNetwork.cpp 37945 2011-07-14 09:40:35Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -17,723 +17,706 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-/* VBox Includes */
-#ifdef VBOX_WITH_VDE
-# include <iprt/ldr.h>
-# include <VBox/VDEPlug.h>
-#endif
-
+/* Local includes: */
#include "QIWidgetValidator.h"
#include "QIArrowButtonSwitch.h"
#include "VBoxGlobal.h"
#include "UIMachineSettingsNetwork.h"
#include "QITabWidget.h"
-/* Qt Includes */
-#include <QTimer>
-#include <QCompleter>
+#ifdef VBOX_WITH_VDE
+# include <iprt/ldr.h>
+# include <VBox/VDEPlug.h>
+#endif /* VBOX_WITH_VDE */
-/* Empty item extra-code */
-const char *emptyItemCode = "#empty#";
+/* Empty item extra-code: */
+const char *pEmptyItemCode = "#empty#";
-/* UIMachineSettingsNetwork Stuff */
-UIMachineSettingsNetwork::UIMachineSettingsNetwork (UIMachineSettingsNetworkPage *aParent, bool aDisableStaticControls)
- : QIWithRetranslateUI <QWidget> (0)
- , mParent (aParent)
- , mValidator (0)
- , m_iSlot(-1)
- , mPolished (false)
- , mDisableStaticControls (false)
+QString wipedOutString(const QString &strInputString)
{
- /* Apply UI decorations */
- Ui::UIMachineSettingsNetwork::setupUi (this);
-
- /* Setup widgets */
- mCbAdapterName->setInsertPolicy (QComboBox::NoInsert);
- mLeMAC->setValidator (new QRegExpValidator (QRegExp (
- "[0-9A-Fa-f][02468ACEace][0-9A-Fa-f]{10}"), this));
- mLeMAC->setMinimumWidthByText (QString().fill ('0', 12));
+ return strInputString.isEmpty() ? QString() : strInputString;
+}
- /* Setup connections */
- connect (mAbsAdvanced, SIGNAL (clicked()), this, SLOT (toggleAdvanced()));
- connect (mTbMAC, SIGNAL (clicked()), this, SLOT (generateMac()));
- connect (mPbPortForwarding, SIGNAL (clicked()), this, SLOT (sltOpenPortForwardingDlg()));
+UIMachineSettingsNetwork::UIMachineSettingsNetwork(UIMachineSettingsNetworkPage *pParent)
+ : QIWithRetranslateUI<QWidget>(0)
+ , m_pParent(pParent)
+ , m_pValidator(0)
+ , m_iSlot(-1)
+{
+ /* Apply UI decorations: */
+ Ui::UIMachineSettingsNetwork::setupUi(this);
+
+ /* Setup widgets: */
+ m_pAdapterNameCombo->setInsertPolicy(QComboBox::NoInsert);
+ m_pMACEditor->setValidator(new QRegExpValidator(QRegExp("[0-9A-Fa-f][02468ACEace][0-9A-Fa-f]{10}"), this));
+ m_pMACEditor->setMinimumWidthByText(QString().fill('0', 12));
+
+ /* Setup connections: */
+ connect(m_pEnableAdapterCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltHandleAdapterActivityChange()));
+ connect(m_pAttachmentTypeComboBox, SIGNAL(activated(int)), this, SLOT(sltHandleAttachmentTypeChange()));
+ connect(m_pAdapterNameCombo, SIGNAL(activated(int)), this, SLOT(sltHandleAlternativeNameChange()));
+ connect(m_pAdapterNameCombo, SIGNAL(editTextChanged(const QString&)), this, SLOT(sltHandleAlternativeNameChange()));
+ connect(m_pAdvancedArrow, SIGNAL(clicked()), this, SLOT(sltHandleAdvancedButtonStateChange()));
+ connect(m_pMACButton, SIGNAL(clicked()), this, SLOT(sltGenerateMac()));
+ connect(m_pPortForwardingButton, SIGNAL(clicked()), this, SLOT(sltOpenPortForwardingDlg()));
+ connect(this, SIGNAL(sigTabUpdated()), m_pParent, SLOT(sltHandleUpdatedTab()));
- /* Applying language settings */
+ /* Applying language settings: */
retranslateUi();
-
- /* If some controls should be disabled or not when the
- * same tab widgets are shown during runtime
- */
- mDisableStaticControls = aDisableStaticControls;
}
-void UIMachineSettingsNetwork::fetchAdapterData(const UINetworkAdapterData &data)
+void UIMachineSettingsNetwork::fetchAdapterCache(const UICacheSettingsMachineNetworkAdapter &adapterCache)
{
- /* Load adapter & slot number: */
- m_iSlot = data.m_iSlot;
- m_adapter = data.m_adapter;
+ /* Get adapter data: */
+ const UIDataSettingsMachineNetworkAdapter &adapterData = adapterCache.base();
- /* Load adapter activity state: */
- mCbEnableAdapter->setChecked(data.m_fAdapterEnabled);
+ /* Load slot number: */
+ m_iSlot = adapterData.m_iSlot;
- /* Load adapter type: */
- int adapterPos = mCbAdapterType->findData(data.m_adapterType);
- mCbAdapterType->setCurrentIndex(adapterPos == -1 ? 0 : adapterPos);
+ /* Load adapter activity state: */
+ m_pEnableAdapterCheckBox->setChecked(adapterData.m_fAdapterEnabled);
+ /* Handle adapter activity change: */
+ sltHandleAdapterActivityChange();
/* Load attachment type: */
- int attachmentPos = mCbAttachmentType->findData(data.m_attachmentType);
- mCbAttachmentType->setCurrentIndex(attachmentPos == -1 ? 0 : attachmentPos);
-
+ m_pAttachmentTypeComboBox->setCurrentIndex(position(m_pAttachmentTypeComboBox, adapterData.m_attachmentType));
/* Load alternative name: */
- switch (attachmentType())
- {
- case KNetworkAttachmentType_Bridged:
- mBrgName = data.m_strBridgedAdapterName;
- if (mBrgName.isEmpty()) mBrgName = QString();
- break;
- case KNetworkAttachmentType_Internal:
- mIntName = data.m_strInternalNetworkName;
- if (mIntName.isEmpty()) mIntName = QString();
- break;
- case KNetworkAttachmentType_HostOnly:
- mHoiName = data.m_strHostInterfaceName;
- if (mHoiName.isEmpty()) mHoiName = QString();
- break;
-#ifdef VBOX_WITH_VDE
- case KNetworkAttachmentType_VDE:
- mVDEName = data.m_strVDENetworkName;
- if (mVDEName.isEmpty()) mVDEName = QString();
- break;
-#endif
- default:
- break;
- }
- updateAttachmentAlternative();
+ m_strBridgedAdapterName = wipedOutString(adapterData.m_strBridgedAdapterName);
+ m_strInternalNetworkName = wipedOutString(adapterData.m_strInternalNetworkName);
+ m_strHostInterfaceName = wipedOutString(adapterData.m_strHostInterfaceName);
+ m_strGenericDriverName = wipedOutString(adapterData.m_strGenericDriverName);
+ /* Handle attachment type change: */
+ sltHandleAttachmentTypeChange();
+
+ /* Load adapter type: */
+ m_pAdapterTypeCombo->setCurrentIndex(position(m_pAdapterTypeCombo, adapterData.m_adapterType));
+
+ /* Load promiscuous mode type: */
+ m_pPromiscuousModeCombo->setCurrentIndex(position(m_pPromiscuousModeCombo, adapterData.m_promiscuousMode));
/* Other options: */
- mLeMAC->setText(data.m_strMACAddress);
- mCbCableConnected->setChecked(data.m_fCableConnected);
+ m_pMACEditor->setText(adapterData.m_strMACAddress);
+ m_pGenericPropertiesTextEdit->setText(adapterData.m_strGenericProperties);
+ m_pCableConnectedCheckBox->setChecked(adapterData.m_fCableConnected);
/* Load port forwarding rules: */
- mPortForwardingRules = data.m_redirects;
+ m_portForwardingRules = adapterData.m_redirects;
}
-void UIMachineSettingsNetwork::uploadAdapterData(UINetworkAdapterData &data)
+void UIMachineSettingsNetwork::uploadAdapterCache(UICacheSettingsMachineNetworkAdapter &adapterCache)
{
- /* Save adapter activity state: */
- data.m_fAdapterEnabled = mCbEnableAdapter->isChecked();
+ /* Prepare adapter data: */
+ UIDataSettingsMachineNetworkAdapter adapterData = adapterCache.base();
- /* Save adapter type: */
- data.m_adapterType = (KNetworkAdapterType)mCbAdapterType->itemData(mCbAdapterType->currentIndex()).toInt();
+ /* Save adapter activity state: */
+ adapterData.m_fAdapterEnabled = m_pEnableAdapterCheckBox->isChecked();
/* Save attachment type & alternative name: */
- data.m_attachmentType = attachmentType();
- switch (data.m_attachmentType)
+ adapterData.m_attachmentType = attachmentType();
+ switch (adapterData.m_attachmentType)
{
case KNetworkAttachmentType_Null:
break;
case KNetworkAttachmentType_NAT:
break;
case KNetworkAttachmentType_Bridged:
- data.m_strBridgedAdapterName = alternativeName();
+ adapterData.m_strBridgedAdapterName = alternativeName();
break;
case KNetworkAttachmentType_Internal:
- data.m_strInternalNetworkName = alternativeName();
+ adapterData.m_strInternalNetworkName = alternativeName();
break;
case KNetworkAttachmentType_HostOnly:
- data.m_strHostInterfaceName = alternativeName();
+ adapterData.m_strHostInterfaceName = alternativeName();
break;
-#ifdef VBOX_WITH_VDE
- case KNetworkAttachmentType_VDE:
- data.m_strVDENetworkName = alternativeName();
+ case KNetworkAttachmentType_Generic:
+ adapterData.m_strGenericDriverName = alternativeName();
+ adapterData.m_strGenericProperties = m_pGenericPropertiesTextEdit->toPlainText();
break;
-#endif
default:
break;
}
+ /* Save adapter type: */
+ adapterData.m_adapterType = (KNetworkAdapterType)m_pAdapterTypeCombo->itemData(m_pAdapterTypeCombo->currentIndex()).toInt();
+
+ /* Save promiscuous mode type: */
+ adapterData.m_promiscuousMode = (KNetworkAdapterPromiscModePolicy)m_pPromiscuousModeCombo->itemData(m_pPromiscuousModeCombo->currentIndex()).toInt();
+
/* Other options: */
- data.m_strMACAddress = mLeMAC->text().isEmpty() ? QString() : mLeMAC->text();
- data.m_fCableConnected = mCbCableConnected->isChecked();
+ adapterData.m_strMACAddress = m_pMACEditor->text().isEmpty() ? QString() : m_pMACEditor->text();
+ adapterData.m_fCableConnected = m_pCableConnectedCheckBox->isChecked();
/* Save port forwarding rules: */
- data.m_redirects = mPortForwardingRules;
+ adapterData.m_redirects = m_portForwardingRules;
+
+ /* Cache adapter data: */
+ adapterCache.cacheCurrentData(adapterData);
}
-void UIMachineSettingsNetwork::setValidator (QIWidgetValidator *aValidator)
+void UIMachineSettingsNetwork::setValidator(QIWidgetValidator *pValidator)
{
- mValidator = aValidator;
-
- if (!mDisableStaticControls)
- connect (mCbEnableAdapter, SIGNAL (toggled (bool)),
- mValidator, SLOT (revalidate()));
- connect (mCbAttachmentType, SIGNAL (activated (const QString&)),
- this, SLOT (updateAttachmentAlternative()));
- connect (mCbAdapterName, SIGNAL (activated (const QString&)),
- this, SLOT (updateAlternativeName()));
- connect (mCbAdapterName, SIGNAL (editTextChanged (const QString&)),
- this, SLOT (updateAlternativeName()));
-
- if (!mDisableStaticControls)
- mValidator->revalidate();
+ m_pValidator = pValidator;
}
-bool UIMachineSettingsNetwork::revalidate (QString &aWarning, QString &aTitle)
+bool UIMachineSettingsNetwork::revalidate(QString &strWarning, QString &strTitle)
{
- /* 'True' for disabled adapter */
- if (!mCbEnableAdapter->isChecked())
+ /* 'True' for disabled adapter: */
+ if (!m_pEnableAdapterCheckBox->isChecked())
return true;
- /* Validate alternatives */
- bool valid = true;
+ /* Validate alternatives: */
+ bool fValid = true;
switch (attachmentType())
{
case KNetworkAttachmentType_Bridged:
+ {
if (alternativeName().isNull())
{
- aWarning = tr ("no bridged network adapter is selected");
- valid = false;
+ strWarning = tr("no bridged network adapter is selected");
+ fValid = false;
}
break;
+ }
case KNetworkAttachmentType_Internal:
+ {
if (alternativeName().isNull())
{
- aWarning = tr ("no internal network name is specified");
- valid = false;
+ strWarning = tr("no internal network name is specified");
+ fValid = false;
}
break;
+ }
case KNetworkAttachmentType_HostOnly:
+ {
+ if (alternativeName().isNull())
+ {
+ strWarning = tr("no host-only network adapter is selected");
+ fValid = false;
+ }
+ break;
+ }
+ case KNetworkAttachmentType_Generic:
+ {
if (alternativeName().isNull())
{
- aWarning = tr ("no host-only network adapter is selected");
- valid = false;
+ strWarning = tr("no generic driver is selected");
+ fValid = false;
}
break;
+ }
default:
break;
}
+ if (!fValid)
+ strTitle += ": " + vboxGlobal().removeAccelMark(tabTitle());
- if (!valid)
- aTitle += ": " + vboxGlobal().removeAccelMark (pageTitle());
-
- return valid;
+ return fValid;
}
-QWidget* UIMachineSettingsNetwork::setOrderAfter (QWidget *aAfter)
+QWidget* UIMachineSettingsNetwork::setOrderAfter(QWidget *pAfter)
{
- setTabOrder (aAfter, mCbEnableAdapter);
- setTabOrder (mCbEnableAdapter, mCbAttachmentType);
- setTabOrder (mCbAttachmentType, mCbAdapterName);
- setTabOrder (mCbAdapterName, mAbsAdvanced);
- setTabOrder (mAbsAdvanced, mCbAdapterType);
- setTabOrder (mCbAdapterType, mLeMAC);
- setTabOrder (mLeMAC, mTbMAC);
- setTabOrder (mTbMAC, mCbCableConnected);
- setTabOrder (mCbCableConnected, mPbPortForwarding);
- return mPbPortForwarding;
+ setTabOrder(pAfter, m_pEnableAdapterCheckBox);
+ setTabOrder(m_pEnableAdapterCheckBox, m_pAttachmentTypeComboBox);
+ setTabOrder(m_pAttachmentTypeComboBox, m_pAdapterNameCombo);
+ setTabOrder(m_pAdapterNameCombo, m_pAdvancedArrow);
+ setTabOrder(m_pAdvancedArrow, m_pAdapterTypeCombo);
+ setTabOrder(m_pAdapterTypeCombo, m_pPromiscuousModeCombo);
+ setTabOrder(m_pPromiscuousModeCombo, m_pMACEditor);
+ setTabOrder(m_pMACEditor, m_pMACButton);
+ setTabOrder(m_pMACButton, m_pGenericPropertiesTextEdit);
+ setTabOrder(m_pGenericPropertiesTextEdit, m_pCableConnectedCheckBox);
+ setTabOrder(m_pCableConnectedCheckBox, m_pPortForwardingButton);
+ return m_pPortForwardingButton;
}
-QString UIMachineSettingsNetwork::pageTitle() const
+QString UIMachineSettingsNetwork::tabTitle() const
{
- return VBoxGlobal::tr("Adapter %1", "network").arg(QString("&%1").arg(m_iSlot + 1));;
+ return VBoxGlobal::tr("Adapter %1").arg(QString("&%1").arg(m_iSlot + 1));
}
KNetworkAttachmentType UIMachineSettingsNetwork::attachmentType() const
{
- return (KNetworkAttachmentType) mCbAttachmentType->itemData (
- mCbAttachmentType->currentIndex()).toInt();
+ return (KNetworkAttachmentType)m_pAttachmentTypeComboBox->itemData(m_pAttachmentTypeComboBox->currentIndex()).toInt();
}
-QString UIMachineSettingsNetwork::alternativeName (int aType) const
+QString UIMachineSettingsNetwork::alternativeName(int iType) const
{
- if (aType == -1) aType = attachmentType();
- QString result;
- switch (aType)
+ if (iType == -1)
+ iType = attachmentType();
+ QString strResult;
+ switch (iType)
{
case KNetworkAttachmentType_Bridged:
- result = mBrgName;
+ strResult = m_strBridgedAdapterName;
break;
case KNetworkAttachmentType_Internal:
- result = mIntName;
+ strResult = m_strInternalNetworkName;
break;
case KNetworkAttachmentType_HostOnly:
- result = mHoiName;
+ strResult = m_strHostInterfaceName;
break;
-#ifdef VBOX_WITH_VDE
- case KNetworkAttachmentType_VDE:
- result = mVDEName;
+ case KNetworkAttachmentType_Generic:
+ strResult = m_strGenericDriverName;
break;
-#endif
default:
break;
}
- Assert (result.isNull() || !result.isEmpty());
- return result;
+ Assert(strResult.isNull() || !strResult.isEmpty());
+ return strResult;
}
-void UIMachineSettingsNetwork::showEvent (QShowEvent *aEvent)
+void UIMachineSettingsNetwork::polishTab()
{
- if (!mPolished)
- {
- mPolished = true;
-
- /* Give the minimum size hint to the first layout column */
- mNetworkChildGridLayout->setColumnMinimumWidth (0, mLbAttachmentType->width());
+ /* Basic attributes: */
+ m_pEnableAdapterCheckBox->setEnabled(m_pParent->isMachineOffline());
+ m_pAttachmentTypeLabel->setEnabled(m_pParent->isMachineInValidMode());
+ m_pAttachmentTypeComboBox->setEnabled(m_pParent->isMachineInValidMode());
+ m_pAdapterNameLabel->setEnabled(m_pParent->isMachineInValidMode() &&
+ attachmentType() != KNetworkAttachmentType_Null &&
+ attachmentType() != KNetworkAttachmentType_NAT);
+ m_pAdapterNameCombo->setEnabled(m_pParent->isMachineInValidMode() &&
+ attachmentType() != KNetworkAttachmentType_Null &&
+ attachmentType() != KNetworkAttachmentType_NAT);
+ m_pAdvancedArrow->setEnabled(m_pParent->isMachineInValidMode());
+
+ /* Advanced attributes: */
+ m_pAdapterTypeLabel->setEnabled(m_pParent->isMachineOffline());
+ m_pAdapterTypeCombo->setEnabled(m_pParent->isMachineOffline());
+ m_pPromiscuousModeLabel->setEnabled(m_pParent->isMachineInValidMode() &&
+ attachmentType() != KNetworkAttachmentType_Null &&
+ attachmentType() != KNetworkAttachmentType_Generic &&
+ attachmentType() != KNetworkAttachmentType_NAT);
+ m_pPromiscuousModeCombo->setEnabled(m_pParent->isMachineInValidMode() &&
+ attachmentType() != KNetworkAttachmentType_Null &&
+ attachmentType() != KNetworkAttachmentType_Generic &&
+ attachmentType() != KNetworkAttachmentType_NAT);
+ m_pMACLabel->setEnabled(m_pParent->isMachineOffline());
+ m_pMACEditor->setEnabled(m_pParent->isMachineOffline());
+ m_pMACButton->setEnabled(m_pParent->isMachineOffline());
+ m_pGenericPropertiesLabel->setEnabled(m_pParent->isMachineInValidMode());
+ m_pGenericPropertiesTextEdit->setEnabled(m_pParent->isMachineInValidMode());
+ m_pPortForwardingButton->setEnabled(m_pParent->isMachineInValidMode() &&
+ attachmentType() == KNetworkAttachmentType_NAT);
+
+ /* Postprocessing: */
+ if ((m_pParent->isMachineSaved() || m_pParent->isMachineOnline()) && !m_pAdvancedArrow->isExpanded())
+ m_pAdvancedArrow->animateClick();
+ sltHandleAdvancedButtonStateChange();
+}
- if (mDisableStaticControls)
- {
- /* Disable controls for dynamically displayed page */
- mCbEnableAdapter->setEnabled (false);
- mCbAdapterType->setEnabled (false);
- mLeMAC->setEnabled (false);
- mTbMAC->setEnabled (false);
- mLbAdapterType->setEnabled (false);
- mLbMAC->setEnabled (false);
- mAbsAdvanced->animateClick();
- }
- else
- {
- /* Hide advanced items initially */
- toggleAdvanced();
- }
- }
- QWidget::showEvent (aEvent);
+void UIMachineSettingsNetwork::reloadAlternative()
+{
+ /* Repopulate alternative-name combo-box content: */
+ updateAlternativeList();
+ /* Select previous or default alternative-name combo-box item: */
+ updateAlternativeName();
}
void UIMachineSettingsNetwork::retranslateUi()
{
- /* Translate uic generated strings */
- Ui::UIMachineSettingsNetwork::retranslateUi (this);
+ /* Translate uic generated strings: */
+ Ui::UIMachineSettingsNetwork::retranslateUi(this);
- /* Translate combo-boxes content */
+ /* Translate combo-boxes content: */
populateComboboxes();
- /* Translate attachment info */
- updateAttachmentAlternative();
+ /* Translate attachment info: */
+ sltHandleAttachmentTypeChange();
}
-void UIMachineSettingsNetwork::updateAttachmentAlternative()
+void UIMachineSettingsNetwork::sltHandleAdapterActivityChange()
{
- /* Blocking signals to change content manually */
- mCbAdapterName->blockSignals (true);
-
- /* Update alternative-name combo-box availability */
- mLbAdapterName->setEnabled (attachmentType() != KNetworkAttachmentType_Null &&
- attachmentType() != KNetworkAttachmentType_NAT);
- mCbAdapterName->setEnabled (attachmentType() != KNetworkAttachmentType_Null &&
- attachmentType() != KNetworkAttachmentType_NAT);
+ /* Update availability: */
+ m_pAdapterOptionsContainer->setEnabled(m_pEnableAdapterCheckBox->isChecked());
+ /* Revalidate if possible: */
+ if (m_pValidator)
+ m_pValidator->revalidate();
+}
- /* Refresh list */
- mCbAdapterName->clear();
+void UIMachineSettingsNetwork::sltHandleAttachmentTypeChange()
+{
+ /* Update alternative-name combo-box availability: */
+ m_pAdapterNameLabel->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
+ attachmentType() != KNetworkAttachmentType_NAT);
+ m_pAdapterNameCombo->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
+ attachmentType() != KNetworkAttachmentType_NAT);
+ /* Update promiscuous-mode combo-box availability: */
+ m_pPromiscuousModeLabel->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
+ attachmentType() != KNetworkAttachmentType_Generic &&
+ attachmentType() != KNetworkAttachmentType_NAT);
+ m_pPromiscuousModeCombo->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
+ attachmentType() != KNetworkAttachmentType_Generic &&
+ attachmentType() != KNetworkAttachmentType_NAT);
+ /* Update generic-properties editor visibility: */
+ m_pGenericPropertiesLabel->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
+ m_pAdvancedArrow->isExpanded());
+ m_pGenericPropertiesTextEdit->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
+ m_pAdvancedArrow->isExpanded());
+ /* Update forwarding-rules button availability: */
+ m_pPortForwardingButton->setEnabled(attachmentType() == KNetworkAttachmentType_NAT);
+ /* Update alternative-name combo-box whats-this and editable state: */
switch (attachmentType())
{
case KNetworkAttachmentType_Bridged:
- mCbAdapterName->insertItems (0, mParent->brgList());
- mCbAdapterName->setEditable (false);
+ {
+ m_pAdapterNameCombo->setWhatsThis(tr("Selects the network adapter on the host system that traffic "
+ "to and from this network card will go through."));
+ m_pAdapterNameCombo->setEditable(false);
break;
+ }
case KNetworkAttachmentType_Internal:
- mCbAdapterName->insertItems (0, mParent->fullIntList());
- mCbAdapterName->setEditable (true);
- mCbAdapterName->setCompleter (0);
- break;
- case KNetworkAttachmentType_HostOnly:
- mCbAdapterName->insertItems (0, mParent->hoiList());
- mCbAdapterName->setEditable (false);
- break;
-#ifdef VBOX_WITH_VDE
- case KNetworkAttachmentType_VDE:
- mCbAdapterName->insertItem(0, alternativeName());
- mCbAdapterName->setEditable (true);
- mCbAdapterName->setCompleter (0);
- break;
-#endif
- default:
- break;
- }
-
- /* Prepend 'empty' or 'default' item */
- if (mCbAdapterName->count() == 0)
- {
- switch (attachmentType())
{
- case KNetworkAttachmentType_Bridged:
- case KNetworkAttachmentType_HostOnly:
- {
- /* Adapters list 'empty' */
- int pos = mCbAdapterName->findData (emptyItemCode);
- if (pos == -1)
- mCbAdapterName->insertItem (0, tr ("Not selected", "network adapter name"), emptyItemCode);
- else
- mCbAdapterName->setItemText (pos, tr ("Not selected", "network adapter name"));
- break;
- }
- case KNetworkAttachmentType_Internal:
- {
- /* Internal network 'default' name */
- if (mCbAdapterName->findText ("intnet") == -1)
- mCbAdapterName->insertItem (0, "intnet");
- break;
- }
- default:
- break;
+ m_pAdapterNameCombo->setWhatsThis(tr("Enter the name of the internal network that this network card "
+ "will be connected to. You can create a new internal network by "
+ "choosing a name which is not used by any other network cards "
+ "in this virtual machine or others."));
+ m_pAdapterNameCombo->setEditable(true);
+ break;
}
- }
-
- /* Select previous or default item */
- switch (attachmentType())
- {
- case KNetworkAttachmentType_Bridged:
case KNetworkAttachmentType_HostOnly:
{
- int pos = mCbAdapterName->findText (alternativeName());
- mCbAdapterName->setCurrentIndex (pos == -1 ? 0 : pos);
+ m_pAdapterNameCombo->setWhatsThis(tr("Selects the virtual network adapter on the host system that traffic "
+ "to and from this network card will go through. "
+ "You can create and remove adapters using the global network "
+ "settings in the virtual machine manager window."));
+ m_pAdapterNameCombo->setEditable(false);
break;
}
- case KNetworkAttachmentType_Internal:
+ case KNetworkAttachmentType_Generic:
{
- int pos = mCbAdapterName->findText (alternativeName());
- mCbAdapterName->setCurrentIndex (pos == -1 ? 0 : pos);
+ m_pAdapterNameCombo->setWhatsThis(tr("Selects the driver to be used with this network card."));
+ m_pAdapterNameCombo->setEditable(true);
break;
}
default:
+ {
+ m_pAdapterNameCombo->setWhatsThis(QString());
break;
+ }
}
- /* Remember selected item */
- updateAlternativeName();
+ /* Update alternative combo: */
+ reloadAlternative();
- /* Update Forwarding rules button availability: */
- mPbPortForwarding->setEnabled(attachmentType() == KNetworkAttachmentType_NAT);
-
- /* Unblocking signals as content is changed already */
- mCbAdapterName->blockSignals (false);
+ /* Handle alternative-name cange: */
+ sltHandleAlternativeNameChange();
}
-void UIMachineSettingsNetwork::updateAlternativeName()
+void UIMachineSettingsNetwork::sltHandleAlternativeNameChange()
{
+ /* Remember new name if its changed,
+ * Call for other pages update, if necessary: */
switch (attachmentType())
{
case KNetworkAttachmentType_Bridged:
{
- QString newName (mCbAdapterName->itemData (mCbAdapterName->currentIndex()).toString() ==
- QString (emptyItemCode) ||
- mCbAdapterName->currentText().isEmpty() ?
- QString::null : mCbAdapterName->currentText());
- if (mBrgName != newName)
- mBrgName = newName;
+ QString newName(m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() == QString(pEmptyItemCode) ||
+ m_pAdapterNameCombo->currentText().isEmpty() ? QString() : m_pAdapterNameCombo->currentText());
+ if (m_strBridgedAdapterName != newName)
+ m_strBridgedAdapterName = newName;
break;
}
case KNetworkAttachmentType_Internal:
{
- QString newName ((mCbAdapterName->itemData (mCbAdapterName->currentIndex()).toString() ==
- QString (emptyItemCode) &&
- mCbAdapterName->currentText() ==
- mCbAdapterName->itemText (mCbAdapterName->currentIndex())) ||
- mCbAdapterName->currentText().isEmpty() ?
- QString::null : mCbAdapterName->currentText());
- if (mIntName != newName)
+ QString newName((m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() == QString(pEmptyItemCode) &&
+ m_pAdapterNameCombo->currentText() == m_pAdapterNameCombo->itemText(m_pAdapterNameCombo->currentIndex())) ||
+ m_pAdapterNameCombo->currentText().isEmpty() ? QString() : m_pAdapterNameCombo->currentText());
+ if (m_strInternalNetworkName != newName)
{
- mIntName = newName;
- if (!mIntName.isNull())
- QTimer::singleShot (0, mParent, SLOT (updatePages()));
+ m_strInternalNetworkName = newName;
+ if (!m_strInternalNetworkName.isNull())
+ emit sigTabUpdated();
}
break;
}
case KNetworkAttachmentType_HostOnly:
{
- QString newName (mCbAdapterName->itemData (mCbAdapterName->currentIndex()).toString() ==
- QString (emptyItemCode) ||
- mCbAdapterName->currentText().isEmpty() ?
- QString::null : mCbAdapterName->currentText());
- if (mHoiName != newName)
- mHoiName = newName;
+ QString newName(m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() == QString(pEmptyItemCode) ||
+ m_pAdapterNameCombo->currentText().isEmpty() ? QString() : m_pAdapterNameCombo->currentText());
+ if (m_strHostInterfaceName != newName)
+ m_strHostInterfaceName = newName;
break;
}
-#ifdef VBOX_WITH_VDE
- case KNetworkAttachmentType_VDE:
+ case KNetworkAttachmentType_Generic:
{
- QString newName ((mCbAdapterName->itemData (mCbAdapterName->currentIndex()).toString() ==
- QString (emptyItemCode) &&
- mCbAdapterName->currentText() ==
- mCbAdapterName->itemText (mCbAdapterName->currentIndex())) ||
- mCbAdapterName->currentText().isEmpty() ?
- QString::null : mCbAdapterName->currentText());
- if (mVDEName != newName)
- mVDEName = newName;
+ QString newName((m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() == QString(pEmptyItemCode) &&
+ m_pAdapterNameCombo->currentText() == m_pAdapterNameCombo->itemText(m_pAdapterNameCombo->currentIndex())) ||
+ m_pAdapterNameCombo->currentText().isEmpty() ? QString() : m_pAdapterNameCombo->currentText());
+ if (m_strGenericDriverName != newName)
+ {
+ m_strGenericDriverName = newName;
+ if (!m_strGenericDriverName.isNull())
+ emit sigTabUpdated();
+ }
break;
}
-#endif
default:
break;
}
- if (mValidator)
- mValidator->revalidate();
+ /* Revalidate if possible: */
+ if (m_pValidator)
+ m_pValidator->revalidate();
}
-void UIMachineSettingsNetwork::toggleAdvanced()
+void UIMachineSettingsNetwork::sltHandleAdvancedButtonStateChange()
{
- mLbAdapterType->setVisible (mAbsAdvanced->isExpanded());
- mCbAdapterType->setVisible (mAbsAdvanced->isExpanded());
- mLbMAC->setVisible (mAbsAdvanced->isExpanded());
- mLeMAC->setVisible (mAbsAdvanced->isExpanded());
- mTbMAC->setVisible (mAbsAdvanced->isExpanded());
- mCbCableConnected->setVisible (mAbsAdvanced->isExpanded());
- mPbPortForwarding->setVisible (mAbsAdvanced->isExpanded());
+ /* Update visibility of advanced options: */
+ m_pAdapterTypeLabel->setVisible(m_pAdvancedArrow->isExpanded());
+ m_pAdapterTypeCombo->setVisible(m_pAdvancedArrow->isExpanded());
+ m_pPromiscuousModeLabel->setVisible(m_pAdvancedArrow->isExpanded());
+ m_pPromiscuousModeCombo->setVisible(m_pAdvancedArrow->isExpanded());
+ m_pGenericPropertiesLabel->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
+ m_pAdvancedArrow->isExpanded());
+ m_pGenericPropertiesTextEdit->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
+ m_pAdvancedArrow->isExpanded());
+ m_pMACLabel->setVisible(m_pAdvancedArrow->isExpanded());
+ m_pMACEditor->setVisible(m_pAdvancedArrow->isExpanded());
+ m_pMACButton->setVisible(m_pAdvancedArrow->isExpanded());
+ m_pCableConnectedCheckBox->setVisible(m_pAdvancedArrow->isExpanded());
+ m_pPortForwardingButton->setVisible(m_pAdvancedArrow->isExpanded());
}
-void UIMachineSettingsNetwork::generateMac()
+void UIMachineSettingsNetwork::sltGenerateMac()
{
- m_adapter.SetMACAddress(QString::null);
- mLeMAC->setText(m_adapter.GetMACAddress());
+ m_pMACEditor->setText(vboxGlobal().virtualBox().GetHost().GenerateMACAddress());
}
void UIMachineSettingsNetwork::sltOpenPortForwardingDlg()
{
- UIMachineSettingsPortForwardingDlg dlg(this, mPortForwardingRules);
+ UIMachineSettingsPortForwardingDlg dlg(this, m_portForwardingRules);
if (dlg.exec() == QDialog::Accepted)
- mPortForwardingRules = dlg.rules();
+ m_portForwardingRules = dlg.rules();
}
void UIMachineSettingsNetwork::populateComboboxes()
{
- /* Save the current selected adapter */
- int currentAdapter = mCbAdapterType->currentIndex();
-
- /* Clear the adapters combo-box */
- mCbAdapterType->clear();
-
- /* Populate adapters */
- mCbAdapterType->insertItem (0,
- vboxGlobal().toString (KNetworkAdapterType_Am79C970A));
- mCbAdapterType->setItemData (0,
- KNetworkAdapterType_Am79C970A);
- mCbAdapterType->setItemData (0,
- mCbAdapterType->itemText (0), Qt::ToolTipRole);
- mCbAdapterType->insertItem (1,
- vboxGlobal().toString (KNetworkAdapterType_Am79C973));
- mCbAdapterType->setItemData (1,
- KNetworkAdapterType_Am79C973);
- mCbAdapterType->setItemData (1,
- mCbAdapterType->itemText (1), Qt::ToolTipRole);
+ /* Attachment type: */
+ {
+ /* Remember the currently selected attachment type: */
+ int iCurrentAttachment = m_pAttachmentTypeComboBox->currentIndex();
+
+ /* Clear the attachments combo-box: */
+ m_pAttachmentTypeComboBox->clear();
+
+ /* Populate attachments: */
+ int iAttachmentTypeIndex = 0;
+ m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, vboxGlobal().toString(KNetworkAttachmentType_Null));
+ m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_Null);
+ m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
+ ++iAttachmentTypeIndex;
+ m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, vboxGlobal().toString(KNetworkAttachmentType_NAT));
+ m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_NAT);
+ m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
+ ++iAttachmentTypeIndex;
+ m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, vboxGlobal().toString(KNetworkAttachmentType_Bridged));
+ m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_Bridged);
+ m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
+ ++iAttachmentTypeIndex;
+ m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, vboxGlobal().toString(KNetworkAttachmentType_Internal));
+ m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_Internal);
+ m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
+ ++iAttachmentTypeIndex;
+ m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, vboxGlobal().toString(KNetworkAttachmentType_HostOnly));
+ m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_HostOnly);
+ m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
+ ++iAttachmentTypeIndex;
+ m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, vboxGlobal().toString(KNetworkAttachmentType_Generic));
+ m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_Generic);
+ m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
+ ++iAttachmentTypeIndex;
+
+ /* Restore the previously selected attachment type: */
+ m_pAttachmentTypeComboBox->setCurrentIndex(iCurrentAttachment == -1 ? 0 : iCurrentAttachment);
+ }
+
+ /* Adapter type: */
+ {
+ /* Remember the currently selected adapter type: */
+ int iCurrentAdapter = m_pAdapterTypeCombo->currentIndex();
+
+ /* Clear the adapter type combo-box: */
+ m_pAdapterTypeCombo->clear();
+
+ /* Populate adapter types: */
+ int iAdapterTypeIndex = 0;
+ m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, vboxGlobal().toString(KNetworkAdapterType_Am79C970A));
+ m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_Am79C970A);
+ m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
+ ++iAdapterTypeIndex;
+ m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, vboxGlobal().toString(KNetworkAdapterType_Am79C973));
+ m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_Am79C973);
+ m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
+ ++iAdapterTypeIndex;
#ifdef VBOX_WITH_E1000
- mCbAdapterType->insertItem (2,
- vboxGlobal().toString (KNetworkAdapterType_I82540EM));
- mCbAdapterType->setItemData (2,
- KNetworkAdapterType_I82540EM);
- mCbAdapterType->setItemData (2,
- mCbAdapterType->itemText (2), Qt::ToolTipRole);
- mCbAdapterType->insertItem (3,
- vboxGlobal().toString (KNetworkAdapterType_I82543GC));
- mCbAdapterType->setItemData (3,
- KNetworkAdapterType_I82543GC);
- mCbAdapterType->setItemData (3,
- mCbAdapterType->itemText (3), Qt::ToolTipRole);
- mCbAdapterType->insertItem (4,
- vboxGlobal().toString (KNetworkAdapterType_I82545EM));
- mCbAdapterType->setItemData (4,
- KNetworkAdapterType_I82545EM);
- mCbAdapterType->setItemData (4,
- mCbAdapterType->itemText (4), Qt::ToolTipRole);
+ m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, vboxGlobal().toString(KNetworkAdapterType_I82540EM));
+ m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_I82540EM);
+ m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
+ ++iAdapterTypeIndex;
+ m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, vboxGlobal().toString(KNetworkAdapterType_I82543GC));
+ m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_I82543GC);
+ m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
+ ++iAdapterTypeIndex;
+ m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, vboxGlobal().toString(KNetworkAdapterType_I82545EM));
+ m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_I82545EM);
+ m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
+ ++iAdapterTypeIndex;
#endif /* VBOX_WITH_E1000 */
#ifdef VBOX_WITH_VIRTIO
- mCbAdapterType->insertItem (5,
- vboxGlobal().toString (KNetworkAdapterType_Virtio));
- mCbAdapterType->setItemData (5,
- KNetworkAdapterType_Virtio);
- mCbAdapterType->setItemData (5,
- mCbAdapterType->itemText (5), Qt::ToolTipRole);
+ m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, vboxGlobal().toString(KNetworkAdapterType_Virtio));
+ m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_Virtio);
+ m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
+ ++iAdapterTypeIndex;
#endif /* VBOX_WITH_VIRTIO */
- /* Set the old value */
- mCbAdapterType->setCurrentIndex (currentAdapter == -1 ?
- 0 : currentAdapter);
-
-
- /* Save the current selected attachment type */
- int currentAttachment = mCbAttachmentType->currentIndex();
-
- /* Clear the attachments combo-box */
- mCbAttachmentType->clear();
-
- /* Populate attachments */
- mCbAttachmentType->insertItem (0,
- vboxGlobal().toString (KNetworkAttachmentType_Null));
- mCbAttachmentType->setItemData (0,
- KNetworkAttachmentType_Null);
- mCbAttachmentType->setItemData (0,
- mCbAttachmentType->itemText (0), Qt::ToolTipRole);
- mCbAttachmentType->insertItem (1,
- vboxGlobal().toString (KNetworkAttachmentType_NAT));
- mCbAttachmentType->setItemData (1,
- KNetworkAttachmentType_NAT);
- mCbAttachmentType->setItemData (1,
- mCbAttachmentType->itemText (1), Qt::ToolTipRole);
- mCbAttachmentType->insertItem (2,
- vboxGlobal().toString (KNetworkAttachmentType_Bridged));
- mCbAttachmentType->setItemData (2,
- KNetworkAttachmentType_Bridged);
- mCbAttachmentType->setItemData (2,
- mCbAttachmentType->itemText (2), Qt::ToolTipRole);
- mCbAttachmentType->insertItem (3,
- vboxGlobal().toString (KNetworkAttachmentType_Internal));
- mCbAttachmentType->setItemData (3,
- KNetworkAttachmentType_Internal);
- mCbAttachmentType->setItemData (3,
- mCbAttachmentType->itemText (3), Qt::ToolTipRole);
- mCbAttachmentType->insertItem (4,
- vboxGlobal().toString (KNetworkAttachmentType_HostOnly));
- mCbAttachmentType->setItemData (4,
- KNetworkAttachmentType_HostOnly);
- mCbAttachmentType->setItemData (4,
- mCbAttachmentType->itemText (4), Qt::ToolTipRole);
-#ifdef VBOX_WITH_VDE
- RTLDRMOD hLdrDummy;
- if (RT_SUCCESS(RTLdrLoad(VBOX_LIB_VDE_PLUG_NAME, &hLdrDummy)))
- {
- mCbAttachmentType->insertItem (5,
- vboxGlobal().toString (KNetworkAttachmentType_VDE));
- mCbAttachmentType->setItemData (5,
- KNetworkAttachmentType_VDE);
- mCbAttachmentType->setItemData (5,
- mCbAttachmentType->itemText (5), Qt::ToolTipRole);
+ /* Restore the previously selected adapter type: */
+ m_pAdapterTypeCombo->setCurrentIndex(iCurrentAdapter == -1 ? 0 : iCurrentAdapter);
}
-#endif
-
- /* Set the old value */
- mCbAttachmentType->setCurrentIndex (currentAttachment);
-}
-
-/* UIMachineSettingsNetworkPage Stuff */
-UIMachineSettingsNetworkPage::UIMachineSettingsNetworkPage(bool aDisableStaticControls)
- : mValidator(0)
- , mTwAdapters(0)
- , mDisableStaticControls(false)
-{
- /* Setup Main Layout */
- QVBoxLayout *mainLayout = new QVBoxLayout (this);
- mainLayout->setContentsMargins (0, 5, 0, 5);
-
- /* Creating Tab Widget */
- mTwAdapters = new QITabWidget (this);
- mainLayout->addWidget (mTwAdapters);
-
- /* If some controls should be disabled or not when the
- * same tab widgets are shown during runtime
- */
- mDisableStaticControls = aDisableStaticControls;
- /* How many adapters to display */
- ulong uCount = qMin((ULONG)4, vboxGlobal().virtualBox().GetSystemProperties().GetNetworkAdapterCount());
- /* Add the tab pages to parent tab widget. Needed for space calculations. */
- for (ulong iSlot = 0; iSlot < uCount; ++iSlot)
+ /* Promiscuous Mode type: */
{
- /* Creating adapter's page: */
- UIMachineSettingsNetwork *pPage = new UIMachineSettingsNetwork(this, mDisableStaticControls);
- /* Attach adapter's page to Tab Widget: */
- mTwAdapters->addTab(pPage, pPage->pageTitle());
+ /* Remember the currently selected promiscuous mode type: */
+ int iCurrentPromiscuousMode = m_pPromiscuousModeCombo->currentIndex();
+
+ /* Clear the promiscuous mode combo-box: */
+ m_pPromiscuousModeCombo->clear();
+
+ /* Populate promiscuous modes: */
+ int iPromiscuousModeIndex = 0;
+ m_pPromiscuousModeCombo->insertItem(iPromiscuousModeIndex, vboxGlobal().toString(KNetworkAdapterPromiscModePolicy_Deny));
+ m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_Deny);
+ m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, m_pPromiscuousModeCombo->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
+ ++iPromiscuousModeIndex;
+ m_pPromiscuousModeCombo->insertItem(iPromiscuousModeIndex, vboxGlobal().toString(KNetworkAdapterPromiscModePolicy_AllowNetwork));
+ m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_AllowNetwork);
+ m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, m_pPromiscuousModeCombo->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
+ ++iPromiscuousModeIndex;
+ m_pPromiscuousModeCombo->insertItem(iPromiscuousModeIndex, vboxGlobal().toString(KNetworkAdapterPromiscModePolicy_AllowAll));
+ m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_AllowAll);
+ m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, m_pPromiscuousModeCombo->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
+ ++iPromiscuousModeIndex;
+
+ /* Restore the previously selected promiscuous mode type: */
+ m_pPromiscuousModeCombo->setCurrentIndex(iCurrentPromiscuousMode == -1 ? 0 : iCurrentPromiscuousMode);
}
}
-void UIMachineSettingsNetworkPage::loadDirectlyFrom(const CMachine &machine)
+void UIMachineSettingsNetwork::updateAlternativeList()
{
- qRegisterMetaType<UISettingsDataMachine>();
- UISettingsDataMachine data(machine);
- QVariant wrapper = QVariant::fromValue(data);
- loadToCacheFrom(wrapper);
- getFromCache();
-}
+ /* Block signals initially: */
+ m_pAdapterNameCombo->blockSignals(true);
-void UIMachineSettingsNetworkPage::saveDirectlyTo(CMachine &machine)
-{
- qRegisterMetaType<UISettingsDataMachine>();
- UISettingsDataMachine data(machine);
- QVariant wrapper = QVariant::fromValue(data);
- putToCache();
- saveFromCacheTo(wrapper);
-}
-
-QStringList UIMachineSettingsNetworkPage::brgList (bool aRefresh)
-{
- if (aRefresh)
+ /* Repopulate alternative-name combo: */
+ m_pAdapterNameCombo->clear();
+ switch (attachmentType())
{
- /* Load & filter interface list */
- mBrgList.clear();
- CHostNetworkInterfaceVector interfaces =
- vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces();
- for (CHostNetworkInterfaceVector::ConstIterator it = interfaces.begin();
- it != interfaces.end(); ++ it)
- {
- if (it->GetInterfaceType() == KHostNetworkInterfaceType_Bridged)
- mBrgList << it->GetName();
- }
+ case KNetworkAttachmentType_Bridged:
+ m_pAdapterNameCombo->insertItems(0, m_pParent->bridgedAdapterList());
+ break;
+ case KNetworkAttachmentType_Internal:
+ m_pAdapterNameCombo->insertItems(0, m_pParent->internalNetworkList());
+ break;
+ case KNetworkAttachmentType_HostOnly:
+ m_pAdapterNameCombo->insertItems(0, m_pParent->hostInterfaceList());
+ break;
+ case KNetworkAttachmentType_Generic:
+ m_pAdapterNameCombo->insertItems(0, m_pParent->genericDriverList());
+ break;
+ default:
+ break;
}
- return mBrgList;
-}
-
-QStringList UIMachineSettingsNetworkPage::intList (bool aRefresh)
-{
- if (aRefresh)
+ /* Prepend 'empty' or 'default' item to alternative-name combo: */
+ if (m_pAdapterNameCombo->count() == 0)
{
- /* Load total network list of all VMs */
- mIntList.clear();
- CVirtualBox vbox = vboxGlobal().virtualBox();
- ulong count = qMin ((ULONG) 4, vbox.GetSystemProperties().GetNetworkAdapterCount());
- CMachineVector vec = vbox.GetMachines();
- for (CMachineVector::ConstIterator m = vec.begin(); m != vec.end(); ++ m)
+ switch (attachmentType())
{
- if (m->GetAccessible())
+ case KNetworkAttachmentType_Bridged:
+ case KNetworkAttachmentType_HostOnly:
{
- for (ulong slot = 0; slot < count; ++ slot)
- {
- QString name = m->GetNetworkAdapter (slot).GetInternalNetwork();
- if (!name.isEmpty() && !mIntList.contains (name))
- mIntList << name;
- }
+ /* If adapter list is empty => add 'Not selected' item: */
+ int pos = m_pAdapterNameCombo->findData(pEmptyItemCode);
+ if (pos == -1)
+ m_pAdapterNameCombo->insertItem(0, tr("Not selected", "network adapter name"), pEmptyItemCode);
+ else
+ m_pAdapterNameCombo->setItemText(pos, tr("Not selected", "network adapter name"));
+ break;
}
+ case KNetworkAttachmentType_Internal:
+ {
+ /* Internal network list should have a default item: */
+ if (m_pAdapterNameCombo->findText("intnet") == -1)
+ m_pAdapterNameCombo->insertItem(0, "intnet");
+ break;
+ }
+ default:
+ break;
}
}
- return mIntList;
+ /* Unblock signals finally: */
+ m_pAdapterNameCombo->blockSignals(false);
}
-QStringList UIMachineSettingsNetworkPage::fullIntList (bool aRefresh)
+void UIMachineSettingsNetwork::updateAlternativeName()
{
- QStringList list (intList (aRefresh));
- /* Append network list with names from all the pages */
- for (int index = 0; index < mTwAdapters->count(); ++ index)
+ /* Block signals initially: */
+ m_pAdapterNameCombo->blockSignals(true);
+
+ switch (attachmentType())
{
- UIMachineSettingsNetwork *page =
- qobject_cast <UIMachineSettingsNetwork*> (mTwAdapters->widget (index));
- if (page)
+ case KNetworkAttachmentType_Bridged:
+ case KNetworkAttachmentType_Internal:
+ case KNetworkAttachmentType_HostOnly:
+ case KNetworkAttachmentType_Generic:
{
- QString name = page->alternativeName (KNetworkAttachmentType_Internal);
- if (!name.isEmpty() && !list.contains (name))
- list << name;
+ m_pAdapterNameCombo->setCurrentIndex(position(m_pAdapterNameCombo, alternativeName()));
+ break;
}
+ default:
+ break;
}
- return list;
+
+ /* Unblock signals finally: */
+ m_pAdapterNameCombo->blockSignals(false);
}
-QStringList UIMachineSettingsNetworkPage::hoiList (bool aRefresh)
+/* static */
+int UIMachineSettingsNetwork::position(QComboBox *pComboBox, int iData)
{
- if (aRefresh)
+ int iPosition = pComboBox->findData(iData);
+ return iPosition == -1 ? 0 : iPosition;
+}
+
+/* static */
+int UIMachineSettingsNetwork::position(QComboBox *pComboBox, const QString &strText)
+{
+ int iPosition = pComboBox->findText(strText);
+ return iPosition == -1 ? 0 : iPosition;
+}
+
+/* UIMachineSettingsNetworkPage Stuff: */
+UIMachineSettingsNetworkPage::UIMachineSettingsNetworkPage()
+ : m_pValidator(0)
+ , m_pTwAdapters(0)
+{
+ /* Setup main layout: */
+ QVBoxLayout *pMainLayout = new QVBoxLayout(this);
+ pMainLayout->setContentsMargins(0, 5, 0, 5);
+
+ /* Creating tab-widget: */
+ m_pTwAdapters = new QITabWidget(this);
+ pMainLayout->addWidget(m_pTwAdapters);
+
+ /* How many adapters to display: */
+ ulong uCount = qMin((ULONG)4, vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3));
+ /* Add corresponding tab pages to parent tab widget: */
+ for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
{
- /* Load & filter interface list */
- mHoiList.clear();
- CHostNetworkInterfaceVector interfaces =
- vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces();
- for (CHostNetworkInterfaceVector::ConstIterator it = interfaces.begin();
- it != interfaces.end(); ++ it)
- {
- if (it->GetInterfaceType() == KHostNetworkInterfaceType_HostOnly)
- mHoiList << it->GetName();
- }
+ /* Creating adapter tab: */
+ UIMachineSettingsNetwork *pTab = new UIMachineSettingsNetwork(this);
+ m_pTwAdapters->addTab(pTab, pTab->tabTitle());
}
-
- return mHoiList;
}
/* Load data to cashe from corresponding external object(s),
@@ -743,71 +726,58 @@ void UIMachineSettingsNetworkPage::loadToCacheFrom(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Cache names lists: */
- brgList(true);
- intList(true);
- hoiList(true);
+ /* Clear cache initially: */
+ m_cache.clear();
- /* Load adapters data: */
- ulong uCount = qMin((ULONG)4, vboxGlobal().virtualBox().GetSystemProperties().GetNetworkAdapterCount());
- for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
- {
- /* Get adapter: */
- const CNetworkAdapter &adapter = m_machine.GetNetworkAdapter(uSlot);
-
- /* Prepare adapter's data container: */
- UINetworkAdapterData data;
-
- /* Load main options: */
- data.m_iSlot = uSlot;
- data.m_adapter = adapter;
- data.m_fAdapterEnabled = adapter.GetEnabled();
- data.m_adapterType = adapter.GetAdapterType();
- data.m_attachmentType = adapter.GetAttachmentType();
- switch (data.m_attachmentType)
- {
- case KNetworkAttachmentType_Bridged:
- data.m_strBridgedAdapterName = adapter.GetHostInterface();
- if (data.m_strBridgedAdapterName.isEmpty()) data.m_strBridgedAdapterName = QString();
- break;
- case KNetworkAttachmentType_Internal:
- data.m_strInternalNetworkName = adapter.GetInternalNetwork();
- if (data.m_strInternalNetworkName.isEmpty()) data.m_strInternalNetworkName = QString();
- break;
- case KNetworkAttachmentType_HostOnly:
- data.m_strHostInterfaceName = adapter.GetHostInterface();
- if (data.m_strHostInterfaceName.isEmpty()) data.m_strHostInterfaceName = QString();
- break;
-#ifdef VBOX_WITH_VDE
- case KNetworkAttachmentType_VDE:
- data.m_strVDENetworkName = adapter.GetVDENetwork();
- if (data.m_strVDENetworkName.isEmpty()) data.m_strVDENetworkName = QString();
- break;
-#endif
- default:
- break;
- }
+ /* Cache name lists: */
+ refreshBridgedAdapterList();
+ refreshInternalNetworkList(true);
+ refreshHostInterfaceList();
+ refreshGenericDriverList(true);
- /* Load advanced options: */
- data.m_strMACAddress = adapter.GetMACAddress();
- data.m_fCableConnected = adapter.GetCableConnected();
+ /* For each network adapter: */
+ for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
+ {
+ /* Prepare adapter data: */
+ UIDataSettingsMachineNetworkAdapter adapterData;
- /* Load redirect options: */
- QVector<QString> redirects = adapter.GetNatDriver().GetRedirects();
- for (int i = 0; i < redirects.size(); ++i)
+ /* Check if adapter is valid: */
+ const CNetworkAdapter &adapter = m_machine.GetNetworkAdapter(iSlot);
+ if (!adapter.isNull())
{
- QStringList redirectData = redirects[i].split(',');
- AssertMsg(redirectData.size() == 6, ("Redirect rule should be composed of 6 parts!\n"));
- data.m_redirects << UIPortForwardingData(redirectData[0],
- (KNATProtocol)redirectData[1].toUInt(),
- redirectData[2],
- redirectData[3].toUInt(),
- redirectData[4],
- redirectData[5].toUInt());
+ /* Gather main options: */
+ adapterData.m_iSlot = iSlot;
+ adapterData.m_fAdapterEnabled = adapter.GetEnabled();
+ adapterData.m_attachmentType = adapter.GetAttachmentType();
+ adapterData.m_strBridgedAdapterName = wipedOutString(adapter.GetBridgedInterface());
+ adapterData.m_strInternalNetworkName = wipedOutString(adapter.GetInternalNetwork());
+ adapterData.m_strHostInterfaceName = wipedOutString(adapter.GetHostOnlyInterface());
+ adapterData.m_strGenericDriverName = wipedOutString(adapter.GetGenericDriver());
+
+ /* Gather advanced options: */
+ adapterData.m_adapterType = adapter.GetAdapterType();
+ adapterData.m_promiscuousMode = adapter.GetPromiscModePolicy();
+ adapterData.m_strMACAddress = adapter.GetMACAddress();
+ adapterData.m_strGenericProperties = summarizeGenericProperties(adapter);
+ adapterData.m_fCableConnected = adapter.GetCableConnected();
+
+ /* Gather redirect options: */
+ QVector<QString> redirects = adapter.GetNatDriver().GetRedirects();
+ for (int i = 0; i < redirects.size(); ++i)
+ {
+ QStringList redirectData = redirects[i].split(',');
+ AssertMsg(redirectData.size() == 6, ("Redirect rule should be composed of 6 parts!\n"));
+ adapterData.m_redirects << UIPortForwardingData(redirectData[0],
+ (KNATProtocol)redirectData[1].toUInt(),
+ redirectData[2],
+ redirectData[3].toUInt(),
+ redirectData[4],
+ redirectData[5].toUInt());
+ }
}
- /* Append adapter's data container: */
- m_cache.m_items << data;
+ /* Cache adapter data: */
+ m_cache.child(iSlot).cacheInitialData(adapterData);
}
/* Upload machine to data: */
@@ -819,50 +789,49 @@ void UIMachineSettingsNetworkPage::loadToCacheFrom(QVariant &data)
void UIMachineSettingsNetworkPage::getFromCache()
{
/* Setup tab order: */
- Assert(m_pFirstWidget);
- setTabOrder(m_pFirstWidget, mTwAdapters->focusProxy());
- QWidget *pLastFocusWidget = mTwAdapters->focusProxy();
+ Assert(firstWidget());
+ setTabOrder(firstWidget(), m_pTwAdapters->focusProxy());
+ QWidget *pLastFocusWidget = m_pTwAdapters->focusProxy();
- int uCount = qMin(mTwAdapters->count(), m_cache.m_items.size());
- for (int iSlot = 0; iSlot < uCount; ++iSlot)
+ /* For each network adapter: */
+ for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
{
- UIMachineSettingsNetwork *pPage =
- qobject_cast<UIMachineSettingsNetwork *>(mTwAdapters->widget(iSlot));
- Assert(pPage);
-
- /* Loading adapter's data into page: */
- pPage->fetchAdapterData(m_cache.m_items[iSlot]);
+ /* Get adapter page: */
+ UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iSlot));
- /* Disable tab page of disabled adapter if it is being configured dynamically: */
- if (mDisableStaticControls && !m_cache.m_items[iSlot].m_fAdapterEnabled)
- mTwAdapters->setTabEnabled(iSlot, false);
+ /* Load adapter data to page: */
+ pTab->fetchAdapterCache(m_cache.child(iSlot));
/* Setup page validation: */
- pPage->setValidator(mValidator);
+ pTab->setValidator(m_pValidator);
/* Setup tab order: */
- pLastFocusWidget = pPage->setOrderAfter(pLastFocusWidget);
+ pLastFocusWidget = pTab->setOrderAfter(pLastFocusWidget);
}
/* Applying language settings: */
retranslateUi();
+ /* Polish page finally: */
+ polishPage();
+
/* Revalidate if possible: */
- if (mValidator) mValidator->revalidate();
+ if (m_pValidator)
+ m_pValidator->revalidate();
}
/* Save data from corresponding widgets to cache,
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsNetworkPage::putToCache()
{
- /* Gather internal variables data from QWidget(s): */
- for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+ /* For each network adapter: */
+ for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
{
- /* Getting adapter's page: */
- UIMachineSettingsNetwork *pPage = qobject_cast<UIMachineSettingsNetwork*>(mTwAdapters->widget(iSlot));
+ /* Get adapter page: */
+ UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iSlot));
- /* Loading Adapter's data from page: */
- pPage->uploadAdapterData(m_cache.m_items[iSlot]);
+ /* Gather & cache adapter data: */
+ pTab->uploadAdapterCache(m_cache.child(iSlot));
}
}
@@ -873,114 +842,294 @@ void UIMachineSettingsNetworkPage::saveFromCacheTo(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Gather corresponding values from internal variables: */
- for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+ /* Check if network data was changed: */
+ if (m_cache.wasChanged())
{
- /* Get adapter: */
- CNetworkAdapter adapter = m_machine.GetNetworkAdapter(iSlot);
-
- /* Get cached data for this adapter: */
- const UINetworkAdapterData &data = m_cache.m_items[iSlot];
-
- /* Save main options: */
- adapter.SetEnabled(data.m_fAdapterEnabled);
- adapter.SetAdapterType(data.m_adapterType);
- switch (data.m_attachmentType)
+ /* For each network adapter: */
+ for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
{
- case KNetworkAttachmentType_Null:
- adapter.Detach();
- break;
- case KNetworkAttachmentType_NAT:
- adapter.AttachToNAT();
- break;
- case KNetworkAttachmentType_Bridged:
- adapter.SetHostInterface(data.m_strBridgedAdapterName);
- adapter.AttachToBridgedInterface();
- break;
- case KNetworkAttachmentType_Internal:
- adapter.SetInternalNetwork(data.m_strInternalNetworkName);
- adapter.AttachToInternalNetwork();
- break;
- case KNetworkAttachmentType_HostOnly:
- adapter.SetHostInterface(data.m_strHostInterfaceName);
- adapter.AttachToHostOnlyInterface();
- break;
- #ifdef VBOX_WITH_VDE
- case KNetworkAttachmentType_VDE:
- adapter.SetVDENetwork(data.m_strVDENetworkName);
- adapter.AttachToVDE();
- break;
- #endif
- default:
- break;
+ /* Check if adapter data was changed: */
+ const UICacheSettingsMachineNetworkAdapter &adapterCache = m_cache.child(iSlot);
+ if (adapterCache.wasChanged())
+ {
+ /* Check if adapter still valid: */
+ CNetworkAdapter adapter = m_machine.GetNetworkAdapter(iSlot);
+ if (!adapter.isNull())
+ {
+ /* Get adapter data from cache: */
+ const UIDataSettingsMachineNetworkAdapter &adapterData = adapterCache.data();
+
+ /* Store adapter data: */
+ if (isMachineOffline())
+ {
+ /* Basic attributes: */
+ adapter.SetEnabled(adapterData.m_fAdapterEnabled);
+ adapter.SetAdapterType(adapterData.m_adapterType);
+ adapter.SetMACAddress(adapterData.m_strMACAddress);
+ }
+ if (isMachineInValidMode())
+ {
+ /* Attachment type: */
+ switch (adapterData.m_attachmentType)
+ {
+ case KNetworkAttachmentType_Bridged:
+ adapter.SetBridgedInterface(adapterData.m_strBridgedAdapterName);
+ break;
+ case KNetworkAttachmentType_Internal:
+ adapter.SetInternalNetwork(adapterData.m_strInternalNetworkName);
+ break;
+ case KNetworkAttachmentType_HostOnly:
+ adapter.SetHostOnlyInterface(adapterData.m_strHostInterfaceName);
+ break;
+ case KNetworkAttachmentType_Generic:
+ adapter.SetGenericDriver(adapterData.m_strGenericDriverName);
+ updateGenericProperties(adapter, adapterData.m_strGenericProperties);
+ break;
+ default:
+ break;
+ }
+ adapter.SetAttachmentType(adapterData.m_attachmentType);
+ /* Advanced attributes: */
+ adapter.SetPromiscModePolicy(adapterData.m_promiscuousMode);
+ /* Cable connected flag: */
+ adapter.SetCableConnected(adapterData.m_fCableConnected);
+ /* Redirect options: */
+ QVector<QString> oldRedirects = adapter.GetNatDriver().GetRedirects();
+ for (int i = 0; i < oldRedirects.size(); ++i)
+ adapter.GetNatDriver().RemoveRedirect(oldRedirects[i].section(',', 0, 0));
+ UIPortForwardingDataList newRedirects = adapterData.m_redirects;
+ for (int i = 0; i < newRedirects.size(); ++i)
+ {
+ UIPortForwardingData newRedirect = newRedirects[i];
+ adapter.GetNatDriver().AddRedirect(newRedirect.name, newRedirect.protocol,
+ newRedirect.hostIp, newRedirect.hostPort.value(),
+ newRedirect.guestIp, newRedirect.guestPort.value());
+ }
+ }
+ }
+ }
}
+ }
+
+ /* Upload machine to data: */
+ UISettingsPageMachine::uploadData(data);
+}
+
+void UIMachineSettingsNetworkPage::setValidator(QIWidgetValidator *pValidator)
+{
+ m_pValidator = pValidator;
+}
+
+bool UIMachineSettingsNetworkPage::revalidate(QString &strWarning, QString &strTitle)
+{
+ bool fValid = true;
+
+ for (int i = 0; i < m_pTwAdapters->count(); ++i)
+ {
+ UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(i));
+ Assert(pTab);
+ fValid = pTab->revalidate(strWarning, strTitle);
+ if (!fValid)
+ break;
+ }
+
+ return fValid;
+}
- /* Save advanced options: */
- adapter.SetMACAddress(data.m_strMACAddress);
- adapter.SetCableConnected(data.m_fCableConnected);
+void UIMachineSettingsNetworkPage::retranslateUi()
+{
+ for (int i = 0; i < m_pTwAdapters->count(); ++ i)
+ {
+ UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(i));
+ Assert(pTab);
+ m_pTwAdapters->setTabText(i, pTab->tabTitle());
+ }
+}
+
+void UIMachineSettingsNetworkPage::sltHandleUpdatedTab()
+{
+ /* Determine the sender: */
+ UIMachineSettingsNetwork *pSender = qobject_cast<UIMachineSettingsNetwork*>(sender());
+ AssertMsg(pSender, ("This slot should be called only through signal<->slot mechanism from one of UIMachineSettingsNetwork tabs!\n"));
- /* Save redirect options: */
- QVector<QString> oldRedirects = adapter.GetNatDriver().GetRedirects();
- for (int i = 0; i < oldRedirects.size(); ++i)
- adapter.GetNatDriver().RemoveRedirect(oldRedirects[i].section(',', 0, 0));
- UIPortForwardingDataList newRedirects = data.m_redirects;
- for (int i = 0; i < newRedirects.size(); ++i)
+ /* Determine sender's attachment type: */
+ KNetworkAttachmentType senderAttachmentType = pSender->attachmentType();
+ switch (senderAttachmentType)
+ {
+ case KNetworkAttachmentType_Internal:
{
- UIPortForwardingData newRedirect = newRedirects[i];
- adapter.GetNatDriver().AddRedirect(newRedirect.name, newRedirect.protocol,
- newRedirect.hostIp, newRedirect.hostPort.value(),
- newRedirect.guestIp, newRedirect.guestPort.value());
+ refreshInternalNetworkList();
+ break;
+ }
+ case KNetworkAttachmentType_Generic:
+ {
+ refreshGenericDriverList();
+ break;
}
+ default:
+ break;
}
- /* Upload machine to data: */
- UISettingsPageMachine::uploadData(data);
+ /* Update all the tabs except the sender: */
+ for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
+ {
+ /* Get the iterated tab: */
+ UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iSlot));
+ AssertMsg(pTab, ("All the tabs of m_pTwAdapters should be of the UIMachineSettingsNetwork type!\n"));
+
+ /* Update all the tabs (except sender) with the same attachment type as sender have: */
+ if (pTab != pSender && pTab->attachmentType() == senderAttachmentType)
+ pTab->reloadAlternative();
+ }
}
-void UIMachineSettingsNetworkPage::setValidator (QIWidgetValidator *aVal)
+void UIMachineSettingsNetworkPage::polishPage()
{
- mValidator = aVal;
+ /* Get the count of network adapter tabs: */
+ for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
+ {
+ m_pTwAdapters->setTabEnabled(iSlot,
+ isMachineOffline() ||
+ (isMachineInValidMode() && m_cache.child(iSlot).base().m_fAdapterEnabled));
+ UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iSlot));
+ pTab->polishTab();
+ }
}
-bool UIMachineSettingsNetworkPage::revalidate (QString &aWarning, QString &aTitle)
+void UIMachineSettingsNetworkPage::refreshBridgedAdapterList()
{
- bool valid = true;
+ /* Reload bridged interface list: */
+ m_bridgedAdapterList.clear();
+ const CHostNetworkInterfaceVector &ifaces = vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces();
+ for (int i = 0; i < ifaces.size(); ++i)
+ {
+ const CHostNetworkInterface &iface = ifaces[i];
+ if (iface.GetInterfaceType() == KHostNetworkInterfaceType_Bridged && !m_bridgedAdapterList.contains(iface.GetName()))
+ m_bridgedAdapterList << iface.GetName();
+ }
+}
- for (int i = 0; i < mTwAdapters->count(); ++ i)
+void UIMachineSettingsNetworkPage::refreshInternalNetworkList(bool fFullRefresh /* = false */)
+{
+ /* Reload internal network list: */
+ m_internalNetworkList.clear();
+ /* Get internal network names from other VMs: */
+ if (fFullRefresh)
+ m_internalNetworkList << otherInternalNetworkList();
+ /* Append internal network list with names from all the tabs: */
+ for (int iTab = 0; iTab < m_pTwAdapters->count(); ++iTab)
{
- UIMachineSettingsNetwork *page =
- qobject_cast <UIMachineSettingsNetwork*> (mTwAdapters->widget (i));
- Assert (page);
- valid = page->revalidate (aWarning, aTitle);
- if (!valid) break;
+ UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iTab));
+ if (pTab)
+ {
+ QString strName = pTab->alternativeName(KNetworkAttachmentType_Internal);
+ if (!strName.isEmpty() && !m_internalNetworkList.contains(strName))
+ m_internalNetworkList << strName;
+ }
}
+}
- return valid;
+void UIMachineSettingsNetworkPage::refreshHostInterfaceList()
+{
+ /* Reload host-only interface list: */
+ m_hostInterfaceList.clear();
+ const CHostNetworkInterfaceVector &ifaces = vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces();
+ for (int i = 0; i < ifaces.size(); ++i)
+ {
+ const CHostNetworkInterface &iface = ifaces[i];
+ if (iface.GetInterfaceType() == KHostNetworkInterfaceType_HostOnly && !m_hostInterfaceList.contains(iface.GetName()))
+ m_hostInterfaceList << iface.GetName();
+ }
}
-void UIMachineSettingsNetworkPage::retranslateUi()
+void UIMachineSettingsNetworkPage::refreshGenericDriverList(bool fFullRefresh /* = false */)
{
- for (int i = 0; i < mTwAdapters->count(); ++ i)
+ /* Load generic driver list: */
+ m_genericDriverList.clear();
+ /* Get generic driver names from other VMs: */
+ if (fFullRefresh)
+ m_genericDriverList << otherGenericDriverList();
+ /* Append generic driver list with names from all the tabs: */
+ for (int iTab = 0; iTab < m_pTwAdapters->count(); ++iTab)
{
- UIMachineSettingsNetwork *page =
- qobject_cast <UIMachineSettingsNetwork*> (mTwAdapters->widget (i));
- Assert (page);
- mTwAdapters->setTabText (i, page->pageTitle());
+ UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iTab));
+ if (pTab)
+ {
+ QString strName = pTab->alternativeName(KNetworkAttachmentType_Generic);
+ if (!strName.isEmpty() && !m_genericDriverList.contains(strName))
+ m_genericDriverList << strName;
+ }
}
}
-void UIMachineSettingsNetworkPage::updatePages()
+/* static */
+QStringList UIMachineSettingsNetworkPage::otherInternalNetworkList()
{
- for (int i = 0; i < mTwAdapters->count(); ++ i)
+ /* Load total internal network list of all VMs: */
+ CVirtualBox vbox = vboxGlobal().virtualBox();
+ QStringList otherInternalNetworks(QList<QString>::fromVector(vbox.GetInternalNetworks()));
+ return otherInternalNetworks;
+}
+
+/* static */
+QStringList UIMachineSettingsNetworkPage::otherGenericDriverList()
+{
+ /* Load total generic driver list of all VMs: */
+ CVirtualBox vbox = vboxGlobal().virtualBox();
+ QStringList otherGenericDrivers(QList<QString>::fromVector(vbox.GetGenericNetworkDrivers()));
+ return otherGenericDrivers;
+}
+
+/* static */
+QString UIMachineSettingsNetworkPage::summarizeGenericProperties(const CNetworkAdapter &adapter)
+{
+ /* Prepare formatted string: */
+ QVector<QString> names;
+ QVector<QString> props;
+ props = adapter.GetProperties(QString(), names);
+ QString strResult;
+ /* Load generic properties: */
+ for (int i = 0; i < names.size(); ++i)
+ {
+ strResult += names[i] + "=" + props[i];
+ if (i < names.size() - 1)
+ strResult += "\n";
+ }
+ /* Return formatted string: */
+ return strResult;
+}
+
+/* static */
+void UIMachineSettingsNetworkPage::updateGenericProperties(CNetworkAdapter &adapter, const QString &strPropText)
+{
+ /* Parse new properties: */
+ QStringList newProps = strPropText.split("\n");
+ QHash<QString, QString> hash;
+
+ /* Save new properties: */
+ for (int i = 0; i < newProps.size(); ++i)
+ {
+ QString strLine = newProps[i];
+ int iSplitPos = strLine.indexOf("=");
+ if (iSplitPos)
+ {
+ QString strKey = strLine.left(iSplitPos);
+ QString strVal = strLine.mid(iSplitPos+1);
+ adapter.SetProperty(strKey, strVal);
+ hash[strKey] = strVal;
+ }
+ }
+
+ /* Removing deleted properties: */
+ QVector<QString> names;
+ QVector<QString> props;
+ props = adapter.GetProperties(QString(), names);
+ for (int i = 0; i < names.size(); ++i)
{
- /* Get the iterated page */
- UIMachineSettingsNetwork *page =
- qobject_cast <UIMachineSettingsNetwork*> (mTwAdapters->widget (i));
- Assert (page);
-
- /* Update the page if the attachment type is 'internal network' */
- if (page->attachmentType() == KNetworkAttachmentType_Internal)
- QTimer::singleShot (0, page, SLOT (updateAttachmentAlternative()));
+ QString strName = names[i];
+ QString strValue = props[i];
+ if (strValue != hash[strName])
+ adapter.SetProperty(strName, hash[strName]);
}
}
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.h b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.h
index ad260857f..ba0d1fea2 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -19,96 +19,153 @@
#ifndef __UIMachineSettingsNetwork_h__
#define __UIMachineSettingsNetwork_h__
-/* VBox Includes */
-#include "COMDefs.h"
+/* Local includes: */
#include "UISettingsPage.h"
#include "UIMachineSettingsNetwork.gen.h"
#include "UIMachineSettingsPortForwardingDlg.h"
-/* VBox Forwards */
+/* Forward declarations: */
class UIMachineSettingsNetworkPage;
class QITabWidget;
/* Machine settings / Network page / Adapter data: */
-struct UINetworkAdapterData
+struct UIDataSettingsMachineNetworkAdapter
{
+ /* Default constructor: */
+ UIDataSettingsMachineNetworkAdapter()
+ : m_iSlot(0)
+ , m_fAdapterEnabled(false)
+ , m_adapterType(KNetworkAdapterType_Null)
+ , m_attachmentType(KNetworkAttachmentType_Null)
+ , m_promiscuousMode(KNetworkAdapterPromiscModePolicy_Deny)
+ , m_strBridgedAdapterName(QString())
+ , m_strInternalNetworkName(QString())
+ , m_strHostInterfaceName(QString())
+ , m_strGenericDriverName(QString())
+ , m_strGenericProperties(QString())
+ , m_strMACAddress(QString())
+ , m_fCableConnected(false)
+ , m_redirects(UIPortForwardingDataList()) {}
+ /* Functions: */
+ bool equal(const UIDataSettingsMachineNetworkAdapter &other) const
+ {
+ return (m_iSlot == other.m_iSlot) &&
+ (m_fAdapterEnabled == other.m_fAdapterEnabled) &&
+ (m_adapterType == other.m_adapterType) &&
+ (m_attachmentType == other.m_attachmentType) &&
+ (m_promiscuousMode == other.m_promiscuousMode) &&
+ (m_strBridgedAdapterName == other.m_strBridgedAdapterName) &&
+ (m_strInternalNetworkName == other.m_strInternalNetworkName) &&
+ (m_strHostInterfaceName == other.m_strHostInterfaceName) &&
+ (m_strGenericDriverName == other.m_strGenericDriverName) &&
+ (m_strGenericProperties == other.m_strGenericProperties) &&
+ (m_strMACAddress == other.m_strMACAddress) &&
+ (m_fCableConnected == other.m_fCableConnected) &&
+ (m_redirects == other.m_redirects);
+ }
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineNetworkAdapter &other) const { return equal(other); }
+ bool operator!=(const UIDataSettingsMachineNetworkAdapter &other) const { return !equal(other); }
+ /* Variables: */
int m_iSlot;
- /* CNetworkAdapter used only for Generate MAC ability! */
- CNetworkAdapter m_adapter;
bool m_fAdapterEnabled;
KNetworkAdapterType m_adapterType;
KNetworkAttachmentType m_attachmentType;
+ KNetworkAdapterPromiscModePolicy m_promiscuousMode;
QString m_strBridgedAdapterName;
QString m_strInternalNetworkName;
QString m_strHostInterfaceName;
-#ifdef VBOX_WITH_VDE
- QString m_strVDENetworkName;
-#endif /* VBOX_WITH_VDE */
+ QString m_strGenericDriverName;
+ QString m_strGenericProperties;
QString m_strMACAddress;
bool m_fCableConnected;
UIPortForwardingDataList m_redirects;
};
+typedef UISettingsCache<UIDataSettingsMachineNetworkAdapter> UICacheSettingsMachineNetworkAdapter;
-/* Machine settings / Network page / Cache: */
-struct UISettingsCacheMachineNetwork
+/* Machine settings / Network page / Network data: */
+struct UIDataSettingsMachineNetwork
{
- QList<UINetworkAdapterData> m_items;
+ /* Default constructor: */
+ UIDataSettingsMachineNetwork() {}
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineNetwork& /* other */) const { return true; }
+ bool operator!=(const UIDataSettingsMachineNetwork& /* other */) const { return false; }
};
+typedef UISettingsCachePool<UIDataSettingsMachineNetwork, UICacheSettingsMachineNetworkAdapter> UICacheSettingsMachineNetwork;
-class UIMachineSettingsNetwork : public QIWithRetranslateUI <QWidget>,
- public Ui::UIMachineSettingsNetwork
+/* Machine settings / Network page / Adapter tab: */
+class UIMachineSettingsNetwork : public QIWithRetranslateUI<QWidget>, public Ui::UIMachineSettingsNetwork
{
Q_OBJECT;
public:
- UIMachineSettingsNetwork (UIMachineSettingsNetworkPage *aParent, bool aDisableStaticControls = false);
+ /* Constructor: */
+ UIMachineSettingsNetwork(UIMachineSettingsNetworkPage *pParent);
- void fetchAdapterData(const UINetworkAdapterData &data);
- void uploadAdapterData(UINetworkAdapterData &data);
+ /* Load / Save API: */
+ void fetchAdapterCache(const UICacheSettingsMachineNetworkAdapter &adapterCache);
+ void uploadAdapterCache(UICacheSettingsMachineNetworkAdapter &adapterCache);
- void setValidator (QIWidgetValidator *aValidator);
- bool revalidate (QString &aWarning, QString &aTitle);
+ /* Validation stuff: */
+ void setValidator(QIWidgetValidator *pValidator);
+ bool revalidate(QString &strWarning, QString &strTitle);
- QWidget* setOrderAfter (QWidget *aAfter);
+ /* Navigation stuff: */
+ QWidget* setOrderAfter(QWidget *pAfter);
- QString pageTitle() const;
+ /* Other public stuff: */
+ QString tabTitle() const;
KNetworkAttachmentType attachmentType() const;
- QString alternativeName (int aType = -1) const;
+ QString alternativeName(int iType = -1) const;
+ void polishTab();
+ void reloadAlternative();
-protected:
+signals:
+
+ /* Signal to notify listeners about tab content changed: */
+ void sigTabUpdated();
- void showEvent (QShowEvent *aEvent);
+protected:
+ /* Translation stuff: */
void retranslateUi();
private slots:
- void updateAttachmentAlternative();
- void updateAlternativeName();
- void toggleAdvanced();
- void generateMac();
+ /* Different handlers: */
+ void sltHandleAdapterActivityChange();
+ void sltHandleAttachmentTypeChange();
+ void sltHandleAlternativeNameChange();
+ void sltHandleAdvancedButtonStateChange();
+ void sltGenerateMac();
void sltOpenPortForwardingDlg();
private:
+ /* Helping stuff: */
void populateComboboxes();
+ void updateAlternativeList();
+ void updateAlternativeName();
+
+ /* Various static stuff: */
+ static int position(QComboBox *pComboBox, int iData);
+ static int position(QComboBox *pComboBox, const QString &strText);
+
+ /* Parent page: */
+ UIMachineSettingsNetworkPage *m_pParent;
+
+ /* Validator: */
+ QIWidgetValidator *m_pValidator;
- UIMachineSettingsNetworkPage *mParent;
- QIWidgetValidator *mValidator;
+ /* Other variables: */
int m_iSlot;
- CNetworkAdapter m_adapter;
-
- QString mBrgName;
- QString mIntName;
- QString mHoiName;
-#ifdef VBOX_WITH_VDE
- QString mVDEName;
-#endif
-
- bool mPolished;
- bool mDisableStaticControls;
- UIPortForwardingDataList mPortForwardingRules;
+ QString m_strBridgedAdapterName;
+ QString m_strInternalNetworkName;
+ QString m_strHostInterfaceName;
+ QString m_strGenericDriverName;
+ UIPortForwardingDataList m_portForwardingRules;
};
/* Machine settings / Network page: */
@@ -118,15 +175,17 @@ class UIMachineSettingsNetworkPage : public UISettingsPageMachine
public:
- UIMachineSettingsNetworkPage (bool aDisableStaticControls = false);
-
- void loadDirectlyFrom(const CMachine &machine);
- void saveDirectlyTo(CMachine &machine);
+ /* Constructor: */
+ UIMachineSettingsNetworkPage();
- QStringList brgList (bool aRefresh = false);
- QStringList intList (bool aRefresh = false);
- QStringList fullIntList (bool aRefresh = false);
- QStringList hoiList (bool aRefresh = false);
+ /* Bridged adapter list: */
+ const QStringList& bridgedAdapterList() const { return m_bridgedAdapterList; }
+ /* Internal network list: */
+ const QStringList& internalNetworkList() const { return m_internalNetworkList; }
+ /* Host-only interface list: */
+ const QStringList& hostInterfaceList() const { return m_hostInterfaceList; }
+ /* Generic driver list: */
+ const QStringList& genericDriverList() const { return m_genericDriverList; }
protected:
@@ -144,28 +203,50 @@ protected:
* this task COULD be performed in other than GUI thread: */
void saveFromCacheTo(QVariant &data);
- void setValidator (QIWidgetValidator *aValidator);
- bool revalidate (QString &aWarning, QString &aTitle);
+ /* Page changed: */
+ bool changed() const { return m_cache.wasChanged(); }
+ /* Validation stuff: */
+ void setValidator(QIWidgetValidator *pValidator);
+ bool revalidate(QString &strWarning, QString &strTitle);
+
+ /* Translation stuff: */
void retranslateUi();
private slots:
- void updatePages();
+ /* Handles tab updates: */
+ void sltHandleUpdatedTab();
private:
- QIWidgetValidator *mValidator;
- QITabWidget *mTwAdapters;
+ /* Private helpers: */
+ void polishPage();
+ void refreshBridgedAdapterList();
+ void refreshInternalNetworkList(bool fFullRefresh = false);
+ void refreshHostInterfaceList();
+ void refreshGenericDriverList(bool fFullRefresh = false);
+
+ /* Various static stuff: */
+ static QStringList otherInternalNetworkList();
+ static QStringList otherGenericDriverList();
+ static QString summarizeGenericProperties(const CNetworkAdapter &adapter);
+ static void updateGenericProperties(CNetworkAdapter &adapter, const QString &strPropText);
+
+ /* Validator: */
+ QIWidgetValidator *m_pValidator;
- QStringList mBrgList;
- QStringList mIntList;
- QStringList mHoiList;
+ /* Tab holder: */
+ QITabWidget *m_pTwAdapters;
- bool mDisableStaticControls;
+ /* Alternative-name lists: */
+ QStringList m_bridgedAdapterList;
+ QStringList m_internalNetworkList;
+ QStringList m_hostInterfaceList;
+ QStringList m_genericDriverList;
/* Cache: */
- UISettingsCacheMachineNetwork m_cache;
+ UICacheSettingsMachineNetwork m_cache;
};
#endif // __UIMachineSettingsNetwork_h__
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.ui b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.ui
index 1eb11ffaf..aa77bdb85 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.ui
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.ui
@@ -1,8 +1,8 @@
-<ui version="4.0" >
+<ui version="4.0">
<comment>
VBox frontends: Qt4 GUI ("VirtualBox"):
- Copyright (C) 2008 Oracle Corporation
+ Copyright (C) 2008-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;
@@ -13,31 +13,28 @@
hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
</comment>
<class>UIMachineSettingsNetwork</class>
- <widget class="QWidget" name="UIMachineSettingsNetwork" >
- <property name="geometry" >
+ <widget class="QWidget" name="UIMachineSettingsNetwork">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>431</width>
- <height>248</height>
+ <width>430</width>
+ <height>250</height>
</rect>
</property>
- <layout class="QGridLayout" name="VBoxVMSettingsNetworkGridLayout">
+ <layout class="QGridLayout" name="m_pMainLayout">
<item row="0" column="0" colspan="2">
- <widget class="QCheckBox" name="mCbEnableAdapter" >
- <property name="whatsThis" >
+ <widget class="QCheckBox" name="m_pEnableAdapterCheckBox">
+ <property name="whatsThis">
<string>When checked, plugs this virtual network adapter into the virtual machine.</string>
</property>
- <property name="text" >
+ <property name="text">
<string>&amp;Enable Network Adapter</string>
</property>
- <property name="checked" >
- <bool>true</bool>
- </property>
</widget>
</item>
<item row="1" column="0">
- <spacer name="horizontalSpacer1">
+ <spacer name="m_pHorizontalSpacer1">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -52,71 +49,68 @@
</property>
</spacer>
</item>
- <item row="1" column="1" >
- <widget class="QWidget" name="mNetworkChild" native="1">
- <layout class="QGridLayout" name="mNetworkChildGridLayout">
+ <item row="1" column="1">
+ <widget class="QWidget" name="m_pAdapterOptionsContainer" native="1">
+ <layout class="QGridLayout" name="m_pAdapterOptionsLayout">
<property name="margin">
<number>0</number>
</property>
- <item row="0" column="0" >
- <widget class="QLabel" name="mLbAttachmentType">
- <property name="text" >
+ <item row="0" column="0">
+ <widget class="QLabel" name="m_pAttachmentTypeLabel">
+ <property name="text">
<string>&amp;Attached to:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
- <property name="buddy" >
- <cstring>mCbAttachmentType</cstring>
+ <property name="buddy">
+ <cstring>m_pAttachmentTypeComboBox</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
- <widget class="QComboBox" name="mCbAttachmentType">
+ <widget class="QComboBox" name="m_pAttachmentTypeComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="whatsThis" >
+ <property name="whatsThis">
<string>Controls how this virtual adapter is attached to the real network of the Host OS.</string>
</property>
</widget>
</item>
- <item row="1" column="0" >
- <widget class="QLabel" name="mLbAdapterName">
- <property name="text" >
+ <item row="1" column="0">
+ <widget class="QLabel" name="m_pAdapterNameLabel">
+ <property name="text">
<string>&amp;Name:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
- <property name="buddy" >
- <cstring>mCbAdapterName</cstring>
+ <property name="buddy">
+ <cstring>m_pAdapterNameCombo</cstring>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
- <widget class="QComboBox" name="mCbAdapterName">
+ <widget class="QComboBox" name="m_pAdapterNameCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="whatsThis" >
- <string>Selects the name of the network adapter for &lt;b&gt;Bridged Adapter&lt;/b&gt; or &lt;b&gt;Host-only Adapter&lt;/b&gt; attachments and the name of the network &lt;b&gt;Internal Network&lt;/b&gt; attachments.</string>
- </property>
</widget>
</item>
<item row="2" column="0">
- <layout class="QHBoxLayout" name="mLtAdvancedBtn">
+ <layout class="QHBoxLayout" name="m_pAdvancedButtonLayout">
<property name="margin">
<number>0</number>
</property>
<item>
- <spacer name="horizontalSpacer2">
+ <spacer name="m_pHorizontalSpacer2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -129,11 +123,11 @@
</spacer>
</item>
<item>
- <widget class="QIArrowButtonSwitch" native="1" name="mAbsAdvanced">
+ <widget class="QIArrowButtonSwitch" native="1" name="m_pAdvancedArrow">
<property name="text">
<string>A&amp;dvanced</string>
</property>
- <property name="whatsThis" >
+ <property name="whatsThis">
<string>Shows or hides additional network adapter options.</string>
</property>
</widget>
@@ -141,7 +135,7 @@
</layout>
</item>
<item row="3" column="0">
- <widget class="QLabel" name="mLbAdapterType">
+ <widget class="QLabel" name="m_pAdapterTypeLabel">
<property name="text">
<string>Adapter &amp;Type:</string>
</property>
@@ -149,12 +143,12 @@
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
- <cstring>mCbAdapterType</cstring>
+ <cstring>m_pAdapterTypeCombo</cstring>
</property>
</widget>
</item>
<item row="3" column="1" colspan="3">
- <widget class="QComboBox" name="mCbAdapterType">
+ <widget class="QComboBox" name="m_pAdapterTypeCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>1</horstretch>
@@ -167,20 +161,46 @@
</widget>
</item>
<item row="4" column="0">
- <widget class="QLabel" name="mLbMAC">
+ <widget class="QLabel" name="m_pPromiscuousModeLabel">
+ <property name="text">
+ <string>&amp;Promiscuous Mode:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>m_pPromiscuousModeCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" colspan="3">
+ <widget class="QComboBox" name="m_pPromiscuousModeCombo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis">
+ <string>Selects the promiscuous mode policy of the network adapter when attached to an internal network, host only network or a bridge.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="m_pMACLabel">
<property name="text">
<string>&amp;Mac Address:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
- <cstring>mLeMAC</cstring>
+ <cstring>m_pMACEditor</cstring>
</property>
</widget>
</item>
- <item row="4" column="1" colspan="2">
- <widget class="QILineEdit" name="mLeMAC">
+ <item row="5" column="1" colspan="2">
+ <widget class="QILineEdit" name="m_pMACEditor">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>1</horstretch>
@@ -192,8 +212,8 @@
</property>
</widget>
</item>
- <item row="4" column="3">
- <widget class="QIToolButton" name="mTbMAC">
+ <item row="5" column="3">
+ <widget class="QIToolButton" name="m_pMACButton">
<property name="whatsThis">
<string>Generates a new random MAC address.</string>
</property>
@@ -206,8 +226,25 @@
</property>
</widget>
</item>
- <item row="5" column="1" colspan="3">
- <widget class="QCheckBox" name="mCbCableConnected">
+ <item row="6" column="0">
+ <widget class="QLabel" name="m_pGenericPropertiesLabel">
+ <property name="text">
+ <string>Generic Properties:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignTop</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1" colspan="3">
+ <widget class="QTextEdit" name="m_pGenericPropertiesTextEdit">
+ <property name="whatsThis">
+ <string>Enter any configuration settings here for the network attachment driver you will be using. The settings should be of the form &lt;b&gt;name=value&lt;/b&gt; and will depend on the driver. Use &lt;b&gt;shift-enter&lt;/b&gt; to add a new entry.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1" colspan="3">
+ <widget class="QCheckBox" name="m_pCableConnectedCheckBox">
<property name="whatsThis">
<string>Indicates whether the virtual network cable is plugged in on machine startup or not.</string>
</property>
@@ -216,8 +253,8 @@
</property>
</widget>
</item>
- <item row="6" column="1">
- <widget class="QPushButton" name="mPbPortForwarding">
+ <item row="8" column="1">
+ <widget class="QPushButton" name="m_pPortForwardingButton">
<property name="whatsThis">
<string>Opens dialog to manage port forwarding rules.</string>
</property>
@@ -226,8 +263,8 @@
</property>
</widget>
</item>
- <item row="7" column="0" colspan="4">
- <spacer name="verticalSpacer">
+ <item row="9" column="0" colspan="4">
+ <spacer name="m_pVerticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
@@ -265,22 +302,5 @@
<resources>
<include location="../VirtualBox1.qrc"/>
</resources>
- <connections>
- <connection>
- <sender>mCbEnableAdapter</sender>
- <signal>toggled(bool)</signal>
- <receiver>mNetworkChild</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>184</x>
- <y>28</y>
- </hint>
- <hint type="destinationlabel">
- <x>196</x>
- <y>111</y>
- </hint>
- </hints>
- </connection>
- </connections>
+ <connections/>
</ui>
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsParallel.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsParallel.cpp
index 4a6985e96..eaf00bbfb 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsParallel.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsParallel.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsParallel.cpp $ */
+/* $Id: UIMachineSettingsParallel.cpp 37126 2011-05-17 13:56:50Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,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;
@@ -25,8 +25,9 @@
#include <QDir>
/* UIMachineSettingsParallel stuff */
-UIMachineSettingsParallel::UIMachineSettingsParallel()
+UIMachineSettingsParallel::UIMachineSettingsParallel(UIMachineSettingsParallelPage *pParent)
: QIWithRetranslateUI<QWidget> (0)
+ , m_pParent(pParent)
, mValidator(0)
, m_iSlot(-1)
{
@@ -57,29 +58,54 @@ UIMachineSettingsParallel::UIMachineSettingsParallel()
retranslateUi();
}
-void UIMachineSettingsParallel::fetchPortData(const UIParallelPortData &data)
+void UIMachineSettingsParallel::polishTab()
{
- /* Load port slot number: */
- m_iSlot = data.m_iSlot;
+ /* Polish port page: */
+ ulong uIRQ, uIOBase;
+ bool fStd = vboxGlobal().toCOMPortNumbers(mCbNumber->currentText(), uIRQ, uIOBase);
+ mGbParallel->setEnabled(m_pParent->isMachineOffline());
+ mLbNumber->setEnabled(m_pParent->isMachineOffline());
+ mCbNumber->setEnabled(m_pParent->isMachineOffline());
+ mLbIRQ->setEnabled(m_pParent->isMachineOffline());
+ mLeIRQ->setEnabled(!fStd && m_pParent->isMachineOffline());
+ mLbIOPort->setEnabled(m_pParent->isMachineOffline());
+ mLeIOPort->setEnabled(!fStd && m_pParent->isMachineOffline());
+ mLbPath->setEnabled(m_pParent->isMachineOffline());
+ mLePath->setEnabled(m_pParent->isMachineOffline());
+}
+
+void UIMachineSettingsParallel::fetchPortData(const UICacheSettingsMachineParallelPort &portCache)
+{
+ /* Get port data: */
+ const UIDataSettingsMachineParallelPort &portData = portCache.base();
- /* Fetch port data: */
- mGbParallel->setChecked(data.m_fPortEnabled);
- mCbNumber->setCurrentIndex(mCbNumber->findText(vboxGlobal().toCOMPortName(data.m_uIRQ, data.m_uIOBase)));
- mLeIRQ->setText(QString::number(data.m_uIRQ));
- mLeIOPort->setText("0x" + QString::number(data.m_uIOBase, 16).toUpper());
- mLePath->setText(data.m_strPath);
+ /* Load port number: */
+ m_iSlot = portData.m_iSlot;
+
+ /* Load port data: */
+ mGbParallel->setChecked(portData.m_fPortEnabled);
+ mCbNumber->setCurrentIndex(mCbNumber->findText(vboxGlobal().toCOMPortName(portData.m_uIRQ, portData.m_uIOBase)));
+ mLeIRQ->setText(QString::number(portData.m_uIRQ));
+ mLeIOPort->setText("0x" + QString::number(portData.m_uIOBase, 16).toUpper());
+ mLePath->setText(portData.m_strPath);
/* Ensure everything is up-to-date */
mGbParallelToggled(mGbParallel->isChecked());
}
-void UIMachineSettingsParallel::uploadPortData(UIParallelPortData &data)
+void UIMachineSettingsParallel::uploadPortData(UICacheSettingsMachineParallelPort &portCache)
{
- /* Upload port data: */
- data.m_fPortEnabled = mGbParallel->isChecked();
- data.m_uIRQ = mLeIRQ->text().toULong(NULL, 0);
- data.m_uIOBase = mLeIOPort->text().toULong(NULL, 0);
- data.m_strPath = QDir::toNativeSeparators(mLePath->text());
+ /* Prepare port data: */
+ UIDataSettingsMachineParallelPort portData = portCache.base();
+
+ /* Save port data: */
+ portData.m_fPortEnabled = mGbParallel->isChecked();
+ portData.m_uIRQ = mLeIRQ->text().toULong(NULL, 0);
+ portData.m_uIOBase = mLeIOPort->text().toULong(NULL, 0);
+ portData.m_strPath = QDir::toNativeSeparators(mLePath->text());
+
+ /* Cache port data: */
+ portCache.cacheCurrentData(portData);
}
void UIMachineSettingsParallel::setValidator (QIWidgetValidator *aVal)
@@ -157,6 +183,16 @@ UIMachineSettingsParallelPage::UIMachineSettingsParallelPage()
QVBoxLayout *layout = new QVBoxLayout (this);
layout->setContentsMargins (0, 5, 0, 5);
layout->addWidget (mTabWidget);
+
+ /* How many ports to display: */
+ ulong uCount = vboxGlobal().virtualBox().GetSystemProperties().GetParallelPortCount();
+ /* Add corresponding tab pages to parent tab widget: */
+ for (ulong uPort = 0; uPort < uCount; ++uPort)
+ {
+ /* Creating port page: */
+ UIMachineSettingsParallel *pPage = new UIMachineSettingsParallel(this);
+ mTabWidget->addTab(pPage, pPage->pageTitle());
+ }
}
/* Load data to cashe from corresponding external object(s),
@@ -166,25 +202,29 @@ void UIMachineSettingsParallelPage::loadToCacheFrom(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Load port data: */
- ulong uCount = vboxGlobal().virtualBox().GetSystemProperties().GetParallelPortCount();
- for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
- {
- /* Get port: */
- const CParallelPort &port = m_machine.GetParallelPort(uSlot);
+ /* Clear cache initially: */
+ m_cache.clear();
- /* Prepare port's data container: */
- UIParallelPortData data;
+ /* For each parallel port: */
+ for (int iSlot = 0; iSlot < mTabWidget->count(); ++iSlot)
+ {
+ /* Prepare port data: */
+ UIDataSettingsMachineParallelPort portData;
- /* Load options: */
- data.m_iSlot = uSlot;
- data.m_fPortEnabled = port.GetEnabled();
- data.m_uIRQ = port.GetIRQ();
- data.m_uIOBase = port.GetIOBase();
- data.m_strPath = port.GetPath();
+ /* Check if port is valid: */
+ const CParallelPort &port = m_machine.GetParallelPort(iSlot);
+ if (!port.isNull())
+ {
+ /* Gather options: */
+ portData.m_iSlot = iSlot;
+ portData.m_fPortEnabled = port.GetEnabled();
+ portData.m_uIRQ = port.GetIRQ();
+ portData.m_uIOBase = port.GetIOBase();
+ portData.m_strPath = port.GetPath();
+ }
- /* Append adapter's data container: */
- m_cache.m_items << data;
+ /* Cache port data: */
+ m_cache.child(iSlot).cacheInitialData(portData);
}
/* Upload machine to data: */
@@ -195,21 +235,19 @@ void UIMachineSettingsParallelPage::loadToCacheFrom(QVariant &data)
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsParallelPage::getFromCache()
{
- Assert(m_pFirstWidget);
- setTabOrder(m_pFirstWidget, mTabWidget->focusProxy());
+ /* Setup tab order: */
+ Assert(firstWidget());
+ setTabOrder(firstWidget(), mTabWidget->focusProxy());
QWidget *pLastFocusWidget = mTabWidget->focusProxy();
- /* Apply internal variables data to QWidget(s): */
- for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+ /* For each parallel port: */
+ for (int iPort = 0; iPort < mTabWidget->count(); ++iPort)
{
- /* Creating port's page: */
- UIMachineSettingsParallel *pPage = new UIMachineSettingsParallel;
-
- /* Loading port's data into page: */
- pPage->fetchPortData(m_cache.m_items[iSlot]);
+ /* Get port page: */
+ UIMachineSettingsParallel *pPage = qobject_cast<UIMachineSettingsParallel*>(mTabWidget->widget(iPort));
- /* Attach port's page to Tab Widget: */
- mTabWidget->addTab(pPage, pPage->pageTitle());
+ /* Load port data to page: */
+ pPage->fetchPortData(m_cache.child(iPort));
/* Setup page validation: */
pPage->setValidator(mValidator);
@@ -221,22 +259,26 @@ void UIMachineSettingsParallelPage::getFromCache()
/* Applying language settings: */
retranslateUi();
+ /* Polish page finally: */
+ polishPage();
+
/* Revalidate if possible: */
- if (mValidator) mValidator->revalidate();
+ if (mValidator)
+ mValidator->revalidate();
}
/* Save data from corresponding widgets to cache,
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsParallelPage::putToCache()
{
- /* Gather internal variables data from QWidget(s): */
- for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+ /* For each parallel port: */
+ for (int iPort = 0; iPort < mTabWidget->count(); ++iPort)
{
- /* Getting adapter's page: */
- UIMachineSettingsParallel *pPage = qobject_cast<UIMachineSettingsParallel*>(mTabWidget->widget(iSlot));
+ /* Getting port page: */
+ UIMachineSettingsParallel *pPage = qobject_cast<UIMachineSettingsParallel*>(mTabWidget->widget(iPort));
- /* Loading Adapter's data from page: */
- pPage->uploadPortData(m_cache.m_items[iSlot]);
+ /* Gather & cache port data: */
+ pPage->uploadPortData(m_cache.child(iPort));
}
}
@@ -247,20 +289,34 @@ void UIMachineSettingsParallelPage::saveFromCacheTo(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Gather corresponding values from internal variables: */
- for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+ /* Check if ports data was changed: */
+ if (m_cache.wasChanged())
{
- /* Get adapter: */
- CParallelPort port = m_machine.GetParallelPort(iSlot);
-
- /* Get cached data for this slot: */
- const UIParallelPortData &data = m_cache.m_items[iSlot];
-
- /* Save options: */
- port.SetIRQ(data.m_uIRQ);
- port.SetIOBase(data.m_uIOBase);
- port.SetPath(data.m_strPath);
- port.SetEnabled(data.m_fPortEnabled);
+ /* For each parallel port: */
+ for (int iPort = 0; iPort < mTabWidget->count(); ++iPort)
+ {
+ /* Check if port data was changed: */
+ const UICacheSettingsMachineParallelPort &portCache = m_cache.child(iPort);
+ if (portCache.wasChanged())
+ {
+ /* Check if port still valid: */
+ CParallelPort port = m_machine.GetParallelPort(iPort);
+ if (!port.isNull())
+ {
+ /* Get port data from cache: */
+ const UIDataSettingsMachineParallelPort &portData = portCache.data();
+
+ /* Store adapter data: */
+ if (isMachineOffline())
+ {
+ port.SetIRQ(portData.m_uIRQ);
+ port.SetIOBase(portData.m_uIOBase);
+ port.SetPath(portData.m_strPath);
+ port.SetEnabled(portData.m_fPortEnabled);
+ }
+ }
+ }
+ }
}
/* Upload machine to data: */
@@ -331,3 +387,16 @@ void UIMachineSettingsParallelPage::retranslateUi()
}
}
+void UIMachineSettingsParallelPage::polishPage()
+{
+ /* Get the count of parallel port tabs: */
+ for (int iPort = 0; iPort < mTabWidget->count(); ++iPort)
+ {
+ mTabWidget->setTabEnabled(iPort,
+ isMachineOffline() ||
+ (isMachineInValidMode() && m_cache.child(iPort).base().m_fPortEnabled));
+ UIMachineSettingsParallel *pTab = qobject_cast<UIMachineSettingsParallel*>(mTabWidget->widget(iPort));
+ pTab->polishTab();
+ }
+}
+
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsParallel.h b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsParallel.h
index f68e06c8d..cd92e05f2 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsParallel.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsParallel.h
@@ -5,7 +5,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;
@@ -23,22 +23,51 @@
#include "UIMachineSettingsParallel.gen.h"
#include "COMDefs.h"
+/* Forward declarations */
+class UIMachineSettingsParallelPage;
class QITabWidget;
-struct UIParallelPortData
+/* Machine settings / Parallel page / Port data: */
+struct UIDataSettingsMachineParallelPort
{
+ /* Default constructor: */
+ UIDataSettingsMachineParallelPort()
+ : m_iSlot(-1)
+ , m_fPortEnabled(false)
+ , m_uIRQ(0)
+ , m_uIOBase(0)
+ , m_strPath(QString()) {}
+ /* Functions: */
+ bool equal(const UIDataSettingsMachineParallelPort &other) const
+ {
+ return (m_iSlot == other.m_iSlot) &&
+ (m_fPortEnabled == other.m_fPortEnabled) &&
+ (m_uIRQ == other.m_uIRQ) &&
+ (m_uIOBase == other.m_uIOBase) &&
+ (m_strPath == other.m_strPath);
+ }
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineParallelPort &other) const { return equal(other); }
+ bool operator!=(const UIDataSettingsMachineParallelPort &other) const { return !equal(other); }
+ /* Variables: */
int m_iSlot;
bool m_fPortEnabled;
ulong m_uIRQ;
ulong m_uIOBase;
QString m_strPath;
};
+typedef UISettingsCache<UIDataSettingsMachineParallelPort> UICacheSettingsMachineParallelPort;
-/* Machine settings / Parallel page / Cache: */
-struct UISettingsCacheMachineParallel
+/* Machine settings / Parallel page / Ports data: */
+struct UIDataSettingsMachineParallel
{
- QList<UIParallelPortData> m_items;
+ /* Default constructor: */
+ UIDataSettingsMachineParallel() {}
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineParallel& /* other */) const { return true; }
+ bool operator!=(const UIDataSettingsMachineParallel& /* other */) const { return false; }
};
+typedef UISettingsCachePool<UIDataSettingsMachineParallel, UICacheSettingsMachineParallelPort> UICacheSettingsMachineParallel;
class UIMachineSettingsParallel : public QIWithRetranslateUI<QWidget>,
public Ui::UIMachineSettingsParallel
@@ -47,10 +76,12 @@ class UIMachineSettingsParallel : public QIWithRetranslateUI<QWidget>,
public:
- UIMachineSettingsParallel();
+ UIMachineSettingsParallel(UIMachineSettingsParallelPage *pParent);
- void fetchPortData(const UIParallelPortData &data);
- void uploadPortData(UIParallelPortData &data);
+ void polishTab();
+
+ void fetchPortData(const UICacheSettingsMachineParallelPort &portCache);
+ void uploadPortData(UICacheSettingsMachineParallelPort &portCache);
void setValidator (QIWidgetValidator *aVal);
@@ -70,6 +101,7 @@ private slots:
private:
+ UIMachineSettingsParallelPage *m_pParent;
QIWidgetValidator *mValidator;
int m_iSlot;
};
@@ -99,6 +131,9 @@ protected:
* this task COULD be performed in other than GUI thread: */
void saveFromCacheTo(QVariant &data);
+ /* Page changed: */
+ bool changed() const { return m_cache.wasChanged(); }
+
void setValidator (QIWidgetValidator *aVal);
bool revalidate (QString &aWarning, QString &aTitle);
@@ -106,11 +141,13 @@ protected:
private:
+ void polishPage();
+
QIWidgetValidator *mValidator;
QITabWidget *mTabWidget;
- /* Internals: */
- UISettingsCacheMachineParallel m_cache;
+ /* Cache: */
+ UICacheSettingsMachineParallel m_cache;
};
#endif // __UIMachineSettingsParallel_h__
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsPortForwardingDlg.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsPortForwardingDlg.cpp
index f810023eb..ee2d874fa 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsPortForwardingDlg.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsPortForwardingDlg.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsPortForwardingDlg.cpp $ */
+/* $Id: UIMachineSettingsPortForwardingDlg.cpp 33882 2010-11-09 09:32:27Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsPortForwardingDlg.h b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsPortForwardingDlg.h
index bc9c1851a..e5c6b1e92 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsPortForwardingDlg.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsPortForwardingDlg.h
@@ -58,6 +58,7 @@ public:
PortData() : m_uValue(0) {}
PortData(ushort uValue) : m_uValue(uValue) {}
PortData(const PortData &other) : m_uValue(other.value()) {}
+ bool operator==(const PortData &other) { return m_uValue == other.m_uValue; }
ushort value() const { return m_uValue; }
private:
@@ -75,6 +76,15 @@ struct UIPortForwardingData
: name(strName), protocol(eProtocol)
, hostIp(strHostIp), hostPort(uHostPort)
, guestIp(strGuestIp), guestPort(uGuestPort) {}
+ bool operator==(const UIPortForwardingData &other)
+ {
+ return name == other.name &&
+ protocol == other.protocol &&
+ hostIp == other.hostIp &&
+ hostPort == other.hostPort &&
+ guestIp == other.guestIp &&
+ guestPort == other.guestPort;
+ }
NameData name;
KNATProtocol protocol;
IpData hostIp;
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp
index 7a1052557..5fd2b12b8 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsSF.cpp $ */
+/* $Id: UIMachineSettingsSF.cpp 37126 2011-05-17 13:56:50Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -165,9 +165,7 @@ private:
};
UIMachineSettingsSF::UIMachineSettingsSF()
- : m_type(WrongType)
- , mNewAction(0), mEdtAction(0), mDelAction(0)
- , mIsListViewChanged(false)
+ : mNewAction(0), mEdtAction(0), mDelAction(0)
{
/* Apply UI decorations */
Ui::UIMachineSettingsSF::setupUi (this);
@@ -211,21 +209,6 @@ UIMachineSettingsSF::UIMachineSettingsSF()
retranslateUi();
}
-void UIMachineSettingsSF::loadDirectlyFrom(const CConsole &console)
-{
- loadToCacheFromMachine(console.GetMachine());
- loadToCacheFromConsole(console);
- getFromCache();
-}
-
-void UIMachineSettingsSF::saveDirectlyTo(CConsole &console)
-{
- putToCache();
- saveFromCacheToConsole(console);
- CMachine machine = console.GetMachine();
- saveFromCacheToMachine(machine);
-}
-
void UIMachineSettingsSF::resizeEvent (QResizeEvent *aEvent)
{
NOREF(aEvent);
@@ -239,44 +222,48 @@ void UIMachineSettingsSF::loadToCacheFrom(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Fill internal variables with corresponding values: */
- loadToCacheFromMachine(m_machine);
+ /* Clear cache initially: */
+ m_cache.clear();
+
+ /* Load machine (permanent) shared folders into shared folders cache if possible: */
+ if (isSharedFolderTypeSupported(MachineType))
+ loadToCacheFrom(MachineType);
+ /* Load console (temporary) shared folders into shared folders cache if possible: */
+ if (isSharedFolderTypeSupported(ConsoleType))
+ loadToCacheFrom(ConsoleType);
/* Upload machine to data: */
UISettingsPageMachine::uploadData(data);
}
-void UIMachineSettingsSF::loadToCacheFromMachine(const CMachine &machine)
+void UIMachineSettingsSF::loadToCacheFrom(UISharedFolderType sharedFoldersType)
{
- /* Update dialog type: */
- if (m_type == WrongType)
- m_type = MachineType;
- /* Load machine items into internal cache: */
- loadToCacheFromVector(machine.GetSharedFolders(), MachineType);
-}
+ /* Get current shared folders: */
+ CSharedFolderVector sharedFolders = getSharedFolders(sharedFoldersType);
-void UIMachineSettingsSF::loadToCacheFromConsole(const CConsole &console)
-{
- /* Update dialog type: */
- if (m_type == WrongType || m_type == MachineType)
- m_type = ConsoleType;
- /* Load console items into internal cache: */
- loadToCacheFromVector(console.GetSharedFolders(), ConsoleType);
-}
-
-void UIMachineSettingsSF::loadToCacheFromVector(const CSharedFolderVector &vector, UISharedFolderType type)
-{
- /* Cache shared folders in internal variables: */
- for (int iFolderIndex = 0; iFolderIndex < vector.size(); ++iFolderIndex)
+ /* For each shared folder: */
+ for (int iFolderIndex = 0; iFolderIndex < sharedFolders.size(); ++iFolderIndex)
{
- const CSharedFolder &folder = vector[iFolderIndex];
- UISharedFolderData data;
- data.m_type = type;
- data.m_strName = folder.GetName();
- data.m_strHostPath = folder.GetHostPath();
- data.m_fAutoMount = folder.GetAutoMount();
- data.m_fWritable = folder.GetWritable();
- m_cache.m_items << data;
+ /* Prepare cache key & data: */
+ QString strSharedFolderKey = QString::number(iFolderIndex);
+ UIDataSettingsSharedFolder sharedFolderData;
+
+ /* Check if shared folder exists: */
+ const CSharedFolder &folder = sharedFolders[iFolderIndex];
+ if (!folder.isNull())
+ {
+ /* Gather shared folder values: */
+ sharedFolderData.m_type = sharedFoldersType;
+ sharedFolderData.m_strName = folder.GetName();
+ sharedFolderData.m_strHostPath = folder.GetHostPath();
+ sharedFolderData.m_fAutoMount = folder.GetAutoMount();
+ sharedFolderData.m_fWritable = folder.GetWritable();
+ /* Override shared folder cache key: */
+ strSharedFolderKey = sharedFolderData.m_strName;
+ }
+
+ /* Cache shared folder data: */
+ m_cache.child(strSharedFolderKey).cacheInitialData(sharedFolderData);
}
}
@@ -284,57 +271,56 @@ void UIMachineSettingsSF::loadToCacheFromVector(const CSharedFolderVector &vecto
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsSF::getFromCache()
{
- /* Apply internal variables data to QWidget(s): */
- if (m_type == MachineType || m_type == ConsoleType)
- root(MachineType);
- if (m_type == ConsoleType)
- root(ConsoleType);
- for (int iFolderIndex = 0; iFolderIndex < m_cache.m_items.size(); ++iFolderIndex)
+ /* Clear list initially: */
+ mTwFolders->clear();
+
+ /* Update root items visibility: */
+ updateRootItemsVisibility();
+
+ /* Load shared folders data: */
+ for (int iFolderIndex = 0; iFolderIndex < m_cache.childCount(); ++iFolderIndex)
{
- /* Get iterated folder's data: */
- const UISharedFolderData &data = m_cache.m_items[iFolderIndex];
- /* Prepare list item's fields: */
+ /* Get shared folder data: */
+ const UIDataSettingsSharedFolder &sharedFolderData = m_cache.child(iFolderIndex).base();
+ /* Prepare item fields: */
QStringList fields;
- fields << data.m_strName << data.m_strHostPath
- << (data.m_fAutoMount ? mTrYes : "")
- << (data.m_fWritable ? mTrFull : mTrReadOnly);
- /* Searching for item's root: */
- SFTreeViewItem *pItemsRoot = root(data.m_type);
- /* Create new folder list item: */
- new SFTreeViewItem(pItemsRoot, fields, SFTreeViewItem::EllipsisFile);
+ fields << sharedFolderData.m_strName
+ << sharedFolderData.m_strHostPath
+ << (sharedFolderData.m_fAutoMount ? mTrYes : "")
+ << (sharedFolderData.m_fWritable ? mTrFull : mTrReadOnly);
+ /* Create new shared folders item: */
+ new SFTreeViewItem(root(sharedFolderData.m_type), fields, SFTreeViewItem::EllipsisFile);
}
- /* Sort populated item's list: */
- mTwFolders->sortItems(0, Qt::AscendingOrder);
/* Ensure current item fetched: */
mTwFolders->setCurrentItem(mTwFolders->topLevelItem(0));
processCurrentChanged(mTwFolders->currentItem());
+
+ /* Polish page finally: */
+ polishPage();
}
/* Save data from corresponding widgets to cache,
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsSF::putToCache()
{
- /* Reset cache: */
- m_cache.m_items.clear();
- /* Gather internal variables data from QWidget(s): */
+ /* For each shared folder type: */
QTreeWidgetItem *pMainRootItem = mTwFolders->invisibleRootItem();
- /* Iterate other all the list top-level items: */
for (int iFodlersTypeIndex = 0; iFodlersTypeIndex < pMainRootItem->childCount(); ++iFodlersTypeIndex)
{
+ /* Get shared folder root item: */
SFTreeViewItem *pFolderTypeRoot = static_cast<SFTreeViewItem*>(pMainRootItem->child(iFodlersTypeIndex));
- UISharedFolderType type = (UISharedFolderType)pFolderTypeRoot->text(1).toInt();
- AssertMsg(type != WrongType, ("Incorrent folders type!"));
- /* Iterate other all the folder items: */
+ UISharedFolderType sharedFolderType = (UISharedFolderType)pFolderTypeRoot->text(1).toInt();
+ /* For each shared folder of current type: */
for (int iFoldersIndex = 0; iFoldersIndex < pFolderTypeRoot->childCount(); ++iFoldersIndex)
{
SFTreeViewItem *pFolderItem = static_cast<SFTreeViewItem*>(pFolderTypeRoot->child(iFoldersIndex));
- UISharedFolderData data;
- data.m_type = type;
- data.m_strName = pFolderItem->getText(0);
- data.m_strHostPath = pFolderItem->getText(1);
- data.m_fAutoMount = pFolderItem->getText(2) == mTrYes ? true : false;
- data.m_fWritable = pFolderItem->getText(3) == mTrFull ? true : false;
- m_cache.m_items << data;
+ UIDataSettingsSharedFolder sharedFolderData;
+ sharedFolderData.m_type = sharedFolderType;
+ sharedFolderData.m_strName = pFolderItem->getText(0);
+ sharedFolderData.m_strHostPath = pFolderItem->getText(1);
+ sharedFolderData.m_fAutoMount = pFolderItem->getText(2) == mTrYes ? true : false;
+ sharedFolderData.m_fWritable = pFolderItem->getText(3) == mTrFull ? true : false;
+ m_cache.child(sharedFolderData.m_strName).cacheCurrentData(sharedFolderData);
}
}
}
@@ -346,90 +332,61 @@ void UIMachineSettingsSF::saveFromCacheTo(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Gather corresponding values from internal variables: */
- saveFromCacheToMachine(m_machine);
+ /* Check if shared folders data was changed at all: */
+ if (m_cache.wasChanged())
+ {
+ /* Save machine (permanent) shared folders if possible: */
+ if (isSharedFolderTypeSupported(MachineType))
+ saveFromCacheTo(MachineType);
+ /* Save console (temporary) shared folders if possible: */
+ if (isSharedFolderTypeSupported(ConsoleType))
+ saveFromCacheTo(ConsoleType);
+ }
/* Upload machine to data: */
UISettingsPageMachine::uploadData(data);
}
-void UIMachineSettingsSF::saveFromCacheToMachine(CMachine &machine)
+void UIMachineSettingsSF::saveFromCacheTo(UISharedFolderType sharedFoldersType)
{
- /* Check if items were NOT changed: */
- if (!mIsListViewChanged)
- return;
-
- /* Delete all machine folders first: */
- const CSharedFolderVector &folders = machine.GetSharedFolders();
- for (int iFolderIndex = 0; iFolderIndex < folders.size() && !failed(); ++iFolderIndex)
- {
- const CSharedFolder &folder = folders[iFolderIndex];
- QString strFolderName = folder.GetName();
- QString strFolderPath = folder.GetHostPath();
- machine.RemoveSharedFolder(strFolderName);
- if (!machine.isOk())
- {
- /* Mark the page as failed: */
- setFailed(true);
- /* Show error message: */
- vboxProblem().cannotRemoveSharedFolder(machine, strFolderName, strFolderPath);
- }
- }
-
- /* Save all new machine folders: */
- for (int iFolderIndex = 0; iFolderIndex < m_cache.m_items.size() && !failed(); ++iFolderIndex)
+ /* For each shared folder data set: */
+ for (int iSharedFolderIndex = 0; iSharedFolderIndex < m_cache.childCount(); ++iSharedFolderIndex)
{
- const UISharedFolderData &data = m_cache.m_items[iFolderIndex];
- if (data.m_type == MachineType)
+ /* Check if this shared folder data was actually changed: */
+ const UICacheSettingsSharedFolder &sharedFolderCache = m_cache.child(iSharedFolderIndex);
+ if (sharedFolderCache.wasChanged())
{
- machine.CreateSharedFolder(data.m_strName, data.m_strHostPath, data.m_fWritable, data.m_fAutoMount);
- if (!machine.isOk())
+ /* If shared folder was removed: */
+ if (sharedFolderCache.wasRemoved())
{
- /* Mark the page as failed: */
- setFailed(true);
- /* Show error message: */
- vboxProblem().cannotCreateSharedFolder(machine, data.m_strName, data.m_strHostPath);
+ /* Get shared folder data: */
+ const UIDataSettingsSharedFolder &sharedFolderData = sharedFolderCache.base();
+ /* Check if thats shared folder of required type before removing: */
+ if (sharedFolderData.m_type == sharedFoldersType)
+ removeSharedFolder(sharedFolderCache);
}
- }
- }
-}
-
-void UIMachineSettingsSF::saveFromCacheToConsole(CConsole &console)
-{
- /* Check if items were NOT changed: */
- if (!mIsListViewChanged)
- return;
- /* Delete all console folders first: */
- const CSharedFolderVector &folders = console.GetSharedFolders();
- for (int iFolderIndex = 0; iFolderIndex < folders.size() && !failed(); ++iFolderIndex)
- {
- const CSharedFolder &folder = folders[iFolderIndex];
- QString strFolderName = folder.GetName();
- QString strFolderPath = folder.GetHostPath();
- console.RemoveSharedFolder(strFolderName);
- if (!console.isOk())
- {
- /* Mark the page as failed: */
- setFailed(true);
- /* Show error message: */
- vboxProblem().cannotRemoveSharedFolder(console, strFolderName, strFolderPath);
- }
- }
+ /* If shared folder was created: */
+ if (sharedFolderCache.wasCreated())
+ {
+ /* Get shared folder data: */
+ const UIDataSettingsSharedFolder &sharedFolderData = sharedFolderCache.data();
+ /* Check if thats shared folder of required type before creating: */
+ if (sharedFolderData.m_type == sharedFoldersType)
+ createSharedFolder(sharedFolderCache);
+ }
- /* Save all new console folders: */
- for (int iFolderIndex = 0; iFolderIndex < m_cache.m_items.size() && !failed(); ++iFolderIndex)
- {
- const UISharedFolderData &data = m_cache.m_items[iFolderIndex];
- if (data.m_type == ConsoleType)
- {
- console.CreateSharedFolder(data.m_strName, data.m_strHostPath, data.m_fWritable, data.m_fAutoMount);
- if (!console.isOk())
+ /* If shared folder was changed: */
+ if (sharedFolderCache.wasUpdated())
{
- /* Mark the page as failed: */
- setFailed(true);
- /* Show error message: */
- vboxProblem().cannotCreateSharedFolder(console, data.m_strName, data.m_strHostPath);
+ /* Get shared folder data: */
+ const UIDataSettingsSharedFolder &sharedFolderData = sharedFolderCache.data();
+ /* Check if thats shared folder of required type before recreating: */
+ if (sharedFolderData.m_type == sharedFoldersType)
+ {
+ removeSharedFolder(sharedFolderCache);
+ createSharedFolder(sharedFolderCache);
+ }
}
}
}
@@ -468,7 +425,7 @@ void UIMachineSettingsSF::retranslateUi()
void UIMachineSettingsSF::addTriggered()
{
/* Invoke Add-Box Dialog */
- UIMachineSettingsSFDetails dlg (UIMachineSettingsSFDetails::AddType, m_type == ConsoleType, usedList (true), this);
+ UIMachineSettingsSFDetails dlg (UIMachineSettingsSFDetails::AddType, isSharedFolderTypeSupported(ConsoleType), usedList (true), this);
if (dlg.exec() == QDialog::Accepted)
{
QString name = dlg.name();
@@ -476,23 +433,19 @@ void UIMachineSettingsSF::addTriggered()
bool isPermanent = dlg.isPermanent();
/* Shared folder's name & path could not be empty */
Assert (!name.isEmpty() && !path.isEmpty());
- /* Searching root for the new listview item */
- SFTreeViewItem *pRoot = root(isPermanent ? MachineType : ConsoleType);
- Assert (pRoot);
/* Appending a new listview item to the root */
QStringList fields;
fields << name /* name */ << path /* path */
<< (dlg.isAutoMounted() ? mTrYes : "" /* auto mount? */)
<< (dlg.isWriteable() ? mTrFull : mTrReadOnly /* writable? */);
- SFTreeViewItem *item = new SFTreeViewItem (pRoot, fields, SFTreeViewItem::EllipsisFile);
+ SFTreeViewItem *item = new SFTreeViewItem (root(isPermanent ? MachineType : ConsoleType),
+ fields, SFTreeViewItem::EllipsisFile);
mTwFolders->sortItems (0, Qt::AscendingOrder);
mTwFolders->scrollToItem (item);
mTwFolders->setCurrentItem (item);
processCurrentChanged (item);
mTwFolders->setFocus();
adjustList();
-
- mIsListViewChanged = true;
}
}
@@ -506,7 +459,7 @@ void UIMachineSettingsSF::edtTriggered()
Assert (item->parent());
/* Invoke Edit-Box Dialog */
- UIMachineSettingsSFDetails dlg (UIMachineSettingsSFDetails::EditType, m_type == ConsoleType, usedList (false), this);
+ UIMachineSettingsSFDetails dlg (UIMachineSettingsSFDetails::EditType, isSharedFolderTypeSupported(ConsoleType), usedList (false), this);
dlg.setPath (item->getText (1));
dlg.setName (item->getText (0));
dlg.setPermanent ((UISharedFolderType)item->parent()->text (1).toInt() != ConsoleType);
@@ -521,7 +474,6 @@ void UIMachineSettingsSF::edtTriggered()
Assert (!name.isEmpty() && !path.isEmpty());
/* Searching new root for the selected listview item */
SFTreeViewItem *pRoot = root(isPermanent ? MachineType : ConsoleType);
- Assert (pRoot);
/* Updating an edited listview item */
QStringList fields;
fields << name /* name */ << path /* path */
@@ -540,8 +492,6 @@ void UIMachineSettingsSF::edtTriggered()
mTwFolders->setFocus();
}
adjustList();
-
- mIsListViewChanged = true;
}
}
@@ -551,7 +501,6 @@ void UIMachineSettingsSF::delTriggered()
Assert (selectedItem);
delete selectedItem;
adjustList();
- mIsListViewChanged = true;
}
void UIMachineSettingsSF::processCurrentChanged (QTreeWidgetItem *aCurrentItem)
@@ -574,20 +523,21 @@ void UIMachineSettingsSF::processDoubleClick (QTreeWidgetItem *aItem)
edtTriggered();
}
-void UIMachineSettingsSF::showContextMenu (const QPoint &aPos)
+void UIMachineSettingsSF::showContextMenu(const QPoint &pos)
{
QMenu menu;
- QTreeWidgetItem *item = mTwFolders->itemAt (aPos);
- if (item && item->flags() & Qt::ItemIsSelectable)
+ QTreeWidgetItem *pItem = mTwFolders->itemAt(pos);
+ if (mTwFolders->isEnabled() && pItem && pItem->flags() & Qt::ItemIsSelectable)
{
- menu.addAction (mEdtAction);
- menu.addAction (mDelAction);
+ menu.addAction(mEdtAction);
+ menu.addAction(mDelAction);
}
else
{
- menu.addAction (mNewAction);
+ menu.addAction(mNewAction);
}
- menu.exec (mTwFolders->viewport()->mapToGlobal (aPos));
+ if (!menu.isEmpty())
+ menu.exec(mTwFolders->viewport()->mapToGlobal(pos));
}
void UIMachineSettingsSF::adjustList()
@@ -649,19 +599,17 @@ void UIMachineSettingsSF::showEvent (QShowEvent *aEvent)
QTimer::singleShot (0, this, SLOT (adjustList()));
}
-SFTreeViewItem* UIMachineSettingsSF::root(UISharedFolderType type)
+SFTreeViewItem* UIMachineSettingsSF::root(UISharedFolderType sharedFolderType)
{
- /* Prepare empty item: */
+ /* Search for the corresponding root item among all the top-level items: */
SFTreeViewItem *pRootItem = 0;
- /* Get top-level root item: */
QTreeWidgetItem *pMainRootItem = mTwFolders->invisibleRootItem();
- /* Iterate other the all root items: */
for (int iFolderTypeIndex = 0; iFolderTypeIndex < pMainRootItem->childCount(); ++iFolderTypeIndex)
{
/* Get iterated item: */
QTreeWidgetItem *pIteratedItem = pMainRootItem->child(iFolderTypeIndex);
- /* If iterated item's type is what we are looking for: */
- if (pIteratedItem->text(1).toInt() == type)
+ /* If iterated item type is what we are looking for: */
+ if (pIteratedItem->text(1).toInt() == sharedFolderType)
{
/* Remember the item: */
pRootItem = static_cast<SFTreeViewItem*>(pIteratedItem);
@@ -669,13 +617,65 @@ SFTreeViewItem* UIMachineSettingsSF::root(UISharedFolderType type)
break;
}
}
- /* If root item we are looking for still not found: */
+ /* Return root item: */
+ return pRootItem;
+}
+
+SFoldersNameList UIMachineSettingsSF::usedList (bool aIncludeSelected)
+{
+ /* Make the used names list: */
+ SFoldersNameList list;
+ QTreeWidgetItemIterator it (mTwFolders);
+ while (*it)
+ {
+ if ((*it)->parent() && (aIncludeSelected || !(*it)->isSelected()) &&
+ (*it)->type() == SFTreeViewItem::SFTreeViewItemType)
+ {
+ SFTreeViewItem *item = static_cast <SFTreeViewItem*> (*it);
+ UISharedFolderType type = (UISharedFolderType) item->parent()->text (1).toInt();
+ list << qMakePair (item->getText (0), type);
+ }
+ ++ it;
+ }
+ return list;
+}
+
+bool UIMachineSettingsSF::isSharedFolderTypeSupported(UISharedFolderType sharedFolderType) const
+{
+ bool fIsSharedFolderTypeSupported = false;
+ switch (sharedFolderType)
+ {
+ case MachineType:
+ fIsSharedFolderTypeSupported = isMachineInValidMode();
+ break;
+ case ConsoleType:
+ fIsSharedFolderTypeSupported = isMachineSaved() || isMachineOnline();
+ break;
+ default:
+ break;
+ }
+ return fIsSharedFolderTypeSupported;
+}
+
+void UIMachineSettingsSF::updateRootItemsVisibility()
+{
+ /* Update (show/hide) machine (permanent) root item: */
+ setRootItemVisible(MachineType, isSharedFolderTypeSupported(MachineType));
+ /* Update (show/hide) console (temporary) root item: */
+ setRootItemVisible(ConsoleType, isSharedFolderTypeSupported(ConsoleType));
+}
+
+void UIMachineSettingsSF::setRootItemVisible(UISharedFolderType sharedFolderType, bool fVisible)
+{
+ /* Search for the corresponding root item among all the top-level items: */
+ SFTreeViewItem *pRootItem = root(sharedFolderType);
+ /* If root item, we are looking for, still not found: */
if (!pRootItem)
{
- /* Preparing fields: */
+ /* Prepare fields for the new root item: */
QStringList fields;
/* Depending on folder type: */
- switch (type)
+ switch (sharedFolderType)
{
case MachineType:
fields << tr(" Machine Folders") << QString::number(MachineType);
@@ -686,33 +686,161 @@ SFTreeViewItem* UIMachineSettingsSF::root(UISharedFolderType type)
default:
break;
}
- /* Creating root: */
+ /* And create the new root item: */
pRootItem = new SFTreeViewItem(mTwFolders, fields, SFTreeViewItem::EllipsisEnd);
- /* We should show it (its not?): */
- pRootItem->setHidden(false);
- /* Expand it: */
- pRootItem->setExpanded(true);
}
- /* Return root item: */
- return pRootItem;
+ /* Expand/collaps it if necessary: */
+ pRootItem->setExpanded(fVisible);
+ /* And hide/show it if necessary: */
+ pRootItem->setHidden(!fVisible);
}
-SFoldersNameList UIMachineSettingsSF::usedList (bool aIncludeSelected)
+void UIMachineSettingsSF::polishPage()
{
- /* Make the used names list: */
- SFoldersNameList list;
- QTreeWidgetItemIterator it (mTwFolders);
- while (*it)
+ /* Update widgets availability: */
+ mNameSeparator->setEnabled(isMachineInValidMode());
+ mTwFolders->setEnabled(isMachineInValidMode());
+ mTbFolders->setEnabled(isMachineInValidMode());
+
+ /* Update root items visibility: */
+ updateRootItemsVisibility();
+}
+
+CSharedFolderVector UIMachineSettingsSF::getSharedFolders(UISharedFolderType sharedFoldersType)
+{
+ CSharedFolderVector sharedFolders;
+ if (isSharedFolderTypeSupported(sharedFoldersType))
{
- if ((*it)->parent() && (aIncludeSelected || !(*it)->isSelected()) &&
- (*it)->type() == SFTreeViewItem::SFTreeViewItemType)
+ switch (sharedFoldersType)
{
- SFTreeViewItem *item = static_cast <SFTreeViewItem*> (*it);
- UISharedFolderType type = (UISharedFolderType) item->parent()->text (1).toInt();
- list << qMakePair (item->getText (0), type);
+ case MachineType:
+ {
+ AssertMsg(!m_machine.isNull(), ("Machine is NOT set!\n"));
+ sharedFolders = m_machine.GetSharedFolders();
+ break;
+ }
+ case ConsoleType:
+ {
+ AssertMsg(!m_console.isNull(), ("Console is NOT set!\n"));
+ sharedFolders = m_console.GetSharedFolders();
+ break;
+ }
+ default:
+ break;
}
- ++ it;
}
- return list;
+ return sharedFolders;
+}
+
+bool UIMachineSettingsSF::removeSharedFolder(const UICacheSettingsSharedFolder &folderCache)
+{
+ /* Get shared folder data: */
+ const UIDataSettingsSharedFolder &folderData = folderCache.base();
+ QString strName = folderData.m_strName;
+ QString strPath = folderData.m_strHostPath;
+ UISharedFolderType sharedFoldersType = folderData.m_type;
+
+ /* Get current shared folders: */
+ CSharedFolderVector sharedFolders = getSharedFolders(sharedFoldersType);
+ /* Check that such shared folder really exists: */
+ CSharedFolder sharedFolder;
+ for (int iSharedFolderIndex = 0; iSharedFolderIndex < sharedFolders.size(); ++iSharedFolderIndex)
+ if (sharedFolders[iSharedFolderIndex].GetName() == strName)
+ sharedFolder = sharedFolders[iSharedFolderIndex];
+ if (!sharedFolder.isNull())
+ {
+ /* Remove existing shared folder: */
+ switch(sharedFoldersType)
+ {
+ case MachineType:
+ {
+ m_machine.RemoveSharedFolder(strName);
+ if (!m_machine.isOk())
+ {
+ /* Mark the page as failed: */
+ setFailed(true);
+ /* Show error message: */
+ vboxProblem().cannotRemoveSharedFolder(m_machine, strName, strPath);
+ /* Finish early: */
+ return false;
+ }
+ break;
+ }
+ case ConsoleType:
+ {
+ m_console.RemoveSharedFolder(strName);
+ if (!m_console.isOk())
+ {
+ /* Mark the page as failed: */
+ setFailed(true);
+ /* Show error message: */
+ vboxProblem().cannotRemoveSharedFolder(m_console, strName, strPath);
+ /* Finish early: */
+ return false;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return true;
}
+bool UIMachineSettingsSF::createSharedFolder(const UICacheSettingsSharedFolder &folderCache)
+{
+ /* Get shared folder data: */
+ const UIDataSettingsSharedFolder &folderData = folderCache.data();
+ QString strName = folderData.m_strName;
+ QString strPath = folderData.m_strHostPath;
+ bool fIsWritable = folderData.m_fWritable;
+ bool fIsAutoMount = folderData.m_fAutoMount;
+ UISharedFolderType sharedFoldersType = folderData.m_type;
+
+ /* Get current shared folders: */
+ CSharedFolderVector sharedFolders = getSharedFolders(sharedFoldersType);
+ /* Check if such shared folder do not exists: */
+ CSharedFolder sharedFolder;
+ for (int iSharedFolderIndex = 0; iSharedFolderIndex < sharedFolders.size(); ++iSharedFolderIndex)
+ if (sharedFolders[iSharedFolderIndex].GetName() == strName)
+ sharedFolder = sharedFolders[iSharedFolderIndex];
+ if (sharedFolder.isNull())
+ {
+ /* Create new shared folder: */
+ switch(sharedFoldersType)
+ {
+ case MachineType:
+ {
+ m_machine.CreateSharedFolder(strName, strPath, fIsWritable, fIsAutoMount);
+ if (!m_machine.isOk())
+ {
+ /* Mark the page as failed: */
+ setFailed(true);
+ /* Show error message: */
+ vboxProblem().cannotCreateSharedFolder(m_machine, strName, strPath);
+ /* Finish early: */
+ return false;
+ }
+ break;
+ }
+ case ConsoleType:
+ {
+ /* Create new shared folder: */
+ m_console.CreateSharedFolder(strName, strPath, fIsWritable, fIsAutoMount);
+ if (!m_console.isOk())
+ {
+ /* Mark the page as failed: */
+ setFailed(true);
+ /* Show error message: */
+ vboxProblem().cannotCreateSharedFolder(m_console, strName, strPath);
+ /* Finish early: */
+ return false;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return true;
+}
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.h b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.h
index 72e6ad864..62a38b255 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -26,31 +26,51 @@
/* Local forwards */
class SFTreeViewItem;
-enum UISharedFolderType
-{
- WrongType = 0x00,
- MachineType = 0x01,
- ConsoleType = 0x02
-};
+enum UISharedFolderType { MachineType, ConsoleType };
typedef QPair <QString, UISharedFolderType> SFolderName;
typedef QList <SFolderName> SFoldersNameList;
-/* Machine settings / Shared Folders page / Folder data: */
-struct UISharedFolderData
+/* Machine settings / Shared Folders page / Shared Folder data: */
+struct UIDataSettingsSharedFolder
{
+ /* Default constructor: */
+ UIDataSettingsSharedFolder()
+ : m_type(MachineType)
+ , m_strName(QString())
+ , m_strHostPath(QString())
+ , m_fAutoMount(false)
+ , m_fWritable(false) {}
+ /* Functions: */
+ bool equal(const UIDataSettingsSharedFolder &other) const
+ {
+ return (m_type == other.m_type) &&
+ (m_strName == other.m_strName) &&
+ (m_strHostPath == other.m_strHostPath) &&
+ (m_fAutoMount == other.m_fAutoMount) &&
+ (m_fWritable == other.m_fWritable);
+ }
+ /* Operators: */
+ bool operator==(const UIDataSettingsSharedFolder &other) const { return equal(other); }
+ bool operator!=(const UIDataSettingsSharedFolder &other) const { return !equal(other); }
+ /* Variables: */
UISharedFolderType m_type;
QString m_strName;
QString m_strHostPath;
bool m_fAutoMount;
bool m_fWritable;
- bool m_fEdited;
};
+typedef UISettingsCache<UIDataSettingsSharedFolder> UICacheSettingsSharedFolder;
-/* Machine settings / Shared Folders page / Cache: */
-struct UISettingsCacheMachineSFolders
+/* Machine settings / Shared Folders page / Shared Folders data: */
+struct UIDataSettingsSharedFolders
{
- QList<UISharedFolderData> m_items;
+ /* Default constructor: */
+ UIDataSettingsSharedFolders() {}
+ /* Operators: */
+ bool operator==(const UIDataSettingsSharedFolders& /* other */) const { return true; }
+ bool operator!=(const UIDataSettingsSharedFolders& /* other */) const { return false; }
};
+typedef UISettingsCachePool<UIDataSettingsSharedFolders, UICacheSettingsSharedFolder> UICacheSettingsSharedFolders;
class UIMachineSettingsSF : public UISettingsPageMachine,
public Ui::UIMachineSettingsSF
@@ -61,17 +81,12 @@ public:
UIMachineSettingsSF();
- void loadDirectlyFrom(const CConsole &console);
- void saveDirectlyTo(CConsole &console);
-
protected:
/* Load data to cashe from corresponding external object(s),
* this task COULD be performed in other than GUI thread: */
void loadToCacheFrom(QVariant &data);
- void loadToCacheFromMachine(const CMachine &machine);
- void loadToCacheFromConsole(const CConsole &console);
- void loadToCacheFromVector(const CSharedFolderVector &vector, UISharedFolderType type);
+ void loadToCacheFrom(UISharedFolderType sharedFoldersType);
/* Load data to corresponding widgets from cache,
* this task SHOULD be performed in GUI thread only: */
void getFromCache();
@@ -82,8 +97,10 @@ protected:
/* Save data from cache to corresponding external object(s),
* this task COULD be performed in other than GUI thread: */
void saveFromCacheTo(QVariant &data);
- void saveFromCacheToMachine(CMachine &machine);
- void saveFromCacheToConsole(CConsole &console);
+ void saveFromCacheTo(UISharedFolderType sharedFoldersType);
+
+ /* Page changed: */
+ bool changed() const { return m_cache.wasChanged(); }
void setOrderAfter (QWidget *aWidget);
@@ -111,18 +128,26 @@ private:
SFTreeViewItem* root(UISharedFolderType type);
SFoldersNameList usedList (bool aIncludeSelected);
- UISharedFolderType m_type;
+ bool isSharedFolderTypeSupported(UISharedFolderType sharedFolderType) const;
+ void updateRootItemsVisibility();
+ void setRootItemVisible(UISharedFolderType sharedFolderType, bool fVisible);
+
+ void polishPage();
+
+ CSharedFolderVector getSharedFolders(UISharedFolderType sharedFoldersType);
+
+ bool removeSharedFolder(const UICacheSettingsSharedFolder &folderCache);
+ bool createSharedFolder(const UICacheSettingsSharedFolder &folderCache);
QAction *mNewAction;
QAction *mEdtAction;
QAction *mDelAction;
- bool mIsListViewChanged;
QString mTrFull;
QString mTrReadOnly;
QString mTrYes;
/* Cache: */
- UISettingsCacheMachineSFolders m_cache;
+ UICacheSettingsSharedFolders m_cache;
};
#endif // __UIMachineSettingsSF_h__
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSFDetails.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSFDetails.cpp
index 25219fd47..710075642 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSFDetails.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSFDetails.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsSFDetails.cpp $ */
+/* $Id: UIMachineSettingsSFDetails.cpp 35956 2011-02-14 11:43:07Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.cpp
index 3334e5ff2..ac2378d88 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsSerial.cpp $ */
+/* $Id: UIMachineSettingsSerial.cpp 37126 2011-05-17 13:56:50Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2006-2008 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;
@@ -25,8 +25,9 @@
#include <QDir>
/* UIMachineSettingsSerial stuff */
-UIMachineSettingsSerial::UIMachineSettingsSerial()
+UIMachineSettingsSerial::UIMachineSettingsSerial(UIMachineSettingsSerialPage *pParent)
: QIWithRetranslateUI<QWidget> (0)
+ , m_pParent(pParent)
, mValidator(0)
, m_iSlot(-1)
{
@@ -64,33 +65,62 @@ UIMachineSettingsSerial::UIMachineSettingsSerial()
retranslateUi();
}
-void UIMachineSettingsSerial::fetchPortData(const UISerialPortData &data)
+void UIMachineSettingsSerial::polishTab()
{
- /* Load port slot number: */
- m_iSlot = data.m_iSlot;
-
- /* Fetch port data: */
- mGbSerial->setChecked(data.m_fPortEnabled);
- mCbNumber->setCurrentIndex(mCbNumber->findText(vboxGlobal().toCOMPortName(data.m_uIRQ, data.m_uIOBase)));
- mLeIRQ->setText(QString::number(data.m_uIRQ));
- mLeIOPort->setText("0x" + QString::number(data.m_uIOBase, 16).toUpper());
- mCbMode->setCurrentIndex(mCbMode->findText(vboxGlobal().toString(data.m_hostMode)));
- mCbPipe->setChecked(data.m_fServer);
- mLePath->setText(data.m_strPath);
+ ulong uIRQ, uIOBase;
+ bool fStd = vboxGlobal().toCOMPortNumbers(mCbNumber->currentText(), uIRQ, uIOBase);
+ KPortMode mode = vboxGlobal().toPortMode(mCbMode->currentText());
+
+ mGbSerial->setEnabled(m_pParent->isMachineOffline());
+ mLbNumber->setEnabled(m_pParent->isMachineOffline());
+ mCbNumber->setEnabled(m_pParent->isMachineOffline());
+ mLbIRQ->setEnabled(m_pParent->isMachineOffline());
+ mLeIRQ->setEnabled(!fStd && m_pParent->isMachineOffline());
+ mLbIOPort->setEnabled(m_pParent->isMachineOffline());
+ mLeIOPort->setEnabled(!fStd && m_pParent->isMachineOffline());
+ mLbMode->setEnabled(m_pParent->isMachineOffline());
+ mCbMode->setEnabled(m_pParent->isMachineOffline());
+ mCbPipe->setEnabled(mode == KPortMode_HostPipe && m_pParent->isMachineOffline());
+ mLbPath->setEnabled(m_pParent->isMachineOffline());
+ mLePath->setEnabled(mode != KPortMode_Disconnected && m_pParent->isMachineOffline());
+}
+
+void UIMachineSettingsSerial::fetchPortData(const UICacheSettingsMachineSerialPort &portCache)
+{
+ /* Get port data: */
+ const UIDataSettingsMachineSerialPort &portData = portCache.base();
+
+ /* Load port number: */
+ m_iSlot = portData.m_iSlot;
+
+ /* Load port data: */
+ mGbSerial->setChecked(portData.m_fPortEnabled);
+ mCbNumber->setCurrentIndex(mCbNumber->findText(vboxGlobal().toCOMPortName(portData.m_uIRQ, portData.m_uIOBase)));
+ mLeIRQ->setText(QString::number(portData.m_uIRQ));
+ mLeIOPort->setText("0x" + QString::number(portData.m_uIOBase, 16).toUpper());
+ mCbMode->setCurrentIndex(mCbMode->findText(vboxGlobal().toString(portData.m_hostMode)));
+ mCbPipe->setChecked(portData.m_fServer);
+ mLePath->setText(portData.m_strPath);
/* Ensure everything is up-to-date */
mGbSerialToggled(mGbSerial->isChecked());
}
-void UIMachineSettingsSerial::uploadPortData(UISerialPortData &data)
+void UIMachineSettingsSerial::uploadPortData(UICacheSettingsMachineSerialPort &portCache)
{
- /* Upload port data: */
- data.m_fPortEnabled = mGbSerial->isChecked();
- data.m_uIRQ = mLeIRQ->text().toULong(NULL, 0);
- data.m_uIOBase = mLeIOPort->text().toULong (NULL, 0);
- data.m_fServer = mCbPipe->isChecked();
- data.m_hostMode = vboxGlobal().toPortMode(mCbMode->currentText());
- data.m_strPath = QDir::toNativeSeparators(mLePath->text());
+ /* Prepare port data: */
+ UIDataSettingsMachineSerialPort portData = portCache.base();
+
+ /* Save port data: */
+ portData.m_fPortEnabled = mGbSerial->isChecked();
+ portData.m_uIRQ = mLeIRQ->text().toULong(NULL, 0);
+ portData.m_uIOBase = mLeIOPort->text().toULong (NULL, 0);
+ portData.m_fServer = mCbPipe->isChecked();
+ portData.m_hostMode = vboxGlobal().toPortMode(mCbMode->currentText());
+ portData.m_strPath = QDir::toNativeSeparators(mLePath->text());
+
+ /* Cache port data to port cache: */
+ portCache.cacheCurrentData(portData);
}
void UIMachineSettingsSerial::setValidator (QIWidgetValidator *aVal)
@@ -171,7 +201,6 @@ void UIMachineSettingsSerial::mCbModeActivated (const QString &aText)
{
KPortMode mode = vboxGlobal().toPortMode (aText);
mCbPipe->setEnabled (mode == KPortMode_HostPipe);
- mLbPath->setEnabled (mode != KPortMode_Disconnected);
mLePath->setEnabled (mode != KPortMode_Disconnected);
if (mValidator)
mValidator->revalidate();
@@ -189,21 +218,15 @@ UIMachineSettingsSerialPage::UIMachineSettingsSerialPage()
layout->setContentsMargins (0, 5, 0, 5);
layout->addWidget (mTabWidget);
- /* Load port data: */
+ /* How many ports to display: */
ulong uCount = vboxGlobal().virtualBox().GetSystemProperties().GetSerialPortCount();
- /* Apply internal variables data to QWidget(s): */
- for (ulong iSlot = 0; iSlot < uCount; ++iSlot)
+ /* Add corresponding tab pages to parent tab widget: */
+ for (ulong uPort = 0; uPort < uCount; ++uPort)
{
- /* Creating port's page: */
- UIMachineSettingsSerial *pPage = new UIMachineSettingsSerial;
-
- /* Attach port's page to Tab Widget: */
+ /* Creating port page: */
+ UIMachineSettingsSerial *pPage = new UIMachineSettingsSerial(this);
mTabWidget->addTab(pPage, pPage->pageTitle());
-
}
-
- /* Applying language settings */
- retranslateUi();
}
/* Load data to cashe from corresponding external object(s),
@@ -213,27 +236,31 @@ void UIMachineSettingsSerialPage::loadToCacheFrom(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Load port data: */
- ulong uCount = vboxGlobal().virtualBox().GetSystemProperties().GetSerialPortCount();
- for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
+ /* Clear cache initially: */
+ m_cache.clear();
+
+ /* For each serial port: */
+ for (int iSlot = 0; iSlot < mTabWidget->count(); ++iSlot)
{
- /* Get port: */
- const CSerialPort &port = m_machine.GetSerialPort(uSlot);
-
- /* Prepare port's data container: */
- UISerialPortData data;
-
- /* Load options: */
- data.m_iSlot = uSlot;
- data.m_fPortEnabled = port.GetEnabled();
- data.m_uIRQ = port.GetIRQ();
- data.m_uIOBase = port.GetIOBase();
- data.m_hostMode = port.GetHostMode();
- data.m_fServer = port.GetServer();
- data.m_strPath = port.GetPath();
-
- /* Append adapter's data container: */
- m_cache.m_items << data;
+ /* Prepare port data: */
+ UIDataSettingsMachineSerialPort portData;
+
+ /* Check if port is valid: */
+ const CSerialPort &port = m_machine.GetSerialPort(iSlot);
+ if (!port.isNull())
+ {
+ /* Gather options: */
+ portData.m_iSlot = iSlot;
+ portData.m_fPortEnabled = port.GetEnabled();
+ portData.m_uIRQ = port.GetIRQ();
+ portData.m_uIOBase = port.GetIOBase();
+ portData.m_hostMode = port.GetHostMode();
+ portData.m_fServer = port.GetServer();
+ portData.m_strPath = port.GetPath();
+ }
+
+ /* Cache port data: */
+ m_cache.child(iSlot).cacheInitialData(portData);
}
/* Upload machine to data: */
@@ -244,19 +271,19 @@ void UIMachineSettingsSerialPage::loadToCacheFrom(QVariant &data)
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsSerialPage::getFromCache()
{
- Assert(m_pFirstWidget);
- setTabOrder(m_pFirstWidget, mTabWidget->focusProxy());
+ /* Setup tab order: */
+ Assert(firstWidget());
+ setTabOrder(firstWidget(), mTabWidget->focusProxy());
QWidget *pLastFocusWidget = mTabWidget->focusProxy();
- ulong uCount = qMin(mTabWidget->count(), m_cache.m_items.size());
- /* Apply internal variables data to QWidget(s): */
- for (ulong iSlot = 0; iSlot < uCount; ++iSlot)
+ /* For each serial port: */
+ for (int iPort = 0; iPort < mTabWidget->count(); ++iPort)
{
- /* Getting adapter's page: */
- UIMachineSettingsSerial *pPage = qobject_cast<UIMachineSettingsSerial*>(mTabWidget->widget(iSlot));
+ /* Get port page: */
+ UIMachineSettingsSerial *pPage = qobject_cast<UIMachineSettingsSerial*>(mTabWidget->widget(iPort));
- /* Loading port's data into page: */
- pPage->fetchPortData(m_cache.m_items[iSlot]);
+ /* Load port data to page: */
+ pPage->fetchPortData(m_cache.child(iPort));
/* Setup page validation: */
pPage->setValidator(mValidator);
@@ -268,22 +295,26 @@ void UIMachineSettingsSerialPage::getFromCache()
/* Applying language settings: */
retranslateUi();
+ /* Polish page finally: */
+ polishPage();
+
/* Revalidate if possible: */
- if (mValidator) mValidator->revalidate();
+ if (mValidator)
+ mValidator->revalidate();
}
/* Save data from corresponding widgets to cache,
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsSerialPage::putToCache()
{
- /* Gather internal variables data from QWidget(s): */
- for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+ /* For each serial port: */
+ for (int iPort = 0; iPort < mTabWidget->count(); ++iPort)
{
- /* Getting adapter's page: */
- UIMachineSettingsSerial *pPage = qobject_cast<UIMachineSettingsSerial*>(mTabWidget->widget(iSlot));
+ /* Getting port page: */
+ UIMachineSettingsSerial *pPage = qobject_cast<UIMachineSettingsSerial*>(mTabWidget->widget(iPort));
- /* Loading Adapter's data from page: */
- pPage->uploadPortData(m_cache.m_items[iSlot]);
+ /* Gather & cache port data: */
+ pPage->uploadPortData(m_cache.child(iPort));
}
}
@@ -294,25 +325,39 @@ void UIMachineSettingsSerialPage::saveFromCacheTo(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Gather corresponding values from internal variables: */
- for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+ /* Check if ports data was changed: */
+ if (m_cache.wasChanged())
{
- /* Get adapter: */
- CSerialPort port = m_machine.GetSerialPort(iSlot);
-
- /* Get cached data for this slot: */
- const UISerialPortData &data = m_cache.m_items[iSlot];
-
- /* Save options: */
- port.SetEnabled(data.m_fPortEnabled);
- port.SetIRQ(data.m_uIRQ);
- port.SetIOBase(data.m_uIOBase);
- port.SetServer(data.m_fServer);
- port.SetPath(data.m_strPath);
- /* This *must* be last. The host mode will be changed to disconnected if
- * some of the necessary settings above will not meet the requirements for
- * the selected mode. */
- port.SetHostMode(data.m_hostMode);
+ /* For each serial port: */
+ for (int iPort = 0; iPort < mTabWidget->count(); ++iPort)
+ {
+ /* Check if port data was changed: */
+ const UICacheSettingsMachineSerialPort &portCache = m_cache.child(iPort);
+ if (portCache.wasChanged())
+ {
+ /* Check if port still valid: */
+ CSerialPort port = m_machine.GetSerialPort(iPort);
+ if (!port.isNull())
+ {
+ /* Get port data: */
+ const UIDataSettingsMachineSerialPort &portData = portCache.data();
+
+ /* Store adapter data: */
+ if (isMachineOffline())
+ {
+ port.SetEnabled(portData.m_fPortEnabled);
+ port.SetIRQ(portData.m_uIRQ);
+ port.SetIOBase(portData.m_uIOBase);
+ port.SetServer(portData.m_fServer);
+ port.SetPath(portData.m_strPath);
+ /* This *must* be last. The host mode will be changed to disconnected if
+ * some of the necessary settings above will not meet the requirements for
+ * the selected mode. */
+ port.SetHostMode(portData.m_hostMode);
+ }
+ }
+ }
+ }
}
/* Upload machine to data: */
@@ -393,3 +438,16 @@ void UIMachineSettingsSerialPage::retranslateUi()
}
}
+void UIMachineSettingsSerialPage::polishPage()
+{
+ /* Get the count of serial port tabs: */
+ for (int iPort = 0; iPort < mTabWidget->count(); ++iPort)
+ {
+ mTabWidget->setTabEnabled(iPort,
+ isMachineOffline() ||
+ (isMachineInValidMode() && m_cache.child(iPort).base().m_fPortEnabled));
+ UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(mTabWidget->widget(iPort));
+ pTab->polishTab();
+ }
+}
+
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.h b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.h
index 962ad8969..083cdcf24 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.h
@@ -5,7 +5,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;
@@ -23,11 +23,37 @@
#include "UIMachineSettingsSerial.gen.h"
#include "COMDefs.h"
+/* Forward declarations */
+class UIMachineSettingsSerialPage;
class QITabWidget;
-/* Machine settings / Network page / Port data: */
-struct UISerialPortData
+/* Machine settings / Serial page / Port data: */
+struct UIDataSettingsMachineSerialPort
{
+ /* Default constructor: */
+ UIDataSettingsMachineSerialPort()
+ : m_iSlot(-1)
+ , m_fPortEnabled(false)
+ , m_uIRQ(0)
+ , m_uIOBase(0)
+ , m_hostMode(KPortMode_Disconnected)
+ , m_fServer(false)
+ , m_strPath(QString()) {}
+ /* Functions: */
+ bool equal(const UIDataSettingsMachineSerialPort &other) const
+ {
+ return (m_iSlot == other.m_iSlot) &&
+ (m_fPortEnabled == other.m_fPortEnabled) &&
+ (m_uIRQ == other.m_uIRQ) &&
+ (m_uIOBase == other.m_uIOBase) &&
+ (m_hostMode == other.m_hostMode) &&
+ (m_fServer == other.m_fServer) &&
+ (m_strPath == other.m_strPath);
+ }
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineSerialPort &other) const { return equal(other); }
+ bool operator!=(const UIDataSettingsMachineSerialPort &other) const { return !equal(other); }
+ /* Variables: */
int m_iSlot;
bool m_fPortEnabled;
ulong m_uIRQ;
@@ -36,12 +62,18 @@ struct UISerialPortData
bool m_fServer;
QString m_strPath;
};
+typedef UISettingsCache<UIDataSettingsMachineSerialPort> UICacheSettingsMachineSerialPort;
-/* Machine settings / Serial page / Cache: */
-struct UISettingsCacheMachineSerial
+/* Machine settings / Serial page / Ports data: */
+struct UIDataSettingsMachineSerial
{
- QList<UISerialPortData> m_items;
+ /* Default constructor: */
+ UIDataSettingsMachineSerial() {}
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineSerial& /* other */) const { return true; }
+ bool operator!=(const UIDataSettingsMachineSerial& /* other */) const { return false; }
};
+typedef UISettingsCachePool<UIDataSettingsMachineSerial, UICacheSettingsMachineSerialPort> UICacheSettingsMachineSerial;
class UIMachineSettingsSerial : public QIWithRetranslateUI<QWidget>,
public Ui::UIMachineSettingsSerial
@@ -50,10 +82,12 @@ class UIMachineSettingsSerial : public QIWithRetranslateUI<QWidget>,
public:
- UIMachineSettingsSerial();
+ UIMachineSettingsSerial(UIMachineSettingsSerialPage *pParent);
- void fetchPortData(const UISerialPortData &data);
- void uploadPortData(UISerialPortData &data);
+ void polishTab();
+
+ void fetchPortData(const UICacheSettingsMachineSerialPort &data);
+ void uploadPortData(UICacheSettingsMachineSerialPort &data);
void setValidator (QIWidgetValidator *aVal);
@@ -74,6 +108,7 @@ private slots:
private:
+ UIMachineSettingsSerialPage *m_pParent;
QIWidgetValidator *mValidator;
int m_iSlot;
};
@@ -103,6 +138,9 @@ protected:
* this task COULD be performed in other than GUI thread: */
void saveFromCacheTo(QVariant &data);
+ /* Page changed: */
+ bool changed() const { return m_cache.wasChanged(); }
+
void setValidator (QIWidgetValidator *aVal);
bool revalidate (QString &aWarning, QString &aTitle);
@@ -110,11 +148,13 @@ protected:
private:
+ void polishPage();
+
QIWidgetValidator *mValidator;
QITabWidget *mTabWidget;
/* Cache: */
- UISettingsCacheMachineSerial m_cache;
+ UICacheSettingsMachineSerial m_cache;
};
#endif // __UIMachineSettingsSerial_h__
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp
index b7a2e9d7d..32e80d3ee 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsStorage.cpp $ */
+/* $Id: UIMachineSettingsStorage.cpp 37956 2011-07-14 12:28:48Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,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;
@@ -20,7 +20,7 @@
/* Local Includes */
#include "QIWidgetValidator.h"
#include "UIIconPool.h"
-#include "UINewHDWzd.h"
+#include "UINewHDWizard.h"
#include "VBoxGlobal.h"
#include "QIFileDialog.h"
#include "VBoxProblemReporter.h"
@@ -385,6 +385,7 @@ ControllerItem::ControllerItem (AbstractItem *aParent, const QString &aName,
: AbstractItem (aParent)
, mCtrName (aName)
, mCtrType (0)
+ , mPortCount (0)
, mUseIoCache (false)
{
/* Check for proper parent type */
@@ -443,6 +444,18 @@ ControllerTypeList ControllerItem::ctrTypes() const
return mCtrType->ctrTypes();
}
+uint ControllerItem::portCount()
+{
+ /* Recalculate actual port count: */
+ for (int i = 0; i < mAttachments.size(); ++i)
+ {
+ AttachmentItem *pItem = static_cast<AttachmentItem*>(mAttachments[i]);
+ if (mPortCount < (uint)pItem->attSlot().port + 1)
+ mPortCount = (uint)pItem->attSlot().port + 1;
+ }
+ return mPortCount;
+}
+
bool ControllerItem::ctrUseIoCache() const
{
return mUseIoCache;
@@ -458,6 +471,12 @@ void ControllerItem::setCtrType (KStorageControllerType aCtrType)
mCtrType->setCtrType (aCtrType);
}
+void ControllerItem::setPortCount (uint aPortCount)
+{
+ /* Limit maximum port count: */
+ mPortCount = qMin(aPortCount, (uint)vboxGlobal().virtualBox().GetSystemProperties().GetMaxPortCountForStorageBus(ctrBusType()));
+}
+
void ControllerItem::setCtrUseIoCache (bool aUseIoCache)
{
mUseIoCache = aUseIoCache;
@@ -550,6 +569,8 @@ AttachmentItem::AttachmentItem (AbstractItem *aParent, KDeviceType aDeviceType)
, mAttDeviceType (aDeviceType)
, mAttIsHostDrive (false)
, mAttIsPassthrough (false)
+ , mAttIsTempEject (false)
+ , mAttIsNonRotational (false)
{
/* Check for proper parent type */
AssertMsg (mParent->rtti() == AbstractItem::Type_ControllerItem, ("Incorrect parent type!\n"));
@@ -603,6 +624,16 @@ bool AttachmentItem::attIsPassthrough() const
return mAttIsPassthrough;
}
+bool AttachmentItem::attIsTempEject() const
+{
+ return mAttIsTempEject;
+}
+
+bool AttachmentItem::attIsNonRotational() const
+{
+ return mAttIsNonRotational;
+}
+
void AttachmentItem::setAttSlot (const StorageSlot &aAttSlot)
{
mAttSlot = aAttSlot;
@@ -625,6 +656,16 @@ void AttachmentItem::setAttIsPassthrough (bool aIsAttPassthrough)
mAttIsPassthrough = aIsAttPassthrough;
}
+void AttachmentItem::setAttIsTempEject (bool aIsAttTempEject)
+{
+ mAttIsTempEject = aIsAttTempEject;
+}
+
+void AttachmentItem::setAttIsNonRotational (bool aIsAttNonRotational)
+{
+ mAttIsNonRotational = aIsAttNonRotational;
+}
+
QString AttachmentItem::attSize() const
{
return mAttSize;
@@ -645,6 +686,11 @@ QString AttachmentItem::attFormat() const
return mAttFormat;
}
+QString AttachmentItem::attDetails() const
+{
+ return mAttDetails;
+}
+
QString AttachmentItem::attUsage() const
{
return mAttUsage;
@@ -675,6 +721,7 @@ void AttachmentItem::cache()
case KDeviceType_HardDisk:
{
mAttFormat = QString("%1 (%2)").arg(medium.hardDiskType(true)).arg(medium.hardDiskFormat(true));
+ mAttDetails = medium.storageDetails();
break;
}
case KDeviceType_DVD:
@@ -765,6 +812,7 @@ StorageModel::StorageModel (QObject *aParent)
, mRootItem (new RootItem)
, mToolTipType (DefaultToolTip)
, m_chipsetType(KChipsetType_PIIX3)
+ , m_dialogType(SettingsDialogType_Wrong)
{
}
@@ -934,28 +982,33 @@ QVariant StorageModel::data (const QModelIndex &aIndex, int aRole) const
}
case R_IsMoreIDEControllersPossible:
{
- return static_cast <RootItem*> (mRootItem)->childCount (KStorageBus_IDE) <
- vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus (chipsetType(), KStorageBus_IDE);
+ return (m_dialogType == SettingsDialogType_Offline) &&
+ (static_cast<RootItem*>(mRootItem)->childCount(KStorageBus_IDE) <
+ vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_IDE));
}
case R_IsMoreSATAControllersPossible:
{
- return static_cast <RootItem*> (mRootItem)->childCount (KStorageBus_SATA) <
- vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus (chipsetType(), KStorageBus_SATA);
+ return (m_dialogType == SettingsDialogType_Offline) &&
+ (static_cast<RootItem*>(mRootItem)->childCount(KStorageBus_SATA) <
+ vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_SATA));
}
case R_IsMoreSCSIControllersPossible:
{
- return static_cast <RootItem*> (mRootItem)->childCount (KStorageBus_SCSI) <
- vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus (chipsetType(), KStorageBus_SCSI);
+ return (m_dialogType == SettingsDialogType_Offline) &&
+ (static_cast<RootItem*>(mRootItem)->childCount(KStorageBus_SCSI) <
+ vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_SCSI));
}
case R_IsMoreFloppyControllersPossible:
{
- return static_cast <RootItem*> (mRootItem)->childCount (KStorageBus_Floppy) <
- vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus (chipsetType(), KStorageBus_Floppy);
+ return (m_dialogType == SettingsDialogType_Offline) &&
+ (static_cast<RootItem*>(mRootItem)->childCount(KStorageBus_Floppy) <
+ vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_Floppy));
}
case R_IsMoreSASControllersPossible:
{
- return static_cast <RootItem*> (mRootItem)->childCount (KStorageBus_SAS) <
- vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus (chipsetType(), KStorageBus_SAS);
+ return (m_dialogType == SettingsDialogType_Offline) &&
+ (static_cast<RootItem*>(mRootItem)->childCount(KStorageBus_SAS) <
+ vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_SAS));
}
case R_IsMoreAttachmentsPossible:
{
@@ -965,8 +1018,9 @@ QVariant StorageModel::data (const QModelIndex &aIndex, int aRole) const
{
ControllerItem *ctr = static_cast <ControllerItem*> (item);
CSystemProperties sp = vboxGlobal().virtualBox().GetSystemProperties();
- return (uint) rowCount (aIndex) < sp.GetMaxPortCountForStorageBus (ctr->ctrBusType()) *
- sp.GetMaxDevicesPerPortForStorageBus (ctr->ctrBusType());
+ return (m_dialogType == SettingsDialogType_Offline) &&
+ ((uint)rowCount(aIndex) < sp.GetMaxPortCountForStorageBus(ctr->ctrBusType()) *
+ sp.GetMaxDevicesPerPortForStorageBus(ctr->ctrBusType()));
}
}
return false;
@@ -1011,6 +1065,13 @@ QVariant StorageModel::data (const QModelIndex &aIndex, int aRole) const
result.setValue (static_cast <ControllerItem*> (item)->ctrBusType());
return result;
}
+ case R_CtrPortCount:
+ {
+ if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
+ if (item->rtti() == AbstractItem::Type_ControllerItem)
+ return static_cast <ControllerItem*> (item)->portCount();
+ return 0;
+ }
case R_CtrIoCache:
{
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
@@ -1064,6 +1125,20 @@ QVariant StorageModel::data (const QModelIndex &aIndex, int aRole) const
return static_cast <AttachmentItem*> (item)->attIsPassthrough();
return false;
}
+ case R_AttIsTempEject:
+ {
+ if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
+ if (item->rtti() == AbstractItem::Type_AttachmentItem)
+ return static_cast <AttachmentItem*> (item)->attIsTempEject();
+ return false;
+ }
+ case R_AttIsNonRotational:
+ {
+ if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
+ if (item->rtti() == AbstractItem::Type_AttachmentItem)
+ return static_cast <AttachmentItem*> (item)->attIsNonRotational();
+ return false;
+ }
case R_AttSize:
{
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
@@ -1092,6 +1167,13 @@ QVariant StorageModel::data (const QModelIndex &aIndex, int aRole) const
return static_cast <AttachmentItem*> (item)->attFormat();
return QString();
}
+ case R_AttDetails:
+ {
+ if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
+ if (item->rtti() == AbstractItem::Type_AttachmentItem)
+ return static_cast <AttachmentItem*> (item)->attDetails();
+ return QString();
+ }
case R_AttUsage:
{
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
@@ -1210,6 +1292,17 @@ bool StorageModel::setData (const QModelIndex &aIndex, const QVariant &aValue, i
}
return false;
}
+ case R_CtrPortCount:
+ {
+ if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
+ if (item->rtti() == AbstractItem::Type_ControllerItem)
+ {
+ static_cast <ControllerItem*> (item)->setPortCount (aValue.toUInt());
+ emit dataChanged (aIndex, aIndex);
+ return true;
+ }
+ return false;
+ }
case R_CtrIoCache:
{
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
@@ -1266,6 +1359,28 @@ bool StorageModel::setData (const QModelIndex &aIndex, const QVariant &aValue, i
}
return false;
}
+ case R_AttIsTempEject:
+ {
+ if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
+ if (item->rtti() == AbstractItem::Type_AttachmentItem)
+ {
+ static_cast <AttachmentItem*> (item)->setAttIsTempEject (aValue.toBool());
+ emit dataChanged (aIndex, aIndex);
+ return true;
+ }
+ return false;
+ }
+ case R_AttIsNonRotational:
+ {
+ if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
+ if (item->rtti() == AbstractItem::Type_AttachmentItem)
+ {
+ static_cast <AttachmentItem*> (item)->setAttIsNonRotational (aValue.toBool());
+ emit dataChanged (aIndex, aIndex);
+ return true;
+ }
+ return false;
+ }
default:
break;
}
@@ -1412,6 +1527,21 @@ void StorageModel::setChipsetType(KChipsetType type)
m_chipsetType = type;
}
+void StorageModel::setDialogType(SettingsDialogType dialogType)
+{
+ m_dialogType = dialogType;
+}
+
+void StorageModel::clear()
+{
+ while (mRootItem->childCount())
+ {
+ beginRemoveRows(root(), 0, 0);
+ delete mRootItem->childByPos(0);
+ endRemoveRows();
+ }
+}
+
QMap<KStorageBus, int> StorageModel::currentControllerTypes() const
{
QMap<KStorageBus, int> currentMap;
@@ -1682,12 +1812,16 @@ UIMachineSettingsStorage::UIMachineSettingsStorage()
QMenu *pOpenMediumMenu = new QMenu(this);
mTbOpen->setMenu(pOpenMediumMenu);
+ /* Controller pane initialization: */
+ mSbPortCount->setValue(0);
+
/* Info Pane initialization */
mLbHDFormatValue->setFullSizeSelection (true);
mLbCDFDTypeValue->setFullSizeSelection (true);
mLbHDVirtualSizeValue->setFullSizeSelection (true);
mLbHDActualSizeValue->setFullSizeSelection (true);
mLbSizeValue->setFullSizeSelection (true);
+ mLbHDDetailsValue->setFullSizeSelection (true);
mLbLocationValue->setFullSizeSelection (true);
mLbUsageValue->setFullSizeSelection (true);
@@ -1729,11 +1863,14 @@ UIMachineSettingsStorage::UIMachineSettingsStorage()
connect (mLeName, SIGNAL (textEdited (const QString&)), this, SLOT (setInformation()));
connect (mCbType, SIGNAL (activated (int)), this, SLOT (setInformation()));
connect (mCbSlot, SIGNAL (activated (int)), this, SLOT (setInformation()));
+ connect (mSbPortCount, SIGNAL (valueChanged (int)), this, SLOT (setInformation()));
connect (mCbIoCache, SIGNAL (stateChanged (int)), this, SLOT (setInformation()));
connect (m_pMediumIdHolder, SIGNAL (sigChanged()), this, SLOT (setInformation()));
connect (mTbOpen, SIGNAL (clicked (bool)), mTbOpen, SLOT (showMenu()));
connect (pOpenMediumMenu, SIGNAL (aboutToShow()), this, SLOT (sltPrepareOpenMediumMenu()));
connect (mCbPassthrough, SIGNAL (stateChanged (int)), this, SLOT (setInformation()));
+ connect (mCbTempEject, SIGNAL (stateChanged (int)), this, SLOT (setInformation()));
+ connect (mCbNonRotational, SIGNAL (stateChanged (int)), this, SLOT (setInformation()));
/* Applying language settings */
retranslateUi();
@@ -1743,27 +1880,12 @@ UIMachineSettingsStorage::UIMachineSettingsStorage()
mSplitter->setSizes (QList<int>() << (int) (0.45 * minimumWidth()) << (int) (0.55 * minimumWidth()));
}
-KChipsetType UIMachineSettingsStorage::chipsetType() const
-{
- return mStorageModel->chipsetType();
-}
-
void UIMachineSettingsStorage::setChipsetType(KChipsetType type)
{
mStorageModel->setChipsetType(type);
updateActionsState();
}
-QMap<KStorageBus, int> UIMachineSettingsStorage::currentControllerTypes() const
-{
- return mStorageModel->currentControllerTypes();
-}
-
-QMap<KStorageBus, int> UIMachineSettingsStorage::maximumControllerTypes() const
-{
- return mStorageModel->maximumControllerTypes();
-}
-
/* Load data to cashe from corresponding external object(s),
* this task COULD be performed in other than GUI thread: */
void UIMachineSettingsStorage::loadToCacheFrom(QVariant &data)
@@ -1771,37 +1893,63 @@ void UIMachineSettingsStorage::loadToCacheFrom(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Fill internal variables with corresponding values: */
- m_cache.m_strMachineId = m_machine.GetId();
- /* Load controllers list: */
+ /* Clear cache initially: */
+ m_cache.clear();
+
+ /* Gather storage data: */
+ m_strMachineId = m_machine.GetId();
+ m_strMachineSettingsFilePath = m_machine.GetSettingsFilePath();
+ m_strMachineGuestOSTypeId = m_machine.GetOSTypeId();
+
+ /* For each controller: */
const CStorageControllerVector &controllers = m_machine.GetStorageControllers();
for (int iControllerIndex = 0; iControllerIndex < controllers.size(); ++iControllerIndex)
{
- /* Prepare controller item: */
+ /* Prepare storage controller data: */
+ UIDataSettingsMachineStorageController storageControllerData;
+
+ /* Check if controller is valid: */
const CStorageController &controller = controllers[iControllerIndex];
- UIStorageControllerData controllerData;
- controllerData.m_strControllerName = controller.GetName();
- controllerData.m_controllerBus = controller.GetBus();
- controllerData.m_controllerType = controller.GetControllerType();
- controllerData.m_fUseHostIOCache = controller.GetUseHostIOCache();
- /* Load attachments list: */
- const CMediumAttachmentVector &attachments = m_machine.GetMediumAttachmentsOfController(controllerData.m_strControllerName);
- for (int iAttachmentIndex = 0; iAttachmentIndex < attachments.size(); ++iAttachmentIndex)
- {
- /* Prepare attachment item: */
- const CMediumAttachment &attachment = attachments[iAttachmentIndex];
- UIStorageAttachmentData attachmentData;
- attachmentData.m_attachmentType = attachment.GetType();
- attachmentData.m_iAttachmentPort = attachment.GetPort();
- attachmentData.m_iAttachmentDevice = attachment.GetDevice();
- attachmentData.m_fAttachmentPassthrough = attachment.GetPassthrough();
- CMedium comMedium(attachment.GetMedium());
- VBoxMedium vboxMedium;
- vboxGlobal().findMedium(comMedium, vboxMedium);
- attachmentData.m_strAttachmentMediumId = vboxMedium.id();
- controllerData.m_items << attachmentData;
- }
- m_cache.m_items << controllerData;
+ if (!controller.isNull())
+ {
+ /* Gather storage controller data: */
+ storageControllerData.m_strControllerName = controller.GetName();
+ storageControllerData.m_controllerBus = controller.GetBus();
+ storageControllerData.m_controllerType = controller.GetControllerType();
+ storageControllerData.m_uPortCount = controller.GetPortCount();
+ storageControllerData.m_fUseHostIOCache = controller.GetUseHostIOCache();
+
+ /* For each attachment: */
+ const CMediumAttachmentVector &attachments = m_machine.GetMediumAttachmentsOfController(storageControllerData.m_strControllerName);
+ for (int iAttachmentIndex = 0; iAttachmentIndex < attachments.size(); ++iAttachmentIndex)
+ {
+ /* Prepare storage attachment data: */
+ UIDataSettingsMachineStorageAttachment storageAttachmentData;
+
+ /* Check if attachment is valid: */
+ const CMediumAttachment &attachment = attachments[iAttachmentIndex];
+ if (!attachment.isNull())
+ {
+ /* Gather storage attachment data: */
+ storageAttachmentData.m_attachmentType = attachment.GetType();
+ storageAttachmentData.m_iAttachmentPort = attachment.GetPort();
+ storageAttachmentData.m_iAttachmentDevice = attachment.GetDevice();
+ storageAttachmentData.m_fAttachmentPassthrough = attachment.GetPassthrough();
+ storageAttachmentData.m_fAttachmentTempEject = attachment.GetTemporaryEject();
+ storageAttachmentData.m_fAttachmentNonRotational = attachment.GetNonRotational();
+ CMedium comMedium(attachment.GetMedium());
+ VBoxMedium vboxMedium;
+ vboxGlobal().findMedium(comMedium, vboxMedium);
+ storageAttachmentData.m_strAttachmentMediumId = vboxMedium.id();
+ }
+
+ /* Cache storage attachment data: */
+ m_cache.child(iControllerIndex).child(iAttachmentIndex).cacheInitialData(storageAttachmentData);
+ }
+ }
+
+ /* Cache storage controller data: */
+ m_cache.child(iControllerIndex).cacheInitialData(storageControllerData);
}
/* Upload machine to data: */
@@ -1812,27 +1960,45 @@ void UIMachineSettingsStorage::loadToCacheFrom(QVariant &data)
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsStorage::getFromCache()
{
- /* Apply internal variables data to QWidget(s): */
- mStorageModel->setMachineId(m_cache.m_strMachineId);
- for (int iControllerIndex = 0; iControllerIndex < m_cache.m_items.size(); ++iControllerIndex)
+ /* Clear model initially: */
+ mStorageModel->clear();
+
+ /* Load storage data to page: */
+ mStorageModel->setMachineId(m_strMachineId);
+
+ /* For each storage controller: */
+ for (int iControllerIndex = 0; iControllerIndex < m_cache.childCount(); ++iControllerIndex)
{
- /* Get iterated controller: */
- const UIStorageControllerData &controllerData = m_cache.m_items[iControllerIndex];
+ /* Get storage controller cache: */
+ const UICacheSettingsMachineStorageController &controllerCache = m_cache.child(iControllerIndex);
+ /* Get storage controller data from cache: */
+ const UIDataSettingsMachineStorageController &controllerData = controllerCache.base();
+
+ /* Load storage controller data to page: */
QModelIndex controllerIndex = mStorageModel->addController(controllerData.m_strControllerName,
controllerData.m_controllerBus,
controllerData.m_controllerType);
QUuid controllerId = QUuid(mStorageModel->data(controllerIndex, StorageModel::R_ItemId).toString());
+ mStorageModel->setData(controllerIndex, controllerData.m_uPortCount, StorageModel::R_CtrPortCount);
mStorageModel->setData(controllerIndex, controllerData.m_fUseHostIOCache, StorageModel::R_CtrIoCache);
- for (int iAttachmentIndex = 0; iAttachmentIndex < controllerData.m_items.size(); ++iAttachmentIndex)
+
+ /* For each storage attachment: */
+ for (int iAttachmentIndex = 0; iAttachmentIndex < controllerCache.childCount(); ++iAttachmentIndex)
{
- /* Get iterated attachment: */
- const UIStorageAttachmentData &attachmentData = controllerData.m_items[iAttachmentIndex];
+ /* Get storage attachment cache: */
+ const UICacheSettingsMachineStorageAttachment &attachmentCache = controllerCache.child(iAttachmentIndex);
+ /* Get storage controller data from cache: */
+ const UIDataSettingsMachineStorageAttachment &attachmentData = attachmentCache.base();
+
+ /* Load storage attachment data to page: */
QModelIndex attachmentIndex = mStorageModel->addAttachment(controllerId, attachmentData.m_attachmentType, attachmentData.m_strAttachmentMediumId);
StorageSlot attachmentStorageSlot(controllerData.m_controllerBus,
attachmentData.m_iAttachmentPort,
attachmentData.m_iAttachmentDevice);
mStorageModel->setData(attachmentIndex, QVariant::fromValue(attachmentStorageSlot), StorageModel::R_AttSlot);
mStorageModel->setData(attachmentIndex, attachmentData.m_fAttachmentPassthrough, StorageModel::R_AttIsPassthrough);
+ mStorageModel->setData(attachmentIndex, attachmentData.m_fAttachmentTempEject, StorageModel::R_AttIsTempEject);
+ mStorageModel->setData(attachmentIndex, attachmentData.m_fAttachmentNonRotational, StorageModel::R_AttIsNonRotational);
}
}
/* Set the first controller as current if present */
@@ -1842,39 +2008,63 @@ void UIMachineSettingsStorage::getFromCache()
/* Update actions: */
updateActionsState();
+ /* Polish page finally: */
+ polishPage();
+
/* Revalidate if possible: */
- if (mValidator) mValidator->revalidate();
+ if (mValidator)
+ mValidator->revalidate();
}
/* Save data from corresponding widgets to cache,
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsStorage::putToCache()
{
- /* Gather internal variables data from QWidget(s): */
- m_cache.m_items.clear();
+ /* Prepare storage data: */
+ UIDataSettingsMachineStorage storageData = m_cache.base();
+
+ /* For each storage controller: */
QModelIndex rootIndex = mStorageModel->root();
for (int iControllerIndex = 0; iControllerIndex < mStorageModel->rowCount(rootIndex); ++iControllerIndex)
{
+ /* Prepare storage controller data & key: */
+ UIDataSettingsMachineStorageController controllerData;
+
+ /* Gather storage controller data: */
QModelIndex controllerIndex = mStorageModel->index(iControllerIndex, 0, rootIndex);
- UIStorageControllerData controllerData;
controllerData.m_strControllerName = mStorageModel->data(controllerIndex, StorageModel::R_CtrName).toString();
controllerData.m_controllerBus = mStorageModel->data(controllerIndex, StorageModel::R_CtrBusType).value<KStorageBus>();
controllerData.m_controllerType = mStorageModel->data(controllerIndex, StorageModel::R_CtrType).value<KStorageControllerType>();
+ controllerData.m_uPortCount = mStorageModel->data(controllerIndex, StorageModel::R_CtrPortCount).toUInt();
controllerData.m_fUseHostIOCache = mStorageModel->data(controllerIndex, StorageModel::R_CtrIoCache).toBool();
+
+ /* For each storage attachment: */
for (int iAttachmentIndex = 0; iAttachmentIndex < mStorageModel->rowCount(controllerIndex); ++iAttachmentIndex)
{
+ /* Prepare storage attachment data & key: */
+ UIDataSettingsMachineStorageAttachment attachmentData;
+
+ /* Gather storage controller data: */
QModelIndex attachmentIndex = mStorageModel->index(iAttachmentIndex, 0, controllerIndex);
- UIStorageAttachmentData attachmentData;
attachmentData.m_attachmentType = mStorageModel->data(attachmentIndex, StorageModel::R_AttDevice).value<KDeviceType>();
StorageSlot attachmentSlot = mStorageModel->data(attachmentIndex, StorageModel::R_AttSlot).value<StorageSlot>();
attachmentData.m_iAttachmentPort = attachmentSlot.port;
attachmentData.m_iAttachmentDevice = attachmentSlot.device;
attachmentData.m_fAttachmentPassthrough = mStorageModel->data(attachmentIndex, StorageModel::R_AttIsPassthrough).toBool();
+ attachmentData.m_fAttachmentTempEject = mStorageModel->data(attachmentIndex, StorageModel::R_AttIsTempEject).toBool();
+ attachmentData.m_fAttachmentNonRotational = mStorageModel->data(attachmentIndex, StorageModel::R_AttIsNonRotational).toBool();
attachmentData.m_strAttachmentMediumId = mStorageModel->data(attachmentIndex, StorageModel::R_AttMediumId).toString();
- controllerData.m_items << attachmentData;
+
+ /* Recache storage attachment data: */
+ m_cache.child(iControllerIndex).child(iAttachmentIndex).cacheCurrentData(attachmentData);
}
- m_cache.m_items << controllerData;
+
+ /* Recache storage controller data: */
+ m_cache.child(iControllerIndex).cacheCurrentData(controllerData);
}
+
+ /* Recache storage data: */
+ m_cache.cacheCurrentData(storageData);
}
/* Save data from cache to corresponding external object(s),
@@ -1884,64 +2074,8 @@ void UIMachineSettingsStorage::saveFromCacheTo(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Remove currently present controllers & attachments */
- const CStorageControllerVector &controllers = m_machine.GetStorageControllers();
- for (int iControllerIndex = 0; iControllerIndex < controllers.size(); ++iControllerIndex)
- {
- const CStorageController &controller = controllers[iControllerIndex];
- QString strControllerName(controller.GetName());
- const CMediumAttachmentVector &attachments = m_machine.GetMediumAttachmentsOfController(strControllerName);
- for (int iAttachmentIndex = 0; iAttachmentIndex < attachments.size(); ++iAttachmentIndex)
- {
- const CMediumAttachment &attachment = attachments[iAttachmentIndex];
- m_machine.DetachDevice(strControllerName, attachment.GetPort(), attachment.GetDevice());
- }
- m_machine.RemoveStorageController(strControllerName);
- }
- /* Save created controllers: */
- for (int iControllerIndex = 0; iControllerIndex < m_cache.m_items.size() && !failed(); ++iControllerIndex)
- {
- const UIStorageControllerData &controllerData = m_cache.m_items[iControllerIndex];
- CStorageController controller = m_machine.AddStorageController(controllerData.m_strControllerName, controllerData.m_controllerBus);
- controller.SetControllerType(controllerData.m_controllerType);
- controller.SetUseHostIOCache(controllerData.m_fUseHostIOCache);
- int cMaxUsedPort = -1;
- /* Save created attachments: */
- for (int iAttachmentIndex = 0; iAttachmentIndex < controllerData.m_items.size() && !failed(); ++iAttachmentIndex)
- {
- const UIStorageAttachmentData &attachmentData = controllerData.m_items[iAttachmentIndex];
- VBoxMedium vboxMedium = vboxGlobal().findMedium(attachmentData.m_strAttachmentMediumId);
- CMedium comMedium = vboxMedium.medium();
- m_machine.AttachDevice(controllerData.m_strControllerName,
- attachmentData.m_iAttachmentPort, attachmentData.m_iAttachmentDevice,
- attachmentData.m_attachmentType, comMedium);
- if (m_machine.isOk())
- {
- if (attachmentData.m_attachmentType == KDeviceType_DVD)
- m_machine.PassthroughDevice(controllerData.m_strControllerName,
- attachmentData.m_iAttachmentPort, attachmentData.m_iAttachmentDevice,
- attachmentData.m_fAttachmentPassthrough);
- cMaxUsedPort = attachmentData.m_iAttachmentPort > cMaxUsedPort ? attachmentData.m_iAttachmentPort : cMaxUsedPort;
- }
- else
- {
- /* Mark the page as failed: */
- setFailed(true);
- /* Show error message: */
- vboxProblem().cannotAttachDevice(m_machine, VBoxDefs::MediumType_HardDisk, vboxMedium.location(),
- StorageSlot(controllerData.m_controllerBus,
- attachmentData.m_iAttachmentPort,
- attachmentData.m_iAttachmentDevice), this);
- }
- }
- if (!failed() && controllerData.m_controllerBus == KStorageBus_SATA)
- {
- ULONG uSataPortsCount = cMaxUsedPort + 1;
- uSataPortsCount = qMax(uSataPortsCount, controller.GetMinPortCount());
- uSataPortsCount = qMin(uSataPortsCount, controller.GetMaxPortCount());
- controller.SetPortCount(uSataPortsCount);
- }
- }
+ /* Update storage data, update failing state: */
+ setFailed(!updateStorageData());
/* Upload machine to data: */
UISettingsPageMachine::uploadData(data);
@@ -1952,14 +2086,34 @@ void UIMachineSettingsStorage::setValidator (QIWidgetValidator *aVal)
mValidator = aVal;
}
-bool UIMachineSettingsStorage::revalidate (QString &aWarning, QString &)
+bool UIMachineSettingsStorage::revalidate (QString &strWarning, QString& /* strTitle */)
{
+ /* Check controllers for name emptiness & coincidence.
+ * Check attachments for the hd presence / uniqueness. */
QModelIndex rootIndex = mStorageModel->root();
QMap <QString, QString> config;
+ QMap<int, QString> names;
+ /* For each controller: */
for (int i = 0; i < mStorageModel->rowCount (rootIndex); ++ i)
{
QModelIndex ctrIndex = rootIndex.child (i, 0);
QString ctrName = mStorageModel->data (ctrIndex, StorageModel::R_CtrName).toString();
+ /* Check for name emptiness: */
+ if (ctrName.isEmpty())
+ {
+ strWarning = tr("no name specified for controller at position <b>%1</b>.").arg(i + 1);
+ return false;
+ }
+ /* Check for name coincidence: */
+ if (names.values().contains(ctrName))
+ {
+ strWarning = tr("controller at position <b>%1</b> uses the name that is "
+ "already used by controller at position <b>%2</b>.")
+ .arg(i + 1).arg(names.key(ctrName) + 1);
+ return false;
+ }
+ else names.insert(i, ctrName);
+ /* For each attachment: */
for (int j = 0; j < mStorageModel->rowCount (ctrIndex); ++ j)
{
QModelIndex attIndex = ctrIndex.child (j, 0);
@@ -1970,20 +2124,47 @@ bool UIMachineSettingsStorage::revalidate (QString &aWarning, QString &)
/* Check for emptiness */
if (vboxGlobal().findMedium (key).isNull() && attDevice == KDeviceType_HardDisk)
{
- aWarning = tr ("No hard disk is selected for <i>%1</i>.").arg (value);
- return aWarning.isNull();
+ strWarning = tr ("no hard disk is selected for <i>%1</i>.").arg (value);
+ return false;
}
/* Check for coincidence */
if (!vboxGlobal().findMedium (key).isNull() && config.contains (key))
{
- aWarning = tr ("<i>%1</i> uses a medium that is already attached to <i>%2</i>.")
+ strWarning = tr ("<i>%1</i> uses a medium that is already attached to <i>%2</i>.")
.arg (value).arg (config [key]);
- return aWarning.isNull();
+ return false;
}
else config.insert (key, value);
}
}
- return aWarning.isNull();
+
+ /* Check for excessive controllers on Storage page controllers list: */
+ QStringList excessiveList;
+ QMap<KStorageBus, int> currentType = mStorageModel->currentControllerTypes();
+ QMap<KStorageBus, int> maximumType = mStorageModel->maximumControllerTypes();
+ for (int iStorageBusType = KStorageBus_IDE; iStorageBusType <= KStorageBus_SAS; ++iStorageBusType)
+ {
+ if (currentType[(KStorageBus)iStorageBusType] > maximumType[(KStorageBus)iStorageBusType])
+ {
+ QString strExcessiveRecord = QString("%1 (%2)");
+ strExcessiveRecord = strExcessiveRecord.arg(QString("<b>%1</b>").arg(vboxGlobal().toString((KStorageBus)iStorageBusType)));
+ strExcessiveRecord = strExcessiveRecord.arg(maximumType[(KStorageBus)iStorageBusType] == 1 ?
+ tr("at most one supported", "controller") :
+ tr("up to %1 supported", "controllers").arg(maximumType[(KStorageBus)iStorageBusType]));
+ excessiveList << strExcessiveRecord;
+ }
+ }
+ if (!excessiveList.isEmpty())
+ {
+ strWarning = tr("you are currently using more storage controllers than a %1 chipset supports. "
+ "Please change the chipset type on the System settings page or reduce the number "
+ "of the following storage controllers on the Storage settings page: %2.")
+ .arg(vboxGlobal().toString(mStorageModel->chipsetType()))
+ .arg(excessiveList.join(", "));
+ return false;
+ }
+
+ return true;
}
void UIMachineSettingsStorage::retranslateUi()
@@ -2249,6 +2430,12 @@ void UIMachineSettingsStorage::getInformation()
int ctrPos = mCbType->findText (vboxGlobal().toString (type));
mCbType->setCurrentIndex (ctrPos == -1 ? 0 : ctrPos);
+ KStorageBus bus = mStorageModel->data (index, StorageModel::R_CtrBusType).value <KStorageBus>();
+ mLbPortCount->setVisible (bus == KStorageBus_SATA);
+ mSbPortCount->setVisible (bus == KStorageBus_SATA);
+ uint uPortCount = mStorageModel->data (index, StorageModel::R_CtrPortCount).toUInt();
+ mSbPortCount->setValue (uPortCount);
+
bool isUseIoCache = mStorageModel->data (index, StorageModel::R_CtrIoCache).toBool();
mCbIoCache->setChecked(isUseIoCache);
@@ -2300,12 +2487,22 @@ void UIMachineSettingsStorage::getInformation()
}
m_pMediumIdHolder->setType(vboxGlobal().mediumTypeToLocal(device));
m_pMediumIdHolder->setId(mStorageModel->data(index, StorageModel::R_AttMediumId).toString());
+ mLbMedium->setEnabled(isMachineOffline() || (isMachineOnline() && device != KDeviceType_HardDisk));
+ mTbOpen->setEnabled(isMachineOffline() || (isMachineOnline() && device != KDeviceType_HardDisk));
/* Getting Passthrough state */
bool isHostDrive = mStorageModel->data (index, StorageModel::R_AttIsHostDrive).toBool();
mCbPassthrough->setVisible (device == KDeviceType_DVD && isHostDrive);
mCbPassthrough->setChecked (isHostDrive && mStorageModel->data (index, StorageModel::R_AttIsPassthrough).toBool());
+ /* Getting TempEject state */
+ mCbTempEject->setVisible (device == KDeviceType_DVD && !isHostDrive);
+ mCbTempEject->setChecked (!isHostDrive && mStorageModel->data (index, StorageModel::R_AttIsTempEject).toBool());
+
+ /* Getting NonRotational state */
+ mCbNonRotational->setVisible (device == KDeviceType_HardDisk);
+ mCbNonRotational->setChecked (mStorageModel->data (index, StorageModel::R_AttIsNonRotational).toBool());
+
/* Update optional widgets visibility */
updateAdditionalObjects (device);
@@ -2315,6 +2512,7 @@ void UIMachineSettingsStorage::getInformation()
mLbHDVirtualSizeValue->setText (compressText (mStorageModel->data (index, StorageModel::R_AttLogicalSize).toString()));
mLbHDActualSizeValue->setText (compressText (mStorageModel->data (index, StorageModel::R_AttSize).toString()));
mLbSizeValue->setText (compressText (mStorageModel->data (index, StorageModel::R_AttSize).toString()));
+ mLbHDDetailsValue->setText (compressText (mStorageModel->data (index, StorageModel::R_AttDetails).toString()));
mLbLocationValue->setText (compressText (mStorageModel->data (index, StorageModel::R_AttLocation).toString()));
mLbUsageValue->setText (compressText (mStorageModel->data (index, StorageModel::R_AttUsage).toString()));
@@ -2349,6 +2547,8 @@ void UIMachineSettingsStorage::setInformation()
else if (sdr == mCbType)
mStorageModel->setData (index, QVariant::fromValue (vboxGlobal().toControllerType (mCbType->currentText())),
StorageModel::R_CtrType);
+ else if (sdr == mSbPortCount)
+ mStorageModel->setData (index, mSbPortCount->value(), StorageModel::R_CtrPortCount);
else if (sdr == mCbIoCache)
mStorageModel->setData (index, mCbIoCache->isChecked(), StorageModel::R_CtrIoCache);
break;
@@ -2373,6 +2573,15 @@ void UIMachineSettingsStorage::setInformation()
if (mStorageModel->data (index, StorageModel::R_AttIsHostDrive).toBool())
mStorageModel->setData (index, mCbPassthrough->isChecked(), StorageModel::R_AttIsPassthrough);
}
+ else if (sdr == mCbTempEject)
+ {
+ if (!mStorageModel->data (index, StorageModel::R_AttIsHostDrive).toBool())
+ mStorageModel->setData (index, mCbTempEject->isChecked(), StorageModel::R_AttIsTempEject);
+ }
+ else if (sdr == mCbNonRotational)
+ {
+ mStorageModel->setData (index, mCbNonRotational->isChecked(), StorageModel::R_AttIsNonRotational);
+ }
break;
}
default:
@@ -2462,7 +2671,7 @@ void UIMachineSettingsStorage::sltUnmountDevice()
void UIMachineSettingsStorage::sltChooseExistingMedium()
{
- QString strMachineFolder(QFileInfo(m_machine.GetSettingsFilePath()).absolutePath());
+ QString strMachineFolder(QFileInfo(m_strMachineSettingsFilePath).absolutePath());
QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(m_pMediumIdHolder->type(), this, strMachineFolder);
if (!strMediumId.isNull())
m_pMediumIdHolder->setId(strMediumId);
@@ -2520,8 +2729,8 @@ void UIMachineSettingsStorage::updateActionsState()
mAddCDAttAction->setEnabled (isController && isAttachmentsPossible);
mAddFDAttAction->setEnabled (isController && isAttachmentsPossible);
- mDelCtrAction->setEnabled (isController);
- mDelAttAction->setEnabled (isAttachment);
+ mDelCtrAction->setEnabled (isMachineOffline() && isController);
+ mDelAttAction->setEnabled (isMachineOffline() && isAttachment);
}
void UIMachineSettingsStorage::onRowInserted (const QModelIndex &aParent, int aPosition)
@@ -2812,7 +3021,7 @@ void UIMachineSettingsStorage::addAttachmentWrapper(KDeviceType deviceType)
Assert(mStorageModel->data(index, StorageModel::R_IsController).toBool());
Assert(mStorageModel->data(index, StorageModel::R_IsMoreAttachmentsPossible).toBool());
QString strControllerName(mStorageModel->data(index, StorageModel::R_CtrName).toString());
- QString strMachineFolder(QFileInfo(m_machine.GetSettingsFilePath()).absolutePath());
+ QString strMachineFolder(QFileInfo(m_strMachineSettingsFilePath).absolutePath());
QString strMediumId;
switch (deviceType)
@@ -2858,14 +3067,11 @@ void UIMachineSettingsStorage::addAttachmentWrapper(KDeviceType deviceType)
QString UIMachineSettingsStorage::getWithNewHDWizard()
{
- /* Run New HD Wizard */
- UINewHDWzd dlg(this);
/* Initialize variables: */
- CGuestOSType guestOSType = vboxGlobal().virtualBox().GetGuestOSType(m_machine.GetOSTypeId());
- dlg.setRecommendedSize(guestOSType.GetRecommendedHDD());
- QString strMachineSettingsFilepath = m_machine.GetSettingsFilePath();
- QFileInfo fileInfo(strMachineSettingsFilepath);
- dlg.setDefaultPath(fileInfo.absolutePath());
+ CGuestOSType guestOSType = vboxGlobal().virtualBox().GetGuestOSType(m_strMachineGuestOSTypeId);
+ QFileInfo fileInfo(m_strMachineSettingsFilePath);
+ /* Run New HD Wizard: */
+ UINewHDWizard dlg(this, QString(), fileInfo.absolutePath(), guestOSType.GetRecommendedHDD());
return dlg.exec() == QDialog::Accepted ? dlg.hardDisk().GetId() : QString();
}
@@ -2886,6 +3092,9 @@ void UIMachineSettingsStorage::updateAdditionalObjects (KDeviceType aType)
mLbSize->setVisible (aType != KDeviceType_HardDisk);
mLbSizeValue->setVisible (aType != KDeviceType_HardDisk);
+
+ mLbHDDetails->setVisible (aType == KDeviceType_HardDisk);
+ mLbHDDetailsValue->setVisible (aType == KDeviceType_HardDisk);
}
QString UIMachineSettingsStorage::generateUniqueName (const QString &aTemplate) const
@@ -2984,5 +3193,481 @@ void UIMachineSettingsStorage::addRecentMediumActions(QMenu *pOpenMediumMenu, VB
}
}
+bool UIMachineSettingsStorage::updateStorageData()
+{
+ /* Prepare result: */
+ bool fSuccess = m_machine.isOk();
+ if (fSuccess)
+ {
+ /* Check if storage data was changed: */
+ if (m_cache.wasChanged())
+ {
+ /* For each controller (removing step): */
+ for (int iControllerIndex = 0; iControllerIndex < m_cache.childCount(); ++iControllerIndex)
+ {
+ /* Get controller cache: */
+ const UICacheSettingsMachineStorageController &controllerCache = m_cache.child(iControllerIndex);
+
+ /* Remove controllers marked for 'remove' and 'update' (if they can't be updated): */
+ if (controllerCache.wasRemoved() || (controllerCache.wasUpdated() && !isControllerCouldBeUpdated(controllerCache)))
+ fSuccess = removeStorageController(controllerCache);
+
+ /* Update controllers marked for 'update' (if they can be updated): */
+ if (controllerCache.wasUpdated() && isControllerCouldBeUpdated(controllerCache))
+ {
+ /* For each attachment (removing step): */
+ for (int iAttachmentIndex = 0; iAttachmentIndex < controllerCache.childCount(); ++iAttachmentIndex)
+ {
+ /* Get attachment cache: */
+ const UICacheSettingsMachineStorageAttachment &attachmentCache = controllerCache.child(iAttachmentIndex);
+
+ /* Remove attachments marked for 'remove' and 'update' (if they can't be updated): */
+ if (attachmentCache.wasRemoved() || (attachmentCache.wasUpdated() && !isAttachmentCouldBeUpdated(attachmentCache)))
+ fSuccess = removeStorageAttachment(controllerCache, attachmentCache);
+ }
+ }
+ }
+ /* For each controller (creating step): */
+ for (int iControllerIndex = 0; iControllerIndex < m_cache.childCount(); ++iControllerIndex)
+ {
+ /* Get controller cache: */
+ UICacheSettingsMachineStorageController controllerCache = m_cache.child(iControllerIndex);
+
+ /* Create controllers marked for 'create' or 'update' (if they can't be updated): */
+ if (controllerCache.wasCreated() || (controllerCache.wasUpdated() && !isControllerCouldBeUpdated(controllerCache)))
+ fSuccess = createStorageController(controllerCache);
+
+ /* Update controllers marked for 'update' (if they can be updated): */
+ if (controllerCache.wasUpdated() && isControllerCouldBeUpdated(controllerCache))
+ fSuccess = updateStorageController(controllerCache);
+ }
+ }
+ }
+ /* Return result: */
+ return fSuccess;
+}
+
+bool UIMachineSettingsStorage::removeStorageController(const UICacheSettingsMachineStorageController &controllerCache)
+{
+ /* Prepare result: */
+ bool fSuccess = m_machine.isOk();
+ if (fSuccess)
+ {
+ /* Get storage controller data form cache: */
+ const UIDataSettingsMachineStorageController &controllerData = controllerCache.base();
+
+ /* Get storage controller name: */
+ QString strControllerName = controllerData.m_strControllerName;
+
+ /* Check that storage controller exists: */
+ const CStorageController &controller = m_machine.GetStorageControllerByName(strControllerName);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ if (fSuccess && !controller.isNull())
+ {
+ /* Remove storage attachments first: */
+ // TODO: Later, it will be possible to remove controller with all the attachments at one shot!
+ /* For each storage attachment: */
+ for (int iAttachmentIndex = 0; fSuccess && iAttachmentIndex < controllerCache.childCount(); ++iAttachmentIndex)
+ fSuccess = removeStorageAttachment(controllerCache, controllerCache.child(iAttachmentIndex));
+ /* Remove storage controller finally: */
+ if (fSuccess)
+ {
+ m_machine.RemoveStorageController(strControllerName);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ }
+ }
+ }
+ /* Return result: */
+ return fSuccess;
+}
+
+bool UIMachineSettingsStorage::createStorageController(const UICacheSettingsMachineStorageController &controllerCache)
+{
+ /* Prepare result: */
+ bool fSuccess = m_machine.isOk();
+ if (fSuccess)
+ {
+ /* Get controller data form cache: */
+ const UIDataSettingsMachineStorageController &controllerData = controllerCache.data();
+
+ /* Get storage controller attributes: */
+ QString strControllerName = controllerData.m_strControllerName;
+ KStorageBus controllerBus = controllerData.m_controllerBus;
+ KStorageControllerType controllerType = controllerData.m_controllerType;
+ ULONG uPortCount = controllerData.m_uPortCount;
+ bool fUseHostIOCache = controllerData.m_fUseHostIOCache;
+
+ /* Check that storage controller doesn't exists: */
+ CStorageController controller = m_machine.GetStorageControllerByName(strControllerName);
+ /* Check that machine is not OK: */
+ fSuccess = !m_machine.isOk();
+ /* If controller doesn't exists: */
+ if (controller.isNull())
+ {
+ /* Create new storage controller: */
+ controller = m_machine.AddStorageController(strControllerName, controllerBus);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ if (!controller.isNull())
+ {
+ /* Set storage controller attributes: */
+ controller.SetControllerType(controllerType);
+ controller.SetUseHostIOCache(fUseHostIOCache);
+ if (controllerData.m_controllerBus == KStorageBus_SATA)
+ {
+ uPortCount = qMax(uPortCount, controller.GetMinPortCount());
+ uPortCount = qMin(uPortCount, controller.GetMaxPortCount());
+ controller.SetPortCount(uPortCount);
+ }
+
+ /* For each storage attachment: */
+ for (int iAttachmentIndex = 0; fSuccess && iAttachmentIndex < controllerCache.childCount(); ++iAttachmentIndex)
+ {
+ /* Get storage attachment cache: */
+ const UICacheSettingsMachineStorageAttachment &attachmentCache = controllerCache.child(iAttachmentIndex);
+
+ /* If storage attachment data was not removed: */
+ if (!attachmentCache.wasRemoved())
+ fSuccess = createStorageAttachment(controllerCache, attachmentCache);
+ }
+ }
+ }
+ }
+ /* Return result: */
+ return fSuccess;
+}
+
+bool UIMachineSettingsStorage::updateStorageController(const UICacheSettingsMachineStorageController &controllerCache)
+{
+ /* Prepare result: */
+ bool fSuccess = m_machine.isOk();
+ if (fSuccess)
+ {
+ /* Get controller data form cache: */
+ const UIDataSettingsMachineStorageController &controllerData = controllerCache.data();
+
+ /* Get storage controller attributes: */
+ QString strControllerName = controllerData.m_strControllerName;
+ KStorageBus controllerBus = controllerData.m_controllerBus;
+ KStorageControllerType controllerType = controllerData.m_controllerType;
+ ULONG uPortCount = controllerData.m_uPortCount;
+ bool fUseHostIOCache = controllerData.m_fUseHostIOCache;
+
+ /* Check that controller exists: */
+ CStorageController controller = m_machine.GetStorageControllerByName(strControllerName);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ if (!controller.isNull())
+ {
+ /* Set storage controller attributes: */
+ controller.SetControllerType(controllerType);
+ controller.SetUseHostIOCache(fUseHostIOCache);
+ if (controllerData.m_controllerBus == KStorageBus_SATA)
+ {
+ uPortCount = qMax(uPortCount, controller.GetMinPortCount());
+ uPortCount = qMin(uPortCount, controller.GetMaxPortCount());
+ controller.SetPortCount(uPortCount);
+ }
+
+ /* For each storage attachment: */
+ for (int iAttachmentIndex = 0; fSuccess && iAttachmentIndex < controllerCache.childCount(); ++iAttachmentIndex)
+ {
+ /* Get storage attachment cache: */
+ const UICacheSettingsMachineStorageAttachment &attachmentCache = controllerCache.child(iAttachmentIndex);
+
+ /* Create attachments marked for 'create' and 'update' (if they can't be updated): */
+ if (attachmentCache.wasCreated() || (attachmentCache.wasUpdated() && !isAttachmentCouldBeUpdated(attachmentCache)))
+ fSuccess = createStorageAttachment(controllerCache, attachmentCache);
+
+ /* Update attachments marked for 'update' (if they can be updated): */
+ if (attachmentCache.wasUpdated() && isAttachmentCouldBeUpdated(attachmentCache))
+ fSuccess = updateStorageAttachment(controllerCache, attachmentCache);
+ }
+ }
+ }
+ /* Return result: */
+ return fSuccess;
+}
+
+bool UIMachineSettingsStorage::removeStorageAttachment(const UICacheSettingsMachineStorageController &controllerCache,
+ const UICacheSettingsMachineStorageAttachment &attachmentCache)
+{
+ /* Prepare result: */
+ bool fSuccess = m_machine.isOk();
+ if (fSuccess)
+ {
+ /* Get storage controller data from cache: */
+ const UIDataSettingsMachineStorageController &controllerData = controllerCache.base();
+ /* Get storage attachment data from cache: */
+ const UIDataSettingsMachineStorageAttachment &attachmentData = attachmentCache.base();
+
+ /* Get storage controller attributes: */
+ QString strControllerName = controllerData.m_strControllerName;
+ /* Get storage attachment attributes: */
+ int iAttachmentPort = attachmentData.m_iAttachmentPort;
+ int iAttachmentDevice = attachmentData.m_iAttachmentDevice;
+
+ /* Check that storage attachment exists: */
+ const CMediumAttachment &attachment = m_machine.GetMediumAttachment(strControllerName, iAttachmentPort, iAttachmentDevice);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ if (fSuccess && !attachment.isNull())
+ {
+ /* Remove storage attachment: */
+ m_machine.DetachDevice(strControllerName, iAttachmentPort, iAttachmentDevice);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ }
+ }
+ /* Return result: */
+ return fSuccess;
+}
+
+bool UIMachineSettingsStorage::createStorageAttachment(const UICacheSettingsMachineStorageController &controllerCache,
+ const UICacheSettingsMachineStorageAttachment &attachmentCache)
+{
+ /* Prepare result: */
+ bool fSuccess = m_machine.isOk();
+ if (fSuccess)
+ {
+ /* Get storage controller data from cache: */
+ const UIDataSettingsMachineStorageController &controllerData = controllerCache.data();
+ /* Get storage attachment data from cache: */
+ const UIDataSettingsMachineStorageAttachment &attachmentData = attachmentCache.data();
+
+ /* Get storage controller attributes: */
+ QString strControllerName = controllerData.m_strControllerName;
+ KStorageBus controllerBus = controllerData.m_controllerBus;
+ /* Get storage attachment attributes: */
+ int iAttachmentPort = attachmentData.m_iAttachmentPort;
+ int iAttachmentDevice = attachmentData.m_iAttachmentDevice;
+ KDeviceType attachmentDeviceType = attachmentData.m_attachmentType;
+ QString strAttachmentMediumId = attachmentData.m_strAttachmentMediumId;
+ bool fAttachmentPassthrough = attachmentData.m_fAttachmentPassthrough;
+ bool fAttachmentTempEject = attachmentData.m_fAttachmentTempEject;
+ bool fAttachmentNonRotational = attachmentData.m_fAttachmentNonRotational;
+ /* Get GUI medium object: */
+ VBoxMedium vboxMedium = vboxGlobal().findMedium(strAttachmentMediumId);
+ /* Get COM medium object: */
+ CMedium comMedium = vboxMedium.medium();
+
+ /* Check that storage attachment doesn't exists: */
+ const CMediumAttachment &attachment = m_machine.GetMediumAttachment(strControllerName, iAttachmentPort, iAttachmentDevice);
+ /* Check that machine is not OK: */
+ fSuccess = !m_machine.isOk();
+ if (attachment.isNull())
+ {
+ /* Create storage attachment: */
+ m_machine.AttachDevice(strControllerName, iAttachmentPort, iAttachmentDevice, attachmentDeviceType, comMedium);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ if (fSuccess)
+ {
+ if (attachmentDeviceType == KDeviceType_DVD)
+ {
+ m_machine.PassthroughDevice(strControllerName, iAttachmentPort, iAttachmentDevice, fAttachmentPassthrough);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ if (fSuccess)
+ {
+ m_machine.TemporaryEjectDevice(strControllerName, iAttachmentPort, iAttachmentDevice, fAttachmentTempEject);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ }
+ }
+ else if (attachmentDeviceType == KDeviceType_HardDisk)
+ {
+ m_machine.NonRotationalDevice(strControllerName, iAttachmentPort, iAttachmentDevice, fAttachmentNonRotational);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ }
+ }
+ else
+ {
+ /* Show error message: */
+ vboxProblem().cannotAttachDevice(m_machine, vboxGlobal().mediumTypeToLocal(attachmentDeviceType),
+ vboxMedium.location(),
+ StorageSlot(controllerBus, iAttachmentPort, iAttachmentDevice), this);
+ }
+ }
+ }
+ /* Return result: */
+ return fSuccess;
+}
+
+bool UIMachineSettingsStorage::updateStorageAttachment(const UICacheSettingsMachineStorageController &controllerCache,
+ const UICacheSettingsMachineStorageAttachment &attachmentCache)
+{
+ /* Prepare result: */
+ bool fSuccess = m_machine.isOk();
+ if (fSuccess)
+ {
+ /* Get storage controller data from cache: */
+ const UIDataSettingsMachineStorageController &controllerData = controllerCache.data();
+ /* Get current storage attachment data from cache: */
+ const UIDataSettingsMachineStorageAttachment &attachmentData = attachmentCache.data();
+
+ /* Get storage controller attributes: */
+ QString strControllerName = controllerData.m_strControllerName;
+ KStorageBus controllerBus = controllerData.m_controllerBus;
+ /* Get storage attachment attributes: */
+ int iAttachmentPort = attachmentData.m_iAttachmentPort;
+ int iAttachmentDevice = attachmentData.m_iAttachmentDevice;
+ QString strAttachmentMediumId = attachmentData.m_strAttachmentMediumId;
+ bool fAttachmentPassthrough = attachmentData.m_fAttachmentPassthrough;
+ bool fAttachmentTempEject = attachmentData.m_fAttachmentTempEject;
+ bool fAttachmentNonRotational = attachmentData.m_fAttachmentNonRotational;
+ KDeviceType attachmentDeviceType = attachmentData.m_attachmentType;
+
+ /* Check that storage attachment exists: */
+ CMediumAttachment attachment = m_machine.GetMediumAttachment(strControllerName, iAttachmentPort, iAttachmentDevice);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ if (!attachment.isNull())
+ {
+ /* Get GUI medium object: */
+ VBoxMedium vboxMedium = vboxGlobal().findMedium(strAttachmentMediumId);
+ /* Get COM medium object: */
+ CMedium comMedium = vboxMedium.medium();
+ /* Remount storage attachment: */
+ m_machine.MountMedium(strControllerName, iAttachmentPort, iAttachmentDevice, comMedium, true /* force? */);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ if (fSuccess)
+ {
+ if (isMachineOffline())
+ {
+ if (attachmentDeviceType == KDeviceType_DVD)
+ {
+ m_machine.PassthroughDevice(strControllerName, iAttachmentPort, iAttachmentDevice, fAttachmentPassthrough);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ }
+ }
+ if (fSuccess)
+ {
+ if (attachmentDeviceType == KDeviceType_DVD)
+ {
+ m_machine.TemporaryEjectDevice(strControllerName, iAttachmentPort, iAttachmentDevice, fAttachmentTempEject);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ }
+ }
+ if (fSuccess)
+ {
+ if (attachmentDeviceType == KDeviceType_HardDisk)
+ {
+ m_machine.NonRotationalDevice(strControllerName, iAttachmentPort, iAttachmentDevice, fAttachmentNonRotational);
+ /* Check that machine is OK: */
+ fSuccess = m_machine.isOk();
+ }
+ }
+ }
+ else
+ {
+ /* Show error message: */
+ vboxProblem().cannotAttachDevice(m_machine, vboxGlobal().mediumTypeToLocal(attachmentDeviceType),
+ vboxMedium.location(),
+ StorageSlot(controllerBus, iAttachmentPort, iAttachmentDevice), this);
+ }
+ }
+ }
+ /* Return result: */
+ return fSuccess;
+}
+
+bool UIMachineSettingsStorage::isControllerCouldBeUpdated(const UICacheSettingsMachineStorageController &controllerCache) const
+{
+ /* IController interface doesn't allows to change 'name' and 'bus' attributes.
+ * But those attributes could be changed in GUI directly or indirectly.
+ * For such cases we have to recreate IController instance,
+ * for other cases we will update controller attributes only. */
+ const UIDataSettingsMachineStorageController &oldControllerData = controllerCache.base();
+ const UIDataSettingsMachineStorageController &newControllerData = controllerCache.data();
+ return newControllerData.m_controllerBus == oldControllerData.m_controllerBus &&
+ newControllerData.m_strControllerName == oldControllerData.m_strControllerName;
+}
+
+bool UIMachineSettingsStorage::isAttachmentCouldBeUpdated(const UICacheSettingsMachineStorageAttachment &attachmentCache) const
+{
+ /* IMediumAttachment could be indirectly updated through IMachine
+ * only if attachment type, device and port were NOT changed and is one of the next types:
+ * KDeviceType_Floppy or KDeviceType_DVD.
+ * For other cases we will recreate attachment fully: */
+ const UIDataSettingsMachineStorageAttachment &initialAttachmentData = attachmentCache.base();
+ const UIDataSettingsMachineStorageAttachment &currentAttachmentData = attachmentCache.data();
+ KDeviceType initialAttachmentDeviceType = initialAttachmentData.m_attachmentType;
+ KDeviceType currentAttachmentDeviceType = currentAttachmentData.m_attachmentType;
+ LONG iInitialAttachmentDevice = initialAttachmentData.m_iAttachmentDevice;
+ LONG iCurrentAttachmentDevice = currentAttachmentData.m_iAttachmentDevice;
+ LONG iInitialAttachmentPort = initialAttachmentData.m_iAttachmentPort;
+ LONG iCurrentAttachmentPort = currentAttachmentData.m_iAttachmentPort;
+ return (currentAttachmentDeviceType == initialAttachmentDeviceType) &&
+ (iCurrentAttachmentDevice == iInitialAttachmentDevice) &&
+ (iCurrentAttachmentPort == iInitialAttachmentPort) &&
+ (currentAttachmentDeviceType == KDeviceType_Floppy || currentAttachmentDeviceType == KDeviceType_DVD);
+}
+
+void UIMachineSettingsStorage::setDialogType(SettingsDialogType settingsDialogType)
+{
+ /* Update model 'settings dialog type': */
+ mStorageModel->setDialogType(settingsDialogType);
+ /* Update 'settings dialog type' of base class: */
+ UISettingsPageMachine::setDialogType(settingsDialogType);
+}
+
+void UIMachineSettingsStorage::polishPage()
+{
+ /* Declare required variables: */
+ QModelIndex index = mTwStorageTree->currentIndex();
+ KDeviceType device = mStorageModel->data(index, StorageModel::R_AttDevice).value<KDeviceType>();
+
+ /* Left pane: */
+ mLsLeftPane->setEnabled(isMachineInValidMode());
+ mTwStorageTree->setEnabled(isMachineInValidMode());
+ /* Empty information pane: */
+ mLsEmpty->setEnabled(isMachineInValidMode());
+ mLbInfo->setEnabled(isMachineInValidMode());
+ /* Controllers pane: */
+ mLsParameters->setEnabled(isMachineInValidMode());
+ mLbName->setEnabled(isMachineOffline());
+ mLeName->setEnabled(isMachineOffline());
+ mLbType->setEnabled(isMachineOffline());
+ mCbType->setEnabled(isMachineOffline());
+ mLbPortCount->setEnabled(isMachineOffline());
+ mSbPortCount->setEnabled(isMachineOffline());
+ mCbIoCache->setEnabled(isMachineOffline());
+ /* Attachments pane: */
+ mLsAttributes->setEnabled(isMachineInValidMode());
+ mLbMedium->setEnabled(isMachineOffline() || (isMachineOnline() && device != KDeviceType_HardDisk));
+ mCbSlot->setEnabled(isMachineOffline());
+ mTbOpen->setEnabled(isMachineOffline() || (isMachineOnline() && device != KDeviceType_HardDisk));
+ mCbPassthrough->setEnabled(isMachineOffline());
+ mCbTempEject->setEnabled(isMachineInValidMode());
+ mCbNonRotational->setEnabled(isMachineOffline());
+ mLsInformation->setEnabled(isMachineInValidMode());
+ mLbHDFormat->setEnabled(isMachineInValidMode());
+ mLbHDFormatValue->setEnabled(isMachineInValidMode());
+ mLbCDFDType->setEnabled(isMachineInValidMode());
+ mLbCDFDTypeValue->setEnabled(isMachineInValidMode());
+ mLbHDVirtualSize->setEnabled(isMachineInValidMode());
+ mLbHDVirtualSizeValue->setEnabled(isMachineInValidMode());
+ mLbHDActualSize->setEnabled(isMachineInValidMode());
+ mLbHDActualSizeValue->setEnabled(isMachineInValidMode());
+ mLbSize->setEnabled(isMachineInValidMode());
+ mLbSizeValue->setEnabled(isMachineInValidMode());
+ mLbHDDetails->setEnabled(isMachineInValidMode());
+ mLbHDDetailsValue->setEnabled(isMachineInValidMode());
+ mLbLocation->setEnabled(isMachineInValidMode());
+ mLbLocationValue->setEnabled(isMachineInValidMode());
+ mLbUsage->setEnabled(isMachineInValidMode());
+ mLbUsageValue->setEnabled(isMachineInValidMode());
+
+ /* Update action states: */
+ updateActionsState();
+}
+
#include "UIMachineSettingsStorage.moc"
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.h b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.h
index 730a630d0..dda3cb430 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.h
@@ -5,7 +5,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;
@@ -310,10 +310,12 @@ public:
QString ctrName() const;
KStorageControllerType ctrType() const;
ControllerTypeList ctrTypes() const;
+ uint portCount();
bool ctrUseIoCache() const;
void setCtrName (const QString &aCtrName);
void setCtrType (KStorageControllerType aCtrType);
+ void setPortCount (uint aPortCount);
void setCtrUseIoCache (bool aUseIoCache);
SlotsList ctrAllSlots() const;
@@ -337,6 +339,7 @@ private:
QString mCtrName;
AbstractControllerType *mCtrType;
+ uint mPortCount;
bool mUseIoCache;
QList <AbstractItem*> mAttachments;
};
@@ -355,16 +358,21 @@ public:
QString attMediumId() const;
bool attIsHostDrive() const;
bool attIsPassthrough() const;
+ bool attIsTempEject() const;
+ bool attIsNonRotational() const;
void setAttSlot (const StorageSlot &aAttSlot);
void setAttDevice (KDeviceType aAttDeviceType);
void setAttMediumId (const QString &aAttMediumId);
void setAttIsPassthrough (bool aPassthrough);
+ void setAttIsTempEject (bool aTempEject);
+ void setAttIsNonRotational (bool aNonRotational);
QString attSize() const;
QString attLogicalSize() const;
QString attLocation() const;
QString attFormat() const;
+ QString attDetails() const;
QString attUsage() const;
private:
@@ -389,6 +397,8 @@ private:
bool mAttIsShowDiffs;
bool mAttIsHostDrive;
bool mAttIsPassthrough;
+ bool mAttIsTempEject;
+ bool mAttIsNonRotational;
QString mAttName;
QString mAttTip;
@@ -398,6 +408,7 @@ private:
QString mAttLogicalSize;
QString mAttLocation;
QString mAttFormat;
+ QString mAttDetails;
QString mAttUsage;
};
@@ -432,6 +443,7 @@ public:
R_CtrTypes,
R_CtrDevices,
R_CtrBusType,
+ R_CtrPortCount,
R_CtrIoCache,
R_AttSlot,
@@ -441,10 +453,13 @@ public:
R_AttIsShowDiffs,
R_AttIsHostDrive,
R_AttIsPassthrough,
+ R_AttIsTempEject,
+ R_AttIsNonRotational,
R_AttSize,
R_AttLogicalSize,
R_AttLocation,
R_AttFormat,
+ R_AttDetails,
R_AttUsage,
R_Margin,
@@ -502,6 +517,10 @@ public:
KChipsetType chipsetType() const;
void setChipsetType(KChipsetType type);
+ void setDialogType(SettingsDialogType settingsDialogType);
+
+ void clear();
+
QMap<KStorageBus, int> currentControllerTypes() const;
QMap<KStorageBus, int> maximumControllerTypes() const;
@@ -520,6 +539,7 @@ private:
ToolTipType mToolTipType;
KChipsetType m_chipsetType;
+ SettingsDialogType m_dialogType;
};
Q_DECLARE_METATYPE (StorageModel::ToolTipType);
@@ -539,32 +559,84 @@ private:
bool mDisableStaticControls;
};
-/* Machine settings / Storage page / Attachment data: */
-struct UIStorageAttachmentData
+/* Machine settings / Storage page / Storage attachment data: */
+struct UIDataSettingsMachineStorageAttachment
{
+ /* Default constructor: */
+ UIDataSettingsMachineStorageAttachment()
+ : m_attachmentType(KDeviceType_Null)
+ , m_iAttachmentPort(-1)
+ , m_iAttachmentDevice(-1)
+ , m_strAttachmentMediumId(QString())
+ , m_fAttachmentPassthrough(false)
+ , m_fAttachmentTempEject(false)
+ , m_fAttachmentNonRotational(false) {}
+ /* Functions: */
+ bool equal(const UIDataSettingsMachineStorageAttachment &other) const
+ {
+ return (m_attachmentType == other.m_attachmentType) &&
+ (m_iAttachmentPort == other.m_iAttachmentPort) &&
+ (m_iAttachmentDevice == other.m_iAttachmentDevice) &&
+ (m_strAttachmentMediumId == other.m_strAttachmentMediumId) &&
+ (m_fAttachmentPassthrough == other.m_fAttachmentPassthrough) &&
+ (m_fAttachmentTempEject == other.m_fAttachmentTempEject) &&
+ (m_fAttachmentNonRotational == other.m_fAttachmentNonRotational);
+ }
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineStorageAttachment &other) const { return equal(other); }
+ bool operator!=(const UIDataSettingsMachineStorageAttachment &other) const { return !equal(other); }
+ /* Variables: */
KDeviceType m_attachmentType;
LONG m_iAttachmentPort;
LONG m_iAttachmentDevice;
QString m_strAttachmentMediumId;
bool m_fAttachmentPassthrough;
+ bool m_fAttachmentTempEject;
+ bool m_fAttachmentNonRotational;
};
+typedef UISettingsCache<UIDataSettingsMachineStorageAttachment> UICacheSettingsMachineStorageAttachment;
-/* Machine settings / Storage page / Controller data: */
-struct UIStorageControllerData
+/* Machine settings / Storage page / Storage controller data: */
+struct UIDataSettingsMachineStorageController
{
+ /* Default constructor: */
+ UIDataSettingsMachineStorageController()
+ : m_strControllerName(QString())
+ , m_controllerBus(KStorageBus_Null)
+ , m_controllerType(KStorageControllerType_Null)
+ , m_uPortCount(0)
+ , m_fUseHostIOCache(false) {}
+ /* Functions: */
+ bool equal(const UIDataSettingsMachineStorageController &other) const
+ {
+ return (m_strControllerName == other.m_strControllerName) &&
+ (m_controllerBus == other.m_controllerBus) &&
+ (m_controllerType == other.m_controllerType) &&
+ (m_uPortCount == other.m_uPortCount) &&
+ (m_fUseHostIOCache == other.m_fUseHostIOCache);
+ }
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineStorageController &other) const { return equal(other); }
+ bool operator!=(const UIDataSettingsMachineStorageController &other) const { return !equal(other); }
+ /* Variables: */
QString m_strControllerName;
KStorageBus m_controllerBus;
KStorageControllerType m_controllerType;
+ uint m_uPortCount;
bool m_fUseHostIOCache;
- QList<UIStorageAttachmentData> m_items;
};
+typedef UISettingsCachePool<UIDataSettingsMachineStorageController, UICacheSettingsMachineStorageAttachment> UICacheSettingsMachineStorageController;
-/* Machine settings / Storage page / Cache: */
-struct UISettingsCacheMachineStorage
+/* Machine settings / Storage page / Storage data: */
+struct UIDataSettingsMachineStorage
{
- QString m_strMachineId;
- QList<UIStorageControllerData> m_items;
+ /* Default constructor: */
+ UIDataSettingsMachineStorage() {}
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineStorage& /* other */) const { return true; }
+ bool operator!=(const UIDataSettingsMachineStorage& /* other */) const { return false; }
};
+typedef UISettingsCachePool<UIDataSettingsMachineStorage, UICacheSettingsMachineStorageController> UICacheSettingsMachineStorage;
/* Machine settings / Storage page: */
class UIMachineSettingsStorage : public UISettingsPageMachine,
@@ -576,12 +648,8 @@ public:
UIMachineSettingsStorage();
- KChipsetType chipsetType() const;
void setChipsetType(KChipsetType type);
- QMap<KStorageBus, int> currentControllerTypes() const;
- QMap<KStorageBus, int> maximumControllerTypes() const;
-
signals:
void storageChanged();
@@ -602,6 +670,9 @@ protected:
* this task COULD be performed in other than GUI thread: */
void saveFromCacheTo(QVariant &data);
+ /* Page changed: */
+ bool changed() const { return m_cache.wasChanged(); }
+
void setValidator (QIWidgetValidator *aVal);
bool revalidate (QString &aWarning, QString &aTitle);
@@ -669,8 +740,28 @@ private:
void addChooseHostDriveActions(QMenu *pOpenMediumMenu);
void addRecentMediumActions(QMenu *pOpenMediumMenu, VBoxDefs::MediumType recentMediumType);
+ bool updateStorageData();
+ bool removeStorageController(const UICacheSettingsMachineStorageController &controllerCache);
+ bool createStorageController(const UICacheSettingsMachineStorageController &controllerCache);
+ bool updateStorageController(const UICacheSettingsMachineStorageController &controllerCache);
+ bool removeStorageAttachment(const UICacheSettingsMachineStorageController &controllerCache,
+ const UICacheSettingsMachineStorageAttachment &attachmentCache);
+ bool createStorageAttachment(const UICacheSettingsMachineStorageController &controllerCache,
+ const UICacheSettingsMachineStorageAttachment &attachmentCache);
+ bool updateStorageAttachment(const UICacheSettingsMachineStorageController &controllerCache,
+ const UICacheSettingsMachineStorageAttachment &attachmentCache);
+ bool isControllerCouldBeUpdated(const UICacheSettingsMachineStorageController &controllerCache) const;
+ bool isAttachmentCouldBeUpdated(const UICacheSettingsMachineStorageAttachment &attachmentCache) const;
+
+ void setDialogType(SettingsDialogType settingsDialogType);
+ void polishPage();
+
QIWidgetValidator *mValidator;
+ QString m_strMachineId;
+ QString m_strMachineSettingsFilePath;
+ QString m_strMachineGuestOSTypeId;
+
StorageModel *mStorageModel;
QAction *mAddCtrAction;
@@ -693,7 +784,7 @@ private:
bool mDisableStaticControls;
/* Cache: */
- UISettingsCacheMachineStorage m_cache;
+ UICacheSettingsMachineStorage m_cache;
};
#endif // __UIMachineSettingsStorage_h__
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.ui b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.ui
index 06c1c0ef7..c7413f535 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.ui
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.ui
@@ -208,7 +208,33 @@
</property>
</widget>
</item>
+ <item row="3" column="1" >
+ <widget class="QLabel" name="mLbPortCount" >
+ <property name="text" >
+ <string>&amp;Port Count:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>mSbPortCount</cstring>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
<item row="3" column="2" >
+ <widget class="QSpinBox" name="mSbPortCount" >
+ <property name="whatsThis" >
+ <string>Selects the port count of the SATA storage controller currently selected in the Storage Tree. This value can't be less than the maximum used port number + 1.</string>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2" >
<widget class="QCheckBox" name="mCbIoCache" >
<property name="whatsThis" >
<string>Allows to use host I/O caching capabilities.</string>
@@ -218,7 +244,7 @@
</property>
</widget>
</item>
- <item row="4" column="0" colspan="3" >
+ <item row="5" column="0" colspan="3" >
<spacer name="mSp3" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
@@ -322,6 +348,38 @@
</property>
</widget>
</item>
+ <item row="2" column="2" >
+ <widget class="QCheckBox" name="mCbTempEject" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" >
+ <string>When checked, it suppresses unmounting the medium when the guest OS ejects it.</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Live CD/DVD</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QCheckBox" name="mCbNonRotational" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" >
+ <string>When checked, this marks the medium as non-rotational storage (SSD).</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Solid-state drive</string>
+ </property>
+ </widget>
+ </item>
<item row="3" column="0" colspan="3" >
<widget class="QILabelSeparator" native="1" name="mLsInformation" >
<property name="text" >
@@ -430,6 +488,26 @@
</widget>
</item>
<item row="9" column="1" >
+ <widget class="QLabel" name="mLbHDDetails" >
+ <property name="text" >
+ <string>Details:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="2" >
+ <widget class="QILabel" name="mLbHDDetailsValue" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="1" >
<widget class="QLabel" name="mLbLocation" >
<property name="text" >
<string>Location:</string>
@@ -439,7 +517,7 @@
</property>
</widget>
</item>
- <item row="9" column="2" >
+ <item row="10" column="2" >
<widget class="QILabel" name="mLbLocationValue" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
@@ -449,7 +527,7 @@
</property>
</widget>
</item>
- <item row="10" column="1" >
+ <item row="11" column="1" >
<widget class="QLabel" name="mLbUsage" >
<property name="text" >
<string>Attached To:</string>
@@ -459,7 +537,7 @@
</property>
</widget>
</item>
- <item row="10" column="2" >
+ <item row="11" column="2" >
<widget class="QILabel" name="mLbUsageValue" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
@@ -469,7 +547,7 @@
</property>
</widget>
</item>
- <item row="11" column="0" colspan="3" >
+ <item row="12" column="0" colspan="3" >
<spacer name="mSp6" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.cpp
index fdedbca11..2918d647b 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsSystem.cpp $ */
+/* $Id: UIMachineSettingsSystem.cpp 37753 2011-07-04 10:09:18Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -30,6 +30,8 @@
UIMachineSettingsSystem::UIMachineSettingsSystem()
: mValidator(0)
, mMinGuestCPU(0), mMaxGuestCPU(0)
+ , mMinGuestCPUExecCap(0), mMedGuestCPUExecCap(0), mMaxGuestCPUExecCap(0)
+ , m_fOHCIEnabled(false)
{
/* Apply UI decorations */
Ui::UIMachineSettingsSystem::setupUi (this);
@@ -39,6 +41,9 @@ UIMachineSettingsSystem::UIMachineSettingsSystem()
uint hostCPUs = vboxGlobal().virtualBox().GetHost().GetProcessorCount();
mMinGuestCPU = properties.GetMinGuestCPUCount();
mMaxGuestCPU = RT_MIN (2 * hostCPUs, properties.GetMaxGuestCPUCount());
+ mMinGuestCPUExecCap = 1;
+ mMedGuestCPUExecCap = 40;
+ mMaxGuestCPUExecCap = 100;
/* Populate possible boot items list.
* Currently, it seems, we are supporting only 4 possible boot device types:
@@ -82,6 +87,7 @@ UIMachineSettingsSystem::UIMachineSettingsSystem()
/* Setup validators */
mLeMemory->setValidator (new QIntValidator (mSlMemory->minRAM(), mSlMemory->maxRAM(), this));
mLeCPU->setValidator (new QIntValidator (mMinGuestCPU, mMaxGuestCPU, this));
+ mLeCPUExecCap->setValidator(new QIntValidator(mMinGuestCPUExecCap, mMaxGuestCPUExecCap, this));
/* Setup connections */
connect (mSlMemory, SIGNAL (valueChanged (int)),
@@ -101,6 +107,9 @@ UIMachineSettingsSystem::UIMachineSettingsSystem()
connect (mLeCPU, SIGNAL (textChanged (const QString&)),
this, SLOT (textChangedCPU (const QString&)));
+ connect(mSlCPUExecCap, SIGNAL(valueChanged(int)), this, SLOT(sltValueChangedCPUExecCap(int)));
+ connect(mLeCPUExecCap, SIGNAL(textChanged(const QString&)), this, SLOT(sltTextChangedCPUExecCap(const QString&)));
+
/* Setup iconsets */
mTbBootItemUp->setIcon(UIIconPool::iconSet(":/list_moveup_16px.png",
":/list_moveup_disabled_16px.png"));
@@ -128,9 +137,24 @@ UIMachineSettingsSystem::UIMachineSettingsSystem()
mSlCPU->setOptimalHint (1, hostCPUs);
mSlCPU->setWarningHint (hostCPUs, mMaxGuestCPU);
/* Limit min/max. size of QLineEdit */
- mLeCPU->setFixedWidthByText (QString().fill ('8', 3));
+ mLeCPU->setFixedWidthByText(QString().fill('8', 4));
/* Ensure mLeMemory value and validation is updated */
valueChangedCPU (mSlCPU->value());
+
+ /* Setup cpu cap slider: */
+ mSlCPUExecCap->setPageStep(10);
+ mSlCPUExecCap->setSingleStep(1);
+ mSlCPUExecCap->setTickInterval(10);
+ /* Setup the scale so that ticks are at page step boundaries: */
+ mSlCPUExecCap->setMinimum(mMinGuestCPUExecCap);
+ mSlCPUExecCap->setMaximum(mMaxGuestCPUExecCap);
+ mSlCPUExecCap->setWarningHint(mMinGuestCPUExecCap, mMedGuestCPUExecCap);
+ mSlCPUExecCap->setOptimalHint(mMedGuestCPUExecCap, mMaxGuestCPUExecCap);
+ /* Limit min/max. size of QLineEdit: */
+ mLeCPUExecCap->setFixedWidthByText(QString().fill('8', 4));
+ /* Ensure mLeMemory value and validation is updated: */
+ sltValueChangedCPUExecCap(mSlCPUExecCap->value());
+
/* Populate chipset combo: */
mCbChipset->insertItem(0, vboxGlobal().toString(KChipsetType_PIIX3), QVariant(KChipsetType_PIIX3));
mCbChipset->insertItem(1, vboxGlobal().toString(KChipsetType_ICH9), QVariant(KChipsetType_ICH9));
@@ -147,11 +171,6 @@ bool UIMachineSettingsSystem::isHWVirtExEnabled() const
return mCbVirt->isChecked();
}
-int UIMachineSettingsSystem::cpuCount() const
-{
- return mSlCPU->value();
-}
-
bool UIMachineSettingsSystem::isHIDEnabled() const
{
return mCbUseAbsHID->isChecked();
@@ -162,6 +181,11 @@ KChipsetType UIMachineSettingsSystem::chipsetType() const
return (KChipsetType)mCbChipset->itemData(mCbChipset->currentIndex()).toInt();
}
+void UIMachineSettingsSystem::setOHCIEnabled(bool fEnabled)
+{
+ m_fOHCIEnabled = fEnabled;
+}
+
/* Load data to cashe from corresponding external object(s),
* this task COULD be performed in other than GUI thread: */
void UIMachineSettingsSystem::loadToCacheFrom(QVariant &data)
@@ -169,7 +193,12 @@ void UIMachineSettingsSystem::loadToCacheFrom(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Fill internal variables with corresponding values: */
+ /* Clear cache initially: */
+ m_cache.clear();
+
+ /* Prepare system data: */
+ UIDataSettingsMachineSystem systemData;
+
/* Load boot-items of current VM: */
QList<KDeviceType> usedBootItems;
for (int i = 1; i <= m_possibleBootItems.size(); ++i)
@@ -181,7 +210,7 @@ void UIMachineSettingsSystem::loadToCacheFrom(QVariant &data)
UIBootItemData data;
data.m_type = type;
data.m_fEnabled = true;
- m_cache.m_bootItems << data;
+ systemData.m_bootItems << data;
}
}
/* Load other unique boot-items: */
@@ -193,21 +222,26 @@ void UIMachineSettingsSystem::loadToCacheFrom(QVariant &data)
UIBootItemData data;
data.m_type = type;
data.m_fEnabled = false;
- m_cache.m_bootItems << data;
+ systemData.m_bootItems << data;
}
}
- m_cache.m_fPFHwVirtExSupported = vboxGlobal().virtualBox().GetHost().GetProcessorFeature(KProcessorFeature_HWVirtEx);
- m_cache.m_fPFPAESupported = vboxGlobal().virtualBox().GetHost().GetProcessorFeature(KProcessorFeature_PAE);
- m_cache.m_fIoApicEnabled = m_machine.GetBIOSSettings().GetIOAPICEnabled();
- m_cache.m_fEFIEnabled = m_machine.GetFirmwareType() >= KFirmwareType_EFI && m_machine.GetFirmwareType() <= KFirmwareType_EFIDUAL;
- m_cache.m_fUTCEnabled = m_machine.GetRTCUseUTC();
- m_cache.m_fUseAbsHID = m_machine.GetPointingHidType() == KPointingHidType_USBTablet;
- m_cache.m_fPAEEnabled = m_machine.GetCPUProperty(KCPUPropertyType_PAE);
- m_cache.m_fHwVirtExEnabled = m_machine.GetHWVirtExProperty(KHWVirtExPropertyType_Enabled);
- m_cache.m_fNestedPagingEnabled = m_machine.GetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging);
- m_cache.m_iRAMSize = m_machine.GetMemorySize();
- m_cache.m_cCPUCount = m_cache.m_fPFHwVirtExSupported ? m_machine.GetCPUCount() : 1;
- m_cache.m_chipsetType = m_machine.GetChipsetType();
+ /* Gather other system data: */
+ systemData.m_fPFHwVirtExSupported = vboxGlobal().virtualBox().GetHost().GetProcessorFeature(KProcessorFeature_HWVirtEx);
+ systemData.m_fPFPAESupported = vboxGlobal().virtualBox().GetHost().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();
+ systemData.m_fUseAbsHID = m_machine.GetPointingHidType() == KPointingHidType_USBTablet;
+ systemData.m_fPAEEnabled = m_machine.GetCPUProperty(KCPUPropertyType_PAE);
+ systemData.m_fHwVirtExEnabled = m_machine.GetHWVirtExProperty(KHWVirtExPropertyType_Enabled);
+ systemData.m_fNestedPagingEnabled = m_machine.GetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging);
+ systemData.m_iRAMSize = m_machine.GetMemorySize();
+ systemData.m_cCPUCount = systemData.m_fPFHwVirtExSupported ? m_machine.GetCPUCount() : 1;
+ systemData.m_cCPUExecCap = m_machine.GetCPUExecutionCap();
+ systemData.m_chipsetType = m_machine.GetChipsetType();
+
+ /* Cache system data: */
+ m_cache.cacheInitialData(systemData);
/* Upload machine to data: */
UISettingsPageMachine::uploadData(data);
@@ -217,65 +251,74 @@ void UIMachineSettingsSystem::loadToCacheFrom(QVariant &data)
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsSystem::getFromCache()
{
- /* Remove any old data in the boot view. */
+ /* Get system data from cache: */
+ const UIDataSettingsMachineSystem &systemData = m_cache.base();
+
+ /* Remove any old data in the boot view: */
QAbstractItemView *iv = qobject_cast <QAbstractItemView*> (mTwBootOrder);
iv->model()->removeRows(0, iv->model()->rowCount());
/* Apply internal variables data to QWidget(s): */
- for (int i = 0; i < m_cache.m_bootItems.size(); ++i)
+ for (int i = 0; i < systemData.m_bootItems.size(); ++i)
{
- UIBootItemData data = m_cache.m_bootItems[i];
+ UIBootItemData data = systemData.m_bootItems[i];
QListWidgetItem *pItem = new UIBootTableItem(data.m_type);
pItem->setCheckState(data.m_fEnabled ? Qt::Checked : Qt::Unchecked);
mTwBootOrder->addItem(pItem);
}
- mCbApic->setChecked(m_cache.m_fIoApicEnabled);
- mCbEFI->setChecked(m_cache.m_fEFIEnabled);
- mCbTCUseUTC->setChecked(m_cache.m_fUTCEnabled);
- mCbUseAbsHID->setChecked(m_cache.m_fUseAbsHID);
- mSlCPU->setEnabled(m_cache.m_fPFHwVirtExSupported);
- mLeCPU->setEnabled(m_cache.m_fPFHwVirtExSupported);
- mCbPae->setEnabled(m_cache.m_fPFPAESupported);
- mCbPae->setChecked(m_cache.m_fPAEEnabled);
- mCbVirt->setEnabled(m_cache.m_fPFHwVirtExSupported);
- mCbVirt->setChecked(m_cache.m_fHwVirtExEnabled);
- mCbNestedPaging->setEnabled(m_cache.m_fPFHwVirtExSupported && m_cache.m_fHwVirtExEnabled);
- mCbNestedPaging->setChecked(m_cache.m_fNestedPagingEnabled);
- mSlMemory->setValue(m_cache.m_iRAMSize);
- mSlCPU->setValue(m_cache.m_cCPUCount);
- int iChipsetPositionPos = mCbChipset->findData(m_cache.m_chipsetType);
+ /* Load other system data to page: */
+ mCbApic->setChecked(systemData.m_fIoApicEnabled);
+ mCbEFI->setChecked(systemData.m_fEFIEnabled);
+ mCbTCUseUTC->setChecked(systemData.m_fUTCEnabled);
+ mCbUseAbsHID->setChecked(systemData.m_fUseAbsHID);
+ mCbPae->setChecked(systemData.m_fPAEEnabled);
+ mCbVirt->setChecked(systemData.m_fHwVirtExEnabled);
+ mCbNestedPaging->setChecked(systemData.m_fNestedPagingEnabled);
+ mSlMemory->setValue(systemData.m_iRAMSize);
+ mSlCPU->setValue(systemData.m_cCPUCount);
+ mSlCPUExecCap->setValue(systemData.m_cCPUExecCap);
+ int iChipsetPositionPos = mCbChipset->findData(systemData.m_chipsetType);
mCbChipset->setCurrentIndex(iChipsetPositionPos == -1 ? 0 : iChipsetPositionPos);
- if (!m_cache.m_fPFHwVirtExSupported)
- mTwSystem->removeTab(2);
+
+ /* Polish page finally: */
+ polishPage();
/* Revalidate if possible: */
- if (mValidator) mValidator->revalidate();
+ if (mValidator)
+ mValidator->revalidate();
}
/* Save data from corresponding widgets to cache,
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsSystem::putToCache()
{
- /* Gather internal variables data from QWidget(s): */
- m_cache.m_bootItems.clear();
+ /* Prepare system data: */
+ UIDataSettingsMachineSystem systemData = m_cache.base();
+
+ /* Gather system data: */
+ systemData.m_bootItems.clear();
for (int i = 0; i < mTwBootOrder->count(); ++i)
{
QListWidgetItem *pItem = mTwBootOrder->item(i);
UIBootItemData data;
data.m_type = static_cast<UIBootTableItem*>(pItem)->type();
data.m_fEnabled = pItem->checkState() == Qt::Checked;
- m_cache.m_bootItems << data;
+ systemData.m_bootItems << data;
}
- m_cache.m_fIoApicEnabled = mCbApic->isChecked() || mSlCPU->value() > 1 ||
- (KChipsetType)mCbChipset->itemData(mCbChipset->currentIndex()).toInt() == KChipsetType_ICH9;
- m_cache.m_fEFIEnabled = mCbEFI->isChecked();
- m_cache.m_fUTCEnabled = mCbTCUseUTC->isChecked();
- m_cache.m_fUseAbsHID = mCbUseAbsHID->isChecked();
- m_cache.m_fPAEEnabled = mCbPae->isChecked();
- m_cache.m_fHwVirtExEnabled = mCbVirt->checkState() == Qt::Checked || mSlCPU->value() > 1;
- m_cache.m_fNestedPagingEnabled = mCbNestedPaging->isChecked();
- m_cache.m_iRAMSize = mSlMemory->value();
- m_cache.m_cCPUCount = mSlCPU->value();
- m_cache.m_chipsetType = (KChipsetType)mCbChipset->itemData(mCbChipset->currentIndex()).toInt();
+ systemData.m_fIoApicEnabled = mCbApic->isChecked() || mSlCPU->value() > 1 ||
+ (KChipsetType)mCbChipset->itemData(mCbChipset->currentIndex()).toInt() == KChipsetType_ICH9;
+ systemData.m_fEFIEnabled = mCbEFI->isChecked();
+ systemData.m_fUTCEnabled = mCbTCUseUTC->isChecked();
+ systemData.m_fUseAbsHID = mCbUseAbsHID->isChecked();
+ systemData.m_fPAEEnabled = mCbPae->isChecked();
+ systemData.m_fHwVirtExEnabled = mCbVirt->checkState() == Qt::Checked || mSlCPU->value() > 1;
+ systemData.m_fNestedPagingEnabled = mCbNestedPaging->isChecked();
+ systemData.m_iRAMSize = mSlMemory->value();
+ systemData.m_cCPUCount = mSlCPU->value();
+ systemData.m_cCPUExecCap = mSlCPUExecCap->value();
+ systemData.m_chipsetType = (KChipsetType)mCbChipset->itemData(mCbChipset->currentIndex()).toInt();
+
+ /* Cache system data: */
+ m_cache.cacheCurrentData(systemData);
}
/* Save data from cache to corresponding external object(s),
@@ -285,30 +328,48 @@ void UIMachineSettingsSystem::saveFromCacheTo(QVariant &data)
/* Fetch data to machine: */
UISettingsPageMachine::fetchData(data);
- /* Gather corresponding values from internal variables: */
- int iBootIndex = 0;
- /* Save boot-items of current VM: */
- for (int i = 0; i < m_cache.m_bootItems.size(); ++i)
- {
- if (m_cache.m_bootItems[i].m_fEnabled)
- m_machine.SetBootOrder(++iBootIndex, m_cache.m_bootItems[i].m_type);
- }
- /* Save other unique boot-items: */
- for (int i = 0; i < m_cache.m_bootItems.size(); ++i)
+ /* Check if system data was changed: */
+ if (m_cache.wasChanged())
{
- if (!m_cache.m_bootItems[i].m_fEnabled)
- m_machine.SetBootOrder(++iBootIndex, KDeviceType_Null);
+ /* Get system data from cache: */
+ const UIDataSettingsMachineSystem &systemData = m_cache.data();
+
+ /* Store system data: */
+ if (isMachineOffline())
+ {
+ /* Motherboard tab: */
+ m_machine.SetMemorySize(systemData.m_iRAMSize);
+ int iBootIndex = 0;
+ /* Save boot-items of current VM: */
+ for (int i = 0; i < systemData.m_bootItems.size(); ++i)
+ {
+ if (systemData.m_bootItems[i].m_fEnabled)
+ m_machine.SetBootOrder(++iBootIndex, systemData.m_bootItems[i].m_type);
+ }
+ /* Save other unique boot-items: */
+ for (int i = 0; i < systemData.m_bootItems.size(); ++i)
+ {
+ if (!systemData.m_bootItems[i].m_fEnabled)
+ m_machine.SetBootOrder(++iBootIndex, KDeviceType_Null);
+ }
+ m_machine.SetChipsetType(systemData.m_chipsetType);
+ m_machine.GetBIOSSettings().SetIOAPICEnabled(systemData.m_fIoApicEnabled);
+ m_machine.SetFirmwareType(systemData.m_fEFIEnabled ? KFirmwareType_EFI : KFirmwareType_BIOS);
+ m_machine.SetRTCUseUTC(systemData.m_fUTCEnabled);
+ m_machine.SetPointingHidType(systemData.m_fUseAbsHID ? KPointingHidType_USBTablet : KPointingHidType_PS2Mouse);
+ /* Processor tab: */
+ m_machine.SetCPUCount(systemData.m_cCPUCount);
+ m_machine.SetCPUProperty(KCPUPropertyType_PAE, systemData.m_fPAEEnabled);
+ /* Acceleration tab: */
+ m_machine.SetHWVirtExProperty(KHWVirtExPropertyType_Enabled, systemData.m_fHwVirtExEnabled);
+ m_machine.SetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging, systemData.m_fNestedPagingEnabled);
+ }
+ if (isMachineInValidMode())
+ {
+ /* Processor tab: */
+ m_machine.SetCPUExecutionCap(systemData.m_cCPUExecCap);
+ }
}
- m_machine.GetBIOSSettings().SetIOAPICEnabled(m_cache.m_fIoApicEnabled);
- m_machine.SetFirmwareType(m_cache.m_fEFIEnabled ? KFirmwareType_EFI : KFirmwareType_BIOS);
- m_machine.SetRTCUseUTC(m_cache.m_fUTCEnabled);
- m_machine.SetPointingHidType(m_cache.m_fUseAbsHID ? KPointingHidType_USBTablet : KPointingHidType_PS2Mouse);
- m_machine.SetCPUProperty(KCPUPropertyType_PAE, m_cache.m_fPAEEnabled);
- m_machine.SetHWVirtExProperty(KHWVirtExPropertyType_Enabled, m_cache.m_fHwVirtExEnabled);
- m_machine.SetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging, m_cache.m_fNestedPagingEnabled);
- m_machine.SetMemorySize(m_cache.m_iRAMSize);
- m_machine.SetCPUCount(m_cache.m_cCPUCount);
- m_machine.SetChipsetType(m_cache.m_chipsetType);
/* Upload machine to data: */
UISettingsPageMachine::uploadData(data);
@@ -391,6 +452,14 @@ bool UIMachineSettingsSystem::revalidate (QString &aWarning, QString & /* aTitle
return true;
}
+ /* CPU execution cap is low: */
+ if (mSlCPUExecCap->value() < (int)mMedGuestCPUExecCap)
+ {
+ aWarning = tr("you have set the processor execution cap to a low value. "
+ "This can make the machine feel slow to respond.");
+ return true;
+ }
+
/* Chipset type & IO-APIC test */
if ((KChipsetType)mCbChipset->itemData(mCbChipset->currentIndex()).toInt() == KChipsetType_ICH9 && !mCbApic->isChecked())
{
@@ -402,6 +471,17 @@ bool UIMachineSettingsSystem::revalidate (QString &aWarning, QString & /* aTitle
return true;
}
+ /* HID dependency from OHCI feature: */
+ if (mCbUseAbsHID->isChecked() && !m_fOHCIEnabled)
+ {
+ aWarning = tr (
+ "you have enabled a USB HID (Human Interface Device). "
+ "This will not work unless USB emulation is also enabled. "
+ "This will be done automatically when you accept the VM Settings "
+ "by pressing the OK button.");
+ return true;
+ }
+
return true;
}
@@ -422,7 +502,9 @@ void UIMachineSettingsSystem::setOrderAfter (QWidget *aWidget)
/* Processor tab-order */
setTabOrder (mCbUseAbsHID, mSlCPU);
setTabOrder (mSlCPU, mLeCPU);
- setTabOrder (mLeCPU, mCbPae);
+ setTabOrder(mLeCPU, mSlCPUExecCap);
+ setTabOrder(mSlCPUExecCap, mLeCPUExecCap);
+ setTabOrder(mLeCPUExecCap, mCbPae);
/* Acceleration tab-order */
setTabOrder (mCbPae, mCbVirt);
@@ -446,6 +528,10 @@ void UIMachineSettingsSystem::retranslateUi()
/* Retranslate the cpu slider legend */
mLbCPUMin->setText (tr ("<qt>%1&nbsp;CPU</qt>", "%1 is 1 for now").arg (mMinGuestCPU));
mLbCPUMax->setText (tr ("<qt>%1&nbsp;CPUs</qt>", "%1 is host cpu count * 2 for now").arg (mMaxGuestCPU));
+
+ /* Retranslate the cpu cap slider legend: */
+ mLbCPUExecCapMin->setText(tr("<qt>%1%</qt>", "Min CPU execution cap in %").arg(mMinGuestCPUExecCap));
+ mLbCPUExecCapMax->setText(tr("<qt>%1%</qt>", "Max CPU execution cap in %").arg(mMaxGuestCPUExecCap));
}
void UIMachineSettingsSystem::valueChangedRAM (int aVal)
@@ -491,6 +577,16 @@ void UIMachineSettingsSystem::textChangedCPU (const QString &aText)
mSlCPU->setValue (aText.toInt());
}
+void UIMachineSettingsSystem::sltValueChangedCPUExecCap(int iValue)
+{
+ mLeCPUExecCap->setText(QString().setNum(iValue));
+}
+
+void UIMachineSettingsSystem::sltTextChangedCPUExecCap(const QString &strText)
+{
+ mSlCPUExecCap->setValue(strText.toInt());
+}
+
bool UIMachineSettingsSystem::eventFilter (QObject *aObject, QEvent *aEvent)
{
if (!aObject->isWidgetType())
@@ -531,3 +627,46 @@ bool UIMachineSettingsSystem::eventFilter (QObject *aObject, QEvent *aEvent)
return QWidget::eventFilter (aObject, aEvent);
}
+void UIMachineSettingsSystem::polishPage()
+{
+ /* Get system data from cache: */
+ const UIDataSettingsMachineSystem &systemData = m_cache.base();
+
+ /* Motherboard tab: */
+ mLbMemory->setEnabled(isMachineOffline());
+ mLbMemoryMin->setEnabled(isMachineOffline());
+ mLbMemoryMax->setEnabled(isMachineOffline());
+ mLbMemoryUnit->setEnabled(isMachineOffline());
+ mSlMemory->setEnabled(isMachineOffline());
+ mLeMemory->setEnabled(isMachineOffline());
+ mLbBootOrder->setEnabled(isMachineOffline());
+ mTwBootOrder->setEnabled(isMachineOffline());
+ mTbBootItemUp->setEnabled(isMachineOffline() && mTwBootOrder->hasFocus() && mTwBootOrder->currentRow() > 0);
+ mTbBootItemDown->setEnabled(isMachineOffline() && mTwBootOrder->hasFocus() && (mTwBootOrder->currentRow() < mTwBootOrder->count() - 1));
+ mLbChipset->setEnabled(isMachineOffline());
+ mCbChipset->setEnabled(isMachineOffline());
+ mLbMotherboardExtended->setEnabled(isMachineOffline());
+ mCbApic->setEnabled(isMachineOffline());
+ mCbEFI->setEnabled(isMachineOffline());
+ mCbTCUseUTC->setEnabled(isMachineOffline());
+ mCbUseAbsHID->setEnabled(isMachineOffline());
+ /* Processor tab: */
+ mLbCPU->setEnabled(isMachineOffline());
+ mLbCPUMin->setEnabled(isMachineOffline());
+ mLbCPUMax->setEnabled(isMachineOffline());
+ mSlCPU->setEnabled(isMachineOffline() && systemData.m_fPFHwVirtExSupported);
+ mLeCPU->setEnabled(isMachineOffline() && systemData.m_fPFHwVirtExSupported);
+ mLbCPUExecCap->setEnabled(isMachineInValidMode());
+ mLbCPUExecCapMin->setEnabled(isMachineInValidMode());
+ mLbCPUExecCapMax->setEnabled(isMachineInValidMode());
+ mSlCPUExecCap->setEnabled(isMachineInValidMode());
+ mLeCPUExecCap->setEnabled(isMachineInValidMode());
+ mLbProcessorExtended->setEnabled(isMachineOffline());
+ mCbPae->setEnabled(isMachineOffline() && systemData.m_fPFPAESupported);
+ /* Acceleration tab: */
+ mTwSystem->setTabEnabled(2, systemData.m_fPFHwVirtExSupported);
+ mLbVirt->setEnabled(isMachineOffline());
+ mCbVirt->setEnabled(isMachineOffline());
+ mCbNestedPaging->setEnabled(isMachineOffline() && mCbVirt->isChecked());
+}
+
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.h b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.h
index 589d5eecd..5e8ccf070 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -26,13 +26,60 @@
/* Machine settings / System page / Boot item: */
struct UIBootItemData
{
+ /* Default constructor: */
+ UIBootItemData() : m_type(KDeviceType_Null), m_fEnabled(false) {}
+ /* Operator==: */
+ bool operator==(const UIBootItemData &other) const
+ {
+ return (m_type == other.m_type) &&
+ (m_fEnabled == other.m_fEnabled);
+ }
+ /* Variables: */
KDeviceType m_type;
bool m_fEnabled;
};
-/* Machine settings / System page / Cache: */
-struct UISettingsCacheMachineSystem
+/* Machine settings / System page / Data: */
+struct UIDataSettingsMachineSystem
{
+ /* Default constructor: */
+ UIDataSettingsMachineSystem()
+ : m_bootItems(QList<UIBootItemData>())
+ , m_chipsetType(KChipsetType_Null)
+ , m_fPFHwVirtExSupported(false)
+ , m_fPFPAESupported(false)
+ , m_fIoApicEnabled(false)
+ , m_fEFIEnabled(false)
+ , m_fUTCEnabled(false)
+ , m_fUseAbsHID(false)
+ , m_fPAEEnabled(false)
+ , m_fHwVirtExEnabled(false)
+ , m_fNestedPagingEnabled(false)
+ , m_iRAMSize(-1)
+ , m_cCPUCount(-1)
+ , m_cCPUExecCap(-1) {}
+ /* Functions: */
+ bool equal(const UIDataSettingsMachineSystem &other) const
+ {
+ return (m_bootItems == other.m_bootItems) &&
+ (m_chipsetType == other.m_chipsetType) &&
+ (m_fPFHwVirtExSupported == other.m_fPFHwVirtExSupported) &&
+ (m_fPFPAESupported == other.m_fPFPAESupported) &&
+ (m_fIoApicEnabled == other.m_fIoApicEnabled) &&
+ (m_fEFIEnabled == other.m_fEFIEnabled) &&
+ (m_fUTCEnabled == other.m_fUTCEnabled) &&
+ (m_fUseAbsHID == other.m_fUseAbsHID) &&
+ (m_fPAEEnabled == other.m_fPAEEnabled) &&
+ (m_fHwVirtExEnabled == other.m_fHwVirtExEnabled) &&
+ (m_fNestedPagingEnabled == other.m_fNestedPagingEnabled) &&
+ (m_iRAMSize == other.m_iRAMSize) &&
+ (m_cCPUCount == other.m_cCPUCount) &&
+ (m_cCPUExecCap == other.m_cCPUExecCap);
+ }
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineSystem &other) const { return equal(other); }
+ bool operator!=(const UIDataSettingsMachineSystem &other) const { return !equal(other); }
+ /* Variables: */
QList<UIBootItemData> m_bootItems;
KChipsetType m_chipsetType;
bool m_fPFHwVirtExSupported;
@@ -46,7 +93,9 @@ struct UISettingsCacheMachineSystem
bool m_fNestedPagingEnabled;
int m_iRAMSize;
int m_cCPUCount;
+ int m_cCPUExecCap;
};
+typedef UISettingsCache<UIDataSettingsMachineSystem> UICacheSettingsMachineSystem;
/* Machine settings / System page: */
class UIMachineSettingsSystem : public UISettingsPageMachine,
@@ -59,9 +108,9 @@ public:
UIMachineSettingsSystem();
bool isHWVirtExEnabled() const;
- int cpuCount() const;
bool isHIDEnabled() const;
KChipsetType chipsetType() const;
+ void setOHCIEnabled(bool fEnabled);
signals:
@@ -83,6 +132,9 @@ protected:
* this task COULD be performed in other than GUI thread: */
void saveFromCacheTo(QVariant &data);
+ /* Page changed: */
+ bool changed() const { return m_cache.wasChanged(); }
+
void setValidator (QIWidgetValidator *aVal);
bool revalidate (QString &aWarning, QString &aTitle);
@@ -99,6 +151,8 @@ private slots:
void valueChangedCPU (int aVal);
void textChangedCPU (const QString &aText);
+ void sltValueChangedCPUExecCap(int iValue);
+ void sltTextChangedCPUExecCap(const QString &strText);
private:
@@ -106,15 +160,22 @@ private:
void adjustBootOrderTWSize();
+ void polishPage();
+
QIWidgetValidator *mValidator;
uint mMinGuestCPU;
uint mMaxGuestCPU;
+ uint mMinGuestCPUExecCap;
+ uint mMedGuestCPUExecCap;
+ uint mMaxGuestCPUExecCap;
QList<KDeviceType> m_possibleBootItems;
+ bool m_fOHCIEnabled;
+
/* Cache: */
- UISettingsCacheMachineSystem m_cache;
+ UICacheSettingsMachineSystem m_cache;
};
#endif // __UIMachineSettingsSystem_h__
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.ui b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.ui
index 41650f777..40d6a9ccd 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.ui
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.ui
@@ -538,6 +538,110 @@
</widget>
</item>
<item row="2" column="0">
+ <widget class="QLabel" name="mLbCPUExecCap">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Execution Cap:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>mLeCPUExecCap</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" rowspan="2">
+ <layout class="QVBoxLayout" name="mLtCPUExecCapSlider">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QIAdvancedSlider" name="mSlCPUExecCap">
+ <property name="whatsThis">
+ <string>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</string>
+ </property>
+ <property name="maximum">
+ <number>4096</number>
+ </property>
+ <property name="singleStep">
+ <number>200</number>
+ </property>
+ <property name="value">
+ <number>512</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBelow</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="mLtCPUExecCapLegend">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="mLbCPUExecCapMin">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="mSpHor5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="mLbCPUExecCapMax">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="2">
+ <widget class="QILineEdit" name="mLeCPUExecCap">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis">
+ <string>Limits the amount of time that each virtual CPU is allowed to run for. Each virtual CPU will be allowed to use up to this percentage of the processing time available on one physical CPU. The execution cap can be disabled by setting it to 100%. Setting the cap too low can make the machine feel slow to respond.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
<widget class="QLabel" name="mLbProcessorExtended">
<property name="text">
<string>Extended Features:</string>
@@ -547,7 +651,7 @@
</property>
</widget>
</item>
- <item row="2" column="1" colspan="2">
+ <item row="4" column="1" colspan="2">
<widget class="QCheckBox" name="mCbPae">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
@@ -563,7 +667,7 @@
</property>
</widget>
</item>
- <item row="3" column="0" colspan="3">
+ <item row="5" column="0" colspan="3">
<spacer name="mSpVer3">
<property name="orientation">
<enum>Qt::Vertical</enum>
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.cpp
index d7dd36dc2..dbc963a26 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsUSB.cpp $ */
+/* $Id: UIMachineSettingsUSB.cpp 37916 2011-07-13 12:46:11Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,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;
@@ -32,10 +32,10 @@
UIMachineSettingsUSB::UIMachineSettingsUSB(UISettingsPageType type)
: UISettingsPage(type)
, mValidator(0)
+ , m_pToolBar(0)
, mNewAction(0), mAddAction(0), mEdtAction(0), mDelAction(0)
, mMupAction(0), mMdnAction(0)
- , mMenu(0), mUSBDevicesMenu(0)
- , mUSBFilterListModified(false)
+ , mUSBDevicesMenu(0)
{
/* Apply UI decorations */
Ui::UIMachineSettingsUSB::setupUi (this);
@@ -68,45 +68,33 @@ UIMachineSettingsUSB::UIMachineSettingsUSB(UISettingsPageType type)
mMdnAction->setIcon(UIIconPool::iconSet(":/usb_movedown_16px.png",
":/usb_movedown_disabled_16px.png"));
- /* Prepare menu and toolbar */
- mMenu = new QMenu (mTwFilters);
- mMenu->addAction (mNewAction);
- mMenu->addAction (mAddAction);
- mMenu->addSeparator();
- mMenu->addAction (mEdtAction);
- mMenu->addSeparator();
- mMenu->addAction (mDelAction);
- mMenu->addSeparator();
- mMenu->addAction (mMupAction);
- mMenu->addAction (mMdnAction);
-
/* Prepare toolbar */
- UIToolBar *toolBar = new UIToolBar (mWtFilterHandler);
- toolBar->setUsesTextLabel (false);
- toolBar->setIconSize (QSize (16, 16));
- toolBar->setOrientation (Qt::Vertical);
- toolBar->addAction (mNewAction);
- toolBar->addAction (mAddAction);
- toolBar->addAction (mEdtAction);
- toolBar->addAction (mDelAction);
- toolBar->addAction (mMupAction);
- toolBar->addAction (mMdnAction);
- toolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::MinimumExpanding);
- toolBar->updateGeometry();
+ m_pToolBar = new UIToolBar (mWtFilterHandler);
+ m_pToolBar->setUsesTextLabel (false);
+ m_pToolBar->setIconSize (QSize (16, 16));
+ m_pToolBar->setOrientation (Qt::Vertical);
+ m_pToolBar->addAction (mNewAction);
+ m_pToolBar->addAction (mAddAction);
+ m_pToolBar->addAction (mEdtAction);
+ m_pToolBar->addAction (mDelAction);
+ m_pToolBar->addAction (mMupAction);
+ m_pToolBar->addAction (mMdnAction);
+ m_pToolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::MinimumExpanding);
+ m_pToolBar->updateGeometry();
#ifdef Q_WS_MAC
/* On the Mac this has to be slightly higher, than what sizeHint returned.
* No idea why. */
- toolBar->setMinimumHeight(toolBar->sizeHint().height() + 4);
+ m_pToolBar->setMinimumHeight(m_pToolBar->sizeHint().height() + 4);
#else
- toolBar->setMinimumHeight(toolBar->sizeHint().height());
+ m_pToolBar->setMinimumHeight(m_pToolBar->sizeHint().height());
#endif /* Q_WS_MAC */
- mWtFilterHandler->layout()->addWidget (toolBar);
+ mWtFilterHandler->layout()->addWidget (m_pToolBar);
/* Setup connections */
connect (mGbUSB, SIGNAL (toggled (bool)),
this, SLOT (usbAdapterToggled (bool)));
connect (mTwFilters, SIGNAL (currentItemChanged (QTreeWidgetItem*, QTreeWidgetItem*)),
- this, SLOT (currentChanged (QTreeWidgetItem*, QTreeWidgetItem*)));
+ this, SLOT (currentChanged (QTreeWidgetItem*)));
connect (mTwFilters, SIGNAL (customContextMenuRequested (const QPoint &)),
this, SLOT (showContextMenu (const QPoint &)));
connect (mTwFilters, SIGNAL (itemDoubleClicked (QTreeWidgetItem *, int)),
@@ -138,7 +126,7 @@ UIMachineSettingsUSB::UIMachineSettingsUSB(UISettingsPageType type)
#ifndef VBOX_WITH_EHCI
mCbUSB2->setHidden(true);
-#endif
+#endif /* VBOX_WITH_EHCI */
}
bool UIMachineSettingsUSB::isOHCIEnabled() const
@@ -153,75 +141,99 @@ void UIMachineSettingsUSB::loadToCacheFrom(QVariant &data)
/* Fetch data to properties & settings or machine: */
fetchData(data);
+ /* Clear cache initially: */
+ m_cache.clear();
+
/* Depending on page type: */
- switch (type())
+ switch (pageType())
{
case UISettingsPageType_Global:
{
- /* Fill internal variables with corresponding values: */
- m_cache.m_fUSBEnabled = false;
- m_cache.m_fEHCIEnabled = false;
+ /* For each USB filter: */
const CHostUSBDeviceFilterVector &filters = vboxGlobal().virtualBox().GetHost().GetUSBDeviceFilters();
for (int iFilterIndex = 0; iFilterIndex < filters.size(); ++iFilterIndex)
{
+ /* Prepare USB filter data: */
+ UIDataSettingsMachineUSBFilter usbFilterData;
+
+ /* Check if filter is valid: */
const CHostUSBDeviceFilter &filter = filters[iFilterIndex];
- UIUSBFilterData data;
- data.m_fActive = filter.GetActive();
- data.m_strName = filter.GetName();
- data.m_strVendorId = filter.GetVendorId();
- data.m_strProductId = filter.GetProductId();
- data.m_strRevision = filter.GetRevision();
- data.m_strManufacturer = filter.GetManufacturer();
- data.m_strProduct = filter.GetProduct();
- data.m_strSerialNumber = filter.GetSerialNumber();
- data.m_strPort = filter.GetPort();
- data.m_strRemote = filter.GetRemote();
- data.m_action = filter.GetAction();
- CHostUSBDevice hostUSBDevice(filter);
- if (!hostUSBDevice.isNull())
+ if (!filter.isNull())
{
- data.m_fHostUSBDevice = true;
- data.m_hostUSBDeviceState = hostUSBDevice.GetState();
- }
- else
- {
- data.m_fHostUSBDevice = false;
- data.m_hostUSBDeviceState = KUSBDeviceState_NotSupported;
+ usbFilterData.m_fActive = filter.GetActive();
+ usbFilterData.m_strName = filter.GetName();
+ usbFilterData.m_strVendorId = filter.GetVendorId();
+ usbFilterData.m_strProductId = filter.GetProductId();
+ usbFilterData.m_strRevision = filter.GetRevision();
+ usbFilterData.m_strManufacturer = filter.GetManufacturer();
+ usbFilterData.m_strProduct = filter.GetProduct();
+ usbFilterData.m_strSerialNumber = filter.GetSerialNumber();
+ usbFilterData.m_strPort = filter.GetPort();
+ usbFilterData.m_strRemote = filter.GetRemote();
+ usbFilterData.m_action = filter.GetAction();
+ CHostUSBDevice hostUSBDevice(filter);
+ if (!hostUSBDevice.isNull())
+ {
+ usbFilterData.m_fHostUSBDevice = true;
+ usbFilterData.m_hostUSBDeviceState = hostUSBDevice.GetState();
+ }
+ else
+ {
+ usbFilterData.m_fHostUSBDevice = false;
+ usbFilterData.m_hostUSBDeviceState = KUSBDeviceState_NotSupported;
+ }
}
- m_cache.m_items << data;
+
+ /* Cache USB filter data: */
+ m_cache.child(iFilterIndex).cacheInitialData(usbFilterData);
}
+
break;
}
case UISettingsPageType_Machine:
{
- /* Initialize machine COM storage: */
- m_machine = data.value<UISettingsDataMachine>().m_machine;
- /* Fill internal variables with corresponding values: */
- const CUSBController &ctl = m_machine.GetUSBController();
- bool fIsControllerAvailable = !ctl.isNull();
- m_cache.m_fUSBEnabled = fIsControllerAvailable && ctl.GetEnabled();
- m_cache.m_fEHCIEnabled = fIsControllerAvailable && ctl.GetEnabledEhci();
- if (fIsControllerAvailable)
+ /* Prepare USB data: */
+ UIDataSettingsMachineUSB usbData;
+
+ /* Check if controller is valid: */
+ const CUSBController &controller = m_machine.GetUSBController();
+ if (!controller.isNull())
{
- const CUSBDeviceFilterVector &filters = ctl.GetDeviceFilters();
+ /* Gather USB values: */
+ usbData.m_fUSBEnabled = controller.GetEnabled();
+ usbData.m_fEHCIEnabled = controller.GetEnabledEhci();
+
+ /* For each USB filter: */
+ const CUSBDeviceFilterVector &filters = controller.GetDeviceFilters();
for (int iFilterIndex = 0; iFilterIndex < filters.size(); ++iFilterIndex)
{
+ /* Prepare USB filter data: */
+ UIDataSettingsMachineUSBFilter usbFilterData;
+
+ /* Check if filter is valid: */
const CUSBDeviceFilter &filter = filters[iFilterIndex];
- UIUSBFilterData data;
- data.m_fActive = filter.GetActive();
- data.m_strName = filter.GetName();
- data.m_strVendorId = filter.GetVendorId();
- data.m_strProductId = filter.GetProductId();
- data.m_strRevision = filter.GetRevision();
- data.m_strManufacturer = filter.GetManufacturer();
- data.m_strProduct = filter.GetProduct();
- data.m_strSerialNumber = filter.GetSerialNumber();
- data.m_strPort = filter.GetPort();
- data.m_strRemote = filter.GetRemote();
- data.m_fHostUSBDevice = false;
- m_cache.m_items << data;
+ if (!filter.isNull())
+ {
+ usbFilterData.m_fActive = filter.GetActive();
+ usbFilterData.m_strName = filter.GetName();
+ usbFilterData.m_strVendorId = filter.GetVendorId();
+ usbFilterData.m_strProductId = filter.GetProductId();
+ usbFilterData.m_strRevision = filter.GetRevision();
+ usbFilterData.m_strManufacturer = filter.GetManufacturer();
+ usbFilterData.m_strProduct = filter.GetProduct();
+ usbFilterData.m_strSerialNumber = filter.GetSerialNumber();
+ usbFilterData.m_strPort = filter.GetPort();
+ usbFilterData.m_strRemote = filter.GetRemote();
+ }
+
+ /* Cache USB filter data: */
+ m_cache.child(iFilterIndex).cacheInitialData(usbFilterData);
}
}
+
+ /* Cache USB data: */
+ m_cache.cacheInitialData(usbData);
+
break;
}
default:
@@ -236,38 +248,49 @@ void UIMachineSettingsUSB::loadToCacheFrom(QVariant &data)
* this task SHOULD be performed in GUI thread only: */
void UIMachineSettingsUSB::getFromCache()
{
+ /* Clear list initially: */
+ mTwFilters->clear();
+ m_filters.clear();
+
/* Depending on page type: */
- switch (type())
+ switch (pageType())
{
case UISettingsPageType_Global:
{
- /* Apply internal variables data to QWidget(s): */
+ /* Hide unused widgets: */
mGbUSB->setVisible(false);
mCbUSB2->setVisible(false);
break;
}
case UISettingsPageType_Machine:
{
- /* Apply internal variables data to QWidget(s): */
- mGbUSB->setChecked(m_cache.m_fUSBEnabled);
- mCbUSB2->setChecked(m_cache.m_fEHCIEnabled);
- usbAdapterToggled(mGbUSB->isChecked());
+ /* Get USB data from cache: */
+ const UIDataSettingsMachineUSB &usbData = m_cache.base();
+ /* Load USB data to page: */
+ mGbUSB->setChecked(usbData.m_fUSBEnabled);
+ mCbUSB2->setChecked(usbData.m_fEHCIEnabled);
break;
}
default:
break;
}
- /* Apply internal variables data to QWidget(s): */
- for (int iFilterIndex = 0; iFilterIndex < m_cache.m_items.size(); ++iFilterIndex)
- addUSBFilter(m_cache.m_items[iFilterIndex], false /* its new? */);
+
+ /* For each USB filter => load it to the page: */
+ for (int iFilterIndex = 0; iFilterIndex < m_cache.childCount(); ++iFilterIndex)
+ addUSBFilter(m_cache.child(iFilterIndex).base(), false /* its new? */);
+
/* Choose first filter as current: */
mTwFilters->setCurrentItem(mTwFilters->topLevelItem(0));
- currentChanged(mTwFilters->currentItem());
- /* Mark dialog as not edited: */
- mUSBFilterListModified = false;
+
+ /* Update page: */
+ usbAdapterToggled(mGbUSB->isChecked());
+
+ /* Polish page finally: */
+ polishPage();
/* Revalidate if possible: */
- if (mValidator) mValidator->revalidate();
+ if (mValidator)
+ mValidator->revalidate();
}
/* Save data from corresponding widgets to cache,
@@ -275,22 +298,32 @@ void UIMachineSettingsUSB::getFromCache()
void UIMachineSettingsUSB::putToCache()
{
/* Depending on page type: */
- switch (type())
+ switch (pageType())
{
case UISettingsPageType_Machine:
{
- /* Gather internal variables data from QWidget(s): */
+ /* Prepare USB data: */
+ UIDataSettingsMachineUSB usbData = m_cache.base();
+
/* USB 1.0 (OHCI): */
- m_cache.m_fUSBEnabled = mGbUSB->isChecked();
+ usbData.m_fUSBEnabled = mGbUSB->isChecked();
/* USB 2.0 (EHCI): */
QString strExtPackName = "Oracle VM VirtualBox Extension Pack";
CExtPack extPack = vboxGlobal().virtualBox().GetExtensionPackManager().Find(strExtPackName);
- m_cache.m_fEHCIEnabled = extPack.isNull() || !extPack.GetUsable() ? false : mCbUSB2->isChecked();
+ usbData.m_fEHCIEnabled = extPack.isNull() || !extPack.GetUsable() ? false : mCbUSB2->isChecked();
+
+ /* Update USB cache: */
+ m_cache.cacheCurrentData(usbData);
+
break;
}
default:
break;
}
+
+ /* For each USB filter => recache USB filter data: */
+ for (int iFilterIndex = 0; iFilterIndex < m_filters.size(); ++iFilterIndex)
+ m_cache.child(iFilterIndex).cacheCurrentData(m_filters[iFilterIndex]);
}
/* Save data from cache to corresponding external object(s),
@@ -300,70 +333,116 @@ void UIMachineSettingsUSB::saveFromCacheTo(QVariant &data)
/* Fetch data to properties & settings or machine: */
fetchData(data);
- /* Depending on page type: */
- switch (type())
+ /* Save settings depending on page type: */
+ switch (pageType())
{
+ /* Here come the global USB properties: */
case UISettingsPageType_Global:
{
- /* Gather corresponding values from internal variables: */
- if (mUSBFilterListModified)
+ /* Check if USB data really changed: */
+ if (m_cache.wasChanged())
{
- /* Get host: */
- CHost host = vboxGlobal().virtualBox().GetHost();
- /* First, remove all old filters: */
- for (ulong count = host.GetUSBDeviceFilters().size(); count; --count)
- host.RemoveUSBDeviceFilter(0);
- /* Then add all new filters: */
- for (int iFilterIndex = 0; iFilterIndex < m_cache.m_items.size(); ++iFilterIndex)
+ /* Store USB data: */
+ if (isMachineInValidMode())
{
- UIUSBFilterData data = m_cache.m_items[iFilterIndex];
- CHostUSBDeviceFilter hostFilter = host.CreateUSBDeviceFilter(data.m_strName);
- hostFilter.SetActive(data.m_fActive);
- hostFilter.SetVendorId(data.m_strVendorId);
- hostFilter.SetProductId(data.m_strProductId);
- hostFilter.SetRevision(data.m_strRevision);
- hostFilter.SetManufacturer(data.m_strManufacturer);
- hostFilter.SetProduct(data.m_strProduct);
- hostFilter.SetSerialNumber(data.m_strSerialNumber);
- hostFilter.SetPort(data.m_strPort);
- hostFilter.SetRemote(data.m_strRemote);
- hostFilter.SetAction(data.m_action);
- host.InsertUSBDeviceFilter(host.GetUSBDeviceFilters().size(), hostFilter);
+ /* Get host: */
+ CHost host = vboxGlobal().virtualBox().GetHost();
+ /* For each USB filter data set: */
+ for (int iFilterIndex = 0; iFilterIndex < m_cache.childCount(); ++iFilterIndex)
+ {
+ /* Check if USB filter data really changed: */
+ const UICacheSettingsMachineUSBFilter &usbFilterCache = m_cache.child(iFilterIndex);
+ if (usbFilterCache.wasChanged())
+ {
+ /* If filter was removed or updated: */
+ if (usbFilterCache.wasRemoved() || usbFilterCache.wasUpdated())
+ host.RemoveUSBDeviceFilter(iFilterIndex);
+ /* If filter was created or updated: */
+ if (usbFilterCache.wasCreated() || usbFilterCache.wasUpdated())
+ {
+ /* Get USB filter data from cache: */
+ const UIDataSettingsMachineUSBFilter &usbFilterData = usbFilterCache.data();
+
+ /* Store USB filter data: */
+ CHostUSBDeviceFilter hostFilter = host.CreateUSBDeviceFilter(usbFilterData.m_strName);
+ hostFilter.SetActive(usbFilterData.m_fActive);
+ hostFilter.SetVendorId(usbFilterData.m_strVendorId);
+ hostFilter.SetProductId(usbFilterData.m_strProductId);
+ hostFilter.SetRevision(usbFilterData.m_strRevision);
+ hostFilter.SetManufacturer(usbFilterData.m_strManufacturer);
+ hostFilter.SetProduct(usbFilterData.m_strProduct);
+ hostFilter.SetSerialNumber(usbFilterData.m_strSerialNumber);
+ hostFilter.SetPort(usbFilterData.m_strPort);
+ hostFilter.SetRemote(usbFilterData.m_strRemote);
+ hostFilter.SetAction(usbFilterData.m_action);
+ host.InsertUSBDeviceFilter(iFilterIndex, hostFilter);
+ }
+ }
+ }
}
}
break;
}
+ /* Here come VM USB properties: */
case UISettingsPageType_Machine:
{
- /* Initialize machine COM storage: */
- m_machine = data.value<UISettingsDataMachine>().m_machine;
- /* Get machine USB controller: */
- CUSBController ctl = m_machine.GetUSBController();
- /* Gather corresponding values from internal variables: */
- if (!ctl.isNull())
+ /* Check if USB data really changed: */
+ if (m_cache.wasChanged())
{
- ctl.SetEnabled(m_cache.m_fUSBEnabled);
- ctl.SetEnabledEhci(m_cache.m_fEHCIEnabled);
- if (mUSBFilterListModified)
+ /* Check if controller is valid: */
+ CUSBController controller = m_machine.GetUSBController();
+ if (!controller.isNull())
{
- /* First, remove all old filters: */
- for (ulong count = ctl.GetDeviceFilters().size(); count; --count)
- ctl.RemoveDeviceFilter(0);
- /* Then add all new filters: */
- for (int iFilterIndex = 0; iFilterIndex < m_cache.m_items.size(); ++iFilterIndex)
+ /* Get USB data from cache: */
+ const UIDataSettingsMachineUSB &usbData = m_cache.data();
+ /* Store USB data: */
+ if (isMachineOffline())
+ {
+ controller.SetEnabled(usbData.m_fUSBEnabled);
+ controller.SetEnabledEhci(usbData.m_fEHCIEnabled);
+ }
+ /* Store USB filters data: */
+ if (isMachineInValidMode())
{
- const UIUSBFilterData &data = m_cache.m_items[iFilterIndex];
- CUSBDeviceFilter filter = ctl.CreateDeviceFilter(data.m_strName);
- filter.SetActive(data.m_fActive);
- filter.SetVendorId(data.m_strVendorId);
- filter.SetProductId(data.m_strProductId);
- filter.SetRevision(data.m_strRevision);
- filter.SetManufacturer(data.m_strManufacturer);
- filter.SetProduct(data.m_strProduct);
- filter.SetSerialNumber(data.m_strSerialNumber);
- filter.SetPort(data.m_strPort);
- filter.SetRemote(data.m_strRemote);
- ctl.InsertDeviceFilter(~0, filter);
+ /* For each USB filter data set: */
+ int iOperationPosition = 0;
+ for (int iFilterIndex = 0; iFilterIndex < m_cache.childCount(); ++iFilterIndex)
+ {
+ /* Check if USB filter data really changed: */
+ const UICacheSettingsMachineUSBFilter &usbFilterCache = m_cache.child(iFilterIndex);
+ if (usbFilterCache.wasChanged())
+ {
+ /* If filter was removed or updated: */
+ if (usbFilterCache.wasRemoved() || usbFilterCache.wasUpdated())
+ {
+ controller.RemoveDeviceFilter(iOperationPosition);
+ if (usbFilterCache.wasRemoved())
+ --iOperationPosition;
+ }
+
+ /* If filter was created or updated: */
+ if (usbFilterCache.wasCreated() || usbFilterCache.wasUpdated())
+ {
+ /* Get USB filter data from cache: */
+ const UIDataSettingsMachineUSBFilter &usbFilterData = usbFilterCache.data();
+ /* Store USB filter data: */
+ CUSBDeviceFilter filter = controller.CreateDeviceFilter(usbFilterData.m_strName);
+ filter.SetActive(usbFilterData.m_fActive);
+ filter.SetVendorId(usbFilterData.m_strVendorId);
+ filter.SetProductId(usbFilterData.m_strProductId);
+ filter.SetRevision(usbFilterData.m_strRevision);
+ filter.SetManufacturer(usbFilterData.m_strManufacturer);
+ filter.SetProduct(usbFilterData.m_strProduct);
+ filter.SetSerialNumber(usbFilterData.m_strSerialNumber);
+ filter.SetPort(usbFilterData.m_strPort);
+ filter.SetRemote(usbFilterData.m_strRemote);
+ controller.InsertDeviceFilter(iOperationPosition, filter);
+ }
+ }
+
+ /* Advance operation position: */
+ ++iOperationPosition;
+ }
}
}
}
@@ -389,10 +468,10 @@ bool UIMachineSettingsUSB::revalidate(QString &strWarningText, QString& /* strTi
/* USB 2.0 Extension Pack presence test: */
QString strExtPackName = "Oracle VM VirtualBox Extension Pack";
CExtPack extPack = vboxGlobal().virtualBox().GetExtensionPackManager().Find(strExtPackName);
- if (mCbUSB2->isChecked() && (extPack.isNull() || !extPack.GetUsable()))
+ if (mGbUSB->isChecked() && mCbUSB2->isChecked() && (extPack.isNull() || !extPack.GetUsable()))
{
strWarningText = tr("USB 2.0 is currently enabled for this virtual machine. "
- "However this requires the <b>%1</b> to be installed. "
+ "However, this requires the <b>%1</b> 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.")
@@ -450,67 +529,77 @@ void UIMachineSettingsUSB::retranslateUi()
mUSBFilterName = tr ("New Filter %1", "usb");
}
-void UIMachineSettingsUSB::usbAdapterToggled (bool aOn)
+void UIMachineSettingsUSB::usbAdapterToggled(bool fEnabled)
{
- mGbUSBFilters->setEnabled (aOn);
+ /* Enable/disable USB children: */
+ mUSBChild->setEnabled(isMachineInValidMode() && fEnabled);
+ mCbUSB2->setEnabled(isMachineOffline() && fEnabled);
+ if (fEnabled)
+ {
+ /* If there is no chosen item but there is something to choose => choose it: */
+ if (mTwFilters->currentItem() == 0 && mTwFilters->topLevelItemCount() != 0)
+ mTwFilters->setCurrentItem(mTwFilters->topLevelItem(0));
+ }
+ /* Update current item: */
+ currentChanged(mTwFilters->currentItem());
}
-void UIMachineSettingsUSB::currentChanged (QTreeWidgetItem *aItem,
- QTreeWidgetItem *)
+void UIMachineSettingsUSB::currentChanged(QTreeWidgetItem *aItem)
{
- /* Make sure only the current item if present => selected */
- if (mTwFilters->selectedItems().count() != 1 ||
- mTwFilters->selectedItems() [0] != aItem)
- {
- QList<QTreeWidgetItem*> list = mTwFilters->selectedItems();
- for (int i = 0; i < list.size(); ++ i)
- list [i]->setSelected (false);
- if (aItem)
- aItem->setSelected (true);
- }
+ /* Get selected items: */
+ QList<QTreeWidgetItem*> selectedItems = mTwFilters->selectedItems();
+ /* Deselect all selected items first: */
+ for (int iItemIndex = 0; iItemIndex < selectedItems.size(); ++iItemIndex)
+ selectedItems[iItemIndex]->setSelected(false);
+
+ /* If tree-widget is NOT enabled => we should NOT select anything: */
+ if (!mTwFilters->isEnabled())
+ return;
- /* Enable/disable operational buttons */
- mEdtAction->setEnabled (aItem);
- mDelAction->setEnabled (aItem);
- mMupAction->setEnabled (aItem && mTwFilters->itemAbove (aItem));
- mMdnAction->setEnabled (aItem && mTwFilters->itemBelow (aItem));
+ /* Select item if requested: */
+ if (aItem)
+ aItem->setSelected(true);
+
+ /* Update corresponding action states: */
+ mEdtAction->setEnabled(aItem);
+ mDelAction->setEnabled(aItem);
+ mMupAction->setEnabled(aItem && mTwFilters->itemAbove(aItem));
+ mMdnAction->setEnabled(aItem && mTwFilters->itemBelow(aItem));
}
void UIMachineSettingsUSB::newClicked()
{
- /* Search for the max available filter index */
- int maxFilterIndex = 0;
- QRegExp regExp (QString ("^") + mUSBFilterName.arg ("([0-9]+)") + QString ("$"));
- QTreeWidgetItemIterator iterator (mTwFilters);
+ /* Search for the max available filter index: */
+ int iMaxFilterIndex = 0;
+ QRegExp regExp(QString("^") + mUSBFilterName.arg("([0-9]+)") + QString("$"));
+ QTreeWidgetItemIterator iterator(mTwFilters);
while (*iterator)
{
- QString filterName = (*iterator)->text (0);
- int pos = regExp.indexIn (filterName);
+ QString filterName = (*iterator)->text(0);
+ int pos = regExp.indexIn(filterName);
if (pos != -1)
- maxFilterIndex = regExp.cap (1).toInt() > maxFilterIndex ?
- regExp.cap (1).toInt() : maxFilterIndex;
- ++ iterator;
+ iMaxFilterIndex = regExp.cap(1).toInt() > iMaxFilterIndex ?
+ regExp.cap(1).toInt() : iMaxFilterIndex;
+ ++iterator;
}
- /* Add new corresponding list item to the cache: */
- UIUSBFilterData data;
- switch (type())
+ /* Prepare new USB filter data: */
+ UIDataSettingsMachineUSBFilter usbFilterData;
+ switch (pageType())
{
case UISettingsPageType_Global:
- data.m_action = KUSBDeviceFilterAction_Hold;
+ usbFilterData.m_action = KUSBDeviceFilterAction_Hold;
break;
default:
break;
}
- data.m_fActive = true;
- data.m_strName = mUSBFilterName.arg(maxFilterIndex + 1);
- data.m_fHostUSBDevice = false;
- m_cache.m_items << data;
-
- /* Add new corresponding tree-widget-item to the tree-widget: */
- addUSBFilter(data, true /* its new? */);
- /* Mark filter's list as edited: */
- markSettingsChanged();
+ usbFilterData.m_fActive = true;
+ usbFilterData.m_strName = mUSBFilterName.arg(iMaxFilterIndex + 1);
+ usbFilterData.m_fHostUSBDevice = false;
+
+ /* Add new USB filter data: */
+ addUSBFilter(usbFilterData, true /* its new? */);
+
/* Revalidate if possible: */
if (mValidator)
mValidator->revalidate();
@@ -518,54 +607,47 @@ void UIMachineSettingsUSB::newClicked()
void UIMachineSettingsUSB::addClicked()
{
- mUSBDevicesMenu->exec (QCursor::pos());
+ mUSBDevicesMenu->exec(QCursor::pos());
}
-void UIMachineSettingsUSB::addConfirmed (QAction *aAction)
+void UIMachineSettingsUSB::addConfirmed(QAction *pAction)
{
/* Get USB device: */
- CUSBDevice usb = mUSBDevicesMenu->getUSB (aAction);
- /* if null then some other item but a USB device is selected */
+ CUSBDevice usb = mUSBDevicesMenu->getUSB(pAction);
if (usb.isNull())
return;
- /* Add new corresponding list item to the cache: */
- UIUSBFilterData data;
- switch (type())
+ /* Prepare new USB filter data: */
+ UIDataSettingsMachineUSBFilter usbFilterData;
+ switch (pageType())
{
case UISettingsPageType_Global:
- data.m_action = KUSBDeviceFilterAction_Hold;
- /* Check that under host (global) USB settings if they will be enabled! */
- data.m_fHostUSBDevice = false;
- break;
- case UISettingsPageType_Machine:
- data.m_fHostUSBDevice = false;
+ usbFilterData.m_action = KUSBDeviceFilterAction_Hold;
break;
default:
break;
}
- data.m_fActive = true;
- data.m_strName = vboxGlobal().details(usb);
- data.m_strVendorId = QString().sprintf("%04hX", usb.GetVendorId());
- data.m_strProductId = QString().sprintf("%04hX", usb.GetProductId());
- data.m_strRevision = QString().sprintf("%04hX", usb.GetRevision());
+ usbFilterData.m_fActive = true;
+ usbFilterData.m_strName = vboxGlobal().details(usb);
+ usbFilterData.m_fHostUSBDevice = false;
+ usbFilterData.m_strVendorId = QString().sprintf("%04hX", usb.GetVendorId());
+ usbFilterData.m_strProductId = QString().sprintf("%04hX", usb.GetProductId());
+ usbFilterData.m_strRevision = QString().sprintf("%04hX", usb.GetRevision());
/* The port property depends on the host computer rather than on the USB
* device itself; for this reason only a few people will want to use it
* in the filter since the same device plugged into a different socket
* will not match the filter in this case. */
#if 0
- data.m_strPort = QString().sprintf("%04hX", usb.GetPort());
+ usbFilterData.m_strPort = QString().sprintf("%04hX", usb.GetPort());
#endif
- data.m_strManufacturer = usb.GetManufacturer();
- data.m_strProduct = usb.GetProduct();
- data.m_strSerialNumber = usb.GetSerialNumber();
- data.m_strRemote = QString::number(usb.GetRemote());
- m_cache.m_items << data;
-
- /* Add new corresponding tree-widget-item to the tree-widget: */
- addUSBFilter(data, true /* its new? */);
- /* Mark filter's list as edited: */
- markSettingsChanged();
+ usbFilterData.m_strManufacturer = usb.GetManufacturer();
+ usbFilterData.m_strProduct = usb.GetProduct();
+ usbFilterData.m_strSerialNumber = usb.GetSerialNumber();
+ usbFilterData.m_strRemote = QString::number(usb.GetRemote());
+
+ /* Add new USB filter data: */
+ addUSBFilter(usbFilterData, true /* its new? */);
+
/* Revalidate if possible: */
if (mValidator)
mValidator->revalidate();
@@ -576,25 +658,25 @@ void UIMachineSettingsUSB::edtClicked()
/* Get current USB filter item: */
QTreeWidgetItem *pItem = mTwFilters->currentItem();
Assert(pItem);
- UIUSBFilterData &data = m_cache.m_items[mTwFilters->indexOfTopLevelItem(pItem)];
+ UIDataSettingsMachineUSBFilter &usbFilterData = m_filters[mTwFilters->indexOfTopLevelItem(pItem)];
/* Configure USB filter details dialog: */
- UIMachineSettingsUSBFilterDetails dlgFilterDetails(type(), this);
- dlgFilterDetails.mLeName->setText(data.m_strName);
- dlgFilterDetails.mLeVendorID->setText(data.m_strVendorId);
- dlgFilterDetails.mLeProductID->setText(data.m_strProductId);
- dlgFilterDetails.mLeRevision->setText(data.m_strRevision);
- dlgFilterDetails.mLePort->setText(data.m_strPort);
- dlgFilterDetails.mLeManufacturer->setText(data.m_strManufacturer);
- dlgFilterDetails.mLeProduct->setText(data.m_strProduct);
- dlgFilterDetails.mLeSerialNo->setText(data.m_strSerialNumber);
- switch (type())
+ UIMachineSettingsUSBFilterDetails dlgFilterDetails(pageType(), this);
+ dlgFilterDetails.mLeName->setText(usbFilterData.m_strName);
+ dlgFilterDetails.mLeVendorID->setText(usbFilterData.m_strVendorId);
+ dlgFilterDetails.mLeProductID->setText(usbFilterData.m_strProductId);
+ dlgFilterDetails.mLeRevision->setText(usbFilterData.m_strRevision);
+ dlgFilterDetails.mLePort->setText(usbFilterData.m_strPort);
+ dlgFilterDetails.mLeManufacturer->setText(usbFilterData.m_strManufacturer);
+ dlgFilterDetails.mLeProduct->setText(usbFilterData.m_strProduct);
+ dlgFilterDetails.mLeSerialNo->setText(usbFilterData.m_strSerialNumber);
+ switch (pageType())
{
case UISettingsPageType_Global:
{
- if (data.m_action == KUSBDeviceFilterAction_Ignore)
+ if (usbFilterData.m_action == KUSBDeviceFilterAction_Ignore)
dlgFilterDetails.mCbAction->setCurrentIndex(0);
- else if (data.m_action == KUSBDeviceFilterAction_Hold)
+ else if (usbFilterData.m_action == KUSBDeviceFilterAction_Hold)
dlgFilterDetails.mCbAction->setCurrentIndex(1);
else
AssertMsgFailed(("Invalid USBDeviceFilterAction type"));
@@ -602,7 +684,7 @@ void UIMachineSettingsUSB::edtClicked()
}
case UISettingsPageType_Machine:
{
- QString strRemote = data.m_strRemote.toLower();
+ QString strRemote = usbFilterData.m_strRemote.toLower();
if (strRemote == "yes" || strRemote == "true" || strRemote == "1")
dlgFilterDetails.mCbRemote->setCurrentIndex(ModeOn);
else if (strRemote == "no" || strRemote == "false" || strRemote == "0")
@@ -618,28 +700,28 @@ void UIMachineSettingsUSB::edtClicked()
/* Run USB filter details dialog: */
if (dlgFilterDetails.exec() == QDialog::Accepted)
{
- data.m_strName = dlgFilterDetails.mLeName->text().isEmpty() ? QString::null : dlgFilterDetails.mLeName->text();
- data.m_strVendorId = dlgFilterDetails.mLeVendorID->text().isEmpty() ? QString::null : dlgFilterDetails.mLeVendorID->text();
- data.m_strProductId = dlgFilterDetails.mLeProductID->text().isEmpty() ? QString::null : dlgFilterDetails.mLeProductID->text();
- data.m_strRevision = dlgFilterDetails.mLeRevision->text().isEmpty() ? QString::null : dlgFilterDetails.mLeRevision->text();
- data.m_strManufacturer = dlgFilterDetails.mLeManufacturer->text().isEmpty() ? QString::null : dlgFilterDetails.mLeManufacturer->text();
- data.m_strProduct = dlgFilterDetails.mLeProduct->text().isEmpty() ? QString::null : dlgFilterDetails.mLeProduct->text();
- data.m_strSerialNumber = dlgFilterDetails.mLeSerialNo->text().isEmpty() ? QString::null : dlgFilterDetails.mLeSerialNo->text();
- data.m_strPort = dlgFilterDetails.mLePort->text().isEmpty() ? QString::null : dlgFilterDetails.mLePort->text();
- switch (type())
+ usbFilterData.m_strName = dlgFilterDetails.mLeName->text().isEmpty() ? QString::null : dlgFilterDetails.mLeName->text();
+ usbFilterData.m_strVendorId = dlgFilterDetails.mLeVendorID->text().isEmpty() ? QString::null : dlgFilterDetails.mLeVendorID->text();
+ usbFilterData.m_strProductId = dlgFilterDetails.mLeProductID->text().isEmpty() ? QString::null : dlgFilterDetails.mLeProductID->text();
+ usbFilterData.m_strRevision = dlgFilterDetails.mLeRevision->text().isEmpty() ? QString::null : dlgFilterDetails.mLeRevision->text();
+ usbFilterData.m_strManufacturer = dlgFilterDetails.mLeManufacturer->text().isEmpty() ? QString::null : dlgFilterDetails.mLeManufacturer->text();
+ usbFilterData.m_strProduct = dlgFilterDetails.mLeProduct->text().isEmpty() ? QString::null : dlgFilterDetails.mLeProduct->text();
+ usbFilterData.m_strSerialNumber = dlgFilterDetails.mLeSerialNo->text().isEmpty() ? QString::null : dlgFilterDetails.mLeSerialNo->text();
+ usbFilterData.m_strPort = dlgFilterDetails.mLePort->text().isEmpty() ? QString::null : dlgFilterDetails.mLePort->text();
+ switch (pageType())
{
case UISettingsPageType_Global:
{
- data.m_action = vboxGlobal().toUSBDevFilterAction(dlgFilterDetails.mCbAction->currentText());
+ usbFilterData.m_action = vboxGlobal().toUSBDevFilterAction(dlgFilterDetails.mCbAction->currentText());
break;
}
case UISettingsPageType_Machine:
{
switch (dlgFilterDetails.mCbRemote->currentIndex())
{
- case ModeAny: data.m_strRemote = QString(); break;
- case ModeOn: data.m_strRemote = QString::number(1); break;
- case ModeOff: data.m_strRemote = QString::number(0); break;
+ case ModeAny: usbFilterData.m_strRemote = QString(); break;
+ case ModeOn: usbFilterData.m_strRemote = QString::number(1); break;
+ case ModeOff: usbFilterData.m_strRemote = QString::number(0); break;
default: AssertMsgFailed(("Invalid combo box index"));
}
break;
@@ -647,10 +729,8 @@ void UIMachineSettingsUSB::edtClicked()
default:
break;
}
- pItem->setText(0, data.m_strName);
- pItem->setToolTip(0, toolTipFor(data));
- /* Mark filter's list as edited: */
- markSettingsChanged();
+ pItem->setText(0, usbFilterData.m_strName);
+ pItem->setToolTip(0, toolTipFor(usbFilterData));
}
}
@@ -661,13 +741,11 @@ void UIMachineSettingsUSB::delClicked()
Assert(pItem);
/* Delete corresponding items: */
- m_cache.m_items.removeAt(mTwFilters->indexOfTopLevelItem(pItem));
+ m_filters.removeAt(mTwFilters->indexOfTopLevelItem(pItem));
delete pItem;
/* Update current item: */
currentChanged(mTwFilters->currentItem());
- /* Mark filter's list as edited: */
- markSettingsChanged();
/* Revalidate if possible: */
if (!mTwFilters->topLevelItemCount())
{
@@ -688,10 +766,9 @@ void UIMachineSettingsUSB::mupClicked()
QTreeWidgetItem *takenItem = mTwFilters->takeTopLevelItem (index);
Assert (item == takenItem);
mTwFilters->insertTopLevelItem (index - 1, takenItem);
- m_cache.m_items.swap (index, index - 1);
+ m_filters.swap (index, index - 1);
mTwFilters->setCurrentItem (takenItem);
- markSettingsChanged();
}
void UIMachineSettingsUSB::mdnClicked()
@@ -703,15 +780,28 @@ void UIMachineSettingsUSB::mdnClicked()
QTreeWidgetItem *takenItem = mTwFilters->takeTopLevelItem (index);
Assert (item == takenItem);
mTwFilters->insertTopLevelItem (index + 1, takenItem);
- m_cache.m_items.swap (index, index + 1);
+ m_filters.swap (index, index + 1);
mTwFilters->setCurrentItem (takenItem);
- markSettingsChanged();
}
-void UIMachineSettingsUSB::showContextMenu (const QPoint &aPos)
+void UIMachineSettingsUSB::showContextMenu(const QPoint &pos)
{
- mMenu->exec (mTwFilters->mapToGlobal (aPos));
+ QMenu menu;
+ if (mTwFilters->isEnabled())
+ {
+ menu.addAction(mNewAction);
+ menu.addAction(mAddAction);
+ menu.addSeparator();
+ menu.addAction(mEdtAction);
+ menu.addSeparator();
+ menu.addAction(mDelAction);
+ menu.addSeparator();
+ menu.addAction(mMupAction);
+ menu.addAction(mMdnAction);
+ }
+ if (!menu.isEmpty())
+ menu.exec(mTwFilters->mapToGlobal(pos));
}
void UIMachineSettingsUSB::sltUpdateActivityState(QTreeWidgetItem *pChangedItem)
@@ -720,24 +810,20 @@ void UIMachineSettingsUSB::sltUpdateActivityState(QTreeWidgetItem *pChangedItem)
Assert(pChangedItem);
/* Delete corresponding items: */
- UIUSBFilterData &data = m_cache.m_items[mTwFilters->indexOfTopLevelItem(pChangedItem)];
+ UIDataSettingsMachineUSBFilter &data = m_filters[mTwFilters->indexOfTopLevelItem(pChangedItem)];
data.m_fActive = pChangedItem->checkState(0) == Qt::Checked;
-
- markSettingsChanged();
}
-void UIMachineSettingsUSB::markSettingsChanged()
+void UIMachineSettingsUSB::addUSBFilter(const UIDataSettingsMachineUSBFilter &usbFilterData, bool fIsNew)
{
- mUSBFilterListModified = true;
-}
+ /* Append internal list with data: */
+ m_filters << usbFilterData;
-void UIMachineSettingsUSB::addUSBFilter(const UIUSBFilterData &data, bool fIsNew)
-{
/* Append tree-widget with item: */
QTreeWidgetItem *pItem = new QTreeWidgetItem;
- pItem->setCheckState(0, data.m_fActive ? Qt::Checked : Qt::Unchecked);
- pItem->setText(0, data.m_strName);
- pItem->setToolTip(0, toolTipFor(data));
+ pItem->setCheckState(0, usbFilterData.m_fActive ? Qt::Checked : Qt::Unchecked);
+ pItem->setText(0, usbFilterData.m_strName);
+ pItem->setToolTip(0, toolTipFor(usbFilterData));
mTwFilters->addTopLevelItem(pItem);
/* Select this item if its new: */
@@ -745,10 +831,10 @@ void UIMachineSettingsUSB::addUSBFilter(const UIUSBFilterData &data, bool fIsNew
mTwFilters->setCurrentItem(pItem);
}
-/* Fetch data to m_properties & m_settings or m_machine: */
+/* Fetch data to m_properties & m_settings or m_machine & m_console: */
void UIMachineSettingsUSB::fetchData(const QVariant &data)
{
- switch (type())
+ switch (pageType())
{
case UISettingsPageType_Global:
{
@@ -759,6 +845,7 @@ void UIMachineSettingsUSB::fetchData(const QVariant &data)
case UISettingsPageType_Machine:
{
m_machine = data.value<UISettingsDataMachine>().m_machine;
+ m_console = data.value<UISettingsDataMachine>().m_console;
break;
}
default:
@@ -766,10 +853,10 @@ void UIMachineSettingsUSB::fetchData(const QVariant &data)
}
}
-/* Upload m_properties & m_settings or m_machine to data: */
+/* Upload m_properties & m_settings or m_machine & m_console to data: */
void UIMachineSettingsUSB::uploadData(QVariant &data) const
{
- switch (type())
+ switch (pageType())
{
case UISettingsPageType_Global:
{
@@ -778,7 +865,7 @@ void UIMachineSettingsUSB::uploadData(QVariant &data) const
}
case UISettingsPageType_Machine:
{
- data = QVariant::fromValue(UISettingsDataMachine(m_machine));
+ data = QVariant::fromValue(UISettingsDataMachine(m_machine, m_console));
break;
}
default:
@@ -786,46 +873,54 @@ void UIMachineSettingsUSB::uploadData(QVariant &data) const
}
}
-/* static */ QString UIMachineSettingsUSB::toolTipFor(const UIUSBFilterData &data)
+/* static */
+QString UIMachineSettingsUSB::toolTipFor(const UIDataSettingsMachineUSBFilter &usbFilterData)
{
/* Prepare tool-tip: */
QString strToolTip;
- QString strVendorId = data.m_strVendorId;
+ QString strVendorId = usbFilterData.m_strVendorId;
if (!strVendorId.isEmpty())
strToolTip += tr("<nobr>Vendor ID: %1</nobr>", "USB filter tooltip").arg(strVendorId);
- QString strProductId = data.m_strProductId;
+ QString strProductId = usbFilterData.m_strProductId;
if (!strProductId.isEmpty())
strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product ID: %2</nobr>", "USB filter tooltip").arg(strProductId);
- QString strRevision = data.m_strRevision;
+ QString strRevision = usbFilterData.m_strRevision;
if (!strRevision.isEmpty())
strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Revision: %3</nobr>", "USB filter tooltip").arg(strRevision);
- QString strProduct = data.m_strProduct;
+ QString strProduct = usbFilterData.m_strProduct;
if (!strProduct.isEmpty())
strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product: %4</nobr>", "USB filter tooltip").arg(strProduct);
- QString strManufacturer = data.m_strManufacturer;
+ QString strManufacturer = usbFilterData.m_strManufacturer;
if (!strManufacturer.isEmpty())
strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Manufacturer: %5</nobr>", "USB filter tooltip").arg(strManufacturer);
- QString strSerial = data.m_strSerialNumber;
+ QString strSerial = usbFilterData.m_strSerialNumber;
if (!strSerial.isEmpty())
strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Serial No.: %1</nobr>", "USB filter tooltip").arg(strSerial);
- QString strPort = data.m_strPort;
+ QString strPort = usbFilterData.m_strPort;
if (!strPort.isEmpty())
strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Port: %1</nobr>", "USB filter tooltip").arg(strPort);
/* Add the state field if it's a host USB device: */
- if (data.m_fHostUSBDevice)
+ if (usbFilterData.m_fHostUSBDevice)
{
strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>State: %1</nobr>", "USB filter tooltip")
- .arg(vboxGlobal().toString(data.m_hostUSBDeviceState));
+ .arg(vboxGlobal().toString(usbFilterData.m_hostUSBDeviceState));
}
return strToolTip;
}
+void UIMachineSettingsUSB::polishPage()
+{
+ mGbUSB->setEnabled(isMachineOffline());
+ mUSBChild->setEnabled(isMachineInValidMode() && mGbUSB->isChecked());
+ mCbUSB2->setEnabled(isMachineOffline() && mGbUSB->isChecked());
+}
+
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.h b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.h
index 8e9665fbe..16be789fb 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.h
@@ -5,7 +5,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;
@@ -24,11 +24,45 @@
#include "COMDefs.h"
class VBoxUSBMenu;
+class UIToolBar;
-/* Common settings / USB page / Filter data: */
-struct UIUSBFilterData
+/* Common settings / USB page / USB filter data: */
+struct UIDataSettingsMachineUSBFilter
{
- /* Common: */
+ /* Default constructor: */
+ UIDataSettingsMachineUSBFilter()
+ : m_fActive(false)
+ , m_strName(QString())
+ , m_strVendorId(QString())
+ , m_strProductId(QString())
+ , m_strRevision(QString())
+ , m_strManufacturer(QString())
+ , m_strProduct(QString())
+ , m_strSerialNumber(QString())
+ , m_strPort(QString())
+ , m_strRemote(QString())
+ , m_action(KUSBDeviceFilterAction_Null)
+ , m_hostUSBDeviceState(KUSBDeviceState_NotSupported) {}
+ /* Functions: */
+ bool equal(const UIDataSettingsMachineUSBFilter &other) const
+ {
+ return (m_fActive == other.m_fActive) &&
+ (m_strName == other.m_strName) &&
+ (m_strVendorId == other.m_strVendorId) &&
+ (m_strProductId == other.m_strProductId) &&
+ (m_strRevision == other.m_strRevision) &&
+ (m_strManufacturer == other.m_strManufacturer) &&
+ (m_strProduct == other.m_strProduct) &&
+ (m_strSerialNumber == other.m_strSerialNumber) &&
+ (m_strPort == other.m_strPort) &&
+ (m_strRemote == other.m_strRemote) &&
+ (m_action == other.m_action) &&
+ (m_hostUSBDeviceState == other.m_hostUSBDeviceState);
+ }
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineUSBFilter &other) const { return equal(other); }
+ bool operator!=(const UIDataSettingsMachineUSBFilter &other) const { return !equal(other); }
+ /* Common variables: */
bool m_fActive;
QString m_strName;
QString m_strVendorId;
@@ -39,20 +73,34 @@ struct UIUSBFilterData
QString m_strSerialNumber;
QString m_strPort;
QString m_strRemote;
-
- /* Host only: */
+ /* Host only variables: */
KUSBDeviceFilterAction m_action;
bool m_fHostUSBDevice;
KUSBDeviceState m_hostUSBDeviceState;
};
+typedef UISettingsCache<UIDataSettingsMachineUSBFilter> UICacheSettingsMachineUSBFilter;
-/* Common settings / USB page / Cache: */
-struct UISettingsCacheCommonUSB
+/* Common settings / USB page / USB data: */
+struct UIDataSettingsMachineUSB
{
+ /* Default constructor: */
+ UIDataSettingsMachineUSB()
+ : m_fUSBEnabled(false)
+ , m_fEHCIEnabled(false) {}
+ /* Functions: */
+ bool equal(const UIDataSettingsMachineUSB &other) const
+ {
+ return (m_fUSBEnabled == other.m_fUSBEnabled) &&
+ (m_fEHCIEnabled == other.m_fEHCIEnabled);
+ }
+ /* Operators: */
+ bool operator==(const UIDataSettingsMachineUSB &other) const { return equal(other); }
+ bool operator!=(const UIDataSettingsMachineUSB &other) const { return !equal(other); }
+ /* Variables: */
bool m_fUSBEnabled;
bool m_fEHCIEnabled;
- QList<UIUSBFilterData> m_items;
};
+typedef UISettingsCachePool<UIDataSettingsMachineUSB, UICacheSettingsMachineUSBFilter> UICacheSettingsMachineUSB;
/* Common settings / USB page: */
class UIMachineSettingsUSB : public UISettingsPage,
@@ -89,6 +137,9 @@ protected:
* this task COULD be performed in other than GUI thread: */
void saveFromCacheTo(QVariant &data);
+ /* Page changed: */
+ bool changed() const { return m_cache.wasChanged(); }
+
void setValidator (QIWidgetValidator *aVal);
bool revalidate(QString &strWarningText, QString &strTitle);
@@ -98,9 +149,8 @@ protected:
private slots:
- void usbAdapterToggled (bool aOn);
- void currentChanged (QTreeWidgetItem *aItem = 0,
- QTreeWidgetItem *aPrev = 0);
+ void usbAdapterToggled(bool fEnabled);
+ void currentChanged (QTreeWidgetItem *aItem = 0);
void newClicked();
void addClicked();
@@ -109,13 +159,12 @@ private slots:
void delClicked();
void mupClicked();
void mdnClicked();
- void showContextMenu (const QPoint &aPos);
+ void showContextMenu(const QPoint &pos);
void sltUpdateActivityState(QTreeWidgetItem *pChangedItem);
- void markSettingsChanged();
private:
- void addUSBFilter(const UIUSBFilterData &data, bool fIsNew);
+ void addUSBFilter(const UIDataSettingsMachineUSBFilter &usbFilterData, bool fIsNew);
/* Fetch data to m_properties, m_settings or m_machine: */
void fetchData(const QVariant &data);
@@ -124,7 +173,9 @@ private:
void uploadData(QVariant &data) const;
/* Returns the multi-line description of the given USB filter: */
- static QString toolTipFor(const UIUSBFilterData &data);
+ static QString toolTipFor(const UIDataSettingsMachineUSBFilter &data);
+
+ void polishPage();
/* Global data source: */
CSystemProperties m_properties;
@@ -132,22 +183,23 @@ private:
/* Machine data source: */
CMachine m_machine;
+ CConsole m_console;
/* Other variables: */
QIWidgetValidator *mValidator;
+ UIToolBar *m_pToolBar;
QAction *mNewAction;
QAction *mAddAction;
QAction *mEdtAction;
QAction *mDelAction;
QAction *mMupAction;
QAction *mMdnAction;
- QMenu *mMenu;
VBoxUSBMenu *mUSBDevicesMenu;
- bool mUSBFilterListModified;
QString mUSBFilterName;
+ QList<UIDataSettingsMachineUSBFilter> m_filters;
/* Cache: */
- UISettingsCacheCommonUSB m_cache;
+ UICacheSettingsMachineUSB m_cache;
};
#endif // __UIMachineSettingsUSB_h__
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.ui b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.ui
index 5a008cf7c..939235709 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.ui
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.ui
@@ -139,22 +139,5 @@
</customwidget>
</customwidgets>
<resources/>
- <connections>
- <connection>
- <sender>mGbUSB</sender>
- <signal>toggled(bool)</signal>
- <receiver>mUSBChild</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>233</x>
- <y>19</y>
- </hint>
- <hint type="destinationlabel" >
- <x>246</x>
- <y>177</y>
- </hint>
- </hints>
- </connection>
- </connections>
+ <connections/>
</ui>
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSBFilterDetails.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSBFilterDetails.cpp
index f9602283b..b2b59c34b 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSBFilterDetails.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSBFilterDetails.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIMachineSettingsUSBFilterDetails.cpp $ */
+/* $Id: UIMachineSettingsUSBFilterDetails.cpp 33882 2010-11-09 09:32:27Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/UIBar.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/UIBar.cpp
index 5fe7f4b28..459f90427 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/UIBar.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/UIBar.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIBar.cpp $ */
+/* $Id: UIBar.cpp 35424 2011-01-07 13:05:41Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/UIBootTable.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/UIBootTable.cpp
index bdfdca1c7..77792d83e 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/UIBootTable.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/UIBootTable.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIBootTable.cpp $ */
+/* $Id: UIBootTable.cpp 34614 2010-12-02 14:09:47Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.cpp
index b31a92aee..c633b852d 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIDownloader.cpp $ */
+/* $Id: UIDownloader.cpp 37544 2011-06-17 13:54:47Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
@@ -6,7 +6,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;
@@ -23,6 +23,7 @@
#include "VBoxGlobal.h"
#include "VBoxProblemReporter.h"
#include "UISpecialControls.h"
+#include "VBoxUtils.h"
/* Global includes */
#include <QFile>
@@ -149,12 +150,25 @@ void UIDownloader::startDownload()
* checking file presence & size */
void UIDownloader::acknowledgeStart()
{
+ /* Recreate HTTP: */
delete m_pHttp;
- m_pHttp = new QIHttp(this, m_source.host());
+ m_pHttp = new QIHttp(this);
+ /* Setup HTTP proxy: */
+ UIProxyManager proxyManager(vboxGlobal().settings().proxySettings());
+ if (proxyManager.proxyEnabled())
+ {
+ m_pHttp->setProxy(proxyManager.proxyHost(), proxyManager.proxyPort().toInt(),
+ proxyManager.authEnabled() ? proxyManager.authLogin() : QString(),
+ proxyManager.authEnabled() ? proxyManager.authPassword() : QString());
+ }
+ /* Set HTTP host: */
+ m_pHttp->setHost(m_source.host());
+ /* Setup connections: */
connect(m_pHttp, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
this, SLOT(acknowledgeProcess(const QHttpResponseHeader &)));
connect(m_pHttp, SIGNAL(allIsDone(bool)),
this, SLOT(acknowledgeFinished(bool)));
+ /* Make a request: */
m_pHttp->get(m_source.toEncoded());
}
@@ -205,12 +219,25 @@ void UIDownloader::acknowledgeFinished(bool /* fError */)
* downloading and saving the target */
void UIDownloader::downloadStart()
{
+ /* Recreate HTTP: */
delete m_pHttp;
- m_pHttp = new QIHttp(this, m_source.host());
+ m_pHttp = new QIHttp(this);
+ /* Setup HTTP proxy: */
+ UIProxyManager proxyManager(vboxGlobal().settings().proxySettings());
+ if (proxyManager.proxyEnabled())
+ {
+ m_pHttp->setProxy(proxyManager.proxyHost(), proxyManager.proxyPort().toInt(),
+ proxyManager.authEnabled() ? proxyManager.authLogin() : QString(),
+ proxyManager.authEnabled() ? proxyManager.authPassword() : QString());
+ }
+ /* Set HTTP host: */
+ m_pHttp->setHost(m_source.host());
+ /* Setup connections: */
connect(m_pHttp, SIGNAL(dataReadProgress (int, int)),
this, SLOT (downloadProcess(int, int)));
connect(m_pHttp, SIGNAL(allIsDone(bool)),
this, SLOT(downloadFinished(bool)));
+ /* Make a request: */
m_pHttp->get(m_source.toEncoded());
}
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.cpp
index 88b6c89a6..127979b83 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIDownloaderAdditions.cpp $ */
+/* $Id: UIDownloaderAdditions.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderUserManual.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderUserManual.cpp
index 701b96d61..b027891e3 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderUserManual.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderUserManual.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIDownloaderUserManual.cpp $ */
+/* $Id: UIDownloaderUserManual.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/UIHotKeyEditor.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/UIHotKeyEditor.cpp
index 7c0317549..ca0a5b678 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/UIHotKeyEditor.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/UIHotKeyEditor.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIHotKeyEditor.cpp $ */
+/* $Id: UIHotKeyEditor.cpp 35862 2011-02-07 08:57:38Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/UIPopupBox.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/UIPopupBox.cpp
index 31b8bae12..1c552fc68 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/UIPopupBox.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/UIPopupBox.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIPopupBox.cpp $ */
+/* $Id: UIPopupBox.cpp 30904 2010-07-19 09:43:24Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/UIProgressDialog.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/UIProgressDialog.cpp
index 03aad59dd..2d43f5d30 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/UIProgressDialog.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/UIProgressDialog.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIProgressDialog.cpp $ */
+/* $Id: UIProgressDialog.cpp 37572 2011-06-21 11:37:31Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/UISpecialControls.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/UISpecialControls.cpp
index 85233ecfb..353c9a5a0 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/UISpecialControls.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/UISpecialControls.cpp
@@ -1,4 +1,4 @@
-/* $Id: UISpecialControls.cpp $ */
+/* $Id: UISpecialControls.cpp 30694 2010-07-07 09:24:18Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.cpp
index 1e19b273c..805bcde54 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxApplianceEditorWgt.cpp $ */
+/* $Id: VBoxApplianceEditorWgt.cpp 37862 2011-07-11 10:09:29Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -1087,6 +1087,9 @@ VBoxApplianceEditorWgt::VBoxApplianceEditorWgt (QWidget *aParent /* = NULL */)
mTvSettings->header()->setStretchLastSection (true);
mTvSettings->header()->setResizeMode (QHeaderView::ResizeToContents);
+ /* Hidden by default */
+ mReinitMACsCheckBox->setHidden(true);
+
/* Applying language settings */
retranslateUi();
}
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.ui b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.ui
index 5024cec49..d70726ad3 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.ui
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.ui
@@ -9,7 +9,7 @@
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
+ Foundation, in version 2 as it comes in the &quot;COPYING&quot; 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.
</comment>
@@ -19,8 +19,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>459</width>
- <height>305</height>
+ <width>548</width>
+ <height>411</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
@@ -38,6 +38,16 @@
</widget>
</item>
<item>
+ <widget class="QCheckBox" name="mReinitMACsCheckBox">
+ <property name="toolTip">
+ <string>When checked a new unique MAC address will assigned to all configured network cards.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Reinitialize the MAC address of all network cards</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QWidget" name="mWarningWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
@@ -46,9 +56,6 @@
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
- </property>
<property name="margin">
<number>0</number>
</property>
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxExportApplianceWgt.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxExportApplianceWgt.cpp
index a4c06b202..be2a3359b 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxExportApplianceWgt.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxExportApplianceWgt.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxExportApplianceWgt.cpp $ */
+/* $Id: VBoxExportApplianceWgt.cpp 29986 2010-06-02 12:30:38Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxFilePathSelectorWidget.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxFilePathSelectorWidget.cpp
index 8f951835c..e16221b11 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxFilePathSelectorWidget.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxFilePathSelectorWidget.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxFilePathSelectorWidget.cpp $ */
+/* $Id: VBoxFilePathSelectorWidget.cpp 33778 2010-11-04 15:25:25Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp
index c194e4742..964c69d49 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxGuestRAMSlider.cpp $ */
+/* $Id: VBoxGuestRAMSlider.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxImportApplianceWgt.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxImportApplianceWgt.cpp
index 223a53edc..acd6a4b63 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxImportApplianceWgt.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxImportApplianceWgt.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxImportApplianceWgt.cpp $ */
+/* $Id: VBoxImportApplianceWgt.cpp 37862 2011-07-11 10:09:29Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -41,6 +41,8 @@ public:
VBoxImportApplianceWgt::VBoxImportApplianceWgt (QWidget *aParent)
: VBoxApplianceEditorWgt (aParent)
{
+ /* Show the MAC check box */
+ mReinitMACsCheckBox->setHidden(false);
}
bool VBoxImportApplianceWgt::setFile (const QString& aFile)
@@ -133,7 +135,10 @@ bool VBoxImportApplianceWgt::import()
{
/* Start the import asynchronously */
CProgress progress;
- progress = mAppliance->ImportMachines();
+ QVector<KImportOptions> options;
+ if (!mReinitMACsCheckBox->isChecked())
+ options.append(KImportOptions_KeepAllMACs);
+ progress = mAppliance->ImportMachines(options);
bool fResult = mAppliance->isOk();
if (fResult)
{
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxLineTextEdit.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxLineTextEdit.cpp
index 8dea6f915..69d234b04 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxLineTextEdit.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxLineTextEdit.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxLineTextEdit.cpp $ */
+/* $Id: VBoxLineTextEdit.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.cpp
index 382711d48..607a5524b 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxMediaComboBox.cpp $ */
+/* $Id: VBoxMediaComboBox.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.cpp
index 703485ee7..6cbac2bcb 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxMiniToolBar.cpp $ */
+/* $Id: VBoxMiniToolBar.cpp 35867 2011-02-07 12:51:10Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorButton.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorButton.cpp
index 6253d4c62..745838c00 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorButton.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorButton.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxOSTypeSelectorButton.cpp $ */
+/* $Id: VBoxOSTypeSelectorButton.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp
index 7d453c8a6..b1dcc7624 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxOSTypeSelectorWidget.cpp $ */
+/* $Id: VBoxOSTypeSelectorWidget.cpp 33781 2010-11-04 15:59:35Z vboxsync $ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxWarningPane.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxWarningPane.cpp
index ba85fdbd5..d24970a01 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxWarningPane.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxWarningPane.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxWarningPane.cpp $ */
+/* $Id: VBoxWarningPane.cpp 37106 2011-05-16 14:50:12Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-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;
@@ -31,16 +31,15 @@ VBoxWarningPane::VBoxWarningPane(QWidget *pParent)
VBoxGlobal::setLayoutMargin(pLayout, 0);
pLayout->addWidget(&m_icon);
pLayout->addWidget(&m_label);
- setVisible(false);
}
void VBoxWarningPane::setWarningPixmap(const QPixmap &imgPixmap)
{
- m_icon.setPixmap (imgPixmap);
+ m_icon.setPixmap(imgPixmap);
}
void VBoxWarningPane::setWarningText(const QString &strText)
{
- m_label.setText (strText);
+ m_label.setText(strText);
}
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Filter/Makefile.kup b/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/Makefile.kup
index e69de29bb..e69de29bb 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/Filter/Makefile.kup
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/Makefile.kup
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.cpp b/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.cpp
new file mode 100644
index 000000000..a45361edc
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.cpp
@@ -0,0 +1,268 @@
+/* $Id: UICloneVMWizard.cpp 38055 2011-07-19 08:55:42Z vboxsync $ */
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * UICloneVMWizard class implementation
+ */
+
+/*
+ * 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.
+ */
+
+/* Global includes: */
+#include <QCheckBox>
+#include <QRadioButton>
+#include <QRegExpValidator>
+
+/* Local includes: */
+#include "VBoxGlobal.h"
+#include "VBoxProblemReporter.h"
+#include "QIFileDialog.h"
+#include "UIIconPool.h"
+#include "UICloneVMWizard.h"
+#include "iprt/path.h"
+
+UICloneVMWizard::UICloneVMWizard(QWidget *pParent, CMachine machine, bool fShowChildsOption /* = true */)
+ : QIWizard(pParent)
+ , m_machine(machine)
+{
+ /* Create & add pages: */
+ addPage(new UICloneVMWizardPage1(machine.GetName()));
+ /* If the machine has no snapshots, we don't bother the user about options
+ * for it. */
+ if (machine.GetSnapshotCount() > 0)
+// addPage(new UICloneVMWizardPage2(fShowChildsOption));
+ addPage(new UICloneVMWizardPage2(false));
+
+ /* Translate wizard: */
+ retranslateUi();
+
+ /* Translate wizard pages: */
+ retranslateAllPages();
+
+ /* Resize wizard to 'golden ratio': */
+ resizeToGoldenRatio();
+
+#ifdef Q_WS_MAC
+ setMinimumSize(QSize(600, 400));
+ /* Assign background image: */
+ assignBackground(":/vmw_clone_bg.png");
+#else /* Q_WS_MAC */
+ /* Assign watermark: */
+ assignWatermark(":/vmw_clone.png");
+#endif /* Q_WS_MAC */
+}
+
+void UICloneVMWizard::retranslateUi()
+{
+ /* Assign wizard title: */
+ setWindowTitle(tr("Clone a virtual machine"));
+
+ setButtonText(QWizard::FinishButton, tr("Clone"));
+}
+
+bool UICloneVMWizard::createClone(const QString &strName, KCloneMode mode, bool fReinitMACs)
+{
+ CVirtualBox vbox = vboxGlobal().virtualBox();
+ const QString &strSettingsFile = vbox.ComposeMachineFilename(strName, QString::null);
+
+ /* Create a new machine object. */
+ CMachine cloneMachine = vbox.CreateMachine(strSettingsFile, strName, QString::null, QString::null, false);
+ if (!vbox.isOk())
+ {
+ vboxProblem().cannotCreateMachine(vbox, this);
+ return false;
+ }
+
+ /* Add the keep all MACs option to the import settings when requested. */
+ QVector<KCloneOptions> options;
+ if (!fReinitMACs)
+ options.append(KCloneOptions_KeepAllMACs);
+
+ /* Start cloning. */
+ CProgress progress = m_machine.CloneTo(cloneMachine, mode, options);
+ if (!m_machine.isOk())
+ {
+ vboxProblem().cannotCreateClone(m_machine, this);
+ return false;
+ }
+
+ /* Wait until done. */
+ vboxProblem().showModalProgressDialog(progress, windowTitle(), ":/progress_clone_90px.png", this, true);
+ if (progress.GetCanceled())
+ return false;
+ if (!progress.isOk() || progress.GetResultCode() != 0)
+ {
+ vboxProblem().cannotCreateClone(m_machine, progress, this);
+ return false;
+ }
+
+ /* Finally register the clone machine. */
+ vbox.RegisterMachine(cloneMachine);
+ if (!vbox.isOk())
+ {
+ vboxProblem().cannotRegisterMachine(vbox, m_machine, this);
+ return false;
+ }
+
+ return true;
+}
+
+UICloneVMWizardPage1::UICloneVMWizardPage1(const QString &strOriName)
+ : m_strOriName(strOriName)
+{
+ /* Decorate page: */
+ Ui::UICloneVMWizardPage1::setupUi(this);
+
+ registerField("cloneName", this, "cloneName");
+ registerField("reinitMACs", this, "reinitMACs");
+
+ connect(m_pNameEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltNameEditorTextChanged(const QString &)));
+}
+
+QString UICloneVMWizardPage1::cloneName() const
+{
+ return m_pNameEditor->text();
+}
+
+void UICloneVMWizardPage1::setCloneName(const QString &strName)
+{
+ m_pNameEditor->setText(strName);
+}
+
+bool UICloneVMWizardPage1::isReinitMACsChecked() const
+{
+ return mReinitMACsCheckBox->isChecked();
+}
+
+void UICloneVMWizardPage1::retranslateUi()
+{
+ /* Translate uic generated strings: */
+ Ui::UICloneVMWizardPage1::retranslateUi(this);
+
+ /* Set 'Page1' page title: */
+ setTitle(tr("Welcome to the virtual machine clone wizard"));
+
+ /* Append page text with common part: */
+ QString strCommonPart = QString("<p>%1</p>").arg(standardHelpText());
+ m_pLabel->setText(m_pLabel->text() + strCommonPart);
+}
+
+void UICloneVMWizardPage1::initializePage()
+{
+ /* Retranslate page: */
+ retranslateUi();
+
+ m_pNameEditor->setText(tr("%1 Clone").arg(m_strOriName));
+}
+
+bool UICloneVMWizardPage1::isComplete() const
+{
+ QString strName = m_pNameEditor->text().trimmed();
+ return !strName.isEmpty() && strName != m_strOriName;
+}
+
+bool UICloneVMWizardPage1::validatePage()
+{
+ if (isFinalPage())
+ {
+ /* Start performing long-time operation: */
+ startProcessing();
+ /* Try to create the clone: */
+ bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(cloneName(), KCloneMode_MachineState, isReinitMACsChecked());
+ /* Finish performing long-time operation: */
+ endProcessing();
+ /* Return operation result: */
+ return fResult;
+ }else
+ return true;
+}
+
+void UICloneVMWizardPage1::sltNameEditorTextChanged(const QString & /* strText */)
+{
+ /* Notify wizard sub-system about complete status changed: */
+ emit completeChanged();
+}
+
+UICloneVMWizardPage2::UICloneVMWizardPage2(bool fShowChildsOption /* = true */)
+ : m_fShowChildsOption(fShowChildsOption)
+{
+ /* Decorate page: */
+ Ui::UICloneVMWizardPage2::setupUi(this);
+
+ if (!fShowChildsOption)
+ m_pMachineAndChildsRadio->hide();
+}
+
+void UICloneVMWizardPage2::retranslateUi()
+{
+ /* Translate uic generated strings: */
+ Ui::UICloneVMWizardPage2::retranslateUi(this);
+
+ /* Set 'Page2' page title: */
+ setTitle(tr("Cloning Configuration"));
+
+ const QString strGeneral = tr("Please choose which parts of the virtual machine should be cloned.");
+ const QString strOpt1 = tr("If you select <b>Current machine state</b>, only the current state of the virtual machine is cloned.");
+ const QString strOpt2 = tr("If you select <b>Current machine and all child states</b> the current state of the virtual machine and any states of child snapshots are cloned.");
+ const QString strOpt3 = tr("If you select <b>All states</b>, the current machine state and all snapshots are cloned.");
+ if (m_fShowChildsOption)
+ m_pLabel->setText(QString("<p>%1</p><p>%2 %3 %4</p>")
+ .arg(strGeneral)
+ .arg(strOpt1)
+ .arg(strOpt2)
+ .arg(strOpt3));
+ else
+ m_pLabel->setText(QString("<p>%1</p><p>%2 %3</p>")
+ .arg(strGeneral)
+ .arg(strOpt1)
+ .arg(strOpt3));
+}
+
+void UICloneVMWizardPage2::initializePage()
+{
+ /* Retranslate page: */
+ retranslateUi();
+}
+
+bool UICloneVMWizardPage2::validatePage()
+{
+ /* Start performing long-time operation: */
+ startProcessing();
+ /* Try to create the clone: */
+ QString strName = field("cloneName").toString();
+ bool fReinitMACs = field("reinitMACs").toBool();
+ bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(strName, cloneMode(), fReinitMACs);
+ /* Finish performing long-time operation: */
+ endProcessing();
+ /* Return operation result: */
+ return fResult;
+}
+
+KCloneMode UICloneVMWizardPage2::cloneMode() const
+{
+ if (m_pMachineRadio->isChecked())
+ return KCloneMode_MachineState;
+ else if (m_pMachineAndChildsRadio->isChecked())
+ return KCloneMode_MachineAndChildStates;
+ return KCloneMode_AllStates;
+}
+
+void UICloneVMWizardPage2::setCloneMode(KCloneMode mode)
+{
+ switch(mode)
+ {
+ case KCloneMode_MachineState: m_pMachineRadio->setChecked(true); break;
+ case KCloneMode_MachineAndChildStates: m_pMachineAndChildsRadio->setChecked(true); break;
+ case KCloneMode_AllStates: m_pAllRadio->setChecked(true); break;
+ }
+}
+
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.h b/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.h
new file mode 100644
index 000000000..18b95e959
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.h
@@ -0,0 +1,136 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * UICloneVMWizard class declaration
+ */
+
+/*
+ * 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 __UICloneVMWizard_h__
+#define __UICloneVMWizard_h__
+
+/* Local includes: */
+#include "QIWizard.h"
+#include "COMDefs.h"
+
+/* Generated includes: */
+#include "UICloneVMWizardPage1.gen.h"
+#include "UICloneVMWizardPage2.gen.h"
+
+/* Clone vm wizard class: */
+class UICloneVMWizard : public QIWizard
+{
+ Q_OBJECT;
+
+public:
+
+ /* Constructor: */
+ UICloneVMWizard(QWidget *pParent, CMachine machine, bool fShowChildsOption = true);
+
+ bool createClone(const QString &strName, KCloneMode mode, bool fReinitMACs);
+
+private:
+
+ /* Translation stuff: */
+ void retranslateUi();
+
+ /* Private member vars */
+ CMachine m_machine;
+};
+
+/* Base wrapper for the wizard page
+ * of the new clonevm wizard class: */
+class UICloneVMWizardPage : public QIWizardPage
+{
+ Q_OBJECT;
+
+public:
+
+ /* Constructor: */
+ UICloneVMWizardPage() {}
+
+protected:
+
+ /* Returns parent wizard object: */
+ UICloneVMWizard* wizard() { return qobject_cast<UICloneVMWizard*>(QIWizardPage::wizard()); }
+};
+
+/* Page1 of the new clonevm wizard: */
+class UICloneVMWizardPage1 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage1
+{
+ Q_OBJECT;
+ Q_PROPERTY(QString cloneName READ cloneName WRITE setCloneName);
+ Q_PROPERTY(bool reinitMACs READ isReinitMACsChecked);
+
+public:
+
+ /* Constructor: */
+ UICloneVMWizardPage1(const QString &strOriName);
+
+ QString cloneName() const;
+ void setCloneName(const QString &strName);
+
+ bool isReinitMACsChecked() const;
+
+protected:
+
+ /* Translation stuff: */
+ void retranslateUi();
+
+ /* Prepare page: */
+ void initializePage();
+
+ bool isComplete() const;
+ bool validatePage();
+
+private slots:
+
+ void sltNameEditorTextChanged(const QString &strText);
+
+private:
+
+ /* Private member vars */
+ QString m_strOriName;
+};
+
+/* Page2 of the new clonevm wizard: */
+class UICloneVMWizardPage2 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage2
+{
+ Q_OBJECT;
+ Q_PROPERTY(KCloneMode cloneMode READ cloneMode WRITE setCloneMode);
+
+public:
+
+ /* Constructor: */
+ UICloneVMWizardPage2(bool fShowChildsOption = true);
+
+protected:
+
+ /* Translation stuff: */
+ void retranslateUi();
+
+ /* Prepare page: */
+ void initializePage();
+
+ bool validatePage();
+
+ KCloneMode cloneMode() const;
+ void setCloneMode(KCloneMode mode);
+
+private:
+
+ bool m_fShowChildsOption;
+};
+
+#endif // __UICloneVMWizard_h__
+
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizardPage1.ui b/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizardPage1.ui
new file mode 100644
index 000000000..b7ac0db4e
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizardPage1.ui
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>
+ VBox frontends: Qt4 GUI (&quot;VirtualBox&quot;):
+
+ 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 &quot;COPYING&quot; 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.
+ </comment>
+ <class>UICloneVMWizardPage1</class>
+ <widget class="QWidget" name="UICloneVMWizardPage1">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QILabel" name="m_pLabel">
+ <property name="text">
+ <string>&lt;p&gt;This wizard will help you to create a clone of your virtual machine.&lt;/p&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QILabel" name="m_pLabel2">
+ <property name="text">
+ <string>&lt;p&gt;Please choose a name for the new virtual machine:&lt;/p&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="m_pNameEditor"/>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="mReinitMACsCheckBox">
+ <property name="toolTip">
+ <string>When checked a new unique MAC address will assigned to all configured network cards.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Reinitialize the MAC address of all network cards</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QILabel</class>
+ <extends>QLabel</extends>
+ <header>QILabel.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizardPage2.ui b/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizardPage2.ui
new file mode 100644
index 000000000..df4990da2
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizardPage2.ui
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>
+ VBox frontends: Qt4 GUI (&quot;VirtualBox&quot;):
+
+ 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 &quot;COPYING&quot; 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.
+ </comment>
+ <class>UICloneVMWizardPage2</class>
+ <widget class="QWidget" name="UICloneVMWizardPage2">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QILabel" name="m_pLabel">
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="m_pMachineRadio">
+ <property name="text">
+ <string>Current machine state</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="m_pMachineAndChildsRadio">
+ <property name="text">
+ <string>Current machine and all child states</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="m_pAllRadio">
+ <property name="text">
+ <string>All states</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="m_pSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QILabel</class>
+ <extends>QLabel</extends>
+ <header>QILabel.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIExportApplianceWzd.cpp b/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIExportApplianceWzd.cpp
index 12cda2962..f4a9a6f7f 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIExportApplianceWzd.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIExportApplianceWzd.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIExportApplianceWzd.cpp $ */
+/* $Id: UIExportApplianceWzd.cpp 37849 2011-07-08 15:15:45Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -93,6 +93,7 @@ void UIExportApplianceWzd::retranslateUi()
/* Extra buttons */
setButtonText(QWizard::CustomButton1, tr("Restore Defaults"));
+ setButtonText(QWizard::FinishButton, tr("Export"));
}
void UIExportApplianceWzd::sltCurrentIdChanged(int iId)
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIFirstRunWzd.cpp b/src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIFirstRunWzd.cpp
index c2c4d1e49..95ae6cdc6 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIFirstRunWzd.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIFirstRunWzd.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIFirstRunWzd.cpp $ */
+/* $Id: UIFirstRunWzd.cpp 37849 2011-07-08 15:15:45Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -97,6 +97,8 @@ void UIFirstRunWzd::retranslateUi()
{
/* Wizard title */
setWindowTitle(tr("First Run Wizard"));
+
+ setButtonText(QWizard::FinishButton, tr("Start"));
}
UIFirstRunWzdPage1::UIFirstRunWzdPage1()
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIImportApplianceWzd.cpp b/src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIImportApplianceWzd.cpp
index c7801f5c2..1a5bee784 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIImportApplianceWzd.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIImportApplianceWzd.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIImportApplianceWzd.cpp $ */
+/* $Id: UIImportApplianceWzd.cpp 37849 2011-07-08 15:15:45Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -155,6 +155,7 @@ void UIImportApplianceWzd::retranslateUi()
/* Translate 'Restore Defaults' button */
setButtonText(QWizard::CustomButton1, tr("Restore Defaults"));
+ setButtonText(QWizard::FinishButton, tr("Import"));
}
void UIImportApplianceWzd::sltCurrentIdChanged(int iId)
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizard.cpp b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizard.cpp
new file mode 100644
index 000000000..f59e782d7
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizard.cpp
@@ -0,0 +1,1083 @@
+/* $Id: UINewHDWizard.cpp 37912 2011-07-13 11:21:36Z vboxsync $ */
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * UINewHDWizard class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* Global includes: */
+#include <QCheckBox>
+#include <QRadioButton>
+#include <QRegExpValidator>
+
+/* Local includes: */
+#include "VBoxGlobal.h"
+#include "VBoxProblemReporter.h"
+#include "QIFileDialog.h"
+#include "UIIconPool.h"
+#include "UINewHDWizard.h"
+#include "iprt/path.h"
+
+/* Class to manage page variants: */
+class UIExclusivenessManager : public QObject
+{
+ Q_OBJECT;
+
+public:
+
+ /* Constructor: */
+ UIExclusivenessManager(QWidget *pParent) : QObject(pParent) {}
+
+ /* Wrapper for adding different children: */
+ void addWidget(QWidget *pWidget, const QVariant &data)
+ {
+ /* Add radio-button: */
+ if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
+ addRadioButton(pRadioButton, data);
+ /* Add check-box: */
+ if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
+ addCheckBox(pCheckBox, data);
+ }
+
+ /* Wrapper for different children data: */
+ QVariant data(QWidget *pWidget) const
+ {
+ /* Return data for radio-button: */
+ if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
+ return dataOfRadioButton(pRadioButton);
+ /* Return data for check-box: */
+ if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
+ return dataOfCheckBox(pCheckBox);
+ /* Return empty data: */
+ return QVariant();
+ }
+
+ void reset()
+ {
+ /* Make sure all radio-buttons are unchecked: */
+ QList<QRadioButton*> radioButtons = m_radioButtons.keys();
+ for (int i = 0; i < radioButtons.size(); ++i)
+ {
+ if (radioButtons[i]->isChecked())
+ {
+ radioButtons[i]->setAutoExclusive(false);
+ radioButtons[i]->setChecked(false);
+ radioButtons[i]->setAutoExclusive(true);
+ }
+ }
+ /* Make sure all check-boxes are unchecked: */
+ QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
+ for (int i = 0; i < checkBoxes.size(); ++i)
+ {
+ if (checkBoxes[i]->isChecked())
+ checkBoxes[i]->setChecked(false);
+ }
+ }
+
+signals:
+
+ void sigNotifyAboutStateChange(QVariant exclusiveData, QList<QVariant> optionsData);
+
+private slots:
+
+ void sltRadioButtonToggled()
+ {
+ recalculateState();
+ }
+
+ void sltCheckBoxToggled()
+ {
+ recalculateState();
+ }
+
+private:
+
+ void addRadioButton(QRadioButton *pRadioButton, const QVariant &exclusiveData)
+ {
+ /* Setup the connections: */
+ connect(pRadioButton, SIGNAL(toggled(bool)), this, SLOT(sltRadioButtonToggled()));
+ /* Add radio-button into corresponding list: */
+ m_radioButtons.insert(pRadioButton, exclusiveData);
+ }
+
+ void addCheckBox(QCheckBox *pCheckBox, const QVariant &optionData)
+ {
+ /* Setup the connections: */
+ connect(pCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltCheckBoxToggled()));
+ /* Add check-box into corresponding list: */
+ m_checkBoxes.insert(pCheckBox, optionData);
+ }
+
+ QVariant dataOfRadioButton(QRadioButton *pRadioButton) const
+ {
+ /* Return radio-button data if present: */
+ if (m_radioButtons.contains(pRadioButton))
+ return m_radioButtons[pRadioButton];
+ /* Return empty data: */
+ return QVariant();
+ }
+
+ QVariant dataOfCheckBox(QCheckBox *pCheckBox) const
+ {
+ /* Return check-box data if present: */
+ if (m_checkBoxes.contains(pCheckBox))
+ return m_checkBoxes[pCheckBox];
+ /* Return empty data: */
+ return QVariant();
+ }
+
+ void recalculateState()
+ {
+ /* Prepare current state: */
+ QList<bool> currentState;
+ /* Get the list of radio-buttons: */
+ QList<QRadioButton*> radioButtons = m_radioButtons.keys();
+ /* Get the list of check-boxes: */
+ QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
+
+ /* Calculate current state: */
+ for (int i = 0; i < radioButtons.size(); ++i)
+ currentState << radioButtons[i]->isChecked();
+ for (int i = 0; i < checkBoxes.size(); ++i)
+ currentState << checkBoxes[i]->isChecked();
+
+ /* Check if state was changed: */
+ if (m_state == currentState)
+ return;
+
+ /* Search for exclusive data: */
+ QVariant exclusiveData;
+ for (int i = 0; i < radioButtons.size(); ++i)
+ {
+ if (radioButtons[i]->isChecked())
+ {
+ exclusiveData = m_radioButtons[radioButtons[i]];
+ break;
+ }
+ }
+
+ /* Search for options data: */
+ QList<QVariant> optionsData;
+ for (int i = 0; i < checkBoxes.size(); ++i)
+ {
+ if (checkBoxes[i]->isChecked())
+ optionsData << m_checkBoxes[checkBoxes[i]];
+ }
+
+ /* Notify listeners about state-change: */
+ emit sigNotifyAboutStateChange(exclusiveData, optionsData);
+ }
+
+ QMap<QRadioButton*, QVariant> m_radioButtons;
+ QMap<QCheckBox*, QVariant> m_checkBoxes;
+ QList<bool> m_state;
+};
+
+UINewHDWizard::UINewHDWizard(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize, const CMedium &sourceHardDisk)
+ : QIWizard(pParent)
+ , m_wizardType(sourceHardDisk.isNull() ? UINewHDWizardType_Creating : UINewHDWizardType_Copying)
+{
+#ifdef Q_WS_WIN
+ /* Hide window icon: */
+ setWindowIcon(QIcon());
+#endif /* Q_WS_WIN */
+
+ /* Create & add pages: */
+ if (wizardType() == UINewHDWizardType_Copying)
+ addPage(new UINewHDWizardPageWelcome(sourceHardDisk));
+ addPage(new UINewHDWizardPageFormat);
+ addPage(new UINewHDWizardPageVariant);
+ addPage(new UINewHDWizardPageOptions(strDefaultName, strDefaultPath, uDefaultSize));
+ addPage(new UINewHDWizardPageSummary);
+
+ /* Translate wizard: */
+ retranslateUi();
+
+ /* Translate wizard pages: */
+ retranslateAllPages();
+
+ /* Resize wizard to 'golden ratio': */
+ resizeToGoldenRatio();
+
+#ifdef Q_WS_MAC
+ /* Assign background image: */
+ assignBackground(":/vmw_new_harddisk_bg.png");
+#else /* Q_WS_MAC */
+ /* Assign watermark: */
+ assignWatermark(":/vmw_new_harddisk.png");
+#endif /* Q_WS_MAC */
+}
+
+CMedium UINewHDWizard::hardDisk() const
+{
+ /* Return 'hardDisk' field value from 'summary' page: */
+ return field("hardDisk").value<CMedium>();
+}
+
+void UINewHDWizard::retranslateUi()
+{
+ /* Translate wizard: */
+ switch (wizardType())
+ {
+ case UINewHDWizardType_Creating:
+ setWindowTitle(tr("Create New Virtual Disk"));
+ setButtonText(QWizard::FinishButton, tr("Create"));
+ break;
+ case UINewHDWizardType_Copying:
+ setWindowTitle(tr("Copy Virtual Disk"));
+ setButtonText(QWizard::FinishButton, tr("Copy"));
+ break;
+ default:
+ break;
+ }
+}
+
+UINewHDWizardPageWelcome::UINewHDWizardPageWelcome(const CMedium &sourceHardDisk)
+ : m_sourceHardDisk(sourceHardDisk)
+{
+ /* Decorate page: */
+ Ui::UINewHDWizardPageWelcome::setupUi(this);
+
+ /* Register CMedium class: */
+ qRegisterMetaType<CMedium>();
+
+ /* Register 'sourceHardDisk' field: */
+ registerField("sourceHardDisk", this, "sourceHardDisk");
+
+ /* Initialise medium-combo-box: */
+ m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
+ m_pSourceDiskSelector->repopulate();
+
+ /* Setup medium-manager button: */
+ m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
+ ":/select_file_dis_16px.png"));
+
+ /* Setup connections: */
+ connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltHandleSourceDiskChange()));
+ connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
+}
+
+void UINewHDWizardPageWelcome::sltHandleSourceDiskChange()
+{
+ m_sourceHardDisk = vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
+ emit completeChanged();
+}
+
+void UINewHDWizardPageWelcome::sltHandleOpenSourceDiskClick()
+{
+ /* Get source virtual disk using file-open dialog: */
+ QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
+ if (!strMediumId.isNull())
+ {
+ /* Update medium-combo if necessary: */
+ m_pSourceDiskSelector->setCurrentItem(strMediumId);
+ /* Update hard disk source: */
+ sltHandleSourceDiskChange();
+ /* Focus on hard disk combo: */
+ m_pSourceDiskSelector->setFocus();
+ }
+}
+
+void UINewHDWizardPageWelcome::retranslateUi()
+{
+ /* Translate uic generated strings: */
+ Ui::UINewHDWizardPageWelcome::retranslateUi(this);
+
+ /* Translate 'welcome' page: */
+ setTitle(UINewHDWizard::tr("Welcome to the virtual disk copying wizard"));
+ m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
+
+ /* Append page text with common part: */
+ m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
+
+ /* Append page text for source virtual disk part: */
+ m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("Please select the virtual disk which you would like to "
+ "copy if it is not already selected. You can either choose one "
+ "from the list or use the folder icon beside the list to "
+ "select a virtual disk file."));
+}
+
+void UINewHDWizardPageWelcome::initializePage()
+{
+ /* Set default item: */
+ m_pSourceDiskSelector->setCurrentItem(m_sourceHardDisk.GetId());
+
+ /* Retranslate page: */
+ retranslateUi();
+}
+
+bool UINewHDWizardPageWelcome::isComplete() const
+{
+ /* Check what 'sourceHardDisk' field value feats the rules: */
+ return !m_sourceHardDisk.isNull();
+}
+
+UINewHDWizardPageFormat::UINewHDWizardPageFormat()
+ : m_pExclusivenessManager(0)
+ , m_pDefaultButton(0)
+{
+ /* Decorate page: */
+ Ui::UINewHDWizardPageFormat::setupUi(this);
+
+ /* Register extended metatypes: */
+ qRegisterMetaType<CMediumFormat>();
+
+ /* Register 'mediumFormat' field: */
+ registerField("mediumFormat", this, "mediumFormat");
+
+ /* Create exclusiveness manager: */
+ m_pExclusivenessManager = new UIExclusivenessManager(this);
+ connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateFormat(QVariant)));
+
+ /* Enumerate supportable formats: */
+ CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
+ const QVector<CMediumFormat> &mediumFormats = systemProperties.GetMediumFormats();
+ /* Search for default format first: */
+ for (int i = 0; i < mediumFormats.size(); ++i)
+ {
+ /* Get iterated medium format: */
+ const CMediumFormat &mediumFormat = mediumFormats[i];
+ if (mediumFormat.GetName().toLower() == "vdi")
+ processFormat(mediumFormat);
+ }
+ /* Look for other formats: */
+ for (int i = 0; i < mediumFormats.size(); ++i)
+ {
+ /* Get iterated medium format: */
+ const CMediumFormat &mediumFormat = mediumFormats[i];
+ if (mediumFormat.GetName().toLower() != "vdi")
+ processFormat(mediumFormat);
+ }
+}
+
+/* static */
+QString UINewHDWizardPageFormat::fullFormatName(const QString &strBaseFormatName)
+{
+ if (strBaseFormatName == "VDI")
+ return UINewHDWizard::tr("&VDI (VirtualBox Disk Image)");
+ else if (strBaseFormatName == "VMDK")
+ return UINewHDWizard::tr("V&MDK (Virtual Machine Disk)");
+ else if (strBaseFormatName == "VHD")
+ return UINewHDWizard::tr("V&HD (Virtual Hard Disk)");
+ return strBaseFormatName;
+}
+
+void UINewHDWizardPageFormat::sltUpdateFormat(QVariant formatData)
+{
+ /* Get medium format: */
+ CMediumFormat mediumFormat = formatData.value<CMediumFormat>();
+
+ /* Check if medium format was changed: */
+ if (m_mediumFormat == mediumFormat)
+ return;
+
+ /* Update medium format: */
+ m_mediumFormat = mediumFormat;
+
+ /* Notify wizard sub-system about complete status changed: */
+ emit completeChanged();
+}
+
+void UINewHDWizardPageFormat::retranslateUi()
+{
+ /* Translate uic generated strings: */
+ Ui::UINewHDWizardPageFormat::retranslateUi(this);
+
+ /* Translate 'format' page: */
+ switch (wizardType())
+ {
+ case UINewHDWizardType_Creating:
+ setTitle(UINewHDWizard::tr("Welcome to the virtual disk creation wizard"));
+ m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
+ m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
+ m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("<p>Please choose the type of file that you would like to use for the new virtual disk. "
+ "If you do not need to use it with other virtualization software you can leave this setting unchanged.</p>"));
+ break;
+ case UINewHDWizardType_Copying:
+ setTitle(UINewHDWizard::tr("Virtual disk file type"));
+ m_pLabel->setText(UINewHDWizard::tr("Please choose the type of file that you would like to use for the new virtual disk. "
+ "If you do not need to use it with other virtualization software you can leave this setting unchanged."));
+ break;
+ default:
+ break;
+ }
+
+ /* Translate 'format' buttons: */
+ QList<QRadioButton*> formatButtons = findChildren<QRadioButton*>();
+ for (int i = 0; i < formatButtons.size(); ++i)
+ {
+ QRadioButton *pFormatButton = formatButtons[i];
+ CMediumFormat mediumFormat = m_pExclusivenessManager->data(pFormatButton).value<CMediumFormat>();
+ pFormatButton->setText(fullFormatName(mediumFormat.GetName()));
+ }
+}
+
+void UINewHDWizardPageFormat::initializePage()
+{
+ /* Retranslate page: */
+ retranslateUi();
+
+ /* Make sure first of buttons (default) is checked: */
+ m_pDefaultButton->setChecked(true);
+ m_pDefaultButton->setFocus();
+}
+
+void UINewHDWizardPageFormat::cleanupPage()
+{
+ /* Reset exclusiveness manager: */
+ m_pExclusivenessManager->reset();
+ /* Call for base-class: */
+ UINewHDWizardPage::cleanupPage();
+}
+
+bool UINewHDWizardPageFormat::isComplete() const
+{
+ return !m_mediumFormat.isNull();
+}
+
+void UINewHDWizardPageFormat::processFormat(CMediumFormat mediumFormat)
+{
+ /* Check that medium format supports creation: */
+ ULONG uFormatCapabilities = mediumFormat.GetCapabilities();
+ if (!(uFormatCapabilities & MediumFormatCapabilities_CreateFixed ||
+ uFormatCapabilities & MediumFormatCapabilities_CreateDynamic))
+ return;
+
+ /* Check that medium format supports creation of hard-disks: */
+ QVector<QString> fileExtensions;
+ QVector<KDeviceType> deviceTypes;
+ mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
+ if (!deviceTypes.contains(KDeviceType_HardDisk))
+ return;
+
+ /* Create corresponding radio-button: */
+ QRadioButton *pFormatButton = new QRadioButton(m_pFormatContainer);
+ m_pExclusivenessManager->addWidget(pFormatButton, QVariant::fromValue(mediumFormat));
+ m_pFormatsLayout->addWidget(pFormatButton);
+ if (mediumFormat.GetName().toLower() == "vdi")
+ m_pDefaultButton = pFormatButton;
+}
+
+UINewHDWizardPageVariant::UINewHDWizardPageVariant()
+ : m_pExclusivenessManager(0)
+ , m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
+ , m_uMediumVariant(KMediumVariant_Max)
+{
+ /* Decorate page: */
+ Ui::UINewHDWizardPageVariant::setupUi(this);
+
+ /* Register 'mediumVariant' field: */
+ registerField("mediumVariant", this, "mediumVariant");
+
+ /* Unfortuanelly, KMediumVariant is very messy,
+ * so we can't enumerate it to make sure GUI will not hard-code its values,
+ * we can only use hard-coded values that we need: */
+
+ /* Create exclusiveness manager: */
+ m_pExclusivenessManager = new UIExclusivenessManager(this);
+ connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateVariant(QVariant, QList<QVariant>)));
+
+ /* Create 'dynamical' (standard) variant radio-button: */
+ m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
+ m_pVariantsLayout->addWidget(m_pDynamicalButton);
+ m_pExclusivenessManager->addWidget(m_pDynamicalButton, QVariant((qulonglong)KMediumVariant_Standard));
+
+ /* Create 'fixed' variant radio-button: */
+ m_pFixedButton = new QRadioButton(m_pVariantContainer);
+ m_pVariantsLayout->addWidget(m_pFixedButton);
+ m_pExclusivenessManager->addWidget(m_pFixedButton, QVariant((qulonglong)(KMediumVariant_Standard | KMediumVariant_Fixed)));
+
+ /* Create '2GByte' variant check-box: */
+ m_pSplitBox = new QCheckBox(m_pVariantContainer);
+ m_pVariantsLayout->addWidget(m_pSplitBox);
+ m_pExclusivenessManager->addWidget(m_pSplitBox, QVariant((qulonglong)(KMediumVariant_VmdkSplit2G)));
+}
+
+void UINewHDWizardPageVariant::sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData)
+{
+ /* Gather new data: */
+ qulonglong uMediumVariant = exclusiveData.isNull() ? (qulonglong)KMediumVariant_Max : exclusiveData.toULongLong();
+ for (int i = 0; i < optionsData.size(); ++i)
+ uMediumVariant |= optionsData[i].toULongLong();
+
+ /* Check if medium variant was changed: */
+ if (m_uMediumVariant == uMediumVariant)
+ return;
+
+ /* Update medium variant: */
+ m_uMediumVariant = uMediumVariant;
+
+ /* Notify wizard sub-system about complete status changed: */
+ emit completeChanged();
+}
+
+void UINewHDWizardPageVariant::retranslateUi()
+{
+ /* Translate uic generated strings: */
+ Ui::UINewHDWizardPageVariant::retranslateUi(this);
+
+ /* Translate 'variant' page: */
+ setTitle(UINewHDWizard::tr("Virtual disk storage details"));
+ m_pLabel->setText(UINewHDWizard::tr("Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated."));
+
+ /* Translate other text: */
+ QString strText = m_pLabel->text();
+ CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
+ if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateDynamic))
+ strText += UINewHDWizard::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on your physical hard disk as it fills up, "
+ "although it will not shrink again automatically when space on it is freed.</p>");
+ if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateFixed))
+ strText += UINewHDWizard::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some systems but is often faster to use.</p>");
+ if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateSplit2G))
+ strText += UINewHDWizard::tr("<p>You can also choose to <b>split</b> the virtual disk into several files of up to two gigabytes each. "
+ "This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, "
+ "some of which cannot handle very large files.");
+ m_pLabel->setText(strText);
+
+ /* Translate buttons: */
+ m_pDynamicalButton->setText(UINewHDWizard::tr("&Dynamically allocated"));
+ m_pFixedButton->setText(UINewHDWizard::tr("&Fixed size"));
+ m_pSplitBox->setText(UINewHDWizard::tr("&Split into files of less than 2GB"));
+}
+
+void UINewHDWizardPageVariant::initializePage()
+{
+ /* Retranslate page: */
+ retranslateUi();
+
+ /* Setup visibility: */
+ CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
+ ULONG uCapabilities = mediumFormat.GetCapabilities();
+ m_pDynamicalButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateDynamic);
+ m_pFixedButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateFixed);
+ m_pSplitBox->setVisible(uCapabilities & KMediumFormatCapabilities_CreateSplit2G);
+ /* Make sure first of buttons (default) is checked if visible: */
+ if (!m_pDynamicalButton->isHidden())
+ {
+ m_pDynamicalButton->setChecked(true);
+ m_pDynamicalButton->setFocus();
+ }
+}
+
+void UINewHDWizardPageVariant::cleanupPage()
+{
+ /* Reset exclusiveness manager: */
+ m_pExclusivenessManager->reset();
+ /* Call for base-class: */
+ UINewHDWizardPage::cleanupPage();
+}
+
+bool UINewHDWizardPageVariant::isComplete() const
+{
+ return m_uMediumVariant != KMediumVariant_Max;
+}
+
+UINewHDWizardPageOptions::UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
+ : m_strDefaultPath(strDefaultPath)
+ , m_strMediumName(strDefaultName.isEmpty() ? QString("NewHardDisk1") : strDefaultName)
+ , m_uMediumSize(uDefaultSize == 0 ? (qulonglong)_1G * 2 : uDefaultSize)
+ , m_uMediumSizeMin(_4M)
+ , m_uMediumSizeMax(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
+ , m_iSliderScale(0)
+{
+ /* Decorate page: */
+ Ui::UINewHDWizardPageOptions::setupUi(this);
+
+ /* Register 'mediumName', 'mediumPath', 'mediumSize' fields: */
+ registerField("mediumName", this, "mediumName");
+ registerField("mediumPath", this, "mediumPath");
+ registerField("mediumSize", this, "mediumSize");
+
+ /* Detect how many steps to recognize between adjacent powers of 2
+ * to ensure that the last slider step is exactly m_uMediumSizeMax: */
+ int iPower = log2i(m_uMediumSizeMax);
+ qulonglong uTickMB = qulonglong (1) << iPower;
+ if (uTickMB < m_uMediumSizeMax)
+ {
+ qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
+ qulonglong uGap = uTickMBNext - m_uMediumSizeMax;
+ m_iSliderScale = (int)((uTickMBNext - uTickMB) / uGap);
+ }
+ m_iSliderScale = qMax(m_iSliderScale, 8);
+
+ /* Setup size-editor field: */
+ m_pSizeEditor->setFixedWidthByText("88888.88 MB");
+ m_pSizeEditor->setAlignment(Qt::AlignRight);
+ m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
+
+ /* Setup size-slider: */
+ m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
+ m_pSizeSlider->setPageStep(m_iSliderScale);
+ m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
+ m_pSizeSlider->setTickInterval(0);
+ m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
+ m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
+ m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
+ m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
+
+ /* Attach button icon: */
+ m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
+
+ /* Setup page connections: */
+ connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltLocationEditorTextChanged(const QString &)));
+ connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(sltSelectLocationButtonClicked()));
+ connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(sltSizeSliderValueChanged(int)));
+ connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltSizeEditorTextChanged(const QString &)));
+}
+
+void UINewHDWizardPageOptions::retranslateUi()
+{
+ /* Translate uic generated strings: */
+ Ui::UINewHDWizardPageOptions::retranslateUi(this);
+
+ /* Translate 'options' page: */
+ switch (wizardType())
+ {
+ case UINewHDWizardType_Creating:
+ setTitle(UINewHDWizard::tr("Virtual disk file location and size"));
+ m_pLabel2->setText(UINewHDWizard::tr("Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk."));
+ break;
+ case UINewHDWizardType_Copying:
+ setTitle(UINewHDWizard::tr("Virtual disk file location"));
+ m_pLabel2->setText(QString());
+ break;
+ default:
+ break;
+ }
+ m_pLabel1->setText(UINewHDWizard::tr("Press the <b>Select</b> button to select the location of a file to store the virtual disk data or type a file name in the entry field."));
+}
+
+void UINewHDWizardPageOptions::initializePage()
+{
+ /* Retranslate page: */
+ retranslateUi();
+
+ /* Setup 'options' page: */
+ switch (wizardType())
+ {
+ case UINewHDWizardType_Creating:
+ {
+ /* Visibility: */
+ m_pLabel2->setVisible(true);
+ m_pSizeCnt->setVisible(true);
+ break;
+ }
+ case UINewHDWizardType_Copying:
+ {
+ /* Visibility: */
+ m_pLabel2->setHidden(true);
+ m_pSizeCnt->setHidden(true);
+ /* Update parameters: */
+ const CMedium &sourceHardDisk = field("sourceHardDisk").value<CMedium>();
+ /* Default path: */
+ m_strDefaultPath = QFileInfo(sourceHardDisk.GetLocation()).absolutePath();
+ /* Default name: */
+ m_strMediumName = UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(sourceHardDisk.GetLocation()).baseName());
+ /* Initialize size: */
+ m_uMediumSize = sourceHardDisk.GetLogicalSize();
+ break;
+ }
+ default:
+ break;
+ }
+
+ /* Initialize name: */
+ m_pLocationEditor->setText(m_strMediumName);
+ /* Initialize size: */
+ m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
+ /* 'Size' editor should have focus initially: */
+ m_pSizeEditor->setFocus();
+ /* Get default extension: */
+ m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
+ m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
+}
+
+void UINewHDWizardPageOptions::cleanupPage()
+{
+ /* Reset widgets: */
+ m_pLocationEditor->clear();
+ m_pSizeSlider->setValue(0);
+ /* Call for base-class: */
+ UINewHDWizardPage::cleanupPage();
+}
+
+bool UINewHDWizardPageOptions::isComplete() const
+{
+ /* Check what current size feats the bounds & current name is not empty! */
+ return m_uMediumSize >= m_uMediumSizeMin && m_uMediumSize <= m_uMediumSizeMax &&
+ !m_strMediumName.trimmed().isEmpty();
+}
+
+bool UINewHDWizardPageOptions::validatePage()
+{
+ if (QFileInfo(m_strMediumPath).exists())
+ {
+ vboxProblem().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
+ return false;
+ }
+ return true;
+}
+
+void UINewHDWizardPageOptions::sltLocationEditorTextChanged(const QString &strText)
+{
+ /* Set current medium name: */
+ m_strMediumName = strText;
+ /* Set current medium path: */
+ m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
+
+ /* Notify wizard sub-system about complete status changed: */
+ emit completeChanged();
+}
+
+void UINewHDWizardPageOptions::sltSelectLocationButtonClicked()
+{
+ /* Get current folder and filename: */
+ QFileInfo fullFilePath(m_strMediumPath);
+ QDir folder = fullFilePath.path();
+ QString strFileName = fullFilePath.fileName();
+
+ /* Set the first parent folder that exists as the current: */
+ while (!folder.exists() && !folder.isRoot())
+ {
+ QFileInfo folderInfo(folder.absolutePath());
+ if (folder == QDir(folderInfo.absolutePath()))
+ break;
+ folder = folderInfo.absolutePath();
+ }
+
+ /* But if it doesn't exists at all: */
+ if (!folder.exists() || folder.isRoot())
+ {
+ /* Use recommended one folder: */
+ QFileInfo defaultFilePath(absoluteFilePath(strFileName, m_strDefaultPath));
+ folder = defaultFilePath.path();
+ }
+
+ /* Prepare backends list: */
+ CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
+ QVector<QString> fileExtensions;
+ QVector<KDeviceType> deviceTypes;
+ mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
+ QStringList validExtensionList;
+ for (int i = 0; i < fileExtensions.size(); ++i)
+ if (deviceTypes[i] == KDeviceType_HardDisk)
+ validExtensionList << QString("*.%1").arg(fileExtensions[i]);
+ /* Compose full filter list: */
+ QString strBackendsList = QString("%1 (%2)").arg(mediumFormat.GetName()).arg(validExtensionList.join(" "));
+
+ /* Open corresponding file-dialog: */
+ QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
+ strBackendsList, this,
+ UINewHDWizard::tr("Select a file for the new hard disk image file"));
+
+ /* If there was something really chosen: */
+ if (!strChosenFilePath.isEmpty())
+ {
+ /* If valid file extension is missed, append it: */
+ if (QFileInfo(strChosenFilePath).completeSuffix().isEmpty())
+ strChosenFilePath += QString(".%1").arg(m_strDefaultExtension);
+ m_pLocationEditor->setText(QDir::toNativeSeparators(strChosenFilePath));
+ m_pLocationEditor->selectAll();
+ m_pLocationEditor->setFocus();
+ }
+}
+
+void UINewHDWizardPageOptions::sltSizeSliderValueChanged(int iValue)
+{
+ /* Update currently stored size: */
+ m_uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
+ /* Update tooltip: */
+ updateSizeToolTip(m_uMediumSize);
+ /* Notify size-editor about size had changed preventing callback: */
+ m_pSizeEditor->blockSignals(true);
+ m_pSizeEditor->setText(vboxGlobal().formatSize(m_uMediumSize));
+ m_pSizeEditor->blockSignals(false);
+
+ /* Notify wizard sub-system about complete status changed: */
+ emit completeChanged();
+}
+
+void UINewHDWizardPageOptions::sltSizeEditorTextChanged(const QString &strValue)
+{
+ /* Update currently stored size: */
+ m_uMediumSize = vboxGlobal().parseSize(strValue);
+ /* Update tooltip: */
+ updateSizeToolTip(m_uMediumSize);
+ /* Notify size-slider about size had changed preventing callback: */
+ m_pSizeSlider->blockSignals(true);
+ m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
+ m_pSizeSlider->blockSignals(false);
+
+ /* Notify wizard sub-system about complete status changed: */
+ emit completeChanged();
+}
+
+/* static */
+QString UINewHDWizardPageOptions::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
+{
+ /* Wrap file-info around received file name: */
+ QFileInfo fileInfo(strFileName);
+ /* If path-info is relative or there is no path-info at all: */
+ if (fileInfo.fileName() == strFileName || fileInfo.isRelative())
+ {
+ /* Resolve path on the basis of default path we have: */
+ fileInfo = QFileInfo(strDefaultPath, strFileName);
+ }
+ /* Return full absolute hard disk file path: */
+ return QDir::toNativeSeparators(fileInfo.absoluteFilePath());
+}
+
+/* static */
+QString UINewHDWizardPageOptions::toFileName(const QString &strName, const QString &strExtension)
+{
+ /* Convert passed name to native separators (it can be full, actually): */
+ QString strFileName = QDir::toNativeSeparators(strName);
+
+ /* Remove all trailing dots to avoid multiple dots before extension: */
+ int iLen;
+ while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
+ strFileName.truncate(iLen - 1);
+
+ /* Add passed extension if its not done yet: */
+ if (QFileInfo(strFileName).completeSuffix().toLower() != strExtension)
+ strFileName += QString(".%1").arg(strExtension);
+
+ /* Return result: */
+ return strFileName;
+}
+
+/* static */
+QString UINewHDWizardPageOptions::defaultExtension(CMediumFormat mediumFormat)
+{
+ /* Load extension / device list: */
+ QVector<QString> fileExtensions;
+ QVector<KDeviceType> deviceTypes;
+ mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
+ for (int i = 0; i < fileExtensions.size(); ++i)
+ if (deviceTypes[i] == KDeviceType_HardDisk)
+ return fileExtensions[i].toLower();
+ AssertMsgFailed(("Extension can't be NULL!\n"));
+ return QString();
+}
+
+/* static */
+int UINewHDWizardPageOptions::log2i(qulonglong uValue)
+{
+ int iPower = -1;
+ while (uValue)
+ {
+ ++iPower;
+ uValue >>= 1;
+ }
+ return iPower;
+}
+
+/* static */
+int UINewHDWizardPageOptions::sizeMBToSlider(qulonglong uValue, int iSliderScale)
+{
+ int iPower = log2i(uValue);
+ qulonglong uTickMB = qulonglong (1) << iPower;
+ qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
+ int iStep = (uValue - uTickMB) * iSliderScale / (uTickMBNext - uTickMB);
+ return iPower * iSliderScale + iStep;
+}
+
+/* static */
+qulonglong UINewHDWizardPageOptions::sliderToSizeMB(int uValue, int iSliderScale)
+{
+ int iPower = uValue / iSliderScale;
+ int iStep = uValue % iSliderScale;
+ qulonglong uTickMB = qulonglong (1) << iPower;
+ qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
+ return uTickMB + (uTickMBNext - uTickMB) * iStep / iSliderScale;
+}
+
+void UINewHDWizardPageOptions::updateSizeToolTip(qulonglong uSize)
+{
+ QString strToolTip = UINewHDWizard::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
+ m_pSizeSlider->setToolTip(strToolTip);
+ m_pSizeEditor->setToolTip(strToolTip);
+}
+
+UINewHDWizardPageSummary::UINewHDWizardPageSummary()
+{
+ /* Decorate page: */
+ Ui::UINewHDWizardPageSummary::setupUi(this);
+
+ /* Register CMedium class: */
+ qRegisterMetaType<CMedium>();
+
+ /* Register 'hardDisk' field: */
+ registerField("hardDisk", this, "hardDisk");
+
+ /* Disable the background painting of the summary widget: */
+ m_pSummaryText->viewport()->setAutoFillBackground(false);
+}
+
+void UINewHDWizardPageSummary::retranslateUi()
+{
+ /* Translate uic generated strings: */
+ Ui::UINewHDWizardPageSummary::retranslateUi(this);
+
+ /* Translate 'options' page: */
+ setTitle(UINewHDWizard::tr("Summary"));
+ switch (wizardType())
+ {
+ case UINewHDWizardType_Creating:
+ m_pLabel1->setText(UINewHDWizard::tr("You are going to create a new virtual disk with the following parameters:"));
+ break;
+ case UINewHDWizardType_Copying:
+ m_pLabel1->setText(UINewHDWizard::tr("You are going to create a copied virtual disk with the following parameters:"));
+ break;
+ default:
+ break;
+ }
+ m_pLabel2->setText(UINewHDWizard::tr("If the above settings are correct, press the <b>%1</b> button. "
+ "Once you press it the new virtual disk file will be created.")
+ .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
+
+ /* Compose common summary: */
+ QString strSummary;
+
+ CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
+ qulonglong uVariant = field("mediumVariant").toULongLong();
+ QString strMediumPath = field("mediumPath").toString();
+ QString sizeFormatted = VBoxGlobal::formatSize(field("mediumSize").toULongLong());
+ QString sizeUnformatted = UINewHDWizard::tr("%1 B").arg(field("mediumSize").toULongLong());
+
+ strSummary += QString
+ (
+ "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
+ "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
+ "<tr><td><nobr>%5: </nobr></td><td><nobr>%6</nobr></td></tr>"
+ "<tr><td><nobr>%7: </nobr></td><td><nobr>%8 (%9)</nobr></td></tr>"
+ )
+ .arg(UINewHDWizard::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UINewHDWizardPageFormat::fullFormatName(mediumFormat.GetName())))
+ .arg(UINewHDWizard::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
+ .arg(UINewHDWizard::tr("Location", "summary"), strMediumPath)
+ .arg(UINewHDWizard::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
+
+ /* Feat summary to 4 lines: */
+ setSummaryFieldLinesNumber(m_pSummaryText, 4);
+
+ m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
+}
+
+void UINewHDWizardPageSummary::initializePage()
+{
+ /* Retranslate page: */
+ retranslateUi();
+
+ /* Summary should have focus initially: */
+ m_pSummaryText->setFocus();
+}
+
+bool UINewHDWizardPageSummary::validatePage()
+{
+ /* Start performing long-time operation: */
+ startProcessing();
+ /* Try to construct hard disk: */
+ bool fResult = createHardDisk();
+ /* Finish performing long-time operation: */
+ endProcessing();
+ /* Return operation result: */
+ return fResult;
+}
+
+bool UINewHDWizardPageSummary::createHardDisk()
+{
+ /* Gather attributes: */
+ CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
+ qulonglong uVariant = field("mediumVariant").toULongLong();
+ QString strMediumPath = field("mediumPath").toString();
+ qulonglong uSize = field("mediumSize").toULongLong();
+
+ /* Check attributes: */
+ AssertReturn(!strMediumPath.isNull(), false);
+ AssertReturn(uSize > 0, false);
+
+ /* Get vbox object: */
+ CVirtualBox vbox = vboxGlobal().virtualBox();
+
+ /* Create new hard disk: */
+ CMedium hardDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
+ CProgress progress;
+ if (!vbox.isOk())
+ {
+ vboxProblem().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
+ return false;
+ }
+
+ /* Depending on dialog type: */
+ switch (wizardType())
+ {
+ case UINewHDWizardType_Creating:
+ {
+ /* Create base storage for the new hard disk: */
+ progress = hardDisk.CreateBaseStorage(uSize, uVariant);
+ break;
+ }
+ case UINewHDWizardType_Copying:
+ {
+ /* Copy existing hard disk to the new hard disk: */
+ CMedium sourceHardDisk = field("sourceHardDisk").value<CMedium>();
+ progress = sourceHardDisk.CloneTo(hardDisk, uVariant, CMedium() /* parent */);
+ break;
+ }
+ default:
+ return false;
+ }
+
+ /* Check for errors: */
+ if (!hardDisk.isOk())
+ {
+ vboxProblem().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
+ return false;
+ }
+ vboxProblem().showModalProgressDialog(progress, windowTitle(), ":/progress_media_create_90px.png", this, true);
+ if (progress.GetCanceled())
+ return false;
+ if (!progress.isOk() || progress.GetResultCode() != 0)
+ {
+ vboxProblem().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
+ return false;
+ }
+
+ /* Assign hardDisk field value: */
+ m_hardDisk = hardDisk;
+
+ /* Depending on dialog type: */
+ switch (wizardType())
+ {
+ case UINewHDWizardType_Creating:
+ {
+ /* Inform everybody there is a new medium: */
+ vboxGlobal().addMedium(VBoxMedium(m_hardDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
+ break;
+ }
+ case UINewHDWizardType_Copying:
+ {
+ /* Just close the clone medium, it is not necessary yet: */
+ m_hardDisk.Close();
+ break;
+ }
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+#include "UINewHDWizard.moc"
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizard.h b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizard.h
new file mode 100644
index 000000000..507576e0a
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizard.h
@@ -0,0 +1,332 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * UINewHDWizard class declaration
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UINewHDWizard_h__
+#define __UINewHDWizard_h__
+
+/* Local includes: */
+#include "QIWizard.h"
+#include "COMDefs.h"
+
+/* Generated includes: */
+#include "UINewHDWizardPageWelcome.gen.h"
+#include "UINewHDWizardPageFormat.gen.h"
+#include "UINewHDWizardPageVariant.gen.h"
+#include "UINewHDWizardPageOptions.gen.h"
+#include "UINewHDWizardPageSummary.gen.h"
+
+/* Forward declarations: */
+class QRadioButton;
+class QCheckBox;
+class UIExclusivenessManager;
+
+/* Wizard type: */
+enum UINewHDWizardType
+{
+ UINewHDWizardType_Creating,
+ UINewHDWizardType_Copying
+};
+
+/* New hard disk wizard class: */
+class UINewHDWizard : public QIWizard
+{
+ Q_OBJECT;
+
+public:
+
+ /* Constructor: */
+ UINewHDWizard(QWidget *pParent,
+ const QString &strDefaultName = QString(), const QString &strDefaultPath = QString(),
+ qulonglong uDefaultSize = 0, const CMedium &sourceHardDisk = CMedium());
+
+ /* Stuff for wizard type: */
+ UINewHDWizardType wizardType() const { return m_wizardType; }
+
+ /* Returns created hard disk: */
+ CMedium hardDisk() const;
+
+private:
+
+ /* Translation stuff: */
+ void retranslateUi();
+
+ /* Wizard type: */
+ UINewHDWizardType m_wizardType;
+};
+
+/* Base wrapper for the wizard page
+ * of the new hard disk wizard class: */
+class UINewHDWizardPage : public QIWizardPage
+{
+ Q_OBJECT;
+
+public:
+
+ /* Constructor: */
+ UINewHDWizardPage() {}
+
+protected:
+
+ /* Returns parent wizard object: */
+ UINewHDWizard* wizard() const { return qobject_cast<UINewHDWizard*>(QIWizardPage::wizard()); }
+
+ /* Returns parent wizard type: */
+ UINewHDWizardType wizardType() const { return wizard()->wizardType(); }
+};
+
+/* Welcome page of the new hard-disk wizard: */
+class UINewHDWizardPageWelcome : public UINewHDWizardPage, public Ui::UINewHDWizardPageWelcome
+{
+ Q_OBJECT;
+ Q_PROPERTY(CMedium sourceHardDisk READ sourceHardDisk WRITE setSourceHardDisk);
+
+public:
+
+ /* Constructor: */
+ UINewHDWizardPageWelcome(const CMedium &sourceHardDisk);
+
+private slots:
+
+ /* Handlers for source disk change: */
+ void sltHandleSourceDiskChange();
+ void sltHandleOpenSourceDiskClick();
+
+private:
+
+ /* Translation stuff: */
+ void retranslateUi();
+
+ /* Prepare page: */
+ void initializePage();
+
+ /* Completeness validator: */
+ bool isComplete() const;
+
+ /* Stuff for 'sourceHardDisk' field: */
+ CMedium sourceHardDisk() const { return m_sourceHardDisk; }
+ void setSourceHardDisk(const CMedium &sourceHardDisk) { m_sourceHardDisk = sourceHardDisk; }
+ CMedium m_sourceHardDisk;
+};
+
+/* Format page of the new hard-disk wizard: */
+class UINewHDWizardPageFormat : public UINewHDWizardPage, public Ui::UINewHDWizardPageFormat
+{
+ Q_OBJECT;
+ Q_PROPERTY(CMediumFormat mediumFormat READ mediumFormat WRITE setMediumFormat);
+
+public:
+
+ /* Constructor: */
+ UINewHDWizardPageFormat();
+
+ /* Returns full medium format name: */
+ static QString fullFormatName(const QString &strBaseFormatName);
+
+private slots:
+
+ /* Handler for the 'format'-change signal: */
+ void sltUpdateFormat(QVariant formatData);
+
+private:
+
+ /* Translation stuff: */
+ void retranslateUi();
+
+ /* Prepare page: */
+ void initializePage();
+ /* Cleanup page: */
+ void cleanupPage();
+
+ /* Completeness validator: */
+ bool isComplete() const;
+
+ /* Helping stuff: */
+ void processFormat(CMediumFormat mediumFormat);
+
+ /* Exclusiveness manager: */
+ UIExclusivenessManager *m_pExclusivenessManager;
+
+ /* Defaut format (VDI) button: */
+ QRadioButton *m_pDefaultButton;
+
+ /* Stuff for 'mediumFormat' field: */
+ CMediumFormat mediumFormat() const { return m_mediumFormat; }
+ void setMediumFormat(const CMediumFormat &mediumFormat) { m_mediumFormat = mediumFormat; }
+ CMediumFormat m_mediumFormat;
+};
+
+/* Variant page of the new hard-disk wizard: */
+class UINewHDWizardPageVariant : public UINewHDWizardPage, public Ui::UINewHDWizardPageVariant
+{
+ Q_OBJECT;
+ Q_PROPERTY(qulonglong mediumVariant READ mediumVariant WRITE setMediumVariant);
+
+public:
+
+ /* Constructor: */
+ UINewHDWizardPageVariant();
+
+private slots:
+
+ /* Handler for the 'variant'-change signal: */
+ void sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData);
+
+private:
+
+ /* Translation stuff: */
+ void retranslateUi();
+
+ /* Prepare page: */
+ void initializePage();
+ /* Cleanup page: */
+ void cleanupPage();
+
+ /* Completeness validator: */
+ bool isComplete() const;
+
+ /* Exclusiveness manager: */
+ UIExclusivenessManager *m_pExclusivenessManager;
+
+ /* Defaut variant (dynamic) button: */
+ QRadioButton *m_pDynamicalButton;
+ QRadioButton *m_pFixedButton;
+ QCheckBox *m_pSplitBox;
+
+ /* Stuff for 'variant' field: */
+ qulonglong mediumVariant() const { return m_uMediumVariant; }
+ void setMediumVariant(qulonglong uMediumVariant) { m_uMediumVariant = uMediumVariant; }
+ qulonglong m_uMediumVariant;
+};
+
+/* Options page of the new hard-disk wizard: */
+class UINewHDWizardPageOptions : public UINewHDWizardPage, public Ui::UINewHDWizardPageOptions
+{
+ Q_OBJECT;
+ Q_PROPERTY(QString mediumName READ mediumName WRITE setMediumName);
+ Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
+ Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
+
+public:
+
+ /* Constructor: */
+ UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
+
+protected:
+
+ /* Translation stuff: */
+ void retranslateUi();
+
+ /* Prepare page: */
+ void initializePage();
+ /* Cleanup page: */
+ void cleanupPage();
+
+ /* Completeness validator: */
+ bool isComplete() const;
+ /* Completeness finisher: */
+ bool validatePage();
+
+private slots:
+
+ /* Location editors stuff: */
+ void sltLocationEditorTextChanged(const QString &strName);
+ void sltSelectLocationButtonClicked();
+
+ /* Size editors stuff: */
+ void sltSizeSliderValueChanged(int iValue);
+ void sltSizeEditorTextChanged(const QString &strValue);
+
+private:
+
+ /* Returns 'file name' for the passed 'name': */
+ static QString toFileName(const QString &strName, const QString &strExtension);
+ /* Returns 'absolute file path' for the passed 'file name': */
+ static QString absoluteFilePath(const QString &strFileName, const QString &strDefaultPath);
+ /* Returns default extension for the passed medium format: */
+ static QString defaultExtension(CMediumFormat mediumFormat);
+
+ /* Size editors stuff: */
+ static int log2i(qulonglong uValue);
+ static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
+ static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
+ void updateSizeToolTip(qulonglong uSize);
+
+ /* The default extension for the hard disk file: */
+ QString m_strDefaultExtension;
+
+ /* The default path for the hard disk file: */
+ QString m_strDefaultPath;
+
+ /* Stuff for 'mediumName' field: */
+ QString mediumName() const { return m_strMediumName; }
+ void setMediumName(const QString &strMediumName) { m_strMediumName = strMediumName; }
+ QString m_strMediumName;
+
+ /* Stuff for 'mediumPath' field: */
+ QString mediumPath() const { return m_strMediumPath; }
+ void setMediumPath(const QString &strMediumPath) { m_strMediumPath = strMediumPath; }
+ QString m_strMediumPath;
+
+ /* Stuff for 'mediumSize' field: */
+ qulonglong mediumSize() const { return m_uMediumSize; }
+ void setMediumSize(qulonglong uMediumSize) { m_uMediumSize = uMediumSize; }
+ qulonglong m_uMediumSize;
+
+ /* Other size editors stuff: */
+ qulonglong m_uMediumSizeMin;
+ qulonglong m_uMediumSizeMax;
+ int m_iSliderScale;
+};
+
+/* Summary page of the new hard-disk wizard: */
+class UINewHDWizardPageSummary : public UINewHDWizardPage, public Ui::UINewHDWizardPageSummary
+{
+ Q_OBJECT;
+ Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
+
+public:
+
+ /* Constructor: */
+ UINewHDWizardPageSummary();
+
+protected:
+
+ /* Translation stuff: */
+ void retranslateUi();
+
+ /* Prepare page: */
+ void initializePage();
+
+ /* Completeness finisher: */
+ bool validatePage();
+
+private:
+
+ /* Creates hard disk: */
+ bool createHardDisk();
+
+ /* Stuff for 'hardDisk' field: */
+ CMedium hardDisk() const { return m_hardDisk; }
+ void setHardDisk(const CMedium &hardDisk) { m_hardDisk = hardDisk; }
+ CMedium m_hardDisk;
+};
+
+Q_DECLARE_METATYPE(CMedium);
+
+#endif // __UINewHDWizard_h__
+
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzdPage1.ui b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageFormat.ui
index d71813c6e..0f9e61305 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzdPage1.ui
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageFormat.ui
@@ -3,7 +3,7 @@
<comment>
VBox frontends: Qt4 GUI ("VirtualBox"):
- Copyright (C) 2009-2010 Oracle Corporation
+ Copyright (C) 2009-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;
@@ -13,8 +13,8 @@
VirtualBox OSE distribution. VirtualBox OSE is distributed in the
hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
</comment>
- <class>UINewHDWzdPage1</class>
- <widget class="QWidget" name="UINewHDWzdPage1">
+ <class>UINewHDWizardPageFormat</class>
+ <widget class="QWidget" name="UINewHDWizardPageFormat">
<property name="geometry">
<rect>
<x>0</x>
@@ -29,19 +29,27 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <layout class="QVBoxLayout" name="m_pLayout1">
+ <layout class="QVBoxLayout" name="m_pMainLayout">
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
- <widget class="QILabel" name="m_pPage1Text1">
+ <widget class="QILabel" name="m_pLabel">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
- <spacer name="m_pSpacer1">
+ <widget class="QGroupBox" name="m_pFormatContainer">
+ <property name="title">
+ <string>File type</string>
+ </property>
+ <layout class="QVBoxLayout" name="m_pFormatsLayout"/>
+ </widget>
+ </item>
+ <item>
+ <spacer name="m_pSpacer">
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzdPage3.ui b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageOptions.ui
index 12f7390cd..87e1998e5 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzdPage3.ui
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageOptions.ui
@@ -3,7 +3,7 @@
<comment>
VBox frontends: Qt4 GUI ("VirtualBox"):
- Copyright (C) 2009-2010 Oracle Corporation
+ Copyright (C) 2009-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;
@@ -13,8 +13,8 @@
VirtualBox OSE distribution. VirtualBox OSE is distributed in the
hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
</comment>
- <class>UINewHDWzdPage3</class>
- <widget class="QWidget" name="UINewHDWzdPage3">
+ <class>UINewHDWizardPageOptions</class>
+ <widget class="QWidget" name="UINewHDWizardPageOptions">
<property name="geometry">
<rect>
<x>0</x>
@@ -29,15 +29,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <layout class="QVBoxLayout" name="m_pLayout1">
+ <layout class="QVBoxLayout" name="m_pMainLayout">
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
- <widget class="QILabel" name="m_pPage3Text1">
- <property name="text">
- <string>&lt;p&gt;Press the &lt;b&gt;Select&lt;/b&gt; button to select the location of a file to store the hard disk data or type a file name in the entry field.&lt;/p&gt;</string>
- </property>
+ <widget class="QILabel" name="m_pLabel1">
<property name="wordWrap">
<bool>true</bool>
</property>
@@ -48,7 +45,7 @@
<property name="title">
<string>&amp;Location</string>
</property>
- <layout class="QHBoxLayout" name="m_pLayout2">
+ <layout class="QHBoxLayout" name="m_pOptionsLayout">
<item>
<widget class="QLineEdit" name="m_pLocationEditor"/>
</item>
@@ -63,10 +60,7 @@
</widget>
</item>
<item>
- <widget class="QILabel" name="m_pPage3Text2">
- <property name="text">
- <string>&lt;p&gt;Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.&lt;/p&gt;</string>
- </property>
+ <widget class="QILabel" name="m_pLabel2">
<property name="wordWrap">
<bool>true</bool>
</property>
@@ -77,7 +71,7 @@
<property name="title">
<string>&amp;Size</string>
</property>
- <layout class="QGridLayout" name="m_pLayout3">
+ <layout class="QGridLayout" name="m_pSizeLayout">
<item row="0" column="0" colspan="3">
<widget class="QSlider" name="m_pSizeSlider">
<property name="sizePolicy">
@@ -115,7 +109,7 @@
</widget>
</item>
<item row="1" column="1">
- <spacer name="m_pSpacer1">
+ <spacer name="m_pSizeSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -141,7 +135,7 @@
</widget>
</item>
<item>
- <spacer name="m_pSpacer2">
+ <spacer name="m_pSpacer">
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzdPage4.ui b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageSummary.ui
index 244ebffd8..2387756c2 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzdPage4.ui
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageSummary.ui
@@ -3,7 +3,7 @@
<comment>
VBox frontends: Qt4 GUI ("VirtualBox"):
- Copyright (C) 2009-2010 Oracle Corporation
+ Copyright (C) 2009-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;
@@ -13,8 +13,8 @@
VirtualBox OSE distribution. VirtualBox OSE is distributed in the
hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
</comment>
- <class>UINewHDWzdPage4</class>
- <widget class="QWidget" name="UINewHDWzdPage4">
+ <class>UINewHDWizardPageSummary</class>
+ <widget class="QWidget" name="UINewHDWizardPageSummary">
<property name="geometry">
<rect>
<x>0</x>
@@ -29,15 +29,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <layout class="QVBoxLayout" name="m_pLayout1">
+ <layout class="QVBoxLayout" name="m_pMainLayout">
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
- <widget class="QILabel" name="m_pPage4Text1">
- <property name="text">
- <string>You are going to create a new virtual hard disk with the following parameters:</string>
- </property>
+ <widget class="QILabel" name="m_pLabel1">
<property name="wordWrap">
<bool>true</bool>
</property>
@@ -66,14 +63,14 @@
</widget>
</item>
<item>
- <widget class="QILabel" name="m_pPage4Text2">
+ <widget class="QILabel" name="m_pLabel2">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
- <spacer name="m_pSpacer1">
+ <spacer name="m_pSpacer">
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageVariant.ui b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageVariant.ui
new file mode 100644
index 000000000..a55c21bc1
--- /dev/null
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageVariant.ui
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>
+ VBox frontends: Qt4 GUI ("VirtualBox"):
+
+ Copyright (C) 2009-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.
+ </comment>
+ <class>UINewHDWizardPageVariant</class>
+ <widget class="QWidget" name="UINewHDWizardPageVariant">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="m_pMainLayout">
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QILabel" name="m_pLabel">
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="m_pVariantContainer">
+ <property name="title">
+ <string>Storage details</string>
+ </property>
+ <layout class="QVBoxLayout" name="m_pVariantsLayout"/>
+ </widget>
+ </item>
+ <item>
+ <spacer name="m_pSpacer">
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QILabel</class>
+ <extends>QLabel</extends>
+ <header>QILabel.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzdPage2.ui b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageWelcome.ui
index 83894d7af..55722898b 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzdPage2.ui
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWizardPageWelcome.ui
@@ -3,7 +3,7 @@
<comment>
VBox frontends: Qt4 GUI ("VirtualBox"):
- Copyright (C) 2009-2010 Oracle Corporation
+ Copyright (C) 2009-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;
@@ -13,8 +13,8 @@
VirtualBox OSE distribution. VirtualBox OSE is distributed in the
hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
</comment>
- <class>UINewHDWzdPage2</class>
- <widget class="QWidget" name="UINewHDWzdPage2">
+ <class>UINewHDWizardPageWelcome</class>
+ <widget class="QWidget" name="UINewHDWizardPageWelcome">
<property name="geometry">
<rect>
<x>0</x>
@@ -29,37 +29,33 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <layout class="QVBoxLayout" name="m_pLayout1">
+ <layout class="QVBoxLayout" name="m_pMainLayout">
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
- <widget class="QILabel" name="m_pPage2Text1">
- <property name="text">
- <string>&lt;p&gt;Select the type of virtual hard disk you want to create.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;dynamically expanding storage&lt;/b&gt; initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.&lt;/p&gt;&lt;p&gt;A &lt;b&gt;fixed-size storage&lt;/b&gt; does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.&lt;/p&gt;</string>
- </property>
+ <widget class="QILabel" name="m_pLabel">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
- <widget class="QGroupBox" name="m_pTypeCnt">
+ <widget class="QGroupBox" name="m_pSourceDiskContainer">
<property name="title">
- <string>Storage Type</string>
+ <string>Virtual disk to copy</string>
</property>
- <layout class="QVBoxLayout" name="m_pLayout2">
+ <layout class="QHBoxLayout" name="m_pSourceDiskLayout">
<item>
- <widget class="QRadioButton" name="m_pTypeDynamic">
- <property name="text">
- <string>&amp;Dynamically expanding storage</string>
- </property>
- </widget>
+ <widget class="VBoxMediaComboBox" name="m_pSourceDiskSelector"/>
</item>
<item>
- <widget class="QRadioButton" name="m_pTypeFixed">
- <property name="text">
- <string>&amp;Fixed-size storage</string>
+ <widget class="QIToolButton" name="m_pOpenSourceDiskButton">
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip">
+ <string>Choose a virtual hard disk file...</string>
</property>
</widget>
</item>
@@ -67,7 +63,7 @@
</widget>
</item>
<item>
- <spacer name="m_pSpacer1">
+ <spacer name="m_pSpacer">
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
@@ -80,10 +76,20 @@
</widget>
<customwidgets>
<customwidget>
+ <class>QIToolButton</class>
+ <extends>QToolButton</extends>
+ <header>QIToolButton.h</header>
+ </customwidget>
+ <customwidget>
<class>QILabel</class>
<extends>QLabel</extends>
<header>QILabel.h</header>
</customwidget>
+ <customwidget>
+ <class>VBoxMediaComboBox</class>
+ <extends>QComboBox</extends>
+ <header>VBoxMediaComboBox.h</header>
+ </customwidget>
</customwidgets>
<resources/>
<connections/>
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzd.cpp b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzd.cpp
deleted file mode 100644
index b0a860dd4..000000000
--- a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzd.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-/* $Id: UINewHDWzd.cpp $ */
-/** @file
- *
- * VBox frontends: Qt4 GUI ("VirtualBox"):
- * UINewHDWzd class implementation
- */
-
-/*
- * Copyright (C) 2006-2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-/* Local includes */
-#include "UIIconPool.h"
-#include "UINewHDWzd.h"
-#include "VBoxGlobal.h"
-#include "VBoxProblemReporter.h"
-
-/* Global includes */
-#include "iprt/path.h"
-#include <QFileDialog>
-#include <QRegExpValidator>
-
-
-UINewHDWzd::UINewHDWzd(QWidget *pParent) : QIWizard(pParent)
-{
- /* Create & add pages */
- addPage(new UINewHDWzdPage1);
- addPage(new UINewHDWzdPage2);
- addPage(new UINewHDWzdPage3);
- addPage(new UINewHDWzdPage4);
-
- /* Initial translate */
- retranslateUi();
-
- /* Initial translate all pages */
- retranslateAllPages();
-
- /* Resize to 'golden ratio' */
- resizeToGoldenRatio();
-
-#ifdef Q_WS_MAC
- /* Assign background image */
- assignBackground(":/vmw_new_harddisk_bg.png");
-#else /* Q_WS_MAC */
- /* Assign watermark */
- assignWatermark(":/vmw_new_harddisk.png");
-#endif /* Q_WS_MAC */
-}
-
-CMedium UINewHDWzd::hardDisk() const
-{
- /* Get 'hardDisk' field value from page 4 */
- return field("hardDisk").value<CMedium>();
-}
-
-void UINewHDWzd::setRecommendedName(const QString &strName)
-{
- /* Set 'initialName' field value for page 3 */
- setField("initialName", strName);
-}
-
-void UINewHDWzd::setRecommendedSize(qulonglong uSize)
-{
- /* Set 'initialSize' field value for page 3 */
- setField("initialSize", uSize);
-}
-
-void UINewHDWzd::setDefaultPath(const QString &strDefaultPath)
-{
- m_strDefaultPath = strDefaultPath;
-}
-
-QString UINewHDWzd::absoluteFilePath(const QString &strFileName)
-{
- /* Wrap file-info around received file name: */
- QFileInfo fi(strFileName);
- /* If there is no path info at all or its relative: */
- if (fi.fileName() == strFileName || fi.isRelative())
- {
- /* Resolve path on the basis of m_strDefaultPath: */
- fi = QFileInfo(m_strDefaultPath, strFileName);
- }
- /* Return full absolute hard disk file path: */
- return QDir::toNativeSeparators(fi.absoluteFilePath());
-}
-
-void UINewHDWzd::retranslateUi()
-{
- /* Wizard title */
- setWindowTitle(tr("Create New Virtual Disk"));
-}
-
-UINewHDWzdPage1::UINewHDWzdPage1()
-{
- /* Decorate page */
- Ui::UINewHDWzdPage1::setupUi(this);
-}
-
-void UINewHDWzdPage1::retranslateUi()
-{
- /* Translate uic generated strings */
- Ui::UINewHDWzdPage1::retranslateUi(this);
-
- /* Wizard page 1 title */
- setTitle(tr("Welcome to the Create New Virtual Disk Wizard!"));
-
-
- m_pPage1Text1->setText(tr("<p>This wizard will help you to create a new virtual hard disk "
- "for your virtual machine.</p><p>%1</p>")
- .arg(standardHelpText()));
-}
-
-void UINewHDWzdPage1::initializePage()
-{
- /* Fill and translate */
- retranslateUi();
-}
-
-UINewHDWzdPage2::UINewHDWzdPage2()
- : m_strType(QString())
- , m_bFixed(false)
-{
- /* Decorate page */
- Ui::UINewHDWzdPage2::setupUi(this);
-
- /* Register 'type', 'fixed' fields */
- registerField("type*", this, "type");
- registerField("fixed", this, "fixed");
-
- /* Setup connections */
- connect (m_pTypeDynamic, SIGNAL(clicked(bool)), this, SLOT(onTypeChanged()));
- connect (m_pTypeFixed, SIGNAL(clicked(bool)), this, SLOT(onTypeChanged()));
-}
-
-void UINewHDWzdPage2::retranslateUi()
-{
- /* Translate uic generated strings */
- Ui::UINewHDWzdPage2::retranslateUi(this);
-
- /* Wizard page 2 title */
- setTitle(tr("Hard Disk Storage Type"));
-}
-
-void UINewHDWzdPage2::initializePage()
-{
- /* Fill and translate */
- retranslateUi();
-
- /* Prepare initial choice */
- m_pTypeDynamic->click();
-
- /* 'Dynamic' choice should have focus initially */
- m_pTypeDynamic->setFocus();
-}
-
-void UINewHDWzdPage2::onTypeChanged()
-{
- if (m_pTypeDynamic->isChecked())
- {
- /* 'Dynamic' storage type */
- m_strType = VBoxGlobal::removeAccelMark(m_pTypeDynamic->text());
- m_bFixed = false;
- }
- else if (m_pTypeFixed->isChecked())
- {
- /* 'Fixed' storage type */
- m_strType = VBoxGlobal::removeAccelMark(m_pTypeFixed->text());
- m_bFixed = true;
- }
- else
- {
- /* Not complete */
- m_strType.clear();
- m_bFixed = false;
- }
- emit completeChanged();
-}
-
-UINewHDWzdPage3::UINewHDWzdPage3()
- : m_strInitialName("NewHardDisk1.vdi")
- , m_strCurrentName(QString())
- , m_strLocation(QString())
- , m_uInitialSize(2 * _1K)
- , m_uCurrentSize(0)
- , m_uMinVDISize(_4M)
- , m_uMaxVDISize(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
- , m_iSliderScale(0)
-{
- /* Decorate page */
- Ui::UINewHDWzdPage3::setupUi(this);
-
- /* Register 'initialName', 'currentName', 'location' &
- * 'initialSize', 'currentSize' fields */
- registerField("initialName", this, "initialName");
- registerField("currentName", this, "currentName");
- registerField("location", this, "location");
- registerField("initialSize", this, "initialSize");
- registerField("currentSize", this, "currentSize");
-
- /* Detect how many steps to recognize between adjacent powers of 2
- * to ensure that the last slider step is exactly m_uMaxVDISize */
- int iPower = log2i(m_uMaxVDISize);
- qulonglong uTickMB = qulonglong (1) << iPower;
- if (uTickMB < m_uMaxVDISize)
- {
- qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
- qulonglong uGap = uTickMBNext - m_uMaxVDISize;
- m_iSliderScale = (int)((uTickMBNext - uTickMB) / uGap);
- }
- m_iSliderScale = qMax(m_iSliderScale, 8);
-
- /* Setup size-editor field */
- m_pSizeEditor->setFixedWidthByText("88888.88 MB");
- m_pSizeEditor->setAlignment(Qt::AlignRight);
- m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
-
- /* Setup size-slider */
- m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
- m_pSizeSlider->setPageStep(m_iSliderScale);
- m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
- m_pSizeSlider->setTickInterval(0);
- m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMinVDISize, m_iSliderScale));
- m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMaxVDISize, m_iSliderScale));
- m_pSizeMin->setText(vboxGlobal().formatSize(m_uMinVDISize));
- m_pSizeMax->setText(vboxGlobal().formatSize(m_uMaxVDISize));
-
- /* Attach button icon */
- m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
- "select_file_dis_16px.png"));
-
- /* Setup page connections */
- connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(onLocationEditorTextChanged(const QString &)));
- connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(onSelectLocationButtonClicked()));
- connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(onSizeSliderValueChanged(int)));
- connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(onSizeEditorTextChanged(const QString &)));
-}
-
-void UINewHDWzdPage3::retranslateUi()
-{
- /* Translate uic generated strings */
- Ui::UINewHDWzdPage3::retranslateUi(this);
-
- /* Wizard page 3 title */
- setTitle(tr("Virtual Disk Location and Size"));
-}
-
-void UINewHDWzdPage3::initializePage()
-{
- /* Fill and translate */
- retranslateUi();
-
- /* Initialise location */
- m_pLocationEditor->setText(m_strInitialName);
-
- /* Initialise size */
- m_pSizeSlider->setValue(sizeMBToSlider(m_uInitialSize, m_iSliderScale));
-
- /* 'Size' editor should have focus initially */
- m_pSizeEditor->setFocus();
-}
-
-void UINewHDWzdPage3::cleanupPage()
-{
- /* Do not call superclass method! */
-}
-
-bool UINewHDWzdPage3::isComplete() const
-{
- /* Check what 'currentSize' field value feats the bounds &
- * what 'currentName' field text is not empty! */
- return field("currentSize").toULongLong() >= m_uMinVDISize &&
- field("currentSize").toULongLong() <= m_uMaxVDISize &&
- !field("currentName").toString().trimmed().isEmpty();
-}
-
-bool UINewHDWzdPage3::validatePage()
-{
- QString location = qobject_cast<UINewHDWzd*>(wizard())->absoluteFilePath(m_strLocation);
- if (QFileInfo(location).exists())
- {
- vboxProblem().sayCannotOverwriteHardDiskStorage(this, location);
- return false;
- }
- return true;
-}
-
-void UINewHDWzdPage3::onLocationEditorTextChanged(const QString &strText)
-{
- /* Set current name */
- m_strCurrentName = strText;
-
- /* Set current fileName */
- m_strLocation = toFileName(strText);
-
- /* Notify wizard sub-system about complete status changed: */
- emit completeChanged();
-}
-
-void UINewHDWzdPage3::onSelectLocationButtonClicked()
-{
- /* Get parent wizard: */
- UINewHDWzd *pWizard = qobject_cast<UINewHDWzd*>(wizard());
-
- /* Get current folder and filename: */
- QFileInfo fullFilePath(pWizard->absoluteFilePath(m_strLocation));
- QDir folder = fullFilePath.path();
- QString strFileName = fullFilePath.fileName();
-
- /* Set the first parent foler that exists as the current: */
- while (!folder.exists() && !folder.isRoot())
- folder = QFileInfo(folder.absolutePath()).dir();
-
- /* But if it doesn't exists at all: */
- if (!folder.exists() || folder.isRoot())
- {
- /* Use recommended one folder: */
- QFileInfo defaultFilePath(pWizard->absoluteFilePath(strFileName));
- folder = defaultFilePath.path();
- }
-
- QString selected = QFileDialog::getSaveFileName(this, tr("Select a file for the new hard disk image file"),
- folder.absoluteFilePath(strFileName), tr("Hard disk images (*.vdi)"));
-
- if (!selected.isEmpty())
- {
- if (QFileInfo(selected).completeSuffix().isEmpty())
- selected += ".vdi";
- m_pLocationEditor->setText(QDir::toNativeSeparators(selected));
- m_pLocationEditor->selectAll();
- m_pLocationEditor->setFocus();
- }
-}
-
-void UINewHDWzdPage3::onSizeSliderValueChanged(int iValue)
-{
- /* Update currently stored size: */
- m_uCurrentSize = sliderToSizeMB(iValue, m_iSliderScale);
- /* Update tooltip: */
- updateSizeToolTip(m_uCurrentSize);
- /* Notify size-editor about size had changed preventing callback: */
- m_pSizeEditor->blockSignals(true);
- m_pSizeEditor->setText(vboxGlobal().formatSize(m_uCurrentSize));
- m_pSizeEditor->blockSignals(false);
- /* Notify wizard sub-system about complete status changed: */
- emit completeChanged();
-}
-
-void UINewHDWzdPage3::onSizeEditorTextChanged(const QString &strValue)
-{
- /* Update currently stored size: */
- m_uCurrentSize = vboxGlobal().parseSize(strValue);
- /* Update tooltip: */
- updateSizeToolTip(m_uCurrentSize);
- /* Notify size-slider about size had changed preventing callback: */
- m_pSizeSlider->blockSignals(true);
- m_pSizeSlider->setValue(sizeMBToSlider(m_uCurrentSize, m_iSliderScale));
- m_pSizeSlider->blockSignals(false);
- /* Notify wizard sub-system about complete status changed: */
- emit completeChanged();
-}
-
-QString UINewHDWzdPage3::toFileName(const QString &strName)
-{
- QString fileName = QDir::toNativeSeparators(strName);
-
- /* Remove all trailing dots to avoid multiple dots before .vdi */
- int len;
- while (len = fileName.length(), len > 0 && fileName [len - 1] == '.')
- fileName.truncate(len - 1);
-
- QString ext = QFileInfo(fileName).completeSuffix();
-
- if (RTPathCompare(ext.toUtf8(), "vdi") != 0)
- fileName += ".vdi";
-
- return fileName;
-}
-
-int UINewHDWzdPage3::log2i(qulonglong uValue)
-{
- int iPower = -1;
- while (uValue)
- {
- ++ iPower;
- uValue >>= 1;
- }
- return iPower;
-}
-
-int UINewHDWzdPage3::sizeMBToSlider(qulonglong uValue, int iSliderScale)
-{
- int iPower = log2i(uValue);
- qulonglong uTickMB = qulonglong (1) << iPower;
- qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
- int iStep = (uValue - uTickMB) * iSliderScale / (uTickMBNext - uTickMB);
- return iPower * iSliderScale + iStep;
-}
-
-qulonglong UINewHDWzdPage3::sliderToSizeMB(int uValue, int iSliderScale)
-{
- int iPower = uValue / iSliderScale;
- int iStep = uValue % iSliderScale;
- qulonglong uTickMB = qulonglong (1) << iPower;
- qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
- return uTickMB + (uTickMBNext - uTickMB) * iStep / iSliderScale;
-}
-
-void UINewHDWzdPage3::updateSizeToolTip(qulonglong uSize)
-{
- QString strToolTip = tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
- m_pSizeSlider->setToolTip(strToolTip);
- m_pSizeEditor->setToolTip(strToolTip);
-}
-
-UINewHDWzdPage4::UINewHDWzdPage4()
-{
- /* Decorate page */
- Ui::UINewHDWzdPage4::setupUi(this);
-
- /* Register CMedium class */
- qRegisterMetaType<CMedium>();
-
- /* Register 'hardDisk' field */
- registerField("hardDisk", this, "hardDisk");
-
- /* Disable the background painting of the summary widget */
- m_pSummaryText->viewport()->setAutoFillBackground (false);
- /* Make the summary field read-only */
- m_pSummaryText->setReadOnly (true);
-}
-
-void UINewHDWzdPage4::retranslateUi()
-{
- /* Translate uic generated strings */
- Ui::UINewHDWzdPage4::retranslateUi(this);
-
- /* Wizard page 4 title */
- setTitle(tr("Summary"));
-
- /* Compose common summary */
- QString summary;
-
- QString type = field("type").toString();
- QString location = qobject_cast<UINewHDWzd*>(wizard())->absoluteFilePath(field("location").toString());
- QString sizeFormatted = VBoxGlobal::formatSize(field("currentSize").toULongLong());
- QString sizeUnformatted = tr("%1 B").arg(field("currentSize").toULongLong());
-
- summary += QString
- (
- "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
- "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
- "<tr><td><nobr>%5: </nobr></td><td><nobr>%6 (%7)</nobr></td></tr>"
- )
- .arg (tr("Type", "summary"), type)
- .arg (tr("Location", "summary"), location)
- .arg (tr("Size", "summary"), sizeFormatted, sizeUnformatted)
- ;
- /* Feat summary to 3 lines */
- setSummaryFieldLinesNumber(m_pSummaryText, 3);
-
- m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + summary + "</table>");
-
- m_pPage4Text2->setText(tr("If the above settings are correct, press the <b>%1</b> button. "
- "Once you press it, a new hard disk will be created.")
- .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
-}
-
-void UINewHDWzdPage4::initializePage()
-{
- /* Fill and translate */
- retranslateUi();
-
- /* Summary should have focus initially */
- m_pSummaryText->setFocus();
-}
-
-bool UINewHDWzdPage4::validatePage()
-{
- startProcessing();
- /* Try to construct hard disk */
- bool fResult = createHardDisk();
- endProcessing();
- return fResult;
-}
-
-bool UINewHDWzdPage4::createHardDisk()
-{
- KMediumVariant variant = KMediumVariant_Standard;
- QString location = qobject_cast<UINewHDWzd*>(wizard())->absoluteFilePath(field("location").toString());
- qulonglong size = field("currentSize").toULongLong();
- bool isFixed = field("fixed").toBool();
-
- AssertReturn(!location.isNull(), false);
- AssertReturn(size > 0, false);
-
- CVirtualBox vbox = vboxGlobal().virtualBox();
-
- CProgress progress;
-
- CMedium hardDisk = vbox.CreateHardDisk(QString("VDI"), location);
-
- if (!vbox.isOk())
- {
- vboxProblem().cannotCreateHardDiskStorage(this, vbox, location, hardDisk, progress);
- return false;
- }
-
- if (isFixed)
- variant = (KMediumVariant)(KMediumVariant_Standard | KMediumVariant_Fixed);
-
- progress = hardDisk.CreateBaseStorage(size, variant);
-
- if (!hardDisk.isOk())
- {
- vboxProblem().cannotCreateHardDiskStorage(this, vbox, location, hardDisk, progress);
- return false;
- }
-
- vboxProblem().showModalProgressDialog(progress, windowTitle(), ":/progress_media_create_90px.png", this, true);
-
- if (progress.GetCanceled())
- return false;
-
- if (!progress.isOk() || progress.GetResultCode() != 0)
- {
- vboxProblem().cannotCreateHardDiskStorage(this, vbox, location, hardDisk, progress);
- return false;
- }
-
- /* Inform everybody there is a new medium */
- vboxGlobal().addMedium(VBoxMedium(CMedium(hardDisk), VBoxDefs::MediumType_HardDisk, KMediumState_Created));
-
- m_HardDisk = hardDisk;
- return true;
-}
-
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzd.h b/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzd.h
deleted file mode 100644
index 47aa38211..000000000
--- a/src/VBox/Frontends/VirtualBox/src/wizards/newhd/UINewHDWzd.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/** @file
- *
- * VBox frontends: Qt4 GUI ("VirtualBox"):
- * UINewHDWzd class declaration
- */
-
-/*
- * Copyright (C) 2006-2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#ifndef __UINewHDWzd_h__
-#define __UINewHDWzd_h__
-
-/* Local includes */
-#include "QIWizard.h"
-#include "COMDefs.h"
-
-/* Generated includes */
-#include "UINewHDWzdPage1.gen.h"
-#include "UINewHDWzdPage2.gen.h"
-#include "UINewHDWzdPage3.gen.h"
-#include "UINewHDWzdPage4.gen.h"
-
-class UINewHDWzd : public QIWizard
-{
- Q_OBJECT;
-
-public:
-
- UINewHDWzd(QWidget *pParent);
-
- CMedium hardDisk() const;
-
- void setRecommendedName(const QString &strName);
- void setRecommendedSize(qulonglong uSize);
-
- void setDefaultPath(const QString &strPath);
- QString absoluteFilePath(const QString &strFileName);
-
-protected:
-
- void retranslateUi();
-
-private:
-
- QString m_strDefaultPath;
-};
-
-class UINewHDWzdPage1 : public QIWizardPage, public Ui::UINewHDWzdPage1
-{
- Q_OBJECT;
-
-public:
-
- UINewHDWzdPage1();
-
-protected:
-
- void retranslateUi();
-
- void initializePage();
-};
-
-class UINewHDWzdPage2 : public QIWizardPage, public Ui::UINewHDWzdPage2
-{
- Q_OBJECT;
- Q_PROPERTY(QString type READ type WRITE setType);
- Q_PROPERTY(bool fixed READ fixed WRITE setFixed);
-
-public:
-
- UINewHDWzdPage2();
-
-protected:
-
- void retranslateUi();
-
- void initializePage();
-
-private slots:
-
- void onTypeChanged();
-
-private:
-
- QString type() const { return m_strType; }
- void setType(const QString &strType) { m_strType = strType; }
- QString m_strType;
-
- bool fixed() const { return m_bFixed; }
- void setFixed(bool bFixed) { m_bFixed = bFixed; }
- bool m_bFixed;
-};
-
-class UINewHDWzdPage3 : public QIWizardPage, public Ui::UINewHDWzdPage3
-{
- Q_OBJECT;
- Q_PROPERTY(QString initialName READ initialName WRITE setInitialName);
- Q_PROPERTY(QString currentName READ currentName WRITE setCurrentName);
- Q_PROPERTY(QString location READ location WRITE setLocation);
- Q_PROPERTY(qulonglong initialSize READ initialSize WRITE setInitialSize);
- Q_PROPERTY(qulonglong currentSize READ currentSize WRITE setCurrentSize);
-
-public:
-
- UINewHDWzdPage3();
-
-protected:
-
- void retranslateUi();
-
- void initializePage();
- void cleanupPage();
-
- bool isComplete() const;
- bool validatePage();
-
-private slots:
-
- void onLocationEditorTextChanged(const QString &strName);
- void onSelectLocationButtonClicked();
-
- void onSizeSliderValueChanged(int iValue);
- void onSizeEditorTextChanged(const QString &strValue);
-
-private:
-
- static QString toFileName(const QString &strName);
-
- static int log2i(qulonglong uValue);
- static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
- static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
-
- void updateSizeToolTip(qulonglong uSize);
-
- QString initialName() const { return m_strInitialName; }
- void setInitialName(const QString &strInitialName) { m_strInitialName = strInitialName; }
- QString m_strInitialName;
-
- QString currentName() const { return m_strCurrentName; }
- void setCurrentName(const QString &strCurrentName) { m_strCurrentName = strCurrentName; }
- QString m_strCurrentName;
-
- QString location() const { return m_strLocation; }
- void setLocation(const QString &strLocation) { m_strLocation = strLocation; }
- QString m_strLocation;
-
- qulonglong initialSize() const { return m_uInitialSize; }
- void setInitialSize(qulonglong uInitialSize) { m_uInitialSize = uInitialSize; }
- qulonglong m_uInitialSize;
-
- qulonglong currentSize() const { return m_uCurrentSize; }
- void setCurrentSize(qulonglong uCurrentSize) { m_uCurrentSize = uCurrentSize; }
- qulonglong m_uCurrentSize;
-
- qulonglong m_uMinVDISize;
- qulonglong m_uMaxVDISize;
- int m_iSliderScale;
-};
-
-class UINewHDWzdPage4 : public QIWizardPage, public Ui::UINewHDWzdPage4
-{
- Q_OBJECT;
- Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
-
-public:
-
- UINewHDWzdPage4();
-
-protected:
-
- void retranslateUi();
-
- void initializePage();
-
- bool validatePage();
-
-private:
-
- bool createHardDisk();
-
- CMedium hardDisk() const { return m_HardDisk; }
- void setHardDisk(const CMedium &hardDisk) { m_HardDisk = hardDisk; }
- CMedium m_HardDisk;
-};
-
-Q_DECLARE_METATYPE(CMedium);
-
-#endif // __UINewHDWzd_h__
-
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UINewVMWzd.cpp b/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UINewVMWzd.cpp
index 0cf29f758..0f15a9c9b 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UINewVMWzd.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UINewVMWzd.cpp
@@ -1,4 +1,4 @@
-/* $Id: UINewVMWzd.cpp $ */
+/* $Id: UINewVMWzd.cpp 37959 2011-07-14 13:03:03Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
@@ -22,7 +22,7 @@
/* Local includes */
#include "UIIconPool.h"
-#include "UINewHDWzd.h"
+#include "UINewHDWizard.h"
#include "UINewVMWzd.h"
#include "QIFileDialog.h"
#include "VBoxProblemReporter.h"
@@ -75,20 +75,20 @@ 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)).*64", Qt::CaseInsensitive), "Ubuntu_64" },
- { QRegExp("(edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)", Qt::CaseInsensitive), "Ubuntu" },
+ { 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("((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)).*64", Qt::CaseInsensitive), "Fedora_64" },
- { QRegExp("(moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)", Qt::CaseInsensitive), "Fedora" },
+ { 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" },
/* Regular names of Linux distributions */
{ QRegExp("Arc.*64", Qt::CaseInsensitive), "ArchLinux_64" },
{ QRegExp("Arc", Qt::CaseInsensitive), "ArchLinux" },
{ QRegExp("De.*64", Qt::CaseInsensitive), "Debian_64" },
{ QRegExp("De", Qt::CaseInsensitive), "Debian" },
- { QRegExp("((SU)|(Nov)).*64", Qt::CaseInsensitive), "OpenSUSE_64" },
- { QRegExp("(SU)|(Nov)", Qt::CaseInsensitive), "OpenSUSE" },
+ { QRegExp("((SU)|(Nov)|(SLE)).*64", Qt::CaseInsensitive), "OpenSUSE_64" },
+ { QRegExp("(SU)|(Nov)|(SLE)", Qt::CaseInsensitive), "OpenSUSE" },
{ QRegExp("Fe.*64", Qt::CaseInsensitive), "Fedora_64" },
{ QRegExp("Fe", Qt::CaseInsensitive), "Fedora" },
{ QRegExp("((Gen)|(Sab)).*64", Qt::CaseInsensitive), "Gentoo_64" },
@@ -166,6 +166,8 @@ void UINewVMWzd::retranslateUi()
{
/* Wizard title */
setWindowTitle(tr("Create New Virtual Machine"));
+
+ setButtonText(QWizard::FinishButton, tr("Create"));
}
UINewVMWzdPage1::UINewVMWzdPage1()
@@ -560,10 +562,7 @@ void UINewVMWzdPage4::getWithFileOpenDialog()
bool UINewVMWzdPage4::getWithNewHardDiskWizard()
{
- UINewHDWzd dlg(this);
- dlg.setRecommendedName(field("name").toString());
- dlg.setRecommendedSize(field("type").value<CGuestOSType>().GetRecommendedHDD());
- dlg.setDefaultPath(field("machineFolder").toString());
+ UINewHDWizard dlg(this, field("name").toString(), field("machineFolder").toString(), field("type").value<CGuestOSType>().GetRecommendedHDD());
if (dlg.exec() == QDialog::Accepted)
{
@@ -739,7 +738,7 @@ bool UINewVMWzdPage5::constructMachine()
/* VRAM size - select maximum between recommended and minimum for fullscreen */
m_Machine.SetVRAMSize (qMax (type.GetRecommendedVRAM(),
- (ULONG) (VBoxGlobal::requiredVideoMemory(&m_Machine) / _1M)));
+ (ULONG) (VBoxGlobal::requiredVideoMemory(typeId) / _1M)));
/* Selecting recommended chipset type */
m_Machine.SetChipsetType(type.GetRecommendedChipset());
@@ -880,17 +879,12 @@ bool UINewVMWzdPage5::constructMachine()
if (!success)
{
/* Unregister on failure */
-#if defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)
- /* XXX currently disabled due to a bug in ComSafeArrayIn on 64-bit Windows hosts! */
- m_Machine.Unregister(KCleanupMode_DetachAllReturnNone);
-#else
QVector<CMedium> aMedia = m_Machine.Unregister(KCleanupMode_UnregisterOnly); // @todo replace with DetachAllReturnHardDisksOnly once a progress dialog is in place below
if (vbox.isOk())
{
CProgress progress = m_Machine.Delete(aMedia);
progress.WaitForCompletion(-1); // @todo do this nicely with a progress dialog, this can delete lots of files
}
-#endif
return false;
}
}
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/registration/UIRegistrationWzd.cpp b/src/VBox/Frontends/VirtualBox/src/wizards/registration/UIRegistrationWzd.cpp
index a6f1464f4..4c7ece4f2 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/registration/UIRegistrationWzd.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/registration/UIRegistrationWzd.cpp
@@ -1,4 +1,4 @@
-/* $Id: UIRegistrationWzd.cpp $ */
+/* $Id: UIRegistrationWzd.cpp 35234 2010-12-20 09:40:31Z vboxsync $ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
diff --git a/src/VBox/GuestHost/HGSMI/Makefile.kmk b/src/VBox/GuestHost/HGSMI/Makefile.kmk
index f44ba3b55..c0461ad45 100644
--- a/src/VBox/GuestHost/HGSMI/Makefile.kmk
+++ b/src/VBox/GuestHost/HGSMI/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the common HGSMI library.
#
diff --git a/src/VBox/GuestHost/Makefile.kmk b/src/VBox/GuestHost/Makefile.kmk
index cbb12c012..c3fe08415 100644
--- a/src/VBox/GuestHost/Makefile.kmk
+++ b/src/VBox/GuestHost/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the VirtualBox Guest/Host part
#
diff --git a/src/VBox/GuestHost/OpenGL/Makefile.kmk b/src/VBox/GuestHost/OpenGL/Makefile.kmk
index 0a6413cf8..fa657099e 100644
--- a/src/VBox/GuestHost/OpenGL/Makefile.kmk
+++ b/src/VBox/GuestHost/OpenGL/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35351 2010-12-27 17:04:17Z vboxsync $
## @file
# Sub-Makefile for the VirtualBox Guest/Host OpenGL part
#
diff --git a/src/VBox/GuestHost/OpenGL/error/error.py b/src/VBox/GuestHost/OpenGL/error/error.py
index afb0f594c..b5d450799 100644
--- a/src/VBox/GuestHost/OpenGL/error/error.py
+++ b/src/VBox/GuestHost/OpenGL/error/error.py
@@ -32,11 +32,10 @@ for func_name in keys:
params = apiutil.Parameters(func_name)
print '\nstatic %s ERROR_APIENTRY error%s( %s )' % (return_type, func_name, apiutil.MakeDeclarationString(params ))
print '{'
- print '\tcrError( "ERROR SPU: Unsupported function gl%s called!" );' % func_name
# Handle the void parameter list
for (name, type, vecSize) in params:
print '\tERROR_UNUSED(%s);' % name
-
+ print '\tcrError( "ERROR SPU: Unsupported function gl%s called!" );' % func_name
if return_type != "void":
print '\treturn (%s)0;' % return_type
print '}'
diff --git a/src/VBox/GuestHost/OpenGL/error/errorspu.rc b/src/VBox/GuestHost/OpenGL/error/errorspu.rc
index af3aac9ec..c62821d41 100644
--- a/src/VBox/GuestHost/OpenGL/error/errorspu.rc
+++ b/src/VBox/GuestHost/OpenGL/error/errorspu.rc
@@ -1,4 +1,4 @@
-/* $Id: errorspu.rc $ */
+/* $Id: errorspu.rc 35319 2010-12-24 15:42:36Z vboxsync $ */
/** @file
* VBoxOGLerrorspu - Resource file containing version info and icon.
*/
diff --git a/src/VBox/GuestHost/OpenGL/glapi_parser/apiutil.py b/src/VBox/GuestHost/OpenGL/glapi_parser/apiutil.py
index d648cc848..d648cc848 100755..100644
--- a/src/VBox/GuestHost/OpenGL/glapi_parser/apiutil.py
+++ b/src/VBox/GuestHost/OpenGL/glapi_parser/apiutil.py
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_glstate.h b/src/VBox/GuestHost/OpenGL/include/cr_glstate.h
index 52703324c..c481a66af 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_glstate.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_glstate.h
@@ -168,9 +168,6 @@ struct CRContext {
CRGLSLState glsl;
#endif
- /*@todo add back buffer, depth and fbos and move out of here*/
- GLvoid *pImage; /*stored front buffer image*/
-
/** For buffering vertices for selection/feedback */
/*@{*/
GLuint vCount;
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_hash.h b/src/VBox/GuestHost/OpenGL/include/cr_hash.h
index 0713093d2..9bda74546 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_hash.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_hash.h
@@ -35,6 +35,8 @@ DECLEXPORT(GLboolean) crHashtableIsKeyUsed( const CRHashTable *h, GLuint id );
DECLEXPORT(void) crHashtableWalk( CRHashTable *hash, CRHashtableWalkCallback walkFunc , void *data);
/*Returns GL_TRUE if given hashtable hold the data, pKey is updated with key value for data in this case*/
DECLEXPORT(GLboolean) crHashtableGetDataKey(CRHashTable *pHash, void *pData, unsigned long *pKey);
+DECLEXPORT(void) crHashtableLock(CRHashTable *h);
+DECLEXPORT(void) crHashtableUnlock(CRHashTable *h);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_server.h b/src/VBox/GuestHost/OpenGL/include/cr_server.h
index 2d9bba686..e4ae49517 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_server.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_server.h
@@ -18,6 +18,7 @@
#include <iprt/types.h>
#include <iprt/err.h>
+#include <iprt/string.h>
#include <VBox/vmm/ssm.h>
@@ -25,7 +26,7 @@
extern "C" {
#endif
-#define SHCROGL_SSM_VERSION 24
+#define SHCROGL_SSM_VERSION 28
#define CR_MAX_WINDOWS 100
#define CR_MAX_CLIENTS 64
@@ -35,6 +36,30 @@ extern "C" {
typedef DECLCALLBACKPTR(void, PFNCRSERVERPRESENTFBO) (void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h);
+/* Callbacks for output of the rendered frames.
+ *
+ * This allows to pass rendered frames to an external component rather than draw them on screen.
+ *
+ * An external component registers the redirection callbacks using crVBoxServerOutputRedirectSet.
+ *
+ * The list of formats supported by the caller is obtained using CRORContextProperty.
+ * The actual format choosed by the service is passed as a CRORBegin parameter.
+ */
+typedef struct {
+ const void *pvContext; /* Supplied by crVBoxServerOutputRedirectSet. */
+ DECLR3CALLBACKMEMBER(void, CRORBegin, (const void *pvContext, void **ppvInstance,
+ const char *pszFormat));
+ DECLR3CALLBACKMEMBER(void, CRORGeometry, (void *pvInstance,
+ int32_t x, int32_t y, uint32_t w, uint32_t h));
+ DECLR3CALLBACKMEMBER(void, CRORVisibleRegion, (void *pvInstance,
+ uint32_t cRects, RTRECT *paRects));
+ DECLR3CALLBACKMEMBER(void, CRORFrame, (void *pvInstance,
+ void *pvData, uint32_t cbData));
+ DECLR3CALLBACKMEMBER(void, CROREnd, (void *pvInstance));
+ DECLR3CALLBACKMEMBER(int, CRORContextProperty, (const void *pvContext, uint32_t index,
+ void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut));
+} CROutputRedirect;
+
typedef struct {
CRrecti imagewindow; /**< coordinates in mural space */
CRrectf bounds; /**< normalized coordinates in [-1,-1] x [1,1] */
@@ -63,11 +88,15 @@ typedef struct {
GLboolean bVisible; /*guest window is visible*/
GLboolean bUseFBO; /*redirect to FBO instead of real host window*/
- GLint cVisibleRects; /*count of visible rects*/
- GLint *pVisibleRects; /*visible rects left, top, right, bottom*/
+ GLint cVisibleRects; /*count of visible rects*/
+ GLint *pVisibleRects; /*visible rects left, top, right, bottom*/
+ GLboolean bReceivedRects; /*indicates if guest did any updates for visible regions*/
GLuint idFBO, idColorTex, idDepthStencilRB;
GLuint fboWidth, fboHeight;
+ GLuint idPBO;
+
+ void *pvOutputRedirectInstance;
} CRMuralInfo;
/**
@@ -227,6 +256,12 @@ typedef struct {
GLuint currentSerialNo;
PFNCRSERVERPRESENTFBO pfnPresentFBO;
+ GLboolean bForceOffscreenRendering; /*Force server to render 3d data offscreen
+ *using callback above to update vbox framebuffers*/
+ GLboolean bUsePBOForReadback; /*Use PBO's for data readback*/
+
+ GLboolean bUseOutputRedirect; /* Whether the output redirect was set. */
+ CROutputRedirect outputRedirect;
} CRServer;
@@ -257,6 +292,10 @@ extern DECLEXPORT(int32_t) crVBoxServerSetRootVisibleRegion(GLint cRects, GLint
extern DECLEXPORT(void) crVBoxServerSetPresentFBOCB(PFNCRSERVERPRESENTFBO pfnPresentFBO);
+extern DECLEXPORT(int32_t) crVBoxServerSetOffscreenRendering(GLboolean value);
+
+extern DECLEXPORT(int32_t) crVBoxServerOutputRedirectSet(const CROutputRedirect *pCallbacks);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_spu.h b/src/VBox/GuestHost/OpenGL/include/cr_spu.h
index d6097c1fb..1836c6e42 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_spu.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_spu.h
@@ -454,6 +454,7 @@ DECLEXPORT(void) crSPUInitDispatchNops(SPUDispatchTable *table);
DECLEXPORT(int) crLoadOpenGL( crOpenGLInterface *crInterface, SPUNamedFunctionTable table[] );
DECLEXPORT(void) crUnloadOpenGL( void );
DECLEXPORT(int) crLoadOpenGLExtensions( const crOpenGLInterface *crInterface, SPUNamedFunctionTable table[] );
+DECLEXPORT(void) crSPUChangeDispatch(SPUDispatchTable *dispatch, const SPUNamedFunctionTable *newtable);
#if defined(GLX)
DECLEXPORT(XVisualInfo *)
diff --git a/src/VBox/GuestHost/OpenGL/include/state/cr_buffer.h b/src/VBox/GuestHost/OpenGL/include/state/cr_buffer.h
index 9a33ecc35..7a57aae9c 100644
--- a/src/VBox/GuestHost/OpenGL/include/state/cr_buffer.h
+++ b/src/VBox/GuestHost/OpenGL/include/state/cr_buffer.h
@@ -74,6 +74,11 @@ typedef struct {
#if defined(CR_EXT_blend_minmax) || defined(CR_EXT_blend_subtract)
GLenum blendEquation;
#endif
+
+ GLint width, height;
+ GLint storedWidth, storedHeight;
+ GLvoid *pFrontImg;
+ GLvoid *pBackImg;
} CRBufferState;
DECLEXPORT(void) crStateBufferInit(CRContext *ctx);
diff --git a/src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h b/src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h
index 2707660dd..8aa724cf8 100644
--- a/src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h
+++ b/src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h
@@ -1,4 +1,4 @@
-/* $Id: cr_framebuffer.h $ */
+/* $Id: cr_framebuffer.h 34107 2010-11-16 11:37:51Z vboxsync $ */
/** @file
* VBox crOpenGL: FBO related state info
diff --git a/src/VBox/GuestHost/OpenGL/include/state/cr_glsl.h b/src/VBox/GuestHost/OpenGL/include/state/cr_glsl.h
index 21e12e0f1..c9409b354 100644
--- a/src/VBox/GuestHost/OpenGL/include/state/cr_glsl.h
+++ b/src/VBox/GuestHost/OpenGL/include/state/cr_glsl.h
@@ -1,4 +1,4 @@
-/* $Id: cr_glsl.h $ */
+/* $Id: cr_glsl.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBox crOpenGL: GLSL related state info
diff --git a/src/VBox/GuestHost/OpenGL/packer/pack_client.c b/src/VBox/GuestHost/OpenGL/packer/pack_client.c
index 878d5d181..01e67f628 100644
--- a/src/VBox/GuestHost/OpenGL/packer/pack_client.c
+++ b/src/VBox/GuestHost/OpenGL/packer/pack_client.c
@@ -558,7 +558,7 @@ crPackExpandArrayElement(GLint index, CRClientState *c)
if (array->a[VERT_ATTRIB_POS].enabled)
{
- crPackVertexAttrib(array, 0, index);
+ crPackVertexAttrib(array, VERT_ATTRIB_POS, index);
}
else if (array->v.enabled)
{
diff --git a/src/VBox/GuestHost/OpenGL/packer/pack_framebuffer.c b/src/VBox/GuestHost/OpenGL/packer/pack_framebuffer.c
index f4d13b362..b2d44caa6 100644
--- a/src/VBox/GuestHost/OpenGL/packer/pack_framebuffer.c
+++ b/src/VBox/GuestHost/OpenGL/packer/pack_framebuffer.c
@@ -1,4 +1,4 @@
-/* $Id: pack_framebuffer.c $ */
+/* $Id: pack_framebuffer.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox OpenGL: EXT_framebuffer_object
diff --git a/src/VBox/GuestHost/OpenGL/packer/pack_shaders.c b/src/VBox/GuestHost/OpenGL/packer/pack_shaders.c
index afffcac53..aa92b7d58 100644
--- a/src/VBox/GuestHost/OpenGL/packer/pack_shaders.c
+++ b/src/VBox/GuestHost/OpenGL/packer/pack_shaders.c
@@ -1,4 +1,4 @@
-/* $Id: pack_shaders.c $ */
+/* $Id: pack_shaders.c 37393 2011-06-09 14:06:42Z vboxsync $ */
/** @file
* VBox OpenGL DRI driver functions
@@ -601,8 +601,8 @@ void PACK_APIENTRY crPackBindAttribLocationSWAP(GLuint program, GLuint index, co
(void)program;
(void)index;
(void)name;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackShaderSourceSWAP(GLuint shader, GLsizei count, const char **string, const GLint *length)
@@ -612,8 +612,8 @@ void PACK_APIENTRY crPackShaderSourceSWAP(GLuint shader, GLsizei count, const ch
(void)count;
(void)string;
(void)length;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniform1fvSWAP(GLint location, GLsizei count, const GLfloat *value)
@@ -622,8 +622,8 @@ void PACK_APIENTRY crPackUniform1fvSWAP(GLint location, GLsizei count, const GLf
(void)location;
(void)count;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
@@ -633,8 +633,8 @@ void PACK_APIENTRY crPackUniform1ivSWAP(GLint location, GLsizei count, const GLi
(void)location;
(void)count;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniform2fvSWAP(GLint location, GLsizei count, const GLfloat *value)
@@ -643,8 +643,8 @@ void PACK_APIENTRY crPackUniform2fvSWAP(GLint location, GLsizei count, const GLf
(void)location;
(void)count;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniform2ivSWAP(GLint location, GLsizei count, const GLint * value)
@@ -653,8 +653,8 @@ void PACK_APIENTRY crPackUniform2ivSWAP(GLint location, GLsizei count, const GLi
(void)location;
(void)count;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniform3fvSWAP(GLint location, GLsizei count, const GLfloat *value)
@@ -663,8 +663,8 @@ void PACK_APIENTRY crPackUniform3fvSWAP(GLint location, GLsizei count, const GLf
(void)location;
(void)count;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniform3ivSWAP(GLint location, GLsizei count, const GLint *value)
@@ -673,8 +673,8 @@ void PACK_APIENTRY crPackUniform3ivSWAP(GLint location, GLsizei count, const GLi
(void)location;
(void)count;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniform4fvSWAP(GLint location, GLsizei count, const GLfloat *value)
@@ -683,8 +683,8 @@ void PACK_APIENTRY crPackUniform4fvSWAP(GLint location, GLsizei count, const GLf
(void)location;
(void)count;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniform4ivSWAP(GLint location, GLsizei count, const GLint *value)
@@ -693,8 +693,8 @@ void PACK_APIENTRY crPackUniform4ivSWAP(GLint location, GLsizei count, const GLi
(void)location;
(void)count;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniformMatrix2fvSWAP(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
@@ -704,8 +704,8 @@ void PACK_APIENTRY crPackUniformMatrix2fvSWAP(GLint location, GLsizei count, GLb
(void)count;
(void)transpose;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniformMatrix3fvSWAP(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
@@ -715,8 +715,8 @@ void PACK_APIENTRY crPackUniformMatrix3fvSWAP(GLint location, GLsizei count, GLb
(void)count;
(void)transpose;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniformMatrix4fvSWAP(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
@@ -726,8 +726,8 @@ void PACK_APIENTRY crPackUniformMatrix4fvSWAP(GLint location, GLsizei count, GLb
(void)count;
(void)transpose;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniformMatrix2x3fvSWAP(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
@@ -737,8 +737,8 @@ void PACK_APIENTRY crPackUniformMatrix2x3fvSWAP(GLint location, GLsizei count, G
(void)count;
(void)transpose;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniformMatrix3x2fvSWAP(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
@@ -748,8 +748,8 @@ void PACK_APIENTRY crPackUniformMatrix3x2fvSWAP(GLint location, GLsizei count, G
(void)count;
(void)transpose;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniformMatrix2x4fvSWAP(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
@@ -759,8 +759,8 @@ void PACK_APIENTRY crPackUniformMatrix2x4fvSWAP(GLint location, GLsizei count, G
(void)count;
(void)transpose;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniformMatrix4x2fvSWAP(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
@@ -770,8 +770,8 @@ void PACK_APIENTRY crPackUniformMatrix4x2fvSWAP(GLint location, GLsizei count, G
(void)count;
(void)transpose;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniformMatrix3x4fvSWAP(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
@@ -781,8 +781,8 @@ void PACK_APIENTRY crPackUniformMatrix3x4fvSWAP(GLint location, GLsizei count, G
(void)count;
(void)transpose;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackUniformMatrix4x3fvSWAP(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
@@ -792,8 +792,8 @@ void PACK_APIENTRY crPackUniformMatrix4x3fvSWAP(GLint location, GLsizei count, G
(void)count;
(void)transpose;
(void)value;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackDrawBuffersSWAP(GLsizei n, const GLenum *bufs)
@@ -801,8 +801,8 @@ void PACK_APIENTRY crPackDrawBuffersSWAP(GLsizei n, const GLenum *bufs)
CR_GET_PACKER_CONTEXT(pc);
(void)n;
(void)bufs;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackGetAttribLocationSWAP(GLuint program, const char * name, GLint * return_value, int * writeback)
@@ -812,8 +812,8 @@ void PACK_APIENTRY crPackGetAttribLocationSWAP(GLuint program, const char * name
(void)name;
(void)return_value;
(void)writeback;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
void PACK_APIENTRY crPackGetUniformLocationSWAP(GLuint program, const char * name, GLint * return_value, int * writeback)
@@ -823,6 +823,6 @@ void PACK_APIENTRY crPackGetUniformLocationSWAP(GLuint program, const char * nam
(void)name;
(void)return_value;
(void)writeback;
+ (void)pc;
crError ("No swap version");
- (void) pc;
}
diff --git a/src/VBox/GuestHost/OpenGL/packer/pack_texture.c b/src/VBox/GuestHost/OpenGL/packer/pack_texture.c
index 6405b8620..a88d307c9 100644
--- a/src/VBox/GuestHost/OpenGL/packer/pack_texture.c
+++ b/src/VBox/GuestHost/OpenGL/packer/pack_texture.c
@@ -521,8 +521,10 @@ crPackTexParameterfv(GLenum target, GLenum pname, const GLfloat * params)
{
CR_GET_PACKER_CONTEXT(pc);
if (__handleTexParameterData(target, pname, params))
+ {
WRITE_OPCODE(pc, CR_TEXPARAMETERFV_OPCODE);
- CR_UNLOCK_PACKER_CONTEXT(pc);
+ CR_UNLOCK_PACKER_CONTEXT(pc);
+ }
}
void PACK_APIENTRY
@@ -530,8 +532,10 @@ crPackTexParameteriv(GLenum target, GLenum pname, const GLint * params)
{
CR_GET_PACKER_CONTEXT(pc);
if (__handleTexParameterData(target, pname, (GLfloat *) params))
+ {
WRITE_OPCODE(pc, CR_TEXPARAMETERIV_OPCODE);
- CR_UNLOCK_PACKER_CONTEXT(pc);
+ CR_UNLOCK_PACKER_CONTEXT(pc);
+ }
}
void PACK_APIENTRY
diff --git a/src/VBox/GuestHost/OpenGL/packer/pack_visibleregion.c b/src/VBox/GuestHost/OpenGL/packer/pack_visibleregion.c
index d76fc29ce..d76fc29ce 100644..100755
--- a/src/VBox/GuestHost/OpenGL/packer/pack_visibleregion.c
+++ b/src/VBox/GuestHost/OpenGL/packer/pack_visibleregion.c
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/glloader.py b/src/VBox/GuestHost/OpenGL/spu_loader/glloader.py
index 8c15d3df7..2b4927559 100644
--- a/src/VBox/GuestHost/OpenGL/spu_loader/glloader.py
+++ b/src/VBox/GuestHost/OpenGL/spu_loader/glloader.py
@@ -65,7 +65,7 @@ static CRDLL *aglDll = NULL;
#define GLLOADER_APIENTRY
#endif
-#if defined(WINDOWS) && (defined(DEBUG_leo) || defined(DEBUG_ll158262))
+#if defined(WINDOWS) && (defined(DEBUG_leo) || defined(DEBUG_ll158262) || defined(DEBUG_misha))
# define CR_NO_GL_SYSTEM_PATH 1
#endif
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/loader.def b/src/VBox/GuestHost/OpenGL/spu_loader/loader.def
index 91e0f6eec..420652359 100644
--- a/src/VBox/GuestHost/OpenGL/spu_loader/loader.def
+++ b/src/VBox/GuestHost/OpenGL/spu_loader/loader.def
@@ -18,3 +18,4 @@ crLoadOpenGLExtensions
crLoadOpenGL
crUnloadOpenGL
crChooseVisual
+crSPUChangeDispatch
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/spuchange.py b/src/VBox/GuestHost/OpenGL/spu_loader/spuchange.py
index a290bae71..0f763f8de 100644
--- a/src/VBox/GuestHost/OpenGL/spu_loader/spuchange.py
+++ b/src/VBox/GuestHost/OpenGL/spu_loader/spuchange.py
@@ -53,3 +53,20 @@ print """
table->mark = 0;
"""
print '}'
+
+print """
+void crSPUChangeDispatch(SPUDispatchTable *dispatch, const SPUNamedFunctionTable *newtable)
+{
+ SPUGenericFunction func;
+"""
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+for func_name in keys:
+ print '\tfunc = crSPUFindFunction(newtable, "%s");' % func_name
+ print '\tif (func && ((SPUGenericFunction)dispatch->%s!=func))' % func_name
+ print '\t{'
+ print '\t\tcrDebug("%%s changed from %%p to %%p", "gl%s", dispatch->%s, func);' % (func_name, func_name)
+ print '\t\tcrSPUChangeInterface(dispatch, dispatch->%s, func);' % func_name
+ print '\t}\n'
+print """
+}
+""" \ No newline at end of file
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_buffer.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_buffer.c
index 2f863a198..6214e8897 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_buffer.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_buffer.c
@@ -16,6 +16,13 @@ void crStateBufferInit (CRContext *ctx)
CRBufferBits *bb = &(sb->buffer);
GLcolorf zero_colorf = {0.0f, 0.0f, 0.0f, 0.0f};
+ b->width = 640;
+ b->height = 480;
+ b->storedWidth = 0;
+ b->storedHeight = 0;
+ b->pFrontImg = NULL;
+ b->pBackImg = NULL;
+
b->depthTest = GL_FALSE;
b->blend = GL_FALSE;
b->alphaTest = GL_FALSE;
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_client.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_client.c
index 277cf96f1..6e240d27a 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_client.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_client.c
@@ -1444,11 +1444,29 @@ static void crStateLockClientPointer(CRClientPointer* cp)
}
}
+static GLboolean crStateCanLockClientPointer(CRClientPointer* cp)
+{
+ return !(cp->enabled && cp->buffer && cp->buffer->id);
+}
+
void STATE_APIENTRY crStateLockArraysEXT(GLint first, GLint count)
{
CRContext *g = GetCurrentContext();
CRClientState *c = &(g->client);
- unsigned int i;
+ int i;
+
+ for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
+ {
+ if (!crStateCanLockClientPointer(crStateGetClientPointerByIndex(i, &c->array)))
+ {
+ break;
+ }
+ }
+ if (i<CRSTATECLIENT_MAX_VERTEXARRAYS)
+ {
+ crDebug("crStateLockArraysEXT ignored because array %i have a bound VBO", i);
+ return;
+ }
c->array.locked = GL_TRUE;
c->array.lockFirst = first;
@@ -1457,20 +1475,9 @@ void STATE_APIENTRY crStateLockArraysEXT(GLint first, GLint count)
c->array.synced = GL_FALSE;
#endif
- crStateLockClientPointer(&c->array.v);
- crStateLockClientPointer(&c->array.c);
- crStateLockClientPointer(&c->array.f);
- crStateLockClientPointer(&c->array.s);
- crStateLockClientPointer(&c->array.e);
- crStateLockClientPointer(&c->array.i);
- crStateLockClientPointer(&c->array.n);
- for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
- {
- crStateLockClientPointer(&c->array.t[i]);
- }
- for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
+ for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
{
- crStateLockClientPointer(&c->array.a[i]);
+ crStateLockClientPointer(crStateGetClientPointerByIndex(i, &c->array));
}
}
@@ -1478,27 +1485,22 @@ void STATE_APIENTRY crStateUnlockArraysEXT()
{
CRContext *g = GetCurrentContext();
CRClientState *c = &(g->client);
- unsigned int i;
+ int i;
+
+ if (!c->array.locked)
+ {
+ crDebug("crStateUnlockArraysEXT ignored because arrays aren't locked");
+ return;
+ }
c->array.locked = GL_FALSE;
#ifdef IN_GUEST
c->array.synced = GL_FALSE;
#endif
- crStateUnlockClientPointer(&c->array.v);
- crStateUnlockClientPointer(&c->array.c);
- crStateUnlockClientPointer(&c->array.f);
- crStateUnlockClientPointer(&c->array.s);
- crStateUnlockClientPointer(&c->array.e);
- crStateUnlockClientPointer(&c->array.i);
- crStateUnlockClientPointer(&c->array.n);
- for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
+ for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
{
- crStateUnlockClientPointer(&c->array.t[i]);
- }
- for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
- {
- crStateUnlockClientPointer(&c->array.a[i]);
+ crStateUnlockClientPointer(crStateGetClientPointerByIndex(i, &c->array));
}
}
@@ -1627,6 +1629,7 @@ crStateClientDiff(CRClientBits *cb, CRbitvalue *bitID,
{
CRClientState *from = &(fromCtx->client);
const CRClientState *to = &(toCtx->client);
+ GLint curClientTextureUnit = from->curClientTextureUnit;
int i;
if (CHECKDIRTY(cb->clientPointer, bitID)) {
@@ -1698,6 +1701,7 @@ crStateClientDiff(CRClientBits *cb, CRbitvalue *bitID,
from->array.t[i].stride != to->array.t[i].stride ||
from->array.t[i].buffer != to->array.t[i].buffer) {
diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
+ curClientTextureUnit = i;
diff_api.TexCoordPointer(to->array.t[i].size, to->array.t[i].type,
to->array.t[i].stride, to->array.t[i].p);
from->array.t[i].size = to->array.t[i].size;
@@ -1801,6 +1805,7 @@ crStateClientDiff(CRClientBits *cb, CRbitvalue *bitID,
for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
if (from->array.t[i].enabled != to->array.t[i].enabled) {
diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
+ curClientTextureUnit = i;
able[to->array.t[i].enabled](GL_TEXTURE_COORD_ARRAY);
from->array.t[i].enabled = to->array.t[i].enabled;
}
@@ -1828,6 +1833,11 @@ crStateClientDiff(CRClientBits *cb, CRbitvalue *bitID,
}
CLEARDIRTY2(cb->enableClientState, bitID);
}
+
+ if (to->curClientTextureUnit != curClientTextureUnit)
+ {
+ diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + to->curClientTextureUnit);
+ }
}
@@ -1837,6 +1847,7 @@ crStateClientSwitch(CRClientBits *cb, CRbitvalue *bitID,
{
const CRClientState *from = &(fromCtx->client);
const CRClientState *to = &(toCtx->client);
+ GLint curClientTextureUnit = from->curClientTextureUnit;
int i;
if (CHECKDIRTY(cb->clientPointer, bitID)) {
@@ -1902,6 +1913,7 @@ crStateClientSwitch(CRClientBits *cb, CRbitvalue *bitID,
from->array.t[i].stride != to->array.t[i].stride ||
from->array.t[i].buffer != to->array.t[i].buffer) {
diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
+ curClientTextureUnit = i;
diff_api.TexCoordPointer(to->array.t[i].size, to->array.t[i].type,
to->array.t[i].stride, to->array.t[i].p);
FILLDIRTY(cb->t[i]);
@@ -2001,6 +2013,7 @@ crStateClientSwitch(CRClientBits *cb, CRbitvalue *bitID,
for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
if (from->array.t[i].enabled != to->array.t[i].enabled) {
diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
+ curClientTextureUnit = i;
able[to->array.t[i].enabled](GL_TEXTURE_COORD_ARRAY);
FILLDIRTY(cb->enableClientState);
FILLDIRTY(cb->dirty);
@@ -2034,6 +2047,11 @@ crStateClientSwitch(CRClientBits *cb, CRbitvalue *bitID,
CLEARDIRTY2(cb->enableClientState, bitID);
}
+ if (to->curClientTextureUnit != curClientTextureUnit)
+ {
+ diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + to->curClientTextureUnit);
+ }
+
CLEARDIRTY2(cb->dirty, bitID);
}
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
index 51f293763..60ec1ee12 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
@@ -7,6 +7,7 @@
#include "state.h"
#include "cr_error.h"
#include "cr_mem.h"
+#include "cr_pixeldata.h"
void crStateDiffContext( CRContext *from, CRContext *to )
{
@@ -122,9 +123,9 @@ void crStateDiffContext( CRContext *from, CRContext *to )
void crStateApplyFBImage(CRContext *to)
{
- if (to->pImage)
+ if (to->buffer.pFrontImg || to->buffer.pBackImg)
{
- CRViewportState *pVP = &to->viewport;
+ CRBufferState *pBuf = &to->buffer;
CRPixelPackState unpack = to->client.unpack;
diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
@@ -136,13 +137,69 @@ void crStateApplyFBImage(CRContext *to)
diff_api.PixelStorei(GL_UNPACK_SWAP_BYTES, 0);
diff_api.PixelStorei(GL_UNPACK_LSB_FIRST, 0);
- diff_api.DrawBuffer(GL_FRONT);
- diff_api.WindowPos2iARB(0, 0);
- diff_api.DrawPixels(pVP->viewportW, pVP->viewportH, GL_RGBA, GL_UNSIGNED_BYTE, to->pImage);
+ if (to->framebufferobject.drawFB)
+ {
+ diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
+ }
+
+ if (to->bufferobject.unpackBuffer->hwid>0)
+ {
+ diff_api.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ }
+
+ diff_api.Disable(GL_ALPHA_TEST);
+ diff_api.Disable(GL_SCISSOR_TEST);
+ diff_api.Disable(GL_BLEND);
+ diff_api.Disable(GL_COLOR_LOGIC_OP);
+
+ if (pBuf->pFrontImg)
+ {
+ diff_api.DrawBuffer(GL_FRONT);
+ diff_api.WindowPos2iARB(0, 0);
+ diff_api.DrawPixels(pBuf->storedWidth, pBuf->storedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pBuf->pFrontImg);
+ crDebug("Applied %ix%i fb image", pBuf->storedWidth, pBuf->storedHeight);
+ crFree(pBuf->pFrontImg);
+ pBuf->pFrontImg = NULL;
+ }
+
+ if (pBuf->pBackImg)
+ {
+ diff_api.DrawBuffer(GL_BACK);
+ diff_api.WindowPos2iARB(0, 0);
+ diff_api.DrawPixels(pBuf->storedWidth, pBuf->storedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pBuf->pBackImg);
+ crDebug("Applied %ix%i bb image", pBuf->storedWidth, pBuf->storedHeight);
+ crFree(pBuf->pBackImg);
+ pBuf->pBackImg = NULL;
+ }
diff_api.WindowPos3fvARB(to->current.rasterAttrib[VERT_ATTRIB_POS]);
+ if (to->bufferobject.unpackBuffer->hwid>0)
+ {
+ diff_api.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, to->bufferobject.unpackBuffer->hwid);
+ }
+ if (to->framebufferobject.drawFB)
+ {
+ diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, to->framebufferobject.drawFB->hwid);
+ }
diff_api.DrawBuffer(to->framebufferobject.drawFB ?
to->framebufferobject.drawFB->drawbuffer[0] : to->buffer.drawBuffer);
+ if (to->buffer.alphaTest)
+ {
+ diff_api.Enable(GL_ALPHA_TEST);
+ }
+ if (to->viewport.scissorTest)
+ {
+ diff_api.Enable(GL_SCISSOR_TEST);
+ }
+ if (to->buffer.blend)
+ {
+ diff_api.Enable(GL_BLEND);
+ }
+ if (to->buffer.logicOp)
+ {
+ diff_api.Enable(GL_COLOR_LOGIC_OP);
+ }
+
diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, unpack.skipRows);
diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, unpack.skipPixels);
diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, unpack.alignment);
@@ -153,11 +210,6 @@ void crStateApplyFBImage(CRContext *to)
diff_api.PixelStorei(GL_UNPACK_LSB_FIRST, unpack.psLSBFirst);
diff_api.Finish();
-
- crDebug("Applied %ix%i fb image", pVP->viewportW, pVP->viewportH);
-
- crFree(to->pImage);
- to->pImage = NULL;
}
}
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c
index d2327de63..ddda089da 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c
@@ -1,4 +1,4 @@
-/* $Id: state_framebuffer.c $ */
+/* $Id: state_framebuffer.c 37394 2011-06-09 15:25:30Z vboxsync $ */
/** @file
* VBox OpenGL: EXT_framebuffer_object state tracking
@@ -734,6 +734,9 @@ crStateFramebufferObjectSwitch(CRContext *from, CRContext *to)
diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, to->framebufferobject.readFB?
to->framebufferobject.readFB->hwid:0);
}
+
+ diff_api.DrawBuffer(to->framebufferobject.drawFB?to->framebufferobject.drawFB->drawbuffer[0]:to->buffer.drawBuffer);
+ diff_api.ReadBuffer(to->framebufferobject.readFB?to->framebufferobject.readFB->readbuffer:to->buffer.readBuffer);
}
if (to->framebufferobject.renderbuffer!=from->framebufferobject.renderbuffer)
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c
index 493ac8cf9..50a2e79e9 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c
@@ -1,4 +1,4 @@
-/* $Id: state_glsl.c $ */
+/* $Id: state_glsl.c 37773 2011-07-04 18:07:09Z vboxsync $ */
/** @file
* VBox OpenGL: GLSL state tracking
@@ -641,6 +641,8 @@ DECLEXPORT(GLint) STATE_APIENTRY crStateGetUniformSize(GLenum type)
case GL_SAMPLER_CUBE:
case GL_SAMPLER_1D_SHADOW:
case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_2D_RECT_ARB:
+ case GL_SAMPLER_2D_RECT_SHADOW_ARB:
size = 1;
break;
#ifdef CR_OPENGL_VERSION_2_1
@@ -687,7 +689,9 @@ DECLEXPORT(GLboolean) STATE_APIENTRY crStateIsIntUniform(GLenum type)
|| GL_SAMPLER_3D==type
|| GL_SAMPLER_CUBE==type
|| GL_SAMPLER_1D_SHADOW==type
- || GL_SAMPLER_2D_SHADOW==type)
+ || GL_SAMPLER_2D_SHADOW==type
+ || GL_SAMPLER_2D_RECT_ARB==type
+ || GL_SAMPLER_2D_RECT_SHADOW_ARB==type)
{
return GL_TRUE;
}
@@ -1102,6 +1106,8 @@ static void crStateGLSLCreateProgramCB(unsigned long key, void *data1, void *dat
case GL_SAMPLER_CUBE:
case GL_SAMPLER_1D_SHADOW:
case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_2D_RECT_ARB:
+ case GL_SAMPLER_2D_RECT_SHADOW_ARB:
diff_api.Uniform1iv(location, 1, pIdata);
break;
#ifdef CR_OPENGL_VERSION_2_1
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c
index c1eb7c9e8..156feae25 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c
@@ -156,8 +156,6 @@ crStateCreateContextId(int i, const CRLimitsState *limits,
int node32 = i >> 5;
int node = i & 0x1f;
- ctx->pImage = NULL;
-
ctx->id = i;
ctx->flush_func = NULL;
for (j=0;j<CR_MAX_BITARRAY;j++){
@@ -275,7 +273,8 @@ crStateFreeContext(CRContext *ctx)
crStateFreeShared(ctx->shared);
crStateFramebufferObjectDestroy(ctx);
crStateGLSLDestroy(ctx);
- if (ctx->pImage) crFree(ctx->pImage);
+ if (ctx->buffer.pFrontImg) crFree(ctx->buffer.pFrontImg);
+ if (ctx->buffer.pBackImg) crFree(ctx->buffer.pBackImg);
crFree( ctx );
}
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_program.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_program.c
index a02b52882..2b0940bb3 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_program.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_program.c
@@ -1594,7 +1594,7 @@ void STATE_APIENTRY crStateDisableVertexAttribArrayARB(GLuint index)
if (index >= g->limits.maxVertexProgramAttribs) {
crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
- "glEnableVertexAttribArrayARB(index)");
+ "glDisableVertexAttribArrayARB(index)");
return;
}
c->array.a[index].enabled = GL_FALSE;
@@ -2105,8 +2105,7 @@ crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
if (from->vpPointSize != to->vpPointSize) {
able[to->vpPointSize](GL_VERTEX_PROGRAM_POINT_SIZE_NV);
}
-
- CLEARDIRTY(b->vpEnable, nbitID);
+ DIRTY(b->vpEnable, nbitID);
}
/* fragment program enable */
@@ -2120,7 +2119,7 @@ crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
if (from->fpEnabledARB != to->fpEnabledARB) {
able[to->fpEnabledARB](GL_FRAGMENT_PROGRAM_ARB);
}
- CLEARDIRTY(b->fpEnable, nbitID);
+ DIRTY(b->fpEnable, nbitID);
}
/* program/track matrices */
@@ -2132,7 +2131,7 @@ crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
to->TrackMatrix[i],
to->TrackMatrixTransform[i]);
}
- CLEARDIRTY(b->trackMatrix[i], nbitID);
+ DIRTY(b->trackMatrix[i], nbitID);
}
}
}
@@ -2148,23 +2147,18 @@ crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
else
diff_api.BindProgramNV(GL_VERTEX_PROGRAM_NV, toProg->id);
}
- CLEARDIRTY(b->vpBinding, nbitID);
+ DIRTY(b->vpBinding, nbitID);
}
if (toProg) {
/* vertex program text */
if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
if (toProg->isARBprogram)
- diff_api.ProgramStringARB( GL_VERTEX_PROGRAM_ARB,
- toProg->format,
- toProg->length,
- toProg->string );
+ diff_api.ProgramStringARB(GL_VERTEX_PROGRAM_ARB, toProg->format, toProg->length, toProg->string);
else
- diff_api.LoadProgramNV( GL_VERTEX_PROGRAM_NV,
- toProg->id,
- toProg->length,
- toProg->string );
- CLEARDIRTY(toProg->dirtyProgram, nbitID);
+ diff_api.LoadProgramNV(GL_VERTEX_PROGRAM_NV, toProg->id, toProg->length, toProg->string);
+
+ DIRTY(toProg->dirtyProgram, nbitID);
}
/* vertex program global/env parameters */
@@ -2172,15 +2166,14 @@ crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
for (i = 0; i < toCtx->limits.maxVertexProgramEnvParams; i++) {
if (CHECKDIRTY(b->vertexEnvParameter[i], bitID)) {
if (toProg->isARBprogram)
- diff_api.ProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i,
- to->vertexParameters[i]);
+ diff_api.ProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i, to->vertexParameters[i]);
else
- diff_api.ProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, i,
- to->vertexParameters[i]);
- CLEARDIRTY(b->vertexEnvParameter[i], nbitID);
+ diff_api.ProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, i, to->vertexParameters[i]);
+
+ DIRTY(b->vertexEnvParameter[i], nbitID);
}
}
- CLEARDIRTY(b->vertexEnvParameters, nbitID);
+ DIRTY(b->vertexEnvParameters, nbitID);
}
/* vertex program local parameters */
@@ -2195,7 +2188,7 @@ crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
diff_api.ProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_NV, i, toProg->parameters[i]);
}
}
- CLEARDIRTY(toProg->dirtyParams, nbitID);
+ DIRTY(toProg->dirtyParams, nbitID);
}
}
}
@@ -2211,15 +2204,14 @@ crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
if (fromProg->id != toProg->id) {
diff_api.BindProgramNV(GL_FRAGMENT_PROGRAM_NV, toProg->id);
}
- CLEARDIRTY(b->fpBinding, nbitID);
+ DIRTY(b->fpBinding, nbitID);
}
if (toProg) {
/* fragment program text */
if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
- diff_api.LoadProgramNV( GL_FRAGMENT_PROGRAM_NV, toProg->id,
- toProg->length, toProg->string );
- CLEARDIRTY(toProg->dirtyProgram, nbitID);
+ diff_api.LoadProgramNV(GL_FRAGMENT_PROGRAM_NV, toProg->id, toProg->length, toProg->string);
+ DIRTY(toProg->dirtyProgram, nbitID);
}
/* fragment program global/env parameters */
@@ -2228,10 +2220,10 @@ crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
if (CHECKDIRTY(b->fragmentEnvParameter[i], bitID)) {
diff_api.ProgramParameter4fvNV(GL_FRAGMENT_PROGRAM_NV, i,
to->fragmentParameters[i]);
- CLEARDIRTY(b->fragmentEnvParameter[i], nbitID);
+ DIRTY(b->fragmentEnvParameter[i], nbitID);
}
}
- CLEARDIRTY(b->fragmentEnvParameters, nbitID);
+ DIRTY(b->fragmentEnvParameters, nbitID);
}
/* named local parameters */
@@ -2243,10 +2235,10 @@ crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
diff_api.ProgramNamedParameter4fvNV(toProg->id, len,
(const GLubyte *) symbol->name,
symbol->value);
- CLEARDIRTY(symbol->dirty, nbitID);
+ DIRTY(symbol->dirty, nbitID);
}
}
- CLEARDIRTY(toProg->dirtyNamedParams, nbitID);
+ DIRTY(toProg->dirtyNamedParams, nbitID);
}
/* numbered local parameters */
@@ -2254,14 +2246,12 @@ crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS; i++) {
if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
if (toProg->isARBprogram)
- diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i,
- toProg->parameters[i]);
+ diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i, toProg->parameters[i]);
else
- diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_NV, i,
- toProg->parameters[i]);
+ diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_NV, i, toProg->parameters[i]);
}
}
- CLEARDIRTY(toProg->dirtyParams, nbitID);
+ DIRTY(toProg->dirtyParams, nbitID);
}
}
}
@@ -2273,44 +2263,41 @@ crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
if (fromProg->id != toProg->id) {
diff_api.BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, toProg->id);
}
- CLEARDIRTY(b->fpBinding, nbitID);
+ DIRTY(b->fpBinding, nbitID);
}
if (toProg) {
/* fragment program text */
if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
- diff_api.ProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, toProg->format,
- toProg->length, toProg->string );
- CLEARDIRTY(toProg->dirtyProgram, nbitID);
+ diff_api.ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, toProg->format, toProg->length, toProg->string);
+ DIRTY(toProg->dirtyProgram, nbitID);
}
/* fragment program global/env parameters */
if (CHECKDIRTY(b->fragmentEnvParameters, bitID)) {
for (i = 0; i < toCtx->limits.maxFragmentProgramEnvParams; i++) {
if (CHECKDIRTY(b->fragmentEnvParameter[i], bitID)) {
- diff_api.ProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i,
- to->fragmentParameters[i]);
- CLEARDIRTY(b->fragmentEnvParameter[i], nbitID);
+ diff_api.ProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i, to->fragmentParameters[i]);
+ DIRTY(b->fragmentEnvParameter[i], nbitID);
}
}
- CLEARDIRTY(b->fragmentEnvParameters, nbitID);
+ DIRTY(b->fragmentEnvParameters, nbitID);
}
/* numbered local parameters */
if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS; i++) {
if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
- diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i,
- toProg->parameters[i]);
- CLEARDIRTY(toProg->dirtyParam[i], nbitID);
+ diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i, toProg->parameters[i]);
+ DIRTY(toProg->dirtyParam[i], nbitID);
}
}
- CLEARDIRTY(toProg->dirtyParams, nbitID);
+ DIRTY(toProg->dirtyParams, nbitID);
}
}
}
- CLEARDIRTY(b->dirty, nbitID);
+ DIRTY(b->dirty, nbitID);
/* Resend program data */
if (toCtx->program.bResyncNeeded)
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c
index decdaf045..509dedd62 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c
@@ -1,4 +1,4 @@
-/* $Id: state_snapshot.c $ */
+/* $Id: state_snapshot.c 37613 2011-06-23 12:42:08Z vboxsync $ */
/** @file
* VBox Context state saving/loading used by VM snapshot
@@ -1010,6 +1010,9 @@ int32_t crStateSaveContext(CRContext *pContext, PSSMHANDLE pSSM)
CRASSERT(pContext && pSSM);
+ pContext->buffer.storedWidth = pContext->buffer.width;
+ pContext->buffer.storedHeight = pContext->buffer.height;
+
rc = SSMR3PutMem(pSSM, pContext, sizeof(*pContext));
AssertRCReturn(rc, rc);
@@ -1282,11 +1285,15 @@ int32_t crStateSaveContext(CRContext *pContext, PSSMHANDLE pSSM)
AssertRCReturn(rc, rc);
#endif
+ if (pContext->buffer.storedWidth && pContext->buffer.storedHeight)
{
- CRViewportState *pVP = &pContext->viewport;
+ CRBufferState *pBuf = &pContext->buffer;
CRPixelPackState packing = pContext->client.pack;
- GLint cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pVP->viewportH * pVP->viewportW;
- void *pData = crAlloc(cbData);
+ GLint cbData;
+ void *pData;
+
+ cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pBuf->storedWidth * pBuf->storedHeight;
+ pData = crAlloc(cbData);
if (!pData)
{
@@ -1302,11 +1309,36 @@ int32_t crStateSaveContext(CRContext *pContext, PSSMHANDLE pSSM)
diff_api.PixelStorei(GL_PACK_SWAP_BYTES, 0);
diff_api.PixelStorei(GL_PACK_LSB_FIRST, 0);
+ if (pContext->framebufferobject.readFB)
+ {
+ diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
+ }
+ if (pContext->bufferobject.packBuffer->hwid>0)
+ {
+ diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
+ }
+
diff_api.ReadBuffer(GL_FRONT);
- diff_api.ReadPixels(0, 0, pVP->viewportW, pVP->viewportH, GL_RGBA, GL_UNSIGNED_BYTE, pData);
+ diff_api.ReadPixels(0, 0, pBuf->storedWidth, pBuf->storedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pData);
+ rc = SSMR3PutMem(pSSM, pData, cbData);
+ AssertRCReturn(rc, rc);
+
+ diff_api.ReadBuffer(GL_BACK);
+ diff_api.ReadPixels(0, 0, pBuf->storedWidth, pBuf->storedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pData);
+ rc = SSMR3PutMem(pSSM, pData, cbData);
+ AssertRCReturn(rc, rc);
+ if (pContext->bufferobject.packBuffer->hwid>0)
+ {
+ diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pContext->bufferobject.packBuffer->hwid);
+ }
+ if (pContext->framebufferobject.readFB)
+ {
+ diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, pContext->framebufferobject.readFB->hwid);
+ }
diff_api.ReadBuffer(pContext->framebufferobject.readFB ?
pContext->framebufferobject.readFB->readbuffer : pContext->buffer.readBuffer);
+
diff_api.PixelStorei(GL_PACK_SKIP_ROWS, packing.skipRows);
diff_api.PixelStorei(GL_PACK_SKIP_PIXELS, packing.skipPixels);
diff_api.PixelStorei(GL_PACK_ALIGNMENT, packing.alignment);
@@ -1316,9 +1348,6 @@ int32_t crStateSaveContext(CRContext *pContext, PSSMHANDLE pSSM)
diff_api.PixelStorei(GL_PACK_SWAP_BYTES, packing.swapBytes);
diff_api.PixelStorei(GL_PACK_LSB_FIRST, packing.psLSBFirst);
- rc = SSMR3PutMem(pSSM, pData, cbData);
- AssertRCReturn(rc, rc);
-
crFree(pData);
}
@@ -1988,22 +2017,39 @@ int32_t crStateLoadContext(CRContext *pContext, CRHashTable * pCtxTable, PSSMHAN
#endif
- /*Restore front buffer image*/
+ /*Restore front/back buffer images*/
+ if (pContext->buffer.storedWidth && pContext->buffer.storedHeight)
{
- CRViewportState *pVP = &pContext->viewport;
- GLint cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pVP->viewportH * pVP->viewportW;
- void *pData = crAlloc(cbData);
+ CRBufferState *pBuf = &pContext->buffer;
+ GLint cbData;
+ void *pData;
+
+ cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pBuf->storedWidth * pBuf->storedHeight;
+
+ pData = crAlloc(cbData);
+ if (!pData)
+ {
+ pBuf->pFrontImg = NULL;
+ pBuf->pBackImg = NULL;
+ return VERR_NO_MEMORY;
+ }
+
+ rc = SSMR3GetMem(pSSM, pData, cbData);
+ AssertRCReturn(rc, rc);
+
+ pBuf->pFrontImg = pData;
+ pData = crAlloc(cbData);
if (!pData)
{
- pContext->pImage = NULL;
+ pBuf->pBackImg = NULL;
return VERR_NO_MEMORY;
}
rc = SSMR3GetMem(pSSM, pData, cbData);
AssertRCReturn(rc, rc);
- pContext->pImage = pData;
+ pBuf->pBackImg = pData;
}
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_texdiff.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_texdiff.c
index 6cae94452..00adbfffc 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_texdiff.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_texdiff.c
@@ -685,24 +685,27 @@ crStateTextureObjectDiff(CRContext *fromCtx,
if (tl->generateMipmap) {
diff_api.TexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
}
- if (tl->compressed) {
- diff_api.CompressedTexImage1DARB(GL_TEXTURE_1D, lvl,
- tl->internalFormat, tl->width,
- tl->border, tl->bytes, tl->img);
- }
- else {
- /* alignment must be one */
- diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
- if (tl->generateMipmap) {
- diff_api.TexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, 1);
+ if (tl->width)
+ {
+ if (tl->compressed) {
+ diff_api.CompressedTexImage1DARB(GL_TEXTURE_1D, lvl,
+ tl->internalFormat, tl->width,
+ tl->border, tl->bytes, tl->img);
+ }
+ else {
+ /* alignment must be one */
+ diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ if (tl->generateMipmap) {
+ diff_api.TexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, 1);
+ }
+ diff_api.TexImage1D(GL_TEXTURE_1D, lvl,
+ tl->internalFormat,
+ tl->width, tl->border,
+ tl->format, tl->type, tl->img);
}
- diff_api.TexImage1D(GL_TEXTURE_1D, lvl,
- tl->internalFormat,
- tl->width, tl->border,
- tl->format, tl->type, tl->img);
}
if (!alwaysDirty)
{
@@ -728,22 +731,25 @@ crStateTextureObjectDiff(CRContext *fromCtx,
diff_api.TexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
}
- if (tl->compressed) {
- diff_api.CompressedTexImage2DARB(GL_TEXTURE_2D, lvl,
- tl->internalFormat, tl->width,
- tl->height, tl->border,
- tl->bytes, tl->img);
- }
- else {
- /* alignment must be one */
- diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
- diff_api.TexImage2D(GL_TEXTURE_2D, lvl,
- tl->internalFormat,
- tl->width, tl->height, tl->border,
- tl->format, tl->type, tl->img);
+ if (tl->width && tl->height)
+ {
+ if (tl->compressed) {
+ diff_api.CompressedTexImage2DARB(GL_TEXTURE_2D, lvl,
+ tl->internalFormat, tl->width,
+ tl->height, tl->border,
+ tl->bytes, tl->img);
+ }
+ else {
+ /* alignment must be one */
+ diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ diff_api.TexImage2D(GL_TEXTURE_2D, lvl,
+ tl->internalFormat,
+ tl->width, tl->height, tl->border,
+ tl->format, tl->type, tl->img);
+ }
}
if (!alwaysDirty)
@@ -770,24 +776,29 @@ crStateTextureObjectDiff(CRContext *fromCtx,
if (tl->generateMipmap) {
diff_api.TexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP_SGIS, 1);
}
- if (tl->compressed) {
- diff_api.CompressedTexImage3DARB(GL_TEXTURE_3D, lvl,
- tl->internalFormat, tl->width,
- tl->height, tl->depth,
- tl->border, tl->bytes, tl->img);
- }
- else {
- /* alignment must be one */
- diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
- diff_api.TexImage3D(GL_TEXTURE_3D, lvl,
- tl->internalFormat,
- tl->width, tl->height, tl->depth,
- tl->border, tl->format,
- tl->type, tl->img);
+
+ if (tl->width && tl->height)
+ {
+ if (tl->compressed) {
+ diff_api.CompressedTexImage3DARB(GL_TEXTURE_3D, lvl,
+ tl->internalFormat, tl->width,
+ tl->height, tl->depth,
+ tl->border, tl->bytes, tl->img);
+ }
+ else {
+ /* alignment must be one */
+ diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ diff_api.TexImage3D(GL_TEXTURE_3D, lvl,
+ tl->internalFormat,
+ tl->width, tl->height, tl->depth,
+ tl->border, tl->format,
+ tl->type, tl->img);
+ }
}
+
if (!alwaysDirty)
{
CLEARDIRTY(tl->dirty, nbitID);
@@ -811,23 +822,27 @@ crStateTextureObjectDiff(CRContext *fromCtx,
CRTextureLevel *tl = &(tobj->level[0][lvl]);
if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
{
- if (tl->compressed) {
- diff_api.CompressedTexImage2DARB(GL_TEXTURE_RECTANGLE_NV, lvl,
- tl->internalFormat, tl->width,
- tl->height, tl->border,
- tl->bytes, tl->img);
- }
- else {
- /* alignment must be one */
- diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
- diff_api.TexImage2D(GL_TEXTURE_RECTANGLE_NV, lvl,
- tl->internalFormat,
- tl->width, tl->height, tl->border,
- tl->format, tl->type, tl->img);
+ if (tl->width && tl->height)
+ {
+ if (tl->compressed) {
+ diff_api.CompressedTexImage2DARB(GL_TEXTURE_RECTANGLE_NV, lvl,
+ tl->internalFormat, tl->width,
+ tl->height, tl->border,
+ tl->bytes, tl->img);
+ }
+ else {
+ /* alignment must be one */
+ diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ diff_api.TexImage2D(GL_TEXTURE_RECTANGLE_NV, lvl,
+ tl->internalFormat,
+ tl->width, tl->height, tl->border,
+ tl->format, tl->type, tl->img);
+ }
}
+
if (!alwaysDirty)
{
CLEARDIRTY(tl->dirty, nbitID);
@@ -857,23 +872,28 @@ crStateTextureObjectDiff(CRContext *fromCtx,
diff_api.TexParameteri(GL_TEXTURE_CUBE_MAP_ARB,
GL_GENERATE_MIPMAP_SGIS, 1);
}
- if (tl->compressed) {
- diff_api.CompressedTexImage2DARB(target,
- lvl, tl->internalFormat,
- tl->width, tl->height,
- tl->border, tl->bytes, tl->img);
- }
- else {
- /* alignment must be one */
- diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
- diff_api.TexImage2D(target, lvl,
- tl->internalFormat,
- tl->width, tl->height, tl->border,
- tl->format, tl->type, tl->img);
+
+ if (tl->width && tl->height)
+ {
+ if (tl->compressed) {
+ diff_api.CompressedTexImage2DARB(target,
+ lvl, tl->internalFormat,
+ tl->width, tl->height,
+ tl->border, tl->bytes, tl->img);
+ }
+ else {
+ /* alignment must be one */
+ diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ diff_api.TexImage2D(target, lvl,
+ tl->internalFormat,
+ tl->width, tl->height, tl->border,
+ tl->format, tl->type, tl->img);
+ }
}
+
if (!alwaysDirty)
{
CLEARDIRTY(tl->dirty, nbitID);
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c
index d321cdaf6..b23c7d94f 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c
@@ -55,16 +55,16 @@ void crStateTextureInit(CRContext *ctx)
/* compute max levels from max sizes */
for (i=0, a=limits->maxTextureSize; a; i++, a=a>>1);
- t->maxLevel = i;
+ t->maxLevel = i-1;
for (i=0, a=limits->max3DTextureSize; a; i++, a=a>>1);
- t->max3DLevel = i;
+ t->max3DLevel = i-1;
#ifdef CR_ARB_texture_cube_map
for (i=0, a=limits->maxCubeMapTextureSize; a; i++, a=a>>1);
- t->maxCubeMapLevel = i;
+ t->maxCubeMapLevel = i-1;
#endif
#ifdef CR_NV_texture_rectangle
for (i=0, a=limits->maxRectTextureSize; a; i++, a=a>>1);
- t->maxRectLevel = i;
+ t->maxRectLevel = i-1;
#endif
crStateTextureInitTextureObj(ctx, &(t->base1D), 0, GL_TEXTURE_1D);
@@ -790,6 +790,8 @@ void STATE_APIENTRY crStateClientActiveTextureARB( GLenum texture )
}
c->curClientTextureUnit = texture - GL_TEXTURE0_ARB;
+
+ DIRTY(GetCurrentBits()->client.dirty, g->neg_bitid);
}
void STATE_APIENTRY crStateActiveTextureARB( GLenum texture )
@@ -901,7 +903,9 @@ void STATE_APIENTRY crStateBindTexture(GLenum target, GLuint texture)
/* Target isn't set so set it now.*/
tobj->target = target;
}
- else if (tobj->target != target)
+ else if ((tobj->target != target)
+ && !((target==GL_TEXTURE_RECTANGLE_NV && tobj->target==GL_TEXTURE_2D)
+ ||(target==GL_TEXTURE_2D && tobj->target==GL_TEXTURE_RECTANGLE_NV)))
{
crWarning( "You called glBindTexture with a target of 0x%x, but the texture you wanted was target 0x%x [1D: %x 2D: %x 3D: %x cube: %x]", (int) target, (int) tobj->target, GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP );
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "Attempt to bind a texture of different dimensions");
diff --git a/src/VBox/GuestHost/OpenGL/util/hash.c b/src/VBox/GuestHost/OpenGL/util/hash.c
index 4e2de726b..c91c4ad0f 100644
--- a/src/VBox/GuestHost/OpenGL/util/hash.c
+++ b/src/VBox/GuestHost/OpenGL/util/hash.c
@@ -352,6 +352,19 @@ void crFreeHashtable( CRHashTable *hash, CRHashtableCallback deleteFunc )
crFree( hash );
}
+void crHashtableLock(CRHashTable *h)
+{
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&h->mutex);
+#endif
+}
+
+void crHashtableUnlock(CRHashTable *h)
+{
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&h->mutex);
+#endif
+}
void crHashtableWalk( CRHashTable *hash, CRHashtableWalkCallback walkFunc , void *dataPtr2)
{
diff --git a/src/VBox/GuestHost/OpenGL/util/util.rc b/src/VBox/GuestHost/OpenGL/util/util.rc
index 794cf2400..cff1898b5 100644
--- a/src/VBox/GuestHost/OpenGL/util/util.rc
+++ b/src/VBox/GuestHost/OpenGL/util/util.rc
@@ -1,4 +1,4 @@
-/* $Id: util.rc $ */
+/* $Id: util.rc 35319 2010-12-24 15:42:36Z vboxsync $ */
/** @file
* VBoxOGLcrutil - Resource file containing version info and icon.
*/
diff --git a/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c b/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c
index b1fc87ec2..fd4a1a238 100644
--- a/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c
+++ b/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c
@@ -1,4 +1,4 @@
-/* $Id: vboxhgcm.c $ */
+/* $Id: vboxhgcm.c 37714 2011-06-30 15:26:38Z vboxsync $ */
/** @file
* VBox HGCM connection
@@ -336,21 +336,21 @@ DECLINLINE(PCRVBOXHGSMI_CLIENT) _crVBoxHGSMIClientGet(CRConnection *conn)
{
#ifdef VBOX_CRHGSMI_WITH_D3DDEV
PCRVBOXHGSMI_CLIENT pClient = (PCRVBOXHGSMI_CLIENT)VBoxCrHgsmiQueryClient();
- Assert(pClient);
+ CRASSERT(pClient);
return pClient;
#else
if (conn->HgsmiClient.pHgsmi)
return &conn->HgsmiClient;
{
PVBOXUHGSMI pHgsmi = VBoxCrHgsmiCreate();
- Assert(pHgsmi);
+ CRASSERT(pHgsmi);
if (pHgsmi)
{
int rc = _crVBoxHGSMIClientInit(&conn->HgsmiClient, pHgsmi);
AssertRC(rc);
if (RT_SUCCESS(rc))
{
- Assert(conn->HgsmiClient.pHgsmi);
+ CRASSERT(conn->HgsmiClient.pHgsmi);
return &conn->HgsmiClient;
}
VBoxCrHgsmiDestroy(pHgsmi);
@@ -502,7 +502,7 @@ DECLINLINE(void*) _crVBoxHGSMIRecvBufData(PCRVBOXHGSMI_CLIENT pClient, uint32_t
{
VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags;
int rc;
- Assert(!pClient->pvHGBuffer);
+ CRASSERT(!pClient->pvHGBuffer);
fFlags.Value = 0;
rc = pClient->pHGBuffer->pfnLock(pClient->pHGBuffer, 0, cbBuffer, fFlags, &pClient->pvHGBuffer);
AssertRC(rc);
@@ -535,7 +535,7 @@ DECLINLINE(void) _crVBoxHGSMIFillCmd(VBOXUHGSMI_BUFFER_SUBMIT *pSubm, PCRVBOXHGS
DECLINLINE(void) _crVBoxHGSMIWaitCmd(PCRVBOXHGSMI_CLIENT pClient)
{
int rc = CRVBOXHGSMI_BUF_WAIT(pClient->pCmdBuffer);
- Assert(rc == 0);
+ CRASSERT(rc == 0);
}
#endif
@@ -600,7 +600,7 @@ static int crVBoxHGCMCall(void *pvData, unsigned cbData)
#ifdef IN_GUEST
# ifdef RT_OS_WINDOWS
- DWORD cbReturned;
+ DWORD cbReturned, lerr;
if (DeviceIoControl (g_crvboxhgcm.hGuestDrv,
VBOXGUEST_IOCTL_HGCM_CALL(cbData),
@@ -611,8 +611,19 @@ static int crVBoxHGCMCall(void *pvData, unsigned cbData)
{
return VINF_SUCCESS;
}
- crDebug("vboxCall failed with %x\n", GetLastError());
- return VERR_NOT_SUPPORTED;
+ lerr=GetLastError();
+ crDebug("vboxCall failed with %x\n", lerr);
+ /*On windows if we exceed max buffer len, we only get ERROR_GEN_FAILURE, and parms.hdr.result isn't changed.
+ *Before every call here we set it to VERR_WRONG_ORDER, so checking it here as well.
+ */
+ if (ERROR_GEN_FAILURE==lerr && VERR_WRONG_ORDER==((VBoxGuestHGCMCallInfo*)pvData)->result)
+ {
+ return VERR_OUT_OF_RANGE;
+ }
+ else
+ {
+ return VERR_NOT_SUPPORTED;
+ }
# else
int rc;
# if defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
@@ -945,7 +956,7 @@ crVBoxHGCMWriteReadExact(CRConnection *conn, const void *buf, unsigned int len,
rc = crVBoxHGCMCall(&parms, sizeof(parms));
-#ifdef RT_OS_LINUX
+#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
if (VERR_OUT_OF_RANGE==rc && CR_VBOXHGCM_USERALLOCATED==bufferKind)
{
/*Buffer is too big, so send it in split chunks*/
@@ -1315,8 +1326,6 @@ static int crVBoxHGCMSetVersion(CRConnection *conn, unsigned int vMajor, unsigne
if (RT_FAILURE(rc) || RT_FAILURE(parms.hdr.result))
{
- Assert(0);
-
crWarning("Host doesn't accept our version %d.%d. Make sure you have appropriate additions installed!",
parms.vMajor.u.value32, parms.vMinor.u.value32);
return FALSE;
@@ -1345,8 +1354,6 @@ static int crVBoxHGCMSetPID(CRConnection *conn, unsigned long long pid)
if (RT_FAILURE(rc) || RT_FAILURE(parms.hdr.result))
{
- Assert(0);
-
crWarning("SHCRGL_GUEST_FN_SET_PID failed!");
return FALSE;
}
@@ -1384,7 +1391,6 @@ static int crVBoxHGCMDoConnect( CRConnection *conn )
/* @todo check if we could rollback to softwareopengl */
if (g_crvboxhgcm.hGuestDrv == INVALID_HANDLE_VALUE)
{
- Assert(0);
crDebug("could not open VBox Guest Additions driver! rc = %d\n", GetLastError());
VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
return FALSE;
@@ -1399,7 +1405,6 @@ static int crVBoxHGCMDoConnect( CRConnection *conn )
{
crDebug("could not open Guest Additions kernel module! rc = %d\n", errno);
VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
- Assert(0);
return FALSE;
}
}
@@ -1451,7 +1456,6 @@ static int crVBoxHGCMDoConnect( CRConnection *conn )
else
{
crDebug("HGCM connect failed with rc=0x%x\n", info.result);
- Assert(0);
VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
return FALSE;
@@ -1461,7 +1465,6 @@ static int crVBoxHGCMDoConnect( CRConnection *conn )
{
#ifdef RT_OS_WINDOWS
DWORD winEr = GetLastError();
- Assert(0);
crDebug("IOCTL for HGCM connect failed with rc=0x%x\n", winEr);
#else
crDebug("IOCTL for HGCM connect failed with rc=0x%x\n", errno);
@@ -1628,7 +1631,7 @@ bool _crVBoxHGSMIInit()
crDebug("CrHgsmi is %s", bHasHGSMI ? "ENABLED" : "DISABLED");
}
- Assert(bHasHGSMI >= 0);
+ CRASSERT(bHasHGSMI >= 0);
return bHasHGSMI;
}
@@ -1646,7 +1649,7 @@ static void *_crVBoxHGSMIDoAlloc(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient
int rc;
buf = _crVBoxHGSMIBufAlloc(pClient, CRVBOXHGSMI_BUF_SIZE(cbSize));
- Assert(buf);
+ CRASSERT(buf);
if (buf)
{
VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags;
@@ -1701,7 +1704,7 @@ static void *crVBoxHGSMIAlloc(CRConnection *conn)
if (pClient)
{
pvBuf = _crVBoxHGSMIDoAlloc(conn, pClient);
- Assert(pvBuf);
+ CRASSERT(pvBuf);
}
else
{
@@ -1728,7 +1731,7 @@ static void _crVBoxHGSMIPollHost(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient
PVBOXUHGSMI_BUFFER pRecvBuffer;
uint32_t cbBuffer;
- Assert(parms);
+ CRASSERT(parms);
parms->hdr.result = VERR_WRONG_ORDER;
parms->hdr.u32ClientID = conn->u32ClientID;
@@ -1742,7 +1745,7 @@ static void _crVBoxHGSMIPollHost(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient
_crVBoxHGSMICmdBufferUnlock(pClient);
pRecvBuffer = _crVBoxHGSMIRecvBufGet(pClient);
- Assert(pRecvBuffer);
+ CRASSERT(pRecvBuffer);
if (!pRecvBuffer)
return;
@@ -1765,7 +1768,7 @@ static void _crVBoxHGSMIPollHost(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient
_crVBoxHGSMIWaitCmd(pClient);
parms = (CRVBOXHGSMIREAD *)_crVBoxHGSMICmdBufferLockRo(pClient, sizeof (*parms));
- Assert(parms);
+ CRASSERT(parms);
if (!parms)
{
crWarning("_crVBoxHGSMICmdBufferLockRo failed\n");
@@ -1782,7 +1785,7 @@ static void _crVBoxHGSMIPollHost(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient
if (cbBuffer)
{
void *pvData = _crVBoxHGSMIRecvBufData(pClient, cbBuffer);
- Assert(pvData);
+ CRASSERT(pvData);
if (pvData)
{
conn->pBuffer = pvData;
@@ -1830,7 +1833,7 @@ _crVBoxHGSMIWriteReadExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient, void
{
void *pvBuf;
pBuf = _crVBoxHGSMIBufAlloc(pClient, len);
- Assert(pBuf);
+
if (!pBuf)
{
/* fallback */
@@ -1838,7 +1841,7 @@ _crVBoxHGSMIWriteReadExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient, void
return;
}
- Assert(!offBuffer);
+ CRASSERT(!offBuffer);
offBuffer = 0;
fFlags.Value = 0;
@@ -1869,7 +1872,7 @@ _crVBoxHGSMIWriteReadExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient, void
do
{
PVBOXUHGSMI_BUFFER pRecvBuffer = _crVBoxHGSMIRecvBufGet(pClient);
- Assert(pRecvBuffer);
+ CRASSERT(pRecvBuffer);
if (!pRecvBuffer)
{
break;
@@ -1899,7 +1902,7 @@ _crVBoxHGSMIWriteReadExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient, void
_crVBoxHGSMIWaitCmd(pClient);
parms = (CRVBOXHGSMIWRITEREAD *)_crVBoxHGSMICmdBufferLockRo(pClient, sizeof (*parms));
- Assert(parms);
+ CRASSERT(parms);
if (parms)
{
uint32_t cbWriteback = parms->cbWriteback;
@@ -1913,7 +1916,7 @@ _crVBoxHGSMIWriteReadExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient, void
if (cbWriteback)
{
void *pvData = _crVBoxHGSMIRecvBufData(pClient, cbWriteback);
- Assert(pvData);
+ CRASSERT(pvData);
if (pvData)
{
conn->pBuffer = pvData;
@@ -1925,7 +1928,7 @@ _crVBoxHGSMIWriteReadExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient, void
else if (VERR_BUFFER_OVERFLOW == rc)
{
PVBOXUHGSMI_BUFFER pOldBuf = pClient->pHGBuffer;
- Assert(!pClient->pvHGBuffer);
+ CRASSERT(!pClient->pvHGBuffer);
CRASSERT(cbWriteback>pClient->pHGBuffer->cbBuffer);
crDebug("Reallocating host buffer from %d to %d bytes", conn->cbHostBufferAllocated, cbWriteback);
@@ -1976,7 +1979,7 @@ static void _crVBoxHGSMIWriteExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClie
if (conn->u32InjectClientID)
{
CRVBOXHGSMIINJECT *parms = (CRVBOXHGSMIINJECT *)_crVBoxHGSMICmdBufferLock(pClient, sizeof (*parms));
- Assert(parms);
+ CRASSERT(parms);
if (!parms)
{
return;
@@ -2098,7 +2101,13 @@ static void crVBoxHGSMISend(CRConnection *conn, void **bufp,
}
hgcm_buffer = (CRVBOXHGCMBUFFER *) *bufp - 1;
- Assert(hgcm_buffer->magic == CR_VBOXHGCM_BUFFER_MAGIC);
+ CRASSERT(hgcm_buffer->magic == CR_VBOXHGCM_BUFFER_MAGIC);
+ if (hgcm_buffer->magic != CR_VBOXHGCM_BUFFER_MAGIC)
+ {
+ crError("HGCM buffer magic mismatch");
+ }
+
+
if (hgcm_buffer->kind != CR_VBOXHGCM_UHGSMI_BUFFER)
{
/* fallback */
@@ -2113,7 +2122,7 @@ static void crVBoxHGSMISend(CRConnection *conn, void **bufp,
*/
pBuf = _crVBoxHGSMIBufFromHdr(hgcm_buffer);
- Assert(pBuf);
+ CRASSERT(pBuf);
if (!pBuf)
{
crVBoxHGCMSend(conn, bufp, start, len);
@@ -2122,6 +2131,10 @@ static void crVBoxHGSMISend(CRConnection *conn, void **bufp,
}
pClient = (PCRVBOXHGSMI_CLIENT)pBuf->pvUserData;
+ if (pClient != &conn->HgsmiClient)
+ {
+ crError("HGSMI client mismatch");
+ }
/* Length would be passed as part of HGCM pointer description
* No need to prepend it to the buffer
@@ -2151,7 +2164,6 @@ static void crVBoxHGSMISend(CRConnection *conn, void **bufp,
static void crVBoxHGSMIWriteExact(CRConnection *conn, const void *buf, unsigned int len)
{
VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
- Assert(0);
CRASSERT(0);
// PCRVBOXHGSMI_CLIENT pClient;
@@ -2171,7 +2183,6 @@ static void crVBoxHGSMISingleRecv(CRConnection *conn, void *buf, unsigned int le
VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
// pBuf = _crVBoxHGSMIBufFromMemPtr(buf);
// Assert(pBuf);
- Assert(0);
CRASSERT(0);
// if (!pBuf)
// {
@@ -2187,7 +2198,7 @@ static void crVBoxHGSMIReceiveMessage(CRConnection *conn)
{
VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
- Assert(0);
+ CRASSERT(0);
_crVBoxHGCMReceiveMessage(conn);
VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
@@ -2199,7 +2210,7 @@ static void crVBoxHGSMIReceiveMessage(CRConnection *conn)
static void crVBoxHGSMIAccept( CRConnection *conn, const char *hostname, unsigned short port )
{
VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
- Assert(0);
+ CRASSERT(0);
CRASSERT(conn && conn->pHostBuffer);
#ifdef IN_GUEST
@@ -2220,7 +2231,7 @@ static void crVBoxHGSMIDoDisconnect( CRConnection *conn )
{
PVBOXUHGSMI pHgsmi;
_crVBoxHGSMIClientTerm(&conn->HgsmiClient, &pHgsmi);
- Assert(pHgsmi);
+ CRASSERT(pHgsmi);
VBoxCrHgsmiDestroy(pHgsmi);
}
@@ -2231,7 +2242,7 @@ static void crVBoxHGSMIDoDisconnect( CRConnection *conn )
static void crVBoxHGSMIInstantReclaim(CRConnection *conn, CRMessage *mess)
{
VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
- Assert(0);
+ CRASSERT(0);
_crVBoxHGSMIFree(conn, mess);
CRASSERT(FALSE);
@@ -2242,7 +2253,7 @@ static void crVBoxHGSMIInstantReclaim(CRConnection *conn, CRMessage *mess)
static void crVBoxHGSMIHandleNewMessage( CRConnection *conn, CRMessage *msg, unsigned int len )
{
VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
- Assert(0);
+ CRASSERT(0);
CRASSERT(FALSE);
VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
diff --git a/src/VBox/GuestHost/OpenGL/util/vboxhgsmi.c b/src/VBox/GuestHost/OpenGL/util/vboxhgsmi.c
index 60d5ce21f..c35cdd932 100644
--- a/src/VBox/GuestHost/OpenGL/util/vboxhgsmi.c
+++ b/src/VBox/GuestHost/OpenGL/util/vboxhgsmi.c
@@ -1,4 +1,4 @@
-/* $Id: vboxhgsmi.c $ */
+/* $Id: vboxhgsmi.c 34110 2010-11-16 12:10:23Z vboxsync $ */
/** @file
* VBox HGCM connection
diff --git a/src/VBox/GuestHost/SharedClipboard/Makefile.kmk b/src/VBox/GuestHost/SharedClipboard/Makefile.kmk
index 68cc8b857..07de4ee07 100644
--- a/src/VBox/GuestHost/SharedClipboard/Makefile.kmk
+++ b/src/VBox/GuestHost/SharedClipboard/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Sub-Makefile for the shared clipboard code for both host and guest.
#
diff --git a/src/VBox/GuestHost/SharedClipboard/clipboard-helper.cpp b/src/VBox/GuestHost/SharedClipboard/clipboard-helper.cpp
index f69d61cf1..f5810f581 100644
--- a/src/VBox/GuestHost/SharedClipboard/clipboard-helper.cpp
+++ b/src/VBox/GuestHost/SharedClipboard/clipboard-helper.cpp
@@ -1,4 +1,4 @@
-/* $Id: clipboard-helper.cpp $ */
+/* $Id: clipboard-helper.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Shared Clipboard: Some helper function for converting between the various eol.
*/
diff --git a/src/VBox/GuestHost/SharedClipboard/x11-clipboard.cpp b/src/VBox/GuestHost/SharedClipboard/x11-clipboard.cpp
index 08ceb8d98..4a8e2e729 100644
--- a/src/VBox/GuestHost/SharedClipboard/x11-clipboard.cpp
+++ b/src/VBox/GuestHost/SharedClipboard/x11-clipboard.cpp
@@ -43,7 +43,6 @@
#include <X11/StringDefs.h>
#include <iprt/types.h>
-#include <iprt/env.h>
#include <iprt/mem.h>
#include <iprt/semaphore.h>
#include <iprt/thread.h>
@@ -697,13 +696,13 @@ static int clipInit(CLIPBACKEND *pCtx)
* Construct the X11 backend of the shared clipboard.
* @note X11 backend code
*/
-CLIPBACKEND *ClipConstructX11(VBOXCLIPBOARDCONTEXT *pFrontend)
+CLIPBACKEND *ClipConstructX11(VBOXCLIPBOARDCONTEXT *pFrontend, bool fHeadless)
{
int rc;
CLIPBACKEND *pCtx = (CLIPBACKEND *)
RTMemAllocZ(sizeof(CLIPBACKEND));
- if (pCtx && !RTEnvExist("DISPLAY"))
+ if (pCtx && fHeadless)
{
/*
* If we don't find the DISPLAY environment variable we assume that
@@ -2240,6 +2239,15 @@ static void testStringFromVBox(RTTEST hTest, CLIPBACKEND *pCtx,
pcszTarget, valueExp);
}
+static void testNoX11(CLIPBACKEND *pCtx, const char *pcszTestCtx)
+{
+ CLIPREADCBREQ *pReq = (CLIPREADCBREQ *)&pReq, *pReqRet = NULL;
+ int rc = ClipRequestDataFromX11(pCtx,
+ VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT,
+ pReq);
+ RTTESTI_CHECK_MSG(rc == VERR_NO_DATA, ("context: %s\n", pcszTestCtx));
+}
+
static void testStringFromVBoxFailed(RTTEST hTest, CLIPBACKEND *pCtx,
const char *pcszTarget)
{
@@ -2256,6 +2264,12 @@ static void testStringFromVBoxFailed(RTTEST hTest, CLIPBACKEND *pCtx,
XtFree((char *)value);
}
+static void testNoSelectionOwnership(CLIPBACKEND *pCtx,
+ const char *pcszTestCtx)
+{
+ RTTESTI_CHECK_MSG(!g_ownsSel, ("context: %s\n", pcszTestCtx));
+}
+
int main()
{
/*
@@ -2270,7 +2284,7 @@ int main()
/*
* Run the test.
*/
- CLIPBACKEND *pCtx = ClipConstructX11(NULL);
+ CLIPBACKEND *pCtx = ClipConstructX11(NULL, false);
char *pc;
uint32_t cbActual;
CLIPREADCBREQ *pReq = (CLIPREADCBREQ *)&pReq, *pReqRet = NULL;
@@ -2523,6 +2537,34 @@ int main()
AssertRCReturn(rc, 1);
ClipDestructX11(pCtx);
+ /*** Headless clipboard tests ***/
+
+ pCtx = ClipConstructX11(NULL, true);
+ rc = ClipStartX11(pCtx);
+ AssertRCReturn(rc, 1);
+
+ /*** Read from X11 ***/
+ RTTestSub(hTest, "reading from X11, headless clipboard");
+ /* Simple test */
+ clipSetVBoxUtf16(pCtx, VINF_SUCCESS, "",
+ sizeof("") * 2);
+ clipSetSelectionValues("UTF8_STRING", XA_STRING, "hello world",
+ sizeof("hello world"), 8);
+ testNoX11(pCtx, "reading from X11, headless clipboard");
+
+ /*** Read from VBox ***/
+ RTTestSub(hTest, "reading from VBox, headless clipboard");
+ /* Simple test */
+ clipEmptyVBox(pCtx, VERR_WRONG_ORDER);
+ clipSetSelectionValues("TEXT", XA_STRING, "", sizeof(""), 8);
+ clipSetVBoxUtf16(pCtx, VINF_SUCCESS, "hello world",
+ sizeof("hello world") * 2);
+ testNoSelectionOwnership(pCtx, "reading from VBox, headless clipboard");
+
+ rc = ClipStopX11(pCtx);
+ AssertRCReturn(rc, 1);
+ ClipDestructX11(pCtx);
+
return RTTestSummaryAndDestroy(hTest);
}
@@ -2535,6 +2577,7 @@ int main()
* interactive mode in which the user can read and copy to the clipboard from
* the command line. */
+#include <iprt/env.h>
#include <iprt/test.h>
int ClipRequestDataForX11(VBOXCLIPBOARDCONTEXT *pCtx,
@@ -2576,7 +2619,7 @@ int main()
"X11 not available, not running test\n");
return RTTestSummaryAndDestroy(hTest);
}
- CLIPBACKEND *pCtx = ClipConstructX11(NULL);
+ CLIPBACKEND *pCtx = ClipConstructX11(NULL, false);
AssertReturn(pCtx, 1);
rc = ClipStartX11(pCtx);
AssertRCReturn(rc, 1);
diff --git a/src/VBox/HostDrivers/Makefile.kmk b/src/VBox/HostDrivers/Makefile.kmk
index 79bf81977..f28fa262e 100644
--- a/src/VBox/HostDrivers/Makefile.kmk
+++ b/src/VBox/HostDrivers/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 36889 2011-04-29 12:03:16Z vboxsync $
## @file
# Top-level makefile for the VBox Host drivers.
#
@@ -24,6 +24,9 @@ include $(PATH_SUB_CURRENT)/Support/Makefile.kmk
if !defined(VBOX_ONLY_DOCS) \
&& !defined(VBOX_ONLY_EXTPACKS) \
&& !defined(VBOX_ONLY_TESTSUITE)
+ if1of ($(KBUILD_TARGET),win)
+ include $(PATH_SUB_CURRENT)/win/Makefile.kmk
+ endif
ifdef VBOX_WITH_USB
include $(PATH_SUB_CURRENT)/VBoxUSB/Makefile.kmk
endif
@@ -41,6 +44,12 @@ if !defined(VBOX_ONLY_DOCS) \
include $(PATH_SUB_CURRENT)/darwin/Makefile.kmk
endif
+ if1of ($(KBUILD_TARGET), linux)
+ ifdef VBOX_WITH_PCI_PASSTHROUGH
+ include $(PATH_SUB_CURRENT)/VBoxPci/Makefile.kmk
+ endif
+ endif
+
if1of ($(KBUILD_TARGET),linux freebsd)
#
# Install the Makefile for module compilation on Linux and FreeBSD hosts
@@ -74,6 +83,7 @@ $$(HostDrivers-dkms-src_0_OUTDIR)/dkms.conf: \
-e "s;_VERSION_;${VBOX_VERSION_STRING};g" \
-e "s;_OMIT_VBOXNETFLT_;$(if $(VBOX_WITH_NETFLT),,#);g" \
-e "s;_OMIT_VBOXNETADP_;$(if $(VBOX_WITH_NETADP),,#);g" \
+ -e "s;_OMIT_VBOXPCI_;$(if $(VBOX_WITH_PCI_PASSTHROUGH),,#);g" \
--output $@ $<
$$(HostDrivers-dkms-sh_0_OUTDIR)/do_dkms: \
diff --git a/src/VBox/HostDrivers/Support/Makefile.kmk b/src/VBox/HostDrivers/Support/Makefile.kmk
index 7b89936d2..77cd26fe8 100644
--- a/src/VBox/HostDrivers/Support/Makefile.kmk
+++ b/src/VBox/HostDrivers/Support/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 38004 2011-07-18 10:17:18Z vboxsync $
## @file
# Sub-Makefile for the support library and the drivers/modules/kexts it uses.
#
@@ -219,7 +219,7 @@ VBoxDrv-inf_SOURCES += \
$(PATH_TARGET)/VBoxDrvCat.dir/VBoxDrv.sys \
$(PATH_TARGET)/VBoxDrvCat.dir/VBoxDrv.cat
-$(PATH_TARGET)/VBoxDrvCat.dir/VBoxDrv.sys: $$(TARGET_VBoxDrv) | $$(dir $$@)
+$(PATH_TARGET)/VBoxDrvCat.dir/VBoxDrv.sys: $$(VBoxDrv_1_TARGET) | $$(dir $$@)
$(INSTALL) -m 644 $< $(@D)
$(PATH_TARGET)/VBoxDrvCat.dir/VBoxDrv.cat: \
@@ -267,7 +267,7 @@ vboxdrv-mod_SOURCES += \
vboxdrv-mod_CLEAN = \
$(vboxdrv-mod_0_OUTDIR)/Makefile
-vboxdrv-sh_INST = bin/src/vboxdrv
+vboxdrv-sh_INST = bin/src/vboxdrv/
vboxdrv-sh_MODE = a+rx,u+w
vboxdrv-sh_SOURCES = $(subst ",,$(FILES_VBOXDRV_BIN)) #"
vboxdrv-sh_SOURCES += \
@@ -377,7 +377,7 @@ VBoxDrv_SOURCES = \
os2/SUPDrvA-os2.asm \
os2/SUPDrv-os2.def
VBoxDrv_LIBS = \
- $(TARGET_VBoxDrvLib) \
+ $(VBoxDrvLib_1_TARGET) \
$(PATH_LIB)/RuntimeR0Drv$(VBOX_SUFF_LIB) \
$(VBOX_GCC_LIBGCC) \
end
@@ -441,11 +441,13 @@ ifeq ($(KBUILD_TARGET),solaris)
# vboxdrv.o - The Solaris Kernel Module.
#
vboxdrv_TEMPLATE = VBOXR0DRV
-vboxdrv_DEFS = IN_RT_R0 IN_SUP_R0 SUPDRV_WITH_RELEASE_LOGGER
+vboxdrv_DEFS = IN_RT_R0 IN_SUP_R0 SUPDRV_WITH_RELEASE_LOGGER VBOX_SVN_REV=$(VBOX_SVN_REV)
ifdef VBOX_WITH_NETFLT
vboxdrv_DEFS += VBOX_WITH_NETFLT
endif
-vboxdrv_DEFS += VBOX_SVN_REV=$(VBOX_SVN_REV)
+ifdef VBOX_WITH_NATIVE_SOLARIS_LOADING
+ vboxdrv_DEFS += VBOX_WITH_NATIVE_SOLARIS_LOADING
+endif
vboxdrv_DEPS += $(VBOX_SVN_REV_KMK)
vboxdrv_INCS := $(PATH_SUB_CURRENT)
vboxdrv_LIBS = $(PATH_LIB)/RuntimeR0Drv$(VBOX_SUFF_LIB)
@@ -453,6 +455,7 @@ vboxdrv_SOURCES = \
$(KBUILD_TARGET)/SUPDrv-$(KBUILD_TARGET).c \
SUPDrv.c \
SUPDrvSem.c
+vboxdrv_LDFLAGS += -N misc/ctf
endif # solaris
diff --git a/src/VBox/HostDrivers/Support/SUPDrv-dtrace.d b/src/VBox/HostDrivers/Support/SUPDrv-dtrace.d
index 2a0535cc4..4a2aaf270 100644
--- a/src/VBox/HostDrivers/Support/SUPDrv-dtrace.d
+++ b/src/VBox/HostDrivers/Support/SUPDrv-dtrace.d
@@ -1,4 +1,4 @@
-/* $Id: SUPDrv-dtrace.d $ */
+/* $Id: SUPDrv-dtrace.d 33375 2010-10-24 12:29:42Z vboxsync $ */
/** @file
* SUPDrv - Static dtrace probes
*/
diff --git a/src/VBox/HostDrivers/Support/SUPDrv.c b/src/VBox/HostDrivers/Support/SUPDrv.c
index bec56c2ac..683904bc1 100644
--- a/src/VBox/HostDrivers/Support/SUPDrv.c
+++ b/src/VBox/HostDrivers/Support/SUPDrv.c
@@ -1,4 +1,4 @@
-/* $Revision: 71409 $ */
+/* $Revision: 37955 $ */
/** @file
* VBoxDrv - The VirtualBox Support Driver - Common code.
*/
@@ -54,13 +54,13 @@
# include <iprt/rand.h>
# include <iprt/path.h>
#endif
+#include <iprt/x86.h>
#include <VBox/param.h>
#include <VBox/log.h>
#include <VBox/err.h>
#include <VBox/vmm/hwacc_svm.h>
#include <VBox/vmm/hwacc_vmx.h>
-#include <VBox/x86.h>
#ifdef VBOX_WITH_DTRACE
# include "SUPDrv-dtrace.h"
@@ -278,7 +278,6 @@ static SUPFUNC g_aFunctions[] =
{ "RTThreadNativeSelf", (void *)RTThreadNativeSelf },
{ "RTThreadSleep", (void *)RTThreadSleep },
{ "RTThreadYield", (void *)RTThreadYield },
-#if 0 /* Thread APIs, Part 2. */
{ "RTThreadSelf", (void *)RTThreadSelf },
{ "RTThreadCreate", (void *)RTThreadCreate },
{ "RTThreadGetNative", (void *)RTThreadGetNative },
@@ -291,7 +290,6 @@ static SUPFUNC g_aFunctions[] =
{ "RTThreadUserReset", (void *)RTThreadUserReset },
{ "RTThreadUserWait", (void *)RTThreadUserWait },
{ "RTThreadUserWaitNoResume", (void *)RTThreadUserWaitNoResume },
-#endif
{ "RTThreadPreemptIsEnabled", (void *)RTThreadPreemptIsEnabled },
{ "RTThreadPreemptIsPending", (void *)RTThreadPreemptIsPending },
{ "RTThreadPreemptIsPendingTrusty", (void *)RTThreadPreemptIsPendingTrusty },
@@ -323,6 +321,8 @@ static SUPFUNC g_aFunctions[] =
{ "RTMpGetSet", (void *)RTMpGetSet },
{ "RTMpIsCpuOnline", (void *)RTMpIsCpuOnline },
{ "RTMpIsCpuWorkPending", (void *)RTMpIsCpuWorkPending },
+ { "RTMpNotificationRegister", (void *)RTMpNotificationRegister },
+ { "RTMpNotificationDeregister", (void *)RTMpNotificationDeregister },
{ "RTMpOnAll", (void *)RTMpOnAll },
{ "RTMpOnOthers", (void *)RTMpOnOthers },
{ "RTMpOnSpecific", (void *)RTMpOnSpecific },
@@ -336,6 +336,7 @@ static SUPFUNC g_aFunctions[] =
{ "RTR0AssertPanicSystem", (void *)RTR0AssertPanicSystem },
{ "RTAssertMsg1", (void *)RTAssertMsg1 },
{ "RTAssertMsg2V", (void *)RTAssertMsg2V },
+ { "RTAssertMsg2AddV", (void *)RTAssertMsg2AddV },
{ "RTAssertSetQuiet", (void *)RTAssertSetQuiet },
{ "RTAssertMayPanic", (void *)RTAssertMayPanic },
{ "RTAssertSetMayPanic", (void *)RTAssertSetMayPanic },
@@ -1399,8 +1400,8 @@ int VBOXCALL supdrvIOCtl(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION
case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_CALL_VMMR0_BIG):
{
/* validate */
+ PSUPCALLVMMR0 pReq = (PSUPCALLVMMR0)pReqHdr;
PSUPVMMR0REQHDR pVMMReq;
- PSUPCALLVMMR0 pReq = (PSUPCALLVMMR0)pReqHdr;
Log4(("SUP_IOCTL_CALL_VMMR0_BIG: op=%u in=%u arg=%RX64 p/t=%RTproc/%RTthrd\n",
pReq->u.In.uOperation, pReq->Hdr.cbIn, pReq->u.In.u64Arg, RTProcSelf(), RTThreadNativeSelf()));
@@ -4064,7 +4065,7 @@ static int supdrvIOCtl_LdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, P
pImage->pfnModuleTerm = pReq->u.In.pfnModuleTerm;
if (pImage->fNative)
- rc = supdrvOSLdrLoad(pDevExt, pImage, pReq->u.In.abImage);
+ rc = supdrvOSLdrLoad(pDevExt, pImage, pReq->u.In.abImage, pReq);
else
memcpy(pImage->pvImage, &pReq->u.In.abImage[0], pImage->cbImageBits);
}
@@ -4276,16 +4277,18 @@ static int supdrvIOCtl_LdrGetSymbol(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSessi
/*
* Search the symbol strings.
+ *
+ * Note! The int32_t is for native loading on solaris where the data
+ * and text segments are in very different places.
*/
pchStrings = pImage->pachStrTab;
paSyms = pImage->paSymbols;
for (i = 0; i < pImage->cSymbols; i++)
{
- if ( paSyms[i].offSymbol < pImage->cbImageBits /* paranoia */
- && paSyms[i].offName + cbSymbol <= pImage->cbStrTab
+ if ( paSyms[i].offName + cbSymbol <= pImage->cbStrTab
&& !memcmp(pchStrings + paSyms[i].offName, pReq->u.In.szSymbol, cbSymbol))
{
- pvSymbol = (uint8_t *)pImage->pvImage + paSyms[i].offSymbol;
+ pvSymbol = (uint8_t *)pImage->pvImage + (int32_t)paSyms[i].offSymbol;
rc = VINF_SUCCESS;
break;
}
@@ -4365,14 +4368,13 @@ static int supdrvIDC_LdrGetSymbol(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession
PCSUPLDRSYM paSyms = pImage->paSymbols;
for (i = 0; i < pImage->cSymbols; i++)
{
- if ( paSyms[i].offSymbol < pImage->cbImageBits /* paranoia */
- && paSyms[i].offName + cbSymbol <= pImage->cbStrTab
+ if ( paSyms[i].offName + cbSymbol <= pImage->cbStrTab
&& !memcmp(pchStrings + paSyms[i].offName, pszSymbol, cbSymbol))
{
/*
* Found it! Calc the symbol address and add a reference to the module.
*/
- pReq->u.Out.pfnSymbol = (PFNRT)((uint8_t *)pImage->pvImage + paSyms[i].offSymbol);
+ pReq->u.Out.pfnSymbol = (PFNRT)((uint8_t *)pImage->pvImage + (int32_t)paSyms[i].offSymbol);
rc = supdrvLdrAddUsage(pSession, pImage);
break;
}
@@ -4991,6 +4993,40 @@ static DECLCALLBACK(void) supdrvGipAsyncTimer(PRTTIMER pTimer, void *pvUser, uin
/**
+ * Finds our (@a idCpu) entry, or allocates a new one if not found.
+ *
+ * @returns Index of the CPU in the cache set.
+ * @param pGip The GIP.
+ * @param idCpu The CPU ID.
+ */
+static uint32_t supdrvGipCpuIndexFromCpuId(PSUPGLOBALINFOPAGE pGip, RTCPUID idCpu)
+{
+ uint32_t i, cTries;
+
+ /*
+ * ASSUMES that CPU IDs are constant.
+ */
+ for (i = 0; i < pGip->cCpus; i++)
+ if (pGip->aCPUs[i].idCpu == idCpu)
+ return i;
+
+ cTries = 0;
+ do
+ {
+ for (i = 0; i < pGip->cCpus; i++)
+ {
+ bool fRc;
+ ASMAtomicCmpXchgSize(&pGip->aCPUs[i].idCpu, idCpu, NIL_RTCPUID, fRc);
+ if (fRc)
+ return i;
+ }
+ } while (cTries++ < 32);
+ AssertReleaseFailed();
+ return i - 1;
+}
+
+
+/**
* The calling CPU should be accounted as online, update GIP accordingly.
*
* This is used by supdrvGipMpEvent as well as the supdrvGipCreate.
@@ -5000,11 +5036,11 @@ static DECLCALLBACK(void) supdrvGipAsyncTimer(PRTTIMER pTimer, void *pvUser, uin
*/
static void supdrvGipMpEventOnline(PSUPGLOBALINFOPAGE pGip, RTCPUID idCpu)
{
- int iCpuSet;
- uint8_t idApic;
- uint32_t i;
+ int iCpuSet = 0;
+ uint16_t idApic = UINT16_MAX;
+ uint32_t i = 0;
- Assert(idCpu == RTMpCpuId());
+ AssertRelease(idCpu == RTMpCpuId());
Assert(pGip->cPossibleCpus == RTMpGetCount());
/*
@@ -5021,38 +5057,22 @@ static void supdrvGipMpEventOnline(PSUPGLOBALINFOPAGE pGip, RTCPUID idCpu)
}
/*
- * Find our entry, or allocate one if not found.
- * ASSUMES that CPU IDs are constant.
- */
- for (i = 0; i < pGip->cCpus; i++)
- if (pGip->aCPUs[i].idCpu == idCpu)
- break;
-
- if (i >= pGip->cCpus)
- for (i = 0; i < pGip->cCpus; i++)
- {
- bool fRc;
- ASMAtomicCmpXchgSize(&pGip->aCPUs[i].idCpu, idCpu, NIL_RTCPUID, fRc);
- if (fRc)
- break;
- }
-
- AssertReturnVoid(i < pGip->cCpus);
-
- /*
* Update the entry.
*/
+ i = supdrvGipCpuIndexFromCpuId(pGip, idCpu);
idApic = ASMGetApicId();
ASMAtomicUoWriteU16(&pGip->aCPUs[i].idApic, idApic);
ASMAtomicUoWriteS16(&pGip->aCPUs[i].iCpuSet, (int16_t)iCpuSet);
ASMAtomicUoWriteSize(&pGip->aCPUs[i].idCpu, idCpu);
- ASMAtomicWriteSize(&pGip->aCPUs[i].enmState, SUPGIPCPUSTATE_ONLINE);
/*
* Update the APIC ID and CPU set index mappings.
*/
ASMAtomicWriteU16(&pGip->aiCpuFromApicId[idApic], i);
ASMAtomicWriteU16(&pGip->aiCpuFromCpuSetIdx[iCpuSet], i);
+
+ /* commit it */
+ ASMAtomicWriteSize(&pGip->aCPUs[i].enmState, SUPGIPCPUSTATE_ONLINE);
}
@@ -5077,8 +5097,10 @@ static void supdrvGipMpEventOffline(PSUPGLOBALINFOPAGE pGip, RTCPUID idCpu)
AssertReturnVoid(pGip->aCPUs[i].idCpu == idCpu);
Assert(RTCpuSetIsMemberByIndex(&pGip->PossibleCpuSet, iCpuSet));
- ASMAtomicWriteSize(&pGip->aCPUs[i].enmState, SUPGIPCPUSTATE_OFFLINE);
RTCpuSetDelByIndex(&pGip->OnlineCpuSet, iCpuSet);
+
+ /* commit it */
+ ASMAtomicWriteSize(&pGip->aCPUs[i].enmState, SUPGIPCPUSTATE_OFFLINE);
}
@@ -5097,6 +5119,9 @@ static DECLCALLBACK(void) supdrvGipMpEvent(RTMPEVENT enmEvent, RTCPUID idCpu, vo
PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pvUser;
PSUPGLOBALINFOPAGE pGip = pDevExt->pGip;
+ AssertRelease(idCpu == RTMpCpuId());
+ AssertRelease(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+
/*
* Update the GIP CPU data.
*/
@@ -5119,8 +5144,7 @@ static DECLCALLBACK(void) supdrvGipMpEvent(RTMPEVENT enmEvent, RTCPUID idCpu, vo
*/
if (enmEvent == RTMPEVENT_OFFLINE)
{
- RTCPUID idGipMaster;
- ASMAtomicReadSize(&pDevExt->idGipMaster, &idGipMaster);
+ RTCPUID idGipMaster = ASMAtomicReadU32(&pDevExt->idGipMaster);
if (idGipMaster == idCpu)
{
/*
@@ -5360,7 +5384,7 @@ static void supdrvGipInit(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, RTHCPH
pGip->aCPUs[i].enmState = SUPGIPCPUSTATE_INVALID;
pGip->aCPUs[i].idCpu = NIL_RTCPUID;
pGip->aCPUs[i].iCpuSet = -1;
- pGip->aCPUs[i].idApic = UINT8_MAX;
+ pGip->aCPUs[i].idApic = UINT16_MAX;
/*
* We don't know the following values until we've executed updates.
@@ -5619,14 +5643,26 @@ static void supdrvGipUpdate(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_
static void supdrvGipUpdatePerCpu(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC,
RTCPUID idCpu, uint8_t idApic, uint64_t iTick)
{
- unsigned iCpu = pGip->aiCpuFromApicId[idApic];
+ uint32_t iCpu;
+ /*
+ * Avoid a potential race when a CPU online notification doesn't fire on
+ * the onlined CPU but the tick creeps in before the event notification is
+ * run.
+ */
+ if (RT_UNLIKELY(iTick == 1))
+ {
+ iCpu = supdrvGipCpuIndexFromCpuId(pGip, idCpu);
+ if (pGip->aCPUs[iCpu].enmState == SUPGIPCPUSTATE_OFFLINE)
+ supdrvGipMpEventOnline(pGip, idCpu);
+ }
+
+ iCpu = pGip->aiCpuFromApicId[idApic];
if (RT_LIKELY(iCpu < pGip->cCpus))
{
PSUPGIPCPU pGipCpu = &pGip->aCPUs[iCpu];
if (pGipCpu->idCpu == idCpu)
{
-
/*
* Start update transaction.
*/
diff --git a/src/VBox/HostDrivers/Support/SUPDrvIDC.h b/src/VBox/HostDrivers/Support/SUPDrvIDC.h
index ca9fe3148..524e6bdfb 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvIDC.h
+++ b/src/VBox/HostDrivers/Support/SUPDrvIDC.h
@@ -1,4 +1,4 @@
-/* $Id: SUPDrvIDC.h $ */
+/* $Id: SUPDrvIDC.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VirtualBox Support Driver - Inter-Driver Communication (IDC) definitions.
*/
diff --git a/src/VBox/HostDrivers/Support/SUPDrvIOC.h b/src/VBox/HostDrivers/Support/SUPDrvIOC.h
index b4d0f54b7..806107953 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvIOC.h
+++ b/src/VBox/HostDrivers/Support/SUPDrvIOC.h
@@ -1,4 +1,4 @@
-/* $Revision: 70529 $ */
+/* $Revision: 37591 $ */
/** @file
* VirtualBox Support Driver - IOCtl definitions.
*/
@@ -192,7 +192,7 @@ typedef SUPREQHDR *PSUPREQHDR;
* @todo Pending work on next major version change:
* - None.
*/
-#define SUPDRV_IOC_VERSION 0x00180000
+#define SUPDRV_IOC_VERSION 0x00190000
/** SUP_IOCTL_COOKIE. */
typedef struct SUPCOOKIE
@@ -345,7 +345,11 @@ typedef struct SUPLDRSYM
{
/** Offset into of the string table. */
uint32_t offName;
- /** Offset of the symbol relative to the image load address. */
+ /** Offset of the symbol relative to the image load address.
+ * @remarks When used inside the SUPDrv to calculate real addresses, it
+ * must be cast to int32_t for the sake of native loader support
+ * on Solaris. (The loader puts the and data in different
+ * memory areans, and the text one is generally higher.) */
uint32_t offSymbol;
} SUPLDRSYM;
/** Pointer to a symbol table entry. */
diff --git a/src/VBox/HostDrivers/Support/SUPDrvInternal.h b/src/VBox/HostDrivers/Support/SUPDrvInternal.h
index f3674ed8b..5eb135350 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvInternal.h
+++ b/src/VBox/HostDrivers/Support/SUPDrvInternal.h
@@ -1,4 +1,4 @@
-/* $Revision: 69603 $ */
+/* $Revision: 37249 $ */
/** @file
* VirtualBox Support Driver - Internal header.
*/
@@ -298,6 +298,12 @@ typedef struct SUPDRVLDRIMAGE
/** Lock object. */
RTR0MEMOBJ hMemLock;
#endif
+#if defined(RT_OS_SOLARIS) && defined(VBOX_WITH_NATIVE_SOLARIS_LOADING)
+ /** The Solaris module ID. */
+ int idSolMod;
+ /** Pointer to the module control structure. */
+ struct modctl *pSolModCtl;
+#endif
/** Whether it's loaded by the native loader or not. */
bool fNative;
/** Image name. */
@@ -570,11 +576,13 @@ int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAG
*
* @returns IPRT status code.
* @param pDevExt The device globals.
- * @param pImage The image data (up to date except for some
- * entry point pointers).
+ * @param pImage The image data (up to date). Adjust entrypoints
+ * and exports if necessary.
* @param pbImageBits The image bits as loaded by ring-3.
+ * @param pReq Pointer to the request packet so that the VMMR0
+ * entry points can be adjusted.
*/
-int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits);
+int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq);
/**
diff --git a/src/VBox/HostDrivers/Support/SUPDrvSem.c b/src/VBox/HostDrivers/Support/SUPDrvSem.c
index f546f56fb..b0c7901c7 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvSem.c
+++ b/src/VBox/HostDrivers/Support/SUPDrvSem.c
@@ -1,4 +1,4 @@
-/* $Revision: 66703 $ */
+/* $Revision: 33167 $ */
/** @file
* VBoxDrv - The VirtualBox Support Driver - Common OS agnostic.
*/
diff --git a/src/VBox/HostDrivers/Support/SUPLib.cpp b/src/VBox/HostDrivers/Support/SUPLib.cpp
index 17ba3a353..4c3821961 100644
--- a/src/VBox/HostDrivers/Support/SUPLib.cpp
+++ b/src/VBox/HostDrivers/Support/SUPLib.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPLib.cpp $ */
+/* $Id: SUPLib.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* VirtualBox Support Library - Common code.
*/
@@ -50,7 +50,6 @@
#include <VBox/err.h>
#include <VBox/param.h>
#include <VBox/log.h>
-#include <VBox/x86.h>
#include <iprt/assert.h>
#include <iprt/alloc.h>
@@ -65,6 +64,7 @@
#include <iprt/string.h>
#include <iprt/env.h>
#include <iprt/rand.h>
+#include <iprt/x86.h>
#include "SUPLibInternal.h"
#include "SUPDrvIOC.h"
@@ -96,7 +96,7 @@ static bool g_fPreInited = false;
* via the pre-init mechanism from the hardened executable stub. */
SUPLIBDATA g_supLibData =
{
- NIL_RTFILE
+ SUP_HDEVICE_NIL
#if defined(RT_OS_DARWIN)
, NULL
#elif defined(RT_OS_LINUX)
@@ -184,10 +184,10 @@ DECLEXPORT(int) supR3PreInit(PSUPPREINITDATA pPreInitData, uint32_t fFlags)
|| pPreInitData->u32EndMagic != SUPPREINITDATA_MAGIC)
return VERR_INVALID_MAGIC;
if ( !(fFlags & SUPSECMAIN_FLAGS_DONT_OPEN_DEV)
- && pPreInitData->Data.hDevice == NIL_RTFILE)
+ && pPreInitData->Data.hDevice == SUP_HDEVICE_NIL)
return VERR_INVALID_HANDLE;
if ( (fFlags & SUPSECMAIN_FLAGS_DONT_OPEN_DEV)
- && pPreInitData->Data.hDevice != NIL_RTFILE)
+ && pPreInitData->Data.hDevice != SUP_HDEVICE_NIL)
return VERR_INVALID_PARAMETER;
/*
@@ -266,9 +266,9 @@ SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession)
CookieReq.Hdr.rc = VERR_INTERNAL_ERROR;
strcpy(CookieReq.u.In.szMagic, SUPCOOKIE_MAGIC);
CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
- const uint32_t uMinVersion = /*(SUPDRV_IOC_VERSION & 0xffff0000) == 0x00160000
- ? 0x00160001
- : */ SUPDRV_IOC_VERSION & 0xffff0000;
+ const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00170000
+ ? 0x00170002
+ : SUPDRV_IOC_VERSION & 0xffff0000;
CookieReq.u.In.u32MinVersion = uMinVersion;
rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_COOKIE, &CookieReq, SUP_IOCTL_COOKIE_SIZE);
if ( RT_SUCCESS(rc)
@@ -1688,6 +1688,29 @@ static DECLCALLBACK(int) supLoadModuleResolveImport(RTLDRMOD hLdrMod, const char
}
/*
+ * Symbols that are undefined by convention.
+ */
+#ifdef RT_OS_SOLARIS
+ static const char * const s_apszConvSyms[] =
+ {
+ "", "mod_getctl",
+ "", "mod_install",
+ "", "mod_remove",
+ "", "mod_info",
+ "", "mod_miscops",
+ };
+ for (unsigned i = 0; i < RT_ELEMENTS(s_apszConvSyms); i += 2)
+ {
+ if ( !RTStrCmp(s_apszConvSyms[i], pszModule)
+ && !RTStrCmp(s_apszConvSyms[i + 1], pszSymbol))
+ {
+ *pValue = ~(uintptr_t)0;
+ return VINF_SUCCESS;
+ }
+ }
+#endif
+
+ /*
* Despair.
*/
c = g_pFunctions->u.Out.cFunctions;
diff --git a/src/VBox/HostDrivers/Support/SUPLibInternal.h b/src/VBox/HostDrivers/Support/SUPLibInternal.h
index 490e88161..34e884e7a 100644
--- a/src/VBox/HostDrivers/Support/SUPLibInternal.h
+++ b/src/VBox/HostDrivers/Support/SUPLibInternal.h
@@ -1,4 +1,4 @@
-/* $Id: SUPLibInternal.h $ */
+/* $Id: SUPLibInternal.h 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VirtualBox Support Library - Internal header.
*/
@@ -184,7 +184,11 @@ typedef SUPVERIFIEDDIR const *PCSUPVERIFIEDDIR;
typedef struct SUPLIBDATA
{
/** The device handle. */
- RTFILE hDevice;
+#if defined(RT_OS_WINDOWS)
+ void *hDevice;
+#else
+ int hDevice;
+#endif
#if defined(RT_OS_DARWIN)
/** The connection to the VBoxSupDrv service. */
uintptr_t uConnection;
@@ -203,6 +207,13 @@ typedef SUPLIBDATA *PSUPLIBDATA;
/** Pointer to const pre-init data. */
typedef SUPLIBDATA const *PCSUPLIBDATA;
+/** The NIL value of SUPLIBDATA::hDevice. */
+#if defined(RT_OS_WINDOWS)
+# define SUP_HDEVICE_NIL NULL
+#else
+# define SUP_HDEVICE_NIL (-1)
+#endif
+
/**
* Pre-init data that is handed over from the hardened executable stub.
diff --git a/src/VBox/HostDrivers/Support/SUPLibSem.cpp b/src/VBox/HostDrivers/Support/SUPLibSem.cpp
index bd7f2e56c..3f91d60fd 100644
--- a/src/VBox/HostDrivers/Support/SUPLibSem.cpp
+++ b/src/VBox/HostDrivers/Support/SUPLibSem.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPLibSem.cpp $ */
+/* $Id: SUPLibSem.cpp 33167 2010-10-15 18:16:59Z vboxsync $ */
/** @file
* VirtualBox Support Library - Semaphores, ring-3 implementation.
*/
diff --git a/src/VBox/HostDrivers/Support/SUPR0.def b/src/VBox/HostDrivers/Support/SUPR0.def
index c57b09ab9..9a72a752b 100644
--- a/src/VBox/HostDrivers/Support/SUPR0.def
+++ b/src/VBox/HostDrivers/Support/SUPR0.def
@@ -1,4 +1,4 @@
-; $Id: SUPR0.def $
+; $Id: SUPR0.def 37410 2011-06-10 15:11:40Z vboxsync $
;; @file
; VirtualBox Support Driver - Exports.
;
@@ -166,6 +166,8 @@ EXPORTS
RTMpGetSet
RTMpIsCpuOnline
RTMpIsCpuWorkPending
+ RTMpNotificationRegister
+ RTMpNotificationDeregister
RTMpOnAll
RTMpOnOthers
RTMpOnSpecific
@@ -179,6 +181,7 @@ EXPORTS
RTLogPrintfV
RTAssertMsg1
RTAssertMsg2V
+ RTAssertMsg2AddV
RTAssertSetQuiet
RTAssertMayPanic
RTAssertSetMayPanic
diff --git a/src/VBox/HostDrivers/Support/SUPR0IdcClient.c b/src/VBox/HostDrivers/Support/SUPR0IdcClient.c
index 7d7193c57..d63dd1d19 100644
--- a/src/VBox/HostDrivers/Support/SUPR0IdcClient.c
+++ b/src/VBox/HostDrivers/Support/SUPR0IdcClient.c
@@ -1,4 +1,4 @@
-/* $Id: SUPR0IdcClient.c $ */
+/* $Id: SUPR0IdcClient.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VirtualBox Support Driver - IDC Client Lib, Core.
*/
diff --git a/src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c b/src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c
index d867a37e1..db7d54ba3 100644
--- a/src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c
+++ b/src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c
@@ -1,4 +1,4 @@
-/* $Id: SUPR0IdcClientComponent.c $ */
+/* $Id: SUPR0IdcClientComponent.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VirtualBox Support Driver - IDC Client Lib, Component APIs.
*/
diff --git a/src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h b/src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h
index 29ada07f1..c5bde94fe 100644
--- a/src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h
+++ b/src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h
@@ -1,4 +1,4 @@
-/* $Id: SUPR0IdcClientInternal.h $ */
+/* $Id: SUPR0IdcClientInternal.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VirtualBox Support Driver - Internal header for the IDC client library.
*/
diff --git a/src/VBox/HostDrivers/Support/SUPR0IdcClientStubs.c b/src/VBox/HostDrivers/Support/SUPR0IdcClientStubs.c
index 595d24740..41ee67d94 100644
--- a/src/VBox/HostDrivers/Support/SUPR0IdcClientStubs.c
+++ b/src/VBox/HostDrivers/Support/SUPR0IdcClientStubs.c
@@ -1,4 +1,4 @@
-/* $Id: SUPR0IdcClientStubs.c $ */
+/* $Id: SUPR0IdcClientStubs.c 29285 2010-05-10 00:22:29Z vboxsync $ */
/** @file
* VirtualBox Support Driver - IDC Client Lib, Stubs for SUPR0 APIs.
*/
diff --git a/src/VBox/HostDrivers/Support/SUPR3HardenedIPRT.cpp b/src/VBox/HostDrivers/Support/SUPR3HardenedIPRT.cpp
index f13e42f67..30378807e 100644
--- a/src/VBox/HostDrivers/Support/SUPR3HardenedIPRT.cpp
+++ b/src/VBox/HostDrivers/Support/SUPR3HardenedIPRT.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPR3HardenedIPRT.cpp $ */
+/* $Id: SUPR3HardenedIPRT.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VirtualBox Support Library - Hardened Support Routines using IPRT.
*/
diff --git a/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp b/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp
index 655661382..61082b00f 100644
--- a/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp
+++ b/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPR3HardenedMain.cpp $ */
+/* $Id: SUPR3HardenedMain.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VirtualBox Support Library - Hardened main().
*/
@@ -1018,9 +1018,9 @@ DECLHIDDEN(int) SUPR3HardenedMain(const char *pszProgName, uint32_t fFlags, int
* to basic CRT functions that everyone agree upon.
*/
g_pszSupLibHardenedProgName = pszProgName;
- g_SupPreInitData.u32Magic = SUPPREINITDATA_MAGIC;
- g_SupPreInitData.Data.hDevice = NIL_RTFILE;
- g_SupPreInitData.u32EndMagic = SUPPREINITDATA_MAGIC;
+ g_SupPreInitData.u32Magic = SUPPREINITDATA_MAGIC;
+ g_SupPreInitData.Data.hDevice = SUP_HDEVICE_NIL;
+ g_SupPreInitData.u32EndMagic = SUPPREINITDATA_MAGIC;
#ifdef SUP_HARDENED_SUID
# ifdef RT_OS_LINUX
diff --git a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
index bd820bace..184d0801a 100644
--- a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
+++ b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPR3HardenedVerify.cpp $ */
+/* $Id: SUPR3HardenedVerify.cpp 37344 2011-06-07 12:23:53Z vboxsync $ */
/** @file
* VirtualBox Support Library - Verification of Hardened Installation.
*/
@@ -1186,11 +1186,10 @@ static int supR3HardenedVerifyFsObject(PCSUPR3HARDENEDFSOBJSTATE pFsObjState, bo
full access. So, to work around we relax the hardening a bit and
permit grand parents and beyond to be group writable by admin. */
if (pFsObjState->Stat.st_gid != 80 /*admin*/) /** @todo dynamically resolve the admin group? */
-#endif
-#ifdef RT_OS_FREEBSD
- /* PC-BSD 9 has group-writable application directory, similar to OSX and
- their Applications directory */
- if (pFsObjState->Stat.st_gid != 5 /*operators*/) /* Allow operators group-writes */
+#elif defined(RT_OS_FREEBSD)
+ /* HACK ALERT: PC-BSD 9 has group-writable application directory,
+ similar to OS X and their /Applications directory (see above). */
+ if (pFsObjState->Stat.st_gid != 5 /*operators*/)
#endif
return supR3HardenedSetError3(VERR_SUPLIB_WRITE_NON_SYS_GROUP, pErrInfo,
"The group is not a system group and it has write access to '", pszPath, "'");
diff --git a/src/VBox/HostDrivers/Support/SUPSvc.cpp b/src/VBox/HostDrivers/Support/SUPSvc.cpp
index de087be52..9e7eb8a2d 100644
--- a/src/VBox/HostDrivers/Support/SUPSvc.cpp
+++ b/src/VBox/HostDrivers/Support/SUPSvc.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPSvc.cpp $ */
+/* $Id: SUPSvc.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VirtualBox Support Service - Common Code.
*/
diff --git a/src/VBox/HostDrivers/Support/SUPSvcGlobal.cpp b/src/VBox/HostDrivers/Support/SUPSvcGlobal.cpp
index f58a03adb..fa2290b58 100644
--- a/src/VBox/HostDrivers/Support/SUPSvcGlobal.cpp
+++ b/src/VBox/HostDrivers/Support/SUPSvcGlobal.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPSvcGlobal.cpp $ */
+/* $Id: SUPSvcGlobal.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VirtualBox Support Service - The Global Service.
*/
diff --git a/src/VBox/HostDrivers/Support/SUPSvcGrant.cpp b/src/VBox/HostDrivers/Support/SUPSvcGrant.cpp
index 50a9cdef8..7f66afed3 100644
--- a/src/VBox/HostDrivers/Support/SUPSvcGrant.cpp
+++ b/src/VBox/HostDrivers/Support/SUPSvcGrant.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPSvcGrant.cpp $ */
+/* $Id: SUPSvcGrant.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VirtualBox Support Service - The Grant Service.
*/
diff --git a/src/VBox/HostDrivers/Support/SUPSvcInternal.h b/src/VBox/HostDrivers/Support/SUPSvcInternal.h
index afdc78f40..eb0f5f02c 100644
--- a/src/VBox/HostDrivers/Support/SUPSvcInternal.h
+++ b/src/VBox/HostDrivers/Support/SUPSvcInternal.h
@@ -1,4 +1,4 @@
-/* $Id: SUPSvcInternal.h $ */
+/* $Id: SUPSvcInternal.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VirtualBox Support Service - Internal header.
*/
diff --git a/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp b/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
index a2c97d020..f6f66574c 100644
--- a/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
+++ b/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPDrv-darwin.cpp $ */
+/* $Id: SUPDrv-darwin.cpp 37970 2011-07-14 14:37:23Z vboxsync $ */
/** @file
* VirtualBox Support Driver - Darwin Specific Code.
*/
@@ -360,8 +360,13 @@ static int VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *p
kauth_cred_t pCred = kauth_cred_proc_ref(pProcess);
if (pCred)
{
- RTUID Uid = pCred->cr_ruid;
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+ RTUID Uid = kauth_cred_getruid(pCred);
+ RTGID Gid = kauth_cred_getrgid(pCred);
+#else
+ RTUID Uid = pCred->cr_ruid;
RTGID Gid = pCred->cr_rgid;
+#endif
RTPROCESS Process = RTProcSelf();
unsigned iHash = SESSION_HASH(Process);
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
@@ -770,9 +775,9 @@ int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAG
}
-int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits)
+int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
{
- NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits);
+ NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits); NOREF(pReq);
return VERR_NOT_SUPPORTED;
}
@@ -809,17 +814,16 @@ static int VBoxDrvDarwinErr2DarwinErr(int rc)
}
-/** @todo move this to assembly where a simple "jmp printf" will to the trick. */
RTDECL(int) SUPR0Printf(const char *pszFormat, ...)
{
- va_list args;
+ va_list va;
char szMsg[512];
- va_start(args, pszFormat);
- vsnprintf(szMsg, sizeof(szMsg) - 1, pszFormat, args);
- va_end(args);
-
+ va_start(va, pszFormat);
+ RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, va);
+ va_end(va);
szMsg[sizeof(szMsg) - 1] = '\0';
+
printf("%s", szMsg);
return 0;
}
diff --git a/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp b/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp
index bf9b87059..d2f2b0122 100644
--- a/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp
+++ b/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPLib-darwin.cpp $ */
+/* $Id: SUPLib-darwin.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VirtualBox Support Library - Darwin specific parts.
*/
@@ -193,7 +193,7 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
/*
* Do the job.
*/
- Assert(pThis->hDevice == NIL_RTFILE);
+ Assert(pThis->hDevice == (intptr_t)NIL_RTFILE);
int rc = suplibDarwinOpenService(pThis);
if (RT_SUCCESS(rc))
{
@@ -236,11 +236,11 @@ int suplibOsTerm(PSUPLIBDATA pThis)
/*
* Check if we're inited at all.
*/
- if (pThis->hDevice != NIL_RTFILE)
+ if (pThis->hDevice != (intptr_t)NIL_RTFILE)
{
if (close(pThis->hDevice))
AssertFailed();
- pThis->hDevice = NIL_RTFILE;
+ pThis->hDevice = (intptr_t)NIL_RTFILE;
}
return VINF_SUCCESS;
diff --git a/src/VBox/HostDrivers/Support/darwin/SUPR0IdcClient-darwin.c b/src/VBox/HostDrivers/Support/darwin/SUPR0IdcClient-darwin.c
index 128a6907c..a9171c940 100644
--- a/src/VBox/HostDrivers/Support/darwin/SUPR0IdcClient-darwin.c
+++ b/src/VBox/HostDrivers/Support/darwin/SUPR0IdcClient-darwin.c
@@ -1,4 +1,4 @@
-/* $Id: SUPR0IdcClient-darwin.c $ */
+/* $Id: SUPR0IdcClient-darwin.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VirtualBox Support Driver - IDC Client Lib, Darwin Specific Code.
*/
diff --git a/src/VBox/HostDrivers/Support/freebsd/Makefile b/src/VBox/HostDrivers/Support/freebsd/Makefile
index 9b0050fc5..5f805155a 100644
--- a/src/VBox/HostDrivers/Support/freebsd/Makefile
+++ b/src/VBox/HostDrivers/Support/freebsd/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile $
+# $Id: Makefile 37233 2011-05-27 13:31:57Z vboxsync $
## @file
# Makefile for the VirtualBox FreeBSD Host Driver.
#
@@ -84,9 +84,9 @@ SRCS += \
.PATH: ${.CURDIR}/common/string
SRCS += \
- RTStrCopyP.c \
- RTStrCopy.c \
RTStrNCmp.c \
+ RTStrCopy.c \
+ RTStrCopyP.c \
strformat.c \
strformatrt.c \
strformattype.c \
@@ -135,6 +135,7 @@ SRCS += \
RTSemEventMultiWait-2-ex-generic.c \
RTSemEventMultiWaitNoResume-2-ex-generic.c \
RTTimerCreate-generic.c \
+ errvars-generic.c \
mppresent-generic.c \
timer-generic.c
diff --git a/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c b/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c
index e2e1b46f9..f0780450a 100644
--- a/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c
+++ b/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: SUPDrv-freebsd.c $ */
+/* $Id: SUPDrv-freebsd.c 37249 2011-05-30 10:03:45Z vboxsync $ */
/** @file
* VBoxDrv - The VirtualBox Support Driver - FreeBSD specifics.
*/
@@ -615,9 +615,9 @@ int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAG
}
-int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits)
+int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
{
- NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits);
+ NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits); NOREF(pReq);
return VERR_NOT_SUPPORTED;
}
diff --git a/src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp b/src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp
index 2b2179041..6e6b28c9f 100644
--- a/src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp
+++ b/src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPLib-freebsd.cpp $ */
+/* $Id: SUPLib-freebsd.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VirtualBox Support Library - FreeBSD specific parts.
*/
@@ -132,11 +132,11 @@ int suplibOsTerm(PSUPLIBDATA pThis)
/*
* Check if we're inited at all.
*/
- if (pThis->hDevice != NIL_RTFILE)
+ if (pThis->hDevice != (intptr_t)NIL_RTFILE)
{
if (close(pThis->hDevice))
AssertFailed();
- pThis->hDevice = NIL_RTFILE;
+ pThis->hDevice = (intptr_t)NIL_RTFILE;
}
return VINF_SUCCESS;
}
diff --git a/src/VBox/HostDrivers/Support/freebsd/SUPR0IdcClient-freebsd.c b/src/VBox/HostDrivers/Support/freebsd/SUPR0IdcClient-freebsd.c
index b0e39038d..570ce7815 100644
--- a/src/VBox/HostDrivers/Support/freebsd/SUPR0IdcClient-freebsd.c
+++ b/src/VBox/HostDrivers/Support/freebsd/SUPR0IdcClient-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: SUPR0IdcClient-freebsd.c $ */
+/* $Id: SUPR0IdcClient-freebsd.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VirtualBox Support Driver - IDC Client Lib, FreeBSD Specific Code.
*/
diff --git a/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv b/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv
index aa585e176..ccfee76a4 100755..100644
--- a/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv
+++ b/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: files_vboxdrv $
+# $Id: files_vboxdrv 37955 2011-07-14 12:23:02Z vboxsync $
## @file
# Shared file between Makefile.kmk and export_modules
#
@@ -67,6 +67,7 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/include/iprt/path.h=>include/iprt/path.h \
${PATH_ROOT}/include/iprt/once.h=>include/iprt/once.h \
${PATH_ROOT}/include/iprt/critsect.h=>include/iprt/critsect.h \
+ ${PATH_ROOT}/include/iprt/x86.h=>include/iprt/x86.h \
${PATH_ROOT}/include/iprt/lockvalidator.h=>include/iprt/lockvalidator.h \
${PATH_ROOT}/include/iprt/nocrt/limits.h=>include/iprt/nocrt/limits.h \
${PATH_ROOT}/include/VBox/cdefs.h=>include/VBox/cdefs.h \
@@ -79,7 +80,6 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/include/VBox/SUPDrvMangling.h=>include/VBox/SUPDrvMangling.h \
${PATH_ROOT}/include/VBox/vmm/hwacc_vmx.h=>include/VBox/vmm/hwacc_vmx.h \
${PATH_ROOT}/include/VBox/vmm/hwacc_svm.h=>include/VBox/vmm/hwacc_svm.h \
- ${PATH_ROOT}/include/VBox/x86.h=>include/VBox/x86.h \
${PATH_ROOT}/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c=>freebsd/SUPDrv-freebsd.c \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrv.c=>SUPDrv.c \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrvSem.c=>SUPDrvSem.c \
@@ -153,15 +153,16 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/generic/RTLogWriteDebugger-generic.cpp=>generic/RTLogWriteDebugger-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTRandAdvCreateSystemFaster-generic.cpp=>generic/RTRandAdvCreateSystemFaster-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTRandAdvCreateSystemTruer-generic.cpp=>generic/RTRandAdvCreateSystemTruer-generic.c \
- ${PATH_ROOT}/src/VBox/Runtime/generic/uuid-generic.cpp=>generic/uuid-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventWait-2-ex-generic.cpp=>generic/RTSemEventWait-2-ex-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventWaitNoResume-2-ex-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp=>generic/RTSemEventMultiWait-2-ex-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventMultiWaitNoResume-2-ex-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTTimerCreate-generic.cpp=>generic/RTTimerCreate-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTMpGetArraySize-generic.cpp=>generic/RTMpGetArraySize-generic.c \
+ ${PATH_ROOT}/src/VBox/Runtime/generic/errvars-generic.cpp=>generic/errvars-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/mppresent-generic.cpp=>generic/mppresent-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/timer-generic.cpp=>generic/timer-generic.c \
+ ${PATH_ROOT}/src/VBox/Runtime/generic/uuid-generic.cpp=>generic/uuid-generic.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.cpp=>r0drv/alloc-r0drv.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.h=>r0drv/alloc-r0drv.h \
${PATH_ROOT}/src/VBox/Runtime/r0drv/initterm-r0drv.cpp=>r0drv/initterm-r0drv.c \
diff --git a/src/VBox/HostDrivers/Support/linux/Makefile b/src/VBox/HostDrivers/Support/linux/Makefile
index 32faa0a8f..e98dba678 100644
--- a/src/VBox/HostDrivers/Support/linux/Makefile
+++ b/src/VBox/HostDrivers/Support/linux/Makefile
@@ -1,4 +1,4 @@
-# $Revision: 70883 $
+# $Revision: 37233 $
## @file
# Makefile for the VirtualBox Linux Host Driver.
#
@@ -118,12 +118,14 @@ OBJS = \
common/misc/assert.o \
common/misc/handletable.o \
common/misc/handletablectx.o \
+ common/misc/thread.o \
common/string/RTStrCopyP.o \
common/string/strformat.o \
common/string/strformatrt.o \
common/string/strformattype.o \
common/string/strprintf.o \
common/string/strtonum.o \
+ common/table/avlpv.o \
common/time/time.o \
r0drv/linux/RTLogWriteDebugger-r0drv-linux.o \
generic/RTAssertShouldPanic-generic.o \
@@ -136,6 +138,7 @@ OBJS = \
generic/RTSemEventMultiWait-2-ex-generic.o \
generic/RTSemEventMultiWaitNoResume-2-ex-generic.o \
generic/RTTimerCreate-generic.o \
+ generic/errvars-generic.o \
generic/mppresent-generic.o \
generic/uuid-generic.o \
VBox/log-vbox.o
diff --git a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
index f4a60d804..a9ebd1e25 100644
--- a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
+++ b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
@@ -1,4 +1,4 @@
-/* $Rev: 69377 $ */
+/* $Rev: 37972 $ */
/** @file
* VBoxDrv - The VirtualBox Support Driver - Linux specifics.
*/
@@ -739,9 +739,9 @@ int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAG
}
-int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits)
+int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
{
- NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits);
+ NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits); NOREF(pReq);
return VERR_NOT_SUPPORTED;
}
@@ -781,22 +781,15 @@ static int VBoxDrvLinuxErr2LinuxErr(int rc)
RTDECL(int) SUPR0Printf(const char *pszFormat, ...)
{
-#if 1
- va_list args;
+ va_list va;
char szMsg[512];
- va_start(args, pszFormat);
- vsnprintf(szMsg, sizeof(szMsg) - 1, pszFormat, args);
+ va_start(va, pszFormat);
+ RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, va);
+ va_end(va);
szMsg[sizeof(szMsg) - 1] = '\0';
+
printk("%s", szMsg);
- va_end(args);
-#else
- /* forward to printf - needs some more GCC hacking to fix ebp... */
- __asm__ __volatile__ ("mov %0, %esp\n\t"
- "jmp %1\n\t",
- :: "r" ((uintptr_t)&pszFormat - 4),
- "m" (printk));
-#endif
return 0;
}
diff --git a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.mod.c b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.mod.c
index 0aaea1a1c..913869e87 100644
--- a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.mod.c
+++ b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.mod.c
@@ -1,4 +1,4 @@
-/* $Id: SUPDrv-linux.mod.c $ */
+/* $Id: SUPDrv-linux.mod.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxDrv - The VirtualBox Support Driver - Autogenerated Linux code.
*
diff --git a/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp b/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp
index 9d31b7f58..0fd899817 100644
--- a/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp
+++ b/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPLib-linux.cpp $ */
+/* $Id: SUPLib-linux.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VirtualBox Support Library - GNU/Linux specific parts.
*/
@@ -78,7 +78,7 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
*/
if (fPreInited)
return VINF_SUCCESS;
- Assert(pThis->hDevice == NIL_RTFILE);
+ Assert(pThis->hDevice == (intptr_t)NIL_RTFILE);
/*
* Check if madvise works.
@@ -144,11 +144,11 @@ int suplibOsTerm(PSUPLIBDATA pThis)
/*
* Close the device if it's actually open.
*/
- if (pThis->hDevice != NIL_RTFILE)
+ if (pThis->hDevice != (intptr_t)NIL_RTFILE)
{
if (close(pThis->hDevice))
AssertFailed();
- pThis->hDevice = NIL_RTFILE;
+ pThis->hDevice = (intptr_t)NIL_RTFILE;
}
return 0;
@@ -171,7 +171,7 @@ int suplibOsUninstall(void)
int suplibOsIOCtl(PSUPLIBDATA pThis, uintptr_t uFunction, void *pvReq, size_t cbReq)
{
- AssertMsg(pThis->hDevice != NIL_RTFILE, ("SUPLIB not initiated successfully!\n"));
+ AssertMsg(pThis->hDevice != (intptr_t)NIL_RTFILE, ("SUPLIB not initiated successfully!\n"));
/*
* Issue device iocontrol.
diff --git a/src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c b/src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c
index 15d9761fe..b9433056c 100644
--- a/src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c
+++ b/src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c
@@ -1,4 +1,4 @@
-/* $Id: SUPR0IdcClient-linux.c $ */
+/* $Id: SUPR0IdcClient-linux.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VirtualBox Support Driver - IDC Client Lib, Linux Specific Code.
*/
diff --git a/src/VBox/HostDrivers/Support/linux/files_vboxdrv b/src/VBox/HostDrivers/Support/linux/files_vboxdrv
index e805b1dce..f67be7ce3 100755..100644
--- a/src/VBox/HostDrivers/Support/linux/files_vboxdrv
+++ b/src/VBox/HostDrivers/Support/linux/files_vboxdrv
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: files_vboxdrv $
+# $Id: files_vboxdrv 37955 2011-07-14 12:23:02Z vboxsync $
## @file
# Shared file between Makefile.kmk and export_modules
#
@@ -63,6 +63,7 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/include/iprt/types.h=>include/iprt/types.h \
${PATH_ROOT}/include/iprt/uni.h=>include/iprt/uni.h \
${PATH_ROOT}/include/iprt/uuid.h=>include/iprt/uuid.h \
+ ${PATH_ROOT}/include/iprt/x86.h=>include/iprt/x86.h \
${PATH_ROOT}/include/iprt/nocrt/limits.h=>include/iprt/nocrt/limits.h \
${PATH_ROOT}/include/VBox/cdefs.h=>include/VBox/cdefs.h \
${PATH_ROOT}/include/VBox/err.h=>include/VBox/err.h \
@@ -73,7 +74,6 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/include/VBox/SUPDrvMangling.h=>include/VBox/SUPDrvMangling.h \
${PATH_ROOT}/include/VBox/vmm/hwacc_vmx.h=>include/VBox/vmm/hwacc_vmx.h \
${PATH_ROOT}/include/VBox/vmm/hwacc_svm.h=>include/VBox/vmm/hwacc_svm.h \
- ${PATH_ROOT}/include/VBox/x86.h=>include/VBox/x86.h \
${PATH_ROOT}/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c=>linux/SUPDrv-linux.c \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrv.c=>SUPDrv.c \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrvSem.c=>SUPDrvSem.c \
@@ -110,12 +110,20 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/common/misc/handletable.cpp=>common/misc/handletable.c \
${PATH_ROOT}/src/VBox/Runtime/common/misc/handletable.h=>common/misc/handletable.h \
${PATH_ROOT}/src/VBox/Runtime/common/misc/handletablectx.cpp=>common/misc/handletablectx.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/misc/thread.cpp=>common/misc/thread.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyP.cpp=>common/string/RTStrCopyP.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/strformat.cpp=>common/string/strformat.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/strformatrt.cpp=>common/string/strformatrt.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/strformattype.cpp=>common/string/strformattype.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf.cpp=>common/string/strprintf.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/strtonum.cpp=>common/string/strtonum.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avlpv.cpp=>common/table/avlpv.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_Base.cpp.h=>common/table/avl_Base.cpp.h \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_Get.cpp.h=>common/table/avl_Get.cpp.h \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_GetBestFit.cpp.h=>common/table/avl_GetBestFit.cpp.h \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_RemoveBestFit.cpp.h=>common/table/avl_RemoveBestFit.cpp.h \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_DoWithAll.cpp.h=>common/table/avl_DoWithAll.cpp.h \
+ ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_Destroy.cpp.h=>common/table/avl_Destroy.cpp.h \
${PATH_ROOT}/src/VBox/Runtime/common/time/time.cpp=>common/time/time.c \
${PATH_ROOT}/src/VBox/Runtime/include/internal/assert.h=>include/internal/assert.h \
${PATH_ROOT}/src/VBox/Runtime/include/internal/initterm.h=>include/internal/initterm.h \
@@ -124,6 +132,8 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/include/internal/magics.h=>include/internal/magics.h \
${PATH_ROOT}/src/VBox/Runtime/include/internal/memobj.h=>include/internal/memobj.h \
${PATH_ROOT}/src/VBox/Runtime/include/internal/string.h=>include/internal/string.h \
+ ${PATH_ROOT}/src/VBox/Runtime/include/internal/sched.h=>include/internal/sched.h \
+ ${PATH_ROOT}/src/VBox/Runtime/include/internal/process.h=>include/internal/process.h \
${PATH_ROOT}/src/VBox/Runtime/include/internal/thread.h=>include/internal/thread.h \
${PATH_ROOT}/src/VBox/Runtime/include/internal/time.h=>include/internal/time.h \
${PATH_ROOT}/src/VBox/Runtime/generic/RTAssertShouldPanic-generic.cpp=>generic/RTAssertShouldPanic-generic.c \
@@ -136,6 +146,7 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp=>generic/RTSemEventMultiWait-2-ex-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventMultiWaitNoResume-2-ex-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTTimerCreate-generic.cpp=>generic/RTTimerCreate-generic.c \
+ ${PATH_ROOT}/src/VBox/Runtime/generic/errvars-generic.cpp=>generic/errvars-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/mppresent-generic.cpp=>generic/mppresent-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/uuid-generic.cpp=>generic/uuid-generic.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.cpp=>r0drv/alloc-r0drv.c \
diff --git a/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp b/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp
index eea542845..de1671e29 100644
--- a/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp
+++ b/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPDrv-os2.cpp $ */
+/* $Id: SUPDrv-os2.cpp 37249 2011-05-30 10:03:45Z vboxsync $ */
/** @file
* VBoxDrv - The VirtualBox Support Driver - OS/2 specifics.
*/
@@ -396,9 +396,9 @@ int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAG
}
-int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits)
+int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
{
- NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits);
+ NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits); NOREF(pReq);
return VERR_NOT_SUPPORTED;
}
diff --git a/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.def b/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.def
index 420bfd619..51d2899d8 100644
--- a/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.def
+++ b/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.def
@@ -1,4 +1,4 @@
-; $Id: SUPDrv-os2.def $
+; $Id: SUPDrv-os2.def 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VBoxDrv - OS/2 definition file.
;
diff --git a/src/VBox/HostDrivers/Support/os2/SUPDrvA-os2.asm b/src/VBox/HostDrivers/Support/os2/SUPDrvA-os2.asm
index 5992ecd16..280470cc4 100644
--- a/src/VBox/HostDrivers/Support/os2/SUPDrvA-os2.asm
+++ b/src/VBox/HostDrivers/Support/os2/SUPDrvA-os2.asm
@@ -1,4 +1,4 @@
-; $Id: SUPDrvA-os2.asm $
+; $Id: SUPDrvA-os2.asm 22077 2009-08-07 16:01:57Z vboxsync $
;; @file
; VBoxDrv - OS/2 assembly file, the first file in the link.
;
diff --git a/src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp b/src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp
index 67cc79648..0f72caad2 100644
--- a/src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp
+++ b/src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPLib-os2.cpp $ */
+/* $Id: SUPLib-os2.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VirtualBox Support Library - OS/2 specific parts.
*/
@@ -99,7 +99,7 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
return vrc;
}
- pThis->hDevice = (RTFILE)hDevice;
+ pThis->hDevice = hDevice;
return VINF_SUCCESS;
}
@@ -111,11 +111,11 @@ int suplibOsTerm(PSUPLIBDATA pThis)
/*
* Check if we're inited at all.
*/
- if (pThis->hDevice != NIL_RTFILE)
+ if (pThis->hDevice != (intptr_t)NIL_RTFILE)
{
APIRET rc = DosClose((HFILE)pThis->hDevice);
AssertMsg(rc == NO_ERROR, ("%d\n", rc)); NOREF(rc);
- pThis->hDevice = NIL_RTFILE;
+ pThis->hDevice = (intptr_t)NIL_RTFILE;
}
return 0;
diff --git a/src/VBox/HostDrivers/Support/os2/SUPR0IdcClient-os2.c b/src/VBox/HostDrivers/Support/os2/SUPR0IdcClient-os2.c
index a20af4603..5455545bf 100644
--- a/src/VBox/HostDrivers/Support/os2/SUPR0IdcClient-os2.c
+++ b/src/VBox/HostDrivers/Support/os2/SUPR0IdcClient-os2.c
@@ -1,4 +1,4 @@
-/* $Id: SUPR0IdcClient-os2.c $ */
+/* $Id: SUPR0IdcClient-os2.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VirtualBox Support Driver - IDC Client Lib, OS/2 Specific Code.
*/
diff --git a/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c b/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
index e8ba15a66..6e8b6c385 100644
--- a/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
+++ b/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: SUPDrv-solaris.c $ */
+/* $Id: SUPDrv-solaris.c 37280 2011-05-31 21:31:19Z vboxsync $ */
/** @file
* VBoxDrv - The VirtualBox Support Driver - Solaris specifics.
*/
@@ -34,6 +34,8 @@
#include <sys/uio.h>
#include <sys/buf.h>
#include <sys/modctl.h>
+#include <sys/kobj.h>
+#include <sys/kobj_impl.h>
#include <sys/open.h>
#include <sys/conf.h>
#include <sys/cmn_err.h>
@@ -50,6 +52,7 @@
#include <iprt/semaphore.h>
#include <iprt/spinlock.h>
#include <iprt/mp.h>
+#include <iprt/path.h>
#include <iprt/power.h>
#include <iprt/process.h>
#include <iprt/thread.h>
@@ -180,7 +183,7 @@ static PSUPDRVSESSION g_apSessionHashTab[19];
/** Spinlock protecting g_apSessionHashTab. */
static RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
/** Calculates bucket index into g_apSessionHashTab.*/
-#define SESSION_HASH(sfn) ((sfn) % RT_ELEMENTS(g_apSessionHashTab))
+#define SESSION_HASH(sfn) ((sfn) % RT_ELEMENTS(g_apSessionHashTab))
/**
* Kernel entry points
@@ -892,11 +895,232 @@ bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt)
return false;
}
+#if defined(VBOX_WITH_NATIVE_SOLARIS_LOADING) \
+ && !defined(VBOX_WITHOUT_NATIVE_R0_LOADER)
+
+int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
+{
+ pImage->idSolMod = -1;
+ pImage->pSolModCtl = NULL;
+
+# if 1 /* This approach requires _init/_fini/_info stubs. */
+ /*
+ * Construct a filename that escapes the module search path and let us
+ * specify a root path.
+ */
+ /** @todo change this to use modctl and use_path=0. */
+ const char *pszName = RTPathFilename(pszFilename);
+ AssertReturn(pszName, VERR_INVALID_PARAMETER);
+ char *pszSubDir = RTStrAPrintf2("../../../../../../../../../../..%.*s", pszName - pszFilename - 1, pszFilename);
+ if (!pszSubDir)
+ return VERR_NO_STR_MEMORY;
+ int idMod = modload(pszSubDir, pszName);
+ if (idMod == -1)
+ {
+ /* This is an horrible hack for avoiding the mod-present check in
+ modrload on S10. Fortunately, nobody else seems to be using that
+ variable... */
+ extern int swaploaded;
+ int saved_swaploaded = swaploaded;
+ swaploaded = 0;
+ idMod = modload(pszSubDir, pszName);
+ swaploaded = saved_swaploaded;
+ }
+ RTStrFree(pszSubDir);
+ if (idMod == -1)
+ {
+ LogRel(("modload(,%s): failed, could be anything...\n", pszFilename));
+ return VERR_LDR_GENERAL_FAILURE;
+ }
+
+ modctl_t *pModCtl = mod_hold_by_id(idMod);
+ if (!pModCtl)
+ {
+ LogRel(("mod_hold_by_id(,%s): failed, weird.\n", pszFilename));
+ /* No point in calling modunload. */
+ return VERR_LDR_GENERAL_FAILURE;
+ }
+ pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD | MOD_NOUNLOAD; /* paranoia */
+
+# else
+
+ const int idMod = -1;
+ modctl_t *pModCtl = mod_hold_by_name(pszFilename);
+ if (!pModCtl)
+ {
+ LogRel(("mod_hold_by_name failed for '%s'\n", pszFilename));
+ return VERR_LDR_GENERAL_FAILURE;
+ }
+
+ int rc = kobj_load_module(pModCtl, 0 /*use_path*/);
+ if (rc != 0)
+ {
+ LogRel(("kobj_load_module failed with rc=%d for '%s'\n", rc, pszFilename));
+ mod_release_mod(pModCtl);
+ return RTErrConvertFromErrno(rc);
+ }
+# endif
+
+ /*
+ * Get the module info.
+ *
+ * Note! The text section is actually not at mi_base, but and the next
+ * alignment boundrary and there seems to be no easy way of
+ * getting at this address. This sabotages supdrvOSLdrLoad.
+ * Bastards!
+ */
+ struct modinfo ModInfo;
+ kobj_getmodinfo(pModCtl->mod_mp, &ModInfo);
+ pImage->pvImage = ModInfo.mi_base;
+ pImage->idSolMod = idMod;
+ pImage->pSolModCtl = pModCtl;
+
+ mod_release_mod(pImage->pSolModCtl);
+ LogRel(("supdrvOSLdrOpen: succeeded for '%s' (mi_base=%p mi_size=%#x), id=%d ctl=%p\n",
+ pszFilename, ModInfo.mi_base, ModInfo.mi_size, idMod, pModCtl));
+ return VINF_SUCCESS;
+}
+
+
+int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
+{
+ NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits);
+ if (kobj_addrcheck(pImage->pSolModCtl->mod_mp, pv))
+ return VERR_INVALID_PARAMETER;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Resolves a module entry point address.
+ *
+ * @returns VBox status code.
+ * @param pImage The image.
+ * @param pszSymbol The symbol name.
+ * @param ppvValue Where to store the value. On input this holds
+ * the symbol value SUPLib calculated.
+ */
+static int supdrvSolLdrResolvEp(PSUPDRVLDRIMAGE pImage, const char *pszSymbol, void **ppvValue)
+{
+ /* Don't try resolve symbols which, according to SUPLib, aren't there. */
+ if (!*ppvValue)
+ return VINF_SUCCESS;
+
+ uintptr_t uValue = modlookup_by_modctl(pImage->pSolModCtl, pszSymbol);
+ if (!uValue)
+ {
+ LogRel(("supdrvOSLdrLoad on %s failed to resolve %s\n", pImage->szName, pszSymbol));
+ return VERR_SYMBOL_NOT_FOUND;
+ }
+ *ppvValue = (void *)uValue;
+ return VINF_SUCCESS;
+}
+
+
+int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
+{
+#if 0 /* This doesn't work because of text alignment. */
+ /*
+ * Comparing is very very difficult since text and data may be allocated
+ * separately.
+ */
+ size_t cbCompare = RT_MIN(pImage->cbImageBits, 64);
+ if (memcmp(pImage->pvImage, pbImageBits, cbCompare))
+ {
+ LogRel(("Image mismatch: %s (%p)\n", pImage->szName, pImage->pvImage));
+ LogRel(("Native: %.*Rhxs\n", cbCompare, pImage->pvImage));
+ LogRel(("SUPLib: %.*Rhxs\n", cbCompare, pbImageBits));
+ return VERR_LDR_MISMATCH_NATIVE;
+ }
+#endif
+
+ /*
+ * Get the exported symbol addresses.
+ */
+ int rc;
+ modctl_t *pModCtl = mod_hold_by_id(pImage->idSolMod);
+ if (pModCtl && pModCtl == pImage->pSolModCtl)
+ {
+ uint32_t iSym = pImage->cSymbols;
+ while (iSym-- > 0)
+ {
+ const char *pszSymbol = &pImage->pachStrTab[pImage->paSymbols[iSym].offName];
+ uintptr_t uValue = modlookup_by_modctl(pImage->pSolModCtl, pszSymbol);
+ if (!uValue)
+ {
+ LogRel(("supdrvOSLdrLoad on %s failed to resolve the exported symbol: '%s'\n", pImage->szName, pszSymbol));
+ break;
+ }
+ uintptr_t offSymbol = uValue - (uintptr_t)pImage->pvImage;
+ pImage->paSymbols[iSym].offSymbol = offSymbol;
+ if (pImage->paSymbols[iSym].offSymbol != (int32_t)offSymbol)
+ {
+ LogRel(("supdrvOSLdrLoad on %s symbol out of range: %p (%s) \n", pImage->szName, offSymbol, pszSymbol));
+ break;
+ }
+ }
+
+ rc = iSym == UINT32_MAX ? VINF_SUCCESS : VERR_LDR_GENERAL_FAILURE;
+
+ /*
+ * Get the standard module entry points.
+ */
+ if (RT_SUCCESS(rc))
+ {
+ rc = supdrvSolLdrResolvEp(pImage, "ModuleInit", (void **)&pImage->pfnModuleInit);
+ if (RT_SUCCESS(rc))
+ rc = supdrvSolLdrResolvEp(pImage, "ModuleTerm", (void **)&pImage->pfnModuleTerm);
+
+ switch (pReq->u.In.eEPType)
+ {
+ case SUPLDRLOADEP_VMMR0:
+ {
+ if (RT_SUCCESS(rc))
+ rc = supdrvSolLdrResolvEp(pImage, "VMMR0EntryInt", (void **)&pReq->u.In.EP.VMMR0.pvVMMR0EntryInt);
+ if (RT_SUCCESS(rc))
+ rc = supdrvSolLdrResolvEp(pImage, "VMMR0EntryFast", (void **)&pReq->u.In.EP.VMMR0.pvVMMR0EntryFast);
+ if (RT_SUCCESS(rc))
+ rc = supdrvSolLdrResolvEp(pImage, "VMMR0EntryEx", (void **)&pReq->u.In.EP.VMMR0.pvVMMR0EntryEx);
+ break;
+ }
+
+ case SUPLDRLOADEP_SERVICE:
+ {
+ /** @todo we need the name of the entry point. */
+ return VERR_NOT_SUPPORTED;
+ }
+ }
+ }
+
+ mod_release_mod(pImage->pSolModCtl);
+ }
+ else
+ {
+ LogRel(("mod_hold_by_id failed in supdrvOSLdrLoad on %s: %p\n", pImage->szName, pModCtl));
+ rc = VERR_LDR_MISMATCH_NATIVE;
+ }
+ return rc;
+}
+
+
+void VBOXCALL supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
+{
+# if 1
+ pImage->pSolModCtl->mod_loadflags &= ~MOD_NOUNLOAD;
+ int rc = modunload(pImage->idSolMod);
+ if (rc)
+ LogRel(("modunload(%u (%s)) failed: %d\n", pImage->idSolMod, pImage->szName, rc));
+# else
+ kobj_unload_module(pImage->pSolModCtl);
+# endif
+ pImage->pSolModCtl = NULL;
+ pImage->idSolMod = NULL;
+}
+
+#else /* !VBOX_WITH_NATIVE_SOLARIS_LOADING */
int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
{
- /** @todo This is something that shouldn't be impossible to implement
- * here and would make a few people happy. */
NOREF(pDevExt); NOREF(pImage); NOREF(pszFilename);
return VERR_NOT_SUPPORTED;
}
@@ -909,9 +1133,9 @@ int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAG
}
-int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits)
+int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
{
- NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits);
+ NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits); NOREF(pReq);
return VERR_NOT_SUPPORTED;
}
@@ -921,6 +1145,8 @@ void VBOXCALL supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
NOREF(pDevExt); NOREF(pImage);
}
+#endif /* !VBOX_WITH_NATIVE_SOLARIS_LOADING */
+
RTDECL(int) SUPR0Printf(const char *pszFormat, ...)
{
diff --git a/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp b/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp
index db3b55cc7..ef294df06 100644
--- a/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp
+++ b/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPLib-solaris.cpp $ */
+/* $Id: SUPLib-solaris.cpp 37611 2011-06-23 12:32:04Z vboxsync $ */
/** @file
* VirtualBox Support Library - Solaris specific parts.
*/
@@ -157,11 +157,11 @@ int suplibOsTerm(PSUPLIBDATA pThis)
/*
* Check if we're initialized
*/
- if (pThis->hDevice != NIL_RTFILE)
+ if (pThis->hDevice != (intptr_t)NIL_RTFILE)
{
if (close(pThis->hDevice))
AssertFailed();
- pThis->hDevice = NIL_RTFILE;
+ pThis->hDevice = (intptr_t)NIL_RTFILE;
}
return VINF_SUCCESS;
diff --git a/src/VBox/HostDrivers/Support/solaris/SUPR0IdcClient-solaris.c b/src/VBox/HostDrivers/Support/solaris/SUPR0IdcClient-solaris.c
index 033fcdec5..5b33761d7 100644
--- a/src/VBox/HostDrivers/Support/solaris/SUPR0IdcClient-solaris.c
+++ b/src/VBox/HostDrivers/Support/solaris/SUPR0IdcClient-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: SUPR0IdcClient-solaris.c $ */
+/* $Id: SUPR0IdcClient-solaris.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VirtualBox Support Driver - IDC Client Lib, Solaris Specific Code.
*/
diff --git a/src/VBox/HostDrivers/Support/solaris/mod.sh b/src/VBox/HostDrivers/Support/solaris/mod.sh
index 89069fec5..5ebb39f2c 100755
--- a/src/VBox/HostDrivers/Support/solaris/mod.sh
+++ b/src/VBox/HostDrivers/Support/solaris/mod.sh
@@ -1,11 +1,11 @@
#!/bin/sh
-# $Id: mod.sh $
+# $Id: mod.sh 37314 2011-06-03 09:23:02Z vboxsync $
## @file
# Helper script for installing the solaris module in a development environment.
#
#
-# Copyright (C) 2006-2009 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;
@@ -70,7 +70,6 @@ old_id=`/usr/sbin/modinfo | /usr/xpg4/bin/grep vbox | grep -v vboxguest | grep -
if test -n "$old_id"; then
echo "* unloading $old_id..."
sync
- sync
$SUDO /usr/sbin/modunload -i $old_id
#else
# echo "* If it fails below, run: $SUDO add_drv -m'* 0666 root sys' vboxdrv"
@@ -91,7 +90,6 @@ fi
echo "* loading vboxdrv..."
sync
-sync
$SUDO /usr/sbin/modload $VBOXDRV_DIR/vboxdrv
/usr/sbin/modinfo | /usr/xpg4/bin/grep vboxdrv
echo "* dmesg:"
diff --git a/src/VBox/HostDrivers/Support/testcase/Makefile.kmk b/src/VBox/HostDrivers/Support/testcase/Makefile.kmk
index 5ec98e0df..f66e4ce08 100644
--- a/src/VBox/HostDrivers/Support/testcase/Makefile.kmk
+++ b/src/VBox/HostDrivers/Support/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the SUPLib testcases.
#
diff --git a/src/VBox/HostDrivers/Support/testcase/SUPInstall.cpp b/src/VBox/HostDrivers/Support/testcase/SUPInstall.cpp
index 58b3f749b..9b9988c20 100644
--- a/src/VBox/HostDrivers/Support/testcase/SUPInstall.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/SUPInstall.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPInstall.cpp $ */
+/* $Id: SUPInstall.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* SUPInstall - Driver Install
*/
diff --git a/src/VBox/HostDrivers/Support/testcase/SUPLoggerCtl.cpp b/src/VBox/HostDrivers/Support/testcase/SUPLoggerCtl.cpp
index 162ae9c06..72e24b0a4 100644
--- a/src/VBox/HostDrivers/Support/testcase/SUPLoggerCtl.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/SUPLoggerCtl.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPLoggerCtl.cpp $ */
+/* $Id: SUPLoggerCtl.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* SUPLoggerCtl - Support Driver Logger Control.
*/
diff --git a/src/VBox/HostDrivers/Support/testcase/SUPUninstall.cpp b/src/VBox/HostDrivers/Support/testcase/SUPUninstall.cpp
index 44d7d3db8..d1f7d8dd2 100644
--- a/src/VBox/HostDrivers/Support/testcase/SUPUninstall.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/SUPUninstall.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPUninstall.cpp $ */
+/* $Id: SUPUninstall.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* SUPUninstall - Driver Uninstall.
*/
diff --git a/src/VBox/HostDrivers/Support/testcase/tstContiguous.cpp b/src/VBox/HostDrivers/Support/testcase/tstContiguous.cpp
index 328857885..7496dc2e3 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstContiguous.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstContiguous.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstContiguous.cpp $ */
+/* $Id: tstContiguous.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* SUP Testcase - Contiguous Memory Interface (ring-3).
*/
diff --git a/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp b/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp
index 2039292a6..e198185dd 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstGIP-2.cpp $ */
+/* $Id: tstGIP-2.cpp 33595 2010-10-29 10:35:00Z vboxsync $ */
/** @file
* SUP Testcase - Global Info Page interface (ring 3).
*/
diff --git a/src/VBox/HostDrivers/Support/testcase/tstGetPagingMode.cpp b/src/VBox/HostDrivers/Support/testcase/tstGetPagingMode.cpp
index 1368f0ceb..c48a4fe6c 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstGetPagingMode.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstGetPagingMode.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstGetPagingMode.cpp $ */
+/* $Id: tstGetPagingMode.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* SUP Testcase - Host paging mode interface (ring 3).
*/
diff --git a/src/VBox/HostDrivers/Support/testcase/tstInit.cpp b/src/VBox/HostDrivers/Support/testcase/tstInit.cpp
index 8c46e1adc..81290ec5e 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstInit.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstInit.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstInit.cpp $ */
+/* $Id: tstInit.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* SUP Testcase - Support Library initialization and termination.
*/
diff --git a/src/VBox/HostDrivers/Support/testcase/tstInt.cpp b/src/VBox/HostDrivers/Support/testcase/tstInt.cpp
index d853cc4ae..349bf00ee 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstInt.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstInt.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstInt.cpp $ */
+/* $Id: tstInt.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* SUP Testcase - Test the interrupt gate feature of the support library.
*/
diff --git a/src/VBox/HostDrivers/Support/testcase/tstLow.cpp b/src/VBox/HostDrivers/Support/testcase/tstLow.cpp
index 553c4711a..4983f98d0 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstLow.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstLow.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstLow.cpp $ */
+/* $Id: tstLow.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* SUP Testcase - Low (<4GB) Memory Allocate interface (ring 3).
*/
diff --git a/src/VBox/HostDrivers/Support/testcase/tstPage.cpp b/src/VBox/HostDrivers/Support/testcase/tstPage.cpp
index bcb550312..286679c03 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstPage.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstPage.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstPage.cpp $ */
+/* $Id: tstPage.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* SUP Testcase - Page allocation interface (ring 3).
*/
diff --git a/src/VBox/HostDrivers/Support/testcase/tstPin.cpp b/src/VBox/HostDrivers/Support/testcase/tstPin.cpp
index ff6a36dfd..da4096ae0 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstPin.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstPin.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstPin.cpp $ */
+/* $Id: tstPin.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* SUP Testcase - Memory locking interface (ring 3).
*/
diff --git a/src/VBox/HostDrivers/Support/testcase/tstSupLoadModule.cpp b/src/VBox/HostDrivers/Support/testcase/tstSupLoadModule.cpp
index cbe204ffb..27d748867 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstSupLoadModule.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstSupLoadModule.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstSupLoadModule.cpp $ */
+/* $Id: tstSupLoadModule.cpp 35188 2010-12-16 15:13:07Z vboxsync $ */
/** @file
* SUP Testcase - Test SUPR3LoadModule.
*/
@@ -94,7 +94,7 @@ int main(int argc, char **argv)
return 1;
case 'V':
- RTPrintf("$Revision: 69027 $\n");
+ RTPrintf("$Revision: 35188 $\n");
return 0;
default:
diff --git a/src/VBox/HostDrivers/Support/testcase/tstSupSem-Zombie.cpp b/src/VBox/HostDrivers/Support/testcase/tstSupSem-Zombie.cpp
index 844446428..6954c1b17 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstSupSem-Zombie.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstSupSem-Zombie.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstSupSem-Zombie.cpp $ */
+/* $Id: tstSupSem-Zombie.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Support Library Testcase - Ring-3 Semaphore interface - Zombie bugs.
*/
diff --git a/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp b/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp
index 14ee9ef59..81ebf1fa9 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstSupSem.cpp $ */
+/* $Id: tstSupSem.cpp 33383 2010-10-24 14:33:13Z vboxsync $ */
/** @file
* Support Library Testcase - Ring-3 Semaphore interface.
*/
diff --git a/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp b/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
index cfa7c4c89..5df1502ea 100644
--- a/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
+++ b/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPDrv-win.cpp $ */
+/* $Id: SUPDrv-win.cpp 37249 2011-05-30 10:03:45Z vboxsync $ */
/** @file
* VBoxDrv - The VirtualBox Support Driver - Windows NT specifics.
*/
@@ -765,9 +765,9 @@ static int supdrvNtCompare(PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, u
return iDiff;
}
-int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits)
+int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
{
- NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits);
+ NOREF(pDevExt); NOREF(pReq);
if (pImage->pvNtSectionObj)
{
/*
diff --git a/src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm b/src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm
index f7d5e9539..ff2cb4d59 100644
--- a/src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm
+++ b/src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm
@@ -1,4 +1,4 @@
-; $Id: SUPDrvA-win.asm $
+; $Id: SUPDrvA-win.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VirtualBox Support Driver - Windows NT specific assembly parts.
;
diff --git a/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp b/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp
index ea60a475e..789641768 100644
--- a/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp
+++ b/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPLib-win.cpp $ */
+/* $Id: SUPLib-win.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VirtualBox Support Library - Windows NT specific parts.
*/
@@ -138,7 +138,7 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
/*
* We're done.
*/
- pThis->hDevice = (RTFILE)hDevice;
+ pThis->hDevice = hDevice;
return VINF_SUCCESS;
}
@@ -474,11 +474,11 @@ int suplibOsTerm(PSUPLIBDATA pThis)
/*
* Check if we're inited at all.
*/
- if (pThis->hDevice != NIL_RTFILE)
+ if (pThis->hDevice != NULL)
{
if (!CloseHandle((HANDLE)pThis->hDevice))
AssertFailed();
- pThis->hDevice = NIL_RTFILE;
+ pThis->hDevice = NIL_RTFILE; /* yes, that's right */
}
return VINF_SUCCESS;
diff --git a/src/VBox/HostDrivers/Support/win/SUPR0IdcClient-win.c b/src/VBox/HostDrivers/Support/win/SUPR0IdcClient-win.c
index 01416ab92..099978a10 100644
--- a/src/VBox/HostDrivers/Support/win/SUPR0IdcClient-win.c
+++ b/src/VBox/HostDrivers/Support/win/SUPR0IdcClient-win.c
@@ -1,4 +1,4 @@
-/* $Id: SUPR0IdcClient-win.c $ */
+/* $Id: SUPR0IdcClient-win.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VirtualBox Support Driver - IDC Client Lib, Windows Specific Code.
*/
diff --git a/src/VBox/HostDrivers/Support/win/SUPSvc-win.cpp b/src/VBox/HostDrivers/Support/win/SUPSvc-win.cpp
index 19245e5f8..bb1cd7371 100644
--- a/src/VBox/HostDrivers/Support/win/SUPSvc-win.cpp
+++ b/src/VBox/HostDrivers/Support/win/SUPSvc-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: SUPSvc-win.cpp $ */
+/* $Id: SUPSvc-win.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VirtualBox Support Service - Windows Specific Code.
*/
diff --git a/src/VBox/HostDrivers/Support/win/VBoxDrv.inf b/src/VBox/HostDrivers/Support/win/VBoxDrv.inf
index 4a5b8661d..37a453a9f 100644
--- a/src/VBox/HostDrivers/Support/win/VBoxDrv.inf
+++ b/src/VBox/HostDrivers/Support/win/VBoxDrv.inf
@@ -1,4 +1,4 @@
-; $Id: VBoxDrv.inf $
+; $Id: VBoxDrv.inf 32408 2010-09-10 13:43:23Z vboxsync $
;; @file
; VirtualBox Support Driver - Windows Driver INF file.
;
diff --git a/src/VBox/HostDrivers/Support/win/VBoxDrv.rc b/src/VBox/HostDrivers/Support/win/VBoxDrv.rc
index 15c34900b..716936107 100644
--- a/src/VBox/HostDrivers/Support/win/VBoxDrv.rc
+++ b/src/VBox/HostDrivers/Support/win/VBoxDrv.rc
@@ -1,4 +1,4 @@
-/* $Id: VBoxDrv.rc $ */
+/* $Id: VBoxDrv.rc 32394 2010-09-10 12:13:11Z vboxsync $ */
/** @file
* VirtualBox Support Driver - Windows Resource File.
*/
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/Makefile.kmk b/src/VBox/HostDrivers/VBoxNetAdp/Makefile.kmk
index f6f6ec4eb..a6c1f18a8 100644
--- a/src/VBox/HostDrivers/VBoxNetAdp/Makefile.kmk
+++ b/src/VBox/HostDrivers/VBoxNetAdp/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Sub-Makefile for the Network Adapter Driver (VBoxNetAdp).
#
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdp.c b/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdp.c
index 228098725..818a3c672 100644
--- a/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdp.c
+++ b/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdp.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetAdp.c $ */
+/* $Id: VBoxNetAdp.c 36951 2011-05-04 07:07:34Z vboxsync $ */
/** @file
* VBoxNetAdp - Virtual Network Adapter Driver (Host), Common Code.
*/
@@ -1189,7 +1189,6 @@ int vboxNetAdpDestroy(PVBOXNETADP pThis)
int vboxNetAdpInit(void)
{
unsigned i;
- PVBOXNETADP pVboxnet0;
/*
* Init common members and call OS-specific init.
*/
@@ -1202,8 +1201,7 @@ int vboxNetAdpInit(void)
vboxNetAdpOsInit(&g_aAdapters[i]);
}
- /* Create vboxnet0 */
- return vboxNetAdpCreate(&pVboxnet0, NULL);
+ return VINF_SUCCESS;
}
/**
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h b/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h
index 2ef9a0764..1382ce1c3 100644
--- a/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h
+++ b/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetAdpInternal.h $ */
+/* $Id: VBoxNetAdpInternal.h 35824 2011-02-02 13:32:03Z vboxsync $ */
/** @file
* VBoxNetAdp - Network Filter Driver (Host), Internal Header.
*/
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/darwin/VBoxNetAdp-darwin.cpp b/src/VBox/HostDrivers/VBoxNetAdp/darwin/VBoxNetAdp-darwin.cpp
index e2c554eae..87431773c 100644
--- a/src/VBox/HostDrivers/VBoxNetAdp/darwin/VBoxNetAdp-darwin.cpp
+++ b/src/VBox/HostDrivers/VBoxNetAdp/darwin/VBoxNetAdp-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetAdp-darwin.cpp $ */
+/* $Id: VBoxNetAdp-darwin.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
* VBoxNetAdp - Virtual Network Adapter Driver (Host), Darwin Specific Code.
*/
@@ -192,6 +192,7 @@ static void vboxNetAdpDarwinDetach(ifnet_t pIface)
}
+
int vboxNetAdpOsCreate(PVBOXNETADP pThis, PCRTMAC pMACAddress)
{
int rc;
@@ -352,7 +353,7 @@ static int VBoxNetAdpDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFla
PVBOXNETADP pNew;
Log(("VBoxNetAdpDarwinIOCtl: szName=%s\n", pReq->szName));
- rc = vboxNetAdpCreate(&pNew,
+ rc = vboxNetAdpCreate(&pNew,
pReq->szName[0] && RTStrEnd(pReq->szName, RT_MIN(cbReq, sizeof(pReq->szName))) ?
pReq->szName : NULL);
if (RT_FAILURE(rc))
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/freebsd/Makefile b/src/VBox/HostDrivers/VBoxNetAdp/freebsd/Makefile
index c432b4687..ae66f4e1b 100644
--- a/src/VBox/HostDrivers/VBoxNetAdp/freebsd/Makefile
+++ b/src/VBox/HostDrivers/VBoxNetAdp/freebsd/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile $
+# $Id: Makefile 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Makefile for the VirtualBox FreeBSD Host Driver.
#
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c b/src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c
index 4dc591465..0654315fc 100644
--- a/src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c
+++ b/src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetAdp-freebsd.c $ */
+/* $Id: VBoxNetAdp-freebsd.c 35950 2011-02-14 07:46:18Z vboxsync $ */
/** @file
* VBoxNetAdp - Virtual Network Adapter Driver (Host), FreeBSD Specific Code.
*/
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/freebsd/files_vboxnetadp b/src/VBox/HostDrivers/VBoxNetAdp/freebsd/files_vboxnetadp
index 6f4bc31d2..691b305fa 100755..100644
--- a/src/VBox/HostDrivers/VBoxNetAdp/freebsd/files_vboxnetadp
+++ b/src/VBox/HostDrivers/VBoxNetAdp/freebsd/files_vboxnetadp
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: files_vboxnetadp $
+# $Id: files_vboxnetadp 36190 2011-03-07 16:28:50Z vboxsync $
## @file
# Shared file between Makefile.kmk and export_modules
#
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/linux/VBoxNetAdp-linux.c b/src/VBox/HostDrivers/VBoxNetAdp/linux/VBoxNetAdp-linux.c
index 0b297da85..8ea781efe 100644
--- a/src/VBox/HostDrivers/VBoxNetAdp/linux/VBoxNetAdp-linux.c
+++ b/src/VBox/HostDrivers/VBoxNetAdp/linux/VBoxNetAdp-linux.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetAdp-linux.c $ */
+/* $Id: VBoxNetAdp-linux.c 35809 2011-02-01 12:31:15Z vboxsync $ */
/** @file
* VBoxNetAdp - Virtual Network Adapter Driver (Host), Linux Specific Code.
*/
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/linux/files_vboxnetadp b/src/VBox/HostDrivers/VBoxNetAdp/linux/files_vboxnetadp
index ab7c5c5d4..64e8dea0b 100755..100644
--- a/src/VBox/HostDrivers/VBoxNetAdp/linux/files_vboxnetadp
+++ b/src/VBox/HostDrivers/VBoxNetAdp/linux/files_vboxnetadp
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Revision: 70408 $
+# $Revision: 37964 $
## @files
# Shared file between Makefile.kmk and export_modules
#
@@ -50,6 +50,7 @@ VBOX_VBOXNETADP_SOURCES=" \
${PATH_ROOT}/include/iprt/types.h=>include/iprt/types.h \
${PATH_ROOT}/include/iprt/uni.h=>include/iprt/uni.h \
${PATH_ROOT}/include/iprt/uuid.h=>include/iprt/uuid.h \
+ ${PATH_ROOT}/include/iprt/x86.h=>include/iprt/x86.h \
${PATH_ROOT}/include/iprt/nocrt/limits.h=>include/iprt/nocrt/limits.h \
${PATH_ROOT}/include/VBox/cdefs.h=>include/VBox/cdefs.h \
${PATH_ROOT}/include/VBox/err.h=>include/VBox/err.h \
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/solaris/VBoxNetAdp-solaris.c b/src/VBox/HostDrivers/VBoxNetAdp/solaris/VBoxNetAdp-solaris.c
index 44aaff152..8d85e4011 100644
--- a/src/VBox/HostDrivers/VBoxNetAdp/solaris/VBoxNetAdp-solaris.c
+++ b/src/VBox/HostDrivers/VBoxNetAdp/solaris/VBoxNetAdp-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetAdp-solaris.c $ */
+/* $Id: VBoxNetAdp-solaris.c 37786 2011-07-05 14:16:15Z vboxsync $ */
/** @file
* VBoxNetAdapter - Network Adapter Driver (Host), Solaris Specific Code.
*/
@@ -207,6 +207,7 @@ static int vboxNetAdpSolarisSend(gld_mac_info_t *pMacInfo, mblk_t *pMsg);
static int vboxNetAdpSolarisStub(gld_mac_info_t *pMacInfo);
static int vboxNetAdpSolarisSetPromisc(gld_mac_info_t *pMacInfo, int fPromisc);
static int vboxNetAdpSolarisSetMulticast(gld_mac_info_t *pMacInfo, unsigned char *pMulticastAddr, int fMulticast);
+static int vboxNetAdpSolarisGetStats(gld_mac_info_t *pMacInfo, struct gld_stats *pStats);
/**
@@ -305,13 +306,13 @@ static int VBoxNetAdpSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
pMacInfo->gldm_set_promiscuous = vboxNetAdpSolarisSetPromisc;
pMacInfo->gldm_send = vboxNetAdpSolarisSend;
pMacInfo->gldm_intr = NULL;
- pMacInfo->gldm_get_stats = NULL;
+ pMacInfo->gldm_get_stats = vboxNetAdpSolarisGetStats;
pMacInfo->gldm_ioctl = NULL;
pMacInfo->gldm_ident = DEVICE_NAME;
pMacInfo->gldm_type = DL_ETHER;
pMacInfo->gldm_minpkt = 0;
pMacInfo->gldm_maxpkt = VBOXNETADP_MTU;
-
+ pMacInfo->gldm_capabilities = GLD_CAP_LINKSTATE;
AssertCompile(sizeof(RTMAC) == ETHERADDRL);
pMacInfo->gldm_addrlen = ETHERADDRL;
@@ -340,6 +341,7 @@ static int VBoxNetAdpSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
if (rc == DDI_SUCCESS)
{
ddi_report_dev(pDip);
+ gld_linkstate(pMacInfo, GLD_LINKSTATE_UP);
return DDI_SUCCESS;
}
else
@@ -398,6 +400,7 @@ static int VBoxNetAdpSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
vboxnetadp_state_t *pState = (vboxnetadp_state_t *)pMacInfo->gldm_private;
if (pState)
{
+ gld_linkstate(pMacInfo, GLD_LINKSTATE_DOWN);
int rc = gld_unregister(pMacInfo);
if (rc == DDI_SUCCESS)
{
@@ -488,3 +491,55 @@ static int vboxNetAdpSolarisSetPromisc(gld_mac_info_t *pMacInfo, int fPromisc)
return GLD_SUCCESS;
}
+
+static int vboxNetAdpSolarisGetStats(gld_mac_info_t *pMacInfo, struct gld_stats *pStats)
+{
+ /*
+ * For now fake up stats. Stats like duplex and speed are better set as they
+ * are used in utilities like dladm. Link state capabilities are critical
+ * as they are used by ipadm while trying to restore persistent interface configs.
+ */
+ vboxnetadp_state_t *pState = (vboxnetadp_state_t *)pMacInfo->gldm_private;
+ if (pState)
+ {
+ pStats->glds_speed = 1000000000ULL; /* Bits/sec. */
+ pStats->glds_media = GLDM_UNKNOWN; /* Media/Connector Type */
+ pStats->glds_intr = 0; /* Interrupt count */
+ pStats->glds_norcvbuf = 0; /* Recv. discards */
+ pStats->glds_errxmt = 0; /* Xmit errors */
+ pStats->glds_errrcv = 0; /* Recv. errors */
+ pStats->glds_missed = 0; /* Pkt Drops on Recv. */
+ pStats->glds_underflow = 0; /* Buffer underflows */
+ pStats->glds_overflow = 0; /* Buffer overflows */
+
+ /* Ether */
+ pStats->glds_frame = 0; /* Align errors */
+ pStats->glds_crc = 0; /* CRC errors */
+ pStats->glds_duplex = GLD_DUPLEX_FULL; /* Link duplex state */
+ pStats->glds_nocarrier = 0; /* Carrier sense errors */
+ pStats->glds_collisions = 0; /* Xmit Collisions */
+ pStats->glds_excoll = 0; /* Frame discard due to excess collisions */
+ pStats->glds_xmtlatecoll = 0; /* Late collisions */
+ pStats->glds_defer = 0; /* Deferred Xmits */
+ pStats->glds_dot3_first_coll = 0; /* Single collision frames */
+ pStats->glds_dot3_multi_coll = 0; /* Multiple collision frames */
+ pStats->glds_dot3_sqe_error = 0; /* SQE errors */
+ pStats->glds_dot3_mac_xmt_error = 0; /* MAC Xmit errors */
+ pStats->glds_dot3_mac_rcv_error = 0; /* Mac Recv. errors */
+ pStats->glds_dot3_frame_too_long = 0; /* Frame too long errors */
+ pStats->glds_short = 0; /* Runt frames */
+
+ pStats->glds_noxmtbuf = 0; /* Xmit Buf errors */
+ pStats->glds_xmtretry = 0; /* Xmit retries */
+ pStats->glds_multixmt = 0; /* Multicast Xmits */
+ pStats->glds_multircv = 0; /* Multicast Recvs. */
+ pStats->glds_brdcstxmt = 0; /* Broadcast Xmits*/
+ pStats->glds_brdcstrcv = 0; /* Broadcast Recvs. */
+
+ return GLD_SUCCESS;
+ }
+ else
+ LogRel((DEVICE_NAME ":vboxNetAdpSolarisGetStats failed to get internal state.\n"));
+ return GLD_FAILURE;
+}
+
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk b/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk
index 3f85bc6e1..c34e0be66 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk
+++ b/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37982 2011-07-15 14:35:40Z vboxsync $
## @file
# Sub-Makefile for the Network Filter Driver (VBoxNetFlt).
#
@@ -30,25 +30,25 @@ if defined(VBOX_SIGNING_MODE) && "$(KBUILD_TARGET)" == "win"
VBoxNetFlt_NOINST = true
endif
VBoxNetFlt_DEFS = IN_RT_R0 IN_SUP_STATIC
-VBoxNetFlt_SDKS.win = W2K3DDK WINPSDKINCS
VBoxNetFlt_INCS = .
VBoxNetFlt_SOURCES.darwin = \
darwin/VBoxNetFlt-darwin.cpp
#VBoxNetFlt_SOURCES.darwin += \
# darwin/VBoxNetAdapter-darwin.cpp
+VBoxNetFlt_SDKS.win = WINDDKWLH WINPSDKINCS
VBoxNetFlt_SOURCES.win = \
- win/VBoxNetFlt-win.c \
- win/VBoxNetFltPt-win.c \
- win/VBoxNetFlt-win.rc
-ifdef VBOX_NETFLT_ONDEMAND_BIND
- VBoxNetFlt_DEFS.win += VBOX_NETFLT_ONDEMAND_BIND
-else
- VBoxNetFlt_DEFS.win += VBOXNETFLT_STATIC_CONFIG
- VBoxNetFlt_DEFS.win += VBOXNETFLT_NO_PACKET_QUEUE
- VBoxNetFlt_DEFS.win += NDIS_MINIPORT_DRIVER NDIS_WDM=1 BINARY_COMPATIBLE=0
- VBoxNetFlt_DEFS.win += NDIS50_MINIPORT=1 NDIS50=1
- VBoxNetFlt_SOURCES.win += win/VBoxNetFltMp-win.c
-endif
+ win/drv/VBoxNetFltP-win.cpp \
+ win/drv/VBoxNetFltM-win.cpp \
+ win/drv/VBoxNetFltRt-win.cpp \
+ win/drv/VBoxNetFlt-win.rc
+# with WINDDKWLH the WIN9X_COMPAT_SPINLOCK is needed to avoid inline declaration of KeInitializeSpinLock
+# otherwise the linker would complain about dumplicate _KeInitializeSpinLock@4 definition
+# in ntoskrnl.lib and our object files
+VBoxNetFlt_DEFS.win += WIN9X_COMPAT_SPINLOCK=1
+VBoxNetFlt_DEFS.win += VBOXNETFLT_STATIC_CONFIG
+VBoxNetFlt_DEFS.win += VBOXNETFLT_NO_PACKET_QUEUE
+VBoxNetFlt_DEFS.win += NDIS_MINIPORT_DRIVER NDIS_WDM=1 BINARY_COMPATIBLE=0
+VBoxNetFlt_DEFS.win += NDIS50_MINIPORT=1 NDIS50=1
ifdef VBOX_LOOPBACK_USEFLAGS
VBoxNetFlt_DEFS.win += VBOX_LOOPBACK_USEFLAGS
endif
@@ -57,9 +57,9 @@ VBoxNetFlt_SOURCES = VBoxNetFlt.c
VBoxNetFlt_LDFLAGS.win.x86 = -Entry:DriverEntry@8
VBoxNetFlt_LDFLAGS.win.amd64 = -Entry:DriverEntry
VBoxNetFlt_LIBS.win = \
- $(PATH_SDK_W2K3DDK_LIB)/ntoskrnl.lib \
- $(PATH_SDK_W2K3DDK_LIB)/hal.lib \
- $(PATH_SDK_W2K3DDK_LIB)/ndis.lib \
+ $(PATH_SDK_WINDDKWLH_LIB)/ntoskrnl.lib \
+ $(PATH_SDK_WINDDKWLH_LIB)/hal.lib \
+ $(PATH_SDK_WINDDKWLH_LIB)/ndis.lib \
$(PATH_LIB)/RuntimeR0Drv$(VBOX_SUFF_LIB)
VBoxNetFlt_LIBS = \
$(PATH_LIB)/SUPR0IdcClient$(VBOX_SUFF_LIB)
@@ -106,35 +106,35 @@ VBoxNetFlt-inf_INST = $(INST_BIN)
VBoxNetFlt-inf_MODE = a+r,u+w
VBoxNetFlt-inf_SOURCES = \
$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.inf \
- $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt_m.inf
+ $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltM.inf
VBoxNetFlt-inf_CLEAN = $(VBoxNetFlt-inf_SOURCES)
VBoxNetFlt-inf_BLDDIRS = $(PATH_TARGET)/VBoxNetFltCat.dir
-$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.inf: $(PATH_SUB_CURRENT)/win/VBoxNetFlt.inf $(MAKEFILE_CURRENT) | $$(dir $$@)
+$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.inf: $(PATH_SUB_CURRENT)/win/drv/VBoxNetFlt.inf $(MAKEFILE_CURRENT) | $$(dir $$@)
$(call MSG_GENERATE,VBoxNetFlt-inf,$@,$<)
$(call VBOX_EDIT_INF_FN,$<,$@)
-$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt_m.inf: $(PATH_SUB_CURRENT)/win/VBoxNetFlt_m.inf $(MAKEFILE_CURRENT) | $$(dir $$@)
+$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltM.inf: $(PATH_SUB_CURRENT)/win/drv/VBoxNetFltM.inf $(MAKEFILE_CURRENT) | $$(dir $$@)
$(call MSG_GENERATE,VBoxNetFlt-inf,$@,$<)
$(call VBOX_EDIT_INF_FN,$<,$@)
ifdef VBOX_SIGNING_MODE
VBoxNetFlt-inf_SOURCES += \
$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.sys \
- $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltNotify.dll \
+ $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltNobj.dll \
$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.cat
-$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.sys: $$(TARGET_VBoxNetFlt) | $$(dir $$@)
+$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.sys: $$(VBoxNetFlt_1_TARGET) | $$(dir $$@)
$(INSTALL) -m 644 $< $(@D)
-$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltNotify.dll: $$(TARGET_VBoxNetFltNotify) | $$(dir $$@)
+$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltNobj.dll: $$(VBoxNetFltNobj_1_TARGET) | $$(dir $$@)
$(INSTALL) -m 644 $< $(@D)
$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.cat: \
$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.sys \
- $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltNotify.dll \
+ $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltNobj.dll \
$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.inf \
- $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt_m.inf
+ $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltM.inf
$(call MSG_TOOL,Inf2Cat,VBoxNetFlt-inf,$@,$<)
$(call VBOX_MAKE_CAT_FN, $(@D),$@)
@@ -148,7 +148,7 @@ WinNetConfig_TEMPLATE = VBOXR3STATIC
WinNetConfig_DEFS = _WIN32_WINNT=0x0501 _UNICODE UNICODE
WinNetConfig_SDKS = WINPSDK W2K3DDK
WinNetConfig_SOURCES = \
- win/WinNetConfig.cpp
+ win/cfg/VBoxNetCfg.cpp
WinNetConfig_INCS.win += $(PATH_TOOL_$(VBOX_VCC_TOOL)_INC)
#
@@ -157,8 +157,10 @@ WinNetConfig_INCS.win += $(PATH_TOOL_$(VBOX_VCC_TOOL)_INC)
PROGRAMS.win += NetFltInstall
NetFltInstall_TEMPLATE = VBOXR3STATIC
NetFltInstall_SDKS = WINPSDK W2K3DDK VBOX_NTDLL
-NetFltInstall_SOURCES = win/NetFltInstall.cpp
-NetFltInstall_LIBS = $(TARGET_WinNetConfig) \
+NetFltInstall_SOURCES = win/tools/VBoxNetFltInstall.cpp
+NetFltInstall_LIBS = \
+ $(WinNetConfig_1_TARGET) \
+ $(VBoxDrvCfg_1_TARGET) \
$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/comsupp.lib \
$(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib
@@ -169,8 +171,10 @@ NetFltInstall_LIBS = $(TARGET_WinNetConfig) \
PROGRAMS.win += NetFltUninstall
NetFltUninstall_TEMPLATE = VBOXR3STATIC
NetFltUninstall_SDKS = WINPSDK W2K3DDK VBOX_NTDLL
-NetFltUninstall_SOURCES = win/NetFltUninstall.cpp
-NetFltUninstall_LIBS = $(TARGET_WinNetConfig) \
+NetFltUninstall_SOURCES = win/tools/VBoxNetFltUninstall.cpp
+NetFltUninstall_LIBS = \
+ $(WinNetConfig_1_TARGET) \
+ $(VBoxDrvCfg_1_TARGET) \
$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/comsupp.lib \
$(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib
@@ -180,8 +184,10 @@ NetFltUninstall_LIBS = $(TARGET_WinNetConfig) \
PROGRAMS.win += NetAdpInstall
NetAdpInstall_TEMPLATE = VBOXR3STATIC
NetAdpInstall_SDKS = WINPSDK W2K3DDK VBOX_NTDLL
-NetAdpInstall_SOURCES = win/NetAdpInstall.cpp
-NetAdpInstall_LIBS = $(TARGET_WinNetConfig) \
+NetAdpInstall_SOURCES = win/tools/VBoxNetAdpInstall.cpp
+NetAdpInstall_LIBS = \
+ $(WinNetConfig_1_TARGET) \
+ $(VBoxDrvCfg_1_TARGET) \
$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/comsupp.lib \
$(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib
@@ -192,53 +198,55 @@ NetAdpInstall_LIBS = $(TARGET_WinNetConfig) \
PROGRAMS.win += NetAdpUninstall
NetAdpUninstall_TEMPLATE = VBOXR3STATIC
NetAdpUninstall_SDKS = WINPSDK W2K3DDK VBOX_NTDLL
-NetAdpUninstall_SOURCES = win/NetAdpUninstall.cpp
-NetAdpUninstall_LIBS = $(TARGET_WinNetConfig) \
+NetAdpUninstall_SOURCES = win/tools/VBoxNetAdpUninstall.cpp
+NetAdpUninstall_LIBS = \
+ $(WinNetConfig_1_TARGET) \
+ $(VBoxDrvCfg_1_TARGET) \
$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/comsupp.lib \
$(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib
#
-# VBoxNetFltNotify
+# VBoxNetFltNobj
#
-DLLS.win += VBoxNetFltNotify
+DLLS.win += VBoxNetFltNobj
if defined(VBOX_SIGNING_MODE)
-VBoxNetFltNotify_NOINST = true
+VBoxNetFltNobj_NOINST = true
endif
-VBoxNetFltNotify_TEMPLATE = VBOXR3STATIC
-VBoxNetFltNotify_SDKS = WINPSDK W2K3DDK VBOX_NTDLL
-VBoxNetFltNotify_DEFS = _WIN32_WINNT=0x0500 WIN32 _ATL_STATIC_REGISTRY
-VBoxNetFltNotify_INCS = \
- $(VBoxNetFltNotify_0_OUTDIR)
-VBoxNetFltNotify_SOURCES = \
- win/notifyobj/VBoxNetFltNotify.cpp \
- win/notifyobj/VBoxNetFltNotify.def \
- win/notifyobj/VBoxNetFltNotify.rc
-VBoxNetFltNotify_LIBS = \
+VBoxNetFltNobj_TEMPLATE = VBOXR3STATIC
+VBoxNetFltNobj_SDKS = WINPSDK W2K3DDK VBOX_NTDLL
+VBoxNetFltNobj_DEFS = _WIN32_WINNT=0x0500 WIN32 _ATL_STATIC_REGISTRY
+VBoxNetFltNobj_INCS = \
+ $(VBoxNetFltNobj_0_OUTDIR)
+VBoxNetFltNobj_SOURCES = \
+ win/nobj/VBoxNetFltNobj.cpp \
+ win/nobj/VBoxNetFltNobj.def \
+ win/nobj/VBoxNetFltNobj.rc
+VBoxNetFltNobj_LIBS = \
$(PATH_TOOL_$(VBOX_VCC_TOOL)_ATLMFC_LIB)/atls$(VBOX_VCC_CRT_TYPE).lib
-#VBoxNetFltNotify_INTERMEDIATES =
-VBoxNetFltNotify_DEPS = \
- $(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn_i.c \
- $(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn_p.c \
- $(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn.h \
- $(VBoxNetFltNotify_0_OUTDIR)/dlldata.c \
- $(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn.tlb
-VBoxNetFltNotify_CLEAN = $(VBoxNetFltNotify_DEPS)
-
-VBOXNETFLT_NOTIFY_IDL ?= $(EXEC_X86_WIN32) $(call VBOX_FN_MAKE_WIN_PATH,$(firstword $(wildcard \
+#VBoxNetFltNobj_INTERMEDIATES =
+VBoxNetFltNobj_DEPS = \
+ $(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT_i.c \
+ $(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT_p.c \
+ $(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT.h \
+ $(VBoxNetFltNobj_0_OUTDIR)/dlldata.c \
+ $(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT.tlb
+VBoxNetFltNobj_CLEAN = $(VBoxNetFltNobj_DEPS)
+
+VBOXNETFLT_NOBJ_IDL ?= $(EXEC_X86_WIN32) $(call VBOX_FN_MAKE_WIN_PATH,$(firstword $(wildcard \
$(PATH_SDK_WINPSDK_BIN)/Midl.Exe\
$(PATH_SDK_WINPSDK)/Bin/Midl.Exe\
$(PATH_DEVTOOLS)/win.x86/bin/midl.exe\
) Sorry_Cannot_Find_The_Midl_Compiler_In_The_PSDK))
-$$(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn_i.c \
-+ $$(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn_p.c \
-+ $$(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn.h \
-+ $$(VBoxNetFltNotify_0_OUTDIR)/dlldata.c \
-+ $$(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn.tlb: \
- $(PATH_SUB_CURRENT)/win/notifyobj/VBoxNetFltNotifyn.idl \
+$$(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT_i.c \
++ $$(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT_p.c \
++ $$(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT.h \
++ $$(VBoxNetFltNobj_0_OUTDIR)/dlldata.c \
++ $$(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT.tlb: \
+ $(PATH_SUB_CURRENT)/win/nobj/VBoxNetFltNobjT.idl \
| $$(dir $$@)
- $(VBOXNETFLT_NOTIFY_IDL) /nologo \
- /out $(call VBOX_FN_MAKE_WIN_PATH,$(VBoxNetFltNotify_0_OUTDIR)) \
+ $(VBOXNETFLT_NOBJ_IDL) /nologo \
+ /out $(call VBOX_FN_MAKE_WIN_PATH,$(VBoxNetFltNobj_0_OUTDIR)) \
/cpp_cmd $(subst $(EXEC_X86_WIN32),,$(call VBOX_FN_MAKE_WIN_PATH,$(TOOL_$(VBOX_VCC_TOOL)_CC))) \
$(addprefix /I , $(call VBOX_FN_MAKE_WIN_PATH,$(SDK_W2K3DDK_INCS))) \
$(call VBOX_FN_MAKE_WIN_PATH,$<)
@@ -253,13 +261,13 @@ VBoxNetAdp_TEMPLATE = VBOXR0DRV
VBoxNetAdp_NOINST = true
endif
VBoxNetAdp_DEFS = IN_RT_R0 IN_SUP_STATIC
-VBoxNetAdp_SDKS = W2K3DDK WINPSDKINCS
VBoxNetAdp_INCS := $(PATH_SUB_CURRENT)
+VBoxNetAdp_SDKS = WINDDKWLH WINPSDKINCS
VBoxNetAdp_SOURCES = \
VBoxNetFlt.c \
- win/VBoxNetFlt-win.c \
- win/VBoxNetFltMp-win.c \
- win/VBoxNetFlt-win.rc
+ win/drv/VBoxNetFltM-win.cpp \
+ win/drv/VBoxNetFltRt-win.cpp \
+ win/drv/VBoxNetFlt-win.rc
VBoxNetAdp_DEFS += VBOXNETFLT_STATIC_CONFIG VBOXNETADP
VBoxNetAdp_DEFS.win += VBOXNETFLT_NO_PACKET_QUEUE
VBoxNetAdp_DEFS += NDIS_MINIPORT_DRIVER NDIS_WDM=1 BINARY_COMPATIBLE=0
@@ -283,7 +291,7 @@ VBoxNetAdp-inf_SOURCES = \
VBoxNetAdp-inf_CLEAN = $(VBoxNetAdp-inf_SOURCES)
VBoxNetAdp-inf_BLDDIRS = $(PATH_TARGET)/VBoxNetAdpCat.dir
-$(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.inf: $(PATH_SUB_CURRENT)/win/VBoxNetAdp.inf $(MAKEFILE_CURRENT) | $$(dir $$@)
+$(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.inf: $(PATH_SUB_CURRENT)/win/drv/VBoxNetAdp.inf $(MAKEFILE_CURRENT) | $$(dir $$@)
$(call MSG_GENERATE,VBoxNetAdp-inf,$@,$<)
$(call VBOX_EDIT_INF_FN,$<,$@)
@@ -292,7 +300,7 @@ VBoxNetAdp-inf_SOURCES += \
$(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.sys \
$(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.cat
-$(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.sys: $$(TARGET_VBoxNetAdp) | $$(dir $$@)
+$(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.sys: $$(VBoxNetAdp_1_TARGET) | $$(dir $$@)
$(INSTALL) -m 644 $< $(@D)
$(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.cat: \
@@ -322,7 +330,7 @@ vboxnetflt_INCS.linux := \
$(PATH_ROOT)/src/VBox/Runtime/r0drv/linux
vboxnetflt_INCS := \
$(PATH_SUB_CURRENT)
-vboxnetflt_LDFLAGS.solaris += -N drv/vboxdrv
+vboxnetflt_LDFLAGS.solaris += -N drv/vboxdrv -N misc/ctf
vboxnetflt_LIBS = \
$(PATH_LIB)/SUPR0IdcClient$(VBOX_SUFF_LIB)
## @todo vboxflt should resolves all the IPRT bits from vboxdrv.
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c
index bca13618b..033c12f01 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetFlt.c $ */
+/* $Id: VBoxNetFlt.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Common Code.
*/
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
index 4eb593a37..ba7439c99 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
+++ b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetFltInternal.h $ */
+/* $Id: VBoxNetFltInternal.h 36956 2011-05-04 12:54:03Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Internal Header.
*/
@@ -242,7 +242,7 @@ typedef struct VBOXNETFLTINS
/** @name Windows instance data.
* @{ */
/** Filter driver device context. */
- ADAPT IfAdaptor;
+ VBOXNETFLTWIN WinIf;
volatile uint32_t cModeNetFltRefs;
volatile uint32_t cModePassThruRefs;
@@ -252,8 +252,8 @@ typedef struct VBOXNETFLTINS
#endif
/** The MAC address of the interface. Caching MAC for performance reasons. */
RTMAC MacAddr;
- /** mutex used to synchronize ADAPT init/deinit */
- RTSEMMUTEX hAdaptMutex;
+ /** mutex used to synchronize WinIf init/deinit */
+ RTSEMMUTEX hWinIfMutex;
/** @} */
# else
# error "PORTME"
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp b/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
index 16c094265..fcc31dce8 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetFlt-darwin.cpp $ */
+/* $Id: VBoxNetFlt-darwin.cpp 33676 2010-11-02 09:48:24Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Darwin Specific Code.
*/
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile
index a6792b019..20ba2da61 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile
+++ b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile $
+# $Id: Makefile 36385 2011-03-24 06:15:17Z vboxsync $
## @file
# Makefile for the VirtualBox FreeBSD Host Driver.
#
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c
index eadb7007d..38ee00d99 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetFlt-freebsd.c $ */
+/* $Id: VBoxNetFlt-freebsd.c 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), FreeBSD Specific Code.
*/
@@ -83,27 +83,27 @@ static ng_disconnect_t ng_vboxnetflt_disconnect;
static int ng_vboxnetflt_mod_event(module_t mod, int event, void *data);
/** Netgraph node type */
-#define NG_VBOXNETFLT_NODE_TYPE "vboxnetflt"
+#define NG_VBOXNETFLT_NODE_TYPE "vboxnetflt"
/** Netgraph message cookie */
-#define NGM_VBOXNETFLT_COOKIE 0x56424f58
+#define NGM_VBOXNETFLT_COOKIE 0x56424f58
/** Input netgraph hook name */
-#define NG_VBOXNETFLT_HOOK_IN "input"
+#define NG_VBOXNETFLT_HOOK_IN "input"
/** Output netgraph hook name */
-#define NG_VBOXNETFLT_HOOK_OUT "output"
+#define NG_VBOXNETFLT_HOOK_OUT "output"
/** mbuf tag identifier */
-#define MTAG_VBOX 0x56424f58
+#define MTAG_VBOX 0x56424f58
/** mbuf packet tag */
-#define PACKET_TAG_VBOX 128
+#define PACKET_TAG_VBOX 128
#if defined(__FreeBSD_version) && __FreeBSD_version >= 800500
# include <sys/jail.h>
# include <net/vnet.h>
-# define VBOXCURVNET_SET(arg) CURVNET_SET_QUIET(arg)
-# define VBOXCURVNET_SET_FROM_UCRED() VBOXCURVNET_SET(CRED_TO_VNET(curthread->td_ucred))
-# define VBOXCURVNET_RESTORE() CURVNET_RESTORE()
+# define VBOXCURVNET_SET(arg) CURVNET_SET_QUIET(arg)
+# define VBOXCURVNET_SET_FROM_UCRED() VBOXCURVNET_SET(CRED_TO_VNET(curthread->td_ucred))
+# define VBOXCURVNET_RESTORE() CURVNET_RESTORE()
#else /* !defined(__FreeBSD_version) || __FreeBSD_version < 800500 */
@@ -127,16 +127,16 @@ static const struct ng_cmdlist ng_vboxnetflt_cmdlist[] =
*/
static struct ng_type ng_vboxnetflt_typestruct =
{
- .version = NG_ABI_VERSION,
- .name = NG_VBOXNETFLT_NODE_TYPE,
- .mod_event = vboxnetflt_modevent,
- .constructor = ng_vboxnetflt_constructor,
- .rcvmsg = ng_vboxnetflt_rcvmsg,
- .shutdown = ng_vboxnetflt_shutdown,
- .newhook = ng_vboxnetflt_newhook,
- .rcvdata = ng_vboxnetflt_rcvdata,
- .disconnect = ng_vboxnetflt_disconnect,
- .cmdlist = ng_vboxnetflt_cmdlist,
+ .version = NG_ABI_VERSION,
+ .name = NG_VBOXNETFLT_NODE_TYPE,
+ .mod_event = vboxnetflt_modevent,
+ .constructor= ng_vboxnetflt_constructor,
+ .rcvmsg = ng_vboxnetflt_rcvmsg,
+ .shutdown = ng_vboxnetflt_shutdown,
+ .newhook = ng_vboxnetflt_newhook,
+ .rcvdata = ng_vboxnetflt_rcvdata,
+ .disconnect = ng_vboxnetflt_disconnect,
+ .cmdlist = ng_vboxnetflt_cmdlist,
};
NETGRAPH_INIT(vboxnetflt, &ng_vboxnetflt_typestruct);
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt
index 691e18fe7..3189c4955 100755..100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt
+++ b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: files_vboxnetflt $
+# $Id: files_vboxnetflt 36190 2011-03-07 16:28:50Z vboxsync $
## @file
# Shared file between Makefile.kmk and export_modules
#
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c b/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
index 59f8ad78a..d1c7f284e 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetFlt-linux.c $ */
+/* $Id: VBoxNetFlt-linux.c 38063 2011-07-19 09:58:08Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Linux Specific Code.
*/
@@ -50,8 +50,9 @@
#define VBOXNETFLT_OS_SPECFIC 1
#include "../VBoxNetFltInternal.h"
+#define VBOXNETFLT_WITH_FILTER_HOST2GUEST_SKBS_EXPERIMENT
#ifdef CONFIG_NET_SCHED
-# define VBOXNETFLT_WITH_QDISC /* Comment this out to disable qdisc support */
+/*# define VBOXNETFLT_WITH_QDISC Comment this out to disable qdisc support */
# ifdef VBOXNETFLT_WITH_QDISC
# include <net/pkt_sched.h>
# endif /* VBOXNETFLT_WITH_QDISC */
@@ -93,7 +94,8 @@
# endif
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
+#ifdef VBOXNETFLT_WITH_QDISC
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch)
{
kfree_skb(skb);
@@ -101,7 +103,8 @@ static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch)
return NET_XMIT_DROP;
}
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) */
+# endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) */
+#endif /* VBOXNETFLT_WITH_QDISC */
#ifndef NET_IP_ALIGN
# define NET_IP_ALIGN 2
@@ -902,7 +905,10 @@ static int vboxNetFltLinuxStartXmitFilter(struct sk_buff *pSkb, struct net_devic
*/
if ( !VALID_PTR(pOverride)
|| pOverride->u32Magic != VBOXNETDEVICEOPSOVERRIDE_MAGIC
- || !VALID_PTR(pOverride->pOrgOps))
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+ || !VALID_PTR(pOverride->pOrgOps)
+# endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) */
+ )
{
printk("vboxNetFltLinuxStartXmitFilter: bad override %p\n", pOverride);
dev_kfree_skb(pSkb);
@@ -952,6 +958,9 @@ static void vboxNetFltLinuxHookDev(PVBOXNETFLTINS pThis, struct net_device *pDev
PVBOXNETDEVICEOPSOVERRIDE pOverride;
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+ /* Cancel override if ethtool_ops is missing (host-only case, #5712) */
+ if (!VALID_PTR(pDev->OVR_OPS))
+ return;
pOverride = RTMemAlloc(sizeof(*pOverride));
if (!pOverride)
return;
@@ -1001,7 +1010,7 @@ static void vboxNetFltLinuxUnhookDev(PVBOXNETFLTINS pThis, struct net_device *pD
# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
ASMAtomicWritePtr((void * volatile *)&pDev->hard_start_xmit, pOverride->pfnStartXmit);
# endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) */
- ASMAtomicWritePtr((void * volatile *)&pDev->OVR_OPS, pOverride->pOrgOps);
+ ASMAtomicWritePtr((void const * volatile *)&pDev->OVR_OPS, pOverride->pOrgOps);
ASMAtomicWriteU32(&pOverride->u32Magic, 0);
}
else
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt b/src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt
index 8e22c249a..f27ac7b4d 100755..100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt
+++ b/src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: files_vboxnetflt $
+# $Id: files_vboxnetflt 36190 2011-03-07 16:28:50Z vboxsync $
## @file
# Shared file between Makefile.kmk and export_modules
#
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c
index 301331cd3..1a4b1b6b0 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetFlt-solaris.c $ */
+/* $Id: VBoxNetFlt-solaris.c 37983 2011-07-15 14:42:57Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Solaris Specific Code.
*/
@@ -64,6 +64,7 @@
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/sunldi.h>
+#include <sys/ctf_api.h>
// Workaround for very strange define in sys/user.h
// #define u (curproc->p_user) /* user is now part of proc structure */
@@ -404,6 +405,64 @@ VBOXNETFLTSTREAMTYPE volatile g_VBoxNetFltSolarisStreamType = kUndefined;
static int g_VBoxNetFltSolarisPollInterval = -1;
#endif
+static int s_off_vnode = -1;
+#define VNODE_FOR_FILE_T(filetpointer) (*(struct vnode **)((char *)(filetpointer) + s_off_vnode))
+
+
+static int
+vboxNetFltSolarisCtfGetMemberOffset(ctf_file_t *pCtfFile, const char *pszStruct, const char *pszMember, int *pOffset)
+{
+ AssertReturn(pCtfFile, VERR_INVALID_PARAMETER);
+ AssertReturn(pszStruct, VERR_INVALID_PARAMETER);
+ AssertReturn(pszMember, VERR_INVALID_PARAMETER);
+ AssertReturn(pOffset, VERR_INVALID_PARAMETER);
+
+ ctf_id_t TypeId = ctf_lookup_by_name(pCtfFile, pszStruct);
+ if (TypeId != CTF_ERR)
+ {
+ ctf_membinfo_t MemberInfo;
+ bzero(&MemberInfo, sizeof(MemberInfo));
+ if (ctf_member_info(pCtfFile, TypeId, pszMember, &MemberInfo) != CTF_ERR)
+ {
+ *pOffset = (MemberInfo.ctm_offset >> 3);
+ LogRel((DEVICE_NAME ":%s::%s at %d\n", pszStruct, pszMember, *pOffset));
+ return VINF_SUCCESS;
+ }
+ else
+ LogRel((DEVICE_NAME ":ctf_member_info failed for struct %s member %s\n", pszStruct, pszMember));
+ }
+ else
+ LogRel((DEVICE_NAME ":ctf_lookup_by_name failed for struct %s\n", pszStruct));
+
+ return VERR_NOT_FOUND;
+}
+
+
+static int
+vboxNetFltSolarisProbeCtf(void)
+{
+ /*
+ * CTF probing for fluid f_vnode member in file_t.
+ */
+ int rc = VERR_INTERNAL_ERROR;
+ modctl_t *pModCtl = mod_hold_by_name("genunix");
+ if (pModCtl)
+ {
+ int err;
+ ctf_file_t *pCtfFile = ctf_modopen(pModCtl->mod_mp, &err);
+ if (pCtfFile)
+ rc = vboxNetFltSolarisCtfGetMemberOffset(pCtfFile, "file_t", "f_vnode", &s_off_vnode);
+ else
+ LogRel((DEVICE_NAME ":ctf_modopen failed. err=%d\n", err));
+
+ mod_release_mod(pModCtl);
+ }
+ else
+ LogRel((DEVICE_NAME ":mod_hold_by_name failed.\n"));
+
+ return rc;
+}
+
/**
* Kernel entry points
@@ -427,46 +486,52 @@ int _init(void)
int rc = RTR0Init(0);
if (RT_SUCCESS(rc))
{
- /*
- * Initialize Solaris specific globals here.
- */
- g_VBoxNetFltSolarisStreams = NULL;
- g_VBoxNetFltSolarisInstance = NULL;
- g_pVBoxNetFltSolarisCred = crdup(kcred);
- if (RT_LIKELY(g_pVBoxNetFltSolarisCred))
+ rc = vboxNetFltSolarisProbeCtf();
+ if (RT_SUCCESS(rc))
{
- rc = RTSemFastMutexCreate(&g_VBoxNetFltSolarisMtx);
- if (RT_SUCCESS(rc))
+ /*
+ * Initialize Solaris specific globals here.
+ */
+ g_VBoxNetFltSolarisStreams = NULL;
+ g_VBoxNetFltSolarisInstance = NULL;
+ g_pVBoxNetFltSolarisCred = crdup(kcred);
+ if (RT_LIKELY(g_pVBoxNetFltSolarisCred))
{
- /*
- * Initialize the globals and connect to the support driver.
- *
- * This will call back vboxNetFltOsOpenSupDrv (and maybe vboxNetFltOsCloseSupDrv)
- * for establishing the connect to the support driver.
- */
- memset(&g_VBoxNetFltSolarisGlobals, 0, sizeof(g_VBoxNetFltSolarisGlobals));
- rc = vboxNetFltInitGlobalsAndIdc(&g_VBoxNetFltSolarisGlobals);
+ rc = RTSemFastMutexCreate(&g_VBoxNetFltSolarisMtx);
if (RT_SUCCESS(rc))
{
- rc = mod_install(&g_VBoxNetFltSolarisModLinkage);
- if (!rc)
- return rc;
+ /*
+ * Initialize the globals and connect to the support driver.
+ *
+ * This will call back vboxNetFltOsOpenSupDrv (and maybe vboxNetFltOsCloseSupDrv)
+ * for establishing the connect to the support driver.
+ */
+ memset(&g_VBoxNetFltSolarisGlobals, 0, sizeof(g_VBoxNetFltSolarisGlobals));
+ rc = vboxNetFltInitGlobalsAndIdc(&g_VBoxNetFltSolarisGlobals);
+ if (RT_SUCCESS(rc))
+ {
+ rc = mod_install(&g_VBoxNetFltSolarisModLinkage);
+ if (!rc)
+ return rc;
- LogRel((DEVICE_NAME ":mod_install failed. rc=%d\n", rc));
- vboxNetFltTryDeleteIdcAndGlobals(&g_VBoxNetFltSolarisGlobals);
- }
- else
- LogRel((DEVICE_NAME ":failed to initialize globals.\n"));
+ LogRel((DEVICE_NAME ":mod_install failed. rc=%d\n", rc));
+ vboxNetFltTryDeleteIdcAndGlobals(&g_VBoxNetFltSolarisGlobals);
+ }
+ else
+ LogRel((DEVICE_NAME ":failed to initialize globals.\n"));
- RTSemFastMutexDestroy(g_VBoxNetFltSolarisMtx);
- g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX;
+ RTSemFastMutexDestroy(g_VBoxNetFltSolarisMtx);
+ g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX;
+ }
+ }
+ else
+ {
+ LogRel((DEVICE_NAME ":failed to allocate credentials.\n"));
+ rc = VERR_NO_MEMORY;
}
}
else
- {
- LogRel((DEVICE_NAME ":failed to allocate credentials.\n"));
- rc = VERR_NO_MEMORY;
- }
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisProbeCtf failed. rc=%d\n", rc));
RTR0Term();
}
@@ -1561,9 +1626,9 @@ static int vboxNetFltSolarisOpenDev(char *pszDev, vnode_t **ppVNode, vnode_t **p
{
if ( pUser
&& pUser->fp
- && pUser->fp->f_vnode)
+ && VNODE_FOR_FILE_T(pUser->fp))
{
- *ppVNode = pUser->fp->f_vnode;
+ *ppVNode = VNODE_FOR_FILE_T(pUser->fp);
*ppVNodeHeld = pVNodeHeld;
*ppUser = pUser;
return VINF_SUCCESS;
@@ -1571,7 +1636,7 @@ static int vboxNetFltSolarisOpenDev(char *pszDev, vnode_t **ppVNode, vnode_t **p
else
{
LogRel((DEVICE_NAME ":vboxNetFltSolarisOpenDev failed. pUser=%p fp=%p f_vnode=%p\n", pUser, pUser ? pUser->fp : NULL,
- pUser && pUser->fp ? pUser->fp->f_vnode : NULL));
+ pUser && pUser->fp ? VNODE_FOR_FILE_T(pUser->fp) : NULL));
}
if (pUser)
@@ -2186,11 +2251,11 @@ static int vboxNetFltSolarisAttachIp4(PVBOXNETFLTINS pThis, bool fAttach)
file_t *pArpFile = getf(ArpMuxFd);
if ( pIpFile
&& pArpFile
- && pArpFile->f_vnode
- && pIpFile->f_vnode)
+ && VNODE_FOR_FILE_T(pArpFile)
+ && VNODE_FOR_FILE_T(pIpFile))
{
- vnode_t *pIp4VNode = pIpFile->f_vnode;
- vnode_t *pArpVNode = pArpFile->f_vnode;
+ vnode_t *pIp4VNode = VNODE_FOR_FILE_T(pIpFile);
+ vnode_t *pArpVNode = VNODE_FOR_FILE_T(pArpFile);
/*
* Find the position on the host stack for attaching/detaching ourselves.
@@ -2430,9 +2495,9 @@ static int vboxNetFltSolarisAttachIp6(PVBOXNETFLTINS pThis, bool fAttach)
*/
file_t *pIpFile = getf(Ip6MuxFd);
if ( pIpFile
- && pIpFile->f_vnode)
+ && VNODE_FOR_FILE_T(pIpFile))
{
- vnode_t *pIp6VNode = pIpFile->f_vnode;
+ vnode_t *pIp6VNode = VNODE_FOR_FILE_T(pIpFile);
/*
* Find the position on the host stack for attaching/detaching ourselves.
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c
index d5a6bc106..7e7afa433 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetFltBow-solaris.c $ */
+/* $Id: VBoxNetFltBow-solaris.c 37766 2011-07-04 14:15:25Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Solaris Specific Code.
*/
@@ -53,17 +53,6 @@
#include <sys/dld.h>
#include <sys/cred.h>
-#if 0
-#include "include/mac_provider.h" /* dependency for other headers */
-#include "include/mac_client.h" /* for mac_* */
-#include "include/mac_client_priv.h" /* for mac_info, mac_capab_get etc. */
-#if 1
-#include "include/dls.h" /* for dls_mgmt_* */
-#include "include/dld_ioc.h" /* required by vnic.h */
-#include "include/vnic.h" /* for vnic_ioc_diag_t */
-#include "include/vnic_impl.h" /* for vnic_dev_create */
-#endif
-#endif
#define VBOXNETFLT_OS_SPECFIC 1
#include "../VBoxNetFltInternal.h"
@@ -72,15 +61,15 @@
* Defined Constants And Macros *
*******************************************************************************/
/** The module name. */
-#define DEVICE_NAME "vboxflt"
+#define DEVICE_NAME "vboxbow"
/** The module descriptions as seen in 'modinfo'. */
#define DEVICE_DESC_DRV "VirtualBox NetBow"
/** The dynamically created VNIC name (hardcoded in NetIf-solaris.cpp).
* @todo move this define into a common header. */
-#define VBOXFLT_VNIC_NAME "vboxvnic"
+#define VBOXBOW_VNIC_NAME "vboxvnic"
/** The VirtualBox VNIC template name (hardcoded in NetIf-solaris.cpp).
* * @todo move this define into a common header. */
-#define VBOXFLT_VNIC_TEMPLATE_NAME "vboxvnic_template"
+#define VBOXBOW_VNIC_TEMPLATE_NAME "vboxvnic_template"
/** Debugging switch for using symbols in kmdb */
# define LOCAL static
/** VBOXNETFLTVNIC::u32Magic */
@@ -392,17 +381,8 @@ LOCAL int VBoxNetFltSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
{
case DDI_ATTACH:
{
- int instance = ddi_get_instance(pDip);
- int rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0, "none", "none", 0666);
- if (rc == DDI_SUCCESS)
- {
- g_pVBoxNetFltSolarisDip = pDip;
- ddi_report_dev(pDip);
- return DDI_SUCCESS;
- }
- else
- LogRel((DEVICE_NAME ":VBoxNetFltSolarisAttach failed to create minor node. rc=%d\n", rc));
- return DDI_FAILURE;
+ g_pVBoxNetFltSolarisDip = pDip;
+ return DDI_SUCCESS;
}
case DDI_RESUME:
@@ -434,7 +414,6 @@ LOCAL int VBoxNetFltSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
{
case DDI_DETACH:
{
- ddi_remove_minor_node(pDip, NULL);
return DDI_SUCCESS;
}
@@ -517,7 +496,6 @@ LOCAL inline mblk_t *vboxNetFltSolarisMBlkFromSG(PVBOXNETFLTINS pThis, PINTNETSG
pMsg->b_wptr += pSG->aSegs[i].cb;
}
}
- DB_TYPE(pMsg) = M_DATA;
return pMsg;
}
@@ -990,7 +968,7 @@ LOCAL int vboxNetFltSolarisInitVNICTemplate(PVBOXNETFLTINS pThis, PVBOXNETFLTVNI
*/
LOCAL PVBOXNETFLTVNIC vboxNetFltSolarisAllocVNIC(void)
{
- PVBOXNETFLTVNIC pVNIC = RTMemAlloc(sizeof(VBOXNETFLTVNIC));
+ PVBOXNETFLTVNIC pVNIC = RTMemAllocZ(sizeof(VBOXNETFLTVNIC));
if (RT_UNLIKELY(!pVNIC))
return NULL;
@@ -1015,8 +993,7 @@ LOCAL PVBOXNETFLTVNIC vboxNetFltSolarisAllocVNIC(void)
*/
LOCAL inline void vboxNetFltSolarisFreeVNIC(PVBOXNETFLTVNIC pVNIC)
{
- if (pVNIC)
- RTMemFree(pVNIC);
+ RTMemFree(pVNIC);
}
@@ -1028,6 +1005,8 @@ LOCAL inline void vboxNetFltSolarisFreeVNIC(PVBOXNETFLTVNIC pVNIC)
*/
LOCAL void vboxNetFltSolarisDestroyVNIC(PVBOXNETFLTVNIC pVNIC)
{
+ AssertPtrReturnVoid(pVNIC);
+ AssertMsgReturnVoid(pVNIC->u32Magic == VBOXNETFLTVNIC_MAGIC, ("pVNIC=%p u32Magic=%#x\n", pVNIC, pVNIC->u32Magic));
if (pVNIC)
{
if (pVNIC->hClient)
@@ -1085,7 +1064,7 @@ LOCAL int vboxNetFltSolarisCreateVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC *ppV
if (RT_UNLIKELY(!pVNIC))
return VERR_NO_MEMORY;
- RTStrPrintf(pVNIC->szName, sizeof(pVNIC->szName), "%s%RU64", VBOXFLT_VNIC_NAME, pThis->u.s.uInstance);
+ RTStrPrintf(pVNIC->szName, sizeof(pVNIC->szName), "%s%RU64", VBOXBOW_VNIC_NAME, pThis->u.s.uInstance);
/*
* Set a random MAC address for now. It will be changed to the VM interface's
@@ -1307,7 +1286,7 @@ int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
else
{
pThis->u.s.fIsVNIC = true;
- if (RTStrNCmp(pThis->szName, VBOXFLT_VNIC_TEMPLATE_NAME, sizeof(VBOXFLT_VNIC_TEMPLATE_NAME) - 1) == 0)
+ if (RTStrNCmp(pThis->szName, VBOXBOW_VNIC_TEMPLATE_NAME, sizeof(VBOXBOW_VNIC_TEMPLATE_NAME) - 1) == 0)
{
LogFlow((DEVICE_NAME ":vboxNetFltOsInitInstance pThis=%p VNIC template '%s' detected.\n", pThis, pThis->szName));
pThis->u.s.fIsVNICTemplate = true;
@@ -1583,7 +1562,7 @@ int vboxNetFltPortOsDisconnectInterface(PVBOXNETFLTINS pThis, void *pvIfData)
* Remove the VNIC from the list, destroy and free it.
*/
list_remove(&pThis->u.s.hVNICs, pVNIC);
- LogRel((DEVICE_NAME ":vboxNetFltPortOsDisconnectInterface destroying pVNIC=%p\n", pVNIC));
+ LogFlow((DEVICE_NAME ":vboxNetFltPortOsDisconnectInterface destroying pVNIC=%p\n", pVNIC));
vboxNetFltSolarisDestroyVNIC(pVNIC);
vboxNetFltSolarisFreeVNIC(pVNIC);
}
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client.h b/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client.h
deleted file mode 100644
index e5524214e..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client.h
+++ /dev/null
@@ -1,199 +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 2009-2010 Oracle Corporation. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * This file captures the MAC client API definitions. It can be
- * included from any MAC clients.
- */
-
-#ifndef _SYS_MAC_CLIENT_H
-#define _SYS_MAC_CLIENT_H
-
-#include <sys/mac.h>
-#include <sys/mac_flow.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _KERNEL
-
-/*
- * MAC client interface.
- */
-
-typedef struct __mac_client_handle *mac_client_handle_t;
-typedef struct __mac_unicast_handle *mac_unicast_handle_t;
-typedef struct __mac_promisc_handle *mac_promisc_handle_t;
-typedef struct __mac_perim_handle *mac_perim_handle_t;
-typedef uintptr_t mac_tx_cookie_t;
-
-typedef void (*mac_tx_notify_t)(void *, mac_tx_cookie_t);
-
-typedef enum {
- MAC_DIAG_NONE,
- MAC_DIAG_MACADDR_NIC,
- MAC_DIAG_MACADDR_INUSE,
- MAC_DIAG_MACADDR_INVALID,
- MAC_DIAG_MACADDRLEN_INVALID,
- MAC_DIAG_MACFACTORYSLOTINVALID,
- MAC_DIAG_MACFACTORYSLOTUSED,
- MAC_DIAG_MACFACTORYSLOTALLUSED,
- MAC_DIAG_MACFACTORYNOTSUP,
- MAC_DIAG_MACPREFIX_INVALID,
- MAC_DIAG_MACPREFIXLEN_INVALID,
- MAC_DIAG_MACNO_HWRINGS
-} mac_diag_t;
-
-typedef enum {
- MAC_CLIENT_PROMISC_ALL,
- MAC_CLIENT_PROMISC_FILTERED,
- MAC_CLIENT_PROMISC_MULTI
-} mac_client_promisc_type_t;
-
-/* flags passed to mac_unicast_add() */
-#define MAC_UNICAST_NODUPCHECK 0x0001
-#define MAC_UNICAST_PRIMARY 0x0002
-#define MAC_UNICAST_HW 0x0004
-#define MAC_UNICAST_VNIC_PRIMARY 0x0008
-#define MAC_UNICAST_TAG_DISABLE 0x0010
-#define MAC_UNICAST_STRIP_DISABLE 0x0020
-#define MAC_UNICAST_DISABLE_TX_VID_CHECK 0x0040
-
-/* flags passed to mac_client_open */
-#define MAC_OPEN_FLAGS_IS_VNIC 0x0001
-#define MAC_OPEN_FLAGS_EXCLUSIVE 0x0002
-#define MAC_OPEN_FLAGS_IS_AGGR_PORT 0x0004
-#define MAC_OPEN_FLAGS_NO_HWRINGS 0x0008
-#define MAC_OPEN_FLAGS_SHARES_DESIRED 0x0010
-#define MAC_OPEN_FLAGS_USE_DATALINK_NAME 0x0020
-#define MAC_OPEN_FLAGS_REQ_HWRINGS 0x0040
-#define MAC_OPEN_FLAGS_MULTI_PRIMARY 0x0080
-
-/* flags passed to mac_client_close */
-#define MAC_CLOSE_FLAGS_IS_VNIC 0x0001
-#define MAC_CLOSE_FLAGS_EXCLUSIVE 0x0002
-#define MAC_CLOSE_FLAGS_IS_AGGR_PORT 0x0004
-
-/* flags passed to mac_promisc_add() */
-#define MAC_PROMISC_FLAGS_NO_TX_LOOP 0x0001
-#define MAC_PROMISC_FLAGS_NO_PHYS 0x0002
-#define MAC_PROMISC_FLAGS_VLAN_TAG_STRIP 0x0004
-#define MAC_PROMISC_FLAGS_NO_COPY 0x0008
-
-/* flags passed to mac_tx() */
-#define MAC_DROP_ON_NO_DESC 0x01 /* freemsg() if no tx descs */
-#define MAC_TX_NO_ENQUEUE 0x02 /* don't enqueue mblks if not xmit'ed */
-#define MAC_TX_NO_HOLD 0x04 /* don't bump the active Tx count */
-
-extern int mac_client_open(mac_handle_t, mac_client_handle_t *, char *,
- uint16_t);
-extern void mac_client_close(mac_client_handle_t, uint16_t);
-
-extern int mac_unicast_add(mac_client_handle_t, uint8_t *, uint16_t,
- mac_unicast_handle_t *, uint16_t, mac_diag_t *);
-extern int mac_unicast_add_set_rx(mac_client_handle_t, uint8_t *, uint16_t,
- mac_unicast_handle_t *, uint16_t, mac_diag_t *, mac_rx_t, void *);
-extern int mac_unicast_remove(mac_client_handle_t, mac_unicast_handle_t);
-
-extern int mac_multicast_add(mac_client_handle_t, const uint8_t *);
-extern void mac_multicast_remove(mac_client_handle_t, const uint8_t *);
-
-extern void mac_rx_set(mac_client_handle_t, mac_rx_t, void *);
-extern void mac_rx_clear(mac_client_handle_t);
-extern mac_tx_cookie_t mac_tx(mac_client_handle_t, mblk_t *,
- uintptr_t, uint16_t, mblk_t **);
-extern boolean_t mac_tx_is_flow_blocked(mac_client_handle_t, mac_tx_cookie_t);
-extern uint64_t mac_client_stat_get(mac_client_handle_t, uint_t);
-
-extern int mac_promisc_add(mac_client_handle_t, mac_client_promisc_type_t,
- mac_rx_t, void *, mac_promisc_handle_t *, uint16_t);
-extern void mac_promisc_remove(mac_promisc_handle_t);
-
-extern mac_notify_handle_t mac_notify_add(mac_handle_t, mac_notify_t, void *);
-extern int mac_notify_remove(mac_notify_handle_t, boolean_t);
-extern void mac_notify_remove_wait(mac_handle_t);
-extern int mac_rename_primary(mac_handle_t, const char *);
-extern char *mac_client_name(mac_client_handle_t);
-
-extern int mac_open(const char *, mac_handle_t *);
-extern void mac_close(mac_handle_t);
-extern uint64_t mac_stat_get(mac_handle_t, uint_t);
-
-extern int mac_unicast_primary_set(mac_handle_t, const uint8_t *);
-extern void mac_unicast_primary_get(mac_handle_t, uint8_t *);
-extern void mac_unicast_primary_info(mac_handle_t, char *, boolean_t *);
-
-extern boolean_t mac_dst_get(mac_handle_t, uint8_t *);
-
-extern int mac_addr_random(mac_client_handle_t, uint_t, uint8_t *,
- mac_diag_t *);
-
-extern int mac_addr_factory_reserve(mac_client_handle_t, int *);
-extern void mac_addr_factory_release(mac_client_handle_t, uint_t);
-extern void mac_addr_factory_value(mac_handle_t, int, uchar_t *, uint_t *,
- char *, boolean_t *);
-extern uint_t mac_addr_factory_num(mac_handle_t);
-
-extern mac_tx_notify_handle_t mac_client_tx_notify(mac_client_handle_t,
- mac_tx_notify_t, void *);
-
-extern int mac_set_resources(mac_handle_t, mac_resource_props_t *);
-extern void mac_get_resources(mac_handle_t, mac_resource_props_t *);
-extern int mac_client_set_resources(mac_client_handle_t,
- mac_resource_props_t *);
-extern void mac_client_get_resources(mac_client_handle_t,
- mac_resource_props_t *);
-
-/* bridging-related interfaces */
-extern int mac_set_pvid(mac_handle_t, uint16_t);
-extern uint16_t mac_get_pvid(mac_handle_t);
-extern uint32_t mac_get_llimit(mac_handle_t);
-extern uint32_t mac_get_ldecay(mac_handle_t);
-
-extern int mac_share_capable(mac_handle_t);
-extern int mac_share_bind(mac_client_handle_t, uint64_t, uint64_t *);
-extern void mac_share_unbind(mac_client_handle_t);
-
-extern int mac_set_mtu(mac_handle_t, uint_t, uint_t *);
-
-extern uint_t mac_hwgrp_num(mac_handle_t);
-extern void mac_get_hwgrp_info(mac_handle_t, int, uint_t *, uint_t *,
- uint_t *, uint_t *, char *);
-
-extern uint32_t mac_no_notification(mac_handle_t);
-extern int mac_set_prop(mac_handle_t, mac_prop_t *, void *, uint_t);
-extern int mac_get_prop(mac_handle_t, mac_prop_t *, void *, uint_t, uint_t *);
-
-extern boolean_t mac_is_vnic(mac_handle_t);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_MAC_CLIENT_H */
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client_priv.h b/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client_priv.h
deleted file mode 100644
index 19ae1d057..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client_priv.h
+++ /dev/null
@@ -1,156 +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 2009-2010 Oracle Corporation. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * This file contains *private* MAC API definitions. This header file
- * should only be included by kernel components which are part of the
- * GLDv3 stack (dld, dls, aggr, softmac).
- */
-
-#ifndef _SYS_MAC_CLIENT_PRIV_H
-#define _SYS_MAC_CLIENT_PRIV_H
-
-#include <sys/mac.h>
-#include <sys/mac_flow.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _KERNEL
-
-#ifdef DEBUG
-#define MAC_PERIM_HELD(mph) mac_perim_held(mph)
-#else
-#define MAC_PERIM_HELD(mph)
-#endif
-
-extern boolean_t mac_rx_bypass_set(mac_client_handle_t, mac_direct_rx_t,
- void *);
-extern void mac_rx_bypass_enable(mac_client_handle_t);
-extern void mac_rx_bypass_disable(mac_client_handle_t);
-
-extern const mac_info_t *mac_info(mac_handle_t);
-extern boolean_t mac_info_get(const char *, mac_info_t *);
-extern boolean_t mac_promisc_get(mac_handle_t);
-
-extern int mac_start(mac_handle_t);
-extern void mac_stop(mac_handle_t);
-
-extern void mac_ioctl(mac_handle_t, queue_t *, mblk_t *);
-extern link_state_t mac_link_get(mac_handle_t);
-extern void mac_resource_set(mac_client_handle_t, mac_resource_add_t, void *);
-extern dev_info_t *mac_devinfo_get(mac_handle_t);
-extern void *mac_driver(mac_handle_t);
-extern boolean_t mac_capab_get(mac_handle_t, mac_capab_t, void *);
-extern boolean_t mac_sap_verify(mac_handle_t, uint32_t, uint32_t *);
-extern mblk_t *mac_header(mac_handle_t, const uint8_t *, uint32_t, mblk_t *,
- size_t);
-extern int mac_header_info(mac_handle_t, mblk_t *, mac_header_info_t *);
-extern int mac_vlan_header_info(mac_handle_t, mblk_t *, mac_header_info_t *);
-extern mblk_t *mac_header_cook(mac_handle_t, mblk_t *);
-extern mblk_t *mac_header_uncook(mac_handle_t, mblk_t *);
-
-extern void mac_resource_set_common(mac_client_handle_t,
- mac_resource_add_t, mac_resource_remove_t, mac_resource_quiesce_t,
- mac_resource_restart_t, mac_resource_bind_t, void *);
-
-extern void mac_perim_enter_by_mh(mac_handle_t, mac_perim_handle_t *);
-extern int mac_perim_enter_by_macname(const char *, mac_perim_handle_t *);
-extern int mac_perim_enter_by_linkid(datalink_id_t, mac_perim_handle_t *);
-extern void mac_perim_exit(mac_perim_handle_t);
-extern boolean_t mac_perim_held(mac_handle_t);
-
-extern uint16_t mac_client_vid(mac_client_handle_t);
-extern int mac_vnic_unicast_set(mac_client_handle_t, const uint8_t *);
-extern boolean_t mac_client_is_vlan_vnic(mac_client_handle_t);
-
-extern void mac_client_poll_enable(mac_client_handle_t);
-extern void mac_client_poll_disable(mac_client_handle_t);
-
-extern int mac_resource_ctl_set(mac_client_handle_t, mac_resource_props_t *);
-extern void mac_resource_ctl_get(mac_client_handle_t, mac_resource_props_t *);
-
-/*
- * Flow-related APIs for MAC clients.
- */
-
-extern void mac_link_init_flows(mac_client_handle_t);
-extern void mac_link_release_flows(mac_client_handle_t);
-extern int mac_link_flow_add(datalink_id_t, char *, flow_desc_t *,
- mac_resource_props_t *);
-extern int mac_link_flow_remove(char *);
-extern int mac_link_flow_modify(char *, mac_resource_props_t *);
-extern boolean_t mac_link_has_flows(mac_client_handle_t);
-
-typedef struct {
- char fi_flow_name[MAXFLOWNAMELEN];
- datalink_id_t fi_link_id;
- flow_desc_t fi_flow_desc;
- mac_resource_props_t fi_resource_props;
-} mac_flowinfo_t;
-
-extern int mac_link_flow_walk(datalink_id_t,
- int (*)(mac_flowinfo_t *, void *), void *);
-extern int mac_link_flow_info(char *, mac_flowinfo_t *);
-
-extern void *mac_tx_hold(mac_client_handle_t);
-extern void mac_tx_rele(mac_client_handle_t, void *);
-extern void mac_rx_client_quiesce(mac_client_handle_t);
-extern void mac_rx_client_restart(mac_client_handle_t);
-extern void mac_srs_perm_quiesce(mac_client_handle_t, boolean_t);
-extern int mac_hwrings_get(mac_client_handle_t, mac_group_handle_t *,
- mac_ring_handle_t *, mac_ring_type_t);
-extern void mac_hwring_setup(mac_ring_handle_t, mac_resource_handle_t);
-extern void mac_hwring_teardown(mac_ring_handle_t);
-extern int mac_hwring_disable_intr(mac_ring_handle_t);
-extern int mac_hwring_enable_intr(mac_ring_handle_t);
-extern int mac_hwring_start(mac_ring_handle_t);
-extern void mac_hwring_stop(mac_ring_handle_t);
-extern mblk_t *mac_hwring_poll(mac_ring_handle_t, int);
-#define MAC_HWRING_POLL(ring, bytes) \
- (((ring)->mr_info.mri_poll) \
- ((ring)->mr_info.mri_driver, (bytes)))
-
-extern int mac_hwgroup_addmac(mac_group_handle_t, const uint8_t *);
-extern int mac_hwgroup_remmac(mac_group_handle_t, const uint8_t *);
-
-extern void mac_set_upper_mac(mac_client_handle_t, mac_handle_t);
-
-extern int mac_mark_exclusive(mac_handle_t);
-extern void mac_unmark_exclusive(mac_handle_t);
-
-extern int32_t mac_client_intr_cpu(mac_client_handle_t);
-extern void mac_client_set_intr_cpu(void *, mac_client_handle_t, int32_t);
-extern void *mac_get_devinfo(mac_handle_t);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_MAC_CLIENT_PRIV_H */
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_provider.h b/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_provider.h
deleted file mode 100644
index 6960f9229..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_provider.h
+++ /dev/null
@@ -1,498 +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 2009-2010 Oracle Corporation. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_MAC_PROVIDER_H
-#define _SYS_MAC_PROVIDER_H
-
-#include <sys/types.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/stream.h>
-#include <sys/mkdev.h>
-#include <sys/mac_flow.h>
-#include <sys/mac.h>
-
-/*
- * MAC Provider Interface
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * MAC version identifier. This is used by mac_alloc() mac_register() to
- * verify that incompatible drivers don't register.
- */
-#define MAC_VERSION 0x2
-
-/*
- * Opaque handle types
- */
-typedef struct __mac_rule_handle *mac_rule_handle_t;
-
-/*
- * Statistics
- */
-
-#define XCVR_UNDEFINED 0
-#define XCVR_NONE 1
-#define XCVR_10 2
-#define XCVR_100T4 3
-#define XCVR_100X 4
-#define XCVR_100T2 5
-#define XCVR_1000X 6
-#define XCVR_1000T 7
-
-#ifdef _KERNEL
-
-/*
- * Definitions for MAC Drivers Capabilities
- */
-/*
- * MAC layer capabilities. These capabilities are handled by the drivers'
- * mc_capab_get() callbacks. Some capabilities require the driver to fill
- * in a given data structure, and others are simply boolean capabilities.
- * Note that capability values must be powers of 2 so that consumers and
- * providers of this interface can keep track of which capabilities they
- * care about by keeping a bitfield of these things around somewhere.
- */
-typedef enum {
- /*
- * Capabilities reserved for internal use only
- */
- MAC_CAPAB_VNIC = 0x0001, /* data is mac_capab_vnic_t */
- MAC_CAPAB_ANCHOR_VNIC = 0x0002, /* boolean only, no data */
- MAC_CAPAB_AGGR = 0x0004, /* data is mac_capab_aggr_t */
- MAC_CAPAB_NO_NATIVEVLAN = 0x0008, /* boolean only, no data */
- MAC_CAPAB_NO_ZCOPY = 0x0010, /* boolean only, no data */
- MAC_CAPAB_LEGACY = 0x0020, /* data is mac_capab_legacy_t */
- MAC_CAPAB_VRRP = 0x0040, /* data is mac_capab_vrrp_t */
-
- /*
- * Public Capabilities
- */
- MAC_CAPAB_HCKSUM = 0x0100, /* data is a uint32_t */
- MAC_CAPAB_LSO = 0x0200, /* data is mac_capab_lso_t */
- MAC_CAPAB_RINGS = 0x0400, /* data is mac_capab_rings_t */
- MAC_CAPAB_MULTIFACTADDR = 0x0800, /* mac_data_multifactaddr_t */
- MAC_CAPAB_SHARES = 0x1000 /* data is mac_capab_share_t */
-
- /* add new capabilities here */
-} mac_capab_t;
-
-
-/*
- * LSO capability
- */
-typedef struct lso_basic_tcp_ipv4_s {
- t_uscalar_t lso_max; /* maximum payload */
-} lso_basic_tcp_ipv4_t;
-
-/*
- * Currently supported flags for LSO.
- */
-#define LSO_TX_BASIC_TCP_IPV4 0x01 /* TCP LSO capability */
-
-/*
- * Future LSO capabilities can be added at the end of the mac_capab_lso_t.
- * When such capability is added to the GLDv3 framework, the size of the
- * mac_capab_lso_t it allocates and passes to the drivers increases. Older
- * drivers wil access only the (upper) sections of that structure, that is the
- * sections carrying the capabilities they understand. This ensures the
- * interface can be safely extended in a binary compatible way.
- */
-typedef struct mac_capab_lso_s {
- t_uscalar_t lso_flags;
- lso_basic_tcp_ipv4_t lso_basic_tcp_ipv4;
- /* Add future lso capabilities here */
-} mac_capab_lso_t;
-
-/*
- * Multiple Factory MAC Addresses Capability
- */
-typedef struct mac_capab_multifactaddr_s {
- /*
- * Number of factory addresses
- */
- uint_t mcm_naddr;
-
- /*
- * Callbacks to query all the factory addresses.
- */
- void (*mcm_getaddr)(void *, uint_t, uint8_t *);
-} mac_capab_multifactaddr_t;
-
-/*
- * Info and callbacks of legacy devices.
- */
-typedef struct mac_capab_legacy_s {
- /*
- * Notifications that the legacy device does not support.
- */
- uint32_t ml_unsup_note;
- /*
- * dev_t of the legacy device; can be held to force attach.
- */
- dev_t ml_dev;
- boolean_t (*ml_active_set)(void *);
- void (*ml_active_clear)(void *);
- int (*ml_fastpath_disable)(void *);
- void (*ml_fastpath_enable)(void *);
-} mac_capab_legacy_t;
-
-/*
- * MAC driver entry point types.
- */
-typedef int (*mac_getstat_t)(void *, uint_t, uint64_t *);
-typedef int (*mac_start_t)(void *);
-typedef void (*mac_stop_t)(void *);
-typedef int (*mac_setpromisc_t)(void *, boolean_t);
-typedef int (*mac_multicst_t)(void *, boolean_t, const uint8_t *);
-typedef int (*mac_unicst_t)(void *, const uint8_t *);
-typedef void (*mac_ioctl_t)(void *, queue_t *, mblk_t *);
-typedef void (*mac_resources_t)(void *);
-typedef mblk_t *(*mac_tx_t)(void *, mblk_t *);
-typedef boolean_t (*mac_getcapab_t)(void *, mac_capab_t, void *);
-typedef int (*mac_open_t)(void *);
-typedef void (*mac_close_t)(void *);
-typedef int (*mac_set_prop_t)(void *, const char *, mac_prop_id_t,
- uint_t, const void *);
-typedef int (*mac_get_prop_t)(void *, const char *, mac_prop_id_t,
- uint_t, uint_t, void *, uint_t *);
-
-/*
- * Drivers must set all of these callbacks except for mc_resources,
- * mc_ioctl, and mc_getcapab, which are optional. If any of these optional
- * callbacks are set, their appropriate flags must be set in mc_callbacks.
- * Any future additions to this list must also be accompanied by an
- * associated mc_callbacks flag so that the framework can grow without
- * affecting the binary compatibility of the interface.
- */
-typedef struct mac_callbacks_s {
- uint_t mc_callbacks; /* Denotes which callbacks are set */
- mac_getstat_t mc_getstat; /* Get the value of a statistic */
- mac_start_t mc_start; /* Start the device */
- mac_stop_t mc_stop; /* Stop the device */
- mac_setpromisc_t mc_setpromisc; /* Enable or disable promiscuous mode */
- mac_multicst_t mc_multicst; /* Enable or disable a multicast addr */
- mac_unicst_t mc_unicst; /* Set the unicast MAC address */
- mac_tx_t mc_tx; /* Transmit a packet */
- mac_ioctl_t mc_ioctl; /* Process an unknown ioctl */
- mac_getcapab_t mc_getcapab; /* Get capability information */
- mac_open_t mc_open; /* Open the device */
- mac_close_t mc_close; /* Close the device */
- mac_set_prop_t mc_setprop;
- mac_get_prop_t mc_getprop;
-} mac_callbacks_t;
-
-typedef struct mac_priv_prop_s {
- char mpp_name[MAXLINKPROPNAME];
- uint_t mpp_flags;
-} mac_priv_prop_t;
-
-/*
- * Virtualization Capabilities
- */
-/*
- * The ordering of entries below is important. MAC_HW_CLASSIFIER
- * is the cutoff below which are entries which don't depend on
- * H/W. MAC_HW_CLASSIFIER and entries after that are cases where
- * H/W has been updated through add/modify/delete APIs.
- */
-typedef enum {
- MAC_NO_CLASSIFIER = 0,
- MAC_SW_CLASSIFIER,
- MAC_HW_CLASSIFIER
-} mac_classify_type_t;
-
-typedef void (*mac_rx_func_t)(void *, mac_resource_handle_t, mblk_t *,
- boolean_t);
-
-/*
- * The virtualization level conveys the extent of the NIC hardware assistance
- * for traffic steering employed for virtualization:
- *
- * MAC_VIRT_NONE: No assist for v12n.
- *
- * MAC_VIRT_LEVEL1: Multiple Rx rings with MAC address level
- * classification between groups of rings.
- * Requires the support of the MAC_CAPAB_RINGS
- * capability.
- *
- * MAC_VIRT_HIO: Hybrid I/O capable MAC. Require the support
- * of the MAC_CAPAB_SHARES capability.
- *
- * MAC_VIRT_SERIALIZE: Temporary flag *ONLY* for nxge. Mac layer
- * uses this to enable mac Tx serializer on
- * outbound traffic and to always enqueue
- * incoming traffic on Rx soft rings in mac.
- */
-#define MAC_VIRT_NONE 0x0
-#define MAC_VIRT_LEVEL1 0x1
-#define MAC_VIRT_HIO 0x2
-#define MAC_VIRT_SERIALIZE 0x4
-
-typedef enum {
- MAC_RING_TYPE_RX = 1, /* Receive ring */
- MAC_RING_TYPE_TX /* Transmit ring */
-} mac_ring_type_t;
-
-#define MAX_RINGS_PER_GROUP 128
-
-/*
- * Grouping type of a ring group
- *
- * MAC_GROUP_TYPE_STATIC: The ring group can not be re-grouped.
- * MAC_GROUP_TYPE_DYNAMIC: The ring group support dynamic re-grouping
- */
-typedef enum {
- MAC_GROUP_TYPE_STATIC = 1, /* Static ring group */
- MAC_GROUP_TYPE_DYNAMIC /* Dynamic ring group */
-} mac_group_type_t;
-
-typedef struct __mac_ring_driver *mac_ring_driver_t;
-typedef struct __mac_group_driver *mac_group_driver_t;
-
-typedef struct mac_ring_info_s mac_ring_info_t;
-typedef struct mac_group_info_s mac_group_info_t;
-
-typedef void (*mac_get_ring_t)(void *, mac_ring_type_t, const int, const int,
- mac_ring_info_t *, mac_ring_handle_t);
-typedef void (*mac_get_group_t)(void *, mac_ring_type_t, const int,
- mac_group_info_t *, mac_group_handle_t);
-
-typedef void (*mac_group_add_ring_t)(mac_group_driver_t,
- mac_ring_driver_t, mac_ring_type_t);
-typedef void (*mac_group_rem_ring_t)(mac_group_driver_t,
- mac_ring_driver_t, mac_ring_type_t);
-
-/*
- * Multiple Rings Capability
- */
-typedef struct mac_capab_rings_s {
- mac_ring_type_t mr_type; /* Ring type: Rx vs Tx */
- mac_group_type_t mr_group_type; /* Dynamic vs static grouping */
- uint_t mr_rnum; /* Number of rings */
- uint_t mr_gnum; /* Number of ring groups */
- mac_get_ring_t mr_rget; /* Get ring from driver */
- mac_get_group_t mr_gget; /* Get ring group from driver */
- mac_group_add_ring_t mr_gaddring; /* Add ring into a group */
- mac_group_rem_ring_t mr_gremring; /* Remove ring from a group */
-} mac_capab_rings_t;
-
-/*
- * Common ring functions and driver interfaces
- */
-typedef int (*mac_ring_start_t)(mac_ring_driver_t, uint64_t);
-typedef void (*mac_ring_stop_t)(mac_ring_driver_t);
-
-typedef mblk_t *(*mac_ring_send_t)(void *, mblk_t *);
-typedef mblk_t *(*mac_ring_poll_t)(void *, int);
-
-typedef struct mac_ring_info_s {
- mac_ring_driver_t mri_driver;
- mac_ring_start_t mri_start;
- mac_ring_stop_t mri_stop;
- mac_intr_t mri_intr;
- union {
- mac_ring_send_t send;
- mac_ring_poll_t poll;
- } mrfunion;
-} mac_ring_info_s;
-
-#define mri_tx mrfunion.send
-#define mri_poll mrfunion.poll
-
-typedef int (*mac_group_start_t)(mac_group_driver_t);
-typedef void (*mac_group_stop_t)(mac_group_driver_t);
-typedef int (*mac_add_mac_addr_t)(void *, const uint8_t *);
-typedef int (*mac_rem_mac_addr_t)(void *, const uint8_t *);
-
-struct mac_group_info_s {
- mac_group_driver_t mgi_driver; /* Driver reference */
- mac_group_start_t mgi_start; /* Start the group */
- mac_group_stop_t mgi_stop; /* Stop the group */
- uint_t mgi_count; /* Count of rings */
- mac_intr_t mgi_intr; /* Optional per-group intr */
-
- /* Only used for rx groups */
- mac_add_mac_addr_t mgi_addmac; /* Add a MAC address */
- mac_rem_mac_addr_t mgi_remmac; /* Remove a MAC address */
-};
-
-/*
- * Share management functions.
- */
-typedef uint64_t mac_share_handle_t;
-
-/*
- * Allocate and free a share. Returns ENOSPC if all shares have been
- * previously allocated.
- */
-typedef int (*mac_alloc_share_t)(void *, mac_share_handle_t *);
-typedef void (*mac_free_share_t)(mac_share_handle_t);
-
-/*
- * Bind and unbind a share. Binding a share allows a domain
- * to have direct access to the groups and rings associated with
- * that share.
- */
-typedef int (*mac_bind_share_t)(mac_share_handle_t, uint64_t, uint64_t *);
-typedef void (*mac_unbind_share_t)(mac_share_handle_t);
-
-/*
- * Return information on about a share.
- */
-typedef void (*mac_share_query_t)(mac_share_handle_t, mac_ring_type_t,
- mac_ring_handle_t *, uint_t *);
-
-/*
- * Basic idea, bind previously created ring groups to shares
- * for them to be exported (or shared) by another domain.
- * These interfaces bind/unbind the ring group to a share.
- * The groups and their rings will be shared with the guest
- * as soon as the share is bound.
- */
-typedef int (*mac_share_add_group_t)(mac_share_handle_t,
- mac_group_driver_t);
-typedef int (*mac_share_rem_group_t)(mac_share_handle_t,
- mac_group_driver_t);
-
-typedef struct mac_capab_share_s {
- uint_t ms_snum; /* Number of shares (vr's) */
- void *ms_handle; /* Handle to driver. */
- mac_alloc_share_t ms_salloc; /* Get a share from driver. */
- mac_free_share_t ms_sfree; /* Return a share to driver. */
- mac_share_add_group_t ms_sadd; /* Add a group to the share. */
- mac_share_rem_group_t ms_sremove; /* Remove group from share. */
- mac_share_query_t ms_squery; /* Query share constraints */
- mac_bind_share_t ms_sbind; /* Bind a share */
- mac_unbind_share_t ms_sunbind; /* Unbind a share */
-} mac_capab_share_t;
-
-typedef struct mac_capab_vrrp_s {
- /* IPv6 or IPv4? */
- int mcv_af;
-} mac_capab_vrrp_t;
-
-/*
- * MAC registration interface
- */
-typedef struct mac_register_s {
- uint_t m_version; /* set by mac_alloc() */
- const char *m_type_ident;
- void *m_driver; /* Driver private data */
- dev_info_t *m_dip;
- uint_t m_instance;
- uint8_t *m_src_addr;
- uint8_t *m_dst_addr;
- mac_callbacks_t *m_callbacks;
- uint_t m_min_sdu;
- uint_t m_max_sdu;
- void *m_pdata;
- size_t m_pdata_size;
- uint32_t m_margin;
- mac_priv_prop_t *m_priv_props;
- size_t m_priv_prop_count;
- uint32_t m_v12n; /* Virtualization level */
-} mac_register_t;
-
-/*
- * Flags for mc_callbacks. Requiring drivers to set the flags associated
- * with optional callbacks initialized in the structure allows the mac
- * module to add optional callbacks in the future without requiring drivers
- * to recompile.
- */
-#define MC_IOCTL 0x001
-#define MC_GETCAPAB 0x002
-#define MC_OPEN 0x004
-#define MC_CLOSE 0x008
-#define MC_SETPROP 0x010
-#define MC_GETPROP 0x020
-
-/*
- * Driver interface functions.
- */
-extern void mac_sdu_get(mac_handle_t, uint_t *, uint_t *);
-extern int mac_maxsdu_update(mac_handle_t, uint_t);
-
-extern mac_register_t *mac_alloc(uint_t);
-extern void mac_free(mac_register_t *);
-extern int mac_register(mac_register_t *, mac_handle_t *);
-extern int mac_disable_nowait(mac_handle_t);
-extern int mac_disable(mac_handle_t);
-extern int mac_unregister(mac_handle_t);
-extern void mac_rx(mac_handle_t, mac_resource_handle_t,
- mblk_t *);
-extern void mac_rx_ring(mac_handle_t, mac_ring_handle_t,
- mblk_t *, uint64_t);
-extern void mac_link_update(mac_handle_t, link_state_t);
-extern void mac_link_redo(mac_handle_t, link_state_t);
-extern void mac_unicst_update(mac_handle_t,
- const uint8_t *);
-extern void mac_dst_update(mac_handle_t, const uint8_t *);
-extern void mac_tx_update(mac_handle_t);
-extern void mac_tx_ring_update(mac_handle_t,
- mac_ring_handle_t);
-extern void mac_capab_update(mac_handle_t);
-extern int mac_pdata_update(mac_handle_t, void *,
- size_t);
-extern void mac_multicast_refresh(mac_handle_t,
- mac_multicst_t, void *, boolean_t);
-extern void mac_unicst_refresh(mac_handle_t, mac_unicst_t,
- void *);
-extern void mac_promisc_refresh(mac_handle_t,
- mac_setpromisc_t, void *);
-extern boolean_t mac_margin_update(mac_handle_t, uint32_t);
-extern void mac_margin_get(mac_handle_t, uint32_t *);
-extern int mac_margin_remove(mac_handle_t, uint32_t);
-extern int mac_margin_add(mac_handle_t, uint32_t *,
- boolean_t);
-extern void mac_init_ops(struct dev_ops *, const char *);
-extern void mac_fini_ops(struct dev_ops *);
-extern int mac_devt_to_instance(dev_t);
-extern minor_t mac_private_minor(void);
-
-extern mactype_register_t *mactype_alloc(uint_t);
-extern void mactype_free(mactype_register_t *);
-extern int mactype_register(mactype_register_t *);
-extern int mactype_unregister(const char *);
-
-extern boolean_t mac_unicst_verify(mac_handle_t,
- const uint8_t *, uint_t);
-
-extern int mac_group_add_ring(mac_group_handle_t, int);
-extern void mac_group_rem_ring(mac_group_handle_t,
- mac_ring_handle_t);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_MAC_PROVIDER_H */
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxbow.conf b/src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxbow.conf
new file mode 100644
index 000000000..45239ad5c
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxbow.conf
@@ -0,0 +1,21 @@
+#
+# Solaris Host VBoxBow (Crossbow) Configuration
+#
+# Copyright (C) 2008-2010 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+# This needs to go into /platform/i86pc/kernel/drv,
+# while the 64-bit driver object goes into the amd64
+# subdirectory (32-bit drivers goes into the same
+# directory).
+#
+name="vboxbow" parent="pseudo" instance=0;
+
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h
deleted file mode 100644
index 167318f86..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h
+++ /dev/null
@@ -1,501 +0,0 @@
-/* $Id: VBoxNetFltCommon-win.h $ */
-/** @file
- * VBoxNetFltCommon.h - Network Filter Driver (Host), Windows Specific Code. Common header with commonly used defines and decls
- */
-
-/*
- * Copyright (C) 2008 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.
- */
-/*
- * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
- * Copyright (c) 1993-1999, Microsoft Corporation
- */
-
-#ifndef ___VBoxNetFltCommon_win_h___
-#define ___VBoxNetFltCommon_win_h___
-
-//#define NTSTRSAFE_LIB
-
-#ifdef DEBUG
-//# define DEBUG_NETFLT_PACKETS
-# ifndef DEBUG_misha
-# define DEBUG_NETFLT_NOASSERT
-# endif
-/* # define DEBUG_NETFLT_LOOPBACK */
-
-/* receive logic has several branches */
-/* the DEBUG_NETFLT_RECV* macros used to debug the ProtocolReceive callback
- * which is typically not used in case the underlying miniport indicates the packets with NdisMIndicateReceivePacket
- * the best way to debug the ProtocolReceive (which in turn has several branches) is to enable the DEBUG_NETFLT_RECV
- * one by one in the below order, i.e.
- * first DEBUG_NETFLT_RECV
- * then DEBUG_NETFLT_RECV + DEBUG_NETFLT_RECV_NOPACKET */
-//# define DEBUG_NETFLT_RECV
-//# define DEBUG_NETFLT_RECV_NOPACKET
-//# define DEBUG_NETFLT_RECV_TRANSFERDATA
-
-//#define DEBUG_NETFLT_USE_EXALLOC
-#endif
-
-#define LOG_GROUP LOG_GROUP_NET_FLT_DRV
-
-#include <VBox/intnet.h>
-#include <VBox/log.h>
-#include <VBox/err.h>
-#include <VBox/version.h>
-#include <iprt/initterm.h>
-#include <iprt/assert.h>
-#include <iprt/spinlock.h>
-#include <iprt/semaphore.h>
-#include <iprt/process.h>
-#include <iprt/alloc.h>
-#include <iprt/alloca.h>
-#include <iprt/time.h>
-#include <iprt/net.h>
-
-RT_C_DECLS_BEGIN
-#include <ndis.h>
-RT_C_DECLS_END
-
-
-
-#define VBOXNETFLT_OS_SPECFIC 1
-
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
-# define VBOXNETFLT_PROTOCOL_NAME L"VBoxNetFltPt"
-#else
-# ifndef VBOXNETADP
-# define VBOXNETFLT_PROTOCOL_NAME L"VBoxNetFlt"
-
-/** this is to support ioctl interface */
-# define LINKNAME_STRING L"\\DosDevices\\Global\\VBoxNetFlt"
-# define NTDEVICE_STRING L"\\Device\\VBoxNetFlt"
-# else
-# define LINKNAME_STRING L"\\DosDevices\\Global\\VBoxNetAdp"
-# define NTDEVICE_STRING L"\\Device\\VBoxNetAdp"
-# endif
-//# define VBOXNETFLT_WIN_IOCTL_INIT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_WRITE_ACCESS)
-//# define VBOXNETFLT_WIN_IOCTL_FINI CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_NEITHER, FILE_WRITE_ACCESS)
-#endif
-
-/** version
- * NOTE: we are NOT using NDIS 5.1 features now, the code under "#ifdef NDIS51xxx" is not tested and may not work and should be removed soon */
-#ifdef NDIS51_MINIPORT
-# define VBOXNETFLT_MAJOR_NDIS_VERSION 5
-# define VBOXNETFLT_MINOR_NDIS_VERSION 1
-#else
-# define VBOXNETFLT_MAJOR_NDIS_VERSION 5
-# define VBOXNETFLT_MINOR_NDIS_VERSION 0
-#endif
-
-#ifdef NDIS51
-# define VBOXNETFLT_PROT_MAJOR_NDIS_VERSION 5
-# define VBOXNETFLT_PROT_MINOR_NDIS_VERSION 0
-#else
-# define VBOXNETFLT_PROT_MAJOR_NDIS_VERSION 5
-# define VBOXNETFLT_PROT_MINOR_NDIS_VERSION 0
-#endif
-
-/** advance declaration */
-typedef struct _ADAPT ADAPT, *PADAPT;
-
-typedef struct VBOXNETFLTINS *PVBOXNETFLTINS;
-
-/** configuration */
-
-/** received packets queue size. the queue is used when the driver is working in a pass-thru mode */
-#define MAX_RECEIVE_PACKET_ARRAY_SIZE 40
-
-/** Ndis Packet pool settings
- * these are applied to both receive and send packet pools */
-#define MAX_PACKET_POOL_SIZE 0x0000FFFF
-#define MIN_PACKET_POOL_SIZE 0x000000FF
-
-/** packet queue size used when the driver is working in the "active" mode */
-#define PACKET_INFO_POOL_SIZE 0x0000FFFF
-
-#ifndef VBOXNETADP
-/** memory tag used for memory allocations
- * (VBNF stands for VBox NetFlt) */
-# define MEM_TAG 'FNBV'
-#else
-/** memory tag used for memory allocations
- * (VBNA stands for VBox NetAdp) */
-# define MEM_TAG 'ANBV'
-#endif
-
-/** receive and transmit Ndis buffer pool size */
-#define TX_BUFFER_POOL_SIZE 128
-#define RX_BUFFER_POOL_SIZE 128
-
-#define ETH_HEADER_SIZE 14
-
-#define PACKET_QUEUE_SG_SEGS_ALLOC 32
-
-#define VBOX_NETFLT_PACKET_HEADER_MATCH_SIZE 24
-
-#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
-# define VBOXNETFLT_PACKETMATCH_LENGTH (ETH_HEADER_SIZE + 2)
-#endif
-
-#ifdef VBOXNETADP
-#define VBOXNETADP_HEADER_SIZE 14
-#define VBOXNETADP_MAX_DATA_SIZE 1500
-#define VBOXNETADP_MAX_PACKET_SIZE VBOXNETADP_HEADER_SIZE + VBOXNETADP_MAX_DATA_SIZE
-#define VBOXNETADP_MIN_PACKET_SIZE 60
-#define VBOXNETADP_LINK_SPEED 1000000 //The unit of measurement is 100 bps, 100Mbps
-#define VBOXNETADP_MAX_LOOKAHEAD_SIZE VBOXNETADP_MAX_DATA_SIZE
-#define VBOXNETADP_VENDOR_ID 0x080027
-#define VBOXNETADP_VENDOR_DRIVER_VERSION 0x00010000
-#define VBOXNETADP_VENDOR_DESC "Sun"
-#define VBOXNETADP_MAX_MCAST_LIST 32
-#define VBOXNETADP_ETH_ADDRESS_LENGTH 6
-
-//#define VBOXNETADP_REPORT_DISCONNECTED
-#endif
-/* type defs */
-
-/** Flag specifying that the type of enqueued packet
- * if set the info contains the PINTNETSG packet
- * if clear the packet info contains the PNDIS_PACKET packet
- * Typically the packet queue we are maintaining contains PNDIS_PACKETs only,
- * however in case the underlying miniport indicates a packet with the NDIS_STATUS_RESOURCES status
- * we MUST return the packet back to the miniport immediately
- * this is why we are creating the INTNETSG, copying the ndis packet info there and enqueueing it */
-#define PACKET_SG 0x00000001
-
-/** the flag specifying that the packet source
- * if set the packet comes from the host (upperlying protocol)
- * if clear the packet comes from the wire (underlying miniport) */
-#define PACKET_SRC_HOST 0x00000002
-
-#ifndef VBOXNETFLT_NO_PACKET_QUEUE
-/** flag specifying the packet was originated by our driver
- * i.e. we could use it on our needs and should not return it
- * we are enqueueing "our" packets on ProtocolReceive call-back when
- * Ndis does not give us a receive packet (the driver below us has called NdisM..IndicateReceive)
- * this is supported for Ndis Packet only */
-#define PACKET_MINE 0x00000004
-
-/** flag passed to vboxNetFltWinQuEnqueuePacket specifying that the packet should be copied
- * this is supported for Ndis Packet only */
-#define PACKET_COPY 0x00000008
-#endif
-
-/** packet queue element containing the packet info */
-typedef struct _PACKET_INFO
-{
- /** list entry used for enqueueing the info */
- LIST_ENTRY ListEntry;
- /** pointer to the pool containing this packet info */
- struct _PACKET_INFO_POOL * pPool;
- /** flags describing the referenced packet. Contains PACKET_xxx flags (i.e. PACKET_SG, PACKET_SRC_HOST) */
- uint32_t fFlags;
- /** pointer to the packet this info represents */
- PVOID pPacket;
-}PACKET_INFO, *PPACKET_INFO;
-
-/* paranoid check to make sure the elements in the packet info array are properly aligned */
-C_ASSERT((sizeof(PACKET_INFO) & (sizeof(PVOID) - 1)) == 0);
-
-/** represents the packet queue */
-typedef LIST_ENTRY PACKET_QUEUE, *PPACKET_QUEUE;
-
-/*
- * we are using non-interlocked versions of LIST_ENTRY-related operations macros and synchronize
- * access to the queue and its elements by acquiring/releasing a spinlock using Ndis[Acquire,Release]Spinlock
- *
- * we are NOT using interlocked versions of insert/remove head/tail list functions because we need to iterate though
- * the queue elements as well as remove elements from the midle of the queue
- *
- * * @todo: it seems that we can switch to using interlocked versions of list-entry functions
- * since we have removed all functionality (mentioned above, i.e. queue elements iteration, etc.) that might prevent us from doing this
- */
-typedef struct _INTERLOCKED_PACKET_QUEUE
-{
- /** queue */
- PACKET_QUEUE Queue;
- /** queue lock */
- NDIS_SPIN_LOCK Lock;
-}INTERLOCKED_PACKET_QUEUE, *PINTERLOCKED_PACKET_QUEUE;
-
-typedef struct _SINGLE_LIST
-{
- /** queue */
- SINGLE_LIST_ENTRY Head;
- /** pointer to the list tail. used to enqueue elements to the tail of the list */
- PSINGLE_LIST_ENTRY pTail;
-} SINGLE_LIST, *PSINGLE_LIST;
-
-typedef struct _INTERLOCKED_SINGLE_LIST
-{
- /** queue */
- SINGLE_LIST List;
- /** queue lock */
- NDIS_SPIN_LOCK Lock;
-} INTERLOCKED_SINGLE_LIST, *PINTERLOCKED_SINGLE_LIST;
-
-/** packet info pool contains free packet info elements to be used for the packet queue
- * we are using the pool mechanism to allocate packet queue elements
- * the pool mechanism is pretty simple now, we are allocating a bunch of memory
- * for maintaining PACKET_INFO_POOL_SIZE queue elements and just returning null when the pool is exhausted
- * This mechanism seems to be enough for now since we are using PACKET_INFO_POOL_SIZE = 0xffff which is
- * the maximum size of packets the ndis packet pool supports */
-typedef struct _PACKET_INFO_POOL
-{
- /** free packet info queue */
- INTERLOCKED_PACKET_QUEUE Queue;
- /** memory bugger used by the pool */
- PVOID pBuffer;
-}PACKET_INFO_POOL, *PPACKET_INFO_POOL;
-
-typedef enum VBOXNETDEVOPSTATE
-{
- kVBoxNetDevOpState_InvalidValue = 0,
- kVBoxNetDevOpState_Initializing,
- kVBoxNetDevOpState_Initialized,
- kVBoxNetDevOpState_Deinitializing,
- kVBoxNetDevOpState_Deinitialized,
-
-} VBOXNETDEVOPSTATE;
-
-typedef enum VBOXADAPTSTATE
-{
- /** The usual invalid state. */
- kVBoxAdaptState_Invalid = 0,
- /** Initialization. */
- kVBoxAdaptState_Connecting,
- /** Connected fuly functional state */
- kVBoxAdaptState_Connected,
- /** Disconnecting */
- kVBoxAdaptState_Disconnecting,
- /** Disconnected */
- kVBoxAdaptState_Disconnected,
-} VBOXADAPTSTATE;
-
-/** structure used to maintain the state and reference count of the miniport and protocol */
-typedef struct _ADAPT_DEVICE
-{
- /** initialize state */
- VBOXNETDEVOPSTATE OpState;
- /** ndis power state */
- NDIS_DEVICE_POWER_STATE PowerState;
- /** reference count */
- uint32_t cReferences;
-/* NDIS_HANDLE hHandle; */
-} ADAPT_DEVICE, *PADAPT_DEVICE;
-
-/* packet filter processing mode constants */
-#define VBOXNETFLT_PFP_NETFLT 1
-#define VBOXNETFLT_PFP_PASSTHRU 2
-
-/** represents filter driver device context*/
-typedef struct _ADAPT
-{
-#ifndef VBOXNETADP
- /** handle the lower miniport */
- NDIS_HANDLE hBindingHandle;
- /** Protocol's Device state */
- ADAPT_DEVICE PTState;
-#endif
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- /** NDIS Handle to for miniport up-calls */
- NDIS_HANDLE hMiniportHandle;
- /** miniport device state */
- ADAPT_DEVICE MPState;
- /** ndis packet pool used for receives */
- NDIS_HANDLE hRecvPacketPoolHandle;
- /** ndis buffer pool used for receives */
- NDIS_HANDLE hRecvBufferPoolHandle;
-#ifndef VBOXNETADP
- /** This is used to wrap a request coming down to us.
- * This exploits the fact that requests are serialized down to us.*/
- NDIS_REQUEST Request;
- /** Ndis Request Bytes needed */
- PULONG BytesNeeded;
- /** Ndis Request Bytes Read or Written */
- PULONG BytesReadOrWritten;
-#else
- volatile ULONG cTxSuccess;
- volatile ULONG cRxSuccess;
- volatile ULONG cTxError;
- volatile ULONG cRxError;
-#endif
- /** driver bind adapter state. */
- VBOXADAPTSTATE enmState;
-#ifndef VBOXNETADP
- /** true if we should indicate the receive complete used by the ProtocolReceive mechanism.
- * We need to indicate it only with the ProtocolReceive + NdisMEthIndicateReceive path.
- * There is no guarantee in the docs that the ProtocolReceive & ProtocolReceiveComplete
- * for one transfer are called on one same CPU, however this is how the latest passthru
- * sample handles this
- * Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case
- * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber
- * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64
- * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */
- bool abIndicateRcvComplete[64];
-
- /** TRUE iff a request is pending at the miniport below */
- bool bOutstandingRequests;
- /** TRUE iff a request is queued at this IM miniport*/
- bool bQueuedRequest;
- /** @todo join all boolean states to one field treated as flags bitmap */
- /** true iff we are processing Set packet filter OID */
- uint8_t fProcessingPacketFilter;
- /** true iff the upper protocol filter cache was initialized */
- bool bUpperProtSetFilterInitialized;
- /** trus if the adapter is closing */
- bool bClosingAdapter;
- /** Pending transfer data packet queue (i.e. packets that were indicated as pending on NdisTransferData call */
- INTERLOCKED_SINGLE_LIST TransferDataList;
- /* mac options initialized on OID_GEN_MAC_OPTIONS */
- ULONG fMacOptions;
- /** For initializing the miniport edge */
- NDIS_STRING DeviceName;
- /** For blocking UnbindAdapter while an IM Init is in progress.*/
- NDIS_EVENT MiniportInitEvent;
- /** The last indicated media status */
- NDIS_STATUS LastIndicatedStatus;
- /** The latest suppressed media status */
- NDIS_STATUS LatestUnIndicateStatus;
- /** when working in the passthru mode the driver puts the received packets to this array
- * instead of passing them up immediately
- * we are flushing the packets on ProtocolReceiveComplete or when the underlying miniport
- * indicates NDIS_STATUS_RESOURCES or when this array is full */
- PNDIS_PACKET aReceivedPackets[MAX_RECEIVE_PACKET_ARRAY_SIZE];
- /** number of packets in the aReceivedPackets array*/
- ULONG cReceivedPacketCount;
- /** packet filter flags set by the upper protocols */
- ULONG fUpperProtocolSetFilter;
- /** packet filter flags set by the upper protocols */
- ULONG fSetFilterBuffer;
- /** packet filter flags set by us */
- ULONG fOurSetFilter;
-#endif /* !VBOXNETADP */
-#endif /* !VBOX_NETFLT_ONDEMAND_BIND */
-
-#ifndef VBOXNETADP
-#if defined(DEBUG_NETFLT_LOOPBACK) || !defined(VBOX_LOOPBACK_USEFLAGS)
- /** used for maintaining the pending send packets for handling packet loopback */
- INTERLOCKED_SINGLE_LIST SendPacketQueue;
-#endif
- /** used for serializing calls to the NdisRequest in the vboxNetFltWinSynchNdisRequest */
- RTSEMFASTMUTEX hSynchRequestMutex;
- /** event used to synchronize with the Ndis Request completion in the vboxNetFltWinSynchNdisRequest */
- KEVENT hSynchCompletionEvent;
- /** status of the Ndis Request initiated by the vboxNetFltWinSynchNdisRequest */
- NDIS_STATUS volatile fSynchCompletionStatus;
- /** pointer to the Ndis Request being executed by the vboxNetFltWinSynchNdisRequest */
- PNDIS_REQUEST volatile pSynchRequest;
- /** ndis packet pool used for sends */
- NDIS_HANDLE hSendPacketPoolHandle;
- /** ndis buffer pool used for sends */
- NDIS_HANDLE hSendBufferPoolHandle;
- /** open/close adapter status.
- * Since ndis adapter open and close requests may complete asynchronously,
- * we are using event mechanism to wait for open/close completion
- * the status field is being set by the completion call-back */
- NDIS_STATUS Status;
- /** open/close adaptor completion event */
- NDIS_EVENT hEvent;
- /** medium we are attached to */
- NDIS_MEDIUM Medium;
-// /** physical medium we are attached to */
-// NDIS_PHYSICAL_MEDIUM PhMedium;
- /** True - When the miniport or protocol is transitioning from a D0 to Standby (>D0) State
- * False - At all other times, - Flag is cleared after a transition to D0 */
- BOOLEAN bStandingBy;
-#endif
-} ADAPT, *PADAPT;
-
-typedef struct _PACKET_QUEUE_WORKER
-{
- /** this event is used to initiate a packet queue worker thread kill */
- KEVENT KillEvent;
- /** this event is used to notify a worker thread that the packets are added to the queue */
- KEVENT NotifyEvent;
- /** pointer to the packet queue worker thread object */
- PKTHREAD pThread;
- /** pointer to the SG used by the packet queue for IntNet receive notifications */
- PINTNETSG pSG;
- /** Packet queue */
- INTERLOCKED_PACKET_QUEUE PacketQueue;
- /** Packet info pool, i.e. the pool for the packet queue elements */
- PACKET_INFO_POOL PacketInfoPool;
-} PACKET_QUEUE_WORKER, *PPACKET_QUEUE_WORKER;
-
-/** Protocol reserved part of a sent packet that is allocated by us. */
-typedef struct _SEND_RSVD
-{
- /** original packet receiver from the upperlying protocol
- * can be null if the packet was originated by intnet */
- PNDIS_PACKET pOriginalPkt;
- /** pointer to the buffer to be freed on send completion
- * can be null if no buffer is to be freed */
- PVOID pBufToFree;
-#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
- SINGLE_LIST_ENTRY ListEntry;
- /* true if the packet is from IntNet */
- bool bFromIntNet;
-#endif
-} SEND_RSVD, *PSEND_RSVD;
-
-/** represents the data stored in the protocol reserved field of ndis packet on NdisTransferData processing*/
-typedef struct _TRANSFERDATA_RSVD
-{
- /** next packet in a list */
- SINGLE_LIST_ENTRY ListEntry;
- /* packet buffer start */
- PNDIS_BUFFER pOriginalBuffer;
-} TRANSFERDATA_RSVD, *PTRANSFERDATA_RSVD;
-
-/** Miniport reserved part of a received packet that is allocated by
- * us. Note that this should fit into the MiniportReserved space
- * in an NDIS_PACKET. */
-typedef struct _RECV_RSVD
-{
- /** original packet receiver from the underling miniport
- * can be null if the packet was originated by intnet */
- PNDIS_PACKET pOriginalPkt;
- /** pointer to the buffer to be freed on receive completion
- * can be null if no buffer is to be freed */
- PVOID pBufToFree;
-} RECV_RSVD, *PRECV_RSVD;
-
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
-
-C_ASSERT(sizeof(RECV_RSVD) <= sizeof(((PNDIS_PACKET)0)->MiniportReserved));
-C_ASSERT(sizeof(TRANSFERDATA_RSVD) <= PROTOCOL_RESERVED_SIZE_IN_PACKET);
-#endif
-
-C_ASSERT(sizeof(NDIS_DEVICE_POWER_STATE) == sizeof(uint32_t));
-C_ASSERT(sizeof(UINT) == sizeof(uint32_t));
-
-#define NDIS_FLAGS_SKIP_LOOPBACK_W2K 0x400
-
-#include "../VBoxNetFltInternal.h"
-#include "VBoxNetFlt-win.h"
-#ifndef VBOXNETADP
-#include "VBoxNetFltPt-win.h"
-#endif
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
-# include "VBoxNetFltMp-win.h"
-#endif
-
-#ifdef DEBUG_NETFLT_NOASSERT
-# ifdef Assert
-# undef Assert
-# endif
-
-# define Assert(_expr) do {} while (0)
-#endif /* #ifdef DEBUG_NETFLT_NOASSERT */
-
-#endif
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c
deleted file mode 100644
index ec9f3f754..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c
+++ /dev/null
@@ -1,2807 +0,0 @@
-/* $Id: VBoxNetFltMp-win.c $ */
-/** @file
- * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Miniport edge of ndis filter driver
- */
-
-/*
- * Copyright (C) 2008 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.
- */
-/*
- * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
- * Copyright (c) 1993-1999, Microsoft Corporation
- */
-
-#include "VBoxNetFltCommon-win.h"
-
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
-# error "unsupported (VBOX_NETFLT_ONDEMAND_BIND)"
-#else
-
-/** driver handle */
-static NDIS_HANDLE g_hDriverHandle = NULL;
-/** Ndis wrapper handle */
-static NDIS_HANDLE g_hNdisWrapperHandle;
-/** device handle for ioctl interface this is not used currently and should be removed soon */
-static NDIS_HANDLE g_hNdisDeviceHandle = NULL;
-/** device object used for ioctl interface this is not used currently and should be removed soon */
-static PDEVICE_OBJECT g_pControlDeviceObject = NULL;
-/** ioctl device ref count */
-static LONG g_cControlDeviceRefs = 0;
-/** true if control device needs to be dereferenced before destroying */
-static bool g_bControlDeviceReferenced = false;
-
-enum _DEVICE_STATE
-{
- /** ready for create/delete */
- PS_DEVICE_STATE_READY = 0,
- /** create operation in progress */
- PS_DEVICE_STATE_CREATING,
- /** delete operation in progress */
- PS_DEVICE_STATE_DELETING
-} g_eControlDeviceState = PS_DEVICE_STATE_READY;
-
-/*
- * miniport
- */
-typedef struct {
- PVOID aBuffer[8];
-}OUR_SECURITY_DESCRIPTOR_BUFFER;
-
-static PUCHAR vboxNetFltWinMpDbgGetOidName(ULONG oid);
-
-#ifdef VBOXNETFLT_WITH_IOCTL_SECURITY
-NTSYSAPI
-NTSTATUS
-NTAPI
-ZwSetSecurityObject(IN HANDLE hHandle,
- IN SECURITY_INFORMATION SInfo,
- IN PSECURITY_DESCRIPTOR pSDescriptor);
-/*
- * makes our device object usable/accessible for non-privileged users
- */
-static NTSTATUS vboxNetFltWinSetSecurity(PNDIS_STRING pDevName)
-{
- NTSTATUS Status;
- OBJECT_ATTRIBUTES ObjAttr;
- IO_STATUS_BLOCK IoStatus;
- HANDLE hFile;
- OUR_SECURITY_DESCRIPTOR_BUFFER SecurityDes;
-
- /*obtain the handle first*/
- NdisZeroMemory(&ObjAttr, sizeof(ObjAttr));
- InitializeObjectAttributes(&ObjAttr, pDevName,
- OBJ_KERNEL_HANDLE /* ULONG Attributes */,
- NULL /*HANDLE RootDirectory*/,
- NULL /*PSECURITY_DESCRIPTOR SecurityDescriptor */
- );
-
- NdisZeroMemory(&IoStatus, sizeof(IoStatus));
- Status = ZwOpenFile(&hFile /* PHANDLE FileHandle*/,
- WRITE_DAC /*ACCESS_MASK DesiredAccess - we want to change the ACL */,
- &ObjAttr /*POBJECT_ATTRIBUTES */,
- &IoStatus /*PIO_STATUS_BLOCK */,
- 0 /*ULONG ShareAccess*/,
- 0 /*ULONG OpenOptions*/
- );
- Assert(Status == STATUS_SUCCESS);
- if(Status == STATUS_SUCCESS)
- {
- /* create and set security descriptor */
- NdisZeroMemory(&SecurityDes, sizeof(SecurityDes));
- Status = RtlCreateSecurityDescriptor(&SecurityDes, SECURITY_DESCRIPTOR_REVISION);
- Assert(Status == STATUS_SUCCESS);
- if(Status == STATUS_SUCCESS)
- {
- Status = ZwSetSecurityObject(hFile, DACL_SECURITY_INFORMATION, &SecurityDes);
- Assert(Status == STATUS_SUCCESS);
- if(Status != STATUS_SUCCESS)
- {
- LogRel(("ZwSetSecurityObject error: Status (0x%x)\n", Status));
- DBGPRINT(("ZwSetSecurityObject error: Status (0x%x)\n", Status));
- }
- }
- else
- {
- LogRel(("RtlCreateSecurityDescriptor error: Status (0x%x)\n", Status));
- DBGPRINT(("RtlCreateSecurityDescriptor error: Status (0x%x)\n", Status));
- }
-
- {
- NTSTATUS Tmp = ZwClose(hFile);
- Assert(Tmp == STATUS_SUCCESS);
- if(Tmp != STATUS_SUCCESS)
- {
- LogRel(("ZwClose error: Status (0x%x), ignoring\n", Status));
- DBGPRINT(("ZwClose error: Status (0x%x), ignoring\n", Status));
- }
- }
- }
- else
- {
- LogRel(("ZwOpenFile error: Status (0x%x)\n", Status));
- DBGPRINT(("ZwOpenFile error: Status (0x%x)\n", Status));
- }
-
- return Status;
-}
-#endif
-/**
- * Register an ioctl interface - a device object to be used for this
- * purpose is created by NDIS when we call NdisMRegisterDevice.
- *
- * This routine is called whenever a new miniport instance is
- * initialized. However, we only create one global device object,
- * when the first miniport instance is initialized. This routine
- * handles potential race conditions with vboxNetFltWinPtDeregisterDevice via
- * the g_eControlDeviceState and g_cControlDeviceRefs variables.
- *
- * NOTE: do not call this from DriverEntry; it will prevent the driver
- * from being unloaded (e.g. on uninstall).
- *
- * @return NDIS_STATUS_SUCCESS if we successfully register a device object. */
-static NDIS_STATUS
-vboxNetFltWinPtRegisterDevice(
- VOID
- )
-{
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
- UNICODE_STRING DeviceName;
- UNICODE_STRING DeviceLinkUnicodeString;
- PDRIVER_DISPATCH DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
-
- LogFlow(("==>vboxNetFltWinPtRegisterDevice\n"));
-
- NdisAcquireSpinLock(&g_GlobalLock);
-
- ++g_cControlDeviceRefs;
-
- if (1 == g_cControlDeviceRefs)
- {
- Assert(g_eControlDeviceState != PS_DEVICE_STATE_CREATING);
-
- /* Another thread could be running vboxNetFltWinPtDeregisterDevice on
- * behalf of another miniport instance. If so, wait for
- * it to exit. */
- while (g_eControlDeviceState != PS_DEVICE_STATE_READY)
- {
- NdisReleaseSpinLock(&g_GlobalLock);
- NdisMSleep(1);
- NdisAcquireSpinLock(&g_GlobalLock);
- }
-
- g_eControlDeviceState = PS_DEVICE_STATE_CREATING;
-
- NdisReleaseSpinLock(&g_GlobalLock);
-
-
- NdisZeroMemory(DispatchTable, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH));
-
- DispatchTable[IRP_MJ_CREATE] = vboxNetFltWinPtDispatch;
- DispatchTable[IRP_MJ_CLEANUP] = vboxNetFltWinPtDispatch;
- DispatchTable[IRP_MJ_CLOSE] = vboxNetFltWinPtDispatch;
- DispatchTable[IRP_MJ_DEVICE_CONTROL] = vboxNetFltWinPtDispatch;
-
-
- NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING);
- NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING);
-
- /* Create a device object and register our dispatch handlers */
-
- Status = NdisMRegisterDevice(
- g_hNdisWrapperHandle,
- &DeviceName,
- &DeviceLinkUnicodeString,
- &DispatchTable[0],
- &g_pControlDeviceObject,
- &g_hNdisDeviceHandle
- );
-
- Assert(Status == NDIS_STATUS_SUCCESS);
- if(Status == NDIS_STATUS_SUCCESS)
- {
-#ifdef VBOXNETFLT_WITH_IOCTL_SECURITY
- /* NdisMRegisterDevice does not offers us the ability to set security attributes */
- /* need to do this "manually" for the device to be accessible by the non-privileged users */
- Status = vboxNetFltWinSetSecurity(&DeviceLinkUnicodeString);
- Assert(Status == STATUS_SUCCESS);
- if(Status != STATUS_SUCCESS)
- {
- LogRel(("Failed to set security attributes for netflt control device, status (0x%x), ignoring\n", Status));
- /* ignore the failure */
- Status = NDIS_STATUS_SUCCESS;
- }
-#endif
-
- Status = ObReferenceObjectByPointer(g_pControlDeviceObject, FILE_READ_DATA, NULL, KernelMode);
- Assert(Status == NDIS_STATUS_SUCCESS);
- if(Status == NDIS_STATUS_SUCCESS)
- {
- g_bControlDeviceReferenced = true;
- }
- else
- {
- LogRel(("Failed to reference netflt control device, status (0x%x), ignoring\n", Status));
- /* ignore the failure */
- Status = NDIS_STATUS_SUCCESS;
- g_bControlDeviceReferenced = false;
- }
- }
-
- NdisAcquireSpinLock(&g_GlobalLock);
-
- g_eControlDeviceState = PS_DEVICE_STATE_READY;
- }
-
- NdisReleaseSpinLock(&g_GlobalLock);
-
- LogFlow(("<==vboxNetFltWinPtRegisterDevice: %x\n", Status));
-
- return (Status);
-}
-
-/**
- * Deregister the ioctl interface. This is called whenever a miniport
- * instance is halted. When the last miniport instance is halted, we
- * request NDIS to delete the device object
- *
- * @return NDIS_STATUS_SUCCESS if everything worked ok
- * */
-static NDIS_STATUS
-vboxNetFltWinPtDeregisterDevice(
- VOID
- )
-{
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
-
- LogFlow(("==>NetFltDeregisterDevice\n"));
-
- NdisAcquireSpinLock(&g_GlobalLock);
-
- Assert(g_cControlDeviceRefs > 0);
-
- --g_cControlDeviceRefs;
-
- if (0 == g_cControlDeviceRefs)
- {
- /* All miniport instances have been halted. Deregister
- * the control device. */
-
- Assert(g_eControlDeviceState == PS_DEVICE_STATE_READY);
-
- /* Block vboxNetFltWinPtRegisterDevice() while we release the control
- * device lock and deregister the device. */
-
- g_eControlDeviceState = PS_DEVICE_STATE_DELETING;
-
- NdisReleaseSpinLock(&g_GlobalLock);
-
- if (g_hNdisDeviceHandle != NULL)
- {
- if(g_bControlDeviceReferenced)
- {
- g_bControlDeviceReferenced = false;
- ObDereferenceObject(g_pControlDeviceObject);
- }
-
- Status = NdisMDeregisterDevice(g_hNdisDeviceHandle);
- g_hNdisDeviceHandle = NULL;
- }
-
- NdisAcquireSpinLock(&g_GlobalLock);
- g_eControlDeviceState = PS_DEVICE_STATE_READY;
- }
-
- NdisReleaseSpinLock(&g_GlobalLock);
-
- LogFlow(("<== NetFltDeregisterDevice: %x\n", Status));
- return Status;
-
-}
-#ifndef VBOXNETADP
-/**
- * This is the initialize handler which gets called as a result of
- * the BindAdapter handler calling NdisIMInitializeDeviceInstanceEx.
- * The context parameter which we pass there is the adapter structure
- * which we retrieve here.
- *
- * @param OpenErrorStatus Not used by us.
- * @param SelectedMediumIndex Place-holder for what media we are using
- * @param MediumArray Array of ndis media passed down to us to pick from
- * @param MediumArraySize Size of the array
- * @param MiniportAdapterHandle The handle NDIS uses to refer to us
- * @param WrapperConfigurationContext For use by NdisOpenConfiguration
- * @return NDIS_STATUS_SUCCESS unless something goes wrong
- * */
-static NDIS_STATUS vboxNetFltWinMpInitialize(
- OUT PNDIS_STATUS OpenErrorStatus,
- OUT PUINT SelectedMediumIndex,
- IN PNDIS_MEDIUM MediumArray,
- IN UINT MediumArraySize,
- IN NDIS_HANDLE MiniportAdapterHandle,
- IN NDIS_HANDLE WrapperConfigurationContext
- )
-{
- UINT i;
- PADAPT pAdapt;
- NDIS_STATUS Status = NDIS_STATUS_FAILURE;
- NDIS_MEDIUM Medium;
-
- UNREFERENCED_PARAMETER(WrapperConfigurationContext);
-
- do
- {
- /*
- * Start off by retrieving our adapter context and storing
- * the Miniport handle in it.
- */
- pAdapt = (PADAPT)NdisIMGetDeviceContext(MiniportAdapterHandle);
- pAdapt->hMiniportHandle = MiniportAdapterHandle;
-
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initializing);
- /* the MP state should be already set to kVBoxNetDevOpState_Initializing, just a paranoia
- * in case NDIS for some reason calls us in some irregular way */
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initializing);
-
- LogFlow(("==> Miniport Initialize: Adapt %p\n", pAdapt));
-
- /*
- * Usually we export the medium type of the adapter below as our
- * virtual miniport's medium type. However if the adapter below us
- * is a WAN device, then we claim to be of medium type 802.3.
- */
- Medium = pAdapt->Medium;
-
- if (Medium == NdisMediumWan)
- {
- Medium = NdisMedium802_3;
- }
-
- for (i = 0; i < MediumArraySize; i++)
- {
- if (MediumArray[i] == Medium)
- {
- *SelectedMediumIndex = i;
- break;
- }
- }
-
- if (i == MediumArraySize)
- {
- Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
- break;
- }
-
-
- /*
- * Set the attributes now. NDIS_ATTRIBUTE_DESERIALIZE enables us
- * to make up-calls to NDIS without having to call NdisIMSwitchToMiniport
- * or NdisIMQueueCallBack. This also forces us to protect our data using
- * spinlocks where appropriate. Also in this case NDIS does not queue
- * packets on our behalf. Since this is a very simple pass-thru
- * miniport, we do not have a need to protect anything. However in
- * a general case there will be a need to use per-adapter spin-locks
- * for the packet queues at the very least.
- */
- NdisMSetAttributesEx(MiniportAdapterHandle,
- pAdapt,
- 0, /* CheckForHangTimeInSeconds */
- NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT |
- NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT|
- NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER |
- NDIS_ATTRIBUTE_DESERIALIZE |
- NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
- (NDIS_INTERFACE_TYPE)0);
-
- /*
- * Initialize LastIndicatedStatus to be NDIS_STATUS_MEDIA_CONNECT
- */
- pAdapt->LastIndicatedStatus = NDIS_STATUS_MEDIA_CONNECT;
-
- /*
- * Initialize the power states for both the lower binding (PTDeviceState)
- * and our miniport edge to Powered On.
- */
- Assert(vboxNetFltWinGetPowerState(&pAdapt->MPState) == NdisDeviceStateD3);
- vboxNetFltWinSetPowerState(&pAdapt->MPState, NdisDeviceStateD0);
- Assert(pAdapt->MPState.OpState == kVBoxNetDevOpState_Initializing);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initialized);
-
- Status = NDIS_STATUS_SUCCESS;
- }
- while (FALSE);
-
- /*
- * If we had received an UnbindAdapter notification on the underlying
- * adapter, we would have blocked that thread waiting for the IM Init
- * process to complete. Wake up any such thread.
- */
- if(Status != NDIS_STATUS_SUCCESS)
- {
- Assert(vboxNetFltWinGetPowerState(&pAdapt->MPState) == NdisDeviceStateD3);
- Assert(pAdapt->MPState.OpState == kVBoxNetDevOpState_Initializing);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
- }
- NdisSetEvent(&pAdapt->MiniportInitEvent);
-
- LogFlow(("<== Miniport Initialize: Adapt %p, Status %x\n", pAdapt, Status));
-
- *OpenErrorStatus = Status;
-
- return Status;
-}
-
-/**
- * process the packet send in a "passthru" mode
- */
-static NDIS_STATUS
-vboxNetFltWinSendPassThru(
- IN PADAPT pAdapt,
- IN PNDIS_PACKET pPacket
-#ifdef VBOXNETFLT_NO_PACKET_QUEUE
- , bool bNetFltActive
-#endif
- )
-{
- PNDIS_PACKET pMyPacket;
- NDIS_STATUS fStatus;
-
- fStatus = vboxNetFltWinPrepareSendPacket(pAdapt, pPacket, &pMyPacket/*, false*/);
-
- Assert(fStatus == NDIS_STATUS_SUCCESS);
- if (fStatus == NDIS_STATUS_SUCCESS)
- {
-#if !defined(VBOX_LOOPBACK_USEFLAGS) /* || defined(DEBUG_NETFLT_PACKETS) */
-# ifdef VBOXNETFLT_NO_PACKET_QUEUE
- if (bNetFltActive)
- vboxNetFltWinLbPutSendPacket(pAdapt, pMyPacket, false /* bFromIntNet */);
-# else
- /* no need for the loop enqueue & check in a passthru mode , ndis will do everything for us */
-# endif
-#endif
- NdisSend(&fStatus,
- pAdapt->hBindingHandle,
- pMyPacket);
- if (fStatus != NDIS_STATUS_PENDING)
- {
-#ifndef WIN9X
- NdisIMCopySendCompletePerPacketInfo (pPacket, pMyPacket);
-#endif
-#if defined(VBOXNETFLT_NO_PACKET_QUEUE) && !defined(VBOX_LOOPBACK_USEFLAGS)
- if (bNetFltActive)
- vboxNetFltWinLbRemoveSendPacket(pAdapt, pMyPacket);
-#endif
- NdisFreePacket(pMyPacket);
- }
- }
- return fStatus;
-}
-
-#else /* defined VBOXNETADP */
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoDeinitialization(PADAPT pAdapt)
-{
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- uint64_t NanoTS = RTTimeSystemNanoTS();
- int cPPUsage;
-
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized);
- /*
- * Set the flag that the miniport below is unbinding, so the request handlers will
- * fail any request coming later
- */
- RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
-
- ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true);
- ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false);
- ASMAtomicUoWriteU64(&pNetFlt->NanoTSLastRediscovery, NanoTS);
-
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitializing);
-
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
-
- vboxNetFltWinWaitDereference(&pAdapt->MPState);
-
- /* check packet pool is empty */
- cPPUsage = NdisPacketPoolUsage(pAdapt->hRecvPacketPoolHandle);
- Assert(cPPUsage == 0);
- /* for debugging only, ignore the err in release */
- NOREF(cPPUsage);
-
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
-
-// pAdapt->hMiniportHandle = NULL;
-
- return NDIS_STATUS_SUCCESS;
-}
-
-static NDIS_STATUS vboxNetFltWinMpReadApplyConfig(PADAPT pAdapt, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext)
-{
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
- NDIS_HANDLE hConfiguration;
- PNDIS_CONFIGURATION_PARAMETER pParameterValue;
- NDIS_STRING strMAC = NDIS_STRING_CONST("MAC");
- PVBOXNETFLTINS pThis = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- RTMAC mac;
-
- //
- // Open the registry for this adapter to read advanced
- // configuration parameters stored by the INF file.
- //
- NdisOpenConfiguration(
- &Status,
- &hConfiguration,
- hWrapperConfigurationContext);
- Assert(Status == NDIS_STATUS_SUCCESS);
- if(Status == NDIS_STATUS_SUCCESS)
- {
- do
- {
- int rc;
- NDIS_CONFIGURATION_PARAMETER param;
- WCHAR MacBuf[13];
-
-
- NdisReadConfiguration(&Status,
- &pParameterValue,
- hConfiguration,
- &strMAC,
- NdisParameterString);
-// Assert(Status == NDIS_STATUS_SUCCESS);
- if(Status == NDIS_STATUS_SUCCESS)
- {
-
- rc = vboxNetFltWinMACFromNdisString(&mac, &pParameterValue->ParameterData.StringData);
- AssertRC(rc);
- if(RT_SUCCESS(rc))
- {
- break;
- }
- }
-
- vboxNetFltWinGenerateMACAddress(&mac);
- param.ParameterType = NdisParameterString;
- param.ParameterData.StringData.Buffer = MacBuf;
- param.ParameterData.StringData.MaximumLength = sizeof(MacBuf);
-
- rc = vboxNetFltWinMAC2NdisString(&mac, &param.ParameterData.StringData);
- Assert(RT_SUCCESS(rc));
- if(RT_SUCCESS(rc))
- {
- NdisWriteConfiguration(&Status,
- hConfiguration,
- &strMAC,
- &param);
- Assert(Status == NDIS_STATUS_SUCCESS);
- if(Status != NDIS_STATUS_SUCCESS)
- {
- /* ignore the failure */
- Status = NDIS_STATUS_SUCCESS;
- }
- }
- }while(0);
-
- NdisCloseConfiguration(hConfiguration);
- }
- else
- {
- vboxNetFltWinGenerateMACAddress(&mac);
- }
-
- pThis->u.s.MacAddr = mac;
-
- return NDIS_STATUS_SUCCESS;
-}
-
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoInitialization(PADAPT pAdapt, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext)
-{
- NDIS_STATUS Status;
- pAdapt->hMiniportHandle = hMiniportAdapter;
-
- LogFlow(("==> vboxNetFltWinMpDoInitialization: Adapt %p\n", pAdapt));
-
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initializing);
-
- vboxNetFltWinMpReadApplyConfig(pAdapt, hMiniportAdapter, hWrapperConfigurationContext);
-
- NdisMSetAttributesEx(hMiniportAdapter,
- pAdapt,
- 0, /* CheckForHangTimeInSeconds */
- NDIS_ATTRIBUTE_DESERIALIZE |
- NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
- NdisInterfaceInternal/*(NDIS_INTERFACE_TYPE)0*/);
-
- /*
- * Initialize the power states for both the lower binding (PTDeviceState)
- * and our miniport edge to Powered On.
- */
- Assert(vboxNetFltWinGetPowerState(&pAdapt->MPState) == NdisDeviceStateD3);
- vboxNetFltWinSetPowerState(&pAdapt->MPState, NdisDeviceStateD0);
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initializing);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initialized);
-
- Status = NDIS_STATUS_SUCCESS;
-
-
-// *OpenErrorStatus = Status;
-
- LogFlow(("<== vboxNetFltWinMpDoInitialization: Adapt %p, Status %x\n", pAdapt, Status));
-
- return Status;
-}
-
-/**
- * This is the initialize handler which gets called as a result of
- * the BindAdapter handler calling NdisIMInitializeDeviceInstanceEx.
- * The context parameter which we pass there is the adapter structure
- * which we retrieve here.
- *
- * @param OpenErrorStatus Not used by us.
- * @param SelectedMediumIndex Place-holder for what media we are using
- * @param MediumArray Array of ndis media passed down to us to pick from
- * @param MediumArraySize Size of the array
- * @param MiniportAdapterHandle The handle NDIS uses to refer to us
- * @param WrapperConfigurationContext For use by NdisOpenConfiguration
- * @return NDIS_STATUS_SUCCESS unless something goes wrong
- * */
-static NDIS_STATUS vboxNetFltWinMpInitialize(
- OUT PNDIS_STATUS OpenErrorStatus,
- OUT PUINT SelectedMediumIndex,
- IN PNDIS_MEDIUM MediumArray,
- IN UINT MediumArraySize,
- IN NDIS_HANDLE MiniportAdapterHandle,
- IN NDIS_HANDLE WrapperConfigurationContext
- )
-{
- UINT i;
- PADAPT pAdapt;
- NDIS_STATUS Status = NDIS_STATUS_FAILURE;
- NDIS_MEDIUM Medium;
-
- UNREFERENCED_PARAMETER(WrapperConfigurationContext);
-
- Medium = NdisMedium802_3;
-
- if (Medium == NdisMediumWan)
- {
- Medium = NdisMedium802_3;
- }
-
- for (i = 0; i < MediumArraySize; i++)
- {
- if (MediumArray[i] == Medium)
- {
- *SelectedMediumIndex = i;
- break;
- }
- }
-
- if (i != MediumArraySize)
- {
- PDEVICE_OBJECT pPdo, pFdo;
-#define KEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"
- UCHAR Buf[512];
- PUCHAR pSuffix;
- ULONG cbBuf;
- NDIS_STRING RtlStr;
-
- wcscpy((WCHAR*)Buf, KEY_PREFIX);
- pSuffix = Buf + (sizeof(KEY_PREFIX)-2);
-
- NdisMGetDeviceProperty(MiniportAdapterHandle,
- &pPdo,
- &pFdo,
- NULL, //Next Device Object
- NULL,
- NULL);
-
- Status = IoGetDeviceProperty (pPdo,
- DevicePropertyDriverKeyName,
- sizeof(Buf) - (sizeof(KEY_PREFIX)-2),
- pSuffix,
- &cbBuf);
- if(Status == STATUS_SUCCESS)
- {
- OBJECT_ATTRIBUTES ObjAttr;
- HANDLE hDrvKey;
- RtlStr.Buffer=(WCHAR*)Buf;
- RtlStr.Length=(USHORT)cbBuf - 2 + sizeof(KEY_PREFIX) - 2;
- RtlStr.MaximumLength=sizeof(Buf);
-
- InitializeObjectAttributes(&ObjAttr, &RtlStr, OBJ_CASE_INSENSITIVE, NULL, NULL);
-
- Status = ZwOpenKey(&hDrvKey, KEY_READ, &ObjAttr);
- if(Status == STATUS_SUCCESS)
- {
- static UNICODE_STRING NetCfgInstanceIdValue = NDIS_STRING_CONST("NetCfgInstanceId");
-// UCHAR valBuf[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + RTUUID_STR_LENGTH*2 + 10];
-// ULONG cLength = sizeof(valBuf);
-#define NAME_PREFIX L"\\DEVICE\\"
- PKEY_VALUE_PARTIAL_INFORMATION pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
- Status = ZwQueryValueKey(hDrvKey,
- &NetCfgInstanceIdValue,
- KeyValuePartialInformation,
- pInfo,
- sizeof(Buf),
- &cbBuf);
- if(Status == STATUS_SUCCESS)
- {
- if(pInfo->Type == REG_SZ && pInfo->DataLength > 2)
- {
- WCHAR *pName;
- Status = vboxNetFltWinMemAlloc(&pName, pInfo->DataLength + sizeof(NAME_PREFIX));
- if(Status == STATUS_SUCCESS)
- {
- wcscpy(pName, NAME_PREFIX);
- wcscpy(pName+(sizeof(NAME_PREFIX)-2)/2, (WCHAR*)pInfo->Data);
- RtlStr.Buffer=pName;
- RtlStr.Length = (USHORT)pInfo->DataLength - 2 + sizeof(NAME_PREFIX) - 2;
- RtlStr.MaximumLength = (USHORT)pInfo->DataLength + sizeof(NAME_PREFIX);
-
- Status = vboxNetFltWinPtInitBind(&pAdapt, MiniportAdapterHandle, &RtlStr, WrapperConfigurationContext);
-
- if(Status == STATUS_SUCCESS)
- {
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initialized);
-#if 0
- NdisMIndicateStatus(pAdapt->hMiniportHandle,
- NDIS_STATUS_MEDIA_CONNECT,
- (PVOID)NULL,
- 0);
-#endif
- }
- else
- {
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
- }
-
- vboxNetFltWinMemFree(pName);
-
- }
- }
- else
- {
- Status = NDIS_STATUS_FAILURE;
- }
- }
- }
- }
- }
- else
- {
- Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
- }
-
- if(Status != NDIS_STATUS_SUCCESS)
- {
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
- }
-
- /* TODO: */
- *OpenErrorStatus = Status;
-
- return Status;
-}
-#endif
-
-
-/**
- * Send Packet Array handler. Either this or our SendPacket handler is called
- * based on which one is enabled in our Miniport Characteristics.
- *
- * @param MiniportAdapterContext Pointer to our adapter
- * @param PacketArray Set of packets to send
- * @param NumberOfPackets Self-explanatory
- * @return none */
-static VOID
-vboxNetFltWinMpSendPackets(
- IN NDIS_HANDLE fMiniportAdapterContext,
- IN PPNDIS_PACKET pPacketArray,
- IN UINT cNumberOfPackets
- )
-{
- PADAPT pAdapt = (PADAPT)fMiniportAdapterContext;
- NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS;
- UINT i;
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- bool bNetFltActive;
-
- Assert(cNumberOfPackets);
-
- if(vboxNetFltWinIncReferenceAdaptNetFlt(pNetFlt, pAdapt, cNumberOfPackets, &bNetFltActive))
- {
- uint32_t cAdaptRefs = cNumberOfPackets;
- uint32_t cNetFltRefs;
- uint32_t cPassThruRefs;
- if(bNetFltActive)
- {
- cNetFltRefs = cNumberOfPackets;
- cPassThruRefs = 0;
- }
- else
- {
- cPassThruRefs = cNumberOfPackets;
- cNetFltRefs = 0;
- }
-
- for (i = 0; i < cNumberOfPackets; i++)
- {
- PNDIS_PACKET pPacket;
-
- pPacket = pPacketArray[i];
-
- if(!cNetFltRefs
-#ifdef VBOXNETFLT_NO_PACKET_QUEUE
- || !vboxNetFltWinPostIntnet(pNetFlt, pPacket, PACKET_SRC_HOST)
-#else
- || (fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, PACKET_SRC_HOST)) != NDIS_STATUS_SUCCESS
-#endif
- )
- {
-#ifndef VBOXNETADP
- fStatus = vboxNetFltWinSendPassThru(pAdapt, pPacket
-#ifdef VBOXNETFLT_NO_PACKET_QUEUE
- , !!cNetFltRefs
-#endif
- );
-#else
- if(!cNetFltRefs)
- {
-# ifdef VBOXNETADP_REPORT_DISCONNECTED
- fStatus = NDIS_STATUS_MEDIA_DISCONNECT;
- STATISTIC_INCREASE(pAdapt->cTxError);
-# else
- fStatus = NDIS_STATUS_SUCCESS;
-# endif
- }
-#endif
-
- if (fStatus != NDIS_STATUS_PENDING)
- {
- NdisMSendComplete(pAdapt->hMiniportHandle,
- pPacket,
- fStatus);
- }
- else
- {
- cAdaptRefs--;
- }
- }
- else
- {
-#ifdef VBOXNETFLT_NO_PACKET_QUEUE
- NdisMSendComplete(pAdapt->hMiniportHandle,
- pPacket,
- NDIS_STATUS_SUCCESS);
-#else
- cAdaptRefs--;
- cNetFltRefs--;
-#endif
- }
- }
-
- if(cNetFltRefs)
- {
- vboxNetFltWinDecReferenceNetFlt(pNetFlt, cNetFltRefs);
- }
- else if(cPassThruRefs)
- {
- vboxNetFltWinDecReferenceModePassThru(pNetFlt, cPassThruRefs);
- }
- if(cAdaptRefs)
- {
- vboxNetFltWinDecReferenceAdapt(pAdapt, cAdaptRefs);
- }
- }
- else
- {
- NDIS_HANDLE h = pAdapt->hMiniportHandle;
- Assert(0);
- if(h)
- {
- for (i = 0; i < cNumberOfPackets; i++)
- {
- PNDIS_PACKET pPacket;
- pPacket = pPacketArray[i];
- NdisMSendComplete(h,
- pPacket,
- NDIS_STATUS_FAILURE);
- }
- }
- }
-}
-#ifndef VBOXNETADP
-/**
- * Entry point called by NDIS to query for the value of the specified OID.
- * Typical processing is to forward the query down to the underlying miniport.
- *
- * The following OIDs are filtered here:
- * OID_PNP_QUERY_POWER - return success right here
- * OID_GEN_SUPPORTED_GUIDS - do not forward, otherwise we will show up
- * multiple instances of private GUIDs supported by the underlying miniport.
- * OID_PNP_CAPABILITIES - we do send this down to the lower miniport, but
- * the values returned are postprocessed before we complete this request;
- * see vboxNetFltWinPtRequestComplete.
- *
- * NOTE on OID_TCP_TASK_OFFLOAD - if this IM driver modifies the contents
- * of data it passes through such that a lower miniport may not be able
- * to perform TCP task offload, then it should not forward this OID down,
- * but fail it here with the status NDIS_STATUS_NOT_SUPPORTED. This is to
- * avoid performing incorrect transformations on data.
- *
- * If our miniport edge (upper edge) is at a low-power state, fail the request.
- * If our protocol edge (lower edge) has been notified of a low-power state,
- * we pend this request until the miniport below has been set to D0. Since
- * requests to miniports are serialized always, at most a single request will
- * be pended.
- *
- * @param MiniportAdapterContext Pointer to the adapter structure
- * @param Oid Oid for this query
- * @param InformationBuffer Buffer for information
- * @param InformationBufferLength Size of this buffer
- * @param BytesWritten Specifies how much info is written
- * @param BytesNeeded In case the buffer is smaller than what we need, tell them how much is needed
- * @return Return code from the NdisRequest below.
- * */
-static NDIS_STATUS
-vboxNetFltWinMpQueryInformation(
- IN NDIS_HANDLE MiniportAdapterContext,
- IN NDIS_OID Oid,
- IN PVOID InformationBuffer,
- IN ULONG InformationBufferLength,
- OUT PULONG BytesWritten,
- OUT PULONG BytesNeeded
- )
-{
- PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
- NDIS_STATUS Status = NDIS_STATUS_FAILURE;
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
-
- do
- {
- if (Oid == OID_PNP_QUERY_POWER)
- {
- /*
- * Do not forward this.
- */
- Status = NDIS_STATUS_SUCCESS;
- break;
- }
-
- if (Oid == OID_GEN_SUPPORTED_GUIDS)
- {
- /*
- * Do not forward this, otherwise we will end up with multiple
- * instances of private GUIDs that the underlying miniport
- * supports.
- */
- Status = NDIS_STATUS_NOT_SUPPORTED;
- break;
- }
-
- if (Oid == OID_TCP_TASK_OFFLOAD)
- {
- /* we want to receive packets with checksums calculated
- * since we are passing them to IntNet
- */
- Status = NDIS_STATUS_NOT_SUPPORTED;
- break;
- }
-
- /*
- * If the miniport below is unbinding, just fail any request
- */
- if (vboxNetFltWinGetOpState(&pAdapt->PTState) > kVBoxNetDevOpState_Initialized) /* protocol unbind in progress */
- {
- Status = NDIS_STATUS_FAILURE;
- break;
- }
-
- /*
- * All other queries are failed, if the miniport is not at D0,
- */
- if (vboxNetFltWinGetPowerState(&pAdapt->MPState) > NdisDeviceStateD0)
- {
- Status = NDIS_STATUS_FAILURE;
- break;
- }
-
- pAdapt->Request.RequestType = NdisRequestQueryInformation;
- pAdapt->Request.DATA.QUERY_INFORMATION.Oid = Oid;
- pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;
- pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;
- pAdapt->BytesNeeded = BytesNeeded;
- pAdapt->BytesReadOrWritten = BytesWritten;
-
- /*
- * If the miniport below is binding, fail the request
- */
- RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
-
- if (vboxNetFltWinGetOpState(&pAdapt->PTState) > kVBoxNetDevOpState_Initialized)
- {
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- Status = NDIS_STATUS_FAILURE;
- break;
- }
- /*
- * If the Protocol device state is OFF, mark this request as being
- * pended. We queue this until the device state is back to D0.
- */
- if ((vboxNetFltWinGetPowerState(&pAdapt->PTState) > NdisDeviceStateD0)
- && (pAdapt->bStandingBy == FALSE))
- {
- pAdapt->bQueuedRequest = TRUE;
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- Status = NDIS_STATUS_PENDING;
- break;
- }
- /*
- * This is in the process of powering down the system, always fail the request
- */
- if (pAdapt->bStandingBy == TRUE)
- {
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- Status = NDIS_STATUS_FAILURE;
- break;
- }
- pAdapt->bOutstandingRequests = TRUE;
-
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- if(Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
- {
- bool fNetFltActive;
- const bool fAdaptActive = vboxNetFltWinReferenceAdaptNetFlt(pNetFlt, pAdapt, &fNetFltActive);
-
- Assert(InformationBuffer);
- Assert(!pAdapt->fProcessingPacketFilter);
-
- if(fNetFltActive)
- {
- /* netflt is active, simply return the cached value */
- *((PULONG)InformationBuffer) = pAdapt->fUpperProtocolSetFilter;
-
- Status = NDIS_STATUS_SUCCESS;
- vboxNetFltWinDereferenceNetFlt(pNetFlt);
- vboxNetFltWinDereferenceAdapt(pAdapt);
-
- RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
- pAdapt->bOutstandingRequests = FALSE;
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- break;
- }
- else if(fAdaptActive)
- {
- pAdapt->fProcessingPacketFilter = VBOXNETFLT_PFP_PASSTHRU;
- /* we're cleaning it in RequestComplete */
- }
- }
-
- /*
- * default case, most requests will be passed to the miniport below
- */
- NdisRequest(&Status,
- pAdapt->hBindingHandle,
- &pAdapt->Request);
-
-
- if (Status != NDIS_STATUS_PENDING)
- {
- vboxNetFltWinPtRequestComplete(pAdapt, &pAdapt->Request, Status);
- Status = NDIS_STATUS_PENDING;
- }
-
- } while (FALSE);
-
- return(Status);
-
-}
-/**
- * Postprocess a request for OID_PNP_CAPABILITIES that was forwarded
- * down to the underlying miniport, and has been completed by it.
- *
- * @param pAdapt - Pointer to the adapter structure
- * @param pStatus - Place to return final status
- * @return None. */
-DECLHIDDEN(VOID)
-vboxNetFltWinMpQueryPNPCapabilities(
- IN OUT PADAPT pAdapt,
- OUT PNDIS_STATUS pStatus
- )
-{
- PNDIS_PNP_CAPABILITIES pPNPCapabilities;
- PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct;
-
- if (pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof(NDIS_PNP_CAPABILITIES))
- {
- pPNPCapabilities = (PNDIS_PNP_CAPABILITIES)(pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer);
-
- /*
- * The following fields must be overwritten by an IM driver.
- */
- pPMstruct= & pPNPCapabilities->WakeUpCapabilities;
- pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
- pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified;
- pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
- *pAdapt->BytesReadOrWritten = sizeof(NDIS_PNP_CAPABILITIES);
- *pAdapt->BytesNeeded = 0;
-
-
- *pStatus = NDIS_STATUS_SUCCESS;
- }
- else
- {
- *pAdapt->BytesNeeded= sizeof(NDIS_PNP_CAPABILITIES);
- *pStatus = NDIS_STATUS_RESOURCES;
- }
-}
-
-#endif /* ifndef VBOXNETADP*/
-
-/**
- * This routine does all the processing for a request with a SetPower Oid
- * The miniport shoud accept the Set Power and transition to the new state
- *
- * The Set Power should not be passed to the miniport below
- *
- * If the IM miniport is going into a low power state, then there is no guarantee if it will ever
- * be asked go back to D0, before getting halted. No requests should be pended or queued.
- *
- * @param pNdisStatus - Status of the operation
- * @param pAdapt - The Adapter structure
- * @param InformationBuffer - The New DeviceState
- * @param InformationBufferLength
- * @param BytesRead - No of bytes read
- * @param BytesNeeded - No of bytes needed
- * @return Status - NDIS_STATUS_SUCCESS if all the wait events succeed. */
-static VOID
-vboxNetFltWinMpProcessSetPowerOid(
- IN OUT PNDIS_STATUS pNdisStatus,
- IN PADAPT pAdapt,
- IN PVOID InformationBuffer,
- IN ULONG InformationBufferLength,
- OUT PULONG BytesRead,
- OUT PULONG BytesNeeded
- )
-{
-
-
- NDIS_DEVICE_POWER_STATE NewDeviceState;
-
- LogFlow(("==>vboxNetFltWinMpProcessSetPowerOid: Adapt %p\n", pAdapt));
-
- Assert (InformationBuffer != NULL);
-
- *pNdisStatus = NDIS_STATUS_FAILURE;
-
- do
- {
- /*
- * Check for invalid length
- */
- if (InformationBufferLength < sizeof(NDIS_DEVICE_POWER_STATE))
- {
- *pNdisStatus = NDIS_STATUS_INVALID_LENGTH;
- break;
- }
-
- NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE)InformationBuffer);
-
- /*
- * Check for invalid device state
- */
- if ((vboxNetFltWinGetPowerState(&pAdapt->MPState) > NdisDeviceStateD0) && (NewDeviceState != NdisDeviceStateD0))
- {
- /*
- * If the miniport is in a non-D0 state, the miniport can only receive a Set Power to D0
- */
- Assert (!(vboxNetFltWinGetPowerState(&pAdapt->MPState) > NdisDeviceStateD0) && (NewDeviceState != NdisDeviceStateD0));
-
- *pNdisStatus = NDIS_STATUS_FAILURE;
- break;
- }
-
-#ifndef VBOXNETADP
- /*
- * Is the miniport transitioning from an On (D0) state to an Low Power State (>D0)
- * If so, then set the bStandingBy Flag - (Block all incoming requests)
- */
- if (vboxNetFltWinGetPowerState(&pAdapt->MPState) == NdisDeviceStateD0 && NewDeviceState > NdisDeviceStateD0)
- {
- pAdapt->bStandingBy = TRUE;
- }
-
- /*
- * If the miniport is transitioning from a low power state to ON (D0), then clear the bStandingBy flag
- * All incoming requests will be pended until the physical miniport turns ON.
- */
- if (vboxNetFltWinGetPowerState(&pAdapt->MPState) > NdisDeviceStateD0 && NewDeviceState == NdisDeviceStateD0)
- {
- pAdapt->bStandingBy = FALSE;
- }
-#endif
- /*
- * Now update the state in the pAdapt structure;
- */
- vboxNetFltWinSetPowerState(&pAdapt->MPState, NewDeviceState);
-#ifndef VBOXNETADP
- if(NewDeviceState != NdisDeviceStateD0)
- {
- vboxNetFltWinPtFlushReceiveQueue(pAdapt,
- true ); /* just return */
- }
-#endif
- *pNdisStatus = NDIS_STATUS_SUCCESS;
-
-
- } while (FALSE);
-
- if (*pNdisStatus == NDIS_STATUS_SUCCESS)
- {
-#ifndef VBOXNETADP
- /*
- * The miniport resume from low power state
- */
- if (pAdapt->bStandingBy == FALSE)
- {
- /*
- * If we need to indicate the media connect state
- */
- if (pAdapt->LastIndicatedStatus != pAdapt->LatestUnIndicateStatus)
- {
- NdisMIndicateStatus(pAdapt->hMiniportHandle,
- pAdapt->LatestUnIndicateStatus,
- (PVOID)NULL,
- 0);
- NdisMIndicateStatusComplete(pAdapt->hMiniportHandle);
- pAdapt->LastIndicatedStatus = pAdapt->LatestUnIndicateStatus;
- }
- }
- else
- {
- /*
- * Initialize LatestUnIndicatedStatus
- */
- pAdapt->LatestUnIndicateStatus = pAdapt->LastIndicatedStatus;
- }
-#endif
- *BytesRead = sizeof(NDIS_DEVICE_POWER_STATE);
- *BytesNeeded = 0;
- }
- else
- {
- *BytesRead = 0;
- *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
- }
-
- LogFlow(("<==vboxNetFltWinMpProcessSetPowerOid: Adapt %p\n", pAdapt));
-}
-#ifndef VBOXNETADP
-/**
- * Miniport SetInfo handler.
- *
- * In the case of OID_PNP_SET_POWER, record the power state and return the OID.
- * Do not pass below
- * If the device is suspended, do not block the SET_POWER_OID
- * as it is used to reactivate the NetFlt miniport
- *
- * PM- If the MP is not ON (DeviceState > D0) return immediately (except for 'query power' and 'set power')
- * If MP is ON, but the PT is not at D0, then queue the queue the request for later processing
- *
- * Requests to miniports are always serialized
- *
- * @param MiniportAdapterContext Pointer to the adapter structure
- * @param Oid Oid for this query
- * @param InformationBuffer Buffer for information
- * @param InformationBufferLength Size of this buffer
- * @param BytesRead Specifies how much info is read
- * @param BytesNeeded In case the buffer is smaller than what we need, tell them how much is needed
- * @return Return code from the NdisRequest below. */
-static NDIS_STATUS
-vboxNetFltWinMpSetInformation(
- IN NDIS_HANDLE MiniportAdapterContext,
- IN NDIS_OID Oid,
- IN PVOID InformationBuffer,
- IN ULONG InformationBufferLength,
- OUT PULONG BytesRead,
- OUT PULONG BytesNeeded
- )
-{
- PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
- NDIS_STATUS Status;
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
-
- Status = NDIS_STATUS_FAILURE;
-
- do
- {
- /*
- * The Set Power should not be sent to the miniport below the NetFlt, but is handled internally
- */
- if (Oid == OID_PNP_SET_POWER)
- {
- vboxNetFltWinMpProcessSetPowerOid(&Status,
- pAdapt,
- InformationBuffer,
- InformationBufferLength,
- BytesRead,
- BytesNeeded);
- break;
-
- }
-
- /*
- * If the miniport below is unbinding, fail the request
- */
- if (vboxNetFltWinGetOpState(&pAdapt->PTState) > kVBoxNetDevOpState_Initialized)
- {
- Status = NDIS_STATUS_FAILURE;
- break;
- }
-
- /*
- * All other Set Information requests are failed, if the miniport is
- * not at D0 or is transitioning to a device state greater than D0.
- */
- if (vboxNetFltWinGetPowerState(&pAdapt->MPState) > NdisDeviceStateD0)
- {
- Status = NDIS_STATUS_FAILURE;
- break;
- }
-
- /* Set up the Request and return the result */
- pAdapt->Request.RequestType = NdisRequestSetInformation;
- pAdapt->Request.DATA.SET_INFORMATION.Oid = Oid;
- pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer = InformationBuffer;
- pAdapt->Request.DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength;
- pAdapt->BytesNeeded = BytesNeeded;
- pAdapt->BytesReadOrWritten = BytesRead;
-
- /*
- * If the miniport below is unbinding, fail the request
- */
- RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
- if (vboxNetFltWinGetOpState(&pAdapt->PTState) > kVBoxNetDevOpState_Initialized)
- {
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- Status = NDIS_STATUS_FAILURE;
- break;
- }
-
- /*
- * If the device below is at a low power state, we cannot send it the
- * request now, and must pend it.
- */
- if ((vboxNetFltWinGetPowerState(&pAdapt->PTState) > NdisDeviceStateD0)
- && (pAdapt->bStandingBy == FALSE))
- {
- pAdapt->bQueuedRequest = TRUE;
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- Status = NDIS_STATUS_PENDING;
- break;
- }
- /*
- * This is in the process of powering down the system, always fail the request
- */
- if (pAdapt->bStandingBy == TRUE)
- {
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- Status = NDIS_STATUS_FAILURE;
- break;
- }
- pAdapt->bOutstandingRequests = TRUE;
-
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
-
- if(Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
- {
- /* need to disable cleaning promiscuous here ?? */
- bool fNetFltActive;
- const bool fAdaptActive = vboxNetFltWinReferenceAdaptNetFlt(pNetFlt, pAdapt, &fNetFltActive);
-
- Assert(InformationBuffer);
- Assert(!pAdapt->fProcessingPacketFilter);
-
- if(fNetFltActive)
- {
- Assert(fAdaptActive);
-
- /* netflt is active, update the cached value */
- /* TODO: in case we are are not in promiscuous now, we are issuing a request.
- * what should we do in case of a failure?
- * i.e. should we update the fUpperProtocolSetFilter in completion routine in this case? etc. */
- pAdapt->fUpperProtocolSetFilter = *((PULONG)InformationBuffer);
- pAdapt->bUpperProtSetFilterInitialized = true;
-
- if(!(pAdapt->fOurSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS))
- {
- pAdapt->fSetFilterBuffer = NDIS_PACKET_TYPE_PROMISCUOUS;
- pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer = &pAdapt->fSetFilterBuffer;
- pAdapt->Request.DATA.SET_INFORMATION.InformationBufferLength = sizeof(pAdapt->fSetFilterBuffer);
- pAdapt->fProcessingPacketFilter = VBOXNETFLT_PFP_NETFLT;
- /* we'll do dereferencing in request complete */
- }
- else
- {
- Status = NDIS_STATUS_SUCCESS;
- vboxNetFltWinDereferenceNetFlt(pNetFlt);
- vboxNetFltWinDereferenceAdapt(pAdapt);
-
- RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
- pAdapt->bOutstandingRequests = FALSE;
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- break;
- }
- }
- else if(fAdaptActive)
- {
- pAdapt->fProcessingPacketFilter = VBOXNETFLT_PFP_PASSTHRU;
- /* dereference on completion */
- }
- }
-
- /*
- * Forward the request to the device below.
- */
- NdisRequest(&Status,
- pAdapt->hBindingHandle,
- &pAdapt->Request);
-
- if (Status != NDIS_STATUS_PENDING)
- {
- vboxNetFltWinPtRequestComplete(pAdapt, &pAdapt->Request, Status);
- }
-
- } while (FALSE);
-
- return(Status);
-}
-#else
-static NDIS_OID g_vboxNetFltWinMpSupportedOids[] =
-{
- OID_GEN_SUPPORTED_LIST,
- OID_GEN_HARDWARE_STATUS,
- OID_GEN_MEDIA_SUPPORTED,
- OID_GEN_MEDIA_IN_USE,
- OID_GEN_MAXIMUM_LOOKAHEAD,
- OID_GEN_MAXIMUM_FRAME_SIZE,
- OID_GEN_LINK_SPEED,
- OID_GEN_TRANSMIT_BUFFER_SPACE,
- OID_GEN_RECEIVE_BUFFER_SPACE,
- OID_GEN_TRANSMIT_BLOCK_SIZE,
- OID_GEN_RECEIVE_BLOCK_SIZE,
- OID_GEN_VENDOR_ID,
- OID_GEN_VENDOR_DESCRIPTION,
- OID_GEN_VENDOR_DRIVER_VERSION,
- OID_GEN_CURRENT_PACKET_FILTER,
- OID_GEN_CURRENT_LOOKAHEAD,
- OID_GEN_DRIVER_VERSION,
- OID_GEN_MAXIMUM_TOTAL_SIZE,
- OID_GEN_PROTOCOL_OPTIONS,
- OID_GEN_MAC_OPTIONS,
- OID_GEN_MEDIA_CONNECT_STATUS,
- OID_GEN_MAXIMUM_SEND_PACKETS,
- OID_GEN_XMIT_OK,
- OID_GEN_RCV_OK,
- OID_GEN_XMIT_ERROR,
- OID_GEN_RCV_ERROR,
- OID_GEN_RCV_NO_BUFFER,
- OID_GEN_RCV_CRC_ERROR,
- OID_GEN_TRANSMIT_QUEUE_LENGTH,
- OID_802_3_PERMANENT_ADDRESS,
- OID_802_3_CURRENT_ADDRESS,
- OID_802_3_MULTICAST_LIST,
- OID_802_3_MAC_OPTIONS,
- OID_802_3_MAXIMUM_LIST_SIZE,
- OID_802_3_RCV_ERROR_ALIGNMENT,
- OID_802_3_XMIT_ONE_COLLISION,
- OID_802_3_XMIT_MORE_COLLISIONS,
- OID_802_3_XMIT_DEFERRED,
- OID_802_3_XMIT_MAX_COLLISIONS,
- OID_802_3_RCV_OVERRUN,
- OID_802_3_XMIT_UNDERRUN,
- OID_802_3_XMIT_HEARTBEAT_FAILURE,
- OID_802_3_XMIT_TIMES_CRS_LOST,
- OID_802_3_XMIT_LATE_COLLISIONS
-#ifndef INTERFACE_WITH_NDISPROT
- ,
- OID_PNP_CAPABILITIES,
- OID_PNP_SET_POWER,
- OID_PNP_QUERY_POWER
-# if 0
- ,
- OID_PNP_ADD_WAKE_UP_PATTERN,
- OID_PNP_REMOVE_WAKE_UP_PATTERN,
- OID_PNP_ENABLE_WAKE_UP
-# endif
-#endif
-};
-
-static NDIS_STATUS
-vboxNetFltWinMpQueryInformation(
- IN NDIS_HANDLE MiniportAdapterContext,
- IN NDIS_OID Oid,
- IN PVOID InformationBuffer,
- IN ULONG InformationBufferLength,
- OUT PULONG BytesWritten,
- OUT PULONG BytesNeeded)
-/*++
-
-Routine Description:
-
- Entry point called by NDIS to query for the value of the specified OID.
- MiniportQueryInformation runs at IRQL = DISPATCH_LEVEL.
-
-Arguments:
-
- MiniportAdapterContext Pointer to the adapter structure
- Oid Oid for this query
- InformationBuffer Buffer for information
- InformationBufferLength Size of this buffer
- BytesWritten Specifies how much info is written
- BytesNeeded In case the buffer is smaller than
- what we need, tell them how much is needed
-
-
-Return Value:
-
- Return code from the NdisRequest below.
-
-Notes: Read "Minimizing Miniport Driver Initialization Time" in the DDK
- for more info on how to handle certain OIDs that affect the init of
- a miniport.
-
---*/
-{
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
- PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
- NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
- NDIS_MEDIUM Medium = NdisMedium802_3;
- UCHAR VendorDesc[] = VBOXNETADP_VENDOR_DESC;
- ULONG ulInfo = 0;
- USHORT usInfo = 0;
- ULONG64 ulInfo64 = 0;
- PVOID pInfo = (PVOID) &ulInfo;
- ULONG ulInfoLen = sizeof(ulInfo);
- NDIS_PNP_CAPABILITIES PMCaps;
-
- LogFlow(("==> vboxNetFltWinMpQueryInformation %s\n", vboxNetFltWinMpDbgGetOidName(Oid)));
-
- // Initialize the result
- *BytesWritten = 0;
- *BytesNeeded = 0;
-
- switch(Oid)
- {
- case OID_GEN_SUPPORTED_LIST:
- //
- // The OID_GEN_SUPPORTED_LIST OID specifies an array of OIDs
- // for objects that the underlying driver or its NIC supports.
- // Objects include general, media-specific, and implementation-
- // specific objects. NDIS forwards a subset of the returned
- // list to protocols that make this query. That is, NDIS filters
- // any supported statistics OIDs out of the list because
- // protocols never make statistics queries.
- //
- pInfo = (PVOID) g_vboxNetFltWinMpSupportedOids;
- ulInfoLen = sizeof(g_vboxNetFltWinMpSupportedOids);
- break;
-
- case OID_GEN_HARDWARE_STATUS:
- //
- // Specify the current hardware status of the underlying NIC as
- // one of the following NDIS_HARDWARE_STATUS-type values.
- //
- pInfo = (PVOID) &HardwareStatus;
- ulInfoLen = sizeof(NDIS_HARDWARE_STATUS);
- break;
-
- case OID_GEN_MEDIA_SUPPORTED:
- //
- // Specify the media types that the NIC can support but not
- // necessarily the media types that the NIC currently uses.
- // fallthrough:
- case OID_GEN_MEDIA_IN_USE:
- //
- // Specify a complete list of the media types that the NIC
- // currently uses.
- //
- pInfo = (PVOID) &Medium;
- ulInfoLen = sizeof(NDIS_MEDIUM);
- break;
-
- case OID_GEN_CURRENT_LOOKAHEAD:
- case OID_GEN_MAXIMUM_LOOKAHEAD:
- //
- // If the miniport driver indicates received data by calling
- // NdisXxxIndicateReceive, it should respond to OID_GEN_MAXIMUM_LOOKAHEAD
- // with the maximum number of bytes the NIC can provide as
- // lookahead data. If that value is different from the size of the
- // lookahead buffer supported by bound protocols, NDIS will call
- // MiniportSetInformation to set the size of the lookahead buffer
- // provided by the miniport driver to the minimum of the miniport
- // driver and protocol(s) values. If the driver always indicates
- // up full packets with NdisMIndicateReceivePacket, it should
- // set this value to the maximum total packet size, which
- // excludes the header.
- // Upper-layer drivers examine lookahead data to determine whether
- // a packet that is associated with the lookahead data is intended
- // for one or more of their clients. If the underlying driver
- // supports multipacket receive indications, bound protocols are
- // given full net packets on every indication. Consequently,
- // this value is identical to that returned for
- // OID_GEN_RECEIVE_BLOCK_SIZE.
- //
- ulInfo = VBOXNETADP_MAX_LOOKAHEAD_SIZE;
- break;
-
- case OID_GEN_MAXIMUM_FRAME_SIZE:
- //
- // Specify the maximum network packet size, in bytes, that the
- // NIC supports excluding the header. A NIC driver that emulates
- // another medium type for binding to a transport must ensure that
- // the maximum frame size for a protocol-supplied net packet does
- // not exceed the size limitations for the true network medium.
- //
- ulInfo = VBOXNETADP_MAX_PACKET_SIZE - VBOXNETADP_HEADER_SIZE;
- break;
-
- case OID_GEN_MAXIMUM_TOTAL_SIZE:
- //
- // Specify the maximum total packet length, in bytes, the NIC
- // supports including the header. A protocol driver might use
- // this returned length as a gauge to determine the maximum
- // size packet that a NIC driver could forward to the
- // protocol driver. The miniport driver must never indicate
- // up to the bound protocol driver packets received over the
- // network that are longer than the packet size specified by
- // OID_GEN_MAXIMUM_TOTAL_SIZE.
- //
- case OID_GEN_TRANSMIT_BLOCK_SIZE:
- //
- // The OID_GEN_TRANSMIT_BLOCK_SIZE OID specifies the minimum
- // number of bytes that a single net packet occupies in the
- // transmit buffer space of the NIC. For example, a NIC that
- // has a transmit space divided into 256-byte pieces would have
- // a transmit block size of 256 bytes. To calculate the total
- // transmit buffer space on such a NIC, its driver multiplies
- // the number of transmit buffers on the NIC by its transmit
- // block size. In our case, the transmit block size is
- // identical to its maximum packet size.
-
- case OID_GEN_RECEIVE_BLOCK_SIZE:
- //
- // The OID_GEN_RECEIVE_BLOCK_SIZE OID specifies the amount of
- // storage, in bytes, that a single packet occupies in the receive
- // buffer space of the NIC.
- //
- ulInfo = (ULONG) VBOXNETADP_MAX_PACKET_SIZE;
- break;
-
- case OID_GEN_MAC_OPTIONS:
- //
- // Specify a bitmask that defines optional properties of the NIC.
- // This miniport indicates receive with NdisMIndicateReceivePacket
- // function. It has no MiniportTransferData function. Such a driver
- // should set this NDIS_MAC_OPTION_TRANSFERS_NOT_PEND flag.
- //
- // NDIS_MAC_OPTION_NO_LOOPBACK tells NDIS that NIC has no internal
- // loopback support so NDIS will manage loopbacks on behalf of
- // this driver.
- //
- // NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA tells the protocol that
- // our receive buffer is not on a device-specific card. If
- // NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA is not set, multi-buffer
- // indications are copied to a single flat buffer.
- //
- ulInfo = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
- NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
- NDIS_MAC_OPTION_NO_LOOPBACK;
- break;
-
- case OID_GEN_LINK_SPEED:
- //
- // Specify the maximum speed of the NIC in kbps.
- // The unit of measurement is 100 bps
- //
- ulInfo = VBOXNETADP_LINK_SPEED;
- break;
-
- case OID_GEN_TRANSMIT_BUFFER_SPACE:
- //
- // Specify the amount of memory, in bytes, on the NIC that
- // is available for buffering transmit data. A protocol can
- // use this OID as a guide for sizing the amount of transmit
- // data per send.
- //
- ulInfo = VBOXNETADP_MAX_PACKET_SIZE * PACKET_INFO_POOL_SIZE;
- break;
-
- case OID_GEN_RECEIVE_BUFFER_SPACE:
- //
- // Specify the amount of memory on the NIC that is available
- // for buffering receive data. A protocol driver can use this
- // OID as a guide for advertising its receive window after it
- // establishes sessions with remote nodes.
- //
-
- ulInfo = VBOXNETADP_MAX_PACKET_SIZE * PACKET_INFO_POOL_SIZE;
- break;
-
- case OID_GEN_VENDOR_ID:
- //
- // Specify a three-byte IEEE-registered vendor code, followed
- // by a single byte that the vendor assigns to identify a
- // particular NIC. The IEEE code uniquely identifies the vendor
- // and is the same as the three bytes appearing at the beginning
- // of the NIC hardware address. Vendors without an IEEE-registered
- // code should use the value 0xFFFFFF.
- //
- ulInfo = VBOXNETADP_VENDOR_ID;
- break;
-
- case OID_GEN_VENDOR_DESCRIPTION:
- //
- // Specify a zero-terminated string describing the NIC vendor.
- //
- pInfo = VendorDesc;
- ulInfoLen = sizeof(VendorDesc);
- break;
-
- case OID_GEN_VENDOR_DRIVER_VERSION:
- //
- // Specify the vendor-assigned version number of the NIC driver.
- // The low-order half of the return value specifies the minor
- // version; the high-order half specifies the major version.
- //
- ulInfo = VBOXNETADP_VENDOR_DRIVER_VERSION;
- break;
-
- case OID_GEN_DRIVER_VERSION:
- //
- // Specify the NDIS version in use by the NIC driver. The high
- // byte is the major version number; the low byte is the minor
- // version number.
- //
- usInfo = (USHORT) (VBOXNETFLT_MAJOR_NDIS_VERSION<<8) + VBOXNETFLT_MINOR_NDIS_VERSION;
- pInfo = (PVOID) &usInfo;
- ulInfoLen = sizeof(USHORT);
- break;
-
- case OID_GEN_MAXIMUM_SEND_PACKETS:
- //
- // If a miniport driver registers a MiniportSendPackets function,
- // MiniportQueryInformation will be called with the
- // OID_GEN_MAXIMUM_SEND_PACKETS request. The miniport driver must
- // respond with the maximum number of packets it is prepared to
- // handle on a single send request. The miniport driver should
- // pick a maximum that minimizes the number of packets that it
- // has to queue internally because it has no resources
- // (its device is full). A miniport driver for a bus-master DMA
- // NIC should attempt to pick a value that keeps its NIC filled
- // under anticipated loads.
- //
- ulInfo = PACKET_INFO_POOL_SIZE;
- break;
-
- case OID_GEN_MEDIA_CONNECT_STATUS:
- //
- // Return the connection status of the NIC on the network as one
- // of the following system-defined values: NdisMediaStateConnected
- // or NdisMediaStateDisconnected.
- //
-#ifdef VBOXNETADP_REPORT_DISCONNECTED
- {
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- bool bNetFltActive;
- bool bActive = vboxNetFltWinReferenceAdaptNetFltFromAdapt(pNetFlt, pAdapt, bNetFltActive);
- if(bActive && bNetFltActive)
- {
- ulInfo = NdisMediaStateConnected;
- }
- else
- {
- ulInfo = NdisMediaStateDisconnected;
- }
-
- if(bActive)
- {
- vboxNetFltWinDereferenceAdapt(pAdapt);
- }
- if(bNetFltActive)
- {
- vboxNetFltWinDereferenceNetFlt(pNetFlt);
- }
- else
- {
- vboxNetFltWinDereferenceModePassThru(pNetFlt);
- }
- }
-#else
- ulInfo = NdisMediaStateConnected;
-#endif
- break;
-
- case OID_GEN_CURRENT_PACKET_FILTER:
- //
- // Specify the types of net packets such as directed, broadcast
- // multicast, for which a protocol receives indications from a
- // NIC driver. After NIC is initialized, a protocol driver
- // can send a set OID_GEN_CURRENT_PACKET_FILTER to a non-zero value,
- // thereby enabling the miniport driver to indicate receive packets
- // to that protocol.
- //
- ulInfo = (
- NDIS_PACKET_TYPE_BROADCAST
- | NDIS_PACKET_TYPE_DIRECTED
- | NDIS_PACKET_TYPE_ALL_FUNCTIONAL
- | NDIS_PACKET_TYPE_ALL_LOCAL
- | NDIS_PACKET_TYPE_GROUP
- | NDIS_PACKET_TYPE_MULTICAST
- );
- break;
-
- case OID_PNP_CAPABILITIES:
- //
- // Return the wake-up capabilities of its NIC. If you return
- // NDIS_STATUS_NOT_SUPPORTED, NDIS considers the miniport driver
- // to be not Power management aware and doesn't send any power
- // or wake-up related queries such as
- // OID_PNP_SET_POWER, OID_PNP_QUERY_POWER,
- // OID_PNP_ADD_WAKE_UP_PATTERN, OID_PNP_REMOVE_WAKE_UP_PATTERN,
- // OID_PNP_ENABLE_WAKE_UP. Here, we are expecting the driver below
- // us to do the right thing.
- //
- RtlZeroMemory (&PMCaps, sizeof(NDIS_PNP_CAPABILITIES));
- ulInfoLen = sizeof (NDIS_PNP_CAPABILITIES);
- pInfo = (PVOID) &PMCaps;
- PMCaps.WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
- PMCaps.WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified;
- break;
-
- case OID_PNP_QUERY_POWER:
- Status = NDIS_STATUS_SUCCESS;
- break;
-
- //
- // Following 4 OIDs are for querying Ethernet Operational
- // Characteristics.
- //
- case OID_802_3_PERMANENT_ADDRESS:
- //
- // Return the MAC address of the NIC burnt in the hardware.
- //
- {
- PVBOXNETFLTINS pNetFlt = (PADAPT_2_PVBOXNETFLTINS(pAdapt));
- pInfo = &pNetFlt->u.s.MacAddr;
- ulInfoLen = VBOXNETADP_ETH_ADDRESS_LENGTH;
- }
- break;
-
- case OID_802_3_CURRENT_ADDRESS:
- //
- // Return the MAC address the NIC is currently programmed to
- // use. Note that this address could be different from the
- // permanent address as the user can override using
- // registry. Read NdisReadNetworkAddress doc for more info.
- //
- {
- PVBOXNETFLTINS pNetFlt = (PADAPT_2_PVBOXNETFLTINS(pAdapt));
- pInfo = &pNetFlt->u.s.MacAddr;
- ulInfoLen = VBOXNETADP_ETH_ADDRESS_LENGTH;
- }
- break;
-
- case OID_802_3_MAXIMUM_LIST_SIZE:
- //
- // The maximum number of multicast addresses the NIC driver
- // can manage. This list is global for all protocols bound
- // to (or above) the NIC. Consequently, a protocol can receive
- // NDIS_STATUS_MULTICAST_FULL from the NIC driver when
- // attempting to set the multicast address list, even if
- // the number of elements in the given list is less than
- // the number originally returned for this query.
- //
- ulInfo = VBOXNETADP_MAX_MCAST_LIST;
- break;
-
- case OID_802_3_MAC_OPTIONS:
- //
- // A protocol can use this OID to determine features supported
- // by the underlying driver such as NDIS_802_3_MAC_OPTION_PRIORITY.
- // Return zero indicating that it supports no options.
- //
- ulInfo = 0;
- break;
-
- //
- // Following list consists of both general and Ethernet
- // specific statistical OIDs.
- //
-
- case OID_GEN_XMIT_OK:
- ulInfo64 = pAdapt->cTxSuccess;
- pInfo = &ulInfo64;
- if (InformationBufferLength >= sizeof(ULONG64) ||
- InformationBufferLength == 0)
- {
- ulInfoLen = sizeof(ULONG64);
- }
- else
- {
- ulInfoLen = sizeof(ULONG);
- }
- // We should always report that 8 bytes are required to keep ndistest happy
- *BytesNeeded = sizeof(ULONG64);
- break;
-
- case OID_GEN_RCV_OK:
- ulInfo64 = pAdapt->cRxSuccess;
- pInfo = &ulInfo64;
- if (InformationBufferLength >= sizeof(ULONG64) ||
- InformationBufferLength == 0)
- {
- ulInfoLen = sizeof(ULONG64);
- }
- else
- {
- ulInfoLen = sizeof(ULONG);
- }
- // We should always report that 8 bytes are required to keep ndistest happy
- *BytesNeeded = sizeof(ULONG64);
- break;
-
- case OID_GEN_XMIT_ERROR:
-
- ulInfo = pAdapt->cTxError;
- break;
-
- case OID_GEN_RCV_ERROR:
- ulInfo = pAdapt->cRxError;
- break;
-
- case OID_GEN_RCV_NO_BUFFER:
- ulInfo = 0;
- break;
-
- case OID_GEN_RCV_CRC_ERROR:
- ulInfo = 0;
- break;
-
- case OID_GEN_TRANSMIT_QUEUE_LENGTH:
- ulInfo = PACKET_INFO_POOL_SIZE;
- break;
-
- case OID_802_3_RCV_ERROR_ALIGNMENT:
- ulInfo = 0;
- break;
-
- case OID_802_3_XMIT_ONE_COLLISION:
- ulInfo = 0;
- break;
-
- case OID_802_3_XMIT_MORE_COLLISIONS:
- ulInfo = 0;
- break;
-
- case OID_802_3_XMIT_DEFERRED:
- ulInfo = 0;
- break;
-
- case OID_802_3_XMIT_MAX_COLLISIONS:
- ulInfo = 0;
- break;
-
- case OID_802_3_RCV_OVERRUN:
- ulInfo = 0;
- break;
-
- case OID_802_3_XMIT_UNDERRUN:
- ulInfo = 0;
- break;
-
- case OID_802_3_XMIT_HEARTBEAT_FAILURE:
- ulInfo = 0;
- break;
-
- case OID_802_3_XMIT_TIMES_CRS_LOST:
- ulInfo = 0;
- break;
-
- case OID_802_3_XMIT_LATE_COLLISIONS:
- ulInfo = 0;
- break;
-
- default:
- Status = NDIS_STATUS_NOT_SUPPORTED;
- break;
- }
-
- if(Status == NDIS_STATUS_SUCCESS)
- {
- if(ulInfoLen <= InformationBufferLength)
- {
- // Copy result into InformationBuffer
- *BytesWritten = ulInfoLen;
- if(ulInfoLen)
- {
- NdisMoveMemory(InformationBuffer, pInfo, ulInfoLen);
- }
- }
- else
- {
- // too short
- *BytesNeeded = ulInfoLen;
- Status = NDIS_STATUS_BUFFER_TOO_SHORT;
- }
- }
-
-
- LogFlow(("<== vboxNetFltWinMpQueryInformation Status = 0x%08x\n",
- Status));
-
- return(Status);
-}
-
-NDIS_STATUS
-vboxNetFltWinMpSetMulticastList(
- IN PADAPT pAdapt,
- IN PVOID InformationBuffer,
- IN ULONG InformationBufferLength,
- OUT PULONG pBytesRead,
- OUT PULONG pBytesNeeded
- )
-/*++
-Routine Description:
- This routine will set up the adapter for a specified multicast
- address list.
-
-Arguments:
- IN PMP_ADAPTER Adapter - Pointer to adapter block
- InformationBuffer - Buffer for information
- InformationBufferLength Size of this buffer
- pBytesRead Specifies how much info is read
- BytesNeeded In case the buffer is smaller than
-
-Return Value:
-
- NDIS_STATUS
-
---*/
-{
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
-#if 0
- ULONG index;
-#endif
-
- LogFlow(("==> vboxNetFltWinMpSetMulticastList\n"));
-
- //
- // Initialize.
- //
- *pBytesNeeded = 0;
- *pBytesRead = InformationBufferLength;
-
- do
- {
- if (InformationBufferLength % VBOXNETADP_ETH_ADDRESS_LENGTH)
- {
- Status = NDIS_STATUS_INVALID_LENGTH;
- break;
- }
-
- if (InformationBufferLength > (VBOXNETADP_MAX_MCAST_LIST * VBOXNETADP_ETH_ADDRESS_LENGTH))
- {
- Status = NDIS_STATUS_MULTICAST_FULL;
- *pBytesNeeded = VBOXNETADP_MAX_MCAST_LIST * VBOXNETADP_ETH_ADDRESS_LENGTH;
- break;
- }
-#if 0
- //
- // Protect the list update with a lock if it can be updated by
- // another thread simultaneously.
- //
-
- NdisZeroMemory(pAdapt->aMCList,
- sizeof(pAdapt->aMCList));
-
- NdisMoveMemory(pAdapt->aMCList,
- InformationBuffer,
- InformationBufferLength);
-
- pAdapt->cMCList = InformationBufferLength / ETH_LENGTH_OF_ADDRESS;
-#endif
-
- }
- while (FALSE);
-
- //
- // Program the hardware to add support for these multicast addresses
- //
-
- LogFlow(("<== vboxNetFltWinMpSetMulticastList\n"));
-
- return(Status);
-
-}
-
-
-static NDIS_STATUS
-vboxNetFltWinMpSetInformation(
- IN NDIS_HANDLE MiniportAdapterContext,
- IN NDIS_OID Oid,
- IN PVOID InformationBuffer,
- IN ULONG InformationBufferLength,
- OUT PULONG BytesRead,
- OUT PULONG BytesNeeded)
-/*++
-
-Routine Description:
-
- This is the handler for an OID set operation.
- MiniportSetInformation runs at IRQL = DISPATCH_LEVEL.
-
-Arguments:
-
- MiniportAdapterContext Pointer to the adapter structure
- Oid Oid for this query
- InformationBuffer Buffer for information
- InformationBufferLength Size of this buffer
- BytesRead Specifies how much info is read
- BytesNeeded In case the buffer is smaller than what
- we need, tell them how much is needed
-
-Return Value:
-
- Return code from the NdisRequest below.
-
---*/
-{
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
- PADAPT pAdapt = (PADAPT) MiniportAdapterContext;
- PNDIS_PM_PACKET_PATTERN pPmPattern = NULL;
-
- LogFlow(("==> vboxNetFltWinMpSetInformation %s\n", vboxNetFltWinMpDbgGetOidName(Oid)));
-
- *BytesRead = 0;
- *BytesNeeded = 0;
-
- switch(Oid)
- {
- case OID_802_3_MULTICAST_LIST:
- //
- // Set the multicast address list on the NIC for packet reception.
- // The NIC driver can set a limit on the number of multicast
- // addresses bound protocol drivers can enable simultaneously.
- // NDIS returns NDIS_STATUS_MULTICAST_FULL if a protocol driver
- // exceeds this limit or if it specifies an invalid multicast
- // address.
- //
- Status = vboxNetFltWinMpSetMulticastList(
- pAdapt,
- InformationBuffer,
- InformationBufferLength,
- BytesRead,
- BytesNeeded);
- break;
-
- case OID_GEN_CURRENT_PACKET_FILTER:
- //
- // Program the hardware to indicate the packets
- // of certain filter types.
- //
- if(InformationBufferLength != sizeof(ULONG))
- {
- *BytesNeeded = sizeof(ULONG);
- Status = NDIS_STATUS_INVALID_LENGTH;
- break;
- }
-
- *BytesRead = InformationBufferLength;
-
- break;
-
- case OID_GEN_CURRENT_LOOKAHEAD:
- //
- // A protocol driver can set a suggested value for the number
- // of bytes to be used in its binding; however, the underlying
- // NIC driver is never required to limit its indications to
- // the value set.
- //
- if(InformationBufferLength != sizeof(ULONG)){
- *BytesNeeded = sizeof(ULONG);
- Status = NDIS_STATUS_INVALID_LENGTH;
- break;
- }
-
- break;
-
- case OID_PNP_SET_POWER:
- //
- // This OID notifies a miniport driver that its NIC will be
- // transitioning to the device power state specified in the
- // InformationBuffer. The miniport driver must always return
- // NDIS_STATUS_SUCCESS to an OID_PNP_SET_POWER request. An
- // OID_PNP_SET_POWER request may or may not be preceded by an
- // OID_PNP_QUERY_POWER request.
- //
- if (InformationBufferLength != sizeof(NDIS_DEVICE_POWER_STATE ))
- {
- Status = NDIS_STATUS_INVALID_LENGTH;
- break;
- }
-
- vboxNetFltWinMpProcessSetPowerOid(&Status, pAdapt, InformationBuffer, InformationBufferLength, BytesRead, BytesNeeded);
- break;
-/*
- case OID_PNP_ADD_WAKE_UP_PATTERN:
- //
- // This OID is sent by a protocol driver to a miniport driver to
- // specify a wake-up pattern. The wake-up pattern, along with its mask,
- // is described by an NDIS_PM_PACKET_PATTERN structure.
- //
- pPmPattern = (PNDIS_PM_PACKET_PATTERN) InformationBuffer;
- if (InformationBufferLength < sizeof(NDIS_PM_PACKET_PATTERN))
- {
- Status = NDIS_STATUS_BUFFER_TOO_SHORT;
-
- *BytesNeeded = sizeof(NDIS_PM_PACKET_PATTERN);
- break;
- }
- if (InformationBufferLength < pPmPattern->PatternOffset + pPmPattern->PatternSize)
- {
- Status = NDIS_STATUS_BUFFER_TOO_SHORT;
-
- *BytesNeeded = pPmPattern->PatternOffset + pPmPattern->PatternSize;
- break;
- }
- *BytesRead = pPmPattern->PatternOffset + pPmPattern->PatternSize;
- Status = NDIS_STATUS_SUCCESS;
- bForwardRequest = TRUE;
- break;
-
- case OID_PNP_REMOVE_WAKE_UP_PATTERN:
- //
- // This OID requests the miniport driver to delete a wake-up pattern
- // that it previously received in an OID_PNP_ADD_WAKE_UP_PATTERN request.
- // The wake-up pattern, along with its mask, is described by an
- // NDIS_PM_PACKET_PATTERN structure.
- //
- pPmPattern = (PNDIS_PM_PACKET_PATTERN) InformationBuffer;
- if (InformationBufferLength < sizeof(NDIS_PM_PACKET_PATTERN))
- {
- Status = NDIS_STATUS_BUFFER_TOO_SHORT;
-
- *BytesNeeded = sizeof(NDIS_PM_PACKET_PATTERN);
- break;
- }
- if (InformationBufferLength < pPmPattern->PatternOffset + pPmPattern->PatternSize)
- {
- Status = NDIS_STATUS_BUFFER_TOO_SHORT;
-
- *BytesNeeded = pPmPattern->PatternOffset + pPmPattern->PatternSize;
- break;
- }
- *BytesRead = pPmPattern->PatternOffset + pPmPattern->PatternSize;
- Status = NDIS_STATUS_SUCCESS;
- bForwardRequest = TRUE;
-
- break;
-
- case OID_PNP_ENABLE_WAKE_UP:
- //
- // This OID specifies which wake-up capabilities a miniport
- // driver should enable in its NIC. Before the miniport
- // transitions to a low-power state (that is, before NDIS
- // sends the miniport driver an OID_PNP_SET_POWER request),
- // NDIS sends the miniport an OID_PNP_ENABLE_WAKE_UP request to
- // enable the appropriate wake-up capabilities.
- //
- DEBUGP(MP_INFO, ("--> OID_PNP_ENABLE_WAKE_UP\n"));
- if(InformationBufferLength != sizeof(ULONG))
- {
- *BytesNeeded = sizeof(ULONG);
- Status = NDIS_STATUS_INVALID_LENGTH;
- break;
- }
- *BytesRead = sizeof(ULONG);
- Status = NDIS_STATUS_SUCCESS;
- bForwardRequest = TRUE;
- break;
-*/
- default:
- Status = NDIS_STATUS_INVALID_OID;
- break;
-
- }
-
-
- LogFlow(("<== vboxNetFltWinMpSetInformation Status = 0x%08x\n", Status));
-
- return(Status);
-}
-
-static PUCHAR vboxNetFltWinMpDbgGetOidName(ULONG oid)
-{
- PCHAR oidName;
-
- switch (oid){
-
- #undef MAKECASE
- #define MAKECASE(oidx) case oidx: oidName = #oidx; break;
-
- MAKECASE(OID_GEN_SUPPORTED_LIST)
- MAKECASE(OID_GEN_HARDWARE_STATUS)
- MAKECASE(OID_GEN_MEDIA_SUPPORTED)
- MAKECASE(OID_GEN_MEDIA_IN_USE)
- MAKECASE(OID_GEN_MAXIMUM_LOOKAHEAD)
- MAKECASE(OID_GEN_MAXIMUM_FRAME_SIZE)
- MAKECASE(OID_GEN_LINK_SPEED)
- MAKECASE(OID_GEN_TRANSMIT_BUFFER_SPACE)
- MAKECASE(OID_GEN_RECEIVE_BUFFER_SPACE)
- MAKECASE(OID_GEN_TRANSMIT_BLOCK_SIZE)
- MAKECASE(OID_GEN_RECEIVE_BLOCK_SIZE)
- MAKECASE(OID_GEN_VENDOR_ID)
- MAKECASE(OID_GEN_VENDOR_DESCRIPTION)
- MAKECASE(OID_GEN_CURRENT_PACKET_FILTER)
- MAKECASE(OID_GEN_CURRENT_LOOKAHEAD)
- MAKECASE(OID_GEN_DRIVER_VERSION)
- MAKECASE(OID_GEN_MAXIMUM_TOTAL_SIZE)
- MAKECASE(OID_GEN_PROTOCOL_OPTIONS)
- MAKECASE(OID_GEN_MAC_OPTIONS)
- MAKECASE(OID_GEN_MEDIA_CONNECT_STATUS)
- MAKECASE(OID_GEN_MAXIMUM_SEND_PACKETS)
- MAKECASE(OID_GEN_VENDOR_DRIVER_VERSION)
- MAKECASE(OID_GEN_SUPPORTED_GUIDS)
- MAKECASE(OID_GEN_NETWORK_LAYER_ADDRESSES)
- MAKECASE(OID_GEN_TRANSPORT_HEADER_OFFSET)
- MAKECASE(OID_GEN_MEDIA_CAPABILITIES)
- MAKECASE(OID_GEN_PHYSICAL_MEDIUM)
- MAKECASE(OID_GEN_XMIT_OK)
- MAKECASE(OID_GEN_RCV_OK)
- MAKECASE(OID_GEN_XMIT_ERROR)
- MAKECASE(OID_GEN_RCV_ERROR)
- MAKECASE(OID_GEN_RCV_NO_BUFFER)
- MAKECASE(OID_GEN_DIRECTED_BYTES_XMIT)
- MAKECASE(OID_GEN_DIRECTED_FRAMES_XMIT)
- MAKECASE(OID_GEN_MULTICAST_BYTES_XMIT)
- MAKECASE(OID_GEN_MULTICAST_FRAMES_XMIT)
- MAKECASE(OID_GEN_BROADCAST_BYTES_XMIT)
- MAKECASE(OID_GEN_BROADCAST_FRAMES_XMIT)
- MAKECASE(OID_GEN_DIRECTED_BYTES_RCV)
- MAKECASE(OID_GEN_DIRECTED_FRAMES_RCV)
- MAKECASE(OID_GEN_MULTICAST_BYTES_RCV)
- MAKECASE(OID_GEN_MULTICAST_FRAMES_RCV)
- MAKECASE(OID_GEN_BROADCAST_BYTES_RCV)
- MAKECASE(OID_GEN_BROADCAST_FRAMES_RCV)
- MAKECASE(OID_GEN_RCV_CRC_ERROR)
- MAKECASE(OID_GEN_TRANSMIT_QUEUE_LENGTH)
- MAKECASE(OID_GEN_GET_TIME_CAPS)
- MAKECASE(OID_GEN_GET_NETCARD_TIME)
- MAKECASE(OID_GEN_NETCARD_LOAD)
- MAKECASE(OID_GEN_DEVICE_PROFILE)
- MAKECASE(OID_GEN_INIT_TIME_MS)
- MAKECASE(OID_GEN_RESET_COUNTS)
- MAKECASE(OID_GEN_MEDIA_SENSE_COUNTS)
- MAKECASE(OID_PNP_CAPABILITIES)
- MAKECASE(OID_PNP_SET_POWER)
- MAKECASE(OID_PNP_QUERY_POWER)
- MAKECASE(OID_PNP_ADD_WAKE_UP_PATTERN)
- MAKECASE(OID_PNP_REMOVE_WAKE_UP_PATTERN)
- MAKECASE(OID_PNP_ENABLE_WAKE_UP)
- MAKECASE(OID_802_3_PERMANENT_ADDRESS)
- MAKECASE(OID_802_3_CURRENT_ADDRESS)
- MAKECASE(OID_802_3_MULTICAST_LIST)
- MAKECASE(OID_802_3_MAXIMUM_LIST_SIZE)
- MAKECASE(OID_802_3_MAC_OPTIONS)
- MAKECASE(OID_802_3_RCV_ERROR_ALIGNMENT)
- MAKECASE(OID_802_3_XMIT_ONE_COLLISION)
- MAKECASE(OID_802_3_XMIT_MORE_COLLISIONS)
- MAKECASE(OID_802_3_XMIT_DEFERRED)
- MAKECASE(OID_802_3_XMIT_MAX_COLLISIONS)
- MAKECASE(OID_802_3_RCV_OVERRUN)
- MAKECASE(OID_802_3_XMIT_UNDERRUN)
- MAKECASE(OID_802_3_XMIT_HEARTBEAT_FAILURE)
- MAKECASE(OID_802_3_XMIT_TIMES_CRS_LOST)
- MAKECASE(OID_802_3_XMIT_LATE_COLLISIONS)
-
- default:
- oidName = "<** UNKNOWN OID **>";
- break;
- }
-
- return oidName;
-}
-#endif
-
-/**
- * NDIS Miniport entry point called whenever protocols are done with
- * a packet that we had indicated up and they had queued up for returning
- * later.
- *
- * @param MiniportAdapterContext - pointer to ADAPT structure
- * @param Packet - packet being returned.
- * @return None. */
-DECLHIDDEN(VOID)
-vboxNetFltWinMpReturnPacket(
- IN NDIS_HANDLE MiniportAdapterContext,
- IN PNDIS_PACKET Packet
- )
-{
- PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
-
- {
- /*
- * This is a packet allocated from this IM's receive packet pool.
- * Reclaim our packet, and return the original to the driver below.
- */
-
- PNDIS_PACKET MyPacket;
- PRECV_RSVD RecvRsvd;
-
- RecvRsvd = (PRECV_RSVD)(Packet->MiniportReserved);
- MyPacket = RecvRsvd->pOriginalPkt;
-
- if(MyPacket)
- {
- /* the packet was sent from underlying miniport */
- NdisFreePacket(Packet);
- NdisReturnPackets(&MyPacket, 1);
- }
- else
- {
- PVOID pBufToFree = RecvRsvd->pBufToFree;
-
- /* the packet was sent from NetFlt */
- vboxNetFltWinFreeSGNdisPacket(Packet, !pBufToFree);
- if(pBufToFree)
- {
- vboxNetFltWinMemFree(pBufToFree);
- }
- }
-
- vboxNetFltWinDereferenceAdapt(pAdapt);
- }
-}
-
-/** Miniport's transfer data handler.
- *
- * @param Packet Destination packet
- * @param BytesTransferred Place-holder for how much data was copied
- * @param MiniportAdapterContext Pointer to the adapter structure
- * @param MiniportReceiveContext Context
- * @param ByteOffset Offset into the packet for copying data
- * @param BytesToTransfer How much to copy.
- * @return Status of transfer */
-static NDIS_STATUS
-vboxNetFltWinMpTransferData(
- OUT PNDIS_PACKET Packet,
- OUT PUINT BytesTransferred,
- IN NDIS_HANDLE MiniportAdapterContext,
- IN NDIS_HANDLE MiniportReceiveContext,
- IN UINT ByteOffset,
- IN UINT BytesToTransfer
- )
-{
-#ifndef VBOXNETADP
-
- PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
- NDIS_STATUS Status;
-
- /*
- * Return, if the device is OFF
- */
- if (vboxNetFltWinGetPowerState(&pAdapt->PTState) != NdisDeviceStateD0
- || vboxNetFltWinGetPowerState(&pAdapt->MPState) != NdisDeviceStateD0)
- {
- return NDIS_STATUS_FAILURE;
- }
-
- NdisTransferData(&Status,
- pAdapt->hBindingHandle,
- MiniportReceiveContext,
- ByteOffset,
- BytesToTransfer,
- Packet,
- BytesTransferred);
-
- return(Status);
-#else
- /* should never be here */
- Assert(0);
- return NDIS_STATUS_FAILURE;
-#endif
-}
-
-/**
- * Halt handler. All the hard-work for clean-up is done here.
- *
- * @param MiniportAdapterContext Pointer to the Adapter
- * @return None. */
-static VOID
-vboxNetFltWinMpHalt(
- IN NDIS_HANDLE MiniportAdapterContext
- )
-{
- PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
-#ifndef VBOXNETADP
- NDIS_STATUS Status;
-#endif
-
- LogFlow(("==>MiniportHalt: Adapt %p\n", pAdapt));
-
-#ifndef VBOXNETADP
-// Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitializing);
-// if(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitializing)
- if(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Disconnecting)
- {
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitializing);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitializing);
- /* we're called from protocolUnbinAdapter, do our job */
- /*
- * If we have a valid bind, close the miniport below the protocol
- */
- vboxNetFltWinPtCloseAdapter(pAdapt, &Status);
-
- Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitializing);
- vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
- }
- else
-#endif
- {
- /* we're NOT called from protocolUnbinAdapter, perform a full disconnect */
- NDIS_STATUS Status;
-
- Assert(/*vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initializing
- ||*/ vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized);
-#ifndef VBOXNETADP
- AssertBreakpoint();
-#endif
- Status = vboxNetFltWinDetachFromInterface(pAdapt, false);
- Assert(Status == NDIS_STATUS_SUCCESS);
-/* you can not access the pAdapt after closure
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
-#ifndef VBOXNETADP
- Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitialized);
- vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
-#endif
-*/
- }
-
- LogFlow(("<== MiniportHalt: pAdapt %p\n", pAdapt));
-}
-
-/**
- * register the miniport edge
- */
-DECLHIDDEN(NDIS_STATUS)
-vboxNetFltWinMpRegister(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
-{
- NDIS_MINIPORT_CHARACTERISTICS MChars;
- NDIS_STATUS Status;
-
- NdisMInitializeWrapper(&g_hNdisWrapperHandle, DriverObject, RegistryPath, NULL);
-
- /*
- * Register the miniport with NDIS. Note that it is the miniport
- * which was started as a driver and not the protocol. Also the miniport
- * must be registered prior to the protocol since the protocol's BindAdapter
- * handler can be initiated anytime and when it is, it must be ready to
- * start driver instances.
- */
-
- NdisZeroMemory(&MChars, sizeof(NDIS_MINIPORT_CHARACTERISTICS));
-
- MChars.MajorNdisVersion = VBOXNETFLT_MAJOR_NDIS_VERSION;
- MChars.MinorNdisVersion = VBOXNETFLT_MINOR_NDIS_VERSION;
-
- MChars.InitializeHandler = vboxNetFltWinMpInitialize;
- MChars.QueryInformationHandler = vboxNetFltWinMpQueryInformation;
- MChars.SetInformationHandler = vboxNetFltWinMpSetInformation;
- MChars.ResetHandler = NULL;
- MChars.TransferDataHandler = vboxNetFltWinMpTransferData;
- MChars.HaltHandler = vboxNetFltWinMpHalt;
-
- /*
- * We will disable the check for hang timeout so we do not
- * need a check for hang handler!
- */
- MChars.CheckForHangHandler = NULL;
- MChars.ReturnPacketHandler = vboxNetFltWinMpReturnPacket;
-
- /*
- * Either the Send or the SendPackets handler should be specified.
- * If SendPackets handler is specified, SendHandler is ignored
- */
- MChars.SendHandler = NULL; /* vboxNetFltWinMpSend; */
- MChars.SendPacketsHandler = vboxNetFltWinMpSendPackets;
-
-#ifndef VBOXNETADP
- Status = NdisIMRegisterLayeredMiniport(g_hNdisWrapperHandle,
- &MChars,
- sizeof(MChars),
- &g_hDriverHandle);
-#else
- Status = NdisMRegisterMiniport(
- g_hNdisWrapperHandle,
- &MChars,
- sizeof(MChars));
-#endif
- if(Status == NDIS_STATUS_SUCCESS)
- {
-# ifndef WIN9X
- NdisMRegisterUnloadHandler(g_hNdisWrapperHandle, vboxNetFltWinUnload);
-# endif
- }
-
- return Status;
-}
-
-/**
- * deregister the miniport edge
- */
-DECLHIDDEN(NDIS_STATUS)
-vboxNetFltWinMpDeregister()
-{
-#ifndef VBOXNETADP
- NdisIMDeregisterLayeredMiniport(g_hDriverHandle);
-#else
- /* don't need to do anything here */
-#endif
- NdisTerminateWrapper(g_hNdisWrapperHandle, NULL);
- return NDIS_STATUS_SUCCESS;
-}
-
-#ifndef VBOXNETADP
-/**
- * return the miniport edge handle
- */
-DECLHIDDEN(NDIS_HANDLE) vboxNetFltWinMpGetHandle()
-{
- return g_hDriverHandle;
-}
-
-/**
- * initialize the instance of a device used for ioctl handling
- */
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpInitializeDevideInstance(PADAPT pAdapt)
-{
- NDIS_STATUS Status;
- /*
- * Now ask NDIS to initialize our miniport (upper) edge.
- * Set the flag below to synchronize with a possible call
- * to our protocol Unbind handler that may come in before
- * our miniport initialization happens.
- */
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initializing);
- /* this is doe in vboxNetFltWinPtInitPADAPT*/
- /* NdisInitializeEvent(&pAdapt->MiniportInitEvent); */
-
- Status = NdisIMInitializeDeviceInstanceEx(g_hDriverHandle,
- &pAdapt->DeviceName,
- pAdapt);
- /* ensure we're taking into account the pAdapt->Status if our miniport halt handler was called */
- if(Status == NDIS_STATUS_SUCCESS)
- {
- if(pAdapt->Status == NDIS_STATUS_SUCCESS)
- {
-// Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized);
-// vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initialized);
- return NDIS_STATUS_SUCCESS;
- }
- AssertBreakpoint();
- vboxNetFltWinMpDeInitializeDevideInstance(pAdapt, &Status);
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
- return pAdapt->Status;
- }
- else
- {
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
- }
- return Status;
-}
-
-/**
- * deinitialize the instance of a device used for ioctl handling
- */
-DECLHIDDEN(bool) vboxNetFltWinMpDeInitializeDevideInstance(PADAPT pAdapt, PNDIS_STATUS pStatus)
-{
-# ifndef WIN9X
- NDIS_STATUS LocalStatus;
- /*
- * Check if we had called NdisIMInitializeDeviceInstanceEx and
- * we are awaiting a call to MiniportInitialize.
- */
- if (vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initializing)
- {
- /*
- * Try to cancel the pending IMInit process.
- */
- LocalStatus = NdisIMCancelInitializeDeviceInstance(
- g_hDriverHandle,
- &pAdapt->DeviceName);
-
- if (LocalStatus == NDIS_STATUS_SUCCESS)
- {
- /*
- * Successfully cancelled IM Initialization; our
- * Miniport Initialize routine will not be called
- * for this device.
- */
- Assert(pAdapt->hMiniportHandle == NULL);
- }
- else
- {
- /*
- * Our Miniport Initialize routine will be called
- * (may be running on another thread at this time).
- * Wait for it to finish.
- */
- NdisWaitEvent(&pAdapt->MiniportInitEvent, 0);
- }
-
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
- }
-#endif
-
- /*
- * Call NDIS to remove our device-instance. We do most of the work
- * inside the HaltHandler.
- *
- * The Handle will be NULL if our miniport Halt Handler has been called or
- * if the IM device was never initialized
- */
-
- if (vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized)
- {
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitializing);
-
- *pStatus = NdisIMDeInitializeDeviceInstance(pAdapt->hMiniportHandle);
-
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
-
- if (*pStatus != NDIS_STATUS_SUCCESS)
- {
- *pStatus = NDIS_STATUS_FAILURE;
- }
-
- return true;
- }
-
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
-
- return false;
-}
-#endif
-
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpReferenceControlDevice()
-{
- return vboxNetFltWinPtRegisterDevice();
-}
-
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDereferenceControlDevice()
-{
- return vboxNetFltWinPtDeregisterDevice();
-}
-
-#endif /* #ifndef VBOX_NETFLT_ONDEMAND_BIND*/
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h
deleted file mode 100644
index 9b121a56e..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* $Id: VBoxNetFltMp-win.h $ */
-/** @file
- * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Miniport edge of ndis filter driver
- */
-
-/*
- * Copyright (C) 2008 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.
- */
-/*
- * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
- * Copyright (c) 1993-1999, Microsoft Corporation
- */
-
-#ifndef ___VBoxNetFltMp_win_h___
-#define ___VBoxNetFltMp_win_h___
-
- #ifdef VBOX_NETFLT_ONDEMAND_BIND
- # error "unsupported (VBOX_NETFLT_ONDEMAND_BIND)"
- #else
-
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpRegister(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDeregister();
-DECLHIDDEN(NDIS_HANDLE) vboxNetFltWinMpGetHandle();
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpInitializeDevideInstance(PADAPT pAdapt);
-DECLHIDDEN(VOID) vboxNetFltWinMpReturnPacket(IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet);
-DECLHIDDEN(bool) vboxNetFltWinMpDeInitializeDevideInstance(PADAPT pAdapt, PNDIS_STATUS pStatus);
-DECLHIDDEN(VOID) vboxNetFltWinMpQueryPNPCapabilities(IN OUT PADAPT pAdapt, OUT PNDIS_STATUS pStatus);
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpReferenceControlDevice();
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDereferenceControlDevice();
-
- #ifdef VBOXNETADP
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoInitialization(PADAPT pAdapt, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext);
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoDeinitialization(PADAPT pAdapt);
- #endif
-
- #endif
-
-#endif
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c
deleted file mode 100644
index 983ca638d..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c
+++ /dev/null
@@ -1,2512 +0,0 @@
-/* $Id: VBoxNetFltPt-win.c $ */
-/** @file
- * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Protocol edge of ndis filter driver
- */
-
-/*
- * Copyright (C) 2008 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.
- */
-/*
- * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
- * Copyright (c) 1993-1999, Microsoft Corporation
- */
-
-#include "VBoxNetFltCommon-win.h"
-
-#ifdef VBOXNETADP
-# error "No protocol edge"
-#endif
-
-/** protocol handle */
-static NDIS_HANDLE g_hProtHandle = NULL;
-/** medium array used while opening underlying adaptor
- * we are actually binding to NdisMedium802_3 and NdisMediumWan
- * as specified in VBoxNetFlt.inf:
- * HKR, Ndi\Interfaces, FilterMediaTypes, , "ethernet, wan" */
-static NDIS_MEDIUM g_aMediumArray[] =
- {
- /* Ethernet */
- NdisMedium802_3,
- /* Wan */
- NdisMediumWan
- };
-
-/**
- * performs binding to the given adapter
- */
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(IN PADAPT pAdapt)
-#else
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(IN PADAPT pAdapt, IN PNDIS_STRING pOurDeviceName, IN PNDIS_STRING pBindToDeviceName)
-#endif
-{
- UINT MediumIndex;
- NDIS_STATUS Status, Sts;
-
- Assert(pAdapt->PTState.PowerState == NdisDeviceStateD3);
- Assert(pAdapt->PTState.OpState == kVBoxNetDevOpState_Deinitialized);
- Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
-
- vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Initializing);
-
- do
- {
-// NDIS_STATUS TmpStatus;
- /* copy the bind to dev name to our buffer */
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- NDIS_STRING BindToDeviceName;
- PNDIS_STRING pBindToDeviceName;
- PVBOXNETFLTINS pThis = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- PWSTR pUnicode;
- ULONG cbUnicode;
- ANSI_STRING AnsiStr;
-
- /* most Rtlxx functions we are using here require this */
- Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
-
- RtlInitAnsiString(&AnsiStr, pThis->szName);
- cbUnicode = RtlAnsiStringToUnicodeSize(&AnsiStr);
-
- pUnicode = alloca(cbUnicode);
- BindToDeviceName.Buffer = pUnicode;
- BindToDeviceName.MaximumLength = (USHORT)cbUnicode;
-
- Status = RtlAnsiStringToUnicodeString(&BindToDeviceName, &AnsiStr, FALSE);
- if(!NT_SUCCESS(Status))
- {
- Assert(0);
- break;
- }
-
- pBindToDeviceName = &BindToDeviceName;
-#else
- Status = vboxNetFltWinCopyString(&pAdapt->DeviceName, pOurDeviceName);
- if(Status != NDIS_STATUS_SUCCESS)
- {
- Assert(0);
- break;
- }
-#endif
-
- vboxNetFltWinSetPowerState(&pAdapt->PTState, NdisDeviceStateD0);
- pAdapt->Status = NDIS_STATUS_SUCCESS;
-
- NdisResetEvent(&pAdapt->hEvent);
-
- /*
- * Now open the adapter below and complete the initialization
- */
- NdisOpenAdapter(&Status,
- &Sts,
- &pAdapt->hBindingHandle,
- &MediumIndex,
- g_aMediumArray,
- sizeof(g_aMediumArray)/sizeof(NDIS_MEDIUM),
- g_hProtHandle,
- pAdapt,
- pBindToDeviceName,
- 0,
- NULL);
-
- if (Status == NDIS_STATUS_PENDING)
- {
- NdisWaitEvent(&pAdapt->hEvent, 0);
- Status = pAdapt->Status;
- }
-
- Assert(Status == NDIS_STATUS_SUCCESS);
- if(Status != NDIS_STATUS_SUCCESS)
- {
- vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
- pAdapt->hBindingHandle = NULL;
- LogRel(("NdisOpenAdapter failed, Status (0c%x)", Status));
- break;
- }
-
- Assert(pAdapt->hBindingHandle);
-
- pAdapt->Medium = g_aMediumArray[MediumIndex];
- vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Initialized);
-
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- Status = vboxNetFltWinMpInitializeDevideInstance(pAdapt);
- if (Status != NDIS_STATUS_SUCCESS)
- {
- Log(("BindAdapter: Adapt %p, IMInitializeDeviceInstance error %x\n",
- pAdapt, Status));
-
- vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitializing);
- vboxNetFltWinPtCloseAdapter(pAdapt, &Sts);
- vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
- break;
- }
-#endif
- } while(0);
-
- return Status;
-}
-
-/**
- * Called by NDIS to bind to a miniport below.
- * @param Status - Return status of bind here.
- * @param BindContext - Can be passed to NdisCompleteBindAdapter if this call is pended.
- * @param DeviceName - Device name to bind to. This is passed to NdisOpenAdapter.
- * @param SystemSpecific1 - Can be passed to NdisOpenProtocolConfiguration to read per-binding information
- * @param SystemSpecific2 - Unused
- * @return NDIS_STATUS_PENDING if this call is pended. In this case call NdisCompleteBindAdapter to complete.
- * Anything else Completes this call synchronously */
-static VOID
-vboxNetFltWinPtBindAdapter(
- OUT PNDIS_STATUS pStatus,
- IN NDIS_HANDLE BindContext,
- IN PNDIS_STRING pDeviceName,
- IN PVOID SystemSpecific1,
- IN PVOID SystemSpecific2
- )
-{
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- /* we initiate the binding ourselves by calling NdisOpenAdapter */
- LogFlow(("==> Protocol BindAdapter\n"));
- Assert(0);
- *pStatus = NDIS_STATUS_OPEN_FAILED;
- LogFlow(("<== Protocol BindAdapter\n"));
- return;
-#else
- NDIS_HANDLE ConfigHandle = NULL;
- PNDIS_CONFIGURATION_PARAMETER Param;
- NDIS_STRING DeviceStr = NDIS_STRING_CONST("UpperBindings");
- PADAPT pAdapt = NULL;
-
- UNREFERENCED_PARAMETER(BindContext);
- UNREFERENCED_PARAMETER(SystemSpecific2);
-
- LogFlow(("==> Protocol BindAdapter\n"));
-
- do
- {
- /* Access the configuration section for our binding-specific
- * parameters. */
-
- NdisOpenProtocolConfiguration(pStatus,
- &ConfigHandle,
- (PNDIS_STRING)SystemSpecific1);
-
- if (*pStatus != NDIS_STATUS_SUCCESS)
- {
- break;
- }
-
- /* Read the "UpperBindings" reserved key that contains a list
- * of device names representing our miniport instances corresponding
- * to this lower binding. Since this is a 1:1 IM driver, this key
- * contains exactly one name.
- *
- * If we want to implement a N:1 mux driver (N adapter instances
- * over a single lower binding), then UpperBindings will be a
- * MULTI_SZ containing a list of device names - we would loop through
- * this list, calling NdisIMInitializeDeviceInstanceEx once for
- * each name in it. */
-
- NdisReadConfiguration(pStatus,
- &Param,
- ConfigHandle,
- &DeviceStr,
- NdisParameterString);
- if (*pStatus != NDIS_STATUS_SUCCESS)
- {
- break;
- }
-
- *pStatus = vboxNetFltWinPtInitBind(&pAdapt, &Param->ParameterData.StringData, pDeviceName);
- if (*pStatus != NDIS_STATUS_SUCCESS)
- {
- break;
- }
- } while(FALSE);
-
- /*
- * Close the configuration handle now - see comments above with
- * the call to NdisIMInitializeDeviceInstanceEx.
- */
- if (ConfigHandle != NULL)
- {
- NdisCloseConfiguration(ConfigHandle);
- }
-
- LogFlow(("<== Protocol BindAdapter: pAdapt %p, Status %x\n", pAdapt, *pStatus));
-#endif
-}
-
-/**
- * Completion routine for NdisOpenAdapter issued from within the vboxNetFltWinPtBindAdapter. Simply
- * unblock the caller.
- *
- * @param ProtocolBindingContext Pointer to the adapter
- * @param Status Status of the NdisOpenAdapter call
- * @param OpenErrorStatus Secondary status(ignored by us).
- * @return None
- * */
-static VOID
-vboxNetFltWinPtOpenAdapterComplete(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN NDIS_STATUS Status,
- IN NDIS_STATUS OpenErrorStatus
- )
-{
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
-
- UNREFERENCED_PARAMETER(OpenErrorStatus);
-
- LogFlow(("==> vboxNetFltWinPtOpenAdapterComplete: Adapt %p, Status %x\n", pAdapt, Status));
- if(pAdapt->Status == NDIS_STATUS_SUCCESS)
- {
- pAdapt->Status = Status;
- }
- NdisSetEvent(&pAdapt->hEvent);
-}
-
-DECLHIDDEN(NDIS_STATUS)
-vboxNetFltWinPtDoUnbinding(PADAPT pAdapt, bool bOnUnbind)
-{
- NDIS_STATUS Status;
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- PNDIS_PACKET PacketArray[MAX_RECEIVE_PACKET_ARRAY_SIZE];
- ULONG NumberOfPackets = 0, i;
- BOOLEAN CompleteRequest = FALSE;
- BOOLEAN ReturnPackets = FALSE;
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- uint64_t NanoTS = RTTimeSystemNanoTS();
-#endif
- int cPPUsage;
-
- LogFlow(("==> vboxNetFltWinPtDoUnbinding: Adapt %p\n", pAdapt));
-
- Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
-
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Initialized);
- /*
- * Set the flag that the miniport below is unbinding, so the request handlers will
- * fail any request coming later
- */
- RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
-
- ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true);
- ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false);
- ASMAtomicUoWriteU64(&pNetFlt->NanoTSLastRediscovery, NanoTS);
-
-// pAdapt->PTState.DeviceState = NdisDeviceStateD3;
-// pAdapt->MPState.DeviceState = NdisDeviceStateD3;
- vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitializing);
- if(!bOnUnbind)
- {
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitializing);
- }
-
- if (pAdapt->bQueuedRequest == TRUE)
- {
- pAdapt->bQueuedRequest = FALSE;
- CompleteRequest = TRUE;
- }
- if (pAdapt->cReceivedPacketCount > 0)
- {
-
- NdisMoveMemory(PacketArray,
- pAdapt->aReceivedPackets,
- pAdapt->cReceivedPacketCount * sizeof(PNDIS_PACKET));
-
- NumberOfPackets = pAdapt->cReceivedPacketCount;
-
- pAdapt->cReceivedPacketCount = 0;
- ReturnPackets = TRUE;
- }
-
-
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
-
- if (CompleteRequest == TRUE)
- {
- vboxNetFltWinPtRequestComplete(pAdapt,
- &pAdapt->Request,
- NDIS_STATUS_FAILURE );
-
- }
- if (ReturnPackets == TRUE)
- {
- for (i = 0; i < NumberOfPackets; i++)
- {
- vboxNetFltWinMpReturnPacket(pAdapt, PacketArray[i]);
- }
- }
-
- vboxNetFltWinWaitDereference(&pAdapt->MPState);
-
- vboxNetFltWinWaitDereference(&pAdapt->PTState);
-
- /* check packet pool is empty */
- cPPUsage = NdisPacketPoolUsage(pAdapt->hSendPacketPoolHandle);
- Assert(cPPUsage == 0);
- cPPUsage = NdisPacketPoolUsage(pAdapt->hRecvPacketPoolHandle);
- Assert(cPPUsage == 0);
- /* for debugging only, ignore the err in release */
- NOREF(cPPUsage);
-
- while (ASMAtomicUoReadBool((volatile bool *)&pAdapt->bOutstandingRequests))
- {
- /*
- * sleep till outstanding requests complete
- */
- vboxNetFltWinSleep(2);
- }
-
- if(!bOnUnbind || !vboxNetFltWinMpDeInitializeDevideInstance(pAdapt, &Status))
-#endif /* #ifndef VBOX_NETFLT_ONDEMAND_BIND */
- {
- /*
- * We need to do some work here.
- * Close the binding below us
- * and release the memory allocated.
- */
- vboxNetFltWinPtCloseAdapter(pAdapt, &Status);
- vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
-
- if(!bOnUnbind)
- {
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitializing);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
- }
- else
- {
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
- }
- }
- else
- {
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
- }
-
- LogFlow(("<== vboxNetFltWinPtDoUnbinding: Adapt %p\n", pAdapt));
-
- return Status;
-}
-
-/**
- * Called by NDIS when we are required to unbind to the adapter below.
- * This functions shares functionality with the miniport's HaltHandler.
- * The code should ensure that NdisCloseAdapter and NdisFreeMemory is called
- * only once between the two functions
- *
- * @param Status Placeholder for return status
- * @param ProtocolBindingContext Pointer to the adapter structure
- * @param UnbindContext Context for NdisUnbindComplete() if this pends
- * @return NONE */
-static VOID
-vboxNetFltWinPtUnbindAdapter(
- OUT PNDIS_STATUS pStatus,
- IN NDIS_HANDLE ProtocolBindingContext,
- IN NDIS_HANDLE UnbindContext
- )
-{
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
- PVBOXNETFLTINS pNetFltIf = PADAPT_2_PVBOXNETFLTINS(pAdapt);
-
- LogFlow(("==> vboxNetFltWinPtUnbindAdapter: Adapt %p\n", pAdapt));
-
- *pStatus = vboxNetFltWinDetachFromInterface(pAdapt, true);
- Assert(*pStatus == NDIS_STATUS_SUCCESS);
-
- LogFlow(("<== vboxNetFltWinPtUnbindAdapter: Adapt %p\n", pAdapt));
-}
-
-/**
- * protocol unload handler
- */
-static VOID
-vboxNetFltWinPtUnloadProtocol(
- VOID
-)
-{
- vboxNetFltWinPtDeregister();
- LogFlow(("vboxNetFltWinPtUnloadProtocol: done!\n"));
-}
-
-
-/**
- * Completion for the CloseAdapter call.
- *
- * @param ProtocolBindingContext Pointer to the adapter structure
- * @param Status Completion status
- * @return None */
-static VOID
-vboxNetFltWinPtCloseAdapterComplete(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN NDIS_STATUS Status
- )
-{
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
-
- LogFlow(("CloseAdapterComplete: Adapt %p, Status %x\n", pAdapt, Status));
- if(pAdapt->Status == NDIS_STATUS_SUCCESS)
- {
- pAdapt->Status = Status;
- }
- NdisSetEvent(&pAdapt->hEvent);
-}
-
-
-/**
- * Completion for the reset.
- *
- * @param ProtocolBindingContext Pointer to the adapter structure
- * @param Status Completion status
- * @return None */
-static VOID
-vboxNetFltWinPtResetComplete(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN NDIS_STATUS Status
- )
-{
-
- UNREFERENCED_PARAMETER(ProtocolBindingContext);
- UNREFERENCED_PARAMETER(Status);
- /*
- * We never issue a reset, so we should not be here.
- */
- Assert(0);
-}
-
-/**
- * Completion handler for the previously posted request. All OIDS
- * are completed by and sent to the same miniport that they were requested for.
- * If Oid == OID_PNP_QUERY_POWER then the data structure needs to returned with all entries =
- * NdisDeviceStateUnspecified
- * @param ProtocolBindingContext Pointer to the adapter structure
- * @param NdisRequest The posted request
- * @param Status Completion status
- * @return None
- *
- */
-DECLHIDDEN(VOID)
-vboxNetFltWinPtRequestComplete(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN PNDIS_REQUEST NdisRequest,
- IN NDIS_STATUS Status
- )
-{
- PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
- PNDIS_REQUEST pSynchRequest = pAdapt->pSynchRequest;
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- NDIS_OID Oid = pAdapt->Request.DATA.SET_INFORMATION.Oid ;
-#endif
-
- if(pSynchRequest == NdisRequest)
- {
- /* asynchronous completion of our sync request */
-
- /*1.set the status */
- pAdapt->fSynchCompletionStatus = Status;
-
- /* 2. set event */
- KeSetEvent(&pAdapt->hSynchCompletionEvent, 0, FALSE);
-
- /* 3. return; */
- return;
- }
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- Assert(0);
- return;
-#else
-
- /*
- * Since our request is not outstanding anymore
- */
- Assert(pAdapt->bOutstandingRequests == TRUE);
-
- pAdapt->bOutstandingRequests = FALSE;
-
- /*
- * Complete the Set or Query, and fill in the buffer for OID_PNP_CAPABILITIES, if need be.
- */
- switch (NdisRequest->RequestType)
- {
- case NdisRequestQueryInformation:
-
- /*
- * We never pass OID_PNP_QUERY_POWER down.
- */
- Assert(Oid != OID_PNP_QUERY_POWER);
-
- if ((Oid == OID_PNP_CAPABILITIES) && (Status == NDIS_STATUS_SUCCESS))
- {
- vboxNetFltWinMpQueryPNPCapabilities(pAdapt, &Status);
- }
- *pAdapt->BytesReadOrWritten = NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;
- *pAdapt->BytesNeeded = NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;
-
- if ((Oid == OID_GEN_MAC_OPTIONS) && (Status == NDIS_STATUS_SUCCESS))
- {
- /* save mac options for adaptor below us to use it with the NdisCopyLookaheadData when our ProtocolReceive is called */
- pAdapt->fMacOptions = *(PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;
-#ifndef VBOX_LOOPBACK_USEFLAGS
- /*
- * Remove the no-loopback bit from mac-options. In essence we are
- * telling NDIS that we can handle loopback. We don't, but the
- * interface below us does. If we do not do this, then loopback
- * processing happens both below us and above us. This is wasteful
- * at best and if Netmon is running, it will see multiple copies
- * of loopback packets when sniffing above us.
- *
- * Only the lowest miniport is a stack of layered miniports should
- * ever report this bit set to NDIS.
- */
- *(PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer &= ~NDIS_MAC_OPTION_NO_LOOPBACK;
-#else
- /* we have to catch loopbacks from the underlying driver, so no duplications will occur,
- * just indicate NDIS to handle loopbacks for the packets coming from the protocol */
- *(PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer |= NDIS_MAC_OPTION_NO_LOOPBACK;
-#endif
- }
- if(Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
- {
- /* we're here _ONLY_ in the passthru mode */
- Assert(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_PASSTHRU);
- if(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_PASSTHRU)
- {
- PVBOXNETFLTINS pNetFltIf = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- Assert(pNetFltIf->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
- vboxNetFltWinDereferenceModePassThru(pNetFltIf);
- vboxNetFltWinDereferenceAdapt(pAdapt);
- }
-
- if(Status == NDIS_STATUS_SUCCESS)
- {
- /* the filter request is issued below only in case netflt is not active,
- * simply update the cache here */
- /* cache the filter used by upper protocols */
- pAdapt->fUpperProtocolSetFilter = *(PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;
- pAdapt->bUpperProtSetFilterInitialized = true;
- }
- }
-
-
- NdisMQueryInformationComplete(pAdapt->hMiniportHandle,
- Status);
- break;
-
- case NdisRequestSetInformation:
-
- Assert( Oid != OID_PNP_SET_POWER);
-
- if(Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
- {
- PVBOXNETFLTINS pNetFltIf = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- Assert(Status == NDIS_STATUS_SUCCESS);
- if(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_NETFLT)
- {
- Assert(pNetFltIf->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE);
- if(Status == NDIS_STATUS_SUCCESS)
- {
- pAdapt->fOurSetFilter = *((PULONG)pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer);
- Assert(pAdapt->fOurSetFilter == NDIS_PACKET_TYPE_PROMISCUOUS);
- }
- vboxNetFltWinDereferenceNetFlt(pNetFltIf);
- vboxNetFltWinDereferenceAdapt(pAdapt);
- pAdapt->fProcessingPacketFilter = 0;
- }
- else if(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_PASSTHRU)
- {
- Assert(pNetFltIf->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
-
- if(Status == NDIS_STATUS_SUCCESS)
- {
- /* the request was issued when the netflt was not active, simply update the cache here */
- pAdapt->fUpperProtocolSetFilter = *((PULONG)pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer);
- pAdapt->bUpperProtSetFilterInitialized = true;
- }
- vboxNetFltWinDereferenceModePassThru(pNetFltIf);
- vboxNetFltWinDereferenceAdapt(pAdapt);
- pAdapt->fProcessingPacketFilter = 0;
- }
- }
-
-
- *pAdapt->BytesReadOrWritten = NdisRequest->DATA.SET_INFORMATION.BytesRead;
- *pAdapt->BytesNeeded = NdisRequest->DATA.SET_INFORMATION.BytesNeeded;
- NdisMSetInformationComplete(pAdapt->hMiniportHandle,
- Status);
- break;
-
- default:
- Assert(0);
- break;
- }
-#endif
-}
-
-/**
- * Status handler for the lower-edge(protocol).
- *
- * @param ProtocolBindingContext Pointer to the adapter structure
- * @param GeneralStatus Status code
- * @param StatusBuffer Status buffer
- * @param StatusBufferSize Size of the status buffer
- * @return None
- */
-static VOID
-vboxNetFltWinPtStatus(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN NDIS_STATUS GeneralStatus,
- IN PVOID StatusBuffer,
- IN UINT StatusBufferSize
- )
-{
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
-
- /*
- * Pass up this indication only if the upper edge miniport is initialized
- * and powered on. Also ignore indications that might be sent by the lower
- * miniport when it isn't at D0.
- */
- if (vboxNetFltWinReferenceAdapt(pAdapt))
- {
- Assert(pAdapt->hMiniportHandle);
-
- if ((GeneralStatus == NDIS_STATUS_MEDIA_CONNECT) ||
- (GeneralStatus == NDIS_STATUS_MEDIA_DISCONNECT))
- {
-
- pAdapt->LastIndicatedStatus = GeneralStatus;
- }
- NdisMIndicateStatus(pAdapt->hMiniportHandle,
- GeneralStatus,
- StatusBuffer,
- StatusBufferSize);
-
- vboxNetFltWinDereferenceAdapt(pAdapt);
- }
- /*
- * Save the last indicated media status
- */
- else
- {
- if ((pAdapt->hMiniportHandle != NULL) &&
- ((GeneralStatus == NDIS_STATUS_MEDIA_CONNECT) ||
- (GeneralStatus == NDIS_STATUS_MEDIA_DISCONNECT)))
- {
- pAdapt->LatestUnIndicateStatus = GeneralStatus;
- }
- }
-#endif
-}
-
-/**
- * status complete handler
- */
-static VOID
-vboxNetFltWinPtStatusComplete(
- IN NDIS_HANDLE ProtocolBindingContext
- )
-{
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
-
- /*
- * Pass up this indication only if the upper edge miniport is initialized
- * and powered on. Also ignore indications that might be sent by the lower
- * miniport when it isn't at D0.
- */
- if (vboxNetFltWinReferenceAdapt(pAdapt))
- {
- NdisMIndicateStatusComplete(pAdapt->hMiniportHandle);
-
- vboxNetFltWinDereferenceAdapt(pAdapt);
- }
-#endif
-}
-
-/**
- * Called by NDIS when the miniport below had completed a send. We should
- * complete the corresponding upper-edge send this represents.
- *
- * @param ProtocolBindingContext - Points to ADAPT structure
- * @param Packet - Low level packet being completed
- * @param Status - status of send
- * @return None
- */
-static VOID
-vboxNetFltWinPtSendComplete(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN PNDIS_PACKET Packet,
- IN NDIS_STATUS Status
- )
-{
- PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
- PNDIS_PACKET Pkt;
-
- {
- PSEND_RSVD SendRsvd;
-
-#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
- /* @todo: for optimization we could check only for netflt-mode packets
- * do it for all for now */
- vboxNetFltWinLbRemoveSendPacket(pAdapt, Packet);
-#endif
-// Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
- SendRsvd = (PSEND_RSVD)(Packet->ProtocolReserved);
- Pkt = SendRsvd->pOriginalPkt;
-
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- if(Pkt)
- {
-#ifndef WIN9X
- NdisIMCopySendCompletePerPacketInfo (Pkt, Packet);
-#endif
- NdisFreePacket(Packet);
-
- /* the ptk was posted from the upperlying protocol */
- NdisMSendComplete(pAdapt->hMiniportHandle,
- Pkt,
- Status);
- }
- else
-#else
- /* TODO: should change the PSEND_RSVD structure as we no nolnger need to handle original packets
- * because all packets are originated by us */
- Assert(!Pkt);
-#endif
- {
- /* if the ptk is zero - the ptk was originated by netFlt send/receive
- * need to free packet buffers */
- PVOID pBufToFree = SendRsvd->pBufToFree;
-
- vboxNetFltWinFreeSGNdisPacket(Packet, !pBufToFree);
- if(pBufToFree)
- {
- vboxNetFltWinMemFree(pBufToFree);
- }
- }
- }
-
- vboxNetFltWinDereferenceAdapt(pAdapt);
-}
-
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
-
-/**
- * removes searches for the packet in the list and removes it if found
- * @return true if the packet was found and removed, false - otherwise
- */
-static bool vboxNetFltWinRemovePacketFromList(PINTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket)
-{
- PTRANSFERDATA_RSVD pTDR = (PTRANSFERDATA_RSVD)pPacket->ProtocolReserved;
- return vboxNetFltWinInterlockedSearchListEntry(pList, &pTDR->ListEntry,
- true /* remove*/);
-}
-
-/**
- * puts the packet to the tail of the list
- */
-static void vboxNetFltWinPutPacketToList(PINTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket, PNDIS_BUFFER pOrigBuffer)
-{
- PTRANSFERDATA_RSVD pTDR = (PTRANSFERDATA_RSVD)pPacket->ProtocolReserved;
- pTDR->pOriginalBuffer = pOrigBuffer;
- vboxNetFltWinInterlockedPutTail(pList, &pTDR->ListEntry);
-}
-
-/**
- * This is to queue the received packets and indicates them up if the given Packet
- * status is NDIS_STATUS_RESOURCES, or the array is full.
- *
- * @param pAdapt - Pointer to the adpater structure.
- * @param Packet - Pointer to the indicated packet.
- * @param Indicate - Do the indication now.
- * @return NONE
- */
-DECLHIDDEN(VOID) vboxNetFltWinPtQueueReceivedPacket(
- IN PADAPT pAdapt,
- IN PNDIS_PACKET Packet,
- IN BOOLEAN DoIndicate
- )
-{
- PNDIS_PACKET PacketArray[MAX_RECEIVE_PACKET_ARRAY_SIZE];
- ULONG NumberOfPackets = 0, i;
- bool bReturn = false;
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
-
- do{
- RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
-
- Assert(pAdapt->cReceivedPacketCount < MAX_RECEIVE_PACKET_ARRAY_SIZE);
-
- /*
- * pAdapt->ReceivePacketCount must be less than MAX_RECEIVE_PACKET_ARRAY_SIZE because
- * the thread which held the pVElan->Lock before should already indicate the packet(s)
- * up if pAdapt->ReceivePacketCount == MAX_RECEIVE_PACKET_ARRAY_SIZE.
- */
- pAdapt->aReceivedPackets[pAdapt->cReceivedPacketCount] = Packet;
- pAdapt->cReceivedPacketCount++;
-
- /* check the device state */
- if(vboxNetFltWinGetPowerState(&pAdapt->PTState) != NdisDeviceStateD0
- || vboxNetFltWinGetPowerState(&pAdapt->MPState) != NdisDeviceStateD0
- || vboxNetFltWinGetOpState(&pAdapt->PTState) > kVBoxNetDevOpState_Initialized
- || vboxNetFltWinGetOpState(&pAdapt->MPState) > kVBoxNetDevOpState_Initialized)
- {
- /* we need to return all packets */
- bReturn = true;
- }
-
- /*
- * If our receive packet array is full, or the miniport below indicated the packets
- * with resources, do the indicating now.
- */
-
- if ((pAdapt->cReceivedPacketCount == MAX_RECEIVE_PACKET_ARRAY_SIZE) || DoIndicate || bReturn)
- {
- NdisMoveMemory(PacketArray,
- pAdapt->aReceivedPackets,
- pAdapt->cReceivedPacketCount * sizeof(PNDIS_PACKET));
-
- NumberOfPackets = pAdapt->cReceivedPacketCount;
- /*
- * So other thread can queue the received packets
- */
- pAdapt->cReceivedPacketCount = 0;
-
- if(!bReturn)
- {
- DoIndicate = TRUE;
- }
- }
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- } while(0);
-
- if(!bReturn)
- {
- if(DoIndicate)
- {
- NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, PacketArray, NumberOfPackets);
- }
- }
- else
- {
- if (DoIndicate)
- {
- NumberOfPackets -= 1;
- }
- for (i = 0; i < NumberOfPackets; i++)
- {
- vboxNetFltWinMpReturnPacket(pAdapt, PacketArray[i]);
- }
- }
-}
-
-#endif
-
-static bool vboxNetFltWinPtTransferDataCompleteActive(IN PADAPT pAdapt,
- IN PNDIS_PACKET pPacket,
- IN NDIS_STATUS Status)
-{
- PVBOXNETFLTINS pNetFltIf = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- PNDIS_BUFFER pBuffer;
- PTRANSFERDATA_RSVD pTDR;
-
- if(!vboxNetFltWinRemovePacketFromList(&pAdapt->TransferDataList, pPacket))
- return false;
-
- pTDR = (PTRANSFERDATA_RSVD)pPacket->ProtocolReserved;
- Assert(pTDR);
- Assert(pTDR->pOriginalBuffer);
-
- do
- {
- NdisUnchainBufferAtFront(pPacket, &pBuffer);
-
- Assert(pBuffer);
-
- NdisFreeBuffer(pBuffer);
-
- pBuffer = pTDR->pOriginalBuffer;
-
- NdisChainBufferAtBack(pPacket, pBuffer);
-
- /* data transfer was initiated when the netFlt was active
- * the netFlt is still retained by us
- * 1. check if loopback
- * 2. enqueue packet
- * 3. release netFlt */
-
- if(Status == NDIS_STATUS_SUCCESS)
- {
-
-#ifdef VBOX_LOOPBACK_USEFLAGS
- if(vboxNetFltWinIsLoopedBackPacket(pPacket))
- {
- /* should not be here */
- Assert(0);
- }
-#else
- PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pAdapt, pPacket, false);
- if(pLb)
- {
-#ifndef DEBUG_NETFLT_RECV_TRANSFERDATA
- /* should not be here */
- Assert(0);
-#endif
- if(!vboxNetFltWinLbIsFromIntNet(pLb))
- {
- /* the packet is not from int net, need to pass it up to the host */
- vboxNetFltWinPtQueueReceivedPacket(pAdapt, pPacket, TRUE);
- /* dereference NetFlt, pAdapt will be dereferenced on Packet return */
- vboxNetFltWinDereferenceNetFlt(pNetFltIf);
- break;
- }
- }
-#endif
- else
- {
- PRECV_RSVD pRecvRsvd;
- /* 2. enqueue */
- /* use the same packet info to put the packet in the processing packet queue */
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
-# error "port me or remove VBOX_NETFLT_ONDEMAND_BIND"
- PNDIS_BUFFER pBuffer;
- PVOID pVA;
- UINT cbLength;
- uint32_t fFlags;
-
- NdisQueryPacket(pPacket, NULL, NULL, &pBuffer, NULL);
- NdisQueryBufferSafe(pBuffer, &pVA, &cbLength, NormalPagePriority);
-
- fFlags = MACS_EQUAL(((PRTNETETHERHDR)pVA)->SrcMac, pNetFltIf->u.s.MacAddr) ?
- PACKET_MINE | PACKET_SRC_HOST : PACKET_MINE;
- SET_FLAGS_TO_INFO(pInfo, fFlags);
-
- pRecvRsvd = (PRECV_RSVD)(pPacket->MiniportReserved);
- pRecvRsvd->pOriginalPkt = NULL;
- pRecvRsvd->pBufToFree = NULL;
-
- NdisSetPacketFlags(pPacket, 0);
-
- Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, fFlags);
-#else
- VBOXNETFLT_LBVERIFY(pNetFltIf, pPacket);
-
- pRecvRsvd = (PRECV_RSVD)(pPacket->MiniportReserved);
- pRecvRsvd->pOriginalPkt = NULL;
- pRecvRsvd->pBufToFree = NULL;
-
- NdisSetPacketFlags(pPacket, 0);
-# ifdef VBOXNETFLT_NO_PACKET_QUEUE
- if (vboxNetFltWinPostIntnet(pNetFltIf, pPacket, 0))
- {
- /* drop it */
- vboxNetFltWinFreeSGNdisPacket(pPacket, true);
- vboxNetFltWinDereferenceAdapt(pAdapt);
- }
- else
- {
- NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, &pPacket, 1);
- }
- vboxNetFltWinDereferenceNetFlt(pNetFltIf);
- break;
-# else
- Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, PACKET_MINE);
- if (Status == NDIS_STATUS_SUCCESS)
- {
- break;
- }
- Assert(0);
-# endif
-#endif
- }
- }
- else
- {
- Assert(0);
- }
- /* we are here because of error either in data transfer or in enqueueing the packet */
- vboxNetFltWinFreeSGNdisPacket(pPacket, true);
- vboxNetFltWinDereferenceNetFlt(pNetFltIf);
- vboxNetFltWinDereferenceAdapt(pAdapt);
- } while(0);
-
- return true;
-}
-
-/**
- * Entry point called by NDIS to indicate completion of a call by us
- * to NdisTransferData.
- *
- * See notes under SendComplete.
- */
-static VOID
-vboxNetFltWinPtTransferDataComplete(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN PNDIS_PACKET pPacket,
- IN NDIS_STATUS Status,
- IN UINT BytesTransferred
- )
-{
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
- if(!vboxNetFltWinPtTransferDataCompleteActive(pAdapt, pPacket, Status))
- {
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- if(pAdapt->hMiniportHandle)
- {
- NdisMTransferDataComplete(pAdapt->hMiniportHandle,
- pPacket,
- Status,
- BytesTransferred);
- }
-
- vboxNetFltWinDereferenceAdapt(pAdapt);
-#else
- /* we are here because we've failed to allocate packet info */
- Assert(0);
-#endif
- }
-}
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
-/**
- * This routine process the queued the packet, if anything is fine, indicate the packet
- * up, otherwise, return the packet to the underlying miniports.
- *
- * @param pAdapt - Pointer to the adpater structure.
- * @param bReturn - if true the packets should be returned without indication to the upper protocol
- * @return None. */
-DECLHIDDEN(VOID)
-vboxNetFltWinPtFlushReceiveQueue(
- IN PADAPT pAdapt,
- IN bool bReturn
- )
-{
-
- PNDIS_PACKET PacketArray[MAX_RECEIVE_PACKET_ARRAY_SIZE];
- ULONG NumberOfPackets = 0, i;
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
-
- do
- {
- RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
-
- if (pAdapt->cReceivedPacketCount > 0)
- {
- NdisMoveMemory(PacketArray,
- pAdapt->aReceivedPackets,
- pAdapt->cReceivedPacketCount * sizeof(PNDIS_PACKET));
-
- NumberOfPackets = pAdapt->cReceivedPacketCount;
- /*
- * So other thread can queue the received packets
- */
- pAdapt->cReceivedPacketCount = 0;
-
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
-
- if(!bReturn)
- {
- if(NumberOfPackets > 0)
- {
- Assert(pAdapt->hMiniportHandle);
-
- /* we are here because the NetFlt is NOT active,
- * so no need for packet queueing here, simply indicate */
- NdisMIndicateReceivePacket(pAdapt->hMiniportHandle,
- PacketArray,
- NumberOfPackets);
- }
- break;
- }
- /*
- * We need return the packet here
- */
- for (i = 0; i < NumberOfPackets; i ++)
- {
- vboxNetFltWinMpReturnPacket(pAdapt, PacketArray[i]);
- }
-
- /* break to ensure we do not call RTSpinlockRelease extra time */
- break;
- }
-
- /* we are here only in case pAdapt->cReceivedPacketCount == 0 */
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- } while (FALSE);
-}
-
-/**
- * ReceivePacket handler. Called by NDIS if the miniport below supports
- * NDIS 4.0 style receives. Re-package the buffer chain in a new packet
- * and indicate the new packet to protocols above us. Any context for
- * packets indicated up must be kept in the MiniportReserved field.
- *
- * @param ProtocolBindingContext - Pointer to our adapter structure.
- * @param Packet - Pointer to the packet
- * @return INT == 0 -> We are done with the packet
- * != 0 -> We will keep the packet and call NdisReturnPackets() this
- * many times when done. */
-static INT
-vboxNetFltWinRecvPacketPassThru(
- IN PADAPT pAdapt,
- IN PNDIS_PACKET pPacket,
- IN BOOLEAN bForceIndicate
- )
-{
- NDIS_STATUS fStatus;
- PNDIS_PACKET pMyPacket;
-
- Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
- fStatus = vboxNetFltWinPrepareRecvPacket(pAdapt, pPacket, &pMyPacket, true);
-
- Assert(pMyPacket);
-
- if(pMyPacket != NULL)
- {
- if (fStatus == NDIS_STATUS_RESOURCES)
- {
- vboxNetFltWinPtQueueReceivedPacket(pAdapt, pMyPacket, TRUE);
-
- /*
- * Our ReturnPackets handler will not be called for this packet.
- * We should reclaim it right here.
- */
- NdisDprFreePacket(pMyPacket);
-
- return 0;
- }
-
- vboxNetFltWinPtQueueReceivedPacket(pAdapt, pMyPacket, bForceIndicate);
-
- return 1;
- }
-
- return 0;
-}
-
-/**
- * process the packet receive in a "passthru" mode
- */
-static NDIS_STATUS
-vboxNetFltWinRecvPassThru(
- IN PADAPT pAdapt,
- IN PNDIS_PACKET pPacket)
-{
-
- NDIS_STATUS fStatus;
- PNDIS_PACKET pMyPacket;
- /*
- * The miniport below did indicate up a packet. Use information
- * from that packet to construct a new packet to indicate up.
- */
-
- Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
- /*
- * Get a packet off the pool and indicate that up
- */
- NdisDprAllocatePacket(&fStatus,
- &pMyPacket,
- pAdapt->hRecvPacketPoolHandle);
- Assert(fStatus == NDIS_STATUS_SUCCESS);
- if (fStatus == NDIS_STATUS_SUCCESS)
- {
- /*
- * Make our packet point to data from the original
- * packet. NOTE: this works only because we are
- * indicating a receive directly from the context of
- * our receive indication. If we need to queue this
- * packet and indicate it from another thread context,
- * we will also have to allocate a new buffer and copy
- * over the packet contents, OOB data and per-packet
- * information. This is because the packet data
- * is available only for the duration of this
- * receive indication call.
- */
- NDIS_PACKET_FIRST_NDIS_BUFFER(pMyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pPacket);
- NDIS_PACKET_LAST_NDIS_BUFFER(pMyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pPacket);
-
- /*
- * Get the original packet (it could be the same packet as the
- * one received or a different one based on the number of layered
- * miniports below) and set it on the indicated packet so the OOB
- * data is visible correctly at protocols above.
- */
- NDIS_SET_ORIGINAL_PACKET(pMyPacket, NDIS_GET_ORIGINAL_PACKET(pPacket));
- NDIS_SET_PACKET_HEADER_SIZE(pMyPacket, NDIS_GET_PACKET_HEADER_SIZE(pPacket));
-
- /*
- * Copy packet flags.
- */
- NdisGetPacketFlags(pMyPacket) = NdisGetPacketFlags(pPacket);
-
- /*
- * Force protocols above to make a copy if they want to hang
- * on to data in this packet. This is because we are in our
- * Receive handler (not ReceivePacket) and we can't return a
- * ref count from here.
- */
- NDIS_SET_PACKET_STATUS(pMyPacket, NDIS_STATUS_RESOURCES);
-
- /*
- * By setting NDIS_STATUS_RESOURCES, we also know that we can reclaim
- * this packet as soon as the call to NdisMIndicateReceivePacket
- * returns.
- *
- * NOTE: we queue the packet and indicate this packet immediately with
- * the already queued packets together. We have to the queue the packet
- * first because some versions of NDIS might call protocols'
- * ReceiveHandler(not ReceivePacketHandler) if the packet indicate status
- * is NDIS_STATUS_RESOURCES. If the miniport below indicates an array of
- * packets, some of them with status NDIS_STATUS_SUCCESS, some of them
- * with status NDIS_STATUS_RESOURCES, vboxNetFltWinPtReceive might be called, by
- * doing this way, we preserve the receive order of packets.
- */
- vboxNetFltWinPtQueueReceivedPacket(pAdapt, pMyPacket, TRUE);
- /*
- * Reclaim the indicated packet. Since we had set its status
- * to NDIS_STATUS_RESOURCES, we are guaranteed that protocols
- * above are done with it.
- */
- NdisDprFreePacket(pMyPacket);
-
- }
- return fStatus;
-}
-
-#endif /* #ifndef VBOX_NETFLT_ONDEMAND_BIND */
-
-
-
-
-/**
- * process the ProtocolReceive in an "active" mode
- *
- * @return NDIS_STATUS_SUCCESS - the packet is processed
- * NDIS_STATUS_PENDING - the packet is being processed, we are waiting for the ProtocolTransferDataComplete to be called
- * NDIS_STATUS_NOT_ACCEPTED - the packet is not needed - typically this is because this is a loopback packet
- * NDIS_STATUS_FAILURE - packet processing failed
- */
-static NDIS_STATUS
-vboxNetFltWinPtReceiveActive(
- IN PADAPT pAdapt,
- IN NDIS_HANDLE MacReceiveContext,
- IN PVOID pHeaderBuffer,
- IN UINT cbHeaderBuffer,
- IN PVOID pLookaheadBuffer,
- IN UINT cbLookaheadBuffer,
- IN UINT cbPacket
- )
-{
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
-
- do
- {
- if (cbHeaderBuffer != ETH_HEADER_SIZE)
- {
- Status = NDIS_STATUS_NOT_ACCEPTED;
- break;
- }
-
-#ifndef DEBUG_NETFLT_RECV_TRANSFERDATA
- if (cbPacket == cbLookaheadBuffer)
- {
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- PINTNETSG pSG;
- PUCHAR pRcvData;
-#ifndef VBOX_LOOPBACK_USEFLAGS
- PNDIS_PACKET pLb;
-#endif
-
- /* allocate SG buffer */
- Status = vboxNetFltWinAllocSG(cbPacket + cbHeaderBuffer, &pSG);
- if(Status != NDIS_STATUS_SUCCESS)
- {
- Assert(0);
- break;
- }
-
- pRcvData = (PUCHAR)pSG->aSegs[0].pv;
-
- NdisMoveMappedMemory(pRcvData, pHeaderBuffer, cbHeaderBuffer);
-
- NdisCopyLookaheadData(pRcvData+cbHeaderBuffer,
- pLookaheadBuffer,
- cbLookaheadBuffer,
- pAdapt->fMacOptions);
-#ifndef VBOX_LOOPBACK_USEFLAGS
- pLb = vboxNetFltWinLbSearchLoopBackBySG(pAdapt, pSG, false);
- if(pLb)
- {
-#ifndef DEBUG_NETFLT_RECV_NOPACKET
- /* should not be here */
- Assert(0);
-#endif
- if(!vboxNetFltWinLbIsFromIntNet(pLb))
- {
- PNDIS_PACKET pMyPacket;
- pMyPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, /* PADAPT */
- pSG, /* PINTNETSG */
- pSG, /* PVOID pBufToFree */
- false, /* bool bToWire */
- false); /* bool bCopyMemory */
- if(pMyPacket)
- {
- vboxNetFltWinPtQueueReceivedPacket(pAdapt, pMyPacket, TRUE);
- /* dereference the NetFlt here & indicate SUCCESS, which would mean the caller would not do a dereference
- * the pAdapt dereference will be done on packet return */
- vboxNetFltWinDereferenceNetFlt(pNetFlt);
- Status = NDIS_STATUS_SUCCESS;
- }
- else
- {
- vboxNetFltWinMemFree(pSG);
- Status = NDIS_STATUS_FAILURE;
- }
- }
- else
- {
- vboxNetFltWinMemFree(pSG);
- Status = NDIS_STATUS_NOT_ACCEPTED;
- }
- break;
- }
-#endif
- VBOXNETFLT_LBVERIFYSG(pNetFlt, pSG);
-
- /* enqueue SG */
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
-# ifdef VBOXNETFLT_NO_PACKET_QUEUE
-# error "port me or remove VBOX_NETFLT_ONDEMAND_BIND"
-# endif
- {
- uint32_t fFlags = MACS_EQUAL(((PRTNETETHERHDR)pRcvData)->SrcMac, pNetFlt->u.s.MacAddr) ?
- PACKET_SG | PACKET_MINE | PACKET_SRC_HOST : PACKET_SG | PACKET_MINE;
- Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pSG, fFlags);
- }
-#else
-# ifdef VBOXNETFLT_NO_PACKET_QUEUE
- if (vboxNetFltWinPostIntnet(pNetFlt, pSG, PACKET_SG))
- {
- /* drop it */
- vboxNetFltWinMemFree(pSG);
- vboxNetFltWinDereferenceAdapt(pAdapt);
- }
- else
- {
- PNDIS_PACKET pMyPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, /* PADAPT */
- pSG, /* PINTNETSG */
- pSG, /* PVOID pBufToFree */
- false, /* bool bToWire */
- false); /* bool bCopyMemory */
- Assert(pMyPacket);
- if (pMyPacket)
- {
- NDIS_SET_PACKET_STATUS(pMyPacket, NDIS_STATUS_SUCCESS);
-
- DBG_CHECK_PACKET_AND_SG(pMyPacket, pSG);
-
- LogFlow(("non-ndis packet info, packet created (%p)\n", pMyPacket));
- NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, &pMyPacket, 1);
- }
- else
- {
- vboxNetFltWinDereferenceAdapt(pAdapt);
- Status = NDIS_STATUS_RESOURCES;
- }
- }
- vboxNetFltWinDereferenceNetFlt(pNetFlt);
-# else
- Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pSG, PACKET_SG | PACKET_MINE);
- if(Status != NDIS_STATUS_SUCCESS)
- {
- Assert(0);
- vboxNetFltWinMemFree(pSG);
- break;
- }
-# endif
-#endif
- }
- else
-#endif /* #ifndef DEBUG_NETFLT_RECV_TRANSFERDATA */
- {
- PNDIS_PACKET pPacket;
- PNDIS_BUFFER pTransferBuffer;
- PNDIS_BUFFER pOrigBuffer;
- PUCHAR pMemBuf;
- UINT cbBuf = cbPacket + cbHeaderBuffer;
- UINT BytesTransferred;
-
- /* allocate NDIS Packet buffer */
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- /* use the Send packet pool for packet allocation */
- NdisAllocatePacket(&Status, &pPacket, pAdapt->hSendPacketPoolHandle);
-#else
- NdisAllocatePacket(&Status, &pPacket, pAdapt->hRecvPacketPoolHandle);
-#endif
- if(Status != NDIS_STATUS_SUCCESS)
- {
- Assert(0);
- break;
- }
-
- VBOXNETFLT_OOB_INIT(pPacket);
-
-#ifdef VBOX_LOOPBACK_USEFLAGS
- /* set "don't loopback" flags */
- NdisSetPacketFlags(pPacket, g_fPacketDontLoopBack);
-#else
- NdisSetPacketFlags(pPacket, 0);
-#endif
-
- Status = vboxNetFltWinMemAlloc(&pMemBuf, cbBuf);
- if(Status != NDIS_STATUS_SUCCESS)
- {
- Assert(0);
- NdisFreePacket(pPacket);
- break;
- }
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- /* use the Send buffer pool for buffer allocation */
- NdisAllocateBuffer(&Status, &pTransferBuffer, pAdapt->hSendBufferPoolHandle, pMemBuf + cbHeaderBuffer, cbPacket);
-#else
- NdisAllocateBuffer(&Status, &pTransferBuffer, pAdapt->hRecvBufferPoolHandle, pMemBuf + cbHeaderBuffer, cbPacket);
-#endif
- if(Status != NDIS_STATUS_SUCCESS)
- {
- Assert(0);
- Status = NDIS_STATUS_FAILURE;
- NdisFreePacket(pPacket);
- vboxNetFltWinMemFree(pMemBuf);
- break;
- }
-
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- /* use the Send buffer pool for buffer allocation */
- NdisAllocateBuffer(&Status, &pOrigBuffer, pAdapt->hSendBufferPoolHandle, pMemBuf, cbBuf);
-#else
- NdisAllocateBuffer(&Status, &pOrigBuffer, pAdapt->hRecvBufferPoolHandle, pMemBuf, cbBuf);
-#endif
- if(Status != NDIS_STATUS_SUCCESS)
- {
- Assert(0);
- Status = NDIS_STATUS_FAILURE;
- NdisFreeBuffer(pTransferBuffer);
- NdisFreePacket(pPacket);
- vboxNetFltWinMemFree(pMemBuf);
- break;
- }
-
- NdisChainBufferAtBack(pPacket, pTransferBuffer);
-
- NdisMoveMappedMemory(pMemBuf, pHeaderBuffer, cbHeaderBuffer);
-
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- vboxNetFltWinPutPacketToList(&pAdapt->TransferDataList, pPacket, pOrigBuffer);
-#endif
-
-#ifdef DEBUG_NETFLT_RECV_TRANSFERDATA
- if(cbPacket == cbLookaheadBuffer)
- {
- NdisCopyLookaheadData(pMemBuf+cbHeaderBuffer,
- pLookaheadBuffer,
- cbLookaheadBuffer,
- pAdapt->fMacOptions);
- }
- else
-#endif
- {
- Assert(cbPacket > cbLookaheadBuffer);
-
- NdisTransferData(
- &Status,
- pAdapt->hBindingHandle,
- MacReceiveContext,
- 0, /* ByteOffset */
- cbPacket,
- pPacket,
- &BytesTransferred);
- }
- if(Status != NDIS_STATUS_PENDING)
- {
- vboxNetFltWinPtTransferDataComplete(pAdapt, pPacket, Status, BytesTransferred);
- }
- }
- } while(0);
-
- return Status;
-}
-
-
-/**
- * Handle receive data indicated up by the miniport below. We pass
- * it along to the protocol above us.
- *
- * If the miniport below indicates packets, NDIS would more
- * likely call us at our ReceivePacket handler. However we
- * might be called here in certain situations even though
- * the miniport below has indicated a receive packet, e.g.
- * if the miniport had set packet status to NDIS_STATUS_RESOURCES.
- *
- * @param ProtocolBindingContext
- * @param MacReceiveContext
- * @param pHeaderBuffer
- * @param cbHeaderBuffer
- * @param pLookAheadBuffer
- * @param cbLookAheadBuffer
- * @param cbPacket
- * @return NDIS_STATUS_SUCCESS if we processed the receive successfully,
- * NDIS_STATUS_XXX error code if we discarded it. */
-static NDIS_STATUS
-vboxNetFltWinPtReceive(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN NDIS_HANDLE MacReceiveContext,
- IN PVOID pHeaderBuffer,
- IN UINT cbHeaderBuffer,
- IN PVOID pLookAheadBuffer,
- IN UINT cbLookAheadBuffer,
- IN UINT cbPacket
- )
-{
- PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
-#if 0
- uint32_t fFlags;
-#endif
-
- pNetFltIf = vboxNetFltWinReferenceAdaptNetFltFromAdapt(pAdapt);
- if(pNetFltIf)
- {
- do
- {
-#if 0
- pPacket = NdisGetReceivedPacket(pAdapt->hBindingHandle, MacReceiveContext);
- if(pPacket)
- {
-# ifdef DEBUG_NETFLT_LOOPBACK
-# error "implement (see comments in the sources below this #error:)"
- /* @todo FIXME no need for the PPACKET_INFO mechanism here;
- instead the the NDIS_PACKET.ProtocolReserved + INTERLOCKED_SINGLE_LIST mechanism \
- similar to that used in TrasferData handling should be used;
- */
-
-// if(vboxNetFltWinIsLoopedBackPacket(pAdapt, pPacket))
-# else
- if(vboxNetFltWinIsLoopedBackPacket(pPacket) || cbHeaderBuffer != ETH_HEADER_SIZE)
-# endif
-
- {
-// Assert(0);
- /* nothing else to do here, just return the packet */
-// NdisReturnPackets(&pPacket, 1);
-// break;
- }
-
- fFlags = MACS_EQUAL(((PRTNETETHERHDR)pHeaderBuffer)->SrcMac, pNetFltIf->u.s.MacAddr) ?
- PACKET_COPY | PACKET_SRC_HOST : PACKET_COPY;
- Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, fFlags);
- if(Status == NDIS_STATUS_SUCCESS)
- {
- NdisReturnPackets(&pPacket, 1);
- pAdapt = NULL;
- pNetFltIf = NULL;
- break;
- }
- }
-#endif
- Status = vboxNetFltWinPtReceiveActive(pAdapt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer,
- pLookAheadBuffer, cbLookAheadBuffer, cbPacket);
- if(NT_SUCCESS(Status))
- {
- if(Status != NDIS_STATUS_NOT_ACCEPTED)
- {
- pAdapt = NULL;
- pNetFltIf = NULL;
- }
- else
- {
- /* this is a looopback packet, nothing to do here */
- }
- break;
- }
- } while(0);
-
- if(pNetFltIf)
- vboxNetFltWinDereferenceNetFlt(pNetFltIf);
- if(pAdapt)
- vboxNetFltWinDereferenceAdapt(pAdapt);
-
-
-#if 0
- if(pPacket)
- {
- NdisReturnPackets(&pPacket, 1);
- }
-#endif
- /* we are here because the vboxNetFltWinPtReceiveActive returned pending,
- * which means our ProtocolDataTransferComplete we will called,
- * so return SUCCESS instead of NOT_ACCEPTED ?? */
-// return NDIS_STATUS_SUCCESS;
- }
- return NDIS_STATUS_NOT_ACCEPTED;
-#else /* if NOT defined VBOX_NETFLT_ONDEMAND_BIND */
- PNDIS_PACKET pPacket = NULL;
- bool bNetFltActive;
- bool fAdaptActive = vboxNetFltWinReferenceAdaptNetFlt(pNetFlt, pAdapt, &bNetFltActive);
- const bool bPassThruActive = !bNetFltActive;
- if(fAdaptActive)
- {
- do
- {
-#ifndef DEBUG_NETFLT_RECV_NOPACKET
- /*
- * Get at the packet, if any, indicated up by the miniport below.
- */
- pPacket = NdisGetReceivedPacket(pAdapt->hBindingHandle, MacReceiveContext);
- if (pPacket != NULL)
- {
-#ifndef VBOX_LOOPBACK_USEFLAGS
- PNDIS_PACKET pLb = NULL;
-#endif
- do
- {
-#ifdef VBOX_LOOPBACK_USEFLAGS
- if(vboxNetFltWinIsLoopedBackPacket(pPacket))
- {
- Assert(0);
- /* nothing else to do here, just return the packet */
- //NdisReturnPackets(&pPacket, 1);
- Status = NDIS_STATUS_NOT_ACCEPTED;
- break;
- }
-
- VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
-#endif
- if(bNetFltActive)
- {
-#ifndef VBOX_LOOPBACK_USEFLAGS
- pLb = vboxNetFltWinLbSearchLoopBack(pAdapt, pPacket, false);
- if(!pLb)
-#endif
- {
- VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
-
-#ifdef VBOXNETFLT_NO_PACKET_QUEUE
- if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0))
- {
- /* drop it */
- break;
- }
-#else
- Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, PACKET_COPY);
- Assert(Status == NDIS_STATUS_SUCCESS);
- if(Status == NDIS_STATUS_SUCCESS)
- {
- //NdisReturnPackets(&pPacket, 1);
- fAdaptActive = false;
- bNetFltActive = false;
- break;
- }
-#endif
- }
-#ifndef VBOX_LOOPBACK_USEFLAGS
- else if(vboxNetFltWinLbIsFromIntNet(pLb))
- {
- /* nothing else to do here, just return the packet */
- //NdisReturnPackets(&pPacket, 1);
- Status = NDIS_STATUS_NOT_ACCEPTED;
- break;
- }
- /* we are here because this is a looped back packet set not from intnet
- * we will post it to the upper protocol */
-#endif
- }
-
-#ifndef VBOX_LOOPBACK_USEFLAGS
- Assert(!pLb || !vboxNetFltWinLbIsFromIntNet(pLb));
-#endif
- Status = vboxNetFltWinRecvPassThru(pAdapt, pPacket);
- /* we are done with packet processing, and we will
- * not receive packet return event for this packet,
- * fAdaptActive should be true to ensure we release adapt*/
- Assert(fAdaptActive);
- } while(FALSE);
-
-#ifdef VBOXNETFLT_NO_PACKET_QUEUE
- if(Status == NDIS_STATUS_SUCCESS || Status == NDIS_STATUS_NOT_ACCEPTED
-# ifndef VBOX_LOOPBACK_USEFLAGS
- || pLb
-# endif
- )
-#endif
- {
- break;
- }
- }
-#endif
- if(bNetFltActive)
- {
- Status = vboxNetFltWinPtReceiveActive(pAdapt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer,
- pLookAheadBuffer, cbLookAheadBuffer, cbPacket);
- if(NT_SUCCESS(Status))
- {
- if(Status != NDIS_STATUS_NOT_ACCEPTED)
- {
- fAdaptActive = false;
- bNetFltActive = false;
- }
- else
- {
-#ifndef VBOX_LOOPBACK_USEFLAGS
- /* this is a loopback packet, nothing to do here */
-#else
- Assert(0);
- /* should not be here */
-#endif
- }
- break;
- }
- }
-
- /* Fall through if the miniport below us has either not
- * indicated a packet or we could not allocate one */
- if(pPacket != NULL)
- {
- /*
- * We are here because we failed to allocate packet
- */
- vboxNetFltWinPtFlushReceiveQueue(pAdapt, false);
- }
-
- /* we are done with packet processing, and we will
- * not receive packet return event for this packet,
- * fAdaptActive should be true to ensure we release adapt*/
- Assert(fAdaptActive);
-
- {
- /* Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case
- * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber
- * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64
- * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */
- ULONG Proc = KeGetCurrentProcessorNumber();
- Assert(Proc < RT_ELEMENTS(pAdapt->abIndicateRcvComplete));
- pAdapt->abIndicateRcvComplete[Proc] = TRUE;
- switch (pAdapt->Medium)
- {
- case NdisMedium802_3:
- case NdisMediumWan:
- NdisMEthIndicateReceive(pAdapt->hMiniportHandle,
- MacReceiveContext,
- (PCHAR)pHeaderBuffer,
- cbHeaderBuffer,
- pLookAheadBuffer,
- cbLookAheadBuffer,
- cbPacket);
- break;
- default:
- Assert(FALSE);
- break;
- }
- }
- } while(0);
-
- if(bNetFltActive)
- {
- vboxNetFltWinDereferenceNetFlt(pNetFlt);
- }
- else if(bPassThruActive)
- {
- vboxNetFltWinDereferenceModePassThru(pNetFlt);
- }
- if(fAdaptActive)
- {
- vboxNetFltWinDereferenceAdapt(pAdapt);
- }
- }
- else
- {
- Status = NDIS_STATUS_FAILURE;
- }
-
- return Status;
-#endif
-}
-
-/**
- * Called by the adapter below us when it is done indicating a batch of
- * received packets.
- *
- * @param ProtocolBindingContext Pointer to our adapter structure.
- * @return None */
-static VOID
-vboxNetFltWinPtReceiveComplete(
- IN NDIS_HANDLE ProtocolBindingContext
- )
-{
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- ULONG NumberOfPackets = 0;
- /* since the receive array queued packets do not hold the reference we need to
- * reference the PassThru/NetFlt mode here to avoid packet reordering caused by
- * concurrently running vboxNetFltWinPtReceiveComplete and vboxNetFltPortOsSetActive
- * on netflt activation/deactivation */
- bool bNetFltActive;
- bool fAdaptActive = vboxNetFltWinReferenceAdaptNetFlt(pNetFlt, pAdapt, &bNetFltActive);
- /* Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case
- * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber
- * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64
- * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */
- ULONG Proc = KeGetCurrentProcessorNumber();
- Assert(Proc < RT_ELEMENTS(pAdapt->abIndicateRcvComplete));
-
- vboxNetFltWinPtFlushReceiveQueue(pAdapt, false);
-
- if ((pAdapt->hMiniportHandle != NULL)
- /* && (pAdapt->MPDeviceState == NdisDeviceStateD0) */
- && (pAdapt->abIndicateRcvComplete[Proc] == TRUE))
- {
- switch (pAdapt->Medium)
- {
- case NdisMedium802_3:
- case NdisMediumWan:
- NdisMEthIndicateReceiveComplete(pAdapt->hMiniportHandle);
- break;
- default:
- Assert(FALSE);
- break;
- }
- }
-
- pAdapt->abIndicateRcvComplete[Proc] = FALSE;
-
- if(fAdaptActive)
- {
- if(bNetFltActive)
- {
- vboxNetFltWinDereferenceNetFlt(pNetFlt);
- }
- else
- {
- vboxNetFltWinDereferenceModePassThru(pNetFlt);
- }
- vboxNetFltWinDereferenceAdapt(pAdapt);
- }
-#endif
-}
-
-/**
- * ReceivePacket handler. Called by NDIS if the miniport below supports
- * NDIS 4.0 style receives. Re-package the buffer chain in a new packet
- * and indicate the new packet to protocols above us. Any context for
- * packets indicated up must be kept in the MiniportReserved field.
- *
- * @param ProtocolBindingContext - Pointer to our adapter structure.
- * @param Packet - Pointer to the packet
- * @return == 0 -> We are done with the packet,
- * != 0 -> We will keep the packet and call NdisReturnPackets() this many times when done.
- */
-static INT
-vboxNetFltWinPtReceivePacket(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN PNDIS_PACKET pPacket
- )
-{
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
- INT cRefCount = 0;
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- PNDIS_BUFFER pBuffer;
- PVOID pVA;
- UINT cbLength;
- uint32_t fFlags;
-
- pNetFltIf = vboxNetFltWinReferenceAdaptNetFltFromAdapt(pAdapt);
-
- if(pNetFltIf)
- {
- NDIS_STATUS Status;
- bool bResources;
- do
- {
-#ifdef DEBUG_NETFLT_LOOPBACK
-# error "implement (see comments in the sources below this #error:)"
- /* @todo FIXME no need for the PPACKET_INFO mechanism here;
- instead the the NDIS_PACKET.ProtocolReserved + INTERLOCKED_SINGLE_LIST mechanism \
- similar to that used in TrasferData handling should be used;
- */
-
-// if(vboxNetFltWinIsLoopedBackPacket(pAdapt, pPacket))
-#else
- if(vboxNetFltWinIsLoopedBackPacket(pPacket))
-#endif
-
- {
- Assert(0);
- NdisReturnPackets(&pPacket, 1);
- break;
- }
- bResources = NDIS_GET_PACKET_STATUS(pPacket) == NDIS_STATUS_RESOURCES;
-
- NdisQueryPacket(pPacket, NULL, NULL, &pBuffer, NULL);
- if(!pBuffer)
- {
- Assert(0);
- NdisReturnPackets(&pPacket, 1);
- cRefCount = 0;
- break;
- }
-
- NdisQueryBufferSafe(pBuffer, &pVA, &cbLength, NormalPagePriority);
- if(!pVA || !cbLength)
- {
- Assert(0);
- NdisReturnPackets(&pPacket, 1);
- cRefCount = 0;
- break;
- }
-
- fFlags = MACS_EQUAL(((PRTNETETHERHDR)pVA)->SrcMac, pNetFltIf->u.s.MacAddr) ? PACKET_SRC_HOST : 0;
-
- Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, bResources ? fFlags | PACKET_COPY : fFlags);
- if(Status == NDIS_STATUS_SUCCESS)
- {
- if(bResources)
- {
- cRefCount = 0;
- NdisReturnPackets(&pPacket, 1);
- }
- else
- {
- cRefCount = 1;
- }
- pNetFltIf = NULL;
- pAdapt = NULL;
- break;
- }
- else
- {
- Assert(0);
- NdisReturnPackets(&pPacket, 1);
- cRefCount = 0;
- break;
- }
- } while (0);
-
- if(pNetFltIf)
- vboxNetFltWinDereferenceNetFlt(pNetFltIf);
- if(pAdapt)
- vboxNetFltWinDereferenceAdapt(pAdapt);
- return cRefCount;
- }
- /* we are here because we are inactive, simply return the packet */
- NdisReturnPackets(&pPacket, 1);
- return 0;
-#else
- bool bNetFltActive;
- bool fAdaptActive = vboxNetFltWinReferenceAdaptNetFlt(pNetFlt, pAdapt, &bNetFltActive);
- const bool bPassThruActive = !bNetFltActive;
- if(fAdaptActive)
- {
- do
- {
-#ifdef VBOX_LOOPBACK_USEFLAGS
- if(vboxNetFltWinIsLoopedBackPacket(pPacket))
- {
- Assert(0);
- Log(("lb_rp"));
-
- /* nothing else to do here, just return the packet */
- cRefCount = 0;
- //NdisReturnPackets(&pPacket, 1);
- break;
- }
-
- VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
-#endif
-
- if(bNetFltActive)
- {
-#ifndef VBOX_LOOPBACK_USEFLAGS
- PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pAdapt, pPacket, false);
- if(!pLb)
-#endif
- {
-#ifndef VBOXNETFLT_NO_PACKET_QUEUE
- NDIS_STATUS fStatus;
-#endif
- bool bResources = NDIS_GET_PACKET_STATUS(pPacket) == NDIS_STATUS_RESOURCES;
-
- VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
-
- /*TODO: remove this assert.
- * this is a temporary assert for debugging purposes:
- * we're probably doing something wrong with the packets if the miniport reports NDIS_STATUS_RESOURCES */
- Assert(!bResources);
-
-#ifdef VBOXNETFLT_NO_PACKET_QUEUE
- if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0))
- {
- /* drop it */
- cRefCount = 0;
- break;
- }
-
-#else
- fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, bResources ? PACKET_COPY : 0);
- if(fStatus == NDIS_STATUS_SUCCESS)
- {
- bNetFltActive = false;
- fAdaptActive = false;
- if(bResources)
- {
- cRefCount = 0;
- //NdisReturnPackets(&pPacket, 1);
- }
- else
- {
- cRefCount = 1;
- }
- break;
- }
- else
- {
- Assert(0);
- }
-#endif
- }
-#ifndef VBOX_LOOPBACK_USEFLAGS
- else if(vboxNetFltWinLbIsFromIntNet(pLb))
- {
- /* the packet is from intnet, it has already been set to the host,
- * no need for loopng it back to the host again */
- /* nothing else to do here, just return the packet */
- cRefCount = 0;
- //NdisReturnPackets(&pPacket, 1);
- break;
- }
-#endif
- }
-
- cRefCount = vboxNetFltWinRecvPacketPassThru(pAdapt, pPacket, bNetFltActive);
- if(cRefCount)
- {
- Assert(cRefCount == 1);
- fAdaptActive = false;
- }
-
- } while(FALSE);
-
- if(bNetFltActive)
- {
- vboxNetFltWinDereferenceNetFlt(pNetFlt);
- }
- else if(bPassThruActive)
- {
- vboxNetFltWinDereferenceModePassThru(pNetFlt);
- }
- if(fAdaptActive)
- {
- vboxNetFltWinDereferenceAdapt(pAdapt);
- }
- }
- else
- {
- cRefCount = 0;
- //NdisReturnPackets(&pPacket, 1);
- }
-
- return cRefCount;
-#endif
-}
-
-/**
- * This routine is called from NDIS to notify our protocol edge of a
- * reconfiguration of parameters for either a specific binding (pAdapt
- * is not NULL), or global parameters if any (pAdapt is NULL).
- *
- * @param pAdapt - Pointer to our adapter structure.
- * @param pNetPnPEvent - the reconfigure event
- * @return NDIS_STATUS_SUCCESS */
-static NDIS_STATUS
-vboxNetFltWinPtPnPNetEventReconfigure(
- IN PADAPT pAdapt,
- IN PNET_PNP_EVENT pNetPnPEvent
- )
-{
- NDIS_STATUS ReconfigStatus = NDIS_STATUS_SUCCESS;
- NDIS_STATUS ReturnStatus = NDIS_STATUS_SUCCESS;
-
- do
- {
- /*
- * Is this is a global reconfiguration notification ?
- */
- if (pAdapt == NULL)
- {
- /*
- * An important event that causes this notification to us is if
- * one of our upper-edge miniport instances was enabled after being
- * disabled earlier, e.g. from Device Manager in Win2000. Note that
- * NDIS calls this because we had set up an association between our
- * miniport and protocol entities by calling NdisIMAssociateMiniport.
- *
- * Since we would have torn down the lower binding for that miniport,
- * we need NDIS' assistance to re-bind to the lower miniport. The
- * call to NdisReEnumerateProtocolBindings does exactly that.
- */
- NdisReEnumerateProtocolBindings (g_hProtHandle);
- break;
- }
-
- ReconfigStatus = NDIS_STATUS_SUCCESS;
-
- } while(FALSE);
-
- LogFlow(("<==PtPNPNetEventReconfigure: pAdapt %p\n", pAdapt));
-
- return ReconfigStatus;
-}
-
-static NDIS_STATUS
-vboxNetFltWinPtPnPNetEventBindsComplete(
- IN PADAPT pAdapt,
- IN PNET_PNP_EVENT pNetPnPEvent
- )
-{
- return NDIS_STATUS_SUCCESS;
-}
-
-DECLHIDDEN(bool) vboxNetFltWinPtCloseAdapter(PADAPT pAdapt, PNDIS_STATUS pStatus)
-{
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
-
- RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
-
- if(pAdapt->bClosingAdapter)
- {
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- Assert(0);
- return false;
- }
- if (pAdapt->hBindingHandle == NULL)
- {
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- Assert(0);
- return false;
- }
-
- pAdapt->bClosingAdapter = true;
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
-
- /*
- * Close the binding below. and wait for it to complete
- */
- NdisResetEvent(&pAdapt->hEvent);
-
- NdisCloseAdapter(pStatus, pAdapt->hBindingHandle);
-
- if (*pStatus == NDIS_STATUS_PENDING)
- {
- NdisWaitEvent(&pAdapt->hEvent, 0);
- *pStatus = pAdapt->Status;
- }
-
- Assert (*pStatus == NDIS_STATUS_SUCCESS);
-
- pAdapt->hBindingHandle = NULL;
-
- return true;
-}
-
-/**
- * This is a notification to our protocol edge of the power state
- * of the lower miniport. If it is going to a low-power state, we must
- * wait here for all outstanding sends and requests to complete.
- *
- * @param pAdapt - Pointer to the adpater structure
- * @param pNetPnPEvent - The Net Pnp Event. this contains the new device state
- * @return NDIS_STATUS_SUCCESS or the status returned by upper-layer protocols.
- * */
-static NDIS_STATUS
-vboxNetFltWinPtPnPNetEventSetPower(
- IN PADAPT pAdapt,
- IN PNET_PNP_EVENT pNetPnPEvent
- )
-{
- PNDIS_DEVICE_POWER_STATE pDeviceState =(PNDIS_DEVICE_POWER_STATE)(pNetPnPEvent->Buffer);
- NDIS_DEVICE_POWER_STATE PrevDeviceState = vboxNetFltWinGetPowerState(&pAdapt->PTState);
- NDIS_STATUS ReturnStatus;
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- int cPPUsage;
-
- ReturnStatus = NDIS_STATUS_SUCCESS;
-
- /*
- * Set the Internal Device State, this blocks all new sends or receives
- */
- RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
-
- vboxNetFltWinSetPowerState(&pAdapt->PTState, *pDeviceState);
-
- /*
- * Check if the miniport below is going to a low power state.
- */
- if (vboxNetFltWinGetPowerState(&pAdapt->PTState) > NdisDeviceStateD0)
- {
- /*
- * If the miniport below is going to standby, fail all incoming requests
- */
- if (PrevDeviceState == NdisDeviceStateD0)
- {
- pAdapt->bStandingBy = TRUE;
- }
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
-
- vboxNetFltWinPtFlushReceiveQueue(pAdapt, false);
-
- vboxNetFltWinWaitDereference(&pAdapt->MPState);
-#endif
-
- /*
- * Wait for outstanding sends and requests to complete.
- */
- vboxNetFltWinWaitDereference(&pAdapt->PTState);
-
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- while (ASMAtomicUoReadBool((volatile bool *)&pAdapt->bOutstandingRequests))
- {
- /*
- * sleep till outstanding requests complete
- */
- vboxNetFltWinSleep(2);
- }
-
- /*
- * If the below miniport is going to low power state, complete the queued request
- */
- RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
- if (pAdapt->bQueuedRequest)
- {
- pAdapt->bQueuedRequest = FALSE;
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- vboxNetFltWinPtRequestComplete(pAdapt, &pAdapt->Request, NDIS_STATUS_FAILURE);
- }
- else
- {
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- }
-#endif
-
- /* check packet pool is empty */
- cPPUsage = NdisPacketPoolUsage(pAdapt->hSendPacketPoolHandle);
- Assert(cPPUsage == 0);
- cPPUsage = NdisPacketPoolUsage(pAdapt->hRecvPacketPoolHandle);
- Assert(cPPUsage == 0);
- /* for debugging only, ignore the err in release */
- NOREF(cPPUsage);
-
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- Assert(pAdapt->bOutstandingRequests == FALSE);
-#endif
- }
- else
- {
- /*
- * If the physical miniport is powering up (from Low power state to D0),
- * clear the flag
- */
- if (PrevDeviceState > NdisDeviceStateD0)
- {
- pAdapt->bStandingBy = FALSE;
- }
-
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
-#else
- /*
- * The device below is being turned on. If we had a request
- * pending, send it down now.
- */
- if (pAdapt->bQueuedRequest == TRUE)
- {
- NDIS_STATUS Status;
-
- pAdapt->bQueuedRequest = FALSE;
-
- pAdapt->bOutstandingRequests = TRUE;
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
-
- NdisRequest(&Status,
- pAdapt->hBindingHandle,
- &pAdapt->Request);
-
- if (Status != NDIS_STATUS_PENDING)
- {
- vboxNetFltWinPtRequestComplete(pAdapt,
- &pAdapt->Request,
- Status);
-
- }
- }
- else
- {
- RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
- }
-
-#endif /* #ifndef VBOX_NETFLT_ONDEMAND_BIND */
-
- }
-
- return ReturnStatus;
-}
-
-/**
- * This is called by NDIS to notify us of a PNP event related to a lower
- * binding. Based on the event, this dispatches to other helper routines.
- *
- * @param ProtocolBindingContext - Pointer to our adapter structure. Can be NULL
- * for "global" notifications
- * @param pNetPnPEvent - Pointer to the PNP event to be processed.
- * @return NDIS_STATUS code indicating status of event processing.
- * */
-static NDIS_STATUS
-vboxNetFltWinPtPnPHandler(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN PNET_PNP_EVENT pNetPnPEvent
- )
-{
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
-
- LogFlow(("vboxNetFltWinPtPnPHandler: Adapt %p, Event %d\n", pAdapt, pNetPnPEvent->NetEvent));
-
- switch (pNetPnPEvent->NetEvent)
- {
- case NetEventSetPower:
- Status = vboxNetFltWinPtPnPNetEventSetPower(pAdapt, pNetPnPEvent);
- break;
-
- case NetEventReconfigure:
- DBGPRINT(("NetEventReconfigure, pAdapt(%p)", pAdapt));
- Status = vboxNetFltWinPtPnPNetEventReconfigure(pAdapt, pNetPnPEvent);
- break;
- case NetEventBindsComplete:
- DBGPRINT(("NetEventBindsComplete"));
- Status = vboxNetFltWinPtPnPNetEventBindsComplete(pAdapt, pNetPnPEvent);
- break;
- default:
- Status = NDIS_STATUS_SUCCESS;
- break;
- }
-
- return Status;
-}
-#ifdef __cplusplus
-# define PTCHARS_40(_p) ((_p).Ndis40Chars)
-#else
-# define PTCHARS_40(_p) (_p)
-#endif
-
-/**
- * register the protocol edge
- */
-DECLHIDDEN(NDIS_STATUS)
-vboxNetFltWinPtRegister(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
-{
- NDIS_STATUS Status;
- NDIS_PROTOCOL_CHARACTERISTICS PChars;
- NDIS_STRING Name;
-
- /*
- * Now register the protocol.
- */
- NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
- PTCHARS_40(PChars).MajorNdisVersion = VBOXNETFLT_PROT_MAJOR_NDIS_VERSION;
- PTCHARS_40(PChars).MinorNdisVersion = VBOXNETFLT_PROT_MINOR_NDIS_VERSION;
-
- /*
- * Make sure the protocol-name matches the service-name
- * (from the INF) under which this protocol is installed.
- * This is needed to ensure that NDIS can correctly determine
- * the binding and call us to bind to miniports below.
- */
- NdisInitUnicodeString(&Name, VBOXNETFLT_PROTOCOL_NAME); /* Protocol name */
- PTCHARS_40(PChars).Name = Name;
- PTCHARS_40(PChars).OpenAdapterCompleteHandler = vboxNetFltWinPtOpenAdapterComplete;
- PTCHARS_40(PChars).CloseAdapterCompleteHandler = vboxNetFltWinPtCloseAdapterComplete;
- PTCHARS_40(PChars).SendCompleteHandler = vboxNetFltWinPtSendComplete;
- PTCHARS_40(PChars).TransferDataCompleteHandler = vboxNetFltWinPtTransferDataComplete;
-
- PTCHARS_40(PChars).ResetCompleteHandler = vboxNetFltWinPtResetComplete;
- PTCHARS_40(PChars).RequestCompleteHandler = vboxNetFltWinPtRequestComplete;
- PTCHARS_40(PChars).ReceiveHandler = vboxNetFltWinPtReceive;
- PTCHARS_40(PChars).ReceiveCompleteHandler = vboxNetFltWinPtReceiveComplete;
- PTCHARS_40(PChars).StatusHandler = vboxNetFltWinPtStatus;
- PTCHARS_40(PChars).StatusCompleteHandler = vboxNetFltWinPtStatusComplete;
- PTCHARS_40(PChars).BindAdapterHandler = vboxNetFltWinPtBindAdapter;
- PTCHARS_40(PChars).UnbindAdapterHandler = vboxNetFltWinPtUnbindAdapter;
- PTCHARS_40(PChars).UnloadHandler = vboxNetFltWinPtUnloadProtocol;
-#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(DEBUG_NETFLT_RECV)
- PTCHARS_40(PChars).ReceivePacketHandler = vboxNetFltWinPtReceivePacket;
-#else
- PTCHARS_40(PChars).ReceivePacketHandler = NULL;
-#endif
- PTCHARS_40(PChars).PnPEventHandler= vboxNetFltWinPtPnPHandler;
-
- NdisRegisterProtocol(&Status,
- &g_hProtHandle,
- &PChars,
- sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
-
- return Status;
-}
-
-/**
- * deregister the protocol edge
- */
-DECLHIDDEN(NDIS_STATUS)
-vboxNetFltWinPtDeregister()
-{
- NDIS_STATUS Status;
-
- if (g_hProtHandle != NULL)
- {
- NdisDeregisterProtocol(&Status, g_hProtHandle);
- g_hProtHandle = NULL;
- }
-
- return Status;
-}
-
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
-/**
- * returns the protocol handle
- */
-DECLHIDDEN(NDIS_HANDLE) vboxNetFltWinPtGetHandle()
-{
- return g_hProtHandle;
-}
-#endif
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h
deleted file mode 100644
index 73abdc1b6..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* $Id: VBoxNetFltPt-win.h $ */
-/** @file
- * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Protocol edge of ndis filter driver
- */
-
-/*
- * Copyright (C) 2008 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.
- */
-/*
- * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
- * Copyright (c) 1993-1999, Microsoft Corporation
- */
-
-#ifndef ___VBoxNetFltPt_win_h___
-#define ___VBoxNetFltPt_win_h___
-
-#ifdef VBOXNETADP
-# error "No protocol edge"
-#endif
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtRegister(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDeregister();
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoUnbinding(PADAPT pAdapt, bool bOnUnbind);
-DECLHIDDEN(VOID) vboxNetFltWinPtFlushReceiveQueue(IN PADAPT pAdapt, IN bool bReturn);
-DECLHIDDEN(VOID) vboxNetFltWinPtQueueReceivedPacket(IN PADAPT pAdapt, IN PNDIS_PACKET Packet, IN BOOLEAN DoIndicate);
-DECLHIDDEN(VOID) vboxNetFltWinPtRequestComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_REQUEST NdisRequest, IN NDIS_STATUS Status);
-DECLHIDDEN(bool) vboxNetFltWinPtCloseAdapter(PADAPT pAdapt, PNDIS_STATUS pStatus);
-
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(IN PADAPT pAdapt);
-#else
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(IN PADAPT pAdapt, IN PNDIS_STRING pOurDeviceName, IN PNDIS_STRING pBindToDeviceName);
-DECLHIDDEN(NDIS_HANDLE) vboxNetFltWinPtGetHandle();
-#endif
-
-#endif
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp
deleted file mode 100644
index 43e232bb2..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp
+++ /dev/null
@@ -1,4368 +0,0 @@
-/* $Id: WinNetConfig.cpp $ */
-/** @file
- * VBoxNetCfgWin - Briefly describe this file, optionally with a longer description in a separate paragraph.
- */
-
-/*
- * Copyright (C) 2008 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.
- */
-/*
- * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
- *+---------------------------------------------------------------------------
- *
- * Microsoft Windows
- * Copyright (C) Microsoft Corporation, 2001.
- *
- * Author: Alok Sinha 15-May-01
- *
- *----------------------------------------------------------------------------
- */
-#include "VBox/WinNetConfig.h"
-
-#define _WIN32_DCOM
-
-
-#include <iphlpapi.h>
-
-#include <devguid.h>
-#include <stdio.h>
-#include <regstr.h>
-//#define INITGUID
-//#include <guiddef.h>
-//#include <devguid.h>
-//#include <objbase.h>
-//#include <setupapi.h>
-#include <shlobj.h>
-#include <cfgmgr32.h>
-#include <tchar.h>
-//#include <VBox/com/Guid.h>
-//#include <VBox/com/String.h>
-//#include <wtypes.h>
-#include <objbase.h>
-
-#include <crtdbg.h>
-#include <stdlib.h>
-
-#include <Wbemidl.h>
-#include <comdef.h>
-
-//#include <Winsock2.h>
-
-//using namespace com;
-
-#ifndef Assert
-//# ifdef DEBUG
-//# define Assert(_expr) assert(_expr)
-//# else
-//# define Assert(_expr) do{ }while(0)
-//# endif
-# define Assert _ASSERT
-# define AssertMsg(expr, msg) do{}while(0)
-#endif
-static LOG_ROUTINE g_Logger = NULL;
-
-static VOID DoLogging(LPCWSTR szString, ...);
-#define Log DoLogging
-
-#define DbgLog
-
-#define VBOX_NETCFG_LOCK_TIME_OUT 5000
-
-typedef bool (*ENUMERATION_CALLBACK) (LPCWSTR pFileName, PVOID pContext);
-
-typedef struct _INF_INFO
-{
- LPCWSTR pPnPId;
-}INF_INFO, *PINF_INFO;
-
-typedef struct _INFENUM_CONTEXT
-{
- INF_INFO InfInfo;
- DWORD Flags;
- HRESULT hr;
-} INFENUM_CONTEXT, *PINFENUM_CONTEXT;
-
-static bool vboxNetCfgWinInfEnumerationCallback(LPCWSTR pFileName, PVOID pCtxt);
-
-class VBoxNetCfgStringList
-{
-public:
- VBoxNetCfgStringList(int aSize);
-
- ~VBoxNetCfgStringList();
-
- HRESULT add(LPWSTR pStr);
-
- int size() {return mSize;}
-
- LPWSTR get(int i) {return maList[i];}
-private:
- HRESULT resize(int newSize);
-
- LPWSTR *maList;
- int mBufSize;
- int mSize;
-};
-
-VBoxNetCfgStringList::VBoxNetCfgStringList(int aSize)
-{
- maList = (LPWSTR*)CoTaskMemAlloc( sizeof(maList[0]) * aSize);
- mBufSize = aSize;
- mSize = 0;
-}
-
-VBoxNetCfgStringList::~VBoxNetCfgStringList()
-{
- if(!mBufSize)
- return;
-
- for(int i = 0; i < mSize; ++i)
- {
- CoTaskMemFree(maList[i]);
- }
-
- CoTaskMemFree(maList);
-}
-
-HRESULT VBoxNetCfgStringList::add(LPWSTR pStr)
-{
- if(mSize == mBufSize)
- {
- int hr = resize(mBufSize+10);
- if(SUCCEEDED(hr))
- return hr;
- }
- size_t cStr = wcslen(pStr) + 1;
- LPWSTR str = (LPWSTR)CoTaskMemAlloc( sizeof(maList[0][0]) * cStr);
- memcpy(str, pStr, sizeof(maList[0][0]) * cStr);
- maList[mSize] = str;
- ++mSize;
- return S_OK;
-}
-
-HRESULT VBoxNetCfgStringList::resize(int newSize)
-{
- Assert(newSize >= mSize);
- if(newSize < mSize)
- return E_FAIL;
- LPWSTR* pOld = maList;
- maList = (LPWSTR*)CoTaskMemAlloc( sizeof(maList[0]) * newSize);
- mBufSize = newSize;
- memcpy(maList, pOld, mSize*sizeof(maList[0]));
- CoTaskMemFree(pOld);
- return S_OK;
-}
-
-static HRESULT vboxNetCfgWinCollectInfs(const GUID * pGuid, LPCWSTR pPnPId, VBoxNetCfgStringList & list)
-{
- DWORD winEr = ERROR_SUCCESS;
- int counter = 0;
- HDEVINFO hDevInfo = SetupDiCreateDeviceInfoList(
- pGuid, /* IN LPGUID ClassGuid, OPTIONAL */
- NULL /*IN HWND hwndParent OPTIONAL */
- );
- if(hDevInfo != INVALID_HANDLE_VALUE)
- {
- if(SetupDiBuildDriverInfoList(hDevInfo,
- NULL, /*IN OUT PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
- SPDIT_CLASSDRIVER /*IN DWORD DriverType*/
- ))
- {
- SP_DRVINFO_DATA DrvInfo;
- DrvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
- char DetailBuf[16384];
- PSP_DRVINFO_DETAIL_DATA pDrvDetail = (PSP_DRVINFO_DETAIL_DATA)DetailBuf;
-
- for(DWORD i = 0;;i++)
- {
- if(SetupDiEnumDriverInfo(hDevInfo,
- NULL, /* IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
- SPDIT_CLASSDRIVER , /*IN DWORD DriverType,*/
- i, /*IN DWORD MemberIndex,*/
- &DrvInfo /*OUT PSP_DRVINFO_DATA DriverInfoData*/
- ))
- {
- DWORD dwReq;
- pDrvDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
- if(SetupDiGetDriverInfoDetail(
- hDevInfo, /*IN HDEVINFO DeviceInfoSet,*/
- NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
- &DrvInfo, /*IN PSP_DRVINFO_DATA DriverInfoData,*/
- pDrvDetail, /*OUT PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData, OPTIONAL*/
- sizeof(DetailBuf), /*IN DWORD DriverInfoDetailDataSize,*/
- &dwReq /*OUT PDWORD RequiredSize OPTIONAL*/
- ))
- {
- for(WCHAR * pHwId = pDrvDetail->HardwareID; pHwId && *pHwId && pHwId < (TCHAR*)(DetailBuf + sizeof(DetailBuf)/sizeof(DetailBuf[0])) ;pHwId += _tcslen(pHwId) + 1)
- {
- if(!wcsicmp(pHwId, pPnPId))
- {
- Assert(pDrvDetail->InfFileName[0]);
- if(pDrvDetail->InfFileName)
- {
- list.add(pDrvDetail->InfFileName);
- }
- }
- }
- }
- else
- {
- DWORD winEr = GetLastError();
- Log(L"Err SetupDiGetDriverInfoDetail (%d), req = %d", winEr, dwReq);
-// Assert(0);
- }
-
- }
- else
- {
- DWORD winEr = GetLastError();
- if(winEr == ERROR_NO_MORE_ITEMS)
- {
- break;
- }
-
- Assert(0);
- }
- }
-
- SetupDiDestroyDriverInfoList(hDevInfo,
- NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
- SPDIT_CLASSDRIVER/*IN DWORD DriverType*/
- );
- }
- else
- {
- winEr = GetLastError();
- Assert(0);
- }
-
- SetupDiDestroyDeviceInfoList(hDevInfo);
- }
- else
- {
- winEr = GetLastError();
- Assert(0);
- }
-
- return HRESULT_FROM_WIN32(winEr);
-}
-
-//
-// Function: GetKeyValue
-//
-// Purpose: Retrieve the value of a key from the inf file.
-//
-// Arguments:
-// hInf [in] Inf file handle.
-// lpszSection [in] Section name.
-// lpszKey [in] Key name.
-// dwIndex [in] Key index.
-// lppszValue [out] Key value.
-//
-// Returns: S_OK on success, otherwise and error code.
-//
-// Notes:
-//
-
-static HRESULT vboxNetCfgWinGetKeyValue (HINF hInf,
- LPCWSTR lpszSection,
- LPCWSTR lpszKey,
- DWORD dwIndex,
- LPWSTR *lppszValue)
-{
- INFCONTEXT infCtx;
- DWORD dwSizeNeeded;
- HRESULT hr;
-
- *lppszValue = NULL;
-
- if ( SetupFindFirstLineW(hInf,
- lpszSection,
- lpszKey,
- &infCtx) == FALSE )
- {
- DWORD winEr = GetLastError();
- DbgLog(L"vboxNetCfgWinGetKeyValue: SetupFindFirstLineW failed, winEr = (%d)\n", winEr);
- //Assert(0);
- return HRESULT_FROM_WIN32(winEr);
- }
-
- SetupGetStringFieldW( &infCtx,
- dwIndex,
- NULL,
- 0,
- &dwSizeNeeded );
-
- *lppszValue = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) * dwSizeNeeded );
-
- if ( !*lppszValue )
- {
- Log(L"vboxNetCfgWinGetKeyValue: CoTaskMemAlloc failed\n");
- Assert(0);
- return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
- }
-
- if ( SetupGetStringFieldW(&infCtx,
- dwIndex,
- *lppszValue,
- dwSizeNeeded,
- NULL) == FALSE )
- {
- DWORD winEr = GetLastError();
- DbgLog(L"vboxNetCfgWinGetKeyValue: SetupGetStringFieldW failed, winEr = (%d)\n", winEr);
- hr = HRESULT_FROM_WIN32(winEr);
- //Assert(0);
- CoTaskMemFree( *lppszValue );
- *lppszValue = NULL;
- }
- else
- {
- hr = S_OK;
- }
-
- return hr;
-}
-
-//
-// Function: GetPnpID
-//
-// Purpose: Retrieve PnpID from an inf file.
-//
-// Arguments:
-// lpszInfFile [in] Inf file to search.
-// lppszPnpID [out] PnpID found.
-//
-// Returns: TRUE on success.
-//
-// Notes:
-//
-
-static HRESULT vboxNetCfgWinGetPnpID (LPCWSTR lpszInfFile,
- LPWSTR *lppszPnpID)
-{
- HINF hInf;
- LPWSTR lpszModelSection;
- HRESULT hr;
-
- *lppszPnpID = NULL;
-
- hInf = SetupOpenInfFileW( lpszInfFile,
- NULL,
- INF_STYLE_WIN4,
- NULL );
-
- if ( hInf == INVALID_HANDLE_VALUE )
- {
- DWORD winEr = GetLastError();
- DbgLog(L"vboxNetCfgWinGetPnpID: SetupOpenInfFileW failed, winEr = (%d), for file (%s)\n", winEr, lpszInfFile);
- //Assert(0);
- return HRESULT_FROM_WIN32(winEr);
- }
-
- //
- // Read the Model section name from Manufacturer section.
- //
-
- hr = vboxNetCfgWinGetKeyValue( hInf,
- L"Manufacturer",
- NULL,
- 1,
- &lpszModelSection );
- //Assert(hr == S_OK);
- if ( hr == S_OK )
- {
-
- //
- // Read PnpID from the Model section.
- //
-
- hr = vboxNetCfgWinGetKeyValue( hInf,
- lpszModelSection,
- NULL,
- 2,
- lppszPnpID );
- //Assert(hr == S_OK);
- if ( hr != S_OK )
- {
- DbgLog(L"vboxNetCfgWinGetPnpID: vboxNetCfgWinGetKeyValue lpszModelSection failed, hr = (0x%x), for file (%s)\n", hr, lpszInfFile);
- }
-
- CoTaskMemFree( lpszModelSection );
- }
- else
- {
- DbgLog(L"vboxNetCfgWinGetPnpID: vboxNetCfgWinGetKeyValue Manufacturer failed, hr = (0x%x), for file (%s)\n", hr, lpszInfFile);
- }
-
- SetupCloseInfFile( hInf );
-
- return hr;
-}
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinUninstallInfs (const GUID * pGuid, LPCWSTR pPnPId, DWORD Flags)
-{
- VBoxNetCfgStringList list(128);
- HRESULT hr = vboxNetCfgWinCollectInfs(pGuid, pPnPId, list);
- if(hr == S_OK)
- {
- INFENUM_CONTEXT Context;
- Context.InfInfo.pPnPId = pPnPId;
- Context.Flags = Flags;
- Context.hr = S_OK;
- int size = list.size();
- for (int i = 0; i < size; ++i)
- {
- LPCWSTR pInf = list.get(i);
- const WCHAR* pRel = wcsrchr(pInf, '\\');
- if(pRel)
- ++pRel;
- else
- pRel = pInf;
-
- vboxNetCfgWinInfEnumerationCallback(pRel, &Context);
-// Log(L"inf : %s\n", list.get(i));
- }
- }
- return hr;
-}
-
-static HRESULT vboxNetCfgWinEnumFiles(LPCWSTR pPattern, ENUMERATION_CALLBACK pCallback, PVOID pContext)
-{
- WIN32_FIND_DATA Data;
- memset(&Data, 0, sizeof(Data));
- HRESULT hr = S_OK;
-
- HANDLE hEnum = FindFirstFile(pPattern,&Data);
- if(hEnum != INVALID_HANDLE_VALUE)
- {
-
- do
- {
- if(!pCallback(Data.cFileName, pContext))
- {
- break;
- }
-
- /* next iteration */
- memset(&Data, 0, sizeof(Data));
- BOOL bNext = FindNextFile(hEnum,&Data);
- if(!bNext)
- {
- int winEr = GetLastError();
- if(winEr != ERROR_NO_MORE_FILES)
- {
- Log(L"vboxNetCfgWinEnumFiles: FindNextFile err winEr (%d)\n", winEr);
- Assert(0);
- hr = HRESULT_FROM_WIN32(winEr);
- }
- break;
- }
- }while(true);
- FindClose(hEnum);
- }
- else
- {
- int winEr = GetLastError();
- if(winEr != ERROR_NO_MORE_FILES)
- {
- Log(L"vboxNetCfgWinEnumFiles: FindFirstFile err winEr (%d)\n", winEr);
- Assert(0);
- hr = HRESULT_FROM_WIN32(winEr);
- }
- }
-
- return hr;
-}
-
-static bool vboxNetCfgWinInfEnumerationCallback(LPCWSTR pFileName, PVOID pCtxt)
-{
- PINFENUM_CONTEXT pContext = (PINFENUM_CONTEXT)pCtxt;
-// Log(L"vboxNetCfgWinInfEnumerationCallback: pFileName (%s)\n", pFileName);
-
- LPWSTR lpszPnpID;
- HRESULT hr = vboxNetCfgWinGetPnpID (pFileName,
- &lpszPnpID);
-// Assert(hr == S_OK);
- if(hr == S_OK)
- {
- if(!wcsicmp(pContext->InfInfo.pPnPId, lpszPnpID))
- {
- if(!SetupUninstallOEMInfW(pFileName,
- pContext->Flags, /*DWORD Flags could be SUOI_FORCEDELETE */
- NULL /*__in PVOID Reserved == NULL */
- ))
- {
- DWORD dwError = GetLastError();
-
- Log(L"vboxNetCfgWinInfEnumerationCallback: SetupUninstallOEMInf failed for file (%s), r (%d)\n", pFileName, dwError);
- Assert(0);
- hr = HRESULT_FROM_WIN32( dwError );
- }
- }
- CoTaskMemFree(lpszPnpID);
- }
- else
- {
- DbgLog(L"vboxNetCfgWinInfEnumerationCallback: vboxNetCfgWinGetPnpID failed, hr = (0x%x)\n", hr);
- }
-
- return true;
-}
-
-
-static HRESULT VBoxNetCfgWinUninstallInfs(LPCWSTR pPnPId, DWORD Flags)
-{
- WCHAR InfDirPath[MAX_PATH];
- HRESULT hr = SHGetFolderPathW(NULL, /* HWND hwndOwner*/
- CSIDL_WINDOWS, /* int nFolder*/
- NULL, /*HANDLE hToken*/
- SHGFP_TYPE_CURRENT, /*DWORD dwFlags*/
- InfDirPath);
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- wcscat(InfDirPath, L"\\inf\\oem*.inf");
-
- INFENUM_CONTEXT Context;
- Context.InfInfo.pPnPId = pPnPId;
- Context.Flags = Flags;
- Context.hr = S_OK;
- hr = vboxNetCfgWinEnumFiles(InfDirPath, vboxNetCfgWinInfEnumerationCallback, &Context);
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- hr = Context.hr;
- }
- else
- {
- Log(L"VBoxNetCfgWinUninstallInfs: vboxNetCfgWinEnumFiles failed, hr = (0x%x)\n", hr);
- }
-//
-// HANDLE hInfDir = CreateFileW(InfDirPath,
-// FILE_READ_DATA, /* DWORD dwDesiredAccess*/
-// FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, /* DWORD dwShareMode */
-// NULL, /* LPSECURITY_ATTRIBUTES lpSecurityAttributes */
-// OPEN_EXISTING, /* DWORD dwCreationDisposition */
-// 0, /* DWORD dwFlagsAndAttributes */
-// NULL);
-// if(hInfDir != INVALID_HANDLE_VALUE)
-// {
-//
-// CloseHandle(hInfDir);
-// }
-// else
-// {
-// int winEr = GetLastError();
-// hr = HRESULT_FROM_WIN32(winEr);
-// }
- }
- else
- {
- Log(L"VBoxNetCfgWinUninstallInfs: SHGetFolderPathW failed, hr = (0x%x)\n", hr);
- }
-
- return hr;
-
-}
-
-
-
-/**
- * Release reference
- *
- * @param punk Pointer to the interface to release reference to.
- */
-VBOXNETCFGWIN_DECL(VOID)
-VBoxNetCfgWinReleaseRef(IN IUnknown* punk)
-{
- if(punk)
- {
- punk->Release();
- }
-
- return;
-}
-
-/**
- * Get a reference to INetCfg.
- *
- * @return HRESULT S_OK on success, otherwise an error code
- * @param fGetWriteLock If TRUE, Write lock requested
- * @param lpszAppName Application name requesting the reference.
- * @param ppnc pointer the Reference to INetCfg to be stored to
- * @param lpszLockedBy pointer the Application name who holds the write lock to be stored to, optional
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinQueryINetCfgEx(IN BOOL fGetWriteLock,
- IN LPCWSTR lpszAppName,
- IN DWORD cmsTimeout,
- OUT INetCfg **ppnc,
- OUT LPWSTR *lpszLockedBy)
-{
- INetCfg *pnc = NULL;
- INetCfgLock *pncLock = NULL;
- HRESULT hr = S_OK;
-
- /*
- * Initialize the output parameters.
- */
- *ppnc = NULL;
-
- if ( lpszLockedBy )
- {
- *lpszLockedBy = NULL;
- }
-// COM should be initialized before using the NetConfig API
-// /*
-// * Initialize COM
-// */
-// hr = CoInitialize( NULL );
-
- if ( hr == S_OK )
- {
-
- /*
- * Create the object implementing INetCfg.
- */
- hr = CoCreateInstance( CLSID_CNetCfg,
- NULL, CLSCTX_INPROC_SERVER,
- IID_INetCfg,
- (void**)&pnc );
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
-
- if ( fGetWriteLock )
- {
-
- /*
- * Get the locking reference
- */
- hr = pnc->QueryInterface( IID_INetCfgLock,
- (LPVOID *)&pncLock );
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
-
- /*
- * Attempt to lock the INetCfg for read/write
- */
- hr = pncLock->AcquireWriteLock( cmsTimeout,
- lpszAppName,
- lpszLockedBy);
- if (hr == S_FALSE )
- {
- Log(L"VBoxNetCfgWinQueryINetCfg: WriteLock busy\n");
- hr = NETCFG_E_NO_WRITE_LOCK;
- }
- else if (hr != S_OK)
- {
- Log(L"VBoxNetCfgWinQueryINetCfg: AcquireWriteLock failed, hr (0x%x)\n", hr);
- }
- }
- else
- {
- Log(L"VBoxNetCfgWinQueryINetCfg: QueryInterface for IID_INetCfgLock failed, hr (0x%x)\n", hr);
- }
- }
-
- if ( hr == S_OK )
- {
-
- /*
- * Initialize the INetCfg object.
- */
- hr = pnc->Initialize( NULL );
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
- *ppnc = pnc;
- pnc->AddRef();
- }
- else
- {
- Log(L"VBoxNetCfgWinQueryINetCfg: Initialize failed, hr (0x%x)\n", hr);
-
- /*
- * Initialize failed, if obtained lock, release it
- */
- if ( pncLock )
- {
- pncLock->ReleaseWriteLock();
- }
- }
- }
-
- VBoxNetCfgWinReleaseRef( pncLock );
- VBoxNetCfgWinReleaseRef( pnc );
- }
- else
- {
- Log(L"VBoxNetCfgWinQueryINetCfg: CoCreateInstance for CLSID_CNetCfg failed, hr (0x%x)\n", hr);
- }
-
-// COM should be initialized before using the NetConfig API
-// /*
-// * In case of error, uninitialize COM.
-// */
-// if ( hr != S_OK )
-// {
-// CoUninitialize();
-// }
- }
-
- return hr;
-}
-
-/**
- * Get a reference to INetCfg.
- *
- * @return HRESULT S_OK on success, otherwise an error code
- * @param fGetWriteLock If TRUE, Write lock requested
- * @param lpszAppName Application name requesting the reference.
- * @param ppnc pointer the Reference to INetCfg to be stored to
- * @param lpszLockedBy pointer the Application name who holds the write lock to be stored to, optional
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinQueryINetCfg(IN BOOL fGetWriteLock,
- IN LPCWSTR lpszAppName,
- OUT INetCfg **ppnc,
- OUT LPWSTR *lpszLockedBy)
-{
- return VBoxNetCfgWinQueryINetCfgEx(fGetWriteLock,
- lpszAppName,
- VBOX_NETCFG_LOCK_TIME_OUT,
- ppnc,
- lpszLockedBy);
-}
-/**
- * Release a reference to INetCfg.
- *
- * @param pnc Reference to INetCfg to release.
- * @param fHasWriteLock If TRUE, reference was held with write lock.
- * @return S_OK on success, otherwise an error code.
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinReleaseINetCfg(IN INetCfg *pnc,
- IN BOOL fHasWriteLock)
-{
- INetCfgLock *pncLock = NULL;
- HRESULT hr = S_OK;
-
- /*
- * Uninitialize INetCfg
- */
- hr = pnc->Uninitialize();
- Assert(hr == S_OK);
- /*
- * If write lock is present, unlock it
- */
- if ( hr == S_OK && fHasWriteLock )
- {
-
- /*
- * Get the locking reference
- */
- hr = pnc->QueryInterface( IID_INetCfgLock,
- (LPVOID *)&pncLock);
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
- hr = pncLock->ReleaseWriteLock();
- VBoxNetCfgWinReleaseRef( pncLock );
- }
- }
- else if(hr != S_OK)
- {
- Log(L"VBoxNetCfgWinReleaseINetCfg: Uninitialize failed, hr (0x%x)\n", hr);
- }
-
- VBoxNetCfgWinReleaseRef( pnc );
-
-// COM should be initialized before using the NetConfig API
-// /*
-// * Uninitialize COM.
-// */
-// CoUninitialize();
-
- return hr;
-}
-
-/**
- * Get network component enumerator reference.
- *
- * @param pnc Reference to INetCfg.
- * @param pguidClass Class GUID of the network component.
- * @param ppencc address the Enumerator reference to be stored to.
- * @return S_OK on success, otherwise an error code.
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinGetComponentEnum(INetCfg *pnc,
- IN const GUID *pguidClass,
- OUT IEnumNetCfgComponent **ppencc)
-{
- INetCfgClass *pncclass;
- HRESULT hr;
-
- *ppencc = NULL;
-
- /*
- * Get the class reference.
- */
- hr = pnc->QueryNetCfgClass( pguidClass,
- IID_INetCfgClass,
- (PVOID *)&pncclass );
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
-
- /*
- * Get the enumerator reference.
- */
- hr = pncclass->EnumComponents( ppencc );
-
- /*
- * We don't need the class reference any more.
- */
- VBoxNetCfgWinReleaseRef( pncclass );
- }
- else
- {
- Log(L"VBoxNetCfgWinGetComponentEnum: QueryNetCfgClass for IID_INetCfgClass failed, hr (0x%x)\n", hr);
- }
-
- return hr;
-}
-
-/**
- * Enumerates the first network component.
- *
- * @param pencc Component enumerator reference.
- * @param ppncc address the Network component reference to be stored to
- * @return S_OK on success, otherwise an error code.
- */
-/**
- * Enumerate the next network component.
- * The function behaves just like VBoxNetCfgWinGetFirstComponent if
- * it is called right after VBoxNetCfgWinGetComponentEnum.
- *
- * @param pencc Component enumerator reference.
- * @param ppncc address the Network component reference to be stored to.
- * @return S_OK on success, otherwise an error code.
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinGetNextComponent(IN IEnumNetCfgComponent *pencc,
- OUT INetCfgComponent **ppncc)
-{
- HRESULT hr;
- ULONG ulCount;
-
- *ppncc = NULL;
-
- hr = pencc->Next( 1,
- ppncc,
- &ulCount );
- Assert(hr == S_OK || hr == S_FALSE);
- if(hr != S_OK && hr != S_FALSE)
- {
- Log(L"VBoxNetCfgWinGetNextComponent: Next failed, hr (0x%x)\n", hr);
- }
- return hr;
-}
-
-/**
- * Install a network component(protocols, clients and services)
- * given its INF file.
- * @param pnc Reference to INetCfg.
- * @param lpszComponentId PnpID of the network component.
- * @param pguidClass Class GUID of the network component.
- * @return S_OK on success, otherwise an error code.
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinInstallComponent(IN INetCfg *pnc,
- IN LPCWSTR szComponentId,
- IN const GUID *pguidClass)
-{
- INetCfgClassSetup *pncClassSetup = NULL;
- INetCfgComponent *pncc = NULL;
- OBO_TOKEN OboToken;
- HRESULT hr = S_OK;
-
- /*
- * OBO_TOKEN specifies on whose behalf this
- * component is being installed.
- * Set it to OBO_USER so that szComponentId will be installed
- * on behalf of the user.
- */
-
- ZeroMemory( &OboToken,
- sizeof(OboToken) );
- OboToken.Type = OBO_USER;
-
- /*
- * Get component's setup class reference.
- */
- hr = pnc->QueryNetCfgClass ( pguidClass,
- IID_INetCfgClassSetup,
- (void**)&pncClassSetup );
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
-
- hr = pncClassSetup->Install( szComponentId,
- &OboToken,
- 0,
- 0, /* Upgrade from build number. */
- NULL, /* Answerfile name */
- NULL, /* Answerfile section name */
- &pncc ); /* Reference after the component */
- /* is installed. */
- Assert(hr == S_OK);
- if ( S_OK == hr )
- {
-
- /*
- * we don't need to use pncc (INetCfgComponent), release it
- */
- VBoxNetCfgWinReleaseRef( pncc );
- }
- else
- {
- Log(L"VBoxNetCfgWinInstallComponent: Install failed, hr (0x%x)\n", hr);
- }
-
- VBoxNetCfgWinReleaseRef( pncClassSetup );
- }
- else
- {
- Log(L"VBoxNetCfgWinInstallComponent: QueryNetCfgClass for IID_INetCfgClassSetup failed, hr (0x%x)\n", hr);
- }
-
- return hr;
-}
-
-static HRESULT vboxNetCfgWinRemoveInf(IN LPCWSTR pInfFullPath, DWORD Flags)
-{
- DWORD dwError;
- HRESULT hr = S_OK;
- WCHAR Drive[_MAX_DRIVE];
- WCHAR Dir[_MAX_DIR];
- WCHAR DirWithDrive[_MAX_DRIVE+_MAX_DIR];
- WCHAR OemInfFullPath[MAX_PATH];
- PWCHAR pOemInfName;
-
- /*
- * Get the path where the INF file is.
- */
- _wsplitpath( pInfFullPath, Drive, Dir, NULL, NULL );
-
- wcscpy( DirWithDrive, Drive );
- wcscat( DirWithDrive, Dir );
-
- /*
- * get the oem file name.
- */
- if (SetupCopyOEMInfW( pInfFullPath,
- DirWithDrive, /* Other files are in the */
- /* same dir. as primary INF */
- SPOST_PATH, /* First param is path to INF */
- SP_COPY_REPLACEONLY, /* we want to get the inf file name */
- OemInfFullPath, /* Name of the INF after */
- /* it's copied to %windir%\inf */
- sizeof(OemInfFullPath) / sizeof(OemInfFullPath[0]), /* Max buf. size for the above */
- NULL, /* Required size if non-null */
- &pOemInfName ) ) /* Optionally get the filename */
- {
- Log(L"vboxNetCfgWinRemoveInf: found inf file (%s) for (%s)\n", OemInfFullPath, pInfFullPath);
-
- if(!SetupUninstallOEMInfW(pOemInfName,
- Flags, /*DWORD Flags could be SUOI_FORCEDELETE */
- NULL /*__in PVOID Reserved == NULL */
- ))
- {
- dwError = GetLastError();
-
- Log(L"vboxNetCfgWinRemoveInf: SetupUninstallOEMInf failed for file (%s), r (%d)\n", pInfFullPath, dwError);
- Log(L"vboxNetCfgWinRemoveInf: DirWithDrive (%s)\n", DirWithDrive);
-
- Assert(0);
- hr = HRESULT_FROM_WIN32( dwError );
- }
- }
- else
- {
- dwError = GetLastError();
-
- Log(L"vboxNetCfgWinRemoveInf: SetupCopyOEMInfW failed for file (%s), r (%d)\n", pInfFullPath, dwError);
- Log(L"vboxNetCfgWinRemoveInf: DirWithDrive (%s)\n", DirWithDrive);
-
-
- Assert(0);
- hr = HRESULT_FROM_WIN32( dwError );
- }
- return hr;
-}
-
-static HRESULT vboxNetCfgWinCopyInf(IN LPCWSTR pInfFullPath)
-{
- DWORD dwError;
- HRESULT hr = S_OK;
- WCHAR Drive[_MAX_DRIVE];
- WCHAR Dir[_MAX_DIR];
- WCHAR DirWithDrive[_MAX_DRIVE+_MAX_DIR];
- WCHAR DirDestInf[_MAX_PATH] = { 0 };
-
- /*
- * Get the path where the INF file is.
- */
- _wsplitpath( pInfFullPath, Drive, Dir, NULL, NULL );
-
- wcscpy( DirWithDrive, Drive );
- wcscat( DirWithDrive, Dir );
-
- /*
- * Copy the INF file and other files referenced in the INF file.
- */
- if ( !SetupCopyOEMInfW( pInfFullPath,
- DirWithDrive, /* Other files are in the */
- /* same dir. as primary INF */
- SPOST_PATH, /* First param is path to INF */
- 0, /* Default copy style */
- DirDestInf, /* Name of the INF after */
- /* it's copied to %windir%\inf */
- sizeof(DirDestInf), /* Max buf. size for the above */
- NULL, /* Required size if non-null */
- NULL ) ) /* Optionally get the filename */
- {
- dwError = GetLastError();
-
- Log(L"vboxNetCfgWinCopyInf: SetupCopyOEMInfW failed for file (%s), r (%d)\n", pInfFullPath, dwError);
- Log(L"vboxNetCfgWinCopyInf: DirWithDrive (%s), DirDestInf(%s)\n", DirWithDrive, DirDestInf);
-
- Assert(0);
-
- hr = HRESULT_FROM_WIN32( dwError );
- }
-
- return hr;
-}
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinInstallInf(IN LPCWSTR pInfFullPath)
-{
- return vboxNetCfgWinCopyInf(pInfFullPath);
-}
-
-/**
- * Install a network component(protocols, clients and services)
- * given its INF file.
- *
- * @param pnc Reference to INetCfg.
- * @param lpszComponentId PnpID of the network component.
- * @param pguidClass Class GUID of the network component.
- * @param lpszInfFullPath INF file to install from.
- * @return S_OK on success, otherwise an error code.
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinInstallNetComponent(IN INetCfg *pnc,
- IN LPCWSTR lpszComponentId,
- IN const GUID *pguidClass,
- IN LPCWSTR * apInfFullPaths,
- IN UINT cInfFullPaths)
-{
- HRESULT hr = S_OK;
-
- /*
- * If full path to INF has been specified, the INF
- * needs to be copied using Setup API to ensure that any other files
- * that the primary INF copies will be correctly found by Setup API
- */
- for(UINT i = 0; i < cInfFullPaths; i++)
- {
- hr = vboxNetCfgWinCopyInf(apInfFullPaths[i]);
- Assert(hr == S_OK);
- if(hr != S_OK)
- {
- Log(L"VBoxNetCfgWinInstallNetComponent: vboxNetCfgWinCopyInf failed, hr (0x%x)\n", hr);
- if(i != 0)
- {
- /* remove infs already installed */
- for(UINT j = i-1; j != 0; j--)
- {
- vboxNetCfgWinRemoveInf(apInfFullPaths[j], 0);
- }
- }
-
- break;
- }
- }
-
- if (S_OK == hr)
- {
- /*
- * Install the network component.
- */
- hr = VBoxNetCfgWinInstallComponent( pnc,
- lpszComponentId,
- pguidClass );
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
- /*
- * On success, apply the changes
- */
- HRESULT tmpHr = pnc->Apply();
- Assert(tmpHr == S_OK);
- if(tmpHr != S_OK)
- {
- Log(L"VBoxNetCfgWinInstallNetComponent: Apply failed, hr (0x%x)\n", tmpHr);
- }
- }
- else
- {
- Log(L"VBoxNetCfgWinInstallNetComponent: VBoxNetCfgWinInstallComponent failed, hr (0x%x)\n", hr);
- }
- }
-
- return hr;
-}
-
-/**
- * Uninstall a network component.
- *
- * @param pnc Reference to INetCfg.
- * @param lpszInfId PnpID of the network component to uninstall
- * @param apInfFiles array of null-terminated strings containing the inf file names describing drivers to be removed from the system
- * @param cInfFiles the size of apInfFiles array
- * @return S_OK on success, otherwise an error code.
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinUninstallComponent(IN INetCfg *pnc,
- IN INetCfgComponent *pncc)
-{
- INetCfgClass *pncClass;
- INetCfgClassSetup *pncClassSetup;
- GUID guidClass;
- OBO_TOKEN obo;
- HRESULT hr;
-
- /*
- * Get the class GUID.
- */
- hr = pncc->GetClassGuid( &guidClass );
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
-
- /*
- * Get a reference to component's class.
- */
- hr = pnc->QueryNetCfgClass( &guidClass,
- IID_INetCfgClass,
- (PVOID *)&pncClass );
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
-
- /*
- * Get the setup interface.
- */
- hr = pncClass->QueryInterface( IID_INetCfgClassSetup,
- (LPVOID *)&pncClassSetup );
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
-
- /*
- * Uninstall the component.
- */
- ZeroMemory( &obo,
- sizeof(OBO_TOKEN) );
-
- obo.Type = OBO_USER;
-
- hr = pncClassSetup->DeInstall( pncc,
- &obo,
- NULL );
- Assert(hr == S_OK);
- if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) )
- {
- HRESULT tmpHr = pnc->Apply();
- /* we ignore apply failures since they might occur on misconfigured systems*/
- Assert(tmpHr == S_OK);
- if ( (tmpHr != S_OK) )
- {
- Log(L"VBoxNetCfgWinUninstallComponent: Apply failed, hr (0x%x), ignoring\n", tmpHr);
- }
- }
- else
- {
- Log(L"VBoxNetCfgWinUninstallComponent: DeInstall failed, hr (0x%x)\n", hr);
- }
-
- VBoxNetCfgWinReleaseRef( pncClassSetup );
- }
- else
- {
- Log(L"VBoxNetCfgWinUninstallComponent: QueryInterface for IID_INetCfgClassSetup failed, hr (0x%x)\n", hr);
- }
-
- VBoxNetCfgWinReleaseRef( pncClass );
- }
- else
- {
- Log(L"VBoxNetCfgWinUninstallComponent: QueryNetCfgClass failed, hr (0x%x)\n", hr);
- }
- }
- else
- {
- Log(L"VBoxNetCfgWinUninstallComponent: GetClassGuid failed, hr (0x%x)\n", hr);
- }
-
- return hr;
-}
-
-#define VBOXNETCFGWIN_NETFLT_ID L"sun_VBoxNetFlt"
-#define VBOXNETCFGWIN_NETFLT_MP_ID L"sun_VBoxNetFltmp"
-
-static HRESULT vboxNetCfgWinNetFltUninstall(IN INetCfg *pNc, DWORD InfRmFlags)
-{
- INetCfgComponent * pNcc = NULL;
- HRESULT hr = pNc->FindComponent(VBOXNETCFGWIN_NETFLT_ID, &pNcc);
- if(hr == S_OK)
- {
- Log(L"NetFlt Is Installed currently\n");
-
- hr = VBoxNetCfgWinUninstallComponent(pNc, pNcc);
-
- VBoxNetCfgWinReleaseRef(pNcc);
- }
- else if(hr == S_FALSE)
- {
- Log(L"NetFlt Is Not Installed currently\n");
- hr = S_OK;
- }
- else
- {
- Log(L"vboxNetCfgWinNetFltUninstall: FindComponent for NetFlt failed, hr (0x%x)\n", hr);
- hr = S_OK;
- }
-
- VBoxNetCfgWinUninstallInfs(VBOXNETCFGWIN_NETFLT_ID, InfRmFlags);
- VBoxNetCfgWinUninstallInfs(VBOXNETCFGWIN_NETFLT_MP_ID, InfRmFlags);
-
- return hr;
-}
-
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinNetFltUninstall(IN INetCfg *pNc)
-{
- return vboxNetCfgWinNetFltUninstall(pNc, 0);
-}
-
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinNetFltInstall(IN INetCfg *pNc, IN LPCWSTR * apInfFullPaths, IN UINT cInfFullPaths)
-{
- HRESULT hr = vboxNetCfgWinNetFltUninstall(pNc, SUOI_FORCEDELETE);
-
- hr = VBoxNetCfgWinInstallNetComponent(pNc, VBOXNETCFGWIN_NETFLT_ID,
- &GUID_DEVCLASS_NETSERVICE,
- apInfFullPaths,
- cInfFullPaths);
-
- return hr;
-}
-
-
-/**
- * Get network component's binding path enumerator reference.
- *
- * @param pncc Network component reference.
- * @param dwBindingType EBP_ABOVE or EBP_BELOW.
- * @param ppencbp address the Enumerator reference to be stored to
- * @return S_OK on success, otherwise an error code.
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinGetBindingPathEnum(IN INetCfgComponent *pncc,
- IN DWORD dwBindingType,
- OUT IEnumNetCfgBindingPath **ppencbp)
-{
- INetCfgComponentBindings *pnccb = NULL;
- HRESULT hr;
-
- *ppencbp = NULL;
-
- /* Get component's binding. */
- hr = pncc->QueryInterface( IID_INetCfgComponentBindings,
- (PVOID *)&pnccb );
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
-
- /* Get binding path enumerator reference. */
- hr = pnccb->EnumBindingPaths( dwBindingType,
- ppencbp );
- if(hr != S_OK)
- {
- Log(L"VBoxNetCfgWinGetBindingPathEnum: EnumBindingPaths failed, hr (0x%x)\n", hr);
- }
-
- VBoxNetCfgWinReleaseRef( pnccb );
- }
- else
- {
- Log(L"VBoxNetCfgWinGetBindingPathEnum: QueryInterface for IID_INetCfgComponentBindings failed, hr (0x%x)\n", hr);
- }
-
- return hr;
-}
-
-/**
- * Enumerates the first binding path.
- *
- * @param pencc Binding path enumerator reference.
- * @param ppncc address the Binding path reference to be stored to
- * @return S_OK on success, otherwise an error code.
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinGetFirstComponent(IN IEnumNetCfgComponent *pencc,
- OUT INetCfgComponent **ppncc)
-{
- HRESULT hr;
- ULONG ulCount;
-
- *ppncc = NULL;
-
- pencc->Reset();
-
- hr = pencc->Next( 1,
- ppncc,
- &ulCount );
- Assert(hr == S_OK || hr == S_FALSE);
- if(hr != S_OK && hr != S_FALSE)
- {
- Log(L"VBoxNetCfgWinGetFirstComponent: Next failed, hr (0x%x)\n", hr);
- }
- return hr;
-}
-
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinGetFirstBindingPath(IN IEnumNetCfgBindingPath *pencbp,
- OUT INetCfgBindingPath **ppncbp)
-{
- ULONG ulCount;
- HRESULT hr;
-
- *ppncbp = NULL;
-
- pencbp->Reset();
-
- hr = pencbp->Next( 1,
- ppncbp,
- &ulCount );
- Assert(hr == S_OK || hr == S_FALSE);
- if(hr != S_OK && hr != S_FALSE)
- {
- Log(L"VBoxNetCfgWinGetFirstBindingPath: Next failed, hr (0x%x)\n", hr);
- }
-
- return hr;
-}
-
-/**
- * Get binding interface enumerator reference.
- *
- * @param pncbp Binding path reference.
- * @param ppencbp address the Enumerator reference to be stored to
- * @return S_OK on success, otherwise an error code
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinGetBindingInterfaceEnum(IN INetCfgBindingPath *pncbp,
- OUT IEnumNetCfgBindingInterface **ppencbi)
-{
- HRESULT hr;
-
- *ppencbi = NULL;
-
- hr = pncbp->EnumBindingInterfaces( ppencbi );
- Assert(hr == S_OK);
- if(hr != S_OK)
- {
- Log(L"VBoxNetCfgWinGetBindingInterfaceEnum: EnumBindingInterfaces failed, hr (0x%x)\n", hr);
- }
-
- return hr;
-}
-
-/**
- * Enumerates the first binding interface.
- *
- * @param pencbi Binding interface enumerator reference.
- * @param ppncbi address the Binding interface reference to be stored to
- * @return S_OK on success, otherwise an error code
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinGetFirstBindingInterface(IN IEnumNetCfgBindingInterface *pencbi,
- OUT INetCfgBindingInterface **ppncbi)
-{
- ULONG ulCount;
- HRESULT hr;
-
- *ppncbi = NULL;
-
- pencbi->Reset();
-
- hr = pencbi->Next( 1,
- ppncbi,
- &ulCount );
- Assert(hr == S_OK || hr == S_FALSE);
- if(hr != S_OK && hr != S_FALSE)
- {
- Log(L"VBoxNetCfgWinGetFirstBindingInterface: Next failed, hr (0x%x)\n", hr);
- }
-
- return hr;
-}
-
-/*@
- * Enumerate the next binding interface.
- * The function behaves just like VBoxNetCfgWinGetFirstBindingInterface if
- * it is called right after VBoxNetCfgWinGetBindingInterfaceEnum.
- *
- * @param pencbi Binding interface enumerator reference.
- * @param ppncbi address the Binding interface reference t be stored to
- * @return S_OK on success, otherwise an error code
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinGetNextBindingInterface(IN IEnumNetCfgBindingInterface *pencbi,
- OUT INetCfgBindingInterface **ppncbi)
-{
- ULONG ulCount;
- HRESULT hr;
-
- *ppncbi = NULL;
-
- hr = pencbi->Next( 1,
- ppncbi,
- &ulCount );
- Assert(hr == S_OK || hr == S_FALSE);
- if(hr != S_OK && hr != S_FALSE)
- {
- Log(L"VBoxNetCfgWinGetNextBindingInterface: Next failed, hr (0x%x)\n", hr);
- }
-
- return hr;
-}
-
-/**
- * Enumerate the next binding path.
- * The function behaves just like VBoxNetCfgWinGetFirstBindingPath if
- * it is called right after VBoxNetCfgWinGetBindingPathEnum.
- *
- * @param pencbp Binding path enumerator reference.
- * @param ppncbp Address the Binding path reference to be stored to
- * @return S_OK on success, otherwise an error code.
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinGetNextBindingPath(IN IEnumNetCfgBindingPath *pencbp,
- OUT INetCfgBindingPath **ppncbp)
-{
- ULONG ulCount;
- HRESULT hr;
-
- *ppncbp = NULL;
-
- hr = pencbp->Next( 1,
- ppncbp,
- &ulCount );
- Assert(hr == S_OK || hr == S_FALSE);
- if(hr != S_OK && hr != S_FALSE)
- {
- Log(L"VBoxNetCfgWinGetNextBindingPath: Next failed, hr (0x%x)\n", hr);
- }
-
- return hr;
-}
-
-/*
- * helper function to get the component by its guid given enum interface
- */
-static HRESULT vboxNetCfgWinGetComponentByGuidEnum(IEnumNetCfgComponent *pEnumNcc, IN const GUID * pGuid, OUT INetCfgComponent ** ppNcc)
-{
- INetCfgComponent * pNcc;
- GUID NccGuid;
- HRESULT hr;
-
- hr = VBoxNetCfgWinGetFirstComponent( pEnumNcc, &pNcc );
- Assert(hr == S_OK || hr == S_FALSE);
- while(hr == S_OK)
- {
- ULONG uComponentStatus;
- hr = pNcc->GetDeviceStatus(&uComponentStatus);
- if(hr == S_OK)
- {
- if(uComponentStatus == 0)
- {
- hr = pNcc->GetInstanceGuid(&NccGuid);
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- if(NccGuid == *pGuid)
- {
- /* found the needed device */
- *ppNcc = pNcc;
- break;
- }
- }
- else
- {
- Log(L"vboxNetCfgWinGetComponentByGuidEnum: GetInstanceGuid failed, hr (0x%x)\n", hr);
- }
- }
- }
-
- VBoxNetCfgWinReleaseRef(pNcc);
-
- hr = VBoxNetCfgWinGetNextComponent( pEnumNcc, &pNcc );
- }
-
- return hr;
-}
-
-/**
- * get the component by its guid
- */
-VBOXNETCFGWIN_DECL(HRESULT)
-VBoxNetCfgWinGetComponentByGuid(IN INetCfg *pNc,
- IN const GUID *pguidClass,
- IN const GUID * pComponentGuid,
- OUT INetCfgComponent **ppncc)
-{
- IEnumNetCfgComponent *pEnumNcc;
- HRESULT hr = VBoxNetCfgWinGetComponentEnum( pNc, pguidClass, &pEnumNcc );
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- hr = vboxNetCfgWinGetComponentByGuidEnum(pEnumNcc, pComponentGuid, ppncc);
- Assert(hr == S_OK || hr == S_FALSE);
- if(hr == S_FALSE)
- {
- Log(L"VBoxNetCfgWinGetComponentByGuid: component not found \n");
- }
- else if(hr != S_OK)
- {
- Log(L"VBoxNetCfgWinGetComponentByGuid: vboxNetCfgWinGetComponentByGuidEnum failed, hr (0x%x)\n", hr);
- }
- VBoxNetCfgWinReleaseRef(pEnumNcc);
- }
- else
- {
- Log(L"VBoxNetCfgWinGetComponentByGuid: VBoxNetCfgWinGetComponentEnum failed, hr (0x%x)\n", hr);
- }
- return hr;
-}
-
-typedef BOOL (*VBOXNETCFGWIN_NETCFGENUM_CALLBACK) (IN INetCfg *pNc, IN INetCfgComponent *pNcc, PVOID pContext);
-
-static HRESULT vboxNetCfgWinEnumNetCfgComponents(IN INetCfg *pNc,
- IN const GUID *pguidClass,
- VBOXNETCFGWIN_NETCFGENUM_CALLBACK callback,
- PVOID pContext)
-{
- IEnumNetCfgComponent *pEnumComponent;
- HRESULT hr = pNc->EnumComponents(pguidClass, &pEnumComponent);
- bool bBreak = false;
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- INetCfgComponent *pNcc;
- hr = pEnumComponent->Reset();
- Assert(hr == S_OK);
- do
- {
- hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pNcc);
- Assert(hr == S_OK || hr == S_FALSE);
- if(hr == S_OK)
- {
- /* this is E_NOTIMPL for all components other than NET */
-// ULONG uComponentStatus;
-// hr = pNcc->GetDeviceStatus(&uComponentStatus);
-// if(hr == S_OK)
- {
- if(!callback(pNc, pNcc, pContext))
- {
- bBreak = true;
- }
- }
- VBoxNetCfgWinReleaseRef(pNcc);
- }
- else
- {
- if(hr ==S_FALSE)
- {
- hr = S_OK;
- }
- else
- {
- Log(L"vboxNetCfgWinEnumNetCfgComponents: VBoxNetCfgWinGetNextComponent failed, hr (0x%x)\n", hr);
- }
- break;
- }
- } while(!bBreak);
-
- VBoxNetCfgWinReleaseRef(pEnumComponent);
- }
- return hr;
-}
-
-static VOID DoLogging(LPCWSTR szString, ...)
-{
- LOG_ROUTINE pRoutine = (LOG_ROUTINE)(*((void * volatile *)&g_Logger));
- if(pRoutine)
- {
- WCHAR szBuffer[1024] = {0};
- va_list pArgList;
- va_start(pArgList, szString);
- _vsnwprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
- va_end(pArgList);
-
- pRoutine(szBuffer);
- }
-}
-
-VBOXNETCFGWIN_DECL(VOID) VBoxNetCfgWinSetLogging(LOG_ROUTINE Log)
-{
- *((void * volatile *)&g_Logger) = Log;
-}
-
-static BOOL vboxNetCfgWinRemoveAllNetDevicesOfIdCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext)
-{
- DWORD winEr;
- HRESULT hr = S_OK;
- SP_REMOVEDEVICE_PARAMS rmdParams;
- rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
- rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE;
- rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL;
- rmdParams.HwProfile = 0;
- if(SetupDiSetClassInstallParams(hDevInfo,pDev,&rmdParams.ClassInstallHeader,sizeof(rmdParams)))
- {
- if(SetupDiSetSelectedDevice (hDevInfo, pDev))
- {
- if(SetupDiCallClassInstaller(DIF_REMOVE,hDevInfo,pDev))
- {
- SP_DEVINSTALL_PARAMS devParams;
- /*
- * see if device needs reboot
- */
- devParams.cbSize = sizeof(devParams);
- if(SetupDiGetDeviceInstallParams(hDevInfo,pDev,&devParams))
- {
- if(devParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT))
- {
- //
- // reboot required
- //
- hr = S_FALSE;
- Log(L"vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: !!!REBOOT REQUIRED!!!\n");
- }
- }
- else
- {
- //
- // appears to have succeeded
- //
- }
- }
- else
- {
- winEr = GetLastError();
- Log(L"vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiCallClassInstaller failed winErr(%d)\n", winEr);
- hr = HRESULT_FROM_WIN32(winEr);
- }
- }
- else
- {
- winEr = GetLastError();
- Log(L"vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiSetSelectedDevice failed winErr(%d)\n", winEr);
- hr = HRESULT_FROM_WIN32(winEr);
- }
- }
- else
- {
- winEr = GetLastError();
- Log(L"vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiSetClassInstallParams failed winErr(%d)\n", winEr);
- hr = HRESULT_FROM_WIN32(winEr);
- }
-
- return TRUE;
-}
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRemoveAllNetDevicesOfId(LPWSTR pPnPId)
-{
- return VBoxNetCfgWinEnumNetDevices(pPnPId, vboxNetCfgWinRemoveAllNetDevicesOfIdCallback, NULL);
-}
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnumNetDevices(LPWSTR pPnPId, VBOXNETCFGWIN_NETENUM_CALLBACK callback, PVOID pContext)
-{
- DWORD winEr;
- HRESULT hr = S_OK;
-
- HDEVINFO hDevInfo = SetupDiGetClassDevsExW(
- &GUID_DEVCLASS_NET,
- NULL, /* IN PCTSTR Enumerator, OPTIONAL*/
- NULL, /*IN HWND hwndParent, OPTIONAL*/
- DIGCF_PRESENT, /*IN DWORD Flags,*/
- NULL, /*IN HDEVINFO DeviceInfoSet, OPTIONAL*/
- NULL, /*IN PCTSTR MachineName, OPTIONAL*/
- NULL /*IN PVOID Reserved*/
- );
- if(hDevInfo != INVALID_HANDLE_VALUE)
- {
- DWORD iDev = 0;
- SP_DEVINFO_DATA Dev;
- PBYTE pBuffer = NULL;
- DWORD cbBuffer = 0;
- DWORD cbRequired = 0;
- BOOL bEnumCompleted;
- size_t cPnPId = wcslen(pPnPId);
-
- Dev.cbSize = sizeof(Dev);
-
- for(; bEnumCompleted = SetupDiEnumDeviceInfo(hDevInfo, iDev, &Dev); iDev++)
- {
- if(!SetupDiGetDeviceRegistryPropertyW(hDevInfo,&Dev,
- SPDRP_HARDWAREID, /* IN DWORD Property,*/
- NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
- pBuffer, /*OUT PBYTE PropertyBuffer,*/
- cbBuffer, /* IN DWORD PropertyBufferSize,*/
- &cbRequired /*OUT PDWORD RequiredSize OPTIONAL*/
- ))
- {
- winEr = GetLastError();
- if(winEr != ERROR_INSUFFICIENT_BUFFER)
- {
- Log(L"VBoxNetCfgWinEnumNetDevices: SetupDiGetDeviceRegistryPropertyW (1) failed winErr(%d)\n", winEr);
- hr = HRESULT_FROM_WIN32(winEr);
- break;
- }
-
- if(pBuffer)
- {
- free(pBuffer);
- }
-
- pBuffer = (PBYTE)malloc(cbRequired);
- cbBuffer = cbRequired;
-
- if(!SetupDiGetDeviceRegistryPropertyW(hDevInfo,&Dev,
- SPDRP_HARDWAREID, /* IN DWORD Property,*/
- NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
- pBuffer, /*OUT PBYTE PropertyBuffer,*/
- cbBuffer, /* IN DWORD PropertyBufferSize,*/
- &cbRequired /*OUT PDWORD RequiredSize OPTIONAL*/
- ))
- {
- winEr = GetLastError();
- Log(L"VBoxNetCfgWinEnumNetDevices: SetupDiGetDeviceRegistryPropertyW (2) failed winErr(%d)\n", winEr);
- hr = HRESULT_FROM_WIN32(winEr);
- break;
- }
- }
-
- PWCHAR pCurId = (PWCHAR)pBuffer;
- size_t cCurId = wcslen(pCurId);
- if(cCurId >= cPnPId)
- {
- pCurId += cCurId - cPnPId;
- if(!wcsnicmp(pCurId, pPnPId, cPnPId))
- {
-
- if(!callback(hDevInfo,&Dev,pContext))
- break;
- }
- }
-
- }
-
- if(pBuffer)
- free(pBuffer);
-
- if(bEnumCompleted)
- {
- winEr = GetLastError();
- hr = winEr == ERROR_NO_MORE_ITEMS ? S_OK : HRESULT_FROM_WIN32(winEr);
- }
-
- SetupDiDestroyDeviceInfoList(hDevInfo);
- }
- else
- {
- DWORD winEr = GetLastError();
- Log(L"VBoxNetCfgWinEnumNetDevices: SetupDiGetClassDevsExW failed winErr(%d)\n", winEr);
- hr = HRESULT_FROM_WIN32(winEr);
- }
-
- return hr;
-}
-
-
-
-/* The original source of the VBoxNetAdp adapter creation/destruction code has the following copyright */
-/*
- Copyright 2004 by the Massachusetts Institute of Technology
-
- All rights reserved.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name of the Massachusetts
- Institute of Technology (M.I.T.) not be used in advertising or publicity
- pertaining to distribution of the software without specific, written
- prior permission.
-
- M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
-*/
-
-
-#define NETSHELL_LIBRARY _T("netshell.dll")
-
-/**
- * Use the IShellFolder API to rename the connection.
- */
-static HRESULT rename_shellfolder (PCWSTR wGuid, PCWSTR wNewName)
-{
- /* This is the GUID for the network connections folder. It is constant.
- * {7007ACC7-3202-11D1-AAD2-00805FC1270E} */
- const GUID CLSID_NetworkConnections = {
- 0x7007ACC7, 0x3202, 0x11D1, {
- 0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E
- }
- };
-
- LPITEMIDLIST pidl = NULL;
- IShellFolder *pShellFolder = NULL;
- HRESULT hr;
-
- /* Build the display name in the form "::{GUID}". */
- if (wcslen (wGuid) >= MAX_PATH)
- return E_INVALIDARG;
- WCHAR szAdapterGuid[MAX_PATH + 2] = {0};
- swprintf (szAdapterGuid, L"::%ls", wGuid);
-
- /* Create an instance of the network connections folder. */
- hr = CoCreateInstance (CLSID_NetworkConnections, NULL,
- CLSCTX_INPROC_SERVER, IID_IShellFolder,
- reinterpret_cast <LPVOID *> (&pShellFolder));
- /* Parse the display name. */
- if (SUCCEEDED (hr))
- {
- hr = pShellFolder->ParseDisplayName (NULL, NULL, szAdapterGuid, NULL,
- &pidl, NULL);
- }
- if (SUCCEEDED (hr))
- {
- hr = pShellFolder->SetNameOf (NULL, pidl, wNewName, SHGDN_NORMAL,
- &pidl);
- }
-
- CoTaskMemFree (pidl);
-
- if (pShellFolder)
- pShellFolder->Release();
-
- return hr;
-}
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRenameConnection (LPWSTR pGuid, PCWSTR NewName)
-{
- typedef HRESULT (WINAPI *lpHrRenameConnection) (const GUID *, PCWSTR);
- lpHrRenameConnection RenameConnectionFunc = NULL;
- HRESULT status;
-// Guid guid(*pDevInstanceGuid);
-// Bstr bstr(guid.toString());
-// BSTR GuidString = bstr.mutableRaw();
-// WCHAR GuidString[50];
-//
-// int length = StringFromGUID2(*pDevInstanceGuid, GuidString, sizeof(GuidString)/sizeof(GuidString[0]));
-// if(!length)
-// return E_FAIL;
-
-// strString[wcslen(strString) - 1] = L'\0';
-//
-// WCHAR * GuidString = strString + 1;
-
- /* First try the IShellFolder interface, which was unimplemented
- * for the network connections folder before XP. */
- status = rename_shellfolder (pGuid, NewName);
- if (status == E_NOTIMPL)
- {
-/** @todo that code doesn't seem to work! */
- /* The IShellFolder interface is not implemented on this platform.
- * Try the (undocumented) HrRenameConnection API in the netshell
- * library. */
- CLSID clsid;
- HINSTANCE hNetShell;
- status = CLSIDFromString ((LPOLESTR) pGuid, &clsid);
- if (FAILED(status))
- return E_FAIL;
- hNetShell = LoadLibrary (NETSHELL_LIBRARY);
- if (hNetShell == NULL)
- return E_FAIL;
- RenameConnectionFunc =
- (lpHrRenameConnection) GetProcAddress (hNetShell,
- "HrRenameConnection");
- if (RenameConnectionFunc == NULL)
- {
- FreeLibrary (hNetShell);
- return E_FAIL;
- }
- status = RenameConnectionFunc (&clsid, NewName);
- FreeLibrary (hNetShell);
- }
- if (FAILED (status))
- return status;
-
- return S_OK;
-}
-
-#define DRIVERHWID _T("sun_VBoxNetAdp")
-
-#define SetErrBreak(strAndArgs) \
- if (1) { \
- hrc = E_FAIL; \
- Log strAndArgs; \
- Assert(0); \
- break; \
- } else do {} while (0)
-
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRemoveHostOnlyNetworkInterface (const GUID *pGUID, BSTR *pErrMsg)
-{
-// LogFlowFuncEnter();
-// LogFlowFunc (("Network connection GUID = {%RTuuid}\n", aGUID.raw()));
-
-// AssertReturn (aClient, VERR_INVALID_POINTER);
-// AssertReturn (!aGUID.isEmpty(), VERR_INVALID_PARAMETER);
-
- HRESULT hrc = S_OK;
-
- do
- {
- TCHAR lszPnPInstanceId [512] = {0};
-
- /* We have to find the device instance ID through a registry search */
-
- HKEY hkeyNetwork = 0;
- HKEY hkeyConnection = 0;
-
- do
- {
- WCHAR strRegLocation [256];
- WCHAR GuidString[50];
-
- int length = StringFromGUID2(*pGUID, GuidString, sizeof(GuidString)/sizeof(GuidString[0]));
- if(!length)
- SetErrBreak((L"Failed to create a Guid string"));
-
- swprintf (strRegLocation,
- L"SYSTEM\\CurrentControlSet\\Control\\Network\\"
- L"{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s",
- GuidString);
-
- LONG status;
- status = RegOpenKeyExW (HKEY_LOCAL_MACHINE, strRegLocation, 0,
- KEY_READ, &hkeyNetwork);
- if ((status != ERROR_SUCCESS) || !hkeyNetwork)
- SetErrBreak ((
- L"Host interface network is not found in registry (%s) [1]",
- strRegLocation));
-
- status = RegOpenKeyExW (hkeyNetwork, L"Connection", 0,
- KEY_READ, &hkeyConnection);
- if ((status != ERROR_SUCCESS) || !hkeyConnection)
- SetErrBreak ((
- L"Host interface network is not found in registry (%s) [2]",
- strRegLocation));
-
- DWORD len = sizeof (lszPnPInstanceId);
- DWORD dwKeyType;
- status = RegQueryValueExW (hkeyConnection, L"PnPInstanceID", NULL,
- &dwKeyType, (LPBYTE) lszPnPInstanceId, &len);
- if ((status != ERROR_SUCCESS) || (dwKeyType != REG_SZ))
- SetErrBreak ((
- L"Host interface network is not found in registry (%s) [3]",
- strRegLocation));
- }
- while (0);
-
- if (hkeyConnection)
- RegCloseKey (hkeyConnection);
- if (hkeyNetwork)
- RegCloseKey (hkeyNetwork);
-
- if (FAILED (hrc))
- break;
-
- /*
- * Now we are going to enumerate all network devices and
- * wait until we encounter the right device instance ID
- */
-
- HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
-
- do
- {
- BOOL ok;
- DWORD ret = 0;
- GUID netGuid;
- SP_DEVINFO_DATA DeviceInfoData;
- DWORD index = 0;
- BOOL found = FALSE;
- DWORD size = 0;
-
- /* initialize the structure size */
- DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
-
- /* copy the net class GUID */
- memcpy (&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET));
-
- /* return a device info set contains all installed devices of the Net class */
- hDeviceInfo = SetupDiGetClassDevs (&netGuid, NULL, NULL, DIGCF_PRESENT);
-
- if (hDeviceInfo == INVALID_HANDLE_VALUE)
- SetErrBreak ((L"SetupDiGetClassDevs failed (0x%08X)", GetLastError()));
-
- /* enumerate the driver info list */
- while (TRUE)
- {
- TCHAR *deviceHwid;
-
- ok = SetupDiEnumDeviceInfo (hDeviceInfo, index, &DeviceInfoData);
-
- if (!ok)
- {
- if (GetLastError() == ERROR_NO_MORE_ITEMS)
- break;
- else
- {
- index++;
- continue;
- }
- }
-
- /* try to get the hardware ID registry property */
- ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
- &DeviceInfoData,
- SPDRP_HARDWAREID,
- NULL,
- NULL,
- 0,
- &size);
- if (!ok)
- {
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
- {
- index++;
- continue;
- }
-
- deviceHwid = (TCHAR *) malloc (size);
- ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
- &DeviceInfoData,
- SPDRP_HARDWAREID,
- NULL,
- (PBYTE)deviceHwid,
- size,
- NULL);
- if (!ok)
- {
- free (deviceHwid);
- deviceHwid = NULL;
- index++;
- continue;
- }
- }
- else
- {
- /* something is wrong. This shouldn't have worked with a NULL buffer */
- index++;
- continue;
- }
-
- for (TCHAR *t = deviceHwid;
- t && *t && t < &deviceHwid[size / sizeof(TCHAR)];
- t += _tcslen (t) + 1)
- {
- if (!_tcsicmp (DRIVERHWID, t))
- {
- /* get the device instance ID */
- TCHAR devID [MAX_DEVICE_ID_LEN];
- if (CM_Get_Device_ID(DeviceInfoData.DevInst,
- devID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS)
- {
- /* compare to what we determined before */
- if (wcscmp(devID, lszPnPInstanceId) == 0)
- {
- found = TRUE;
- break;
- }
- }
- }
- }
-
- if (deviceHwid)
- {
- free (deviceHwid);
- deviceHwid = NULL;
- }
-
- if (found)
- break;
-
- index++;
- }
-
- if (found == FALSE)
- SetErrBreak ((L"Host Interface Network driver not found (0x%08X)",
- GetLastError()));
-
- ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
- if (!ok)
- SetErrBreak ((L"SetupDiSetSelectedDevice failed (0x%08X)",
- GetLastError()));
-
- ok = SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
- if (!ok)
- SetErrBreak ((L"SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)",
- GetLastError()));
- }
- while (0);
-
- /* clean up the device info set */
- if (hDeviceInfo != INVALID_HANDLE_VALUE)
- SetupDiDestroyDeviceInfoList (hDeviceInfo);
-
- if (FAILED (hrc))
- break;
- }
- while (0);
-
-// LogFlowFunc (("vrc=%Rrc\n", vrc));
-// LogFlowFuncLeave();
- return hrc;
-}
-
-static UINT WINAPI vboxNetCfgWinPspFileCallback(
- PVOID Context,
- UINT Notification,
- UINT_PTR Param1,
- UINT_PTR Param2
- )
-{
- switch(Notification)
- {
- case SPFILENOTIFY_TARGETNEWER:
- case SPFILENOTIFY_TARGETEXISTS:
- return TRUE;
- }
- return SetupDefaultQueueCallback(Context, Notification, Param1, Param2);
-}
-
-static BOOL vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority (IN INetCfg *pNc, IN INetCfgComponent *pNcc, PVOID pContext)
-{
- INetCfgComponentBindings *pNccb = NULL;
- IEnumNetCfgBindingPath *pEnumNccbp;
- GUID *pGuid = (GUID*)pContext;
- HRESULT hr;
- bool bFound = false;
-
- /* Get component's binding. */
- hr = pNcc->QueryInterface( IID_INetCfgComponentBindings,
- (PVOID *)&pNccb );
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
- /* Get binding path enumerator reference. */
- hr = pNccb->EnumBindingPaths(EBP_BELOW, &pEnumNccbp);
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- INetCfgBindingPath *pNccbp;
- hr = pEnumNccbp->Reset();
- Assert(hr == S_OK);
- do
- {
- hr = VBoxNetCfgWinGetNextBindingPath(pEnumNccbp, &pNccbp);
- Assert(hr == S_OK || hr == S_FALSE);
- if(hr == S_OK)
- {
-// if(pNccbp->IsEnabled() == S_OK)
- {
- IEnumNetCfgBindingInterface *pEnumNcbi;
- hr = VBoxNetCfgWinGetBindingInterfaceEnum(pNccbp, &pEnumNcbi);
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
- INetCfgBindingInterface *pNcbi;
- hr = pEnumNcbi->Reset();
- Assert(hr == S_OK);
- do
- {
- hr = VBoxNetCfgWinGetNextBindingInterface(pEnumNcbi, &pNcbi);
- Assert(hr == S_OK || hr == S_FALSE);
- if(hr == S_OK)
- {
- INetCfgComponent * pNccBoud;
- hr = pNcbi->GetLowerComponent(&pNccBoud);
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- ULONG uComponentStatus;
- hr = pNccBoud->GetDeviceStatus(&uComponentStatus);
- if(hr == S_OK)
- {
-// if(uComponentStatus == 0)
- {
- GUID guid;
- hr = pNccBoud->GetInstanceGuid(&guid);
- if(guid == *pGuid)
- {
- hr = pNccb->MoveAfter(pNccbp, NULL);
- Assert(hr == S_OK);
- bFound = true;
- }
- }
- }
- VBoxNetCfgWinReleaseRef(pNccBoud);
- }
- VBoxNetCfgWinReleaseRef(pNcbi);
- }
- else
- {
- if(hr == S_FALSE)
- {
- hr = S_OK;
- }
- else
- {
- Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetNextBindingInterface failed, hr (0x%x)\n", hr);
- }
- break;
- }
- } while(!bFound);
- VBoxNetCfgWinReleaseRef(pEnumNcbi);
- }
- else
- {
- Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetBindingInterfaceEnum failed, hr (0x%x)\n", hr);
- }
- }
-
- VBoxNetCfgWinReleaseRef(pNccbp);
- }
- else
- {
- if(hr = S_FALSE)
- {
- hr = S_OK;
- }
- else
- {
- Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetNextBindingPath failed, hr (0x%x)\n", hr);
- }
- break;
- }
- } while(!bFound);
-
- VBoxNetCfgWinReleaseRef(pEnumNccbp);
- }
- else
- {
- Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: EnumBindingPaths failed, hr (0x%x)\n", hr);
- }
-
- VBoxNetCfgWinReleaseRef( pNccb );
- }
- else
- {
- Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: QueryInterface for IID_INetCfgComponentBindings failed, hr (0x%x)\n", hr);
- }
-
- return true;
-}
-
-static BOOL vboxNetCfgWinListUpperBindings (IN INetCfg *pNc, IN INetCfgComponent *pNcc, PVOID pContext)
-{
- INetCfgComponentBindings *pNccb = NULL;
- IEnumNetCfgBindingPath *pEnumNccbp;
- GUID *pGuid = (GUID*)pContext;
- HRESULT hr;
- LPWSTR pszwCompDisplayName;
-
- hr = pNcc->GetDisplayName(&pszwCompDisplayName);
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
- Log(L" enumerating bindings for component (%s)\n", pszwCompDisplayName);
- /* Get component's binding. */
- hr = pNcc->QueryInterface( IID_INetCfgComponentBindings,
- (PVOID *)&pNccb );
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
- /* Get binding path enumerator reference. */
- hr = pNccb->EnumBindingPaths(EBP_ABOVE, &pEnumNccbp);
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- INetCfgBindingPath *pNccbp;
- hr = pEnumNccbp->Reset();
- Assert(hr == S_OK);
- do
- {
- hr = VBoxNetCfgWinGetNextBindingPath(pEnumNccbp, &pNccbp);
- Assert(hr == S_OK || hr == S_FALSE);
- if(hr == S_OK)
- {
- LPWSTR pszwPathToken;
- hr = pNccbp->GetPathToken(&pszwPathToken);
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- Log(L" enumerating bp (%s), enabled(0x%x)\n", pszwPathToken, pNccbp->IsEnabled());
- IEnumNetCfgBindingInterface *pEnumNcbi;
- hr = VBoxNetCfgWinGetBindingInterfaceEnum(pNccbp, &pEnumNcbi);
- Assert(hr == S_OK);
- if ( hr == S_OK )
- {
- INetCfgBindingInterface *pNcbi;
- hr = pEnumNcbi->Reset();
- Assert(hr == S_OK);
- do
- {
- hr = VBoxNetCfgWinGetNextBindingInterface(pEnumNcbi, &pNcbi);
- Assert(hr == S_OK || hr == S_FALSE);
- if(hr == S_OK)
- {
- LPWSTR pszwInterfaceName;
- hr = pNcbi->GetName(&pszwInterfaceName);
- if(hr == S_OK)
- {
- Log(L" enumerating bi (%s)\n", pszwInterfaceName);
- INetCfgComponent * pNccBoud;
- hr = pNcbi->GetUpperComponent(&pNccBoud);
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- LPWSTR pszwDisplayName;
- hr = pNccBoud->GetDisplayName(&pszwDisplayName);
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- Log(L" name (%s)\n", pszwDisplayName);
- CoTaskMemFree(pszwDisplayName);
- }
- else
- {
- Log(L" ERROR getting name (0x%x)\n", hr);
- }
-
- VBoxNetCfgWinReleaseRef(pNccBoud);
- }
- VBoxNetCfgWinReleaseRef(pNcbi);
- }
- else
- {
- Log(L" ERROR getting bi name (0x%x)\n", hr);
- }
- }
- else
- {
- if(hr == S_FALSE)
- {
- hr = S_OK;
- break;
- }
- else
- {
- Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetNextBindingInterface failed, hr (0x%x)\n", hr);
- }
- break;
- }
- } while(true);
- VBoxNetCfgWinReleaseRef(pEnumNcbi);
- }
- else
- {
- Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetBindingInterfaceEnum failed, hr (0x%x)\n", hr);
- }
- CoTaskMemFree(pszwPathToken);
- }
- else
- {
- Log(L" ERROR getting bp name (0x%x)\n", hr);
- }
-
- VBoxNetCfgWinReleaseRef(pNccbp);
- }
- else
- {
- if(hr = S_FALSE)
- {
- hr = S_OK;
- break;
- }
- else
- {
- Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetNextBindingPath failed, hr (0x%x)\n", hr);
- }
- break;
- }
- } while(true);
-
- VBoxNetCfgWinReleaseRef(pEnumNccbp);
- }
- else
- {
- Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: EnumBindingPaths failed, hr (0x%x)\n", hr);
- }
-
- VBoxNetCfgWinReleaseRef( pNccb );
- }
- else
- {
- Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: QueryInterface for IID_INetCfgComponentBindings failed, hr (0x%x)\n", hr);
- }
-
- CoTaskMemFree(pszwCompDisplayName);
- }
- else
- {
- Log(L" ERROR getting component name (0x%x)\n", hr);
- }
-
- return true;
-}
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinCreateHostOnlyNetworkInterface (LPCWSTR pInfPath, bool bIsInfPathFile, /* <- input params */
- GUID *pGuid, BSTR *lppszName, BSTR *pErrMsg) /* <- output params */
-{
- HRESULT hrc = S_OK;
-
- HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
- SP_DEVINFO_DATA DeviceInfoData;
- PVOID pQueueCallbackContext = NULL;
- DWORD ret = 0;
- BOOL found = FALSE;
- BOOL registered = FALSE;
- BOOL destroyList = FALSE;
- WCHAR pWCfgGuidString [50];
- WCHAR DevName[256];
-
- do
- {
- BOOL ok;
- GUID netGuid;
- SP_DRVINFO_DATA DriverInfoData;
- SP_DEVINSTALL_PARAMS DeviceInstallParams;
- TCHAR className [MAX_PATH];
- DWORD index = 0;
- PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail;
- /* for our purposes, 2k buffer is more
- * than enough to obtain the hardware ID
- * of the VBoxNetAdp driver. */
- DWORD detailBuf [2048];
-
- HKEY hkey = NULL;
- DWORD cbSize;
- DWORD dwValueType;
-
- /* initialize the structure size */
- DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
- DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
-
- /* copy the net class GUID */
- memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));
-
- /* create an empty device info set associated with the net class GUID */
- hDeviceInfo = SetupDiCreateDeviceInfoList (&netGuid, NULL);
- if (hDeviceInfo == INVALID_HANDLE_VALUE)
- SetErrBreak ((L"SetupDiCreateDeviceInfoList failed (0x%08X)",
- GetLastError()));
-
- /* get the class name from GUID */
- ok = SetupDiClassNameFromGuid (&netGuid, className, MAX_PATH, NULL);
- if (!ok)
- SetErrBreak ((L"SetupDiClassNameFromGuid failed (0x%08X)",
- GetLastError()));
-
- /* create a device info element and add the new device instance
- * key to registry */
- ok = SetupDiCreateDeviceInfo (hDeviceInfo, className, &netGuid, NULL, NULL,
- DICD_GENERATE_ID, &DeviceInfoData);
- if (!ok)
- SetErrBreak ((L"SetupDiCreateDeviceInfo failed (0x%08X)",
- GetLastError()));
-
- /* select the newly created device info to be the currently
- selected member */
- ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
- if (!ok)
- SetErrBreak ((L"SetupDiSetSelectedDevice failed (0x%08X)",
- GetLastError()));
-
- if(pInfPath)
- {
- /* get the device install parameters and disable filecopy */
- DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
- ok = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
- &DeviceInstallParams);
- if (ok)
- {
- memset(DeviceInstallParams.DriverPath, 0, sizeof(DeviceInstallParams.DriverPath));
- size_t pathLenght = wcslen(pInfPath) + 1/* null terminator */;
- if(pathLenght < sizeof(DeviceInstallParams.DriverPath)/sizeof(DeviceInstallParams.DriverPath[0]))
- {
- memcpy(DeviceInstallParams.DriverPath, pInfPath, pathLenght*sizeof(DeviceInstallParams.DriverPath[0]));
-
- if(bIsInfPathFile)
- {
- DeviceInstallParams.Flags |= DI_ENUMSINGLEINF;
- }
-
- ok = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
- &DeviceInstallParams);
- if(!ok)
- {
- DWORD winEr = GetLastError();
- Log(L"SetupDiSetDeviceInstallParams: SetupDiSetDeviceInstallParams failed, winEr (%d)\n", winEr);
- Assert(0);
- break;
- }
- }
- else
- {
- Log(L"SetupDiSetDeviceInstallParams: inf path is too long\n");
- Assert(0);
- break;
- }
- }
- else
- {
- DWORD winEr = GetLastError();
- Assert(0);
- Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: SetupDiGetDeviceInstallParams failed, winEr (%d)\n", winEr);
- }
-
- }
-
- /* build a list of class drivers */
- ok = SetupDiBuildDriverInfoList (hDeviceInfo, &DeviceInfoData,
- SPDIT_CLASSDRIVER);
- if (!ok)
- SetErrBreak ((L"SetupDiBuildDriverInfoList failed (0x%08X)",
- GetLastError()));
-
- destroyList = TRUE;
-
- /* enumerate the driver info list */
- while (TRUE)
- {
- BOOL ret;
-
- ret = SetupDiEnumDriverInfo (hDeviceInfo, &DeviceInfoData,
- SPDIT_CLASSDRIVER, index, &DriverInfoData);
-
- /* if the function failed and GetLastError() returned
- * ERROR_NO_MORE_ITEMS, then we have reached the end of the
- * list. Otherwise there was something wrong with this
- * particular driver. */
- if (!ret)
- {
- if(GetLastError() == ERROR_NO_MORE_ITEMS)
- break;
- else
- {
- index++;
- continue;
- }
- }
-
- pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf;
- pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
-
- /* if we successfully find the hardware ID and it turns out to
- * be the one for the loopback driver, then we are done. */
- if (SetupDiGetDriverInfoDetail (hDeviceInfo,
- &DeviceInfoData,
- &DriverInfoData,
- pDriverInfoDetail,
- sizeof (detailBuf),
- NULL))
- {
- TCHAR * t;
-
- /* pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the
- * whole list and see if there is a match somewhere. */
- t = pDriverInfoDetail->HardwareID;
- while (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)])
- {
- if (!_tcsicmp(t, DRIVERHWID))
- break;
-
- t += _tcslen(t) + 1;
- }
-
- if (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)])
- {
- found = TRUE;
- break;
- }
- }
-
- index ++;
- }
-
- if (!found)
- SetErrBreak ((L"Could not find Host Interface Networking driver! "
- L"Please reinstall"));
-
- /* set the loopback driver to be the currently selected */
- ok = SetupDiSetSelectedDriver (hDeviceInfo, &DeviceInfoData,
- &DriverInfoData);
- if (!ok)
- SetErrBreak ((L"SetupDiSetSelectedDriver failed (0x%08X)",
- GetLastError()));
-
- /* register the phantom device to prepare for install */
- ok = SetupDiCallClassInstaller (DIF_REGISTERDEVICE, hDeviceInfo,
- &DeviceInfoData);
- if (!ok)
- {
- DWORD err = GetLastError();
- SetErrBreak ((L"SetupDiCallClassInstaller failed (0x%08X)",
- err));
- }
-
- /* registered, but remove if errors occur in the following code */
- registered = TRUE;
-
- /* ask the installer if we can install the device */
- ok = SetupDiCallClassInstaller (DIF_ALLOW_INSTALL, hDeviceInfo,
- &DeviceInfoData);
- if (!ok)
- {
- if (GetLastError() != ERROR_DI_DO_DEFAULT)
- SetErrBreak ((L"SetupDiCallClassInstaller (DIF_ALLOW_INSTALL) failed (0x%08X)",
- GetLastError()));
- /* that's fine */
- }
-
- /* get the device install parameters and disable filecopy */
- DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
- ok = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
- &DeviceInstallParams);
- if (ok)
- {
- pQueueCallbackContext = SetupInitDefaultQueueCallback(NULL);
- if(pQueueCallbackContext)
- {
- DeviceInstallParams.InstallMsgHandlerContext = pQueueCallbackContext;
- DeviceInstallParams.InstallMsgHandler = (PSP_FILE_CALLBACK)vboxNetCfgWinPspFileCallback;
- ok = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
- &DeviceInstallParams);
- if(!ok)
- {
- DWORD winEr = GetLastError();
- Assert(0);
- Log(L"SetupDiSetDeviceInstallParams: SetupDiSetDeviceInstallParams failed, winEr (%d)\n", winEr);
- }
- Assert(ok);
- }
- else
- {
- DWORD winEr = GetLastError();
- Assert(0);
- Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: SetupInitDefaultQueueCallback failed, winEr (%d)\n", winEr);
- }
- }
- else
- {
- DWORD winEr = GetLastError();
- Assert(0);
- Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: SetupDiGetDeviceInstallParams failed, winEr (%d)\n", winEr);
- }
-
- /* install the files first */
- ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES, hDeviceInfo,
- &DeviceInfoData);
- if (!ok)
- SetErrBreak ((L"SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES) failed (0x%08X)",
- GetLastError()));
-
- /* get the device install parameters and disable filecopy */
- DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
- ok = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
- &DeviceInstallParams);
- if (ok)
- {
- DeviceInstallParams.Flags |= DI_NOFILECOPY;
- ok = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
- &DeviceInstallParams);
- if (!ok)
- SetErrBreak ((L"SetupDiSetDeviceInstallParams failed (0x%08X)",
- GetLastError()));
- }
-
- /*
- * Register any device-specific co-installers for this device,
- */
-
- ok = SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS,
- hDeviceInfo,
- &DeviceInfoData);
- if (!ok)
- SetErrBreak ((L"SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS) failed (0x%08X)",
- GetLastError()));
-
- /*
- * install any installer-specified interfaces.
- * and then do the real install
- */
- ok = SetupDiCallClassInstaller (DIF_INSTALLINTERFACES,
- hDeviceInfo,
- &DeviceInfoData);
- if (!ok)
- SetErrBreak ((L"SetupDiCallClassInstaller (DIF_INSTALLINTERFACES) failed (0x%08X)",
- GetLastError()));
-
- ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICE,
- hDeviceInfo,
- &DeviceInfoData);
- if (!ok)
- SetErrBreak ((L"SetupDiCallClassInstaller (DIF_INSTALLDEVICE) failed (0x%08X)",
- GetLastError()));
-
- /* Figure out NetCfgInstanceId */
- hkey = SetupDiOpenDevRegKey (hDeviceInfo,
- &DeviceInfoData,
- DICS_FLAG_GLOBAL,
- 0,
- DIREG_DRV,
- KEY_READ);
- if (hkey == INVALID_HANDLE_VALUE)
- SetErrBreak ((L"SetupDiOpenDevRegKey failed (0x%08X)",
- GetLastError()));
-
- cbSize = sizeof (pWCfgGuidString);
- DWORD ret;
- ret = RegQueryValueExW (hkey, L"NetCfgInstanceId", NULL,
- &dwValueType, (LPBYTE) pWCfgGuidString, &cbSize);
-
- RegCloseKey (hkey);
-
- if(!SetupDiGetDeviceRegistryPropertyW(hDeviceInfo, &DeviceInfoData,
- SPDRP_FRIENDLYNAME , /* IN DWORD Property,*/
- NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
- (PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/
- sizeof(DevName), /* IN DWORD PropertyBufferSize,*/
- NULL /*OUT PDWORD RequiredSize OPTIONAL*/
- ))
- {
- int err = GetLastError();
- if(err != ERROR_INVALID_DATA)
- {
- SetErrBreak ((L"SetupDiGetDeviceRegistryProperty failed (0x%08X)",
- err));
- }
-
- if(!SetupDiGetDeviceRegistryPropertyW(hDeviceInfo, &DeviceInfoData,
- SPDRP_DEVICEDESC , /* IN DWORD Property,*/
- NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
- (PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/
- sizeof(DevName), /* IN DWORD PropertyBufferSize,*/
- NULL /*OUT PDWORD RequiredSize OPTIONAL*/
- ))
- {
- err = GetLastError();
- SetErrBreak ((L"SetupDiGetDeviceRegistryProperty failed (0x%08X)",
- err));
- }
- }
- }
- while (0);
-
- /*
- * cleanup
- */
- if(pQueueCallbackContext)
- {
- SetupTermDefaultQueueCallback(pQueueCallbackContext);
- }
-
- if (hDeviceInfo != INVALID_HANDLE_VALUE)
- {
- /* an error has occurred, but the device is registered, we must remove it */
- if (ret != 0 && registered)
- SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
-
- found = SetupDiDeleteDeviceInfo (hDeviceInfo, &DeviceInfoData);
-
- /* destroy the driver info list */
- if (destroyList)
- SetupDiDestroyDriverInfoList (hDeviceInfo, &DeviceInfoData,
- SPDIT_CLASSDRIVER);
- /* clean up the device info set */
- SetupDiDestroyDeviceInfoList (hDeviceInfo);
- }
-
- /* return the network connection GUID on success */
- if (SUCCEEDED(hrc))
- {
- WCHAR ConnectoinName[128];
- ULONG cbName = sizeof(ConnectoinName);
-
- HRESULT hr = VBoxNetCfgWinGenHostonlyConnectionName (DevName, ConnectoinName, &cbName);
- if(hr == S_OK)
- {
- hr = VBoxNetCfgWinRenameConnection (pWCfgGuidString, ConnectoinName);
- }
-
- if(lppszName)
- {
- *lppszName = ::SysAllocString ((const OLECHAR *) DevName);
- if ( !*lppszName )
- {
- Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: SysAllocString failed\n");
- Assert(0);
- hrc = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
- }
- }
-
- if(pGuid)
- {
- hrc = CLSIDFromString(pWCfgGuidString, (LPCLSID) pGuid);
- if(hrc != S_OK)
- {
- Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: CLSIDFromString failed, hrc (0x%x)\n", hrc);
- Assert(0);
- }
- }
-
- INetCfg *pNc;
- LPWSTR lpszApp = NULL;
-
-
-
- hr = VBoxNetCfgWinQueryINetCfgEx( TRUE,
- L"VirtualBox Host-Only Creation",
- 30000, /* on Vista we often get 6to4svc.dll holding the lock, wait for 30 sec, */
- &pNc, /* TODO: special handling for 6to4svc.dll ???, i.e. several retrieves */
- &lpszApp );
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- hr = vboxNetCfgWinEnumNetCfgComponents(pNc,
- &GUID_DEVCLASS_NETSERVICE,
- vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority,
- pGuid);
- Assert(hr == S_OK);
-
- hr = vboxNetCfgWinEnumNetCfgComponents(pNc,
- &GUID_DEVCLASS_NETTRANS,
- vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority,
- pGuid);
- Assert(hr == S_OK);
-
- hr = vboxNetCfgWinEnumNetCfgComponents(pNc,
- &GUID_DEVCLASS_NETCLIENT,
- vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority,
- pGuid);
- Assert(hr == S_OK);
-
- if(hr == S_OK)
- {
- hr = pNc->Apply();
- Assert(hr == S_OK);
- }
-
- VBoxNetCfgWinReleaseINetCfg(pNc, TRUE);
- }
- else if(hr == NETCFG_E_NO_WRITE_LOCK && lpszApp)
- {
- Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: app %s is holding the lock, failed\n", lpszApp);
- CoTaskMemFree(lpszApp);
- }
- else
- {
- Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: VBoxNetCfgWinQueryINetCfgEx failed, hr 0x%x\n", hr);
- }
- }
-
- return hrc;
-}
-
-#undef SetErrBreak
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnumUpperBindings ()
-{
- INetCfg *pNc;
- LPWSTR lpszApp = NULL;
- HRESULT hr = VBoxNetCfgWinQueryINetCfgEx( FALSE,
- L"VirtualBox Host-Only Creation",
- 30000, /* on Vista we often get 6to4svc.dll holding the lock, wait for 30 sec, */
- &pNc, /* TODO: special handling for 6to4svc.dll ???, i.e. several retrieves */
- &lpszApp );
- Assert(hr == S_OK);
- if(hr == S_OK)
- {
- Log(L"Enumerating Net\n");
- hr = vboxNetCfgWinEnumNetCfgComponents(pNc,
- &GUID_DEVCLASS_NET,
- vboxNetCfgWinListUpperBindings,
- NULL);
- Assert(hr == S_OK);
-
- Log(L"Enumerating NetService\n");
- hr = vboxNetCfgWinEnumNetCfgComponents(pNc,
- &GUID_DEVCLASS_NETSERVICE,
- vboxNetCfgWinListUpperBindings,
- NULL);
- Assert(hr == S_OK);
-
- Log(L"Enumerating NetTrans\n");
- hr = vboxNetCfgWinEnumNetCfgComponents(pNc,
- &GUID_DEVCLASS_NETTRANS,
- vboxNetCfgWinListUpperBindings,
- NULL);
- Assert(hr == S_OK);
-
- Log(L"Enumerating NetClient\n");
- hr = vboxNetCfgWinEnumNetCfgComponents(pNc,
- &GUID_DEVCLASS_NETCLIENT,
- vboxNetCfgWinListUpperBindings,
- NULL);
- Assert(hr == S_OK);
-
- if(hr == S_OK)
- {
- hr = pNc->Apply();
- Assert(hr == S_OK);
- }
-
- VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
- }
- else if(hr == NETCFG_E_NO_WRITE_LOCK && lpszApp)
- {
- Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: app %s is holding the lock, failed\n", lpszApp);
- CoTaskMemFree(lpszApp);
- }
- else
- {
- Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: VBoxNetCfgWinQueryINetCfgEx failed, hr 0x%x\n", hr);
- }
-
- return hr;
-}
-
-
-#define VBOX_CONNECTION_NAME L"VirtualBox Host-Only Network"
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostonlyConnectionName (PCWSTR DevName, WCHAR *pBuf, PULONG pcbBuf)
-{
- const WCHAR * pSuffix = wcsrchr( DevName, L'#' );
- ULONG cbSize = sizeof(VBOX_CONNECTION_NAME);
- ULONG cbSufSize = 0;
-
- if(pSuffix)
- {
- cbSize += (ULONG)wcslen(pSuffix) * 2;
- cbSize += 2; /* for space */
- }
-
- if(*pcbBuf < cbSize)
- {
- *pcbBuf = cbSize;
- return E_FAIL;
- }
-
- wcscpy(pBuf, VBOX_CONNECTION_NAME);
- if(pSuffix)
- {
- wcscat(pBuf, L" ");
- wcscat(pBuf, pSuffix);
- }
-
- return S_OK;
-}
-
-/* network settings config */
-/**
- * Strong referencing operators. Used as a second argument to ComPtr<>/ComObjPtr<>.
- */
-template <class C>
-class ComStrongRef
-{
-protected:
-
- static void addref (C *p) { p->AddRef(); }
- static void release (C *p) { p->Release(); }
-};
-
-/**
- * Weak referencing operators. Used as a second argument to ComPtr<>/ComObjPtr<>.
- */
-template <class C>
-class ComWeakRef
-{
-protected:
-
- static void addref (C * /* p */) {}
- static void release (C * /* p */) {}
-};
-
-/**
- * Base template for smart COM pointers. Not intended to be used directly.
- */
-template <class C, template <class> class RefOps = ComStrongRef>
-class ComPtrBase : protected RefOps <C>
-{
-public:
-
- /* special template to disable AddRef()/Release() */
- template <class I>
- class NoAddRefRelease : public I
- {
- private:
-#if !defined (VBOX_WITH_XPCOM)
- STDMETHOD_(ULONG, AddRef)() = 0;
- STDMETHOD_(ULONG, Release)() = 0;
-#else /* !defined (VBOX_WITH_XPCOM) */
- NS_IMETHOD_(nsrefcnt) AddRef(void) = 0;
- NS_IMETHOD_(nsrefcnt) Release(void) = 0;
-#endif /* !defined (VBOX_WITH_XPCOM) */
- };
-
-protected:
-
- ComPtrBase () : p (NULL) {}
- ComPtrBase (const ComPtrBase &that) : p (that.p) { addref(); }
- ComPtrBase (C *that_p) : p (that_p) { addref(); }
-
- ~ComPtrBase() { release(); }
-
- ComPtrBase &operator= (const ComPtrBase &that)
- {
- safe_assign (that.p);
- return *this;
- }
-
- ComPtrBase &operator= (C *that_p)
- {
- safe_assign (that_p);
- return *this;
- }
-
-public:
-
- void setNull()
- {
- release();
- p = NULL;
- }
-
- bool isNull() const
- {
- return (p == NULL);
- }
-
- bool operator! () const { return isNull(); }
-
- bool operator< (C* that_p) const { return p < that_p; }
- bool operator== (C* that_p) const { return p == that_p; }
-
- template <class I>
- bool equalsTo (I *aThat) const
- {
- return ComPtrEquals (p, aThat);
- }
-
- template <class OC>
- bool equalsTo (const ComPtrBase <OC> &oc) const
- {
- return equalsTo ((OC *) oc);
- }
-
- /** Intended to pass instances as in parameters to interface methods */
- operator C* () const { return p; }
-
- /**
- * Dereferences the instance (redirects the -> operator to the managed
- * pointer).
- */
- NoAddRefRelease <C> *operator-> () const
- {
- AssertMsg (p, ("Managed pointer must not be null\n"));
- return (NoAddRefRelease <C> *) p;
- }
-
- template <class I>
- HRESULT queryInterfaceTo (I **pp) const
- {
- if (pp)
- {
- if (p)
- {
- return p->QueryInterface (COM_IIDOF (I), (void **) pp);
- }
- else
- {
- *pp = NULL;
- return S_OK;
- }
- }
-
- return E_INVALIDARG;
- }
-
- /** Intended to pass instances as out parameters to interface methods */
- C **asOutParam()
- {
- setNull();
- return &p;
- }
-
-private:
-
- void addref()
- {
- if (p)
- RefOps <C>::addref (p);
- }
-
- void release()
- {
- if (p)
- RefOps <C>::release (p);
- }
-
- void safe_assign (C *that_p)
- {
- /* be aware of self-assignment */
- if (that_p)
- RefOps <C>::addref (that_p);
- release();
- p = that_p;
- }
-
- C *p;
-};
-
-/**
- * Smart COM pointer wrapper that automatically manages refcounting of
- * interface pointers.
- *
- * @param I COM interface class
- */
-template <class I, template <class> class RefOps = ComStrongRef>
-class ComPtr : public ComPtrBase <I, RefOps>
-{
- typedef ComPtrBase <I, RefOps> Base;
-
-public:
-
- ComPtr () : Base() {}
- ComPtr (const ComPtr &that) : Base (that) {}
- ComPtr &operator= (const ComPtr &that)
- {
- Base::operator= (that);
- return *this;
- }
-
- template <class OI>
- ComPtr (OI *that_p) : Base () { operator= (that_p); }
-
- /* specialization for I */
- ComPtr (I *that_p) : Base (that_p) {}
-
- template <class OC>
- ComPtr (const ComPtr <OC, RefOps> &oc) : Base () { operator= ((OC *) oc); }
-
- template <class OI>
- ComPtr &operator= (OI *that_p)
- {
- if (that_p)
- that_p->QueryInterface (COM_IIDOF (I), (void **) Base::asOutParam());
- else
- Base::setNull();
- return *this;
- }
-
- /* specialization for I */
- ComPtr &operator=(I *that_p)
- {
- Base::operator= (that_p);
- return *this;
- }
-
- template <class OC>
- ComPtr &operator= (const ComPtr <OC, RefOps> &oc)
- {
- return operator= ((OC *) oc);
- }
-};
-
-static HRESULT netIfWinFindAdapterClassById(IWbemServices * pSvc, const GUID * pGuid, IWbemClassObject **pAdapterConfig)
-{
- HRESULT hres;
- WCHAR aQueryString[256];
- WCHAR GuidString[50];
-
- int length = StringFromGUID2(*pGuid, GuidString, sizeof(GuidString)/sizeof(GuidString[0]));
- if(length)
- {
- swprintf(aQueryString, L"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE SettingID = \"%s\"", GuidString);
- // Step 6: --------------------------------------------------
- // Use the IWbemServices pointer to make requests of WMI ----
-
- IEnumWbemClassObject* pEnumerator = NULL;
- hres = pSvc->ExecQuery(
- bstr_t("WQL"),
- bstr_t(aQueryString),
- WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
- NULL,
- &pEnumerator);
- if(SUCCEEDED(hres))
- {
- // Step 7: -------------------------------------------------
- // Get the data from the query in step 6 -------------------
-
- IWbemClassObject *pclsObj;
- ULONG uReturn = 0;
-
- if (pEnumerator)
- {
- HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
- &pclsObj, &uReturn);
-
- if(SUCCEEDED(hres))
- {
- if(uReturn)
- {
- pEnumerator->Release();
- *pAdapterConfig = pclsObj;
- hres = S_OK;
- return hres;
- }
- else
- {
- hres = S_FALSE;
- }
- }
-
- pEnumerator->Release();
- }
- }
- else
- {
- Log(L"Query for operating system name failed. Error code = 0x%x\n", hres);
- }
- }
- else
- {
- DWORD winEr = GetLastError();
- Log(L"Failed to create guid string from guid, winEr (%d)\n", winEr);
- hres = HRESULT_FROM_WIN32( winEr );
- }
-
- return hres;
-}
-
-static HRESULT netIfWinIsHostOnly(IWbemClassObject * pAdapterConfig, BOOL * pbIsHostOnly)
-{
- VARIANT vtServiceName;
- BOOL bIsHostOnly = FALSE;
- VariantInit(&vtServiceName);
-
- HRESULT hr = pAdapterConfig->Get(L"ServiceName", 0, &vtServiceName, 0, 0);
- if(SUCCEEDED(hr))
- {
- *pbIsHostOnly = (bstr_t(vtServiceName.bstrVal) == bstr_t("VBoxNetAdp"));
-
- VariantClear(&vtServiceName);
- }
-
- return hr;
-}
-
-static HRESULT netIfWinGetIpSettings(IWbemClassObject * pAdapterConfig, ULONG *pIpv4, ULONG *pMaskv4)
-{
- VARIANT vtIp;
- HRESULT hr;
- VariantInit(&vtIp);
-
- *pIpv4 = 0;
- *pMaskv4 = 0;
-
- hr = pAdapterConfig->Get(L"IPAddress", 0, &vtIp, 0, 0);
- if(SUCCEEDED(hr))
- {
- if(vtIp.vt == (VT_ARRAY | VT_BSTR))
- {
- VARIANT vtMask;
- VariantInit(&vtMask);
- hr = pAdapterConfig->Get(L"IPSubnet", 0, &vtMask, 0, 0);
- if(SUCCEEDED(hr))
- {
- if(vtMask.vt == (VT_ARRAY | VT_BSTR))
- {
- SAFEARRAY * pIpArray = vtIp.parray;
- SAFEARRAY * pMaskArray = vtMask.parray;
- if(pIpArray && pMaskArray)
- {
- BSTR pCurIp;
- BSTR pCurMask;
- for(long index = 0;
- SafeArrayGetElement(pIpArray, &index, (PVOID)&pCurIp) == S_OK
- && SafeArrayGetElement(pMaskArray, &index, (PVOID)&pCurMask) == S_OK;
- index++)
- {
- _bstr_t ip(pCurIp);
-
- ULONG Ipv4 = inet_addr((char*)(ip));
- if(Ipv4 != INADDR_NONE)
- {
- *pIpv4 = Ipv4;
- _bstr_t mask(pCurMask);
- *pMaskv4 = inet_addr((char*)(mask));
- break;
- }
- }
- }
- }
- else
- {
- *pIpv4 = 0;
- *pMaskv4 = 0;
- }
-
- VariantClear(&vtMask);
- }
- }
- else
- {
- *pIpv4 = 0;
- *pMaskv4 = 0;
- }
-
- VariantClear(&vtIp);
- }
-
- return hr;
-}
-
-
-static HRESULT netIfWinHasIpSettings(IWbemClassObject * pAdapterConfig, SAFEARRAY * pCheckIp, SAFEARRAY * pCheckMask, bool *pFound)
-{
- VARIANT vtIp;
- HRESULT hr;
- VariantInit(&vtIp);
-
- *pFound = false;
-
- hr = pAdapterConfig->Get(L"IPAddress", 0, &vtIp, 0, 0);
- if(SUCCEEDED(hr))
- {
- VARIANT vtMask;
- VariantInit(&vtMask);
- hr = pAdapterConfig->Get(L"IPSubnet", 0, &vtMask, 0, 0);
- if(SUCCEEDED(hr))
- {
- SAFEARRAY * pIpArray = vtIp.parray;
- SAFEARRAY * pMaskArray = vtMask.parray;
- if(pIpArray && pMaskArray)
- {
- BSTR pIp, pMask;
- for(long k = 0;
- SafeArrayGetElement(pCheckIp, &k, (PVOID)&pIp) == S_OK
- && SafeArrayGetElement(pCheckMask, &k, (PVOID)&pMask) == S_OK;
- k++)
- {
- BSTR pCurIp;
- BSTR pCurMask;
- for(long index = 0;
- SafeArrayGetElement(pIpArray, &index, (PVOID)&pCurIp) == S_OK
- && SafeArrayGetElement(pMaskArray, &index, (PVOID)&pCurMask) == S_OK;
- index++)
- {
- if(!wcsicmp(pCurIp, pIp))
- {
- if(!wcsicmp(pCurMask, pMask))
- {
- *pFound = true;
- }
- break;
- }
- }
- }
- }
-
-
- VariantClear(&vtMask);
- }
-
- VariantClear(&vtIp);
- }
-
- return hr;
-}
-
-static HRESULT netIfWinWaitIpSettings(IWbemServices *pSvc, const GUID * pGuid, SAFEARRAY * pCheckIp, SAFEARRAY * pCheckMask, ULONG sec2Wait, bool *pFound)
-{
- /* on Vista we need to wait for the address to get applied */
- /* wait for the address to appear in the list */
- HRESULT hr = S_OK;
- ULONG i;
- *pFound = false;
- ComPtr <IWbemClassObject> pAdapterConfig;
- for(i = 0;
- (hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam())) == S_OK
- && (hr = netIfWinHasIpSettings(pAdapterConfig, pCheckIp, pCheckMask, pFound)) == S_OK
- && !(*pFound)
- && i < sec2Wait/6;
- i++)
- {
- Sleep(6000);
- }
-
- return hr;
-}
-
-static HRESULT netIfWinCreateIWbemServices(IWbemServices ** ppSvc)
-{
- HRESULT hres;
-
- // Step 3: ---------------------------------------------------
- // Obtain the initial locator to WMI -------------------------
-
- IWbemLocator *pLoc = NULL;
-
- hres = CoCreateInstance(
- CLSID_WbemLocator,
- 0,
- CLSCTX_INPROC_SERVER,
- IID_IWbemLocator, (LPVOID *) &pLoc);
- if(SUCCEEDED(hres))
- {
- // Step 4: -----------------------------------------------------
- // Connect to WMI through the IWbemLocator::ConnectServer method
-
- IWbemServices *pSvc = NULL;
-
- // Connect to the root\cimv2 namespace with
- // the current user and obtain pointer pSvc
- // to make IWbemServices calls.
- hres = pLoc->ConnectServer(
- _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
- NULL, // User name. NULL = current user
- NULL, // User password. NULL = current
- 0, // Locale. NULL indicates current
- NULL, // Security flags.
- 0, // Authority (e.g. Kerberos)
- 0, // Context object
- &pSvc // pointer to IWbemServices proxy
- );
- if(SUCCEEDED(hres))
- {
- Log(L"Connected to ROOT\\CIMV2 WMI namespace\n");
-
- // Step 5: --------------------------------------------------
- // Set security levels on the proxy -------------------------
-
- hres = CoSetProxyBlanket(
- pSvc, // Indicates the proxy to set
- RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
- RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
- NULL, // Server principal name
- RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
- RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
- NULL, // client identity
- EOAC_NONE // proxy capabilities
- );
- if(SUCCEEDED(hres))
- {
- *ppSvc = pSvc;
- /* do not need it any more */
- pLoc->Release();
- return hres;
- }
- else
- {
- Log(L"Could not set proxy blanket. Error code = 0x%x\n", hres);
- }
-
- pSvc->Release();
- }
- else
- {
- Log(L"Could not connect. Error code = 0x%x\n", hres);
- }
-
- pLoc->Release();
- }
- else
- {
- Log(L"Failed to create IWbemLocator object. Err code = 0x%x\n", hres);
-// CoUninitialize();
- }
-
- return hres;
-}
-
-static HRESULT netIfWinAdapterConfigPath(IWbemClassObject *pObj, BSTR * pStr)
-{
- VARIANT index;
-
- // Get the value of the key property
- HRESULT hr = pObj->Get(L"Index", 0, &index, 0, 0);
- if(SUCCEEDED(hr))
- {
- WCHAR strIndex[8];
- swprintf(strIndex, L"%u", index.uintVal);
- *pStr = (bstr_t(L"Win32_NetworkAdapterConfiguration.Index='") + strIndex + "'").copy();
- }
- else
- {
- DWORD dwError = GetLastError();
- Assert(0);
- hr = HRESULT_FROM_WIN32( dwError );
- }
- return hr;
-}
-
-static HRESULT netIfExecMethod(IWbemServices * pSvc, IWbemClassObject *pClass, BSTR ObjPath,
- BSTR MethodName, LPWSTR *pArgNames, LPVARIANT *pArgs, UINT cArgs,
- IWbemClassObject** ppOutParams
- )
-{
- HRESULT hres = S_OK;
- // Step 6: --------------------------------------------------
- // Use the IWbemServices pointer to make requests of WMI ----
-
- ComPtr<IWbemClassObject> pInParamsDefinition;
- ComPtr<IWbemClassObject> pClassInstance;
-
- if(cArgs)
- {
- hres = pClass->GetMethod(MethodName, 0,
- pInParamsDefinition.asOutParam(), NULL);
- if(SUCCEEDED(hres))
- {
- hres = pInParamsDefinition->SpawnInstance(0, pClassInstance.asOutParam());
-
- if(SUCCEEDED(hres))
- {
- for(UINT i = 0; i < cArgs; i++)
- {
- // Store the value for the in parameters
- hres = pClassInstance->Put(pArgNames[i], 0,
- pArgs[i], 0);
- if(FAILED(hres))
- {
- break;
- }
- }
- }
- }
- }
-
- if(SUCCEEDED(hres))
- {
- IWbemClassObject* pOutParams = NULL;
- hres = pSvc->ExecMethod(ObjPath, MethodName, 0,
- NULL, pClassInstance, &pOutParams, NULL);
- if(SUCCEEDED(hres))
- {
- *ppOutParams = pOutParams;
- }
- }
-
- return hres;
-}
-
-static HRESULT netIfWinCreateIpArray(SAFEARRAY **ppArray, in_addr* aIp, UINT cIp)
-{
- HRESULT hr;
- SAFEARRAY * pIpArray = SafeArrayCreateVector(VT_BSTR, 0, cIp);
- if(pIpArray)
- {
- for(UINT i = 0; i < cIp; i++)
- {
- char* addr = inet_ntoa(aIp[i]);
- BSTR val = bstr_t(addr).copy();
- long aIndex[1];
- aIndex[0] = i;
- hr = SafeArrayPutElement(pIpArray, aIndex, val);
- if(FAILED(hr))
- {
- SysFreeString(val);
- SafeArrayDestroy(pIpArray);
- break;
- }
- }
-
- if(SUCCEEDED(hr))
- {
- *ppArray = pIpArray;
- }
- }
- else
- {
- DWORD dwError = GetLastError();
- Assert(0);
- hr = HRESULT_FROM_WIN32( dwError );
- }
-
- return hr;
-}
-
-static HRESULT netIfWinCreateIpArrayV4V6(SAFEARRAY **ppArray, BSTR Ip)
-{
- HRESULT hr;
- SAFEARRAY * pIpArray = SafeArrayCreateVector(VT_BSTR, 0, 1);
- if(pIpArray)
- {
- BSTR val = bstr_t(Ip, false).copy();
- long aIndex[1];
- aIndex[0] = 0;
- hr = SafeArrayPutElement(pIpArray, aIndex, val);
- if(FAILED(hr))
- {
- SysFreeString(val);
- SafeArrayDestroy(pIpArray);
- }
-
- if(SUCCEEDED(hr))
- {
- *ppArray = pIpArray;
- }
- }
- else
- {
- DWORD dwError = GetLastError();
- Assert(0);
- hr = HRESULT_FROM_WIN32( dwError );
- }
-
- return hr;
-}
-
-
-static HRESULT netIfWinCreateIpArrayVariantV4(VARIANT * pIpAddresses, in_addr* aIp, UINT cIp)
-{
- HRESULT hr;
- VariantInit(pIpAddresses);
- pIpAddresses->vt = VT_ARRAY | VT_BSTR;
- SAFEARRAY *pIpArray;
- hr = netIfWinCreateIpArray(&pIpArray, aIp, cIp);
- if(SUCCEEDED(hr))
- {
- pIpAddresses->parray = pIpArray;
- }
- return hr;
-}
-
-static HRESULT netIfWinCreateIpArrayVariantV4V6(VARIANT * pIpAddresses, BSTR Ip)
-{
- HRESULT hr;
- VariantInit(pIpAddresses);
- pIpAddresses->vt = VT_ARRAY | VT_BSTR;
- SAFEARRAY *pIpArray;
- hr = netIfWinCreateIpArrayV4V6(&pIpArray, Ip);
- if(SUCCEEDED(hr))
- {
- pIpAddresses->parray = pIpArray;
- }
- return hr;
-}
-
-static HRESULT netIfWinEnableStatic(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, VARIANT * pIp, VARIANT * pMask)
-{
- ComPtr<IWbemClassObject> pClass;
- BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
- HRESULT hr;
- if(ClassName)
- {
- hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
- if(SUCCEEDED(hr))
- {
- LPWSTR argNames[] = {L"IPAddress", L"SubnetMask"};
- LPVARIANT args[] = {pIp, pMask};
- ComPtr<IWbemClassObject> pOutParams;
-
- hr = netIfExecMethod(pSvc, pClass, ObjPath,
- bstr_t(L"EnableStatic"), argNames, args, 2, pOutParams.asOutParam());
- if(SUCCEEDED(hr))
- {
- VARIANT varReturnValue;
- hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
- &varReturnValue, NULL, 0);
- Assert(SUCCEEDED(hr));
- if(SUCCEEDED(hr))
- {
-// Assert(varReturnValue.vt == VT_UINT);
- int winEr = varReturnValue.uintVal;
- switch(winEr)
- {
- case 0:
- {
- hr = S_OK;
-// bool bFound;
-// HRESULT tmpHr = netIfWinWaitIpSettings(pSvc, pGuid, pIp->parray, pMask->parray, 180, &bFound);
- }
- break;
- default:
- hr = HRESULT_FROM_WIN32( winEr );
- break;
- }
- }
- }
- }
- SysFreeString(ClassName);
- }
- else
- {
- DWORD dwError = GetLastError();
- Assert(0);
- hr = HRESULT_FROM_WIN32( dwError );
- }
-
- return hr;
-}
-
-
-static HRESULT netIfWinEnableStaticV4(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, in_addr* aIp, in_addr * aMask, UINT cIp)
-{
- VARIANT ipAddresses;
- HRESULT hr = netIfWinCreateIpArrayVariantV4(&ipAddresses, aIp, cIp);
- if(SUCCEEDED(hr))
- {
- VARIANT ipMasks;
- hr = netIfWinCreateIpArrayVariantV4(&ipMasks, aMask, cIp);
- if(SUCCEEDED(hr))
- {
- hr = netIfWinEnableStatic(pSvc, pGuid, ObjPath, &ipAddresses, &ipMasks);
- VariantClear(&ipMasks);
- }
- VariantClear(&ipAddresses);
- }
- return hr;
-}
-
-static HRESULT netIfWinEnableStaticV4V6(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, BSTR Ip, BSTR Mask)
-{
- VARIANT ipAddresses;
- HRESULT hr = netIfWinCreateIpArrayVariantV4V6(&ipAddresses, Ip);
- if(SUCCEEDED(hr))
- {
- VARIANT ipMasks;
- hr = netIfWinCreateIpArrayVariantV4V6(&ipMasks, Mask);
- if(SUCCEEDED(hr))
- {
- hr = netIfWinEnableStatic(pSvc, pGuid, ObjPath, &ipAddresses, &ipMasks);
- VariantClear(&ipMasks);
- }
- VariantClear(&ipAddresses);
- }
- return hr;
-}
-
-/* win API allows to set gw metrics as well, we are not setting them */
-static HRESULT netIfWinSetGateways(IWbemServices * pSvc, BSTR ObjPath, VARIANT * pGw)
-{
- ComPtr<IWbemClassObject> pClass;
- BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
- HRESULT hr;
- if(ClassName)
- {
- hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
- if(SUCCEEDED(hr))
- {
- LPWSTR argNames[] = {L"DefaultIPGateway"};
- LPVARIANT args[] = {pGw};
- ComPtr<IWbemClassObject> pOutParams;
-
- hr = netIfExecMethod(pSvc, pClass, ObjPath,
- bstr_t(L"SetGateways"), argNames, args, 1, pOutParams.asOutParam());
- if(SUCCEEDED(hr))
- {
- VARIANT varReturnValue;
- hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
- &varReturnValue, NULL, 0);
- Assert(SUCCEEDED(hr));
- if(SUCCEEDED(hr))
- {
-// Assert(varReturnValue.vt == VT_UINT);
- int winEr = varReturnValue.uintVal;
- switch(winEr)
- {
- case 0:
- hr = S_OK;
- break;
- default:
- hr = HRESULT_FROM_WIN32( winEr );
- break;
- }
- }
- } }
- SysFreeString(ClassName);
- }
- else
- {
- DWORD dwError = GetLastError();
- Assert(0);
- hr = HRESULT_FROM_WIN32( dwError );
- }
-
- return hr;
-}
-
-/* win API allows to set gw metrics as well, we are not setting them */
-static HRESULT netIfWinSetGatewaysV4(IWbemServices * pSvc, BSTR ObjPath, in_addr* aGw, UINT cGw)
-{
- VARIANT gwais;
- HRESULT hr = netIfWinCreateIpArrayVariantV4(&gwais, aGw, cGw);
- if(SUCCEEDED(hr))
- {
- netIfWinSetGateways(pSvc, ObjPath, &gwais);
- VariantClear(&gwais);
- }
- return hr;
-}
-
-/* win API allows to set gw metrics as well, we are not setting them */
-static HRESULT netIfWinSetGatewaysV4V6(IWbemServices * pSvc, BSTR ObjPath, BSTR Gw)
-{
- VARIANT vGw;
- HRESULT hr = netIfWinCreateIpArrayVariantV4V6(&vGw, Gw);
- if(SUCCEEDED(hr))
- {
- netIfWinSetGateways(pSvc, ObjPath, &vGw);
- VariantClear(&vGw);
- }
- return hr;
-}
-
-static HRESULT netIfWinEnableDHCP(IWbemServices * pSvc, BSTR ObjPath)
-{
- ComPtr<IWbemClassObject> pClass;
- BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
- HRESULT hr;
- if(ClassName)
- {
- hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
- if(SUCCEEDED(hr))
- {
- ComPtr<IWbemClassObject> pOutParams;
-
- hr = netIfExecMethod(pSvc, pClass, ObjPath,
- bstr_t(L"EnableDHCP"), NULL, NULL, 0, pOutParams.asOutParam());
- if(SUCCEEDED(hr))
- {
- VARIANT varReturnValue;
- hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
- &varReturnValue, NULL, 0);
- Assert(SUCCEEDED(hr));
- if(SUCCEEDED(hr))
- {
-// Assert(varReturnValue.vt == VT_UINT);
- int winEr = varReturnValue.uintVal;
- switch(winEr)
- {
- case 0:
- hr = S_OK;
- break;
- default:
- hr = HRESULT_FROM_WIN32( winEr );
- break;
- }
- }
- }
- }
- SysFreeString(ClassName);
- }
- else
- {
- DWORD dwError = GetLastError();
- Assert(0);
- hr = HRESULT_FROM_WIN32( dwError );
- }
-
- return hr;
-}
-
-static HRESULT netIfWinDhcpRediscover(IWbemServices * pSvc, BSTR ObjPath)
-{
- ComPtr<IWbemClassObject> pClass;
- BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
- HRESULT hr;
- if(ClassName)
- {
- hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
- if(SUCCEEDED(hr))
- {
- ComPtr<IWbemClassObject> pOutParams;
-
- hr = netIfExecMethod(pSvc, pClass, ObjPath,
- bstr_t(L"ReleaseDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam());
- if(SUCCEEDED(hr))
- {
- VARIANT varReturnValue;
- hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
- &varReturnValue, NULL, 0);
- Assert(SUCCEEDED(hr));
- if(SUCCEEDED(hr))
- {
-// Assert(varReturnValue.vt == VT_UINT);
- int winEr = varReturnValue.uintVal;
- if(winEr == 0)
- {
- hr = netIfExecMethod(pSvc, pClass, ObjPath,
- bstr_t(L"RenewDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam());
- if(SUCCEEDED(hr))
- {
- VARIANT varReturnValue;
- hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
- &varReturnValue, NULL, 0);
- Assert(SUCCEEDED(hr));
- if(SUCCEEDED(hr))
- {
- // Assert(varReturnValue.vt == VT_UINT);
- int winEr = varReturnValue.uintVal;
- if(winEr == 0)
- {
- hr = S_OK;
- }
- else
- {
- hr = HRESULT_FROM_WIN32( winEr );
- }
- }
- }
- }
- else
- {
- hr = HRESULT_FROM_WIN32( winEr );
- }
- }
- }
- }
- SysFreeString(ClassName);
- }
- else
- {
- DWORD dwError = GetLastError();
- Assert(0);
- hr = HRESULT_FROM_WIN32( dwError );
- }
-
- return hr;
-}
-
-static HRESULT vboxNetCfgWinIsDhcpEnabled(IWbemClassObject * pAdapterConfig, BOOL *pEnabled)
-{
- VARIANT vtEnabled;
- HRESULT hr = pAdapterConfig->Get(L"DHCPEnabled", 0, &vtEnabled, 0, 0);
- if(SUCCEEDED(hr))
- {
- *pEnabled = vtEnabled.boolVal;
- }
- return hr;
-}
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGetAdapterSettings(const GUID * pGuid, PADAPTER_SETTINGS pSettings)
-{
- HRESULT hr;
- ComPtr <IWbemServices> pSvc;
- hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
- if(SUCCEEDED(hr))
- {
- ComPtr <IWbemClassObject> pAdapterConfig;
- hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam());
- if(hr == S_OK)
- {
- hr = vboxNetCfgWinIsDhcpEnabled(pAdapterConfig, &pSettings->bDhcp);
- if(SUCCEEDED(hr))
- {
- hr = netIfWinGetIpSettings(pAdapterConfig, &pSettings->ip, &pSettings->mask);
- }
- }
- }
-
- return hr;
-}
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinIsDhcpEnabled(const GUID * pGuid, BOOL *pEnabled)
-{
- HRESULT hr;
- ComPtr <IWbemServices> pSvc;
- hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
- if(SUCCEEDED(hr))
- {
- ComPtr <IWbemClassObject> pAdapterConfig;
- hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam());
- if(hr == S_OK)
- {
- VARIANT vtEnabled;
- hr = pAdapterConfig->Get(L"DHCPEnabled", 0, &vtEnabled, 0, 0);
- if(SUCCEEDED(hr))
- {
- *pEnabled = vtEnabled.boolVal;
- }
- }
- }
-
- return hr;
-}
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnableStaticIpConfig(const GUID *pGuid, ULONG ip, ULONG mask)
-{
- HRESULT hr;
- ComPtr <IWbemServices> pSvc;
- hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
- if(SUCCEEDED(hr))
- {
- ComPtr <IWbemClassObject> pAdapterConfig;
- hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam());
- if(hr == S_OK)
- {
- BOOL bIsHostOnly;
- hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly);
- if(SUCCEEDED(hr))
- {
- if(bIsHostOnly)
- {
- in_addr aIp[1];
- in_addr aMask[1];
- aIp[0].S_un.S_addr = ip;
- aMask[0].S_un.S_addr = mask;
-
- BSTR ObjPath;
- hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
- if(SUCCEEDED(hr))
- {
- hr = netIfWinEnableStaticV4(pSvc, pGuid, ObjPath, aIp, aMask, ip != 0 ? 1 : 0);
- if(SUCCEEDED(hr))
- {
-#if 0
- in_addr aGw[1];
- aGw[0].S_un.S_addr = gw;
- hr = netIfWinSetGatewaysV4(pSvc, ObjPath, aGw, 1);
- if(SUCCEEDED(hr))
-#endif
- {
- }
- }
- SysFreeString(ObjPath);
- }
- }
- else
- {
- hr = E_FAIL;
- }
- }
- }
- }
-
- return hr;
-}
-
-#if 0
-static HRESULT netIfEnableStaticIpConfigV6(const GUID *pGuid, IN_BSTR aIPV6Address, IN_BSTR aIPV6Mask, IN_BSTR aIPV6DefaultGateway)
-{
- HRESULT hr;
- ComPtr <IWbemServices> pSvc;
- hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
- if(SUCCEEDED(hr))
- {
- ComPtr <IWbemClassObject> pAdapterConfig;
- hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam());
- if(hr == S_OK)
- {
- BSTR ObjPath;
- hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
- if(SUCCEEDED(hr))
- {
- hr = netIfWinEnableStaticV4V6(pSvc, pAdapterConfig, ObjPath, aIPV6Address, aIPV6Mask);
- if(SUCCEEDED(hr))
- {
- if(aIPV6DefaultGateway)
- {
- hr = netIfWinSetGatewaysV4V6(pSvc, ObjPath, aIPV6DefaultGateway);
- }
- if(SUCCEEDED(hr))
- {
-// hr = netIfWinUpdateConfig(pIf);
- }
- }
- SysFreeString(ObjPath);
- }
- }
- }
-
- return SUCCEEDED(hr) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
-}
-
-static HRESULT netIfEnableStaticIpConfigV6(const GUID *pGuid, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
-{
- RTNETADDRIPV6 Mask;
- int rc = prefixLength2IPv6Address(aIPV6MaskPrefixLength, &Mask);
- if(RT_SUCCESS(rc))
- {
- Bstr maskStr = composeIPv6Address(&Mask);
- rc = netIfEnableStaticIpConfigV6(pGuid, aIPV6Address, maskStr, NULL);
- }
- return rc;
-}
-#endif
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnableDynamicIpConfig(const GUID *pGuid)
-{
- HRESULT hr;
- ComPtr <IWbemServices> pSvc;
- hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
- if(SUCCEEDED(hr))
- {
- ComPtr <IWbemClassObject> pAdapterConfig;
- hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam());
- if(hr == S_OK)
- {
- BOOL bIsHostOnly;
- hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly);
- if(SUCCEEDED(hr))
- {
- if(bIsHostOnly)
- {
- BSTR ObjPath;
- hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
- if(SUCCEEDED(hr))
- {
- hr = netIfWinEnableDHCP(pSvc, ObjPath);
- if(SUCCEEDED(hr))
- {
-// hr = netIfWinUpdateConfig(pIf);
- }
- SysFreeString(ObjPath);
- }
- }
- else
- {
- hr = E_FAIL;
- }
- }
- }
- }
-
-
- return hr;
-}
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinDhcpRediscover(const GUID *pGuid)
-{
- HRESULT hr;
- ComPtr <IWbemServices> pSvc;
- hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
- if(SUCCEEDED(hr))
- {
- ComPtr <IWbemClassObject> pAdapterConfig;
- hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam());
- if(hr == S_OK)
- {
- BOOL bIsHostOnly;
- hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly);
- if(SUCCEEDED(hr))
- {
- if(bIsHostOnly)
- {
- BSTR ObjPath;
- hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
- if(SUCCEEDED(hr))
- {
- hr = netIfWinDhcpRediscover(pSvc, ObjPath);
- if(SUCCEEDED(hr))
- {
-// hr = netIfWinUpdateConfig(pIf);
- }
- SysFreeString(ObjPath);
- }
- }
- else
- {
- hr = E_FAIL;
- }
- }
- }
- }
-
-
- return hr;
-}
-
-typedef bool (*IPSETTINGS_CALLBACK) (ULONG ip, ULONG mask, PVOID pContext);
-
-static void vboxNetCfgWinEnumIpConfig(PIP_ADAPTER_ADDRESSES pAddresses, IPSETTINGS_CALLBACK pCallback, PVOID pContext)
-{
- PIP_ADAPTER_ADDRESSES pAdapter;
- for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
- {
- PIP_ADAPTER_UNICAST_ADDRESS pAddr = pAdapter->FirstUnicastAddress;
- PIP_ADAPTER_PREFIX pPrefix = pAdapter->FirstPrefix;
-
- if(pAddr && pPrefix)
- {
- do
- {
- bool fIPFound, fMaskFound;
- fIPFound = fMaskFound = false;
- ULONG ip, mask;
- for (; pAddr && !fIPFound; pAddr = pAddr->Next)
- {
- switch (pAddr->Address.lpSockaddr->sa_family)
- {
- case AF_INET:
- fIPFound = true;
- memcpy(&ip,
- &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
- sizeof(ip));
- break;
-// case AF_INET6:
-// break;
- }
- }
-
- for (; pPrefix && !fMaskFound; pPrefix = pPrefix->Next)
- {
- switch (pPrefix->Address.lpSockaddr->sa_family)
- {
- case AF_INET:
- if(!pPrefix->PrefixLength || pPrefix->PrefixLength > 31) /* in case the ip helper API is queried while NetCfg write lock is held */
- break; /* the address values can contain illegal values */
- fMaskFound = true;
- mask = (~(((ULONG)~0) >> pPrefix->PrefixLength));
- mask = htonl(mask);
- break;
-// case AF_INET6:
-// break;
- }
- }
-
- if(!fIPFound || !fMaskFound)
- break;
-
- if(!pCallback(ip, mask, pContext))
- return;
- }while(true);
- }
- }
-}
-
-typedef struct _IPPROBE_CONTEXT
-{
- ULONG Prefix;
- bool bConflict;
-}IPPROBE_CONTEXT, *PIPPROBE_CONTEXT;
-
-#define IPPROBE_INIT(_pContext, _addr) \
- ((_pContext)->bConflict = false, \
- (_pContext)->Prefix = _addr)
-
-#define IPPROBE_INIT_STR(_pContext, _straddr) \
- IPROBE_INIT(_pContext, inet_addr(_straddr))
-
-static bool vboxNetCfgWinIpProbeCallback (ULONG ip, ULONG mask, PVOID pContext)
-{
- PIPPROBE_CONTEXT pProbe = (PIPPROBE_CONTEXT)pContext;
-
- if((ip & mask) == (pProbe->Prefix & mask))
- {
- pProbe->bConflict = true;
- return false;
- }
-
- return true;
-}
-
-VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(PULONG pNetIp, PULONG pNetMask)
-{
- DWORD dwRc;
- HRESULT hr = S_OK;
- /*
- * Most of the hosts probably have less than 10 adapters,
- * so we'll mostly succeed from the first attempt.
- */
- ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
- PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)malloc(uBufLen);
- if (!pAddresses)
- return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
- dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
- if (dwRc == ERROR_BUFFER_OVERFLOW)
- {
- /* Impressive! More than 10 adapters! Get more memory and try again. */
- free(pAddresses);
- pAddresses = (PIP_ADAPTER_ADDRESSES)malloc(uBufLen);
- if (!pAddresses)
- return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
- dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
- }
- if (dwRc == NO_ERROR)
- {
- IPPROBE_CONTEXT Context;
- const ULONG ip192168 = inet_addr("192.168.0.0");
- srand(GetTickCount());
-
- *pNetIp = 0;
- *pNetMask = 0;
-
- for(int i = 0; i < 255; i++)
- {
- ULONG ipProbe = rand()*255/RAND_MAX;
- ipProbe = ip192168 | (ipProbe << 16);
- IPPROBE_INIT(&Context, ipProbe);
- vboxNetCfgWinEnumIpConfig(pAddresses, vboxNetCfgWinIpProbeCallback, &Context);
- if(!Context.bConflict)
- {
- *pNetIp = ipProbe;
- *pNetMask = inet_addr("255.255.255.0");
- break;
- }
- }
- if(*pNetIp == 0)
- dwRc = ERROR_DHCP_ADDRESS_CONFLICT;
- }
- else
- {
- Log(L"VBoxNetCfgWinGenHostOnlyNetworkNetworkIp: GetAdaptersAddresses err (%d)\n", dwRc);
- }
- free(pAddresses);
-
- if(dwRc != NO_ERROR)
- {
- hr = HRESULT_FROM_WIN32(dwRc);
- }
-
- return hr;
-}
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Monitor/Makefile.kup b/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/Makefile.kup
index e69de29bb..e69de29bb 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/Monitor/Makefile.kup
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/Makefile.kup
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp
new file mode 100644
index 000000000..9692ff87d
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp
@@ -0,0 +1,2771 @@
+/* $Id: VBoxNetCfg.cpp 37301 2011-06-01 19:57:39Z vboxsync $ */
+/** @file
+ * VBoxNetCfg.cpp - Network Configuration API.
+ */
+/*
+ * 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.
+ */
+#include "VBox/VBoxNetCfg-win.h"
+#include "VBox/VBoxDrvCfg-win.h"
+
+#define _WIN32_DCOM
+
+#include <iphlpapi.h>
+
+#include <devguid.h>
+#include <stdio.h>
+#include <regstr.h>
+#include <shlobj.h>
+#include <cfgmgr32.h>
+#include <tchar.h>
+#include <objbase.h>
+
+#include <crtdbg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <Wbemidl.h>
+#include <comdef.h>
+
+
+#ifndef Assert
+//# ifdef DEBUG
+//# define Assert(_expr) assert(_expr)
+//# else
+//# define Assert(_expr) do{ }while (0)
+//# endif
+# define Assert _ASSERT
+# define AssertMsg(expr, msg) do{}while (0)
+#endif
+static LOG_ROUTINE g_Logger = NULL;
+
+static VOID DoLogging(LPCSTR szString, ...);
+#define Log DoLogging
+#define LogFlow(x) DoLogging x
+
+#define DbgLog
+
+#define VBOX_NETCFG_LOCK_TIME_OUT 5000
+
+
+static HRESULT vboxNetCfgWinINetCfgLock(IN INetCfg *pNetCfg,
+ IN LPCWSTR pszwClientDescription,
+ IN DWORD cmsTimeout,
+ OUT LPWSTR *ppszwClientDescription)
+{
+ INetCfgLock *pLock;
+ HRESULT hr = pNetCfg->QueryInterface(IID_INetCfgLock, (PVOID*)&pLock);
+ if (FAILED(hr))
+ {
+ LogFlow(("QueryInterface failed, hr (0x%x)\n", hr));
+ return hr;
+ }
+
+ hr = pLock->AcquireWriteLock(cmsTimeout, pszwClientDescription, ppszwClientDescription);
+ if (hr == S_FALSE)
+ {
+ LogFlow(("Write lock busy\n"));
+ }
+ else if (FAILED(hr))
+ {
+ LogFlow(("AcquireWriteLock failed, hr (0x%x)\n", hr));
+ }
+
+ pLock->Release();
+ return hr;
+}
+
+static HRESULT vboxNetCfgWinINetCfgUnlock(IN INetCfg *pNetCfg)
+{
+ INetCfgLock *pLock;
+ HRESULT hr = pNetCfg->QueryInterface(IID_INetCfgLock, (PVOID*)&pLock);
+ if (FAILED(hr))
+ {
+ LogFlow(("QueryInterface failed, hr (0x%x)\n", hr));
+ return hr;
+ }
+
+ hr = pLock->ReleaseWriteLock();
+ if (FAILED(hr))
+ LogFlow(("ReleaseWriteLock failed, hr (0x%x)\n", hr));
+
+ pLock->Release();
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinQueryINetCfg(OUT INetCfg **ppNetCfg,
+ IN BOOL fGetWriteLock,
+ IN LPCWSTR pszwClientDescription,
+ IN DWORD cmsTimeout,
+ OUT LPWSTR *ppszwClientDescription)
+{
+ INetCfg *pNetCfg;
+ HRESULT hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (PVOID*)&pNetCfg);
+ if (FAILED(hr))
+ {
+ LogFlow(("CoCreateInstance failed, hr (0x%x)\n", hr));
+ return hr;
+ }
+
+ if (fGetWriteLock)
+ {
+ hr = vboxNetCfgWinINetCfgLock(pNetCfg, pszwClientDescription, cmsTimeout, ppszwClientDescription);
+ if (hr == S_FALSE)
+ {
+ LogFlow(("Write lock is busy\n", hr));
+ hr = NETCFG_E_NO_WRITE_LOCK;
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = pNetCfg->Initialize(NULL);
+ if (SUCCEEDED(hr))
+ {
+ *ppNetCfg = pNetCfg;
+ return S_OK;
+ }
+ else
+ LogFlow(("Initialize failed, hr (0x%x)\n", hr));
+ }
+
+ pNetCfg->Release();
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinReleaseINetCfg(IN INetCfg *pNetCfg, IN BOOL fHasWriteLock)
+{
+ HRESULT hr = pNetCfg->Uninitialize();
+ if (FAILED(hr))
+ {
+ LogFlow(("Uninitialize failed, hr (0x%x)\n", hr));
+ return hr;
+ }
+
+ if (fHasWriteLock)
+ {
+ hr = vboxNetCfgWinINetCfgUnlock(pNetCfg);
+ if (FAILED(hr))
+ LogFlow(("vboxNetCfgWinINetCfgUnlock failed, hr (0x%x)\n", hr));
+ }
+
+ pNetCfg->Release();
+ return hr;
+}
+
+static HRESULT vboxNetCfgWinGetComponentByGuidEnum(IEnumNetCfgComponent *pEnumNcc,
+ IN const GUID *pGuid,
+ OUT INetCfgComponent **ppNcc)
+{
+ HRESULT hr = pEnumNcc->Reset();
+ if (FAILED(hr))
+ {
+ LogFlow(("Reset failed, hr (0x%x)\n", hr));
+ return hr;
+ }
+
+ INetCfgComponent *pNcc;
+ while ((hr = pEnumNcc->Next(1, &pNcc, NULL)) == S_OK)
+ {
+ ULONG uComponentStatus;
+ hr = pNcc->GetDeviceStatus(&uComponentStatus);
+ if (SUCCEEDED(hr))
+ {
+ if (uComponentStatus == 0)
+ {
+ GUID NccGuid;
+ hr = pNcc->GetInstanceGuid(&NccGuid);
+
+ if (SUCCEEDED(hr))
+ {
+ if (NccGuid == *pGuid)
+ {
+ /* found the needed device */
+ *ppNcc = pNcc;
+ break;
+ }
+ }
+ else
+ LogFlow(("GetInstanceGuid failed, hr (0x%x)\n", hr));
+ }
+ }
+
+ pNcc->Release();
+ }
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGetComponentByGuid(IN INetCfg *pNc,
+ IN const GUID *pguidClass,
+ IN const GUID * pComponentGuid,
+ OUT INetCfgComponent **ppncc)
+{
+ IEnumNetCfgComponent *pEnumNcc;
+ HRESULT hr = pNc->EnumComponents(pguidClass, &pEnumNcc);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = vboxNetCfgWinGetComponentByGuidEnum(pEnumNcc, pComponentGuid, ppncc);
+ if (hr == S_FALSE)
+ {
+ LogFlow(("Component not found\n"));
+ }
+ else if (FAILED(hr))
+ {
+ LogFlow(("vboxNetCfgWinGetComponentByGuidEnum failed, hr (0x%x)\n", hr));
+ }
+ pEnumNcc->Release();
+ }
+ else
+ LogFlow(("EnumComponents failed, hr (0x%x)\n", hr));
+ return hr;
+}
+
+static HRESULT vboxNetCfgWinQueryInstaller(IN INetCfg *pNetCfg, IN const GUID *pguidClass, INetCfgClassSetup **ppSetup)
+{
+ HRESULT hr = pNetCfg->QueryNetCfgClass(pguidClass, IID_INetCfgClassSetup, (void**)ppSetup);
+ if (FAILED(hr))
+ LogFlow(("QueryNetCfgClass failed, hr (0x%x)\n", hr));
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinInstallComponent(IN INetCfg *pNetCfg, IN LPCWSTR pszwComponentId, IN const GUID *pguidClass,
+ OUT INetCfgComponent **ppComponent)
+{
+ INetCfgClassSetup *pSetup;
+ HRESULT hr = vboxNetCfgWinQueryInstaller(pNetCfg, pguidClass, &pSetup);
+ if (FAILED(hr))
+ {
+ LogFlow(("vboxNetCfgWinQueryInstaller failed, hr (0x%x)\n", hr));
+ return hr;
+ }
+
+ OBO_TOKEN Token;
+ ZeroMemory(&Token, sizeof (Token));
+ Token.Type = OBO_USER;
+
+ hr = pSetup->Install(pszwComponentId, &Token,
+ 0, /* IN DWORD dwSetupFlags */
+ 0, /* IN DWORD dwUpgradeFromBuildNo */
+ NULL, /* IN LPCWSTR pszwAnswerFile */
+ NULL, /* IN LPCWSTR pszwAnswerSections */
+ ppComponent);
+ if (SUCCEEDED(hr))
+ {
+ /* ignore the apply failure */
+ HRESULT tmpHr = pNetCfg->Apply();
+ Assert(tmpHr == S_OK);
+ if (tmpHr != S_OK)
+ LogFlow(("Apply failed, hr (0x%x)\n", tmpHr));
+ }
+ else
+ LogFlow(("Install failed, hr (0x%x)\n", hr));
+
+ pSetup->Release();
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinInstallInfAndComponent(IN INetCfg *pNetCfg, IN LPCWSTR pszwComponentId, IN const GUID *pguidClass,
+ IN LPCWSTR * apInfPaths, IN UINT cInfPaths,
+ OUT INetCfgComponent **ppComponent)
+{
+ HRESULT hr = S_OK;
+ UINT i = 0;
+
+ LogFlow(("Installing %u INF files ...\n", cInfPaths));
+
+ for (; i < cInfPaths; i++)
+ {
+ LogFlow(("Installing INF file \"%ws\" ...\n", apInfPaths[i]));
+ hr = VBoxDrvCfgInfInstall(apInfPaths[i]);
+ if (FAILED(hr))
+ {
+ LogFlow(("VBoxNetCfgWinInfInstall failed, hr (0x%x)\n", hr));
+ break;
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = VBoxNetCfgWinInstallComponent(pNetCfg, pszwComponentId, pguidClass, ppComponent);
+ if (FAILED(hr))
+ LogFlow(("VBoxNetCfgWinInstallComponent failed, hr (0x%x)\n", hr));
+ }
+
+ if (FAILED(hr))
+ {
+ for (UINT j = i - 1; j != 0; j--)
+ VBoxDrvCfgInfUninstall(apInfPaths[j], 0);
+ }
+
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinUninstallComponent(IN INetCfg *pNetCfg, IN INetCfgComponent *pComponent)
+{
+ GUID GuidClass;
+ HRESULT hr = pComponent->GetClassGuid(&GuidClass);
+ if (FAILED(hr))
+ {
+ LogFlow(("GetClassGuid failed, hr (0x%x)\n", hr));
+ return hr;
+ }
+
+ INetCfgClassSetup *pSetup = NULL;
+ hr = vboxNetCfgWinQueryInstaller(pNetCfg, &GuidClass, &pSetup);
+ if (FAILED(hr))
+ {
+ LogFlow(("vboxNetCfgWinQueryInstaller failed, hr (0x%x)\n", hr));
+ return hr;
+ }
+
+ OBO_TOKEN Token;
+ ZeroMemory(&Token, sizeof(Token));
+ Token.Type = OBO_USER;
+
+ hr = pSetup->DeInstall(pComponent, &Token, NULL /* OUT LPWSTR *pmszwRefs */);
+ if (SUCCEEDED(hr))
+ {
+ hr = pNetCfg->Apply();
+ if (FAILED(hr))
+ LogFlow(("Apply failed, hr (0x%x)\n", hr));
+ }
+ else
+ LogFlow(("DeInstall failed, hr (0x%x)\n", hr));
+
+ if (pSetup)
+ pSetup->Release();
+ return hr;
+}
+
+typedef BOOL (*VBOXNETCFGWIN_NETCFGENUM_CALLBACK) (IN INetCfg *pNetCfg, IN INetCfgComponent *pNetCfgComponent, PVOID pContext);
+
+static HRESULT vboxNetCfgWinEnumNetCfgComponents(IN INetCfg *pNetCfg,
+ IN const GUID *pguidClass,
+ VBOXNETCFGWIN_NETCFGENUM_CALLBACK callback,
+ PVOID pContext)
+{
+ IEnumNetCfgComponent *pEnumComponent;
+ HRESULT hr = pNetCfg->EnumComponents(pguidClass, &pEnumComponent);
+ if (SUCCEEDED(hr))
+ {
+ INetCfgComponent *pNetCfgComponent;
+ hr = pEnumComponent->Reset();
+ do
+ {
+ hr = pEnumComponent->Next(1, &pNetCfgComponent, NULL);
+ if (hr == S_OK)
+ {
+// ULONG uComponentStatus;
+// hr = pNcc->GetDeviceStatus(&uComponentStatus);
+// if (SUCCEEDED(hr))
+ BOOL fResult = FALSE;
+ if (pNetCfgComponent)
+ {
+ if (pContext)
+ fResult = callback(pNetCfg, pNetCfgComponent, pContext);
+ pNetCfgComponent->Release();
+ }
+
+ if (!fResult)
+ break;
+ }
+ else
+ {
+ if (hr == S_FALSE)
+ {
+ hr = S_OK;
+ }
+ else
+ LogFlow(("Next failed, hr (0x%x)\n", hr));
+ break;
+ }
+ } while (true);
+ pEnumComponent->Release();
+ }
+ return hr;
+}
+
+static BOOL vboxNetCfgWinRemoveAllNetDevicesOfIdCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext)
+{
+ HRESULT hr = S_OK;
+ SP_REMOVEDEVICE_PARAMS rmdParams;
+
+ rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
+ rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE;
+ rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL;
+ rmdParams.HwProfile = 0;
+
+ if (SetupDiSetClassInstallParams(hDevInfo,pDev,&rmdParams.ClassInstallHeader,sizeof(rmdParams)))
+ {
+ if (SetupDiSetSelectedDevice (hDevInfo, pDev))
+ {
+ if (SetupDiCallClassInstaller(DIF_REMOVE,hDevInfo,pDev))
+ {
+ SP_DEVINSTALL_PARAMS devParams;
+ devParams.cbSize = sizeof(devParams);
+ if (SetupDiGetDeviceInstallParams(hDevInfo,pDev,&devParams))
+ {
+ if (devParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT))
+ {
+ hr = S_FALSE;
+ Log(("!!!REBOOT REQUIRED!!!\n"));
+ }
+ }
+ }
+ else
+ {
+ DWORD dwErr = GetLastError();
+ LogFlow(("SetupDiCallClassInstaller failed with %ld\n", dwErr));
+ hr = HRESULT_FROM_WIN32(dwErr);
+ }
+ }
+ else
+ {
+ DWORD dwErr = GetLastError();
+ LogFlow(("SetupDiSetSelectedDevice failed with %ld\n", dwErr));
+ hr = HRESULT_FROM_WIN32(dwErr);
+ }
+ }
+ else
+ {
+ DWORD dwErr = GetLastError();
+ LogFlow(("SetupDiSetClassInstallParams failed with %ld\n", dwErr));
+ hr = HRESULT_FROM_WIN32(dwErr);
+ }
+
+ return TRUE;
+}
+
+typedef BOOL (*VBOXNETCFGWIN_NETENUM_CALLBACK) (HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext);
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnumNetDevices(LPCWSTR pPnPId, VBOXNETCFGWIN_NETENUM_CALLBACK callback, PVOID pContext)
+{
+ DWORD winEr;
+ HRESULT hr = S_OK;
+
+ HDEVINFO hDevInfo = SetupDiGetClassDevsExW(
+ &GUID_DEVCLASS_NET,
+ NULL, /* IN PCTSTR Enumerator, OPTIONAL*/
+ NULL, /*IN HWND hwndParent, OPTIONAL*/
+ DIGCF_PRESENT, /*IN DWORD Flags,*/
+ NULL, /*IN HDEVINFO DeviceInfoSet, OPTIONAL*/
+ NULL, /*IN PCTSTR MachineName, OPTIONAL*/
+ NULL /*IN PVOID Reserved*/
+ );
+ if (hDevInfo != INVALID_HANDLE_VALUE)
+ {
+ DWORD iDev = 0;
+ SP_DEVINFO_DATA Dev;
+ PBYTE pBuffer = NULL;
+ DWORD cbBuffer = 0;
+ DWORD cbRequired = 0;
+ BOOL bEnumCompleted;
+ size_t cPnPId = wcslen(pPnPId);
+
+ Dev.cbSize = sizeof(Dev);
+
+ for (; bEnumCompleted = SetupDiEnumDeviceInfo(hDevInfo, iDev, &Dev); iDev++)
+ {
+ if (!SetupDiGetDeviceRegistryPropertyW(hDevInfo,&Dev,
+ SPDRP_HARDWAREID, /* IN DWORD Property,*/
+ NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
+ pBuffer, /*OUT PBYTE PropertyBuffer,*/
+ cbBuffer, /* IN DWORD PropertyBufferSize,*/
+ &cbRequired /*OUT PDWORD RequiredSize OPTIONAL*/
+ ))
+ {
+ winEr = GetLastError();
+ if (winEr != ERROR_INSUFFICIENT_BUFFER)
+ {
+ LogFlow(("SetupDiGetDeviceRegistryPropertyW (1) failed winErr(%d)\n", winEr));
+ hr = HRESULT_FROM_WIN32(winEr);
+ break;
+ }
+
+ if (pBuffer)
+ free(pBuffer);
+
+ pBuffer = (PBYTE)malloc(cbRequired);
+ cbBuffer = cbRequired;
+
+ if (!SetupDiGetDeviceRegistryPropertyW(hDevInfo,&Dev,
+ SPDRP_HARDWAREID, /* IN DWORD Property,*/
+ NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
+ pBuffer, /*OUT PBYTE PropertyBuffer,*/
+ cbBuffer, /* IN DWORD PropertyBufferSize,*/
+ &cbRequired /*OUT PDWORD RequiredSize OPTIONAL*/
+ ))
+ {
+ winEr = GetLastError();
+ LogFlow(("SetupDiGetDeviceRegistryPropertyW (2) failed winErr(%d)\n", winEr));
+ hr = HRESULT_FROM_WIN32(winEr);
+ break;
+ }
+ }
+
+ PWCHAR pCurId = (PWCHAR)pBuffer;
+ size_t cCurId = wcslen(pCurId);
+ if (cCurId >= cPnPId)
+ {
+ pCurId += cCurId - cPnPId;
+ if (!wcsnicmp(pCurId, pPnPId, cPnPId))
+ {
+
+ if (!callback(hDevInfo,&Dev,pContext))
+ break;
+ }
+ }
+
+ }
+
+ if (pBuffer)
+ free(pBuffer);
+
+ if (bEnumCompleted)
+ {
+ winEr = GetLastError();
+ hr = winEr == ERROR_NO_MORE_ITEMS ? S_OK : HRESULT_FROM_WIN32(winEr);
+ }
+
+ SetupDiDestroyDeviceInfoList(hDevInfo);
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ LogFlow(("SetupDiGetClassDevsExW failed winErr(%d)\n", winEr));
+ hr = HRESULT_FROM_WIN32(winEr);
+ }
+
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRemoveAllNetDevicesOfId(IN LPCWSTR lpszPnPId)
+{
+ return VBoxNetCfgWinEnumNetDevices(lpszPnPId, vboxNetCfgWinRemoveAllNetDevicesOfIdCallback, NULL);
+}
+
+/*
+ * logging
+ */
+static VOID DoLogging(LPCSTR szString, ...)
+{
+ LOG_ROUTINE pRoutine = (LOG_ROUTINE)(*((void * volatile *)&g_Logger));
+ if (pRoutine)
+ {
+ char szBuffer[4096] = {0};
+ va_list pArgList;
+ va_start(pArgList, szString);
+ _vsnprintf(szBuffer, RT_ELEMENTS(szBuffer), szString, pArgList);
+ va_end(pArgList);
+
+ pRoutine(szBuffer);
+ }
+}
+
+VBOXNETCFGWIN_DECL(VOID) VBoxNetCfgWinSetLogging(IN LOG_ROUTINE pfnLog)
+{
+ *((void * volatile *)&g_Logger) = pfnLog;
+}
+
+/*
+ * IP configuration API
+ */
+/* network settings config */
+/**
+ * Strong referencing operators. Used as a second argument to ComPtr<>/ComObjPtr<>.
+ */
+template <class C>
+class ComStrongRef
+{
+protected:
+
+ static void addref (C *p) { p->AddRef(); }
+ static void release (C *p) { p->Release(); }
+};
+
+
+/**
+ * Base template for smart COM pointers. Not intended to be used directly.
+ */
+template <class C, template <class> class RefOps = ComStrongRef>
+class ComPtrBase : protected RefOps <C>
+{
+public:
+
+ /* special template to disable AddRef()/Release() */
+ template <class I>
+ class NoAddRefRelease : public I
+ {
+ private:
+#if !defined (VBOX_WITH_XPCOM)
+ STDMETHOD_(ULONG, AddRef)() = 0;
+ STDMETHOD_(ULONG, Release)() = 0;
+#else /* !defined (VBOX_WITH_XPCOM) */
+ NS_IMETHOD_(nsrefcnt) AddRef(void) = 0;
+ NS_IMETHOD_(nsrefcnt) Release(void) = 0;
+#endif /* !defined (VBOX_WITH_XPCOM) */
+ };
+
+protected:
+
+ ComPtrBase () : p (NULL) {}
+ ComPtrBase (const ComPtrBase &that) : p (that.p) { addref(); }
+ ComPtrBase (C *that_p) : p (that_p) { addref(); }
+
+ ~ComPtrBase() { release(); }
+
+ ComPtrBase &operator= (const ComPtrBase &that)
+ {
+ safe_assign (that.p);
+ return *this;
+ }
+
+ ComPtrBase &operator= (C *that_p)
+ {
+ safe_assign (that_p);
+ return *this;
+ }
+
+public:
+
+ void setNull()
+ {
+ release();
+ p = NULL;
+ }
+
+ bool isNull() const
+ {
+ return (p == NULL);
+ }
+
+ bool operator! () const { return isNull(); }
+
+ bool operator< (C* that_p) const { return p < that_p; }
+ bool operator== (C* that_p) const { return p == that_p; }
+
+ template <class I>
+ bool equalsTo (I *aThat) const
+ {
+ return ComPtrEquals (p, aThat);
+ }
+
+ template <class OC>
+ bool equalsTo (const ComPtrBase <OC> &oc) const
+ {
+ return equalsTo ((OC *) oc);
+ }
+
+ /** Intended to pass instances as in parameters to interface methods */
+ operator C* () const { return p; }
+
+ /**
+ * Dereferences the instance (redirects the -> operator to the managed
+ * pointer).
+ */
+ NoAddRefRelease <C> *operator-> () const
+ {
+ AssertMsg (p, ("Managed pointer must not be null\n"));
+ return (NoAddRefRelease <C> *) p;
+ }
+
+ template <class I>
+ HRESULT queryInterfaceTo (I **pp) const
+ {
+ if (pp)
+ {
+ if (p)
+ {
+ return p->QueryInterface (COM_IIDOF (I), (void **) pp);
+ }
+ else
+ {
+ *pp = NULL;
+ return S_OK;
+ }
+ }
+
+ return E_INVALIDARG;
+ }
+
+ /** Intended to pass instances as out parameters to interface methods */
+ C **asOutParam()
+ {
+ setNull();
+ return &p;
+ }
+
+private:
+
+ void addref()
+ {
+ if (p)
+ RefOps <C>::addref (p);
+ }
+
+ void release()
+ {
+ if (p)
+ RefOps <C>::release (p);
+ }
+
+ void safe_assign (C *that_p)
+ {
+ /* be aware of self-assignment */
+ if (that_p)
+ RefOps <C>::addref (that_p);
+ release();
+ p = that_p;
+ }
+
+ C *p;
+};
+
+/**
+ * Smart COM pointer wrapper that automatically manages refcounting of
+ * interface pointers.
+ *
+ * @param I COM interface class
+ */
+template <class I, template <class> class RefOps = ComStrongRef>
+class ComPtr : public ComPtrBase <I, RefOps>
+{
+ typedef ComPtrBase <I, RefOps> Base;
+
+public:
+
+ ComPtr () : Base() {}
+ ComPtr (const ComPtr &that) : Base(that) {}
+ ComPtr &operator= (const ComPtr &that)
+ {
+ Base::operator= (that);
+ return *this;
+ }
+
+ template <class OI>
+ ComPtr (OI *that_p) : Base () { operator= (that_p); }
+
+ /* specialization for I */
+ ComPtr (I *that_p) : Base (that_p) {}
+
+ template <class OC>
+ ComPtr (const ComPtr <OC, RefOps> &oc) : Base () { operator= ((OC *) oc); }
+
+ template <class OI>
+ ComPtr &operator= (OI *that_p)
+ {
+ if (that_p)
+ that_p->QueryInterface (COM_IIDOF (I), (void **) Base::asOutParam());
+ else
+ Base::setNull();
+ return *this;
+ }
+
+ /* specialization for I */
+ ComPtr &operator=(I *that_p)
+ {
+ Base::operator= (that_p);
+ return *this;
+ }
+
+ template <class OC>
+ ComPtr &operator= (const ComPtr <OC, RefOps> &oc)
+ {
+ return operator= ((OC *) oc);
+ }
+};
+
+static HRESULT netIfWinFindAdapterClassById(IWbemServices * pSvc, const GUID * pGuid, IWbemClassObject **pAdapterConfig)
+{
+ HRESULT hr;
+ WCHAR aQueryString[256];
+ WCHAR GuidString[50];
+
+ int length = StringFromGUID2(*pGuid, GuidString, sizeof(GuidString)/sizeof(GuidString[0]));
+ if (length)
+ {
+ swprintf(aQueryString, L"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE SettingID = \"%s\"", GuidString);
+ IEnumWbemClassObject* pEnumerator = NULL;
+ hr = pSvc->ExecQuery(bstr_t("WQL"), bstr_t(aQueryString), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
+ if (SUCCEEDED(hr))
+ {
+ IWbemClassObject *pclsObj;
+ ULONG uReturn = 0;
+
+ if (pEnumerator)
+ {
+ HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+
+ if (SUCCEEDED(hr))
+ {
+ if (uReturn)
+ {
+ pEnumerator->Release();
+ *pAdapterConfig = pclsObj;
+ hr = S_OK;
+ return hr;
+ }
+ else
+ {
+ hr = S_FALSE;
+ }
+ }
+
+ pEnumerator->Release();
+ }
+ }
+ else
+ LogFlow(("ExecQuery failed (0x%x)\n", hr));
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ LogFlow(("StringFromGUID2 failed winEr (%d)\n", winEr));
+ hr = HRESULT_FROM_WIN32( winEr );
+ }
+
+ return hr;
+}
+
+static HRESULT netIfWinIsHostOnly(IWbemClassObject * pAdapterConfig, BOOL * pbIsHostOnly)
+{
+ VARIANT vtServiceName;
+ BOOL bIsHostOnly = FALSE;
+ VariantInit(&vtServiceName);
+
+ HRESULT hr = pAdapterConfig->Get(L"ServiceName", 0, &vtServiceName, 0, 0);
+ if (SUCCEEDED(hr))
+ {
+ *pbIsHostOnly = (bstr_t(vtServiceName.bstrVal) == bstr_t("VBoxNetAdp"));
+
+ VariantClear(&vtServiceName);
+ }
+
+ return hr;
+}
+
+static HRESULT netIfWinGetIpSettings(IWbemClassObject * pAdapterConfig, ULONG *pIpv4, ULONG *pMaskv4)
+{
+ VARIANT vtIp;
+ HRESULT hr;
+ VariantInit(&vtIp);
+
+ *pIpv4 = 0;
+ *pMaskv4 = 0;
+
+ hr = pAdapterConfig->Get(L"IPAddress", 0, &vtIp, 0, 0);
+ if (SUCCEEDED(hr))
+ {
+ if (vtIp.vt == (VT_ARRAY | VT_BSTR))
+ {
+ VARIANT vtMask;
+ VariantInit(&vtMask);
+ hr = pAdapterConfig->Get(L"IPSubnet", 0, &vtMask, 0, 0);
+ if (SUCCEEDED(hr))
+ {
+ if (vtMask.vt == (VT_ARRAY | VT_BSTR))
+ {
+ SAFEARRAY * pIpArray = vtIp.parray;
+ SAFEARRAY * pMaskArray = vtMask.parray;
+ if (pIpArray && pMaskArray)
+ {
+ BSTR pCurIp;
+ BSTR pCurMask;
+ for (LONG i = 0;
+ SafeArrayGetElement(pIpArray, &i, (PVOID)&pCurIp) == S_OK
+ && SafeArrayGetElement(pMaskArray, &i, (PVOID)&pCurMask) == S_OK;
+ i++)
+ {
+ bstr_t ip(pCurIp);
+
+ ULONG Ipv4 = inet_addr((char*)(ip));
+ if (Ipv4 != INADDR_NONE)
+ {
+ *pIpv4 = Ipv4;
+ bstr_t mask(pCurMask);
+ *pMaskv4 = inet_addr((char*)(mask));
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ *pIpv4 = 0;
+ *pMaskv4 = 0;
+ }
+
+ VariantClear(&vtMask);
+ }
+ }
+ else
+ {
+ *pIpv4 = 0;
+ *pMaskv4 = 0;
+ }
+
+ VariantClear(&vtIp);
+ }
+
+ return hr;
+}
+
+
+static HRESULT netIfWinHasIpSettings(IWbemClassObject * pAdapterConfig, SAFEARRAY * pCheckIp, SAFEARRAY * pCheckMask, bool *pFound)
+{
+ VARIANT vtIp;
+ HRESULT hr;
+ VariantInit(&vtIp);
+
+ *pFound = false;
+
+ hr = pAdapterConfig->Get(L"IPAddress", 0, &vtIp, 0, 0);
+ if (SUCCEEDED(hr))
+ {
+ VARIANT vtMask;
+ VariantInit(&vtMask);
+ hr = pAdapterConfig->Get(L"IPSubnet", 0, &vtMask, 0, 0);
+ if (SUCCEEDED(hr))
+ {
+ SAFEARRAY * pIpArray = vtIp.parray;
+ SAFEARRAY * pMaskArray = vtMask.parray;
+ if (pIpArray && pMaskArray)
+ {
+ BSTR pIp, pMask;
+ for (LONG k = 0;
+ SafeArrayGetElement(pCheckIp, &k, (PVOID)&pIp) == S_OK
+ && SafeArrayGetElement(pCheckMask, &k, (PVOID)&pMask) == S_OK;
+ k++)
+ {
+ BSTR pCurIp;
+ BSTR pCurMask;
+ for (LONG i = 0;
+ SafeArrayGetElement(pIpArray, &i, (PVOID)&pCurIp) == S_OK
+ && SafeArrayGetElement(pMaskArray, &i, (PVOID)&pCurMask) == S_OK;
+ i++)
+ {
+ if (!wcsicmp(pCurIp, pIp))
+ {
+ if (!wcsicmp(pCurMask, pMask))
+ *pFound = true;
+ break;
+ }
+ }
+ }
+ }
+
+
+ VariantClear(&vtMask);
+ }
+
+ VariantClear(&vtIp);
+ }
+
+ return hr;
+}
+
+static HRESULT netIfWinWaitIpSettings(IWbemServices *pSvc, const GUID * pGuid, SAFEARRAY * pCheckIp, SAFEARRAY * pCheckMask, ULONG sec2Wait, bool *pFound)
+{
+ /* on Vista we need to wait for the address to get applied */
+ /* wait for the address to appear in the list */
+ HRESULT hr = S_OK;
+ ULONG i;
+ *pFound = false;
+ ComPtr <IWbemClassObject> pAdapterConfig;
+ for (i = 0;
+ (hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam())) == S_OK
+ && (hr = netIfWinHasIpSettings(pAdapterConfig, pCheckIp, pCheckMask, pFound)) == S_OK
+ && !(*pFound)
+ && i < sec2Wait/6;
+ i++)
+ {
+ Sleep(6000);
+ }
+
+ return hr;
+}
+
+static HRESULT netIfWinCreateIWbemServices(IWbemServices ** ppSvc)
+{
+ IWbemLocator *pLoc = NULL;
+ HRESULT hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
+ if (SUCCEEDED(hr))
+ {
+ IWbemServices *pSvc = NULL;
+ hr = pLoc->ConnectServer(bstr_t(L"ROOT\\CIMV2"), /* [in] const BSTR strNetworkResource */
+ NULL, /* [in] const BSTR strUser */
+ NULL, /* [in] const BSTR strPassword */
+ 0, /* [in] const BSTR strLocale */
+ NULL, /* [in] LONG lSecurityFlags */
+ 0, /* [in] const BSTR strAuthority */
+ 0, /* [in] IWbemContext* pCtx */
+ &pSvc /* [out] IWbemServices** ppNamespace */);
+ if (SUCCEEDED(hr))
+ {
+ hr = CoSetProxyBlanket(pSvc, /* IUnknown * pProxy */
+ RPC_C_AUTHN_WINNT, /* DWORD dwAuthnSvc */
+ RPC_C_AUTHZ_NONE, /* DWORD dwAuthzSvc */
+ NULL, /* WCHAR * pServerPrincName */
+ RPC_C_AUTHN_LEVEL_CALL, /* DWORD dwAuthnLevel */
+ RPC_C_IMP_LEVEL_IMPERSONATE, /* DWORD dwImpLevel */
+ NULL, /* RPC_AUTH_IDENTITY_HANDLE pAuthInfo */
+ EOAC_NONE /* DWORD dwCapabilities */
+ );
+ if (SUCCEEDED(hr))
+ {
+ *ppSvc = pSvc;
+ /* do not need it any more */
+ pLoc->Release();
+ return hr;
+ }
+ else
+ LogFlow(("CoSetProxyBlanket failed, hr (0x%x)\n", hr));
+
+ pSvc->Release();
+ }
+ else
+ LogFlow(("ConnectServer failed, hr (0x%x)\n", hr));
+ pLoc->Release();
+ }
+ else
+ LogFlow(("CoCreateInstance failed, hr (0x%x)\n", hr));
+ return hr;
+}
+
+static HRESULT netIfWinAdapterConfigPath(IWbemClassObject *pObj, BSTR * pStr)
+{
+ VARIANT index;
+ HRESULT hr = pObj->Get(L"Index", 0, &index, 0, 0);
+ if (SUCCEEDED(hr))
+ {
+ WCHAR strIndex[8];
+ swprintf(strIndex, L"%u", index.uintVal);
+ *pStr = (bstr_t(L"Win32_NetworkAdapterConfiguration.Index='") + strIndex + "'").copy();
+ }
+ else
+ LogFlow(("Get failed, hr (0x%x)\n", hr));
+ return hr;
+}
+
+static HRESULT netIfExecMethod(IWbemServices * pSvc, IWbemClassObject *pClass, BSTR ObjPath,
+ BSTR MethodName, LPWSTR *pArgNames, LPVARIANT *pArgs, UINT cArgs,
+ IWbemClassObject** ppOutParams
+ )
+{
+ HRESULT hr = S_OK;
+ ComPtr<IWbemClassObject> pInParamsDefinition;
+ ComPtr<IWbemClassObject> pClassInstance;
+
+ if (cArgs)
+ {
+ hr = pClass->GetMethod(MethodName, 0, pInParamsDefinition.asOutParam(), NULL);
+ if (SUCCEEDED(hr))
+ {
+ hr = pInParamsDefinition->SpawnInstance(0, pClassInstance.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ for (UINT i = 0; i < cArgs; i++)
+ {
+ hr = pClassInstance->Put(pArgNames[i], 0,
+ pArgs[i], 0);
+ if (FAILED(hr))
+ break;
+ }
+ }
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ IWbemClassObject* pOutParams = NULL;
+ hr = pSvc->ExecMethod(ObjPath, MethodName, 0, NULL, pClassInstance, &pOutParams, NULL);
+ if (SUCCEEDED(hr))
+ {
+ *ppOutParams = pOutParams;
+ }
+ }
+
+ return hr;
+}
+
+static HRESULT netIfWinCreateIpArray(SAFEARRAY **ppArray, in_addr* aIp, UINT cIp)
+{
+ HRESULT hr;
+ SAFEARRAY * pIpArray = SafeArrayCreateVector(VT_BSTR, 0, cIp);
+ if (pIpArray)
+ {
+ for (UINT i = 0; i < cIp; i++)
+ {
+ char* addr = inet_ntoa(aIp[i]);
+ BSTR val = bstr_t(addr).copy();
+ long aIndex[1];
+ aIndex[0] = i;
+ hr = SafeArrayPutElement(pIpArray, aIndex, val);
+ if (FAILED(hr))
+ {
+ SysFreeString(val);
+ SafeArrayDestroy(pIpArray);
+ break;
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ *ppArray = pIpArray;
+ }
+ }
+ else
+ hr = HRESULT_FROM_WIN32(GetLastError());
+
+ return hr;
+}
+
+static HRESULT netIfWinCreateIpArrayV4V6(SAFEARRAY **ppArray, BSTR Ip)
+{
+ HRESULT hr;
+ SAFEARRAY *pIpArray = SafeArrayCreateVector(VT_BSTR, 0, 1);
+ if (pIpArray)
+ {
+ BSTR val = bstr_t(Ip, false).copy();
+ long aIndex[1];
+ aIndex[0] = 0;
+ hr = SafeArrayPutElement(pIpArray, aIndex, val);
+ if (FAILED(hr))
+ {
+ SysFreeString(val);
+ SafeArrayDestroy(pIpArray);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ *ppArray = pIpArray;
+ }
+ }
+ else
+ hr = HRESULT_FROM_WIN32(GetLastError());
+
+ return hr;
+}
+
+
+static HRESULT netIfWinCreateIpArrayVariantV4(VARIANT * pIpAddresses, in_addr* aIp, UINT cIp)
+{
+ HRESULT hr;
+ VariantInit(pIpAddresses);
+ pIpAddresses->vt = VT_ARRAY | VT_BSTR;
+ SAFEARRAY *pIpArray;
+ hr = netIfWinCreateIpArray(&pIpArray, aIp, cIp);
+ if (SUCCEEDED(hr))
+ {
+ pIpAddresses->parray = pIpArray;
+ }
+ return hr;
+}
+
+static HRESULT netIfWinCreateIpArrayVariantV4V6(VARIANT * pIpAddresses, BSTR Ip)
+{
+ HRESULT hr;
+ VariantInit(pIpAddresses);
+ pIpAddresses->vt = VT_ARRAY | VT_BSTR;
+ SAFEARRAY *pIpArray;
+ hr = netIfWinCreateIpArrayV4V6(&pIpArray, Ip);
+ if (SUCCEEDED(hr))
+ {
+ pIpAddresses->parray = pIpArray;
+ }
+ return hr;
+}
+
+static HRESULT netIfWinEnableStatic(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, VARIANT * pIp, VARIANT * pMask)
+{
+ ComPtr<IWbemClassObject> pClass;
+ BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
+ HRESULT hr;
+ if (ClassName)
+ {
+ hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
+ if (SUCCEEDED(hr))
+ {
+ LPWSTR argNames[] = {L"IPAddress", L"SubnetMask"};
+ LPVARIANT args[] = {pIp, pMask};
+ ComPtr<IWbemClassObject> pOutParams;
+
+ hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"EnableStatic"), argNames, args, 2, pOutParams.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ VARIANT varReturnValue;
+ hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
+ &varReturnValue, NULL, 0);
+ Assert(SUCCEEDED(hr));
+ if (SUCCEEDED(hr))
+ {
+// Assert(varReturnValue.vt == VT_UINT);
+ int winEr = varReturnValue.uintVal;
+ switch (winEr)
+ {
+ case 0:
+ {
+ hr = S_OK;
+// bool bFound;
+// HRESULT tmpHr = netIfWinWaitIpSettings(pSvc, pGuid, pIp->parray, pMask->parray, 180, &bFound);
+ }
+ break;
+ default:
+ hr = HRESULT_FROM_WIN32( winEr );
+ break;
+ }
+ }
+ }
+ }
+ SysFreeString(ClassName);
+ }
+ else
+ hr = HRESULT_FROM_WIN32(GetLastError());
+
+ return hr;
+}
+
+
+static HRESULT netIfWinEnableStaticV4(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, in_addr* aIp, in_addr * aMask, UINT cIp)
+{
+ VARIANT ipAddresses;
+ HRESULT hr = netIfWinCreateIpArrayVariantV4(&ipAddresses, aIp, cIp);
+ if (SUCCEEDED(hr))
+ {
+ VARIANT ipMasks;
+ hr = netIfWinCreateIpArrayVariantV4(&ipMasks, aMask, cIp);
+ if (SUCCEEDED(hr))
+ {
+ hr = netIfWinEnableStatic(pSvc, pGuid, ObjPath, &ipAddresses, &ipMasks);
+ VariantClear(&ipMasks);
+ }
+ VariantClear(&ipAddresses);
+ }
+ return hr;
+}
+
+static HRESULT netIfWinEnableStaticV4V6(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, BSTR Ip, BSTR Mask)
+{
+ VARIANT ipAddresses;
+ HRESULT hr = netIfWinCreateIpArrayVariantV4V6(&ipAddresses, Ip);
+ if (SUCCEEDED(hr))
+ {
+ VARIANT ipMasks;
+ hr = netIfWinCreateIpArrayVariantV4V6(&ipMasks, Mask);
+ if (SUCCEEDED(hr))
+ {
+ hr = netIfWinEnableStatic(pSvc, pGuid, ObjPath, &ipAddresses, &ipMasks);
+ VariantClear(&ipMasks);
+ }
+ VariantClear(&ipAddresses);
+ }
+ return hr;
+}
+
+/* win API allows to set gw metrics as well, we are not setting them */
+static HRESULT netIfWinSetGateways(IWbemServices * pSvc, BSTR ObjPath, VARIANT * pGw)
+{
+ ComPtr<IWbemClassObject> pClass;
+ BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
+ HRESULT hr;
+ if (ClassName)
+ {
+ hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
+ if (SUCCEEDED(hr))
+ {
+ LPWSTR argNames[] = {L"DefaultIPGateway"};
+ LPVARIANT args[] = {pGw};
+ ComPtr<IWbemClassObject> pOutParams;
+
+ hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"SetGateways"), argNames, args, 1, pOutParams.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ VARIANT varReturnValue;
+ hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0);
+ Assert(SUCCEEDED(hr));
+ if (SUCCEEDED(hr))
+ {
+// Assert(varReturnValue.vt == VT_UINT);
+ int winEr = varReturnValue.uintVal;
+ switch (winEr)
+ {
+ case 0:
+ hr = S_OK;
+ break;
+ default:
+ hr = HRESULT_FROM_WIN32( winEr );
+ break;
+ }
+ }
+ }
+ }
+ SysFreeString(ClassName);
+ }
+ else
+ hr = HRESULT_FROM_WIN32(GetLastError());
+
+ return hr;
+}
+
+/* win API allows to set gw metrics as well, we are not setting them */
+static HRESULT netIfWinSetGatewaysV4(IWbemServices * pSvc, BSTR ObjPath, in_addr* aGw, UINT cGw)
+{
+ VARIANT gwais;
+ HRESULT hr = netIfWinCreateIpArrayVariantV4(&gwais, aGw, cGw);
+ if (SUCCEEDED(hr))
+ {
+ netIfWinSetGateways(pSvc, ObjPath, &gwais);
+ VariantClear(&gwais);
+ }
+ return hr;
+}
+
+/* win API allows to set gw metrics as well, we are not setting them */
+static HRESULT netIfWinSetGatewaysV4V6(IWbemServices * pSvc, BSTR ObjPath, BSTR Gw)
+{
+ VARIANT vGw;
+ HRESULT hr = netIfWinCreateIpArrayVariantV4V6(&vGw, Gw);
+ if (SUCCEEDED(hr))
+ {
+ netIfWinSetGateways(pSvc, ObjPath, &vGw);
+ VariantClear(&vGw);
+ }
+ return hr;
+}
+
+static HRESULT netIfWinEnableDHCP(IWbemServices * pSvc, BSTR ObjPath)
+{
+ ComPtr<IWbemClassObject> pClass;
+ BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
+ HRESULT hr;
+ if (ClassName)
+ {
+ hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
+ if (SUCCEEDED(hr))
+ {
+ ComPtr<IWbemClassObject> pOutParams;
+
+ hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"EnableDHCP"), NULL, NULL, 0, pOutParams.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ VARIANT varReturnValue;
+ hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
+ &varReturnValue, NULL, 0);
+ Assert(SUCCEEDED(hr));
+ if (SUCCEEDED(hr))
+ {
+// Assert(varReturnValue.vt == VT_UINT);
+ int winEr = varReturnValue.uintVal;
+ switch (winEr)
+ {
+ case 0:
+ hr = S_OK;
+ break;
+ default:
+ hr = HRESULT_FROM_WIN32( winEr );
+ break;
+ }
+ }
+ }
+ }
+ SysFreeString(ClassName);
+ }
+ else
+ hr = HRESULT_FROM_WIN32(GetLastError());
+
+ return hr;
+}
+
+static HRESULT netIfWinDhcpRediscover(IWbemServices * pSvc, BSTR ObjPath)
+{
+ ComPtr<IWbemClassObject> pClass;
+ BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
+ HRESULT hr;
+ if (ClassName)
+ {
+ hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
+ if (SUCCEEDED(hr))
+ {
+ ComPtr<IWbemClassObject> pOutParams;
+
+ hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"ReleaseDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ VARIANT varReturnValue;
+ hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0);
+ Assert(SUCCEEDED(hr));
+ if (SUCCEEDED(hr))
+ {
+// Assert(varReturnValue.vt == VT_UINT);
+ int winEr = varReturnValue.uintVal;
+ if (winEr == 0)
+ {
+ hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"RenewDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ VARIANT varReturnValue;
+ hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0);
+ Assert(SUCCEEDED(hr));
+ if (SUCCEEDED(hr))
+ {
+ // Assert(varReturnValue.vt == VT_UINT);
+ int winEr = varReturnValue.uintVal;
+ if (winEr == 0)
+ hr = S_OK;
+ else
+ hr = HRESULT_FROM_WIN32( winEr );
+ }
+ }
+ }
+ else
+ hr = HRESULT_FROM_WIN32( winEr );
+ }
+ }
+ }
+ SysFreeString(ClassName);
+ }
+ else
+ hr = HRESULT_FROM_WIN32(GetLastError());
+
+ return hr;
+}
+
+static HRESULT vboxNetCfgWinIsDhcpEnabled(IWbemClassObject * pAdapterConfig, BOOL *pEnabled)
+{
+ VARIANT vtEnabled;
+ HRESULT hr = pAdapterConfig->Get(L"DHCPEnabled", 0, &vtEnabled, 0, 0);
+ if (SUCCEEDED(hr))
+ *pEnabled = vtEnabled.boolVal;
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGetAdapterSettings(IN const GUID * pGuid, OUT PADAPTER_SETTINGS pSettings)
+{
+ HRESULT hr;
+ ComPtr <IWbemServices> pSvc;
+ hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ ComPtr <IWbemClassObject> pAdapterConfig;
+ hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ hr = vboxNetCfgWinIsDhcpEnabled(pAdapterConfig, &pSettings->bDhcp);
+ if (SUCCEEDED(hr))
+ hr = netIfWinGetIpSettings(pAdapterConfig, &pSettings->ip, &pSettings->mask);
+ }
+ }
+
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinIsDhcpEnabled(const GUID * pGuid, BOOL *pEnabled)
+{
+ HRESULT hr;
+ ComPtr <IWbemServices> pSvc;
+ hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ ComPtr <IWbemClassObject> pAdapterConfig;
+ hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ VARIANT vtEnabled;
+ hr = pAdapterConfig->Get(L"DHCPEnabled", 0, &vtEnabled, 0, 0);
+ if (SUCCEEDED(hr))
+ *pEnabled = vtEnabled.boolVal;
+ }
+ }
+
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnableStaticIpConfig(IN const GUID *pGuid, IN ULONG ip, IN ULONG mask)
+{
+ HRESULT hr;
+ ComPtr <IWbemServices> pSvc;
+ hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ ComPtr <IWbemClassObject> pAdapterConfig;
+ hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ BOOL bIsHostOnly;
+ hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly);
+ if (SUCCEEDED(hr))
+ {
+ if (bIsHostOnly)
+ {
+ in_addr aIp[1];
+ in_addr aMask[1];
+ aIp[0].S_un.S_addr = ip;
+ aMask[0].S_un.S_addr = mask;
+
+ BSTR ObjPath;
+ hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
+ if (SUCCEEDED(hr))
+ {
+ hr = netIfWinEnableStaticV4(pSvc, pGuid, ObjPath, aIp, aMask, ip != 0 ? 1 : 0);
+ if (SUCCEEDED(hr))
+ {
+#if 0
+ in_addr aGw[1];
+ aGw[0].S_un.S_addr = gw;
+ hr = netIfWinSetGatewaysV4(pSvc, ObjPath, aGw, 1);
+ if (SUCCEEDED(hr))
+#endif
+ {
+ }
+ }
+ SysFreeString(ObjPath);
+ }
+ }
+ else
+ {
+ hr = E_FAIL;
+ }
+ }
+ }
+ }
+
+ return hr;
+}
+
+#if 0
+static HRESULT netIfEnableStaticIpConfigV6(const GUID *pGuid, IN_BSTR aIPV6Address, IN_BSTR aIPV6Mask, IN_BSTR aIPV6DefaultGateway)
+{
+ HRESULT hr;
+ ComPtr <IWbemServices> pSvc;
+ hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ ComPtr <IWbemClassObject> pAdapterConfig;
+ hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ BSTR ObjPath;
+ hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
+ if (SUCCEEDED(hr))
+ {
+ hr = netIfWinEnableStaticV4V6(pSvc, pAdapterConfig, ObjPath, aIPV6Address, aIPV6Mask);
+ if (SUCCEEDED(hr))
+ {
+ if (aIPV6DefaultGateway)
+ {
+ hr = netIfWinSetGatewaysV4V6(pSvc, ObjPath, aIPV6DefaultGateway);
+ }
+ if (SUCCEEDED(hr))
+ {
+// hr = netIfWinUpdateConfig(pIf);
+ }
+ }
+ SysFreeString(ObjPath);
+ }
+ }
+ }
+
+ return SUCCEEDED(hr) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
+}
+
+static HRESULT netIfEnableStaticIpConfigV6(const GUID *pGuid, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
+{
+ RTNETADDRIPV6 Mask;
+ int rc = prefixLength2IPv6Address(aIPV6MaskPrefixLength, &Mask);
+ if (RT_SUCCESS(rc))
+ {
+ Bstr maskStr = composeIPv6Address(&Mask);
+ rc = netIfEnableStaticIpConfigV6(pGuid, aIPV6Address, maskStr, NULL);
+ }
+ return rc;
+}
+#endif
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnableDynamicIpConfig(IN const GUID *pGuid)
+{
+ HRESULT hr;
+ ComPtr <IWbemServices> pSvc;
+ hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ ComPtr <IWbemClassObject> pAdapterConfig;
+ hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ BOOL bIsHostOnly;
+ hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly);
+ if (SUCCEEDED(hr))
+ {
+ if (bIsHostOnly)
+ {
+ BSTR ObjPath;
+ hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
+ if (SUCCEEDED(hr))
+ {
+ hr = netIfWinEnableDHCP(pSvc, ObjPath);
+ if (SUCCEEDED(hr))
+ {
+// hr = netIfWinUpdateConfig(pIf);
+ }
+ SysFreeString(ObjPath);
+ }
+ }
+ else
+ {
+ hr = E_FAIL;
+ }
+ }
+ }
+ }
+
+
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinDhcpRediscover(IN const GUID *pGuid)
+{
+ HRESULT hr;
+ ComPtr <IWbemServices> pSvc;
+ hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ ComPtr <IWbemClassObject> pAdapterConfig;
+ hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam());
+ if (SUCCEEDED(hr))
+ {
+ BOOL bIsHostOnly;
+ hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly);
+ if (SUCCEEDED(hr))
+ {
+ if (bIsHostOnly)
+ {
+ BSTR ObjPath;
+ hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
+ if (SUCCEEDED(hr))
+ {
+ hr = netIfWinDhcpRediscover(pSvc, ObjPath);
+ if (SUCCEEDED(hr))
+ {
+// hr = netIfWinUpdateConfig(pIf);
+ }
+ SysFreeString(ObjPath);
+ }
+ }
+ else
+ {
+ hr = E_FAIL;
+ }
+ }
+ }
+ }
+
+
+ return hr;
+}
+
+typedef bool (*PFNVBOXNETCFG_IPSETTINGS_CALLBACK) (ULONG ip, ULONG mask, PVOID pContext);
+
+static void vboxNetCfgWinEnumIpConfig(PIP_ADAPTER_ADDRESSES pAddresses, PFNVBOXNETCFG_IPSETTINGS_CALLBACK pfnCallback, PVOID pContext)
+{
+ PIP_ADAPTER_ADDRESSES pAdapter;
+ for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
+ {
+ PIP_ADAPTER_UNICAST_ADDRESS pAddr = pAdapter->FirstUnicastAddress;
+ PIP_ADAPTER_PREFIX pPrefix = pAdapter->FirstPrefix;
+
+ if (pAddr && pPrefix)
+ {
+ do
+ {
+ bool fIPFound, fMaskFound;
+ fIPFound = fMaskFound = false;
+ ULONG ip, mask;
+ for (; pAddr && !fIPFound; pAddr = pAddr->Next)
+ {
+ switch (pAddr->Address.lpSockaddr->sa_family)
+ {
+ case AF_INET:
+ fIPFound = true;
+ memcpy(&ip,
+ &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
+ sizeof(ip));
+ break;
+// case AF_INET6:
+// break;
+ }
+ }
+
+ for (; pPrefix && !fMaskFound; pPrefix = pPrefix->Next)
+ {
+ switch (pPrefix->Address.lpSockaddr->sa_family)
+ {
+ case AF_INET:
+ if (!pPrefix->PrefixLength || pPrefix->PrefixLength > 31) /* in case the ip helper API is queried while NetCfg write lock is held */
+ break; /* the address values can contain illegal values */
+ fMaskFound = true;
+ mask = (~(((ULONG)~0) >> pPrefix->PrefixLength));
+ mask = htonl(mask);
+ break;
+// case AF_INET6:
+// break;
+ }
+ }
+
+ if (!fIPFound || !fMaskFound)
+ break;
+
+ if (!pfnCallback(ip, mask, pContext))
+ return;
+ } while (true);
+ }
+ }
+}
+
+typedef struct _IPPROBE_CONTEXT
+{
+ ULONG Prefix;
+ bool bConflict;
+}IPPROBE_CONTEXT, *PIPPROBE_CONTEXT;
+
+#define IPPROBE_INIT(_pContext, _addr) \
+ ((_pContext)->bConflict = false, \
+ (_pContext)->Prefix = _addr)
+
+#define IPPROBE_INIT_STR(_pContext, _straddr) \
+ IPROBE_INIT(_pContext, inet_addr(_straddr))
+
+static bool vboxNetCfgWinIpProbeCallback (ULONG ip, ULONG mask, PVOID pContext)
+{
+ PIPPROBE_CONTEXT pProbe = (PIPPROBE_CONTEXT)pContext;
+
+ if ((ip & mask) == (pProbe->Prefix & mask))
+ {
+ pProbe->bConflict = true;
+ return false;
+ }
+
+ return true;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(OUT PULONG pNetIp, OUT PULONG pNetMask)
+{
+ DWORD dwRc;
+ HRESULT hr = S_OK;
+ /*
+ * Most of the hosts probably have less than 10 adapters,
+ * so we'll mostly succeed from the first attempt.
+ */
+ ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
+ PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)malloc(uBufLen);
+ if (!pAddresses)
+ return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
+ dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
+ if (dwRc == ERROR_BUFFER_OVERFLOW)
+ {
+ /* Impressive! More than 10 adapters! Get more memory and try again. */
+ free(pAddresses);
+ pAddresses = (PIP_ADAPTER_ADDRESSES)malloc(uBufLen);
+ if (!pAddresses)
+ return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
+ dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
+ }
+ if (dwRc == NO_ERROR)
+ {
+ IPPROBE_CONTEXT Context;
+ const ULONG ip192168 = inet_addr("192.168.0.0");
+ srand(GetTickCount());
+
+ *pNetIp = 0;
+ *pNetMask = 0;
+
+ for (int i = 0; i < 255; i++)
+ {
+ ULONG ipProbe = rand()*255/RAND_MAX;
+ ipProbe = ip192168 | (ipProbe << 16);
+ IPPROBE_INIT(&Context, ipProbe);
+ vboxNetCfgWinEnumIpConfig(pAddresses, vboxNetCfgWinIpProbeCallback, &Context);
+ if (!Context.bConflict)
+ {
+ *pNetIp = ipProbe;
+ *pNetMask = inet_addr("255.255.255.0");
+ break;
+ }
+ }
+ if (*pNetIp == 0)
+ dwRc = ERROR_DHCP_ADDRESS_CONFLICT;
+ }
+ else
+ LogFlow(("GetAdaptersAddresses err (%d)\n", dwRc));
+
+ if (pAddresses)
+ free(pAddresses);
+
+ if (dwRc != NO_ERROR)
+ {
+ hr = HRESULT_FROM_WIN32(dwRc);
+ }
+
+ return hr;
+}
+
+/*
+ * convenience functions to perform netflt/adp manipulations
+ */
+#define VBOXNETCFGWIN_NETFLT_ID L"sun_VBoxNetFlt"
+#define VBOXNETCFGWIN_NETFLT_MP_ID L"sun_VBoxNetFltmp"
+
+static HRESULT vboxNetCfgWinNetFltUninstall(IN INetCfg *pNc, DWORD InfRmFlags)
+{
+ INetCfgComponent * pNcc = NULL;
+ HRESULT hr = pNc->FindComponent(VBOXNETCFGWIN_NETFLT_ID, &pNcc);
+ if (hr == S_OK)
+ {
+ Log("NetFlt is installed currently, uninstalling ...\n");
+
+ hr = VBoxNetCfgWinUninstallComponent(pNc, pNcc);
+
+ pNcc->Release();
+ }
+ else if (hr == S_FALSE)
+ {
+ Log("NetFlt is not installed currently\n");
+ hr = S_OK;
+ }
+ else
+ {
+ LogFlow(("FindComponent failed, hr (0x%x)\n", hr));
+ hr = S_OK;
+ }
+
+ VBoxDrvCfgInfUninstallAllF(L"NetService", VBOXNETCFGWIN_NETFLT_ID, InfRmFlags);
+ VBoxDrvCfgInfUninstallAllF(L"Net", VBOXNETCFGWIN_NETFLT_MP_ID, InfRmFlags);
+
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetFltUninstall(IN INetCfg *pNc)
+{
+ return vboxNetCfgWinNetFltUninstall(pNc, 0);
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetFltInstall(IN INetCfg *pNc,
+ IN LPCWSTR * apInfFullPaths, IN UINT cInfFullPaths)
+{
+ HRESULT hr = vboxNetCfgWinNetFltUninstall(pNc, SUOI_FORCEDELETE);
+ if (SUCCEEDED(hr))
+ {
+ Log("NetFlt will be installed ...\n");
+ hr = VBoxNetCfgWinInstallInfAndComponent(pNc, VBOXNETCFGWIN_NETFLT_ID,
+ &GUID_DEVCLASS_NETSERVICE,
+ apInfFullPaths,
+ cInfFullPaths,
+ NULL);
+ }
+ return hr;
+}
+
+#define VBOX_CONNECTION_NAME L"VirtualBox Host-Only Network"
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostonlyConnectionName(PCWSTR DevName, WCHAR *pBuf, PULONG pcbBuf)
+{
+ const WCHAR * pSuffix = wcsrchr( DevName, L'#' );
+ ULONG cbSize = sizeof(VBOX_CONNECTION_NAME);
+ ULONG cbSufSize = 0;
+
+ if (pSuffix)
+ {
+ cbSize += (ULONG)wcslen(pSuffix) * 2;
+ cbSize += 2; /* for space */
+ }
+
+ if (*pcbBuf < cbSize)
+ {
+ *pcbBuf = cbSize;
+ return E_FAIL;
+ }
+
+ wcscpy(pBuf, VBOX_CONNECTION_NAME);
+ if (pSuffix)
+ {
+ wcscat(pBuf, L" ");
+ wcscat(pBuf, pSuffix);
+ }
+
+ return S_OK;
+}
+
+static BOOL vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority(IN INetCfg *pNc, IN INetCfgComponent *pNcc, PVOID pContext)
+{
+ INetCfgComponentBindings *pNetCfgBindings;
+ GUID *pGuid = (GUID*)pContext;
+
+ /* Get component's binding. */
+ HRESULT hr = pNcc->QueryInterface(IID_INetCfgComponentBindings, (PVOID*)&pNetCfgBindings);
+ if (SUCCEEDED(hr))
+ {
+ /* Get binding path enumerator reference. */
+ IEnumNetCfgBindingPath *pEnumNetCfgBindPath;
+ hr = pNetCfgBindings->EnumBindingPaths(EBP_BELOW, &pEnumNetCfgBindPath);
+ if (SUCCEEDED(hr))
+ {
+ bool bFoundIface = false;
+ hr = pEnumNetCfgBindPath->Reset();
+ do
+ {
+ INetCfgBindingPath *pNetCfgBindPath;
+ hr = pEnumNetCfgBindPath->Next(1, &pNetCfgBindPath, NULL);
+ if (hr == S_OK)
+ {
+ IEnumNetCfgBindingInterface *pEnumNetCfgBindIface;
+ hr = pNetCfgBindPath->EnumBindingInterfaces(&pEnumNetCfgBindIface);
+ if (hr == S_OK)
+ {
+ pEnumNetCfgBindIface->Reset();
+ do
+ {
+ INetCfgBindingInterface *pNetCfgBindIfce;
+ hr = pEnumNetCfgBindIface->Next(1, &pNetCfgBindIfce, NULL);
+ if (hr == S_OK)
+ {
+ INetCfgComponent *pNetCfgCompo;
+ hr = pNetCfgBindIfce->GetLowerComponent(&pNetCfgCompo);
+ if (hr == S_OK)
+ {
+ ULONG uComponentStatus;
+ hr = pNetCfgCompo->GetDeviceStatus(&uComponentStatus);
+ if (hr == S_OK)
+ {
+ GUID guid;
+ hr = pNetCfgCompo->GetInstanceGuid(&guid);
+ if ( hr == S_OK
+ && guid == *pGuid)
+ {
+ hr = pNetCfgBindings->MoveAfter(pNetCfgBindPath, NULL);
+ if (FAILED(hr))
+ LogFlow(("Unable to move interface, hr (0x%x)\n", hr));
+ bFoundIface = true;
+ }
+ }
+ pNetCfgCompo->Release();
+ }
+ else
+ LogFlow(("GetLowerComponent failed, hr (0x%x)\n", hr));
+ pNetCfgBindIfce->Release();
+ }
+ else
+ {
+ if (hr == S_FALSE) /* No more binding interfaces? */
+ hr = S_OK;
+ else
+ LogFlow(("Next binding interface failed, hr (0x%x)\n", hr));
+ break;
+ }
+ } while (!bFoundIface);
+ pEnumNetCfgBindIface->Release();
+ }
+ else
+ LogFlow(("EnumBindingInterfaces failed, hr (0x%x)\n", hr));
+ pNetCfgBindPath->Release();
+ }
+ else
+ {
+ if (hr = S_FALSE) /* No more binding paths? */
+ hr = S_OK;
+ else
+ LogFlow(("Next bind path failed, hr (0x%x)\n", hr));
+ break;
+ }
+ } while (!bFoundIface);
+ pEnumNetCfgBindPath->Release();
+ }
+ else
+ LogFlow(("EnumBindingPaths failed, hr (0x%x)\n", hr));
+ pNetCfgBindings->Release();
+ }
+ else
+ LogFlow(("QueryInterface for IID_INetCfgComponentBindings failed, hr (0x%x)\n", hr));
+ return TRUE;
+}
+
+static UINT WINAPI vboxNetCfgWinPspFileCallback(
+ PVOID Context,
+ UINT Notification,
+ UINT_PTR Param1,
+ UINT_PTR Param2
+ )
+{
+ switch (Notification)
+ {
+ case SPFILENOTIFY_TARGETNEWER:
+ case SPFILENOTIFY_TARGETEXISTS:
+ return TRUE;
+ }
+ return SetupDefaultQueueCallback(Context, Notification, Param1, Param2);
+}
+
+/* The original source of the VBoxNetAdp adapter creation/destruction code has the following copyright */
+/*
+ Copyright 2004 by the Massachusetts Institute of Technology
+
+ All rights reserved.
+
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appear in all copies and that
+ both that copyright notice and this permission notice appear in
+ supporting documentation, and that the name of the Massachusetts
+ Institute of Technology (M.I.T.) not be used in advertising or publicity
+ pertaining to distribution of the software without specific, written
+ prior permission.
+
+ M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ SOFTWARE.
+*/
+
+
+#define NETSHELL_LIBRARY _T("netshell.dll")
+
+/**
+ * Use the IShellFolder API to rename the connection.
+ */
+static HRESULT rename_shellfolder (PCWSTR wGuid, PCWSTR wNewName)
+{
+ /* This is the GUID for the network connections folder. It is constant.
+ * {7007ACC7-3202-11D1-AAD2-00805FC1270E} */
+ const GUID CLSID_NetworkConnections = {
+ 0x7007ACC7, 0x3202, 0x11D1, {
+ 0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E
+ }
+ };
+
+ LPITEMIDLIST pidl = NULL;
+ IShellFolder *pShellFolder = NULL;
+ HRESULT hr;
+
+ /* Build the display name in the form "::{GUID}". */
+ if (wcslen (wGuid) >= MAX_PATH)
+ return E_INVALIDARG;
+ WCHAR szAdapterGuid[MAX_PATH + 2] = {0};
+ swprintf (szAdapterGuid, L"::%ls", wGuid);
+
+ /* Create an instance of the network connections folder. */
+ hr = CoCreateInstance (CLSID_NetworkConnections, NULL,
+ CLSCTX_INPROC_SERVER, IID_IShellFolder,
+ reinterpret_cast <LPVOID *> (&pShellFolder));
+ /* Parse the display name. */
+ if (SUCCEEDED (hr))
+ {
+ hr = pShellFolder->ParseDisplayName (NULL, NULL, szAdapterGuid, NULL,
+ &pidl, NULL);
+ }
+ if (SUCCEEDED (hr))
+ {
+ hr = pShellFolder->SetNameOf (NULL, pidl, wNewName, SHGDN_NORMAL,
+ &pidl);
+ }
+
+ CoTaskMemFree (pidl);
+
+ if (pShellFolder)
+ pShellFolder->Release();
+
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRenameConnection (LPWSTR pGuid, PCWSTR NewName)
+{
+ typedef HRESULT (WINAPI *lpHrRenameConnection) (const GUID *, PCWSTR);
+ lpHrRenameConnection RenameConnectionFunc = NULL;
+ HRESULT status;
+
+ /* First try the IShellFolder interface, which was unimplemented
+ * for the network connections folder before XP. */
+ status = rename_shellfolder (pGuid, NewName);
+ if (status == E_NOTIMPL)
+ {
+/** @todo that code doesn't seem to work! */
+ /* The IShellFolder interface is not implemented on this platform.
+ * Try the (undocumented) HrRenameConnection API in the netshell
+ * library. */
+ CLSID clsid;
+ HINSTANCE hNetShell;
+ status = CLSIDFromString ((LPOLESTR) pGuid, &clsid);
+ if (FAILED(status))
+ return E_FAIL;
+ hNetShell = LoadLibrary (NETSHELL_LIBRARY);
+ if (hNetShell == NULL)
+ return E_FAIL;
+ RenameConnectionFunc =
+ (lpHrRenameConnection) GetProcAddress (hNetShell,
+ "HrRenameConnection");
+ if (RenameConnectionFunc == NULL)
+ {
+ FreeLibrary (hNetShell);
+ return E_FAIL;
+ }
+ status = RenameConnectionFunc (&clsid, NewName);
+ FreeLibrary (hNetShell);
+ }
+ if (FAILED (status))
+ return status;
+
+ return S_OK;
+}
+
+#define DRIVERHWID _T("sun_VBoxNetAdp")
+
+#define SetErrBreak(strAndArgs) \
+ if (1) { \
+ hrc = E_FAIL; \
+ Log strAndArgs; \
+ break; \
+ } else do {} while (0)
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRemoveHostOnlyNetworkInterface(IN const GUID *pGUID, OUT BSTR *pErrMsg)
+{
+ HRESULT hrc = S_OK;
+
+ do
+ {
+ TCHAR lszPnPInstanceId [512] = {0};
+
+ /* We have to find the device instance ID through a registry search */
+
+ HKEY hkeyNetwork = 0;
+ HKEY hkeyConnection = 0;
+
+ do
+ {
+ WCHAR strRegLocation [256];
+ WCHAR GuidString[50];
+
+ int length = StringFromGUID2(*pGUID, GuidString, sizeof(GuidString)/sizeof(GuidString[0]));
+ if (!length)
+ SetErrBreak(("Failed to create a Guid string"));
+
+ swprintf (strRegLocation,
+ L"SYSTEM\\CurrentControlSet\\Control\\Network\\"
+ L"{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s",
+ GuidString);
+
+ LONG status;
+ status = RegOpenKeyExW (HKEY_LOCAL_MACHINE, strRegLocation, 0,
+ KEY_READ, &hkeyNetwork);
+ if ((status != ERROR_SUCCESS) || !hkeyNetwork)
+ SetErrBreak (("Host interface network is not found in registry (%S) [1]",
+ strRegLocation));
+
+ status = RegOpenKeyExW (hkeyNetwork, L"Connection", 0,
+ KEY_READ, &hkeyConnection);
+ if ((status != ERROR_SUCCESS) || !hkeyConnection)
+ SetErrBreak (("Host interface network is not found in registry (%S) [2]",
+ strRegLocation));
+
+ DWORD len = sizeof (lszPnPInstanceId);
+ DWORD dwKeyType;
+ status = RegQueryValueExW (hkeyConnection, L"PnPInstanceID", NULL,
+ &dwKeyType, (LPBYTE) lszPnPInstanceId, &len);
+ if ((status != ERROR_SUCCESS) || (dwKeyType != REG_SZ))
+ SetErrBreak (("Host interface network is not found in registry (%S) [3]",
+ strRegLocation));
+ }
+ while (0);
+
+ if (hkeyConnection)
+ RegCloseKey (hkeyConnection);
+ if (hkeyNetwork)
+ RegCloseKey (hkeyNetwork);
+
+ if (FAILED (hrc))
+ break;
+
+ /*
+ * Now we are going to enumerate all network devices and
+ * wait until we encounter the right device instance ID
+ */
+
+ HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
+
+ do
+ {
+ BOOL ok;
+ DWORD ret = 0;
+ GUID netGuid;
+ SP_DEVINFO_DATA DeviceInfoData;
+ DWORD index = 0;
+ BOOL found = FALSE;
+ DWORD size = 0;
+
+ /* initialize the structure size */
+ DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
+
+ /* copy the net class GUID */
+ memcpy (&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET));
+
+ /* return a device info set contains all installed devices of the Net class */
+ hDeviceInfo = SetupDiGetClassDevs (&netGuid, NULL, NULL, DIGCF_PRESENT);
+
+ if (hDeviceInfo == INVALID_HANDLE_VALUE)
+ SetErrBreak (("SetupDiGetClassDevs failed (0x%08X)", GetLastError()));
+
+ /* enumerate the driver info list */
+ while (TRUE)
+ {
+ TCHAR *deviceHwid;
+
+ ok = SetupDiEnumDeviceInfo (hDeviceInfo, index, &DeviceInfoData);
+
+ if (!ok)
+ {
+ if (GetLastError() == ERROR_NO_MORE_ITEMS)
+ break;
+ else
+ {
+ index++;
+ continue;
+ }
+ }
+
+ /* try to get the hardware ID registry property */
+ ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
+ &DeviceInfoData,
+ SPDRP_HARDWAREID,
+ NULL,
+ NULL,
+ 0,
+ &size);
+ if (!ok)
+ {
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ index++;
+ continue;
+ }
+
+ deviceHwid = (TCHAR *) malloc (size);
+ ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
+ &DeviceInfoData,
+ SPDRP_HARDWAREID,
+ NULL,
+ (PBYTE)deviceHwid,
+ size,
+ NULL);
+ if (!ok)
+ {
+ free (deviceHwid);
+ deviceHwid = NULL;
+ index++;
+ continue;
+ }
+ }
+ else
+ {
+ /* something is wrong. This shouldn't have worked with a NULL buffer */
+ index++;
+ continue;
+ }
+
+ for (TCHAR *t = deviceHwid;
+ t && *t && t < &deviceHwid[size / sizeof(TCHAR)];
+ t += _tcslen (t) + 1)
+ {
+ if (!_tcsicmp (DRIVERHWID, t))
+ {
+ /* get the device instance ID */
+ TCHAR devID [MAX_DEVICE_ID_LEN];
+ if (CM_Get_Device_ID(DeviceInfoData.DevInst,
+ devID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS)
+ {
+ /* compare to what we determined before */
+ if (wcscmp(devID, lszPnPInstanceId) == 0)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ if (deviceHwid)
+ {
+ free (deviceHwid);
+ deviceHwid = NULL;
+ }
+
+ if (found)
+ break;
+
+ index++;
+ }
+
+ if (found == FALSE)
+ SetErrBreak (("Host Interface Network driver not found (0x%08X)",
+ GetLastError()));
+
+ ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
+ if (!ok)
+ SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",
+ GetLastError()));
+
+ ok = SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
+ if (!ok)
+ SetErrBreak (("SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)",
+ GetLastError()));
+ }
+ while (0);
+
+ /* clean up the device info set */
+ if (hDeviceInfo != INVALID_HANDLE_VALUE)
+ SetupDiDestroyDeviceInfoList (hDeviceInfo);
+
+ if (FAILED (hrc))
+ break;
+ }
+ while (0);
+
+ return hrc;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinCreateHostOnlyNetworkInterface(IN LPCWSTR pInfPath, IN bool bIsInfPathFile,
+ OUT GUID *pGuid, OUT BSTR *lppszName, OUT BSTR *pErrMsg)
+{
+ HRESULT hrc = S_OK;
+
+ HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
+ SP_DEVINFO_DATA DeviceInfoData;
+ PVOID pQueueCallbackContext = NULL;
+ DWORD ret = 0;
+ BOOL found = FALSE;
+ BOOL registered = FALSE;
+ BOOL destroyList = FALSE;
+ WCHAR pWCfgGuidString [50];
+ WCHAR DevName[256];
+
+ do
+ {
+ GUID netGuid;
+ SP_DRVINFO_DATA DriverInfoData;
+ SP_DEVINSTALL_PARAMS DeviceInstallParams;
+ TCHAR className [MAX_PATH];
+ DWORD index = 0;
+ PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail;
+ /* for our purposes, 2k buffer is more
+ * than enough to obtain the hardware ID
+ * of the VBoxNetAdp driver. */
+ DWORD detailBuf [2048];
+
+ HKEY hkey = NULL;
+ DWORD cbSize;
+ DWORD dwValueType;
+
+ /* initialize the structure size */
+ DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
+ DriverInfoData.cbSize = sizeof (SP_DRVINFO_DATA);
+
+ /* copy the net class GUID */
+ memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));
+
+ /* create an empty device info set associated with the net class GUID */
+ hDeviceInfo = SetupDiCreateDeviceInfoList(&netGuid, NULL);
+ if (hDeviceInfo == INVALID_HANDLE_VALUE)
+ SetErrBreak (("SetupDiCreateDeviceInfoList failed (0x%08X)",
+ GetLastError()));
+
+ /* get the class name from GUID */
+ BOOL fResult = SetupDiClassNameFromGuid (&netGuid, className, MAX_PATH, NULL);
+ if (!fResult)
+ SetErrBreak (("SetupDiClassNameFromGuid failed (0x%08X)",
+ GetLastError()));
+
+ /* create a device info element and add the new device instance
+ * key to registry */
+ fResult = SetupDiCreateDeviceInfo (hDeviceInfo, className, &netGuid, NULL, NULL,
+ DICD_GENERATE_ID, &DeviceInfoData);
+ if (!fResult)
+ SetErrBreak (("SetupDiCreateDeviceInfo failed (0x%08X)",
+ GetLastError()));
+
+ /* select the newly created device info to be the currently
+ selected member */
+ fResult = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
+ if (!fResult)
+ SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",
+ GetLastError()));
+
+ if (pInfPath)
+ {
+ /* get the device install parameters and disable filecopy */
+ DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
+ fResult = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
+ &DeviceInstallParams);
+ if (fResult)
+ {
+ memset(DeviceInstallParams.DriverPath, 0, sizeof(DeviceInstallParams.DriverPath));
+ size_t pathLenght = wcslen(pInfPath) + 1/* null terminator */;
+ if (pathLenght < sizeof(DeviceInstallParams.DriverPath)/sizeof(DeviceInstallParams.DriverPath[0]))
+ {
+ memcpy(DeviceInstallParams.DriverPath, pInfPath, pathLenght*sizeof(DeviceInstallParams.DriverPath[0]));
+
+ if (bIsInfPathFile)
+ {
+ DeviceInstallParams.Flags |= DI_ENUMSINGLEINF;
+ }
+
+ fResult = SetupDiSetDeviceInstallParams(hDeviceInfo, &DeviceInfoData,
+ &DeviceInstallParams);
+ if (!fResult)
+ {
+ DWORD winEr = GetLastError();
+ LogFlow(("SetupDiSetDeviceInstallParams failed, winEr (%d)\n", winEr));
+ break;
+ }
+ }
+ else
+ {
+ LogFlow(("SetupDiSetDeviceInstallParams faileed: INF path is too long\n"));
+ break;
+ }
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ LogFlow(("SetupDiGetDeviceInstallParams failed, winEr (%d)\n", winEr));
+ }
+ }
+
+ /* build a list of class drivers */
+ fResult = SetupDiBuildDriverInfoList (hDeviceInfo, &DeviceInfoData,
+ SPDIT_CLASSDRIVER);
+ if (!fResult)
+ SetErrBreak (("SetupDiBuildDriverInfoList failed (0x%08X)",
+ GetLastError()));
+
+ destroyList = TRUE;
+
+ /* enumerate the driver info list */
+ while (TRUE)
+ {
+ BOOL ret;
+
+ ret = SetupDiEnumDriverInfo (hDeviceInfo, &DeviceInfoData,
+ SPDIT_CLASSDRIVER, index, &DriverInfoData);
+
+ /* if the function failed and GetLastError() returned
+ * ERROR_NO_MORE_ITEMS, then we have reached the end of the
+ * list. Otherwise there was something wrong with this
+ * particular driver. */
+ if (!ret)
+ {
+ if (GetLastError() == ERROR_NO_MORE_ITEMS)
+ break;
+ else
+ {
+ index++;
+ continue;
+ }
+ }
+
+ pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf;
+ pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
+
+ /* if we successfully find the hardware ID and it turns out to
+ * be the one for the loopback driver, then we are done. */
+ if (SetupDiGetDriverInfoDetail (hDeviceInfo,
+ &DeviceInfoData,
+ &DriverInfoData,
+ pDriverInfoDetail,
+ sizeof (detailBuf),
+ NULL))
+ {
+ TCHAR * t;
+
+ /* pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the
+ * whole list and see if there is a match somewhere. */
+ t = pDriverInfoDetail->HardwareID;
+ while (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)])
+ {
+ if (!_tcsicmp(t, DRIVERHWID))
+ break;
+
+ t += _tcslen(t) + 1;
+ }
+
+ if (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)])
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ index ++;
+ }
+
+ if (!found)
+ SetErrBreak(("Could not find Host Interface Networking driver! Please reinstall"));
+
+ /* set the loopback driver to be the currently selected */
+ fResult = SetupDiSetSelectedDriver (hDeviceInfo, &DeviceInfoData,
+ &DriverInfoData);
+ if (!fResult)
+ SetErrBreak(("SetupDiSetSelectedDriver failed (0x%08X)",
+ GetLastError()));
+
+ /* register the phantom device to prepare for install */
+ fResult = SetupDiCallClassInstaller (DIF_REGISTERDEVICE, hDeviceInfo,
+ &DeviceInfoData);
+ if (!fResult)
+ {
+ DWORD err = GetLastError();
+ SetErrBreak (("SetupDiCallClassInstaller failed (0x%08X)",
+ err));
+ }
+
+ /* registered, but remove if errors occur in the following code */
+ registered = TRUE;
+
+ /* ask the installer if we can install the device */
+ fResult = SetupDiCallClassInstaller (DIF_ALLOW_INSTALL, hDeviceInfo,
+ &DeviceInfoData);
+ if (!fResult)
+ {
+ if (GetLastError() != ERROR_DI_DO_DEFAULT)
+ SetErrBreak (("SetupDiCallClassInstaller (DIF_ALLOW_INSTALL) failed (0x%08X)",
+ GetLastError()));
+ /* that's fine */
+ }
+
+ /* get the device install parameters and disable filecopy */
+ DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
+ fResult = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
+ &DeviceInstallParams);
+ if (fResult)
+ {
+ pQueueCallbackContext = SetupInitDefaultQueueCallback(NULL);
+ if (pQueueCallbackContext)
+ {
+ DeviceInstallParams.InstallMsgHandlerContext = pQueueCallbackContext;
+ DeviceInstallParams.InstallMsgHandler = (PSP_FILE_CALLBACK)vboxNetCfgWinPspFileCallback;
+ fResult = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
+ &DeviceInstallParams);
+ if (!fResult)
+ {
+ DWORD winEr = GetLastError();
+ LogFlow(("SetupDiSetDeviceInstallParams failed, winEr (%d)\n", winEr));
+ }
+ Assert(fResult);
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ LogFlow(("SetupInitDefaultQueueCallback failed, winEr (%d)\n", winEr));
+ }
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ LogFlow(("SetupDiGetDeviceInstallParams failed, winEr (%d)\n", winEr));
+ }
+
+ /* install the files first */
+ fResult = SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES, hDeviceInfo,
+ &DeviceInfoData);
+ if (!fResult)
+ SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES) failed (0x%08X)",
+ GetLastError()));
+ /* get the device install parameters and disable filecopy */
+ DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
+ fResult = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
+ &DeviceInstallParams);
+ if (fResult)
+ {
+ DeviceInstallParams.Flags |= DI_NOFILECOPY;
+ fResult = SetupDiSetDeviceInstallParams(hDeviceInfo, &DeviceInfoData,
+ &DeviceInstallParams);
+ if (!fResult)
+ SetErrBreak (("SetupDiSetDeviceInstallParams failed (0x%08X)",
+ GetLastError()));
+ }
+
+ /*
+ * Register any device-specific co-installers for this device,
+ */
+ fResult = SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS,
+ hDeviceInfo,
+ &DeviceInfoData);
+ if (!fResult)
+ SetErrBreak (("SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS) failed (0x%08X)",
+ GetLastError()));
+
+ /*
+ * install any installer-specified interfaces.
+ * and then do the real install
+ */
+ fResult = SetupDiCallClassInstaller(DIF_INSTALLINTERFACES,
+ hDeviceInfo,
+ &DeviceInfoData);
+ if (!fResult)
+ SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLINTERFACES) failed (0x%08X)",
+ GetLastError()));
+
+ fResult = SetupDiCallClassInstaller(DIF_INSTALLDEVICE,
+ hDeviceInfo,
+ &DeviceInfoData);
+ if (!fResult)
+ SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICE) failed (0x%08X)",
+ GetLastError()));
+
+ /* Figure out NetCfgInstanceId */
+ hkey = SetupDiOpenDevRegKey(hDeviceInfo,
+ &DeviceInfoData,
+ DICS_FLAG_GLOBAL,
+ 0,
+ DIREG_DRV,
+ KEY_READ);
+ if (hkey == INVALID_HANDLE_VALUE)
+ SetErrBreak (("SetupDiOpenDevRegKey failed (0x%08X)",
+ GetLastError()));
+
+ cbSize = sizeof (pWCfgGuidString);
+ DWORD ret;
+ ret = RegQueryValueExW (hkey, L"NetCfgInstanceId", NULL,
+ &dwValueType, (LPBYTE) pWCfgGuidString, &cbSize);
+
+ RegCloseKey (hkey);
+
+ if (!SetupDiGetDeviceRegistryPropertyW(hDeviceInfo, &DeviceInfoData,
+ SPDRP_FRIENDLYNAME , /* IN DWORD Property,*/
+ NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
+ (PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/
+ sizeof(DevName), /* IN DWORD PropertyBufferSize,*/
+ NULL /*OUT PDWORD RequiredSize OPTIONAL*/))
+ {
+ int err = GetLastError();
+ if (err != ERROR_INVALID_DATA)
+ {
+ SetErrBreak (("SetupDiGetDeviceRegistryProperty failed (0x%08X)",
+ err));
+ }
+
+ if (!SetupDiGetDeviceRegistryPropertyW(hDeviceInfo, &DeviceInfoData,
+ SPDRP_DEVICEDESC, /* IN DWORD Property,*/
+ NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
+ (PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/
+ sizeof(DevName), /* IN DWORD PropertyBufferSize,*/
+ NULL /*OUT PDWORD RequiredSize OPTIONAL*/
+ ))
+ {
+ err = GetLastError();
+ SetErrBreak (("SetupDiGetDeviceRegistryProperty failed (0x%08X)",
+ err));
+ }
+ }
+ }
+ while (0);
+
+ /*
+ * cleanup
+ */
+ if (pQueueCallbackContext)
+ SetupTermDefaultQueueCallback(pQueueCallbackContext);
+
+ if (hDeviceInfo != INVALID_HANDLE_VALUE)
+ {
+ /* an error has occurred, but the device is registered, we must remove it */
+ if (ret != 0 && registered)
+ SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
+
+ found = SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData);
+
+ /* destroy the driver info list */
+ if (destroyList)
+ SetupDiDestroyDriverInfoList(hDeviceInfo, &DeviceInfoData,
+ SPDIT_CLASSDRIVER);
+ /* clean up the device info set */
+ SetupDiDestroyDeviceInfoList (hDeviceInfo);
+ }
+
+ /* return the network connection GUID on success */
+ if (SUCCEEDED(hrc))
+ {
+ WCHAR ConnectoinName[128];
+ ULONG cbName = sizeof(ConnectoinName);
+
+ HRESULT hr = VBoxNetCfgWinGenHostonlyConnectionName(DevName, ConnectoinName, &cbName);
+ if (SUCCEEDED(hr))
+ hr = VBoxNetCfgWinRenameConnection(pWCfgGuidString, ConnectoinName);
+
+ if (lppszName)
+ {
+ *lppszName = ::SysAllocString((const OLECHAR *) DevName);
+ if (!*lppszName)
+ {
+ LogFlow(("SysAllocString failed\n"));
+ hrc = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
+ }
+ }
+
+ if (pGuid)
+ {
+ hrc = CLSIDFromString(pWCfgGuidString, (LPCLSID)pGuid);
+ if (FAILED(hrc))
+ LogFlow(("CLSIDFromString failed, hrc (0x%x)\n", hrc));
+ }
+
+ INetCfg *pNetCfg = NULL;
+ LPWSTR lpszApp = NULL;
+ hr = VBoxNetCfgWinQueryINetCfg(&pNetCfg, TRUE, L"VirtualBox Host-Only Creation",
+ 30 * 1000, /* on Vista we often get 6to4svc.dll holding the lock, wait for 30 sec. */
+ /* TODO: special handling for 6to4svc.dll ???, i.e. several retrieves */
+ &lpszApp);
+ if (hr == S_OK)
+ {
+ hr = vboxNetCfgWinEnumNetCfgComponents(pNetCfg,
+ &GUID_DEVCLASS_NETSERVICE,
+ vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority,
+ pGuid);
+ if (SUCCEEDED(hr))
+ {
+ hr = vboxNetCfgWinEnumNetCfgComponents(pNetCfg,
+ &GUID_DEVCLASS_NETTRANS,
+ vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority,
+ pGuid);
+ if (SUCCEEDED(hr))
+ hr = vboxNetCfgWinEnumNetCfgComponents(pNetCfg,
+ &GUID_DEVCLASS_NETCLIENT,
+ vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority,
+ pGuid);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = pNetCfg->Apply();
+ }
+ else
+ LogFlow(("Enumeration failed, hr 0x%x\n", hr));
+ VBoxNetCfgWinReleaseINetCfg(pNetCfg, TRUE);
+ }
+ else if (hr == NETCFG_E_NO_WRITE_LOCK && lpszApp)
+ {
+ LogFlow(("Application %ws is holding the lock, failed\n", lpszApp));
+ CoTaskMemFree(lpszApp);
+ }
+ else
+ LogFlow(("VBoxNetCfgWinQueryINetCfg failed, hr 0x%x\n", hr));
+ }
+ return hrc;
+}
+
+#undef SetErrBreak
+
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/Makefile.kup b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/Makefile.kup
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/Makefile.kup
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetAdp.inf b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetAdp.inf
index 7b62e000f..b7d2702c8 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetAdp.inf
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetAdp.inf
@@ -1,9 +1,9 @@
+; $Id: VBoxNetAdp.inf 36184 2011-03-07 10:57:04Z vboxsync $
+; @file
+; VBoxNetAdp.inf - VirtualBox Host-Only Driver inf file
;
-; VirtualBox Network Adapter
;
-
-;
-; Copyright (C) 2008 Oracle Corporation
+; 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;
@@ -14,11 +14,6 @@
; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
;
-;
-; Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
-; Copyright (c) 1993-1999, Microsoft Corporation
-;
-
[Version]
signature = "$Windows NT$"
;cat CatalogFile = VBoxNetAdp.cat
@@ -45,11 +40,9 @@ VBoxNetAdp.Files.Sys = 12 ; %windir%\System32\drivers
[Manufacturer]
%Provider% = VBox,NTx86,NTia64,NTamd64
-; For Win2K
[VBox]
%VBoxNetAdp_Desc% = VBoxNetAdp.ndi, sun_VBoxNetAdp
-; For XP and later
[VBox.NTx86]
%VBoxNetAdp_Desc% = VBoxNetAdp.ndi, sun_VBoxNetAdp
@@ -71,7 +64,6 @@ VBoxNetAdp.sys,,,2
[VBoxNetAdp.ndi.Services]
AddService = VBoxNetAdp,0x2, VBoxNetAdp.AddService
-
[VBoxNetAdp.AddService]
DisplayName = %VBoxNetAdp_Desc%
ServiceType = 1 ;SERVICE_KERNEL_DRIVER
@@ -87,12 +79,6 @@ HKR, Ndi\Interfaces, UpperRange, 0, "ndis5"
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
[VBoxNetAdp.AddService]
-; ----------------------------------------------------------------------
-; Add any miniport-specific parameters here. These are params that your
-; [filter] device is going to use.
-;
-;HKR, Parameters, ParameterName, 0x10000, "MultiSz", "Parameter", "Value"
-;HKR, Parameters, ParameterName2, 0x10001, 4
[Strings]
Provider = "Oracle Corporation"
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.rc b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc
index 1af3c0cbb..41da1c3ea 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.rc
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc
@@ -1,10 +1,9 @@
-/* $Id: VBoxNetFlt-win.rc $ */
+/* $Id: VBoxNetFlt-win.rc 36184 2011-03-07 10:57:04Z vboxsync $ */
/** @file
* VBoxNetFlt - Resource file containing version info and icon.
*/
-
/*
- * Copyright (C) 2009-2010 Oracle Corporation
+ * 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;
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt.inf b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt.inf
index de3dfc82b..8745ae884 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt.inf
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt.inf
@@ -1,9 +1,10 @@
+; $Id: VBoxNetFlt.inf 36184 2011-03-07 10:57:04Z vboxsync $
+; @file
+; VBoxNetFlt.inf - VirtualBox Bridged Networking Driver inf file
+; Protocol edge
;
-; VirtualBox Bridged Networking Driver
;
-
-;
-; Copyright (C) 2008 Oracle Corporation
+; 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;
@@ -14,11 +15,6 @@
; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
;
-;
-; Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
-; Copyright (c) 1993-1999, Microsoft Corporation
-;
-
[Version]
Signature = "$Windows NT$"
;cat CatalogFile = VBoxNetFlt.cat
@@ -31,33 +27,24 @@ Provider = %Provider%
[Manufacturer]
-%Provider% = VBox,NTx86,NTia64,NTamd64
+%Provider% = VBox,NTx86,NTamd64
[ControlFlags]
-;=========================================================================
-;
-;=========================================================================
-
-; For Win2K
[VBox]
%VBoxNetFlt_Desc% = VBoxNetFlt.ndi, sun_VBoxNetFlt
-; For XP and later
[VBox.NTx86]
%VBoxNetFlt_Desc% = VBoxNetFlt.ndi, sun_VBoxNetFlt
-[VBox.NTia64]
-%VBoxNetFlt_Desc% = VBoxNetFlt.ndi, sun_VBoxNetFlt
-
[VBox.NTamd64]
%VBoxNetFlt_Desc% = VBoxNetFlt.ndi, sun_VBoxNetFlt
[VBoxNetFlt.ndi]
AddReg = VBoxNetFlt.ndi.AddReg, VBoxNetFlt.AddReg
-Characteristics = 0x4410 ; NCF_FILTER | NCF_NDIS_PROTOCOL !--Filter Specific--!!
+Characteristics = 0x4410 ; NCF_FILTER | NCF_NDIS_PROTOCOL
CopyFiles = VBoxNetFlt.Files.DLL, VBoxNetFlt.Files.Sys
-CopyInf = VBoxNetFlt_m.inf
+CopyInf = VBoxNetFltM.inf
[VBoxNetFlt.ndi.Remove]
DelFiles = VBoxNetFlt.Files.DLL, VBoxNetFlt.Files.Sys
@@ -76,23 +63,13 @@ AddReg = VBoxNetFlt.AddService.AddReg
[VBoxNetFlt.AddService.AddReg]
-; ----------------------------------------------------------------------
-; Add any miniport-specific parameters here. These are params that your
-; filter device is going to use.
-;
-;HKR, Parameters, ParameterName, 0x10000, "MultiSz", "Parameter", "Value"
-;HKR, Parameters, ParameterName2, 0x10001, 4
-
-; ----------------------------------------------------------------------
-; File copy
-;
[SourceDisksNames]
1=%DiskDescription%,"",,
[SourceDisksFiles]
VBoxNetFlt.sys=1
-VBoxNetFltNotify.dll=1
+VBoxNetFltNobj.dll=1
[DestinationDirs]
DefaultDestDir = 12
@@ -103,29 +80,12 @@ VBoxNetFlt.Files.Sys = 12 ; %windir%\System32\drivers
VBoxNetFlt.sys,,,2
[VBoxNetFlt.Files.DLL]
-VBoxNetFltNotify.dll,,,2
-
-; ----------------------------------------------------------------------
-; Filter Install
-;
+VBoxNetFltNobj.dll,,,2
[VBoxNetFlt.ndi.AddReg]
HKR, Ndi, HelpText, , %VBoxNetFlt_HELP%
-
-; ----------------------------------------------------------------------
-; !!--Filter Specific--!!
-;
-; Note:
-; 1. Other components may also have UpperRange/LowerRange but for filters
-; the value of both of them must be noupper/nolower
-; 2. The value FilterClass is required.
-; 3. The value Service is required
-; 4. FilterDeviceInfId is the InfId of the filter device (miniport) that will
-; be installed for each filtered adapter.
-; In this case this is sun_VBoxNetFltmp (refer to VBoxNetFlt_m.inf)
-;
-HKR, Ndi, ClsID, 0, {c631480a-acbe-4add-bb1d-3ed8aa52b5d9}
-HKR, Ndi, ComponentDll, , VBoxNetFltNotify.dll
+HKR, Ndi, ClsID, 0, {f374d1a0-bf08-4bdc-9cb2-c15ddaeef955}
+HKR, Ndi, ComponentDll, , VBoxNetFltNobj.dll
HKR, Ndi, FilterClass, , failover
HKR, Ndi, FilterDeviceInfId, , sun_VBoxNetFltmp
HKR, Ndi, Service, , VBoxNetFlt
@@ -134,18 +94,11 @@ HKR, Ndi\Interfaces, LowerRange, , nolower
HKR, Ndi\Interfaces, FilterMediaTypes, , "ethernet, nolower"
[VBoxNetFlt.AddReg]
-; The following key is Required
-; The following key is VBoxNetFlt specific
HKR, Parameters, Param1, 0, 4
-; ----------------------------------------------------------------------
[Strings]
Provider = "Oracle Corporation"
DiskDescription = "VirtualBox Bridged Networking Driver"
-
VBoxNetFlt_Desc = "VirtualBox Bridged Networking Driver"
-VBoxNetFlt_HELP = "VBoxNetFlt Driver"
-VBoxNetFltService_Desc = "VBoxNetFlt Service"
-
-
-
+VBoxNetFlt_HELP = "VirtualBox Bridged Networking Driver"
+VBoxNetFltService_Desc = "VirtualBox Bridged Networking Service"
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltCmn-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltCmn-win.h
new file mode 100644
index 000000000..9d89ededd
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltCmn-win.h
@@ -0,0 +1,544 @@
+/* $Id: VBoxNetFltCmn-win.h 36184 2011-03-07 10:57:04Z vboxsync $ */
+/** @file
+ * VBoxNetFltCmn-win.h - Bridged Networking Driver, Windows Specific Code.
+ * Common header with configuration defines and global defs
+ */
+/*
+ * 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 ___VBoxNetFltCmn_win_h___
+#define ___VBoxNetFltCmn_win_h___
+
+#define LOG_GROUP LOG_GROUP_NET_FLT_DRV
+
+/* debugging flags */
+#ifdef DEBUG
+//# define DEBUG_NETFLT_PACKETS
+# ifndef DEBUG_misha
+# define DEBUG_NETFLT_NOASSERT
+# endif
+/* # define DEBUG_NETFLT_LOOPBACK */
+/* receive logic has several branches */
+/* the DEBUG_NETFLT_RECV* macros used to debug the ProtocolReceive callback
+ * which is typically not used in case the underlying miniport indicates the packets with NdisMIndicateReceivePacket
+ * the best way to debug the ProtocolReceive (which in turn has several branches) is to enable the DEBUG_NETFLT_RECV
+ * one by one in the below order, i.e.
+ * first DEBUG_NETFLT_RECV
+ * then DEBUG_NETFLT_RECV + DEBUG_NETFLT_RECV_NOPACKET */
+//# define DEBUG_NETFLT_RECV
+//# define DEBUG_NETFLT_RECV_NOPACKET
+//# define DEBUG_NETFLT_RECV_TRANSFERDATA
+/* use ExAllocatePoolWithTag instead of NdisAllocateMemoryWithTag */
+// #define DEBUG_NETFLT_USE_EXALLOC
+#endif
+
+#include <VBox/intnet.h>
+#include <VBox/log.h>
+#include <VBox/err.h>
+#include <VBox/version.h>
+#include <iprt/initterm.h>
+#include <iprt/assert.h>
+#include <iprt/spinlock.h>
+#include <iprt/semaphore.h>
+#include <iprt/process.h>
+#include <iprt/alloc.h>
+#include <iprt/alloca.h>
+#include <iprt/time.h>
+#include <iprt/net.h>
+
+RT_C_DECLS_BEGIN
+/* ntddk.h has a missing #pragma pack(), work around it
+ * see #ifdef VBOX_WITH_WORKAROUND_MISSING_PACK below for detail */
+#define VBOX_WITH_WORKAROUND_MISSING_PACK
+#if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
+# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
+# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
+# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap
+# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
+# define _interlockedbittestandset _interlockedbittestandset_StupidDDKVsCompilerCrap
+# define _interlockedbittestandreset _interlockedbittestandreset_StupidDDKVsCompilerCrap
+# define _interlockedbittestandset64 _interlockedbittestandset64_StupidDDKVsCompilerCrap
+# define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap
+# pragma warning(disable : 4163)
+# ifdef VBOX_WITH_WORKAROUND_MISSING_PACK
+# pragma warning(disable : 4103)
+# endif
+# include <ntddk.h>
+# pragma warning(default : 4163)
+# ifdef VBOX_WITH_WORKAROUND_MISSING_PACK
+# pragma pack()
+# pragma warning(default : 4103)
+# endif
+# undef _InterlockedExchange
+# undef _InterlockedExchangeAdd
+# undef _InterlockedCompareExchange
+# undef _InterlockedAddLargeStatistic
+# undef _interlockedbittestandset
+# undef _interlockedbittestandreset
+# undef _interlockedbittestandset64
+# undef _interlockedbittestandreset64
+# include <ndis.h>
+#else
+//# include <ntddk.h>
+/* can include ndis.h right away */
+# include <ndis.h>
+#endif
+RT_C_DECLS_END
+
+#define VBOXNETFLT_OS_SPECFIC 1
+
+/** version
+ * NOTE: we are NOT using NDIS 5.1 features now */
+#ifdef NDIS51_MINIPORT
+# define VBOXNETFLT_VERSION_MP_NDIS_MAJOR 5
+# define VBOXNETFLT_VERSION_MP_NDIS_MINOR 1
+#else
+# define VBOXNETFLT_VERSION_MP_NDIS_MAJOR 5
+# define VBOXNETFLT_VERSION_MP_NDIS_MINOR 0
+#endif
+
+#ifndef VBOXNETADP
+#ifdef NDIS51
+# define VBOXNETFLT_VERSION_PT_NDIS_MAJOR 5
+# define VBOXNETFLT_VERSION_PT_NDIS_MINOR 1 /* todo: use 0 here as well ? */
+#else
+# define VBOXNETFLT_VERSION_PT_NDIS_MAJOR 5
+# define VBOXNETFLT_VERSION_PT_NDIS_MINOR 0
+#endif
+
+# define VBOXNETFLT_NAME_PROTOCOL L"VBoxNetFlt"
+/** device to be used to prevent the driver unload & ioctl interface (if necessary in the future) */
+# define VBOXNETFLT_NAME_LINK L"\\DosDevices\\Global\\VBoxNetFlt"
+# define VBOXNETFLT_NAME_DEVICE L"\\Device\\VBoxNetFlt"
+#else
+# define VBOXNETFLT_NAME_LINK L"\\DosDevices\\Global\\VBoxNetAdp"
+# define VBOXNETFLT_NAME_DEVICE L"\\Device\\VBoxNetAdp"
+#endif
+
+typedef struct VBOXNETFLTINS *PVBOXNETFLTINS;
+
+/** configuration */
+
+/** Ndis Packet pool settings
+ * these are applied to both receive and send packet pools */
+/* number of packets for normal used */
+#define VBOXNETFLT_PACKET_POOL_SIZE_NORMAL 0x000000FF
+/* number of additional overflow packets */
+#define VBOXNETFLT_PACKET_POOL_SIZE_OVERFLOW 0x0000FF00
+
+/** packet queue size used when the driver is working in the "active" mode */
+#define VBOXNETFLT_PACKET_INFO_POOL_SIZE 0x0000FFFF
+
+#ifndef VBOXNETADP
+/** memory tag used for memory allocations
+ * (VBNF stands for VBox NetFlt) */
+# define VBOXNETFLT_MEM_TAG 'FNBV'
+#else
+/** memory tag used for memory allocations
+ * (VBNA stands for VBox NetAdp) */
+# define VBOXNETFLT_MEM_TAG 'ANBV'
+#endif
+
+/** receive and transmit Ndis buffer pool size */
+#define VBOXNETFLT_BUFFER_POOL_SIZE_TX 128
+#define VBOXNETFLT_BUFFER_POOL_SIZE_RX 128
+
+#define VBOXNETFLT_PACKET_ETHEADER_SIZE 14
+#define VBOXNETFLT_PACKET_HEADER_MATCH_SIZE 24
+#define VBOXNETFLT_PACKET_QUEUE_SG_SEGS_ALLOC 32
+
+
+#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
+# define VBOXNETFLT_PACKETMATCH_LENGTH (VBOXNETFLT_PACKET_ETHEADER_SIZE + 2)
+#endif
+
+#ifdef VBOXNETADP
+#define VBOXNETADP_HEADER_SIZE 14
+#define VBOXNETADP_MAX_DATA_SIZE 1500
+#define VBOXNETADP_MAX_PACKET_SIZE (VBOXNETADP_HEADER_SIZE + VBOXNETADP_MAX_DATA_SIZE)
+#define VBOXNETADP_MIN_PACKET_SIZE 60
+/* link speed 100Mbps (measured in 100 bps) */
+#define VBOXNETADP_LINK_SPEED 1000000
+#define VBOXNETADP_MAX_LOOKAHEAD_SIZE VBOXNETADP_MAX_DATA_SIZE
+#define VBOXNETADP_VENDOR_ID 0x080027
+#define VBOXNETADP_VENDOR_DRIVER_VERSION 0x00010000
+#define VBOXNETADP_VENDOR_DESC "Sun"
+#define VBOXNETADP_MAX_MCAST_LIST 32
+#define VBOXNETADP_ETH_ADDRESS_LENGTH 6
+
+//#define VBOXNETADP_REPORT_DISCONNECTED
+#endif
+/* type defs */
+
+/** Flag specifying that the type of enqueued packet
+ * if set the info contains the PINTNETSG packet
+ * if clear the packet info contains the PNDIS_PACKET packet
+ * Typically the packet queue we are maintaining contains PNDIS_PACKETs only,
+ * however in case the underlying miniport indicates a packet with the NDIS_STATUS_RESOURCES status
+ * we MUST return the packet back to the miniport immediately
+ * this is why we are creating the INTNETSG, copying the ndis packet info there and enqueueing it */
+#define VBOXNETFLT_PACKET_SG 0x00000001
+
+/** the flag specifying that the packet source
+ * if set the packet comes from the host (upperlying protocol)
+ * if clear the packet comes from the wire (underlying miniport) */
+#define VBOXNETFLT_PACKET_SRC_HOST 0x00000002
+
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
+/** flag specifying the packet was originated by our driver
+ * i.e. we could use it on our needs and should not return it
+ * we are enqueueing "our" packets on ProtocolReceive call-back when
+ * Ndis does not give us a receive packet (the driver below us has called NdisM..IndicateReceive)
+ * this is supported for Ndis Packet only */
+#define VBOXNETFLT_PACKET_MINE 0x00000004
+
+/** flag passed to vboxNetFltWinQuEnqueuePacket specifying that the packet should be copied
+ * this is supported for Ndis Packet only */
+#define VBOXNETFLT_PACKET_COPY 0x00000008
+#endif
+
+/** packet queue element containing the packet info */
+typedef struct VBOXNETFLT_PACKET_INFO
+{
+ /** list entry used for enqueueing the info */
+ LIST_ENTRY ListEntry;
+ /** pointer to the pool containing this packet info */
+ struct VBOXNETFLT_PACKET_INFO_POOL *pPool;
+ /** flags describing the referenced packet. Contains PACKET_xxx flags (i.e. PACKET_SG, PACKET_SRC_HOST) */
+ uint32_t fFlags;
+ /** pointer to the packet this info represents */
+ PVOID pPacket;
+} VBOXNETFLT_PACKET_INFO, *PVBOXNETFLT_PACKET_INFO;
+
+/* paranoid check to make sure the elements in the packet info array are properly aligned */
+AssertCompile((sizeof(VBOXNETFLT_PACKET_INFO) & (sizeof(PVOID) - 1)) == 0);
+
+/** represents the packet queue */
+typedef LIST_ENTRY PVBOXNETFLT_ACKET_QUEUE, *PVBOXNETFLT_PACKET_QUEUE;
+
+/*
+ * we are using non-interlocked versions of LIST_ENTRY-related operations macros and synchronize
+ * access to the queue and its elements by acquiring/releasing a spinlock using Ndis[Acquire,Release]Spinlock
+ *
+ * we are NOT using interlocked versions of insert/remove head/tail list functions because we need to iterate though
+ * the queue elements as well as remove elements from the midle of the queue
+ *
+ * * @todo: it seems that we can switch to using interlocked versions of list-entry functions
+ * since we have removed all functionality (mentioned above, i.e. queue elements iteration, etc.) that might prevent us from doing this
+ */
+typedef struct VBOXNETFLT_INTERLOCKED_PACKET_QUEUE
+{
+ /** queue */
+ PVBOXNETFLT_ACKET_QUEUE Queue;
+ /** queue lock */
+ NDIS_SPIN_LOCK Lock;
+} VBOXNETFLT_INTERLOCKED_PACKET_QUEUE, *PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE;
+
+typedef struct VBOXNETFLT_SINGLE_LIST
+{
+ /** queue */
+ SINGLE_LIST_ENTRY Head;
+ /** pointer to the list tail. used to enqueue elements to the tail of the list */
+ PSINGLE_LIST_ENTRY pTail;
+} VBOXNETFLT_SINGLE_LIST, *PVBOXNETFLT_SINGLE_LIST;
+
+typedef struct VBOXNETFLT_INTERLOCKED_SINGLE_LIST
+{
+ /** queue */
+ VBOXNETFLT_SINGLE_LIST List;
+ /** queue lock */
+ NDIS_SPIN_LOCK Lock;
+} VBOXNETFLT_INTERLOCKED_SINGLE_LIST, *PVBOXNETFLT_INTERLOCKED_SINGLE_LIST;
+
+/** packet info pool contains free packet info elements to be used for the packet queue
+ * we are using the pool mechanism to allocate packet queue elements
+ * the pool mechanism is pretty simple now, we are allocating a bunch of memory
+ * for maintaining VBOXNETFLT_PACKET_INFO_POOL_SIZE queue elements and just returning null when the pool is exhausted
+ * This mechanism seems to be enough for now since we are using VBOXNETFLT_PACKET_INFO_POOL_SIZE = 0xffff which is
+ * the maximum size of packets the ndis packet pool supports */
+typedef struct VBOXNETFLT_PACKET_INFO_POOL
+{
+ /** free packet info queue */
+ VBOXNETFLT_INTERLOCKED_PACKET_QUEUE Queue;
+ /** memory bugger used by the pool */
+ PVOID pBuffer;
+} VBOXNETFLT_PACKET_INFO_POOL, *PVBOXNETFLT_PACKET_INFO_POOL;
+
+typedef enum VBOXNETDEVOPSTATE
+{
+ kVBoxNetDevOpState_InvalidValue = 0,
+ kVBoxNetDevOpState_Initializing,
+ kVBoxNetDevOpState_Initialized,
+ kVBoxNetDevOpState_Deinitializing,
+ kVBoxNetDevOpState_Deinitialized,
+
+} VBOXNETDEVOPSTATE;
+
+typedef enum VBOXNETFLT_WINIFSTATE
+{
+ /** The usual invalid state. */
+ kVBoxWinIfState_Invalid = 0,
+ /** Initialization. */
+ kVBoxWinIfState_Connecting,
+ /** Connected fuly functional state */
+ kVBoxWinIfState_Connected,
+ /** Disconnecting */
+ kVBoxWinIfState_Disconnecting,
+ /** Disconnected */
+ kVBoxWinIfState_Disconnected,
+} VBOXNETFLT_WINIFSTATE;
+
+/** structure used to maintain the state and reference count of the miniport and protocol */
+typedef struct VBOXNETFLT_WINIF_DEVICE
+{
+ /** initialize state */
+ VBOXNETDEVOPSTATE OpState;
+ /** ndis power state */
+ NDIS_DEVICE_POWER_STATE PowerState;
+ /** reference count */
+ uint32_t cReferences;
+} VBOXNETFLT_WINIF_DEVICE, *PVBOXNETFLT_WINIF_DEVICE;
+
+#define VBOXNDISREQUEST_INPROGRESS 1
+#define VBOXNDISREQUEST_QUEUED 2
+
+typedef struct VBOXNETFLTWIN_STATE
+{
+ union
+ {
+ struct
+ {
+ UINT fRequestInfo : 2;
+ UINT fInterfaceClosing : 1;
+ UINT fStandBy : 1;
+ UINT fProcessingPacketFilter : 1;
+ UINT fPPFNetFlt : 1;
+ UINT fUpperProtSetFilterInitialized : 1;
+ UINT Reserved : 25;
+ };
+ UINT Value;
+ };
+} VBOXNETFLTWIN_STATE, *PVBOXNETFLTWIN_STATE;
+
+DECLINLINE(VBOXNETFLTWIN_STATE) vboxNetFltWinAtomicUoReadWinState(VBOXNETFLTWIN_STATE State)
+{
+ UINT fValue = ASMAtomicUoReadU32((volatile uint32_t *)&State.Value);
+ return *((PVBOXNETFLTWIN_STATE)((void*)&fValue));
+}
+
+/* miniport layer globals */
+typedef struct VBOXNETFLTGLOBALS_MP
+{
+ /** our miniport handle */
+ NDIS_HANDLE hMiniport;
+ /** ddis wrapper handle */
+ NDIS_HANDLE hNdisWrapper;
+} VBOXNETFLTGLOBALS_MP, *PVBOXNETFLTGLOBALS_MP;
+
+#ifndef VBOXNETADP
+/* protocol layer globals */
+typedef struct VBOXNETFLTGLOBALS_PT
+{
+ /** our protocol handle */
+ NDIS_HANDLE hProtocol;
+} VBOXNETFLTGLOBALS_PT, *PVBOXNETFLTGLOBALS_PT;
+#endif /* #ifndef VBOXNETADP */
+
+typedef struct VBOXNETFLTGLOBALS_WIN
+{
+ /** synch event used for device creation synchronization */
+ KEVENT SynchEvent;
+ /** Device reference count */
+ int cDeviceRefs;
+ /** ndis device */
+ NDIS_HANDLE hDevice;
+ /** device object */
+ PDEVICE_OBJECT pDevObj;
+ /* loopback flags */
+ /* ndis packet flags to disable packet loopback */
+ UINT fPacketDontLoopBack;
+ /* ndis packet flags specifying whether the packet is looped back */
+ UINT fPacketIsLoopedBack;
+ /* Minport info */
+ VBOXNETFLTGLOBALS_MP Mp;
+#ifndef VBOXNETADP
+ /* Protocol info */
+ VBOXNETFLTGLOBALS_PT Pt;
+#endif
+} VBOXNETFLTGLOBALS_WIN, *PVBOXNETFLTGLOBALS_WIN;
+
+extern VBOXNETFLTGLOBALS_WIN g_VBoxNetFltGlobalsWin;
+
+/** represents filter driver device context*/
+typedef struct VBOXNETFLTWIN
+{
+ /** handle used by miniport edge for ndis calls */
+ NDIS_HANDLE hMiniport;
+ /** miniport edge state */
+ VBOXNETFLT_WINIF_DEVICE MpState;
+ /** ndis packet pool used for receives */
+ NDIS_HANDLE hRecvPacketPool;
+ /** ndis buffer pool used for receives */
+ NDIS_HANDLE hRecvBufferPool;
+ /** driver bind adapter state. */
+ VBOXNETFLT_WINIFSTATE enmState;
+#ifndef VBOXNETADP
+ /* misc state flags */
+ VBOXNETFLTWIN_STATE StateFlags;
+ /** handle used by protocol edge for ndis calls */
+ NDIS_HANDLE hBinding;
+ /** protocol edge state */
+ VBOXNETFLT_WINIF_DEVICE PtState;
+ /** ndis packet pool used for receives */
+ NDIS_HANDLE hSendPacketPool;
+ /** ndis buffer pool used for receives */
+ NDIS_HANDLE hSendBufferPool;
+ /** used for maintaining the pending send packets for handling packet loopback */
+ VBOXNETFLT_INTERLOCKED_SINGLE_LIST SendPacketQueue;
+ /** used for serializing calls to the NdisRequest in the vboxNetFltWinSynchNdisRequest */
+ RTSEMFASTMUTEX hSynchRequestMutex;
+ /** event used to synchronize with the Ndis Request completion in the vboxNetFltWinSynchNdisRequest */
+ KEVENT hSynchCompletionEvent;
+ /** status of the Ndis Request initiated by the vboxNetFltWinSynchNdisRequest */
+ NDIS_STATUS volatile SynchCompletionStatus;
+ /** pointer to the Ndis Request being executed by the vboxNetFltWinSynchNdisRequest */
+ PNDIS_REQUEST volatile pSynchRequest;
+ /** open/close adapter status.
+ * Since ndis adapter open and close requests may complete asynchronously,
+ * we are using event mechanism to wait for open/close completion
+ * the status field is being set by the completion call-back */
+ NDIS_STATUS OpenCloseStatus;
+ /** open/close adaptor completion event */
+ NDIS_EVENT OpenCloseEvent;
+ /** medium we are attached to */
+ NDIS_MEDIUM enmMedium;
+ /**
+ * Passdown request info
+ */
+ /** ndis request we pass down to the miniport below */
+ NDIS_REQUEST PassDownRequest;
+ /** Ndis pass down request bytes read or written original pointer */
+ PULONG pcPDRBytesRW;
+ /** Ndis pass down request bytes needed original pointer */
+ PULONG pcPDRBytesNeeded;
+ /** true if we should indicate the receive complete used by the ProtocolReceive mechanism.
+ * We need to indicate it only with the ProtocolReceive + NdisMEthIndicateReceive path.
+ * Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case
+ * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber
+ * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64
+ * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */
+ bool abIndicateRxComplete[64];
+ /** Pending transfer data packet queue (i.e. packets that were indicated as pending on NdisTransferData call */
+ VBOXNETFLT_INTERLOCKED_SINGLE_LIST TransferDataList;
+ /* mac options initialized on OID_GEN_MAC_OPTIONS */
+ ULONG fMacOptions;
+ /** our miniport devuice name */
+ NDIS_STRING MpDeviceName;
+ /** synchronize with unbind with Miniport initialization */
+ NDIS_EVENT MpInitCompleteEvent;
+ /** media connect status that we indicated */
+ NDIS_STATUS MpIndicatedMediaStatus;
+ /** media connect status pending to indicate */
+ NDIS_STATUS MpUnindicatedMediaStatus;
+ /** packet filter flags set by the upper protocols */
+ ULONG fUpperProtocolSetFilter;
+ /** packet filter flags set by the upper protocols */
+ ULONG fSetFilterBuffer;
+ /** packet filter flags set by us */
+ ULONG fOurSetFilter;
+#else
+ volatile ULONG cTxSuccess;
+ volatile ULONG cRxSuccess;
+ volatile ULONG cTxError;
+ volatile ULONG cRxError;
+#endif
+} VBOXNETFLTWIN, *PVBOXNETFLTWIN;
+
+typedef struct VBOXNETFLT_PACKET_QUEUE_WORKER
+{
+ /** this event is used to initiate a packet queue worker thread kill */
+ KEVENT KillEvent;
+ /** this event is used to notify a worker thread that the packets are added to the queue */
+ KEVENT NotifyEvent;
+ /** pointer to the packet queue worker thread object */
+ PKTHREAD pThread;
+ /** pointer to the SG used by the packet queue for IntNet receive notifications */
+ PINTNETSG pSG;
+ /** Packet queue */
+ VBOXNETFLT_INTERLOCKED_PACKET_QUEUE PacketQueue;
+ /** Packet info pool, i.e. the pool for the packet queue elements */
+ VBOXNETFLT_PACKET_INFO_POOL PacketInfoPool;
+} VBOXNETFLT_PACKET_QUEUE_WORKER, *PVBOXNETFLT_PACKET_QUEUE_WORKER;
+
+/* protocol reserved data held in ndis packet */
+typedef struct VBOXNETFLT_PKTRSVD_PT
+{
+ /** original packet received from the upperlying protocol
+ * can be null if the packet was originated by intnet */
+ PNDIS_PACKET pOrigPacket;
+ /** pointer to the buffer to be freed on send completion
+ * can be null if no buffer is to be freed */
+ PVOID pBufToFree;
+#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
+ SINGLE_LIST_ENTRY ListEntry;
+ /* true if the packet is from IntNet */
+ bool bFromIntNet;
+#endif
+} VBOXNETFLT_PKTRSVD_PT, *PVBOXNETFLT_PKTRSVD_PT;
+
+/** miniport reserved data held in ndis packet */
+typedef struct VBOXNETFLT_PKTRSVD_MP
+{
+ /** original packet received from the underling miniport
+ * can be null if the packet was originated by intnet */
+ PNDIS_PACKET pOrigPacket;
+ /** pointer to the buffer to be freed on receive completion
+ * can be null if no buffer is to be freed */
+ PVOID pBufToFree;
+} VBOXNETFLT_PKTRSVD_MP, *PVBOXNETFLT_PKTRSVD_MP;
+
+/** represents the data stored in the protocol reserved field of ndis packet on NdisTransferData processing */
+typedef struct VBOXNETFLT_PKTRSVD_TRANSFERDATA_PT
+{
+ /** next packet in a list */
+ SINGLE_LIST_ENTRY ListEntry;
+ /* packet buffer start */
+ PNDIS_BUFFER pOrigBuffer;
+} VBOXNETFLT_PKTRSVD_TRANSFERDATA_PT, *PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT;
+
+/* VBOXNETFLT_PKTRSVD_TRANSFERDATA_PT should fit into PROTOCOL_RESERVED_SIZE_IN_PACKET because we use protocol reserved part
+ * of our miniport edge on transfer data processing for honding our own info */
+AssertCompile(sizeof (VBOXNETFLT_PKTRSVD_TRANSFERDATA_PT) <= PROTOCOL_RESERVED_SIZE_IN_PACKET);
+/* this should fit in MiniportReserved */
+AssertCompile(sizeof (VBOXNETFLT_PKTRSVD_MP) <= RT_SIZEOFMEMB(NDIS_PACKET, MiniportReserved));
+/* we use RTAsmAtomic*U32 for those, make sure we're correct */
+AssertCompile(sizeof (NDIS_DEVICE_POWER_STATE) == sizeof (uint32_t));
+AssertCompile(sizeof (UINT) == sizeof (uint32_t));
+
+
+#define NDIS_FLAGS_SKIP_LOOPBACK_W2K 0x400
+
+#include "../../VBoxNetFltInternal.h"
+#include "VBoxNetFltRt-win.h"
+#ifndef VBOXNETADP
+#include "VBoxNetFltP-win.h"
+#endif
+# include "VBoxNetFltM-win.h"
+
+#ifdef DEBUG_NETFLT_NOASSERT
+# ifdef Assert
+# undef Assert
+# endif
+
+# define Assert(_expr) do {} while (0)
+#endif /* #ifdef DEBUG_NETFLT_NOASSERT */
+
+#endif /* #ifndef ___VBoxNetFltCmn_win_h___ */
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.cpp
new file mode 100644
index 000000000..897dc09c2
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.cpp
@@ -0,0 +1,1552 @@
+/* $Id: VBoxNetFltM-win.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */
+/** @file
+ * VBoxNetFltM-win.cpp - Bridged Networking Driver, Windows Specific Code.
+ * Miniport edge
+ */
+/*
+ * 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.
+ */
+#include "VBoxNetFltCmn-win.h"
+
+static const char* vboxNetFltWinMpDumpOid(ULONG oid);
+
+#ifndef VBOXNETADP
+static NDIS_STATUS vboxNetFltWinMpInitialize(OUT PNDIS_STATUS OpenErrorStatus,
+ OUT PUINT SelectedMediumIndex,
+ IN PNDIS_MEDIUM MediumArray,
+ IN UINT MediumArraySize,
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN NDIS_HANDLE WrapperConfigurationContext)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)NdisIMGetDeviceContext(MiniportAdapterHandle);
+ NDIS_STATUS Status = NDIS_STATUS_FAILURE;
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
+
+ pNetFlt->u.s.WinIf.hMiniport = MiniportAdapterHandle;
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initializing);
+ /* the MP state should be already set to kVBoxNetDevOpState_Initializing, just a paranoia
+ * in case NDIS for some reason calls us in some irregular way */
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initializing);
+
+ NDIS_MEDIUM enmMedium = pNetFlt->u.s.WinIf.enmMedium;
+ if (enmMedium == NdisMediumWan)
+ enmMedium = NdisMedium802_3;
+
+ UINT i = 0;
+ for (; i < MediumArraySize; i++)
+ {
+ if (MediumArray[i] == enmMedium)
+ {
+ *SelectedMediumIndex = i;
+ break;
+ }
+ }
+
+ do
+ {
+ if (i != MediumArraySize)
+ {
+ NdisMSetAttributesEx(MiniportAdapterHandle, pNetFlt, 0,
+ NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT |
+ NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT|
+ NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER |
+ NDIS_ATTRIBUTE_DESERIALIZE |
+ NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
+ NdisInterfaceInternal /* 0 */);
+
+ pNetFlt->u.s.WinIf.MpIndicatedMediaStatus = NDIS_STATUS_MEDIA_CONNECT;
+ Assert(vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) == NdisDeviceStateD3);
+ vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.MpState, NdisDeviceStateD0);
+ Assert(pNetFlt->u.s.WinIf.MpState.OpState == kVBoxNetDevOpState_Initializing);
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initialized);
+
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+ }
+ else
+ {
+ Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
+ }
+
+ Assert(Status != NDIS_STATUS_SUCCESS);
+ Assert(vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) == NdisDeviceStateD3);
+ Assert(pNetFlt->u.s.WinIf.MpState.OpState == kVBoxNetDevOpState_Initializing);
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
+ } while (0);
+
+ NdisSetEvent(&pNetFlt->u.s.WinIf.MpInitCompleteEvent);
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status));
+
+ *OpenErrorStatus = Status;
+
+ return Status;
+}
+
+/**
+ * process the packet send in a "passthru" mode
+ */
+static NDIS_STATUS vboxNetFltWinSendPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ , bool bNetFltActive
+#endif
+ )
+{
+ PNDIS_PACKET pMyPacket;
+ NDIS_STATUS Status = vboxNetFltWinPrepareSendPacket(pNetFlt, pPacket, &pMyPacket);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+#if !defined(VBOX_LOOPBACK_USEFLAGS) /* || defined(DEBUG_NETFLT_PACKETS) */
+# ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ if (bNetFltActive)
+ vboxNetFltWinLbPutSendPacket(pNetFlt, pMyPacket, false /* bFromIntNet */);
+# else
+ /* no need for the loop enqueue & check in a passthru mode , ndis will do everything for us */
+# endif
+#endif
+ NdisSend(&Status, pNetFlt->u.s.WinIf.hBinding, pMyPacket);
+ if (Status != NDIS_STATUS_PENDING)
+ {
+ NdisIMCopySendCompletePerPacketInfo(pPacket, pMyPacket);
+#if defined(VBOXNETFLT_NO_PACKET_QUEUE) && !defined(VBOX_LOOPBACK_USEFLAGS)
+ if (bNetFltActive)
+ vboxNetFltWinLbRemoveSendPacket(pNetFlt, pMyPacket);
+#endif
+ NdisFreePacket(pMyPacket);
+ }
+ }
+ return Status;
+}
+
+#else /* defined VBOXNETADP */
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoDeinitialization(PVBOXNETFLTINS pNetFlt)
+{
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+ uint64_t NanoTS = RTTimeSystemNanoTS();
+
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized);
+
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
+ ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true);
+ ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false);
+ ASMAtomicUoWriteU64(&pNetFlt->NanoTSLastRediscovery, NanoTS);
+
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing);
+
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+
+ vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState);
+
+ /* check packet pool is empty */
+ int cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool);
+ Assert(cPPUsage == 0);
+ /* for debugging only, ignore the err in release */
+ NOREF(cPPUsage);
+
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+static NDIS_STATUS vboxNetFltWinMpReadApplyConfig(PVBOXNETFLTINS pThis, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext)
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ NDIS_HANDLE hConfiguration;
+ PNDIS_CONFIGURATION_PARAMETER pParameterValue;
+ NDIS_STRING strMAC = NDIS_STRING_CONST("MAC");
+ RTMAC mac;
+
+ NdisOpenConfiguration(
+ &Status,
+ &hConfiguration,
+ hWrapperConfigurationContext);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ do
+ {
+ int rc;
+ NDIS_CONFIGURATION_PARAMETER param;
+ WCHAR MacBuf[13];
+
+ NdisReadConfiguration(&Status,
+ &pParameterValue,
+ hConfiguration,
+ &strMAC,
+ NdisParameterString);
+// Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+
+ rc = vboxNetFltWinMACFromNdisString(&mac, &pParameterValue->ParameterData.StringData);
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ {
+ break;
+ }
+ }
+
+ vboxNetFltWinGenerateMACAddress(&mac);
+ param.ParameterType = NdisParameterString;
+ param.ParameterData.StringData.Buffer = MacBuf;
+ param.ParameterData.StringData.MaximumLength = sizeof(MacBuf);
+
+ rc = vboxNetFltWinMAC2NdisString(&mac, &param.ParameterData.StringData);
+ Assert(RT_SUCCESS(rc));
+ if (RT_SUCCESS(rc))
+ {
+ NdisWriteConfiguration(&Status,
+ hConfiguration,
+ &strMAC,
+ &param);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ /* ignore the failure */
+ Status = NDIS_STATUS_SUCCESS;
+ }
+ }
+ } while (0);
+
+ NdisCloseConfiguration(hConfiguration);
+ }
+ else
+ {
+ vboxNetFltWinGenerateMACAddress(&mac);
+ }
+
+ pThis->u.s.MacAddr = mac;
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoInitialization(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext)
+{
+ NDIS_STATUS Status;
+ pNetFlt->u.s.WinIf.hMiniport = hMiniportAdapter;
+
+ LogFlow(("==>"__FUNCTION__" : pNetFlt 0x%p\n", pNetFlt));
+
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initializing);
+
+ vboxNetFltWinMpReadApplyConfig(pNetFlt, hMiniportAdapter, hWrapperConfigurationContext);
+
+ NdisMSetAttributesEx(hMiniportAdapter, pNetFlt,
+ 0, /* CheckForHangTimeInSeconds */
+ NDIS_ATTRIBUTE_DESERIALIZE |
+ NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
+ NdisInterfaceInternal/* 0 */);
+
+ Assert(vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) == NdisDeviceStateD3);
+ vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.MpState, NdisDeviceStateD0);
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initializing);
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initialized);
+
+ Status = NDIS_STATUS_SUCCESS;
+
+ LogFlow(("<=="__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", pNetFlt, Status));
+
+ return Status;
+}
+
+static NDIS_STATUS vboxNetFltWinMpInitialize(OUT PNDIS_STATUS OpenErrorStatus,
+ OUT PUINT SelectedMediumIndex,
+ IN PNDIS_MEDIUM MediumArray,
+ IN UINT MediumArraySize,
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN NDIS_HANDLE WrapperConfigurationContext)
+{
+
+ NDIS_STATUS Status = NDIS_STATUS_FAILURE;
+ UINT i = 0;
+
+ LogFlow(("==>"__FUNCTION__"\n"));
+
+ for (; i < MediumArraySize; i++)
+ {
+ if (MediumArray[i] == NdisMedium802_3)
+ {
+ *SelectedMediumIndex = i;
+ break;
+ }
+ }
+
+ if (i != MediumArraySize)
+ {
+ PDEVICE_OBJECT pPdo, pFdo;
+#define KEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"
+ UCHAR Buf[512];
+ PUCHAR pSuffix;
+ ULONG cbBuf;
+ NDIS_STRING RtlStr;
+
+ wcscpy((WCHAR*)Buf, KEY_PREFIX);
+ pSuffix = Buf + (sizeof(KEY_PREFIX)-2);
+
+ NdisMGetDeviceProperty(MiniportAdapterHandle,
+ &pPdo,
+ &pFdo,
+ NULL, //Next Device Object
+ NULL,
+ NULL);
+
+ Status = IoGetDeviceProperty (pPdo,
+ DevicePropertyDriverKeyName,
+ sizeof(Buf) - (sizeof(KEY_PREFIX)-2),
+ pSuffix,
+ &cbBuf);
+ if (Status == STATUS_SUCCESS)
+ {
+ OBJECT_ATTRIBUTES ObjAttr;
+ HANDLE hDrvKey;
+ RtlStr.Buffer=(WCHAR*)Buf;
+ RtlStr.Length=(USHORT)cbBuf - 2 + sizeof(KEY_PREFIX) - 2;
+ RtlStr.MaximumLength=sizeof(Buf);
+
+ InitializeObjectAttributes(&ObjAttr, &RtlStr, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+ Status = ZwOpenKey(&hDrvKey, KEY_READ, &ObjAttr);
+ if (Status == STATUS_SUCCESS)
+ {
+ static UNICODE_STRING NetCfgInstanceIdValue = NDIS_STRING_CONST("NetCfgInstanceId");
+// UCHAR valBuf[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + RTUUID_STR_LENGTH*2 + 10];
+// ULONG cLength = sizeof(valBuf);
+#define NAME_PREFIX L"\\DEVICE\\"
+ PKEY_VALUE_PARTIAL_INFORMATION pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
+ Status = ZwQueryValueKey(hDrvKey,
+ &NetCfgInstanceIdValue,
+ KeyValuePartialInformation,
+ pInfo,
+ sizeof(Buf),
+ &cbBuf);
+ if (Status == STATUS_SUCCESS)
+ {
+ if (pInfo->Type == REG_SZ && pInfo->DataLength > 2)
+ {
+ WCHAR *pName;
+ Status = vboxNetFltWinMemAlloc((PVOID*)&pName, pInfo->DataLength + sizeof(NAME_PREFIX));
+ if (Status == STATUS_SUCCESS)
+ {
+ PVBOXNETFLTINS pNetFlt;
+ wcscpy(pName, NAME_PREFIX);
+ wcscpy(pName+(sizeof(NAME_PREFIX)-2)/2, (WCHAR*)pInfo->Data);
+ RtlStr.Buffer=pName;
+ RtlStr.Length = (USHORT)pInfo->DataLength - 2 + sizeof(NAME_PREFIX) - 2;
+ RtlStr.MaximumLength = (USHORT)pInfo->DataLength + sizeof(NAME_PREFIX);
+
+ Status = vboxNetFltWinPtInitBind(&pNetFlt, MiniportAdapterHandle, &RtlStr, WrapperConfigurationContext);
+
+ if (Status == STATUS_SUCCESS)
+ {
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized);
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initialized);
+#if 0
+ NdisMIndicateStatus(pNetFlt->u.s.WinIf.hMiniport,
+ NDIS_STATUS_MEDIA_CONNECT,
+ (PVOID)NULL,
+ 0);
+#endif
+ }
+ else
+ {
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
+ }
+
+ vboxNetFltWinMemFree(pName);
+
+ }
+ }
+ else
+ {
+ Status = NDIS_STATUS_FAILURE;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
+ }
+
+ /* TODO: */
+ *OpenErrorStatus = Status;
+
+ LogFlow(("<=="__FUNCTION__": Status (0x%x)\n", Status));
+
+ return Status;
+}
+#endif
+
+static VOID vboxNetFltWinMpSendPackets(IN NDIS_HANDLE hMiniportAdapterContext,
+ IN PPNDIS_PACKET pPacketArray,
+ IN UINT cNumberOfPackets)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hMiniportAdapterContext;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ bool bNetFltActive;
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
+
+ Assert(cNumberOfPackets);
+
+ if (vboxNetFltWinIncReferenceWinIfNetFlt(pNetFlt, cNumberOfPackets, &bNetFltActive))
+ {
+ uint32_t cAdaptRefs = cNumberOfPackets;
+ uint32_t cNetFltRefs;
+ uint32_t cPassThruRefs;
+ if (bNetFltActive)
+ {
+ cNetFltRefs = cNumberOfPackets;
+ cPassThruRefs = 0;
+ }
+ else
+ {
+ cPassThruRefs = cNumberOfPackets;
+ cNetFltRefs = 0;
+ }
+
+ for (UINT i = 0; i < cNumberOfPackets; i++)
+ {
+ PNDIS_PACKET pPacket;
+
+ pPacket = pPacketArray[i];
+
+ if (!cNetFltRefs
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ || !vboxNetFltWinPostIntnet(pNetFlt, pPacket, VBOXNETFLT_PACKET_SRC_HOST)
+#else
+ || (fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, VBOXNETFLT_PACKET_SRC_HOST)) != NDIS_STATUS_SUCCESS
+#endif
+ )
+ {
+#ifndef VBOXNETADP
+ Status = vboxNetFltWinSendPassThru(pNetFlt, pPacket
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ , !!cNetFltRefs
+#endif
+ );
+#else
+ if (!cNetFltRefs)
+ {
+# ifdef VBOXNETADP_REPORT_DISCONNECTED
+ Status = NDIS_STATUS_MEDIA_DISCONNECT;
+ STATISTIC_INCREASE(pNetFlt->u.s.WinIf.cTxError);
+# else
+ Status = NDIS_STATUS_SUCCESS;
+# endif
+ }
+#endif
+
+ if (Status != NDIS_STATUS_PENDING)
+ {
+ NdisMSendComplete(pNetFlt->u.s.WinIf.hMiniport, pPacket, Status);
+ }
+ else
+ {
+ cAdaptRefs--;
+ }
+ }
+ else
+ {
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ NdisMSendComplete(pNetFlt->u.s.WinIf.hMiniport, pPacket, NDIS_STATUS_SUCCESS);
+#else
+ cAdaptRefs--;
+ cNetFltRefs--;
+#endif
+ }
+ }
+
+ if (cNetFltRefs)
+ {
+ vboxNetFltWinDecReferenceNetFlt(pNetFlt, cNetFltRefs);
+ }
+ else if (cPassThruRefs)
+ {
+ vboxNetFltWinDecReferenceModePassThru(pNetFlt, cPassThruRefs);
+ }
+ if (cAdaptRefs)
+ {
+ vboxNetFltWinDecReferenceWinIf(pNetFlt, cAdaptRefs);
+ }
+ }
+ else
+ {
+ NDIS_HANDLE h = pNetFlt->u.s.WinIf.hMiniport;
+ Assert(0);
+ if (h)
+ {
+ for (UINT i = 0; i < cNumberOfPackets; i++)
+ {
+ PNDIS_PACKET pPacket;
+ pPacket = pPacketArray[i];
+ NdisMSendComplete(h, pPacket, NDIS_STATUS_FAILURE);
+ }
+ }
+ }
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
+}
+
+#ifndef VBOXNETADP
+static UINT vboxNetFltWinMpRequestStatePrep(PVBOXNETFLTINS pNetFlt, NDIS_STATUS *pStatus)
+{
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+
+ Assert(!pNetFlt->u.s.WinIf.StateFlags.fRequestInfo);
+
+ if (vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) > kVBoxNetDevOpState_Initialized /* protocol unbind in progress */
+ || vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) > NdisDeviceStateD0)
+ {
+ *pStatus = NDIS_STATUS_FAILURE;
+ return 0;
+ }
+
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
+ Assert(!pNetFlt->u.s.WinIf.StateFlags.fRequestInfo);
+ if (vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) > kVBoxNetDevOpState_Initialized /* protocol unbind in progress */
+ || vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) > NdisDeviceStateD0)
+ {
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+ *pStatus = NDIS_STATUS_FAILURE;
+ return 0;
+ }
+
+ if ((vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState) > NdisDeviceStateD0)
+ && !pNetFlt->u.s.WinIf.StateFlags.fStandBy)
+ {
+ pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS | VBOXNDISREQUEST_QUEUED;
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+ *pStatus = NDIS_STATUS_PENDING;
+ return VBOXNDISREQUEST_INPROGRESS | VBOXNDISREQUEST_QUEUED;
+ }
+
+ if (pNetFlt->u.s.WinIf.StateFlags.fStandBy)
+ {
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+ *pStatus = NDIS_STATUS_FAILURE;
+ return 0;
+ }
+
+ pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS;
+
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+
+ *pStatus = NDIS_STATUS_SUCCESS;
+ return VBOXNDISREQUEST_INPROGRESS;
+}
+
+static NDIS_STATUS vboxNetFltWinMpRequestPostQuery(PVBOXNETFLTINS pNetFlt)
+{
+ if (pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt))
+ {
+ bool fNetFltActive;
+ const bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &fNetFltActive);
+
+ Assert(pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.InformationBuffer);
+ Assert(!pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter);
+
+ if (fNetFltActive)
+ {
+ /* netflt is active, simply return the cached value */
+ *((PULONG)pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.InformationBuffer) = pNetFlt->u.s.WinIf.fUpperProtocolSetFilter;
+
+ /* we've intercepted the query and completed it */
+ vboxNetFltWinMpRequestStateComplete(pNetFlt);
+
+ vboxNetFltWinDereferenceNetFlt(pNetFlt);
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+
+ return NDIS_STATUS_SUCCESS;
+ }
+ else if (fWinIfActive)
+ {
+ pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 1;
+ pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 0;
+ /* we're cleaning it in RequestComplete */
+ }
+ }
+
+ NDIS_STATUS Status;
+ /* issue the request */
+ NdisRequest(&Status, pNetFlt->u.s.WinIf.hBinding, &pNetFlt->u.s.WinIf.PassDownRequest);
+ if (Status != NDIS_STATUS_PENDING)
+ {
+ vboxNetFltWinPtRequestComplete(pNetFlt, &pNetFlt->u.s.WinIf.PassDownRequest, Status);
+ Status = NDIS_STATUS_PENDING;
+ }
+
+ return Status;
+}
+
+static NDIS_STATUS vboxNetFltWinMpQueryInformation(IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesWritten,
+ OUT PULONG BytesNeeded)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)MiniportAdapterContext;
+ NDIS_STATUS Status = NDIS_STATUS_FAILURE;
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Oid (%s)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid)));
+
+ /* fist check if this is the oid we want to pass down */
+ switch (Oid)
+ {
+ case OID_PNP_QUERY_POWER:
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+ case OID_TCP_TASK_OFFLOAD:
+ case OID_GEN_SUPPORTED_GUIDS:
+ Status = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ default:
+ {
+ /* the oid is to be passed down,
+ * check the device state if we can do it
+ * and update device state accordingly */
+ UINT uOp = vboxNetFltWinMpRequestStatePrep(pNetFlt, &Status);
+ if (uOp)
+ {
+ /* save the request info */
+ pNetFlt->u.s.WinIf.PassDownRequest.RequestType = NdisRequestQueryInformation;
+ pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.Oid = Oid;
+ pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;
+ pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;
+ pNetFlt->u.s.WinIf.pcPDRBytesNeeded = BytesNeeded;
+ pNetFlt->u.s.WinIf.pcPDRBytesRW = BytesWritten;
+
+ /* the oid can be processed */
+ if (!(uOp & VBOXNDISREQUEST_QUEUED))
+ {
+ Status = vboxNetFltWinMpRequestPostQuery(pNetFlt);
+ }
+ }
+ break;
+ }
+ }
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Oid (%s), Status (0x%x)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid), Status));
+
+ return Status;
+}
+
+#endif /* ifndef VBOXNETADP*/
+
+static NDIS_STATUS vboxNetFltWinMpHandlePowerState(PVBOXNETFLTINS pNetFlt, NDIS_DEVICE_POWER_STATE enmState)
+{
+ if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) > NdisDeviceStateD0
+ && enmState != NdisDeviceStateD0)
+ {
+ /* invalid state transformation */
+ Assert(0);
+ return NDIS_STATUS_FAILURE;
+ }
+
+#ifndef VBOXNETADP
+ if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) == NdisDeviceStateD0
+ && enmState > NdisDeviceStateD0)
+ {
+ pNetFlt->u.s.WinIf.StateFlags.fStandBy = TRUE;
+ }
+
+ if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) > NdisDeviceStateD0
+ && enmState == NdisDeviceStateD0)
+ {
+ pNetFlt->u.s.WinIf.StateFlags.fStandBy = FALSE;
+ }
+#endif
+
+ vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.MpState, enmState);
+
+#ifndef VBOXNETADP
+ if (pNetFlt->u.s.WinIf.StateFlags.fStandBy == FALSE)
+ {
+ if (pNetFlt->u.s.WinIf.MpIndicatedMediaStatus != pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus)
+ {
+ NdisMIndicateStatus(pNetFlt->u.s.WinIf.hMiniport, pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus, NULL, 0);
+ NdisMIndicateStatusComplete(pNetFlt->u.s.WinIf.hMiniport);
+ pNetFlt->u.s.WinIf.MpIndicatedMediaStatus = pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus;
+ }
+ }
+ else
+ {
+ pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus = pNetFlt->u.s.WinIf.MpIndicatedMediaStatus;
+ }
+#endif
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+#ifndef VBOXNETADP
+static NDIS_STATUS vboxNetFltWinMpRequestPostSet(PVBOXNETFLTINS pNetFlt)
+{
+ if (pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt))
+ {
+ /* need to disable cleaning promiscuous here ?? */
+ bool fNetFltActive;
+ const bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &fNetFltActive);
+
+ Assert(pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBuffer);
+ Assert(!pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter);
+
+ if (fNetFltActive)
+ {
+ Assert(fWinIfActive);
+
+ /* netflt is active, update the cached value */
+ /* TODO: in case we are are not in promiscuous now, we are issuing a request.
+ * what should we do in case of a failure?
+ * i.e. should we update the fUpperProtocolSetFilter in completion routine in this case? etc. */
+ pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = *((PULONG)pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBuffer);
+ pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE;
+
+ if (!(pNetFlt->u.s.WinIf.fOurSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS))
+ {
+ pNetFlt->u.s.WinIf.fSetFilterBuffer = NDIS_PACKET_TYPE_PROMISCUOUS;
+ pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBuffer = &pNetFlt->u.s.WinIf.fSetFilterBuffer;
+ pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBufferLength = sizeof (pNetFlt->u.s.WinIf.fSetFilterBuffer);
+ pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 1;
+ pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 1;
+ /* we'll do dereferencing in request complete */
+ }
+ else
+ {
+ vboxNetFltWinDereferenceNetFlt(pNetFlt);
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+
+ /* we've intercepted the query and completed it */
+ vboxNetFltWinMpRequestStateComplete(pNetFlt);
+ return NDIS_STATUS_SUCCESS;
+ }
+ }
+ else if (fWinIfActive)
+ {
+ pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 1;
+ pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 0;
+ /* dereference on completion */
+ }
+ }
+
+ NDIS_STATUS Status;
+
+ NdisRequest(&Status, pNetFlt->u.s.WinIf.hBinding, &pNetFlt->u.s.WinIf.PassDownRequest);
+ if (Status != NDIS_STATUS_PENDING)
+ {
+ vboxNetFltWinPtRequestComplete(pNetFlt, &pNetFlt->u.s.WinIf.PassDownRequest, Status);
+ }
+
+ return Status;
+}
+
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpRequestPost(PVBOXNETFLTINS pNetFlt)
+{
+ switch (pNetFlt->u.s.WinIf.PassDownRequest.RequestType)
+ {
+ case NdisRequestQueryInformation:
+ return vboxNetFltWinMpRequestPostQuery(pNetFlt);
+ case NdisRequestSetInformation:
+ return vboxNetFltWinMpRequestPostSet(pNetFlt);
+ default:
+ AssertBreakpoint();
+ return NDIS_STATUS_FAILURE;
+ }
+}
+
+static NDIS_STATUS vboxNetFltWinMpSetInformation(IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesRead,
+ OUT PULONG BytesNeeded)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)MiniportAdapterContext;
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+ NDIS_STATUS Status = NDIS_STATUS_FAILURE;
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Oid (%s)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid)));
+
+ switch (Oid)
+ {
+ case OID_PNP_SET_POWER:
+ {
+ if (InformationBufferLength >= sizeof (NDIS_DEVICE_POWER_STATE))
+ {
+ NDIS_DEVICE_POWER_STATE *penmState = (NDIS_DEVICE_POWER_STATE*)InformationBuffer;
+ Status = vboxNetFltWinMpHandlePowerState(pNetFlt, *penmState);
+ }
+ else
+ {
+ Status = NDIS_STATUS_INVALID_LENGTH;
+ }
+
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ *BytesRead = sizeof (NDIS_DEVICE_POWER_STATE);
+ *BytesNeeded = 0;
+ }
+ else
+ {
+ *BytesRead = 0;
+ *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
+ }
+ break;
+ }
+ default:
+ {
+ /* the oid is to be passed down,
+ * check the device state if we can do it
+ * and update device state accordingly */
+ UINT uOp = vboxNetFltWinMpRequestStatePrep(pNetFlt, &Status);
+ if (uOp)
+ {
+ /* save the request info */
+ pNetFlt->u.s.WinIf.PassDownRequest.RequestType = NdisRequestSetInformation;
+ pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.Oid = Oid;
+ pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBuffer = InformationBuffer;
+ pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength;
+ pNetFlt->u.s.WinIf.pcPDRBytesNeeded = BytesNeeded;
+ pNetFlt->u.s.WinIf.pcPDRBytesRW = BytesRead;
+
+ /* the oid can be processed */
+ if (!(uOp & VBOXNDISREQUEST_QUEUED))
+ {
+ Status = vboxNetFltWinMpRequestPostSet(pNetFlt);
+ }
+ }
+ break;
+ }
+ }
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Oid (%s), Status (0x%x)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid), Status));
+
+ return Status;
+}
+#else
+static NDIS_OID g_vboxNetFltWinMpSupportedOids[] =
+{
+ OID_GEN_SUPPORTED_LIST,
+ OID_GEN_HARDWARE_STATUS,
+ OID_GEN_MEDIA_SUPPORTED,
+ OID_GEN_MEDIA_IN_USE,
+ OID_GEN_MAXIMUM_LOOKAHEAD,
+ OID_GEN_CURRENT_LOOKAHEAD,
+ OID_GEN_MAXIMUM_FRAME_SIZE,
+ OID_GEN_MAXIMUM_TOTAL_SIZE,
+ OID_GEN_TRANSMIT_BLOCK_SIZE,
+ OID_GEN_RECEIVE_BLOCK_SIZE,
+ OID_GEN_MAC_OPTIONS,
+ OID_GEN_LINK_SPEED,
+ OID_GEN_TRANSMIT_BUFFER_SPACE,
+ OID_GEN_RECEIVE_BUFFER_SPACE,
+ OID_GEN_VENDOR_ID,
+ OID_GEN_VENDOR_DESCRIPTION,
+ OID_GEN_VENDOR_DRIVER_VERSION,
+ OID_GEN_DRIVER_VERSION,
+ OID_GEN_MAXIMUM_SEND_PACKETS,
+ OID_GEN_MEDIA_CONNECT_STATUS,
+ OID_GEN_CURRENT_PACKET_FILTER,
+ OID_PNP_CAPABILITIES,
+ OID_PNP_QUERY_POWER,
+ OID_GEN_XMIT_OK,
+ OID_GEN_RCV_OK,
+ OID_GEN_XMIT_ERROR,
+ OID_GEN_RCV_ERROR,
+ OID_GEN_RCV_NO_BUFFER,
+ OID_GEN_RCV_CRC_ERROR,
+ OID_GEN_TRANSMIT_QUEUE_LENGTH,
+ OID_PNP_SET_POWER,
+ OID_802_3_PERMANENT_ADDRESS,
+ OID_802_3_CURRENT_ADDRESS,
+ OID_802_3_MULTICAST_LIST,
+ OID_802_3_MAC_OPTIONS,
+ OID_802_3_MAXIMUM_LIST_SIZE,
+ OID_802_3_RCV_ERROR_ALIGNMENT,
+ OID_802_3_XMIT_ONE_COLLISION,
+ OID_802_3_XMIT_MORE_COLLISIONS,
+ OID_802_3_XMIT_DEFERRED,
+ OID_802_3_XMIT_MAX_COLLISIONS,
+ OID_802_3_RCV_OVERRUN,
+ OID_802_3_XMIT_UNDERRUN,
+ OID_802_3_XMIT_HEARTBEAT_FAILURE,
+ OID_802_3_XMIT_TIMES_CRS_LOST,
+ OID_802_3_XMIT_LATE_COLLISIONS,
+};
+
+static NDIS_STATUS vboxNetFltWinMpQueryInformation(IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesWritten,
+ OUT PULONG BytesNeeded)
+{
+ /* static data */
+ static const NDIS_HARDWARE_STATUS enmHwStatus = NdisHardwareStatusReady;
+ static const NDIS_MEDIUM enmMedium = NdisMedium802_3;
+ static NDIS_PNP_CAPABILITIES PnPCaps = {0};
+ static BOOLEAN bPnPCapsInited = FALSE;
+
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)MiniportAdapterContext;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ ULONG64 u64Info = 0;
+ ULONG u32Info = 0;
+ USHORT u16Info = 0;
+ /* default is 4bytes */
+ const void* pvInfo = (void*)&u32Info;
+ ULONG cbInfo = sizeof (u32Info);
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Oid (%s)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid)));
+
+ *BytesWritten = 0;
+ *BytesNeeded = 0;
+
+ switch (Oid)
+ {
+ case OID_GEN_SUPPORTED_LIST:
+ pvInfo = g_vboxNetFltWinMpSupportedOids;
+ cbInfo = sizeof (g_vboxNetFltWinMpSupportedOids);
+ break;
+
+ case OID_GEN_HARDWARE_STATUS:
+ pvInfo = &enmHwStatus;
+ cbInfo = sizeof (NDIS_HARDWARE_STATUS);
+ break;
+
+ case OID_GEN_MEDIA_SUPPORTED:
+ case OID_GEN_MEDIA_IN_USE:
+ pvInfo = &enmMedium;
+ cbInfo = sizeof (NDIS_MEDIUM);
+ break;
+
+ case OID_GEN_MAXIMUM_LOOKAHEAD:
+ case OID_GEN_CURRENT_LOOKAHEAD:
+ u32Info = VBOXNETADP_MAX_LOOKAHEAD_SIZE;
+ break;
+
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+ u32Info = VBOXNETADP_MAX_PACKET_SIZE - VBOXNETADP_HEADER_SIZE;
+ break;
+
+ case OID_GEN_MAXIMUM_TOTAL_SIZE:
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+ u32Info = VBOXNETADP_MAX_PACKET_SIZE;
+ break;
+
+ case OID_GEN_MAC_OPTIONS:
+ u32Info = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
+ NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
+ NDIS_MAC_OPTION_NO_LOOPBACK;
+ break;
+
+ case OID_GEN_LINK_SPEED:
+ u32Info = VBOXNETADP_LINK_SPEED;
+ break;
+
+ case OID_GEN_TRANSMIT_BUFFER_SPACE:
+ case OID_GEN_RECEIVE_BUFFER_SPACE:
+ u32Info = VBOXNETADP_MAX_PACKET_SIZE * VBOXNETFLT_PACKET_INFO_POOL_SIZE;
+ break;
+
+ case OID_GEN_VENDOR_ID:
+ u32Info = VBOXNETADP_VENDOR_ID;
+ break;
+
+ case OID_GEN_VENDOR_DESCRIPTION:
+ pvInfo = VBOXNETADP_VENDOR_DESC;
+ cbInfo = sizeof (VBOXNETADP_VENDOR_DESC);
+ break;
+
+ case OID_GEN_VENDOR_DRIVER_VERSION:
+ u32Info = VBOXNETADP_VENDOR_DRIVER_VERSION;
+ break;
+
+ case OID_GEN_DRIVER_VERSION:
+ u16Info = (USHORT)((VBOXNETFLT_VERSION_MP_NDIS_MAJOR << 8) + VBOXNETFLT_VERSION_MP_NDIS_MINOR);
+ pvInfo = (PVOID)&u16Info;
+ cbInfo = sizeof (USHORT);
+ break;
+
+ case OID_GEN_MAXIMUM_SEND_PACKETS:
+ u32Info = VBOXNETFLT_PACKET_INFO_POOL_SIZE;
+ break;
+
+ case OID_GEN_MEDIA_CONNECT_STATUS:
+#ifdef VBOXNETADP_REPORT_DISCONNECTED
+ {
+ bool bNetFltActive;
+ bool bActive = vboxNetFltWinReferenceWinIfNetFltFromAdapt(pNetFlt, bNetFltActive);
+ if (bActive && bNetFltActive)
+ {
+ u32Info = NdisMediaStateConnected;
+ }
+ else
+ {
+ u32Info = NdisMediaStateDisconnected;
+ }
+
+ if (bActive)
+ {
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+ }
+ if (bNetFltActive)
+ {
+ vboxNetFltWinDereferenceNetFlt(pNetFlt);
+ }
+ else
+ {
+ vboxNetFltWinDereferenceModePassThru(pNetFlt);
+ }
+ }
+#else
+ u32Info = NdisMediaStateConnected;
+#endif
+ break;
+
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ u32Info = NDIS_PACKET_TYPE_BROADCAST
+ | NDIS_PACKET_TYPE_DIRECTED
+ | NDIS_PACKET_TYPE_ALL_FUNCTIONAL
+ | NDIS_PACKET_TYPE_ALL_LOCAL
+ | NDIS_PACKET_TYPE_GROUP
+ | NDIS_PACKET_TYPE_MULTICAST;
+ break;
+
+ case OID_PNP_CAPABILITIES:
+ if (!bPnPCapsInited)
+ {
+ PnPCaps.WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
+ PnPCaps.WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified;
+ bPnPCapsInited = TRUE;
+ }
+ cbInfo = sizeof (NDIS_PNP_CAPABILITIES);
+ pvInfo = &PnPCaps;
+
+ break;
+
+ case OID_PNP_QUERY_POWER:
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_GEN_XMIT_OK:
+ u64Info = pNetFlt->u.s.WinIf.cTxSuccess;
+ pvInfo = &u64Info;
+ if (InformationBufferLength >= sizeof (ULONG64) || InformationBufferLength == 0)
+ {
+ cbInfo = sizeof (ULONG64);
+ }
+ else
+ {
+ cbInfo = sizeof (ULONG);
+ }
+ *BytesNeeded = sizeof (ULONG64);
+ break;
+
+ case OID_GEN_RCV_OK:
+ u64Info = pNetFlt->u.s.WinIf.cRxSuccess;
+ pvInfo = &u64Info;
+ if (InformationBufferLength >= sizeof (ULONG64) || InformationBufferLength == 0)
+ {
+ cbInfo = sizeof (ULONG64);
+ }
+ else
+ {
+ cbInfo = sizeof (ULONG);
+ }
+ *BytesNeeded = sizeof (ULONG64);
+ break;
+
+ case OID_GEN_XMIT_ERROR:
+ u32Info = pNetFlt->u.s.WinIf.cTxError;
+ break;
+
+ case OID_GEN_RCV_ERROR:
+ u32Info = pNetFlt->u.s.WinIf.cRxError;
+ break;
+
+ case OID_GEN_RCV_NO_BUFFER:
+ case OID_GEN_RCV_CRC_ERROR:
+ u32Info = 0;
+ break;
+
+ case OID_GEN_TRANSMIT_QUEUE_LENGTH:
+ u32Info = VBOXNETFLT_PACKET_INFO_POOL_SIZE;
+ break;
+
+ case OID_802_3_PERMANENT_ADDRESS:
+ pvInfo = &pNetFlt->u.s.MacAddr;
+ cbInfo = VBOXNETADP_ETH_ADDRESS_LENGTH;
+ break;
+
+ case OID_802_3_CURRENT_ADDRESS:
+ pvInfo = &pNetFlt->u.s.MacAddr;
+ cbInfo = VBOXNETADP_ETH_ADDRESS_LENGTH;
+ break;
+
+ case OID_802_3_MAXIMUM_LIST_SIZE:
+ u32Info = VBOXNETADP_MAX_MCAST_LIST;
+ break;
+
+ case OID_802_3_MAC_OPTIONS:
+ case OID_802_3_RCV_ERROR_ALIGNMENT:
+ case OID_802_3_XMIT_ONE_COLLISION:
+ case OID_802_3_XMIT_MORE_COLLISIONS:
+ case OID_802_3_XMIT_DEFERRED:
+ case OID_802_3_XMIT_MAX_COLLISIONS:
+ case OID_802_3_RCV_OVERRUN:
+ case OID_802_3_XMIT_UNDERRUN:
+ case OID_802_3_XMIT_HEARTBEAT_FAILURE:
+ case OID_802_3_XMIT_TIMES_CRS_LOST:
+ case OID_802_3_XMIT_LATE_COLLISIONS:
+ u32Info = 0;
+ break;
+
+ default:
+ Status = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ if (cbInfo <= InformationBufferLength)
+ {
+ *BytesWritten = cbInfo;
+ if (cbInfo)
+ NdisMoveMemory(InformationBuffer, pvInfo, cbInfo);
+ }
+ else
+ {
+ *BytesNeeded = cbInfo;
+ Status = NDIS_STATUS_INVALID_LENGTH;
+ }
+ }
+
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Oid (%s), Status (0x%x)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid), Status));
+
+ return Status;
+}
+
+static NDIS_STATUS vboxNetFltWinMpSetInformation(IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesRead,
+ OUT PULONG BytesNeeded)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS) MiniportAdapterContext;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Oid (%s)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid)));
+
+ *BytesRead = 0;
+ *BytesNeeded = 0;
+
+ switch (Oid)
+ {
+ case OID_802_3_MULTICAST_LIST:
+ *BytesRead = InformationBufferLength;
+ if (InformationBufferLength % VBOXNETADP_ETH_ADDRESS_LENGTH)
+ {
+ Status = NDIS_STATUS_INVALID_LENGTH;
+ break;
+ }
+
+ if (InformationBufferLength > (VBOXNETADP_MAX_MCAST_LIST * VBOXNETADP_ETH_ADDRESS_LENGTH))
+ {
+ Status = NDIS_STATUS_MULTICAST_FULL;
+ *BytesNeeded = VBOXNETADP_MAX_MCAST_LIST * VBOXNETADP_ETH_ADDRESS_LENGTH;
+ break;
+ }
+ break;
+
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ if (InformationBufferLength != sizeof (ULONG))
+ {
+ *BytesNeeded = sizeof (ULONG);
+ Status = NDIS_STATUS_INVALID_LENGTH;
+ break;
+ }
+
+ *BytesRead = InformationBufferLength;
+
+ break;
+
+ case OID_GEN_CURRENT_LOOKAHEAD:
+ if (InformationBufferLength != sizeof (ULONG)){
+ *BytesNeeded = sizeof(ULONG);
+ Status = NDIS_STATUS_INVALID_LENGTH;
+ break;
+ }
+
+ break;
+
+ case OID_PNP_SET_POWER:
+ if (InformationBufferLength >= sizeof(NDIS_DEVICE_POWER_STATE))
+ {
+ NDIS_DEVICE_POWER_STATE *penmState = (NDIS_DEVICE_POWER_STATE*)InformationBuffer;
+ Status = vboxNetFltWinMpHandlePowerState(pNetFlt, *penmState);
+ }
+ else
+ {
+ Status = NDIS_STATUS_INVALID_LENGTH;
+ }
+
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ *BytesRead = sizeof (NDIS_DEVICE_POWER_STATE);
+ *BytesNeeded = 0;
+ }
+ else
+ {
+ *BytesRead = 0;
+ *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
+ }
+ break;
+
+ default:
+ Status = NDIS_STATUS_INVALID_OID;
+ break;
+ }
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Oid (%s), Status (0x%x)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid), Status));
+
+ return Status;
+}
+
+#endif
+
+#define VBOXNETFLTDUMP_STRCASE(_t) \
+ case _t: return #_t;
+#define VBOXNETFLTDUMP_STRCASE_UNKNOWN() \
+ default: /*Assert(0);*/ return "Unknown";
+
+static const char* vboxNetFltWinMpDumpOid(ULONG oid)
+{
+ switch (oid)
+ {
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_SUPPORTED_LIST)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_HARDWARE_STATUS)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_SUPPORTED)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_IN_USE)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MAXIMUM_LOOKAHEAD)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MAXIMUM_FRAME_SIZE)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_LINK_SPEED)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_TRANSMIT_BUFFER_SPACE)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_RECEIVE_BUFFER_SPACE)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_TRANSMIT_BLOCK_SIZE)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_RECEIVE_BLOCK_SIZE)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_VENDOR_ID)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_VENDOR_DESCRIPTION)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_CURRENT_PACKET_FILTER)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_CURRENT_LOOKAHEAD)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_DRIVER_VERSION)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MAXIMUM_TOTAL_SIZE)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_PROTOCOL_OPTIONS)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MAC_OPTIONS)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_CONNECT_STATUS)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MAXIMUM_SEND_PACKETS)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_VENDOR_DRIVER_VERSION)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_SUPPORTED_GUIDS)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_NETWORK_LAYER_ADDRESSES)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_TRANSPORT_HEADER_OFFSET)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MACHINE_NAME)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_RNDIS_CONFIG_PARAMETER)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_VLAN_ID)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_CAPABILITIES)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_PHYSICAL_MEDIUM)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_XMIT_OK)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_RCV_OK)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_XMIT_ERROR)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_RCV_ERROR)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_RCV_NO_BUFFER)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_DIRECTED_BYTES_XMIT)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_DIRECTED_FRAMES_XMIT)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MULTICAST_BYTES_XMIT)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MULTICAST_FRAMES_XMIT)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_BROADCAST_BYTES_XMIT)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_BROADCAST_FRAMES_XMIT)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_DIRECTED_BYTES_RCV)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_DIRECTED_FRAMES_RCV)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MULTICAST_BYTES_RCV)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MULTICAST_FRAMES_RCV)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_BROADCAST_BYTES_RCV)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_BROADCAST_FRAMES_RCV)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_RCV_CRC_ERROR)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_TRANSMIT_QUEUE_LENGTH)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_GET_TIME_CAPS)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_GET_NETCARD_TIME)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_NETCARD_LOAD)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_DEVICE_PROFILE)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_INIT_TIME_MS)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_RESET_COUNTS)
+ VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_SENSE_COUNTS)
+ VBOXNETFLTDUMP_STRCASE(OID_PNP_CAPABILITIES)
+ VBOXNETFLTDUMP_STRCASE(OID_PNP_SET_POWER)
+ VBOXNETFLTDUMP_STRCASE(OID_PNP_QUERY_POWER)
+ VBOXNETFLTDUMP_STRCASE(OID_PNP_ADD_WAKE_UP_PATTERN)
+ VBOXNETFLTDUMP_STRCASE(OID_PNP_REMOVE_WAKE_UP_PATTERN)
+ VBOXNETFLTDUMP_STRCASE(OID_PNP_ENABLE_WAKE_UP)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_PERMANENT_ADDRESS)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_CURRENT_ADDRESS)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_MULTICAST_LIST)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_MAXIMUM_LIST_SIZE)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_MAC_OPTIONS)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_RCV_ERROR_ALIGNMENT)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_ONE_COLLISION)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_MORE_COLLISIONS)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_DEFERRED)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_MAX_COLLISIONS)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_RCV_OVERRUN)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_UNDERRUN)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_HEARTBEAT_FAILURE)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_TIMES_CRS_LOST)
+ VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_LATE_COLLISIONS)
+ VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_OFFLOAD)
+ VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_IPSEC_ADD_SA)
+ VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_IPSEC_DELETE_SA)
+ VBOXNETFLTDUMP_STRCASE(OID_TCP_SAN_SUPPORT)
+ VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_IPSEC_ADD_UDPESP_SA)
+ VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_IPSEC_DELETE_UDPESP_SA)
+ VBOXNETFLTDUMP_STRCASE_UNKNOWN()
+ }
+}
+
+DECLHIDDEN(VOID) vboxNetFltWinMpReturnPacket(IN NDIS_HANDLE hMiniportAdapterContext, IN PNDIS_PACKET pPacket)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hMiniportAdapterContext;
+ PVBOXNETFLT_PKTRSVD_MP pInfo = (PVBOXNETFLT_PKTRSVD_MP)pPacket->MiniportReserved;
+ PNDIS_PACKET pOrigPacket = pInfo->pOrigPacket;
+ PVOID pBufToFree = pInfo->pBufToFree;
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
+
+ if (pOrigPacket)
+ {
+ /* the packet was sent from underlying miniport */
+ NdisFreePacket(pPacket);
+ NdisReturnPackets(&pOrigPacket, 1);
+ }
+ else
+ {
+ /* the packet was sent from IntNet or it is a packet we allocated on PtReceive for TransferData processing */
+ vboxNetFltWinFreeSGNdisPacket(pPacket, !pBufToFree /* bFreeMem */);
+ }
+
+ if (pBufToFree)
+ {
+ vboxNetFltWinMemFree(pBufToFree);
+ }
+
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
+}
+
+static NDIS_STATUS vboxNetFltWinMpTransferData(OUT PNDIS_PACKET Packet,
+ OUT PUINT BytesTransferred,
+ IN NDIS_HANDLE hContext,
+ IN NDIS_HANDLE MiniportReceiveContext,
+ IN UINT ByteOffset,
+ IN UINT BytesToTransfer)
+{
+#ifndef VBOXNETADP
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext;
+ NDIS_STATUS Status;
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
+
+ if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState) != NdisDeviceStateD0
+ || vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) != NdisDeviceStateD0)
+ {
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, NDIS_STATUS_FAILURE));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ NdisTransferData(&Status, pNetFlt->u.s.WinIf.hBinding, MiniportReceiveContext,
+ ByteOffset, BytesToTransfer, Packet, BytesTransferred);
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status));
+ return Status;
+#else
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", hContext));
+ /* should never be here */
+ Assert(0);
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x)\n", hContext, NDIS_STATUS_FAILURE));
+ return NDIS_STATUS_FAILURE;
+#endif
+}
+
+static void vboxNetFltWinMpHalt(IN NDIS_HANDLE hContext)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext;
+ NDIS_STATUS Status;
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
+
+#ifndef VBOXNETADP
+ if (vboxNetFltWinGetWinIfState(pNetFlt) == kVBoxWinIfState_Disconnecting)
+ {
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitializing);
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing);
+
+ vboxNetFltWinPtCloseInterface(pNetFlt, &Status);
+
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Deinitializing);
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
+ }
+ else
+#endif
+ {
+ /* we're NOT called from protocolUnbinAdapter, perform a full disconnect */
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized);
+#ifndef VBOXNETADP
+ AssertBreakpoint();
+#endif
+ Status = vboxNetFltWinDetachFromInterface(pNetFlt, false);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ }
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
+}
+
+/**
+ * register the miniport edge
+ */
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpRegister(PVBOXNETFLTGLOBALS_MP pGlobalsMp, PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr)
+{
+ NDIS_MINIPORT_CHARACTERISTICS MpChars;
+
+ NdisMInitializeWrapper(&pGlobalsMp->hNdisWrapper, pDriverObject, pRegistryPathStr, NULL);
+
+ NdisZeroMemory(&MpChars, sizeof (MpChars));
+
+ MpChars.MajorNdisVersion = VBOXNETFLT_VERSION_MP_NDIS_MAJOR;
+ MpChars.MinorNdisVersion = VBOXNETFLT_VERSION_MP_NDIS_MINOR;
+
+ MpChars.HaltHandler = vboxNetFltWinMpHalt;
+ MpChars.InitializeHandler = vboxNetFltWinMpInitialize;
+ MpChars.QueryInformationHandler = vboxNetFltWinMpQueryInformation;
+ MpChars.SetInformationHandler = vboxNetFltWinMpSetInformation;
+ MpChars.TransferDataHandler = vboxNetFltWinMpTransferData;
+ MpChars.ReturnPacketHandler = vboxNetFltWinMpReturnPacket;
+ MpChars.SendPacketsHandler = vboxNetFltWinMpSendPackets;
+
+#ifndef VBOXNETADP
+ NDIS_STATUS Status = NdisIMRegisterLayeredMiniport(pGlobalsMp->hNdisWrapper, &MpChars, sizeof (MpChars), &pGlobalsMp->hMiniport);
+#else
+ NDIS_STATUS Status = NdisMRegisterMiniport(pGlobalsMp->hNdisWrapper, &MpChars, sizeof (MpChars));
+#endif
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ NdisMRegisterUnloadHandler(pGlobalsMp->hNdisWrapper, vboxNetFltWinUnload);
+ }
+
+ return Status;
+}
+
+/**
+ * deregister the miniport edge
+ */
+DECLHIDDEN(VOID) vboxNetFltWinMpDeregister(PVBOXNETFLTGLOBALS_MP pGlobalsMp)
+{
+#ifndef VBOXNETADP
+ NdisIMDeregisterLayeredMiniport(pGlobalsMp->hMiniport);
+#endif
+ NdisTerminateWrapper(pGlobalsMp->hNdisWrapper, NULL);
+
+ NdisZeroMemory(pGlobalsMp, sizeof (*pGlobalsMp));
+}
+
+#ifndef VBOXNETADP
+
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpInitializeDevideInstance(PVBOXNETFLTINS pThis)
+{
+ NDIS_STATUS Status;
+ Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Initializing);
+
+ Status = NdisIMInitializeDeviceInstanceEx(g_VBoxNetFltGlobalsWin.Mp.hMiniport,
+ &pThis->u.s.WinIf.MpDeviceName,
+ pThis);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ if (pThis->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS)
+ {
+ return NDIS_STATUS_SUCCESS;
+ }
+ AssertBreakpoint();
+ vboxNetFltWinMpDeInitializeDeviceInstance(pThis, &Status);
+ Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
+ return pThis->u.s.WinIf.OpenCloseStatus;
+ }
+
+ Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
+
+ return Status;
+}
+
+DECLHIDDEN(bool) vboxNetFltWinMpDeInitializeDeviceInstance(PVBOXNETFLTINS pThis, PNDIS_STATUS pStatus)
+{
+ NDIS_STATUS Status;
+
+ if (vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initializing)
+ {
+ Status = NdisIMCancelInitializeDeviceInstance(g_VBoxNetFltGlobalsWin.Mp.hMiniport, &pThis->u.s.WinIf.MpDeviceName);
+
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ /* we've canceled the initialization successfully */
+ Assert(pThis->u.s.WinIf.hMiniport == NULL);
+ Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
+ }
+ else
+ {
+ NdisWaitEvent(&pThis->u.s.WinIf.MpInitCompleteEvent, 0);
+ }
+ }
+
+ Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized
+ || vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
+ if (vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized)
+ {
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing);
+
+ Status = NdisIMDeInitializeDeviceInstance(pThis->u.s.WinIf.hMiniport);
+
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ Status = NDIS_STATUS_FAILURE;
+ }
+
+ *pStatus = Status;
+ return true;
+ }
+
+ Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
+
+ *pStatus = Status;
+ return false;
+}
+#endif
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.h
new file mode 100644
index 000000000..958deb4cb
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.h
@@ -0,0 +1,42 @@
+/* $Id: VBoxNetFltM-win.h 36207 2011-03-08 17:12:10Z vboxsync $ */
+/** @file
+ * VBoxNetFltM-win.h - Bridged Networking Driver, Windows Specific Code - Miniport edge API
+ */
+
+/*
+ * 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 ___VBoxNetFltM_win_h___
+#define ___VBoxNetFltM_win_h___
+
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpRegister(PVBOXNETFLTGLOBALS_MP pGlobalsMp, PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr);
+DECLHIDDEN(VOID) vboxNetFltWinMpDeregister(PVBOXNETFLTGLOBALS_MP pGlobalsMp);
+DECLHIDDEN(VOID) vboxNetFltWinMpReturnPacket(IN NDIS_HANDLE hMiniportAdapterContext, IN PNDIS_PACKET pPacket);
+
+#ifdef VBOXNETADP
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoInitialization(PVBOXNETFLTINS pThis, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext);
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoDeinitialization(PVBOXNETFLTINS pThis);
+#else
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpInitializeDevideInstance(PVBOXNETFLTINS pThis);
+DECLHIDDEN(bool) vboxNetFltWinMpDeInitializeDeviceInstance(PVBOXNETFLTINS pThis, PNDIS_STATUS pStatus);
+DECLINLINE(VOID) vboxNetFltWinMpRequestStateComplete(PVBOXNETFLTINS pNetFlt)
+{
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
+ pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = 0;
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+}
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpRequestPost(PVBOXNETFLTINS pNetFlt);
+#endif
+
+#endif /* !___VBoxNetFltM_win_h___ */
+
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt_m.inf b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM.inf
index 0a1b4a874..25748e10d 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt_m.inf
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM.inf
@@ -1,9 +1,10 @@
+; $Id: VBoxNetFltM.inf 36184 2011-03-07 10:57:04Z vboxsync $
+; @file
+; VBoxNetFltM.inf - VirtualBox Bridged Networking Driver inf file
+; Miniport edge
;
-; VirtualBox Bridged Networking Driver
;
-
-;
-; Copyright (C) 2008 Oracle Corporation
+; 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;
@@ -14,11 +15,6 @@
; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
;
-;
-; Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
-; Copyright (c) 1993-1999, Microsoft Corporation
-;
-
[Version]
signature = "$Windows NT$"
;cat CatalogFile = VBoxNetFlt.cat
@@ -37,19 +33,14 @@ DefaultDestDir=12
; No files to copy
[Manufacturer]
-%Provider% = VBox,NTx86,NTia64,NTamd64
+%Provider% = VBox,NTx86,NTamd64
-; For Win2K
[VBox]
%VBoxNetFltMP_Desc% = VBoxNetFltMP.ndi, sun_VBoxNetFltmp
-; For XP and later
[VBox.NTx86]
%VBoxNetFltMP_Desc% = VBoxNetFltMP.ndi, sun_VBoxNetFltmp
-[VBox.NTia64]
-%VBoxNetFltMP_Desc% = VBoxNetFltMP.ndi, sun_VBoxNetFltmp
-
[VBox.NTamd64]
%VBoxNetFltMP_Desc% = VBoxNetFltMP.ndi, sun_VBoxNetFltmp
@@ -60,31 +51,21 @@ CopyFiles =
[VBoxNetFltMP.ndi.Services]
AddService = VBoxNetFlt,0x2, VBoxNetFltMP.AddService
-
[VBoxNetFltMP.AddService]
ServiceType = 1 ;SERVICE_KERNEL_DRIVER
StartType = 3 ;SERVICE_DEMAND_START
ErrorControl = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary = %12%\VBoxNetFlt.sys
-
[VBoxNetFltMP.AddService.AddReg]
-; ----------------------------------------------------------------------
-; Add any miniport-specific parameters here. These are params that your
-; filter device is going to use.
-;
-;HKR, Parameters, ParameterName, 0x10000, "MultiSz", "Parameter", "Value"
-;HKR, Parameters, ParameterName2, 0x10001, 4
[Strings]
Provider = "Oracle Corporation"
VBoxNetFltMP_Desc = "VirtualBox Bridged Networking Driver Miniport"
[SourceDisksNames]
-;None
[SourceDisksFiles]
-;None
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.cpp
new file mode 100644
index 000000000..bba6ba40d
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.cpp
@@ -0,0 +1,1580 @@
+/* $Id: VBoxNetFltP-win.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */
+/** @file
+ * VBoxNetFltP-win.cpp - Bridged Networking Driver, Windows Specific Code.
+ * Protocol edge
+ */
+/*
+ * 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.
+ */
+#include "VBoxNetFltCmn-win.h"
+
+#ifdef VBOXNETADP
+# error "No protocol edge"
+#endif
+
+#define VBOXNETFLT_PT_STATUS_IS_FILTERED(_s) (\
+ (_s) == NDIS_STATUS_MEDIA_CONNECT \
+ || (_s) == NDIS_STATUS_MEDIA_DISCONNECT \
+ )
+
+/**
+ * performs binding to the given adapter
+ */
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(PVBOXNETFLTINS pThis, PNDIS_STRING pOurDeviceName, PNDIS_STRING pBindToDeviceName)
+{
+ Assert(pThis->u.s.WinIf.PtState.PowerState == NdisDeviceStateD3);
+ Assert(pThis->u.s.WinIf.PtState.OpState == kVBoxNetDevOpState_Deinitialized);
+ Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
+
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Initializing);
+
+ NDIS_STATUS Status = vboxNetFltWinCopyString(&pThis->u.s.WinIf.MpDeviceName, pOurDeviceName);
+ Assert (Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ vboxNetFltWinSetPowerState(&pThis->u.s.WinIf.PtState, NdisDeviceStateD0);
+ pThis->u.s.WinIf.OpenCloseStatus = NDIS_STATUS_SUCCESS;
+
+ UINT iMedium;
+ NDIS_STATUS TmpStatus;
+ NDIS_MEDIUM aenmNdisMedium[] =
+ {
+ /* Ethernet */
+ NdisMedium802_3,
+ /* Wan */
+ NdisMediumWan
+ };
+
+ NdisResetEvent(&pThis->u.s.WinIf.OpenCloseEvent);
+
+ NdisOpenAdapter(&Status, &TmpStatus, &pThis->u.s.WinIf.hBinding, &iMedium,
+ aenmNdisMedium, RT_ELEMENTS(aenmNdisMedium),
+ g_VBoxNetFltGlobalsWin.Pt.hProtocol,
+ pThis,
+ pBindToDeviceName,
+ 0, /* IN UINT OpenOptions, (reserved, should be NULL) */
+ NULL /* IN PSTRING AddressingInformation OPTIONAL */
+ );
+ Assert(Status == NDIS_STATUS_PENDING || Status == STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_PENDING)
+ {
+ NdisWaitEvent(&pThis->u.s.WinIf.OpenCloseEvent, 0);
+ Status = pThis->u.s.WinIf.OpenCloseStatus;
+ }
+
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ Assert(pThis->u.s.WinIf.hBinding);
+ pThis->u.s.WinIf.enmMedium = aenmNdisMedium[iMedium];
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Initialized);
+
+ Status = vboxNetFltWinMpInitializeDevideInstance(pThis);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ return NDIS_STATUS_SUCCESS;
+ }
+ else
+ {
+ LogRel((__FUNCTION__": vboxNetFltWinMpInitializeDevideInstance failed, Status 0x%x\n", Status));
+ }
+
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitializing);
+ vboxNetFltWinPtCloseInterface(pThis, &TmpStatus);
+ Assert(TmpStatus == NDIS_STATUS_SUCCESS);
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
+ }
+ else
+ {
+ LogRel((__FUNCTION__"NdisOpenAdapter failed, Status (0x%x)", Status));
+ }
+
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
+ pThis->u.s.WinIf.hBinding = NULL;
+ }
+
+ return Status;
+}
+
+static VOID vboxNetFltWinPtBindAdapter(OUT PNDIS_STATUS pStatus,
+ IN NDIS_HANDLE hBindContext,
+ IN PNDIS_STRING pDeviceNameStr,
+ IN PVOID pvSystemSpecific1,
+ IN PVOID pvSystemSpecific2)
+{
+ LogFlow(("==>"__FUNCTION__"\n"));
+
+ NDIS_STATUS Status;
+ NDIS_HANDLE hConfig = NULL;
+
+ NdisOpenProtocolConfiguration(&Status, &hConfig, (PNDIS_STRING)pvSystemSpecific1);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ PNDIS_CONFIGURATION_PARAMETER pParam;
+ NDIS_STRING UppedBindStr = NDIS_STRING_CONST("UpperBindings");
+ NdisReadConfiguration(&Status, &pParam, hConfig, &UppedBindStr, NdisParameterString);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ PVBOXNETFLTINS pNetFlt;
+ Status = vboxNetFltWinPtInitBind(&pNetFlt, &pParam->ParameterData.StringData, pDeviceNameStr);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ }
+
+ NdisCloseConfiguration(hConfig);
+ }
+
+ *pStatus = Status;
+
+ LogFlow(("<=="__FUNCTION__": Status 0x%x\n", Status));
+}
+
+static VOID vboxNetFltWinPtOpenAdapterComplete(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS Status, IN NDIS_STATUS OpenErrorStatus)
+{
+ PVBOXNETFLTINS pNetFlt =(PVBOXNETFLTINS)hProtocolBindingContext;
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Status (0x%x), OpenErrorStatus(0x%x)\n", pNetFlt, Status, OpenErrorStatus));
+ Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS)
+ {
+ pNetFlt->u.s.WinIf.OpenCloseStatus = Status;
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status != NDIS_STATUS_SUCCESS)
+ LogRel((__FUNCTION__" : Open Complete status is 0x%x", Status));
+ }
+ else
+ LogRel((__FUNCTION__" : Adapter maintained status is 0x%x", pNetFlt->u.s.WinIf.OpenCloseStatus));
+ NdisSetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent);
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x), OpenErrorStatus(0x%x)\n", pNetFlt, Status, OpenErrorStatus));
+}
+
+static void vboxNetFltWinPtRequestsWaitComplete(PVBOXNETFLTINS pNetFlt)
+{
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+
+ /* wait for request to complete */
+ while (vboxNetFltWinAtomicUoReadWinState(pNetFlt->u.s.WinIf.StateFlags).fRequestInfo == VBOXNDISREQUEST_INPROGRESS)
+ {
+ vboxNetFltWinSleep(2);
+ }
+
+ /*
+ * If the below miniport is going to low power state, complete the queued request
+ */
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
+ if (pNetFlt->u.s.WinIf.StateFlags.fRequestInfo & VBOXNDISREQUEST_QUEUED)
+ {
+ /* mark the request as InProgress before posting it to RequestComplete */
+ pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS;
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+ vboxNetFltWinPtRequestComplete(pNetFlt, &pNetFlt->u.s.WinIf.PassDownRequest, NDIS_STATUS_FAILURE);
+ }
+ else
+ {
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+ }
+}
+
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoUnbinding(PVBOXNETFLTINS pNetFlt, bool bOnUnbind)
+{
+ NDIS_STATUS Status;
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+ uint64_t NanoTS = RTTimeSystemNanoTS();
+ int cPPUsage;
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt 0x%p\n", pNetFlt));
+
+ Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
+
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Initialized);
+
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
+
+ ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true);
+ ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false);
+ ASMAtomicUoWriteU64(&pNetFlt->NanoTSLastRediscovery, NanoTS);
+
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitializing);
+ if (!bOnUnbind)
+ {
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing);
+ }
+
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+
+ vboxNetFltWinPtRequestsWaitComplete(pNetFlt);
+
+ vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState);
+ vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.PtState);
+
+ /* check packet pool is empty */
+ cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hSendPacketPool);
+ Assert(cPPUsage == 0);
+ cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool);
+ Assert(cPPUsage == 0);
+ /* for debugging only, ignore the err in release */
+ NOREF(cPPUsage);
+
+ if (!bOnUnbind || !vboxNetFltWinMpDeInitializeDeviceInstance(pNetFlt, &Status))
+ {
+ vboxNetFltWinPtCloseInterface(pNetFlt, &Status);
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
+
+ if (!bOnUnbind)
+ {
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitializing);
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
+ }
+ else
+ {
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
+ }
+ }
+ else
+ {
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
+ }
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt 0x%p\n", pNetFlt));
+
+ return Status;
+}
+
+static VOID vboxNetFltWinPtUnbindAdapter(OUT PNDIS_STATUS pStatus,
+ IN NDIS_HANDLE hContext,
+ IN NDIS_HANDLE hUnbindContext)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext;
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
+
+ *pStatus = vboxNetFltWinDetachFromInterface(pNetFlt, true);
+ Assert(*pStatus == NDIS_STATUS_SUCCESS);
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
+}
+
+static VOID vboxNetFltWinPtUnloadProtocol()
+{
+ LogFlow(("==>"__FUNCTION__"\n"));
+ NDIS_STATUS Status = vboxNetFltWinPtDeregister(&g_VBoxNetFltGlobalsWin.Pt);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ LogFlow(("<=="__FUNCTION__": PtDeregister Status (0x%x)\n", Status));
+}
+
+
+static VOID vboxNetFltWinPtCloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)ProtocolBindingContext;
+
+ LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status));
+ Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS);
+ if (pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS)
+ {
+ pNetFlt->u.s.WinIf.OpenCloseStatus = Status;
+ }
+ NdisSetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent);
+ LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status));
+}
+
+static VOID vboxNetFltWinPtResetComplete(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS Status)
+{
+ LogFlow(("==>"__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", hProtocolBindingContext, Status));
+ /*
+ * should never be here
+ */
+ Assert(0);
+ LogFlow(("<=="__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", hProtocolBindingContext, Status));
+}
+
+static NDIS_STATUS vboxNetFltWinPtHandleQueryInfoComplete(PVBOXNETFLTINS pNetFlt, NDIS_STATUS Status)
+{
+ PNDIS_REQUEST pRequest = &pNetFlt->u.s.WinIf.PassDownRequest;
+
+ switch (pRequest->DATA.QUERY_INFORMATION.Oid)
+ {
+ case OID_PNP_CAPABILITIES:
+ {
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (NDIS_PNP_CAPABILITIES))
+ {
+ PNDIS_PNP_CAPABILITIES pPnPCaps = (PNDIS_PNP_CAPABILITIES)(pRequest->DATA.QUERY_INFORMATION.InformationBuffer);
+ PNDIS_PM_WAKE_UP_CAPABILITIES pPmWuCaps = &pPnPCaps->WakeUpCapabilities;
+ pPmWuCaps->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
+ pPmWuCaps->MinPatternWakeUp = NdisDeviceStateUnspecified;
+ pPmWuCaps->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
+ *pNetFlt->u.s.WinIf.pcPDRBytesRW = sizeof (NDIS_PNP_CAPABILITIES);
+ *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = 0;
+ Status = NDIS_STATUS_SUCCESS;
+ }
+ else
+ {
+ Assert(0);
+ *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof(NDIS_PNP_CAPABILITIES);
+ Status = NDIS_STATUS_RESOURCES;
+ }
+ }
+ break;
+ }
+
+ case OID_GEN_MAC_OPTIONS:
+ {
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (ULONG))
+ {
+ pNetFlt->u.s.WinIf.fMacOptions = *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer;
+#ifndef VBOX_LOOPBACK_USEFLAGS
+ /* clearing this flag tells ndis we'll handle loopback ourselves
+ * the ndis layer or nic driver below us would loopback packets as necessary */
+ *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer &= ~NDIS_MAC_OPTION_NO_LOOPBACK;
+#else
+ /* we have to catch loopbacks from the underlying driver, so no duplications will occur,
+ * just indicate NDIS to handle loopbacks for the packets coming from the protocol */
+ *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer |= NDIS_MAC_OPTION_NO_LOOPBACK;
+#endif
+ }
+ else
+ {
+ Assert(0);
+ *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
+ Status = NDIS_STATUS_RESOURCES;
+ }
+ }
+ break;
+ }
+
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ {
+ if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt))
+ {
+ /* we're here _ONLY_ in the passthru mode */
+ Assert(pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter && !pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt);
+ if (pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter && !pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt)
+ {
+ Assert(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
+ vboxNetFltWinDereferenceModePassThru(pNetFlt);
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+ }
+
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (ULONG))
+ {
+ /* the filter request is issued below only in case netflt is not active,
+ * simply update the cache here */
+ /* cache the filter used by upper protocols */
+ pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer;
+ pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE;
+ }
+ else
+ {
+ Assert(0);
+ *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
+ Status = NDIS_STATUS_RESOURCES;
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ Assert(pRequest->DATA.QUERY_INFORMATION.Oid != OID_PNP_QUERY_POWER);
+ break;
+ }
+
+ *pNetFlt->u.s.WinIf.pcPDRBytesRW = pRequest->DATA.QUERY_INFORMATION.BytesWritten;
+ *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = pRequest->DATA.QUERY_INFORMATION.BytesNeeded;
+
+ return Status;
+}
+
+static NDIS_STATUS vboxNetFltWinPtHandleSetInfoComplete(PVBOXNETFLTINS pNetFlt, NDIS_STATUS Status)
+{
+ PNDIS_REQUEST pRequest = &pNetFlt->u.s.WinIf.PassDownRequest;
+
+ switch (pRequest->DATA.SET_INFORMATION.Oid)
+ {
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ {
+ if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt))
+ {
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter)
+ {
+ if (pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt)
+ {
+ Assert(pNetFlt->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE);
+ pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 0;
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ if (pRequest->DATA.SET_INFORMATION.InformationBufferLength >= sizeof (ULONG))
+ {
+ pNetFlt->u.s.WinIf.fOurSetFilter = *((PULONG)pRequest->DATA.SET_INFORMATION.InformationBuffer);
+ Assert(pNetFlt->u.s.WinIf.fOurSetFilter == NDIS_PACKET_TYPE_PROMISCUOUS);
+ }
+ else
+ {
+ Assert(0);
+ *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
+ Status = NDIS_STATUS_RESOURCES;
+ }
+ }
+ vboxNetFltWinDereferenceNetFlt(pNetFlt);
+ }
+ else
+ {
+ Assert(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
+
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ if (pRequest->DATA.SET_INFORMATION.InformationBufferLength >= sizeof (ULONG))
+ {
+ /* the request was issued when the netflt was not active, simply update the cache here */
+ pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = *((PULONG)pRequest->DATA.SET_INFORMATION.InformationBuffer);
+ pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE;
+ }
+ else
+ {
+ Assert(0);
+ *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
+ Status = NDIS_STATUS_RESOURCES;
+ }
+ }
+ vboxNetFltWinDereferenceModePassThru(pNetFlt);
+ }
+
+ pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 0;
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+ }
+#ifdef DEBUG_misha
+ else
+ {
+ Assert(0);
+ }
+#endif
+ }
+ break;
+ }
+
+ default:
+ Assert(pRequest->DATA.SET_INFORMATION.Oid != OID_PNP_SET_POWER);
+ break;
+ }
+
+ *pNetFlt->u.s.WinIf.pcPDRBytesRW = pRequest->DATA.SET_INFORMATION.BytesRead;
+ *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = pRequest->DATA.SET_INFORMATION.BytesNeeded;
+
+ return Status;
+}
+
+DECLHIDDEN(VOID) vboxNetFltWinPtRequestComplete(NDIS_HANDLE hContext, PNDIS_REQUEST pNdisRequest, NDIS_STATUS Status)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext;
+ PNDIS_REQUEST pSynchRequest = pNetFlt->u.s.WinIf.pSynchRequest;
+ NDIS_OID Oid = pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.Oid;
+
+ LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status));
+
+ if (pSynchRequest == pNdisRequest)
+ {
+ /* asynchronous completion of our sync request */
+ /*1.set the status */
+ pNetFlt->u.s.WinIf.SynchCompletionStatus = Status;
+ /* 2. set event */
+ KeSetEvent(&pNetFlt->u.s.WinIf.hSynchCompletionEvent, 0, FALSE);
+ /* 3. return; */
+
+ LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status));
+ return;
+ }
+
+ Assert(&pNetFlt->u.s.WinIf.PassDownRequest == pNdisRequest);
+ Assert(pNetFlt->u.s.WinIf.StateFlags.fRequestInfo == VBOXNDISREQUEST_INPROGRESS);
+ vboxNetFltWinMpRequestStateComplete(pNetFlt);
+
+ switch (pNdisRequest->RequestType)
+ {
+ case NdisRequestQueryInformation:
+ Status = vboxNetFltWinPtHandleQueryInfoComplete(pNetFlt, Status);
+ NdisMQueryInformationComplete(pNetFlt->u.s.WinIf.hMiniport, Status);
+ break;
+
+ case NdisRequestSetInformation:
+ Status = vboxNetFltWinPtHandleSetInfoComplete(pNetFlt, Status);
+ NdisMSetInformationComplete(pNetFlt->u.s.WinIf.hMiniport, Status);
+ break;
+
+ default:
+ Assert(0);
+ break;
+ }
+
+ LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status));
+}
+
+static VOID vboxNetFltWinPtStatus(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS GeneralStatus, IN PVOID pvStatusBuffer, IN UINT cbStatusBuffer)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
+
+ LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), GeneralStatus (0x%x)\n", pNetFlt, GeneralStatus));
+
+ if (vboxNetFltWinReferenceWinIf(pNetFlt))
+ {
+ Assert(pNetFlt->u.s.WinIf.hMiniport);
+
+ if (VBOXNETFLT_PT_STATUS_IS_FILTERED(GeneralStatus))
+ {
+ pNetFlt->u.s.WinIf.MpIndicatedMediaStatus = GeneralStatus;
+ }
+ NdisMIndicateStatus(pNetFlt->u.s.WinIf.hMiniport,
+ GeneralStatus,
+ pvStatusBuffer,
+ cbStatusBuffer);
+
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+ }
+ else
+ {
+ if (pNetFlt->u.s.WinIf.hMiniport != NULL
+ && VBOXNETFLT_PT_STATUS_IS_FILTERED(GeneralStatus)
+ )
+ {
+ pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus = GeneralStatus;
+ }
+ }
+
+ LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), GeneralStatus (0x%x)\n", pNetFlt, GeneralStatus));
+}
+
+
+static VOID vboxNetFltWinPtStatusComplete(IN NDIS_HANDLE hProtocolBindingContext)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
+
+ LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
+
+ if (vboxNetFltWinReferenceWinIf(pNetFlt))
+ {
+ NdisMIndicateStatusComplete(pNetFlt->u.s.WinIf.hMiniport);
+
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+ }
+
+ LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
+}
+
+static VOID vboxNetFltWinPtSendComplete(IN NDIS_HANDLE hProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
+ PVBOXNETFLT_PKTRSVD_PT pSendInfo = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved;
+ PNDIS_PACKET pOrigPacket = pSendInfo->pOrigPacket;
+ PVOID pBufToFree = pSendInfo->pBufToFree;
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x)\n", pNetFlt, pPacket, Status));
+
+#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
+ /* @todo: for optimization we could check only for netflt-mode packets
+ * do it for all for now */
+ vboxNetFltWinLbRemoveSendPacket(pNetFlt, pPacket);
+#endif
+
+ if (pOrigPacket)
+ {
+ NdisIMCopySendCompletePerPacketInfo(pOrigPacket, pPacket);
+ NdisFreePacket(pPacket);
+ /* the ptk was posted from the upperlying protocol */
+ NdisMSendComplete(pNetFlt->u.s.WinIf.hMiniport, pOrigPacket, Status);
+ }
+ else
+ {
+ /* if the pOrigPacket is zero - the ptk was originated by netFlt send/receive
+ * need to free packet buffers */
+ vboxNetFltWinFreeSGNdisPacket(pPacket, !pBufToFree);
+ }
+
+ if (pBufToFree)
+ {
+ vboxNetFltWinMemFree(pBufToFree);
+ }
+
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x)\n", pNetFlt, pPacket, Status));
+}
+
+/**
+ * removes searches for the packet in the list and removes it if found
+ * @return true if the packet was found and removed, false - otherwise
+ */
+static bool vboxNetFltWinRemovePacketFromList(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket)
+{
+ PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved;
+ return vboxNetFltWinInterlockedSearchListEntry(pList, &pTDR->ListEntry, true /* remove*/);
+}
+
+/**
+ * puts the packet to the tail of the list
+ */
+static void vboxNetFltWinPutPacketToList(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket, PNDIS_BUFFER pOrigBuffer)
+{
+ PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved;
+ pTDR->pOrigBuffer = pOrigBuffer;
+ vboxNetFltWinInterlockedPutTail(pList, &pTDR->ListEntry);
+}
+
+static bool vboxNetFltWinPtTransferDataCompleteActive(PVBOXNETFLTINS pNetFltIf, PNDIS_PACKET pPacket, NDIS_STATUS Status)
+{
+ PNDIS_BUFFER pBuffer;
+ PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR;
+
+ if (!vboxNetFltWinRemovePacketFromList(&pNetFltIf->u.s.WinIf.TransferDataList, pPacket))
+ return false;
+
+ pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved;
+ Assert(pTDR);
+ Assert(pTDR->pOrigBuffer);
+
+ do
+ {
+ NdisUnchainBufferAtFront(pPacket, &pBuffer);
+
+ Assert(pBuffer);
+
+ NdisFreeBuffer(pBuffer);
+
+ pBuffer = pTDR->pOrigBuffer;
+
+ NdisChainBufferAtBack(pPacket, pBuffer);
+
+ /* data transfer was initiated when the netFlt was active
+ * the netFlt is still retained by us
+ * 1. check if loopback
+ * 2. enqueue packet
+ * 3. release netFlt */
+
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+
+#ifdef VBOX_LOOPBACK_USEFLAGS
+ if (vboxNetFltWinIsLoopedBackPacket(pPacket))
+ {
+ /* should not be here */
+ Assert(0);
+ }
+#else
+ PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pNetFltIf, pPacket, false);
+ if (pLb)
+ {
+#ifndef DEBUG_NETFLT_RECV_TRANSFERDATA
+ /* should not be here */
+ Assert(0);
+#endif
+ if (!vboxNetFltWinLbIsFromIntNet(pLb))
+ {
+ /* the packet is not from int net, need to pass it up to the host */
+ NdisMIndicateReceivePacket(pNetFltIf->u.s.WinIf.hMiniport, &pPacket, 1);
+ /* dereference NetFlt, WinIf will be dereferenced on Packet return */
+ vboxNetFltWinDereferenceNetFlt(pNetFltIf);
+ break;
+ }
+ }
+#endif
+ else
+ {
+ /* 2. enqueue */
+ /* use the same packet info to put the packet in the processing packet queue */
+ PVBOXNETFLT_PKTRSVD_MP pRecvInfo = (PVBOXNETFLT_PKTRSVD_MP)pPacket->MiniportReserved;
+
+ VBOXNETFLT_LBVERIFY(pNetFltIf, pPacket);
+
+ pRecvInfo->pOrigPacket = NULL;
+ pRecvInfo->pBufToFree = NULL;
+
+ NdisGetPacketFlags(pPacket) = 0;
+# ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ if (vboxNetFltWinPostIntnet(pNetFltIf, pPacket, 0))
+ {
+ /* drop it */
+ vboxNetFltWinFreeSGNdisPacket(pPacket, true);
+ vboxNetFltWinDereferenceWinIf(pNetFltIf);
+ }
+ else
+ {
+ NdisMIndicateReceivePacket(pNetFltIf->u.s.WinIf.hMiniport, &pPacket, 1);
+ }
+ vboxNetFltWinDereferenceNetFlt(pNetFltIf);
+ break;
+# else
+ Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, PACKET_MINE);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ break;
+ }
+ Assert(0);
+# endif
+ }
+ }
+ else
+ {
+ Assert(0);
+ }
+ /* we are here because of error either in data transfer or in enqueueing the packet */
+ vboxNetFltWinFreeSGNdisPacket(pPacket, true);
+ vboxNetFltWinDereferenceNetFlt(pNetFltIf);
+ vboxNetFltWinDereferenceWinIf(pNetFltIf);
+ } while (0);
+
+ return true;
+}
+
+static VOID vboxNetFltWinPtTransferDataComplete(IN NDIS_HANDLE hProtocolBindingContext,
+ IN PNDIS_PACKET pPacket,
+ IN NDIS_STATUS Status,
+ IN UINT cbTransferred)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x), cbTransfered (%d)\n", pNetFlt, pPacket, Status, cbTransferred));
+ if (!vboxNetFltWinPtTransferDataCompleteActive(pNetFlt, pPacket, Status))
+ {
+ if (pNetFlt->u.s.WinIf.hMiniport)
+ {
+ NdisMTransferDataComplete(pNetFlt->u.s.WinIf.hMiniport,
+ pPacket,
+ Status,
+ cbTransferred);
+ }
+
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+ }
+ /* else - all processing is done with vboxNetFltWinPtTransferDataCompleteActive already */
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x), cbTransfered (%d)\n", pNetFlt, pPacket, Status, cbTransferred));
+}
+
+static INT vboxNetFltWinRecvPacketPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, BOOLEAN bForceIndicate)
+{
+ Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ PNDIS_PACKET pMyPacket;
+ NDIS_STATUS Status = vboxNetFltWinPrepareRecvPacket(pNetFlt, pPacket, &pMyPacket, true);
+ /* the Status holds the current packet status it will be checked for NDIS_STATUS_RESOURCES later
+ * (see below) */
+ Assert(pMyPacket);
+ if (pMyPacket)
+ {
+ NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
+ if (Status == NDIS_STATUS_RESOURCES)
+ {
+ NdisDprFreePacket(pMyPacket);
+ return 0;
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * process the packet receive in a "passthru" mode
+ */
+static NDIS_STATUS vboxNetFltWinRecvPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket)
+{
+ Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ NDIS_STATUS Status;
+ PNDIS_PACKET pMyPacket;
+
+ NdisDprAllocatePacket(&Status, &pMyPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ vboxNetFltWinCopyPacketInfoOnRecv(pMyPacket, pPacket, true /* force NDIS_STATUS_RESOURCES */);
+ Assert(NDIS_GET_PACKET_STATUS(pMyPacket) == NDIS_STATUS_RESOURCES);
+
+ NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
+
+ NdisDprFreePacket(pMyPacket);
+ }
+ return Status;
+}
+
+static VOID vboxNetFltWinRecvIndicatePassThru(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE MacReceiveContext,
+ PVOID pHeaderBuffer, UINT cbHeaderBuffer, PVOID pLookAheadBuffer, UINT cbLookAheadBuffer, UINT cbPacket)
+{
+ /* Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case
+ * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber
+ * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64
+ * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */
+ ULONG Proc = KeGetCurrentProcessorNumber();
+ Assert(Proc < RT_ELEMENTS(pNetFlt->u.s.WinIf.abIndicateRxComplete));
+ pNetFlt->u.s.WinIf.abIndicateRxComplete[Proc] = TRUE;
+ switch (pNetFlt->u.s.WinIf.enmMedium)
+ {
+ case NdisMedium802_3:
+ case NdisMediumWan:
+ NdisMEthIndicateReceive(pNetFlt->u.s.WinIf.hMiniport,
+ MacReceiveContext,
+ (PCHAR)pHeaderBuffer,
+ cbHeaderBuffer,
+ pLookAheadBuffer,
+ cbLookAheadBuffer,
+ cbPacket);
+ break;
+ default:
+ Assert(FALSE);
+ break;
+ }
+}
+
+/**
+ * process the ProtocolReceive in an "active" mode
+ *
+ * @return NDIS_STATUS_SUCCESS - the packet is processed
+ * NDIS_STATUS_PENDING - the packet is being processed, we are waiting for the ProtocolTransferDataComplete to be called
+ * NDIS_STATUS_NOT_ACCEPTED - the packet is not needed - typically this is because this is a loopback packet
+ * NDIS_STATUS_FAILURE - packet processing failed
+ */
+static NDIS_STATUS vboxNetFltWinPtReceiveActive(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE MacReceiveContext, PVOID pHeaderBuffer, UINT cbHeaderBuffer,
+ PVOID pLookaheadBuffer, UINT cbLookaheadBuffer, UINT cbPacket)
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+
+ do
+ {
+ if (cbHeaderBuffer != VBOXNETFLT_PACKET_ETHEADER_SIZE)
+ {
+ Status = NDIS_STATUS_NOT_ACCEPTED;
+ break;
+ }
+
+#ifndef DEBUG_NETFLT_RECV_TRANSFERDATA
+ if (cbPacket == cbLookaheadBuffer)
+ {
+ PINTNETSG pSG;
+ PUCHAR pRcvData;
+#ifndef VBOX_LOOPBACK_USEFLAGS
+ PNDIS_PACKET pLb;
+#endif
+
+ /* allocate SG buffer */
+ Status = vboxNetFltWinAllocSG(cbPacket + cbHeaderBuffer, &pSG);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ Assert(0);
+ break;
+ }
+
+ pRcvData = (PUCHAR)pSG->aSegs[0].pv;
+
+ NdisMoveMappedMemory(pRcvData, pHeaderBuffer, cbHeaderBuffer);
+
+ NdisCopyLookaheadData(pRcvData+cbHeaderBuffer,
+ pLookaheadBuffer,
+ cbLookaheadBuffer,
+ pNetFlt->u.s.WinIf.fMacOptions);
+#ifndef VBOX_LOOPBACK_USEFLAGS
+ pLb = vboxNetFltWinLbSearchLoopBackBySG(pNetFlt, pSG, false);
+ if (pLb)
+ {
+#ifndef DEBUG_NETFLT_RECV_NOPACKET
+ /* should not be here */
+ Assert(0);
+#endif
+ if (!vboxNetFltWinLbIsFromIntNet(pLb))
+ {
+ PNDIS_PACKET pMyPacket;
+ pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt, /* PVBOXNETFLTINS */
+ pSG, /* PINTNETSG */
+ pSG, /* PVOID pBufToFree */
+ false, /* bool bToWire */
+ false); /* bool bCopyMemory */
+ if (pMyPacket)
+ {
+ NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
+ /* dereference the NetFlt here & indicate SUCCESS, which would mean the caller would not do a dereference
+ * the WinIf dereference will be done on packet return */
+ vboxNetFltWinDereferenceNetFlt(pNetFlt);
+ Status = NDIS_STATUS_SUCCESS;
+ }
+ else
+ {
+ vboxNetFltWinMemFree(pSG);
+ Status = NDIS_STATUS_FAILURE;
+ }
+ }
+ else
+ {
+ vboxNetFltWinMemFree(pSG);
+ Status = NDIS_STATUS_NOT_ACCEPTED;
+ }
+ break;
+ }
+#endif
+ VBOXNETFLT_LBVERIFYSG(pNetFlt, pSG);
+
+ /* enqueue SG */
+# ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ if (vboxNetFltWinPostIntnet(pNetFlt, pSG, VBOXNETFLT_PACKET_SG))
+ {
+ /* drop it */
+ vboxNetFltWinMemFree(pSG);
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+ }
+ else
+ {
+ PNDIS_PACKET pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt, /* PVBOXNETFLTINS */
+ pSG, /* PINTNETSG */
+ pSG, /* PVOID pBufToFree */
+ false, /* bool bToWire */
+ false); /* bool bCopyMemory */
+ Assert(pMyPacket);
+ if (pMyPacket)
+ {
+ NDIS_SET_PACKET_STATUS(pMyPacket, NDIS_STATUS_SUCCESS);
+
+ DBG_CHECK_PACKET_AND_SG(pMyPacket, pSG);
+
+ LogFlow(("non-ndis packet info, packet created (%p)\n", pMyPacket));
+ NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
+ }
+ else
+ {
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+ Status = NDIS_STATUS_RESOURCES;
+ }
+ }
+ vboxNetFltWinDereferenceNetFlt(pNetFlt);
+# else
+ Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pSG, PACKET_SG | PACKET_MINE);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ Assert(0);
+ vboxNetFltWinMemFree(pSG);
+ break;
+ }
+# endif
+#endif
+ }
+ else
+ {
+ PNDIS_PACKET pPacket;
+ PNDIS_BUFFER pTransferBuffer;
+ PNDIS_BUFFER pOrigBuffer;
+ PUCHAR pMemBuf;
+ UINT cbBuf = cbPacket + cbHeaderBuffer;
+ UINT cbTransferred;
+
+ /* allocate NDIS Packet buffer */
+ NdisAllocatePacket(&Status, &pPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ Assert(0);
+ break;
+ }
+
+ VBOXNETFLT_OOB_INIT(pPacket);
+
+#ifdef VBOX_LOOPBACK_USEFLAGS
+ /* set "don't loopback" flags */
+ NdisGetPacketFlags(pPacket) = g_VBoxNetFltGlobalsWin.fPacketDontLoopBack;
+#else
+ NdisGetPacketFlags(pPacket) = 0;
+#endif
+
+ Status = vboxNetFltWinMemAlloc((PVOID*)(&pMemBuf), cbBuf);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ Assert(0);
+ NdisFreePacket(pPacket);
+ break;
+ }
+ NdisAllocateBuffer(&Status, &pTransferBuffer, pNetFlt->u.s.WinIf.hRecvBufferPool, pMemBuf + cbHeaderBuffer, cbPacket);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ Assert(0);
+ Status = NDIS_STATUS_FAILURE;
+ NdisFreePacket(pPacket);
+ vboxNetFltWinMemFree(pMemBuf);
+ break;
+ }
+
+ NdisAllocateBuffer(&Status, &pOrigBuffer, pNetFlt->u.s.WinIf.hRecvBufferPool, pMemBuf, cbBuf);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ Assert(0);
+ Status = NDIS_STATUS_FAILURE;
+ NdisFreeBuffer(pTransferBuffer);
+ NdisFreePacket(pPacket);
+ vboxNetFltWinMemFree(pMemBuf);
+ break;
+ }
+
+ NdisChainBufferAtBack(pPacket, pTransferBuffer);
+
+ NdisMoveMappedMemory(pMemBuf, pHeaderBuffer, cbHeaderBuffer);
+
+ vboxNetFltWinPutPacketToList(&pNetFlt->u.s.WinIf.TransferDataList, pPacket, pOrigBuffer);
+
+#ifdef DEBUG_NETFLT_RECV_TRANSFERDATA
+ if (cbPacket == cbLookaheadBuffer)
+ {
+ NdisCopyLookaheadData(pMemBuf+cbHeaderBuffer,
+ pLookaheadBuffer,
+ cbLookaheadBuffer,
+ pNetFlt->u.s.WinIf.fMacOptions);
+ }
+ else
+#endif
+ {
+ Assert(cbPacket > cbLookaheadBuffer);
+
+ NdisTransferData(&Status, pNetFlt->u.s.WinIf.hBinding, MacReceiveContext,
+ 0, /* ByteOffset */
+ cbPacket, pPacket, &cbTransferred);
+ }
+
+ if (Status != NDIS_STATUS_PENDING)
+ {
+ vboxNetFltWinPtTransferDataComplete(pNetFlt, pPacket, Status, cbTransferred);
+ }
+ }
+ } while (0);
+
+ return Status;
+}
+
+static NDIS_STATUS vboxNetFltWinPtReceive(IN NDIS_HANDLE hProtocolBindingContext,
+ IN NDIS_HANDLE MacReceiveContext,
+ IN PVOID pHeaderBuffer,
+ IN UINT cbHeaderBuffer,
+ IN PVOID pLookAheadBuffer,
+ IN UINT cbLookAheadBuffer,
+ IN UINT cbPacket)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
+ PNDIS_PACKET pPacket = NULL;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ bool bNetFltActive;
+ bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive);
+ const bool bPassThruActive = !bNetFltActive;
+
+ LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
+
+ if (fWinIfActive)
+ {
+ do
+ {
+#ifndef DEBUG_NETFLT_RECV_NOPACKET
+ pPacket = NdisGetReceivedPacket(pNetFlt->u.s.WinIf.hBinding, MacReceiveContext);
+ if (pPacket)
+ {
+# ifndef VBOX_LOOPBACK_USEFLAGS
+ PNDIS_PACKET pLb = NULL;
+# else
+ if (vboxNetFltWinIsLoopedBackPacket(pPacket))
+ {
+ Assert(0);
+ /* nothing else to do here, just return the packet */
+ //NdisReturnPackets(&pPacket, 1);
+ Status = NDIS_STATUS_NOT_ACCEPTED;
+ break;
+ }
+
+ VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
+# endif
+
+ if (bNetFltActive)
+ {
+# ifndef VBOX_LOOPBACK_USEFLAGS
+ pLb = vboxNetFltWinLbSearchLoopBack(pNetFlt, pPacket, false);
+ if (!pLb)
+# endif
+ {
+ VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
+
+# ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0))
+ {
+ /* drop it */
+ break;
+ }
+# else
+ Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, PACKET_COPY);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ //NdisReturnPackets(&pPacket, 1);
+ fWinIfActive = false;
+ bNetFltActive = false;
+ break;
+ }
+# endif
+ }
+# ifndef VBOX_LOOPBACK_USEFLAGS
+ else if (vboxNetFltWinLbIsFromIntNet(pLb))
+ {
+ /* nothing else to do here, just return the packet */
+ //NdisReturnPackets(&pPacket, 1);
+ Status = NDIS_STATUS_NOT_ACCEPTED;
+ break;
+ }
+ /* we are here because this is a looped back packet set not from intnet
+ * we will post it to the upper protocol */
+# endif
+ }
+
+ Assert(Status == STATUS_SUCCESS);
+ if (Status == STATUS_SUCCESS)
+ {
+# ifndef VBOX_LOOPBACK_USEFLAGS
+ Assert(!pLb || !vboxNetFltWinLbIsFromIntNet(pLb));
+# endif
+ Status = vboxNetFltWinRecvPassThru(pNetFlt, pPacket);
+ Assert(Status == STATUS_SUCCESS);
+ /* we are done with packet processing, and we will
+ * not receive packet return event for this packet,
+ * fWinIfActive should be true to ensure we release WinIf*/
+ Assert(fWinIfActive);
+ if (Status == STATUS_SUCCESS)
+ break;
+ }
+ else
+ {
+ /* intnet processing failed - fall back to no-packet mode */
+ Assert(bNetFltActive);
+ Assert(fWinIfActive);
+ }
+
+ }
+#endif /* #ifndef DEBUG_NETFLT_RECV_NOPACKET */
+
+ if (bNetFltActive)
+ {
+ Status = vboxNetFltWinPtReceiveActive(pNetFlt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer,
+ pLookAheadBuffer, cbLookAheadBuffer, cbPacket);
+ if (NT_SUCCESS(Status))
+ {
+ if (Status != NDIS_STATUS_NOT_ACCEPTED)
+ {
+ fWinIfActive = false;
+ bNetFltActive = false;
+ }
+ else
+ {
+#ifndef VBOX_LOOPBACK_USEFLAGS
+ /* this is a loopback packet, nothing to do here */
+#else
+ Assert(0);
+ /* should not be here */
+#endif
+ }
+ break;
+ }
+ }
+
+ /* we are done with packet processing, and we will
+ * not receive packet return event for this packet,
+ * fWinIfActive should be true to ensure we release WinIf*/
+ Assert(fWinIfActive);
+
+ vboxNetFltWinRecvIndicatePassThru(pNetFlt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer, pLookAheadBuffer, cbLookAheadBuffer, cbPacket);
+ /* the status could contain an error value here in case the the IntNet recv failed,
+ * ensure we return back success status */
+ Status = NDIS_STATUS_SUCCESS;
+
+ } while (0);
+
+ if (bNetFltActive)
+ {
+ vboxNetFltWinDereferenceNetFlt(pNetFlt);
+ }
+ else if (bPassThruActive)
+ {
+ vboxNetFltWinDereferenceModePassThru(pNetFlt);
+ }
+ if (fWinIfActive)
+ {
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+ }
+ }
+ else
+ {
+ Status = NDIS_STATUS_FAILURE;
+ }
+
+ LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
+
+ return Status;
+
+}
+
+static VOID vboxNetFltWinPtReceiveComplete(NDIS_HANDLE hProtocolBindingContext)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
+ ULONG cPackets = 0;
+ bool bNetFltActive;
+ bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive);
+ NDIS_HANDLE hMiniport = pNetFlt->u.s.WinIf.hMiniport;
+ /* Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case
+ * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber
+ * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64
+ * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */
+ ULONG iProc = KeGetCurrentProcessorNumber();
+ Assert(iProc < RT_ELEMENTS(pNetFlt->u.s.WinIf.abIndicateRxComplete));
+
+ LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
+
+ if (hMiniport != NULL && pNetFlt->u.s.WinIf.abIndicateRxComplete[iProc])
+ {
+ switch (pNetFlt->u.s.WinIf.enmMedium)
+ {
+ case NdisMedium802_3:
+ case NdisMediumWan:
+ NdisMEthIndicateReceiveComplete(hMiniport);
+ break;
+ default:
+ Assert(0);
+ break;
+ }
+ }
+
+ pNetFlt->u.s.WinIf.abIndicateRxComplete[iProc] = FALSE;
+
+ if (fWinIfActive)
+ {
+ if (bNetFltActive)
+ {
+ vboxNetFltWinDereferenceNetFlt(pNetFlt);
+ }
+ else
+ {
+ vboxNetFltWinDereferenceModePassThru(pNetFlt);
+ }
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+ }
+
+ LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
+}
+
+static INT vboxNetFltWinPtReceivePacket(NDIS_HANDLE hProtocolBindingContext, PNDIS_PACKET pPacket)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
+ INT cRefCount = 0;
+ bool bNetFltActive;
+ bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive);
+ const bool bPassThruActive = !bNetFltActive;
+
+ LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
+
+ if (fWinIfActive)
+ {
+ do
+ {
+#ifdef VBOX_LOOPBACK_USEFLAGS
+ if (vboxNetFltWinIsLoopedBackPacket(pPacket))
+ {
+ Assert(0);
+ Log(("lb_rp"));
+
+ /* nothing else to do here, just return the packet */
+ cRefCount = 0;
+ //NdisReturnPackets(&pPacket, 1);
+ break;
+ }
+
+ VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
+#endif
+
+ if (bNetFltActive)
+ {
+#ifndef VBOX_LOOPBACK_USEFLAGS
+ PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pNetFlt, pPacket, false);
+ if (!pLb)
+#endif
+ {
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
+ NDIS_STATUS fStatus;
+#endif
+ bool bResources = NDIS_GET_PACKET_STATUS(pPacket) == NDIS_STATUS_RESOURCES;
+
+ VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
+#ifdef DEBUG_misha
+ /*TODO: remove this assert.
+ * this is a temporary assert for debugging purposes:
+ * we're probably doing something wrong with the packets if the miniport reports NDIS_STATUS_RESOURCES */
+ Assert(!bResources);
+#endif
+
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0))
+ {
+ /* drop it */
+ cRefCount = 0;
+ break;
+ }
+
+#else
+ fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, bResources ? PACKET_COPY : 0);
+ if (fStatus == NDIS_STATUS_SUCCESS)
+ {
+ bNetFltActive = false;
+ fWinIfActive = false;
+ if (bResources)
+ {
+ cRefCount = 0;
+ //NdisReturnPackets(&pPacket, 1);
+ }
+ else
+ {
+ cRefCount = 1;
+ }
+ break;
+ }
+ else
+ {
+ Assert(0);
+ }
+#endif
+ }
+#ifndef VBOX_LOOPBACK_USEFLAGS
+ else if (vboxNetFltWinLbIsFromIntNet(pLb))
+ {
+ /* the packet is from intnet, it has already been set to the host,
+ * no need for loopng it back to the host again */
+ /* nothing else to do here, just return the packet */
+ cRefCount = 0;
+ //NdisReturnPackets(&pPacket, 1);
+ break;
+ }
+#endif
+ }
+
+ cRefCount = vboxNetFltWinRecvPacketPassThru(pNetFlt, pPacket, bNetFltActive);
+ if (cRefCount)
+ {
+ Assert(cRefCount == 1);
+ fWinIfActive = false;
+ }
+
+ } while (FALSE);
+
+ if (bNetFltActive)
+ {
+ vboxNetFltWinDereferenceNetFlt(pNetFlt);
+ }
+ else if (bPassThruActive)
+ {
+ vboxNetFltWinDereferenceModePassThru(pNetFlt);
+ }
+ if (fWinIfActive)
+ {
+ vboxNetFltWinDereferenceWinIf(pNetFlt);
+ }
+ }
+ else
+ {
+ cRefCount = 0;
+ //NdisReturnPackets(&pPacket, 1);
+ }
+
+ LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), cRefCount (%d)\n", pNetFlt, cRefCount));
+
+ return cRefCount;
+}
+
+DECLHIDDEN(bool) vboxNetFltWinPtCloseInterface(PVBOXNETFLTINS pNetFlt, PNDIS_STATUS pStatus)
+{
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
+
+ if (pNetFlt->u.s.WinIf.StateFlags.fInterfaceClosing)
+ {
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+ Assert(0);
+ return false;
+ }
+ if (pNetFlt->u.s.WinIf.hBinding == NULL)
+ {
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+ Assert(0);
+ return false;
+ }
+
+ pNetFlt->u.s.WinIf.StateFlags.fInterfaceClosing = TRUE;
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+
+ NdisResetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent);
+ NdisCloseAdapter(pStatus, pNetFlt->u.s.WinIf.hBinding);
+ if (*pStatus == NDIS_STATUS_PENDING)
+ {
+ NdisWaitEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent, 0);
+ *pStatus = pNetFlt->u.s.WinIf.OpenCloseStatus;
+ }
+
+ Assert (*pStatus == NDIS_STATUS_SUCCESS);
+
+ pNetFlt->u.s.WinIf.hBinding = NULL;
+
+ return true;
+}
+
+static NDIS_STATUS vboxNetFltWinPtPnPSetPower(PVBOXNETFLTINS pNetFlt, NDIS_DEVICE_POWER_STATE enmPowerState)
+{
+ NDIS_DEVICE_POWER_STATE enmPrevPowerState = vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState);
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
+
+ vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.PtState, enmPowerState);
+
+ if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState) > NdisDeviceStateD0)
+ {
+ if (enmPrevPowerState == NdisDeviceStateD0)
+ {
+ pNetFlt->u.s.WinIf.StateFlags.fStandBy = TRUE;
+ }
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+ vboxNetFltWinPtRequestsWaitComplete(pNetFlt);
+ vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState);
+ vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.PtState);
+
+ /* check packet pool is empty */
+ UINT cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hSendPacketPool);
+ Assert(cPPUsage == 0);
+ cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool);
+ Assert(cPPUsage == 0);
+ /* for debugging only, ignore the err in release */
+ NOREF(cPPUsage);
+
+ Assert(!pNetFlt->u.s.WinIf.StateFlags.fRequestInfo);
+ }
+ else
+ {
+ if (enmPrevPowerState > NdisDeviceStateD0)
+ {
+ pNetFlt->u.s.WinIf.StateFlags.fStandBy = FALSE;
+ }
+
+ if (pNetFlt->u.s.WinIf.StateFlags.fRequestInfo & VBOXNDISREQUEST_QUEUED)
+ {
+ pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS;
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+
+ vboxNetFltWinMpRequestPost(pNetFlt);
+ }
+ else
+ {
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
+ }
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+static NDIS_STATUS vboxNetFltWinPtPnPEvent(IN NDIS_HANDLE hProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent)
+{
+ PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
+
+ LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), NetEvent (%d)\n", pNetFlt, pNetPnPEvent->NetEvent));
+
+ switch (pNetPnPEvent->NetEvent)
+ {
+ case NetEventSetPower:
+ {
+ NDIS_DEVICE_POWER_STATE enmPowerState = *((PNDIS_DEVICE_POWER_STATE)pNetPnPEvent->Buffer);
+ return vboxNetFltWinPtPnPSetPower(pNetFlt, enmPowerState);
+ }
+ case NetEventReconfigure:
+ {
+ if (!pNetFlt)
+ {
+ NdisReEnumerateProtocolBindings(g_VBoxNetFltGlobalsWin.Pt.hProtocol);
+ }
+ }
+ default:
+ return NDIS_STATUS_SUCCESS;
+ }
+
+ LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), NetEvent (%d)\n", pNetFlt, pNetPnPEvent->NetEvent));
+}
+
+#ifdef __cplusplus
+# define PTCHARS_40(_p) ((_p).Ndis40Chars)
+#else
+# define PTCHARS_40(_p) (_p)
+#endif
+
+/**
+ * register the protocol edge
+ */
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtRegister(PVBOXNETFLTGLOBALS_PT pGlobalsPt, PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr)
+{
+ NDIS_PROTOCOL_CHARACTERISTICS PtChars;
+ NDIS_STRING NameStr;
+
+ NdisInitUnicodeString(&NameStr, VBOXNETFLT_NAME_PROTOCOL);
+
+ NdisZeroMemory(&PtChars, sizeof (PtChars));
+ PTCHARS_40(PtChars).MajorNdisVersion = VBOXNETFLT_VERSION_PT_NDIS_MAJOR;
+ PTCHARS_40(PtChars).MinorNdisVersion = VBOXNETFLT_VERSION_PT_NDIS_MINOR;
+
+ PTCHARS_40(PtChars).Name = NameStr;
+ PTCHARS_40(PtChars).OpenAdapterCompleteHandler = vboxNetFltWinPtOpenAdapterComplete;
+ PTCHARS_40(PtChars).CloseAdapterCompleteHandler = vboxNetFltWinPtCloseAdapterComplete;
+ PTCHARS_40(PtChars).SendCompleteHandler = vboxNetFltWinPtSendComplete;
+ PTCHARS_40(PtChars).TransferDataCompleteHandler = vboxNetFltWinPtTransferDataComplete;
+ PTCHARS_40(PtChars).ResetCompleteHandler = vboxNetFltWinPtResetComplete;
+ PTCHARS_40(PtChars).RequestCompleteHandler = vboxNetFltWinPtRequestComplete;
+ PTCHARS_40(PtChars).ReceiveHandler = vboxNetFltWinPtReceive;
+ PTCHARS_40(PtChars).ReceiveCompleteHandler = vboxNetFltWinPtReceiveComplete;
+ PTCHARS_40(PtChars).StatusHandler = vboxNetFltWinPtStatus;
+ PTCHARS_40(PtChars).StatusCompleteHandler = vboxNetFltWinPtStatusComplete;
+ PTCHARS_40(PtChars).BindAdapterHandler = vboxNetFltWinPtBindAdapter;
+ PTCHARS_40(PtChars).UnbindAdapterHandler = vboxNetFltWinPtUnbindAdapter;
+ PTCHARS_40(PtChars).UnloadHandler = vboxNetFltWinPtUnloadProtocol;
+#if !defined(DEBUG_NETFLT_RECV)
+ PTCHARS_40(PtChars).ReceivePacketHandler = vboxNetFltWinPtReceivePacket;
+#endif
+ PTCHARS_40(PtChars).PnPEventHandler = vboxNetFltWinPtPnPEvent;
+
+ NDIS_STATUS Status;
+ NdisRegisterProtocol(&Status, &pGlobalsPt->hProtocol, &PtChars, sizeof (PtChars));
+ Assert(Status == STATUS_SUCCESS);
+ return Status;
+}
+
+/**
+ * deregister the protocol edge
+ */
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDeregister(PVBOXNETFLTGLOBALS_PT pGlobalsPt)
+{
+ if (!pGlobalsPt->hProtocol)
+ return NDIS_STATUS_SUCCESS;
+
+ NDIS_STATUS Status;
+
+ NdisDeregisterProtocol(&Status, pGlobalsPt->hProtocol);
+ Assert (Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ NdisZeroMemory(pGlobalsPt, sizeof (*pGlobalsPt));
+ }
+ return Status;
+}
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.h
new file mode 100644
index 000000000..63e8f102b
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.h
@@ -0,0 +1,29 @@
+/* $Id: VBoxNetFltP-win.h 36184 2011-03-07 10:57:04Z vboxsync $ */
+/** @file
+ * VBoxNetFltP-win.h - Bridged Networking Driver, Windows Specific Code.
+ * Protocol edge API
+ */
+/*
+ * 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 ___VBoxNetFltP_win_h___
+#define ___VBoxNetFltP_win_h___
+
+#ifdef VBOXNETADP
+# error "No protocol edge"
+#endif
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtRegister(PVBOXNETFLTGLOBALS_PT pGlobalsPt, PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr);
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDeregister(PVBOXNETFLTGLOBALS_PT pGlobalsPt);
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoUnbinding(PVBOXNETFLTINS pNetFlt, bool bOnUnbind);
+DECLHIDDEN(VOID) vboxNetFltWinPtRequestComplete(NDIS_HANDLE hContext, PNDIS_REQUEST pNdisRequest, NDIS_STATUS Status);
+DECLHIDDEN(bool) vboxNetFltWinPtCloseInterface(PVBOXNETFLTINS pNetFlt, PNDIS_STATUS pStatus);
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(PVBOXNETFLTINS pThis, PNDIS_STRING pOurDeviceName, PNDIS_STRING pBindToDeviceName);
+#endif /* #ifndef ___VBoxNetFltP_win_h___ */
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.c b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.cpp
index 02f1651ba..7175be6b3 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFlt-win.c $ */
+/* $Id: VBoxNetFltRt-win.cpp 37161 2011-05-20 07:28:21Z vboxsync $ */
/** @file
- * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Integration with IntNet/NetFlt
+ * VBoxNetFltRt-win.cpp - Bridged Networking Driver, Windows Specific Code.
+ * NetFlt Runtime
*/
-
/*
- * Copyright (C) 2008 Oracle Corporation
+ * 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;
@@ -14,30 +14,25 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-/*
- * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
- * Copyright (c) 1993-1999, Microsoft Corporation
- */
-
-#include "VBoxNetFltCommon-win.h"
+#include "VBoxNetFltCmn-win.h"
#include <VBox/intnetinline.h>
#include <iprt/thread.h>
/** represents the job element of the job queue
- * see comments for JOB_QUEUE */
-typedef struct _JOB
+ * see comments for VBOXNETFLT_JOB_QUEUE */
+typedef struct VBOXNETFLT_JOB
{
/** link in the job queue */
LIST_ENTRY ListEntry;
/** job function to be executed */
- JOB_ROUTINE pRoutine;
+ PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine;
/** parameter to be passed to the job function */
PVOID pContext;
/** event that will be fired on job completion */
KEVENT CompletionEvent;
/** true if the job manager should use the completion even for completion indication, false-otherwise*/
bool bUseCompletionEvent;
-} JOB, *PJOB;
+} VBOXNETFLT_JOB, *PVBOXNETFLT_JOB;
/**
* represents the queue of jobs processed by the worker thread
@@ -46,7 +41,7 @@ typedef struct _JOB
* our callbacks may be called at APC level by IntNet, there are some tasks that we can not create at APC,
* e.g. thread creation. This is why we schedule such jobs to the worker thread working at passive level
*/
-typedef struct _JOB_QUEUE
+typedef struct VBOXNETFLT_JOB_QUEUE
{
/* jobs */
LIST_ENTRY Jobs;
@@ -58,7 +53,7 @@ typedef struct _JOB_QUEUE
KEVENT NotifyEvent;
/** worker thread */
PKTHREAD pThread;
-} JOB_QUEUE, *PJOB_QUEUE;
+} VBOXNETFLT_JOB_QUEUE, *PVBOXNETFLT_JOB_QUEUE;
typedef struct _CREATE_INSTANCE_CONTEXT
{
@@ -69,7 +64,7 @@ typedef struct _CREATE_INSTANCE_CONTEXT
NDIS_HANDLE hMiniportAdapter;
NDIS_HANDLE hWrapperConfigurationContext;
#endif
- NDIS_STATUS Status;
+ NDIS_STATUS Status;
}CREATE_INSTANCE_CONTEXT, *PCREATE_INSTANCE_CONTEXT;
/*contexts used for our jobs */
@@ -92,33 +87,29 @@ typedef struct _WORKER_INFO
/* idc initialization */
typedef struct _INIT_IDC_INFO
{
- JOB Job;
- bool bInitialized;
- volatile bool bStop;
+ VBOXNETFLT_JOB Job;
+ bool bInitialized;
+ volatile bool bStop;
volatile int rc;
KEVENT hCompletionEvent;
}INIT_IDC_INFO, *PINIT_IDC_INFO;
/** globals */
-
-/** global lock */
-NDIS_SPIN_LOCK g_GlobalLock;
/** global job queue. some operations are required to be done at passive level, e.g. thread creation, adapter bind/unbind initiation,
* while IntNet typically calls us APC_LEVEL, so we just create a system thread in our DriverEntry and enqueue the jobs to that thread */
-static JOB_QUEUE g_JobQueue;
+static VBOXNETFLT_JOB_QUEUE g_VBoxJobQueue;
+volatile static bool g_bVBoxIdcInitialized;
+INIT_IDC_INFO g_VBoxInitIdcInfo;
/**
* The (common) global data.
*/
static VBOXNETFLTGLOBALS g_VBoxNetFltGlobals;
-volatile static bool g_bIdcInitialized;
-INIT_IDC_INFO g_InitIdcInfo;
-
-UINT g_fPacketDontLoopBack;
-UINT g_fPacketIsLoopedBack;
+/* win-specific global data */
+VBOXNETFLTGLOBALS_WIN g_VBoxNetFltGlobalsWin = {0};
#define LIST_ENTRY_2_JOB(pListEntry) \
- ( (PJOB)((uint8_t *)(pListEntry) - RT_OFFSETOF(JOB, ListEntry)) )
+ ( (PVBOXNETFLT_JOB)((uint8_t *)(pListEntry) - RT_OFFSETOF(VBOXNETFLT_JOB, ListEntry)) )
static int vboxNetFltWinAttachToInterface(PVBOXNETFLTINS pThis, void * pContext, bool fRediscovery);
static int vboxNetFltWinConnectIt(PVBOXNETFLTINS pThis);
@@ -136,7 +127,7 @@ DECLHIDDEN(void) vboxNetFltWinSleep(ULONG milis)
}
/** wait for the given device to be dereferenced */
-DECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState)
+DECLHIDDEN(void) vboxNetFltWinWaitDereference(PVBOXNETFLT_WINIF_DEVICE pState)
{
#ifdef DEBUG
uint64_t StartNanoTS = RTTimeSystemNanoTS();
@@ -149,9 +140,9 @@ DECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState)
vboxNetFltWinSleep(2);
#ifdef DEBUG
CurNanoTS = RTTimeSystemNanoTS();
- if(CurNanoTS - StartNanoTS > 20000000)
+ if (CurNanoTS - StartNanoTS > 20000000)
{
- DBGPRINT(("device not idle"));
+ LogRel(("device not idle"));
AssertFailed();
// break;
}
@@ -166,16 +157,16 @@ DECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState)
DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMemAlloc(PVOID* ppMemBuf, UINT cbLength)
{
#ifdef DEBUG_NETFLT_USE_EXALLOC
- *ppMemBuf = ExAllocatePoolWithTag(NonPagedPool, cbLength, MEM_TAG);
- if(*ppMemBuf)
+ *ppMemBuf = ExAllocatePoolWithTag(NonPagedPool, cbLength, VBOXNETFLT_MEM_TAG);
+ if (*ppMemBuf)
{
NdisZeroMemory(*ppMemBuf, cbLength);
return NDIS_STATUS_SUCCESS;
}
return NDIS_STATUS_FAILURE;
#else
- NDIS_STATUS fStatus = NdisAllocateMemoryWithTag(ppMemBuf, cbLength, MEM_TAG);
- if(fStatus == NDIS_STATUS_SUCCESS)
+ NDIS_STATUS fStatus = NdisAllocateMemoryWithTag(ppMemBuf, cbLength, VBOXNETFLT_MEM_TAG);
+ if (fStatus == NDIS_STATUS_SUCCESS)
{
NdisZeroMemory(*ppMemBuf, cbLength);
}
@@ -193,58 +184,10 @@ DECLHIDDEN(void) vboxNetFltWinMemFree(PVOID pvMemBuf)
#endif
}
-/* frees ndis buffers used on send/receive */
-static VOID vboxNetFltWinFiniBuffers(PADAPT pAdapt)
-{
- /* NOTE: don't check for NULL since NULL is a valid handle */
-#ifndef VBOXNETADP
- NdisFreeBufferPool(pAdapt->hSendBufferPoolHandle);
-#endif
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- NdisFreeBufferPool(pAdapt->hRecvBufferPoolHandle);
-#endif
-}
-
-/* initializes ndis buffers used on send/receive */
-static NDIS_STATUS vboxNetFltWinInitBuffers(PADAPT pAdapt)
-{
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
-
- do
- {
- /* NOTE: NULL is a valid handle !!! */
-#ifndef VBOXNETADP
- NdisAllocateBufferPool(&Status,
- &pAdapt->hSendBufferPoolHandle,
- TX_BUFFER_POOL_SIZE);
- Assert(Status == NDIS_STATUS_SUCCESS);
- if (Status != NDIS_STATUS_SUCCESS)
- {
- break;
- }
-#endif
-
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- /* NOTE: NULL is a valid handle !!! */
- NdisAllocateBufferPool(&Status,
- &pAdapt->hRecvBufferPoolHandle,
- RX_BUFFER_POOL_SIZE);
- Assert(Status == NDIS_STATUS_SUCCESS);
- if (Status != NDIS_STATUS_SUCCESS)
- {
-#ifndef VBOXNETADP
- NdisFreeBufferPool(pAdapt->hSendBufferPoolHandle);
-#endif
- break;
- }
-#endif
- } while (FALSE);
-
- return Status;
-}
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
/* initializes packet info pool and allocates the cSize packet infos for the pool */
-static NDIS_STATUS vboxNetFltWinPpAllocatePacketInfoPool(PPACKET_INFO_POOL pPool, UINT cSize)
+static NDIS_STATUS vboxNetFltWinPpAllocatePacketInfoPool(PVBOXNETFLT_PACKET_INFO_POOL pPool, UINT cSize)
{
UINT cbBufSize = sizeof(PACKET_INFO)*cSize;
PACKET_INFO * pPacketInfos;
@@ -257,12 +200,12 @@ static NDIS_STATUS vboxNetFltWinPpAllocatePacketInfoPool(PPACKET_INFO_POOL pPool
fStatus = vboxNetFltWinMemAlloc((PVOID*)&pPacketInfos, cbBufSize);
- if(fStatus == NDIS_STATUS_SUCCESS)
+ if (fStatus == NDIS_STATUS_SUCCESS)
{
- PPACKET_INFO pInfo;
+ PVBOXNETFLTPACKET_INFO pInfo;
pPool->pBuffer = pPacketInfos;
- for(i = 0; i < cSize; i++)
+ for (i = 0; i < cSize; i++)
{
pInfo = &pPacketInfos[i];
vboxNetFltWinQuEnqueueTail(&pPool->Queue.Queue, pInfo);
@@ -278,13 +221,15 @@ static NDIS_STATUS vboxNetFltWinPpAllocatePacketInfoPool(PPACKET_INFO_POOL pPool
}
/* frees the packet info pool */
-VOID vboxNetFltWinPpFreePacketInfoPool(PPACKET_INFO_POOL pPool)
+VOID vboxNetFltWinPpFreePacketInfoPool(PVBOXNETFLT_PACKET_INFO_POOL pPool)
{
vboxNetFltWinMemFree(pPool->pBuffer);
FINI_INTERLOCKED_PACKET_QUEUE(&pPool->Queue)
}
+#endif
+
/**
* copies one string to another. in case the destination string size is not enough to hold the complete source string
* does nothing and returns NDIS_STATUS_RESOURCES .
@@ -293,9 +238,9 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
- if(pDst != pSrc)
+ if (pDst != pSrc)
{
- if(pDst->MaximumLength < pSrc->Length)
+ if (pDst->MaximumLength < pSrc->Length)
{
AssertFailed();
Status = NDIS_STATUS_RESOURCES;
@@ -304,7 +249,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING
{
pDst->Length = pSrc->Length;
- if(pDst->Buffer != pSrc->Buffer)
+ if (pDst->Buffer != pSrc->Buffer)
{
NdisMoveMemory(pDst->Buffer, pSrc->Buffer, pSrc->Length);
}
@@ -339,15 +284,11 @@ static NDIS_STATUS vboxNetFltWinNdisBufferMoveToSG0(PNDIS_BUFFER pBuffer, PINTNE
Assert(paSeg->pv);
- while(pBuffer)
+ while (pBuffer)
{
- NdisQueryBufferSafe(
- pBuffer,
- &pVirtualAddress,
- &cbCurrentLength,
- NormalPagePriority);
+ NdisQueryBufferSafe(pBuffer, &pVirtualAddress, &cbCurrentLength, NormalPagePriority);
- if(!pVirtualAddress)
+ if (!pVirtualAddress)
{
fStatus = NDIS_STATUS_FAILURE;
break;
@@ -358,15 +299,13 @@ static NDIS_STATUS vboxNetFltWinNdisBufferMoveToSG0(PNDIS_BUFFER pBuffer, PINTNE
NdisMoveMemory(ptr, pVirtualAddress, cbCurrentLength);
ptr += cbCurrentLength;
- NdisGetNextBuffer(
- pBuffer,
- &pBuffer);
+ NdisGetNextBuffer(pBuffer, &pBuffer);
}
- if(fStatus == NDIS_STATUS_SUCCESS)
+ if (fStatus == NDIS_STATUS_SUCCESS)
{
pSG->cSegsUsed = 1;
- Assert(pSG->cbTotal == paSeg->cb);
+ Assert(pSG->cbTotal == paSeg->cb);
}
return fStatus;
}
@@ -376,21 +315,18 @@ static NDIS_STATUS vboxNetFltWinNdisBufferMoveToSG0(PNDIS_BUFFER pBuffer, PINTNE
static NDIS_STATUS vboxNetFltWinNdisBuffersToSG(PNDIS_BUFFER pBuffer, PINTNETSG pSG)
{
UINT cSegs = 0;
- NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PVOID pVirtualAddress;
UINT cbCurrentLength;
- while(pBuffer)
+ while (pBuffer)
{
- NdisQueryBufferSafe(
- pBuffer,
- &pVirtualAddress,
- &cbCurrentLength,
- NormalPagePriority);
+ NdisQueryBufferSafe(pBuffer, &pVirtualAddress, &cbCurrentLength, NormalPagePriority);
- if(!pVirtualAddress) {
- fStatus = NDIS_STATUS_FAILURE;
- break;
+ if (!pVirtualAddress)
+ {
+ Status = NDIS_STATUS_FAILURE;
+ break;
}
pSG->cbTotal += cbCurrentLength;
@@ -399,19 +335,17 @@ static NDIS_STATUS vboxNetFltWinNdisBuffersToSG(PNDIS_BUFFER pBuffer, PINTNETSG
pSG->aSegs[cSegs].Phys = NIL_RTHCPHYS;
cSegs++;
- NdisGetNextBuffer(
- pBuffer,
- &pBuffer);
+ NdisGetNextBuffer(pBuffer, &pBuffer);
}
AssertFatal(cSegs <= pSG->cSegsAlloc);
- if(fStatus == NDIS_STATUS_SUCCESS)
+ if (Status == NDIS_STATUS_SUCCESS)
{
pSG->cSegsUsed = cSegs;
}
- return fStatus;
+ return Status;
}
static void vboxNetFltWinDeleteSG(PINTNETSG pSG)
@@ -423,7 +357,7 @@ static PINTNETSG vboxNetFltWinCreateSG(uint32_t cSegs)
{
PINTNETSG pSG;
NTSTATUS Status = vboxNetFltWinMemAlloc((PVOID*)&pSG, RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
- if(Status == STATUS_SUCCESS)
+ if (Status == STATUS_SUCCESS)
{
IntNetSgInitTempSegs(pSG, 0 /*cbTotal*/, cSegs, 0 /*cSegsUsed*/);
return pSG;
@@ -436,23 +370,23 @@ static PINTNETSG vboxNetFltWinCreateSG(uint32_t cSegs)
* packet queue functions
************************************************************************************/
#ifndef VBOXNETFLT_NO_PACKET_QUEUE
-#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
-static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket, PINTNETSG pSG, uint32_t fFlags
+#if !defined(VBOXNETADP)
+static NDIS_STATUS vboxNetFltWinQuPostPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PINTNETSG pSG, uint32_t fFlags
# ifdef DEBUG_NETFLT_PACKETS
, PNDIS_PACKET pTmpPacket
# endif
)
{
- NDIS_STATUS fStatus;
+ NDIS_STATUS Status;
PNDIS_PACKET pMyPacket;
bool bSrcHost = fFlags & PACKET_SRC_HOST;
LogFlow(("posting packet back to driver stack..\n"));
- if(!pPacket)
+ if (!pPacket)
{
/* INTNETSG was in the packet queue, create a new NdisPacket from INTNETSG*/
- pMyPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, /* PADAPT */
+ pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt,
pSG, /* PINTNETSG */
pSG, /* PVOID pBufToFree */
bSrcHost, /* bool bToWire */
@@ -479,20 +413,20 @@ static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket
/* NDIS_PACKET was in the packet queue */
DBG_CHECK_PACKET_AND_SG(pPacket, pSG);
- if(!(fFlags & PACKET_MINE))
+ if (!(fFlags & PACKET_MINE))
{
/* the packet is the one that was passed to us in send/receive callback
* According to the DDK, we can not post it further,
* instead we should allocate our own packet.
* So, allocate our own packet (pMyPacket) and copy the packet info there */
- if(bSrcHost)
+ if (bSrcHost)
{
- fStatus = vboxNetFltWinPrepareSendPacket(pAdapt, pPacket, &pMyPacket/*, true*/);
+ Status = vboxNetFltWinPrepareSendPacket(pNetFlt, pPacket, &pMyPacket/*, true*/);
LogFlow(("packet from wire, packet created (%p)\n", pMyPacket));
}
else
{
- fStatus = vboxNetFltWinPrepareRecvPacket(pAdapt, pPacket, &pMyPacket, false);
+ Status = vboxNetFltWinPrepareRecvPacket(pNetFlt, pPacket, &pMyPacket, false);
LogFlow(("packet from wire, packet created (%p)\n", pMyPacket));
}
}
@@ -508,26 +442,26 @@ static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket
if (pMyPacket)
{
/* we have successfully initialized our packet, post it to the host or to the wire */
- if(bSrcHost)
+ if (bSrcHost)
{
#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
- vboxNetFltWinLbPutSendPacket(pAdapt, pMyPacket, false /* bFromIntNet */);
+ vboxNetFltWinLbPutSendPacket(pNetFlt, pMyPacket, false /* bFromIntNet */);
#endif
- NdisSend(&fStatus, pAdapt->hBindingHandle, pMyPacket);
+ NdisSend(&Status, pNetFlt->u.s.hBinding, pMyPacket);
- if (fStatus != NDIS_STATUS_PENDING)
+ if (Status != NDIS_STATUS_PENDING)
{
#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
/* the status is NOT pending, complete the packet */
- bool bTmp = vboxNetFltWinLbRemoveSendPacket(pAdapt, pMyPacket);
+ bool bTmp = vboxNetFltWinLbRemoveSendPacket(pNetFlt, pMyPacket);
Assert(bTmp);
#endif
- if(pPacket)
+ if (pPacket)
{
LogFlow(("status is not pending, completing packet (%p)\n", pPacket));
-#ifndef WIN9X
+
NdisIMCopySendCompletePerPacketInfo (pPacket, pMyPacket);
-#endif
+
NdisFreePacket(pMyPacket);
}
else
@@ -543,9 +477,9 @@ static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket
}
else
{
- NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, &pMyPacket, 1);
+ NdisMIndicateReceivePacket(pNetFlt->u.s.hMiniport, &pMyPacket, 1);
- fStatus = NDIS_STATUS_PENDING;
+ Status = NDIS_STATUS_PENDING;
/* the packet receive completion is always indicated via MiniportReturnPacket */
}
}
@@ -553,10 +487,10 @@ static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket
{
/*we failed to create our packet */
AssertFailed();
- fStatus = NDIS_STATUS_FAILURE;
+ Status = NDIS_STATUS_FAILURE;
}
- return fStatus;
+ return Status;
}
#endif
@@ -567,7 +501,6 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
{
PNDIS_PACKET pPacket = NULL;
PINTNETSG pSG = NULL;
- PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pNetFltIf);
NDIS_STATUS Status;
#ifndef VBOXNETADP
bool bSrcHost;
@@ -585,7 +518,7 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
#endif
#ifndef VBOXNETADP
- bSrcHost = (fFlags & PACKET_SRC_HOST) != 0;
+ bSrcHost = (fFlags & VBOXNETFLT_PACKET_SRC_HOST) != 0;
#endif
/* we first need to obtain the INTNETSG to be passed to intnet */
@@ -596,33 +529,27 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
* however in case our ProtocolReceive is called or the packet's status is set to NDIS_STSTUS_RESOURCES
* in ProtocolReceivePacket, we must return the packet immediately on ProtocolReceive*** exit
* In this case we allocate the INTNETSG, copy the ndis packet data there and enqueue it.
- * In this case the packet info flags has the PACKET_SG fag set
+ * In this case the packet info flags has the VBOXNETFLT_PACKET_SG fag set
*
* Besides that the NDIS_PACKET contained in the queue could be either the one passed to us in our send/receive callback
* or the one created by us. The latter is possible in case our ProtocolReceive callback is called and we call NdisTransferData
* in this case we need to allocate the packet the data to be transferred to.
- * If the enqueued packet is the one allocated by us the PACKET_MINE flag is set
+ * If the enqueued packet is the one allocated by us the VBOXNETFLT_PACKET_MINE flag is set
* */
- if((fFlags & PACKET_SG) == 0)
+ if ((fFlags & VBOXNETFLT_PACKET_SG) == 0)
{
/* we have NDIS_PACKET enqueued, we need to convert it to INTNETSG to be passed to intnet */
- PNDIS_BUFFER pCurrentBuffer = NULL;
- UINT cBufferCount;
- UINT uBytesCopied = 0;
- UINT cbPacketLength;
+ PNDIS_BUFFER pCurrentBuffer = NULL;
+ UINT cBufferCount;
+ UINT uBytesCopied = 0;
+ UINT cbPacketLength;
pPacket = (PNDIS_PACKET)pvPacket;
LogFlow(("ndis packet info, packet (%p)\n", pPacket));
LogFlow(("preparing pSG"));
- NdisQueryPacket(pPacket,
- NULL,
- &cBufferCount,
- &pCurrentBuffer,
- &cbPacketLength);
-
-
+ NdisQueryPacket(pPacket, NULL, &cBufferCount, &pCurrentBuffer, &cbPacketLength);
Assert(cBufferCount);
#ifdef VBOXNETFLT_NO_PACKET_QUEUE
@@ -632,13 +559,13 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
* somewhere outside of our driver (3 pages of system thread stack does not seem to be enough)
*
* since we have a "serialized" packet processing, i.e. all packets are being processed and passed
- * to intnet by this thread, we just use one previously allocated INTNETSG which is stored in PADAPT */
+ * to intnet by this thread, we just use one previously allocated INTNETSG which is stored in PVBOXNETFLTINS */
pSG = pWorker->pSG;
- if(cBufferCount > pSG->cSegsAlloc)
+ if (cBufferCount > pSG->cSegsAlloc)
{
pSG = vboxNetFltWinCreateSG(cBufferCount + 2);
- if(pSG)
+ if (pSG)
{
vboxNetFltWinDeleteSG(pWorker->pSG);
pWorker->pSG = pSG;
@@ -650,7 +577,7 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
}
#endif
- if(pSG)
+ if (pSG)
{
#ifdef VBOXNETFLT_NO_PACKET_QUEUE
bDeleteSG = true;
@@ -660,7 +587,7 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
/* convert the ndis buffers to INTNETSG */
Status = vboxNetFltWinNdisBuffersToSG(pCurrentBuffer, pSG);
- if(Status != NDIS_STATUS_SUCCESS)
+ if (Status != NDIS_STATUS_SUCCESS)
{
pSG = NULL;
}
@@ -674,15 +601,11 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
{
/* we have the INTNETSG enqueued. (see the above comment explaining why/when this may happen)
* just use the INTNETSG to pass it to intnet */
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- #ifndef VBOXNETADP
+#ifndef VBOXNETADP
/* the PINTNETSG is stored only when the underlying miniport
* indicates NDIS_STATUS_RESOURCES, we should never have this when processing
* the "from-host" packedts */
Assert(!bSrcHost);
- #endif
-#else
- /* we have both host and wire in ProtocolReceive */
#endif
pSG = (PINTNETSG)pvPacket;
@@ -690,10 +613,10 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
}
#ifdef DEBUG_NETFLT_PACKETS
- if(!pPacket && !pTmpPacket)
+ if (!pPacket && !pTmpPacket)
{
/* create tmp packet that woud be used for matching */
- pTmpPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, /* PADAPT */
+ pTmpPacket = vboxNetFltWinNdisPacketFromSG(pNetFltIf,
pSG, /* PINTNETSG */
pSG, /* PVOID pBufToFree */
bSrcHost, /* bool bToWire */
@@ -710,37 +633,34 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
{
#ifndef VBOXNETADP
/* the pSG was successfully initialized, post it to the netFlt*/
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- bDropIt =
-#endif
- pSG ? pNetFltIf->pSwitchPort->pfnRecv(pNetFltIf->pSwitchPort, NULL /* pvIf */, pSG,
+ bDropIt = pSG ? pNetFltIf->pSwitchPort->pfnRecv(pNetFltIf->pSwitchPort, NULL /* pvIf */, pSG,
bSrcHost ? INTNETTRUNKDIR_HOST : INTNETTRUNKDIR_WIRE
)
: false;
#else
- if(pSG)
+ if (pSG)
{
pNetFltIf->pSwitchPort->pfnRecv(pNetFltIf->pSwitchPort, NULL /* pvIf */, pSG, INTNETTRUNKDIR_HOST);
- STATISTIC_INCREASE(pAdapt->cTxSuccess);
+ STATISTIC_INCREASE(pNetFltIf->u.s.WinIf.cTxSuccess);
}
else
{
- STATISTIC_INCREASE(pAdapt->cTxError);
+ STATISTIC_INCREASE(pNetFltIf->u.s.WinIf.cTxError);
}
#endif
#ifndef VBOXNETFLT_NO_PACKET_QUEUE
-# if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
- if(!bDropIt)
+# if !defined(VBOXNETADP)
+ if (!bDropIt)
{
- Status = vboxNetFltWinQuPostPacket(pAdapt, pPacket, pSG, fFlags
+ Status = vboxNetFltWinQuPostPacket(pNetFltIf, pPacket, pSG, fFlags
# ifdef DEBUG_NETFLT_PACKETS
, pTmpPacket
# endif
);
- if(Status == NDIS_STATUS_PENDING)
+ if (Status == NDIS_STATUS_PENDING)
{
/* we will process packet completion in the completion routine */
bPending = true;
@@ -754,20 +674,18 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
}
/* drop it */
- if(pPacket)
+ if (pPacket)
{
- if(!(fFlags & PACKET_MINE))
+ if (!(fFlags & PACKET_MINE))
{
-# if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
+# if !defined(VBOXNETADP)
/* complete the packets */
- if(fFlags & PACKET_SRC_HOST)
+ if (fFlags & PACKET_SRC_HOST)
{
# endif
-# ifndef VBOX_NETFLT_ONDEMAND_BIND
/* NDIS_SET_PACKET_STATUS(pPacket, Status); */
- NdisMSendComplete(pAdapt->hMiniportHandle, pPacket, Status);
-# endif
-# if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
+ NdisMSendComplete(pNetFltIf->u.s.hMiniport, pPacket, Status);
+# if !defined(VBOXNETADP)
}
else
{
@@ -775,15 +693,13 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
# ifndef VBOXNETADP
NdisReturnPackets(&pPacket, 1);
# endif
-# if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
+# if !defined(VBOXNETADP)
}
# endif
}
else
{
-# ifndef VBOX_NETFLT_ONDEMAND_BIND
Assert(!(fFlags & PACKET_SRC_HOST));
-# endif
vboxNetFltWinFreeSGNdisPacket(pPacket, true);
}
}
@@ -795,10 +711,10 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
# ifndef VBOXNETADP
bPending = false;
# endif
- } while(0);
+ } while (0);
#ifdef DEBUG_NETFLT_PACKETS
- if(pTmpPacket)
+ if (pTmpPacket)
{
vboxNetFltWinFreeSGNdisPacket(pTmpPacket, true);
}
@@ -810,7 +726,7 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
return false;
#endif
#else /* #ifdef VBOXNETFLT_NO_PACKET_QUEUE */
- } while(0);
+ } while (0);
if (bDeleteSG)
vboxNetFltWinMemFree(pSG);
@@ -822,7 +738,6 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke
# endif
#endif
}
-
#ifndef VBOXNETFLT_NO_PACKET_QUEUE
/*
* thread start function for the thread which processes the packets enqueued in our send and receive callbacks called by ndis
@@ -836,39 +751,34 @@ static VOID vboxNetFltWinQuPacketQueueWorkerThreadProc(PVBOXNETFLTINS pNetFltIf)
{
bool fResume = true;
NTSTATUS fStatus;
- PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pNetFltIf);
PPACKET_QUEUE_WORKER pWorker = &pNetFltIf->u.s.PacketQueueWorker;
- /* two events we're waiting is "kill" and "notify" events
- * the former is used for the thread termination
- * the latter gets fired each time the packet is added to the queue */
- PVOID pEvents[] = {
- (PVOID) &pWorker->KillEvent,
- (PVOID) &pWorker->NotifyEvent,
- };
+ PVOID apEvents[] = {
+ (PVOID)&pWorker->KillEvent,
+ (PVOID)&pWorker->NotifyEvent
+ };
- while(fResume)
+ while (fResume)
{
uint32_t cNumProcessed;
uint32_t cNumPostedToHostWire;
- fStatus = KeWaitForMultipleObjects(2, pEvents, WaitAny, Executive, KernelMode, FALSE,
- NULL, NULL);
- if(!NT_SUCCESS(fStatus) || fStatus == STATUS_WAIT_0)
+ fStatus = KeWaitForMultipleObjects(RT_ELEMENTS(apEvents), apEvents, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);
+ if (!NT_SUCCESS(fStatus) || fStatus == STATUS_WAIT_0)
{
/* "kill" event was set
* will process queued packets and exit */
fResume = false;
}
- LogFlow(("==> processing vboxNetFltWinQuPacketQueueWorkerThreadProc\n"));
+ LogFlow(("processing vboxNetFltWinQuPacketQueueWorkerThreadProc\n"));
cNumProcessed = 0;
cNumPostedToHostWire = 0;
do
{
- PPACKET_INFO pInfo;
+ PVBOXNETFLTPACKET_INFO pInfo;
#ifdef DEBUG_NETFLT_PACKETS
/* packet used for matching */
@@ -880,14 +790,14 @@ static VOID vboxNetFltWinQuPacketQueueWorkerThreadProc(PVBOXNETFLTINS pNetFltIf)
* the same should be done for enqueue !!! */
pInfo = vboxNetFltWinQuInterlockedDequeueHead(&pWorker->PacketQueue);
- if(!pInfo)
+ if (!pInfo)
{
break;
}
- LogFlow(("==> found info (%p)\n", pInfo));
+ LogFlow(("found info (0x%p)\n", pInfo));
- if(vboxNetFltWinQuProcessInfo(pNetFltIf, pWorker, pInfo->pPacket, pInfo->fFlags))
+ if (vboxNetFltWinQuProcessInfo(pNetFltIf, pWorker, pInfo->pPacket, pInfo->fFlags))
{
cNumPostedToHostWire++;
}
@@ -895,17 +805,17 @@ static VOID vboxNetFltWinQuPacketQueueWorkerThreadProc(PVBOXNETFLTINS pNetFltIf)
vboxNetFltWinPpFreePacketInfo(pInfo);
cNumProcessed++;
- } while(TRUE);
+ } while (TRUE);
- if(cNumProcessed)
+ if (cNumProcessed)
{
vboxNetFltWinDecReferenceNetFlt(pNetFltIf, cNumProcessed);
Assert(cNumProcessed >= cNumPostedToHostWire);
- if(cNumProcessed != cNumPostedToHostWire)
+ if (cNumProcessed != cNumPostedToHostWire)
{
- vboxNetFltWinDecReferenceAdapt(pAdapt, cNumProcessed - cNumPostedToHostWire);
+ vboxNetFltWinDecReferenceWinIf(pNetFltIf, cNumProcessed - cNumPostedToHostWire);
}
}
}
@@ -916,24 +826,23 @@ static VOID vboxNetFltWinQuPacketQueueWorkerThreadProc(PVBOXNETFLTINS pNetFltIf)
/**
* thread start function for the job processing thread
*
- * see comments for PJOB_QUEUE
+ * see comments for PVBOXNETFLT_JOB_QUEUE
*/
-static VOID vboxNetFltWinJobWorkerThreadProc(PJOB_QUEUE pQueue)
+static VOID vboxNetFltWinJobWorkerThreadProc(PVBOXNETFLT_JOB_QUEUE pQueue)
{
bool fResume = true;
NTSTATUS Status;
- PVOID pEvents[] = {
- (PVOID) &pQueue->KillEvent,
- (PVOID) &pQueue->NotifyEvent,
- };
+ PVOID apEvents[] = {
+ (PVOID)&pQueue->KillEvent,
+ (PVOID)&pQueue->NotifyEvent,
+ };
do
{
- Status = KeWaitForMultipleObjects(2, pEvents, WaitAny, Executive, KernelMode, FALSE,
- NULL, NULL);
+ Status = KeWaitForMultipleObjects(RT_ELEMENTS(apEvents), apEvents, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);
Assert(NT_SUCCESS(Status));
- if(!NT_SUCCESS(Status) || Status == STATUS_WAIT_0)
+ if (!NT_SUCCESS(Status) || Status == STATUS_WAIT_0)
{
/* will process queued jobs and exit */
Assert(Status == STATUS_WAIT_0);
@@ -943,23 +852,23 @@ static VOID vboxNetFltWinJobWorkerThreadProc(PJOB_QUEUE pQueue)
do
{
PLIST_ENTRY pJobEntry = ExInterlockedRemoveHeadList(&pQueue->Jobs, &pQueue->Lock);
- PJOB pJob;
+ PVBOXNETFLT_JOB pJob;
- if(!pJobEntry)
+ if (!pJobEntry)
break;
pJob = LIST_ENTRY_2_JOB(pJobEntry);
Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
- pJob->pRoutine(pJob->pContext);
+ pJob->pfnRoutine(pJob->pContext);
Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
- if(pJob->bUseCompletionEvent)
+ if (pJob->bUseCompletionEvent)
{
KeSetEvent(&pJob->CompletionEvent, 1, FALSE);
}
- } while(TRUE);
- } while(fResume);
+ } while (TRUE);
+ } while (fResume);
Assert(Status == STATUS_WAIT_0);
@@ -968,11 +877,11 @@ static VOID vboxNetFltWinJobWorkerThreadProc(PJOB_QUEUE pQueue)
/**
* enqueues the job to the job queue to be processed by the job worker thread
- * see comments for PJOB_QUEUE
+ * see comments for PVBOXNETFLT_JOB_QUEUE
*/
-static VOID vboxNetFltWinJobEnqueueJob(PJOB_QUEUE pQueue, PJOB pJob, bool bEnqueueHead)
+static VOID vboxNetFltWinJobEnqueueJob(PVBOXNETFLT_JOB_QUEUE pQueue, PVBOXNETFLT_JOB pJob, bool bEnqueueHead)
{
- if(bEnqueueHead)
+ if (bEnqueueHead)
{
ExInterlockedInsertHeadList(&pQueue->Jobs, &pJob->ListEntry, &pQueue->Lock);
}
@@ -984,27 +893,27 @@ static VOID vboxNetFltWinJobEnqueueJob(PJOB_QUEUE pQueue, PJOB pJob, bool bEnque
KeSetEvent(&pQueue->NotifyEvent, 1, FALSE);
}
-DECLINLINE(VOID) vboxNetFltWinJobInit(PJOB pJob, JOB_ROUTINE pRoutine, PVOID pContext, bool bUseEvent)
+DECLINLINE(VOID) vboxNetFltWinJobInit(PVBOXNETFLT_JOB pJob, PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine, PVOID pContext, bool bUseEvent)
{
- pJob->pRoutine = pRoutine;
+ pJob->pfnRoutine = pfnRoutine;
pJob->pContext = pContext;
pJob->bUseCompletionEvent = bUseEvent;
- if(bUseEvent)
+ if (bUseEvent)
KeInitializeEvent(&pJob->CompletionEvent, NotificationEvent, FALSE);
}
/**
* enqueues the job to the job queue to be processed by the job worker thread and
* blocks until the job is done
- * see comments for PJOB_QUEUE
+ * see comments for PVBOXNETFLT_JOB_QUEUE
*/
-static VOID vboxNetFltWinJobSynchExec(PJOB_QUEUE pQueue, JOB_ROUTINE pRoutine, PVOID pContext)
+static VOID vboxNetFltWinJobSynchExec(PVBOXNETFLT_JOB_QUEUE pQueue, PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine, PVOID pContext)
{
- JOB Job;
+ VBOXNETFLT_JOB Job;
Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
- vboxNetFltWinJobInit(&Job, pRoutine, pContext, true);
+ vboxNetFltWinJobInit(&Job, pfnRoutine, pContext, true);
vboxNetFltWinJobEnqueueJob(pQueue, &Job, false);
@@ -1015,48 +924,50 @@ static VOID vboxNetFltWinJobSynchExec(PJOB_QUEUE pQueue, JOB_ROUTINE pRoutine, P
* enqueues the job to be processed by the job worker thread at passive level and
* blocks until the job is done
*/
-DECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(JOB_ROUTINE pRoutine, PVOID pContext)
+DECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine, PVOID pContext)
{
- vboxNetFltWinJobSynchExec(&g_JobQueue, pRoutine, pContext);
+ vboxNetFltWinJobSynchExec(&g_VBoxJobQueue, pfnRoutine, pContext);
}
/**
* helper function used for system thread creation
*/
-static NTSTATUS vboxNetFltWinQuCreateSystemThread(PKTHREAD * ppThread, PKSTART_ROUTINE pStartRoutine, PVOID pStartContext)
+static NTSTATUS vboxNetFltWinQuCreateSystemThread(PKTHREAD *ppThread, PKSTART_ROUTINE pfnStartRoutine, PVOID pvStartContext)
{
- NTSTATUS fStatus;
- HANDLE hThread;
- OBJECT_ATTRIBUTES fObjectAttributes;
-
+ OBJECT_ATTRIBUTES ObjectAttributes;
Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
- InitializeObjectAttributes(&fObjectAttributes, NULL, OBJ_KERNEL_HANDLE,
- NULL, NULL);
+ InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
- fStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS,
- &fObjectAttributes, NULL, NULL,
- (PKSTART_ROUTINE) pStartRoutine, pStartContext);
- if (!NT_SUCCESS(fStatus))
- return fStatus;
+ HANDLE hThread;
+ NTSTATUS Status = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &ObjectAttributes, NULL, NULL, (PKSTART_ROUTINE)pfnStartRoutine, pvStartContext);
+ Assert(Status == STATUS_SUCCESS);
+ if (Status == STATUS_SUCCESS)
+ {
+ Status = ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*)ppThread, NULL);
+ Assert(Status == STATUS_SUCCESS);
+ ZwClose(hThread);
+ if (Status == STATUS_SUCCESS)
+ {
+ return STATUS_SUCCESS;
+ }
- ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL,
- KernelMode, (PVOID*) ppThread, NULL);
- ZwClose(hThread);
- return STATUS_SUCCESS;
+ /* @todo: how would we fail in this case ?*/
+ }
+ return Status;
}
/**
* initialize the job queue
- * see comments for PJOB_QUEUE
+ * see comments for PVBOXNETFLT_JOB_QUEUE
*/
-static NTSTATUS vboxNetFltWinJobInitQueue(PJOB_QUEUE pQueue)
+static NTSTATUS vboxNetFltWinJobInitQueue(PVBOXNETFLT_JOB_QUEUE pQueue)
{
NTSTATUS fStatus;
Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
- NdisZeroMemory(pQueue, sizeof(JOB_QUEUE));
+ NdisZeroMemory(pQueue, sizeof(VBOXNETFLT_JOB_QUEUE));
KeInitializeEvent(&pQueue->KillEvent, NotificationEvent, FALSE);
@@ -1065,7 +976,7 @@ static NTSTATUS vboxNetFltWinJobInitQueue(PJOB_QUEUE pQueue)
InitializeListHead(&pQueue->Jobs);
fStatus = vboxNetFltWinQuCreateSystemThread(&pQueue->pThread, (PKSTART_ROUTINE)vboxNetFltWinJobWorkerThreadProc, pQueue);
- if(fStatus != STATUS_SUCCESS)
+ if (fStatus != STATUS_SUCCESS)
{
pQueue->pThread = NULL;
}
@@ -1079,13 +990,13 @@ static NTSTATUS vboxNetFltWinJobInitQueue(PJOB_QUEUE pQueue)
/**
* deinitialize the job queue
- * see comments for PJOB_QUEUE
+ * see comments for PVBOXNETFLT_JOB_QUEUE
*/
-static void vboxNetFltWinJobFiniQueue(PJOB_QUEUE pQueue)
+static void vboxNetFltWinJobFiniQueue(PVBOXNETFLT_JOB_QUEUE pQueue)
{
Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
- if(pQueue->pThread)
+ if (pQueue->pThread)
{
KeSetEvent(&pQueue->KillEvent, 0, FALSE);
@@ -1116,19 +1027,19 @@ DECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance)
do
{
- Status = vboxNetFltWinPpAllocatePacketInfoPool(&pWorker->PacketInfoPool, PACKET_INFO_POOL_SIZE);
+ Status = vboxNetFltWinPpAllocatePacketInfoPool(&pWorker->PacketInfoPool, VBOXNETFLT_PACKET_INFO_POOL_SIZE);
- if(Status == NDIS_STATUS_SUCCESS)
+ if (Status == NDIS_STATUS_SUCCESS)
{
pWorker->pSG = vboxNetFltWinCreateSG(PACKET_QUEUE_SG_SEGS_ALLOC);
- if(!pWorker->pSG)
+ if (!pWorker->pSG)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
Status = vboxNetFltWinQuCreateSystemThread(&pWorker->pThread, (PKSTART_ROUTINE)vboxNetFltWinQuPacketQueueWorkerThreadProc, pInstance);
- if(Status != STATUS_SUCCESS)
+ if (Status != STATUS_SUCCESS)
{
vboxNetFltWinPpFreePacketInfoPool(&pWorker->PacketInfoPool);
vboxNetFltWinMemFree(pWorker->pSG);
@@ -1137,7 +1048,7 @@ DECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance)
}
}
- } while(0);
+ } while (0);
return Status;
}
@@ -1152,11 +1063,9 @@ DECLHIDDEN(void) vboxNetFltWinQuFiniPacketQueue(PVBOXNETFLTINS pInstance)
PPACKET_QUEUE_WORKER pWorker = &pInstance->u.s.PacketQueueWorker;
Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
-// Assert(pAdapt->pPacketQueueSG);
-
/* using the pPacketQueueSG as an indicator that the packet queue is initialized */
RTSpinlockAcquireNoInts((pInstance)->hSpinlock, &Tmp);
- if(pWorker->pSG)
+ if (pWorker->pSG)
{
pSG = pWorker->pSG;
pWorker->pSG = NULL;
@@ -1194,10 +1103,10 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbPacket, PINTNETSG *ppSG)
* 2. buffer of cbPacket containing the entire packet */
AssertCompileSizeAlignment(INTNETSG, sizeof(PVOID));
Status = vboxNetFltWinMemAlloc((PVOID*)&pSG, cbPacket + sizeof(INTNETSG));
- if(Status == NDIS_STATUS_SUCCESS)
+ if (Status == NDIS_STATUS_SUCCESS)
{
IntNetSgInitTemp(pSG, pSG + 1, cbPacket);
- LogFlow(("pSG created (%p)\n", pSG));
+ LogFlow(("pSG created (%p)\n", pSG));
*ppSG = pSG;
}
return Status;
@@ -1207,7 +1116,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbPacket, PINTNETSG *ppSG)
/**
* put the packet info to the queue
*/
-DECLINLINE(void) vboxNetFltWinQuEnqueueInfo(PPACKET_QUEUE_WORKER pWorker, PPACKET_INFO pInfo)
+DECLINLINE(void) vboxNetFltWinQuEnqueueInfo(PVBOXNETFLTPACKET_QUEUE_WORKER pWorker, PVBOXNETFLTPACKET_INFO pInfo)
{
vboxNetFltWinQuInterlockedEnqueueTail(&pWorker->PacketQueue, pInfo);
@@ -1225,18 +1134,18 @@ DECLINLINE(void) vboxNetFltWinQuEnqueueInfo(PPACKET_QUEUE_WORKER pWorker, PPACKE
*/
DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, PVOID pPacket, const UINT fPacketFlags)
{
- PPACKET_INFO pInfo;
- PPACKET_QUEUE_WORKER pWorker = &pInstance->u.s.PacketQueueWorker;
+ PVBOXNETFLT_PACKET_INFO pInfo;
+ PVBOXNETFLT_PACKET_QUEUE_WORKER pWorker = &pInstance->u.s.PacketQueueWorker;
NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS;
do
{
- if(fPacketFlags & PACKET_COPY)
+ if (fPacketFlags & PACKET_COPY)
{
- PNDIS_BUFFER pBuffer = NULL;
- UINT cBufferCount;
- UINT uBytesCopied = 0;
- UINT cbPacketLength;
+ PNDIS_BUFFER pBuffer = NULL;
+ UINT cBufferCount;
+ UINT uBytesCopied = 0;
+ UINT cbPacketLength;
PINTNETSG pSG;
/* the packet is Ndis packet */
@@ -1253,7 +1162,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P
Assert(cBufferCount);
fStatus = vboxNetFltWinAllocSG(cbPacketLength, &pSG);
- if(fStatus != NDIS_STATUS_SUCCESS)
+ if (fStatus != NDIS_STATUS_SUCCESS)
{
AssertFailed();
break;
@@ -1261,7 +1170,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P
pInfo = vboxNetFltWinPpAllocPacketInfo(&pWorker->PacketInfoPool);
- if(!pInfo)
+ if (!pInfo)
{
AssertFailed();
/* TODO: what status to set? */
@@ -1277,7 +1186,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P
SET_PACKET_TO_INFO(pInfo, pSG);
fStatus = vboxNetFltWinNdisBufferMoveToSG0(pBuffer, pSG);
- if(fStatus != NDIS_STATUS_SUCCESS)
+ if (fStatus != NDIS_STATUS_SUCCESS)
{
AssertFailed();
vboxNetFltWinPpFreePacketInfo(pInfo);
@@ -1291,7 +1200,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P
{
pInfo = vboxNetFltWinPpAllocPacketInfo(&pWorker->PacketInfoPool);
- if(!pInfo)
+ if (!pInfo)
{
AssertFailed();
/* TODO: what status to set? */
@@ -1307,164 +1216,56 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P
vboxNetFltWinQuEnqueueInfo(pWorker, pInfo);
- } while(0);
+ } while (0);
return fStatus;
}
#endif
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
-/*
- * ioctl i/f
- */
-static NTSTATUS
-vboxNetFltWinPtDispatchIoctl(
- IN PDEVICE_OBJECT pDeviceObject,
- IN PIO_STACK_LOCATION pIrpStack)
-{
-#if 0
- ULONG CtlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
- NTSTATUS Status = STATUS_SUCCESS;
- int rc;
-
- switch(CtlCode)
- {
-
- case VBOXNETFLT_WIN_IOCTL_INIT:
- rc = vboxNetFltWinInitIdc();
- if(!RT_SUCCESS(rc))
- {
- Status = STATUS_UNSUCCESSFUL;
- }
- break;
- case VBOXNETFLT_WIN_IOCTL_FINI:
- /* we are finalizing during unload */
- /* TODO: FIXME: need to prevent driver unload that can occur in case IntNet is connected to us,
- * but we are not bound to any adapters */
-/* rc = vboxNetFltWinTryFiniIdc();
- if(!RT_SUCCESS(rc))
- {
- Status = STATUS_UNSUCCESSFUL;
- }
- */
- break;
-
- default:
- Status = STATUS_NOT_SUPPORTED;
- break;
- }
-
- return Status;
-#else
- return STATUS_NOT_SUPPORTED;
-#endif
-}
-
-/*
-Routine Description:
-
- Process IRPs sent to this device.
-
-Arguments:
-
- DeviceObject - pointer to a device object
- Irp - pointer to an I/O Request Packet
-
-Return Value:
-
- NTSTATUS - STATUS_SUCCESS always - change this when adding
- real code to handle ioctls.
-
-*/
-DECLHIDDEN(NTSTATUS)
-vboxNetFltWinPtDispatch(
- IN PDEVICE_OBJECT pDeviceObject,
- IN PIRP pIrp
- )
-{
- PIO_STACK_LOCATION pIrpStack;
- NTSTATUS Status = STATUS_SUCCESS;
-
- LogFlow(("==>Pt Dispatch\n"));
- pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
-
-
- switch (pIrpStack->MajorFunction)
- {
- case IRP_MJ_CREATE:
- break;
-
- case IRP_MJ_CLEANUP:
- break;
-
- case IRP_MJ_CLOSE:
- break;
-
- case IRP_MJ_DEVICE_CONTROL:
- Status = vboxNetFltWinPtDispatchIoctl(pDeviceObject, pIrpStack);
- break;
- default:
- break;
- }
-
- pIrp->IoStatus.Status = Status;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
-
- LogFlow(("<== Pt Dispatch\n"));
-
- return Status;
-
-}
-#endif
/*
* netflt
*/
#ifndef VBOXNETADP
-/*
- * NOTE! the routine is NOT re-enterable for the given pAdapt
- * the serialization is not implemented for performance reasons
- * since we are assuming the caller serializes the requests as IntNet does
- */
-static NDIS_STATUS vboxNetFltWinSynchNdisRequest(PADAPT pAdapt, PNDIS_REQUEST pRequest)
+static NDIS_STATUS vboxNetFltWinSynchNdisRequest(PVBOXNETFLTINS pNetFlt, PNDIS_REQUEST pRequest)
{
int rc;
Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
/* 1. serialize */
- rc = RTSemFastMutexRequest(pAdapt->hSynchRequestMutex); AssertRC(rc);
- if(RT_SUCCESS(rc))
+ rc = RTSemFastMutexRequest(pNetFlt->u.s.WinIf.hSynchRequestMutex); AssertRC(rc);
+ if (RT_SUCCESS(rc))
{
NDIS_STATUS fRequestStatus = NDIS_STATUS_SUCCESS;
- /* 2. set pAdapt->pSynchRequest */
- Assert(!pAdapt->pSynchRequest);
- pAdapt->pSynchRequest = pRequest;
+ /* 2. set pNetFlt->u.s.pSynchRequest */
+ Assert(!pNetFlt->u.s.WinIf.pSynchRequest);
+ pNetFlt->u.s.WinIf.pSynchRequest = pRequest;
/* 3. call NdisRequest */
- NdisRequest(&fRequestStatus, pAdapt->hBindingHandle, pRequest);
+ NdisRequest(&fRequestStatus, pNetFlt->u.s.WinIf.hBinding, pRequest);
- if(fRequestStatus == NDIS_STATUS_PENDING)
+ if (fRequestStatus == NDIS_STATUS_PENDING)
{
/* 3.1 if pending wait and assign the resulting status */
- KeWaitForSingleObject(&pAdapt->hSynchCompletionEvent, Executive,
+ KeWaitForSingleObject(&pNetFlt->u.s.WinIf.hSynchCompletionEvent, Executive,
KernelMode, FALSE, NULL);
- fRequestStatus = pAdapt->fSynchCompletionStatus;
+ fRequestStatus = pNetFlt->u.s.WinIf.SynchCompletionStatus;
}
- /* 4. clear the pAdapt->pSynchRequest */
- pAdapt->pSynchRequest = NULL;
+ /* 4. clear the pNetFlt->u.s.pSynchRequest */
+ pNetFlt->u.s.WinIf.pSynchRequest = NULL;
- RTSemFastMutexRelease(pAdapt->hSynchRequestMutex); AssertRC(rc);
+ RTSemFastMutexRelease(pNetFlt->u.s.WinIf.hSynchRequestMutex); AssertRC(rc);
return fRequestStatus;
}
return NDIS_STATUS_FAILURE;
}
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac)
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PVBOXNETFLTINS pNetFlt, PRTMAC pMac)
{
NDIS_REQUEST request;
NDIS_STATUS status;
@@ -1472,8 +1273,8 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac)
request.DATA.QUERY_INFORMATION.InformationBuffer = pMac;
request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(RTMAC);
request.DATA.QUERY_INFORMATION.Oid = OID_802_3_CURRENT_ADDRESS;
- status = vboxNetFltWinSynchNdisRequest(pAdapt, &request);
- if(status != NDIS_STATUS_SUCCESS)
+ status = vboxNetFltWinSynchNdisRequest(pNetFlt, &request);
+ if (status != NDIS_STATUS_SUCCESS)
{
/* TODO */
AssertFailed();
@@ -1483,7 +1284,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac)
}
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHYSICAL_MEDIUM * pMedium)
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PVBOXNETFLTINS pNetFlt, NDIS_PHYSICAL_MEDIUM * pMedium)
{
NDIS_REQUEST Request;
NDIS_STATUS Status;
@@ -1491,10 +1292,10 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHY
Request.DATA.QUERY_INFORMATION.InformationBuffer = pMedium;
Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(NDIS_PHYSICAL_MEDIUM);
Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_PHYSICAL_MEDIUM;
- Status = vboxNetFltWinSynchNdisRequest(pAdapt, &Request);
- if(Status != NDIS_STATUS_SUCCESS)
+ Status = vboxNetFltWinSynchNdisRequest(pNetFlt, &Request);
+ if (Status != NDIS_STATUS_SUCCESS)
{
- if(Status == NDIS_STATUS_NOT_SUPPORTED || Status == NDIS_STATUS_NOT_RECOGNIZED || Status == NDIS_STATUS_INVALID_OID)
+ if (Status == NDIS_STATUS_NOT_SUPPORTED || Status == NDIS_STATUS_NOT_RECOGNIZED || Status == NDIS_STATUS_INVALID_OID)
{
Status = NDIS_STATUS_NOT_SUPPORTED;
}
@@ -1507,7 +1308,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHY
return Status;
}
-DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt)
+DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PVBOXNETFLTINS pNetFlt)
{
/** @todo r=bird: This is too slow and is probably returning the wrong
* information. What we're interested in is whether someone besides us
@@ -1515,13 +1316,13 @@ DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt)
NDIS_REQUEST request;
NDIS_STATUS status;
ULONG filter;
- Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt));
+ Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt));
request.RequestType = NdisRequestQueryInformation;
request.DATA.QUERY_INFORMATION.InformationBuffer = &filter;
request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(filter);
request.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
- status = vboxNetFltWinSynchNdisRequest(pAdapt, &request);
- if(status != NDIS_STATUS_SUCCESS)
+ status = vboxNetFltWinSynchNdisRequest(pNetFlt, &request);
+ if (status != NDIS_STATUS_SUCCESS)
{
/* TODO */
AssertFailed();
@@ -1530,13 +1331,13 @@ DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt)
return (filter & NDIS_PACKET_TYPE_PROMISCUOUS) != 0;
}
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes)
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PVBOXNETFLTINS pNetFlt, bool bYes)
{
/** @todo Need to report changes to the switch via:
* pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, fPromisc);
*/
- Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt));
- if(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
+ Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt));
+ if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt))
{
NDIS_REQUEST Request;
NDIS_STATUS fStatus;
@@ -1547,48 +1348,48 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes)
Request.DATA.QUERY_INFORMATION.InformationBuffer = &fFilter;
Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(fFilter);
Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
- fStatus = vboxNetFltWinSynchNdisRequest(pAdapt, &Request);
- if(fStatus != NDIS_STATUS_SUCCESS)
+ fStatus = vboxNetFltWinSynchNdisRequest(pNetFlt, &Request);
+ if (fStatus != NDIS_STATUS_SUCCESS)
{
/* TODO: */
AssertFailed();
return fStatus;
}
- if(!pAdapt->bUpperProtSetFilterInitialized)
+ if (!pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized)
{
/* the cache was not initialized yet, initiate it with the current filter value */
- pAdapt->fUpperProtocolSetFilter = fFilter;
- pAdapt->bUpperProtSetFilterInitialized = true;
+ pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = fFilter;
+ pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE;
}
- if(bYes)
+ if (bYes)
{
fExpectedFilter = NDIS_PACKET_TYPE_PROMISCUOUS;
fOurFilter = NDIS_PACKET_TYPE_PROMISCUOUS;
}
else
{
- fExpectedFilter = pAdapt->fUpperProtocolSetFilter;
+ fExpectedFilter = pNetFlt->u.s.WinIf.fUpperProtocolSetFilter;
fOurFilter = 0;
}
- if(fExpectedFilter != fFilter)
+ if (fExpectedFilter != fFilter)
{
Request.RequestType = NdisRequestSetInformation;
Request.DATA.SET_INFORMATION.InformationBuffer = &fExpectedFilter;
Request.DATA.SET_INFORMATION.InformationBufferLength = sizeof(fExpectedFilter);
Request.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
- fStatus = vboxNetFltWinSynchNdisRequest(pAdapt, &Request);
- if(fStatus != NDIS_STATUS_SUCCESS)
+ fStatus = vboxNetFltWinSynchNdisRequest(pNetFlt, &Request);
+ if (fStatus != NDIS_STATUS_SUCCESS)
{
/* TODO */
AssertFailed();
return fStatus;
}
}
- pAdapt->fOurSetFilter = fOurFilter;
+ pNetFlt->u.s.WinIf.fOurSetFilter = fOurFilter;
return fStatus;
}
return NDIS_STATUS_NOT_SUPPORTED;
@@ -1612,8 +1413,6 @@ DECLHIDDEN(void) vboxNetFltWinGenerateMACAddress(RTMAC *pMac)
DECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisString)
{
static const char s_achDigits[17] = "0123456789abcdef";
- uint8_t u8;
- int i;
PWSTR pString;
/* validate parameters */
@@ -1623,11 +1422,11 @@ DECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisStrin
pString = pNdisString->Buffer;
- for( i = 0; i < 6; i++)
+ for (int i = 0; i < 6; i++)
{
- u8 = pMac->au8[i];
- pString[ 0] = s_achDigits[(u8 >> 4) & 0xf];
- pString[ 1] = s_achDigits[(u8/*>>0*/)& 0xf];
+ uint8_t u8 = pMac->au8[i];
+ pString[0] = s_achDigits[(u8 >> 4) & 0xf];
+ pString[1] = s_achDigits[(u8/*>>0*/)& 0xf];
pString += 2;
}
@@ -1640,15 +1439,15 @@ DECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisStrin
static int vboxNetFltWinWchar2Int(WCHAR c, uint8_t * pv)
{
- if(c >= L'A' && c <= L'F')
+ if (c >= L'A' && c <= L'F')
{
*pv = (c - L'A') + 10;
}
- else if(c >= L'a' && c <= L'f')
+ else if (c >= L'a' && c <= L'f')
{
*pv = (c - L'a') + 10;
}
- else if(c >= L'0' && c <= L'9')
+ else if (c >= L'0' && c <= L'9')
{
*pv = (c - L'0');
}
@@ -1671,17 +1470,17 @@ DECLHIDDEN(int) vboxNetFltWinMACFromNdisString(RTMAC *pMac, PNDIS_STRING pNdisSt
pString = pNdisString->Buffer;
- for(i = 0; i < 6; i++)
+ for (i = 0; i < 6; i++)
{
uint8_t v1, v2;
rc = vboxNetFltWinWchar2Int(pString[0], &v1);
- if(RT_FAILURE(rc))
+ if (RT_FAILURE(rc))
{
break;
}
rc = vboxNetFltWinWchar2Int(pString[1], &v2);
- if(RT_FAILURE(rc))
+ if (RT_FAILURE(rc))
{
break;
}
@@ -1698,29 +1497,24 @@ DECLHIDDEN(int) vboxNetFltWinMACFromNdisString(RTMAC *pMac, PNDIS_STRING pNdisSt
/**
* creates a NDIS_PACKET from the PINTNETSG
*/
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
-/* TODO: the bToWire parameter seems to be unneeded here, remove them*/
-#endif
-DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory)
+DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PVBOXNETFLTINS pNetFlt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory)
{
NDIS_STATUS fStatus;
PNDIS_PACKET pPacket;
Assert(pSG->aSegs[0].pv);
- Assert(pSG->cbTotal >= sizeof(ETH_HEADER_SIZE));
+ Assert(pSG->cbTotal >= sizeof(VBOXNETFLT_PACKET_ETHEADER_SIZE));
/** @todo Hrmpf, how can we fix this assumption? I fear this'll cause data
* corruption and maybe even BSODs ... */
AssertReturn(pSG->cSegsUsed == 1 || bCopyMemory, NULL);
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- NdisAllocatePacket(&fStatus, &pPacket, pAdapt->hSendPacketPoolHandle);
-#elif defined(VBOXNETADP)
- NdisAllocatePacket(&fStatus, &pPacket, pAdapt->hRecvPacketPoolHandle);
+#ifdef VBOXNETADP
+ NdisAllocatePacket(&fStatus, &pPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
#else
- NdisAllocatePacket(&fStatus, &pPacket, bToWire ? pAdapt->hSendPacketPoolHandle : pAdapt->hRecvPacketPoolHandle);
+ NdisAllocatePacket(&fStatus, &pPacket, bToWire ? pNetFlt->u.s.WinIf.hSendPacketPool : pNetFlt->u.s.WinIf.hRecvPacketPool);
#endif
- if(fStatus == NDIS_STATUS_SUCCESS)
+ if (fStatus == NDIS_STATUS_SUCCESS)
{
PNDIS_BUFFER pBuffer;
PVOID pvMemBuf;
@@ -1730,76 +1524,65 @@ DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG
* in case the status contains NDIS_STATUS_RESOURCES */
VBOXNETFLT_OOB_INIT(pPacket);
- if(bCopyMemory)
+ if (bCopyMemory)
{
fStatus = vboxNetFltWinMemAlloc(&pvMemBuf, pSG->cbTotal);
Assert(fStatus == NDIS_STATUS_SUCCESS);
- if(fStatus == NDIS_STATUS_SUCCESS)
+ if (fStatus == NDIS_STATUS_SUCCESS)
IntNetSgRead(pSG, pvMemBuf);
}
else
{
pvMemBuf = pSG->aSegs[0].pv;
}
- if(fStatus == NDIS_STATUS_SUCCESS)
+ if (fStatus == NDIS_STATUS_SUCCESS)
{
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- NdisAllocateBuffer(&fStatus, &pBuffer,
- pAdapt->hSendBufferPoolHandle,
- pvMemBuf,
- pSG->cbTotal);
-#elif defined(VBOXNETADP)
+#ifdef VBOXNETADP
NdisAllocateBuffer(&fStatus, &pBuffer,
- pAdapt->hRecvBufferPoolHandle,
+ pNetFlt->u.s.WinIf.hRecvBufferPool,
pvMemBuf,
pSG->cbTotal);
#else
NdisAllocateBuffer(&fStatus, &pBuffer,
- bToWire ? pAdapt->hSendBufferPoolHandle : pAdapt->hRecvBufferPoolHandle,
+ bToWire ? pNetFlt->u.s.WinIf.hSendBufferPool : pNetFlt->u.s.WinIf.hRecvBufferPool,
pvMemBuf,
pSG->cbTotal);
#endif
- if(fStatus == NDIS_STATUS_SUCCESS)
+ if (fStatus == NDIS_STATUS_SUCCESS)
{
NdisChainBufferAtBack(pPacket, pBuffer);
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- if(bToWire)
-#endif
+ if (bToWire)
{
- PSEND_RSVD pSendRsvd;
- pSendRsvd = (PSEND_RSVD)(pPacket->ProtocolReserved);
- pSendRsvd->pOriginalPkt = NULL;
- pSendRsvd->pBufToFree = pBufToFree;
+ PVBOXNETFLT_PKTRSVD_PT pSendInfo = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved;
+ pSendInfo->pOrigPacket = NULL;
+ pSendInfo->pBufToFree = pBufToFree;
#ifdef VBOX_LOOPBACK_USEFLAGS
/* set "don't loopback" flags */
- NdisSetPacketFlags(pPacket, g_fPacketDontLoopBack);
+ NdisGetPacketFlags(pPacket) = g_VBoxNetFltGlobalsWin.fPacketDontLoopBack;
#else
- NdisSetPacketFlags(pPacket, 0);
+ NdisGetPacketFlags(pPacket) = 0;
#endif
}
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
else
{
- PRECV_RSVD pRecvRsvd;
- pRecvRsvd = (PRECV_RSVD)(pPacket->MiniportReserved);
- pRecvRsvd->pOriginalPkt = NULL;
- pRecvRsvd->pBufToFree = pBufToFree;
+ PVBOXNETFLT_PKTRSVD_MP pRecvInfo = (PVBOXNETFLT_PKTRSVD_MP)pPacket->MiniportReserved;
+ pRecvInfo->pOrigPacket = NULL;
+ pRecvInfo->pBufToFree = pBufToFree;
- /* me must set the header size on receive */
- NDIS_SET_PACKET_HEADER_SIZE(pPacket, ETH_HEADER_SIZE);
+ /* we must set the header size on receive */
+ NDIS_SET_PACKET_HEADER_SIZE(pPacket, VBOXNETFLT_PACKET_ETHEADER_SIZE);
/* NdisAllocatePacket zero-initializes the OOB data,
* but keeps the packet flags, clean them here */
- NdisSetPacketFlags(pPacket, 0);
+ NdisGetPacketFlags(pPacket) = 0;
}
-#endif
/* TODO: set out of bound data */
}
else
{
AssertFailed();
- if(bCopyMemory)
+ if (bCopyMemory)
{
vboxNetFltWinMemFree(pvMemBuf);
}
@@ -1841,14 +1624,14 @@ DECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeM
do
{
NdisUnchainBufferAtBack(pPacket, &pBuffer);
- if(pBuffer != NULL)
+ if (pBuffer != NULL)
{
PVOID pvMemBuf;
UINT cbLength;
NdisQueryBufferSafe(pBuffer, &pvMemBuf, &cbLength, NormalPagePriority);
NdisFreeBuffer(pBuffer);
- if(bFreeMem)
+ if (bFreeMem)
{
vboxNetFltWinMemFree(pvMemBuf);
}
@@ -1857,65 +1640,27 @@ DECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeM
{
break;
}
- } while(true);
+ } while (true);
NdisFreePacket(pPacket);
}
-/*
- * Free all packet pools on the specified adapter.
- * @param pAdapt - pointer to ADAPT structure
- */
-static VOID
-vboxNetFltWinPtFreeAllPacketPools(
- IN PADAPT pAdapt
- )
-{
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- if (pAdapt->hRecvPacketPoolHandle != NULL)
- {
- /*
- * Free the packet pool that is used to indicate receives
- */
- NdisFreePacketPool(pAdapt->hRecvPacketPoolHandle);
-
- pAdapt->hRecvPacketPoolHandle = NULL;
- }
-#endif /* #ifndef VBOX_NETFLT_ONDEMAND_BIND*/
-#ifndef VBOXNETADP
- if (pAdapt->hSendPacketPoolHandle != NULL)
- {
-
- /*
- * Free the packet pool that is used to send packets below
- */
-
- NdisFreePacketPool(pAdapt->hSendPacketPoolHandle);
-
- pAdapt->hSendPacketPoolHandle = NULL;
-
- }
-#endif
-}
-#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
-static void vboxNetFltWinAssociateMiniportProtocol()
+#if !defined(VBOXNETADP)
+static void vboxNetFltWinAssociateMiniportProtocol(PVBOXNETFLTGLOBALS_WIN pGlobalsWin)
{
- NdisIMAssociateMiniport(vboxNetFltWinMpGetHandle(), vboxNetFltWinPtGetHandle());
+ NdisIMAssociateMiniport(pGlobalsWin->Mp.hMiniport, pGlobalsWin->Pt.hProtocol);
}
#endif
/*
* NetFlt driver unload function
*/
-DECLHIDDEN(VOID)
-vboxNetFltWinUnload(
- IN PDRIVER_OBJECT DriverObject
- )
+DECLHIDDEN(VOID) vboxNetFltWinUnload(IN PDRIVER_OBJECT DriverObject)
{
int rc;
UNREFERENCED_PARAMETER(DriverObject);
- LogFlow(("vboxNetFltWinUnload: entered\n"));
+ LogFlow((__FUNCTION__" ==> DO (0x%x)\n", DriverObject));
rc = vboxNetFltWinTryFiniIdc();
if (RT_FAILURE(rc))
@@ -1923,111 +1668,89 @@ vboxNetFltWinUnload(
/* TODO: we can not prevent driver unload here */
AssertFailed();
- Log(("vboxNetFltWinTryFiniIdc - failed, busy.\n"));
+ Log((__FUNCTION__": vboxNetFltWinTryFiniIdc - failed, busy.\n"));
}
- vboxNetFltWinJobFiniQueue(&g_JobQueue);
+ vboxNetFltWinJobFiniQueue(&g_VBoxJobQueue);
#ifndef VBOXNETADP
- vboxNetFltWinPtDeregister();
-#endif
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- vboxNetFltWinMpDeregister();
+ vboxNetFltWinPtDeregister(&g_VBoxNetFltGlobalsWin.Pt);
#endif
+ vboxNetFltWinMpDeregister(&g_VBoxNetFltGlobalsWin.Mp);
+
vboxNetFltWinFiniNetFltBase();
/* don't use logging or any RT after de-init */
- NdisFreeSpinLock(&g_GlobalLock);
+ LogFlow((__FUNCTION__" <== DO (0x%x)\n", DriverObject));
}
RT_C_DECLS_BEGIN
-NTSTATUS
-DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- );
+NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
RT_C_DECLS_END
-/*
- * First entry point to be called, when this driver is loaded.
- * Register with NDIS as an intermediate driver.
- * @return STATUS_SUCCESS if all initialization is successful, STATUS_XXX
- * error code if not.
- */
-NTSTATUS
-DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
+
+NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
int rc;
- ULONG MjVersion;
- ULONG MnVersion;
-
- NdisAllocateSpinLock(&g_GlobalLock);
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- /* we are registering in the DriverEntry only when we are working as a protocol
- * since in this case our driver is loaded after the VBoxDrv*/
- rc = vboxNetFltWinInitNetFlt();
-#else
- /* the idc registration is initiated via IOCTL since our driver
- * can be loaded when the VBoxDrv is not in case we are a Ndis IM driver */
+ /* the idc registration is initiated via IOCTL since our driver
+ * can be loaded when the VBoxDrv is not in case we are a Ndis IM driver */
rc = vboxNetFltWinInitNetFltBase();
-#endif
AssertRC(rc);
- if(RT_SUCCESS(rc))
+ if (RT_SUCCESS(rc))
{
- PsGetVersion(&MjVersion, &MnVersion,
- NULL, /* PULONG BuildNumber OPTIONAL */
- NULL /* PUNICODE_STRING CSDVersion OPTIONAL */
- );
-
- g_fPacketDontLoopBack = NDIS_FLAGS_DONT_LOOPBACK;
-
- if(MjVersion == 5 && MnVersion == 0)
- {
- /* this is Win2k*/
- g_fPacketDontLoopBack |= NDIS_FLAGS_SKIP_LOOPBACK_W2K;
- }
-
- g_fPacketIsLoopedBack = NDIS_FLAGS_IS_LOOPBACK_PACKET;
-
- Status = vboxNetFltWinJobInitQueue(&g_JobQueue);
+ Status = vboxNetFltWinJobInitQueue(&g_VBoxJobQueue);
Assert(Status == STATUS_SUCCESS);
- if(Status == STATUS_SUCCESS)
+ if (Status == STATUS_SUCCESS)
{
+ ULONG MjVersion;
+ ULONG MnVersion;
+
/* note: we do it after we initialize the Job Queue */
vboxNetFltWinStartInitIdcProbing();
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- Status = vboxNetFltWinMpRegister(DriverObject, RegistryPath);
+ NdisZeroMemory(&g_VBoxNetFltGlobalsWin, sizeof (g_VBoxNetFltGlobalsWin));
+ KeInitializeEvent(&g_VBoxNetFltGlobalsWin.SynchEvent, SynchronizationEvent, TRUE /* signalled*/);
+
+ PsGetVersion(&MjVersion, &MnVersion,
+ NULL, /* PULONG BuildNumber OPTIONAL */
+ NULL /* PUNICODE_STRING CSDVersion OPTIONAL */
+ );
+
+ g_VBoxNetFltGlobalsWin.fPacketDontLoopBack = NDIS_FLAGS_DONT_LOOPBACK;
+
+ if (MjVersion == 5 && MnVersion == 0)
+ {
+ /* this is Win2k, we don't support it actually, but just in case */
+ g_VBoxNetFltGlobalsWin.fPacketDontLoopBack |= NDIS_FLAGS_SKIP_LOOPBACK_W2K;
+ }
+
+ g_VBoxNetFltGlobalsWin.fPacketIsLoopedBack = NDIS_FLAGS_IS_LOOPBACK_PACKET;
+
+ Status = vboxNetFltWinMpRegister(&g_VBoxNetFltGlobalsWin.Mp, DriverObject, RegistryPath);
Assert(Status == STATUS_SUCCESS);
if (Status == NDIS_STATUS_SUCCESS)
-#endif
{
#ifndef VBOXNETADP
- Status = vboxNetFltWinPtRegister(DriverObject, RegistryPath);
+ Status = vboxNetFltWinPtRegister(&g_VBoxNetFltGlobalsWin.Pt, DriverObject, RegistryPath);
Assert(Status == STATUS_SUCCESS);
if (Status == NDIS_STATUS_SUCCESS)
#endif
{
-#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
- vboxNetFltWinAssociateMiniportProtocol();
+#ifndef VBOXNETADP
+ vboxNetFltWinAssociateMiniportProtocol(&g_VBoxNetFltGlobalsWin);
#endif
return STATUS_SUCCESS;
//#ifndef VBOXNETADP
-// vboxNetFltWinPtDeregister();
+// vboxNetFltWinPtDeregister(&g_VBoxNetFltGlobalsWin.Pt);
//#endif
}
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- vboxNetFltWinMpDeregister();
-#endif
+ vboxNetFltWinMpDeregister(&g_VBoxNetFltGlobalsWin.Mp);
}
- vboxNetFltWinJobFiniQueue(&g_JobQueue);
+ vboxNetFltWinJobFiniQueue(&g_VBoxJobQueue);
}
vboxNetFltWinFiniNetFlt();
}
@@ -2036,45 +1759,31 @@ DriverEntry(
Status = NDIS_STATUS_FAILURE;
}
- NdisFreeSpinLock(&g_GlobalLock);
-
- return(Status);
+ return Status;
}
-#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
+#ifndef VBOXNETADP
/**
* creates and initializes the packet to be sent to the underlying miniport given a packet posted to our miniport edge
* according to DDK docs we must create our own packet rather than posting the one passed to us
*/
-DECLHIDDEN(NDIS_STATUS)
-vboxNetFltWinPrepareSendPacket(
- IN PADAPT pAdapt,
- IN PNDIS_PACKET pPacket,
- OUT PNDIS_PACKET *ppMyPacket
- /*, IN bool bNetFltActive */
- )
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPrepareSendPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PNDIS_PACKET *ppMyPacket)
{
- NDIS_STATUS fStatus;
+ NDIS_STATUS Status;
- NdisAllocatePacket(&fStatus,
- ppMyPacket,
- pAdapt->hSendPacketPoolHandle);
+ NdisAllocatePacket(&Status, ppMyPacket, pNetFlt->u.s.WinIf.hSendPacketPool);
- if (fStatus == NDIS_STATUS_SUCCESS)
+ if (Status == NDIS_STATUS_SUCCESS)
{
- PSEND_RSVD pSendRsvd;
-
- pSendRsvd = (PSEND_RSVD)((*ppMyPacket)->ProtocolReserved);
- pSendRsvd->pOriginalPkt = pPacket;
- pSendRsvd->pBufToFree = NULL;
-
- NDIS_PACKET_FIRST_NDIS_BUFFER(*ppMyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pPacket);
- NDIS_PACKET_LAST_NDIS_BUFFER(*ppMyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pPacket);
+ PVBOXNETFLT_PKTRSVD_PT pSendInfo = (PVBOXNETFLT_PKTRSVD_PT)((*ppMyPacket)->ProtocolReserved);
+ pSendInfo->pOrigPacket = pPacket;
+ pSendInfo->pBufToFree = NULL;
+ /* the rest will be filled on send */
vboxNetFltWinCopyPacketInfoOnSend(*ppMyPacket, pPacket);
#ifdef VBOX_LOOPBACK_USEFLAGS
- NdisGetPacketFlags(*ppMyPacket) |= g_fPacketDontLoopBack;
+ NdisGetPacketFlags(*ppMyPacket) |= g_VBoxNetFltGlobalsWin.fPacketDontLoopBack;
#endif
}
else
@@ -2082,77 +1791,54 @@ vboxNetFltWinPrepareSendPacket(
*ppMyPacket = NULL;
}
- return fStatus;
+ return Status;
}
/**
* creates and initializes the packet to be sent to the upperlying protocol given a packet indicated to our protocol edge
* according to DDK docs we must create our own packet rather than posting the one passed to us
*/
-DECLHIDDEN(NDIS_STATUS)
-vboxNetFltWinPrepareRecvPacket(
- IN PADAPT pAdapt,
- IN PNDIS_PACKET pPacket,
- OUT PNDIS_PACKET *ppMyPacket,
- IN bool bDpr
- )
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPrepareRecvPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PNDIS_PACKET *ppMyPacket, bool bDpr)
{
- NDIS_STATUS fStatus;
+ NDIS_STATUS Status;
- /*
- * Get a packet off the pool and indicate that up
- */
- if(bDpr)
+ if (bDpr)
{
Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
- NdisDprAllocatePacket(&fStatus,
- ppMyPacket,
- pAdapt->hRecvPacketPoolHandle);
+ NdisDprAllocatePacket(&Status, ppMyPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
}
else
{
- NdisAllocatePacket(&fStatus,
- ppMyPacket,
- pAdapt->hRecvPacketPoolHandle);
+ NdisAllocatePacket(&Status, ppMyPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
}
- if (fStatus == NDIS_STATUS_SUCCESS)
+ if (Status == NDIS_STATUS_SUCCESS)
{
- PRECV_RSVD pRecvRsvd;
+ PVBOXNETFLT_PKTRSVD_MP pRecvInfo = (PVBOXNETFLT_PKTRSVD_MP)((*ppMyPacket)->MiniportReserved);
+ pRecvInfo->pOrigPacket = pPacket;
+ pRecvInfo->pBufToFree = NULL;
- pRecvRsvd = (PRECV_RSVD)((*ppMyPacket)->MiniportReserved);
- pRecvRsvd->pOriginalPkt = pPacket;
- pRecvRsvd->pBufToFree = NULL;
-
- NDIS_PACKET_FIRST_NDIS_BUFFER(*ppMyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pPacket);
- NDIS_PACKET_LAST_NDIS_BUFFER(*ppMyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pPacket);
-
- fStatus = vboxNetFltWinCopyPacketInfoOnRecv(*ppMyPacket, pPacket);
+ Status = vboxNetFltWinCopyPacketInfoOnRecv(*ppMyPacket, pPacket, false);
}
else
{
*ppMyPacket = NULL;
}
- return fStatus;
+ return Status;
}
#endif
-
/**
- * initializes the ADAPT (our context structure) and binds to the given adapter
+ * initializes the VBOXNETFLTINS (our context structure) and binds to the given adapter
*/
-#if defined(VBOX_NETFLT_ONDEMAND_BIND)
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT pAdapt)
-#elif defined(VBOXNETADP)
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext)
+#if defined(VBOXNETADP)
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PVBOXNETFLTINS *ppNetFlt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext)
#else
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName)
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PVBOXNETFLTINS *ppNetFlt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName)
#endif
{
NDIS_STATUS Status;
do
{
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
ANSI_STRING AnsiString;
int rc;
PVBOXNETFLTINS pInstance;
@@ -2177,14 +1863,14 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pO
Status = RtlUnicodeStringToAnsiString(&AnsiString, pBindToMiniportName, true);
- if(Status != STATUS_SUCCESS)
+ if (Status != STATUS_SUCCESS)
{
break;
}
rc = vboxNetFltSearchCreateInstance(&g_VBoxNetFltGlobals, AnsiString.Buffer, &pInstance, &Context);
RtlFreeAnsiString(&AnsiString);
- if(RT_FAILURE(rc))
+ if (RT_FAILURE(rc))
{
AssertFailed();
Status = Context.Status != NDIS_STATUS_SUCCESS ? Context.Status : NDIS_STATUS_FAILURE;
@@ -2193,15 +1879,12 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pO
Assert(pInstance);
- if(rc == VINF_ALREADY_INITIALIZED)
+ if (rc == VINF_ALREADY_INITIALIZED)
{
- PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pInstance);
/* the case when our adapter was unbound while IntNet was connected to it */
- /* the instance remains valid until intNet disconnects from it, we simply search and re-use it*/
-
- /* re-initialize PADAPT */
+ /* the instance remains valid until IntNet disconnects from it, we simply search and re-use it*/
rc = vboxNetFltWinAttachToInterface(pInstance, &Context, true);
- if(RT_FAILURE(rc))
+ if (RT_FAILURE(rc))
{
AssertFailed();
Status = Context.Status != NDIS_STATUS_SUCCESS ? Context.Status : NDIS_STATUS_FAILURE;
@@ -2212,257 +1895,138 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pO
}
}
- *ppAdapt = PVBOXNETFLTINS_2_PADAPT(pInstance);
-#else
- Status = vboxNetFltWinPtAllocInitPADAPT(pAdapt);
- if (Status != NDIS_STATUS_SUCCESS)
- {
- break;
- }
-
- Status = vboxNetFltWinPtDoBinding(pAdapt);
- if (Status != NDIS_STATUS_SUCCESS)
- {
- vboxNetFltWinPtFiniPADAPT(pAdapt);
- break;
- }
-#endif
- }while(FALSE);
-
- return Status;
-}
-
-/**
- * initializes the ADAPT
- */
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT pAdapt)
-{
- NDIS_STATUS Status;
-
- do
- {
- Status = vboxNetFltWinPtInitPADAPT(pAdapt);
- if (Status != NDIS_STATUS_SUCCESS)
- {
- break;
- }
- Status = NDIS_STATUS_SUCCESS;
- } while(0);
-
- return Status;
-}
+ *ppNetFlt = pInstance;
-/**
- * unbinds from the adapter we are bound to and deinitializes the ADAPT
- */
-static NDIS_STATUS vboxNetFltWinPtFiniUnbind(PADAPT pAdapt)
-{
- NDIS_STATUS Status;
-
- LogFlow(("==> vboxNetFltWinPtFiniUnbind: Adapt %p\n", pAdapt));
-
- Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
-
- do
- {
- Status = vboxNetFltWinPtDoUnbinding(pAdapt, true);
- if(Status != NDIS_STATUS_SUCCESS)
- {
- AssertFailed();
- /* TODO: should we break ? */
- /* break; */
- }
-
- vboxNetFltWinPtFiniPADAPT(pAdapt);
- } while(0);
- LogFlow(("<== vboxNetFltWinPtFiniUnbind: Adapt %p\n", pAdapt));
+ } while (FALSE);
return Status;
}
-#endif
-
/*
- * deinitializes the ADAPT
+ * deinitializes the VBOXNETFLTWIN
*/
-DECLHIDDEN(VOID) vboxNetFltWinPtFiniPADAPT(PADAPT pAdapt)
+DECLHIDDEN(VOID) vboxNetFltWinPtFiniWinIf(PVBOXNETFLTWIN pWinIf)
{
#ifndef VBOXNETADP
int rc;
#endif
- LogFlow(("<== vboxNetFltWinPtFiniPADAPT : pAdapt %p\n", pAdapt));
+ LogFlow(("==>"__FUNCTION__" : pWinIf 0x%p\n", pWinIf));
Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
#ifndef VBOXNETADP
- if(pAdapt->DeviceName.Buffer)
+ if (pWinIf->MpDeviceName.Buffer)
{
- vboxNetFltWinMemFree(pAdapt->DeviceName.Buffer);
+ vboxNetFltWinMemFree(pWinIf->MpDeviceName.Buffer);
}
- FINI_INTERLOCKED_SINGLE_LIST(&pAdapt->TransferDataList);
+ FINI_INTERLOCKED_SINGLE_LIST(&pWinIf->TransferDataList);
# if defined(DEBUG_NETFLT_LOOPBACK) || !defined(VBOX_LOOPBACK_USEFLAGS)
- FINI_INTERLOCKED_SINGLE_LIST(&pAdapt->SendPacketQueue);
+ FINI_INTERLOCKED_SINGLE_LIST(&pWinIf->SendPacketQueue);
# endif
+ NdisFreeBufferPool(pWinIf->hSendBufferPool);
+ NdisFreePacketPool(pWinIf->hSendPacketPool);
+ rc = RTSemFastMutexDestroy(pWinIf->hSynchRequestMutex); AssertRC(rc);
#endif
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- /* moved to vboxNetFltWinDetachFromInterfaceWorker */
-#else
-# ifndef VBOXNETFLT_NO_PACKET_QUEUE
- vboxNetFltWinQuFiniPacketQueue(pAdapt);
-# endif
-#endif
-
- vboxNetFltWinFiniBuffers(pAdapt);
-
- /*
- * Free the memory here, if was not released earlier(by calling the HaltHandler)
- */
- vboxNetFltWinPtFreeAllPacketPools (pAdapt);
-#ifndef VBOXNETADP
- rc = RTSemFastMutexDestroy(pAdapt->hSynchRequestMutex); AssertRC(rc);
-#endif
+ /* NOTE: NULL is a valid handle */
+ NdisFreeBufferPool(pWinIf->hRecvBufferPool);
+ NdisFreePacketPool(pWinIf->hRecvPacketPool);
- LogFlow(("<== vboxNetFltWinPtFiniPADAPT : pAdapt %p\n", pAdapt));
+ LogFlow(("<=="__FUNCTION__" : pWinIf 0x%p\n", pWinIf));
}
-DECLHIDDEN(VOID) vboxNetFltWinPtFiniPADAPT(PADAPT pAdapt);
#ifndef VBOXNETADP
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt, IN PNDIS_STRING pOurDeviceName)
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitWinIf(PVBOXNETFLTWIN pWinIf, IN PNDIS_STRING pOurDeviceName)
#else
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt)
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitWinIf(PVBOXNETFLTWIN pWinIf)
#endif
{
- NDIS_STATUS Status;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
#ifndef VBOXNETADP
int rc;
#endif
- BOOLEAN bCallFiniOnFail = FALSE;
+ BOOLEAN bCallFiniOnFail = FALSE;
- LogFlow(("==> vboxNetFltWinPtInitPADAPT : pAdapt %p\n", pAdapt));
+ LogFlow(("==>"__FUNCTION__": pWinIf 0x%p\n", pWinIf));
Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
- do
+ NdisZeroMemory(pWinIf, sizeof (VBOXNETFLTWIN));
+ NdisAllocatePacketPoolEx(&Status, &pWinIf->hRecvPacketPool,
+ VBOXNETFLT_PACKET_POOL_SIZE_NORMAL,
+ VBOXNETFLT_PACKET_POOL_SIZE_OVERFLOW,
+ PROTOCOL_RESERVED_SIZE_IN_PACKET);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
{
- NdisZeroMemory(pAdapt, sizeof(ADAPT));
-#ifndef VBOXNETADP
- NdisInitializeEvent(&pAdapt->hEvent);
-
- KeInitializeEvent(&pAdapt->hSynchCompletionEvent, SynchronizationEvent, FALSE);
-
- /*
- * Allocate a packet pool for sends. We need this to pass sends down.
- * We cannot use the same packet descriptor that came down to our send
- * handler (see also NDIS 5.1 packet stacking).
- */
- NdisAllocatePacketPoolEx(&Status,
- &pAdapt->hSendPacketPoolHandle,
- MIN_PACKET_POOL_SIZE,
- MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
- sizeof(SEND_RSVD));
-
- if (Status != NDIS_STATUS_SUCCESS)
- {
- pAdapt->hSendPacketPoolHandle = NULL;
- break;
- }
-#else
-#endif
-
- Status = vboxNetFltWinInitBuffers(pAdapt);
- if (Status != NDIS_STATUS_SUCCESS)
+ /* NOTE: NULL is a valid handle !!! */
+ NdisAllocateBufferPool(&Status, &pWinIf->hRecvBufferPool, VBOXNETFLT_BUFFER_POOL_SIZE_RX);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
{
- break;
- }
-
- bCallFiniOnFail = TRUE;
+ pWinIf->MpState.PowerState = NdisDeviceStateD3;
+ vboxNetFltWinSetOpState(&pWinIf->MpState, kVBoxNetDevOpState_Deinitialized);
#ifndef VBOXNETADP
- rc = RTSemFastMutexCreate(&pAdapt->hSynchRequestMutex);
- if(RT_FAILURE(rc))
- {
- Status = NDIS_STATUS_FAILURE;
- break;
- }
-#endif
+ pWinIf->PtState.PowerState = NdisDeviceStateD3;
+ vboxNetFltWinSetOpState(&pWinIf->PtState, kVBoxNetDevOpState_Deinitialized);
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
-# ifndef VBOXNETADP
- Status = vboxNetFltWinMemAlloc((PVOID*)&pAdapt->DeviceName.Buffer, pOurDeviceName->Length);
- if(Status != NDIS_STATUS_SUCCESS)
- {
- AssertFailed();
- pAdapt->DeviceName.Buffer = NULL;
- break;
- }
- pAdapt->DeviceName.MaximumLength = pOurDeviceName->Length;
- pAdapt->DeviceName.Length = 0;
- Status = vboxNetFltWinCopyString(&pAdapt->DeviceName, pOurDeviceName);
- if(Status != NDIS_STATUS_SUCCESS)
- {
- AssertFailed();
- break;
- }
-# endif
+ NdisAllocateBufferPool(&Status,
+ &pWinIf->hSendBufferPool,
+ VBOXNETFLT_BUFFER_POOL_SIZE_TX);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ INIT_INTERLOCKED_SINGLE_LIST(&pWinIf->TransferDataList);
- /*
- * Allocate a packet pool for receives. We need this to indicate receives.
- * Same consideration as sends (see also NDIS 5.1 packet stacking).
- */
- NdisAllocatePacketPoolEx(&Status,
- &pAdapt->hRecvPacketPoolHandle,
- MIN_PACKET_POOL_SIZE,
- MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
- PROTOCOL_RESERVED_SIZE_IN_PACKET);
+# if defined(DEBUG_NETFLT_LOOPBACK) || !defined(VBOX_LOOPBACK_USEFLAGS)
+ INIT_INTERLOCKED_SINGLE_LIST(&pWinIf->SendPacketQueue);
+# endif
+ NdisInitializeEvent(&pWinIf->OpenCloseEvent);
- if (Status != NDIS_STATUS_SUCCESS)
- {
- pAdapt->hRecvPacketPoolHandle = NULL;
- break;
- }
-#ifndef VBOXNETADP
- NdisInitializeEvent(&pAdapt->MiniportInitEvent);
-#endif
-#endif
-#ifndef VBOXNETADP
- pAdapt->PTState.PowerState = NdisDeviceStateD3;
- vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
+ KeInitializeEvent(&pWinIf->hSynchCompletionEvent, SynchronizationEvent, FALSE);
- INIT_INTERLOCKED_SINGLE_LIST(&pAdapt->TransferDataList);
+ NdisInitializeEvent(&pWinIf->MpInitCompleteEvent);
-# if defined(DEBUG_NETFLT_LOOPBACK) || !defined(VBOX_LOOPBACK_USEFLAGS)
- INIT_INTERLOCKED_SINGLE_LIST(&pAdapt->SendPacketQueue);
-# endif
+ NdisAllocatePacketPoolEx(&Status, &pWinIf->hSendPacketPool,
+ VBOXNETFLT_PACKET_POOL_SIZE_NORMAL,
+ VBOXNETFLT_PACKET_POOL_SIZE_OVERFLOW,
+ sizeof (PVBOXNETFLT_PKTRSVD_PT));
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ rc = RTSemFastMutexCreate(&pWinIf->hSynchRequestMutex);
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ {
+ Status = vboxNetFltWinMemAlloc((PVOID*)&pWinIf->MpDeviceName.Buffer, pOurDeviceName->Length);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ pWinIf->MpDeviceName.MaximumLength = pOurDeviceName->Length;
+ pWinIf->MpDeviceName.Length = 0;
+ Status = vboxNetFltWinCopyString(&pWinIf->MpDeviceName, pOurDeviceName);
#endif
- /* TODO: do we need it here ?? */
- pAdapt->MPState.PowerState = NdisDeviceStateD3;
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
-
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- {
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- rc = vboxNetFltWinConnectIt(pNetFlt);
- if(RT_FAILURE(rc))
- {
- AssertFailed();
- Status = NDIS_STATUS_FAILURE;
- break;
+ return NDIS_STATUS_SUCCESS;
+#ifndef VBOXNETADP
+ vboxNetFltWinMemFree(pWinIf->MpDeviceName.Buffer);
+ }
+ RTSemFastMutexDestroy(pWinIf->hSynchRequestMutex);
+ }
+ else
+ {
+ Status = NDIS_STATUS_FAILURE;
+ }
+ NdisFreePacketPool(pWinIf->hSendPacketPool);
+ }
+ NdisFreeBufferPool(pWinIf->hSendBufferPool);
}
- }
#endif
- /* moved to vboxNetFltOsInitInstance */
- } while(0);
-
- if (Status != NDIS_STATUS_SUCCESS)
- {
- if(bCallFiniOnFail)
- {
- vboxNetFltWinPtFiniPADAPT(pAdapt);
+ NdisFreeBufferPool(pWinIf->hRecvBufferPool);
}
+ NdisFreePacketPool(pWinIf->hRecvPacketPool);
}
- LogFlow(("<== vboxNetFltWinPtInitPADAPT : pAdapt %p, Status %x\n", pAdapt, Status));
+ LogFlow(("<=="__FUNCTION__": pWinIf 0x%p, Status 0x%x\n", pWinIf, Status));
return Status;
}
@@ -2496,13 +2060,13 @@ DECLHIDDEN(PRTNETETHERHDR) vboxNetFltWinGetEthHdr(PNDIS_PACKET pPacket)
NdisQueryPacket(pPacket, NULL, &cBufCount1, &pBuffer1, &uTotalPacketLength1);
Assert(pBuffer1);
- Assert(uTotalPacketLength1 >= ETH_HEADER_SIZE);
- if(uTotalPacketLength1 < ETH_HEADER_SIZE)
+ Assert(uTotalPacketLength1 >= VBOXNETFLT_PACKET_ETHEADER_SIZE);
+ if (uTotalPacketLength1 < VBOXNETFLT_PACKET_ETHEADER_SIZE)
return NULL;
NdisQueryBufferSafe(pBuffer1, &pEth, &cbLength1, NormalPagePriority);
- Assert(cbLength1 >= ETH_HEADER_SIZE);
- if(cbLength1 < ETH_HEADER_SIZE)
+ Assert(cbLength1 >= VBOXNETFLT_PACKET_ETHEADER_SIZE);
+ if (cbLength1 < VBOXNETFLT_PACKET_ETHEADER_SIZE)
return NULL;
return pEth;
@@ -2512,12 +2076,12 @@ DECLHIDDEN(PRTNETETHERHDR) vboxNetFltWinGetEthHdrSG(PINTNETSG pSG)
{
Assert(pSG->cSegsUsed);
Assert(pSG->cSegsAlloc >= pSG->cSegsUsed);
- Assert(pSG->aSegs[0].cb >= ETH_HEADER_SIZE);
+ Assert(pSG->aSegs[0].cb >= VBOXNETFLT_PACKET_ETHEADER_SIZE);
- if(!pSG->cSegsUsed)
+ if (!pSG->cSegsUsed)
return NULL;
- if(pSG->aSegs[0].cb < ETH_HEADER_SIZE)
+ if (pSG->aSegs[0].cb < VBOXNETFLT_PACKET_ETHEADER_SIZE)
return NULL;
return (PRTNETETHERHDR)pSG->aSegs[0].pv;
@@ -2528,13 +2092,13 @@ DECLHIDDEN(bool) vboxNetFltWinCheckMACs(PNDIS_PACKET pPacket, PRTMAC pDst, PRTMA
PRTNETETHERHDR pHdr = vboxNetFltWinGetEthHdr(pPacket);
Assert(pHdr);
- if(!pHdr)
+ if (!pHdr)
return false;
- if(pDst && memcmp(pDst, &pHdr->DstMac, sizeof(RTMAC)))
+ if (pDst && memcmp(pDst, &pHdr->DstMac, sizeof(RTMAC)))
return false;
- if(pSrc && memcmp(pSrc, &pHdr->SrcMac, sizeof(RTMAC)))
+ if (pSrc && memcmp(pSrc, &pHdr->SrcMac, sizeof(RTMAC)))
return false;
return true;
@@ -2545,13 +2109,13 @@ DECLHIDDEN(bool) vboxNetFltWinCheckMACsSG(PINTNETSG pSG, PRTMAC pDst, PRTMAC pSr
PRTNETETHERHDR pHdr = vboxNetFltWinGetEthHdrSG(pSG);
Assert(pHdr);
- if(!pHdr)
+ if (!pHdr)
return false;
- if(pDst && memcmp(pDst, &pHdr->DstMac, sizeof(RTMAC)))
+ if (pDst && memcmp(pDst, &pHdr->DstMac, sizeof(RTMAC)))
return false;
- if(pSrc && memcmp(pSrc, &pHdr->SrcMac, sizeof(RTMAC)))
+ if (pSrc && memcmp(pSrc, &pHdr->SrcMac, sizeof(RTMAC)))
return false;
return true;
@@ -2588,7 +2152,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET p
Assert(pBuffer1);
Assert(pBuffer2);
- if(uTotalPacketLength1 != uTotalPacketLength2)
+ if (uTotalPacketLength1 != uTotalPacketLength2)
{
bMatch = false;
}
@@ -2596,7 +2160,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET p
{
UINT ucbLength2Match = 0;
UINT ucbMatch;
- if(cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1)
+ if (cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1)
{
/* NOTE: assuming uTotalPacketLength1 == uTotalPacketLength2*/
ucbMatch = uTotalPacketLength1;
@@ -2609,9 +2173,9 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET p
ucbMatch = (UINT)cbMatch;
}
- for(;;)
+ for (;;)
{
- if(!cbLength1)
+ if (!cbLength1)
{
NdisQueryBufferSafe(pBuffer1, &pMemBuf1, &cbLength1, NormalPagePriority);
NdisGetNextBuffer(pBuffer1, &pBuffer1);
@@ -2623,7 +2187,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET p
pMemBuf1 += ucbLength2Match;
}
- if(!cbLength2)
+ if (!cbLength2)
{
NdisQueryBufferSafe(pBuffer2, &pMemBuf2, &cbLength2, NormalPagePriority);
NdisGetNextBuffer(pBuffer2, &pBuffer2);
@@ -2638,14 +2202,14 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET p
ucbLength2Match = MIN(ucbMatch, cbLength1);
ucbLength2Match = MIN(ucbLength2Match, cbLength2);
- if(memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match))
+ if (memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match))
{
bMatch = false;
break;
}
ucbMatch -= ucbLength2Match;
- if(!ucbMatch)
+ if (!ucbMatch)
break;
cbLength1 -= ucbLength2Match;
@@ -2654,7 +2218,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET p
}
#ifdef DEBUG_NETFLT_PACKETS
- if(bMatch && !bCompleteMatch)
+ if (bMatch && !bCompleteMatch)
{
/* check that the packets fully match */
DBG_CHECK_PACKETS(pPacket1, pPacket2);
@@ -2688,7 +2252,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p
Assert(pSG->cSegsUsed);
Assert(pSG->cSegsAlloc >= pSG->cSegsUsed);
- if(uTotalPacketLength1 != uTotalPacketLength2)
+ if (uTotalPacketLength1 != uTotalPacketLength2)
{
AssertFailed();
bMatch = false;
@@ -2698,7 +2262,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p
UINT ucbLength2Match = 0;
UINT ucbMatch;
- if(cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1)
+ if (cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1)
{
/* NOTE: assuming uTotalPacketLength1 == uTotalPacketLength2*/
ucbMatch = uTotalPacketLength1;
@@ -2709,9 +2273,9 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p
ucbMatch = (UINT)cbMatch;
}
- for(;;)
+ for (;;)
{
- if(!cbLength1)
+ if (!cbLength1)
{
NdisQueryBufferSafe(pBuffer1, &pMemBuf1, &cbLength1, NormalPagePriority);
NdisGetNextBuffer(pBuffer1, &pBuffer1);
@@ -2723,7 +2287,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p
pMemBuf1 += ucbLength2Match;
}
- if(!cbLength2)
+ if (!cbLength2)
{
Assert(i < pSG->cSegsUsed);
pMemBuf2 = (uint8_t*)pSG->aSegs[i].pv;
@@ -2740,7 +2304,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p
ucbLength2Match = MIN(ucbMatch, cbLength1);
ucbLength2Match = MIN(ucbLength2Match, cbLength2);
- if(memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match))
+ if (memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match))
{
bMatch = false;
AssertFailed();
@@ -2748,7 +2312,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p
}
ucbMatch -= ucbLength2Match;
- if(!ucbMatch)
+ if (!ucbMatch)
break;
cbLength1 -= ucbLength2Match;
@@ -2756,7 +2320,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p
}
}
- if(bMatch && !bCompleteMatch)
+ if (bMatch && !bCompleteMatch)
{
/* check that the packets fully match */
DBG_CHECK_PACKET_AND_SG(pPacket, pSG);
@@ -2788,7 +2352,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa
Assert(pSG1->cSegsAlloc >= pSG1->cSegsUsed);
Assert(pSG2->cSegsAlloc >= pSG2->cSegsUsed);
- if(uTotalPacketLength1 != uTotalPacketLength2)
+ if (uTotalPacketLength1 != uTotalPacketLength2)
{
AssertFailed();
bMatch = false;
@@ -2796,7 +2360,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa
else
{
UINT ucbMatch;
- if(cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1)
+ if (cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1)
{
/* NOTE: assuming uTotalPacketLength1 == uTotalPacketLength2*/
ucbMatch = uTotalPacketLength1;
@@ -2810,7 +2374,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa
do
{
UINT ucbLength2Match;
- if(!cbLength1)
+ if (!cbLength1)
{
Assert(i1 < pSG1->cSegsUsed);
pMemBuf1 = pSG1->aSegs[i1].pv;
@@ -2818,7 +2382,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa
i1++;
}
- if(!cbLength2)
+ if (!cbLength2)
{
Assert(i2 < pSG2->cSegsUsed);
pMemBuf2 = pSG2->aSegs[i2].pv;
@@ -2829,7 +2393,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa
ucbLength2Match = MIN(ucbMatch, cbLength1);
ucbLength2Match = MIN(ucbLength2Match, cbLength2);
- if(memcmp(pMemBuf1, pMemBuf2, ucbLength2Match))
+ if (memcmp(pMemBuf1, pMemBuf2, ucbLength2Match))
{
bMatch = false;
AssertFailed();
@@ -2841,7 +2405,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa
} while (ucbMatch);
}
- if(bMatch && !bCompleteMatch)
+ if (bMatch && !bCompleteMatch)
{
/* check that the packets fully match */
DBG_CHECK_SGS(pSG1, pSG2);
@@ -2876,12 +2440,12 @@ static int vboxNetFltWinTryFiniIdc()
vboxNetFltWinStopInitIdcProbing();
- if(g_bIdcInitialized)
+ if (g_bVBoxIdcInitialized)
{
rc = vboxNetFltTryDeleteIdc(&g_VBoxNetFltGlobals);
- if(RT_SUCCESS(rc))
+ if (RT_SUCCESS(rc))
{
- g_bIdcInitialized = false;
+ g_bVBoxIdcInitialized = false;
}
}
else
@@ -2895,7 +2459,7 @@ static int vboxNetFltWinTryFiniIdc()
static int vboxNetFltWinFiniNetFlt()
{
int rc = vboxNetFltWinTryFiniIdc();
- if(RT_SUCCESS(rc))
+ if (RT_SUCCESS(rc))
{
vboxNetFltWinFiniNetFltBase();
}
@@ -2911,7 +2475,7 @@ static int vboxNetFltWinInitNetFltBase()
do
{
- Assert(!g_bIdcInitialized);
+ Assert(!g_bVBoxIdcInitialized);
rc = RTR0Init(0);
if (!RT_SUCCESS(rc))
@@ -2926,7 +2490,7 @@ static int vboxNetFltWinInitNetFltBase()
RTR0Term();
break;
}
- }while(0);
+ }while (0);
return rc;
}
@@ -2940,11 +2504,8 @@ static int vboxNetFltWinInitIdc()
do
{
- if(g_bIdcInitialized)
+ if (g_bVBoxIdcInitialized)
{
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- AssertFailed();
-#endif
rc = VINF_ALREADY_INITIALIZED;
break;
}
@@ -2961,25 +2522,26 @@ static int vboxNetFltWinInitIdc()
break;
}
- g_bIdcInitialized = true;
+ g_bVBoxIdcInitialized = true;
} while (0);
return rc;
}
-static void vboxNetFltWinInitIdcProbingWorker(PINIT_IDC_INFO pInitIdcInfo)
+static VOID vboxNetFltWinInitIdcProbingWorker(PVOID pvContext)
{
+ PINIT_IDC_INFO pInitIdcInfo = (PINIT_IDC_INFO)pvContext;
int rc = vboxNetFltWinInitIdc();
- if(RT_FAILURE(rc))
+ if (RT_FAILURE(rc))
{
bool bInterupted = ASMAtomicUoReadBool(&pInitIdcInfo->bStop);
- if(!bInterupted)
+ if (!bInterupted)
{
RTThreadSleep(1000); /* 1 s */
bInterupted = ASMAtomicUoReadBool(&pInitIdcInfo->bStop);
- if(!bInterupted)
+ if (!bInterupted)
{
- vboxNetFltWinJobEnqueueJob(&g_JobQueue, &pInitIdcInfo->Job, false);
+ vboxNetFltWinJobEnqueueJob(&g_VBoxJobQueue, &pInitIdcInfo->Job, false);
return;
}
}
@@ -2988,29 +2550,29 @@ static void vboxNetFltWinInitIdcProbingWorker(PINIT_IDC_INFO pInitIdcInfo)
rc = VERR_INTERRUPTED;
}
- ASMAtomicUoWriteU32(&pInitIdcInfo->rc, rc);
+ ASMAtomicUoWriteS32(&pInitIdcInfo->rc, rc);
KeSetEvent(&pInitIdcInfo->hCompletionEvent, 0, FALSE);
}
static int vboxNetFltWinStopInitIdcProbing()
{
- if(!g_InitIdcInfo.bInitialized)
+ if (!g_VBoxInitIdcInfo.bInitialized)
return VERR_INVALID_STATE;
- ASMAtomicUoWriteBool(&g_InitIdcInfo.bStop, true);
- KeWaitForSingleObject(&g_InitIdcInfo.hCompletionEvent, Executive, KernelMode, FALSE, NULL);
+ ASMAtomicUoWriteBool(&g_VBoxInitIdcInfo.bStop, true);
+ KeWaitForSingleObject(&g_VBoxInitIdcInfo.hCompletionEvent, Executive, KernelMode, FALSE, NULL);
- return g_InitIdcInfo.rc;
+ return g_VBoxInitIdcInfo.rc;
}
static int vboxNetFltWinStartInitIdcProbing()
{
- Assert(!g_bIdcInitialized);
- KeInitializeEvent(&g_InitIdcInfo.hCompletionEvent, NotificationEvent, FALSE);
- g_InitIdcInfo.bStop = false;
- g_InitIdcInfo.bInitialized = true;
- vboxNetFltWinJobInit(&g_InitIdcInfo.Job, vboxNetFltWinInitIdcProbingWorker, &g_InitIdcInfo, false);
- vboxNetFltWinJobEnqueueJob(&g_JobQueue, &g_InitIdcInfo.Job, false);
+ Assert(!g_bVBoxIdcInitialized);
+ KeInitializeEvent(&g_VBoxInitIdcInfo.hCompletionEvent, NotificationEvent, FALSE);
+ g_VBoxInitIdcInfo.bStop = false;
+ g_VBoxInitIdcInfo.bInitialized = true;
+ vboxNetFltWinJobInit(&g_VBoxInitIdcInfo.Job, vboxNetFltWinInitIdcProbingWorker, &g_VBoxInitIdcInfo, false);
+ vboxNetFltWinJobEnqueueJob(&g_VBoxJobQueue, &g_VBoxInitIdcInfo.Job, false);
return VINF_SUCCESS;
}
@@ -3021,7 +2583,7 @@ static int vboxNetFltWinInitNetFlt()
do
{
rc = vboxNetFltWinInitNetFltBase();
- if(RT_FAILURE(rc))
+ if (RT_FAILURE(rc))
{
AssertFailed();
break;
@@ -3048,40 +2610,26 @@ static int vboxNetFltWinInitNetFlt()
/* detach*/
static int vboxNetFltWinDeleteInstance(PVBOXNETFLTINS pThis)
{
- PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- NDIS_STATUS Status;
- LogFlow(("vboxNetFltWinDeleteInstance: pThis=%p \n", pThis));
+ LogFlow(("vboxNetFltWinDeleteInstance: pThis=0x%p \n", pThis));
Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
- Assert(pAdapt);
Assert(pThis);
Assert(pThis->fDisconnectedFromHost);
Assert(!pThis->fRediscoveryPending);
Assert(pThis->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
#ifndef VBOXNETADP
- Assert(pAdapt->PTState.OpState == kVBoxNetDevOpState_Deinitialized);
- Assert(!pAdapt->hBindingHandle);
+ Assert(pThis->u.s.WinIf.PtState.OpState == kVBoxNetDevOpState_Deinitialized);
+ Assert(!pThis->u.s.WinIf.hBinding);
#endif
- Assert(pAdapt->MPState.OpState == kVBoxNetDevOpState_Deinitialized);
+ Assert(pThis->u.s.WinIf.MpState.OpState == kVBoxNetDevOpState_Deinitialized);
#ifndef VBOXNETFLT_NO_PACKET_QUEUE
Assert(!pThis->u.s.PacketQueueWorker.pSG);
#endif
-// Assert(!pAdapt->hMiniportHandle);
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- Status = vboxNetFltWinMpDereferenceControlDevice();
- Assert(Status == NDIS_STATUS_SUCCESS);
-#else
- Status = vboxNetFltWinPtFiniUnbind(pAdapt);
- if(Status != NDIS_STATUS_SUCCESS)
- {
- AssertFailed();
- /* pDetachInfo->Status = VERR_GENERAL_FAILURE; */
- }
-#endif
+ RTSemMutexDestroy(pThis->u.s.hWinIfMutex);
- RTSemMutexDestroy(pThis->u.s.hAdaptMutex);
+ vboxNetFltWinDrvDereference();
return VINF_SUCCESS;
}
@@ -3095,88 +2643,62 @@ static NDIS_STATUS vboxNetFltWinDisconnectIt(PVBOXNETFLTINS pInstance)
}
/* detach*/
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOnUnbind)
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PVBOXNETFLTINS pNetFlt, bool bOnUnbind)
{
- PVBOXNETFLTINS pThis = PADAPT_2_PVBOXNETFLTINS(pAdapt);
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
NDIS_STATUS Status;
int rc;
- LogFlow(("vboxNetFltWinDetachFromInterface: pThis=%p\n", pThis));
+ LogFlow((__FUNCTION__": pThis=%0xp\n", pNetFlt));
Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
- Assert(pAdapt);
- Assert(pThis);
-/* Assert(!pThis->fActive); */
+ Assert(pNetFlt);
- /* paranoia to ensyre the instance is not removed while we're waiting on the mutex
+ /* paranoia to ensure the instance is not removed while we're waiting on the mutex
* in case ndis does something unpredictable, e.g. calls our miniport halt independently
* from protocol unbind and concurrently with it*/
- vboxNetFltRetain(pThis, false);
+ vboxNetFltRetain(pNetFlt, false);
- rc = RTSemMutexRequest(pThis->u.s.hAdaptMutex, RT_INDEFINITE_WAIT);
- if(RT_SUCCESS(rc))
+ rc = RTSemMutexRequest(pNetFlt->u.s.hWinIfMutex, RT_INDEFINITE_WAIT);
+ if (RT_SUCCESS(rc))
{
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- Assert(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Connected);
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized);
+ Assert(vboxNetFltWinGetWinIfState(pNetFlt) == kVBoxWinIfState_Connected);
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized);
#ifndef VBOXNETADP
- Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Initialized);
-#endif
-// if(
-//#ifdef VBOXNETADP
-// vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized
-//#else
-// vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Initialized
-//// && vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized
-//#endif
-// )
- if(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Connected)
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Initialized);
+#endif
+ if (vboxNetFltWinGetWinIfState(pNetFlt) == kVBoxWinIfState_Connected)
{
- vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Disconnecting);
+ vboxNetFltWinSetWinIfState(pNetFlt, kVBoxWinIfState_Disconnecting);
#ifndef VBOXNETADP
- Status = vboxNetFltWinPtDoUnbinding(pAdapt, bOnUnbind);
+ Status = vboxNetFltWinPtDoUnbinding(pNetFlt, bOnUnbind);
#else
- Status = vboxNetFltWinMpDoDeinitialization(pAdapt);
+ Status = vboxNetFltWinMpDoDeinitialization(pNetFlt);
#endif
Assert(Status == NDIS_STATUS_SUCCESS);
- vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Disconnected);
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetWinIfState(pNetFlt, kVBoxWinIfState_Disconnected);
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
#ifndef VBOXNETADP
- Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitialized);
+ Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Deinitialized);
#endif
-// /* paranoia */
-// vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
-//#ifndef VBOXNETADP
-// vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
-//#endif
-
- vboxNetFltWinPtFiniPADAPT(pAdapt);
+ vboxNetFltWinPtFiniWinIf(&pNetFlt->u.s.WinIf);
/* we're unbinding, make an unbind-related release */
- vboxNetFltRelease(pThis, false);
-#else
- Status = vboxNetFltWinPtFiniUnbind(pAdapt);
- if(Status != NDIS_STATUS_SUCCESS)
- {
- AssertFailed();
- /* pDetachInfo->Status = VERR_GENERAL_FAILURE; */
- }
-#endif
+ vboxNetFltRelease(pNetFlt, false);
}
else
{
AssertBreakpoint();
#ifndef VBOXNETADP
- pAdapt->Status = NDIS_STATUS_FAILURE;
+ pNetFlt->u.s.WinIf.OpenCloseStatus = NDIS_STATUS_FAILURE;
#endif
- if(!bOnUnbind)
+ if (!bOnUnbind)
{
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
}
Status = NDIS_STATUS_FAILURE;
}
- RTSemMutexRelease(pThis->u.s.hAdaptMutex);
+ RTSemMutexRelease(pNetFlt->u.s.hWinIfMutex);
}
else
{
@@ -3185,7 +2707,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOn
}
/* release for the retain we made before waining on the mutex */
- vboxNetFltRelease(pThis, false);
+ vboxNetFltRelease(pNetFlt, false);
return Status;
}
@@ -3200,17 +2722,16 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOn
static bool vboxNetFltWinIsPromiscuous2(PVBOXNETFLTINS pThis)
{
#ifndef VBOXNETADP
- PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
- if(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
+ if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pThis))
{
bool bPromiscuous;
- if(!vboxNetFltWinReferenceAdapt(pAdapt))
+ if (!vboxNetFltWinReferenceWinIf(pThis))
return false;
- bPromiscuous = (pAdapt->fUpperProtocolSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS) == NDIS_PACKET_TYPE_PROMISCUOUS;
+ bPromiscuous = (pThis->u.s.WinIf.fUpperProtocolSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS) == NDIS_PACKET_TYPE_PROMISCUOUS;
/*vboxNetFltWinIsPromiscuous(pAdapt);*/
- vboxNetFltWinDereferenceAdapt(pAdapt);
+ vboxNetFltWinDereferenceWinIf(pThis);
return bPromiscuous;
}
return false;
@@ -3231,7 +2752,7 @@ static bool vboxNetFltWinIsPromiscuous2(PVBOXNETFLTINS pThis)
static void vboxNetFltWinReportStuff(PVBOXNETFLTINS pThis)
{
/** @todo Keep these up to date, esp. the promiscuous mode bit. */
- if ( pThis->pSwitchPort
+ if (pThis->pSwitchPort
&& vboxNetFltTryRetainBusyNotDisconnected(pThis))
{
pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
@@ -3256,142 +2777,101 @@ static void vboxNetFltWinAttachToInterfaceWorker(PATTACH_INFO pAttachInfo)
PVBOXNETFLTINS pThis = pAttachInfo->pNetFltIf;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
int rc;
- PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
/* to ensure we're not removed while we're here */
vboxNetFltRetain(pThis, false);
- rc = RTSemMutexRequest(pThis->u.s.hAdaptMutex, RT_INDEFINITE_WAIT);
- if(RT_SUCCESS(rc))
+ rc = RTSemMutexRequest(pThis->u.s.hWinIfMutex, RT_INDEFINITE_WAIT);
+ if (RT_SUCCESS(rc))
{
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- Assert(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Disconnected);
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
+ Assert(vboxNetFltWinGetWinIfState(pThis) == kVBoxWinIfState_Disconnected);
+ Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
#ifndef VBOXNETADP
- Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitialized);
+ Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.PtState) == kVBoxNetDevOpState_Deinitialized);
#endif
-// if(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized
-//#ifndef VBOXNETADP
-// && vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized
-//#endif
-// )
- if(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Disconnected)
+ if (vboxNetFltWinGetWinIfState(pThis) == kVBoxWinIfState_Disconnected)
{
-
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
- if(pAttachInfo->fRediscovery)
+ if (pAttachInfo->fRediscovery)
{
/* rediscovery means adaptor bind is performed while intnet is already using it
* i.e. adaptor was unbound while being used by intnet and now being bound back again */
Assert(((VBOXNETFTLINSSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pThis->enmState)) == kVBoxNetFltInsState_Connected);
}
#ifndef VBOXNETADP
- Status = vboxNetFltWinPtInitPADAPT(pAdapt, pAttachInfo->pCreateContext->pOurName);
+ Status = vboxNetFltWinPtInitWinIf(&pThis->u.s.WinIf, pAttachInfo->pCreateContext->pOurName);
#else
- Status = vboxNetFltWinPtInitPADAPT(pAdapt);
+ Status = vboxNetFltWinPtInitWinIf(&pThis->u.s.WinIf);
#endif
- if(Status == NDIS_STATUS_SUCCESS)
+ if (Status == NDIS_STATUS_SUCCESS)
{
- vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Connecting);
+ vboxNetFltWinSetWinIfState(pThis, kVBoxWinIfState_Connecting);
#ifndef VBOXNETADP
- Status = vboxNetFltWinPtDoBinding(pAdapt, pAttachInfo->pCreateContext->pOurName, pAttachInfo->pCreateContext->pBindToName);
+ Status = vboxNetFltWinPtDoBinding(pThis, pAttachInfo->pCreateContext->pOurName, pAttachInfo->pCreateContext->pBindToName);
#else
- Status = vboxNetFltWinMpDoInitialization(pAdapt, pAttachInfo->pCreateContext->hMiniportAdapter, pAttachInfo->pCreateContext->hWrapperConfigurationContext);
+ Status = vboxNetFltWinMpDoInitialization(pThis, pAttachInfo->pCreateContext->hMiniportAdapter, pAttachInfo->pCreateContext->hWrapperConfigurationContext);
#endif
if (Status == NDIS_STATUS_SUCCESS)
{
- if(pAttachInfo->fRediscovery || (Status = vboxNetFltWinMpReferenceControlDevice()) == NDIS_STATUS_SUCCESS)
+ if (!pAttachInfo->fRediscovery)
{
+ vboxNetFltWinDrvReference();
+ }
#ifndef VBOXNETADP
- if(pAdapt->Status == NDIS_STATUS_SUCCESS)
+ if (pThis->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS)
#endif
- {
- vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Connected);
-// Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized);
+ {
+ vboxNetFltWinSetWinIfState(pThis, kVBoxWinIfState_Connected);
#ifndef VBOXNETADP
- Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Initialized);
+ Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.PtState) == kVBoxNetDevOpState_Initialized);
#endif
-// /* paranoia */
-//// vboxNetFltWinSetAdaptState(&pAdapt->MPState, kVBoxNetDevOpState_Initialized);
-//#ifndef VBOXNETADP
-// vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Initialized);
-//#endif
-
-
- /* 4. mark as connected */
- RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
- ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, false);
- RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
+ /* 4. mark as connected */
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
+ ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, false);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
- pAttachInfo->Status = VINF_SUCCESS;
- pAttachInfo->pCreateContext->Status = NDIS_STATUS_SUCCESS;
+ pAttachInfo->Status = VINF_SUCCESS;
+ pAttachInfo->pCreateContext->Status = NDIS_STATUS_SUCCESS;
- RTSemMutexRelease(pThis->u.s.hAdaptMutex);
+ RTSemMutexRelease(pThis->u.s.hWinIfMutex);
- vboxNetFltRelease(pThis, false);
+ vboxNetFltRelease(pThis, false);
- /* 5. Report MAC address, promiscuousness and GSO capabilities. */
- vboxNetFltWinReportStuff(pThis);
+ /* 5. Report MAC address, promiscuousness and GSO capabilities. */
+ vboxNetFltWinReportStuff(pThis);
- return;
- }
- AssertBreakpoint();
-
- if(!pAttachInfo->fRediscovery)
- {
- vboxNetFltWinMpDereferenceControlDevice();
- }
+ return;
}
AssertBreakpoint();
+
+ if (!pAttachInfo->fRediscovery)
+ {
+ vboxNetFltWinDrvDereference();
+ }
#ifndef VBOXNETADP
- vboxNetFltWinPtDoUnbinding(pAdapt, true);
+ vboxNetFltWinPtDoUnbinding(pThis, true);
#else
- vboxNetFltWinMpDoDeinitialization(pAdapt);
+ vboxNetFltWinMpDoDeinitialization(pThis);
#endif
}
AssertBreakpoint();
- vboxNetFltWinPtFiniPADAPT(pAdapt);
+ vboxNetFltWinPtFiniWinIf(&pThis->u.s.WinIf);
}
AssertBreakpoint();
- vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Disconnected);
- Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetWinIfState(pThis, kVBoxWinIfState_Disconnected);
+ Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
#ifndef VBOXNETADP
- Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitialized);
+ Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.PtState) == kVBoxNetDevOpState_Deinitialized);
#endif
-// /* paranoia */
-// vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
-//#ifndef VBOXNETADP
-// vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
-//#endif
}
AssertBreakpoint();
-#else /* VBOX_NETFLT_ONDEMAND_BIND */
- Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
-
- Status = vboxNetFltWinPtInitBind(pAdapt);
- if (Status != NDIS_STATUS_SUCCESS)
- {
- pAttachInfo->Status = VERR_GENERAL_FAILURE;
- break;
- }
-
- Status = vboxNetFltWinGetMacAddress(pAdapt, &pThis->u.s.MacAddr);
- if (Status != NDIS_STATUS_SUCCESS)
- {
- vboxNetFltWinPtFiniUnbind(pAdapt);
- pAttachInfo->Status = VERR_GENERAL_FAILURE;
- break;
- }
-#endif /* VBOX_NETFLT_ONDEMAND_BIND */
-
-
pAttachInfo->Status = VERR_GENERAL_FAILURE;
pAttachInfo->pCreateContext->Status = Status;
- RTSemMutexRelease(pThis->u.s.hAdaptMutex);
+ RTSemMutexRelease(pThis->u.s.hWinIfMutex);
}
else
{
@@ -3420,15 +2900,143 @@ static int vboxNetFltWinAttachToInterface(PVBOXNETFLTINS pThis, void * pContext,
Info.fRediscovery = fRediscovery;
Info.pCreateContext = (PCREATE_INSTANCE_CONTEXT)pContext;
-
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- /* packet queue worker thread gets created on attach interface, need to do it via job at passive level */
- vboxNetFltWinJobSynchExecAtPassive((JOB_ROUTINE)vboxNetFltWinAttachToInterfaceWorker, &Info);
-#else
vboxNetFltWinAttachToInterfaceWorker(&Info);
-#endif
+
return Info.Status;
}
+static NTSTATUS vboxNetFltWinPtDevDispatch(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
+{
+ PIO_STACK_LOCATION pIrpSl = IoGetCurrentIrpStackLocation(pIrp);;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ switch (pIrpSl->MajorFunction)
+ {
+ case IRP_MJ_DEVICE_CONTROL:
+ Status = STATUS_NOT_SUPPORTED;
+ break;
+ case IRP_MJ_CREATE:
+ case IRP_MJ_CLEANUP:
+ case IRP_MJ_CLOSE:
+ break;
+ default:
+ Assert(0);
+ break;
+ }
+
+ pIrp->IoStatus.Status = Status;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+
+ return Status;
+}
+
+static NDIS_STATUS vboxNetFltWinDevCreate(PVBOXNETFLTGLOBALS_WIN pGlobals)
+{
+ NDIS_STRING DevName, LinkName;
+ PDRIVER_DISPATCH aMajorFunctions[IRP_MJ_MAXIMUM_FUNCTION+1];
+ NdisInitUnicodeString(&DevName, VBOXNETFLT_NAME_DEVICE);
+ NdisInitUnicodeString(&LinkName, VBOXNETFLT_NAME_LINK);
+
+ Assert(!pGlobals->hDevice);
+ Assert(!pGlobals->pDevObj);
+ NdisZeroMemory(aMajorFunctions, sizeof (aMajorFunctions));
+ aMajorFunctions[IRP_MJ_CREATE] = vboxNetFltWinPtDevDispatch;
+ aMajorFunctions[IRP_MJ_CLEANUP] = vboxNetFltWinPtDevDispatch;
+ aMajorFunctions[IRP_MJ_CLOSE] = vboxNetFltWinPtDevDispatch;
+ aMajorFunctions[IRP_MJ_DEVICE_CONTROL] = vboxNetFltWinPtDevDispatch;
+
+ NDIS_STATUS Status = NdisMRegisterDevice(pGlobals->Mp.hNdisWrapper,
+ &DevName, &LinkName,
+ aMajorFunctions,
+ &pGlobals->pDevObj,
+ &pGlobals->hDevice);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ return Status;
+}
+
+static NDIS_STATUS vboxNetFltWinDevDestroy(PVBOXNETFLTGLOBALS_WIN pGlobals)
+{
+ Assert(pGlobals->hDevice);
+ Assert(pGlobals->pDevObj);
+ NDIS_STATUS Status = NdisMDeregisterDevice(pGlobals->hDevice);
+ Assert(Status == NDIS_STATUS_SUCCESS);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ pGlobals->hDevice = NULL;
+ pGlobals->pDevObj = NULL;
+ }
+ return Status;
+}
+
+static NDIS_STATUS vboxNetFltWinDevCreateReference(PVBOXNETFLTGLOBALS_WIN pGlobals)
+{
+ Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
+ NDIS_STATUS Status = KeWaitForSingleObject(&pGlobals->SynchEvent, Executive, KernelMode, FALSE, NULL);
+ Assert(Status == STATUS_SUCCESS);
+ if (Status == STATUS_SUCCESS)
+ {
+ Assert(pGlobals->cDeviceRefs >= 0);
+ if (++pGlobals->cDeviceRefs == 1)
+ {
+ Status = vboxNetFltWinDevCreate(pGlobals);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ ObReferenceObject(pGlobals->pDevObj);
+ }
+ }
+ else
+ {
+ Status = NDIS_STATUS_SUCCESS;
+ }
+ KeSetEvent(&pGlobals->SynchEvent, 0, FALSE);
+ }
+ else
+ {
+ /* should never happen actually */
+ Assert(0);
+ Status = NDIS_STATUS_FAILURE;
+ }
+ return Status;
+}
+
+static NDIS_STATUS vboxNetFltWinDevDereference(PVBOXNETFLTGLOBALS_WIN pGlobals)
+{
+ Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
+ NDIS_STATUS Status = KeWaitForSingleObject(&pGlobals->SynchEvent, Executive, KernelMode, FALSE, NULL);
+ Assert(Status == STATUS_SUCCESS);
+ if (Status == STATUS_SUCCESS)
+ {
+ Assert(pGlobals->cDeviceRefs > 0);
+ if (!(--pGlobals->cDeviceRefs))
+ {
+ ObDereferenceObject(pGlobals->pDevObj);
+ Status = vboxNetFltWinDevDestroy(pGlobals);
+ }
+ else
+ {
+ Status = NDIS_STATUS_SUCCESS;
+ }
+ KeSetEvent(&pGlobals->SynchEvent, 0, FALSE);
+ }
+ else
+ {
+ /* should never happen actually */
+ Assert(0);
+ Status = NDIS_STATUS_FAILURE;
+ }
+ return Status;
+}
+
+/* reference the driver module to prevent driver unload */
+DECLHIDDEN(void) vboxNetFltWinDrvReference()
+{
+ vboxNetFltWinDevCreateReference(&g_VBoxNetFltGlobalsWin);
+}
+
+/* dereference the driver module to prevent driver unload */
+DECLHIDDEN(void) vboxNetFltWinDrvDereference()
+{
+ vboxNetFltWinDevDereference(&g_VBoxNetFltGlobalsWin);
+}
/*
*
@@ -3447,18 +3055,17 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, ui
{
int rc = VINF_SUCCESS;
uint32_t cRefs = 0;
- PADAPT pAdapt;
-#if !defined(VBOXNETADP) && !defined(VBOX_NETFLT_ONDEMAND_BIND)
- if(fDst & INTNETTRUNKDIR_WIRE)
+#ifndef VBOXNETADP
+ if (fDst & INTNETTRUNKDIR_WIRE)
{
cRefs++;
}
- if(fDst & INTNETTRUNKDIR_HOST)
+ if (fDst & INTNETTRUNKDIR_HOST)
{
cRefs++;
}
#else
- if(fDst & INTNETTRUNKDIR_WIRE || fDst & INTNETTRUNKDIR_HOST)
+ if (fDst & INTNETTRUNKDIR_WIRE || fDst & INTNETTRUNKDIR_HOST)
{
cRefs = 1;
}
@@ -3466,22 +3073,16 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, ui
AssertReturn(cRefs, VINF_SUCCESS);
- pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
-
- if(!vboxNetFltWinIncReferenceAdapt(pAdapt, cRefs))
+ if (!vboxNetFltWinIncReferenceWinIf(pThis, cRefs))
{
return VERR_GENERAL_FAILURE;
}
#ifndef VBOXNETADP
- if ((fDst & INTNETTRUNKDIR_WIRE)
-# ifdef VBOX_NETFLT_ONDEMAND_BIND
- || (fDst & INTNETTRUNKDIR_HOST)
-# endif
- )
+ if (fDst & INTNETTRUNKDIR_WIRE)
{
PNDIS_PACKET pPacket;
- pPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, pSG, NULL /*pBufToFree*/,
+ pPacket = vboxNetFltWinNdisPacketFromSG(pThis, pSG, NULL /*pBufToFree*/,
true /*fToWire*/, true /*fCopyMemory*/);
if (pPacket)
@@ -3491,23 +3092,23 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, ui
#ifndef VBOX_LOOPBACK_USEFLAGS
/* force "don't loopback" flags to prevent loopback branch invocation in any case
* to avoid ndis misbehave */
- NdisGetPacketFlags(pPacket) |= g_fPacketDontLoopBack;
+ NdisGetPacketFlags(pPacket) |= g_VBoxNetFltGlobalsWin.fPacketDontLoopBack;
#else
/* this is done by default in vboxNetFltWinNdisPacketFromSG */
#endif
#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
- vboxNetFltWinLbPutSendPacket(pAdapt, pPacket, true /* bFromIntNet */);
+ vboxNetFltWinLbPutSendPacket(pThis, pPacket, true /* bFromIntNet */);
#endif
- NdisSend(&fStatus, pAdapt->hBindingHandle, pPacket);
+ NdisSend(&fStatus, pThis->u.s.WinIf.hBinding, pPacket);
if (fStatus != NDIS_STATUS_PENDING)
{
#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
/* the status is NOT pending, complete the packet */
- bool bTmp = vboxNetFltWinLbRemoveSendPacket(pAdapt, pPacket);
+ bool bTmp = vboxNetFltWinLbRemoveSendPacket(pThis, pPacket);
Assert(bTmp);
#endif
- if(!NT_SUCCESS(fStatus))
+ if (!NT_SUCCESS(fStatus))
{
/* TODO: convert status to VERR_xxx */
rc = VERR_GENERAL_FAILURE;
@@ -3528,33 +3129,28 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, ui
}
}
#endif
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
+
#ifndef VBOXNETADP
if (fDst & INTNETTRUNKDIR_HOST)
#else
- if(cRefs)
+ if (cRefs)
#endif
{
- PNDIS_PACKET pPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, pSG, NULL /*pBufToFree*/,
+ PNDIS_PACKET pPacket = vboxNetFltWinNdisPacketFromSG(pThis, pSG, NULL /*pBufToFree*/,
false /*fToWire*/, true /*fCopyMemory*/);
if (pPacket)
{
-#ifdef VBOXNETADP
- NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, &pPacket, 1);
-#else
- /* flush any packets currently queued */
- vboxNetFltWinPtQueueReceivedPacket(pAdapt, pPacket, TRUE /* BOOLEAN DoIndicate */);
-#endif
+ NdisMIndicateReceivePacket(pThis->u.s.WinIf.hMiniport, &pPacket, 1);
cRefs--;
#ifdef VBOXNETADP
- STATISTIC_INCREASE(pAdapt->cRxSuccess);
+ STATISTIC_INCREASE(pThis->u.s.WinIf.cRxSuccess);
#endif
}
else
{
AssertFailed();
#ifdef VBOXNETADP
- STATISTIC_INCREASE(pAdapt->cRxError);
+ STATISTIC_INCREASE(pThis->u.s.WinIf.cRxError);
#endif
rc = VERR_NO_MEMORY;
}
@@ -3562,11 +3158,10 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, ui
Assert(cRefs <= 2);
- if(cRefs)
+ if (cRefs)
{
- vboxNetFltWinDecReferenceAdapt(pAdapt, cRefs);
+ vboxNetFltWinDecReferenceWinIf(pThis, cRefs);
}
-#endif
return rc;
}
@@ -3576,22 +3171,20 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
#ifndef VBOXNETADP
NDIS_STATUS Status;
#endif
- PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
-
/* we first wait for all pending ops to complete
* this might include all packets queued for processing */
- for(;;)
+ for (;;)
{
- if(fActive)
+ if (fActive)
{
- if(!pThis->u.s.cModePassThruRefs)
+ if (!pThis->u.s.cModePassThruRefs)
{
break;
}
}
else
{
- if(!pThis->u.s.cModeNetFltRefs)
+ if (!pThis->u.s.cModeNetFltRefs)
{
break;
}
@@ -3599,27 +3192,23 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
vboxNetFltWinSleep(2);
}
- if(!vboxNetFltWinReferenceAdapt(pAdapt))
+ if (!vboxNetFltWinReferenceWinIf(pThis))
return;
#ifndef VBOXNETADP
- /* the packets put to ReceiveQueue Array are currently not holding the references,
- * simply need to flush them */
- vboxNetFltWinPtFlushReceiveQueue(pAdapt, false /*fReturn*/);
-
- if(fActive)
+ if (fActive)
{
#ifdef DEBUG_misha
- NDIS_PHYSICAL_MEDIUM PhMedium;
+ NDIS_PHYSICAL_MEDIUM PhMedium;
bool bPromiscSupported;
- Status = vboxNetFltWinQueryPhysicalMedium(pAdapt, &PhMedium);
- if(Status != NDIS_STATUS_SUCCESS)
+ Status = vboxNetFltWinQueryPhysicalMedium(pThis, &PhMedium);
+ if (Status != NDIS_STATUS_SUCCESS)
{
- DBGPRINT(("vboxNetFltWinQueryPhysicalMedium failed, Status (0x%x), setting medium to NdisPhysicalMediumUnspecified\n", Status));
+ LogRel(("vboxNetFltWinQueryPhysicalMedium failed, Status (0x%x), setting medium to NdisPhysicalMediumUnspecified\n", Status));
Assert(Status == NDIS_STATUS_NOT_SUPPORTED);
- if(Status != NDIS_STATUS_NOT_SUPPORTED)
+ if (Status != NDIS_STATUS_NOT_SUPPORTED)
{
LogRel(("vboxNetFltWinQueryPhysicalMedium failed, Status (0x%x), setting medium to NdisPhysicalMediumUnspecified\n", Status));
}
@@ -3627,63 +3216,62 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
}
else
{
- DBGPRINT(("(SUCCESS) vboxNetFltWinQueryPhysicalMedium SUCCESS\n"));
+ LogRel(("(SUCCESS) vboxNetFltWinQueryPhysicalMedium SUCCESS\n"));
}
- bPromiscSupported = (!(PhMedium == NdisPhysicalMediumWirelessWan
+ bPromiscSupported = (!(PhMedium == NdisPhysicalMediumWirelessWan
|| PhMedium == NdisPhysicalMediumWirelessLan
|| PhMedium == NdisPhysicalMediumNative802_11
|| PhMedium == NdisPhysicalMediumBluetooth
/*|| PhMedium == NdisPhysicalMediumWiMax */
));
- Assert(bPromiscSupported == VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt));
+ Assert(bPromiscSupported == VBOXNETFLT_PROMISCUOUS_SUPPORTED(pThis));
#endif
}
- if(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
+ if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pThis))
{
- Status = vboxNetFltWinSetPromiscuous(pAdapt, fActive);
- if(Status != NDIS_STATUS_SUCCESS)
+ Status = vboxNetFltWinSetPromiscuous(pThis, fActive);
+ if (Status != NDIS_STATUS_SUCCESS)
{
- DBGPRINT(("vboxNetFltWinSetPromiscuous failed, Status (0x%x), fActive (%d)\n", Status, fActive));
- AssertFailed();
LogRel(("vboxNetFltWinSetPromiscuous failed, Status (0x%x), fActive (%d)\n", Status, fActive));
+ AssertFailed();
}
}
#else
# ifdef VBOXNETADP_REPORT_DISCONNECTED
- if(fActive)
+ if (fActive)
{
- NdisMIndicateStatus(pAdapt->hMiniportHandle,
+ NdisMIndicateStatus(pThis->u.s.WinIf.hMiniport,
NDIS_STATUS_MEDIA_CONNECT,
(PVOID)NULL,
0);
}
else
{
- NdisMIndicateStatus(pAdapt->hMiniportHandle,
+ NdisMIndicateStatus(pThis->u.s.WinIf.hMiniport,
NDIS_STATUS_MEDIA_DISCONNECT,
(PVOID)NULL,
0);
}
#else
- if(fActive)
+ if (fActive)
{
/* indicate status change to make the ip settings be re-picked for dhcp */
- NdisMIndicateStatus(pAdapt->hMiniportHandle,
+ NdisMIndicateStatus(pThis->u.s.WinIf.hMiniport,
NDIS_STATUS_MEDIA_DISCONNECT,
(PVOID)NULL,
0);
- NdisMIndicateStatus(pAdapt->hMiniportHandle,
+ NdisMIndicateStatus(pThis->u.s.WinIf.hMiniport,
NDIS_STATUS_MEDIA_CONNECT,
(PVOID)NULL,
0);
}
# endif
#endif
- vboxNetFltWinDereferenceAdapt(pAdapt);
+ vboxNetFltWinDereferenceWinIf(pThis);
return;
}
@@ -3694,21 +3282,21 @@ int vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis)
return Status == NDIS_STATUS_SUCCESS ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
}
-static void vboxNetFltWinConnectItWorker(PWORKER_INFO pInfo)
+static void vboxNetFltWinConnectItWorker(PVOID pvContext)
{
+ PWORKER_INFO pInfo = (PWORKER_INFO)pvContext;
#if !defined(VBOXNETADP) || !defined(VBOXNETFLT_NO_PACKET_QUEUE)
NDIS_STATUS Status;
#endif
PVBOXNETFLTINS pInstance = pInfo->pNetFltIf;
- PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pInstance);
Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
/* this is not a rediscovery, initialize Mac cache */
- if(vboxNetFltWinReferenceAdapt(pAdapt))
+ if (vboxNetFltWinReferenceWinIf(pInstance))
{
#ifndef VBOXNETADP
- Status = vboxNetFltWinGetMacAddress(pAdapt, &pInstance->u.s.MacAddr);
+ Status = vboxNetFltWinGetMacAddress(pInstance, &pInstance->u.s.MacAddr);
if (Status == NDIS_STATUS_SUCCESS)
#endif
{
@@ -3716,7 +3304,7 @@ static void vboxNetFltWinConnectItWorker(PWORKER_INFO pInfo)
pInfo->Status = VINF_SUCCESS;
#else
Status = vboxNetFltWinQuInitPacketQueue(pInstance);
- if(Status == NDIS_STATUS_SUCCESS)
+ if (Status == NDIS_STATUS_SUCCESS)
{
pInfo->Status = VINF_SUCCESS;
}
@@ -3733,7 +3321,7 @@ static void vboxNetFltWinConnectItWorker(PWORKER_INFO pInfo)
}
#endif
- vboxNetFltWinDereferenceAdapt(pAdapt);
+ vboxNetFltWinDereferenceWinIf(pInstance);
}
else
{
@@ -3766,7 +3354,7 @@ void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)
int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
{
- int rc = RTSemMutexCreate(&pThis->u.s.hAdaptMutex);
+ int rc = RTSemMutexCreate(&pThis->u.s.hWinIfMutex);
if (RT_SUCCESS(rc))
{
rc = vboxNetFltWinAttachToInterface(pThis, pvContext, false /*fRediscovery*/ );
@@ -3774,20 +3362,19 @@ int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
{
return rc;
}
- RTSemMutexDestroy(pThis->u.s.hAdaptMutex);
+ RTSemMutexDestroy(pThis->u.s.hWinIfMutex);
}
return rc;
}
int vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)
{
- PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
pThis->u.s.cModeNetFltRefs = 0;
pThis->u.s.cModePassThruRefs = 0;
- vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Disconnected);
- vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetWinIfState(pThis, kVBoxWinIfState_Disconnected);
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
#ifndef VBOXNETADP
- vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
+ vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
#endif
return VINF_SUCCESS;
}
@@ -3807,4 +3394,3 @@ int vboxNetFltPortOsDisconnectInterface(PVBOXNETFLTINS pThis, void *pvIfData)
/* Nothing to do */
return VINF_SUCCESS;
}
-
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.h
index 541c04033..9ef0d2588 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.h
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFlt-win.h $ */
+/* $Id: VBoxNetFltRt-win.h 36184 2011-03-07 10:57:04Z vboxsync $ */
/** @file
- * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Integration with IntNet/NetFlt
+ * VBoxNetFltRt-win.h - Bridged Networking Driver, Windows Specific Code.
+ * NetFlt Runtime API
*/
-
/*
- * Copyright (C) 2008 Oracle Corporation
+ * 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;
@@ -14,44 +14,8 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-/*
- * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
- * Copyright (c) 1993-1999, Microsoft Corporation
- */
-
-#ifndef ___VBoxNetFlt_win_h___
-#define ___VBoxNetFlt_win_h___
-
-/*
- * globals
- */
-
-/** global lock */
-extern NDIS_SPIN_LOCK g_GlobalLock;
-
-extern UINT g_fPacketDontLoopBack;
-extern UINT g_fPacketIsLoopedBack;
-
-/*
- * Debug Print API
- */
-#ifdef DEBUG
-
-#define DBGPRINT(Fmt) DbgPrint Fmt
-
-#else /* if DBG */
-
-#define DBGPRINT(Fmt)
-
-#endif /* if DBG */
-
-/** get the PVBOXNETFLTINS from PADAPT */
-#define PADAPT_2_PVBOXNETFLTINS(_pAdapt) ( (PVBOXNETFLTINS)((uint8_t *)(_pAdapt) - RT_OFFSETOF(VBOXNETFLTINS, u.s.IfAdaptor)) )
-/** get the PADAPT from PVBOXNETFLTINS */
-#define PVBOXNETFLTINS_2_PADAPT(_pNetFlt) ( &(_pNetFlt)->u.s.IfAdaptor )
-
-
-DECLHIDDEN(NTSTATUS) vboxNetFltWinPtDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp);
+#ifndef ___VBoxNetFltRt_win_h___
+#define ___VBoxNetFltRt_win_h___
DECLHIDDEN(VOID) vboxNetFltWinUnload(IN PDRIVER_OBJECT DriverObject);
#ifndef VBOXNETADP
@@ -67,26 +31,26 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p
#define LIST_ENTRY_2_PACKET_INFO(pListEntry) \
- ( (PPACKET_INFO)((uint8_t *)(pListEntry) - RT_OFFSETOF(PACKET_INFO, ListEntry)) )
+ ( (PVBOXNETFLT_PACKET_INFO)((uint8_t *)(pListEntry) - RT_OFFSETOF(VBOXNETFLT_PACKET_INFO, ListEntry)) )
#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
-#define VBOX_SLE_2_SEND_RSVD(_pEntry) \
- ( (PSEND_RSVD)((uint8_t *)(_pEntry) - RT_OFFSETOF(SEND_RSVD, ListEntry)) )
+#define VBOX_SLE_2_PKTRSVD_PT(_pEntry) \
+ ( (PVBOXNETFLT_PKTRSVD_PT)((uint8_t *)(_pEntry) - RT_OFFSETOF(VBOXNETFLT_PKTRSVD_PT, ListEntry)) )
#define VBOX_SLE_2_SENDPACKET(_pEntry) \
- ( (PNDIS_PACKET)((uint8_t *)(VBOX_SLE_2_SEND_RSVD(_pEntry)) - RT_OFFSETOF(NDIS_PACKET, ProtocolReserved)) )
+ ( (PNDIS_PACKET)((uint8_t *)(VBOX_SLE_2_PKTRSVD_PT(_pEntry)) - RT_OFFSETOF(NDIS_PACKET, ProtocolReserved)) )
#endif
/**
* enqueus the packet info to the tail of the queue
*/
-DECLINLINE(void) vboxNetFltWinQuEnqueueTail(PPACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo)
+DECLINLINE(void) vboxNetFltWinQuEnqueueTail(PVBOXNETFLT_PACKET_QUEUE pQueue, PVBOXNETFLT_PACKET_INFO pPacketInfo)
{
InsertTailList(pQueue, &pPacketInfo->ListEntry);
}
-DECLINLINE(void) vboxNetFltWinQuEnqueueHead(PPACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo)
+DECLINLINE(void) vboxNetFltWinQuEnqueueHead(PVBOXNETFLT_PACKET_QUEUE pQueue, PVBOXNETFLT_PACKET_INFO pPacketInfo)
{
Assert(pPacketInfo->pPool);
InsertHeadList(pQueue, &pPacketInfo->ListEntry);
@@ -95,7 +59,7 @@ DECLINLINE(void) vboxNetFltWinQuEnqueueHead(PPACKET_QUEUE pQueue, PPACKET_INFO p
/**
* enqueus the packet info to the tail of the queue
*/
-DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueTail(PINTERLOCKED_PACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo)
+DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueTail(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pQueue, PVBOXNETFLT_PACKET_INFO pPacketInfo)
{
Assert(pPacketInfo->pPool);
NdisAcquireSpinLock(&pQueue->Lock);
@@ -103,7 +67,7 @@ DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueTail(PINTERLOCKED_PACKET_QUEUE
NdisReleaseSpinLock(&pQueue->Lock);
}
-DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueHead(PINTERLOCKED_PACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo)
+DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueHead(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pQueue, PVBOXNETFLT_PACKET_INFO pPacketInfo)
{
NdisAcquireSpinLock(&pQueue->Lock);
vboxNetFltWinQuEnqueueHead(&pQueue->Queue, pPacketInfo);
@@ -113,54 +77,54 @@ DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueHead(PINTERLOCKED_PACKET_QUEUE
/**
* dequeus the packet info from the head of the queue
*/
-DECLINLINE(PPACKET_INFO) vboxNetFltWinQuDequeueHead(PPACKET_QUEUE pQueue)
+DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinQuDequeueHead(PVBOXNETFLT_PACKET_QUEUE pQueue)
{
PLIST_ENTRY pListEntry = RemoveHeadList(pQueue);
if(pListEntry != pQueue)
{
- PPACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry);
+ PVBOXNETFLT_PACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry);
Assert(pInfo->pPool);
return pInfo;
}
return NULL;
}
-DECLINLINE(PPACKET_INFO) vboxNetFltWinQuDequeueTail(PPACKET_QUEUE pQueue)
+DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinQuDequeueTail(PVBOXNETFLT_PACKET_QUEUE pQueue)
{
PLIST_ENTRY pListEntry = RemoveTailList(pQueue);
if(pListEntry != pQueue)
{
- PPACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry);
+ PVBOXNETFLT_PACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry);
Assert(pInfo->pPool);
return pInfo;
}
return NULL;
}
-DECLINLINE(PPACKET_INFO) vboxNetFltWinQuInterlockedDequeueHead(PINTERLOCKED_PACKET_QUEUE pInterlockedQueue)
+DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinQuInterlockedDequeueHead(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pInterlockedQueue)
{
- PPACKET_INFO pInfo;
+ PVBOXNETFLT_PACKET_INFO pInfo;
NdisAcquireSpinLock(&pInterlockedQueue->Lock);
pInfo = vboxNetFltWinQuDequeueHead(&pInterlockedQueue->Queue);
NdisReleaseSpinLock(&pInterlockedQueue->Lock);
return pInfo;
}
-DECLINLINE(PPACKET_INFO) vboxNetFltWinQuInterlockedDequeueTail(PINTERLOCKED_PACKET_QUEUE pInterlockedQueue)
+DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinQuInterlockedDequeueTail(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pInterlockedQueue)
{
- PPACKET_INFO pInfo;
+ PVBOXNETFLT_PACKET_INFO pInfo;
NdisAcquireSpinLock(&pInterlockedQueue->Lock);
pInfo = vboxNetFltWinQuDequeueTail(&pInterlockedQueue->Queue);
NdisReleaseSpinLock(&pInterlockedQueue->Lock);
return pInfo;
}
-DECLINLINE(void) vboxNetFltWinQuDequeue(PPACKET_INFO pInfo)
+DECLINLINE(void) vboxNetFltWinQuDequeue(PVBOXNETFLT_PACKET_INFO pInfo)
{
RemoveEntryList(&pInfo->ListEntry);
}
-DECLINLINE(void) vboxNetFltWinQuInterlockedDequeue(PINTERLOCKED_PACKET_QUEUE pInterlockedQueue, PPACKET_INFO pInfo)
+DECLINLINE(void) vboxNetFltWinQuInterlockedDequeue(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pInterlockedQueue, PVBOXNETFLT_PACKET_INFO pInfo)
{
NdisAcquireSpinLock(&pInterlockedQueue->Lock);
vboxNetFltWinQuDequeue(pInfo);
@@ -170,7 +134,7 @@ DECLINLINE(void) vboxNetFltWinQuInterlockedDequeue(PINTERLOCKED_PACKET_QUEUE pIn
/**
* allocates the packet info from the pool
*/
-DECLINLINE(PPACKET_INFO) vboxNetFltWinPpAllocPacketInfo(PPACKET_INFO_POOL pPool)
+DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinPpAllocPacketInfo(PVBOXNETFLT_PACKET_INFO_POOL pPool)
{
return vboxNetFltWinQuInterlockedDequeueHead(&pPool->Queue);
}
@@ -178,9 +142,9 @@ DECLINLINE(PPACKET_INFO) vboxNetFltWinPpAllocPacketInfo(PPACKET_INFO_POOL pPool)
/**
* returns the packet info to the pool
*/
-DECLINLINE(void) vboxNetFltWinPpFreePacketInfo(PPACKET_INFO pInfo)
+DECLINLINE(void) vboxNetFltWinPpFreePacketInfo(PVBOXNETFLT_PACKET_INFO pInfo)
{
- PPACKET_INFO_POOL pPool = pInfo->pPool;
+ PVBOXNETFLT_PACKET_INFO_POOL pPool = pInfo->pPool;
vboxNetFltWinQuInterlockedEnqueueHead(&pPool->Queue, pInfo);
}
@@ -213,13 +177,8 @@ DECLINLINE(void) vboxNetFltWinPpFreePacketInfo(PPACKET_INFO pInfo)
DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pInstance, PVOID pvPacket, const UINT fFlags);
#else
DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, PVOID pPacket, const UINT fPacketFlags);
-
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
DECLHIDDEN(void) vboxNetFltWinQuFiniPacketQueue(PVBOXNETFLTINS pInstance);
-
DECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance);
-#endif
-
#endif /* #ifndef VBOXNETFLT_NO_PACKET_QUEUE */
@@ -227,7 +186,7 @@ DECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance);
/**
* searches the list entry in a single-linked list
*/
-DECLINLINE(bool) vboxNetFltWinSearchListEntry(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove)
+DECLINLINE(bool) vboxNetFltWinSearchListEntry(PVBOXNETFLT_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove)
{
PSINGLE_LIST_ENTRY pHead = &pList->Head;
PSINGLE_LIST_ENTRY pCur;
@@ -252,7 +211,7 @@ DECLINLINE(bool) vboxNetFltWinSearchListEntry(PSINGLE_LIST pList, PSINGLE_LIST_E
#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
-DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacket(PSINGLE_LIST pList, PNDIS_PACKET pPacket2Search, int cbMatch, bool bRemove)
+DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacket(PVBOXNETFLT_SINGLE_LIST pList, PNDIS_PACKET pPacket2Search, int cbMatch, bool bRemove)
{
PSINGLE_LIST_ENTRY pHead = &pList->Head;
PSINGLE_LIST_ENTRY pCur;
@@ -277,7 +236,7 @@ DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacket(PSINGLE_LIST pList, PNDIS_PAC
return NULL;
}
-DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacketBySG(PSINGLE_LIST pList, PINTNETSG pSG, int cbMatch, bool bRemove)
+DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacketBySG(PVBOXNETFLT_SINGLE_LIST pList, PINTNETSG pSG, int cbMatch, bool bRemove)
{
PSINGLE_LIST_ENTRY pHead = &pList->Head;
PSINGLE_LIST_ENTRY pCur;
@@ -304,19 +263,19 @@ DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacketBySG(PSINGLE_LIST pList, PINTN
#endif /* #if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) */
-DECLINLINE(bool) vboxNetFltWinSListIsEmpty(PSINGLE_LIST pList)
+DECLINLINE(bool) vboxNetFltWinSListIsEmpty(PVBOXNETFLT_SINGLE_LIST pList)
{
return !pList->Head.Next;
}
-DECLINLINE(void) vboxNetFltWinPutTail(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
+DECLINLINE(void) vboxNetFltWinPutTail(PVBOXNETFLT_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
{
pList->pTail->Next = pEntry;
pList->pTail = pEntry;
pEntry->Next = NULL;
}
-DECLINLINE(void) vboxNetFltWinPutHead(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
+DECLINLINE(void) vboxNetFltWinPutHead(PVBOXNETFLT_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
{
pEntry->Next = pList->Head.Next;
pList->Head.Next = pEntry;
@@ -324,7 +283,7 @@ DECLINLINE(void) vboxNetFltWinPutHead(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEn
pList->pTail = pEntry;
}
-DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinGetHead(PSINGLE_LIST pList)
+DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinGetHead(PVBOXNETFLT_SINGLE_LIST pList)
{
PSINGLE_LIST_ENTRY pEntry = pList->Head.Next;
if(pEntry && pEntry == pList->pTail)
@@ -335,7 +294,7 @@ DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinGetHead(PSINGLE_LIST pList)
return pEntry;
}
-DECLINLINE(bool) vboxNetFltWinInterlockedSearchListEntry(PINTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove)
+DECLINLINE(bool) vboxNetFltWinInterlockedSearchListEntry(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove)
{
bool bFound;
NdisAcquireSpinLock(&pList->Lock);
@@ -346,7 +305,7 @@ DECLINLINE(bool) vboxNetFltWinInterlockedSearchListEntry(PINTERLOCKED_SINGLE_LIS
#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
-DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacket(PINTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket2Search, int cbMatch, bool bRemove)
+DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacket(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket2Search, int cbMatch, bool bRemove)
{
PNDIS_PACKET pFound;
NdisAcquireSpinLock(&pList->Lock);
@@ -355,7 +314,7 @@ DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacket(PINTERLOCKED_SINGL
return pFound;
}
-DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacketBySG(PINTERLOCKED_SINGLE_LIST pList, PINTNETSG pSG, int cbMatch, bool bRemove)
+DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacketBySG(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PINTNETSG pSG, int cbMatch, bool bRemove)
{
PNDIS_PACKET pFound;
NdisAcquireSpinLock(&pList->Lock);
@@ -365,21 +324,21 @@ DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacketBySG(PINTERLOCKED_S
}
#endif /* #if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) */
-DECLINLINE(void) vboxNetFltWinInterlockedPutTail(PINTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
+DECLINLINE(void) vboxNetFltWinInterlockedPutTail(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
{
NdisAcquireSpinLock(&pList->Lock);
vboxNetFltWinPutTail(&pList->List, pEntry);
NdisReleaseSpinLock(&pList->Lock);
}
-DECLINLINE(void) vboxNetFltWinInterlockedPutHead(PINTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
+DECLINLINE(void) vboxNetFltWinInterlockedPutHead(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
{
NdisAcquireSpinLock(&pList->Lock);
vboxNetFltWinPutHead(&pList->List, pEntry);
NdisReleaseSpinLock(&pList->Lock);
}
-DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinInterlockedGetHead(PINTERLOCKED_SINGLE_LIST pList)
+DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinInterlockedGetHead(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList)
{
PSINGLE_LIST_ENTRY pEntry;
NdisAcquireSpinLock(&pList->Lock);
@@ -389,35 +348,34 @@ DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinInterlockedGetHead(PINTERLOCKED_SING
}
# if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
-DECLINLINE(void) vboxNetFltWinLbPutSendPacket(PADAPT pAdapt, PNDIS_PACKET pPacket, bool bFromIntNet)
+DECLINLINE(void) vboxNetFltWinLbPutSendPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, bool bFromIntNet)
{
- PSEND_RSVD pSrv = (PSEND_RSVD)pPacket->ProtocolReserved;
+ PVBOXNETFLT_PKTRSVD_PT pSrv = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved;
pSrv->bFromIntNet = bFromIntNet;
- vboxNetFltWinInterlockedPutHead(&pAdapt->SendPacketQueue, &pSrv->ListEntry);
+ vboxNetFltWinInterlockedPutHead(&pNetFlt->u.s.WinIf.SendPacketQueue, &pSrv->ListEntry);
}
DECLINLINE(bool) vboxNetFltWinLbIsFromIntNet(PNDIS_PACKET pPacket)
{
- PSEND_RSVD pSrv = (PSEND_RSVD)pPacket->ProtocolReserved;
+ PVBOXNETFLT_PKTRSVD_PT pSrv = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved;
return pSrv->bFromIntNet;
}
-DECLINLINE(PNDIS_PACKET) vboxNetFltWinLbSearchLoopBack(PADAPT pAdapt, PNDIS_PACKET pPacket, bool bRemove)
+DECLINLINE(PNDIS_PACKET) vboxNetFltWinLbSearchLoopBack(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, bool bRemove)
{
- return vboxNetFltWinInterlockedSearchPacket(&pAdapt->SendPacketQueue, pPacket, VBOXNETFLT_PACKETMATCH_LENGTH, bRemove);
+ return vboxNetFltWinInterlockedSearchPacket(&pNetFlt->u.s.WinIf.SendPacketQueue, pPacket, VBOXNETFLT_PACKETMATCH_LENGTH, bRemove);
}
-DECLINLINE(PNDIS_PACKET) vboxNetFltWinLbSearchLoopBackBySG(PADAPT pAdapt, PINTNETSG pSG, bool bRemove)
+DECLINLINE(PNDIS_PACKET) vboxNetFltWinLbSearchLoopBackBySG(PVBOXNETFLTINS pNetFlt, PINTNETSG pSG, bool bRemove)
{
- return vboxNetFltWinInterlockedSearchPacketBySG(&pAdapt->SendPacketQueue, pSG, VBOXNETFLT_PACKETMATCH_LENGTH, bRemove);
+ return vboxNetFltWinInterlockedSearchPacketBySG(&pNetFlt->u.s.WinIf.SendPacketQueue, pSG, VBOXNETFLT_PACKETMATCH_LENGTH, bRemove);
}
-DECLINLINE(bool) vboxNetFltWinLbRemoveSendPacket(PADAPT pAdapt, PNDIS_PACKET pPacket)
+DECLINLINE(bool) vboxNetFltWinLbRemoveSendPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket)
{
- PSEND_RSVD pSrv = (PSEND_RSVD)pPacket->ProtocolReserved;
- bool bRet = vboxNetFltWinInterlockedSearchListEntry(&pAdapt->SendPacketQueue, &pSrv->ListEntry, true);
+ PVBOXNETFLT_PKTRSVD_PT pSrv = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved;
+ bool bRet = vboxNetFltWinInterlockedSearchListEntry(&pNetFlt->u.s.WinIf.SendPacketQueue, &pSrv->ListEntry, true);
#ifdef DEBUG_misha
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
Assert(bRet == (pNetFlt->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE));
#endif
return bRet;
@@ -472,19 +430,12 @@ extern RTMAC g_vboxNetFltWinVerifyMACGuest;
} while(0)
-/** obtains the PTRANSFERDATA_RSVD given a single list entry it contains */
-//#define PT_SLE_2_TRANSFERDATA_RSVD(_pl) \
-// ( (PTRANSFERDATA_RSVD)((uint8_t *)(_pl) - RT_OFFSETOF(TRANSFERDATA_RSVD, ListEntry)))
-
-///** obtains the ndis packet given a single list entry assuming it is stored in ProtocolReserved field of the packet */
-//#define PT_SLE_2_NDIS_PACKET(_pl) \
-// ( (PNDIS_PACKET)((uint8_t *)PT_SLE_2_TRANSFERDATA_RSVD(_pl) - RT_OFFSETOF(NDIS_PACKET, ProtocolReserved)))
-
/**************************************************************************
- * PADAPT, PVBOXNETFLTINS reference/dereference (i.e. retain/release) API *
+ * PVBOXNETFLTINS , WinIf reference/dereference (i.e. retain/release) API *
**************************************************************************/
-DECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState);
+
+DECLHIDDEN(void) vboxNetFltWinWaitDereference(PVBOXNETFLT_WINIF_DEVICE pState);
DECLINLINE(void) vboxNetFltWinReferenceModeNetFlt(PVBOXNETFLTINS pIns)
{
@@ -528,27 +479,27 @@ DECLINLINE(void) vboxNetFltWinDecReferenceModePassThru(PVBOXNETFLTINS pIns, uint
ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs, (uint32_t)(-((int32_t)v)));
}
-DECLINLINE(void) vboxNetFltWinSetPowerState(PADAPT_DEVICE pState, NDIS_DEVICE_POWER_STATE State)
+DECLINLINE(void) vboxNetFltWinSetPowerState(PVBOXNETFLT_WINIF_DEVICE pState, NDIS_DEVICE_POWER_STATE State)
{
ASMAtomicUoWriteU32((volatile uint32_t *)&pState->PowerState, State);
}
-DECLINLINE(NDIS_DEVICE_POWER_STATE) vboxNetFltWinGetPowerState(PADAPT_DEVICE pState)
+DECLINLINE(NDIS_DEVICE_POWER_STATE) vboxNetFltWinGetPowerState(PVBOXNETFLT_WINIF_DEVICE pState)
{
return (NDIS_DEVICE_POWER_STATE)ASMAtomicUoReadU32((volatile uint32_t *)&pState->PowerState);
}
-DECLINLINE(void) vboxNetFltWinSetOpState(PADAPT_DEVICE pState, VBOXNETDEVOPSTATE State)
+DECLINLINE(void) vboxNetFltWinSetOpState(PVBOXNETFLT_WINIF_DEVICE pState, VBOXNETDEVOPSTATE State)
{
ASMAtomicUoWriteU32((volatile uint32_t *)&pState->OpState, State);
}
-DECLINLINE(VBOXNETDEVOPSTATE) vboxNetFltWinGetOpState(PADAPT_DEVICE pState)
+DECLINLINE(VBOXNETDEVOPSTATE) vboxNetFltWinGetOpState(PVBOXNETFLT_WINIF_DEVICE pState)
{
return (VBOXNETDEVOPSTATE)ASMAtomicUoReadU32((volatile uint32_t *)&pState->OpState);
}
-DECLINLINE(bool) vboxNetFltWinDoReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState)
+DECLINLINE(bool) vboxNetFltWinDoReferenceDevice(PVBOXNETFLT_WINIF_DEVICE pState)
{
if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized)
{
@@ -561,7 +512,7 @@ DECLINLINE(bool) vboxNetFltWinDoReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pSt
}
#ifndef VBOXNETADP
-DECLINLINE(bool) vboxNetFltWinDoReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2)
+DECLINLINE(bool) vboxNetFltWinDoReferenceDevices(PVBOXNETFLT_WINIF_DEVICE pState1, PVBOXNETFLT_WINIF_DEVICE pState2)
{
if (vboxNetFltWinGetPowerState(pState1) == NdisDeviceStateD0
&& vboxNetFltWinGetOpState(pState1) == kVBoxNetDevOpState_Initialized
@@ -576,40 +527,36 @@ DECLINLINE(bool) vboxNetFltWinDoReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pS
}
#endif
-DECLINLINE(void) vboxNetFltWinDereferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState)
+DECLINLINE(void) vboxNetFltWinDereferenceDevice(PVBOXNETFLT_WINIF_DEVICE pState)
{
-/* NdisAcquireSpinLock(&pAdapt->Lock); */
ASMAtomicDecU32((uint32_t volatile *)&pState->cReferences);
/** @todo r=bird: Add comment explaining why these cannot hit 0 or why
* reference are counted */
-/* NdisReleaseSpinLock(&pAdapt->Lock); */
}
#ifndef VBOXNETADP
-DECLINLINE(void) vboxNetFltWinDereferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2)
+DECLINLINE(void) vboxNetFltWinDereferenceDevices(PVBOXNETFLT_WINIF_DEVICE pState1, PVBOXNETFLT_WINIF_DEVICE pState2)
{
-/* NdisAcquireSpinLock(&pAdapt->Lock); */
ASMAtomicDecU32((uint32_t volatile *)&pState1->cReferences);
ASMAtomicDecU32((uint32_t volatile *)&pState2->cReferences);
-/* NdisReleaseSpinLock(&pAdapt->Lock); */
}
#endif
-DECLINLINE(void) vboxNetFltWinDecReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState, uint32_t v)
+DECLINLINE(void) vboxNetFltWinDecReferenceDevice(PVBOXNETFLT_WINIF_DEVICE pState, uint32_t v)
{
Assert(v);
ASMAtomicAddU32((uint32_t volatile *)&pState->cReferences, (uint32_t)(-((int32_t)v)));
}
#ifndef VBOXNETADP
-DECLINLINE(void) vboxNetFltWinDecReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2, uint32_t v)
+DECLINLINE(void) vboxNetFltWinDecReferenceDevices(PVBOXNETFLT_WINIF_DEVICE pState1, PVBOXNETFLT_WINIF_DEVICE pState2, uint32_t v)
{
ASMAtomicAddU32((uint32_t volatile *)&pState1->cReferences, (uint32_t)(-((int32_t)v)));
ASMAtomicAddU32((uint32_t volatile *)&pState2->cReferences, (uint32_t)(-((int32_t)v)));
}
#endif
-DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState, uint32_t v)
+DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevice(PVBOXNETFLT_WINIF_DEVICE pState, uint32_t v)
{
Assert(v);
if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized)
@@ -621,7 +568,7 @@ DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE
}
#ifndef VBOXNETADP
-DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2, uint32_t v)
+DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevices(PVBOXNETFLT_WINIF_DEVICE pState1, PVBOXNETFLT_WINIF_DEVICE pState2, uint32_t v)
{
if (vboxNetFltWinGetPowerState(pState1) == NdisDeviceStateD0
&& vboxNetFltWinGetOpState(pState1) == kVBoxNetDevOpState_Initialized
@@ -636,43 +583,16 @@ DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE
}
#endif
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
-DECLINLINE(PVBOXNETFLTINS) vboxNetFltWinReferenceAdaptNetFltFromAdapt(PADAPT pAdapt)
-{
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- PVBOXNETFLTINS pNetFlt;
-
- pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
-
- RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp);
- if(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE)
- {
- RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
- return NULL;
- }
-
- if(!vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->PTState))
- {
- RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
- return NULL;
- }
- vboxNetFltRetain((pNetFlt), true /* fBusy */);
-
- RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
-
- return pNetFlt;
-}
-#else
-DECLINLINE(bool) vboxNetFltWinReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PADAPT pAdapt, bool * pbNetFltActive)
+DECLINLINE(bool) vboxNetFltWinReferenceWinIfNetFlt(PVBOXNETFLTINS pNetFlt, bool * pbNetFltActive)
{
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp);
#ifndef VBOXNETADP
- if(!vboxNetFltWinDoReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState))
+ if(!vboxNetFltWinDoReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState))
#else
- if(!vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->MPState))
+ if(!vboxNetFltWinDoReferenceDevice(&pNetFlt->u.s.WinIf.MpState))
#endif
{
RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
@@ -695,50 +615,8 @@ DECLINLINE(bool) vboxNetFltWinReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PADAP
*pbNetFltActive = true;
return true;
}
-#endif
-
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
-DECLINLINE(PVBOXNETFLTINS) vboxNetFltWinIncReferenceAdaptNetFltFromAdapt(PADAPT pAdapt, uint32_t v)
-{
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- PVBOXNETFLTINS pNetFlt;
- uint32_t i;
-
- Assert(v);
- if(!v)
- {
- return NULL;
- }
-
- pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
-
- RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp);
- if(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE)
- {
- RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
- return NULL;
- }
-
- if(!vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->PTState, v))
- {
- RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
- return NULL;
- }
-
- vboxNetFltRetain((pNetFlt), true /* fBusy */);
- RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
-
- /* we have marked it as busy, so can do the res references outside the lock */
- for(i = 0; i < v-1; i++)
- {
- vboxNetFltRetain((pNetFlt), true /* fBusy */);
- }
-
- return pNetFlt;
-}
-#else
-DECLINLINE(bool) vboxNetFltWinIncReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PADAPT pAdapt, uint32_t v, bool *pbNetFltActive)
+DECLINLINE(bool) vboxNetFltWinIncReferenceWinIfNetFlt(PVBOXNETFLTINS pNetFlt, uint32_t v, bool *pbNetFltActive)
{
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
uint32_t i;
@@ -752,9 +630,9 @@ DECLINLINE(bool) vboxNetFltWinIncReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PA
RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp);
#ifndef VBOXNETADP
- if(!vboxNetFltWinDoIncReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v))
+ if(!vboxNetFltWinDoIncReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState, v))
#else
- if(!vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->MPState, v))
+ if(!vboxNetFltWinDoIncReferenceDevice(&pNetFlt->u.s.WinIf.MpState, v))
#endif
{
RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
@@ -788,8 +666,6 @@ DECLINLINE(bool) vboxNetFltWinIncReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PA
return true;
}
-#endif
-
DECLINLINE(void) vboxNetFltWinDecReferenceNetFlt(PVBOXNETFLTINS pNetFlt, uint32_t n)
{
uint32_t i;
@@ -808,31 +684,26 @@ DECLINLINE(void) vboxNetFltWinDereferenceNetFlt(PVBOXNETFLTINS pNetFlt)
vboxNetFltWinDereferenceModeNetFlt(pNetFlt);
}
-DECLINLINE(void) vboxNetFltWinDecReferenceAdapt(PADAPT pAdapt, uint32_t v)
+DECLINLINE(void) vboxNetFltWinDecReferenceWinIf(PVBOXNETFLTINS pNetFlt, uint32_t v)
{
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- vboxNetFltWinDecReferenceDevice(pAdapt, &pAdapt->PTState, v);
-#elif defined(VBOXNETADP)
- vboxNetFltWinDecReferenceDevice(pAdapt, &pAdapt->MPState, v);
+#ifdef VBOXNETADP
+ vboxNetFltWinDecReferenceDevice(&pNetFlt->u.s.WinIf.MpState, v);
#else
- vboxNetFltWinDecReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v);
+ vboxNetFltWinDecReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState, v);
#endif
}
-DECLINLINE(void) vboxNetFltWinDereferenceAdapt(PADAPT pAdapt)
+DECLINLINE(void) vboxNetFltWinDereferenceWinIf(PVBOXNETFLTINS pNetFlt)
{
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- vboxNetFltWinDereferenceDevice(pAdapt, &pAdapt->PTState);
-#elif defined(VBOXNETADP)
- vboxNetFltWinDereferenceDevice(pAdapt, &pAdapt->MPState);
+#ifdef VBOXNETADP
+ vboxNetFltWinDereferenceDevice(&pNetFlt->u.s.WinIf.MpState);
#else
- vboxNetFltWinDereferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState);
+ vboxNetFltWinDereferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState);
#endif
}
-DECLINLINE(bool) vboxNetFltWinIncReferenceAdapt(PADAPT pAdapt, uint32_t v)
+DECLINLINE(bool) vboxNetFltWinIncReferenceWinIf(PVBOXNETFLTINS pNetFlt, uint32_t v)
{
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
Assert(v);
@@ -842,12 +713,10 @@ DECLINLINE(bool) vboxNetFltWinIncReferenceAdapt(PADAPT pAdapt, uint32_t v)
}
RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- if(vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->PTState))
-#elif defined(VBOXNETADP)
- if(vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->MPState, v))
+#ifdef VBOXNETADP
+ if(vboxNetFltWinDoIncReferenceDevice(&pNetFlt->u.s.WinIf.MpState, v))
#else
- if(vboxNetFltWinDoIncReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v))
+ if(vboxNetFltWinDoIncReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState, v))
#endif
{
RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
@@ -858,17 +727,14 @@ DECLINLINE(bool) vboxNetFltWinIncReferenceAdapt(PADAPT pAdapt, uint32_t v)
return false;
}
-DECLINLINE(bool) vboxNetFltWinReferenceAdapt(PADAPT pAdapt)
+DECLINLINE(bool) vboxNetFltWinReferenceWinIf(PVBOXNETFLTINS pNetFlt)
{
- PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
- if(vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->PTState))
-#elif defined(VBOXNETADP)
- if(vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->MPState))
+#ifdef VBOXNETADP
+ if(vboxNetFltWinDoReferenceDevice(&pNetFlt->u.s.WinIf.MpState))
#else
- if(vboxNetFltWinDoReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState))
+ if(vboxNetFltWinDoReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState))
#endif
{
RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
@@ -883,10 +749,10 @@ DECLINLINE(bool) vboxNetFltWinReferenceAdapt(PADAPT pAdapt)
* methods for accessing the network card info *
***********************************************/
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac);
-DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt);
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes);
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHYSICAL_MEDIUM * pMedium);
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PVBOXNETFLTINS pNetFlt, PRTMAC pMac);
+DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PVBOXNETFLTINS pNetFlt);
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PVBOXNETFLTINS pNetFlt, bool bYes);
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PVBOXNETFLTINS pNetFlt, NDIS_PHYSICAL_MEDIUM * pMedium);
/*********************
* mem alloc API *
@@ -906,56 +772,30 @@ DECLHIDDEN(void) vboxNetFltWinMemFree(PVOID pMemBuf);
DECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbBufSize, PINTNETSG *ppSG);
/************************
- * PADAPT init/fini API *
+ * WinIf init/fini API *
************************/
-
-#if defined(VBOX_NETFLT_ONDEMAND_BIND)
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT pAdapt);
-#elif defined(VBOXNETADP)
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext);
+#if defined(VBOXNETADP)
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PVBOXNETFLTINS *ppNetFlt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext);
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitWinIf(PVBOXNETFLTWIN pWinIf);
#else
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName);
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PVBOXNETFLTINS *ppNetFlt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName);
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitWinIf(PVBOXNETFLTWIN pWinIf, PNDIS_STRING pOurDeviceName);
#endif
-#ifdef VBOX_NETFLT_ONDEMAND_BIND
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT pAdapt);
-#else
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName);
-#endif
-
-DECLHIDDEN(VOID) vboxNetFltWinPtFiniPADAPT(PADAPT pAdapt);
-#ifndef VBOXNETADP
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt, IN PNDIS_STRING pOurDeviceName);
-#else
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt);
-#endif
+DECLHIDDEN(VOID) vboxNetFltWinPtFiniWinIf(PVBOXNETFLTWIN pWinIf);
/************************************
* Execute Job at passive level API *
************************************/
-typedef VOID (*JOB_ROUTINE) (PVOID pContext);
+typedef VOID (*PFNVBOXNETFLT_JOB_ROUTINE) (PVOID pContext);
-DECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(JOB_ROUTINE pRoutine, PVOID pContext);
+DECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine, PVOID pContext);
/*******************************
* Ndis Packets processing API *
*******************************/
-
-#ifndef NDIS_PACKET_FIRST_NDIS_BUFFER
-#define NDIS_PACKET_FIRST_NDIS_BUFFER(_Packet) ((_Packet)->Private.Head)
-#endif
-
-#ifndef NDIS_PACKET_LAST_NDIS_BUFFER
-#define NDIS_PACKET_LAST_NDIS_BUFFER(_Packet) ((_Packet)->Private.Tail)
-#endif
-
-#ifndef NDIS_PACKET_VALID_COUNTS
-#define NDIS_PACKET_VALID_COUNTS(_Packet) ((_Packet)->Private.ValidCounts)
-#endif
-
-
-DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory);
+DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PVBOXNETFLTINS pNetFlt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory);
DECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeMem);
@@ -1009,96 +849,53 @@ DECLINLINE(bool) vboxNetFltWinIsLoopedBackPacket(PNDIS_PACKET pPacket)
#define VBOXNETFLT_OOB_INIT(_p) \
{ \
NdisZeroMemory(NDIS_OOB_DATA_FROM_PACKET(_p), sizeof(NDIS_PACKET_OOB_DATA)); \
- NDIS_SET_PACKET_HEADER_SIZE(_p, ETH_HEADER_SIZE); \
+ NDIS_SET_PACKET_HEADER_SIZE(_p, VBOXNETFLT_PACKET_ETHEADER_SIZE); \
}
-#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
+#ifndef VBOXNETADP
-DECLINLINE(NDIS_STATUS) vboxNetFltWinCopyPacketInfoOnRecv(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket)
+DECLINLINE(NDIS_STATUS) vboxNetFltWinCopyPacketInfoOnRecv(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket, bool bForceStatusResources)
{
- NDIS_STATUS fStatus;
-
- /*
- * Get the original packet (it could be the same packet as the one
- * received or a different one based on the number of layered miniports
- * below) and set it on the indicated packet so the OOB data is visible
- * correctly to protocols above us.
- */
- NDIS_SET_ORIGINAL_PACKET(pDstPacket, NDIS_GET_ORIGINAL_PACKET(pSrcPacket));
+ NDIS_STATUS Status = bForceStatusResources ? NDIS_STATUS_RESOURCES : NDIS_GET_PACKET_STATUS(pSrcPacket);
+ NDIS_SET_PACKET_STATUS(pDstPacket, Status);
- /*
- * Set Packet Flags
- */
- NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket);
+ NDIS_PACKET_FIRST_NDIS_BUFFER(pDstPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pSrcPacket);
+ NDIS_PACKET_LAST_NDIS_BUFFER(pDstPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pSrcPacket);
- fStatus = NDIS_GET_PACKET_STATUS(pSrcPacket);
+ NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket);
- NDIS_SET_PACKET_STATUS(pDstPacket, fStatus);
+ NDIS_SET_ORIGINAL_PACKET(pDstPacket, NDIS_GET_ORIGINAL_PACKET(pSrcPacket));
NDIS_SET_PACKET_HEADER_SIZE(pDstPacket, NDIS_GET_PACKET_HEADER_SIZE(pSrcPacket));
- return fStatus;
+ return Status;
}
DECLINLINE(void) vboxNetFltWinCopyPacketInfoOnSend(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket)
{
- PVOID pMediaSpecificInfo = NULL;
- UINT fMediaSpecificInfoSize = 0;
+ NDIS_PACKET_FIRST_NDIS_BUFFER(pDstPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pSrcPacket);
+ NDIS_PACKET_LAST_NDIS_BUFFER(pDstPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pSrcPacket);
NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket);
-#ifdef WIN9X
- /*
- * Work around the fact that NDIS does not initialize this
- * to FALSE on Win9x.
- */
- NDIS_PACKET_VALID_COUNTS(pDstPacket) = FALSE;
-#endif /* WIN9X */
-
- /*
- * Copy the OOB data from the original packet to the new
- * packet.
- */
NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(pDstPacket),
- NDIS_OOB_DATA_FROM_PACKET(pSrcPacket),
- sizeof(NDIS_PACKET_OOB_DATA));
- /*
- * Copy relevant parts of the per packet info into the new packet
- */
-#ifndef WIN9X
+ NDIS_OOB_DATA_FROM_PACKET(pSrcPacket),
+ sizeof (NDIS_PACKET_OOB_DATA));
+
NdisIMCopySendPerPacketInfo(pDstPacket, pSrcPacket);
-#endif
- /*
- * Copy the Media specific information
- */
- NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(pSrcPacket,
- &pMediaSpecificInfo,
- &fMediaSpecificInfoSize);
+ PVOID pMediaSpecificInfo = NULL;
+ UINT fMediaSpecificInfoSize = 0;
+
+ NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(pSrcPacket, &pMediaSpecificInfo, &fMediaSpecificInfoSize);
if (pMediaSpecificInfo || fMediaSpecificInfoSize)
{
- NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(pDstPacket,
- pMediaSpecificInfo,
- fMediaSpecificInfoSize);
+ NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(pDstPacket, pMediaSpecificInfo, fMediaSpecificInfoSize);
}
}
-DECLHIDDEN(NDIS_STATUS)
-vboxNetFltWinPrepareSendPacket(
- IN PADAPT pAdapt,
- IN PNDIS_PACKET pPacket,
- OUT PNDIS_PACKET *ppMyPacket
- /*, IN bool bNetFltActive*/
- );
-
-
-DECLHIDDEN(NDIS_STATUS)
-vboxNetFltWinPrepareRecvPacket(
- IN PADAPT pAdapt,
- IN PNDIS_PACKET pPacket,
- OUT PNDIS_PACKET *ppMyPacket,
- IN bool bDpr
- );
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPrepareSendPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PNDIS_PACKET *ppMyPacket);
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPrepareRecvPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PNDIS_PACKET *ppMyPacket, bool bDpr);
#endif
DECLHIDDEN(void) vboxNetFltWinSleep(ULONG milis);
@@ -1109,7 +906,7 @@ DECLHIDDEN(void) vboxNetFltWinSleep(ULONG milis);
&& (_m1).au16[2] == (_m2).au16[2])
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOnUnbind);
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PVBOXNETFLTINS pNetFlt, bool bOnUnbind);
DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING pSrc);
@@ -1121,9 +918,9 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING
* @param pThis The instance.
* @param enmNewState The new value.
*/
-DECLINLINE(void) vboxNetFltWinSetAdaptState(PADAPT pAdapt, VBOXADAPTSTATE enmNewState)
+DECLINLINE(void) vboxNetFltWinSetWinIfState(PVBOXNETFLTINS pNetFlt, VBOXNETFLT_WINIFSTATE enmNewState)
{
- ASMAtomicWriteU32((uint32_t volatile *)&pAdapt->enmState, enmNewState);
+ ASMAtomicWriteU32((uint32_t volatile *)&pNetFlt->u.s.WinIf.enmState, enmNewState);
}
/**
@@ -1134,21 +931,19 @@ DECLINLINE(void) vboxNetFltWinSetAdaptState(PADAPT pAdapt, VBOXADAPTSTATE enmNew
* @returns The enmState value.
* @param pThis The instance.
*/
-DECLINLINE(VBOXADAPTSTATE) vboxNetFltWinGetAdaptState(PADAPT pAdapt)
+DECLINLINE(VBOXNETFLT_WINIFSTATE) vboxNetFltWinGetWinIfState(PVBOXNETFLTINS pNetFlt)
{
- return (VBOXADAPTSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pAdapt->enmState);
+ return (VBOXNETFLT_WINIFSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pNetFlt->u.s.WinIf.enmState);
}
+/* reference the driver module to prevent driver unload */
+DECLHIDDEN(void) vboxNetFltWinDrvReference();
+/* dereference the driver module to prevent driver unload */
+DECLHIDDEN(void) vboxNetFltWinDrvDereference();
+
#ifndef VBOXNETADP
-# define VBOXNETFLT_PROMISCUOUS_SUPPORTED(_pAdapt) \
- (!PADAPT_2_PVBOXNETFLTINS(_pAdapt)->fDisablePromiscuous)
-// (!((_pAdapt)->PhMedium == NdisPhysicalMediumWirelessWan \
-// || (_pAdapt)->PhMedium == NdisPhysicalMediumWirelessLan \
-// || (_pAdapt)->PhMedium == NdisPhysicalMediumNative802_11 \
-// || (_pAdapt)->PhMedium == NdisPhysicalMediumBluetooth \
-// /*|| (_pAdapt)->PhMedium == NdisPhysicalMediumWiMax */ \
-// ))
+# define VBOXNETFLT_PROMISCUOUS_SUPPORTED(_pNetFlt) (!(_pNetFlt)->fDisablePromiscuous)
#else
# define STATISTIC_INCREASE(_s) ASMAtomicIncU32((uint32_t volatile *)&(_s));
@@ -1157,4 +952,4 @@ DECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisStrin
DECLHIDDEN(int) vboxNetFltWinMACFromNdisString(RTMAC *pMac, PNDIS_STRING pNdisString);
#endif
-#endif
+#endif /* #ifndef ___VBoxNetFltRt_win_h___ */
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/Makefile.kup b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/Makefile.kup
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/Makefile.kup
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.cpp
new file mode 100644
index 000000000..d0a7ac23a
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.cpp
@@ -0,0 +1,585 @@
+/* $Id: VBoxNetFltNobj.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */
+/** @file
+ * VBoxNetFltNobj.cpp - Notify Object for Bridged Networking Driver.
+ * Used to filter Bridged Networking Driver bindings
+ */
+/*
+ * 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.
+ */
+#include "VBoxNetFltNobj.h"
+#include <Ntddndis.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include <VBoxNetFltNobjT_i.c>
+
+//# define VBOXNETFLTNOTIFY_DEBUG_BIND
+
+#ifdef DEBUG
+# define Assert(a) assert(a)
+# define AssertBreakpoint() assert(0)
+
+#else
+# define Assert(a) do{}while (0)
+# define AssertBreakpoint() do{}while (0)
+
+#endif
+
+VBoxNetFltNobj::VBoxNetFltNobj() :
+ mpNetCfg(NULL),
+ mpNetCfgComponent(NULL),
+ mbInstalling(FALSE)
+{
+}
+
+VBoxNetFltNobj::~VBoxNetFltNobj()
+{
+ cleanup();
+}
+
+void VBoxNetFltNobj::cleanup()
+{
+ if (mpNetCfg)
+ {
+ mpNetCfg->Release();
+ mpNetCfg = NULL;
+ }
+
+ if (mpNetCfgComponent)
+ {
+ mpNetCfgComponent->Release();
+ mpNetCfgComponent = NULL;
+ }
+}
+
+void VBoxNetFltNobj::init(IN INetCfgComponent *pNetCfgComponent, IN INetCfg *pNetCfg, IN BOOL bInstalling)
+{
+ cleanup();
+
+ Assert(pNetCfg);
+ Assert(pNetCfgComponent);
+ if (pNetCfg)
+ {
+ pNetCfg->AddRef();
+ mpNetCfg = pNetCfg;
+ }
+
+ if (pNetCfgComponent)
+ {
+ pNetCfgComponent->AddRef();
+ mpNetCfgComponent = pNetCfgComponent;
+ }
+
+ mbInstalling = bInstalling;
+}
+
+/* INetCfgComponentControl methods */
+STDMETHODIMP VBoxNetFltNobj::Initialize(IN INetCfgComponent *pNetCfgComponent, IN INetCfg *pNetCfg, IN BOOL bInstalling)
+{
+ init(pNetCfgComponent, pNetCfg, bInstalling);
+ return S_OK;
+}
+
+STDMETHODIMP VBoxNetFltNobj::ApplyRegistryChanges()
+{
+ return S_OK;
+}
+
+STDMETHODIMP VBoxNetFltNobj::ApplyPnpChanges(IN INetCfgPnpReconfigCallback *pCallback)
+{
+ return S_OK;
+}
+
+STDMETHODIMP VBoxNetFltNobj::CancelChanges()
+{
+ return S_OK;
+}
+
+static HRESULT vboxNetFltWinQueryInstanceKey(IN INetCfgComponent *pComponent, OUT PHKEY phKey)
+{
+ LPWSTR pPnpId;
+ HRESULT hr = pComponent->GetPnpDevNodeId(&pPnpId);
+ if (hr == S_OK)
+ {
+ WCHAR KeyName[MAX_PATH];
+ wcscpy(KeyName, L"SYSTEM\\CurrentControlSet\\Enum\\");
+ wcscat(KeyName,pPnpId);
+
+ LONG winEr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyName,
+ 0, /*__reserved DWORD ulOptions*/
+ KEY_READ, /*__in REGSAM samDesired*/
+ phKey);
+
+ if (winEr != ERROR_SUCCESS)
+ {
+ hr = HRESULT_FROM_WIN32(winEr);
+ AssertBreakpoint();
+ }
+
+ CoTaskMemFree(pPnpId);
+ }
+ else
+ {
+ AssertBreakpoint();
+ }
+
+ return hr;
+}
+
+static HRESULT vboxNetFltWinQueryDriverKey(IN HKEY InstanceKey, OUT PHKEY phKey)
+{
+ DWORD Type = REG_SZ;
+ WCHAR Value[MAX_PATH];
+ DWORD cbValue = sizeof(Value);
+ HRESULT hr = S_OK;
+ LONG winEr = RegQueryValueExW(InstanceKey,
+ L"Driver", /*__in_opt LPCTSTR lpValueName*/
+ 0, /*__reserved LPDWORD lpReserved*/
+ &Type, /*__out_opt LPDWORD lpType*/
+ (LPBYTE)Value, /*__out_opt LPBYTE lpData*/
+ &cbValue/*__inout_opt LPDWORD lpcbData*/
+ );
+
+ if (winEr == ERROR_SUCCESS)
+ {
+ WCHAR KeyName[MAX_PATH];
+ wcscpy(KeyName, L"SYSTEM\\CurrentControlSet\\Control\\Class\\");
+ wcscat(KeyName,Value);
+
+ winEr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyName,
+ 0, /*__reserved DWORD ulOptions*/
+ KEY_READ, /*__in REGSAM samDesired*/
+ phKey);
+
+ if (winEr != ERROR_SUCCESS)
+ {
+ hr = HRESULT_FROM_WIN32(winEr);
+ AssertBreakpoint();
+ }
+ }
+ else
+ {
+ hr = HRESULT_FROM_WIN32(winEr);
+ AssertBreakpoint();
+ }
+
+ return hr;
+}
+
+static HRESULT vboxNetFltWinQueryDriverKey(IN INetCfgComponent *pComponent, OUT PHKEY phKey)
+{
+ HKEY InstanceKey;
+ HRESULT hr = vboxNetFltWinQueryInstanceKey(pComponent, &InstanceKey);
+ if (hr == S_OK)
+ {
+ hr = vboxNetFltWinQueryDriverKey(InstanceKey, phKey);
+ if (hr != S_OK)
+ {
+ AssertBreakpoint();
+ }
+ RegCloseKey(InstanceKey);
+ }
+ else
+ {
+ AssertBreakpoint();
+ }
+
+ return hr;
+}
+
+static HRESULT vboxNetFltWinNotifyCheckNetAdp(IN INetCfgComponent *pComponent, OUT bool * pbShouldBind)
+{
+ HRESULT hr;
+ LPWSTR pDevId;
+ hr = pComponent->GetId(&pDevId);
+ if (hr == S_OK)
+ {
+ if (!_wcsnicmp(pDevId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
+ {
+ *pbShouldBind = false;
+ }
+ else
+ {
+ hr = S_FALSE;
+ }
+ CoTaskMemFree(pDevId);
+ }
+ else
+ {
+ AssertBreakpoint();
+ }
+
+ return hr;
+}
+
+static HRESULT vboxNetFltWinNotifyCheckMsLoop(IN INetCfgComponent *pComponent, OUT bool * pbShouldBind)
+{
+ HRESULT hr;
+ LPWSTR pDevId;
+ hr = pComponent->GetId(&pDevId);
+ if (hr == S_OK)
+ {
+ if (!_wcsnicmp(pDevId, L"*msloop", sizeof(L"*msloop")/2))
+ {
+ /* we need to detect the medium the adapter is presenting
+ * to do that we could examine in the registry the *msloop params */
+ HKEY DriverKey;
+ hr = vboxNetFltWinQueryDriverKey(pComponent, &DriverKey);
+ if (hr == S_OK)
+ {
+ DWORD Type = REG_SZ;
+ WCHAR Value[64]; /* 2 should be enough actually, paranoid check for extra spaces */
+ DWORD cbValue = sizeof(Value);
+ LONG winEr = RegQueryValueExW(DriverKey,
+ L"Medium", /*__in_opt LPCTSTR lpValueName*/
+ 0, /*__reserved LPDWORD lpReserved*/
+ &Type, /*__out_opt LPDWORD lpType*/
+ (LPBYTE)Value, /*__out_opt LPBYTE lpData*/
+ &cbValue/*__inout_opt LPDWORD lpcbData*/
+ );
+ if (winEr == ERROR_SUCCESS)
+ {
+ PWCHAR endPrt;
+ ULONG enmMedium = wcstoul(Value,
+ &endPrt,
+ 0 /* base*/);
+
+ winEr = errno;
+ if (winEr == ERROR_SUCCESS)
+ {
+ if (enmMedium == 0) /* 0 is Ethernet */
+ {
+ *pbShouldBind = true;
+ }
+ else
+ {
+ *pbShouldBind = false;
+ }
+ }
+ else
+ {
+ AssertBreakpoint();
+ *pbShouldBind = true;
+ }
+ }
+ else
+ {
+ /* TODO: we should check the default medium in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\<driver_id>\Ndi\Params\Medium, REG_SZ "Default" value */
+ AssertBreakpoint();
+ *pbShouldBind = true;
+ }
+
+ RegCloseKey(DriverKey);
+ }
+ else
+ {
+ AssertBreakpoint();
+ }
+ }
+ else
+ {
+ hr = S_FALSE;
+ }
+ CoTaskMemFree(pDevId);
+ }
+ else
+ {
+ AssertBreakpoint();
+ }
+
+ return hr;
+}
+
+static HRESULT vboxNetFltWinNotifyCheckLowerRange(IN INetCfgComponent *pComponent, OUT bool * pbShouldBind)
+{
+ HKEY DriverKey;
+ HKEY InterfacesKey;
+ HRESULT hr = vboxNetFltWinQueryDriverKey(pComponent, &DriverKey);
+ if (hr == S_OK)
+ {
+ LONG winEr = RegOpenKeyExW(DriverKey, L"Ndi\\Interfaces",
+ 0, /*__reserved DWORD ulOptions*/
+ KEY_READ, /*__in REGSAM samDesired*/
+ &InterfacesKey);
+ if (winEr == ERROR_SUCCESS)
+ {
+ DWORD Type = REG_SZ;
+ WCHAR Value[MAX_PATH];
+ DWORD cbValue = sizeof(Value);
+ winEr = RegQueryValueExW(InterfacesKey,
+ L"LowerRange", /*__in_opt LPCTSTR lpValueName*/
+ 0, /*__reserved LPDWORD lpReserved*/
+ &Type, /*__out_opt LPDWORD lpType*/
+ (LPBYTE)Value, /*__out_opt LPBYTE lpData*/
+ &cbValue/*__inout_opt LPDWORD lpcbData*/
+ );
+ if (winEr == ERROR_SUCCESS)
+ {
+ if (wcsstr(Value,L"ethernet") || wcsstr(Value, L"wan"))
+ {
+ *pbShouldBind = true;
+ }
+ else
+ {
+ *pbShouldBind = false;
+ }
+ }
+ else
+ {
+ /* do not set err status to it */
+ *pbShouldBind = false;
+ AssertBreakpoint();
+ }
+
+ RegCloseKey(InterfacesKey);
+ }
+ else
+ {
+ hr = HRESULT_FROM_WIN32(winEr);
+ AssertBreakpoint();
+ }
+
+ RegCloseKey(DriverKey);
+ }
+ else
+ {
+ AssertBreakpoint();
+ }
+
+ return hr;
+}
+
+static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgComponent *pComponent, OUT bool *pbShouldBind)
+{
+ DWORD fCharacteristics;
+ HRESULT hr;
+
+ do
+ {
+ /* filter out only physical adapters */
+ hr = pComponent->GetCharacteristics(&fCharacteristics);
+ if (hr != S_OK)
+ {
+ AssertBreakpoint();
+ break;
+ }
+
+
+ if (fCharacteristics & NCF_HIDDEN)
+ {
+ /* we are not binding to hidden adapters */
+ *pbShouldBind = false;
+ break;
+ }
+
+ hr = vboxNetFltWinNotifyCheckMsLoop(pComponent, pbShouldBind);
+ if (hr == S_OK)
+ {
+ /* this is a loopback adapter,
+ * the pbShouldBind already contains the result */
+ break;
+ }
+ else if (hr != S_FALSE)
+ {
+ /* error occurred */
+ break;
+ }
+
+ hr = vboxNetFltWinNotifyCheckNetAdp(pComponent, pbShouldBind);
+ if (hr == S_OK)
+ {
+ /* this is a VBoxNetAdp adapter,
+ * the pbShouldBind already contains the result */
+ break;
+ }
+ else if (hr != S_FALSE)
+ {
+ /* error occurred */
+ break;
+ }
+
+ /* hr == S_FALSE means this is not a loopback adpater, set it to S_OK */
+ hr = S_OK;
+
+// if (!(fCharacteristics & NCF_PHYSICAL))
+// {
+// /* we are binding to physical adapters only */
+// *pbShouldBind = false;
+// break;
+// }
+
+ hr = vboxNetFltWinNotifyCheckLowerRange(pComponent, pbShouldBind);
+ if (hr == S_OK)
+ {
+ /* the vboxNetFltWinNotifyCheckLowerRange ccucceeded,
+ * the pbShouldBind already contains the result */
+ break;
+ }
+ /* we are here because of the fail, nothing else to do */
+ } while (0);
+
+ return hr;
+}
+
+
+static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgBindingInterface *pIf, OUT bool *pbShouldBind)
+{
+ INetCfgComponent * pAdapterComponent;
+ HRESULT hr = pIf->GetLowerComponent(&pAdapterComponent);
+ if (hr == S_OK)
+ {
+ hr = vboxNetFltWinNotifyShouldBind(pAdapterComponent, pbShouldBind);
+
+ pAdapterComponent->Release();
+ }
+ else
+ {
+ AssertBreakpoint();
+ }
+
+ return hr;
+}
+
+static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgBindingPath *pPath, OUT bool *pbDoBind)
+{
+ IEnumNetCfgBindingInterface *pEnumBindingIf;
+ HRESULT hr = pPath->EnumBindingInterfaces(&pEnumBindingIf);
+ if (hr == S_OK)
+ {
+ hr = pEnumBindingIf->Reset();
+ if (hr == S_OK)
+ {
+ ULONG ulCount;
+ INetCfgBindingInterface *pBindingIf;
+ do
+ {
+ hr = pEnumBindingIf->Next(1, &pBindingIf, &ulCount);
+ if (hr == S_OK)
+ {
+ hr = vboxNetFltWinNotifyShouldBind(pBindingIf, pbDoBind);
+
+ pBindingIf->Release();
+
+ if (hr == S_OK)
+ {
+ if (!(*pbDoBind))
+ {
+ break;
+ }
+ }
+ else
+ {
+ /* break on failure */
+ break;
+ }
+ }
+ else if (hr == S_FALSE)
+ {
+ /* no more elements */
+ hr = S_OK;
+ break;
+ }
+ else
+ {
+ AssertBreakpoint();
+ /* break on falure */
+ break;
+ }
+ } while (true);
+ }
+ else
+ {
+ AssertBreakpoint();
+ }
+
+ pEnumBindingIf->Release();
+ }
+ else
+ {
+ AssertBreakpoint();
+ }
+
+ return hr;
+}
+
+static bool vboxNetFltWinNotifyShouldBind(IN INetCfgBindingPath *pPath)
+{
+#ifdef VBOXNETFLTNOTIFY_DEBUG_BIND
+ return VBOXNETFLTNOTIFY_DEBUG_BIND;
+#else
+ bool bShouldBind;
+ HRESULT hr = vboxNetFltWinNotifyShouldBind(pPath, &bShouldBind) ;
+ if (hr != S_OK)
+ {
+ bShouldBind = VBOXNETFLTNOTIFY_ONFAIL_BINDDEFAULT;
+ }
+
+ return bShouldBind;
+#endif
+}
+
+
+/* INetCfgComponentNotifyBinding methods */
+STDMETHODIMP VBoxNetFltNobj::NotifyBindingPath(IN DWORD dwChangeFlag, IN INetCfgBindingPath *pNetCfgBP)
+{
+ if (!(dwChangeFlag & NCN_ENABLE) || (dwChangeFlag & NCN_REMOVE) || vboxNetFltWinNotifyShouldBind(pNetCfgBP))
+ return S_OK;
+ return NETCFG_S_DISABLE_QUERY;
+}
+
+STDMETHODIMP VBoxNetFltNobj::QueryBindingPath(IN DWORD dwChangeFlag, IN INetCfgBindingPath *pNetCfgBP)
+{
+ if (vboxNetFltWinNotifyShouldBind(pNetCfgBP))
+ return S_OK;
+ return NETCFG_S_DISABLE_QUERY;
+}
+
+
+CComModule _Module;
+
+BEGIN_OBJECT_MAP(ObjectMap)
+ OBJECT_ENTRY(CLSID_VBoxNetFltNobj, VBoxNetFltNobj)
+END_OBJECT_MAP()
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ _Module.Init(ObjectMap, hInstance);
+ DisableThreadLibraryCalls(hInstance);
+ }
+ else if (dwReason == DLL_PROCESS_DETACH)
+ {
+ _Module.Term();
+ }
+ return TRUE;
+}
+
+STDAPI DllCanUnloadNow()
+{
+ return (_Module.GetLockCount() == 0) ? S_OK : S_FALSE;
+}
+
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
+{
+ return _Module.GetClassObject(rclsid, riid, ppv);
+}
+
+STDAPI DllRegisterServer()
+{
+ return _Module.RegisterServer(TRUE);
+}
+
+STDAPI DllUnregisterServer()
+{
+ return _Module.UnregisterServer(TRUE);
+}
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.def b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.def
new file mode 100644
index 000000000..6512eefc6
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.def
@@ -0,0 +1,22 @@
+; $Id: VBoxNetFltNobj.def 36184 2011-03-07 10:57:04Z vboxsync $
+; @file
+; VBoxNetFltNobj.def - Notify Object for Bridged Networking Driver.
+; Library def file
+;
+;
+; 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.
+;
+LIBRARY VBoxNetFltNobj
+EXPORTS
+ DllCanUnloadNow PRIVATE
+ DllGetClassObject PRIVATE
+ DllRegisterServer PRIVATE
+ DllUnregisterServer PRIVATE \ No newline at end of file
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.h b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.h
new file mode 100644
index 000000000..036df1dee
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.h
@@ -0,0 +1,73 @@
+/* $Id: VBoxNetFltNobj.h 36184 2011-03-07 10:57:04Z vboxsync $ */
+/** @file
+ * VBoxNetFltNobj.h - Notify Object for Bridged Networking Driver.
+ * Used to filter Bridged Networking Driver bindings
+ */
+/*
+ * 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 ___VboxNetFltNobj_h___
+#define ___VboxNetFltNobj_h___
+
+#include <windows.h>
+/* atl stuff */
+#include <atlbase.h>
+extern CComModule _Module;
+#include <atlcom.h>
+
+#include "VBoxNetFltNobjT.h"
+#include "VBoxNetFltNobjRc.h"
+
+#define VBOXNETFLTNOTIFY_ONFAIL_BINDDEFAULT false
+
+/*
+ * VirtualBox Bridging driver notify object.
+ * Needed to make our driver bind to "real" host adapters only
+ */
+class ATL_NO_VTABLE VBoxNetFltNobj :
+ public CComObjectRootEx<CComObjectThreadModel>,
+ public CComCoClass<VBoxNetFltNobj, &CLSID_VBoxNetFltNobj>,
+ public INetCfgComponentControl,
+ public INetCfgComponentNotifyBinding
+{
+public:
+ VBoxNetFltNobj();
+ ~VBoxNetFltNobj();
+
+ BEGIN_COM_MAP(VBoxNetFltNobj)
+ COM_INTERFACE_ENTRY(INetCfgComponentControl)
+ COM_INTERFACE_ENTRY(INetCfgComponentNotifyBinding)
+ END_COM_MAP()
+
+ DECLARE_REGISTRY_RESOURCEID(IDR_VBOXNETFLT_NOBJ)
+
+ /* INetCfgComponentControl methods */
+ STDMETHOD(Initialize)(IN INetCfgComponent *pNetCfgComponent, IN INetCfg *pNetCfg, IN BOOL bInstalling);
+ STDMETHOD(ApplyRegistryChanges)();
+ STDMETHOD(ApplyPnpChanges)(IN INetCfgPnpReconfigCallback *pCallback);
+ STDMETHOD(CancelChanges)();
+
+ /* INetCfgComponentNotifyBinding methods */
+ STDMETHOD(NotifyBindingPath)(IN DWORD dwChangeFlag, IN INetCfgBindingPath *pNetCfgBP);
+ STDMETHOD(QueryBindingPath)(IN DWORD dwChangeFlag, IN INetCfgBindingPath *pNetCfgBP);
+private:
+
+ void init(IN INetCfgComponent *pNetCfgComponent, IN INetCfg *pNetCfg, IN BOOL bInstalling);
+ void cleanup();
+
+ /* these two used to maintain the component info passed to
+ * INetCfgComponentControl::Initialize */
+ INetCfg *mpNetCfg;
+ INetCfgComponent *mpNetCfgComponent;
+ BOOL mbInstalling;
+};
+
+#endif /* #ifndef ___VboxNetFltNobj_h___ */
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rc b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rc
index 165b50bd0..57f92364c 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rc
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rc
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFltNotify.rc $ */
+/* $Id: VBoxNetFltNobj.rc 36184 2011-03-07 10:57:04Z vboxsync $ */
/** @file
- * VBoxNetFltNotify - Resource file containing version info and icon.
+ * VBoxNetFltNobj.h - Notify Object for Bridged Networking Driver.
+ * Resource file
*/
-
/*
- * Copyright (C) 2009-2010 Oracle Corporation
+ * 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;
@@ -18,13 +18,7 @@
#include <windows.h>
#include <VBox/version.h>
-#include "VBoxNetFltNotifyRc.h"
-/////////////////////////////////////////////////////////////////////////////
-//
-// REGISTRY
-//
-1 TYPELIB "VBoxNetFltNotifyn.tlb"
-IDR_REG_VBOXNETFLT_NOTIFY REGISTRY "VBoxNetFltNotify.rgs"
+#include "VBoxNetFltNobjRc.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
@@ -44,11 +38,11 @@ BEGIN
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
BEGIN
VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", "VirtualBox Bridged Networking Driver Notify Object\0"
+ VALUE "FileDescription", "VirtualBox Bridged Networking Driver Notify Object v1.1\0"
VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", "VBoxNetFltNotify.dll\0"
+ VALUE "InternalName", "VBoxNetFltNobj.dll\0"
VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
- VALUE "OriginalFilename","VBoxNetFltNotify.dll\0"
+ VALUE "OriginalFilename","VBoxNetFltNobj.dll\0"
VALUE "ProductName", VBOX_PRODUCT "\0"
VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
END
@@ -59,3 +53,11 @@ BEGIN
END
END
+/////////////////////////////////////////////////////////////////////////////
+//
+// REGISTRY
+//
+
+IDR_VBOXNETFLT_NOBJ REGISTRY "VBoxNetFltNobj.rgs"
+
+1 TYPELIB "VBoxNetFltNobjT.tlb"
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rgs b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rgs
index 2cc93c88d..d6f9bae32 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rgs
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rgs
@@ -2,7 +2,7 @@ HKCR
{
NoRemove CLSID
{
- ForceRemove {c631480a-acbe-4add-bb1d-3ed8aa52b5d9} = s 'VirtualBox Bridged Networking Driver Notify Object'
+ ForceRemove {f374d1a0-bf08-4bdc-9cb2-c15ddaeef955} = s 'VirtualBox Bridged Networking Driver Notify Object v1.1'
{
InProcServer32 = s '%MODULE%'
{
diff --git a/src/VBox/Additions/linux/installer/test_drm.c b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjRc.h
index faccbce3d..cedcda7f3 100644
--- a/src/VBox/Additions/linux/installer/test_drm.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjRc.h
@@ -1,7 +1,10 @@
+/* $Id: VBoxNetFltNobjRc.h 36184 2011-03-07 10:57:04Z vboxsync $ */
+/** @file
+ * VBoxNetFltNobjRc.h - Notify Object for Bridged Networking Driver.
+ * Resource definitions
+ */
/*
- * VirtualBox Guest Additions installer test module for Linux
- *
- * Copyright (C) 2006-2007 Oracle Corporation
+ * 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;
@@ -11,22 +14,10 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
+#ifndef ___VboxNetFltNobjRc_h___
+#define ___VboxNetFltNobjRc_h___
-#include <linux/init.h>
-#include <linux/module.h>
-#include "drm/drmP.h"
-
-
-MODULE_DESCRIPTION("VirtualBox Guest Additions drm test module");
-MODULE_AUTHOR("Oracle Corporation");
-MODULE_LICENSE("GPL");
-
-static int init(void)
-{
- return 0;
-}
-
-static void fini(void) {}
+/* registry script rc ID */
+#define IDR_VBOXNETFLT_NOBJ 101
-module_init(init);
-module_exit(fini);
+#endif /* #ifndef ___VboxNetFltNobjRc_h___ */
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyn.idl b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjT.idl
index 089b79ee2..22b6f2bfe 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyn.idl
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjT.idl
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFltNotifyn.idl $ */
+/* $Id: VBoxNetFltNobjT.idl 36184 2011-03-07 10:57:04Z vboxsync $ */
/** @file
- * VBoxNetFltNotify.idl - Network Filter Driver (Host), Windows Specific Code. Integration with IntNet/NetFlt
+ * VBoxNetFltNobjT.idl - Notify Object for Bridged Networking Driver.
+ * Type lib definition
*/
-
/*
- * Copyright (C) 2008 Oracle Corporation
+ * 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;
@@ -14,29 +14,20 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-/*
- * Based in part on Microsoft DDK sample code for Sample Notify Object
- *+---------------------------------------------------------------------------
- *
- * Microsoft Windows
- * Copyright (C) Microsoft Corporation, 1992-2001.
- *
- *----------------------------------------------------------------------------
- */
#include <netcfgn.idl>
[
- uuid(1ea703af-a150-4fdd-83dc-c07a7a460c7e),
- version(1.0),
- helpstring("VirtualBox Bridged Networking Driver Notify Object 1.0 Type Library")
+ uuid(2a0c94d1-40e1-439c-8fe8-24107cab0840),
+ version(1.1),
+ helpstring("VirtualBox Bridged Networking Driver Notify Object v1.1 Type Library")
]
-library VBoxNetFltNotifyLib
+library VBoxNetFltNobjLib
{
[
- uuid(c631480a-acbe-4add-bb1d-3ed8aa52b5d9),
+ uuid(f374d1a0-bf08-4bdc-9cb2-c15ddaeef955),
helpstring("VirtualBox Bridged Networking Driver Notify Object Class")
]
- coclass VBoxNetFltNotify
+ coclass VBoxNetFltNobj
{
[restricted] interface INetCfgComponentControl;
[restricted] interface INetCfgComponentNotifyBinding;
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp
deleted file mode 100644
index b5c57ea36..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-/*
- * Based in part on Microsoft DDK sample code for Sample Notify Object
- *+---------------------------------------------------------------------------
- *
- * Microsoft Windows
- * Copyright (C) Microsoft Corporation, 1992-2001.
- *
- * Author: Alok Sinha
- *
- *----------------------------------------------------------------------------
- */
-#include "VBoxNetFltNotify.h"
-#include <Ntddndis.h>
-#include <assert.h>
-#include <stdio.h>
-
-#include <VBoxNetFltNotifyn_i.c>
-
-CComModule _Module;
-
-BEGIN_OBJECT_MAP(ObjectMap)
- OBJECT_ENTRY(CLSID_VBoxNetFltNotify, VBoxNetFltNotify)
-END_OBJECT_MAP()
-
-#define ReleaseObj( x ) if ( x ) \
- ((IUnknown*)(x))->Release();
-
-//# define VBOXNETFLTNOTIFY_DEBUG_BIND true
-
-#ifdef DEBUG
-# define Assert(a) assert(a)
-# define AssertBreakpoint() assert(0)
-
-# define TraceMsg DbgTraceMsg
-#else
-# define Assert(a) do{}while(0)
-# define AssertBreakpoint() do{}while(0)
-
-# define TraceMsg
-#endif
-
-
-static void DbgTraceMsg (LPWSTR szFormat, ...)
-{
- static WCHAR szTempBuf[4096];
-
- va_list arglist;
-
- va_start(arglist, szFormat);
-
- vswprintf( szTempBuf, szFormat, arglist );
-
- OutputDebugStringW( szTempBuf );
-
- va_end(arglist);
-}
-
-VBoxNetFltNotify::VBoxNetFltNotify (VOID) : m_pncc (NULL),
- m_pnc(NULL)
- /*,
- m_eApplyAction(eActUnknown),
- m_pUnkContext(NULL)*/
-{
- TraceMsg(L"VBoxNetFltNotify\n");
-}
-
-VBoxNetFltNotify::~VBoxNetFltNotify (VOID)
-{
- TraceMsg(L"-->~VBoxNetFltNotify (destructor)\n");
- ReleaseObj( m_pncc );
- ReleaseObj( m_pnc );
- TraceMsg(L"<--~VBoxNetFltNotify (destructor)\n");
-}
-
-/*
- * NOTIFY OBJECT FUNCTIONS
- */
-
-/*
- * INetCfgComponentControl
- *
- * The following functions provide the INetCfgComponentControl interface.
- */
-
-/**
- * Initialize the notify object
- *
- * @param pnccItem Pointer to INetCfgComponent object
- * @param pnc Pointer to INetCfg object
- * @param fInstalling TRUE if we are being installed
- * @return S_OK on success, otherwise an error code
- */
-STDMETHODIMP VBoxNetFltNotify::Initialize (INetCfgComponent* pncc,
- INetCfg* pnc,
- BOOL fInstalling)
-{
- HRESULT hr = S_OK;
-
- TraceMsg(L"-->Initialize\n");
-
- m_pncc = pncc;
- m_pnc = pnc;
-
- if (m_pncc)
- {
- m_pncc->AddRef();
- }
-
- if (m_pnc)
- {
- m_pnc->AddRef();
- }
-
- TraceMsg(L"<--Initialize\n");
-
- return hr;
-}
-
-/**
- * Cancel any changes made to internal data
- * @return S_OK on success, otherwise an error code
- */
-STDMETHODIMP VBoxNetFltNotify::CancelChanges (VOID)
-{
- TraceMsg(L"CancelChanges\n");
- return S_OK;
-}
-
-/*
- * Apply changes. We can make changes to registry etc. here.
- * @return S_OK on success, otherwise an error code
- */
-STDMETHODIMP VBoxNetFltNotify::ApplyRegistryChanges(VOID)
-{
- TraceMsg(L"ApplyRegistryChanges\n");
- return S_OK;
-}
-
-/**
- * Apply changes.
- * @param pfCallback PnPConfigCallback interface.
- * @return S_OK on success, otherwise an error code
- */
-STDMETHODIMP VBoxNetFltNotify::ApplyPnpChanges (
- INetCfgPnpReconfigCallback* pfCallback)
-{
- TraceMsg(L"ApplyPnpChanges\n");
- return S_OK;
-}
-
-static HRESULT vboxNetFltWinQueryInstanceKey(IN INetCfgComponent *pComponent, OUT PHKEY phKey)
-{
- LPWSTR pPnpId;
- HRESULT hr = pComponent->GetPnpDevNodeId(&pPnpId);
- if(hr == S_OK)
- {
- WCHAR KeyName[MAX_PATH];
- wcscpy(KeyName, L"SYSTEM\\CurrentControlSet\\Enum\\");
- wcscat(KeyName,pPnpId);
-
- LONG winEr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyName,
- 0, /*__reserved DWORD ulOptions*/
- KEY_READ, /*__in REGSAM samDesired*/
- phKey);
-
- if(winEr != ERROR_SUCCESS)
- {
- hr = HRESULT_FROM_WIN32(winEr);
- TraceMsg(L"vboxNetFltWinQueryInstanceKey: RegOpenKeyExW error, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
-
- CoTaskMemFree(pPnpId);
- }
- else
- {
- TraceMsg(L"vboxNetFltWinQueryInstanceKey: GetPnpDevNodeId error, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
-
- return hr;
-}
-
-static HRESULT vboxNetFltWinQueryDriverKey(IN HKEY InstanceKey, OUT PHKEY phKey)
-{
- DWORD Type = REG_SZ;
- WCHAR Value[MAX_PATH];
- DWORD cbValue = sizeof(Value);
- HRESULT hr = S_OK;
- LONG winEr = RegQueryValueExW(InstanceKey,
- L"Driver", /*__in_opt LPCTSTR lpValueName*/
- 0, /*__reserved LPDWORD lpReserved*/
- &Type, /*__out_opt LPDWORD lpType*/
- (LPBYTE)Value, /*__out_opt LPBYTE lpData*/
- &cbValue/*__inout_opt LPDWORD lpcbData*/
- );
-
- if(winEr == ERROR_SUCCESS)
- {
- WCHAR KeyName[MAX_PATH];
- wcscpy(KeyName, L"SYSTEM\\CurrentControlSet\\Control\\Class\\");
- wcscat(KeyName,Value);
-
- winEr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyName,
- 0, /*__reserved DWORD ulOptions*/
- KEY_READ, /*__in REGSAM samDesired*/
- phKey);
-
- if(winEr != ERROR_SUCCESS)
- {
- hr = HRESULT_FROM_WIN32(winEr);
- TraceMsg(L"vboxNetFltWinQueryDriverKey from instance key: RegOpenKeyExW error, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
- }
- else
- {
- hr = HRESULT_FROM_WIN32(winEr);
- TraceMsg(L"vboxNetFltWinQueryDriverKey from instance key: RegQueryValueExW error, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
-
- return hr;
-}
-
-static HRESULT vboxNetFltWinQueryDriverKey(IN INetCfgComponent *pComponent, OUT PHKEY phKey)
-{
- HKEY InstanceKey;
- HRESULT hr = vboxNetFltWinQueryInstanceKey(pComponent, &InstanceKey);
- if(hr == S_OK)
- {
- hr = vboxNetFltWinQueryDriverKey(InstanceKey, phKey);
- if(hr != S_OK)
- {
- TraceMsg(L"vboxNetFltWinQueryDriverKey from Component: vboxNetFltWinQueryDriverKey error, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
- RegCloseKey(InstanceKey);
- }
- else
- {
- TraceMsg(L"vboxNetFltWinQueryDriverKey from Component: vboxNetFltWinQueryInstanceKey error, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
-
- return hr;
-}
-
-static HRESULT vboxNetFltWinNotifyCheckNetAdp(IN INetCfgComponent *pComponent, OUT bool * pbShouldBind)
-{
- HRESULT hr;
- LPWSTR pDevId;
- hr = pComponent->GetId(&pDevId);
- if(hr == S_OK)
- {
- if(!_wcsnicmp(pDevId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
- {
- *pbShouldBind = false;
- }
- else
- {
- hr = S_FALSE;
- }
- CoTaskMemFree(pDevId);
- }
- else
- {
- TraceMsg(L"vboxNetFltWinNotifyCheckNetAdp: GetId failed, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
-
- return hr;
-}
-
-static HRESULT vboxNetFltWinNotifyCheckMsLoop(IN INetCfgComponent *pComponent, OUT bool * pbShouldBind)
-{
- HRESULT hr;
- LPWSTR pDevId;
- hr = pComponent->GetId(&pDevId);
- if(hr == S_OK)
- {
- if(!_wcsnicmp(pDevId, L"*msloop", sizeof(L"*msloop")/2))
- {
- /* we need to detect the medium the adapter is presenting
- * to do that we could examine in the registry the *msloop params */
- HKEY DriverKey;
- hr = vboxNetFltWinQueryDriverKey(pComponent, &DriverKey);
- if(hr == S_OK)
- {
- DWORD Type = REG_SZ;
- WCHAR Value[64]; /* 2 should be enough actually, paranoid check for extra spaces */
- DWORD cbValue = sizeof(Value);
- LONG winEr = RegQueryValueExW(DriverKey,
- L"Medium", /*__in_opt LPCTSTR lpValueName*/
- 0, /*__reserved LPDWORD lpReserved*/
- &Type, /*__out_opt LPDWORD lpType*/
- (LPBYTE)Value, /*__out_opt LPBYTE lpData*/
- &cbValue/*__inout_opt LPDWORD lpcbData*/
- );
- if(winEr == ERROR_SUCCESS)
- {
- PWCHAR endPrt;
- ULONG enmMedium = wcstoul(Value,
- &endPrt,
- 0 /* base*/);
-
- winEr = errno;
- if(winEr == ERROR_SUCCESS)
- {
- if(enmMedium == 0) /* 0 is Ethernet */
- {
- TraceMsg(L"vboxNetFltWinNotifyCheckMsLoop: loopback is configured as ethernet, binding\n", winEr);
- *pbShouldBind = true;
- }
- else
- {
- TraceMsg(L"vboxNetFltWinNotifyCheckMsLoop: loopback is configured as NOT ethernet, NOT binding\n", winEr);
- *pbShouldBind = false;
- }
- }
- else
- {
- TraceMsg(L"vboxNetFltWinNotifyCheckMsLoop: wcstoul error, winEr (%d), ignoring and binding\n", winEr);
- AssertBreakpoint();
- *pbShouldBind = true;
- }
- }
- else
- {
- TraceMsg(L"vboxNetFltWinNotifyCheckMsLoop: RegQueryValueExW failed, winEr (%d), ignoring, binding\n", hr);
- /* TODO: we should check the default medium in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\<driver_id>\Ndi\Params\Medium, REG_SZ "Default" value */
- AssertBreakpoint();
- *pbShouldBind = true;
- }
-
- RegCloseKey(DriverKey);
- }
- else
- {
- TraceMsg(L"vboxNetFltWinNotifyCheckMsLoop: vboxNetFltWinQueryDriverKey for msloop failed, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
- }
- else
- {
- hr = S_FALSE;
- }
- CoTaskMemFree(pDevId);
- }
- else
- {
- TraceMsg(L"vboxNetFltWinNotifyCheckMsLoop: GetId failed, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
-
- return hr;
-}
-
-static HRESULT vboxNetFltWinNotifyCheckLowerRange(IN INetCfgComponent *pComponent, OUT bool * pbShouldBind)
-{
- HKEY DriverKey;
- HKEY InterfacesKey;
- HRESULT hr = vboxNetFltWinQueryDriverKey(pComponent, &DriverKey);
- if(hr == S_OK)
- {
- LONG winEr = RegOpenKeyExW(DriverKey, L"Ndi\\Interfaces",
- 0, /*__reserved DWORD ulOptions*/
- KEY_READ, /*__in REGSAM samDesired*/
- &InterfacesKey);
- if(winEr == ERROR_SUCCESS)
- {
- DWORD Type = REG_SZ;
- WCHAR Value[MAX_PATH];
- DWORD cbValue = sizeof(Value);
- winEr = RegQueryValueExW(InterfacesKey,
- L"LowerRange", /*__in_opt LPCTSTR lpValueName*/
- 0, /*__reserved LPDWORD lpReserved*/
- &Type, /*__out_opt LPDWORD lpType*/
- (LPBYTE)Value, /*__out_opt LPBYTE lpData*/
- &cbValue/*__inout_opt LPDWORD lpcbData*/
- );
- if(winEr == ERROR_SUCCESS)
- {
- if(wcsstr(Value,L"ethernet") || wcsstr(Value, L"wan"))
- {
- *pbShouldBind = true;
- }
- else
- {
- *pbShouldBind = false;
- }
- }
- else
- {
- /* do not set err status to it */
- *pbShouldBind = false;
- TraceMsg(L"vboxNetFltWinNotifyCheckLowerRange: RegQueryValueExW for LowerRange error, winEr (%d), not binding\n", winEr);
- AssertBreakpoint();
- }
-
- RegCloseKey(InterfacesKey);
- }
- else
- {
- hr = HRESULT_FROM_WIN32(winEr);
- TraceMsg(L"vboxNetFltWinNotifyCheckLowerRange: RegOpenKeyExW error, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
-
- RegCloseKey(DriverKey);
- }
- else
- {
- TraceMsg(L"vboxNetFltWinNotifyShouldBind for INetCfgComponen: vboxNetFltWinQueryDriverKey failed, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
-
- return hr;
-}
-
-static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgComponent *pComponent, OUT bool *pbShouldBind)
-{
- TraceMsg(L"-->vboxNetFltWinNotifyShouldBind for INetCfgComponent\n");
- DWORD fCharacteristics;
- HRESULT hr;
-
- do
- {
- /* filter out only physical adapters */
- hr = pComponent->GetCharacteristics(&fCharacteristics);
- if(hr != S_OK)
- {
- TraceMsg(L"vboxNetFltWinNotifyShouldBind for INetCfgComponen: GetCharacteristics failed, hr (0x%x)\n", hr);
- AssertBreakpoint();
- break;
- }
-
-
- if(fCharacteristics & NCF_HIDDEN)
- {
- /* we are not binding to hidden adapters */
- *pbShouldBind = false;
- break;
- }
-
- hr = vboxNetFltWinNotifyCheckMsLoop(pComponent, pbShouldBind);
- if(hr == S_OK)
- {
- /* this is a loopback adapter,
- * the pbShouldBind already contains the result */
- break;
- }
- else if(hr != S_FALSE)
- {
- /* error occurred */
- break;
- }
-
- hr = vboxNetFltWinNotifyCheckNetAdp(pComponent, pbShouldBind);
- if(hr == S_OK)
- {
- /* this is a VBoxNetAdp adapter,
- * the pbShouldBind already contains the result */
- break;
- }
- else if(hr != S_FALSE)
- {
- /* error occurred */
- break;
- }
-
- /* hr == S_FALSE means this is not a loopback adpater, set it to S_OK */
- hr = S_OK;
-
-// if(!(fCharacteristics & NCF_PHYSICAL))
-// {
-// /* we are binding to physical adapters only */
-// *pbShouldBind = false;
-// break;
-// }
-
- hr = vboxNetFltWinNotifyCheckLowerRange(pComponent, pbShouldBind);
- if(hr == S_OK)
- {
- /* the vboxNetFltWinNotifyCheckLowerRange ccucceeded,
- * the pbShouldBind already contains the result */
- break;
- }
- /* we are here because of the fail, nothing else to do */
- } while(0);
-
- TraceMsg(L"<--vboxNetFltWinNotifyShouldBind for INetCfgComponent, hr (0x%x)\n", hr);
-
- return hr;
-}
-
-
-static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgBindingInterface *pIf, OUT bool *pbShouldBind)
-{
- TraceMsg(L"-->vboxNetFltWinNotifyShouldBind for INetCfgBindingInterface\n");
-
- INetCfgComponent * pAdapterComponent;
- HRESULT hr = pIf->GetLowerComponent(&pAdapterComponent);
- if(hr == S_OK)
- {
- hr = vboxNetFltWinNotifyShouldBind(pAdapterComponent, pbShouldBind);
-
- pAdapterComponent->Release();
- }
- else
- {
- TraceMsg(L"vboxNetFltWinNotifyShouldBind: GetLowerComponent failed, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
-
- TraceMsg(L"<--vboxNetFltWinNotifyShouldBind for INetCfgBindingInterface, hr (0x%x)\n", hr);
- return hr;
-}
-
-static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgBindingPath *pPath, OUT bool * pbDoBind)
-{
- TraceMsg(L"-->vboxNetFltWinNotifyShouldBind for INetCfgBindingPath\n");
- IEnumNetCfgBindingInterface *pEnumBindingIf;
- HRESULT hr = pPath->EnumBindingInterfaces(&pEnumBindingIf);
-
- if(hr == S_OK)
- {
- hr = pEnumBindingIf->Reset();
- if(hr == S_OK)
- {
- ULONG ulCount;
- INetCfgBindingInterface *pBindingIf;
-
- do
- {
- hr = pEnumBindingIf->Next( 1,
- &pBindingIf,
- &ulCount );
- if(hr == S_OK)
- {
- hr = vboxNetFltWinNotifyShouldBind(pBindingIf, pbDoBind);
-
- pBindingIf->Release();
-
- if(hr == S_OK)
- {
- if(!(*pbDoBind))
- {
- break;
- }
- }
- else
- {
- /* break on failure */
- break;
- }
- }
- else if(hr == S_FALSE)
- {
- /* no more elements */
- hr = S_OK;
- break;
- }
- else
- {
- TraceMsg(L"vboxNetFltWinNotifyShouldBind: Next failed, hr (0x%x)\n", hr);
- AssertBreakpoint();
- /* break on falure */
- break;
- }
- } while(true);
- }
- else
- {
- TraceMsg(L"vboxNetFltWinNotifyShouldBind: Reset failed, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
-
- pEnumBindingIf->Release();
- }
- else
- {
- TraceMsg(L"vboxNetFltWinNotifyShouldBind: EnumBindingInterfaces failed, hr (0x%x)\n", hr);
- AssertBreakpoint();
- }
-
- TraceMsg(L"<--vboxNetFltWinNotifyShouldBind for INetCfgBindingPath, hr (0x%x)\n", hr);
- return hr;
-}
-
-static bool vboxNetFltWinNotifyShouldBind(IN INetCfgBindingPath *pPath)
-{
-#ifdef VBOXNETFLTNOTIFY_DEBUG_BIND
- return VBOXNETFLTNOTIFY_DEBUG_BIND;
-#else
- HRESULT hr;
- bool bShouldBind;
-
- TraceMsg( L"-->vboxNetFltWinNotifyShouldBind\n");
-
- hr = vboxNetFltWinNotifyShouldBind(pPath, &bShouldBind) ;
- if(hr != S_OK)
- {
- TraceMsg( L"vboxNetFltWinNotifyShouldBind: vboxNetFltWinNotifyShouldBind failed, hr (0x%x)\n", hr );
- bShouldBind = VBOXNETFLTNOTIFY_ONFAIL_BINDDEFAULT;
- }
-
-
- TraceMsg( L"<--vboxNetFltWinNotifyShouldBind, bShouldBind (%d)\n", bShouldBind);
- return bShouldBind;
-#endif
-}
-
-/*
- * INetCfgComponentNotifyBinding
- * The following functions provide the INetCfgComponentNotifyBinding interface.
- */
-
-/**
- * This is specific to the component being installed. This will
- * ask us if we want to bind to the Item being passed into
- * this routine. We can disable the binding by returning
- * NETCFG_S_DISABLE_QUERY
- *
- * @param dwChangeFlag Type of binding change
- * @param pncbpItem Pointer to INetCfgBindingPath object
- * @return S_OK on success, otherwise an error code.
- */
-STDMETHODIMP VBoxNetFltNotify::QueryBindingPath (IN DWORD dwChangeFlag,
- IN INetCfgBindingPath *pPath)
-{
- HRESULT hr = S_OK;
- TraceMsg( L"-->QueryBindingPath, flags (0x%x)\n", dwChangeFlag );
-
- if(!vboxNetFltWinNotifyShouldBind(pPath))
- {
- TraceMsg( L"QueryBindingPath: we are NOT supporting the current component\n");
- hr = NETCFG_S_DISABLE_QUERY;
- }
- else
- {
- TraceMsg( L"QueryBindingPath: we are supporting the current component\n");
- }
- TraceMsg( L"<--QueryBindingPath, hr (0x%x)\n", hr);
- return hr;
-}
-
-/**
- * bind to the component passed to us.
- * @param dwChangeFlag Type of system change
- * @param pncc Pointer to INetCfgComponent object
- * @return S_OK on success, otherwise an error code
- */
-STDMETHODIMP VBoxNetFltNotify::NotifyBindingPath (IN DWORD dwChangeFlag,
- IN INetCfgBindingPath *pPath)
-{
- HRESULT hr = S_OK;
-
- TraceMsg( L"-->NotifyBindingPath, flags (0x%x)\n", dwChangeFlag );
- /* NCN_ADD | NCN_ENABLE
- * NCN_REMOVE | NCN_ENABLE
- * NCN_ADD | NCN_DISABLE
- * NCN_REMOVE | NCN_DISABLE
- * */
- if ( (dwChangeFlag & NCN_ENABLE) && !(dwChangeFlag & NCN_REMOVE))
- {
- if(!vboxNetFltWinNotifyShouldBind(pPath))
- {
- TraceMsg( L"NotifyBindingPath: binding enabled for the component we are not supporting\n");
- AssertBreakpoint();
- hr = NETCFG_S_DISABLE_QUERY;
- }
- }
-
- TraceMsg( L"<--NotifyBindingPath, hr (0x%x)\n", hr);
-
- return hr;
-}
-
-/*
- * DLL Entry Point
- */
-extern "C"
-BOOL WINAPI DllMain (HINSTANCE hInstance,
- DWORD dwReason,
- LPVOID /*lpReserved*/)
-{
- TraceMsg( L"-->DllMain.\n");
-
- if (dwReason == DLL_PROCESS_ATTACH) {
-
- TraceMsg( L" Reason: Attach.\n");
-
- _Module.Init(ObjectMap, hInstance);
-
- DisableThreadLibraryCalls(hInstance);
- }
- else if (dwReason == DLL_PROCESS_DETACH) {
-
- TraceMsg( L" Reason: Detach.\n");
-
- _Module.Term();
- }
-
- TraceMsg( L"<--DllMain.\n");
-
- return TRUE;
-}
-
-/*
- * Used to determine whether the DLL can be unloaded by OLE
- */
-STDAPI DllCanUnloadNow(void)
-{
- HRESULT hr;
-
- TraceMsg( L"-->DllCanUnloadNow.\n");
-
- hr = (_Module.GetLockCount() == 0) ? S_OK : S_FALSE;
-
- TraceMsg( L"<--DllCanUnloadNow, hr (0x%x).\n",
- hr );
-
- return hr;
-}
-
-/*
- * Returns a class factory to create an object of the requested type
- */
-STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
-{
- TraceMsg( L"DllGetClassObject.\n");
-
- return _Module.GetClassObject(rclsid, riid, ppv);
-}
-
-
-/*
- * DllRegisterServer - Adds entries to the system registry
- */
-STDAPI DllRegisterServer(void)
-{
- /* Registers object, typelib and all interfaces in typelib */
-
- TraceMsg( L"DllRegisterServer.\n");
-
- return _Module.RegisterServer(TRUE);
-}
-
-/*
- * DllUnregisterServer - Removes entries from the system registry
- */
-STDAPI DllUnregisterServer(void)
-{
- TraceMsg( L"DllUnregisterServer.\n");
- _Module.UnregisterServer(TRUE);
- return S_OK;
-}
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.def b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.def
deleted file mode 100644
index a45750ce7..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.def
+++ /dev/null
@@ -1,6 +0,0 @@
-LIBRARY VBOXNETFLTNOTIFY
-EXPORTS
- DllCanUnloadNow PRIVATE
- DllGetClassObject PRIVATE
- DllRegisterServer PRIVATE
- DllUnregisterServer PRIVATE
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h
deleted file mode 100644
index ae772727c..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-/*
- * Based in part on Microsoft DDK sample code for Sample Notify Object
- *+---------------------------------------------------------------------------
- *
- * Microsoft Windows
- * Copyright (C) Microsoft Corporation, 1992-2001.
- *
- * Author: Alok Sinha
- *
- *----------------------------------------------------------------------------
- */
-#ifndef ___VboxNetFltNotify_h___
-#define ___VboxNetFltNotify_h___
-
-#include <windows.h>
-#include <atlbase.h>
-extern CComModule _Module; // required by atlcom.h
-#include <atlcom.h>
-#include <VBoxNetFltNotifyn.h>
-//#include <Netcfgx.h>
-
-#include "VBoxNetFltNotifyRc.h"
-
-#define VBOXNETFLTNOTIFY_ONFAIL_BINDDEFAULT false
-
-/*
- * VboxNetFlt Notify Object used to control bindings
- */
-class VBoxNetFltNotify :
-
- /*
- * Must inherit from CComObjectRoot(Ex) for reference count
- * management and default threading model.
- */
- public CComObjectRoot,
-
- /*
- * Define the default class factory and aggregation model.
- */
- public CComCoClass<VBoxNetFltNotify, &CLSID_VBoxNetFltNotify>,
-
- /*
- * Notify Object's interfaces.
- */
- public INetCfgComponentControl,
- public INetCfgComponentNotifyBinding
-{
-
- /*
- * Public members.
- */
- public:
-
- /*
- * Constructor
- */
- VBoxNetFltNotify(VOID);
-
- /*
- * Destructors.
- */
- ~VBoxNetFltNotify(VOID);
-
- /*
- * Notify Object's interfaces.
- */
- BEGIN_COM_MAP(VBoxNetFltNotify)
- COM_INTERFACE_ENTRY(INetCfgComponentControl)
-// COM_INTERFACE_ENTRY(INetCfgComponentSetup)
-// COM_INTERFACE_ENTRY(INetCfgComponentPropertyUi)
- COM_INTERFACE_ENTRY(INetCfgComponentNotifyBinding)
-// COM_INTERFACE_ENTRY(INetCfgComponentNotifyGlobal)
- END_COM_MAP()
-
- /*
- * Uncomment the the line below if you don't want your object to
- * support aggregation. The default is to support it
- *
- * DECLARE_NOT_AGGREGATABLE(CMuxNotify)
- */
-
- DECLARE_REGISTRY_RESOURCEID(IDR_REG_VBOXNETFLT_NOTIFY)
-
- /*
- * INetCfgComponentControl
- */
- STDMETHOD (Initialize) (
- IN INetCfgComponent *pIComp,
- IN INetCfg *pINetCfg,
- IN BOOL fInstalling);
-
- STDMETHOD (CancelChanges) ();
-
- STDMETHOD (ApplyRegistryChanges) ();
-
- STDMETHOD (ApplyPnpChanges) (
- IN INetCfgPnpReconfigCallback* pICallback);
-
- /*
- * INetCfgNotifyBinding
- */
- STDMETHOD (QueryBindingPath) (
- IN DWORD dwChangeFlag,
- IN INetCfgBindingPath* pncbp);
-
- STDMETHOD (NotifyBindingPath) (
- IN DWORD dwChangeFlag,
- IN INetCfgBindingPath* pncbp);
-
- /*
- * Private members.
- */
- private:
-
- /*
- * Private member variables.
- */
- INetCfgComponent *m_pncc; /* Our Protocol's Net Config component */
- INetCfg *m_pnc;
-};
-
-#endif
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyRc.h b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyRc.h
deleted file mode 100644
index 1703bbe6a..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyRc.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef ___VboxNetFltNotifyRc_h___
-#define ___VboxNetFltNotifyRc_h___
-
-#define IDR_REG_VBOXNETFLT_NOTIFY 40001
-
-#endif
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/tools/Makefile.kup b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/Makefile.kup
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/Makefile.kup
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpInstall.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetAdpInstall.cpp
index 5c3783c3c..a836cf023 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpInstall.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetAdpInstall.cpp
@@ -1,4 +1,4 @@
-/* $Id: NetAdpInstall.cpp $ */
+/* $Id: VBoxNetAdpInstall.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */
/** @file
* NetAdpInstall - VBoxNetAdp installer command line tool
*/
@@ -15,17 +15,17 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include <vbox/WinNetConfig.h>
+#include <VBox/VBoxNetCfg-win.h>
#include <stdio.h>
#define VBOX_NETADP_INF L".\\VBoxNetAdp.inf"
-static VOID winNetCfgLogger (LPCWSTR szString)
+static VOID winNetCfgLogger (LPCSTR szString)
{
- wprintf(L"%s", szString);
+ printf("%s", szString);
}
-static int InstallNetAdp()
+static int VBoxNetAdpInstall()
{
int r = 1;
VBoxNetCfgWinSetLogging(winNetCfgLogger);
@@ -33,13 +33,9 @@ static int InstallNetAdp()
HRESULT hr = CoInitialize(NULL);
if(hr == S_OK)
{
-#ifndef DEBUG_misha
+#if 0 //ndef DEBUG_misha
printf("not implemented yet, please use device manager for Host-Only net interface installation.. sorry :( \n");
#else
- /* this installs the Net Adp from the pre-installed driver package,
- * it does NOT install the new driver package, so the installation might use old drivers
- * or fail in case no NetAdp package is currently installed
- * the code is here for debugging NetAdp installation only */
GUID guid;
BSTR name, errMsg;
printf("adding host-only interface..\n");
@@ -99,5 +95,5 @@ static int InstallNetAdp()
int __cdecl main(int argc, char **argv)
{
- return InstallNetAdp();
+ return VBoxNetAdpInstall();
}
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpUninstall.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetAdpUninstall.cpp
index deb31779a..63e6772c0 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpUninstall.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetAdpUninstall.cpp
@@ -1,4 +1,4 @@
-/* $Id: NetAdpUninstall.cpp $ */
+/* $Id: VBoxNetAdpUninstall.cpp 36487 2011-04-01 08:21:30Z vboxsync $ */
/** @file
* NetAdpUninstall - VBoxNetAdp uninstaller command line tool
*/
@@ -15,18 +15,19 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include <vbox/WinNetConfig.h>
+#include <VBox/VBoxNetCfg-win.h>
+#include <VBox/VBoxDrvCfg-win.h>
#include <stdio.h>
#include <devguid.h>
-static VOID winNetCfgLogger (LPCWSTR szString)
+static VOID winNetCfgLogger (LPCSTR szString)
{
- wprintf(L"%s", szString);
+ printf("%s", szString);
}
-static int UninstallNetAdp()
+static int VBoxNetAdpUninstall()
{
int r = 1;
VBoxNetCfgWinSetLogging(winNetCfgLogger);
@@ -39,7 +40,7 @@ static int UninstallNetAdp()
hr = VBoxNetCfgWinRemoveAllNetDevicesOfId(L"sun_VBoxNetAdp");
if(hr == S_OK)
{
- hr = VBoxNetCfgWinUninstallInfs (&GUID_DEVCLASS_NET, L"sun_VBoxNetAdp", 0/* could be SUOI_FORCEDELETE */);
+ hr = VBoxDrvCfgInfUninstallAllSetupDi(&GUID_DEVCLASS_NET, L"Net", L"sun_VBoxNetAdp", 0/* could be SUOI_FORCEDELETE */);
if(hr == S_OK)
{
printf("uninstalled successfully\n");
@@ -69,5 +70,5 @@ static int UninstallNetAdp()
int __cdecl main(int argc, char **argv)
{
- return UninstallNetAdp();
+ return VBoxNetAdpUninstall();
}
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltInstall.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetFltInstall.cpp
index 44cebbb17..3ce13ab90 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltInstall.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetFltInstall.cpp
@@ -1,4 +1,4 @@
-/* $Id: NetFltInstall.cpp $ */
+/* $Id: VBoxNetFltInstall.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */
/** @file
* NetFltInstall - VBoxNetFlt installer command line tool
*/
@@ -15,20 +15,20 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include <vbox/WinNetConfig.h>
+#include <VBox/VBoxNetCfg-win.h>
#include <devguid.h>
#include <stdio.h>
-#define NETFLT_ID L"sun_VBoxNetFlt"
+#define NETFLT_ID L"sun_VBoxNetFlt"
#define VBOX_NETCFG_APP_NAME L"NetFltInstall"
#define VBOX_NETFLT_PT_INF L".\\VBoxNetFlt.inf"
-#define VBOX_NETFLT_MP_INF L".\\VBoxNetFlt_m.inf"
+#define VBOX_NETFLT_MP_INF L".\\VBoxNetFltM.inf"
#define VBOX_NETFLT_RETRIES 10
-static VOID winNetCfgLogger (LPCWSTR szString)
+static VOID winNetCfgLogger (LPCSTR szString)
{
- wprintf(L"%s", szString);
+ printf("%s", szString);
}
/** Wrapper around GetfullPathNameW that will try an alternative INF location.
@@ -40,7 +40,7 @@ static VOID winNetCfgLogger (LPCWSTR szString)
static DWORD MyGetfullPathNameW(LPCWSTR pwszName, size_t cchFull, LPWSTR pwszFull)
{
LPWSTR pwszFilePart;
- DWORD dwSize = GetFullPathNameW(pwszName, cchFull, pwszFull, &pwszFilePart);
+ DWORD dwSize = GetFullPathNameW(pwszName, (DWORD)cchFull, pwszFull, &pwszFilePart);
if(dwSize <= 0)
return dwSize;
@@ -59,9 +59,8 @@ static DWORD MyGetfullPathNameW(LPCWSTR pwszName, size_t cchFull, LPWSTR pwszFul
wsz[cch] = pwszFilePart[i++];
if(!wsz[cch])
{
- dwSize = GetFullPathNameW(wsz, cchFull, pwszFull, NULL);
- if( dwSize > 0
- && GetFileAttributesW(pwszFull) != INVALID_FILE_ATTRIBUTES)
+ dwSize = GetFullPathNameW(wsz, (DWORD)cchFull, pwszFull, NULL);
+ if(dwSize > 0 && GetFileAttributesW(pwszFull) != INVALID_FILE_ATTRIBUTES)
return dwSize;
break;
}
@@ -71,10 +70,10 @@ static DWORD MyGetfullPathNameW(LPCWSTR pwszName, size_t cchFull, LPWSTR pwszFul
}
/* fallback */
- return GetFullPathNameW(pwszName, cchFull, pwszFull, NULL);
+ return GetFullPathNameW(pwszName, (DWORD)cchFull, pwszFull, NULL);
}
-static int InstallNetFlt()
+static int VBoxNetFltInstall()
{
WCHAR PtInf[MAX_PATH];
WCHAR MpInf[MAX_PATH];
@@ -90,7 +89,7 @@ static int InstallNetFlt()
int i = 0;
do
{
- hr = VBoxNetCfgWinQueryINetCfg(TRUE, VBOX_NETCFG_APP_NAME, &pnc, &lpszLockedBy);
+ hr = VBoxNetCfgWinQueryINetCfg(&pnc, TRUE, VBOX_NETCFG_APP_NAME, 10000, &lpszLockedBy);
if(hr == S_OK)
{
DWORD dwSize;
@@ -118,13 +117,13 @@ static int InstallNetFlt()
}
else
{
- hr = HRESULT_FROM_WIN32(GetLastError());
- wprintf(L"error getting full inf path for VBoxNetFlt_m.inf (0x%x)\n", hr);
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ wprintf(L"error getting full inf path for VBoxNetFltM.inf (0x%x)\n", hr);
}
}
else
{
- hr = HRESULT_FROM_WIN32(GetLastError());
+ hr = HRESULT_FROM_WIN32(GetLastError());
wprintf(L"error getting full inf path for VBoxNetFlt.inf (0x%x)\n", hr);
}
@@ -170,5 +169,5 @@ static int InstallNetFlt()
int __cdecl main(int argc, char **argv)
{
- return InstallNetFlt();
+ return VBoxNetFltInstall();
}
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltUninstall.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetFltUninstall.cpp
index 03dfa66ae..710db34ab 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltUninstall.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetFltUninstall.cpp
@@ -1,4 +1,4 @@
-/* $Id: NetFltUninstall.cpp $ */
+/* $Id: VBoxNetFltUninstall.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */
/** @file
* NetFltUninstall - VBoxNetFlt uninstaller command line tool
*/
@@ -15,21 +15,21 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include <vbox/WinNetConfig.h>
+#include <VBox/VBoxNetCfg-win.h>
#include <stdio.h>
-#define NETFLT_ID L"sun_VBoxNetFlt"
+#define NETFLT_ID L"sun_VBoxNetFlt"
#define VBOX_NETCFG_APP_NAME L"NetFltUninstall"
#define VBOX_NETFLT_PT_INF L".\\VBoxNetFlt.inf"
-#define VBOX_NETFLT_MP_INF L".\\VBoxNetFlt_m.inf"
+#define VBOX_NETFLT_MP_INF L".\\VBoxNetFltM.inf"
#define VBOX_NETFLT_RETRIES 10
-static VOID winNetCfgLogger (LPCWSTR szString)
+static VOID winNetCfgLogger (LPCSTR szString)
{
- wprintf(L"%s", szString);
+ printf("%s", szString);
}
-static int UninstallNetFlt()
+static int VBoxNetFltUninstall()
{
INetCfg *pnc;
LPWSTR lpszLockedBy = NULL;
@@ -43,7 +43,7 @@ static int UninstallNetFlt()
int i = 0;
do
{
- hr = VBoxNetCfgWinQueryINetCfg(TRUE, VBOX_NETCFG_APP_NAME, &pnc, &lpszLockedBy);
+ hr = VBoxNetCfgWinQueryINetCfg(&pnc, TRUE, VBOX_NETCFG_APP_NAME, 10000, &lpszLockedBy);
if(hr == S_OK)
{
hr = VBoxNetCfgWinNetFltUninstall(pnc);
@@ -99,5 +99,5 @@ static int UninstallNetFlt()
int __cdecl main(int argc, char **argv)
{
- return UninstallNetFlt();
+ return VBoxNetFltUninstall();
}
diff --git a/src/VBox/HostDrivers/VBoxPci/Makefile.kmk b/src/VBox/HostDrivers/VBoxPci/Makefile.kmk
new file mode 100644
index 000000000..ab43b88a8
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxPci/Makefile.kmk
@@ -0,0 +1,78 @@
+SUB_DEPTH = ../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+ifeq (1,1)
+
+if1of ($(KBUILD_TARGET), linux)
+
+SYSMODS += VBoxPci
+VBoxPci_TEMPLATE = VBOXR0DRV
+VBoxPci_INST = $(INST_VBOXPCI)$(if $(eq $(KBUILD_TARGET),darwin),Contents/MacOS/)
+VBoxPci_NAME.linux = vboxpci
+VBoxPci_NOINST.linux = true
+VBoxPci_DEFS = IN_RT_R0 VBOX_SVN_REV=$(VBOX_SVN_REV) IN_SUP_STATIC
+VBoxPci_DEFS.linux = KBUILD_MODNAME=KBUILD_STR\(vboxpci\) KBUILD_BASENAME=KBUILD_STR\(vboxpci\) MODULE
+VBoxPci_INCS.linux := \
+ $(PATH_ROOT)/src/VBox/Runtime/r0drv/linux
+VBoxPci_INCS = \
+ .
+VBoxPci_SOURCES.linux = \
+ linux/VBoxPci-linux.c \
+ VBoxPci.c
+VBoxPci_SOURCES =
+VBoxPci_LIBS += \
+ $(PATH_LIB)/SUPR0IdcClient$(VBOX_SUFF_LIB)
+
+endif
+
+
+ifeq ($(KBUILD_TARGET),linux)
+
+ include $(PATH_SUB_CURRENT)/linux/files_vboxpci
+
+ INSTALLS += VBoxPci-src VBoxPci-sh
+
+ VBoxPci-src_INST = bin/src/vboxpci/
+ VBoxPci-src_MODE = a+r,u+w
+ VBoxPci-src_SOURCES = $(subst ",,$(VBOX_VBOXPCI_SOURCES)) #"
+ VBoxPci-src_SOURCES+= \
+ $(VBoxPci-src_0_OUTDIR)/Makefile
+ VBoxPci-src_CLEAN = \
+ $(VBoxPci-src_0_OUTDIR)/Makefile \
+ $(PATH_TARGET)/VBoxPciSrc-src-1.dep
+
+ VBoxPci-sh_INST = bin/src/vboxpci/
+ VBoxPci-sh_MODE = a+rx,u+w
+ VBoxPci-sh_SOURCES = \
+ $(VBoxPci-sh_0_OUTDIR)/build_in_tmp \
+ $(PATH_ROOT)/src/VBox/HostDrivers/linux/do_Module.symvers
+ VBoxPci-sh_CLEAN = $(VBoxPci-sh_0_OUTDIR)/build_in_tmp
+
+
+includedep $(PATH_TARGET)/VBoxPci-src-1.dep
+$$(VBoxPci-src_0_OUTDIR)/Makefile: \
+ $(PATH_SUB_CURRENT)/linux/Makefile \
+ $$(if $$(eq $$(VBoxPci/linux/Makefile_VBOX_HARDENED),$$(VBOX_WITH_HARDENING)),,FORCE) \
+ | $$(dir $$@)
+ifndef VBOX_WITH_HARDENING
+ $(QUIET)$(SED) -e "s;-DVBOX_WITH_HARDENING;;g" --output $@ $<
+else
+ $(QUIET)$(CP) -f $< $@
+endif
+ %$(QUIET2)$(RM) -f -- $(PATH_TARGET)/VBoxPci-src-1.dep
+ %$(QUIET2)$(APPEND) '$(PATH_TARGET)/VBoxPci-src-1.dep' 'VBoxPci/linux/Makefile_VBOX_HARDENED=$(VBOX_WITH_HARDENING)'
+
+## Scripts needed for building the kernel modules
+
+$$(VBoxPci-sh_0_OUTDIR)/build_in_tmp: \
+ $(PATH_ROOT)/src/VBox/HostDrivers/linux/build_in_tmp \
+ $(VBOX_VERSION_STAMP) \
+ | $$(dir $$@)
+ $(call MSG_TOOL,Creating,,$@)
+ $(QUIET)$(SED) -e "s;_VERSION_;${VBOX_VERSION_STRING};g; s;_MODULE_;vboxpci;g; s;_BUILDTYPE_;${KBUILD_TYPE};g" --output $@ $<
+ $(QUIET)chmod 0755 $@
+endif
+
+endif
+
+include $(KBUILD_PATH)/subfooter.kmk
diff --git a/src/VBox/HostDrivers/VBoxPci/VBoxPci.c b/src/VBox/HostDrivers/VBoxPci/VBoxPci.c
new file mode 100644
index 000000000..7bea5706e
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxPci/VBoxPci.c
@@ -0,0 +1,791 @@
+/* $Id $ */
+/** @file
+ * VBoxPci - PCI card passthrough support (Host), Common Code.
+ */
+
+/*
+ * 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.
+ */
+
+/** @page pg_rawpci VBoxPci - host PCI support
+ *
+ * This is a kernel module that works as host proxy between guest and
+ * PCI hardware.
+ *
+ */
+
+#define LOG_GROUP LOG_GROUP_DEV_PCI_RAW
+#include <VBox/log.h>
+#include <VBox/err.h>
+#include <VBox/sup.h>
+#include <VBox/version.h>
+
+#include <iprt/string.h>
+#include <iprt/assert.h>
+#include <iprt/spinlock.h>
+#include <iprt/uuid.h>
+#include <iprt/asm.h>
+#include <iprt/mem.h>
+
+#include "VBoxPciInternal.h"
+
+
+#define DEVPORT_2_VBOXRAWPCIINS(pPort) \
+ ( (PVBOXRAWPCIINS)((uint8_t *)pPort - RT_OFFSETOF(VBOXRAWPCIINS, DevPort)) )
+
+
+/**
+ * Implements the SUPDRV component factor interface query method.
+ *
+ * @returns Pointer to an interface. NULL if not supported.
+ *
+ * @param pSupDrvFactory Pointer to the component factory registration structure.
+ * @param pSession The session - unused.
+ * @param pszInterfaceUuid The factory interface id.
+ */
+static DECLCALLBACK(void *) vboxPciQueryFactoryInterface(PCSUPDRVFACTORY pSupDrvFactory, PSUPDRVSESSION pSession, const char *pszInterfaceUuid)
+{
+ PVBOXRAWPCIGLOBALS pGlobals = (PVBOXRAWPCIGLOBALS)((uint8_t *)pSupDrvFactory - RT_OFFSETOF(VBOXRAWPCIGLOBALS, SupDrvFactory));
+
+ /*
+ * Convert the UUID strings and compare them.
+ */
+ RTUUID UuidReq;
+ int rc = RTUuidFromStr(&UuidReq, pszInterfaceUuid);
+ if (RT_SUCCESS(rc))
+ {
+ if (!RTUuidCompareStr(&UuidReq, RAWPCIFACTORY_UUID_STR))
+ {
+ ASMAtomicIncS32(&pGlobals->cFactoryRefs);
+ return &pGlobals->RawPciFactory;
+ }
+ }
+ else
+ Log(("VBoxRawPci: rc=%Rrc, uuid=%s\n", rc, pszInterfaceUuid));
+
+ return NULL;
+}
+DECLINLINE(int) vboxPciDevLock(PVBOXRAWPCIINS pThis,
+ PRTSPINLOCKTMP pTmp)
+{
+#ifdef VBOX_WITH_SHARED_PCI_INTERRUPTS
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, pTmp);
+ return VINF_SUCCESS;
+#else
+ int rc = RTSemFastMutexRequest(pThis->hFastMtx);
+
+ NOREF(pTmp);
+ AssertRC(rc);
+ return rc;
+#endif
+}
+
+DECLINLINE(void) vboxPciDevUnlock(PVBOXRAWPCIINS pThis,
+ PRTSPINLOCKTMP pTmp)
+{
+#ifdef VBOX_WITH_SHARED_PCI_INTERRUPTS
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, pTmp);
+#else
+ NOREF(pTmp);
+ RTSemFastMutexRelease(pThis->hFastMtx);
+#endif
+}
+
+DECLINLINE(int) vboxPciVmLock(PVBOXRAWPCIDRVVM pThis)
+{
+ int rc = RTSemFastMutexRequest(pThis->hFastMtx);
+ AssertRC(rc);
+ return rc;
+}
+
+DECLINLINE(void) vboxPciVmUnlock(PVBOXRAWPCIDRVVM pThis)
+{
+ RTSemFastMutexRelease(pThis->hFastMtx);
+}
+
+DECLINLINE(int) vboxPciGlobalsLock(PVBOXRAWPCIGLOBALS pGlobals)
+{
+ int rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
+ AssertRC(rc);
+ return rc;
+}
+
+DECLINLINE(void) vboxPciGlobalsUnlock(PVBOXRAWPCIGLOBALS pGlobals)
+{
+ RTSemFastMutexRelease(pGlobals->hFastMtx);
+}
+
+static PVBOXRAWPCIINS vboxPciFindInstanceLocked(PVBOXRAWPCIGLOBALS pGlobals, uint32_t iHostAddress)
+{
+ PVBOXRAWPCIINS pCur;
+ for (pCur = pGlobals->pInstanceHead; pCur != NULL; pCur = pCur->pNext)
+ {
+ if (iHostAddress == pCur->HostPciAddress)
+ return pCur;
+ }
+ return NULL;
+}
+
+static void vboxPciUnlinkInstanceLocked(PVBOXRAWPCIGLOBALS pGlobals, PVBOXRAWPCIINS pToUnlink)
+{
+ if (pGlobals->pInstanceHead == pToUnlink)
+ pGlobals->pInstanceHead = pToUnlink->pNext;
+ else
+ {
+ PVBOXRAWPCIINS pCur;
+ for (pCur = pGlobals->pInstanceHead; pCur != NULL; pCur = pCur->pNext)
+ {
+ if (pCur->pNext == pToUnlink)
+ {
+ pCur->pNext = pToUnlink->pNext;
+ break;
+ }
+ }
+ }
+ pToUnlink->pNext = NULL;
+}
+
+
+DECLHIDDEN(void) vboxPciDevCleanup(PVBOXRAWPCIINS pThis)
+{
+ pThis->DevPort.pfnDeinit(&pThis->DevPort, 0);
+
+ if (pThis->hFastMtx)
+ {
+ RTSemFastMutexDestroy(pThis->hFastMtx);
+ pThis->hFastMtx = NIL_RTSEMFASTMUTEX;
+ }
+
+ if (pThis->hSpinlock)
+ {
+ RTSpinlockDestroy(pThis->hSpinlock);
+ pThis->hSpinlock = NIL_RTSPINLOCK;
+ }
+
+ vboxPciGlobalsLock(pThis->pGlobals);
+ vboxPciUnlinkInstanceLocked(pThis->pGlobals, pThis);
+ vboxPciGlobalsUnlock(pThis->pGlobals);
+}
+
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnInit
+ */
+static DECLCALLBACK(int) vboxPciDevInit(PRAWPCIDEVPORT pPort, uint32_t fFlags)
+{
+ PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
+ int rc;
+ RTSPINLOCKTMP aTmp;
+
+ vboxPciDevLock(pThis, &aTmp);
+
+ rc = vboxPciOsDevInit(pThis, fFlags);
+
+ vboxPciDevUnlock(pThis, &aTmp);
+
+ return rc;
+}
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnDeinit
+ */
+static DECLCALLBACK(int) vboxPciDevDeinit(PRAWPCIDEVPORT pPort, uint32_t fFlags)
+{
+ PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
+ int rc;
+ RTSPINLOCKTMP aTmp;
+
+ vboxPciDevLock(pThis, &aTmp);
+
+ if (pThis->IrqHandler.pfnIrqHandler)
+ {
+ vboxPciOsDevUnregisterIrqHandler(pThis, pThis->IrqHandler.iHostIrq);
+ pThis->IrqHandler.iHostIrq = 0;
+ pThis->IrqHandler.pfnIrqHandler = NULL;
+ }
+
+ rc = vboxPciOsDevDeinit(pThis, fFlags);
+
+ vboxPciDevUnlock(pThis, &aTmp);
+
+ return rc;
+}
+
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnDestroy
+ */
+static DECLCALLBACK(int) vboxPciDevDestroy(PRAWPCIDEVPORT pPort)
+{
+ PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
+ int rc;
+
+ rc = vboxPciOsDevDestroy(pThis);
+ if (rc == VINF_SUCCESS)
+ {
+ if (pThis->hFastMtx)
+ {
+ RTSemFastMutexDestroy(pThis->hFastMtx);
+ pThis->hFastMtx = NIL_RTSEMFASTMUTEX;
+ }
+
+ if (pThis->hSpinlock)
+ {
+ RTSpinlockDestroy(pThis->hSpinlock);
+ pThis->hSpinlock = NIL_RTSPINLOCK;
+ }
+
+ vboxPciGlobalsLock(pThis->pGlobals);
+ vboxPciUnlinkInstanceLocked(pThis->pGlobals, pThis);
+ vboxPciGlobalsUnlock(pThis->pGlobals);
+
+ RTMemFree(pThis);
+ }
+
+ return rc;
+}
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnGetRegionInfo
+ */
+static DECLCALLBACK(int) vboxPciDevGetRegionInfo(PRAWPCIDEVPORT pPort,
+ int32_t iRegion,
+ RTHCPHYS *pRegionStart,
+ uint64_t *pu64RegionSize,
+ bool *pfPresent,
+ uint32_t *pfFlags)
+{
+ PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
+ int rc;
+ RTSPINLOCKTMP aTmp;
+
+ vboxPciDevLock(pThis, &aTmp);
+
+ rc = vboxPciOsDevGetRegionInfo(pThis, iRegion,
+ pRegionStart, pu64RegionSize,
+ pfPresent, pfFlags);
+ vboxPciDevUnlock(pThis, &aTmp);
+
+ return rc;
+}
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnMapRegion
+ */
+static DECLCALLBACK(int) vboxPciDevMapRegion(PRAWPCIDEVPORT pPort,
+ int32_t iRegion,
+ RTHCPHYS RegionStart,
+ uint64_t u64RegionSize,
+ int32_t fFlags,
+ RTR0PTR *pRegionBase)
+{
+ PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
+ int rc;
+ RTSPINLOCKTMP aTmp;
+
+ vboxPciDevLock(pThis, &aTmp);
+
+ rc = vboxPciOsDevMapRegion(pThis, iRegion, RegionStart, u64RegionSize, fFlags, pRegionBase);
+
+ vboxPciDevUnlock(pThis, &aTmp);
+
+ return rc;
+}
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnUnapRegion
+ */
+static DECLCALLBACK(int) vboxPciDevUnmapRegion(PRAWPCIDEVPORT pPort,
+ int32_t iRegion,
+ RTHCPHYS RegionStart,
+ uint64_t u64RegionSize,
+ RTR0PTR RegionBase)
+{
+ PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
+ int rc;
+ RTSPINLOCKTMP aTmp;
+
+ vboxPciDevLock(pThis, &aTmp);
+
+ rc = vboxPciOsDevUnmapRegion(pThis, iRegion, RegionStart, u64RegionSize, RegionBase);
+
+ vboxPciDevUnlock(pThis, &aTmp);
+
+ return rc;
+}
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnPciCfgRead
+ */
+static DECLCALLBACK(int) vboxPciDevPciCfgRead(PRAWPCIDEVPORT pPort,
+ uint32_t Register,
+ PCIRAWMEMLOC *pValue)
+{
+ PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
+ RTSPINLOCKTMP aTmp;
+ int rc;
+
+ vboxPciDevLock(pThis, &aTmp);
+
+ rc = vboxPciOsDevPciCfgRead(pThis, Register, pValue);
+
+ vboxPciDevUnlock(pThis, &aTmp);
+
+ return rc;
+}
+
+/**
+ * @copydoc RAWPCIDEVPORT:: pfnPciCfgWrite
+ */
+static DECLCALLBACK(int) vboxPciDevPciCfgWrite(PRAWPCIDEVPORT pPort,
+ uint32_t Register,
+ PCIRAWMEMLOC *pValue)
+{
+ PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
+ int rc;
+ RTSPINLOCKTMP aTmp;
+
+ vboxPciDevLock(pThis, &aTmp);
+
+ rc = vboxPciOsDevPciCfgWrite(pThis, Register, pValue);
+
+ vboxPciDevUnlock(pThis, &aTmp);
+
+ return rc;
+}
+
+static DECLCALLBACK(int) vboxPciDevRegisterIrqHandler(PRAWPCIDEVPORT pPort,
+ PFNRAWPCIISR pfnHandler,
+ void* pIrqContext,
+ PCIRAWISRHANDLE *phIsr)
+{
+ PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
+ int rc;
+ int32_t iHostIrq = 0;
+ RTSPINLOCKTMP aTmp;
+
+ if (pfnHandler == NULL)
+ return VERR_INVALID_PARAMETER;
+
+ vboxPciDevLock(pThis, &aTmp);
+
+ if (pThis->IrqHandler.pfnIrqHandler)
+ {
+ rc = VERR_ALREADY_EXISTS;
+ }
+ else
+ {
+ rc = vboxPciOsDevRegisterIrqHandler(pThis, pfnHandler, pIrqContext, &iHostIrq);
+ if (RT_SUCCESS(rc))
+ {
+ *phIsr = 0xcafe0000;
+ pThis->IrqHandler.iHostIrq = iHostIrq;
+ pThis->IrqHandler.pfnIrqHandler = pfnHandler;
+ pThis->IrqHandler.pIrqContext = pIrqContext;
+ }
+ }
+
+ vboxPciDevUnlock(pThis, &aTmp);
+
+ return rc;
+}
+
+static DECLCALLBACK(int) vboxPciDevUnregisterIrqHandler(PRAWPCIDEVPORT pPort,
+ PCIRAWISRHANDLE hIsr)
+{
+ PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
+ int rc;
+ RTSPINLOCKTMP aTmp;
+
+ if (hIsr != 0xcafe0000)
+ return VERR_INVALID_PARAMETER;
+
+ vboxPciDevLock(pThis, &aTmp);
+
+ rc = vboxPciOsDevUnregisterIrqHandler(pThis, pThis->IrqHandler.iHostIrq);
+ if (RT_SUCCESS(rc))
+ {
+ pThis->IrqHandler.pfnIrqHandler = NULL;
+ pThis->IrqHandler.pIrqContext = NULL;
+ pThis->IrqHandler.iHostIrq = 0;
+ }
+ vboxPciDevUnlock(pThis, &aTmp);
+
+ return rc;
+}
+
+static DECLCALLBACK(int) vboxPciDevPowerStateChange(PRAWPCIDEVPORT pPort,
+ PCIRAWPOWERSTATE aState,
+ uint64_t *pu64Param)
+{
+ PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
+ int rc;
+ RTSPINLOCKTMP aTmp;
+
+ vboxPciDevLock(pThis, &aTmp);
+
+ rc = vboxPciOsDevPowerStateChange(pThis, aState);
+
+ switch (aState)
+ {
+ case PCIRAW_POWER_ON:
+ /*
+ * Let virtual device know about VM caps.
+ */
+ *pu64Param = VBOX_DRV_VMDATA(pThis)->pPerVmData->fVmCaps;
+ break;
+ default:
+ pu64Param = 0;
+ break;
+ }
+
+
+ vboxPciDevUnlock(pThis, &aTmp);
+
+ return rc;
+}
+
+/**
+ * Creates a new instance.
+ *
+ * @returns VBox status code.
+ * @param pGlobals The globals.
+ * @param pszName The instance name.
+ * @param ppDevPort Where to store the pointer to our port interface.
+ */
+static int vboxPciNewInstance(PVBOXRAWPCIGLOBALS pGlobals,
+ uint32_t u32HostAddress,
+ uint32_t fFlags,
+ PRAWPCIPERVM pVmCtx,
+ PRAWPCIDEVPORT *ppDevPort,
+ uint32_t *pfDevFlags)
+{
+ int rc;
+ PVBOXRAWPCIINS pNew = (PVBOXRAWPCIINS)RTMemAllocZ(sizeof(*pNew));
+ if (!pNew)
+ return VERR_NO_MEMORY;
+
+ pNew->pGlobals = pGlobals;
+ pNew->hSpinlock = NIL_RTSPINLOCK;
+ pNew->cRefs = 1;
+ pNew->pNext = NULL;
+ pNew->HostPciAddress = u32HostAddress;
+ pNew->pVmCtx = pVmCtx;
+
+ pNew->DevPort.u32Version = RAWPCIDEVPORT_VERSION;
+
+ pNew->DevPort.pfnInit = vboxPciDevInit;
+ pNew->DevPort.pfnDeinit = vboxPciDevDeinit;
+ pNew->DevPort.pfnDestroy = vboxPciDevDestroy;
+ pNew->DevPort.pfnGetRegionInfo = vboxPciDevGetRegionInfo;
+ pNew->DevPort.pfnMapRegion = vboxPciDevMapRegion;
+ pNew->DevPort.pfnUnmapRegion = vboxPciDevUnmapRegion;
+ pNew->DevPort.pfnPciCfgRead = vboxPciDevPciCfgRead;
+ pNew->DevPort.pfnPciCfgWrite = vboxPciDevPciCfgWrite;
+ pNew->DevPort.pfnPciCfgRead = vboxPciDevPciCfgRead;
+ pNew->DevPort.pfnPciCfgWrite = vboxPciDevPciCfgWrite;
+ pNew->DevPort.pfnRegisterIrqHandler = vboxPciDevRegisterIrqHandler;
+ pNew->DevPort.pfnUnregisterIrqHandler = vboxPciDevUnregisterIrqHandler;
+ pNew->DevPort.pfnPowerStateChange = vboxPciDevPowerStateChange;
+ pNew->DevPort.u32VersionEnd = RAWPCIDEVPORT_VERSION;
+
+ rc = RTSpinlockCreate(&pNew->hSpinlock);
+
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTSemFastMutexCreate(&pNew->hFastMtx);
+ if (RT_SUCCESS(rc))
+ {
+ rc = pNew->DevPort.pfnInit(&pNew->DevPort, fFlags);
+ if (RT_SUCCESS(rc))
+ {
+ *ppDevPort = &pNew->DevPort;
+
+ pNew->pNext = pGlobals->pInstanceHead;
+ pGlobals->pInstanceHead = pNew;
+ }
+ else
+ {
+ RTSemFastMutexDestroy(pNew->hFastMtx);
+ RTSpinlockDestroy(pNew->hSpinlock);
+ RTMemFree(pNew);
+ }
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * @copydoc RAWPCIFACTORY::pfnCreateAndConnect
+ */
+static DECLCALLBACK(int) vboxPciFactoryCreateAndConnect(PRAWPCIFACTORY pFactory,
+ uint32_t u32HostAddress,
+ uint32_t fFlags,
+ PRAWPCIPERVM pVmCtx,
+ PRAWPCIDEVPORT *ppDevPort,
+ uint32_t *pfDevFlags)
+{
+ PVBOXRAWPCIGLOBALS pGlobals = (PVBOXRAWPCIGLOBALS)((uint8_t *)pFactory - RT_OFFSETOF(VBOXRAWPCIGLOBALS, RawPciFactory));
+ int rc;
+
+ LogFlow(("vboxPciFactoryCreateAndConnect: PCI=%x fFlags=%#x\n", u32HostAddress, fFlags));
+ Assert(pGlobals->cFactoryRefs > 0);
+ rc = vboxPciGlobalsLock(pGlobals);
+ AssertRCReturn(rc, rc);
+
+ /* First search if there's no existing instance with same host device
+ * address - if so - we cannot continue.
+ */
+ if (vboxPciFindInstanceLocked(pGlobals, u32HostAddress) != NULL)
+ {
+ rc = VERR_RESOURCE_BUSY;
+ goto unlock;
+ }
+
+ rc = vboxPciNewInstance(pGlobals, u32HostAddress, fFlags, pVmCtx, ppDevPort, pfDevFlags);
+
+unlock:
+ vboxPciGlobalsUnlock(pGlobals);
+
+ return rc;
+}
+
+/**
+ * @copydoc RAWPCIFACTORY::pfnRelease
+ */
+static DECLCALLBACK(void) vboxPciFactoryRelease(PRAWPCIFACTORY pFactory)
+{
+ PVBOXRAWPCIGLOBALS pGlobals = (PVBOXRAWPCIGLOBALS)((uint8_t *)pFactory - RT_OFFSETOF(VBOXRAWPCIGLOBALS, RawPciFactory));
+
+ int32_t cRefs = ASMAtomicDecS32(&pGlobals->cFactoryRefs);
+ Assert(cRefs >= 0); NOREF(cRefs);
+ LogFlow(("vboxPciFactoryRelease: cRefs=%d (new)\n", cRefs));
+}
+
+/**
+ * @copydoc RAWPCIFACTORY::pfnInitVm
+ */
+static DECLCALLBACK(int) vboxPciFactoryInitVm(PRAWPCIFACTORY pFactory,
+ PVM pVM,
+ PRAWPCIPERVM pVmData)
+{
+ PVBOXRAWPCIDRVVM pThis = (PVBOXRAWPCIDRVVM)RTMemAllocZ(sizeof(VBOXRAWPCIDRVVM));
+ int rc;
+
+ if (!pThis)
+ return VERR_NO_MEMORY;
+
+ rc = RTSemFastMutexCreate(&pThis->hFastMtx);
+ if (RT_SUCCESS(rc))
+ {
+ rc = vboxPciOsInitVm(pThis, pVM, pVmData);
+
+ if (RT_SUCCESS(rc))
+ {
+#ifdef VBOX_WITH_IOMMU
+ /* If IOMMU notification routine in pVmData->pfnContigMemInfo
+ is set - we have functional IOMMU hardware. */
+ if (pVmData->pfnContigMemInfo)
+ pVmData->fVmCaps |= PCIRAW_VMFLAGS_HAS_IOMMU;
+#endif
+ pThis->pPerVmData = pVmData;
+ pVmData->pDriverData = pThis;
+ return VINF_SUCCESS;
+ }
+
+ RTSemFastMutexDestroy(pThis->hFastMtx);
+ pThis->hFastMtx = NIL_RTSEMFASTMUTEX;
+ RTMemFree(pThis);
+ }
+
+ return rc;
+}
+
+/**
+ * @copydoc RAWPCIFACTORY::pfnDeinitVm
+ */
+static DECLCALLBACK(void) vboxPciFactoryDeinitVm(PRAWPCIFACTORY pFactory,
+ PVM pVM,
+ PRAWPCIPERVM pPciData)
+{
+ if (pPciData->pDriverData)
+ {
+ PVBOXRAWPCIDRVVM pThis = (PVBOXRAWPCIDRVVM)pPciData->pDriverData;
+
+#ifdef VBOX_WITH_IOMMU
+ /* If we have IOMMU, need to unmap all guest's physical pages from IOMMU on VM termination. */
+#endif
+
+ vboxPciOsDeinitVm(pThis, pVM);
+
+ if (pThis->hFastMtx)
+ {
+ RTSemFastMutexDestroy(pThis->hFastMtx);
+ pThis->hFastMtx = NIL_RTSEMFASTMUTEX;
+ }
+
+ RTMemFree(pThis);
+ pPciData->pDriverData = NULL;
+ }
+}
+
+
+static bool vboxPciCanUnload(PVBOXRAWPCIGLOBALS pGlobals)
+{
+ int rc = vboxPciGlobalsLock(pGlobals);
+ bool fRc = !pGlobals->pInstanceHead
+ && pGlobals->cFactoryRefs <= 0;
+ vboxPciGlobalsUnlock(pGlobals);
+ AssertRC(rc);
+ return fRc;
+}
+
+
+static int vboxPciInitIdc(PVBOXRAWPCIGLOBALS pGlobals)
+{
+ int rc;
+ Assert(!pGlobals->fIDCOpen);
+
+ /*
+ * Establish a connection to SUPDRV and register our component factory.
+ */
+ rc = SUPR0IdcOpen(&pGlobals->SupDrvIDC, 0 /* iReqVersion = default */, 0 /* iMinVersion = default */, NULL, NULL, NULL);
+ if (RT_SUCCESS(rc))
+ {
+ rc = SUPR0IdcComponentRegisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
+ if (RT_SUCCESS(rc))
+ {
+ pGlobals->fIDCOpen = true;
+ Log(("VBoxRawPci: pSession=%p\n", SUPR0IdcGetSession(&pGlobals->SupDrvIDC)));
+ return rc;
+ }
+
+ /* bail out. */
+ LogRel(("VBoxRawPci: Failed to register component factory, rc=%Rrc\n", rc));
+ SUPR0IdcClose(&pGlobals->SupDrvIDC);
+ }
+
+ return rc;
+}
+
+/**
+ * Try to close the IDC connection to SUPDRV if established.
+ *
+ * @returns VBox status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_WRONG_ORDER if we're busy.
+ *
+ * @param pGlobals Pointer to the globals.
+ */
+DECLHIDDEN(int) vboxPciDeleteIdc(PVBOXRAWPCIGLOBALS pGlobals)
+{
+ int rc;
+
+ Assert(pGlobals->hFastMtx != NIL_RTSEMFASTMUTEX);
+
+ /*
+ * Check before trying to deregister the factory.
+ */
+ if (!vboxPciCanUnload(pGlobals))
+ return VERR_WRONG_ORDER;
+
+ if (!pGlobals->fIDCOpen)
+ rc = VINF_SUCCESS;
+ else
+ {
+ /*
+ * Disconnect from SUPDRV.
+ */
+ rc = SUPR0IdcComponentDeregisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
+ AssertRC(rc);
+ SUPR0IdcClose(&pGlobals->SupDrvIDC);
+ pGlobals->fIDCOpen = false;
+ }
+
+ return rc;
+}
+
+
+/**
+ * Initializes the globals.
+ *
+ * @returns VBox status code.
+ * @param pGlobals Pointer to the globals.
+ */
+DECLHIDDEN(int) vboxPciInitGlobals(PVBOXRAWPCIGLOBALS pGlobals)
+{
+ /*
+ * Initialize the common portions of the structure.
+ */
+ int rc = RTSemFastMutexCreate(&pGlobals->hFastMtx);
+ if (RT_SUCCESS(rc))
+ {
+ pGlobals->pInstanceHead = NULL;
+ pGlobals->RawPciFactory.pfnRelease = vboxPciFactoryRelease;
+ pGlobals->RawPciFactory.pfnCreateAndConnect = vboxPciFactoryCreateAndConnect;
+ pGlobals->RawPciFactory.pfnInitVm = vboxPciFactoryInitVm;
+ pGlobals->RawPciFactory.pfnDeinitVm = vboxPciFactoryDeinitVm;
+ memcpy(pGlobals->SupDrvFactory.szName, "VBoxRawPci", sizeof("VBoxRawPci"));
+ pGlobals->SupDrvFactory.pfnQueryFactoryInterface = vboxPciQueryFactoryInterface;
+ pGlobals->fIDCOpen = false;
+ }
+ return rc;
+}
+
+
+/**
+ * Deletes the globals.
+ *
+ *
+ * @param pGlobals Pointer to the globals.
+ */
+DECLHIDDEN(void) vboxPciDeleteGlobals(PVBOXRAWPCIGLOBALS pGlobals)
+{
+ Assert(!pGlobals->fIDCOpen);
+
+ /*
+ * Release resources.
+ */
+ if (pGlobals->hFastMtx)
+ {
+ RTSemFastMutexDestroy(pGlobals->hFastMtx);
+ pGlobals->hFastMtx = NIL_RTSEMFASTMUTEX;
+ }
+}
+
+
+int vboxPciInit(PVBOXRAWPCIGLOBALS pGlobals)
+{
+
+ /*
+ * Initialize the common portions of the structure.
+ */
+ int rc = vboxPciInitGlobals(pGlobals);
+ if (RT_SUCCESS(rc))
+ {
+ rc = vboxPciInitIdc(pGlobals);
+ if (RT_SUCCESS(rc))
+ return rc;
+
+ /* bail out. */
+ vboxPciDeleteGlobals(pGlobals);
+ }
+
+ return rc;
+}
+
+void vboxPciShutdown(PVBOXRAWPCIGLOBALS pGlobals)
+{
+ int rc = vboxPciDeleteIdc(pGlobals);
+
+ if (RT_SUCCESS(rc))
+ vboxPciDeleteGlobals(pGlobals);
+}
diff --git a/src/VBox/HostDrivers/VBoxPci/VBoxPciInternal.h b/src/VBox/HostDrivers/VBoxPci/VBoxPciInternal.h
new file mode 100644
index 000000000..b52841862
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxPci/VBoxPciInternal.h
@@ -0,0 +1,189 @@
+/* $Id: VBoxPciInternal.h 37423 2011-06-12 18:37:56Z vboxsync $ */
+/** @file
+ * VBoxPci - PCI driver (Host), Internal Header.
+ */
+
+/*
+ * 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 ___VBoPciInternal_h___
+#define ___VBoxPciInternal_h___
+
+#include <VBox/sup.h>
+#include <VBox/rawpci.h>
+#include <iprt/semaphore.h>
+#include <iprt/assert.h>
+
+#ifdef RT_OS_LINUX
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+# define VBOX_WITH_IOMMU
+#endif
+
+#ifdef VBOX_WITH_IOMMU
+#include <linux/errno.h>
+#include <linux/iommu.h>
+#endif
+
+#endif
+
+RT_C_DECLS_BEGIN
+
+/* Forward declaration. */
+typedef struct VBOXRAWPCIGLOBALS *PVBOXRAWPCIGLOBALS;
+typedef struct VBOXRAWPCIDRVVM *PVBOXRAWPCIDRVVM;
+typedef struct VBOXRAWPCIINS *PVBOXRAWPCIINS;
+
+typedef struct VBOXRAWPCIISRDESC
+{
+ /** Handler function. */
+ PFNRAWPCIISR pfnIrqHandler;
+ /** Handler context. */
+ void *pIrqContext;
+ /** Host IRQ. */
+ int32_t iHostIrq;
+} VBOXRAWPCIISRDESC;
+typedef struct VBOXRAWPCIISRDESC *PVBOXRAWPCIISRDESC;
+
+/**
+ * The per-instance data of the VBox raw PCI interface.
+ *
+ * This is data associated with a host PCI card attached to the VM.
+ *
+ */
+typedef struct VBOXRAWPCIINS
+{
+ /** Pointer to the globals. */
+ PVBOXRAWPCIGLOBALS pGlobals;
+
+ /** Mutex protecting device access. */
+ RTSEMFASTMUTEX hFastMtx;
+ /** The spinlock protecting the state variables and device access. */
+ RTSPINLOCK hSpinlock;
+ /** Pointer to the next device in the list. */
+ PVBOXRAWPCIINS pNext;
+ /** Reference count. */
+ uint32_t volatile cRefs;
+
+ /* Host PCI address of this device. */
+ uint32_t HostPciAddress;
+
+#ifdef RT_OS_LINUX
+ struct pci_dev * pPciDev;
+ char szPrevDriver[64];
+#endif
+ bool fMsiUsed;
+ bool fMsixUsed;
+ bool fIommuUsed;
+ bool fPad0;
+
+ /** Port, given to the outside world. */
+ RAWPCIDEVPORT DevPort;
+
+ /** IRQ handler. */
+ VBOXRAWPCIISRDESC IrqHandler;
+
+ /** Pointer to per-VM context in hypervisor data. */
+ PRAWPCIPERVM pVmCtx;
+} VBOXRAWPCIINS;
+
+/**
+ * Per-VM data of the VBox PCI driver. Pointed to by pGVM->rawpci.s.pDriverData.
+ *
+ */
+typedef struct VBOXRAWPCIDRVVM
+{
+ /** Mutex protecting state changes. */
+ RTSEMFASTMUTEX hFastMtx;
+
+#ifdef RT_OS_LINUX
+# ifdef VBOX_WITH_IOMMU
+ /* IOMMU domain. */
+ struct iommu_domain* pIommuDomain;
+# endif
+#endif
+ /* Back pointer to pGVM->rawpci.s. */
+ PRAWPCIPERVM pPerVmData;
+} VBOXRAWPCIDRVVM;
+
+/**
+ * The global data of the VBox PCI driver.
+ *
+ * This contains the bit required for communicating with support driver, VBoxDrv
+ * (start out as SupDrv).
+ */
+typedef struct VBOXRAWPCIGLOBALS
+{
+ /** Mutex protecting the list of instances and state changes. */
+ RTSEMFASTMUTEX hFastMtx;
+
+ /** Pointer to a list of instance data. */
+ PVBOXRAWPCIINS pInstanceHead;
+
+ /** The raw PCI interface factory. */
+ RAWPCIFACTORY RawPciFactory;
+ /** The SUPDRV component factory registration. */
+ SUPDRVFACTORY SupDrvFactory;
+ /** The number of current factory references. */
+ int32_t volatile cFactoryRefs;
+ /** Whether the IDC connection is open or not.
+ * This is only for cleaning up correctly after the separate IDC init on Windows. */
+ bool fIDCOpen;
+ /** The SUPDRV IDC handle (opaque struct). */
+ SUPDRVIDCHANDLE SupDrvIDC;
+#ifdef RT_OS_LINUX
+ bool fPciStubModuleAvail;
+ struct module * pciStubModule;
+#endif
+} VBOXRAWPCIGLOBALS;
+
+DECLHIDDEN(int) vboxPciInit(PVBOXRAWPCIGLOBALS pGlobals);
+DECLHIDDEN(void) vboxPciShutdown(PVBOXRAWPCIGLOBALS pGlobals);
+
+DECLHIDDEN(int) vboxPciOsInitVm(PVBOXRAWPCIDRVVM pThis, PVM pVM, PRAWPCIPERVM pVmData);
+DECLHIDDEN(void) vboxPciOsDeinitVm(PVBOXRAWPCIDRVVM pThis, PVM pVM);
+
+DECLHIDDEN(int) vboxPciOsDevInit (PVBOXRAWPCIINS pIns, uint32_t fFlags);
+DECLHIDDEN(int) vboxPciOsDevDeinit(PVBOXRAWPCIINS pIns, uint32_t fFlags);
+DECLHIDDEN(int) vboxPciOsDevDestroy(PVBOXRAWPCIINS pIns);
+
+DECLHIDDEN(int) vboxPciOsDevGetRegionInfo(PVBOXRAWPCIINS pIns,
+ int32_t iRegion,
+ RTHCPHYS *pRegionStart,
+ uint64_t *pu64RegionSize,
+ bool *pfPresent,
+ uint32_t *pfFlags);
+DECLHIDDEN(int) vboxPciOsDevMapRegion(PVBOXRAWPCIINS pIns,
+ int32_t iRegion,
+ RTHCPHYS pRegionStart,
+ uint64_t u64RegionSize,
+ uint32_t fFlags,
+ RTR0PTR *pRegionBase);
+DECLHIDDEN(int) vboxPciOsDevUnmapRegion(PVBOXRAWPCIINS pIns,
+ int32_t iRegion,
+ RTHCPHYS RegionStart,
+ uint64_t u64RegionSize,
+ RTR0PTR RegionBase);
+
+DECLHIDDEN(int) vboxPciOsDevPciCfgWrite(PVBOXRAWPCIINS pIns, uint32_t Register, PCIRAWMEMLOC *pValue);
+DECLHIDDEN(int) vboxPciOsDevPciCfgRead (PVBOXRAWPCIINS pIns, uint32_t Register, PCIRAWMEMLOC *pValue);
+
+DECLHIDDEN(int) vboxPciOsDevRegisterIrqHandler (PVBOXRAWPCIINS pIns, PFNRAWPCIISR pfnHandler, void* pIrqContext, int32_t *piHostIrq);
+DECLHIDDEN(int) vboxPciOsDevUnregisterIrqHandler(PVBOXRAWPCIINS pIns, int32_t iHostIrq);
+
+DECLHIDDEN(int) vboxPciOsDevPowerStateChange(PVBOXRAWPCIINS pIns, PCIRAWPOWERSTATE aState);
+
+#define VBOX_DRV_VMDATA(pIns) ((PVBOXRAWPCIDRVVM)(pIns->pVmCtx ? pIns->pVmCtx->pDriverData : NULL))
+
+RT_C_DECLS_END
+
+#endif
diff --git a/src/VBox/HostDrivers/VBoxPci/linux/Makefile b/src/VBox/HostDrivers/VBoxPci/linux/Makefile
new file mode 100644
index 000000000..7601e2701
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxPci/linux/Makefile
@@ -0,0 +1,235 @@
+#
+# Makefile for the VirtualBox Linux Host PCI Driver.
+# (For 2.6.x this file must be called 'Makefile'!)
+#
+
+#
+#
+# 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.
+#
+
+#
+# First, figure out which architecture we're targeting and the build type.
+# (We have to support basic cross building (ARCH=i386|x86_64).)
+# While at it, warn about BUILD_* vars found to help with user problems.
+#
+ifeq ($(filter-out x86_64 amd64 AMD64,$(shell uname -m)),)
+ BUILD_TARGET_ARCH_DEF := amd64
+else
+ BUILD_TARGET_ARCH_DEF := x86
+endif
+ifneq ($(filter-out amd64 x86,$(BUILD_TARGET_ARCH)),)
+ $(warning Ignoring unknown BUILD_TARGET_ARCH value '$(BUILD_TARGET_ARCH)'.)
+ BUILD_TARGET_ARCH :=
+endif
+ifeq ($(BUILD_TARGET_ARCH),)
+ ifeq ($(ARCH),x86_64)
+ BUILD_TARGET_ARCH := amd64
+ else
+ ifeq ($(ARCH),i386)
+ BUILD_TARGET_ARCH := x86
+ else
+ BUILD_TARGET_ARCH := $(BUILD_TARGET_ARCH_DEF)
+ endif
+ endif
+else
+ ifneq ($(BUILD_TARGET_ARCH),$(BUILD_TARGET_ARCH_DEF))
+ $(warning Using BUILD_TARGET_ARCH='$(BUILD_TARGET_ARCH)' from the $(origin BUILD_TARGET_ARCH).)
+ endif
+endif
+
+ifneq ($(filter-out release profile debug strict,$(BUILD_TYPE)),)
+ $(warning Ignoring unknown BUILD_TYPE value '$(BUILD_TYPE)'.)
+ BUILD_TYPE :=
+endif
+ifeq ($(BUILD_TYPE),)
+ BUILD_TYPE := release
+else
+ ifneq ($(BUILD_TYPE),release)
+ $(warning Using BUILD_TYPE='$(BUILD_TYPE)' from the $(origin BUILD_TYPE).)
+ endif
+endif
+
+# override is required by the Debian guys
+override MODULE = vboxpci
+OBJS = \
+ linux/VBoxPci-linux.o \
+ VBoxPci.o \
+ SUPR0IdcClient.o \
+ SUPR0IdcClientComponent.o \
+ linux/SUPR0IdcClient-linux.o
+
+ifeq ($(BUILD_TARGET_ARCH),x86)
+OBJS += math/gcc/divdi3.o \
+ math/gcc/moddi3.o \
+ math/gcc/qdivrem.o \
+ math/gcc/udivdi3.o \
+ math/gcc/divdi3.o \
+ math/gcc/umoddi3.o
+endif
+
+ifneq ($(MAKECMDGOALS),clean)
+
+ifeq ($(KERNELRELEASE),)
+
+ #
+ # building from this directory
+ #
+
+ # kernel base directory
+ ifndef KERN_DIR
+ # build for the current kernel, version check
+ KERN_DIR := /lib/modules/$(shell uname -r)/build
+ ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
+ KERN_DIR := /usr/src/linux
+ ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
+ $(error Error: unable to find the sources of your current Linux kernel. \
+ Specify KERN_DIR=<directory> and run Make again)
+ endif
+ $(warning Warning: using /usr/src/linux as the source directory of your \
+ Linux kernel. If this is not correct, specify \
+ KERN_DIR=<directory> and run Make again.)
+ endif
+ else
+ ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
+ $(error Error: KERN_DIR does not point to a directory)
+ endif
+ endif
+
+ # includes
+ ifndef KERN_INCL
+ KERN_INCL = $(KERN_DIR)/include
+ endif
+ ifneq ($(shell if test -d $(KERN_INCL); then echo yes; fi),yes)
+ $(error Error: unable to find the include directory for your current Linux \
+ kernel. Specify KERN_INCL=<directory> and run Make again)
+ endif
+
+ # module install dir, only for current kernel
+ ifneq ($(filter install install_rpm,$(MAKECMDGOALS)),)
+ ifndef MODULE_DIR
+ MODULE_DIR_TST := /lib/modules/$(shell uname -r)
+ ifeq ($(shell if test -d $(MODULE_DIR_TST); then echo yes; fi),yes)
+ MODULE_DIR := $(MODULE_DIR_TST)/misc
+ else
+ $(error Unable to find the folder to install the support driver to)
+ endif
+ endif # MODULE_DIR unspecified
+ endif
+
+else # neq($(KERNELRELEASE),)
+
+ #
+ # building from kbuild (make -C <kernel_directory> M=`pwd`)
+ #
+
+endif # neq($(KERNELRELEASE),)
+
+# debug - show guesses.
+ifdef DEBUG
+$(warning dbg: KERN_DIR = $(KERN_DIR))
+$(warning dbg: KERN_INCL = $(KERN_INCL))
+$(warning dbg: MODULE_DIR = $(MODULE_DIR))
+endif
+
+KBUILD_VERBOSE ?= 1
+
+#
+# Compiler options
+#
+ifndef INCL
+ INCL := $(addprefix -I,$(KERN_INCL) $(EXTRA_INCL))
+ ifndef KBUILD_EXTMOD
+ KBUILD_EXTMOD := $(shell pwd)
+ endif
+ INCL += $(addprefix -I$(KBUILD_EXTMOD),/ /include /r0drv/linux)
+ INCL += $(addprefix -I$(KBUILD_EXTMOD)/vboxpci,/ /include /r0drv/linux)
+ export INCL
+endif
+ifneq ($(wildcard $(KBUILD_EXTMOD)/vboxpci),)
+ MANGLING := $(KBUILD_EXTMOD)/vboxpci/include/VBox/SUPDrvMangling.h
+else
+ MANGLING := $(KBUILD_EXTMOD)/include/VBox/SUPDrvMangling.h
+endif
+KFLAGS := -D__KERNEL__ -DMODULE -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 \
+ -DIN_SUP_R0 -DVBOX -DRT_WITH_VBOX -DVBOX_WITH_HARDENING
+ifdef VBOX_REDHAT_KABI
+ KFLAGS += -DVBOX_REDHAT_KABI
+endif
+ifeq ($(BUILD_TARGET_ARCH),amd64)
+ KFLAGS += -DRT_ARCH_AMD64
+else
+ KFLAGS += -DRT_ARCH_X86
+endif
+# must be consistent with Config.kmk!
+KFLAGS += -DVBOX_WITH_64_BITS_GUESTS
+ifeq ($(BUILD_TYPE),debug)
+ KFLAGS += -DDEBUG -DDEBUG_$(USER) -g
+ # IPRT_DEBUG_SEMS indicates thread wrt sems state via the comm field.
+ #KFLAGS += -DIPRT_DEBUG_SEMS
+endif
+
+# By default we use remap_pfn_range() kernel API to make kernel pages
+# visible for userland. Unfortunately, it leads to situation that
+# during debug session all structures on that page (such as PVM pointer)
+# are not accessible to the debugger (see #3214).
+# This code enables experimental support
+# for vm_insert_page() kernel API, allowing to export kernel pages
+# to the userland in more debugger-friendly way. Due to stability
+# concerns, not enabled by default yet.
+ifdef VBOX_USE_INSERT_PAGE
+ KFLAGS += -DVBOX_USE_INSERT_PAGE
+endif
+
+MODULE_EXT := ko
+$(MODULE)-y := $(OBJS)
+
+# build defs
+EXTRA_CFLAGS += -include $(MANGLING) $(INCL) $(KFLAGS) $(KDEBUG)
+
+all: $(MODULE)
+
+obj-m += $(MODULE).o
+
+$(MODULE):
+ $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) -C $(KERN_DIR) modules
+
+install: $(MODULE)
+ @mkdir -p $(MODULE_DIR); \
+ install -m 0664 -o root -g root $(MODULE).$(MODULE_EXT) $(MODULE_DIR); \
+ PATH="$(PATH):/bin:/sbin" depmod -a;
+
+install_rpm: $(MODULE)
+ @mkdir -p $(MODULE_DIR); \
+ install -m 0664 $(MODULE).$(MODULE_EXT) $(MODULE_DIR)
+
+else # eq ($(MAKECMDGOALS),clean)
+
+ ifndef KERN_DIR
+ KERN_DIR := /lib/modules/$(shell uname -r)/build
+ ifeq ($(wildcard $(KERN_DIR)/Makefile),)
+ KERN_DIR := /usr/src/linux
+ endif
+ endif
+ ifeq ($(wildcard $(KERN_DIR)/Makefile),)
+
+clean:
+ find . \( -name \*.o -o -name \*.cmd \) -print0 | xargs -0 rm -f
+ rm -rf .tmp_ver* $(MODULE).* Module.symvers Modules.symvers modules.order
+
+ else
+
+clean:
+ $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) -C $(KERN_DIR) clean
+
+ endif
+
+endif # eq($(MAKECMDGOALS),clean)
diff --git a/src/VBox/HostDrivers/VBoxPci/linux/Makefile.kup b/src/VBox/HostDrivers/VBoxPci/linux/Makefile.kup
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxPci/linux/Makefile.kup
diff --git a/src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c b/src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c
new file mode 100644
index 000000000..baabd998e
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c
@@ -0,0 +1,1012 @@
+/* $Id: VBoxPci-linux.c 37868 2011-07-11 12:34:04Z vboxsync $ */
+/** @file
+ * VBoxPci - PCI Driver (Host), Linux Specific Code.
+ */
+
+/*
+ * 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 "the-linux-kernel.h"
+#include "version-generated.h"
+#include "product-generated.h"
+
+#define LOG_GROUP LOG_GROUP_DEV_PCI_RAW
+#include <VBox/log.h>
+#include <VBox/err.h>
+#include <iprt/process.h>
+#include <iprt/initterm.h>
+#include <iprt/string.h>
+#include <iprt/mem.h>
+
+#include "VBoxPciInternal.h"
+
+#ifdef VBOX_WITH_IOMMU
+#include <linux/dmar.h>
+#include <linux/intel-iommu.h>
+#include <asm/amd_iommu.h>
+#endif
+
+
+/*******************************************************************************
+ * Internal Functions *
+ *******************************************************************************/
+static int VBoxPciLinuxInit(void);
+static void VBoxPciLinuxUnload(void);
+
+/*******************************************************************************
+ * Global Variables *
+ *******************************************************************************/
+static VBOXRAWPCIGLOBALS g_VBoxPciGlobals;
+
+module_init(VBoxPciLinuxInit);
+module_exit(VBoxPciLinuxUnload);
+
+MODULE_AUTHOR(VBOX_VENDOR);
+MODULE_DESCRIPTION(VBOX_PRODUCT " PCI access Driver");
+MODULE_LICENSE("GPL");
+#ifdef MODULE_VERSION
+MODULE_VERSION(VBOX_VERSION_STRING);
+#endif
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+# define PCI_DEV_GET(v,d,p) pci_get_device(v,d,p)
+# define PCI_DEV_PUT(x) pci_dev_put(x)
+# define PCI_DEV_GET_SLOT(bus, devfn) pci_get_bus_and_slot(bus, devfn)
+#else
+# define PCI_DEV_GET(v,d,p) pci_find_device(v,d,p)
+# define PCI_DEV_PUT(x) do {} while(0)
+# define PCI_DEV_GET_SLOT(bus, devfn) pci_find_slot(bus, devfn)
+#endif
+
+/**
+ * Name of module used to attach to the host PCI device, when
+ * PCI device passthrough is used.
+ */
+#define PCI_STUB_MODULE "pci-stub"
+/* For some reasons my kernel names module for find_module() this way,
+ * while device name seems to be above one.
+ */
+#define PCI_STUB_MODULE_NAME "pci_stub"
+
+/**
+ * Our driver name.
+ */
+#define DRIVER_NAME "vboxpci"
+
+/**
+ * Initialize module.
+ *
+ * @returns appropriate status code.
+ */
+static int __init VBoxPciLinuxInit(void)
+{
+ int rc;
+ /*
+ * Initialize IPRT.
+ */
+ rc = RTR0Init(0);
+
+ if (RT_FAILURE(rc))
+ goto error;
+
+
+ LogRel(("VBoxPciLinuxInit\n"));
+
+ RT_ZERO(g_VBoxPciGlobals);
+
+ rc = vboxPciInit(&g_VBoxPciGlobals);
+ if (RT_FAILURE(rc))
+ {
+ LogRel(("cannot do VBoxPciInit: %Rc\n", rc));
+ goto error;
+ }
+
+#if defined(CONFIG_PCI_STUB)
+ /* nothing to do, pci_stub module part of the kernel */
+ g_VBoxPciGlobals.fPciStubModuleAvail = true;
+
+#elif defined(CONFIG_PCI_STUB_MODULE)
+ if (request_module(PCI_STUB_MODULE) == 0)
+ {
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
+ /* find_module() is static before Linux 2.6.30 */
+ g_VBoxPciGlobals.pciStubModule = find_module(PCI_STUB_MODULE_NAME);
+ if (g_VBoxPciGlobals.pciStubModule)
+ {
+ if (try_module_get(g_VBoxPciGlobals.pciStubModule))
+ g_VBoxPciGlobals.fPciStubModuleAvail = true;
+ }
+ else
+ printk(KERN_INFO "vboxpci: find_module %s failed\n", PCI_STUB_MODULE);
+# endif
+ }
+ else
+ printk(KERN_INFO "vboxpci: cannot load %s\n", PCI_STUB_MODULE);
+
+#else
+ printk(KERN_INFO "vboxpci: %s module not available, cannot detach PCI devices\n",
+ PCI_STUB_MODULE);
+#endif
+
+#ifdef VBOX_WITH_IOMMU
+ if (iommu_found())
+ printk(KERN_INFO "vboxpci: IOMMU found\n");
+ else
+ printk(KERN_INFO "vboxpci: IOMMU not found (not registered)\n");
+#else
+ printk(KERN_INFO "vboxpci: IOMMU not found (not compiled)\n");
+#endif
+
+ return 0;
+
+ error:
+ return -RTErrConvertToErrno(rc);
+}
+
+/**
+ * Unload the module.
+ */
+static void __exit VBoxPciLinuxUnload(void)
+{
+ LogRel(("VBoxPciLinuxLinuxUnload\n"));
+
+ /*
+ * Undo the work done during start (in reverse order).
+ */
+ vboxPciShutdown(&g_VBoxPciGlobals);
+
+ RTR0Term();
+
+ if (g_VBoxPciGlobals.pciStubModule)
+ {
+ module_put(g_VBoxPciGlobals.pciStubModule);
+ g_VBoxPciGlobals.pciStubModule = NULL;
+ }
+
+ Log(("VBoxPciLinuxUnload - done\n"));
+}
+
+int vboxPciOsDevRegisterWithIommu(PVBOXRAWPCIINS pIns)
+{
+#ifdef VBOX_WITH_IOMMU
+ int rc;
+ int status;
+ PVBOXRAWPCIDRVVM pData = VBOX_DRV_VMDATA(pIns);
+
+ if (!pData)
+ {
+ printk(KERN_DEBUG "vboxpci: VM data not initialized (attach)\n");
+ return VERR_INVALID_PARAMETER;
+ }
+
+ if (!pData->pIommuDomain)
+ {
+ printk(KERN_DEBUG "vboxpci: No IOMMU domain (attach)\n");
+ return VERR_NOT_FOUND;
+ }
+
+ status = iommu_attach_device(pData->pIommuDomain, &pIns->pPciDev->dev);
+ if (status == 0)
+ {
+ printk(KERN_DEBUG "vboxpci: iommu_attach_device() success\n");
+ pIns->fIommuUsed = true;
+ rc = VINF_SUCCESS;;
+ }
+ else
+ {
+ printk(KERN_DEBUG "vboxpci: iommu_attach_device() failed\n");
+ rc = VERR_INTERNAL_ERROR;
+ }
+
+ /* @todo: KVM checks IOMMU_CAP_CACHE_COHERENCY and sets
+ flag IOMMU_CACHE later used when mapping physical
+ addresses, which could improve performance. */
+
+ return rc;
+#else
+ return VERR_NOT_SUPPORTED;
+#endif
+}
+
+int vboxPciOsDevUnregisterWithIommu(PVBOXRAWPCIINS pIns)
+{
+#ifdef VBOX_WITH_IOMMU
+ int rc = VINF_SUCCESS;
+ PVBOXRAWPCIDRVVM pData = VBOX_DRV_VMDATA(pIns);
+
+ if (!pData)
+ {
+ printk(KERN_DEBUG "vboxpci: VM data not inited (detach)\n");
+ return VERR_INVALID_PARAMETER;
+ }
+
+ if (!pData->pIommuDomain)
+ {
+ printk(KERN_DEBUG "vboxpci: No IOMMU domain (detach)\n");
+ return VERR_NOT_FOUND;
+ }
+
+ if (pIns->fIommuUsed)
+ {
+ iommu_detach_device(pData->pIommuDomain, &pIns->pPciDev->dev);
+ printk(KERN_DEBUG "vboxpci: iommu_detach_device()\n");
+ pIns->fIommuUsed = false;
+ }
+
+ return rc;
+#else
+ return VERR_NOT_SUPPORTED;
+#endif
+}
+
+int vboxPciOsDevReset(PVBOXRAWPCIINS pIns)
+{
+ int rc = VINF_SUCCESS;
+
+ if (pIns->pPciDev)
+ {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+ if (pci_reset_function(pIns->pPciDev))
+ {
+ printk(KERN_DEBUG "vboxpci: pci_reset_function() failed\n");
+ rc = VERR_INTERNAL_ERROR;
+ }
+#else
+ rc = VERR_NOT_SUPPORTED;
+#endif
+ }
+
+ return rc;
+}
+
+static struct file* vboxPciFileOpen(const char* path, int flags)
+{
+ struct file* filp = NULL;
+ int err = 0;
+
+ filp = filp_open(path, flags, 0);
+
+ if (IS_ERR(filp))
+ {
+ err = PTR_ERR(filp);
+ printk(KERN_DEBUG "vboxPciFileOpen: error %d\n", err);
+ return NULL;
+ }
+
+ if (!filp->f_op || !filp->f_op->write)
+ {
+ printk(KERN_DEBUG "Not writable FS\n");
+ filp_close(filp, NULL);
+ return NULL;
+ }
+
+ return filp;
+}
+
+static void vboxPciFileClose(struct file* file)
+{
+ filp_close(file, NULL);
+}
+
+static int vboxPciFileWrite(struct file* file, unsigned long long offset, unsigned char* data, unsigned int size)
+{
+ int ret;
+ mm_segment_t fs_save;
+
+ fs_save = get_fs();
+ set_fs(get_ds());
+ ret = vfs_write(file, data, size, &offset);
+ set_fs(fs_save);
+ if (ret < 0)
+ printk(KERN_DEBUG "vboxPciFileWrite: error %d\n", ret);
+
+ return ret;
+}
+
+#if 0
+static int vboxPciFileRead(struct file* file, unsigned long long offset, unsigned char* data, unsigned int size)
+{
+ int ret;
+ mm_segment_t fs_save;
+
+ fs_save = get_fs();
+ set_fs(get_ds());
+ ret = vfs_read(file, data, size, &offset);
+ set_fs(fs_save);
+
+ return ret;
+}
+#endif
+
+int vboxPciOsDevDetachHostDriver(PVBOXRAWPCIINS pIns)
+{
+ struct pci_dev *pPciDev = NULL;
+ uint8_t uBus = (pIns->HostPciAddress) >> 8;
+ uint8_t uDevFn = (pIns->HostPciAddress) & 0xff;
+ const char* currentDriver;
+ uint16_t uVendor, uDevice;
+ int fDetach = 0;
+
+ if (!g_VBoxPciGlobals.fPciStubModuleAvail)
+ {
+ printk(KERN_INFO "vboxpci: stub module %s not detected: cannot detach\n",
+ PCI_STUB_MODULE);
+ return VERR_ACCESS_DENIED;
+ }
+
+ pPciDev = PCI_DEV_GET_SLOT(uBus, uDevFn);
+
+ if (!pPciDev)
+ {
+ printk(KERN_INFO "vboxpci: device at %02x:%02x.%d not found\n",
+ uBus, uDevFn>>3, uDevFn&7);
+ return VERR_NOT_FOUND;
+ }
+
+ uVendor = pPciDev->vendor;
+ uDevice = pPciDev->device;
+
+ currentDriver = pPciDev->driver ? pPciDev->driver->name : NULL;
+
+ printk(KERN_DEBUG "vboxpci: detected device: %04x:%04x at %02x:%02x.%d, driver %s\n",
+ uVendor, uDevice, uBus, uDevFn>>3, uDevFn&7,
+ currentDriver ? currentDriver : "<none>");
+
+ fDetach = (currentDriver == NULL || (strcmp(currentDriver, PCI_STUB_MODULE) != 0)) ? 1 : 0;
+
+ /* Init previous driver data. */
+ pIns->szPrevDriver[0] = '\0';
+
+ if (fDetach && currentDriver)
+ {
+ /* Dangerous: if device name for some reasons contains slashes - arbitrary file could be written to. */
+ if (strchr(currentDriver, '/') != 0)
+ {
+ printk(KERN_DEBUG "vboxpci: ERROR: %s contains invalid symbols\n", currentDriver);
+ return VERR_ACCESS_DENIED;
+ }
+ /** @todo: RTStrCopy not exported. */
+ strncpy(pIns->szPrevDriver, currentDriver, sizeof(pIns->szPrevDriver));
+ }
+
+ PCI_DEV_PUT(pPciDev);
+ pPciDev = NULL;
+
+ if (fDetach)
+ {
+ char* szCmdBuf;
+ char* szFileBuf;
+ struct file* pFile;
+ int iCmdLen;
+ const int cMaxBuf = 128;
+ const struct cred *pOldCreds;
+ struct cred *pNewCreds;
+
+ /*
+ * Now perform kernel analog of:
+ *
+ * echo -n "10de 040a" > /sys/bus/pci/drivers/pci-stub/new_id
+ * echo -n 0000:03:00.0 > /sys/bus/pci/drivers/nvidia/unbind
+ * echo -n 0000:03:00.0 > /sys/bus/pci/drivers/pci-stub/bind
+ *
+ * We do this way, as this interface is presumingly more stable than
+ * in-kernel ones.
+ */
+ szCmdBuf = kmalloc(cMaxBuf, GFP_KERNEL);
+ szFileBuf = kmalloc(cMaxBuf, GFP_KERNEL);
+ if (!szCmdBuf || !szFileBuf)
+ goto done;
+
+ /* Somewhat ugly hack - override current credentials */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+ pNewCreds = prepare_creds();
+ if (!pNewCreds)
+ goto done;
+
+ pNewCreds->fsuid = 0;
+ pOldCreds = override_creds(pNewCreds);
+#endif
+
+ RTStrPrintf(szFileBuf, cMaxBuf,
+ "/sys/bus/pci/drivers/%s/new_id",
+ PCI_STUB_MODULE);
+ pFile = vboxPciFileOpen(szFileBuf, O_WRONLY);
+ if (pFile)
+ {
+ iCmdLen = RTStrPrintf(szCmdBuf, cMaxBuf,
+ "%04x %04x",
+ uVendor, uDevice);
+ /* Don't write trailing \0 */
+ vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen);
+ vboxPciFileClose(pFile);
+ }
+ else
+ printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf);
+
+ iCmdLen = RTStrPrintf(szCmdBuf, cMaxBuf,
+ "0000:%02x:%02x.%d",
+ uBus, uDevFn>>3, uDevFn&7);
+
+ /* Unbind if bound to smth */
+ if (pIns->szPrevDriver[0])
+ {
+ RTStrPrintf(szFileBuf, cMaxBuf,
+ "/sys/bus/pci/drivers/%s/unbind",
+ pIns->szPrevDriver);
+ pFile = vboxPciFileOpen(szFileBuf, O_WRONLY);
+ if (pFile)
+ {
+
+ /* Don't write trailing \0 */
+ vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen);
+ vboxPciFileClose(pFile);
+ }
+ else
+ printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf);
+ }
+
+ RTStrPrintf(szFileBuf, cMaxBuf,
+ "/sys/bus/pci/drivers/%s/bind",
+ PCI_STUB_MODULE);
+ pFile = vboxPciFileOpen(szFileBuf, O_WRONLY);
+ if (pFile)
+ {
+ /* Don't write trailing \0 */
+ vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen);
+ vboxPciFileClose(pFile);
+ }
+ else
+ printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+ revert_creds(pOldCreds);
+ put_cred(pNewCreds);
+#endif
+
+ done:
+ kfree(szCmdBuf);
+ kfree(szFileBuf);
+ }
+
+ return 0;
+}
+
+int vboxPciOsDevReattachHostDriver(PVBOXRAWPCIINS pIns)
+{
+ struct pci_dev *pPciDev = pIns->pPciDev;
+
+ if (!pPciDev)
+ return VINF_SUCCESS;
+
+ if (pIns->szPrevDriver[0])
+ {
+ char* szCmdBuf;
+ char* szFileBuf;
+ struct file* pFile;
+ int iCmdLen;
+ const int cMaxBuf = 128;
+ const struct cred *pOldCreds;
+ struct cred *pNewCreds;
+ uint8_t uBus = (pIns->HostPciAddress) >> 8;
+ uint8_t uDevFn = (pIns->HostPciAddress) & 0xff;
+
+ printk(KERN_DEBUG "vboxpci: reattaching old host driver %s\n", pIns->szPrevDriver);
+ /*
+ * Now perform kernel analog of:
+ *
+ * echo -n 0000:03:00.0 > /sys/bus/pci/drivers/pci-stub/unbind
+ * echo -n 0000:03:00.0 > /sys/bus/pci/drivers/nvidia/bind
+ */
+ szCmdBuf = kmalloc(cMaxBuf, GFP_KERNEL);
+ szFileBuf = kmalloc(cMaxBuf, GFP_KERNEL);
+
+ if (!szCmdBuf || !szFileBuf)
+ goto done;
+
+ iCmdLen = RTStrPrintf(szCmdBuf, cMaxBuf,
+ "0000:%02x:%02x.%d",
+ uBus, uDevFn>>3, uDevFn&7);
+
+ /* Somewhat ugly hack - override current credentials */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+ pNewCreds = prepare_creds();
+ if (!pNewCreds)
+ goto done;
+
+ pNewCreds->fsuid = 0;
+ pOldCreds = override_creds(pNewCreds);
+#endif
+ RTStrPrintf(szFileBuf, cMaxBuf,
+ "/sys/bus/pci/drivers/%s/unbind",
+ PCI_STUB_MODULE);
+ pFile = vboxPciFileOpen(szFileBuf, O_WRONLY);
+ if (pFile)
+ {
+
+ /* Don't write trailing \0 */
+ vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen);
+ vboxPciFileClose(pFile);
+ }
+ else
+ printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf);
+
+ RTStrPrintf(szFileBuf, cMaxBuf,
+ "/sys/bus/pci/drivers/%s/bind",
+ pIns->szPrevDriver);
+ pFile = vboxPciFileOpen(szFileBuf, O_WRONLY);
+ if (pFile)
+ {
+
+ /* Don't write trailing \0 */
+ vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen);
+ vboxPciFileClose(pFile);
+ pIns->szPrevDriver[0] = '\0';
+ }
+ else
+ printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+ revert_creds(pOldCreds);
+ put_cred(pNewCreds);
+#endif
+
+ done:
+ kfree(szCmdBuf);
+ kfree(szFileBuf);
+ }
+
+ return VINF_SUCCESS;
+}
+
+int vboxPciOsDevInit(PVBOXRAWPCIINS pIns, uint32_t fFlags)
+{
+ struct pci_dev *pPciDev = NULL;
+ int rc;
+
+ printk(KERN_DEBUG "vboxpci: vboxPciOsDevInit: dev=%x\n", pIns->HostPciAddress);
+
+ if (fFlags & PCIRAWDRIVERRFLAG_DETACH_HOST_DRIVER)
+ {
+ rc = vboxPciOsDevDetachHostDriver(pIns);
+ if (RT_FAILURE(rc))
+ {
+ printk(KERN_DEBUG "Cannot detach host driver for device %x: %d\n",
+ pIns->HostPciAddress, rc);
+ return VERR_ACCESS_DENIED;
+ }
+ }
+
+
+ pPciDev = PCI_DEV_GET_SLOT((pIns->HostPciAddress) >> 8,
+ (pIns->HostPciAddress) & 0xff);
+
+ printk(KERN_DEBUG "vboxpci: vboxPciOsDevInit: dev=%x pdev=%p\n",
+ pIns->HostPciAddress, pPciDev);
+
+ if (!pPciDev)
+ return 0;
+
+ pIns->pPciDev = pPciDev;
+
+ rc = pci_enable_device(pPciDev);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 1)
+ if (pci_enable_msi(pPciDev) == 0)
+ {
+ printk(KERN_DEBUG "vboxpci: enabled MSI\n");
+ pIns->fMsiUsed = true;
+ }
+#endif
+
+ // pci_enable_msix(pPciDev, entries, nvec)
+
+ /* In fact, if device uses interrupts, and cannot be forced to use MSI or MSI-X
+ we have to refuse using it, as we cannot work with shared PCI interrupts (unless we're lucky
+ to grab unshared PCI interrupt). */
+
+ return VINF_SUCCESS;
+}
+
+int vboxPciOsDevDeinit(PVBOXRAWPCIINS pIns, uint32_t fFlags)
+{
+ struct pci_dev *pPciDev = NULL;
+
+ printk(KERN_DEBUG "vboxpci: vboxPciOsDevDeinit: dev=%x\n", pIns->HostPciAddress);
+
+ pPciDev = pIns->pPciDev;
+
+ if (pPciDev)
+ {
+ vboxPciOsDevUnregisterWithIommu(pIns);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 1)
+ if (pIns->fMsiUsed)
+ pci_disable_msi(pPciDev);
+#endif
+ // pci_disable_msix(pPciDev);
+ pci_disable_device(pPciDev);
+ vboxPciOsDevReattachHostDriver(pIns);
+
+ PCI_DEV_PUT(pPciDev);
+ pIns->pPciDev = NULL;
+ }
+
+ return 0;
+}
+
+int vboxPciOsDevDestroy(PVBOXRAWPCIINS pIns)
+{
+ return 0;
+}
+
+int vboxPciOsDevGetRegionInfo(PVBOXRAWPCIINS pIns,
+ int32_t iRegion,
+ RTHCPHYS *pRegionStart,
+ uint64_t *pu64RegionSize,
+ bool *pfPresent,
+ uint32_t *pfFlags)
+{
+ int flags;
+ struct pci_dev *pPciDev = pIns->pPciDev;
+ uint32_t fResFlags;
+
+ if (!pPciDev)
+ {
+ *pfPresent = false;
+ return 0;
+ }
+
+ printk(KERN_DEBUG "%x: linux vboxPciOsDevGetRegionInfo: reg=%d\n",
+ pIns->HostPciAddress, iRegion);
+
+ flags = pci_resource_flags(pPciDev, iRegion);
+ if (((flags & (IORESOURCE_MEM | IORESOURCE_IO)) == 0)
+ ||
+ ((flags & IORESOURCE_DISABLED) != 0))
+ {
+ *pfPresent = false;
+ return 0;
+ }
+
+ *pfPresent = true;
+ fResFlags = 0;
+
+ if (flags & IORESOURCE_MEM)
+ fResFlags |= PCIRAW_ADDRESS_SPACE_MEM;
+
+ if (flags & IORESOURCE_IO)
+ fResFlags |= PCIRAW_ADDRESS_SPACE_IO;
+
+#ifdef IORESOURCE_MEM_64
+ if (flags & IORESOURCE_MEM_64)
+ fResFlags |= PCIRAW_ADDRESS_SPACE_BAR64;
+#endif
+
+ if (flags & IORESOURCE_PREFETCH)
+ fResFlags |= PCIRAW_ADDRESS_SPACE_MEM_PREFETCH;
+
+ *pfFlags = fResFlags;
+ *pRegionStart = pci_resource_start(pPciDev, iRegion);
+ *pu64RegionSize = pci_resource_len (pPciDev, iRegion);
+
+ printk(KERN_DEBUG "got %s region: %llx:%lld\n",
+ (flags & IORESOURCE_MEM) ? "mmio" : "pio", *pRegionStart, *pu64RegionSize);
+
+ return 0;
+}
+
+int vboxPciOsDevMapRegion(PVBOXRAWPCIINS pIns,
+ int32_t iRegion,
+ RTHCPHYS RegionStart,
+ uint64_t u64RegionSize,
+ uint32_t fFlags,
+ RTR0PTR *pRegionBase)
+{
+ struct pci_dev *pPciDev = pIns->pPciDev;
+ struct resource *pRegion;
+ RTR0PTR result = 0;
+
+ printk(KERN_DEBUG "linux vboxPciOsDevMapRegion: reg=%d start=%llx size=%lld\n", iRegion, RegionStart, u64RegionSize);
+
+ if (!pPciDev)
+ return 0;
+
+ if (iRegion < 0 || iRegion > 6)
+ {
+ printk(KERN_DEBUG "vboxPciOsDevMapRegion: invalid region: %d\n", iRegion);
+ return VERR_INVALID_PARAMETER;
+ }
+
+ pRegion = request_mem_region(RegionStart, u64RegionSize, "vboxpci");
+ if (!pRegion)
+ {
+ /** @todo: need to make sure if thise error indeed can be ignored. */
+ printk(KERN_DEBUG "request_mem_region() failed, don't care\n");
+ }
+
+ /* For now no caching, try to optimize later. */
+ result = ioremap_nocache(RegionStart, u64RegionSize);
+
+ if (!result)
+ {
+ printk(KERN_DEBUG "cannot ioremap_nocache\n");
+ if (pRegion)
+ release_mem_region(RegionStart, u64RegionSize);
+ return 0;
+ }
+
+ *pRegionBase = result;
+
+ return 0;
+}
+
+int vboxPciOsDevUnmapRegion(PVBOXRAWPCIINS pIns,
+ int32_t iRegion,
+ RTHCPHYS RegionStart,
+ uint64_t u64RegionSize,
+ RTR0PTR RegionBase)
+{
+
+ iounmap(RegionBase);
+ release_mem_region(RegionStart, u64RegionSize);
+
+ return VINF_SUCCESS;
+}
+
+int vboxPciOsDevPciCfgWrite(PVBOXRAWPCIINS pIns, uint32_t Register, PCIRAWMEMLOC *pValue)
+{
+ struct pci_dev *pPciDev = pIns->pPciDev;
+
+ if (!pPciDev)
+ return VINF_SUCCESS;
+
+ switch (pValue->cb)
+ {
+ case 1:
+ pci_write_config_byte(pPciDev, Register, pValue->u.u8);
+ break;
+ case 2:
+ pci_write_config_word(pPciDev, Register, pValue->u.u16);
+ break;
+ case 4:
+ pci_write_config_dword(pPciDev, Register, pValue->u.u32);
+ break;
+ }
+
+ return VINF_SUCCESS;
+}
+
+int vboxPciOsDevPciCfgRead (PVBOXRAWPCIINS pIns, uint32_t Register, PCIRAWMEMLOC *pValue)
+{
+ struct pci_dev *pPciDev = pIns->pPciDev;
+
+ if (!pPciDev)
+ return VINF_SUCCESS;
+
+ switch (pValue->cb)
+ {
+ case 1:
+ pci_read_config_byte(pPciDev, Register, &pValue->u.u8);
+ break;
+ case 2:
+ pci_read_config_word(pPciDev, Register, &pValue->u.u16);
+ break;
+ case 4:
+ pci_read_config_dword(pPciDev, Register, &pValue->u.u32);
+ break;
+ }
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * Interrupt service routine.
+ *
+ * @returns In 2.6 we indicate whether we've handled the IRQ or not.
+ *
+ * @param iIrq The IRQ number.
+ * @param pvDevId The device ID, a pointer to PVBOXRAWPCIINS.
+ * @param pvRegs Register set. Removed in 2.6.19.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+static irqreturn_t vboxPciOsIrqHandler(int iIrq, void *pvDevId)
+#else
+static irqreturn_t vboxPciOsIrqHandler(int iIrq, void *pvDevId, struct pt_regs *pRegs)
+#endif
+{
+ PVBOXRAWPCIINS pIns = (PVBOXRAWPCIINS)pvDevId;
+ bool fTaken = true;
+
+ if (pIns && pIns->IrqHandler.pfnIrqHandler)
+ fTaken = pIns->IrqHandler.pfnIrqHandler(pIns->IrqHandler.pIrqContext, iIrq);
+#ifndef VBOX_WITH_SHARED_PCI_INTERRUPTS
+ /* If we don't allow interrupts sharing, we consider all interrupts as non-shared, thus targetted to us. */
+ fTaken = true;
+#endif
+
+ return fTaken;
+}
+
+int vboxPciOsDevRegisterIrqHandler(PVBOXRAWPCIINS pIns, PFNRAWPCIISR pfnHandler, void* pIrqContext, int32_t *piHostIrq)
+{
+ int rc;
+ int32_t iIrq = pIns->pPciDev->irq;
+
+ if (iIrq == 0)
+ {
+ printk(KERN_DEBUG "device not assigned host interrupt\n");
+ return VERR_INVALID_PARAMETER;
+ }
+
+ rc = request_irq(iIrq,
+ vboxPciOsIrqHandler,
+#ifdef VBOX_WITH_SHARED_PCI_INTERRUPTS
+ /* Allow interrupts sharing. */
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+ IRQF_SHARED,
+# else
+ SA_SHIRQ,
+# endif
+
+#else
+
+ /* We don't allow interrupts sharing */
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+ IRQF_DISABLED, /* keep irqs disabled when calling the action handler */
+# else
+ 0,
+# endif
+#endif
+ DRIVER_NAME,
+ pIns);
+ if (rc)
+ {
+ printk(KERN_DEBUG "could not request IRQ %d: err=%d\n", iIrq, rc);
+ return VERR_RESOURCE_BUSY;
+ }
+
+ printk(KERN_DEBUG "got PCI IRQ: %d\n", iIrq);
+ *piHostIrq = iIrq;
+ return VINF_SUCCESS;
+}
+
+int vboxPciOsDevUnregisterIrqHandler(PVBOXRAWPCIINS pIns, int32_t iHostIrq)
+{
+ printk(KERN_DEBUG "free PCI IRQ: %d\n", iHostIrq);
+ free_irq(iHostIrq, pIns);
+ return VINF_SUCCESS;
+}
+
+int vboxPciOsDevPowerStateChange(PVBOXRAWPCIINS pIns, PCIRAWPOWERSTATE aState)
+{
+ int rc;
+
+ printk(KERN_DEBUG "power state: %d\n", (int)aState);
+
+ switch (aState)
+ {
+ case PCIRAW_POWER_ON:
+ /* Reset device, just in case. */
+ vboxPciOsDevReset(pIns);
+ /* register us with IOMMU */
+ rc = vboxPciOsDevRegisterWithIommu(pIns);
+ break;
+ case PCIRAW_POWER_RESET:
+ rc = vboxPciOsDevReset(pIns);
+ break;
+ case PCIRAW_POWER_OFF:
+ /* unregister us from IOMMU */
+ rc = vboxPciOsDevUnregisterWithIommu(pIns);
+ break;
+ case PCIRAW_POWER_SUSPEND:
+ case PCIRAW_POWER_RESUME:
+ rc = VINF_SUCCESS;
+ /// @todo: what do we do here?
+ break;
+ default:
+ /* to make compiler happy */
+ rc = VERR_NOT_SUPPORTED;
+ break;
+ }
+
+ return rc;
+}
+
+
+#ifdef VBOX_WITH_IOMMU
+/** Callback for FNRAWPCICONTIGPHYSMEMINFO. */
+static int vboxPciOsContigMemInfo(PRAWPCIPERVM pVmCtx, RTHCPHYS HostStart, RTGCPHYS GuestStart, uint64_t cMemSize, PCIRAWMEMINFOACTION Action)
+{
+ struct iommu_domain* domain = ((PVBOXRAWPCIDRVVM)(pVmCtx->pDriverData))->pIommuDomain;
+ int rc = VINF_SUCCESS;
+
+ switch (Action)
+ {
+ case PCIRAW_MEMINFO_MAP:
+ {
+ int flags, r;
+
+ if (iommu_iova_to_phys(domain, GuestStart))
+ break;
+
+ flags = IOMMU_READ | IOMMU_WRITE;
+ /* @todo: flags |= IOMMU_CACHE; */
+
+ r = iommu_map(domain, GuestStart, HostStart, get_order(cMemSize), flags);
+ if (r)
+ {
+ printk(KERN_ERR "vboxPciOsContigMemInfo:"
+ "iommu failed to map pfn=%llx\n", HostStart);
+ rc = VERR_GENERAL_FAILURE;
+ break;
+ }
+ rc = VINF_SUCCESS;
+ break;
+ }
+ case PCIRAW_MEMINFO_UNMAP:
+ {
+ int order;
+ order = iommu_unmap(domain, GuestStart, get_order(cMemSize));
+ NOREF(order);
+ break;
+ }
+
+ default:
+ printk(KERN_DEBUG "Unsupported action: %d\n", (int)Action);
+ rc = VERR_NOT_SUPPORTED;
+ break;
+ }
+
+ return rc;
+}
+#endif
+
+int vboxPciOsInitVm(PVBOXRAWPCIDRVVM pThis, PVM pVM, PRAWPCIPERVM pVmData)
+{
+#ifdef DEBUG
+ printk(KERN_DEBUG "vboxPciOsInitVm: %p\n", pThis);
+#endif
+#ifdef VBOX_WITH_IOMMU
+ if (iommu_found())
+ {
+ pThis->pIommuDomain = iommu_domain_alloc();
+ if (!pThis->pIommuDomain)
+ {
+ printk(KERN_DEBUG "cannot allocate IOMMU domain\n");
+ return VERR_NO_MEMORY;
+ }
+
+ pVmData->pfnContigMemInfo = vboxPciOsContigMemInfo;
+
+ printk(KERN_DEBUG "created IOMMU domain %p\n", pThis->pIommuDomain);
+ }
+#endif
+ return VINF_SUCCESS;
+}
+
+void vboxPciOsDeinitVm(PVBOXRAWPCIDRVVM pThis, PVM pVM)
+{
+#ifdef DEBUG
+ printk(KERN_DEBUG "vboxPciOsDeinitVm: %p\n", pThis);
+#endif
+#ifdef VBOX_WITH_IOMMU
+ if (pThis->pIommuDomain)
+ {
+ iommu_domain_free(pThis->pIommuDomain);
+ pThis->pIommuDomain = NULL;
+ }
+#endif
+}
diff --git a/src/VBox/HostDrivers/VBoxPci/linux/dkms.conf b/src/VBox/HostDrivers/VBoxPci/linux/dkms.conf
new file mode 100644
index 000000000..e2e6eb07a
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxPci/linux/dkms.conf
@@ -0,0 +1,7 @@
+BUILT_MODULE_NAME=vboxpci
+DEST_MODULE_LOCATION=/kernel/misc
+PACKAGE_NAME=vboxpci
+PACKAGE_VERSION=_VERSION_
+AUTOINSTALL=yes
+CLEAN="make -C $dkms_tree/$module/$module_version/build clean"
+PRE_BUILD="do_Module.symvers vboxdrv restore $dkms_tree/$module/$module_version/build/Module.symvers"
diff --git a/src/VBox/HostDrivers/VBoxPci/linux/files_vboxpci b/src/VBox/HostDrivers/VBoxPci/linux/files_vboxpci
new file mode 100644
index 000000000..3e5a7abde
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxPci/linux/files_vboxpci
@@ -0,0 +1,81 @@
+#!/bin/sh
+# $Id: files_vboxpci 37798 2011-07-06 11:35:19Z vboxsync $
+## @file
+# Shared file between Makefile.kmk and export_modules
+#
+
+#
+# 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.
+#
+
+VBOX_VBOXPCI_SOURCES=" \
+ ${PATH_ROOT}/include/iprt/alloc.h=>include/iprt/alloc.h \
+ ${PATH_ROOT}/include/iprt/alloca.h=>include/iprt/alloca.h \
+ ${PATH_ROOT}/include/iprt/asm.h=>include/iprt/asm.h \
+ ${PATH_ROOT}/include/iprt/asm-amd64-x86.h=>include/iprt/asm-amd64-x86.h \
+ ${PATH_ROOT}/include/iprt/asm-math.h=>include/iprt/asm-math.h \
+ ${PATH_ROOT}/include/iprt/assert.h=>include/iprt/assert.h \
+ ${PATH_ROOT}/include/iprt/avl.h=>include/iprt/avl.h \
+ ${PATH_ROOT}/include/iprt/cdefs.h=>include/iprt/cdefs.h \
+ ${PATH_ROOT}/include/iprt/cpuset.h=>include/iprt/cpuset.h \
+ ${PATH_ROOT}/include/iprt/ctype.h=>include/iprt/ctype.h \
+ ${PATH_ROOT}/include/iprt/err.h=>include/iprt/err.h \
+ ${PATH_ROOT}/include/iprt/heap.h=>include/iprt/heap.h \
+ ${PATH_ROOT}/include/iprt/initterm.h=>include/iprt/initterm.h \
+ ${PATH_ROOT}/include/iprt/log.h=>include/iprt/log.h \
+ ${PATH_ROOT}/include/iprt/mangling.h=>include/iprt/mangling.h \
+ ${PATH_ROOT}/include/iprt/mem.h=>include/iprt/mem.h \
+ ${PATH_ROOT}/include/iprt/memobj.h=>include/iprt/memobj.h \
+ ${PATH_ROOT}/include/iprt/mp.h=>include/iprt/mp.h \
+ ${PATH_ROOT}/include/iprt/param.h=>include/iprt/param.h \
+ ${PATH_ROOT}/include/iprt/power.h=>include/iprt/power.h \
+ ${PATH_ROOT}/include/iprt/process.h=>include/iprt/process.h \
+ ${PATH_ROOT}/include/iprt/semaphore.h=>include/iprt/semaphore.h \
+ ${PATH_ROOT}/include/iprt/spinlock.h=>include/iprt/spinlock.h \
+ ${PATH_ROOT}/include/iprt/stdarg.h=>include/iprt/stdarg.h \
+ ${PATH_ROOT}/include/iprt/stdint.h=>include/iprt/stdint.h \
+ ${PATH_ROOT}/include/iprt/string.h=>include/iprt/string.h \
+ ${PATH_ROOT}/include/iprt/thread.h=>include/iprt/thread.h \
+ ${PATH_ROOT}/include/iprt/time.h=>include/iprt/time.h \
+ ${PATH_ROOT}/include/iprt/timer.h=>include/iprt/timer.h \
+ ${PATH_ROOT}/include/iprt/types.h=>include/iprt/types.h \
+ ${PATH_ROOT}/include/iprt/uni.h=>include/iprt/uni.h \
+ ${PATH_ROOT}/include/iprt/uuid.h=>include/iprt/uuid.h \
+ ${PATH_ROOT}/include/iprt/nocrt/limits.h=>include/iprt/nocrt/limits.h \
+ ${PATH_ROOT}/include/VBox/cdefs.h=>include/VBox/cdefs.h \
+ ${PATH_ROOT}/include/VBox/err.h=>include/VBox/err.h \
+ ${PATH_ROOT}/include/VBox/log.h=>include/VBox/log.h \
+ ${PATH_ROOT}/include/VBox/rawpci.h=>include/VBox/rawpci.h \
+ ${PATH_ROOT}/include/VBox/vmm/stam.h=>include/VBox/vmm/stam.h \
+ ${PATH_ROOT}/include/VBox/param.h=>include/VBox/param.h \
+ ${PATH_ROOT}/include/VBox/sup.h=>include/VBox/sup.h \
+ ${PATH_ROOT}/include/VBox/types.h=>include/VBox/types.h \
+ ${PATH_ROOT}/include/VBox/version.h=>include/VBox/version.h \
+ ${PATH_ROOT}/include/VBox/SUPDrvMangling.h=>include/VBox/SUPDrvMangling.h \
+ ${PATH_ROOT}/src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c=>linux/VBoxPci-linux.c \
+ ${PATH_ROOT}/src/VBox/HostDrivers/VBoxPci/VBoxPci.c=>VBoxPci.c \
+ ${PATH_ROOT}/src/VBox/HostDrivers/VBoxPci/VBoxPciInternal.h=>VBoxPciInternal.h \
+ ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrvIDC.h=>SUPDrvIDC.h \
+ ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPR0IdcClient.c=>SUPR0IdcClient.c \
+ ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c=>SUPR0IdcClientComponent.c \
+ ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h=>SUPR0IdcClientInternal.h \
+ ${PATH_ROOT}/src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c=>linux/SUPR0IdcClient-linux.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/divdi3.c=>math/gcc/divdi3.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/moddi3.c=>math/gcc/moddi3.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/qdivrem.c=>math/gcc/qdivrem.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/quad.h=>math/gcc/quad.h \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/udivdi3.c=>math/gcc/udivdi3.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/umoddi3.c=>math/gcc/umoddi3.c \
+ ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h=>r0drv/linux/the-linux-kernel.h \
+ ${PATH_OUT}/version-generated.h=>version-generated.h \
+ ${PATH_OUT}/product-generated.h=>product-generated.h \
+"
+
diff --git a/src/VBox/HostDrivers/VBoxUSB/Makefile.kmk b/src/VBox/HostDrivers/VBoxUSB/Makefile.kmk
index b7f6b88a5..b2774cab7 100644
--- a/src/VBox/HostDrivers/VBoxUSB/Makefile.kmk
+++ b/src/VBox/HostDrivers/VBoxUSB/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37423 2011-06-12 18:37:56Z vboxsync $
## @file
# Sub-Makefile for the Windows USB drivers.
#
@@ -34,6 +34,7 @@ USBLib_TEMPLATE = VBOXR3
USBLib_SDKS.win = WINPSDK W2K3DDK
USBLib_DEFS = IN_USBLIB
USBLib_DEFS.os2 = STATIC_USBCALLS
+USBLib_DEFS.win = _WIN32_WINNT=0x0500
USBLib_SOURCES = \
USBLib.cpp \
USBFilter.cpp
@@ -46,8 +47,7 @@ USBLib_SOURCES.os2 = \
USBLib_SOURCES.solaris = \
solaris/USBLib-solaris.cpp
USBLib_SOURCES.win = \
- win/USBLib-win.cpp
-
+ win/lib/VBoxUsbLib-win.cpp
#
# USBFilter testcase.
diff --git a/src/VBox/HostDrivers/VBoxUSB/USBFilter.cpp b/src/VBox/HostDrivers/VBoxUSB/USBFilter.cpp
index fd1882835..6c958ce09 100644
--- a/src/VBox/HostDrivers/VBoxUSB/USBFilter.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/USBFilter.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBFilter.cpp $ */
+/* $Id: USBFilter.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VirtualBox USB filter abstraction.
*/
diff --git a/src/VBox/HostDrivers/VBoxUSB/USBLib.cpp b/src/VBox/HostDrivers/VBoxUSB/USBLib.cpp
index e404a396f..c4b8011b3 100644
--- a/src/VBox/HostDrivers/VBoxUSB/USBLib.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/USBLib.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBLib.cpp $ */
+/* $Id: USBLib.cpp 31898 2010-08-24 09:28:43Z vboxsync $ */
/** @file
* VirtualBox USB Library, Common Bits.
*/
diff --git a/src/VBox/HostDrivers/VBoxUSB/VBoxUSBFilterMgr.cpp b/src/VBox/HostDrivers/VBoxUSB/VBoxUSBFilterMgr.cpp
index 16aaef68c..182373993 100644
--- a/src/VBox/HostDrivers/VBoxUSB/VBoxUSBFilterMgr.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/VBoxUSBFilterMgr.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxUSBFilterMgr.cpp $ */
+/* $Id: VBoxUSBFilterMgr.cpp 36941 2011-05-03 14:56:08Z vboxsync $ */
/** @file
* VirtualBox Ring-0 USB Filter Manager.
*/
@@ -78,7 +78,7 @@ typedef struct VBOXUSBFILTER
/** The core filter. */
USBFILTER Core;
/** The filter owner. */
- RTPROCESS Owner;
+ VBOXUSBFILTER_CONTEXT Owner;
/** The filter Id. */
uintptr_t uId;
/** Pointer to the next filter in the list. */
@@ -145,7 +145,7 @@ int VBoxUSBFilterInit(void)
static void vboxUSBFilterFree(PVBOXUSBFILTER pFilter)
{
USBFilterDelete(&pFilter->Core);
- pFilter->Owner = NIL_RTPROCESS;
+ pFilter->Owner = VBOXUSBFILTER_CONTEXT_NIL;
pFilter->pNext = NULL;
RTMemFree(pFilter);
}
@@ -188,7 +188,7 @@ void VBoxUSBFilterTerm(void)
* @param Owner The filter owner. Must be non-zero.
* @param puId Where to store the filter ID.
*/
-int VBoxUSBFilterAdd(PCUSBFILTER pFilter, RTPROCESS Owner, uintptr_t *puId)
+int VBoxUSBFilterAdd(PCUSBFILTER pFilter, VBOXUSBFILTER_CONTEXT Owner, uintptr_t *puId)
{
/*
* Validate input.
@@ -196,7 +196,7 @@ int VBoxUSBFilterAdd(PCUSBFILTER pFilter, RTPROCESS Owner, uintptr_t *puId)
int rc = USBFilterValidate(pFilter);
if (RT_FAILURE(rc))
return rc;
- if (!Owner || Owner == NIL_RTPROCESS)
+ if (!Owner || Owner == VBOXUSBFILTER_CONTEXT_NIL)
return VERR_INVALID_PARAMETER;
if (!VALID_PTR(puId))
return VERR_INVALID_POINTER;
@@ -246,14 +246,14 @@ int VBoxUSBFilterAdd(PCUSBFILTER pFilter, RTPROCESS Owner, uintptr_t *puId)
* @param uId The ID of the filter that's to be removed.
* Returned by VBoxUSBFilterAdd().
*/
-int VBoxUSBFilterRemove(RTPROCESS Owner, uintptr_t uId)
+int VBoxUSBFilterRemove(VBOXUSBFILTER_CONTEXT Owner, uintptr_t uId)
{
/*
* Validate input.
*/
if (!uId)
return VERR_INVALID_PARAMETER;
- if (!Owner || Owner == NIL_RTPROCESS)
+ if (!Owner || Owner == VBOXUSBFILTER_CONTEXT_NIL)
return VERR_INVALID_PARAMETER;
/*
@@ -301,6 +301,41 @@ int VBoxUSBFilterRemove(RTPROCESS Owner, uintptr_t uId)
return VERR_FILE_NOT_FOUND;
}
+VBOXUSBFILTER_CONTEXT VBoxUSBFilterGetOwner(uintptr_t uId)
+{
+ Assert(uId);
+ /*
+ * Validate input.
+ */
+ if (!uId)
+ return VBOXUSBFILTER_CONTEXT_NIL;
+
+ /*
+ * Result.
+ */
+ VBOXUSBFILTER_CONTEXT Owner = VBOXUSBFILTER_CONTEXT_NIL;
+
+ VBOXUSBFILTERMGR_LOCK();
+
+ for (unsigned i = USBFILTERTYPE_FIRST; i < RT_ELEMENTS(g_aLists); i++)
+ {
+ for (PVBOXUSBFILTER pCur = g_aLists[i].pHead; pCur; pCur = pCur->pNext)
+ {
+ if (pCur->uId == uId)
+ {
+ Owner = pCur->Owner;
+ Assert(Owner != VBOXUSBFILTER_CONTEXT_NIL);
+ break;
+ }
+ }
+ }
+
+ Assert(Owner != VBOXUSBFILTER_CONTEXT_NIL);
+
+ VBOXUSBFILTERMGR_UNLOCK();
+
+ return Owner;
+}
/**
* Removes all filters belonging to the specified owner.
@@ -310,7 +345,7 @@ int VBoxUSBFilterRemove(RTPROCESS Owner, uintptr_t uId)
*
* @param Owner The owner
*/
-void VBoxUSBFilterRemoveOwner(RTPROCESS Owner)
+void VBoxUSBFilterRemoveOwner(VBOXUSBFILTER_CONTEXT Owner)
{
/*
* Collect the filters that should be freed.
@@ -361,22 +396,27 @@ void VBoxUSBFilterRemoveOwner(RTPROCESS Owner)
}
}
-
/**
* Match the specified device against the filters.
+ * Unlike the VBoxUSBFilterMatch, returns Owner also if exclude filter is matched
*
- * @returns Owner on if matched, NIL_RTPROCESS it not matched.
+ * @returns Owner on if matched, VBOXUSBFILTER_CONTEXT_NIL it not matched.
* @param pDevice The device data as a filter structure.
* See USBFilterMatch for how to construct this.
* @param puId Where to store the filter id (optional).
+ * @param pfFilter Where to store whether the device must be filtered or not
*/
-RTPROCESS VBoxUSBFilterMatch(PCUSBFILTER pDevice, uintptr_t *puId)
+VBOXUSBFILTER_CONTEXT VBoxUSBFilterMatchEx(PCUSBFILTER pDevice, uintptr_t *puId, bool fRemoveFltIfOneShot, bool *pfFilter, bool *pfIsOneShot)
{
/*
* Validate input.
*/
int rc = USBFilterValidate(pDevice);
- AssertRCReturn(rc, NIL_RTPROCESS);
+ AssertRCReturn(rc, VBOXUSBFILTER_CONTEXT_NIL);
+
+ *pfFilter = false;
+ if (puId)
+ *puId = 0;
/*
* Search the lists for a match.
@@ -402,29 +442,43 @@ RTPROCESS VBoxUSBFilterMatch(PCUSBFILTER pDevice, uintptr_t *puId)
*/
if (puId)
*puId = pCur->uId;
- RTPROCESS Owner = i != USBFILTERTYPE_IGNORE
- && i != USBFILTERTYPE_ONESHOT_IGNORE
- ? pCur->Owner
- : NIL_RTPROCESS;
+ VBOXUSBFILTER_CONTEXT Owner = pCur->Owner;
+ *pfFilter = !!(i != USBFILTERTYPE_IGNORE
+ && i != USBFILTERTYPE_ONESHOT_IGNORE);
if ( i == USBFILTERTYPE_ONESHOT_IGNORE
|| i == USBFILTERTYPE_ONESHOT_CAPTURE)
{
- /* unlink */
- PVBOXUSBFILTER pNext = pCur->pNext;
- if (pPrev)
- pPrev->pNext = pNext;
- else
- g_aLists[i].pHead = pNext;
- if (!pNext)
- g_aLists[i].pTail = pPrev;
+ if (fRemoveFltIfOneShot)
+ {
+ /* unlink */
+ PVBOXUSBFILTER pNext = pCur->pNext;
+ if (pPrev)
+ pPrev->pNext = pNext;
+ else
+ g_aLists[i].pHead = pNext;
+ if (!pNext)
+ g_aLists[i].pTail = pPrev;
+ }
}
VBOXUSBFILTERMGR_UNLOCK();
if ( i == USBFILTERTYPE_ONESHOT_IGNORE
|| i == USBFILTERTYPE_ONESHOT_CAPTURE)
- vboxUSBFilterFree(pCur);
+ {
+ if (fRemoveFltIfOneShot)
+ {
+ vboxUSBFilterFree(pCur);
+ }
+ if (pfIsOneShot)
+ *pfIsOneShot = true;
+ }
+ else
+ {
+ if (pfIsOneShot)
+ *pfIsOneShot = false;
+ }
return Owner;
}
@@ -434,6 +488,28 @@ RTPROCESS VBoxUSBFilterMatch(PCUSBFILTER pDevice, uintptr_t *puId)
}
VBOXUSBFILTERMGR_UNLOCK();
- return NIL_RTPROCESS;
+ return VBOXUSBFILTER_CONTEXT_NIL;
+}
+
+/**
+ * Match the specified device against the filters.
+ *
+ * @returns Owner on if matched, VBOXUSBFILTER_CONTEXT_NIL it not matched.
+ * @param pDevice The device data as a filter structure.
+ * See USBFilterMatch for how to construct this.
+ * @param puId Where to store the filter id (optional).
+ */
+VBOXUSBFILTER_CONTEXT VBoxUSBFilterMatch(PCUSBFILTER pDevice, uintptr_t *puId)
+{
+ bool fFilter = false;
+ VBOXUSBFILTER_CONTEXT Owner = VBoxUSBFilterMatchEx(pDevice, puId,
+ true, /* remove filter is it's a one-shot*/
+ &fFilter, NULL /* bool * fIsOneShot */);
+ if (fFilter)
+ {
+ Assert(Owner != VBOXUSBFILTER_CONTEXT_NIL);
+ return Owner;
+ }
+ return VBOXUSBFILTER_CONTEXT_NIL;
}
diff --git a/src/VBox/HostDrivers/VBoxUSB/VBoxUSBFilterMgr.h b/src/VBox/HostDrivers/VBoxUSB/VBoxUSBFilterMgr.h
index bae3ebf8d..fd2a8b1d3 100644
--- a/src/VBox/HostDrivers/VBoxUSB/VBoxUSBFilterMgr.h
+++ b/src/VBox/HostDrivers/VBoxUSB/VBoxUSBFilterMgr.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxUSBFilterMgr.h $ */
+/* $Id: VBoxUSBFilterMgr.h 36941 2011-05-03 14:56:08Z vboxsync $ */
/** @file
* VirtualBox Ring-0 USB Filter Manager.
*/
@@ -22,12 +22,22 @@
RT_C_DECLS_BEGIN
+#if defined(RT_OS_WINDOWS)
+typedef struct VBOXUSBFLTCTX *VBOXUSBFILTER_CONTEXT;
+#define VBOXUSBFILTER_CONTEXT_NIL NULL
+#else
+typedef RTPROCESS VBOXUSBFILTER_CONTEXT;
+#define VBOXUSBFILTER_CONTEXT_NIL NIL_RTPROCESS
+#endif
+
int VBoxUSBFilterInit(void);
void VBoxUSBFilterTerm(void);
-void VBoxUSBFilterRemoveOwner(RTPROCESS Owner);
-int VBoxUSBFilterAdd(PCUSBFILTER pFilter, RTPROCESS Owner, uintptr_t *puId);
-int VBoxUSBFilterRemove(RTPROCESS Owner, uintptr_t uId);
-RTPROCESS VBoxUSBFilterMatch(PCUSBFILTER pDevice, uintptr_t *puId);
+void VBoxUSBFilterRemoveOwner(VBOXUSBFILTER_CONTEXT Owner);
+int VBoxUSBFilterAdd(PCUSBFILTER pFilter, VBOXUSBFILTER_CONTEXT Owner, uintptr_t *puId);
+int VBoxUSBFilterRemove(VBOXUSBFILTER_CONTEXT Owner, uintptr_t uId);
+VBOXUSBFILTER_CONTEXT VBoxUSBFilterMatch(PCUSBFILTER pDevice, uintptr_t *puId);
+VBOXUSBFILTER_CONTEXT VBoxUSBFilterMatchEx(PCUSBFILTER pDevice, uintptr_t *puId, bool fRemoveFltIfOneShot, bool *pfFilter, bool *pfIsOneShot);
+VBOXUSBFILTER_CONTEXT VBoxUSBFilterGetOwner(uintptr_t uId);
RT_C_DECLS_END
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/Info.plist b/src/VBox/HostDrivers/VBoxUSB/darwin/Info.plist
index bf3d2c402..512671d0b 100644
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/Info.plist
+++ b/src/VBox/HostDrivers/VBoxUSB/darwin/Info.plist
@@ -30,7 +30,7 @@
<key>idVendor</key> <string>*</string>
<key>idProduct</key> <string>*</string>
<key>bcdDevice</key> <string>*</string>
- <key>IOProbeScore</key> <string>9942</string>
+ <key>IOProbeScore</key> <integer>9942</integer>
<key>IOProviderMergeProperties</key>
<dict>
<key>IOCFPlugInTypes</key>
@@ -50,7 +50,7 @@
<key>bcdDevice</key> <string>*</string>
<key>bConfigurationValue</key> <string>*</string>
<key>bInterfaceNumber</key> <string>*</string>
- <key>IOProbeScore</key> <string>9942</string>
+ <key>IOProbeScore</key> <integer>9942</integer>
<key>IOProviderMergeProperties</key>
<dict>
<key>IOCFPlugInTypes</key>
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/Makefile.kmk b/src/VBox/HostDrivers/VBoxUSB/darwin/Makefile.kmk
index 7bf288e80..d6a0ecda6 100644
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/Makefile.kmk
+++ b/src/VBox/HostDrivers/VBoxUSB/darwin/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Sub-Makefile for the Darwin VBoxUSB kernel extension.
#
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/USBLib-darwin.cpp b/src/VBox/HostDrivers/VBoxUSB/darwin/USBLib-darwin.cpp
index c55829726..d00784485 100644
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/USBLib-darwin.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/darwin/USBLib-darwin.cpp
@@ -1,4 +1,4 @@
-/** $Id: USBLib-darwin.cpp $ */
+/** $Id: USBLib-darwin.cpp 31898 2010-08-24 09:28:43Z vboxsync $ */
/** @file
* USBLib - Library for wrapping up the VBoxUSB functionality, Darwin flavor.
*/
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSB.cpp b/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSB.cpp
index 64945f997..c967bbd7c 100644
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSB.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSB.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxUSB.cpp $ */
+/* $Id: VBoxUSB.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VirtualBox USB driver for Darwin.
*
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSBInterface.h b/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSBInterface.h
index 6b39bcfd5..f3f2b8275 100644
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSBInterface.h
+++ b/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSBInterface.h
@@ -1,4 +1,4 @@
-/** $Id: VBoxUSBInterface.h $ */
+/** $Id: VBoxUSBInterface.h 31898 2010-08-24 09:28:43Z vboxsync $ */
/** @file
* VirtualBox USB Driver User<->Kernel Interface.
*/
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/testcase/tstOpenUSBDev.cpp b/src/VBox/HostDrivers/VBoxUSB/darwin/testcase/tstOpenUSBDev.cpp
index a2e879172..9eaa8aaef 100644
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/testcase/tstOpenUSBDev.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/darwin/testcase/tstOpenUSBDev.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstOpenUSBDev.cpp $ */
+/* $Id: tstOpenUSBDev.cpp 31898 2010-08-24 09:28:43Z vboxsync $ */
/** @file
* Testcase that attempts to locate and open the specfied device.
*/
@@ -206,7 +206,7 @@ int main(int argc, char **argv)
case 'h':
return tstSyntax(argv[0]);
case 'V':
- RTPrintf("$Revision: 65108 $\n");
+ RTPrintf("$Revision: 31898 $\n");
return 0;
default:
diff --git a/src/VBox/HostDrivers/VBoxUSB/solaris/Makefile.kmk b/src/VBox/HostDrivers/VBoxUSB/solaris/Makefile.kmk
index cfb87be6e..b2da85822 100644
--- a/src/VBox/HostDrivers/VBoxUSB/solaris/Makefile.kmk
+++ b/src/VBox/HostDrivers/VBoxUSB/solaris/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37149 2011-05-19 11:59:08Z vboxsync $
## @file
# Sub-Makefile for the Solaris VBoxUSB kernel extension.
#
diff --git a/src/VBox/HostDrivers/VBoxUSB/solaris/USBLib-solaris.cpp b/src/VBox/HostDrivers/VBoxUSB/solaris/USBLib-solaris.cpp
index d85fb3cb3..20e149309 100644
--- a/src/VBox/HostDrivers/VBoxUSB/solaris/USBLib-solaris.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/solaris/USBLib-solaris.cpp
@@ -1,4 +1,4 @@
-/** $Id: USBLib-solaris.cpp $ */
+/** $Id: USBLib-solaris.cpp 37151 2011-05-19 12:12:16Z vboxsync $ */
/** @file
* USBLib - Library for wrapping up the VBoxUSB functionality, Solaris flavor.
*/
@@ -199,17 +199,17 @@ USBLIB_DECL(int) USBLibGetClientInfo(char *pszDeviceIdent, char **ppszClientPath
VBOXUSBREQ_CLIENT_INFO Req;
bzero(&Req, sizeof(Req));
- RTStrPrintf(Req.achDeviceIdent, sizeof(Req.achDeviceIdent), "%s", pszDeviceIdent);
+ RTStrPrintf(Req.szDeviceIdent, sizeof(Req.szDeviceIdent), "%s", pszDeviceIdent);
int rc = usblibDoIOCtl(VBOXUSBMON_IOCTL_CLIENT_INFO, &Req, sizeof(Req));
if (RT_SUCCESS(rc))
{
*pInstance = Req.Instance;
- rc = RTStrDupEx(ppszClientPath, Req.achClientPath);
+ rc = RTStrDupEx(ppszClientPath, Req.szClientPath);
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
- LogRel((USBLIBR3 ":USBLibGetClientInfo RTStrAPrintf failed! rc=%Rrc achClientPath=%s\n", rc, Req.achClientPath));
+ LogRel((USBLIBR3 ":USBLibGetClientInfo RTStrDupEx failed! rc=%Rrc szClientPath=%s\n", rc, Req.szClientPath));
}
else
LogRel((USBLIBR3 ":USBLibGetClientInfo VBOXUSBMON_IOCTL_CLIENTPATH failed! rc=%Rrc\n", rc));
diff --git a/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c b/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c
index 4b43420c0..6da399aeb 100644
--- a/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c
+++ b/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxUSB-solaris.c $ */
+/* $Id: VBoxUSB-solaris.c 38017 2011-07-18 13:24:08Z vboxsync $ */
/** @file
* VirtualBox USB Client Driver, Solaris Hosts.
*/
@@ -351,6 +351,9 @@ LOCAL void vboxUSBSolarisPowerIdle(vboxusb_state_t *pState);
int VBoxUSBMonSolarisRegisterClient(dev_info_t *pClientDip, PVBOXUSB_CLIENT_INFO pClientInfo);
int VBoxUSBMonSolarisUnregisterClient(dev_info_t *pClientDip);
+/** Callbacks from Monitor */
+LOCAL int vboxUSBSolarisSetConsumerCredentials(RTPROCESS Process, int Instance, void *pvReserved);
+
/*******************************************************************************
* Global Variables *
@@ -463,7 +466,7 @@ int VBoxUSBSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
if (rc == DDI_SUCCESS)
{
pState = ddi_get_soft_state(g_pVBoxUSBSolarisState, instance);
- if (pState)
+ if (RT_LIKELY(pState))
{
pState->pDip = pDip;
pState->pDevDesc = NULL;
@@ -555,25 +558,32 @@ int VBoxUSBSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
bzero(&pState->ClientInfo, sizeof(pState->ClientInfo));
char szDevicePath[MAXPATHLEN];
ddi_pathname(pState->pDip, szDevicePath);
- RTStrPrintf(pState->ClientInfo.achClientPath, sizeof(pState->ClientInfo.achClientPath),
+ RTStrPrintf(pState->ClientInfo.szClientPath, sizeof(pState->ClientInfo.szClientPath),
"/devices%s:%s",
szDevicePath,
DEVICE_NAME);
RTPathStripFilename(szDevicePath);
- RTStrPrintf(pState->ClientInfo.achDeviceIdent, sizeof(pState->ClientInfo.achDeviceIdent),
+ RTStrPrintf(pState->ClientInfo.szDeviceIdent, sizeof(pState->ClientInfo.szDeviceIdent),
"%#x:%#x:%d:%s",
pState->pDevDesc->dev_descr->idVendor,
pState->pDevDesc->dev_descr->idProduct,
pState->pDevDesc->dev_descr->bcdDevice,
szDevicePath);
pState->ClientInfo.Instance = instance;
+ pState->ClientInfo.pfnSetConsumerCredentials = &vboxUSBSolarisSetConsumerCredentials;
rc = VBoxUSBMonSolarisRegisterClient(pState->pDip, &pState->ClientInfo);
if (RT_SUCCESS(rc))
+ {
+ LogRel((DEVICE_NAME ": Captured %s %s\n",
+ pState->pDevDesc->dev_product ? pState->pDevDesc->dev_product : "<Unnamed USB device>",
+ pState->ClientInfo.szDeviceIdent));
+
return DDI_SUCCESS;
+ }
else
{
LogRel((DEVICE_NAME ":VBoxUSBMonSolarisRegisterClient failed! rc=%d path=%s instance=%d\n",
- rc, pState->ClientInfo.achClientPath, instance));
+ rc, pState->ClientInfo.szClientPath, instance));
}
usb_unregister_event_cbs(pState->pDip, &g_VBoxUSBSolarisEvents);
@@ -738,6 +748,10 @@ int VBoxUSBSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
ddi_remove_minor_node(pState->pDip, NULL);
+ LogRel((DEVICE_NAME ": Released %s %s\n",
+ pState->pDevDesc->dev_product ? pState->pDevDesc->dev_product : "<Unnamed USB device>",
+ pState->ClientInfo.szDeviceIdent));
+
ddi_soft_state_free(g_pVBoxUSBSolarisState, instance);
pState = NULL;
@@ -806,6 +820,45 @@ int VBoxUSBSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pvArg,
}
+/**
+ * Callback invoked from the Monitor driver when a VM process tries to access
+ * this client instance. This determines which VM process will be allowed to
+ * open and access the USB device.
+ *
+ * @returns VBox status code.
+ *
+ * @param Process The VM process performing the client info. query.
+ * @param Instance This client instance (the one set while we register
+ * ourselves to the Monitor driver)
+ * @param pvReserved Reserved for future, unused.
+ */
+LOCAL int vboxUSBSolarisSetConsumerCredentials(RTPROCESS Process, int Instance, void *pvReserved)
+{
+ LogFlowFunc((DEVICE_NAME ":vboxUSBSolarisSetConsumerCredentials Process=%u Instance=%d\n", Process, Instance));
+ vboxusb_state_t *pState = ddi_get_soft_state(g_pVBoxUSBSolarisState, Instance);
+ if (!pState)
+ {
+ LogRel((DEVICE_NAME ":vboxUSBSolarisSetConsumerCredentials failed to get device state for instance %d\n", Instance));
+ return VERR_INVALID_STATE;
+ }
+
+ int rc = VINF_SUCCESS;
+ mutex_enter(&pState->Mtx);
+
+ if (pState->Process == NIL_RTPROCESS)
+ pState->Process = Process;
+ else
+ {
+ LogRel((DEVICE_NAME ":vboxUSBSolarisSetConsumerCredentials failed! Process %u already has client open.\n", pState->Process));
+ rc = VERR_RESOURCE_BUSY;
+ }
+
+ mutex_exit(&pState->Mtx);
+
+ return rc;
+}
+
+
int VBoxUSBSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
{
LogFlowFunc((DEVICE_NAME ":VBoxUSBSolarisOpen pDev=%p fFlag=%d fType=%d pCred=%p\n", pDev, fFlag, fType, pCred));
@@ -827,18 +880,26 @@ int VBoxUSBSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
return ENXIO;
}
+ mutex_enter(&pState->Mtx);
+
/*
* Only one user process can open a device instance at a time.
*/
- if (pState->Process != NIL_RTPROCESS)
+ if (pState->Process != RTProcSelf())
{
- LogRel((DEVICE_NAME ":VBoxUSBSolarisOpen a process is already using this device instance.\n"));
- return EBUSY;
+ if (pState->Process == NIL_RTPROCESS)
+ LogRel((DEVICE_NAME ":VBoxUSBSolarisOpen No prior information about authorized process.\n"));
+ else
+ LogRel((DEVICE_NAME ":VBoxUSBSolarisOpen Process %d is already using this device instance.\n", pState->Process));
+
+ mutex_exit(&pState->Mtx);
+ return EPERM;
}
- pState->Process = RTProcSelf();
pState->fPoll = VBOXUSB_POLL_ON;
+ mutex_exit(&pState->Mtx);
+
NOREF(fFlag);
NOREF(pCred);
@@ -1559,8 +1620,8 @@ LOCAL int vboxUSBSolarisSendURB(vboxusb_state_t *pState, PVBOXUSBREQ_URB pUrbReq
vboxusb_ep_t *pEp = &pState->aEps[EndPtIndex];
AssertPtrReturn(pEp, VERR_INVALID_POINTER);
-// LogFlowFunc((DEVICE_NAME ":vboxUSBSolarisSendUrb pState=%p pUrbReq=%p bEndpoint=%#x[%d] enmDir=%#x enmType=%#x cbData=%d pvData=%p\n",
-// pState, pUrbReq, pUrbReq->bEndpoint, EndPtIndex, pUrbReq->enmDir, pUrbReq->enmType, pUrbReq->cbData, pUrbReq->pvData));
+ /* LogFlowFunc((DEVICE_NAME ":vboxUSBSolarisSendUrb pState=%p pUrbReq=%p bEndpoint=%#x[%d] enmDir=%#x enmType=%#x cbData=%d pvData=%p\n",
+ pState, pUrbReq, pUrbReq->bEndpoint, EndPtIndex, pUrbReq->enmDir, pUrbReq->enmType, pUrbReq->cbData, pUrbReq->pvData)); */
if (RT_UNLIKELY(!pUrbReq->pvData))
{
diff --git a/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSBMon-solaris.c b/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSBMon-solaris.c
index 4ce34cee7..e1861d5ef 100644
--- a/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSBMon-solaris.c
+++ b/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSBMon-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxUSBMon-solaris.c $ */
+/* $Id: VBoxUSBMon-solaris.c 38016 2011-07-18 13:06:11Z vboxsync $ */
/** @file
* VirtualBox USB Monitor Driver, Solaris Hosts.
*/
@@ -164,13 +164,13 @@ typedef struct
* Global Variables *
*******************************************************************************/
/** Global Device handle we only support one instance. */
-static dev_info_t *g_pDip;
+static dev_info_t *g_pDip = NULL;
/** Global Mutex. */
static kmutex_t g_VBoxUSBMonSolarisMtx;
/** Number of userland clients that have kept us open. */
static uint64_t g_cVBoxUSBMonSolarisClient = 0;
/** Global list of client drivers registered with us. */
-vboxusbmon_client_t *g_pVBoxUSBMonSolarisClients = 0;
+vboxusbmon_client_t *g_pVBoxUSBMonSolarisClients = NULL;
/** Opaque pointer to list of soft states. */
static void *g_pVBoxUSBMonSolarisState;
@@ -292,28 +292,23 @@ static int VBoxUSBMonSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
{
case DDI_ATTACH:
{
- vboxusbmon_state_t *pState = NULL;
- int instance = ddi_get_instance(pDip);
- int rc;
+ if (RT_UNLIKELY(g_pDip))
+ {
+ LogRel((DEVICE_NAME ":VBoxUSBMonSolarisAttach global instance already initialized.\n"));
+ return DDI_FAILURE;
+ }
- pState = RTMemAllocZ(sizeof(*pState));
- if (pState)
+ g_pDip = pDip;
+ int instance = ddi_get_instance(pDip);
+ int rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0,
+ "none", "none", 0660);
+ if (rc == DDI_SUCCESS)
{
- g_pDip = pDip;
- rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0,
- "none", "none", 0666);
- if (rc == DDI_SUCCESS)
- {
- ddi_set_driver_private(pDip, pState);
- ddi_report_dev(pDip);
- return rc;
- }
- else
- LogRel((DEVICE_NAME ":ddi_create_minor_node failed! rc=%d\n", rc));
- RTMemFree(pState);
+ ddi_report_dev(pDip);
+ return rc;
}
else
- LogRel((DEVICE_NAME ":RTMemAllocZ failed to allocated %d bytes for pState\n", sizeof(*pState)));
+ LogRel((DEVICE_NAME ":VBoxUSBMonSolarisAttach ddi_create_minor_node failed! rc=%d\n", rc));
return DDI_FAILURE;
}
@@ -358,16 +353,9 @@ static int VBoxUSBMonSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
}
mutex_exit(&g_VBoxUSBMonSolarisMtx);
- vboxusbmon_state_t *pState = ddi_get_driver_private(g_pDip);
- if (pState)
- {
- ddi_remove_minor_node(pDip, NULL);
- RTMemFree(pState);
- return DDI_SUCCESS;
- }
- else
- LogRel((DEVICE_NAME ":failed to get soft state on detach.\n"));
- break;
+ ddi_remove_minor_node(pDip, NULL);
+ g_pDip = NULL;
+ return DDI_SUCCESS;
}
case DDI_SUSPEND:
@@ -852,6 +840,15 @@ static int vboxUSBMonSolarisResetDevice(char *pszDevicePath, bool fReattach)
return rc;
}
+
+/**
+ * Query client driver information. This also has a side-effect that it informs
+ * the client driver which upcoming VM process should be allowed to open it.
+ *
+ * @returns VBox status code.
+ * @param pState Pointer to the device state.
+ * @param pClientInfo Pointer to the client info. object.
+ */
static int vboxUSBMonSolarisClientInfo(vboxusbmon_state_t *pState, PVBOXUSB_CLIENT_INFO pClientInfo)
{
LogFlowFunc((DEVICE_NAME ":vboxUSBMonSolarisClientInfo pState=%p pClientInfo=%p\n", pState, pClientInfo));
@@ -864,15 +861,28 @@ static int vboxUSBMonSolarisClientInfo(vboxusbmon_state_t *pState, PVBOXUSB_CLIE
vboxusbmon_client_t *pPrev = NULL;
while (pCur)
{
- if (strncmp(pClientInfo->achDeviceIdent, pCur->Info.achDeviceIdent, sizeof(pCur->Info.achDeviceIdent) - 1) == 0)
+ if (strncmp(pClientInfo->szDeviceIdent, pCur->Info.szDeviceIdent, sizeof(pCur->Info.szDeviceIdent) - 1) == 0)
{
pClientInfo->Instance = pCur->Info.Instance;
- RTStrPrintf(pClientInfo->achClientPath, sizeof(pClientInfo->achClientPath), "%s", pCur->Info.achClientPath);
+ RTStrPrintf(pClientInfo->szClientPath, sizeof(pClientInfo->szClientPath), "%s", pCur->Info.szClientPath);
+
+ /*
+ * Inform the client driver that this is the client process that is going to open it. We can predict the future!
+ */
+ int rc;
+ if (pCur->Info.pfnSetConsumerCredentials)
+ {
+ rc = pCur->Info.pfnSetConsumerCredentials(pState->Process, pCur->Info.Instance, NULL /* pvReserved */);
+ if (RT_FAILURE(rc))
+ LogRel((DEVICE_NAME ":vboxUSBMonSolarisClientInfo pfnSetConsumerCredentials failed. rc=%d\n", rc));
+ }
+ else
+ rc = VERR_INVALID_FUNCTION;
mutex_exit(&g_VBoxUSBMonSolarisMtx);
- LogFlow((DEVICE_NAME ":vboxUSBMonSolarisClientInfo found. %s\n", pClientInfo->achDeviceIdent));
- return VINF_SUCCESS;
+ LogFlow((DEVICE_NAME ":vboxUSBMonSolarisClientInfo found. %s rc=%d\n", pClientInfo->szDeviceIdent, rc));
+ return rc;
}
pPrev = pCur;
pCur = pCur->pNext;
@@ -880,7 +890,7 @@ static int vboxUSBMonSolarisClientInfo(vboxusbmon_state_t *pState, PVBOXUSB_CLIE
mutex_exit(&g_VBoxUSBMonSolarisMtx);
- LogRel((DEVICE_NAME ":vboxUSBMonSolarisClientInfo Failed to find client %s\n", pClientInfo->achDeviceIdent));
+ LogRel((DEVICE_NAME ":vboxUSBMonSolarisClientInfo Failed to find client %s\n", pClientInfo->szDeviceIdent));
return VERR_NOT_FOUND;
}
@@ -899,34 +909,30 @@ int VBoxUSBMonSolarisRegisterClient(dev_info_t *pClientDip, PVBOXUSB_CLIENT_INFO
if (RT_LIKELY(g_pDip))
{
- vboxusbmon_state_t *pState = ddi_get_driver_private(g_pDip);
-
- if (RT_LIKELY(pState))
+ vboxusbmon_client_t *pClient = RTMemAllocZ(sizeof(vboxusbmon_client_t));
+ if (RT_LIKELY(pClient))
{
- vboxusbmon_client_t *pClient = RTMemAlloc(sizeof(vboxusbmon_client_t));
- if (RT_LIKELY(pClient))
- {
- bcopy(pClientInfo, &pClient->Info, sizeof(pClient->Info));
- pClient->pDip = pClientDip;
+ pClient->Info.Instance = pClientInfo->Instance;
+ strncpy(pClient->Info.szClientPath, pClientInfo->szClientPath, sizeof(pClient->Info.szClientPath));
+ strncpy(pClient->Info.szDeviceIdent, pClientInfo->szDeviceIdent, sizeof(pClient->Info.szDeviceIdent));
+ pClient->Info.pfnSetConsumerCredentials = pClientInfo->pfnSetConsumerCredentials;
+ pClient->pDip = pClientDip;
- mutex_enter(&g_VBoxUSBMonSolarisMtx);
- pClient->pNext = g_pVBoxUSBMonSolarisClients;
- g_pVBoxUSBMonSolarisClients = pClient;
- mutex_exit(&g_VBoxUSBMonSolarisMtx);
+ mutex_enter(&g_VBoxUSBMonSolarisMtx);
+ pClient->pNext = g_pVBoxUSBMonSolarisClients;
+ g_pVBoxUSBMonSolarisClients = pClient;
+ mutex_exit(&g_VBoxUSBMonSolarisMtx);
- LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisRegisterClient registered. %d %s %s\n",
- pClient->Info.Instance, pClient->Info.achClientPath, pClient->Info.achDeviceIdent));
+ LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisRegisterClient registered. %d %s %s\n",
+ pClient->Info.Instance, pClient->Info.szClientPath, pClient->Info.szDeviceIdent));
- return VINF_SUCCESS;
- }
- else
- return VERR_NO_MEMORY;
+ return VINF_SUCCESS;
}
else
- return VERR_INTERNAL_ERROR;
+ return VERR_NO_MEMORY;
}
else
- return VERR_INTERNAL_ERROR_2;
+ return VERR_INVALID_STATE;
}
@@ -940,48 +946,42 @@ int VBoxUSBMonSolarisRegisterClient(dev_info_t *pClientDip, PVBOXUSB_CLIENT_INFO
int VBoxUSBMonSolarisUnregisterClient(dev_info_t *pClientDip)
{
LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient pClientDip=%p\n", pClientDip));
+ AssertReturn(pClientDip, VERR_INVALID_PARAMETER);
if (RT_LIKELY(g_pDip))
{
- vboxusbmon_state_t *pState = ddi_get_driver_private(g_pDip);
+ mutex_enter(&g_VBoxUSBMonSolarisMtx);
- if (RT_LIKELY(pState))
+ vboxusbmon_client_t *pCur = g_pVBoxUSBMonSolarisClients;
+ vboxusbmon_client_t *pPrev = NULL;
+ while (pCur)
{
- mutex_enter(&g_VBoxUSBMonSolarisMtx);
-
- vboxusbmon_client_t *pCur = g_pVBoxUSBMonSolarisClients;
- vboxusbmon_client_t *pPrev = NULL;
- while (pCur)
+ if (pCur->pDip == pClientDip)
{
- if (pCur->pDip == pClientDip)
- {
- if (pPrev)
- pPrev->pNext = pCur->pNext;
- else
- g_pVBoxUSBMonSolarisClients = pCur->pNext;
-
- mutex_exit(&g_VBoxUSBMonSolarisMtx);
-
- LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient unregistered. %d %s %s\n",
- pCur->Info.Instance, pCur->Info.achClientPath, pCur->Info.achDeviceIdent));
- RTMemFree(pCur);
- pCur = NULL;
- return VINF_SUCCESS;
- }
- pPrev = pCur;
- pCur = pCur->pNext;
- }
+ if (pPrev)
+ pPrev->pNext = pCur->pNext;
+ else
+ g_pVBoxUSBMonSolarisClients = pCur->pNext;
- mutex_exit(&g_VBoxUSBMonSolarisMtx);
+ mutex_exit(&g_VBoxUSBMonSolarisMtx);
- LogRel((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient Failed to find registered client %p\n", pClientDip));
- return VERR_SEARCH_ERROR;
+ LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient unregistered. %d %s %s\n",
+ pCur->Info.Instance, pCur->Info.szClientPath, pCur->Info.szDeviceIdent));
+ RTMemFree(pCur);
+ pCur = NULL;
+ return VINF_SUCCESS;
+ }
+ pPrev = pCur;
+ pCur = pCur->pNext;
}
- else
- return VERR_INTERNAL_ERROR;
+
+ mutex_exit(&g_VBoxUSBMonSolarisMtx);
+
+ LogRel((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient Failed to find registered client %p\n", pClientDip));
+ return VERR_NOT_FOUND;
}
else
- return VERR_INTERNAL_ERROR_2;
+ return VERR_INVALID_STATE;
}
diff --git a/src/VBox/HostDrivers/VBoxUSB/testcase/tstUSBFilter.cpp b/src/VBox/HostDrivers/VBoxUSB/testcase/tstUSBFilter.cpp
index d19edb4ed..c41a6448e 100644
--- a/src/VBox/HostDrivers/VBoxUSB/testcase/tstUSBFilter.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/testcase/tstUSBFilter.cpp
@@ -1,4 +1,4 @@
-/** $Id: tstUSBFilter.cpp $ */
+/** $Id: tstUSBFilter.cpp 31898 2010-08-24 09:28:43Z vboxsync $ */
/** @file
* VirtualBox USB filter abstraction - testcase.
*/
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxdev.cpp b/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxdev.cpp
deleted file mode 100644
index e05f7393a..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxdev.cpp
+++ /dev/null
@@ -1,3103 +0,0 @@
-/*++
-
-Copyright (c) 2000 Microsoft Corporation
-
-Module Name:
-
- vboxdev.cpp
-
-Abstract:
-
- This file contains dispatch routines for create,
- close and selective suspend.
- The selective suspend feature is enabled if
- the SSRegistryEnable key in the registry is set to 1.
-
-Environment:
-
- Kernel mode
-
-Notes:
-
- Copyright (c) 2000 Microsoft Corporation.
- All Rights Reserved.
-
---*/
-
-#include "vboxusb.h"
-#include "vboxpnp.h"
-#include "vboxpwr.h"
-#include "vboxdev.h"
-#include "vboxrwr.h"
-#include <iprt/assert.h>
-#include <VBox/usblib.h>
-#include <usbioctl.h>
-#define _USBD_
-#include <usbdlib.h>
-#include <usbbusif.h>
-
-
-static NTSTATUS VBoxUSBSetConfig(PDEVICE_EXTENSION pDevice, unsigned uConfiguration);
-static NTSTATUS VBoxUSBSetInterface(PDEVICE_EXTENSION pDevice, uint32_t InterfaceNumber, int AlternateSetting);
-static NTSTATUS VBoxUSBClearEndpoint(PDEVICE_EXTENSION pDevice, uint32_t EndPointAddress, bool fReset);
-static NTSTATUS VBoxUSBClearPipe(PDEVICE_EXTENSION pDevice, HANDLE PipeHandle, bool fReset);
-static HANDLE VBoxUSBGetPipeHandle(PDEVICE_EXTENSION pDevice, uint32_t EndPointAddress);
-static void VBoxUSBFreeInterfaces(PDEVICE_EXTENSION pDevice, bool fAbortPipes);
-static NTSTATUS VBoxUSBGetDeviceDescription(PDEVICE_EXTENSION pDevice);
-static NTSTATUS VBoxUSBGetDeviceSpeed(PDEVICE_EXTENSION pDevExt);
- NTSTATUS VBoxUSBSendIOCTL(PDEVICE_EXTENSION pDevice, ULONG control_code, void *buffer);
- NTSTATUS VBoxUSBSendURB(PDEVICE_EXTENSION pDevExt, PIRP pIrp, PUSBSUP_URB pIn, PUSBSUP_URB pOut);
- NTSTATUS VBoxUSBSyncSendRequest(PDEVICE_EXTENSION deviceExtension, ULONG control_code, void *buffer);
-
-
-/**
- * Get USB descriptor
- *
- * @returns NT Status
- * @param Pdo Device object
- * @param buffer Descriptor buffer
- * @param size size of buffer
- * @param type descriptor type
- * @param index descriptor index
- * @param language_id descriptor language id
- */
-NTSTATUS VBoxUSBGetDescriptor(PDEVICE_EXTENSION pDevice, void *buffer, int size, int type, int index, int language_id)
-{
- NTSTATUS rc;
- PURB urb;
-
- urb = (PURB)ExAllocatePool(NonPagedPool,sizeof(URB));
- if(urb == NULL)
- {
- dprintf(("Failed to alloc mem for urb\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- memset(urb, 0, sizeof(*urb));
-
- urb->UrbHeader.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE;
- urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
- urb->UrbControlDescriptorRequest.TransferBufferLength = size;
- urb->UrbControlDescriptorRequest.TransferBuffer = buffer;
- urb->UrbControlDescriptorRequest.Index = (UCHAR)index;
- urb->UrbControlDescriptorRequest.DescriptorType = (UCHAR)type;
- urb->UrbControlDescriptorRequest.LanguageId = (USHORT)language_id;
-
- rc = VBoxUSBSendIOCTL(pDevice, IOCTL_INTERNAL_USB_SUBMIT_URB, urb);
- if(!NT_SUCCESS(rc) || !USBD_SUCCESS(urb->UrbHeader.Status))
- {
- dprintf(("VBoxUSBGetDescriptor: VBoxUSBSendIOCTL failed with %x (%x)\n", rc, urb->UrbHeader.Status));
- }
- ExFreePool(urb);
- return rc;
-}
-
-/**
- * Free cached USB device/configuration descriptors
- *
- * @param pDevice USB device pointer
- */
-static void VBoxUSBFreeCachedDescriptors(PDEVICE_EXTENSION pDevice)
-{
- unsigned i;
-
- if (pDevice->usbdev.devdescr)
- {
- ExFreePool(pDevice->usbdev.devdescr);
- pDevice->usbdev.devdescr = NULL;
- }
- for (i = 0; i < MAX_CFGS; ++i)
- {
- if (pDevice->usbdev.cfgdescr[i])
- {
- ExFreePool(pDevice->usbdev.cfgdescr[i]);
- pDevice->usbdev.cfgdescr[i] = NULL;
- }
- }
-}
-
-/**
- * Cache USB device/configuration descriptors
- *
- * @returns NT Status
- * @param pDevice USB device pointer
- */
-static NTSTATUS VBoxUSBCacheDescriptors(PDEVICE_EXTENSION pDevice)
-{
- NTSTATUS status;
- USB_CONFIGURATION_DESCRIPTOR *tmp_cfgdescr = NULL;
- uint32_t uTotalLength;
- unsigned i;
-
- /* Reading descriptors is relatively expensive and they aren't going to change
- * except possibly when the device is reset (and even then only very rarely).
- */
-
- /* Read device descriptor */
- pDevice->usbdev.devdescr = (PUSB_DEVICE_DESCRIPTOR)ExAllocatePool(NonPagedPool, sizeof(USB_DEVICE_DESCRIPTOR));
- if (pDevice->usbdev.devdescr == NULL)
- {
- dprintf(("Failed to alloc mem for device descriptor\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto end;
- }
- memset(pDevice->usbdev.devdescr, 0, sizeof(USB_DEVICE_DESCRIPTOR));
-
- status = VBoxUSBGetDescriptor(pDevice, pDevice->usbdev.devdescr, sizeof(USB_DEVICE_DESCRIPTOR), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0);
- if (!NT_SUCCESS(status))
- {
- AssertMsgFailed(("VBoxUSBCacheDescriptors: getting device descriptor failed\n"));
- goto end;
- }
- Assert(pDevice->usbdev.devdescr->bNumConfigurations > 0);
- dprintf(("Nr of configurations %d\n", pDevice->usbdev.devdescr->bNumConfigurations));
-
- tmp_cfgdescr = (USB_CONFIGURATION_DESCRIPTOR *) ExAllocatePool(NonPagedPool, sizeof(USB_CONFIGURATION_DESCRIPTOR));
- if (!tmp_cfgdescr)
- {
- AssertMsgFailed(("VBoxUSBCacheDescriptors: ExAllocatePool failed\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto end;
- }
-
- /* Read descriptors for all configurations */
- for (i = 0; i < pDevice->usbdev.devdescr->bNumConfigurations; ++i)
- {
- status = VBoxUSBGetDescriptor(pDevice, tmp_cfgdescr, sizeof(USB_CONFIGURATION_DESCRIPTOR), USB_CONFIGURATION_DESCRIPTOR_TYPE, i, 0);
- if (!NT_SUCCESS(status))
- {
- AssertMsgFailed(("VBoxUSBCacheDescriptors: VBoxUSBGetDescriptor (cfg %d) failed with %x\n", i + 1, status));
- goto end;
- }
-
- uTotalLength = tmp_cfgdescr->wTotalLength;
- dprintf(("Total length = %d\n", tmp_cfgdescr->wTotalLength));
-
- pDevice->usbdev.cfgdescr[i] = (USB_CONFIGURATION_DESCRIPTOR *)ExAllocatePool(NonPagedPool, uTotalLength);
- if (!pDevice->usbdev.cfgdescr[i])
- {
- AssertMsgFailed(("VBoxUSBCacheDescriptors: ExAllocatePool failed!\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto end;
- }
-
- status = VBoxUSBGetDescriptor(pDevice, pDevice->usbdev.cfgdescr[i], uTotalLength, USB_CONFIGURATION_DESCRIPTOR_TYPE, i, 0);
- if (!NT_SUCCESS(status))
- {
- AssertMsgFailed(("VBoxUSBCacheDescriptors: VBoxUSBGetDescriptor (cfg %d) failed with %x\n", i + 1, status));
- goto end;
- }
- }
-
-end:
- if (tmp_cfgdescr) ExFreePool(tmp_cfgdescr);
-
- return status;
-}
-
-/**
- * Free memory allocated by this module
- *
- * @param pDevice USB device pointer
- */
-VOID VBoxUSB_FreeMemory(PDEVICE_EXTENSION DeviceExtension)
-{
- VBoxUSBFreeCachedDescriptors(DeviceExtension);
- VBoxUSBFreeInterfaces(DeviceExtension, FALSE);
-}
-
-NTSTATUS
-VBoxUSB_DispatchCreate(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- Dispatch routine for create.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet.
-
-Return Value:
-
- NT status value
-
---*/
-{
-// ULONG i;
- NTSTATUS ntStatus;
- PFILE_OBJECT fileObject;
- PDEVICE_EXTENSION deviceExtension;
- PIO_STACK_LOCATION irpStack;
-// PVBOXUSB_PIPE_CONTEXT pipeContext;
-// PUSBD_INTERFACE_INFORMATION interface;
-
- PAGED_CODE();
-
- dprintf(("VBoxUSB_DispatchCreate - begins\n"));
-
- //
- // initialize variables
- //
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- fileObject = irpStack->FileObject;
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- if(deviceExtension->DeviceState != Working) {
-
- ntStatus = STATUS_INVALID_DEVICE_STATE;
- goto VBoxUSB_DispatchCreate_Exit;
- }
-
-#if 0
- if(deviceExtension->UsbInterface) {
-
- interface = deviceExtension->UsbInterface;
- }
- else {
-
- dprintf(("UsbInterface not found\n"));
-
- ntStatus = STATUS_INVALID_DEVICE_STATE;
- goto VBoxUSB_DispatchCreate_Exit;
- }
-#endif
-
- //
- // FsContext is Null for the device
- //
- if(fileObject) {
-
- fileObject->FsContext = NULL;
- }
- else {
-
- ntStatus = STATUS_INVALID_PARAMETER;
- goto VBoxUSB_DispatchCreate_Exit;
- }
-
- if(0 == fileObject->FileName.Length) {
-
- //
- // opening a device as opposed to pipe.
- //
- ntStatus = STATUS_SUCCESS;
-
- InterlockedIncrement(&deviceExtension->OpenHandleCount);
-
- //
- // the device is idle if it has no open handles or pending PnP Irps
- // since we just received an open handle request, cancel idle req.
- //
- if(deviceExtension->SSEnable) {
-
- CancelSelectSuspend(deviceExtension);
- }
-
- goto VBoxUSB_DispatchCreate_Exit;
- }
-
-#if 0
- pipeContext = VBoxUSB_PipeWithName(DeviceObject, &fileObject->FileName);
-
- if(pipeContext == NULL) {
-
- ntStatus = STATUS_INVALID_PARAMETER;
- goto VBoxUSB_DispatchCreate_Exit;
- }
-
- ntStatus = STATUS_INVALID_PARAMETER;
-
- for(i=0; i<interface->NumberOfPipes; i++) {
-
- if(pipeContext == &deviceExtension->PipeContext[i]) {
-
- //
- // found a match
- //
- dprintf(("open pipe %d\n", i));
-
- fileObject->FsContext = &interface->Pipes[i];
-
- ASSERT(fileObject->FsContext);
-
- pipeContext->PipeOpen = TRUE;
-
- ntStatus = STATUS_SUCCESS;
-
- //
- // increment OpenHandleCounts
- //
- InterlockedIncrement(&deviceExtension->OpenHandleCount);
-
- //
- // the device is idle if it has no open handles or pending PnP Irps
- // since we just received an open handle request, cancel idle req.
- //
- if(deviceExtension->SSEnable) {
-
- CancelSelectSuspend(deviceExtension);
- }
- }
- }
-#endif
-
-VBoxUSB_DispatchCreate_Exit:
-
- Irp->IoStatus.Status = ntStatus;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- dprintf(("VBoxUSB_DispatchCreate - ends\n"));
-
- return ntStatus;
-}
-
-NTSTATUS
-VBoxUSB_DispatchClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- Dispatch routine for close.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet
-
-Return Value:
-
- NT status value
-
---*/
-{
- NTSTATUS ntStatus;
- PFILE_OBJECT fileObject;
- PDEVICE_EXTENSION deviceExtension;
- PIO_STACK_LOCATION irpStack;
- PVBOXUSB_PIPE_CONTEXT pipeContext;
- PUSBD_PIPE_INFORMATION pipeInformation;
-
- PAGED_CODE();
-
- //
- // initialize variables
- //
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- fileObject = irpStack->FileObject;
- pipeContext = NULL;
- pipeInformation = NULL;
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- dprintf(("VBoxUSB_DispatchClose - begins\n"));
-
- if(fileObject && fileObject->FsContext) {
-
- pipeInformation = (PUSBD_PIPE_INFORMATION)fileObject->FsContext;
-
- if(0 != fileObject->FileName.Length) {
-
- pipeContext = VBoxUSB_PipeWithName(DeviceObject,
- &fileObject->FileName);
- }
-
- if(pipeContext && pipeContext->PipeOpen) {
-
- pipeContext->PipeOpen = FALSE;
- }
- }
-
- //
- // set ntStatus to STATUS_SUCCESS
- //
- ntStatus = STATUS_SUCCESS;
-
- Irp->IoStatus.Status = ntStatus;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- InterlockedDecrement(&deviceExtension->OpenHandleCount);
-
- dprintf(("VBoxUSB_DispatchClose - ends\n"));
-
-#if 0
- /* Force an unplug and re-plug to load the original Windows driver (or to give it to another running VM)
- * Only when the device was actually claimed and it's still operational (not removed already for instance).
- */
- if ( deviceExtension->OpenHandleCount == 0
- && deviceExtension->usbdev.fClaimed
- && deviceExtension->DeviceState == Working)
- {
- NTSTATUS rc = VBoxUSBSendIOCTL(deviceExtension, IOCTL_INTERNAL_USB_CYCLE_PORT, NULL);
- Assert(NT_SUCCESS(rc));
- }
- else
- dprintf(("Didn't cycle port OpenHandleCount=%d fClaimed=%d DeviceState=%d\n", deviceExtension->OpenHandleCount, deviceExtension->usbdev.fClaimed, deviceExtension->DeviceState));
-#endif
-
- return ntStatus;
-}
-
-NTSTATUS
-VBoxUSB_DispatchDevCtrl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- Dispatch routine for IRP_MJ_DEVICE_CONTROL
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet
-
-Return Value:
-
- NT status value
-
---*/
-{
- ULONG code;
- PVOID ioBuffer;
- ULONG inputBufferLength;
- ULONG outputBufferLength;
- ULONG info;
- NTSTATUS ntStatus = STATUS_SUCCESS;
- PDEVICE_EXTENSION deviceExtension;
- PIO_STACK_LOCATION irpStack;
-
- //
- // initialize variables
- //
- info = 0;
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- code = irpStack->Parameters.DeviceIoControl.IoControlCode;
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- ioBuffer = Irp->AssociatedIrp.SystemBuffer;
- inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
- outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if(deviceExtension->DeviceState != Working)
- {
- dprintf(("Invalid device state\n"));
-
- Irp->IoStatus.Status = ntStatus = STATUS_INVALID_DEVICE_STATE;
- Irp->IoStatus.Information = info;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return ntStatus;
- }
-
- dprintf(("VBoxUSB_DispatchDevCtrl::"));
- VBoxUSB_IoIncrement(deviceExtension);
-
- //
- // It is true that the client driver cancelled the selective suspend
- // request in the dispatch routine for create.
- // But there is no guarantee that it has indeed been completed.
- // so wait on the NoIdleReqPendEvent and proceed only if this event
- // is signalled.
- //
- dprintf(("Waiting on the IdleReqPendEvent\n"));
-
- //
- // make sure that the selective suspend request has been completed.
- //
-
- if(deviceExtension->SSEnable)
- {
- KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- }
-
- switch(code) {
-
- case SUPUSB_IOCTL_USB_CLAIM_DEVICE:
- {
- PUSBSUP_CLAIMDEV pIn = (PUSBSUP_CLAIMDEV)ioBuffer;
- PUSBSUP_CLAIMDEV pOut = (PUSBSUP_CLAIMDEV)ioBuffer;
-
- dprintf(("SUPUSB_IOCTL_USB_CLAIM_DEVICE\n"));
- if (!ioBuffer || inputBufferLength != sizeof(*pIn) || outputBufferLength != sizeof(*pOut))
- {
- AssertMsgFailed(("SUPUSB_IOCTL_USB_GRAB_DEVICE: Invalid input/output sizes. inputBufferLength=%d expected %d. outputBufferLength=%d expected %d.\n",
- inputBufferLength, sizeof(*pIn), outputBufferLength, sizeof(*pOut)));
- ntStatus = STATUS_INVALID_PARAMETER;
- break;
- }
- if (deviceExtension->usbdev.fClaimed == false)
- {
- VBoxUSBFreeCachedDescriptors(deviceExtension);
- ntStatus = VBoxUSBCacheDescriptors(deviceExtension);
- if (NT_SUCCESS(ntStatus))
- {
- InterlockedExchange(&deviceExtension->usbdev.fClaimed, true);
- pIn->fClaimed = true;
- }
- }
- else
- {
- pIn->fClaimed = false;
- }
- info = sizeof(*pOut);
- break;
- }
-
- case SUPUSB_IOCTL_USB_RELEASE_DEVICE:
- {
- VBoxUSBFreeCachedDescriptors(deviceExtension);
- /* Don't set fClaimed to false here, or else the device won't be returned to Windows afterwards */
- break;
- }
-
- case SUPUSB_IOCTL_GET_DEVICE:
- {
- PUSBSUP_GETDEV pIn = (PUSBSUP_GETDEV)ioBuffer;
- PUSBSUP_GETDEV pOut = (PUSBSUP_GETDEV)ioBuffer;
-
- dprintf(("SUPUSB_IOCTL_GET_DEVICE\n"));
- if (!ioBuffer || inputBufferLength != outputBufferLength || inputBufferLength != sizeof(*pIn))
- {
- AssertMsgFailed(("SUPUSB_IOCTL_GET_DEVICE: Invalid input/output sizes. inputBufferLength=%d expected %d. outputBufferLength=%d expected %d.\n",
- inputBufferLength, sizeof(*pIn), outputBufferLength, sizeof(*pOut)));
- ntStatus = STATUS_INVALID_PARAMETER;
- break;
- }
-
- ntStatus = VBoxUSBGetDeviceDescription(deviceExtension);
- if (!NT_SUCCESS(ntStatus))
- {
- AssertMsgFailed(("VBoxUSBGetDeviceDescription failed with %x\n", ntStatus));
- break;
- }
- ntStatus = VBoxUSBGetDeviceSpeed(deviceExtension);
- if (!NT_SUCCESS(ntStatus))
- {
- AssertMsgFailed(("VBoxUSBGetDeviceSpeed failed with %x\n", ntStatus));
- break;
- }
-
- pOut->fAttached = true;
- pOut->fHiSpeed = deviceExtension->usbdev.fIsHighSpeed;
- pOut->vid = deviceExtension->usbdev.idVendor;
- pOut->did = deviceExtension->usbdev.idProduct;
- pOut->rev = deviceExtension->usbdev.bcdDevice;
- strncpy(pOut->serial_hash, deviceExtension->usbdev.szSerial, sizeof(pOut->serial_hash));
-
- dprintf(("New device vid=%x pid=%x rev=%x\n", deviceExtension->usbdev.idVendor, deviceExtension->usbdev.idProduct, deviceExtension->usbdev.bcdDevice));
-
- info = sizeof(*pOut);
- break;
- }
-
- case SUPUSB_IOCTL_USB_RESET:
- {
- dprintf(("SUPUSB_IOCTL_USB_RESET\n"));
-
- if (ioBuffer || inputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSB_IOCTL_USB_RESET: Invalid input/output sizes. inputBufferLength=%d expected %d. outputBufferLength=%d expected %d.\n",
- inputBufferLength, 0, outputBufferLength, outputBufferLength));
- ntStatus = STATUS_INVALID_PARAMETER;
- break;
- }
- ntStatus = VBoxUSBSendIOCTL(deviceExtension, IOCTL_INTERNAL_USB_RESET_PORT, NULL);
- dprintf(("IOCTL_INTERNAL_USB_RESET_PORT returned %x\n", ntStatus));
- break;
- }
-
- case SUPUSB_IOCTL_USB_SET_CONFIG:
- {
- PUSBSUP_SET_CONFIG pIn = (PUSBSUP_SET_CONFIG)ioBuffer;
-
- dprintf(("SUPUSB_IOCTL_USB_SET_CONFIG\n"));
- if (!ioBuffer || inputBufferLength != sizeof(*pIn) || outputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSB_IOCTL_USB_SET_CONFIG: Invalid input/output sizes. inputBufferLength=%d expected %d. outputBufferLength=%d expected %d.\n",
- inputBufferLength, sizeof(*pIn), outputBufferLength, 0));
- ntStatus = STATUS_INVALID_PARAMETER;
- break;
- }
- ntStatus = VBoxUSBSetConfig(deviceExtension, pIn->bConfigurationValue);
- dprintf(("VBoxUSBSetConfig returned %x\n", ntStatus));
- break;
- }
-
- case SUPUSB_IOCTL_USB_SELECT_INTERFACE:
- {
- PUSBSUP_SELECT_INTERFACE pIn = (PUSBSUP_SELECT_INTERFACE)ioBuffer;
-
- dprintf(("SUPUSB_IOCTL_USB_SELECT_INTERFACE\n"));
- if (!ioBuffer || inputBufferLength != sizeof(*pIn) || outputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSB_IOCTL_USB_SELECT_INTERFACE: Invalid input/output sizes. inputBufferLength=%d expected %d. outputBufferLength=%d expected %d.\n",
- inputBufferLength, 0, outputBufferLength, 0));
- ntStatus = STATUS_INVALID_PARAMETER;
- break;
- }
- ntStatus = VBoxUSBSetInterface(deviceExtension, pIn->bInterfaceNumber, pIn->bAlternateSetting);
- dprintf(("VBoxUSBSetInterface returned %x\n", ntStatus));
- break;
- }
-
- case SUPUSB_IOCTL_USB_CLEAR_ENDPOINT:
- {
- PUSBSUP_CLEAR_ENDPOINT pIn = (PUSBSUP_CLEAR_ENDPOINT)ioBuffer;
-
- dprintf(("SUPUSB_IOCTL_USB_CLEAR_ENDPOINT\n"));
- if (!ioBuffer || inputBufferLength != sizeof(*pIn) || outputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSB_IOCTL_USB_CLEAR_ENDPOINT: Invalid input/output sizes. inputBufferLength=%d expected %d. outputBufferLength=%d expected %d.\n",
- inputBufferLength, 0, outputBufferLength, 0));
- ntStatus = STATUS_INVALID_PARAMETER;
- break;
- }
- ntStatus = VBoxUSBClearEndpoint(deviceExtension, pIn->bEndpoint, TRUE);
- dprintf(("VBoxUSBClearEndpoint returned %x\n", ntStatus));
- break;
- }
-
- case SUPUSB_IOCTL_USB_ABORT_ENDPOINT:
- {
- PUSBSUP_CLEAR_ENDPOINT pIn = (PUSBSUP_CLEAR_ENDPOINT)ioBuffer;
-
- dprintf(("SUPUSB_IOCTL_USB_ABORT_ENDPOINT\n"));
- if (!ioBuffer || inputBufferLength != sizeof(*pIn) || outputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSB_IOCTL_USB_ABORT_ENDPOINT: Invalid input/output sizes. inputBufferLength=%d expected %d. outputBufferLength=%d expected %d.\n",
- inputBufferLength, 0, outputBufferLength, 0));
- ntStatus = STATUS_INVALID_PARAMETER;
- break;
- }
- ntStatus = VBoxUSBClearEndpoint(deviceExtension, pIn->bEndpoint, FALSE);
- dprintf(("VBoxUSBClearEndpoint returned %x\n", ntStatus));
- break;
- }
-
- case SUPUSB_IOCTL_SEND_URB:
- {
- PUSBSUP_URB pIn = (PUSBSUP_URB)ioBuffer;
- PUSBSUP_URB pOut = (PUSBSUP_URB)ioBuffer;
-
- dprintf(("SUPUSB_IOCTL_SEND_URB\n"));
- if (!ioBuffer || inputBufferLength != outputBufferLength || inputBufferLength != sizeof(*pIn))
- {
- AssertMsgFailed(("SUPUSB_IOCTL_SEND_URB: Invalid input/output sizes. inputBufferLength=%d expected %d. outputBufferLength=%d expected %d.\n",
- inputBufferLength, sizeof(*pIn), outputBufferLength, sizeof(*pOut)));
- ntStatus = STATUS_INVALID_PARAMETER;
- break;
- }
-
- ntStatus = VBoxUSBSendURB(deviceExtension, Irp, pIn, pOut);
- break;
- }
-
- case SUPUSB_IOCTL_IS_OPERATIONAL:
- {
- // if we get this far, then we're still up and running
- break;
- }
-
- case SUPUSB_IOCTL_GET_VERSION:
- {
- PUSBSUP_VERSION pOut = (PUSBSUP_VERSION)ioBuffer;
-
- if (!ioBuffer || outputBufferLength != sizeof(*pOut) || inputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSB_IOCTL_GET_VERSION: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, 0, outputBufferLength, sizeof(*pOut)));
- ntStatus = STATUS_INVALID_PARAMETER;
- break;
- }
- pOut->u32Major = USBDRV_MAJOR_VERSION;
- pOut->u32Minor = USBDRV_MINOR_VERSION;
- info = sizeof(*pOut);
- break;
- }
-
- default :
- ntStatus = STATUS_INVALID_DEVICE_REQUEST;
- break;
- }
-
- if (ntStatus != STATUS_PENDING)
- {
- Irp->IoStatus.Status = ntStatus;
- Irp->IoStatus.Information = info;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- }
- else
- {
- // pIrp status already filled in by the lower layer (as we reuse the IRP for sending URBs)
- Assert(code == SUPUSB_IOCTL_SEND_URB);
- }
-
- dprintf(("VBoxUSB_DispatchDevCtrl::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- return ntStatus;
-}
-
-NTSTATUS
-VBoxUSB_ResetPipe(
- IN PDEVICE_OBJECT DeviceObject,
- IN USBD_PIPE_HANDLE PipeHandle
- )
-/*++
-
-Routine Description:
-
- This routine synchronously submits a URB_FUNCTION_RESET_PIPE
- request down the stack.
-
-Arguments:
-
- DeviceObject - pointer to device object
- PipeHandle - pipe handle
-
-Return Value:
-
- NT status value
-
---*/
-{
- PURB urb;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
-
- //
- // initialize variables
- //
-
- urb = NULL;
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- urb = (PURB)ExAllocatePool(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
- if(urb) {
-
- urb->UrbHeader.Length = (USHORT) sizeof(struct _URB_PIPE_REQUEST);
- urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
- urb->UrbPipeRequest.PipeHandle = PipeHandle;
-
- ntStatus = CallUSBD(DeviceObject, urb);
-
- ExFreePool(urb);
- }
- else {
-
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- if(NT_SUCCESS(ntStatus)) {
-
- dprintf(("VBoxUSB_ResetPipe - success\n"));
- ntStatus = STATUS_SUCCESS;
- }
- else {
-
- dprintf(("VBoxUSB_ResetPipe - failed\n"));
- }
-
- return ntStatus;
-}
-
-NTSTATUS
-VBoxUSB_ResetDevice(
- IN PDEVICE_OBJECT DeviceObject
- )
-/*++
-
-Routine Description:
-
- This routine invokes VBoxUSB_ResetParentPort to reset the device
-
-Arguments:
-
- DeviceObject - pointer to device object
-
-Return Value:
-
- NT status value
-
---*/
-{
- NTSTATUS ntStatus;
- ULONG portStatus;
-
- dprintf(("VBoxUSB_ResetDevice - begins\n"));
-
- ntStatus = VBoxUSB_GetPortStatus(DeviceObject, &portStatus);
-
- if((NT_SUCCESS(ntStatus)) &&
- (!(portStatus & USBD_PORT_ENABLED)) &&
- (portStatus & USBD_PORT_CONNECTED)) {
-
- ntStatus = VBoxUSB_ResetParentPort(DeviceObject);
- }
-
- dprintf(("VBoxUSB_ResetDevice - ends\n"));
-
- return ntStatus;
-}
-
-NTSTATUS
-VBoxUSB_GetPortStatus(
- IN PDEVICE_OBJECT DeviceObject,
- IN OUT PULONG PortStatus
- )
-/*++
-
-Routine Description:
-
- This routine retrieves the status value
-
-Arguments:
-
- DeviceObject - pointer to device object
- PortStatus - port status
-
-Return Value:
-
- NT status value
-
---*/
-{
- NTSTATUS ntStatus;
- KEVENT event;
- PIRP irp;
- IO_STATUS_BLOCK ioStatus;
- PIO_STACK_LOCATION nextStack;
- PDEVICE_EXTENSION deviceExtension;
-
- //
- // initialize variables
- //
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- *PortStatus = 0;
-
- dprintf(("VBoxUSB_GetPortStatus - begins\n"));
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
-
- irp = IoBuildDeviceIoControlRequest(
- IOCTL_INTERNAL_USB_GET_PORT_STATUS,
- deviceExtension->TopOfStackDeviceObject,
- NULL,
- 0,
- NULL,
- 0,
- TRUE,
- &event,
- &ioStatus);
-
- if(NULL == irp) {
-
- dprintf(("memory alloc for irp failed\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- nextStack = IoGetNextIrpStackLocation(irp);
-
- ASSERT(nextStack != NULL);
-
- nextStack->Parameters.Others.Argument1 = PortStatus;
-
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
-
- if(STATUS_PENDING == ntStatus) {
-
- KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
- }
- else {
-
- ioStatus.Status = ntStatus;
- }
-
- ntStatus = ioStatus.Status;
-
- dprintf(("VBoxUSB_GetPortStatus - ends\n"));
-
- return ntStatus;
-}
-
-NTSTATUS
-VBoxUSB_ResetParentPort(
- IN PDEVICE_OBJECT DeviceObject
- )
-/*++
-
-Routine Description:
-
- This routine sends an IOCTL_INTERNAL_USB_RESET_PORT
- synchronously down the stack.
-
-Arguments:
-
-Return Value:
-
---*/
-{
- NTSTATUS ntStatus;
- KEVENT event;
- PIRP irp;
- IO_STATUS_BLOCK ioStatus;
- PIO_STACK_LOCATION nextStack;
- PDEVICE_EXTENSION deviceExtension;
-
- //
- // initialize variables
- //
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- dprintf(("VBoxUSB_ResetParentPort - begins\n"));
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
-
- irp = IoBuildDeviceIoControlRequest(
- IOCTL_INTERNAL_USB_RESET_PORT,
- deviceExtension->TopOfStackDeviceObject,
- NULL,
- 0,
- NULL,
- 0,
- TRUE,
- &event,
- &ioStatus);
-
- if(NULL == irp) {
-
- dprintf(("memory alloc for irp failed\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- nextStack = IoGetNextIrpStackLocation(irp);
-
- ASSERT(nextStack != NULL);
-
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
-
- if(STATUS_PENDING == ntStatus) {
-
- KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
- }
- else {
-
- ioStatus.Status = ntStatus;
- }
-
- ntStatus = ioStatus.Status;
-
- dprintf(("VBoxUSB_ResetParentPort - ends\n"));
-
- return ntStatus;
-}
-
-
-NTSTATUS
-SubmitIdleRequestIrp(
- IN PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- This routine builds an idle request irp with an associated callback routine
- and a completion routine in the driver and passes the irp down the stack.
-
-Arguments:
-
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- NT status value
-
---*/
-{
- PIRP irp;
- NTSTATUS ntStatus;
- KIRQL oldIrql;
- PUSB_IDLE_CALLBACK_INFO idleCallbackInfo;
- PIO_STACK_LOCATION nextStack;
-
- //
- // initialize variables
- //
-
- irp = NULL;
- idleCallbackInfo = NULL;
-
- dprintf(("SubmitIdleRequest - begins\n"));
-
- ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
-
- if(PowerDeviceD0 != DeviceExtension->DevPower) {
-
- ntStatus = STATUS_POWER_STATE_INVALID;
-
- goto SubmitIdleRequestIrp_Exit;
- }
-
- KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
-
- if(InterlockedExchange(&DeviceExtension->IdleReqPend, 1)) {
-
- dprintf(("Idle request pending..\n"));
-
- KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
-
- ntStatus = STATUS_DEVICE_BUSY;
-
- goto SubmitIdleRequestIrp_Exit;
- }
-
- //
- // clear the NoIdleReqPendEvent because we are about
- // to submit an idle request. Since we are so early
- // to clear this event, make sure that if we fail this
- // request we set back the event.
- //
- KeClearEvent(&DeviceExtension->NoIdleReqPendEvent);
-
- idleCallbackInfo = (PUSB_IDLE_CALLBACK_INFO)ExAllocatePool(NonPagedPool, sizeof(struct _USB_IDLE_CALLBACK_INFO));
-
- if(idleCallbackInfo) {
-
- idleCallbackInfo->IdleCallback = (USB_IDLE_CALLBACK)IdleNotificationCallback;
-
- idleCallbackInfo->IdleContext = (PVOID)DeviceExtension;
-
- ASSERT(DeviceExtension->IdleCallbackInfo == NULL);
-
- DeviceExtension->IdleCallbackInfo = idleCallbackInfo;
-
- //
- // we use IoAllocateIrp to create an irp to selectively suspend the
- // device. This irp lies pending with the hub driver. When appropriate
- // the hub driver will invoked callback, where we power down. The completion
- // routine is invoked when we power back.
- //
- irp = IoAllocateIrp(DeviceExtension->TopOfStackDeviceObject->StackSize,
- FALSE);
-
- if(irp == NULL) {
-
- dprintf(("cannot build idle request irp\n"));
-
- KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
- IO_NO_INCREMENT,
- FALSE);
-
- InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
-
- KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
-
- ExFreePool(idleCallbackInfo);
-
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
-
- goto SubmitIdleRequestIrp_Exit;
- }
-
- nextStack = IoGetNextIrpStackLocation(irp);
-
- nextStack->MajorFunction =
- IRP_MJ_INTERNAL_DEVICE_CONTROL;
-
- nextStack->Parameters.DeviceIoControl.IoControlCode =
- IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION;
-
- nextStack->Parameters.DeviceIoControl.Type3InputBuffer =
- idleCallbackInfo;
-
- nextStack->Parameters.DeviceIoControl.InputBufferLength =
- sizeof(struct _USB_IDLE_CALLBACK_INFO);
-
-
- IoSetCompletionRoutine(irp,
- (PIO_COMPLETION_ROUTINE)IdleNotificationRequestComplete,
- DeviceExtension,
- TRUE,
- TRUE,
- TRUE);
-
- DeviceExtension->PendingIdleIrp = irp;
-
- //
- // we initialize the count to 2.
- // The reason is, if the CancelSelectSuspend routine manages
- // to grab the irp from the device extension, then the last of the
- // CancelSelectSuspend routine/IdleNotificationRequestComplete routine
- // to execute will free this irp. We need to have this schema so that
- // 1. completion routine does not attempt to touch the irp freed by
- // CancelSelectSuspend routine.
- // 2. CancelSelectSuspend routine doesn't wait for ever for the completion
- // routine to complete!
- //
- DeviceExtension->FreeIdleIrpCount = 2;
-
- KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
-
- //
- // check if the device is idle.
- // A check here ensures that a race condition did not
- // completely reverse the call sequence of SubmitIdleRequestIrp
- // and CancelSelectiveSuspend
- //
-
- if(!CanDeviceSuspend(DeviceExtension) ||
- PowerDeviceD0 != DeviceExtension->DevPower) {
-
- //
- // IRPs created using IoBuildDeviceIoControlRequest should be
- // completed by calling IoCompleteRequest and not merely
- // deallocated.
- //
-
- dprintf(("Device is not idle\n"));
-
- KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
-
- DeviceExtension->IdleCallbackInfo = NULL;
-
- DeviceExtension->PendingIdleIrp = NULL;
-
- KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
- IO_NO_INCREMENT,
- FALSE);
-
- InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
-
- KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
-
- if(idleCallbackInfo) {
-
- ExFreePool(idleCallbackInfo);
- }
-
- //
- // it is still safe to touch the local variable "irp" here.
- // the irp has not been passed down the stack, the irp has
- // no cancellation routine. The worse position is that the
- // CancelSelectSuspend has run after we released the spin
- // lock above. It is still essential to free the irp.
- //
- if(irp) {
-
- IoFreeIrp(irp);
- }
-
- ntStatus = STATUS_UNSUCCESSFUL;
-
- goto SubmitIdleRequestIrp_Exit;
- }
-
- dprintf(("Cancel the timers\n"));
- //
- // Cancel the timer so that the DPCs are no longer fired.
- // Thus, we are making judicious usage of our resources.
- // we do not need DPCs because we already have an idle irp pending.
- // The timers are re-initialized in the completion routine.
- //
- KeCancelTimer(&DeviceExtension->Timer);
-
- ntStatus = IoCallDriver(DeviceExtension->TopOfStackDeviceObject, irp);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("IoCallDriver failed\n"));
-
- goto SubmitIdleRequestIrp_Exit;
- }
- }
- else {
-
- dprintf(("Memory allocation for idleCallbackInfo failed\n"));
-
- KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
- IO_NO_INCREMENT,
- FALSE);
-
- InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
-
- KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
-
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
-
-SubmitIdleRequestIrp_Exit:
-
- dprintf(("SubmitIdleRequest - ends\n"));
-
- return ntStatus;
-}
-
-
-VOID
-IdleNotificationCallback(
- IN PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- "A pointer to a callback function in your driver is passed down the stack with
- this IOCTL, and it is this callback function that is called by USBHUB when it
- safe for your device to power down."
-
- "When the callback in your driver is called, all you really need to do is to
- to first ensure that a WaitWake Irp has been submitted for your device, if
- remote wake is possible for your device and then request a SetD2 (or DeviceWake)"
-
-Arguments:
-
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- NT status value
-
---*/
-{
- NTSTATUS ntStatus;
- POWER_STATE powerState;
- KEVENT irpCompletionEvent;
- PIRP_COMPLETION_CONTEXT irpContext;
-
- dprintf(("IdleNotificationCallback - begins\n"));
-
- //
- // Dont idle, if the device was just disconnected or being stopped
- // i.e. return for the following DeviceState(s)
- // NotStarted, Stopped, PendingStop, PendingRemove, SurpriseRemoved, Removed
- //
-
- if(DeviceExtension->DeviceState != Working) {
-
- return;
- }
-
- //
- // If there is not already a WW IRP pending, submit one now
- //
- if(DeviceExtension->WaitWakeEnable) {
-
- IssueWaitWake(DeviceExtension);
- }
-
-
- //
- // power down the device
- //
-
- irpContext = (PIRP_COMPLETION_CONTEXT)
- ExAllocatePool(NonPagedPool,
- sizeof(IRP_COMPLETION_CONTEXT));
-
- if(!irpContext) {
-
- dprintf(("Failed to alloc memory for irpContext\n"));
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
- else {
-
- //
- // increment the count. In the HoldIoRequestWorkerRoutine, the
- // count is decremented twice (one for the system Irp and the
- // other for the device Irp. An increment here compensates for
- // the system irp..The decrement corresponding to this increment
- // is in the completion function
- //
-
- dprintf(("IdleNotificationCallback::"));
- VBoxUSB_IoIncrement(DeviceExtension);
-
- powerState.DeviceState = (DEVICE_POWER_STATE)DeviceExtension->PowerDownLevel;
-
- KeInitializeEvent(&irpCompletionEvent, NotificationEvent, FALSE);
-
- irpContext->DeviceExtension = DeviceExtension;
- irpContext->Event = &irpCompletionEvent;
-
- ntStatus = PoRequestPowerIrp(
- DeviceExtension->PhysicalDeviceObject,
- IRP_MN_SET_POWER,
- powerState,
- (PREQUEST_POWER_COMPLETE) PoIrpCompletionFunc,
- irpContext,
- NULL);
-
- if(STATUS_PENDING == ntStatus) {
-
- dprintf(("IdleNotificationCallback::"
- "waiting for the power irp to complete\n"));
-
- KeWaitForSingleObject(&irpCompletionEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- }
- }
-
- if(!NT_SUCCESS(ntStatus)) {
-
- if(irpContext) {
-
- ExFreePool(irpContext);
- }
- }
-
- dprintf(("IdleNotificationCallback - ends\n"));
-}
-
-
-NTSTATUS
-IdleNotificationRequestComplete(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- Completion routine for idle notification irp
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- NT status value
-
---*/
-{
- NTSTATUS ntStatus;
- POWER_STATE powerState;
- KIRQL oldIrql;
- LARGE_INTEGER dueTime;
- PIRP idleIrp;
- PUSB_IDLE_CALLBACK_INFO idleCallbackInfo;
-
- dprintf(("IdleNotificationRequestCompete - begins\n"));
-
- idleIrp = NULL;
-
- //
- // check the Irp status
- //
-
- ntStatus = Irp->IoStatus.Status;
-
- if(!NT_SUCCESS(ntStatus) && ntStatus != STATUS_NOT_SUPPORTED) {
-
- dprintf(("Idle irp completes with error::"));
-
- switch(ntStatus) {
-
- case STATUS_INVALID_DEVICE_REQUEST:
-
- dprintf(("STATUS_INVALID_DEVICE_REQUEST\n"));
-
- break;
-
- case STATUS_CANCELLED:
-
- dprintf(("STATUS_CANCELLED\n"));
-
- break;
-
- case STATUS_POWER_STATE_INVALID:
-
- dprintf(("STATUS_POWER_STATE_INVALID\n"));
-
- goto IdleNotificationRequestComplete_Exit;
-
- case STATUS_DEVICE_BUSY:
-
- dprintf(("STATUS_DEVICE_BUSY\n"));
-
- break;
-
- default:
-
- dprintf(("default: status = %X\n", ntStatus));
-
- break;
- }
-
- //
- // if in error, issue a SetD0 (only when not in D0)
- //
-
- if(PowerDeviceD0 != DeviceExtension->DevPower) {
- dprintf(("IdleNotificationRequestComplete::"));
- VBoxUSB_IoIncrement(DeviceExtension);
-
- powerState.DeviceState = PowerDeviceD0;
-
- ntStatus = PoRequestPowerIrp(
- DeviceExtension->PhysicalDeviceObject,
- IRP_MN_SET_POWER,
- powerState,
- (PREQUEST_POWER_COMPLETE) PoIrpAsyncCompletionFunc,
- DeviceExtension,
- NULL);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("PoRequestPowerIrp failed\n"));
- }
- }
- }
-
-IdleNotificationRequestComplete_Exit:
-
- KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
-
- idleCallbackInfo = DeviceExtension->IdleCallbackInfo;
-
- DeviceExtension->IdleCallbackInfo = NULL;
-
- idleIrp = (PIRP) InterlockedExchangePointer(
- (PVOID *)&DeviceExtension->PendingIdleIrp,
- NULL);
-
- InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
-
- KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
-
- if(idleCallbackInfo) {
-
- ExFreePool(idleCallbackInfo);
- }
-
- //
- // since the irp was created using IoAllocateIrp,
- // the Irp needs to be freed using IoFreeIrp.
- // Also return STATUS_MORE_PROCESSING_REQUIRED so that
- // the kernel does not reference this in the near future.
- //
-
- if(idleIrp) {
-
- dprintf(("completion routine has a valid irp and frees it\n"));
- IoFreeIrp(Irp);
- KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
- IO_NO_INCREMENT,
- FALSE);
- }
- else {
-
- //
- // The CancelSelectiveSuspend routine has grabbed the Irp from the device
- // extension. Now the last one to decrement the FreeIdleIrpCount should
- // free the irp.
- //
- if(0 == InterlockedDecrement(&DeviceExtension->FreeIdleIrpCount)) {
-
- dprintf(("completion routine frees the irp\n"));
- IoFreeIrp(Irp);
-
- KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
- IO_NO_INCREMENT,
- FALSE);
- }
- }
-
- if(DeviceExtension->SSEnable) {
-
- dprintf(("Set the timer to fire DPCs\n"));
-
- dueTime.QuadPart = -10000 * IDLE_INTERVAL; // 5000 ms
-
- KeSetTimerEx(&DeviceExtension->Timer,
- dueTime,
- IDLE_INTERVAL, // 5000 ms
- &DeviceExtension->DeferredProcCall);
-
- dprintf(("IdleNotificationRequestCompete - ends\n"));
- }
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-VOID
-CancelSelectSuspend(
- IN PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- This routine is invoked to cancel selective suspend request.
-
-Arguments:
-
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- None.
-
---*/
-{
- PIRP irp;
- KIRQL oldIrql;
-
- irp = NULL;
-
- dprintf(("CancelSelectSuspend - begins\n"));
-
- KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
-
- if(!CanDeviceSuspend(DeviceExtension))
- {
- dprintf(("Device is not idle\n"));
-
- irp = (PIRP) InterlockedExchangePointer(
- (PVOID *)&DeviceExtension->PendingIdleIrp,
- NULL);
- }
-
- KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
-
- //
- // since we have a valid Irp ptr,
- // we can call IoCancelIrp on it,
- // without the fear of the irp
- // being freed underneath us.
- //
- if(irp) {
-
- //
- // This routine has the irp pointer.
- // It is safe to call IoCancelIrp because we know that
- // the completion routine will not free this irp unless...
- //
- //
- if(IoCancelIrp(irp)) {
-
- dprintf(("IoCancelIrp returns TRUE\n"));
- }
- else {
- dprintf(("IoCancelIrp returns FALSE\n"));
- }
-
- //
- // ....we decrement the FreeIdleIrpCount from 2 to 1.
- // if completion routine runs ahead of us, then this routine
- // decrements the FreeIdleIrpCount from 1 to 0 and hence shall
- // free the irp.
- //
- if(0 == InterlockedDecrement(&DeviceExtension->FreeIdleIrpCount)) {
-
- dprintf(("CancelSelectSuspend frees the irp\n"));
- IoFreeIrp(irp);
-
- KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
- IO_NO_INCREMENT,
- FALSE);
- }
- }
-
- dprintf(("CancelSelectSuspend - ends\n"));
-
- return;
-}
-
-VOID
-PoIrpCompletionFunc(
- IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR MinorFunction,
- IN POWER_STATE PowerState,
- IN PVOID Context,
- IN PIO_STATUS_BLOCK IoStatus
- )
-/*++
-
-Routine Description:
-
- Completion routine for power irp PoRequested in
- IdleNotificationCallback.
-
-Arguments:
-
- DeviceObject - pointer to device object
- MinorFunciton - minor function for the irp.
- PowerState - irp power state
- Context - context passed to the completion function
- IoStatus - status block.
-
-Return Value:
-
- None
-
---*/
-{
- PIRP_COMPLETION_CONTEXT irpContext;
-
- //
- // initialize variables
- //
- irpContext = NULL;
-
- if(Context) {
-
- irpContext = (PIRP_COMPLETION_CONTEXT) Context;
- }
-
- //
- // all we do is set the event and decrement the count
- //
-
- if(irpContext) {
-
- KeSetEvent(irpContext->Event, 0, FALSE);
-
- dprintf(("PoIrpCompletionFunc::"));
- VBoxUSB_IoDecrement(irpContext->DeviceExtension);
-
- ExFreePool(irpContext);
- }
-
- return;
-}
-
-VOID
-PoIrpAsyncCompletionFunc(
- IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR MinorFunction,
- IN POWER_STATE PowerState,
- IN PVOID Context,
- IN PIO_STATUS_BLOCK IoStatus
- )
-/*++
-
-Routine Description:
-
- Completion routine for power irp PoRequested in IdleNotification
- RequestComplete routine.
-
-Arguments:
-
- DeviceObject - pointer to device object
- MinorFunciton - minor function for the irp.
- PowerState - irp power state
- Context - context passed to the completion function
- IoStatus - status block.
-
-Return Value:
-
- None
-
---*/
-{
- PDEVICE_EXTENSION DeviceExtension;
-
- //
- // initialize variables
- //
- DeviceExtension = (PDEVICE_EXTENSION) Context;
-
- //
- // all we do is decrement the count
- //
-
- dprintf(("PoIrpAsyncCompletionFunc::"));
- VBoxUSB_IoDecrement(DeviceExtension);
-
- return;
-}
-
-VOID
-WWIrpCompletionFunc(
- IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR MinorFunction,
- IN POWER_STATE PowerState,
- IN PVOID Context,
- IN PIO_STATUS_BLOCK IoStatus
- )
-/*++
-
-Routine Description:
-
- Completion routine for PoRequest wait wake irp
-
-Arguments:
-
- DeviceObject - pointer to device object
- MinorFunciton - minor function for the irp.
- PowerState - irp power state
- Context - context passed to the completion function
- IoStatus - status block.
-
-Return Value:
-
- None
-
---*/
-{
- PDEVICE_EXTENSION DeviceExtension;
-
- //
- // initialize variables
- //
- DeviceExtension = (PDEVICE_EXTENSION) Context;
-
- //
- // all we do is decrement the count
- //
-
- dprintf(("WWIrpCompletionFunc::"));
- VBoxUSB_IoDecrement(DeviceExtension);
-
- return;
-}
-
-
-
-/**
- * Free per-device interface info
- *
- * @param pDevice USB device pointer
- * @param fAbortPipes If true, also abort any open pipes
- */
-void VBoxUSBFreeInterfaces(PDEVICE_EXTENSION pDevice, bool fAbortPipes)
-{
- unsigned i;
- unsigned j;
-
- /*
- * Free old interface info
- */
- if (pDevice->usbdev.pVBIfaceInfo)
- {
- for (i=0;i<pDevice->usbdev.uNumInterfaces;i++)
- {
- if (pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo)
- {
- if (fAbortPipes)
- {
- for(j=0; j<pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo->NumberOfPipes; j++)
- {
- dprintf(("Aborting Pipe %d handle %x address %x\n", j,
- pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].PipeHandle,
- pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].EndpointAddress));
- VBoxUSBClearPipe(pDevice, pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].PipeHandle, FALSE);
- }
- }
- ExFreePool(pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo);
- }
- pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo = NULL;
- if (pDevice->usbdev.pVBIfaceInfo[i].pPipeInfo)
- ExFreePool(pDevice->usbdev.pVBIfaceInfo[i].pPipeInfo);
- pDevice->usbdev.pVBIfaceInfo[i].pPipeInfo = NULL;
- }
- ExFreePool(pDevice->usbdev.pVBIfaceInfo);
- pDevice->usbdev.pVBIfaceInfo = NULL;
- }
-}
-
-/**
- * Return handle of pipe that corresponds to given endpoint address
- *
- * @returns Pipe handle (or 0 when not found)
- * @param pDevice USB device pointer
- * @param EndPointAddress end point address
- */
-HANDLE VBoxUSBGetPipeHandle(PDEVICE_EXTENSION pDevice, uint32_t EndPointAddress)
-{
- unsigned i, j;
-
- for (i=0;i<pDevice->usbdev.uNumInterfaces;i++)
- {
- for (j=0;j<pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo->NumberOfPipes;j++)
- {
- /* Note that bit 7 determines pipe direction, but is still significant
- * because endpoints may be numbered like 0x01, 0x81, 0x02, 0x82 etc.
- */
- if (pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].EndpointAddress == EndPointAddress)
- return pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].PipeHandle;
- }
- }
- return 0;
-}
-
-/**
- * Return pipe state information for given endpoint address
- *
- * @returns Pointer to pipe state (or NULL if not found)
- * @param pDevice USB device pointer
- * @param EndPointAddress end point address
- */
-VBOXUSB_PIPE_INFO *VBoxUSBGetPipeState(PDEVICE_EXTENSION pDevice, uint32_t EndPointAddress)
-{
- unsigned i, j;
-
- for (i=0;i<pDevice->usbdev.uNumInterfaces;i++)
- {
- for (j=0;j<pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo->NumberOfPipes;j++)
- {
- if (pDevice->usbdev.pVBIfaceInfo[i].pPipeInfo[j].EndpointAddress == EndPointAddress)
- return &pDevice->usbdev.pVBIfaceInfo[i].pPipeInfo[j];
- }
- }
- return NULL;
-}
-
-static VOID VBoxUSBStringDescriptorToUnicodeString(PUSB_STRING_DESCRIPTOR pDr, PUNICODE_STRING pUnicode)
-{
- /* for some reason the string dr sometimes contains a non-null terminated string
- * although we zeroed up the complete descriptor buffer
- * this is why RtlInitUnicodeString won't work
- * we need to init the scting length based on dr length */
- pUnicode->Buffer = pDr->bString;
- pUnicode->Length = pUnicode->MaximumLength = pDr->bLength - RT_OFFSETOF(USB_STRING_DESCRIPTOR, bString);
-}
-
-/**
- * Get a valid USB string descriptor language ID (the first ID found).
- *
- * @returns NT Status
- * @param pDevice device extension
- * @param lang_id pointer to language id
- */
-NTSTATUS VBoxUSBGetLangID(PDEVICE_EXTENSION pDevice, int *lang_id)
-{
- NTSTATUS status;
- unsigned length;
- char buffer[MAXIMUM_USB_STRING_LENGTH];
- PUSB_STRING_DESCRIPTOR pstrdescr = (PUSB_STRING_DESCRIPTOR)&buffer;
-
- Assert(lang_id);
- *lang_id = 0;
-
- length = sizeof(buffer);
- memset(pstrdescr, 0, length);
- pstrdescr->bLength = length;
- pstrdescr->bDescriptorType = USB_STRING_DESCRIPTOR_TYPE;
-
- status = VBoxUSBGetDescriptor(pDevice, pstrdescr, length, USB_STRING_DESCRIPTOR_TYPE, 0, 0);
- if (!NT_SUCCESS(status))
- {
- dprintf(("VBoxUSBGetLangID: language ID table not present (?)\n"));
- goto fail;
- }
- /* Just grab the first lang ID if available. In 99% cases, it will be US English (0x0409).*/
- if (pstrdescr->bLength >= sizeof(USB_STRING_DESCRIPTOR))
- {
- Assert(sizeof(pstrdescr->bString[0]) == sizeof(uint16_t));
- *lang_id = pstrdescr->bString[0];
- status = STATUS_SUCCESS;
- }
- else
- status = STATUS_INVALID_PARAMETER;
-fail:
- return status;
-}
-
-/**
- * Query device descriptor
- *
- * @returns NT Status
- * @param pDevice USB device pointer
- */
-NTSTATUS VBoxUSBGetDeviceDescription(PDEVICE_EXTENSION pDevice)
-{
- NTSTATUS status;
- PUSB_DEVICE_DESCRIPTOR devdescr = 0;
- PUSB_STRING_DESCRIPTOR pstrdescr = 0;
- uint32_t uLength;
-
- devdescr = (PUSB_DEVICE_DESCRIPTOR)ExAllocatePool(NonPagedPool,sizeof(USB_DEVICE_DESCRIPTOR));
- if(devdescr == NULL)
- {
- dprintf(("Failed to alloc mem for urb\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto fail;
- }
- memset(devdescr, 0, sizeof(*devdescr));
-
- status = VBoxUSBGetDescriptor(pDevice, devdescr, sizeof(*devdescr), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0);
- if (!NT_SUCCESS(status))
- {
- AssertMsgFailed(("VBoxUSBGetDeviceDescription: getting device descriptor failed\n"));
- goto fail;
- }
- dprintf(("Device pid=%x vid=%x rev=%x\n", devdescr->idVendor, devdescr->idProduct, devdescr->bcdDevice));
- pDevice->usbdev.idVendor = devdescr->idVendor;
- pDevice->usbdev.idProduct = devdescr->idProduct;
- pDevice->usbdev.bcdDevice = devdescr->bcdDevice;
- pDevice->usbdev.szSerial[0] = 0;
-
- UNICODE_STRING ustr;
- ANSI_STRING astr;
- int langId = 0;
-
- if (devdescr->iSerialNumber
-#ifdef DEBUG
- || devdescr->iProduct || devdescr->iManufacturer
-#endif
- )
- {
- status = VBoxUSBGetLangID(pDevice, &langId);
- if (!NT_SUCCESS(status))
- {
- dprintf(("VBoxUSBGetDeviceDescription: no language ID (?)\n"));
- status = STATUS_SUCCESS; //not fatal
- goto fail;
- }
-
- uLength = sizeof(USB_STRING_DESCRIPTOR) + MAX_USB_SERIAL_STRING * sizeof(pstrdescr->bString[0]);
-
- pstrdescr = (PUSB_STRING_DESCRIPTOR)ExAllocatePool(NonPagedPool, uLength);
- if (!pstrdescr)
- {
- AssertMsgFailed(("VBoxUSBGetDeviceDescription: ExAllocatePool failed\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto fail;
- }
- memset(pstrdescr, 0, uLength);
-
- pstrdescr->bLength = uLength;
- pstrdescr->bDescriptorType = USB_STRING_DESCRIPTOR_TYPE;
-
- status = VBoxUSBGetDescriptor(pDevice, pstrdescr, uLength, USB_STRING_DESCRIPTOR_TYPE, devdescr->iSerialNumber, langId);
- if (!NT_SUCCESS(status))
- {
- dprintf(("VBoxUSBGetDeviceDescription: no serial string present (?)\n"));
- status = STATUS_SUCCESS; //not fatal
- goto fail;
- }
- /* Did we get a string back or not? */
- if (pstrdescr->bLength > sizeof(USB_STRING_DESCRIPTOR))
- {
- VBoxUSBStringDescriptorToUnicodeString(pstrdescr, &ustr);
- astr.Buffer = pDevice->usbdev.szSerial;
- astr.Length = 0;
- astr.MaximumLength = (USHORT)sizeof(pDevice->usbdev.szSerial) - 1;
- memset(pDevice->usbdev.szSerial, 0, sizeof(pDevice->usbdev.szSerial));
- status = RtlUnicodeStringToAnsiString(&astr, &ustr, FALSE);
- if (!NT_SUCCESS(status))
- {
- AssertMsgFailed((__FUNCTION__": RtlUnicodeStringToAnsiString Failed status (0x%x)\n", status));
- goto fail;
- }
- }
- }
-
-#ifdef DEBUG
- if (pDevice->usbdev.szSerial[0])
- dprintf(("Serial number %s\n", pDevice->usbdev.szSerial));
-
- if (devdescr->iManufacturer)
- {
- memset(pstrdescr, 0, uLength);
- pstrdescr->bLength = uLength;
- pstrdescr->bDescriptorType = USB_STRING_DESCRIPTOR_TYPE;
-
- status = VBoxUSBGetDescriptor(pDevice, pstrdescr, uLength, USB_STRING_DESCRIPTOR_TYPE, devdescr->iManufacturer, langId);
- if (!NT_SUCCESS(status))
- {
- dprintf(("VBoxUSBGetDeviceDescription: no manufacturer string present (?)\n"));
- status = STATUS_SUCCESS; //not fatal
- goto fail;
- }
- if (pstrdescr->bLength > sizeof(USB_STRING_DESCRIPTOR))
- {
- RtlInitUnicodeString(&ustr, pstrdescr->bString);
- RtlInitAnsiString(&astr, NULL);
-
- RtlUnicodeStringToAnsiString(&astr, &ustr, TRUE);
- if (astr.Buffer[0])
- dprintf(("Manufacturer: %s\n", astr.Buffer));
- RtlFreeAnsiString(&astr);
- }
- }
- if (devdescr->iProduct)
- {
- memset(pstrdescr, 0, uLength);
- pstrdescr->bLength = uLength;
- pstrdescr->bDescriptorType = USB_STRING_DESCRIPTOR_TYPE;
-
- status = VBoxUSBGetDescriptor(pDevice, pstrdescr, uLength, USB_STRING_DESCRIPTOR_TYPE, devdescr->iProduct, langId);
- if (!NT_SUCCESS(status))
- {
- dprintf(("VBoxUSBGetDeviceDescription: no product string present (?)\n"));
- status = STATUS_SUCCESS; //not fatal
- goto fail;
- }
- if (pstrdescr->bLength > sizeof(USB_STRING_DESCRIPTOR))
- {
- RtlInitUnicodeString(&ustr, pstrdescr->bString);
- RtlInitAnsiString(&astr, NULL);
-
- RtlUnicodeStringToAnsiString(&astr, &ustr, TRUE);
- if (astr.Buffer[0])
- dprintf(("Product: %s\n", astr.Buffer));
- RtlFreeAnsiString(&astr);
- }
- }
-#endif
-
- status = STATUS_SUCCESS;
-
-fail:
- if (pstrdescr)
- ExFreePool(pstrdescr);
- if (devdescr)
- ExFreePool(devdescr);
- return status;
-}
-
-static NTSTATUS VBoxUSBClearPipe(PDEVICE_EXTENSION pDevice, HANDLE PipeHandle, bool fReset)
-{
- NTSTATUS status = STATUS_SUCCESS;
- URB *urb = NULL;
-
- urb = (URB *)ExAllocatePool(NonPagedPool, sizeof(URB));
- if (!urb)
- {
- AssertMsgFailed(("VBoxUSBClearPipe: ExAllocatePool failed!\n"));
- status = STATUS_NO_MEMORY;
- goto end;
- }
-
- if (fReset)
- urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
- else
- urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
- urb->UrbHeader.Length = sizeof(struct _URB_PIPE_REQUEST);
- urb->UrbPipeRequest.PipeHandle = PipeHandle;
- if (urb->UrbPipeRequest.PipeHandle == 0)
- {
- // pretend success
- dprintf(("Resetting the control pipe??\n"));
- status = STATUS_SUCCESS;
- goto end;
- }
-
- urb->UrbPipeRequest.Reserved = 0;
-
- status = VBoxUSBSendIOCTL(pDevice, IOCTL_INTERNAL_USB_SUBMIT_URB, urb);
- if (!NT_SUCCESS(status) || !USBD_SUCCESS(urb->UrbHeader.Status))
- {
- AssertMsgFailed(("VBoxUSBClearPipe: VBoxUSBSendIOCTL failed with %x (%x)\n", status, urb->UrbHeader.Status));
- goto end;
- }
-
-end:
- if (urb) ExFreePool(urb);
-
- return status;
-}
-
-static NTSTATUS VBoxUSBClearEndpoint(PDEVICE_EXTENSION pDevice, uint32_t EndPointAddress, bool fReset)
-{
- NTSTATUS status = STATUS_SUCCESS;
- URB *urb = NULL;
-
- status = VBoxUSBClearPipe(pDevice, VBoxUSBGetPipeHandle(pDevice, EndPointAddress), fReset );
- if (!NT_SUCCESS(status))
- {
- AssertMsgFailed(("VBoxUSBClearEndpoint: VBoxUSBSendIOCTL failed with %x (%x)\n", status, urb->UrbHeader.Status));
- }
-
- return status;
-}
-
-static USB_CONFIGURATION_DESCRIPTOR *VBoxUSBFindConfigDesc(PDEVICE_EXTENSION pDevice, unsigned uConfigValue)
-{
- USB_CONFIGURATION_DESCRIPTOR *cfgdescr = NULL;
- unsigned i;
-
- Assert(pDevice);
- for (i = 0; i < MAX_CFGS; ++i)
- {
- if (pDevice->usbdev.cfgdescr[i])
- {
- if (pDevice->usbdev.cfgdescr[i]->bConfigurationValue == uConfigValue)
- {
- cfgdescr = pDevice->usbdev.cfgdescr[i];
- break;
- }
- }
- }
-
- return cfgdescr;
-}
-
-/**
- * Select USB interface
- *
- * @returns NT Status
- * @param pDevice USB device pointer
- * @param InterfaceNumber interface number
- * @param AlternateSetting alternate setting
- */
-NTSTATUS VBoxUSBSetInterface(PDEVICE_EXTENSION pDevice, uint32_t InterfaceNumber, int AlternateSetting)
-{
- NTSTATUS status;
- URB *urb = NULL;
- USB_CONFIGURATION_DESCRIPTOR *cfgdescr = NULL;
- USB_INTERFACE_DESCRIPTOR *ifacedesc = NULL;
- USBD_INTERFACE_LIST_ENTRY *interfaces = NULL;
- uint32_t uTotalIfaceInfoLength;
- USHORT uUrbSize;
- unsigned i;
-
- if (!pDevice->usbdev.uConfigValue)
- {
- AssertMsgFailed(("Can't select an interface without an active configuration\n"));
- status = STATUS_INVALID_PARAMETER;
- goto end;
- }
-
- if (InterfaceNumber >= pDevice->usbdev.uNumInterfaces)
- {
- AssertMsgFailed(("InterfaceNumber %d too high!!\n", InterfaceNumber));
- status = STATUS_INVALID_PARAMETER;
- goto end;
- }
-
- cfgdescr = VBoxUSBFindConfigDesc(pDevice, pDevice->usbdev.uConfigValue);
- if (!cfgdescr)
- {
- AssertMsgFailed(("VBoxUSBSetInterface: configuration %d not found!!\n", pDevice->usbdev.uConfigValue));
- status = STATUS_INVALID_PARAMETER;
- goto end;
- }
-
- dprintf(("Calling USBD_ParseConfigurationDescriptorEx...\n"));
- ifacedesc = USBD_ParseConfigurationDescriptorEx(cfgdescr, cfgdescr, InterfaceNumber, AlternateSetting, -1, -1, -1);
- if (!ifacedesc)
- {
- AssertMsgFailed(("VBoxUSBSetInterface: invalid interface %d or alternate setting %d\n", InterfaceNumber, AlternateSetting));
- status = STATUS_UNSUCCESSFUL;
- goto end;
- }
- dprintf(("USBD_ParseConfigurationDescriptorEx successful\n"));
-
- uUrbSize = GET_SELECT_INTERFACE_REQUEST_SIZE(ifacedesc->bNumEndpoints);
- uTotalIfaceInfoLength = GET_USBD_INTERFACE_SIZE(ifacedesc->bNumEndpoints);
-
- urb = (URB *)ExAllocatePool(NonPagedPool, uUrbSize);
- if (!urb)
- {
- AssertMsgFailed(("VBoxUSBSetInterface: ExAllocatePool failed!\n"));
- status = STATUS_NO_MEMORY;
- goto end;
- }
-
- /*
- * Free old interface and pipe info, allocate new again
- */
- if (pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo) {
- /* Clear pipes associated with the interface, else Windows may hang. */
- for(i=0; i<pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo->NumberOfPipes; i++)
- {
- dprintf(("Aborting Pipe %d handle %x address %x\n", i,
- pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo->Pipes[i].PipeHandle,
- pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo->Pipes[i].EndpointAddress));
- VBoxUSBClearPipe(pDevice, pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo->Pipes[i].PipeHandle, FALSE);
- }
- ExFreePool(pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo);
- }
- if (pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pPipeInfo)
- ExFreePool(pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pPipeInfo);
-
- pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo = (PUSBD_INTERFACE_INFORMATION) ExAllocatePool(NonPagedPool, uTotalIfaceInfoLength);
- if (!pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo)
- {
- AssertMsgFailed(("VBoxUSBSetInterface: ExAllocatePool failed!\n"));
- status = STATUS_NO_MEMORY;
- goto end;
- }
- if (ifacedesc->bNumEndpoints > 0) {
- pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pPipeInfo = (VBOXUSB_PIPE_INFO *) ExAllocatePool(NonPagedPool, ifacedesc->bNumEndpoints * sizeof(VBOXUSB_PIPE_INFO));
- if (!pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pPipeInfo)
- {
- AssertMsgFailed(("VBoxUSBSetInterface: ExAllocatePool failed!\n"));
- status = STATUS_NO_MEMORY;
- goto end;
- }
- }
- else
- pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pPipeInfo = NULL;
-
- memset(urb, 0, uUrbSize);
- UsbBuildSelectInterfaceRequest(urb, uUrbSize, pDevice->usbdev.hConfiguration, InterfaceNumber, AlternateSetting);
- urb->UrbSelectInterface.Interface.Length = GET_USBD_INTERFACE_SIZE(ifacedesc->bNumEndpoints);
-
- status = VBoxUSBSendIOCTL(pDevice, IOCTL_INTERNAL_USB_SUBMIT_URB, urb);
-// status = VBoxUSBSyncSendRequest(pDevice, IOCTL_INTERNAL_USB_SUBMIT_URB, urb);
- if (!NT_SUCCESS(status) || !USBD_SUCCESS(urb->UrbHeader.Status))
- {
- AssertMsgFailed(("VBoxUSBSetInterface: VBoxUSBSendIOCTL failed with %x (%x)\n", status, urb->UrbHeader.Status));
- goto end;
- }
-
- USBD_INTERFACE_INFORMATION *ifaceinfo = &urb->UrbSelectInterface.Interface;
- memcpy(pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo, ifaceinfo, GET_USBD_INTERFACE_SIZE(ifacedesc->bNumEndpoints));
-
- Assert(ifaceinfo->NumberOfPipes == ifacedesc->bNumEndpoints);
- for(i=0;i<ifaceinfo->NumberOfPipes;i++)
- {
- dprintf(("Pipe %d: handle %x address %x transfer size=%d\n", i, ifaceinfo->Pipes[i].PipeHandle, ifaceinfo->Pipes[i].EndpointAddress, ifaceinfo->Pipes[i].MaximumTransferSize));
- pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo->Pipes[i] = ifaceinfo->Pipes[i];
- pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pPipeInfo[i].EndpointAddress = ifaceinfo->Pipes[i].EndpointAddress;
- pDevice->usbdev.pVBIfaceInfo[InterfaceNumber].pPipeInfo[i].NextScheduledFrame = 0;
- }
-
-end:
- if (interfaces) ExFreePool(interfaces);
- if (urb) ExFreePool(urb);
-
- return status;
-}
-
-/**
- * Select USB configuration
- *
- * @returns NT Status
- * @param pDevice USB device pointer
- * @param uConfiguration configuration value
- */
-NTSTATUS VBoxUSBSetConfig(PDEVICE_EXTENSION pDevice, unsigned uConfiguration)
-{
- NTSTATUS status;
- URB *urb = NULL;
- USB_CONFIGURATION_DESCRIPTOR *cfgdescr = NULL;
- USBD_INTERFACE_LIST_ENTRY *interfaces = NULL;
- unsigned i;
-
- if (uConfiguration == 0)
- {
- urb = (PURB)ExAllocatePool(NonPagedPool,sizeof(URB));
- if(urb == NULL)
- {
- dprintf(("VBoxUSBSetConfig: Failed to alloc mem for urb\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Before setting the configuration, free any existing interface information.
- * Also abort any open pipes, else the set config request will hang.
- */
- VBoxUSBFreeInterfaces(pDevice, TRUE);
-
- memset(urb, 0, sizeof(URB));
- urb->UrbHeader.Function = URB_FUNCTION_SELECT_CONFIGURATION;
- urb->UrbHeader.Length = sizeof(struct _URB_SELECT_CONFIGURATION);
- urb->UrbSelectConfiguration.ConfigurationDescriptor = NULL; //no config
-
- status = VBoxUSBSendIOCTL(pDevice, IOCTL_INTERNAL_USB_SUBMIT_URB, urb);
- if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb->UrbHeader.Status))
- {
- AssertMsgFailed(("VBoxUSBSetConfig: VBoxUSBSendIOCTL failed with %x (%x)\n", status, urb->UrbHeader.Status));
- ExFreePool(urb);
- return status;
- }
-
- pDevice->usbdev.hConfiguration = urb->UrbSelectConfiguration.ConfigurationHandle;
- pDevice->usbdev.uConfigValue = uConfiguration;
- ExFreePool(urb);
- return status;
- }
-
- cfgdescr = VBoxUSBFindConfigDesc(pDevice, uConfiguration);
- if (!cfgdescr)
- {
- AssertMsgFailed(("VBoxUSBSetConfig: configuration %d not found\n", uConfiguration));
- status = STATUS_INVALID_PARAMETER;
- goto end;
- }
-
- interfaces = (USBD_INTERFACE_LIST_ENTRY *) ExAllocatePool(NonPagedPool,(cfgdescr->bNumInterfaces + 1) * sizeof(USBD_INTERFACE_LIST_ENTRY));
- if (!interfaces)
- {
- AssertMsgFailed(("VBoxUSBSetConfig: ExAllocatePool failed!\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto end;
- }
-
- memset(interfaces, 0, (cfgdescr->bNumInterfaces + 1) * sizeof(USBD_INTERFACE_LIST_ENTRY));
-
- dprintf(("NumInterfaces %d\n", cfgdescr->bNumInterfaces));
- for(i=0;i<cfgdescr->bNumInterfaces;i++)
- {
- interfaces[i].InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(cfgdescr, cfgdescr, i, 0, -1, -1, -1);
- if (!interfaces[i].InterfaceDescriptor)
- {
- AssertMsgFailed(("VBoxUSBSetConfig: interface %d not found\n", i));
- status = STATUS_INVALID_PARAMETER;
- goto end;
- }
- else
- {
- dprintf(("VBoxUSBSetConfig: interface %d found\n", i));
- }
- }
-
- urb = USBD_CreateConfigurationRequestEx(cfgdescr, interfaces);
- if (!urb)
- {
- AssertMsgFailed(("VBoxUSBSetConfig: USBD_CreateConfigurationRequestEx failed!\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto end;
- }
-
- status = VBoxUSBSendIOCTL(pDevice, IOCTL_INTERNAL_USB_SUBMIT_URB, urb);
- if (!NT_SUCCESS(status) || !USBD_SUCCESS(urb->UrbHeader.Status))
- {
- AssertMsgFailed(("VBoxUSBSetConfig: VBoxUSBSendIOCTL failed with %x (%x)\n", status, urb->UrbHeader.Status));
- goto end;
- }
-
- /*
- * Free per-device interface info
- */
- VBoxUSBFreeInterfaces(pDevice, FALSE);
-
- pDevice->usbdev.hConfiguration = urb->UrbSelectConfiguration.ConfigurationHandle;
- pDevice->usbdev.uConfigValue = uConfiguration;
- pDevice->usbdev.uNumInterfaces = cfgdescr->bNumInterfaces;
-
- /*
- * Allocate room for interface pointer array
- */
- pDevice->usbdev.pVBIfaceInfo = (VBOXUSB_IFACE_INFO *)ExAllocatePool(NonPagedPool, pDevice->usbdev.uNumInterfaces * sizeof(VBOXUSB_IFACE_INFO));
- if (!pDevice->usbdev.pVBIfaceInfo)
- {
- AssertMsgFailed(("VBoxUSBSetConfig: ExAllocatePool failed!\n"));
- status = STATUS_NO_MEMORY;
- goto end;
- }
- memset(pDevice->usbdev.pVBIfaceInfo, 0, pDevice->usbdev.uNumInterfaces * sizeof(VBOXUSB_IFACE_INFO));
-
- /*
- * And fill in the information for all interfaces
- */
- for (i=0;i<pDevice->usbdev.uNumInterfaces;i++)
- {
- uint32_t uTotalIfaceInfoLength = sizeof(struct _URB_SELECT_INTERFACE) + ((interfaces[i].Interface->NumberOfPipes > 0) ? (interfaces[i].Interface->NumberOfPipes - 1) : 0) * sizeof(USBD_PIPE_INFORMATION);
-
- pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo = (PUSBD_INTERFACE_INFORMATION) ExAllocatePool(NonPagedPool, uTotalIfaceInfoLength);
- if (!pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo)
- {
- AssertMsgFailed(("VBoxUSBSetConfig: ExAllocatePool failed!\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto end;
- }
- if (interfaces[i].Interface->NumberOfPipes > 0)
- {
- pDevice->usbdev.pVBIfaceInfo[i].pPipeInfo = (VBOXUSB_PIPE_INFO *) ExAllocatePool(NonPagedPool, interfaces[i].Interface->NumberOfPipes * sizeof(VBOXUSB_PIPE_INFO));
- if (!pDevice->usbdev.pVBIfaceInfo[i].pPipeInfo)
- {
- AssertMsgFailed(("VBoxUSBSetConfig: ExAllocatePool failed!\n"));
- status = STATUS_NO_MEMORY;
- goto end;
- }
- }
- else
- pDevice->usbdev.pVBIfaceInfo[i].pPipeInfo = NULL;
-
- *pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo = *interfaces[i].Interface;
-
- dprintf(("interface %d nr %d\n", i, interfaces[i].Interface->InterfaceNumber));
- dprintf(("interface %d aset %d\n", i, interfaces[i].Interface->AlternateSetting));
-
- for (int j=0;j<(int)interfaces[i].Interface->NumberOfPipes;j++)
- {
- dprintf(("Pipe %d: handle %x address %x transfer size=%d\n", j, interfaces[i].Interface->Pipes[j].PipeHandle, interfaces[i].Interface->Pipes[j].EndpointAddress, interfaces[i].Interface->Pipes[j].MaximumTransferSize));
- pDevice->usbdev.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j] = interfaces[i].Interface->Pipes[j];
- pDevice->usbdev.pVBIfaceInfo[i].pPipeInfo[j].EndpointAddress = interfaces[i].Interface->Pipes[j].EndpointAddress;
- pDevice->usbdev.pVBIfaceInfo[i].pPipeInfo[j].NextScheduledFrame = 0;
-
- }
- }
-
-end:
- if (interfaces) ExFreePool(interfaces);
- if (urb) ExFreePool(urb);
-
- return status;
-}
-
-
-
-// Generic completion routine for simple requests
-static NTSTATUS _stdcall VBoxUSB_StopCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
-{
- PKEVENT event;
-
- event = (PKEVENT) Context;
- KeSetEvent(event, IO_NO_INCREMENT, FALSE);
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-// Send IRP/URB to fetch the current frame number for isochronous transfers
-static ULONG VBoxUSB_GetCurrentFrame(PDEVICE_EXTENSION DeviceExtension, PIRP Irp)
-{
- KEVENT event;
- PIO_STACK_LOCATION nextStack;
- struct _URB_GET_CURRENT_FRAME_NUMBER urb;
-
- // initialize the urb
- urb.Hdr.Function = URB_FUNCTION_GET_CURRENT_FRAME_NUMBER;
- urb.Hdr.Length = sizeof(urb);
- urb.FrameNumber = (ULONG) -1;
-
- nextStack = IoGetNextIrpStackLocation(Irp);
- nextStack->Parameters.Others.Argument1 = (PVOID) &urb;
- nextStack->Parameters.DeviceIoControl.IoControlCode =
- IOCTL_INTERNAL_USB_SUBMIT_URB;
- nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
- IoSetCompletionRoutine(Irp, VBoxUSB_StopCompletion, &event, TRUE, TRUE, TRUE);
-
- dprintf(("VBoxUSB_GetCurrentFrame::"));
- VBoxUSB_IoIncrement(DeviceExtension);
-
- IoCallDriver(DeviceExtension->TopOfStackDeviceObject, Irp);
- KeWaitForSingleObject((PVOID) &event, Executive, KernelMode, FALSE, NULL);
-
- dprintf(("VBoxUSB_GetCurrentFrame::"));
- VBoxUSB_IoDecrement(DeviceExtension);
-
- dprintf(("VBoxUSB_GetCurrentFrame returns %d\n", urb.FrameNumber));
-
- return urb.FrameNumber;
-}
-
-/**
- * Query device speed (High-speed vs. low/full-speed)
- *
- * @returns NT Status
- * @param pDevice USB device pointer
- */
-NTSTATUS VBoxUSBGetDeviceSpeed(PDEVICE_EXTENSION pDevExt)
-{
- PIRP irp;
- KEVENT event;
- NTSTATUS ntStatus;
- PIO_STACK_LOCATION nextStack;
- USB_BUS_INTERFACE_USBDI_V1 busInterfaceVer1;
-
- irp = IoAllocateIrp(pDevExt->TopOfStackDeviceObject->StackSize, FALSE);
-
- if (irp == NULL) {
- AssertMsgFailed(("VBoxUSBGetDeviceSpeed: Failed to allocate IRP!\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- // All PnP IRPs need the status field initialized to STATUS_NOT_SUPPORTED
- irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- KeInitializeEvent(&event, NotificationEvent, FALSE);
-
- // Set the completion routine, which will signal the event
- IoSetCompletionRoutine(irp,
- VBoxUSB_StopCompletion,
- &event,
- TRUE, // InvokeOnSuccess
- TRUE, // InvokeOnError
- TRUE); // InvokeOnCancel
-
- nextStack = IoGetNextIrpStackLocation(irp);
- Assert(nextStack);
- nextStack->MajorFunction = IRP_MJ_PNP;
- nextStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
-
- // Allocate memory for an interface of type
- // USB_BUS_INTERFACE_USBDI_V1 and set up the IRP
- nextStack->Parameters.QueryInterface.Interface = (PINTERFACE)&busInterfaceVer1;
- nextStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
- nextStack->Parameters.QueryInterface.InterfaceType = &USB_BUS_INTERFACE_USBDI_GUID;
- nextStack->Parameters.QueryInterface.Size = sizeof(USB_BUS_INTERFACE_USBDI_V1);
- nextStack->Parameters.QueryInterface.Version = USB_BUSIF_USBDI_VERSION_1;
-
- dprintf(("VBoxUSBGetDeviceSpeed::"));
- VBoxUSB_IoIncrement(pDevExt);
-
- ntStatus = IoCallDriver(pDevExt->TopOfStackDeviceObject, irp);
- if(STATUS_PENDING == ntStatus) {
- KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
- ntStatus = irp->IoStatus.Status;
- }
-
- if(NT_SUCCESS(ntStatus)) {
- pDevExt->usbdev.fIsHighSpeed = busInterfaceVer1.IsDeviceHighSpeed(busInterfaceVer1.BusContext);
- dprintf(("VBoxUSBGetDeviceSpeed: IsDeviceHighSpeed = %x\n", pDevExt->usbdev.fIsHighSpeed));
- }
-
- IoFreeIrp(irp);
-
- dprintf(("VBoxUSBGetDeviceSpeed::"));
- VBoxUSB_IoDecrement(pDevExt);
- return ntStatus;
-}
-
-static NTSTATUS _stdcall VBoxUSBIOCTLAsyncCompletion(DEVICE_OBJECT *device_object, IRP *pIrp, void *context)
-{
- PVBOXUSB_URB_CONTEXT pContext = (PVBOXUSB_URB_CONTEXT)context;
- PURB urb = NULL;
- PMDL pMdlBuf = NULL;
- PUSBSUP_URB pOut;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION pDevExt;
-
- if (!context)
- {
- AssertFailed();
- pIrp->IoStatus.Information = 0;
- return STATUS_CONTINUE_COMPLETION;
- }
-
- if (pContext->ulMagic != VBOXUSB_MAGIC)
- {
- AssertMsgFailed(("Invalid context magic!!\n"));
- pIrp->IoStatus.Information = 0;
- return STATUS_CONTINUE_COMPLETION;
- }
-
- urb = pContext->pUrb;
- pMdlBuf = pContext->pMdlBuf;
- pOut = (PUSBSUP_URB)pContext->pOut;
- pDevExt = (PDEVICE_EXTENSION)pContext->DeviceExtension;
-
- dprintf(("VBoxURBAsyncCompletion %p status=%x URB %p IRQL=%d\n", pIrp, pIrp->IoStatus.Status, urb, KeGetCurrentIrql()));
-
- if (!urb || !pMdlBuf || !pOut | !pDevExt)
- {
- AssertFailed();
- if (pDevExt)
- VBoxUSB_IoDecrement(pDevExt);
- pIrp->IoStatus.Information = 0;
- return STATUS_CONTINUE_COMPLETION;
- }
-
- ////rt(MmIsAddressValid(pOut) == TRUE);
-
- ntStatus = pIrp->IoStatus.Status;
- if (ntStatus == STATUS_SUCCESS)
- {
- switch(urb->UrbHeader.Status)
- {
- case USBD_STATUS_CRC:
- pOut->error = USBSUP_XFER_CRC;
- break;
- case USBD_STATUS_SUCCESS:
- pOut->error = USBSUP_XFER_OK;
- break;
- case USBD_STATUS_STALL_PID:
- pOut->error = USBSUP_XFER_STALL;
- break;
- case USBD_STATUS_INVALID_URB_FUNCTION:
- case USBD_STATUS_INVALID_PARAMETER:
- AssertFailed(); // SW error - we probably messed up
- // fall through
- case USBD_STATUS_DEV_NOT_RESPONDING:
- default:
- pOut->error = USBSUP_XFER_DNR;
- break;
- }
-
- switch(pContext->ulTransferType)
- {
- case USBSUP_TRANSFER_TYPE_CTRL:
- case USBSUP_TRANSFER_TYPE_MSG:
- pOut->len = urb->UrbControlTransfer.TransferBufferLength;
- if (pContext->ulTransferType == USBSUP_TRANSFER_TYPE_MSG)
- {
- /* QUSB_TRANSFER_TYPE_MSG is a control transfer, but it is special
- * the first 8 bytes of the buffer is the setup packet so the real
- * data length is therefore urb->len - 8
- */
- pOut->len += sizeof(urb->UrbControlTransfer.SetupPacket);
- }
- break;
- case USBSUP_TRANSFER_TYPE_ISOC:
- pOut->len = urb->UrbIsochronousTransfer.TransferBufferLength;
- break;
- case USBSUP_TRANSFER_TYPE_BULK:
- case USBSUP_TRANSFER_TYPE_INTR:
- if ( (pOut->dir == USBSUP_DIRECTION_IN) && (pOut->error == USBSUP_XFER_OK)
- && !(pOut->flags & USBSUP_FLAG_SHORT_OK) && (pOut->len > urb->UrbBulkOrInterruptTransfer.TransferBufferLength))
- {
- /* If we don't use the USBD_SHORT_TRANSFER_OK flag, the returned buffer lengths are
- * wrong for short transfers (always a multiple of max packet size?). So we just figure
- * out if this was a data underrun on our own.
- */
- pOut->error = USBSUP_XFER_UNDERRUN;
- }
- pOut->len = urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
- break;
- }
- }
- else
- {
- pOut->len = 0;
-
- dprintf(("URB failed with %x\n", urb->UrbHeader.Status));
-#ifdef DEBUG
- switch(pContext->ulTransferType)
- {
- case USBSUP_TRANSFER_TYPE_CTRL:
- case USBSUP_TRANSFER_TYPE_MSG:
- dprintf(("Ctrl/Msg length=%d\n", urb->UrbControlTransfer.TransferBufferLength));
- break;
- case USBSUP_TRANSFER_TYPE_ISOC:
- dprintf(("ISOC length=%d\n", urb->UrbIsochronousTransfer.TransferBufferLength));
- break;
- case USBSUP_TRANSFER_TYPE_BULK:
- case USBSUP_TRANSFER_TYPE_INTR:
- dprintf(("BULK/INTR length=%d\n", urb->UrbBulkOrInterruptTransfer.TransferBufferLength));
- break;
- }
-#endif
- switch(urb->UrbHeader.Status)
- {
- case USBD_STATUS_CRC:
- pOut->error = USBSUP_XFER_CRC;
- ntStatus = STATUS_SUCCESS;
- break;
- case USBD_STATUS_STALL_PID:
- pOut->error = USBSUP_XFER_STALL;
- ntStatus = STATUS_SUCCESS;
- break;
- case USBD_STATUS_DEV_NOT_RESPONDING:
- pOut->error = USBSUP_XFER_DNR;
- ntStatus = STATUS_SUCCESS;
- break;
- case ((USBD_STATUS)0xC0010000L): // USBD_STATUS_CANCELED - too bad usbdi.h and usb.h aren't consistent!
- // TODO: What the heck are we really supposed to do here?
- pOut->error = USBSUP_XFER_STALL;
- ntStatus = STATUS_SUCCESS;
- break;
- case USBD_STATUS_BAD_START_FRAME: // This one really shouldn't happen
- case USBD_STATUS_ISOCH_REQUEST_FAILED:
- pOut->error = USBSUP_XFER_NAC;
- ntStatus = STATUS_SUCCESS;
- break;
- default:
- AssertMsgFailed(("VBoxUSBSendIOCTL returned %x (%x)\n", ntStatus, urb->UrbHeader.Status));
- pOut->error = USBSUP_XFER_DNR;
- ntStatus = STATUS_SUCCESS;
- break;
- }
- }
- // For isochronous transfers, always update the individual packets
- if (pContext->ulTransferType == USBSUP_TRANSFER_TYPE_ISOC)
- {
- Assert(pOut->numIsoPkts == urb->UrbIsochronousTransfer.NumberOfPackets);
- for (unsigned i = 0; i < pOut->numIsoPkts; ++i)
- {
- Assert(pOut->aIsoPkts[i].off == urb->UrbIsochronousTransfer.IsoPacket[i].Offset);
- pOut->aIsoPkts[i].cb = (uint16_t)urb->UrbIsochronousTransfer.IsoPacket[i].Length;
- switch (urb->UrbIsochronousTransfer.IsoPacket[i].Status)
- {
- case USBD_STATUS_SUCCESS:
- pOut->aIsoPkts[i].stat = USBSUP_XFER_OK;
- break;
- case USBD_STATUS_NOT_ACCESSED:
- pOut->aIsoPkts[i].stat = USBSUP_XFER_NAC;
- break;
- default:
- pOut->aIsoPkts[i].stat = USBSUP_XFER_STALL;
- break;
- }
- }
- }
- MmUnlockPages(pMdlBuf);
- IoFreeMdl(pMdlBuf);
-
- ExFreePool(pContext);
-
- dprintf(("VBoxUSBIOCTLAsyncCompletion::"));
- VBoxUSB_IoDecrement(pDevExt);
-
- Assert(pIrp->IoStatus.Status != STATUS_IO_TIMEOUT);
- // Number of bytes returned
- pIrp->IoStatus.Information = sizeof(*pOut);
- pIrp->IoStatus.Status = ntStatus;
- return STATUS_CONTINUE_COMPLETION;
-}
-
-NTSTATUS VBoxUSBSendURB(PDEVICE_EXTENSION pDevExt, PIRP pIrp, PUSBSUP_URB pIn, PUSBSUP_URB pOut)
-{
- NTSTATUS status;
- PIO_STACK_LOCATION stackloc;
- PURB urb = NULL;
- HANDLE PipeHandle;
- PMDL pMdlBuf = NULL;
- PVBOXUSB_URB_CONTEXT pContext = NULL;
- ULONG urbSize;
-
- Assert(pIn && pOut);
-
- // Isochronous transfers use multiple packets -> variable URB size
- if (pIn->type == USBSUP_TRANSFER_TYPE_ISOC)
- {
- Assert(pOut->numIsoPkts <= 8);
- urbSize = GET_ISO_URB_SIZE(pOut->numIsoPkts);
- }
- else
- urbSize = sizeof(URB);
-
- pContext = (PVBOXUSB_URB_CONTEXT)ExAllocatePool(NonPagedPool, urbSize + sizeof(VBOXUSB_URB_CONTEXT));
- if(pContext == NULL)
- {
- dprintf(("Failed to alloc mem for urb\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto SendUrbFailure;
- }
- memset(pContext, 0, urbSize + sizeof(VBOXUSB_URB_CONTEXT));
- urb = (PURB)(pContext + 1);
-
- PipeHandle = 0;
- if (pIn->ep)
- {
- PipeHandle = VBoxUSBGetPipeHandle(pDevExt, pIn->ep | ((pIn->dir == USBSUP_DIRECTION_IN) ? 0x80 : 0x00));
- if (PipeHandle == 0)
- {
- AssertMsgFailed(("VBoxUSBGetPipeHandle failed for endpoint %x!\n", pIn->ep));
- status = STATUS_INVALID_PARAMETER;
- goto SendUrbFailure;
- }
- }
-
- /*
- * Allocate pMdl for the user mode data buffer
- */
- pMdlBuf = IoAllocateMdl(pIn->buf, (ULONG)pIn->len, FALSE, FALSE, NULL);
- if (!pMdlBuf)
- {
- AssertMsgFailed(("IoAllocateMdl failed for buffer %p length %d\n", pIn->buf, pIn->len));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto SendUrbFailure;
- }
- __try
- {
- MmProbeAndLockPages(pMdlBuf, KernelMode, IoModifyAccess);
- }
- __except(EXCEPTION_EXECUTE_HANDLER)
- {
- status = GetExceptionCode();
- IoFreeMdl(pMdlBuf);
- pMdlBuf = NULL;
- dprintf(("MmProbeAndLockPages: Exception Code %x\n", status));
- goto SendUrbFailure;
- }
-
- /* For some reason, passing a MDL in the URB does not work reliably. Notably
- * the iPhone when used with iTunes fails.
- */
- PVOID pBuffer = MmGetSystemAddressForMdlSafe(pMdlBuf, NormalPagePriority);
- if (!pBuffer)
- {
- AssertMsgFailed(("MmGetSystemAddressForMdlSafe failed for buffer!!\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto SendUrbFailure;
- }
-
- /* Setup URB */
- switch(pIn->type)
- {
- case USBSUP_TRANSFER_TYPE_CTRL:
- case USBSUP_TRANSFER_TYPE_MSG:
- urb->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER;
- urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_TRANSFER);
- urb->UrbControlTransfer.PipeHandle = PipeHandle;
- urb->UrbControlTransfer.TransferBufferLength = (ULONG)pIn->len;
- urb->UrbControlTransfer.TransferFlags = ((pIn->dir == USBSUP_DIRECTION_IN) ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT);
- urb->UrbControlTransfer.UrbLink = 0;
-
- if (PipeHandle == 0)
- urb->UrbControlTransfer.TransferFlags |= USBD_DEFAULT_PIPE_TRANSFER;
-
- if (pIn->type == USBSUP_TRANSFER_TYPE_MSG)
- {
- /* QUSB_TRANSFER_TYPE_MSG is a control transfer, but it is special
- * the first 8 bytes of the buffer is the setup packet so the real
- * data length is therefore urb->len - 8
- */
- PUSBSETUP pSetup = (PUSBSETUP)urb->UrbControlTransfer.SetupPacket;
- memcpy(urb->UrbControlTransfer.SetupPacket, pBuffer, min(sizeof(urb->UrbControlTransfer.SetupPacket), pIn->len));
-
- if (urb->UrbControlTransfer.TransferBufferLength <= sizeof(urb->UrbControlTransfer.SetupPacket))
- urb->UrbControlTransfer.TransferBufferLength = 0;
- else
- urb->UrbControlTransfer.TransferBufferLength -= sizeof(urb->UrbControlTransfer.SetupPacket);
-
- urb->UrbControlTransfer.TransferBuffer = (uint8_t *)pBuffer + sizeof(urb->UrbControlTransfer.SetupPacket);
- urb->UrbControlTransfer.TransferBufferMDL = 0;
- urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
- }
- else
- {
- urb->UrbControlTransfer.TransferBuffer = 0;
- urb->UrbControlTransfer.TransferBufferMDL = pMdlBuf;
- }
- break;
-
- case USBSUP_TRANSFER_TYPE_ISOC:
- ULONG frameNum, startFrame;
- VBOXUSB_PIPE_INFO *pipeInfo;
-
- Assert(pIn->dir == USBSUP_DIRECTION_IN || pIn->type == USBSUP_TRANSFER_TYPE_BULK);
- Assert(PipeHandle);
- pipeInfo = VBoxUSBGetPipeState(pDevExt, pIn->ep | ((pIn->dir == USBSUP_DIRECTION_IN) ? 0x80 : 0x00));
- if (pipeInfo == NULL)
- {
- /* Can happen if the isoc request comes in too early or late. */
- AssertMsgFailed(("pipeInfo not found!!\n"));
- status = STATUS_INVALID_PARAMETER;
- goto SendUrbFailure;
- }
-
- urb->UrbHeader.Function = URB_FUNCTION_ISOCH_TRANSFER;
- urb->UrbHeader.Length = (USHORT)urbSize;
- urb->UrbIsochronousTransfer.PipeHandle = PipeHandle;
- urb->UrbIsochronousTransfer.TransferBufferLength = (ULONG)pIn->len;
- urb->UrbIsochronousTransfer.TransferBufferMDL = 0;
- urb->UrbIsochronousTransfer.TransferBuffer = pBuffer;
- urb->UrbIsochronousTransfer.TransferFlags = ((pIn->dir == USBSUP_DIRECTION_IN) ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT);
- urb->UrbIsochronousTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK; // May be implied already
- urb->UrbIsochronousTransfer.NumberOfPackets = pOut->numIsoPkts;
- urb->UrbIsochronousTransfer.ErrorCount = 0;
- urb->UrbIsochronousTransfer.UrbLink = 0;
-
- Assert(pOut->numIsoPkts == urb->UrbIsochronousTransfer.NumberOfPackets);
- for (unsigned i = 0; i < pOut->numIsoPkts; ++i)
- {
- urb->UrbIsochronousTransfer.IsoPacket[i].Offset = pOut->aIsoPkts[i].off;
- urb->UrbIsochronousTransfer.IsoPacket[i].Length = pOut->aIsoPkts[i].cb;
- }
-
- /* We have to schedule the URBs ourselves. There is an ASAP flag but
- * that can only be reliably used after pipe creation/reset, ie. it's
- * almost completely useless.
- */
- frameNum = VBoxUSB_GetCurrentFrame(pDevExt, pIrp) + 2; // Some fudge factor is required
- startFrame = pipeInfo->NextScheduledFrame;
- if ((frameNum < startFrame) || (startFrame > frameNum + 512))
- frameNum = startFrame;
- pipeInfo->NextScheduledFrame = frameNum + pOut->numIsoPkts;
- urb->UrbIsochronousTransfer.StartFrame = frameNum;
- dprintf(("URB scheduled to start at frame %d (%d packets)\n", frameNum, pOut->numIsoPkts));
- break;
-
- case USBSUP_TRANSFER_TYPE_BULK:
- case USBSUP_TRANSFER_TYPE_INTR:
- Assert(pIn->dir != USBSUP_DIRECTION_SETUP);
- // Interrupt transfers must have USBD_TRANSFER_DIRECTION_IN according to the DDK
- Assert(pIn->dir == USBSUP_DIRECTION_IN || pIn->type == USBSUP_TRANSFER_TYPE_BULK);
- Assert(PipeHandle);
-
- urb->UrbHeader.Function = URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
- urb->UrbHeader.Length = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
- urb->UrbBulkOrInterruptTransfer.PipeHandle = PipeHandle;
- urb->UrbBulkOrInterruptTransfer.TransferBufferLength = (ULONG)pIn->len;
- urb->UrbBulkOrInterruptTransfer.TransferBufferMDL = 0;
- urb->UrbBulkOrInterruptTransfer.TransferBuffer = pBuffer;
- urb->UrbBulkOrInterruptTransfer.TransferFlags = ((pIn->dir == USBSUP_DIRECTION_IN) ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT);
-
- if (urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
- urb->UrbBulkOrInterruptTransfer.TransferFlags |= (USBD_SHORT_TRANSFER_OK);
-
- urb->UrbBulkOrInterruptTransfer.UrbLink = 0;
- break;
-
- default:
- AssertFailed();
- status = STATUS_INVALID_PARAMETER;
- goto SendUrbFailure;
- }
-
- pContext->DeviceExtension = pDevExt;
- pContext->pMdlBuf = pMdlBuf;
- pContext->pUrb = urb;
- pContext->pOut = pOut;
- pContext->ulTransferType = pIn->type;
- pContext->ulMagic = VBOXUSB_MAGIC;
-
- // Reuse the original IRP
- stackloc = IoGetNextIrpStackLocation(pIrp);
- stackloc->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
- stackloc->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
- stackloc->Parameters.Others.Argument1 = urb;
- stackloc->Parameters.Others.Argument2 = NULL;
-
- IoSetCompletionRoutine(pIrp, VBoxUSBIOCTLAsyncCompletion, pContext, TRUE, TRUE, TRUE);
- IoMarkIrpPending(pIrp);
-
- dprintf(("VBoxUSBSendURB::"));
- VBoxUSB_IoIncrement(pDevExt);
-
- dprintf(("Send URB %p Pipe=%x Buffer=%p Length=%d\n", urb, PipeHandle, pIn->buf, pIn->len));
- status = IoCallDriver(pDevExt->TopOfStackDeviceObject, pIrp);
- if (!NT_SUCCESS(status))
- {
- dprintf(("IoCallDriver failed with status %X\n", status));
- }
-
- dprintf(("IoCallDriver returned %x\n", status));
- /* We've marked the IRP as pending, so we must return STATUS_PENDING regardless of what IoCallDriver returns. */
- return STATUS_PENDING;
-
-SendUrbFailure:
- if (pMdlBuf)
- {
- MmUnlockPages(pMdlBuf);
- IoFreeMdl(pMdlBuf);
- }
- if (pContext)
- ExFreePool(pContext);
-
- return status;
-}
-
-
-NTSTATUS VBoxUSBSendIOCTL(PDEVICE_EXTENSION pDevExt, ULONG control_code, void *buffer)
-{
- IO_STATUS_BLOCK io_status;
- KEVENT event;
- NTSTATUS status;
- IRP *pIrp;
- PIO_STACK_LOCATION stackloc;
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
-
- pIrp = IoBuildDeviceIoControlRequest(control_code, pDevExt->TopOfStackDeviceObject, NULL, 0, NULL, 0, TRUE, &event, &io_status);
- if (!pIrp)
- {
- AssertMsgFailed(("IoBuildDeviceIoControlRequest failed!!\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- stackloc = IoGetNextIrpStackLocation(pIrp);
- stackloc->Parameters.Others.Argument1 = buffer;
- stackloc->Parameters.Others.Argument2 = NULL;
-
- dprintf(("VBoxUSBSendIOCTL::"));
- VBoxUSB_IoIncrement(pDevExt);
-
- status = IoCallDriver(pDevExt->TopOfStackDeviceObject, pIrp);
- if (status == STATUS_PENDING)
- {
- dprintf(("IoCallDriver returned STATUS_PENDING!!\n"));
- KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
- status = io_status.Status;
- }
- dprintf(("VBoxUSBSendIOCTL::"));
- VBoxUSB_IoDecrement(pDevExt);
-
- dprintf(("IoCallDriver returned %x\n", status));
-
- return status;
-}
-
-#if 0 /* dead code */
-NTSTATUS VBoxUSBSyncCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
-{
- PKEVENT kevent;
-
- kevent = (PKEVENT)Context;
- KeSetEvent(kevent, IO_NO_INCREMENT, FALSE);
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-NTSTATUS VBoxUSBSyncSendRequest(PDEVICE_EXTENSION deviceExtension, ULONG control_code, void *buffer)
-{
- KEVENT localevent;
- PIRP irp;
- PIO_STACK_LOCATION nextStack;
- NTSTATUS ntStatus;
-
-// VBoxUsb_DbgPrint(2, ("enter: VBoxUsb_SyncSendUsbRequest\n"));
-
- // Initialize the event we'll wait on
- KeInitializeEvent(&localevent, SynchronizationEvent, FALSE);
-
- // Allocate the Irp
- irp = IoAllocateIrp(deviceExtension->TopOfStackDeviceObject->StackSize, FALSE);
-
- if (irp == NULL)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- // Set the Irp parameters
- nextStack = IoGetNextIrpStackLocation(irp);
-
- nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
- nextStack->Parameters.DeviceIoControl.IoControlCode = control_code;
- nextStack->Parameters.Others.Argument1 = buffer;
-
- // Set the completion routine, which will signal the event
- IoSetCompletionRoutine(irp,
- VBoxUSBSyncCompletionRoutine,
- &localevent,
- TRUE, // InvokeOnSuccess
- TRUE, // InvokeOnError
- TRUE); // InvokeOnCancel
-
-
-
- // Pass the Irp & Urb down the stack
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
-
- // If the request is pending, block until it completes
- if (ntStatus == STATUS_PENDING)
- {
- LARGE_INTEGER timeout;
-
- // Specify a timeout of 5 seconds to wait for this call to complete.
- timeout.QuadPart = -10000 * 5000;
- ntStatus = KeWaitForSingleObject(&localevent, Executive, KernelMode, FALSE, &timeout);
-
- if (ntStatus == STATUS_TIMEOUT)
- {
- ntStatus = STATUS_IO_TIMEOUT;
-
- // Cancel the Irp we just sent.
- IoCancelIrp(irp);
-
- // And wait until the cancel completes
- KeWaitForSingleObject(&localevent, Executive, KernelMode, FALSE, NULL);
- }
- else
- {
- ntStatus = irp->IoStatus.Status;
- }
- }
-
- // Done with the Irp, now free it.
- IoFreeIrp(irp);
-
-// VBoxUsb_DbgPrint(2, ("exit: VBoxUsb_SyncSendUsbRequest %08X\n", ntStatus));
- return ntStatus;
-}
-#endif
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxdev.h b/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxdev.h
deleted file mode 100644
index b60054ac3..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxdev.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*++
-
-Copyright (c) 2000 Microsoft Corporation
-
-Module Name:
-
- vboxdev.h
-
-Abstract:
-
-Environment:
-
- Kernel mode
-
-Notes:
-
- Copyright (c) 2000 Microsoft Corporation.
- All Rights Reserved.
-
---*/
-
-#ifndef _VBoxUSB_DEV_H
-#define _VBoxUSB_DEV_H
-
-#define VBOXUSB_MAGIC 0xABCF1423
-
-typedef struct {
- PURB pUrb;
- PMDL pMdlBuf;
- PDEVICE_EXTENSION DeviceExtension;
- PVOID pOut;
- ULONG ulTransferType;
- ULONG ulMagic;
-} VBOXUSB_URB_CONTEXT, * PVBOXUSB_URB_CONTEXT;
-
-RT_C_DECLS_BEGIN
-
-NTSTATUS
-VBoxUSB_DispatchCreate(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-VBoxUSB_DispatchClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-VBoxUSB_DispatchDevCtrl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-VBoxUSB_ResetPipe(
- IN PDEVICE_OBJECT DeviceObject,
- IN USBD_PIPE_HANDLE PipeHandle
- );
-
-NTSTATUS
-VBoxUSB_ResetDevice(
- IN PDEVICE_OBJECT DeviceObject
- );
-
-NTSTATUS
-VBoxUSB_GetPortStatus(
- IN PDEVICE_OBJECT DeviceObject,
- IN PULONG PortStatus
- );
-
-NTSTATUS
-VBoxUSB_ResetParentPort(
- IN IN PDEVICE_OBJECT DeviceObject
- );
-
-VOID
-VBoxUSB_FreeMemory(
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-NTSTATUS
-SubmitIdleRequestIrp(
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-VOID
-IdleNotificationCallback(
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-NTSTATUS
-IdleNotificationRequestComplete(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-VOID
-CancelSelectSuspend(
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-VOID
-PoIrpCompletionFunc(
- IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR MinorFunction,
- IN POWER_STATE PowerState,
- IN PVOID Context,
- IN PIO_STATUS_BLOCK IoStatus
- );
-
-VOID
-PoIrpAsyncCompletionFunc(
- IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR MinorFunction,
- IN POWER_STATE PowerState,
- IN PVOID Context,
- IN PIO_STATUS_BLOCK IoStatus
- );
-
-VOID
-WWIrpCompletionFunc(
- IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR MinorFunction,
- IN POWER_STATE PowerState,
- IN PVOID Context,
- IN PIO_STATUS_BLOCK IoStatus
- );
-
-NTSTATUS VBoxUSBCheckRootHub(IN IN PDEVICE_OBJECT DeviceObject);
-
-RT_C_DECLS_END
-
-#ifndef STATUS_CONTINUE_COMPLETION
-#define STATUS_CONTINUE_COMPLETION STATUS_SUCCESS
-#endif
-
-#endif
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpnp.cpp b/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpnp.cpp
deleted file mode 100644
index cbcac224f..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpnp.cpp
+++ /dev/null
@@ -1,2752 +0,0 @@
-/*++
-
-Copyright (c) 2000 Microsoft Corporation
-
-Module Name:
-
- vboxpnp.c
-
-Abstract:
-
- Bulk USB device driver for Intel 82930 USB test board
- Plug and Play module.
- This file contains routines to handle pnp requests.
- These routines are not USB specific but is required
- for every driver which conforms to the WDM model.
-
-Environment:
-
- Kernel mode
-
-Notes:
-
- Copyright (c) 2000 Microsoft Corporation.
- All Rights Reserved.
-
---*/
-
-#include "vboxusb.h"
-#include "vboxpnp.h"
-#include "vboxpwr.h"
-#include "vboxdev.h"
-#include "vboxrwr.h"
-#include <iprt/assert.h>
-
-NTSTATUS
-VBoxUSB_DispatchPnP(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- The plug and play dispatch routines.
- Most of these requests the driver will completely ignore.
- In all cases it must pass on the IRP to the lower driver.
-
-Arguments:
-
- DeviceObject - pointer to a device object.
-
- Irp - pointer to an I/O Request Packet.
-
-Return Value:
-
- NT status value
-
---*/
-{
- PIO_STACK_LOCATION irpStack;
- PDEVICE_EXTENSION deviceExtension;
- NTSTATUS ntStatus;
-
- //
- // initialize variables
- //
-
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // since the device is removed, fail the Irp.
- //
-
- if(Removed == deviceExtension->DeviceState) {
-
- ntStatus = STATUS_DELETE_PENDING;
-
- Irp->IoStatus.Status = ntStatus;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return ntStatus;
- }
-
- dprintf(("///////////////////////////////////////////\n"));
- dprintf(("VBoxUSB_DispatchPnP::"));
- VBoxUSB_IoIncrement(deviceExtension);
-
- if(irpStack->MinorFunction == IRP_MN_START_DEVICE) {
-
- ASSERT(deviceExtension->IdleReqPend == 0);
- }
- else {
-
- if(deviceExtension->SSEnable) {
-
- CancelSelectSuspend(deviceExtension);
- }
- }
-
- dprintf((PnPMinorFunctionString(irpStack->MinorFunction)));
-
- switch(irpStack->MinorFunction) {
-
- case IRP_MN_START_DEVICE:
-
- ntStatus = HandleStartDevice(DeviceObject, Irp);
-
- break;
-
- case IRP_MN_QUERY_STOP_DEVICE:
-
- //
- // if we cannot stop the device, we fail the query stop irp
- //
-
- ntStatus = CanStopDevice(DeviceObject, Irp);
-
- if(NT_SUCCESS(ntStatus)) {
-
- ntStatus = HandleQueryStopDevice(DeviceObject, Irp);
-
- return ntStatus;
- }
- break;
-
- case IRP_MN_CANCEL_STOP_DEVICE:
-
- ntStatus = HandleCancelStopDevice(DeviceObject, Irp);
-
- break;
-
- case IRP_MN_STOP_DEVICE:
-
- ntStatus = HandleStopDevice(DeviceObject, Irp);
-
- dprintf(("VBoxUSB_DispatchPnP::IRP_MN_STOP_DEVICE::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- return ntStatus;
-
- case IRP_MN_QUERY_REMOVE_DEVICE:
-
- //
- // if we cannot remove the device, we fail the query remove irp
- //
- ntStatus = HandleQueryRemoveDevice(DeviceObject, Irp);
-
- return ntStatus;
-
- case IRP_MN_CANCEL_REMOVE_DEVICE:
-
- ntStatus = HandleCancelRemoveDevice(DeviceObject, Irp);
-
- break;
-
- case IRP_MN_SURPRISE_REMOVAL:
-
- ntStatus = HandleSurpriseRemoval(DeviceObject, Irp);
-
- dprintf(("VBoxUSB_DispatchPnP::IRP_MN_SURPRISE_REMOVAL::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- return ntStatus;
-
- case IRP_MN_REMOVE_DEVICE:
-
- ntStatus = HandleRemoveDevice(DeviceObject, Irp);
-
- return ntStatus;
-
- case IRP_MN_QUERY_CAPABILITIES:
-
- ntStatus = HandleQueryCapabilities(DeviceObject, Irp);
-
- break;
-
- default:
-
- IoSkipCurrentIrpStackLocation(Irp);
-
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- dprintf(("VBoxUSB_DispatchPnP::default::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- return ntStatus;
-
- } // switch
-
-//
-// complete request
-//
-
- Irp->IoStatus.Status = ntStatus;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-//
-// decrement count
-//
- dprintf(("VBoxUSB_DispatchPnP::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- return ntStatus;
-}
-
-NTSTATUS
-HandleStartDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This is the dispatch routine for IRP_MN_START_DEVICE
-
-Arguments:
-
- DeviceObject - pointer to a device object.
-
- Irp - I/O request packet
-
-Return Value:
-
- NT status value
-
---*/
-{
- KIRQL oldIrql;
- KEVENT startDeviceEvent;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
- LARGE_INTEGER dueTime;
-
- dprintf(("HandleStartDevice - begins\n"));
-
- //
- // initialize variables
- //
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- deviceExtension->UsbConfigurationDescriptor = NULL;
- deviceExtension->UsbInterface = NULL;
- deviceExtension->PipeContext = NULL;
-
- //
- // We cannot touch the device (send it any non pnp irps) until a
- // start device has been passed down to the lower drivers.
- // first pass the Irp down
- //
-
- KeInitializeEvent(&startDeviceEvent, NotificationEvent, FALSE);
-
- IoCopyCurrentIrpStackLocationToNext(Irp);
-
- IoSetCompletionRoutine(Irp,
- (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine,
- (PVOID)&startDeviceEvent,
- TRUE,
- TRUE,
- TRUE);
-
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- if(ntStatus == STATUS_PENDING) {
-
- KeWaitForSingleObject(&startDeviceEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- ntStatus = Irp->IoStatus.Status;
- }
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("Lower drivers failed this Irp\n"));
- return ntStatus;
- }
-
-#if 0
- //
- // Read the device descriptor, configuration descriptor
- // and select the interface descriptors
- //
-
- ntStatus = ReadandSelectDescriptors(DeviceObject);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("ReadandSelectDescriptors failed\n"));
- return ntStatus;
- }
-#endif
-
- //
- // enable the symbolic links for system components to open
- // handles to the device
- //
-
- ntStatus = IoSetDeviceInterfaceState(&deviceExtension->InterfaceName,
- TRUE);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("IoSetDeviceInterfaceState:enable:failed\n"));
- return ntStatus;
- }
-
- KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
-
- SET_NEW_PNP_STATE(deviceExtension, Working);
- deviceExtension->QueueState = AllowRequests;
-
- KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
-
- //
- // initialize wait wake outstanding flag to false.
- // and issue a wait wake.
-
- deviceExtension->FlagWWOutstanding = 0;
- deviceExtension->FlagWWCancel = 0;
- deviceExtension->WaitWakeIrp = NULL;
-
- if(deviceExtension->WaitWakeEnable) {
-
- IssueWaitWake(deviceExtension);
- }
-
- ProcessQueuedRequests(deviceExtension);
-
-
- if(WinXpOrBetter == deviceExtension->WdmVersion) {
-
-
- deviceExtension->SSEnable = deviceExtension->SSRegistryEnable;
-
- //
- // set timer.for selective suspend requests
- //
-
- if(deviceExtension->SSEnable) {
-
- dueTime.QuadPart = -10000 * IDLE_INTERVAL; // 5000 ms
-
- KeSetTimerEx(&deviceExtension->Timer,
- dueTime,
- IDLE_INTERVAL, // 5000 ms
- &deviceExtension->DeferredProcCall);
-
- deviceExtension->FreeIdleIrpCount = 0;
- }
- }
-
- dprintf(("HandleStartDevice - ends\n"));
-
- return ntStatus;
-}
-
-
-NTSTATUS
-ReadandSelectDescriptors(
- IN PDEVICE_OBJECT DeviceObject
- )
-/*++
-
-Routine Description:
-
- This routine configures the USB device.
- In this routines we get the device descriptor,
- the configuration descriptor and select the
- configuration descriptor.
-
-Arguments:
-
- DeviceObject - pointer to a device object
-
-Return Value:
-
- NTSTATUS - NT status value.
-
---*/
-{
- PURB urb;
- ULONG siz;
- NTSTATUS ntStatus;
- PUSB_DEVICE_DESCRIPTOR deviceDescriptor;
-
- //
- // initialize variables
- //
-
- urb = NULL;
- deviceDescriptor = NULL;
-
- //
- // 1. Read the device descriptor
- //
-
- urb = (PURB)ExAllocatePool(NonPagedPool,
- sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
-
- if(urb) {
-
- memset(urb, 0, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
-
- siz = sizeof(USB_DEVICE_DESCRIPTOR);
- deviceDescriptor = (PUSB_DEVICE_DESCRIPTOR)ExAllocatePool(NonPagedPool, siz);
-
- if(deviceDescriptor) {
-
- UsbBuildGetDescriptorRequest(
- urb,
- (USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
- USB_DEVICE_DESCRIPTOR_TYPE,
- 0,
- 0,
- deviceDescriptor,
- NULL,
- siz,
- NULL);
-
- ntStatus = CallUSBD(DeviceObject, urb);
-
- if(NT_SUCCESS(ntStatus)) {
-
- ASSERT(deviceDescriptor->bNumConfigurations);
- ntStatus = ConfigureDevice(DeviceObject);
- }
-
- ExFreePool(urb);
- ExFreePool(deviceDescriptor);
- }
- else {
-
- dprintf(("Failed to allocate memory for deviceDescriptor\n"));
-
- ExFreePool(urb);
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
- }
- else {
-
- dprintf(("Failed to allocate memory for urb\n"));
-
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- return ntStatus;
-}
-
-NTSTATUS
-ConfigureDevice(
- IN PDEVICE_OBJECT DeviceObject
- )
-/*++
-
-Routine Description:
-
- This helper routine reads the configuration descriptor
- for the device in couple of steps.
-
-Arguments:
-
- DeviceObject - pointer to a device object
-
-Return Value:
-
- NTSTATUS - NT status value
-
---*/
-{
- PURB urb;
- ULONG siz;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
- PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor;
-
- //
- // initialize the variables
- //
-
- urb = NULL;
- configurationDescriptor = NULL;
- deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // Read the first configuration descriptor
- // This requires two steps:
- // 1. Read the fixed sized configuration descriptor (CD)
- // 2. Read the CD with all embedded interface and endpoint descriptors
- //
-
- urb = (PURB)ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
- if(urb) {
-
- memset(urb, 0, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
- siz = sizeof(USB_CONFIGURATION_DESCRIPTOR);
- configurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)ExAllocatePool(NonPagedPool, siz);
-
- if(configurationDescriptor) {
-
- UsbBuildGetDescriptorRequest(
- urb,
- (USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
- USB_CONFIGURATION_DESCRIPTOR_TYPE,
- 0,
- 0,
- configurationDescriptor,
- NULL,
- sizeof(USB_CONFIGURATION_DESCRIPTOR),
- NULL);
-
- ntStatus = CallUSBD(DeviceObject, urb);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("UsbBuildGetDescriptorRequest failed\n"));
- goto ConfigureDevice_Exit;
- }
- }
- else {
-
- dprintf(("Failed to allocate mem for config Descriptor\n"));
-
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- goto ConfigureDevice_Exit;
- }
-
- siz = configurationDescriptor->wTotalLength;
-
- ExFreePool(configurationDescriptor);
-
- configurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)ExAllocatePool(NonPagedPool, siz);
-
- if(configurationDescriptor) {
- memset(configurationDescriptor, 0, siz);
-
- UsbBuildGetDescriptorRequest(
- urb,
- (USHORT)sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
- USB_CONFIGURATION_DESCRIPTOR_TYPE,
- 0,
- 0,
- configurationDescriptor,
- NULL,
- siz,
- NULL);
-
- ntStatus = CallUSBD(DeviceObject, urb);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("Failed to read configuration descriptor\n"));
- goto ConfigureDevice_Exit;
- }
- }
- else {
-
- dprintf(("Failed to alloc mem for config Descriptor\n"));
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- goto ConfigureDevice_Exit;
- }
- }
- else {
-
- dprintf(("Failed to allocate memory for urb\n"));
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- goto ConfigureDevice_Exit;
- }
-
- if(configurationDescriptor) {
-
- //
- // save a copy of configurationDescriptor in deviceExtension
- // remember to free it later.
- //
- deviceExtension->UsbConfigurationDescriptor = configurationDescriptor;
-
- if(configurationDescriptor->bmAttributes & REMOTE_WAKEUP_MASK)
- {
- //
- // this configuration supports remote wakeup
- //
- deviceExtension->WaitWakeEnable = 1;
- }
- else
- {
- deviceExtension->WaitWakeEnable = 0;
- }
-
- ntStatus = SelectInterfaces(DeviceObject, configurationDescriptor);
- }
- else {
-
- deviceExtension->UsbConfigurationDescriptor = NULL;
- }
-
-ConfigureDevice_Exit:
-
- if(urb) {
-
- ExFreePool(urb);
- }
-
- return ntStatus;
-}
-
-NTSTATUS
-SelectInterfaces(
- IN PDEVICE_OBJECT DeviceObject,
- IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
- )
-/*++
-
-Routine Description:
-
- This helper routine selects the configuration
-
-Arguments:
-
- DeviceObject - pointer to device object
- ConfigurationDescriptor - pointer to the configuration
- descriptor for the device
-
-Return Value:
-
- NT status value
-
---*/
-{
- LONG numberOfInterfaces,
- interfaceNumber,
- interfaceindex;
- ULONG i;
- PURB urb;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
- PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor;
- PUSBD_INTERFACE_LIST_ENTRY interfaceList,
- tmp;
- PUSBD_INTERFACE_INFORMATION Interface;
-
- //
- // initialize the variables
- //
-
- urb = NULL;
- Interface = NULL;
- interfaceDescriptor = NULL;
- deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
- numberOfInterfaces = ConfigurationDescriptor->bNumInterfaces;
- interfaceindex = interfaceNumber = 0;
-
- //
- // Parse the configuration descriptor for the interface;
- //
-
- tmp = interfaceList = (PUSBD_INTERFACE_LIST_ENTRY)
- ExAllocatePool(
- NonPagedPool,
- sizeof(USBD_INTERFACE_LIST_ENTRY) * (numberOfInterfaces + 1));
-
- if(!tmp) {
-
- dprintf(("Failed to allocate mem for interfaceList\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
-
- while(interfaceNumber < numberOfInterfaces) {
-
- interfaceDescriptor = USBD_ParseConfigurationDescriptorEx(
- ConfigurationDescriptor,
- ConfigurationDescriptor,
- interfaceindex,
- 0, -1, -1, -1);
-
- if(interfaceDescriptor) {
-
- interfaceList->InterfaceDescriptor = interfaceDescriptor;
- interfaceList->Interface = NULL;
- interfaceList++;
- interfaceNumber++;
- }
-
- interfaceindex++;
- }
-
- interfaceList->InterfaceDescriptor = NULL;
- interfaceList->Interface = NULL;
- urb = USBD_CreateConfigurationRequestEx(ConfigurationDescriptor, tmp);
-
- if(urb) {
-
- Interface = &urb->UrbSelectConfiguration.Interface;
-
- for(i=0; i<Interface->NumberOfPipes; i++) {
-
- //
- // perform pipe initialization here
- // set the transfer size and any pipe flags we use
- // USBD sets the rest of the Interface struct members
- //
-
- Interface->Pipes[i].MaximumTransferSize =
- USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
- }
-
- ntStatus = CallUSBD(DeviceObject, urb);
-
- if(NT_SUCCESS(ntStatus)) {
-
- //
- // save a copy of interface information in the device extension.
- //
- deviceExtension->UsbInterface = (PUSBD_INTERFACE_INFORMATION)ExAllocatePool(NonPagedPool, Interface->Length);
-
- if(deviceExtension->UsbInterface) {
-
- RtlCopyMemory(deviceExtension->UsbInterface,
- Interface,
- Interface->Length);
- }
- else {
-
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- dprintf(("memory alloc for UsbInterface failed\n"));
- }
-
- //
- // Dump the interface to the debugger
- //
-
- Interface = &urb->UrbSelectConfiguration.Interface;
-
- dprintf(("---------\n"));
- dprintf(("NumberOfPipes 0x%x\n",
- Interface->NumberOfPipes));
- dprintf(("Length 0x%x\n",
- Interface->Length));
- dprintf(("Alt Setting 0x%x\n",
- Interface->AlternateSetting));
- dprintf(("Interface Number 0x%x\n",
- Interface->InterfaceNumber));
- dprintf(("Class, subclass, protocol 0x%x 0x%x 0x%x\n",
- Interface->Class,
- Interface->SubClass,
- Interface->Protocol));
- //
- // Initialize the PipeContext
- // Dump the pipe info
- //
-
- if(Interface->NumberOfPipes) {
- deviceExtension->PipeContext = (PVBOXUSB_PIPE_CONTEXT)
- ExAllocatePool(NonPagedPool,
- Interface->NumberOfPipes *
- sizeof(VBOXUSB_PIPE_CONTEXT));
-
- if(deviceExtension->PipeContext) {
-
- for(i=0; i<Interface->NumberOfPipes; i++) {
-
- deviceExtension->PipeContext[i].PipeOpen = FALSE;
- }
- }
- else {
-
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- dprintf(("memory alloc for UsbInterface failed\n"));
- }
- }
-
- for(i=0; i<Interface->NumberOfPipes; i++) {
-
- dprintf(("---------\n"));
- dprintf(("PipeType 0x%x\n",
- Interface->Pipes[i].PipeType));
- dprintf(("EndpointAddress 0x%x\n",
- Interface->Pipes[i].EndpointAddress));
- dprintf(("MaxPacketSize 0x%x\n",
- Interface->Pipes[i].MaximumPacketSize));
- dprintf(("Interval 0x%x\n",
- Interface->Pipes[i].Interval));
- dprintf(("Handle 0x%x\n",
- Interface->Pipes[i].PipeHandle));
- dprintf(("MaximumTransferSize 0x%x\n",
- Interface->Pipes[i].MaximumTransferSize));
- }
-
- dprintf(("---------\n"));
- }
- else {
-
- dprintf(("Failed to select an interface\n"));
- }
- }
- else {
-
- dprintf(("USBD_CreateConfigurationRequestEx failed\n"));
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- if(tmp) {
-
- ExFreePool(tmp);
- }
-
- if(urb) {
-
- ExFreePool(urb);
- }
-
- return ntStatus;
-}
-
-
-NTSTATUS
-DeconfigureDevice(
- IN PDEVICE_OBJECT DeviceObject
- )
-/*++
-
-Routine Description:
-
- This routine is invoked when the device is removed or stopped.
- This routine de-configures the usb device.
-
-Arguments:
-
- DeviceObject - pointer to device object
-
-Return Value:
-
- NT status value
-
---*/
-{
- PURB urb;
- ULONG siz;
- NTSTATUS ntStatus;
-
- //
- // initialize variables
- //
-
- siz = sizeof(struct _URB_SELECT_CONFIGURATION);
- urb = (PURB)ExAllocatePool(NonPagedPool, siz);
- if(urb) {
-
- UsbBuildSelectConfigurationRequest(urb, (USHORT)siz, NULL);
-
- ntStatus = CallUSBD(DeviceObject, urb);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("Failed to deconfigure device\n"));
- }
-
- ExFreePool(urb);
- }
- else {
-
- dprintf(("Failed to allocate urb\n"));
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- return ntStatus;
-}
-
-NTSTATUS
-CallUSBD(
- IN PDEVICE_OBJECT DeviceObject,
- IN PURB Urb
- )
-/*++
-
-Routine Description:
-
- This routine synchronously submits an urb down the stack.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Urb - USB request block
-
-Return Value:
-
---*/
-{
- PIRP irp;
- KEVENT event;
- NTSTATUS ntStatus;
- IO_STATUS_BLOCK ioStatus;
- PIO_STACK_LOCATION nextStack;
- PDEVICE_EXTENSION deviceExtension;
-
- //
- // initialize the variables
- //
-
- irp = NULL;
- deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
-
- irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
- deviceExtension->TopOfStackDeviceObject,
- NULL,
- 0,
- NULL,
- 0,
- TRUE,
- &event,
- &ioStatus);
-
- if(!irp) {
-
- dprintf(("IoBuildDeviceIoControlRequest failed\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- nextStack = IoGetNextIrpStackLocation(irp);
- ASSERT(nextStack != NULL);
- nextStack->Parameters.Others.Argument1 = Urb;
-
- dprintf(("CallUSBD::"));
- VBoxUSB_IoIncrement(deviceExtension);
-
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
-
- if(ntStatus == STATUS_PENDING) {
-
- KeWaitForSingleObject(&event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- ntStatus = ioStatus.Status;
- }
-
- dprintf(("CallUSBD::"));
- VBoxUSB_IoDecrement(deviceExtension);
- return ntStatus;
-}
-
-NTSTATUS
-HandleQueryStopDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine services the Irps of minor type IRP_MN_QUERY_STOP_DEVICE
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the pnp manager.
-
-Return Value:
-
- NT status value
-
---*/
-{
- KIRQL oldIrql;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
-
- dprintf(("HandleQueryStopDevice - begins\n"));
-
- //
- // initialize variables
- //
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- //
- // If we can stop the device, we need to set the QueueState to
- // HoldRequests so further requests will be queued.
- //
-
- KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
-
- SET_NEW_PNP_STATE(deviceExtension, PendingStop);
- deviceExtension->QueueState = HoldRequests;
-
- KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
-
- //
- // wait for the existing ones to be finished.
- // first, decrement this operation
- //
-
- dprintf(("HandleQueryStopDevice::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- KeWaitForSingleObject(&deviceExtension->StopEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
-
- IoSkipCurrentIrpStackLocation(Irp);
-
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- dprintf(("HandleQueryStopDevice - ends\n"));
-
- return ntStatus;
-}
-
-NTSTATUS
-HandleCancelStopDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine services Irp of minor type IRP_MN_CANCEL_STOP_DEVICE
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the pnp manager.
-
-Return Value:
-
- NT value
-
---*/
-{
- KIRQL oldIrql;
- KEVENT event;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
-
- dprintf(("HandleCancelStopDevice - begins\n"));
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- //
- // Send this IRP down and wait for it to come back.
- // Set the QueueState flag to AllowRequests,
- // and process all the previously queued up IRPs.
- //
- // First check to see whether you have received cancel-stop
- // without first receiving a query-stop. This could happen if someone
- // above us fails a query-stop and passes down the subsequent
- // cancel-stop.
- //
-
- if(PendingStop == deviceExtension->DeviceState) {
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
-
- IoCopyCurrentIrpStackLocationToNext(Irp);
- IoSetCompletionRoutine(Irp,
- (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine,
- (PVOID)&event,
- TRUE,
- TRUE,
- TRUE);
-
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- if(ntStatus == STATUS_PENDING) {
-
- KeWaitForSingleObject(&event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- ntStatus = Irp->IoStatus.Status;
- }
-
- if(NT_SUCCESS(ntStatus)) {
-
- KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
-
- RESTORE_PREVIOUS_PNP_STATE(deviceExtension);
- deviceExtension->QueueState = AllowRequests;
- ASSERT(deviceExtension->DeviceState == Working);
-
- KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
-
- ProcessQueuedRequests(deviceExtension);
- }
-
- }
- else {
-
- // spurious Irp
- ntStatus = STATUS_SUCCESS;
- }
-
- dprintf(("HandleCancelStopDevice - ends\n"));
-
- return ntStatus;
-}
-
-NTSTATUS
-HandleStopDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine services Irp of minor type IRP_MN_STOP_DEVICE
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the pnp manager.
-
-Return Value:
-
- NT status value
-
---*/
-{
- KIRQL oldIrql;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
-
- dprintf(("HandleStopDevice - begins\n"));
-
- //
- // initialize variables
- //
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
-
- if(WinXpOrBetter == deviceExtension->WdmVersion) {
-
- if(deviceExtension->SSEnable) {
-
- //
- // Cancel the timer so that the DPCs are no longer fired.
- // Thus, we are making judicious usage of our resources.
- // we do not need DPCs because the device is stopping.
- // The timers are re-initialized while handling the start
- // device irp.
- //
-
- KeCancelTimer(&deviceExtension->Timer);
-
- //
- // after the device is stopped, it can be surprise removed.
- // we set this to 0, so that we do not attempt to cancel
- // the timer while handling surprise remove or remove irps.
- // when we get the start device request, this flag will be
- // reinitialized.
- //
- deviceExtension->SSEnable = 0;
-
- //
- // make sure that if a DPC was fired before we called cancel timer,
- // then the DPC and work-time have run to their completion
- //
- KeWaitForSingleObject(&deviceExtension->NoDpcWorkItemPendingEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- //
- // make sure that the selective suspend request has been completed.
- //
- KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- }
- }
-
- //
- // after the stop Irp is sent to the lower driver object,
- // the driver must not send any more Irps down that touch
- // the device until another Start has occurred.
- //
-
- if(deviceExtension->WaitWakeEnable) {
-
- CancelWaitWake(deviceExtension);
- }
-
- KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
-
- SET_NEW_PNP_STATE(deviceExtension, Stopped);
-
- KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
-
- //
- // This is the right place to actually give up all the resources used
- // This might include calls to IoDisconnectInterrupt, MmUnmapIoSpace,
- // etc.
- //
-
- ReleaseMemory(DeviceObject);
-
- ntStatus = DeconfigureDevice(DeviceObject);
-
- Irp->IoStatus.Status = ntStatus;
- Irp->IoStatus.Information = 0;
-
- IoSkipCurrentIrpStackLocation(Irp);
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- dprintf(("HandleStopDevice - ends\n"));
-
- return ntStatus;
-}
-
-NTSTATUS
-HandleQueryRemoveDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine services Irp of minor type IRP_MN_QUERY_REMOVE_DEVICE
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the pnp manager.
-
-Return Value:
-
- NT status value
-
---*/
-{
- KIRQL oldIrql;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
-
- dprintf(("HandleQueryRemoveDevice - begins\n"));
-
- //
- // initialize variables
- //
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- //
- // If we can allow removal of the device, we should set the QueueState
- // to HoldRequests so further requests will be queued. This is required
- // so that we can process queued up requests in cancel-remove just in
- // case somebody else in the stack fails the query-remove.
- //
-
- ntStatus = CanRemoveDevice(DeviceObject, Irp);
-
- KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
-
- deviceExtension->QueueState = HoldRequests;
- SET_NEW_PNP_STATE(deviceExtension, PendingRemove);
-
- KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
-
- dprintf(("HandleQueryRemoveDevice::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- //
- // wait for all the requests to be completed
- //
-
- KeWaitForSingleObject(&deviceExtension->StopEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
-
- IoSkipCurrentIrpStackLocation(Irp);
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- dprintf(("HandleQueryRemoveDevice - ends\n"));
-
- return ntStatus;
-}
-
-NTSTATUS
-HandleCancelRemoveDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine services Irp of minor type IRP_MN_CANCEL_REMOVE_DEVICE
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the pnp manager.
-
-Return Value:
-
- NT status value
-
---*/
-{
- KIRQL oldIrql;
- KEVENT event;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
-
- dprintf(("HandleCancelRemoveDevice - begins\n"));
-
- //
- // initialize variables
- //
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- //
- // We need to reset the QueueState flag to ProcessRequest,
- // since the device resume its normal activities.
- //
-
- //
- // First check to see whether you have received cancel-remove
- // without first receiving a query-remove. This could happen if
- // someone above us fails a query-remove and passes down the
- // subsequent cancel-remove.
- //
-
- if(PendingRemove == deviceExtension->DeviceState) {
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
-
- IoCopyCurrentIrpStackLocationToNext(Irp);
- IoSetCompletionRoutine(Irp,
- (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine,
- (PVOID)&event,
- TRUE,
- TRUE,
- TRUE);
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- if(ntStatus == STATUS_PENDING) {
-
- KeWaitForSingleObject(&event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- ntStatus = Irp->IoStatus.Status;
- }
-
- if(NT_SUCCESS(ntStatus)) {
-
- KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
-
- deviceExtension->QueueState = AllowRequests;
- RESTORE_PREVIOUS_PNP_STATE(deviceExtension);
-
- KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
- //
- // process the queued requests that arrive between
- // QUERY_REMOVE and CANCEL_REMOVE
- //
-
- ProcessQueuedRequests(deviceExtension);
-
- }
- }
- else {
-
- //
- // spurious cancel-remove
- //
- ntStatus = STATUS_SUCCESS;
- }
-
- dprintf(("HandleCancelRemoveDevice - ends\n"));
-
- return ntStatus;
-}
-
-NTSTATUS
-HandleSurpriseRemoval(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine services Irp of minor type IRP_MN_SURPRISE_REMOVAL
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the pnp manager.
-
-Return Value:
-
- NT status value
-
---*/
-{
- KIRQL oldIrql;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
-
- dprintf(("HandleSurpriseRemoval - begins\n"));
-
- //
- // initialize variables
- //
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- //
- // 1. fail pending requests
- // 2. return device and memory resources
- // 3. disable interfaces
- //
-
- if(deviceExtension->WaitWakeEnable) {
-
- CancelWaitWake(deviceExtension);
- }
-
-
- if(WinXpOrBetter == deviceExtension->WdmVersion) {
-
- if(deviceExtension->SSEnable) {
-
- //
- // Cancel the timer so that the DPCs are no longer fired.
- // we do not need DPCs because the device has been surprise
- // removed
- //
-
- KeCancelTimer(&deviceExtension->Timer);
-
- deviceExtension->SSEnable = 0;
-
- //
- // make sure that if a DPC was fired before we called cancel timer,
- // then the DPC and work-time have run to their completion
- //
- KeWaitForSingleObject(&deviceExtension->NoDpcWorkItemPendingEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- //
- // make sure that the selective suspend request has been completed.
- //
- KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- }
- }
-
- KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
-
- deviceExtension->QueueState = FailRequests;
- SET_NEW_PNP_STATE(deviceExtension, SurpriseRemoved);
-
- KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
-
- ProcessQueuedRequests(deviceExtension);
-
- ntStatus = IoSetDeviceInterfaceState(&deviceExtension->InterfaceName,
- FALSE);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("IoSetDeviceInterfaceState::disable:failed\n"));
- }
-
- RtlFreeUnicodeString(&deviceExtension->InterfaceName);
-
- VBoxUSB_AbortPipes(DeviceObject);
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
-
- IoSkipCurrentIrpStackLocation(Irp);
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- dprintf(("HandleSurpriseRemoval - ends\n"));
-
- return ntStatus;
-}
-
-NTSTATUS
-HandleRemoveDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine services Irp of minor type IRP_MN_REMOVE_DEVICE
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the pnp manager.
-
-Return Value:
-
- NT status value
-
---*/
-{
- KIRQL oldIrql;
- ULONG requestCount;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
-
- dprintf(("HandleRemoveDevice - begins\n"));
-
- //
- // initialize variables
- //
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- //
- // The Plug & Play system has dictated the removal of this device. We
- // have no choice but to detach and delete the device object.
- // (If we wanted to express an interest in preventing this removal,
- // we should have failed the query remove IRP).
- //
-
- if(SurpriseRemoved != deviceExtension->DeviceState) {
-
- //
- // we are here after QUERY_REMOVE
- //
-
- KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
-
- deviceExtension->QueueState = FailRequests;
-
- KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
-
- if(deviceExtension->WaitWakeEnable) {
-
- CancelWaitWake(deviceExtension);
- }
-
- if(WinXpOrBetter == deviceExtension->WdmVersion) {
-
- if(deviceExtension->SSEnable) {
-
- //
- // Cancel the timer so that the DPCs are no longer fired.
- // we do not need DPCs because the device has been removed
- //
- KeCancelTimer(&deviceExtension->Timer);
-
- deviceExtension->SSEnable = 0;
-
- //
- // make sure that if a DPC was fired before we called cancel timer,
- // then the DPC and work-time have run to their completion
- //
- KeWaitForSingleObject(&deviceExtension->NoDpcWorkItemPendingEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- //
- // make sure that the selective suspend request has been completed.
- //
- KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- }
- }
-
- ProcessQueuedRequests(deviceExtension);
-
- ntStatus = IoSetDeviceInterfaceState(&deviceExtension->InterfaceName,
- FALSE);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("IoSetDeviceInterfaceState::disable:failed\n"));
- }
-
- RtlFreeUnicodeString(&deviceExtension->InterfaceName);
-
- VBoxUSB_AbortPipes(DeviceObject);
- }
-
- KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
-
- SET_NEW_PNP_STATE(deviceExtension, Removed);
-
- KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
-
-#ifdef SUPPORT_WMI
- VBoxUSB_WmiDeRegistration(deviceExtension);
-#endif
- //
- // need 2 decrements
- //
-
- dprintf(("HandleRemoveDevice::"));
- requestCount = VBoxUSB_IoDecrement(deviceExtension);
-
- ASSERT(requestCount > 0);
-
- dprintf(("HandleRemoveDevice::"));
- requestCount = VBoxUSB_IoDecrement(deviceExtension);
-
- KeWaitForSingleObject(&deviceExtension->RemoveEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- ReleaseMemory(DeviceObject);
- //
- // We need to send the remove down the stack before we detach,
- // but we don't need to wait for the completion of this operation
- // (and to register a completion routine).
- //
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
-
- IoSkipCurrentIrpStackLocation(Irp);
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- //
- // Detach the FDO from the device stack
- //
- IoDetachDevice(deviceExtension->TopOfStackDeviceObject);
- IoDeleteDevice(DeviceObject);
-
- dprintf(("HandleRemoveDevice - ends\n"));
-
- return ntStatus;
-}
-
-NTSTATUS
-HandleQueryCapabilities(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine services Irp of minor type IRP_MN_QUERY_CAPABILITIES
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the pnp manager.
-
-Return Value:
-
- NT status value
-
---*/
-{
- ULONG i;
- KEVENT event;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
- PDEVICE_CAPABILITIES pdc;
- PIO_STACK_LOCATION irpStack;
-
- dprintf(("HandleQueryCapabilities - begins\n"));
-
- //
- // initialize variables
- //
-
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- pdc = irpStack->Parameters.DeviceCapabilities.Capabilities;
-
- //
- // We will provide here an example of an IRP that is processed
- // both on its way down and on its way up: there might be no need for
- // a function driver process this Irp (the bus driver will do that).
- // The driver will wait for the lower drivers (the bus driver among
- // them) to process this IRP, then it processes it again.
- //
-
- if(pdc->Version < 1 || pdc->Size < sizeof(DEVICE_CAPABILITIES)) {
-
- dprintf(("HandleQueryCapabilities::request failed\n"));
- ntStatus = STATUS_UNSUCCESSFUL;
- return ntStatus;
- }
-
- //
- // Add in the SurpriseRemovalOK bit before passing it down.
- //
- pdc->SurpriseRemovalOK = TRUE;
- Irp->IoStatus.Status = STATUS_SUCCESS;
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
-
- IoCopyCurrentIrpStackLocationToNext(Irp);
- IoSetCompletionRoutine(Irp,
- (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine,
- (PVOID)&event,
- TRUE,
- TRUE,
- TRUE);
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- if(ntStatus == STATUS_PENDING) {
-
- KeWaitForSingleObject(&event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- ntStatus = Irp->IoStatus.Status;
- }
-
- //
- // initialize PowerDownLevel to disabled
- //
-
- deviceExtension->PowerDownLevel = PowerDeviceUnspecified;
-
- if(NT_SUCCESS(ntStatus)) {
-
- deviceExtension->DeviceCapabilities = *pdc;
-
- for(i = PowerSystemSleeping1; i <= PowerSystemSleeping3; i++) {
-
- if(deviceExtension->DeviceCapabilities.DeviceState[i] <
- PowerDeviceD3) {
-
- deviceExtension->PowerDownLevel =
- deviceExtension->DeviceCapabilities.DeviceState[i];
- }
- }
-
- //
- // since its safe to surprise-remove this device, we shall
- // set the SurpriseRemoveOK flag to suppress any dialog to
- // user.
- //
-
- pdc->SurpriseRemovalOK = 1;
- }
-
- if(deviceExtension->PowerDownLevel == PowerDeviceUnspecified ||
- deviceExtension->PowerDownLevel <= PowerDeviceD0) {
-
- deviceExtension->PowerDownLevel = PowerDeviceD2;
- }
-
- dprintf(("HandleQueryCapabilities - ends\n"));
-
- return ntStatus;
-}
-
-
-VOID
-DpcRoutine(
- IN PKDPC Dpc,
- IN PVOID DeferredContext,
- IN PVOID SystemArgument1,
- IN PVOID SystemArgument2
- )
-/*++
-
-Routine Description:
-
- DPC routine triggered by the timer to check the idle state
- of the device and submit an idle request for the device.
-
-Arguments:
-
- DeferredContext - context for the dpc routine.
- DeviceObject in our case.
-
-Return Value:
-
- None
-
---*/
-{
- NTSTATUS ntStatus;
- PDEVICE_OBJECT deviceObject;
- PDEVICE_EXTENSION deviceExtension;
- PIO_WORKITEM item;
-
- dprintf(("DpcRoutine - begins\n"));
-
- deviceObject = (PDEVICE_OBJECT)DeferredContext;
- deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
-
- //
- // Clear this event since a DPC has been fired!
- //
- KeClearEvent(&deviceExtension->NoDpcWorkItemPendingEvent);
-
- if(CanDeviceSuspend(deviceExtension)) {
-
- dprintf(("Device is Idle\n"));
-
- item = IoAllocateWorkItem(deviceObject);
-
- if(item) {
-
- IoQueueWorkItem(item,
- IdleRequestWorkerRoutine,
- DelayedWorkQueue,
- item);
-
- ntStatus = STATUS_PENDING;
-
- }
- else {
-
- dprintf(("Cannot alloc memory for work item\n"));
-
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
-
- //
- // signal the NoDpcWorkItemPendingEvent.
- //
- KeSetEvent(&deviceExtension->NoDpcWorkItemPendingEvent,
- IO_NO_INCREMENT,
- FALSE);
- }
- }
- else {
-
- dprintf(("Idle event not signaled\n"));
-
- //
- // signal the NoDpcWorkItemPendingEvent.
- //
- KeSetEvent(&deviceExtension->NoDpcWorkItemPendingEvent,
- IO_NO_INCREMENT,
- FALSE);
- }
-
- dprintf(("DpcRoutine - ends\n"));
-}
-
-
-VOID
-IdleRequestWorkerRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PVOID Context
- )
-/*++
-
-Routine Description:
-
- This is the work item fired from the DPC.
- This workitem checks the idle state of the device
- and submits an idle request.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Context - context for the work item.
-
-Return Value:
-
- None
-
---*/
-{
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
- PIO_WORKITEM workItem;
-
- dprintf(("IdleRequestWorkerRoutine - begins\n"));
-
- //
- // initialize variables
- //
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- workItem = (PIO_WORKITEM) Context;
-
- if(CanDeviceSuspend(deviceExtension)) {
-
- dprintf(("Device is idle\n"));
-
- ntStatus = SubmitIdleRequestIrp(deviceExtension);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("SubmitIdleRequestIrp failed\n"));
- }
- }
- else {
-
- dprintf(("Device is not idle\n"));
- }
-
- IoFreeWorkItem(workItem);
-
- //
- // signal the NoDpcWorkItemPendingEvent.
- //
- KeSetEvent(&deviceExtension->NoDpcWorkItemPendingEvent,
- IO_NO_INCREMENT,
- FALSE);
-
- dprintf(("IdleRequestsWorkerRoutine - ends\n"));
-}
-
-
-VOID
-ProcessQueuedRequests(
- IN OUT PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- Remove and process the entries in the queue. If this routine is called
- when processing IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_CANCEL_REMOVE_DEVICE
- or IRP_MN_START_DEVICE, the requests are passed to the next lower driver.
- If the routine is called when IRP_MN_REMOVE_DEVICE is received, the IRPs
- are complete with STATUS_DELETE_PENDING
-
-Arguments:
-
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- None
-
---*/
-{
- KIRQL oldIrql;
- PIRP nextIrp,
- cancelledIrp;
- PVOID cancelRoutine;
- LIST_ENTRY cancelledIrpList;
- PLIST_ENTRY listEntry;
-
- dprintf(("ProcessQueuedRequests - begins\n"));
-
- //
- // initialize variables
- //
-
- cancelRoutine = NULL;
- InitializeListHead(&cancelledIrpList);
-
- //
- // 1. dequeue the entries in the queue
- // 2. reset the cancel routine
- // 3. process them
- // 3a. if the device is active, send them down
- // 3b. else complete with STATUS_DELETE_PENDING
- //
-
- while(1) {
-
- KeAcquireSpinLock(&DeviceExtension->QueueLock, &oldIrql);
-
- if(IsListEmpty(&DeviceExtension->NewRequestsQueue)) {
-
- KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql);
- break;
- }
-
- //
- // Remove a request from the queue
- //
-
- listEntry = RemoveHeadList(&DeviceExtension->NewRequestsQueue);
- nextIrp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry);
-
- //
- // set the cancel routine to NULL
- //
-
- cancelRoutine = IoSetCancelRoutine(nextIrp, NULL);
-
- //
- // check if its already cancelled
- //
-
- if(nextIrp->Cancel) {
- if(cancelRoutine) {
-
- //
- // the cancel routine for this IRP hasn't been called yet
- // so queue the IRP in the cancelledIrp list and complete
- // after releasing the lock
- //
-
- InsertTailList(&cancelledIrpList, listEntry);
- }
- else {
-
- //
- // the cancel routine has run
- // it must be waiting to hold the queue lock
- // so initialize the IRPs listEntry
- //
-
- InitializeListHead(listEntry);
- }
-
- KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql);
- }
- else {
-
- KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql);
-
- if(FailRequests == DeviceExtension->QueueState) {
-
- nextIrp->IoStatus.Information = 0;
- nextIrp->IoStatus.Status = STATUS_DELETE_PENDING;
- IoCompleteRequest(nextIrp, IO_NO_INCREMENT);
- }
- else {
-
- dprintf(("ProcessQueuedRequests::"));
- VBoxUSB_IoIncrement(DeviceExtension);
-
- IoSkipCurrentIrpStackLocation(nextIrp);
- IoCallDriver(DeviceExtension->TopOfStackDeviceObject, nextIrp);
-
- dprintf(("ProcessQueuedRequests::"));
- VBoxUSB_IoDecrement(DeviceExtension);
- }
- }
- } // while loop
-
- //
- // walk through the cancelledIrp list and cancel them
- //
-
- while(!IsListEmpty(&cancelledIrpList)) {
-
- PLIST_ENTRY cancelEntry = RemoveHeadList(&cancelledIrpList);
-
- cancelledIrp = CONTAINING_RECORD(cancelEntry, IRP, Tail.Overlay.ListEntry);
-
- cancelledIrp->IoStatus.Status = STATUS_CANCELLED;
- cancelledIrp->IoStatus.Information = 0;
-
- IoCompleteRequest(cancelledIrp, IO_NO_INCREMENT);
- }
-
- dprintf(("ProcessQueuedRequests - ends\n"));
-
- return;
-}
-
-NTSTATUS
-VBoxUSB_GetRegistryDword(
- IN PWCHAR RegPath,
- IN PWCHAR ValueName,
- IN OUT PULONG Value
- )
-/*++
-
-Routine Description:
-
- This routine reads the specified registry value.
-
-Arguments:
-
- RegPath - registry path
- ValueName - property to be fetched from the registry
- Value - corresponding value read from the registry.
-
-Return Value:
-
- NT status value
-
---*/
-{
- ULONG defaultData;
- WCHAR buffer[MAXIMUM_FILENAME_LENGTH];
- NTSTATUS ntStatus;
- UNICODE_STRING regPath;
- RTL_QUERY_REGISTRY_TABLE paramTable[2];
-
- dprintf(("VBoxUSB_GetRegistryDword - begins\n"));
-
- regPath.Length = 0;
- regPath.MaximumLength = MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR);
- regPath.Buffer = buffer;
-
- RtlZeroMemory(regPath.Buffer, regPath.MaximumLength);
- RtlMoveMemory(regPath.Buffer,
- RegPath,
- wcslen(RegPath) * sizeof(WCHAR));
-
- RtlZeroMemory(paramTable, sizeof(paramTable));
-
- paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
- paramTable[0].Name = ValueName;
- paramTable[0].EntryContext = Value;
- paramTable[0].DefaultType = REG_DWORD;
- paramTable[0].DefaultData = &defaultData;
- paramTable[0].DefaultLength = sizeof(ULONG);
-
- ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE |
- RTL_REGISTRY_OPTIONAL,
- regPath.Buffer,
- paramTable,
- NULL,
- NULL);
-
- if(NT_SUCCESS(ntStatus)) {
-
- dprintf(("success Value = %X\n", *Value));
- return STATUS_SUCCESS;
- }
- else {
-
- *Value = 0;
- return STATUS_UNSUCCESSFUL;
- }
-}
-
-
-NTSTATUS
-VBoxUSB_DispatchClean(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- Dispatch routine for IRP_MJ_CLEANUP
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the pnp manager
-
-Return Value:
-
- NT status value
-
---*/
-{
- PDEVICE_EXTENSION deviceExtension;
- KIRQL oldIrql;
- LIST_ENTRY cleanupList;
- PLIST_ENTRY thisEntry,
- nextEntry,
- listHead;
- PIRP pendingIrp;
- PIO_STACK_LOCATION pendingIrpStack,
- irpStack;
-
- //
- // initialize variables
- //
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- InitializeListHead(&cleanupList);
-
- dprintf(("VBoxUSB_DispatchClean::"));
- VBoxUSB_IoIncrement(deviceExtension);
-
- //
- // acquire queue lock
- //
- KeAcquireSpinLock(&deviceExtension->QueueLock, &oldIrql);
-
- //
- // remove all Irp's that belong to input Irp's fileobject
- //
-
- listHead = &deviceExtension->NewRequestsQueue;
-
- for(thisEntry = listHead->Flink, nextEntry = thisEntry->Flink;
- thisEntry != listHead;
- thisEntry = nextEntry, nextEntry = thisEntry->Flink) {
-
- pendingIrp = CONTAINING_RECORD(thisEntry, IRP, Tail.Overlay.ListEntry);
-
- pendingIrpStack = IoGetCurrentIrpStackLocation(pendingIrp);
-
- if(irpStack->FileObject == pendingIrpStack->FileObject) {
-
- RemoveEntryList(thisEntry);
-
- //
- // set the cancel routine to NULL
- //
- if(NULL == IoSetCancelRoutine(pendingIrp, NULL)) {
-
- InitializeListHead(thisEntry);
- }
- else {
-
- InsertTailList(&cleanupList, thisEntry);
- }
- }
- }
-
- //
- // Release the spin lock
- //
-
- KeReleaseSpinLock(&deviceExtension->QueueLock, oldIrql);
-
- //
- // walk thru the cleanup list and cancel all the Irps
- //
-
- while(!IsListEmpty(&cleanupList)) {
-
- //
- // complete the Irp
- //
- thisEntry = RemoveHeadList(&cleanupList);
-
- pendingIrp = CONTAINING_RECORD(thisEntry, IRP, Tail.Overlay.ListEntry);
-
- pendingIrp->IoStatus.Information = 0;
- pendingIrp->IoStatus.Status = STATUS_CANCELLED;
-
- IoCompleteRequest(pendingIrp, IO_NO_INCREMENT);
- }
-
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_SUCCESS;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- dprintf(("VBoxUSB_DispatchClean::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- return STATUS_SUCCESS;
-}
-
-
-BOOLEAN
-CanDeviceSuspend(
- IN PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- This is the routine where we check if the device
- can selectively suspend.
-
-Arguments:
-
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- TRUE - if the device can suspend
- FALSE - otherwise.
-
---*/
-{
- dprintf(("CanDeviceSuspend\n"));
-
- if((DeviceExtension->OpenHandleCount == 0) &&
- (DeviceExtension->OutStandingIO == 1)) {
-
- return TRUE;
- }
- else {
-
- return FALSE;
- }
-}
-
-NTSTATUS
-VBoxUSB_AbortPipes(
- IN PDEVICE_OBJECT DeviceObject
- )
-/*++
-
-Routine Description
-
- sends an abort pipe request for open pipes.
-
-Arguments:
-
- DeviceObject - pointer to device object
-
-Return Value:
-
- NT status value
-
---*/
-{
- PURB urb;
- ULONG i;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
- PVBOXUSB_PIPE_CONTEXT pipeContext;
- PUSBD_INTERFACE_INFORMATION interfaceInfo;
-
- //
- // initialize variables
- //
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- pipeContext = deviceExtension->PipeContext;
- interfaceInfo = deviceExtension->UsbInterface;
-
- dprintf(("VBoxUSB_AbortPipes - begins\n"));
-
- if(interfaceInfo == NULL || pipeContext == NULL) {
-
- return STATUS_SUCCESS;
- }
-
- for(i=0; i<interfaceInfo->NumberOfPipes; i++) {
-
- if(pipeContext[i].PipeOpen) {
-
- dprintf(("Aborting open pipe %d\n", i));
-
- urb = (PURB)ExAllocatePool(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
-
- if(urb) {
-
- urb->UrbHeader.Length = sizeof(struct _URB_PIPE_REQUEST);
- urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
- urb->UrbPipeRequest.PipeHandle =
- interfaceInfo->Pipes[i].PipeHandle;
-
- ntStatus = CallUSBD(DeviceObject, urb);
-
- ExFreePool(urb);
- }
- else {
-
- dprintf(("Failed to alloc memory for urb\n"));
-
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- return ntStatus;
- }
-
- if(NT_SUCCESS(ntStatus)) {
-
- pipeContext[i].PipeOpen = FALSE;
- }
- }
- }
-
- dprintf(("VBoxUSB_AbortPipes - ends\n"));
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-IrpCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-/*++
-
-Routine Description:
-
- This routine is a completion routine.
- In this routine we set an event.
-
- Since the completion routine returns
- STATUS_MORE_PROCESSING_REQUIRED, the Irps,
- which set this routine as the completion routine,
- should be marked pending.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet
- Context -
-
-Return Value:
-
- NT status value
-
---*/
-{
- PKEVENT event = (PKEVENT)Context;
-
- KeSetEvent(event, 0, FALSE);
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-
-LONG
-VBoxUSB_IoIncrement(
- IN OUT PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- This routine bumps up the I/O count.
- This routine is typically invoked when any of the
- dispatch routines handle new irps for the driver.
-
-Arguments:
-
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- new value
-
---*/
-{
- LONG result = 0;
- KIRQL oldIrql;
-
- KeAcquireSpinLock(&DeviceExtension->IOCountLock, &oldIrql);
-
- result = InterlockedIncrement((volatile LONG *)&DeviceExtension->OutStandingIO);
-
- //
- // when OutStandingIO bumps from 1 to 2, clear the StopEvent
- //
-
- if(result == 2) {
-
- KeClearEvent(&DeviceExtension->StopEvent);
- }
-
- KeReleaseSpinLock(&DeviceExtension->IOCountLock, oldIrql);
-
- dprintf(("VBoxUSB_IoIncrement::%d\n", result));
-
- return result;
-}
-
-LONG
-VBoxUSB_IoDecrement(
- IN OUT PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- This routine decrements the outstanding I/O count
- This is typically invoked after the dispatch routine
- has finished processing the irp.
-
-Arguments:
-
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- new value
-
---*/
-{
- LONG result = 0;
- KIRQL oldIrql;
-
- KeAcquireSpinLock(&DeviceExtension->IOCountLock, &oldIrql);
-
- result = InterlockedDecrement((volatile LONG *)&DeviceExtension->OutStandingIO);
-
- if(result == 1) {
-
- KeSetEvent(&DeviceExtension->StopEvent, IO_NO_INCREMENT, FALSE);
- }
-
- if(result == 0) {
-
- ASSERT(Removed == DeviceExtension->DeviceState);
-
- KeSetEvent(&DeviceExtension->RemoveEvent, IO_NO_INCREMENT, FALSE);
- }
-
- KeReleaseSpinLock(&DeviceExtension->IOCountLock, oldIrql);
-
- dprintf(("VBoxUSB_IoDecrement::%d\n", result));
-
- return result;
-}
-
-NTSTATUS
-CanStopDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine determines whether the device can be safely stopped. In our
- particular case, we'll assume we can always stop the device.
- A device might fail the request if it doesn't have a queue for the
- requests it might come or if it was notified that it is in the paging
- path.
-
-Arguments:
-
- DeviceObject - pointer to the device object.
-
- Irp - pointer to the current IRP.
-
-Return Value:
-
- STATUS_SUCCESS if the device can be safely stopped, an appropriate
- NT Status if not.
-
---*/
-{
- //
- // We assume we can stop the device
- //
-
- UNREFERENCED_PARAMETER(DeviceObject);
- UNREFERENCED_PARAMETER(Irp);
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-CanRemoveDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine determines whether the device can be safely removed. In our
- particular case, we'll assume we can always remove the device.
- A device shouldn't be removed if, for example, it has open handles or
- removing the device could result in losing data (plus the reasons
- mentioned at CanStopDevice). The PnP manager on Windows 2000 fails
- on its own any attempt to remove, if there any open handles to the device.
- However on Win9x, the driver must keep count of open handles and fail
- query_remove if there are any open handles.
-
-Arguments:
-
- DeviceObject - pointer to the device object.
-
- Irp - pointer to the current IRP.
-
-Return Value:
-
- STATUS_SUCCESS if the device can be safely removed, an appropriate
- NT Status if not.
-
---*/
-{
- //
- // We assume we can remove the device
- //
-
- UNREFERENCED_PARAMETER(DeviceObject);
- UNREFERENCED_PARAMETER(Irp);
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-ReleaseMemory(
- IN PDEVICE_OBJECT DeviceObject
- )
-/*++
-
-Routine Description:
-
- This routine returns all the memory allocations acquired during
- device startup.
-
-Arguments:
-
- DeviceObject - pointer to the device object.
-
-
-Return Value:
-
- STATUS_SUCCESS if the device can be safely removed, an appropriate
- NT Status if not.
-
---*/
-{
- //
- // Disconnect from the interrupt and unmap any I/O ports
- //
-
- PDEVICE_EXTENSION deviceExtension;
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- if(deviceExtension->UsbConfigurationDescriptor) {
-
- ExFreePool(deviceExtension->UsbConfigurationDescriptor);
- deviceExtension->UsbConfigurationDescriptor = NULL;
- }
-
- if(deviceExtension->UsbInterface) {
-
- ExFreePool(deviceExtension->UsbInterface);
- deviceExtension->UsbInterface = NULL;
- }
-
- if(deviceExtension->PipeContext) {
-
- ExFreePool(deviceExtension->PipeContext);
- deviceExtension->PipeContext = NULL;
- }
-
- VBoxUSB_FreeMemory(deviceExtension);
-
- return STATUS_SUCCESS;
-}
-
-PCHAR
-PnPMinorFunctionString (
- UCHAR MinorFunction
- )
-/*++
-
-Routine Description:
-
-Arguments:
-
-Return Value:
-
---*/
-{
- switch (MinorFunction) {
-
- case IRP_MN_START_DEVICE:
- return "IRP_MN_START_DEVICE\n";
-
- case IRP_MN_QUERY_REMOVE_DEVICE:
- return "IRP_MN_QUERY_REMOVE_DEVICE\n";
-
- case IRP_MN_REMOVE_DEVICE:
- return "IRP_MN_REMOVE_DEVICE\n";
-
- case IRP_MN_CANCEL_REMOVE_DEVICE:
- return "IRP_MN_CANCEL_REMOVE_DEVICE\n";
-
- case IRP_MN_STOP_DEVICE:
- return "IRP_MN_STOP_DEVICE\n";
-
- case IRP_MN_QUERY_STOP_DEVICE:
- return "IRP_MN_QUERY_STOP_DEVICE\n";
-
- case IRP_MN_CANCEL_STOP_DEVICE:
- return "IRP_MN_CANCEL_STOP_DEVICE\n";
-
- case IRP_MN_QUERY_DEVICE_RELATIONS:
- return "IRP_MN_QUERY_DEVICE_RELATIONS\n";
-
- case IRP_MN_QUERY_INTERFACE:
- return "IRP_MN_QUERY_INTERFACE\n";
-
- case IRP_MN_QUERY_CAPABILITIES:
- return "IRP_MN_QUERY_CAPABILITIES\n";
-
- case IRP_MN_QUERY_RESOURCES:
- return "IRP_MN_QUERY_RESOURCES\n";
-
- case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
- return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n";
-
- case IRP_MN_QUERY_DEVICE_TEXT:
- return "IRP_MN_QUERY_DEVICE_TEXT\n";
-
- case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
- return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n";
-
- case IRP_MN_READ_CONFIG:
- return "IRP_MN_READ_CONFIG\n";
-
- case IRP_MN_WRITE_CONFIG:
- return "IRP_MN_WRITE_CONFIG\n";
-
- case IRP_MN_EJECT:
- return "IRP_MN_EJECT\n";
-
- case IRP_MN_SET_LOCK:
- return "IRP_MN_SET_LOCK\n";
-
- case IRP_MN_QUERY_ID:
- return "IRP_MN_QUERY_ID\n";
-
- case IRP_MN_QUERY_PNP_DEVICE_STATE:
- return "IRP_MN_QUERY_PNP_DEVICE_STATE\n";
-
- case IRP_MN_QUERY_BUS_INFORMATION:
- return "IRP_MN_QUERY_BUS_INFORMATION\n";
-
- case IRP_MN_DEVICE_USAGE_NOTIFICATION:
- return "IRP_MN_DEVICE_USAGE_NOTIFICATION\n";
-
- case IRP_MN_SURPRISE_REMOVAL:
- return "IRP_MN_SURPRISE_REMOVAL\n";
-
- default:
- return "IRP_MN_?????\n";
- }
-}
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpnp.h b/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpnp.h
deleted file mode 100644
index 6156bbaaf..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpnp.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*++
-
-Copyright (c) 2000 Microsoft Corporation
-
-Module Name:
-
- vboxpnp.h
-
-Abstract:
-
-Environment:
-
- Kernel mode
-
-Notes:
-
- Copyright (c) 2000 Microsoft Corporation.
- All Rights Reserved.
-
---*/
-
-#ifndef _VBoxUSB_PNP_H
-#define _VBoxUSB_PNP_H
-
-#define REMOTE_WAKEUP_MASK 0x20
-
-RT_C_DECLS_BEGIN
-
-NTSTATUS
-VBoxUSB_DispatchPnP(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-HandleStartDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-HandleQueryStopDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-HandleQueryRemoveDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-HandleCancelRemoveDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-HandleSurpriseRemoval(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-HandleRemoveDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-HandleCancelStopDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-HandleStopDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-HandleQueryCapabilities(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-ReadandSelectDescriptors(
- IN PDEVICE_OBJECT DeviceObject
- );
-
-NTSTATUS
-ConfigureDevice(
- IN PDEVICE_OBJECT DeviceObject
- );
-
-NTSTATUS
-SelectInterfaces(
- IN PDEVICE_OBJECT DeviceObject,
- IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
- );
-
-NTSTATUS
-DeconfigureDevice(
- IN PDEVICE_OBJECT DeviceObject
- );
-
-NTSTATUS
-CallUSBD(
- IN PDEVICE_OBJECT DeviceObject,
- IN PURB Urb
- );
-
-VOID
-ProcessQueuedRequests(
- IN OUT PDEVICE_EXTENSION DeviceExtension
- );
-
-NTSTATUS
-VBoxUSB_GetRegistryDword(
- IN PWCHAR RegPath,
- IN PWCHAR ValueName,
- IN OUT PULONG Value
- );
-
-NTSTATUS
-VBoxUSB_DispatchClean(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-VOID
-DpcRoutine(
- IN PKDPC Dpc,
- IN PVOID DeferredContext,
- IN PVOID SystemArgument1,
- IN PVOID SystemArgument2
- );
-
-VOID
-IdleRequestWorkerRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PVOID Context
- );
-
-NTSTATUS
-VBoxUSB_AbortPipes(
- IN PDEVICE_OBJECT DeviceObject
- );
-
-NTSTATUS
-IrpCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- );
-
-NTSTATUS
-CanStopDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-CanRemoveDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-ReleaseMemory(
- IN PDEVICE_OBJECT DeviceObject
- );
-
-LONG
-VBoxUSB_IoIncrement(
- IN OUT PDEVICE_EXTENSION DeviceExtension
- );
-
-LONG
-VBoxUSB_IoDecrement(
- IN OUT PDEVICE_EXTENSION DeviceExtension
- );
-
-BOOLEAN
-CanDeviceSuspend(
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-PCHAR
-PnPMinorFunctionString (
- IN UCHAR MinorFunction
- );
-
-RT_C_DECLS_END
-
-#endif
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpwr.cpp b/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpwr.cpp
deleted file mode 100644
index b2ed435a4..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpwr.cpp
+++ /dev/null
@@ -1,1645 +0,0 @@
-/*++
-
-Copyright (c) 2000 Microsoft Corporation
-
-Module Name:
-
- vboxpwr.c
-
-Abstract:
-
- The power management related processing.
-
- The Power Manager uses IRPs to direct drivers to change system
- and device power levels, to respond to system wake-up events,
- and to query drivers about their devices. All power IRPs have
- the major function code IRP_MJ_POWER.
-
- Most function and filter drivers perform some processing for
- each power IRP, then pass the IRP down to the next lower driver
- without completing it. Eventually the IRP reaches the bus driver,
- which physically changes the power state of the device and completes
- the IRP.
-
- When the IRP has been completed, the I/O Manager calls any
- IoCompletion routines set by drivers as the IRP traveled
- down the device stack. Whether a driver needs to set a completion
- routine depends upon the type of IRP and the driver's individual
- requirements.
-
- This code is not USB specific. It is essential for every WDM driver
- to handle power irps.
-
-Environment:
-
- Kernel mode
-
-Notes:
-
- Copyright (c) 2000 Microsoft Corporation.
- All Rights Reserved.
-
---*/
-
-#include "vboxusb.h"
-#include "vboxpwr.h"
-#include "vboxpnp.h"
-#include "vboxdev.h"
-#include <iprt/assert.h>
-
-NTSTATUS
-VBoxUSB_DispatchPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- The power dispatch routine.
-
-Arguments:
-
- DeviceObject - pointer to a device object.
-
- Irp - pointer to an I/O Request Packet.
-
-Return Value:
-
- NT status code
-
---*/
-{
- NTSTATUS ntStatus;
- PIO_STACK_LOCATION irpStack;
- PDEVICE_EXTENSION deviceExtension;
-
- //
- // initialize the variables
- //
-
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // We don't queue power Irps, we'll only check if the
- // device was removed, otherwise we'll take appropriate
- // action and send it to the next lower driver. In general
- // drivers should not cause long delays while handling power
- // IRPs. If a driver cannot handle a power IRP in a brief time,
- // it should return STATUS_PENDING and queue all incoming
- // IRPs until the IRP completes.
- //
-
- if(Removed == deviceExtension->DeviceState) {
-
- //
- // Even if a driver fails the IRP, it must nevertheless call
- // PoStartNextPowerIrp to inform the Power Manager that it
- // is ready to handle another power IRP.
- //
-
- PoStartNextPowerIrp(Irp);
-
- Irp->IoStatus.Status = ntStatus = STATUS_DELETE_PENDING;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return ntStatus;
- }
-
- if(NotStarted == deviceExtension->DeviceState) {
-
- //
- // if the device is not started yet, pass it down
- //
-
- PoStartNextPowerIrp(Irp);
-
- IoSkipCurrentIrpStackLocation(Irp);
-
- return PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
- }
-
- dprintf(("VBoxUSB_DispatchPower::"));
- VBoxUSB_IoIncrement(deviceExtension);
-
- switch(irpStack->MinorFunction) {
-
- case IRP_MN_SET_POWER:
-
- //
- // The Power Manager sends this IRP for one of the
- // following reasons:
- // 1) To notify drivers of a change to the system power state.
- // 2) To change the power state of a device for which
- // the Power Manager is performing idle detection.
- // A driver sends IRP_MN_SET_POWER to change the power
- // state of its device if it's a power policy owner for the
- // device.
- //
-
- IoMarkIrpPending(Irp);
-
- switch(irpStack->Parameters.Power.Type) {
-
- case SystemPowerState:
-
- HandleSystemSetPower(DeviceObject, Irp);
-
- ntStatus = STATUS_PENDING;
-
- break;
-
- case DevicePowerState:
-
- HandleDeviceSetPower(DeviceObject, Irp);
-
- ntStatus = STATUS_PENDING;
-
- break;
- }
-
- break;
-
- case IRP_MN_QUERY_POWER:
-
- //
- // The Power Manager sends a power IRP with the minor
- // IRP code IRP_MN_QUERY_POWER to determine whether it
- // can safely change to the specified system power state
- // (S1-S5) and to allow drivers to prepare for such a change.
- // If a driver can put its device in the requested state,
- // it sets status to STATUS_SUCCESS and passes the IRP down.
- //
-
- IoMarkIrpPending(Irp);
-
- switch(irpStack->Parameters.Power.Type) {
-
- case SystemPowerState:
-
- HandleSystemQueryPower(DeviceObject, Irp);
-
- ntStatus = STATUS_PENDING;
-
- break;
-
- case DevicePowerState:
-
- HandleDeviceQueryPower(DeviceObject, Irp);
-
- ntStatus = STATUS_PENDING;
-
- break;
- }
-
- break;
-
- case IRP_MN_WAIT_WAKE:
-
- //
- // The minor power IRP code IRP_MN_WAIT_WAKE provides
- // for waking a device or waking the system. Drivers
- // of devices that can wake themselves or the system
- // send IRP_MN_WAIT_WAKE. The system sends IRP_MN_WAIT_WAKE
- // only to devices that always wake the system, such as
- // the power-on switch.
- //
-
- IoMarkIrpPending(Irp);
-
- IoCopyCurrentIrpStackLocationToNext(Irp);
-
- IoSetCompletionRoutine(
- Irp,
- (PIO_COMPLETION_ROUTINE)WaitWakeCompletionRoutine,
- deviceExtension,
- TRUE,
- TRUE,
- TRUE);
-
- PoStartNextPowerIrp(Irp);
-
- ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("Lower drivers failed the wait-wake Irp\n"));
- }
-
- ntStatus = STATUS_PENDING;
-
- //
- // push back the count HERE and NOT in completion routine
- // a pending Wait Wake Irp should not impede stopping the device
- //
-
- dprintf(("IRP_MN_WAIT_WAKE::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- break;
-
- case IRP_MN_POWER_SEQUENCE:
-
- //
- // A driver sends this IRP as an optimization to determine
- // whether its device actually entered a specific power state.
- // This IRP is optional. Power Manager cannot send this IRP.
- //
-
- default:
-
- PoStartNextPowerIrp(Irp);
-
- IoSkipCurrentIrpStackLocation(Irp);
-
- ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("Lower drivers failed default power Irp\n"));
- }
-
- dprintf(("VBoxUSB_DispatchPower::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- break;
- }
-
- return ntStatus;
-}
-
-NTSTATUS
-HandleSystemQueryPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine handles the irp with minor function of type IRP_MN_QUERY_POWER
- for the system power states.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the power manager.
-
-Return Value:
-
- NT status value
-
---*/
-{
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
- SYSTEM_POWER_STATE systemState;
- PIO_STACK_LOCATION irpStack;
-
- dprintf(("HandleSystemQueryPower - begins\n"));
-
- //
- // initialize variables
- //
-
- deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- systemState = irpStack->Parameters.Power.State.SystemState;
-
- dprintf(("Query for system power state S%X\n"
- "Current system power state S%X\n",
- systemState - 1,
- deviceExtension->SysPower - 1));
-
- //
- // if querying for a lower S-state, issue a wait-wake
- //
-
- if((systemState > deviceExtension->SysPower) &&
- (deviceExtension->WaitWakeEnable)) {
-
- IssueWaitWake(deviceExtension);
- }
-
- IoCopyCurrentIrpStackLocationToNext(Irp);
-
- IoSetCompletionRoutine(
- Irp,
- (PIO_COMPLETION_ROUTINE)SysPoCompletionRoutine,
- deviceExtension,
- TRUE,
- TRUE,
- TRUE);
-
- ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- dprintf(("HandleSystemQueryPower - ends\n"));
-
- return STATUS_PENDING;
-}
-
-NTSTATUS
-HandleSystemSetPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine services irps of minor type IRP_MN_SET_POWER
- for the system power state
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the power manager
-
-Return Value:
-
- NT status value:
-
---*/
-{
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
- SYSTEM_POWER_STATE systemState;
- PIO_STACK_LOCATION irpStack;
-
- dprintf(("HandleSystemSetPower - begins\n"));
-
- //
- // initialize variables
- //
-
- deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- systemState = irpStack->Parameters.Power.State.SystemState;
-
- dprintf(("Set request for system power state S%X\n"
- "Current system power state S%X\n",
- systemState - 1,
- deviceExtension->SysPower - 1));
-
- IoCopyCurrentIrpStackLocationToNext(Irp);
-
- IoSetCompletionRoutine(
- Irp,
- (PIO_COMPLETION_ROUTINE)SysPoCompletionRoutine,
- deviceExtension,
- TRUE,
- TRUE,
- TRUE);
-
- ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- dprintf(("HandleSystemSetPower - ends\n"));
-
- return STATUS_PENDING;
-}
-
-NTSTATUS
-HandleDeviceQueryPower(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine services irps of minor type IRP_MN_QUERY_POWER
- for the device power state
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the power manager
-
-Return Value:
-
- NT status value
-
---*/
-{
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
- PIO_STACK_LOCATION irpStack;
- DEVICE_POWER_STATE deviceState;
-
- dprintf(("HandleDeviceQueryPower - begins\n"));
-
- //
- // initialize variables
- //
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- deviceState = irpStack->Parameters.Power.State.DeviceState;
-
- dprintf(("Query for device power state D%X\n"
- "Current device power state D%X\n",
- deviceState - 1,
- deviceExtension->DevPower - 1));
-
- if(deviceState < deviceExtension->DevPower) {
-
- ntStatus = STATUS_SUCCESS;
- }
- else {
-
- ntStatus = HoldIoRequests(DeviceObject, Irp);
-
- if(STATUS_PENDING == ntStatus) {
-
- return ntStatus;
- }
- }
-
- //
- // on error complete the Irp.
- // on success pass it to the lower layers
- //
-
- PoStartNextPowerIrp(Irp);
-
- Irp->IoStatus.Status = ntStatus;
- Irp->IoStatus.Information = 0;
-
- if(!NT_SUCCESS(ntStatus)) {
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- }
- else {
-
- IoSkipCurrentIrpStackLocation(Irp);
-
- ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
- }
-
- dprintf(("HandleDeviceQueryPower::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- dprintf(("HandleDeviceQueryPower - ends\n"));
-
- return ntStatus;
-}
-
-
-NTSTATUS
-SysPoCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- This is the completion routine for the system power irps of minor
- function types IRP_MN_QUERY_POWER and IRP_MN_SET_POWER.
- This completion routine sends the corresponding device power irp and
- returns STATUS_MORE_PROCESSING_REQUIRED. The system irp is passed as a
- context to the device power irp completion routine and is completed in
- the device power irp completion routine.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- NT status value
-
---*/
-{
- NTSTATUS ntStatus;
- PIO_STACK_LOCATION irpStack;
-
- //
- // initialize variables
- //
- ntStatus = Irp->IoStatus.Status;
- irpStack = IoGetCurrentIrpStackLocation(Irp);
-
-
- dprintf(("SysPoCompletionRoutine - begins\n"));
-
- //
- // lower drivers failed this Irp
- //
-
- if(!NT_SUCCESS(ntStatus)) {
-
- PoStartNextPowerIrp(Irp);
-
- dprintf(("SysPoCompletionRoutine::"));
- VBoxUSB_IoDecrement(DeviceExtension);
-
- return STATUS_SUCCESS;
- }
-
- //
- // ..otherwise update the cached system power state (IRP_MN_SET_POWER)
- //
-
- if(irpStack->MinorFunction == IRP_MN_SET_POWER) {
-
- DeviceExtension->SysPower = irpStack->Parameters.Power.State.SystemState;
- }
-
- //
- // queue device irp and return STATUS_MORE_PROCESSING_REQUIRED
- //
-
- SendDeviceIrp(DeviceObject, Irp);
-
- dprintf(("SysPoCompletionRoutine - ends\n"));
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-VOID
-SendDeviceIrp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP SIrp
- )
-/*++
-
-Routine Description:
-
- This routine is invoked from the completion routine of the system power
- irp. This routine will PoRequest a device power irp. The system irp is
- passed as a context to the device power irp.
-
-Arguments:
-
- DeviceObject - pointer to device object
- SIrp - system power irp.
-
-Return Value:
-
- None
-
---*/
-{
- NTSTATUS ntStatus;
- POWER_STATE powState;
- PDEVICE_EXTENSION deviceExtension;
- PIO_STACK_LOCATION irpStack;
- SYSTEM_POWER_STATE systemState;
- DEVICE_POWER_STATE devState;
- PPOWER_COMPLETION_CONTEXT powerContext;
-
- //
- // initialize variables
- //
-
- irpStack = IoGetCurrentIrpStackLocation(SIrp);
- systemState = irpStack->Parameters.Power.State.SystemState;
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- dprintf(("SendDeviceIrp - begins\n"));
-
- //
- // Read out the D-IRP out of the S->D mapping array captured in QueryCap's.
- // we can choose deeper sleep states than our mapping but never choose
- // lighter ones.
- //
-
- devState = deviceExtension->DeviceCapabilities.DeviceState[systemState];
- powState.DeviceState = devState;
-
- powerContext = (PPOWER_COMPLETION_CONTEXT)
- ExAllocatePool(NonPagedPool,
- sizeof(POWER_COMPLETION_CONTEXT));
-
- if(!powerContext) {
-
- dprintf(("Failed to alloc memory for powerContext\n"));
-
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
- else {
-
- powerContext->DeviceObject = DeviceObject;
- powerContext->SIrp = SIrp;
-
- //
- // in win2k PoRequestPowerIrp can take fdo or pdo.
- //
-
- ntStatus = PoRequestPowerIrp(
- deviceExtension->PhysicalDeviceObject,
- irpStack->MinorFunction,
- powState,
- (PREQUEST_POWER_COMPLETE)DevPoCompletionRoutine,
- powerContext,
- NULL);
- }
-
- if(!NT_SUCCESS(ntStatus)) {
-
- if(powerContext) {
-
- ExFreePool(powerContext);
- }
-
- PoStartNextPowerIrp(SIrp);
-
- SIrp->IoStatus.Status = ntStatus;
- SIrp->IoStatus.Information = 0;
-
- IoCompleteRequest(SIrp, IO_NO_INCREMENT);
-
- dprintf(("SendDeviceIrp::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- }
-
- dprintf(("SendDeviceIrp - ends\n"));
-}
-
-
-VOID
-DevPoCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR MinorFunction,
- IN POWER_STATE PowerState,
- IN PVOID Context,
- IN PIO_STATUS_BLOCK IoStatus
- )
-/*++
-
-Routine Description:
-
- This is the PoRequest - completion routine for the device power irp.
- This routine is responsible for completing the system power irp,
- received as a context.
-
-Arguments:
-
- DeviceObject - pointer to device object
- MinorFunction - minor function of the irp.
- PowerState - power state of the irp.
- Context - context passed to the completion routine.
- IoStatus - status of the device power irp.
-
-Return Value:
-
- None
-
---*/
-{
- PIRP sIrp;
- PDEVICE_EXTENSION deviceExtension;
- PPOWER_COMPLETION_CONTEXT powerContext;
-
- //
- // initialize variables
- //
-
- powerContext = (PPOWER_COMPLETION_CONTEXT) Context;
- sIrp = powerContext->SIrp;
- deviceExtension = (PDEVICE_EXTENSION)powerContext->DeviceObject->DeviceExtension;
-
- dprintf(("DevPoCompletionRoutine - begins\n"));
-
- //
- // copy the D-Irp status into S-Irp
- //
-
- sIrp->IoStatus.Status = IoStatus->Status;
-
- //
- // complete the system Irp
- //
-
- PoStartNextPowerIrp(sIrp);
-
- sIrp->IoStatus.Information = 0;
-
- IoCompleteRequest(sIrp, IO_NO_INCREMENT);
-
- //
- // cleanup
- //
-
- dprintf(("DevPoCompletionRoutine::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- ExFreePool(powerContext);
-
- dprintf(("DevPoCompletionRoutine - ends\n"));
-
-}
-
-NTSTATUS
-HandleDeviceSetPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine services irps of minor type IRP_MN_SET_POWER
- for the device power state
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet sent by the power manager
-
-Return Value:
-
- NT status value
-
---*/
-{
- KIRQL oldIrql;
- NTSTATUS ntStatus;
- POWER_STATE newState;
- PIO_STACK_LOCATION irpStack;
- PDEVICE_EXTENSION deviceExtension;
- DEVICE_POWER_STATE newDevState,
- oldDevState;
-
- dprintf(("HandleDeviceSetPower - begins\n"));
-
- //
- // initialize variables
- //
-
- deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- oldDevState = deviceExtension->DevPower;
- newState = irpStack->Parameters.Power.State;
- newDevState = newState.DeviceState;
-
- dprintf(("Set request for device power state D%X\n"
- "Current device power state D%X\n",
- newDevState - 1,
- deviceExtension->DevPower - 1));
-
- if(newDevState < oldDevState) {
-
- //
- // adding power
- //
- dprintf(("Adding power to the device\n"));
-
- //
- // send the power IRP to the next driver in the stack
- //
- IoCopyCurrentIrpStackLocationToNext(Irp);
-
- IoSetCompletionRoutine(
- Irp,
- (PIO_COMPLETION_ROUTINE)FinishDevPoUpIrp,
- deviceExtension,
- TRUE,
- TRUE,
- TRUE);
-
- ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- }
- else {
-
- //
- // newDevState >= oldDevState
- //
- // hold I/O if transition from D0 -> DX (X = 1, 2, 3)
- // if transition from D1 or D2 to deeper sleep states,
- // I/O queue is already on hold.
- //
-
- if(PowerDeviceD0 == oldDevState && newDevState > oldDevState) {
-
- //
- // D0 -> DX transition
- //
-
- dprintf(("Removing power from the device\n"));
-
- ntStatus = HoldIoRequests(DeviceObject, Irp);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- PoStartNextPowerIrp(Irp);
-
- Irp->IoStatus.Status = ntStatus;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- dprintf(("HandleDeviceSetPower::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- return ntStatus;
- }
- else {
-
- goto HandleDeviceSetPower_Exit;
- }
-
- }
- else if(PowerDeviceD0 == oldDevState && PowerDeviceD0 == newDevState) {
-
- //
- // D0 -> D0
- // unblock the queue which may have been blocked processing
- // query irp
- //
-
- dprintf(("A SetD0 request\n"));
-
- KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
-
- deviceExtension->QueueState = AllowRequests;
-
- KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
-
- ProcessQueuedRequests(deviceExtension);
- }
-
- IoCopyCurrentIrpStackLocationToNext(Irp);
-
- IoSetCompletionRoutine(
- Irp,
- (PIO_COMPLETION_ROUTINE) FinishDevPoDnIrp,
- deviceExtension,
- TRUE,
- TRUE,
- TRUE);
-
- ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("Lower drivers failed a power Irp\n"));
- }
-
- }
-
-HandleDeviceSetPower_Exit:
-
- dprintf(("HandleDeviceSetPower - ends\n"));
-
- return STATUS_PENDING;
-}
-
-NTSTATUS
-FinishDevPoUpIrp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- completion routine for the device power UP irp with minor function
- IRP_MN_SET_POWER.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- NT status value
-
---*/
-{
- NTSTATUS ntStatus;
-
- //
- // initialize variables
- //
-
- ntStatus = Irp->IoStatus.Status;
-
- dprintf(("FinishDevPoUpIrp - begins\n"));
-
- if(Irp->PendingReturned) {
-
- IoMarkIrpPending(Irp);
- }
-
- if(!NT_SUCCESS(ntStatus)) {
-
- PoStartNextPowerIrp(Irp);
-
- dprintf(("FinishDevPoUpIrp::"));
- VBoxUSB_IoDecrement(DeviceExtension);
-
- return STATUS_SUCCESS;
- }
-
- SetDeviceFunctional(DeviceObject, Irp, DeviceExtension);
-
- dprintf(("FinishDevPoUpIrp - ends\n"));
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-NTSTATUS
-SetDeviceFunctional(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- This routine processes queue of pending irps.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- NT status value
-
---*/
-{
- KIRQL oldIrql;
- NTSTATUS ntStatus;
- POWER_STATE newState;
- PIO_STACK_LOCATION irpStack;
- DEVICE_POWER_STATE newDevState,
- oldDevState;
-
- //
- // initialize variables
- //
-
- ntStatus = Irp->IoStatus.Status;
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- newState = irpStack->Parameters.Power.State;
- newDevState = newState.DeviceState;
- oldDevState = DeviceExtension->DevPower;
-
- dprintf(("SetDeviceFunctional - begins\n"));
-
- //
- // update the cached state
- //
- DeviceExtension->DevPower = newDevState;
-
- //
- // restore appropriate amount of state to our h/w
- // this driver does not implement partial context
- // save/restore.
- //
-
- PoSetPowerState(DeviceObject, DevicePowerState, newState);
-
- if(PowerDeviceD0 == newDevState) {
-
- //
- // empty existing queue of all pending irps.
- //
-
- KeAcquireSpinLock(&DeviceExtension->DevStateLock, &oldIrql);
-
- DeviceExtension->QueueState = AllowRequests;
-
- KeReleaseSpinLock(&DeviceExtension->DevStateLock, oldIrql);
-
- ProcessQueuedRequests(DeviceExtension);
- }
-
- PoStartNextPowerIrp(Irp);
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- dprintf(("SetDeviceFunctional::"));
- VBoxUSB_IoDecrement(DeviceExtension);
-
- dprintf(("SetDeviceFunctional - ends\n"));
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-FinishDevPoDnIrp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- This routine is the completion routine for device power DOWN irp.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- NT status value
-
---*/
-{
- NTSTATUS ntStatus;
- POWER_STATE newState;
- PIO_STACK_LOCATION irpStack;
-
- //
- // initialize variables
- //
- ntStatus = Irp->IoStatus.Status;
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- newState = irpStack->Parameters.Power.State;
-
- dprintf(("FinishDevPoDnIrp - begins\n"));
-
- if(NT_SUCCESS(ntStatus) && irpStack->MinorFunction == IRP_MN_SET_POWER) {
-
- //
- // update the cache;
- //
-
- dprintf(("updating cache..\n"));
-
- DeviceExtension->DevPower = newState.DeviceState;
-
- PoSetPowerState(DeviceObject, DevicePowerState, newState);
- }
-
- PoStartNextPowerIrp(Irp);
-
- dprintf(("FinishDevPoDnIrp::"));
- VBoxUSB_IoDecrement(DeviceExtension);
-
- dprintf(("FinishDevPoDnIrp - ends\n"));
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-HoldIoRequests(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine is called on query or set power DOWN irp for the device.
- This routine queues a workitem.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet
-
-Return Value:
-
- NT status value
-
---*/
-{
- NTSTATUS ntStatus;
- PIO_WORKITEM item;
- PDEVICE_EXTENSION deviceExtension;
- PWORKER_THREAD_CONTEXT context;
-
- //
- // initialize variables
- //
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- dprintf(("HoldIoRequests - begins\n"));
-
- deviceExtension->QueueState = HoldRequests;
-
- context = (PWORKER_THREAD_CONTEXT)ExAllocatePool(NonPagedPool, sizeof(WORKER_THREAD_CONTEXT));
-
- if(context) {
-
- item = IoAllocateWorkItem(DeviceObject);
-
- context->Irp = Irp;
- context->DeviceObject = DeviceObject;
- context->WorkItem = item;
-
- if(item) {
-
- IoMarkIrpPending(Irp);
-
- IoQueueWorkItem(item, HoldIoRequestsWorkerRoutine,
- DelayedWorkQueue, context);
-
- ntStatus = STATUS_PENDING;
- }
- else {
-
- dprintf(("Failed to allocate memory for workitem\n"));
- ExFreePool(context);
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
- }
- else {
-
- dprintf(("Failed to alloc memory for worker thread context\n"));
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- dprintf(("HoldIoRequests - ends\n"));
-
- return ntStatus;
-}
-
-VOID
-HoldIoRequestsWorkerRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PVOID Context
- )
-/*++
-
-Routine Description:
-
- This routine waits for the I/O in progress to finish and then
- sends the device power irp (query/set) down the stack.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Context - context passed to the work-item.
-
-Return Value:
-
- None
-
---*/
-{
- PIRP irp;
- NTSTATUS ntStatus;
- PDEVICE_EXTENSION deviceExtension;
- PWORKER_THREAD_CONTEXT context;
-
- dprintf(("HoldIoRequestsWorkerRoutine - begins\n"));
-
- //
- // initialize variables
- //
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- context = (PWORKER_THREAD_CONTEXT) Context;
- irp = (PIRP) context->Irp;
-
-
- //
- // wait for I/O in progress to finish.
- // the stop event is signalled when the counter drops to 1.
- // invoke VBoxUSB_IoDecrement twice: once each for the S-Irp and D-Irp.
- //
- dprintf(("HoldIoRequestsWorkerRoutine::"));
- VBoxUSB_IoDecrement(deviceExtension);
- dprintf(("HoldIoRequestsWorkerRoutine::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- KeWaitForSingleObject(&deviceExtension->StopEvent, Executive,
- KernelMode, FALSE, NULL);
-
- //
- // Increment twice to restore the count
- //
- dprintf(("HoldIoRequestsWorkerRoutine::"));
- VBoxUSB_IoIncrement(deviceExtension);
- dprintf(("HoldIoRequestsWorkerRoutine::"));
- VBoxUSB_IoIncrement(deviceExtension);
-
- //
- // now send the Irp down
- //
-
- IoCopyCurrentIrpStackLocationToNext(irp);
-
- IoSetCompletionRoutine(irp, (PIO_COMPLETION_ROUTINE) FinishDevPoDnIrp,
- deviceExtension, TRUE, TRUE, TRUE);
-
- ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("Lower driver fail a power Irp\n"));
- }
-
- IoFreeWorkItem(context->WorkItem);
- ExFreePool((PVOID)context);
-
- dprintf(("HoldIoRequestsWorkerRoutine - ends\n"));
-
-}
-
-NTSTATUS
-QueueRequest(
- IN OUT PDEVICE_EXTENSION DeviceExtension,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- Queue the Irp in the device queue
-
-Arguments:
-
- DeviceExtension - pointer to device extension
- Irp - I/O request packet.
-
-Return Value:
-
- NT status value
-
---*/
-{
- KIRQL oldIrql;
- NTSTATUS ntStatus;
-
- //
- // initialize variables
- //
- ntStatus = STATUS_PENDING;
-
- dprintf(("QueueRequests - begins\n"));
-
- ASSERT(HoldRequests == DeviceExtension->QueueState);
-
- KeAcquireSpinLock(&DeviceExtension->QueueLock, &oldIrql);
-
- InsertTailList(&DeviceExtension->NewRequestsQueue,
- &Irp->Tail.Overlay.ListEntry);
-
- IoMarkIrpPending(Irp);
-
- //
- // Set the cancel routine
- //
-
- IoSetCancelRoutine(Irp, CancelQueued);
-
- KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql);
-
- dprintf(("QueueRequests - ends\n"));
-
- return ntStatus;
-}
-
-VOID
-CancelQueued(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine removes the irp from the queue and completes it with
- STATUS_CANCELLED
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet
-
-Return Value:
-
- None.
-
---*/
-{
- PDEVICE_EXTENSION deviceExtension;
- KIRQL oldIrql;
-
- //
- // initialize variables
- //
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- oldIrql = Irp->CancelIrql;
-
- dprintf(("CancelQueued - begins\n"));
-
- //
- // Release the cancel spin lock
- //
-
- IoReleaseCancelSpinLock(Irp->CancelIrql);
-
- //
- // Acquire the queue lock
- //
-
- KeAcquireSpinLockAtDpcLevel(&deviceExtension->QueueLock);
-
- //
- // Remove the cancelled Irp from queue and release the lock
- //
- RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
-
- KeReleaseSpinLock(&deviceExtension->QueueLock, oldIrql);
-
- //
- // complete with STATUS_CANCELLED
- //
-
- Irp->IoStatus.Status = STATUS_CANCELLED;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- dprintf(("CancelQueued - ends\n"));
-
- return;
-}
-
-NTSTATUS
-IssueWaitWake(
- IN PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- This routine will PoRequest a WAIT WAKE irp for the device
-
-Arguments:
-
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- NT status value.
-
---*/
-{
- POWER_STATE poState;
- NTSTATUS ntStatus;
-
- dprintf(("IssueWaitWake - begins\n"));
-
- if(InterlockedExchange(&DeviceExtension->FlagWWOutstanding, 1)) {
-
- return STATUS_DEVICE_BUSY;
- }
-
- InterlockedExchange(&DeviceExtension->FlagWWCancel, 0);
-
- //
- // lowest state from which this Irp will wake the system
- //
-
- poState.SystemState = DeviceExtension->DeviceCapabilities.SystemWake;
-
- ntStatus = PoRequestPowerIrp(DeviceExtension->PhysicalDeviceObject,
- IRP_MN_WAIT_WAKE,
- poState,
- (PREQUEST_POWER_COMPLETE) WaitWakeCallback,
- DeviceExtension,
- &DeviceExtension->WaitWakeIrp);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- InterlockedExchange(&DeviceExtension->FlagWWOutstanding, 0);
- }
-
- dprintf(("IssueWaitWake - ends\n"));
-
- return ntStatus;
-}
-
-VOID
-CancelWaitWake(
- IN PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- This routine cancels the Wait Wake request.
-
-Arguments:
-
- DeviceExtension - pointer to the device extension
-
-Return Value:
-
- None.
-
---*/
-{
- PIRP Irp;
-
- dprintf(("CancelWaitWake - begins\n"));
-
- Irp = (PIRP) InterlockedExchangePointer((PVOID *)&DeviceExtension->WaitWakeIrp,
- NULL);
-
- if(Irp) {
-
- IoCancelIrp(Irp);
-
- if(InterlockedExchange(&DeviceExtension->FlagWWCancel, 1)) {
-
- PoStartNextPowerIrp(Irp);
-
- Irp->IoStatus.Status = STATUS_CANCELLED;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- }
- }
-
- dprintf(("CancelWaitWake - ends\n"));
-}
-
-NTSTATUS
-WaitWakeCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PDEVICE_EXTENSION DeviceExtension
- )
-/*++
-
-Routine Description:
-
- This is the IoSet completion routine for the wait wake irp.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet
- DeviceExtension - pointer to device extension
-
-Return Value:
-
- NT status value
-
---*/
-{
- dprintf(("WaitWakeCompletionRoutine - begins\n"));
-
- if(Irp->PendingReturned) {
-
- IoMarkIrpPending(Irp);
- }
-
- //
- // Nullify the WaitWakeIrp pointer-the Irp is released
- // as part of the completion process. If it's already NULL,
- // avoid race with the CancelWaitWake routine.
- //
-
- if(InterlockedExchangePointer((PVOID *)&DeviceExtension->WaitWakeIrp, NULL)) {
-
- PoStartNextPowerIrp(Irp);
-
- return STATUS_SUCCESS;
- }
-
- //
- // CancelWaitWake has run.
- // If FlagWWCancel != 0, complete the Irp.
- // If FlagWWCancel == 0, CancelWaitWake completes it.
- //
- if(InterlockedExchange(&DeviceExtension->FlagWWCancel, 1)) {
-
- PoStartNextPowerIrp(Irp);
-
- return STATUS_CANCELLED;
- }
-
- dprintf(("WaitWakeCompletionRoutine - ends\n"));
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-VOID
-WaitWakeCallback(
- IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR MinorFunction,
- IN POWER_STATE PowerState,
- IN PVOID Context,
- IN PIO_STATUS_BLOCK IoStatus
- )
-/*++
-
-Routine Description:
-
- This is the PoRequest completion routine for the wait wake irp.
-
-Arguments:
-
- DeviceObject - pointer to device object
- MinorFunction - irp minor function
- PowerState - power state of the irp.
- Context - context passed to the completion routine.
- IoStatus - status block.
-
-Return Value:
-
- None
-
---*/
-{
- NTSTATUS ntStatus;
- POWER_STATE powerState;
- PDEVICE_EXTENSION deviceExtension;
-
- dprintf(("WaitWakeCallback - begins\n"));
-
- deviceExtension = (PDEVICE_EXTENSION) Context;
-
- InterlockedExchange(&deviceExtension->FlagWWOutstanding, 0);
-
- if(!NT_SUCCESS(IoStatus->Status)) {
-
- return;
- }
-
- //
- // wake up the device
- //
-
- if(deviceExtension->DevPower == PowerDeviceD0) {
-
- dprintf(("device already powered up...\n"));
-
- return;
- }
-
- dprintf(("WaitWakeCallback::"));
- VBoxUSB_IoIncrement(deviceExtension);
-
- powerState.DeviceState = PowerDeviceD0;
-
- ntStatus = PoRequestPowerIrp(deviceExtension->PhysicalDeviceObject,
- IRP_MN_SET_POWER,
- powerState,
- (PREQUEST_POWER_COMPLETE) WWIrpCompletionFunc,
- deviceExtension,
- NULL);
-
- if(deviceExtension->WaitWakeEnable) {
-
- IssueWaitWake(deviceExtension);
- }
-
- dprintf(("WaitWakeCallback - ends\n"));
-
- return;
-}
-
-
-PCHAR
-PowerMinorFunctionString (
- IN UCHAR MinorFunction
- )
-/*++
-
-Routine Description:
-
-Arguments:
-
-Return Value:
-
---*/
-{
- switch (MinorFunction) {
-
- case IRP_MN_SET_POWER:
- return "IRP_MN_SET_POWER\n";
-
- case IRP_MN_QUERY_POWER:
- return "IRP_MN_QUERY_POWER\n";
-
- case IRP_MN_POWER_SEQUENCE:
- return "IRP_MN_POWER_SEQUENCE\n";
-
- case IRP_MN_WAIT_WAKE:
- return "IRP_MN_WAIT_WAKE\n";
-
- default:
- return "IRP_MN_?????\n";
- }
-}
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpwr.h b/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpwr.h
deleted file mode 100644
index ab8b0f4cd..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxpwr.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*++
-
-Copyright (c) 2000 Microsoft Corporation
-
-Module Name:
-
- vboxpwr.h
-
-Abstract:
-
-Environment:
-
- Kernel mode
-
-Notes:
-
- Copyright (c) 2000 Microsoft Corporation.
- All Rights Reserved.
-
---*/
-
-#ifndef _VBoxUSB_POWER_H
-#define _VBoxUSB_POWER_H
-
-typedef struct _POWER_COMPLETION_CONTEXT {
- PDEVICE_OBJECT DeviceObject;
- PIRP SIrp;
-} POWER_COMPLETION_CONTEXT, *PPOWER_COMPLETION_CONTEXT;
-
-typedef struct _WORKER_THREAD_CONTEXT {
- PDEVICE_OBJECT DeviceObject;
- PIRP Irp;
- PIO_WORKITEM WorkItem;
-} WORKER_THREAD_CONTEXT, *PWORKER_THREAD_CONTEXT;
-
-RT_C_DECLS_BEGIN
-NTSTATUS
-VBoxUSB_DispatchPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-HandleSystemQueryPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-HandleSystemSetPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-HandleDeviceQueryPower(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp
- );
-
-NTSTATUS
-SysPoCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-VOID
-SendDeviceIrp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-VOID
-DevPoCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR MinorFunction,
- IN POWER_STATE PowerState,
- IN PVOID Context,
- IN PIO_STATUS_BLOCK IoStatus
- );
-
-NTSTATUS
-HandleDeviceSetPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-FinishDevPoUpIrp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-NTSTATUS
-SetDeviceFunctional(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-NTSTATUS
-FinishDevPoDnIrp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-NTSTATUS
-HoldIoRequests(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-VOID
-HoldIoRequestsWorkerRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PVOID Context
- );
-
-NTSTATUS
-QueueRequest(
- IN OUT PDEVICE_EXTENSION DeviceExtension,
- IN PIRP Irp
- );
-
-VOID
-CancelQueued(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-WaitWakeCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-NTSTATUS
-IssueWaitWake(
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-VOID
-CancelWaitWake(
- IN PDEVICE_EXTENSION DeviceExtension
- );
-
-VOID
-WaitWakeCallback(
- IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR MinorFunction,
- IN POWER_STATE PowerState,
- IN PVOID Context,
- IN PIO_STATUS_BLOCK IoStatus
- );
-
-PCHAR
-PowerMinorFunctionString (
- IN UCHAR MinorFunction
- );
-
-RT_C_DECLS_END
-
-#endif
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxrwr.cpp b/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxrwr.cpp
deleted file mode 100644
index 206d387eb..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxrwr.cpp
+++ /dev/null
@@ -1,309 +0,0 @@
-/*++
-
-Copyright (c) 2000 Microsoft Corporation
-
-Module Name:
-
- vboxrwr.cpp
-
-Abstract:
-
- This file has routines to perform reads and writes.
- The read and writes are for bulk transfers.
-
-Environment:
-
- Kernel mode
-
-Notes:
-
- Copyright (c) 2000 Microsoft Corporation.
- All Rights Reserved.
-
---*/
-
-#include "vboxusb.h"
-#include "vboxpnp.h"
-#include "vboxpwr.h"
-#include "vboxdev.h"
-#include "vboxrwr.h"
-#include <VBox/log.h>
-#include <iprt/assert.h>
-
-
-PVBOXUSB_PIPE_CONTEXT
-VBoxUSB_PipeWithName(
- IN PDEVICE_OBJECT DeviceObject,
- IN PUNICODE_STRING FileName
- )
-/*++
-
-Routine Description:
-
- This routine will pass the string pipe name and
- fetch the pipe number.
-
-Arguments:
-
- DeviceObject - pointer to DeviceObject
- FileName - string pipe name
-
-Return Value:
-
- The device extension maintains a pipe context for
- the pipes on 82930 board.
- This routine returns the pointer to this context in
- the device extension for the "FileName" pipe.
-
---*/
-{
- LONG ix;
- ULONG uval;
- ULONG nameLength;
- ULONG umultiplier;
- PDEVICE_EXTENSION deviceExtension;
- PVBOXUSB_PIPE_CONTEXT pipeContext;
-
- //
- // initialize variables
- //
- pipeContext = NULL;
- //
- // typedef WCHAR *PWSTR;
- //
- nameLength = (FileName->Length / sizeof(WCHAR));
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- dprintf(("VBoxUSB_PipeWithName - begins\n"));
-
- if(nameLength != 0) {
-
- dprintf(("Filename = %ws nameLength = %d\n", FileName->Buffer, nameLength));
-
- //
- // Parse the pipe#
- //
- ix = nameLength - 1;
-
- // if last char isn't digit, decrement it.
- while((ix > -1) &&
- ((FileName->Buffer[ix] < (WCHAR) '0') ||
- (FileName->Buffer[ix] > (WCHAR) '9'))) {
-
- ix--;
- }
-
- if(ix > -1) {
-
- uval = 0;
- umultiplier = 1;
-
- // traversing least to most significant digits.
-
- while((ix > -1) &&
- (FileName->Buffer[ix] >= (WCHAR) '0') &&
- (FileName->Buffer[ix] <= (WCHAR) '9')) {
-
- uval += (umultiplier *
- (ULONG) (FileName->Buffer[ix] - (WCHAR) '0'));
-
- ix--;
- umultiplier *= 10;
- }
-
- if(uval < 6 && deviceExtension->PipeContext) {
-
- pipeContext = &deviceExtension->PipeContext[uval];
- }
- }
- }
-
- dprintf(("VBoxUSB_PipeWithName - ends\n"));
-
- return pipeContext;
-}
-
-NTSTATUS
-VBoxUSB_DispatchReadWrite(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-{
- /* should never be here ! since all communication is performed via IOCTL */
- AssertFailed();
-
- NTSTATUS Status = STATUS_ACCESS_DENIED;
- PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- dprintf(("VBoxUSB_DispatchReadWrite - begins\n"));
-
- if(deviceExtension->DeviceState != Working) {
- dprintf(("Invalid device state\n"));
- Status = STATUS_INVALID_DEVICE_STATE;
- }
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
-}
-
-NTSTATUS
-VBoxUSB_ReadWriteCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-/*++
-
-Routine Description:
-
- This is the completion routine for reads/writes
- If the irp completes with success, we check if we
- need to recirculate this irp for another stage of
- transfer. In this case return STATUS_MORE_PROCESSING_REQUIRED.
- if the irp completes in error, free all memory allocs and
- return the status.
-
-Arguments:
-
- DeviceObject - pointer to device object
- Irp - I/O request packet
- Context - context passed to the completion routine.
-
-Return Value:
-
- NT status value
-
---*/
-{
- ULONG stageLength;
- NTSTATUS ntStatus;
- PIO_STACK_LOCATION nextStack;
- PVBOXUSB_RW_CONTEXT rwContext;
-
- //
- // initialize variables
- //
- rwContext = (PVBOXUSB_RW_CONTEXT) Context;
- ntStatus = Irp->IoStatus.Status;
-
- UNREFERENCED_PARAMETER(DeviceObject);
- dprintf(("VBoxUSB_ReadWriteCompletion - begins\n"));
-
- //
- // successfully performed a stageLength of transfer.
- // check if we need to recirculate the irp.
- //
- if(NT_SUCCESS(ntStatus)) {
-
- if(rwContext) {
-
- rwContext->Numxfer +=
- rwContext->Urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
-
- if(rwContext->Length) {
-
- //
- // another stage transfer
- //
- dprintf(("Another stage transfer...\n"));
-
- if(rwContext->Length > VBOXUSB_MAX_TRANSFER_SIZE) {
-
- stageLength = VBOXUSB_MAX_TRANSFER_SIZE;
- }
- else {
-
- stageLength = rwContext->Length;
- }
-
- // the source MDL is not mapped and so when the lower driver
- // calls MmGetSystemAddressForMdl(Safe) on Urb->Mdl (target Mdl),
- // system PTEs are used.
- // IoFreeMdl calls MmPrepareMdlForReuse to release PTEs (unlock
- // VA address before freeing any Mdl
- // Rather than calling IoFreeMdl and IoAllocateMdl each time,
- // just call MmPrepareMdlForReuse
- // Not calling MmPrepareMdlForReuse will leak system PTEs
- //
- MmPrepareMdlForReuse(rwContext->Mdl);
-
- IoBuildPartialMdl(Irp->MdlAddress,
- rwContext->Mdl,
- (PVOID) rwContext->VirtualAddress,
- stageLength);
-
- //
- // reinitialize the urb
- //
- rwContext->Urb->UrbBulkOrInterruptTransfer.TransferBufferLength
- = stageLength;
- rwContext->VirtualAddress += stageLength;
- rwContext->Length -= stageLength;
-
- nextStack = IoGetNextIrpStackLocation(Irp);
- nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
- nextStack->Parameters.Others.Argument1 = rwContext->Urb;
- nextStack->Parameters.DeviceIoControl.IoControlCode =
- IOCTL_INTERNAL_USB_SUBMIT_URB;
-
- IoSetCompletionRoutine(Irp,
- VBoxUSB_ReadWriteCompletion,
- rwContext,
- TRUE,
- TRUE,
- TRUE);
-
- IoCallDriver(rwContext->DeviceExtension->TopOfStackDeviceObject,
- Irp);
-
- return STATUS_MORE_PROCESSING_REQUIRED;
- }
- else {
-
- //
- // this is the last transfer
- //
-
- Irp->IoStatus.Information = rwContext->Numxfer;
- }
- }
- }
- else {
-
- dprintf(("ReadWriteCompletion - failed with status = %X\n", ntStatus));
- }
-
- if(rwContext) {
-
- //
- // dump rwContext
- //
- dprintf(("rwContext->Urb = %X\n",
- rwContext->Urb));
- dprintf(("rwContext->Mdl = %X\n",
- rwContext->Mdl));
- dprintf(("rwContext->Length = %d\n",
- rwContext->Length));
- dprintf(("rwContext->Numxfer = %d\n",
- rwContext->Numxfer));
- dprintf(("rwContext->VirtualAddress = %X\n",
- rwContext->VirtualAddress));
- dprintf(("rwContext->DeviceExtension = %X\n",
- rwContext->DeviceExtension));
-
- dprintf(("VBoxUSB_ReadWriteCompletion::"));
- VBoxUSB_IoDecrement(rwContext->DeviceExtension);
-
- ExFreePool(rwContext->Urb);
- IoFreeMdl(rwContext->Mdl);
- ExFreePool(rwContext);
- }
-
- dprintf(("VBoxUSB_ReadWriteCompletion - ends\n"));
-
- return ntStatus;
-}
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxrwr.h b/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxrwr.h
deleted file mode 100644
index 14ca94d88..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxrwr.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*++
-
-Copyright (c) 2000 Microsoft Corporation
-
-Module Name:
-
- vboxrwr.h
-
-Abstract:
-
-Environment:
-
- Kernel mode
-
-Notes:
-
- Copyright (c) 2000 Microsoft Corporation.
- All Rights Reserved.
-
---*/
-#ifndef _VBoxUSB_RWR_H
-#define _VBoxUSB_RWR_H
-
-typedef struct _VBOXUSB_RW_CONTEXT {
-
- PURB Urb;
- PMDL Mdl;
- ULONG Length; // remaining to xfer
- ULONG Numxfer; // acumulated xfer
- ULONG_PTR VirtualAddress; // va for next segment of xfer.
- PDEVICE_EXTENSION DeviceExtension;
-
-} VBOXUSB_RW_CONTEXT, * PVBOXUSB_RW_CONTEXT;
-
-RT_C_DECLS_BEGIN
-
-PVBOXUSB_PIPE_CONTEXT
-VBoxUSB_PipeWithName(
- IN PDEVICE_OBJECT DeviceObject,
- IN PUNICODE_STRING FileName
- );
-
-NTSTATUS
-VBoxUSB_DispatchReadWrite(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-VBoxUSB_ReadWriteCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- );
-
-RT_C_DECLS_END
-
-#endif
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxusb.cpp b/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxusb.cpp
deleted file mode 100644
index 3f008d64e..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxusb.cpp
+++ /dev/null
@@ -1,582 +0,0 @@
-/*++
-
-Copyright (c) 2000 Microsoft Corporation
-
-Module Name:
-
- VBoxUSB.c
-
-Abstract:
-
- Bulk USB device driver for Intel 82930 USB test board
- Main module
-
-Author:
-
-Environment:
-
- kernel mode only
-
-Notes:
-
- Copyright (c) 2000 Microsoft Corporation.
- All Rights Reserved.
-
---*/
-
-#include "vboxusb.h"
-#include "vboxpnp.h"
-#include "vboxpwr.h"
-#include "vboxdev.h"
-#include "vboxrwr.h"
-#include <iprt/assert.h>
-
-//
-// Globals
-//
-
-GLOBALS Globals;
-ULONG DebugLevel = 3;
-
-/*******************************************************************************
-* Exported Functions *
-*******************************************************************************/
-RT_C_DECLS_BEGIN
-NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath);
-RT_C_DECLS_END
-
-VOID
-VBoxUSB_DriverUnload(
- IN PDRIVER_OBJECT DriverObject
- );
-
-NTSTATUS
-VBoxUSB_AddDevice(
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT PhysicalDeviceObject
- );
-
-NTSTATUS
-VBoxUSB_DispatchSysCtrl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-
-#ifdef DEBUG
-PCHAR
-WMIMinorFunctionString (
- UCHAR MinorFunction
- );
-#endif
-
-#ifdef PAGE_CODE
-#ifdef ALLOC_PRAGMA
-#pragma alloc_text(INIT, DriverEntry)
-#pragma alloc_text(PAGE, VBoxUSB_DriverUnload)
-#endif
-#endif
-
-
-NTSTATUS
-DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING UniRegistryPath
- )
-/*++
-
-Routine Description:
-
- Installable driver initialization entry point.
- This entry point is called directly by the I/O system.
-
-Arguments:
-
- DriverObject - pointer to driver object
-
- RegistryPath - pointer to a unicode string representing the path to driver
- specific key in the registry.
-
-Return Values:
-
- NT status value
-
---*/
-{
-
- NTSTATUS ntStatus;
- PUNICODE_STRING registryPath;
-
- dprintf(("VBoxUSB: DriverEntry (DriverObject=%p)\n", DriverObject));
-
- //
- // initialization of variables
- //
-
- registryPath = &Globals.VBoxUSB_RegistryPath;
-
- //
- // Allocate pool to hold a null-terminated copy of the path.
- // Safe in paged pool since all registry routines execute at
- // PASSIVE_LEVEL.
- //
-
- registryPath->MaximumLength = UniRegistryPath->Length + sizeof(UNICODE_NULL);
- registryPath->Length = UniRegistryPath->Length;
- registryPath->Buffer = (LPWSTR)ExAllocatePool(PagedPool, registryPath->MaximumLength);
-
- if (!registryPath->Buffer) {
-
- dprintf(("Failed to allocate memory for registryPath\n"));
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- goto DriverEntry_Exit;
- }
-
-
- RtlZeroMemory (registryPath->Buffer,
- registryPath->MaximumLength);
- RtlMoveMemory (registryPath->Buffer,
- UniRegistryPath->Buffer,
- UniRegistryPath->Length);
-
- ntStatus = STATUS_SUCCESS;
-
- //
- // Initialize the driver object with this driver's entry points.
- //
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxUSB_DispatchDevCtrl;
- DriverObject->MajorFunction[IRP_MJ_POWER] = VBoxUSB_DispatchPower;
- DriverObject->MajorFunction[IRP_MJ_PNP] = VBoxUSB_DispatchPnP;
- DriverObject->MajorFunction[IRP_MJ_CREATE] = VBoxUSB_DispatchCreate;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = VBoxUSB_DispatchClose;
- DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VBoxUSB_DispatchClean;
- DriverObject->MajorFunction[IRP_MJ_READ] =
- DriverObject->MajorFunction[IRP_MJ_WRITE] = VBoxUSB_DispatchReadWrite;
- DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = VBoxUSB_DispatchSysCtrl;
- DriverObject->DriverUnload = VBoxUSB_DriverUnload;
- DriverObject->DriverExtension->AddDevice = VBoxUSB_AddDevice;
-DriverEntry_Exit:
-
- return ntStatus;
-}
-
-VOID
-VBoxUSB_DriverUnload(
- IN PDRIVER_OBJECT DriverObject
- )
-/*++
-
-Description:
-
- This function will free the memory allocations in DriverEntry.
-
-Arguments:
-
- DriverObject - pointer to driver object
-
-Return:
-
- None
-
---*/
-{
- PUNICODE_STRING registryPath;
-
- dprintf(("vboxUsb_DriverUnload - begins\n"));
-
- registryPath = &Globals.VBoxUSB_RegistryPath;
-
- if(registryPath->Buffer) {
-
- ExFreePool(registryPath->Buffer);
- registryPath->Buffer = NULL;
- }
-
- dprintf(("vboxUsb_DriverUnload - ends\n"));
-
- return;
-}
-
-NTSTATUS
-VBoxUSB_AddDevice(
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT PhysicalDeviceObject
- )
-/*++
-
-Description:
-
-Arguments:
-
- DriverObject - Store the pointer to the object representing us.
-
- PhysicalDeviceObject - Pointer to the device object created by the
- underlying bus driver.
-
-Return:
-
- STATUS_SUCCESS - if successful
- STATUS_UNSUCCESSFUL - otherwise
-
---*/
-{
- NTSTATUS ntStatus;
- PDEVICE_OBJECT deviceObject;
- PDEVICE_EXTENSION deviceExtension;
- POWER_STATE state;
-
- dprintf(("vboxUsb_AddDevice - begins\n"));
-
- deviceObject = NULL;
-
- ntStatus = IoCreateDevice(
- DriverObject, // our driver object
- sizeof(DEVICE_EXTENSION), // extension size for us
- NULL, // name for this device
- FILE_DEVICE_UNKNOWN,
- FILE_AUTOGENERATED_DEVICE_NAME, // device characteristics
- FALSE, // Not exclusive
- &deviceObject); // Our device object
-
- if(!NT_SUCCESS(ntStatus)) {
- //
- // returning failure here prevents the entire stack from functioning,
- // but most likely the rest of the stack will not be able to create
- // device objects either, so it is still OK.
- //
- dprintf(("Failed to create device object\n"));
- return ntStatus;
- }
-
- //
- // Initialize the device extension
- //
-
- deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
- deviceExtension->FunctionalDeviceObject = deviceObject;
- deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
- deviceObject->Flags |= DO_DIRECT_IO;
-
- //
- // initialize the device state lock and set the device state
- //
-
- KeInitializeSpinLock(&deviceExtension->DevStateLock);
- INITIALIZE_PNP_STATE(deviceExtension);
-
- //
- //initialize OpenHandleCount
- //
- deviceExtension->OpenHandleCount = 0;
-
- //
- // Initialize the selective suspend variables
- //
- KeInitializeSpinLock(&deviceExtension->IdleReqStateLock);
- deviceExtension->IdleReqPend = 0;
- deviceExtension->PendingIdleIrp = NULL;
-
- //
- // Hold requests until the device is started
- //
-
- deviceExtension->QueueState = HoldRequests;
-
- //
- // Initialize the queue and the queue spin lock
- //
-
- InitializeListHead(&deviceExtension->NewRequestsQueue);
- KeInitializeSpinLock(&deviceExtension->QueueLock);
-
- //
- // Initialize the remove event to not-signaled.
- //
-
- KeInitializeEvent(&deviceExtension->RemoveEvent,
- SynchronizationEvent,
- FALSE);
-
- //
- // Initialize the stop event to signaled.
- // This event is signaled when the OutstandingIO becomes 1
- //
-
- KeInitializeEvent(&deviceExtension->StopEvent,
- SynchronizationEvent,
- TRUE);
-
- //
- // OutstandingIo count biased to 1.
- // Transition to 0 during remove device means IO is finished.
- // Transition to 1 means the device can be stopped
- //
-
- deviceExtension->OutStandingIO = 1;
- KeInitializeSpinLock(&deviceExtension->IOCountLock);
-
-#ifdef SUPPORT_WMI
- //
- // Delegating to WMILIB
- //
- ntStatus = VBoxUSB_WmiRegistration(deviceExtension);
-
- if(!NT_SUCCESS(ntStatus)) {
-
- dprintf(("vboxUsb_WmiRegistration failed with %X\n", ntStatus));
- IoDeleteDevice(deviceObject);
- return ntStatus;
- }
-#endif
- //
- // set the flags as underlying PDO
- //
-
- if(PhysicalDeviceObject->Flags & DO_POWER_PAGABLE) {
-
- deviceObject->Flags |= DO_POWER_PAGABLE;
- }
-
- //
- // Typically, the function driver for a device is its
- // power policy owner, although for some devices another
- // driver or system component may assume this role.
- // Set the initial power state of the device, if known, by calling
- // PoSetPowerState.
- //
-
- deviceExtension->DevPower = PowerDeviceD0;
- deviceExtension->SysPower = PowerSystemWorking;
-
- state.DeviceState = PowerDeviceD0;
- PoSetPowerState(deviceObject, DevicePowerState, state);
-
- //
- // attach our driver to device stack
- // The return value of IoAttachDeviceToDeviceStack is the top of the
- // attachment chain. This is where all the IRPs should be routed.
- //
-
- deviceExtension->TopOfStackDeviceObject =
- IoAttachDeviceToDeviceStack(deviceObject,
- PhysicalDeviceObject);
-
- if(NULL == deviceExtension->TopOfStackDeviceObject) {
-#ifdef SUPPORT_WMI
- VBoxUSB_WmiDeRegistration(deviceExtension);
-#endif
- IoDeleteDevice(deviceObject);
- return STATUS_NO_SUCH_DEVICE;
- }
-
- //
- // Register device interfaces
- //
-
- ntStatus = IoRegisterDeviceInterface(deviceExtension->PhysicalDeviceObject,
- &GUID_CLASS_VBOXUSB,
- NULL,
- &deviceExtension->InterfaceName);
-
- if(!NT_SUCCESS(ntStatus)) {
-
-#ifdef SUPPORT_WMI
- VBoxUSB_WmiDeRegistration(deviceExtension);
-#endif
- IoDetachDevice(deviceExtension->TopOfStackDeviceObject);
- IoDeleteDevice(deviceObject);
- return ntStatus;
- }
-
- if(IoIsWdmVersionAvailable(1, 0x20)) {
-
- deviceExtension->WdmVersion = WinXpOrBetter;
- }
- else if(IoIsWdmVersionAvailable(1, 0x10)) {
-
- deviceExtension->WdmVersion = Win2kOrBetter;
- }
- else if(IoIsWdmVersionAvailable(1, 0x5)) {
-
- deviceExtension->WdmVersion = WinMeOrBetter;
- }
- else if(IoIsWdmVersionAvailable(1, 0x0)) {
-
- deviceExtension->WdmVersion = Win98OrBetter;
- }
-
- deviceExtension->SSRegistryEnable = 0;
- deviceExtension->SSEnable = 0;
-
- //
- // WinXP only
- // check the registry flag -
- // whether the device should selectively
- // suspend when idle
- //
-
- if(WinXpOrBetter == deviceExtension->WdmVersion) {
-
- VBoxUSB_GetRegistryDword(VBOXUSB_REGISTRY_PARAMETERS_PATH,
- L"vboxUsbEnable",
- (PULONG)&deviceExtension->SSRegistryEnable);
-
- if(deviceExtension->SSRegistryEnable) {
-
- //
- // initialize DPC
- //
- KeInitializeDpc(&deviceExtension->DeferredProcCall,
- DpcRoutine,
- deviceObject);
-
- //
- // initialize the timer.
- // the DPC and the timer in conjunction,
- // monitor the state of the device to
- // selectively suspend the device.
- //
- KeInitializeTimerEx(&deviceExtension->Timer,
- NotificationTimer);
-
- //
- // Initialize the NoDpcWorkItemPendingEvent to signaled state.
- // This event is cleared when a Dpc is fired and signaled
- // on completion of the work-item.
- //
- KeInitializeEvent(&deviceExtension->NoDpcWorkItemPendingEvent,
- NotificationEvent,
- TRUE);
-
- //
- // Initialize the NoIdleReqPendEvent to ensure that the idle request
- // is indeed complete before we unload the drivers.
- //
- KeInitializeEvent(&deviceExtension->NoIdleReqPendEvent,
- NotificationEvent,
- TRUE);
- }
- }
-
- //
- // Clear the DO_DEVICE_INITIALIZING flag.
- // Note: Do not clear this flag until the driver has set the
- // device power state and the power DO flags.
- //
-
- deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-
- /* Clear all VBox USB device data. */
- memset(&deviceExtension->usbdev, 0, sizeof(deviceExtension->usbdev));
-
- dprintf(("vboxUsb_AddDevice - ends\n"));
-
- return ntStatus;
-}
-
-
-NTSTATUS
-VBoxUSB_DispatchSysCtrl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
-Arguments:
-
-Return Value:
-
---*/
-{
- PDEVICE_EXTENSION deviceExtension;
- NTSTATUS ntStatus;
- PIO_STACK_LOCATION irpStack;
-
- PAGED_CODE();
-
- irpStack = IoGetCurrentIrpStackLocation (Irp);
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
- dprintf((WMIMinorFunctionString(irpStack->MinorFunction)));
-
- if (Removed == deviceExtension->DeviceState)
- {
- ntStatus = STATUS_DELETE_PENDING;
-
- Irp->IoStatus.Status = ntStatus;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return ntStatus;
- }
-
- dprintf(("VBoxUSB_DispatchSysCtrl::"));
- VBoxUSB_IoIncrement(deviceExtension);
-
- /* Always pass it on to the next driver. */
- IoSkipCurrentIrpStackLocation (Irp);
-
- ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
-
- dprintf(("VBoxUSB_DispatchSysCtrl::"));
- VBoxUSB_IoDecrement(deviceExtension);
-
- return ntStatus;
-}
-
-
-#ifdef DEBUG
-PCHAR
-WMIMinorFunctionString (
- UCHAR MinorFunction
- )
-/*++
-
-Routine Description:
-
-Arguments:
-
-Return Value:
-
---*/
-{
- switch (MinorFunction) {
-
- case IRP_MN_CHANGE_SINGLE_INSTANCE:
- return "IRP_MN_CHANGE_SINGLE_INSTANCE\n";
-
- case IRP_MN_CHANGE_SINGLE_ITEM:
- return "IRP_MN_CHANGE_SINGLE_ITEM\n";
-
- case IRP_MN_DISABLE_COLLECTION:
- return "IRP_MN_DISABLE_COLLECTION\n";
-
- case IRP_MN_DISABLE_EVENTS:
- return "IRP_MN_DISABLE_EVENTS\n";
-
- case IRP_MN_ENABLE_COLLECTION:
- return "IRP_MN_ENABLE_COLLECTION\n";
-
- case IRP_MN_ENABLE_EVENTS:
- return "IRP_MN_ENABLE_EVENTS\n";
-
- case IRP_MN_EXECUTE_METHOD:
- return "IRP_MN_EXECUTE_METHOD\n";
-
- case IRP_MN_QUERY_ALL_DATA:
- return "IRP_MN_QUERY_ALL_DATA\n";
-
- case IRP_MN_QUERY_SINGLE_INSTANCE:
- return "IRP_MN_QUERY_SINGLE_INSTANCE\n";
-
- case IRP_MN_REGINFO:
- return "IRP_MN_REGINFO\n";
-
- default:
- return "IRP_MN_?????\n";
- }
-}
-#endif
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxusb.h b/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxusb.h
deleted file mode 100644
index dca09e767..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxusb.h
+++ /dev/null
@@ -1,373 +0,0 @@
-/*++
-
-Copyright (c) 2000 Microsoft Corporation
-
-Module Name:
-
- vboxusb.h
-
-Abstract:
-
-Environment:
-
- Kernel mode
-
-Notes:
-
- Copyright (c) 2000 Microsoft Corporation.
- All Rights Reserved.
-
---*/
-#ifndef _VBOXUSB_H
-#define _VBOXUSB_H
-
-
-#include <VBox/cdefs.h>
-#include <VBox/types.h>
-#include <iprt/assert.h>
-#include <VBox/sup.h>
-#include <iprt/asm.h>
-
-RT_C_DECLS_BEGIN
-#if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
-# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
-# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
-# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap
-# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
-# pragma warning(disable : 4163)
-#endif
-#if (_MSC_VER >= 1600) && !defined(VBOX_WITH_PATCHED_DDK)
-# define _interlockedbittestandset _interlockedbittestandset_StillStupidDdkVsCompilerCrap
-# define _interlockedbittestandreset _interlockedbittestandreset_StillStupidDdkVsCompilerCrap
-# define _interlockedbittestandset64 _interlockedbittestandset64_StillStupidDdkVsCompilerCrap
-# define _interlockedbittestandreset64 _interlockedbittestandreset64_StillStupidDdkVsCompilerCrap
-# pragma warning(disable : 4163)
-#endif
-
-#include <initguid.h>
-#include <wdm.h>
-#include <wmilib.h>
-#include <wmistr.h>
-/* The pragma shuts up the following warning:
- ...inc\ddk\wnet\usbioctl.h(447) : warning C4200: nonstandard extension used : zero-sized array in struct/union
- Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array */
-#pragma warning( disable : 4200 )
-#include "usbdi.h"
-#pragma warning( default : 4200 )
-#include "usbdlib.h"
-#include <VBox/usblib.h>
-
-#if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
-# pragma warning(default : 4163)
-# undef _InterlockedExchange
-# undef _InterlockedExchangeAdd
-# undef _InterlockedCompareExchange
-# undef _InterlockedAddLargeStatistic
-#endif
-#if (_MSC_VER >= 1600) && !defined(VBOX_WITH_PATCHED_DDK)
-# pragma warning(default : 4163)
-# undef _interlockedbittestandset
-# undef _interlockedbittestandreset
-# undef _interlockedbittestandset64
-# undef _interlockedbittestandreset64
-#endif
-RT_C_DECLS_END
-
-#if defined(DEBUG) && !defined(NO_LOGGING)
-# define dprintf(a) DbgPrint a
-#else
-# define dprintf(a) do {} while (0)
-#endif
-
-// from usb.h
-#define USBD_DEFAULT_PIPE_TRANSFER 0x00000008
-
-#define VBOXUSBTAG (ULONG) 'UxBV'
-
-#undef ExAllocatePool
-#define ExAllocatePool(type, size) \
- ExAllocatePoolWithTag(type, size, VBOXUSBTAG);
-
-typedef struct _GLOBALS {
-
- UNICODE_STRING VBoxUSB_RegistryPath;
-
-} GLOBALS;
-
-#define IDLE_INTERVAL 5000
-
-typedef enum _DEVSTATE {
-
- NotStarted, // not started
- Stopped, // device stopped
- Working, // started and working
- PendingStop, // stop pending
- PendingRemove, // remove pending
- SurpriseRemoved, // removed by surprise
- Removed // removed
-
-} DEVSTATE;
-
-typedef enum _QUEUE_STATE {
-
- HoldRequests, // device is not started yet
- AllowRequests, // device is ready to process
- FailRequests // fail both existing and queued up requests
-
-} QUEUE_STATE;
-
-typedef enum _WDM_VERSION {
-
- WinXpOrBetter,
- Win2kOrBetter,
- WinMeOrBetter,
- Win98OrBetter
-
-} WDM_VERSION;
-
-#define INITIALIZE_PNP_STATE(_Data_) \
- (_Data_)->DeviceState = NotStarted;\
- (_Data_)->PrevDevState = NotStarted;
-
-#define SET_NEW_PNP_STATE(_Data_, _state_) \
- (_Data_)->PrevDevState = (_Data_)->DeviceState;\
- (_Data_)->DeviceState = (_state_);
-
-#define RESTORE_PREVIOUS_PNP_STATE(_Data_) \
- (_Data_)->DeviceState = (_Data_)->PrevDevState;
-
-
-#define VBOXUSB_MAX_TRANSFER_SIZE 256
-#define VBOXUSB_TEST_BOARD_TRANSFER_BUFFER_SIZE (64 *1024 )
-
-//
-// registry path used for parameters
-// global to all instances of the driver
-//
-
-#define VBOXUSB_REGISTRY_PARAMETERS_PATH \
- L"\\REGISTRY\\Machine\\System\\CurrentControlSet\\SERVICES\\VBOXUSB\\Parameters"
-
-
-typedef struct _VBOXUSB_PIPE_CONTEXT {
-
- BOOLEAN PipeOpen;
-
-} VBOXUSB_PIPE_CONTEXT, *PVBOXUSB_PIPE_CONTEXT;
-
-typedef struct _VBOXUSB_PIPE_INFO {
- UCHAR EndpointAddress;
- ULONG NextScheduledFrame;
-} VBOXUSB_PIPE_INFO;
-
-typedef struct _VBOXUSB_IFACE_INFO {
- USBD_INTERFACE_INFORMATION *pInterfaceInfo;
- VBOXUSB_PIPE_INFO *pPipeInfo;
-} VBOXUSB_IFACE_INFO;
-
-
-// A number that should cover the vast majority of USB devices
-#define MAX_CFGS 4
-
-//
-// A structure representing the instance information associated with
-// this particular device.
-//
-
-typedef struct _DEVICE_EXTENSION {
-
- // Functional Device Object
- PDEVICE_OBJECT FunctionalDeviceObject;
-
- // Device object we call when submitting Urbs
- PDEVICE_OBJECT TopOfStackDeviceObject;
-
- // The bus driver object
- PDEVICE_OBJECT PhysicalDeviceObject;
-
- // Name buffer for our named Functional device object link
- // The name is generated based on the driver's class GUID
- UNICODE_STRING InterfaceName;
-
- // Bus drivers set the appropriate values in this structure in response
- // to an IRP_MN_QUERY_CAPABILITIES IRP. Function and filter drivers might
- // alter the capabilities set by the bus driver.
- DEVICE_CAPABILITIES DeviceCapabilities;
-
- // Configuration Descriptor
- PUSB_CONFIGURATION_DESCRIPTOR UsbConfigurationDescriptor;
-
- // Interface Information structure
- PUSBD_INTERFACE_INFORMATION UsbInterface;
-
- // Pipe context for the vboxusb driver
- PVBOXUSB_PIPE_CONTEXT PipeContext;
-
- // current state of device
- DEVSTATE DeviceState;
-
- // state prior to removal query
- DEVSTATE PrevDevState;
-
- // obtain and hold this lock while changing the device state,
- // the queue state and while processing the queue.
- KSPIN_LOCK DevStateLock;
-
- // current system power state
- SYSTEM_POWER_STATE SysPower;
-
- // current device power state
- DEVICE_POWER_STATE DevPower;
-
- // Pending I/O queue state
- QUEUE_STATE QueueState;
-
- // Pending I/O queue
- LIST_ENTRY NewRequestsQueue;
-
- // I/O Queue Lock
- KSPIN_LOCK QueueLock;
-
- KEVENT RemoveEvent;
-
- KEVENT StopEvent;
-
- ULONG OutStandingIO;
-
- KSPIN_LOCK IOCountLock;
-
- // selective suspend variables
-
- LONG SSEnable;
-
- LONG SSRegistryEnable;
-
- PUSB_IDLE_CALLBACK_INFO IdleCallbackInfo;
-
- PIRP PendingIdleIrp;
-
- LONG IdleReqPend;
-
- LONG FreeIdleIrpCount;
-
- KSPIN_LOCK IdleReqStateLock;
-
- KEVENT NoIdleReqPendEvent;
-
- // default power state to power down to on self-suspend
- ULONG PowerDownLevel;
-
- // remote wakeup variables
- PIRP WaitWakeIrp;
-
- LONG FlagWWCancel;
-
- LONG FlagWWOutstanding;
-
- LONG WaitWakeEnable;
-
- // open handle count
- LONG OpenHandleCount;
-
- // selective suspend model uses timers, dpcs and work item.
- KTIMER Timer;
-
- KDPC DeferredProcCall;
-
- // This event is cleared when a DPC/Work Item is queued.
- // and signaled when the work-item completes.
- // This is essential to prevent the driver from unloading
- // while we have DPC or work-item queued up.
- KEVENT NoDpcWorkItemPendingEvent;
-
-#ifdef SUPPORT_WMI
- // WMI information
- WMILIB_CONTEXT WmiLibInfo;
-#endif
-
- // WDM version
- WDM_VERSION WdmVersion;
-
- struct
- {
- HANDLE hConfiguration;
- uint32_t uConfigValue;
-
- LONG fClaimed;
-
- uint32_t uNumInterfaces;
- USB_DEVICE_DESCRIPTOR *devdescr;
- USB_CONFIGURATION_DESCRIPTOR *cfgdescr[MAX_CFGS];
-
- VBOXUSB_IFACE_INFO *pVBIfaceInfo;
-
- uint16_t idVendor, idProduct, bcdDevice;
- char szSerial[MAX_USB_SERIAL_STRING];
- uint8_t fIsHighSpeed;
-
- } usbdev;
-
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
-
-
-typedef struct _IRP_COMPLETION_CONTEXT {
-
- PDEVICE_EXTENSION DeviceExtension;
-
- PKEVENT Event;
-
-} IRP_COMPLETION_CONTEXT, *PIRP_COMPLETION_CONTEXT;
-
-extern GLOBALS Globals;
-
-
-typedef struct {
- uint8_t bmRequestType;
- uint8_t bRequest;
- uint16_t wValue;
- uint16_t wIndex;
- uint16_t wLength;
-} USBSETUP, *PUSBSETUP;
-
-
-RT_C_DECLS_BEGIN
-
-/* Hack to get imported names correctly in both win32 & win64 */
-#ifdef _WIN64
-#define DECLSPEC_USBIMPORT DECLSPEC_IMPORT
-#else
-#define DECLSPEC_USBIMPORT
-
-#define USBD_ParseDescriptors _USBD_ParseDescriptors
-#define USBD_ParseConfigurationDescriptorEx _USBD_ParseConfigurationDescriptorEx
-#define USBD_CreateConfigurationRequestEx _USBD_CreateConfigurationRequestEx
-#endif
-
-DECLSPEC_USBIMPORT PUSB_COMMON_DESCRIPTOR
-USBD_ParseDescriptors(
- IN PVOID DescriptorBuffer,
- IN ULONG TotalLength,
- IN PVOID StartPosition,
- IN LONG DescriptorType
- );
-
-DECLSPEC_USBIMPORT PUSB_INTERFACE_DESCRIPTOR
-USBD_ParseConfigurationDescriptorEx(
- IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
- IN PVOID StartPosition,
- IN LONG InterfaceNumber,
- IN LONG AlternateSetting,
- IN LONG InterfaceClass,
- IN LONG InterfaceSubClass,
- IN LONG InterfaceProtocol
- );
-
-DECLSPEC_USBIMPORT PURB
-USBD_CreateConfigurationRequestEx(
- IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
- IN PUSBD_INTERFACE_LIST_ENTRY InterfaceList
- );
-
-RT_C_DECLS_END
-
-#endif
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilt-win32.cpp b/src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilt-win32.cpp
deleted file mode 100644
index b23b22e12..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilt-win32.cpp
+++ /dev/null
@@ -1,858 +0,0 @@
-/** @file
- *
- * VBox host drivers - USB drivers - Win32 USB filter driver
- */
-
-/*
- * Copyright (C) 2006-2007 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-
-/*******************************************************************************
-* Header Files *
-*******************************************************************************/
-#include <VBox/cdefs.h>
-#include <VBox/types.h>
-#include <iprt/assert.h>
-#include <VBox/sup.h>
-
-RT_C_DECLS_BEGIN
-#include <ntddk.h>
-RT_C_DECLS_END
-
-#include <VBox/log.h>
-#include <iprt/assert.h>
-#include <VBox/usblib.h>
-
-#include "USBFilter.h"
-
-/*
- * Note: Must match the VID & PID in the USB driver .inf file!!
- */
-/*
- BusQueryDeviceID USB\Vid_80EE&Pid_CAFE
- BusQueryInstanceID 2
- BusQueryHardwareIDs USB\Vid_80EE&Pid_CAFE&Rev_0100
- BusQueryHardwareIDs USB\Vid_80EE&Pid_CAFE
- BusQueryCompatibleIDs USB\Class_ff&SubClass_00&Prot_00
- BusQueryCompatibleIDs USB\Class_ff&SubClass_00
- BusQueryCompatibleIDs USB\Class_ff
-*/
-
-#define szBusQueryDeviceId L"USB\\Vid_80EE&Pid_CAFE"
-#define szBusQueryHardwareIDs L"USB\\Vid_80EE&Pid_CAFE&Rev_0100\0USB\\Vid_80EE&Pid_CAFE\0\0"
-#define szBusQueryCompatibleIDs L"USB\\Class_ff&SubClass_00&Prot_00\0USB\\Class_ff&SubClass_00\0USB\\Class_ff\0\0"
-
-#define szDeviceTextDescription L"VirtualBox USB"
-
-
-#define MAX_ATTACHED_USB_DEVICES 128
-
-typedef struct
-{
- bool fAttached, fCaptured;
-
- PDEVICE_OBJECT Pdo, Fdo;
-} FLTUSB_DEVICE, *PFLTUSB_DEVICE;
-
-typedef struct
-{
- char szVendor[MAX_VENDOR_NAME];
- char szProduct[MAX_PRODUCT_NAME];
- char szRevision[MAX_REVISION_NAME];
- uintptr_t id;
- int cActive;
-} USBDEV_FILTER, *PUSBDEV_FILTER;
-
-/* Device driver instance data */
-typedef struct
-{
- LONG cUSBDevices;
- LONG CaptureCount;
-
- LONG cUSBChangeNotification;
-
- KSPIN_LOCK lock;
-
- FLTUSB_DEVICE USBDevice[MAX_ATTACHED_USB_DEVICES];
-
- LONG cFilters;
- USBDEV_FILTER aFilter[MAX_ATTACHED_USB_DEVICES];
-
-} DRVINSTANCE, *PDRVINSTANCE;
-
-DRVINSTANCE DrvInstance = {0};
-
-
-#define ACQUIRE_LOCK() \
- KIRQL oldIrql; \
- KeAcquireSpinLock(&DrvInstance.lock, &oldIrql);
-
-#define RELEASE_LOCK() \
- KeReleaseSpinLock(&DrvInstance.lock, oldIrql);
-
-
-/*
- * Internal functions
- */
-static NTSTATUS VBoxAddFilter(PUSBSUP_FILTER pFilter);
-static NTSTATUS VBoxRemoveFilter(PUSBSUP_FILTER pFilter);
-static NTSTATUS VBoxClearFilters();
-static bool VBoxMatchFilter(WCHAR *pszDeviceId);
-
-
-NTSTATUS _stdcall VBoxUSBInit()
-{
- KeInitializeSpinLock(&DrvInstance.lock);
- return STATUS_SUCCESS;
-}
-
-
-/*++
-Routine Description:
- A completion routine for use when calling the lower device objects to
- which our filter deviceobject is attached.
-
-Arguments:
-
- DeviceObject - Pointer to deviceobject
- Irp - Pointer to a PnP Irp.
- Context - NULL
-Return Value:
-
- NT Status is returned.
-
---*/
-
-NTSTATUS _stdcall VBoxUSBPnPCompletion(DEVICE_OBJECT *fido, IRP *Irp, void *context)
-{
- PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
- PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
-
- UCHAR type = stack->MajorFunction;
- ULONG dwControlCode = stack->Parameters.DeviceIoControl.IoControlCode;
-
- if (Irp->PendingReturned) {
- DebugPrint(("Pending IRP returned\n"));
- IoMarkIrpPending(Irp);
- }
-
- //
- // On the way up, pageable might become clear. Mimic the driver below us.
- //
- if (!(pdx->NextLowerDriver->Flags & DO_POWER_PAGABLE)) {
-
- fido->Flags &= ~DO_POWER_PAGABLE;
- }
-
- ULONG fcn = stack->MinorFunction;
- if (type == IRP_MJ_PNP && DrvInstance.CaptureCount > 0)
- {
-#ifdef DEBUG
- const char * MinorFunctionName = PnPMinorFunctionString((UCHAR)fcn);
- if (MinorFunctionName != NULL)
- DebugPrint(("VBoxUSB - Finished %x %x: IRP_MJ_PNP (%s) rc=%x\n", fido, pdx, MinorFunctionName, Irp->IoStatus.Status));
- else
- DebugPrint(("VBoxUSB - Finished %x %x: IRP_MJ_PNP (0x%x) rc=%x\n", fido, pdx, fcn, Irp->IoStatus.Status));
-#endif
-
- if (fcn == IRP_MN_QUERY_DEVICE_RELATIONS)
- {
- switch(stack->Parameters.QueryDeviceRelations.Type)
- {
- case BusRelations:
- {
- DebugPrint(("BusRelations\n"));
-
- if (Irp->IoStatus.Status == STATUS_SUCCESS)
- {
- PDEVICE_RELATIONS pRel = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
- DebugPrint(("pRel = %08x\n", pRel));
- if ((ULONG_PTR)pRel > 0x10000)
- {
- for (unsigned i=0;i<pRel->Count;i++)
- {
- DebugPrint(("PDO: %x\n", pRel->Objects[i]));
- if (ListKnownPDO(pRel->Objects[i]) == false)
- {
- DebugPrint(("Hooking new PDO\n"));
- FilterAddDevice(fido->DriverObject, pRel->Objects[i]);
- }
- }
- }
- }
- break;
- }
- case TargetDeviceRelation:
- DebugPrint(("TargetDeviceRelation\n"));
- break;
- case RemovalRelations:
- DebugPrint(("RemovalRelations\n"));
- break;
- case EjectionRelations:
- DebugPrint(("EjectionRelations\n"));
- break;
- }
- }
- else
- if (fcn == IRP_MN_QUERY_ID)
- {
- if (Irp->IoStatus.Status == STATUS_SUCCESS)
- {
- WCHAR *pId = (WCHAR *)Irp->IoStatus.Information;
- WCHAR *pTmp;
-
- DebugPrint(("pId = %08x\n", pId));
- if ((ULONG_PTR)pId > 0x10000)
- {
- switch(stack->Parameters.QueryDeviceRelations.Type)
- {
- case BusQueryInstanceID:
- DebugPrint(("BusQueryInstanceID %ws\n", pId));
- break;
-
- case BusQueryDeviceID:
- DebugPrint(("BusQueryDeviceID %ws\n", pId));
-
- if (VBoxMatchFilter(pId) == true)
- {
- pId = (WCHAR *)ExAllocatePool(PagedPool, sizeof(szBusQueryDeviceId));
- if (!pId)
- {
- AssertFailed();
- break;
- }
- memcpy(pId, szBusQueryDeviceId, sizeof(szBusQueryDeviceId));
- DebugPrint(("NEW BusQueryDeviceID %ws\n", pId));
- ExFreePool((PVOID)Irp->IoStatus.Information);
- Irp->IoStatus.Information = (ULONG_PTR)pId;
-
- ListCaptureDevice(fido);
- }
- break;
-
- case BusQueryHardwareIDs:
-#ifdef DEBUG
- while(*pId) //MULTI_SZ
- {
- DebugPrint(("BusQueryHardwareIDs %ws\n", pId));
- while(*pId) pId++;
- pId++;
- }
-#endif
- if (VBoxMatchFilter((WCHAR *)Irp->IoStatus.Information) == true)
- {
- pTmp = pId = (WCHAR *)ExAllocatePool(PagedPool, sizeof(szBusQueryHardwareIDs));
- if (!pId)
- {
- AssertFailed();
- break;
- }
- memcpy(pId, szBusQueryHardwareIDs, sizeof(szBusQueryHardwareIDs));
- #ifdef DEBUG
- while(*pTmp) //MULTI_SZ
- {
- DebugPrint(("NEW BusQueryHardwareIDs %ws\n", pTmp));
- while(*pTmp) pTmp++;
- pTmp++;
- }
- #endif
- ExFreePool((PVOID)Irp->IoStatus.Information);
- Irp->IoStatus.Information = (ULONG_PTR)pId;
-
- ListCaptureDevice(fido);
- }
- break;
-
- case BusQueryCompatibleIDs:
-#ifdef DEBUG
- while(*pId) //MULTI_SZ
- {
- DebugPrint(("BusQueryCompatibleIDs %ws\n", pId));
- while(*pId) pId++;
- pId++;
- }
-#endif
- if (ListDeviceIsCaptured(fido))
- {
- pTmp = pId = (WCHAR *)ExAllocatePool(PagedPool, sizeof(szBusQueryCompatibleIDs));
- if (!pId)
- {
- AssertFailed();
- break;
- }
- memcpy(pId, szBusQueryCompatibleIDs, sizeof(szBusQueryCompatibleIDs));
- #ifdef DEBUG
- while(*pTmp) //MULTI_SZ
- {
- DebugPrint(("NEW BusQueryCompatibleIDs %ws\n", pTmp));
- while(*pTmp) pTmp++;
- pTmp++;
- }
- #endif
- ExFreePool((PVOID)Irp->IoStatus.Information);
- Irp->IoStatus.Information = (ULONG_PTR)pId;
- }
- break;
- }
- }
- }
- }
- else
- if (fcn == IRP_MN_QUERY_DEVICE_TEXT)
- {
- if (Irp->IoStatus.Status == STATUS_SUCCESS)
- {
- WCHAR *pId = (WCHAR *)Irp->IoStatus.Information;
- if ((ULONG_PTR)pId > 0x10000)
- {
- switch(stack->Parameters.QueryDeviceText.DeviceTextType)
- {
- case DeviceTextLocationInformation:
- DebugPrint(("DeviceTextLocationInformation %ws\n", pId));
- break;
- case DeviceTextDescription:
- DebugPrint(("DeviceTextDescription %ws\n", pId));
- if (ListDeviceIsCaptured(fido))
- {
- WCHAR *pId = (WCHAR *)ExAllocatePool(PagedPool, sizeof(szDeviceTextDescription));
- if (!pId)
- {
- AssertFailed();
- break;
- }
- memcpy(pId, szDeviceTextDescription, sizeof(szDeviceTextDescription));
- DebugPrint(("NEW szDeviceTextDescription %ws\n", pId));
- ExFreePool((PVOID)Irp->IoStatus.Information);
- Irp->IoStatus.Information = (ULONG_PTR)pId;
- }
- }
- }
- }
- }
-#ifdef DEBUG
- else
- if (fcn == IRP_MN_QUERY_CAPABILITIES)
- {
- if (Irp->IoStatus.Status == STATUS_SUCCESS)
- {
- PDEVICE_CAPABILITIES pCaps = stack->Parameters.DeviceCapabilities.Capabilities;
- if ((ULONG_PTR)pCaps > 0x10000)
- {
- DebugPrint(("Caps.SilentInstall = %d\n", pCaps->SilentInstall));
- DebugPrint(("Caps.UniqueID = %d\n", pCaps->UniqueID ));
- DebugPrint(("Caps.Address = %d\n", pCaps->Address ));
- DebugPrint(("Caps.UINumber = %d\n", pCaps->UINumber ));
-#if 0
- if (ListDeviceIsCaptured(fido))
- {
- pCaps->SilentInstall = 1;
- DebugPrint(("NEW: Caps.SilentInstall = %d\n", pCaps->SilentInstall));
- }
-#endif
- }
- }
- }
-#endif
- }
-
- IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
- return STATUS_CONTINUE_COMPLETION;
-}
-
-NTSTATUS _stdcall VBoxUSBDispatchIO(PDEVICE_OBJECT DeviceObject, PIRP Irp)
-{
- PIO_STACK_LOCATION irpStack;
- NTSTATUS status;
- ULONG info = 0;
- PVOID ioBuffer;
- ULONG inputBufferLength;
- ULONG outputBufferLength;
-
- status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- irpStack = IoGetCurrentIrpStackLocation (Irp);
-
- ioBuffer = Irp->AssociatedIrp.SystemBuffer;
- inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
- outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
- {
- case SUPUSBFLT_IOCTL_USB_CHANGE:
- {
- PUSBSUP_USB_CHANGE pOut = (PUSBSUP_USB_CHANGE)ioBuffer;
-
- if (!ioBuffer || outputBufferLength != sizeof(*pOut) || inputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSBFLT_IOCTL_USB_CHANGE: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, 0, outputBufferLength, sizeof(*pOut)));
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- Assert(sizeof(DrvInstance.cUSBChangeNotification) == sizeof(LONG));
-
- if (DrvInstance.cUSBChangeNotification > 0)
- {
- InterlockedDecrement((volatile LONG *)&DrvInstance.cUSBChangeNotification);
- pOut->fUSBChange = true;
- }
- else {
- pOut->fUSBChange = false;
- }
-
- if (pOut->fUSBChange)
- DebugPrint(("SUPUSBFLT_IOCTL_USB_CHANGE -> %d\n", pOut->fUSBChange));
-
- info = sizeof(*pOut);
- break;
- }
-
- case SUPUSBFLT_IOCTL_ENABLE_CAPTURE:
- DebugPrint(("SUPUSBFLT_IOCTL_ENABLE_CAPTURE\n"));
- break;
-
- case SUPUSBFLT_IOCTL_DISABLE_CAPTURE:
- DebugPrint(("SUPUSBFLT_IOCTL_DISABLE_CAPTURE\n"));
- break;
-
- case SUPUSBFLT_IOCTL_GET_NUM_DEVICES:
- {
- PUSBSUP_GETNUMDEV pOut = (PUSBSUP_GETNUMDEV)ioBuffer;
-
- DebugPrint(("SUPUSBFLT_IOCTL_GET_NUM_DEVICES\n"));
- if (!ioBuffer || outputBufferLength != sizeof(*pOut) || inputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSBFLT_IOCTL_GET_NUM_DEVICES: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, 0, outputBufferLength, sizeof(*pOut)));
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- pOut->cUSBDevices = DrvInstance.cUSBDevices;
- info = sizeof(*pOut);
- break;
- }
-
- /* deprecated */
- case SUPUSBFLT_IOCTL_IGNORE_DEVICE:
- {
- break;
- }
-
- case SUPUSBFLT_IOCTL_GET_VERSION:
- {
- PUSBSUP_VERSION pOut = (PUSBSUP_VERSION)ioBuffer;
-
- if (!ioBuffer || outputBufferLength != sizeof(*pOut) || inputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSBFLT_IOCTL_GET_VERSION: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, 0, outputBufferLength, sizeof(*pOut)));
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- pOut->u32Major = USBFLT_MAJOR_VERSION;
- pOut->u32Minor = USBFLT_MINOR_VERSION;
- info = sizeof(*pOut);
- break;
- }
-
- case SUPUSBFLT_IOCTL_ADD_FILTER:
- {
- PUSBSUP_FILTER pIn = (PUSBSUP_FILTER)ioBuffer;
- PUSBSUP_FILTER pOut = pIn;
-
- if (!ioBuffer || inputBufferLength != sizeof(*pIn) || outputBufferLength != sizeof(*pOut))
- {
- AssertMsgFailed(("SUPUSBFLT_IOCTL_ADD_FILTER: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, sizeof(pIn), outputBufferLength, 0));
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- DebugPrint(("SUPUSBFLT_IOCTL_ADD_FILTER %s %s %s\n", pIn->szVendor, pIn->szProduct, pIn->szRevision));
- VBoxAddFilter(pIn);
- pOut->id = pIn->id;
- info = sizeof(*pOut);
- break;
- }
-
- case SUPUSBFLT_IOCTL_REMOVE_FILTER:
- {
- PUSBSUP_FILTER pIn = (PUSBSUP_FILTER)ioBuffer;
-
- if (!ioBuffer || inputBufferLength != sizeof(*pIn))
- {
- AssertMsgFailed(("SUPUSBFLT_IOCTL_REMOVE_FILTER: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, sizeof(pIn), outputBufferLength, 0));
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- DebugPrint(("SUPUSBFLT_IOCTL_REMOVE_FILTER %x\n", pIn->id));
- VBoxRemoveFilter(pIn);
- break;
- }
-
- default:
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- Irp->IoStatus.Information = info;
-
- return status;
-}
-
-NTSTATUS _stdcall VBoxUSBCreate()
-{
- Assert(sizeof(DrvInstance.CaptureCount) == sizeof(LONG));
- InterlockedIncrement(&DrvInstance.CaptureCount);
- return STATUS_SUCCESS;
-}
-
-NTSTATUS _stdcall VBoxUSBClose()
-{
- ACQUIRE_LOCK();
- Assert(sizeof(DrvInstance.CaptureCount) == sizeof(LONG));
- InterlockedDecrement(&DrvInstance.CaptureCount);
- Assert(DrvInstance.CaptureCount >= 0);
-
- if (DrvInstance.CaptureCount == 0)
- {
- VBoxClearFilters();
- }
- if (DrvInstance.CaptureCount == 0 && DrvInstance.cUSBDevices > 0)
- {
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if (DrvInstance.USBDevice[i].fAttached == true)
- {
- if (DrvInstance.USBDevice[i].fCaptured == true)
- {
- PDEVICE_OBJECT Pdo = DrvInstance.USBDevice[i].Pdo;
- RELEASE_LOCK();
-
- DebugPrint(("Invalidate PDO %08x\n", Pdo));
-//// IoInvalidateDeviceRelations(Pdo, BusRelations);
- }
- else
- RELEASE_LOCK();
-
- return STATUS_SUCCESS;
- }
- }
- }
- RELEASE_LOCK();
- return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS VBoxAddFilter(PUSBSUP_FILTER pFilter)
-{
- NTSTATUS rc = STATUS_SUCCESS;
-
- Assert(sizeof(DrvInstance.aFilter[0].szProduct) == sizeof(pFilter->szProduct));
- Assert(sizeof(DrvInstance.aFilter[0].szVendor) == sizeof(pFilter->szVendor));
- Assert(sizeof(DrvInstance.aFilter[0].szRevision) == sizeof(pFilter->szRevision));
-
- ACQUIRE_LOCK();
- /* We ignore duplicate filters as they must get a unique id */
- if (DrvInstance.cFilters < MAX_ATTACHED_USB_DEVICES)
- {
- int i;
- for (i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if (DrvInstance.aFilter[i].cActive == 0)
- {
- DrvInstance.aFilter[i].cActive = 1;
- strncpy(DrvInstance.aFilter[i].szProduct, pFilter->szProduct, sizeof(DrvInstance.aFilter[i].szProduct));
- strncpy(DrvInstance.aFilter[i].szVendor, pFilter->szVendor, sizeof(DrvInstance.aFilter[i].szVendor));
- strncpy(DrvInstance.aFilter[i].szRevision, pFilter->szRevision, sizeof(DrvInstance.aFilter[i].szRevision));
- strupr(DrvInstance.aFilter[i].szProduct);
- strupr(DrvInstance.aFilter[i].szVendor);
- strupr(DrvInstance.aFilter[i].szRevision);
- DrvInstance.aFilter[i].id = i;
- pFilter->id = i;
- break;
- }
- }
- if (i != MAX_ATTACHED_USB_DEVICES)
- {
- InterlockedIncrement(&DrvInstance.cFilters);
- }
- else
- {
- AssertFailed();
- rc = STATUS_NO_MEMORY;
- }
-
- }
- RELEASE_LOCK();
- return rc;
-}
-
-static NTSTATUS VBoxRemoveFilter(PUSBSUP_FILTER pFilter)
-{
- NTSTATUS rc = STATUS_SUCCESS;
-
- ACQUIRE_LOCK();
- Assert(DrvInstance.cFilters);
- Assert(sizeof(DrvInstance.aFilter[0].szProduct) == sizeof(pFilter->szProduct));
- Assert(sizeof(DrvInstance.aFilter[0].szVendor) == sizeof(pFilter->szVendor));
- Assert(sizeof(DrvInstance.aFilter[0].szRevision) == sizeof(pFilter->szRevision));
-
- if (DrvInstance.cFilters)
- {
- int i;
- for (i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if ( DrvInstance.aFilter[i].cActive > 0
- && DrvInstance.aFilter[i].id == pFilter->id)
- {
- DrvInstance.aFilter[i].cActive--;
- /* simplify the lookup later on; no need for the loop */
- Assert(DrvInstance.aFilter[i].id == i);
- Assert(DrvInstance.aFilter[i].cActive == 0);
- break;
- }
- }
- if (i != MAX_ATTACHED_USB_DEVICES)
- {
- InterlockedDecrement(&DrvInstance.cFilters);
- }
- else
- {
- AssertFailed();
- rc = STATUS_NO_SUCH_FILE;
- }
-
- }
- RELEASE_LOCK();
- return rc;
-}
-
-static NTSTATUS VBoxClearFilters()
-{
- /* Clear all active filters */
- memset(DrvInstance.aFilter, 0, sizeof(DrvInstance.aFilter));
- return STATUS_SUCCESS;
-}
-
-char * _cdecl strupr(char *psz)
-{
- for(int i=0;psz[i] != 0;i++)
- {
- psz[i] = RtlUpperChar(psz[i]);
- }
- return psz;
-}
-
-static bool MatchFilter(char *pszString, char *pszStringFilter)
-{
- for (int i=0;i<4;i++)
- {
- if (pszStringFilter[i] == 0)
- break;
-
- if (pszStringFilter[i] == ' ')
- continue;
-
- if (pszStringFilter[i] != pszString[i])
- return false;
- }
- return true;
-}
-
-static bool VBoxMatchFilter(WCHAR *pszDeviceId)
-{
- //#define szBusQueryDeviceId L"USB\\Vid_80EE&Pid_CAFE"
- char szProduct[4];
- char szVendor[4];
-// char szRevision[4];
-
- if (RtlCompareMemory(pszDeviceId, L"USB\\", 4*sizeof(WCHAR)) != 4*sizeof(WCHAR))
- {
- return false;
- }
-
- while(*pszDeviceId != 0 && *pszDeviceId != '_')
- pszDeviceId++;
- if(*pszDeviceId == 0)
- return false;
- pszDeviceId++;
-
- /* Vid_ skipped */
- szVendor[0] = RtlUpperChar((CHAR)pszDeviceId[0]);
- szVendor[1] = RtlUpperChar((CHAR)pszDeviceId[1]);
- szVendor[2] = RtlUpperChar((CHAR)pszDeviceId[2]);
- szVendor[3] = RtlUpperChar((CHAR)pszDeviceId[3]);
-
- while(*pszDeviceId != 0 && *pszDeviceId != '_')
- pszDeviceId++;
- if(*pszDeviceId == 0)
- return false;
- pszDeviceId++;
-
- /* Pid_ skipped */
- szProduct[0] = RtlUpperChar((CHAR)pszDeviceId[0]);
- szProduct[1] = RtlUpperChar((CHAR)pszDeviceId[1]);
- szProduct[2] = RtlUpperChar((CHAR)pszDeviceId[2]);
- szProduct[3] = RtlUpperChar((CHAR)pszDeviceId[3]);
-
- ACQUIRE_LOCK();
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if ( DrvInstance.aFilter[i].cActive > 0
- && MatchFilter(szVendor, DrvInstance.aFilter[i].szVendor) == true
- && MatchFilter(szProduct, DrvInstance.aFilter[i].szProduct) == true
- )
- {
- RELEASE_LOCK();
- return true;
- }
- }
- RELEASE_LOCK();
- return false;
-}
-
-int ListAddDevice(PDEVICE_OBJECT pdo, PDEVICE_OBJECT fdo)
-{
- ACQUIRE_LOCK()
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if (DrvInstance.USBDevice[i].fAttached == false)
- {
- DebugPrint(("ListAddDevice %08x %08x\n", pdo, fdo));
- DrvInstance.USBDevice[i].fAttached = true;
- DrvInstance.USBDevice[i].Pdo = pdo;
- DrvInstance.USBDevice[i].Fdo = fdo;
- DrvInstance.USBDevice[i].fCaptured = false;
- Assert(DrvInstance.cUSBDevices <= MAX_ATTACHED_USB_DEVICES);
-
- RELEASE_LOCK();
- return true;
- }
- }
- RELEASE_LOCK();
- return false;
-}
-
-int ListCaptureDevice(PDEVICE_OBJECT fdo)
-{
- Assert(fdo);
- ACQUIRE_LOCK();
-
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if (DrvInstance.USBDevice[i].Fdo == fdo)
- {
- if (DrvInstance.USBDevice[i].fCaptured == false)
- {
- Assert(DrvInstance.CaptureCount);
- Assert(DrvInstance.USBDevice[i].fAttached);
-
- DebugPrint(("ListCaptureDevice %08x\n", fdo));
- if (DrvInstance.CaptureCount > 0)
- {
- DrvInstance.USBDevice[i].fCaptured = true;
- DrvInstance.cUSBDevices++;
- }
- }
- //else already captured
- break;
- }
- }
- RELEASE_LOCK();
- return true;
-}
-
-int ListKnownPDO(PDEVICE_OBJECT pdo)
-{
- Assert(pdo);
- ACQUIRE_LOCK();
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if (DrvInstance.USBDevice[i].Pdo == pdo)
- {
- RELEASE_LOCK();
- return true;
- }
- }
- RELEASE_LOCK();
- return false;
-}
-
-int ListStartDevice(PDEVICE_OBJECT fdo)
-{
- Assert(fdo);
- ACQUIRE_LOCK();
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if (DrvInstance.USBDevice[i].Fdo == fdo)
- {
- if (DrvInstance.USBDevice[i].fCaptured == true)
- {
- DebugPrint(("Signal USB change ADD\n"));
- InterlockedExchange(&DrvInstance.cUSBChangeNotification, DrvInstance.CaptureCount);
- }
- RELEASE_LOCK();
- return true;
- }
- }
- RELEASE_LOCK();
- return false;
-}
-
-int ListRemoveDevice(PDEVICE_OBJECT fdo)
-{
- ACQUIRE_LOCK();
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if (DrvInstance.USBDevice[i].Fdo == fdo)
- {
- DebugPrint(("ListRemoveDevice %08x\n", fdo));
- DrvInstance.USBDevice[i].fAttached = false;
- DrvInstance.USBDevice[i].Pdo = NULL;
- DrvInstance.USBDevice[i].Fdo = NULL;
-
- if (DrvInstance.USBDevice[i].fCaptured == true)
- {
- InterlockedDecrement(&DrvInstance.cUSBDevices);
- Assert(DrvInstance.cUSBDevices >= 0);
- DebugPrint(("Signal USB change REMOVE\n"));
- InterlockedExchange(&DrvInstance.cUSBChangeNotification, DrvInstance.CaptureCount);
-
- DrvInstance.USBDevice[i].fCaptured = false;
- }
-
- RELEASE_LOCK();
- return true;
- }
- }
- RELEASE_LOCK();
- return false;
-}
-
-int ListDeviceIsCaptured(PDEVICE_OBJECT fdo)
-{
- bool ret;
-
- ACQUIRE_LOCK();
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if (DrvInstance.USBDevice[i].Fdo == fdo)
- {
- ret = DrvInstance.USBDevice[i].fCaptured;
- RELEASE_LOCK();
- return ret;
- }
- }
- RELEASE_LOCK();
- return false;
-}
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilter.c b/src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilter.c
deleted file mode 100644
index d04ba02fe..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilter.c
+++ /dev/null
@@ -1,1063 +0,0 @@
-
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- PURPOSE.
-
-Module Name:
-
- filter.c
-
-Abstract:
-
- This module shows how to a write a generic filter driver.
-
-Environment:
-
- Kernel mode
-
-Revision History:
-
- Eliyas Yakub Oct 29 1998
-
- Fixed bugs - March 15, 2001
-
- Added Ioctl interface - Aug 16, 2001
-
- Updated to use IoCreateDeviceSecure function - Sep 17, 2002
-
- Updated to use RemLocks - Oct 29, 2002
-
---*/
-
-#include "USBFilter.h"
-#include <VBox/usblib.h>
-
-#ifdef ALLOC_PRAGMA
-#pragma alloc_text (INIT, DriverEntry)
-#pragma alloc_text (PAGE, FilterAddDevice)
-#pragma alloc_text (PAGE, FilterDispatchPnp)
-#pragma alloc_text (PAGE, FilterUnload)
-#endif
-
-//
-// Define IOCTL_INTERFACE in your sources file if you want your
-// app to have private interaction with the filter driver. Read KB Q262305
-// for more information.
-//
-
-#ifdef IOCTL_INTERFACE
-
-#ifdef ALLOC_PRAGMA
-#pragma alloc_text (PAGE, FilterCreateControlObject)
-#pragma alloc_text (PAGE, FilterDeleteControlObject)
-#pragma alloc_text (PAGE, FilterDispatchIo)
-#endif
-FAST_MUTEX ControlMutex;
-ULONG InstanceCount = 0;
-PDEVICE_OBJECT ControlDeviceObject;
-
-#endif
-
-NTSTATUS
-DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
-/*++
-
-Routine Description:
-
- Installable driver initialization entry point.
- This entry point is called directly by the I/O system.
-
-Arguments:
-
- DriverObject - pointer to the driver object
-
- RegistryPath - pointer to a unicode string representing the path,
- to driver-specific key in the registry.
-
-Return Value:
-
- STATUS_SUCCESS if successful,
- STATUS_UNSUCCESSFUL otherwise.
-
---*/
-{
- NTSTATUS status = STATUS_SUCCESS;
- ULONG ulIndex;
- PDRIVER_DISPATCH * dispatch;
-
- UNREFERENCED_PARAMETER (RegistryPath);
-
- DebugPrint (("Entered the Driver Entry\n"));
-
-
- //
- // Create dispatch points
- //
- for (ulIndex = 0, dispatch = DriverObject->MajorFunction;
- ulIndex <= IRP_MJ_MAXIMUM_FUNCTION;
- ulIndex++, dispatch++) {
-
- *dispatch = FilterPass;
- }
-
- DriverObject->MajorFunction[IRP_MJ_PNP] = FilterDispatchPnp;
- DriverObject->MajorFunction[IRP_MJ_POWER] = FilterDispatchPower;
- DriverObject->DriverExtension->AddDevice = FilterAddDevice;
- DriverObject->DriverUnload = FilterUnload;
-
-#ifdef IOCTL_INTERFACE
- //
- // Set the following dispatch points as we will be doing
- // something useful to these requests instead of just
- // passing them down.
- //
-
- DriverObject->MajorFunction[IRP_MJ_CREATE] =
- DriverObject->MajorFunction[IRP_MJ_CLOSE] =
- DriverObject->MajorFunction[IRP_MJ_CLEANUP] =
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
- FilterDispatchIo;
- //
- // Mutex is to synchronize multiple threads creating & deleting
- // control deviceobjects.
- //
- ExInitializeFastMutex(&ControlMutex);
-
-#endif
-
- VBoxUSBInit();
-
- return status;
-}
-
-
-NTSTATUS
-FilterAddDevice(
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT PhysicalDeviceObject
- )
-/*++
-
-Routine Description:
-
- The Plug & Play subsystem is handing us a brand new PDO, for which we
- (by means of INF registration) have been asked to provide a driver.
-
- We need to determine if we need to be in the driver stack for the device.
- Create a function device object to attach to the stack
- Initialize that device object
- Return status success.
-
- Remember: We can NOT actually send ANY non pnp IRPS to the given driver
- stack, UNTIL we have received an IRP_MN_START_DEVICE.
-
-Arguments:
-
- DeviceObject - pointer to a device object.
-
- PhysicalDeviceObject - pointer to a device object created by the
- underlying bus driver.
-
-Return Value:
-
- NT status code.
-
---*/
-{
- NTSTATUS status = STATUS_SUCCESS;
- PDEVICE_OBJECT deviceObject = NULL;
- PDEVICE_EXTENSION deviceExtension;
- ULONG deviceType = FILE_DEVICE_UNKNOWN;
-
- PAGED_CODE ();
-
-
- if (ListKnownPDO(PhysicalDeviceObject))
- {
- DebugPrint(("FilterAddDevice already added %08x\n", PhysicalDeviceObject));
- return STATUS_SUCCESS;
- }
-
- //
- // IoIsWdmVersionAvailable(1, 0x20) returns TRUE on os after Windows 2000.
- //
- if (!IoIsWdmVersionAvailable(1, 0x20)) {
- //
- // Win2K system bugchecks if the filter attached to a storage device
- // doesn't specify the same DeviceType as the device it's attaching
- // to. This bugcheck happens in the filesystem when you disable
- // the devicestack whose top level deviceobject doesn't have a VPB.
- // To workaround we will get the toplevel object's DeviceType and
- // specify that in IoCreateDevice.
- //
- deviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
- deviceType = deviceObject->DeviceType;
- ObDereferenceObject(deviceObject);
- }
-
- //
- // Create a filter device object.
- //
-
- status = IoCreateDevice (DriverObject,
- sizeof (DEVICE_EXTENSION),
- NULL, // No Name
- deviceType,
- FILE_DEVICE_SECURE_OPEN,
- FALSE,
- &deviceObject);
-
-
- if (!NT_SUCCESS (status)) {
- //
- // Returning failure here prevents the entire stack from functioning,
- // but most likely the rest of the stack will not be able to create
- // device objects either, so it is still OK.
- //
- return status;
- }
-
- DebugPrint (("AddDevice PDO (0x%x) FDO (0x%x)\n",
- PhysicalDeviceObject, deviceObject));
-
- deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
-
- deviceExtension->NextLowerDriver = IoAttachDeviceToDeviceStack (
- deviceObject,
- PhysicalDeviceObject);
- //
- // Failure for attachment is an indication of a broken plug & play system.
- //
-
- if(NULL == deviceExtension->NextLowerDriver) {
-
- IoDeleteDevice(deviceObject);
- return STATUS_UNSUCCESSFUL;
- }
-
- deviceObject->Flags |= deviceExtension->NextLowerDriver->Flags &
- (DO_BUFFERED_IO | DO_DIRECT_IO |
- DO_POWER_PAGABLE );
-
-
- deviceObject->DeviceType = deviceExtension->NextLowerDriver->DeviceType;
-
- deviceObject->Characteristics =
- deviceExtension->NextLowerDriver->Characteristics;
-
- deviceExtension->Self = deviceObject;
-
- //
- // Let us use remove lock to keep count of IRPs so that we don't
- // detach and delete our deviceobject until all pending I/Os in our
- // devstack are completed. Remlock is required to protect us from
- // various race conditions where our driver can get unloaded while we
- // are still running dispatch or completion code.
- //
-
- IoInitializeRemoveLock (&deviceExtension->RemoveLock ,
- POOL_TAG,
- 1, // MaxLockedMinutes
- 100); // HighWatermark, this parameter is
- // used only on checked build. Specifies
- // the maximum number of outstanding
- // acquisitions allowed on the lock
-
-
- //
- // Set the initial state of the Filter DO
- //
-
- INITIALIZE_PNP_STATE(deviceExtension);
-
- DebugPrint(("AddDevice: %x to %x->%x \n", deviceObject,
- deviceExtension->NextLowerDriver,
- PhysicalDeviceObject));
-
- deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-
- ListAddDevice(PhysicalDeviceObject, deviceObject);
-
- return STATUS_SUCCESS;
-
-}
-
-
-NTSTATUS
-FilterPass (
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- The default dispatch routine. If this driver does not recognize the
- IRP, then it should send it down, unmodified.
- If the device holds iris, this IRP must be queued in the device extension
- No completion routine is required.
-
- For demonstrative purposes only, we will pass all the (non-PnP) Irps down
- on the stack (as we are a filter driver). A real driver might choose to
- service some of these Irps.
-
- As we have NO idea which function we are happily passing on, we can make
- NO assumptions about whether or not it will be called at raised IRQL.
- For this reason, this function must be in put into non-paged pool
- (aka the default location).
-
-Arguments:
-
- DeviceObject - pointer to a device object.
-
- Irp - pointer to an I/O Request Packet.
-
-Return Value:
-
- NT status code
-
---*/
-{
- PDEVICE_EXTENSION deviceExtension;
- NTSTATUS status;
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
- if (!NT_SUCCESS (status)) {
- Irp->IoStatus.Status = status;
- IoCompleteRequest (Irp, IO_NO_INCREMENT);
- return status;
- }
-
- IoSkipCurrentIrpStackLocation (Irp);
- status = IoCallDriver (deviceExtension->NextLowerDriver, Irp);
- IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);
- return status;
-}
-
-
-
-
-
-
-NTSTATUS
-FilterDispatchPnp (
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- The plug and play dispatch routines.
-
- Most of these the driver will completely ignore.
- In all cases it must pass on the IRP to the lower driver.
-
-Arguments:
-
- DeviceObject - pointer to a device object.
-
- Irp - pointer to an I/O Request Packet.
-
-Return Value:
-
- NT status code
-
---*/
-{
- PDEVICE_EXTENSION deviceExtension;
- PIO_STACK_LOCATION irpStack;
- NTSTATUS status;
- KEVENT event;
- ULONG MinorFunction;
-
- PAGED_CODE();
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- irpStack = IoGetCurrentIrpStackLocation(Irp);
-
- DebugPrint(("FilterDO %s IRP:0x%x \n",
- PnPMinorFunctionString(irpStack->MinorFunction), Irp));
-
- status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
- if (!NT_SUCCESS (status)) {
- Irp->IoStatus.Status = status;
- IoCompleteRequest (Irp, IO_NO_INCREMENT);
- return status;
- }
-
- switch (irpStack->MinorFunction) {
- case IRP_MN_START_DEVICE:
-
- //
- // The device is starting.
- // We cannot touch the device (send it any non pnp irps) until a
- // start device has been passed down to the lower drivers.
- //
- KeInitializeEvent(&event, NotificationEvent, FALSE);
- IoCopyCurrentIrpStackLocationToNext(Irp);
- IoSetCompletionRoutine(Irp,
- (PIO_COMPLETION_ROUTINE) FilterStartCompletionRoutine,
- &event,
- TRUE,
- TRUE,
- TRUE);
-
- status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);
-
- //
- // Wait for lower drivers to be done with the Irp. Important thing to
- // note here is when you allocate memory for an event in the stack
- // you must do a KernelMode wait instead of UserMode to prevent
- // the stack from getting paged out.
- //
- if (status == STATUS_PENDING) {
-
- KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
- status = Irp->IoStatus.Status;
- }
-
- if (NT_SUCCESS (status)) {
-
- //
- // As we are successfully now back, we will
- // first set our state to Started.
- //
-
- SET_NEW_PNP_STATE(deviceExtension, Started);
-
- //
- // On the way up inherit FILE_REMOVABLE_MEDIA during Start.
- // This characteristic is available only after the driver stack is started!.
- //
- if (deviceExtension->NextLowerDriver->Characteristics & FILE_REMOVABLE_MEDIA) {
-
- DeviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
- }
-
-#ifdef IOCTL_INTERFACE
- //
- // If the PreviousPnPState is stopped then we are being stopped temporarily
- // and restarted for resource rebalance.
- //
- if(Stopped != deviceExtension->PreviousPnPState) {
- //
- // Device is started for the first time.
- //
- FilterCreateControlObject(DeviceObject);
- }
-#endif
- ListStartDevice(DeviceObject);
- }
-
- Irp->IoStatus.Status = status;
- IoCompleteRequest (Irp, IO_NO_INCREMENT);
- IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);
- return status;
-
- case IRP_MN_REMOVE_DEVICE:
-
- //
- // Wait for all outstanding requests to complete
- //
- DebugPrint(("Waiting for outstanding requests\n"));
- IoReleaseRemoveLockAndWait(&deviceExtension->RemoveLock, Irp);
-
- IoSkipCurrentIrpStackLocation(Irp);
-
- status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);
-
- SET_NEW_PNP_STATE(deviceExtension, Deleted);
-
-#ifdef IOCTL_INTERFACE
- FilterDeleteControlObject();
-#endif
-
- ListRemoveDevice(DeviceObject);
-
- IoDetachDevice(deviceExtension->NextLowerDriver);
- IoDeleteDevice(DeviceObject);
- return status;
-
-
- case IRP_MN_QUERY_STOP_DEVICE:
- SET_NEW_PNP_STATE(deviceExtension, StopPending);
- status = STATUS_SUCCESS;
- break;
-
- case IRP_MN_CANCEL_STOP_DEVICE:
-
- //
- // Check to see whether you have received cancel-stop
- // without first receiving a query-stop. This could happen if someone
- // above us fails a query-stop and passes down the subsequent
- // cancel-stop.
- //
-
- if(StopPending == deviceExtension->DevicePnPState)
- {
- //
- // We did receive a query-stop, so restore.
- //
- RESTORE_PREVIOUS_PNP_STATE(deviceExtension);
- }
- status = STATUS_SUCCESS; // We must not fail this IRP.
- break;
-
- case IRP_MN_STOP_DEVICE:
- SET_NEW_PNP_STATE(deviceExtension, Stopped);
- status = STATUS_SUCCESS;
- break;
-
- case IRP_MN_QUERY_REMOVE_DEVICE:
-
- SET_NEW_PNP_STATE(deviceExtension, RemovePending);
- status = STATUS_SUCCESS;
- break;
-
- case IRP_MN_SURPRISE_REMOVAL:
-
- SET_NEW_PNP_STATE(deviceExtension, SurpriseRemovePending);
- ListRemoveDevice(DeviceObject);
- status = STATUS_SUCCESS;
- break;
-
- case IRP_MN_CANCEL_REMOVE_DEVICE:
-
- //
- // Check to see whether you have received cancel-remove
- // without first receiving a query-remove. This could happen if
- // someone above us fails a query-remove and passes down the
- // subsequent cancel-remove.
- //
-
- if(RemovePending == deviceExtension->DevicePnPState)
- {
- //
- // We did receive a query-remove, so restore.
- //
- RESTORE_PREVIOUS_PNP_STATE(deviceExtension);
- }
-
- status = STATUS_SUCCESS; // We must not fail this IRP.
- break;
-
- case IRP_MN_DEVICE_USAGE_NOTIFICATION:
-
- //
- // On the way down, pageable might become set. Mimic the driver
- // above us. If no one is above us, just set pageable.
- //
- if ((DeviceObject->AttachedDevice == NULL) ||
- (DeviceObject->AttachedDevice->Flags & DO_POWER_PAGABLE)) {
-
- DeviceObject->Flags |= DO_POWER_PAGABLE;
- }
-
- IoCopyCurrentIrpStackLocationToNext(Irp);
-
- IoSetCompletionRoutine(
- Irp,
- FilterDeviceUsageNotificationCompletionRoutine,
- NULL,
- TRUE,
- TRUE,
- TRUE
- );
-
- return IoCallDriver(deviceExtension->NextLowerDriver, Irp);
-
- case IRP_MN_QUERY_DEVICE_RELATIONS:
- case IRP_MN_QUERY_ID:
- case IRP_MN_QUERY_DEVICE_TEXT:
-#ifdef DEBUG
- case IRP_MN_QUERY_CAPABILITIES:
-#endif
- //
- // On the way down, pageable might become set. Mimic the driver
- // above us. If no one is above us, just set pageable.
- //
- if ((DeviceObject->AttachedDevice == NULL) ||
- (DeviceObject->AttachedDevice->Flags & DO_POWER_PAGABLE)) {
-
- DeviceObject->Flags |= DO_POWER_PAGABLE;
- }
-
- IoCopyCurrentIrpStackLocationToNext(Irp);
-
- IoSetCompletionRoutine(
- Irp,
- VBoxUSBPnPCompletion,
- NULL,
- TRUE,
- TRUE,
- TRUE
- );
-
- return IoCallDriver(deviceExtension->NextLowerDriver, Irp);
-
- default:
- //
- // If you don't handle any IRP you must leave the
- // status as is.
- //
- status = Irp->IoStatus.Status;
-
- break;
- }
-
- //
- // Pass the IRP down and forget it.
- //
- Irp->IoStatus.Status = status;
- IoSkipCurrentIrpStackLocation (Irp);
- status = IoCallDriver (deviceExtension->NextLowerDriver, Irp);
- IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);
-
- return status;
-}
-
-NTSTATUS
-FilterStartCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-/*++
-Routine Description:
- A completion routine for use when calling the lower device objects to
- which our filter deviceobject is attached.
-
-Arguments:
-
- DeviceObject - Pointer to deviceobject
- Irp - Pointer to a PnP Irp.
- Context - NULL
-Return Value:
-
- NT Status is returned.
-
---*/
-
-{
- PKEVENT event = (PKEVENT)Context;
-
- UNREFERENCED_PARAMETER (DeviceObject);
-
- //
- // If the lower driver didn't return STATUS_PENDING, we don't need to
- // set the event because we won't be waiting on it.
- // This optimization avoids grabbing the dispatcher lock, and improves perf.
- //
- if (Irp->PendingReturned == TRUE) {
- KeSetEvent (event, IO_NO_INCREMENT, FALSE);
- }
-
- //
- // The dispatch routine will have to call IoCompleteRequest
- //
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-
-}
-
-NTSTATUS
-FilterDeviceUsageNotificationCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-/*++
-Routine Description:
- A completion routine for use when calling the lower device objects to
- which our filter deviceobject is attached.
-
-Arguments:
-
- DeviceObject - Pointer to deviceobject
- Irp - Pointer to a PnP Irp.
- Context - NULL
-Return Value:
-
- NT Status is returned.
-
---*/
-
-{
- PDEVICE_EXTENSION deviceExtension;
-
- UNREFERENCED_PARAMETER(Context);
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
-
- if (Irp->PendingReturned) {
-
- IoMarkIrpPending(Irp);
- }
-
- //
- // On the way up, pageable might become clear. Mimic the driver below us.
- //
- if (!(deviceExtension->NextLowerDriver->Flags & DO_POWER_PAGABLE)) {
-
- DeviceObject->Flags &= ~DO_POWER_PAGABLE;
- }
-
- IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);
-
- return STATUS_CONTINUE_COMPLETION;
-
-}
-
-NTSTATUS
-FilterDispatchPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine is the dispatch routine for power irps.
-
-Arguments:
-
- DeviceObject - Pointer to the device object.
-
- Irp - Pointer to the request packet.
-
-Return Value:
-
- NT Status code
---*/
-{
- PDEVICE_EXTENSION deviceExtension;
- NTSTATUS status;
-
- deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
- if (!NT_SUCCESS (status)) { // may be device is being removed.
- Irp->IoStatus.Status = status;
- PoStartNextPowerIrp(Irp);
- IoCompleteRequest (Irp, IO_NO_INCREMENT);
- return status;
- }
-
- PoStartNextPowerIrp(Irp);
- IoSkipCurrentIrpStackLocation(Irp);
- status = PoCallDriver(deviceExtension->NextLowerDriver, Irp);
- IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);
- return status;
-}
-
-
-
-VOID
-FilterUnload(
- IN PDRIVER_OBJECT DriverObject
- )
-/*++
-
-Routine Description:
-
- Free all the allocated resources in DriverEntry, etc.
-
-Arguments:
-
- DriverObject - pointer to a driver object.
-
-Return Value:
-
- VOID.
-
---*/
-{
- PAGED_CODE ();
-
- //
- // The device object(s) should be NULL now
- // (since we unload, all the devices objects associated with this
- // driver must be deleted.
- //
- ASSERT(DriverObject->DeviceObject == NULL);
-
- //
- // We should not be unloaded until all the devices we control
- // have been removed from our queue.
- //
- DebugPrint (("unload\n"));
-
- return;
-}
-
-#ifdef IOCTL_INTERFACE
-NTSTATUS
-FilterCreateControlObject(
- IN PDEVICE_OBJECT DeviceObject
-)
-{
- UNICODE_STRING ntDeviceName;
- UNICODE_STRING symbolicLinkName;
- PCONTROL_DEVICE_EXTENSION deviceExtension;
- NTSTATUS status = STATUS_UNSUCCESSFUL;
-
- PAGED_CODE();
-
- //
- // Using unsafe function so that the IRQL remains at PASSIVE_LEVEL.
- // IoCreateDeviceSecure & IoCreateSymbolicLink must be called at
- // PASSIVE_LEVEL.
- //
- ExAcquireFastMutexUnsafe(&ControlMutex);
-
- //
- // If this is a first instance of the device, then create a controlobject
- // and register dispatch points to handle ioctls.
- //
- if(1 == ++InstanceCount)
- {
-
- //
- // Initialize the unicode strings
- //
- RtlInitUnicodeString(&ntDeviceName, USBFLT_NTDEVICE_NAME_STRING);
- RtlInitUnicodeString(&symbolicLinkName, USBFLT_SYMBOLIC_NAME_STRING);
-
- status = IoCreateDevice(DeviceObject->DriverObject,
- sizeof(CONTROL_DEVICE_EXTENSION),
- &ntDeviceName,
- FILE_DEVICE_UNKNOWN,
- 0,
- FALSE,
- &ControlDeviceObject);
-
- if (NT_SUCCESS( status )) {
-
- ControlDeviceObject->Flags |= DO_BUFFERED_IO;
-
- status = IoCreateSymbolicLink( &symbolicLinkName, &ntDeviceName );
-
- if ( !NT_SUCCESS( status )) {
- IoDeleteDevice(ControlDeviceObject);
- DebugPrint(("IoCreateSymbolicLink failed %x\n", status));
- goto End;
- }
-
- deviceExtension = ControlDeviceObject->DeviceExtension;
- deviceExtension->ControlData = NULL;
- deviceExtension->Deleted = FALSE;
-
- ControlDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-
- }
- else {
- DebugPrint(("IoCreateDevice failed %x\n", status));
- }
- }
-
-End:
-
- ExReleaseFastMutexUnsafe(&ControlMutex);
- return status;
-
-}
-
-VOID
-FilterDeleteControlObject(
-)
-{
- UNICODE_STRING symbolicLinkName;
- PCONTROL_DEVICE_EXTENSION deviceExtension;
-
- PAGED_CODE();
-
- ExAcquireFastMutexUnsafe (&ControlMutex);
-
- //
- // If this is the last instance of the device then delete the controlobject
- // and symbolic link to enable the pnp manager to unload the driver.
- //
-
- if(!(--InstanceCount) && ControlDeviceObject)
- {
- DebugPrint(("FilterDeleteControlObject -> instancecnt=0\n"));
- RtlInitUnicodeString(&symbolicLinkName, USBFLT_SYMBOLIC_NAME_STRING);
- deviceExtension = ControlDeviceObject->DeviceExtension;
- deviceExtension->Deleted = TRUE;
- IoDeleteSymbolicLink(&symbolicLinkName);
- IoDeleteDevice(ControlDeviceObject);
- ControlDeviceObject = NULL;
- }
-
- ExReleaseFastMutexUnsafe (&ControlMutex);
-
-}
-
-
-NTSTATUS
-FilterDispatchIo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-
-Routine Description:
-
- This routine is the dispatch routine for non passthru irps.
- We will check the input device object to see if the request
- is meant for the control device object. If it is, we will
- handle and complete the IRP, if not, we will pass it down to
- the lower driver.
-
-Arguments:
-
- DeviceObject - Pointer to the device object.
-
- Irp - Pointer to the request packet.
-
-Return Value:
-
- NT Status code
---*/
-{
- PIO_STACK_LOCATION irpStack;
- NTSTATUS status;
- PCONTROL_DEVICE_EXTENSION deviceExtension;
-
- PAGED_CODE();
-
- //
- // Please note that this is a common dispatch point for controlobject and
- // filter deviceobject attached to the pnp stack.
- //
- if(DeviceObject != ControlDeviceObject) {
- //
- // We will just the request down as we are not interested in handling
- // requests that come on the PnP stack.
- //
- return FilterPass(DeviceObject, Irp);
- }
-
- deviceExtension = ControlDeviceObject->DeviceExtension;
-
- //
- // Else this is targeted at our control deviceobject so let's handle it.
- // Here we will handle the IOCTl requests that come from the app.
- // We don't have to worry about acquiring remlocks for I/Os that come
- // on our control object because the I/O manager takes reference on our
- // deviceobject when it initiates a request to our device and that keeps
- // our driver from unloading when we have pending I/Os. But we still
- // have to watch out for a scenario where another driver can send
- // requests to our deviceobject directly without opening an handle.
- //
- if(!deviceExtension->Deleted) { //if not deleted
- status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- irpStack = IoGetCurrentIrpStackLocation (Irp);
-
- switch (irpStack->MajorFunction) {
- case IRP_MJ_CREATE:
- DebugPrint(("Create \n"));
- VBoxUSBCreate();
- break;
-
- case IRP_MJ_CLOSE:
- DebugPrint(("Close \n"));
- VBoxUSBClose();
- break;
-
- case IRP_MJ_CLEANUP:
- DebugPrint(("Cleanup \n"));
- break;
-
- case IRP_MJ_DEVICE_CONTROL:
- status = VBoxUSBDispatchIO(DeviceObject, Irp);
- break;
-
- default:
- break;
- }
- } else {
- ASSERTMSG(FALSE, "Requests being sent to a dead device\n");
- status = STATUS_DEVICE_REMOVED;
- }
- Irp->IoStatus.Status = status;
- IoCompleteRequest (Irp, IO_NO_INCREMENT);
- return status;
-}
-
-#endif
-
-#ifdef DEBUG
-
-PCHAR
-PnPMinorFunctionString (
- UCHAR MinorFunction
-)
-{
- switch (MinorFunction)
- {
- case IRP_MN_START_DEVICE:
- return "IRP_MN_START_DEVICE";
- case IRP_MN_QUERY_REMOVE_DEVICE:
- return "IRP_MN_QUERY_REMOVE_DEVICE";
- case IRP_MN_REMOVE_DEVICE:
- return "IRP_MN_REMOVE_DEVICE";
- case IRP_MN_CANCEL_REMOVE_DEVICE:
- return "IRP_MN_CANCEL_REMOVE_DEVICE";
- case IRP_MN_STOP_DEVICE:
- return "IRP_MN_STOP_DEVICE";
- case IRP_MN_QUERY_STOP_DEVICE:
- return "IRP_MN_QUERY_STOP_DEVICE";
- case IRP_MN_CANCEL_STOP_DEVICE:
- return "IRP_MN_CANCEL_STOP_DEVICE";
- case IRP_MN_QUERY_DEVICE_RELATIONS:
- return "IRP_MN_QUERY_DEVICE_RELATIONS";
- case IRP_MN_QUERY_INTERFACE:
- return "IRP_MN_QUERY_INTERFACE";
- case IRP_MN_QUERY_CAPABILITIES:
- return "IRP_MN_QUERY_CAPABILITIES";
- case IRP_MN_QUERY_RESOURCES:
- return "IRP_MN_QUERY_RESOURCES";
- case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
- return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS";
- case IRP_MN_QUERY_DEVICE_TEXT:
- return "IRP_MN_QUERY_DEVICE_TEXT";
- case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
- return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS";
- case IRP_MN_READ_CONFIG:
- return "IRP_MN_READ_CONFIG";
- case IRP_MN_WRITE_CONFIG:
- return "IRP_MN_WRITE_CONFIG";
- case IRP_MN_EJECT:
- return "IRP_MN_EJECT";
- case IRP_MN_SET_LOCK:
- return "IRP_MN_SET_LOCK";
- case IRP_MN_QUERY_ID:
- return "IRP_MN_QUERY_ID";
- case IRP_MN_QUERY_PNP_DEVICE_STATE:
- return "IRP_MN_QUERY_PNP_DEVICE_STATE";
- case IRP_MN_QUERY_BUS_INFORMATION:
- return "IRP_MN_QUERY_BUS_INFORMATION";
- case IRP_MN_DEVICE_USAGE_NOTIFICATION:
- return "IRP_MN_DEVICE_USAGE_NOTIFICATION";
- case IRP_MN_SURPRISE_REMOVAL:
- return "IRP_MN_SURPRISE_REMOVAL";
-
- default:
- return "unknown_pnp_irp";
- }
-}
-
-#endif
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilter.h b/src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilter.h
deleted file mode 100644
index 9f1091479..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilter.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- PURPOSE.
-
-Module Name:
-
- filter.h
-
-Abstract:
-
- Contains structure definitions and function prototypes for filter driver.
-
-Environment:
-
- Kernel mode
-
-Revision History:
-
- Eliyas Yakub Oct 29 1998
-
---*/
-#include <ntddk.h>
-#include <wdmsec.h> // for IoCreateDeviceSecure
-#include <initguid.h>
-
-#define IOCTL_INTERFACE 1
-
-#if !defined(_FILTER_H_)
-#define _FILTER_H_
-
-#define DRIVERNAME "VBoxUSBFlt.sys: "
-
-
-#ifdef DEBUG
-#define DebugPrint(_x_) DbgPrint _x_
-
-#define TRAP() DbgBreakPoint()
-
-#else
-#define DebugPrint(_x_)
-#define TRAP()
-#endif
-
-
-#ifndef STATUS_CONTINUE_COMPLETION //required to build driver in Win2K and XP build environment
-//
-// This value should be returned from completion routines to continue
-// completing the IRP upwards. Otherwise, STATUS_MORE_PROCESSING_REQUIRED
-// should be returned.
-//
-#define STATUS_CONTINUE_COMPLETION STATUS_SUCCESS
-
-#endif
-
-#define POOL_TAG 'liFT'
-
-//
-// These are the states Filter transition to upon
-// receiving a specific PnP Irp. Refer to the PnP Device States
-// diagram in DDK documentation for better understanding.
-//
-
-typedef enum _DEVICE_PNP_STATE {
-
- NotStarted = 0, // Not started yet
- Started, // Device has received the START_DEVICE IRP
- StopPending, // Device has received the QUERY_STOP IRP
- Stopped, // Device has received the STOP_DEVICE IRP
- RemovePending, // Device has received the QUERY_REMOVE IRP
- SurpriseRemovePending, // Device has received the SURPRISE_REMOVE IRP
- Deleted // Device has received the REMOVE_DEVICE IRP
-
-} DEVICE_PNP_STATE;
-
-#define INITIALIZE_PNP_STATE(_Data_) \
- (_Data_)->DevicePnPState = NotStarted;\
- (_Data_)->PreviousPnPState = NotStarted;
-
-#define SET_NEW_PNP_STATE(_Data_, _state_) \
- (_Data_)->PreviousPnPState = (_Data_)->DevicePnPState;\
- (_Data_)->DevicePnPState = (_state_);
-
-#define RESTORE_PREVIOUS_PNP_STATE(_Data_) \
- (_Data_)->DevicePnPState = (_Data_)->PreviousPnPState;\
-
-
-typedef struct _DEVICE_EXTENSION
-{
- //
- // A back pointer to the device object.
- //
-
- PDEVICE_OBJECT Self;
-
- //
- // The top of the stack before this filter was added.
- //
-
- PDEVICE_OBJECT NextLowerDriver;
-
- //
- // current PnP state of the device
- //
-
- DEVICE_PNP_STATE DevicePnPState;
-
- //
- // Remembers the previous pnp state
- //
-
- DEVICE_PNP_STATE PreviousPnPState;
-
- //
- // Removelock to track IRPs so that device can be removed and
- // the driver can be unloaded safely.
- //
- IO_REMOVE_LOCK RemoveLock;
-
-
- BOOLEAN fHookDevice;
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef DEBUG
-PCHAR
-PnPMinorFunctionString (
- UCHAR MinorFunction
-);
-#endif
-
-NTSTATUS
-FilterAddDevice(
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT PhysicalDeviceObject
- );
-
-
-NTSTATUS
-FilterDispatchPnp (
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-FilterDispatchPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-VOID
-FilterUnload(
- IN PDRIVER_OBJECT DriverObject
- );
-
-NTSTATUS
-FilterPass (
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- );
-
-NTSTATUS
-FilterStartCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- );
-
-NTSTATUS
-FilterDeviceUsageNotificationCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- );
-
-int ListAddDevice(PDEVICE_OBJECT pdo, PDEVICE_OBJECT fdo);
-int ListKnownPDO(PDEVICE_OBJECT pdo);
-int ListRemoveDevice(PDEVICE_OBJECT fdo);
-int ListDeviceIsCaptured(PDEVICE_OBJECT fdo);
-int ListStartDevice(PDEVICE_OBJECT fdo);
-int ListCaptureDevice(PDEVICE_OBJECT fdo);
-
-#ifdef IOCTL_INTERFACE
-
-typedef struct _CONTROL_DEVICE_EXTENSION {
-
- ULONG Deleted; // False if the deviceobject is valid, TRUE if it's deleted
-
- PVOID ControlData; // Store your control data here
-
-} CONTROL_DEVICE_EXTENSION, *PCONTROL_DEVICE_EXTENSION;
-
-NTSTATUS
-FilterCreateControlObject(
- IN PDEVICE_OBJECT DeviceObject
-);
-
-VOID
-FilterDeleteControlObject(
- );
-
-NTSTATUS
-FilterDispatchIo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-#endif
-
-NTSTATUS _stdcall VBoxUSBPnPCompletion(DEVICE_OBJECT *fido, IRP *Irp, void *context);
-NTSTATUS _stdcall VBoxUSBDispatchIO(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS _stdcall VBoxUSBCreate();
-NTSTATUS _stdcall VBoxUSBClose();
-NTSTATUS _stdcall VBoxUSBInit();
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilter.rc b/src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilter.rc
deleted file mode 100644
index 50761d3ca..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Filter/USBFilter.rc
+++ /dev/null
@@ -1,50 +0,0 @@
-/* $Id: USBFilter.rc $ */
-/** @file
- * VBoxUSBFilter - Resource file containing version info and icon.
- */
-
-/*
- * Copyright (C) 2006-2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#include <windows.h>
-#include <VBox/version.h>
-
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS 0x0L
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_DRV
- FILESUBTYPE VFT2_DRV_SYSTEM
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", "VirtualBox USB Filter Driver\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", "VBoxUSBFlt.sys\0"
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
- VALUE "OriginalFilename", "VBoxUSBFlt.sys\0"
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Filter/VBoxUSBFlt.inf b/src/VBox/HostDrivers/VBoxUSB/win/Filter/VBoxUSBFlt.inf
deleted file mode 100644
index 08adf145d..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Filter/VBoxUSBFlt.inf
+++ /dev/null
@@ -1,70 +0,0 @@
-;
-; VBox host drivers - USB drivers - Win32 USB filter driver
-;
-; Installation file
-;
-; Copyright (C) 2006-2007 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.
-;
-
-[Version]
-Signature = "$Windows NT$"
-Provider = %ORACLE%
-;edit-DriverVer = 08/26/2008,2.00.0000
-DriverPackageType = ClassFilter
-;cat CatalogFile = VBoxUSBFlt.cat
-
-[DefaultInstall.NT]
-CopyFiles = VBoxUSBFilter.CopyFiles
-AddReg = VBoxUSBFilter.AddReg
-
-[VBoxUSBFilter.CopyFiles]
-VBoxUSBFlt.sys
-
-[VBoxUSBFilter.AddReg]
-HKLM, System\CurrentControlSet\Control\Class\{36FC9E60-C465-11CF-8056-444553540000}, LowerFilters, 0x00010000, VBoxUSBFlt
-
-[DefaultInstall.NT.Services]
-AddService = VBoxUSBFlt, , VBoxUSBFlt_Service_Inst, VBoxUSBFlt_EventLog_Inst
-
-[VBoxUSBFlt_Service_Inst]
-DisplayName = %VBoxUSBFlt.SvcDesc%
-ServiceType = %SERVICE_KERNEL_DRIVER%
-StartType = %SERVICE_DEMAND_START%
-ErrorControl = %SERVICE_ERROR_IGNORE%
-ServiceBinary = %12%\VBoxUSBFlt.sys
-
-[VBoxUSBFlt_EventLog_Inst]
-AddReg = VBoxUSBFlt_EventLog_AddReg
-
-[VBoxUSBFlt_EventLog_AddReg]
-HKR,,EventMessageFile, %REG_EXPAND_SZ%,"%%SystemRoot%%\System32\IoLogMsg.dll;%%SystemRoot%%\System32\drivers\VBoxUSBFlt.sys"
-HKR,,TypesSupported, %REG_DWORD%, 7
-
-[SourceDisksNames]
-1 = %VBoxUSBFlt.MediaDesc%
-
-[SourceDisksFiles]
-VBoxUSBFlt.sys = 1
-
-[DestinationDirs]
-DefaultDestDir = 12 ; DIRID_DRIVERS
-
-[Strings]
-ORACLE = "Oracle Corporation"
-VBoxUSBFlt.SvcDesc = "VirtualBox USB Filter Driver"
-VBoxUSBFlt.MediaDesc = "VirtualBox USB Filter Driver Disc"
-
-; Useful constants
-SERVICE_KERNEL_DRIVER = 1
-SERVICE_DEMAND_START = 3
-SERVICE_ERROR_IGNORE = 0
-REG_EXPAND_SZ = 0x00020000
-REG_DWORD = 0x00010001
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Install/USBInstall.cpp b/src/VBox/HostDrivers/VBoxUSB/win/Install/USBInstall.cpp
index f1ed807dc..ab42f3550 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/Install/USBInstall.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/win/Install/USBInstall.cpp
@@ -32,6 +32,28 @@
#include <VBox/err.h>
#include <stdio.h>
+#include <VBox/VBoxDrvCfg-win.h>
+
+static DECLCALLBACK(void) vboxUsbLog(VBOXDRVCFG_LOG_SEVERITY enmSeverity, char * msg, void * pvContext)
+{
+ switch (enmSeverity)
+ {
+ case VBOXDRVCFG_LOG_SEVERITY_FLOW:
+ case VBOXDRVCFG_LOG_SEVERITY_REGULAR:
+ break;
+ case VBOXDRVCFG_LOG_SEVERITY_REL:
+ RTPrintf("%s", msg);
+ break;
+ default:
+ break;
+ }
+}
+
+static DECLCALLBACK(void) vboxUsbPanic(void * pvPanic)
+{
+ AssertFailed();
+}
+
int usblibOsCreateService(void);
int __cdecl main(int argc, char **argv)
@@ -42,41 +64,36 @@ int __cdecl main(int argc, char **argv)
return 1;
}
+ VBoxDrvCfgLoggerSet(vboxUsbLog, NULL);
+ VBoxDrvCfgPanicSet(vboxUsbPanic, NULL);
+
RTPrintf("USB installation\n");
int rc = usblibOsCreateService();
if (RT_SUCCESS(rc))
{
- LPSTR lpszFilePart;
- TCHAR szFullPath[MAX_PATH];
- TCHAR szCurDir[MAX_PATH];
+ LPWSTR lpszFilePart;
+ WCHAR szFullPath[MAX_PATH];
DWORD len;
- len = GetFullPathName(".\\VBoxUSB.inf", sizeof(szFullPath), szFullPath, &lpszFilePart);
+ len = GetFullPathNameW(L".\\VBoxUSB.inf", RT_ELEMENTS(szFullPath), szFullPath, &lpszFilePart);
Assert(len);
- if (GetCurrentDirectory(sizeof(szCurDir), szCurDir) == 0)
+ HRESULT hr = VBoxDrvCfgInfInstall(szFullPath);
+ if (hr == S_OK)
{
- rc = RTErrConvertFromWin32(GetLastError());
- RTPrintf("GetCurrentDirectory failed with rc=%Rrc\n", rc);
+ RTPrintf("Installation successful.\n");
}
else
{
- /* Copy INF file to Windows\INF, so Windows will automatically install it when our USB device is detected */
- BOOL b = SetupCopyOEMInf(szFullPath, NULL, SPOST_PATH, 0, NULL, 0, NULL, NULL);
- if (b == FALSE)
- {
- rc = RTErrConvertFromWin32(GetLastError());
- RTPrintf("SetupCopyOEMInf failed with rc=%Rrc\n", rc);
- }
- else
- {
- RTPrintf("Installation successful.\n");
- }
+ rc = -1;
}
}
+ if (RT_SUCCESS(rc))
+ rc = 0;
+
/** @todo RTR3Term(); */
return rc;
}
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Install/USBUninstall.cpp b/src/VBox/HostDrivers/VBoxUSB/win/Install/USBUninstall.cpp
index 807eb3fef..f4690a74b 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/Install/USBUninstall.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/win/Install/USBUninstall.cpp
@@ -22,41 +22,60 @@
#include <windows.h>
#include <setupapi.h>
#include <newdev.h>
+
#include <iprt/assert.h>
#include <iprt/err.h>
#include <iprt/param.h>
#include <iprt/path.h>
#include <iprt/string.h>
#include <VBox/err.h>
+#include <VBox/VBoxDrvCfg-win.h>
#include <stdio.h>
int usblibOsStopService(void);
int usblibOsDeleteService(void);
+static DECLCALLBACK(void) vboxUsbLog(VBOXDRVCFG_LOG_SEVERITY enmSeverity, char * msg, void * pvContext)
+{
+ switch (enmSeverity)
+ {
+ case VBOXDRVCFG_LOG_SEVERITY_FLOW:
+ case VBOXDRVCFG_LOG_SEVERITY_REGULAR:
+ break;
+ case VBOXDRVCFG_LOG_SEVERITY_REL:
+ printf("%s", msg);
+ break;
+ default:
+ break;
+ }
+}
-int __cdecl main(int argc, char **argv)
+static DECLCALLBACK(void) vboxUsbPanic(void * pvPanic)
{
- BOOL rc;
- TCHAR szFullPath[MAX_PATH];
- CHAR *lpszFilePart;
- int len;
+ AssertFailed();
+}
+
+int __cdecl main(int argc, char **argv)
+{
printf("USB uninstallation\n");
+ VBoxDrvCfgLoggerSet(vboxUsbLog, NULL);
+ VBoxDrvCfgPanicSet(vboxUsbPanic, NULL);
+
usblibOsStopService();
usblibOsDeleteService();
- len = GetFullPathName(".\\VBoxUSB.inf", sizeof(szFullPath), szFullPath, &lpszFilePart);
- Assert(len);
-
- /* Remove the inf plus all associated files. */
- rc = SetupUninstallOEMInf(szFullPath, SUOI_FORCEDELETE, NULL);
- if (rc == FALSE)
+ HRESULT hr = VBoxDrvCfgInfUninstallAllF(L"USB", L"USB\\VID_80EE&PID_CAFE", SUOI_FORCEDELETE);
+ if (hr != S_OK)
{
- printf("SetupUninstallOEMInf failed with rc=%x\n", GetLastError());
+ printf("SetupUninstallOEMInf failed with hr=0x%x\n", hr);
return 1;
}
+
+ printf("USB uninstallation succeeded!\n");
+
return 0;
}
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Makefile.kmk b/src/VBox/HostDrivers/VBoxUSB/win/Makefile.kmk
index b8e265931..f65938649 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/Makefile.kmk
+++ b/src/VBox/HostDrivers/VBoxUSB/win/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37801 2011-07-06 12:16:41Z vboxsync $
## @file
# Sub-Makefile for the Windows USB drivers.
#
@@ -41,36 +41,18 @@ VBoxUSB_DEFS = IN_RT_R0 IN_SUP_R0
VBoxUSB_LDFLAGS.x86 = -Entry:DriverEntry@8
VBoxUSB_LDFLAGS.amd64 = -Entry:DriverEntry
VBoxUSB_SOURCES = \
- Device/vboxusb.cpp \
- Device/vboxdev.cpp \
- Device/vboxpnp.cpp \
- Device/vboxpwr.cpp \
- Device/vboxrwr.cpp \
- Device/vboxusb.rc
+ dev/VBoxUsbDev.cpp \
+ dev/VBoxUsbRt.cpp \
+ dev/VBoxUsbPnP.cpp \
+ dev/VBoxUsbPwr.cpp \
+ cmn/VBoxUsbTool.cpp \
+ cmn/VBoxDrvTool.cpp \
+ dev/VBoxUsbDev.rc
VBoxUSB_LIBS = \
$(PATH_SDK_W2K3DDK_LIB)/ntoskrnl.lib \
$(PATH_SDK_W2K3DDK_LIB)/hal.lib \
$(PATH_LIB)/RuntimeR0Drv$(VBOX_SUFF_LIB) \
- $(TARGET_usbd)
-
-#
-# VBoxUSBFlt
-#
-VBoxUSBFlt_TEMPLATE = VBOXR0DRV
-VBoxUSBFlt_SDKS = W2K3DDK WINPSDKINCS
-VBoxUSBFlt_DEFS = IN_SUP_R0 i386=1 STD_CALL CONDITION_HANDLING=1 NT_INST=0 \
- WIN32=100 _NT1X_=100 WINNT=1 _WIN32_WINNT=0x0501 WINVER=0x0501 _WIN32_IE=0x0600 WIN32_LEAN_AND_MEAN=1
-VBoxUSBFlt_LDFLAGS.x86 = -Entry:DriverEntry@8
-VBoxUSBFlt_LDFLAGS.amd64 = -Entry:DriverEntry
-VBoxUSBFlt_SOURCES = \
- Filter/USBFilter.c \
- Filter/USBFilt-win32.cpp \
- Filter/USBFilter.rc
-VBoxUSBFlt_LIBS = \
- $(PATH_SDK_W2K3DDK_LIB)/ntoskrnl.lib \
- $(PATH_SDK_W2K3DDK_LIB)/hal.lib \
- $(PATH_LIB)/RuntimeR0Drv$(VBOX_SUFF_LIB) \
- $(TARGET_usbd)
+ $(usbd_1_TARGET)
#
# VBoxUSBMon
@@ -86,17 +68,23 @@ VBoxUSBMon_DEFS = IN_RT_R0 IN_SUP_R0 i386=1 STD_CALL CONDITION_HANDLING=1
VBOXUSBFILTERMGR_USB_SPINLOCK
VBoxUSBMon_LDFLAGS.x86 = -Entry:DriverEntry@8
VBoxUSBMon_LDFLAGS.amd64 = -Entry:DriverEntry
+ifdef VBOX_USBMON_WITH_FILTER_AUTOAPPLY
+ VBoxUSBMon_DEFS += VBOX_USBMON_WITH_FILTER_AUTOAPPLY
+endif
VBoxUSBMon_SOURCES = \
- Monitor/USBMon.cpp \
- Monitor/USBMonFlt.cpp \
+ mon/VBoxUsbMon.cpp \
+ mon/VBoxUsbFlt.cpp \
+ mon/VBoxUsbHook.cpp \
+ cmn/VBoxUsbTool.cpp \
+ cmn/VBoxDrvTool.cpp \
../USBFilter.cpp \
../VBoxUSBFilterMgr.cpp \
- Monitor/USBMon.rc
+ mon/VBoxUsbMon.rc
VBoxUSBMon_LIBS = \
$(PATH_SDK_W2K3DDK_LIB)/ntoskrnl.lib \
$(PATH_SDK_W2K3DDK_LIB)/hal.lib \
$(PATH_LIB)/RuntimeR0Drv$(VBOX_SUFF_LIB) \
- $(TARGET_usbd)
+ $(usbd_1_TARGET)
#
# USBInstall
@@ -111,7 +99,9 @@ USBInstall_SOURCES = \
USBInstall_LIBS = \
$(PATH_SDK_W2K3DDK_LIB)/newdev.lib \
$(LIB_RUNTIME) \
- $(PATH_LIB)/SUPR3$(VBOX_SUFF_LIB)
+ $(PATH_LIB)/SUPR3$(VBOX_SUFF_LIB) \
+ $(VBoxDrvCfg_1_TARGET)
+
#
# USBUninstall
@@ -126,7 +116,8 @@ USBUninstall_SOURCES = \
USBUninstall_LIBS = \
$(PATH_SDK_W2K3DDK_LIB)/newdev.lib \
$(LIB_RUNTIME) \
- $(PATH_LIB)/SUPR3$(VBOX_SUFF_LIB)
+ $(PATH_LIB)/SUPR3$(VBOX_SUFF_LIB) \
+ $(VBoxDrvCfg_1_TARGET)
#
# USBTest
@@ -141,7 +132,8 @@ USBTest_SOURCES = \
USBTest_LIBS = \
$(PATH_SDK_W2K3DDK_LIB)/newdev.lib \
$(LIB_RUNTIME) \
- $(PATH_LIB)/SUPR3$(VBOX_SUFF_LIB)
+ $(PATH_LIB)/SUPR3$(VBOX_SUFF_LIB) \
+ $(VBoxDrvCfg_1_TARGET)
#
# Install the INF files.
@@ -156,15 +148,11 @@ install-infs_BLDDIRS = \
$(PATH_TARGET)/VBoxUSBCat.dir \
$(PATH_TARGET)/VBoxUSBMonCat.dir
-$(PATH_TARGET)/VBoxUSBCat.dir/VBoxUSB.inf: $(PATH_SUB_CURRENT)/Device/VBoxUSB.inf $(MAKEFILE_CURRENT) | $$(dir $$@)
- $(call MSG_GENERATE,install-infs,$@,$<)
- $(call VBOX_EDIT_INF_FN,$<,$@)
-
-$(PATH_TARGET)/VBoxUSBMonCat.dir/VBoxUSBMon.inf: $(PATH_SUB_CURRENT)/Monitor/VBoxUSBMon.inf $(MAKEFILE_CURRENT) | $$(dir $$@)
+$(PATH_TARGET)/VBoxUSBCat.dir/VBoxUSB.inf: $(PATH_SUB_CURRENT)/dev/VBoxUSB.inf $(MAKEFILE_CURRENT) | $$(dir $$@)
$(call MSG_GENERATE,install-infs,$@,$<)
$(call VBOX_EDIT_INF_FN,$<,$@)
-$(PATH_TARGET)/VBoxUSBFltCat.dir/VBoxUSBFlt.inf: $(PATH_SUB_CURRENT)/Filter/VBoxUSBFlt.inf $(MAKEFILE_CURRENT) | $$(dir $$@)
+$(PATH_TARGET)/VBoxUSBMonCat.dir/VBoxUSBMon.inf: $(PATH_SUB_CURRENT)/mon/VBoxUSBMon.inf $(MAKEFILE_CURRENT) | $$(dir $$@)
$(call MSG_GENERATE,install-infs,$@,$<)
$(call VBOX_EDIT_INF_FN,$<,$@)
@@ -175,7 +163,7 @@ install-infs_SOURCES += \
$(PATH_TARGET)/VBoxUSBMonCat.dir/VBoxUSBMon.cat \
$(PATH_TARGET)/VBoxUSBMonCat.dir/VBoxUSBMon.sys
-$(PATH_TARGET)/VBoxUSBCat.dir/VBoxUSB.sys: $$(TARGET_VBoxUSB) | $$(dir $$@)
+$(PATH_TARGET)/VBoxUSBCat.dir/VBoxUSB.sys: $$(VBoxUSB_1_TARGET) | $$(dir $$@)
$(INSTALL) -m 644 $< $(@D)
$(PATH_TARGET)/VBoxUSBCat.dir/VBoxUSB.cat: \
@@ -184,7 +172,7 @@ $(PATH_TARGET)/VBoxUSBCat.dir/VBoxUSB.cat: \
$(call MSG_TOOL,Inf2Cat,VBoxUSB-inf,$@,$<)
$(call VBOX_MAKE_CAT_FN, $(@D),$@)
-$(PATH_TARGET)/VBoxUSBMonCat.dir/VBoxUSBMon.sys: $$(TARGET_VBoxUSBMon) | $$(dir $$@)
+$(PATH_TARGET)/VBoxUSBMonCat.dir/VBoxUSBMon.sys: $$(VBoxUSBMon_1_TARGET) | $$(dir $$@)
$(INSTALL) -m 644 $< $(@D)
$(PATH_TARGET)/VBoxUSBMonCat.dir/VBoxUSBMon.cat: \
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMon.cpp b/src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMon.cpp
deleted file mode 100644
index 34564057e..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMon.cpp
+++ /dev/null
@@ -1,1007 +0,0 @@
-/** @file
- *
- * VBox USB drivers - USB Monitor driver - Win32 host:
- */
-
-/*
- * Copyright (C) 2006-2007 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-
-#include "USBMon.h"
-#include <VBox/usblib.h>
-#include <excpt.h>
-#include <stdio.h>
-
-/*
- * Note: Must match the VID & PID in the USB driver .inf file!!
- */
-/*
- BusQueryDeviceID USB\Vid_80EE&Pid_CAFE
- BusQueryInstanceID 2
- BusQueryHardwareIDs USB\Vid_80EE&Pid_CAFE&Rev_0100
- BusQueryHardwareIDs USB\Vid_80EE&Pid_CAFE
- BusQueryCompatibleIDs USB\Class_ff&SubClass_00&Prot_00
- BusQueryCompatibleIDs USB\Class_ff&SubClass_00
- BusQueryCompatibleIDs USB\Class_ff
-*/
-
-#define szBusQueryDeviceId L"USB\\Vid_80EE&Pid_CAFE"
-#define szBusQueryHardwareIDs L"USB\\Vid_80EE&Pid_CAFE&Rev_0100\0USB\\Vid_80EE&Pid_CAFE\0\0"
-#define szBusQueryCompatibleIDs L"USB\\Class_ff&SubClass_00&Prot_00\0USB\\Class_ff&SubClass_00\0USB\\Class_ff\0\0"
-
-#define szDeviceTextDescription L"VirtualBox USB"
-
-static PDEVICE_OBJECT ControlDeviceObject = NULL;
-static PDRIVER_DISPATCH pfnOldPnPHandler = 0;
-
-static struct
-{
- bool fValid;
-} InstalledPDOHooks[16] = {0};
-
-/**
- * Driver entry point.
- *
- * @returns appropriate status code.
- * @param pDrvObj Pointer to driver object.
- * @param pRegPath Registry base path.
- */
-NTSTATUS _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
-{
- NTSTATUS rc;
- UNICODE_STRING DevName;
- PDEVICE_OBJECT pDevObj;
-
- DebugPrint(("VBoxUSBMon::DriverEntry\n"));
-
- /*
- * Create device.
- * (That means creating a device object and a symbolic link so the DOS
- * subsystems (OS/2, win32, ++) can access the device.)
- */
- RtlInitUnicodeString(&DevName, USBMON_DEVICE_NAME_NT);
- rc = IoCreateDevice(pDrvObj, sizeof(DEVICE_EXTENSION), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj);
- if (NT_SUCCESS(rc))
- {
- UNICODE_STRING DosName;
-
- /* Save device object pointer in order to check whether we're being called in the entry points we register. */
- ControlDeviceObject = pDevObj;
-
- RtlInitUnicodeString(&DosName, USBMON_DEVICE_NAME_DOS);
- rc = IoCreateSymbolicLink(&DosName, &DevName);
- if (NT_SUCCESS(rc))
- {
- ULONG ulIndex;
- PDRIVER_DISPATCH *dispatch;
-
- /*
- * Initialize the device extension.
- */
- PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
- memset(pDevExt, 0, sizeof(*pDevExt));
-
- /*
- * Setup the driver entry points in pDrvObj.
- */
- for (ulIndex = 0, dispatch = pDrvObj->MajorFunction;
- ulIndex <= IRP_MJ_MAXIMUM_FUNCTION;
- ulIndex++, dispatch++) {
-
- *dispatch = VBoxUSBMonStub;
- }
-
- pDrvObj->DriverUnload = VBoxUSBMonUnload;
- pDrvObj->MajorFunction[IRP_MJ_CREATE] = VBoxUSBMonCreate;
- pDrvObj->MajorFunction[IRP_MJ_CLOSE] = VBoxUSBMonClose;
- pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxUSBMonDeviceControl;
-
-// pDrvObj->MajorFunction[IRP_MJ_PNP] = VBoxUSBMonDispatchPnp;
-// pDrvObj->MajorFunction[IRP_MJ_POWER] = VBoxUSBMonDispatchPower;
- /* Note: unable to unload driver if this is set: */
-//// pDrvObj->DriverExtension->AddDevice = VBoxUSBMonAddDevice;
-
- VBoxUSBInit();
- DebugPrint(("VBoxUSBMon::DriverEntry returning STATUS_SUCCESS\n"));
- return STATUS_SUCCESS;
- }
- else
- DebugPrint(("IoCreateSymbolicLink failed with rc=%#x!\n", rc));
-
- IoDeleteDevice(pDevObj);
- }
- else
- DebugPrint(("IoCreateDevice failed with rc=%#x!\n", rc));
-
- if (NT_SUCCESS(rc))
- rc = STATUS_INVALID_PARAMETER;
- DebugPrint(("VBoxUSBMon::DriverEntry returning %#x\n", rc));
- return rc;
-}
-
-/**
- * Uninstall the PnP irp hook
- *
- * @param pDevExt Device extension
- */
-void VBoxUSBUninstallPnPHook(PDEVICE_EXTENSION pDevExt)
-{
- NTSTATUS status;
- UNICODE_STRING szStandardHubName;
-
- szStandardHubName.Length = 0;
- szStandardHubName.MaximumLength = 0;
- szStandardHubName.Buffer = 0;
- RtlInitUnicodeString(&szStandardHubName, L"\\Driver\\usbhub");
-
- DebugPrint(("Unhook USB hub drivers\n"));
- for (int i = 0; i < RT_ELEMENTS(InstalledPDOHooks); i++)
- {
- char szHubName[32];
- UNICODE_STRING UnicodeName;
- ANSI_STRING AnsiName;
- PDEVICE_OBJECT pHubDevObj;
- PFILE_OBJECT pHubFileObj;
-
- /* Don't bother to check PDO's that we haven't hooked; might even lead to host crashes during shutdown as IoGetDeviceObjectPointer can reopen a driver. */
- if (!InstalledPDOHooks[i].fValid)
- continue;
-
- sprintf(szHubName, "\\Device\\USBPDO-%d", i);
-
- UnicodeName.Length = 0;
- UnicodeName.MaximumLength = 0;
- UnicodeName.Buffer = 0;
-
- RtlInitAnsiString(&AnsiName, szHubName);
- RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, TRUE);
-
- status = IoGetDeviceObjectPointer(&UnicodeName, FILE_READ_DATA, &pHubFileObj, &pHubDevObj);
- if (status == STATUS_SUCCESS)
- {
- DebugPrint(("IoGetDeviceObjectPointer for %s returned %p %p\n", szHubName, pHubDevObj, pHubFileObj));
-
- if ( pHubDevObj->DriverObject
- && pHubDevObj->DriverObject->DriverName.Buffer
- && pHubDevObj->DriverObject->DriverName.Length
- && !RtlCompareUnicodeString(&szStandardHubName, &pHubDevObj->DriverObject->DriverName, TRUE /* case insensitive */))
- {
-#if 0
- DebugPrint(("Associated driver"));
- DebugPrintUnicodeString(&pHubDevObj->DriverObject->DriverName);
-#endif
- DebugPrint(("pnp handler %p\n", pHubDevObj->DriverObject->MajorFunction[IRP_MJ_PNP]));
- InterlockedCompareExchangePointer((PVOID *)&pHubDevObj->DriverObject->MajorFunction[IRP_MJ_PNP], pfnOldPnPHandler, VBoxUSBMonPnPHook);
- }
- ObDereferenceObject(pHubFileObj);
- }
-// else
-// DebugPrint(("IoGetDeviceObjectPointer for %s returned %x\n", szHubName, status));
-
- RtlFreeUnicodeString(&UnicodeName);
- }
- pDevExt->fHookDevice = FALSE;
- pfnOldPnPHandler = NULL;
-}
-
-/**
- * Unload the driver.
- *
- * @param pDrvObj Driver object.
- */
-void _stdcall VBoxUSBMonUnload(PDRIVER_OBJECT pDrvObj)
-{
- PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDrvObj->DeviceObject->DeviceExtension;
-
- DebugPrint(("VBoxUSBMonUnload pDevExt=%p ControlDeviceObject=%p\n", pDevExt, ControlDeviceObject));
-
- Assert(!pfnOldPnPHandler);
- if (pfnOldPnPHandler) /* very bad! */
- VBoxUSBUninstallPnPHook(pDevExt);
-
- /* Clean up the filter manager */
- VBoxUSBTerm();
-
- /*
- * We ASSUME that it's not possible to unload a driver with open handles.
- * Start by deleting the symbolic link
- */
- UNICODE_STRING DosName;
- RtlInitUnicodeString(&DosName, USBMON_DEVICE_NAME_DOS);
- NTSTATUS rc = IoDeleteSymbolicLink(&DosName);
-
- IoDeleteDevice(pDrvObj->DeviceObject);
-}
-
-
-/**
- * Create (i.e. Open) file entry point.
- *
- * @param pDevObj Device object.
- * @param pIrp Request packet.
- */
-NTSTATUS _stdcall VBoxUSBMonCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
-{
- PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
- PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
- NTSTATUS status;
-
- DebugPrint(("VBoxUSBMonCreate\n"));
-
- /*
- * We are not remotely similar to a directory...
- * (But this is possible.)
- */
- if (pStack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
- {
- pIrp->IoStatus.Status = STATUS_NOT_A_DIRECTORY;
- pIrp->IoStatus.Information = 0;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return STATUS_NOT_A_DIRECTORY;
- }
-
- VBoxUSBCreate();
-
- if (InterlockedIncrement(&pDevExt->cOpened) == 1)
- {
- UNICODE_STRING szStandardHubName;
-
- pDevExt->fHookDevice = TRUE;
-
- szStandardHubName.Length = 0;
- szStandardHubName.MaximumLength = 0;
- szStandardHubName.Buffer = 0;
- RtlInitUnicodeString(&szStandardHubName, L"\\Driver\\usbhub");
-
- DebugPrint(("Hook USB hub drivers\n"));
- for (int i = 0; i < RT_ELEMENTS(InstalledPDOHooks); i++)
- {
- char szHubName[32];
- UNICODE_STRING UnicodeName;
- ANSI_STRING AnsiName;
- PDEVICE_OBJECT pHubDevObj;
- PFILE_OBJECT pHubFileObj;
-
- sprintf(szHubName, "\\Device\\USBPDO-%d", i);
-
- InstalledPDOHooks[i].fValid = false;
-
- UnicodeName.Length = 0;
- UnicodeName.MaximumLength = 0;
- UnicodeName.Buffer = 0;
-
- RtlInitAnsiString(&AnsiName, szHubName);
- RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, TRUE);
-
- status = IoGetDeviceObjectPointer(&UnicodeName, FILE_READ_DATA, &pHubFileObj, &pHubDevObj);
- if (status == STATUS_SUCCESS)
- {
- DebugPrint(("IoGetDeviceObjectPointer for %s returned %p %p\n", szHubName, pHubDevObj, pHubFileObj));
-
- if ( pHubDevObj->DriverObject
- && pHubDevObj->DriverObject->DriverName.Buffer
- && pHubDevObj->DriverObject->DriverName.Length
- && !RtlCompareUnicodeString(&szStandardHubName, &pHubDevObj->DriverObject->DriverName, TRUE /* case insensitive */))
- {
-#if 0
- DebugPrint(("Associated driver"));
- DebugPrintUnicodeString(&pHubDevObj->DriverObject->DriverName);
-#endif
- DebugPrint(("pnp handler %p\n", pHubDevObj->DriverObject->MajorFunction[IRP_MJ_PNP]));
- if ( !pfnOldPnPHandler
- || pHubDevObj->DriverObject->MajorFunction[IRP_MJ_PNP] == pfnOldPnPHandler)
- {
- InstalledPDOHooks[i].fValid = true;
- pfnOldPnPHandler = (PDRIVER_DISPATCH)InterlockedExchangePointer((PVOID *)&pHubDevObj->DriverObject->MajorFunction[IRP_MJ_PNP], VBoxUSBMonPnPHook);
- }
- }
- ObDereferenceObject(pHubFileObj);
- }
-// else
-// DebugPrint(("IoGetDeviceObjectPointer for %s returned %x\n", szHubName, status));
-
- RtlFreeUnicodeString(&UnicodeName);
- }
-
- //
- // Let us use remove lock to keep count of IRPs so that we don't
- // detach and delete our deviceobject until all pending I/Os in our
- // devstack are completed. Remlock is required to protect us from
- // various race conditions where our driver can get unloaded while we
- // are still running dispatch or completion code.
- //
-
- IoInitializeRemoveLock (&pDevExt->RemoveLock , POOL_TAG,
- 1, // MaxLockedMinutes
- 100); // HighWatermark, this parameter is
- // used only on checked build. Specifies
- // the maximum number of outstanding
- // acquisitions allowed on the lock
-
- DebugPrint(("VBoxUSBMon: remove lock = %x\n", pDevExt->RemoveLock.Common.RemoveEvent));
- }
-
- status = IoAcquireRemoveLock(&pDevExt->RemoveLock, ControlDeviceObject);
- if (!NT_SUCCESS(status))
- {
- DebugPrint(("IoAcquireRemoveLock failed with %x\n", status));
- pIrp->IoStatus.Status = status;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return status;
- }
-
- pIrp->IoStatus.Information = 0;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
-
- return STATUS_SUCCESS;
-}
-
-
-/**
- * Close file entry point.
- *
- * @param pDevObj Device object.
- * @param pIrp Request packet.
- */
-NTSTATUS _stdcall VBoxUSBMonClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
-{
- PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
- PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
- PFILE_OBJECT pFileObj = pStack->FileObject;
-
- DebugPrint(("VBoxUSBMonClose: pDevExt=%p pFileObj=%p pSession=%p\n", pDevExt, pFileObj, pFileObj->FsContext));
-
- /* Uninstall hook when we close the last instance. */
- if (InterlockedDecrement(&pDevExt->cOpened) == 0)
- VBoxUSBUninstallPnPHook(pDevExt);
-
- VBoxUSBClose();
-
- /* Wait for all outstanding requests to complete */
- /* We're supposed to use it in the remove device function. During unload
- * is no option as that crashes Vista64
- */
- DebugPrint(("Waiting for outstanding requests\n"));
- IoReleaseRemoveLockAndWait(&pDevExt->RemoveLock, ControlDeviceObject);
-
- DebugPrint(("Done waiting.\n"));
- pFileObj->FsContext = NULL;
- pIrp->IoStatus.Information = 0;
- pIrp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
-
- return STATUS_SUCCESS;
-}
-
-
-/**
- * Device I/O Control entry point.
- *
- * @param pDevObj Device object.
- * @param pIrp Request packet.
- */
-NTSTATUS _stdcall VBoxUSBMonDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
-{
- PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
- PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
- NTSTATUS status = STATUS_SUCCESS;
-
- status = IoAcquireRemoveLock(&pDevExt->RemoveLock, ControlDeviceObject);
- if (!NT_SUCCESS(status))
- {
- DebugPrint(("IoAcquireRemoveLock failed with %x\n", status));
- pIrp->IoStatus.Status = status;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return status;
- }
-
- /* Handle ioctl meant for us */
- pIrp->IoStatus.Information = 0;
- status = VBoxUSBDispatchIO(pDevObj, pIrp);
- pIrp->IoStatus.Status = status;
- IoCompleteRequest (pIrp, IO_NO_INCREMENT);
-
- /* Release the remove lock */
- IoReleaseRemoveLock(&pDevExt->RemoveLock, ControlDeviceObject);
- return status;
-}
-
-/**
- * Pass on or refuse entry point
- *
- * @param pDevObj Device object.
- * @param pIrp Request packet.
- */
-NTSTATUS _stdcall VBoxUSBMonStub(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp)
-{
-#ifdef DEBUG
- PIO_STACK_LOCATION irpStack;
-
- irpStack = IoGetCurrentIrpStackLocation(pIrp);
- DebugPrint (("VBoxUSBMonStub %x\n", irpStack->MinorFunction));
-#endif
-
- /* Meant for us; report error */
- pIrp->IoStatus.Information = 0;
- pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
-
- return STATUS_NOT_SUPPORTED;
-}
-
-
-/**
- * Handle the specific PnP ioctls we need for stealing devices.
- *
- * @param irpStack Device object
- * @param pIoStatus IO status of finished IRP
- */
-NTSTATUS _stdcall VBoxUSBMonHandlePnPIoctl(PIO_STACK_LOCATION irpStack, PIO_STATUS_BLOCK pIoStatus)
-{
- DebugPrint(("VBoxUSBMonHandlePnPIoctl IRQL = %d\n", KeGetCurrentIrql()));
- switch(irpStack->MinorFunction)
- {
- case IRP_MN_QUERY_DEVICE_TEXT:
- {
- DebugPrint(("IRP_MN_QUERY_DEVICE_TEXT: pIoStatus->Status = %x\n", pIoStatus->Status));
- if (pIoStatus->Status == STATUS_SUCCESS)
- {
- WCHAR *pId = (WCHAR *)pIoStatus->Information;
- if (VALID_PTR(pId))
- {
- switch(irpStack->Parameters.QueryDeviceText.DeviceTextType)
- {
- case DeviceTextLocationInformation:
- DebugPrint(("DeviceTextLocationInformation %ws\n", pId));
- break;
-
- case DeviceTextDescription:
- DebugPrint(("DeviceTextDescription %ws\n", pId));
- if (VBoxUSBDeviceIsCaptured(irpStack->DeviceObject))
- {
- WCHAR *pId = (WCHAR *)ExAllocatePool(PagedPool, sizeof(szDeviceTextDescription));
- if (!pId)
- {
- AssertFailed();
- break;
- }
- memcpy(pId, szDeviceTextDescription, sizeof(szDeviceTextDescription));
- DebugPrint(("NEW szDeviceTextDescription %ws\n", pId));
- ExFreePool((PVOID)pIoStatus->Information);
- pIoStatus->Information = (ULONG_PTR)pId;
- }
- break;
- }
- }
- else
- DebugPrint(("Invalid pointer %p\n", pId));
- }
- break;
- }
-
- case IRP_MN_QUERY_ID:
- {
- DebugPrint(("IRP_MN_QUERY_ID: Irp->pIoStatus->Status = %x\n", pIoStatus->Status));
- if ( pIoStatus->Status == STATUS_SUCCESS
- && irpStack->DeviceObject)
- {
- WCHAR *pId = (WCHAR *)pIoStatus->Information;
-#ifdef DEBUG
- WCHAR *pTmp;
-#endif
- if (VALID_PTR(pId))
- {
- switch(irpStack->Parameters.QueryDeviceRelations.Type)
- {
- case BusQueryInstanceID:
- DebugPrint(("BusQueryInstanceID %ws\n", pId));
- break;
-
- case BusQueryDeviceID:
- VBoxUSBAddDevice(irpStack->DeviceObject);
- if (VBoxMatchFilter(irpStack->DeviceObject) == true)
- {
- pId = (WCHAR *)ExAllocatePool(PagedPool, sizeof(szBusQueryDeviceId));
- if (!pId)
- {
- AssertFailed();
- break;
- }
- memcpy(pId, szBusQueryDeviceId, sizeof(szBusQueryDeviceId));
- DebugPrint(("NEW BusQueryDeviceID %ws\n", pId));
- ExFreePool((PVOID)pIoStatus->Information);
- pIoStatus->Information = (ULONG_PTR)pId;
- VBoxUSBCaptureDevice(irpStack->DeviceObject);
- }
- break;
-
- case BusQueryHardwareIDs:
-#ifdef DEBUG
- while(*pId) //MULTI_SZ
- {
- DebugPrint(("BusQueryHardwareIDs %ws\n", pId));
- while(*pId) pId++;
- pId++;
- }
-#endif
- VBoxUSBAddDevice(irpStack->DeviceObject);
- if (VBoxMatchFilter(irpStack->DeviceObject) == true)
- {
- pId = (WCHAR *)ExAllocatePool(PagedPool, sizeof(szBusQueryHardwareIDs));
- if (!pId)
- {
- AssertFailed();
- break;
- }
- memcpy(pId, szBusQueryHardwareIDs, sizeof(szBusQueryHardwareIDs));
-#ifdef DEBUG
- pTmp = pId;
- while(*pTmp) //MULTI_SZ
- {
- DebugPrint(("NEW BusQueryHardwareIDs %ws\n", pTmp));
- while(*pTmp) pTmp++;
- pTmp++;
- }
-#endif
- ExFreePool((PVOID)pIoStatus->Information);
- pIoStatus->Information = (ULONG_PTR)pId;
- VBoxUSBCaptureDevice(irpStack->DeviceObject);
- }
- break;
-
- case BusQueryCompatibleIDs:
-#ifdef DEBUG
- while(*pId) //MULTI_SZ
- {
- DebugPrint(("BusQueryCompatibleIDs %ws\n", pId));
- while(*pId) pId++;
- pId++;
- }
-#endif
- if (VBoxUSBDeviceIsCaptured(irpStack->DeviceObject))
- {
- pId = (WCHAR *)ExAllocatePool(PagedPool, sizeof(szBusQueryCompatibleIDs));
- if (!pId)
- {
- AssertFailed();
- break;
- }
- memcpy(pId, szBusQueryCompatibleIDs, sizeof(szBusQueryCompatibleIDs));
-#ifdef DEBUG
- pTmp = pId;
- while(*pTmp) //MULTI_SZ
- {
- DebugPrint(("NEW BusQueryCompatibleIDs %ws\n", pTmp));
- while(*pTmp) pTmp++;
- pTmp++;
- }
-#endif
- ExFreePool((PVOID)pIoStatus->Information);
- pIoStatus->Information = (ULONG_PTR)pId;
- }
- break;
- }
- }
- else
- DebugPrint(("Invalid pointer %p\n", pId));
- }
- break;
- }
-
-#ifdef DEBUG
- case IRP_MN_QUERY_DEVICE_RELATIONS:
- {
- switch(irpStack->Parameters.QueryDeviceRelations.Type)
- {
- case BusRelations:
- {
- DebugPrint(("BusRelations\n"));
-
- if (pIoStatus->Status == STATUS_SUCCESS)
- {
- PDEVICE_RELATIONS pRel = (PDEVICE_RELATIONS)pIoStatus->Information;
- DebugPrint(("pRel = %p\n", pRel));
- if (VALID_PTR(pRel))
- {
- for (unsigned i=0;i<pRel->Count;i++)
- {
- if (VBoxUSBDeviceIsCaptured(irpStack->DeviceObject))
- DebugPrint(("New PDO %p\n", pRel->Objects[i]));
- }
- }
- else
- DebugPrint(("Invalid pointer %p\n", pRel));
- }
- break;
- }
- case TargetDeviceRelation:
- DebugPrint(("TargetDeviceRelation\n"));
- break;
- case RemovalRelations:
- DebugPrint(("RemovalRelations\n"));
- break;
- case EjectionRelations:
- DebugPrint(("EjectionRelations\n"));
- break;
- }
- break;
- }
-
- case IRP_MN_QUERY_CAPABILITIES:
- {
- DebugPrint(("IRP_MN_QUERY_CAPABILITIES: pIoStatus->Status = %x\n", pIoStatus->Status));
- if (pIoStatus->Status == STATUS_SUCCESS)
- {
- PDEVICE_CAPABILITIES pCaps = irpStack->Parameters.DeviceCapabilities.Capabilities;
- if (VALID_PTR(pCaps))
- {
- DebugPrint(("Caps.SilentInstall = %d\n", pCaps->SilentInstall));
- DebugPrint(("Caps.UniqueID = %d\n", pCaps->UniqueID ));
- DebugPrint(("Caps.Address = %d\n", pCaps->Address ));
- DebugPrint(("Caps.UINumber = %d\n", pCaps->UINumber ));
- }
- else
- DebugPrint(("Invalid pointer %p\n", pCaps));
- }
- break;
- }
-#endif
- } /*switch */
- DebugPrint(("VBoxUSBMonHandlePnPIoctl returns %x (IRQL = %d)\n", pIoStatus->Status, KeGetCurrentIrql()));
- return pIoStatus->Status;
-}
-
-/**
- * IRP completion notification callback. Used for selected PNP irps.
- *
- * @param pDevObj Device object.(always NULL!)
- * @param pIrp Request packet.
- * @param context User parameter (old IRP)
- */
-NTSTATUS _stdcall VBoxUSBPnPCompletion(DEVICE_OBJECT *pDevObj, IRP *pIrp, void *context)
-{
- /* Note: pDevObj is NULL! */
- PIRP pOrgIrp = (PIRP)context;
- PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(pOrgIrp);
- PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)ControlDeviceObject->DeviceExtension;
-
- DebugPrint(("VBoxUSBPnPCompletion %p %p %p minor=%x\n", pDevObj, pIrp, context, irpStack->MinorFunction));
-
-#ifdef USBMON_ASYNC
- VBoxUSBMonHandlePnPIoctl(irpStack, &pIrp->IoStatus);
-
- /* Copy back the result to the original IRP. */
- pOrgIrp->IoStatus.Information = pIrp->IoStatus.Information;
- pOrgIrp->IoStatus.Status = pIrp->IoStatus.Status;
-
- /* Unlock & free mdls of our duplicate IRP. */
- while (pIrp->MdlAddress != NULL)
- {
- PMDL nextMdl;
- nextMdl = pIrp->MdlAddress->Next;
- DebugPrint(("Unlock & free MDL %p\n", pIrp->MdlAddress));
- MmUnlockPages(pIrp->MdlAddress);
- IoFreeMdl(pIrp->MdlAddress);
- pIrp->MdlAddress = nextMdl;
- }
- /* Free our duplicate IRP */
- IoFreeIrp(pIrp);
-
- /* Release the remove lock */
- IoReleaseRemoveLock(&pDevExt->RemoveLock, ControlDeviceObject);
-
- /* Complete the original request */
- IoCompleteRequest(pOrgIrp, IO_NO_INCREMENT);
-
- return STATUS_MORE_PROCESSING_REQUIRED; /* must return this as we allocated the IRP with IoBuildAsynchronousFsdRequest! */
-#else
- return STATUS_CONTINUE_COMPLETION;
-#endif
-}
-
-/**
- * Device PnP hook
- *
- * @param pDevObj Device object.
- * @param pIrp Request packet.
- */
-NTSTATUS _stdcall VBoxUSBMonPnPHook(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
-{
- PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(pIrp);
- PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)ControlDeviceObject->DeviceExtension;
- NTSTATUS status;
-
- DebugPrint(("VBoxUSBMonPnPHook pDevObj=%p %s IRP:%p \n", pDevObj, PnPMinorFunctionString(irpStack->MinorFunction), pIrp));
-
- status = IoAcquireRemoveLock(&pDevExt->RemoveLock, ControlDeviceObject);
- if (!NT_SUCCESS(status))
- {
- DebugPrint(("IoAcquireRemoveLock failed with %x\n", status));
- pIrp->IoStatus.Status = status;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return status;
- }
-
- if (pDevExt->fHookDevice == TRUE)
- {
- switch(irpStack->MinorFunction)
- {
- case IRP_MN_QUERY_DEVICE_TEXT:
- case IRP_MN_QUERY_ID:
-#ifdef DEBUG
- /* hooking this IRP causes problems for some reason */
- //case IRP_MN_QUERY_DEVICE_RELATIONS:
- case IRP_MN_QUERY_CAPABILITIES:
-#endif
- {
-#ifdef USBMON_ASYNC
- PIRP pNewIrp;
- PIO_STACK_LOCATION newIrpStack;
-
- /* The driver verifier claims all PNP irps must have Status preset to STATUS_NOT_SUPPORTED */
- IoStatus.Status = STATUS_NOT_SUPPORTED;
-
- pNewIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_PNP, pDevObj, NULL, 0, NULL, NULL);
- Assert(pNewIrp);
- if (!pNewIrp)
- break;
-
- /* The driver verifier claims all PNP irps must have Status preset to STATUS_NOT_SUPPORTED */
- pNewIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
-
- /* Get the next stack location as that is used for the new irp */
- newIrpStack = IoGetNextIrpStackLocation(pNewIrp);
- Assert(newIrpStack);
- if (newIrpStack)
- {
- /* Make a copy of the original IRP */
- newIrpStack->MajorFunction = irpStack->MajorFunction;
- newIrpStack->MinorFunction = irpStack->MinorFunction;
- newIrpStack->Parameters = irpStack->Parameters;
- newIrpStack->FileObject = irpStack->FileObject;
-
- IoSetCompletionRoutine(pNewIrp, VBoxUSBPnPCompletion, pIrp, TRUE, TRUE, TRUE);
-
- /* Mark the original Irp as pending; will be completed above */
- IoMarkIrpPending(pIrp);
-
- pDevExt->fHookDevice = FALSE;
- status = IoCallDriver(pDevObj, pNewIrp);
- pDevExt->fHookDevice = TRUE;
- return STATUS_PENDING; /* always return this! */
- }
- else
- {
- IoFreeIrp(pNewIrp);
- break;
- }
-#else
- PIRP pNewIrp;
- PIO_STACK_LOCATION newIrpStack;
- KEVENT event;
- IO_STATUS_BLOCK IoStatus;
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
-
- /* The driver verifier claims all PNP irps must have Status preset to STATUS_NOT_SUPPORTED */
- IoStatus.Status = STATUS_NOT_SUPPORTED;
-
- pNewIrp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, pDevObj, NULL, 0, NULL, &event, &IoStatus);
- Assert(pNewIrp);
- if (!pNewIrp)
- break;
-
- /* The driver verifier claims all PNP irps must have Status preset to STATUS_NOT_SUPPORTED */
- pNewIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
-
- /* Get the next stack location as that is used for the new irp */
- newIrpStack = IoGetNextIrpStackLocation(pNewIrp);
- Assert(newIrpStack);
- if (newIrpStack)
- {
- /* Make a copy of the original IRP */
- newIrpStack->MajorFunction = irpStack->MajorFunction;
- newIrpStack->MinorFunction = irpStack->MinorFunction;
- newIrpStack->Parameters = irpStack->Parameters;
- newIrpStack->FileObject = irpStack->FileObject;
-
- IoSetCompletionRoutine(pNewIrp, VBoxUSBPnPCompletion, pIrp, TRUE, TRUE, TRUE);
-
- pDevExt->fHookDevice = FALSE;
- status = IoCallDriver(pDevObj, pNewIrp);
- pDevExt->fHookDevice = TRUE;
-
- if (status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
- status = IoStatus.Status;
- }
-
- if (status == STATUS_SUCCESS)
- {
- VBoxUSBMonHandlePnPIoctl(irpStack, &IoStatus);
- }
- /* Copy back the result to the original IRP. */
- pIrp->IoStatus.Information = IoStatus.Information;
- pIrp->IoStatus.Status = IoStatus.Status;
-
- /* Complete the original request */
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
-
- /* Release the remove lock */
- IoReleaseRemoveLock(&pDevExt->RemoveLock, ControlDeviceObject);
-
- return status;
- }
- else
- {
- IoFreeIrp(pNewIrp);
- break;
- }
-#endif
- }
-
- case IRP_MN_SURPRISE_REMOVAL:
- case IRP_MN_REMOVE_DEVICE:
- VBoxUSBRemoveDevice(irpStack->DeviceObject);
- break;
-
- /* These two IRPs are received when the PnP subsystem has determined the id of the newly arrived device */
- /* IRP_MN_START_DEVICE only arrives if it's a USB device of a known class or with a present host driver */
- case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
- case IRP_MN_QUERY_RESOURCES:
- VBoxUSBDeviceArrived(irpStack->DeviceObject);
- break;
-
- default:
- break;
- }
- }
- status = pfnOldPnPHandler(pDevObj, pIrp);
- IoReleaseRemoveLock(&pDevExt->RemoveLock, ControlDeviceObject);
- return status;
-}
-
-
-/**
- * Send IRP_MN_QUERY_DEVICE_RELATIONS
- *
- * @returns NT Status
- * @param pDevObj USB device pointer
- * @param pFileObj Valid file object pointer
- * @param pDevRelations Pointer to DEVICE_RELATIONS pointer (out)
- */
-NTSTATUS VBoxUSBQueryBusRelations(PDEVICE_OBJECT pDevObj, PFILE_OBJECT pFileObj, PDEVICE_RELATIONS *pDevRelations)
-{
- PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)ControlDeviceObject->DeviceExtension;
- IO_STATUS_BLOCK IoStatus;
- KEVENT event;
- NTSTATUS status;
- IRP *pIrp;
- PIO_STACK_LOCATION irpStack;
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
-
- Assert(pDevRelations);
- *pDevRelations = NULL;
-
- pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, pDevObj, NULL, 0, NULL, &event, &IoStatus);
- if (!pIrp)
- {
- AssertMsgFailed(("IoBuildDeviceIoControlRequest failed!!\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- IoStatus.Status = STATUS_NOT_SUPPORTED;
-
- /* Get the next stack location as that is used for the new irp */
- irpStack = IoGetNextIrpStackLocation(pIrp);
- irpStack->MajorFunction = IRP_MJ_PNP;
- irpStack->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
- irpStack->Parameters.QueryDeviceRelations.Type = BusRelations;
- irpStack->FileObject = pFileObj;
-
- pDevExt->fHookDevice = FALSE;
- status = IoCallDriver(pDevObj, pIrp);
- pDevExt->fHookDevice = TRUE;
- if (status == STATUS_PENDING)
- {
- DebugPrint(("IoCallDriver returned STATUS_PENDING!!\n"));
- KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
- status = IoStatus.Status;
- }
-
- if (status == STATUS_SUCCESS)
- {
- PDEVICE_RELATIONS pRel = (PDEVICE_RELATIONS)IoStatus.Information;
- DebugPrint(("pRel = %p\n", pRel));
- if (VALID_PTR(pRel))
- {
- *pDevRelations = pRel;
- }
- else
- DebugPrint(("Invalid pointer %p\n", pRel));
- }
-
- DebugPrint(("IoCallDriver returned %x\n", status));
- return status;
-}
-
-#ifdef DEBUG
-
-PCHAR PnPMinorFunctionString(UCHAR MinorFunction)
-{
- switch (MinorFunction)
- {
- case IRP_MN_START_DEVICE:
- return "IRP_MN_START_DEVICE";
- case IRP_MN_QUERY_REMOVE_DEVICE:
- return "IRP_MN_QUERY_REMOVE_DEVICE";
- case IRP_MN_REMOVE_DEVICE:
- return "IRP_MN_REMOVE_DEVICE";
- case IRP_MN_CANCEL_REMOVE_DEVICE:
- return "IRP_MN_CANCEL_REMOVE_DEVICE";
- case IRP_MN_STOP_DEVICE:
- return "IRP_MN_STOP_DEVICE";
- case IRP_MN_QUERY_STOP_DEVICE:
- return "IRP_MN_QUERY_STOP_DEVICE";
- case IRP_MN_CANCEL_STOP_DEVICE:
- return "IRP_MN_CANCEL_STOP_DEVICE";
- case IRP_MN_QUERY_DEVICE_RELATIONS:
- return "IRP_MN_QUERY_DEVICE_RELATIONS";
- case IRP_MN_QUERY_INTERFACE:
- return "IRP_MN_QUERY_INTERFACE";
- case IRP_MN_QUERY_CAPABILITIES:
- return "IRP_MN_QUERY_CAPABILITIES";
- case IRP_MN_QUERY_RESOURCES:
- return "IRP_MN_QUERY_RESOURCES";
- case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
- return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS";
- case IRP_MN_QUERY_DEVICE_TEXT:
- return "IRP_MN_QUERY_DEVICE_TEXT";
- case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
- return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS";
- case IRP_MN_READ_CONFIG:
- return "IRP_MN_READ_CONFIG";
- case IRP_MN_WRITE_CONFIG:
- return "IRP_MN_WRITE_CONFIG";
- case IRP_MN_EJECT:
- return "IRP_MN_EJECT";
- case IRP_MN_SET_LOCK:
- return "IRP_MN_SET_LOCK";
- case IRP_MN_QUERY_ID:
- return "IRP_MN_QUERY_ID";
- case IRP_MN_QUERY_PNP_DEVICE_STATE:
- return "IRP_MN_QUERY_PNP_DEVICE_STATE";
- case IRP_MN_QUERY_BUS_INFORMATION:
- return "IRP_MN_QUERY_BUS_INFORMATION";
- case IRP_MN_DEVICE_USAGE_NOTIFICATION:
- return "IRP_MN_DEVICE_USAGE_NOTIFICATION";
- case IRP_MN_SURPRISE_REMOVAL:
- return "IRP_MN_SURPRISE_REMOVAL";
-
- default:
- return "unknown_pnp_irp";
- }
-}
-
-void DebugPrintUnicodeString(PUNICODE_STRING pString)
-{
- int i;
-
- for (i=0;i<pString->Length/2;i++)
- {
- DebugPrint(("%c", pString->Buffer[i]));
- }
-}
-
-#endif
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMon.h b/src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMon.h
deleted file mode 100644
index 619a46d6e..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMon.h
+++ /dev/null
@@ -1,241 +0,0 @@
-#ifndef __USBFilter_h__
-#define __USBFilter_h__
-
-/*******************************************************************************
-* Header Files *
-*******************************************************************************/
-#include <VBox/cdefs.h>
-#include <VBox/types.h>
-#include <iprt/assert.h>
-#include <VBox/sup.h>
-#include <iprt/asm.h>
-
-RT_C_DECLS_BEGIN
-#if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
-# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
-# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
-# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap
-# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
-# pragma warning(disable : 4163)
-#endif
-#if (_MSC_VER >= 1600) && !defined(VBOX_WITH_PATCHED_DDK)
-# define _interlockedbittestandset _interlockedbittestandset_StillStupidDdkVsCompilerCrap
-# define _interlockedbittestandreset _interlockedbittestandreset_StillStupidDdkVsCompilerCrap
-# define _interlockedbittestandset64 _interlockedbittestandset64_StillStupidDdkVsCompilerCrap
-# define _interlockedbittestandreset64 _interlockedbittestandreset64_StillStupidDdkVsCompilerCrap
-# pragma warning(disable : 4163)
-#endif
-
-#include <initguid.h>
-#include <wdm.h>
-#include <wmilib.h>
-#include <wmistr.h>
-
-#if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
-# pragma warning(default : 4163)
-# undef _InterlockedExchange
-# undef _InterlockedExchangeAdd
-# undef _InterlockedCompareExchange
-# undef _InterlockedAddLargeStatistic
-#endif
-#if (_MSC_VER >= 1600) && !defined(VBOX_WITH_PATCHED_DDK)
-# pragma warning(default : 4163)
-# undef _interlockedbittestandset
-# undef _interlockedbittestandreset
-# undef _interlockedbittestandset64
-# undef _interlockedbittestandreset64
-#endif
-RT_C_DECLS_END
-
-extern "C" {
-/* from ntddk.h */
-NTSYSAPI
-CHAR
-NTAPI
-RtlUpperChar (
- CHAR Character
- );
-}
-
-#ifdef DEBUG
-#define DebugPrint(_x_) DbgPrint _x_
-
-#define TRAP() DbgBreakPoint()
-
-#else
-#define DebugPrint(_x_)
-#define TRAP()
-#endif
-
-
-#ifndef STATUS_CONTINUE_COMPLETION
-#define STATUS_CONTINUE_COMPLETION STATUS_SUCCESS
-#endif
-
-#define POOL_TAG 'VBox'
-
-typedef struct _DEVICE_EXTENSION
-{
- //
- // Removelock to track IRPs so that device can be removed and
- // the driver can be unloaded safely.
- //
- IO_REMOVE_LOCK RemoveLock;
-
-
- /* Number of times the device was opened. */
- LONG cOpened;
-
- BOOLEAN fHookDevice;
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef DEBUG
-PCHAR
-PnPMinorFunctionString (
- UCHAR MinorFunction
-);
-
-void DebugPrintUnicodeString(PUNICODE_STRING pString);
-#else
-
-#define DebugPrintUnicodeString(x)
-
-#endif
-
-NTSTATUS _stdcall
-VBoxUSBMonAddDevice(
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT PhysicalDeviceObject
- );
-
-
-NTSTATUS _stdcall
-VBoxUSBMonDispatchPnp (
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP pIrp
- );
-
-NTSTATUS _stdcall
-VBoxUSBMonDispatchPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP pIrp
- );
-
-/**
- * Unload the driver.
- *
- * @param pDrvObj Driver object.
- */
-void _stdcall VBoxUSBMonUnload(PDRIVER_OBJECT pDrvObj);
-
-
-/**
- * Driver entry point.
- *
- * @returns appropriate status code.
- * @param pDrvObj Pointer to driver object.
- * @param pRegPath Registry base path.
- */
-NTSTATUS _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath);
-
-/**
- * Device I/O Control entry point.
- *
- * @param pDevObj Device object.
- * @param pIrp Request packet.
- */
-NTSTATUS _stdcall VBoxUSBMonDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-
-/**
- * Pass on or refuse entry point
- *
- * @param pDevObj Device object.
- * @param pIrp Request packet.
- */
-NTSTATUS _stdcall VBoxUSBMonStub(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp);
-
-/**
- * Create (i.e. Open) file entry point.
- *
- * @param pDevObj Device object.
- * @param pIrp Request packet.
- */
-NTSTATUS _stdcall VBoxUSBMonCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-
-/**
- * Close file entry point.
- *
- * @param pDevObj Device object.
- * @param pIrp Request packet.
- */
-NTSTATUS _stdcall VBoxUSBMonClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-
-/**
- * Device PnP hook
- *
- * @param pDevObj Device object.
- * @param pIrp Request packet.
- */
-NTSTATUS _stdcall VBoxUSBMonPnPHook(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp);
-
-/**
- * Send IRP_MN_QUERY_DEVICE_RELATIONS
- *
- * @returns NT Status
- * @param pDevObj USB device pointer
- * @param pFileObj Valid file object pointer
- * @param pDevRelations Pointer to DEVICE_RELATIONS pointer (out)
- */
-NTSTATUS VBoxUSBQueryBusRelations(PDEVICE_OBJECT pDevObj, PFILE_OBJECT pFileObj, PDEVICE_RELATIONS *pDevRelations);
-
-
-
-NTSTATUS _stdcall VBoxUSBPnPCompletion(DEVICE_OBJECT *fido, IRP *pIrp, void *context);
-NTSTATUS _stdcall VBoxUSBDispatchIO(PDEVICE_OBJECT DeviceObject, PIRP pIrp);
-NTSTATUS _stdcall VBoxUSBCreate();
-NTSTATUS _stdcall VBoxUSBClose();
-NTSTATUS _stdcall VBoxUSBInit();
-NTSTATUS _stdcall VBoxUSBTerm();
-
-/**
- * Capture specified USB device
- *
- * @returns NT status code
- * @param usVendorId Vendor id
- * @param usProductId Product id
- * @param usRevision Revision
- */
-NTSTATUS VBoxUSBGrabDevice(USHORT usVendorId, USHORT usProductId, USHORT usRevision);
-
-/**
- * Capture specified USB device
- *
- * @returns NT status code
- * @param usVendorId Vendor id
- * @param usProductId Product id
- * @param usRevision Revision
- */
-NTSTATUS VBoxUSBReleaseDevice(USHORT usVendorId, USHORT usProductId, USHORT usRevision);
-
-bool VBoxMatchFilter(PDEVICE_OBJECT pdo);
-
-bool VBoxUSBAddDevice(PDEVICE_OBJECT pdo);
-int VBoxUSBIsKnownPDO(PDEVICE_OBJECT pdo);
-bool VBoxUSBRemoveDevice(PDEVICE_OBJECT pdo);
-void VBoxUSBDeviceArrived(PDEVICE_OBJECT pdo);
-bool VBoxUSBDeviceIsCaptured(PDEVICE_OBJECT pdo);
-void VBoxUSBSignalChange();
-bool VBoxUSBCaptureDevice(PDEVICE_OBJECT pdo);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __USBFilter_h__ */
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMonFlt.cpp b/src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMonFlt.cpp
deleted file mode 100644
index 451a983c3..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMonFlt.cpp
+++ /dev/null
@@ -1,1065 +0,0 @@
-/** @file
- * VBox host drivers - USB drivers - Win32 USB monitor driver
- */
-
-/*
- * Copyright (C) 2006-2007 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 "USBMon.h"
-#include <VBox/cdefs.h>
-#include <VBox/types.h>
-#include <iprt/process.h>
-#include <iprt/assert.h>
-#include <VBox/sup.h>
-
-#include <VBox/log.h>
-#include <iprt/assert.h>
-#include <stdio.h>
-
-#pragma warning(disable : 4200)
-#include "usbdi.h"
-#pragma warning(default : 4200)
-#include "usbdlib.h"
-#include "VBoxUSBFilterMgr.h"
-#include <VBox/usblib.h>
-#include <devguid.h>
-
-/*
- * Note: Must match the VID & PID in the USB driver .inf file!!
- */
-/*
- BusQueryDeviceID USB\Vid_80EE&Pid_CAFE
- BusQueryInstanceID 2
- BusQueryHardwareIDs USB\Vid_80EE&Pid_CAFE&Rev_0100
- BusQueryHardwareIDs USB\Vid_80EE&Pid_CAFE
- BusQueryCompatibleIDs USB\Class_ff&SubClass_00&Prot_00
- BusQueryCompatibleIDs USB\Class_ff&SubClass_00
- BusQueryCompatibleIDs USB\Class_ff
-*/
-
-#define szBusQueryDeviceId L"USB\\Vid_80EE&Pid_CAFE"
-#define szBusQueryHardwareIDs L"USB\\Vid_80EE&Pid_CAFE&Rev_0100\0USB\\Vid_80EE&Pid_CAFE\0\0"
-#define szBusQueryCompatibleIDs L"USB\\Class_ff&SubClass_00&Prot_00\0USB\\Class_ff&SubClass_00\0USB\\Class_ff\0\0"
-
-#define szDeviceTextDescription L"VirtualBox USB"
-
-/* Possible USB bus driver names. */
-static LPWSTR lpszStandardControllerName[1] =
-{
- L"\\Driver\\usbhub",
-};
-
-#define MAX_ATTACHED_USB_DEVICES 64
-
-typedef struct
-{
- bool fAttached, fCaptured;
- PDEVICE_OBJECT Pdo;
- uint16_t idVendor;
- uint16_t idProduct;
- uint16_t bcdDevice;
- uint8_t bClass;
- uint8_t bSubClass;
- uint8_t bProtocol;
- char szSerial[MAX_USB_SERIAL_STRING];
- char szMfgName[MAX_USB_SERIAL_STRING];
- char szProduct[MAX_USB_SERIAL_STRING];
-} FLTUSB_DEVICE, *PFLTUSB_DEVICE;
-
-/* Device driver instance data */
-typedef struct
-{
- LONG cUSBDevices;
- LONG CaptureCount;
-
- LONG cUSBStateChange;
-
- KSPIN_LOCK lock;
-
- FLTUSB_DEVICE USBDevice[MAX_ATTACHED_USB_DEVICES];
-
- /* Set to force grabbing of newly arrived devices */
- bool fForceGrab;
- /* Set to disable all filters */
- bool fDisableFilters;
-
-} DRVINSTANCE, *PDRVINSTANCE;
-
-DRVINSTANCE DrvInstance = {0};
-
-/* Forward declarations. */
-NTSTATUS VBoxUSBGetDeviceDescription(PDEVICE_OBJECT pDevObj, USHORT *pusVendorId, USHORT *pusProductId, USHORT *pusRevision);
-NTSTATUS VBoxUSBGetDeviceIdStrings(PDEVICE_OBJECT pDevObj, PFLTUSB_DEVICE pFltDev);
-
-#define ACQUIRE_LOCK() \
- KIRQL oldIrql; \
- KeAcquireSpinLock(&DrvInstance.lock, &oldIrql);
-
-#define RELEASE_LOCK() \
- KeReleaseSpinLock(&DrvInstance.lock, oldIrql);
-
-
-NTSTATUS _stdcall VBoxUSBInit()
-{
- memset(&DrvInstance, 0, sizeof(DrvInstance));
- KeInitializeSpinLock(&DrvInstance.lock);
- VBoxUSBFilterInit();
- return STATUS_SUCCESS;
-}
-
-NTSTATUS _stdcall VBoxUSBTerm()
-{
- VBoxUSBFilterTerm();
- return STATUS_SUCCESS;
-}
-
-
-/**
- * Device I/O Control entry point.
- *
- * @param pDevObj Device object.
- * @param pIrp Request packet.
- */
-NTSTATUS _stdcall VBoxUSBDispatchIO(PDEVICE_OBJECT DeviceObject, PIRP Irp)
-{
- PIO_STACK_LOCATION irpStack;
- NTSTATUS status;
- ULONG info = 0;
- PVOID ioBuffer;
- ULONG inputBufferLength;
- ULONG outputBufferLength;
-
- status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- irpStack = IoGetCurrentIrpStackLocation (Irp);
-
- ioBuffer = Irp->AssociatedIrp.SystemBuffer;
- inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
- outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
- {
- case SUPUSBFLT_IOCTL_USB_CHANGE:
- {
- PUSBSUP_USB_CHANGE pOut = (PUSBSUP_USB_CHANGE)ioBuffer;
-
- if (!ioBuffer || outputBufferLength != sizeof(*pOut) || inputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSBFLT_IOCTL_USB_CHANGE: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, 0, outputBufferLength, sizeof(*pOut)));
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- Assert(sizeof(DrvInstance.cUSBStateChange) == sizeof(uint32_t));
-
-//// DebugPrint(("SUPUSBFLT_IOCTL_USB_CHANGE -> %d\n", DrvInstance.cUSBStateChange));
- pOut->cUSBStateChange = DrvInstance.cUSBStateChange;
-
- info = sizeof(*pOut);
- break;
- }
-
- case SUPUSBFLT_IOCTL_GET_NUM_DEVICES:
- {
- PUSBSUP_GETNUMDEV pOut = (PUSBSUP_GETNUMDEV)ioBuffer;
-
- if (!ioBuffer || outputBufferLength != sizeof(*pOut) || inputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSBFLT_IOCTL_GET_NUM_DEVICES: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, 0, outputBufferLength, sizeof(*pOut)));
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- DebugPrint(("SUPUSBFLT_IOCTL_GET_NUM_DEVICES -> %d devices\n", DrvInstance.cUSBDevices));
- pOut->cUSBDevices = DrvInstance.cUSBDevices;
- info = sizeof(*pOut);
- break;
- }
-
- case SUPUSBFLT_IOCTL_CAPTURE_DEVICE:
- {
- PUSBSUP_CAPTURE pIn = (PUSBSUP_CAPTURE)ioBuffer;
-
- DebugPrint(("SUPUSBFLT_IOCTL_CAPTURE_DEVICE\n"));
- if (!ioBuffer || inputBufferLength != sizeof(*pIn) || outputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSBFLT_IOCTL_CAPTURE_DEVICE: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, sizeof(*pIn), outputBufferLength, 0));
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- status = VBoxUSBGrabDevice(pIn->usVendorId, pIn->usProductId, pIn->usRevision);
- break;
- }
-
- case SUPUSBFLT_IOCTL_RELEASE_DEVICE:
- {
- PUSBSUP_RELEASE pIn = (PUSBSUP_RELEASE)ioBuffer;
-
- DebugPrint(("SUPUSBFLT_IOCTL_RELEASE_DEVICE\n"));
- if (!ioBuffer || inputBufferLength != sizeof(*pIn) || outputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSBFLT_IOCTL_RELEASE_DEVICE: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, sizeof(*pIn), outputBufferLength, 0));
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- status = VBoxUSBReleaseDevice(pIn->usVendorId, pIn->usProductId, pIn->usRevision);
- break;
- }
-
- case SUPUSBFLT_IOCTL_GET_VERSION:
- {
- PUSBSUP_VERSION pOut = (PUSBSUP_VERSION)ioBuffer;
-
- DebugPrint(("SUPUSBFLT_IOCTL_GET_VERSION\n"));
- if (!ioBuffer || outputBufferLength != sizeof(*pOut) || inputBufferLength != 0)
- {
- AssertMsgFailed(("SUPUSBFLT_IOCTL_GET_VERSION: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, 0, outputBufferLength, sizeof(*pOut)));
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- pOut->u32Major = USBMON_MAJOR_VERSION;
- pOut->u32Minor = USBMON_MINOR_VERSION;
- info = sizeof(*pOut);
- break;
- }
-
- case SUPUSBFLT_IOCTL_ADD_FILTER:
- {
- PUSBFILTER pFilter = (PUSBFILTER)ioBuffer;
- PUSBSUP_FLTADDOUT pOut = (PUSBSUP_FLTADDOUT)ioBuffer;
- RTPROCESS pid = RTProcSelf();
- uintptr_t uId = 0;
-
- /* Validate input. */
- if (RT_UNLIKELY(!ioBuffer || inputBufferLength != sizeof(*pFilter) || outputBufferLength != sizeof(*pOut)))
- {
- AssertMsgFailed(("SUPUSBFLT_IOCTL_ADD_FILTER: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, sizeof(pFilter), outputBufferLength, 0));
- status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- /* Log the filter details. */
- DebugPrint(("SUPUSBFLT_IOCTL_ADD_FILTER %s %s %s\n",
- USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) : "<null>",
- USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) : "<null>",
- USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) : "<null>"));
-#ifdef DEBUG
- DebugPrint(("VBoxUSBClient::addFilter: idVendor=%#x idProduct=%#x bcdDevice=%#x bDeviceClass=%#x bDeviceSubClass=%#x bDeviceProtocol=%#x bBus=%#x bPort=%#x\n",
- USBFilterGetNum(pFilter, USBFILTERIDX_VENDOR_ID),
- USBFilterGetNum(pFilter, USBFILTERIDX_PRODUCT_ID),
- USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_REV),
- USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_CLASS),
- USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_SUB_CLASS),
- USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_PROTOCOL),
- USBFilterGetNum(pFilter, USBFILTERIDX_BUS),
- USBFilterGetNum(pFilter, USBFILTERIDX_PORT)));
-#endif
-
- /* We can't get the bus/port numbers. Ignore them while matching. */
- USBFilterSetMustBePresent(pFilter, USBFILTERIDX_BUS, false);
- USBFilterSetMustBePresent(pFilter, USBFILTERIDX_PORT, false);
-
- /* Add the filter. */
- pOut->rc = VBoxUSBFilterAdd(pFilter, pid, &uId);
- pOut->uId = uId;
-
- info = sizeof(*pOut);
- break;
- }
-
- case SUPUSBFLT_IOCTL_REMOVE_FILTER:
- {
- uintptr_t *pIn = (uintptr_t *)ioBuffer;
- RTPROCESS pid = RTProcSelf();
-
- if (!ioBuffer || inputBufferLength != sizeof(*pIn))
- {
- AssertMsgFailed(("SUPUSBFLT_IOCTL_REMOVE_FILTER: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
- inputBufferLength, sizeof(pIn), outputBufferLength, 0));
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- DebugPrint(("SUPUSBFLT_IOCTL_REMOVE_FILTER %x\n", *pIn));
- VBoxUSBFilterRemove(pid, *pIn);
- break;
- }
-
- default:
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- Irp->IoStatus.Information = info;
-
- return status;
-}
-
-NTSTATUS _stdcall VBoxUSBCreate()
-{
- Assert(sizeof(DrvInstance.CaptureCount) == sizeof(LONG));
- InterlockedIncrement(&DrvInstance.CaptureCount);
- return STATUS_SUCCESS;
-}
-
-NTSTATUS _stdcall VBoxUSBClose()
-{
- ACQUIRE_LOCK();
- Assert(sizeof(DrvInstance.CaptureCount) == sizeof(LONG));
- InterlockedDecrement(&DrvInstance.CaptureCount);
- Assert(DrvInstance.CaptureCount >= 0);
- VBoxUSBFilterRemoveOwner(RTProcSelf());
-
- if (DrvInstance.CaptureCount == 0)
- {
- DrvInstance.cUSBDevices = 0;
- }
- RELEASE_LOCK();
- return STATUS_SUCCESS;
-}
-
-
-unsigned myxdigit(char c)
-{
- if (c >= 'a' && c <= 'z')
- c = c - 'a' + 'A';
- if (c >= '0' && c <= '9')
- return c - '0';
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- return 0;
-}
-
-#if 1
-bool VBoxMatchFilter(PDEVICE_OBJECT pdo)
-{
- USBFILTER Device;
- int index;
- PFLTUSB_DEVICE USBDevice;
-
- if (DrvInstance.fForceGrab)
- {
- DebugPrint(("VBoxMatchFilter -> Force Grab -> TRUE\n"));
- return true;
- }
- if (DrvInstance.fDisableFilters)
- {
- DebugPrint(("VBoxMatchFilter -> filters disabled -> FALSE\n"));
- return false;
- }
-
- index = VBoxUSBIsKnownPDO(pdo);
- if (index == -1)
- {
- DebugPrint(("VBoxMatchFilter -> unknown PDO -> FALSE\n"));
- return false;
- }
- ACQUIRE_LOCK();
-
- USBDevice = &DrvInstance.USBDevice[index];
- USBFilterInit(&Device, USBFILTERTYPE_CAPTURE);
-
- USBFilterSetNumExact(&Device, USBFILTERIDX_VENDOR_ID, USBDevice->idVendor, true);
- USBFilterSetNumExact(&Device, USBFILTERIDX_PRODUCT_ID, USBDevice->idProduct, true);
- USBFilterSetNumExact(&Device, USBFILTERIDX_DEVICE_REV, USBDevice->bcdDevice, true);
- USBFilterSetNumExact(&Device, USBFILTERIDX_DEVICE_CLASS, USBDevice->bClass, true);
- USBFilterSetNumExact(&Device, USBFILTERIDX_DEVICE_SUB_CLASS, USBDevice->bSubClass, true);
- USBFilterSetNumExact(&Device, USBFILTERIDX_DEVICE_PROTOCOL, USBDevice->bProtocol, true);
- USBFilterSetStringExact(&Device, USBFILTERIDX_MANUFACTURER_STR, USBDevice->szMfgName, true);
- USBFilterSetStringExact(&Device, USBFILTERIDX_PRODUCT_STR, USBDevice->szProduct, true);
- USBFilterSetStringExact(&Device, USBFILTERIDX_SERIAL_NUMBER_STR, USBDevice->szSerial, true);
-
- /* Run filters on the thing. */
- uintptr_t uId = 0;
- RTPROCESS Owner = VBoxUSBFilterMatch(&Device, &uId);
- USBFilterDelete(&Device);
- if (Owner == NIL_RTPROCESS)
- {
- RELEASE_LOCK();
- return false;
- }
- DebugPrint(("VBoxMatchFilter: HIT\n"));
- RELEASE_LOCK();
- return true;
-}
-#else
-bool VBoxMatchFilter(WCHAR *pszDeviceId)
-{
- //#define szBusQueryDeviceId L"USB\\Vid_80EE&Pid_CAFE"
- uint16_t pId;
- uint16_t vId;
-// char szRevision[4];
-#ifdef DEBUG
- WCHAR *pszOrgDeviceId = pszDeviceId;
-#endif
- USBFILTER Device;
-
- if (DrvInstance.fForceGrab)
- {
- DebugPrint(("VBoxMatchFilter -> Force Grab -> TRUE\n"));
- return true;
- }
- if (DrvInstance.fDisableFilters)
- {
- DebugPrint(("VBoxMatchFilter -> filters disabled -> FALSE\n"));
- return false;
- }
-
- if (RtlCompareMemory(pszDeviceId, L"USB\\", 4*sizeof(WCHAR)) != 4*sizeof(WCHAR))
- return false;
-
- while(*pszDeviceId != 0 && *pszDeviceId != '_')
- pszDeviceId++;
- if(*pszDeviceId == 0)
- return false;
- pszDeviceId++;
-
- /* Vid_ skipped */
- vId = myxdigit((CHAR)pszDeviceId[0]) << 12
- | myxdigit((CHAR)pszDeviceId[1]) << 8
- | myxdigit((CHAR)pszDeviceId[2]) << 4
- | myxdigit((CHAR)pszDeviceId[3]) << 0;
-
- while(*pszDeviceId != 0 && *pszDeviceId != '_')
- pszDeviceId++;
- if(*pszDeviceId == 0)
- return false;
- pszDeviceId++;
-
- /* Pid_ skipped */
- pId = myxdigit((CHAR)pszDeviceId[0]) << 12
- | myxdigit((CHAR)pszDeviceId[1]) << 8
- | myxdigit((CHAR)pszDeviceId[2]) << 4
- | myxdigit((CHAR)pszDeviceId[3]) << 0;
-
- ACQUIRE_LOCK();
-
- USBFilterInit(&Device, USBFILTERTYPE_CAPTURE);
-
- USBFilterSetNumExact(&Device, USBFILTERIDX_VENDOR_ID, vId, true);
- USBFilterSetNumExact(&Device, USBFILTERIDX_PRODUCT_ID, pId, true);
-
- /* Run filters on the thing. */
- uintptr_t uId = 0;
- RTPROCESS Owner = VBoxUSBFilterMatch(&Device, &uId);
- USBFilterDelete(&Device);
- if (Owner == NIL_RTPROCESS)
- {
- RELEASE_LOCK();
- return false;
- }
- DebugPrint(("VBoxMatchFilter: HIT\n"));
- RELEASE_LOCK();
- return true;
-}
-#endif
-
-bool VBoxUSBAddDevice(PDEVICE_OBJECT pdo)
-{
- if (VBoxUSBIsKnownPDO(pdo) != -1)
- return true;
-
- ACQUIRE_LOCK()
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if (DrvInstance.USBDevice[i].fAttached == false)
- {
- DebugPrint(("VBoxUSBAddDevice %p\n", pdo));
- DrvInstance.USBDevice[i].fAttached = true;
- DrvInstance.USBDevice[i].Pdo = pdo;
- DrvInstance.USBDevice[i].fCaptured = false;
- Assert(DrvInstance.cUSBDevices <= MAX_ATTACHED_USB_DEVICES);
-
- DebugPrint(("Signal USB change ADD\n"));
- RELEASE_LOCK();
- /* There doesn't appear to be any good way to get device information
- * from Windows. Reading its descriptor should do the trick though.
- */
- VBoxUSBGetDeviceIdStrings(pdo, &DrvInstance.USBDevice[i]);
-
- InterlockedIncrement(&DrvInstance.cUSBStateChange);
- return true;
- }
- }
- RELEASE_LOCK();
- return false;
-}
-
-int VBoxUSBIsKnownPDO(PDEVICE_OBJECT pdo)
-{
- Assert(pdo);
- ACQUIRE_LOCK();
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if (DrvInstance.USBDevice[i].Pdo == pdo)
- {
- RELEASE_LOCK();
- return i;
- }
- }
- RELEASE_LOCK();
- return -1;
-}
-
-bool VBoxUSBRemoveDevice(PDEVICE_OBJECT pdo)
-{
- ACQUIRE_LOCK();
-
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if (DrvInstance.USBDevice[i].Pdo == pdo)
- {
- DebugPrint(("VBoxUSBRemoveDevice %p\n", pdo));
- DrvInstance.USBDevice[i].fAttached = false;
- DrvInstance.USBDevice[i].Pdo = NULL;
-
- if (DrvInstance.USBDevice[i].fCaptured == true)
- {
- InterlockedDecrement(&DrvInstance.cUSBDevices);
- Assert(DrvInstance.cUSBDevices >= 0);
-
- DrvInstance.USBDevice[i].fCaptured = false;
- }
-
- DebugPrint(("Signal USB change REMOVE\n"));
- InterlockedIncrement(&DrvInstance.cUSBStateChange);
-
- RELEASE_LOCK();
- return true;
- }
- }
- RELEASE_LOCK();
- return false;
-}
-
-bool VBoxUSBCaptureDevice(PDEVICE_OBJECT pdo)
-{
- Assert(DrvInstance.CaptureCount);
- if (DrvInstance.CaptureCount == 0)
- return false;
-
- ACQUIRE_LOCK();
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if ( DrvInstance.USBDevice[i].Pdo == pdo
- && DrvInstance.USBDevice[i].fCaptured == false)
- {
- DebugPrint(("VBoxUSBCaptureDevice %p\n", pdo));
-
- Assert(DrvInstance.USBDevice[i].fAttached);
-
- DrvInstance.USBDevice[i].fCaptured = true;
- InterlockedIncrement(&DrvInstance.cUSBDevices);
- RELEASE_LOCK();
- return true;
- }
- }
- RELEASE_LOCK();
- return false;
-}
-
-void VBoxUSBDeviceArrived(PDEVICE_OBJECT pdo)
-{
- /* If we manually release a device, then all filters will be temporarily disabled; Enable them again when the
- * device has been started.
- */
- DrvInstance.fDisableFilters = false;
-
- /* If we manually capture a device, we are forced to grab the next device that arrives. Disable this mode here */
- DrvInstance.fForceGrab = false;
- return;
-}
-
-bool VBoxUSBDeviceIsCaptured(PDEVICE_OBJECT pdo)
-{
- bool ret;
-
- ACQUIRE_LOCK();
- for (int i=0;i<MAX_ATTACHED_USB_DEVICES;i++)
- {
- if (DrvInstance.USBDevice[i].Pdo == pdo)
- {
- ret = DrvInstance.USBDevice[i].fCaptured;
- RELEASE_LOCK();
- return ret;
- }
- }
- RELEASE_LOCK();
- return false;
-}
-
-/**
- * Send USB ioctl
- *
- * @returns NT Status
- * @param pDevObj USB device pointer
- * @param control_code ioctl
- * @param buffer Descriptor buffer
- * @param size size of buffer
- */
-NTSTATUS VBoxUSBSendIOCTL(PDEVICE_OBJECT pDevObj, ULONG control_code, void *buffer, uint32_t size)
-{
- IO_STATUS_BLOCK io_status;
- KEVENT event;
- NTSTATUS status;
- IRP *pIrp;
- PIO_STACK_LOCATION stackloc;
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
-
- pIrp = IoBuildDeviceIoControlRequest(control_code, pDevObj, NULL, 0, NULL, 0, TRUE, &event, &io_status);
- if (!pIrp)
- {
- AssertMsgFailed(("IoBuildDeviceIoControlRequest failed!!\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Get the next stack location as that is used for the new irp */
- stackloc = IoGetNextIrpStackLocation(pIrp);
- stackloc->Parameters.Others.Argument1 = buffer;
- stackloc->Parameters.Others.Argument2 = NULL;
-
- status = IoCallDriver(pDevObj, pIrp);
- if (status == STATUS_PENDING)
- {
- DebugPrint(("IoCallDriver returned STATUS_PENDING!!\n"));
- KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
- status = io_status.Status;
- }
-
- DebugPrint(("IoCallDriver returned %x\n", status));
-
- return status;
-}
-
-/**
- * Get USB descriptor
- *
- * @returns NT Status
- * @param pDevObj USB device pointer
- * @param buffer Descriptor buffer
- * @param size size of buffer
- * @param type descriptor type
- * @param index descriptor index
- * @param language_id descriptor language id
- */
-NTSTATUS VBoxUSBGetDescriptor(PDEVICE_OBJECT pDevObj, void *buffer, int size, int type, int index, int language_id)
-{
- NTSTATUS rc;
- PURB urb;
-
- urb = (PURB)ExAllocatePool(NonPagedPool,sizeof(URB));
- if(urb == NULL)
- {
- DebugPrint(("Failed to alloc mem for urb\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- memset(urb, 0, sizeof(*urb));
-
- urb->UrbHeader.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE;
- urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
- urb->UrbControlDescriptorRequest.TransferBufferLength = size;
- urb->UrbControlDescriptorRequest.TransferBuffer = buffer;
- urb->UrbControlDescriptorRequest.Index = (UCHAR)index;
- urb->UrbControlDescriptorRequest.DescriptorType = (UCHAR)type;
- urb->UrbControlDescriptorRequest.LanguageId = (USHORT)language_id;
-
- rc = VBoxUSBSendIOCTL(pDevObj, IOCTL_INTERNAL_USB_SUBMIT_URB, urb, sizeof(*urb));
-#ifdef DEBUG
- if(!NT_SUCCESS(rc) || !USBD_SUCCESS(urb->UrbHeader.Status))
- DebugPrint(("VBoxUSBGetDescriptor: VBoxUSBSendIOCTL failed with %x (%x)\n", rc, urb->UrbHeader.Status));
-#endif
-
- ExFreePool(urb);
- return rc;
-}
-
-/**
- * Get a valid USB string descriptor language ID (the first ID found).
- *
- * @returns NT Status
- * @param pDevObj USB device pointer
- * @param lang_id pointer to language id
- */
-NTSTATUS VBoxUSBGetLangID(PDEVICE_OBJECT pDevObj, int *lang_id)
-{
- NTSTATUS status;
- unsigned length;
- char buffer[MAXIMUM_USB_STRING_LENGTH];
- PUSB_STRING_DESCRIPTOR pstrdescr = (PUSB_STRING_DESCRIPTOR)&buffer;
-
- Assert(lang_id);
- *lang_id = 0;
-
- length = sizeof(buffer);
- memset(pstrdescr, 0, length);
- pstrdescr->bLength = length;
- pstrdescr->bDescriptorType = USB_STRING_DESCRIPTOR_TYPE;
-
- status = VBoxUSBGetDescriptor(pDevObj, pstrdescr, length, USB_STRING_DESCRIPTOR_TYPE, 0, 0);
- if (!NT_SUCCESS(status))
- {
- DebugPrint(("VBoxUSBGetLangID: language ID table not present (?)\n"));
- goto fail;
- }
- /* Just grab the first lang ID if available. In 99% cases, it will be US English (0x0409).*/
- if (pstrdescr->bLength >= sizeof(USB_STRING_DESCRIPTOR))
- {
- Assert(sizeof(pstrdescr->bString[0]) == sizeof(uint16_t));
- *lang_id = pstrdescr->bString[0];
- status = STATUS_SUCCESS;
- }
- else
- status = STATUS_INVALID_PARAMETER;
-fail:
- return status;
-}
-
-static VOID VBoxUSBStringDescriptorToUnicodeString(PUSB_STRING_DESCRIPTOR pDr, PUNICODE_STRING pUnicode)
-{
- /* for some reason the string dr sometimes contains a non-null terminated string
- * although we zeroed up the complete descriptor buffer
- * this is why RtlInitUnicodeString won't work
- * we need to init the scting length based on dr length */
- pUnicode->Buffer = pDr->bString;
- pUnicode->Length = pUnicode->MaximumLength = pDr->bLength - RT_OFFSETOF(USB_STRING_DESCRIPTOR, bString);
-}
-
-NTSTATUS VBoxUSBGetStringDescriptor(PDEVICE_OBJECT pDevObj, char *dest, unsigned size, int index, int lang_id)
-{
- NTSTATUS status;
- PUSB_STRING_DESCRIPTOR pstrdescr = NULL;
- unsigned length;
- UNICODE_STRING ustr;
- ANSI_STRING astr;
-
- *dest = '\0';
- if (index)
- {
- /* An entire USB string descriptor is Unicode and can't be longer than 256 bytes.
- * Hence 128 bytes is enough for an ASCII string.
- */
- length = sizeof(USB_STRING_DESCRIPTOR) + MAX_USB_SERIAL_STRING * sizeof(pstrdescr->bString[0]);
- pstrdescr = (PUSB_STRING_DESCRIPTOR)ExAllocatePool(NonPagedPool, length);
- if (!pstrdescr)
- {
- AssertMsgFailed(("VBoxUSBGetStringDescriptor: ExAllocatePool failed\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto fail;
- }
- memset(pstrdescr, 0, length);
- pstrdescr->bLength = length;
- pstrdescr->bDescriptorType = USB_STRING_DESCRIPTOR_TYPE;
-
- status = VBoxUSBGetDescriptor(pDevObj, pstrdescr, length, USB_STRING_DESCRIPTOR_TYPE, index, lang_id);
- if (!NT_SUCCESS(status))
- {
- DebugPrint(("VBoxUSBGetStringDescriptor: requested string not present (?)\n"));
- status = STATUS_SUCCESS; //not fatal
- goto fail;
- }
- if (pstrdescr->bLength > sizeof(USB_STRING_DESCRIPTOR))
- {
- VBoxUSBStringDescriptorToUnicodeString(pstrdescr, &ustr);
- astr.Buffer = dest;
- astr.Length = 0;
- astr.MaximumLength = (USHORT)size - 1;
- memset(dest, 0, size);
- status = RtlUnicodeStringToAnsiString(&astr, &ustr, FALSE);
- if (!NT_SUCCESS(status))
- {
- AssertMsgFailed((__FUNCTION__": RtlUnicodeStringToAnsiString Failed status (0x%x)\n", status));
- goto fail;
- }
- }
- }
- status = STATUS_SUCCESS;
-fail:
- if (pstrdescr)
- ExFreePool(pstrdescr);
- return status;
-}
-
-NTSTATUS VBoxUSBGetDeviceIdStrings(PDEVICE_OBJECT pDevObj, PFLTUSB_DEVICE pFltDev)
-{
- NTSTATUS status;
- PUSB_DEVICE_DESCRIPTOR devdescr = 0;
-
- devdescr = (PUSB_DEVICE_DESCRIPTOR)ExAllocatePool(NonPagedPool, sizeof(USB_DEVICE_DESCRIPTOR));
- if (devdescr == NULL)
- {
- DebugPrint(("Failed to alloc mem for urb\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto fail;
- }
- memset(devdescr, 0, sizeof(*devdescr));
-
- status = VBoxUSBGetDescriptor(pDevObj, devdescr, sizeof(*devdescr), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0);
- if (!NT_SUCCESS(status))
- {
- AssertMsgFailed(("VBoxUSBGetDeviceDescription: getting device descriptor failed\n"));
- goto fail;
- }
- DebugPrint(("Device pid=%x vid=%x rev=%x\n", devdescr->idVendor, devdescr->idProduct, devdescr->bcdDevice));
- pFltDev->idVendor = devdescr->idVendor;
- pFltDev->idProduct = devdescr->idProduct;
- pFltDev->bcdDevice = devdescr->bcdDevice;
- pFltDev->bClass = devdescr->bDeviceClass;
- pFltDev->bSubClass = devdescr->bDeviceSubClass;
- pFltDev->bProtocol = devdescr->bDeviceProtocol;
- pFltDev->szSerial[0] = 0;
- pFltDev->szMfgName[0] = 0;
- pFltDev->szProduct[0] = 0;
-
- /* If there are no strings, don't even try to get any string descriptors. */
- if (devdescr->iSerialNumber || devdescr->iManufacturer || devdescr->iProduct)
- {
- int langId;
-
- status = VBoxUSBGetLangID(pDevObj, &langId);
- if (!NT_SUCCESS(status))
- {
- AssertMsgFailed(("VBoxUSBGetDeviceDescription: reading language ID failed\n"));
- goto fail;
- }
- status = VBoxUSBGetStringDescriptor(pDevObj, pFltDev->szSerial, sizeof(pFltDev->szSerial), devdescr->iSerialNumber, langId);
- if (!NT_SUCCESS(status))
- {
- AssertMsgFailed(("VBoxUSBGetDeviceDescription: reading serial number failed\n"));
- goto fail;
- }
- status = VBoxUSBGetStringDescriptor(pDevObj, pFltDev->szMfgName, sizeof(pFltDev->szMfgName), devdescr->iManufacturer, langId);
- if (!NT_SUCCESS(status))
- {
- AssertMsgFailed(("VBoxUSBGetDeviceDescription: reading manufacturer name failed\n"));
- goto fail;
- }
- status = VBoxUSBGetStringDescriptor(pDevObj, pFltDev->szProduct, sizeof(pFltDev->szProduct), devdescr->iProduct, langId);
- if (!NT_SUCCESS(status))
- {
- AssertMsgFailed(("VBoxUSBGetDeviceDescription: reading product name failed\n"));
- goto fail;
- }
-
- DebugPrint(("VBoxUSBGetStringDescriptor: strings: '%s':'%s':'%s' (lang ID %x)\n",
- pFltDev->szMfgName, pFltDev->szProduct, pFltDev->szSerial, langId));
- }
- status = STATUS_SUCCESS;
-
-fail:
- if (devdescr)
- ExFreePool(devdescr);
- return status;
-}
-
-/**
- * Get USB device description
- *
- * @returns NT Status
- * @param pDevObj USB device pointer
- * @param pusVendorId Vendor id (out)
- * @param pusProductId Product id (out)
- * @param pusRevision Revision (out)
- */
-NTSTATUS VBoxUSBGetDeviceDescription(PDEVICE_OBJECT pDevObj, USHORT *pusVendorId, USHORT *pusProductId, USHORT *pusRevision)
-{
- NTSTATUS status;
- PUSB_DEVICE_DESCRIPTOR devdescr = 0;
-
- devdescr = (PUSB_DEVICE_DESCRIPTOR)ExAllocatePool(NonPagedPool,sizeof(USB_DEVICE_DESCRIPTOR));
- if(devdescr == NULL)
- {
- DebugPrint(("Failed to alloc mem for urb\n"));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto fail;
- }
- memset(devdescr, 0, sizeof(*devdescr));
-
- status = VBoxUSBGetDescriptor(pDevObj, devdescr, sizeof(*devdescr), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0);
- if (!NT_SUCCESS(status))
- {
- DebugPrint(("VBoxUSBGetDeviceDescription: getting device descriptor failed\n"));
- goto fail;
- }
- DebugPrint(("Device pid=%x vid=%x rev=%x\n", devdescr->idVendor, devdescr->idProduct, devdescr->bcdDevice));
- *pusVendorId = devdescr->idVendor;
- *pusProductId = devdescr->idProduct;
- *pusRevision = devdescr->bcdDevice;
-
- ExFreePool(devdescr);
- return STATUS_SUCCESS;
-
-fail:
- if (devdescr)
- ExFreePool(devdescr);
- return status;
-}
-
-/**
- * Unplug and replug the specified USB device
- *
- * @returns NT status code
- * @param usVendorId Vendor id
- * @param usProductId Product id
- * @param usRevision Revision
- * @param fCaptured Already captured or not
- * @param pfReplugged Replugged or not (out)
- */
-NTSTATUS VBoxUSBReplugDevice(USHORT usVendorId, USHORT usProductId, USHORT usRevision, bool fCaptured, bool *pfReplugged)
-{
- NTSTATUS status;
- UNICODE_STRING szStandardControllerName[RT_ELEMENTS(lpszStandardControllerName)];
-
- DebugPrint(("VBoxUSBReplugDevice: %04X %04X %04X\n", usVendorId, usProductId, usRevision));
-
- Assert(pfReplugged);
- *pfReplugged = false;
-
- for (int i=0;i<RT_ELEMENTS(lpszStandardControllerName);i++)
- {
- szStandardControllerName[i].Length = 0;
- szStandardControllerName[i].MaximumLength = 0;
- szStandardControllerName[i].Buffer = 0;
-
- RtlInitUnicodeString(&szStandardControllerName[i], lpszStandardControllerName[i]);
- }
-
- for (int i=0;i<16;i++)
- {
- char szHubName[32];
- UNICODE_STRING UnicodeName;
- ANSI_STRING AnsiName;
- PDEVICE_OBJECT pHubDevObj;
- PFILE_OBJECT pHubFileObj;
-
- sprintf(szHubName, "\\Device\\USBPDO-%d", i);
-
- UnicodeName.Length = 0;
- UnicodeName.MaximumLength = 0;
- UnicodeName.Buffer = 0;
-
- RtlInitAnsiString(&AnsiName, szHubName);
- RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, TRUE);
-
- status = IoGetDeviceObjectPointer(&UnicodeName, FILE_READ_DATA, &pHubFileObj, &pHubDevObj);
- if (status == STATUS_SUCCESS)
- {
- DebugPrint(("IoGetDeviceObjectPointer for %s returned %p %p\n", szHubName, pHubDevObj, pHubFileObj));
-
- if ( pHubDevObj->DriverObject
- && pHubDevObj->DriverObject->DriverName.Buffer
- && pHubDevObj->DriverObject->DriverName.Length
- )
- {
- for (int j=0;j<RT_ELEMENTS(lpszStandardControllerName);j++)
- {
- if (!RtlCompareUnicodeString(&szStandardControllerName[j], &pHubDevObj->DriverObject->DriverName, TRUE /* case insensitive */))
- {
- PDEVICE_RELATIONS pDevRelations = NULL;
-
- DebugPrint(("Associated driver %wZ -> related dev obj=%p\n", pHubDevObj->DriverObject->DriverName, IoGetRelatedDeviceObject(pHubFileObj)));
-
- status = VBoxUSBQueryBusRelations(pHubDevObj, pHubFileObj, &pDevRelations);
- if ( status == STATUS_SUCCESS
- && pDevRelations)
- {
- for (unsigned k=0;k<pDevRelations->Count;k++)
- {
- USHORT usPDOVendorId, usPDOProductId, usPDORevision;
-
- DebugPrint(("Found existing USB PDO %p\n", pDevRelations->Objects[k]));
- VBoxUSBGetDeviceDescription(pDevRelations->Objects[k], &usPDOVendorId, &usPDOProductId, &usPDORevision);
-
- if ( VBoxUSBDeviceIsCaptured(pDevRelations->Objects[k]) == fCaptured
- && usPDOVendorId == usVendorId
- && usPDOProductId == usProductId
- && usPDORevision == usRevision)
- {
- DebugPrint(("REPLUG device -> \n"));
- /* Simulate a device replug */
- status = VBoxUSBSendIOCTL(pDevRelations->Objects[k], IOCTL_INTERNAL_USB_CYCLE_PORT, NULL, 0);
-
- *pfReplugged = true;
- }
- ObDereferenceObject(pDevRelations->Objects[k]);
- if (*pfReplugged == true)
- break;
- }
- ExFreePool(pDevRelations);
- }
- if (*pfReplugged == true)
- break;
- }
- }
- }
- ObDereferenceObject(pHubFileObj);
- }
- RtlFreeUnicodeString(&UnicodeName);
- if (*pfReplugged == true)
- break;
- }
-
- return STATUS_SUCCESS;
-}
-
-/**
- * Capture specified USB device
- *
- * @returns NT status code
- * @param usVendorId Vendor id
- * @param usProductId Product id
- * @param usRevision Revision
- */
-NTSTATUS VBoxUSBReleaseDevice(USHORT usVendorId, USHORT usProductId, USHORT usRevision)
-{
- NTSTATUS status;
- bool fReplugged;
-
- DebugPrint(("VBoxUSBReleaseDevice\n"));
-
- DrvInstance.fDisableFilters = true;
- status = VBoxUSBReplugDevice(usVendorId, usProductId, usRevision, true, &fReplugged);
- if ( status != STATUS_SUCCESS
- || !fReplugged)
- DrvInstance.fDisableFilters = false;
- return status;
-}
-
-/**
- * Capture specified USB device
- *
- * @returns NT status code
- * @param usVendorId Vendor id
- * @param usProductId Product id
- * @param usRevision Revision
- */
-NTSTATUS VBoxUSBGrabDevice(USHORT usVendorId, USHORT usProductId, USHORT usRevision)
-{
- NTSTATUS status;
- bool fReplugged;
-
- DebugPrint(("VBoxUSBGrabDevice\n"));
-
- DrvInstance.fForceGrab = true;
- status = VBoxUSBReplugDevice(usVendorId, usProductId, usRevision, false, &fReplugged);
- if ( status != STATUS_SUCCESS
- || !fReplugged)
- DrvInstance.fForceGrab = false;
- return status;
-}
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/USBLib-win.cpp b/src/VBox/HostDrivers/VBoxUSB/win/USBLib-win.cpp
deleted file mode 100644
index 0b7a35fc0..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/USBLib-win.cpp
+++ /dev/null
@@ -1,2940 +0,0 @@
-/* $Id: USBLib-win.cpp $ */
-/** @file
- * USBLIB - USB support library interface, Windows.
- */
-
-/*
- * Copyright (C) 2006-2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-
-/*******************************************************************************
-* Header Files *
-*******************************************************************************/
-#define LOG_GROUP LOG_GROUP_DRV_USBPROXY
-#include <windows.h>
-
-#include <VBox/sup.h>
-#include <VBox/types.h>
-#include <VBox/err.h>
-#include <VBox/param.h>
-#include <iprt/path.h>
-#include <iprt/assert.h>
-#include <iprt/alloc.h>
-#include <iprt/string.h>
-#include <iprt/thread.h>
-#include <VBox/log.h>
-#include <VBox/usblib.h>
-#include <VBox/usb.h>
-#include "../USBLibInternal.h"
-#include <stdio.h>
-#pragma warning (disable:4200) /* shuts up the empty array member warnings */
-#include <setupapi.h>
-#include <usbdi.h>
-#include <hidsdi.h>
-
-
-/*******************************************************************************
-* Global Variables *
-*******************************************************************************/
-/** Flags whether or not we started the service. */
-static bool g_fStartedService = false;
-static char completeDeviceName[256] = ""; //generated from the GUID registered by the driver itself
-
-typedef struct
-{
- char szName[512];
- char szDriverRegName[512];
-} USBDEV, *PUSBDEV;
-
-static PUSBDEV g_pUSBDev = NULL;
-static uint32_t g_cMaxDevices = 0;
-static uint32_t g_cUSBStateChange = 0;
-
-static HANDLE g_hUSBMonitor = INVALID_HANDLE_VALUE;
-
-
-/*******************************************************************************
-* Defined Constants And Macros *
-*******************************************************************************/
-/** @def VBOX_WITH_ANNOYING_USB_ASSERTIONS
- * Enable this to get assertions on various failures.
- */
-//#define VBOX_WITH_ANNOYING_USB_ASSERTIONS
-#ifdef DOXYGEN_RUNNING
-# define VBOX_WITH_ANNOYING_USB_ASSERTIONS
-#endif
-
-/*******************************************************************************
-* Internal Functions *
-*******************************************************************************/
-
-bool ValidateUSBDevice(char *pszName)
-{
- HANDLE hOut = INVALID_HANDLE_VALUE;
-
- hOut = CreateFile(pszName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
-
- if (INVALID_HANDLE_VALUE == hOut)
- {
- Log(( "USB: FAILED to open %s\n", pszName));
- goto failure;
- }
- else
- {
- /*
- * Check the version
- */
- USBSUP_VERSION version = {0};
- DWORD cbReturned = 0;
-
- if (!DeviceIoControl(hOut, SUPUSB_IOCTL_GET_VERSION, NULL, 0,&version, sizeof(version), &cbReturned, NULL))
- {
- Log(("DeviceIoControl SUPUSB_IOCTL_GET_VERSION failed with LastError=%Rwa\n", GetLastError()));
- goto failure;
- }
-
- if (version.u32Major != USBDRV_MAJOR_VERSION ||
- version.u32Minor < USBDRV_MINOR_VERSION)
- {
- Log(("USB: Invalid version %d:%d vs %d:%d\n", version.u32Major, version.u32Minor, USBDRV_MAJOR_VERSION, USBDRV_MINOR_VERSION));
- goto failure;
- }
- if (!DeviceIoControl(hOut, SUPUSB_IOCTL_IS_OPERATIONAL, NULL, 0, NULL, NULL, &cbReturned, NULL))
- {
- Log(("DeviceIoControl SUPUSB_IOCTL_IS_OPERATIONAL failed with LastError=%Rwa\n", GetLastError()));
- goto failure;
- }
-
- }
- CloseHandle(hOut);
- return true;
-
-failure:
- if (hOut != INVALID_HANDLE_VALUE)
- CloseHandle(hOut);
-
- return false;
-}
-
-bool OpenOneDevice (HDEVINFO HardwareDeviceInfo,
- PSP_DEVICE_INTERFACE_DATA DeviceInfoData,
- USBDEV *pUsbDev)
-{
- PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData = NULL;
- ULONG predictedLength = 0;
- ULONG requiredLength = 0;
- SP_DEVINFO_DATA devInfo;
-
- //
- // allocate a function class device data structure to receive the
- // goods about this particular device.
- //
- SetupDiGetDeviceInterfaceDetail (
- HardwareDeviceInfo,
- DeviceInfoData,
- NULL, // probing so no output buffer yet
- 0, // probing so output buffer length of zero
- &requiredLength,
- NULL); // not interested in the specific dev-node
-
- predictedLength = requiredLength;
-
- functionClassDeviceData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) RTMemAllocZ(predictedLength);
- if (NULL == functionClassDeviceData)
- {
- return false;
- }
- functionClassDeviceData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
-
- //
- // Retrieve the information from Plug and Play.
- //
- devInfo.cbSize = sizeof(devInfo);
- if (! SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo, DeviceInfoData,
- functionClassDeviceData, predictedLength,
- &requiredLength, &devInfo))
- {
- goto failure;
- }
-
- strcpy(pUsbDev->szName, functionClassDeviceData->DevicePath) ;
- Log(( "USB: Attempting to open %s\n", pUsbDev->szName));
-
- /* Query the registry path of the associated driver */
- requiredLength = 0;
- SetupDiGetDeviceRegistryProperty(HardwareDeviceInfo, &devInfo, SPDRP_DRIVER, NULL, NULL, 0, &requiredLength);
- Assert(sizeof(pUsbDev->szDriverRegName) >= requiredLength);
- if (requiredLength && sizeof(pUsbDev->szDriverRegName) >= requiredLength)
- {
- predictedLength = requiredLength;
-
- if (!SetupDiGetDeviceRegistryProperty(HardwareDeviceInfo, &devInfo, SPDRP_DRIVER, NULL, (PBYTE)pUsbDev->szDriverRegName, predictedLength, &requiredLength))
- goto failure;
-
- Log(("USB: Driver name %s\n", pUsbDev->szDriverRegName));
- }
-
- bool rc = ValidateUSBDevice(functionClassDeviceData->DevicePath);
- RTMemFree(functionClassDeviceData);
-
- return rc;
-
-failure:
- if (functionClassDeviceData)
- RTMemFree(functionClassDeviceData);
-
- return false;
-}
-
-bool OpenUsbDevices(LPGUID pGuid, uint32_t *pcNumDevices)
-{
- HDEVINFO hardwareDeviceInfo;
- SP_DEVICE_INTERFACE_DATA deviceInfoData;
- USBDEV usbDev;
-
- //
- // Open a handle to the plug and play dev node.
- // SetupDiGetClassDevs() returns a device information set that contains info on all
- // installed devices of a specified class.
- //
- hardwareDeviceInfo = SetupDiGetClassDevs (
- pGuid,
- NULL, // Define no enumerator (global)
- NULL, // Define no
- (DIGCF_PRESENT | // Only Devices present
- DIGCF_DEVICEINTERFACE)); // Function class devices.
-
- deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
-
- int j = 0, i = 0;
-
- while (true)
- {
- // SetupDiEnumDeviceInterfaces() returns information about device interfaces
- // exposed by one or more devices. Each call returns information about one interface;
- // the routine can be called repeatedly to get information about several interfaces
- // exposed by one or more devices.
-
- Log(("OpenUsbDevices: SetupDiEnumDeviceInterfaces\n"));
- if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
- 0, // We don't care about specific PDOs
- pGuid,
- i,
- &deviceInfoData))
- {
- if (OpenOneDevice (hardwareDeviceInfo, &deviceInfoData, &usbDev) == true)
- {
- uint32_t z;
- for (z = 0; z < g_cMaxDevices; z++)
- {
- if (g_pUSBDev[z].szName[0] == 0)
- {
- memcpy(&g_pUSBDev[z], &usbDev, sizeof(usbDev));
- Log(("Captured device %s\n", g_pUSBDev[z].szName));
- j++;
- break;
- }
- }
- AssertMsg(z < g_cMaxDevices, ("z=%d g_cMaxDevices=%d\n", z, g_cMaxDevices));
- }
- }
- else
- {
- if (ERROR_NO_MORE_ITEMS == GetLastError())
- {
- Log(("OpenUsbDevices: No more items\n"));
- break;
- }
- }
- i++;
- }
-
- *pcNumDevices = j;
-
- // SetupDiDestroyDeviceInfoList() destroys a device information set
- // and frees all associated memory.
-
- SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
- return true;
-}
-
-/**
- * Initialize the OS specific part of the library.
- * On Win32 this involves:
- * - registering the device driver
- * - start device driver.
- * - open driver.
- *
- * @returns VBox status code
- */
-static int usblibEnumDevices(uint32_t cNumNewDevices, uint32_t *pcNumDevices)
-{
- if (g_pUSBDev)
- RTMemFree(g_pUSBDev);
- g_pUSBDev = NULL;
- g_cMaxDevices = 0;
- *pcNumDevices = 0;
-
- if (cNumNewDevices == 0)
- return 0; /* nothing to do */
-
- g_pUSBDev = (PUSBDEV)RTMemAllocZ(cNumNewDevices*sizeof(USBDEV));
- if (!g_pUSBDev)
- {
- AssertFailed();
- return VERR_NO_MEMORY;
- }
- g_cMaxDevices = cNumNewDevices;
-
- if (OpenUsbDevices((LPGUID)&GUID_CLASS_VBOXUSB, pcNumDevices) == false)
- {
- AssertFailed();
- return VERR_INTERNAL_ERROR;
- }
- AssertMsg(*pcNumDevices <= cNumNewDevices, ("cNumDevices = %d, cNumNewDevices = %d\n", *pcNumDevices, cNumNewDevices));
- return VINF_SUCCESS;
-}
-
-/**
- * Returns the nth USB device name
- *
- * @returns NULL on failure, otherwise the requested name
- */
-char *usblibQueryDeviceName(uint32_t idxDev)
-{
- int j=0;
-
- Assert(idxDev < g_cMaxDevices);
- for (uint32_t i=0; i<g_cMaxDevices; i++)
- {
- if (g_pUSBDev[i].szName[0])
- {
- if (j == idxDev)
- return g_pUSBDev[i].szName;
- j++;
- }
- }
-
- Log(("USB: usblibQueryHandle returned -1; g_cMaxDevices = %d\n", g_cMaxDevices));
- return NULL;
-}
-
-/**
- * Returns the nth USB device registry path
- *
- * @returns NULL on failure, otherwise the requested name
- */
-char *usblibQueryDeviceRegPath(uint32_t idxDev)
-{
- int j=0;
-
- Assert(idxDev < g_cMaxDevices);
- for (uint32_t i=0; i<g_cMaxDevices; i++)
- {
- if (g_pUSBDev[i].szName[0])
- {
- if (j == idxDev)
- return g_pUSBDev[i].szDriverRegName;
- j++;
- }
- }
-
- Log(("USB: usblibQueryHandle returned -1; g_cMaxDevices = %d\n", g_cMaxDevices));
- return NULL;
-}
-
-/**
- * Converts a supdrv error code to an nt status code.
- *
- * @returns corresponding SUPDRV_ERR_*.
- * @param rc Win32 error code.
- */
-static int suplibConvertWin32Err(int rc)
-{
- /* Conversion program (link with ntdll.lib from ddk):
- #define _WIN32_WINNT 0x0501
- #include <windows.h>
- #include <ntstatus.h>
- #include <winternl.h>
- #include <stdio.h>
-
- int main()
- {
- #define CONVERT(a) printf(#a " %#x -> %d\n", a, RtlNtStatusToDosError((a)))
- CONVERT(STATUS_SUCCESS);
- CONVERT(STATUS_NOT_SUPPORTED);
- CONVERT(STATUS_INVALID_PARAMETER);
- CONVERT(STATUS_ACCESS_DENIED);
- CONVERT(STATUS_INVALID_HANDLE);
- CONVERT(STATUS_INVALID_ADDRESS);
- CONVERT(STATUS_NOT_LOCKED);
- CONVERT(STATUS_IMAGE_ALREADY_LOADED);
- return 0;
- }
- */
-
- switch (rc)
- {
- //case 0: return STATUS_SUCCESS;
- case 0: return 0;
- //case SUPDRV_ERR_GENERAL_FAILURE: return STATUS_NOT_SUPPORTED;
- case ERROR_NOT_SUPPORTED: return VERR_GENERAL_FAILURE;
- //case SUPDRV_ERR_INVALID_PARAM: return STATUS_INVALID_PARAMETER;
- case ERROR_INVALID_PARAMETER: return VERR_INVALID_PARAMETER;
- //case SUPDRV_ERR_INVALID_MAGIC: return STATUS_ACCESS_DENIED;
- case ERROR_ACCESS_DENIED: return VERR_INVALID_MAGIC;
- //case SUPDRV_ERR_INVALID_HANDLE: return STATUS_INVALID_HANDLE;
- case ERROR_INVALID_HANDLE: return VERR_INVALID_HANDLE;
- //case SUPDRV_ERR_INVALID_POINTER: return STATUS_INVALID_ADDRESS;
- case ERROR_UNEXP_NET_ERR: return VERR_INVALID_POINTER;
- //case SUPDRV_ERR_LOCK_FAILED: return STATUS_NOT_LOCKED;
- case ERROR_NOT_LOCKED: return VERR_LOCK_FAILED;
- //case SUPDRV_ERR_ALREADY_LOADED: return STATUS_IMAGE_ALREADY_LOADED;
- case ERROR_SERVICE_ALREADY_RUNNING: return VERR_ALREADY_LOADED;
- }
-
- return VERR_GENERAL_FAILURE;
-}
-
-
-
-//*****************************************************************************
-// D E F I N E S
-//*****************************************************************************
-
-#define NUM_HCS_TO_CHECK 10
-
-#include <cfgmgr32.h>
-#include "usbdesc.h"
-//
-// Structure used to build a linked list of String Descriptors
-// retrieved from a device.
-//
-
-typedef struct _STRING_DESCRIPTOR_NODE
-{
- struct _STRING_DESCRIPTOR_NODE *Next;
- UCHAR DescriptorIndex;
- USHORT LanguageID;
- USB_STRING_DESCRIPTOR StringDescriptor[0];
-} STRING_DESCRIPTOR_NODE, *PSTRING_DESCRIPTOR_NODE;
-
-//
-// Structures associated with TreeView items through the lParam. When an item
-// is selected, the lParam is retrieved and the structure it which it points
-// is used to display information in the edit control.
-//
-
-typedef struct
-{
- PUSB_NODE_INFORMATION HubInfo; // NULL if not a HUB
-
- PCHAR HubName; // NULL if not a HUB
-
- PUSB_NODE_CONNECTION_INFORMATION_EX ConnectionInfo; // NULL if root HUB
-
- PUSB_DESCRIPTOR_REQUEST ConfigDesc; // NULL if root HUB
-
- PSTRING_DESCRIPTOR_NODE StringDescs;
-
-} USBDEVICEINFO, *PUSBDEVICEINFO;
-
-//*****************************************************************************
-// L O C A L F U N C T I O N P R O T O T Y P E S
-//*****************************************************************************
-
-VOID
-EnumerateHub (
- PCHAR HubName,
- PUSB_NODE_CONNECTION_INFORMATION_EX ConnectionInfo,
- PUSB_DESCRIPTOR_REQUEST ConfigDesc,
- PSTRING_DESCRIPTOR_NODE StringDescs,
- PCHAR DeviceDesc
-);
-
-VOID
-EnumerateHubPorts (
- HANDLE hHubDevice,
- ULONG NumPorts,
- const char *pszHubName
-);
-
-PCHAR GetRootHubName (
- HANDLE HostController
-);
-
-PCHAR GetExternalHubName (
- HANDLE Hub,
- ULONG ConnectionIndex
-);
-
-PCHAR GetHCDDriverKeyName (
- HANDLE HCD
-);
-
-PCHAR GetDriverKeyName (
- HANDLE Hub,
- ULONG ConnectionIndex
-);
-
-PUSB_DESCRIPTOR_REQUEST
-GetConfigDescriptor (
- HANDLE hHubDevice,
- ULONG ConnectionIndex,
- UCHAR DescriptorIndex
-);
-
-BOOL
-AreThereStringDescriptors (
- PUSB_DEVICE_DESCRIPTOR DeviceDesc,
- PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc
-);
-
-PSTRING_DESCRIPTOR_NODE
-GetAllStringDescriptors (
- HANDLE hHubDevice,
- ULONG ConnectionIndex,
- PUSB_DEVICE_DESCRIPTOR DeviceDesc,
- PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc
-);
-
-PSTRING_DESCRIPTOR_NODE
-GetStringDescriptor (
- HANDLE hHubDevice,
- ULONG ConnectionIndex,
- UCHAR DescriptorIndex,
- USHORT LanguageID
-);
-
-PSTRING_DESCRIPTOR_NODE
-GetStringDescriptors (
- HANDLE hHubDevice,
- ULONG ConnectionIndex,
- UCHAR DescriptorIndex,
- ULONG NumLanguageIDs,
- USHORT *LanguageIDs,
- PSTRING_DESCRIPTOR_NODE StringDescNodeTail
-);
-
-PCHAR DriverNameToDeviceDesc (PCHAR DriverName);
-
-//*****************************************************************************
-// G L O B A L S P R I V A T E T O T H I S F I L E
-//*****************************************************************************
-
-PCHAR ConnectionStatuses[] =
-{
- "NoDeviceConnected",
- "DeviceConnected",
- "DeviceFailedEnumeration",
- "DeviceGeneralFailure",
- "DeviceCausedOvercurrent",
- "DeviceNotEnoughPower"
-};
-
-static ULONG g_TotalDevicesConnected;
-static BOOL g_DoConfigDesc = TRUE;
-static int g_TotalHubs;
-static PUSBDEVICE *g_ppDeviceList = NULL;
-
-PCHAR ConnectionStatuses[];
-
-VOID AddLeaf(PUSBDEVICEINFO info, PCHAR pszLeafName, PCHAR pszDriverKeyName, const char *pszHubName, ULONG iHubPort)
-{
- Log3(("usbproxy:AddLeaf: pszDriverKeyName=%s pszLeafName=%s pszHubName=%s iHubPort=%d\n", pszDriverKeyName, pszLeafName, pszHubName, iHubPort));
- PUSBDEVICE pDevice = (PUSBDEVICE)RTMemAllocZ(sizeof(USBDEVICE));
-
- if (pDevice)
- {
- Assert(info->ConnectionInfo);
-
- if (info->ConnectionInfo)
- {
- PSTRING_DESCRIPTOR_NODE pStrDesc;
- char **pString;
-
- pDevice->bcdUSB = info->ConnectionInfo->DeviceDescriptor.bcdUSB;
- pDevice->bDeviceClass = info->ConnectionInfo->DeviceDescriptor.bDeviceClass;
- pDevice->bDeviceSubClass = info->ConnectionInfo->DeviceDescriptor.bDeviceSubClass;
- pDevice->bDeviceProtocol = info->ConnectionInfo->DeviceDescriptor.bDeviceProtocol;
- pDevice->idVendor = info->ConnectionInfo->DeviceDescriptor.idVendor;
- pDevice->idProduct = info->ConnectionInfo->DeviceDescriptor.idProduct;
- pDevice->bcdDevice = info->ConnectionInfo->DeviceDescriptor.bcdDevice;
- pDevice->bBus = 0; /** @todo figure out bBus on windows... */
- pDevice->bPort = iHubPort;
- /** @todo check which devices are used for primary input (keyboard & mouse) */
- if (!pszDriverKeyName || *pszDriverKeyName == 0)
- pDevice->enmState = USBDEVICESTATE_UNUSED;
- else
- pDevice->enmState = USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
- pDevice->enmSpeed = USBDEVICESPEED_UNKNOWN;
-
- pDevice->pszAddress = RTStrDup(pszDriverKeyName);
- pDevice->pszHubName = RTStrDup(pszHubName);
- pDevice->bNumConfigurations = 0;
- pDevice->u64SerialHash = 0;
- pStrDesc = info->StringDescs;
- while (pStrDesc)
- {
- pString = NULL;
- if ( info->ConnectionInfo->DeviceDescriptor.iManufacturer
- && pStrDesc->DescriptorIndex == info->ConnectionInfo->DeviceDescriptor.iManufacturer)
- {
- pString = (char **)&pDevice->pszManufacturer;
- }
- else
- if ( info->ConnectionInfo->DeviceDescriptor.iProduct
- && pStrDesc->DescriptorIndex == info->ConnectionInfo->DeviceDescriptor.iProduct)
- {
- pString = (char **)&pDevice->pszProduct;
- }
- else
- if ( info->ConnectionInfo->DeviceDescriptor.iSerialNumber
- && pStrDesc->DescriptorIndex == info->ConnectionInfo->DeviceDescriptor.iSerialNumber)
- {
- pString = (char **)&pDevice->pszSerialNumber;
- }
- if (pString)
- {
- char *pStringUTF8 = NULL;
- RTUtf16ToUtf8((PCRTUTF16)&pStrDesc->StringDescriptor->bString[0], &pStringUTF8);
- RTStrUtf8ToCurrentCP(pString, pStringUTF8);
- RTStrFree(pStringUTF8);
- if (pStrDesc->DescriptorIndex == info->ConnectionInfo->DeviceDescriptor.iSerialNumber)
- {
- pDevice->u64SerialHash = USBLibHashSerial(pDevice->pszSerialNumber);
- }
- }
-
- pStrDesc = pStrDesc->Next;
- }
- if (*g_ppDeviceList == NULL)
- {
- pDevice->pNext = NULL;
- *g_ppDeviceList = pDevice;
- }
- else
- {
- pDevice->pNext = *g_ppDeviceList;
- *g_ppDeviceList = pDevice;
- }
- }
- return;
- }
- AssertFailed();
-}
-
-//*****************************************************************************
-//
-// EnumerateHostController()
-//
-// hTreeParent - Handle of the TreeView item under which host controllers
-// should be added.
-//
-//*****************************************************************************
-
-VOID
-EnumerateHostController (
- HANDLE hHCDev,
- PCHAR leafName
-)
-{
- PCHAR driverKeyName;
- PCHAR deviceDesc;
- PCHAR rootHubName;
-
- driverKeyName = GetHCDDriverKeyName(hHCDev);
-
- if (driverKeyName)
- {
- deviceDesc = DriverNameToDeviceDesc(driverKeyName);
-
- if (deviceDesc)
- {
- leafName = deviceDesc;
- }
-
- RTMemFree(driverKeyName);
- }
-
- rootHubName = GetRootHubName(hHCDev);
-
- if (rootHubName != NULL)
- {
- EnumerateHub(rootHubName,
- NULL, // ConnectionInfo
- NULL, // ConfigDesc
- NULL, // StringDescs
- "RootHub" // DeviceDesc
- );
- }
-}
-
-
-//*****************************************************************************
-//
-// EnumerateHostControllers()
-//
-// hTreeParent - Handle of the TreeView item under which host controllers
-// should be added.
-//
-//*****************************************************************************
-
-void usbLibEnumerateHostControllers(PUSBDEVICE *ppDevices, uint32_t *DevicesConnected)
-{
- char HCName[16];
- int HCNum;
- HANDLE hHCDev;
- PCHAR leafName;
-
- g_TotalDevicesConnected = 0;
- g_TotalHubs = 0;
- g_ppDeviceList = ppDevices;
-
- // Iterate over some Host Controller names and try to open them.
- //
- for (HCNum = 0; HCNum < NUM_HCS_TO_CHECK; HCNum++)
- {
- sprintf(HCName, "\\\\.\\HCD%d", HCNum);
-
- hHCDev = CreateFile(HCName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
-
- // If the handle is valid, then we've successfully opened a Host
- // Controller. Display some info about the Host Controller itself,
- // then enumerate the Root Hub attached to the Host Controller.
- //
- if (hHCDev != INVALID_HANDLE_VALUE)
- {
- leafName = HCName + sizeof("\\\\.\\") - sizeof("");
-
- EnumerateHostController(hHCDev,
- leafName);
-
- CloseHandle(hHCDev);
- }
- }
-
- g_ppDeviceList = NULL;
- *DevicesConnected = g_TotalDevicesConnected - g_TotalHubs;
-}
-
-//*****************************************************************************
-//
-// EnumerateHub()
-//
-// hTreeParent - Handle of the TreeView item under which this hub should be
-// added.
-//
-// HubName - Name of this hub. This pointer is kept so the caller can neither
-// free nor reuse this memory.
-//
-// ConnectionInfo - NULL if this is a root hub, else this is the connection
-// info for an external hub. This pointer is kept so the caller can neither
-// free nor reuse this memory.
-//
-// ConfigDesc - NULL if this is a root hub, else this is the Configuration
-// Descriptor for an external hub. This pointer is kept so the caller can
-// neither free nor reuse this memory.
-//
-//*****************************************************************************
-
-VOID
-EnumerateHub (
- PCHAR HubName,
- PUSB_NODE_CONNECTION_INFORMATION_EX ConnectionInfo,
- PUSB_DESCRIPTOR_REQUEST ConfigDesc,
- PSTRING_DESCRIPTOR_NODE StringDescs,
- PCHAR DeviceDesc
-)
-{
- HANDLE hHubDevice;
- PCHAR deviceName;
- BOOL success;
- ULONG nBytes;
- PUSBDEVICEINFO info;
- CHAR leafName[512]; // XXXXX how big does this have to be?
-
- Log3(("usbproxy::EnumerateHub: HubName=%s\n", HubName));
-
- // Initialize locals to not allocated state so the error cleanup routine
- // only tries to cleanup things that were successfully allocated.
- //
- info = NULL;
- hHubDevice = INVALID_HANDLE_VALUE;
-
- // Allocate some space for a USBDEVICEINFO structure to hold the
- // hub info, hub name, and connection info pointers. GPTR zero
- // initializes the structure for us.
- //
- info = (PUSBDEVICEINFO) RTMemAllocZ(sizeof(USBDEVICEINFO));
-
- if (info == NULL)
- {
- AssertFailed();
- goto EnumerateHubError;
- }
-
- // Keep copies of the Hub Name, Connection Info, and Configuration
- // Descriptor pointers
- //
- info->HubName = HubName;
-
- info->ConnectionInfo = ConnectionInfo;
-
- info->ConfigDesc = ConfigDesc;
-
- info->StringDescs = StringDescs;
-
-
- // Allocate some space for a USB_NODE_INFORMATION structure for this Hub,
- //
- info->HubInfo = (PUSB_NODE_INFORMATION)RTMemAllocZ(sizeof(USB_NODE_INFORMATION));
-
- if (info->HubInfo == NULL)
- {
- AssertFailed();
- goto EnumerateHubError;
- }
-
- // Allocate a temp buffer for the full hub device name.
- //
- deviceName = (PCHAR)RTMemAllocZ(strlen(HubName) + sizeof("\\\\.\\"));
-
- if (deviceName == NULL)
- {
- AssertFailed();
- goto EnumerateHubError;
- }
-
- // Create the full hub device name
- //
- strcpy(deviceName, "\\\\.\\");
- strcpy(deviceName + sizeof("\\\\.\\") - 1, info->HubName);
-
- // Try to hub the open device
- //
- hHubDevice = CreateFile(deviceName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
-
- // Done with temp buffer for full hub device name
- //
- RTMemFree(deviceName);
-
- if (hHubDevice == INVALID_HANDLE_VALUE)
- {
- AssertFailed();
- goto EnumerateHubError;
- }
-
- //
- // Now query USBHUB for the USB_NODE_INFORMATION structure for this hub.
- // This will tell us the number of downstream ports to enumerate, among
- // other things.
- //
- success = DeviceIoControl(hHubDevice,
- IOCTL_USB_GET_NODE_INFORMATION,
- info->HubInfo,
- sizeof(USB_NODE_INFORMATION),
- info->HubInfo,
- sizeof(USB_NODE_INFORMATION),
- &nBytes,
- NULL);
-
- if (!success)
- {
- AssertFailed();
- goto EnumerateHubError;
- }
-
- // Build the leaf name from the port number and the device description
- //
- if (ConnectionInfo)
- {
- sprintf(leafName, "[Port%d] ", ConnectionInfo->ConnectionIndex);
- strcat(leafName, ConnectionStatuses[ConnectionInfo->ConnectionStatus]);
- strcat(leafName, " : ");
- }
- else
- {
- leafName[0] = 0;
- }
-
- if (DeviceDesc)
- {
-
- strcat(leafName, DeviceDesc);
- }
- else
- {
- strcat(leafName, info->HubName);
- }
-
- // Now recursively enumerate the ports of this hub.
- //
- EnumerateHubPorts(
- hHubDevice,
- info->HubInfo->u.HubInformation.HubDescriptor.bNumberOfPorts,
- HubName
- );
-
-
- CloseHandle(hHubDevice);
- return;
-
-EnumerateHubError:
- //
- // Clean up any stuff that got allocated
- //
-
- if (hHubDevice != INVALID_HANDLE_VALUE)
- {
- CloseHandle(hHubDevice);
- hHubDevice = INVALID_HANDLE_VALUE;
- }
-
- if (info != NULL)
- {
- if (info->HubName != NULL)
- {
- RTMemFree(info->HubName);
- info->HubName = NULL;
- }
-
- if (info->HubInfo != NULL)
- {
- RTMemFree(info->HubInfo);
- info->HubInfo;
- }
-
- RTMemFree(info);
- info = NULL;
- }
-
- if (ConnectionInfo)
- {
- RTMemFree(ConnectionInfo);
- }
-
- if (ConfigDesc)
- {
- RTMemFree(ConfigDesc);
- }
-
- if (StringDescs != NULL)
- {
- PSTRING_DESCRIPTOR_NODE Next;
-
- do {
-
- Next = StringDescs->Next;
- RTMemFree(StringDescs);
- StringDescs = Next;
-
- } while (StringDescs != NULL);
- }
-}
-
-//*****************************************************************************
-//
-// EnumerateHubPorts()
-//
-// hTreeParent - Handle of the TreeView item under which the hub port should
-// be added.
-//
-// hHubDevice - Handle of the hub device to enumerate.
-//
-// NumPorts - Number of ports on the hub.
-//
-//*****************************************************************************
-
-VOID
-EnumerateHubPorts (
- HANDLE hHubDevice,
- ULONG NumPorts,
- const char *pszHubName
-)
-{
- ULONG index;
- BOOL success;
-
- PUSB_NODE_CONNECTION_INFORMATION_EX connectionInfo;
- PUSB_DESCRIPTOR_REQUEST configDesc;
- PSTRING_DESCRIPTOR_NODE stringDescs;
- PUSBDEVICEINFO info;
-
- PCHAR pszDriverKeyName;
- PCHAR deviceDesc;
- CHAR leafName[512]; // XXXXX how big does this have to be?
- CHAR szDriverKeyName[512];
-
-
- // Loop over all ports of the hub.
- //
- // Port indices are 1 based, not 0 based.
- //
- for (index = 1; index <= NumPorts; index++)
- {
- ULONG nBytes;
-
- // Allocate space to hold the connection info for this port.
- // For now, allocate it big enough to hold info for 30 pipes.
- //
- // Endpoint numbers are 0-15. Endpoint number 0 is the standard
- // control endpoint which is not explicitly listed in the Configuration
- // Descriptor. There can be an IN endpoint and an OUT endpoint at
- // endpoint numbers 1-15 so there can be a maximum of 30 endpoints
- // per device configuration.
- //
- // Should probably size this dynamically at some point.
- //
- nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION_EX) +
- sizeof(USB_PIPE_INFO) * 30;
-
- connectionInfo = (PUSB_NODE_CONNECTION_INFORMATION_EX)RTMemAllocZ(nBytes);
-
- if (connectionInfo == NULL)
- {
- AssertFailed();
- break;
- }
-
- //
- // Now query USBHUB for the USB_NODE_CONNECTION_INFORMATION_EX structure
- // for this port. This will tell us if a device is attached to this
- // port, among other things.
- //
- connectionInfo->ConnectionIndex = index;
-
- success = DeviceIoControl(hHubDevice,
- IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX,
- connectionInfo,
- nBytes,
- connectionInfo,
- nBytes,
- &nBytes,
- NULL);
-
- if (!success)
- {
- RTMemFree(connectionInfo);
- continue;
- }
-
- // Update the count of connected devices
- //
- if (connectionInfo->ConnectionStatus == DeviceConnected)
- g_TotalDevicesConnected++;
- else
- {
- RTMemFree(connectionInfo);
- continue;
- }
-
- if (connectionInfo->DeviceIsHub)
- g_TotalHubs++;
-
- // If there is a device connected, get the Device Description
- //
- deviceDesc = NULL;
- szDriverKeyName[0] = 0;
- if (connectionInfo->ConnectionStatus != NoDeviceConnected)
- {
- pszDriverKeyName = GetDriverKeyName(hHubDevice,
- index);
-
- if (pszDriverKeyName)
- {
- Log(("Attached driver %s [port=%d]%s\n", pszDriverKeyName, index, connectionInfo->DeviceIsHub ? " DeviceIsHub" : ""));
- deviceDesc = DriverNameToDeviceDesc(pszDriverKeyName);
- Assert(strlen(pszDriverKeyName)+1 < sizeof(szDriverKeyName));
- if (strlen(pszDriverKeyName)+1 < sizeof(szDriverKeyName))
- strcpy(szDriverKeyName, pszDriverKeyName);
-
- RTMemFree(pszDriverKeyName);
- }
- }
-
- // If there is a device connected to the port, try to retrieve the
- // Configuration Descriptor from the device.
- //
- if (g_DoConfigDesc &&
- connectionInfo->ConnectionStatus == DeviceConnected)
- {
- configDesc = GetConfigDescriptor(hHubDevice,
- index,
- 0);
- }
- else
- {
- configDesc = NULL;
- }
-
- if (configDesc != NULL &&
- AreThereStringDescriptors(&connectionInfo->DeviceDescriptor,
- (PUSB_CONFIGURATION_DESCRIPTOR)(configDesc+1)))
- {
- stringDescs = GetAllStringDescriptors(
- hHubDevice,
- index,
- &connectionInfo->DeviceDescriptor,
- (PUSB_CONFIGURATION_DESCRIPTOR)(configDesc+1));
- }
- else
- {
- stringDescs = NULL;
- }
-
- // If the device connected to the port is an external hub, get the
- // name of the external hub and recursively enumerate it.
- //
- if (connectionInfo->DeviceIsHub)
- {
- PCHAR extHubName;
-
- extHubName = GetExternalHubName(hHubDevice,
- index);
-
- if (extHubName != NULL)
- {
- EnumerateHub(extHubName,
- connectionInfo,
- configDesc,
- stringDescs,
- deviceDesc);
-
- // On to the next port
- //
- continue;
- }
- }
-
- // Allocate some space for a USBDEVICEINFO structure to hold the
- // hub info, hub name, and connection info pointers. GPTR zero
- // initializes the structure for us.
- //
- info = (PUSBDEVICEINFO) RTMemAllocZ(sizeof(USBDEVICEINFO));
-
- if (info == NULL)
- {
- AssertFailed();
- if (configDesc != NULL)
- {
- RTMemFree(configDesc);
- }
- RTMemFree(connectionInfo);
- break;
- }
-
- info->ConnectionInfo = connectionInfo;
-
- info->ConfigDesc = configDesc;
-
- info->StringDescs = stringDescs;
-
- sprintf(leafName, "[Port%d] ", index);
-
- strcat(leafName, ConnectionStatuses[connectionInfo->ConnectionStatus]);
-
- if (deviceDesc)
- {
- strcat(leafName, " : ");
- strcat(leafName, deviceDesc);
- }
-
- AddLeaf(info, leafName, szDriverKeyName, pszHubName, index);
- }
-}
-
-
-//*****************************************************************************
-//
-// WideStrToMultiStr()
-//
-//*****************************************************************************
-
-PCHAR WideStrToMultiStr (PWCHAR WideStr)
-{
- ULONG nBytes;
- PCHAR MultiStr;
-
- // Get the length of the converted string
- //
- nBytes = WideCharToMultiByte(
- CP_ACP,
- 0,
- WideStr,
- -1,
- NULL,
- 0,
- NULL,
- NULL);
-
- if (nBytes == 0)
- {
- return NULL;
- }
-
- // Allocate space to hold the converted string
- //
- MultiStr = (PCHAR)RTMemAllocZ(nBytes);
-
- if (MultiStr == NULL)
- {
- return NULL;
- }
-
- // Convert the string
- //
- nBytes = WideCharToMultiByte(
- CP_ACP,
- 0,
- WideStr,
- -1,
- MultiStr,
- nBytes,
- NULL,
- NULL);
-
- if (nBytes == 0)
- {
- RTMemFree(MultiStr);
- return NULL;
- }
-
- return MultiStr;
-}
-
-
-//*****************************************************************************
-//
-// GetRootHubName()
-//
-//*****************************************************************************
-
-PCHAR GetRootHubName (
- HANDLE HostController
-)
-{
- BOOL success;
- ULONG nBytes;
- USB_ROOT_HUB_NAME rootHubName;
- PUSB_ROOT_HUB_NAME rootHubNameW;
- PCHAR rootHubNameA;
-
- rootHubNameW = NULL;
- rootHubNameA = NULL;
-
- // Get the length of the name of the Root Hub attached to the
- // Host Controller
- //
- success = DeviceIoControl(HostController,
- IOCTL_USB_GET_ROOT_HUB_NAME,
- 0,
- 0,
- &rootHubName,
- sizeof(rootHubName),
- &nBytes,
- NULL);
-
- if (!success)
- {
- AssertFailed();
- goto GetRootHubNameError;
- }
-
- // Allocate space to hold the Root Hub name
- //
- nBytes = rootHubName.ActualLength;
-
- rootHubNameW = (PUSB_ROOT_HUB_NAME)RTMemAllocZ(nBytes);
-
- if (rootHubNameW == NULL)
- {
- AssertFailed();
- goto GetRootHubNameError;
- }
-
- // Get the name of the Root Hub attached to the Host Controller
- //
- success = DeviceIoControl(HostController,
- IOCTL_USB_GET_ROOT_HUB_NAME,
- NULL,
- 0,
- rootHubNameW,
- nBytes,
- &nBytes,
- NULL);
-
- if (!success)
- {
- AssertFailed();
- goto GetRootHubNameError;
- }
-
- // Convert the Root Hub name
- //
- rootHubNameA = WideStrToMultiStr(rootHubNameW->RootHubName);
-
- // All done, free the uncoverted Root Hub name and return the
- // converted Root Hub name
- //
- RTMemFree(rootHubNameW);
-
- return rootHubNameA;
-
-
-GetRootHubNameError:
- // There was an error, free anything that was allocated
- //
- if (rootHubNameW != NULL)
- {
- RTMemFree(rootHubNameW);
- rootHubNameW = NULL;
- }
-
- return NULL;
-}
-
-
-//*****************************************************************************
-//
-// GetExternalHubName()
-//
-//*****************************************************************************
-
-PCHAR GetExternalHubName (
- HANDLE Hub,
- ULONG ConnectionIndex
-)
-{
- BOOL success;
- ULONG nBytes;
- USB_NODE_CONNECTION_NAME extHubName;
- PUSB_NODE_CONNECTION_NAME extHubNameW;
- PCHAR extHubNameA;
-
- extHubNameW = NULL;
- extHubNameA = NULL;
-
- // Get the length of the name of the external hub attached to the
- // specified port.
- //
- extHubName.ConnectionIndex = ConnectionIndex;
-
- success = DeviceIoControl(Hub,
- IOCTL_USB_GET_NODE_CONNECTION_NAME,
- &extHubName,
- sizeof(extHubName),
- &extHubName,
- sizeof(extHubName),
- &nBytes,
- NULL);
-
- if (!success)
- {
- AssertFailed();
- goto GetExternalHubNameError;
- }
-
- // Allocate space to hold the external hub name
- //
- nBytes = extHubName.ActualLength;
-
- if (nBytes <= sizeof(extHubName))
- {
- AssertFailed();
- goto GetExternalHubNameError;
- }
-
- extHubNameW = (PUSB_NODE_CONNECTION_NAME)RTMemAllocZ(nBytes);
-
- if (extHubNameW == NULL)
- {
- AssertFailed();
- goto GetExternalHubNameError;
- }
-
- // Get the name of the external hub attached to the specified port
- //
- extHubNameW->ConnectionIndex = ConnectionIndex;
-
- success = DeviceIoControl(Hub,
- IOCTL_USB_GET_NODE_CONNECTION_NAME,
- extHubNameW,
- nBytes,
- extHubNameW,
- nBytes,
- &nBytes,
- NULL);
-
- if (!success)
- {
- AssertFailed();
- goto GetExternalHubNameError;
- }
-
- // Convert the External Hub name
- //
- extHubNameA = WideStrToMultiStr(extHubNameW->NodeName);
-
- // All done, free the uncoverted external hub name and return the
- // converted external hub name
- //
- RTMemFree(extHubNameW);
-
- return extHubNameA;
-
-
-GetExternalHubNameError:
- // There was an error, free anything that was allocated
- //
- if (extHubNameW != NULL)
- {
- RTMemFree(extHubNameW);
- extHubNameW = NULL;
- }
-
- return NULL;
-}
-
-
-//*****************************************************************************
-//
-// GetDriverKeyName()
-//
-//*****************************************************************************
-
-PCHAR GetDriverKeyName (
- HANDLE Hub,
- ULONG ConnectionIndex
-)
-{
- BOOL success;
- ULONG nBytes;
- USB_NODE_CONNECTION_DRIVERKEY_NAME driverKeyName;
- PUSB_NODE_CONNECTION_DRIVERKEY_NAME driverKeyNameW;
- PCHAR driverKeyNameA;
-
- driverKeyNameW = NULL;
- driverKeyNameA = NULL;
-
- // Get the length of the name of the driver key of the device attached to
- // the specified port.
- //
- driverKeyName.ConnectionIndex = ConnectionIndex;
-
- success = DeviceIoControl(Hub,
- IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,
- &driverKeyName,
- sizeof(driverKeyName),
- &driverKeyName,
- sizeof(driverKeyName),
- &nBytes,
- NULL);
-
- if (!success)
- {
- goto GetDriverKeyNameError;
- }
-
- // Allocate space to hold the driver key name
- //
- nBytes = driverKeyName.ActualLength;
-
- if (nBytes <= sizeof(driverKeyName))
- {
- AssertFailed();
- goto GetDriverKeyNameError;
- }
-
- driverKeyNameW = (PUSB_NODE_CONNECTION_DRIVERKEY_NAME)RTMemAllocZ(nBytes);
-
- if (driverKeyNameW == NULL)
- {
- AssertFailed();
- goto GetDriverKeyNameError;
- }
-
- // Get the name of the driver key of the device attached to
- // the specified port.
- //
- driverKeyNameW->ConnectionIndex = ConnectionIndex;
-
- success = DeviceIoControl(Hub,
- IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,
- driverKeyNameW,
- nBytes,
- driverKeyNameW,
- nBytes,
- &nBytes,
- NULL);
-
- if (!success)
- {
- AssertFailed();
- goto GetDriverKeyNameError;
- }
-
- // Convert the driver key name
- //
- driverKeyNameA = WideStrToMultiStr(driverKeyNameW->DriverKeyName);
-
- // All done, free the uncoverted driver key name and return the
- // converted driver key name
- //
- RTMemFree(driverKeyNameW);
-
- return driverKeyNameA;
-
-
-GetDriverKeyNameError:
- // There was an error, free anything that was allocated
- //
- if (driverKeyNameW != NULL)
- {
- RTMemFree(driverKeyNameW);
- driverKeyNameW = NULL;
- }
-
- return NULL;
-}
-
-
-//*****************************************************************************
-//
-// GetHCDDriverKeyName()
-//
-//*****************************************************************************
-
-PCHAR GetHCDDriverKeyName (
- HANDLE HCD
-)
-{
- BOOL success;
- ULONG nBytes;
- USB_HCD_DRIVERKEY_NAME driverKeyName;
- PUSB_HCD_DRIVERKEY_NAME driverKeyNameW;
- PCHAR driverKeyNameA;
-
- driverKeyNameW = NULL;
- driverKeyNameA = NULL;
-
- // Get the length of the name of the driver key of the HCD
- //
- success = DeviceIoControl(HCD,
- IOCTL_GET_HCD_DRIVERKEY_NAME,
- &driverKeyName,
- sizeof(driverKeyName),
- &driverKeyName,
- sizeof(driverKeyName),
- &nBytes,
- NULL);
-
- if (!success)
- {
- AssertFailed();
- goto GetHCDDriverKeyNameError;
- }
-
- // Allocate space to hold the driver key name
- //
- nBytes = driverKeyName.ActualLength;
-
- if (nBytes <= sizeof(driverKeyName))
- {
- AssertFailed();
- goto GetHCDDriverKeyNameError;
- }
-
- driverKeyNameW = (PUSB_HCD_DRIVERKEY_NAME)RTMemAllocZ(nBytes);
-
- if (driverKeyNameW == NULL)
- {
- AssertFailed();
- goto GetHCDDriverKeyNameError;
- }
-
- // Get the name of the driver key of the device attached to
- // the specified port.
- //
- success = DeviceIoControl(HCD,
- IOCTL_GET_HCD_DRIVERKEY_NAME,
- driverKeyNameW,
- nBytes,
- driverKeyNameW,
- nBytes,
- &nBytes,
- NULL);
-
- if (!success)
- {
- AssertFailed();
- goto GetHCDDriverKeyNameError;
- }
-
- // Convert the driver key name
- //
- driverKeyNameA = WideStrToMultiStr(driverKeyNameW->DriverKeyName);
-
- // All done, free the uncoverted driver key name and return the
- // converted driver key name
- //
- RTMemFree(driverKeyNameW);
-
- return driverKeyNameA;
-
-
-GetHCDDriverKeyNameError:
- // There was an error, free anything that was allocated
- //
- if (driverKeyNameW != NULL)
- {
- RTMemFree(driverKeyNameW);
- driverKeyNameW = NULL;
- }
-
- return NULL;
-}
-
-
-//*****************************************************************************
-//
-// GetConfigDescriptor()
-//
-// hHubDevice - Handle of the hub device containing the port from which the
-// Configuration Descriptor will be requested.
-//
-// ConnectionIndex - Identifies the port on the hub to which a device is
-// attached from which the Configuration Descriptor will be requested.
-//
-// DescriptorIndex - Configuration Descriptor index, zero based.
-//
-//*****************************************************************************
-
-PUSB_DESCRIPTOR_REQUEST
-GetConfigDescriptor (
- HANDLE hHubDevice,
- ULONG ConnectionIndex,
- UCHAR DescriptorIndex
-)
-{
- BOOL success;
- ULONG nBytes;
- ULONG nBytesReturned;
-
- UCHAR configDescReqBuf[sizeof(USB_DESCRIPTOR_REQUEST) +
- sizeof(USB_CONFIGURATION_DESCRIPTOR)];
-
- PUSB_DESCRIPTOR_REQUEST configDescReq;
- PUSB_CONFIGURATION_DESCRIPTOR configDesc;
-
-
- // Request the Configuration Descriptor the first time using our
- // local buffer, which is just big enough for the Cofiguration
- // Descriptor itself.
- //
- nBytes = sizeof(configDescReqBuf);
-
- configDescReq = (PUSB_DESCRIPTOR_REQUEST)configDescReqBuf;
- configDesc = (PUSB_CONFIGURATION_DESCRIPTOR)(configDescReq+1);
-
- // Zero fill the entire request structure
- //
- memset(configDescReq, 0, nBytes);
-
- // Indicate the port from which the descriptor will be requested
- //
- configDescReq->ConnectionIndex = ConnectionIndex;
-
- //
- // USBHUB uses URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE to process this
- // IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION request.
- //
- // USBD will automatically initialize these fields:
- // bmRequest = 0x80
- // bRequest = 0x06
- //
- // We must initialize these fields:
- // wValue = Descriptor Type (high) and Descriptor Index (low byte)
- // wIndex = Zero (or Language ID for String Descriptors)
- // wLength = Length of descriptor buffer
- //
- configDescReq->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8)
- | DescriptorIndex;
-
- configDescReq->SetupPacket.wLength = (USHORT)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST));
-
- // Now issue the get descriptor request.
- //
- success = DeviceIoControl(hHubDevice,
- IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
- configDescReq,
- nBytes,
- configDescReq,
- nBytes,
- &nBytesReturned,
- NULL);
-
- if (!success)
- {
-#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
- AssertMsgFailed(("DeviceIoControl IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION failed with LastError=%Rwa\n", GetLastError()));
-#else
- LogRel(("DeviceIoControl IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION failed with LastError=%Rwa\n", GetLastError()));
-#endif
- return NULL;
- }
-
- if (nBytes != nBytesReturned)
- {
- AssertFailed();
- return NULL;
- }
-
- if (configDesc->wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))
- {
- AssertFailed();
- return NULL;
- }
-
- // Now request the entire Configuration Descriptor using a dynamically
- // allocated buffer which is sized big enough to hold the entire descriptor
- //
- nBytes = sizeof(USB_DESCRIPTOR_REQUEST) + configDesc->wTotalLength;
-
- configDescReq = (PUSB_DESCRIPTOR_REQUEST)RTMemAllocZ(nBytes);
-
- if (configDescReq == NULL)
- {
- AssertFailed();
- return NULL;
- }
-
- configDesc = (PUSB_CONFIGURATION_DESCRIPTOR)(configDescReq+1);
-
- // Indicate the port from which the descriptor will be requested
- //
- configDescReq->ConnectionIndex = ConnectionIndex;
-
- //
- // USBHUB uses URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE to process this
- // IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION request.
- //
- // USBD will automatically initialize these fields:
- // bmRequest = 0x80
- // bRequest = 0x06
- //
- // We must initialize these fields:
- // wValue = Descriptor Type (high) and Descriptor Index (low byte)
- // wIndex = Zero (or Language ID for String Descriptors)
- // wLength = Length of descriptor buffer
- //
- configDescReq->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8)
- | DescriptorIndex;
-
- configDescReq->SetupPacket.wLength = (USHORT)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST));
-
- // Now issue the get descriptor request.
- //
- success = DeviceIoControl(hHubDevice,
- IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
- configDescReq,
- nBytes,
- configDescReq,
- nBytes,
- &nBytesReturned,
- NULL);
-
- if (!success)
- {
-#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
- AssertMsgFailed(("DeviceIoControl IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION failed with LastError=%Rwa\n", GetLastError()));
-#else
- LogRel(("DeviceIoControl IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION failed with LastError=%Rwa\n", GetLastError()));
-#endif
- RTMemFree(configDescReq);
- return NULL;
- }
-
- if (nBytes != nBytesReturned)
- {
-#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
- AssertMsgFailed(("DeviceIoControl IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION %d != %d\n", nBytes, nBytesReturned));
-#else
- LogRel(("DeviceIoControl IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION %d != %d\n", nBytes, nBytesReturned));
-#endif
- RTMemFree(configDescReq);
- return NULL;
- }
-
- if (configDesc->wTotalLength != (nBytes - sizeof(USB_DESCRIPTOR_REQUEST)))
- {
-#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
- AssertMsgFailed(("DeviceIoControl IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION %d != %d\n", configDesc->wTotalLength, (nBytes - sizeof(USB_DESCRIPTOR_REQUEST))));
-#else
- LogRel(("DeviceIoControl IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION %d != %d\n", configDesc->wTotalLength, (nBytes - sizeof(USB_DESCRIPTOR_REQUEST)) ));
-#endif
- RTMemFree(configDescReq);
- return NULL;
- }
-
- return configDescReq;
-}
-
-
-//*****************************************************************************
-//
-// AreThereStringDescriptors()
-//
-// DeviceDesc - Device Descriptor for which String Descriptors should be
-// checked.
-//
-// ConfigDesc - Configuration Descriptor (also containing Interface Descriptor)
-// for which String Descriptors should be checked.
-//
-//*****************************************************************************
-
-BOOL
-AreThereStringDescriptors (
- PUSB_DEVICE_DESCRIPTOR DeviceDesc,
- PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc
-)
-{
- PUCHAR descEnd;
- PUSB_COMMON_DESCRIPTOR commonDesc;
-
- //
- // Check Device Descriptor strings
- //
-
- if (DeviceDesc->iManufacturer ||
- DeviceDesc->iProduct ||
- DeviceDesc->iSerialNumber
- )
- {
- return TRUE;
- }
-
-
- //
- // Check the Configuration and Interface Descriptor strings
- //
-
- descEnd = (PUCHAR)ConfigDesc + ConfigDesc->wTotalLength;
-
- commonDesc = (PUSB_COMMON_DESCRIPTOR)ConfigDesc;
-
- while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd &&
- (PUCHAR)commonDesc + commonDesc->bLength <= descEnd)
- {
- switch (commonDesc->bDescriptorType)
- {
- case USB_CONFIGURATION_DESCRIPTOR_TYPE:
- if (commonDesc->bLength != sizeof(USB_CONFIGURATION_DESCRIPTOR))
- {
- AssertFailed();
- break;
- }
- if (((PUSB_CONFIGURATION_DESCRIPTOR)commonDesc)->iConfiguration)
- {
- return TRUE;
- }
- commonDesc = (PUSB_COMMON_DESCRIPTOR)((PUCHAR)commonDesc + commonDesc->bLength);
- continue;
-
- case USB_INTERFACE_DESCRIPTOR_TYPE:
- if (commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR) &&
- commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR2))
- {
- AssertFailed();
- break;
- }
- if (((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->iInterface)
- {
- return TRUE;
- }
- commonDesc = (PUSB_COMMON_DESCRIPTOR)((PUCHAR)commonDesc + commonDesc->bLength);
- continue;
-
- default:
- commonDesc = (PUSB_COMMON_DESCRIPTOR)((PUCHAR)commonDesc + commonDesc->bLength);
- continue;
- }
- break;
- }
-
- return FALSE;
-}
-
-
-//*****************************************************************************
-//
-// GetAllStringDescriptors()
-//
-// hHubDevice - Handle of the hub device containing the port from which the
-// String Descriptors will be requested.
-//
-// ConnectionIndex - Identifies the port on the hub to which a device is
-// attached from which the String Descriptors will be requested.
-//
-// DeviceDesc - Device Descriptor for which String Descriptors should be
-// requested.
-//
-// ConfigDesc - Configuration Descriptor (also containing Interface Descriptor)
-// for which String Descriptors should be requested.
-//
-//*****************************************************************************
-
-PSTRING_DESCRIPTOR_NODE
-GetAllStringDescriptors (
- HANDLE hHubDevice,
- ULONG ConnectionIndex,
- PUSB_DEVICE_DESCRIPTOR DeviceDesc,
- PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc
-)
-{
- PSTRING_DESCRIPTOR_NODE supportedLanguagesString;
- PSTRING_DESCRIPTOR_NODE stringDescNodeTail;
- ULONG numLanguageIDs;
- USHORT *languageIDs;
-
- PUCHAR descEnd;
- PUSB_COMMON_DESCRIPTOR commonDesc;
-
- //
- // Get the array of supported Language IDs, which is returned
- // in String Descriptor 0
- //
- supportedLanguagesString = GetStringDescriptor(hHubDevice,
- ConnectionIndex,
- 0,
- 0);
-
- if (supportedLanguagesString == NULL)
- {
- return NULL;
- }
-
- numLanguageIDs = (supportedLanguagesString->StringDescriptor->bLength - 2) / 2;
-
- languageIDs = (PUSHORT)&supportedLanguagesString->StringDescriptor->bString[0];
-
- stringDescNodeTail = supportedLanguagesString;
-
- //
- // Get the Device Descriptor strings
- //
-
- if (DeviceDesc->iManufacturer)
- {
- stringDescNodeTail = GetStringDescriptors(hHubDevice,
- ConnectionIndex,
- DeviceDesc->iManufacturer,
- numLanguageIDs,
- languageIDs,
- stringDescNodeTail);
- }
-
- if (DeviceDesc->iProduct)
- {
- stringDescNodeTail = GetStringDescriptors(hHubDevice,
- ConnectionIndex,
- DeviceDesc->iProduct,
- numLanguageIDs,
- languageIDs,
- stringDescNodeTail);
- }
-
- if (DeviceDesc->iSerialNumber)
- {
- stringDescNodeTail = GetStringDescriptors(hHubDevice,
- ConnectionIndex,
- DeviceDesc->iSerialNumber,
- numLanguageIDs,
- languageIDs,
- stringDescNodeTail);
- }
-
-
- //
- // Get the Configuration and Interface Descriptor strings
- //
-
- descEnd = (PUCHAR)ConfigDesc + ConfigDesc->wTotalLength;
-
- commonDesc = (PUSB_COMMON_DESCRIPTOR)ConfigDesc;
-
- while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd &&
- (PUCHAR)commonDesc + commonDesc->bLength <= descEnd)
- {
- switch (commonDesc->bDescriptorType)
- {
- case USB_CONFIGURATION_DESCRIPTOR_TYPE:
- if (commonDesc->bLength != sizeof(USB_CONFIGURATION_DESCRIPTOR))
- {
- AssertFailed();
- break;
- }
- if (((PUSB_CONFIGURATION_DESCRIPTOR)commonDesc)->iConfiguration)
- {
- stringDescNodeTail = GetStringDescriptors(
- hHubDevice,
- ConnectionIndex,
- ((PUSB_CONFIGURATION_DESCRIPTOR)commonDesc)->iConfiguration,
- numLanguageIDs,
- languageIDs,
- stringDescNodeTail);
- }
- commonDesc = (PUSB_COMMON_DESCRIPTOR)((PUCHAR)commonDesc + commonDesc->bLength);
- continue;
-
- case USB_INTERFACE_DESCRIPTOR_TYPE:
- if (commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR) &&
- commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR2))
- {
- AssertFailed();
- break;
- }
- if (((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->iInterface)
- {
- stringDescNodeTail = GetStringDescriptors(
- hHubDevice,
- ConnectionIndex,
- ((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->iInterface,
- numLanguageIDs,
- languageIDs,
- stringDescNodeTail);
- }
- commonDesc = (PUSB_COMMON_DESCRIPTOR)((PUCHAR)commonDesc + commonDesc->bLength);
- continue;
-
- default:
- commonDesc = (PUSB_COMMON_DESCRIPTOR)((PUCHAR)commonDesc + commonDesc->bLength);
- continue;
- }
- break;
- }
-
- return supportedLanguagesString;
-}
-
-
-//*****************************************************************************
-//
-// GetStringDescriptor()
-//
-// hHubDevice - Handle of the hub device containing the port from which the
-// String Descriptor will be requested.
-//
-// ConnectionIndex - Identifies the port on the hub to which a device is
-// attached from which the String Descriptor will be requested.
-//
-// DescriptorIndex - String Descriptor index.
-//
-// LanguageID - Language in which the string should be requested.
-//
-//*****************************************************************************
-
-PSTRING_DESCRIPTOR_NODE
-GetStringDescriptor (
- HANDLE hHubDevice,
- ULONG ConnectionIndex,
- UCHAR DescriptorIndex,
- USHORT LanguageID
-)
-{
- BOOL success;
- ULONG nBytes;
- ULONG nBytesReturned;
-
- UCHAR stringDescReqBuf[sizeof(USB_DESCRIPTOR_REQUEST) +
- MAXIMUM_USB_STRING_LENGTH];
-
- PUSB_DESCRIPTOR_REQUEST stringDescReq;
- PUSB_STRING_DESCRIPTOR stringDesc;
- PSTRING_DESCRIPTOR_NODE stringDescNode;
-
- nBytes = sizeof(stringDescReqBuf);
-
- stringDescReq = (PUSB_DESCRIPTOR_REQUEST)stringDescReqBuf;
- stringDesc = (PUSB_STRING_DESCRIPTOR)(stringDescReq+1);
-
- // Zero fill the entire request structure
- //
- memset(stringDescReq, 0, nBytes);
-
- // Indicate the port from which the descriptor will be requested
- //
- stringDescReq->ConnectionIndex = ConnectionIndex;
-
- //
- // USBHUB uses URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE to process this
- // IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION request.
- //
- // USBD will automatically initialize these fields:
- // bmRequest = 0x80
- // bRequest = 0x06
- //
- // We must initialize these fields:
- // wValue = Descriptor Type (high) and Descriptor Index (low byte)
- // wIndex = Zero (or Language ID for String Descriptors)
- // wLength = Length of descriptor buffer
- //
- stringDescReq->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8)
- | DescriptorIndex;
-
- stringDescReq->SetupPacket.wIndex = LanguageID;
-
- stringDescReq->SetupPacket.wLength = (USHORT)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST));
-
- // Now issue the get descriptor request.
- //
- success = DeviceIoControl(hHubDevice,
- IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
- stringDescReq,
- nBytes,
- stringDescReq,
- nBytes,
- &nBytesReturned,
- NULL);
-
- //
- // Do some sanity checks on the return from the get descriptor request.
- //
-
- if (!success)
- {
-#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
- AssertMsgFailed(("DeviceIoControl IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION failed with LastError=%Rwa\n", GetLastError()));
-#else
- LogRel(("DeviceIoControl IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION failed with LastError=%Rwa\n", GetLastError()));
-#endif
- return NULL;
- }
-
- if (nBytesReturned < 2)
- {
- AssertFailed();
- return NULL;
- }
-
- if (stringDesc->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE)
- {
- AssertFailed();
- return NULL;
- }
-
- if (stringDesc->bLength != nBytesReturned - sizeof(USB_DESCRIPTOR_REQUEST))
- {
- AssertFailed();
- return NULL;
- }
-
- if (stringDesc->bLength % 2 != 0)
- {
- AssertFailed();
- return NULL;
- }
-
- //
- // Looks good, allocate some (zero filled) space for the string descriptor
- // node and copy the string descriptor to it.
- //
-
- stringDescNode = (PSTRING_DESCRIPTOR_NODE)RTMemAllocZ(sizeof(STRING_DESCRIPTOR_NODE) +
- stringDesc->bLength + 2);
-
- if (stringDescNode == NULL)
- {
- AssertFailed();
- return NULL;
- }
-
- stringDescNode->DescriptorIndex = DescriptorIndex;
- stringDescNode->LanguageID = LanguageID;
-
- memcpy(stringDescNode->StringDescriptor,
- stringDesc,
- stringDesc->bLength);
-
- return stringDescNode;
-}
-
-
-//*****************************************************************************
-//
-// GetStringDescriptors()
-//
-// hHubDevice - Handle of the hub device containing the port from which the
-// String Descriptor will be requested.
-//
-// ConnectionIndex - Identifies the port on the hub to which a device is
-// attached from which the String Descriptor will be requested.
-//
-// DescriptorIndex - String Descriptor index.
-//
-// NumLanguageIDs - Number of languages in which the string should be
-// requested.
-//
-// LanguageIDs - Languages in which the string should be requested.
-//
-//*****************************************************************************
-
-PSTRING_DESCRIPTOR_NODE
-GetStringDescriptors (
- HANDLE hHubDevice,
- ULONG ConnectionIndex,
- UCHAR DescriptorIndex,
- ULONG NumLanguageIDs,
- USHORT *LanguageIDs,
- PSTRING_DESCRIPTOR_NODE StringDescNodeTail
-)
-{
- ULONG i;
-
- for (i = 0; i < NumLanguageIDs; i++)
- {
- StringDescNodeTail->Next = GetStringDescriptor(hHubDevice,
- ConnectionIndex,
- DescriptorIndex,
- *LanguageIDs);
-
- if (StringDescNodeTail->Next)
- {
- StringDescNodeTail = StringDescNodeTail->Next;
- }
-
- LanguageIDs++;
- }
-
- return StringDescNodeTail;
-}
-
-
-//*****************************************************************************
-//
-// DriverNameToDeviceDesc()
-//
-// Returns the Device Description of the DevNode with the matching DriverName.
-// Returns NULL if the matching DevNode is not found.
-//
-// The caller should copy the returned string buffer instead of just saving
-// the pointer value. XXXXX Dynamically allocate return buffer?
-//
-//*****************************************************************************
-CHAR buf[512]; // XXXXX How big does this have to be? Dynamically size it?
-
-PCHAR DriverNameToDeviceDesc (PCHAR DriverName)
-{
- DEVINST devInst;
- DEVINST devInstNext;
- CONFIGRET cr;
- ULONG walkDone = 0;
- ULONG len;
-
- // Get Root DevNode
- //
- cr = CM_Locate_DevNode(&devInst,
- NULL,
- 0);
-
- if (cr != CR_SUCCESS)
- {
- return NULL;
- }
-
- // Do a depth first search for the DevNode with a matching
- // DriverName value
- //
- while (!walkDone)
- {
- // Get the DriverName value
- //
- len = sizeof(buf);
- cr = CM_Get_DevNode_Registry_Property(devInst,
- CM_DRP_DRIVER,
- NULL,
- buf,
- &len,
- 0);
-
- // If the DriverName value matches, return the DeviceDescription
- //
- if (cr == CR_SUCCESS && _stricmp(DriverName, buf) == 0)
- {
- len = sizeof(buf);
- cr = CM_Get_DevNode_Registry_Property(devInst,
- CM_DRP_DEVICEDESC,
- NULL,
- buf,
- &len,
- 0);
-
- if (cr == CR_SUCCESS)
- {
- return buf;
- }
- else
- {
- return NULL;
- }
- }
-
- // This DevNode didn't match, go down a level to the first child.
- //
- cr = CM_Get_Child(&devInstNext,
- devInst,
- 0);
-
- if (cr == CR_SUCCESS)
- {
- devInst = devInstNext;
- continue;
- }
-
- // Can't go down any further, go across to the next sibling. If
- // there are no more siblings, go back up until there is a sibling.
- // If we can't go up any further, we're back at the root and we're
- // done.
- //
- for (;;)
- {
- cr = CM_Get_Sibling(&devInstNext,
- devInst,
- 0);
-
- if (cr == CR_SUCCESS)
- {
- devInst = devInstNext;
- break;
- }
-
- cr = CM_Get_Parent(&devInstNext,
- devInst,
- 0);
-
-
- if (cr == CR_SUCCESS)
- {
- devInst = devInstNext;
- }
- else
- {
- walkDone = 1;
- break;
- }
- }
- }
-
- return NULL;
-}
-
-
-/**
- * Attempts to start the service, creating it if necessary.
- *
- * @returns 0 on success.
- * @returns -1 on failure.
- * @param fRetry Indicates retry call.
- */
-int usbMonStartService(void)
-{
- /*
- * Check if the driver service is there.
- */
- SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_QUERY_STATUS | SERVICE_START);
- if (hSMgr == NULL)
- {
- AssertMsgFailed(("couldn't open service manager in SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS mode!\n"));
- return -1;
- }
-
- /*
- * Try open our service to check it's status.
- */
- SC_HANDLE hService = OpenService(hSMgr, USBMON_SERVICE_NAME, SERVICE_QUERY_STATUS | SERVICE_START);
- if (!hService)
- return -1;
-
- /*
- * Check if open and on demand create succeeded.
- */
- int rc = -1;
- if (hService)
- {
-
- /*
- * Query service status to see if we need to start it or not.
- */
- SERVICE_STATUS Status;
- BOOL fRc = QueryServiceStatus(hService, &Status);
- Assert(fRc);
- if ( Status.dwCurrentState != SERVICE_RUNNING
- && Status.dwCurrentState != SERVICE_START_PENDING)
- {
- /*
- * Start it.
- */
- LogRel(("usbMonStartService -> start it\n"));
-
- fRc = StartService(hService, 0, NULL);
- DWORD LastError = GetLastError(); NOREF(LastError);
- AssertMsg(fRc, ("StartService failed with LastError=%Rwa\n", LastError));
- if (fRc)
- g_fStartedService = true;
- }
-
- /*
- * Wait for the service to finish starting.
- * We'll wait for 10 seconds then we'll give up.
- */
- QueryServiceStatus(hService, &Status);
- if (Status.dwCurrentState == SERVICE_START_PENDING)
- {
- int iWait;
- for (iWait = 100; iWait > 0 && Status.dwCurrentState == SERVICE_START_PENDING; iWait--)
- {
- Sleep(100);
- QueryServiceStatus(hService, &Status);
- }
- DWORD LastError = GetLastError(); NOREF(LastError);
- AssertMsg(Status.dwCurrentState != SERVICE_RUNNING,
- ("Failed to start. LastError=%Rwa iWait=%d status=%d\n",
- LastError, iWait, Status.dwCurrentState));
- }
-
- if (Status.dwCurrentState == SERVICE_RUNNING)
- rc = 0;
-
- /*
- * Close open handles.
- */
- CloseServiceHandle(hService);
- }
- else
- {
- DWORD LastError = GetLastError(); NOREF(LastError);
- AssertMsgFailed(("OpenService failed! LastError=%Rwa\n", LastError));
- }
- if (!CloseServiceHandle(hSMgr))
- AssertFailed();
-
- return rc;
-}
-
-/**
- * Stops a possibly running service.
- *
- * @returns 0 on success.
- * @returns -1 on failure.
- */
-int usbMonStopService(void)
-{
- LogRel(("usbMonStopService\n"));
- /*
- * Assume it didn't exist, so we'll create the service.
- */
- int rc = -1;
- SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_STOP | SERVICE_QUERY_STATUS);
- DWORD LastError = GetLastError(); NOREF(LastError);
- AssertMsg(hSMgr, ("OpenSCManager(,,delete) failed rc=%d\n", LastError));
- if (hSMgr)
- {
- SC_HANDLE hService = OpenService(hSMgr, USBMON_SERVICE_NAME, SERVICE_STOP | SERVICE_QUERY_STATUS);
- if (hService)
- {
- /*
- * Stop the service.
- */
- SERVICE_STATUS Status;
- QueryServiceStatus(hService, &Status);
- if (Status.dwCurrentState == SERVICE_STOPPED)
- rc = 0;
- else if (ControlService(hService, SERVICE_CONTROL_STOP, &Status))
- {
- int iWait = 100;
- while (Status.dwCurrentState == SERVICE_STOP_PENDING && iWait-- > 0)
- {
- Sleep(100);
- QueryServiceStatus(hService, &Status);
- }
- if (Status.dwCurrentState == SERVICE_STOPPED)
- rc = 0;
- else
- AssertMsgFailed(("Failed to stop service. status=%d\n", Status.dwCurrentState));
- }
- else
- {
- DWORD LastError = GetLastError(); NOREF(LastError);
- AssertMsgFailed(("ControlService failed with LastError=%Rwa. status=%d\n", LastError, Status.dwCurrentState));
- }
- CloseServiceHandle(hService);
- }
- else if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
- rc = 0;
- else
- {
- DWORD LastError = GetLastError(); NOREF(LastError);
- AssertMsgFailed(("OpenService failed with LastError=%Rwa\n", LastError));
- }
- CloseServiceHandle(hSMgr);
- }
- return rc;
-}
-
-
-/**
- * Initialize the USB library
- *
- * @returns VBox status code.
- */
-USBLIB_DECL(int) USBLibInit(void)
-{
- int rc;
- USBSUP_VERSION version = {0};
- DWORD cbReturned;
-
- Log(("usbproxy: usbLibInit\n"));
-
- g_hUSBMonitor = CreateFile(USBMON_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
-
- if (g_hUSBMonitor == INVALID_HANDLE_VALUE)
- {
- usbMonStartService();
-
- g_hUSBMonitor = CreateFile(USBMON_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
-
- if (g_hUSBMonitor == INVALID_HANDLE_VALUE)
- {
- /* AssertFailed(); */
- LogRel(("usbproxy: Unable to open monitor driver!! LastError=%Rwa\n", GetLastError()));
- rc = VERR_FILE_NOT_FOUND;
- goto failure;
- }
- }
-
- /*
- * Check the version
- */
- cbReturned = 0;
- if (!DeviceIoControl(g_hUSBMonitor, SUPUSBFLT_IOCTL_GET_VERSION, NULL, 0,&version, sizeof(version), &cbReturned, NULL))
- {
- LogRel(("usbproxy: Unable to query filter version!! LastError=%Rwa\n", GetLastError()));
- rc = VERR_VERSION_MISMATCH;
- goto failure;
- }
-
- if (version.u32Major != USBMON_MAJOR_VERSION ||
- version.u32Minor < USBMON_MINOR_VERSION)
- {
- LogRel(("usbproxy: Filter driver version mismatch!!\n"));
- rc = VERR_VERSION_MISMATCH;
- goto failure;
- }
- return VINF_SUCCESS;
-
-failure:
- if (g_hUSBMonitor != INVALID_HANDLE_VALUE)
- {
- CloseHandle(g_hUSBMonitor);
- g_hUSBMonitor = INVALID_HANDLE_VALUE;
- }
- return rc;
-}
-
-
-/**
- * Terminate the USB library
- *
- * @returns VBox status code.
- */
-USBLIB_DECL(int) USBLibTerm(void)
-{
- if (g_hUSBMonitor != INVALID_HANDLE_VALUE)
- {
- CloseHandle(g_hUSBMonitor);
- g_hUSBMonitor = INVALID_HANDLE_VALUE;
- }
-#if 0
- /*
- * If we started the service we might consider stopping it too.
- *
- * Since this won't work unless the process starting it is the
- * last user we might wanna skip this...
- */
- if (g_fStartedService)
- {
- usbMonStopService();
- g_fStartedService = false;
- }
-#endif
-
- return VINF_SUCCESS;
-}
-
-/**
- * Capture specified USB device
- *
- * @returns VBox status code
- * @param usVendorId Vendor id
- * @param usProductId Product id
- * @param usRevision Revision
- */
-USBLIB_DECL(int) USBLibCaptureDevice(uint16_t usVendorId, uint16_t usProductId, uint16_t usRevision)
-{
- USBSUP_CAPTURE capture;
- DWORD cbReturned = 0;
-
- Log(("usbLibCaptureDevice %x %x %x\n", usVendorId, usProductId, usRevision));
-
- if (g_hUSBMonitor == INVALID_HANDLE_VALUE)
- return VERR_NOT_SUPPORTED;
-
- capture.usVendorId = usVendorId;
- capture.usProductId = usProductId;
- capture.usRevision = usRevision;
-
- if (!DeviceIoControl(g_hUSBMonitor, SUPUSBFLT_IOCTL_CAPTURE_DEVICE, &capture, sizeof(capture), NULL, 0, &cbReturned, NULL))
- {
- AssertMsgFailed(("DeviceIoControl failed with LastError=%Rwa\n", GetLastError()));
- return RTErrConvertFromWin32(GetLastError());
- }
-
- return VINF_SUCCESS;
-}
-
-/**
- * Release specified USB device to the host.
- *
- * @returns VBox status code
- * @param usVendorId Vendor id
- * @param usProductId Product id
- * @param usRevision Revision
- */
-USBLIB_DECL(int) USBLibReleaseDevice(uint16_t usVendorId, uint16_t usProductId, uint16_t usRevision)
-{
- USBSUP_RELEASE release;
- DWORD cbReturned = 0;
-
- Log(("usbLibReleaseDevice %x %x %x\n", usVendorId, usProductId, usRevision));
-
- if (g_hUSBMonitor == INVALID_HANDLE_VALUE)
- return VERR_NOT_SUPPORTED;
-
- release.usVendorId = usVendorId;
- release.usProductId = usProductId;
- release.usRevision = usRevision;
-
- if (!DeviceIoControl(g_hUSBMonitor, SUPUSBFLT_IOCTL_RELEASE_DEVICE, &release, sizeof(release), NULL, 0, &cbReturned, NULL))
- {
- AssertMsgFailed(("DeviceIoControl failed with LastError=%Rwa\n", GetLastError()));
- return RTErrConvertFromWin32(GetLastError());
- }
-
- return VINF_SUCCESS;
-}
-
-
-USBLIB_DECL(void *) USBLibAddFilter(PCUSBFILTER pFilter)
-{
- USBSUP_FLTADDOUT add_out;
- DWORD cbReturned = 0;
-
- if (g_hUSBMonitor == INVALID_HANDLE_VALUE)
- return NULL;
-
- Log(("usblibInsertFilter: Manufacturer=%s Product=%s Serial=%s\n",
- USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) : "<null>",
- USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) : "<null>",
- USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) : "<null>"));
-
- if (!DeviceIoControl(g_hUSBMonitor, SUPUSBFLT_IOCTL_ADD_FILTER, (LPVOID)pFilter, sizeof(*pFilter), &add_out, sizeof(add_out), &cbReturned, NULL))
- {
- AssertMsgFailed(("DeviceIoControl failed with LastError=%Rwa\n", GetLastError()));
- return NULL;
- }
- if (RT_FAILURE(add_out.rc))
- {
- AssertMsgFailed(("Adding filter failed with %d\n", add_out.rc));
- return NULL;
- }
- return (void *)add_out.uId;
-}
-
-
-USBLIB_DECL(void) USBLibRemoveFilter(void *pvId)
-{
- uintptr_t uId;
- DWORD cbReturned = 0;
-
- if (g_hUSBMonitor == INVALID_HANDLE_VALUE)
- return;
-
- Log(("usblibRemoveFilter %p\n", pvId));
-
- uId = (uintptr_t)pvId;
- if (!DeviceIoControl(g_hUSBMonitor, SUPUSBFLT_IOCTL_REMOVE_FILTER, &uId, sizeof(uId), NULL, 0,&cbReturned, NULL))
- AssertMsgFailed(("DeviceIoControl failed with LastError=%Rwa\n", GetLastError()));
-}
-
-
-static void usbLibLogHostDevices(PUSBDEVICE pDevice)
-{
-#ifdef LOG_ENABLED
- int iDevice = 0;
- while (pDevice)
- {
- iDevice++;
- Log(("Detected device: #%d\n", iDevice));
- Log((" Vendor Id: 0x%04X\n", pDevice->idVendor));
- Log((" Product Id: 0x%04X\n", pDevice->idProduct));
- Log((" Revision: 0x%04X\n", pDevice->bcdDevice));
- Log((" Address: %s\n", pDevice->pszAddress));
- Log((" AltAddress: %s\n", pDevice->pszAltAddress));
- Log((" HubName: %s\n", pDevice->pszHubName));
- Log((" Port: %u\n", pDevice->bPort));
- Log((" Manufacturer: %s\n", pDevice->pszManufacturer));
- Log((" Product: %s\n", pDevice->pszProduct));
- if (pDevice->pszSerialNumber)
- Log((" Serial Nr.: %s\n", pDevice->pszSerialNumber));
-
- switch(pDevice->enmState)
- {
- case USBDEVICESTATE_UNSUPPORTED:
- Log((" State USBDEVICESTATE_UNSUPPORTED\n"));
- break;
- case USBDEVICESTATE_USED_BY_HOST:
- Log((" State USBDEVICESTATE_USED_BY_HOST\n"));
- break;
- case USBDEVICESTATE_USED_BY_HOST_CAPTURABLE:
- Log((" State USBDEVICESTATE_USED_BY_HOST_CAPTURABLE\n"));
- break;
- case USBDEVICESTATE_UNUSED:
- Log((" State USBDEVICESTATE_UNUSED\n"));
- break;
- case USBDEVICESTATE_HELD_BY_PROXY:
- Log((" State USBDEVICESTATE_HELD_BY_PROXY\n"));
- break;
- case USBDEVICESTATE_USED_BY_GUEST:
- Log((" State USBDEVICESTATE_USED_BY_GUEST\n"));
- break;
- }
- pDevice = pDevice->pNext;
- }
-#endif
-}
-
-
-/**
- * Return all attached USB devices that are captured by the filter
- *
- * @returns VBox status code
- * @param ppDevices Receives pointer to list of devices
- * @param pcDevices Number of USB devices in the list
- */
-USBLIB_DECL(int) USBLibGetDevices(PUSBDEVICE *ppDevices, uint32_t *pcDevices)
-{
- Log(("usbLibGetDevices: enter\n"));
- int rc = VINF_SUCCESS;
-
- if (g_hUSBMonitor == INVALID_HANDLE_VALUE)
- return VERR_NOT_SUPPORTED;
-
- /*
- * 1: Enumerate all USB devices attached to the host.
- */
- PUSBDEVICE pHostDevices = NULL;
- uint32_t cHostDevices = 0;
- usbLibEnumerateHostControllers(&pHostDevices, &cHostDevices);
-
- Log(("usbLibGetDevices: Detected %d host devices\n", cHostDevices));
- usbLibLogHostDevices(pHostDevices);
-
- /*
- * Get the return data. Note that we might be called a bit too early here.
- * Give Windows time to register the new USB driver/device. It's no problem
- * to block here as we're in the async usb detection thread (not EMT).
- */
- USBSUP_GETNUMDEV numdev;
- *ppDevices = NULL;
- *pcDevices = 0;
- for (uint32_t i = 0; i < 100; i++)
- {
- /*
- * Get the number of USB devices.
- */
- DWORD cbReturned = 0;
- if (!DeviceIoControl(g_hUSBMonitor, SUPUSBFLT_IOCTL_GET_NUM_DEVICES, NULL, 0, &numdev, sizeof(numdev), &cbReturned, NULL))
- {
- DWORD LastError = GetLastError();
- AssertMsgFailed(("DeviceIoControl failed with LastError=%Rwa\n", LastError));
- /* Free the host devices */
- PUSBDEVICE pDevice = pHostDevices;
- while (pDevice)
- {
- PUSBDEVICE pNext = pDevice->pNext;
-
- RTStrFree((char*)pDevice->pszAddress);
- RTStrFree(pDevice->pszAltAddress);
- RTStrFree(pDevice->pszHubName);
- RTStrFree((char*)pDevice->pszManufacturer);
- RTStrFree((char*)pDevice->pszProduct);
- RTStrFree((char*)pDevice->pszSerialNumber);
- RTMemFree(pDevice);
-
- pDevice = pNext;
- }
-
- *ppDevices = NULL;
- int rc = RTErrConvertFromWin32(LastError);
- Log(("usbLibGetDevices: returns %Rrc\n", rc));
- return rc;
- }
-
- AssertMsg((int32_t)numdev.cUSBDevices >= 0, ("%d", numdev.cUSBDevices));
- /* This can be < 0 when detaching a captured device which hadn't yet been
- * opened by a VM process. */
- if ((int32_t)numdev.cUSBDevices <= 0)
- break;
-
- Log(("Monitor detected %d captured devices\n", numdev.cUSBDevices));
-
- usblibEnumDevices(numdev.cUSBDevices, pcDevices);
- Log(("usblibEnumDevices detected %d devices\n", *pcDevices));
-
- if (numdev.cUSBDevices == *pcDevices)
- break;
- RTThreadSleep(100);
- }
- Assert(numdev.cUSBDevices == *pcDevices);
-
- if ((int32_t)numdev.cUSBDevices <= 0 || *pcDevices == 0)
- {
- /* Only return the host devices */
- *ppDevices = pHostDevices;
- *pcDevices = cHostDevices;
- Log(("usbLibGetDevices: returns %d host devices - no captured devices\n", cHostDevices));
- return VINF_SUCCESS;
- }
-
- /*
- * 2: Get all the USB devices that the filter has captured for us. Then
- * update the corresponding device information in the host devices.
- */
- uint32_t cCaptured = 0;
- for (uint32_t i = 0; i < numdev.cUSBDevices; i++)
- {
- USBSUP_GETDEV dev = {0};
- HANDLE hDev;
-
- char *pszDevName = usblibQueryDeviceName(i);
- hDev = CreateFile(pszDevName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
-
- if (hDev != INVALID_HANDLE_VALUE)
- {
- DWORD cbReturned = 0;
- if (!DeviceIoControl(hDev, SUPUSB_IOCTL_GET_DEVICE, &dev, sizeof(dev), &dev, sizeof(dev), &cbReturned, NULL))
- {
- DWORD LastError = GetLastError();
- /* ERROR_DEVICE_NOT_CONNECTED -> device was removed just now */
- AssertMsg(LastError == ERROR_DEVICE_NOT_CONNECTED, ("DeviceIoControl %d failed with LastError=%Rwa\n", i, LastError));
- Log(("SUPUSB_IOCTL_GET_DEVICE: DeviceIoControl %d no longer connected\n", i));
- }
- else
- {
- /* Now search the captured device in the host list and update
- * the information there */
- char *pszDeviceRegPath = usblibQueryDeviceRegPath(i);
- if (pszDeviceRegPath)
- {
- PUSBDEVICE pDevice = pHostDevices;
- uint32_t j;
- for (j = 0; j < cHostDevices; j++)
- {
- if (!strcmp(pszDeviceRegPath, pDevice->pszAddress))
- {
- Log(("usbLibGetDevices: Found captured device in host list %s (%s)\n", pszDeviceRegPath, pszDevName));
-
- pDevice->enmState = USBDEVICESTATE_HELD_BY_PROXY;
- /* The following is not 100% accurate but we only care about high-speed vs. non-high-speed */
- pDevice->enmSpeed = dev.fHiSpeed ? USBDEVICESPEED_HIGH : USBDEVICESPEED_FULL;
- RTStrFree(pDevice->pszAltAddress);
- pDevice->pszAltAddress = (char *)pDevice->pszAddress;
- pDevice->pszAddress = RTStrDup(pszDevName);
- cCaptured++;
- }
- pDevice = pDevice->pNext;
- }
-
- if (j == cHostDevices)
- {
- Assert(!pDevice);
-
- /* Probably in the process of being reattached */
- Log(("usbLibGetDevices: Captured device %s not found in host device list\n", pszDeviceRegPath));
- /* do nothing */
- }
- }
- else
- Log(("usbLibGetDevices: Cannot determine the path to %s\n", pszDevName));
- }
- CloseHandle(hDev);
- }
- else
- AssertMsgFailed(("Unexpected failure to open %s. LastError=%Rwa\n", pszDevName, GetLastError()));
- }
-
- if (!cCaptured)
- {
- /* Only return the host devices */
- *ppDevices = pHostDevices;
- *pcDevices = cHostDevices;
- Log(("usbLibGetDevices: returns %d host devices - no captured devices after all\n", cHostDevices));
- return VINF_SUCCESS;
- }
-
- *pcDevices = cHostDevices;
-
- Log(("usbLibGetDevices: returns %d devices (%d captured)\n", *pcDevices, cCaptured));
- usbLibLogHostDevices(pHostDevices);
-
- *ppDevices = pHostDevices;
- return VINF_SUCCESS;
-}
-
-
-/**
- * Check for USB device arrivals or removals
- *
- * @returns boolean
- */
-USBLIB_DECL(bool) USBLibHasPendingDeviceChanges(void)
-{
- USBSUP_USB_CHANGE out;
- DWORD cbReturned;
-
- if (g_hUSBMonitor == INVALID_HANDLE_VALUE)
- return false;
- cbReturned = 0;
- if ( DeviceIoControl(g_hUSBMonitor, SUPUSBFLT_IOCTL_USB_CHANGE, NULL, 0, &out, sizeof(out), &cbReturned, NULL)
- && out.cUSBStateChange != g_cUSBStateChange)
- {
- g_cUSBStateChange = out.cUSBStateChange;
- Log(("usbLibHasPendingDeviceChanges: Detected USB state change!!\n"));
- return true;
- }
- return false;
-}
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/cmn/Makefile.kup b/src/VBox/HostDrivers/VBoxUSB/win/cmn/Makefile.kup
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/cmn/Makefile.kup
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp b/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp
new file mode 100644
index 000000000..9f78b2c89
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp
@@ -0,0 +1,212 @@
+/* $Id: VBoxDrvTool.cpp 37490 2011-06-16 10:58:27Z vboxsync $ */
+/** @file
+ * Windows Driver R0 Tooling.
+ */
+
+/*
+ * 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.
+ */
+
+#include "VBoxDrvTool.h"
+
+#include <iprt/assert.h>
+
+#define VBOXDRVTOOL_MEMTAG 'TDBV'
+
+static PVOID vboxDrvToolMemAlloc(SIZE_T cbBytes)
+{
+ PVOID pvMem = ExAllocatePoolWithTag(NonPagedPool, cbBytes, VBOXDRVTOOL_MEMTAG);
+ Assert(pvMem);
+ return pvMem;
+}
+
+static PVOID vboxDrvToolMemAllocZ(SIZE_T cbBytes)
+{
+ PVOID pvMem = vboxDrvToolMemAlloc(cbBytes);
+ if (pvMem)
+ {
+ RtlZeroMemory(pvMem, cbBytes);
+ }
+ return pvMem;
+}
+
+static VOID vboxDrvToolMemFree(PVOID pvMem)
+{
+ ExFreePoolWithTag(pvMem, VBOXDRVTOOL_MEMTAG);
+}
+
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegOpenKeyU(OUT PHANDLE phKey, IN PUNICODE_STRING pName, IN ACCESS_MASK fAccess)
+{
+ OBJECT_ATTRIBUTES ObjAttr;
+
+ InitializeObjectAttributes(&ObjAttr, pName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
+
+ return ZwOpenKey(phKey, fAccess, &ObjAttr);
+}
+
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess)
+{
+ UNICODE_STRING RtlStr;
+ RtlInitUnicodeString(&RtlStr, pName);
+
+ return VBoxDrvToolRegOpenKeyU(phKey, &RtlStr, fAccess);
+}
+
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegCloseKey(IN HANDLE hKey)
+{
+ return ZwClose(hKey);
+}
+
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PULONG pDword)
+{
+ struct
+ {
+ KEY_VALUE_PARTIAL_INFORMATION Info;
+ UCHAR Buf[32]; /* should be enough */
+ } Buf;
+ ULONG cbBuf;
+ UNICODE_STRING RtlStr;
+ RtlInitUnicodeString(&RtlStr, pName);
+ NTSTATUS Status = ZwQueryValueKey(hKey,
+ &RtlStr,
+ KeyValuePartialInformation,
+ &Buf.Info,
+ sizeof(Buf),
+ &cbBuf);
+ if (Status == STATUS_SUCCESS)
+ {
+ if (Buf.Info.Type == REG_DWORD)
+ {
+ Assert(Buf.Info.DataLength == 4);
+ *pDword = *((PULONG)Buf.Info.Data);
+ return STATUS_SUCCESS;
+ }
+ }
+
+ return STATUS_INVALID_PARAMETER;
+}
+
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT ULONG val)
+{
+ UNICODE_STRING RtlStr;
+ RtlInitUnicodeString(&RtlStr, pName);
+ return ZwSetValueKey(hKey, &RtlStr,
+ NULL, /* IN ULONG TitleIndex OPTIONAL, reserved */
+ REG_DWORD,
+ &val,
+ sizeof(val));
+}
+
+static NTSTATUS vboxDrvToolIoCompletionSetEvent(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN PVOID pvContext)
+{
+ PKEVENT pEvent = (PKEVENT)pvContext;
+ KeSetEvent(pEvent, 0, FALSE);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostAsync(PDEVICE_OBJECT pDevObj, PIRP pIrp, PKEVENT pEvent)
+{
+ IoSetCompletionRoutine(pIrp, vboxDrvToolIoCompletionSetEvent, pEvent, TRUE, TRUE, TRUE);
+ return IoCallDriver(pDevObj, pIrp);
+}
+
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostSync(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+{
+ KEVENT Event;
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ NTSTATUS Status = VBoxDrvToolIoPostAsync(pDevObj, pIrp, &Event);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Status = pIrp->IoStatus.Status;
+ }
+ return Status;
+}
+
+/* !!!NOTE: the caller MUST be the IRP owner!!! *
+ * !! one can not post threaded IRPs this way!! */
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostSyncWithTimeout(PDEVICE_OBJECT pDevObj, PIRP pIrp, ULONG dwTimeoutMs)
+{
+ KEVENT Event;
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ NTSTATUS Status = VBoxDrvToolIoPostAsync(pDevObj, pIrp, &Event);
+ if (Status == STATUS_PENDING)
+ {
+ LARGE_INTEGER Interval;
+ PLARGE_INTEGER pInterval = NULL;
+ if (dwTimeoutMs != RT_INDEFINITE_WAIT)
+ {
+ Interval.QuadPart = -(int64_t) dwTimeoutMs /* ms */ * 10000;
+ pInterval = &Interval;
+ }
+
+ Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, pInterval);
+ if (Status == STATUS_TIMEOUT)
+ {
+#ifdef DEBUG_misha
+ /* debugging only */
+ AssertFailed();
+#endif
+ if (!IoCancelIrp(pIrp))
+ {
+ /* this may happen, but this is something the caller with timeout is not expecting */
+ AssertFailed();
+ }
+
+ /* wait for the IRP to complete */
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ }
+ else
+ {
+ Assert(Status == STATUS_SUCCESS);
+ }
+
+ /* by this time the IRP is completed */
+ Status = pIrp->IoStatus.Status;
+ }
+ return Status;
+}
+
+VBOXDRVTOOL_DECL(VOID) VBoxDrvToolRefWaitEqual(PVBOXDRVTOOL_REF pRef, uint32_t u32Val)
+{
+ LARGE_INTEGER Interval;
+ Interval.QuadPart = -(int64_t) 2 /* ms */ * 10000;
+ uint32_t cRefs;
+
+ while ((cRefs = ASMAtomicReadU32(&pRef->cRefs)) != u32Val)
+ {
+ Assert(cRefs >= u32Val);
+ Assert(cRefs < UINT32_MAX/2);
+
+ KeDelayExecutionThread(KernelMode, FALSE, &Interval);
+ }
+}
+
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolStrCopy(PUNICODE_STRING pDst, CONST PUNICODE_STRING pSrc)
+{
+ USHORT cbLength = pSrc->Length + sizeof (pDst->Buffer[0]);
+ pDst->Buffer = (PWCHAR)vboxDrvToolMemAlloc(cbLength);
+ Assert(pDst->Buffer);
+ if (pDst->Buffer)
+ {
+ RtlMoveMemory(pDst->Buffer, pSrc->Buffer, pSrc->Length);
+ pDst->Buffer[pSrc->Length / sizeof (pDst->Buffer[0])] = L'\0';
+ pDst->Length = pSrc->Length;
+ pDst->MaximumLength = cbLength;
+ return STATUS_SUCCESS;
+ }
+ return STATUS_NO_MEMORY;
+}
+
+VBOXDRVTOOL_DECL(VOID) VBoxDrvToolStrFree(PUNICODE_STRING pStr)
+{
+ vboxDrvToolMemFree(pStr->Buffer);
+}
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.h b/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.h
new file mode 100644
index 000000000..1579fdfe8
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.h
@@ -0,0 +1,118 @@
+/* $Id: VBoxDrvTool.h 37047 2011-05-12 10:29:26Z vboxsync $ */
+/** @file
+ * Windows Driver R0 Tooling.
+ */
+
+/*
+ * 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 ___VBoxDrvTool_win_h___
+#define ___VBoxDrvTool_win_h___
+#include <VBox/cdefs.h>
+#include <iprt/stdint.h>
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+
+RT_C_DECLS_BEGIN
+#if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
+# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
+# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
+# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap
+# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
+# pragma warning(disable : 4163)
+#endif
+#if (_MSC_VER >= 1600) && !defined(VBOX_WITH_PATCHED_DDK)
+# define _interlockedbittestandset _interlockedbittestandset_StillStupidDdkVsCompilerCrap
+# define _interlockedbittestandreset _interlockedbittestandreset_StillStupidDdkVsCompilerCrap
+# define _interlockedbittestandset64 _interlockedbittestandset64_StillStupidDdkVsCompilerCrap
+# define _interlockedbittestandreset64 _interlockedbittestandreset64_StillStupidDdkVsCompilerCrap
+# pragma warning(disable : 4163)
+#endif
+
+#include <wdm.h>
+
+#if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
+# pragma warning(default : 4163)
+# undef _InterlockedExchange
+# undef _InterlockedExchangeAdd
+# undef _InterlockedCompareExchange
+# undef _InterlockedAddLargeStatistic
+#endif
+#if (_MSC_VER >= 1600) && !defined(VBOX_WITH_PATCHED_DDK)
+# pragma warning(default : 4163)
+# undef _interlockedbittestandset
+# undef _interlockedbittestandreset
+# undef _interlockedbittestandset64
+# undef _interlockedbittestandreset64
+#endif
+
+
+#if 0
+/* enable this in case we include this in a dll*/
+# ifdef IN_VBOXDRVTOOL
+# define VBOXDRVTOOL_DECL(a_Type) DECLEXPORT(a_Type)
+# else
+# define VBOXDRVTOOL_DECL(a_Type) DECLIMPORT(a_Type)
+# endif
+#else
+/*enable this in case we include this in a static lib*/
+# define VBOXDRVTOOL_DECL(a_Type) a_Type VBOXCALL
+#endif
+
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegOpenKeyU(OUT PHANDLE phKey, IN PUNICODE_STRING pName, IN ACCESS_MASK fAccess);
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess);
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegCloseKey(IN HANDLE hKey);
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PULONG pDword);
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT ULONG val);
+
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostAsync(PDEVICE_OBJECT pDevObj, PIRP pIrp, PKEVENT pEvent);
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostSync(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostSyncWithTimeout(PDEVICE_OBJECT pDevObj, PIRP pIrp, ULONG dwTimeoutMs);
+DECLINLINE(NTSTATUS) VBoxDrvToolIoComplete(PIRP pIrp, NTSTATUS Status, ULONG ulInfo)
+{
+ pIrp->IoStatus.Status = Status;
+ pIrp->IoStatus.Information = ulInfo;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ return Status;
+}
+
+typedef struct VBOXDRVTOOL_REF
+{
+ volatile uint32_t cRefs;
+} VBOXDRVTOOL_REF, *PVBOXDRVTOOL_REF;
+
+DECLINLINE(void) VBoxDrvToolRefInit(PVBOXDRVTOOL_REF pRef)
+{
+ pRef->cRefs = 1;
+}
+
+DECLINLINE(uint32_t) VBoxDrvToolRefRetain(PVBOXDRVTOOL_REF pRef)
+{
+ Assert(pRef->cRefs);
+ Assert(pRef->cRefs < UINT32_MAX / 2);
+ return ASMAtomicIncU32(&pRef->cRefs);
+}
+
+DECLINLINE(uint32_t) VBoxDrvToolRefRelease(PVBOXDRVTOOL_REF pRef)
+{
+ uint32_t cRefs = ASMAtomicDecU32(&pRef->cRefs);
+ Assert(cRefs < UINT32_MAX/2);
+ return cRefs;
+}
+
+VBOXDRVTOOL_DECL(VOID) VBoxDrvToolRefWaitEqual(PVBOXDRVTOOL_REF pRef, uint32_t u32Val);
+
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolStrCopy(PUNICODE_STRING pDst, CONST PUNICODE_STRING pSrc);
+VBOXDRVTOOL_DECL(VOID) VBoxDrvToolStrFree(PUNICODE_STRING pStr);
+
+RT_C_DECLS_END
+
+#endif /* #ifndef ___VBoxDrvTool_win_h___ */
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbIdc.h b/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbIdc.h
new file mode 100644
index 000000000..38c25bd35
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbIdc.h
@@ -0,0 +1,72 @@
+/* $Id: VBoxUsbIdc.h 36968 2011-05-05 08:55:16Z vboxsync $ */
+/** @file
+ * Windows USB Proxy - Monitor Driver communication interface.
+ */
+
+/*
+ * 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 ___VBoxUsbIdc_h___
+#define ___VBoxUsbIdc_h___
+
+#define VBOXUSBIDC_VERSION_MAJOR 1
+#define VBOXUSBIDC_VERSION_MINOR 0
+
+#define VBOXUSBIDC_INTERNAL_IOCTL_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x618, METHOD_NEITHER, FILE_WRITE_ACCESS)
+#define VBOXUSBIDC_INTERNAL_IOCTL_PROXY_STARTUP CTL_CODE(FILE_DEVICE_UNKNOWN, 0x619, METHOD_NEITHER, FILE_WRITE_ACCESS)
+#define VBOXUSBIDC_INTERNAL_IOCTL_PROXY_TEARDOWN CTL_CODE(FILE_DEVICE_UNKNOWN, 0x61A, METHOD_NEITHER, FILE_WRITE_ACCESS)
+#define VBOXUSBIDC_INTERNAL_IOCTL_PROXY_STATE_CHANGE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x61B, METHOD_NEITHER, FILE_WRITE_ACCESS)
+
+typedef struct
+{
+ uint32_t u32Major;
+ uint32_t u32Minor;
+} VBOXUSBIDC_VERSION, *PVBOXUSBIDC_VERSION;
+
+typedef void *HVBOXUSBIDCDEV;
+
+/* the initial device state is USBDEVICESTATE_HELD_BY_PROXY */
+typedef struct VBOXUSBIDC_PROXY_STARTUP
+{
+ union
+ {
+ /* in: device PDO */
+ PDEVICE_OBJECT pPDO;
+ /* out: device handle to be used for subsequent USBSUP_PROXY_XXX calls */
+ HVBOXUSBIDCDEV hDev;
+ } u;
+} VBOXUSBIDC_PROXY_STARTUP, *PVBOXUSBIDC_PROXY_STARTUP;
+
+typedef struct VBOXUSBIDC_PROXY_TEARDOWN
+{
+ HVBOXUSBIDCDEV hDev;
+} VBOXUSBIDC_PROXY_TEARDOWN, *PVBOXUSBIDC_PROXY_TEARDOWN;
+
+typedef enum
+{
+ VBOXUSBIDC_PROXY_STATE_UNKNOWN = 0,
+ VBOXUSBIDC_PROXY_STATE_IDLE,
+ VBOXUSBIDC_PROXY_STATE_INITIAL = VBOXUSBIDC_PROXY_STATE_IDLE,
+ VBOXUSBIDC_PROXY_STATE_USED_BY_GUEST
+} VBOXUSBIDC_PROXY_STATE;
+
+typedef struct VBOXUSBIDC_PROXY_STATE_CHANGE
+{
+ HVBOXUSBIDCDEV hDev;
+ VBOXUSBIDC_PROXY_STATE enmState;
+} VBOXUSBIDC_PROXY_STATE_CHANGE, *PVBOXUSBIDC_PROXY_STATE_CHANGE;
+
+NTSTATUS VBoxUsbIdcInit();
+VOID VBoxUsbIdcTerm();
+NTSTATUS VBoxUsbIdcProxyStarted(PDEVICE_OBJECT pPDO, HVBOXUSBIDCDEV *phDev);
+NTSTATUS VBoxUsbIdcProxyStopped(HVBOXUSBIDCDEV hDev);
+
+#endif /* #ifndef ___VBoxUsbIdc_h___ */
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.cpp b/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.cpp
new file mode 100644
index 000000000..812ce0a7a
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.cpp
@@ -0,0 +1,406 @@
+/* $Id: VBoxUsbTool.cpp 37065 2011-05-13 10:58:58Z vboxsync $ */
+/** @file
+ * Windows USB R0 Tooling.
+ */
+
+/*
+ * 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.
+ */
+#define INITGUID
+#include "VBoxUsbTool.h"
+#include <usbbusif.h>
+
+#include <iprt/assert.h>
+#include <VBox/log.h>
+
+#define VBOXUSBTOOL_MEMTAG 'TUBV'
+
+static PVOID vboxUsbToolMemAlloc(SIZE_T cbBytes)
+{
+ PVOID pvMem = ExAllocatePoolWithTag(NonPagedPool, cbBytes, VBOXUSBTOOL_MEMTAG);
+ Assert(pvMem);
+ return pvMem;
+}
+
+static PVOID vboxUsbToolMemAllocZ(SIZE_T cbBytes)
+{
+ PVOID pvMem = vboxUsbToolMemAlloc(cbBytes);
+ if (pvMem)
+ {
+ RtlZeroMemory(pvMem, cbBytes);
+ }
+ return pvMem;
+}
+
+static VOID vboxUsbToolMemFree(PVOID pvMem)
+{
+ ExFreePoolWithTag(pvMem, VBOXUSBTOOL_MEMTAG);
+}
+
+VBOXUSBTOOL_DECL(PURB) VBoxUsbToolUrbAlloc(USHORT u16Function, USHORT cbSize)
+{
+ PURB pUrb = (PURB)vboxUsbToolMemAlloc(cbSize);
+ Assert(pUrb);
+ if (!pUrb)
+ return NULL;
+
+ pUrb->UrbHeader.Length = cbSize;
+ pUrb->UrbHeader.Function = u16Function;
+ return pUrb;
+}
+
+VBOXUSBTOOL_DECL(PURB) VBoxUsbToolUrbAllocZ(USHORT u16Function, USHORT cbSize)
+{
+ PURB pUrb = (PURB)vboxUsbToolMemAllocZ(cbSize);
+ Assert(pUrb);
+ if (!pUrb)
+ return NULL;
+
+ pUrb->UrbHeader.Length = cbSize;
+ pUrb->UrbHeader.Function = u16Function;
+ return pUrb;
+}
+
+VBOXUSBTOOL_DECL(PURB) VBoxUsbToolUrbReinit(PURB pUrb, USHORT cbSize, USHORT u16Function)
+{
+ Assert(pUrb->UrbHeader.Length == cbSize);
+ if (pUrb->UrbHeader.Length < cbSize)
+ return NULL;
+ pUrb->UrbHeader.Length = cbSize;
+ pUrb->UrbHeader.Function = u16Function;
+ return pUrb;
+}
+
+VBOXUSBTOOL_DECL(VOID) VBoxUsbToolUrbFree(PURB pUrb)
+{
+ vboxUsbToolMemFree(pUrb);
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolUrbPost(PDEVICE_OBJECT pDevObj, PURB pUrb, ULONG dwTimeoutMs)
+{
+ if (dwTimeoutMs == RT_INDEFINITE_WAIT)
+ return VBoxUsbToolIoInternalCtlSendSync(pDevObj, IOCTL_INTERNAL_USB_SUBMIT_URB, pUrb, NULL);
+ return VBoxUsbToolIoInternalCtlSendSyncWithTimeout(pDevObj, IOCTL_INTERNAL_USB_SUBMIT_URB, pUrb, NULL, dwTimeoutMs);
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetDescriptor(PDEVICE_OBJECT pDevObj, void *pvBuffer, int cbBuffer, int Type, int iIndex, int LangId, ULONG dwTimeoutMs)
+{
+ NTSTATUS Status;
+ USHORT cbUrb = sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST);
+ PURB pUrb = VBoxUsbToolUrbAllocZ(URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE, cbUrb);
+ Assert(pUrb);
+ if(!pUrb)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ PUSB_COMMON_DESCRIPTOR pCmn = (PUSB_COMMON_DESCRIPTOR)pvBuffer;
+ pCmn->bLength = cbBuffer;
+ pCmn->bDescriptorType = Type;
+
+ pUrb->UrbHeader.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE;
+ pUrb->UrbHeader.Length = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
+ pUrb->UrbControlDescriptorRequest.TransferBufferLength = cbBuffer;
+ pUrb->UrbControlDescriptorRequest.TransferBuffer = pvBuffer;
+ pUrb->UrbControlDescriptorRequest.Index = (UCHAR)iIndex;
+ pUrb->UrbControlDescriptorRequest.DescriptorType = (UCHAR)Type;
+ pUrb->UrbControlDescriptorRequest.LanguageId = (USHORT)LangId;
+
+ Status = VBoxUsbToolUrbPost(pDevObj, pUrb, dwTimeoutMs);
+#ifdef DEBUG_misha
+ Assert(Status == STATUS_SUCCESS);
+#endif
+
+ VBoxUsbToolUrbFree(pUrb);
+
+ return Status;
+}
+
+VBOXUSBTOOL_DECL(VOID) VBoxUsbToolStringDescriptorToUnicodeString(PUSB_STRING_DESCRIPTOR pDr, PUNICODE_STRING pUnicode)
+{
+ /* for some reason the string dr sometimes contains a non-null terminated string
+ * although we zeroed up the complete descriptor buffer
+ * this is why RtlInitUnicodeString won't work
+ * we need to init the scting length based on dr length */
+ pUnicode->Buffer = pDr->bString;
+ pUnicode->Length = pUnicode->MaximumLength = pDr->bLength - RT_OFFSETOF(USB_STRING_DESCRIPTOR, bString);
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetStringDescriptorA(PDEVICE_OBJECT pDevObj, char *pResult, ULONG cbResult, int iIndex, int LangId, ULONG dwTimeoutMs)
+{
+ char aBuf[MAXIMUM_USB_STRING_LENGTH];
+ AssertCompile(sizeof (aBuf) <= UINT8_MAX);
+ UCHAR cbBuf = (UCHAR)sizeof (aBuf);
+ PUSB_STRING_DESCRIPTOR pDr = (PUSB_STRING_DESCRIPTOR)&aBuf;
+
+ Assert(pResult);
+ *pResult = 0;
+
+ memset(pDr, 0, cbBuf);
+ pDr->bLength = cbBuf;
+ pDr->bDescriptorType = USB_STRING_DESCRIPTOR_TYPE;
+
+ NTSTATUS Status = VBoxUsbToolGetDescriptor(pDevObj, pDr, cbBuf, USB_STRING_DESCRIPTOR_TYPE, iIndex, LangId, dwTimeoutMs);
+ if (NT_SUCCESS(Status))
+ {
+ if (pDr->bLength >= sizeof (USB_STRING_DESCRIPTOR))
+ {
+ UNICODE_STRING Unicode;
+ ANSI_STRING Ansi;
+ /* for some reason the string dr sometimes contains a non-null terminated string
+ * although we zeroed up the complete descriptor buffer
+ * this is why RtlInitUnicodeString won't work*/
+ VBoxUsbToolStringDescriptorToUnicodeString(pDr, &Unicode);
+ Ansi.Buffer = pResult;
+ Ansi.Length = 0;
+ Ansi.MaximumLength = (USHORT)cbResult - 1;
+ memset(pResult, 0, cbResult);
+ Status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
+ Assert(Status == STATUS_SUCCESS);
+ if (NT_SUCCESS(Status))
+ {
+ /* just to make sure the string is null-terminated */
+ Assert(pResult[cbResult-1] == 0);
+ Status = STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }
+ return Status;
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetLangID(PDEVICE_OBJECT pDevObj, int *pLangId, ULONG dwTimeoutMs)
+{
+ char aBuf[MAXIMUM_USB_STRING_LENGTH];
+ AssertCompile(sizeof (aBuf) <= UINT8_MAX);
+ UCHAR cbBuf = (UCHAR)sizeof (aBuf);
+ PUSB_STRING_DESCRIPTOR pDr = (PUSB_STRING_DESCRIPTOR)&aBuf;
+
+ Assert(pLangId);
+ *pLangId = 0;
+
+ memset(pDr, 0, cbBuf);
+ pDr->bLength = cbBuf;
+ pDr->bDescriptorType = USB_STRING_DESCRIPTOR_TYPE;
+
+ NTSTATUS Status = VBoxUsbToolGetDescriptor(pDevObj, pDr, cbBuf, USB_STRING_DESCRIPTOR_TYPE, 0, 0, dwTimeoutMs);
+ if (NT_SUCCESS(Status))
+ {
+ /* Just grab the first lang ID if available. In 99% cases, it will be US English (0x0409).*/
+ if (pDr->bLength >= sizeof (USB_STRING_DESCRIPTOR))
+ {
+ AssertCompile(sizeof (pDr->bString[0]) == sizeof (uint16_t));
+ *pLangId = pDr->bString[0];
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }
+ return Status;
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetDeviceSpeed(PDEVICE_OBJECT pDevObj, BOOLEAN *pbIsHigh)
+{
+ Assert(pbIsHigh);
+ *pbIsHigh = FALSE;
+
+ PIRP pIrp = IoAllocateIrp(pDevObj->StackSize, FALSE);
+ Assert(pIrp);
+ if (!pIrp)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ USB_BUS_INTERFACE_USBDI_V1 BusIf;
+ PIO_STACK_LOCATION pSl = IoGetNextIrpStackLocation(pIrp);
+ pSl->MajorFunction = IRP_MJ_PNP;
+ pSl->MinorFunction = IRP_MN_QUERY_INTERFACE;
+ pSl->Parameters.QueryInterface.InterfaceType = &USB_BUS_INTERFACE_USBDI_GUID;
+ pSl->Parameters.QueryInterface.Size = sizeof (BusIf);
+ pSl->Parameters.QueryInterface.Version = USB_BUSIF_USBDI_VERSION_1;
+ pSl->Parameters.QueryInterface.Interface = (PINTERFACE)&BusIf;
+ pSl->Parameters.QueryInterface.InterfaceSpecificData = NULL;
+
+ pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+ NTSTATUS Status = VBoxDrvToolIoPostSync(pDevObj, pIrp);
+ Assert(NT_SUCCESS(Status) || Status == STATUS_NOT_SUPPORTED);
+ if (NT_SUCCESS(Status))
+ {
+ *pbIsHigh = BusIf.IsDeviceHighSpeed(BusIf.BusContext);
+ BusIf.InterfaceDereference(BusIf.BusContext);
+ }
+ IoFreeIrp(pIrp);
+
+ return Status;
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolPipeClear(PDEVICE_OBJECT pDevObj, HANDLE hPipe, bool fReset)
+{
+ if (!hPipe)
+ {
+ Log(("Resetting the control pipe??\n"));
+ return STATUS_SUCCESS;
+ }
+ USHORT u16Function = fReset ? URB_FUNCTION_RESET_PIPE : URB_FUNCTION_ABORT_PIPE;
+ PURB pUrb = VBoxUsbToolUrbAlloc(u16Function, sizeof (struct _URB_PIPE_REQUEST));
+ if (!pUrb)
+ {
+ AssertMsgFailed((__FUNCTION__": VBoxUsbToolUrbAlloc failed!\n"));
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ pUrb->UrbPipeRequest.PipeHandle = hPipe;
+ pUrb->UrbPipeRequest.Reserved = 0;
+
+ NTSTATUS Status = VBoxUsbToolUrbPost(pDevObj, pUrb, RT_INDEFINITE_WAIT);
+ if (!NT_SUCCESS(Status) || !USBD_SUCCESS(pUrb->UrbHeader.Status))
+ {
+ AssertMsgFailed((__FUNCTION__": vboxUsbToolRequest failed with %x (%x)\n", Status, pUrb->UrbHeader.Status));
+ }
+
+ VBoxUsbToolUrbFree(pUrb);
+
+ return Status;
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolCurrentFrame(PDEVICE_OBJECT pDevObj, PIRP pIrp, PULONG piFrame)
+{
+ struct _URB_GET_CURRENT_FRAME_NUMBER Urb;
+ Urb.Hdr.Function = URB_FUNCTION_GET_CURRENT_FRAME_NUMBER;
+ Urb.Hdr.Length = sizeof(Urb);
+ Urb.FrameNumber = (ULONG)-1;
+
+ Assert(piFrame);
+ *piFrame = (ULONG)-1;
+
+ PIO_STACK_LOCATION pSl = IoGetNextIrpStackLocation(pIrp);
+ pSl->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
+ pSl->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
+ pSl->Parameters.Others.Argument1 = (PVOID)&Urb;
+ pSl->Parameters.Others.Argument2 = NULL;
+
+ NTSTATUS Status = VBoxUsbToolUrbPost(pDevObj, (PURB)&Urb, RT_INDEFINITE_WAIT);
+ Assert(NT_SUCCESS(Status));
+ if (NT_SUCCESS(Status))
+ {
+ *piFrame = Urb.FrameNumber;
+ }
+
+ return Status;
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolDevUnconfigure(PDEVICE_OBJECT pDevObj)
+{
+ USHORT cbUrb = sizeof (struct _URB_SELECT_CONFIGURATION);
+ PURB pUrb = VBoxUsbToolUrbAlloc(URB_FUNCTION_SELECT_CONFIGURATION, cbUrb);
+ Assert(pUrb);
+ if (!pUrb)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ UsbBuildSelectConfigurationRequest(pUrb, (USHORT)cbUrb, NULL);
+
+ NTSTATUS Status = VBoxUsbToolUrbPost(pDevObj, pUrb, RT_INDEFINITE_WAIT);
+ Assert(NT_SUCCESS(Status));
+
+ VBoxUsbToolUrbFree(pUrb);
+
+ return Status;
+}
+
+VBOXUSBTOOL_DECL(PIRP) VBoxUsbToolIoBuildAsyncInternalCtl(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2)
+{
+ PIRP pIrp = IoAllocateIrp(pDevObj->StackSize, FALSE);
+ Assert(pIrp);
+ if (!pIrp)
+ {
+ return NULL;
+ }
+
+ pIrp->IoStatus.Status = STATUS_SUCCESS;
+ pIrp->IoStatus.Information = NULL;
+
+ PIO_STACK_LOCATION pSl = IoGetNextIrpStackLocation(pIrp);
+ pSl->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
+ pSl->MinorFunction = 0;
+ pSl->Parameters.DeviceIoControl.IoControlCode = uCtl;
+ pSl->Parameters.Others.Argument1 = pvArg1;
+ pSl->Parameters.Others.Argument2 = pvArg2;
+ return pIrp;
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolIoInternalCtlSendSyncWithTimeout(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2, ULONG dwTimeoutMs)
+{
+ /* since we're going to cancel the irp on timeout, we should allocate our own IRP rather than using the threaded one
+ * */
+ PIRP pIrp = VBoxUsbToolIoBuildAsyncInternalCtl(pDevObj, uCtl, pvArg1, pvArg2);
+ if (!pIrp)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ NTSTATUS Status = VBoxDrvToolIoPostSyncWithTimeout(pDevObj, pIrp, dwTimeoutMs);
+
+ IoFreeIrp(pIrp);
+
+ return Status;
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolIoInternalCtlSendAsync(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2,
+ PKEVENT pEvent, PIO_STATUS_BLOCK pIoStatus)
+{
+ NTSTATUS Status;
+ PIRP pIrp;
+ PIO_STACK_LOCATION pSl;
+ KIRQL Irql = KeGetCurrentIrql();
+ Assert(Irql == PASSIVE_LEVEL);
+
+ pIrp = IoBuildDeviceIoControlRequest(uCtl, pDevObj, NULL, 0, NULL, 0, TRUE, pEvent, pIoStatus);
+ if (!pIrp)
+ {
+ AssertMsgFailed(("IoBuildDeviceIoControlRequest failed!!\n"));
+ pIoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
+ pIoStatus->Information = 0;
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Get the next stack location as that is used for the new irp */
+ pSl = IoGetNextIrpStackLocation(pIrp);
+ pSl->Parameters.Others.Argument1 = pvArg1;
+ pSl->Parameters.Others.Argument2 = pvArg2;
+
+ Status = IoCallDriver(pDevObj, pIrp);
+
+ return Status;
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolIoInternalCtlSendSync(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2)
+{
+ IO_STATUS_BLOCK IoStatus = {0};
+ KEVENT Event;
+ NTSTATUS Status;
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ Status = VBoxUsbToolIoInternalCtlSendAsync(pDevObj, uCtl, pvArg1, pvArg2, &Event, &IoStatus);
+
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Status = IoStatus.Status;
+ }
+
+ return Status;
+}
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.h b/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.h
new file mode 100644
index 000000000..324104d0c
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.h
@@ -0,0 +1,66 @@
+/* $Id: VBoxUsbTool.h 37047 2011-05-12 10:29:26Z vboxsync $ */
+/** @file
+ * Windows USB R0 Tooling.
+ */
+
+/*
+ * 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 ___VBoxUsbTool_h___
+#define ___VBoxUsbTool_h___
+
+#include "VBoxDrvTool.h"
+
+RT_C_DECLS_BEGIN
+#pragma warning( disable : 4200 )
+#include <usbdi.h>
+#pragma warning( default : 4200 )
+#include <usbdlib.h>
+
+RT_C_DECLS_END
+
+#if 0
+/* enable this in case we include this in a dll*/
+# ifdef IN_VBOXUSBTOOL
+# define VBOXUSBTOOL_DECL(a_Type) DECLEXPORT(a_Type)
+# else
+# define VBOXUSBTOOL_DECL(a_Type) DECLIMPORT(a_Type)
+# endif
+#else
+/*enable this in case we include this in a static lib*/
+# define VBOXUSBTOOL_DECL(a_Type) a_Type VBOXCALL
+#endif
+
+
+RT_C_DECLS_BEGIN
+
+VBOXUSBTOOL_DECL(PURB) VBoxUsbToolUrbAlloc(USHORT u16Function, USHORT cbSize);
+VBOXUSBTOOL_DECL(PURB) VBoxUsbToolUrbAllocZ(USHORT u16Function, USHORT cbSize);
+VBOXUSBTOOL_DECL(PURB) VBoxUsbToolUrbReinit(PURB pUrb, USHORT cbSize, USHORT u16Function);
+VBOXUSBTOOL_DECL(VOID) VBoxUsbToolUrbFree(PURB pUrb);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolUrbPost(PDEVICE_OBJECT pDevObj, PURB pUrb, ULONG dwTimeoutMs);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetDescriptor(PDEVICE_OBJECT pDevObj, void *pvBuffer, int cbBuffer, int Type, int iIndex, int LangId, ULONG dwTimeoutMs);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetStringDescriptorA(PDEVICE_OBJECT pDevObj, char *pResult, ULONG cbResult, int iIndex, int LangId, ULONG dwTimeoutMs);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetLangID(PDEVICE_OBJECT pDevObj, int *pLangId, ULONG dwTimeoutMs);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetDeviceSpeed(PDEVICE_OBJECT pDevObj, BOOLEAN *pbIsHigh);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolPipeClear(PDEVICE_OBJECT pDevObj, HANDLE hPipe, bool fReset);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolCurrentFrame(PDEVICE_OBJECT pDevObj, PIRP pIrp, PULONG piFrame);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolDevUnconfigure(PDEVICE_OBJECT pDevObj);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolIoInternalCtlSendAsync(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2, PKEVENT pEvent, PIO_STATUS_BLOCK pIoStatus);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolIoInternalCtlSendSync(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2);
+VBOXUSBTOOL_DECL(PIRP) VBoxUsbToolIoBuildAsyncInternalCtl(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolIoInternalCtlSendSyncWithTimeout(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2, ULONG dwTimeoutMs);
+VBOXUSBTOOL_DECL(VOID) VBoxUsbToolStringDescriptorToUnicodeString(PUSB_STRING_DESCRIPTOR pDr, PUNICODE_STRING pUnicode);
+
+
+RT_C_DECLS_END
+
+#endif /* #ifndef ___VBoxUsbTool_h___ */
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/Makefile.kup b/src/VBox/HostDrivers/VBoxUSB/win/dev/Makefile.kup
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/Makefile.kup
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/VBoxUSB.inf b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUSB.inf
index 1b121ea54..d02950ed4 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/VBoxUSB.inf
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUSB.inf
@@ -1,7 +1,7 @@
;
; VBox host drivers - USB drivers - Win32 USB device
;
-; Copyright (C) 2006-2007 Oracle Corporation
+; 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;
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbCmn.h b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbCmn.h
new file mode 100644
index 000000000..fc9bfcee7
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbCmn.h
@@ -0,0 +1,80 @@
+/* $Id: VBoxUsbCmn.h 36968 2011-05-05 08:55:16Z vboxsync $ */
+/** @file
+ * VBoxUsmCmn.h - USB device. Common defs
+ */
+/*
+ * 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 ___VBoxUsbCmn_h___
+#define ___VBoxUsbCmn_h___
+
+#include "../cmn/VBoxDrvTool.h"
+#include "../cmn/VBoxUsbTool.h"
+
+#include <iprt/cdefs.h>
+#include <iprt/asm.h>
+
+#include <VBox/usblib-win.h>
+
+#define VBOXUSB_CFG_IDLE_TIME_MS 5000
+
+typedef struct VBOXUSBDEV_EXT *PVBOXUSBDEV_EXT;
+
+RT_C_DECLS_BEGIN
+
+#ifdef _WIN64
+#define DECLSPEC_USBIMPORT DECLSPEC_IMPORT
+#else
+#define DECLSPEC_USBIMPORT
+
+#define USBD_ParseDescriptors _USBD_ParseDescriptors
+#define USBD_ParseConfigurationDescriptorEx _USBD_ParseConfigurationDescriptorEx
+#define USBD_CreateConfigurationRequestEx _USBD_CreateConfigurationRequestEx
+#endif
+
+DECLSPEC_USBIMPORT PUSB_COMMON_DESCRIPTOR
+USBD_ParseDescriptors(
+ IN PVOID DescriptorBuffer,
+ IN ULONG TotalLength,
+ IN PVOID StartPosition,
+ IN LONG DescriptorType
+ );
+
+DECLSPEC_USBIMPORT PUSB_INTERFACE_DESCRIPTOR
+USBD_ParseConfigurationDescriptorEx(
+ IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+ IN PVOID StartPosition,
+ IN LONG InterfaceNumber,
+ IN LONG AlternateSetting,
+ IN LONG InterfaceClass,
+ IN LONG InterfaceSubClass,
+ IN LONG InterfaceProtocol
+ );
+
+DECLSPEC_USBIMPORT PURB
+USBD_CreateConfigurationRequestEx(
+ IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+ IN PUSBD_INTERFACE_LIST_ENTRY InterfaceList
+ );
+
+RT_C_DECLS_END
+
+DECLHIDDEN(PVOID) vboxUsbMemAlloc(SIZE_T cbBytes);
+DECLHIDDEN(PVOID) vboxUsbMemAllocZ(SIZE_T cbBytes);
+DECLHIDDEN(VOID) vboxUsbMemFree(PVOID pvMem);
+
+#include "VBoxUsbRt.h"
+#include "VBoxUsbPnP.h"
+#include "VBoxUsbPwr.h"
+#include "VBoxUsbDev.h"
+
+
+#endif /* #ifndef ___VBoxUsbCmn_h___ */
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.cpp b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.cpp
new file mode 100644
index 000000000..5fe98612e
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.cpp
@@ -0,0 +1,335 @@
+/* $Id: VBoxUsbDev.cpp 36968 2011-05-05 08:55:16Z vboxsync $ */
+/** @file
+ * VBoxUsbDev.cpp - USB device.
+ */
+/*
+ * 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.
+ */
+#include "VBoxUsbCmn.h"
+#include <iprt/assert.h>
+#include <VBox/log.h>
+
+#define VBOXUSB_MEMTAG 'bUBV'
+
+DECLHIDDEN(PVOID) vboxUsbMemAlloc(SIZE_T cbBytes)
+{
+ PVOID pvMem = ExAllocatePoolWithTag(NonPagedPool, cbBytes, VBOXUSB_MEMTAG);
+ Assert(pvMem);
+ return pvMem;
+}
+
+DECLHIDDEN(PVOID) vboxUsbMemAllocZ(SIZE_T cbBytes)
+{
+ PVOID pvMem = vboxUsbMemAlloc(cbBytes);
+ if (pvMem)
+ {
+ RtlZeroMemory(pvMem, cbBytes);
+ }
+ return pvMem;
+}
+
+DECLHIDDEN(VOID) vboxUsbMemFree(PVOID pvMem)
+{
+ ExFreePoolWithTag(pvMem, VBOXUSB_MEMTAG);
+}
+
+VBOXUSB_GLOBALS g_VBoxUsbGlobals = {0};
+
+static NTSTATUS vboxUsbDdiAddDevice(PDRIVER_OBJECT pDriverObject,
+ PDEVICE_OBJECT pPDO)
+{
+ PDEVICE_OBJECT pFDO = NULL;
+ NTSTATUS Status = IoCreateDevice(pDriverObject,
+ sizeof (VBOXUSBDEV_EXT),
+ NULL, /* IN PUNICODE_STRING pDeviceName OPTIONAL */
+ FILE_DEVICE_UNKNOWN, /* IN DEVICE_TYPE DeviceType */
+ FILE_AUTOGENERATED_DEVICE_NAME, /* IN ULONG DeviceCharacteristics */
+ FALSE, /* IN BOOLEAN fExclusive */
+ &pFDO);
+ Assert(Status == STATUS_SUCCESS);
+ if (Status == STATUS_SUCCESS)
+ {
+ PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pFDO->DeviceExtension;
+ /* init Device Object bits */
+ pFDO->Flags |= DO_DIRECT_IO;
+ if (pPDO->Flags & DO_POWER_PAGABLE)
+ pFDO->Flags |= DO_POWER_PAGABLE;
+
+
+ /* now init our state bits */
+
+ pDevExt->cHandles = 0;
+
+ pDevExt->pFDO = pFDO;
+ pDevExt->pPDO = pPDO;
+ pDevExt->pLowerDO = IoAttachDeviceToDeviceStack(pFDO, pPDO);
+ Assert(pDevExt->pLowerDO);
+ if (pDevExt->pLowerDO)
+ {
+ vboxUsbDdiStateInit(pDevExt);
+ Status = vboxUsbRtInit(pDevExt);
+ if (Status == STATUS_SUCCESS)
+ {
+ /* we're done! */
+ pFDO->Flags &= ~DO_DEVICE_INITIALIZING;
+ return STATUS_SUCCESS;
+ }
+
+ IoDetachDevice(pDevExt->pLowerDO);
+ }
+ else
+ Status = STATUS_NO_SUCH_DEVICE;
+
+ IoDeleteDevice(pFDO);
+ }
+
+ return Status;
+}
+
+static VOID vboxUsbDdiUnload(PDRIVER_OBJECT pDriverObject)
+{
+ LogRel(("VBoxUsb::DriverUnload. Built Date (%s) Time (%s)\n", __DATE__, __TIME__));
+ VBoxDrvToolStrFree(&g_VBoxUsbGlobals.RegPath);
+
+ vboxUsbRtGlobalsTerm();
+
+ PRTLOGGER pLogger = RTLogRelSetDefaultInstance(NULL);
+ if (pLogger)
+ {
+ RTLogDestroy(pLogger);
+ }
+ pLogger = RTLogSetDefaultInstance(NULL);
+ if (pLogger)
+ {
+ RTLogDestroy(pLogger);
+ }
+}
+
+static NTSTATUS vboxUsbDispatchCreate(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
+{
+ PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
+ NTSTATUS Status = STATUS_INVALID_HANDLE;
+ do
+ {
+ if (vboxUsbPnPStateGet(pDevExt) != ENMVBOXUSB_PNPSTATE_STARTED)
+ {
+ Status = STATUS_INVALID_DEVICE_STATE;
+ break;
+ }
+
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFObj = pSl->FileObject;
+ if (!pFObj)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ pFObj->FsContext = NULL;
+
+ if (pFObj->FileName.Length)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ Status = vboxUsbRtCreate(pDevExt, pIrp);
+ if (!NT_SUCCESS(Status))
+ {
+ AssertFailed();
+ break;
+ }
+
+ ASMAtomicIncU32(&pDevExt->cHandles);
+ Status = STATUS_SUCCESS;
+ break;
+ } while (0);
+
+ Status = VBoxDrvToolIoComplete(pIrp, Status, 0);
+ return Status;
+}
+
+static NTSTATUS vboxUsbDispatchClose(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
+{
+ PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFObj = pSl->FileObject;
+ NTSTATUS Status = STATUS_SUCCESS;
+ Assert(pFObj);
+ Assert(!pFObj->FileName.Length);
+ Status = vboxUsbRtClose(pDevExt, pIrp);
+ if (NT_SUCCESS(Status))
+ {
+ ASMAtomicDecU32(&pDevExt->cHandles);
+ }
+ else
+ {
+ AssertFailed();
+ }
+ Status = VBoxDrvToolIoComplete(pIrp, Status, 0);
+ return Status;
+}
+
+static NTSTATUS vboxUsbDispatchDeviceControl(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
+{
+ PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
+ NTSTATUS Status = STATUS_INVALID_HANDLE;
+ if (vboxUsbDdiStateRetainIfStarted(pDevExt))
+ {
+ return vboxUsbRtDispatch(pDevExt, pIrp);
+ }
+ else
+ {
+ Status = STATUS_INVALID_DEVICE_STATE;
+ }
+
+ Status = VBoxDrvToolIoComplete(pIrp, Status, 0);
+ return Status;
+}
+
+static NTSTATUS vboxUsbDispatchCleanup(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
+{
+ PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
+ NTSTATUS Status = STATUS_SUCCESS;
+ Status = VBoxDrvToolIoComplete(pIrp, Status, 0);
+ return Status;
+}
+
+static NTSTATUS vboxUsbDevAccessDeviedDispatchStub(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
+{
+ PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
+ if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt))
+ {
+ VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0);
+ return STATUS_DELETE_PENDING;
+ }
+
+ NTSTATUS Status = STATUS_ACCESS_DENIED;
+ Status = VBoxDrvToolIoComplete(pIrp, Status, 0);
+
+ vboxUsbDdiStateRelease(pDevExt);
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbDispatchSystemControl(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
+{
+ PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
+ if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt))
+ {
+ VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0);
+ return STATUS_DELETE_PENDING;
+ }
+
+ IoSkipCurrentIrpStackLocation(pIrp);
+
+ NTSTATUS Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
+
+ vboxUsbDdiStateRelease(pDevExt);
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbDispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
+{
+#ifdef DEBUG_misha
+ AssertFailed();
+#endif
+ return vboxUsbDevAccessDeviedDispatchStub(pDeviceObject, pIrp);
+}
+
+static NTSTATUS vboxUsbDispatchWrite(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
+{
+#ifdef DEBUG_misha
+ AssertFailed();
+#endif
+ return vboxUsbDevAccessDeviedDispatchStub(pDeviceObject, pIrp);
+}
+
+RT_C_DECLS_BEGIN
+
+NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath);
+
+RT_C_DECLS_END
+
+NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
+{
+ LogRel(("VBoxUsb::DriverEntry. Built Date (%s) Time (%s)\n", __DATE__, __TIME__));
+
+ NTSTATUS Status = vboxUsbRtGlobalsInit();
+ Assert(Status == STATUS_SUCCESS);
+ if (Status == STATUS_SUCCESS)
+ {
+ Status = VBoxDrvToolStrCopy(&g_VBoxUsbGlobals.RegPath, pRegistryPath);
+ Assert(Status == STATUS_SUCCESS);
+ if (Status == STATUS_SUCCESS)
+ {
+ g_VBoxUsbGlobals.pDrvObj = pDriverObject;
+
+ pDriverObject->DriverExtension->AddDevice = vboxUsbDdiAddDevice;
+
+ pDriverObject->DriverUnload = vboxUsbDdiUnload;
+
+ pDriverObject->MajorFunction[IRP_MJ_CREATE] = vboxUsbDispatchCreate;
+ pDriverObject->MajorFunction[IRP_MJ_CLOSE] = vboxUsbDispatchClose;
+ pDriverObject->MajorFunction[IRP_MJ_READ] = vboxUsbDispatchRead;
+ pDriverObject->MajorFunction[IRP_MJ_WRITE] = vboxUsbDispatchWrite;
+ pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = vboxUsbDispatchDeviceControl;
+ pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = vboxUsbDispatchCleanup;
+ pDriverObject->MajorFunction[IRP_MJ_POWER] = vboxUsbDispatchPower;
+ pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = vboxUsbDispatchSystemControl;
+ pDriverObject->MajorFunction[IRP_MJ_PNP] = vboxUsbDispatchPnP;
+
+ return STATUS_SUCCESS;
+ }
+ vboxUsbRtGlobalsTerm();
+ }
+
+ LogRel(("VBoxUsb::DriverEntry. failed with Status (0x%x)\n", Status));
+
+ return Status;
+}
+
+#ifdef DEBUG
+DECLHIDDEN(VOID) vboxUsbPnPStateGbgChange(ENMVBOXUSB_PNPSTATE enmOldState, ENMVBOXUSB_PNPSTATE enmNewState)
+{
+ /* *ensure the state change is valid */
+ switch (enmNewState)
+ {
+ case ENMVBOXUSB_PNPSTATE_STARTED:
+ Assert(enmOldState == ENMVBOXUSB_PNPSTATE_START_PENDING
+ || ENMVBOXUSB_PNPSTATE_REMOVE_PENDING
+ || ENMVBOXUSB_PNPSTATE_STOPPED
+ || ENMVBOXUSB_PNPSTATE_STOP_PENDING);
+ break;
+ case ENMVBOXUSB_PNPSTATE_STOP_PENDING:
+ Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STARTED);
+ break;
+ case ENMVBOXUSB_PNPSTATE_STOPPED:
+ Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STOP_PENDING);
+ break;
+ case ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED:
+ Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STARTED);
+ break;
+ case ENMVBOXUSB_PNPSTATE_REMOVE_PENDING:
+ Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STARTED);
+ break;
+ case ENMVBOXUSB_PNPSTATE_REMOVED:
+ Assert(enmOldState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING
+ || enmOldState == ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED);
+ break;
+ default:
+ AssertBreakpoint();
+ break;
+ }
+
+}
+#endif
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.h b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.h
new file mode 100644
index 000000000..ce65b8c9e
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.h
@@ -0,0 +1,197 @@
+/* $Id: VBoxUsbDev.h 36998 2011-05-07 20:19:55Z vboxsync $ */
+/** @file
+ * VBoxUsbDev.h - USB device.
+ */
+/*
+ * 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 ___VBoxUsbDev_h___
+#define ___VBoxUsbDev_h___
+#include "VBoxUsbCmn.h"
+#include <iprt/assert.h>
+
+typedef struct VBOXUSB_GLOBALS
+{
+ PDRIVER_OBJECT pDrvObj;
+ UNICODE_STRING RegPath;
+ VBOXUSBRT_IDC RtIdc;
+} VBOXUSB_GLOBALS, *PVBOXUSB_GLOBALS;
+
+extern VBOXUSB_GLOBALS g_VBoxUsbGlobals;
+
+/* pnp state decls */
+typedef enum
+{
+ ENMVBOXUSB_PNPSTATE_UNKNOWN = 0,
+ ENMVBOXUSB_PNPSTATE_START_PENDING,
+ ENMVBOXUSB_PNPSTATE_STARTED,
+ ENMVBOXUSB_PNPSTATE_STOP_PENDING,
+ ENMVBOXUSB_PNPSTATE_STOPPED,
+ ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED,
+ ENMVBOXUSB_PNPSTATE_REMOVE_PENDING,
+ ENMVBOXUSB_PNPSTATE_REMOVED,
+ ENMVBOXUSB_PNPSTATE_FORSEDWORD = 0x8fffffff
+} ENMVBOXUSB_PNPSTATE;
+AssertCompile(sizeof (ENMVBOXUSB_PNPSTATE) == sizeof (uint32_t));
+
+#ifdef DEBUG
+DECLHIDDEN(VOID) vboxUsbPnPStateGbgChange(ENMVBOXUSB_PNPSTATE enmOld, ENMVBOXUSB_PNPSTATE enmNew);
+# define VBOXUSB_PNP_GBG_STATE_CHANGE(_old, _new) vboxUsbPnPStateGbgChange((_old), (_new))
+#else
+# define VBOXUSB_PNP_GBG_STATE_CHANGE(_old, _new) do {} while(0)
+#endif
+
+
+typedef struct VBOXUSB_PNPSTATE
+{
+ /* Current state */
+ volatile ENMVBOXUSB_PNPSTATE Curr;
+ /* Previous state, used to restore state info on cancell stop device */
+ ENMVBOXUSB_PNPSTATE Prev;
+} VBOXUSB_PNPSTATE, *PVBOXUSB_PNPSTATE;
+
+typedef struct VBOXUSBDEV_DDISTATE
+{
+ /* Lock */
+ KSPIN_LOCK Lock;
+ VBOXDRVTOOL_REF Ref;
+ VBOXUSB_PNPSTATE PnPState;
+ VBOXUSB_PWRSTATE PwrState;
+ /* current dev caps */
+ DEVICE_CAPABILITIES DevCaps;
+} VBOXUSBDEV_DDISTATE, *PVBOXUSBDEV_DDISTATE;
+
+typedef struct VBOXUSBDEV_EXT
+{
+ PDEVICE_OBJECT pFDO;
+ PDEVICE_OBJECT pPDO;
+ PDEVICE_OBJECT pLowerDO;
+
+ VBOXUSBDEV_DDISTATE DdiState;
+
+ uint32_t cHandles;
+
+ VBOXUSB_RT Rt;
+
+} VBOXUSBDEV_EXT, *PVBOXUSBDEV_EXT;
+
+/* pnp state api */
+static DECLINLINE(ENMVBOXUSB_PNPSTATE) vboxUsbPnPStateGet(PVBOXUSBDEV_EXT pDevExt)
+{
+ return (ENMVBOXUSB_PNPSTATE)ASMAtomicUoReadU32((volatile uint32_t*)&pDevExt->DdiState.PnPState.Curr);
+}
+
+static DECLINLINE(ENMVBOXUSB_PNPSTATE) vboxUsbPnPStateSet(PVBOXUSBDEV_EXT pDevExt, ENMVBOXUSB_PNPSTATE enmState)
+{
+ KIRQL Irql;
+ ENMVBOXUSB_PNPSTATE enmOldState;
+ KeAcquireSpinLock(&pDevExt->DdiState.Lock, &Irql);
+ pDevExt->DdiState.PnPState.Prev = (ENMVBOXUSB_PNPSTATE)ASMAtomicUoReadU32((volatile uint32_t*)&pDevExt->DdiState.PnPState.Curr);
+ ASMAtomicWriteU32((volatile uint32_t*)&pDevExt->DdiState.PnPState.Curr, (uint32_t)enmState);
+ pDevExt->DdiState.PnPState.Curr = enmState;
+ enmOldState = pDevExt->DdiState.PnPState.Prev;
+ KeReleaseSpinLock(&pDevExt->DdiState.Lock, Irql);
+ VBOXUSB_PNP_GBG_STATE_CHANGE(enmOldState, enmState);
+ return enmState;
+}
+
+static DECLINLINE(ENMVBOXUSB_PNPSTATE) vboxUsbPnPStateRestore(PVBOXUSBDEV_EXT pDevExt)
+{
+ ENMVBOXUSB_PNPSTATE enmNewState, enmOldState;
+ KIRQL Irql;
+ KeAcquireSpinLock(&pDevExt->DdiState.Lock, &Irql);
+ enmOldState = pDevExt->DdiState.PnPState.Curr;
+ enmNewState = pDevExt->DdiState.PnPState.Prev;
+ ASMAtomicWriteU32((volatile uint32_t*)&pDevExt->DdiState.PnPState.Curr, (uint32_t)pDevExt->DdiState.PnPState.Prev);
+ KeReleaseSpinLock(&pDevExt->DdiState.Lock, Irql);
+ VBOXUSB_PNP_GBG_STATE_CHANGE(enmOldState, enmNewState);
+ Assert(enmNewState == ENMVBOXUSB_PNPSTATE_STARTED);
+ Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STOP_PENDING
+ || enmOldState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING);
+ return enmNewState;
+}
+
+static DECLINLINE(VOID) vboxUsbPnPStateInit(PVBOXUSBDEV_EXT pDevExt)
+{
+ pDevExt->DdiState.PnPState.Curr = pDevExt->DdiState.PnPState.Prev = ENMVBOXUSB_PNPSTATE_START_PENDING;
+}
+
+static DECLINLINE(VOID) vboxUsbDdiStateInit(PVBOXUSBDEV_EXT pDevExt)
+{
+ KeInitializeSpinLock(&pDevExt->DdiState.Lock);
+ VBoxDrvToolRefInit(&pDevExt->DdiState.Ref);
+ vboxUsbPwrStateInit(pDevExt);
+ vboxUsbPnPStateInit(pDevExt);
+}
+
+static DECLINLINE(bool) vboxUsbDdiStateRetainIfStarted(PVBOXUSBDEV_EXT pDevExt)
+{
+ KIRQL oldIrql;
+ bool bRetained = true;
+ KeAcquireSpinLock(&pDevExt->DdiState.Lock, &oldIrql);
+ if (vboxUsbPnPStateGet(pDevExt) == ENMVBOXUSB_PNPSTATE_STARTED)
+ {
+ VBoxDrvToolRefRetain(&pDevExt->DdiState.Ref);
+ }
+ else
+ {
+ bRetained = false;
+ }
+ KeReleaseSpinLock(&pDevExt->DdiState.Lock, oldIrql);
+ return bRetained;
+}
+
+/* if device is removed - does nothing and returns zero,
+ * otherwise increments a ref counter and returns the current pnp state
+ * NOTE: never returns ENMVBOXUSB_PNPSTATE_REMOVED
+ * */
+static DECLINLINE(ENMVBOXUSB_PNPSTATE) vboxUsbDdiStateRetainIfNotRemoved(PVBOXUSBDEV_EXT pDevExt)
+{
+ KIRQL oldIrql;
+ ENMVBOXUSB_PNPSTATE enmState;
+ KeAcquireSpinLock(&pDevExt->DdiState.Lock, &oldIrql);
+ enmState = vboxUsbPnPStateGet(pDevExt);
+ if (enmState != ENMVBOXUSB_PNPSTATE_REMOVED)
+ {
+ VBoxDrvToolRefRetain(&pDevExt->DdiState.Ref);
+ }
+ KeReleaseSpinLock(&pDevExt->DdiState.Lock, oldIrql);
+ return enmState != ENMVBOXUSB_PNPSTATE_REMOVED ? enmState : (ENMVBOXUSB_PNPSTATE)0;
+}
+
+static DECLINLINE(uint32_t) vboxUsbDdiStateRetain(PVBOXUSBDEV_EXT pDevExt)
+{
+ return VBoxDrvToolRefRetain(&pDevExt->DdiState.Ref);
+}
+
+static DECLINLINE(uint32_t) vboxUsbDdiStateRelease(PVBOXUSBDEV_EXT pDevExt)
+{
+ return VBoxDrvToolRefRelease(&pDevExt->DdiState.Ref);
+}
+
+static DECLINLINE(VOID) vboxUsbDdiStateReleaseAndWaitCompleted(PVBOXUSBDEV_EXT pDevExt)
+{
+ VBoxDrvToolRefRelease(&pDevExt->DdiState.Ref);
+ VBoxDrvToolRefWaitEqual(&pDevExt->DdiState.Ref, 1);
+}
+
+static DECLINLINE(VOID) vboxUsbDdiStateReleaseAndWaitRemoved(PVBOXUSBDEV_EXT pDevExt)
+{
+ VBoxDrvToolRefRelease(&pDevExt->DdiState.Ref);
+ VBoxDrvToolRefWaitEqual(&pDevExt->DdiState.Ref, 0);
+}
+
+static DECLHIDDEN(VOID) vboxUsbDdiStateWaitOtherCompleted(PVBOXUSBDEV_EXT pDevExt)
+{
+ VBoxDrvToolRefWaitEqual(&pDevExt->DdiState.Ref, 2);
+}
+
+#endif /* #ifndef ___VBoxUsbDev_h___ */
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxusb.rc b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.rc
index b6c782189..94f31a29c 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxusb.rc
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.rc
@@ -1,10 +1,10 @@
-/* $Id: vboxusb.rc $ */
+/* $Id: VBoxUsbDev.rc 36968 2011-05-05 08:55:16Z vboxsync $ */
/** @file
* VBoxUSB - Resource file containing version info and icon.
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * 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;
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.cpp b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.cpp
new file mode 100644
index 000000000..bc236a2a2
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.cpp
@@ -0,0 +1,277 @@
+/* $Id: VBoxUsbPnP.cpp 36968 2011-05-05 08:55:16Z vboxsync $ */
+/** @file
+ * USB PnP Handling
+ */
+/*
+ * 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.
+ */
+#include "VBoxUsbCmn.h"
+
+static NTSTATUS vboxUsbPnPMnStartDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ IoCopyCurrentIrpStackLocationToNext(pIrp);
+ NTSTATUS Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
+ Assert(NT_SUCCESS(Status) || Status == STATUS_NOT_SUPPORTED);
+ if (NT_SUCCESS(Status))
+ {
+ Status = vboxUsbRtStart(pDevExt);
+ Assert(Status == STATUS_SUCCESS);
+ if (NT_SUCCESS(Status))
+ {
+ vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_STARTED);
+ }
+ }
+
+ VBoxDrvToolIoComplete(pIrp, Status, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static NTSTATUS vboxUsbPnPMnQueryStopDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_STOP_PENDING);
+
+ vboxUsbDdiStateReleaseAndWaitCompleted(pDevExt);
+
+ pIrp->IoStatus.Status = STATUS_SUCCESS;
+ pIrp->IoStatus.Information = 0;
+ IoSkipCurrentIrpStackLocation(pIrp);
+ return IoCallDriver(pDevExt->pLowerDO, pIrp);
+}
+
+static NTSTATUS vboxUsbPnPMnStopDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_STOPPED);
+
+ vboxUsbRtClear(pDevExt);
+
+ NTSTATUS Status = VBoxUsbToolDevUnconfigure(pDevExt->pLowerDO);
+ Assert(NT_SUCCESS(Status));
+
+ pIrp->IoStatus.Status = Status;
+ pIrp->IoStatus.Information = 0;
+ IoSkipCurrentIrpStackLocation(pIrp);
+ Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
+
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static NTSTATUS vboxUsbPnPMnCancelStopDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
+ NTSTATUS Status = STATUS_SUCCESS;
+ if (enmState == ENMVBOXUSB_PNPSTATE_STOP_PENDING)
+ {
+ IoCopyCurrentIrpStackLocationToNext(pIrp);
+ Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
+ if (NT_SUCCESS(Status))
+ {
+ vboxUsbPnPStateRestore(pDevExt);
+ }
+ }
+ else
+ {
+ Assert(0);
+ Assert(enmState == ENMVBOXUSB_PNPSTATE_STARTED);
+ }
+
+ VBoxDrvToolIoComplete(pIrp, Status, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbPnPMnQueryRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_REMOVE_PENDING);
+
+ vboxUsbDdiStateReleaseAndWaitCompleted(pDevExt);
+
+ pIrp->IoStatus.Status = STATUS_SUCCESS;
+ pIrp->IoStatus.Information = 0;
+ IoSkipCurrentIrpStackLocation(pIrp);
+ return IoCallDriver(pDevExt->pLowerDO, pIrp);
+}
+
+static NTSTATUS vboxUsbPnPRmDev(PVBOXUSBDEV_EXT pDevExt)
+{
+ NTSTATUS Status = vboxUsbRtRm(pDevExt);
+ Assert(Status == STATUS_SUCCESS);
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbPnPMnRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
+ NTSTATUS Status = STATUS_SUCCESS;
+ if (enmState != ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED)
+ {
+ Status = vboxUsbPnPRmDev(pDevExt);
+ Assert(Status == STATUS_SUCCESS);
+ }
+
+ vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_REMOVED);
+
+ vboxUsbDdiStateRelease(pDevExt);
+
+ vboxUsbDdiStateReleaseAndWaitRemoved(pDevExt);
+
+ vboxUsbRtClear(pDevExt);
+
+ pIrp->IoStatus.Status = STATUS_SUCCESS;
+ pIrp->IoStatus.Information = 0;
+ IoSkipCurrentIrpStackLocation(pIrp);
+ Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
+
+ IoDetachDevice(pDevExt->pLowerDO);
+ IoDeleteDevice(pDevExt->pFDO);
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbPnPMnCancelRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
+ NTSTATUS Status = STATUS_SUCCESS;
+ if (enmState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING)
+ {
+ IoCopyCurrentIrpStackLocationToNext(pIrp);
+ Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
+ if (NT_SUCCESS(Status))
+ {
+ vboxUsbPnPStateRestore(pDevExt);
+ }
+ }
+ else
+ {
+ Assert(0);
+ Assert(enmState == ENMVBOXUSB_PNPSTATE_STARTED);
+ }
+
+ VBoxDrvToolIoComplete(pIrp, Status, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbPnPMnSurpriseRemoval(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED);
+
+ NTSTATUS Status = vboxUsbPnPRmDev(pDevExt);
+ Assert(Status == STATUS_SUCCESS);
+
+ pIrp->IoStatus.Status = STATUS_SUCCESS;
+ pIrp->IoStatus.Information = 0;
+ IoSkipCurrentIrpStackLocation(pIrp);
+ Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
+
+ vboxUsbDdiStateRelease(pDevExt);
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbPnPMnQueryCapabilities(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PDEVICE_CAPABILITIES pDevCaps = pSl->Parameters.DeviceCapabilities.Capabilities;
+
+ if (pDevCaps->Version < 1 || pDevCaps->Size < sizeof (*pDevCaps))
+ {
+ Assert(0);
+ /* todo: return more appropriate status ?? */
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ pDevCaps->SurpriseRemovalOK = TRUE;
+ pIrp->IoStatus.Status = STATUS_SUCCESS;
+
+ IoCopyCurrentIrpStackLocationToNext(pIrp);
+ NTSTATUS Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
+ Assert(NT_SUCCESS(Status));
+ if (NT_SUCCESS(Status))
+ {
+ pDevCaps->SurpriseRemovalOK = 1;
+ pDevExt->DdiState.DevCaps = *pDevCaps;
+ }
+
+ VBoxDrvToolIoComplete(pIrp, Status, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbPnPMnDefault(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ NTSTATUS Status;
+ IoSkipCurrentIrpStackLocation(pIrp);
+ Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+DECLHIDDEN(NTSTATUS) vboxUsbDispatchPnP(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
+{
+ PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
+ ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
+ if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt))
+ {
+ return VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0);
+ }
+
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+
+ switch (pSl->MinorFunction)
+ {
+ case IRP_MN_START_DEVICE:
+ {
+ return vboxUsbPnPMnStartDevice(pDevExt, pIrp);
+ }
+ case IRP_MN_QUERY_STOP_DEVICE:
+ {
+ return vboxUsbPnPMnQueryStopDevice(pDevExt, pIrp);
+ }
+ case IRP_MN_STOP_DEVICE:
+ {
+ return vboxUsbPnPMnStopDevice(pDevExt, pIrp);
+ }
+ case IRP_MN_CANCEL_STOP_DEVICE:
+ {
+ return vboxUsbPnPMnCancelStopDevice(pDevExt, pIrp);
+ }
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ {
+ return vboxUsbPnPMnQueryRemoveDevice(pDevExt, pIrp);
+ }
+ case IRP_MN_REMOVE_DEVICE:
+ {
+ return vboxUsbPnPMnRemoveDevice(pDevExt, pIrp);
+ }
+ case IRP_MN_CANCEL_REMOVE_DEVICE:
+ {
+ return vboxUsbPnPMnCancelRemoveDevice(pDevExt, pIrp);
+ }
+ case IRP_MN_SURPRISE_REMOVAL:
+ {
+ return vboxUsbPnPMnSurpriseRemoval(pDevExt, pIrp);
+ }
+ case IRP_MN_QUERY_CAPABILITIES:
+ {
+ return vboxUsbPnPMnQueryCapabilities(pDevExt, pIrp);
+ }
+ default:
+ {
+ return vboxUsbPnPMnDefault(pDevExt, pIrp);
+ }
+ }
+}
diff --git a/src/VBox/Additions/linux/installer/test.c b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.h
index 970a07e16..0450d0a26 100644
--- a/src/VBox/Additions/linux/installer/test.c
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.h
@@ -1,7 +1,9 @@
+/* $Id: VBoxUsbPnP.h 36968 2011-05-05 08:55:16Z vboxsync $ */
+/** @file
+ * USB PnP Handling
+ */
/*
- * VirtualBox Guest Additions installer test module for Linux
- *
- * Copyright (C) 2006-2007 Oracle Corporation
+ * 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;
@@ -11,20 +13,10 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
+#ifndef ___VBoxUsbPnP_h___
+#define ___VBoxUsbPnP_h___
+#include "VBoxUsbCmn.h"
-#include <linux/init.h>
-#include <linux/module.h>
-
-MODULE_DESCRIPTION("VirtualBox Guest Additions configuration test module");
-MODULE_AUTHOR("Oracle Corporation");
-MODULE_LICENSE("GPL");
-
-static int init(void)
-{
- return 0;
-}
-
-static void fini(void) {}
+DECLHIDDEN(NTSTATUS) vboxUsbDispatchPnP(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp);
-module_init(init);
-module_exit(fini);
+#endif /* #ifndef ___VBoxUsbPnP_h___ */
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.cpp b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.cpp
new file mode 100644
index 000000000..80e28ece1
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.cpp
@@ -0,0 +1,438 @@
+/* $Id: VBoxUsbPwr.cpp 36968 2011-05-05 08:55:16Z vboxsync $ */
+/** @file
+ * USB Power state Handling
+ */
+/*
+ * 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.
+ */
+
+#include "VBoxUsbCmn.h"
+
+#include <iprt/assert.h>
+
+DECLHIDDEN(VOID) vboxUsbPwrStateInit(PVBOXUSBDEV_EXT pDevExt)
+{
+ POWER_STATE PowerState;
+ PowerState.SystemState = PowerSystemWorking;
+ PowerState.DeviceState = PowerDeviceD0;
+ PoSetPowerState(pDevExt->pFDO, DevicePowerState, PowerState);
+ pDevExt->DdiState.PwrState.PowerState = PowerState;
+ pDevExt->DdiState.PwrState.PowerDownLevel = PowerDeviceUnspecified;
+}
+
+static NTSTATUS vboxUsbPwrMnDefault(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ NTSTATUS Status;
+ PoStartNextPowerIrp(pIrp);
+ IoSkipCurrentIrpStackLocation(pIrp);
+ Status = PoCallDriver(pDevExt->pLowerDO, pIrp);
+ Assert(NT_SUCCESS(Status) || Status == STATUS_NOT_SUPPORTED);
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static NTSTATUS vboxUsbPwrMnPowerSequence(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ Assert(0);
+ return vboxUsbPwrMnDefault(pDevExt, pIrp);
+}
+
+typedef struct VBOXUSB_PWRDEV_CTX
+{
+ PVBOXUSBDEV_EXT pDevExt;
+ PIRP pIrp;
+} VBOXUSB_PWRDEV_CTX, *PVBOXUSB_PWRDEV_CTX;
+
+static VOID vboxUsbPwrIoDeviceCompletion(IN PDEVICE_OBJECT pDeviceObject,
+ IN UCHAR MinorFunction,
+ IN POWER_STATE PowerState,
+ IN PVOID pvContext,
+ IN PIO_STATUS_BLOCK pIoStatus)
+{
+ PVBOXUSB_PWRDEV_CTX pDevCtx = (PVBOXUSB_PWRDEV_CTX)pvContext;
+ PVBOXUSBDEV_EXT pDevExt = pDevCtx->pDevExt;
+ PIRP pIrp = pDevCtx->pIrp;
+ pIrp->IoStatus.Status = pIoStatus->Status;
+ pIrp->IoStatus.Information = 0;
+
+ PoStartNextPowerIrp(pIrp);
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ vboxUsbDdiStateRelease(pDevExt);
+
+ vboxUsbMemFree(pDevCtx);
+}
+
+static NTSTATUS vboxUsbPwrIoRequestDev(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ POWER_STATE PwrState;
+ PwrState.SystemState = pSl->Parameters.Power.State.SystemState;
+ PwrState.DeviceState = pDevExt->DdiState.DevCaps.DeviceState[PwrState.SystemState];
+
+ NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
+ PVBOXUSB_PWRDEV_CTX pDevCtx = (PVBOXUSB_PWRDEV_CTX)vboxUsbMemAlloc(sizeof (*pDevCtx));
+ Assert(pDevCtx);
+ if (pDevCtx)
+ {
+ pDevCtx->pDevExt = pDevExt;
+ pDevCtx->pIrp = pIrp;
+
+ Status = PoRequestPowerIrp(pDevExt->pPDO, pSl->MinorFunction, PwrState,
+ vboxUsbPwrIoDeviceCompletion, pDevCtx, NULL);
+ Assert(NT_SUCCESS(Status));
+ if (NT_SUCCESS(Status))
+ {
+ return STATUS_MORE_PROCESSING_REQUIRED;
+ }
+
+ vboxUsbMemFree(pDevCtx);
+ }
+
+ PoStartNextPowerIrp(pIrp);
+ pIrp->IoStatus.Status = Status;
+ pIrp->IoStatus.Information = 0;
+ vboxUsbDdiStateRelease(pDevExt);
+
+ /* the "real" Status is stored in pIrp->IoStatus.Status,
+ * return success here to complete the Io */
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS vboxUsbPwrIoPostSysCompletion(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN PVOID pvContext)
+{
+ PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pvContext;
+ NTSTATUS Status = pIrp->IoStatus.Status;
+ Assert(Status == STATUS_SUCCESS);
+ if (NT_SUCCESS(Status))
+ {
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ switch (pSl->MinorFunction)
+ {
+ case IRP_MN_SET_POWER:
+ {
+ pDevExt->DdiState.PwrState.PowerState.SystemState = pSl->Parameters.Power.State.SystemState;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return vboxUsbPwrIoRequestDev(pDevExt, pIrp);
+ }
+
+ PoStartNextPowerIrp(pIrp);
+ vboxUsbDdiStateRelease(pDevExt);
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS vboxUsbPwrIoPostSys(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ IoMarkIrpPending(pIrp);
+ IoCopyCurrentIrpStackLocationToNext(pIrp);
+ IoSetCompletionRoutine(pIrp, vboxUsbPwrIoPostSysCompletion, pDevExt, TRUE, TRUE, TRUE);
+ NTSTATUS Status = PoCallDriver(pDevExt->pLowerDO, pIrp);
+ Assert(NT_SUCCESS(Status));
+ return STATUS_PENDING;
+}
+
+static NTSTATUS vboxUsbPwrQueryPowerSys(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ SYSTEM_POWER_STATE enmSysPState = pSl->Parameters.Power.State.SystemState;
+
+ return vboxUsbPwrIoPostSys(pDevExt, pIrp);
+}
+
+static NTSTATUS vboxUsbPwrIoPostDevCompletion(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN PVOID pvContext)
+{
+ PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pvContext;
+
+ if (pIrp->PendingReturned)
+ {
+ IoMarkIrpPending(pIrp);
+ }
+
+ NTSTATUS Status = pIrp->IoStatus.Status;
+ Assert(Status == STATUS_SUCCESS);
+ if (NT_SUCCESS(Status))
+ {
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ switch (pSl->MinorFunction)
+ {
+ case IRP_MN_SET_POWER:
+ {
+ pDevExt->DdiState.PwrState.PowerState.DeviceState = pSl->Parameters.Power.State.DeviceState;
+ PoSetPowerState(pDevExt->pFDO, DevicePowerState, pSl->Parameters.Power.State);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ PoStartNextPowerIrp(pIrp);
+ vboxUsbDdiStateRelease(pDevExt);
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS vboxUsbPwrIoPostDev(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ IoMarkIrpPending(pIrp);
+ IoCopyCurrentIrpStackLocationToNext(pIrp);
+ IoSetCompletionRoutine(pIrp, vboxUsbPwrIoPostDevCompletion, pDevExt, TRUE, TRUE, TRUE);
+ NTSTATUS Status = PoCallDriver(pDevExt->pLowerDO, pIrp);
+ Assert(NT_SUCCESS(Status));
+ return STATUS_PENDING;
+}
+
+typedef struct VBOXUSB_IOASYNC_CTX
+{
+ PIO_WORKITEM pWrkItem;
+ PIRP pIrp;
+} VBOXUSB_IOASYNC_CTX, *PVBOXUSB_IOASYNC_CTX;
+
+static VOID vboxUsbPwrIoWaitCompletionAndPostAsyncWorker(IN PDEVICE_OBJECT pDeviceObject, IN PVOID pvContext)
+{
+ PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
+ PVBOXUSB_IOASYNC_CTX pCtx = (PVBOXUSB_IOASYNC_CTX)pvContext;
+ PIRP pIrp = pCtx->pIrp;
+
+ vboxUsbDdiStateWaitOtherCompleted(pDevExt);
+
+ vboxUsbPwrIoPostDev(pDevExt, pIrp);
+
+ IoFreeWorkItem(pCtx->pWrkItem);
+ vboxUsbMemFree(pCtx);
+}
+
+static NTSTATUS vboxUsbPwrIoWaitCompletionAndPostAsync(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
+ PVBOXUSB_IOASYNC_CTX pCtx = (PVBOXUSB_IOASYNC_CTX)vboxUsbMemAlloc(sizeof (*pCtx));
+ Assert(pCtx);
+ if (pCtx)
+ {
+ PIO_WORKITEM pWrkItem = IoAllocateWorkItem(pDevExt->pFDO);
+ Assert(pWrkItem);
+ if (pWrkItem)
+ {
+ pCtx->pWrkItem = pWrkItem;
+ pCtx->pIrp = pIrp;
+ IoMarkIrpPending(pIrp);
+ IoQueueWorkItem(pWrkItem, vboxUsbPwrIoWaitCompletionAndPostAsyncWorker, DelayedWorkQueue, pCtx);
+ return STATUS_PENDING;
+ }
+ vboxUsbMemFree(pCtx);
+ }
+ return Status;
+}
+
+static NTSTATUS vboxUsbPwrQueryPowerDev(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ DEVICE_POWER_STATE enmDevPState = pSl->Parameters.Power.State.DeviceState;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (enmDevPState >= pDevExt->DdiState.PwrState.PowerState.DeviceState)
+ {
+ Status = vboxUsbPwrIoWaitCompletionAndPostAsync(pDevExt, pIrp);
+ Assert(NT_SUCCESS(Status));
+ if (NT_SUCCESS(Status))
+ return Status;
+ }
+
+ pIrp->IoStatus.Status = Status;
+ pIrp->IoStatus.Information = 0;
+
+ PoStartNextPowerIrp(pIrp);
+
+ if (NT_SUCCESS(Status))
+ {
+ IoSkipCurrentIrpStackLocation(pIrp);
+ Status = PoCallDriver(pDevExt->pLowerDO, pIrp);
+ }
+ else
+ {
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ }
+
+ vboxUsbDdiStateRelease(pDevExt);
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbPwrMnQueryPower(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+
+ switch (pSl->Parameters.Power.Type)
+ {
+ case SystemPowerState:
+ {
+ return vboxUsbPwrQueryPowerSys(pDevExt, pIrp);
+ }
+ case DevicePowerState:
+ {
+ return vboxUsbPwrQueryPowerDev(pDevExt, pIrp);
+ }
+ default:
+ {
+ Assert(0);
+ return vboxUsbPwrMnDefault(pDevExt, pIrp);
+ }
+
+ }
+ return vboxUsbPwrMnDefault(pDevExt, pIrp);
+}
+
+static NTSTATUS vboxUsbPwrSetPowerSys(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ SYSTEM_POWER_STATE enmSysPState = pSl->Parameters.Power.State.SystemState;
+
+ return vboxUsbPwrIoPostSys(pDevExt, pIrp);
+}
+
+static NTSTATUS vboxUsbPwrSetPowerDev(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ DEVICE_POWER_STATE enmDevPState = pSl->Parameters.Power.State.DeviceState;
+ DEVICE_POWER_STATE enmCurDevPState = pDevExt->DdiState.PwrState.PowerState.DeviceState;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (enmDevPState > enmCurDevPState && enmCurDevPState == PowerDeviceD0)
+ {
+ Status = vboxUsbPwrIoWaitCompletionAndPostAsync(pDevExt, pIrp);
+ Assert(NT_SUCCESS(Status));
+ if (NT_SUCCESS(Status))
+ return Status;
+ }
+
+ PoStartNextPowerIrp(pIrp);
+
+ if (NT_SUCCESS(Status))
+ {
+ IoCopyCurrentIrpStackLocationToNext(pIrp);
+ IoSetCompletionRoutine(pIrp, vboxUsbPwrIoPostDevCompletion, pDevExt, TRUE, TRUE, TRUE);
+ Status = PoCallDriver(pDevExt->pLowerDO, pIrp);
+ }
+ else
+ {
+ pIrp->IoStatus.Status = Status;
+ pIrp->IoStatus.Information = 0;
+
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ vboxUsbDdiStateRelease(pDevExt);
+ }
+
+ return Status;
+}
+
+
+static NTSTATUS vboxUsbPwrMnSetPower(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+
+ switch (pSl->Parameters.Power.Type)
+ {
+ case SystemPowerState:
+ {
+ return vboxUsbPwrSetPowerSys(pDevExt, pIrp);
+ }
+ case DevicePowerState:
+ {
+ return vboxUsbPwrSetPowerDev(pDevExt, pIrp);
+ }
+ default:
+ {
+ Assert(0);
+ return vboxUsbPwrMnDefault(pDevExt, pIrp);
+ }
+
+ }
+ return vboxUsbPwrMnDefault(pDevExt, pIrp);
+}
+
+static NTSTATUS vboxUsbPwrMnWaitWake(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ AssertFailed();
+ return vboxUsbPwrMnDefault(pDevExt, pIrp);
+}
+
+
+static NTSTATUS vboxUsbPwrDispatch(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+
+ switch (pSl->MinorFunction)
+ {
+ case IRP_MN_POWER_SEQUENCE:
+ {
+ return vboxUsbPwrMnPowerSequence(pDevExt, pIrp);
+ }
+ case IRP_MN_QUERY_POWER:
+ {
+ return vboxUsbPwrMnQueryPower(pDevExt, pIrp);
+ }
+ case IRP_MN_SET_POWER:
+ {
+ return vboxUsbPwrMnSetPower(pDevExt, pIrp);
+ }
+ case IRP_MN_WAIT_WAKE:
+ {
+ return vboxUsbPwrMnWaitWake(pDevExt, pIrp);
+ }
+ default:
+ {
+// Assert(0);
+ return vboxUsbPwrMnDefault(pDevExt, pIrp);
+ }
+ }
+}
+
+DECLHIDDEN(NTSTATUS) vboxUsbDispatchPower(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
+{
+ PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
+ ENMVBOXUSB_PNPSTATE enmState = vboxUsbDdiStateRetainIfNotRemoved(pDevExt);
+ switch (enmState)
+ {
+ case ENMVBOXUSB_PNPSTATE_REMOVED:
+ {
+ PoStartNextPowerIrp(pIrp);
+
+ pIrp->IoStatus.Status = STATUS_DELETE_PENDING;
+ pIrp->IoStatus.Information = 0;
+
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+
+ vboxUsbDdiStateRelease(pDevExt);
+
+ return STATUS_DELETE_PENDING;
+ }
+ case ENMVBOXUSB_PNPSTATE_START_PENDING:
+ {
+ PoStartNextPowerIrp(pIrp);
+ IoSkipCurrentIrpStackLocation(pIrp);
+
+ vboxUsbDdiStateRelease(pDevExt);
+
+ return PoCallDriver(pDevExt->pLowerDO, pIrp);
+ }
+ default:
+ {
+ return vboxUsbPwrDispatch(pDevExt, pIrp);
+ }
+ }
+}
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.h b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.h
new file mode 100644
index 000000000..272bfad72
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.h
@@ -0,0 +1,29 @@
+/* $Id: VBoxUsbPwr.h 36968 2011-05-05 08:55:16Z vboxsync $ */
+/** @file
+ * USB Power state Handling
+ */
+/*
+ * 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 ___VBoxUsbPwr_h___
+#define ___VBoxUsbPwr_h___
+
+typedef struct VBOXUSB_PWRSTATE
+{
+ POWER_STATE PowerState;
+ ULONG PowerDownLevel;
+} VBOXUSB_PWRSTATE, *PVBOXUSB_PWRSTATE;
+
+DECLHIDDEN(VOID) vboxUsbPwrStateInit(PVBOXUSBDEV_EXT pDevExt);
+DECLHIDDEN(NTSTATUS) vboxUsbDispatchPower(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp);
+
+#endif /* #ifndef ___VBoxUsbPwr_h___ */
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.cpp b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.cpp
new file mode 100644
index 000000000..52e1394dc
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.cpp
@@ -0,0 +1,1576 @@
+/* $Id: VBoxUsbRt.cpp 37047 2011-05-12 10:29:26Z vboxsync $ */
+/** @file
+ * VBox USB R0 runtime
+ */
+/*
+ * 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.
+ */
+
+#include "VBoxUsbCmn.h"
+#include "../cmn/VBoxUsbIdc.h"
+#include "../cmn/VBoxUsbTool.h"
+
+#include <VBox/usblib-win.h>
+#include <iprt/assert.h>
+#include <VBox/log.h>
+#define _USBD_
+
+#define USBD_DEFAULT_PIPE_TRANSFER 0x00000008
+
+#define VBOXUSB_MAGIC 0xABCF1423
+
+typedef struct VBOXUSB_URB_CONTEXT
+{
+ PURB pUrb;
+ PMDL pMdlBuf;
+ PVBOXUSBDEV_EXT pDevExt;
+ PVOID pOut;
+ ULONG ulTransferType;
+ ULONG ulMagic;
+} VBOXUSB_URB_CONTEXT, * PVBOXUSB_URB_CONTEXT;
+
+typedef struct VBOXUSB_SETUP
+{
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} VBOXUSB_SETUP, *PVBOXUSB_SETUP;
+
+static bool vboxUsbRtCtxSetOwner(PVBOXUSBDEV_EXT pDevExt, PFILE_OBJECT pFObj)
+{
+ bool bRc = ASMAtomicCmpXchgPtr(&pDevExt->Rt.pOwner, pFObj, NULL);
+ if (bRc)
+ {
+ Log((__FUNCTION__": pDevExt (0x%x) Owner(0x%x) acquired\n", pFObj));
+ }
+ else
+ {
+ Log((__FUNCTION__": pDevExt (0x%x) Owner(0x%x) FAILED!!\n", pFObj));
+ }
+ return bRc;
+}
+
+static bool vboxUsbRtCtxReleaseOwner(PVBOXUSBDEV_EXT pDevExt, PFILE_OBJECT pFObj)
+{
+ bool bRc = ASMAtomicCmpXchgPtr(&pDevExt->Rt.pOwner, NULL, pFObj);
+ if (bRc)
+ {
+ Log((__FUNCTION__": pDevExt (0x%x) Owner(0x%x) released\n", pFObj));
+ }
+ else
+ {
+ Log((__FUNCTION__": pDevExt (0x%x) Owner(0x%x) release: is NOT an owner\n", pFObj));
+ }
+ return bRc;
+}
+
+static bool vboxUsbRtCtxIsOwner(PVBOXUSBDEV_EXT pDevExt, PFILE_OBJECT pFObj)
+{
+ PFILE_OBJECT pOwner = (PFILE_OBJECT)ASMAtomicReadPtr((void *volatile *)(&pDevExt->Rt.pOwner));
+ return pOwner == pFObj;
+}
+
+static NTSTATUS vboxUsbRtIdcSubmit(ULONG uCtl, void *pvBuffer)
+{
+ /* we just reuse the standard usb tooling for simplicity here */
+ NTSTATUS Status = VBoxUsbToolIoInternalCtlSendSync(g_VBoxUsbGlobals.RtIdc.pDevice, uCtl, pvBuffer, NULL);
+ Assert(Status == STATUS_SUCCESS);
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtIdcInit()
+{
+ UNICODE_STRING UniName;
+ RtlInitUnicodeString(&UniName, USBMON_DEVICE_NAME_NT);
+ NTSTATUS Status = IoGetDeviceObjectPointer(&UniName, FILE_ALL_ACCESS, &g_VBoxUsbGlobals.RtIdc.pFile, &g_VBoxUsbGlobals.RtIdc.pDevice);
+ if (NT_SUCCESS(Status))
+ {
+ VBOXUSBIDC_VERSION Version;
+ vboxUsbRtIdcSubmit(VBOXUSBIDC_INTERNAL_IOCTL_GET_VERSION, &Version);
+ if (NT_SUCCESS(Status))
+ {
+ if (Version.u32Major == VBOXUSBIDC_VERSION_MAJOR
+ && Version.u32Minor >= VBOXUSBIDC_VERSION_MINOR)
+ return STATUS_SUCCESS;
+ AssertFailed();
+ }
+ else
+ {
+ AssertFailed();
+ }
+
+ /* this will as well dereference the dev obj */
+ ObDereferenceObject(g_VBoxUsbGlobals.RtIdc.pFile);
+ }
+ else
+ {
+ AssertFailed();
+ }
+
+ memset(&g_VBoxUsbGlobals.RtIdc, 0, sizeof (g_VBoxUsbGlobals.RtIdc));
+ return Status;
+}
+
+static VOID vboxUsbRtIdcTerm()
+{
+ Assert(g_VBoxUsbGlobals.RtIdc.pFile);
+ Assert(g_VBoxUsbGlobals.RtIdc.pDevice);
+ ObDereferenceObject(g_VBoxUsbGlobals.RtIdc.pFile);
+ memset(&g_VBoxUsbGlobals.RtIdc, 0, sizeof (g_VBoxUsbGlobals.RtIdc));
+}
+
+static NTSTATUS vboxUsbRtIdcReportDevStart(PDEVICE_OBJECT pPDO, HVBOXUSBIDCDEV *phDev)
+{
+ VBOXUSBIDC_PROXY_STARTUP Start;
+ Start.u.pPDO = pPDO;
+
+ *phDev = NULL;
+
+ NTSTATUS Status = vboxUsbRtIdcSubmit(VBOXUSBIDC_INTERNAL_IOCTL_PROXY_STARTUP, &Start);
+ Assert(Status == STATUS_SUCCESS);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ *phDev = Start.u.hDev;
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS vboxUsbRtIdcReportDevStop(HVBOXUSBIDCDEV hDev)
+{
+ VBOXUSBIDC_PROXY_TEARDOWN Stop;
+ Stop.hDev = hDev;
+
+ NTSTATUS Status = vboxUsbRtIdcSubmit(VBOXUSBIDC_INTERNAL_IOCTL_PROXY_TEARDOWN, &Stop);
+ Assert(Status == STATUS_SUCCESS);
+ return Status;
+}
+
+
+DECLHIDDEN(NTSTATUS) vboxUsbRtGlobalsInit()
+{
+ return vboxUsbRtIdcInit();
+}
+
+DECLHIDDEN(VOID) vboxUsbRtGlobalsTerm()
+{
+ vboxUsbRtIdcTerm();
+}
+
+
+DECLHIDDEN(NTSTATUS) vboxUsbRtInit(PVBOXUSBDEV_EXT pDevExt)
+{
+ RtlZeroMemory(&pDevExt->Rt, sizeof (pDevExt->Rt));
+ NTSTATUS Status = IoRegisterDeviceInterface(pDevExt->pPDO, &GUID_CLASS_VBOXUSB,
+ NULL, /* IN PUNICODE_STRING ReferenceString OPTIONAL */
+ &pDevExt->Rt.IfName);
+ Assert(Status == STATUS_SUCCESS);
+ if (NT_SUCCESS(Status))
+ {
+ Status = vboxUsbRtIdcReportDevStart(pDevExt->pPDO, &pDevExt->Rt.hMonDev);
+ Assert(Status == STATUS_SUCCESS);
+ if (NT_SUCCESS(Status))
+ {
+ Assert(pDevExt->Rt.hMonDev);
+ return STATUS_SUCCESS;
+ }
+
+ NTSTATUS tmpStatus = IoSetDeviceInterfaceState(&pDevExt->Rt.IfName, FALSE);
+ Assert(tmpStatus == STATUS_SUCCESS);
+ if (NT_SUCCESS(tmpStatus))
+ {
+ RtlFreeUnicodeString(&pDevExt->Rt.IfName);
+ }
+ }
+ return Status;
+}
+
+/**
+ * Free cached USB device/configuration descriptors
+ *
+ * @param pDevExt USB DevExt pointer
+ */
+static void vboxUsbRtFreeCachedDescriptors(PVBOXUSBDEV_EXT pDevExt)
+{
+ if (pDevExt->Rt.devdescr)
+ {
+ vboxUsbMemFree(pDevExt->Rt.devdescr);
+ pDevExt->Rt.devdescr = NULL;
+ }
+ for (ULONG i = 0; i < VBOXUSBRT_MAX_CFGS; ++i)
+ {
+ if (pDevExt->Rt.cfgdescr[i])
+ {
+ vboxUsbMemFree(pDevExt->Rt.cfgdescr[i]);
+ pDevExt->Rt.cfgdescr[i] = NULL;
+ }
+ }
+}
+
+/**
+ * Free per-device interface info
+ *
+ * @param pDevExt USB DevExt pointer
+ * @param fAbortPipes If true, also abort any open pipes
+ */
+static void vboxUsbRtFreeInterfaces(PVBOXUSBDEV_EXT pDevExt, BOOLEAN fAbortPipes)
+{
+ unsigned i;
+ unsigned j;
+
+ /*
+ * Free old interface info
+ */
+ if (pDevExt->Rt.pVBIfaceInfo)
+ {
+ for (i=0;i<pDevExt->Rt.uNumInterfaces;i++)
+ {
+ if (pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo)
+ {
+ if (fAbortPipes)
+ {
+ for(j=0; j<pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->NumberOfPipes; j++)
+ {
+ Log(("Aborting Pipe %d handle %x address %x\n", j,
+ pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].PipeHandle,
+ pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].EndpointAddress));
+ VBoxUsbToolPipeClear(pDevExt->pLowerDO, pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].PipeHandle, FALSE);
+ }
+ }
+ vboxUsbMemFree(pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo);
+ }
+ pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo = NULL;
+ if (pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo)
+ vboxUsbMemFree(pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo);
+ pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo = NULL;
+ }
+ vboxUsbMemFree(pDevExt->Rt.pVBIfaceInfo);
+ pDevExt->Rt.pVBIfaceInfo = NULL;
+ }
+}
+
+DECLHIDDEN(VOID) vboxUsbRtClear(PVBOXUSBDEV_EXT pDevExt)
+{
+ vboxUsbRtFreeCachedDescriptors(pDevExt);
+ vboxUsbRtFreeInterfaces(pDevExt, FALSE);
+}
+
+DECLHIDDEN(NTSTATUS) vboxUsbRtRm(PVBOXUSBDEV_EXT pDevExt)
+{
+ if (!pDevExt->Rt.IfName.Buffer)
+ return STATUS_SUCCESS;
+
+ NTSTATUS Status = vboxUsbRtIdcReportDevStop(pDevExt->Rt.hMonDev);
+ Assert(Status == STATUS_SUCCESS);
+ Status = IoSetDeviceInterfaceState(&pDevExt->Rt.IfName, FALSE);
+ Assert(Status == STATUS_SUCCESS);
+ if (NT_SUCCESS(Status))
+ {
+ RtlFreeUnicodeString(&pDevExt->Rt.IfName);
+ pDevExt->Rt.IfName.Buffer = NULL;
+ }
+ return Status;
+}
+
+DECLHIDDEN(NTSTATUS) vboxUsbRtStart(PVBOXUSBDEV_EXT pDevExt)
+{
+ NTSTATUS Status = IoSetDeviceInterfaceState(&pDevExt->Rt.IfName, TRUE);
+ Assert(Status == STATUS_SUCCESS);
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtCacheDescriptors(PVBOXUSBDEV_EXT pDevExt)
+{
+ NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
+// uint32_t uTotalLength;
+// unsigned i;
+
+ /* Read device descriptor */
+ Assert(!pDevExt->Rt.devdescr);
+ pDevExt->Rt.devdescr = (PUSB_DEVICE_DESCRIPTOR)vboxUsbMemAlloc(sizeof (USB_DEVICE_DESCRIPTOR));
+ if (pDevExt->Rt.devdescr)
+ {
+ memset(pDevExt->Rt.devdescr, 0, sizeof (USB_DEVICE_DESCRIPTOR));
+ Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDevExt->Rt.devdescr, sizeof (USB_DEVICE_DESCRIPTOR), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, RT_INDEFINITE_WAIT);
+ if (NT_SUCCESS(Status))
+ {
+ Assert(pDevExt->Rt.devdescr->bNumConfigurations > 0);
+ PUSB_CONFIGURATION_DESCRIPTOR pDr = (PUSB_CONFIGURATION_DESCRIPTOR)vboxUsbMemAlloc(sizeof (USB_CONFIGURATION_DESCRIPTOR));
+ Assert(pDr);
+ if (pDr)
+ {
+ UCHAR i = 0;
+ for (; i < pDevExt->Rt.devdescr->bNumConfigurations; ++i)
+ {
+ Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDr, sizeof (USB_CONFIGURATION_DESCRIPTOR), USB_CONFIGURATION_DESCRIPTOR_TYPE, i, 0, RT_INDEFINITE_WAIT);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
+
+ USHORT uTotalLength = pDr->wTotalLength;
+ pDevExt->Rt.cfgdescr[i] = (PUSB_CONFIGURATION_DESCRIPTOR)vboxUsbMemAlloc(uTotalLength);
+ if (!pDevExt->Rt.cfgdescr[i])
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+
+ Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDevExt->Rt.cfgdescr[i], uTotalLength, USB_CONFIGURATION_DESCRIPTOR_TYPE, i, 0, RT_INDEFINITE_WAIT);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
+ }
+
+ vboxUsbMemFree(pDr);
+
+ if (NT_SUCCESS(Status))
+ return Status;
+
+ /* recources will be freed in vboxUsbRtFreeCachedDescriptors below */
+ }
+ }
+
+ vboxUsbRtFreeCachedDescriptors(pDevExt);
+ }
+
+ /* shoud be only on fail here */
+ Assert(!NT_SUCCESS(Status));
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtDispatchClaimDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFObj = pSl->FileObject;
+ PUSBSUP_CLAIMDEV pDev = (PUSBSUP_CLAIMDEV)pIrp->AssociatedIrp.SystemBuffer;
+ ULONG cbOut = 0;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ do
+ {
+ if (!pFObj)
+ {
+ AssertFailed();
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if ( !pDev
+ || pSl->Parameters.DeviceIoControl.InputBufferLength != sizeof (*pDev)
+ || pSl->Parameters.DeviceIoControl.OutputBufferLength != sizeof (*pDev))
+ {
+ AssertFailed();
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (!vboxUsbRtCtxSetOwner(pDevExt, pFObj))
+ {
+ AssertFailed();
+ pDev->fClaimed = false;
+ cbOut = sizeof (*pDev);
+ break;
+ }
+
+ vboxUsbRtFreeCachedDescriptors(pDevExt);
+ Status = vboxUsbRtCacheDescriptors(pDevExt);
+ if (NT_SUCCESS(Status))
+ {
+ pDev->fClaimed = true;
+ cbOut = sizeof (*pDev);
+ }
+ } while (0);
+
+ Assert(Status != STATUS_PENDING);
+ VBoxDrvToolIoComplete(pIrp, Status, cbOut);
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtDispatchReleaseDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFObj = pSl->FileObject;
+ NTSTATUS Status= STATUS_SUCCESS;
+
+ if (vboxUsbRtCtxIsOwner(pDevExt, pFObj))
+ {
+ vboxUsbRtFreeCachedDescriptors(pDevExt);
+ bool bRc = vboxUsbRtCtxReleaseOwner(pDevExt, pFObj);
+ Assert(bRc);
+ }
+ else
+ {
+ AssertFailed();
+ Status = STATUS_ACCESS_DENIED;
+ }
+
+ VBoxDrvToolIoComplete(pIrp, STATUS_SUCCESS, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS vboxUsbRtGetDeviceDescription(PVBOXUSBDEV_EXT pDevExt)
+{
+ NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
+ PUSB_DEVICE_DESCRIPTOR pDr = (PUSB_DEVICE_DESCRIPTOR)vboxUsbMemAllocZ(sizeof (USB_DEVICE_DESCRIPTOR));
+ if (pDr)
+ {
+ Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDr, sizeof(*pDr), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, RT_INDEFINITE_WAIT);
+ if (NT_SUCCESS(Status))
+ {
+ pDevExt->Rt.idVendor = pDr->idVendor;
+ pDevExt->Rt.idProduct = pDr->idProduct;
+ pDevExt->Rt.bcdDevice = pDr->bcdDevice;
+ pDevExt->Rt.szSerial[0] = 0;
+
+ if (pDr->iSerialNumber
+#ifdef DEBUG
+ || pDr->iProduct || pDr->iManufacturer
+#endif
+ )
+ {
+ int langId;
+ Status = VBoxUsbToolGetLangID(pDevExt->pLowerDO, &langId, RT_INDEFINITE_WAIT);
+ if (NT_SUCCESS(Status))
+ {
+ Status = VBoxUsbToolGetStringDescriptorA(pDevExt->pLowerDO, pDevExt->Rt.szSerial, sizeof (pDevExt->Rt.szSerial), pDr->iSerialNumber, langId, RT_INDEFINITE_WAIT);
+ }
+ else
+ {
+ Status = STATUS_SUCCESS;
+ }
+ }
+ }
+ vboxUsbMemFree(pDr);
+ }
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtDispatchGetDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PUSBSUP_GETDEV pDev = (PUSBSUP_GETDEV)pIrp->AssociatedIrp.SystemBuffer;
+ NTSTATUS Status = STATUS_SUCCESS;
+ ULONG cbOut = 0;
+
+ /* don't check for owner since this request is allowed for non-owners as well */
+
+ if (pDev && pSl->Parameters.DeviceIoControl.InputBufferLength == sizeof (*pDev)
+ && pSl->Parameters.DeviceIoControl.OutputBufferLength == sizeof (*pDev))
+ {
+ Status = VBoxUsbToolGetDeviceSpeed(pDevExt->pLowerDO, &pDevExt->Rt.fIsHighSpeed);
+ if (NT_SUCCESS(Status))
+ {
+ pDev->hDevice = pDevExt->Rt.hMonDev;
+ pDev->fAttached = true;
+ pDev->fHiSpeed = pDevExt->Rt.fIsHighSpeed;
+ cbOut = sizeof (*pDev);
+ }
+ }
+ else
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+ Assert(Status != STATUS_PENDING);
+ VBoxDrvToolIoComplete(pIrp, Status, cbOut);
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtDispatchUsbReset(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFObj = pSl->FileObject;
+ PUSBSUP_GETDEV pDev = (PUSBSUP_GETDEV)pIrp->AssociatedIrp.SystemBuffer;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ do
+ {
+ if (!pFObj)
+ {
+ AssertFailed();
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (!vboxUsbRtCtxIsOwner(pDevExt, pFObj))
+ {
+ AssertFailed();
+ Status = STATUS_ACCESS_DENIED;
+ break;
+ }
+
+ if (pIrp->AssociatedIrp.SystemBuffer
+ || pSl->Parameters.DeviceIoControl.InputBufferLength
+ || pSl->Parameters.DeviceIoControl.OutputBufferLength)
+ {
+ AssertFailed();
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ Status = VBoxUsbToolIoInternalCtlSendSync(pDevExt->pLowerDO, IOCTL_INTERNAL_USB_RESET_PORT, NULL, NULL);
+ Assert(NT_SUCCESS(Status));
+ } while (0);
+
+ Assert(Status != STATUS_PENDING);
+ VBoxDrvToolIoComplete(pIrp, Status, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static PUSB_CONFIGURATION_DESCRIPTOR vboxUsbRtFindConfigDesc(PVBOXUSBDEV_EXT pDevExt, uint8_t uConfiguration)
+{
+ PUSB_CONFIGURATION_DESCRIPTOR pCfgDr = NULL;
+
+ for (ULONG i = 0; i < VBOXUSBRT_MAX_CFGS; ++i)
+ {
+ if (pDevExt->Rt.cfgdescr[i])
+ {
+ if (pDevExt->Rt.cfgdescr[i]->bConfigurationValue == uConfiguration)
+ {
+ pCfgDr = pDevExt->Rt.cfgdescr[i];
+ break;
+ }
+ }
+ }
+
+ return pCfgDr;
+}
+
+static NTSTATUS vboxUsbRtSetConfig(PVBOXUSBDEV_EXT pDevExt, uint8_t uConfiguration)
+{
+ PURB pUrb = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+ uint32_t i;
+
+ if (!uConfiguration)
+ {
+ pUrb = VBoxUsbToolUrbAllocZ(URB_FUNCTION_SELECT_CONFIGURATION, sizeof (struct _URB_SELECT_CONFIGURATION));
+ if(!pUrb)
+ {
+ AssertMsgFailed((__FUNCTION__": VBoxUsbToolUrbAlloc failed\n"));
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ vboxUsbRtFreeInterfaces(pDevExt, TRUE);
+
+ pUrb->UrbSelectConfiguration.ConfigurationDescriptor = NULL;
+
+ Status = VBoxUsbToolUrbPost(pDevExt->pLowerDO, pUrb, RT_INDEFINITE_WAIT);
+ if(NT_SUCCESS(Status) && USBD_SUCCESS(pUrb->UrbHeader.Status))
+ {
+ pDevExt->Rt.hConfiguration = pUrb->UrbSelectConfiguration.ConfigurationHandle;
+ pDevExt->Rt.uConfigValue = uConfiguration;
+ }
+ else
+ {
+ AssertMsgFailed((__FUNCTION__": VBoxUsbToolUrbPost failed Status (0x%x), usb Status (0x%x)\n", Status, pUrb->UrbHeader.Status));
+ }
+
+ VBoxUsbToolUrbFree(pUrb);
+
+ return Status;
+ }
+
+ PUSB_CONFIGURATION_DESCRIPTOR pCfgDr = vboxUsbRtFindConfigDesc(pDevExt, uConfiguration);
+ if (!pCfgDr)
+ {
+ AssertMsgFailed((__FUNCTION__": VBoxUSBFindConfigDesc did not find cfg (%d)\n", uConfiguration));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ PUSBD_INTERFACE_LIST_ENTRY pIfLe = (PUSBD_INTERFACE_LIST_ENTRY)vboxUsbMemAllocZ((pCfgDr->bNumInterfaces + 1) * sizeof(USBD_INTERFACE_LIST_ENTRY));
+ if (!pIfLe)
+ {
+ AssertMsgFailed((__FUNCTION__": vboxUsbMemAllocZ for pIfLe failed\n"));
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ for (i = 0; i < pCfgDr->bNumInterfaces; i++)
+ {
+ pIfLe[i].InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(pCfgDr, pCfgDr, i, 0, -1, -1, -1);
+ if (!pIfLe[i].InterfaceDescriptor)
+ {
+ AssertMsgFailed((__FUNCTION__": interface %d not found\n", i));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ pUrb = USBD_CreateConfigurationRequestEx(pCfgDr, pIfLe);
+ if (pUrb)
+ {
+ Status = VBoxUsbToolUrbPost(pDevExt->pLowerDO, pUrb, RT_INDEFINITE_WAIT);
+ if (NT_SUCCESS(Status) && USBD_SUCCESS(pUrb->UrbHeader.Status))
+ {
+ vboxUsbRtFreeInterfaces(pDevExt, FALSE);
+
+ pDevExt->Rt.hConfiguration = pUrb->UrbSelectConfiguration.ConfigurationHandle;
+ pDevExt->Rt.uConfigValue = uConfiguration;
+ pDevExt->Rt.uNumInterfaces = pCfgDr->bNumInterfaces;
+
+ pDevExt->Rt.pVBIfaceInfo = (VBOXUSB_IFACE_INFO*)vboxUsbMemAllocZ(pDevExt->Rt.uNumInterfaces * sizeof (VBOXUSB_IFACE_INFO));
+ if (pDevExt->Rt.pVBIfaceInfo)
+ {
+ Assert(NT_SUCCESS(Status));
+ for (i = 0; i < pDevExt->Rt.uNumInterfaces; i++)
+ {
+ uint32_t uTotalIfaceInfoLength = sizeof (struct _URB_SELECT_INTERFACE) + ((pIfLe[i].Interface->NumberOfPipes > 0) ? (pIfLe[i].Interface->NumberOfPipes - 1) : 0) * sizeof(USBD_PIPE_INFORMATION);
+ pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo = (PUSBD_INTERFACE_INFORMATION)vboxUsbMemAlloc(uTotalIfaceInfoLength);
+ if (!pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo)
+ {
+ AssertMsgFailed((__FUNCTION__": vboxUsbMemAlloc failed\n"));
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+
+ if (pIfLe[i].Interface->NumberOfPipes > 0)
+ {
+ pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo = (VBOXUSB_PIPE_INFO *)vboxUsbMemAlloc(pIfLe[i].Interface->NumberOfPipes * sizeof(VBOXUSB_PIPE_INFO));
+ if (!pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo)
+ {
+ AssertMsgFailed((__FUNCTION__": vboxUsbMemAlloc failed\n"));
+ Status = STATUS_NO_MEMORY;
+ break;
+ }
+ }
+ else
+ {
+ pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo = NULL;
+ }
+
+ *pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo = *pIfLe[i].Interface;
+
+ for (ULONG j = 0; j < pIfLe[i].Interface->NumberOfPipes; j++)
+ {
+ pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j] = pIfLe[i].Interface->Pipes[j];
+ pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo[j].EndpointAddress = pIfLe[i].Interface->Pipes[j].EndpointAddress;
+ pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo[j].NextScheduledFrame = 0;
+ }
+ }
+
+// if (NT_SUCCESS(Status))
+// {
+//
+// }
+ }
+ else
+ {
+ AssertMsgFailed((__FUNCTION__": vboxUsbMemAllocZ failed\n"));
+ Status = STATUS_NO_MEMORY;
+ }
+ }
+ else
+ {
+ AssertMsgFailed((__FUNCTION__": VBoxUsbToolUrbPost failed Status (0x%x), usb Status (0x%x)\n", Status, pUrb->UrbHeader.Status));
+ }
+ ExFreePool(pUrb);
+ }
+ else
+ {
+ AssertMsgFailed((__FUNCTION__": USBD_CreateConfigurationRequestEx failed\n"));
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ vboxUsbMemFree(pIfLe);
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtDispatchUsbSetConfig(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFObj = pSl->FileObject;
+ PUSBSUP_SET_CONFIG pCfg = (PUSBSUP_SET_CONFIG)pIrp->AssociatedIrp.SystemBuffer;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ do
+ {
+ if (!pFObj)
+ {
+ AssertFailed();
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (!vboxUsbRtCtxIsOwner(pDevExt, pFObj))
+ {
+ AssertFailed();
+ Status = STATUS_ACCESS_DENIED;
+ break;
+ }
+
+ if ( !pCfg
+ || pSl->Parameters.DeviceIoControl.InputBufferLength != sizeof (*pCfg)
+ || pSl->Parameters.DeviceIoControl.OutputBufferLength != 0)
+ {
+ AssertMsgFailed((__FUNCTION__": STATUS_INVALID_PARAMETER\n"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ Status = vboxUsbRtSetConfig(pDevExt, pCfg->bConfigurationValue);
+ } while (0);
+
+ Assert(Status != STATUS_PENDING);
+ VBoxDrvToolIoComplete(pIrp, Status, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtSetInterface(PVBOXUSBDEV_EXT pDevExt, uint32_t InterfaceNumber, int AlternateSetting)
+{
+ if (!pDevExt->Rt.uConfigValue)
+ {
+ AssertMsgFailed((__FUNCTION__": Can't select an interface without an active configuration\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (InterfaceNumber >= pDevExt->Rt.uNumInterfaces)
+ {
+ AssertMsgFailed((__FUNCTION__": InterfaceNumber %d too high!!\n", InterfaceNumber));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ PUSB_CONFIGURATION_DESCRIPTOR pCfgDr = vboxUsbRtFindConfigDesc(pDevExt, pDevExt->Rt.uConfigValue);
+ if (!pCfgDr)
+ {
+ AssertMsgFailed((__FUNCTION__": configuration %d not found!!\n", pDevExt->Rt.uConfigValue));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ PUSB_INTERFACE_DESCRIPTOR pIfDr = USBD_ParseConfigurationDescriptorEx(pCfgDr, pCfgDr, InterfaceNumber, AlternateSetting, -1, -1, -1);
+ if (!pIfDr)
+ {
+ AssertMsgFailed((__FUNCTION__": invalid interface %d or alternate setting %d\n", InterfaceNumber, AlternateSetting));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ USHORT uUrbSize = GET_SELECT_INTERFACE_REQUEST_SIZE(pIfDr->bNumEndpoints);
+ ULONG uTotalIfaceInfoLength = GET_USBD_INTERFACE_SIZE(pIfDr->bNumEndpoints);
+ NTSTATUS Status = STATUS_SUCCESS;
+ PURB pUrb = VBoxUsbToolUrbAllocZ(0, uUrbSize);
+ if (!pUrb)
+ {
+ AssertMsgFailed((__FUNCTION__": VBoxUsbToolUrbAlloc failed\n"));
+ return STATUS_NO_MEMORY;
+ }
+
+ /*
+ * Free old interface and pipe info, allocate new again
+ */
+ if (pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo)
+ {
+ /* Clear pipes associated with the interface, else Windows may hang. */
+ for(ULONG i = 0; i < pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo->NumberOfPipes; i++)
+ {
+ VBoxUsbToolPipeClear(pDevExt->pLowerDO, pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo->Pipes[i].PipeHandle, FALSE);
+ }
+ vboxUsbMemFree(pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo);
+ }
+
+ if (pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo)
+ {
+ vboxUsbMemFree(pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo);
+ }
+
+ pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo = (PUSBD_INTERFACE_INFORMATION)vboxUsbMemAlloc(uTotalIfaceInfoLength);
+ if (pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo)
+ {
+ if (pIfDr->bNumEndpoints > 0)
+ {
+ pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo = (VBOXUSB_PIPE_INFO*)vboxUsbMemAlloc(pIfDr->bNumEndpoints * sizeof(VBOXUSB_PIPE_INFO));
+ if (!pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo)
+ {
+ AssertMsgFailed(("VBoxUSBSetInterface: ExAllocatePool failed!\n"));
+ Status = STATUS_NO_MEMORY;
+ }
+ }
+ else
+ {
+ pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo = NULL;
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ UsbBuildSelectInterfaceRequest(pUrb, uUrbSize, pDevExt->Rt.hConfiguration, InterfaceNumber, AlternateSetting);
+ pUrb->UrbSelectInterface.Interface.Length = GET_USBD_INTERFACE_SIZE(pIfDr->bNumEndpoints);
+
+ Status = VBoxUsbToolUrbPost(pDevExt->pLowerDO, pUrb, RT_INDEFINITE_WAIT);
+ if (NT_SUCCESS(Status) && USBD_SUCCESS(pUrb->UrbHeader.Status))
+ {
+ USBD_INTERFACE_INFORMATION *pIfInfo = &pUrb->UrbSelectInterface.Interface;
+ memcpy(pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo, pIfInfo, GET_USBD_INTERFACE_SIZE(pIfDr->bNumEndpoints));
+
+ Assert(pIfInfo->NumberOfPipes == pIfDr->bNumEndpoints);
+ for(ULONG i = 0; i < pIfInfo->NumberOfPipes; i++)
+ {
+ pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo->Pipes[i] = pIfInfo->Pipes[i];
+ pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo[i].EndpointAddress = pIfInfo->Pipes[i].EndpointAddress;
+ pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo[i].NextScheduledFrame = 0;
+ }
+ }
+ else
+ {
+ AssertMsgFailed((__FUNCTION__": VBoxUsbToolUrbPost failed Status (0x%x) usb Status (0x%x)\n", Status, pUrb->UrbHeader.Status));
+ }
+ }
+
+ }
+ else
+ {
+ AssertMsgFailed(("VBoxUSBSetInterface: ExAllocatePool failed!\n"));
+ Status = STATUS_NO_MEMORY;
+ }
+
+ VBoxUsbToolUrbFree(pUrb);
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtDispatchUsbSelectInterface(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFObj = pSl->FileObject;
+ PUSBSUP_SELECT_INTERFACE pIf = (PUSBSUP_SELECT_INTERFACE)pIrp->AssociatedIrp.SystemBuffer;
+ NTSTATUS Status;
+
+ do
+ {
+ if (!pFObj)
+ {
+ AssertFailed();
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (!vboxUsbRtCtxIsOwner(pDevExt, pFObj))
+ {
+ AssertFailed();
+ Status = STATUS_ACCESS_DENIED;
+ break;
+ }
+
+ if ( !pIf
+ || pSl->Parameters.DeviceIoControl.InputBufferLength != sizeof (*pIf)
+ || pSl->Parameters.DeviceIoControl.OutputBufferLength != 0)
+ {
+ AssertMsgFailed((__FUNCTION__": STATUS_INVALID_PARAMETER\n"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ Status = vboxUsbRtSetInterface(pDevExt, pIf->bInterfaceNumber, pIf->bAlternateSetting);
+ } while (0);
+
+ Assert(Status != STATUS_PENDING);
+ VBoxDrvToolIoComplete(pIrp, Status, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static HANDLE vboxUsbRtGetPipeHandle(PVBOXUSBDEV_EXT pDevExt, uint32_t EndPointAddress)
+{
+ for (ULONG i = 0; i < pDevExt->Rt.uNumInterfaces; i++)
+ {
+ for (ULONG j = 0; j < pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->NumberOfPipes; j++)
+ {
+ /* Note that bit 7 determines pipe direction, but is still significant
+ * because endpoints may be numbered like 0x01, 0x81, 0x02, 0x82 etc.
+ */
+ if (pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].EndpointAddress == EndPointAddress)
+ return pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].PipeHandle;
+ }
+ }
+ return 0;
+}
+
+static VBOXUSB_PIPE_INFO* vboxUsbRtGetPipeInfo(PVBOXUSBDEV_EXT pDevExt, uint32_t EndPointAddress)
+{
+ for (ULONG i = 0; i < pDevExt->Rt.uNumInterfaces; i++)
+ {
+ for (ULONG j = 0; j < pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->NumberOfPipes; j++)
+ {
+ if (pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo[j].EndpointAddress == EndPointAddress)
+ return &pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo[j];
+ }
+ }
+ return NULL;
+}
+
+
+
+static NTSTATUS vboxUsbRtClearEndpoint(PVBOXUSBDEV_EXT pDevExt, uint32_t EndPointAddress, bool fReset)
+{
+ NTSTATUS Status = VBoxUsbToolPipeClear(pDevExt->pLowerDO, vboxUsbRtGetPipeHandle(pDevExt, EndPointAddress), fReset);
+ if (!NT_SUCCESS(Status))
+ {
+ AssertMsgFailed((__FUNCTION__": VBoxUsbToolPipeClear failed Status (0x%x)\n", Status));
+ }
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtDispatchUsbClearEndpoint(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFObj = pSl->FileObject;
+ PUSBSUP_CLEAR_ENDPOINT pCe = (PUSBSUP_CLEAR_ENDPOINT)pIrp->AssociatedIrp.SystemBuffer;
+ NTSTATUS Status;
+
+ do
+ {
+ if (!pFObj)
+ {
+ AssertFailed();
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (!vboxUsbRtCtxIsOwner(pDevExt, pFObj))
+ {
+ AssertFailed();
+ Status = STATUS_ACCESS_DENIED;
+ break;
+ }
+
+ if ( !pCe
+ || pSl->Parameters.DeviceIoControl.InputBufferLength != sizeof (*pCe)
+ || pSl->Parameters.DeviceIoControl.OutputBufferLength != 0)
+ {
+ AssertMsgFailed((__FUNCTION__": STATUS_INVALID_PARAMETER\n"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ Status = vboxUsbRtClearEndpoint(pDevExt, pCe->bEndpoint, TRUE);
+ } while (0);
+
+ Assert(Status != STATUS_PENDING);
+ VBoxDrvToolIoComplete(pIrp, Status, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtDispatchUsbAbortEndpoint(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFObj = pSl->FileObject;
+ PUSBSUP_CLEAR_ENDPOINT pCe = (PUSBSUP_CLEAR_ENDPOINT)pIrp->AssociatedIrp.SystemBuffer;
+ NTSTATUS Status;
+
+ do
+ {
+ if (!pFObj)
+ {
+ AssertFailed();
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (!vboxUsbRtCtxIsOwner(pDevExt, pFObj))
+ {
+ AssertFailed();
+ Status = STATUS_ACCESS_DENIED;
+ break;
+ }
+
+ if ( !pCe
+ || pSl->Parameters.DeviceIoControl.InputBufferLength != sizeof (*pCe)
+ || pSl->Parameters.DeviceIoControl.OutputBufferLength != 0)
+ {
+ AssertMsgFailed((__FUNCTION__": STATUS_INVALID_PARAMETER\n"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ Status = vboxUsbRtClearEndpoint(pDevExt, pCe->bEndpoint, FALSE);
+ } while (0);
+
+ Assert(Status != STATUS_PENDING);
+ VBoxDrvToolIoComplete(pIrp, Status, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtUrbSendCompletion(PDEVICE_OBJECT pDevObj, IRP *pIrp, void *pvContext)
+{
+ if (!pvContext)
+ {
+ AssertMsgFailed((__FUNCTION__": context is NULL\n"));
+ pIrp->IoStatus.Information = 0;
+ return STATUS_CONTINUE_COMPLETION;
+ }
+
+ PVBOXUSB_URB_CONTEXT pContext = (PVBOXUSB_URB_CONTEXT)pvContext;
+
+ if (pContext->ulMagic != VBOXUSB_MAGIC)
+ {
+ AssertMsgFailed((__FUNCTION__": Invalid context magic\n"));
+ pIrp->IoStatus.Information = 0;
+ return STATUS_CONTINUE_COMPLETION;
+ }
+
+ PURB pUrb = pContext->pUrb;
+ PMDL pMdlBuf = pContext->pMdlBuf;
+ PUSBSUP_URB pUrbInfo = (PUSBSUP_URB)pContext->pOut;
+ PVBOXUSBDEV_EXT pDevExt = pContext->pDevExt;
+
+ if (!pUrb || !pMdlBuf || !pUrbInfo | !pDevExt)
+ {
+ AssertMsgFailed((__FUNCTION__": Invalid args\n"));
+ if (pDevExt)
+ vboxUsbDdiStateRelease(pDevExt);
+ pIrp->IoStatus.Information = 0;
+ return STATUS_CONTINUE_COMPLETION;
+ }
+
+ NTSTATUS Status = pIrp->IoStatus.Status;
+ if (Status == STATUS_SUCCESS)
+ {
+ switch(pUrb->UrbHeader.Status)
+ {
+ case USBD_STATUS_CRC:
+ pUrbInfo->error = USBSUP_XFER_CRC;
+ break;
+ case USBD_STATUS_SUCCESS:
+ pUrbInfo->error = USBSUP_XFER_OK;
+ break;
+ case USBD_STATUS_STALL_PID:
+ pUrbInfo->error = USBSUP_XFER_STALL;
+ break;
+ case USBD_STATUS_INVALID_URB_FUNCTION:
+ case USBD_STATUS_INVALID_PARAMETER:
+ AssertMsgFailed((__FUNCTION__": sw error, urb Status (0x%x)\n", pUrb->UrbHeader.Status));
+ case USBD_STATUS_DEV_NOT_RESPONDING:
+ default:
+ pUrbInfo->error = USBSUP_XFER_DNR;
+ break;
+ }
+
+ switch(pContext->ulTransferType)
+ {
+ case USBSUP_TRANSFER_TYPE_CTRL:
+ case USBSUP_TRANSFER_TYPE_MSG:
+ pUrbInfo->len = pUrb->UrbControlTransfer.TransferBufferLength;
+ if (pContext->ulTransferType == USBSUP_TRANSFER_TYPE_MSG)
+ {
+ /* QUSB_TRANSFER_TYPE_MSG is a control transfer, but it is special
+ * the first 8 bytes of the buffer is the setup packet so the real
+ * data length is therefore urb->len - 8
+ */
+ pUrbInfo->len += sizeof (pUrb->UrbControlTransfer.SetupPacket);
+ }
+ break;
+ case USBSUP_TRANSFER_TYPE_ISOC:
+ pUrbInfo->len = pUrb->UrbIsochronousTransfer.TransferBufferLength;
+ break;
+ case USBSUP_TRANSFER_TYPE_BULK:
+ case USBSUP_TRANSFER_TYPE_INTR:
+ if (pUrbInfo->dir == USBSUP_DIRECTION_IN && pUrbInfo->error == USBSUP_XFER_OK
+ && !(pUrbInfo->flags & USBSUP_FLAG_SHORT_OK)
+ && pUrbInfo->len > pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength
+ )
+ {
+ /* If we don't use the USBD_SHORT_TRANSFER_OK flag, the returned buffer lengths are
+ * wrong for short transfers (always a multiple of max packet size?). So we just figure
+ * out if this was a data underrun on our own.
+ */
+ pUrbInfo->error = USBSUP_XFER_UNDERRUN;
+ }
+ pUrbInfo->len = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ pUrbInfo->len = 0;
+
+ Log((__FUNCTION__": URB failed Status (0x%x) urb Status (0x%x)\n", Status, pUrb->UrbHeader.Status));
+#ifdef DEBUG
+ switch(pContext->ulTransferType)
+ {
+ case USBSUP_TRANSFER_TYPE_CTRL:
+ case USBSUP_TRANSFER_TYPE_MSG:
+ LogRel(("Ctrl/Msg length=%d\n", pUrb->UrbControlTransfer.TransferBufferLength));
+ break;
+ case USBSUP_TRANSFER_TYPE_ISOC:
+ LogRel(("ISOC length=%d\n", pUrb->UrbIsochronousTransfer.TransferBufferLength));
+ break;
+ case USBSUP_TRANSFER_TYPE_BULK:
+ case USBSUP_TRANSFER_TYPE_INTR:
+ LogRel(("BULK/INTR length=%d\n", pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength));
+ break;
+ }
+#endif
+ switch(pUrb->UrbHeader.Status)
+ {
+ case USBD_STATUS_CRC:
+ pUrbInfo->error = USBSUP_XFER_CRC;
+ Status = STATUS_SUCCESS;
+ break;
+ case USBD_STATUS_STALL_PID:
+ pUrbInfo->error = USBSUP_XFER_STALL;
+ Status = STATUS_SUCCESS;
+ break;
+ case USBD_STATUS_DEV_NOT_RESPONDING:
+ pUrbInfo->error = USBSUP_XFER_DNR;
+ Status = STATUS_SUCCESS;
+ break;
+ case ((USBD_STATUS)0xC0010000L): // USBD_STATUS_CANCELED - too bad usbdi.h and usb.h aren't consistent!
+ // TODO: What the heck are we really supposed to do here?
+ pUrbInfo->error = USBSUP_XFER_STALL;
+ Status = STATUS_SUCCESS;
+ break;
+ case USBD_STATUS_BAD_START_FRAME: // This one really shouldn't happen
+ case USBD_STATUS_ISOCH_REQUEST_FAILED:
+ pUrbInfo->error = USBSUP_XFER_NAC;
+ Status = STATUS_SUCCESS;
+ break;
+ default:
+ AssertMsgFailed((__FUNCTION__": err Status (0x%x) (0x%x)\n", Status, pUrb->UrbHeader.Status));
+ pUrbInfo->error = USBSUP_XFER_DNR;
+ Status = STATUS_SUCCESS;
+ break;
+ }
+ }
+ // For isochronous transfers, always update the individual packets
+ if (pContext->ulTransferType == USBSUP_TRANSFER_TYPE_ISOC)
+ {
+ Assert(pUrbInfo->numIsoPkts == pUrb->UrbIsochronousTransfer.NumberOfPackets);
+ for (ULONG i = 0; i < pUrbInfo->numIsoPkts; ++i)
+ {
+ Assert(pUrbInfo->aIsoPkts[i].off == pUrb->UrbIsochronousTransfer.IsoPacket[i].Offset);
+ pUrbInfo->aIsoPkts[i].cb = (uint16_t)pUrb->UrbIsochronousTransfer.IsoPacket[i].Length;
+ switch (pUrb->UrbIsochronousTransfer.IsoPacket[i].Status)
+ {
+ case USBD_STATUS_SUCCESS:
+ pUrbInfo->aIsoPkts[i].stat = USBSUP_XFER_OK;
+ break;
+ case USBD_STATUS_NOT_ACCESSED:
+ pUrbInfo->aIsoPkts[i].stat = USBSUP_XFER_NAC;
+ break;
+ default:
+ pUrbInfo->aIsoPkts[i].stat = USBSUP_XFER_STALL;
+ break;
+ }
+ }
+ }
+
+ MmUnlockPages(pMdlBuf);
+ IoFreeMdl(pMdlBuf);
+
+ vboxUsbMemFree(pContext);
+
+ vboxUsbDdiStateRelease(pDevExt);
+
+ Assert(pIrp->IoStatus.Status != STATUS_IO_TIMEOUT);
+ pIrp->IoStatus.Information = sizeof(*pUrbInfo);
+ pIrp->IoStatus.Status = Status;
+ return STATUS_CONTINUE_COMPLETION;
+}
+
+static NTSTATUS vboxUsbRtUrbSend(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp, PUSBSUP_URB pUrbInfo)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVBOXUSB_URB_CONTEXT pContext = NULL;
+ PMDL pMdlBuf = NULL;
+ ULONG cbUrb;
+
+ Assert(pUrbInfo);
+ if (pUrbInfo->type == USBSUP_TRANSFER_TYPE_ISOC)
+ {
+ Assert(pUrbInfo->numIsoPkts <= 8);
+ cbUrb = GET_ISO_URB_SIZE(pUrbInfo->numIsoPkts);
+ }
+ else
+ cbUrb = sizeof (URB);
+
+ do
+ {
+ pContext = (PVBOXUSB_URB_CONTEXT)vboxUsbMemAllocZ(cbUrb + sizeof (VBOXUSB_URB_CONTEXT));
+ if (!pContext)
+ {
+ AssertMsgFailed((__FUNCTION__": vboxUsbMemAlloc failed\n"));
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+
+ PURB pUrb = (PURB)(pContext + 1);
+ HANDLE hPipe = NULL;
+ if (pUrbInfo->ep)
+ {
+ hPipe = vboxUsbRtGetPipeHandle(pDevExt, pUrbInfo->ep | ((pUrbInfo->dir == USBSUP_DIRECTION_IN) ? 0x80 : 0x00));
+ if (!hPipe)
+ {
+ AssertMsgFailed((__FUNCTION__": vboxUsbRtGetPipeHandle failed for endpoint (0x%x)\n", pUrbInfo->ep));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ }
+
+ pMdlBuf = IoAllocateMdl(pUrbInfo->buf, (ULONG)pUrbInfo->len, FALSE, FALSE, NULL);
+ if (!pMdlBuf)
+ {
+ AssertMsgFailed((__FUNCTION__": IoAllocateMdl failed for buffer (0x%p) length (%d)\n", pUrbInfo->buf, pUrbInfo->len));
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+
+ __try
+ {
+ MmProbeAndLockPages(pMdlBuf, KernelMode, IoModifyAccess);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = GetExceptionCode();
+ IoFreeMdl(pMdlBuf);
+ pMdlBuf = NULL;
+ AssertMsgFailed((__FUNCTION__": Exception Code (0x%x)\n", Status));
+ break;
+ }
+
+ /* For some reason, passing a MDL in the URB does not work reliably. Notably
+ * the iPhone when used with iTunes fails.
+ */
+ PVOID pBuffer = MmGetSystemAddressForMdlSafe(pMdlBuf, NormalPagePriority);
+ if (!pBuffer)
+ {
+ AssertMsgFailed((__FUNCTION__": MmGetSystemAddressForMdlSafe failed\n"));
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+
+ switch (pUrbInfo->type)
+ {
+ case USBSUP_TRANSFER_TYPE_CTRL:
+ case USBSUP_TRANSFER_TYPE_MSG:
+ {
+ pUrb->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER;
+ pUrb->UrbHeader.Length = sizeof (struct _URB_CONTROL_TRANSFER);
+ pUrb->UrbControlTransfer.PipeHandle = hPipe;
+ pUrb->UrbControlTransfer.TransferBufferLength = (ULONG)pUrbInfo->len;
+ pUrb->UrbControlTransfer.TransferFlags = ((pUrbInfo->dir == USBSUP_DIRECTION_IN) ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT);
+ pUrb->UrbControlTransfer.UrbLink = 0;
+
+ if (!hPipe)
+ pUrb->UrbControlTransfer.TransferFlags |= USBD_DEFAULT_PIPE_TRANSFER;
+
+ if (pUrbInfo->type == USBSUP_TRANSFER_TYPE_MSG)
+ {
+ /* QUSB_TRANSFER_TYPE_MSG is a control transfer, but it is special
+ * the first 8 bytes of the buffer is the setup packet so the real
+ * data length is therefore pUrb->len - 8
+ */
+ PVBOXUSB_SETUP pSetup = (PVBOXUSB_SETUP)pUrb->UrbControlTransfer.SetupPacket;
+ memcpy(pUrb->UrbControlTransfer.SetupPacket, pBuffer, min(sizeof (pUrb->UrbControlTransfer.SetupPacket), pUrbInfo->len));
+
+ if (pUrb->UrbControlTransfer.TransferBufferLength <= sizeof (pUrb->UrbControlTransfer.SetupPacket))
+ pUrb->UrbControlTransfer.TransferBufferLength = 0;
+ else
+ pUrb->UrbControlTransfer.TransferBufferLength -= sizeof (pUrb->UrbControlTransfer.SetupPacket);
+
+ pUrb->UrbControlTransfer.TransferBuffer = (uint8_t *)pBuffer + sizeof(pUrb->UrbControlTransfer.SetupPacket);
+ pUrb->UrbControlTransfer.TransferBufferMDL = 0;
+ pUrb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
+ }
+ else
+ {
+ pUrb->UrbControlTransfer.TransferBuffer = 0;
+ pUrb->UrbControlTransfer.TransferBufferMDL = pMdlBuf;
+ }
+ break;
+ }
+ case USBSUP_TRANSFER_TYPE_ISOC:
+ {
+ Assert(pUrbInfo->dir == USBSUP_DIRECTION_IN || pUrbInfo->type == USBSUP_TRANSFER_TYPE_BULK);
+ Assert(hPipe);
+ VBOXUSB_PIPE_INFO *pPipeInfo = vboxUsbRtGetPipeInfo(pDevExt, pUrbInfo->ep | ((pUrbInfo->dir == USBSUP_DIRECTION_IN) ? 0x80 : 0x00));
+ if (pPipeInfo == NULL)
+ {
+ /* Can happen if the isoc request comes in too early or late. */
+ AssertMsgFailed((__FUNCTION__": pPipeInfo not found\n"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ pUrb->UrbHeader.Function = URB_FUNCTION_ISOCH_TRANSFER;
+ pUrb->UrbHeader.Length = (USHORT)cbUrb;
+ pUrb->UrbIsochronousTransfer.PipeHandle = hPipe;
+ pUrb->UrbIsochronousTransfer.TransferBufferLength = (ULONG)pUrbInfo->len;
+ pUrb->UrbIsochronousTransfer.TransferBufferMDL = 0;
+ pUrb->UrbIsochronousTransfer.TransferBuffer = pBuffer;
+ pUrb->UrbIsochronousTransfer.TransferFlags = ((pUrbInfo->dir == USBSUP_DIRECTION_IN) ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT);
+ pUrb->UrbIsochronousTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK; // May be implied already
+ pUrb->UrbIsochronousTransfer.NumberOfPackets = pUrbInfo->numIsoPkts;
+ pUrb->UrbIsochronousTransfer.ErrorCount = 0;
+ pUrb->UrbIsochronousTransfer.UrbLink = 0;
+
+ Assert(pUrbInfo->numIsoPkts == pUrb->UrbIsochronousTransfer.NumberOfPackets);
+ for (ULONG i = 0; i = pUrbInfo->numIsoPkts; ++i)
+ {
+ pUrb->UrbIsochronousTransfer.IsoPacket[i].Offset = pUrbInfo->aIsoPkts[i].off;
+ pUrb->UrbIsochronousTransfer.IsoPacket[i].Length = pUrbInfo->aIsoPkts[i].cb;
+ }
+
+ /* We have to schedule the URBs ourselves. There is an ASAP flag but
+ * that can only be reliably used after pipe creation/reset, ie. it's
+ * almost completely useless.
+ */
+ ULONG iFrame, iStartFrame;
+ VBoxUsbToolCurrentFrame(pDevExt->pLowerDO, pIrp, &iFrame);
+ iFrame += 2;
+ iStartFrame = pPipeInfo->NextScheduledFrame;
+ if ((iFrame < iStartFrame) || (iStartFrame > iFrame + 512))
+ iFrame = iStartFrame;
+ pPipeInfo->NextScheduledFrame = iFrame + pUrbInfo->numIsoPkts;
+ pUrb->UrbIsochronousTransfer.StartFrame = iFrame;
+ break;
+ }
+ case USBSUP_TRANSFER_TYPE_BULK:
+ case USBSUP_TRANSFER_TYPE_INTR:
+ {
+ Assert(pUrbInfo->dir != USBSUP_DIRECTION_SETUP);
+ Assert(pUrbInfo->dir == USBSUP_DIRECTION_IN || pUrbInfo->type == USBSUP_TRANSFER_TYPE_BULK);
+ Assert(hPipe);
+
+ pUrb->UrbHeader.Function = URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
+ pUrb->UrbHeader.Length = sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER);
+ pUrb->UrbBulkOrInterruptTransfer.PipeHandle = hPipe;
+ pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength = (ULONG)pUrbInfo->len;
+ pUrb->UrbBulkOrInterruptTransfer.TransferBufferMDL = 0;
+ pUrb->UrbBulkOrInterruptTransfer.TransferBuffer = pBuffer;
+ pUrb->UrbBulkOrInterruptTransfer.TransferFlags = ((pUrbInfo->dir == USBSUP_DIRECTION_IN) ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT);
+
+ if (pUrb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+ pUrb->UrbBulkOrInterruptTransfer.TransferFlags |= (USBD_SHORT_TRANSFER_OK);
+
+ pUrb->UrbBulkOrInterruptTransfer.UrbLink = 0;
+ break;
+ }
+ default:
+ {
+ AssertFailed();
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
+
+ pContext->pDevExt = pDevExt;
+ pContext->pMdlBuf = pMdlBuf;
+ pContext->pUrb = pUrb;
+ pContext->pOut = pUrbInfo;
+ pContext->ulTransferType = pUrbInfo->type;
+ pContext->ulMagic = VBOXUSB_MAGIC;
+
+ PIO_STACK_LOCATION pSl = IoGetNextIrpStackLocation(pIrp);
+ pSl->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
+ pSl->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
+ pSl->Parameters.Others.Argument1 = pUrb;
+ pSl->Parameters.Others.Argument2 = NULL;
+
+ IoSetCompletionRoutine(pIrp, vboxUsbRtUrbSendCompletion, pContext, TRUE, TRUE, TRUE);
+ IoMarkIrpPending(pIrp);
+ Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
+ AssertMsg(NT_SUCCESS(Status), (__FUNCTION__": IoCallDriver failed Status (0x%x)\n", Status));
+ return STATUS_PENDING;
+ } while (0);
+
+ Assert(!NT_SUCCESS(Status));
+
+ if (pMdlBuf)
+ {
+ MmUnlockPages(pMdlBuf);
+ IoFreeMdl(pMdlBuf);
+ }
+
+ if (pContext)
+ vboxUsbMemFree(pContext);
+
+ VBoxDrvToolIoComplete(pIrp, Status, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtDispatchSendUrb(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFObj = pSl->FileObject;
+ PUSBSUP_URB pUrbInfo = (PUSBSUP_URB)pIrp->AssociatedIrp.SystemBuffer;
+ NTSTATUS Status;
+
+ do
+ {
+ if (!pFObj)
+ {
+ AssertFailed();
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (!vboxUsbRtCtxIsOwner(pDevExt, pFObj))
+ {
+ AssertFailed();
+ Status = STATUS_ACCESS_DENIED;
+ break;
+ }
+
+ if ( !pUrbInfo
+ || pSl->Parameters.DeviceIoControl.InputBufferLength != sizeof (*pUrbInfo)
+ || pSl->Parameters.DeviceIoControl.OutputBufferLength != sizeof (*pUrbInfo))
+ {
+ AssertMsgFailed((__FUNCTION__": STATUS_INVALID_PARAMETER\n"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ return vboxUsbRtUrbSend(pDevExt, pIrp, pUrbInfo);
+ } while (0);
+
+ Assert(Status != STATUS_PENDING);
+ VBoxDrvToolIoComplete(pIrp, Status, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtDispatchIsOperational(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ VBoxDrvToolIoComplete(pIrp, STATUS_SUCCESS, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS vboxUsbRtDispatchGetVersion(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PUSBSUP_VERSION pVer= (PUSBSUP_VERSION)pIrp->AssociatedIrp.SystemBuffer;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (pVer && pSl->Parameters.DeviceIoControl.InputBufferLength == 0
+ && pSl->Parameters.DeviceIoControl.OutputBufferLength == sizeof (*pVer))
+ {
+ pVer->u32Major = USBDRV_MAJOR_VERSION;
+ pVer->u32Minor = USBDRV_MINOR_VERSION;
+ }
+ else
+ {
+ AssertMsgFailed((__FUNCTION__": STATUS_INVALID_PARAMETER\n"));
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+ Assert(Status != STATUS_PENDING);
+ VBoxDrvToolIoComplete(pIrp, Status, sizeof (*pVer));
+ vboxUsbDdiStateRelease(pDevExt);
+ return Status;
+}
+
+static NTSTATUS vboxUsbRtDispatchDefault(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ VBoxDrvToolIoComplete(pIrp, STATUS_INVALID_DEVICE_REQUEST, 0);
+ vboxUsbDdiStateRelease(pDevExt);
+ return STATUS_INVALID_DEVICE_REQUEST;
+}
+
+DECLHIDDEN(NTSTATUS) vboxUsbRtCreate(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFObj = pSl->FileObject;
+ if (!pFObj)
+ {
+ AssertFailed();
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+DECLHIDDEN(NTSTATUS) vboxUsbRtClose(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFObj = pSl->FileObject;
+ Assert(pFObj);
+
+ vboxUsbRtCtxReleaseOwner(pDevExt, pFObj);
+
+ return STATUS_SUCCESS;
+}
+
+DECLHIDDEN(NTSTATUS) vboxUsbRtDispatch(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ switch (pSl->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case SUPUSB_IOCTL_USB_CLAIM_DEVICE:
+ {
+ return vboxUsbRtDispatchClaimDevice(pDevExt, pIrp);
+ }
+ case SUPUSB_IOCTL_USB_RELEASE_DEVICE:
+ {
+ return vboxUsbRtDispatchReleaseDevice(pDevExt, pIrp);
+ }
+ case SUPUSB_IOCTL_GET_DEVICE:
+ {
+ return vboxUsbRtDispatchGetDevice(pDevExt, pIrp);
+ }
+ case SUPUSB_IOCTL_USB_RESET:
+ {
+ return vboxUsbRtDispatchUsbReset(pDevExt, pIrp);
+ }
+ case SUPUSB_IOCTL_USB_SET_CONFIG:
+ {
+ return vboxUsbRtDispatchUsbSetConfig(pDevExt, pIrp);
+ }
+ case SUPUSB_IOCTL_USB_SELECT_INTERFACE:
+ {
+ return vboxUsbRtDispatchUsbSelectInterface(pDevExt, pIrp);
+ }
+ case SUPUSB_IOCTL_USB_CLEAR_ENDPOINT:
+ {
+ return vboxUsbRtDispatchUsbClearEndpoint(pDevExt, pIrp);
+ }
+ case SUPUSB_IOCTL_USB_ABORT_ENDPOINT:
+ {
+ return vboxUsbRtDispatchUsbAbortEndpoint(pDevExt, pIrp);
+ }
+ case SUPUSB_IOCTL_SEND_URB:
+ {
+ return vboxUsbRtDispatchSendUrb(pDevExt, pIrp);
+ }
+ case SUPUSB_IOCTL_IS_OPERATIONAL:
+ {
+ return vboxUsbRtDispatchIsOperational(pDevExt, pIrp);
+ }
+ case SUPUSB_IOCTL_GET_VERSION:
+ {
+ return vboxUsbRtDispatchGetVersion(pDevExt, pIrp);
+ }
+ default:
+ {
+ return vboxUsbRtDispatchDefault(pDevExt, pIrp);
+ }
+ }
+}
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.h b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.h
new file mode 100644
index 000000000..39dc36c1e
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.h
@@ -0,0 +1,73 @@
+/* $Id: VBoxUsbRt.h 36968 2011-05-05 08:55:16Z vboxsync $ */
+/** @file
+ * VBox USB R0 runtime
+ */
+/*
+ * 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 ___VBoxUsbRt_h___
+#define ___VBoxUsbRt_h___
+
+#include "VBoxUsbCmn.h"
+#include "../cmn/VBoxUsbIdc.h"
+
+#define VBOXUSBRT_MAX_CFGS 4
+
+typedef struct VBOXUSB_PIPE_INFO {
+ UCHAR EndpointAddress;
+ ULONG NextScheduledFrame;
+} VBOXUSB_PIPE_INFO;
+
+typedef struct VBOXUSB_IFACE_INFO {
+ USBD_INTERFACE_INFORMATION *pInterfaceInfo;
+ VBOXUSB_PIPE_INFO *pPipeInfo;
+} VBOXUSB_IFACE_INFO;
+
+typedef struct VBOXUSB_RT
+{
+ UNICODE_STRING IfName;
+
+ HANDLE hConfiguration;
+ uint32_t uConfigValue;
+
+ uint32_t uNumInterfaces;
+ USB_DEVICE_DESCRIPTOR *devdescr;
+ USB_CONFIGURATION_DESCRIPTOR *cfgdescr[VBOXUSBRT_MAX_CFGS];
+
+ VBOXUSB_IFACE_INFO *pVBIfaceInfo;
+
+ uint16_t idVendor, idProduct, bcdDevice;
+ char szSerial[MAX_USB_SERIAL_STRING];
+ BOOLEAN fIsHighSpeed;
+
+ HVBOXUSBIDCDEV hMonDev;
+ PFILE_OBJECT pOwner;
+} VBOXUSB_RT, *PVBOXUSB_RT;
+
+typedef struct VBOXUSBRT_IDC
+{
+ PDEVICE_OBJECT pDevice;
+ PFILE_OBJECT pFile;
+} VBOXUSBRT_IDC, *PVBOXUSBRT_IDC;
+
+DECLHIDDEN(NTSTATUS) vboxUsbRtGlobalsInit();
+DECLHIDDEN(VOID) vboxUsbRtGlobalsTerm();
+
+DECLHIDDEN(NTSTATUS) vboxUsbRtInit(PVBOXUSBDEV_EXT pDevExt);
+DECLHIDDEN(VOID) vboxUsbRtClear(PVBOXUSBDEV_EXT pDevExt);
+DECLHIDDEN(NTSTATUS) vboxUsbRtRm(PVBOXUSBDEV_EXT pDevExt);
+DECLHIDDEN(NTSTATUS) vboxUsbRtStart(PVBOXUSBDEV_EXT pDevExt);
+
+DECLHIDDEN(NTSTATUS) vboxUsbRtDispatch(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp);
+DECLHIDDEN(NTSTATUS) vboxUsbRtCreate(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp);
+DECLHIDDEN(NTSTATUS) vboxUsbRtClose(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp);
+
+#endif /* #ifndef ___VBoxUsbRt_h___ */
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/lib/Makefile.kup b/src/VBox/HostDrivers/VBoxUSB/win/lib/Makefile.kup
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/lib/Makefile.kup
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/lib/VBoxUsbLib-win.cpp b/src/VBox/HostDrivers/VBoxUSB/win/lib/VBoxUsbLib-win.cpp
new file mode 100644
index 000000000..7076c25e5
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/lib/VBoxUsbLib-win.cpp
@@ -0,0 +1,1545 @@
+/* $Id: VBoxUsbLib-win.cpp 37431 2011-06-14 09:32:05Z vboxsync $ */
+/** @file
+ * VBox USB R3 Driver Interface library
+ */
+/*
+ * 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.
+ */
+#define LOG_GROUP LOG_GROUP_DRV_USBPROXY
+#include <windows.h>
+
+#include <VBox/sup.h>
+#include <VBox/types.h>
+#include <VBox/err.h>
+#include <VBox/param.h>
+#include <iprt/path.h>
+#include <iprt/assert.h>
+#include <iprt/alloc.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
+#include <VBox/log.h>
+#include <VBox/usblib.h>
+#include <VBox/usblib-win.h>
+#include <VBox/usb.h>
+#include <VBox/VBoxDrvCfg-win.h>
+#include <stdio.h>
+#pragma warning (disable:4200) /* shuts up the empty array member warnings */
+#include <setupapi.h>
+#include <usbdi.h>
+#include <hidsdi.h>
+
+#define VBOX_USB_USE_DEVICE_NOTIFICATION
+
+#ifdef VBOX_USB_USE_DEVICE_NOTIFICATION
+# include <Dbt.h>
+#endif
+
+typedef struct _USB_INTERFACE_DESCRIPTOR2 {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ UCHAR bInterfaceNumber;
+ UCHAR bAlternateSetting;
+ UCHAR bNumEndpoints;
+ UCHAR bInterfaceClass;
+ UCHAR bInterfaceSubClass;
+ UCHAR bInterfaceProtocol;
+ UCHAR iInterface;
+ USHORT wNumClasses;
+} USB_INTERFACE_DESCRIPTOR2, *PUSB_INTERFACE_DESCRIPTOR2;
+
+typedef struct VBOXUSBGLOBALSTATE
+{
+ HANDLE hMonitor;
+ HANDLE hNotifyEvent;
+ HANDLE hInterruptEvent;
+#ifdef VBOX_USB_USE_DEVICE_NOTIFICATION
+ HANDLE hThread;
+ HWND hWnd;
+ HANDLE hTimerQueue;
+ HANDLE hTimer;
+#endif
+} VBOXUSBGLOBALSTATE, *PVBOXUSBGLOBALSTATE;
+
+static VBOXUSBGLOBALSTATE g_VBoxUsbGlobal;
+
+typedef struct VBOXUSB_STRING_DR_ENTRY
+{
+ struct VBOXUSB_STRING_DR_ENTRY *pNext;
+ UCHAR iDr;
+ USHORT idLang;
+ USB_STRING_DESCRIPTOR StrDr;
+} VBOXUSB_STRING_DR_ENTRY, *PVBOXUSB_STRING_DR_ENTRY;
+
+/* this represents VBoxUsb device instance */
+typedef struct VBOXUSB_DEV
+{
+ struct VBOXUSB_DEV *pNext;
+ char szName[512];
+ char szDriverRegName[512];
+} VBOXUSB_DEV, *PVBOXUSB_DEV;
+
+int usbLibVuDeviceValidate(PVBOXUSB_DEV pVuDev)
+{
+ HANDLE hOut = INVALID_HANDLE_VALUE;
+
+ hOut = CreateFile(pVuDev->szName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
+
+ if (hOut == INVALID_HANDLE_VALUE)
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": CreateFile FAILED to open %s, winEr (%d)\n", pVuDev->szName, winEr));
+ return VERR_GENERAL_FAILURE;
+ }
+
+ USBSUP_VERSION version = {0};
+ DWORD cbReturned = 0;
+ int rc = VERR_VERSION_MISMATCH;
+
+ do
+ {
+ if (!DeviceIoControl(hOut, SUPUSB_IOCTL_GET_VERSION, NULL, 0,&version, sizeof(version), &cbReturned, NULL))
+ {
+ AssertMsgFailed((__FUNCTION__": DeviceIoControl SUPUSB_IOCTL_GET_VERSION failed with LastError=%Rwa\n", GetLastError()));
+ break;
+ }
+
+ if (version.u32Major != USBDRV_MAJOR_VERSION
+ || version.u32Minor < USBDRV_MINOR_VERSION)
+ {
+ AssertMsgFailed((__FUNCTION__": Invalid version %d:%d vs %d:%d\n", version.u32Major, version.u32Minor, USBDRV_MAJOR_VERSION, USBDRV_MINOR_VERSION));
+ break;
+ }
+
+ if (!DeviceIoControl(hOut, SUPUSB_IOCTL_IS_OPERATIONAL, NULL, 0, NULL, NULL, &cbReturned, NULL))
+ {
+ AssertMsgFailed((__FUNCTION__": DeviceIoControl SUPUSB_IOCTL_IS_OPERATIONAL failed with LastError=%Rwa\n", GetLastError()));
+ break;
+ }
+
+ rc = VINF_SUCCESS;
+ } while (0);
+
+ CloseHandle(hOut);
+ return rc;
+}
+
+static int usbLibVuDevicePopulate(PVBOXUSB_DEV pVuDev, HDEVINFO hDevInfo, PSP_DEVICE_INTERFACE_DATA pIfData)
+{
+ DWORD cbIfDetailData;
+ int rc = VINF_SUCCESS;
+
+ SetupDiGetDeviceInterfaceDetail(hDevInfo, pIfData,
+ NULL, /* OUT PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData */
+ 0, /* IN DWORD DeviceInterfaceDetailDataSize */
+ &cbIfDetailData,
+ NULL
+ );
+ Assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
+
+ PSP_DEVICE_INTERFACE_DETAIL_DATA pIfDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)RTMemAllocZ(cbIfDetailData);
+ if (!pIfDetailData)
+ {
+ AssertMsgFailed((__FUNCTION__": RTMemAllocZ failed\n"));
+ return VERR_OUT_OF_RESOURCES;
+ }
+
+ DWORD cbDbgRequired;
+ SP_DEVINFO_DATA DevInfoData;
+ DevInfoData.cbSize = sizeof (DevInfoData);
+ /* the cbSize should contain the sizeof a fixed-size part according to the docs */
+ pIfDetailData->cbSize = sizeof (*pIfDetailData);
+ do
+ {
+ if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, pIfData,
+ pIfDetailData,
+ cbIfDetailData,
+ &cbDbgRequired,
+ &DevInfoData))
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": SetupDiGetDeviceInterfaceDetail, cbRequired (%d), was (%d), winEr (%d)\n", cbDbgRequired, cbIfDetailData, winEr));
+ rc = VERR_GENERAL_FAILURE;
+ break;
+ }
+
+ strncpy(pVuDev->szName, pIfDetailData->DevicePath, sizeof (pVuDev->szName));
+
+ if (!SetupDiGetDeviceRegistryPropertyA(hDevInfo, &DevInfoData, SPDRP_DRIVER,
+ NULL, /* OUT PDWORD PropertyRegDataType */
+ (PBYTE)pVuDev->szDriverRegName,
+ sizeof (pVuDev->szDriverRegName),
+ &cbDbgRequired))
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": SetupDiGetDeviceRegistryPropertyA, cbRequired (%d), was (%d), winEr (%d)\n", cbDbgRequired, sizeof (pVuDev->szDriverRegName), winEr));
+ rc = VERR_GENERAL_FAILURE;
+ break;
+ }
+
+ rc = usbLibVuDeviceValidate(pVuDev);
+ AssertRC(rc);
+ } while (0);
+
+ RTMemFree(pIfDetailData);
+ return rc;
+}
+
+static void usbLibVuFreeDevices(PVBOXUSB_DEV pDevInfos)
+{
+ while (pDevInfos)
+ {
+ PVBOXUSB_DEV pNext = pDevInfos->pNext;
+ RTMemFree(pDevInfos);
+ pDevInfos = pNext;
+ }
+}
+
+static int usbLibVuGetDevices(PVBOXUSB_DEV *ppVuDevs, uint32_t *pcVuDevs)
+{
+ *ppVuDevs = NULL;
+ *pcVuDevs = 0;
+
+ HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_CLASS_VBOXUSB,
+ NULL, /* IN PCTSTR Enumerator */
+ NULL, /* IN HWND hwndParent */
+ (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE) /* IN DWORD Flags */
+ );
+ if (hDevInfo == INVALID_HANDLE_VALUE)
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": SetupDiGetClassDevs, winEr (%d)\n", winEr));
+ return VERR_GENERAL_FAILURE;
+ }
+
+ for (int i = 0; ; ++i)
+ {
+ SP_DEVICE_INTERFACE_DATA IfData;
+ IfData.cbSize = sizeof (IfData);
+ if (!SetupDiEnumDeviceInterfaces(hDevInfo,
+ NULL, /* IN PSP_DEVINFO_DATA DeviceInfoData */
+ &GUID_CLASS_VBOXUSB, /* IN LPGUID InterfaceClassGuid */
+ i,
+ &IfData))
+ {
+ DWORD winEr = GetLastError();
+ if (winEr == ERROR_NO_MORE_ITEMS)
+ break;
+
+ AssertMsgFailed((__FUNCTION__": SetupDiEnumDeviceInterfaces, winEr (%d), resuming\n", winEr));
+ continue;
+ }
+
+ /* we've now got the IfData */
+ PVBOXUSB_DEV pVuDev = (PVBOXUSB_DEV)RTMemAllocZ(sizeof (*pVuDev));
+ if (!pVuDev)
+ {
+ AssertMsgFailed((__FUNCTION__": RTMemAllocZ failed, resuming\n"));
+ continue;
+ }
+
+ int rc = usbLibVuDevicePopulate(pVuDev, hDevInfo, &IfData);
+ if (!RT_SUCCESS(rc))
+ {
+ AssertMsgFailed((__FUNCTION__": usbLibVuDevicePopulate failed, rc (%d), resuming\n", rc));
+ continue;
+ }
+
+ pVuDev->pNext = *ppVuDevs;
+ *ppVuDevs = pVuDev;
+ ++*pcVuDevs;
+ }
+
+ SetupDiDestroyDeviceInfoList(hDevInfo);
+
+ return VINF_SUCCESS;
+}
+
+static void usbLibDevFree(PUSBDEVICE pDevice)
+{
+ RTStrFree((char*)pDevice->pszAddress);
+ RTStrFree((char*)pDevice->pszHubName);
+ if (pDevice->pszManufacturer)
+ RTStrFree((char*)pDevice->pszManufacturer);
+ if (pDevice->pszProduct)
+ RTStrFree((char*)pDevice->pszProduct);
+ if (pDevice->pszSerialNumber)
+ RTStrFree((char*)pDevice->pszSerialNumber);
+ RTMemFree(pDevice);
+}
+
+static void usbLibDevFreeList(PUSBDEVICE pDevice)
+{
+ while (pDevice)
+ {
+ PUSBDEVICE pNext = pDevice->pNext;
+ usbLibDevFree(pDevice);
+ pDevice = pNext;
+ }
+}
+
+static int usbLibDevPopulate(PUSBDEVICE pDev, PUSB_NODE_CONNECTION_INFORMATION_EX pConInfo, ULONG iPort, LPCSTR lpszDrvKeyName, LPCSTR lpszHubName, PVBOXUSB_STRING_DR_ENTRY pDrList)
+{
+ pDev->bcdUSB = pConInfo->DeviceDescriptor.bcdUSB;
+ pDev->bDeviceClass = pConInfo->DeviceDescriptor.bDeviceClass;
+ pDev->bDeviceSubClass = pConInfo->DeviceDescriptor.bDeviceSubClass;
+ pDev->bDeviceProtocol = pConInfo->DeviceDescriptor.bDeviceProtocol;
+ pDev->idVendor = pConInfo->DeviceDescriptor.idVendor;
+ pDev->idProduct = pConInfo->DeviceDescriptor.idProduct;
+ pDev->bcdDevice = pConInfo->DeviceDescriptor.bcdDevice;
+ pDev->bBus = 0; /** @todo figure out bBus on windows... */
+ pDev->bPort = iPort;
+ /** @todo check which devices are used for primary input (keyboard & mouse) */
+ if (!lpszDrvKeyName || *lpszDrvKeyName == 0)
+ pDev->enmState = USBDEVICESTATE_UNUSED;
+ else
+ pDev->enmState = USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
+ pDev->enmSpeed = USBDEVICESPEED_UNKNOWN;
+ pDev->pszAddress = RTStrDup(lpszDrvKeyName);
+ pDev->pszHubName = RTStrDup(lpszHubName);
+ pDev->bNumConfigurations = 0;
+ pDev->u64SerialHash = 0;
+
+ for (; pDrList; pDrList = pDrList->pNext)
+ {
+ LPSTR *lppszString = NULL;
+ if (pConInfo->DeviceDescriptor.iManufacturer && pDrList->iDr == pConInfo->DeviceDescriptor.iManufacturer)
+ {
+ lppszString = (LPSTR*)&pDev->pszManufacturer;
+ }
+ else if (pConInfo->DeviceDescriptor.iProduct && pDrList->iDr == pConInfo->DeviceDescriptor.iProduct)
+ {
+ lppszString = (LPSTR*)&pDev->pszProduct;
+ }
+ else if (pConInfo->DeviceDescriptor.iSerialNumber && pDrList->iDr == pConInfo->DeviceDescriptor.iSerialNumber)
+ {
+ lppszString = (LPSTR*)&pDev->pszSerialNumber;
+ }
+
+ if (lppszString)
+ {
+ char *pStringUTF8 = NULL;
+ RTUtf16ToUtf8((PCRTUTF16)pDrList->StrDr.bString, &pStringUTF8);
+ RTStrUtf8ToCurrentCP(lppszString, pStringUTF8);
+ RTStrFree(pStringUTF8);
+ if (pDrList->iDr == pConInfo->DeviceDescriptor.iSerialNumber)
+ {
+ pDev->u64SerialHash = USBLibHashSerial(pDev->pszSerialNumber);
+ }
+ }
+ }
+
+ return VINF_SUCCESS;
+}
+
+static void usbLibDevStrFree(LPSTR lpszName)
+{
+ RTStrFree(lpszName);
+}
+
+static int usbLibDevStrDriverKeyGet(HANDLE hHub, ULONG iPort, LPSTR* plpszName)
+{
+ USB_NODE_CONNECTION_DRIVERKEY_NAME Name;
+ DWORD cbReturned = 0;
+ Name.ConnectionIndex = iPort;
+ *plpszName = NULL;
+ if (!DeviceIoControl(hHub, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, &Name, sizeof (Name), &Name, sizeof (Name), &cbReturned, NULL))
+ {
+#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": DeviceIoControl 1 fail winEr (%d)\n", winEr));
+#endif
+ return VERR_GENERAL_FAILURE;
+ }
+
+ if (Name.ActualLength < sizeof (Name))
+ {
+ AssertFailed();
+ return VERR_OUT_OF_RESOURCES;
+ }
+
+ PUSB_NODE_CONNECTION_DRIVERKEY_NAME pName = (PUSB_NODE_CONNECTION_DRIVERKEY_NAME)RTMemAllocZ(Name.ActualLength);
+ if (!pName)
+ {
+ AssertFailed();
+ return VERR_OUT_OF_RESOURCES;
+ }
+
+ int rc = VINF_SUCCESS;
+ 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);
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ rc = VINF_SUCCESS;
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": DeviceIoControl 2 fail winEr (%d)\n", winEr));
+ rc = VERR_GENERAL_FAILURE;
+ }
+ RTMemFree(pName);
+ return rc;
+}
+
+static int usbLibDevStrHubNameGet(HANDLE hHub, ULONG iPort, LPSTR* plpszName)
+{
+ USB_NODE_CONNECTION_NAME Name;
+ DWORD cbReturned = 0;
+ Name.ConnectionIndex = iPort;
+ *plpszName = NULL;
+ if (!DeviceIoControl(hHub, IOCTL_USB_GET_NODE_CONNECTION_NAME, &Name, sizeof (Name), &Name, sizeof (Name), &cbReturned, NULL))
+ {
+ AssertFailed();
+ return VERR_GENERAL_FAILURE;
+ }
+
+ if (Name.ActualLength < sizeof (Name))
+ {
+ AssertFailed();
+ return VERR_OUT_OF_RESOURCES;
+ }
+
+ PUSB_NODE_CONNECTION_NAME pName = (PUSB_NODE_CONNECTION_NAME)RTMemAllocZ(Name.ActualLength);
+ if (!pName)
+ {
+ AssertFailed();
+ return VERR_OUT_OF_RESOURCES;
+ }
+
+ int rc = VINF_SUCCESS;
+ 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);
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ rc = VINF_SUCCESS;
+ }
+ else
+ {
+ AssertFailed();
+ rc = VERR_GENERAL_FAILURE;
+ }
+ RTMemFree(pName);
+ return rc;
+}
+
+static int usbLibDevStrRootHubNameGet(HANDLE hCtl, LPSTR* plpszName)
+{
+ USB_ROOT_HUB_NAME HubName;
+ DWORD cbReturned = 0;
+ *plpszName = NULL;
+ if (!DeviceIoControl(hCtl, IOCTL_USB_GET_ROOT_HUB_NAME, NULL, 0, &HubName, sizeof (HubName), &cbReturned, NULL))
+ {
+ return VERR_GENERAL_FAILURE;
+ }
+ PUSB_ROOT_HUB_NAME pHubName = (PUSB_ROOT_HUB_NAME)RTMemAllocZ(HubName.ActualLength);
+ if (!pHubName)
+ return VERR_OUT_OF_RESOURCES;
+
+ 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);
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ rc = VINF_SUCCESS;
+ }
+ else
+ {
+ rc = VERR_GENERAL_FAILURE;
+ }
+ RTMemFree(pHubName);
+ return rc;
+}
+
+static int usbLibDevCfgDrGet(HANDLE hHub, ULONG iPort, ULONG iDr, PUSB_CONFIGURATION_DESCRIPTOR *ppDr)
+{
+ *ppDr = NULL;
+
+ char Buf[sizeof (USB_DESCRIPTOR_REQUEST) + sizeof (USB_CONFIGURATION_DESCRIPTOR)];
+ memset(&Buf, 0, sizeof (Buf));
+
+ PUSB_DESCRIPTOR_REQUEST pCfgDrRq = (PUSB_DESCRIPTOR_REQUEST)Buf;
+ PUSB_CONFIGURATION_DESCRIPTOR pCfgDr = (PUSB_CONFIGURATION_DESCRIPTOR)(Buf + sizeof (*pCfgDrRq));
+
+ pCfgDrRq->ConnectionIndex = iPort;
+ pCfgDrRq->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | iDr;
+ pCfgDrRq->SetupPacket.wLength = (USHORT)(sizeof (USB_CONFIGURATION_DESCRIPTOR));
+ DWORD cbReturned = 0;
+ if (!DeviceIoControl(hHub, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, pCfgDrRq, sizeof (Buf),
+ pCfgDrRq, sizeof (Buf),
+ &cbReturned, NULL))
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__": DeviceIoControl 1 fail winEr (%d)\n", winEr));
+#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
+ AssertFailed();
+#endif
+ return VERR_GENERAL_FAILURE;
+ }
+
+ if (sizeof (Buf) != cbReturned)
+ {
+ AssertFailed();
+ return VERR_GENERAL_FAILURE;
+ }
+
+ if (pCfgDr->wTotalLength < sizeof (USB_CONFIGURATION_DESCRIPTOR))
+ {
+ AssertFailed();
+ return VERR_GENERAL_FAILURE;
+ }
+
+ DWORD cbRq = sizeof (USB_DESCRIPTOR_REQUEST) + pCfgDr->wTotalLength;
+ PUSB_DESCRIPTOR_REQUEST pRq = (PUSB_DESCRIPTOR_REQUEST)RTMemAllocZ(cbRq);
+ Assert(pRq);
+ if (!pRq)
+ return VERR_OUT_OF_RESOURCES;
+
+ int rc = VERR_GENERAL_FAILURE;
+ do
+ {
+ PUSB_CONFIGURATION_DESCRIPTOR pDr = (PUSB_CONFIGURATION_DESCRIPTOR)(pRq + 1);
+ pRq->ConnectionIndex = iPort;
+ pRq->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | iDr;
+ pRq->SetupPacket.wLength = (USHORT)(cbRq - sizeof (USB_DESCRIPTOR_REQUEST));
+ if (!DeviceIoControl(hHub, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, pRq, cbRq,
+ pRq, cbRq,
+ &cbReturned, NULL))
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__": DeviceIoControl 2 fail winEr (%d)\n", winEr));
+#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
+ AssertFailed();
+#endif
+ break;
+ }
+
+ if (cbRq != cbReturned)
+ {
+ AssertFailed();
+ break;
+ }
+
+ if (pDr->wTotalLength != cbRq - sizeof (USB_DESCRIPTOR_REQUEST))
+ {
+ AssertFailed();
+ break;
+ }
+
+ *ppDr = pDr;
+ return VINF_SUCCESS;
+ } while (0);
+
+ RTMemFree(pRq);
+ return rc;
+}
+
+static void usbLibDevCfgDrFree(PUSB_CONFIGURATION_DESCRIPTOR pDr)
+{
+ Assert(pDr);
+ PUSB_DESCRIPTOR_REQUEST pRq = ((PUSB_DESCRIPTOR_REQUEST)pDr)-1;
+ RTMemFree(pRq);
+}
+
+static int usbLibDevStrDrEntryGet(HANDLE hHub, ULONG iPort, ULONG iDr, USHORT idLang, PVBOXUSB_STRING_DR_ENTRY *ppList)
+{
+ char Buf[sizeof (USB_DESCRIPTOR_REQUEST) + MAXIMUM_USB_STRING_LENGTH];
+ PUSB_DESCRIPTOR_REQUEST pRq = (PUSB_DESCRIPTOR_REQUEST)Buf;
+ PUSB_STRING_DESCRIPTOR pDr = (PUSB_STRING_DESCRIPTOR)(Buf + sizeof (*pRq));
+ memset (&Buf, 0, sizeof (Buf));
+ pRq->ConnectionIndex = iPort;
+ pRq->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8) | iDr;
+ pRq->SetupPacket.wIndex = idLang;
+ pRq->SetupPacket.wLength = sizeof (Buf) - sizeof (*pRq);
+ DWORD cbReturned = 0;
+ if (!DeviceIoControl(hHub, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, pRq, sizeof (Buf),
+ pRq, sizeof (Buf),
+ &cbReturned, NULL))
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__": DeviceIoControl 1 fail winEr (%d)\n", winEr));
+#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
+ AssertFailed();
+#endif
+ return VERR_GENERAL_FAILURE;
+ }
+
+ if (cbReturned < sizeof (*pDr) + 2)
+ {
+ AssertFailed();
+ return VERR_GENERAL_FAILURE;
+ }
+
+ if (!!(pDr->bLength % 2))
+ {
+ AssertFailed();
+ return VERR_GENERAL_FAILURE;
+ }
+
+ if (pDr->bLength != cbReturned - sizeof (*pRq))
+ {
+ AssertFailed();
+ return VERR_GENERAL_FAILURE;
+ }
+
+ if (pDr->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE)
+ {
+ AssertFailed();
+ return VERR_GENERAL_FAILURE;
+ }
+
+ PVBOXUSB_STRING_DR_ENTRY pEntry = (PVBOXUSB_STRING_DR_ENTRY)RTMemAllocZ(sizeof (*pEntry) + pDr->bLength + 2);
+ Assert(pEntry);
+ if (!pEntry)
+ {
+ return VERR_OUT_OF_RESOURCES;
+ }
+
+ pEntry->pNext = *ppList;
+ pEntry->iDr = iDr;
+ pEntry->idLang = idLang;
+ memcpy(&pEntry->StrDr, pDr, pDr->bLength);
+ *ppList = pEntry;
+ return VINF_SUCCESS;
+}
+
+static void usbLibDevStrDrEntryFree(PVBOXUSB_STRING_DR_ENTRY pDr)
+{
+ RTMemFree(pDr);
+}
+
+static void usbLibDevStrDrEntryFreeList(PVBOXUSB_STRING_DR_ENTRY pDr)
+{
+ while (pDr)
+ {
+ PVBOXUSB_STRING_DR_ENTRY pNext = pDr->pNext;
+ usbLibDevStrDrEntryFree(pDr);
+ pDr = pNext;
+ }
+}
+
+static int usbLibDevStrDrEntryGetForLangs(HANDLE hHub, ULONG iPort, ULONG iDr, ULONG cIdLang, const USHORT *pIdLang, PVBOXUSB_STRING_DR_ENTRY *ppList)
+{
+ for (ULONG i = 0; i < cIdLang; ++i)
+ {
+ usbLibDevStrDrEntryGet(hHub, iPort, iDr, pIdLang[i], ppList);
+ }
+ return VINF_SUCCESS;
+}
+
+static int usbLibDevStrDrEntryGetAll(HANDLE hHub, ULONG iPort, PUSB_DEVICE_DESCRIPTOR pDevDr, PUSB_CONFIGURATION_DESCRIPTOR pCfgDr, PVBOXUSB_STRING_DR_ENTRY *ppList)
+{
+ int rc = usbLibDevStrDrEntryGet(hHub, iPort, 0, 0, ppList);
+#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
+ AssertRC(rc);
+#endif
+ if (RT_FAILURE(rc))
+ return rc;
+
+ PUSB_STRING_DESCRIPTOR pLandStrDr = &(*ppList)->StrDr;
+ USHORT *pIdLang = pLandStrDr->bString;
+ ULONG cIdLang = (pLandStrDr->bLength - RT_OFFSETOF(USB_STRING_DESCRIPTOR, bString)) / sizeof (*pIdLang);
+
+ if (pDevDr->iManufacturer)
+ {
+ rc = usbLibDevStrDrEntryGetForLangs(hHub, iPort, pDevDr->iManufacturer, cIdLang, pIdLang, ppList);
+ AssertRC(rc);
+ }
+
+ if (pDevDr->iProduct)
+ {
+ rc = usbLibDevStrDrEntryGetForLangs(hHub, iPort, pDevDr->iProduct, cIdLang, pIdLang, ppList);
+ AssertRC(rc);
+ }
+
+ if (pDevDr->iSerialNumber)
+ {
+ rc = usbLibDevStrDrEntryGetForLangs(hHub, iPort, pDevDr->iSerialNumber, cIdLang, pIdLang, ppList);
+ AssertRC(rc);
+ }
+
+ PUCHAR pCur = (PUCHAR)pCfgDr;
+ PUCHAR pEnd = pCur + pCfgDr->wTotalLength;
+ while (pCur + sizeof (USB_COMMON_DESCRIPTOR) <= pEnd)
+ {
+ PUSB_COMMON_DESCRIPTOR pCmnDr = (PUSB_COMMON_DESCRIPTOR)pCur;
+ if (pCur + pCmnDr->bLength > pEnd)
+ {
+ AssertFailed();
+ break;
+ }
+
+ switch (pCmnDr->bDescriptorType)
+ {
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ {
+ if (pCmnDr->bLength != sizeof (USB_CONFIGURATION_DESCRIPTOR))
+ {
+ AssertFailed();
+ break;
+ }
+ PUSB_CONFIGURATION_DESCRIPTOR pCurCfgDr = (PUSB_CONFIGURATION_DESCRIPTOR)pCmnDr;
+ if (!pCurCfgDr->iConfiguration)
+ break;
+ rc = usbLibDevStrDrEntryGetForLangs(hHub, iPort, pCurCfgDr->iConfiguration, cIdLang, pIdLang, ppList);
+ AssertRC(rc);
+ break;
+ }
+ case USB_INTERFACE_DESCRIPTOR_TYPE:
+ {
+ if (pCmnDr->bLength != sizeof (USB_INTERFACE_DESCRIPTOR) && pCmnDr->bLength != sizeof (USB_INTERFACE_DESCRIPTOR2))
+ {
+ AssertFailed();
+ break;
+ }
+ PUSB_INTERFACE_DESCRIPTOR pCurIfDr = (PUSB_INTERFACE_DESCRIPTOR)pCmnDr;
+ if (!pCurIfDr->iInterface)
+ break;
+ rc = usbLibDevStrDrEntryGetForLangs(hHub, iPort, pCurIfDr->iInterface, cIdLang, pIdLang, ppList);
+ AssertRC(rc);
+ break;
+ }
+ default:
+ break;
+ }
+
+ pCur = pCur + pCmnDr->bLength;
+ }
+
+ return VINF_SUCCESS;
+}
+
+static int usbLibDevGetHubDevices(LPCSTR lpszName, PUSBDEVICE *ppDevs, uint32_t *pcDevs);
+
+static int usbLibDevGetHubPortDevices(HANDLE hHub, LPCSTR lpcszHubName, ULONG iPort, PUSBDEVICE *ppDevs, uint32_t *pcDevs)
+{
+ int rc = VINF_SUCCESS;
+ char Buf[sizeof (USB_NODE_CONNECTION_INFORMATION_EX) + (sizeof (USB_PIPE_INFO) * 20)];
+ PUSB_NODE_CONNECTION_INFORMATION_EX pConInfo = (PUSB_NODE_CONNECTION_INFORMATION_EX)Buf;
+ PUSB_PIPE_INFO paPipeInfo = (PUSB_PIPE_INFO)(Buf + sizeof (PUSB_NODE_CONNECTION_INFORMATION_EX));
+ DWORD cbReturned = 0;
+ memset(&Buf, 0, sizeof (Buf));
+ pConInfo->ConnectionIndex = iPort;
+ if (!DeviceIoControl(hHub, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX,
+ pConInfo, sizeof (Buf),
+ pConInfo, sizeof (Buf),
+ &cbReturned, NULL))
+ {
+ DWORD winEr = GetLastError();
+ AssertMsg(winEr == ERROR_DEVICE_NOT_CONNECTED, (__FUNCTION__": DeviceIoControl failed winEr (%d)\n", winEr));
+ return VERR_GENERAL_FAILURE;
+ }
+
+ if (pConInfo->ConnectionStatus != DeviceConnected)
+ {
+ /* just ignore & return success */
+ return VWRN_INVALID_HANDLE;
+ }
+
+ if (pConInfo->DeviceIsHub)
+ {
+ LPSTR lpszHubName = NULL;
+ rc = usbLibDevStrHubNameGet(hHub, iPort, &lpszHubName);
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ {
+ rc = usbLibDevGetHubDevices(lpszHubName, ppDevs, pcDevs);
+ usbLibDevStrFree(lpszHubName);
+ AssertRC(rc);
+ return rc;
+ }
+ /* ignore this err */
+ return VINF_SUCCESS;
+ }
+
+ LPSTR lpszName = NULL;
+ rc = usbLibDevStrDriverKeyGet(hHub, iPort, &lpszName);
+ if (RT_FAILURE(rc))
+ {
+ return rc;
+ }
+
+ Assert(lpszName);
+
+ PUSB_CONFIGURATION_DESCRIPTOR pCfgDr = NULL;
+ PVBOXUSB_STRING_DR_ENTRY pList = NULL;
+ rc = usbLibDevCfgDrGet(hHub, iPort, 0, &pCfgDr);
+ if (pCfgDr)
+ {
+ rc = usbLibDevStrDrEntryGetAll(hHub, iPort, &pConInfo->DeviceDescriptor, pCfgDr, &pList);
+#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
+ AssertRC(rc);
+#endif
+ }
+
+ PUSBDEVICE pDev = (PUSBDEVICE)RTMemAllocZ(sizeof (*pDev));
+ rc = usbLibDevPopulate(pDev, pConInfo, iPort, lpszName, lpcszHubName, pList);
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ {
+ pDev->pNext = *ppDevs;
+ *ppDevs = pDev;
+ ++*pcDevs;
+ }
+
+ if (pCfgDr)
+ usbLibDevCfgDrFree(pCfgDr);
+ if (lpszName)
+ usbLibDevStrFree(lpszName);
+ if (pList)
+ usbLibDevStrDrEntryFreeList(pList);
+
+ return VINF_SUCCESS;
+}
+
+static int usbLibDevGetHubDevices(LPCSTR lpszName, PUSBDEVICE *ppDevs, uint32_t *pcDevs)
+{
+ LPSTR lpszDevName = (LPSTR)RTMemAllocZ(strlen(lpszName) + sizeof("\\\\.\\"));
+ HANDLE hDev = INVALID_HANDLE_VALUE;
+ Assert(lpszDevName);
+ if (!lpszDevName)
+ {
+ AssertFailed();
+ return VERR_OUT_OF_RESOURCES;
+ }
+
+ int rc = VINF_SUCCESS;
+ strcpy(lpszDevName, "\\\\.\\");
+ strcpy(lpszDevName + sizeof("\\\\.\\") - sizeof (lpszDevName[0]), lpszName);
+ do
+ {
+ DWORD cbReturned = 0;
+ hDev = CreateFile(lpszDevName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+ if (hDev == INVALID_HANDLE_VALUE)
+ {
+ AssertFailed();
+ break;
+ }
+
+ USB_NODE_INFORMATION NodeInfo;
+ memset(&NodeInfo, 0, sizeof (NodeInfo));
+ if (!DeviceIoControl(hDev, IOCTL_USB_GET_NODE_INFORMATION,
+ &NodeInfo, sizeof (NodeInfo),
+ &NodeInfo, sizeof (NodeInfo),
+ &cbReturned, NULL))
+ {
+ AssertFailed();
+ break;
+ }
+
+ for (ULONG i = 1; i <= NodeInfo.u.HubInformation.HubDescriptor.bNumberOfPorts; ++i)
+ {
+ usbLibDevGetHubPortDevices(hDev, lpszName, i, ppDevs, pcDevs);
+ }
+ } while (0);
+
+ if (hDev != INVALID_HANDLE_VALUE)
+ CloseHandle(hDev);
+
+ RTMemFree(lpszDevName);
+
+ return rc;
+}
+
+static int usbLibDevGetDevices(PUSBDEVICE *ppDevs, uint32_t *pcDevs)
+{
+ char CtlName[16];
+ int rc = VINF_SUCCESS;
+
+ for (int i = 0; i < 10; ++i)
+ {
+ sprintf(CtlName, "\\\\.\\HCD%d", i);
+ HANDLE hCtl = CreateFile(CtlName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+ if (hCtl != INVALID_HANDLE_VALUE)
+ {
+ char* lpszName;
+ rc = usbLibDevStrRootHubNameGet(hCtl, &lpszName);
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ {
+ rc = usbLibDevGetHubDevices(lpszName, ppDevs, pcDevs);
+ AssertRC(rc);
+ usbLibDevStrFree(lpszName);
+ }
+ CloseHandle(hCtl);
+ if (RT_FAILURE(rc))
+ break;
+ }
+ }
+ return VINF_SUCCESS;
+}
+
+static PUSBSUP_GET_DEVICES usbLibMonGetDevRqAlloc(uint32_t cDevs, PDWORD pcbRq)
+{
+ DWORD cbRq = RT_OFFSETOF(USBSUP_GET_DEVICES, aDevices[cDevs]);
+ PUSBSUP_GET_DEVICES pRq = (PUSBSUP_GET_DEVICES)RTMemAllocZ(cbRq);
+ Assert(pRq);
+ if (!pRq)
+ return NULL;
+ pRq->cDevices = cDevs;
+ *pcbRq = cbRq;
+ return pRq;
+}
+
+static int usbLibMonDevicesCmp(PUSBDEVICE pDev, PVBOXUSB_DEV pDevInfo)
+{
+ int iDiff;
+ iDiff = strcmp(pDev->pszAddress, pDevInfo->szDriverRegName);
+ return iDiff;
+}
+
+static int usbLibMonDevicesUpdate(PVBOXUSBGLOBALSTATE pGlobal, PUSBDEVICE pDevs, uint32_t cDevs, PVBOXUSB_DEV pDevInfos, uint32_t cDevInfos)
+{
+ PUSBDEVICE pDevsHead = pDevs;
+ for (; pDevInfos; pDevInfos = pDevInfos->pNext)
+ {
+ for (pDevs = pDevsHead; pDevs; pDevs = pDevs->pNext)
+ {
+ if (usbLibMonDevicesCmp(pDevs, pDevInfos))
+ continue;
+
+ if (!pDevInfos->szDriverRegName[0])
+ {
+ AssertFailed();
+ break;
+ }
+
+ USBSUP_GETDEV Dev = {0};
+ HANDLE hDev = CreateFile(pDevInfos->szName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
+ if (hDev == INVALID_HANDLE_VALUE)
+ {
+ AssertFailed();
+ break;
+ }
+
+ DWORD cbReturned = 0;
+ if (!DeviceIoControl(hDev, SUPUSB_IOCTL_GET_DEVICE, &Dev, sizeof (Dev), &Dev, sizeof (Dev), &cbReturned, NULL))
+ {
+ DWORD winEr = GetLastError();
+ /* ERROR_DEVICE_NOT_CONNECTED -> device was removed just now */
+#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
+ AssertMsg(winEr == ERROR_DEVICE_NOT_CONNECTED, (__FUNCTION__": DeviceIoControl failed winEr (%d)\n", winEr));
+#endif
+ Log(("SUPUSB_IOCTL_GET_DEVICE: DeviceIoControl no longer connected\n"));
+ CloseHandle(hDev);
+ break;
+ }
+
+ /* we must not close the handle until we request for the device state from the monitor to ensure
+ * the device handle returned by the device driver does not disappear */
+ Assert(Dev.hDevice);
+ USBSUP_GETDEV_MON MonInfo;
+ HVBOXUSBDEVUSR hDevice = Dev.hDevice;
+ if (!DeviceIoControl(pGlobal->hMonitor, SUPUSBFLT_IOCTL_GET_DEVICE, &hDevice, sizeof (hDevice), &MonInfo, sizeof (MonInfo), &cbReturned, NULL))
+ {
+ DWORD winEr = GetLastError();
+ /* ERROR_DEVICE_NOT_CONNECTED -> device was removed just now */
+ AssertMsgFailed((__FUNCTION__": Monitor DeviceIoControl failed winEr (%d)\n", winEr));
+ Log(("SUPUSBFLT_IOCTL_GET_DEVICE: DeviceIoControl no longer connected\n"));
+ CloseHandle(hDev);
+ break;
+ }
+
+ CloseHandle(hDev);
+
+ /* success!! update device info */
+ /* ensure the state returned is valid */
+ Assert( MonInfo.enmState == USBDEVICESTATE_USED_BY_HOST
+ || MonInfo.enmState == USBDEVICESTATE_USED_BY_HOST_CAPTURABLE
+ || MonInfo.enmState == USBDEVICESTATE_UNUSED
+ || MonInfo.enmState == USBDEVICESTATE_HELD_BY_PROXY
+ || MonInfo.enmState == USBDEVICESTATE_USED_BY_GUEST);
+ pDevs->enmState = MonInfo.enmState;
+ /* The following is not 100% accurate but we only care about high-speed vs. non-high-speed */
+ pDevs->enmSpeed = Dev.fHiSpeed ? USBDEVICESPEED_HIGH : USBDEVICESPEED_FULL;
+ if (pDevs->enmState != USBDEVICESTATE_USED_BY_HOST)
+ {
+ /* only set the interface name if device can be grabbed */
+ RTStrFree(pDevs->pszAltAddress);
+ pDevs->pszAltAddress = (char*)pDevs->pszAddress;
+ pDevs->pszAddress = RTStrDup(pDevInfos->szName);
+ }
+#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
+ else
+ {
+ /* dbg breakpoint */
+ Assert(0);
+ }
+#endif
+
+ /* we've found the device, break in any way */
+ break;
+ }
+ }
+
+ return VINF_SUCCESS;
+}
+
+static int usbLibGetDevices(PVBOXUSBGLOBALSTATE pGlobal, PUSBDEVICE *ppDevs, uint32_t *pcDevs)
+{
+ *ppDevs = NULL;
+ *pcDevs = 0;
+
+ int rc = usbLibDevGetDevices(ppDevs, pcDevs);
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ {
+ PVBOXUSB_DEV pDevInfos = NULL;
+ uint32_t cDevInfos = 0;
+ rc = usbLibVuGetDevices(&pDevInfos, &cDevInfos);
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ {
+ rc = usbLibMonDevicesUpdate(pGlobal, *ppDevs, *pcDevs, pDevInfos, cDevInfos);
+ AssertRC(rc);
+ usbLibVuFreeDevices(pDevInfos);
+ }
+
+ return VINF_SUCCESS;
+ }
+ return rc;
+}
+
+AssertCompile(INFINITE == RT_INDEFINITE_WAIT);
+static int usbLibStateWaitChange(PVBOXUSBGLOBALSTATE pGlobal, RTMSINTERVAL cMillies)
+{
+ HANDLE ahEvents[] = {pGlobal->hNotifyEvent, pGlobal->hInterruptEvent};
+ DWORD dwResult = WaitForMultipleObjects(RT_ELEMENTS(ahEvents), ahEvents,
+ FALSE, /* BOOL bWaitAll */
+ cMillies);
+
+ switch (dwResult)
+ {
+ case WAIT_OBJECT_0:
+ return VINF_SUCCESS;
+ case WAIT_OBJECT_0 + 1:
+ return VERR_INTERRUPTED;
+ case WAIT_TIMEOUT:
+ return VERR_TIMEOUT;
+ default:
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": WaitForMultipleObjects failed, winEr (%d)\n", winEr));
+ return VERR_GENERAL_FAILURE;
+ }
+ }
+}
+
+AssertCompile(RT_INDEFINITE_WAIT == INFINITE);
+AssertCompile(sizeof (RTMSINTERVAL) == sizeof (DWORD));
+USBLIB_DECL(int) USBLibWaitChange(RTMSINTERVAL msWaitTimeout)
+{
+ return usbLibStateWaitChange(&g_VBoxUsbGlobal, msWaitTimeout);
+}
+
+static int usbLibInterruptWaitChange(PVBOXUSBGLOBALSTATE pGlobal)
+{
+ BOOL bRc = SetEvent(pGlobal->hInterruptEvent);
+ if (!bRc)
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": SetEvent failed, winEr (%d)\n", winEr));
+ return VERR_GENERAL_FAILURE;
+ }
+ return VINF_SUCCESS;
+}
+
+USBLIB_DECL(int) USBLibInterruptWaitChange()
+{
+ return usbLibInterruptWaitChange(&g_VBoxUsbGlobal);
+}
+
+/*
+USBLIB_DECL(bool) USBLibHasPendingDeviceChanges(void)
+{
+ int rc = USBLibWaitChange(0);
+ return rc == VINF_SUCCESS;
+}
+*/
+
+USBLIB_DECL(int) USBLibGetDevices(PUSBDEVICE *ppDevices, uint32_t *pcbNumDevices)
+{
+ Assert(g_VBoxUsbGlobal.hMonitor != INVALID_HANDLE_VALUE);
+ return usbLibGetDevices(&g_VBoxUsbGlobal, ppDevices, pcbNumDevices);
+}
+
+USBLIB_DECL(void *) USBLibAddFilter(PCUSBFILTER pFilter)
+{
+ USBSUP_FLTADDOUT FltAddRc;
+ DWORD cbReturned = 0;
+
+ if (g_VBoxUsbGlobal.hMonitor == INVALID_HANDLE_VALUE)
+ {
+#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
+ AssertFailed();
+#endif
+ return NULL;
+ }
+
+ Log(("usblibInsertFilter: Manufacturer=%s Product=%s Serial=%s\n",
+ USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) : "<null>",
+ USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) : "<null>",
+ USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) : "<null>"));
+
+ if (!DeviceIoControl(g_VBoxUsbGlobal.hMonitor, SUPUSBFLT_IOCTL_ADD_FILTER,
+ (LPVOID)pFilter, sizeof(*pFilter),
+ &FltAddRc, sizeof(FltAddRc),
+ &cbReturned, NULL))
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed(("DeviceIoControl failed with winEr (%d(\n", winEr));
+ return NULL;
+ }
+
+ if (RT_FAILURE(FltAddRc.rc))
+ {
+ AssertMsgFailed(("Adding filter failed with %d\n", FltAddRc.rc));
+ return NULL;
+ }
+ return (void *)FltAddRc.uId;
+}
+
+
+USBLIB_DECL(void) USBLibRemoveFilter(void *pvId)
+{
+ uintptr_t uId;
+ DWORD cbReturned = 0;
+
+ if (g_VBoxUsbGlobal.hMonitor == INVALID_HANDLE_VALUE)
+ {
+#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
+ AssertFailed();
+#endif
+ return;
+ }
+
+ Log(("usblibRemoveFilter %p\n", pvId));
+
+ uId = (uintptr_t)pvId;
+ if (!DeviceIoControl(g_VBoxUsbGlobal.hMonitor, SUPUSBFLT_IOCTL_REMOVE_FILTER, &uId, sizeof(uId), NULL, 0,&cbReturned, NULL))
+ AssertMsgFailed(("DeviceIoControl failed with LastError=%Rwa\n", GetLastError()));
+}
+
+USBLIB_DECL(int) USBLibRunFilters()
+{
+ DWORD cbReturned = 0;
+
+ Assert(g_VBoxUsbGlobal.hMonitor != INVALID_HANDLE_VALUE);
+
+ if (!DeviceIoControl(g_VBoxUsbGlobal.hMonitor, SUPUSBFLT_IOCTL_RUN_FILTERS,
+ NULL, 0,
+ NULL, 0,
+ &cbReturned, NULL))
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed(("DeviceIoControl failed with winEr (%d(\n", winEr));
+ return RTErrConvertFromWin32(winEr);
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+#ifdef VBOX_USB_USE_DEVICE_NOTIFICATION
+
+static VOID CALLBACK usbLibTimerCallback(
+ __in PVOID lpParameter,
+ __in BOOLEAN TimerOrWaitFired
+ )
+{
+ SetEvent(g_VBoxUsbGlobal.hNotifyEvent);
+}
+
+static void usbLibOnDeviceChange()
+{
+ /* we're getting series of events like that especially on device re-attach
+ * (i.e. first for device detach and then for device attach)
+ * unfortunately the event does not tell us what actually happened.
+ * To avoid extra notifications, we delay the SetEvent via a timer
+ * and update the timer if additional notification comes before the timer fires
+ * */
+ if (g_VBoxUsbGlobal.hTimer)
+ {
+ if (!DeleteTimerQueueTimer(g_VBoxUsbGlobal.hTimerQueue, g_VBoxUsbGlobal.hTimer, NULL))
+ {
+ DWORD winEr = GetLastError();
+ AssertMsg(winEr == ERROR_IO_PENDING, (__FUNCTION__": DeleteTimerQueueTimer failed, winEr (%d)\n", winEr));
+ }
+ }
+
+ if (!CreateTimerQueueTimer(&g_VBoxUsbGlobal.hTimer, g_VBoxUsbGlobal.hTimerQueue,
+ usbLibTimerCallback,
+ NULL,
+ 500, /* ms*/
+ 0,
+ WT_EXECUTEONLYONCE))
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": CreateTimerQueueTimer failed, winEr (%d)\n", winEr));
+
+ /* call it directly */
+ usbLibTimerCallback(NULL, FALSE);
+ }
+}
+
+static LRESULT CALLBACK usbLibWndProc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam
+)
+{
+ switch (uMsg)
+ {
+ case WM_DEVICECHANGE:
+ if (wParam == DBT_DEVNODES_CHANGED)
+ {
+ /* we notify change any device arivals/removals on the system
+ * and let the client decide whether the usb change actually happened
+ * so far this is more clean than reporting events from the Monitor
+ * because monitor sees only PDO arrivals/removals,
+ * and by the time PDO is created, device can not
+ * be yet started and fully functional,
+ * so usblib won't be able to pick it up
+ * */
+
+ usbLibOnDeviceChange();
+ }
+ break;
+ case WM_DESTROY:
+ return 0;
+ }
+ return DefWindowProc (hwnd, uMsg, wParam, lParam);
+}
+
+static LPCSTR g_VBoxUsbWndClassName = "VBoxUsbLibClass";
+
+static DWORD WINAPI usbLibMsgThreadProc(__in LPVOID lpParameter)
+{
+ HWND hwnd = 0;
+ HINSTANCE hInstance = (HINSTANCE)GetModuleHandle (NULL);
+ bool bExit = false;
+
+ /* Register the Window Class. */
+ WNDCLASS wc;
+ wc.style = 0;
+ wc.lpfnWndProc = usbLibWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = sizeof(void *);
+ wc.hInstance = hInstance;
+ wc.hIcon = NULL;
+ wc.hCursor = NULL;
+ wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = g_VBoxUsbWndClassName;
+
+ ATOM atomWindowClass = RegisterClass(&wc);
+
+ if (atomWindowClass != 0)
+ {
+ /* Create the window. */
+ g_VBoxUsbGlobal.hWnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
+ g_VBoxUsbWndClassName, g_VBoxUsbWndClassName,
+ WS_POPUPWINDOW,
+ -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
+ SetEvent(g_VBoxUsbGlobal.hNotifyEvent);
+
+ if (g_VBoxUsbGlobal.hWnd)
+ {
+ SetWindowPos(hwnd, HWND_TOPMOST, -200, -200, 0, 0,
+ SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
+
+ MSG msg;
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ DestroyWindow (hwnd);
+
+ bExit = true;
+ }
+
+ UnregisterClass (g_VBoxUsbWndClassName, hInstance);
+ }
+
+ if(bExit)
+ {
+ /* no need any accuracy here, in anyway the DHCP server usually gets terminated with TerminateProcess */
+ exit(0);
+ }
+
+ return 0;
+}
+#endif
+
+/**
+ * Initialize the USB library
+ *
+ * @returns VBox status code.
+ */
+USBLIB_DECL(int) USBLibInit(void)
+{
+ int rc = VERR_GENERAL_FAILURE;
+
+ Log(("usbproxy: usbLibInit\n"));
+
+ memset(&g_VBoxUsbGlobal, 0, sizeof (g_VBoxUsbGlobal));
+
+ g_VBoxUsbGlobal.hMonitor = INVALID_HANDLE_VALUE;
+
+ g_VBoxUsbGlobal.hNotifyEvent = CreateEvent(NULL, /* LPSECURITY_ATTRIBUTES lpEventAttributes */
+ FALSE, /* BOOL bManualReset */
+#ifndef VBOX_USB_USE_DEVICE_NOTIFICATION
+ TRUE, /* BOOL bInitialState */
+#else
+ FALSE, /* set to false since it will be initially used for notification thread startup sync */
+#endif
+ NULL /* LPCTSTR lpName */);
+ if (g_VBoxUsbGlobal.hNotifyEvent)
+ {
+ g_VBoxUsbGlobal.hInterruptEvent = CreateEvent(NULL, /* LPSECURITY_ATTRIBUTES lpEventAttributes */
+ FALSE, /* BOOL bManualReset */
+ FALSE, /* BOOL bInitialState */
+ NULL /* LPCTSTR lpName */);
+ if (g_VBoxUsbGlobal.hInterruptEvent)
+ {
+ g_VBoxUsbGlobal.hMonitor = CreateFile(USBMON_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
+
+ if (g_VBoxUsbGlobal.hMonitor == INVALID_HANDLE_VALUE)
+ {
+ HRESULT hr = VBoxDrvCfgSvcStart(USBMON_SERVICE_NAME_W);
+ if (hr == S_OK)
+ {
+ g_VBoxUsbGlobal.hMonitor = CreateFile(USBMON_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
+ if (g_VBoxUsbGlobal.hMonitor == INVALID_HANDLE_VALUE)
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__": CreateFile failed winEr(%d)\n", winEr));
+ rc = VERR_FILE_NOT_FOUND;
+ }
+ }
+ }
+
+ if (g_VBoxUsbGlobal.hMonitor != INVALID_HANDLE_VALUE)
+ {
+ USBSUP_VERSION Version = {0};
+ DWORD cbReturned = 0;
+
+ if (DeviceIoControl(g_VBoxUsbGlobal.hMonitor, SUPUSBFLT_IOCTL_GET_VERSION, NULL, 0, &Version, sizeof (Version), &cbReturned, NULL))
+ {
+ if (Version.u32Major == USBMON_MAJOR_VERSION || Version.u32Minor <= USBMON_MINOR_VERSION)
+ {
+#ifndef VBOX_USB_USE_DEVICE_NOTIFICATION
+ USBSUP_SET_NOTIFY_EVENT SetEvent = {0};
+ Assert(g_VBoxUsbGlobal.hNotifyEvent);
+ SetEvent.u.hEvent = g_VBoxUsbGlobal.hNotifyEvent;
+ if (DeviceIoControl(g_VBoxUsbGlobal.hMonitor, SUPUSBFLT_IOCTL_SET_NOTIFY_EVENT,
+ &SetEvent, sizeof (SetEvent),
+ &SetEvent, sizeof (SetEvent),
+ &cbReturned, NULL))
+ {
+ rc = SetEvent.u.rc;
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ else
+ AssertMsgFailed((__FUNCTION__": SetEvent failed, rc (%d)\n", rc));
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": SetEvent Ioctl failed, winEr (%d)\n", winEr));
+ rc = VERR_VERSION_MISMATCH;
+ }
+#else
+ g_VBoxUsbGlobal.hTimerQueue = CreateTimerQueue();
+ if (g_VBoxUsbGlobal.hTimerQueue)
+ {
+ g_VBoxUsbGlobal.hThread = CreateThread(
+ NULL, /*__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, */
+ 0, /*__in SIZE_T dwStackSize, */
+ usbLibMsgThreadProc, /*__in LPTHREAD_START_ROUTINE lpStartAddress,*/
+ NULL, /*__in_opt LPVOID lpParameter,*/
+ 0, /*__in DWORD dwCreationFlags,*/
+ NULL /*__out_opt LPDWORD lpThreadId*/
+ );
+
+ if(g_VBoxUsbGlobal.hThread)
+ {
+ DWORD dwResult = WaitForSingleObject(g_VBoxUsbGlobal.hNotifyEvent, INFINITE);
+ Assert(dwResult == WAIT_OBJECT_0);
+
+ if (g_VBoxUsbGlobal.hWnd)
+ {
+ /* ensure the event is set so the first "wait change" request processes */
+ SetEvent(g_VBoxUsbGlobal.hNotifyEvent);
+ return VINF_SUCCESS;
+ }
+ dwResult = WaitForSingleObject(g_VBoxUsbGlobal.hThread, INFINITE);
+ Assert(dwResult == WAIT_OBJECT_0);
+ BOOL bRc = CloseHandle(g_VBoxUsbGlobal.hThread);
+ if (!bRc)
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": CloseHandle for hThread failed winEr(%d)\n", winEr));
+ }
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": CreateThread failed, winEr (%d)\n", winEr));
+ rc = VERR_GENERAL_FAILURE;
+ }
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": CreateTimerQueue failed winEr(%d)\n", winEr));
+ }
+#endif
+ }
+ else
+ {
+ AssertMsgFailed((__FUNCTION__": Monitor driver version mismatch!!\n"));
+ rc = VERR_VERSION_MISMATCH;
+ }
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": DeviceIoControl failed winEr(%d)\n", winEr));
+ rc = VERR_VERSION_MISMATCH;
+ }
+
+ CloseHandle(g_VBoxUsbGlobal.hMonitor);
+ }
+ else
+ {
+ LogRel((__FUNCTION__": USB Service not found\n"));
+#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
+ AssertFailed();
+#endif
+ rc = VERR_FILE_NOT_FOUND;
+ }
+
+ CloseHandle(g_VBoxUsbGlobal.hInterruptEvent);
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": CreateEvent for InterruptEvent failed winEr(%d)\n", winEr));
+ rc = VERR_GENERAL_FAILURE;
+ }
+
+ CloseHandle(g_VBoxUsbGlobal.hNotifyEvent);
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": CreateEvent for NotifyEvent failed winEr(%d)\n", winEr));
+ rc = VERR_GENERAL_FAILURE;
+ }
+
+ /* since main calls us even if USBLibInit fails,
+ * we use hMonitor == INVALID_HANDLE_VALUE as a marker to indicate whether the lib is inited */
+
+ Assert(RT_FAILURE(rc));
+ return rc;
+}
+
+
+/**
+ * Terminate the USB library
+ *
+ * @returns VBox status code.
+ */
+USBLIB_DECL(int) USBLibTerm(void)
+{
+ if (g_VBoxUsbGlobal.hMonitor == INVALID_HANDLE_VALUE)
+ {
+#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
+ AssertFailed();
+#endif
+ return VINF_ALREADY_INITIALIZED;
+ }
+
+ BOOL bRc;
+#ifdef VBOX_USB_USE_DEVICE_NOTIFICATION
+ bRc= PostMessage(g_VBoxUsbGlobal.hWnd, WM_QUIT, 0, 0);
+ if (!bRc)
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": PostMessage for hWnd failed winEr(%d)\n", winEr));
+ }
+
+ DWORD dwResult = WaitForSingleObject(g_VBoxUsbGlobal.hThread, INFINITE);
+ Assert(dwResult == WAIT_OBJECT_0);
+ bRc = CloseHandle(g_VBoxUsbGlobal.hThread);
+ if (!bRc)
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": CloseHandle for hThread failed winEr(%d)\n", winEr));
+ }
+
+ if (g_VBoxUsbGlobal.hTimer)
+ {
+ bRc = DeleteTimerQueueTimer(g_VBoxUsbGlobal.hTimerQueue, g_VBoxUsbGlobal.hTimer,
+ INVALID_HANDLE_VALUE /* <-- to block until the timer is completed */
+ );
+ if (!bRc)
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": DeleteTimerQueueEx failed winEr(%d)\n", winEr));
+ }
+ }
+
+ bRc = DeleteTimerQueueEx(g_VBoxUsbGlobal.hTimerQueue,
+ INVALID_HANDLE_VALUE /* <-- to block until all timers are completed */
+ );
+ if (!bRc)
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": DeleteTimerQueueEx failed winEr(%d)\n", winEr));
+ }
+#endif
+
+ bRc = CloseHandle(g_VBoxUsbGlobal.hMonitor);
+ if (!bRc)
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": CloseHandle for hMonitor failed winEr(%d)\n", winEr));
+ }
+
+ bRc = CloseHandle(g_VBoxUsbGlobal.hInterruptEvent);
+ if (!bRc)
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": CloseHandle for hInterruptEvent failed winEr(%d)\n", winEr));
+ }
+
+ bRc = CloseHandle(g_VBoxUsbGlobal.hNotifyEvent);
+ if (!bRc)
+ {
+ DWORD winEr = GetLastError();
+ AssertMsgFailed((__FUNCTION__": CloseHandle for hNotifyEvent failed winEr(%d)\n", winEr));
+ }
+
+ return VINF_SUCCESS;
+}
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/mon/Makefile.kup b/src/VBox/HostDrivers/VBoxUSB/win/mon/Makefile.kup
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/mon/Makefile.kup
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Monitor/VBoxUSBMon.inf b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUSBMon.inf
index 158307372..e4650df7f 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/Monitor/VBoxUSBMon.inf
+++ b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUSBMon.inf
@@ -1,9 +1,9 @@
;
-; VBox host drivers - USB drivers - Win32 USB monitor driver
+; VBox USB Monitor driver
;
; Installation file
;
-; Copyright (C) 2006-2007 Oracle Corporation
+; 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;
@@ -51,7 +51,7 @@ ServiceBinary = %12%\VBoxUSBMon.sys
VBoxUSBMon.sys = 1
[DestinationDirs]
-DefaultDestDir = 12 ; DIRID_DRIVERS
+DefaultDestDir = 12 ; DIRID_DRIVERS
[Strings]
ORACLE = "Oracle Corporation"
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp
new file mode 100644
index 000000000..e516c35d1
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp
@@ -0,0 +1,1387 @@
+/* $Id: VBoxUsbFlt.cpp 37047 2011-05-12 10:29:26Z vboxsync $ */
+/** @file
+ * VBox USB Monitor Device Filtering functionality
+ */
+/*
+ * 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 "VBoxUsbMon.h"
+#include "../cmn/VBoxUsbTool.h"
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <iprt/process.h>
+#include <iprt/assert.h>
+#include <VBox/err.h>
+//#include <VBox/sup.h>
+
+#include <iprt/assert.h>
+#include <stdio.h>
+
+#pragma warning(disable : 4200)
+#include "usbdi.h"
+#pragma warning(default : 4200)
+#include "usbdlib.h"
+#include "VBoxUSBFilterMgr.h"
+#include <VBox/usblib.h>
+#include <devguid.h>
+
+/*
+ * Note: Must match the VID & PID in the USB driver .inf file!!
+ */
+/*
+ BusQueryDeviceID USB\Vid_80EE&Pid_CAFE
+ BusQueryInstanceID 2
+ BusQueryHardwareIDs USB\Vid_80EE&Pid_CAFE&Rev_0100
+ BusQueryHardwareIDs USB\Vid_80EE&Pid_CAFE
+ BusQueryCompatibleIDs USB\Class_ff&SubClass_00&Prot_00
+ BusQueryCompatibleIDs USB\Class_ff&SubClass_00
+ BusQueryCompatibleIDs USB\Class_ff
+*/
+
+#define szBusQueryDeviceId L"USB\\Vid_80EE&Pid_CAFE"
+#define szBusQueryHardwareIDs L"USB\\Vid_80EE&Pid_CAFE&Rev_0100\0USB\\Vid_80EE&Pid_CAFE\0\0"
+#define szBusQueryCompatibleIDs L"USB\\Class_ff&SubClass_00&Prot_00\0USB\\Class_ff&SubClass_00\0USB\\Class_ff\0\0"
+
+#define szDeviceTextDescription L"VirtualBox USB"
+
+/* Possible USB bus driver names. */
+static LPWSTR lpszStandardControllerName[1] =
+{
+ L"\\Driver\\usbhub",
+};
+
+/*
+ * state transitions:
+ *
+ * (we are not filtering this device )
+ * ADDED --> UNCAPTURED ------------------------------->-
+ * | |
+ * | (we are filtering this device, | (the device is being
+ * | waiting for our device driver | re-plugged to perform
+ * | to pick it up) | capture-uncapture transition)
+ * |-> CAPTURING -------------------------------->|---> REPLUGGING -----
+ * ^ | (device driver picked | |
+ * | | up the device) | (remove cased | (device is removed
+ * | ->---> CAPTURED ---------------------->| by "real" removal | the device info is removed form the list)
+ * | | |------------------->->--> REMOVED
+ * | | |
+ * |-----------<->---> USED_BY_GUEST ------->|
+ * | |
+ * |------------------------<-
+ *
+ * NOTE: the order of enums DOES MATTER!!
+ * Do not blindly modify!! as the code assumes the state is ordered this way.
+ */
+typedef enum
+{
+ VBOXUSBFLT_DEVSTATE_UNKNOWN = 0,
+ VBOXUSBFLT_DEVSTATE_REMOVED,
+ VBOXUSBFLT_DEVSTATE_REPLUGGING,
+ VBOXUSBFLT_DEVSTATE_ADDED,
+ VBOXUSBFLT_DEVSTATE_UNCAPTURED,
+ VBOXUSBFLT_DEVSTATE_CAPTURING,
+ VBOXUSBFLT_DEVSTATE_CAPTURED,
+ VBOXUSBFLT_DEVSTATE_USED_BY_GUEST,
+ VBOXUSBFLT_DEVSTATE_32BIT_HACK = 0x7fffffff
+} VBOXUSBFLT_DEVSTATE;
+
+typedef struct VBOXUSBFLT_DEVICE
+{
+ LIST_ENTRY GlobalLe;
+ /* auxiliary list to be used for gathering devices to be re-plugged
+ * only thread that puts the device to the REPLUGGING state can use this list */
+ LIST_ENTRY RepluggingLe;
+ /* Owning session. Each matched device has an owning session. */
+ struct VBOXUSBFLTCTX *pOwner;
+ /* filter id - if NULL AND device has an owner - the filter is destroyed */
+ uintptr_t uFltId;
+ /* true iff device is filtered with a one-shot filter */
+ bool fIsFilterOneShot;
+ /* The device state. If the non-owner session is requesting the state while the device is grabbed,
+ * the USBDEVICESTATE_USED_BY_HOST is returned. */
+ VBOXUSBFLT_DEVSTATE enmState;
+ volatile uint32_t cRefs;
+ PDEVICE_OBJECT Pdo;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+ uint8_t bClass;
+ uint8_t bSubClass;
+ uint8_t bProtocol;
+ char szSerial[MAX_USB_SERIAL_STRING];
+ char szMfgName[MAX_USB_SERIAL_STRING];
+ char szProduct[MAX_USB_SERIAL_STRING];
+#if 0
+ char szDrvKeyName[512];
+ BOOLEAN fHighSpeed;
+#endif
+} VBOXUSBFLT_DEVICE, *PVBOXUSBFLT_DEVICE;
+
+#define PVBOXUSBFLT_DEVICE_FROM_LE(_pLe) ( (PVBOXUSBFLT_DEVICE)( ((uint8_t*)(_pLe)) - RT_OFFSETOF(VBOXUSBFLT_DEVICE, GlobalLe) ) )
+#define PVBOXUSBFLT_DEVICE_FROM_REPLUGGINGLE(_pLe) ( (PVBOXUSBFLT_DEVICE)( ((uint8_t*)(_pLe)) - RT_OFFSETOF(VBOXUSBFLT_DEVICE, RepluggingLe) ) )
+#define PVBOXUSBFLTCTX_FROM_LE(_pLe) ( (PVBOXUSBFLTCTX)( ((uint8_t*)(_pLe)) - RT_OFFSETOF(VBOXUSBFLTCTX, ListEntry) ) )
+
+typedef struct VBOXUSBFLT_LOCK
+{
+ KSPIN_LOCK Lock;
+ KIRQL OldIrql;
+} VBOXUSBFLT_LOCK, *PVBOXUSBFLT_LOCK;
+
+#define VBOXUSBFLT_LOCK_INIT() \
+ KeInitializeSpinLock(&g_VBoxUsbFltGlobals.Lock.Lock)
+#define VBOXUSBFLT_LOCK_TERM() do { } while (0)
+#define VBOXUSBFLT_LOCK_ACQUIRE() \
+ KeAcquireSpinLock(&g_VBoxUsbFltGlobals.Lock.Lock, &g_VBoxUsbFltGlobals.Lock.OldIrql);
+#define VBOXUSBFLT_LOCK_RELEASE() \
+ KeReleaseSpinLock(&g_VBoxUsbFltGlobals.Lock.Lock, g_VBoxUsbFltGlobals.Lock.OldIrql);
+
+
+typedef struct VBOXUSBFLT_BLDEV
+{
+ LIST_ENTRY ListEntry;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+} VBOXUSBFLT_BLDEV, *PVBOXUSBFLT_BLDEV;
+
+#define PVBOXUSBFLT_BLDEV_FROM_LE(_pLe) ( (PVBOXUSBFLT_BLDEV)( ((uint8_t*)(_pLe)) - RT_OFFSETOF(VBOXUSBFLT_BLDEV, ListEntry) ) )
+
+typedef struct VBOXUSBFLTGLOBALS
+{
+ LIST_ENTRY DeviceList;
+ LIST_ENTRY ContextList;
+ /* devices known to misbehave */
+ LIST_ENTRY BlackDeviceList;
+ VBOXUSBFLT_LOCK Lock;
+} VBOXUSBFLTGLOBALS, *PVBOXUSBFLTGLOBALS;
+static VBOXUSBFLTGLOBALS g_VBoxUsbFltGlobals;
+
+static bool vboxUsbFltBlDevMatchLocked(uint16_t idVendor, uint16_t idProduct, uint16_t bcdDevice)
+{
+ for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.BlackDeviceList.Flink;
+ pEntry != &g_VBoxUsbFltGlobals.BlackDeviceList;
+ pEntry = pEntry->Flink)
+ {
+ PVBOXUSBFLT_BLDEV pDev = PVBOXUSBFLT_BLDEV_FROM_LE(pEntry);
+ if (pDev->idVendor != idVendor)
+ continue;
+ if (pDev->idProduct != idProduct)
+ continue;
+ if (pDev->bcdDevice != bcdDevice)
+ continue;
+
+ return true;
+ }
+ return false;
+}
+
+static NTSTATUS vboxUsbFltBlDevAddLocked(uint16_t idVendor, uint16_t idProduct, uint16_t bcdDevice)
+{
+ if (vboxUsbFltBlDevMatchLocked(idVendor, idProduct, bcdDevice))
+ return STATUS_SUCCESS;
+ PVBOXUSBFLT_BLDEV pDev = (PVBOXUSBFLT_BLDEV)VBoxUsbMonMemAllocZ(sizeof (*pDev));
+ if (!pDev)
+ {
+ AssertFailed();
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ pDev->idVendor = idVendor;
+ pDev->idProduct = idProduct;
+ pDev->bcdDevice = bcdDevice;
+ InsertHeadList(&g_VBoxUsbFltGlobals.BlackDeviceList, &pDev->ListEntry);
+ return STATUS_SUCCESS;
+}
+
+static void vboxUsbFltBlDevClearLocked()
+{
+ PLIST_ENTRY pNext;
+ for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.BlackDeviceList.Flink;
+ pEntry != &g_VBoxUsbFltGlobals.BlackDeviceList;
+ pEntry = pNext)
+ {
+ pNext = pEntry->Flink;
+ VBoxUsbMonMemFree(pEntry);
+ }
+}
+
+static void vboxUsbFltBlDevPopulateWithKnownLocked()
+{
+ /* this one halts when trying to get string descriptors from it */
+ vboxUsbFltBlDevAddLocked(0x5ac, 0x921c, 0x115);
+}
+
+
+DECLINLINE(void) vboxUsbFltDevRetain(PVBOXUSBFLT_DEVICE pDevice)
+{
+ Assert(pDevice->cRefs);
+ ASMAtomicIncU32(&pDevice->cRefs);
+}
+
+static void vboxUsbFltDevDestroy(PVBOXUSBFLT_DEVICE pDevice)
+{
+ Assert(!pDevice->cRefs);
+ Assert(pDevice->enmState == VBOXUSBFLT_DEVSTATE_REMOVED);
+ VBoxUsbMonMemFree(pDevice);
+}
+
+DECLINLINE(void) vboxUsbFltDevRelease(PVBOXUSBFLT_DEVICE pDevice)
+{
+ uint32_t cRefs = ASMAtomicDecU32(&pDevice->cRefs);
+ Assert(cRefs < UINT32_MAX/2);
+ if (!cRefs)
+ {
+ vboxUsbFltDevDestroy(pDevice);
+ }
+}
+
+static void vboxUsbFltDevOwnerSetLocked(PVBOXUSBFLT_DEVICE pDevice, PVBOXUSBFLTCTX pContext, uintptr_t uFltId, bool fIsOneShot)
+{
+ Assert(!pDevice->pOwner);
+ ++pContext->cActiveFilters;
+ pDevice->pOwner = pContext;
+ pDevice->uFltId = uFltId;
+ pDevice->fIsFilterOneShot = fIsOneShot;
+}
+
+static void vboxUsbFltDevOwnerClearLocked(PVBOXUSBFLT_DEVICE pDevice)
+{
+ Assert(pDevice->pOwner);
+ --pDevice->pOwner->cActiveFilters;
+ Assert(pDevice->pOwner->cActiveFilters < UINT32_MAX/2);
+ pDevice->pOwner = NULL;
+ pDevice->uFltId = 0;
+}
+
+static void vboxUsbFltDevOwnerUpdateLocked(PVBOXUSBFLT_DEVICE pDevice, PVBOXUSBFLTCTX pContext, uintptr_t uFltId, bool fIsOneShot)
+{
+ if (pDevice->pOwner != pContext)
+ {
+ if (pDevice->pOwner)
+ vboxUsbFltDevOwnerClearLocked(pDevice);
+ if (pContext)
+ vboxUsbFltDevOwnerSetLocked(pDevice, pContext, uFltId, fIsOneShot);
+ }
+ else if (pContext)
+ {
+ pDevice->uFltId = uFltId;
+ pDevice->fIsFilterOneShot = fIsOneShot;
+ }
+}
+
+static PVBOXUSBFLT_DEVICE vboxUsbFltDevGetLocked(PDEVICE_OBJECT pPdo)
+{
+#ifdef DEBUG_misha
+ for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.DeviceList.Flink;
+ pEntry != &g_VBoxUsbFltGlobals.DeviceList;
+ pEntry = pEntry->Flink)
+ {
+ PVBOXUSBFLT_DEVICE pDevice = PVBOXUSBFLT_DEVICE_FROM_LE(pEntry);
+ for (PLIST_ENTRY pEntry2 = pEntry->Flink;
+ pEntry2 != &g_VBoxUsbFltGlobals.DeviceList;
+ pEntry2 = pEntry2->Flink)
+ {
+ PVBOXUSBFLT_DEVICE pDevice2 = PVBOXUSBFLT_DEVICE_FROM_LE(pEntry2);
+ Assert( pDevice->idVendor != pDevice2->idVendor
+ || pDevice->idProduct != pDevice2->idProduct
+ || pDevice->bcdDevice != pDevice2->bcdDevice);
+ }
+ }
+#endif
+ for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.DeviceList.Flink;
+ pEntry != &g_VBoxUsbFltGlobals.DeviceList;
+ pEntry = pEntry->Flink)
+ {
+ PVBOXUSBFLT_DEVICE pDevice = PVBOXUSBFLT_DEVICE_FROM_LE(pEntry);
+ Assert( pDevice->enmState == VBOXUSBFLT_DEVSTATE_REPLUGGING
+ || pDevice->enmState == VBOXUSBFLT_DEVSTATE_UNCAPTURED
+ || pDevice->enmState == VBOXUSBFLT_DEVSTATE_CAPTURING
+ || pDevice->enmState == VBOXUSBFLT_DEVSTATE_CAPTURED
+ || pDevice->enmState == VBOXUSBFLT_DEVSTATE_USED_BY_GUEST);
+ if (pDevice->Pdo == pPdo)
+ return pDevice;
+ }
+ return NULL;
+}
+
+PVBOXUSBFLT_DEVICE vboxUsbFltDevGet(PDEVICE_OBJECT pPdo)
+{
+ PVBOXUSBFLT_DEVICE pDevice;
+
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ pDevice = vboxUsbFltDevGetLocked(pPdo);
+ if (pDevice->enmState > VBOXUSBFLT_DEVSTATE_ADDED)
+ {
+ vboxUsbFltDevRetain(pDevice);
+ }
+ else
+ {
+ pDevice = NULL;
+ }
+ VBOXUSBFLT_LOCK_RELEASE();
+
+ return pDevice;
+}
+
+static NTSTATUS vboxUsbFltPdoReplug(PDEVICE_OBJECT pDo)
+{
+ NTSTATUS Status = VBoxUsbToolIoInternalCtlSendSync(pDo, IOCTL_INTERNAL_USB_CYCLE_PORT, NULL, NULL);
+ Assert(Status == STATUS_SUCCESS);
+ return Status;
+}
+
+static PVBOXUSBFLTCTX vboxUsbFltDevMatchLocked(PVBOXUSBFLT_DEVICE pDevice, uintptr_t *puId, bool fRemoveFltIfOneShot, bool *pfFilter, bool *pfIsOneShot)
+{
+ USBFILTER DevFlt;
+ USBFilterInit(&DevFlt, USBFILTERTYPE_CAPTURE);
+ USBFilterSetNumExact(&DevFlt, USBFILTERIDX_VENDOR_ID, pDevice->idVendor, true);
+ USBFilterSetNumExact(&DevFlt, USBFILTERIDX_PRODUCT_ID, pDevice->idProduct, true);
+ USBFilterSetNumExact(&DevFlt, USBFILTERIDX_DEVICE_REV, pDevice->bcdDevice, true);
+ USBFilterSetNumExact(&DevFlt, USBFILTERIDX_DEVICE_CLASS, pDevice->bClass, true);
+ USBFilterSetNumExact(&DevFlt, USBFILTERIDX_DEVICE_SUB_CLASS, pDevice->bSubClass, true);
+ USBFilterSetNumExact(&DevFlt, USBFILTERIDX_DEVICE_PROTOCOL, pDevice->bProtocol, true);
+ USBFilterSetStringExact(&DevFlt, USBFILTERIDX_MANUFACTURER_STR, pDevice->szMfgName, true);
+ USBFilterSetStringExact(&DevFlt, USBFILTERIDX_PRODUCT_STR, pDevice->szProduct, true);
+ USBFilterSetStringExact(&DevFlt, USBFILTERIDX_SERIAL_NUMBER_STR, pDevice->szSerial, true);
+
+ /* Run filters on the thing. */
+ *puId = 0;
+ *pfFilter = false;
+ *pfIsOneShot = false;
+ PVBOXUSBFLTCTX pOwner = VBoxUSBFilterMatchEx(&DevFlt, puId, fRemoveFltIfOneShot, pfFilter, pfIsOneShot);
+ USBFilterDelete(&DevFlt);
+ return pOwner;
+}
+
+static void vboxUsbFltDevStateMarkReplugLocked(PVBOXUSBFLT_DEVICE pDevice)
+{
+ vboxUsbFltDevOwnerUpdateLocked(pDevice, NULL, 0, false);
+ pDevice->enmState = VBOXUSBFLT_DEVSTATE_REPLUGGING;
+}
+
+static bool vboxUsbFltDevStateIsNotFiltered(PVBOXUSBFLT_DEVICE pDevice)
+{
+ return pDevice->enmState == VBOXUSBFLT_DEVSTATE_UNCAPTURED;
+}
+
+static bool vboxUsbFltDevStateIsFiltered(PVBOXUSBFLT_DEVICE pDevice)
+{
+ return pDevice->enmState >= VBOXUSBFLT_DEVSTATE_CAPTURING;
+}
+
+#define VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS 10000
+
+static NTSTATUS vboxUsbFltDevPopulate(PVBOXUSBFLT_DEVICE pDevice, PDEVICE_OBJECT pDo /*, BOOLEAN bPopulateNonFilterProps*/)
+{
+ NTSTATUS Status;
+ PUSB_DEVICE_DESCRIPTOR pDevDr = 0;
+
+ pDevice->Pdo = pDo;
+
+ pDevDr = (PUSB_DEVICE_DESCRIPTOR)VBoxUsbMonMemAllocZ(sizeof(*pDevDr));
+ if (pDevDr == NULL)
+ {
+ AssertMsgFailed(("Failed to alloc mem for urb\n"));
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ do
+ {
+ Status = VBoxUsbToolGetDescriptor(pDo, pDevDr, sizeof(*pDevDr), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS);
+ if (!NT_SUCCESS(Status))
+ {
+ LogRel((__FUNCTION__": getting device descriptor failed\n"));
+ break;
+ }
+
+ if (vboxUsbFltBlDevMatchLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice))
+ {
+ LogRel((__FUNCTION__": found a known black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+#ifdef DEBUG_misha
+ AssertFailed();
+#endif
+ Status = STATUS_UNSUCCESSFUL;
+ break;
+ }
+
+ Log(("Device pid=%x vid=%x rev=%x\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+ pDevice->idVendor = pDevDr->idVendor;
+ pDevice->idProduct = pDevDr->idProduct;
+ pDevice->bcdDevice = pDevDr->bcdDevice;
+ pDevice->bClass = pDevDr->bDeviceClass;
+ pDevice->bSubClass = pDevDr->bDeviceSubClass;
+ pDevice->bProtocol = pDevDr->bDeviceProtocol;
+ pDevice->szSerial[0] = 0;
+ pDevice->szMfgName[0] = 0;
+ pDevice->szProduct[0] = 0;
+
+ /* If there are no strings, don't even try to get any string descriptors. */
+ if (pDevDr->iSerialNumber || pDevDr->iManufacturer || pDevDr->iProduct)
+ {
+ int langId;
+
+ Status = VBoxUsbToolGetLangID(pDo, &langId, VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS);
+ if (!NT_SUCCESS(Status))
+ {
+ AssertMsgFailed((__FUNCTION__": reading language ID failed\n"));
+ if (Status == STATUS_CANCELLED)
+ {
+ AssertMsgFailed((__FUNCTION__": found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+ vboxUsbFltBlDevAddLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice);
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ break;
+ }
+
+ if (pDevDr->iSerialNumber)
+ {
+ Status = VBoxUsbToolGetStringDescriptorA(pDo, pDevice->szSerial, sizeof (pDevice->szSerial), pDevDr->iSerialNumber, langId, VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS);
+ if (!NT_SUCCESS(Status))
+ {
+ AssertMsgFailed((__FUNCTION__": reading serial number failed\n"));
+ if (Status == STATUS_CANCELLED)
+ {
+ AssertMsgFailed((__FUNCTION__": found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+ vboxUsbFltBlDevAddLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice);
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ break;
+ }
+ }
+
+ if (pDevDr->iManufacturer)
+ {
+ Status = VBoxUsbToolGetStringDescriptorA(pDo, pDevice->szMfgName, sizeof (pDevice->szMfgName), pDevDr->iManufacturer, langId, VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS);
+ if (!NT_SUCCESS(Status))
+ {
+ AssertMsgFailed((__FUNCTION__": reading manufacturer name failed\n"));
+ if (Status == STATUS_CANCELLED)
+ {
+ AssertMsgFailed((__FUNCTION__": found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+ vboxUsbFltBlDevAddLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice);
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ break;
+ }
+ }
+
+ if (pDevDr->iProduct)
+ {
+ Status = VBoxUsbToolGetStringDescriptorA(pDo, pDevice->szProduct, sizeof (pDevice->szProduct), pDevDr->iProduct, langId, VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS);
+ if (!NT_SUCCESS(Status))
+ {
+ AssertMsgFailed((__FUNCTION__": reading product name failed\n"));
+ if (Status == STATUS_CANCELLED)
+ {
+ AssertMsgFailed((__FUNCTION__": found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+ vboxUsbFltBlDevAddLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice);
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ break;
+ }
+ }
+
+#if 0
+ if (bPopulateNonFilterProps)
+ {
+ WCHAR RegKeyBuf[512];
+ ULONG cbRegKeyBuf = sizeof (RegKeyBuf);
+ Status = IoGetDeviceProperty(pDo,
+ DevicePropertyDriverKeyName,
+ cbRegKeyBuf,
+ RegKeyBuf,
+ &cbRegKeyBuf);
+ if (!NT_SUCCESS(Status))
+ {
+ AssertMsgFailed((__FUNCTION__": IoGetDeviceProperty failed Status (0x%x)\n", Status));
+ break;
+ }
+
+ ANSI_STRING Ansi;
+ UNICODE_STRING Unicode;
+ Ansi.Buffer = pDevice->szDrvKeyName;
+ Ansi.Length = 0;
+ Ansi.MaximumLength = sizeof(pDevice->szDrvKeyName);
+ RtlInitUnicodeString(&Unicode, RegKeyBuf);
+
+ Status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE /* do not allocate */);
+ if (!NT_SUCCESS(Status))
+ {
+ AssertMsgFailed((__FUNCTION__": RtlUnicodeStringToAnsiString failed Status (0x%x)\n", Status));
+ break;
+ }
+
+ pDevice->fHighSpend = FALSE;
+ Status = VBoxUsbToolGetDeviceSpeed(pDo, &pDevice->fHighSpend);
+ if (!NT_SUCCESS(Status))
+ {
+ AssertMsgFailed((__FUNCTION__": VBoxUsbToolGetDeviceSpeed failed Status (0x%x)\n", Status));
+ break;
+ }
+ }
+#endif
+ Log((__FUNCTION__": strings: '%s':'%s':'%s' (lang ID %x)\n",
+ pDevice->szMfgName, pDevice->szProduct, pDevice->szSerial, langId));
+ }
+
+ Status = STATUS_SUCCESS;
+ } while (0);
+
+ VBoxUsbMonMemFree(pDevDr);
+ return Status;
+}
+
+static void vboxUsbFltSignalChangeLocked()
+{
+ for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.ContextList.Flink;
+ pEntry != &g_VBoxUsbFltGlobals.ContextList;
+ pEntry = pEntry->Flink)
+ {
+ PVBOXUSBFLTCTX pCtx = PVBOXUSBFLTCTX_FROM_LE(pEntry);
+ /* the removed context can not be in a list */
+ Assert(!pCtx->bRemoved);
+ if (pCtx->pChangeEvent)
+ {
+ KeSetEvent(pCtx->pChangeEvent,
+ 0, /* increment*/
+ FALSE /* wait */);
+ }
+ }
+}
+
+static bool vboxUsbFltDevCheckReplugLocked(PVBOXUSBFLT_DEVICE pDevice, PVBOXUSBFLTCTX pContext)
+{
+ Assert(pContext);
+
+ /* check if device is already replugging */
+ if (pDevice->enmState <= VBOXUSBFLT_DEVSTATE_ADDED)
+ {
+ /* it is, do nothing */
+ Assert(pDevice->enmState == VBOXUSBFLT_DEVSTATE_REPLUGGING);
+ return false;
+ }
+
+ if (pDevice->pOwner && pContext != pDevice->pOwner)
+ {
+ /* this device is owned by another context, we're not allowed to do anything */
+ return false;
+ }
+
+ uintptr_t uId = 0;
+ bool bNeedReplug = false;
+ bool fFilter = false;
+ bool fIsOneShot = false;
+ PVBOXUSBFLTCTX pNewOwner = vboxUsbFltDevMatchLocked(pDevice, &uId,
+ false, /* do not remove a one-shot filter */
+ &fFilter, &fIsOneShot);
+ if (pDevice->pOwner && pNewOwner && pDevice->pOwner != pNewOwner)
+ {
+ /* the device is owned by another owner, we can not change the owner here */
+ return false;
+ }
+
+ if (!fFilter)
+ {
+ /* the device should NOT be filtered, check the current state */
+ if (vboxUsbFltDevStateIsNotFiltered(pDevice))
+ {
+ /* no changes */
+ if (fIsOneShot)
+ {
+ Assert(pNewOwner);
+ /* remove a one-shot filter and keep the original filter data */
+ int tmpRc = VBoxUSBFilterRemove(pNewOwner, uId);
+ AssertRC(tmpRc);
+ if (!pDevice->pOwner)
+ {
+ /* update owner for one-shot if the owner is changed (i.e. assigned) */
+ vboxUsbFltDevOwnerUpdateLocked(pDevice, pNewOwner, uId, true);
+ }
+ }
+ else
+ {
+ if (pNewOwner)
+ {
+ vboxUsbFltDevOwnerUpdateLocked(pDevice, pNewOwner, uId, false);
+ }
+ }
+ }
+ else
+ {
+ /* the device is currently filtered, we should release it only if
+ * 1. device does not have an owner
+ * or
+ * 2. it should be released bue to a one-shot filter
+ * or
+ * 3. it is NOT grabbed by a one-shot filter */
+ if (!pDevice->pOwner || fIsOneShot || !pDevice->fIsFilterOneShot)
+ {
+ bNeedReplug = true;
+ }
+ }
+ }
+ else
+ {
+ /* the device should be filtered, check the current state */
+ Assert(uId);
+ Assert(pNewOwner);
+ if (vboxUsbFltDevStateIsFiltered(pDevice))
+ {
+ /* the device is filtered */
+ if (pNewOwner == pDevice->pOwner)
+ {
+ /* no changes */
+ if (fIsOneShot)
+ {
+ /* remove a one-shot filter and keep the original filter data */
+ int tmpRc = VBoxUSBFilterRemove(pNewOwner, uId);
+ AssertRC(tmpRc);
+ }
+ else
+ {
+ vboxUsbFltDevOwnerUpdateLocked(pDevice, pDevice->pOwner, uId, false);
+ }
+ }
+ else
+ {
+ Assert(!pDevice->pOwner);
+ /* the device needs to be filtered, but the owner changes, replug needed */
+ bNeedReplug = true;
+ }
+ }
+ else
+ {
+ /* the device is currently NOT filtered,
+ * we should replug it only if
+ * 1. device does not have an owner
+ * or
+ * 2. it should be captured due to a one-shot filter
+ * or
+ * 3. it is NOT released by a one-shot filter */
+ if (!pDevice->pOwner || fIsOneShot || !pDevice->fIsFilterOneShot)
+ {
+ bNeedReplug = true;
+ }
+ }
+ }
+
+ if (bNeedReplug)
+ {
+ vboxUsbFltDevStateMarkReplugLocked(pDevice);
+ }
+
+ return bNeedReplug;
+}
+
+static void vboxUsbFltReplugList(PLIST_ENTRY pList)
+{
+ PLIST_ENTRY pNext;
+ for (PLIST_ENTRY pEntry = pList->Flink;
+ pEntry != pList;
+ pEntry = pNext)
+ {
+ pNext = pEntry->Flink;
+ PVBOXUSBFLT_DEVICE pDevice = PVBOXUSBFLT_DEVICE_FROM_REPLUGGINGLE(pEntry);
+ Assert(pDevice->enmState == VBOXUSBFLT_DEVSTATE_REPLUGGING
+ || pDevice->enmState == VBOXUSBFLT_DEVSTATE_REMOVED);
+
+ vboxUsbFltPdoReplug(pDevice->Pdo);
+ ObDereferenceObject(pDevice->Pdo);
+ vboxUsbFltDevRelease(pDevice);
+ }
+}
+
+NTSTATUS VBoxUsbFltFilterCheck(PVBOXUSBFLTCTX pContext)
+{
+ NTSTATUS Status;
+ UNICODE_STRING szStandardControllerName[RT_ELEMENTS(lpszStandardControllerName)];
+ KIRQL Irql = KeGetCurrentIrql();
+ Assert(Irql == PASSIVE_LEVEL);
+
+ Log(("==" __FUNCTION__"\n"));
+
+ for (int i=0;i<RT_ELEMENTS(lpszStandardControllerName);i++)
+ {
+ szStandardControllerName[i].Length = 0;
+ szStandardControllerName[i].MaximumLength = 0;
+ szStandardControllerName[i].Buffer = 0;
+
+ RtlInitUnicodeString(&szStandardControllerName[i], lpszStandardControllerName[i]);
+ }
+
+ for (int i = 0; i < 16; i++)
+ {
+ char szHubName[32];
+ WCHAR szwHubName[32];
+ UNICODE_STRING UnicodeName;
+ ANSI_STRING AnsiName;
+ PDEVICE_OBJECT pHubDevObj;
+ PFILE_OBJECT pHubFileObj;
+
+ sprintf(szHubName, "\\Device\\USBPDO-%d", i);
+
+ UnicodeName.Length = 0;
+ UnicodeName.MaximumLength = sizeof (szwHubName);
+ UnicodeName.Buffer = szwHubName;
+
+ RtlInitAnsiString(&AnsiName, szHubName);
+ RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, FALSE);
+
+ Status = IoGetDeviceObjectPointer(&UnicodeName, FILE_READ_DATA, &pHubFileObj, &pHubDevObj);
+ if (Status == STATUS_SUCCESS)
+ {
+ Log(("IoGetDeviceObjectPointer for %s returned %p %p\n", szHubName, pHubDevObj, pHubFileObj));
+
+ if (pHubDevObj->DriverObject
+ && pHubDevObj->DriverObject->DriverName.Buffer
+ && pHubDevObj->DriverObject->DriverName.Length
+ )
+ {
+ for (int j = 0; j < RT_ELEMENTS(lpszStandardControllerName); ++j)
+ {
+ if (!RtlCompareUnicodeString(&szStandardControllerName[j], &pHubDevObj->DriverObject->DriverName, TRUE /* case insensitive */))
+ {
+ PDEVICE_RELATIONS pDevRelations = NULL;
+
+#ifdef DEBUG
+ Log(("Associated driver "));
+ vboxUsbDbgPrintUnicodeString(&pHubDevObj->DriverObject->DriverName);
+ Log((" -> related dev obj=0x%p\n", IoGetRelatedDeviceObject(pHubFileObj)));
+#endif
+
+ Status = VBoxUsbMonQueryBusRelations(pHubDevObj, pHubFileObj, &pDevRelations);
+ if (Status == STATUS_SUCCESS && pDevRelations)
+ {
+ ULONG cReplugPdos = pDevRelations->Count;
+ LIST_ENTRY ReplugDevList;
+ InitializeListHead(&ReplugDevList);
+ for (ULONG k = 0; k < pDevRelations->Count; ++k)
+ {
+ PDEVICE_OBJECT pDevObj = pDevRelations->Objects[k];
+
+ Log(("Found existing USB PDO 0x%p\n", pDevObj));
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ PVBOXUSBFLT_DEVICE pDevice = vboxUsbFltDevGetLocked(pDevObj);
+ if (pDevice)
+ {
+ bool bReplug = vboxUsbFltDevCheckReplugLocked(pDevice, pContext);
+ if (bReplug)
+ {
+ InsertHeadList(&ReplugDevList, &pDevice->RepluggingLe);
+ vboxUsbFltDevRetain(pDevice);
+ /* do not dereference object since we will use it later */
+ }
+ else
+ {
+ ObDereferenceObject(pDevObj);
+ }
+
+ VBOXUSBFLT_LOCK_RELEASE();
+
+ pDevRelations->Objects[k] = NULL;
+ --cReplugPdos;
+ Assert((uint32_t)cReplugPdos < UINT32_MAX/2);
+ continue;
+ }
+ VBOXUSBFLT_LOCK_RELEASE();
+
+ VBOXUSBFLT_DEVICE Device;
+ Status = vboxUsbFltDevPopulate(&Device, pDevObj /*, FALSE /* only need filter properties */);
+ if (NT_SUCCESS(Status))
+ {
+ uintptr_t uId = 0;
+ bool fFilter = false;
+ bool fIsOneShot = false;
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ PVBOXUSBFLTCTX pCtx = vboxUsbFltDevMatchLocked(&Device, &uId,
+ false, /* do not remove a one-shot filter */
+ &fFilter, &fIsOneShot);
+ VBOXUSBFLT_LOCK_RELEASE();
+ if (!fFilter)
+ {
+ /* this device should not be filtered, and it's not */
+ ObDereferenceObject(pDevObj);
+ pDevRelations->Objects[k] = NULL;
+ --cReplugPdos;
+ Assert((uint32_t)cReplugPdos < UINT32_MAX/2);
+ continue;
+ }
+
+ /* this device needs to be filtered, but it's not,
+ * leave the PDO in array to issue a replug request for it
+ * later on */
+
+ }
+ }
+
+ if (cReplugPdos)
+ {
+ for (ULONG k = 0; k < pDevRelations->Count; ++k)
+ {
+ if (!pDevRelations->Objects[k])
+ continue;
+
+ Status = vboxUsbFltPdoReplug(pDevRelations->Objects[k]);
+ Assert(Status == STATUS_SUCCESS);
+ ObDereferenceObject(pDevRelations->Objects[k]);
+ if (!--cReplugPdos)
+ break;
+ }
+
+ Assert(!cReplugPdos);
+ }
+
+ vboxUsbFltReplugList(&ReplugDevList);
+
+ ExFreePool(pDevRelations);
+ }
+ }
+ }
+ }
+ ObDereferenceObject(pHubFileObj);
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS VBoxUsbFltClose(PVBOXUSBFLTCTX pContext)
+{
+ LIST_ENTRY ReplugDevList;
+ InitializeListHead(&ReplugDevList);
+
+ Assert(pContext);
+
+ KIRQL Irql = KeGetCurrentIrql();
+ Assert(Irql == PASSIVE_LEVEL);
+
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ uint32_t cActiveFilters = pContext->cActiveFilters;
+ pContext->bRemoved = TRUE;
+ if (pContext->pChangeEvent)
+ {
+ KeSetEvent(pContext->pChangeEvent,
+ 0, /* increment*/
+ FALSE /* wait */);
+ ObDereferenceObject(pContext->pChangeEvent);
+ pContext->pChangeEvent = NULL;
+ }
+ RemoveEntryList(&pContext->ListEntry);
+
+ /* now re-arrange the filters */
+ /* 1. remove filters */
+ VBoxUSBFilterRemoveOwner(pContext);
+
+ /* 2. check if there are devices owned */
+ for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.DeviceList.Flink;
+ pEntry != &g_VBoxUsbFltGlobals.DeviceList;
+ pEntry = pEntry->Flink)
+ {
+ PVBOXUSBFLT_DEVICE pDevice = PVBOXUSBFLT_DEVICE_FROM_LE(pEntry);
+ if (pDevice->pOwner != pContext)
+ continue;
+
+ Assert(pDevice->enmState != VBOXUSBFLT_DEVSTATE_ADDED);
+ Assert(pDevice->enmState != VBOXUSBFLT_DEVSTATE_REMOVED);
+
+ vboxUsbFltDevOwnerClearLocked(pDevice);
+
+ if (vboxUsbFltDevCheckReplugLocked(pDevice, pContext))
+ {
+ InsertHeadList(&ReplugDevList, &pDevice->RepluggingLe);
+ /* retain to ensure the device is not removed before we issue a replug */
+ vboxUsbFltDevRetain(pDevice);
+ /* keep the PDO alive */
+ ObReferenceObject(pDevice->Pdo);
+ }
+ }
+ VBOXUSBFLT_LOCK_RELEASE();
+
+ /* this should replug all devices that were either skipped or grabbed due to the context's */
+ vboxUsbFltReplugList(&ReplugDevList);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS VBoxUsbFltCreate(PVBOXUSBFLTCTX pContext)
+{
+ memset(pContext, 0, sizeof (*pContext));
+ pContext->Process = RTProcSelf();
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ InsertHeadList(&g_VBoxUsbFltGlobals.ContextList, &pContext->ListEntry);
+ VBOXUSBFLT_LOCK_RELEASE();
+ return STATUS_SUCCESS;
+}
+
+int VBoxUsbFltAdd(PVBOXUSBFLTCTX pContext, PUSBFILTER pFilter, uintptr_t *pId)
+{
+ *pId = 0;
+ /* Log the filter details. */
+ Log((__FUNCTION__": %s %s %s\n",
+ USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) : "<null>",
+ USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) : "<null>",
+ USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) : "<null>"));
+#ifdef DEBUG
+ Log(("VBoxUSBClient::addFilter: idVendor=%#x idProduct=%#x bcdDevice=%#x bDeviceClass=%#x bDeviceSubClass=%#x bDeviceProtocol=%#x bBus=%#x bPort=%#x\n",
+ USBFilterGetNum(pFilter, USBFILTERIDX_VENDOR_ID),
+ USBFilterGetNum(pFilter, USBFILTERIDX_PRODUCT_ID),
+ USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_REV),
+ USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_CLASS),
+ USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_SUB_CLASS),
+ USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_PROTOCOL),
+ USBFilterGetNum(pFilter, USBFILTERIDX_BUS),
+ USBFilterGetNum(pFilter, USBFILTERIDX_PORT)));
+#endif
+
+ /* We can't get the bus/port numbers. Ignore them while matching. */
+ USBFilterSetMustBePresent(pFilter, USBFILTERIDX_BUS, false);
+ USBFilterSetMustBePresent(pFilter, USBFILTERIDX_PORT, false);
+
+ uintptr_t uId = 0;
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ /* Add the filter. */
+ int rc = VBoxUSBFilterAdd(pFilter, pContext, &uId);
+ VBOXUSBFLT_LOCK_RELEASE();
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ {
+ Assert(uId);
+#ifdef VBOX_USBMON_WITH_FILTER_AUTOAPPLY
+ VBoxUsbFltFilterCheck();
+#endif
+ }
+ else
+ {
+ Assert(!uId);
+ }
+
+ *pId = uId;
+ return rc;
+}
+
+int VBoxUsbFltRemove(PVBOXUSBFLTCTX pContext, uintptr_t uId)
+{
+ Assert(uId);
+
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ int rc = VBoxUSBFilterRemove(pContext, uId);
+ if (!RT_SUCCESS(rc))
+ {
+ AssertFailed();
+ VBOXUSBFLT_LOCK_RELEASE();
+ return rc;
+ }
+
+ for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.DeviceList.Flink;
+ pEntry != &g_VBoxUsbFltGlobals.DeviceList;
+ pEntry = pEntry->Flink)
+ {
+ PVBOXUSBFLT_DEVICE pDevice = PVBOXUSBFLT_DEVICE_FROM_LE(pEntry);
+ if (pDevice->fIsFilterOneShot)
+ {
+ Assert(!pDevice->uFltId);
+ }
+
+ if (pDevice->uFltId != uId)
+ continue;
+
+ Assert(pDevice->pOwner == pContext);
+ if (pDevice->pOwner != pContext)
+ continue;
+
+ Assert(!pDevice->fIsFilterOneShot);
+ pDevice->uFltId = 0;
+ /* clear the fIsFilterOneShot flag to ensure the device is replugged on the next VBoxUsbFltFilterCheck call */
+ pDevice->fIsFilterOneShot = false;
+ }
+ VBOXUSBFLT_LOCK_RELEASE();
+
+ if (RT_SUCCESS(rc))
+ {
+#ifdef VBOX_USBMON_WITH_FILTER_AUTOAPPLY
+ VBoxUsbFltFilterCheck();
+#endif
+ }
+ return rc;
+}
+
+NTSTATUS VBoxUsbFltSetNotifyEvent(PVBOXUSBFLTCTX pContext, HANDLE hEvent)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PKEVENT pEvent = NULL;
+ PKEVENT pOldEvent = NULL;
+ if (hEvent)
+ {
+ Status = ObReferenceObjectByHandle(hEvent,
+ EVENT_MODIFY_STATE,
+ *ExEventObjectType, UserMode,
+ (PVOID*)&pEvent,
+ NULL);
+ Assert(Status == STATUS_SUCCESS);
+ if (!NT_SUCCESS(Status))
+ return Status;
+ }
+
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ pOldEvent = pContext->pChangeEvent;
+ pContext->pChangeEvent = pEvent;
+ VBOXUSBFLT_LOCK_RELEASE();
+
+ if (pOldEvent)
+ {
+ ObDereferenceObject(pOldEvent);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static USBDEVICESTATE vboxUsbDevGetUserState(PVBOXUSBFLTCTX pContext, PVBOXUSBFLT_DEVICE pDevice)
+{
+ if (vboxUsbFltDevStateIsNotFiltered(pDevice))
+ return USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
+
+ /* the device is filtered, or replugging */
+ if (pDevice->enmState == VBOXUSBFLT_DEVSTATE_REPLUGGING)
+ {
+ Assert(!pDevice->pOwner);
+ Assert(!pDevice->uFltId);
+ AssertFailed();
+ /* no user state for this, we should not return it tu the user */
+ return USBDEVICESTATE_USED_BY_HOST;
+ }
+
+ /* the device is filtered, if owner differs from the context, return as USED_BY_HOST */
+ Assert(pDevice->pOwner);
+ /* the id can be null if a filter is removed */
+// Assert(pDevice->uFltId);
+
+ if (pDevice->pOwner != pContext)
+ return USBDEVICESTATE_USED_BY_HOST;
+
+ switch (pDevice->enmState)
+ {
+ case VBOXUSBFLT_DEVSTATE_UNCAPTURED:
+ case VBOXUSBFLT_DEVSTATE_CAPTURING:
+ return USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
+ case VBOXUSBFLT_DEVSTATE_CAPTURED:
+ return USBDEVICESTATE_HELD_BY_PROXY;
+ case VBOXUSBFLT_DEVSTATE_USED_BY_GUEST:
+ return USBDEVICESTATE_USED_BY_GUEST;
+ default:
+ AssertFailed();
+ return USBDEVICESTATE_UNSUPPORTED;
+ }
+}
+
+static void vboxUsbDevToUserInfo(PVBOXUSBFLTCTX pContext, PVBOXUSBFLT_DEVICE pDevice, PUSBSUP_DEVINFO pDevInfo)
+{
+#if 0
+ pDevInfo->usVendorId = pDevice->idVendor;
+ pDevInfo->usProductId = pDevice->idProduct;
+ pDevInfo->usRevision = pDevice->bcdDevice;
+ pDevInfo->enmState = vboxUsbDevGetUserState(pContext, pDevice);
+
+ strcpy(pDevInfo->szDrvKeyName, pDevice->szDrvKeyName);
+ if (pDevInfo->enmState == USBDEVICESTATE_HELD_BY_PROXY
+ || pDevInfo->enmState == USBDEVICESTATE_USED_BY_GUEST)
+ {
+ /* this is the only case where we return the obj name to the client */
+ strcpy(pDevInfo->szObjName, pDevice->szObjName);
+ }
+ pDevInfo->fHighSpeed = pDevice->fHighSpeed;
+#endif
+}
+
+NTSTATUS VBoxUsbFltGetDevice(PVBOXUSBFLTCTX pContext, HVBOXUSBDEVUSR hDevice, PUSBSUP_GETDEV_MON pInfo)
+{
+ Assert(hDevice);
+
+ memset (pInfo, 0, sizeof (*pInfo));
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.DeviceList.Flink;
+ pEntry != &g_VBoxUsbFltGlobals.DeviceList;
+ pEntry = pEntry->Flink)
+ {
+ PVBOXUSBFLT_DEVICE pDevice = PVBOXUSBFLT_DEVICE_FROM_LE(pEntry);
+ Assert(pDevice->enmState != VBOXUSBFLT_DEVSTATE_REMOVED);
+ Assert(pDevice->enmState != VBOXUSBFLT_DEVSTATE_ADDED);
+
+ if (pDevice != hDevice)
+ continue;
+
+ USBDEVICESTATE enmUsrState = vboxUsbDevGetUserState(pContext, pDevice);
+ pInfo->enmState = enmUsrState;
+ VBOXUSBFLT_LOCK_RELEASE();
+ return STATUS_SUCCESS;
+ }
+
+ VBOXUSBFLT_LOCK_RELEASE();
+
+ /* this should not occur */
+ AssertFailed();
+
+ return STATUS_INVALID_PARAMETER;
+}
+
+NTSTATUS VBoxUsbFltPdoAdd(PDEVICE_OBJECT pPdo, BOOLEAN *pbFiltered)
+{
+ *pbFiltered = FALSE;
+ PVBOXUSBFLT_DEVICE pDevice;
+
+ /* first check if device is in the a already */
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ pDevice = vboxUsbFltDevGetLocked(pPdo);
+ if (pDevice)
+ {
+ Assert(pDevice->enmState != VBOXUSBFLT_DEVSTATE_ADDED);
+ Assert(pDevice->enmState != VBOXUSBFLT_DEVSTATE_REMOVED);
+ *pbFiltered = pDevice->enmState >= VBOXUSBFLT_DEVSTATE_CAPTURING;
+ VBOXUSBFLT_LOCK_RELEASE();
+ return STATUS_SUCCESS;
+ }
+ VBOXUSBFLT_LOCK_RELEASE();
+ pDevice = (PVBOXUSBFLT_DEVICE)VBoxUsbMonMemAllocZ(sizeof (*pDevice));
+ if (!pDevice)
+ {
+ AssertFailed();
+ return STATUS_NO_MEMORY;
+ }
+
+ pDevice->enmState = VBOXUSBFLT_DEVSTATE_ADDED;
+ pDevice->cRefs = 1;
+ NTSTATUS Status = vboxUsbFltDevPopulate(pDevice, pPdo /* , TRUE /* need all props */);
+ if (!NT_SUCCESS(Status))
+ {
+ AssertFailed();
+ VBoxUsbMonMemFree(pDevice);
+ return Status;
+ }
+
+ uintptr_t uId;
+ bool fFilter = false;
+ bool fIsOneShot = false;
+ PVBOXUSBFLTCTX pCtx;
+ PVBOXUSBFLT_DEVICE pTmpDev;
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ /* (paranoia) re-check the device is still not here */
+ pTmpDev = vboxUsbFltDevGetLocked(pPdo);
+ if (pTmpDev)
+ {
+ Assert(pTmpDev->enmState != VBOXUSBFLT_DEVSTATE_ADDED);
+ Assert(pTmpDev->enmState != VBOXUSBFLT_DEVSTATE_REMOVED);
+ *pbFiltered = pTmpDev->enmState >= VBOXUSBFLT_DEVSTATE_CAPTURING;
+ VBOXUSBFLT_LOCK_RELEASE();
+ VBoxUsbMonMemFree(pDevice);
+ return STATUS_SUCCESS;
+ }
+
+ pCtx = vboxUsbFltDevMatchLocked(pDevice, &uId,
+ true, /* remove a one-shot filter */
+ &fFilter, &fIsOneShot);
+ if (fFilter)
+ {
+ Assert(pCtx);
+ Assert(uId);
+ pDevice->enmState = VBOXUSBFLT_DEVSTATE_CAPTURING;
+ }
+ else
+ {
+ Assert(!uId == !pCtx); /* either both zero or both not */
+ pDevice->enmState = VBOXUSBFLT_DEVSTATE_UNCAPTURED;
+ }
+
+ if (pCtx)
+ vboxUsbFltDevOwnerSetLocked(pDevice, pCtx, fIsOneShot ? 0 : uId, fIsOneShot);
+
+ InsertHeadList(&g_VBoxUsbFltGlobals.DeviceList, &pDevice->GlobalLe);
+
+ /* do not need to signal anything here -
+ * going to do that once the proxy device object starts */
+ VBOXUSBFLT_LOCK_RELEASE();
+
+ *pbFiltered = fFilter;
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS VBoxUsbFltPdoAddCompleted(PDEVICE_OBJECT pPdo)
+{
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ vboxUsbFltSignalChangeLocked();
+ VBOXUSBFLT_LOCK_RELEASE();
+ return STATUS_SUCCESS;
+}
+
+BOOLEAN VBoxUsbFltPdoIsFiltered(PDEVICE_OBJECT pPdo)
+{
+ VBOXUSBFLT_DEVSTATE enmState = VBOXUSBFLT_DEVSTATE_REMOVED;
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ PVBOXUSBFLT_DEVICE pDevice = vboxUsbFltDevGetLocked(pPdo);
+ if (pDevice)
+ {
+ enmState = pDevice->enmState;
+ }
+ VBOXUSBFLT_LOCK_RELEASE();
+
+ return enmState >= VBOXUSBFLT_DEVSTATE_CAPTURING;
+}
+
+NTSTATUS VBoxUsbFltPdoRemove(PDEVICE_OBJECT pPdo)
+{
+ PVBOXUSBFLT_DEVICE pDevice;
+ VBOXUSBFLT_DEVSTATE enmOldState;
+
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ pDevice = vboxUsbFltDevGetLocked(pPdo);
+ if (pDevice)
+ {
+ RemoveEntryList(&pDevice->GlobalLe);
+ enmOldState = pDevice->enmState;
+ pDevice->enmState = VBOXUSBFLT_DEVSTATE_REMOVED;
+ if (enmOldState != VBOXUSBFLT_DEVSTATE_REPLUGGING)
+ {
+ vboxUsbFltSignalChangeLocked();
+ }
+ else
+ {
+ /* the device *should* reappear, do signlling on re-appear only
+ * to avoid extra signaling. still there might be a situation
+ * when the device will not re-appear if it gets physically removed
+ * before it re-appears
+ * @todo: set a timer callback to do a notification from it */
+ }
+ }
+ VBOXUSBFLT_LOCK_RELEASE();
+ if (pDevice)
+ vboxUsbFltDevRelease(pDevice);
+ return STATUS_SUCCESS;
+}
+
+HVBOXUSBFLTDEV VBoxUsbFltProxyStarted(PDEVICE_OBJECT pPdo)
+{
+ PVBOXUSBFLT_DEVICE pDevice;
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ pDevice = vboxUsbFltDevGetLocked(pPdo);
+ if (pDevice->enmState = VBOXUSBFLT_DEVSTATE_CAPTURING)
+ {
+ pDevice->enmState = VBOXUSBFLT_DEVSTATE_CAPTURED;
+ vboxUsbFltDevRetain(pDevice);
+ vboxUsbFltSignalChangeLocked();
+ }
+ else
+ {
+ AssertFailed();
+ pDevice = NULL;
+ }
+ VBOXUSBFLT_LOCK_RELEASE();
+ return pDevice;
+}
+
+void VBoxUsbFltProxyStopped(HVBOXUSBFLTDEV hDev)
+{
+ PVBOXUSBFLT_DEVICE pDevice = (PVBOXUSBFLT_DEVICE)hDev;
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ if (pDevice->enmState == VBOXUSBFLT_DEVSTATE_CAPTURED
+ || pDevice->enmState == VBOXUSBFLT_DEVSTATE_USED_BY_GUEST)
+ {
+ /* this is due to devie was physically removed */
+ Log(("The proxy notified progy stop for the captured device 0x%x\n", pDevice));
+ pDevice->enmState = VBOXUSBFLT_DEVSTATE_CAPTURING;
+ vboxUsbFltSignalChangeLocked();
+ }
+ else
+ {
+ Assert(pDevice->enmState == VBOXUSBFLT_DEVSTATE_REPLUGGING);
+ }
+ VBOXUSBFLT_LOCK_RELEASE();
+
+ vboxUsbFltDevRelease(pDevice);
+}
+
+NTSTATUS VBoxUsbFltInit()
+{
+ int rc = VBoxUSBFilterInit();
+ AssertRC(rc);
+ if (RT_FAILURE(rc))
+ return STATUS_UNSUCCESSFUL;
+
+ memset(&g_VBoxUsbFltGlobals, 0, sizeof (g_VBoxUsbFltGlobals));
+ InitializeListHead(&g_VBoxUsbFltGlobals.DeviceList);
+ InitializeListHead(&g_VBoxUsbFltGlobals.ContextList);
+ InitializeListHead(&g_VBoxUsbFltGlobals.BlackDeviceList);
+ vboxUsbFltBlDevPopulateWithKnownLocked();
+ VBOXUSBFLT_LOCK_INIT();
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS VBoxUsbFltTerm()
+{
+ bool bBusy = false;
+ VBOXUSBFLT_LOCK_ACQUIRE();
+ do
+ {
+ if (!IsListEmpty(&g_VBoxUsbFltGlobals.ContextList))
+ {
+ AssertFailed();
+ bBusy = true;
+ break;
+ }
+
+ PLIST_ENTRY pNext = NULL;
+ for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.DeviceList.Flink;
+ pEntry != &g_VBoxUsbFltGlobals.DeviceList;
+ pEntry = pNext)
+ {
+ pNext = pEntry->Flink;
+ PVBOXUSBFLT_DEVICE pDevice = PVBOXUSBFLT_DEVICE_FROM_LE(pEntry);
+ Assert(!pDevice->uFltId);
+ Assert(!pDevice->pOwner);
+ if (pDevice->cRefs != 1)
+ {
+ AssertFailed();
+ bBusy = true;
+ break;
+ }
+ }
+ } while (0);
+
+ VBOXUSBFLT_LOCK_RELEASE()
+
+ if (bBusy)
+ {
+ return STATUS_DEVICE_BUSY;
+ }
+
+ for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.DeviceList.Flink;
+ pEntry != &g_VBoxUsbFltGlobals.DeviceList;
+ pEntry = g_VBoxUsbFltGlobals.DeviceList.Flink)
+ {
+ RemoveEntryList(pEntry);
+ PVBOXUSBFLT_DEVICE pDevice = PVBOXUSBFLT_DEVICE_FROM_LE(pEntry);
+ pDevice->enmState = VBOXUSBFLT_DEVSTATE_REMOVED;
+ vboxUsbFltDevRelease(pDevice);
+ }
+
+ vboxUsbFltBlDevClearLocked();
+
+ VBOXUSBFLT_LOCK_TERM();
+
+ VBoxUSBFilterTerm();
+
+ return STATUS_SUCCESS;
+}
+
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.h b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.h
new file mode 100644
index 000000000..8016c7e7e
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.h
@@ -0,0 +1,53 @@
+/* $Id: VBoxUsbFlt.h 36998 2011-05-07 20:19:55Z vboxsync $ */
+/** @file
+ * VBox USB Monitor Device Filtering functionality
+ */
+/*
+ * 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 ___VBoxUsbFlt_h___
+#define ___VBoxUsbFlt_h___
+
+#include "VBoxUsbMon.h"
+#include <VBoxUSBFilterMgr.h>
+
+#include <VBox/usblib-win.h>
+
+typedef struct VBOXUSBFLTCTX
+{
+ LIST_ENTRY ListEntry;
+ PKEVENT pChangeEvent;
+ RTPROCESS Process;
+ uint32_t cActiveFilters;
+ BOOLEAN bRemoved;
+} VBOXUSBFLTCTX, *PVBOXUSBFLTCTX;
+
+NTSTATUS VBoxUsbFltInit();
+NTSTATUS VBoxUsbFltTerm();
+NTSTATUS VBoxUsbFltCreate(PVBOXUSBFLTCTX pContext);
+NTSTATUS VBoxUsbFltClose(PVBOXUSBFLTCTX pContext);
+int VBoxUsbFltAdd(PVBOXUSBFLTCTX pContext, PUSBFILTER pFilter, uintptr_t *pId);
+int VBoxUsbFltRemove(PVBOXUSBFLTCTX pContext, uintptr_t uId);
+NTSTATUS VBoxUsbFltSetNotifyEvent(PVBOXUSBFLTCTX pContext, HANDLE hEvent);
+NTSTATUS VBoxUsbFltFilterCheck(PVBOXUSBFLTCTX pContext);
+
+NTSTATUS VBoxUsbFltGetDevice(PVBOXUSBFLTCTX pContext, HVBOXUSBDEVUSR hDevice, PUSBSUP_GETDEV_MON pInfo);
+
+typedef void* HVBOXUSBFLTDEV;
+HVBOXUSBFLTDEV VBoxUsbFltProxyStarted(PDEVICE_OBJECT pPdo);
+void VBoxUsbFltProxyStopped(HVBOXUSBFLTDEV hDev);
+
+NTSTATUS VBoxUsbFltPdoAdd(PDEVICE_OBJECT pPdo, BOOLEAN *pbFiltered);
+NTSTATUS VBoxUsbFltPdoAddCompleted(PDEVICE_OBJECT pPdo);
+NTSTATUS VBoxUsbFltPdoRemove(PDEVICE_OBJECT pPdo);
+BOOLEAN VBoxUsbFltPdoIsFiltered(PDEVICE_OBJECT pPdo);
+
+#endif /* #ifndef ___VBoxUsbFlt_h___ */
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbHook.cpp b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbHook.cpp
new file mode 100644
index 000000000..0fe7b22dd
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbHook.cpp
@@ -0,0 +1,186 @@
+/* $Id: VBoxUsbHook.cpp 37083 2011-05-13 19:24:39Z vboxsync $ */
+/** @file
+ * Driver Dispatch Table Hooking API
+ */
+/*
+ * 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.
+ */
+#include "VBoxUsbMon.h"
+
+#define VBOXUSBHOOK_MEMTAG 'HUBV'
+
+NTSTATUS VBoxUsbHookInstall(PVBOXUSBHOOK_ENTRY pHook)
+{
+ KIRQL Irql;
+ KeAcquireSpinLock(&pHook->Lock, &Irql);
+ if (pHook->fIsInstalled)
+ {
+ AssertFailed();
+ KeReleaseSpinLock(&pHook->Lock, Irql);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ pHook->pfnOldHandler = (PDRIVER_DISPATCH)InterlockedExchangePointer((PVOID*)&pHook->pDrvObj->MajorFunction[pHook->iMjFunction], pHook->pfnHook);
+ Assert(pHook->pfnOldHandler);
+ Assert(pHook->pfnHook != pHook->pfnOldHandler);
+ pHook->fIsInstalled = TRUE;
+ KeReleaseSpinLock(&pHook->Lock, Irql);
+ return STATUS_SUCCESS;
+
+}
+NTSTATUS VBoxUsbHookUninstall(PVBOXUSBHOOK_ENTRY pHook)
+{
+ KIRQL Irql;
+ KeAcquireSpinLock(&pHook->Lock, &Irql);
+ if (!pHook->fIsInstalled)
+ {
+ KeReleaseSpinLock(&pHook->Lock, Irql);
+ return STATUS_SUCCESS;
+ }
+
+ PDRIVER_DISPATCH pfnOldVal = (PDRIVER_DISPATCH)InterlockedCompareExchangePointer((PVOID*)&pHook->pDrvObj->MajorFunction[pHook->iMjFunction], pHook->pfnOldHandler, pHook->pfnHook);
+ Assert(pfnOldVal == pHook->pfnHook);
+ if (pfnOldVal != pHook->pfnHook)
+ {
+ AssertMsgFailed(("unhook failed!!!\n"));
+ /* this is bad! this could happen if someone else has chained another hook,
+ * or (which is even worse) restored the "initial" entry value it saved when doing a hooking before us
+ * return the failure and don't do anything else
+ * the best thing to do if this happens is to leave everything as is
+ * and to prevent the driver from being unloaded to ensure no one references our unloaded hook routine */
+ KeReleaseSpinLock(&pHook->Lock, Irql);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ pHook->fIsInstalled = FALSE;
+ KeReleaseSpinLock(&pHook->Lock, Irql);
+
+ /* wait for the current handlers to exit */
+ VBoxDrvToolRefWaitEqual(&pHook->HookRef, 1);
+
+ return STATUS_SUCCESS;
+}
+
+BOOLEAN VBoxUsbHookIsInstalled(PVBOXUSBHOOK_ENTRY pHook)
+{
+ KIRQL Irql;
+ BOOLEAN fIsInstalled;
+ KeAcquireSpinLock(&pHook->Lock, &Irql);
+ fIsInstalled = pHook->fIsInstalled;
+ KeReleaseSpinLock(&pHook->Lock, Irql);
+ return fIsInstalled;
+}
+
+VOID VBoxUsbHookInit(PVBOXUSBHOOK_ENTRY pHook, PDRIVER_OBJECT pDrvObj, UCHAR iMjFunction, PDRIVER_DISPATCH pfnHook)
+{
+ Assert(pDrvObj);
+ Assert(iMjFunction <= IRP_MJ_MAXIMUM_FUNCTION);
+ Assert(pfnHook);
+ memset(pHook, 0, sizeof (*pHook));
+ InitializeListHead(&pHook->RequestList);
+ KeInitializeSpinLock(&pHook->Lock);
+ VBoxDrvToolRefInit(&pHook->HookRef);
+ pHook->pDrvObj = pDrvObj;
+ pHook->iMjFunction = iMjFunction;
+ pHook->pfnHook = pfnHook;
+ Assert(!pHook->pfnOldHandler);
+ Assert(!pHook->fIsInstalled);
+
+}
+
+static void vboxUsbHookRequestRegisterCompletion(PVBOXUSBHOOK_ENTRY pHook, PDEVICE_OBJECT pDevObj, PIRP pIrp, PIO_COMPLETION_ROUTINE pfnCompletion, PVBOXUSBHOOK_REQUEST pRequest)
+{
+ Assert(pfnCompletion);
+ Assert(pRequest);
+ Assert(pDevObj);
+ Assert(pIrp);
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ memset(pRequest, 0, sizeof (*pRequest));
+ pRequest->pHook = pHook;
+ pRequest->OldLocation = *pSl;
+ pRequest->pDevObj = pDevObj;
+ pRequest->pIrp = pIrp;
+ pRequest->bCompletionStopped = FALSE;
+ pSl->CompletionRoutine = pfnCompletion;
+ pSl->Context = pRequest;
+ pSl->Control = SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR | SL_INVOKE_ON_CANCEL;
+
+ KIRQL oldIrql;
+ KeAcquireSpinLock(&pHook->Lock, &oldIrql);
+ InsertTailList(&pHook->RequestList, &pRequest->ListEntry);
+ KeReleaseSpinLock(&pHook->Lock, oldIrql);
+}
+
+NTSTATUS VBoxUsbHookRequestPassDownHookCompletion(PVBOXUSBHOOK_ENTRY pHook, PDEVICE_OBJECT pDevObj, PIRP pIrp, PIO_COMPLETION_ROUTINE pfnCompletion, PVBOXUSBHOOK_REQUEST pRequest)
+{
+ Assert(pfnCompletion);
+ vboxUsbHookRequestRegisterCompletion(pHook, pDevObj, pIrp, pfnCompletion, pRequest);
+ return pHook->pfnOldHandler(pDevObj, pIrp);
+}
+
+NTSTATUS VBoxUsbHookRequestPassDownHookSkip(PVBOXUSBHOOK_ENTRY pHook, PDEVICE_OBJECT pDevObj, PIRP pIrp)
+{
+ return pHook->pfnOldHandler(pDevObj, pIrp);
+}
+
+NTSTATUS VBoxUsbHookRequestMoreProcessingRequired(PVBOXUSBHOOK_ENTRY pHook, PDEVICE_OBJECT pDevObj, PIRP pIrp, PVBOXUSBHOOK_REQUEST pRequest)
+{
+ Assert(!pRequest->bCompletionStopped);
+ pRequest->bCompletionStopped = TRUE;
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS VBoxUsbHookRequestComplete(PVBOXUSBHOOK_ENTRY pHook, PDEVICE_OBJECT pDevObj, PIRP pIrp, PVBOXUSBHOOK_REQUEST pRequest)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (pRequest->OldLocation.CompletionRoutine && pRequest->OldLocation.Control)
+ {
+ Status = pRequest->OldLocation.CompletionRoutine(pDevObj, pIrp, pRequest->OldLocation.Context);
+ }
+
+ if (Status != STATUS_MORE_PROCESSING_REQUIRED)
+ {
+ if (pRequest->bCompletionStopped)
+ {
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ }
+ }
+ /*
+ * else - in case driver returned STATUS_MORE_PROCESSING_REQUIRED,
+ * it will call IoCompleteRequest itself
+ */
+
+ KIRQL oldIrql;
+ KeAcquireSpinLock(&pHook->Lock, &oldIrql);
+ RemoveEntryList(&pRequest->ListEntry);
+ KeReleaseSpinLock(&pHook->Lock, oldIrql);
+ return Status;
+}
+
+#define PVBOXUSBHOOK_REQUEST_FROM_LE(_pLe) ( (PVBOXUSBHOOK_REQUEST)( ((uint8_t*)(_pLe)) - RT_OFFSETOF(VBOXUSBHOOK_REQUEST, ListEntry) ) )
+
+VOID VBoxUsbHookVerifyCompletion(PVBOXUSBHOOK_ENTRY pHook, PVBOXUSBHOOK_REQUEST pRequest, PIRP pIrp)
+{
+ KIRQL oldIrql;
+ KeAcquireSpinLock(&pHook->Lock, &oldIrql);
+ for (PLIST_ENTRY pLe = pHook->RequestList.Flink; pLe != &pHook->RequestList; pLe = pLe->Flink)
+ {
+ PVBOXUSBHOOK_REQUEST pCur = PVBOXUSBHOOK_REQUEST_FROM_LE(pLe);
+ if (pCur != pRequest)
+ continue;
+ if (pCur->pIrp != pIrp)
+ continue;
+ AssertFailed();
+ }
+ KeReleaseSpinLock(&pHook->Lock, oldIrql);
+
+}
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbHook.h b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbHook.h
new file mode 100644
index 000000000..f34c6d8cb
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbHook.h
@@ -0,0 +1,74 @@
+/* $Id: VBoxUsbHook.h 37042 2011-05-11 19:04:07Z vboxsync $ */
+/** @file
+ * Driver Dispatch Table Hooking API impl
+ */
+/*
+ * 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 ___VBoxUsbHook_h___
+#define ___VBoxUsbHook_h___
+
+#include "VBoxUsbMon.h"
+
+typedef struct VBOXUSBHOOK_ENTRY
+{
+ LIST_ENTRY RequestList;
+ KSPIN_LOCK Lock;
+ BOOLEAN fIsInstalled;
+ PDRIVER_DISPATCH pfnOldHandler;
+ VBOXDRVTOOL_REF HookRef;
+ PDRIVER_OBJECT pDrvObj;
+ UCHAR iMjFunction;
+ PDRIVER_DISPATCH pfnHook;
+} VBOXUSBHOOK_ENTRY, *PVBOXUSBHOOK_ENTRY;
+
+typedef struct VBOXUSBHOOK_REQUEST
+{
+ LIST_ENTRY ListEntry;
+ PVBOXUSBHOOK_ENTRY pHook;
+ IO_STACK_LOCATION OldLocation;
+ PDEVICE_OBJECT pDevObj;
+ PIRP pIrp;
+ BOOLEAN bCompletionStopped;
+} VBOXUSBHOOK_REQUEST, *PVBOXUSBHOOK_REQUEST;
+
+DECLINLINE(BOOLEAN) VBoxUsbHookRetain(PVBOXUSBHOOK_ENTRY pHook)
+{
+ KIRQL Irql;
+ KeAcquireSpinLock(&pHook->Lock, &Irql);
+ if (!pHook->fIsInstalled)
+ {
+ KeReleaseSpinLock(&pHook->Lock, Irql);
+ return FALSE;
+ }
+
+ VBoxDrvToolRefRetain(&pHook->HookRef);
+ KeReleaseSpinLock(&pHook->Lock, Irql);
+ return TRUE;
+}
+
+DECLINLINE(VOID) VBoxUsbHookRelease(PVBOXUSBHOOK_ENTRY pHook)
+{
+ VBoxDrvToolRefRelease(&pHook->HookRef);
+}
+
+VOID VBoxUsbHookInit(PVBOXUSBHOOK_ENTRY pHook, PDRIVER_OBJECT pDrvObj, UCHAR iMjFunction, PDRIVER_DISPATCH pfnHook);
+NTSTATUS VBoxUsbHookInstall(PVBOXUSBHOOK_ENTRY pHook);
+NTSTATUS VBoxUsbHookUninstall(PVBOXUSBHOOK_ENTRY pHook);
+BOOLEAN VBoxUsbHookIsInstalled(PVBOXUSBHOOK_ENTRY pHook);
+NTSTATUS VBoxUsbHookRequestPassDownHookCompletion(PVBOXUSBHOOK_ENTRY pHook, PDEVICE_OBJECT pDevObj, PIRP pIrp, PIO_COMPLETION_ROUTINE pfnCompletion, PVBOXUSBHOOK_REQUEST pRequest);
+NTSTATUS VBoxUsbHookRequestPassDownHookSkip(PVBOXUSBHOOK_ENTRY pHook, PDEVICE_OBJECT pDevObj, PIRP pIrp);
+NTSTATUS VBoxUsbHookRequestMoreProcessingRequired(PVBOXUSBHOOK_ENTRY pHook, PDEVICE_OBJECT pDevObj, PIRP pIrp, PVBOXUSBHOOK_REQUEST pRequest);
+NTSTATUS VBoxUsbHookRequestComplete(PVBOXUSBHOOK_ENTRY pHook, PDEVICE_OBJECT pDevObj, PIRP pIrp, PVBOXUSBHOOK_REQUEST pRequest);
+VOID VBoxUsbHookVerifyCompletion(PVBOXUSBHOOK_ENTRY pHook, PVBOXUSBHOOK_REQUEST pRequest, PIRP pIrp);
+
+#endif /* #ifndef ___VBoxUsbHook_h___ */
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.cpp b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.cpp
new file mode 100644
index 000000000..0fab88b5a
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.cpp
@@ -0,0 +1,1262 @@
+/* $Id: VBoxUsbMon.cpp 37757 2011-07-04 10:44:53Z vboxsync $ */
+/** @file
+ * VBox USB Monitor
+ */
+/*
+ * 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.
+ */
+
+#include "VBoxUsbMon.h"
+#include "../cmn/VBoxUsbIdc.h"
+#include <vbox/err.h>
+#include <VBox/usblib.h>
+#include <excpt.h>
+#include <stdio.h>
+
+/*
+ * Note: Must match the VID & PID in the USB driver .inf file!!
+ */
+/*
+ BusQueryDeviceID USB\Vid_80EE&Pid_CAFE
+ BusQueryInstanceID 2
+ BusQueryHardwareIDs USB\Vid_80EE&Pid_CAFE&Rev_0100
+ BusQueryHardwareIDs USB\Vid_80EE&Pid_CAFE
+ BusQueryCompatibleIDs USB\Class_ff&SubClass_00&Prot_00
+ BusQueryCompatibleIDs USB\Class_ff&SubClass_00
+ BusQueryCompatibleIDs USB\Class_ff
+*/
+
+#define szBusQueryDeviceId L"USB\\Vid_80EE&Pid_CAFE"
+#define szBusQueryHardwareIDs L"USB\\Vid_80EE&Pid_CAFE&Rev_0100\0USB\\Vid_80EE&Pid_CAFE\0\0"
+#define szBusQueryCompatibleIDs L"USB\\Class_ff&SubClass_00&Prot_00\0USB\\Class_ff&SubClass_00\0USB\\Class_ff\0\0"
+
+#define szDeviceTextDescription L"VirtualBox USB"
+
+typedef struct VBOXUSBMONINS
+{
+ void * pvDummy;
+} VBOXUSBMONINS, *PVBOXUSBMONINS;
+
+typedef struct VBOXUSBMONCTX
+{
+ VBOXUSBFLTCTX FltCtx;
+} VBOXUSBMONCTX, *PVBOXUSBMONCTX;
+
+typedef struct VBOXUSBHUB_PNPHOOK
+{
+ VBOXUSBHOOK_ENTRY Hook;
+ bool fUninitFailed;
+} VBOXUSBHUB_PNPHOOK, *PVBOXUSBHUB_PNPHOOK;
+
+typedef struct VBOXUSBHUB_PNPHOOK_COMPLETION
+{
+ VBOXUSBHOOK_REQUEST Rq;
+} VBOXUSBHUB_PNPHOOK_COMPLETION, *PVBOXUSBHUB_PNPHOOK_COMPLETION;
+
+typedef struct VBOXUSBMONGLOBALS
+{
+ PDEVICE_OBJECT pDevObj;
+ VBOXUSBHUB_PNPHOOK UsbHubPnPHook;
+ KEVENT OpenSynchEvent;
+ IO_REMOVE_LOCK RmLock;
+ uint32_t cOpens;
+ volatile LONG ulPreventUnloadOn;
+ PFILE_OBJECT pPreventUnloadFileObj;
+} VBOXUSBMONGLOBALS, *PVBOXUSBMONGLOBALS;
+
+static VBOXUSBMONGLOBALS g_VBoxUsbMonGlobals;
+
+#define VBOXUSBMON_MEMTAG 'MUBV'
+
+PVOID VBoxUsbMonMemAlloc(SIZE_T cbBytes)
+{
+ PVOID pvMem = ExAllocatePoolWithTag(NonPagedPool, cbBytes, VBOXUSBMON_MEMTAG);
+ Assert(pvMem);
+ return pvMem;
+}
+
+PVOID VBoxUsbMonMemAllocZ(SIZE_T cbBytes)
+{
+ PVOID pvMem = VBoxUsbMonMemAlloc(cbBytes);
+ if (pvMem)
+ {
+ RtlZeroMemory(pvMem, cbBytes);
+ }
+ return pvMem;
+}
+
+VOID VBoxUsbMonMemFree(PVOID pvMem)
+{
+ ExFreePoolWithTag(pvMem, VBOXUSBMON_MEMTAG);
+}
+
+#define VBOXUSBDBG_STRCASE(_t) \
+ case _t: return #_t
+#define VBOXUSBDBG_STRCASE_UNKNOWN(_v) \
+ default: Log((__FUNCTION__": Unknown Value (0n%d), (0x%x)\n", _v, _v)); return "Unknown"
+
+static const char* vboxUsbDbgStrPnPMn(UCHAR uMn)
+{
+ switch (uMn)
+ {
+ VBOXUSBDBG_STRCASE(IRP_MN_START_DEVICE);
+ VBOXUSBDBG_STRCASE(IRP_MN_QUERY_REMOVE_DEVICE);
+ VBOXUSBDBG_STRCASE(IRP_MN_REMOVE_DEVICE);
+ VBOXUSBDBG_STRCASE(IRP_MN_CANCEL_REMOVE_DEVICE);
+ VBOXUSBDBG_STRCASE(IRP_MN_STOP_DEVICE);
+ VBOXUSBDBG_STRCASE(IRP_MN_QUERY_STOP_DEVICE);
+ VBOXUSBDBG_STRCASE(IRP_MN_CANCEL_STOP_DEVICE);
+ VBOXUSBDBG_STRCASE(IRP_MN_QUERY_DEVICE_RELATIONS);
+ VBOXUSBDBG_STRCASE(IRP_MN_QUERY_INTERFACE);
+ VBOXUSBDBG_STRCASE(IRP_MN_QUERY_CAPABILITIES);
+ VBOXUSBDBG_STRCASE(IRP_MN_QUERY_RESOURCES);
+ VBOXUSBDBG_STRCASE(IRP_MN_QUERY_RESOURCE_REQUIREMENTS);
+ VBOXUSBDBG_STRCASE(IRP_MN_QUERY_DEVICE_TEXT);
+ VBOXUSBDBG_STRCASE(IRP_MN_FILTER_RESOURCE_REQUIREMENTS);
+ VBOXUSBDBG_STRCASE(IRP_MN_READ_CONFIG);
+ VBOXUSBDBG_STRCASE(IRP_MN_WRITE_CONFIG);
+ VBOXUSBDBG_STRCASE(IRP_MN_EJECT);
+ VBOXUSBDBG_STRCASE(IRP_MN_SET_LOCK);
+ VBOXUSBDBG_STRCASE(IRP_MN_QUERY_ID);
+ VBOXUSBDBG_STRCASE(IRP_MN_QUERY_PNP_DEVICE_STATE);
+ VBOXUSBDBG_STRCASE(IRP_MN_QUERY_BUS_INFORMATION);
+ VBOXUSBDBG_STRCASE(IRP_MN_DEVICE_USAGE_NOTIFICATION);
+ VBOXUSBDBG_STRCASE(IRP_MN_SURPRISE_REMOVAL);
+ VBOXUSBDBG_STRCASE_UNKNOWN(uMn);
+ }
+}
+
+void vboxUsbDbgPrintUnicodeString(PUNICODE_STRING pUnicodeString)
+{
+ PWSTR pStr = pUnicodeString->Buffer;
+ for (int i = 0; i < pUnicodeString->Length/2; ++i)
+ {
+ Log(("%c", *pStr++));
+ }
+}
+
+/**
+ * Send IRP_MN_QUERY_DEVICE_RELATIONS
+ *
+ * @returns NT Status
+ * @param pDevObj USB device pointer
+ * @param pFileObj Valid file object pointer
+ * @param pDevRelations Pointer to DEVICE_RELATIONS pointer (out)
+ */
+NTSTATUS VBoxUsbMonQueryBusRelations(PDEVICE_OBJECT pDevObj, PFILE_OBJECT pFileObj, PDEVICE_RELATIONS *pDevRelations)
+{
+ IO_STATUS_BLOCK IoStatus;
+ KEVENT Event;
+ NTSTATUS Status;
+ PIRP pIrp;
+ PIO_STACK_LOCATION pSl;
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ Assert(pDevRelations);
+ *pDevRelations = NULL;
+
+ pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, pDevObj, NULL, 0, NULL, &Event, &IoStatus);
+ if (!pIrp)
+ {
+ AssertMsgFailed(("IoBuildDeviceIoControlRequest failed!!\n"));
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+ pSl = IoGetNextIrpStackLocation(pIrp);
+ pSl->MajorFunction = IRP_MJ_PNP;
+ pSl->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
+ pSl->Parameters.QueryDeviceRelations.Type = BusRelations;
+ pSl->FileObject = pFileObj;
+
+ Status = IoCallDriver(pDevObj, pIrp);
+ if (Status == STATUS_PENDING)
+ {
+ Log(("IoCallDriver returned STATUS_PENDING!!\n"));
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Status = IoStatus.Status;
+ }
+
+ if (Status == STATUS_SUCCESS)
+ {
+ PDEVICE_RELATIONS pRel = (PDEVICE_RELATIONS)IoStatus.Information;
+ Log(("pRel = %p\n", pRel));
+ if (VALID_PTR(pRel))
+ {
+ *pDevRelations = pRel;
+ }
+ else
+ Log(("Invalid pointer %p\n", pRel));
+ }
+
+ Log(("IoCallDriver returned %x\n", Status));
+ return Status;
+}
+
+static PDRIVER_OBJECT vboxUsbMonHookFindHubDrvObj()
+{
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+ UNICODE_STRING szStandardHubName;
+ PDRIVER_OBJECT pDrvObj = NULL;
+ szStandardHubName.Length = 0;
+ szStandardHubName.MaximumLength = 0;
+ szStandardHubName.Buffer = 0;
+ RtlInitUnicodeString(&szStandardHubName, L"\\Driver\\usbhub");
+
+ Log(("Search USB hub\n"));
+ for (int i = 0; i < 16; i++)
+ {
+ WCHAR szwHubName[32];
+ char szHubName[32];
+ ANSI_STRING AnsiName;
+ UNICODE_STRING UnicodeName;
+ PDEVICE_OBJECT pHubDevObj;
+ PFILE_OBJECT pHubFileObj;
+
+ sprintf(szHubName, "\\Device\\USBPDO-%d", i);
+
+ RtlInitAnsiString(&AnsiName, szHubName);
+
+ UnicodeName.Length = 0;
+ UnicodeName.MaximumLength = sizeof (szwHubName);
+ UnicodeName.Buffer = szwHubName;
+
+ RtlInitAnsiString(&AnsiName, szHubName);
+ Status = RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, FALSE);
+ if (Status == STATUS_SUCCESS)
+ {
+ Status = IoGetDeviceObjectPointer(&UnicodeName, FILE_READ_DATA, &pHubFileObj, &pHubDevObj);
+ if (Status == STATUS_SUCCESS)
+ {
+ Log(("IoGetDeviceObjectPointer for %S returned %p %p\n", szwHubName, pHubDevObj, pHubFileObj));
+
+ if (pHubDevObj->DriverObject
+ && pHubDevObj->DriverObject->DriverName.Buffer
+ && pHubDevObj->DriverObject->DriverName.Length
+ && !RtlCompareUnicodeString(&szStandardHubName, &pHubDevObj->DriverObject->DriverName, TRUE /* case insensitive */))
+ {
+#if 0
+ Log(("Associated driver"));
+ Log(("%S\n", &pHubDevObj->DriverObject->DriverName.Buffer));
+#endif
+ Log(("pnp handler %p\n", pHubDevObj->DriverObject->MajorFunction[IRP_MJ_PNP]));
+
+ pDrvObj = pHubDevObj->DriverObject;
+ break;
+ }
+ ObDereferenceObject(pHubFileObj);
+ }
+ else
+ {
+ AssertFailed();
+ }
+ }
+ else
+ {
+ AssertFailed();
+ }
+ }
+
+ return pDrvObj;
+}
+
+/* NOTE: the stack location data is not the "actual" IRP stack location,
+ * but a copy being preserved on the IRP way down.
+ * See the note in VBoxUsbPnPCompletion for detail */
+static NTSTATUS vboxUsbMonHandlePnPIoctl(PDEVICE_OBJECT pDevObj, PIO_STACK_LOCATION pSl, PIO_STATUS_BLOCK pIoStatus)
+{
+ Log(("VBoxUSBMonHandlePnPIoctl IRQL = %d\n", KeGetCurrentIrql()));
+ switch(pSl->MinorFunction)
+ {
+ case IRP_MN_QUERY_DEVICE_TEXT:
+ {
+ Log(("IRP_MN_QUERY_DEVICE_TEXT: pIoStatus->Status = %x\n", pIoStatus->Status));
+ if (pIoStatus->Status == STATUS_SUCCESS)
+ {
+ WCHAR *pId = (WCHAR *)pIoStatus->Information;
+ if (VALID_PTR(pId))
+ {
+ KIRQL Iqrl = KeGetCurrentIrql();
+ /* IRQL should be always passive here */
+ Assert(Iqrl == PASSIVE_LEVEL);
+ switch(pSl->Parameters.QueryDeviceText.DeviceTextType)
+ {
+ case DeviceTextLocationInformation:
+ Log(("DeviceTextLocationInformation %ws\n", pId));
+ break;
+
+ case DeviceTextDescription:
+ Log(("DeviceTextDescription %ws\n", pId));
+ if (VBoxUsbFltPdoIsFiltered(pDevObj))
+ {
+ WCHAR *pId = (WCHAR *)ExAllocatePool(PagedPool, sizeof(szDeviceTextDescription));
+ if (!pId)
+ {
+ AssertFailed();
+ break;
+ }
+ memcpy(pId, szDeviceTextDescription, sizeof(szDeviceTextDescription));
+ Log(("NEW szDeviceTextDescription %ws\n", pId));
+ ExFreePool((PVOID)pIoStatus->Information);
+ pIoStatus->Information = (ULONG_PTR)pId;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ Log(("Invalid pointer %p\n", pId));
+ }
+ break;
+ }
+
+ case IRP_MN_QUERY_ID:
+ {
+ Log(("IRP_MN_QUERY_ID: Irp->pIoStatus->Status = %x\n", pIoStatus->Status));
+ if (pIoStatus->Status == STATUS_SUCCESS && pDevObj)
+ {
+ WCHAR *pId = (WCHAR *)pIoStatus->Information;
+#ifdef DEBUG
+ WCHAR *pTmp;
+#endif
+ if (VALID_PTR(pId))
+ {
+ KIRQL Iqrl = KeGetCurrentIrql();
+ /* IRQL should be always passive here */
+ Assert(Iqrl == PASSIVE_LEVEL);
+
+ switch (pSl->Parameters.QueryDeviceRelations.Type)
+ {
+ case BusQueryInstanceID:
+ Log(("BusQueryInstanceID %ws\n", pId));
+ break;
+
+ case BusQueryDeviceID:
+ {
+ pId = (WCHAR *)ExAllocatePool(PagedPool, sizeof(szBusQueryDeviceId));
+ if (!pId)
+ {
+ AssertFailed();
+ break;
+ }
+
+ BOOLEAN bFiltered = FALSE;
+ NTSTATUS Status = VBoxUsbFltPdoAdd(pDevObj, &bFiltered);
+ if (Status != STATUS_SUCCESS || !bFiltered)
+ {
+ Assert(Status == STATUS_SUCCESS);
+ ExFreePool(pId);
+ break;
+ }
+
+ ExFreePool((PVOID)pIoStatus->Information);
+ memcpy(pId, szBusQueryDeviceId, sizeof(szBusQueryDeviceId));
+ pIoStatus->Information = (ULONG_PTR)pId;
+ break;
+ }
+ case BusQueryHardwareIDs:
+ {
+#ifdef DEBUG
+ while(*pId) //MULTI_SZ
+ {
+ Log(("BusQueryHardwareIDs %ws\n", pId));
+ while(*pId) pId++;
+ pId++;
+ }
+#endif
+ pId = (WCHAR *)ExAllocatePool(PagedPool, sizeof(szBusQueryHardwareIDs));
+ if (!pId)
+ {
+ AssertFailed();
+ break;
+ }
+
+ BOOLEAN bFiltered = FALSE;
+ NTSTATUS Status = VBoxUsbFltPdoAdd(pDevObj, &bFiltered);
+ if (Status != STATUS_SUCCESS || !bFiltered)
+ {
+ Assert(Status == STATUS_SUCCESS);
+ ExFreePool(pId);
+ break;
+ }
+
+ memcpy(pId, szBusQueryHardwareIDs, sizeof(szBusQueryHardwareIDs));
+#ifdef DEBUG
+ pTmp = pId;
+ while(*pTmp) //MULTI_SZ
+ {
+ Log(("NEW BusQueryHardwareIDs %ws\n", pTmp));
+ while(*pTmp) pTmp++;
+ pTmp++;
+ }
+#endif
+ ExFreePool((PVOID)pIoStatus->Information);
+ pIoStatus->Information = (ULONG_PTR)pId;
+ break;
+ }
+ case BusQueryCompatibleIDs:
+#ifdef DEBUG
+ while(*pId) //MULTI_SZ
+ {
+ Log(("BusQueryCompatibleIDs %ws\n", pId));
+ while(*pId) pId++;
+ pId++;
+ }
+#endif
+ if (VBoxUsbFltPdoIsFiltered(pDevObj))
+ {
+ pId = (WCHAR *)ExAllocatePool(PagedPool, sizeof(szBusQueryCompatibleIDs));
+ if (!pId)
+ {
+ AssertFailed();
+ break;
+ }
+ memcpy(pId, szBusQueryCompatibleIDs, sizeof(szBusQueryCompatibleIDs));
+#ifdef DEBUG
+ pTmp = pId;
+ while(*pTmp) //MULTI_SZ
+ {
+ Log(("NEW BusQueryCompatibleIDs %ws\n", pTmp));
+ while(*pTmp) pTmp++;
+ pTmp++;
+ }
+#endif
+ ExFreePool((PVOID)pIoStatus->Information);
+ pIoStatus->Information = (ULONG_PTR)pId;
+ }
+ break;
+ }
+ }
+ else
+ Log(("Invalid pointer %p\n", pId));
+ }
+ break;
+ }
+
+#ifdef DEBUG
+ case IRP_MN_QUERY_DEVICE_RELATIONS:
+ {
+ switch(pSl->Parameters.QueryDeviceRelations.Type)
+ {
+ case BusRelations:
+ {
+ Log(("BusRelations\n"));
+
+ if (pIoStatus->Status == STATUS_SUCCESS)
+ {
+ PDEVICE_RELATIONS pRel = (PDEVICE_RELATIONS)pIoStatus->Information;
+ Log(("pRel = %p\n", pRel));
+ if (VALID_PTR(pRel))
+ {
+ for (unsigned i=0;i<pRel->Count;i++)
+ {
+ if (VBoxUsbFltPdoIsFiltered(pDevObj))
+ Log(("New PDO %p\n", pRel->Objects[i]));
+ }
+ }
+ else
+ Log(("Invalid pointer %p\n", pRel));
+ }
+ break;
+ }
+ case TargetDeviceRelation:
+ Log(("TargetDeviceRelation\n"));
+ break;
+ case RemovalRelations:
+ Log(("RemovalRelations\n"));
+ break;
+ case EjectionRelations:
+ Log(("EjectionRelations\n"));
+ break;
+ }
+ break;
+ }
+
+ case IRP_MN_QUERY_CAPABILITIES:
+ {
+ Log(("IRP_MN_QUERY_CAPABILITIES: pIoStatus->Status = %x\n", pIoStatus->Status));
+ if (pIoStatus->Status == STATUS_SUCCESS)
+ {
+ PDEVICE_CAPABILITIES pCaps = pSl->Parameters.DeviceCapabilities.Capabilities;
+ if (VALID_PTR(pCaps))
+ {
+ Log(("Caps.SilentInstall = %d\n", pCaps->SilentInstall));
+ Log(("Caps.UniqueID = %d\n", pCaps->UniqueID ));
+ Log(("Caps.Address = %d\n", pCaps->Address ));
+ Log(("Caps.UINumber = %d\n", pCaps->UINumber ));
+ }
+ else
+ Log(("Invalid pointer %p\n", pCaps));
+ }
+ break;
+ }
+
+ default:
+ break;
+#endif
+ } /*switch */
+
+ Log(("VBoxUSBMonHandlePnPIoctl returns %x (IRQL = %d)\n", pIoStatus->Status, KeGetCurrentIrql()));
+ return pIoStatus->Status;
+}
+
+NTSTATUS _stdcall VBoxUsbPnPCompletion(DEVICE_OBJECT *pDevObj, IRP *pIrp, void *pvContext)
+{
+ Assert(pvContext);
+
+ PVBOXUSBHOOK_REQUEST pRequest = (PVBOXUSBHOOK_REQUEST)pvContext;
+ /* NOTE: despite a regular IRP processing the stack location in our completion
+ * differs from those of the PnP hook since the hook is invoked in the "context" of the calle,
+ * while the completion is in the "coller" context in terms of IRP,
+ * so the completion stack location is one level "up" here.
+ *
+ * Moreover we CAN NOT access irp stack location in the completion because we might not have one at all
+ * in case the hooked driver is at the top of the irp call stack
+ *
+ * This is why we use the stack location we saved on IRP way down.
+ * */
+ PIO_STACK_LOCATION pSl = &pRequest->OldLocation;
+ Assert(pIrp == pRequest->pIrp);
+ /* NOTE: we can not rely on pDevObj passed in IoCompletion since it may be zero
+ * in case IRP was created with extra stack locations and the caller did not initialize
+ * the IO_STACK_LOCATION::DeviceObject */
+ DEVICE_OBJECT *pRealDevObj = pRequest->pDevObj;
+// Assert(!pDevObj || pDevObj == pRealDevObj);
+// Assert(pSl->DeviceObject == pDevObj);
+
+ switch(pSl->MinorFunction)
+ {
+ case IRP_MN_QUERY_DEVICE_TEXT:
+ case IRP_MN_QUERY_ID:
+#ifdef DEBUG
+ case IRP_MN_QUERY_DEVICE_RELATIONS:
+ case IRP_MN_QUERY_CAPABILITIES:
+#endif
+ if (NT_SUCCESS(pIrp->IoStatus.Status))
+ {
+ vboxUsbMonHandlePnPIoctl(pRealDevObj, pSl, &pIrp->IoStatus);
+ }
+ else
+ {
+ Assert(pIrp->IoStatus.Status == STATUS_NOT_SUPPORTED);
+ }
+ break;
+
+ case IRP_MN_SURPRISE_REMOVAL:
+ case IRP_MN_REMOVE_DEVICE:
+ if (NT_SUCCESS(pIrp->IoStatus.Status))
+ {
+ VBoxUsbFltPdoRemove(pRealDevObj);
+ }
+ else
+ {
+ AssertFailed();
+ }
+ break;
+
+ /* These two IRPs are received when the PnP subsystem has determined the id of the newly arrived device */
+ /* IRP_MN_START_DEVICE only arrives if it's a USB device of a known class or with a present host driver */
+ case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
+ case IRP_MN_QUERY_RESOURCES:
+ if (NT_SUCCESS(pIrp->IoStatus.Status) || pIrp->IoStatus.Status == STATUS_NOT_SUPPORTED)
+ {
+ VBoxUsbFltPdoAddCompleted(pRealDevObj);
+ }
+ else
+ {
+ AssertFailed();
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ Log(("<==PnP: Mn(%s), PDO(0x%p), IRP(0x%p), Status(0x%x), Sl PDO(0x%p), Compl PDO(0x%p)\n",
+ vboxUsbDbgStrPnPMn(pSl->MinorFunction),
+ pRealDevObj, pIrp, pIrp->IoStatus.Status,
+ pSl->DeviceObject, pDevObj));
+#ifdef DEBUG_misha
+ NTSTATUS tmpStatus = pIrp->IoStatus.Status;
+#endif
+ NTSTATUS Status = VBoxUsbHookRequestComplete(&g_VBoxUsbMonGlobals.UsbHubPnPHook.Hook, pDevObj, pIrp, pRequest);
+ VBoxUsbMonMemFree(pRequest);
+#ifdef DEBUG_misha
+ if (Status != STATUS_MORE_PROCESSING_REQUIRED)
+ {
+ Assert(pIrp->IoStatus.Status == tmpStatus);
+ }
+#endif
+ VBoxUsbHookRelease(&g_VBoxUsbMonGlobals.UsbHubPnPHook.Hook);
+ return Status;
+}
+
+/**
+ * Device PnP hook
+ *
+ * @param pDevObj Device object.
+ * @param pIrp Request packet.
+ */
+NTSTATUS _stdcall VBoxUsbMonPnPHook(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
+{
+ if(!VBoxUsbHookRetain(&g_VBoxUsbMonGlobals.UsbHubPnPHook.Hook))
+ {
+ return VBoxUsbHookRequestPassDownHookSkip(&g_VBoxUsbMonGlobals.UsbHubPnPHook.Hook, pDevObj, pIrp);
+ }
+
+ PVBOXUSBHUB_PNPHOOK_COMPLETION pCompletion = (PVBOXUSBHUB_PNPHOOK_COMPLETION)VBoxUsbMonMemAlloc(sizeof (*pCompletion));
+ if (!pCompletion)
+ {
+ AssertFailed();
+ VBoxUsbHookRelease(&g_VBoxUsbMonGlobals.UsbHubPnPHook.Hook);
+ pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+ pIrp->IoStatus.Information = 0;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Log(("==>PnP: Mn(%s), PDO(0x%p), IRP(0x%p), Status(0x%x)\n", vboxUsbDbgStrPnPMn(IoGetCurrentIrpStackLocation(pIrp)->MinorFunction), pDevObj, pIrp, pIrp->IoStatus.Status));
+
+ NTSTATUS Status = VBoxUsbHookRequestPassDownHookCompletion(&g_VBoxUsbMonGlobals.UsbHubPnPHook.Hook, pDevObj, pIrp, VBoxUsbPnPCompletion, &pCompletion->Rq);
+#ifdef DEBUG
+ if (Status != STATUS_PENDING)
+ {
+ VBoxUsbHookVerifyCompletion(&g_VBoxUsbMonGlobals.UsbHubPnPHook.Hook, &pCompletion->Rq, pIrp);
+ }
+#endif
+ return Status;
+}
+
+
+static NTSTATUS vboxUsbMonHookCheckInit()
+{
+ static bool fIsHookInited = false;
+ if (fIsHookInited)
+ return STATUS_SUCCESS;
+ PDRIVER_OBJECT pDrvObj = vboxUsbMonHookFindHubDrvObj();
+ Assert(pDrvObj);
+ if (pDrvObj)
+ {
+ VBoxUsbHookInit(&g_VBoxUsbMonGlobals.UsbHubPnPHook.Hook, pDrvObj, IRP_MJ_PNP, VBoxUsbMonPnPHook);
+ fIsHookInited = true;
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+static NTSTATUS vboxUsbMonHookInstall()
+{
+#ifdef VBOXUSBMON_DBG_NO_PNPHOOK
+ return STATUS_SUCCESS;
+#else
+ if (g_VBoxUsbMonGlobals.UsbHubPnPHook.fUninitFailed)
+ {
+ AssertMsgFailed(("trying to hook usbhub pnp after the unhook failed, do nothing & pretend success..\n"));
+ return STATUS_SUCCESS;
+ }
+ return VBoxUsbHookInstall(&g_VBoxUsbMonGlobals.UsbHubPnPHook.Hook);
+#endif
+}
+
+static NTSTATUS vboxUsbMonHookUninstall()
+{
+#ifdef VBOXUSBMON_DBG_NO_PNPHOOK
+ return STATUS_SUCCESS;
+#else
+ NTSTATUS Status = VBoxUsbHookUninstall(&g_VBoxUsbMonGlobals.UsbHubPnPHook.Hook);
+ if (!NT_SUCCESS(Status))
+ {
+ AssertMsgFailed(("usbhub pnp unhook failed, setting the fUninitFailed flag, the current value of fUninitFailed (%d)\n", g_VBoxUsbMonGlobals.UsbHubPnPHook.fUninitFailed));
+ g_VBoxUsbMonGlobals.UsbHubPnPHook.fUninitFailed = true;
+ }
+ return Status;
+#endif
+}
+
+
+static NTSTATUS vboxUsbMonCheckTermStuff()
+{
+ NTSTATUS Status = KeWaitForSingleObject(&g_VBoxUsbMonGlobals.OpenSynchEvent,
+ Executive, KernelMode,
+ FALSE, /* BOOLEAN Alertable */
+ NULL /* IN PLARGE_INTEGER Timeout */
+ );
+ AssertRelease(Status == STATUS_SUCCESS);
+
+ do
+ {
+ if (--g_VBoxUsbMonGlobals.cOpens)
+ break;
+
+ Status = vboxUsbMonHookUninstall();
+
+ NTSTATUS tmpStatus = VBoxUsbFltTerm();
+ if (!NT_SUCCESS(tmpStatus))
+ {
+ /* this means a driver state is screwed up, KeBugCheckEx here ? */
+ AssertReleaseFailed();
+ }
+ } while (0);
+
+ KeSetEvent(&g_VBoxUsbMonGlobals.OpenSynchEvent, 0, FALSE);
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbMonCheckInitStuff()
+{
+ NTSTATUS Status = KeWaitForSingleObject(&g_VBoxUsbMonGlobals.OpenSynchEvent,
+ Executive, KernelMode,
+ FALSE, /* BOOLEAN Alertable */
+ NULL /* IN PLARGE_INTEGER Timeout */
+ );
+ Assert(Status == STATUS_SUCCESS);
+ if (Status == STATUS_SUCCESS)
+ {
+ do
+ {
+ if (g_VBoxUsbMonGlobals.cOpens++)
+ break;
+
+ Status = VBoxUsbFltInit();
+ if (NT_SUCCESS(Status))
+ {
+ Status = vboxUsbMonHookCheckInit();
+ if (NT_SUCCESS(Status))
+ {
+ Status = vboxUsbMonHookInstall();
+ if (NT_SUCCESS(Status))
+ {
+ Status = STATUS_SUCCESS;
+ break;
+ }
+ else
+ {
+ AssertFailed();
+ }
+ }
+ VBoxUsbFltTerm();
+ }
+ else
+ {
+ AssertFailed();
+ }
+
+ --g_VBoxUsbMonGlobals.cOpens;
+ Assert(!g_VBoxUsbMonGlobals.cOpens);
+ } while (0);
+
+ KeSetEvent(&g_VBoxUsbMonGlobals.OpenSynchEvent, 0, FALSE);
+ }
+ return Status;
+}
+
+static NTSTATUS vboxUsbMonContextCreate(PVBOXUSBMONCTX *ppCtx)
+{
+ NTSTATUS Status;
+ *ppCtx = NULL;
+ PVBOXUSBMONCTX pFileCtx = (PVBOXUSBMONCTX)VBoxUsbMonMemAllocZ(sizeof (*pFileCtx));
+ if (pFileCtx)
+ {
+ Status = vboxUsbMonCheckInitStuff();
+ if (Status == STATUS_SUCCESS)
+ {
+ Status = VBoxUsbFltCreate(&pFileCtx->FltCtx);
+ if (Status == STATUS_SUCCESS)
+ {
+ *ppCtx = pFileCtx;
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ AssertFailed();
+ }
+ vboxUsbMonCheckTermStuff();
+ }
+ else
+ {
+ AssertFailed();
+ }
+ VBoxUsbMonMemFree(pFileCtx);
+ }
+ else
+ {
+ AssertFailed();
+ Status = STATUS_NO_MEMORY;
+ }
+
+ return Status;
+}
+
+static NTSTATUS vboxUsbMonContextClose(PVBOXUSBMONCTX pCtx)
+{
+ NTSTATUS Status = VBoxUsbFltClose(&pCtx->FltCtx);
+ if (Status == STATUS_SUCCESS)
+ {
+ Status = vboxUsbMonCheckTermStuff();
+ Assert(Status == STATUS_SUCCESS);
+ /* ignore the failure */
+ VBoxUsbMonMemFree(pCtx);
+ }
+
+ return Status;
+}
+
+static NTSTATUS _stdcall VBoxUsbMonClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFileObj = pStack->FileObject;
+ Assert(pFileObj->FsContext);
+ PVBOXUSBMONCTX pCtx = (PVBOXUSBMONCTX)pFileObj->FsContext;
+ NTSTATUS Status = vboxUsbMonContextClose(pCtx);
+ Assert(Status == STATUS_SUCCESS);
+ if (Status != STATUS_SUCCESS)
+ {
+ AssertMsgFailed(("close failed with Status 0x%x, prefent unload\n", Status));
+ if (!InterlockedExchange(&g_VBoxUsbMonGlobals.ulPreventUnloadOn, 1))
+ {
+ LogRel(("ulPreventUnloadOn not set, preventing unload\n"));
+ UNICODE_STRING UniName;
+ PDEVICE_OBJECT pTmpDevObj;
+ RtlInitUnicodeString(&UniName, USBMON_DEVICE_NAME_NT);
+ NTSTATUS tmpStatus = IoGetDeviceObjectPointer(&UniName, FILE_ALL_ACCESS, &g_VBoxUsbMonGlobals.pPreventUnloadFileObj, &pTmpDevObj);
+ AssertRelease(NT_SUCCESS(tmpStatus));
+ AssertRelease(pTmpDevObj == pDevObj);
+ }
+ else
+ {
+ AssertMsgFailed(("ulPreventUnloadOn already set\n"));
+ }
+ Status = STATUS_SUCCESS;
+ }
+ pFileObj->FsContext = NULL;
+ pIrp->IoStatus.Status = Status;
+ pIrp->IoStatus.Information = 0;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ return Status;
+}
+
+
+static NTSTATUS _stdcall VBoxUsbMonCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+{
+ PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFileObj = pStack->FileObject;
+ NTSTATUS Status;
+
+ Log(("VBoxUSBMonCreate\n"));
+
+ if (pStack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
+ {
+ pIrp->IoStatus.Status = STATUS_NOT_A_DIRECTORY;
+ pIrp->IoStatus.Information = 0;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ return STATUS_NOT_A_DIRECTORY;
+ }
+
+ pFileObj->FsContext = NULL;
+ PVBOXUSBMONCTX pCtx = NULL;
+ Status = vboxUsbMonContextCreate(&pCtx);
+ if (Status == STATUS_SUCCESS)
+ {
+ Assert(pCtx);
+ pFileObj->FsContext = pCtx;
+ }
+
+ pIrp->IoStatus.Status = Status;
+ pIrp->IoStatus.Information = 0;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ return Status;
+}
+
+static int VBoxUsbMonSetNotifyEvent(PVBOXUSBMONCTX pContext, HANDLE hEvent)
+{
+ int rc = VBoxUsbFltSetNotifyEvent(&pContext->FltCtx, hEvent);
+ return rc;
+}
+
+static int VBoxUsbMonFltAdd(PVBOXUSBMONCTX pContext, PUSBFILTER pFilter, uintptr_t *pId)
+{
+#ifdef VBOXUSBMON_DBG_NO_FILTERS
+ static uintptr_t idDummy = 1;
+ *pId = idDummy;
+ ++idDummy;
+ return VINF_SUCCESS;
+#else
+ int rc = VBoxUsbFltAdd(&pContext->FltCtx, pFilter, pId);
+ return rc;
+#endif
+}
+
+static int VBoxUsbMonFltRemove(PVBOXUSBMONCTX pContext, uintptr_t uId)
+{
+#ifdef VBOXUSBMON_DBG_NO_FILTERS
+ return VINF_SUCCESS;
+#else
+ int rc = VBoxUsbFltRemove(&pContext->FltCtx, uId);
+ return rc;
+#endif
+}
+
+static NTSTATUS VBoxUsbMonRunFilters(PVBOXUSBMONCTX pContext)
+{
+ NTSTATUS Status = VBoxUsbFltFilterCheck(&pContext->FltCtx);
+ return Status;
+}
+
+static NTSTATUS VBoxUsbMonGetDevice(PVBOXUSBMONCTX pContext, HVBOXUSBDEVUSR hDevice, PUSBSUP_GETDEV_MON pInfo)
+{
+ NTSTATUS Status = VBoxUsbFltGetDevice(&pContext->FltCtx, hDevice, pInfo);
+ return Status;
+}
+
+static NTSTATUS vboxUsbMonIoctlDispatch(PVBOXUSBMONCTX pContext, ULONG Ctl, PVOID pvBuffer, ULONG cbInBuffer, ULONG cbOutBuffer, ULONG_PTR* pInfo)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ ULONG_PTR Info = 0;
+ switch (Ctl)
+ {
+ case SUPUSBFLT_IOCTL_GET_VERSION:
+ {
+ PUSBSUP_VERSION pOut = (PUSBSUP_VERSION)pvBuffer;
+
+ Log(("SUPUSBFLT_IOCTL_GET_VERSION\n"));
+ if (!pvBuffer || cbOutBuffer != sizeof(*pOut) || cbInBuffer != 0)
+ {
+ AssertMsgFailed(("SUPUSBFLT_IOCTL_GET_VERSION: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
+ cbInBuffer, 0, cbOutBuffer, sizeof (*pOut)));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ pOut->u32Major = USBMON_MAJOR_VERSION;
+ pOut->u32Minor = USBMON_MINOR_VERSION;
+ Info = sizeof (*pOut);
+ break;
+ }
+
+ case SUPUSBFLT_IOCTL_ADD_FILTER:
+ {
+ PUSBFILTER pFilter = (PUSBFILTER)pvBuffer;
+ PUSBSUP_FLTADDOUT pOut = (PUSBSUP_FLTADDOUT)pvBuffer;
+ uintptr_t uId = 0;
+ int rc;
+ if (RT_UNLIKELY(!pvBuffer || cbInBuffer != sizeof (*pFilter) || cbOutBuffer != sizeof (*pOut)))
+ {
+ AssertMsgFailed(("SUPUSBFLT_IOCTL_ADD_FILTER: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
+ cbInBuffer, sizeof (*pFilter), cbOutBuffer, sizeof (*pOut)));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ rc = VBoxUsbMonFltAdd(pContext, pFilter, &uId);
+ pOut->rc = rc;
+ pOut->uId = uId;
+ Info = sizeof (*pOut);
+ break;
+ }
+
+ case SUPUSBFLT_IOCTL_REMOVE_FILTER:
+ {
+ uintptr_t *pIn = (uintptr_t *)pvBuffer;
+ int *pRc = (int *)pvBuffer;
+
+ if (!pvBuffer || cbInBuffer != sizeof (*pIn) || (cbOutBuffer && cbOutBuffer != sizeof (*pRc)))
+ {
+ AssertMsgFailed(("SUPUSBFLT_IOCTL_REMOVE_FILTER: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
+ cbInBuffer, sizeof (*pIn), cbOutBuffer, 0));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ Log(("SUPUSBFLT_IOCTL_REMOVE_FILTER %x\n", *pIn));
+ int rc = VBoxUsbMonFltRemove(pContext, *pIn);
+ if (cbOutBuffer)
+ {
+ /* we've validated that already */
+ Assert(cbOutBuffer == *pRc);
+ *pRc = rc;
+ Info = sizeof (*pRc);
+ }
+ break;
+ }
+
+ case SUPUSBFLT_IOCTL_RUN_FILTERS:
+ {
+ if (pvBuffer || cbInBuffer || cbOutBuffer)
+ {
+ AssertMsgFailed(("SUPUSBFLT_IOCTL_RUN_FILTERS: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
+ cbInBuffer, 0, cbOutBuffer, 0));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ Log(("SUPUSBFLT_IOCTL_RUN_FILTERS \n"));
+ Status = VBoxUsbMonRunFilters(pContext);
+ Assert(Status == STATUS_SUCCESS);
+ Assert(Status != STATUS_PENDING);
+ break;
+ }
+
+ case SUPUSBFLT_IOCTL_GET_DEVICE:
+ {
+ HVBOXUSBDEVUSR hDevice = *((HVBOXUSBDEVUSR*)pvBuffer);
+ PUSBSUP_GETDEV_MON pOut = (PUSBSUP_GETDEV_MON)pvBuffer;
+ if (!pvBuffer || cbInBuffer != sizeof (hDevice) || cbOutBuffer < sizeof (*pOut))
+ {
+ AssertMsgFailed(("SUPUSBFLT_IOCTL_GET_DEVICE: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected >= %d.\n",
+ cbInBuffer, sizeof (hDevice), cbOutBuffer, sizeof (*pOut)));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ Status = VBoxUsbMonGetDevice(pContext, hDevice, pOut);
+
+ if (NT_SUCCESS(Status))
+ {
+ Info = sizeof (*pOut);
+ }
+ else
+ {
+ AssertFailed();
+ }
+ break;
+ }
+
+ case SUPUSBFLT_IOCTL_SET_NOTIFY_EVENT:
+ {
+ PUSBSUP_SET_NOTIFY_EVENT pSne = (PUSBSUP_SET_NOTIFY_EVENT)pvBuffer;
+ if (!pvBuffer || cbInBuffer != sizeof (*pSne) || cbOutBuffer != sizeof (*pSne))
+ {
+ AssertMsgFailed(("SUPUSBFLT_IOCTL_SET_NOTIFY_EVENT: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
+ cbInBuffer, sizeof (*pSne), cbOutBuffer, sizeof (*pSne)));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ pSne->u.rc = VBoxUsbMonSetNotifyEvent(pContext, pSne->u.hEvent);
+ Info = sizeof (*pSne);
+ break;
+ }
+
+ default:
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ Assert(Status != STATUS_PENDING);
+
+ *pInfo = Info;
+ return Status;
+}
+
+static NTSTATUS _stdcall VBoxUsbMonDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+{
+ ULONG_PTR Info = 0;
+ NTSTATUS Status = IoAcquireRemoveLock(&g_VBoxUsbMonGlobals.RmLock, pDevObj);
+ if (NT_SUCCESS(Status))
+ {
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFileObj = pSl->FileObject;
+ Assert(pFileObj);
+ Assert(pFileObj->FsContext);
+ PVBOXUSBMONCTX pCtx = (PVBOXUSBMONCTX)pFileObj->FsContext;
+ Assert(pCtx);
+ Status = vboxUsbMonIoctlDispatch(pCtx,
+ pSl->Parameters.DeviceIoControl.IoControlCode,
+ pIrp->AssociatedIrp.SystemBuffer,
+ pSl->Parameters.DeviceIoControl.InputBufferLength,
+ pSl->Parameters.DeviceIoControl.OutputBufferLength,
+ &Info);
+ Assert(Status != STATUS_PENDING);
+
+ IoReleaseRemoveLock(&g_VBoxUsbMonGlobals.RmLock, pDevObj);
+ }
+
+ pIrp->IoStatus.Information = Info;
+ pIrp->IoStatus.Status = Status;
+ IoCompleteRequest (pIrp, IO_NO_INCREMENT);
+ return Status;
+}
+
+static NTSTATUS vboxUsbMonInternalIoctlDispatch(ULONG Ctl, PVOID pvBuffer, ULONG_PTR *pInfo)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ *pInfo = 0;
+ switch (Ctl)
+ {
+ case VBOXUSBIDC_INTERNAL_IOCTL_GET_VERSION:
+ {
+ PVBOXUSBIDC_VERSION pOut = (PVBOXUSBIDC_VERSION)pvBuffer;
+
+ Log(("VBOXUSBIDC_INTERNAL_IOCTL_GET_VERSION\n"));
+ if (!pvBuffer)
+ {
+ AssertMsgFailed(("VBOXUSBIDC_INTERNAL_IOCTL_GET_VERSION: Buffer is NULL\n"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ pOut->u32Major = VBOXUSBIDC_VERSION_MAJOR;
+ pOut->u32Minor = VBOXUSBIDC_VERSION_MINOR;
+ break;
+ }
+
+ case VBOXUSBIDC_INTERNAL_IOCTL_PROXY_STARTUP:
+ {
+ PVBOXUSBIDC_PROXY_STARTUP pOut = (PVBOXUSBIDC_PROXY_STARTUP)pvBuffer;
+
+ Log(("VBOXUSBIDC_INTERNAL_IOCTL_PROXY_STARTUP\n"));
+ if (!pvBuffer)
+ {
+ AssertMsgFailed(("VBOXUSBIDC_INTERNAL_IOCTL_GET_VERSION: Buffer is NULL\n"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ pOut->u.hDev = VBoxUsbFltProxyStarted(pOut->u.pPDO);
+ break;
+ }
+
+ case VBOXUSBIDC_INTERNAL_IOCTL_PROXY_TEARDOWN:
+ {
+ PVBOXUSBIDC_PROXY_TEARDOWN pOut = (PVBOXUSBIDC_PROXY_TEARDOWN)pvBuffer;
+
+ Log(("VBOXUSBIDC_INTERNAL_IOCTL_PROXY_TEARDOWN\n"));
+ if (!pvBuffer)
+ {
+ AssertMsgFailed(("VBOXUSBIDC_INTERNAL_IOCTL_PROXY_TEARDOWN: Buffer is NULL\n"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ VBoxUsbFltProxyStopped(pOut->hDev);
+ break;
+ }
+
+ default:
+ {
+ AssertFailed();
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ }
+
+ return Status;
+}
+
+static NTSTATUS _stdcall VBoxUsbMonInternalDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+{
+ ULONG_PTR Info = 0;
+ NTSTATUS Status = IoAcquireRemoveLock(&g_VBoxUsbMonGlobals.RmLock, pDevObj);
+ if (NT_SUCCESS(Status))
+ {
+ PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
+ Status = vboxUsbMonInternalIoctlDispatch(pSl->Parameters.DeviceIoControl.IoControlCode,
+ pSl->Parameters.Others.Argument1,
+ &Info);
+ Assert(Status != STATUS_PENDING);
+
+ IoReleaseRemoveLock(&g_VBoxUsbMonGlobals.RmLock, pDevObj);
+ }
+
+ pIrp->IoStatus.Information = Info;
+ pIrp->IoStatus.Status = Status;
+ IoCompleteRequest (pIrp, IO_NO_INCREMENT);
+ return Status;
+}
+
+/**
+ * Unload the driver.
+ *
+ * @param pDrvObj Driver object.
+ */
+static void _stdcall VBoxUsbMonUnload(PDRIVER_OBJECT pDrvObj)
+{
+ Log(("VBoxUSBMonUnload pDrvObj (0x%p)\n", pDrvObj));
+
+ IoReleaseRemoveLockAndWait(&g_VBoxUsbMonGlobals.RmLock, &g_VBoxUsbMonGlobals);
+
+ Assert(!g_VBoxUsbMonGlobals.cOpens);
+
+ UNICODE_STRING DosName;
+ RtlInitUnicodeString(&DosName, USBMON_DEVICE_NAME_DOS);
+ NTSTATUS rc = IoDeleteSymbolicLink(&DosName);
+
+ IoDeleteDevice(g_VBoxUsbMonGlobals.pDevObj);
+
+ /* cleanup the logger */
+ PRTLOGGER pLogger = RTLogRelSetDefaultInstance(NULL);
+ if (pLogger)
+ {
+ RTLogDestroy(pLogger);
+ }
+ pLogger = RTLogSetDefaultInstance(NULL);
+ if (pLogger)
+ {
+ RTLogDestroy(pLogger);
+ }
+}
+
+RT_C_DECLS_BEGIN
+NTSTATUS _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath);
+RT_C_DECLS_END
+
+/**
+ * Driver entry point.
+ *
+ * @returns appropriate status code.
+ * @param pDrvObj Pointer to driver object.
+ * @param pRegPath Registry base path.
+ */
+NTSTATUS _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
+{
+#ifdef DEBUG_misha
+ RTLogGroupSettings(0, "+default.e.l.f.l2.l3");;
+#endif
+
+ Log(("VBoxUSBMon::DriverEntry\n"));
+
+ memset (&g_VBoxUsbMonGlobals, 0, sizeof (g_VBoxUsbMonGlobals));
+ KeInitializeEvent(&g_VBoxUsbMonGlobals.OpenSynchEvent, SynchronizationEvent, TRUE /* signaled */);
+ IoInitializeRemoveLock(&g_VBoxUsbMonGlobals.RmLock, VBOXUSBMON_MEMTAG, 1, 100);
+ UNICODE_STRING DevName;
+ PDEVICE_OBJECT pDevObj;
+ /* create the device */
+ RtlInitUnicodeString(&DevName, USBMON_DEVICE_NAME_NT);
+ NTSTATUS Status = IoAcquireRemoveLock(&g_VBoxUsbMonGlobals.RmLock, &g_VBoxUsbMonGlobals);
+ if (NT_SUCCESS(Status))
+ {
+ Status = IoCreateDevice(pDrvObj, sizeof (VBOXUSBMONINS), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj);
+ if (NT_SUCCESS(Status))
+ {
+ UNICODE_STRING DosName;
+ RtlInitUnicodeString(&DosName, USBMON_DEVICE_NAME_DOS);
+ Status = IoCreateSymbolicLink(&DosName, &DevName);
+ if (NT_SUCCESS(Status))
+ {
+ PVBOXUSBMONINS pDevExt = (PVBOXUSBMONINS)pDevObj->DeviceExtension;
+ memset(pDevExt, 0, sizeof(*pDevExt));
+
+ pDrvObj->DriverUnload = VBoxUsbMonUnload;
+ pDrvObj->MajorFunction[IRP_MJ_CREATE] = VBoxUsbMonCreate;
+ pDrvObj->MajorFunction[IRP_MJ_CLOSE] = VBoxUsbMonClose;
+ pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxUsbMonDeviceControl;
+ pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = VBoxUsbMonInternalDeviceControl;
+
+ g_VBoxUsbMonGlobals.pDevObj = pDevObj;
+ Log(("VBoxUSBMon::DriverEntry returning STATUS_SUCCESS\n"));
+ return STATUS_SUCCESS;
+ }
+ IoDeleteDevice(pDevObj);
+ }
+ IoReleaseRemoveLockAndWait(&g_VBoxUsbMonGlobals.RmLock, &g_VBoxUsbMonGlobals);
+ }
+
+ return Status;
+}
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.h b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.h
new file mode 100644
index 000000000..b54f38e8b
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.h
@@ -0,0 +1,64 @@
+/* $Id: VBoxUsbMon.h 37038 2011-05-11 14:57:23Z vboxsync $ */
+/** @file
+ * VBox USB Monitor
+ */
+/*
+ * 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 ___VBoxUsbMon_h___
+#define ___VBoxUsbMon_h___
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <iprt/assert.h>
+#include <VBox/sup.h>
+#include <iprt/asm.h>
+#include <VBox/log.h>
+
+#ifdef DEBUG
+/* disables filters */
+//#define VBOXUSBMON_DBG_NO_FILTERS
+/* disables pnp hooking */
+//#define VBOXUSBMON_DBG_NO_PNPHOOK
+#endif
+
+#include "../cmn/VBoxDrvTool.h"
+
+#ifdef Log
+# undef Log
+# define Log(_m) DbgPrint _m
+#endif
+
+#ifdef LogRel
+# undef LogRel
+# define LogRel(_m) DbgPrint _m
+#endif
+
+#ifdef LogFlow
+# undef LogFlow
+# define LogFlow(_m) DbgPrint _m
+#endif
+
+#include "../cmn/VBoxUsbTool.h"
+
+#include "VBoxUsbHook.h"
+#include "VBoxUsbFlt.h"
+
+PVOID VBoxUsbMonMemAlloc(SIZE_T cbBytes);
+PVOID VBoxUsbMonMemAllocZ(SIZE_T cbBytes);
+VOID VBoxUsbMonMemFree(PVOID pvMem);
+
+NTSTATUS VBoxUsbMonGetDescriptor(PDEVICE_OBJECT pDevObj, void *buffer, int size, int type, int index, int language_id);
+NTSTATUS VBoxUsbMonQueryBusRelations(PDEVICE_OBJECT pDevObj, PFILE_OBJECT pFileObj, PDEVICE_RELATIONS *pDevRelations);
+
+void vboxUsbDbgPrintUnicodeString(PUNICODE_STRING pUnicodeString);
+
+#endif /* #ifndef ___VBoxUsbMon_h___ */
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMon.rc b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.rc
index 6f53ff981..8411ba288 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/Monitor/USBMon.rc
+++ b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.rc
@@ -1,10 +1,10 @@
-/* $Id: USBMon.rc $ */
+/* $Id: VBoxUsbMon.rc 36968 2011-05-05 08:55:16Z vboxsync $ */
/** @file
* VBoxUSBMon - Resource file containing version info and icon.
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * 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;
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/testcase/USBTest.cpp b/src/VBox/HostDrivers/VBoxUSB/win/testcase/USBTest.cpp
index d56a151e5..393dbd470 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/testcase/USBTest.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/win/testcase/USBTest.cpp
@@ -30,6 +30,7 @@
#include <VBox/err.h>
#include <stdio.h>
#include <VBox/usblib.h>
+#include <VBox/VBoxDrvCfg-win.h>
/** Handle to the open device. */
static HANDLE g_hUSBMonitor = INVALID_HANDLE_VALUE;
@@ -45,87 +46,13 @@ static bool g_fStartedService = false;
*/
int usbMonStartService(void)
{
- /*
- * Check if the driver service is there.
- */
- SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_QUERY_STATUS | SERVICE_START);
- if (hSMgr == NULL)
+ HRESULT hr = VBoxDrvCfgSvcStart(USBMON_SERVICE_NAME_W);
+ if (hr != S_OK)
{
- AssertMsgFailed(("couldn't open service manager in SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS mode!\n"));
+ AssertMsgFailed(("couldn't start service, hr (0x%x)\n", hr));
return -1;
}
-
- /*
- * Try open our service to check it's status.
- */
- SC_HANDLE hService = OpenService(hSMgr, USBMON_SERVICE_NAME, SERVICE_QUERY_STATUS | SERVICE_START);
- if (!hService)
- return -1;
-
- /*
- * Check if open and on demand create succeeded.
- */
- int rc = -1;
- if (hService)
- {
-
- /*
- * Query service status to see if we need to start it or not.
- */
- SERVICE_STATUS Status;
- BOOL fRc = QueryServiceStatus(hService, &Status);
- Assert(fRc);
- if ( Status.dwCurrentState != SERVICE_RUNNING
- && Status.dwCurrentState != SERVICE_START_PENDING)
- {
- /*
- * Start it.
- */
- printf("usbMonStartService -> start it\n");
-
- fRc = StartService(hService, 0, NULL);
- DWORD LastError = GetLastError(); NOREF(LastError);
- AssertMsg(fRc, ("StartService failed with LastError=%Rwa\n", LastError));
- if (fRc)
- g_fStartedService = true;
- }
-
- /*
- * Wait for the service to finish starting.
- * We'll wait for 10 seconds then we'll give up.
- */
- QueryServiceStatus(hService, &Status);
- if (Status.dwCurrentState == SERVICE_START_PENDING)
- {
- int iWait;
- for (iWait = 100; iWait > 0 && Status.dwCurrentState == SERVICE_START_PENDING; iWait--)
- {
- Sleep(100);
- QueryServiceStatus(hService, &Status);
- }
- DWORD LastError = GetLastError(); NOREF(LastError);
- AssertMsg(Status.dwCurrentState != SERVICE_RUNNING,
- ("Failed to start. LastError=%Rwa iWait=%d status=%d\n",
- LastError, iWait, Status.dwCurrentState));
- }
-
- if (Status.dwCurrentState == SERVICE_RUNNING)
- rc = 0;
-
- /*
- * Close open handles.
- */
- CloseServiceHandle(hService);
- }
- else
- {
- DWORD LastError = GetLastError(); NOREF(LastError);
- AssertMsgFailed(("OpenService failed! LastError=%Rwa\n", LastError));
- }
- if (!CloseServiceHandle(hSMgr))
- AssertFailed();
-
- return rc;
+ return 0;
}
/**
@@ -146,7 +73,7 @@ int usbMonStopService(void)
AssertMsg(hSMgr, ("OpenSCManager(,,delete) failed rc=%d\n", LastError));
if (hSMgr)
{
- SC_HANDLE hService = OpenService(hSMgr, USBMON_SERVICE_NAME, SERVICE_STOP | SERVICE_QUERY_STATUS);
+ SC_HANDLE hService = OpenServiceW(hSMgr, USBMON_SERVICE_NAME_W, SERVICE_STOP | SERVICE_QUERY_STATUS);
if (hService)
{
/*
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/usbdesc.h b/src/VBox/HostDrivers/VBoxUSB/win/usbdesc.h
deleted file mode 100644
index e592ff212..000000000
--- a/src/VBox/HostDrivers/VBoxUSB/win/usbdesc.h
+++ /dev/null
@@ -1,318 +0,0 @@
-/*++
-
-Copyright (c) 1997-1998 Microsoft Corporation
-
-Module Name:
-
- USBDESC.H
-
-Abstract:
-
- This is a header file for USB descriptors which are not yet in
- a standard system header file.
-
-Environment:
-
- user mode
-
-Revision History:
-
- 03-06-1998 : created
-
---*/
-
-#include <pshpack1.h>
-
-//*****************************************************************************
-// D E F I N E S
-//*****************************************************************************
-
-#define USB_HID_DESCRIPTOR_TYPE 0x21
-
-
-//
-// USB Device Class Definition for Audio Devices
-// Appendix A. Audio Device Class Codes
-//
-
-// A.2 Audio Interface Subclass Codes
-//
-#define USB_AUDIO_SUBCLASS_UNDEFINED 0x00
-#define USB_AUDIO_SUBCLASS_AUDIOCONTROL 0x01
-#define USB_AUDIO_SUBCLASS_AUDIOSTREAMING 0x02
-#define USB_AUDIO_SUBCLASS_MIDISTREAMING 0x03
-
-// A.4 Audio Class-Specific Descriptor Types
-//
-#define USB_AUDIO_CS_UNDEFINED 0x20
-#define USB_AUDIO_CS_DEVICE 0x21
-#define USB_AUDIO_CS_CONFIGURATION 0x23
-#define USB_AUDIO_CS_STRING 0x24
-#define USB_AUDIO_CS_INTERFACE 0x24
-#define USB_AUDIO_CS_ENDPOINT 0x25
-
-// A.5 Audio Class-Specific AC (Audio Control) Interface Descriptor Subtypes
-//
-#define USB_AUDIO_AC_UNDEFINED 0x00
-#define USB_AUDIO_AC_HEADER 0x01
-#define USB_AUDIO_AC_INPUT_TERMINAL 0x02
-#define USB_AUDIO_AC_OUTPUT_TERMINAL 0x03
-#define USB_AUDIO_AC_MIXER_UNIT 0x04
-#define USB_AUDIO_AC_SELECTOR_UNIT 0x05
-#define USB_AUDIO_AC_FEATURE_UNIT 0x06
-#define USB_AUDIO_AC_PROCESSING_UNIT 0x07
-#define USB_AUDIO_AC_EXTENSION_UNIT 0x08
-
-// A.6 Audio Class-Specific AS (Audio Streaming) Interface Descriptor Subtypes
-//
-#define USB_AUDIO_AS_UNDEFINED 0x00
-#define USB_AUDIO_AS_GENERAL 0x01
-#define USB_AUDIO_AS_FORMAT_TYPE 0x02
-#define USB_AUDIO_AS_FORMAT_SPECIFIC 0x03
-
-// A.7 Processing Unit Process Types
-//
-#define USB_AUDIO_PROCESS_UNDEFINED 0x00
-#define USB_AUDIO_PROCESS_UPDOWNMIX 0x01
-#define USB_AUDIO_PROCESS_DOLBYPROLOGIC 0x02
-#define USB_AUDIO_PROCESS_3DSTEREOEXTENDER 0x03
-#define USB_AUDIO_PROCESS_REVERBERATION 0x04
-#define USB_AUDIO_PROCESS_CHORUS 0x05
-#define USB_AUDIO_PROCESS_DYNRANGECOMP 0x06
-
-
-//*****************************************************************************
-// T Y P E D E F S
-//*****************************************************************************
-
-// HID Class HID Descriptor
-//
-typedef struct _USB_HID_DESCRIPTOR
-{
- UCHAR bLength;
- UCHAR bDescriptorType;
- USHORT bcdHID;
- UCHAR bCountryCode;
- UCHAR bNumDescriptors;
- struct
- {
- UCHAR bDescriptorType;
- USHORT wDescriptorLength;
- } OptionalDescriptors[1];
-} USB_HID_DESCRIPTOR, *PUSB_HID_DESCRIPTOR;
-
-
-// Common Class Endpoint Descriptor
-//
-typedef struct _USB_ENDPOINT_DESCRIPTOR2 {
- UCHAR bLength; // offset 0, size 1
- UCHAR bDescriptorType; // offset 1, size 1
- UCHAR bEndpointAddress; // offset 2, size 1
- UCHAR bmAttributes; // offset 3, size 1
- USHORT wMaxPacketSize; // offset 4, size 2
- USHORT wInterval; // offset 6, size 2
- UCHAR bSyncAddress; // offset 8, size 1
-} USB_ENDPOINT_DESCRIPTOR2, *PUSB_ENDPOINT_DESCRIPTOR2;
-
-// Common Class Interface Descriptor
-//
-typedef struct _USB_INTERFACE_DESCRIPTOR2 {
- UCHAR bLength; // offset 0, size 1
- UCHAR bDescriptorType; // offset 1, size 1
- UCHAR bInterfaceNumber; // offset 2, size 1
- UCHAR bAlternateSetting; // offset 3, size 1
- UCHAR bNumEndpoints; // offset 4, size 1
- UCHAR bInterfaceClass; // offset 5, size 1
- UCHAR bInterfaceSubClass; // offset 6, size 1
- UCHAR bInterfaceProtocol; // offset 7, size 1
- UCHAR iInterface; // offset 8, size 1
- USHORT wNumClasses; // offset 9, size 2
-} USB_INTERFACE_DESCRIPTOR2, *PUSB_INTERFACE_DESCRIPTOR2;
-
-
-//
-// USB Device Class Definition for Audio Devices
-//
-
-typedef struct _USB_AUDIO_COMMON_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
-} USB_AUDIO_COMMON_DESCRIPTOR,
-*PUSB_AUDIO_COMMON_DESCRIPTOR;
-
-// 4.3.2 Class-Specific AC (Audio Control) Interface Descriptor
-//
-typedef struct _USB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- USHORT bcdADC;
- USHORT wTotalLength;
- UCHAR bInCollection;
- UCHAR baInterfaceNr[1];
-} USB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR,
-*PUSB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR;
-
-// 4.3.2.1 Input Terminal Descriptor
-//
-typedef struct _USB_AUDIO_INPUT_TERMINAL_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- UCHAR bTerminalID;
- USHORT wTerminalType;
- UCHAR bAssocTerminal;
- UCHAR bNrChannels;
- USHORT wChannelConfig;
- UCHAR iChannelNames;
- UCHAR iTerminal;
-} USB_AUDIO_INPUT_TERMINAL_DESCRIPTOR,
-*PUSB_AUDIO_INPUT_TERMINAL_DESCRIPTOR;
-
-// 4.3.2.2 Output Terminal Descriptor
-//
-typedef struct _USB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- UCHAR bTerminalID;
- USHORT wTerminalType;
- UCHAR bAssocTerminal;
- UCHAR bSoruceID;
- UCHAR iTerminal;
-} USB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR,
-*PUSB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR;
-
-// 4.3.2.3 Mixer Unit Descriptor
-//
-typedef struct _USB_AUDIO_MIXER_UNIT_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- UCHAR bUnitID;
- UCHAR bNrInPins;
- UCHAR baSourceID[1];
-} USB_AUDIO_MIXER_UNIT_DESCRIPTOR,
-*PUSB_AUDIO_MIXER_UNIT_DESCRIPTOR;
-
-// 4.3.2.4 Selector Unit Descriptor
-//
-typedef struct _USB_AUDIO_SELECTOR_UNIT_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- UCHAR bUnitID;
- UCHAR bNrInPins;
- UCHAR baSourceID[1];
-} USB_AUDIO_SELECTOR_UNIT_DESCRIPTOR,
-*PUSB_AUDIO_SELECTOR_UNIT_DESCRIPTOR;
-
-// 4.3.2.5 Feature Unit Descriptor
-//
-typedef struct _USB_AUDIO_FEATURE_UNIT_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- UCHAR bUnitID;
- UCHAR bSourceID;
- UCHAR bControlSize;
- UCHAR bmaControls[1];
-} USB_AUDIO_FEATURE_UNIT_DESCRIPTOR,
-*PUSB_AUDIO_FEATURE_UNIT_DESCRIPTOR;
-
-// 4.3.2.6 Processing Unit Descriptor
-//
-typedef struct _USB_AUDIO_PROCESSING_UNIT_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- UCHAR bUnitID;
- USHORT wProcessType;
- UCHAR bNrInPins;
- UCHAR baSourceID[1];
-} USB_AUDIO_PROCESSING_UNIT_DESCRIPTOR,
-*PUSB_AUDIO_PROCESSING_UNIT_DESCRIPTOR;
-
-// 4.3.2.7 Extension Unit Descriptor
-//
-typedef struct _USB_AUDIO_EXTENSION_UNIT_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- UCHAR bUnitID;
- USHORT wExtensionCode;
- UCHAR bNrInPins;
- UCHAR baSourceID[1];
-} USB_AUDIO_EXTENSION_UNIT_DESCRIPTOR,
-*PUSB_AUDIO_EXTENSION_UNIT_DESCRIPTOR;
-
-// 4.5.2 Class-Specific AS Interface Descriptor
-//
-typedef struct _USB_AUDIO_GENERAL_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- UCHAR bTerminalLink;
- UCHAR bDelay;
- USHORT wFormatTag;
-} USB_AUDIO_GENERAL_DESCRIPTOR,
-*PUSB_AUDIO_GENERAL_DESCRIPTOR;
-
-// 4.6.1.2 Class-Specific AS Endpoint Descriptor
-//
-typedef struct _USB_AUDIO_ENDPOINT_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- UCHAR bmAttributes;
- UCHAR bLockDelayUnits;
- USHORT wLockDelay;
-} USB_AUDIO_ENDPOINT_DESCRIPTOR,
-*PUSB_AUDIO_ENDPOINT_DESCRIPTOR;
-
-
-//
-// USB Device Class Definition for Audio Data Formats
-//
-
-typedef struct _USB_AUDIO_COMMON_FORMAT_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- UCHAR bFormatType;
-} USB_AUDIO_COMMON_FORMAT_DESCRIPTOR,
-*PUSB_AUDIO_COMMON_FORMAT_DESCRIPTOR;
-
-
-// 2.1.5 Type I Format Type Descriptor
-// 2.3.1 Type III Format Type Descriptor
-//
-typedef struct _USB_AUDIO_TYPE_I_OR_III_FORMAT_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- UCHAR bFormatType;
- UCHAR bNrChannels;
- UCHAR bSubframeSize;
- UCHAR bBitResolution;
- UCHAR bSamFreqType;
-} USB_AUDIO_TYPE_I_OR_III_FORMAT_DESCRIPTOR,
-*PUSB_AUDIO_TYPE_I_OR_III_FORMAT_DESCRIPTOR;
-
-
-// 2.2.6 Type II Format Type Descriptor
-//
-typedef struct _USB_AUDIO_TYPE_II_FORMAT_DESCRIPTOR {
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bDescriptorSubtype;
- UCHAR bFormatType;
- USHORT wMaxBitRate;
- USHORT wSamplesPerFrame;
- UCHAR bSamFreqType;
-} USB_AUDIO_TYPE_II_FORMAT_DESCRIPTOR,
-*PUSB_AUDIO_TYPE_II_FORMAT_DESCRIPTOR;
-
-
-#include <poppack.h>
diff --git a/src/VBox/HostDrivers/darwin/Makefile.kmk b/src/VBox/HostDrivers/darwin/Makefile.kmk
index e717ddf61..99a823a75 100644
--- a/src/VBox/HostDrivers/darwin/Makefile.kmk
+++ b/src/VBox/HostDrivers/darwin/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-makefile for the darwin host driver helper scripts.
#
diff --git a/src/VBox/HostDrivers/darwin/loadall.sh b/src/VBox/HostDrivers/darwin/loadall.sh
index 058b85e93..058b85e93 100755..100644
--- a/src/VBox/HostDrivers/darwin/loadall.sh
+++ b/src/VBox/HostDrivers/darwin/loadall.sh
diff --git a/src/VBox/HostDrivers/linux/Makefile b/src/VBox/HostDrivers/linux/Makefile
index a95109bd5..b569e68e6 100644
--- a/src/VBox/HostDrivers/linux/Makefile
+++ b/src/VBox/HostDrivers/linux/Makefile
@@ -26,7 +26,9 @@ endif
ifneq ($(wildcard $(KBUILD_EXTMOD)/vboxnetadp/Makefile),)
obj-m += vboxnetadp/
endif
-
+ifneq ($(wildcard $(KBUILD_EXTMOD)/vboxpci/Makefile),)
+ obj-m += vboxpci/
+endif
else # ! KBUILD_EXTMOD
# convenience Makefile without DKMS
@@ -56,6 +58,15 @@ all:
cp vboxnetadp/vboxnetadp.ko .; \
echo; \
fi
+ @if [ -d vboxpci ]; then \
+ if [ -f vboxdrv/Module.symvers ]; then \
+ cp vboxdrv/Module.symvers vboxpci; \
+ fi; \
+ echo "*** Building 'vboxpci' module ***"; \
+ $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C vboxpci; \
+ cp vboxpci/vboxpci.ko .; \
+ echo; \
+ fi
install:
@$(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C vboxdrv install
@@ -65,6 +76,9 @@ install:
@if [ -d vboxnetadp ]; then \
$(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C vboxnetadp install; \
fi
+ @if [ -d vboxpci ]; then \
+ $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C vboxpci install; \
+ fi
clean:
@$(MAKE) -C vboxdrv clean
@@ -74,7 +88,10 @@ clean:
@if [ -d vboxnetadp ]; then \
$(MAKE) -C vboxnetadp clean; \
fi
- rm -f vboxdrv.ko vboxnetflt.ko vboxnetadp.ko
+ @if [ -d vboxpci ]; then \
+ $(MAKE) -C vboxpci clean; \
+ fi
+ rm -f vboxdrv.ko vboxnetflt.ko vboxnetadp.ko vboxpci.ko
check:
@$(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C vboxdrv check
@@ -88,7 +105,7 @@ unload:
done
load: unload
- @for module in vboxdrv vboxnetflt vboxnetadp; do \
+ @for module in vboxdrv vboxnetflt vboxnetadp vboxpci; do \
if test -f $$module.ko; then \
echo "Installing $$module module"; \
/sbin/insmod $$module.ko; \
diff --git a/src/VBox/HostDrivers/linux/dkms.conf b/src/VBox/HostDrivers/linux/dkms.conf
index 3293712d7..672c099dc 100644
--- a/src/VBox/HostDrivers/linux/dkms.conf
+++ b/src/VBox/HostDrivers/linux/dkms.conf
@@ -29,3 +29,7 @@ _OMIT_VBOXNETFLT_DEST_MODULE_LOCATION[1]="/kernel/misc"
_OMIT_VBOXNETADP_BUILT_MODULE_NAME[2]="vboxnetadp"
_OMIT_VBOXNETADP_BUILT_MODULE_LOCATION[2]="vboxnetadp"
_OMIT_VBOXNETADP_DEST_MODULE_LOCATION[2]="/kernel/misc"
+
+_OMIT_VBOXPCI_BUILT_MODULE_NAME[3]="vboxpci"
+_OMIT_VBOXPCI_BUILT_MODULE_LOCATION[3]="vboxpci"
+_OMIT_VBOXPCI_DEST_MODULE_LOCATION[3]="/kernel/misc"
diff --git a/src/VBox/HostDrivers/linux/do_Module.symvers b/src/VBox/HostDrivers/linux/do_Module.symvers
index 36be428de..36be428de 100755..100644
--- a/src/VBox/HostDrivers/linux/do_Module.symvers
+++ b/src/VBox/HostDrivers/linux/do_Module.symvers
diff --git a/src/VBox/HostDrivers/linux/export_modules b/src/VBox/HostDrivers/linux/export_modules
index fc682dd08..58e5cc41a 100755
--- a/src/VBox/HostDrivers/linux/export_modules
+++ b/src/VBox/HostDrivers/linux/export_modules
@@ -33,16 +33,18 @@ PATH_LINUX="$PATH_ROOT/src/VBox/HostDrivers/linux"
PATH_VBOXDRV="$PATH_ROOT/src/VBox/HostDrivers/Support"
PATH_VBOXNET="$PATH_ROOT/src/VBox/HostDrivers/VBoxNetFlt"
PATH_VBOXADP="$PATH_ROOT/src/VBox/HostDrivers/VBoxNetAdp"
+PATH_VBOXPCI="$PATH_ROOT/src/VBox/HostDrivers/VBoxPci"
VBOX_VERSION_MAJOR=`sed -e "s/^ *VBOX_VERSION_MAJOR *= \+\([0-9]\+\)/\1/;t;d" $PATH_ROOT/Config.kmk`
VBOX_VERSION_MINOR=`sed -e "s/^ *VBOX_VERSION_MINOR *= \+\([0-9]\+\)/\1/;t;d" $PATH_ROOT/Config.kmk`
VBOX_VERSION_BUILD=`sed -e "s/^ *VBOX_VERSION_BUILD *= \+\([0-9]\+\)/\1/;t;d" $PATH_ROOT/Config.kmk`
VBOX_VERSION_STRING=$VBOX_VERSION_MAJOR.$VBOX_VERSION_MINOR.$VBOX_VERSION_BUILD
-VBOX_SVN_REV=`sed -e 's/^ *VBOX_SVN_REV_FALLBACK *:= \+\$(patsubst *%:,, *\$Rev: *\([0-9]\+\) *\$ *) */\1/;t;d' $PATH_ROOT/Config.kmk` VBOX_VENDOR=`sed -e 's/^ *VBOX_VENDOR *= \+\(.\+\)/\1/;t;d' $PATH_ROOT/Config.kmk` VBOX_VENDOR_SHORT=`sed -e 's/^ *VBOX_VENDOR_SHORT *= \+\(.\+\)/\1/;t;d' $PATH_ROOT/Config.kmk` VBOX_PRODUCT=`sed -e 's/^ *VBOX_PRODUCT *= \+\(.\+\)/\1/;t;d' $PATH_ROOT/Config.kmk` VBOX_C_YEAR=`date +%Y`
+VBOX_SVN_REV=`sed -e 's/^ *VBOX_SVN_REV_FALLBACK *:= \+\$(patsubst *%:,, *\$Rev: *\([0-9]\+\) *\$ *) */\1/;t;d' $PATH_ROOT/Config.kmk` VBOX_VENDOR=`sed -e 's/^ *VBOX_VENDOR *= \+\(.\+\)/\1/;t;d' $PATH_ROOT/Config.kmk` VBOX_VENDOR_SHORT=`sed -e 's/^ *VBOX_VENDOR_SHORT *= \+\(.\+\)/\1/;t;d' $PATH_ROOT/Config.kmk` VBOX_PRODUCT=`sed -e 's/^ *VBOX_PRODUCT *= \+\(.\+\)/\1/;t;d' $PATH_ROOT/Config.kmk` VBOX_C_YEAR=`date +%Y`
. $PATH_VBOXDRV/linux/files_vboxdrv
. $PATH_VBOXNET/linux/files_vboxnetflt
. $PATH_VBOXADP/linux/files_vboxnetadp
+. $PATH_VBOXPCI/linux/files_vboxpci
# Temporary path for creating the modules, will be removed later
mkdir $PATH_TMP || exit 1
@@ -123,6 +125,20 @@ else
sed -e "s;-DVBOX_WITH_HARDENING;;g" < $PATH_VBOXADP/linux/Makefile > $PATH_TMP/vboxnetadp/Makefile
fi
+# vboxpci (VirtualBox host PCI access kernel module)
+mkdir $PATH_TMP/vboxpci || exit 1
+for f in $VBOX_VBOXPCI_SOURCES; do
+ install -D -m 0644 `echo $f|cut -d'=' -f1` "$PATH_TMP/vboxpci/`echo $f|cut -d'>' -f2`"
+done
+sed -e "s;_VERSION_;$VBOX_VERSION_STRING;g" < $PATH_LINUX/build_in_tmp > $PATH_TMP/vboxpci/build_in_tmp
+chmod 0755 $PATH_TMP/vboxpci/build_in_tmp
+sed -e "s;_VERSION_;$VBOX_VERSION_STRING;g" < $PATH_VBOXPCI/linux/dkms.conf > $PATH_TMP/vboxpci/dkms.conf
+if [ -n "$VBOX_WITH_HARDENING" ]; then
+ cat $PATH_VBOXPCI/linux/Makefile > $PATH_TMP/vboxpci/Makefile
+else
+ sed -e "s;-DVBOX_WITH_HARDENING;;g" < $PATH_VBOXPCI/linux/Makefile > $PATH_TMP/vboxpci/Makefile
+fi
+
install -D -m 0644 $PATH_LINUX/Makefile $PATH_TMP/Makefile
# Only temporary, omit from archive
@@ -135,4 +151,3 @@ tar -czf $FILE_OUT -C $PATH_TMP . || exit 1
# Remove the temporary directory
rm -r $PATH_TMP
-
diff --git a/src/VBox/HostDrivers/win/Makefile.kmk b/src/VBox/HostDrivers/win/Makefile.kmk
new file mode 100644
index 000000000..19c15d58d
--- /dev/null
+++ b/src/VBox/HostDrivers/win/Makefile.kmk
@@ -0,0 +1,29 @@
+# $Id: Makefile.kmk 36871 2011-04-28 07:57:12Z vboxsync $
+## @file
+# Sub-Makefile for Windows driver tooling lib.
+#
+
+#
+# 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.
+#
+
+SUB_DEPTH = ../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+LIBRARIES += VBoxDrvCfg
+VBoxDrvCfg_TEMPLATE = VBOXR3STATIC
+VBoxDrvCfg_SDKS = WINPSDK W2K3DDK
+VBoxDrvCfg_DEFS = _WIN32_WINNT=0x0501 _UNICODE UNICODE
+VBoxDrvCfg_SOURCES = cfg/VBoxDrvCfg.cpp
+
+# generate rules
+include $(KBUILD_PATH)/subfooter.kmk
+
diff --git a/src/VBox/HostDrivers/win/cfg/Makefile.kup b/src/VBox/HostDrivers/win/cfg/Makefile.kup
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/VBox/HostDrivers/win/cfg/Makefile.kup
diff --git a/src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp b/src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp
new file mode 100644
index 000000000..a1a9bf05d
--- /dev/null
+++ b/src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp
@@ -0,0 +1,812 @@
+/* $Id: VBoxDrvCfg.cpp 36941 2011-05-03 14:56:08Z vboxsync $ */
+/** @file
+ * VBoxDrvCfg.cpp - Windows Driver Manipulation API implementation
+ */
+/*
+ * 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.
+ */
+#include <VBox/VBoxDrvCfg-win.h>
+
+#include <setupapi.h>
+#include <shlobj.h>
+
+#include <string.h>
+
+#include <stdlib.h>
+#include <malloc.h>
+#include <stdio.h>
+
+static PFNVBOXDRVCFG_LOG g_pfnVBoxDrvCfgLog;
+static void *g_pvVBoxDrvCfgLog;
+
+static PFNVBOXDRVCFG_PANIC g_pfnVBoxDrvCfgPanic;
+static void *g_pvVBoxDrvCfgPanic;
+
+
+VBOXDRVCFG_DECL(void) VBoxDrvCfgLoggerSet(PFNVBOXDRVCFG_LOG pfnLog, void *pvLog)
+{
+ g_pfnVBoxDrvCfgLog = pfnLog;
+ g_pvVBoxDrvCfgLog = pvLog;
+}
+
+VBOXDRVCFG_DECL(void) VBoxDrvCfgPanicSet(PFNVBOXDRVCFG_PANIC pfnPanic, void *pvPanic)
+{
+ g_pfnVBoxDrvCfgPanic = pfnPanic;
+ g_pvVBoxDrvCfgPanic = pvPanic;
+}
+
+static void vboxDrvCfgLogRel(LPCSTR szString, ...)
+{
+ PFNVBOXDRVCFG_LOG pfnLog = g_pfnVBoxDrvCfgLog;
+ void * pvLog = g_pvVBoxDrvCfgLog;
+ if (pfnLog)
+ {
+ char szBuffer[4096] = {0};
+ va_list pArgList;
+ va_start(pArgList, szString);
+ _vsnprintf(szBuffer, RT_ELEMENTS(szBuffer), szString, pArgList);
+ va_end(pArgList);
+ pfnLog(VBOXDRVCFG_LOG_SEVERITY_REL, szBuffer, pvLog);
+ }
+}
+
+static void vboxDrvCfgLogRegular(LPCSTR szString, ...)
+{
+ PFNVBOXDRVCFG_LOG pfnLog = g_pfnVBoxDrvCfgLog;
+ void * pvLog = g_pvVBoxDrvCfgLog;
+ if (pfnLog)
+ {
+ char szBuffer[4096] = {0};
+ va_list pArgList;
+ va_start(pArgList, szString);
+ _vsnprintf(szBuffer, RT_ELEMENTS(szBuffer), szString, pArgList);
+ va_end(pArgList);
+ pfnLog(VBOXDRVCFG_LOG_SEVERITY_REGULAR, szBuffer, pvLog);
+ }
+}
+
+static void vboxDrvCfgLogFlow(LPCSTR szString, ...)
+{
+ PFNVBOXDRVCFG_LOG pfnLog = g_pfnVBoxDrvCfgLog;
+ void * pvLog = g_pvVBoxDrvCfgLog;
+ if (pfnLog)
+ {
+ char szBuffer[4096] = {0};
+ va_list pArgList;
+ va_start(pArgList, szString);
+ _vsnprintf(szBuffer, RT_ELEMENTS(szBuffer), szString, pArgList);
+ va_end(pArgList);
+ pfnLog(VBOXDRVCFG_LOG_SEVERITY_FLOW, szBuffer, pvLog);
+ }
+}
+
+static void vboxDrvCfgPanic()
+{
+ PFNVBOXDRVCFG_PANIC pfnPanic = g_pfnVBoxDrvCfgPanic;
+ void * pvPanic = g_pvVBoxDrvCfgPanic;
+ if (pfnPanic)
+ {
+ pfnPanic(pvPanic);
+ }
+}
+
+/* we do not use IPRT Logging because the lib is used in host installer and needs to
+ * post its msgs to MSI logger */
+#define Log(_m) do { vboxDrvCfgLogRegular _m ; } while (0)
+#define LogFlow(_m) do { vboxDrvCfgLogFlow _m ; } while (0)
+#define LogRel(_m) do { vboxDrvCfgLogRel _m ; } while (0)
+#define AssertFailed() vboxDrvCfgPanic()
+#define Assert(_m) do { \
+ if (RT_UNLIKELY(!(_m))) { vboxDrvCfgPanic(); } \
+ } while (0)
+
+
+class VBoxDrvCfgStringList
+{
+public:
+ VBoxDrvCfgStringList(int aSize);
+
+ ~VBoxDrvCfgStringList();
+
+ HRESULT add(LPWSTR pStr);
+
+ int size() {return mSize;}
+
+ LPWSTR get(int i) {return maList[i];}
+private:
+ HRESULT resize(int newSize);
+
+ LPWSTR *maList;
+ int mBufSize;
+ int mSize;
+};
+
+VBoxDrvCfgStringList::VBoxDrvCfgStringList(int aSize)
+{
+ maList = (LPWSTR*)malloc( sizeof(maList[0]) * aSize);
+ mBufSize = aSize;
+ mSize = 0;
+}
+
+VBoxDrvCfgStringList::~VBoxDrvCfgStringList()
+{
+ if (!mBufSize)
+ return;
+
+ for (int i = 0; i < mSize; ++i)
+ {
+ free(maList[i]);
+ }
+
+ free(maList);
+}
+
+HRESULT VBoxDrvCfgStringList::add(LPWSTR pStr)
+{
+ if (mSize == mBufSize)
+ {
+ int hr = resize(mBufSize+10);
+ if (SUCCEEDED(hr))
+ return hr;
+ }
+ size_t cStr = wcslen(pStr) + 1;
+ LPWSTR str = (LPWSTR)malloc( sizeof(maList[0][0]) * cStr);
+ memcpy(str, pStr, sizeof(maList[0][0]) * cStr);
+ maList[mSize] = str;
+ ++mSize;
+ return S_OK;
+}
+
+HRESULT VBoxDrvCfgStringList::resize(int newSize)
+{
+ Assert(newSize >= mSize);
+ if (newSize < mSize)
+ return E_FAIL;
+ LPWSTR* pOld = maList;
+ maList = (LPWSTR*)malloc( sizeof(maList[0]) * newSize);
+ mBufSize = newSize;
+ memcpy(maList, pOld, mSize*sizeof(maList[0]));
+ free(pOld);
+ return S_OK;
+}
+
+/*
+ * inf file manipulation API
+ */
+typedef bool (*PFNVBOXNETCFG_ENUMERATION_CALLBACK) (LPCWSTR lpszFileName, PVOID pContext);
+
+typedef struct _INF_INFO
+{
+ LPCWSTR lpszClassName;
+ LPCWSTR lpszPnPId;
+} INF_INFO, *PINF_INFO;
+
+typedef struct _INFENUM_CONTEXT
+{
+ INF_INFO InfInfo;
+ DWORD Flags;
+ HRESULT hr;
+} INFENUM_CONTEXT, *PINFENUM_CONTEXT;
+
+static HRESULT vboxDrvCfgInfQueryContext(HINF hInf, LPCWSTR lpszSection, LPCWSTR lpszKey, PINFCONTEXT pCtx)
+{
+ if (!SetupFindFirstLineW(hInf, lpszSection, lpszKey, pCtx))
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__ ": SetupFindFirstLine failed WinEr (%d) for Section(%S), Key(%S)\n", winEr, lpszSection, lpszKey));
+ return HRESULT_FROM_WIN32(winEr);
+ }
+ return S_OK;
+}
+
+static HRESULT vboxDrvCfgInfQueryKeyValue(PINFCONTEXT pCtx, DWORD iValue, LPWSTR *lppszValue, PDWORD pcValue)
+{
+ DWORD winEr;
+ DWORD cValue;
+
+ if (!SetupGetStringFieldW(pCtx, iValue, NULL, 0, &cValue))
+ {
+ winEr = GetLastError();
+// Assert(winEr == ERROR_INSUFFICIENT_BUFFER);
+ if (winEr != ERROR_INSUFFICIENT_BUFFER)
+ {
+ LogFlow((__FUNCTION__ ": SetupGetStringField failed WinEr (%d) for iValue(%d)\n", winEr, iValue));
+ return HRESULT_FROM_WIN32(winEr);
+ }
+ }
+
+ LPWSTR lpszValue = (LPWSTR)malloc(cValue * sizeof (lpszValue[0]));
+ Assert(lpszValue);
+ if (!lpszValue)
+ {
+ LogRel((__FUNCTION__ ": SetCoTaskMemAlloc failed to alloc mem of size (%d), for iValue(%d)\n", cValue * sizeof (lpszValue[0]), winEr, iValue));
+ return E_FAIL;
+ }
+
+ if (!SetupGetStringFieldW(pCtx, iValue, lpszValue, cValue, &cValue))
+ {
+ winEr = GetLastError();
+ LogRel((__FUNCTION__ ": SetupGetStringField failed WinEr (%d) for iValue(%d)\n", winEr, iValue));
+ Assert(0);
+ free(lpszValue);
+ return HRESULT_FROM_WIN32(winEr);
+ }
+
+ *lppszValue = lpszValue;
+ if (pcValue)
+ *pcValue = cValue;
+ return S_OK;
+}
+#if defined(RT_ARCH_AMD64)
+# define VBOXDRVCFG_ARCHSTR L"amd64"
+#else
+# define VBOXDRVCFG_ARCHSTR L"x86"
+#endif
+
+static HRESULT vboxDrvCfgInfQueryModelsSectionName(HINF hInf, LPWSTR *lppszValue, PDWORD pcValue)
+{
+ INFCONTEXT InfCtx;
+ LPWSTR lpszModels, lpszPlatform = NULL, lpszPlatformCur;
+ LPWSTR lpszResult = NULL;
+ DWORD cModels, cPlatform = 0, cPlatformCur, cResult = 0;
+ bool bNt = false, bArch = false /*, bOs = false */;
+
+ HRESULT hr = vboxDrvCfgInfQueryContext(hInf, L"Manufacturer", NULL, &InfCtx);
+ if (hr != S_OK)
+ {
+ Log((__FUNCTION__ ": vboxDrvCfgInfQueryContext for Manufacturer failed, hr = (0x%x)\n", hr));
+ return hr;
+ }
+
+ hr = vboxDrvCfgInfQueryKeyValue(&InfCtx, 1, &lpszModels, &cModels);
+ if (hr != S_OK)
+ {
+ LogRel((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue 1 for Manufacturer failed, hr = (0x%x)\n", hr));
+ return hr;
+ }
+
+ for (DWORD i = 2; (hr = vboxDrvCfgInfQueryKeyValue(&InfCtx, i, &lpszPlatformCur, &cPlatformCur)) == S_OK; ++i)
+ {
+ if (wcsicmp(lpszPlatformCur, L"NT"VBOXDRVCFG_ARCHSTR))
+ {
+ if (bNt)
+ {
+ free(lpszPlatformCur);
+ lpszPlatformCur = NULL;
+ continue;
+ }
+
+ if (wcsicmp(lpszPlatformCur, L"NT"))
+ {
+ free(lpszPlatformCur);
+ lpszPlatformCur = NULL;
+ continue;
+ }
+
+ bNt = true;
+ }
+ else
+ {
+ bArch = true;
+ }
+
+ cPlatform = cPlatformCur;
+ if(lpszPlatform)
+ free(lpszPlatform);
+ lpszPlatform = lpszPlatformCur;
+ lpszPlatformCur = NULL;
+ }
+
+ hr = S_OK;
+
+ if (lpszPlatform)
+ {
+ lpszResult = (LPWSTR)malloc((cModels + cPlatform) * sizeof (lpszResult[0]));
+ if (lpszResult)
+ {
+ memcpy(lpszResult, lpszModels, (cModels - 1) * sizeof (lpszResult[0]));
+ *(lpszResult + cModels - 1) = L'.';
+ memcpy(lpszResult + cModels, lpszPlatform, cPlatform * sizeof (lpszResult[0]));
+ cResult = cModels + cPlatform;
+ }
+ else
+ {
+ hr = E_FAIL;
+ }
+ }
+ else
+ {
+ lpszResult = lpszModels;
+ cResult = cModels;
+ lpszModels = NULL;
+ }
+
+ if (lpszModels)
+ free(lpszModels);
+ if (lpszPlatform)
+ free(lpszPlatform);
+
+ if (hr == S_OK)
+ {
+ *lppszValue = lpszResult;
+ if (pcValue)
+ *pcValue = cResult;
+ }
+
+ return hr;
+}
+
+static HRESULT vboxDrvCfgInfQueryFirstPnPId(HINF hInf, LPWSTR *lppszPnPId)
+{
+ LPWSTR lpszModels;
+ LPWSTR lpszPnPId;
+ HRESULT hr = vboxDrvCfgInfQueryModelsSectionName(hInf, &lpszModels, NULL);
+ if (hr != S_OK)
+ {
+ Log((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for Manufacturer failed, hr = (0x%x)\n", hr));
+ return hr;
+ }
+
+ INFCONTEXT InfCtx;
+ hr = vboxDrvCfgInfQueryContext(hInf, lpszModels, NULL, &InfCtx);
+ if (hr != S_OK)
+ {
+ LogRel((__FUNCTION__ ": vboxDrvCfgInfQueryContext for models (%S) failed, hr = (0x%x)\n", lpszModels, hr));
+ }
+ else
+ {
+ hr = vboxDrvCfgInfQueryKeyValue(&InfCtx, 2, &lpszPnPId, NULL);
+ if (hr != S_OK)
+ {
+ LogRel((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for models (%S) failed, hr = (0x%x)\n", lpszModels, hr));
+ }
+ }
+ /* free models string right away */
+ free(lpszModels);
+ if (hr != S_OK)
+ {
+ return hr;
+ }
+
+ *lppszPnPId = lpszPnPId;
+ return S_OK;
+}
+
+static bool vboxDrvCfgInfEnumerationCallback(LPCWSTR lpszFileName, PVOID pCtxt);
+
+#define VBOXDRVCFG_S_INFEXISTS (HRESULT_FROM_WIN32(ERROR_FILE_EXISTS))
+
+static HRESULT vboxDrvCfgInfCopyEx(IN LPCWSTR lpszInfPath, IN DWORD fCopyStyle, OUT LPWSTR lpszDstName, IN DWORD cbDstName, OUT PDWORD pcbDstNameSize, OUT LPWSTR* lpszDstNameComponent)
+{
+ WCHAR aMediaLocation[_MAX_DIR];
+ WCHAR aDir[_MAX_DIR];
+
+ _wsplitpath(lpszInfPath, aMediaLocation, aDir, NULL, NULL);
+ wcscat(aMediaLocation, aDir);
+
+ if (!SetupCopyOEMInfW(lpszInfPath, aMediaLocation, SPOST_PATH, fCopyStyle,
+ lpszDstName, cbDstName, pcbDstNameSize,
+ lpszDstNameComponent))
+ {
+ DWORD winEr = GetLastError();
+ HRESULT hr = HRESULT_FROM_WIN32(winEr);
+ if (fCopyStyle != SP_COPY_REPLACEONLY || hr != VBOXDRVCFG_S_INFEXISTS)
+ {
+ LogRel((__FUNCTION__ ": SetupCopyOEMInf fail winEr (%d)\n", winEr));
+ }
+ return hr;
+ }
+
+ return S_OK;
+}
+
+static HRESULT vboxDrvCfgInfCopy(IN LPCWSTR lpszInfPath)
+{
+ return vboxDrvCfgInfCopyEx(lpszInfPath, 0, NULL, 0, NULL, NULL);
+}
+
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfInstall(IN LPCWSTR lpszInfPath)
+{
+ return vboxDrvCfgInfCopy(lpszInfPath);
+}
+
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstall(IN LPCWSTR lpszInfPath, DWORD fFlags)
+{
+ WCHAR DstInfName[MAX_PATH];
+ DWORD cbDword = sizeof (DstInfName);
+ HRESULT hr = vboxDrvCfgInfCopyEx(lpszInfPath, SP_COPY_REPLACEONLY, DstInfName, cbDword, &cbDword, NULL);
+ if (hr == VBOXDRVCFG_S_INFEXISTS)
+ {
+ if (!SetupUninstallOEMInfW(DstInfName, fFlags, NULL /*__in PVOID Reserved == NULL */))
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__ ": SetupUninstallOEMInf failed for file (%S), oem(%S), winEr (%d)\n", lpszInfPath, DstInfName, winEr));
+ Assert(0);
+ return HRESULT_FROM_WIN32(winEr);
+ }
+ }
+ return S_OK;
+}
+
+
+static HRESULT vboxDrvCfgCollectInfsSetupDi(const GUID * pGuid, LPCWSTR pPnPId, VBoxDrvCfgStringList & list)
+{
+ DWORD winEr = ERROR_SUCCESS;
+ int counter = 0;
+ HDEVINFO hDevInfo = SetupDiCreateDeviceInfoList(
+ pGuid, /* IN LPGUID ClassGuid, OPTIONAL */
+ NULL /*IN HWND hwndParent OPTIONAL */
+ );
+ if (hDevInfo != INVALID_HANDLE_VALUE)
+ {
+ if (SetupDiBuildDriverInfoList(hDevInfo,
+ NULL, /*IN OUT PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
+ SPDIT_CLASSDRIVER /*IN DWORD DriverType*/
+ ))
+ {
+ SP_DRVINFO_DATA DrvInfo;
+ DrvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
+ char DetailBuf[16384];
+ PSP_DRVINFO_DETAIL_DATA pDrvDetail = (PSP_DRVINFO_DETAIL_DATA)DetailBuf;
+
+ for (DWORD i = 0; ; i++)
+ {
+ if (SetupDiEnumDriverInfo(hDevInfo,
+ NULL, /* IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
+ SPDIT_CLASSDRIVER , /*IN DWORD DriverType,*/
+ i, /*IN DWORD MemberIndex,*/
+ &DrvInfo /*OUT PSP_DRVINFO_DATA DriverInfoData*/
+ ))
+ {
+ DWORD dwReq;
+ pDrvDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
+ if (SetupDiGetDriverInfoDetail(
+ hDevInfo, /*IN HDEVINFO DeviceInfoSet,*/
+ NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
+ &DrvInfo, /*IN PSP_DRVINFO_DATA DriverInfoData,*/
+ pDrvDetail, /*OUT PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData, OPTIONAL*/
+ sizeof(DetailBuf), /*IN DWORD DriverInfoDetailDataSize,*/
+ &dwReq /*OUT PDWORD RequiredSize OPTIONAL*/
+ ))
+ {
+ for (WCHAR * pHwId = pDrvDetail->HardwareID; pHwId && *pHwId && pHwId < (TCHAR*)(DetailBuf + sizeof(DetailBuf)/sizeof(DetailBuf[0])) ;pHwId += wcslen(pHwId) + 1)
+ {
+ if (!wcsicmp(pHwId, pPnPId))
+ {
+ Assert(pDrvDetail->InfFileName[0]);
+ if (pDrvDetail->InfFileName)
+ {
+ list.add(pDrvDetail->InfFileName);
+ }
+ }
+ }
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__": SetupDiGetDriverInfoDetail fail winEr (%d), size(%d)", winEr, dwReq));
+// Assert(0);
+ }
+
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ if (winEr == ERROR_NO_MORE_ITEMS)
+ {
+ break;
+ }
+
+ Assert(0);
+ }
+ }
+
+ SetupDiDestroyDriverInfoList(hDevInfo,
+ NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
+ SPDIT_CLASSDRIVER/*IN DWORD DriverType*/
+ );
+ }
+ else
+ {
+ winEr = GetLastError();
+ Assert(0);
+ }
+
+ SetupDiDestroyDeviceInfoList(hDevInfo);
+ }
+ else
+ {
+ winEr = GetLastError();
+ Assert(0);
+ }
+
+ return HRESULT_FROM_WIN32(winEr);
+}
+
+#if 0
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInit()
+{
+ int rc = RTR3Init();
+ if (rc != VINF_SUCCESS)
+ {
+ LogRel(("Could not init IPRT!, rc (%d)\n", rc));
+ return E_FAIL;
+ }
+
+ return S_OK;
+}
+
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgTerm()
+{
+ return S_OK;
+}
+#endif
+
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllSetupDi(IN const GUID * pGuidClass, IN LPCWSTR lpszClassName, IN LPCWSTR lpszPnPId, IN DWORD Flags)
+{
+ VBoxDrvCfgStringList list(128);
+ HRESULT hr = vboxDrvCfgCollectInfsSetupDi(pGuidClass, lpszPnPId, list);
+ if (hr == S_OK)
+ {
+ INFENUM_CONTEXT Context;
+ Context.InfInfo.lpszClassName = lpszClassName;
+ Context.InfInfo.lpszPnPId = lpszPnPId;
+ Context.Flags = Flags;
+ Context.hr = S_OK;
+ int size = list.size();
+ for (int i = 0; i < size; ++i)
+ {
+ LPCWSTR pInf = list.get(i);
+ const WCHAR* pRel = wcsrchr(pInf, '\\');
+ if (pRel)
+ ++pRel;
+ else
+ pRel = pInf;
+
+ vboxDrvCfgInfEnumerationCallback(pRel, &Context);
+// LogRel(("inf : %S\n", list.get(i)));
+ }
+ }
+ return hr;
+}
+
+static HRESULT vboxDrvCfgEnumFiles(LPCWSTR pPattern, PFNVBOXNETCFG_ENUMERATION_CALLBACK pfnCallback, PVOID pContext)
+{
+ WIN32_FIND_DATA Data;
+ memset(&Data, 0, sizeof(Data));
+ HRESULT hr = S_OK;
+
+ HANDLE hEnum = FindFirstFile(pPattern,&Data);
+ if (hEnum != INVALID_HANDLE_VALUE)
+ {
+
+ do
+ {
+ if (!pfnCallback(Data.cFileName, pContext))
+ {
+ break;
+ }
+
+ /* next iteration */
+ memset(&Data, 0, sizeof(Data));
+ BOOL bNext = FindNextFile(hEnum,&Data);
+ if (!bNext)
+ {
+ int winEr = GetLastError();
+ if (winEr != ERROR_NO_MORE_FILES)
+ {
+ LogRel((__FUNCTION__": FindNextFile fail winEr (%d)\n", winEr));
+ Assert(0);
+ hr = HRESULT_FROM_WIN32(winEr);
+ }
+ break;
+ }
+ }while (true);
+ FindClose(hEnum);
+ }
+ else
+ {
+ int winEr = GetLastError();
+ if (winEr != ERROR_NO_MORE_FILES)
+ {
+ LogRel((__FUNCTION__": FindFirstFile fail winEr (%d)\n", winEr));
+ Assert(0);
+ hr = HRESULT_FROM_WIN32(winEr);
+ }
+ }
+
+ return hr;
+}
+
+static bool vboxDrvCfgInfEnumerationCallback(LPCWSTR lpszFileName, PVOID pCtxt)
+{
+ PINFENUM_CONTEXT pContext = (PINFENUM_CONTEXT)pCtxt;
+ DWORD winEr;
+// LogRel(("vboxDrvCfgInfEnumerationCallback: pFileName (%S)\n", pFileName));
+
+ HINF hInf = SetupOpenInfFileW(lpszFileName, pContext->InfInfo.lpszClassName, INF_STYLE_WIN4, NULL /*__in PUINT ErrorLine */);
+ if (hInf == INVALID_HANDLE_VALUE)
+ {
+ winEr = GetLastError();
+// Assert(winEr == ERROR_CLASS_MISMATCH);
+ if (winEr != ERROR_CLASS_MISMATCH)
+ {
+ Log((__FUNCTION__ ": SetupOpenInfFileW err winEr (%d)\n", winEr));
+ }
+
+ return true;
+ }
+
+ LPWSTR lpszPnPId;
+ HRESULT hr = vboxDrvCfgInfQueryFirstPnPId(hInf, &lpszPnPId);
+ if (hr == S_OK)
+ {
+ if (!wcsicmp(pContext->InfInfo.lpszPnPId, lpszPnPId))
+ {
+ if (!SetupUninstallOEMInfW(lpszFileName,
+ pContext->Flags, /*DWORD Flags could be SUOI_FORCEDELETE */
+ NULL /*__in PVOID Reserved == NULL */
+ ))
+ {
+ winEr = GetLastError();
+ LogRel((__FUNCTION__ ": SetupUninstallOEMInf failed for file (%S), winEr (%d)\n", lpszFileName, winEr));
+ Assert(0);
+ hr = HRESULT_FROM_WIN32( winEr );
+ }
+ }
+
+ free(lpszPnPId);
+ }
+ else
+ {
+ Log((__FUNCTION__ ": vboxDrvCfgInfQueryFirstPnPId failed, hr = (0x%x)\n", hr));
+ }
+
+ SetupCloseInfFile(hInf);
+
+ return true;
+}
+
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllF(LPCWSTR lpszClassName, LPCWSTR lpszPnPId, DWORD Flags)
+{
+ WCHAR InfDirPath[MAX_PATH];
+ HRESULT hr = SHGetFolderPathW(NULL, /* HWND hwndOwner*/
+ CSIDL_WINDOWS, /* int nFolder*/
+ NULL, /*HANDLE hToken*/
+ SHGFP_TYPE_CURRENT, /*DWORD dwFlags*/
+ InfDirPath);
+ Assert(hr == S_OK);
+ if (hr == S_OK)
+ {
+ wcscat(InfDirPath, L"\\inf\\oem*.inf");
+
+ INFENUM_CONTEXT Context;
+ Context.InfInfo.lpszClassName = lpszClassName;
+ Context.InfInfo.lpszPnPId = lpszPnPId;
+ Context.Flags = Flags;
+ Context.hr = S_OK;
+ hr = vboxDrvCfgEnumFiles(InfDirPath, vboxDrvCfgInfEnumerationCallback, &Context);
+ Assert(hr == S_OK);
+ if (hr == S_OK)
+ {
+ hr = Context.hr;
+ }
+ else
+ {
+ LogRel((__FUNCTION__": vboxDrvCfgEnumFiles failed, hr = (0x%x)\n", hr));
+ }
+ }
+ else
+ {
+ LogRel((__FUNCTION__": SHGetFolderPathW failed, hr = (0x%x)\n", hr));
+ }
+
+ return hr;
+
+}
+
+/* time intervals in milliseconds */
+/* max time to wait for the service to startup */
+#define VBOXDRVCFG_SVC_WAITSTART_TIME 10000
+/* sleep time before service status polls */
+#define VBOXDRVCFG_SVC_WAITSTART_TIME_PERIOD 100
+/* number of service start polls */
+#define VBOXDRVCFG_SVC_WAITSTART_RETRIES (VBOXDRVCFG_SVC_WAITSTART_TIME/VBOXDRVCFG_SVC_WAITSTART_TIME_PERIOD)
+
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgSvcStart(LPCWSTR lpszSvcName)
+{
+ SC_HANDLE hMgr = OpenSCManager(NULL, NULL, SERVICE_QUERY_STATUS | SERVICE_START);
+ if (hMgr == NULL)
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__": OpenSCManager failed, winEr (%d)\n", winEr));
+ return HRESULT_FROM_WIN32(winEr);
+ }
+
+ HRESULT hr = S_OK;
+ SC_HANDLE hSvc = OpenServiceW(hMgr, lpszSvcName, SERVICE_QUERY_STATUS | SERVICE_START);
+ if (hSvc)
+ {
+ do
+ {
+ SERVICE_STATUS Status;
+ BOOL fRc = QueryServiceStatus(hSvc, &Status);
+ if (!fRc)
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__": QueryServiceStatus failed winEr (%d)\n", winEr));
+ hr = HRESULT_FROM_WIN32(winEr);
+ break;
+ }
+
+ if (Status.dwCurrentState != SERVICE_RUNNING && Status.dwCurrentState != SERVICE_START_PENDING)
+ {
+ LogRel(("Starting service (%S)\n", lpszSvcName));
+
+ fRc = StartService(hSvc, 0, NULL);
+ if (!fRc)
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__": StartService failed winEr (%d)\n", winEr));
+ hr = HRESULT_FROM_WIN32(winEr);
+ break;
+ }
+ }
+
+ fRc = QueryServiceStatus(hSvc, &Status);
+ if (!fRc)
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__": QueryServiceStatus failed winEr (%d)\n", winEr));
+ hr = HRESULT_FROM_WIN32(winEr);
+ break;
+ }
+
+ if (Status.dwCurrentState == SERVICE_START_PENDING)
+ {
+ for (int i = 0; i < VBOXDRVCFG_SVC_WAITSTART_RETRIES; ++i)
+ {
+ Sleep(VBOXDRVCFG_SVC_WAITSTART_TIME_PERIOD);
+ fRc = QueryServiceStatus(hSvc, &Status);
+ if (!fRc)
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__": QueryServiceStatus failed winEr (%d)\n", winEr));
+ hr = HRESULT_FROM_WIN32(winEr);
+ break;
+ }
+ else if (Status.dwCurrentState != SERVICE_START_PENDING)
+ break;
+ }
+ }
+
+ if (hr != S_OK || Status.dwCurrentState != SERVICE_RUNNING)
+ {
+ LogRel((__FUNCTION__": Failed to start the service\n"));
+ hr = E_FAIL;
+ break;
+ }
+
+ } while (0);
+
+ CloseServiceHandle(hSvc);
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ LogRel((__FUNCTION__": OpenServiceW failed, winEr (%d)\n", winEr));
+ hr = HRESULT_FROM_WIN32(winEr);
+ }
+
+ CloseServiceHandle(hMgr);
+
+ return hr;
+}
diff --git a/src/VBox/HostServices/GuestControl/Makefile.kmk b/src/VBox/HostServices/GuestControl/Makefile.kmk
index d4515c7cb..e743aa2b8 100644
--- a/src/VBox/HostServices/GuestControl/Makefile.kmk
+++ b/src/VBox/HostServices/GuestControl/Makefile.kmk
@@ -1,10 +1,10 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 36873 2011-04-28 08:55:09Z vboxsync $
## @file
# Sub-Makefile for the Guest Control Host Service.
#
#
-# Copyright (C) 2010 Oracle Corporation
+# 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;
@@ -19,7 +19,7 @@ SUB_DEPTH = ../../../..
include $(KBUILD_PATH)/subheader.kmk
# Include sub-makefile(s).
-# include $(PATH_SUB_CURRENT)/testcase/Makefile.kmk
+include $(PATH_SUB_CURRENT)/testcase/Makefile.kmk
#
# The guest control service DLL.
diff --git a/src/VBox/HostServices/GuestControl/gctrl.cpp b/src/VBox/HostServices/GuestControl/gctrl.cpp
index dcb74a626..ebe86e63f 100644
--- a/src/VBox/HostServices/GuestControl/gctrl.cpp
+++ b/src/VBox/HostServices/GuestControl/gctrl.cpp
@@ -1,4 +1,4 @@
-/* $Id: gctrl.cpp $ */
+/* $Id: gctrl.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Guest Control Service: Internal function used by service, Main and testcase.
*/
diff --git a/src/VBox/HostServices/GuestControl/service.cpp b/src/VBox/HostServices/GuestControl/service.cpp
index 905c6b961..23f94d892 100644
--- a/src/VBox/HostServices/GuestControl/service.cpp
+++ b/src/VBox/HostServices/GuestControl/service.cpp
@@ -1,10 +1,10 @@
-/* $Id: service.cpp $ */
+/* $Id: service.cpp 37375 2011-06-08 10:51:26Z vboxsync $ */
/** @file
* Guest Control Service: Controlling the guest.
*/
/*
- * Copyright (C) 2010 Oracle Corporation
+ * 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;
@@ -149,7 +149,7 @@ typedef std::list< HostCmd >::const_iterator HostCmdListIterConst;
/**
* Class containing the shared information service functionality.
*/
-class Service : public iprt::non_copyable
+class Service : public RTCNonCopyable
{
private:
/** Type definition for use in callback functions. */
@@ -308,70 +308,72 @@ private:
*/
int Service::paramBufferAllocate(PVBOXGUESTCTRPARAMBUFFER pBuf, uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
{
- AssertPtr(pBuf);
- int rc = VINF_SUCCESS;
+ AssertPtrReturn(pBuf, VERR_INVALID_POINTER);
+ if (cParms)
+ AssertPtrReturn(paParms, VERR_INVALID_POINTER);
/* Paranoia. */
if (cParms > 256)
cParms = 256;
+ int rc = VINF_SUCCESS;
+
/*
* Don't verify anything here (yet), because this function only buffers
* the HGCM data into an internal structure and reaches it back to the guest (client)
* in an unmodified state.
*/
- if (RT_SUCCESS(rc))
+ pBuf->uMsg = uMsg;
+ pBuf->uParmCount = cParms;
+ if (pBuf->uParmCount)
{
- pBuf->uMsg = uMsg;
- pBuf->uParmCount = cParms;
pBuf->pParms = (VBOXHGCMSVCPARM*)RTMemAlloc(sizeof(VBOXHGCMSVCPARM) * pBuf->uParmCount);
if (NULL == pBuf->pParms)
- {
rc = VERR_NO_MEMORY;
- }
- else
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ for (uint32_t i = 0; i < pBuf->uParmCount; i++)
{
- for (uint32_t i = 0; i < pBuf->uParmCount; i++)
+ pBuf->pParms[i].type = paParms[i].type;
+ switch (paParms[i].type)
{
- pBuf->pParms[i].type = paParms[i].type;
- switch (paParms[i].type)
- {
- case VBOX_HGCM_SVC_PARM_32BIT:
- pBuf->pParms[i].u.uint32 = paParms[i].u.uint32;
- break;
+ case VBOX_HGCM_SVC_PARM_32BIT:
+ pBuf->pParms[i].u.uint32 = paParms[i].u.uint32;
+ break;
- case VBOX_HGCM_SVC_PARM_64BIT:
- /* Not supported yet. */
- break;
+ case VBOX_HGCM_SVC_PARM_64BIT:
+ /* Not supported yet. */
+ break;
- case VBOX_HGCM_SVC_PARM_PTR:
- pBuf->pParms[i].u.pointer.size = paParms[i].u.pointer.size;
- if (pBuf->pParms[i].u.pointer.size > 0)
+ case VBOX_HGCM_SVC_PARM_PTR:
+ pBuf->pParms[i].u.pointer.size = paParms[i].u.pointer.size;
+ if (pBuf->pParms[i].u.pointer.size > 0)
+ {
+ pBuf->pParms[i].u.pointer.addr = RTMemAlloc(pBuf->pParms[i].u.pointer.size);
+ if (NULL == pBuf->pParms[i].u.pointer.addr)
{
- pBuf->pParms[i].u.pointer.addr = RTMemAlloc(pBuf->pParms[i].u.pointer.size);
- if (NULL == pBuf->pParms[i].u.pointer.addr)
- {
- rc = VERR_NO_MEMORY;
- break;
- }
- else
- memcpy(pBuf->pParms[i].u.pointer.addr,
- paParms[i].u.pointer.addr,
- pBuf->pParms[i].u.pointer.size);
+ rc = VERR_NO_MEMORY;
+ break;
}
else
- {
- /* Size is 0 -- make sure we don't have any pointer. */
- pBuf->pParms[i].u.pointer.addr = NULL;
- }
- break;
+ memcpy(pBuf->pParms[i].u.pointer.addr,
+ paParms[i].u.pointer.addr,
+ pBuf->pParms[i].u.pointer.size);
+ }
+ else
+ {
+ /* Size is 0 -- make sure we don't have any pointer. */
+ pBuf->pParms[i].u.pointer.addr = NULL;
+ }
+ break;
- default:
- break;
- }
- if (RT_FAILURE(rc))
+ default:
break;
}
+ if (RT_FAILURE(rc))
+ break;
}
}
return rc;
@@ -528,7 +530,7 @@ int Service::clientDisconnect(uint32_t u32ClientID, void *pvClient)
if (mpfnHostCallback)
{
CALLBACKDATACLIENTDISCONNECTED data;
- data.hdr.u32Magic = CALLBACKDATAMAGICCLIENTDISCONNECTED;
+ data.hdr.u32Magic = CALLBACKDATAMAGIC_CLIENT_DISCONNECTED;
data.hdr.u32ContextID = (*itContext);
rc = mpfnHostCallback(mpvHostData, GUEST_DISCONNECTED, (void *)(&data), sizeof(data));
if (RT_FAILURE(rc))
@@ -715,7 +717,7 @@ int Service::notifyHost(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paP
&& cParms == 5)
{
CALLBACKDATAEXECSTATUS data;
- data.hdr.u32Magic = CALLBACKDATAMAGICEXECSTATUS;
+ data.hdr.u32Magic = CALLBACKDATAMAGIC_EXEC_STATUS;
paParms[0].getUInt32(&data.hdr.u32ContextID);
paParms[1].getUInt32(&data.u32PID);
@@ -731,7 +733,7 @@ int Service::notifyHost(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paP
&& cParms == 5)
{
CALLBACKDATAEXECOUT data;
- data.hdr.u32Magic = CALLBACKDATAMAGICEXECOUT;
+ data.hdr.u32Magic = CALLBACKDATAMAGIC_EXEC_OUT;
paParms[0].getUInt32(&data.hdr.u32ContextID);
paParms[1].getUInt32(&data.u32PID);
@@ -747,7 +749,7 @@ int Service::notifyHost(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paP
&& cParms == 5)
{
CALLBACKDATAEXECINSTATUS data;
- data.hdr.u32Magic = CALLBACKDATAMAGICEXECINSTATUS;
+ data.hdr.u32Magic = CALLBACKDATAMAGIC_EXEC_IN_STATUS;
paParms[0].getUInt32(&data.hdr.u32ContextID);
paParms[1].getUInt32(&data.u32PID);
@@ -759,6 +761,33 @@ int Service::notifyHost(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paP
rc = mpfnHostCallback(mpvHostData, eFunction,
(void *)(&data), sizeof(data));
}
+ else if ( eFunction == GUEST_DIR_SEND_OPEN
+ && cParms == 2)
+ {
+ CALLBACKDATADIROPEN data;
+ data.hdr.u32Magic = CALLBACKDATAMAGIC_DIR_OPEN;
+ paParms[0].getUInt32(&data.hdr.u32ContextID);
+
+ paParms[1].getUInt32(&data.u32Handle);
+
+ if (mpfnHostCallback)
+ rc = mpfnHostCallback(mpvHostData, eFunction,
+ (void *)(&data), sizeof(data));
+ }
+ else if ( eFunction == GUEST_DIR_SEND_READ
+ && cParms == 3)
+ {
+ CALLBACKDATADIRREAD data;
+ data.hdr.u32Magic = CALLBACKDATAMAGIC_DIR_READ;
+ paParms[0].getUInt32(&data.hdr.u32ContextID);
+
+ paParms[1].getUInt64(&data.u64NodeId);
+ paParms[2].getString(&data.pszName, &data.cbName);
+
+ if (mpfnHostCallback)
+ rc = mpfnHostCallback(mpvHostData, eFunction,
+ (void *)(&data), sizeof(data));
+ }
else
rc = VERR_NOT_SUPPORTED;
LogFlowFunc(("returning %Rrc\n", rc));
@@ -784,11 +813,9 @@ int Service::processHostCmd(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM
*/
if (mNumClients == 0)
return VERR_NOT_FOUND;
-
HostCmd newCmd;
int rc = paramBufferAllocate(&newCmd.mParmBuf, eFunction, cParms, paParms);
- if ( RT_SUCCESS(rc)
- && newCmd.mParmBuf.uParmCount > 0)
+ if (RT_SUCCESS(rc) && cParms)
{
/*
* Assume that the context ID *always* is the first parameter,
@@ -798,9 +825,10 @@ int Service::processHostCmd(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM
Assert(newCmd.mContextID > 0);
}
- bool fProcessed = false;
if (RT_SUCCESS(rc))
{
+ bool fProcessed = false;
+
/* Can we wake up a waiting client on guest? */
if (!mClientWaiterList.empty())
{
@@ -813,9 +841,11 @@ int Service::processHostCmd(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM
mpHelpers->pfnCallComplete(guest.mHandle, rc);
mClientWaiterList.pop_front();
- /* If we got VERR_TOO_MUCH_DATA we buffer the host command in the next block
- * and return success to the host. */
- if (rc == VERR_TOO_MUCH_DATA)
+ /*
+ * If we got back an error (like VERR_TOO_MUCH_DATA or VERR_BUFFER_OVERFLOW)
+ * we buffer the host command in the next block and return success to the host.
+ */
+ if (RT_FAILURE(rc))
{
rc = VINF_SUCCESS;
}
@@ -879,28 +909,12 @@ void Service::call(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID,
break;
/*
- * The guest notifies the host that some output at stdout/stderr is available.
- */
- case GUEST_EXEC_SEND_OUTPUT:
- LogFlowFunc(("GUEST_EXEC_SEND_OUTPUT\n"));
- rc = notifyHost(eFunction, cParms, paParms);
- break;
-
- /*
- * The guest notifies the host of the executed process status.
+ * For all other regular commands we call our notifyHost
+ * function. If the current command does not support notifications
+ * notifyHost will return VERR_NOT_SUPPORTED.
*/
- case GUEST_EXEC_SEND_STATUS:
- LogFlowFunc(("GUEST_EXEC_SEND_STATUS\n"));
- rc = notifyHost(eFunction, cParms, paParms);
- break;
-
- case GUEST_EXEC_SEND_INPUT_STATUS:
- LogFlowFunc(("GUEST_EXEC_SEND_INPUT_STATUS\n"));
- rc = notifyHost(eFunction, cParms, paParms);
- break;
-
default:
- rc = VERR_NOT_SUPPORTED;
+ rc = notifyHost(eFunction, cParms, paParms);
break;
}
if (rc != VINF_HGCM_ASYNC_EXECUTE)
@@ -924,35 +938,12 @@ void Service::call(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID,
*/
int Service::hostCall(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
{
- int rc = VINF_SUCCESS;
+ int rc = VERR_NOT_SUPPORTED;
LogFlowFunc(("fn = %d, cParms = %d, pparms = %d\n",
eFunction, cParms, paParms));
try
{
- switch (eFunction)
- {
- /* The host wants to execute something. */
- case HOST_EXEC_CMD:
- LogFlowFunc(("HOST_EXEC_CMD\n"));
- rc = processHostCmd(eFunction, cParms, paParms);
- break;
-
- /* The host wants to send something to the
- * started process' stdin pipe. */
- case HOST_EXEC_SET_INPUT:
- LogFlowFunc(("HOST_EXEC_SET_INPUT\n"));
- rc = processHostCmd(eFunction, cParms, paParms);
- break;
-
- case HOST_EXEC_GET_OUTPUT:
- LogFlowFunc(("HOST_EXEC_GET_OUTPUT\n"));
- rc = processHostCmd(eFunction, cParms, paParms);
- break;
-
- default:
- rc = VERR_NOT_SUPPORTED;
- break;
- }
+ rc = processHostCmd(eFunction, cParms, paParms);
}
catch (std::bad_alloc)
{
diff --git a/src/VBox/HostServices/GuestControl/testcase/Makefile.kmk b/src/VBox/HostServices/GuestControl/testcase/Makefile.kmk
index 86974d758..4cf085b2d 100644
--- a/src/VBox/HostServices/GuestControl/testcase/Makefile.kmk
+++ b/src/VBox/HostServices/GuestControl/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Sub-Makefile for the Guest Control Host Service testcases.
#
diff --git a/src/VBox/HostServices/GuestControl/testcase/tstGuestControlSvc.cpp b/src/VBox/HostServices/GuestControl/testcase/tstGuestControlSvc.cpp
index ef5c1dc97..671476663 100644
--- a/src/VBox/HostServices/GuestControl/testcase/tstGuestControlSvc.cpp
+++ b/src/VBox/HostServices/GuestControl/testcase/tstGuestControlSvc.cpp
@@ -1,11 +1,11 @@
-/* $Id: tstGuestControlSvc.cpp $ */
+/* $Id: tstGuestControlSvc.cpp 36873 2011-04-28 08:55:09Z vboxsync $ */
/** @file
*
* Testcase for the guest control service.
*/
/*
- * Copyright (C) 2010 Oracle Corporation
+ * 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;
@@ -20,63 +20,28 @@
* Header Files *
*******************************************************************************/
#include <VBox/HostServices/GuestControlSvc.h>
-#include <iprt/alloca.h>
#include <iprt/initterm.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/message.h>
-#include <iprt/param.h>
-#include <iprt/path.h>
-#include <iprt/pipe.h>
-#include <iprt/poll.h>
-#include <iprt/process.h>
#include <iprt/stream.h>
-#include <iprt/thread.h>
+#include <iprt/test.h>
#include "../gctrl.h"
-using namespace guestControl;
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+static RTTEST g_hTest = NIL_RTTEST;
-extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *pTable);
-char g_szImageName[RTPATH_MAX];
+using namespace guestControl;
-/** Prototypes. */
-int guestExecSendStdOut(VBOXHGCMSVCFNTABLE *pTable,
- const char *pszStdOut, uint32_t cbStdOut);
+extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad(VBOXHGCMSVCFNTABLE *pTable);
/** Simple call handle structure for the guest call completion callback */
struct VBOXHGCMCALLHANDLE_TYPEDEF
{
- /** Where to store the result code */
+ /** Where to store the result code. */
int32_t rc;
};
-/**
- * For buffering process input supplied by the client.
- */
-typedef struct TXSEXECSTDINBUF
-{
- /** The mount of buffered data. */
- size_t cb;
- /** The current data offset. */
- size_t off;
- /** The data buffer. */
- char *pch;
- /** The amount of allocated buffer space. */
- size_t cbAllocated;
- /** Send further input into the bit bucket (stdin is dead). */
- bool fBitBucket;
- /** The CRC-32 for standard input (received part). */
- uint32_t uCrc32;
-} TXSEXECSTDINBUF;
-/** Pointer to a standard input buffer. */
-typedef TXSEXECSTDINBUF *PTXSEXECSTDINBUF;
-
/** Call completion callback for guest calls. */
static void callComplete(VBOXHGCMCALLHANDLE callHandle, int32_t rc)
{
@@ -85,1070 +50,253 @@ static void callComplete(VBOXHGCMCALLHANDLE callHandle, int32_t rc)
/**
* Initialise the HGCM service table as much as we need to start the
- * service
+ * service.
+ *
+ * @return IPRT status.
* @param pTable the table to initialise
*/
-void initTable(VBOXHGCMSVCFNTABLE *pTable, VBOXHGCMSVCHELPERS *pHelpers)
+int initTable(VBOXHGCMSVCFNTABLE *pTable, VBOXHGCMSVCHELPERS *pHelpers)
{
pTable->cbSize = sizeof (VBOXHGCMSVCFNTABLE);
pTable->u32Version = VBOX_HGCM_SVC_VERSION;
pHelpers->pfnCallComplete = callComplete;
pTable->pHelpers = pHelpers;
-}
-
-/**
- * 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. Always set.
- */
-static int guestExecSetupPipe(int fd, PRTHANDLE ph, PRTHANDLE *pph, PRTPIPE phPipe)
-{
- AssertPtr(ph);
- AssertPtr(pph);
- AssertPtr(phPipe);
-
- 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;
+ return VINF_SUCCESS;
}
-/**
- * Handle an error event on standard input.
- *
- * @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 void guestExecProcHandleStdInErrorEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phStdInW,
- PTXSEXECSTDINBUF pStdInBuf)
+typedef struct CMDHOST
{
- int rc2;
- if (pStdInBuf->off < pStdInBuf->cb)
- {
- rc2 = RTPollSetRemove(hPollSet, 4 /*TXSEXECHNDID_STDIN_WRITABLE*/);
- AssertRC(rc2);
- }
-
- rc2 = RTPollSetRemove(hPollSet, 0 /*TXSEXECHNDID_STDIN*/);
- AssertRC(rc2);
-
- rc2 = RTPipeClose(*phStdInW);
- AssertRC(rc2);
- *phStdInW = NIL_RTPIPE;
-
- RTMemFree(pStdInBuf->pch);
- pStdInBuf->pch = NULL;
- pStdInBuf->off = 0;
- pStdInBuf->cb = 0;
- pStdInBuf->cbAllocated = 0;
- pStdInBuf->fBitBucket = true;
-}
-
-/**
- * Try write some more data to the standard input of the child.
- *
- * @returns IPRT status code.
- * @param pStdInBuf The standard input buffer.
- * @param hStdInW The standard input pipe.
- */
-static int guestExecProcWriteStdIn(PTXSEXECSTDINBUF pStdInBuf, RTPIPE hStdInW)
-{
- size_t cbToWrite = pStdInBuf->cb - pStdInBuf->off;
- size_t cbWritten;
- int rc = RTPipeWrite(hStdInW, &pStdInBuf->pch[pStdInBuf->off], cbToWrite, &cbWritten);
- if (RT_SUCCESS(rc))
- {
- Assert(cbWritten == cbToWrite);
- pStdInBuf->off += cbWritten;
- }
- return rc;
-}
+ /** The HGCM command to execute. */
+ int cmd;
+ /** Number of parameters. */
+ int num_parms;
+ /** The actual parameters. */
+ const PVBOXHGCMSVCPARM parms;
+ /** Flag indicating whether we need a connected client for this command. */
+ bool fNeedsClient;
+ /** The desired return value from the host. */
+ int rc;
+} CMDHOST, *PCMDHOST;
-/**
- * Handle an event indicating we can write to the standard input pipe of the
- * child process.
- *
- * @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.
- */
-static void guestExecProcHandleStdInWritableEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phStdInW,
- PTXSEXECSTDINBUF pStdInBuf)
+typedef struct CMDCLIENT
{
+ /** The client's ID. */
+ int client_id;
+ /** The HGCM command to execute. */
+ int cmd;
+ /** Number of parameters. */
+ int num_parms;
+ /** The actual parameters. */
+ const PVBOXHGCMSVCPARM parms;
+ /** The desired return value from the host. */
int rc;
- if (!(fPollEvt & RTPOLL_EVT_ERROR))
- {
- rc = guestExecProcWriteStdIn(pStdInBuf, *phStdInW);
- if (RT_FAILURE(rc) && rc != VERR_BAD_PIPE)
- {
- /** @todo do we need to do something about this error condition? */
- AssertRC(rc);
- }
-
- if (pStdInBuf->off < pStdInBuf->cb)
- {
- rc = RTPollSetRemove(hPollSet, 4 /*TXSEXECHNDID_STDIN_WRITABLE*/);
- AssertRC(rc);
- }
- }
- else
- guestExecProcHandleStdInErrorEvent(hPollSet, fPollEvt, phStdInW, pStdInBuf);
-}
+} CMDCLIENT, *PCMDCLIENT;
/**
- * Handle pending output data or error on standard out, standard error or the
- * test pipe.
- *
- * @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 pu32Crc The current CRC-32 of the stream. (In/Out)
- * @param uHandleId The handle ID.
- * @param pszOpcode The opcode for the data upload.
- *
- * @todo Put the last 4 parameters into a struct!
+ * Tests the HOST_EXEC_CMD function.
+ * @returns iprt status value to indicate whether the test went as expected.
+ * @note prints its own diagnostic information to stdout.
*/
-static int guestExecProcHandleOutputEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phPipeR,
- uint32_t *puCrc32 , uint32_t uHandleId)
+static int testHostCmd(const VBOXHGCMSVCFNTABLE *pTable, const PCMDHOST pCmd, uint32_t uNumTests)
{
- Log(("guestExecProcHandleOutputEvent: fPollEvt=%#x\n", fPollEvt));
-
- /*
- * Try drain the pipe before acting on any errors.
- */
int rc = VINF_SUCCESS;
-
- char abBuf[_64K];
- size_t cbRead;
- int rc2 = RTPipeRead(*phPipeR, abBuf, sizeof(abBuf), &cbRead);
- if (RT_SUCCESS(rc2) && cbRead)
- {
- Log(("Crc32=%#x ", *puCrc32));
-
-#if 1
- abBuf[cbRead] = '\0';
- RTPrintf("%s: %s\n", uHandleId == 1 ? "StdOut: " : "StdErr: ", abBuf);
-#endif
-
- /**puCrc32 = RTCrc32Process(*puCrc32, abBuf, cbRead);
- Log(("cbRead=%#x Crc32=%#x \n", cbRead, *puCrc32));
- Pkt.uCrc32 = RTCrc32Finish(*puCrc32);*/
- /* if (g_fDisplayOutput)
- {
- if (enmHndId == TXSEXECHNDID_STDOUT)
- RTStrmPrintf(g_pStdErr, "%.*s", cbRead, Pkt.abBuf);
- else if (enmHndId == TXSEXECHNDID_STDERR)
- RTStrmPrintf(g_pStdErr, "%.*s", cbRead, Pkt.abBuf);
- }
-
- rc = txsReplyInternal(&Pkt.Hdr, pszOpcode, cbRead + sizeof(uint32_t));*/
-
- /* 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 raised signalled,
- */
- if (fPollEvt & RTPOLL_EVT_ERROR)
- {
- rc2 = RTPollSetRemove(hPollSet, uHandleId);
- AssertRC(rc2);
-
- rc2 = RTPipeClose(*phPipeR);
- AssertRC(rc2);
- *phPipeR = NIL_RTPIPE;
- }
- return rc;
-}
-
-/**
- * Handle a transport event or successful pfnPollIn() call.
- *
- * @returns IPRT status code from client send.
- * @retval VINF_EOF indicates ABORT command.
- *
- * @param hPollSet The polling set.
- * @param fPollEvt The event mask returned by RTPollNoResume.
- * @param idPollHnd The handle ID.
- * @param hStdInW The standard input pipe.
- * @param pStdInBuf The standard input buffer.
- */
-static int guestExecProcHandleTransportEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, uint32_t idPollHnd,
- PRTPIPE phStdInW, PTXSEXECSTDINBUF pStdInBuf)
-{
-
- int rc = RTPollSetAddPipe(hPollSet, *phStdInW, RTPOLL_EVT_WRITE, 4 /*TXSEXECHNDID_STDIN_WRITABLE*/);
-
- return rc;
-}
-
-static int guestExecProcLoop(VBOXHGCMSVCFNTABLE *pTable,
- RTPROCESS hProcess, RTMSINTERVAL cMillies, RTPOLLSET hPollSet,
- RTPIPE hStdInW, RTPIPE hStdOutR, RTPIPE hStdErrR)
-{
- int rc;
- int rc2;
- TXSEXECSTDINBUF StdInBuf = { 0, 0, NULL, 0, hStdInW == NIL_RTPIPE, RTCrc32Start() };
- uint32_t uStdOutCrc32 = RTCrc32Start();
- uint32_t uStdErrCrc32 = uStdOutCrc32;
- uint64_t const MsStart = RTTimeMilliTS();
- RTPROCSTATUS ProcessStatus = { 254, RTPROCEXITREASON_ABEND };
- bool fProcessAlive = true;
- bool fProcessTimedOut = false;
- uint64_t MsProcessKilled = UINT64_MAX;
- bool const fHavePipes = hStdInW != NIL_RTPIPE
- || hStdOutR != NIL_RTPIPE
- || hStdErrR != NIL_RTPIPE;
- RTMSINTERVAL const cMsPollBase = hStdInW != NIL_RTPIPE
- ? 100 /* need to poll for input */
- : 1000; /* need only poll for process exit and aborts */
- RTMSINTERVAL cMsPollCur = 0;
-
- /*
- * 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.
- */
- rc = VINF_SUCCESS;
-
- /*
- * Process input, output, the test pipe and client requests.
- */
- while (RT_SUCCESS(rc))
+ if (!VALID_PTR(pTable->pfnHostCall))
{
- /*
- * Wait/Process all pending events.
- */
- uint32_t idPollHnd;
- uint32_t fPollEvt;
- rc2 = RTPollNoResume(hPollSet, cMsPollCur, &fPollEvt, &idPollHnd);
-
- cMsPollCur = 0; /* no rest until we've checked everything. */
-
- if (RT_SUCCESS(rc2))
- {
- switch (idPollHnd)
- {
- case 0 /* TXSEXECHNDID_STDIN */:
- guestExecProcHandleStdInErrorEvent(hPollSet, fPollEvt, &hStdInW, &StdInBuf);
- break;
-
- case 1 /* TXSEXECHNDID_STDOUT */:
- rc = guestExecProcHandleOutputEvent(hPollSet, fPollEvt, &hStdOutR, &uStdOutCrc32, 1 /* TXSEXECHNDID_STDOUT */);
- break;
-
- case 2 /*TXSEXECHNDID_STDERR */:
- rc = guestExecProcHandleOutputEvent(hPollSet, fPollEvt, &hStdErrR, &uStdErrCrc32, 2 /*TXSEXECHNDID_STDERR */);
- break;
-
- case 4 /* TXSEXECHNDID_STDIN_WRITABLE */:
- guestExecProcHandleStdInWritableEvent(hPollSet, fPollEvt, &hStdInW, &StdInBuf);
- break;
-
- default:
- rc = guestExecProcHandleTransportEvent(hPollSet, fPollEvt, idPollHnd, &hStdInW, &StdInBuf);
- break;
- }
- if (RT_FAILURE(rc) || rc == VINF_EOF)
- break; /* abort command, or client dead or something */
- continue;
- }
-
- /*
- * Check for incoming data.
- */
-
- /*
- * 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 (cMillies != RT_INDEFINITE_WAIT)
- {
- uint64_t u64Now = RTTimeMilliTS();
- uint64_t cMsElapsed = u64Now - MsStart;
- if (cMsElapsed >= cMillies)
- {
- 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 = cMillies - (uint32_t)cMsElapsed;
- }
-
- /* Reset the polling interval since we've done all pending work. */
- cMsPollCur = cMilliesLeft >= cMsPollBase ? cMsPollBase : cMilliesLeft;
+ RTTestPrintf(g_hTest, RTTESTLVL_FAILURE, "Invalid pfnHostCall() pointer\n");
+ rc = VERR_INVALID_POINTER;
}
-
- /*
- * Try kill the process if it's still alive at this point.
- */
- if (fProcessAlive)
+ if (RT_SUCCESS(rc))
{
- if (MsProcessKilled == UINT64_MAX)
+ for (unsigned i = 0; (i < uNumTests) && RT_SUCCESS(rc); i++)
{
- MsProcessKilled = RTTimeMilliTS();
- RTProcTerminate(hProcess);
- RTThreadSleep(500);
- }
+ RTTestPrintf(g_hTest, RTTESTLVL_INFO, "Testing #%u (cmd: %d, num_parms: %d, parms: 0x%p\n",
+ i, pCmd[i].cmd, pCmd[i].num_parms, pCmd[i].parms);
- for (size_t i = 0; i < 10; i++)
- {
- rc2 = RTProcWait(hProcess, RTPROCWAIT_FLAGS_NOBLOCK, &ProcessStatus);
- if (RT_SUCCESS(rc2))
+ if (pCmd[i].fNeedsClient)
{
- fProcessAlive = false;
- break;
+ int client_rc = pTable->pfnConnect(pTable->pvService, 1000 /* Client ID */, NULL /* pvClient */);
+ if (RT_FAILURE(client_rc))
+ rc = client_rc;
}
- if (i >= 5)
- RTProcTerminate(hProcess);
- RTThreadSleep(i >= 5 ? 2000 : 500);
- }
- }
-
- /*
- * If we don't have a client problem (RT_FAILURE(rc) we'll reply to the
- * clients exec packet now.
- */
- if (RT_SUCCESS(rc))
- {
- if ( fProcessTimedOut && !fProcessAlive && MsProcessKilled != UINT64_MAX)
- {
-
- }
- else if (fProcessTimedOut && fProcessAlive && MsProcessKilled != UINT64_MAX)
- {
-
- }
- /*else if (g_fTerminate && (fProcessAlive || MsProcessKilled != UINT64_MAX))
- {
-
- }*/
- else if (fProcessAlive)
- {
-
- }
- else if (MsProcessKilled != UINT64_MAX)
- {
-
- }
- else if ( ProcessStatus.enmReason == RTPROCEXITREASON_NORMAL
- && ProcessStatus.iStatus == 0)
- {
-
- }
- else if (ProcessStatus.enmReason == RTPROCEXITREASON_NORMAL)
- {
-
- }
- else if (ProcessStatus.enmReason == RTPROCEXITREASON_SIGNAL)
- {
- }
- else if (ProcessStatus.enmReason == RTPROCEXITREASON_ABEND)
- {
-
- }
- else
- {
-
- }
- }
-
- RTMemFree(StdInBuf.pch);
- return rc;
-}
-
-int guestExecProcess(VBOXHGCMSVCFNTABLE *pTable,
- uint32_t fFlags, const char *pszExecName,
- uint32_t cArgs, const char * const *papszArgs,
- uint32_t cEnvVars, const char * const *papszEnv,
- const char *pszStdIn, const char *pszStdOut, const char *pszStdErr,
- const char *pszUsername, const char *pszPassword, RTMSINTERVAL cMillies)
-{
-#if 0
- /* Print some info */
- RTPrintf("Flags: %u\n"
- "# Args: %u\n"
- "# Env: %u\n"
- "StdIn: %s, StdOut: %s, StdErr: %s\n"
- "User: %s, Timelimit: %u\n",
- fFlags, cArgs, cEnvVars,
- pszStdIn, pszStdOut, pszStdErr,
- pszUsername ? pszUsername : "<None>", cMillies);
- for (uint32_t i=0; i<cArgs; i++)
- RTPrintf("Arg %u: %s\n", i, papszArgs[i]);
- for (uint32_t i=0; i<cEnvVars; i++)
- RTPrintf("Env %u: %s\n", i, papszEnv[i]);
-#endif
-
- /*
- * Create the environment.
- */
- RTENV hEnv;
- int rc = RTEnvClone(&hEnv, RTENV_DEFAULT);
- if (RT_SUCCESS(rc))
- {
- size_t i;
- for (i = 0; i < cEnvVars; i++)
- {
- rc = RTEnvPutEx(hEnv, 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;
- RTPIPE hStdInW;
- rc = guestExecSetupPipe(0 /* stdin */, &hStdIn, &phStdIn, &hStdInW);
if (RT_SUCCESS(rc))
{
- RTHANDLE hStdOut;
- PRTHANDLE phStdOut;
- RTPIPE hStdOutR;
- rc = guestExecSetupPipe(1 /* stdout */, &hStdOut, &phStdOut, &hStdOutR);
- if (RT_SUCCESS(rc))
+ int host_rc = pTable->pfnHostCall(pTable->pvService,
+ pCmd[i].cmd,
+ pCmd[i].num_parms,
+ pCmd[i].parms);
+ if (host_rc != pCmd[i].rc)
{
- RTHANDLE hStdErr;
- PRTHANDLE phStdErr;
- RTPIPE hStdErrR;
- rc = guestExecSetupPipe(2 /* stderr */, &hStdErr, &phStdErr, &hStdErrR);
+ RTTestPrintf(g_hTest, RTTESTLVL_FAILURE, "Host call test #%u returned with rc=%Rrc instead of rc=%Rrc\n",
+ i, host_rc, pCmd[i].rc);
+ rc = host_rc;
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, hStdInW, RTPOLL_EVT_ERROR, 0 /* TXSEXECHNDID_STDIN */);
- if (RT_SUCCESS(rc))
- rc = RTPollSetAddPipe(hPollSet, hStdOutR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, 1 /* TXSEXECHNDID_STDOUT */);
- if (RT_SUCCESS(rc))
- rc = RTPollSetAddPipe(hPollSet, hStdErrR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, 2 /* TXSEXECHNDID_TESTPIPE */);
- if (RT_SUCCESS(rc))
- {
- RTPROCESS hProcess;
- rc = RTProcCreateEx(pszExecName, papszArgs, hEnv, 0 /*fFlags*/,
- phStdIn, phStdOut, phStdErr,
- /*pszUsername, pszPassword,*/ NULL, NULL,
- &hProcess);
- if (RT_SUCCESS(rc))
- {
- /*
- * Close the child ends of any pipes and redirected files.
- */
- int rc2 = RTHandleClose(phStdIn); AssertRC(rc2);
- phStdIn = NULL;
- rc2 = RTHandleClose(phStdOut); AssertRC(rc2);
- phStdOut = NULL;
- rc2 = RTHandleClose(phStdErr); AssertRC(rc2);
- phStdErr = NULL;
-
- rc = guestExecProcLoop(pTable,
- hProcess, cMillies, hPollSet,
- hStdInW, 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, 0 /* stdin */, NULL)))
- hStdInW = NIL_RTPIPE;
- if (RT_FAILURE(RTPollSetQueryHandle(hPollSet, 1 /* stdout */, NULL)))
- hStdOutR = NIL_RTPIPE;
- if (RT_FAILURE(RTPollSetQueryHandle(hPollSet, 2 /* stderr */, NULL)))
- hStdErrR = NIL_RTPIPE;
- }
- }
- }
- RTPipeClose(hStdErrR);
- RTHandleClose(phStdErr);
- }
- RTPipeClose(hStdOutR);
- RTHandleClose(phStdOut);
+ rc = VERR_INVALID_PARAMETER;
}
- RTPipeClose(hStdInW);
- RTHandleClose(phStdIn);
- }
- }
- RTEnvDestroy(hEnv);
- }
-
- return rc;
-}
-
-int guestExecHandleCmdExecute(VBOXHGCMSVCFNTABLE *pTable, PVBOXHGCMSVCPARM paParms, uint32_t cParms)
-{
- char *pcBuf;
- uint32_t cbLen;
- if(cParms < 13)
- return VERR_INVALID_PARAMETER;
-
- /* flags */
- uint32_t uFlags;
- int rc = paParms[1].getUInt32(&uFlags);
- if (RT_SUCCESS(rc))
- {
- /* cmd */
- rc = paParms[2].getString(&pcBuf, &cbLen);
- char *pszExecName = RTStrDup(pcBuf);
-
- /* arguments */
- if ( pszExecName
- && RT_SUCCESS(rc))
- {
- /* argc */
- uint32_t uArgc;
- paParms[3].getUInt32(&uArgc);
-
- /* argv */
- char *pcData;
- paParms[4].getBuffer((void**)&pcData, &cbLen);
- AssertPtr(pcData);
-
- char **ppaArg;
- int iArgs;
- rc = RTGetOptArgvFromString(&ppaArg, &iArgs, pcData, NULL);
- Assert(uArgc == iArgs);
-
- /* environment */
- if (RT_SUCCESS(rc))
- {
- /* envc */
- uint32_t uEnvc;
- paParms[5].getUInt32(&uEnvc);
-
- /* envv */
- paParms[6].getBuffer((void**)&pcData, &cbLen);
- AssertPtr(pcData);
-
- char **ppaEnv = NULL;
- if (uEnvc)
- {
- ppaEnv = (char**)RTMemAlloc(uEnvc * sizeof(char*));
- AssertPtr(ppaEnv);
-
- char *pcCur = pcData;
- uint32_t i = 0;
- while (pcCur < pcData + cbLen)
- {
- if (RTStrAPrintf(&ppaEnv[i++], "%s", pcCur) < 0)
- {
- rc = VERR_NO_MEMORY;
- break;
- }
- pcCur += strlen(pcCur) + 1; /* Skip terminating zero. */
- }
- }
- if (RT_SUCCESS(rc))
+ if (pCmd[i].fNeedsClient)
{
- /* stdin */
- rc = paParms[7].getString(&pcBuf, &cbLen);
- char *pszStdIn = RTStrDup(pcBuf);
- if ( pszStdIn
- && RT_SUCCESS(rc))
- {
- /* stdout */
- rc = paParms[8].getString(&pcBuf, &cbLen);
- char *pszStdOut = RTStrDup(pcBuf);
- if ( pszStdOut
- && RT_SUCCESS(rc))
- {
- /* stderr */
- rc = paParms[9].getString(&pcBuf, &cbLen);
- char *pszStdErr = RTStrDup(pcBuf);
- if ( pszStdErr
- && RT_SUCCESS(rc))
- {
- /* user */
- rc = paParms[10].getString(&pcBuf, &cbLen);
- char *pszUser = RTStrDup(pcBuf);
- if ( pszUser
- && RT_SUCCESS(rc))
- {
- /* password */
- rc = paParms[11].getString(&pcBuf, &cbLen);
- char *pszPassword = RTStrDup(pcBuf);
- if (RT_SUCCESS(rc))
- {
- /* time to wait (0 = max, no time limit) */
- RTMSINTERVAL msTimeLimit;
- rc = paParms[12].getUInt32(&msTimeLimit);
- if (RT_SUCCESS(rc))
- {
- rc = guestExecProcess(pTable,
- uFlags, pszExecName,
- uArgc, ppaArg,
- uEnvc, ppaEnv,
- pszStdIn, pszStdOut, pszStdIn,
- pszUser, pszPassword,
- msTimeLimit == UINT32_MAX ? RT_INDEFINITE_WAIT : msTimeLimit);
- }
- }
- RTStrFree(pszUser);
- }
- RTStrFree(pszStdErr);
- }
- RTStrFree(pszStdOut);
- }
- RTStrFree(pszStdIn);
- }
- for (uint32_t i=0; i<uEnvc; i++)
- RTStrFree(ppaEnv[i]);
- RTMemFree(ppaEnv);
+ int client_rc = pTable->pfnDisconnect(pTable->pvService, 1000 /* Client ID */, NULL /* pvClient */);
+ if (RT_SUCCESS(rc))
+ rc = client_rc;
}
- RTGetOptArgvFree(ppaArg);
}
- RTStrFree(pszExecName);
}
}
return rc;
}
-/** Sends the current stdout (stderr later?) data to the host. */
-int guestExecSendStdOut(VBOXHGCMSVCFNTABLE *pTable,
- const char *pszStdOut, uint32_t cbStdOut)
+static int testHost(const VBOXHGCMSVCFNTABLE *pTable)
{
- VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
- int command = GUEST_EXEC_SEND_STDOUT;
- VBOXHGCMSVCPARM paParms[3];
-
- if ( pszStdOut == NULL
- || cbStdOut == 0)
- {
- return VERR_INVALID_PARAMETER;
- }
+ RTTestSub(g_hTest, "Testing host commands ...");
- paParms[0].setUInt32(123 /* @todo PID. */);
- paParms[1].setUInt32(1 /* @todo Pipe ID. */);
- paParms[2].setPointer((void*)pszStdOut, cbStdOut + 1);
+ static VBOXHGCMSVCPARM s_aParms[1];
+ s_aParms[0].setUInt32(1000 /* Context ID */);
- pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL, command,
- 3, paParms);
- int rc = VINF_SUCCESS;
- if (RT_FAILURE(callHandle.rc))
+ static CMDHOST s_aCmdHostAll[] =
{
- RTPrintf("guestSendStdOut failed with callHandle.rc=%Rrc\n", callHandle.rc);
- rc = callHandle.rc;
- }
+ /** No client connected, invalid command. */
+ { 1024 /* Not existing command */, 0, 0, false, VERR_NOT_SUPPORTED },
+ { -1 /* Invalid command */, 0, 0, false, VERR_NOT_SUPPORTED },
+ { HOST_CANCEL_PENDING_WAITS, 1024, 0, false, VERR_NOT_FOUND },
+ { HOST_CANCEL_PENDING_WAITS, 0, &s_aParms[0], false, VERR_NOT_FOUND },
+
+ /** No client connected, valid command. */
+ { HOST_CANCEL_PENDING_WAITS, 0, 0, false, VERR_NOT_FOUND },
+
+ /** Client connected. */
+ { 1024 /* Not existing command */, 0, 0, true, VERR_NOT_SUPPORTED },
+ { -1 /* Invalid command */, 0, 0, true, VERR_NOT_SUPPORTED },
+
+ /** Client connected, valid parameters given. */
+ { HOST_CANCEL_PENDING_WAITS, 0, 0, true, VINF_SUCCESS },
+ { HOST_CANCEL_PENDING_WAITS, 1024, &s_aParms[0], true, VINF_SUCCESS },
+ { HOST_CANCEL_PENDING_WAITS, 0, &s_aParms[0], true, VINF_SUCCESS},
+
+ /** Client connected, invalid parameters given. */
+ { HOST_CANCEL_PENDING_WAITS, 1024, 0, true, VERR_INVALID_POINTER },
+ { HOST_CANCEL_PENDING_WAITS, 1, 0, true, VERR_INVALID_POINTER },
+ { HOST_CANCEL_PENDING_WAITS, -1, 0, true, VERR_INVALID_POINTER },
+
+ /** Client connected, parameters given. */
+ { HOST_CANCEL_PENDING_WAITS, 1, &s_aParms[0], true, VINF_SUCCESS },
+ { HOST_EXEC_CMD, 1, &s_aParms[0], true, VINF_SUCCESS },
+ { HOST_EXEC_SET_INPUT, 1, &s_aParms[0], true, VINF_SUCCESS },
+ { HOST_EXEC_GET_OUTPUT, 1, &s_aParms[0], true, VINF_SUCCESS }
+ };
+
+ int rc = testHostCmd(pTable, &s_aCmdHostAll[0], RT_ELEMENTS(s_aCmdHostAll));
+ RTTestSubDone(g_hTest);
return rc;
}
-/** Gets a new message (command) from the host and does the appropriate action. */
-int guestGetHostMsg(VBOXHGCMSVCFNTABLE *pTable)
+static int testClient(const VBOXHGCMSVCFNTABLE *pTable)
{
- VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
- int command = GUEST_GET_HOST_MSG;
- VBOXHGCMSVCPARM paParms[13];
- /* Work around silly constant issues - we ought to allow passing
- * constant strings in the hgcm parameters. */
- pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL, command,
- 13, paParms);
- int rc;
- if (RT_FAILURE(callHandle.rc))
- {
- RTPrintf("guestGetHostMsg failed with callHandle.rc=%Rrc\n", callHandle.rc);
- rc = callHandle.rc;
- }
- else
- {
- uint32_t uCmd;
+ RTTestSub(g_hTest, "Testing client commands ...");
- /*
- * Parameter 0 *always* specifies the actual command the host wants
- * to execute.
- */
- rc = paParms[0].getUInt32(&uCmd);
+ int rc = pTable->pfnConnect(pTable->pvService, 1 /* Client ID */, NULL /* pvClient */);
+ if (RT_SUCCESS(rc))
+ {
+ VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
+
+ /* No commands from host yet. */
+ static VBOXHGCMSVCPARM s_aParmsGuest[8];
+ pTable->pfnCall(pTable->pvService, &callHandle, 1 /* Client ID */, NULL /* pvClient */,
+ GUEST_GET_HOST_MSG, 2, &s_aParmsGuest[0]);
+ RTTEST_CHECK_RC_RET(g_hTest, callHandle.rc, VINF_SUCCESS, callHandle.rc);
+
+ /* Host: Add a dummy command. */
+ static VBOXHGCMSVCPARM s_aParmsHost[8];
+ s_aParmsHost[0].setUInt32(1000 /* Context ID */);
+ s_aParmsHost[1].setString("foo.bar");
+
+ rc = pTable->pfnHostCall(pTable->pvService, HOST_EXEC_CMD, 2, &s_aParmsHost[0]);
+ RTTEST_CHECK_RC_RET(g_hTest, rc, VINF_SUCCESS, rc);
+
+ /* Client: Get host command with a invalid parameter count specified. */
+ pTable->pfnCall(pTable->pvService, &callHandle, 1 /* Client ID */, NULL /* pvClient */,
+ GUEST_GET_HOST_MSG, 1024, &s_aParmsGuest[0]);
+ RTTEST_CHECK_RC_RET(g_hTest, callHandle.rc, VERR_INVALID_PARAMETER, callHandle.rc);
+ pTable->pfnCall(pTable->pvService, &callHandle, 1 /* Client ID */, NULL /* pvClient */,
+ GUEST_GET_HOST_MSG, -1, &s_aParmsGuest[0]);
+ RTTEST_CHECK_RC_RET(g_hTest, callHandle.rc, VERR_INVALID_PARAMETER, callHandle.rc);
+ pTable->pfnCall(pTable->pvService, &callHandle, 1 /* Client ID */, NULL /* pvClient */,
+ GUEST_GET_HOST_MSG, -1, NULL);
+ RTTEST_CHECK_RC_RET(g_hTest, callHandle.rc, VERR_INVALID_PARAMETER, callHandle.rc);
+ pTable->pfnCall(pTable->pvService, &callHandle, 1 /* Client ID */, NULL /* pvClient */,
+ GUEST_GET_HOST_MSG, 16, NULL);
+ RTTEST_CHECK_RC_RET(g_hTest, callHandle.rc, VERR_INVALID_PARAMETER, callHandle.rc);
+
+ /* Client: Get host command with a too small HGCM array. */
+ pTable->pfnCall(pTable->pvService, &callHandle, 1 /* Client ID */, NULL /* pvClient */,
+ GUEST_GET_HOST_MSG, 0, &s_aParmsGuest[0]);
+ RTTEST_CHECK_RC_RET(g_hTest, callHandle.rc, VERR_TOO_MUCH_DATA, callHandle.rc);
+ pTable->pfnCall(pTable->pvService, &callHandle, 1 /* Client ID */, NULL /* pvClient */,
+ GUEST_GET_HOST_MSG, 1, &s_aParmsGuest[0]);
+ RTTEST_CHECK_RC_RET(g_hTest, callHandle.rc, VERR_TOO_MUCH_DATA, callHandle.rc);
+
+ /* Client: Get host command without an allocated buffer. */
+ pTable->pfnCall(pTable->pvService, &callHandle, 1 /* Client ID */, NULL /* pvClient */,
+ GUEST_GET_HOST_MSG, 2, &s_aParmsGuest[0]);
+ RTTEST_CHECK_RC_RET(g_hTest, callHandle.rc, VERR_BUFFER_OVERFLOW, callHandle.rc);
+
+ /* Client: Get host command, this time with a valid buffer. */
+ char szBuf[16];
+ s_aParmsGuest[1].setPointer(szBuf, sizeof(szBuf));
+ pTable->pfnCall(pTable->pvService, &callHandle, 1 /* Client ID */, NULL /* pvClient */,
+ GUEST_GET_HOST_MSG, 2, &s_aParmsGuest[0]);
+ RTTEST_CHECK_RC_RET(g_hTest, callHandle.rc, VINF_SUCCESS, callHandle.rc);
+
+ /* Client: Now make sure there's no host message left anymore. */
+ pTable->pfnCall(pTable->pvService, &callHandle, 1 /* Client ID */, NULL /* pvClient */,
+ GUEST_GET_HOST_MSG, 2, &s_aParmsGuest[0]);
+ RTTEST_CHECK_RC_RET(g_hTest, callHandle.rc, VINF_SUCCESS, callHandle.rc);
+
+ /* Client: Disconnect again. */
+ int rc2 = pTable->pfnDisconnect(pTable->pvService, 1000 /* Client ID */, NULL /* pvClient */);
if (RT_SUCCESS(rc))
- {
- switch(uCmd)
- {
- case GETHOSTMSG_EXEC_CMD:
- rc = guestExecHandleCmdExecute(pTable, paParms, 13);
- break;
-
- case GETHOSTMSG_EXEC_STDIN:
- //rc = guestExecHandleCmdStdIn(pTable, paParms, 12);
- break;
-
- default:
- RTPrintf("guestGetHostMsg: Invalid host command: %u\n", uCmd);
- rc = VERR_INVALID_PARAMETER;
- break;
- }
- }
+ rc = rc2;
}
- return rc;
-}
-
-/** This represents the execution service thread in VBoxService. */
-static DECLCALLBACK(int) guestThread(RTTHREAD Thread, void *pvUser)
-{
- VBOXHGCMSVCFNTABLE *pTable = (VBOXHGCMSVCFNTABLE*)pvUser;
- AssertPtr(pTable);
- int rc = guestGetHostMsg(pTable);
- if(RT_FAILURE(rc))
- return rc;
-
- /* We don't remove the current request from the host queue yet,
- * so don't try to get a new host message more than once atm. */
-
- for(;;) /* Run forever atm. */
- {
- RTThreadSleep(1);
- /** @tdo Add graceful shutdown here. */
- }
+ RTTestSubDone(g_hTest);
return rc;
}
-int hostExecCmd(VBOXHGCMSVCFNTABLE *pTable,
- uint32_t u32Flags,
- const char *pszCmd,
- uint32_t u32Argc,
- const void *pvArgs,
- uint32_t cbArgs,
- uint32_t u32Envc,
- const void *pvEnv,
- uint32_t cbEnv,
- const char *pszStdin,
- const char *pszStdOut,
- const char *pszStdErr,
- const char *pszUser,
- const char *pszPassword,
- uint32_t u32TimeLimit)
-{
- int command = HOST_EXEC_CMD;
- VBOXHGCMSVCPARM paParms[13];
-
- /** @todo Put some assert macros here! */
- paParms[0].setUInt32(HOST_EXEC_CMD);
- paParms[1].setUInt32(u32Flags);
- paParms[2].setPointer((void*)pszCmd, (uint32_t)strlen(pszCmd) + 1);
- paParms[3].setUInt32(u32Argc);
- paParms[4].setPointer((void*)pvArgs, cbArgs);
- paParms[5].setUInt32(u32Envc);
- paParms[6].setPointer((void*)pvEnv, cbEnv);
- paParms[7].setPointer((void*)pszStdin, (uint32_t)strlen(pszStdin) + 1);
- paParms[8].setPointer((void*)pszStdOut, (uint32_t)strlen(pszStdOut) + 1);
- paParms[9].setPointer((void*)pszStdErr, (uint32_t)strlen(pszStdErr) + 1);
- paParms[10].setPointer((void*)pszUser, (uint32_t)strlen(pszUser) + 1);
- paParms[11].setPointer((void*)pszPassword, (uint32_t)strlen(pszPassword) + 1);
- paParms[12].setUInt32(u32TimeLimit);
-
- int rc = pTable->pfnHostCall(pTable->pvService, command,
- 13, paParms);
- if (RT_FAILURE(rc))
- {
- RTPrintf("hostDoExecute() call failed with rc=%Rrc\n", rc);
- }
- return rc;
-}
-
-int hostExecGetStatus(VBOXHGCMSVCFNTABLE *pTable)
-{
- int command = HOST_EXEC_GET_STATUS;
- VBOXHGCMSVCPARM paParms[13];
-
- /** @todo Put some assert macros here! */
- paParms[0].setUInt32(0 /* @todo 0=Execute */);
-
- return 0;
-}
-
-/**
- * Test the EXECUTE function.
- * @returns iprt status value to indicate whether the test went as expected.
- * @note prints its own diagnostic information to stdout.
+/*
+ * Set environment variable "IPRT_TEST_MAX_LEVEL=all" to get more debug output!
*/
-int testExecute(VBOXHGCMSVCFNTABLE *pTable)
-{
- RTPrintf("Testing the EXECUTE call.\n");
- if (!VALID_PTR(pTable->pfnHostCall))
- {
- RTPrintf("Invalid pfnHostCall() pointer\n");
- return VERR_INVALID_POINTER;
- }
-
- int rc = VINF_SUCCESS;
- /*
- * The host code (= later Main?) will run in this thread,
- * while the client (guest) code will run in another one (= VBoxService in guest).
- */
- RTTHREAD threadGuest;
- rc = RTThreadCreate(&threadGuest, guestThread, pTable /* Save call table. */,
- 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "GUEST");
-
- /* This is the host code. */
- if(RT_SUCCESS(rc))
- {
- void *pvArgs;
- uint32_t cArgs;
- uint32_t cbArgs;
-
- void *pvEnv = NULL;
- uint32_t cEnv;
- uint32_t cbEnv;
-
- char szCmdLine[_1K];
-
- /* Test stdout*/
- RTStrPrintf(szCmdLine, sizeof(szCmdLine),
- "%s --test-stdout", g_szImageName); /* Include image name as argv[0]. */
- rc = gctrlPrepareExecArgv(szCmdLine, &pvArgs, &cbArgs, &cArgs);
- if (RT_SUCCESS(rc))
- {
- rc = gctrlAddToExecEnvv("VBOX_LOG=all", &pvEnv, &cbEnv, &cEnv);
- if (RT_SUCCESS(rc))
- rc = gctrlAddToExecEnvv("VBOX_LOG_DEST=file=c:\\baz\\barfoo.txt", &pvEnv, &cbEnv, &cEnv);
- if (RT_SUCCESS(rc))
- rc = gctrlAddToExecEnvv("HOME=iN-WoNdeRlAnd", &pvEnv, &cbEnv, &cEnv);
- if (RT_SUCCESS(rc))
- {
- rc = hostExecCmd(pTable,
- 456123,
- g_szImageName,
- cArgs,
- pvArgs,
- cbArgs,
- cEnv,
- pvEnv,
- cbEnv,
- "|",
- "|",
- "|",
- "vbox",
- "password",
- UINT32_MAX);
- RTMemFree(pvEnv);
- }
- RTMemFree(pvArgs);
- }
- if (RT_SUCCESS(rc))
- {
- for(;;)
- {
- RTThreadSleep(1);
- }
- }
-
- /* Wait for guest thread to finish. */
- int rc2;
- rc = RTThreadWait(threadGuest, RT_INDEFINITE_WAIT, &rc2);
- if (RT_FAILURE(rc))
- RTPrintf("RTThreadWait failed, rc=%Rrc\n", rc);
- else if (RT_FAILURE(rc2))
- RTPrintf("Thread failed, rc2=%Rrc\n", rc2);
- }
- return rc;
-}
-
-int selfTestExecStdOut(int h, int argc, char **argv)
+int main(int argc, char **argv)
{
- RTStrmPrintf(g_pStdOut, "This is the first text to StdOut!\n");
- RTStrmPrintf(g_pStdErr, "Hum, this really should be ignored because it's stderr! :-/\n");
- /*for (int i=0; i<10; i++)
- {
- RTStrmPrintf(g_pStdOut, "This is the i=%d to StdOut! Waiting ...\n", i+1);
- RTStrmPrintf(g_pStdErr, "This is the i=%d to StdErr!\n", i+1);
- RTThreadSleep(1000);
+ RTEXITCODE rcExit = RTTestInitAndCreate("tstGuestControlSvc", &g_hTest);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ RTTestBanner(g_hTest);
- }*/
- RTThreadSleep(5000);
- return VINF_SUCCESS;
-}
+ /* Some host info. */
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "sizeof(void*)=%d\n", sizeof(void*));
-RTEXITCODE selfTestExecStd(int h, int argc, char **argv)
-{
- int rc = VINF_SUCCESS;
+ /* Do the tests. */
+ VBOXHGCMSVCFNTABLE svcTable;
+ VBOXHGCMSVCHELPERS svcHelpers;
+ RTTEST_CHECK_RC_RET(g_hTest, initTable(&svcTable, &svcHelpers), VINF_SUCCESS, 1);
-#if 0
- /* Dump arguments and environment. */
- RTENV env;
- rc = RTEnvCreate(&env);
- if (RT_SUCCESS(rc))
+ do
{
- const char *const *pcEnv = RTEnvGetExecEnvP(env);
- RTPrintf("Environment: %s\n" , pcEnv);
- rc = RTEnvDestroy(env);
- }
-#endif
+ RTTESTI_CHECK_RC_BREAK(VBoxHGCMSvcLoad(&svcTable), VINF_SUCCESS);
- /* Do the test(s) based on the handle number(s). */
- switch (h)
- {
- case 0: /* stdin */
- break;
+ RTTESTI_CHECK_RC_BREAK(testHost(&svcTable), VINF_SUCCESS);
- case 1: /* stdout */
- rc = selfTestExecStdOut(h, argc, argv);
- break;
+ RTTESTI_CHECK_RC_BREAK(svcTable.pfnUnload(svcTable.pvService), VINF_SUCCESS);
- case 2: /* stderr */
- break;
+ RTTESTI_CHECK_RC_BREAK(VBoxHGCMSvcLoad(&svcTable), VINF_SUCCESS);
- case 3: /* all std* */
- break;
- }
+ RTTESTI_CHECK_RC_BREAK(testClient(&svcTable), VINF_SUCCESS);
- return RTEXITCODE_SUCCESS;
-}
+ RTTESTI_CHECK_RC_BREAK(svcTable.pfnUnload(svcTable.pvService), VINF_SUCCESS);
-/**
- * Parses the arguments.
- *
- * @returns Exit code. Exit if this is non-zero or @a *pfExit is set.
- * @param argc The number of arguments.
- * @param argv The argument vector.
- * @param pfExit For indicating exit when the exit code is zero.
- */
-static RTEXITCODE parseArgv(int argc, char **argv, bool *pfExit)
-{
-#if 1
- RTPrintf("ArgC: %d\n", argc);
- for (int i=0; i<argc; i++)
- RTPrintf("ArgV: %s\n", argv[i]);
-#endif
+ } while (0);
- if (argc == 2)
- {
- *pfExit = true;
- if (!strcmp(argv[1], "--test-stdin"))
- return selfTestExecStd(0 /* stdin */, argc, argv);
- else if (!strcmp(argv[1], "--test-stdout"))
- return selfTestExecStd(1 /* stdout */, argc, argv);
- else if (!strcmp(argv[1], "--test-stderr"))
- return selfTestExecStd(2 /* stderr */, argc, argv);
- else if (!strcmp(argv[1], "--test-all"))
- return selfTestExecStd(3 /* all */, argc, argv);
-
- RTPrintf("Unknown test! Exit.\n");
- return RTEXITCODE_FAILURE;
- }
- return RTEXITCODE_SUCCESS;
+ return RTTestSummaryAndDestroy(g_hTest);
}
-int main(int argc, char **argv)
-{
- int rc = RTR3Init();
- if (RT_FAILURE(rc))
- return RTMsgInitFailure(rc);
-
- /* Save image name for later use. */
- if (!RTProcGetExecutablePath(g_szImageName, sizeof(g_szImageName)))
- return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTProcGetExecutablePath failed\n");
-
- VBOXHGCMSVCFNTABLE svcTable;
- VBOXHGCMSVCHELPERS svcHelpers;
-
- initTable(&svcTable, &svcHelpers);
-
- RTPrintf("PID: %u\n", RTProcSelf ());
-
- bool fExit = false;
- rc = parseArgv(argc, argv, &fExit);
- if (rc || fExit)
- return rc;
-
- /* The function is inside the service, not HGCM. */
- if (RT_FAILURE(VBoxHGCMSvcLoad(&svcTable)))
- {
- RTPrintf("Failed to start the HGCM service.\n");
- return 1;
- }
- if (RT_FAILURE(testExecute(&svcTable)))
- return 1;
- RTPrintf("tstGuestControlSvc: SUCCEEDED.\n");
- return 0;
-}
diff --git a/src/VBox/HostServices/GuestProperties/Makefile.kmk b/src/VBox/HostServices/GuestProperties/Makefile.kmk
index 6c387e104..c449bd411 100644
--- a/src/VBox/HostServices/GuestProperties/Makefile.kmk
+++ b/src/VBox/HostServices/GuestProperties/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the Shared Info Services Host Service.
#
diff --git a/src/VBox/HostServices/GuestProperties/service.cpp b/src/VBox/HostServices/GuestProperties/service.cpp
index d46b30a29..50cf8176c 100644
--- a/src/VBox/HostServices/GuestProperties/service.cpp
+++ b/src/VBox/HostServices/GuestProperties/service.cpp
@@ -1,4 +1,4 @@
-/* $Id: service.cpp $ */
+/* $Id: service.cpp 36529 2011-04-04 13:54:13Z vboxsync $ */
/** @file
* Guest Property Service: Host service entry points.
*/
@@ -146,7 +146,7 @@ typedef std::list <GuestCall> CallList;
/**
* Class containing the shared information service functionality.
*/
-class Service : public iprt::non_copyable
+class Service : public RTCNonCopyable
{
private:
/** Type definition for use in callback functions */
diff --git a/src/VBox/HostServices/GuestProperties/testcase/Makefile.kmk b/src/VBox/HostServices/GuestProperties/testcase/Makefile.kmk
index f2978e278..e9598cb5f 100644
--- a/src/VBox/HostServices/GuestProperties/testcase/Makefile.kmk
+++ b/src/VBox/HostServices/GuestProperties/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Sub-Makefile for the Guest Properties Host Service testcases.
#
diff --git a/src/VBox/HostServices/GuestProperties/testcase/tstGuestPropSvc.cpp b/src/VBox/HostServices/GuestProperties/testcase/tstGuestPropSvc.cpp
index 76c563e3f..0d9683e53 100644
--- a/src/VBox/HostServices/GuestProperties/testcase/tstGuestPropSvc.cpp
+++ b/src/VBox/HostServices/GuestProperties/testcase/tstGuestPropSvc.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstGuestPropSvc.cpp $ */
+/* $Id: tstGuestPropSvc.cpp 36412 2011-03-24 17:25:33Z vboxsync $ */
/** @file
*
* Testcase for the guest property service.
diff --git a/src/VBox/HostServices/Makefile.kmk b/src/VBox/HostServices/Makefile.kmk
index 66d9dfbd8..f414f09ce 100644
--- a/src/VBox/HostServices/Makefile.kmk
+++ b/src/VBox/HostServices/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 33185 2010-10-18 08:40:50Z vboxsync $
## @file
# Top-level makefile for the VBox Host Services.
#
diff --git a/src/VBox/HostServices/SharedClipboard/Makefile.kmk b/src/VBox/HostServices/SharedClipboard/Makefile.kmk
index 77d5da99b..b5e2503bc 100644
--- a/src/VBox/HostServices/SharedClipboard/Makefile.kmk
+++ b/src/VBox/HostServices/SharedClipboard/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37434 2011-06-14 13:14:57Z vboxsync $
## @file
# Sub-Makefile for the Shared Clipboard Host Service.
#
@@ -18,6 +18,9 @@
SUB_DEPTH = ../../../..
include $(KBUILD_PATH)/subheader.kmk
+# Include sub-makefile(s).
+include $(PATH_SUB_CURRENT)/testcase/Makefile.kmk
+
#
# The shared folder service DLL.
#
diff --git a/src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp b/src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp
index 0f7d6f90e..e10be7464 100644
--- a/src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp
+++ b/src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp
@@ -611,7 +611,7 @@ void vboxClipboardDestroy (void)
g_ctx.thread = NIL_RTTHREAD;
}
-int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient)
+int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool)
{
Log(("vboxClipboardConnect\n"));
diff --git a/src/VBox/HostServices/SharedClipboard/VBoxClipboard.h b/src/VBox/HostServices/SharedClipboard/VBoxClipboard.h
index 23c4ee223..81f184be8 100644
--- a/src/VBox/HostServices/SharedClipboard/VBoxClipboard.h
+++ b/src/VBox/HostServices/SharedClipboard/VBoxClipboard.h
@@ -19,6 +19,7 @@
#define __VBOXCLIPBOARD__H
#define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD
+#include <VBox/hgcmsvc.h>
#include <VBox/log.h>
struct _VBOXCLIPBOARDCONTEXT;
@@ -72,6 +73,7 @@ void vboxSvcClipboardReportMsg (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Ms
void vboxSvcClipboardCompleteReadData(VBOXCLIPBOARDCLIENTDATA *pClient, int rc, uint32_t cbActual);
+bool vboxSvcClipboardGetHeadless(void);
/*
* Platform dependent functions.
@@ -79,7 +81,7 @@ void vboxSvcClipboardCompleteReadData(VBOXCLIPBOARDCLIENTDATA *pClient, int rc,
int vboxClipboardInit (void);
void vboxClipboardDestroy (void);
-int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient);
+int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool fHeadless);
void vboxClipboardDisconnect (VBOXCLIPBOARDCLIENTDATA *pClient);
void vboxClipboardFormatAnnounce (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Formats);
@@ -90,4 +92,9 @@ void vboxClipboardWriteData (VBOXCLIPBOARDCLIENTDATA *pClient, void *pv, uint32_
int vboxClipboardSync (VBOXCLIPBOARDCLIENTDATA *pClient);
+/* Host unit testing interface */
+#ifdef UNIT_TEST
+uint32_t TestClipSvcGetMode(void);
+#endif
+
#endif /* __VBOXCLIPBOARD__H */
diff --git a/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp b/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp
index 31da35b83..2ad88d3a8 100644
--- a/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp
+++ b/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp
@@ -1,4 +1,4 @@
-/* $Id: darwin-pasteboard.cpp $ */
+/* $Id: darwin-pasteboard.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Shared Clipboard: Mac OS X host implementation.
*/
diff --git a/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.h b/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.h
index 4e36ff1a5..a93c6ed1c 100644
--- a/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.h
+++ b/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.h
@@ -1,4 +1,4 @@
-/* $Id: darwin-pasteboard.h $ */
+/* $Id: darwin-pasteboard.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Shared Clipboard: Mac OS X host implementation.
*/
diff --git a/src/VBox/HostServices/SharedClipboard/darwin.cpp b/src/VBox/HostServices/SharedClipboard/darwin.cpp
index b0cd44cd0..3d5ae6e99 100644
--- a/src/VBox/HostServices/SharedClipboard/darwin.cpp
+++ b/src/VBox/HostServices/SharedClipboard/darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: darwin.cpp $ */
+/* $Id: darwin.cpp 37472 2011-06-15 16:15:34Z vboxsync $ */
/** @file
* Shared Clipboard: Mac OS X host.
*/
@@ -152,7 +152,7 @@ void vboxClipboardDestroy (void)
* @param pClient Structure containing context information about the guest system
* @returns RT status code
*/
-int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient)
+int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool)
{
if (g_ctx.pClient != NULL)
{
diff --git a/src/VBox/HostServices/SharedClipboard/service.cpp b/src/VBox/HostServices/SharedClipboard/service.cpp
index 52fab68f4..a7a28788f 100644
--- a/src/VBox/HostServices/SharedClipboard/service.cpp
+++ b/src/VBox/HostServices/SharedClipboard/service.cpp
@@ -1,4 +1,4 @@
-/* $Id: service.cpp $ */
+/* $Id: service.cpp 37472 2011-06-15 16:15:34Z vboxsync $ */
/** @file
* Shared Clipboard: Host service entry points.
*/
@@ -133,11 +133,28 @@ static bool g_fReadingData = false;
static bool g_fDelayedAnnouncement = false;
static uint32_t g_u32DelayedFormats = 0;
+/** Is the clipboard running in headless mode? */
+static bool g_fHeadless = false;
+
static uint32_t vboxSvcClipboardMode (void)
{
return g_u32Mode;
}
+#ifdef UNIT_TEST
+/** Testing interface, getter for clipboard mode */
+uint32_t TestClipSvcGetMode(void)
+{
+ return vboxSvcClipboardMode();
+}
+#endif
+
+/** Getter for headless setting */
+bool vboxSvcClipboardGetHeadless(void)
+{
+ return g_fHeadless;
+}
+
static void vboxSvcClipboardModeSet (uint32_t u32Mode)
{
switch (u32Mode)
@@ -344,7 +361,7 @@ static DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClien
pClient->u32ClientID = u32ClientID;
- rc = vboxClipboardConnect (pClient);
+ rc = vboxClipboardConnect (pClient, vboxSvcClipboardGetHeadless());
if (RT_SUCCESS (rc))
{
@@ -705,6 +722,20 @@ static DECLCALLBACK(int) svcHostCall (void *,
}
} break;
+ case VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS:
+ {
+ uint32_t u32Headless = g_fHeadless;
+
+ rc = VERR_INVALID_PARAMETER;
+ if (cParms != 1)
+ break;
+ rc = VBoxHGCMParmUInt32Get (&paParms[0], &u32Headless);
+ if (RT_SUCCESS(rc))
+ LogRelFlow(("svcCall: VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS, u32Headless=%u\n",
+ (unsigned) u32Headless));
+ g_fHeadless = RT_BOOL(u32Headless);
+ } break;
+
default:
break;
}
@@ -713,6 +744,18 @@ static DECLCALLBACK(int) svcHostCall (void *,
return rc;
}
+#ifdef UNIT_TEST
+static int testSSMStubRC(void) { AssertFailedReturn(VERR_WRONG_ORDER); }
+static uint32_t testSSMStubU32(void) { AssertFailedReturn(0); }
+# define SSMR3PutU32(pSSM, u32) testSSMStubRC()
+# define SSMR3PutStructEx(pSSM, pvStruct, cbStruct, fFlags, paFields, pvUser) \
+ testSSMStubRC()
+# define SSMR3GetU32(pSSM, pu32) ( *(pu32) = 0, testSSMStubRC() )
+# define SSMR3HandleHostBits(pSSM) testSSMStubU32()
+# define SSMR3GetStructEx(pSSM, pvStruct, cbStruct, fFlags, paFields, pvUser) \
+ testSSMStubRC()
+#endif
+
/**
* SSM descriptor table for the VBOXCLIPBOARDCLIENTDATA structure.
*/
@@ -877,6 +920,13 @@ static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClie
return VINF_SUCCESS;
}
+#ifdef UNIT_TEST
+# undef SSMR3PutU32
+# undef SSMR3GetU32
+# undef SSMR3HandleHostBits
+# undef SSMR3GetStructEx
+#endif
+
static DECLCALLBACK(int) extCallback (uint32_t u32Function, uint32_t u32Format, void *pvData, uint32_t cbData)
{
if (g_pClient != NULL)
diff --git a/src/VBox/HostServices/SharedClipboard/testcase/Makefile.kmk b/src/VBox/HostServices/SharedClipboard/testcase/Makefile.kmk
new file mode 100644
index 000000000..68201e33a
--- /dev/null
+++ b/src/VBox/HostServices/SharedClipboard/testcase/Makefile.kmk
@@ -0,0 +1,33 @@
+# $Id: Makefile.kmk 37458 2011-06-14 21:15:32Z vboxsync $
+## @file
+# Sub-Makefile for the Shared Clipboard Host Service testcases.
+#
+
+#
+# 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.
+#
+
+SUB_DEPTH = ../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+if defined(VBOX_WITH_TESTCASES) && !defined(VBOX_ONLY_ADDITIONS) && !defined(VBOX_ONLY_SDK)
+
+ PROGRAMS += tstClipboardServiceHost
+
+ tstClipboardServiceHost_TEMPLATE = VBOXR3TSTEXE
+ tstClipboardServiceHost_DEFS = VBOX_WITH_HGCM UNIT_TEST
+ tstClipboardServiceHost_SOURCES = \
+ ../service.cpp \
+ tstClipboardServiceHost.cpp
+
+endif
+
+include $(KBUILD_PATH)/subfooter.kmk
diff --git a/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceHost.cpp b/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceHost.cpp
new file mode 100644
index 000000000..6ca74b65c
--- /dev/null
+++ b/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceHost.cpp
@@ -0,0 +1,164 @@
+/* $Id: tstClipboardServiceHost.cpp 37472 2011-06-15 16:15:34Z vboxsync $ */
+/** @file
+ * Shared Clipboard host service test case.
+ */
+
+/*
+ * 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.
+ */
+
+#include "../VBoxClipboard.h"
+
+#include <VBox/HostServices/VBoxClipboardSvc.h>
+
+#include <iprt/assert.h>
+#include <iprt/string.h>
+#include <iprt/test.h>
+
+extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable);
+
+static int setupTable(VBOXHGCMSVCFNTABLE *pTable)
+{
+ pTable->cbSize = sizeof(*pTable);
+ pTable->u32Version = VBOX_HGCM_SVC_VERSION;
+ return VBoxHGCMSvcLoad(pTable);
+}
+
+static void testSetMode(void)
+{
+ struct VBOXHGCMSVCPARM parms[2];
+ VBOXHGCMSVCFNTABLE table;
+ uint32_t u32Mode;
+ int rc;
+
+ RTTestISub("Testing HOST_FN_SET_MODE");
+ rc = setupTable(&table);
+ RTTESTI_CHECK_MSG_RETV(RT_SUCCESS(rc), ("rc=%Rrc\n", rc));
+ /* Reset global variable which doesn't reset itself. */
+ parms[0].setUInt32(VBOX_SHARED_CLIPBOARD_MODE_OFF);
+ rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
+ 1, parms);
+ RTTESTI_CHECK_RC_OK(rc);
+ u32Mode = TestClipSvcGetMode();
+ RTTESTI_CHECK_MSG(u32Mode == VBOX_SHARED_CLIPBOARD_MODE_OFF,
+ ("u32Mode=%u\n", (unsigned) u32Mode));
+ rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
+ 0, parms);
+ RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER);
+ rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
+ 2, parms);
+ RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER);
+ parms[0].setUInt64(99);
+ rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
+ 1, parms);
+ RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER);
+ parms[0].setUInt32(VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST);
+ rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
+ 1, parms);
+ RTTESTI_CHECK_RC_OK(rc);
+ u32Mode = TestClipSvcGetMode();
+ RTTESTI_CHECK_MSG(u32Mode == VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST,
+ ("u32Mode=%u\n", (unsigned) u32Mode));
+ parms[0].setUInt32(99);
+ rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
+ 1, parms);
+ RTTESTI_CHECK_RC_OK(rc);
+ u32Mode = TestClipSvcGetMode();
+ RTTESTI_CHECK_MSG(u32Mode == VBOX_SHARED_CLIPBOARD_MODE_OFF,
+ ("u32Mode=%u\n", (unsigned) u32Mode));
+}
+
+static void testSetHeadless(void)
+{
+ struct VBOXHGCMSVCPARM parms[2];
+ VBOXHGCMSVCFNTABLE table;
+ bool fHeadless;
+ int rc;
+
+ RTTestISub("Testing HOST_FN_SET_HEADLESS");
+ rc = setupTable(&table);
+ RTTESTI_CHECK_MSG_RETV(RT_SUCCESS(rc), ("rc=%Rrc\n", rc));
+ /* Reset global variable which doesn't reset itself. */
+ parms[0].setUInt32(false);
+ rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS,
+ 1, parms);
+ RTTESTI_CHECK_RC_OK(rc);
+ fHeadless = vboxSvcClipboardGetHeadless();
+ RTTESTI_CHECK_MSG(fHeadless == false, ("fHeadless=%RTbool\n", fHeadless));
+ rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS,
+ 0, parms);
+ RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER);
+ rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS,
+ 2, parms);
+ RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER);
+ parms[0].setUInt64(99);
+ rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS,
+ 1, parms);
+ RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER);
+ parms[0].setUInt32(true);
+ rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS,
+ 1, parms);
+ RTTESTI_CHECK_RC_OK(rc);
+ fHeadless = vboxSvcClipboardGetHeadless();
+ RTTESTI_CHECK_MSG(fHeadless == true, ("fHeadless=%RTbool\n", fHeadless));
+ parms[0].setUInt32(99);
+ rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS,
+ 1, parms);
+ RTTESTI_CHECK_RC_OK(rc);
+ fHeadless = vboxSvcClipboardGetHeadless();
+ RTTESTI_CHECK_MSG(fHeadless == true, ("fHeadless=%RTbool\n", fHeadless));
+}
+
+static void testHostCall(void)
+{
+ testSetMode();
+ testSetHeadless();
+}
+
+
+int main(int argc, char *argv[])
+{
+ /*
+ * Init the runtime, test and say hello.
+ */
+ const char *pcszExecName;
+ NOREF(argc);
+ pcszExecName = strrchr(argv[0], '/');
+ pcszExecName = pcszExecName ? pcszExecName + 1 : argv[0];
+ RTTEST hTest;
+ RTEXITCODE rcExit = RTTestInitAndCreate(pcszExecName, &hTest);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ RTTestBanner(hTest);
+
+ /*
+ * Run the tests.
+ */
+ testHostCall();
+
+ /*
+ * Summary
+ */
+ return RTTestSummaryAndDestroy(hTest);
+}
+
+int vboxClipboardInit() { return VINF_SUCCESS; }
+void vboxClipboardDestroy() { AssertFailed(); }
+void vboxClipboardDisconnect(_VBOXCLIPBOARDCLIENTDATA*) { AssertFailed(); }
+int vboxClipboardConnect(_VBOXCLIPBOARDCLIENTDATA*, bool)
+{ AssertFailed(); return VERR_WRONG_ORDER; }
+void vboxClipboardFormatAnnounce(_VBOXCLIPBOARDCLIENTDATA*, unsigned int)
+{ AssertFailed(); }
+int vboxClipboardReadData(_VBOXCLIPBOARDCLIENTDATA*, unsigned int, void*, unsigned int, unsigned int*)
+{ AssertFailed(); return VERR_WRONG_ORDER; }
+void vboxClipboardWriteData(_VBOXCLIPBOARDCLIENTDATA*, void*, unsigned int, unsigned int) { AssertFailed(); }
+int vboxClipboardSync(_VBOXCLIPBOARDCLIENTDATA*)
+{ AssertFailed(); return VERR_WRONG_ORDER; }
diff --git a/src/VBox/HostServices/SharedClipboard/x11-clipboard.cpp b/src/VBox/HostServices/SharedClipboard/x11-clipboard.cpp
index e36483dc9..3a509232c 100644
--- a/src/VBox/HostServices/SharedClipboard/x11-clipboard.cpp
+++ b/src/VBox/HostServices/SharedClipboard/x11-clipboard.cpp
@@ -22,6 +22,7 @@
#include <iprt/assert.h>
#include <iprt/critsect.h>
+#include <iprt/env.h>
#include <iprt/mem.h>
#include <iprt/semaphore.h>
@@ -97,7 +98,7 @@ void vboxClipboardDestroy (void)
* @note on the host, we assume that some other application already owns
* the clipboard and leave ownership to X11.
*/
-int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient)
+int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool fHeadless)
{
int rc = VINF_SUCCESS;
CLIPBACKEND *pBackend = NULL;
@@ -110,7 +111,7 @@ int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient)
else
{
RTCritSectInit(&pCtx->clipboardMutex);
- pBackend = ClipConstructX11(pCtx);
+ pBackend = ClipConstructX11(pCtx, fHeadless);
if (pBackend == NULL)
rc = VERR_NO_MEMORY;
else
@@ -469,7 +470,7 @@ void vboxSvcClipboardCompleteReadData(VBOXCLIPBOARDCLIENTDATA *pClient, int rc,
pBackend->completeRead.cbActual = cbActual;
}
-CLIPBACKEND *ClipConstructX11(VBOXCLIPBOARDCONTEXT *pFrontend)
+CLIPBACKEND *ClipConstructX11(VBOXCLIPBOARDCONTEXT *pFrontend, bool)
{
return (CLIPBACKEND *)RTMemAllocZ(sizeof(CLIPBACKEND));
}
@@ -510,7 +511,7 @@ int main()
int rc = RTR3Init();
RTPrintf(TEST_NAME ": TESTING\n");
AssertRCReturn(rc, 1);
- rc = vboxClipboardConnect(&client);
+ rc = vboxClipboardConnect(&client, false);
CLIPBACKEND *pBackend = client.pCtx->pBackend;
AssertRCReturn(rc, 1);
vboxClipboardFormatAnnounce(&client,
diff --git a/src/VBox/HostServices/SharedFolders/Makefile.kmk b/src/VBox/HostServices/SharedFolders/Makefile.kmk
index cc250c8e4..1e22e76d4 100644
--- a/src/VBox/HostServices/SharedFolders/Makefile.kmk
+++ b/src/VBox/HostServices/SharedFolders/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the Shared Folders Host Service.
#
diff --git a/src/VBox/HostServices/SharedFolders/testcase/Makefile.kmk b/src/VBox/HostServices/SharedFolders/testcase/Makefile.kmk
index e3f5788d7..aca880b69 100644
--- a/src/VBox/HostServices/SharedFolders/testcase/Makefile.kmk
+++ b/src/VBox/HostServices/SharedFolders/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Sub-Makefile for the Shared Folders Host Service testcases.
#
diff --git a/src/VBox/HostServices/SharedOpenGL/Makefile.kmk b/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
index 3227dd557..6342dca35 100644
--- a/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
+++ b/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37332 2011-06-06 16:41:41Z vboxsync $
## @file
# Sub-Makefile for the Shared OpenGL Host Service.
#
diff --git a/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp b/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
index 3d88fe267..7eb5c3ce7 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
+++ b/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
@@ -1,4 +1,4 @@
-/* $Id: crservice.cpp $ */
+/* $Id: crservice.cpp 37433 2011-06-14 11:44:45Z vboxsync $ */
/** @file
* VBox crOpenGL: Host service entry points.
@@ -57,6 +57,12 @@
#endif
#include <VBox/com/errorprint.h>
+#include <iprt/thread.h>
+#include <iprt/critsect.h>
+#include <iprt/semaphore.h>
+#include <iprt/asm.h>
+
+#include "cr_mem.h"
PVBOXHGCMSVCHELPERS g_pHelpers;
static IConsole* g_pConsole = NULL;
@@ -72,6 +78,7 @@ static uint8_t* g_pvVRamBase;
static const char* gszVBoxOGLSSMMagic = "***OpenGL state data***";
+/* Used to process guest calls exceeding maximum allowed HGCM call size in a sequence of smaller calls */
typedef struct _CRVBOXSVCBUFFER_t {
uint32_t uiId;
uint32_t uiSize;
@@ -82,6 +89,168 @@ typedef struct _CRVBOXSVCBUFFER_t {
static CRVBOXSVCBUFFER_t *g_pCRVBoxSVCBuffers = NULL;
static uint32_t g_CRVBoxSVCBufferID = 0;
+/* svcPresentFBO related data */
+typedef struct _CRVBOXSVCPRESENTFBOCMD_t {
+ void *pData;
+ int32_t screenId, x, y, w, h;
+ _CRVBOXSVCPRESENTFBOCMD_t *pNext;
+} CRVBOXSVCPRESENTFBOCMD_t, *PCRVBOXSVCPRESENTFBOCMD_t;
+
+typedef struct _CRVBOXSVCPRESENTFBO_t {
+ PCRVBOXSVCPRESENTFBOCMD_t pQueueHead, pQueueTail; /* Head/Tail of FIFO cmds queue */
+ RTCRITSECT hQueueLock; /* Queue lock */
+ RTTHREAD hWorkerThread; /* Worker thread */
+ bool volatile bShutdownWorker; /* Shutdown flag */
+ RTSEMEVENT hEventProcess; /* Signalled when worker thread should process data or exit */
+} CRVBOXSVCPRESENTFBO_t;
+
+static CRVBOXSVCPRESENTFBO_t g_SvcPresentFBO;
+
+/* Schedule a call to a separate worker thread to avoid deadlock on EMT thread when the screen configuration changes
+ and we're processing crServerPresentFBO caused by guest application command.
+ To avoid unnecessary memcpy, worker thread frees the data passed.
+*/
+static DECLCALLBACK(void) svcPresentFBO(void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h)
+{
+ PCRVBOXSVCPRESENTFBOCMD_t pCmd;
+
+ pCmd = (PCRVBOXSVCPRESENTFBOCMD_t) RTMemAlloc(sizeof(CRVBOXSVCPRESENTFBOCMD_t));
+ if (!pCmd)
+ {
+ LogRel(("SHARED_CROPENGL svcPresentFBO: not enough memory (%d)\n", sizeof(CRVBOXSVCPRESENTFBOCMD_t)));
+ return;
+ }
+ pCmd->pData = data;
+ pCmd->screenId = screenId;
+ pCmd->x = x;
+ pCmd->y = y;
+ pCmd->w = w;
+ pCmd->h = h;
+ pCmd->pNext = NULL;
+
+ RTCritSectEnter(&g_SvcPresentFBO.hQueueLock);
+
+ if (g_SvcPresentFBO.pQueueTail)
+ {
+ g_SvcPresentFBO.pQueueTail->pNext = pCmd;
+ }
+ else
+ {
+ Assert(!g_SvcPresentFBO.pQueueHead);
+ g_SvcPresentFBO.pQueueHead = pCmd;
+ }
+ g_SvcPresentFBO.pQueueTail = pCmd;
+
+ RTCritSectLeave(&g_SvcPresentFBO.hQueueLock);
+
+ RTSemEventSignal(g_SvcPresentFBO.hEventProcess);
+}
+
+static DECLCALLBACK(int) svcPresentFBOWorkerThreadProc(RTTHREAD ThreadSelf, void *pvUser)
+{
+ int rc = VINF_SUCCESS;
+ PCRVBOXSVCPRESENTFBOCMD_t pCmd;
+
+ Log(("SHARED_CROPENGL svcPresentFBOWorkerThreadProc started\n"));
+
+ for (;;)
+ {
+ rc = RTSemEventWait(g_SvcPresentFBO.hEventProcess, RT_INDEFINITE_WAIT);
+ AssertRCReturn(rc, rc);
+
+ if (g_SvcPresentFBO.bShutdownWorker)
+ {
+ break;
+ }
+
+ // @todo use critsect only to fetch the list and update the g_SvcPresentFBO's pQueueHead and pQueueTail.
+ rc = RTCritSectEnter(&g_SvcPresentFBO.hQueueLock);
+ AssertRCReturn(rc, rc);
+
+ pCmd = g_SvcPresentFBO.pQueueHead;
+ while (pCmd)
+ {
+ ComPtr<IDisplay> pDisplay;
+
+ /*remove from queue*/
+ g_SvcPresentFBO.pQueueHead = pCmd->pNext;
+ if (!g_SvcPresentFBO.pQueueHead)
+ {
+ g_SvcPresentFBO.pQueueTail = NULL;
+ }
+
+ CHECK_ERROR_RET(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), rc);
+
+ RTCritSectLeave(&g_SvcPresentFBO.hQueueLock);
+
+ CHECK_ERROR_RET(pDisplay, DrawToScreen(pCmd->screenId, (BYTE*)pCmd->pData, pCmd->x, pCmd->y, pCmd->w, pCmd->h), rc);
+
+ crFree(pCmd->pData);
+ RTMemFree(pCmd);
+
+ rc = RTCritSectEnter(&g_SvcPresentFBO.hQueueLock);
+ AssertRCReturn(rc, rc);
+ pCmd = g_SvcPresentFBO.pQueueHead;
+ }
+
+ RTCritSectLeave(&g_SvcPresentFBO.hQueueLock);
+ }
+
+ Log(("SHARED_CROPENGL svcPresentFBOWorkerThreadProc finished\n"));
+
+ return rc;
+}
+
+static int svcPresentFBOInit(void)
+{
+ int rc = VINF_SUCCESS;
+
+ g_SvcPresentFBO.pQueueHead = NULL;
+ g_SvcPresentFBO.pQueueTail = NULL;
+ g_SvcPresentFBO.bShutdownWorker = false;
+
+ rc = RTCritSectInit(&g_SvcPresentFBO.hQueueLock);
+ AssertRCReturn(rc, rc);
+
+ rc = RTSemEventCreate(&g_SvcPresentFBO.hEventProcess);
+ AssertRCReturn(rc, rc);
+
+ rc = RTThreadCreate(&g_SvcPresentFBO.hWorkerThread, svcPresentFBOWorkerThreadProc, NULL, 0,
+ RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "OpenGLWorker");
+ AssertRCReturn(rc, rc);
+
+ crVBoxServerSetPresentFBOCB(svcPresentFBO);
+
+ return rc;
+}
+
+static int svcPresentFBOTearDown(void)
+{
+ int rc = VINF_SUCCESS;
+ PCRVBOXSVCPRESENTFBOCMD_t pQueue, pTmp;
+
+ ASMAtomicWriteBool(&g_SvcPresentFBO.bShutdownWorker, true);
+ RTSemEventSignal(g_SvcPresentFBO.hEventProcess);
+ rc = RTThreadWait(g_SvcPresentFBO.hWorkerThread, 5000, NULL);
+ AssertRCReturn(rc, rc);
+
+ RTCritSectDelete(&g_SvcPresentFBO.hQueueLock);
+ RTSemEventDestroy(g_SvcPresentFBO.hEventProcess);
+
+ pQueue = g_SvcPresentFBO.pQueueHead;
+ while (pQueue)
+ {
+ pTmp = pQueue->pNext;
+ crFree(pQueue->pData);
+ RTMemFree(pQueue);
+ pQueue = pTmp;
+ }
+ g_SvcPresentFBO.pQueueHead = NULL;
+ g_SvcPresentFBO.pQueueTail = NULL;
+
+ return rc;
+}
+
static DECLCALLBACK(int) svcUnload (void *)
{
int rc = VINF_SUCCESS;
@@ -90,6 +259,8 @@ static DECLCALLBACK(int) svcUnload (void *)
crVBoxServerTearDown();
+ svcPresentFBOTearDown();
+
return rc;
}
@@ -304,38 +475,6 @@ static void svcClientVersionUnsupported(uint32_t minor, uint32_t major)
}
}
-static DECLCALLBACK(void) svcPresentFBO(void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h)
-{
-#if 0
- ComPtr<IDisplay> pDisplay;
- BYTE *data;
- int i,j;
- CHECK_ERROR(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
-
- data = (BYTE*) RTMemTmpAllocZ(100*100*4);
-
- for (i=0; i<100; i+=2)
- {
- for (j=0; j<100; ++j)
- {
- *(data+i*100*4+j*4+0) = 0xFF;
- *(data+i*100*4+j*4+1) = 0xFF;
- *(data+i*100*4+j*4+2) = 0xFF;
- *(data+i*100*4+j*4+3) = 0xFF;
- }
- }
-
- CHECK_ERROR(pDisplay, DrawToScreen(screenId, data, 0, 0, 100, 100));
-
- RTMemTmpFree(data);
-#endif
- HRESULT rc;
- ComPtr<IDisplay> pDisplay;
-
- CHECK_ERROR(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
- CHECK_ERROR(pDisplay, DrawToScreen(screenId, (BYTE*)data, x, y, w, h));
-}
-
static CRVBOXSVCBUFFER_t* svcGetBuffer(uint32_t iBuffer, uint32_t cbBufferSize)
{
CRVBOXSVCBUFFER_t* pBuffer;
@@ -349,8 +488,14 @@ static CRVBOXSVCBUFFER_t* svcGetBuffer(uint32_t iBuffer, uint32_t cbBufferSize)
{
if (pBuffer->uiSize!=cbBufferSize)
{
- LogRel(("SHARED_CROPENGL svcGetBuffer: invalid buffer(%i) size %i instead of %i\n",
- iBuffer, pBuffer->uiSize, cbBufferSize));
+ static int shown=0;
+
+ if (shown<20)
+ {
+ shown++;
+ LogRel(("SHARED_CROPENGL svcGetBuffer: invalid buffer(%i) size %i instead of %i\n",
+ iBuffer, pBuffer->uiSize, cbBufferSize));
+ }
return NULL;
}
return pBuffer;
@@ -1091,7 +1236,7 @@ static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cPa
{
CHECK_ERROR_RET(pDisplay, GetFramebuffer(i, pFramebuffer.asOutParam(), &xo, &yo), rc);
- if (!pDisplay)
+ if (!pFramebuffer)
{
rc = crVBoxServerUnmapScreen(i);
AssertRCReturn(rc, rc);
@@ -1108,6 +1253,7 @@ static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cPa
}
g_pConsole = pConsole;
+
rc = VINF_SUCCESS;
}
}
@@ -1217,6 +1363,56 @@ static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cPa
}
break;
}
+ case SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT:
+ {
+ /*
+ * OutputRedirect.
+ * Note: the service calls OutputRedirect callbacks directly
+ * and they must not block. If asynchronous processing is needed,
+ * the callback provider must organize this.
+ */
+ Log(("svcCall: SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT\n"));
+
+ /* Verify parameter count and types. */
+ if (cParms != SHCRGL_CPARMS_SET_OUTPUT_REDIRECT)
+ {
+ rc = VERR_INVALID_PARAMETER;
+ }
+ else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
+ {
+ rc = VERR_INVALID_PARAMETER;
+ }
+ else
+ {
+ /* Fetch parameters. */
+ H3DOUTPUTREDIRECT *pOutputRedirect = (H3DOUTPUTREDIRECT *)paParms[0].u.pointer.addr;
+ uint32_t cbData = paParms[0].u.pointer.size;
+
+ /* Verify parameters values. */
+ if (cbData != sizeof (H3DOUTPUTREDIRECT))
+ {
+ rc = VERR_INVALID_PARAMETER;
+ }
+ else /* Execute the function. */
+ {
+ rc = crVBoxServerSetOffscreenRendering(GL_TRUE);
+
+ if (RT_SUCCESS(rc))
+ {
+ CROutputRedirect outputRedirect;
+ outputRedirect.pvContext = pOutputRedirect->pvContext;
+ outputRedirect.CRORBegin = pOutputRedirect->H3DORBegin;
+ outputRedirect.CRORGeometry = pOutputRedirect->H3DORGeometry;
+ outputRedirect.CRORVisibleRegion = pOutputRedirect->H3DORVisibleRegion;
+ outputRedirect.CRORFrame = pOutputRedirect->H3DORFrame;
+ outputRedirect.CROREnd = pOutputRedirect->H3DOREnd;
+ outputRedirect.CRORContextProperty = pOutputRedirect->H3DORContextProperty;
+ rc = crVBoxServerOutputRedirectSet(&outputRedirect);
+ }
+ }
+ }
+ break;
+ }
default:
rc = VERR_NOT_IMPLEMENTED;
break;
@@ -1263,7 +1459,7 @@ extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *pt
if (!crVBoxServerInit())
return VERR_NOT_SUPPORTED;
- crVBoxServerSetPresentFBOCB(svcPresentFBO);
+ rc = svcPresentFBOInit();
}
}
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/get_components.py b/src/VBox/HostServices/SharedOpenGL/crserverlib/get_components.py
index a1a522054..e1909d711 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/get_components.py
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/get_components.py
@@ -30,7 +30,7 @@ num_components = {
'GL_TEXTURE_WIDTH': 1,
'GL_TEXTURE_HEIGHT': 1,
'GL_TEXTURE_DEPTH': 1,
- # 'GL_TEXTURE_INTERNAL_FORMAT': 1, THIS CONFLICTS WITH SOMETHING?!
+ # 'GL_TEXTURE_INTERNAL_FORMAT': 1, THIS CONFLICTS WITH GL_TEXTURE_COMPONENTS!
'GL_TEXTURE_BORDER': 1,
'GL_TEXTURE_RED_SIZE': 1,
'GL_TEXTURE_GREEN_SIZE': 1,
@@ -109,6 +109,7 @@ num_extended_components = {
'GL_QUERY_RESULT_ARB': (1, 'CR_ARB_occlusion_query'),
'GL_CURRENT_QUERY_ARB': (1, 'CR_ARB_occlusion_query'),
'GL_TEXTURE_COMPRESSED_IMAGE_SIZE': (1, 'CR_ARB_texture_compression'),
+ 'GL_TEXTURE_COMPRESSED': (1, 'CR_ARB_texture_compression'),
'GL_COORD_REPLACE_ARB': (1, 'CR_ARB_point_sprite'),
}
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h b/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
index 6a6dea7f5..e2a5c81a0 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
@@ -88,6 +88,7 @@ GLint crServerSPUWindowID(GLint serverWindow);
GLuint crServerTranslateProgramID(GLuint id);
+void crServerSetupOutputRedirect(CRMuralInfo *mural);
void crServerCheckMuralGeometry(CRMuralInfo *mural);
GLboolean crServerSupportRedirMuralFBO(void);
void crServerRedirMuralFBO(CRMuralInfo *mural, GLboolean redir);
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c
index 07f409f79..577b82dcc 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c
@@ -55,6 +55,9 @@ setDefaults(void)
cr_server.idsPool.freeClientID = 1;
cr_server.screenCount = 0;
+ cr_server.bForceOffscreenRendering = GL_FALSE;
+ cr_server.bUsePBOForReadback = GL_FALSE;
+ cr_server.bUseOutputRedirect = GL_FALSE;
}
void crServerSetVBoxConfiguration()
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c
index 3a246c806..52dceb2cd 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c
@@ -217,7 +217,7 @@ crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context )
mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
if (!mural)
{
- crWarning("CRServer: invalid window %d passed to crServerDispatchMakeCurrent()");
+ crWarning("CRServer: invalid window %d passed to crServerDispatchMakeCurrent()", window);
return;
}
@@ -230,11 +230,16 @@ crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context )
}
else {
oldMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, cr_server.currentWindow);
- if (oldMural && oldMural->bUseFBO
- && crServerSupportRedirMuralFBO()
- && !crStateGetCurrent()->framebufferobject.drawFB)
+ if (oldMural && oldMural->bUseFBO && crServerSupportRedirMuralFBO())
{
- cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ if (!crStateGetCurrent()->framebufferobject.drawFB)
+ {
+ cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
+ }
+ if (!crStateGetCurrent()->framebufferobject.readFB)
+ {
+ cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
+ }
}
ctx = cr_server.DummyContext;
@@ -305,8 +310,23 @@ crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context )
{
if (!crStateGetCurrent()->framebufferobject.drawFB)
{
- cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mural->bUseFBO ? mural->idFBO:0);
+ cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, mural->bUseFBO ? mural->idFBO:0);
+ }
+ if (!crStateGetCurrent()->framebufferobject.readFB)
+ {
+ cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, mural->bUseFBO ? mural->idFBO:0);
}
}
+
+ if (!mural->bUseFBO)
+ {
+ ctx->buffer.width = mural->width;
+ ctx->buffer.height = mural->height;
+ }
+ else
+ {
+ ctx->buffer.width = 0;
+ ctx->buffer.height = 0;
+ }
}
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_framebuffer.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_framebuffer.c
index 8fb33c511..8978b9292 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_framebuffer.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_framebuffer.c
@@ -1,4 +1,4 @@
-/* $Id: server_framebuffer.c $ */
+/* $Id: server_framebuffer.c 31808 2010-08-20 09:40:40Z vboxsync $ */
/** @file
* VBox OpenGL: EXT_framebuffer_object
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_getshaders.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_getshaders.c
index 3807b695b..57bf2a4a8 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_getshaders.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_getshaders.c
@@ -1,4 +1,4 @@
-/* $Id: server_getshaders.c $ */
+/* $Id: server_getshaders.c 33045 2010-10-11 16:57:21Z vboxsync $ */
/** @file
* VBox OpenGL GLSL related get functions
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_glsl.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_glsl.c
index dd0a870f3..9598b4546 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_glsl.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_glsl.c
@@ -1,4 +1,4 @@
-/* $Id: server_glsl.c $ */
+/* $Id: server_glsl.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBox OpenGL: GLSL related functions
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
index 45169d60a..aa5a369b6 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
@@ -338,6 +338,12 @@ GLboolean crVBoxServerInit(void)
crServerInitDispatch();
crStateDiffAPI( &(cr_server.head_spu->dispatch_table) );
+ /*Check for PBO support*/
+ if (crStateGetCurrent()->extensions.ARB_pixel_buffer_object)
+ {
+ cr_server.bUsePBOForReadback=GL_TRUE;
+ }
+
return GL_TRUE;
}
@@ -942,7 +948,7 @@ DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version)
crServerDispatchWindowSize(key, muralInfo.width, muralInfo.height);
crServerDispatchWindowPosition(key, muralInfo.gX, muralInfo.gY);
/* Same workaround as described in stub.c:stubUpdateWindowVisibileRegions for compiz on a freshly booted VM*/
- if (muralInfo.cVisibleRects)
+ if (muralInfo.bReceivedRects)
{
crServerDispatchWindowVisibleRegion(key, muralInfo.cVisibleRects, muralInfo.pVisibleRects);
}
@@ -1199,11 +1205,11 @@ DECLEXPORT(int32_t) crVBoxServerMapScreen(int sIndex, int32_t x, int32_t y, uint
{
cr_server.curClient = cr_server.clients[i];
if (cr_server.curClient->currentCtx
- && cr_server.curClient->currentCtx->pImage
+ && (cr_server.curClient->currentCtx->buffer.pFrontImg || cr_server.curClient->currentCtx->buffer.pBackImg)
&& cr_server.curClient->currentMural
&& cr_server.curClient->currentMural->screenId == sIndex
- && cr_server.curClient->currentCtx->viewport.viewportH == h
- && cr_server.curClient->currentCtx->viewport.viewportW == w)
+ && cr_server.curClient->currentCtx->buffer.storedHeight == h
+ && cr_server.curClient->currentCtx->buffer.storedWidth == w)
{
int clientWindow = cr_server.curClient->currentWindow;
int clientContext = cr_server.curClient->currentContextNumber;
@@ -1234,3 +1240,41 @@ DECLEXPORT(void) crVBoxServerSetPresentFBOCB(PFNCRSERVERPRESENTFBO pfnPresentFBO
{
cr_server.pfnPresentFBO = pfnPresentFBO;
}
+
+DECLEXPORT(int32_t) crVBoxServerSetOffscreenRendering(GLboolean value)
+{
+ if (cr_server.bForceOffscreenRendering==value)
+ {
+ return VINF_SUCCESS;
+ }
+
+ if (value && !crServerSupportRedirMuralFBO())
+ {
+ return VERR_NOT_SUPPORTED;
+ }
+
+ cr_server.bForceOffscreenRendering=value;
+
+ crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL);
+
+ return VINF_SUCCESS;
+}
+
+DECLEXPORT(int32_t) crVBoxServerOutputRedirectSet(const CROutputRedirect *pCallbacks)
+{
+ /* No need for a synchronization as this is single threaded. */
+ if (pCallbacks)
+ {
+ cr_server.outputRedirect = *pCallbacks;
+ cr_server.bUseOutputRedirect = true;
+ }
+ else
+ {
+ cr_server.bUseOutputRedirect = false;
+ }
+
+ // @todo dynamically intercept already existing output:
+ // crHashtableWalk(cr_server.muralTable, crVBoxServerOutputRedirectCB, NULL);
+
+ return VINF_SUCCESS;
+}
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c
index 56a5841d8..6464995ae 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c
@@ -1,4 +1,4 @@
-/* $Id: server_muralfbo.c $ */
+/* $Id: server_muralfbo.c 37613 2011-06-23 12:42:08Z vboxsync $ */
/** @file
* VBox crOpenGL: Window to FBO redirect support.
@@ -45,12 +45,62 @@ static GLboolean crServerMuralCoverScreen(CRMuralInfo *mural, int sId)
&& mural->gY+(int)mural->height > cr_server.screen[sId].y+(int)cr_server.screen[sId].h;
}
+/* Called when a new CRMuralInfo is created
+ * or when OutputRedirect status is changed.
+ */
+void crServerSetupOutputRedirect(CRMuralInfo *mural)
+{
+ /* Unset the previous redirect. */
+ if (mural->pvOutputRedirectInstance)
+ {
+ cr_server.outputRedirect.CROREnd(mural->pvOutputRedirectInstance);
+ mural->pvOutputRedirectInstance = NULL;
+ }
+
+ /* Setup a new redirect. */
+ if (cr_server.bUseOutputRedirect)
+ {
+ /* Query supported formats. */
+ uint32_t cbFormats = 4096;
+ char *pachFormats = (char *)crAlloc(cbFormats);
+
+ if (pachFormats)
+ {
+ int rc = cr_server.outputRedirect.CRORContextProperty(cr_server.outputRedirect.pvContext,
+ 0 /* H3DOR_PROP_FORMATS */, // @todo from a header
+ pachFormats, cbFormats, &cbFormats);
+ if (RT_SUCCESS(rc))
+ {
+ if (RTStrStr(pachFormats, "H3DOR_FMT_RGBA_TOPDOWN"))
+ {
+ cr_server.outputRedirect.CRORBegin(cr_server.outputRedirect.pvContext,
+ &mural->pvOutputRedirectInstance,
+ "H3DOR_FMT_RGBA_TOPDOWN"); // @todo from a header
+ }
+ }
+
+ crFree(pachFormats);
+ }
+
+ /* If this is not NULL then there was a supported format. */
+ if (mural->pvOutputRedirectInstance)
+ {
+ cr_server.outputRedirect.CRORGeometry(mural->pvOutputRedirectInstance,
+ mural->hX, mural->hY,
+ mural->width, mural->height);
+ // @todo the code assumes that RTRECT == four of GLInts
+ cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance,
+ mural->cVisibleRects, (RTRECT *)mural->pVisibleRects);
+ }
+ }
+}
+
void crServerCheckMuralGeometry(CRMuralInfo *mural)
{
int tlS, brS, trS, blS;
int overlappingScreenCount, primaryS, i;
- if (cr_server.screenCount<2)
+ if (cr_server.screenCount<2 && !cr_server.bForceOffscreenRendering)
{
CRASSERT(cr_server.screenCount>0);
@@ -104,7 +154,7 @@ void crServerCheckMuralGeometry(CRMuralInfo *mural)
mural->hX = mural->gX-cr_server.screen[primaryS].x;
mural->hY = mural->gY-cr_server.screen[primaryS].y;
- if (overlappingScreenCount<2)
+ if (overlappingScreenCount<2 && !cr_server.bForceOffscreenRendering)
{
if (mural->bUseFBO)
{
@@ -136,6 +186,13 @@ void crServerCheckMuralGeometry(CRMuralInfo *mural)
cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX, mural->hY);
}
}
+
+ if (mural->pvOutputRedirectInstance)
+ {
+ cr_server.outputRedirect.CRORGeometry(mural->pvOutputRedirectInstance,
+ mural->hX, mural->hY,
+ mural->width, mural->height);
+ }
}
GLboolean crServerSupportRedirMuralFBO(void)
@@ -166,18 +223,34 @@ void crServerRedirMuralFBO(CRMuralInfo *mural, GLboolean redir)
if (!crStateGetCurrent()->framebufferobject.drawFB)
{
- cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mural->idFBO);
+ cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, mural->idFBO);
}
+ if (!crStateGetCurrent()->framebufferobject.readFB)
+ {
+ cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, mural->idFBO);
+ }
+
+ crStateGetCurrent()->buffer.width = 0;
+ crStateGetCurrent()->buffer.height = 0;
}
else
{
cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, mural->bVisible);
- if (mural->bUseFBO && crServerSupportRedirMuralFBO()
- && !crStateGetCurrent()->framebufferobject.drawFB)
+ if (mural->bUseFBO && crServerSupportRedirMuralFBO())
{
- cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ if (!crStateGetCurrent()->framebufferobject.drawFB)
+ {
+ cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
+ }
+ if (!crStateGetCurrent()->framebufferobject.readFB)
+ {
+ cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
+ }
}
+
+ crStateGetCurrent()->buffer.width = mural->width;
+ crStateGetCurrent()->buffer.height = mural->height;
}
mural->bUseFBO = redir;
@@ -188,37 +261,42 @@ void crServerCreateMuralFBO(CRMuralInfo *mural)
CRContext *ctx = crStateGetCurrent();
GLuint uid;
GLenum status;
+ SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
CRASSERT(mural->idFBO==0);
/*Color texture*/
- cr_server.head_spu->dispatch_table.GenTextures(1, &mural->idColorTex);
- cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, mural->idColorTex);
- cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- cr_server.head_spu->dispatch_table.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mural->width, mural->height,
- 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
+ gl->GenTextures(1, &mural->idColorTex);
+ gl->BindTexture(GL_TEXTURE_2D, mural->idColorTex);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ }
+ gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mural->width, mural->height,
+ 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
/*Depth&Stencil*/
- cr_server.head_spu->dispatch_table.GenRenderbuffersEXT(1, &mural->idDepthStencilRB);
- cr_server.head_spu->dispatch_table.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
- cr_server.head_spu->dispatch_table.RenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT,
- mural->width, mural->height);
+ gl->GenRenderbuffersEXT(1, &mural->idDepthStencilRB);
+ gl->BindRenderbufferEXT(GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
+ gl->RenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT,
+ mural->width, mural->height);
/*FBO*/
- cr_server.head_spu->dispatch_table.GenFramebuffersEXT(1, &mural->idFBO);
- cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mural->idFBO);
+ gl->GenFramebuffersEXT(1, &mural->idFBO);
+ gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mural->idFBO);
- cr_server.head_spu->dispatch_table.FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, mural->idColorTex, 0);
- cr_server.head_spu->dispatch_table.FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
- GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
- cr_server.head_spu->dispatch_table.FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
- GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
+ gl->FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, mural->idColorTex, 0);
+ gl->FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
+ gl->FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
- status = cr_server.head_spu->dispatch_table.CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ status = gl->CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status!=GL_FRAMEBUFFER_COMPLETE_EXT)
{
crWarning("FBO status(0x%x) isn't complete", status);
@@ -227,15 +305,37 @@ void crServerCreateMuralFBO(CRMuralInfo *mural)
mural->fboWidth = mural->width;
mural->fboHeight = mural->height;
+ /*PBO*/
+ if (cr_server.bUsePBOForReadback)
+ {
+ gl->GenBuffersARB(1, &mural->idPBO);
+ gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, mural->idPBO);
+ gl->BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, mural->width*mural->height*4, 0, GL_STREAM_READ_ARB);
+ gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
+
+ if (!mural->idPBO)
+ {
+ crWarning("PBO create failed");
+ }
+ }
+
/*Restore gl state*/
uid = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid;
- cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, uid);
+ gl->BindTexture(GL_TEXTURE_2D, uid);
uid = ctx->framebufferobject.renderbuffer ? ctx->framebufferobject.renderbuffer->hwid:0;
- cr_server.head_spu->dispatch_table.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, uid);
+ gl->BindRenderbufferEXT(GL_RENDERBUFFER_EXT, uid);
uid = ctx->framebufferobject.drawFB ? ctx->framebufferobject.drawFB->hwid:0;
- cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, uid);
+ gl->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, uid);
+
+ uid = ctx->framebufferobject.readFB ? ctx->framebufferobject.readFB->hwid:0;
+ gl->BindFramebufferEXT(GL_READ_FRAMEBUFFER, uid);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ctx->bufferobject.unpackBuffer->hwid);
+ }
}
void crServerDeleteMuralFBO(CRMuralInfo *mural)
@@ -252,6 +352,13 @@ void crServerDeleteMuralFBO(CRMuralInfo *mural)
mural->idColorTex = 0;
mural->idDepthStencilRB = 0;
}
+
+ if (mural->idPBO!=0)
+ {
+ CRASSERT(cr_server.bUsePBOForReadback);
+ cr_server.head_spu->dispatch_table.DeleteBuffersARB(1, &mural->idPBO);
+ mural->idPBO = 0;
+ }
}
#define MIN(a, b) ((a) < (b) ? (a) : (b))
@@ -307,10 +414,11 @@ static void crServerTransformRect(CRrecti *pDst, CRrecti *pSrc, int dx, int dy)
void crServerPresentFBO(CRMuralInfo *mural)
{
- char *pixels, *tmppixels;
+ char *pixels=NULL, *tmppixels;
GLuint uid;
int i, j;
CRrecti rect, rectwr, sectr;
+ GLboolean bUsePBO;
CRContext *ctx = crStateGetCurrent();
CRASSERT(cr_server.pfnPresentFBO);
@@ -320,37 +428,81 @@ void crServerPresentFBO(CRMuralInfo *mural)
return;
}
- pixels = crAlloc(4*mural->fboWidth*mural->fboHeight);
- if (!pixels)
+ if (!mural->width || !mural->height)
{
- crWarning("Out of memory in crServerPresentFBO");
return;
}
+ if (cr_server.bUsePBOForReadback && !mural->idPBO)
+ {
+ crWarning("Mural doesn't have PBO even though bUsePBOForReadback is set!");
+ }
+
+ bUsePBO = cr_server.bUsePBOForReadback && mural->idPBO;
+
cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, mural->idColorTex);
+
+ if (bUsePBO)
+ {
+ CRASSERT(mural->idPBO);
+ cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, mural->idPBO);
+ }
+ else
+ {
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
+ }
+
+ pixels = crAlloc(4*mural->fboWidth*mural->fboHeight);
+ if (!pixels)
+ {
+ crWarning("Out of memory in crServerPresentFBO");
+ return;
+ }
+ }
+
+ /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
+
+ /*restore gl state*/
uid = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid;
cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, uid);
+ if (bUsePBO)
+ {
+ pixels = cr_server.head_spu->dispatch_table.MapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
+ if (!pixels)
+ {
+ crWarning("Failed to MapBuffer in crServerPresentFBO");
+ return;
+ }
+ }
+
for (i=0; i<cr_server.screenCount; ++i)
{
if (crServerIntersectScreen(mural, i, &rect))
{
- tmppixels = crAlloc(4*(rect.x2-rect.x1)*(rect.y2-rect.y1));
- if (!tmppixels)
- {
- crWarning("Out of memory in crServerPresentFBO");
- crFree(pixels);
- return;
- }
-
/* rect in window relative coords */
crServerTransformRect(&rectwr, &rect, -mural->gX, -mural->gY);
if (!mural->pVisibleRects)
{
- crServerCopySubImage(tmppixels, pixels, &rectwr, mural->fboWidth, mural->fboHeight);
- cr_server.pfnPresentFBO(tmppixels, i, rect.x1-cr_server.screen[i].x, rect.y1-cr_server.screen[i].y, rect.x2-rect.x1, rect.y2-rect.y1);
+ /*we don't get any rects info for guest compiz windows, so we treat windows as visible unless explicitly received 0 visible rects*/
+ if (!mural->bReceivedRects)
+ {
+ tmppixels = crAlloc(4*(rect.x2-rect.x1)*(rect.y2-rect.y1));
+ if (!tmppixels)
+ {
+ crWarning("Out of memory in crServerPresentFBO");
+ crFree(pixels);
+ return;
+ }
+
+ crServerCopySubImage(tmppixels, pixels, &rectwr, mural->fboWidth, mural->fboHeight);
+ /*Note: pfnPresentFBO would free tmppixels*/
+ cr_server.pfnPresentFBO(tmppixels, i, rect.x1-cr_server.screen[i].x, rect.y1-cr_server.screen[i].y, rect.x2-rect.x1, rect.y2-rect.y1);
+ }
}
else
{
@@ -358,7 +510,16 @@ void crServerPresentFBO(CRMuralInfo *mural)
{
if (crServerIntersectRect(&rectwr, (CRrecti*) &mural->pVisibleRects[4*j], &sectr))
{
+ tmppixels = crAlloc(4*(sectr.x2-sectr.x1)*(sectr.y2-sectr.y1));
+ if (!tmppixels)
+ {
+ crWarning("Out of memory in crServerPresentFBO");
+ crFree(pixels);
+ return;
+ }
+
crServerCopySubImage(tmppixels, pixels, &sectr, mural->fboWidth, mural->fboHeight);
+ /*Note: pfnPresentFBO would free tmppixels*/
cr_server.pfnPresentFBO(tmppixels, i,
sectr.x1+mural->gX-cr_server.screen[i].x,
sectr.y1+mural->gY-cr_server.screen[i].y,
@@ -366,11 +527,30 @@ void crServerPresentFBO(CRMuralInfo *mural)
}
}
}
+ }
+ }
+
+ if (mural->pvOutputRedirectInstance)
+ {
+ /* @todo find out why presentfbo is not called but crorframe is called. */
+ cr_server.outputRedirect.CRORFrame(mural->pvOutputRedirectInstance,
+ pixels,
+ 4 * mural->fboWidth * mural->fboHeight);
+ }
- crFree(tmppixels);
+ if (bUsePBO)
+ {
+ cr_server.head_spu->dispatch_table.UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
+ cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
+ }
+ else
+ {
+ crFree(pixels);
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
}
}
- crFree(pixels);
}
GLboolean crServerIsRedirectedToFBO()
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_texture.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_texture.c
index 392bcd20c..2806dbae8 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_texture.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_texture.c
@@ -1,4 +1,4 @@
-/* $Id: server_texture.c $ */
+/* $Id: server_texture.c 29857 2010-05-28 12:25:02Z vboxsync $ */
/** @file
* VBox crOpenGL: teximage functions.
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
index 5918e5915..962a799ab 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
@@ -85,6 +85,9 @@ crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preload
mural->cVisibleRects = 0;
mural->pVisibleRects = NULL;
+ mural->bReceivedRects = GL_FALSE;
+
+ mural->pvOutputRedirectInstance = NULL;
/* generate ID for this new window/mural (special-case for file conns) */
if (cr_server.curClient && cr_server.curClient->conn->type == CR_FILE)
@@ -97,6 +100,11 @@ crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preload
pCreateInfo->pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
pCreateInfo->visualBits = visBits;
crHashtableAdd(cr_server.pWindowCreateInfoTable, windowID, pCreateInfo);
+
+ crServerSetupOutputRedirect(mural);
+
+ crStateGetCurrent()->buffer.width = mural->width;
+ crStateGetCurrent()->buffer.height = mural->height;
}
crDebug("CRServer: client %p created new window %d (SPU window %d)",
@@ -146,6 +154,12 @@ crServerDispatchWindowDestroy( GLint window )
return;
}
+ if (mural->pvOutputRedirectInstance)
+ {
+ cr_server.outputRedirect.CROREnd(mural->pvOutputRedirectInstance);
+ mural->pvOutputRedirectInstance = NULL;
+ }
+
if (cr_server.currentWindow == window)
{
cr_server.currentWindow = -1;
@@ -240,6 +254,9 @@ crServerDispatchWindowSize( GLint window, GLint width, GLint height )
mural->width = width;
mural->height = height;
+ crStateGetCurrent()->buffer.width = mural->width;
+ crStateGetCurrent()->buffer.height = mural->height;
+
crServerCheckMuralGeometry(mural);
cr_server.head_spu->dispatch_table.WindowSize(mural->spuWindow, width, height);
@@ -281,6 +298,7 @@ crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, GLint *pRects )
}
mural->cVisibleRects = cRects;
+ mural->bReceivedRects = GL_TRUE;
if (cRects)
{
mural->pVisibleRects = (GLint*) crAlloc(4*sizeof(GLint)*cRects);
@@ -292,6 +310,13 @@ crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, GLint *pRects )
}
cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
+
+ if (mural->pvOutputRedirectInstance)
+ {
+ /* @todo the code assumes that RTRECT == four GLInts. */
+ cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance,
+ cRects, (RTRECT *)pRects);
+ }
}
diff --git a/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m b/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
index bd0c55827..772684daf 100644
--- a/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
+++ b/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
@@ -1550,10 +1550,18 @@ while(0);
if (cRects > 0)
{
+#ifdef DEBUG_poetzsch
+ int i =0;
+ for (i = 0; i < cRects; ++i)
+ DEBUG_MSG_1(("OVIW(%p): setVisibleRegions: %d - %d %d %d %d\n", (void*)self, i, paRects[i * 4], paRects[i * 4 + 1], paRects[i * 4 + 2], paRects[i * 4 + 3]));
+#endif
+
m_paClipRects = (GLint*)RTMemAlloc(sizeof(GLint) * 4 * cRects);
m_cClipRects = cRects;
memcpy(m_paClipRects, paRects, sizeof(GLint) * 4 * cRects);
}
+ else
+ [self tryDraw];
}
- (NSView*)dockTileScreen
diff --git a/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c b/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
index 32fbefaf6..139f6e6e7 100644
--- a/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
+++ b/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
@@ -868,6 +868,30 @@ void renderspu_SystemMakeCurrent( WindowInfo *window, GLint nativeWindow, Contex
{
crError( "Render SPU: (MakeCurrent) Couldn't create the context for the window (error 0x%x)", GetLastError() );
}
+
+ /*Requery ext function pointers, we skip dummy ctx as it should never be used with ext functions*/
+ if (0 && context->id)
+ {
+ int numFuncs, i;
+ SPUNamedFunctionTable ext_table[1000];
+
+
+ crDebug("Default server ctx created, requerying ext functions");
+ /*requery ext functions*/
+ numFuncs = renderspuCreateFunctions(ext_table);
+ numFuncs += crLoadOpenGLExtensions( &render_spu.ws, ext_table+numFuncs);
+ CRASSERT(numFuncs < 1000);
+
+ /*change spu dispatch*/
+ crSPUChangeDispatch(&render_spu.self, ext_table);
+
+
+ /*cleanup temp table*/
+ for (i=0; i<numFuncs; ++i)
+ {
+ if (ext_table[i].name) crFree(ext_table[i].name);
+ }
+ }
}
/*crDebug("MakeCurrent 0x%x, 0x%x", window->device_context, context->hRC);*/
diff --git a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_framebuffer.c b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_framebuffer.c
index ca4d82b30..1241f4bcb 100644
--- a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_framebuffer.c
+++ b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_framebuffer.c
@@ -1,4 +1,4 @@
-/* $Id: unpack_framebuffer.c $ */
+/* $Id: unpack_framebuffer.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox OpenGL: EXT_framebuffer_object
diff --git a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_shaders.c b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_shaders.c
index 6b3204ce4..6bc97422a 100644
--- a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_shaders.c
+++ b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_shaders.c
@@ -1,4 +1,4 @@
-/* $Id: unpack_shaders.c $ */
+/* $Id: unpack_shaders.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox OpenGL DRI driver functions
diff --git a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_visibleregion.c b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_visibleregion.c
index 4bae17d19..503e015c5 100644..100755
--- a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_visibleregion.c
+++ b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_visibleregion.c
@@ -1,4 +1,4 @@
-/* $Id: unpack_visibleregion.c $ */
+/* $Id: unpack_visibleregion.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox Packing VisibleRegion information
diff --git a/src/VBox/HostServices/auth/Makefile.kmk b/src/VBox/HostServices/auth/Makefile.kmk
index f23dcabf1..b605bf007 100644
--- a/src/VBox/HostServices/auth/Makefile.kmk
+++ b/src/VBox/HostServices/auth/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37429 2011-06-13 19:59:08Z vboxsync $
## @file
# Sub-Makefile for the VBox RDP authentication plugins.
#
diff --git a/src/VBox/HostServices/testcase/Makefile.kmk b/src/VBox/HostServices/testcase/Makefile.kmk
index 592a89bbe..cc66229a0 100644
--- a/src/VBox/HostServices/testcase/Makefile.kmk
+++ b/src/VBox/HostServices/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Sub-Makefile for the HGCM service testcase.
#
diff --git a/src/VBox/HostServices/testcase/tstHGCMSvc.cpp b/src/VBox/HostServices/testcase/tstHGCMSvc.cpp
index 6adf1a28c..648a9c18f 100644
--- a/src/VBox/HostServices/testcase/tstHGCMSvc.cpp
+++ b/src/VBox/HostServices/testcase/tstHGCMSvc.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstHGCMSvc.cpp $ */
+/* $Id: tstHGCMSvc.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* HGCM Service Testcase.
*/
diff --git a/src/VBox/ImageMounter/VBoxFUSE/Makefile.kmk b/src/VBox/ImageMounter/VBoxFUSE/Makefile.kmk
index 5800b1dc0..2e23fb460 100644
--- a/src/VBox/ImageMounter/VBoxFUSE/Makefile.kmk
+++ b/src/VBox/ImageMounter/VBoxFUSE/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 31844 2010-08-21 19:37:58Z vboxsync $
## @file
# Sub-Makefile for the VBoxFUSE Program.
#
diff --git a/src/VBox/ImageMounter/VBoxFUSE/VBoxFUSE.cpp b/src/VBox/ImageMounter/VBoxFUSE/VBoxFUSE.cpp
index 6cce87e6c..de3a47305 100644
--- a/src/VBox/ImageMounter/VBoxFUSE/VBoxFUSE.cpp
+++ b/src/VBox/ImageMounter/VBoxFUSE/VBoxFUSE.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxFUSE.cpp $ */
+/* $Id: VBoxFUSE.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* VBoxFUSE - Disk Image Flattening FUSE Program.
*/
diff --git a/src/VBox/Installer/Makefile.kmk b/src/VBox/Installer/Makefile.kmk
index a3712dbe8..be9b4c954 100644
--- a/src/VBox/Installer/Makefile.kmk
+++ b/src/VBox/Installer/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Install misc stuff and create dist packages.
#
diff --git a/src/VBox/Installer/common/Makefile.kmk b/src/VBox/Installer/common/Makefile.kmk
index b31eb60ba..86ef520fd 100644
--- a/src/VBox/Installer/common/Makefile.kmk
+++ b/src/VBox/Installer/common/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 38001 2011-07-18 10:16:11Z vboxsync $
## @file
# Common installer stuff.
#
@@ -28,7 +28,7 @@ ifdef VBOX_WITH_PYTHON
INSTALLS += VBox-python-glue-installer
-VBox-python-glue-installer_INST = $(INST_SDK)/installer
+VBox-python-glue-installer_INST = $(INST_SDK)/installer/
VBox-python-glue-installer_SOURCES = vboxapisetup.py
endif # VBOX_WITH_PYTHON
diff --git a/src/VBox/Installer/common/virtualbox.xml b/src/VBox/Installer/common/virtualbox.xml
index 089c4f91a..3af24a30d 100644
--- a/src/VBox/Installer/common/virtualbox.xml
+++ b/src/VBox/Installer/common/virtualbox.xml
@@ -27,4 +27,32 @@
<glob pattern="*.ova"/>
<icon name="virtualbox-ova"/>
</mime-type>
+
+ <mime-type type="application/x-virtualbox-vdi">
+ <comment>Virtual Disk Image</comment>
+ <comment xml:lang="en">Virtual Disk Image</comment>
+ <glob pattern="*.vdi"/>
+ <icon name="virtualbox-vdi"/>
+ </mime-type>
+
+ <mime-type type="application/x-virtualbox-vmdk">
+ <comment>Virtual Machine Disk Format</comment>
+ <comment xml:lang="en">Virtual Machine Disk Format</comment>
+ <glob pattern="*.vmdk"/>
+ <icon name="virtualbox-vmdk"/>
+ </mime-type>
+
+ <mime-type type="application/x-virtualbox-vhd">
+ <comment>Virtual Hard Disk</comment>
+ <comment xml:lang="en">Virtual Hard Disk</comment>
+ <glob pattern="*.vhd"/>
+ <icon name="virtualbox-vhd"/>
+ </mime-type>
+
+ <mime-type type="application/x-virtualbox-hdd">
+ <comment>Virtual Hard Disk</comment>
+ <comment xml:lang="en">Virtual Hard Disk</comment>
+ <glob pattern="*.hdd"/>
+ <icon name="virtualbox-hdd"/>
+ </mime-type>
</mime-info>
diff --git a/src/VBox/Installer/darwin/Makefile.kmk b/src/VBox/Installer/darwin/Makefile.kmk
index 34c67ccf8..94e0fa326 100644
--- a/src/VBox/Installer/darwin/Makefile.kmk
+++ b/src/VBox/Installer/darwin/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37549 2011-06-20 08:44:19Z vboxsync $
## @file
# Install misc stuff and create dist packages for Mac OS X.
#
@@ -660,6 +660,10 @@ VBOX_DI_VBAPP_MISC_FILES = \
Resources/virtualbox-vbox-extpack.icns \
Resources/virtualbox-ovf.icns \
Resources/virtualbox-ova.icns \
+ Resources/virtualbox-vdi.icns \
+ Resources/virtualbox-vmdk.icns \
+ Resources/virtualbox-vhd.icns \
+ Resources/virtualbox-hdd.icns \
MacOS/components/VBoxXPCOMBase.xpt \
MacOS/components/VirtualBox_XPCOM.xpt
ifdef VBOX_WITH_DOCS_PACKING
diff --git a/src/VBox/Installer/darwin/VirtualBox/postflight b/src/VBox/Installer/darwin/VirtualBox/postflight
index 0a1320037..0a1320037 100755..100644
--- a/src/VBox/Installer/darwin/VirtualBox/postflight
+++ b/src/VBox/Installer/darwin/VirtualBox/postflight
diff --git a/src/VBox/Installer/freebsd/Makefile.kmk b/src/VBox/Installer/freebsd/Makefile.kmk
index 71beed19b..e5e3f2efe 100644
--- a/src/VBox/Installer/freebsd/Makefile.kmk
+++ b/src/VBox/Installer/freebsd/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 35380 2010-12-30 16:06:17Z vboxsync $
## @file
# Makefile for the FreeBSD installer.
#
diff --git a/src/VBox/Installer/freebsd/postdeinstall.sh b/src/VBox/Installer/freebsd/postdeinstall.sh
index 394d5d4a7..394d5d4a7 100755..100644
--- a/src/VBox/Installer/freebsd/postdeinstall.sh
+++ b/src/VBox/Installer/freebsd/postdeinstall.sh
diff --git a/src/VBox/Installer/freebsd/postinstall.sh b/src/VBox/Installer/freebsd/postinstall.sh
index 7bb905b75..7bb905b75 100755..100644
--- a/src/VBox/Installer/freebsd/postinstall.sh
+++ b/src/VBox/Installer/freebsd/postinstall.sh
diff --git a/src/VBox/Installer/linux/Makefile.include.footer b/src/VBox/Installer/linux/Makefile.include.footer
new file mode 100644
index 000000000..a7cc480de
--- /dev/null
+++ b/src/VBox/Installer/linux/Makefile.include.footer
@@ -0,0 +1,92 @@
+#
+# VirtualBox Guest Additions kernel module Makefile, common parts.
+#
+# See Makefile.include.header for details of how to use this.
+#
+# Copyright (C) 2006-2011 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+# override is required by the Debian guys
+override MODULE = $(MOD_NAME)
+OBJS = $(MOD_OBJS)
+
+ifneq ($(MAKECMDGOALS),clean)
+
+KBUILD_VERBOSE ?= 1
+
+#
+# Compiler options
+#
+ifndef INCL
+ INCL := $(addprefix -I,$(KERN_INCL) $(EXTRA_INCL))
+ ifndef KBUILD_EXTMOD
+ KBUILD_EXTMOD := $(shell pwd)
+ endif
+ INCL += $(MOD_INCL)
+ export INCL
+endif
+KFLAGS := -D__KERNEL__ -DMODULE $(MOD_DEFS)
+ifeq ($(BUILD_TYPE),debug)
+ KFLAGS += -DDEBUG
+endif
+
+ifeq ($(KERN_VERSION), 24)
+#
+# 2.4
+#
+
+ifeq ($(BUILD_TARGET_ARCH),amd64)
+ KFLAGS += -mcmodel=kernel
+endif
+
+CFLAGS := -O2 -DVBOX_LINUX_2_4 $(MOD_CFLAGS) $(INCL) $(KFLAGS) $(MOD_EXTRA) $(KDEBUG)
+MODULE_EXT := o
+
+# 2.4 Module linking
+$(MODULE).o: $(OBJS)
+ $(LD) -o $@ -r $(OBJS)
+
+.PHONY: $(MODULE)
+all: $(MODULE)
+$(MODULE): $(MODULE).o
+
+else
+#
+# 2.6 and later
+#
+
+MODULE_EXT := ko
+
+$(MODULE)-y := $(OBJS)
+
+# build defs
+EXTRA_CFLAGS += $(MOD_CFLAGS) $(INCL) $(KFLAGS) $(MOD_EXTRA) $(KDEBUG)
+
+all: $(MODULE)
+
+obj-m += $(MODULE).o
+
+$(MODULE):
+ $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C $(KERN_DIR) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) modules
+
+endif
+
+install: $(MODULE)
+ @mkdir -p $(MODULE_DIR); \
+ install -m 0664 -o root -g root $(MODULE).$(MODULE_EXT) $(MODULE_DIR); \
+ PATH="$(PATH):/bin:/sbin" depmod -a;
+
+endif # eq($(MAKECMDGOALS),clean)
+
+# important: Don't remove Module.symvers! DKMS does 'make clean' before building ...
+clean:
+ for f in $(MOD_CLEAN); do rm -f $$f/*.o $$f/.*.cmd $$f/.*.flags; done
+ rm -rf .$(MOD_NAME)* .tmp_ver* $(MOD_NAME).* Modules.symvers modules.order
diff --git a/src/VBox/Additions/linux/installer/Makefile.include.footer b/src/VBox/Installer/linux/Makefile.include.header
index a9d1223fd..21183da65 100644
--- a/src/VBox/Additions/linux/installer/Makefile.include.footer
+++ b/src/VBox/Installer/linux/Makefile.include.header
@@ -3,7 +3,7 @@
#
# (For 2.6.x, the main file must be called 'Makefile'!)
#
-# Copyright (C) 2006-2007 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;
@@ -19,44 +19,63 @@
# build as part of the Guest Additions. The intended way of doing this is as
# follows:
#
-# include Makefile.include
+# # Linux kbuild sets this to our source directory if we are called from
+# # there
+# obj ?= $(CURDIR)
+# include $(obj)/Makefile.include.header
# MOD_NAME = <name of the module to be built, without extension>
# MOD_OBJS = <list of object files which should be included>
-# MOD_FLAGS = <any additional CFLAGS which this module needs>
+# MOD_DEFS = <any additional defines which this module needs>
+# MOD_INCL = <any additional include paths which this module needs>
+# MOD_CFLAGS = <any additional CFLAGS which this module needs>
+# MOD_CLEAN = <list of directories that the clean target should look at>
+# include $(obj)/Makefile.include.footer
#
# The kmk kBuild define KBUILD_TARGET_ARCH is available.
#
-# @todo the shared folders module Makefile also includes the following bits.
-# Integrate them if necessary.
-# MOD_FLAGS += -DEXPORT_SYMTAB -DVBGL_VBOXGUEST -DRT_WITH_VBOX
+
+
+#
+# First, figure out which architecture we're targeting and the build type.
+# (We have to support basic cross building (ARCH=i386|x86_64).)
+# While at it, warn about BUILD_* vars found to help with user problems.
#
-# # special hack for Fedora Core 6 2.6.18 (fc6), rhel5 2.6.18 (el5),
-# # ClarkConnect 4.3 (cc4) and ClarkConnect 5 (v5)
-# ifeq ($(KERNELRELEASE),)
-# KFLAGS += $(foreach inc,$(KERN_INCL),\
-# $(if $(wildcard $(inc)/linux/utsrelease.h),\
-# $(if $(shell grep '"2.6.18.*fc6.*"' $(inc)/linux/utsrelease.h; \
-# grep '"2.6.18.*el5.*"' $(inc)/linux/utsrelease.h; \
-# grep '"2.6.18.*v5.*"' $(inc)/linux/utsrelease.h; \
-# grep '"2.6.18.*cc4.*"' $(inc)/linux/utsrelease.h),\
-# -DKERNEL_FC6,),))
-# else
-# KFLAGS += $(if $(shell echo "$(KERNELRELEASE)"|grep '2.6.18.*fc6.*';\
-# echo "$(KERNELRELEASE)"|grep '2.6.18.*el5.*';\
-# echo "$(KERNELRELEASE)"|grep '2.6.18.*v5.*';\
-# echo "$(KERNELRELEASE)"|grep '2.6.18.*cc4.*'),\
-# -DKERNEL_FC6,)
-# endif
-#
-## important: Don't remove Module.symvers! DKMS does 'make clean' before building ...
-# rm -rf .vboxsf* .tmp_ver* vboxsf.* Modules.symvers modules.order
-#
-
-
-
-# override is required by the Debian guys
-override MODULE = $(MOD_NAME)
-OBJS = $(MOD_OBJS)
+ifeq ($(filter-out x86_64 amd64 AMD64,$(shell uname -m)),)
+ BUILD_TARGET_ARCH_DEF := amd64
+else
+ BUILD_TARGET_ARCH_DEF := x86
+endif
+ifneq ($(filter-out amd64 x86,$(BUILD_TARGET_ARCH)),)
+ $(warning Ignoring unknown BUILD_TARGET_ARCH value '$(BUILD_TARGET_ARCH)'.)
+ BUILD_TARGET_ARCH :=
+endif
+ifeq ($(BUILD_TARGET_ARCH),)
+ ifeq ($(ARCH),x86_64)
+ BUILD_TARGET_ARCH := amd64
+ else
+ ifeq ($(ARCH),i386)
+ BUILD_TARGET_ARCH := x86
+ else
+ BUILD_TARGET_ARCH := $(BUILD_TARGET_ARCH_DEF)
+ endif
+ endif
+else
+ ifneq ($(BUILD_TARGET_ARCH),$(BUILD_TARGET_ARCH_DEF))
+ $(warning Using BUILD_TARGET_ARCH='$(BUILD_TARGET_ARCH)' from the $(origin BUILD_TARGET_ARCH).)
+ endif
+endif
+
+ifneq ($(filter-out release profile debug strict,$(BUILD_TYPE)),)
+ $(warning Ignoring unknown BUILD_TYPE value '$(BUILD_TYPE)'.)
+ BUILD_TYPE :=
+endif
+ifeq ($(BUILD_TYPE),)
+ BUILD_TYPE := release
+else
+ ifneq ($(BUILD_TYPE),release)
+ $(warning Using BUILD_TYPE='$(BUILD_TYPE)' from the $(origin BUILD_TYPE).)
+ endif
+endif
ifneq ($(MAKECMDGOALS),clean)
@@ -101,7 +120,7 @@ ifeq ($(KERNELRELEASE),)
ifeq ($(shell if test -d $(MODULE_DIR_TST); then echo yes; fi),yes)
MODULE_DIR := $(MODULE_DIR_TST)/misc
else
- $(error Unable to find the folder to install the driver ($(MOD_NAME)) to)
+ $(error Unable to find the folder to install the module to)
endif
endif # MODULE_DIR unspecified
endif
@@ -120,7 +139,7 @@ else # neq($(KERNELRELEASE),)
#
# guess kernel version (24 or 26)
- ifeq ($(shell if echo "$(VERSION).$(PATCHLEVEL)." | grep '2\.4\.' > /dev/null; then echo yes; fi),yes)
+ ifeq ($(shell if echo "$(VERSION).$(PATCHLEVEL)." | grep '2\.4\.' > /dev/null; then echo yes; fi),yes)
KERN_VERSION := 24
else
KERN_VERSION := 26
@@ -136,75 +155,4 @@ $(warning dbg: MODULE_DIR = $(MODULE_DIR))
$(warning dbg: KERN_VERSION = $(KERN_VERSION))
endif
-KBUILD_VERBOSE ?= 1
-
-#
-# Compiler options
-#
-ifndef INCL
- INCL := $(addprefix -I,$(KERN_INCL) $(EXTRA_INCL))
- ifndef KBUILD_EXTMOD
- KBUILD_EXTMOD := $(shell pwd)
- endif
- INCL += $(addprefix -I$(KBUILD_EXTMOD),/ /include /r0drv/linux)
- export INCL
-endif
-KFLAGS := -D__KERNEL__ -DMODULE -DRT_OS_LINUX -DIN_RING0 \
- -DIN_RT_R0 -DIN_SUP_R0 -DVBOX -DVBGL_VBOXGUEST -DVBOX_WITH_HGCM \
- -DLOG_TO_BACKDOOR -DRT_WITH_VBOX -DIN_MODULE -DIN_GUEST_R0
-ifeq ($(BUILD_TARGET_ARCH),amd64)
- KFLAGS += -DRT_ARCH_AMD64 -DVBOX_WITH_64_BITS_GUESTS
-else
- KFLAGS += -DRT_ARCH_X86
-endif
-ifeq ($(BUILD_TYPE),debug)
-KFLAGS += -DDEBUG
-endif
-
-ifeq ($(KERN_VERSION), 24)
-#
-# 2.4
-#
-
-CFLAGS := -O2 -DVBOX_LINUX_2_4 -DEXPORT_SYMTAB $(INCL) $(KFLAGS) $(KDEBUG)
-MODULE_EXT := o
-
-# 2.4 Module linking
-$(MODULE).o: $(OBJS)
- $(LD) -o $@ -r $(OBJS)
-
-.PHONY: $(MODULE)
-all: $(MODULE)
-$(MODULE): $(MODULE).o
-
-else
-#
-# 2.6 and later
-#
-
-MODULE_EXT := ko
-
-$(MODULE)-y := $(OBJS)
-
-# build defs
-EXTRA_CFLAGS += $(INCL) $(KFLAGS) $(KDEBUG)
-
-all: $(MODULE)
-
-obj-m += $(MODULE).o
-
-$(MODULE):
- $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C $(KERN_DIR) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) modules
-
-endif
-
-install: $(MODULE)
- @mkdir -p $(MODULE_DIR); \
- install -m 0664 -o root -g root $(MODULE).$(MODULE_EXT) $(MODULE_DIR); \
- PATH="$(PATH):/bin:/sbin" depmod -a;
-
endif # eq($(MAKECMDGOALS),clean)
-
-clean:
- for f in . linux r0drv r0drv/linux; do rm -f $$f/*.o $$f/.*.cmd $$f/.*.flags; done
- rm -rf .$(MOD_NAME)* .tmp_ver* $(MOD_NAME).* Module.symvers Modules.symvers modules.order
diff --git a/src/VBox/Installer/linux/Makefile.kmk b/src/VBox/Installer/linux/Makefile.kmk
index 9a45f8887..792058a47 100644
--- a/src/VBox/Installer/linux/Makefile.kmk
+++ b/src/VBox/Installer/linux/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 38001 2011-07-18 10:16:11Z vboxsync $
## @file
# Makefile for the Linux installer.
#
@@ -18,6 +18,11 @@
SUB_DEPTH = ../../../..
include $(KBUILD_PATH)/subheader.kmk
+# Include sub-makefile.
+ifdef VBOX_WITH_TESTCASES
+ include $(PATH_SUB_CURRENT)/testcase/Makefile.kmk
+endif
+
ifneq ($(KBUILD_HOST),linux)
$(error "The Linux installer can only be built on Linux!")
endif
@@ -94,7 +99,7 @@ else
endif
INSTALLS += linux-icons
-linux-icons_INST = bin/icons
+linux-icons_INST = bin/icons/
linux-icons_MODE = a+r,u+w
linux-icons_SOURCES = $(VBOX_MIME_ICONS) $(VBOX_DESKTOP_ICONS)
@@ -277,7 +282,7 @@ endif
VBOX_MIME_ICONS = \
$(addprefix $(PATH_ROOT)/src/VBox/Resources/other/,\
- $(foreach f,ova ovf vbox vbox-extpack, \
+ $(foreach f,ova ovf vbox vbox-extpack vdi vmdk vhd hdd, \
$(foreach s,16 20 24 32 48 64 72 96 128 256,\
virtualbox-$(f)-$(s)px.png=>$(s)x$(s)/virtualbox-$(f).png)))
@@ -309,12 +314,9 @@ $(PATH_BIN)/$(VBOX_LNX_PACKAGE_NAME): \
$(VBOX_LNX_INST_OUT_DIR)/vboxdrv.sh \
$(VBOX_LNX_INST_OUT_DIR)/vboxweb-service.sh \
$(VBOX_LNX_INST_OUT_DIR)/install.sh \
+ $(VBOX_PATH_LNX_INST_SRC)/installer-utils.sh \
$(VBOX_PATH_LNX_INST_SRC)/vboxdrv-pardus.py \
- $(VBOX_PATH_LNX_INST_SRC)/uninstall.sh \
- $(wildcard $(PATH_BIN)/src/*) \
- $(wildcard $(PATH_BIN)/src/*/*) \
- $(wildcard $(PATH_BIN)/src/*/*/*) \
- $(wildcard $(PATH_BIN)/src/*/*/*/*)
+ $(VBOX_PATH_LNX_INST_SRC)/uninstall.sh
$(call MSG_TOOL,makeself,,$@)
$(QUIET)$(RM) -f $(wildcard $(PATH_BIN)/VirtualBox-*.run)
$(QUIET)$(INSTALL) -m 0755 $(VBOX_PATH_LNX_INST_SRC)/routines.sh $(VBOX_LNX_INST_STAGE_DIR)/
@@ -356,7 +358,7 @@ $(VBOX_LNX_INST_OUT_DIR)/vboxweb-service.sh: $(VBOX_PATH_LNX_INST_SRC)/vboxweb-s
--output $@ \
$<
-$(VBOX_LNX_INST_OUT_DIR)/install.sh: $(VBOX_PATH_LNX_INST_SRC)/install.sh $(VBOX_VERSION_STAMP) $(VBOX_SVN_REV_KMK).ts | $$(dir $$@)
+$(VBOX_LNX_INST_OUT_DIR)/install.sh: $(VBOX_PATH_LNX_INST_SRC)/install.sh $(VBOX_PATH_LNX_INST_SRC)/installer-utils.sh $(VBOX_VERSION_STAMP) $(VBOX_SVN_REV_KMK).ts | $$(dir $$@)
$(QUIET)$(SED) \
-e "s;_VERSION_;$(VBOX_VERSION_STRING);g" \
-e "s;_SVNREV_;$(VBOX_SVN_REV);g" \
@@ -364,16 +366,32 @@ $(VBOX_LNX_INST_OUT_DIR)/install.sh: $(VBOX_PATH_LNX_INST_SRC)/install.sh $(VBOX
-e "s;_ARCH_;$(KBUILD_TARGET_ARCH);g" \
-e "s;_HARDENED_;$(VBOX_WITH_HARDENING);g" \
-e "s;_PYTHON_;$(VBOX_WITH_PYTHON);g" \
+ -e '/#include installer-utils.sh/ {' \
+ -e "r $(PATH_ROOT)/src/VBox/Installer/linux/installer-utils.sh" \
+ -e 'd' \
+ -e '}' \
--output $@ \
$<
#
+# The files that the tar archives depend on. The wildcards are ugly, but they
+# do save us from having to update the makefile whenever something new is added
+# to the module source directories.
+#
+VBOX_LNX_INST_ARCH_DEPS := \
+ $(addprefix $(VBOX_LNX_INST_OUT_DIR)/archive/, $(VBOX_LNX_ARCH_FILES)) \
+ $(VBOX_LNX_INST_DEP_ON_MAKEFILE) \
+ $(VBOX_VERSION_STAMP) \
+ $(wildcard $(PATH_BIN)/src/*) \
+ $(wildcard $(PATH_BIN)/src/*/*) \
+ $(wildcard $(PATH_BIN)/src/*/*/*) \
+ $(wildcard $(PATH_BIN)/src/*/*/*/*)
+
+
+#
# .tar.bz2 for converting into .run
#
-$(VBOX_LNX_INST_STAGE_DIR)/VirtualBox.tar.bz2: \
- $(addprefix $(VBOX_LNX_INST_OUT_DIR)/archive/, $(VBOX_LNX_ARCH_FILES)) \
- $(VBOX_LNX_INST_DEP_ON_MAKEFILE) \
- $(VBOX_VERSION_STAMP)
+$(VBOX_LNX_INST_STAGE_DIR)/VirtualBox.tar.bz2: $(VBOX_LNX_INST_ARCH_DEPS)
$(call MSG_L1,Packing $@)
$(QUIET)$(RM) -f -- $@ $(patsubst %.bz2,%,$@)
$(QUIET)$(MKDIR) -p $(@D)
@@ -388,10 +406,7 @@ endif
#
# .tar.bz2 for distribution with the files under VirtualBox-<ver>/.
#
-$(PATH_BIN)/VirtualBox.tar.bz2: \
- $(addprefix $(VBOX_LNX_INST_OUT_DIR)/archive/, $(VBOX_LNX_ARCH_FILES)) \
- $(VBOX_LNX_INST_DEP_ON_MAKEFILE) \
- $(VBOX_VERSION_STAMP)
+$(PATH_BIN)/VirtualBox.tar.bz2: $(VBOX_LNX_INST_ARCH_DEPS)
$(call MSG_L1,Packing $@)
$(QUIET)$(RM) -f -- $(VBOX_LNX_INST_OUT_DIR)/VirtualBox-$(VBOX_VERSION_STRING) $@ $(patsubst %.bz2,%,$@)
$(QUIET)$(LN_SYMLINK) $(VBOX_LNX_INST_OUT_DIR)/archive/ $(VBOX_LNX_INST_OUT_DIR)/VirtualBox-$(VBOX_VERSION_STRING)
diff --git a/src/VBox/Installer/linux/VBox.sh b/src/VBox/Installer/linux/VBox.sh
index e427872f6..e427872f6 100755..100644
--- a/src/VBox/Installer/linux/VBox.sh
+++ b/src/VBox/Installer/linux/VBox.sh
diff --git a/src/VBox/Installer/linux/VBoxCreateUSBNode.sh b/src/VBox/Installer/linux/VBoxCreateUSBNode.sh
index ab93c5ffa..7d307f547 100755..100644
--- a/src/VBox/Installer/linux/VBoxCreateUSBNode.sh
+++ b/src/VBox/Installer/linux/VBoxCreateUSBNode.sh
@@ -1,5 +1,5 @@
#! /bin/sh
-# $Id: VBoxCreateUSBNode.sh $ */
+# $Id: VBoxCreateUSBNode.sh 37339 2011-06-07 09:40:34Z vboxsync $ */
## @file
# VirtualBox USB Proxy Service, Linux Specialization.
# udev helper for creating and removing device nodes for VirtualBox USB devices
@@ -17,6 +17,9 @@
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
+# Constant, from the USB specifications
+usb_class_hub=9
+
do_remove=0
case "$1" in "--remove")
do_remove=1; shift;;
@@ -25,22 +28,21 @@ bus=`expr "$2" '/' 128 + 1`
device=`expr "$2" '%' 128 + 1`
class="$3"
group="$4"
-if test "$class" -eq 9; then
- exit 0
-fi
devdir="`printf "/dev/vboxusb/%.3d" $bus`"
devpath="`printf "/dev/vboxusb/%.3d/%.3d" $bus $device`"
-if test "$do_remove" -eq 0; then
- if test -z "$group"; then
- group="vboxusers"
- fi
+case "$do_remove" in
+ 0)
+ case "$class" in "$usb_class_hub") exit 0;; esac
+ case "$group" in "") group="vboxusers";; esac
mkdir /dev/vboxusb -m 0750 2>/dev/null
chown root:$group /dev/vboxusb 2>/dev/null
mkdir "$devdir" -m 0750 2>/dev/null
chown root:$group "$devdir" 2>/dev/null
mknod "$devpath" c $1 $2 -m 0660 2>/dev/null
chown root:$group "$devpath" 2>/dev/null
-else
+ ;;
+ 1)
rm -f "$devpath"
-fi
+ ;;
+esac
diff --git a/src/VBox/Installer/linux/VBoxSysInfo.sh b/src/VBox/Installer/linux/VBoxSysInfo.sh
index c30c75bde..c30c75bde 100755..100644
--- a/src/VBox/Installer/linux/VBoxSysInfo.sh
+++ b/src/VBox/Installer/linux/VBoxSysInfo.sh
diff --git a/src/VBox/Installer/linux/deffiles b/src/VBox/Installer/linux/deffiles
index e350ca198..e2eaa1513 100755..100644
--- a/src/VBox/Installer/linux/deffiles
+++ b/src/VBox/Installer/linux/deffiles
@@ -99,6 +99,7 @@ DEFAULT_FILE_NAMES=" \
src/include/iprt/thread.h \
src/include/iprt/types.h \
src/include/iprt/uuid.h \
+ src/include/iprt/x86.h \
src/include/internal/initterm.h \
src/include/internal/magics.h \
src/include/internal/thread.h \
diff --git a/src/VBox/Installer/linux/install.sh b/src/VBox/Installer/linux/install.sh
index 96198089f..be1951a9b 100755..100644
--- a/src/VBox/Installer/linux/install.sh
+++ b/src/VBox/Installer/linux/install.sh
@@ -17,8 +17,9 @@
PATH=$PATH:/bin:/sbin:/usr/sbin
-# Source functions needed by the installer
+# Include routines and utilities needed by the installer
. ./routines.sh
+#include installer-utils.sh
LOG="/var/log/vbox-install.log"
VERSION="_VERSION_"
@@ -281,6 +282,7 @@ if [ "$ACTION" = "install" ]; then
$DKMS remove -m vboxnetadp -v $INSTALL_VER --all > /dev/null 2>&1
fi
# OSE doesn't always have the initscript
+ rmmod vboxpci > /dev/null 2>&1
rmmod vboxnetadp > /dev/null 2>&1
rmmod vboxnetflt > /dev/null 2>&1
rmmod vboxdrv > /dev/null 2>&1
@@ -440,41 +442,8 @@ if [ "$ACTION" = "install" ]; then
fi
# Create udev description file
- if [ -d /etc/udev/rules.d ]; then
- udev_call=""
- udev_app=`which udevadm 2> /dev/null`
- if [ $? -eq 0 ]; then
- udev_call="${udev_app} version 2> /dev/null"
- else
- udev_app=`which udevinfo 2> /dev/null`
- if [ $? -eq 0 ]; then
- udev_call="${udev_app} -V 2> /dev/null"
- fi
- fi
- udev_fix="="
- if [ "${udev_call}" != "" ]; then
- udev_out=`${udev_call}`
- udev_ver=`expr "$udev_out" : '[^0-9]*\([0-9]*\)'`
- if [ "$udev_ver" = "" -o "$udev_ver" -lt 55 ]; then
- udev_fix=""
- fi
- fi
- # Write udev rules
- echo "KERNEL=${udev_fix}\"vboxdrv\", NAME=\"vboxdrv\", OWNER=\"root\", GROUP=\"$VBOXDRV_GRP\", MODE=\"$VBOXDRV_MODE\"" \
- > /etc/udev/rules.d/10-vboxdrv.rules
- echo "SUBSYSTEM=${udev_fix}\"usb_device\", ACTION=${udev_fix}\"add\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh \$major \$minor \$attr{bDeviceClass}\"" \
- >> /etc/udev/rules.d/10-vboxdrv.rules
- echo "SUBSYSTEM=${udev_fix}\"usb\", ACTION=${udev_fix}\"add\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh \$major \$minor \$attr{bDeviceClass}\"" \
- >> /etc/udev/rules.d/10-vboxdrv.rules
- echo "SUBSYSTEM=${udev_fix}\"usb_device\", ACTION=${udev_fix}\"remove\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh --remove \$major \$minor\"" \
- >> /etc/udev/rules.d/10-vboxdrv.rules
- echo "SUBSYSTEM=${udev_fix}\"usb\", ACTION=${udev_fix}\"remove\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh --remove \$major \$minor\"" \
- >> /etc/udev/rules.d/10-vboxdrv.rules
- fi
- # Remove old udev description file
- if [ -f /etc/udev/rules.d/60-vboxdrv.rules ]; then
- rm -f /etc/udev/rules.d/60-vboxdrv.rules 2> /dev/null
- fi
+ install_udev "$VBOXDRV_GRP" "$VBOXDRV_MODE" "$INSTALLATION_DIR" \
+ > /etc/udev/rules.d/10-vboxdrv.rules
# Build our device tree
for i in /sys/bus/usb/devices/*; do
diff --git a/src/VBox/Installer/linux/installer-utils.sh b/src/VBox/Installer/linux/installer-utils.sh
new file mode 100644
index 000000000..a732fcc10
--- /dev/null
+++ b/src/VBox/Installer/linux/installer-utils.sh
@@ -0,0 +1,114 @@
+# Oracle VM VirtualBox
+# VirtualBox installer shell routines
+#
+
+# Copyright (C) 2007-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.
+#
+
+setup_normal_input_install_udev() {
+ TEST_UDEV_VERSION="$1" # udev version to simulate
+ eval 'my_which() { which "$@" ; }'
+ eval 'my_test() { test "$@" ; }'
+ eval 'my_rm() { rm "$@" ; }'
+}
+
+setup_normal_input_install_udev
+
+setup_test_input_install_udev() {
+ TEST_NAME="$1" # used to identify the current test
+ TEST_UDEV_VERSION="$2" # udev version to simulate
+ eval 'my_which() { echo test_udev ; }'
+ eval 'my_test() { true ; }'
+ eval 'my_rm() { case "$2" in "/etc/udev/rules.d/60-vboxdrv.rules") true ;; *) echo "rm: bad file name \"$2\"!"; false ;; esac ; }'
+ eval 'test_udev() { echo "$TEST_UDEV_VERSION" ; }'
+ DELETED_UDEV_FILE=""
+}
+
+udev_write_vboxdrv() {
+ VBOXDRV_GRP="$1"
+ VBOXDRV_MODE="$2"
+
+ echo "KERNEL==\"vboxdrv\", NAME=\"vboxdrv\", OWNER=\"root\", GROUP=\"$VBOXDRV_GRP\", MODE=\"$VBOXDRV_MODE\""
+}
+
+udev_write_usb() {
+ INSTALLATION_DIR="$1"
+ USB_GROUP="$2"
+
+ echo "SUBSYSTEM==\"usb_device\", ACTION==\"add\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh \$major \$minor \$attr{bDeviceClass}${USB_GROUP}\""
+ echo "SUBSYSTEM==\"usb\", ACTION==\"add\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh \$major \$minor \$attr{bDeviceClass}${USB_GROUP}\""
+ echo "SUBSYSTEM==\"usb_device\", ACTION==\"remove\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh --remove \$major \$minor\""
+ echo "SUBSYSTEM==\"usb\", ACTION==\"remove\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh --remove \$major \$minor\""
+}
+
+install_udev() {
+ # install udev rule (disable with INSTALL_NO_UDEV=1 in /etc/default/virtualbox) for distribution packages
+ VBOXDRV_GRP="$1" # The group owning the vboxdrv device
+ VBOXDRV_MODE="$2" # The access mode for the vboxdrv device
+ INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
+ USB_GROUP="$4" # The group that has permission to access USB devices
+ NO_INSTALL="$5" # Set this to "1" to remove but not re-install rules
+
+ # Extra space!
+ case "$USB_GROUP" in ?*) USB_GROUP=" $USB_GROUP" ;; esac
+ case "$NO_INSTALL" in
+ "1") ;;
+ *)
+ if my_test -d /etc/udev/rules.d; then
+ udev_call=""
+ udev_app=`my_which udevadm 2> /dev/null`
+ if [ $? -eq 0 ]; then
+ udev_call="${udev_app} version 2> /dev/null"
+ else
+ udev_app=`my_which udevinfo 2> /dev/null`
+ if [ $? -eq 0 ]; then
+ udev_call="${udev_app} -V 2> /dev/null"
+ fi
+ fi
+ udev_fix=""
+ if [ "${udev_call}" != "" ]; then
+ udev_out=`${udev_call}`
+ udev_ver=`expr "$udev_out" : '[^0-9]*\([0-9]*\)'`
+ if [ "$udev_ver" = "" -o "$udev_ver" -lt 55 ]; then
+ udev_fix="1"
+ fi
+ udev_do_usb=""
+ if [ "$udev_ver" -ge 59 ]; then
+ udev_do_usb="1"
+ fi
+ fi
+ case "$udev_fix" in
+ "1")
+ udev_write_vboxdrv "$VBOXDRV_GRP" "$VBOXDRV_MODE" |
+ sed 's/\([^+=]*\)[+=]*\([^"]*"[^"]*"\)/\1=\2/g'
+ ;;
+ *)
+ udev_write_vboxdrv "$VBOXDRV_GRP" "$VBOXDRV_MODE"
+ case "$udev_do_usb" in "1")
+ udev_write_usb "$INSTALLATION_DIR" "$USB_GROUP" ;;
+ esac
+ ;;
+ esac
+
+ fi
+ ;;
+ esac
+ # Remove old udev description file
+ if my_test -f /etc/udev/rules.d/60-vboxdrv.rules; then
+ my_rm -f /etc/udev/rules.d/60-vboxdrv.rules 2> /dev/null
+ fi
+}
+
+cleanup_test_input_install_udev() {
+ setup_normal_input_install_udev
+ unset test_udev
+ DELETED_UDEV_FILE=""
+}
diff --git a/src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec b/src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec
index ac55e3583..d0e588b8f 100644
--- a/src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec
+++ b/src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec
@@ -27,7 +27,7 @@ License: GPLv2
Group: Applications/System
Vendor: Oracle Corporation
BuildRoot: %BUILDROOT%
-Requires: %LIBASOUND%
+Requires: %INITSCRIPTS% %LIBASOUND%
%if %{?rpm_suse:1}%{!?rpm_suse:0}
%debug_package
@@ -129,6 +129,10 @@ for d in /lib/modules/*; do
--use-module-symvers /tmp/vboxdrv-Module.symvers \
KBUILD_VERBOSE= KERN_DIR=$d/build MODULE_DIR=$RPM_BUILD_ROOT/$d/misc -j4 \
%INSTMOD%
+ ./src/vboxhost/vboxpci/build_in_tmp \
+ --use-module-symvers /tmp/vboxdrv-Module.symvers \
+ KBUILD_VERBOSE= KERN_DIR=$d/build MODULE_DIR=$RPM_BUILD_ROOT/$d/misc -j4 \
+ %INSTMOD%
fi
done
mv kchmviewer $RPM_BUILD_ROOT/usr/lib/virtualbox
@@ -209,10 +213,13 @@ if [ "$INSTALL_NO_VBOXDRV" != "1" ]; then
find /lib/modules -name "vboxdrv\.*" 2>/dev/null|xargs rm -f 2> /dev/null || true
find /lib/modules -name "vboxnetflt\.*" 2>/dev/null|xargs rm -f 2> /dev/null || true
find /lib/modules -name "vboxnetadp\.*" 2>/dev/null|xargs rm -f 2> /dev/null || true
+ find /lib/modules -name "vboxpci\.*" 2>/dev/null|xargs rm -f 2> /dev/null || true
fi
%post
+#include installer-utils.sh
+
LOG="/var/log/vbox-install.log"
# defaults
@@ -230,41 +237,9 @@ fi
rm -f /etc/vbox/module_not_compiled
# install udev rule (disable with INSTALL_NO_UDEV=1 in /etc/default/virtualbox)
-if [ -d /etc/udev/rules.d -a "$INSTALL_NO_UDEV" != "1" ]; then
- udev_call=""
- udev_app=`which udevadm 2> /dev/null`
- if [ $? -eq 0 ]; then
- udev_call="${udev_app} version 2> /dev/null"
- else
- udev_app=`which udevinfo 2> /dev/null`
- if [ $? -eq 0 ]; then
- udev_call="${udev_app} -V 2> /dev/null"
- fi
- fi
- udev_fix="="
- if [ "${udev_call}" != "" ]; then
- udev_out=`${udev_call}`
- udev_ver=`expr "$udev_out" : '[^0-9]*\([0-9]*\)'`
- if [ "$udev_ver" = "" -o "$udev_ver" -lt 55 ]; then
- udev_fix=""
- fi
- fi
- usb_createnode="/usr/share/virtualbox/VBoxCreateUSBNode.sh"
- echo "KERNEL=${udev_fix}\"vboxdrv\", NAME=\"vboxdrv\", OWNER=\"root\", GROUP=\"root\", MODE=\"0600\"" \
- > /etc/udev/rules.d/10-vboxdrv.rules
- echo "SUBSYSTEM=${udev_fix}\"usb_device\", ACTION=${udev_fix}\"add\", RUN+=\"${usb_createnode} \$major \$minor \$attr{bDeviceClass}\"" \
- >> /etc/udev/rules.d/10-vboxdrv.rules
- echo "SUBSYSTEM=${udev_fix}\"usb\", ACTION=${udev_fix}\"add\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"${usb_createnode} \$major \$minor \$attr{bDeviceClass}\"" \
- >> /etc/udev/rules.d/10-vboxdrv.rules
- echo "SUBSYSTEM=${udev_fix}\"usb_device\", ACTION=${udev_fix}\"remove\", RUN+=\"${usb_createnode} --remove \$major \$minor\"" \
- >> /etc/udev/rules.d/10-vboxdrv.rules
- echo "SUBSYSTEM=${udev_fix}\"usb\", ACTION=${udev_fix}\"remove\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"${usb_createnode} --remove \$major \$minor\"" \
- >> /etc/udev/rules.d/10-vboxdrv.rules
-fi
-# Remove old udev description file
-if [ -f /etc/udev/rules.d/60-vboxdrv.rules ]; then
- rm -f /etc/udev/rules.d/60-vboxdrv.rules 2> /dev/null
-fi
+install_udev root 0600 /usr/share/virtualbox vboxusers "$INSTALL_NO_UDEV" \
+ > /etc/udev/rules.d/10-vboxdrv.rules
+
# Build our device tree
for i in /sys/bus/usb/devices/*; do
if test -r "$i/dev"; then
@@ -339,6 +314,7 @@ if [ "$INSTALL_NO_VBOXDRV" = "1" ]; then
rm -f /lib/modules/*/misc/vboxdrv.ko
rm -f /lib/modules/*/misc/vboxnetflt.ko
rm -f /lib/modules/*/misc/vboxnetadp.ko
+ rm -f /lib/modules/*/misc/vboxpci.ko
fi
if [ $BUILD_MODULES -eq 1 ]; then
/etc/init.d/vboxdrv setup || true
diff --git a/src/VBox/Installer/linux/rpm/rules b/src/VBox/Installer/linux/rpm/rules
index baf026d32..b69fa7482 100755
--- a/src/VBox/Installer/linux/rpm/rules
+++ b/src/VBox/Installer/linux/rpm/rules
@@ -29,7 +29,7 @@ ifeq ($(shell if grep -q '^/usr/lib/virtualbox' /etc/permissions* 2>/dev/null; t
$(error Fix /etc/permissions*)
endif
-verpkg := VirtualBox-4.0
+verpkg := VirtualBox-4.1
current := $(shell pwd)
vboxroot := $(shell cd ../../../../; pwd)
pkgdir := $(if $(PKGDIR),$(PKGDIR),$(shell cd ../../../../..; pwd))
@@ -113,6 +113,7 @@ cfg_flags := $(if $(filter rhel4 sles10.1,$(rpmrel)),--build-libxml2,) \
bld_flags := AUTOCFG=$(current)/rpm/AutoConfig.kmk \
LOCALCFG=$(current)/rpm/LocalConfig.kmk \
PATH_OUT=$(builddir) \
+ VBOX_WITHOUT_EXTPACK_PUEL_PACKING=1 \
VBOX_DO_STRIP= \
VBOX_WITH_MULTIVERSION_PYTHON= \
$(doc_dir) \
@@ -169,6 +170,11 @@ binary: rpm/build-stamp
-e 's|%MACROSPYTHON%|$(if $(wildcard /usr/lib/rpm/macros.python),%include /usr/lib/rpm/macros.python,)|g' \
-e 's|%INSTMOD%|$(instmod)|g' \
-e 's|%LIBASOUND%|$(if $(filter lib64,$(rpmlib)),libasound.so.2()(64bit),libasound.so.2)|g' \
+ -e 's|%INITSCRIPTS%|$(if $(filter fedora,$(rpmspec)),initscripts,)|g' \
+ -e '/#include installer-utils.sh/ {' \
+ -e "r $(vboxroot)/src/VBox/Installer/linux/installer-utils.sh" \
+ -e 'd' \
+ -e '}' \
rpm/VirtualBox.tmpl.spec > $(archdir)/VirtualBox.spec
sed \
-e 's|%NOLSB%|yes|g' \
diff --git a/src/VBox/Installer/linux/run-inst.sh b/src/VBox/Installer/linux/run-inst.sh
index a513fc0b7..a513fc0b7 100755..100644
--- a/src/VBox/Installer/linux/run-inst.sh
+++ b/src/VBox/Installer/linux/run-inst.sh
diff --git a/src/VBox/Installer/linux/runasroot.sh b/src/VBox/Installer/linux/runasroot.sh
index 41125ced1..89460abe6 100755..100644
--- a/src/VBox/Installer/linux/runasroot.sh
+++ b/src/VBox/Installer/linux/runasroot.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: runasroot.sh $
+# $Id: runasroot.sh 36785 2011-04-21 08:07:14Z vboxsync $
## @file
# VirtualBox privileged execution helper script for Linux and Solaris
#
diff --git a/src/VBox/Installer/linux/sh-utils.sh b/src/VBox/Installer/linux/sh-utils.sh
index dc9e0e823..2921a184d 100644
--- a/src/VBox/Installer/linux/sh-utils.sh
+++ b/src/VBox/Installer/linux/sh-utils.sh
@@ -1,4 +1,4 @@
-# $Id: sh-utils.sh $
+# $Id: sh-utils.sh 36779 2011-04-20 20:55:49Z vboxsync $
# Shell script include file
## @file
# Shell script routines which are likely to be useful for different scripts
diff --git a/src/VBox/Installer/linux/testcase/Makefile.kmk b/src/VBox/Installer/linux/testcase/Makefile.kmk
new file mode 100644
index 000000000..7a3b295db
--- /dev/null
+++ b/src/VBox/Installer/linux/testcase/Makefile.kmk
@@ -0,0 +1,40 @@
+# $Id: Makefile.kmk 38001 2011-07-18 10:16:11Z vboxsync $
+## @file
+# Sub-Makefile for the VBox Linux installer testcase.
+#
+
+#
+# Copyright (C) 2006-2011 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+SUB_DEPTH = ../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+INSTALLS += tstInstallerLinux
+TESTING += tstInstallerLinux
+tstInstallerLinux_INST = $(INST_TESTCASE)
+tstInstallerLinux_MODE = a+rx,u+w
+tstInstallerLinux_SOURCES = $(tstInstallerLinux_0_OUTDIR)/tstInstallerLinux.sh
+tstInstallerLinux_CLEAN = $(tstInstallerLinux_0_OUTDIR)/tstInstallerLinux.sh
+
+$$(tstInstallerLinux_0_OUTDIR)/tstInstallerLinux.sh: \
+ $(PATH_SUB_CURRENT)/tstInstallerLinux.sh \
+ $(PATH_SUB_CURRENT)/../installer-utils.sh \
+ | $$(dir $$@)
+ $(QUIET)$(SED) \
+ -e '/#include installer-utils.sh/ {' \
+ -e "r $(PATH_ROOT)/src/VBox/Installer/linux/installer-utils.sh" \
+ -e 'd' \
+ -e '}' \
+ --output $@ \
+ $<
+
+include $(KBUILD_PATH)/subfooter.kmk
diff --git a/src/VBox/Installer/linux/testcase/tstInstaller.sh b/src/VBox/Installer/linux/testcase/tstInstaller.sh
new file mode 100644
index 000000000..094321e08
--- /dev/null
+++ b/src/VBox/Installer/linux/testcase/tstInstaller.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# Oracle VM VirtualBox
+# VirtualBox linux installation script unit test
+
+#
+# Copyright (C) 2007-2011 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+#include installer-utils.sh
+
+echo Testing udev rule generation
+
+setup_test_install_udev
+
+TEST_UDEV_VERSION=55
+
+udev_55_rules=`cat <<UDEV_END
+KERNEL=="vboxdrv", NAME="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660"
+SUBSYSTEM=="usb_device", ACTION=="add", RUN="/opt/VirtualBox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
+SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN="/opt/VirtualBox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
+SUBSYSTEM=="usb_device", ACTION=="remove", RUN="/opt/VirtualBox/VBoxCreateUSBNode.sh --remove $major $minor"
+SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN="/opt/VirtualBox/VBoxCreateUSBNode.sh --remove $major $minor"
+UDEV_END
+
+install_udev_output="`install_udev_run`"
+case "$install_udev_output" in
+ "$udev_55_rules") ;;
+ *)
+ echo "Bad output for udev version 55. Expected:"
+ echo "$udev_55_rules"
+ echo "Actual:"
+ echo "$install_udev_output"
+ ;;
+esac
+
+TEST_UDEV_VERSION=54
+
+udev_54_rules=`cat <<UDEV_END
+KERNEL="vboxdrv", NAME="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660"
+SUBSYSTEM="usb_device", ACTION="add", RUN="/opt/VirtualBox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
+SUBSYSTEM="usb", ACTION="add", ENV{DEVTYPE}="usb_device", RUN="/opt/VirtualBox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
+SUBSYSTEM="usb_device", ACTION="remove", RUN="/opt/VirtualBox/VBoxCreateUSBNode.sh --remove $major $minor"
+SUBSYSTEM="usb", ACTION="remove", ENV{DEVTYPE}="usb_device", RUN="/opt/VirtualBox/VBoxCreateUSBNode.sh --remove $major $minor"
+UDEV_END
+
+install_udev_output="`install_udev_run`"
+case "$install_udev_output" in
+ "$udev_54_rules") ;;
+ *)
+ echo "Bad output for udev version 54. Expected:"
+ echo "$udev_54_rules"
+ echo "Actual:"
+ echo "$install_udev_output"
+ ;;
+esac
+
+echo Done.
diff --git a/src/VBox/Installer/linux/testcase/tstInstallerLinux.sh b/src/VBox/Installer/linux/testcase/tstInstallerLinux.sh
new file mode 100644
index 000000000..cd20491d6
--- /dev/null
+++ b/src/VBox/Installer/linux/testcase/tstInstallerLinux.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+#
+# Oracle VM VirtualBox
+# VirtualBox linux installation script unit test
+
+#
+# Copyright (C) 2007-2011 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+#include installer-utils.sh
+
+CERRS=0
+
+echo "Testing udev rule generation"
+
+setup_test_input_install_udev ".run, udev-59" 59
+
+udev_59_rules=`cat <<'UDEV_END'
+KERNEL=="vboxdrv", NAME="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660"
+SUBSYSTEM=="usb_device", ACTION=="add", RUN+="/opt/VirtualBox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
+SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/opt/VirtualBox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
+SUBSYSTEM=="usb_device", ACTION=="remove", RUN+="/opt/VirtualBox/VBoxCreateUSBNode.sh --remove $major $minor"
+SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="/opt/VirtualBox/VBoxCreateUSBNode.sh --remove $major $minor"
+UDEV_END`
+
+install_udev_output="`install_udev vboxusers 0660 /opt/VirtualBox`"
+case "$install_udev_output" in
+ "$udev_59_rules") ;;
+ *)
+ echo "Bad output for udev version 59. Expected:"
+ echo "$udev_59_rules"
+ echo "Actual:"
+ echo "$install_udev_output"
+ CERRS="`expr "$CERRS" + 1`"
+ ;;
+esac
+
+cleanup_test_input_install_udev
+
+setup_test_input_install_udev ".run, udev-55" 55
+
+udev_55_rules=`cat <<'UDEV_END'
+KERNEL=="vboxdrv", NAME="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660"
+UDEV_END`
+
+install_udev_output="`install_udev vboxusers 0660 /opt/VirtualBox`"
+case "$install_udev_output" in
+ "$udev_55_rules") ;;
+ *)
+ echo "Bad output for udev version 55. Expected:"
+ echo "$udev_55_rules"
+ echo "Actual:"
+ echo "$install_udev_output"
+ CERRS="`expr "$CERRS" + 1`"
+ ;;
+esac
+
+cleanup_test_input_install_udev
+
+setup_test_input_install_udev ".run, udev-54" 54
+
+udev_54_rules=`cat <<'UDEV_END'
+KERNEL="vboxdrv", NAME="vboxdrv", OWNER="root", GROUP="root", MODE="0600"
+UDEV_END`
+
+install_udev_output="`install_udev root 0600 /usr/lib/virtualbox`"
+case "$install_udev_output" in
+ "$udev_54_rules") ;;
+ *)
+ echo "Bad output for udev version 54. Expected:"
+ echo "$udev_54_rules"
+ echo "Actual:"
+ echo "$install_udev_output"
+ CERRS="`expr "$CERRS" + 1`"
+ ;;
+esac
+
+cleanup_test_input_install_udev
+
+echo "Done. Error count $CERRS."
diff --git a/src/VBox/Installer/linux/uninstall.sh b/src/VBox/Installer/linux/uninstall.sh
index 4ec1241af..4ec1241af 100755..100644
--- a/src/VBox/Installer/linux/uninstall.sh
+++ b/src/VBox/Installer/linux/uninstall.sh
diff --git a/src/VBox/Installer/linux/vboxballoonctrl-service.sh.in b/src/VBox/Installer/linux/vboxballoonctrl-service.sh.in
index 488fd238f..488fd238f 100755..100644
--- a/src/VBox/Installer/linux/vboxballoonctrl-service.sh.in
+++ b/src/VBox/Installer/linux/vboxballoonctrl-service.sh.in
diff --git a/src/VBox/Installer/linux/vboxdrv.sh.in b/src/VBox/Installer/linux/vboxdrv.sh.in
index a80746544..cdec04d84 100755..100644
--- a/src/VBox/Installer/linux/vboxdrv.sh.in
+++ b/src/VBox/Installer/linux/vboxdrv.sh.in
@@ -46,12 +46,14 @@ if [ -n "$INSTALL_DIR" ]; then
BUILDVBOXDRV="$INSTALL_DIR/src/vboxhost/vboxdrv/build_in_tmp"
BUILDVBOXNETFLT="$INSTALL_DIR/src/vboxhost/vboxnetflt/build_in_tmp"
BUILDVBOXNETADP="$INSTALL_DIR/src/vboxhost/vboxnetadp/build_in_tmp"
+ BUILDVBOXPCI="$INSTALL_DIR/src/vboxhost/vboxpci/build_in_tmp"
else
VBOXMANAGE="/usr/lib/%PACKAGE%/VBoxManage"
DODKMS="/usr/share/%PACKAGE%/src/vboxhost/do_dkms"
BUILDVBOXDRV="/usr/share/%PACKAGE%/src/vboxhost/vboxdrv/build_in_tmp"
BUILDVBOXNETFLT="/usr/share/%PACKAGE%/src/vboxhost/vboxnetflt/build_in_tmp"
BUILDVBOXNETADP="/usr/share/%PACKAGE%/src/vboxhost/vboxnetadp/build_in_tmp"
+ BUILDVBOXPCI="/usr/share/%PACKAGE%/src/vboxhost/vboxpci/build_in_tmp"
fi
# silently exit if the package was uninstalled but not purged,
@@ -194,6 +196,7 @@ start()
fi
# ensure permissions
if ! chown :%GROUP% $DEVICE 2>/dev/null; then
+ rmmod vboxpci 2>/dev/null
rmmod vboxnetadp 2>/dev/null
rmmod vboxnetflt 2>/dev/null
rmmod vboxdrv 2>/dev/null
@@ -205,6 +208,9 @@ start()
if ! $MODPROBE vboxnetadp > /dev/null 2>&1; then
failure "modprobe vboxnetadp failed. Please use 'dmesg' to find out why"
fi
+ if ! $MODPROBE vboxpci > /dev/null 2>&1; then
+ failure "modprobe vboxpci failed. Please use 'dmesg' to find out why"
+ fi
# Create the /dev/vboxusb directory if the host supports that method
# of USB access. The USB code checks for the existance of that path.
if grep -q usb_device /proc/devices; then
@@ -217,6 +223,11 @@ start()
stop()
{
begin_msg "Stopping VirtualBox kernel modules"
+ if running vboxpci; then
+ if ! rmmod vboxpci 2>/dev/null; then
+ failure "Cannot unload module vboxpci"
+ fi
+ fi
if running vboxnetadp; then
if ! rmmod vboxnetadp 2>/dev/null; then
failure "Cannot unload module vboxnetadp"
@@ -292,6 +303,11 @@ setup()
begin_msg "Uninstalling old VirtualBox DKMS kernel modules"
$DODKMS uninstall > $LOG
succ_msg
+ if find /lib/modules/`uname -r` -name "vboxpci\.*" 2>/dev/null|grep -q vboxpci; then
+ begin_msg "Removing old VirtualBox pci kernel module"
+ find /lib/modules/`uname -r` -name "vboxpci\.*" 2>/dev/null|xargs rm -f 2>/dev/null
+ succ_msg
+ fi
if find /lib/modules/`uname -r` -name "vboxnetadp\.*" 2>/dev/null|grep -q vboxnetadp; then
begin_msg "Removing old VirtualBox netadp kernel module"
find /lib/modules/`uname -r` -name "vboxnetadp\.*" 2>/dev/null|xargs rm -f 2>/dev/null
@@ -326,6 +342,11 @@ setup()
--no-print-directory install >> $LOG 2>&1; then
failure "Look at $LOG to find out what went wrong"
fi
+ if ! $BUILDVBOXPCI \
+ --use-module-symvers /tmp/vboxdrv-Module.symvers \
+ --no-print-directory install >> $LOG 2>&1; then
+ failure "Look at $LOG to find out what went wrong"
+ fi
fi
rm -f /etc/vbox/module_not_compiled
succ_msg
@@ -335,15 +356,17 @@ setup()
dmnstatus()
{
if running vboxdrv; then
+ str="vboxdrv"
if running vboxnetflt; then
+ str="$str, vboxnetflt"
if running vboxnetadp; then
- echo "VirtualBox kernel modules (vboxdrv, vboxnetflt and vboxnetadp) are loaded."
- else
- echo "VirtualBox kernel modules (vboxdrv and vboxnetflt) are loaded."
+ str="$str, vboxnetadp"
fi
- else
- echo "VirtualBox kernel module is loaded."
fi
+ if running vboxpci; then
+ str="$str, vboxpci"
+ fi
+ echo "VirtualBox kernel modules ($str) are loaded."
for i in $SHUTDOWN_USERS; do
# don't create the ipcd directory with wrong permissions!
if [ -d /tmp/.vbox-$i-ipc ]; then
diff --git a/src/VBox/Installer/linux/vboxweb-service.sh.in b/src/VBox/Installer/linux/vboxweb-service.sh.in
index dfd9605eb..dfd9605eb 100755..100644
--- a/src/VBox/Installer/linux/vboxweb-service.sh.in
+++ b/src/VBox/Installer/linux/vboxweb-service.sh.in
diff --git a/src/VBox/Installer/solaris/Makefile.kmk b/src/VBox/Installer/solaris/Makefile.kmk
index 5dc319e91..0ba257e2f 100644
--- a/src/VBox/Installer/solaris/Makefile.kmk
+++ b/src/VBox/Installer/solaris/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37549 2011-06-20 08:44:19Z vboxsync $
## @file
# Sub-Makefile for the Solaris installer.
#
@@ -165,6 +165,7 @@ solaris-drv-confs_MODE = a+r,u+w
solaris-drv-confs_SOURCES = \
$(PATH_ROOT)/src/VBox/HostDrivers/Support/solaris/vboxdrv.conf \
$(if $(VBOX_WITH_NETFLT),$(PATH_ROOT)/src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxflt.conf) \
+ $(if $(VBOX_WITH_NETFLT_CROSSBOW),$(PATH_ROOT)/src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxbow.conf) \
$(if $(VBOX_WITH_NETADP),$(PATH_ROOT)/src/VBox/HostDrivers/VBoxNetAdp/solaris/vboxnet.conf) \
$(if $(VBOX_WITH_USB),$(PATH_ROOT)/src/VBox/HostDrivers/VBoxUSB/solaris/vboxusbmon.conf) \
$(if $(VBOX_WITH_USB),$(PATH_ROOT)/src/VBox/HostDrivers/VBoxUSB/solaris/vboxusb.conf)
@@ -183,12 +184,12 @@ BLDDIRS += \
VBOX_MIME_ICONS = \
$(addprefix $(PATH_ROOT)/src/VBox/Resources/other/,\
- $(foreach f,ova ovf vbox vbox-extpack, \
+ $(foreach f,ova ovf vbox vbox-extpack vdi vmdk vhd hdd, \
$(foreach s,16 20 24 32 48 64 72 96 128 256,\
virtualbox-$(f)-$(s)px.png=>$(s)x$(s)/mimetypes/virtualbox-$(f).png)))
SOLARIS_COMMON_ICONS = \
- $(foreach f,ova ovf vbox vbox-extpack, \
+ $(foreach f,ova ovf vbox vbox-extpack vdi vmdk vhd hdd, \
$(foreach s,16 20 24 32 48 64 72 96 128 256,\
$(s)x$(s)/mimetypes/virtualbox-$(f).png))
@@ -217,6 +218,7 @@ SOLARIS_STRIP_EXES = \
SOLARIS_DRIVER_BINS = \
vboxdrv \
$(if $(VBOX_WITH_NETFLT),vboxflt,) \
+ $(if $(VBOX_WITH_NETFLT_CROSSBOW),vboxbow,) \
$(if $(VBOX_WITH_NETADP),vboxnet,) \
$(if $(VBOX_WITH_USB),vboxusbmon,) \
$(if $(VBOX_WITH_USB),vboxusb,)
@@ -224,6 +226,7 @@ SOLARIS_DRIVER_BINS = \
SOLARIS_DRIVER_CONFS = \
vboxdrv.conf \
$(if $(VBOX_WITH_NETFLT),vboxflt.conf,) \
+ $(if $(VBOX_WITH_NETFLT_CROSSBOW),vboxbow.conf,) \
$(if $(VBOX_WITH_NETADP),vboxnet.conf,) \
$(if $(VBOX_WITH_USB),vboxusbmon.conf,) \
$(if $(VBOX_WITH_USB),vboxusb.conf,)
@@ -636,7 +639,7 @@ endif
$(PATH_ROOT)/src/VBox/Installer/common/virtualbox.desktop.in
$(QUIET)$(INSTALL) -m 0644 $(SOLARIS_USRSHR_APPS_DIR)/virtualbox.desktop.tmp $(SOLARIS_USRSHR_APPS_DIR)/virtualbox.desktop
$(QUIET)$(RM) -f $(SOLARIS_USRSHR_APPS_DIR)/virtualbox.desktop.tmp
- # S10 cannot deal with icon information in virtrtualbox.xml
+ # S10 cannot deal with icon information in virtualbox.xml
$(QUIET)$(SED) \
-e '/<icon/d' \
--output $(SOLARIS_USRSHR_MIMEXML_DIR)/virtualbox.xml.tmp \
diff --git a/src/VBox/Installer/solaris/VBoxISAExec.c b/src/VBox/Installer/solaris/VBoxISAExec.c
index 97f8ad9fc..db5f341e6 100644
--- a/src/VBox/Installer/solaris/VBoxISAExec.c
+++ b/src/VBox/Installer/solaris/VBoxISAExec.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxISAExec.c $ */
+/* $Id: VBoxISAExec.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxISAExec, ISA exec wrapper, Solaris hosts.
*/
diff --git a/src/VBox/Installer/solaris/VBoxZoneAccess.c b/src/VBox/Installer/solaris/VBoxZoneAccess.c
index a77f32cb4..e8d9174e8 100644
--- a/src/VBox/Installer/solaris/VBoxZoneAccess.c
+++ b/src/VBox/Installer/solaris/VBoxZoneAccess.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxZoneAccess.c $ */
+/* $Id: VBoxZoneAccess.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxZoneAccess - Hack that keeps vboxdrv referenced for granting zone access, Solaris hosts.
*/
diff --git a/src/VBox/Installer/solaris/checkinstall.sh b/src/VBox/Installer/solaris/checkinstall.sh
index 040ce57df..040ce57df 100755..100644
--- a/src/VBox/Installer/solaris/checkinstall.sh
+++ b/src/VBox/Installer/solaris/checkinstall.sh
diff --git a/src/VBox/Installer/solaris/makepackage.sh b/src/VBox/Installer/solaris/makepackage.sh
index 9261f979c..113ad5d3a 100755..100644
--- a/src/VBox/Installer/solaris/makepackage.sh
+++ b/src/VBox/Installer/solaris/makepackage.sh
@@ -162,6 +162,10 @@ filelist_fixup prototype '$3 == "platform/i86pc/kernel/drv/amd64/vboxdrv"'
filelist_fixup prototype '$3 == "platform/i86pc/kernel/drv/vboxflt"' '$6 = "sys"'
filelist_fixup prototype '$3 == "platform/i86pc/kernel/drv/amd64/vboxflt"' '$6 = "sys"'
+# NetFilter vboxbow
+filelist_fixup prototype '$3 == "platform/i86pc/kernel/drv/vboxbow"' '$6 = "sys"'
+filelist_fixup prototype '$3 == "platform/i86pc/kernel/drv/amd64/vboxbow"' '$6 = "sys"'
+
# NetAdapter vboxnet
filelist_fixup prototype '$3 == "platform/i86pc/kernel/drv/vboxnet"' '$6 = "sys"'
filelist_fixup prototype '$3 == "platform/i86pc/kernel/drv/amd64/vboxnet"' '$6 = "sys"'
diff --git a/src/VBox/Installer/solaris/pkginstall.sh b/src/VBox/Installer/solaris/pkginstall.sh
index 49aea0cff..49aea0cff 100755..100644
--- a/src/VBox/Installer/solaris/pkginstall.sh
+++ b/src/VBox/Installer/solaris/pkginstall.sh
diff --git a/src/VBox/Installer/solaris/postinstall.sh b/src/VBox/Installer/solaris/postinstall.sh
index 1dbfa2bde..1dbfa2bde 100755..100644
--- a/src/VBox/Installer/solaris/postinstall.sh
+++ b/src/VBox/Installer/solaris/postinstall.sh
diff --git a/src/VBox/Installer/solaris/preremove.sh b/src/VBox/Installer/solaris/preremove.sh
index a0ab4b528..a0ab4b528 100755..100644
--- a/src/VBox/Installer/solaris/preremove.sh
+++ b/src/VBox/Installer/solaris/preremove.sh
diff --git a/src/VBox/Installer/solaris/smf-vboxballoonctrl.sh b/src/VBox/Installer/solaris/smf-vboxballoonctrl.sh
index 9b4ee5b05..dfcd835cc 100755
--- a/src/VBox/Installer/solaris/smf-vboxballoonctrl.sh
+++ b/src/VBox/Installer/solaris/smf-vboxballoonctrl.sh
@@ -1,5 +1,5 @@
#!/sbin/sh
-# $Id: smf-vboxballoonctrl.sh $
+# $Id: smf-vboxballoonctrl.sh 36748 2011-04-20 11:24:54Z vboxsync $
# Copyright (C) 2008-2011 Oracle Corporation
#
diff --git a/src/VBox/Installer/solaris/smf-vboxwebsrv.sh b/src/VBox/Installer/solaris/smf-vboxwebsrv.sh
index 9a5b57d8f..c03201036 100755
--- a/src/VBox/Installer/solaris/smf-vboxwebsrv.sh
+++ b/src/VBox/Installer/solaris/smf-vboxwebsrv.sh
@@ -1,5 +1,5 @@
#!/sbin/sh
-# $Id: smf-vboxwebsrv.sh $
+# $Id: smf-vboxwebsrv.sh 36748 2011-04-20 11:24:54Z vboxsync $
# Copyright (C) 2008-2011 Oracle Corporation
#
diff --git a/src/VBox/Installer/solaris/vbi/makepackage.sh b/src/VBox/Installer/solaris/vbi/makepackage.sh
index 60689207d..60689207d 100755..100644
--- a/src/VBox/Installer/solaris/vbi/makepackage.sh
+++ b/src/VBox/Installer/solaris/vbi/makepackage.sh
diff --git a/src/VBox/Installer/solaris/vbi/preremove.sh b/src/VBox/Installer/solaris/vbi/preremove.sh
index f1e0b750e..f1e0b750e 100755..100644
--- a/src/VBox/Installer/solaris/vbi/preremove.sh
+++ b/src/VBox/Installer/solaris/vbi/preremove.sh
diff --git a/src/VBox/Installer/solaris/vboxconfig.sh b/src/VBox/Installer/solaris/vboxconfig.sh
index e26875fdd..5da68cf47 100755..100644
--- a/src/VBox/Installer/solaris/vboxconfig.sh
+++ b/src/VBox/Installer/solaris/vboxconfig.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: vboxconfig.sh $
+# $Id: vboxconfig.sh 38016 2011-07-18 13:06:11Z vboxsync $
#
# VirtualBox Configuration Script, Solaris host.
@@ -55,7 +55,10 @@ DESC_VBOXNET="NetAdapter"
MOD_VBOXNET_INST=32
MOD_VBOXFLT=vboxflt
-DESC_VBOXFLT="NetFilter"
+DESC_VBOXFLT="NetFilter (STREAMS)"
+
+MOD_VBOXBOW=vboxbow
+DESC_VBOXBOW="NetFilter (Crossbow)"
# No Separate VBI since (3.1)
#MOD_VBI=vbi
@@ -67,6 +70,7 @@ DESC_VBOXUSBMON="USBMonitor"
MOD_VBOXUSB=vboxusb
DESC_VBOXUSB="USB"
+UPDATEBOOTARCHIVE=0
REMOTEINST=0
FATALOP=fatal
NULLOP=nulloutput
@@ -223,17 +227,17 @@ get_sysinfo()
{
if test "$REMOTEINST" -eq 1 || test -z "$HOST_OS_MINORVERSION" || test -z "$HOST_OS_MAJORVERSION"; then
if test -f "$PKG_INSTALL_ROOT/etc/release"; then
- HOST_OS_MAJORVERSION=`cat $PKG_INSTALL_ROOT/etc/release | grep "Solaris 10"`
+ HOST_OS_MAJORVERSION=`cat "$PKG_INSTALL_ROOT/etc/release" | grep "Solaris 10"`
if test -n "$HOST_OS_MAJORVERSION"; then
HOST_OS_MAJORVERSION="5.10"
else
- HOST_OS_MAJORVERSION=`cat $PKG_INSTALL_ROOT/etc/release | egrep "snv_|oi_"`
+ HOST_OS_MAJORVERSION=`cat "$PKG_INSTALL_ROOT/etc/release" | egrep "snv_|oi_"`
if test -n "$HOST_OS_MAJORVERSION"; then
HOST_OS_MAJORVERSION="5.11"
fi
fi
if test "$HOST_OS_MAJORVERSION" != "5.10"; then
- HOST_OS_MINORVERSION=`cat $PKG_INSTALL_ROOT/etc/release | tr ' ' '\n' | egrep 'snv_|oi_' | sed -e "s/snv_//" -e "s/oi_//" -e "s/[^0-9]//"`
+ HOST_OS_MINORVERSION=`cat "$PKG_INSTALL_ROOT/etc/release" | tr ' ' '\n' | egrep 'snv_|oi_' | sed -e "s/snv_//" -e "s/oi_//" -e "s/[^0-9]//"`
else
HOST_OS_MINORVERSION=""
fi
@@ -277,6 +281,20 @@ check_module_arch()
fi
}
+# update_boot_archive()
+# cannot fail
+update_boot_archive()
+{
+ infoprint "Updating the boot archive..."
+ if test "$REMOTEINST" -eq 0; then
+ $BIN_BOOTADM update-archive > /dev/null
+ else
+ $BIN_BOOTADM update-archive -R "$PKG_INSTALL_ROOT" > /dev/null
+ fi
+ UPDATEBOOTARCHIVE=0
+}
+
+
# module_added(modname)
# returns 1 if added, 0 otherwise
module_added()
@@ -288,7 +306,7 @@ module_added()
# Add a space at end of module name to make sure we have a perfect match to avoid
# any substring matches: e.g "vboxusb" & "vboxusbmon"
- loadentry=`cat $PKG_INSTALL_ROOT/etc/name_to_major | grep "$1 "`
+ loadentry=`cat "$PKG_INSTALL_ROOT/etc/name_to_major" | grep "$1 "`
if test -z "$loadentry"; then
return 1
fi
@@ -369,6 +387,7 @@ rem_driver()
module_added $modname
if test "$?" -eq 0; then
+ UPDATEBOOTARCHIVE=1
if test "$ISIPS" != "$IPSOP"; then
$BIN_REMDRV $BASEDIR_OPT $modname
else
@@ -452,6 +471,28 @@ load_module()
fi
}
+load_vboxflt()
+{
+ if test -f "$DIR_CONF/vboxflt.conf"; then
+ add_driver "$MOD_VBOXFLT" "$DESC_VBOXFLT" "$FATALOP"
+ load_module "drv/$MOD_VBOXFLT" "$DESC_VBOXFLT" "$FATALOP"
+ else
+ # For custom pkgs that optionally ship this module, let's not fail but just warn
+ warnprint "$DESC_VBOXFLT installation requested but not shipped in this package."
+ fi
+}
+
+load_vboxbow()
+{
+ if test -f "$DIR_CONF/vboxbow.conf"; then
+ add_driver "$MOD_VBOXBOW" "$DESC_VBOXBOW" "$FATALOP"
+ load_module "drv/$MOD_VBOXBOW" "$DESC_VBOXBOW" "$FATALOP"
+ else
+ # For custom pkgs that optionally ship this module, let's not fail but just warn
+ warnprint "$DESC_VBOXBOW installation requested but not shipped in this package."
+ fi
+}
+
# install_drivers()
# !! failure is always fatal
install_drivers()
@@ -470,9 +511,9 @@ install_drivers()
# Add vboxdrv to devlink.tab
if test -f "$PKG_INSTALL_ROOT/etc/devlink.tab"; then
- sed -e '/name=vboxdrv/d' $PKG_INSTALL_ROOT/etc/devlink.tab > $PKG_INSTALL_ROOT/etc/devlink.vbox
- echo "type=ddi_pseudo;name=vboxdrv \D" >> $PKG_INSTALL_ROOT/etc/devlink.vbox
- mv -f $PKG_INSTALL_ROOT/etc/devlink.vbox $PKG_INSTALL_ROOT/etc/devlink.tab
+ sed -e '/name=vboxdrv/d' "$PKG_INSTALL_ROOT/etc/devlink.tab" > "$PKG_INSTALL_ROOT/etc/devlink.vbox"
+ echo "type=ddi_pseudo;name=vboxdrv \D" >> "$PKG_INSTALL_ROOT/etc/devlink.vbox"
+ mv -f "$PKG_INSTALL_ROOT/etc/devlink.vbox" "$PKG_INSTALL_ROOT/etc/devlink.tab"
else
errorprint "Missing $PKG_INSTALL_ROOT/etc/devlink.tab, aborting install"
return 1
@@ -493,23 +534,46 @@ install_drivers()
load_module "drv/$MOD_VBOXNET" "$DESC_VBOXNET" "$FATALOP"
fi
- # Load VBoxNetFlt
- if test -f "$DIR_CONF/vboxflt.conf"; then
- add_driver "$MOD_VBOXFLT" "$DESC_VBOXFLT" "$FATALOP"
- load_module "drv/$MOD_VBOXFLT" "$DESC_VBOXFLT" "$FATALOP"
+ # If both vboxinst_vboxbow and vboxinst_vboxflt exist, bail.
+ if test -f "$PKG_INSTALL_ROOT/etc/vboxinst_vboxflt" && test -f "$PKG_INSTALL_ROOT/etc/vboxinst_vboxbow"; then
+ errorprint "Force-install files '$PKG_INSTALL_ROOT/etc/vboxinst_vboxflt' and '$PKG_INSTALL_ROOT/etc/vboxinst_vboxbow' both exist."
+ errorprint "Cannot load $DESC_VBOXFLT and $DESC_VBOXBOW drivers at the same time."
+ return 1
+ fi
+
+ # If the force-install files exists, install blindly
+ if test -f "$PKG_INSTALL_ROOT/etc/vboxinst_vboxflt"; then
+ load_vboxflt
+ elif test -f "$PKG_INSTALL_ROOT/etc/vboxinst_vboxbow"; then
+ infoprint "here"
+ load_vboxbow
+ else
+ # If host is S10 or S11 (< snv_159) or vboxbow isn't shipped, then load vboxflt
+ if test "$HOST_OS_MAJORVERSION" = "5.10" || test "$HOST_OS_MINORVERSION" -lt 159 || test ! -f "$DIR_CONF/vboxbow.conf"; then
+ load_vboxflt
+ else
+ # For S11 snv_159+ load vboxbow
+ load_vboxbow
+ fi
fi
# Load VBoxUSBMon, VBoxUSB
if test -f "$DIR_CONF/vboxusbmon.conf" && test "$HOST_OS_MAJORVERSION" != "5.10"; then
# For VirtualBox 3.1 the new USB code requires Nevada > 123
if test "$HOST_OS_MINORVERSION" -gt 123; then
+ # Add a group "vboxuser" (8-character limit) for USB access.
+ # All users which need host USB-passthrough support will have to be added to this group.
+ groupadd vboxuser >/dev/null 2>&1
+
add_driver "$MOD_VBOXUSBMON" "$DESC_VBOXUSBMON" "$FATALOP" "not-$NULLOP" "'* 0666 root sys'"
load_module "drv/$MOD_VBOXUSBMON" "$DESC_VBOXUSBMON" "$FATALOP"
+ chown root:vboxuser "/devices/pseudo/vboxusbmon@0:vboxusbmon"
+
# Add vboxusbmon to devlink.tab
- sed -e '/name=vboxusbmon/d' $PKG_INSTALL_ROOT/etc/devlink.tab > $PKG_INSTALL_ROOT/etc/devlink.vbox
- echo "type=ddi_pseudo;name=vboxusbmon \D" >> $PKG_INSTALL_ROOT/etc/devlink.vbox
- mv -f $PKG_INSTALL_ROOT/etc/devlink.vbox $PKG_INSTALL_ROOT/etc/devlink.tab
+ sed -e '/name=vboxusbmon/d' "$PKG_INSTALL_ROOT/etc/devlink.tab" > "$PKG_INSTALL_ROOT/etc/devlink.vbox"
+ echo "type=ddi_pseudo;name=vboxusbmon \D" >> "$PKG_INSTALL_ROOT/etc/devlink.vbox"
+ mv -f "$PKG_INSTALL_ROOT/etc/devlink.vbox" "$PKG_INSTALL_ROOT/etc/devlink.tab"
# Create the device link for non-remote installs
if test "$REMOTEINST" -eq 0; then
@@ -547,18 +611,18 @@ remove_drivers()
fatal=$1
# Remove vboxdrv from devlink.tab
- if test -f $PKG_INSTALL_ROOT/etc/devlink.tab; then
- devlinkfound=`cat $PKG_INSTALL_ROOT/etc/devlink.tab | grep vboxdrv`
+ if test -f "$PKG_INSTALL_ROOT/etc/devlink.tab"; then
+ devlinkfound=`cat "$PKG_INSTALL_ROOT/etc/devlink.tab" | grep vboxdrv`
if test -n "$devlinkfound"; then
- sed -e '/name=vboxdrv/d' $PKG_INSTALL_ROOT/etc/devlink.tab > $PKG_INSTALL_ROOT/etc/devlink.vbox
- mv -f $PKG_INSTALL_ROOT/etc/devlink.vbox $PKG_INSTALL_ROOT/etc/devlink.tab
+ sed -e '/name=vboxdrv/d' "$PKG_INSTALL_ROOT/etc/devlink.tab" > "$PKG_INSTALL_ROOT/etc/devlink.vbox"
+ mv -f "$PKG_INSTALL_ROOT/etc/devlink.vbox" "$PKG_INSTALL_ROOT/etc/devlink.tab"
fi
# Remove vboxusbmon from devlink.tab
- devlinkfound=`cat $PKG_INSTALL_ROOT/etc/devlink.tab | grep vboxusbmon`
+ devlinkfound=`cat "$PKG_INSTALL_ROOT/etc/devlink.tab" | grep vboxusbmon`
if test -n "$devlinkfound"; then
- sed -e '/name=vboxusbmon/d' $PKG_INSTALL_ROOT/etc/devlink.tab > $PKG_INSTALL_ROOT/etc/devlink.vbox
- mv -f $PKG_INSTALL_ROOT/etc/devlink.vbox $PKG_INSTALL_ROOT/etc/devlink.tab
+ sed -e '/name=vboxusbmon/d' "$PKG_INSTALL_ROOT/etc/devlink.tab" > "$PKG_INSTALL_ROOT/etc/devlink.vbox"
+ mv -f "$PKG_INSTALL_ROOT/etc/devlink.vbox" "$PKG_INSTALL_ROOT/etc/devlink.tab"
fi
fi
@@ -571,6 +635,9 @@ remove_drivers()
unload_module "$MOD_VBOXFLT" "$DESC_VBOXFLT" "$fatal"
rem_driver "$MOD_VBOXFLT" "$DESC_VBOXFLT" "$fatal"
+ unload_module "$MOD_VBOXBOW" "$DESC_VBOXBOW" "$fatal"
+ rem_driver "$MOD_VBOXBOW" "$DESC_VBOXBOW" "$fatal"
+
unload_module "$MOD_VBOXNET" "$DESC_VBOXNET" "$fatal"
rem_driver "$MOD_VBOXNET" "$DESC_VBOXNET" "$fatal"
@@ -582,14 +649,14 @@ remove_drivers()
# remove devlinks
if test -h "$PKG_INSTALL_ROOT/dev/vboxdrv" || test -f "$PKG_INSTALL_ROOT/dev/vboxdrv"; then
- rm -f $PKG_INSTALL_ROOT/dev/vboxdrv
+ rm -f "$PKG_INSTALL_ROOT/dev/vboxdrv"
fi
if test -h "$PKG_INSTALL_ROOT/dev/vboxusbmon" || test -f "$PKG_INSTALL_ROOT/dev/vboxusbmon"; then
- rm -f $PKG_INSTALL_ROOT/dev/vboxusbmon
+ rm -f "$PKG_INSTALL_ROOT/dev/vboxusbmon"
fi
# unpatch nwam/dhcpagent fix
- nwamfile=$PKG_INSTALL_ROOT/etc/nwam/llp
+ nwamfile="$PKG_INSTALL_ROOT/etc/nwam/llp"
nwambackupfile=$nwamfile.vbox
if test -f "$nwamfile"; then
sed -e '/vboxnet/d' $nwamfile > $nwambackupfile
@@ -597,13 +664,21 @@ remove_drivers()
fi
# remove netmask configuration
- nmaskfile=$PKG_INSTALL_ROOT/etc/netmasks
+ if test -h "$PKG_INSTALL_ROOT/etc/netmasks"; then
+ nmaskfile="$PKG_INSTALL_ROOT/etc/inet/netmasks"
+ else
+ nmaskfile="$PKG_INSTALL_ROOT/etc/netmasks"
+ fi
nmaskbackupfile=$nmaskfile.vbox
if test -f "$nmaskfile"; then
sed -e '/#VirtualBox_SectionStart/,/#VirtualBox_SectionEnd/d' $nmaskfile > $nmaskbackupfile
mv -f $nmaskbackupfile $nmaskfile
fi
+ if test $UPDATEBOOTARCHIVE -eq 1; then
+ update_boot_archive
+ fi
+
return 0
}
@@ -664,57 +739,44 @@ stop_process()
}
-# cleanup_install([fatal])
-# failure: depends on [fatal]
-cleanup_install()
+# stop_service(servicename, shortFMRI-suitable for grep, full FMRI)
+# failure: non fatal
+stop_service()
{
- fatal=$1
-
- # No-Op for remote installs
- if test "$REMOTEINST" -eq 1; then
- return 0
+ if test -z "$1" || test -z "$2" || test -z "$3"; then
+ errorprint "missing argument to stop_service()"
+ exit 1
fi
-
- # stop webservice
- servicefound=`$BIN_SVCS -a | grep "virtualbox/webservice" 2>/dev/null`
+ servicefound=`$BIN_SVCS -a | grep "$2" 2>/dev/null`
if test ! -z "$servicefound"; then
- $BIN_SVCADM disable -s svc:/application/virtualbox/webservice:default
+ $BIN_SVCADM disable -s $3
# Don't delete the manifest, this is handled by the manifest class action
- # $BIN_SVCCFG delete svc:/application/virtualbox/webservice:default
+ # $BIN_SVCCFG delete $3
if test "$?" -eq 0; then
- subprint "Unloaded: Web service"
+ subprint "Unloaded: $1"
else
- subprint "Unloading: Web service ...ERROR(S)."
+ subprint "Unloading: $1 ...ERROR(S)."
fi
fi
+}
- # stop balloonctrl
- servicefound=`$BIN_SVCS -a | grep "virtualbox/balloonctrl" 2>/dev/null`
- if test ! -z "$servicefound"; then
- $BIN_SVCADM disable -s svc:/application/virtualbox/balloonctrl:default
- # Don't delete the manifest, this is handled by the manifest class action
- # $BIN_SVCCFG delete svc:/application/virtualbox/balloonctrl:default
- if test "$?" -eq 0; then
- subprint "Unloaded: Balloon control service"
- else
- subprint "Unloading: Balloon control service ...ERROR(S)."
- fi
- fi
+# cleanup_install([fatal])
+# failure: depends on [fatal]
+cleanup_install()
+{
+ fatal=$1
- # stop zoneaccess service
- servicefound=`$BIN_SVCS -a | grep "virtualbox/zoneaccess" 2>/dev/null`
- if test ! -z "$servicefound"; then
- $BIN_SVCADM disable -s svc:/application/virtualbox/zoneaccess:default
- # Don't delete the manifest, this is handled by the manifest class action
- # $BIN_SVCCFG delete svc:/application/virtualbox/zoneaccess
- if test "$?" -eq 0; then
- subprint "Unloaded: Zone access service"
- else
- subprint "Unloading: Zone access service ...ERROR(S)."
- fi
+ # No-Op for remote installs
+ if test "$REMOTEINST" -eq 1; then
+ return 0
fi
+ # stop the services
+ stop_service "Web service" "virtualbox/webservice" "svc:/application/virtualbox/webservice:default"
+ stop_service "Balloon control service" "virtualbox/balloonctrl" "svc:/application/virtualbox/balloonctrl:default"
+ stop_service "Zone access service" "virtualbox/zoneaccess" "svc:/application/virtualbox/zoneaccess:default"
+
# unplumb all vboxnet instances for non-remote installs
inst=0
while test $inst -ne $MOD_VBOXNET_INST; do
@@ -754,14 +816,14 @@ cleanup_install()
# !! failure is always fatal
postinstall()
{
- infoprint "Detected Solaris $HOST_OS_MAJORVERSION Version $HOST_OS_MINORVERSION"
+ infoprint "Detected Solaris $HOST_OS_MAJORVERSION Version $HOST_OS_MINORVERSION"
infoprint "Loading VirtualBox kernel modules..."
install_drivers
if test "$?" -eq 0; then
if test -f "$DIR_CONF/vboxnet.conf"; then
# nwam/dhcpagent fix
- nwamfile=$PKG_INSTALL_ROOT/etc/nwam/llp
+ nwamfile="$PKG_INSTALL_ROOT/etc/nwam/llp"
nwambackupfile=$nwamfile.vbox
if test -f "$nwamfile"; then
sed -e '/vboxnet/d' $nwamfile > $nwambackupfile
@@ -779,15 +841,35 @@ postinstall()
# plumb and configure vboxnet0 for non-remote installs
if test "$REMOTEINST" -eq 0; then
- $BIN_IFCONFIG vboxnet0 plumb up
+ $BIN_IFCONFIG vboxnet0 plumb
+ $BIN_IFCONFIG vboxnet0 up
if test "$?" -eq 0; then
$BIN_IFCONFIG vboxnet0 192.168.56.1 netmask 255.255.255.0 up
+ # /etc/netmasks is a symlink, older installers replaced this with
+ # a copy of the actual file, repair that behaviour here.
+ recreatelink=0
+ if test -h "$PKG_INSTALL_ROOT/etc/netmasks"; then
+ nmaskfile="$PKG_INSTALL_ROOT/etc/inet/netmasks"
+ else
+ nmaskfile="$PKG_INSTALL_ROOT/etc/netmasks"
+ recreatelink=1
+ fi
+
# add the netmask to stay persistent across host reboots
- nmaskfile=$PKG_INSTALL_ROOT/etc/netmasks
nmaskbackupfile=$nmaskfile.vbox
if test -f $nmaskfile; then
sed -e '/#VirtualBox_SectionStart/,/#VirtualBox_SectionEnd/d' $nmaskfile > $nmaskbackupfile
+
+ if test $recreatelink -eq 1; then
+ # Check after removing our settings if /etc/netmasks is identifcal to /etc/inet/netmasks
+ anydiff=`diff $nmaskbackupfile "$PKG_INSTALL_ROOT/etc/inet/netmasks"`
+ if test ! -z "$anydiff"; then
+ # User may have some custom settings in /etc/netmasks, don't overwrite /etc/netmasks!
+ recreatelink=2
+ fi
+ fi
+
echo "#VirtualBox_SectionStart" >> $nmaskbackupfile
inst=0
networkn=56
@@ -798,6 +880,18 @@ postinstall()
done
echo "#VirtualBox_SectionEnd" >> $nmaskbackupfile
mv -f $nmaskbackupfile $nmaskfile
+
+ # Recreate /etc/netmasks as a link if necessary
+ if test $recreatelink -eq 1; then
+ cp -f "$PKG_INSTALL_ROOT/etc/netmasks" "$PKG_INSTALL_ROOT/etc/inet/netmasks"
+ ln -sf ./inet/netmasks "$PKG_INSTALL_ROOT/etc/netmasks"
+ elif test $recreatelink -eq 2; then
+ warnprint "/etc/netmasks is a symlink (to /etc/inet/netmasks) that older"
+ warnprint "VirtualBox installers incorrectly overwrote. Now the contents"
+ warnprint "of /etc/netmasks and /etc/inet/netmasks differ, therefore "
+ warnprint "VirtualBox will not attempt to overwrite /etc/netmasks as a"
+ warnprint "symlink to /etc/inet/netmasks. Please resolve this manually."
+ fi
fi
else
# Should this be fatal?
@@ -806,22 +900,20 @@ postinstall()
fi
fi
- if test -f $PKG_INSTALL_ROOT/var/svc/manifest/application/virtualbox/virtualbox-webservice.xml || test -f $PKG_INSTALL_ROOT/var/svc/manifest/application/virtualbox/virtualbox-zoneaccess.xml; then
+ if test -f "$PKG_INSTALL_ROOT/var/svc/manifest/application/virtualbox/virtualbox-webservice.xml" || test -f "$PKG_INSTALL_ROOT/var/svc/manifest/application/virtualbox/virtualbox-zoneaccess.xml"; then
infoprint "Configuring services..."
if test "$REMOTEINST" -eq 1; then
subprint "Skipped for targetted installs."
- fi
- fi
-
- # Enable Zone access service for non-remote installs, other services (Webservice) are delivered disabled by the manifest class action
- if test "$REMOTEINST" -eq 0; then
- servicefound=`$BIN_SVCS -a | grep "virtualbox/zoneaccess" | grep "disabled" 2>/dev/null`
- if test ! -z "$servicefound"; then
- /usr/sbin/svcadm enable -s svc:/application/virtualbox/zoneaccess
- if test "$?" -eq 0; then
- subprint "Loaded: Zone access service"
- else
- subprint "Loading Zone access service ...FAILED."
+ else
+ # Enable Zone access service for non-remote installs, other services (Webservice) are delivered disabled by the manifest class action
+ servicefound=`$BIN_SVCS -a | grep "virtualbox/zoneaccess" | grep "disabled" 2>/dev/null`
+ if test ! -z "$servicefound"; then
+ /usr/sbin/svcadm enable -s svc:/application/virtualbox/zoneaccess
+ if test "$?" -eq 0; then
+ subprint "Loaded: Zone access service"
+ else
+ subprint "Loading Zone access service ...FAILED."
+ fi
fi
fi
fi
@@ -829,8 +921,8 @@ postinstall()
# Update mime and desktop databases to get the right menu entries
# and icons. There is still some delay until the GUI picks it up,
# but that cannot be helped.
- if test -d $PKG_INSTALL_ROOT/usr/share/icons; then
- infoprint "Installing MIME types and icons"
+ if test -d "$PKG_INSTALL_ROOT/usr/share/icons"; then
+ infoprint "Installing MIME types and icons..."
if test "$REMOTEINST" -eq 0; then
/usr/bin/update-mime-database /usr/share/mime >/dev/null 2>&1
/usr/bin/update-desktop-database -q 2>/dev/null
@@ -878,14 +970,8 @@ postinstall()
warnprint "Skipped installing Python bindings. Run, as root, 'vboxapisetup.py install' manually from the booted system."
fi
- # Update boot archive
- infoprint "Updating the boot archive..."
- if test "$REMOTEINST" -eq 0; then
- $BIN_BOOTADM update-archive > /dev/null
- else
- $BIN_BOOTADM update-archive -R $PKG_INSTALL_ROOT > /dev/null
- fi
-
+ update_boot_archive
+
return 0
else
errorprint "Failed to install drivers"
@@ -971,6 +1057,7 @@ case "$drvop" in
;;
--setupdrivers)
remove_drivers "$fatal"
+ infoprint "Installing VirtualBox drivers:"
install_drivers
;;
*)
diff --git a/src/VBox/Installer/solaris/virtualbox.applications.in b/src/VBox/Installer/solaris/virtualbox.applications.in
index 054b0da2b..601d274c7 100644
--- a/src/VBox/Installer/solaris/virtualbox.applications.in
+++ b/src/VBox/Installer/solaris/virtualbox.applications.in
@@ -4,5 +4,5 @@ virtualbox
expects_uris=false
can_open_multiple_files=true
name=@VBOX_PRODUCT@
- mime_types=application/x-virtualbox-vbox;application/x-virtualbox-vbox-extpack;application/x-virtualbox-ovf;application/x-virtualbox-ova
+ mime_types=application/x-virtualbox-vbox;application/x-virtualbox-vbox-extpack;application/x-virtualbox-ovf;application/x-virtualbox-ova;application/x-virtualbox-vdi;application/x-virtualbox-vmdk;application/x-virtualbox-vhd;application/x-virtualbox-hdd
diff --git a/src/VBox/Installer/solaris/virtualbox.keys b/src/VBox/Installer/solaris/virtualbox.keys
index 37fb93c23..65ddd53e8 100644
--- a/src/VBox/Installer/solaris/virtualbox.keys
+++ b/src/VBox/Installer/solaris/virtualbox.keys
@@ -38,3 +38,42 @@ application/x-virtualbox-ovf
category=System
use_category_default=no
+application/x-virtualbox-vdi
+ icon_filename=virtualbox-vdi
+ description=Virtual Disk Image
+ default_action_type=none
+ short_list_application_ids_for_novice_user_level=virtualbox
+ short_list_application_ids_for_intermediate_user_level=virtualbox
+ short_list_application_ids_for_advanced_user_level=virtualbox
+ category=System
+ use_category_default=no
+
+application/x-virtualbox-vmdk
+ icon_filename=virtualbox-vmdk
+ description=Virtual Machine Disk Format
+ default_action_type=none
+ short_list_application_ids_for_novice_user_level=virtualbox
+ short_list_application_ids_for_intermediate_user_level=virtualbox
+ short_list_application_ids_for_advanced_user_level=virtualbox
+ category=System
+ use_category_default=no
+
+application/x-virtualbox-vhd
+ icon_filename=virtualbox-vhd
+ description=Virtual Hard Disk
+ default_action_type=none
+ short_list_application_ids_for_novice_user_level=virtualbox
+ short_list_application_ids_for_intermediate_user_level=virtualbox
+ short_list_application_ids_for_advanced_user_level=virtualbox
+ category=System
+ use_category_default=no
+
+application/x-virtualbox-hdd
+ icon_filename=virtualbox-hdd
+ description=Virtual Hard Disk
+ default_action_type=none
+ short_list_application_ids_for_novice_user_level=virtualbox
+ short_list_application_ids_for_intermediate_user_level=virtualbox
+ short_list_application_ids_for_advanced_user_level=virtualbox
+ category=System
+ use_category_default=no
diff --git a/src/VBox/Installer/solaris/virtualbox.mime b/src/VBox/Installer/solaris/virtualbox.mime
index fe4e699ff..7401f4c03 100644
--- a/src/VBox/Installer/solaris/virtualbox.mime
+++ b/src/VBox/Installer/solaris/virtualbox.mime
@@ -9,3 +9,15 @@ application/x-virtualbox-ovf:
application/x-virtualbox-ova:
ext: ova
+
+application/x-virtualbox-vdi:
+ ext: vdi
+
+application/x-virtualbox-vmdk:
+ ext: vmdk
+
+application/x-virtualbox-vhd:
+ ext: vhd
+
+application/x-virtualbox-hdd:
+ ext: hdd
diff --git a/src/VBox/Installer/win/InstallHelper/Makefile.kmk b/src/VBox/Installer/win/InstallHelper/Makefile.kmk
index 38fda620a..856bc6c04 100644
--- a/src/VBox/Installer/win/InstallHelper/Makefile.kmk
+++ b/src/VBox/Installer/win/InstallHelper/Makefile.kmk
@@ -1,10 +1,10 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37053 2011-05-12 14:19:25Z vboxsync $
## @file
# Sub-Makefile for VBoxInstallHelper.dll.
#
#
-# Copyright (C) 2008-2010 Oracle Corporation
+# Copyright (C) 2008-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;
@@ -36,9 +36,11 @@ endif
VBoxInstallHelper_SDKS = WINPSDK W2K3DDK
VBoxInstallHelper_LIBS = $(PATH_SDK_W2K3DDK_LIB)/Msi.lib
ifdef VBOX_WITH_NETFLT
- VBoxInstallHelper_LIBS += $(PATH_LIB)/WinNetConfig.lib \
+ VBoxInstallHelper_LIBS += \
+ $(PATH_LIB)/WinNetConfig.lib \
+ $(PATH_LIB)/VBoxDrvCfg.lib \
$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/comsupp.lib \
- $(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib
+ $(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib
endif
ifeq ($(KBUILD_TARGET),win)
diff --git a/src/VBox/Installer/win/InstallHelper/VBoxCommon.cpp b/src/VBox/Installer/win/InstallHelper/VBoxCommon.cpp
index efea76d75..a7fb8450f 100644
--- a/src/VBox/Installer/win/InstallHelper/VBoxCommon.cpp
+++ b/src/VBox/Installer/win/InstallHelper/VBoxCommon.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxCommon.cpp $ */
+/* $Id: VBoxCommon.cpp 37289 2011-06-01 11:59:23Z vboxsync $ */
/** @file
* VBoxCommon - Misc helper routines for install helper.
*/
@@ -51,7 +51,6 @@ UINT VBoxGetProperty(MSIHANDLE a_hModule, TCHAR* a_pszName, TCHAR* a_pValue, DWO
ZeroMemory(a_pValue, a_dwSize);
uiRet = MsiGetProperty(a_hModule, a_pszName, a_pValue, &dwBuffer);
}
-
return uiRet;
}
diff --git a/src/VBox/Installer/win/InstallHelper/VBoxCommon.h b/src/VBox/Installer/win/InstallHelper/VBoxCommon.h
index 28ed47a68..2adb275e8 100644
--- a/src/VBox/Installer/win/InstallHelper/VBoxCommon.h
+++ b/src/VBox/Installer/win/InstallHelper/VBoxCommon.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxCommon.h $ */
+/* $Id: VBoxCommon.h 32112 2010-08-31 08:44:09Z vboxsync $ */
/** @file
* VBoxCommon - Misc helper routines for install helper.
*/
diff --git a/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.cpp b/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.cpp
index a5c49fa27..e564add60 100644
--- a/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.cpp
+++ b/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxInstallHelper.cpp $ */
+/* $Id: VBoxInstallHelper.cpp 37765 2011-07-04 13:54:00Z vboxsync $ */
/** @file
* VBoxInstallHelper - Various helper routines for Windows host installer.
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -16,7 +16,8 @@
*/
#ifdef VBOX_WITH_NETFLT
-# include "VBox/WinNetConfig.h"
+# include "VBox/VBoxNetCfg-win.h"
+# include "VBox/VBoxDrvCfg-win.h"
#endif /* VBOX_WITH_NETFLT */
#include <VBox/version.h>
@@ -59,17 +60,17 @@ BOOL APIENTRY DllMain(HANDLE hModule,
return TRUE;
}
-void LogString(MSIHANDLE hInstall, TCHAR* szString, ...)
+static void LogString(MSIHANDLE hInstall, LPCSTR szString, ...)
{
- PMSIHANDLE newHandle = ::MsiCreateRecord(2);
+ PMSIHANDLE newHandle = MsiCreateRecord(2);
- TCHAR szBuffer[1024] = {0};
+ char szBuffer[1024] = {0};
va_list pArgList;
va_start(pArgList, szString);
- _vsntprintf(szBuffer, sizeof(szBuffer) / sizeof(TCHAR), szString, pArgList);
+ _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(char), szString, pArgList);
va_end(pArgList);
- MsiRecordSetString(newHandle, 0, szBuffer);
+ MsiRecordSetStringA(newHandle, 0, szBuffer);
MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_INFO), newHandle);
MsiCloseHandle(newHandle);
@@ -80,7 +81,7 @@ void LogString(MSIHANDLE hInstall, TCHAR* szString, ...)
static void LogStringW(MSIHANDLE hInstall, LPCWSTR szString, ...)
{
- PMSIHANDLE newHandle = ::MsiCreateRecord(2);
+ PMSIHANDLE newHandle = MsiCreateRecord(2);
TCHAR szBuffer[1024] = {0};
va_list pArgList;
@@ -93,89 +94,92 @@ static void LogStringW(MSIHANDLE hInstall, LPCWSTR szString, ...)
MsiCloseHandle(newHandle);
}
-UINT __stdcall IsSerialCheckNeeded(MSIHANDLE a_hModule)
+UINT __stdcall IsSerialCheckNeeded(MSIHANDLE hModule)
{
#ifndef VBOX_OSE
- /*BOOL bRet =*/ serialCheckNeeded(a_hModule);
+ /*BOOL bRet =*/ serialCheckNeeded(hModule);
#endif
return ERROR_SUCCESS;
}
-UINT __stdcall CheckSerial(MSIHANDLE a_hModule)
+UINT __stdcall CheckSerial(MSIHANDLE hModule)
{
#ifndef VBOX_OSE
- /*BOOL bRet =*/ serialIsValid(a_hModule);
+ /*BOOL bRet =*/ serialIsValid(hModule);
#endif
return ERROR_SUCCESS;
}
-DWORD Exec(MSIHANDLE hModule, TCHAR* szAppName, TCHAR* szCmdLine, TCHAR* szWorkDir, DWORD* dwExitCode)
+DWORD Exec(MSIHANDLE hModule,
+ const TCHAR *pszAppName, TCHAR *pszCmdLine, const TCHAR *pszWorkDir,
+ DWORD *pdwExitCode)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD rc = ERROR_SUCCESS;
- ::ZeroMemory(&si, sizeof(si));
+ ZeroMemory(&si, sizeof(si));
si.dwFlags = STARTF_USESHOWWINDOW;
#ifdef UNICODE
si.dwFlags |= CREATE_UNICODE_ENVIRONMENT;
#endif
si.wShowWindow = SW_HIDE; /* For debugging: SW_SHOW; */
si.cb = sizeof(si);
- ::ZeroMemory(&pi, sizeof(pi));
-
- LogString(hModule, TEXT("Executing command line: %s %s (Working Dir: %s)"), szAppName, szCmdLine, szWorkDir == NULL ? L"Current" : szWorkDir);
-
- ::SetLastError(0);
- if (!::CreateProcess(szAppName, /* Module name. */
- szCmdLine, /* Command line. */
- NULL, /* Process handle not inheritable. */
- NULL, /* Thread handle not inheritable. */
- FALSE, /* Set handle inheritance to FALSE .*/
- 0, /* No creation flags. */
- NULL, /* Use parent's environment block. */
- szWorkDir, /* Use parent's starting directory. */
- &si, /* Pointer to STARTUPINFO structure. */
- &pi)) /* Pointer to PROCESS_INFORMATION structure. */
+ ZeroMemory(&pi, sizeof(pi));
+
+ LogStringW(hModule, TEXT("Executing command line: %s %s (Working Dir: %s)"),
+ pszAppName, pszCmdLine, pszWorkDir == NULL ? L"Current" : pszWorkDir);
+
+ SetLastError(0);
+ if (!CreateProcess(pszAppName, /* Module name. */
+ pszCmdLine, /* Command line. */
+ NULL, /* Process handle not inheritable. */
+ NULL, /* Thread handle not inheritable. */
+ FALSE, /* Set handle inheritance to FALSE .*/
+ 0, /* No creation flags. */
+ NULL, /* Use parent's environment block. */
+ pszWorkDir, /* Use parent's starting directory. */
+ &si, /* Pointer to STARTUPINFO structure. */
+ &pi)) /* Pointer to PROCESS_INFORMATION structure. */
{
- rc = ::GetLastError();
- LogString(hModule, TEXT("Executing command line: CreateProcess() failed! Error: %ld"), rc);
+ rc = GetLastError();
+ LogStringW(hModule, TEXT("Executing command line: CreateProcess() failed! Error: %ld"), rc);
return rc;
}
/* Wait until child process exits. */
- if (WAIT_FAILED == ::WaitForSingleObject(pi.hProcess, 30 * 1000 /* Wait 30 secs max. */))
+ if (WAIT_FAILED == WaitForSingleObject(pi.hProcess, 30 * 1000 /* Wait 30 secs max. */))
{
- rc = ::GetLastError();
- LogString(hModule, TEXT("Executing command line: WaitForSingleObject() failed! Error: %ld"), rc);
+ rc = GetLastError();
+ LogStringW(hModule, TEXT("Executing command line: WaitForSingleObject() failed! Error: %ld"), rc);
}
else
{
- if (0 == ::GetExitCodeProcess(pi.hProcess, dwExitCode))
+ if (!GetExitCodeProcess(pi.hProcess, pdwExitCode))
{
- rc = ::GetLastError();
- LogString(hModule, TEXT("Executing command line: GetExitCodeProcess() failed! Error: %ld"), rc);
+ rc = GetLastError();
+ LogStringW(hModule, TEXT("Executing command line: GetExitCodeProcess() failed! Error: %ld"), rc);
}
}
/* Close process and thread handles. */
- ::CloseHandle(pi.hProcess);
- ::CloseHandle(pi.hThread);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
- LogString(hModule, TEXT("Executing command returned: %ld (exit code %ld)"), rc, *dwExitCode);
+ LogStringW(hModule, TEXT("Executing command returned: %ld (exit code %ld)"), rc, *pdwExitCode);
return rc;
}
UINT __stdcall InstallPythonAPI(MSIHANDLE hModule)
{
- LogString(hModule, TEXT("InstallPythonAPI: Checking for installed Python environment ..."));
+ LogStringW(hModule, TEXT("InstallPythonAPI: Checking for installed Python environment ..."));
HKEY hkPythonCore = NULL;
- BOOL bInstalled = FALSE;
- LONG rc = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Python\\PythonCore", 0, KEY_READ, &hkPythonCore);
+ BOOL bFound = FALSE;
+ LONG rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Python\\PythonCore", 0, KEY_READ, &hkPythonCore);
if (rc != ERROR_SUCCESS)
{
- LogString(hModule, TEXT("InstallPythonAPI: No environment seems to be installed."));
+ LogStringW(hModule, TEXT("InstallPythonAPI: Python seems not to be installed."));
return ERROR_SUCCESS;
}
@@ -188,7 +192,7 @@ UINT __stdcall InstallPythonAPI(MSIHANDLE hModule)
DWORD dwLen = sizeof (szPath);
DWORD dwKeyType = REG_SZ;
- rc = ::RegEnumKeyEx(hkPythonCore, i, szRoot, &dwLen, NULL, NULL, NULL, NULL);
+ rc = RegEnumKeyEx(hkPythonCore, i, szRoot, &dwLen, NULL, NULL, NULL, NULL);
if (rc != ERROR_SUCCESS || dwLen <= 0)
break;
@@ -196,70 +200,88 @@ UINT __stdcall InstallPythonAPI(MSIHANDLE hModule)
dwLen = sizeof(szVal);
HKEY hkPythonInstPath = NULL;
- rc = ::RegOpenKeyEx(hkPythonCore, szPath, 0, KEY_READ, &hkPythonInstPath);
+ rc = RegOpenKeyEx(hkPythonCore, szPath, 0, KEY_READ, &hkPythonInstPath);
if (rc != ERROR_SUCCESS)
continue;
- rc = ::RegQueryValueEx(hkPythonInstPath, L"", NULL, &dwKeyType, (LPBYTE)szVal, &dwLen);
- if(rc == ERROR_SUCCESS)
- LogString(hModule, TEXT("InstallPythonAPI: Path \"%s\" detected."), szVal);
- }
+ rc = RegQueryValueEx(hkPythonInstPath, L"", NULL, &dwKeyType, (LPBYTE)szVal, &dwLen);
+ if (rc == ERROR_SUCCESS)
+ LogStringW(hModule, TEXT("InstallPythonAPI: Path \"%s\" detected."), szVal);
- ::RegCloseKey (hkPythonCore);
+ RegCloseKey(hkPythonInstPath);
+ }
+ RegCloseKey(hkPythonCore);
/* Python path found? */
TCHAR szExec[MAX_PATH] = { 0 };
TCHAR szCmdLine[MAX_PATH] = { 0 };
DWORD dwExitCode = 0;
- if (::_tcslen(szVal) > 0)
+ if (_tcslen(szVal) > 0)
{
/* Cool, check for installed Win32 extensions. */
- LogString(hModule, TEXT("InstallPythonAPI: Python installed. Checking for Win32 extensions ..."));
+ LogStringW(hModule, TEXT("InstallPythonAPI: Python installed. Checking for Win32 extensions ..."));
_stprintf_s(szExec, sizeof(szExec) / sizeof(TCHAR), L"%s\\python.exe", szVal);
_stprintf_s(szCmdLine, sizeof(szCmdLine) / sizeof(TCHAR), L"%s\\python.exe -c \"import win32api\"", szVal);
- if ( (0 == Exec(hModule, szExec, szCmdLine, NULL, &dwExitCode))
- && (0 == dwExitCode))
+ DWORD dwRetExec = Exec(hModule, szExec, szCmdLine, NULL, &dwExitCode);
+ if ( (ERROR_SUCCESS == dwRetExec)
+ && ( 0 == dwExitCode))
{
/* Did we get the correct error level (=0)? */
- LogString(hModule, TEXT("InstallPythonAPI: Win32 extensions installed."));
- bInstalled = TRUE;
+ LogStringW(hModule, TEXT("InstallPythonAPI: Win32 extensions installed."));
+ bFound = TRUE;
}
- else LogString(hModule, TEXT("InstallPythonAPI: Win32 extensions not found."));
+ else
+ LogStringW(hModule, TEXT("InstallPythonAPI: Win32 extensions not found."));
}
- if (bInstalled) /* Is Python and all required stuff installed? */
+ BOOL bInstalled = FALSE;
+ if (bFound) /* Is Python and all required stuff installed? */
{
/* Get the VBoxAPI setup string. */
- TCHAR szVBoxAPISetupPath[MAX_PATH] = {0};
- VBoxGetProperty(hModule, L"INSTALLDIR", szVBoxAPISetupPath, sizeof(szVBoxAPISetupPath));
+ TCHAR szPathTargetDir[MAX_PATH] = {0};
+ VBoxGetProperty(hModule, L"CustomActionData", szPathTargetDir, sizeof(szPathTargetDir));
+ if (_tcslen(szPathTargetDir))
+ {
- /* Set final path. */
- _stprintf_s(szPath, sizeof(szPath) / sizeof(TCHAR), L"%s\\sdk\\install", szVBoxAPISetupPath);
+ /* Set final path. */
+ _stprintf_s(szPath, sizeof(szPath) / sizeof(TCHAR), L"%s\\sdk\\install", szPathTargetDir);
- /* Install our API module. */
- _stprintf_s(szCmdLine, sizeof(szCmdLine) / sizeof(TCHAR), L"%s\\python.exe vboxapisetup.py install", szVal);
+ /* Install our API module. */
+ _stprintf_s(szCmdLine, sizeof(szCmdLine) / sizeof(TCHAR), L"%s\\python.exe vboxapisetup.py install", szVal);
- /* Set required environment variables. */
- if (!SetEnvironmentVariable(L"VBOX_INSTALL_PATH", szVBoxAPISetupPath))
- {
- LogString(hModule, TEXT("InstallPythonAPI: Cannot set environment variable VBOX_INSTALL_PATH!"));
- return FALSE;
- }
- else
- {
- if ( (0 == Exec(hModule, szExec, szCmdLine, szPath, &dwExitCode))
- && (0 == dwExitCode))
+ /* Set required environment variables. */
+ if (!SetEnvironmentVariable(L"VBOX_INSTALL_PATH", szPathTargetDir))
{
- /* All done! */
- LogString(hModule, TEXT("InstallPythonAPI: VBoxAPI for Python successfully installed."));
- return ERROR_SUCCESS;
+ LogStringW(hModule, TEXT("InstallPythonAPI: Could set environment variable VBOX_INSTALL_PATH!"));
+ }
+ else
+ {
+ DWORD dwRetExec = Exec(hModule, szExec, szCmdLine, szPath, &dwExitCode);
+ if ( (ERROR_SUCCESS == dwRetExec)
+ && ( 0 == dwExitCode))
+ {
+ /* All done! */
+ LogStringW(hModule, TEXT("InstallPythonAPI: VBoxAPI for Python successfully installed."));
+ bInstalled = TRUE;
+ }
+ else
+ {
+ if (dwRetExec)
+ LogStringW(hModule, TEXT("InstallPythonAPI: Error while executing installation of VBox API: %ld"), dwRetExec);
+ else
+ LogStringW(hModule, TEXT("InstallPythonAPI: Python reported an error while installing VBox API: %ld"), dwExitCode);
+ }
}
- else LogString(hModule, TEXT("InstallPythonAPI: Error while installing VBoxAPI: %ld"), dwExitCode);
}
+ else
+ LogStringW(hModule, TEXT("InstallPythonAPI: Unable to retrieve VBox installation path!"));
}
- LogString(hModule, TEXT("InstallPythonAPI: VBoxAPI not installed."));
+ VBoxSetProperty(hModule, L"PYTHON_INSTALLED", bInstalled ? L"1" : L"0");
+
+ if (!bInstalled)
+ LogStringW(hModule, TEXT("InstallPythonAPI: VBox API not installed."));
return ERROR_SUCCESS; /* Do not fail here. */
}
@@ -292,7 +314,7 @@ static LONG InstallBrandingValue(MSIHANDLE hModule,
(BYTE*)szValue,
(DWORD)wcslen(szValue));
if (rc != ERROR_SUCCESS)
- LogString(hModule, TEXT("InstallBranding: Could not write value %s! Error %ld"), pszValue, rc);
+ LogStringW(hModule, TEXT("InstallBranding: Could not write value %s! Error %ld"), pszValue, rc);
RegCloseKey (hkBranding);
}
}
@@ -320,12 +342,12 @@ UINT CopyDir(MSIHANDLE hModule, const TCHAR *pszDestDir, const TCHAR *pszSourceD
FOF_NOCONFIRMMKDIR |
FOF_NOERRORUI;
- LogString(hModule, TEXT("CopyDir: DestDir=%s, SourceDir=%s"),
+ LogStringW(hModule, TEXT("CopyDir: DestDir=%s, SourceDir=%s"),
szDest, szSource);
int r = SHFileOperation(&s);
if (r != 0)
{
- LogString(hModule, TEXT("CopyDir: Copy operation returned status 0x%x"), r);
+ LogStringW(hModule, TEXT("CopyDir: Copy operation returned status 0x%x"), r);
rc = ERROR_GEN_FAILURE;
}
else
@@ -349,11 +371,11 @@ UINT RemoveDir(MSIHANDLE hModule, const TCHAR *pszDestDir)
FOF_NOCONFIRMMKDIR |
FOF_NOERRORUI;
- LogString(hModule, TEXT("RemoveDir: DestDir=%s"), szDest);
+ LogStringW(hModule, TEXT("RemoveDir: DestDir=%s"), szDest);
int r = SHFileOperation(&s);
if (r != 0)
{
- LogString(hModule, TEXT("RemoveDir: Remove operation returned status 0x%x"), r);
+ LogStringW(hModule, TEXT("RemoveDir: Remove operation returned status 0x%x"), r);
rc = ERROR_GEN_FAILURE;
}
else
@@ -380,12 +402,12 @@ UINT RenameDir(MSIHANDLE hModule, const TCHAR *pszDestDir, const TCHAR *pszSourc
FOF_NOCONFIRMMKDIR |
FOF_NOERRORUI;
- LogString(hModule, TEXT("RenameDir: DestDir=%s, SourceDir=%s"),
+ LogStringW(hModule, TEXT("RenameDir: DestDir=%s, SourceDir=%s"),
szDest, szSource);
int r = SHFileOperation(&s);
if (r != 0)
{
- LogString(hModule, TEXT("RenameDir: Rename operation returned status 0x%x"), r);
+ LogStringW(hModule, TEXT("RenameDir: Rename operation returned status 0x%x"), r);
rc = ERROR_GEN_FAILURE;
}
else
@@ -396,12 +418,12 @@ UINT RenameDir(MSIHANDLE hModule, const TCHAR *pszDestDir, const TCHAR *pszSourc
UINT __stdcall UninstallBranding(MSIHANDLE hModule)
{
UINT rc;
- LogString(hModule, TEXT("UninstallBranding: Handling branding file ..."));
+ LogStringW(hModule, TEXT("UninstallBranding: Handling branding file ..."));
TCHAR szPathTargetDir[_MAX_PATH];
TCHAR szPathDest[_MAX_PATH];
- rc = VBoxGetProperty(hModule, L"INSTALLDIR", szPathTargetDir, sizeof(szPathTargetDir));
+ rc = VBoxGetProperty(hModule, L"CustomActionData", szPathTargetDir, sizeof(szPathTargetDir));
if (rc == ERROR_SUCCESS)
{
/** @todo Check trailing slash after %s. */
@@ -415,14 +437,14 @@ UINT __stdcall UninstallBranding(MSIHANDLE hModule)
}
}
- LogString(hModule, TEXT("UninstallBranding: Handling done."));
+ LogStringW(hModule, TEXT("UninstallBranding: Handling done."));
return ERROR_SUCCESS; /* Do not fail here. */
}
UINT __stdcall InstallBranding(MSIHANDLE hModule)
{
UINT rc;
- LogString(hModule, TEXT("InstallBranding: Handling branding file ..."));
+ LogStringW(hModule, TEXT("InstallBranding: Handling branding file ..."));
TCHAR szPathMSI[_MAX_PATH];
TCHAR szPathTargetDir[_MAX_PATH];
@@ -431,22 +453,25 @@ UINT __stdcall InstallBranding(MSIHANDLE hModule)
TCHAR szPathDest[_MAX_PATH];
rc = VBoxGetProperty(hModule, L"SOURCEDIR", szPathMSI, sizeof(szPathMSI));
- rc = VBoxGetProperty(hModule, L"INSTALLDIR", szPathTargetDir, sizeof(szPathTargetDir));
if (rc == ERROR_SUCCESS)
{
- /** @todo Check for trailing slash after %s. */
- _stprintf_s(szPathDest, sizeof(szPathDest) / sizeof(TCHAR), L"%s", szPathTargetDir);
- _stprintf_s(szPathSource, sizeof(szPathSource) / sizeof(TCHAR), L"%s.custom", szPathMSI);
- rc = CopyDir(hModule, szPathDest, szPathSource);
+ rc = VBoxGetProperty(hModule, L"CustomActionData", szPathTargetDir, sizeof(szPathTargetDir));
if (rc == ERROR_SUCCESS)
{
- _stprintf_s(szPathDest, sizeof(szPathDest) / sizeof(TCHAR), L"%scustom", szPathTargetDir);
- _stprintf_s(szPathSource, sizeof(szPathSource) / sizeof(TCHAR), L"%s.custom", szPathTargetDir);
- rc = RenameDir(hModule, szPathDest, szPathSource);
+ /** @todo Check for trailing slash after %s. */
+ _stprintf_s(szPathDest, sizeof(szPathDest) / sizeof(TCHAR), L"%s", szPathTargetDir);
+ _stprintf_s(szPathSource, sizeof(szPathSource) / sizeof(TCHAR), L"%s.custom", szPathMSI);
+ rc = CopyDir(hModule, szPathDest, szPathSource);
+ if (rc == ERROR_SUCCESS)
+ {
+ _stprintf_s(szPathDest, sizeof(szPathDest) / sizeof(TCHAR), L"%scustom", szPathTargetDir);
+ _stprintf_s(szPathSource, sizeof(szPathSource) / sizeof(TCHAR), L"%s.custom", szPathTargetDir);
+ rc = RenameDir(hModule, szPathDest, szPathSource);
+ }
}
}
- LogString(hModule, TEXT("InstallBranding: Handling done."));
+ LogStringW(hModule, TEXT("InstallBranding: Handling done."));
return ERROR_SUCCESS; /* Do not fail here. */
}
@@ -456,82 +481,80 @@ UINT __stdcall InstallBranding(MSIHANDLE hModule)
#define VBOX_NETCFG_APP_NAME L"VirtualBox Installer"
#define VBOX_NETCFG_MAX_RETRIES 10
#define NETFLT_PT_INF_REL_PATH L"drivers\\network\\netflt\\VBoxNetFlt.inf"
-#define NETFLT_MP_INF_REL_PATH L"drivers\\network\\netflt\\VBoxNetFlt_m.inf"
+#define NETFLT_MP_INF_REL_PATH L"drivers\\network\\netflt\\VBoxNetFltM.inf"
#define NETFLT_ID L"sun_VBoxNetFlt" /** @todo Needs to be changed (?). */
#define NETADP_ID L"sun_VBoxNetAdp" /** @todo Needs to be changed (?). */
static MSIHANDLE g_hCurrentModule = NULL;
-static VOID winNetCfgLogger(LPCWSTR szString)
+
+static VOID netCfgLoggerCallback(LPCSTR szString)
+{
+ if (g_hCurrentModule)
+ LogString(g_hCurrentModule, szString);
+}
+
+static VOID netCfgLoggerDisable()
{
- Assert(g_hCurrentModule);
- if(g_hCurrentModule)
+ if (g_hCurrentModule)
{
- LogStringW(g_hCurrentModule, szString);
+ VBoxNetCfgWinSetLogging((LOG_ROUTINE)NULL);
+ g_hCurrentModule = NULL;
}
}
-static VOID inintWinNetCfgLogger(MSIHANDLE hModule)
+static VOID netCfgLoggerEnable(MSIHANDLE hModule)
{
- Assert(!g_hCurrentModule);
Assert(hModule);
- g_hCurrentModule = hModule;
-
- VBoxNetCfgWinSetLogging((LOG_ROUTINE)winNetCfgLogger);
-}
-
-static VOID finiWinNetCfgLogger()
-{
- Assert(g_hCurrentModule);
+ if (g_hCurrentModule)
+ netCfgLoggerDisable();
- VBoxNetCfgWinSetLogging((LOG_ROUTINE)NULL);
+ g_hCurrentModule = hModule;
- g_hCurrentModule = NULL;
+ VBoxNetCfgWinSetLogging((LOG_ROUTINE)netCfgLoggerCallback);
}
-static UINT Hresult2Error(MSIHANDLE hModule, HRESULT hr)
+static UINT ErrorConvertFromHResult(MSIHANDLE hModule, HRESULT hr)
{
- switch(hr)
+ UINT uRet;
+ switch (hr)
{
case S_OK:
- return ERROR_SUCCESS;
+ uRet = ERROR_SUCCESS;
+ break;
+
case NETCFG_S_REBOOT:
- LogString(hModule, TEXT("Reboot required, setting REBOOT property to Force"));
- if(MsiSetProperty(hModule, TEXT("REBOOT"), TEXT("Force")) != ERROR_SUCCESS)
- {
- LogString(hModule, TEXT("Failed to set REBOOT property"));
- return ERROR_GEN_FAILURE;
- }
- return ERROR_SUCCESS;
+ {
+ LogStringW(hModule, TEXT("Reboot required, setting REBOOT property to Force"));
+ HRESULT hr2 = MsiSetProperty(hModule, TEXT("REBOOT"), TEXT("Force"));
+ if (hr2 != ERROR_SUCCESS)
+ LogStringW(hModule, TEXT("Failed to set REBOOT property, error = 0x%x"), hr2);
+ uRet = ERROR_SUCCESS; /* Never fail here. */
+ break;
+ }
+
default:
- LogString(hModule, TEXT("converting hresult (0x%x) to ERROR_GEN_FAILURE"), hr);
- return ERROR_GEN_FAILURE;
+ LogStringW(hModule, TEXT("Converting unhandled HRESULT (0x%x) to ERROR_GEN_FAILURE"), hr);
+ uRet = ERROR_GEN_FAILURE;
}
+ return uRet;
}
static MSIHANDLE createNetCfgLockedMsgRecord(MSIHANDLE hModule)
{
MSIHANDLE hRecord = MsiCreateRecord(2);
- Assert(hRecord);
- if(hRecord)
+ if (hRecord)
{
- do
+ UINT uErr = MsiRecordSetInteger(hRecord, 1, 25001);
+ if (uErr != ERROR_SUCCESS)
{
- UINT r = MsiRecordSetInteger(hRecord, 1, 25001);
- Assert(r == ERROR_SUCCESS);
- if(r != ERROR_SUCCESS)
- {
- LogString(hModule, TEXT("createNetCfgLockedMsgRecord: MsiRecordSetInteger failed, r (0x%x)"), r);
- MsiCloseHandle(hRecord);
- hRecord = NULL;
- break;
- }
- }while(0);
+ LogStringW(hModule, TEXT("createNetCfgLockedMsgRecord: MsiRecordSetInteger failed, error = 0x%x"), uErr);
+ MsiCloseHandle(hRecord);
+ hRecord = NULL;
+ }
}
else
- {
- LogString(hModule, TEXT("createNetCfgLockedMsgRecord: failed to create a record"));
- }
+ LogStringW(hModule, TEXT("createNetCfgLockedMsgRecord: Failed to create a record"));
return hRecord;
}
@@ -539,31 +562,27 @@ static MSIHANDLE createNetCfgLockedMsgRecord(MSIHANDLE hModule)
static UINT doNetCfgInit(MSIHANDLE hModule, INetCfg **ppnc, BOOL bWrite)
{
MSIHANDLE hMsg = NULL;
- UINT r = ERROR_GEN_FAILURE;
+ UINT uErr = ERROR_GEN_FAILURE;
int MsgResult;
int cRetries = 0;
do
{
LPWSTR lpszLockedBy;
- HRESULT hr = VBoxNetCfgWinQueryINetCfg(bWrite, VBOX_NETCFG_APP_NAME, ppnc, &lpszLockedBy);
- if(hr != NETCFG_E_NO_WRITE_LOCK)
+ HRESULT hr = VBoxNetCfgWinQueryINetCfg(ppnc, bWrite, VBOX_NETCFG_APP_NAME, 10000, &lpszLockedBy);
+ if (hr != NETCFG_E_NO_WRITE_LOCK)
{
- Assert(hr == S_OK);
- if(hr != S_OK)
- {
- LogString(hModule, TEXT("doNetCfgInit: VBoxNetCfgWinQueryINetCfg failed, hr (0x%x)"), hr);
- }
- r = Hresult2Error(hModule, hr);
+ if (FAILED(hr))
+ LogStringW(hModule, TEXT("doNetCfgInit: VBoxNetCfgWinQueryINetCfg failed, error = 0x%x"), hr);
+ uErr = ErrorConvertFromHResult(hModule, hr);
break;
}
/* hr == NETCFG_E_NO_WRITE_LOCK */
- Assert(lpszLockedBy);
- if(!lpszLockedBy)
+ if (!lpszLockedBy)
{
- LogString(hModule, TEXT("doNetCfgInit: lpszLockedBy == NULL, breaking"));
+ LogStringW(hModule, TEXT("doNetCfgInit: lpszLockedBy == NULL, breaking"));
break;
}
@@ -573,21 +592,21 @@ static UINT doNetCfgInit(MSIHANDLE hModule, INetCfg **ppnc, BOOL bWrite)
* however it seems unneeded for most cases, e.g. in case some network connection property
* dialog is opened, it would be better to post a notification to the user as soon as possible
* rather than waiting for a longer period of time before displaying it */
- if(cRetries < VBOX_NETCFG_MAX_RETRIES
- && !wcscmp(lpszLockedBy, L"6to4svc.dll"))
+ if ( cRetries < VBOX_NETCFG_MAX_RETRIES
+ && !wcscmp(lpszLockedBy, L"6to4svc.dll"))
{
cRetries++;
- LogString(hModule, TEXT("doNetCfgInit: lpszLockedBy is 6to4svc.dll, retrying %d out of %d"), cRetries, VBOX_NETCFG_MAX_RETRIES);
+ LogStringW(hModule, TEXT("doNetCfgInit: lpszLockedBy is 6to4svc.dll, retrying %d out of %d"), cRetries, VBOX_NETCFG_MAX_RETRIES);
MsgResult = IDRETRY;
}
else
{
- if(!hMsg)
+ if (!hMsg)
{
hMsg = createNetCfgLockedMsgRecord(hModule);
- if(!hMsg)
+ if (!hMsg)
{
- LogString(hModule, TEXT("doNetCfgInit: failed to create a message record, breaking"));
+ LogStringW(hModule, TEXT("doNetCfgInit: Failed to create a message record, breaking"));
CoTaskMemFree(lpszLockedBy);
break;
}
@@ -595,57 +614,62 @@ static UINT doNetCfgInit(MSIHANDLE hModule, INetCfg **ppnc, BOOL bWrite)
UINT rTmp = MsiRecordSetStringW(hMsg, 2, lpszLockedBy);
Assert(rTmp == ERROR_SUCCESS);
- if(rTmp != ERROR_SUCCESS)
+ if (rTmp != ERROR_SUCCESS)
{
- LogString(hModule, TEXT("doNetCfgInit: MsiRecordSetStringW failed, r (0x%x)"), rTmp);
+ LogStringW(hModule, TEXT("doNetCfgInit: MsiRecordSetStringW failed, error = 0x%x"), rTmp);
CoTaskMemFree(lpszLockedBy);
break;
}
MsgResult = MsiProcessMessage(hModule, (INSTALLMESSAGE)(INSTALLMESSAGE_USER | MB_RETRYCANCEL), hMsg);
Assert(MsgResult == IDRETRY || MsgResult == IDCANCEL);
- LogString(hModule, TEXT("doNetCfgInit: MsiProcessMessage returned (0x%x)"), MsgResult);
+ LogStringW(hModule, TEXT("doNetCfgInit: MsiProcessMessage returned (0x%x)"), MsgResult);
}
CoTaskMemFree(lpszLockedBy);
} while(MsgResult == IDRETRY);
- if(hMsg)
- {
+ if (hMsg)
MsiCloseHandle(hMsg);
- }
- return r;
+ return uErr;
}
-static UINT vboxNetFltQueryInfArray(MSIHANDLE hModule, OUT LPWSTR *apInfFullPaths, PUINT pcInfs, DWORD cSize)
+static UINT vboxNetFltQueryInfArray(MSIHANDLE hModule, OUT LPWSTR *apInfFullPaths, PUINT pcInfs, DWORD dwSize)
{
- UINT r;
- Assert(*pcInfs >= 2);
- if(*pcInfs >= 2)
+ UINT uErr;
+ if (*pcInfs >= 2)
{
*pcInfs = 2;
- r = MsiGetPropertyW(hModule, L"CustomActionData", apInfFullPaths[0], &cSize);
- Assert(r == ERROR_SUCCESS);
- if(r == ERROR_SUCCESS)
+
+ DWORD dwBuf = dwSize;
+ uErr = MsiGetPropertyW(hModule, L"CustomActionData", apInfFullPaths[0], &dwBuf);
+ if ( uErr == ERROR_SUCCESS
+ && dwBuf)
{
+ /** @todo r=andy Avoid wcscpy and wcsncat, can cause buffer overruns! */
wcscpy(apInfFullPaths[1], apInfFullPaths[0]);
wcsncat(apInfFullPaths[0], NETFLT_PT_INF_REL_PATH, sizeof(NETFLT_PT_INF_REL_PATH));
+ LogStringW(hModule, TEXT("vboxNetFltQueryInfArray: INF 1: %s"), apInfFullPaths[0]);
+
wcsncat(apInfFullPaths[1], NETFLT_MP_INF_REL_PATH, sizeof(NETFLT_MP_INF_REL_PATH));
+ LogStringW(hModule, TEXT("vboxNetFltQueryInfArray: INF 2: %s"), apInfFullPaths[1]);
}
else
{
- LogString(hModule, TEXT("vboxNetFltQueryInfArray: MsiGetPropertyW failes, r (%d)"), r);
+ if (uErr != ERROR_SUCCESS)
+ LogStringW(hModule, TEXT("vboxNetFltQueryInfArray: MsiGetPropertyW failed, error = 0x%x"), uErr);
+ else
+ LogStringW(hModule, TEXT("vboxNetFltQueryInfArray: Empty installation directory"));
}
}
else
{
- r = ERROR_GEN_FAILURE;
- LogString(hModule, TEXT("vboxNetFltQueryInfArray: buffer array size is < 2 : (%d)"), *pcInfs);
- *pcInfs = 2;
+ uErr = ERROR_BUFFER_OVERFLOW;
+ LogStringW(hModule, TEXT("vboxNetFltQueryInfArray: Buffer array size is < 2 (%u)"), *pcInfs);
}
- return r;
+ return uErr;
}
#endif /*VBOX_WITH_NETFLT*/
@@ -653,135 +677,106 @@ static UINT vboxNetFltQueryInfArray(MSIHANDLE hModule, OUT LPWSTR *apInfFullPath
UINT __stdcall UninstallNetFlt(MSIHANDLE hModule)
{
#ifdef VBOX_WITH_NETFLT
- INetCfg *pnc;
- UINT r;
+ INetCfg *pNetCfg;
+ UINT uErr;
- inintWinNetCfgLogger(hModule);
+ netCfgLoggerEnable(hModule);
BOOL bOldIntMode = SetupSetNonInteractiveMode(FALSE);
__try
{
- LogString(hModule, TEXT("Uninstalling NetFlt"));
+ LogStringW(hModule, TEXT("Uninstalling NetFlt"));
- r = doNetCfgInit(hModule, &pnc, TRUE);
- Assert(r == ERROR_SUCCESS);
- if(r == ERROR_SUCCESS)
+ uErr = doNetCfgInit(hModule, &pNetCfg, TRUE);
+ if (uErr == ERROR_SUCCESS)
{
- HRESULT hr = VBoxNetCfgWinNetFltUninstall(pnc);
- Assert(hr == S_OK);
- if(hr != S_OK)
- {
- LogString(hModule, TEXT("UninstallNetFlt: VBoxNetCfgWinUninstallComponent failed, hr (0x%x)"), hr);
- }
+ HRESULT hr = VBoxNetCfgWinNetFltUninstall(pNetCfg);
+ if (hr != S_OK)
+ LogStringW(hModule, TEXT("UninstallNetFlt: VBoxNetCfgWinUninstallComponent failed, error = 0x%x"), hr);
- r = Hresult2Error(hModule, hr);
+ uErr = ErrorConvertFromHResult(hModule, hr);
- VBoxNetCfgWinReleaseINetCfg(pnc, TRUE);
+ VBoxNetCfgWinReleaseINetCfg(pNetCfg, TRUE);
- /* Never fail the uninstall */
- r = ERROR_SUCCESS;
+ LogStringW(hModule, TEXT("Uninstalling NetFlt done, error = 0x%x"), uErr);
+
+ /* Never fail on uninstall. */
+ uErr = ERROR_SUCCESS;
}
else
- {
- LogString(hModule, TEXT("UninstallNetFlt: doNetCfgInit failed, r (0x%x)"), r);
- }
-
- LogString(hModule, TEXT("Uninstalling NetFlt done, r (0x%x)"), r);
+ LogStringW(hModule, TEXT("UninstallNetFlt: doNetCfgInit failed, error = 0x%x"), uErr);
}
__finally
{
- if(bOldIntMode)
+ if (bOldIntMode)
{
- /* the prev mode != FALSE, i.e. non-interactive */
+ /* The prev mode != FALSE, i.e. non-interactive. */
SetupSetNonInteractiveMode(bOldIntMode);
}
- finiWinNetCfgLogger();
+ netCfgLoggerDisable();
}
+#endif /* VBOX_WITH_NETFLT */
+ /* Never fail the install even if we did not succeed. */
return ERROR_SUCCESS;
-#else /* not defined VBOX_WITH_NETFLT */
- return ERROR_SUCCESS;
-#endif /* VBOX_WITH_NETFLT */
}
UINT __stdcall InstallNetFlt(MSIHANDLE hModule)
{
#ifdef VBOX_WITH_NETFLT
- UINT r;
- INetCfg *pnc;
+ UINT uErr;
+ INetCfg *pNetCfg;
- inintWinNetCfgLogger(hModule);
+ netCfgLoggerEnable(hModule);
BOOL bOldIntMode = SetupSetNonInteractiveMode(FALSE);
__try
{
- LogString(hModule, TEXT("Installing NetFlt"));
+ LogStringW(hModule, TEXT("Installing NetFlt"));
- r = doNetCfgInit(hModule, &pnc, TRUE);
- Assert(r == ERROR_SUCCESS);
- if(r == ERROR_SUCCESS)
+ uErr = doNetCfgInit(hModule, &pNetCfg, TRUE);
+ if (uErr == ERROR_SUCCESS)
{
WCHAR PtInf[MAX_PATH];
WCHAR MpInf[MAX_PATH];
DWORD sz = sizeof(PtInf);
LPWSTR aInfs[] = {PtInf, MpInf};
UINT cInfs = 2;
-
- r = vboxNetFltQueryInfArray(hModule, aInfs, &cInfs, sz);
- Assert(r == ERROR_SUCCESS);
- Assert(cInfs == 2);
- if(r == ERROR_SUCCESS)
+ uErr = vboxNetFltQueryInfArray(hModule, aInfs, &cInfs, sz);
+ if (uErr == ERROR_SUCCESS)
{
- // HRESULT hr = VBoxNetCfgWinInstallSpecifiedComponent (
- // pnc,
- // (LPCWSTR*)aInfs,
- // cInfs,
- // NETFLT_ID,
- // &GUID_DEVCLASS_NETSERVICE,
- // true);
- HRESULT hr = VBoxNetCfgWinNetFltInstall(pnc, (LPCWSTR*)aInfs, cInfs);
- Assert(hr == S_OK);
- if(hr != S_OK)
- {
- LogString(hModule, TEXT("InstallNetFlt: VBoxNetCfgWinInstallSpecifiedComponent failed, hr (0x%x)"), hr);
- }
+ HRESULT hr = VBoxNetCfgWinNetFltInstall(pNetCfg, (LPCWSTR*)aInfs, cInfs);
+ if (FAILED(hr))
+ LogStringW(hModule, TEXT("InstallNetFlt: VBoxNetCfgWinNetFltInstall failed, error = 0x%x"), hr);
- r = Hresult2Error(hModule, hr);
+ uErr = ErrorConvertFromHResult(hModule, hr);
}
else
- {
- LogString(hModule, TEXT("InstallNetFlt: vboxNetFltQueryInfArray failed, r (0x%x)"), r);
- }
+ LogStringW(hModule, TEXT("InstallNetFlt: vboxNetFltQueryInfArray failed, error = 0x%x"), uErr);
- VBoxNetCfgWinReleaseINetCfg(pnc, TRUE);
+ VBoxNetCfgWinReleaseINetCfg(pNetCfg, TRUE);
- /* Never fail the uninstall */
- r = ERROR_SUCCESS;
+ LogStringW(hModule, TEXT("Installing NetFlt done"));
}
else
- {
- LogString(hModule, TEXT("InstallNetFlt: doNetCfgInit failed, r (0x%x)"), r);
- }
-
- LogString(hModule, TEXT("Installing NetFlt done, r (0x%x)"), r);
+ LogStringW(hModule, TEXT("InstallNetFlt: doNetCfgInit failed, error = 0x%x"), uErr);
}
__finally
{
- if(bOldIntMode)
+ if (bOldIntMode)
{
- /* the prev mode != FALSE, i.e. non-interactive */
+ /* The prev mode != FALSE, i.e. non-interactive. */
SetupSetNonInteractiveMode(bOldIntMode);
}
- finiWinNetCfgLogger();
+ netCfgLoggerDisable();
}
+#endif /* VBOX_WITH_NETFLT */
+ /* Never fail the install even if we did not succeed. */
return ERROR_SUCCESS;
-#else /* not defined VBOX_WITH_NETFLT */
- return ERROR_SUCCESS;
-#endif /* VBOX_WITH_NETFLT */
}
#if 0
@@ -790,7 +785,7 @@ static BOOL RenameHostOnlyConnectionsCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DAT
WCHAR DevName[256];
DWORD winEr;
- if(SetupDiGetDeviceRegistryPropertyW(hDevInfo, pDev,
+ if (SetupDiGetDeviceRegistryPropertyW(hDevInfo, pDev,
SPDRP_FRIENDLYNAME , /* IN DWORD Property,*/
NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
(PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/
@@ -817,14 +812,14 @@ static BOOL RenameHostOnlyConnectionsCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DAT
&cbGuid /*guid__inout_opt LPDWORD lpcbData*/
);
Assert(winEr == ERROR_SUCCESS);
- if(winEr == ERROR_SUCCESS)
+ if (winEr == ERROR_SUCCESS)
{
WCHAR ConnectoinName[128];
ULONG cbName = sizeof(ConnectoinName);
HRESULT hr = VBoxNetCfgWinGenHostonlyConnectionName (DevName, ConnectoinName, &cbName);
Assert(hr == S_OK);
- if(hr == S_OK)
+ if (SUCCEEDED(hr))
{
hr = VBoxNetCfgWinRenameConnection (guid, ConnectoinName);
Assert(hr == S_OK);
@@ -845,18 +840,17 @@ static BOOL RenameHostOnlyConnectionsCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DAT
UINT __stdcall CreateHostOnlyInterface(MSIHANDLE hModule)
{
#ifdef VBOX_WITH_NETFLT
- inintWinNetCfgLogger(hModule);
+ netCfgLoggerEnable(hModule);
- BOOL bPrevMode = SetupSetNonInteractiveMode(FALSE);
+ BOOL bSetupModeInteractive = SetupSetNonInteractiveMode(FALSE);
bool bSetStaticIp = true;
- LogString(hModule, TEXT("Creating Host-Only Interface"));
+ LogStringW(hModule, TEXT("Creating host-only interface"));
HRESULT hr = VBoxNetCfgWinRemoveAllNetDevicesOfId(NETADP_ID);
- Assert(hr == S_OK);
- if(hr != S_OK)
+ if (FAILED(hr))
{
- LogString(hModule, TEXT("CreateHostOnlyInterface: VBoxNetCfgWinRemoveAllNetDevicesOfId failed, hr (0x%x)"), hr);
+ LogStringW(hModule, TEXT("CreateHostOnlyInterface: VBoxNetCfgWinRemoveAllNetDevicesOfId failed, error = 0x%x"), hr);
bSetStaticIp = false;
}
@@ -865,159 +859,145 @@ UINT __stdcall CreateHostOnlyInterface(MSIHANDLE hModule)
DWORD cSize = sizeof(MpInf)/sizeof(MpInf[0]);
LPCWSTR pInfPath = NULL;
bool bIsFile = false;
- UINT r = MsiGetPropertyW(hModule, L"CustomActionData", MpInf, &cSize);
- Assert(r == ERROR_SUCCESS);
- if(r == ERROR_SUCCESS)
+ UINT uErr = MsiGetPropertyW(hModule, L"CustomActionData", MpInf, &cSize);
+ if (uErr == ERROR_SUCCESS)
{
- LogString(hModule, TEXT("NetAdpDir property: (%s)"), MpInf);
- if(cSize)
+ if (cSize)
{
- if(MpInf[cSize-1] != L'\\')
+ LogStringW(hModule, TEXT("CreateHostOnlyInterface: NetAdpDir property = %s"), MpInf);
+ if (MpInf[cSize-1] != L'\\')
{
MpInf[cSize] = L'\\';
++cSize;
MpInf[cSize] = L'\0';
}
-// wcscat(MpInf, L"VBoxNetFlt.inf");
+
+ /** @todo r=andy Avoid wcscat, can cause buffer overruns! */
wcscat(MpInf, L"drivers\\network\\netadp\\VBoxNetAdp.inf");
pInfPath = MpInf;
bIsFile = true;
- LogString(hModule, TEXT("Resulting inf path is: (%s)"), pInfPath);
+
+ LogStringW(hModule, TEXT("CreateHostOnlyInterface: Resulting INF path = %s"), pInfPath);
}
else
- {
- LogString(hModule, TEXT("CreateHostOnlyInterface: NetAdpDir property value is empty"));
- }
+ LogStringW(hModule, TEXT("CreateHostOnlyInterface: NetAdpDir property value is empty"));
}
else
- {
- LogString(hModule, TEXT("CreateHostOnlyInterface: failed to get NetAdpDir property, r(%d)"), r);
- }
+ LogStringW(hModule, TEXT("CreateHostOnlyInterface: Failed to get NetAdpDir property, error = 0x%x"), uErr);
- /* make sure the inf file is installed */
- if(!!pInfPath && bIsFile)
+ /* Make sure the inf file is installed. */
+ if (!!pInfPath && bIsFile)
{
- HRESULT tmpHr = VBoxNetCfgWinInstallInf(pInfPath);
- Assert(tmpHr == S_OK);
+ hr = VBoxDrvCfgInfInstall(pInfPath);
+ if (FAILED(hr))
+ LogStringW(hModule, TEXT("CreateHostOnlyInterface: Failed to install INF file, error = 0x%x"), hr);
}
- hr = VBoxNetCfgWinCreateHostOnlyNetworkInterface (pInfPath, bIsFile, &guid, NULL, NULL);
- Assert(hr == S_OK);
- if(hr == S_OK)
+ if (SUCCEEDED(hr))
{
- ULONG ip = inet_addr("192.168.56.1");
- ULONG mask = inet_addr("255.255.255.0");
-
- hr = VBoxNetCfgWinEnableStaticIpConfig(&guid, ip, mask);
- Assert(hr == S_OK);
- if(hr != S_OK)
+ hr = VBoxNetCfgWinCreateHostOnlyNetworkInterface(pInfPath, bIsFile, &guid, NULL, NULL);
+ if (SUCCEEDED(hr))
{
- LogString(hModule, TEXT("CreateHostOnlyInterface: VBoxNetCfgWinEnableStaticIpConfig failed, hr (0x%x)"), hr);
+ ULONG ip = inet_addr("192.168.56.1");
+ ULONG mask = inet_addr("255.255.255.0");
+ hr = VBoxNetCfgWinEnableStaticIpConfig(&guid, ip, mask);
+ if (FAILED(hr))
+ LogStringW(hModule, TEXT("CreateHostOnlyInterface: VBoxNetCfgWinEnableStaticIpConfig failed, error = 0x%x"), hr);
}
- }
- else
- {
- LogString(hModule, TEXT("CreateHostOnlyInterface: VBoxNetCfgWinCreateHostOnlyNetworkInterface failed, hr (0x%x)"), hr);
+ else
+ LogStringW(hModule, TEXT("CreateHostOnlyInterface: VBoxNetCfgWinCreateHostOnlyNetworkInterface failed, error = 0x%x"), hr);
}
- if(bPrevMode)
- {
- /* the prev mode != FALSE, i.e. non-interactive */
- SetupSetNonInteractiveMode(bPrevMode);
- }
+ if (SUCCEEDED(hr))
+ LogStringW(hModule, TEXT("Creating host-only interface done"));
- finiWinNetCfgLogger();
+ /* Restore original setup mode. */
+ if (bSetupModeInteractive)
+ SetupSetNonInteractiveMode(bSetupModeInteractive);
+
+ netCfgLoggerDisable();
- /* never fail the install even if we are not succeeded */
- return ERROR_SUCCESS;
-#else /* not defined VBOX_WITH_NETFLT */
- return ERROR_SUCCESS;
#endif /* VBOX_WITH_NETFLT */
+
+ /* Never fail the install even if we did not succeed. */
+ return ERROR_SUCCESS;
}
UINT __stdcall RemoveHostOnlyInterfaces(MSIHANDLE hModule)
{
#ifdef VBOX_WITH_NETFLT
- inintWinNetCfgLogger(hModule);
+ netCfgLoggerEnable(hModule);
- LogString(hModule, TEXT("Removing All Host-Only Interface"));
+ LogStringW(hModule, TEXT("RemoveHostOnlyInterfaces: Removing All Host-Only Interface"));
- BOOL bPrevMode = SetupSetNonInteractiveMode(FALSE);
+ BOOL bSetupModeInteractive = SetupSetNonInteractiveMode(FALSE);
HRESULT hr = VBoxNetCfgWinRemoveAllNetDevicesOfId(NETADP_ID);
- if(hr == S_OK)
+ if (SUCCEEDED(hr))
{
- hr = VBoxNetCfgWinUninstallInfs(&GUID_DEVCLASS_NET, NETADP_ID, 0/* could be SUOI_FORCEDELETE */);
- if(hr != S_OK)
+ hr = VBoxDrvCfgInfUninstallAllSetupDi(&GUID_DEVCLASS_NET, NETADP_ID, L"Net", 0/* could be SUOI_FORCEDELETE */);
+ if (FAILED(hr))
{
- LogString(hModule, TEXT("NetAdp uninstalled successfully, but failed to remove infs\n"));
+ LogStringW(hModule, TEXT("RemoveHostOnlyInterfaces: NetAdp uninstalled successfully, but failed to remove infs\n"));
}
}
else
- {
- LogString(hModule, TEXT("NetAdp uninstall failed, hr = 0x%x\n"), hr);
- }
+ LogStringW(hModule, TEXT("RemoveHostOnlyInterfaces: NetAdp uninstall failed, hr = 0x%x\n"), hr);
- if(bPrevMode)
- {
- /* the prev mode != FALSE, i.e. non-interactive */
- SetupSetNonInteractiveMode(bPrevMode);
- }
+ /* Restore original setup mode. */
+ if (bSetupModeInteractive)
+ SetupSetNonInteractiveMode(bSetupModeInteractive);
- finiWinNetCfgLogger();
+ netCfgLoggerDisable();
+#endif /* VBOX_WITH_NETFLT */
+ /* Never fail the install even if we did not succeed. */
return ERROR_SUCCESS;
-#else /* not defined VBOX_WITH_NETFLT */
- return ERROR_SUCCESS;
-#endif /* VBOX_WITH_NETFLT */
}
-static bool IsTAPDevice (const TCHAR *a_pcGUID)
+static bool IsTAPDevice(const TCHAR *pcGUID)
{
HKEY hNetcard;
- LONG status;
- DWORD len;
- int i = 0;
- bool ret = false;
-
- status = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
- TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),
- 0, KEY_READ, &hNetcard);
-
- if (status != ERROR_SUCCESS)
+ bool bIsTapDevice = false;
+ LONG lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),
+ 0, KEY_READ, &hNetcard);
+ if (lStatus != ERROR_SUCCESS)
return false;
- while(true)
+ int i = 0;
+ while (true)
{
TCHAR szEnumName[256];
TCHAR szNetCfgInstanceId[256];
DWORD dwKeyType;
HKEY hNetCardGUID;
- len = sizeof(szEnumName);
- status = RegEnumKeyEx (hNetcard, i, szEnumName, &len, NULL, NULL, NULL, NULL);
- if (status != ERROR_SUCCESS)
+ DWORD dwLen = sizeof(szEnumName);
+ lStatus = RegEnumKeyEx(hNetcard, i, szEnumName, &dwLen, NULL, NULL, NULL, NULL);
+ if (lStatus != ERROR_SUCCESS)
break;
- status = RegOpenKeyEx (hNetcard, szEnumName, 0, KEY_READ, &hNetCardGUID);
- if (status == ERROR_SUCCESS)
+ lStatus = RegOpenKeyEx(hNetcard, szEnumName, 0, KEY_READ, &hNetCardGUID);
+ if (lStatus == ERROR_SUCCESS)
{
- len = sizeof (szNetCfgInstanceId);
- status = RegQueryValueEx (hNetCardGUID, TEXT("NetCfgInstanceId"), NULL, &dwKeyType, (LPBYTE)szNetCfgInstanceId, &len);
- if (status == ERROR_SUCCESS && dwKeyType == REG_SZ)
+ dwLen = sizeof(szNetCfgInstanceId);
+ lStatus = RegQueryValueEx(hNetCardGUID, TEXT("NetCfgInstanceId"), NULL, &dwKeyType, (LPBYTE)szNetCfgInstanceId, &dwLen);
+ if ( lStatus == ERROR_SUCCESS
+ && dwKeyType == REG_SZ)
{
TCHAR szNetProductName[256];
TCHAR szNetProviderName[256];
szNetProductName[0] = 0;
- len = sizeof(szNetProductName);
- status = RegQueryValueEx (hNetCardGUID, TEXT("ProductName"), NULL, &dwKeyType, (LPBYTE)szNetProductName, &len);
+ dwLen = sizeof(szNetProductName);
+ lStatus = RegQueryValueEx(hNetCardGUID, TEXT("ProductName"), NULL, &dwKeyType, (LPBYTE)szNetProductName, &dwLen);
szNetProviderName[0] = 0;
- len = sizeof(szNetProviderName);
- status = RegQueryValueEx (hNetCardGUID, TEXT("ProviderName"), NULL, &dwKeyType, (LPBYTE)szNetProviderName, &len);
+ dwLen = sizeof(szNetProviderName);
+ lStatus = RegQueryValueEx(hNetCardGUID, TEXT("ProviderName"), NULL, &dwKeyType, (LPBYTE)szNetProviderName, &dwLen);
- if ( !wcscmp(szNetCfgInstanceId, a_pcGUID)
+ if ( !wcscmp(szNetCfgInstanceId, pcGUID)
&& !wcscmp(szNetProductName, TEXT("VirtualBox TAP Adapter"))
&& ( (!wcscmp(szNetProviderName, TEXT("innotek GmbH"))) /* Legacy stuff. */
|| (!wcscmp(szNetProviderName, TEXT("Sun Microsystems, Inc."))) /* Legacy stuff. */
@@ -1025,7 +1005,7 @@ static bool IsTAPDevice (const TCHAR *a_pcGUID)
)
)
{
- ret = true;
+ bIsTapDevice = true;
RegCloseKey(hNetCardGUID);
break;
}
@@ -1036,7 +1016,7 @@ static bool IsTAPDevice (const TCHAR *a_pcGUID)
}
RegCloseKey (hNetcard);
- return ret;
+ return bIsTapDevice;
}
#define VBOX_TAP_HWID _T("vboxtap")
@@ -1044,11 +1024,11 @@ static bool IsTAPDevice (const TCHAR *a_pcGUID)
#define SetErrBreak(strAndArgs) \
if (1) { \
rc = 0; \
- LogString (a_hModule, strAndArgs); \
+ LogStringW(hModule, strAndArgs); \
break; \
} else do {} while (0)
-int removeNetworkInterface (MSIHANDLE a_hModule, const TCHAR* pcGUID)
+int removeNetworkInterface(MSIHANDLE hModule, const TCHAR* pcGUID)
{
int rc = 1;
do
@@ -1067,30 +1047,30 @@ int removeNetworkInterface (MSIHANDLE a_hModule, const TCHAR* pcGUID)
TEXT("SYSTEM\\CurrentControlSet\\Control\\Network\\")
TEXT("{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s"),
pcGUID);
- LONG status;
- status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, strRegLocation, 0,
+ LONG lStatus;
+ lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strRegLocation, 0,
KEY_READ, &hkeyNetwork);
- if ((status != ERROR_SUCCESS) || !hkeyNetwork)
- SetErrBreak ((TEXT("VBox HostInterfaces: Host interface network was not found in registry (%s)! [1]"), strRegLocation));
+ if ((lStatus != ERROR_SUCCESS) || !hkeyNetwork)
+ SetErrBreak((TEXT("VBox HostInterfaces: Host interface network was not found in registry (%s)! [1]"), strRegLocation));
- status = RegOpenKeyExA (hkeyNetwork, "Connection", 0,
+ lStatus = RegOpenKeyExA(hkeyNetwork, "Connection", 0,
KEY_READ, &hkeyConnection);
- if ((status != ERROR_SUCCESS) || !hkeyConnection)
- SetErrBreak ((TEXT("VBox HostInterfaces: Host interface network was not found in registry (%s)! [2]"), strRegLocation));
+ if ((lStatus != ERROR_SUCCESS) || !hkeyConnection)
+ SetErrBreak((TEXT("VBox HostInterfaces: Host interface network was not found in registry (%s)! [2]"), strRegLocation));
DWORD len = sizeof (lszPnPInstanceId);
DWORD dwKeyType;
- status = RegQueryValueExW (hkeyConnection, L"PnPInstanceID", NULL,
+ lStatus = RegQueryValueExW(hkeyConnection, L"PnPInstanceID", NULL,
&dwKeyType, (LPBYTE) lszPnPInstanceId, &len);
- if ((status != ERROR_SUCCESS) || (dwKeyType != REG_SZ))
- SetErrBreak ((TEXT("VBox HostInterfaces: Host interface network was not found in registry (%s)! [3]"), strRegLocation));
+ if ((lStatus != ERROR_SUCCESS) || (dwKeyType != REG_SZ))
+ SetErrBreak((TEXT("VBox HostInterfaces: Host interface network was not found in registry (%s)! [3]"), strRegLocation));
}
while (0);
if (hkeyConnection)
- RegCloseKey (hkeyConnection);
+ RegCloseKey(hkeyConnection);
if (hkeyNetwork)
- RegCloseKey (hkeyNetwork);
+ RegCloseKey(hkeyNetwork);
/*
* Now we are going to enumerate all network devices and
@@ -1098,40 +1078,39 @@ int removeNetworkInterface (MSIHANDLE a_hModule, const TCHAR* pcGUID)
*/
HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
+ BOOL fResult;
do
{
- BOOL ok;
DWORD ret = 0;
GUID netGuid;
SP_DEVINFO_DATA DeviceInfoData;
DWORD index = 0;
- BOOL found = FALSE;
DWORD size = 0;
/* initialize the structure size */
- DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
+ DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
/* copy the net class GUID */
- memcpy (&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET));
+ memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET));
/* return a device info set contains all installed devices of the Net class */
- hDeviceInfo = SetupDiGetClassDevs (&netGuid, NULL, NULL, DIGCF_PRESENT);
-
+ hDeviceInfo = SetupDiGetClassDevs(&netGuid, NULL, NULL, DIGCF_PRESENT);
if (hDeviceInfo == INVALID_HANDLE_VALUE)
{
- LogString (a_hModule, TEXT("VBox HostInterfaces: SetupDiGetClassDevs failed (0x%08X)!"), GetLastError());
- SetErrBreak (TEXT("VBox HostInterfaces: Uninstallation failed!"));
+ LogStringW(hModule, TEXT("VBox HostInterfaces: SetupDiGetClassDevs failed (0x%08X)!"), GetLastError());
+ SetErrBreak(TEXT("VBox HostInterfaces: Uninstallation failed!"));
}
+ BOOL fFoundDevice = FALSE;
+
/* enumerate the driver info list */
while (TRUE)
{
- TCHAR *deviceHwid;
+ TCHAR *pszDeviceHwid;
- ok = SetupDiEnumDeviceInfo (hDeviceInfo, index, &DeviceInfoData);
-
- if (!ok)
+ fResult = SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData);
+ if (!fResult)
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
break;
@@ -1143,14 +1122,14 @@ int removeNetworkInterface (MSIHANDLE a_hModule, const TCHAR* pcGUID)
}
/* try to get the hardware ID registry property */
- ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
- &DeviceInfoData,
- SPDRP_HARDWAREID,
- NULL,
- NULL,
- 0,
- &size);
- if (!ok)
+ fResult = SetupDiGetDeviceRegistryProperty(hDeviceInfo,
+ &DeviceInfoData,
+ SPDRP_HARDWAREID,
+ NULL,
+ NULL,
+ 0,
+ &size);
+ if (!fResult)
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
@@ -1158,20 +1137,23 @@ int removeNetworkInterface (MSIHANDLE a_hModule, const TCHAR* pcGUID)
continue;
}
- deviceHwid = (TCHAR *) malloc (size);
- ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
- &DeviceInfoData,
- SPDRP_HARDWAREID,
- NULL,
- (PBYTE)deviceHwid,
- size,
- NULL);
- if (!ok)
+ pszDeviceHwid = (TCHAR *)malloc(size);
+ if (pszDeviceHwid)
{
- free (deviceHwid);
- deviceHwid = NULL;
- index++;
- continue;
+ fResult = SetupDiGetDeviceRegistryProperty(hDeviceInfo,
+ &DeviceInfoData,
+ SPDRP_HARDWAREID,
+ NULL,
+ (PBYTE)pszDeviceHwid,
+ size,
+ NULL);
+ if (!fResult)
+ {
+ free(pszDeviceHwid);
+ pszDeviceHwid = NULL;
+ index++;
+ continue;
+ }
}
}
else
@@ -1181,11 +1163,11 @@ int removeNetworkInterface (MSIHANDLE a_hModule, const TCHAR* pcGUID)
continue;
}
- for (TCHAR *t = deviceHwid;
- t && *t && t < &deviceHwid[size / sizeof(TCHAR)];
+ for (TCHAR *t = pszDeviceHwid;
+ t && *t && t < &pszDeviceHwid[size / sizeof(TCHAR)];
t += _tcslen (t) + 1)
{
- if (!_tcsicmp (VBOX_TAP_HWID, t))
+ if (!_tcsicmp(VBOX_TAP_HWID, t))
{
/* get the device instance ID */
TCHAR devID [MAX_DEVICE_ID_LEN];
@@ -1193,83 +1175,82 @@ int removeNetworkInterface (MSIHANDLE a_hModule, const TCHAR* pcGUID)
devID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS)
{
/* compare to what we determined before */
- if (wcscmp(devID, lszPnPInstanceId) == 0)
+ if (!wcscmp(devID, lszPnPInstanceId))
{
- found = TRUE;
+ fFoundDevice = TRUE;
break;
}
}
}
}
- if (deviceHwid)
+ if (pszDeviceHwid)
{
- free (deviceHwid);
- deviceHwid = NULL;
+ free(pszDeviceHwid);
+ pszDeviceHwid = NULL;
}
- if (found)
+ if (fFoundDevice)
break;
index++;
}
- if (found == FALSE)
- SetErrBreak (TEXT("VBox HostInterfaces: Host Interface Network driver not found!"));
-
- ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
- if (!ok)
+ if (fFoundDevice)
{
- LogString (a_hModule, TEXT("VBox HostInterfaces: SetupDiSetSelectedDevice failed (0x%08X)!"), GetLastError());
- SetErrBreak (TEXT("VBox HostInterfaces: Uninstallation failed!"));
- }
+ fResult = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData);
+ if (!fResult)
+ {
+ LogStringW(hModule, TEXT("VBox HostInterfaces: SetupDiSetSelectedDevice failed (0x%08X)!"), GetLastError());
+ SetErrBreak(TEXT("VBox HostInterfaces: Uninstallation failed!"));
+ }
- ok = SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
- if (!ok)
- {
- LogString (a_hModule, TEXT("VBox HostInterfaces: SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)!"), GetLastError());
- SetErrBreak (TEXT("VBox HostInterfaces: Uninstallation failed!"));
+ fResult = SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
+ if (!fResult)
+ {
+ LogStringW(hModule, TEXT("VBox HostInterfaces: SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)!"), GetLastError());
+ SetErrBreak(TEXT("VBox HostInterfaces: Uninstallation failed!"));
+ }
}
+ else
+ SetErrBreak(TEXT("VBox HostInterfaces: Host interface network device not found!"));
}
while (0);
/* clean up the device info set */
if (hDeviceInfo != INVALID_HANDLE_VALUE)
- SetupDiDestroyDeviceInfoList (hDeviceInfo);
+ SetupDiDestroyDeviceInfoList(hDeviceInfo);
}
while (0);
return rc;
}
-UINT __stdcall UninstallTAPInstances (MSIHANDLE a_hModule)
+UINT __stdcall UninstallTAPInstances(MSIHANDLE hModule)
{
static const TCHAR *NetworkKey = TEXT("SYSTEM\\CurrentControlSet\\Control\\Network\\")
TEXT("{4D36E972-E325-11CE-BFC1-08002BE10318}");
HKEY hCtrlNet;
- LONG status = 0;
- DWORD len = 0;
- LONG cnt = 0;
- status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, NetworkKey, 0, KEY_READ, &hCtrlNet);
- if (status == ERROR_SUCCESS)
+ LONG lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NetworkKey, 0, KEY_READ, &hCtrlNet);
+ if (lStatus == ERROR_SUCCESS)
{
- LogString(a_hModule, TEXT("VBox HostInterfaces: Enumerating interfaces ..."));
+ LogStringW(hModule, TEXT("VBox HostInterfaces: Enumerating interfaces ..."));
for (int i = 0;; ++ i)
{
TCHAR szNetworkGUID [256] = { 0 };
TCHAR szNetworkConnection [256] = { 0 };
- len = sizeof (szNetworkGUID);
- status = RegEnumKeyEx (hCtrlNet, i, szNetworkGUID, &len, NULL, NULL, NULL, NULL);
- if (status != ERROR_SUCCESS)
+ DWORD dwLen = (DWORD)sizeof(szNetworkGUID);
+ lStatus = RegEnumKeyEx(hCtrlNet, i, szNetworkGUID, &dwLen, NULL, NULL, NULL, NULL);
+ if (lStatus != ERROR_SUCCESS)
{
- switch (status)
+ switch (lStatus)
{
case ERROR_NO_MORE_ITEMS:
- LogString(a_hModule, TEXT("VBox HostInterfaces: No interfaces found."));
+ LogStringW(hModule, TEXT("VBox HostInterfaces: No interfaces found."));
break;
default:
- LogString(a_hModule, TEXT("VBox HostInterfaces: Enumeration failed: %ld"), status);
+ LogStringW(hModule, TEXT("VBox HostInterfaces: Enumeration failed: %ld"), lStatus);
break;
};
break;
@@ -1277,13 +1258,13 @@ UINT __stdcall UninstallTAPInstances (MSIHANDLE a_hModule)
if (IsTAPDevice(szNetworkGUID))
{
- LogString(a_hModule, TEXT("VBox HostInterfaces: Removing interface \"%s\" ..."), szNetworkGUID);
- removeNetworkInterface (a_hModule, szNetworkGUID);
- status = RegDeleteKey (hCtrlNet, szNetworkGUID);
+ LogStringW(hModule, TEXT("VBox HostInterfaces: Removing interface \"%s\" ..."), szNetworkGUID);
+ removeNetworkInterface (hModule, szNetworkGUID);
+ lStatus = RegDeleteKey (hCtrlNet, szNetworkGUID);
}
}
RegCloseKey (hCtrlNet);
- LogString(a_hModule, TEXT("VBox HostInterfaces: Removing interfaces done."));
+ LogStringW(hModule, TEXT("VBox HostInterfaces: Removing interfaces done."));
}
return ERROR_SUCCESS;
}
diff --git a/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.def b/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.def
index cfe118b94..27f50954e 100644
--- a/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.def
+++ b/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.def
@@ -1,4 +1,4 @@
-; $Id: VBoxInstallHelper.def $
+; $Id: VBoxInstallHelper.def 32112 2010-08-31 08:44:09Z vboxsync $
;; @file
; VBoxInstallHelper - Defines the exports the MSI engine uses.
;
diff --git a/src/VBox/Installer/win/Languages/de_DE.wxl b/src/VBox/Installer/win/Languages/de_DE.wxl
index 24b6e8c1a..f8cb24bdd 100644
--- a/src/VBox/Installer/win/Languages/de_DE.wxl
+++ b/src/VBox/Installer/win/Languages/de_DE.wxl
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="utf-8"?>
-<WixLocalization xmlns="http://schemas.microsoft.com/wix/2003/11/localization" Codepage='1252'>
+<?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) 2010 Oracle Corporation
+ Copyright (C) 2011 Oracle Corporation
All rights reserved.
-->
diff --git a/src/VBox/Installer/win/Languages/en_US.wxl b/src/VBox/Installer/win/Languages/en_US.wxl
index 26fa3c773..82da635a5 100644
--- a/src/VBox/Installer/win/Languages/en_US.wxl
+++ b/src/VBox/Installer/win/Languages/en_US.wxl
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
-<WixLocalization xmlns="http://schemas.microsoft.com/wix/2003/11/localization" Codepage='1252'>
+<WixLocalization xmlns="http://schemas.microsoft.com/wix/2003/11/localization" Codepage="1252" Culture="en_US">
<!--
Language Definition Include for VirtualBox WiX script.
- Copyright (C) 2010 Oracle Corporation
+ Copyright (C) 2011 Oracle Corporation
All rights reserved.
-->
diff --git a/src/VBox/Installer/win/Languages/fr_FR.wxl b/src/VBox/Installer/win/Languages/fr_FR.wxl
index 1615ab65a..58b3ac6a4 100644
--- a/src/VBox/Installer/win/Languages/fr_FR.wxl
+++ b/src/VBox/Installer/win/Languages/fr_FR.wxl
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<WixLocalization xmlns="http://schemas.microsoft.com/wix/2003/11/localization" Codepage='1252'>
+<WixLocalization xmlns="http://schemas.microsoft.com/wix/2003/11/localization" Codepage="1252" Culture="fr_FR">
<!--
Language Definition Include for VirtualBox WiX script.
diff --git a/src/VBox/Installer/win/Makefile.kmk b/src/VBox/Installer/win/Makefile.kmk
index df7ff83b1..aa76e3caa 100644
--- a/src/VBox/Installer/win/Makefile.kmk
+++ b/src/VBox/Installer/win/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37622 2011-06-24 07:11:33Z vboxsync $
## @file
# Makefile for the Windows installer.
#
@@ -106,7 +106,8 @@ OTHER_CLEAN += \
$(VBOX_WIN_INST_OUT_DIR)/VirtualBox_$(lang).wixobj \
$(VBOX_WIN_INST_OUT_DIR)/$(PACKAGE_NAME_LANG)_$(lang).msi) \
$(VBOX_WIN_INST_OUT_DIR)/Files_Doc.wxi \
- $(VBOX_WIN_INST_OUT_DIR)/Files_License.wxi
+ $(VBOX_WIN_INST_OUT_DIR)/Files_License.wxi \
+ $(VBOX_WIN_INST_OUT_DIR)/Shortcuts_StartMenu.wxi
ifdef VBOX_WITH_COMBINED_PACKAGE
ifeq ($(KBUILD_TARGET_ARCH),x86)
@@ -145,6 +146,13 @@ ifdef VBOX_WITH_BUNDLED_INSTALLER
PACKING.win += $(VBOX_PATH_PACK_BUNDLE_ZIP)
endif
+#
+# Surpress/skip the following ICE (internal consistency evaluators):
+# - ICE64: Checks that new directories in the user profile are removed correctly in roaming scenarios.
+# -> We don't want to remove system folders (like "Microsoft/Internet Explorer/Quick Launch").
+#
+VBOX_MSI_ICE_IGNORE := \
+ -ice:64
#
# Create intermediate XML file for languages (needed for .MSI linking).
@@ -181,7 +189,7 @@ define def_vbox_license_xml
$(VBOX_WIN_INST_OUT_DIR)/Languages/License_$(lang).wxl: $(license_file) $(MAKEFILE_CURRENT) | $$$$(dir $$$$@)
$$(call MSG_GENERATE,,$$@,$$<)
$(APPEND) -t $$@ '<?xml version="1.0" encoding="utf-8"?>'
- $(APPEND) $$@ '<WixLocalization xmlns="http://schemas.microsoft.com/wix/2003/11/localization" Codepage="1252">'
+ $(APPEND) $$@ '<WixLocalization xmlns="http://schemas.microsoft.com/wix/2006/localization" Codepage="1252" Culture="$(lang)">'
$(REDIRECT) -a+to $$@ -- $(ECHO_EXT) -n '<String Id=\"LicenseText\">'
$(REDIRECT) -a+to $$@ -- $(SED) -e "s|<|\&lt;|g" -e "s|>|\&gt;|g" $(license_file)
@@ -209,40 +217,64 @@ $(foreach lang,$(VBOX_INSTALLER_LANGUAGES), \
$(VBOX_WIN_INST_OUT_DIR)/Files_Main.wxi: $(MAKEFILE_CURRENT) | $$(dir $$@)
$(call MSG_GENERATE,,$@,$<)
$(APPEND) -t $@ '<?xml version="1.0" ?>'
- $(APPEND) $@ '<Include>'
+ $(APPEND) $@ '<Include xmlns="http://schemas.microsoft.com/wix/2006/wi">'
ifdef VBOX_WITH_DOCS_CHM
- $(APPEND) $@ ' <File Id="VirtualBox.chm" Name="VBox.chm" LongName="VirtualBox.chm" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$(PATH_BIN)/VirtualBox.chm"></File>'
+ $(APPEND) $@ ' <File Id="file_VirtualBox.chm" Name="VirtualBox.chm" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$(PATH_BIN)/VirtualBox.chm"></File>'
$(APPEND) -n $@ $(foreach lang,$(VBOX_MANUAL_ADD_LANGUAGES), \
- ' <File Id="VirtualBox_$(lang).chm" Name="VB_$(lang).chm" LongName="VirtualBox_$(lang).chm" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$(PATH_BIN)/VirtualBox_$(lang).chm"></File>')
+ ' <File Id="file_VirtualBox_$(lang).chm" Name="VirtualBox_$(lang).chm" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$(PATH_BIN)/VirtualBox_$(lang).chm"></File>')
endif
$(APPEND) $@ '</Include>'
$(VBOX_WIN_INST_OUT_DIR)/Files_Doc.wxi: $(MAKEFILE_CURRENT) | $$(dir $$@)
$(call MSG_GENERATE,,$@,$<)
$(APPEND) -t $@ '<?xml version="1.0" ?>'
- $(APPEND) $@ '<Include>'
- $(APPEND) $@ ' <File Id="UserManual.pdf" Name="Manual.pdf" LongName="UserManual.pdf" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$(PATH_BIN)/UserManual.pdf">'
- $(APPEND) $@ ' <Shortcut Id="startmenuManPDF_en_US" Directory="ProgramMenuDir" Name="M_en_US" LongName="$$(loc.StartMenu_UserManual) (English)" WorkingDirectory="INSTALLDIR"/>'
+ $(APPEND) $@ '<Include xmlns="http://schemas.microsoft.com/wix/2006/wi">'
+ $(APPEND) $@ ' <File Id="file_UserManual.pdf" Name="UserManual.pdf" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$(PATH_BIN)/UserManual.pdf">'
$(APPEND) $@ ' </File>'
$(APPEND) -n $@ $(foreach lang,$(VBOX_MANUAL_ADD_LANGUAGES), \
- ' <File Id="UserManual_$(lang).pdf" Name="Mn_$(lang).pdf" LongName="UserManual_$(lang).pdf" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$(PATH_BIN)/UserManual_$(lang).pdf">' \
- ' <Shortcut Id="startmenuManPDF_$(lang)" Directory="ProgramMenuDir" Name="M_$(lang)" LongName="$$(loc.StartMenu_UserManual) ($(VBOX_BRAND_$(lang)_LANG_NAME))" WorkingDirectory="INSTALLDIR"/>' \
+ ' <File Id="file_UserManual_$(lang).pdf" Name="UserManual_$(lang).pdf" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$(PATH_BIN)/UserManual_$(lang).pdf">' \
' </File>')
$(APPEND) $@ '</Include>'
$(VBOX_WIN_INST_OUT_DIR)/Files_License.wxi: $(MAKEFILE_CURRENT) | $$(dir $$@)
$(call MSG_GENERATE,,$@,$<)
$(APPEND) -t $@ '<?xml version="1.0" ?>'
- $(APPEND) $@ '<Include>'
- $(APPEND) $@ ' <File Id="License_en_US.rtf" Name="Li_en_US.rtf" LongName="License_en_US.rtf" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$(VBOX_BRAND_LICENSE_RTF)">'
- $(APPEND) $@ ' <Shortcut Id="startmenuLicRTF_en_US" Directory="ProgramMenuDir" Name="L_en_US" LongName="$$(loc.StartMenu_License) (English)" WorkingDirectory="INSTALLDIR"/>'
- $(APPEND) $@ ' </File>'
+ $(APPEND) $@ '<Include xmlns="http://schemas.microsoft.com/wix/2006/wi">'
+ $(APPEND) $@ ' <File Id="file_License_en_US.rtf" Name="License_en_US.rtf" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$(VBOX_BRAND_LICENSE_RTF)">' \
+ ' </File>'
$(APPEND) -n $@ $(foreach lang,$(VBOX_MANUAL_ADD_LANGUAGES), \
- ' <File Id="License_$(lang).rtf" Name="Li_$(lang).rtf" LongName="License_$(lang).rtf" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$(VBOX_BRAND_$(lang)_LICENSE_RTF)">' \
- ' <Shortcut Id="startmenuLicRTF_$(lang)" Directory="ProgramMenuDir" Name="L_$(lang)" LongName="$$(loc.StartMenu_License) ($(VBOX_BRAND_$(lang)_LANG_NAME))" WorkingDirectory="INSTALLDIR"/>' \
+ ' <File Id="file_License_$(lang).rtf" Name="License_$(lang).rtf" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$(VBOX_BRAND_$(lang)_LICENSE_RTF)"/>' \
' </File>')
$(APPEND) $@ '</Include>'
+$(VBOX_WIN_INST_OUT_DIR)/Shortcuts_StartMenu.wxi: $(MAKEFILE_CURRENT) | $$(dir $$@)
+ $(call MSG_GENERATE,,$@,$<)
+ $(APPEND) -t $@ '<?xml version="1.0" ?>'
+ $(APPEND) $@ '<Include xmlns="http://schemas.microsoft.com/wix/2006/wi">'
+ #
+ # Documentation (PDF/CHM)
+ #
+ ifdef VBOX_WITH_DOCS_CHM
+ $(APPEND) $@ ' <Shortcut Id="sc_StartMenu_ManualCHM_en_US" Directory="dir_StartMenuVBox" Name="!(loc.StartMenu_UserManual) (CHM, English)" Description="!(loc.StartMenu_UserManual)"' \
+ ' Target="[INSTALLDIR]\doc\VirtualBox.chm" WorkingDirectory="dir_Documents" Advertise="no"/>'
+ $(APPEND) -n $@ $(foreach lang,$(VBOX_MANUAL_ADD_LANGUAGES), \
+ ' <Shortcut Id="sc_StartMenu_ManualCHM_$(lang)" Directory="dir_StartMenuVBox" Name="$!(loc.StartMenu_UserManual) (CHM, $(VBOX_BRAND_$(lang)_LANG_NAME))"' \
+ ' Description="$!(loc.StartMenu_UserManual) ($(VBOX_BRAND_$(lang)_LANG_NAME))" Target="[INSTALLDIR]\doc\VirtualBox_$(lang).chm" WorkingDirectory="dir_Documents"/>')
+ endif
+ $(APPEND) $@ ' <Shortcut Id="sc_StartMenu_ManualPDF_en_US" Directory="dir_StartMenuVBox" Name="!(loc.StartMenu_UserManual) (PDF, English)" Description="!(loc.StartMenu_UserManual)"' \
+ ' Target="[INSTALLDIR]\doc\UserManual.pdf" WorkingDirectory="dir_Documents" Advertise="no"/>'
+ $(APPEND) -n $@ $(foreach lang,$(VBOX_MANUAL_ADD_LANGUAGES), \
+ ' <Shortcut Id="sc_StartMenu_ManualPDF_$(lang)" Directory="dir_StartMenuVBox" Name="$!(loc.StartMenu_UserManual) (PDF, $(VBOX_BRAND_$(lang)_LANG_NAME))"' \
+ ' Description="$!(loc.StartMenu_UserManual) ($(VBOX_BRAND_$(lang)_LANG_NAME))" Target="[INSTALLDIR]\doc\UserManual_$(lang).pdf" WorkingDirectory="dir_Documents"/>')
+ #
+ # License(s) (RTF)
+ #
+ $(APPEND) $@ ' <Shortcut Id="sc_StartMenu_License_en_US" Directory="dir_StartMenuVBox" Name="!(loc.StartMenu_License) (English)" Description="!(loc.StartMenu_License)"' \
+ ' Target="[INSTALLDIR]License_en_US.rtf" WorkingDirectory="INSTALLDIR" Advertise="no"/>'
+ $(APPEND) -n $@ $(foreach lang,$(VBOX_MANUAL_ADD_LANGUAGES), \
+ ' <Shortcut Id="sc_StartMenu_License_$(lang)" Directory="dir_StartMenuVBox" Name="$!(loc.StartMenu_License) ($(VBOX_BRAND_$(lang)_LANG_NAME))"' \
+ ' Description="$!(loc.StartMenu_License) ($(VBOX_BRAND_$(lang)_LANG_NAME))" Target="License_$(lang).rtf" WorkingDirectory="INSTALLDIR"/>')
+ $(APPEND) $@ '</Include>'
#
# .MSI link (all languages).
@@ -263,10 +295,14 @@ $(VBOX_WIN_INST_OUT_DIR)/$(PACKAGE_NAME_LANG)_$(lang).msi: \
$(VBOX_PATH_WIX)/light.exe -nologo \
-loc $(VBOX_WIN_INST_OUT_DIR)/Languages/Language_$(lang).wxl \
-loc $(VBOX_WIN_INST_OUT_DIR)/Languages/License_$(lang).wxl \
+ -ext $(VBOX_PATH_WIX)/WixUIExtension.dll \
+ -ext $(VBOX_PATH_WIX)/WixDifxAppExtension.dll \
+ $(VBOX_MSI_ICE_IGNORE) \
-out $$@ \
$$< \
- $(VBOX_PATH_WIX)/wixca.wixlib \
- $(VBOX_PATH_DIFX)/DIFxApp.wixlib
+ $(if-expr "$(KBUILD_TARGET_ARCH)" == "x86", \
+ $(VBOX_PATH_WIX)/difxapp_x86.wixlib, \
+ $(VBOX_PATH_WIX)/difxapp_x64.wixlib)
$(RM) -f $(VBOX_WIN_INST_OUT_DIR)/Languages/$(lang).mst
$(call VBOX_SIGN_FILE_FN,$$@)
endef
@@ -280,7 +316,6 @@ $(foreach lang,$(VBOX_INSTALLER_LANGUAGES), $(eval $(def_vbox_link_msi)))
-include $(VBOX_WIN_INST_OUT_DIR)/VirtualBox.wixobj.dep
# Filter out some files depending on build type and compiler.
-VBOX_MSI_DEPENDENCIES := $(filter-out wixca.dll, $(VBOX_MSI_DEPENDENCIES))
ifeq ($(KBUILD_TYPE),release)
VBOX_MSI_DEPENDENCIES := $(filer-out $(PATH_OUT)/bin/VBoxDbg3.dll, $(VBOX_MSI_DEPENDENCIES))
endif
@@ -302,6 +337,39 @@ else
$(PATH_OUT)/bin/Microsoft.VC80.CRT/msvcm80.dll \
, $(VBOX_MSI_DEPENDENCIES))
endif
+# TODO: Add filtering out more dependencies here!
+ifndef VBOX_WITH_QTGUI
+ $(PATH_OUT)/bin/VirtualBox.exe \
+ $(PATH_OUT)/bin/VBoxTestOGL.exe \
+ $(PATH_OUT)/bin/QtCoreVBox4.dll \
+ $(PATH_OUT)/bin/QtGuiVBox4.dll \
+ $(PATH_OUT)/bin/QtNetworkVBox4.dll \
+ $(PATH_OUT)/bin/QtOpenGLVBox4.dll \
+ $(PATH_OUT)/bin/accessible/qtaccessiblewidgets4.dll \
+ , $(VBOX_MSI_DEPENDENCIES))
+endif
+ifndef VBOX_WITH_PYTHON
+ VBOX_MSI_DEPENDENCIES := $(filer-out $ \
+ $(PATH_OUT)/bin/sdk/installer/vboxapisetup.py \
+ $(PATH_OUT)/bin/sdk/installer/vboxapi/__init__.py \
+ $(PATH_OUT)/bin/sdk/installer/vboxapi/VirtualBox_constants.py \
+ , $(VBOX_MSI_DEPENDENCIES))
+endif
+ifndef VBOX_WITH_CROGL
+ VBOX_MSI_DEPENDENCIES := $(filer-out $ \
+ $(PATH_OUT)/bin/VBoxOGLhostcrutil.dll \
+ $(PATH_OUT)/bin/VBoxOGLhosterrorspu.dll \
+ $(PATH_OUT)/bin/VBoxOGLrenderspu.dll \
+ $(PATH_OUT)/bin/VBoxSharedCrOpenGL.dll \
+ , $(VBOX_MSI_DEPENDENCIES))
+endif
+ifndef VBOX_WITH_SECURELABEL
+ VBOX_MSI_DEPENDENCIES := $(filer-out $(PATH_OUT)/bin/SDL_ttf.dll, $(VBOX_MSI_DEPENDENCIES))
+endif
+ifndef VBOX_WITH_WEBSERVICES
+ VBOX_MSI_DEPENDENCIES := $(filer-out $(PATH_OUT)/bin/vboxwebsrv.exe, $(VBOX_MSI_DEPENDENCIES))
+endif
+
ifneq ($(KBUILD_TARGET_ARCH),amd64)
VBOX_MSI_DEPENDENCIES := $(filter-out \
$(PATH_OUT)/bin/VBoxREM2.rel \
@@ -383,7 +451,10 @@ $(VBOX_WIN_INST_OUT_DIR)/VirtualBox_$(lang).wixobj: \
-E 'BUILD_TARGET_ARCH=$(KBUILD_TARGET_ARCH)' \
-E 'VBOX_USE_VCC80=$(if $(VBOX_USE_VCC80),yes,no)' \
-- \
- $(VBOX_PATH_WIX)/candle.exe $(filter-out $(VBOX_VERSION_STAMP),$$<) -out $$@
+ $(VBOX_PATH_WIX)/candle.exe $(filter-out $(VBOX_VERSION_STAMP),$$<) \
+ -ext $(VBOX_PATH_WIX)/WixUIExtension.dll \
+ -ext $(VBOX_PATH_WIX)/WixDifxAppExtension.dll \
+ -out $$@
ifeq ($(lang),en_US)
#
# Generate dependency file, we share this between all the languages.
@@ -419,8 +490,8 @@ $(VBOX_WIN_INST_OUT_DIR)/VBoxGuiNLS.wxi: $(PATH_ROOT)/src/VBox/Frontends/Virtual
$(APPEND) -t $@ '<?xml version="1.0" ?>'
$(APPEND) $@ '<Include>'
$(APPEND) -n $@ $(foreach lang,$(VBOX_APPROVED_GUI_LANGUAGES), \
- ' <File Id="nlsqt${lang}" Name="qt_${lang}.qm" LongName="qt_${lang}.qm" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" src="$$(env.PATH_OUT)\bin\nls\qt_${lang}.qm" />' \
- ' <File Id="nlsgui${lang}" Name="vb_${lang}.qm" LongName="VirtualBox_${lang}.qm" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" src="$$(env.PATH_OUT)\bin\nls\VirtualBox_${lang}.qm" />')
+ ' <File Id="nlsqt${lang}" Name="qt_${lang}.qm" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$$(env.PATH_OUT)\bin\nls\qt_${lang}.qm" />' \
+ ' <File Id="nlsgui${lang}" Name="VirtualBox_${lang}.qm" DiskId="$(VBOX_INSTALLER_COMMON_DISKID)" Vital="yes" Source="$$(env.PATH_OUT)\bin\nls\VirtualBox_${lang}.qm" />')
$(APPEND) $@ '</Include>'
#
@@ -475,6 +546,7 @@ $(PACKAGE_NAME_FINAL): \
$(VBOX_WIN_INST_OUT_DIR)/Files_Main.wxi \
$(VBOX_WIN_INST_OUT_DIR)/Files_Doc.wxi \
$(VBOX_WIN_INST_OUT_DIR)/Files_License.wxi \
+ $(VBOX_WIN_INST_OUT_DIR)/Shortcuts_StartMenu.wxi \
$(foreach lang,$(VBOX_INSTALLER_LANGUAGES), $(VBOX_WIN_INST_OUT_DIR)/$(PACKAGE_NAME_LANG)_$(lang).msi) \
$(foreach lang,$(VBOX_INSTALLER_ADD_LANGUAGES), $(VBOX_WIN_INST_OUT_DIR)/Languages/$(lang).mst) \
| $$(dir $$@)
diff --git a/src/VBox/Installer/win/Resources/Makefile.kmk b/src/VBox/Installer/win/Resources/Makefile.kmk
index 44d470a75..f3143551d 100644
--- a/src/VBox/Installer/win/Resources/Makefile.kmk
+++ b/src/VBox/Installer/win/Resources/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37549 2011-06-20 08:44:19Z vboxsync $
## @file
# Sub-Makefile for VBoxRes.dll.
#
@@ -42,11 +42,19 @@ ifdef VBOX_OSE
VBOX_WINDOWS_ICON_EXT_EXTPACK := $(VBOX_RESOURCES_PATH_WIN)/OSE/virtualbox-vbox-extpack.ico
VBOX_WINDOWS_ICON_EXT_OVA := $(VBOX_RESOURCES_PATH_WIN)/OSE/virtualbox-ova.ico
VBOX_WINDOWS_ICON_EXT_OVF := $(VBOX_RESOURCES_PATH_WIN)/OSE/virtualbox-ovf.ico
+ VBOX_WINDOWS_ICON_EXT_VDI := $(VBOX_RESOURCES_PATH_WIN)/virtualbox-vdi.ico
+ VBOX_WINDOWS_ICON_EXT_VMDK := $(VBOX_RESOURCES_PATH_WIN)/virtualbox-vmdk.ico
+ VBOX_WINDOWS_ICON_EXT_VHD := $(VBOX_RESOURCES_PATH_WIN)/virtualbox-vhd.ico
+ VBOX_WINDOWS_ICON_EXT_HDD := $(VBOX_RESOURCES_PATH_WIN)/virtualbox-hdd.ico
else
VBOX_WINDOWS_ICON_EXT_VBOX := $(VBOX_RESOURCES_PATH_WIN)/virtualbox-vbox.ico
VBOX_WINDOWS_ICON_EXT_EXTPACK := $(VBOX_RESOURCES_PATH_WIN)/virtualbox-vbox-extpack.ico
VBOX_WINDOWS_ICON_EXT_OVA := $(VBOX_RESOURCES_PATH_WIN)/virtualbox-ova.ico
VBOX_WINDOWS_ICON_EXT_OVF := $(VBOX_RESOURCES_PATH_WIN)/virtualbox-ovf.ico
+ VBOX_WINDOWS_ICON_EXT_VDI := $(VBOX_RESOURCES_PATH_WIN)/virtualbox-vdi.ico
+ VBOX_WINDOWS_ICON_EXT_VMDK := $(VBOX_RESOURCES_PATH_WIN)/virtualbox-vmdk.ico
+ VBOX_WINDOWS_ICON_EXT_VHD := $(VBOX_RESOURCES_PATH_WIN)/virtualbox-vhd.ico
+ VBOX_WINDOWS_ICON_EXT_HDD := $(VBOX_RESOURCES_PATH_WIN)/virtualbox-hdd.ico
endif
VBOX_RESOURCES_WIN := \
@@ -54,7 +62,10 @@ VBOX_RESOURCES_WIN := \
$(VBOX_WINDOWS_ICON_EXT_VBOX) \
$(VBOX_WINDOWS_ICON_EXT_EXTPACK) \
$(VBOX_WINDOWS_ICON_EXT_OVA) \
- $(VBOX_WINDOWS_ICON_EXT_OVF)
+ $(VBOX_WINDOWS_ICON_EXT_OVF) \
+ $(VBOX_WINDOWS_ICON_EXT_VMDK) \
+ $(VBOX_WINDOWS_ICON_EXT_VHD) \
+ $(VBOX_WINDOWS_ICON_EXT_HDD)
$$(VBoxRes_0_OUTDIR)/VBoxRes-icons.rc: \
$$(VBOX_RESOURCES_WIN) $(MAKEFILE_CURRENT) | $$(dir $$@)
@@ -62,7 +73,10 @@ $$(VBoxRes_0_OUTDIR)/VBoxRes-icons.rc: \
$(APPEND) $@ 'IDI_VIRTUALBOX ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_FILE))"'
$(APPEND) $@ 'IDI_FILETYPE_VBOX ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_EXT_VBOX))"'
$(APPEND) $@ 'IDI_FILETYPE_VBOX_EXTPACK ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_EXT_EXTPACK))"'
- $(APPEND) $@ 'IDI_FILETYPE_VBOX_OVA ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_EXT_OVA))"'
- $(APPEND) $@ 'IDI_FILETYPE_VBOX_OVF ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_EXT_OVF))"'
+ $(APPEND) $@ 'IDI_FILETYPE_VBOX_OVA ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_EXT_OVA))"'
+ $(APPEND) $@ 'IDI_FILETYPE_VBOX_OVF ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_EXT_OVF))"'
+ $(APPEND) $@ 'IDI_FILETYPE_VBOX_VMDK ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_EXT_VMDK))"'
+ $(APPEND) $@ 'IDI_FILETYPE_VBOX_VHD ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_EXT_VHD))"'
+ $(APPEND) $@ 'IDI_FILETYPE_VBOX_HDD ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_EXT_HDD))"'
include $(KBUILD_PATH)/subfooter.kmk
diff --git a/src/VBox/Installer/win/Resources/VBoxRes.rc b/src/VBox/Installer/win/Resources/VBoxRes.rc
index a5a61624b..367025391 100644
--- a/src/VBox/Installer/win/Resources/VBoxRes.rc
+++ b/src/VBox/Installer/win/Resources/VBoxRes.rc
@@ -1,4 +1,4 @@
-/* $Id: VBoxRes.rc $ */
+/* $Id: VBoxRes.rc 34454 2010-11-29 11:27:20Z vboxsync $ */
/** @file
* VBoxRes - Resource file for VirtualBox binaries.
*/
diff --git a/src/VBox/Installer/win/Resources/dummy.cpp b/src/VBox/Installer/win/Resources/dummy.cpp
index 5a40e3698..6bd5dca1b 100644
--- a/src/VBox/Installer/win/Resources/dummy.cpp
+++ b/src/VBox/Installer/win/Resources/dummy.cpp
@@ -1,4 +1,4 @@
-/* $Id: dummy.cpp $ */
+/* $Id: dummy.cpp 35477 2011-01-11 11:20:35Z vboxsync $ */
/** @file
* dummy.cpp - file to make kBuild happy when building a resource only DLL.
*/
diff --git a/src/VBox/Installer/win/Resources/resource.h b/src/VBox/Installer/win/Resources/resource.h
index 3b76f2c18..af271d98e 100644
--- a/src/VBox/Installer/win/Resources/resource.h
+++ b/src/VBox/Installer/win/Resources/resource.h
@@ -1,4 +1,4 @@
-/* $Id: resource.h $ */
+/* $Id: resource.h 37549 2011-06-20 08:44:19Z vboxsync $ */
/** @file
* resource.h - resource header file.
*/
@@ -22,3 +22,7 @@
#define IDI_FILETYPE_VBOX_OVF 301
#define IDI_FILETYPE_VBOX_OVA 302
+#define IDI_FILETYPE_VBOX_VDI 303
+#define IDI_FILETYPE_VBOX_VMDK 304
+#define IDI_FILETYPE_VBOX_VHD 305
+#define IDI_FILETYPE_VBOX_HDD 306
diff --git a/src/VBox/Installer/win/Stub/Makefile.kmk b/src/VBox/Installer/win/Stub/Makefile.kmk
index 6b8ca3f28..a8f89ebe7 100644
--- a/src/VBox/Installer/win/Stub/Makefile.kmk
+++ b/src/VBox/Installer/win/Stub/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37991 2011-07-18 09:26:43Z vboxsync $
## @file
# Sub-Makefile for the stub installer.
#
@@ -27,7 +27,7 @@ TEMPLATE_VBOXSTUB_POST_CMDS = $(NO_SUCH_VARIABLE)
PROGRAMS.x86 += VBoxStub
VBoxStub_TEMPLATE= VBOXSTUB
-VBoxStub_DEFS = _WIN32_WINNT=0x0400 IN_RT_R3
+VBoxStub_DEFS = _WIN32_WINNT=0x0501 IN_RT_R3
VBoxStub_SOURCES = \
VBoxStub.cpp \
VBoxStub.rc
@@ -42,13 +42,22 @@ VBoxStub.cpp_DEPS = $(VBOX_SVN_REV_KMK)
# The icon location is configurable.
VBoxStub.rc_INCS += $(VBoxStub_0_OUTDIR)
-VBoxStub.rc_DEPS += $(VBoxStub_0_OUTDIR)/VBoxStub-icon.rc
-VBoxStub.rc_CLEAN = $(VBoxStub_0_OUTDIR)/VBoxStub-icon.rc
+VBoxStub.rc_DEPS += \
+ $(VBoxStub_0_OUTDIR)/VBoxStub-icon.rc \
+ $(VBoxStub_0_OUTDIR)/VBoxStub-manifest.rc
+VBoxStub.rc_CLEAN = \
+ $(VBoxStub_0_OUTDIR)/VBoxStub-icon.rc \
+ $(VBoxStub_0_OUTDIR)/VBoxStub-manifest.rc
# Icon include file.
$$(VBoxStub_0_OUTDIR)/VBoxStub-icon.rc: $(VBOX_WINDOWS_ICON_FILE) $(MAKEFILE_CURRENT) | $$(dir $$@)
$(APPEND) -t $@ 'IDI_VIRTUALBOX ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_FILE))"'
+# Manifest.
+VBOX_STUB_MANIFEST_FILE := $(PATH_SUB_CURRENT)/VBoxStub.manifest
+$$(VBoxStub_0_OUTDIR)/VBoxStub-manifest.rc: $(VBOX_STUB_MANIFEST_FILE) $(MAKEFILE_CURRENT) | $$(dir $$@)
+ $(APPEND) -t $@ 'APP_MANIFEST RT_MANIFEST "$(subst /,\\,$(VBOX_STUB_MANIFEST_FILE))"'
+
endif # x86 only
include $(KBUILD_PATH)/subfooter.kmk
diff --git a/src/VBox/Installer/win/Stub/VBoxStub.cpp b/src/VBox/Installer/win/Stub/VBoxStub.cpp
index 5b57bc766..7491d79a9 100644
--- a/src/VBox/Installer/win/Stub/VBoxStub.cpp
+++ b/src/VBox/Installer/win/Stub/VBoxStub.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxStub.cpp $ */
+/* $Id: VBoxStub.cpp 37989 2011-07-18 08:51:46Z vboxsync $ */
/** @file
* VBoxStub - VirtualBox's Windows installer stub.
*/
@@ -19,6 +19,7 @@
* Header Files *
*******************************************************************************/
#include <windows.h>
+#include <commctrl.h>
#include <lmerr.h>
#include <msiquery.h>
#include <objbase.h>
@@ -568,6 +569,16 @@ int WINAPI WinMain(HINSTANCE hInstance,
AssertMsgBreak(uLogLevel == ERROR_SUCCESS, ("Could not set installer logging level!\n"));
}
+ /* Initialize the common controls (extended version). This is necessary to
+ * run the actual .MSI installers with the new fancy visual control
+ * styles (XP+). Also, an integrated manifest is required. */
+ INITCOMMONCONTROLSEX ccEx;
+ ccEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ ccEx.dwICC = ICC_LINK_CLASS | ICC_LISTVIEW_CLASSES | ICC_PAGESCROLLER_CLASS |
+ ICC_PROGRESS_CLASS | ICC_STANDARD_CLASSES | ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES |
+ ICC_UPDOWN_CLASS | ICC_USEREX_CLASSES | ICC_WIN95_CLASSES;
+ InitCommonControlsEx(&ccEx); /* Ignore failure. */
+
UINT uStatus = ::MsiInstallProductA(pszTempFile, szMSIArgs);
if ( (uStatus != ERROR_SUCCESS)
&& (uStatus != ERROR_SUCCESS_REBOOT_REQUIRED)
diff --git a/src/VBox/Installer/win/Stub/VBoxStub.h b/src/VBox/Installer/win/Stub/VBoxStub.h
index 455023a67..4931bcd36 100644
--- a/src/VBox/Installer/win/Stub/VBoxStub.h
+++ b/src/VBox/Installer/win/Stub/VBoxStub.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxStub.h $ */
+/* $Id: VBoxStub.h 31667 2010-08-13 15:57:03Z vboxsync $ */
/** @file
* VBoxStub - VirtualBox's Windows installer stub.
*/
diff --git a/src/VBox/Installer/win/Stub/VBoxStub.manifest b/src/VBox/Installer/win/Stub/VBoxStub.manifest
new file mode 100644
index 000000000..f2076feec
--- /dev/null
+++ b/src/VBox/Installer/win/Stub/VBoxStub.manifest
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="*"
+ name="VBoxStub.exe"
+ type="win32"
+/>
+<description>VirtualBox Windows Installer</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="*"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+</assembly>
diff --git a/src/VBox/Installer/win/Stub/VBoxStub.rc b/src/VBox/Installer/win/Stub/VBoxStub.rc
index c2f00374d..a02e8e5b6 100644
--- a/src/VBox/Installer/win/Stub/VBoxStub.rc
+++ b/src/VBox/Installer/win/Stub/VBoxStub.rc
@@ -1,10 +1,10 @@
-/* $Id: VBoxStub.rc $*/
+/* $Id: VBoxStub.rc 37987 2011-07-18 08:11:16Z vboxsync $*/
/** @file
* Resource file for the Windows install stub program.
*/
/*
- * Copyright (C) 2009-2010 Oracle Corporation
+ * Copyright (C) 2009-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;
@@ -51,4 +51,5 @@ BEGIN
END
#include "VBoxStub-icon.rc"
+#include "VBoxStub-manifest.rc"
diff --git a/src/VBox/Installer/win/Stub/resource.h b/src/VBox/Installer/win/Stub/resource.h
index c0bddfbc6..b9d3adc0e 100644
--- a/src/VBox/Installer/win/Stub/resource.h
+++ b/src/VBox/Installer/win/Stub/resource.h
@@ -1,4 +1,4 @@
-/* $Id: resource.h $ */
+/* $Id: resource.h 37987 2011-07-18 08:11:16Z vboxsync $ */
/** @file
* VBoxStub - resource header file.
*/
@@ -14,5 +14,8 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-
#define IDI_VIRTUALBOX 101
+
+#define RT_MANIFEST 24
+#define APP_MANIFEST 1
+
diff --git a/src/VBox/Installer/win/StubBld/Makefile.kmk b/src/VBox/Installer/win/StubBld/Makefile.kmk
index 45aa9b402..99299d722 100644
--- a/src/VBox/Installer/win/StubBld/Makefile.kmk
+++ b/src/VBox/Installer/win/StubBld/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 31667 2010-08-13 15:57:03Z vboxsync $
## @file
# Sub-Makefile for the stub builder.
#
diff --git a/src/VBox/Installer/win/StubBld/VBoxStubBld.cpp b/src/VBox/Installer/win/StubBld/VBoxStubBld.cpp
index 862b088da..95e57dd78 100644
--- a/src/VBox/Installer/win/StubBld/VBoxStubBld.cpp
+++ b/src/VBox/Installer/win/StubBld/VBoxStubBld.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxStubBld.cpp $ */
+/* $Id: VBoxStubBld.cpp 32388 2010-09-10 10:13:07Z vboxsync $ */
/** @file
* VBoxStubBld - VirtualBox's Windows installer stub builder.
*/
diff --git a/src/VBox/Installer/win/StubBld/VBoxStubBld.h b/src/VBox/Installer/win/StubBld/VBoxStubBld.h
index 67005674c..242996a0e 100644
--- a/src/VBox/Installer/win/StubBld/VBoxStubBld.h
+++ b/src/VBox/Installer/win/StubBld/VBoxStubBld.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxStubBld.h $ */
+/* $Id: VBoxStubBld.h 31667 2010-08-13 15:57:03Z vboxsync $ */
/** @file
* VBoxStubBld - VirtualBox's Windows installer stub builder.
*/
diff --git a/src/VBox/Installer/win/UserInterface.wxi b/src/VBox/Installer/win/UserInterface.wxi
index 7e1860322..24631a2b5 100644
--- a/src/VBox/Installer/win/UserInterface.wxi
+++ b/src/VBox/Installer/win/UserInterface.wxi
@@ -1,8 +1,8 @@
-<?xml version="1.0" ?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
- User Interface Include for VirtualBox WiX script
+ User interface include for VirtualBox WiX script.
- 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;
@@ -13,39 +13,35 @@
hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-->
-<Include>
-
+<Include xmlns="http://schemas.microsoft.com/wix/2006/wi">
<UI>
- <Property Id="DefaultUIFont">DlgFont8</Property>
- <!-- <Property Id="ErrorDialog">ErrorDlg</Property> -->
-
<!-- This dialog will be shown when the user cancels the installation -->
- <Dialog Id="CancelDlg" Width="260" Height="85" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
- <Control Id="No" Type="PushButton" X="132" Y="57" Width="56" Height="17" Default="yes" Cancel="yes" Text="$(loc.ButtonText_No)">
+ <Dialog Id="VBoxCancelDlg" Width="260" Height="85" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
+ <Control Id="No" Type="PushButton" X="132" Y="57" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.ButtonText_No)">
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
- <Control Id="Yes" Type="PushButton" X="72" Y="57" Width="56" Height="17" Text="$(loc.ButtonText_Yes)">
+ <Control Id="Yes" Type="PushButton" X="72" Y="57" Width="56" Height="17" Text="!(loc.ButtonText_Yes)">
<Publish Event="EndDialog" Value="Exit">1</Publish>
</Control>
<Control Id="Text" Type="Text" X="48" Y="15" Width="194" Height="30">
- <Text>$(loc.CancelDlg_Question)</Text>
+ <Text>!(loc.CancelDlg_Question)</Text>
</Control>
<Control Id="Icon" Type="Icon" X="15" Y="15" Width="24" Height="24" ToolTip="Information icon" FixedSize="yes" IconSize="32" Text="[InfoIcon]" />
</Dialog>
<!-- This is the very first page the user will see -->
- <Dialog Id="WelcomeDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
+ <Dialog Id="VBoxWelcomeDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
<!-- The wizard has a bitmap as background. The source is defined as a property below. -->
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="[DialogBitmap]" />
<!-- Title text drawn on the background -->
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
- <Text>{\DlgVerdanaBold13}$(loc.WelcomeDlg_Header)</Text>
+ <Text>{\DlgVerdanaBold13}!(loc.WelcomeDlg_Header)</Text>
</Control>
<!-- Text saying what we gonna do -->
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="130" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.WelcomeDlg_Body)</Text>
+ <Text>!(loc.WelcomeDlg_Body)</Text>
</Control>
<!-- And a line for looking nice... -->
@@ -56,57 +52,57 @@
<Text>[Version_text] $(var.Property_Version)</Text>
</Control>
- <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="$(loc.ButtonText_Next)">
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Next)">
<?if $(env.VBOX_WITH_LICENSE_DISPLAY) = "yes" ?>
<!-- Next dialog is the license agreement -->
- <Publish Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
+ <Publish Event="NewDialog" Value="VBoxLicenseAgreementDlg">1</Publish>
<?else ?>
<!-- Decide which dialog to show next: The serial number dialog (if this is a branded build)
or directly proceed to the customization dialog (Vbox not installed yet) -->
<?if $(env.VBOX_WITH_SERIALNUMBER_INSTALL) = "yes" ?>
- <Publish Event="NewDialog" Value="CheckSerialDlg">1</Publish>
+ <Publish Event="NewDialog" Value="VBoxCheckSerialDlg">1</Publish>
<?else ?>
- <Publish Event="NewDialog" Value="CustomizeDlg"><![CDATA[(PREVIOUSVERSIONSINSTALLED OR NEWERVERSIONDETECTED)]]></Publish>
- <Publish Event="NewDialog" Value="CustomizeDlg"><![CDATA[(NOT PREVIOUSVERSIONSINSTALLED) AND (NOT NEWERVERSIONDETECTED)]]></Publish>
+ <Publish Event="NewDialog" Value="VBoxCustomizeDlg"><![CDATA[(PREVIOUSVERSIONSINSTALLED OR NEWERVERSIONDETECTED)]]></Publish>
+ <Publish Event="NewDialog" Value="VBoxCustomizeDlg"><![CDATA[(NOT PREVIOUSVERSIONSINSTALLED) AND (NOT NEWERVERSIONDETECTED)]]></Publish>
<?endif ?>
<?endif ?>
</Control>
<!-- Canceling will bring up a confirmation dialog ('SpawnDialog' attribute) -->
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
<!-- Uncomment if we need a 'back' button
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="$(loc.ButtonText_Back)" />
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.ButtonText_Back)" />
-->
</Dialog>
<!-- The radio button group used for the license agreement page -->
<RadioButtonGroup Property="IAgree">
- <RadioButton Text="{\DlgFont8}$(loc.LicenseAgreementDlg_Accept)" Value="Yes" X="5" Y="0" Width="250" Height="15" />
- <RadioButton Text="{\DlgFont8}$(loc.LicenseAgreementDlg_Decline)" Value="No" X="5" Y="20" Width="250" Height="15" />
+ <RadioButton Text="{\DlgFont8}!(loc.LicenseAgreementDlg_Accept)" Value="Yes" X="5" Y="0" Width="250" Height="15" />
+ <RadioButton Text="{\DlgFont8}!(loc.LicenseAgreementDlg_Decline)" Value="No" X="5" Y="20" Width="250" Height="15" />
</RadioButtonGroup>
<!-- The dialog page showing the license. The user has to set the appropriate check box to proceed -->
- <Dialog Id="LicenseAgreementDlg" Width="370" Height="270" Title="[ProductName] License Agreement" NoMinimize="yes">
+ <Dialog Id="VBoxLicenseAgreementDlg" Width="370" Height="270" Title="[ProductName] License Agreement" NoMinimize="yes">
<!-- The bitmap at the top of the dialog. This dialog doesn't have a background -->
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
<!-- The font used here is defined below -->
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>[DlgTitleFont]$(loc.LicenseAgreementDlg_Header)</Text>
+ <Text>[DlgTitleFont]!(loc.LicenseAgreementDlg_Header)</Text>
</Control>
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.LicenseAgreementDlg_Body)</Text>
+ <Text>!(loc.LicenseAgreementDlg_Body)</Text>
</Control>
<!-- The line directly below of the banner bmp -->
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<!-- The license text should be a RTF text so we have formatting -->
- <Control Id="AgreementText" Type="ScrollableText" X="20" Y="60" Width="330" Height="120" Sunken="yes" TabSkip="no" Text="$(loc.LicenseText)"/>
+ <Control Id="AgreementText" Type="ScrollableText" X="20" Y="60" Width="330" Height="120" Sunken="yes" TabSkip="no" Text="!(loc.LicenseText)"/>
<!-- This radio button group is defined below -->
<Control Id="Buttons" Type="RadioButtonGroup" X="20" Y="187" Width="330" Height="40" Property="IAgree" />
@@ -119,43 +115,43 @@
<Text>[Version_text] $(var.Property_Version)</Text>
</Control>
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="$(loc.ButtonText_Back)">
- <Publish Event="NewDialog" Value="WelcomeDlg">1</Publish>
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.ButtonText_Back)">
+ <Publish Event="NewDialog" Value="VBoxWelcomeDlg">1</Publish>
</Control>
- <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="$(loc.ButtonText_Next)">
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Next)">
<!-- 'Next' button is only enabled when 'I agree' radio button is selected -->
<Condition Action="disable"><![CDATA[IAgree <> "Yes"]]></Condition>
<Condition Action="enable">IAgree = "Yes"</Condition>
- <Publish Property="InstallMode" Value="$(loc.InstallModeCustom)">1</Publish>
+ <Publish Property="InstallMode" Value="!(loc.InstallModeCustom)">1</Publish>
<!-- Decide which dialog to show next: The serial number dialog (if this is a branded build)
or directly proceed to the customization dialog (Vbox not installed yet) -->
<?if $(env.VBOX_WITH_SERIALNUMBER_INSTALL) = "yes" ?>
- <Publish Event="NewDialog" Value="CheckSerialDlg">1</Publish>
+ <Publish Event="NewDialog" Value="VBoxCheckSerialDlg">1</Publish>
<?else ?>
- <Publish Event="NewDialog" Value="CustomizeDlg"><![CDATA[(PREVIOUSVERSIONSINSTALLED OR NEWERVERSIONDETECTED)]]></Publish>
- <Publish Event="NewDialog" Value="CustomizeDlg"><![CDATA[(NOT PREVIOUSVERSIONSINSTALLED) AND (NOT NEWERVERSIONDETECTED)]]></Publish>
+ <Publish Event="NewDialog" Value="VBoxCustomizeDlg"><![CDATA[(PREVIOUSVERSIONSINSTALLED OR NEWERVERSIONDETECTED)]]></Publish>
+ <Publish Event="NewDialog" Value="VBoxCustomizeDlg"><![CDATA[(NOT PREVIOUSVERSIONSINSTALLED) AND (NOT NEWERVERSIONDETECTED)]]></Publish>
<?endif ?>
</Control>
<!-- Canceling will bring up a confirmation dialog ('SpawnDialog' attribute) -->
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
</Dialog>
- <Dialog Id="CheckSerialDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
+ <Dialog Id="VBoxCheckSerialDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
<!-- The wizard has a bitmap as background. The source is defined as a property below. -->
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="[DialogBitmap]" />
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
- <Text>{\DlgVerdanaBold13}$(loc.CheckSerialDlg_Header)</Text>
+ <Text>{\DlgVerdanaBold13}!(loc.CheckSerialDlg_Header)</Text>
</Control>
<!-- Text saying what we gonna do -->
<Control Id="Description" Type="Text" X="135" Y="50" Width="220" Height="130" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.CheckSerialDlg_Body)</Text>
+ <Text>!(loc.CheckSerialDlg_Body)</Text>
</Control>
<Control Id="Serial1Edit" Type="Edit" X="135" Y="90" Width="30" Height="18" Property="Serial1" Text="{5}">
@@ -175,7 +171,7 @@
</Control>
<Control Id="Description3" Type="Text" X="135" Y="120" Width="220" Height="130" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.CheckSerialDlg_Footer)</Text>
+ <Text>!(loc.CheckSerialDlg_Footer)</Text>
</Control>
<!-- And a line for looking nice... -->
@@ -186,42 +182,42 @@
<Text>[Version_text] $(var.Property_Version)</Text>
</Control>
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="$(loc.ButtonText_Back)">
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.ButtonText_Back)">
<?if $(env.VBOX_WITH_LICENSE_DISPLAY) = "yes" ?>
- <Publish Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
+ <Publish Event="NewDialog" Value="VBoxLicenseAgreementDlg">1</Publish>
<?else ?>
- <Publish Event="NewDialog" Value="WelcomeDlg">1</Publish>
+ <Publish Event="NewDialog" Value="VBoxWelcomeDlg">1</Publish>
<?endif ?>
</Control>
- <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="$(loc.ButtonText_Check)">
- <Publish Event="DoAction" Value="CheckSerial">1</Publish>
- <Publish Event="NewDialog" Value="CustomizeDlg"><![CDATA[(PREVIOUSVERSIONSINSTALLED OR NEWERVERSIONDETECTED) AND (SERIALVALID = "1")]]></Publish>
- <Publish Event="NewDialog" Value="CustomizeDlg"><![CDATA[(NOT PREVIOUSVERSIONSINSTALLED) AND (NOT NEWERVERSIONDETECTED) AND (SERIALVALID = "1")]]></Publish>
- <Publish Event="NewDialog" Value="WrongSerialDlg"><![CDATA[SERIALVALID = "0"]]></Publish>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Check)">
+ <Publish Event="DoAction" Value="ca_CheckSerial">1</Publish>
+ <Publish Event="NewDialog" Value="VBoxCustomizeDlg"><![CDATA[(PREVIOUSVERSIONSINSTALLED OR NEWERVERSIONDETECTED) AND (SERIALVALID = "1")]]></Publish>
+ <Publish Event="NewDialog" Value="VBoxCustomizeDlg"><![CDATA[(NOT PREVIOUSVERSIONSINSTALLED) AND (NOT NEWERVERSIONDETECTED) AND (SERIALVALID = "1")]]></Publish>
+ <Publish Event="NewDialog" Value="VBoxWrongSerialDlg"><![CDATA[SERIALVALID = "0"]]></Publish>
</Control>
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
</Dialog>
- <Dialog Id="WrongSerialDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
+ <Dialog Id="VBoxWrongSerialDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
<!-- The wizard has a bitmap as background. The source is defined as a property below. -->
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="[DialogBitmap]" />
<!-- Title text drawn on the background -->
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
- <Text>{\DlgInvalidSerial}$(loc.WrongSerialDlg_Header)</Text>
+ <Text>{\DlgInvalidSerial}!(loc.WrongSerialDlg_Header)</Text>
</Control>
<!-- Text saying what we gonna do -->
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="130" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.WrongSerialDlg_Desc1)</Text>
+ <Text>!(loc.WrongSerialDlg_Desc1)</Text>
</Control>
<Control Id="Description2" Type="Text" X="135" Y="95" Width="220" Height="130" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.WrongSerialDlg_Desc2)</Text>
+ <Text>!(loc.WrongSerialDlg_Desc2)</Text>
</Control>
<!-- And a line for looking nice... -->
@@ -232,76 +228,76 @@
<Text>[Version_text] $(var.Property_Version)</Text>
</Control>
- <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="$(loc.ButtonText_Back)">
- <Publish Event="NewDialog" Value="CheckSerialDlg">1</Publish>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Back)">
+ <Publish Event="NewDialog" Value="VBoxCheckSerialDlg">1</Publish>
</Control>
<!-- Canceling will bring up a confirmation dialog ('SpawnDialog' attribute) -->
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
</Dialog>
<!-- Dialog used to set another installation path. This is taken from the tutorial template on the web and can also be
used for package selection etc. if necessary after some tweaking. -->
- <Dialog Id="CustomizeDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes" TrackDiskSpace="yes">
+ <Dialog Id="VBoxCustomizeDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes" TrackDiskSpace="yes">
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>[DlgTitleFont]$(loc.CustomizeDlg_CustomSetup)</Text>
+ <Text>[DlgTitleFont]!(loc.CustomizeDlg_CustomSetup)</Text>
</Control>
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.CustomizeDlg_SelFeatures)</Text>
+ <Text>!(loc.CustomizeDlg_SelFeatures)</Text>
</Control>
<Control Id="Text" Type="Text" X="25" Y="55" Width="320" Height="20">
- <Text>$(loc.CustomizeDlg_IconTree)</Text>
+ <Text>!(loc.CustomizeDlg_IconTree)</Text>
</Control>
<Control Id="Tree" Type="SelectionTree" X="25" Y="85" Width="175" Height="95" Property="_BrowseProperty"
Sunken="yes" TabSkip="no" Text="Tree of selections" />
- <Control Id="Browse" Type="PushButton" X="304" Y="200" Width="56" Height="17" Text="$(loc.ButtonText_Browse)">
- <Publish Event="SelectionBrowse" Value="BrowseDlg">1</Publish>
+ <Control Id="Browse" Type="PushButton" X="304" Y="200" Width="56" Height="17" Text="!(loc.ButtonText_Browse)">
+ <Publish Event="SelectionBrowse" Value="VBoxBrowseDlg">1</Publish>
<Condition Action="hide">Installed</Condition>
</Control>
<Control Id="DiskCost" Type="PushButton" X="111" Y="243" Width="56" Height="17">
- <Text>$(loc.CustomizeDlg_DiskUsage)</Text>
- <Publish Event="SpawnDialog" Value="DiskCostDlg">1</Publish>
+ <Text>!(loc.CustomizeDlg_DiskUsage)</Text>
+ <Publish Event="SpawnDialog" Value="VBoxDiskCostDlg">1</Publish>
<Subscribe Event="SelectionNoItems" Attribute="Enabled" />
</Control>
<Control Id="Box" Type="GroupBox" X="210" Y="81" Width="140" Height="98" />
<Control Id="ItemDescription" Type="Text" X="215" Y="90" Width="131" Height="30">
- <Text>$(loc.CustomizeDlg_SelItemDesc)</Text>
+ <Text>!(loc.CustomizeDlg_SelItemDesc)</Text>
<Subscribe Event="SelectionDescription" Attribute="Text" />
</Control>
<Control Id="ItemSize" Type="Text" X="215" Y="130" Width="131" Height="45">
- <Text>$(loc.CustomizeDlg_SelItemSize)</Text>
+ <Text>!(loc.CustomizeDlg_SelItemSize)</Text>
<Subscribe Event="SelectionSize" Attribute="Text" />
</Control>
<Control Id="Location" Type="Text" X="75" Y="200" Width="215" Height="20">
- <Text>$(loc.CustomizeDlg_SelItemPath)</Text>
+ <Text>!(loc.CustomizeDlg_SelItemPath)</Text>
<Subscribe Event="SelectionPath" Attribute="Text" />
<Subscribe Event="SelectionPathOn" Attribute="Visible" />
<Condition Action="hide">Installed</Condition>
</Control>
- <Control Id="LocationLabel" Type="Text" X="25" Y="200" Width="50" Height="10" Text="$(loc.CustomizeDlg_Location)">
+ <Control Id="LocationLabel" Type="Text" X="25" Y="200" Width="50" Height="10" Text="!(loc.CustomizeDlg_Location)">
<Subscribe Event="SelectionPathOn" Attribute="Visible" />
<Condition Action="hide">Installed</Condition>
</Control>
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="$(loc.ButtonText_Back)">
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.ButtonText_Back)">
<?if $(env.VBOX_WITH_LICENSE_DISPLAY) = "yes" ?>
- <Publish Event="NewDialog" Value="LicenseAgreementDlg"><![CDATA[(NOT CHECKSERIAL) AND (InstallMode = "$(loc.InstallModeCustom)")]]></Publish>
- <Publish Event="NewDialog" Value="CheckSerialDlg"><![CDATA[CHECKSERIAL]]></Publish>
+ <Publish Event="NewDialog" Value="VBoxLicenseAgreementDlg"><![CDATA[(NOT CHECKSERIAL) AND (InstallMode = "!(loc.InstallModeCustom)")]]></Publish>
+ <Publish Event="NewDialog" Value="VBoxCheckSerialDlg"><![CDATA[CHECKSERIAL]]></Publish>
<?else ?>
- <Publish Event="NewDialog" Value="WelcomeDlg">1</Publish>
+ <Publish Event="NewDialog" Value="VBoxWelcomeDlg">1</Publish>
<?endif ?>
</Control>
- <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="$(loc.ButtonText_Next)">
- <Publish Event="NewDialog" Value="Customize2Dlg">1</Publish>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Next)">
+ <Publish Event="NewDialog" Value="VBoxCustomize2Dlg">1</Publish>
<Subscribe Event="SelectionNoItems" Attribute="Enabled" />
</Control>
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
<!-- Build number text drawn left bottom -->
@@ -311,17 +307,17 @@
</Control>
</Dialog>
- <Dialog Id="Customize2Dlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
+ <Dialog Id="VBoxCustomize2Dlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="220" Height="40" Transparent="yes" NoPrefix="yes">
- <Text>[DlgTitleFont]$(loc.CustomizeDlg_CustomSetup)</Text>
+ <Text>[DlgTitleFont]!(loc.CustomizeDlg_CustomSetup)</Text>
</Control>
<Control Id="Description" Type="Text" X="25" Y="23" Width="220" Height="20" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.CustomizeDlg_SelFeatures)</Text>
+ <Text>!(loc.CustomizeDlg_SelFeatures)</Text>
</Control>
<Control Id="Text" Type="Text" X="25" Y="70" Width="320" Height="20">
- <Text>$(loc.Customize2Dlg_Desc)</Text>
+ <Text>!(loc.Customize2Dlg_Desc)</Text>
</Control>
<!-- Note the gray background behind the checkboxes. Unfortunately there's no easy way to
fix this, without fixing it in the WiX source code. Because the control's background
@@ -332,29 +328,29 @@
Also see: http://osdir.com/ml/windows.devel.wix.user/2005-02/msg00300.html -->
<Control Id="DesktopShortcutCheckBox" Type="CheckBox" X="25" Y="95" Width="200" Height="17"
Property="INSTALLDESKTOPSHORTCUT" CheckBoxValue="1">
- <Text>$(loc.Customize2Dlg_CreateShortcut)</Text>
+ <Text>!(loc.Customize2Dlg_CreateShortcut)</Text>
</Control>
<Control Id="QuicklaunchShortcutCheckBox" Type="CheckBox" X="25" Y="115" Width="200" Height="17"
- Property="INSTALLQUICKLAUNCHSHORTCUT" CheckBoxValue="1">
- <Text>$(loc.Customize2Dlg_CreateQuickLaunch)</Text>
+ Property="INSTALLQUICKLAUNCHSHORTCUT" CheckBoxValue="1">
+ <Text>!(loc.Customize2Dlg_CreateQuickLaunch)</Text>
</Control>
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17"
- Default="yes" Cancel="yes" Text="$(loc.ButtonText_Next)">
+ Default="yes" Cancel="yes" Text="!(loc.ButtonText_Next)">
<?if $(env.VBOX_WITH_NETFLT) = "yes" ?>
- <Publish Event="NewDialog" Value="WarnDisconNetIfacesDlg"><![CDATA[(&VBoxNetworkFlt=3) AND NOT(!VBoxNetworkFlt=3)]]></Publish>
- <Publish Event="NewDialog" Value="VerifyReadyDlg"><![CDATA[(&VBoxNetworkFlt<3)]]></Publish>
+ <Publish Event="NewDialog" Value="VBoxWarnDisconNetIfacesDlg"><![CDATA[(&ft_VBoxNetworkFlt=3) AND NOT(!ft_VBoxNetworkFlt=3)]]></Publish>
+ <Publish Event="NewDialog" Value="VBoxVerifyReadyDlg"><![CDATA[(&ft_VBoxNetworkFlt<3)]]></Publish>
<?else ?>
- <Publish Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
+ <Publish Event="NewDialog" Value="VBoxVerifyReadyDlg">1</Publish>
<?endif?>
</Control>
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17"
- Text="$(loc.ButtonText_Back)">
- <Publish Event="NewDialog" Value="CustomizeDlg">1</Publish>
+ Text="!(loc.ButtonText_Back)">
+ <Publish Event="NewDialog" Value="VBoxCustomizeDlg">1</Publish>
</Control>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17"
- Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
<!-- Build number text drawn left bottom -->
@@ -364,27 +360,27 @@
</Control>
</Dialog>
- <Dialog Id="WarnDisconNetIfacesDlg" Width="370" Height="270" Title="[ProductName] [Setup]" NoMinimize="yes">
+ <Dialog Id="VBoxWarnDisconNetIfacesDlg" Width="370" Height="270" Title="[ProductName] [Setup]" NoMinimize="yes">
<!-- The wizard has a bitmap as background. The source is defined as a property below. -->
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="[DialogBitmap]" />
<!-- Title text drawn on the background -->
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
- <Text>{\DlgWarnDisconNetIfaces}$(loc.WarnDisconNetIfacesDlg_Title)</Text>
+ <Text>{\DlgWarnDisconNetIfaces}!(loc.WarnDisconNetIfacesDlg_Title)</Text>
</Control>
<Control Id="Title2" Type="Text" X="135" Y="40" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
- <Text>{\DlgWarnDisconNetIfaces}$(loc.WarnDisconNetIfacesDlg_Title2)</Text>
+ <Text>{\DlgWarnDisconNetIfaces}!(loc.WarnDisconNetIfacesDlg_Title2)</Text>
</Control>
<!-- Text saying what we gonna do -->
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="130" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.WarnDisconNetIfacesDlg_Desc)</Text>
+ <Text>!(loc.WarnDisconNetIfacesDlg_Desc)</Text>
</Control>
<Control Id="Description2" Type="Text" X="135" Y="115" Width="220" Height="130" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.WarnDisconNetIfacesDlg_Question)</Text>
+ <Text>!(loc.WarnDisconNetIfacesDlg_Question)</Text>
</Control>
<!-- And a line for looking nice... -->
@@ -396,107 +392,107 @@
</Control>
<!-- Next dialog is the warning dialog for TAP devices -->
- <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="$(loc.ButtonText_Yes)">
- <Publish Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Yes)">
+ <Publish Event="NewDialog" Value="VBoxVerifyReadyDlg">1</Publish>
</Control>
<!-- Canceling will bring up a confirmation dialog ('SpawnDialog' attribute) -->
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_No)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_No)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
</Dialog>
- <Dialog Id="DiskCostDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
- <Control Id="OK" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="$(loc.ButtonText_OK)">
+ <Dialog Id="VBoxDiskCostDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
+ <Control Id="OK" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.ButtonText_OK)">
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
<Control Id="Description" Type="Text" X="20" Y="20" Width="280" Height="20" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.DiskCostDlg_SpaceRequired)</Text>
+ <Text>!(loc.DiskCostDlg_SpaceRequired)</Text>
</Control>
<Control Id="Text" Type="Text" X="20" Y="53" Width="330" Height="40">
- <Text>$(loc.DiskCostDlg_NotEnoughSpace)</Text>
+ <Text>!(loc.DiskCostDlg_NotEnoughSpace)</Text>
</Control>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>[DlgTitleFont]$(loc.DiskCostDlg_SpaceRequirements)</Text>
+ <Text>[DlgTitleFont]!(loc.DiskCostDlg_SpaceRequirements)</Text>
</Control>
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="VolumeList" Type="VolumeCostList" X="20" Y="100" Width="330" Height="120" Sunken="yes" Fixed="yes" Remote="yes">
- <Text>$(loc.DiskCostDlg_VolumeList)</Text>
+ <Text>!(loc.DiskCostDlg_VolumeList)</Text>
</Control>
</Dialog>
<!-- Dialog used to change the installation directory -->
- <Dialog Id="BrowseDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
+ <Dialog Id="VBoxBrowseDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
<Control Id="PathEdit" Type="PathEdit" X="84" Y="202" Width="261" Height="18" Property="_BrowseProperty" Indirect="yes" />
- <Control Id="OK" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Text="$(loc.ButtonText_OK)">
+ <Control Id="OK" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_OK)">
<Publish Event="SetTargetPath" Value="[_BrowseProperty]">1</Publish>
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
- <Control Id="Cancel" Type="PushButton" X="240" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
+ <Control Id="Cancel" Type="PushButton" X="240" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
<Publish Event="Reset" Value="0">1</Publish>
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
- <Control Id="ComboLabel" Type="Text" X="25" Y="58" Width="44" Height="10" TabSkip="no" Text="$(loc.BrowseDlg_LookIn)" />
+ <Control Id="ComboLabel" Type="Text" X="25" Y="58" Width="44" Height="10" TabSkip="no" Text="!(loc.BrowseDlg_LookIn)" />
<Control Id="DirectoryCombo" Type="DirectoryCombo" X="70" Y="55" Width="220" Height="80"
Property="_BrowseProperty" Indirect="yes" Fixed="yes" Remote="yes">
<Subscribe Event="IgnoreChange" Attribute="IgnoreChange" />
</Control>
- <Control Id="Up" Type="PushButton" X="298" Y="55" Width="19" Height="19" ToolTip="$(loc.BrowseDlg_UpOneLevelTooltip)" Icon="yes" FixedSize="yes" IconSize="16" Text="[FolderUp]">
+ <Control Id="Up" Type="PushButton" X="298" Y="55" Width="19" Height="19" ToolTip="!(loc.BrowseDlg_UpOneLevelTooltip)" Icon="yes" FixedSize="yes" IconSize="16" Text="[FolderUp]">
<Publish Event="DirectoryListUp" Value="0">1</Publish>
</Control>
<Control Id="NewFolder" Type="PushButton" X="325" Y="55" Width="19" Height="19"
- ToolTip="$(loc.BrowseDlg_CreateNewFolderTooltip)" Icon="yes" FixedSize="yes" IconSize="16" Text="[FolderNew]">
+ ToolTip="!(loc.BrowseDlg_CreateNewFolderTooltip)" Icon="yes" FixedSize="yes" IconSize="16" Text="[FolderNew]">
<Publish Event="DirectoryListNew" Value="0">1</Publish>
</Control>
<Control Id="DirectoryList" Type="DirectoryList" X="25" Y="83" Width="320" Height="110"
Property="_BrowseProperty" Sunken="yes" Indirect="yes" TabSkip="no" />
- <Control Id="PathLabel" Type="Text" X="25" Y="205" Width="59" Height="10" TabSkip="no" Text="$(loc.BrowseDlg_FolderName)" />
+ <Control Id="PathLabel" Type="Text" X="25" Y="205" Width="59" Height="10" TabSkip="no" Text="!(loc.BrowseDlg_FolderName)" />
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.BrowseDlg_BrowseDestFolder)</Text>
+ <Text>!(loc.BrowseDlg_BrowseDestFolder)</Text>
</Control>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>[DlgTitleFont]$(loc.BrowseDlg_ChangeCurFolder)</Text>
+ <Text>[DlgTitleFont]!(loc.BrowseDlg_ChangeCurFolder)</Text>
</Control>
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
</Dialog>
- <Dialog Id="PrepareDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" Modeless="yes">
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Dialog Id="VBoxPrepareDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" Modeless="yes">
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="[DialogBitmap]" />
</Dialog>
- <Dialog Id="VerifyReadyDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes" TrackDiskSpace="yes">
+ <Dialog Id="VBoxVerifyReadyDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes" TrackDiskSpace="yes">
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>[DlgTitleFont]$(loc.VerifyReadyDlg_ReadyToInstall)</Text>
+ <Text>[DlgTitleFont]!(loc.VerifyReadyDlg_ReadyToInstall)</Text>
</Control>
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.VerifyReadyDlg_ReadyToBegin)</Text>
+ <Text>!(loc.VerifyReadyDlg_ReadyToBegin)</Text>
</Control>
<Control Id="Text" Type="Text" X="25" Y="70" Width="320" Height="80">
- <Text>$(loc.VerifyReadyDlg_ClickInstall)</Text>
+ <Text>!(loc.VerifyReadyDlg_ClickInstall)</Text>
</Control>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
- <Control Id="Install" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="$(loc.ButtonText_Install)">
+ <Control Id="Install" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Install)">
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
- <Publish Event="SpawnDialog" Value="OutOfRbDiskDlg"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)]]></Publish>
+ <Publish Event="SpawnDialog" Value="VBoxOutOfRbDiskDlg"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)]]></Publish>
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"]]></Publish>
<Publish Event="EnableRollback" Value="False"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"]]></Publish>
- <Publish Event="SpawnDialog" Value="OutOfDiskDlg"><![CDATA[(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")]]></Publish>
+ <Publish Event="SpawnDialog" Value="VBoxOutOfDiskDlg"><![CDATA[(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")]]></Publish>
</Control>
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="$(loc.ButtonText_Back)">
- <Publish Event="NewDialog" Value="Customize2Dlg"><![CDATA[InstallMode = "$(loc.InstallModeCustom)"]]></Publish>
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.ButtonText_Back)">
+ <Publish Event="NewDialog" Value="VBoxCustomize2Dlg"><![CDATA[InstallMode = "!(loc.InstallModeCustom)"]]></Publish>
</Control>
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
<!-- Build number text drawn left bottom -->
@@ -506,9 +502,9 @@
</Dialog>
<!-- This dialog is called after successful installation -->
- <Dialog Id="ExitDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
- <Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="$(loc.ButtonText_Finish)">
- <Publish Event="DoAction" Value="StartVBox"><![CDATA[STARTVBOX]]></Publish>
+ <Dialog Id="VBoxExitDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
+ <Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.ButtonText_Finish)">
+ <Publish Event="DoAction" Value="ca_StartVBox"><![CDATA[STARTVBOX]]></Publish>
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
@@ -517,11 +513,11 @@
<Text>[Version_text] $(var.Property_Version)</Text>
</Control>
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="$(loc.ButtonText_Cancel)" />
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.ButtonText_Cancel)" />
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="[DialogBitmap]" />
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="$(loc.ButtonText_Back)" />
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.ButtonText_Back)" />
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="20" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.ExitDlg_ClickFinish)</Text>
+ <Text>!(loc.ExitDlg_ClickFinish)</Text>
</Control>
<!-- Note the gray background behind the checkboxes. Unfortunately there's no easy way to
@@ -533,7 +529,7 @@
Also see: http://osdir.com/ml/windows.devel.wix.user/2005-02/msg00300.html -->
<Control Id="StartVBoxCheckBox" Type="CheckBox" X="135" Y="115" Width="200" Height="17"
Property="STARTVBOX" CheckBoxValue="1">
- <Text>$(loc.ExitDlg_StartVBox)</Text>
+ <Text>!(loc.ExitDlg_StartVBox)</Text>
<Condition Action="hide">
<![CDATA[(InstallMode="Repair") OR (InstallMode="Remove") OR
(InstallMode="Change")]]>
@@ -542,57 +538,69 @@
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
- <Text>{\DlgVerdanaBold13}$(loc.ExitDlg_InstComplete)</Text>
+ <Text>{\DlgVerdanaBold13}!(loc.ExitDlg_InstComplete)</Text>
</Control>
</Dialog>
<!-- This dialog is called after an error during installation -->
- <Dialog Id="FatalErrorDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
- <Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="$(loc.ButtonText_Finish)">
- <Publish Event="EndDialog" Value="Exit">1</Publish>
+ <Dialog Id="VBoxFatalErrorDlg" ErrorDialog="yes" Width="270" Height="150" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
+ <!-- Do *not* change the control IDs in the dialog! -->
+ <Control Id="ErrorIcon" Type="Icon" X="15" Y="15" Width="24" Height="24" ToolTip="Icon" FixedSize="yes" IconSize="32" Text="[ExclamationIcon]" />
+ <Control Id="ErrorText" Type="Text" X="75" Y="20" Width="155" Height="80" TabSkip="no">
+ <Text><![CDATA[{&DlgFont8}]]></Text>
</Control>
-
- <!-- Build number text drawn left bottom -->
- <Control Id="Build" Type="Text" X="20" Y="247" Width="220" Height="10" Transparent="yes" NoPrefix="yes">
- <Text>[Version_text] $(var.Property_Version)</Text>
+ <Control Id="Y" Type="PushButton" X="20" Y="110" Width="80" Height="18" TabSkip="yes">
+ <Text><![CDATA[{\DlgFont8}&Yes]]></Text>
+ <Publish Event="EndDialog" Value="ErrorYes">1</Publish>
</Control>
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="$(loc.ButtonText_Cancel)" />
- <Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="[DialogBitmap]" />
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="$(loc.ButtonText_Back)" />
- <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
- <Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
- <Text>{\DlgVerdanaBold13}$(loc.FatalErrorDlg_Header)</Text>
+ <Control Id="A" Type="PushButton" X="20" Y="110" Width="80" Height="18" TabSkip="yes">
+ <Text><![CDATA[{\DlgFont8}&Cancel]]></Text>
+ <Publish Event="EndDialog" Value="ErrorAbort">1</Publish>
</Control>
- <Control Id="Description1" Type="Text" X="135" Y="70" Width="220" Height="40" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.FatalErrorDlg_Desc)</Text>
+ <Control Id="C" Type="PushButton" X="20" Y="110" Width="80" Height="18" TabSkip="yes">
+ <Text><![CDATA[{\DlgFont8}&Cancel]]></Text>
+ <Publish Event="EndDialog" Value="ErrorCancel">1</Publish>
</Control>
- <Control Id="Description2" Type="Text" X="135" Y="115" Width="220" Height="20" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.FatalErrorDlg_Footer)</Text>
+ <Control Id="I" Type="PushButton" X="20" Y="110" Width="80" Height="18" TabSkip="yes">
+ <Text><![CDATA[{\DlgFont8}&Ignore]]></Text>
+ <Publish Event="EndDialog" Value="ErrorIgnore">1</Publish>
+ </Control>
+ <Control Id="N" Type="PushButton" X="20" Y="110" Width="80" Height="18" TabSkip="yes">
+ <Text><![CDATA[{\DlgFont8}&No]]></Text>
+ <Publish Event="EndDialog" Value="ErrorNo">1</Publish>
+ </Control>
+ <Control Id="O" Type="PushButton" X="20" Y="110" Width="80" Height="18" TabSkip="yes">
+ <Text><![CDATA[{\DlgFont8}&OK]]></Text>
+ <Publish Event="EndDialog" Value="ErrorOk">1</Publish>
+ </Control>
+ <Control Id="R" Type="PushButton" X="20" Y="110" Width="80" Height="18" TabSkip="yes">
+ <Text><![CDATA[{\DlgFont8}&Retry]]></Text>
+ <Publish Event="EndDialog" Value="ErrorRetry">1</Publish>
</Control>
</Dialog>
- <Dialog Id="FilesInUse" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" KeepModeless="yes">
- <Control Id="Retry" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="$(loc.ButtonText_Retry)">
+ <Dialog Id="FilesInUse" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" KeepModeless="yes">
+ <Control Id="Retry" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.ButtonText_Retry)">
<Publish Event="EndDialog" Value="Retry">1</Publish>
</Control>
- <Control Id="Ignore" Type="PushButton" X="235" Y="243" Width="56" Height="17" Text="$(loc.ButtonText_Ignore)">
+ <Control Id="Ignore" Type="PushButton" X="235" Y="243" Width="56" Height="17" Text="!(loc.ButtonText_Ignore)">
<Publish Event="EndDialog" Value="Ignore">1</Publish>
</Control>
- <Control Id="Exit" Type="PushButton" X="166" Y="243" Width="56" Height="17" Text="$(loc.ButtonText_Exit)">
+ <Control Id="Exit" Type="PushButton" X="166" Y="243" Width="56" Height="17" Text="!(loc.ButtonText_Exit)">
<Publish Event="EndDialog" Value="Exit">1</Publish>
</Control>
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
- <Control Id="Text" Type="Text" X="20" Y="55" Width="330" Height="50" Text="$(loc.FilesInUse_Text)" />
+ <Control Id="Text" Type="Text" X="20" Y="55" Width="330" Height="50" Text="!(loc.FilesInUse_Text)" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
- <Control Id="Description" Type="Text" X="20" Y="23" Width="280" Height="20" Transparent="yes" NoPrefix="yes" Text="$(loc.FilesInUse_Description)" />
- <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="[DlgTitleFont]$(loc.FilesInUse_Title)" />
+ <Control Id="Description" Type="Text" X="20" Y="23" Width="280" Height="20" Transparent="yes" NoPrefix="yes" Text="!(loc.FilesInUse_Description)" />
+ <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="[DlgTitleFont]!(loc.FilesInUse_Title)" />
<Control Id="List" Type="ListBox" X="20" Y="107" Width="330" Height="130" Property="FileInUseProcess" Sunken="yes" TabSkip="yes" />
</Dialog>
<!-- This dialog is shown if the user interrupts the installation process -->
- <Dialog Id="UserExitDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
- <Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="$(loc.ButtonText_Finish)">
+ <Dialog Id="VBoxUserExitDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
+ <Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.ButtonText_Finish)">
<Publish Event="EndDialog" Value="Exit">1</Publish>
</Control>
<!-- Build number text drawn left bottom -->
@@ -600,25 +608,25 @@
<Text>[Version_text] $(var.Property_Version)</Text>
</Control>
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="$(loc.ButtonText_Cancel)" />
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.ButtonText_Cancel)" />
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="[DialogBitmap]" />
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="$(loc.ButtonText_Back)" />
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.ButtonText_Back)" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
- <Text>{\DlgVerdanaBold13}$(loc.UserExitDlg_Header)</Text>
+ <Text>{\DlgVerdanaBold13}!(loc.UserExitDlg_Header)</Text>
</Control>
<Control Id="Description1" Type="Text" X="135" Y="70" Width="220" Height="40" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.UserExitDlg_Desc)</Text>
+ <Text>!(loc.UserExitDlg_Desc)</Text>
</Control>
<Control Id="Description2" Type="Text" X="135" Y="115" Width="220" Height="20" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.UserExitDlg_Footer)</Text>
+ <Text>!(loc.UserExitDlg_Footer)</Text>
</Control>
</Dialog>
<!-- Progress dialog shown during file copying and other lengthy operations -->
- <Dialog Id="ProgressDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" Modeless="yes">
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Dialog Id="VBoxProgressDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" Modeless="yes">
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
<!-- Build number text drawn left bottom -->
@@ -627,13 +635,13 @@
</Control>
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="$(loc.ButtonText_Back)" />
- <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Disabled="yes" Text="$(loc.ButtonText_Next)" />
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.ButtonText_Back)" />
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.ButtonText_Next)" />
<Control Id="ActionText" Type="Text" X="70" Y="100" Width="265" Height="10">
<Subscribe Event="ActionText" Attribute="Text" />
</Control>
<Control Id="Text" Type="Text" X="35" Y="65" Width="300" Height="20">
- <Text>$(loc.ProgressDlg_PleaseWait)</Text>
+ <Text>!(loc.ProgressDlg_PleaseWait)</Text>
</Control>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="20" Y="15" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
@@ -646,31 +654,31 @@
<Control Id="StatusLabel" Type="Text" X="35" Y="100" Width="35" Height="10" Text="Status:" />
</Dialog>
- <Dialog Id="ResumeDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
- <Control Id="Install" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="[$(loc.ButtonText_Install)]">
- <Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">CostingComplete = 1</Publish>
+ <Dialog Id="VBoxResumeDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
+ <Control Id="Install" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Install)">
+ <Publish Event="SpawnWaitDialog" Value="VBoxWaitForCostingDlg">CostingComplete = 1</Publish>
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
- <Publish Event="SpawnDialog" Value="OutOfRbDiskDlg">
+ <Publish Event="SpawnDialog" Value="VBoxOutOfRbDiskDlg">
<![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)]]>
</Publish>
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"]]></Publish>
<Publish Event="EnableRollback" Value="False"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"]]></Publish>
- <Publish Event="SpawnDialog" Value="OutOfDiskDlg">
+ <Publish Event="SpawnDialog" Value="VBoxOutOfDiskDlg">
<![CDATA[(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")]]>
</Publish>
</Control>
<!-- Build number text drawn left bottom -->
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="[DialogBitmap]" />
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="$(loc.ButtonText_Back)" />
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.ButtonText_Back)" />
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
- <Text>{\DlgVerdanaBold13}$(loc.ResumeDlg_Header)</Text>
+ <Text>{\DlgVerdanaBold13}!(loc.ResumeDlg_Header)</Text>
</Control>
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="30" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.ResumeDlg_Desc)</Text>
+ <Text>!(loc.ResumeDlg_Desc)</Text>
</Control>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Build" Type="Text" X="20" Y="247" Width="220" Height="10" Transparent="yes" NoPrefix="yes">
@@ -680,26 +688,26 @@
<!-- This dialog is shown after the welcome page if the user restarts the MSI package on a system where the product is already installed. The user
may choose to repair the installation or remove it. -->
- <Dialog Id="MaintenanceTypeDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
+ <Dialog Id="VBoxMaintenanceTypeDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
<Control Id="RepairLabel" Type="Text" X="105" Y="90" Width="100" Height="10" TabSkip="no">
- <Text>[DlgTitleFont]$(loc.MaintenanceTypeDlg_Repair)</Text>
+ <Text>[DlgTitleFont]!(loc.MaintenanceTypeDlg_Repair)</Text>
</Control>
- <Control Id="RepairButton" Type="PushButton" X="50" Y="90" Width="38" Height="38" ToolTip="$(loc.MaintenanceTypeDlg_RepairTooltip)"
+ <Control Id="RepairButton" Type="PushButton" X="50" Y="90" Width="38" Height="38" ToolTip="!(loc.MaintenanceTypeDlg_RepairTooltip)"
Icon="yes" FixedSize="yes" IconSize="32" Text="[RepairIcon]">
<Publish Property="InstallMode" Value="Repair">1</Publish>
- <Publish Property="Progress1" Value="$(loc.MaintenanceTypeDlg_RepairProgress1)">1</Publish>
- <Publish Property="Progress2" Value="$(loc.MaintenanceTypeDlg_RepairProgress2)">1</Publish>
- <Publish Event="NewDialog" Value="VerifyRepairDlg">1</Publish>
+ <Publish Property="Progress1" Value="!(loc.MaintenanceTypeDlg_RepairProgress1)">1</Publish>
+ <Publish Property="Progress2" Value="!(loc.MaintenanceTypeDlg_RepairProgress2)">1</Publish>
+ <Publish Event="NewDialog" Value="VBoxVerifyRepairDlg">1</Publish>
</Control>
<Control Id="RemoveLabel" Type="Text" X="105" Y="163" Width="100" Height="10" TabSkip="no">
- <Text>[DlgTitleFont]$(loc.MaintenanceTypeDlg_Remove)</Text>
+ <Text>[DlgTitleFont]!(loc.MaintenanceTypeDlg_Remove)</Text>
</Control>
- <Control Id="RemoveButton" Type="PushButton" X="50" Y="163" Width="38" Height="38" ToolTip="$(loc.MaintenanceTypeDlg_RemoveTooltip)"
+ <Control Id="RemoveButton" Type="PushButton" X="50" Y="163" Width="38" Height="38" ToolTip="!(loc.MaintenanceTypeDlg_RemoveTooltip)"
Icon="yes" FixedSize="yes" IconSize="32" Text="[RemoveIcon]">
<Publish Property="InstallMode" Value="Remove">1</Publish>
- <Publish Property="Progress1" Value="$(loc.MaintenanceTypeDlg_RemoveProgress1)">1</Publish>
- <Publish Property="Progress2" Value="$(loc.MaintenanceTypeDlg_RemoveProgress2)">1</Publish>
- <Publish Event="NewDialog" Value="VerifyRemoveDlg">1</Publish>
+ <Publish Property="Progress1" Value="!(loc.MaintenanceTypeDlg_RemoveProgress1)">1</Publish>
+ <Publish Property="Progress2" Value="!(loc.MaintenanceTypeDlg_RemoveProgress2)">1</Publish>
+ <Publish Event="NewDialog" Value="VBoxVerifyRemoveDlg">1</Publish>
</Control>
<!-- Build number text drawn left bottom -->
@@ -707,35 +715,35 @@
<Text>[Version_text] $(var.Property_Version)</Text>
</Control>
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="$(loc.ButtonText_Back)">
- <Publish Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.ButtonText_Back)">
+ <Publish Event="NewDialog" Value="VBoxMaintenanceWelcomeDlg">1</Publish>
</Control>
- <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Disabled="yes" Text="$(loc.ButtonText_Next)" />
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.ButtonText_Next)" />
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="20" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.MaintenanceTypeDlg_SelOption)</Text>
+ <Text>!(loc.MaintenanceTypeDlg_SelOption)</Text>
</Control>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="240" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>[DlgTitleFont]$(loc.MaintenanceTypeDlg_Header)</Text>
+ <Text>[DlgTitleFont]!(loc.MaintenanceTypeDlg_Header)</Text>
</Control>
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="RemoveText" Type="Text" X="105" Y="176" Width="230" Height="20">
- <Text>$(loc.MaintenanceTypeDlg_RemoveText)</Text>
+ <Text>!(loc.MaintenanceTypeDlg_RemoveText)</Text>
</Control>
<Control Id="RepairText" Type="Text" X="105" Y="102" Width="230" Height="30">
- <Text>$(loc.MaintenanceTypeDlg_RepairText)</Text>
+ <Text>!(loc.MaintenanceTypeDlg_RepairText)</Text>
</Control>
</Dialog>
<!-- This dialog is shown if the app is installed and the installation package is started again. It's the welcome
screen for maintenance -->
- <Dialog Id="MaintenanceWelcomeDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
+ <Dialog Id="VBoxMaintenanceWelcomeDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
- <Text>{\DlgVerdanaBold13}$(loc.MaintenanceWelcomeDlg_Header)</Text>
+ <Text>{\DlgVerdanaBold13}!(loc.MaintenanceWelcomeDlg_Header)</Text>
</Control>
<!-- Build number text drawn left bottom -->
@@ -743,42 +751,42 @@
<Text>[Version_text] $(var.Property_Version)</Text>
</Control>
- <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="$(loc.ButtonText_Next)">
- <Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">CostingComplete = 1</Publish>
- <Publish Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Next)">
+ <Publish Event="SpawnWaitDialog" Value="VBoxWaitForCostingDlg">CostingComplete = 1</Publish>
+ <Publish Event="NewDialog" Value="VBoxMaintenanceTypeDlg">1</Publish>
</Control>
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="[DialogBitmap]" />
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="$(loc.ButtonText_Back)" />
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.ButtonText_Back)" />
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.MaintenanceWelcomeDlg_Desc)</Text>
+ <Text>!(loc.MaintenanceWelcomeDlg_Desc)</Text>
</Control>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
</Dialog>
<!-- Out of disk error dialog -->
- <Dialog Id="OutOfDiskDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
+ <Dialog Id="VBoxOutOfDiskDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
<!-- Build number text drawn left bottom -->
<Control Id="Build" Type="Text" X="20" Y="247" Width="220" Height="10" Transparent="yes" NoPrefix="yes">
<Text>[Version_text] $(var.Property_Version)</Text>
</Control>
- <Control Id="OK" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="$(loc.ButtonText_OK)">
+ <Control Id="OK" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.ButtonText_OK)">
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
<Control Id="Description" Type="Text" X="20" Y="20" Width="280" Height="20" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.OutOfDiskDlg_InstallationExceeds)</Text>
+ <Text>!(loc.OutOfDiskDlg_InstallationExceeds)</Text>
</Control>
<Control Id="Text" Type="Text" X="20" Y="53" Width="330" Height="40">
- <Text>$(loc.OutOfDiskDlg_NotEnoughDiskSpace)</Text>
+ <Text>!(loc.OutOfDiskDlg_NotEnoughDiskSpace)</Text>
</Control>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>[DlgTitleFont]$(loc.OutOfDiskDlg_OutOfDiskSpace)</Text>
+ <Text>[DlgTitleFont]!(loc.OutOfDiskDlg_OutOfDiskSpace)</Text>
</Control>
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="VolumeList" Type="VolumeCostList" X="20" Y="100" Width="330" Height="120" Sunken="yes" Fixed="yes" Remote="yes">
@@ -786,78 +794,78 @@
</Control>
</Dialog>
- <Dialog Id="OutOfRbDiskDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
- <Control Id="No" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="$(loc.ButtonText_No)">
+ <Dialog Id="VBoxOutOfRbDiskDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
+ <Control Id="No" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.ButtonText_No)">
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
- <Control Id="Yes" Type="PushButton" X="240" Y="243" Width="56" Height="17" Text="$(loc.ButtonText_Yes)">
+ <Control Id="Yes" Type="PushButton" X="240" Y="243" Width="56" Height="17" Text="!(loc.ButtonText_Yes)">
<Publish Event="EnableRollback" Value="False">1</Publish>
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
<Control Id="Description" Type="Text" X="20" Y="20" Width="280" Height="20" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.OutOfRbDiskDlg_InstallationExceeds)</Text>
+ <Text>!(loc.OutOfRbDiskDlg_InstallationExceeds)</Text>
</Control>
<Control Id="Text" Type="Text" X="20" Y="53" Width="330" Height="40">
- <Text>$(loc.OutOfRbDiskDlg_NotEnoughDiskSpace)</Text>
+ <Text>!(loc.OutOfRbDiskDlg_NotEnoughDiskSpace)</Text>
</Control>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>[DlgTitleFont]$(loc.OutOfRbDiskDlg_OutOfDiskSpace)</Text>
+ <Text>[DlgTitleFont]!(loc.OutOfRbDiskDlg_OutOfDiskSpace)</Text>
</Control>
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="VolumeList" Type="VolumeCostList" X="20" Y="140" Width="330" Height="80" Sunken="yes" Fixed="yes" Remote="yes" ShowRollbackCost="yes">
<Text>{120}{70}{70}{70}{70}</Text>
</Control>
<Control Id="Text2" Type="Text" X="20" Y="94" Width="330" Height="40">
- <Text>$(loc.OutOfRbDiskDlg_Desc)</Text>
+ <Text>!(loc.OutOfRbDiskDlg_Desc)</Text>
</Control>
</Dialog>
- <Dialog Id="VerifyRemoveDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes" TrackDiskSpace="yes">
+ <Dialog Id="VBoxVerifyRemoveDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes" TrackDiskSpace="yes">
<!-- Build number text drawn left bottom -->
<Control Id="Build" Type="Text" X="20" Y="247" Width="220" Height="10" Transparent="yes" NoPrefix="yes">
<Text>[Version_text] $(var.Property_Version)</Text>
</Control>
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Default="yes" Text="$(loc.ButtonText_Back)">
- <Publish Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Back)">
+ <Publish Event="NewDialog" Value="VBoxMaintenanceTypeDlg">1</Publish>
</Control>
- <Control Id="Remove" Type="PushButton" X="236" Y="243" Width="56" Height="17" Text="$(loc.ButtonText_Remove)">
+ <Control Id="Remove" Type="PushButton" X="236" Y="243" Width="56" Height="17" Text="!(loc.ButtonText_Remove)">
<Publish Event="Remove" Value="All"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
- <Publish Event="SpawnDialog" Value="OutOfRbDiskDlg"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)]]></Publish>
+ <Publish Event="SpawnDialog" Value="VBoxOutOfRbDiskDlg"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)]]></Publish>
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"]]></Publish>
<Publish Event="EnableRollback" Value="False"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"]]></Publish>
- <Publish Event="SpawnDialog" Value="OutOfDiskDlg"><![CDATA[(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")]]></Publish>
+ <Publish Event="SpawnDialog" Value="VBoxOutOfDiskDlg"><![CDATA[(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")]]></Publish>
</Control>
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.VerifyRemoveDlg_Desc)</Text>
+ <Text>!(loc.VerifyRemoveDlg_Desc)</Text>
</Control>
<Control Id="Text" Type="Text" X="25" Y="70" Width="320" Height="30">
- <Text>$(loc.VerifyRemoveDlg_ClickRemove)</Text>
+ <Text>!(loc.VerifyRemoveDlg_ClickRemove)</Text>
</Control>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>[DlgTitleFont]$(loc.VerifyRemoveDlg_Header)</Text>
+ <Text>[DlgTitleFont]!(loc.VerifyRemoveDlg_Header)</Text>
</Control>
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
</Dialog>
- <Dialog Id="VerifyRepairDlg" Width="370" Height="270" Title="[ProductName] $(loc.Setup)" NoMinimize="yes" TrackDiskSpace="yes">
- <Control Id="Repair" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="$(loc.ButtonText_Repair)">
+ <Dialog Id="VBoxVerifyRepairDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes" TrackDiskSpace="yes">
+ <Control Id="Repair" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Repair)">
<Publish Event="ReinstallMode" Value="ecmus"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
<Publish Event="Reinstall" Value="All"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
- <Publish Event="SpawnDialog" Value="OutOfRbDiskDlg"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)]]></Publish>
+ <Publish Event="SpawnDialog" Value="VBoxOutOfRbDiskDlg"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)]]></Publish>
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"]]></Publish>
<Publish Event="EnableRollback" Value="False"><![CDATA[OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"]]></Publish>
- <Publish Event="SpawnDialog" Value="OutOfDiskDlg"><![CDATA[(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")]]></Publish>
+ <Publish Event="SpawnDialog" Value="VBoxOutOfDiskDlg"><![CDATA[(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")]]></Publish>
</Control>
<!-- Build number text drawn left bottom -->
@@ -865,61 +873,41 @@
<Text>[Version_text] $(var.Property_Version)</Text>
</Control>
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)">
+ <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish>
</Control>
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
- <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="$(loc.ButtonText_Back)">
- <Publish Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.ButtonText_Back)">
+ <Publish Event="NewDialog" Value="VBoxMaintenanceTypeDlg">1</Publish>
</Control>
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>$(loc.VerifyRepairDlg_ReadyToBegin)</Text>
+ <Text>!(loc.VerifyRepairDlg_ReadyToBegin)</Text>
</Control>
<Control Id="Text" Type="Text" X="25" Y="70" Width="320" Height="30">
- <Text>$(loc.VerifyRepairDlg_ClickRepair)</Text>
+ <Text>!(loc.VerifyRepairDlg_ClickRepair)</Text>
</Control>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
- <Text>[DlgTitleFont]$(loc.VerifyRepairDlg_Header)</Text>
+ <Text>[DlgTitleFont]!(loc.VerifyRepairDlg_Header)</Text>
</Control>
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
</Dialog>
- <Dialog Id="WaitForCostingDlg" Width="260" Height="85" Title="[ProductName] $(loc.Setup)" NoMinimize="yes">
+ <Dialog Id="VBoxWaitForCostingDlg" Width="260" Height="85" Title="[ProductName] !(loc.Setup)" NoMinimize="yes">
<Control Id="Return" Type="PushButton" X="102" Y="57" Width="56" Height="17" Default="yes" Cancel="yes" Text="[ButtonText_Return]">
<Publish Event="EndDialog" Value="Exit">1</Publish>
</Control>
<Control Id="Text" Type="Text" X="48" Y="15" Width="194" Height="30">
- <Text>$(loc.WaitForCostingDlg_PleaseWait)</Text>
+ <Text>!(loc.WaitForCostingDlg_PleaseWait)</Text>
</Control>
<Control Id="Icon" Type="Icon" X="15" Y="15" Width="24" Height="24" ToolTip="Exclamation icon" FixedSize="yes" IconSize="32" Text="[ExclamationIcon]" />
</Dialog>
- <!-- Dialogs used by the .MSI internally. -->
- <Dialog Id="MsiRMFilesInUse" Width="370" Height="270" Title="[ProductName] $(loc.Setup) Test" KeepModeless="yes">
- <Control Id="OK" Type="PushButton" X="240" Y="243" Width="56" Height="17" Default="yes" Text="$(loc.ButtonText_OK)">
- <Publish Event="EndDialog" Value="Return">1</Publish>
- <Publish Event="RMShutdownAndRestart" Value="0">WixUIRMOption~="UseRM"</Publish>
- </Control>
- <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="$(loc.ButtonText_Cancel)">
- <Publish Event="EndDialog" Value="Exit">1</Publish>
- </Control>
- <Control Id="ShutdownOption" Type="RadioButtonGroup" X="26" Y="190" Width="305" Height="45" Property="WixUIRMOption">
- <RadioButtonGroup Property="WixUIRMOption">
- <RadioButton Value="UseRM" X="0" Y="0" Width="295" Height="16" Text="$(loc.MsiRMFilesInUse_UseRM)" />
- <RadioButton Value="DontUseRM" X="0" Y="20" Width="295" Height="16" Text="$(loc.MsiRMFilesInUse_DontUseRM)" />
- </RadioButtonGroup>
- </Control>
- <Control Id="List" Type="ListBox" X="20" Y="100" Width="330" Height="100" Property="FileInUseProcess" Sunken="yes" TabSkip="yes" />
- <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" />
- <Control Id="Text" Type="Text" X="20" Y="55" Width="330" Height="45" Text="$(loc.MsiRMFilesInUse_Text)" />
- <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
- <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
- <Control Id="Description" Type="Text" X="20" Y="23" Width="280" Height="20" Transparent="yes" NoPrefix="yes" Text="$(loc.MsiRMFilesInUse_Description)" />
- <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="$(loc.MsiRMFilesInUse_Title)" />
- </Dialog>
+ <!-- Dialog property table. -->
+ <Property Id="ErrorDialog" Value="VBoxFatalErrorDlg"/>
<!-- Define some textstyles used for formatting dialog items. -->
+ <Property Id="DefaultUIFont">DlgFont8</Property>
<TextStyle Id="DlgFont8" FaceName="Tahoma" Size="8" />
<TextStyle Id="DlgFontBold8" FaceName="Tahoma" Size="8" Bold="yes" />
<TextStyle Id="DlgVerdanaBold13" FaceName="Verdana" Size="13" Bold="yes" />
@@ -928,130 +916,130 @@
<!-- The UIText table contains the localized versions of some of the strings used in the user interface.
These strings are not part of any other table. The UIText table is for strings that have no logical place in any other table. -->
- <ProgressText Action="CostFinalize">$(loc.ProgressTextCostFinalize)</ProgressText>
- <ProgressText Action="CostInitialize">$(loc.ProgressTextCostInitialize)</ProgressText>
- <ProgressText Action="FileCost">$(loc.ProgressTextFileCost)</ProgressText>
- <ProgressText Action="InstallValidate">$(loc.ProgressTextInstallValidate)</ProgressText>
- <ProgressText Action="InstallFiles" Template="File: [1], Directory: [9], Size: [6]">$(loc.ProgressTextInstallFiles)</ProgressText>
- <ProgressText Action="InstallAdminPackage" Template="File: [1], Directory: [9], Size: [6]">$(loc.ProgressTextInstallAdminPackage)</ProgressText>
- <ProgressText Action="CreateShortcuts" Template="Shortcut: [1]">$(loc.ProgressTextCreateShortcuts)</ProgressText>
- <ProgressText Action="PublishComponents" Template="Component ID: [1], Qualifier: [2]">$(loc.ProgressTextPublishComponents)</ProgressText>
- <ProgressText Action="PublishFeatures" Template="Feature: [1]">$(loc.ProgressTextPublishFeatures)</ProgressText>
- <ProgressText Action="PublishProduct">$(loc.ProgressTextPublishProduct)</ProgressText>
- <ProgressText Action="RegisterClassInfo" Template="Class Id: [1]">$(loc.ProgressTextRegisterClassInfo)</ProgressText>
- <ProgressText Action="RegisterExtensionInfo" Template="Extension: [1]">$(loc.ProgressTextRegisterExtensionInfo)</ProgressText>
- <ProgressText Action="RegisterMIMEInfo" Template="MIME Content Type: [1], Extension: [2]">$(loc.ProgressTextRegisterMIMEInfo)</ProgressText>
- <ProgressText Action="RegisterProgIdInfo" Template="ProgId: [1]">$(loc.ProgressTextRegisterProgIdInfo)</ProgressText>
- <ProgressText Action="AllocateRegistrySpace" Template="Free space: [1]">$(loc.ProgressTextAllocateRegistrySpace)</ProgressText>
- <ProgressText Action="AppSearch" Template="Property: [1], Signature: [2]">$(loc.ProgressTextAppSearch)</ProgressText>
- <ProgressText Action="BindImage" Template="File: [1]">$(loc.ProgressTextBindImage)</ProgressText>
- <ProgressText Action="CCPSearch">$(loc.ProgressTextCCPSearch)</ProgressText>
- <ProgressText Action="CreateFolders" Template="Folder: [1]">$(loc.ProgressTextCreateFolders)</ProgressText>
- <ProgressText Action="DeleteServices" Template="Service: [1]">$(loc.ProgressTextDeleteServices)</ProgressText>
- <ProgressText Action="DuplicateFiles" Template="File: [1], Directory: [9], Size: [6]">$(loc.ProgressTextDuplicateFiles)</ProgressText>
- <ProgressText Action="FindRelatedProducts" Template="Found application: [1]">$(loc.ProgressTextFindRelatedProducts)</ProgressText>
- <ProgressText Action="InstallODBC">$(loc.ProgressTextInstallODBC)</ProgressText>
- <ProgressText Action="InstallServices" Template="Service: [2]">$(loc.ProgressTextInstallServices)</ProgressText>
- <ProgressText Action="LaunchConditions">$(loc.ProgressTextLaunchConditions)</ProgressText>
- <ProgressText Action="MigrateFeatureStates" Template="Application: [1]">$(loc.ProgressTextMigrateFeatureStates)</ProgressText>
- <ProgressText Action="MoveFiles" Template="File: [1], Directory: [9], Size: [6]">$(loc.ProgressTextMoveFiles)</ProgressText>
- <ProgressText Action="PatchFiles" Template="File: [1], Directory: [2], Size: [3]">$(loc.ProgressTextPatchFiles)</ProgressText>
- <ProgressText Action="ProcessComponents">$(loc.ProgressTextProcessComponents)</ProgressText>
- <ProgressText Action="RegisterComPlus" Template="AppId: [1]{{, AppType: [2], Users: [3], RSN: [4]}}">$(loc.ProgressTextRegisterComPlus)</ProgressText>
- <ProgressText Action="RegisterFonts" Template="Font: [1]">$(loc.ProgressTextRegisterFonts)</ProgressText>
- <ProgressText Action="RegisterProduct" Template="[1]">$(loc.ProgressTextRegisterProduct)</ProgressText>
- <ProgressText Action="RegisterTypeLibraries" Template="LibID: [1]">$(loc.ProgressTextRegisterTypeLibraries)</ProgressText>
- <ProgressText Action="RegisterUser" Template="[1]">$(loc.ProgressTextRegisterUser)</ProgressText>
- <ProgressText Action="RemoveDuplicateFiles" Template="File: [1], Directory: [9]">$(loc.ProgressTextRemoveDuplicateFiles)</ProgressText>
- <ProgressText Action="RemoveEnvironmentStrings" Template="Name: [1], Value: [2], Action [3]">$(loc.ProgressTextRemoveEnvironmentStrings)</ProgressText>
- <ProgressText Action="RemoveExistingProducts" Template="Application: [1], Command line: [2]">$(loc.ProgressTextRemoveExistingProducts)</ProgressText>
- <ProgressText Action="RemoveFiles" Template="File: [1], Directory: [9]">$(loc.ProgressTextRemoveFiles)</ProgressText>
- <ProgressText Action="RemoveFolders" Template="Folder: [1]">$(loc.ProgressTextRemoveFolders)</ProgressText>
- <ProgressText Action="RemoveIniValues" Template="File: [1], Section: [2], Key: [3], Value: [4]">$(loc.ProgressTextRemoveIniValues)</ProgressText>
- <ProgressText Action="RemoveODBC">$(loc.ProgressTextRemoveODBC)</ProgressText>
- <ProgressText Action="RemoveRegistryValues" Template="Key: [1], Name: [2]">$(loc.ProgressTextRemoveRegistryValues)</ProgressText>
- <ProgressText Action="RemoveShortcuts" Template="Shortcut: [1]">$(loc.ProgressTextRemoveShortcuts)</ProgressText>
- <ProgressText Action="RMCCPSearch">$(loc.ProgressTextRMCCPSearch)</ProgressText>
- <ProgressText Action="SelfRegModules" Template="File: [1], Folder: [2]">$(loc.ProgressTextSelfRegModules)</ProgressText>
- <ProgressText Action="SelfUnregModules" Template="File: [1], Folder: [2]">$(loc.ProgressTextSelfUnregModules)</ProgressText>
- <ProgressText Action="SetODBCFolders">$(loc.ProgressTextSetODBCFolders)</ProgressText>
- <ProgressText Action="StartServices" Template="Service: [1]">$(loc.ProgressTextStartServices)</ProgressText>
- <ProgressText Action="StopServices" Template="Service: [1]">$(loc.ProgressTextStopServices)</ProgressText>
- <ProgressText Action="UnpublishComponents" Template="Component ID: [1], Qualifier: [2]">$(loc.ProgressTextUnpublishComponents)</ProgressText>
- <ProgressText Action="UnpublishFeatures" Template="Feature: [1]">$(loc.ProgressTextUnpublishFeatures)</ProgressText>
- <ProgressText Action="UnregisterClassInfo" Template="Class Id: [1]">$(loc.ProgressTextUnregisterClassInfo)</ProgressText>
- <ProgressText Action="UnregisterComPlus" Template="AppId: [1]{{, AppType: [2]}}">$(loc.ProgressTextUnregisterComPlus)</ProgressText>
- <ProgressText Action="UnregisterExtensionInfo" Template="Extension: [1]">$(loc.ProgressTextUnregisterExtensionInfo)</ProgressText>
- <ProgressText Action="UnregisterFonts" Template="Font: [1]">$(loc.ProgressTextUnregisterFonts)</ProgressText>
- <ProgressText Action="UnregisterMIMEInfo" Template="MIME Content Type: [1], Extension: [2]">$(loc.ProgressTextUnregisterMIMEInfo)</ProgressText>
- <ProgressText Action="UnregisterProgIdInfo" Template="ProgId: [1]">$(loc.ProgressTextUnregisterProgIdInfo)</ProgressText>
- <ProgressText Action="UnregisterTypeLibraries" Template="LibID: [1]">$(loc.ProgressTextUnregisterTypeLibraries)</ProgressText>
- <ProgressText Action="WriteEnvironmentStrings" Template="Name: [1], Value: [2], Action [3]">$(loc.ProgressTextWriteEnvironmentStrings)</ProgressText>
- <ProgressText Action="WriteIniValues" Template="File: [1], Section: [2], Key: [3], Value: [4]">$(loc.ProgressTextWriteIniValues)</ProgressText>
- <ProgressText Action="WriteRegistryValues" Template="Key: [1], Name: [2], Value: [3]">$(loc.ProgressTextWriteRegistryValues)</ProgressText>
- <ProgressText Action="Advertise">$(loc.ProgressTextAdvertise)</ProgressText>
- <ProgressText Action="GenerateScript" Template="[1]">$(loc.ProgressTextGenerateScript)</ProgressText>
- <ProgressText Action="InstallSFPCatalogFile" Template="File: [1], Dependencies: [2]">$(loc.ProgressTextInstallSFPCatalogFile)</ProgressText>
- <ProgressText Action="MsiPublishAssemblies" Template="Application Context:[1], Assembly Name:[2]">$(loc.ProgressTextMsiPublishAssemblies)</ProgressText>
- <ProgressText Action="MsiUnpublishAssemblies" Template="Application Context:[1], Assembly Name:[2]">$(loc.ProgressTextMsiUnpublishAssemblies)</ProgressText>
- <ProgressText Action="Rollback" Template="[1]">$(loc.ProgressTextRollback)</ProgressText>
- <ProgressText Action="RollbackCleanup" Template="File: [1]">$(loc.ProgressTextRollbackCleanup)</ProgressText>
- <ProgressText Action="UnmoveFiles" Template="File: [1], Directory: [9]">$(loc.ProgressTextUnmoveFiles)</ProgressText>
- <ProgressText Action="UnpublishProduct">$(loc.ProgressTextUnpublishProduct)</ProgressText>
-
- <UIText Id="bytes">$(loc.UITextbytes)</UIText>
- <UIText Id="GB">$(loc.UITextGB)</UIText>
- <UIText Id="KB">$(loc.UITextKB)</UIText>
- <UIText Id="MB">$(loc.UITextMB)</UIText>
+ <ProgressText Action="CostFinalize">!(loc.ProgressTextCostFinalize)</ProgressText>
+ <ProgressText Action="CostInitialize">!(loc.ProgressTextCostInitialize)</ProgressText>
+ <ProgressText Action="FileCost">!(loc.ProgressTextFileCost)</ProgressText>
+ <ProgressText Action="InstallValidate">!(loc.ProgressTextInstallValidate)</ProgressText>
+ <ProgressText Action="InstallFiles" Template="File: [1], Directory: [9], Size: [6]">!(loc.ProgressTextInstallFiles)</ProgressText>
+ <ProgressText Action="InstallAdminPackage" Template="File: [1], Directory: [9], Size: [6]">!(loc.ProgressTextInstallAdminPackage)</ProgressText>
+ <ProgressText Action="CreateShortcuts" Template="Shortcut: [1]">!(loc.ProgressTextCreateShortcuts)</ProgressText>
+ <ProgressText Action="PublishComponents" Template="Component ID: [1], Qualifier: [2]">!(loc.ProgressTextPublishComponents)</ProgressText>
+ <ProgressText Action="PublishFeatures" Template="Feature: [1]">!(loc.ProgressTextPublishFeatures)</ProgressText>
+ <ProgressText Action="PublishProduct">!(loc.ProgressTextPublishProduct)</ProgressText>
+ <ProgressText Action="RegisterClassInfo" Template="Class Id: [1]">!(loc.ProgressTextRegisterClassInfo)</ProgressText>
+ <ProgressText Action="RegisterExtensionInfo" Template="Extension: [1]">!(loc.ProgressTextRegisterExtensionInfo)</ProgressText>
+ <ProgressText Action="RegisterMIMEInfo" Template="MIME Content Type: [1], Extension: [2]">!(loc.ProgressTextRegisterMIMEInfo)</ProgressText>
+ <ProgressText Action="RegisterProgIdInfo" Template="ProgId: [1]">!(loc.ProgressTextRegisterProgIdInfo)</ProgressText>
+ <ProgressText Action="AllocateRegistrySpace" Template="Free space: [1]">!(loc.ProgressTextAllocateRegistrySpace)</ProgressText>
+ <ProgressText Action="AppSearch" Template="Property: [1], Signature: [2]">!(loc.ProgressTextAppSearch)</ProgressText>
+ <ProgressText Action="BindImage" Template="File: [1]">!(loc.ProgressTextBindImage)</ProgressText>
+ <ProgressText Action="CCPSearch">!(loc.ProgressTextCCPSearch)</ProgressText>
+ <ProgressText Action="CreateFolders" Template="Folder: [1]">!(loc.ProgressTextCreateFolders)</ProgressText>
+ <ProgressText Action="DeleteServices" Template="Service: [1]">!(loc.ProgressTextDeleteServices)</ProgressText>
+ <ProgressText Action="DuplicateFiles" Template="File: [1], Directory: [9], Size: [6]">!(loc.ProgressTextDuplicateFiles)</ProgressText>
+ <ProgressText Action="FindRelatedProducts" Template="Found application: [1]">!(loc.ProgressTextFindRelatedProducts)</ProgressText>
+ <ProgressText Action="InstallODBC">!(loc.ProgressTextInstallODBC)</ProgressText>
+ <ProgressText Action="InstallServices" Template="Service: [2]">!(loc.ProgressTextInstallServices)</ProgressText>
+ <ProgressText Action="LaunchConditions">!(loc.ProgressTextLaunchConditions)</ProgressText>
+ <ProgressText Action="MigrateFeatureStates" Template="Application: [1]">!(loc.ProgressTextMigrateFeatureStates)</ProgressText>
+ <ProgressText Action="MoveFiles" Template="File: [1], Directory: [9], Size: [6]">!(loc.ProgressTextMoveFiles)</ProgressText>
+ <ProgressText Action="PatchFiles" Template="File: [1], Directory: [2], Size: [3]">!(loc.ProgressTextPatchFiles)</ProgressText>
+ <ProgressText Action="ProcessComponents">!(loc.ProgressTextProcessComponents)</ProgressText>
+ <ProgressText Action="RegisterComPlus" Template="AppId: [1]{{, AppType: [2], Users: [3], RSN: [4]}}">!(loc.ProgressTextRegisterComPlus)</ProgressText>
+ <ProgressText Action="RegisterFonts" Template="Font: [1]">!(loc.ProgressTextRegisterFonts)</ProgressText>
+ <ProgressText Action="RegisterProduct" Template="[1]">!(loc.ProgressTextRegisterProduct)</ProgressText>
+ <ProgressText Action="RegisterTypeLibraries" Template="LibID: [1]">!(loc.ProgressTextRegisterTypeLibraries)</ProgressText>
+ <ProgressText Action="RegisterUser" Template="[1]">!(loc.ProgressTextRegisterUser)</ProgressText>
+ <ProgressText Action="RemoveDuplicateFiles" Template="File: [1], Directory: [9]">!(loc.ProgressTextRemoveDuplicateFiles)</ProgressText>
+ <ProgressText Action="RemoveEnvironmentStrings" Template="Name: [1], Value: [2], Action [3]">!(loc.ProgressTextRemoveEnvironmentStrings)</ProgressText>
+ <ProgressText Action="RemoveExistingProducts" Template="Application: [1], Command line: [2]">!(loc.ProgressTextRemoveExistingProducts)</ProgressText>
+ <ProgressText Action="RemoveFiles" Template="File: [1], Directory: [9]">!(loc.ProgressTextRemoveFiles)</ProgressText>
+ <ProgressText Action="RemoveFolders" Template="Folder: [1]">!(loc.ProgressTextRemoveFolders)</ProgressText>
+ <ProgressText Action="RemoveIniValues" Template="File: [1], Section: [2], Key: [3], Value: [4]">!(loc.ProgressTextRemoveIniValues)</ProgressText>
+ <ProgressText Action="RemoveODBC">!(loc.ProgressTextRemoveODBC)</ProgressText>
+ <ProgressText Action="RemoveRegistryValues" Template="Key: [1], Name: [2]">!(loc.ProgressTextRemoveRegistryValues)</ProgressText>
+ <ProgressText Action="RemoveShortcuts" Template="Shortcut: [1]">!(loc.ProgressTextRemoveShortcuts)</ProgressText>
+ <ProgressText Action="RMCCPSearch">!(loc.ProgressTextRMCCPSearch)</ProgressText>
+ <ProgressText Action="SelfRegModules" Template="File: [1], Folder: [2]">!(loc.ProgressTextSelfRegModules)</ProgressText>
+ <ProgressText Action="SelfUnregModules" Template="File: [1], Folder: [2]">!(loc.ProgressTextSelfUnregModules)</ProgressText>
+ <ProgressText Action="SetODBCFolders">!(loc.ProgressTextSetODBCFolders)</ProgressText>
+ <ProgressText Action="StartServices" Template="Service: [1]">!(loc.ProgressTextStartServices)</ProgressText>
+ <ProgressText Action="StopServices" Template="Service: [1]">!(loc.ProgressTextStopServices)</ProgressText>
+ <ProgressText Action="UnpublishComponents" Template="Component ID: [1], Qualifier: [2]">!(loc.ProgressTextUnpublishComponents)</ProgressText>
+ <ProgressText Action="UnpublishFeatures" Template="Feature: [1]">!(loc.ProgressTextUnpublishFeatures)</ProgressText>
+ <ProgressText Action="UnregisterClassInfo" Template="Class Id: [1]">!(loc.ProgressTextUnregisterClassInfo)</ProgressText>
+ <ProgressText Action="UnregisterComPlus" Template="AppId: [1]{{, AppType: [2]}}">!(loc.ProgressTextUnregisterComPlus)</ProgressText>
+ <ProgressText Action="UnregisterExtensionInfo" Template="Extension: [1]">!(loc.ProgressTextUnregisterExtensionInfo)</ProgressText>
+ <ProgressText Action="UnregisterFonts" Template="Font: [1]">!(loc.ProgressTextUnregisterFonts)</ProgressText>
+ <ProgressText Action="UnregisterMIMEInfo" Template="MIME Content Type: [1], Extension: [2]">!(loc.ProgressTextUnregisterMIMEInfo)</ProgressText>
+ <ProgressText Action="UnregisterProgIdInfo" Template="ProgId: [1]">!(loc.ProgressTextUnregisterProgIdInfo)</ProgressText>
+ <ProgressText Action="UnregisterTypeLibraries" Template="LibID: [1]">!(loc.ProgressTextUnregisterTypeLibraries)</ProgressText>
+ <ProgressText Action="WriteEnvironmentStrings" Template="Name: [1], Value: [2], Action [3]">!(loc.ProgressTextWriteEnvironmentStrings)</ProgressText>
+ <ProgressText Action="WriteIniValues" Template="File: [1], Section: [2], Key: [3], Value: [4]">!(loc.ProgressTextWriteIniValues)</ProgressText>
+ <ProgressText Action="WriteRegistryValues" Template="Key: [1], Name: [2], Value: [3]">!(loc.ProgressTextWriteRegistryValues)</ProgressText>
+ <ProgressText Action="Advertise">!(loc.ProgressTextAdvertise)</ProgressText>
+ <ProgressText Action="GenerateScript" Template="[1]">!(loc.ProgressTextGenerateScript)</ProgressText>
+ <ProgressText Action="InstallSFPCatalogFile" Template="File: [1], Dependencies: [2]">!(loc.ProgressTextInstallSFPCatalogFile)</ProgressText>
+ <ProgressText Action="MsiPublishAssemblies" Template="Application Context:[1], Assembly Name:[2]">!(loc.ProgressTextMsiPublishAssemblies)</ProgressText>
+ <ProgressText Action="MsiUnpublishAssemblies" Template="Application Context:[1], Assembly Name:[2]">!(loc.ProgressTextMsiUnpublishAssemblies)</ProgressText>
+ <ProgressText Action="Rollback" Template="[1]">!(loc.ProgressTextRollback)</ProgressText>
+ <ProgressText Action="RollbackCleanup" Template="File: [1]">!(loc.ProgressTextRollbackCleanup)</ProgressText>
+ <ProgressText Action="UnmoveFiles" Template="File: [1], Directory: [9]">!(loc.ProgressTextUnmoveFiles)</ProgressText>
+ <ProgressText Action="UnpublishProduct">!(loc.ProgressTextUnpublishProduct)</ProgressText>
+
+ <UIText Id="bytes">!(loc.UITextbytes)</UIText>
+ <UIText Id="GB">!(loc.UITextGB)</UIText>
+ <UIText Id="KB">!(loc.UITextKB)</UIText>
+ <UIText Id="MB">!(loc.UITextMB)</UIText>
<UIText Id="AbsentPath"><![CDATA[-]]></UIText>
- <UIText Id="MenuAbsent">$(loc.UITextMenuAbsent)</UIText>
- <UIText Id="MenuAdvertise">$(loc.UITextMenuAdvertise)</UIText>
- <UIText Id="MenuAllCD">$(loc.UITextMenuAllCD)</UIText>
- <UIText Id="MenuAllLocal">$(loc.UITextMenuAllLocal)</UIText>
- <UIText Id="MenuAllNetwork">$(loc.UITextMenuAllNetwork)</UIText>
- <UIText Id="MenuCD">$(loc.UITextMenuCD)</UIText>
- <UIText Id="MenuLocal">$(loc.UITextMenuLocal)</UIText>
- <UIText Id="MenuNetwork">$(loc.UITextMenuNetwork)</UIText>
- <UIText Id="ScriptInProgress">$(loc.UITextScriptInProgress)</UIText>
- <UIText Id="SelAbsentAbsent">$(loc.UITextSelAbsentAbsent)</UIText>
- <UIText Id="SelAbsentAdvertise">$(loc.UITextSelAbsentAdvertise)</UIText>
- <UIText Id="SelAbsentCD">$(loc.UITextSelAbsentCD)</UIText>
- <UIText Id="SelAbsentLocal">$(loc.UITextSelAbsentLocal)</UIText>
- <UIText Id="SelAbsentNetwork">$(loc.UITextSelAbsentNetwork)</UIText>
- <UIText Id="SelAdvertiseAbsent">$(loc.UITextSelAdvertiseAbsent)</UIText>
- <UIText Id="SelAdvertiseAdvertise">$(loc.UITextSelAdvertiseAdvertise)</UIText>
- <UIText Id="SelAdvertiseCD">$(loc.UITextSelAdvertiseCD)</UIText>
- <UIText Id="SelAdvertiseLocal">$(loc.UITextSelAdvertiseLocal)</UIText>
- <UIText Id="SelAdvertiseNetwork">$(loc.UITextSelAdvertiseNetwork)</UIText>
- <UIText Id="SelCDAbsent">$(loc.UITextSelCDAbsent)</UIText>
- <UIText Id="SelCDAdvertise">$(loc.UITextSelCDAdvertise)</UIText>
- <UIText Id="SelCDCD">$(loc.UITextSelCDCD)</UIText>
- <UIText Id="SelCDLocal">$(loc.UITextSelCDLocal)</UIText>
- <UIText Id="SelChildCostNeg">$(loc.UITextSelChildCostNeg)</UIText>
- <UIText Id="SelChildCostPos">$(loc.UITextSelChildCostPos)</UIText>
- <UIText Id="SelCostPending">$(loc.UITextSelCostPending)</UIText>
- <UIText Id="SelLocalAbsent">$(loc.UITextSelLocalAbsent)</UIText>
- <UIText Id="SelLocalAdvertise">$(loc.UITextSelLocalAdvertise)</UIText>
- <UIText Id="SelLocalCD">$(loc.UITextSelLocalCD)</UIText>
- <UIText Id="SelLocalLocal">$(loc.UITextSelLocalLocal)</UIText>
- <UIText Id="SelLocalNetwork">$(loc.UITextSelLocalNetwork)</UIText>
- <UIText Id="SelNetworkAbsent">$(loc.UITextSelNetworkAbsent)</UIText>
- <UIText Id="SelNetworkAdvertise">$(loc.UITextSelNetworkAdvertise)</UIText>
- <UIText Id="SelNetworkLocal">$(loc.UITextSelNetworkLocal)</UIText>
- <UIText Id="SelNetworkNetwork">$(loc.UITextSelNetworkNetwork)</UIText>
- <UIText Id="SelParentCostNegNeg">$(loc.UITextSelParentCostNegNeg)</UIText>
- <UIText Id="SelParentCostNegPos">$(loc.UITextSelParentCostNegPos)</UIText>
- <UIText Id="SelParentCostPosNeg">$(loc.UITextSelParentCostPosNeg)</UIText>
- <UIText Id="SelParentCostPosPos">$(loc.UITextSelParentCostPosPos)</UIText>
- <UIText Id="TimeRemaining">$(loc.UITextTimeRemaining)</UIText>
- <UIText Id="VolumeCostAvailable">$(loc.UITextVolumeCostAvailable)</UIText>
- <UIText Id="VolumeCostDifference">$(loc.UITextVolumeCostDifference)</UIText>
- <UIText Id="VolumeCostRequired">$(loc.UITextVolumeCostRequired)</UIText>
- <UIText Id="VolumeCostSize">$(loc.UITextVolumeCostSize)</UIText>
- <UIText Id="VolumeCostVolume">$(loc.UITextVolumeCostVolume)</UIText>
+ <UIText Id="MenuAbsent">!(loc.UITextMenuAbsent)</UIText>
+ <UIText Id="MenuAdvertise">!(loc.UITextMenuAdvertise)</UIText>
+ <UIText Id="MenuAllCD">!(loc.UITextMenuAllCD)</UIText>
+ <UIText Id="MenuAllLocal">!(loc.UITextMenuAllLocal)</UIText>
+ <UIText Id="MenuAllNetwork">!(loc.UITextMenuAllNetwork)</UIText>
+ <UIText Id="MenuCD">!(loc.UITextMenuCD)</UIText>
+ <UIText Id="MenuLocal">!(loc.UITextMenuLocal)</UIText>
+ <UIText Id="MenuNetwork">!(loc.UITextMenuNetwork)</UIText>
+ <UIText Id="ScriptInProgress">!(loc.UITextScriptInProgress)</UIText>
+ <UIText Id="SelAbsentAbsent">!(loc.UITextSelAbsentAbsent)</UIText>
+ <UIText Id="SelAbsentAdvertise">!(loc.UITextSelAbsentAdvertise)</UIText>
+ <UIText Id="SelAbsentCD">!(loc.UITextSelAbsentCD)</UIText>
+ <UIText Id="SelAbsentLocal">!(loc.UITextSelAbsentLocal)</UIText>
+ <UIText Id="SelAbsentNetwork">!(loc.UITextSelAbsentNetwork)</UIText>
+ <UIText Id="SelAdvertiseAbsent">!(loc.UITextSelAdvertiseAbsent)</UIText>
+ <UIText Id="SelAdvertiseAdvertise">!(loc.UITextSelAdvertiseAdvertise)</UIText>
+ <UIText Id="SelAdvertiseCD">!(loc.UITextSelAdvertiseCD)</UIText>
+ <UIText Id="SelAdvertiseLocal">!(loc.UITextSelAdvertiseLocal)</UIText>
+ <UIText Id="SelAdvertiseNetwork">!(loc.UITextSelAdvertiseNetwork)</UIText>
+ <UIText Id="SelCDAbsent">!(loc.UITextSelCDAbsent)</UIText>
+ <UIText Id="SelCDAdvertise">!(loc.UITextSelCDAdvertise)</UIText>
+ <UIText Id="SelCDCD">!(loc.UITextSelCDCD)</UIText>
+ <UIText Id="SelCDLocal">!(loc.UITextSelCDLocal)</UIText>
+ <UIText Id="SelChildCostNeg">!(loc.UITextSelChildCostNeg)</UIText>
+ <UIText Id="SelChildCostPos">!(loc.UITextSelChildCostPos)</UIText>
+ <UIText Id="SelCostPending">!(loc.UITextSelCostPending)</UIText>
+ <UIText Id="SelLocalAbsent">!(loc.UITextSelLocalAbsent)</UIText>
+ <UIText Id="SelLocalAdvertise">!(loc.UITextSelLocalAdvertise)</UIText>
+ <UIText Id="SelLocalCD">!(loc.UITextSelLocalCD)</UIText>
+ <UIText Id="SelLocalLocal">!(loc.UITextSelLocalLocal)</UIText>
+ <UIText Id="SelLocalNetwork">!(loc.UITextSelLocalNetwork)</UIText>
+ <UIText Id="SelNetworkAbsent">!(loc.UITextSelNetworkAbsent)</UIText>
+ <UIText Id="SelNetworkAdvertise">!(loc.UITextSelNetworkAdvertise)</UIText>
+ <UIText Id="SelNetworkLocal">!(loc.UITextSelNetworkLocal)</UIText>
+ <UIText Id="SelNetworkNetwork">!(loc.UITextSelNetworkNetwork)</UIText>
+ <UIText Id="SelParentCostNegNeg">!(loc.UITextSelParentCostNegNeg)</UIText>
+ <UIText Id="SelParentCostNegPos">!(loc.UITextSelParentCostNegPos)</UIText>
+ <UIText Id="SelParentCostPosNeg">!(loc.UITextSelParentCostPosNeg)</UIText>
+ <UIText Id="SelParentCostPosPos">!(loc.UITextSelParentCostPosPos)</UIText>
+ <UIText Id="TimeRemaining">!(loc.UITextTimeRemaining)</UIText>
+ <UIText Id="VolumeCostAvailable">!(loc.UITextVolumeCostAvailable)</UIText>
+ <UIText Id="VolumeCostDifference">!(loc.UITextVolumeCostDifference)</UIText>
+ <UIText Id="VolumeCostRequired">!(loc.UITextVolumeCostRequired)</UIText>
+ <UIText Id="VolumeCostSize">!(loc.UITextVolumeCostSize)</UIText>
+ <UIText Id="VolumeCostVolume">!(loc.UITextVolumeCostVolume)</UIText>
<!-- Own error messages -->
- <Error Id="25001">$(loc.Error25001)</Error>
+ <Error Id="25001">!(loc.Error25001)</Error>
<!-- The text used in front of the build number -->
<Property Id="Version_text">Version</Property>
@@ -1062,46 +1050,55 @@
<!-- This property preselects the "Don't agree" radio button in the license page -->
<Property Id="IAgree">No</Property>
- <!-- Aliases for the icon files -->
- <Property Id="RemoveIcon">removico</Property>
- <Property Id="RepairIcon">repairic</Property>
-
<!-- Icon files used for the UI -->
- <Binary Id="removico" src="$(env.VBOX_PATH_WIN_INST_SRC)\Binary\Remove.ico" />
- <Binary Id="repairic" src="$(env.VBOX_PATH_WIN_INST_SRC)\Binary\Repair.ico" />
- <Binary Id="folderupico" src="$(env.VBOX_PATH_WIN_INST_SRC)\Binary\Up.ico" />
- <Binary Id="foldernewico" src="$(env.VBOX_PATH_WIN_INST_SRC)\Binary\New.ico" />
+ <Binary Id="infoico" SourceFile="$(env.VBOX_PATH_WIN_INST_SRC)\Binary\Info.ico" />
+ <Binary Id="exclico" SourceFile="$(env.VBOX_PATH_WIN_INST_SRC)\Binary\Exclamation.ico" />
+ <Binary Id="folderupico" SourceFile="$(env.VBOX_PATH_WIN_INST_SRC)\Binary\Up.ico" />
+ <Binary Id="foldernewico" SourceFile="$(env.VBOX_PATH_WIN_INST_SRC)\Binary\New.ico" />
+ <Binary Id="removico" SourceFile="$(env.VBOX_PATH_WIN_INST_SRC)\Binary\Remove.ico" />
+ <Binary Id="repairic" SourceFile="$(env.VBOX_PATH_WIN_INST_SRC)\Binary\Repair.ico" />
<!-- Graphic files used for the UI -->
<!-- See: http://wix.sourceforge.net/manual-wix3/WixUI_customizations.htm -->
- <Binary Id="bannerjpg" src="$(env.VBOX_PATH_WIN_INST_SRC)\Binary\Banner.jpg" />
- <Binary Id="dlgjpg" src="$(env.VBOX_BRAND_WIN_INST_DLGJPG)" />
+ <Binary Id="bannerjpg" SourceFile="$(env.VBOX_PATH_WIN_INST_SRC)\Binary\Banner.jpg" />
+ <Binary Id="dlgjpg" SourceFile="$(env.VBOX_BRAND_WIN_INST_DLGJPG)" />
<!-- Aliases for the graphic files -->
+ <Property Id="InfoIcon">infoico</Property>
+ <Property Id="ExclamationIcon">exclico</Property>
+ <Property Id="RemoveIcon">removico</Property>
+ <Property Id="RepairIcon">repairic</Property>
<Property Id="DialogBitmap">dlgjpg</Property>
<Property Id="BannerBitmap">bannerjpg</Property>
<Property Id="FolderUp">folderupico</Property>
<Property Id="FolderNew">foldernewico</Property>
- <Binary Id="wixca" src="wixca.dll"/>
-
<!-- This defines the order in which the GUI panels will be shown to the user -->
<InstallUISequence>
- <Custom Action="OriginalTargetDir" After="FileCost"><![CDATA[(NOT INSTALLDIR) AND (NOT EXISTINGINSTALLDIR)]]></Custom>
- <Custom Action="DefaultTargetDir" After="FileCost"><![CDATA[NOT Installed AND (NOT INSTALLDIR) AND EXISTINGINSTALLDIR]]></Custom>
+ <Custom Action="ca_OriginalTargetDir" After="FileCost"><![CDATA[(NOT INSTALLDIR) AND (NOT EXISTINGINSTALLDIR)]]></Custom>
+ <Custom Action="ca_DefaultTargetDir" After="FileCost"><![CDATA[NOT Installed AND (NOT INSTALLDIR) AND EXISTINGINSTALLDIR]]></Custom>
<FindRelatedProducts Suppress="no">1</FindRelatedProducts>
- <Show Dialog="FatalErrorDlg" OnExit="error" />
- <Show Dialog="UserExitDlg" OnExit="cancel" />
- <Show Dialog="PrepareDlg" After="LaunchConditions" />
- <Show Dialog="WelcomeDlg" After="MigrateFeatureStates">NOT Installed</Show>
- <Show Dialog="ResumeDlg" After="WelcomeDlg">Installed AND (RESUME OR Preselected)</Show>
- <Show Dialog="MaintenanceWelcomeDlg" After="ResumeDlg">Installed AND (NOT RESUME) AND (NOT Preselected)</Show>
- <Show Dialog="ExitDlg" OnExit="success">1</Show>
- <Show Dialog="ProgressDlg" After="MaintenanceWelcomeDlg" />
+ <Show Dialog="VBoxFatalErrorDlg" OnExit="error" />
+ <Show Dialog="VBoxUserExitDlg" OnExit="cancel" />
+ <Show Dialog="VBoxPrepareDlg" After="LaunchConditions" />
+ <Show Dialog="VBoxWelcomeDlg" After="MigrateFeatureStates">NOT Installed</Show>
+ <Show Dialog="VBoxResumeDlg" After="VBoxWelcomeDlg">Installed AND (RESUME OR Preselected)</Show>
+ <Show Dialog="VBoxMaintenanceWelcomeDlg" After="VBoxResumeDlg">Installed AND (NOT RESUME) AND (NOT Preselected)</Show>
+ <Show Dialog="VBoxExitDlg" OnExit="success">1</Show>
+ <Show Dialog="VBoxProgressDlg" After="VBoxMaintenanceWelcomeDlg" />
</InstallUISequence>
+
+ <!-- The AdminUISequence table lists actions that the installer calls in sequence when the top-level ADMIN
+ action is executed and the internal user interface level is set to full UI or reduced UI. The installer
+ skips the actions in this table if the user interface level is set to basic UI or no UI. -->
+ <AdminUISequence>
+ <Show Dialog="VBoxFatalErrorDlg" OnExit="error" />
+ <Show Dialog="VBoxUserExitDlg" OnExit="cancel" />
+ <Show Dialog="VBoxExitDlg" OnExit="success" />
+ </AdminUISequence>
</UI>
</Include>
diff --git a/src/VBox/Installer/win/VBoxKey.wxi b/src/VBox/Installer/win/VBoxKey.wxi
index e77a25590..6c7a503e5 100644
--- a/src/VBox/Installer/win/VBoxKey.wxi
+++ b/src/VBox/Installer/win/VBoxKey.wxi
@@ -1,5 +1,5 @@
<Include>
- <Registry Root="HKLM" Key="$(var.Property_RegKey)" Name="Version" Value="%VER%" Type="string" />
- <Registry Root="HKLM" Key="$(var.Property_RegKey)" Name="VersionExt" Value="%VER_EXT%" Type="string" />
- <Registry Root="HKLM" Key="$(var.Property_RegKey)" Name="InstallDir" Value="[INSTALLDIR]" Type="string" />
+ <RegistryValue Root="HKLM" Key="$(var.Property_RegKey)" Name="Version" Value="%VER%" Type="string" />
+ <RegistryValue Root="HKLM" Key="$(var.Property_RegKey)" Name="VersionExt" Value="%VER_EXT%" Type="string" />
+ <RegistryValue Root="HKLM" Key="$(var.Property_RegKey)" Name="InstallDir" Value="[INSTALLDIR]" Type="string" />
</Include>
diff --git a/src/VBox/Installer/win/VirtualBox.wxs b/src/VBox/Installer/win/VirtualBox.wxs
index a52f4310e..758ac52bb 100644
--- a/src/VBox/Installer/win/VirtualBox.wxs
+++ b/src/VBox/Installer/win/VirtualBox.wxs
@@ -13,7 +13,8 @@
hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-->
-<?define Property_RegKey ="Software\$(env.VBOX_VENDOR_SHORT)\VirtualBox" ?>
+<?define Property_RegKey = "Software\$(env.VBOX_VENDOR_SHORT)\VirtualBox" ?>
+<?define Property_RegKeyInstall = "Software\$(env.VBOX_VENDOR_SHORT)\VirtualBox\Install" ?>
<?define Property_Version = "$(env.VBOX_VERSION_STRING_RAW)" ?>
<?define Property_VersionExt = "$(env.VBOX_VERSION_STRING)" ?>
<?define Property_Upgrade = "yes" ?>
@@ -31,7 +32,7 @@
<?else ?>
<?define Property_ProgramFiles = "ProgramFilesFolder" ?>
- <?define Property_Platform = "Intel" ?>
+ <?define Property_Platform = "x86" ?>
<?define Property_Win64 = "no" ?>
<?if $(env.VBOX_SIGNING_MODE) != none ?>
@@ -49,7 +50,8 @@
<?define Property_DiskIdCommon = "1" ?>
<?endif ?>
-<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
+ xmlns:difxapp="http://schemas.microsoft.com/wix/DifxAppExtension">
<!-- Note: GUIDs in WiX *must* be uppercase! -->
<!-- Always include an upgrade ID or otherwise upgrade installation will not be possible. When doing
@@ -64,23 +66,23 @@
<!-- Old product ID: <Product Id="B59FE77B-738F-4f1c-AB48-3104895AF676"
Old upgrade code of innotek: UpgradeCode="F5FFAEBF-97AE-4038-8F91-4DE719456127" -->
- <Product Id="????????-????-????-????-????????????"
+ <Product Id="*"
UpgradeCode="C4BAD770-BFE8-4D2C-A592-693028A7215B"
Name="$(env.VBOX_PRODUCT) $(env.VBOX_VERSION_STRING)"
- Language="$(loc.LANG)"
+ Language="!(loc.LANG)"
Codepage="1252"
Version="$(var.Property_Version)"
Manufacturer="$(env.VBOX_VENDOR)">
<!-- Package GUIDs must be different for each package. The "???" directs WiX to create one. -->
- <Package Id="????????-????-????-????-????????????" Keywords="Installer"
+ <Package Id="*" Keywords="Installer"
Description="$(env.VBOX_PRODUCT) $(var.Property_VersionExt) installation package"
Comments="$(env.VBOX_PRODUCT) installation package"
Manufacturer="$(env.VBOX_VENDOR)"
InstallerVersion="200"
Compressed="yes"
InstallPrivileges="elevated"
- Platforms="$(var.Property_Platform)"/>
+ Platform="$(var.Property_Platform)"/>
<!-- *************************** Upgrade packages only ******************************* -->
<!-- Minimum and Maximum specify the range of versions we are supposed to update with this upgrade.
@@ -117,91 +119,97 @@
<!-- Make sure installation will not start on anything other but the NT family -->
<?if $(env.BUILD_TARGET_ARCH) = "amd64" ?>
- <Condition Message="$(loc.Only64Bit)">
+ <Condition Message="!(loc.Only64Bit)">
VersionNT64
</Condition>
<?else ?>
- <Condition Message="$(loc.Only32Bit)">
+ <Condition Message="!(loc.Only32Bit)">
NOT VersionNT64
</Condition>
- <Condition Message="$(loc.WrongOS)">
+ <Condition Message="!(loc.WrongOS)">
NOT VersionNT=500 AND NOT Version9X AND NOT VersionNT64
</Condition>
<?endif ?>
- <Condition Message="$(loc.NeedAdmin)">
+ <Condition Message="!(loc.NeedAdmin)">
Privileged
</Condition>
- <!-- Force overwriting all files and re-create shortcuts to guarantee a working environment. -->
+ <!-- Force overwriting all files and re-create shortcuts to guarantee a working environment -->
<Property Id='REINSTALLMODE' Value='amus'/>
<!-- Custom actions -->
<!-- Figure out where a previous installation was, if any -->
<?if $(env.BUILD_TARGET_ARCH) = "amd64" ?>
- <CustomAction Id="OriginalTargetDir" Execute="firstSequence" Property="INSTALLDIR" Value="[ProgramFiles64Folder]\$(env.VBOX_VENDOR_SHORT)\VirtualBox" />
+ <CustomAction Id="ca_OriginalTargetDir" Execute="firstSequence" Property="INSTALLDIR" Value="[ProgramFiles64Folder]\$(env.VBOX_VENDOR_SHORT)\VirtualBox" />
<Property Id="EXISTINGINSTALLDIR" Secure="yes">
<RegistrySearch Id="RegistryGetInstallPath" Root="HKLM" Key="$(var.Property_RegKey)" Name="InstallDir" Type="raw" Win64="$(var.Property_Win64)"/>
</Property>
- <CustomAction Id="DefaultTargetDir" Execute="firstSequence" Property="INSTALLDIR" Value="[EXISTINGINSTALLDIR]" />
+ <CustomAction Id="ca_DefaultTargetDir" Execute="firstSequence" Property="INSTALLDIR" Value="[EXISTINGINSTALLDIR]" />
<?else ?>
- <CustomAction Id="OriginalTargetDir" Execute="firstSequence" Property="INSTALLDIR" Value="[ProgramFilesFolder]\$(env.VBOX_VENDOR_SHORT)\VirtualBox" />
+ <CustomAction Id="ca_OriginalTargetDir" Execute="firstSequence" Property="INSTALLDIR" Value="[ProgramFilesFolder]\$(env.VBOX_VENDOR_SHORT)\VirtualBox" />
<Property Id="EXISTINGINSTALLDIR" Secure="yes">
<RegistrySearch Id="RegistryGetInstallPath" Root="HKLM" Key="$(var.Property_RegKey)" Name="InstallDir" Type="raw" Win64="$(var.Property_Win64)"/>
</Property>
- <CustomAction Id="DefaultTargetDir" Execute="firstSequence" Property="INSTALLDIR" Value="[EXISTINGINSTALLDIR]" />
+ <CustomAction Id="ca_DefaultTargetDir" Execute="firstSequence" Property="INSTALLDIR" Value="[EXISTINGINSTALLDIR]" />
<?endif ?>
<Binary Id="VBoxInstallHelper" SourceFile="$(env.PATH_OUT)\bin\VBoxInstallHelper.dll" />
- <CustomAction Id="CheckSerial" BinaryKey="VBoxInstallHelper" DllEntry="CheckSerial" Impersonate="no"/>
- <CustomAction Id="InstallPythonAPI" BinaryKey="VBoxInstallHelper" DllEntry="InstallPythonAPI" Impersonate="no"/>
- <CustomAction Id="InstallBranding" BinaryKey="VBoxInstallHelper" DllEntry="InstallBranding" Impersonate="no"/>
- <CustomAction Id="UninstallBranding" BinaryKey="VBoxInstallHelper" DllEntry="UninstallBranding" Impersonate="no"/>
+ <CustomAction Id="ca_CheckSerial" BinaryKey="VBoxInstallHelper" DllEntry="CheckSerial" Impersonate="no"/>
- <CustomAction Id="UninstallTAPInstances" BinaryKey="VBoxInstallHelper"
- DllEntry="UninstallTAPInstances" Execute="deferred" Return="check" Impersonate="no"/>
+ <CustomAction Id="ca_InstallPythonAPI" BinaryKey="VBoxInstallHelper" DllEntry="InstallPythonAPI" Execute="deferred" Return="check" Impersonate="no"/>
+ <CustomAction Id="ca_InstallPythonAPIArgs" Property="ca_InstallPythonAPI" Value="[INSTALLDIR]" Execute="immediate"/>
+
+ <CustomAction Id="ca_InstallBranding" BinaryKey="VBoxInstallHelper" DllEntry="InstallBranding" Execute="deferred" Return="check" Impersonate="no"/>
+ <CustomAction Id="ca_InstallBrandingArgs" Property="ca_InstallBranding" Value="[INSTALLDIR]" Execute="immediate"/>
+
+ <CustomAction Id="ca_UninstallBranding" BinaryKey="VBoxInstallHelper" DllEntry="UninstallBranding" Execute="deferred" Return="check" Impersonate="no"/>
+ <CustomAction Id="ca_UninstallBrandingArgs" Property="ca_UninstallBranding" Value="[INSTALLDIR]" Execute="immediate"/>
+
+ <CustomAction Id="ca_UninstallTAPInstances" BinaryKey="VBoxInstallHelper"
+ DllEntry="UninstallTAPInstances" Execute="deferred" Return="check" Impersonate="no"/>
<?if $(env.VBOX_WITH_NETFLT) = "yes" ?>
- <CustomAction Id="CreateHostOnlyInterfaceArgs" Property="CreateHostOnlyInterface" Value="[INSTALLDIR]" Execute="immediate"/>
- <CustomAction Id="CreateHostOnlyInterface" BinaryKey="VBoxInstallHelper" DllEntry="CreateHostOnlyInterface" Execute="deferred" Return="check" Impersonate="no"/>
+ <CustomAction Id="ca_CreateHostOnlyInterface" BinaryKey="VBoxInstallHelper" DllEntry="CreateHostOnlyInterface" Execute="deferred" Return="check" Impersonate="no"/>
+ <CustomAction Id="ca_CreateHostOnlyInterfaceArgs" Property="ca_CreateHostOnlyInterface" Value="[INSTALLDIR]" Execute="immediate"/>
- <CustomAction Id="RemoveHostOnlyInterfaces" BinaryKey="VBoxInstallHelper" DllEntry="RemoveHostOnlyInterfaces" Execute="deferred" Return="check" Impersonate="no"/>
+ <CustomAction Id="ca_RemoveHostOnlyInterfaces" BinaryKey="VBoxInstallHelper" DllEntry="RemoveHostOnlyInterfaces" Execute="deferred" Return="check" Impersonate="no"/>
- <CustomAction Id="InstallNetFlt" BinaryKey="VBoxInstallHelper" DllEntry="InstallNetFlt" Execute="deferred" Return="check" Impersonate="no"/>
- <CustomAction Id="InstallNetFltArgs" Property="InstallNetFlt" Value="[INSTALLDIR]" Execute="immediate"/>
+ <CustomAction Id="ca_InstallNetFlt" BinaryKey="VBoxInstallHelper" DllEntry="InstallNetFlt" Execute="deferred" Return="check" Impersonate="no"/>
+ <CustomAction Id="ca_InstallNetFltArgs" Property="ca_InstallNetFlt" Value="[INSTALLDIR]" Execute="immediate"/>
- <CustomAction Id="RollbackInstallNetFlt" BinaryKey="VBoxInstallHelper" DllEntry="UninstallNetFlt" Execute="rollback" Impersonate="no"/>
- <CustomAction Id="RollbackInstallNetFltArgs" Property="RollbackInstallNetFlt" Value="[INSTALLDIR]" Execute="immediate"/>
+ <CustomAction Id="ca_RollbackInstallNetFlt" BinaryKey="VBoxInstallHelper" DllEntry="UninstallNetFlt" Execute="rollback" Impersonate="no"/>
+ <CustomAction Id="ca_RollbackInstallNetFltArgs" Property="ca_RollbackInstallNetFlt" Value="[INSTALLDIR]" Execute="immediate"/>
- <CustomAction Id="UninstallNetFlt" BinaryKey="VBoxInstallHelper" DllEntry="UninstallNetFlt" Execute="deferred" Return="check" Impersonate="no"/>
- <CustomAction Id="UninstallNetFltArgs" Property="UninstallNetFlt" Value="[INSTALLDIR]" Execute="immediate"/>
+ <CustomAction Id="ca_UninstallNetFlt" BinaryKey="VBoxInstallHelper" DllEntry="UninstallNetFlt" Execute="deferred" Return="check" Impersonate="no"/>
+ <CustomAction Id="ca_UninstallNetFltArgs" Property="ca_UninstallNetFlt" Value="[INSTALLDIR]" Execute="immediate"/>
- <CustomAction Id="RollbackUninstallNetFlt" BinaryKey="VBoxInstallHelper" DllEntry="InstallNetFlt" Execute="rollback" Impersonate="no"/>
- <CustomAction Id="RollbackUninstallNetFltArgs" Property="RollbackUninstallNetFlt" Value="[INSTALLDIR]" Execute="immediate"/>
+ <CustomAction Id="ca_RollbackUninstallNetFlt" BinaryKey="VBoxInstallHelper" DllEntry="InstallNetFlt" Execute="rollback" Impersonate="no"/>
+ <CustomAction Id="ca_RollbackUninstallNetFltArgs" Property="ca_RollbackUninstallNetFlt" Value="[INSTALLDIR]" Execute="immediate"/>
<?endif ?>
- <CustomAction Id="StartVBox" FileKey="vbox" ExeCommand="" Return="asyncNoWait" Impersonate="yes" />
+ <CustomAction Id="ca_StartVBox" FileKey="file_VirtualBox.exe" ExeCommand="" Return="asyncNoWait" Impersonate="yes" />
- <!-- Detect old Sun installation. -->
- <!-- Force a manual uninstall of an already installed Sun VirtualBox version first. -->
+ <!-- Detect old Sun installation -->
+ <!-- Force a manual uninstall of an already installed Sun VirtualBox version first -->
<!--<Property Id="VBOXSUN">
<RegistrySearch Id="RegSearchSunVersion" Root="HKLM" Key="SOFTWARE\Sun\VirtualBox" Name="Version" Type="raw" Win64="$(var.Property_Win64)"/>
</Property>
- <Condition Message="$(loc.SunFound)">
+ <Condition Message="!(loc.SunFound)">
NOT VBOXSUN
</Condition>-->
- <!-- Detect old innotek installation. -->
- <!-- Force a manual uninstall of an already installed innotek VirtualBox version first. -->
+ <!-- Detect old innotek installation -->
+ <!-- Force a manual uninstall of an already installed innotek VirtualBox version first -->
<Property Id="VBOXINNOTEK">
<RegistrySearch Id="RegSearchInnotekVersion" Root="HKLM" Key="SOFTWARE\Innotek\VirtualBox" Name="Version" Type="raw" Win64="$(var.Property_Win64)"/>
</Property>
- <Condition Message="$(loc.InnotekFound)">
+ <Condition Message="!(loc.InnotekFound)">
NOT VBOXINNOTEK
</Condition>
@@ -213,110 +221,106 @@
<!-- Here comes the file/directory list. -->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="$(var.Property_ProgramFiles)" Name="PFiles">
- <Directory Id="INSTALLDIR" Name="VirtualB" LongName="$(env.VBOX_PRODUCT)">
+ <Directory Id="INSTALLDIR" Name="$(env.VBOX_PRODUCT)">
<?if $(env.VBOX_WITH_DOCS_PACKING) = "yes" ?>
- <Directory Id="documents" Name="doc">
+ <Directory Id="dir_Documents" Name="doc">
<!-- The documentation is a separate component. This allows to split the install process
into pieces if ever necessary. Maintenance is easier, too. The following component
will be installed in the "doc" folder. -->
- <Component Id="docs" Guid="40BD12C5-89A8-4B81-8A5E-5EEE2C2763C4">
+ <Component Id="cp_Docs" Guid="40BD12C5-89A8-4B81-8A5E-5EEE2C2763C4">
<?include $(env.PATH_TARGET)\Files_Doc.wxi ?>
</Component>
-
</Directory>
<?endif ?>
<!-- Device driver directory -->
- <Directory Id="drivers" Name="drivers">
-
- <Directory Id="vboxdrv" Name="vboxdrv">
- <Component Id="VBoxDrv" Guid="D3E2F2BB-569F-46A2-836C-BDF30FF1EDF8"
- DriverSequence="2" DriverLegacy="$(var.Property_DriverLegacy)" DriverForceInstall="yes"
- DriverAddRemovePrograms="no" DriverPlugAndPlayPrompt="no" Win64="$(var.Property_Win64)">
- <File Id="vboxdrvsys" Name="VBoxDrv.sys" DiskId="1" Vital="yes" KeyPath="yes"
+ <Directory Id="dir_Drivers" Name="drivers">
+ <Directory Id="dir_VBoxDrv" Name="vboxdrv">
+ <Component Id="cp_VBoxDrv" Guid="D3E2F2BB-569F-46A2-836C-BDF30FF1EDF8" Win64="$(var.Property_Win64)">
+ <difxapp:Driver AddRemovePrograms="no" ForceInstall="yes"
+ Legacy="$(var.Property_DriverLegacy)" Sequence="2" PlugAndPlayPrompt="no"/>
+ <File Id="file_VBoxDrv.sys" Name="VBoxDrv.sys" KeyPath="yes"
Source="$(env.PATH_OUT)\bin\VBoxDrv.sys"/>
- <File Id="vboxdrvinf" Name="VBoxDrv.inf" DiskId="1" Vital="yes"
+ <File Id="file_VBoxDrv.inf" Name="VBoxDrv.inf"
Source="$(env.PATH_OUT)\bin\VBoxDrv.inf" />
<?if $(env.VBOX_SIGNING_MODE) != none ?>
- <File Id="vboxdrvcat" Name="VBoxDrv.cat" DiskId="1" Vital="yes"
+ <File Id="file_VBoxDrv.cat" Name="VBoxDrv.cat"
Source="$(env.PATH_OUT)\bin\VBoxDrv.cat" />
<?endif ?>
- </Component> <!-- Directory "drivers\vboxdrv" -->
+ </Component>
</Directory>
- <Directory Id="usbdrv" Name="USB">
- <Directory Id="usbfilter" Name="filter">
- <Component Id="USBFilterDriver" Guid="B7D782D2-96DF-4775-A0E1-A76CF7B04B65"
- DriverSequence="0" DriverLegacy="$(var.Property_DriverLegacy)" DriverForceInstall="yes"
- DriverAddRemovePrograms="no" DriverPlugAndPlayPrompt="no" Win64="$(var.Property_Win64)">
- <File Id="vboxusbmon" Name="VBoxUSBM.sys" LongName="VBoxUSBMon.sys" DiskId="1" Vital="yes"
+ <Directory Id="dir_USB" Name="USB">
+ <Directory Id="dir_USBFilter" Name="filter">
+ <Component Id="cp_USBFilterDriver" Guid="B7D782D2-96DF-4775-A0E1-A76CF7B04B65" Win64="$(var.Property_Win64)">
+ <difxapp:Driver AddRemovePrograms="no" ForceInstall="yes"
+ Legacy="$(var.Property_DriverLegacy)" Sequence="0" PlugAndPlayPrompt="no"/>
+ <File Id="file_VBoxUSBMon.sys" Name="VBoxUSBMon.sys"
Source="$(env.PATH_OUT)\bin\VBoxUSBMon.sys" />
- <File Id="vboxusbmoninf" Name="VBoxUSBM.inf" LongName="VBoxUSBMon.inf" DiskId="1" Vital="yes"
+ <File Id="file_VBoxUSBMon.inf" Name="VBoxUSBMon.inf"
Source="$(env.PATH_OUT)\bin\VBoxUSBMon.inf" />
<?if $(env.VBOX_SIGNING_MODE) != none ?>
- <File Id="vboxusbmoncat" Name="VBoxUSBM.cat" LongName="VBoxUSBMon.cat" DiskId="1" Vital="yes"
+ <File Id="file_VBoxUSBMon.cat" Name="VBoxUSBMon.cat"
Source="$(env.PATH_OUT)\bin\VBoxUSBMon.cat" />
<?endif ?>
- </Component> <!-- USBFilterDriver -->
- </Directory> <!-- Directory "drivers\usb\filter" -->
-
- <Directory Id="usbdevice" Name="device">
- <Component Id="USBDeviceDriver" Guid="010FE46A-E358-43E2-8BDC-38BC8BEC82E0"
- DriverSequence="0" DriverLegacy="$(var.Property_DriverLegacy)" DriverForceInstall="yes"
- DriverAddRemovePrograms="no" DriverPlugAndPlayPrompt="no" Win64="$(var.Property_Win64)">
- <File Id="vboxusbdrv" Name="VBoxUSB.sys" DiskId="1" Vital="yes"
+ </Component>
+ </Directory>
+
+ <Directory Id="dir_USBDevice" Name="device">
+ <Component Id="cp_USBDeviceDriver" Guid="010FE46A-E358-43E2-8BDC-38BC8BEC82E0" Win64="$(var.Property_Win64)">
+ <difxapp:Driver AddRemovePrograms="no" ForceInstall="yes"
+ Legacy="$(var.Property_DriverLegacy)" Sequence="0" PlugAndPlayPrompt="no"/>
+ <File Id="file_VBoxUSB.sys" Name="VBoxUSB.sys"
Source="$(env.PATH_OUT)\bin\VBoxUSB.sys" />
- <File Id="vboxusbinf" Name="VBoxUSB.inf" DiskId="1" Vital="yes"
+ <File Id="file_VBoxUSB.inf" Name="VBoxUSB.inf"
Source="$(env.PATH_OUT)\bin\VBoxUSB.inf" />
<?if $(env.VBOX_SIGNING_MODE) != none ?>
- <File Id="vboxusbcat" Name="VBoxUSB.cat" DiskId="1" Vital="yes"
+ <File Id="file_VBoxUSB.cat" Name="VBoxUSB.cat"
Source="$(env.PATH_OUT)\bin\VBoxUSB.cat" />
<?endif ?>
- </Component> <!-- USBDeviceDriver -->
- </Directory> <!-- Directory "drivers\usb\device" -->
- </Directory> <!-- Directory "drivers\usb" -->
+ </Component>
+ </Directory>
+ </Directory>
<?if $(env.VBOX_WITH_NETFLT) = "yes" ?>
- <Directory Id="network" Name="network">
- <Directory Id="NetFltDir" Name="netflt">
- <Component Id="NetFltDriver" Guid="F0A02F6B-A349-42f8-A2EB-569DCAAAF846" Win64="$(var.Property_Win64)">
- <File Id="vboxnetfltsys" Name="VBoxNFlt.sys" LongName="VBoxNetFlt.sys" DiskId="1" Vital="yes" KeyPath="yes"
- Source="$(env.PATH_OUT)\bin\VBoxNetFlt.sys"
- Checksum="yes"/>
- <File Id="vboxnetfltnotifydll" Name="VBoxNFN.dll" LongName="VBoxNetFltNotify.dll" DiskId="1" Vital="yes"
- Source="$(env.PATH_OUT)\bin\VBoxNetFltNotify.dll"
- Checksum="yes"/>
- <File Id="vboxnetfltinf" Name="VBoxNFlt.inf" LongName="VBoxNetFlt.inf" DiskId="1" Vital="yes"
- Source="$(env.PATH_OUT)\bin\VBoxNetFlt.inf" />
+ <Directory Id="dir_Network" Name="network">
+ <Directory Id="dir_NetFlt" Name="netflt">
+ <Component Id="cp_NetFltDriver" Guid="F0A02F6B-A349-42f8-A2EB-569DCAAAF846" Win64="$(var.Property_Win64)">
+ <File Id="file_VBoxNetFlt.sys" Name="VBoxNetFlt.sys" KeyPath="yes"
+ Source="$(env.PATH_OUT)\bin\VBoxNetFlt.sys" Checksum="yes"/>
+ <File Id="file_VBoxNetFltNobj.sys" Name="VBoxNetFltNobj.dll"
+ Source="$(env.PATH_OUT)\bin\VBoxNetFltNobj.dll" Checksum="yes"/>
+ <File Id="file_VBoxNetFltM.inf" Name="VBoxNetFltM.inf"
+ Source="$(env.PATH_OUT)\bin\VBoxNetFltM.inf" />
+ <File Id="file_VBoxNetFlt.inf" Name="VBoxNetFlt.inf"
+ Source="$(env.PATH_OUT)\bin\VBoxNetFlt.inf" />
<?if $(env.VBOX_SIGNING_MODE) != none ?>
- <File Id="vboxnetfltcat" Name="VBoxNFlt.cat" LongName="VBoxNetFlt.cat" DiskId="1" Vital="yes"
- Source="$(env.PATH_OUT)\bin\VBoxNetFlt.cat" />
+ <File Id="file_VBoxNetFlt.cat" Name="VBoxNetFlt.cat"
+ Source="$(env.PATH_OUT)\bin\VBoxNetFlt.cat" />
<?endif ?>
- <File Id="vboxnetflt_minf" Name="VBoxNFlM.inf" LongName="VBoxNetFlt_m.inf" DiskId="1" Vital="yes"
- Source="$(env.PATH_OUT)\bin\VBoxNetFlt_m.inf" />
</Component>
- </Directory> <!-- Directory "drivers\network\netflt" -->
- <Directory Id="NetAdpDir" Name="netadp">
- <Component Id="NetAdpDriver" Guid="7adf3e12-af3c-4d36-8bec-36d5064cf84f" Win64="$(var.Property_Win64)">
- <File Id="vboxnetadpsys" Name="VBoxNAdp.sys" LongName="VBoxNetAdp.sys" DiskId="1" Vital="yes" KeyPath="yes"
- Source="$(env.PATH_OUT)\bin\VBoxNetAdp.sys"
- Checksum="yes"/>
- <File Id="vboxnetadpinf" Name="VBoxNAdp.inf" LongName="VBoxNetAdp.inf" DiskId="1" Vital="yes"
- Source="$(env.PATH_OUT)\bin\VBoxNetAdp.inf" />
+ </Directory>
+
+ <Directory Id="dir_NetAdp" Name="netadp">
+ <Component Id="cp_NetAdpDriver" Guid="7adf3e12-af3c-4d36-8bec-36d5064cf84f" Win64="$(var.Property_Win64)">
+ <File Id="file_VBoxNetAdp.sys" Name="VBoxNetAdp.sys" KeyPath="yes"
+ Source="$(env.PATH_OUT)\bin\VBoxNetAdp.sys" Checksum="yes"/>
+ <File Id="file_VBoxNetAdp.inf" Name="VBoxNetAdp.inf"
+ Source="$(env.PATH_OUT)\bin\VBoxNetAdp.inf" />
<?if $(env.VBOX_SIGNING_MODE) != none ?>
- <File Id="vboxnetadpcat" Name="VBoxNAdp.cat" LongName="VBoxNetAdp.cat" DiskId="1" Vital="yes"
- Source="$(env.PATH_OUT)\bin\VBoxNetAdp.cat" />
+ <File Id="file_VBoxNetAdp.cat" Name="VBoxNetAdp.cat"
+ Source="$(env.PATH_OUT)\bin\VBoxNetAdp.cat" />
<?endif ?>
- </Component> <!-- NetAdpDriver -->
- </Directory> <!-- Directory "drivers\network\netadp" -->
- </Directory> <!-- Directory "drivers\network" -->
+ </Component>
+ </Directory>
+ </Directory>
<?endif ?>
</Directory> <!-- Directory "drivers" -->
<!-- National Language Support directory -->
- <Directory Id="nls" Name="nls">
- <Component Id="nls" Guid="D63517D7-1CF3-4D06-B3EE-C561E323069B">
+ <Directory Id="dir_NLS" Name="nls">
+ <Component Id="cp_NLS" Guid="D63517D7-1CF3-4D06-B3EE-C561E323069B" Win64="$(var.Property_Win64)">
<!-- Include the autogenerated NLS file list -->
<?include $(env.PATH_TARGET)\VBoxGuiNLS.wxi ?>
</Component>
@@ -324,18 +328,19 @@
<!-- COM components have a separate entry mainly because of the KeyPath attribute (that hints the
TypeLib element where to take the TLB resource from) may appear only once per Component. -->
- <Component Id="MainCOM" Guid="CD4A3C6C-C2D5-428D-90A1-B6DA3D0777D6" Win64="$(var.Property_Win64)">
+ <Component Id="cp_MainCOM" Guid="CD4A3C6C-C2D5-428D-90A1-B6DA3D0777D6" Win64="$(var.Property_Win64)">
- <File Id="VBoxSVC" Name="VBoxSVC.exe" DiskId="1" Vital="yes"
+ <!-- File ID *must not* be changed because of our typelib template generation file! -->
+ <File Id="VBoxSVC" Name="VBoxSVC.exe"
Source="$(env.PATH_OUT)\bin\VBoxSVC.exe">
</File>
<!-- We set KeyPath on this file to instruct TypeLib to read the TLB resource from it
and create appropriate Interface registry entries. Note that the same TLB is present
in VBoxSVC.exe - it's just a matter of choice which one to use -->
- <File Id="VBoxC" Name="VBoxC.dll" DiskId="1" Vital="yes"
- Source="$(env.PATH_OUT)\bin\VBoxC.dll"
- KeyPath="yes">
+ <!-- File ID *must not* be changed because of our typelib template generation file! -->
+ <File Id="VBoxC" Name="VBoxC.dll"
+ Source="$(env.PATH_OUT)\bin\VBoxC.dll" KeyPath="yes">
</File>
<!-- Include the autogenerated TypeLib block -->
@@ -343,59 +348,63 @@
</Component>
- <Component Id="DesktopShortcut" Guid="668F8A1A-F5CE-48B3-BB1A-3042EE27B279" Win64="$(var.Property_Win64)">
- <Condition>INSTALLDESKTOPSHORTCUT</Condition>
- <CreateFolder/>
- <Shortcut Id="VBoxDesktopShortcut" Directory="DesktopFolder"
- Name="VBox" LongName="$(env.VBOX_PRODUCT)" WorkingDirectory="INSTALLDIR"
- Advertise="no" Target="[#vbox]" />
- </Component>
+ <!--
- <Component Id="QuicklaunchShortcut" Guid="CC19E026-938A-41CB-8E77-3F33296244B6" Win64="$(var.Property_Win64)">
- <Condition>INSTALLQUICKLAUNCHSHORTCUT</Condition>
- <CreateFolder/>
- <Shortcut Id="VBoxQuicklaunchShortcut" Directory="QuicklaunchFolder"
- Name="VBox" LongName="$(env.VBOX_PRODUCT)" WorkingDirectory="INSTALLDIR"
- Advertise="no" Target="[#vbox]" />
- </Component>
+ <Component Id="Cp_StartMenuShortcut" Guid="1C137D24-E599-47BD-98D0-2F62F202A8EA" Win64="$(var.Property_Win64)">
+ <RegistryValue Root="HKCU" Key="$(var.Property_RegKeyInstall)" Type="string"
+ Value="installed" KeyPath="yes" />
+ <Shortcut Id="ShortcutStartMenuVBox" Directory="ProgramMenuDir"
+ Name="VirtualBox" WorkingDirectory="INSTALLDIR" Advertise="no" Target="VirtualBox.exe" />
+ <RemoveFolder Id="ShortcutStartMenuVBoxRemove" On="uninstall" />
+ </Component>-->
+
+ <!---->
<!-- All Binaries, DLLs (except COM) and drivers are in one component because they belong together. Additional
binaries e.g. test tools, utilities etc. should be in another component so they"re clearly separated. -->
- <Component Id="MainBinaries" Guid="5C8FE57A-F744-4DE0-AA3F-A563F486AD98" Win64="$(var.Property_Win64)">
+ <Component Id="cp_MainBinaries" Guid="5C8FE57A-F744-4DE0-AA3F-A563F486AD98" Win64="$(var.Property_Win64)">
+
<!-- Set required environment variables. -->
- <Environment Id="EnvVBoxInstallDir" Action="set" Name="VBOX_INSTALL_PATH"
- System="yes" Part="last" Permanent="no" Value="[INSTALLDIR]" />
+ <Environment Id="env_VBoxInstallDir" Action="set" Name="VBOX_INSTALL_PATH"
+ System="yes" Part="last" Permanent="no" Value="[INSTALLDIR]" />
+
<!-- Register file extensions. Note: Extension Id's *must not* be changed! These specify the actual
file extension to handle. Also, here would be the place to add more fancy DDE stuff later.
Important: The IDs in "IconIndex" *must* be matching "Resources\resource.h". -->
- <ProgId Id="VirtualBox.Shell.vbox" Description="VirtualBox Machine Definition" Icon="[#vboxresdll]" IconIndex="-201">
+ <ProgId Id="progId_VirtualBox.Shell.vbox" Description="VirtualBox Machine Definition" Icon="file_VBoxRes.dll" IconIndex="-201">
<Extension Id="vbox" ContentType="application/x-virtualbox-vbox">
- <Verb Id="open" Sequence="1" Command="Open" Target="[#vbox]" Argument="&quot;%1&quot;" />
+ <Verb Id="open" Command="Open" TargetFile="file_VirtualBox.exe" Argument="&quot;%1&quot;" />
</Extension>
</ProgId>
- <ProgId Id="VirtualBox.Shell.vbox-extpack" Description="VirtualBox Extension Pack" Icon="[#vboxresdll]" IconIndex="-202">
+ <ProgId Id="progId_VirtualBox.Shell.vbox-extpack" Description="VirtualBox Extension Pack" Icon="file_VBoxRes.dll" IconIndex="-202">
<Extension Id="vbox-extpack" ContentType="application/x-virtualbox-vbox-extpack">
- <Verb Id="open" Sequence="1" Command="Open" Target="[#vbox]" Argument="&quot;%1&quot;" />
+ <Verb Id="open" Command="Open" TargetFile="file_VirtualBox.exe" Argument="&quot;%1&quot;" />
</Extension>
</ProgId>
- <ProgId Id="VirtualBox.Shell.ovf" Description="Open Virtualization Format" Icon="[#vboxresdll]" IconIndex="-301">
+ <ProgId Id="progId_VirtualBox.Shell.ovf" Description="Open Virtualization Format" Icon="file_VBoxRes.dll" IconIndex="-301">
<Extension Id="ovf" ContentType="application/x-virtualbox-ovf">
- <Verb Id="open" Sequence="1" Command="Open" Target="[#vbox]" Argument="&quot;%1&quot;" />
+ <Verb Id="open" Command="Open" TargetFile="file_VirtualBox.exe" Argument="&quot;%1&quot;" />
</Extension>
</ProgId>
- <ProgId Id="VirtualBox.Shell.ova" Description="Open Virtualization Format Archive" Icon="[#vboxresdll]" IconIndex="-302">
+ <ProgId Id="progId_VirtualBox.Shell.ova" Description="Open Virtualization Format Archive" Icon="file_VBoxRes.dll" IconIndex="-302">
<Extension Id="ova" ContentType="application/x-virtualbox-ova">
- <Verb Id="open" Sequence="1" Command="Open" Target="[#vbox]" Argument="&quot;%1&quot;" />
+ <Verb Id="open" Command="Open" TargetFile="file_VirtualBox.exe" Argument="&quot;%1&quot;" />
</Extension>
</ProgId>
- <!-- The "Name" attribute must always be present. If the name is longer than 8.3 the additional "LongName"
- attribute can be used. -->
- <File Id="vbox" Name="vbox.exe" LongName="VirtualBox.exe" DiskId="1" Vital="yes"
- Source="$(env.PATH_OUT)\bin\VirtualBox.exe">
- <!-- The target folder for the shortcut in the "Programs" menu is defined below. -->
- <Shortcut Id="startmenuVBox" Directory="ProgramMenuDir" Name="VBox"
- LongName="VirtualBox" WorkingDirectory="INSTALLDIR"/>
- </File>
+ <ProgId Id="progId_VirtualBox.Shell.vdi" Description="Virtual Disk Image" Icon="file_VBoxRes.dll" IconIndex="-303">
+ <Extension Id="vdi" ContentType="application/x-virtualbox-vdi" />
+ </ProgId>
+ <ProgId Id="progId_VirtualBox.Shell.vmdk" Description="Virtual Machine Disk Format" Icon="file_VBoxRes.dll" IconIndex="-304">
+ <Extension Id="vmdk" ContentType="application/x-virtualbox-vmdk" />
+ </ProgId>
+ <ProgId Id="progId_VirtualBox.Shell.vhd" Description="Virtual Hard Disk" Icon="file_VBoxRes.dll" IconIndex="-305">
+ <Extension Id="vhd" ContentType="application/x-virtualbox-vhd" />
+ </ProgId>
+ <ProgId Id="progId_VirtualBox.Shell.hdd" Description="Virtual Hard Disk" Icon="file_VBoxRes.dll" IconIndex="-306">
+ <Extension Id="hdd" ContentType="application/x-virtualbox-hdd" />
+ </ProgId>
+
+ <!-- Files -->
<?if $(env.VBOX_WITH_DOCS_PACKING) = "yes" ?>
<!-- Include all user manual .CHM files (file is generated by makefile). -->
<?include $(env.PATH_TARGET)\Files_Main.wxi ?>
@@ -403,142 +412,145 @@
<!-- Include all license files (file is generated by makefile). -->
<?include $(env.PATH_TARGET)\Files_License.wxi ?>
-<?if $(env.VBOX_WITH_DEBUGGER_GUI) = "yes" ?>
- <File Id="vboxdbgdll" Name="VBoxDbg.dll" DiskId="1" Vital="yes"
- Source="$(env.PATH_OUT)\bin\VBoxDbg.dll" />
-<?endif ?>
-
- <File Id="vboxmanage" Name="VBoxMan.exe" LongName="VBoxManage.exe" DiskId="1" Vital="yes"
+ <!-- Frontends -->
+ <File Id="file_VBoxManage.exe" Name="VBoxManage.exe"
Source="$(env.PATH_OUT)\bin\VBoxManage.exe" />
- <File Id="vboxheadless" Name="VBoxHead.exe" LongName="VBoxHeadless.exe" DiskId="1" Vital="yes"
+ <File Id="file_VBoxHeadless.exe" Name="VBoxHeadless.exe"
Source="$(env.PATH_OUT)\bin\VBoxHeadless.exe">
-
<!-- Create a simple shortcut for VBoxVRDP, which is not present anymore, pointing to VBoxHeadless.exe -->
- <Shortcut Id="ShortcutVBoxVRDP" Directory="INSTALLDIR" Name="VBoxVRDP" Show="normal" WorkingDirectory="INSTALLDIR"/>
-
+ <!-- <Shortcut Id="ShortcutVBoxVRDP" Directory="INSTALLDIR" Name="VBoxVRDP" Show="normal" WorkingDirectory="INSTALLDIR"/> -->
</File>
+ <File Id="file_VBoxBalloonCtrl.exe" Name="VBoxBalloonCtrl.exe"
+ Source="$(env.PATH_OUT)\bin\VBoxBalloonCtrl.exe"/>
- <File Id="vboxnetdhcp" Name="VBoxDHCP.exe" LongName="VBoxNetDHCP.exe" DiskId="1" Vital="yes"
+ <!-- Misc tools -->
+ <File Id="file_VBoxImg.exe" Name="vbox-img.exe"
+ Source="$(env.PATH_OUT)\bin\vbox-img.exe"/>
+ <File Id="file_VBoxNetDHCP.exe" Name="VBoxNetDHCP.exe"
Source="$(env.PATH_OUT)\bin\VBoxNetDHCP.exe"/>
<?if $(env.VBOX_WITH_EXTPACK) = "yes" ?>
- <File Id="vboxepha" Name="VBoxEPHA.exe" LongName="VBoxExtPackHelperApp.exe" DiskId="1" Vital="yes"
+ <File Id="file_VBoxExtPackHelperApp.exe" Name="VBoxExtPackHelperApp.exe"
Source="$(env.PATH_OUT)\bin\VBoxExtPackHelperApp.exe"/>
<?endif ?>
- <File Id="vboxballoonctrl" Name="VBoxBCtl.exe" LongName="VBoxBalloonCtrl.exe" DiskId="1" Vital="yes"
- Source="$(env.PATH_OUT)\bin\VBoxBalloonCtrl.exe"/>
-
<!-- VBox DLL files -->
- <File Id="vboxdddll" Name="VBoxDD.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxDD.dll" Name="VBoxDD.dll"
Source="$(env.PATH_OUT)\bin\VBoxDD.dll" />
- <File Id="vboxdd2dll" Name="VBoxDD2.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxDD2.dll" Name="VBoxDD2.dll"
Source="$(env.PATH_OUT)\bin\VBoxDD2.dll" />
- <File Id="vboxddudll" Name="VBoxDDU.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxDDU.dll" Name="VBoxDDU.dll"
Source="$(env.PATH_OUT)\bin\VBoxDDU.dll" />
- <File Id="vboxrtdll" Name="VBoxRT.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxRT.dll" Name="VBoxRT.dll"
Source="$(env.PATH_OUT)\bin\VBoxRT.dll" />
- <File Id="vboxremdll" Name="VBoxREM.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxREM.dll" Name="VBoxREM.dll"
Source="$(env.PATH_OUT)\bin\VBoxREM.dll" />
<?if $(env.BUILD_TARGET_ARCH) = "amd64" ?>
- <File Id="vboxrem2rel" Name="VBoxREM2.rel" DiskId="1" Vital="yes"
+ <File Id="file_VBoxREM2.rel" Name="VBoxREM2.rel"
Source="$(env.PATH_OUT)\bin\VBoxREM2.rel" />
<?else ?>
- <File Id="vboxrem32dll" Name="VBoxREM3.dll" LongName="VBoxREM32.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxREM32.dll" Name="VBoxREM32.dll"
Source="$(env.PATH_OUT)\bin\VBoxREM32.dll" />
- <File Id="vboxrem64dll" Name="VBoxREM6.dll" LongName="VBoxREM64.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxREM64.dll" Name="VBoxREM64.dll"
Source="$(env.PATH_OUT)\bin\VBoxREM64.dll" />
<?endif ?>
- <File Id="vboxvmmdll" Name="VBoxVMM.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxVMM.dll" Name="VBoxVMM.dll"
Source="$(env.PATH_OUT)\bin\VBoxVMM.dll" />
<?if $(env.VBOX_WITH_VRDP) = "yes" ?>
- <File Id="vboxvrdpdll" Name="VBoxVRDP.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxVRDP.dll" Name="VBoxVRDP.dll"
Source="$(env.PATH_OUT)\bin\VBoxVRDP.dll" />
<?endif ?>
- <File Id="vboxshfolderdll" Name="VBoxSF.dll" LongName="VBoxSharedFolders.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxSharedFolders.dll" Name="VBoxSharedFolders.dll"
Source="$(env.PATH_OUT)\bin\VBoxSharedFolders.dll" />
- <File Id="vboxshclpbrddll" Name="VBoxClip.dll" LongName="VBoxSharedClipboard.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxSharedClipboard.dll" Name="VBoxSharedClipboard.dll"
Source="$(env.PATH_OUT)\bin\VBoxSharedClipboard.dll" />
<?if $(env.VBOX_WITH_GUEST_PROPS) = "yes" ?>
- <File Id="vboxguestpropdll" Name="VBoxProp.dll" LongName="VBoxGuestPropSvc.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxGuestPropSvc.dll" Name="VBoxGuestPropSvc.dll"
Source="$(env.PATH_OUT)\bin\VBoxGuestPropSvc.dll" />
<?endif ?>
<?if $(env.VBOX_WITH_GUEST_CONTROL) = "yes" ?>
- <File Id="vboxguestctrldll" Name="VBoxCtrl.dll" LongName="VBoxGuestControlSvc.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxGuestControlSvc.dll" Name="VBoxGuestControlSvc.dll"
Source="$(env.PATH_OUT)\bin\VBoxGuestControlSvc.dll" />
<?endif ?>
- <File Id="vboxauthdll" Name="VBoxAuth.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxAuth.dll" Name="VBoxAuth.dll"
Source="$(env.PATH_OUT)\bin\VBoxAuth.dll" />
- <File Id="vboxauthsimpledll" Name="VBoxASim.dll" LongName="VBoxAuthSimple.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxAuthSimple.dll" Name="VBoxAuthSimple.dll"
Source="$(env.PATH_OUT)\bin\VBoxAuthSimple.dll" />
<!-- Include resource DLL (icons, ...). -->
- <File Id="vboxresdll" LongName="VBoxRes.dll" Name="VBoxRes.dll" DiskId="$(var.Property_DiskIdCommon)" Vital="yes"
+ <File Id="file_VBoxRes.dll" Name="VBoxRes.dll" DiskId="$(var.Property_DiskIdCommon)"
Source="$(env.PATH_OUT)\bin\VBoxRes.dll" />
- <File Id="vmmgc" Name="VMMGC.gc" DiskId="1" Vital="yes"
+ <File Id="file_VMMGC.gc" Name="VMMGC.gc"
Source="$(env.PATH_OUT)\bin\VMMGC.gc" />
- <File Id="vboxddgc" Name="VBoxDDGC.gc" DiskId="1" Vital="yes"
+ <File Id="file_VBoxDDGC.gc" Name="VBoxDDGC.gc"
Source="$(env.PATH_OUT)\bin\VBoxDDGC.gc" />
- <File Id="vboxdd2gc" Name="VBoxDD2.gc" LongName="VBoxDD2GC.gc" DiskId="1" Vital="yes"
+ <File Id="file_VBoxDD2GC.gc" Name="VBoxDD2GC.gc"
Source="$(env.PATH_OUT)\bin\VBoxDD2GC.gc" />
- <File Id="vmmr0" Name="VMMR0.r0" DiskId="1" Vital="yes"
+ <File Id="file_VMMR0.r0" Name="VMMR0.r0"
Source="$(env.PATH_OUT)\bin\VMMR0.r0" />
- <File Id="vboxddr0" Name="VBoxDDR0.r0" DiskId="1" Vital="yes"
+ <File Id="file_VBoxDDR0.r0" Name="VBoxDDR0.r0"
Source="$(env.PATH_OUT)\bin\VBoxDDR0.r0" />
- <File Id="vboxdd2r0" Name="VBDD2R0.r0" LongName="VBoxDD2R0.r0" DiskId="1" Vital="yes"
+ <File Id="file_VBoxDD2R0.r0" Name="VBoxDD2R0.r0"
Source="$(env.PATH_OUT)\bin\VBoxDD2R0.r0" />
<?if $(env.VBOX_WITH_CROGL) = "yes" ?>
- <File Id="vboxtestogl" Name="VBTstOGL.exe" LongName="VBoxTestOGL.exe" DiskId="1" Vital="yes"
+ <File Id="file_VBoxTestOGL.exe" Name="VBoxTestOGL.exe"
Source="$(env.PATH_OUT)\bin\VBoxTestOGL.exe" />
<?endif ?>
- <!-- Qt stuff -->
- <File Id="qtcore4dll" Name="QtCrVBx4.dll" LongName="QtCoreVBox4.dll" DiskId="1" Vital="yes"
+ <!-- Qt frontend -->
+ <File Id="file_VirtualBox.exe" Name="VirtualBox.exe"
+ Source="$(env.PATH_OUT)\bin\VirtualBox.exe">
+ </File>
+ <File Id="file_QtCoreVBox4.dll" Name="QtCoreVBox4.dll"
Source="$(env.PATH_OUT)\bin\QtCoreVBox4.dll" />
- <File Id="qtgui4dll" Name="QtGuVbx4.dll" LongName="QtGuiVBox4.dll" DiskId="1" Vital="yes"
+ <File Id="file_QtGuiVBox4.dll" Name="QtGuiVBox4.dll"
Source="$(env.PATH_OUT)\bin\QtGuiVBox4.dll" />
- <File Id="qtnetwork4dll" Name="QtNwVBx4.dll" LongName="QtNetworkVBox4.dll" DiskId="1" Vital="yes"
+ <File Id="file_QtNetworkVBox4.dll" Name="QtNetworkVBox4.dll"
Source="$(env.PATH_OUT)\bin\QtNetworkVBox4.dll" />
+<?if $(env.VBOX_WITH_DEBUGGER_GUI) = "yes" ?>
+ <File Id="file_VBoxDbg.dll" Name="VBoxDbg.dll"
+ Source="$(env.PATH_OUT)\bin\VBoxDbg.dll" />
+<?endif ?>
<?if $(env.VBOX_GUI_USE_QGL) = "yes" ?>
- <File Id="qtopengl4dll" Name="QtGlVBx4.dll" LongName="QtOpenGLVBox4.dll" DiskId="1" Vital="yes"
+ <File Id="file_QtOpenGLVBox4.dll" Name="QtOpenGLVBox4.dll"
Source="$(env.PATH_OUT)\bin\QtOpenGLVBox4.dll" />
<?endif?>
<?if $(env.VBOX_USE_VCC80) = "yes" ?>
<!-- MS v8 Runtime DLL files (private assembly) -->
- <File Id="vc80crtmft" Name="VC80CRT.mft" LongName="Microsoft.VC80.CRT.manifest" DiskId="1" Vital="yes"
+ <File Id="file_Microsoft.VC80.CRT.manifest" Name="Microsoft.VC80.CRT.manifest"
Source="$(env.PATH_OUT)\bin\Microsoft.VC80.CRT\Microsoft.VC80.CRT.manifest" />
- <File Id="msvcr80dll" Name="msvcr80.dll" DiskId="1" Vital="yes"
+ <File Id="file_msvcr80.dll" Name="msvcr80.dll"
Source="$(env.PATH_OUT)\bin\Microsoft.VC80.CRT\msvcr80.dll" />
- <File Id="msvcp80dll" Name="msvcp80.dll" DiskId="1" Vital="yes"
+ <File Id="file_msvcp80.dll" Name="msvcp80.dll"
Source="$(env.PATH_OUT)\bin\Microsoft.VC80.CRT\msvcp80.dll" />
<?endif?>
<!-- MS v7 Runtime DLL files -->
<?if $(env.VBOX_USE_VCC80) != "yes" ?>
- <File Id="msvcpdll" Name="msvcp71.dll" DiskId="1" Vital="yes"
+ <File Id="file_msvcp71.dll" Name="msvcp71.dll"
Source="$(env.PATH_OUT)\bin\msvcp71.dll" />
- <File Id="msvcrtdll" Name="msvcrt.dll" DiskId="1" Vital="yes"
+ <File Id="file_msvcrt.dll" Name="msvcrt.dll"
Source="$(env.PATH_OUT)\bin\msvcrt.dll" />
<?endif?>
<?if $(env.BUILD_TARGET_ARCH) != "amd64" ?>
- <File Id="msvcrdll" Name="msvcr71.dll" DiskId="1" Vital="yes"
+ <File Id="msvcrdll" Name="msvcr71.dll"
Source="$(env.PATH_OUT)\bin\msvcr71.dll" />
<?endif?>
<!-- EFI firmware -->
<?if $(env.VBOX_WITH_EFIFW_PACKING) = "yes" ?>
- <File Id="vboxefifd32" LongName="VBoxEFI32.fd" Name="efi32.fd" DiskId="$(var.Property_DiskIdCommon)" Vital="yes"
+ <File Id="file_VBoxEFI32.fd" Name="VBoxEFI32.fd" DiskId="$(var.Property_DiskIdCommon)"
Source="$(env.PATH_OUT)\bin\VBoxEFI32.fd" />
- <File Id="vboxefifd64" LongName="VBoxEFI64.fd" Name="efi64.fd" DiskId="$(var.Property_DiskIdCommon)" Vital="yes"
+ <File Id="file_VBoxEFI64.fd" Name="VBoxEFI64.fd" DiskId="$(var.Property_DiskIdCommon)"
Source="$(env.PATH_OUT)\bin\VBoxEFI64.fd" />
<?endif?>
<!-- VBox guest additions -->
<?if $(env.VBOX_WITH_ADDITIONS_PACKING) = "yes" ?>
<?if $(env.VBOX_WITH_COMBINED_PACKAGE) = "yes" ?>
- <File Id="VBoxGuestAdditions.iso" Name="VBoxAdd.iso" LongName="VBoxGuestAdditions.iso" DiskId="2" Vital="yes"
+ <File Id="file_VBoxGuestAdditions.iso" Name="VBoxGuestAdditions.iso" DiskId="2"
Source="$(env.PATH_MULTIARCH_GUEST_ADDITIONS_ISO)\VBoxGuestAdditions.iso" />
<?else ?>
- <File Id="vboxguest" Name="VBoxAdd.iso" LongName="VBoxGuestAdditionsiso" DiskId="1" Vital="yes"
+ <File Id="file_VBoxGuestAdditions.iso" Name="VBoxGuestAdditions.iso"
Source="$(env.PATH_OUT)\bin\additions\VBoxGuestAdditions.iso" />
<?endif ?>
<?endif ?>
@@ -549,154 +561,180 @@
<?if $(env.VBOX_WITH_QTGUI) = "yes" ?>
<!-- Qt accessible plugins -->
- <Directory Id="accessible" Name="accessbl" LongName="accessible">
- <Component Id="qtaccessible" Guid="12040EF9-D4A8-4FB2-A69C-CA2F5C354A45">
- <File Id="qtaccessibleplugindll" Name="qtacsw4.dll" LongName="qtaccessiblewidgets4.dll" DiskId="1" Vital="yes"
+ <Directory Id="dir_Accessible" Name="accessible">
+ <Component Id="cp_QtAccessible" Guid="12040EF9-D4A8-4FB2-A69C-CA2F5C354A45" Win64="$(var.Property_Win64)">
+ <File Id="file_qtaccessiblewidgets4.dll" Name="qtaccessiblewidgets4.dll"
Source="$(env.PATH_OUT)\bin\accessible\qtaccessiblewidgets4.dll" />
</Component>
- </Directory> <!-- Qt accessible plugins -->
+ </Directory>
<?endif?>
<?if $(env.VBOX_WITH_PYTHON) = "yes" ?>
<!-- Python bindings -->
- <Directory Id="sdk" Name="sdk">
- <Directory Id="installer" Name="install">
- <Component Id="VBoxPyInst" Guid="C9A40306-5102-11DE-A7BA-C3C555D89593">
- <File Id="vboxapisetup" Name="pysetup.py" LongName="vboxapisetup.py" DiskId="$(var.Property_DiskIdCommon)" Vital="yes"
- Source="$(env.PATH_OUT)\bin\sdk\installer\vboxapisetup.py" />
+ <Directory Id="dir_SDK" Name="sdk">
+ <Directory Id="dir_SDKInstall" Name="install">
+ <Component Id="cp_VBoxPyInst" Guid="C9A40306-5102-11DE-A7BA-C3C555D89593" Win64="$(var.Property_Win64)">
+ <File Id="file_vboxapisetup.py" Name="vboxapisetup.py" DiskId="$(var.Property_DiskIdCommon)"
+ Source="$(env.PATH_OUT)\bin\sdk\installer\vboxapisetup.py" />
</Component>
- <Directory Id="vboxapi" Name="vboxapi">
- <Component Id="VBoxPyMod" Guid="DF19CB76-5102-11DE-943B-13C755D89593">
- <File Id="__init__.py" Name="__init__.py" DiskId="$(var.Property_DiskIdCommon)" Vital="yes"
- Source="$(env.PATH_OUT)\bin\sdk\installer\vboxapi\__init__.py" />
- <File Id="VirtualBox_constants.py" Name="vbconst.py" LongName="VirtualBox_constants.py" DiskId="$(var.Property_DiskIdCommon)" Vital="yes"
- Source="$(env.PATH_OUT)\bin\sdk\installer\vboxapi\VirtualBox_constants.py" />
+ <Directory Id="dir_SDKVBoxAPI" Name="vboxapi">
+ <Component Id="cp_VBoxPyMod" Guid="DF19CB76-5102-11DE-943B-13C755D89593" Win64="$(var.Property_Win64)">
+ <File Id="file___init__.py" Name="__init__.py" DiskId="$(var.Property_DiskIdCommon)"
+ Source="$(env.PATH_OUT)\bin\sdk\installer\vboxapi\__init__.py" />
+ <File Id="file_VirtualBox_constants.py" Name="VirtualBox_constants.py" DiskId="$(var.Property_DiskIdCommon)"
+ Source="$(env.PATH_OUT)\bin\sdk\installer\vboxapi\VirtualBox_constants.py" />
</Component>
</Directory>
</Directory>
</Directory>
- <!-- Python bindings -->
<?endif?>
<?if $(env.VBOX_WITH_CROGL) = "yes" ?>
- <Component Id="VBoxCROpenGL" Guid="874A1297-835A-491D-8A9D-7E723BC29EE7" Win64="$(var.Property_Win64)">
- <File Id="vboxoglhostcrutil" Name="VbGlHCRU.dll" LongName="VBoxOGLhostcrutil.dll" DiskId="1" Vital="yes"
+ <Component Id="cp_VBoxCROpenGL" Guid="874A1297-835A-491D-8A9D-7E723BC29EE7" Win64="$(var.Property_Win64)">
+ <File Id="file_VBoxOGLhostcrutil.dll" Name="VBoxOGLhostcrutil.dll"
Source="$(env.PATH_OUT)\bin\VBoxOGLhostcrutil.dll" />
- <File Id="vboxoglhosterrorspu" Name="VbGlHers.dll" LongName="VBoxOGLhosterrorspu.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxOGLhosterrorspu.dll" Name="VBoxOGLhosterrorspu.dll"
Source="$(env.PATH_OUT)\bin\VBoxOGLhosterrorspu.dll" />
- <File Id="vboxoglrenderspu" Name="VbGlRndr.dll" LongName="VBoxOGLrenderspu.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxOGLrenderspu.dll" Name="VBoxOGLrenderspu.dll"
Source="$(env.PATH_OUT)\bin\VBoxOGLrenderspu.dll" />
- <File Id="vboxsharedcropengl" Name="VbShCRGL.dll" LongName="VBoxSharedCrOpenGL.dll" DiskId="1" Vital="yes"
+ <File Id="file_VBoxSharedCrOpenGL.dll" Name="VBoxSharedCrOpenGL.dll"
Source="$(env.PATH_OUT)\bin\VBoxSharedCrOpenGL.dll" />
</Component>
<?endif?>
<!-- SDL plugins -->
- <Component Id="VBoxSDLBinaries" Guid="F09D5FD9-E176-42B0-90A9-481BB18B0CB4" Win64="$(var.Property_Win64)">
- <File Id="vboxsdl" Name="VBoxSDL.exe" DiskId="1" Vital="yes"
+ <Component Id="cp_VBoxSDLBinaries" Guid="F09D5FD9-E176-42B0-90A9-481BB18B0CB4" Win64="$(var.Property_Win64)">
+ <File Id="file_VBoxSDL.exe" Name="VBoxSDL.exe"
Source="$(env.PATH_OUT)\bin\VBoxSDL.exe" />
- <File Id="sdldll" Name="SDL.dll" DiskId="1" Vital="yes"
+ <File Id="file_SDL.dll" Name="SDL.dll"
Source="$(env.PATH_OUT)\bin\SDL.dll" />
<?if $(env.VBOX_WITH_SECURELABEL) = "yes" ?>
- <File Id="sdlttfdll" Name="SDL_ttf.dll" DiskId="1" Vital="yes"
+ <File Id="file_SDL_ttf.dll" Name="SDL_ttf.dll"
Source="$(env.PATH_OUT)\bin\SDL_ttf.dll" />
<?endif?>
</Component> <!-- SDL plugins -->
<?if $(env.VBOX_WITH_WEBSERVICES) = "yes" ?>
<!-- Webservice -->
- <Component Id="VBoxWebService" Guid="DD404F04-9874-43E9-AEE2-7762924D922E">
- <File Id="vboxweb" Name="vboxwebs.exe" LongName="vboxwebsrv.exe" DiskId="1" Vital="yes"
+ <Component Id="cp_VBoxWebService" Guid="DD404F04-9874-43E9-AEE2-7762924D922E">
+ <File Id="file_VBoxWebSrv.exe" Name="VBoxWebSrv.exe"
Source="$(env.PATH_OUT)\bin\vboxwebsrv.exe" />
- </Component> <!-- Webservice -->
+ </Component>
<?endif?>
<?if $(env.VBOX_WITH_PYTHON) = "yes" ?>
- <!--Python -->
- <Component Id="VBoxPythonBinding" Guid="293D7E11-78DA-4C31-AEED-AE2FE42F6881">
- <Condition>PYTHONINSTALLED</Condition>
- <!-- Nothing in here yet. -->
+ <Component Id="cp_VBoxPythonBinding" Guid="293D7E11-78DA-4C31-AEED-AE2FE42F6881">
+ <Condition>PYTHON_INSTALLED</Condition>
</Component>
<?endif?>
</Directory> <!-- Installation directory -->
</Directory> <!-- Windows program files directory -->
- <!-- Create a subdirectory in the "Programs" start menu -->
- <Directory Id="ProgramMenuFolder" Name="PMenu" LongName="Programs">
- <Directory Id="ProgramMenuDir" Name="vbox" LongName="$(env.VBOX_PRODUCT)" />
+ <!-- Set up special directory IDs for referencing to the start menu
+ or the Quick Launch bar.
+ See: http://msdn.microsoft.com/en-us/library/aa368276.aspx
+ http://wix.mindcapers.com/wiki/Shortcuts_in_WiX -->
+ <Directory Id="ProgramMenuFolder">
+ <Directory Id="dir_StartMenuVBox" Name="$(env.VBOX_PRODUCT)"/>
</Directory>
- <Directory Id="DesktopFolder" Name="Desktop" />
+ <Directory Id="DesktopFolder" Name="Desktop"/>
<Directory Id="AppDataFolder" Name="AppData">
- <Directory Id="AppDataMicrosoft" Name="MS" LongName="Microsoft">
- <Directory Id="AppDataMSIE" Name="IE" LongName="Internet Explorer">
- <Directory Id="QuicklaunchFolder" Name="QL" LongName="Quick Launch"/>
+ <Directory Id="dir_AppDataMicrosoft" Name="Microsoft">
+ <Directory Id="dir_AppDataMSIE" Name="Internet Explorer">
+ <Directory Id="dir_QuicklaunchFolder" Name="Quick Launch"/>
</Directory>
</Directory>
</Directory>
- </Directory>
+
+ <!-- Shortcut(s) in start menu -->
+ <Component Id="cp_StartMenuVBox" Guid="C2DC321A-CE63-40EE-8A98-724DF8BD12FB" Win64="$(var.Property_Win64)">
+ <Shortcut Id="sc_StartMenuVBox" Directory="dir_StartMenuVBox" Name="$(env.VBOX_PRODUCT)" Description="$(env.VBOX_PRODUCT)"
+ Target="[INSTALLDIR]VirtualBox.exe" WorkingDirectory="INSTALLDIR"/>
+ <RegistryValue Root="HKCU" Key="$(var.Property_RegKeyInstall)"
+ Type="string" Value="installed" KeyPath="yes" />
+ <?include $(env.PATH_TARGET)\Shortcuts_StartMenu.wxi ?>
+ </Component>
+
+ <Component Id="cp_DesktopShortcut" Guid="668F8A1A-F5CE-48B3-BB1A-3042EE27B279" Win64="$(var.Property_Win64)">
+ <Condition>INSTALLDESKTOPSHORTCUT</Condition>
+ <Shortcut Id="sc_DesktopVBox" Directory="DesktopFolder" Name="$(env.VBOX_PRODUCT)" Description="$(env.VBOX_PRODUCT)"
+ Target="[INSTALLDIR]VirtualBox.exe" WorkingDirectory="INSTALLDIR"/>
+ <RegistryValue Root="HKCU" Key="$(var.Property_RegKeyInstall)" Type="string"
+ Value="installed" KeyPath="yes" />
+ </Component>
+
+ <Component Id="cp_QuickLaunchVBox" Guid="CC19E026-938A-41CB-8E77-3F33296244B6" Win64="$(var.Property_Win64)">
+ <CreateFolder/>
+ <Condition>INSTALLQUICKLAUNCHSHORTCUT</Condition>
+ <Shortcut Id="sc_QuickLaunchVBox" Directory="dir_QuicklaunchFolder" Name="$(env.VBOX_PRODUCT)" Description="$(env.VBOX_PRODUCT)"
+ Target="[INSTALLDIR]VirtualBox.exe" WorkingDirectory="INSTALLDIR"/>
+ <RegistryValue Root="HKCU" Key="$(var.Property_RegKeyInstall)"
+ Type="string" Value="installed" KeyPath="yes" />
+ </Component>
+ </Directory> <!-- TARGETDIR -->
<Feature Id="VBoxApplication" Title="VirtualBox Application" Level="1"
- Description="$(loc.VB_App)"
+ Description="!(loc.VB_App)"
ConfigurableDirectory="INSTALLDIR" TypicalDefault="install" Display="expand"
Absent="disallow">
- <ComponentRef Id="DesktopShortcut" />
- <ComponentRef Id="QuicklaunchShortcut" />
+ <ComponentRef Id="cp_StartMenuVBox" />
+ <ComponentRef Id="cp_DesktopShortcut" />
+ <ComponentRef Id="cp_QuickLaunchVBox" />
<?if $(env.VBOX_WITH_DOCS_PACKING) = "yes" ?>
- <ComponentRef Id="docs" />
+ <ComponentRef Id="cp_Docs" />
<?endif?>
- <ComponentRef Id="nls" />
- <ComponentRef Id="MainCOM" />
- <ComponentRef Id="MainBinaries" />
+ <ComponentRef Id="cp_NLS" />
+ <ComponentRef Id="cp_MainCOM" />
+ <ComponentRef Id="cp_MainBinaries" />
<?if $(env.VBOX_WITH_QTGUI) = "yes" ?>
- <ComponentRef Id="qtaccessible" />
+ <ComponentRef Id="cp_QtAccessible" />
<?endif?>
<?if $(env.VBOX_WITH_PYTHON) = "yes" ?>
- <ComponentRef Id="VBoxPyInst" />
- <ComponentRef Id="VBoxPyMod" />
+ <ComponentRef Id="cp_VBoxPyInst" />
+ <ComponentRef Id="cp_VBoxPyMod" />
<?endif?>
<?if $(env.VBOX_WITH_CROGL) = "yes" ?>
- <ComponentRef Id="VBoxCROpenGL" />
+ <ComponentRef Id="cp_VBoxCROpenGL" />
<?endif?>
- <ComponentRef Id="VBoxSDLBinaries" />
+ <ComponentRef Id="cp_VBoxSDLBinaries" />
<?if $(env.VBOX_WITH_WEBSERVICES) = "yes" ?>
- <ComponentRef Id="VBoxWebService" />
+ <ComponentRef Id="cp_VBoxWebService" />
<?endif?>
- <ComponentRef Id="VBoxDrv" />
+ <ComponentRef Id="cp_VBoxDrv" />
- <Feature Id="VBoxUSB" Title="VirtualBox USB Support" Level="1"
- Description="$(loc.VB_USBDriver)"
+ <Feature Id="ft_VBoxUSB" Title="VirtualBox USB Support" Level="1"
+ Description="!(loc.VB_USBDriver)"
ConfigurableDirectory="INSTALLDIR" TypicalDefault="install" Display="expand" >
- <ComponentRef Id="USBFilterDriver" />
- <ComponentRef Id="USBDeviceDriver" />
+ <ComponentRef Id="cp_USBFilterDriver" />
+ <ComponentRef Id="cp_USBDeviceDriver" />
</Feature>
<?if $(env.VBOX_WITH_NETFLT) = "yes" ?>
- <Feature Id="VBoxNetwork" Title="VirtualBox Networking" Level="1"
- Description="$(loc.VB_Network)"
+ <Feature Id="ft_VBoxNetwork" Title="VirtualBox Networking" Level="1"
+ Description="!(loc.VB_Network)"
ConfigurableDirectory="INSTALLDIR" TypicalDefault="install" Display="expand" >
- <Feature Id="VBoxNetworkFlt" Title="VirtualBox Bridged Networking" Level="1"
- Description="$(loc.VB_NetFltDriver)"
- ConfigurableDirectory="INSTALLDIR" TypicalDefault="install" Display="expand" >
- <ComponentRef Id="NetFltDriver" />
+ <Feature Id="ft_VBoxNetworkFlt" Title="VirtualBox Bridged Networking" Level="1"
+ Description="!(loc.VB_NetFltDriver)"
+ ConfigurableDirectory="INSTALLDIR" TypicalDefault="install" Display="expand" >
+ <ComponentRef Id="cp_NetFltDriver" />
</Feature>
- <Feature Id="VBoxNetworkAdp" Title="VirtualBox Host-Only Networking" Level="1"
- Description="$(loc.VB_NetAdpDriver)"
- ConfigurableDirectory="INSTALLDIR" TypicalDefault="install" Display="expand" >
- <ComponentRef Id="NetAdpDriver" />
+ <Feature Id="ft_VBoxNetworkAdp" Title="VirtualBox Host-Only Networking" Level="1"
+ Description="!(loc.VB_NetAdpDriver)"
+ ConfigurableDirectory="INSTALLDIR" TypicalDefault="install" Display="expand" >
+ <ComponentRef Id="cp_NetAdpDriver" />
</Feature>
</Feature>
<?endif?>
<?if $(env.VBOX_WITH_PYTHON) = "yes" ?>
-
- <Feature Id="VBoxPython" Title="VirtualBox Python Support" Level="1"
- Description="$(loc.VB_Python)"
+ <Feature Id="ft_VBoxPython" Title="VirtualBox Python 2.x Support" Level="1"
+ Description="!(loc.VB_Python)"
ConfigurableDirectory="INSTALLDIR" TypicalDefault="install" Display="expand" >
- <ComponentRef Id="VBoxPythonBinding" />
+ <ComponentRef Id="cp_VBoxPythonBinding" />
</Feature>
<?endif?>
@@ -712,30 +750,36 @@
<LaunchConditions After="AppSearch" />
<RemoveExistingProducts After="InstallValidate"><![CDATA[NEWERVERSIONDETECTED OR PREVIOUSVERSIONSINSTALLED]]></RemoveExistingProducts>
- <Custom Action="OriginalTargetDir" After="FileCost"><![CDATA[(NOT INSTALLDIR) AND (NOT EXISTINGINSTALLDIR)]]></Custom>
- <Custom Action="DefaultTargetDir" Before="FileCost" ><![CDATA[NOT Installed AND (NOT INSTALLDIR) AND EXISTINGINSTALLDIR]]></Custom>
+ <Custom Action="ca_OriginalTargetDir" After="FileCost"><![CDATA[(NOT INSTALLDIR) AND (NOT EXISTINGINSTALLDIR)]]></Custom>
+ <Custom Action="ca_DefaultTargetDir" Before="FileCost" ><![CDATA[NOT Installed AND (NOT INSTALLDIR) AND EXISTINGINSTALLDIR]]></Custom>
- <Custom Action="UninstallTAPInstances" Before="InstallFiles" >1</Custom>
+ <Custom Action="ca_UninstallTAPInstances" Before="InstallFiles" >1</Custom>
<?if $(env.VBOX_WITH_NETFLT) = "yes" ?>
- <Custom Action="CreateHostOnlyInterfaceArgs" Before="CreateHostOnlyInterface" ><![CDATA[&VBoxNetworkAdp=3]]></Custom>
- <Custom Action="CreateHostOnlyInterface" Before="InstallFinalize" ><![CDATA[&VBoxNetworkAdp=3]]></Custom>
- <Custom Action="RemoveHostOnlyInterfaces" After="UninstallNetFlt" ></Custom>
-
- <Custom Action="RollbackInstallNetFltArgs" Before="RollbackInstallNetFlt" ><![CDATA[&VBoxNetworkFlt=3]]></Custom>
- <Custom Action="RollbackInstallNetFlt" Before="InstallNetFlt" ><![CDATA[&VBoxNetworkFlt=3]]></Custom>
- <Custom Action="InstallNetFltArgs" Before="InstallNetFlt" ><![CDATA[&VBoxNetworkFlt=3]]></Custom>
- <Custom Action="InstallNetFlt" Before="CreateHostOnlyInterface" ><![CDATA[&VBoxNetworkFlt=3]]></Custom>
-
- <Custom Action="RollbackUninstallNetFltArgs" Before="RollbackUninstallNetFlt" ><![CDATA[&VBoxNetworkFlt=2]]></Custom>
- <Custom Action="RollbackUninstallNetFlt" Before="UninstallNetFlt" ><![CDATA[&VBoxNetworkFlt=2]]></Custom>
- <Custom Action="UninstallNetFltArgs" Before="UninstallNetFlt" ><![CDATA[&VBoxNetworkFlt=2]]></Custom>
- <Custom Action="UninstallNetFlt" After="InstallInitialize" ><![CDATA[&VBoxNetworkFlt=2]]></Custom>
+ <Custom Action="ca_CreateHostOnlyInterfaceArgs" Before="ca_CreateHostOnlyInterface" ><![CDATA[&ft_VBoxNetworkAdp=3]]></Custom>
+ <Custom Action="ca_CreateHostOnlyInterface" Before="InstallFinalize" ><![CDATA[&ft_VBoxNetworkAdp=3]]></Custom>
+ <Custom Action="ca_RemoveHostOnlyInterfaces" After="ca_UninstallNetFlt" ></Custom>
+
+ <Custom Action="ca_RollbackInstallNetFltArgs" Before="ca_RollbackInstallNetFlt" ><![CDATA[&ft_VBoxNetworkFlt=3]]></Custom>
+ <Custom Action="ca_RollbackInstallNetFlt" Before="ca_InstallNetFlt" ><![CDATA[&ft_VBoxNetworkFlt=3]]></Custom>
+ <Custom Action="ca_InstallNetFltArgs" Before="ca_InstallNetFlt" ><![CDATA[&ft_VBoxNetworkFlt=3]]></Custom>
+ <Custom Action="ca_InstallNetFlt" Before="ca_CreateHostOnlyInterface" ><![CDATA[&ft_VBoxNetworkFlt=3]]></Custom>
+
+ <Custom Action="ca_RollbackUninstallNetFltArgs" Before="ca_RollbackUninstallNetFlt" ><![CDATA[&ft_VBoxNetworkFlt=2]]></Custom>
+ <Custom Action="ca_RollbackUninstallNetFlt" Before="ca_UninstallNetFlt" ><![CDATA[&ft_VBoxNetworkFlt=2]]></Custom>
+ <Custom Action="ca_UninstallNetFltArgs" Before="ca_UninstallNetFlt" ><![CDATA[&ft_VBoxNetworkFlt=2]]></Custom>
+ <Custom Action="ca_UninstallNetFlt" After="InstallInitialize" ><![CDATA[&ft_VBoxNetworkFlt=2]]></Custom>
<?endif?>
- <Custom Action="InstallPythonAPI" After="InstallFinalize" ><![CDATA[&VBoxPython=3]]></Custom>
- <Custom Action="InstallBranding" After="InstallFinalize" ><![CDATA[NOT REMOVE]]></Custom>
- <Custom Action="UninstallBranding" After="InstallFinalize" ><![CDATA[REMOVE]]></Custom>
+ <Custom Action="ca_InstallPythonAPIArgs" Before="ca_InstallPythonAPI" ><![CDATA[&ft_VBoxPython=3]]></Custom>
+ <Custom Action="ca_InstallPythonAPI" Before="InstallFinalize" ><![CDATA[&ft_VBoxPython=3]]></Custom>
+
+ <Custom Action="ca_InstallBrandingArgs" Before="ca_InstallBranding" ><![CDATA[NOT REMOVE]]></Custom>
+ <Custom Action="ca_InstallBranding" Before="InstallFinalize" ><![CDATA[NOT REMOVE]]></Custom>
+
+ <Custom Action="ca_UninstallBrandingArgs" Before="ca_UninstallBranding" ><![CDATA[REMOVE]]></Custom>
+ <Custom Action="ca_UninstallBranding" Before="InstallFinalize" ><![CDATA[REMOVE]]></Custom>
</InstallExecuteSequence>
</Product>
</Wix>
+
diff --git a/src/VBox/Installer/win/VirtualBox_TypeLib.xsl b/src/VBox/Installer/win/VirtualBox_TypeLib.xsl
index 30608baa1..86a11adde 100644
--- a/src/VBox/Installer/win/VirtualBox_TypeLib.xsl
+++ b/src/VBox/Installer/win/VirtualBox_TypeLib.xsl
@@ -58,6 +58,9 @@
<Include>
<TypeLib>
<xsl:attribute name="Id"><xsl:value-of select="@uuid"/></xsl:attribute>
+ <xsl:attribute name="Advertise">yes</xsl:attribute>
+ <xsl:attribute name="MajorVersion">1</xsl:attribute>
+ <xsl:attribute name="MinorVersion">0</xsl:attribute>
<xsl:attribute name="Language">0</xsl:attribute>
<xsl:attribute name="Description"><xsl:value-of select="@desc"/></xsl:attribute>
<AppId>
diff --git a/src/VBox/Installer/win/dep.sed b/src/VBox/Installer/win/dep.sed
index d312386ac..0e349152c 100644
--- a/src/VBox/Installer/win/dep.sed
+++ b/src/VBox/Installer/win/dep.sed
@@ -1,10 +1,10 @@
-# $Id: dep.sed $
+# $Id: dep.sed 37289 2011-06-01 11:59:23Z vboxsync $
## @file
# Generate dependencies from .wxs and .wxi sources.
#
#
-# 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;
@@ -16,9 +16,9 @@
#
# drop all lines not including a src property.
-/src=\"/!d
+/Source=\"/!d
# extract the file spec
-s/^.*src="\([^"]*\).*$/\1 /
+s/^.*Source="\([^"]*\).*$/\1 /
# convert to unix slashes
s/\\/\//g
# $(env.PATH_OUT stuff.
diff --git a/src/VBox/Main/Makefile.kmk b/src/VBox/Main/Makefile.kmk
index 6a21eccc4..ce2b225da 100644
--- a/src/VBox/Main/Makefile.kmk
+++ b/src/VBox/Main/Makefile.kmk
@@ -1,10 +1,10 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 38037 2011-07-18 17:31:38Z vboxsync $
## @file
# Makefile for the VBox Main module.
#
#
-# 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;
@@ -61,8 +61,8 @@ VBOX_MAIN_DEFS += \
$(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS,) \
$(if $(VBOX_WITH_GUEST_PROPS_RDONLY_GUEST),VBOX_WITH_GUEST_PROPS_RDONLY_GUEST,) \
$(if $(VBOX_WITH_GUEST_CONTROL),VBOX_WITH_GUEST_CONTROL,) \
- $(if $(VBOX_WITH_HOSTNETIF_API),VBOX_WITH_HOSTNETIF_API,) \
- $(if $(VBOX_WITH_VDE),VBOX_WITH_VDE,)
+ $(if $(VBOX_WITH_USB_VIDEO),VBOX_WITH_USB_VIDEO,) \
+ $(if $(VBOX_WITH_HOSTNETIF_API),VBOX_WITH_HOSTNETIF_API,)
# Unconditionally enable the new semaphore key generation code
VBOX_MAIN_DEFS += VBOX_WITH_NEW_SYS_V_KEYGEN
@@ -168,7 +168,7 @@ ifdef VBOX_WITH_PYTHON
VBOX_PYTHON_CONSTANTS = $(PATH_TARGET)/VirtualBox_constants.py
INSTALLS += VBox-python-glue
-VBox-python-glue_INST = $(INST_SDK)installer
+VBox-python-glue_INST = $(INST_SDK)installer/
VBox-python-glue_SOURCES = glue/vboxapi.py=>vboxapi/__init__.py \
$(VBOX_PYTHON_CONSTANTS)=>vboxapi/VirtualBox_constants.py
@@ -209,7 +209,6 @@ VBoxSVC_DEFS = \
$(if $(VBOX_WITH_QTGUI),VBOX_WITH_QTGUI,) \
$(if $(VBOX_WITH_COCOA_QT),VBOX_WITH_COCOA_QT,) \
$(if $(VBOX_WITH_HGCM),VBOX_WITH_HGCM,) \
- $(if $(VBOX_MAIN_RELEASE_LOG),VBOX_MAIN_RELEASE_LOG LOG_ENABLED,) \
$(if $(VBOX_WITH_ALSA),VBOX_WITH_ALSA,) \
$(if $(VBOX_WITH_PULSE),VBOX_WITH_PULSE,) \
$(if $(VBOX_WITH_WINMM),VBOX_WITH_WINMM,) \
@@ -227,7 +226,8 @@ VBoxSVC_DEFS = \
$(if $(VBOX_WITH_LIVE_MIGRATION),VBOX_WITH_LIVE_MIGRATION,) \
$(if $(VBOX_WITH_EXTPACK),VBOX_WITH_EXTPACK,) \
$(if $(VBOX_WITH_VUSB),VBOX_WITH_VUSB,) \
- $(if $(VBOX_WITH_S3),VBOX_WITH_S3,)
+ $(if $(VBOX_WITH_S3),VBOX_WITH_S3,) \
+ $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,)
ifdef VBOX_WITH_USB
VBoxSVC_DEFS += \
VBOX_WITH_USB \
@@ -299,7 +299,9 @@ VBoxSVC_SOURCES = \
src-server/HostImpl.cpp \
src-server/HostNetworkInterfaceImpl.cpp \
src-server/HostPower.cpp \
+ src-server/Logging.cpp \
src-server/MachineImpl.cpp \
+ src-server/MachineImplCloneVM.cpp \
src-server/Matching.cpp \
src-server/MediumAttachmentImpl.cpp \
src-server/MediumFormatImpl.cpp \
@@ -351,6 +353,11 @@ VBoxSVC_SOURCES.solaris = \
VBoxSVC_SOURCES.freebsd = \
src-server/freebsd/HostHardwareFreeBSD.cpp
+src-server/Logging.cpp_DEFS = \
+ VBOX_BUILD_TARGET=\"$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)\" \
+ $(if $(VBOX_BLEEDING_EDGE),VBOX_BLEEDING_EDGE=\"$(VBOX_BLEEDING_EDGE)\",)
+
+
ifdef VBOX_WITH_USB
ifdef VBOX_WITH_SYSFS_BY_DEFAULT
src-server/linux/USBProxyServiceLinux.cpp_DEFS += VBOX_WITH_SYSFS_BY_DEFAULT
@@ -376,12 +383,10 @@ ifdef VBOX_WITH_NETFLT
# needing it.
src-server/win/NetIf-win.cpp_INCS.win += $(PATH_TOOL_$(VBOX_VCC_TOOL)_INC)
VBoxSVC_LIBS.win += \
- $(PATH_LIB)/WinNetConfig.lib \
+ $(WinNetConfig_1_TARGET) \
+ $(VBoxDrvCfg_1_TARGET) \
$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/comsupp.lib \
$(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib
- ifdef VBOX_NETFLT_ONDEMAND_BIND
- VBoxSVC_DEFS.win += VBOX_NETFLT_ONDEMAND_BIND
- endif
endif
VBoxSVC_LDFLAGS.darwin = -framework IOKit -framework SystemConfiguration
@@ -564,7 +569,6 @@ VBoxC_DEFS = \
VBOX_COM_INPROC \
$(if $(VBOX_WITH_VRDP_VIDEO_CHANNEL),VBOX_WITH_VRDP_VIDEO_CHANNEL,) \
$(if $(VBOX_WITH_HGCM),VBOX_WITH_HGCM,) \
- $(if $(VBOX_MAIN_RELEASE_LOG),VBOX_MAIN_RELEASE_LOG LOG_ENABLED,) \
$(if $(VBOX_WITH_ALSA),VBOX_WITH_ALSA,) \
$(if $(VBOX_WITH_PULSE),VBOX_WITH_PULSE,) \
$(if $(VBOX_WITH_WINMM),VBOX_WITH_WINMM,) \
@@ -580,7 +584,8 @@ VBoxC_DEFS = \
$(if $(VBOX_WITH_VIDEOHWACCEL),VBOX_WITH_VIDEOHWACCEL,) \
$(if $(VBOX_WITH_USB),VBOX_WITH_USB,) \
$(if-expr defined(VBOX_WITH_EHCI) && defined(VBOX_WITH_USB),VBOX_WITH_EHCI,) \
- $(if $(VBOX_WITH_EXTPACK),VBOX_WITH_EXTPACK,)
+ $(if $(VBOX_WITH_EXTPACK),VBOX_WITH_EXTPACK,) \
+ $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,)
VBoxC_DEFS.darwin.x86 = VBOX_WITH_2X_4GB_ADDR_SPACE
VBoxC_DEFS.win.x86 += _WIN32_WINNT=0x0500
@@ -607,9 +612,11 @@ VBoxC_LIBS += \
$(LIB_REM)
ifdef VBOX_WITH_NETFLT
- VBoxC_LIBS.win += $(PATH_LIB)/WinNetConfig.lib \
- $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/comsupp.lib \
- $(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib
+ VBoxC_LIBS.win += \
+ $(VBoxDrvCfg_1_TARGET) \
+ $(WinNetConfig_1_TARGET) \
+ $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/comsupp.lib \
+ $(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib
endif
VBoxC_INTERMEDIATES = \
@@ -630,8 +637,11 @@ VBoxC_SOURCES = \
src-all/VirtualBoxBase.cpp \
src-all/VirtualBoxErrorInfoImpl.cpp \
$(if $(VBOX_WITH_EXTPACK),src-all/ExtPackManagerImpl.cpp src-all/ExtPackUtil.cpp,) \
+ $(if $(VBOX_WITH_USB_VIDEO),src-client/UsbWebcamInterface.cpp,) \
+ src-client/AdditionsFacilityImpl.cpp \
src-client/AudioSnifferInterface.cpp \
src-client/BusAssignmentManager.cpp \
+ $(if $(VBOX_WITH_PCI_PASSTHROUGH),src-client/PciRawDevImpl.cpp,) \
src-client/ConsoleImpl.cpp \
src-client/ConsoleImpl2.cpp \
src-client/ConsoleImplTeleporter.cpp \
@@ -911,7 +921,7 @@ endif # VBOX_WITH_JMSCOM
# Install Java glue sample code.
#
INSTALLS += javagluesample
-javagluesample_INST = $(INST_SDK)bindings/glue/java
+javagluesample_INST = $(INST_SDK)bindings/glue/java/
javagluesample_MODE = a+rx,u+w
javagluesample_SOURCES = \
$(VBOX_PATH_MAIN_SRC)/glue/tests/TestVBox.java=>TestVBox.java \
diff --git a/src/VBox/Main/cbinding/Makefile.kmk b/src/VBox/Main/cbinding/Makefile.kmk
index 03af2602a..d221e4d61 100644
--- a/src/VBox/Main/cbinding/Makefile.kmk
+++ b/src/VBox/Main/cbinding/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 29167 2010-05-06 15:58:14Z vboxsync $
## @file
# Sub-Makefile for the VBox C Binding.
#
diff --git a/src/VBox/Main/cbinding/VBoxXPCOMC.cpp b/src/VBox/Main/cbinding/VBoxXPCOMC.cpp
index 505ee7202..dd236f911 100644
--- a/src/VBox/Main/cbinding/VBoxXPCOMC.cpp
+++ b/src/VBox/Main/cbinding/VBoxXPCOMC.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxXPCOMC.cpp $ */
+/* $Id: VBoxXPCOMC.cpp 29167 2010-05-06 15:58:14Z vboxsync $ */
/** @file VBoxXPCOMC.cpp
* Utility functions to use with the C binding for XPCOM.
*/
diff --git a/src/VBox/Main/cbinding/VBoxXPCOMCGlue.c b/src/VBox/Main/cbinding/VBoxXPCOMCGlue.c
index 3484ad65e..69ad2d36d 100644
--- a/src/VBox/Main/cbinding/VBoxXPCOMCGlue.c
+++ b/src/VBox/Main/cbinding/VBoxXPCOMCGlue.c
@@ -1,4 +1,4 @@
-/* $Revision: 66985 $ */
+/* $Revision: 33396 $ */
/** @file
* Glue code for dynamically linking to VBoxXPCOMC.
*/
diff --git a/src/VBox/Main/cbinding/VBoxXPCOMCGlue.h b/src/VBox/Main/cbinding/VBoxXPCOMCGlue.h
index 3edd49a79..61ab816fb 100644
--- a/src/VBox/Main/cbinding/VBoxXPCOMCGlue.h
+++ b/src/VBox/Main/cbinding/VBoxXPCOMCGlue.h
@@ -1,4 +1,4 @@
-/* $Revision: 61277 $ */
+/* $Revision: 29200 $ */
/** @file VBoxXPCOMCGlue.h
* Glue for dynamically linking with VBoxXPCOMC.
*/
diff --git a/src/VBox/Main/cbinding/makefile.tstXPCOMCGlue b/src/VBox/Main/cbinding/makefile.tstXPCOMCGlue
index 07838aba6..11769019e 100644
--- a/src/VBox/Main/cbinding/makefile.tstXPCOMCGlue
+++ b/src/VBox/Main/cbinding/makefile.tstXPCOMCGlue
@@ -1,4 +1,4 @@
-# $Revision: 60692 $
+# $Revision: 28800 $
## @file makefile.tstLinuxC
# Makefile for sample program illustrating use of C binding for XPCOM.
#
diff --git a/src/VBox/Main/cbinding/tstXPCOMCCall.c b/src/VBox/Main/cbinding/tstXPCOMCCall.c
index a2311829f..e65e144c2 100644
--- a/src/VBox/Main/cbinding/tstXPCOMCCall.c
+++ b/src/VBox/Main/cbinding/tstXPCOMCCall.c
@@ -1,4 +1,4 @@
-/* $Revision: 60692 $ */
+/* $Revision: 28800 $ */
/** @file tstXPCOMCGlue.c
* Demonstrator program to illustrate use of C bindings of Main API.
*
diff --git a/src/VBox/Main/cbinding/tstXPCOMCGlue.c b/src/VBox/Main/cbinding/tstXPCOMCGlue.c
index 751bb1acd..d2e87876a 100644
--- a/src/VBox/Main/cbinding/tstXPCOMCGlue.c
+++ b/src/VBox/Main/cbinding/tstXPCOMCGlue.c
@@ -1,4 +1,4 @@
-/* $Revision: 66862 $ */
+/* $Revision: 33294 $ */
/** @file tstXPCOMCGlue.c
* Demonstrator program to illustrate use of C bindings of Main API.
*
diff --git a/src/VBox/Main/cbinding/xpcidl.xsl b/src/VBox/Main/cbinding/xpcidl.xsl
index fdab2a8ba..38d3139cb 100644
--- a/src/VBox/Main/cbinding/xpcidl.xsl
+++ b/src/VBox/Main/cbinding/xpcidl.xsl
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
-<!-- $Id: xpcidl.xsl $ -->
+<!-- $Id: xpcidl.xsl 32404 2010-09-10 13:17:42Z vboxsync $ -->
<!--
* A template to generate a XPCOM IDL compatible interface definition file
diff --git a/src/VBox/Main/glue/ErrorInfo.cpp b/src/VBox/Main/glue/ErrorInfo.cpp
index 8d7e31eca..758f2b5a5 100644
--- a/src/VBox/Main/glue/ErrorInfo.cpp
+++ b/src/VBox/Main/glue/ErrorInfo.cpp
@@ -1,4 +1,4 @@
-/* $Id: ErrorInfo.cpp $ */
+/* $Id: ErrorInfo.cpp 33782 2010-11-04 16:23:22Z vboxsync $ */
/** @file
*
diff --git a/src/VBox/Main/glue/EventQueue.cpp b/src/VBox/Main/glue/EventQueue.cpp
index 364c3a85b..1216f512e 100644
--- a/src/VBox/Main/glue/EventQueue.cpp
+++ b/src/VBox/Main/glue/EventQueue.cpp
@@ -1,4 +1,4 @@
-/* $Id: EventQueue.cpp $ */
+/* $Id: EventQueue.cpp 33720 2010-11-03 10:54:42Z vboxsync $ */
/** @file
* MS COM / XPCOM Abstraction Layer:
* Event and EventQueue class declaration
diff --git a/src/VBox/Main/glue/VirtualBoxErrorInfo.cpp b/src/VBox/Main/glue/VirtualBoxErrorInfo.cpp
index 6e863edb1..8854a99e4 100644
--- a/src/VBox/Main/glue/VirtualBoxErrorInfo.cpp
+++ b/src/VBox/Main/glue/VirtualBoxErrorInfo.cpp
@@ -1,4 +1,4 @@
-/* $Id: VirtualBoxErrorInfo.cpp $ */
+/* $Id: VirtualBoxErrorInfo.cpp 32780 2010-09-27 19:00:22Z vboxsync $ */
/** @file
* MS COM / XPCOM Abstraction Layer:
diff --git a/src/VBox/Main/glue/com.cpp b/src/VBox/Main/glue/com.cpp
index 896c1d91f..465ab400b 100644
--- a/src/VBox/Main/glue/com.cpp
+++ b/src/VBox/Main/glue/com.cpp
@@ -1,4 +1,4 @@
-/* $Id: com.cpp $ */
+/* $Id: com.cpp 30632 2010-07-05 19:36:40Z vboxsync $ */
/** @file
* MS COM / XPCOM Abstraction Layer
*/
diff --git a/src/VBox/Main/glue/errorprint.cpp b/src/VBox/Main/glue/errorprint.cpp
index 3e8c9caf0..68da8bbe9 100644
--- a/src/VBox/Main/glue/errorprint.cpp
+++ b/src/VBox/Main/glue/errorprint.cpp
@@ -1,4 +1,4 @@
-/* $Id: errorprint.cpp $ */
+/* $Id: errorprint.cpp 32718 2010-09-23 12:57:52Z vboxsync $ */
/** @file
* MS COM / XPCOM Abstraction Layer:
diff --git a/src/VBox/Main/glue/glue-java.xsl b/src/VBox/Main/glue/glue-java.xsl
index 18ed6f147..db03e8dc8 100644
--- a/src/VBox/Main/glue/glue-java.xsl
+++ b/src/VBox/Main/glue/glue-java.xsl
@@ -287,12 +287,12 @@
<xsl:template name="typeIdl2Back">
<xsl:param name="type" />
<xsl:param name="safearray" />
- <xsl:param name="forceelem" />
-
- <xsl:variable name="needarray" select="($safearray='yes') and not($forceelem='yes')" />
+ <xsl:param name="forceelem" />
- <xsl:choose>
+ <xsl:choose>
<xsl:when test="($G_vboxGlueStyle='xpcom')">
+ <xsl:variable name="needarray" select="($safearray='yes') and not($forceelem='yes')" />
+
<xsl:choose>
<xsl:when test="$type='long long'">
<xsl:value-of select="'long'" />
@@ -367,6 +367,8 @@
</xsl:when>
<xsl:when test="($G_vboxGlueStyle='jaxws')">
+ <xsl:variable name="needarray" select="($safearray='yes' and not($type='octet')) and not($forceelem='yes')" />
+
<xsl:if test="$needarray">
<xsl:value-of select="'List&lt;'" />
</xsl:if>
@@ -387,6 +389,11 @@
<xsl:value-of select="concat($G_virtualBoxPackageCom, '.', $type)" />
</xsl:when>
+ <!-- we encode byte arrays as Base64 strings. -->
+ <xsl:when test="$type='octet'">
+ <xsl:value-of select="'/*base64*/String'" />
+ </xsl:when>
+
<xsl:when test="$type='long long'">
<xsl:value-of select="'Long'" />
</xsl:when>
@@ -407,10 +414,6 @@
<xsl:value-of select="'Short'" />
</xsl:when>
- <xsl:when test="$type='octet'">
- <xsl:value-of select="'Short'" />
- </xsl:when>
-
<xsl:when test="$type='boolean'">
<xsl:value-of select="'Boolean'" />
</xsl:when>
@@ -649,7 +652,7 @@
<xsl:value-of select="concat('Helper.wrap(',$elemgluetype,'.class, port, ', $value,')')"/>
</xsl:when>
<xsl:when test="$idltype='octet'">
- <xsl:value-of select="concat('Helper.wrapBytes(',$value,')')"/>
+ <xsl:value-of select="concat('Helper.decodeBase64(',$value,')')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$value" />
@@ -955,6 +958,10 @@
</xsl:choose>
</xsl:when>
+ <xsl:when test="($idltype='octet') and ($safearray='yes')">
+ <xsl:value-of select="concat('Helper.encodeBase64(', $value,')')"/>
+ </xsl:when>
+
<xsl:otherwise>
<xsl:call-template name="fatalError">
<xsl:with-param name="msg" select="concat('Unhandled type: ', $idltype)" />
@@ -1026,7 +1033,7 @@
</xsl:when>
<xsl:when test="($idltype='octet') and ($safearray='yes')">
- <xsl:value-of select="concat('Helper.unwrapBytes(',$value,')')"/>
+ <xsl:value-of select="concat('Helper.encodeBase64(',$value,')')"/>
</xsl:when>
<xsl:otherwise>
@@ -2441,12 +2448,10 @@ public class VirtualBoxManager
private Mozilla mozilla;
private IVirtualBox vbox;
private nsIComponentManager componentManager;
- private nsIServiceManager servMgr;
- private VirtualBoxManager(Mozilla mozilla, nsIServiceManager servMgr)
+ private VirtualBoxManager(Mozilla mozilla)
{
this.mozilla = mozilla;
- this.servMgr = servMgr;
this.componentManager = mozilla.getComponentManager();
this.vbox = new IVirtualBox((org.mozilla.interfaces.IVirtualBox) this.componentManager
.createInstanceByContractID("@virtualbox.org/VirtualBox;1",
@@ -2498,29 +2503,36 @@ public class VirtualBoxManager
}
private static boolean hasInstance = false;
+ private static boolean isMozillaInited = false;
public static synchronized VirtualBoxManager createInstance(String home)
{
if (hasInstance)
throw new VBoxException(null, "only one instance at the time allowed");
+ if (home == null || "".equals(home))
+ home = System.getProperty("vbox.home");
if (home == null)
- home = System.getProperty("vbox.home");
+ throw new RuntimeException("vbox.home Java property must be defined to use XPCOM bridge");
File grePath = new File(home);
+
Mozilla mozilla = Mozilla.getInstance();
- mozilla.initialize(grePath);
- nsIServiceManager servMgr = null;
- try {
- servMgr = mozilla.initXPCOM(grePath, null);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
+ if (!isMozillaInited)
+ {
+ mozilla.initialize(grePath);
+ try {
+ mozilla.initXPCOM(grePath, null);
+ isMozillaInited = true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
}
hasInstance = true;
- return new VirtualBoxManager(mozilla, servMgr);
+ return new VirtualBoxManager(mozilla);
}
public IEventListener createListener(Object sink)
@@ -2530,8 +2542,9 @@ public class VirtualBoxManager
public void cleanup()
{
deinitPerThread();
- // cleanup
- mozilla.shutdownXPCOM(servMgr);
+ // cleanup, we don't do that, as XPCOM bridge doesn't cleanly
+ // shuts down, so we prefer to avoid native shutdown
+ // mozilla.shutdownXPCOM(null);
mozilla = null;
hasInstance = false;
}
@@ -2856,11 +2869,24 @@ public class Helper {
SafeArray result = new SafeArray(Variant.VariantBoolean, vals.size());
int i = 0;
for (boolean l : vals) {
- result.setBoolean(i, l);
+ result.setBoolean(i++, l);
+ }
+ return result;
+ }
+
+
+ public static SafeArray unwrapBytes(byte[] vals) {
+ if (vals==null) return null;
+
+ SafeArray result = new SafeArray(Variant.VariantByte, vals.length);
+ int i = 0;
+ for (byte l : vals) {
+ result.setByte(i++, l);
}
return result;
}
+
public static <T extends Enum <T>> SafeArray unwrapEnum(Class<T> enumClass, List<T> values) {
if (values == null) return null;
@@ -2869,7 +2895,7 @@ public class Helper {
java.lang.reflect.Method valueM = enumClass.getMethod("value");
int i = 0;
for (T v : values) {
- result.setInt(i, (Integer)valueM.invoke(v));
+ result.setInt(i++, (Integer)valueM.invoke(v));
}
return result;
} catch (NoSuchMethodException e) {
@@ -2890,7 +2916,7 @@ public class Helper {
SafeArray result = new SafeArray(Variant.VariantString, vals.size());
int i = 0;
for (String l : vals) {
- result.setString(i, l);
+ result.setString(i++, l);
}
return result;
}
@@ -3216,27 +3242,136 @@ public class Helper {
throw new AssertionError(e);
}
}
- // temporary methods, will go away soon
- public static byte[] wrapBytes(List<Short> arr)
+
+ /* Pretty naive Base64 encoder/decoder. */
+ private static final char[] valToChar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
+ private static final int[] charToVal = new int[256];
+
+ /* Initialize recoding alphabet. */
+ static
{
- if (arr == null)
- return null;
- int i = 0;
- byte[] rv = new byte[arr.size()];
- for (short s : arr)
- rv[i++] = (byte)(s & 0xff);
- return rv;
+ for (int i = 0; i < charToVal.length; i++)
+ charToVal[i] = -1;
+
+ for (int i = 0; i < valToChar.length; i++)
+ charToVal[valToChar[i]] = i;
+
+ charToVal['='] = 0;
}
- public static List<Short> unwrapBytes(byte[] arr)
+ public static String encodeBase64(byte[] data)
{
- if (arr == null)
- return null;
- List<Short> ret = new ArrayList<Short>(arr.length);
- for (byte b : arr) {
- ret.add((short)b);
- }
- return ret;
+ if (data == null)
+ return null;
+
+ if (data.length == 0)
+ return "";
+
+ int fullTriplets = data.length / 3;
+ int resultLen = ((data.length - 1) / 3 + 1) * 4;
+ char[] result = new char[resultLen];
+ int dataIndex = 0, stringIndex = 0;
+
+ for (int i = 0; i < fullTriplets; i++)
+ {
+ int ch1 = data[dataIndex++] & 0xff;
+ result[stringIndex++] = valToChar[ch1 >> 2];
+ int ch2 = data[dataIndex++] & 0xff;
+ result[stringIndex++] = valToChar[((ch1 << 4) & 0x3f) | (ch2 >> 4)];
+ int ch3 = data[dataIndex++] & 0xff;
+ result[stringIndex++] = valToChar[((ch2 << 2) & 0x3f) | (ch3 >> 6)];
+ result[stringIndex++] = valToChar[ch3 & 0x3f];
+ }
+
+ switch (data.length - dataIndex)
+ {
+ case 0:
+ // do nothing
+ break;
+ case 1:
+ {
+ int ch1 = data[dataIndex++] & 0xff;
+ result[stringIndex++] = valToChar[ch1 >> 2];
+ result[stringIndex++] = valToChar[(ch1 << 4) & 0x3f];
+ result[stringIndex++] = '=';
+ result[stringIndex++] = '=';
+ break;
+ }
+ case 2:
+ {
+ int ch1 = data[dataIndex++] & 0xff;
+ result[stringIndex++] = valToChar[ch1 >> 2];
+ int ch2 = data[dataIndex++] & 0xff;
+ result[stringIndex++] = valToChar[((ch1 << 4) & 0x3f) | (ch2 >> 4)];
+ result[stringIndex++] = valToChar[(ch2 << 2) & 0x3f];
+ result[stringIndex++] = '=';
+ break;
+ }
+ default:
+ throw new RuntimeException("bug!");
+ }
+
+ return new String(result);
+ }
+
+ private static int skipInvalid(String str, int stringIndex)
+ {
+ while (charToVal[str.charAt(stringIndex)] < 0)
+ stringIndex++;
+
+ return stringIndex;
+ }
+
+ public static byte[] decodeBase64(String str)
+ {
+ if (str == null)
+ return null;
+
+ int stringLength = str.length();
+ if (stringLength == 0)
+ return new byte[0];
+
+ int validChars = 0, padChars = 0;
+ for (int i = 0; i < str.length(); i++)
+ {
+ char ch = str.charAt(i);
+
+ if (charToVal[ch] >= 0)
+ validChars++;
+
+ if (ch == '=')
+ padChars++;
+ }
+
+ if ((validChars * 3 % 4) != 0)
+ throw new RuntimeException("invalid encoded string "+str);
+
+ int resultLength = validChars * 3 / 4 - padChars;
+ byte[] result = new byte[resultLength];
+
+ int dataIndex = 0, stringIndex = 0;
+ int quadraplets = validChars / 4;
+
+ for (int i=0; i<quadraplets; i++)
+ {
+ stringIndex = skipInvalid(str, stringIndex);
+ int ch1 = str.charAt(stringIndex++);
+ stringIndex = skipInvalid(str, stringIndex);
+ int ch2 = str.charAt(stringIndex++);
+ stringIndex = skipInvalid(str, stringIndex);
+ int ch3 = str.charAt(stringIndex++);
+ stringIndex = skipInvalid(str, stringIndex);
+ int ch4 = str.charAt(stringIndex++);
+
+ result[dataIndex++] = (byte)(((charToVal[ch1] << 2) | charToVal[ch2] >> 4) & 0xff);
+ /* we check this to ensure that we don't override data with '=' padding. */
+ if (dataIndex < result.length)
+ result[dataIndex++] = (byte)(((charToVal[ch2] << 4) | charToVal[ch3] >> 2) & 0xff);
+ if (dataIndex < result.length)
+ result[dataIndex++] = (byte)(((charToVal[ch3] << 6) | charToVal[ch4]) & 0xff);
+ }
+
+ return result;
}
}
]]></xsl:text>
diff --git a/src/VBox/Main/glue/initterm.cpp b/src/VBox/Main/glue/initterm.cpp
index e44c4df17..c2adf88ce 100644
--- a/src/VBox/Main/glue/initterm.cpp
+++ b/src/VBox/Main/glue/initterm.cpp
@@ -1,4 +1,4 @@
-/* $Id: initterm.cpp $ */
+/* $Id: initterm.cpp 35640 2011-01-19 20:44:02Z vboxsync $ */
/** @file
* MS COM / XPCOM Abstraction Layer - Initialization and Termination.
@@ -246,87 +246,30 @@ static uint32_t gCOMMainInitCount = 0;
*
* @return S_OK on success and a COM result code in case of failure.
*/
-HRESULT Initialize()
+HRESULT Initialize(bool fGui)
{
HRESULT rc = E_FAIL;
#if !defined(VBOX_WITH_XPCOM)
- DWORD flags = COINIT_MULTITHREADED
+ /*
+ * We initialize COM in GUI thread in STA, to be compliant with QT and
+ * OLE requirments (for example to allow D&D), while other threads
+ * initialized in regular MTA. To allow fast proxyless access from
+ * GUI thread to COM objects, we explicitly provide our COM objects
+ * with free threaded marshaller.
+ * !!!!! Please think twice before touching this code !!!!!
+ */
+ DWORD flags = fGui ?
+ COINIT_APARTMENTTHREADED
+ | COINIT_SPEED_OVER_MEMORY
+ :
+ COINIT_MULTITHREADED
| COINIT_DISABLE_OLE1DDE
| COINIT_SPEED_OVER_MEMORY;
rc = CoInitializeEx(NULL, flags);
- /// @todo the below rough method of changing the apartment type doesn't
- /// work on some systems for unknown reason (CoUninitialize() simply does
- /// nothing there, or at least all 10 000 of subsequent CoInitializeEx()
- /// continue to return RPC_E_CHANGED_MODE there). The problem on those
- /// systems is related to the "Extend support for advanced text services
- /// to all programs" checkbox in the advanced language settings dialog,
- /// i.e. the problem appears when this checkbox is checked and disappears
- /// if you clear it. For this reason, we disable the code below and
- /// instead initialize COM in MTA as early as possible, before 3rd party
- /// libraries we use have done so (i.e. Qt).
-# if 0
- /* If we fail to set the necessary apartment model, it may mean that some
- * DLL that was indirectly loaded by the process calling this function has
- * already initialized COM on the given thread in an incompatible way
- * which we can't leave with. Therefore, we try to fix this by using the
- * brute force method: */
-
- if (rc == RPC_E_CHANGED_MODE)
- {
- /* Before we use brute force, we need to check if we are in the
- * neutral threaded apartment -- in this case there is no need to
- * worry at all. */
-
- rc = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- if (rc == RPC_E_CHANGED_MODE)
- {
- /* This is a neutral apartment, reset the error */
- rc = S_OK;
-
- LogFlowFunc(("COM is already initialized in neutral threaded "
- "apartment mode,\nwill accept it.\n"));
- }
- else if (rc == S_FALSE)
- {
- /* balance the test CoInitializeEx above */
- CoUninitialize();
- rc = RPC_E_CHANGED_MODE;
-
- LogFlowFunc(("COM is already initialized in single threaded "
- "apartment mode,\nwill reinitialize as "
- "multi threaded.\n"));
-
- enum { MaxTries = 10000 };
- int tries = MaxTries;
- while (rc == RPC_E_CHANGED_MODE && tries --)
- {
- CoUninitialize();
- rc = CoInitializeEx(NULL, flags);
- if (rc == S_OK)
- {
- /* We've successfully reinitialized COM; restore the
- * initialization reference counter */
-
- LogFlowFunc(("Will call CoInitializeEx() %d times.\n",
- MaxTries - tries));
-
- while (tries ++ < MaxTries)
- {
- rc = CoInitializeEx(NULL, flags);
- Assert(rc == S_FALSE);
- }
- }
- }
- }
- else
- AssertMsgFailed(("rc=%08X\n", rc));
- }
-# endif
-
/* the overall result must be either S_OK or S_FALSE (S_FALSE means
* "already initialized using the same apartment model") */
AssertMsg(rc == S_OK || rc == S_FALSE, ("rc=%08X\n", rc));
@@ -341,6 +284,10 @@ HRESULT Initialize()
ASMAtomicCmpXchgHandle(&gCOMMainThread, hSelf, NIL_RTTHREAD, fRc);
else
fRc = false;
+
+ if (fGui)
+ Assert(RTThreadIsMain(hSelf));
+
if (!fRc)
{
if ( gCOMMainThread == hSelf
@@ -359,6 +306,9 @@ HRESULT Initialize()
#else /* !defined (VBOX_WITH_XPCOM) */
+ /* Unused here */
+ NOREF(fGui);
+
if (ASMAtomicXchgBool(&gIsXPCOMInitialized, true) == true)
{
/* XPCOM is already initialized on the main thread, no special
diff --git a/src/VBox/Main/glue/string.cpp b/src/VBox/Main/glue/string.cpp
index 930dc2ef2..49fe8366c 100644
--- a/src/VBox/Main/glue/string.cpp
+++ b/src/VBox/Main/glue/string.cpp
@@ -1,13 +1,10 @@
-/* $Id: string.cpp $ */
-
+/* $Id: string.cpp 36530 2011-04-04 13:56:10Z vboxsync $ */
/** @file
- *
- * MS COM / XPCOM Abstraction Layer:
- * UTF-8 and UTF-16 string classes
+ * MS COM / XPCOM Abstraction Layer - UTF-8 and UTF-16 string classes.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -22,6 +19,7 @@
#include <iprt/err.h>
#include <iprt/path.h>
+#include <iprt/log.h>
namespace com
{
@@ -30,7 +28,7 @@ namespace com
// this will work on Windows as well as other platforms where BSTR does
// not use length prefixes
const OLECHAR g_achEmptyBstr[3] = { 0, 0, 0 };
-const BSTR g_bstrEmpty = (BSTR)(&g_achEmptyBstr[2]);
+const BSTR g_bstrEmpty = (BSTR)&g_achEmptyBstr[2];
/* static */
const Bstr Bstr::Empty; /* default ctor is OK */
@@ -52,22 +50,26 @@ void Bstr::copyFromN(const char *a_pszSrc, size_t a_cchMax)
*/
size_t cwc;
int vrc = ::RTStrCalcUtf16LenEx(a_pszSrc, a_cchMax, &cwc);
- AssertRCReturnVoid(vrc); /* throw instead? */
+ if (RT_FAILURE(vrc))
+ {
+ /* ASSUME: input is valid Utf-8. Fake out of memory error. */
+ AssertLogRelMsgFailed(("%Rrc %.*Rhxs\n", vrc, RTStrNLen(a_pszSrc, a_cchMax), a_pszSrc));
+ throw std::bad_alloc();
+ }
m_bstr = ::SysAllocStringByteLen(NULL, cwc * sizeof(OLECHAR));
- if (m_bstr)
+ if (RT_UNLIKELY(!m_bstr))
+ throw std::bad_alloc();
+
+ PRTUTF16 pwsz = (PRTUTF16)m_bstr;
+ vrc = ::RTStrToUtf16Ex(a_pszSrc, a_cchMax, &pwsz, cwc + 1, NULL);
+ if (RT_FAILURE(vrc))
{
- PRTUTF16 pwsz = (PRTUTF16)m_bstr;
- vrc = ::RTStrToUtf16Ex(a_pszSrc, a_cchMax, &pwsz, cwc + 1, NULL);
- if (RT_FAILURE(vrc))
- {
- /* This should not happen! */
- AssertRC(vrc);
- cleanup();
- }
- }
- else
+ /* This should not happen! */
+ AssertRC(vrc);
+ cleanup();
throw std::bad_alloc();
+ }
}
@@ -79,7 +81,7 @@ void Utf8Str::cloneTo(char **pstr) const
{
size_t cb = length() + 1;
*pstr = (char*)nsMemory::Alloc(cb);
- if (!*pstr)
+ if (RT_UNLIKELY(!*pstr))
throw std::bad_alloc();
memcpy(*pstr, c_str(), cb);
}
@@ -136,40 +138,46 @@ Utf8Str& Utf8Str::stripExt()
* Internal function used in Utf8Str copy constructors and assignment when
* copying from a UTF-16 string.
*
- * As with the iprt::ministring::copyFrom() variants, this unconditionally
- * sets the members to a copy of the given other strings and makes
- * no assumptions about previous contents. This can therefore be used
- * both in copy constructors, when member variables have no defined
- * value, and in assignments after having called cleanup().
+ * As with the RTCString::copyFrom() variants, this unconditionally sets the
+ * members to a copy of the given other strings and makes no assumptions about
+ * previous contents. This can therefore be used both in copy constructors,
+ * when member variables have no defined value, and in assignments after having
+ * called cleanup().
*
* This variant converts from a UTF-16 string, most probably from
* a Bstr assignment.
*
- * @param s
+ * @param a_pbstr The source string. The caller guarantees that this
+ * is valid UTF-16.
+ *
+ * @sa RTCString::copyFromN
*/
-void Utf8Str::copyFrom(CBSTR s)
+void Utf8Str::copyFrom(CBSTR a_pbstr)
{
- if (s && *s)
+ if (a_pbstr && *a_pbstr)
{
- int vrc = RTUtf16ToUtf8Ex((PRTUTF16)s, // PCRTUTF16 pwszString
+ int vrc = RTUtf16ToUtf8Ex((PCRTUTF16)a_pbstr,
RTSTR_MAX, // size_t cwcString: translate entire string
&m_psz, // char **ppsz: output buffer
0, // size_t cch: if 0, func allocates buffer in *ppsz
&m_cch); // size_t *pcch: receives the size of the output string, excluding the terminator.
- if (RT_FAILURE(vrc))
+ if (RT_SUCCESS(vrc))
+ m_cbAllocated = m_cch + 1;
+ else
{
- if ( vrc == VERR_NO_STR_MEMORY
- || vrc == VERR_NO_MEMORY
- )
- throw std::bad_alloc();
+ if ( vrc != VERR_NO_STR_MEMORY
+ && vrc != VERR_NO_MEMORY)
+ {
+ /* ASSUME: input is valid Utf-16. Fake out of memory error. */
+ AssertLogRelMsgFailed(("%Rrc %.*Rhxs\n", vrc, RTUtf16Len(a_pbstr) * sizeof(RTUTF16), a_pbstr));
+ }
- // @todo what do we do with bad input strings? throw also? for now just keep an empty string
m_cch = 0;
m_cbAllocated = 0;
m_psz = NULL;
+
+ throw std::bad_alloc();
}
- else
- m_cbAllocated = m_cch + 1;
}
else
{
diff --git a/src/VBox/Main/glue/tests/TestVBox.java b/src/VBox/Main/glue/tests/TestVBox.java
index 18956a9b9..447260548 100644
--- a/src/VBox/Main/glue/tests/TestVBox.java
+++ b/src/VBox/Main/glue/tests/TestVBox.java
@@ -1,4 +1,4 @@
-/* $Id: TestVBox.java $ */
+/* $Id: TestVBox.java 36281 2011-03-15 11:49:08Z vboxsync $ */
/*
* Copyright (C) 2010 Oracle Corporation
*
@@ -10,7 +10,7 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-import org.virtualbox_3_3.*;
+import org.virtualbox_4_1.*;
import java.util.List;
import java.util.Arrays;
import java.math.BigInteger;
diff --git a/src/VBox/Main/idl/VirtualBox.xidl b/src/VBox/Main/idl/VirtualBox.xidl
index 54b98d847..f434cfda3 100644
--- a/src/VBox/Main/idl/VirtualBox.xidl
+++ b/src/VBox/Main/idl/VirtualBox.xidl
@@ -271,8 +271,8 @@
<tr><td>E_POINTER</td>
<td>
Returned if a memory pointer for the output argument is invalid (for
- example, @c null). Note that when pointers representing input
- arguments (such as strings) are invalid, E_INVALIDARG is returned.
+ example, @c null). When pointers representing input arguments (such
+ as strings) are invalid, E_INVALIDARG is returned.
</td>
</tr>
<tr><td>E_ACCESSDENIED</td>
@@ -480,8 +480,16 @@
/@format attribute for DVD and floppy images.
-->
</const>
+ <const name="v1_12" value="14">
+ <desc>Settings version "1.12", written by VirtualBox 4.1.x.</desc>
+ <!--
+ Machine changes: raw PCI device attachment;
+ NetworkAdapter changes: bandwidth group.
+ -->
+ </const>
+
<const name="Future" value="99999">
- <desc>Settings version greater than "1.11", written by a future VirtualBox version.</desc>
+ <desc>Settings version greater than "1.12", written by a future VirtualBox version.</desc>
</const>
</enum>
@@ -1198,11 +1206,11 @@
specifically for this purpose and allows to represent a chain of errors
through a single IVirtualBoxErrorInfo object set after method invocation.
- Note that errors are stored to a chain in the reverse order, i.e. the
+ <note>errors are stored to a chain in the reverse order, i.e. the
initial error object you query right after method invocation is the last
error set by the callee, the object it points to in the @a next attribute
is the previous error and so on, up to the first error (which is the last
- in the chain).
+ in the chain).</note>
</desc>
<attribute name="resultCode" type="long" readonly="yes">
@@ -1383,7 +1391,7 @@
<interface
name="IVirtualBox" extends="$unknown"
- uuid="d2de270c-1d4b-4c9e-843f-bbb9b47269ff"
+ uuid="c28be65f-1a8f-43b4-81f1-eb60cb516e66"
wsmap="managed"
>
<desc>
@@ -1425,6 +1433,18 @@
</desc>
</attribute>
+ <attribute name="APIVersion" type="wstring" readonly="yes">
+ <desc>
+ A string representing the VirtualBox API version number. The format is
+ 2 integer numbers divided by an underscore (e.g. 1_0). After the
+ first public release of packages with a particular API version the
+ API will not be changed in an incompatible way. Note that this
+ guarantee does not apply to development builds, and also there is no
+ guarantee that this version is identical to the first two integer
+ numbers of the package version.
+ </desc>
+ </attribute>
+
<attribute name="homeFolder" type="wstring" readonly="yes">
<desc>
Full path to the directory where the global settings file,
@@ -1530,6 +1550,18 @@
</attribute>
+ <attribute name="internalNetworks" type="wstring" safearray="yes" readonly="yes">
+ <desc>
+ Names of all internal networks.
+ </desc>
+ </attribute>
+
+ <attribute name="genericNetworkDrivers" type="wstring" safearray="yes" readonly="yes">
+ <desc>
+ Names of all generic network drivers.
+ </desc>
+ </attribute>
+
<method name="composeMachineFilename">
<desc>
Returns a recommended full path of the settings file name for a new virtual
@@ -1759,9 +1791,9 @@
Creates a new base medium object that will use the given storage
format and location for medium data.
- Note that the actual storage unit is not created by this method. In
- order to do it, and before you are able to attach the created medium
- to virtual machines, you must call one of the following methods to
+ The actual storage unit is not created by this method. In order to
+ do it, and before you are able to attach the created medium to
+ virtual machines, you must call one of the following methods to
allocate a format-specific storage unit at the specified location:
<ul>
<li><link to="IMedium::createBaseStorage"/></li>
@@ -1893,6 +1925,12 @@
<desc>Whether to open the image in read/write or read-only mode. For
a "DVD" device type, this is ignored and read-only mode is always assumed.</desc>
</param>
+ <param name="forceNewUuid" type="boolean" dir="in">
+ <desc>Allows the caller to request a completely new medium UUID for
+ the image which is to be opened. Useful if one intends to open an exact
+ copy of a previously opened image, as this would normally fail due to
+ the duplicate UUID.</desc>
+ </param>
<param name="medium" type="IMedium" dir="return">
<desc>Opened medium object.</desc>
</param>
@@ -2317,6 +2355,25 @@
</interface>
+ <enum
+ name="ImportOptions" extends="$unknown"
+ uuid="0a981523-3b20-4004-8ee3-dfd322202ace"
+ >
+
+ <desc>
+ Import options, used with <link to="IAppliance::importMachines" />.
+ </desc>
+
+ <const name="KeepAllMACs" value="1">
+ <desc>Don't generate new MAC addresses of the attached network adapters.</desc>
+ </const>
+ <const name="KeepNATMACs" value="2">
+ <desc>Don't generate new MAC addresses of the attached network adapters when they are using NAT.</desc>
+ </const>
+
+ </enum>
+
+
<!--
// IAppliance
/////////////////////////////////////////////////////////////////////////
@@ -2324,7 +2381,7 @@
<interface
name="IAppliance" extends="$unknown"
- uuid="7b148032-4124-4f46-b56a-b48ac1273f5a"
+ uuid="3059cf9e-25c7-4f0b-9fa5-3c42e441670b"
wsmap="managed"
>
<desc>
@@ -2371,7 +2428,7 @@
</li>
<li>If desired, call <link to="IVirtualSystemDescription::setFinalValues" /> for each
- virtual system (machine) to override the suggestions made by the interpret() routine.
+ virtual system (machine) to override the suggestions made by the <link to="#interpret" /> routine.
</li>
<li>Finally, call <link to="#importMachines" /> to create virtual machines in
@@ -2394,7 +2451,7 @@
</li>
<li>If desired, call <link to="IVirtualSystemDescription::setFinalValues" /> for each
- virtual system (machine) to override the suggestions made by the export() routine.
+ virtual system (machine) to override the suggestions made by the <link to="IMachine::export"/> routine.
</li>
<li>Finally, call <link to="#write" /> with a path specification to have the OVF
@@ -2415,7 +2472,7 @@
<desc>
Array of virtual disk definitions. One such description exists for each
disk definition in the OVF; each string array item represents one such piece of
- disk information, with the information fields separated by tab (\t) characters.
+ disk information, with the information fields separated by tab (\\t) characters.
The caller should be prepared for additional fields being appended to
this string in future versions of VirtualBox and therefore check for
@@ -2520,6 +2577,10 @@
retrieved from the <link to="#machines" /> array attribute.
</desc>
+ <param name="options" type="ImportOptions" dir="in" safearray="yes">
+ <desc>Options for the importing operation.</desc>
+ </param>
+
<param name="aProgress" type="IProgress" dir="return">
<desc>Progress object to track the operation completion.</desc>
</param>
@@ -2583,7 +2644,7 @@
<enum
name="VirtualSystemDescriptionType"
- uuid="c0f8f135-3a1d-417d-afa6-b38b95a91f90"
+ uuid="303c0900-a746-4612-8c67-79003e91f459"
>
<desc>Used with <link to="IVirtualSystemDescription" /> to describe the type of
a configuration value.</desc>
@@ -2611,7 +2672,9 @@
<const name="NetworkAdapter" value="21" />
<const name="USBController" value="22" />
<const name="SoundCard" value="23" />
-
+ <const name="SettingsFile" value="24">
+ <desc>Not used/implemented right now, will be added later in 4.1.x.</desc>
+ </const>
</enum>
<enum
@@ -2845,8 +2908,8 @@
and SoundCard.
For the "vbox" and "extra configuration" values, if you pass in the same arrays
- as returned in the aVBoxValues and aExtraConfigValues arrays from getDescription(),
- the configuration remains unchanged. Please see the documentation for getDescription()
+ as returned in the aVBoxValues and aExtraConfigValues arrays from <link to="#getDescription"/>,
+ the configuration remains unchanged. Please see the documentation for <link to="#getDescription"/>
for valid configuration values for the individual array item types. If the
corresponding item in the aEnabled array is @c false, the configuration value is ignored.
</desc>
@@ -2894,7 +2957,7 @@
<interface
name="IInternalMachineControl" extends="$unknown"
- uuid="8e723ab0-812c-5662-dd8e-7ebc89637acf"
+ uuid="2087906d-bb92-43a0-8014-4cab009e4888"
internal="yes"
wsmap="suppress"
>
@@ -3114,7 +3177,7 @@
<method name="adoptSavedState">
<desc>
- Gets called by IConsole::adoptSavedState.
+ Gets called by <link to="IConsole::adoptSavedState"/>.
<result name="VBOX_E_FILE_ERROR">
Invalid saved state file path.
</result>
@@ -3185,16 +3248,26 @@
<method name="deleteSnapshot">
<desc>
- Gets called by IConsole::deleteSnapshot.
+ Gets called by <link to="IConsole::deleteSnapshot"/>,
+ <link to="IConsole::deleteSnapshotAndAllChildren"/> and
+ <link to="IConsole::deleteSnapshotRange"/>.
<result name="VBOX_E_INVALID_OBJECT_STATE">
- Snapshot has more than one child snapshot.
+ Snapshot has more than one child snapshot. Only possible if the
+ delete operation does not delete all children or the range does
+ not meet the linearity condition.
</result>
</desc>
<param name="initiator" type="IConsole" dir="in">
<desc>The console object that initiated this call.</desc>
</param>
- <param name="id" type="uuid" mod="string" dir="in">
- <desc>UUID of the snapshot to delete.</desc>
+ <param name="startId" type="uuid" mod="string" dir="in">
+ <desc>UUID of the first snapshot to delete.</desc>
+ </param>
+ <param name="endId" type="uuid" mod="string" dir="in">
+ <desc>UUID of the last snapshot to delete.</desc>
+ </param>
+ <param name="deleteAllChildren" type="boolean" dir="in">
+ <desc>Whether all children should be deleted.</desc>
</param>
<param name="machineState" type="MachineState" dir="out">
<desc>New machine state after this operation is started.</desc>
@@ -3206,7 +3279,7 @@
<method name="finishOnlineMergeMedium">
<desc>
- Gets called by IConsole::onlineMergeMedium.
+ Gets called by <link to="IInternalSessionControl::onlineMergeMedium"/>.
</desc>
<param name="mediumAttachment" type="IMediumAttachment" dir="in">
<desc>The medium attachment which needs to be cleaned up.</desc>
@@ -3231,7 +3304,7 @@
<method name="restoreSnapshot">
<desc>
- Gets called by IConsole::RestoreSnapshot.
+ Gets called by <link to="IConsole::restoreSnapshot"/>.
</desc>
<param name="initiator" type="IConsole" dir="in">
<desc>The console object that initiated this call.</desc>
@@ -3324,6 +3397,24 @@
possible to teleport between processes on the same machine.
</desc>
</method>
+
+ <method name="ejectMedium">
+ <desc>
+ Tells VBoxSVC that the guest has ejected the medium associated with
+ the medium attachment.
+ </desc>
+ <param name="attachment" type="IMediumAttachment" dir="in">
+ <desc>
+ The medium attachment where the eject happened.
+ </desc>
+ </param>
+ <param name="newAttachment" type="IMediumAttachment" dir="return">
+ <desc>
+ A new reference to the medium attachment, as the config change can
+ result in the creation of a new instance.
+ </desc>
+ </param>
+ </method>
</interface>
<interface
@@ -3409,17 +3500,6 @@
</enum>
<interface
- name="IEventContext" extends="$unknown"
- uuid="7563F4E7-1583-40F7-B4C4-C9BA02CB0AE3"
- wsmap="managed"
- >
- <desc>
- Placeholder class for event contexts.
- </desc>
- </interface>
-
-
- <interface
name="IPciAddress" extends="$unknown"
uuid="D88B324F-DB19-4D3B-A1A9-BF5B127199A8"
wsmap="struct"
@@ -3498,10 +3578,55 @@
</interface>
+ <enum
+ name="CloneMode" extends="$unknown"
+ uuid="A7A159FE-5096-4B8D-8C3C-D033CB0B35A8"
+ >
+
+ <desc>
+ Clone mode, used with <link to="IMachine::cloneTo" />.
+ </desc>
+
+ <const name="MachineState" value="1">
+ <desc>Clone the state of the selected machine.</desc>
+ </const>
+ <const name="MachineAndChildStates" value="2">
+ <desc>Clone the state of the selected machine and its child snapshots if present.</desc>
+ </const>
+ <const name="AllStates" value="3">
+ <desc>Clone all states (including all snapshots) of the machine, regardless of the machine object used.</desc>
+ </const>
+
+ </enum>
+
+ <enum
+ name="CloneOptions" extends="$unknown"
+ uuid="22243f8e-96ab-497c-8cf0-f40a566c630b"
+ >
+
+ <desc>
+ Clone options, used with <link to="IMachine::cloneTo" />.
+ </desc>
+
+ <const name="Link" value="1">
+ <desc>Create a clone VM where all virtual disks are linked to the original VM.</desc>
+ </const>
+ <const name="KeepAllMACs" value="2">
+ <desc>Don't generate new MAC addresses of the attached network adapters.</desc>
+ </const>
+ <const name="KeepNATMACs" value="3">
+ <desc>Don't generate new MAC addresses of the attached network adapters when they are using NAT.</desc>
+ </const>
+ <const name="KeepDiskNames" value="4">
+ <desc>Don't change the disk names.</desc>
+ </const>
+
+ </enum>
+
<interface
name="IMachine" extends="$unknown"
- uuid="662c175e-a69d-40b8-a77a-1d719d0ab062"
+ uuid="5eaa9319-62fc-4b0a-843c-0cb1940f8a91"
wsmap="managed"
>
<desc>
@@ -3537,7 +3662,7 @@
execution (such as start the machine, or power it down) -- these methods
are grouped in a separate interface called <link to="IConsole" />.
- <see>ISession, IConsole</see>
+ <see><link to="ISession"/>, <link to="IConsole"/></see>
</desc>
<attribute name="parent" type="IVirtualBox" readonly="yes">
@@ -3669,7 +3794,7 @@
</desc>
</attribute>
- <attribute name="HardwareVersion" type="wstring">
+ <attribute name="hardwareVersion" type="wstring">
<desc>Hardware version identifier. Internal use only for now.</desc>
</attribute>
@@ -3709,7 +3834,7 @@
<desc>Memory balloon size in megabytes.</desc>
</attribute>
- <attribute name="PageFusionEnabled" type="boolean">
+ <attribute name="pageFusionEnabled" type="boolean">
<desc>
This setting determines whether VirtualBox allows page
fusion for this machine (64 bits host only).
@@ -3812,6 +3937,9 @@
<desc>VirtualBox Remote Desktop Extension (VRDE) server object.</desc>
</attribute>
+ <attribute name="emulatedUSBWebcameraEnabled" type="boolean" default="false"/>
+ <attribute name="emulatedUSBCardReaderEnabled" type="boolean" default="false"/>
+
<attribute name="mediumAttachments" type="IMediumAttachment" readonly="yes" safearray="yes">
<desc>Array of media attached to this machine.</desc>
</attribute>
@@ -4101,11 +4229,12 @@
</attribute>
<attribute name="pciDeviceAssignments" type="IPciDeviceAttachment" readonly="yes" safearray="yes">
- <desc>Array of PCI devices assigned to this machine, to get list of all PCI devices
- attached to the machine use IConsole::attachedPciDevices attribute, as
- this attribute is intended to list only devices additional to what
- described in virtual hardware config. Usually, this list keeps host's
- physical devices assigned to the particular machine.
+ <desc>Array of PCI devices assigned to this machine, to get list of all
+ PCI devices attached to the machine use
+ <link to="IConsole::attachedPciDevices"/> attribute, as this attribute
+ is intended to list only devices additional to what described in
+ virtual hardware config. Usually, this list keeps host's physical
+ devices assigned to the particular machine.
</desc>
</attribute>
@@ -4558,6 +4687,81 @@
</param>
</method>
+ <method name="temporaryEjectDevice">
+ <desc>
+ Sets the behavior for guest-triggered medium eject. In some situations
+ it is desirable that such ejects update the VM configuration, and in
+ others the eject should keep the VM configuration. The device must
+ already exist; see <link to="IMachine::attachDevice"/> for how to
+ attach a new device.
+
+ The @a controllerPort and @a device parameters specify the device slot and
+ have have the same meaning as with <link to="IMachine::attachDevice" />.
+
+ <result name="E_INVALIDARG">
+ SATA device, SATA port, IDE port or IDE slot out of range.
+ </result>
+ <result name="VBOX_E_INVALID_OBJECT_STATE">
+ Attempt to modify an unregistered virtual machine.
+ </result>
+ <result name="VBOX_E_INVALID_VM_STATE">
+ Invalid machine state.
+ </result>
+
+ </desc>
+ <param name="name" type="wstring" dir="in">
+ <desc>Name of the storage controller.</desc>
+ </param>
+ <param name="controllerPort" type="long" dir="in">
+ <desc>Storage controller port.</desc>
+ </param>
+ <param name="device" type="long" dir="in">
+ <desc>Device slot in the given port.</desc>
+ </param>
+ <param name="temporaryEject" type="boolean" dir="in">
+ <desc>New value for the eject behavior.</desc>
+ </param>
+ </method>
+
+ <method name="nonRotationalDevice">
+ <desc>
+ Sets a flag in the device information which indicates that the medium
+ is not based on rotational technology, i.e. that the access times are
+ more or less independent of the position on the medium. This may or may
+ not be supported by a particular drive, and is silently ignored in the
+ latter case. At the moment only hard disks (which is a misnomer in this
+ context) accept this setting. Changing the setting while the VM is
+ running is forbidden. The device must already exist; see
+ <link to="IMachine::attachDevice"/> for how to attach a new device.
+
+ The @a controllerPort and @a device parameters specify the device slot and
+ have have the same meaning as with <link to="IMachine::attachDevice" />.
+
+ <result name="E_INVALIDARG">
+ SATA device, SATA port, IDE port or IDE slot out of range.
+ </result>
+ <result name="VBOX_E_INVALID_OBJECT_STATE">
+ Attempt to modify an unregistered virtual machine.
+ </result>
+ <result name="VBOX_E_INVALID_VM_STATE">
+ Invalid machine state.
+ </result>
+
+ </desc>
+ <param name="name" type="wstring" dir="in">
+ <desc>Name of the storage controller.</desc>
+ </param>
+ <param name="controllerPort" type="long" dir="in">
+ <desc>Storage controller port.</desc>
+ </param>
+ <param name="device" type="long" dir="in">
+ <desc>Device slot in the given port.</desc>
+ </param>
+ <param name="nonRotational" type="boolean" dir="in">
+ <desc>New value for the non-rotational device flag.</desc>
+ </param>
+ </method>
+
<method name="setBandwidthGroupForDevice">
<desc>
Sets the bandwidth group of an existing storage device.
@@ -4711,11 +4915,8 @@
is two phase, as real attachment will happen when VM will start,
and most information will be delivered as IHostPciDevicePlugEvent
on IVirtualBox event source.
- <note>
- Not yet implemented.
- </note>
- <see>IHostPciDevicePlugEvent</see>
+ <see><link to="IHostPciDevicePlugEvent"/></see>
<result name="VBOX_E_INVALID_VM_STATE">
Virtual machine state is not stopped (PCI hotplug not yet implemented).
@@ -4733,9 +4934,6 @@
<param name="desiredGuestAddress" type="long" dir="in">
<desc>Desired position of this device on guest PCI bus.</desc>
</param>
- <param name="eventContext" type="IEventContext" dir="in">
- <desc>Context passed into IHostPciDevicePlugEvent event.</desc>
- </param>
<param name="tryToUnbind" type="boolean" dir="in">
<desc>If VMM shall try to unbind existing drivers from the
device before attaching it to the guest.</desc>
@@ -4746,13 +4944,10 @@
<desc>
Detach host PCI device from the virtual machine.
Also HostPciDevicePlugEvent on IVirtualBox event source
- will be delivered.
-
- <note>
- Not yet implemented.
- </note>
+ will be delivered. As currently we don't support hot device
+ unplug, IHostPciDevicePlugEvent event is delivered immediately.
- <see>IHostPciDevicePlugEvent</see>
+ <see><link to="IHostPciDevicePlugEvent"/></see>
<result name="VBOX_E_INVALID_VM_STATE">
Virtual machine state is not stopped (PCI hotplug not yet implemented).
@@ -4777,7 +4972,7 @@
Returns the network adapter associated with the given slot.
Slots are numbered sequentially, starting with zero. The total
number of adapters per machine is defined by the
- <link to="ISystemProperties::networkAdapterCount"/> property,
+ <link to="ISystemProperties::getMaxNetworkAdapters"/> property,
so the maximum slot number is one less than that property's value.
<result name="E_INVALIDARG">
@@ -5279,7 +5474,7 @@
registry, the other machine cannot find its media any more and would become inaccessible.
This API implicitly calls <link to="#saveSettings"/> to save all current machine settings
- before unregistering it. It may also silently call saveSettings() on other machines
+ before unregistering it. It may also silently call <link to="#saveSettings"/> on other machines
if media are moved to other machines' media registries.
After successful method invocation, the <link to="IMachineRegisteredEvent"/> event
@@ -5327,7 +5522,7 @@
for each online snapshot that the machine had.</li>
<li>On each medium object passed in the @a aMedia array, this will call
<link to="IMedium::close" />. If that succeeds, this will attempt to delete the
- medium's storage on disk. Since the close() call will fail if the medium is still
+ medium's storage on disk. Since the <link to="IMedium::close"/> call will fail if the medium is still
in use, e.g. because it is still attached to a second machine; in that case the
storage will not be deleted.</li>
<li>Finally, the machine's own XML file will be deleted.</li>
@@ -5651,7 +5846,7 @@
</param>
</method>
- <method name="enumerateGuestProperties">
+ <method name="enumerateGuestProperties" const="yes">
<desc>
Return a list of the guest properties matching a set of patterns along
with their values, time stamps and flags.
@@ -5687,7 +5882,7 @@
</param>
</method>
- <method name="querySavedGuestSize">
+ <method name="querySavedGuestSize" const="yes">
<desc>
Returns the guest dimensions from the saved state.
</desc>
@@ -5928,6 +6123,42 @@
</desc>
</param>
</method>
+
+ <method name="cloneTo">
+ <desc>
+ Creates a clone of this machine, either as a full clone (which means
+ creating independent copies of the hard disk media, save states and so
+ on), or as a linked clone (which uses its own differencing media,
+ sharing the parent media with the source machine).
+
+ The target machine object must have been created previously with <link
+ to="IVirtualBox::createMachine"/>, and all the settings will be
+ transferred except the VM name and the hardware UUID. You can set the
+ VM name and the new hardware UUID when creating the target machine. The
+ network MAC addresses are newly created for all newtwork adapters. You
+ can change that behaviour with the options parameter. The operation is
+ performed asynchronously, so the machine object will be not be usable
+ until the @a progress object signals completion.
+
+ <result name="E_INVALIDARG">
+ @a target is @c null.
+ </result>
+ </desc>
+
+ <param name="target" type="IMachine" dir="in">
+ <desc>Target machine object.</desc>
+ </param>
+ <param name="mode" type="CloneMode" dir="in">
+ <desc>Which states should be cloned.</desc>
+ </param>
+ <param name="options" type="CloneOptions" dir="in" safearray="yes">
+ <desc>Options for the cloning operation.</desc>
+ </param>
+ <param name="progress" type="IProgress" dir="return">
+ <desc>Progress object to track the operation completion.</desc>
+ </param>
+ </method>
+
</interface>
<!--
@@ -6045,7 +6276,7 @@
<interface
name="IConsole" extends="$unknown"
- uuid="515e8e8d-f932-4d8e-9f32-79a52aead882"
+ uuid="1968b7d3-e3bf-4ceb-99e0-cb7c913317bb"
wsmap="managed"
>
<desc>
@@ -6062,7 +6293,7 @@
the machine state or take a snapshot, attach and detach removable media
and so on.
- <see>ISession</see>
+ <see><link to="ISession"/></see>
</desc>
<attribute name="machine" type="IMachine" readonly="yes">
@@ -6176,6 +6407,15 @@
<desc>Array of PCI devices attached to this machine.</desc>
</attribute>
+ <attribute name="useHostClipboard" type="boolean">
+ <desc>
+ Whether the guest clipboard should be connected to the host one or
+ whether it should only be allowed access to the VRDE clipboard. This
+ setting may not affect existing guest clipboard connections which
+ are already connected to the host clipboard.
+ </desc>
+ </attribute>
+
<method name="powerUp">
<desc>
Starts the virtual machine execution using the current machine
@@ -6211,7 +6451,7 @@
last three operations of the progress objected returned by
<link to="IMachine::launchVMProcess"/> as well.
- <see>#saveState</see>
+ <see><link to="#saveState"/></see>
<result name="VBOX_E_INVALID_VM_STATE">
Virtual machine already running.
@@ -6234,7 +6474,7 @@
<link to="MachineState_Paused"/> state, instead of
<link to="MachineState_Running"/>.
- <see>#powerUp</see>
+ <see><link to="#powerUp"/></see>
<result name="VBOX_E_INVALID_VM_STATE">
Virtual machine already running.
</result>
@@ -6467,7 +6707,8 @@
<link to="USBDeviceState_Busy">Busy</link>, an error may also
be returned if the host computer refuses to release it for some reason.
- <see>IUSBController::deviceFilters, USBDeviceState</see>
+ <see><link to="IUSBController::deviceFilters"/>,
+ <link to="USBDeviceState"/></see>
<result name="VBOX_E_INVALID_VM_STATE">
Virtual machine state neither Running nor Paused.
</result>
@@ -6490,7 +6731,8 @@
to the host, but filters of this machine are ignored to avoid
a possible automatic re-attachment.
- <see>IUSBController::deviceFilters, USBDeviceState</see>
+ <see><link to="IUSBController::deviceFilters"/>,
+ <link to="USBDeviceState"/></see>
<result name="VBOX_E_PDM_ERROR">
Virtual machine does not have a USB controller.
@@ -6515,7 +6757,7 @@
Given @c name does not correspond to any USB device.
</result>
- <see>IUSBDevice::address</see>
+ <see><link to="IUSBDevice::address"/></see>
</desc>
<param name="name" type="wstring" dir="in">
<desc>
@@ -6536,7 +6778,7 @@
Given @c id does not correspond to any USB device.
</result>
- <see>IUSBDevice::id</see>
+ <see><link to="IUSBDevice::id"/></see>
</desc>
<param name="id" type="uuid" mod="string" dir="in">
<desc>UUID of the USB device to search for.</desc>
@@ -6658,20 +6900,22 @@
<ul>
<li>Child media of all normal media of the deleted snapshot
- must be accessible (see <link to="IMedium::state"/>) for this
- operation to succeed. In particular, this means that all virtual
- machines whose media are directly or indirectly based on the
- media of deleted snapshot must be powered off.</li>
+ must be accessible (see <link to="IMedium::state"/>) for this
+ operation to succeed. If only one running VM refers to all images
+ which participates in merging the operation can be performed while
+ the VM is running. Otherwise all virtual machines whose media are
+ directly or indirectly based on the media of deleted snapshot must
+ be powered off. In any case, online snapshot deleting usually is
+ slower than the same operation without any running VM.</li>
<li>You cannot delete the snapshot if a medium attached to it has
- more than once child medium (differencing images) because otherwise
+ more than one child medium (differencing images) because otherwise
merging would be impossible. This might be the case if there is
more than one child snapshot or differencing images were created
for other reason (e.g. implicitly because of multiple machine
attachments).</li>
</ul>
-
The virtual machine's <link to="IMachine::state">state</link> is
changed to "DeletingSnapshot", "DeletingSnapshotOnline" or
"DeletingSnapshotPaused" while this operation is in progress.
@@ -6698,6 +6942,77 @@
</param>
</method>
+ <method name="deleteSnapshotAndAllChildren">
+ <desc>
+ Starts deleting the specified snapshot and all its children
+ asynchronously. See <link to="ISnapshot" /> for an introduction to
+ snapshots. The conditions and many details are the same as with
+ <link to="#deleteSnapshot"/>.
+
+ This operation is very fast if the snapshot subtree does not include
+ the current state. It is still significantly faster than deleting the
+ snapshots one by one if the current state is in the subtree and there
+ are more than one snapshots from current state to the snapshot which
+ marks the subtree, since it eliminates the incremental image merging.
+
+ <note>This API method is right now not implemented!</note>
+
+ <result name="VBOX_E_INVALID_VM_STATE">
+ The running virtual machine prevents deleting this snapshot. This
+ happens only in very specific situations, usually snapshots can be
+ deleted without trouble while a VM is running. The error message
+ text explains the reason for the failure.
+ </result>
+ <result name="E_NOTIMPL">
+ The method is not implemented yet.
+ </result>
+ </desc>
+ <param name="id" type="uuid" mod="string" dir="in">
+ <desc>UUID of the snapshot to delete, including all its children.</desc>
+ </param>
+ <param name="progress" type="IProgress" dir="return">
+ <desc>Progress object to track the operation completion.</desc>
+ </param>
+ </method>
+
+ <method name="deleteSnapshotRange">
+ <desc>
+ Starts deleting the specified snapshot range. This is limited to
+ linear snapshot lists, which means there may not be any other child
+ snapshots other than the direct sequence between the start and end
+ snapshot. If the start and end snapshot point to the same snapshot this
+ method is completely equivalent to <link to="#deleteSnapshot"/>. See
+ <link to="ISnapshot" /> for an introduction to snapshots. The
+ conditions and many details are the same as with
+ <link to="#deleteSnapshot"/>.
+
+ This operation is generally faster than deleting snapshots one by one
+ and often also needs less extra disk space before freeing up disk space
+ by deleting the removed disk images corresponding to the snapshot.
+
+ <note>This API method is right now not implemented!</note>
+
+ <result name="VBOX_E_INVALID_VM_STATE">
+ The running virtual machine prevents deleting this snapshot. This
+ happens only in very specific situations, usually snapshots can be
+ deleted without trouble while a VM is running. The error message
+ text explains the reason for the failure.
+ </result>
+ <result name="E_NOTIMPL">
+ The method is not implemented yet.
+ </result>
+ </desc>
+ <param name="startId" type="uuid" mod="string" dir="in">
+ <desc>UUID of the first snapshot to delete.</desc>
+ </param>
+ <param name="endId" type="uuid" mod="string" dir="in">
+ <desc>UUID of the last snapshot to delete.</desc>
+ </param>
+ <param name="progress" type="IProgress" dir="return">
+ <desc>Progress object to track the operation completion.</desc>
+ </param>
+ </method>
+
<method name="restoreSnapshot">
<desc>
Starts resetting the machine's current state to the state contained
@@ -6790,7 +7105,7 @@
<desc>
Type of encapsulation. Ethernet encapsulation includes both wired and
wireless Ethernet connections.
- <see>IHostNetworkInterface</see>
+ <see><link to="IHostNetworkInterface"/></see>
</desc>
<const name="Unknown" value="0">
@@ -6821,7 +7136,7 @@
>
<desc>
Current status of the interface.
- <see>IHostNetworkInterface</see>
+ <see><link to="IHostNetworkInterface"/></see>
</desc>
<const name="Unknown" value="0">
@@ -6955,7 +7270,7 @@
<interface
name="IHost" extends="$unknown"
- uuid="35b004f4-7806-4009-bfa8-d1308adba7e5"
+ uuid="dab4a2b8-c735-4f08-94fc-9bec84182e2f"
wsmap="managed"
>
<desc>
@@ -7009,7 +7324,8 @@
VirtualBox, this method will set the result code to @c E_NOTIMPL.
</note>
- <see>IHostUSBDeviceFilter, USBDeviceState</see>
+ <see><link to="IHostUSBDeviceFilter"/>,
+ <link to="USBDeviceState"/></see>
</desc>
</attribute>
@@ -7198,7 +7514,7 @@
The created filter can be added to the list of filters using
<link to="#insertUSBDeviceFilter"/>.
- <see>#USBDeviceFilters</see>
+ <see><link to="#USBDeviceFilters"/></see>
</desc>
<param name="name" type="wstring" dir="in">
<desc>
@@ -7228,7 +7544,7 @@
VirtualBox, this method will set the result code to @c E_NOTIMPL.
</note>
- <see>#USBDeviceFilters</see>
+ <see><link to="#USBDeviceFilters"/></see>
<result name="VBOX_E_INVALID_OBJECT_STATE">
USB device filter is not created within this VirtualBox instance.
@@ -7260,7 +7576,7 @@
VirtualBox, this method will set the result code to @c E_NOTIMPL.
</note>
- <see>#USBDeviceFilters</see>
+ <see><link to="#USBDeviceFilters"/></see>
<result name="E_INVALIDARG">
USB device filter list empty or invalid @a position.
@@ -7358,7 +7674,7 @@
Given @c id does not correspond to any USB device.
</result>
- <see>IHostUSBDevice::id</see>
+ <see><link to="IUSBDevice::id"/></see>
</desc>
<param name="id" type="uuid" mod="string" dir="in">
<desc>UUID of the USB device to search for.</desc>
@@ -7376,7 +7692,7 @@
Given @c name does not correspond to any USB device.
</result>
- <see>IHostUSBDevice::address</see>
+ <see><link to="IUSBDevice::address"/></see>
</desc>
<param name="name" type="wstring" dir="in">
<desc>
@@ -7389,6 +7705,15 @@
</param>
</method>
+ <method name="generateMACAddress">
+ <desc>
+ Generates a valid Ethernet MAC address, 12 hexadecimal characters.
+ </desc>
+ <param name="address" type="wstring" dir="return">
+ <desc>New Ethernet MAC address.</desc>
+ </param>
+ </method>
+
</interface>
<!--
@@ -7399,7 +7724,7 @@
<interface
name="ISystemProperties"
extends="$unknown"
- uuid="51c81048-b261-4fa2-a44e-fd756f0db589"
+ uuid="8a0ab9ab-48c1-4d04-954b-4a751413d084"
wsmap="managed"
>
<desc>
@@ -7444,23 +7769,16 @@
does not reflect the limits of any virtual disk image format.</desc>
</attribute>
- <attribute name="networkAdapterCount" type="unsigned long" readonly="yes">
- <desc>
- Number of network adapters associated with every
- <link to="IMachine"/> instance.
- </desc>
- </attribute>
-
<attribute name="serialPortCount" type="unsigned long" readonly="yes">
<desc>
- Number of serial ports associated with every
+ Maximum number of serial ports associated with every
<link to="IMachine"/> instance.
</desc>
</attribute>
<attribute name="parallelPortCount" type="unsigned long" readonly="yes">
<desc>
- Number of parallel ports associated with every
+ Maximum number of parallel ports associated with every
<link to="IMachine"/> instance.
</desc>
</attribute>
@@ -7519,9 +7837,7 @@
the list of supported formats depends on what backends are currently
installed.
- <see>
- <link to="IMediumFormat"/>,
- </see>
+ <see><link to="IMediumFormat"/></see>
</desc>
</attribute>
@@ -7647,7 +7963,7 @@
</desc>
</attribute>
- <attribute name="LogHistoryCount" type="unsigned long">
+ <attribute name="logHistoryCount" type="unsigned long">
<desc>
This value specifies how many old release log files are kept.
</desc>
@@ -7658,6 +7974,46 @@
system.</desc>
</attribute>
+
+ <method name="getMaxNetworkAdapters">
+ <desc>
+ Maximum total number of network adapters associated with every
+ <link to="IMachine"/> instance.
+ </desc>
+
+ <param name="chipset" type="ChipsetType" dir="in">
+ <desc>The chipset type to get the value for.</desc>
+ </param>
+
+
+ <param name="maxNetworkAdapters" type="unsigned long" dir="return">
+ <desc>The maximum total number of network adapters allowed.</desc>
+ </param>
+
+ </method>
+
+ <method name="getMaxNetworkAdaptersOfType">
+ <desc>
+ Maximum number of network adapters of a given attachment type,
+ associated with every <link to="IMachine"/> instance.
+ </desc>
+
+ <param name="chipset" type="ChipsetType" dir="in">
+ <desc>The chipset type to get the value for.</desc>
+ </param>
+
+ <param name="type" type="NetworkAttachmentType" dir="in">
+ <desc>Type of attachment.</desc>
+ </param>
+
+ <param name="maxNetworkAdapters" type="unsigned long" dir="return">
+ <desc>The maximum number of network adapters allowed for
+ particular chipset and attachment type.</desc>
+ </param>
+
+ </method>
+
+
<method name="getMaxDevicesPerPortForStorageBus">
<desc>Returns the maximum number of devices which can be attached to a port
for the given storage bus.</desc>
@@ -7667,7 +8023,7 @@
</param>
<param name="maxDevicesPerPort" type="unsigned long" dir="return">
- <desc>The maximum number of devices which can eb attached to the port for the given
+ <desc>The maximum number of devices which can be attached to the port for the given
storage bus.</desc>
</param>
</method>
@@ -7851,6 +8207,141 @@
</interface>
<enum
+ name="AdditionsFacilityType"
+ uuid="98f7f957-89fb-49b6-a3b1-31e3285eb1d8"
+ >
+ <desc>
+ Guest Additions facility IDs.
+ </desc>
+
+ <const name="None" value="0">
+ <desc>No/invalid facility.</desc>
+ </const>
+ <const name="VBoxGuestDriver" value="20">
+ <desc>VirtualBox base driver (VBoxGuest).</desc>
+ </const>
+ <const name="VBoxService" value="100">
+ <desc>VirtualBox system service (VBoxService).</desc>
+ </const>
+ <const name="VBoxTrayClient" value="101">
+ <desc>VirtualBox desktop integration (VBoxTray on Windows, VBoxClient on non-Windows).</desc>
+ </const>
+ <const name="Seamless" value="1000">
+ <desc>Seamless guest desktop integration.</desc>
+ </const>
+ <const name="Graphics" value="1100">
+ <desc>Guest graphics mode. If not enabled, seamless rendering will not work, resize hints
+ are not immediately acted on and guest display resizes are probably not initiated by
+ the guest additions.
+ </desc>
+ </const>
+ <const name="All" value="2147483646">
+ <desc>All facilities selected.</desc>
+ </const>
+ </enum>
+
+ <enum
+ name="AdditionsFacilityClass"
+ uuid="446451b2-c88d-4e5d-84c9-91bc7f533f5f"
+ >
+ <desc>
+ Guest Additions facility classes.
+ </desc>
+
+ <const name="None" value="0">
+ <desc>No/invalid class.</desc>
+ </const>
+ <const name="Driver" value="10">
+ <desc>Driver.</desc>
+ </const>
+ <const name="Service" value="30">
+ <desc>System service.</desc>
+ </const>
+ <const name="Program" value="50">
+ <desc>Program.</desc>
+ </const>
+ <const name="Feature" value="100">
+ <desc>Feature.</desc>
+ </const>
+ <const name="ThirdParty" value="999">
+ <desc>Third party.</desc>
+ </const>
+ <const name="All" value="2147483646">
+ <desc>All facility classes selected.</desc>
+ </const>
+ </enum>
+
+ <enum
+ name="AdditionsFacilityStatus"
+ uuid="ce06f9e1-394e-4fe9-9368-5a88c567dbde"
+ >
+ <desc>
+ Guest Additions facility states.
+ </desc>
+
+ <const name="Inactive" value="0">
+ <desc>Facility is not active.</desc>
+ </const>
+ <const name="Paused" value="1">
+ <desc>Facility has been paused.</desc>
+ </const>
+ <const name="PreInit" value="20">
+ <desc>Facility is preparing to initialize.</desc>
+ </const>
+ <const name="Init" value="30">
+ <desc>Facility is initializing.</desc>
+ </const>
+ <const name="Active" value="50">
+ <desc>Facility is up and running.</desc>
+ </const>
+ <const name="Terminating" value="100">
+ <desc>Facility is shutting down.</desc>
+ </const>
+ <const name="Terminated" value="101">
+ <desc>Facility successfully shut down.</desc>
+ </const>
+ <const name="Failed" value="800">
+ <desc>Facility failed to start.</desc>
+ </const>
+ <const name="Unknown" value="999">
+ <desc>Facility status is unknown.</desc>
+ </const>
+ </enum>
+
+ <interface
+ name="IAdditionsFacility" extends="$unknown"
+ uuid="54992946-6af1-4e49-98ec-58b558b7291e"
+ wsmap="struct"
+ >
+ <desc>
+ Structure representing a Guest Additions facility.
+ </desc>
+
+ <attribute name="classType" type="AdditionsFacilityClass" readonly="yes">
+ <desc>The class this facility is part of.</desc>
+ </attribute>
+
+ <attribute name="lastUpdated" type="long long" readonly="yes">
+ <desc>
+ Time stamp of the last status update,
+ in milliseconds since 1970-01-01 UTC.
+ </desc>
+ </attribute>
+
+ <attribute name="name" type="wstring" readonly="yes">
+ <desc>The facility's friendly name.</desc>
+ </attribute>
+
+ <attribute name="status" type="AdditionsFacilityStatus" readonly="yes">
+ <desc>The current status.</desc>
+ </attribute>
+
+ <attribute name="type" type="AdditionsFacilityType" readonly="yes">
+ <desc>The facility's type ID.</desc>
+ </attribute>
+ </interface>
+
+ <enum
name="AdditionsRunLevelType"
uuid="a25417ee-a9dd-4f5b-b0dc-377860087754"
>
@@ -7891,7 +8382,7 @@
<enum
name="ExecuteProcessFlag"
- uuid="3258e8a5-ba0c-43d5-86b5-cf91405fddc0"
+ uuid="286ceb91-5f66-4c96-9845-4483e90e00ae"
>
<desc>
Guest process execution flags.
@@ -7900,16 +8391,13 @@
<const name="None" value="0">
<desc>No flag set.</desc>
</const>
-
<const name="WaitForProcessStartOnly" value="1">
<desc>Only use the specified timeout value to wait for starting the guest process - the guest
process itself then uses an infinite timeout.</desc>
</const>
-
<const name="IgnoreOrphanedProcesses" value="2">
<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>
</const>
@@ -7919,13 +8407,49 @@
</enum>
<enum
+ name="ExecuteProcessStatus"
+ uuid="153768d9-d971-4098-8b5a-c5cb1ab9ea88"
+ >
+ <desc>
+ Guest process execution status.
+ </desc>
+ <const name="Undefined" value="0">
+ <desc>Process is in an undefined state.</desc>
+ </const>
+
+ <const name="Started" value="1">
+ <desc>Process has been started.</desc>
+ </const>
+ <const name="TerminatedNormally" value="2">
+ <desc>Process terminated normally.</desc>
+ </const>
+ <const name="TerminatedSignal" value="3">
+ <desc>Process terminated via signal.</desc>
+ </const>
+ <const name="TerminatedAbnormally" value="4">
+ <desc>Process terminated abnormally.</desc>
+ </const>
+ <const name="TimedOutKilled" value="5">
+ <desc>Process timed out and was killed.</desc>
+ </const>
+ <const name="TimedOutAbnormally" value="6">
+ <desc>Process timed out and was not killed successfully.</desc>
+ </const>
+ <const name="Down" value="7">
+ <desc>Service/OS is stopping, process was killed.</desc>
+ </const>
+ <const name="Error" value="8">
+ <desc>Something went wrong (error code in flags).</desc>
+ </const>
+ </enum>
+
+ <enum
name="ProcessInputFlag"
uuid="5d38c1dd-2604-4ddf-92e5-0c0cdd3bdbd5"
>
<desc>
Guest process input flags.
</desc>
-
<const name="None" value="0">
<desc>No flag set.</desc>
</const>
@@ -7935,6 +8459,22 @@
</enum>
<enum
+ name="ProcessOutputFlag"
+ uuid="9979e85a-52bb-40b7-870c-57115e27e0f1"
+ >
+ <desc>
+ Guest process output flags for specifying which
+ type of output to retrieve.
+ </desc>
+ <const name="None" value="0">
+ <desc>No flags set. Get output from stdout.</desc>
+ </const>
+ <const name="StdErr" value="1">
+ <desc>Get output from stderr.</desc>
+ </const>
+ </enum>
+
+ <enum
name="CopyFileFlag"
uuid="23f79fdf-738a-493d-b80b-42d607c9b916"
>
@@ -7942,44 +8482,90 @@
Host/Guest copy flags. At the moment none of these flags
are implemented.
</desc>
-
<const name="None" value="0">
<desc>No flag set.</desc>
</const>
-
<const name="Recursive" value="1">
<desc>Copy directories recursively.</desc>
</const>
-
<const name="Update" value="2">
<desc>Only copy when the source file is newer than the destination file or when the destination file is missing.</desc>
</const>
-
<const name="FollowLinks" value="4">
<desc>Follow symbolic links.</desc>
</const>
</enum>
<enum
- name="CreateDirectoryFlag"
- uuid="26ff5bdd-c81f-4304-857b-b8be5e3f9cd6"
- >
+ name="DirectoryCreateFlag"
+ uuid="bd721b0e-ced5-4f79-b368-249897c32a36"
+ >
<desc>
Directory creation flags.
</desc>
-
<const name="None" value="0">
<desc>No flag set.</desc>
</const>
-
<const name="Parents" value="1">
<desc>No error if existing, make parent directories as needed.</desc>
</const>
</enum>
+ <enum
+ name="DirectoryOpenFlag"
+ uuid="fc8f6203-0072-4f34-bd08-0b35e50bf071"
+ >
+ <desc>
+ Directory open flags.
+ </desc>
+ <const name="None" value="0">
+ <desc>No flag set.</desc>
+ </const>
+ </enum>
+
+ <enum
+ name="GuestDirEntryType"
+ uuid="6d19d924-1b77-4fc8-b369-a3b2c85c8241"
+ >
+ <desc>
+ Guest directory entry type.
+ </desc>
+ <const name="Unknown" value="0">
+ <desc>Unknown.</desc>
+ </const>
+ <const name="Directory" value="4">
+ <desc>Regular file.</desc>
+ </const>
+ <const name="File" value="10">
+ <desc>Regular file.</desc>
+ </const>
+ <const name="Symlink" value="12">
+ <desc>Symbolic link.</desc>
+ </const>
+ </enum>
+
+ <interface
+ name="IGuestDirEntry" extends="$unknown"
+ uuid="20a66efc-c2f6-4438-826f-38454c04369e"
+ wsmap="struct"
+ >
+ <desc>
+ Structure representing a directory entry on the guest OS.
+ </desc>
+ <attribute name="nodeId" type="long long" readonly="yes">
+ <desc>The unique identifier (within the guest's file system) of this file system object.</desc>
+ </attribute>
+ <attribute name="name" type="wstring" readonly="yes">
+ <desc>The filename.</desc>
+ </attribute>
+ <attribute name="type" type="GuestDirEntryType" readonly="yes">
+ <desc>The entry type.</desc>
+ </attribute>
+ </interface>
+
<interface
name="IGuest" extends="$unknown"
- uuid="7ce7e4d8-cdaa-4d83-a0f4-510c8ee70aea"
+ uuid="ed109b6e-0578-4b17-8ace-52646789f1a0"
wsmap="managed"
>
<desc>
@@ -8020,19 +8606,10 @@
</desc>
</attribute>
- <attribute name="supportsSeamless" type="boolean" readonly="yes">
- <desc>
- Flag whether seamless guest display rendering (seamless desktop
- integration) is supported.
- </desc>
- </attribute>
-
- <attribute name="supportsGraphics" type="boolean" readonly="yes">
+ <attribute name="facilities" type="IAdditionsFacility" readonly="yes" safearray="yes">
<desc>
- Flag whether the guest is in graphics mode. If it is not, then
- seamless rendering will not work, resize hints are not immediately
- acted on and guest display resizes are probably not initiated by
- the guest additions.
+ Array of current known facilities. Only returns facilities where a status is known,
+ e.g. facilities with an unknown status will not be returned.
</desc>
</attribute>
@@ -8046,46 +8623,61 @@
<method name="internalGetStatistics">
<desc>
- Internal method; do not use as it might change at any time
+ Internal method; do not use as it might change at any time.
</desc>
<param name="cpuUser" type="unsigned long" dir="out">
- <desc>Percentage of processor time spent in user mode as seen by the guest</desc>
+ <desc>Percentage of processor time spent in user mode as seen by the guest.</desc>
</param>
<param name="cpuKernel" type="unsigned long" dir="out">
- <desc>Percentage of processor time spent in kernel mode as seen by the guest</desc>
+ <desc>Percentage of processor time spent in kernel mode as seen by the guest.</desc>
</param>
<param name="cpuIdle" type="unsigned long" dir="out">
- <desc>Percentage of processor time spent idling as seen by the guest</desc>
+ <desc>Percentage of processor time spent idling as seen by the guest.</desc>
</param>
<param name="memTotal" type="unsigned long" dir="out">
- <desc>Total amount of physical guest RAM</desc>
+ <desc>Total amount of physical guest RAM.</desc>
</param>
<param name="memFree" type="unsigned long" dir="out">
- <desc>Free amount of physical guest RAM</desc>
+ <desc>Free amount of physical guest RAM.</desc>
</param>
<param name="memBalloon" type="unsigned long" dir="out">
- <desc>Amount of ballooned physical guest RAM</desc>
+ <desc>Amount of ballooned physical guest RAM.</desc>
</param>
<param name="memShared" type="unsigned long" dir="out">
- <desc>Amount of shared physical guest RAM</desc>
+ <desc>Amount of shared physical guest RAM.</desc>
</param>
<param name="memCache" type="unsigned long" dir="out">
- <desc>Total amount of guest (disk) cache memory</desc>
+ <desc>Total amount of guest (disk) cache memory.</desc>
</param>
<param name="pagedTotal" type="unsigned long" dir="out">
- <desc>Total amount of space in the page file</desc>
+ <desc>Total amount of space in the page file.</desc>
</param>
<param name="memAllocTotal" type="unsigned long" dir="out">
- <desc>Total amount of memory allocated by the hypervisor</desc>
+ <desc>Total amount of memory allocated by the hypervisor.</desc>
</param>
<param name="memFreeTotal" type="unsigned long" dir="out">
- <desc>Total amount of free memory available in the hypervisor</desc>
+ <desc>Total amount of free memory available in the hypervisor.</desc>
</param>
<param name="memBalloonTotal" type="unsigned long" dir="out">
- <desc>Total amount of memory ballooned by the hypervisor</desc>
+ <desc>Total amount of memory ballooned by the hypervisor.</desc>
</param>
<param name="memSharedTotal" type="unsigned long" dir="out">
- <desc>Total amount of shared memory in the hypervisor</desc>
+ <desc>Total amount of shared memory in the hypervisor.</desc>
+ </param>
+ </method>
+
+ <method name="getFacilityStatus">
+ <desc>
+ Get the current status of a Guest Additions facility.
+ </desc>
+ <param name="facility" type="AdditionsFacilityType" dir="in">
+ <desc>Facility to check status for.</desc>
+ </param>
+ <param name="timestamp" type="long long" dir="out">
+ <desc>Timestamp (in ms) of last status update seen by the host.</desc>
+ </param>
+ <param name="status" type="AdditionsFacilityStatus" dir="return">
+ <desc>The current (latest) facility status.</desc>
</param>
</method>
@@ -8207,12 +8799,12 @@
</desc>
<param name="pid" type="unsigned long" dir="in">
<desc>
- Process id returned by earlier executeProcess() call.
+ Process id returned by earlier <link to="#executeProcess"/> call.
</desc>
</param>
<param name="flags" type="unsigned long" dir="in">
<desc>
- Flags describing which output to retrieve.
+ <link to="ProcessOutputFlag"/> flags.
</desc>
</param>
<param name="timeoutMS" type="unsigned long" dir="in">
@@ -8226,7 +8818,7 @@
Size in bytes to read in the buffer.
</desc>
</param>
- <param name="data" type="octet" dir="return" safearray="yes">
+ <param name="data" type="octet" safearray="yes" dir="return">
<desc>
Buffer for retrieving the actual output. A data size of 0 means end of file
if the requested size was not 0. This is the unprocessed
@@ -8247,7 +8839,7 @@
</desc>
<param name="pid" type="unsigned long" dir="in">
<desc>
- Process id returned by earlier executeProcess() call.
+ Process id returned by earlier <link to="#executeProcess"/> call.
</desc>
</param>
<param name="exitcode" type="unsigned long" dir="out">
@@ -8261,13 +8853,54 @@
must be set to 0.
</desc>
</param>
- <param name="reason" type="unsigned long" dir="return">
+ <param name="reason" type="ExecuteProcessStatus" dir="return">
<desc>
The current process status.
</desc>
</param>
</method>
+ <method name="copyFromGuest">
+ <desc>
+ Copies files/directories from guest to the host.
+
+ <result name="VBOX_E_IPRT_ERROR">
+ Error while copying.
+ </result>
+
+ </desc>
+ <param name="source" type="wstring" dir="in">
+ <desc>
+ Source file on the guest to copy.
+ </desc>
+ </param>
+ <param name="dest" type="wstring" dir="in">
+ <desc>
+ Destination path on the host.
+ </desc>
+ </param>
+ <param name="userName" type="wstring" dir="in">
+ <desc>
+ User name under which the copy command will be executed; the
+ user has to exist and have the appropriate rights to read from
+ the source path.
+ </desc>
+ </param>
+ <param name="password" type="wstring" dir="in">
+ <desc>
+ Password of the user account specified.
+ </desc>
+ </param>
+ <param name="flags" type="unsigned long" dir="in">
+ <desc>
+ <link to="CopyFileFlag"/> flags. Not used at the moment and should be set to 0.
+ </desc>
+ </param>
+ <param name="progress" type="IProgress" dir="return">
+ <desc>Progress object to track the operation completion.</desc>
+ </param>
+ </method>
+
<method name="copyToGuest">
<desc>
Copies files/directories from host to the guest.
@@ -8309,7 +8942,23 @@
</param>
</method>
- <method name="createDirectory">
+ <method name="directoryClose">
+ <desc>
+ Closes a formerly opened guest directory.
+
+ <result name="VBOX_E_IPRT_ERROR">
+ Error while closing directory.
+ </result>
+
+ </desc>
+ <param name="handle" type="unsigned long" dir="in">
+ <desc>
+ Handle of opened directory to close.
+ </desc>
+ </param>
+ </method>
+
+ <method name="directoryCreate">
<desc>
Creates a directory on the guest.
@@ -8342,11 +8991,139 @@
</param>
<param name="flags" type="unsigned long" dir="in">
<desc>
- <link to="CreateDirectoryFlag"/> flags.
+ <link to="DirectoryCreateFlag"/> flags.
</desc>
</param>
- <param name="progress" type="IProgress" dir="return">
- <desc>Progress object to track the operation completion.</desc>
+ </method>
+
+ <method name="directoryOpen">
+ <desc>
+ Opens a directory on the guest.
+
+ <result name="VBOX_E_IPRT_ERROR">
+ Error while opening / reading directory.
+ </result>
+
+ </desc>
+ <param name="directory" type="wstring" dir="in">
+ <desc>
+ Directory to read.
+ </desc>
+ </param>
+ <param name="filter" type="wstring" dir="in">
+ <desc>
+ Directory filter (DOS style wildcards). Set to empty
+ string if no filter required.
+ </desc>
+ </param>
+ <param name="flags" type="unsigned long" dir="in">
+ <desc>
+ <link to="DirectoryOpenFlag"/> flags.
+ </desc>
+ </param>
+ <param name="userName" type="wstring" dir="in">
+ <desc>
+ User name under which the directory reading will be performed; the
+ user has to exist and have the appropriate rights to access / read the
+ desired directory.
+ </desc>
+ </param>
+ <param name="password" type="wstring" dir="in">
+ <desc>
+ Password of the user account specified.
+ </desc>
+ </param>
+ <param name="handle" type="unsigned long" dir="return">
+ <desc>
+ Handle of opened directory returned by openDirectory.
+ </desc>
+ </param>
+ </method>
+
+ <method name="directoryRead">
+ <desc>
+ Reads the next directory entry of an opened guest directory.
+
+ <result name="VBOX_E_IPRT_ERROR">
+ Error while opening / reading directory.
+ </result>
+
+ </desc>
+ <param name="handle" type="unsigned long" dir="in">
+ <desc>
+ Handle of opened directory returned by openDirectory.
+ </desc>
+ </param>
+ <param name="entry" type="IGuestDirEntry" dir="return">
+ <desc>
+ Information about next directory entry on success.
+ </desc>
+ </param>
+ </method>
+
+ <method name="fileExists">
+ <desc>
+ Checks if the specified file name exists and is a regular file.
+
+ <result name="VBOX_E_IPRT_ERROR">
+ Error while looking up information.
+ </result>
+
+ </desc>
+ <param name="file" type="wstring" dir="in">
+ <desc>
+ Full path of file to check.
+ </desc>
+ </param>
+ <param name="userName" type="wstring" dir="in">
+ <desc>
+ User name under which the lookup will be performed; the
+ user has to exist and have the appropriate rights to access / read the
+ desired directory.
+ </desc>
+ </param>
+ <param name="password" type="wstring" dir="in">
+ <desc>
+ Password of the user account specified.
+ </desc>
+ </param>
+ <param name="exists" type="boolean" dir="return">
+ <desc>
+ True if it's a regular file, false if it isn't (or doesn't exist).
+ </desc>
+ </param>
+ </method>
+
+ <method name="fileQuerySize">
+ <desc>
+ Queries the size of a file, given the path to it.
+
+ <result name="VBOX_E_IPRT_ERROR">
+ Error while looking up information.
+ </result>
+
+ </desc>
+ <param name="file" type="wstring" dir="in">
+ <desc>
+ Full path of file to query file size for.
+ </desc>
+ </param>
+ <param name="userName" type="wstring" dir="in">
+ <desc>
+ User name under which the lookup will be performed; the
+ user has to exist and have the appropriate rights to access / read the
+ desired directory.
+ </desc>
+ </param>
+ <param name="password" type="wstring" dir="in">
+ <desc>
+ Password of the user account specified.
+ </desc>
+ </param>
+ <param name="size" type="long long" dir="return">
+ <desc>
+ Size (in bytes) of file specified.
+ </desc>
</param>
</method>
@@ -8361,7 +9138,7 @@
</desc>
<param name="pid" type="unsigned long" dir="in">
<desc>
- Process id returned by earlier executeProcess() call.
+ Process id returned by earlier <link to="#executeProcess"/> call.
</desc>
</param>
<param name="flags" type="unsigned long" dir="in">
@@ -8422,7 +9199,7 @@
<interface
name="IProgress" extends="$unknown"
- uuid="A163C98F-8635-4AA8-B770-A9941737F3EF"
+ uuid="c20238e4-3221-4d3f-8891-81ce92d9f913"
wsmap="managed"
>
<desc>
@@ -8618,6 +9395,34 @@
</param>
</method>
+ <method name="waitForAsyncProgressCompletion">
+ <desc>
+ Waits until the other task is completed (including all
+ sub-operations) and forward all changes from the other progress to
+ this progress. This means sub-operation number, description, percent
+ and so on.
+
+ You have to take care on setting up at least the same count on
+ sub-operations in this progress object like there are in the other
+ progress object.
+
+ If the other progress object supports cancel and this object gets any
+ cancel request (when here enabled as well), it will be forwarded to
+ the other progress object.
+
+ If there is an error in the other progress, this error isn't
+ automatically transfered to this progress object. So you have to
+ check any operation error within the other progress object, after
+ this method returns.
+ </desc>
+
+ <param name="pProgressAsync" type="IProgress" dir="in">
+ <desc>
+ The progress object of the asynchrony process.
+ </desc>
+ </param>
+ </method>
+
<method name="cancel">
<desc>
Cancels the task.
@@ -8641,7 +9446,7 @@
<interface
name="ISnapshot" extends="$unknown"
- uuid="1a2d0551-58a4-4107-857e-ef414fc42ffc"
+ uuid="0472823b-c6e7-472a-8e9f-d732e86b8463"
wsmap="managed"
>
<desc>
@@ -8789,6 +9594,16 @@
</desc>
</attribute>
+ <method name="getChildrenCount" const="yes">
+ <desc>
+ Returns the number of direct childrens of this snapshot.
+ </desc>
+ <param name="childrenCount" type="unsigned long" dir="return">
+ <desc>
+ </desc>
+ </param>
+ </method>
+
</interface>
@@ -8803,7 +9618,7 @@
>
<desc>
Virtual medium state.
- <see>IMedium</see>
+ <see><link to="IMedium"/></see>
</desc>
<const name="NotCreated" value="0">
@@ -8909,7 +9724,7 @@
>
<desc>
Virtual medium image variant. More than one flag may be set.
- <see>IMedium</see>
+ <see><link to="IMedium"/></see>
</desc>
<const name="Standard" value="0">
@@ -8947,7 +9762,7 @@
<interface
name="IMediumAttachment" extends="$unknown"
- uuid="aa4b4840-934f-454d-9a28-23e8f4235edf"
+ uuid="b5dfbb8c-7498-48c3-bf10-78fc60f064e1"
wsmap="struct"
>
<desc>
@@ -9160,6 +9975,19 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<desc>Pass I/O requests through to a device on the host.</desc>
</attribute>
+ <attribute name="temporaryEject" type="boolean" readonly="yes">
+ <desc>Whether guest-triggered eject results in unmounting the medium.</desc>
+ </attribute>
+
+ <attribute name="isEjected" type="boolean" readonly="yes">
+ <desc>Signals that the removable medium has been ejected. This is not
+ necessarily equivalent to having a @c null medium association.</desc>
+ </attribute>
+
+ <attribute name="nonRotational" type="boolean" readonly="yes">
+ <desc>Whether the associated medium is non-rotational.</desc>
+ </attribute>
+
<attribute name="bandwidthGroup" type="IBandwidthGroup" readonly="yes">
<desc>The bandwidth group this medium attachment is assigned to.</desc>
</attribute>
@@ -9168,7 +9996,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<interface
name="IMedium" extends="$unknown"
- uuid="9edda847-1279-4b0a-9af7-9d66251ccc18"
+ uuid="53f9cc0c-e0fd-40a5-a404-a7a5272082cd"
wsmap="managed"
>
<desc>
@@ -9251,7 +10079,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
See <link to="IVirtualBox::openMedium" /> for more information.
- Media are removed from media registries by the <link to="#close"/>,
+ Media are removed from media registries by the <link to="IMedium::close"/>,
<link to="#deleteStorage"/> and <link to="#mergeTo"/> methods.
<h3>Accessibility checks</h3>
@@ -9501,6 +10329,16 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</desc>
</attribute>
+ <attribute name="allowedTypes" type="MediumType" safearray="yes" readonly="yes">
+ <desc>
+ Returns which medium types can selected for this medium.
+
+ <result name="E_NOTIMPL">
+ This attribute is not implemented at the moment.
+ </result>
+ </desc>
+ </attribute>
+
<attribute name="parent" type="IMedium" readonly="yes">
<desc>
Parent of this medium (the medium this medium is directly based
@@ -9929,17 +10767,17 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</desc>
</method>
- <!-- storage methods -->
+ <!-- property methods -->
- <method name="getProperty">
+ <method name="getProperty" const="yes">
<desc>
Returns the value of the custom medium property with the given name.
The list of all properties supported by the given medium format can
be obtained with <link to="IMediumFormat::describeProperties"/>.
- Note that if this method returns an empty string in @a value, the
- requested property is supported but currently not assigned any value.
+ <note>If this method returns an empty string in @a value, the requested
+ property is supported but currently not assigned any value.</note>
<result name="VBOX_E_OBJECT_NOT_FOUND">
Requested property does not exist (not supported by the format).
@@ -9961,10 +10799,10 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
The list of all properties supported by the given medium format can
be obtained with <link to="IMediumFormat::describeProperties"/>.
- Note that setting the property value to @c null or an empty string is
+ <note>Setting the property value to @c null or an empty string is
equivalent to deleting the existing value. A default value (if it is
defined for this property) will be used by the format backend in this
- case.
+ case.</note>
<result name="VBOX_E_OBJECT_NOT_FOUND">
Requested property does not exist (not supported by the format).
@@ -9979,28 +10817,27 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</param>
</method>
- <method name="getProperties">
+ <method name="getProperties" const="yes">
<desc>
Returns values for a group of properties in one call.
The names of the properties to get are specified using the @a names
argument which is a list of comma-separated property names or
- an empty string if all properties are to be returned. Note that currently
- the value of this argument is ignored and the method always returns all
- existing properties.
+ an empty string if all properties are to be returned.
+ <note>Currently the value of this argument is ignored and the method
+ always returns all existing properties.</note>
The list of all properties supported by the given medium format can
be obtained with <link to="IMediumFormat::describeProperties"/>.
The method returns two arrays, the array of property names corresponding
to the @a names argument and the current values of these properties.
- Both arrays have the same number of elements with each elemend at the
+ Both arrays have the same number of elements with each element at the
given index in the first array corresponds to an element at the same
index in the second array.
- Note that for properties that do not have assigned values,
- an empty string is returned at the appropriate index in the
- @a returnValues array.
+ For properties that do not have assigned values, an empty string is
+ returned at the appropriate index in the @a returnValues array.
</desc>
<param name="names" type="wstring" dir="in">
@@ -10022,7 +10859,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
The names of the properties to set are passed in the @a names
array along with the new values for them in the @a values array. Both
- arrays have the same number of elements with each elemend at the given
+ arrays have the same number of elements with each element at the given
index in the first array corresponding to an element at the same index
in the second array.
@@ -10031,16 +10868,14 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
from the @a names array.
Using this method over <link to="#setProperty"/> is preferred if you
- need to set several properties at once since it will result into less
- IPC calls.
+ need to set several properties at once since it is more efficient.
The list of all properties supported by the given medium format can
be obtained with <link to="IMediumFormat::describeProperties"/>.
- Note that setting the property value to @c null or an empty string is
- equivalent to deleting the existing value. A default value (if it is
- defined for this property) will be used by the format backend in this
- case.
+ Setting the property value to @c null or an empty string is equivalent
+ to deleting the existing value. A default value (if it is defined for
+ this property) will be used by the format backend in this case.
</desc>
<param name="names" type="wstring" safearray="yes" dir="in">
<desc>Names of properties to set.</desc>
@@ -10108,7 +10943,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<link to="MediumState_NotCreated"/> and you will be able to use one of
the storage creation methods to create it again.
- <see>#close()</see>
+ <see><link to="#close"/></see>
<result name="VBOX_E_OBJECT_IN_USE">
Medium is attached to a virtual machine.
@@ -10271,7 +11106,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
an arbitrary medium for this parameter, including the parent of the
medium which is being cloned. Even cloning to a child of the source
medium is possible. Note that when cloning to an existing image, the
- @a parent irgument is ignored.
+ @a parent argument is ignored.
After the returned progress object reports that the operation is
successfully complete, the target medium gets remembered by this
@@ -10493,7 +11328,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<interface
name="IMediumFormat" extends="$unknown"
- uuid="4e9a873f-0599-434a-8345-619ef3fb3111"
+ uuid="9bd5b655-ea47-4637-99f3-aad0948be35b"
wsmap="managed"
>
<desc>
@@ -10511,7 +11346,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
The list of all supported medium formats can be obtained using
<link to="ISystemProperties::mediumFormats"/>.
- <see>IMedium</see>
+ <see><link to="IMedium"/></see>
</desc>
<attribute name="id" type="wstring" readonly="yes">
@@ -10560,7 +11395,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
Note that some backends do not work on files, so this array may be
empty.
- <see>IMediumFormat::capabilities</see>
+ <see><link to="IMediumFormat::capabilities"/></see>
</desc>
<param name="extensions" type="wstring" safearray="yes" dir="out">
<desc>The array of supported extensions.</desc>
@@ -10570,7 +11405,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</param>
</method>
- <method name="describeProperties">
+ <method name="describeProperties" const="yes">
<desc>
Returns several arrays describing the properties supported by this
format.
@@ -10583,8 +11418,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<link to="MediumFormatCapabilities_Properties"/> flag is set.
All arguments must be non-@c null.
- <see>DataType</see>
- <see>DataFlags</see>
+ <see><link to="DataType"/>, <link to="DataFlags"/></see>
</desc>
<param name="names" type="wstring" safearray="yes" dir="out">
@@ -11353,7 +12187,8 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
integration) mode.
<note>
Calling this method has no effect if <link
- to="IGuest::supportsSeamless"/> returns @c false.
+ to="IGuest::getFacilityStatus"/> with facility @c Seamless
+ does not return @c Active.
</note>
</desc>
<param name="enabled" type="boolean" dir="in"/>
@@ -11365,9 +12200,11 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
32-bpp buffer allocated by the caller and pointed to by @a address.
A pixel consists of 4 bytes in order: B, G, R, 0.
- <note>This API can be used only by the COM/XPCOM C++ API as it
- requires pointer support. Use <link to="#takeScreenShotToArray" />
- with other language bindings.
+ <note>This API can be used only locally by a VM process through the
+ COM/XPCOM C++ API as it requires pointer support. It is not
+ available for scripting langages, Java or any webservice clients.
+ Unless you are writing a new VM frontend use
+ <link to="#takeScreenShotToArray" />.
</note>
<result name="E_NOTIMPL">
@@ -11545,7 +12382,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<enum
name="NetworkAttachmentType"
- uuid="44bce1ee-99f7-4e8e-89fc-80597fd9eeaf"
+ uuid="2ac4bc71-6b82-417a-acd1-f7426d2570d6"
>
<desc>
Network attachment type.
@@ -11558,7 +12395,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<const name="Bridged" value="2"/>
<const name="Internal" value="3"/>
<const name="HostOnly" value="4"/>
- <const name="VDE" value="5"/>
+ <const name="Generic" value="5"/>
</enum>
<enum
@@ -11592,9 +12429,34 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</const>
</enum>
+ <enum
+ name="NetworkAdapterPromiscModePolicy"
+ uuid="c963768a-376f-4c85-8d84-d8ced4b7269e"
+ >
+ <desc>
+ The promiscuous mode policy of an interface.
+ </desc>
+
+ <const name="Deny" value="1">
+ <desc>Deny promiscuous mode requests.</desc>
+ </const>
+ <const name="AllowNetwork" value="2">
+ <desc>
+ Allow promicuous mode, but restrict the scope it to the internal
+ network so that it only applies to other VMs.
+ </desc>
+ </const>
+ <const name="AllowAll" value="3">
+ <desc>
+ Allow promicuous mode, include unrelated traffic going over the wire
+ and internally on the host.
+ </desc>
+ </const>
+ </enum>
+
<interface
name="INetworkAdapter" extends="$unknown"
- uuid="9bf58a46-c3f7-4f31-80fa-dde9a5dc0b7b"
+ uuid="8b2e705c-0547-4008-b7bc-788757346092"
wsmap="managed"
>
<desc>
@@ -11641,11 +12503,21 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</desc>
</attribute>
- <attribute name="attachmentType" type="NetworkAttachmentType" readonly="yes"/>
+ <attribute name="attachmentType" type="NetworkAttachmentType">
+ <desc>
+ Sets/Gets network attachment type of this network adapter.
+ </desc>
+ </attribute>
- <attribute name="hostInterface" type="wstring">
+ <attribute name="bridgedInterface" type="wstring">
<desc>
- Name of the host network interface the VM is attached to.
+ Name of the network interface the VM should be bridged to.
+ </desc>
+ </attribute>
+
+ <attribute name="hostOnlyInterface" type="wstring">
+ <desc>
+ Name of the host only network interface the VM is attached to.
</desc>
</attribute>
@@ -11661,9 +12533,9 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</desc>
</attribute>
- <attribute name="VDENetwork" type="wstring">
+ <attribute name="genericDriver" type="wstring">
<desc>
- Name of the VDE switch the VM is attached to.
+ Name of the driver to use for the "Generic" network attachment type.
</desc>
</attribute>
@@ -11680,6 +12552,13 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</desc>
</attribute>
+ <attribute name="promiscModePolicy" type="NetworkAdapterPromiscModePolicy">
+ <desc>
+ The promiscuous mode policy of the network adapter when attached to an
+ internal network, host only network or a bridge.
+ </desc>
+ </attribute>
+
<attribute name="traceEnabled" type="boolean">
<desc>
Flag whether network traffic from/to the network card should be traced.
@@ -11698,7 +12577,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<desc>
Points to the NAT engine which handles the network address translation
for this interface. This is active only when the interface actually uses
- NAT (see <link to="#attachToNAT" />).
+ NAT.
</desc>
</attribute>
@@ -11709,48 +12588,75 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</desc>
</attribute>
- <attribute name="bandwidthLimit" type="unsigned long">
- <desc>
- Maximum throughput allowed for this network adapter, in units of 1 mbps.
- A zero value means uncapped/unlimited.
- </desc>
+ <attribute name="bandwidthGroup" type="IBandwidthGroup">
+ <desc>The bandwidth group this network adapter is assigned to.</desc>
</attribute>
- <method name="attachToNAT">
- <desc>
- Attach the network adapter to the Network Address Translation (NAT) interface.
- </desc>
- </method>
+ <!-- property methods -->
- <method name="attachToBridgedInterface">
+ <method name="getProperty" const="yes">
<desc>
- Attach the network adapter to a bridged host interface.
- </desc>
- </method>
+ Returns the value of the network attachment property with the given name.
- <method name="attachToInternalNetwork">
- <desc>
- Attach the network adapter to an internal network.
- </desc>
- </method>
+ If the requested data @a key does not exist, this function will
+ succeed and return an empty string in the @a value argument.
- <method name="attachToHostOnlyInterface">
- <desc>
- Attach the network adapter to the host-only network.
+ <result name="E_INVALIDARG">@a name is @c null or empty.</result>
</desc>
+ <param name="key" type="wstring" dir="in">
+ <desc>Name of the property to get.</desc>
+ </param>
+ <param name="value" type="wstring" dir="return">
+ <desc>Current property value.</desc>
+ </param>
</method>
- <method name="attachToVDE">
+ <method name="setProperty">
<desc>
- Attach the network adapter to a VDE network.
+ Sets the value of the network attachment property with the given name.
+
+ Setting the property value to @c null or an empty string is equivalent
+ to deleting the existing value.
+
+ <result name="E_INVALIDARG">@a name is @c null or empty.</result>
</desc>
+ <param name="key" type="wstring" dir="in">
+ <desc>Name of the property to set.</desc>
+ </param>
+ <param name="value" type="wstring" dir="in">
+ <desc>Property value to set.</desc>
+ </param>
</method>
- <method name="detach">
+ <method name="getProperties" const="yes">
<desc>
- Detach the network adapter
+ Returns values for a group of properties in one call.
+
+ The names of the properties to get are specified using the @a names
+ argument which is a list of comma-separated property names or
+ an empty string if all properties are to be returned.
+ <note>Currently the value of this argument is ignored and the method
+ always returns all existing properties.</note>
+
+ The method returns two arrays, the array of property names corresponding
+ to the @a names argument and the current values of these properties.
+ Both arrays have the same number of elements with each element at the
+ given index in the first array corresponds to an element at the same
+ index in the second array.
</desc>
+ <param name="names" type="wstring" dir="in">
+ <desc>
+ Names of properties to get.
+ </desc>
+ </param>
+ <param name="returnNames" type="wstring" safearray="yes" dir="out">
+ <desc>Names of returned properties.</desc>
+ </param>
+ <param name="returnValues" type="wstring" safearray="yes" dir="return">
+ <desc>Values of returned properties.</desc>
+ </param>
</method>
+
</interface>
@@ -11809,7 +12715,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
detect the serial port, but all port write operations will be discarded
and all port read operations will return no data.
- <see>IMachine::getSerialPort</see>
+ <see><link to="IMachine::getSerialPort"/></see>
</desc>
<attribute name="slot" type="unsigned long" readonly="yes">
@@ -11888,7 +12794,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
IRQ number that will be reported to the guest operating system and used
to operate the given parallel port from within the virtual machine.
- <see>IMachine::getParallelPort</see>
+ <see><link to="IMachine::getParallelPort"/></see>
</desc>
<attribute name="slot" type="unsigned long" readonly="yes">
@@ -11917,7 +12823,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<attribute name="path" type="wstring">
<desc>
Host parallel device name. If this parallel port is enabled, setting a
- @c null or an empty string as this attribute's value will result into
+ @c null or an empty string as this attribute's value will result in
an error.
</desc>
</attribute>
@@ -12425,7 +13331,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
device is automatically captured (attached to) the virtual USB
controller of this machine.
- <see>IUSBDeviceFilter, ::IUSBController</see>
+ <see><link to="IUSBDeviceFilter"/>, <link to="IUSBController"/></see>
</desc>
</attribute>
@@ -12442,7 +13348,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
The virtual machine is not mutable.
</result>
- <see>#deviceFilters</see>
+ <see><link to="#deviceFilters"/></see>
</desc>
<param name="name" type="wstring" dir="in">
<desc>
@@ -12480,7 +13386,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
USB device filter already in list.
</result>
- <see>#deviceFilters</see>
+ <see><link to="#deviceFilters"/></see>
</desc>
<param name="position" type="unsigned long" dir="in">
<desc>Position to insert the filter to.</desc>
@@ -12499,7 +13405,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
position equal to or greater than the number of elements in
the list will produce an error.
- <see>#deviceFilters</see>
+ <see><link to="#deviceFilters"/></see>
<result name="VBOX_E_INVALID_VM_STATE">
Virtual machine is not mutable.
@@ -12684,7 +13590,8 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<i>any match</i> no matter what string expression is specified.
</note>
- <see>IUSBController::deviceFilters, IHostUSBDeviceFilter</see>
+ <see><link to="IUSBController::deviceFilters"/>,
+ <link to="IHostUSBDeviceFilter"/></see>
</desc>
<attribute name="name" type="wstring">
@@ -12820,7 +13727,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
device state is USBDeviceState_Held.
</note>
- <see>IHostUSBDevice, IHostUSBDeviceFilter</see>
+ <see><link to="IHostUSBDevice"/>, <link to="IHostUSBDeviceFilter"/></see>
</desc>
<const name="NotSupported" value="0">
@@ -12872,7 +13779,8 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<link to="#state"/> property that holds the current state of the USB
device.
- <see>IHost::USBDevices, IHost::USBDeviceFilters</see>
+ <see><link to="IHost::USBDevices"/>,
+ <link to="IHost::USBDeviceFilters"/></see>
</desc>
<attribute name="state" type="USBDeviceState" readonly="yes">
@@ -12897,7 +13805,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
>
<desc>
Actions for host USB device filters.
- <see>IHostUSBDeviceFilter, USBDeviceState</see>
+ <see><link to="IHostUSBDeviceFilter"/>, <link to="USBDeviceState"/></see>
</desc>
<const name="Null" value="0">
@@ -12931,7 +13839,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<link to="IUSBController::deviceFilters">machine USB filters</link>.
</note>
- <see>IHost::USBDeviceFilters</see>
+ <see><link to="IHost::USBDeviceFilters"/></see>
</desc>
<attribute name="action" type="USBDeviceFilterAction">
@@ -13050,7 +13958,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<interface
name="IVRDEServer" extends="$unknown"
- uuid="be24e0db-e1d6-4d58-b85b-21053d1511b4"
+ uuid="d38de40a-c2c1-4e95-b5a4-167b05f5694c"
wsmap="managed"
>
<attribute name="enabled" type="boolean">
@@ -13087,7 +13995,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</desc>
</attribute>
- <attribute name="AuthLibrary" type="wstring">
+ <attribute name="authLibrary" type="wstring">
<desc>
Library used for authentication of RDP clients by this VM. Overrides
<link to="ISystemProperties::VRDEAuthLibrary"/>.
@@ -13116,7 +14024,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</param>
</method>
- <method name="getVRDEProperty">
+ <method name="getVRDEProperty" const="yes">
<desc>
Returns a VRDE specific property string.
@@ -13248,7 +14156,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<interface
name="IInternalSessionControl" extends="$unknown"
- uuid="a2fbf834-149d-41da-ae52-0dc3b0f032b3"
+ uuid="0bdda5da-67c8-47be-a610-b83a7fa3e8b6"
internal="yes"
wsmap="suppress"
>
@@ -13412,8 +14320,34 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</desc>
- <param name="mediumAttachment" type="IMediumAttachment" dir="in"/>
- <param name="force" type="boolean" dir="in"/>
+ <param name="mediumAttachment" type="IMediumAttachment" dir="in">
+ <desc>The medium attachment which changed.</desc>
+ </param>
+ <param name="force" type="boolean" dir="in">
+ <desc>If the medium change was forced.</desc>
+ </param>
+ </method>
+
+ <method name="onStorageDeviceChange">
+ <desc>
+ Triggered when attached storage devices of the
+ associated virtual machine have changed.
+
+ <result name="VBOX_E_INVALID_VM_STATE">
+ Session state prevents operation.
+ </result>
+ <result name="VBOX_E_INVALID_OBJECT_STATE">
+ Session type prevents operation.
+ </result>
+
+ </desc>
+
+ <param name="mediumAttachment" type="IMediumAttachment" dir="in">
+ <desc>The medium attachment which changed.</desc>
+ </param>
+ <param name="remove" type="boolean" dir="in">
+ <desc>TRUE if the device is removed, FALSE if it was added.</desc>
+ </param>
</method>
<method name="onCPUChange">
@@ -13583,7 +14517,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<param name="retFlags" type="wstring" dir="out"/>
</method>
- <method name="enumerateGuestProperties">
+ <method name="enumerateGuestProperties" const="yes">
<desc>
Return a list of the guest properties matching a set of patterns along
with their values, time stamps and flags.
@@ -14098,7 +15032,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
Returns a managed object reference to the internal ISession object that was created
for this web service session when the client logged on.
- <see>ISession</see>
+ <see><link to="ISession"/></see>
</desc>
<param name="refIVirtualBox" type="IVirtualBox" dir="in"/>
<param name="return" type="ISession" dir="return"/>
@@ -14242,6 +15176,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<li>CPU/Load</li>
<li>CPU/MHz</li>
<li>RAM/Usage</li>
+ <li>RAM/VMM</li>
</ul>
The general sequence for collecting and retrieving the metrics is:
@@ -14823,9 +15758,8 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
>
<desc>
Extension pack file (aka tarball, .vbox-extpack) representation returned
- by IExtPackManager::openExtPackFile. This provides the base extension
- pack information with the addition of the file name. It also provides an
- alternative to IExtPackManager::install.
+ by <link to="IExtPackManager::openExtPackFile"/>. This provides the base
+ extension pack information with the addition of the file name.
</desc>
<attribute name="filePath" type="wstring" readonly="yes">
<desc>
@@ -14858,7 +15792,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<interface
name="IExtPackManager" extends="$unknown"
- uuid="2451b1ba-ab1c-42fb-b453-c58433bea8c7"
+ uuid="3295e6ce-b051-47b2-9514-2c588bfe7554"
wsmap="suppress"
>
<desc>
@@ -14930,7 +15864,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<desc>Cleans up failed installs and uninstalls</desc>
</method>
- <method name="QueryAllPlugInsForFrontend">
+ <method name="queryAllPlugInsForFrontend">
<desc>
Gets the path to all the plug-in modules for a given frontend.
@@ -14945,12 +15879,14 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</param>
</method>
- <method name="IsExtPackUsable">
+ <method name="isExtPackUsable">
<desc>Check if the given extension pack is loaded and usable.</desc>
<param name="name" type="wstring" dir="in">
<desc>The name of the extension pack to check for.</desc>
</param>
- <param name="usable" type="boolean" dir="return"/>
+ <param name="usable" type="boolean" dir="return">
+ <desc>Is the given extension pack loaded and usable.</desc>
+ </param>
</method>
</interface>
@@ -15023,7 +15959,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
-->
<interface
name="IBandwidthControl" extends="$unknown"
- uuid="d0a24db0-f756-11df-98cf-0800200c9a66"
+ uuid="e2eb3930-d2f4-4f87-be17-0707e30f019f"
wsmap="managed"
>
<desc>
@@ -15037,7 +15973,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</desc>
</attribute>
- <method name="CreateBandwidthGroup">
+ <method name="createBandwidthGroup">
<desc>
Creates a new bandwidth group.
</desc>
@@ -15054,7 +15990,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</param>
</method>
- <method name="DeleteBandwidthGroup">
+ <method name="deleteBandwidthGroup">
<desc>
Deletes a new bandwidth group.
</desc>
@@ -15064,7 +16000,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</param>
</method>
- <method name="GetBandwidthGroup" const="yes">
+ <method name="getBandwidthGroup" const="yes">
<desc>
Get a bandwidth group by name.
</desc>
@@ -15077,7 +16013,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</param>
</method>
- <method name="GetAllBandwidthGroups" const="yes">
+ <method name="getAllBandwidthGroups" const="yes">
<desc>
Get all managed bandwidth groups.
</desc>
@@ -15133,7 +16069,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
-->
<enum
name="VBoxEventType"
- uuid="e71c487f-755e-46e9-a476-dd6a5d134597"
+ uuid="cce48db6-8561-479d-8d46-1358bab45d4e"
>
<desc>
@@ -15151,28 +16087,28 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<desc>
Wildcard for all events.
Events of this type are never delivered, and only used in
- registerListener() call to simplify registration.
+ <link to="IEventSource::registerListener"/> call to simplify registration.
</desc>
</const>
<const name="Vetoable" value="2">
<desc>
Wildcard for all vetoable events. Events of this type are never delivered, and only
- used in registerListener() call to simplify registration.
+ used in <link to="IEventSource::registerListener"/> call to simplify registration.
</desc>
</const>
<const name="MachineEvent" value="3">
<desc>
Wildcard for all machine events. Events of this type are never delivered, and only used in
- registerListener() call to simplify registration.
+ <link to="IEventSource::registerListener"/> call to simplify registration.
</desc>
</const>
<const name="SnapshotEvent" value="4">
<desc>
Wildcard for all snapshot events. Events of this type are never delivered, and only used in
- registerListener() call to simplify registration.
+ <link to="IEventSource::registerListener"/> call to simplify registration.
</desc>
</const>
@@ -15180,7 +16116,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<desc>
Wildcard for all input device (keyboard, mouse) events.
Events of this type are never delivered, and only used in
- registerListener() call to simplify registration.
+ <link to="IEventSource::registerListener"/> call to simplify registration.
</desc>
</const>
@@ -15386,9 +16322,14 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
See <link to="IGuestMonitorChangedEvent">IGuestMonitorChangedEvent</link>.
</desc>
</const>
+ <const name="OnStorageDeviceChanged" value="71">
+ <desc>
+ See <link to="IStorageDeviceChangedEvent">IStorageDeviceChangedEvent</link>.
+ </desc>
+ </const>
<!-- Last event marker -->
- <const name="Last" value="71">
+ <const name="Last" value="72">
<desc>
Must be last event, used for iterations and structures relying on numerical event values.
</desc>
@@ -15422,14 +16363,18 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<desc>
Creates an aggregator event source, collecting events from multiple sources.
This way a single listener can listen for events coming from multiple sources,
- using a single blocking getEvent() on the returned aggregator.
+ using a single blocking <link to="#getEvent"/> on the returned aggregator.
</desc>
<param name="subordinates" type="IEventSource" dir="in" safearray="yes">
<desc>
Subordinate event source this one aggregatres.
</desc>
</param>
- <param name="result" type="IEventSource" dir="return"/>
+ <param name="result" type="IEventSource" dir="return">
+ <desc>
+ Event source aggregating passed sources.
+ </desc>
+ </param>
</method>
<method name="registerListener">
@@ -15548,10 +16493,12 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<method name="handleEvent">
<desc>
- Handle event callback for active listeners. It is not called for passive listeners. After
- calling handleEvent() on all active listeners and having received acknowledgement from all
- passive listeners via IEventSource::eventProcessed(), the event is marked as processed and
- IEvent::waitProcessed() will return immediately.
+ Handle event callback for active listeners. It is not called for
+ passive listeners. After calling <link to="#handleEvent"/> on all active listeners
+ and having received acknowledgement from all passive listeners via
+ <link to="IEventSource::eventProcessed"/>, the event is marked as
+ processed and <link to="IEvent::waitProcessed"/> will return
+ immediately.
</desc>
<param name="event" type="IEvent" dir="in">
<desc>Event available.</desc>
@@ -15621,7 +16568,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
an object implementing the <link to="IEventListener" /> interface must be provided.
For active listeners, such an object is typically created by the consumer, while for
passive listeners <link to="IEventSource::createListener" /> should be used. Please
- note that a listener created with @c createListener() must not be used as an active listener.
+ note that a listener created with <link to="IEventSource::createListener"/> must not be used as an active listener.
Once created, the listener must be registered to listen for the desired events
(see <link to="IEventSource::registerListener" />), providing an array of
@@ -15653,8 +16600,8 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<attribute name="waitable" readonly="yes" type="boolean">
<desc>
- If we can wait for this event being processed. If false, waitProcessed() returns immediately,
- and setProcessed() doesn't make sense. Non-waitable events are generally better performing,
+ If we can wait for this event being processed. If false, <link to="#waitProcessed"/> returns immediately,
+ and <link to="#setProcessed"/> doesn't make sense. Non-waitable events are generally better performing,
as no additional overhead associated with waitability imposed.
Waitable events are needed when one need to be able to wait for particular event processed,
for example for vetoable changes, or if event refers to some resource which need to be kept immutable
@@ -15733,12 +16680,19 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<interface
name="IMachineDataChangedEvent" extends="IMachineEvent"
- uuid="6AA70A6C-0DCA-4810-8C5C-457B278E3D49"
+ uuid="abe94809-2e88-4436-83d7-50f3e64d0503"
wsmap="managed" autogen="VBoxEvent" id="OnMachineDataChanged"
>
<desc>
Any of the settings of the given machine has changed.
</desc>
+
+ <attribute name="temporary" readonly="yes" type="boolean">
+ <desc>@c true if the settings change is temporary. All permanent
+ settings changes will trigger an event, and only temporary settings
+ changes for running VMs will trigger an event. Note: sending events
+ for temporary changes is NOT IMPLEMENTED.</desc>
+ </attribute>
</interface>
<interface
@@ -15792,7 +16746,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
>
<desc>
The state of the session for the given machine was changed.
- <see>IMachine::sessionState</see>
+ <see><link to="IMachine::sessionState"/></see>
</desc>
<attribute name="state" type="SessionState" readonly="yes">
@@ -15851,7 +16805,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
>
<desc>
A new snapshot of the machine has been taken.
- <see>ISnapshot</see>
+ <see><link to="ISnapshot"/></see>
</desc>
</interface>
@@ -15869,7 +16823,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
attempt to call its methods will return an error).
</note>
- <see>ISnapshot</see>
+ <see><link to="ISnapshot"/></see>
</desc>
</interface>
@@ -15880,7 +16834,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
>
<desc>
Snapshot properties (name and/or description) have been changed.
- <see>ISnapshot</see>
+ <see><link to="ISnapshot"/></see>
</desc>
</interface>
@@ -16630,16 +17584,21 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<interface
name="IHostPciDevicePlugEvent" extends="IMachineEvent"
waitable="yes"
- uuid="EDD4782B-DB74-43A0-B724-2BAA36F039CC"
+ uuid="9cebfc27-c579-4965-8eb7-d31794cd7dcf"
wsmap="managed" autogen="VBoxEvent" id="OnHostPciDevicePlug"
>
<desc>
- Notification when host PCI device is plugged/unplugged.
+ Notification when host PCI device is plugged/unplugged. Plugging
+ usually takes place on VM startup, unplug - when
+ <link to="IMachine::detachHostPciDevice"/> is called.
+
+ <see><link to="IMachine::detachHostPciDevice"/></see>
+
</desc>
<attribute name="plugged" type="boolean" readonly="yes">
<desc>
- If device successfully plugged or unplugged.
+ If device successfully plugged or unplugged.
</desc>
</attribute>
@@ -16656,13 +17615,6 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</desc>
</attribute>
- <attribute name="eventContext" type="IEventContext" readonly="yes">
- <desc>
- Context object, passed into attachHostPciDevice() and
- attachHostPciDevice().
- </desc>
- </attribute>
-
<attribute name="message" type="wstring" readonly="yes">
<desc>
Optional error message.
@@ -16782,6 +17734,28 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</interface>
+ <interface
+ name="IStorageDeviceChangedEvent" extends="IEvent"
+ uuid="8a5c2dce-e341-49d4-afce-c95979f7d70c"
+ wsmap="managed" autogen="VBoxEvent" id="OnStorageDeviceChanged"
+ >
+ <desc>
+ Notification when a
+ <link to="IMachine::mediumAttachments">storage device</link>
+ is attached or removed.
+ </desc>
+ <attribute name="storageDevice" type="IMediumAttachment" readonly="yes">
+ <desc>
+ Storage device that is subject to change.
+ </desc>
+ </attribute>
+ <attribute name="removed" type="boolean" readonly="yes">
+ <desc>
+ Flag whether the device was removed or added to the VM.
+ </desc>
+ </attribute>
+ </interface>
+
<module name="VBoxSVC" context="LocalServer">
<class name="VirtualBox" uuid="B1A7A4F2-47B9-4A1E-82B2-07CCD5323C3F"
namespace="virtualbox.org">
diff --git a/src/VBox/Main/idl/comimpl.xsl b/src/VBox/Main/idl/comimpl.xsl
index e037500fa..e92386190 100644
--- a/src/VBox/Main/idl/comimpl.xsl
+++ b/src/VBox/Main/idl/comimpl.xsl
@@ -69,7 +69,7 @@
<xsl:value-of select="concat(' COM_INTERFACE_ENTRY(', $name, ')&#10;')" />
<xsl:choose>
<xsl:when test="$extends='$unknown'">
- <xsl:value-of select=" ' COM_INTERFACE_ENTRY(IDispatch)&#10;'" />
+ <!-- Reached base -->
</xsl:when>
<xsl:when test="//interface[@name=$extends]">
<xsl:call-template name="genComEntry">
@@ -293,7 +293,7 @@
</xsl:call-template>
</xsl:variable>
<xsl:value-of select=" '#ifdef RT_OS_WINDOWS&#10;'"/>
- <xsl:value-of select=" ' SAFEARRAY ** aPtr = va_arg(args, SAFEARRAY **);&#10;'"/>
+ <xsl:value-of select=" ' SAFEARRAY * aPtr = va_arg(args, SAFEARRAY *);&#10;'"/>
<xsl:value-of select="concat(' com::SafeArray&lt;', $elemtype,'&gt; aArr(aPtr);&#10;')"/>
<xsl:value-of select=" '#else&#10;'"/>
<xsl:value-of select=" ' PRUint32 aArrSize = va_arg(args, PRUint32);&#10;'"/>
@@ -470,6 +470,8 @@
<xsl:value-of select="concat(' DECLARE_NOT_AGGREGATABLE(', $implName, ')&#10;')" />
<xsl:value-of select=" ' DECLARE_PROTECT_FINAL_CONSTRUCT()&#10;'" />
<xsl:value-of select="concat(' BEGIN_COM_MAP(', $implName, ')&#10;')" />
+ <xsl:value-of select="concat(' VBOX_DEFAULT_INTERFACE_ENTRIES(', @name, ')&#10;')" />
+
<xsl:call-template name="genComEntry">
<xsl:with-param name="name" select="@name" />
</xsl:call-template>
@@ -479,11 +481,13 @@
<xsl:text><![CDATA[
HRESULT FinalConstruct()
{
+ BaseFinalConstruct();
return mEvent.createObject();
}
void FinalRelease()
{
mEvent->FinalRelease();
+ BaseFinalRelease();
}
STDMETHOD(COMGETTER(Type)) (VBoxEventType_T *aType)
{
diff --git a/src/VBox/Main/idl/midl.xsl b/src/VBox/Main/idl/midl.xsl
index dfb535ee3..b9fe818c6 100644
--- a/src/VBox/Main/idl/midl.xsl
+++ b/src/VBox/Main/idl/midl.xsl
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
-<!-- $Id: midl.xsl $ -->
+<!-- $Id: midl.xsl 35913 2011-02-09 12:44:03Z vboxsync $ -->
<!--
* A template to generate a MS IDL compatible interface definition file
@@ -686,10 +686,6 @@
<xsl:when test="@dir='return'">out, retval</xsl:when>
<xsl:otherwise>in</xsl:otherwise>
</xsl:choose>
- <xsl:if test="@safearray='yes'">
- <!-- VB supports only [in, out], [out] and [out, retval] arrays -->
- <xsl:if test="@dir='in'">, out</xsl:if>
- </xsl:if>
<xsl:text>] </xsl:text>
<xsl:if test="@safearray='yes'">
<xsl:text>SAFEARRAY(</xsl:text>
@@ -698,7 +694,7 @@
<xsl:if test="@safearray='yes'">
<xsl:text>)</xsl:text>
</xsl:if>
- <xsl:if test="@dir='out' or @dir='return' or @safearray='yes'">
+ <xsl:if test="@dir='out' or @dir='return'">
<xsl:text> *</xsl:text>
</xsl:if>
<xsl:text> a</xsl:text>
diff --git a/src/VBox/Main/idl/xpidl.xsl b/src/VBox/Main/idl/xpidl.xsl
index e53819da7..18c9e3e23 100644
--- a/src/VBox/Main/idl/xpidl.xsl
+++ b/src/VBox/Main/idl/xpidl.xsl
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
-<!-- $Id: xpidl.xsl $ -->
+<!-- $Id: xpidl.xsl 30631 2010-07-05 19:20:03Z vboxsync $ -->
<!--
* A template to generate a XPCOM IDL compatible interface definition file
diff --git a/src/VBox/Main/include/AdditionsFacilityImpl.h b/src/VBox/Main/include/AdditionsFacilityImpl.h
new file mode 100644
index 000000000..d7a4b75d3
--- /dev/null
+++ b/src/VBox/Main/include/AdditionsFacilityImpl.h
@@ -0,0 +1,94 @@
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * 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 ____H_ADDITIONSFACILITYIMPL
+#define ____H_ADDITIONSFACILITYIMPL
+
+#include "VirtualBoxBase.h"
+#include <iprt/time.h>
+
+class Guest;
+
+class ATL_NO_VTABLE AdditionsFacility :
+ public VirtualBoxBase,
+ VBOX_SCRIPTABLE_IMPL(IAdditionsFacility)
+{
+public:
+ VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(AdditionsFacility, IAdditionsFacility)
+
+ DECLARE_NOT_AGGREGATABLE(AdditionsFacility)
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(AdditionsFacility)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IAdditionsFacility)
+ END_COM_MAP()
+
+ DECLARE_EMPTY_CTOR_DTOR(AdditionsFacility)
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Guest *aParent, AdditionsFacilityType_T enmFacility, AdditionsFacilityStatus_T enmStatus);
+ void uninit();
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // IAdditionsFacility properties
+ STDMETHOD(COMGETTER(ClassType))(AdditionsFacilityClass_T *aClass);
+ STDMETHOD(COMGETTER(LastUpdated))(LONG64 *aTimestamp);
+ STDMETHOD(COMGETTER(Name))(BSTR *aName);
+ STDMETHOD(COMGETTER(Status))(AdditionsFacilityStatus_T *aStatus);
+ STDMETHOD(COMGETTER(Type))(AdditionsFacilityType_T *aType);
+
+public:
+ /** Facility <-> string mappings. */
+ struct FacilityInfo
+ {
+ /** The facilitie's name. */
+ const char *mName; /* utf-8 */
+ /** The facilitie's type. */
+ AdditionsFacilityType_T mType;
+ /** The facilitie's class. */
+ AdditionsFacilityClass_T mClass;
+ };
+ static const FacilityInfo sFacilityInfo[8];
+
+ // public internal methods
+ static const AdditionsFacility::FacilityInfo &typeToInfo(AdditionsFacilityType_T aType);
+ AdditionsFacilityClass_T getClass() const;
+ LONG64 getLastUpdated() const;
+ Bstr getName() const;
+ AdditionsFacilityStatus_T getStatus() const;
+ AdditionsFacilityType_T getType() const;
+ HRESULT update(AdditionsFacilityStatus_T aStatus, RTTIMESPEC aTimestamp);
+
+private:
+ struct Data
+ {
+ /** 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;
+ /** The facilitie's current status. */
+ AdditionsFacilityStatus_T mStatus;
+ /** The facilitie's ID/type. */
+ AdditionsFacilityType_T mType;
+ } mData;
+};
+
+#endif // ____H_ADDITIONSFACILITYIMPL
+
diff --git a/src/VBox/Main/include/ApplianceImpl.h b/src/VBox/Main/include/ApplianceImpl.h
index 3f099d269..3cb7821ef 100644
--- a/src/VBox/Main/include/ApplianceImpl.h
+++ b/src/VBox/Main/include/ApplianceImpl.h
@@ -1,4 +1,4 @@
-/* $Id: ApplianceImpl.h $ */
+/* $Id: ApplianceImpl.h 37862 2011-07-11 10:09:29Z vboxsync $ */
/** @file
*
@@ -67,9 +67,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(Appliance)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IAppliance)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IAppliance)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (Appliance)
@@ -82,8 +80,8 @@ public:
};
// public initializer/uninitializer for internal purposes only
- HRESULT FinalConstruct() { return S_OK; }
- void FinalRelease() { uninit(); }
+ HRESULT FinalConstruct() { return BaseFinalConstruct(); }
+ void FinalRelease() { uninit(); BaseFinalRelease(); }
HRESULT init(VirtualBox *aVirtualBox);
void uninit();
@@ -98,7 +96,7 @@ public:
/* Import methods */
STDMETHOD(Read)(IN_BSTR path, IProgress **aProgress);
STDMETHOD(Interpret)(void);
- STDMETHOD(ImportMachines)(IProgress **aProgress);
+ STDMETHOD(ImportMachines)(ComSafeArrayIn(ImportOptions_T, options), IProgress **aProgress);
/* Export methods */
STDMETHOD(CreateVFSExplorer)(IN_BSTR aURI, IVFSExplorer **aExplorer);
STDMETHOD(Write)(IN_BSTR format, BOOL fManifest, IN_BSTR path, IProgress **aProgress);
@@ -251,16 +249,14 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(VirtualSystemDescription)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IVirtualSystemDescription)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IVirtualSystemDescription)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (VirtualSystemDescription)
// public initializer/uninitializer for internal purposes only
- HRESULT FinalConstruct() { return S_OK; }
- void FinalRelease() { uninit(); }
+ HRESULT FinalConstruct() { return BaseFinalConstruct(); }
+ void FinalRelease() { uninit(); BaseFinalRelease(); }
HRESULT init();
void uninit();
diff --git a/src/VBox/Main/include/ApplianceImplPrivate.h b/src/VBox/Main/include/ApplianceImplPrivate.h
index 1e05402c2..e67033583 100644
--- a/src/VBox/Main/include/ApplianceImplPrivate.h
+++ b/src/VBox/Main/include/ApplianceImplPrivate.h
@@ -72,6 +72,7 @@ struct Appliance::Data
LocationInfo locInfo; // location info for the currently processed OVF
bool fManifest; // Create a manifest file on export
+ RTCList<ImportOptions_T> optList;
ovf::OVFReader *pReader;
diff --git a/src/VBox/Main/include/AudioAdapterImpl.h b/src/VBox/Main/include/AudioAdapterImpl.h
index f445501b1..becf72ecb 100644
--- a/src/VBox/Main/include/AudioAdapterImpl.h
+++ b/src/VBox/Main/include/AudioAdapterImpl.h
@@ -1,4 +1,4 @@
-/* $Id: AudioAdapterImpl.h $ */
+/* $Id: AudioAdapterImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -49,9 +49,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(AudioAdapter)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IAudioAdapter)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IAudioAdapter)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (AudioAdapter)
diff --git a/src/VBox/Main/include/BIOSSettingsImpl.h b/src/VBox/Main/include/BIOSSettingsImpl.h
index cad88a4cd..6df3a15bc 100644
--- a/src/VBox/Main/include/BIOSSettingsImpl.h
+++ b/src/VBox/Main/include/BIOSSettingsImpl.h
@@ -1,4 +1,4 @@
-/* $Id: BIOSSettingsImpl.h $ */
+/* $Id: BIOSSettingsImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -41,9 +41,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(BIOSSettings)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IBIOSSettings)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IBIOSSettings)
END_COM_MAP()
HRESULT FinalConstruct();
diff --git a/src/VBox/Main/include/BandwidthControlImpl.h b/src/VBox/Main/include/BandwidthControlImpl.h
index d27ab473b..98101cc5d 100644
--- a/src/VBox/Main/include/BandwidthControlImpl.h
+++ b/src/VBox/Main/include/BandwidthControlImpl.h
@@ -39,9 +39,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(BandwidthControl)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IBandwidthControl)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IBandwidthControl)
END_COM_MAP()
BandwidthControl() { };
diff --git a/src/VBox/Main/include/BandwidthGroupImpl.h b/src/VBox/Main/include/BandwidthGroupImpl.h
index 9c0539042..3ceb5a2c6 100644
--- a/src/VBox/Main/include/BandwidthGroupImpl.h
+++ b/src/VBox/Main/include/BandwidthGroupImpl.h
@@ -33,9 +33,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(BandwidthGroup)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IBandwidthGroup)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IBandwidthGroup)
END_COM_MAP()
BandwidthGroup() { };
diff --git a/src/VBox/Main/include/BusAssignmentManager.h b/src/VBox/Main/include/BusAssignmentManager.h
index c83df4f7d..a0531a554 100644
--- a/src/VBox/Main/include/BusAssignmentManager.h
+++ b/src/VBox/Main/include/BusAssignmentManager.h
@@ -1,4 +1,4 @@
-/* $Id: BusAssignmentManager.h $ */
+/* $Id: BusAssignmentManager.h 36107 2011-02-28 18:24:32Z vboxsync $ */
/** @file
*
@@ -32,16 +32,29 @@ private:
BusAssignmentManager();
virtual ~BusAssignmentManager();
+ HRESULT assignPciDeviceImpl(const char* pszDevName, PCFGMNODE pCfg, PciBusAddress& GuestAddress, PciBusAddress HostAddress, bool fGuestAddressRequired = false);
+
public:
static BusAssignmentManager* createInstance(ChipsetType_T chipsetType);
virtual void AddRef();
virtual void Release();
- virtual HRESULT assignPciDevice(const char* pszDevName, PCFGMNODE pCfg, PciBusAddress& Address, bool fAddressRequired = false);
+ virtual HRESULT assignHostPciDevice(const char* pszDevName, PCFGMNODE pCfg, PciBusAddress HostAddress, PciBusAddress& GuestAddress, bool fAddressRequired = false)
+ {
+ return assignPciDeviceImpl(pszDevName, pCfg, GuestAddress, HostAddress, fAddressRequired);
+ }
+
+ virtual HRESULT assignPciDevice(const char* pszDevName, PCFGMNODE pCfg, PciBusAddress& Address, bool fAddressRequired = false)
+ {
+ PciBusAddress HostAddress;
+ return assignPciDeviceImpl(pszDevName, pCfg, Address, HostAddress, fAddressRequired);
+ }
+
virtual HRESULT assignPciDevice(const char* pszDevName, PCFGMNODE pCfg)
{
- PciBusAddress Address;
- return assignPciDevice(pszDevName, pCfg, Address, false);
+ PciBusAddress GuestAddress;
+ PciBusAddress HostAddress;
+ return assignPciDeviceImpl(pszDevName, pCfg, GuestAddress, HostAddress, false);
}
virtual bool findPciAddress(const char* pszDevName, int iInstance, PciBusAddress& Address);
virtual bool hasPciDevice(const char* pszDevName, int iInstance)
diff --git a/src/VBox/Main/include/ConsoleImpl.h b/src/VBox/Main/include/ConsoleImpl.h
index 3688794f6..a566fa5ca 100644
--- a/src/VBox/Main/include/ConsoleImpl.h
+++ b/src/VBox/Main/include/ConsoleImpl.h
@@ -1,4 +1,4 @@
-/* $Id: ConsoleImpl.h $ */
+/* $Id: ConsoleImpl.h 37851 2011-07-08 17:04:03Z vboxsync $ */
/** @file
* VBox Console COM Class definition
*/
@@ -34,6 +34,9 @@ class RemoteUSBDevice;
class SharedFolder;
class VRDEServerInfo;
class AudioSniffer;
+#ifdef VBOX_WITH_USB_VIDEO
+class UsbWebcamInterface;
+#endif
class ConsoleVRDPServer;
class VMMDev;
class Progress;
@@ -97,9 +100,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(Console)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IConsole)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IConsole)
END_COM_MAP()
Console();
@@ -126,6 +127,8 @@ public:
STDMETHOD(COMGETTER(SharedFolders))(ComSafeArrayOut(ISharedFolder *, aSharedFolders));
STDMETHOD(COMGETTER(EventSource)) (IEventSource ** aEventSource);
STDMETHOD(COMGETTER(AttachedPciDevices))(ComSafeArrayOut(IPciDeviceAttachment *, aAttachments));
+ STDMETHOD(COMGETTER(UseHostClipboard))(BOOL *aUseHostClipboard);
+ STDMETHOD(COMSETTER(UseHostClipboard))(BOOL aUseHostClipboard);
// IConsole methods
STDMETHOD(PowerUp)(IProgress **aProgress);
@@ -152,6 +155,8 @@ public:
STDMETHOD(TakeSnapshot)(IN_BSTR aName, IN_BSTR aDescription,
IProgress **aProgress);
STDMETHOD(DeleteSnapshot)(IN_BSTR aId, IProgress **aProgress);
+ STDMETHOD(DeleteSnapshotAndAllChildren)(IN_BSTR aId, IProgress **aProgress);
+ STDMETHOD(DeleteSnapshotRange)(IN_BSTR aStartId, IN_BSTR aEndId, IProgress **aProgress);
STDMETHOD(RestoreSnapshot)(ISnapshot *aSnapshot, IProgress **aProgress);
STDMETHOD(Teleport)(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, ULONG aMaxDowntime, IProgress **aProgress);
@@ -171,6 +176,8 @@ public:
const ComPtr<IMachine> &machine() const { return mMachine; }
+ bool useHostClipboard() { return mfUseHostClipboard; }
+
/** Method is called only from ConsoleVRDPServer */
IVRDEServer *getVRDEServer() const { return mVRDEServer; }
@@ -192,6 +199,7 @@ public:
HRESULT onUSBDeviceAttach(IUSBDevice *aDevice, IVirtualBoxErrorInfo *aError, ULONG aMaskedIfs);
HRESULT onUSBDeviceDetach(IN_BSTR aId, IVirtualBoxErrorInfo *aError);
HRESULT onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup);
+ HRESULT onStorageDeviceChange(IMediumAttachment *aMediumAttachment, BOOL aRemove);
HRESULT getGuestProperty(IN_BSTR aKey, BSTR *aValue, LONG64 *aTimestamp, BSTR *aFlags);
HRESULT setGuestProperty(IN_BSTR aKey, IN_BSTR aValue, IN_BSTR aFlags);
HRESULT enumerateGuestProperties(IN_BSTR aPatterns,
@@ -272,7 +280,7 @@ private:
mThat->releaseVMCaller();
}
/** Decreases the number of callers before the instance is destroyed. */
- void release()
+ void releaseCaller()
{
AssertReturnVoid(SUCCEEDED(mRC));
mThat->releaseVMCaller();
@@ -280,7 +288,7 @@ private:
}
/** Restores the number of callers after by #release(). #rc() must be
* rechecked to ensure the operation succeeded. */
- void add()
+ void addYY()
{
AssertReturnVoid(!SUCCEEDED(mRC));
mRC = mThat->addVMCaller(taQuiet, taAllowNullVM);
@@ -294,9 +302,9 @@ private:
HRESULT mRC;
private:
DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoVMCallerBase)
- DECLARE_CLS_NEW_DELETE_NOOP(AutoVMCallerBase)
};
+#if 0
/**
* Helper class that protects sections of code using the mpVM pointer by
* automatically calling addVMCaller() on construction and
@@ -312,13 +320,16 @@ private:
* @note Temporarily locks the argument for writing.
*
* @sa SafeVMPtr, SafeVMPtrQuiet
+ * @obsolete Use SafeVMPtr
*/
typedef AutoVMCallerBase<false, false> AutoVMCaller;
+#endif
/**
* Same as AutoVMCaller but doesn't set extended error info on failure.
*
* @note Temporarily locks the argument for writing.
+ * @obsolete Use SafeVMPtrQuiet
*/
typedef AutoVMCallerBase<true, false> AutoVMCallerQuiet;
@@ -327,6 +338,7 @@ private:
* instead of assertion).
*
* @note Temporarily locks the argument for writing.
+ * @obsolete Use SafeVMPtr
*/
typedef AutoVMCallerBase<false, true> AutoVMCallerWeak;
@@ -336,6 +348,7 @@ private:
* assertion).
*
* @note Temporarily locks the argument for writing.
+ * @obsolete Use SafeVMPtrQuiet
*/
typedef AutoVMCallerBase<true, true> AutoVMCallerQuietWeak;
@@ -347,23 +360,34 @@ private:
{
typedef AutoVMCallerBase<taQuiet, true> Base;
public:
- SafeVMPtrBase(Console *aThat) : Base(aThat), mpVM(NULL)
+ SafeVMPtrBase(Console *aThat) : Base(aThat), mpVM(NULL), mpUVM(NULL)
{
if (SUCCEEDED(Base::mRC))
- {
- mpVM = aThat->mpVM;
- if (!mpVM)
- Base::mRC = E_FAIL; /** @todo use setError here. */
- }
+ Base::mRC = aThat->safeVMPtrRetainer(&mpVM, &mpUVM, taQuiet);
+ }
+ ~SafeVMPtrBase()
+ {
+ if (SUCCEEDED(Base::mRC))
+ release();
}
/** Smart SaveVMPtr to PVM cast operator */
operator PVM() const { return mpVM; }
/** Direct PVM access for printf()-like functions */
PVM raw() const { return mpVM; }
+ /** Direct PUVM access for printf()-like functions */
+ PUVM rawUVM() const { return mpUVM; }
+ /** Release the handles. */
+ void release()
+ {
+ AssertReturnVoid(SUCCEEDED(Base::mRC));
+ Base::mThat->safeVMPtrReleaser(&mpVM, &mpUVM);
+ Base::releaseCaller();
+ }
+
private:
- PVM mpVM;
+ PVM mpVM;
+ PUVM mpUVM;
DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(SafeVMPtrBase)
- DECLARE_CLS_NEW_DELETE_NOOP(SafeVMPtrBase)
};
public:
@@ -432,6 +456,7 @@ public:
typedef std::map<Utf8Str, ComObjPtr<SharedFolder> > SharedFolderMap;
typedef std::map<Utf8Str, SharedFolderData> SharedFolderDataMap;
+ typedef std::map<Utf8Str, ComPtr<IMediumAttachment> > MediumAttachmentMap;
private:
@@ -439,7 +464,9 @@ private:
typedef std::list <ComObjPtr<RemoteUSBDevice> > RemoteUSBDeviceList;
HRESULT addVMCaller(bool aQuiet = false, bool aAllowNullVM = false);
- void releaseVMCaller();
+ void releaseVMCaller();
+ HRESULT safeVMPtrRetainer(PVM *a_ppVM, PUVM *a_ppUVM, bool aQuiet);
+ void safeVMPtrReleaser(PVM *a_ppVM, PUVM *a_ppUVM);
HRESULT consoleInitReleaseLog(const ComPtr<IMachine> aMachine);
@@ -488,6 +515,7 @@ private:
HRESULT *phrc,
bool fAttachDetach,
bool fForceUnmount,
+ bool fHotplug,
PVM pVM,
DeviceType_T *paLedDevType);
int configMedium(PCFGMNODE pLunL0,
@@ -516,6 +544,7 @@ private:
MachineState_T aMachineState,
HRESULT *phrc);
static DECLCALLBACK(int) changeRemovableMedium(Console *pThis,
+ PVM pVM,
const char *pcszDevice,
unsigned uInstance,
StorageBus_T enmBus,
@@ -523,6 +552,12 @@ private:
IMediumAttachment *aMediumAtt,
bool fForce);
+ HRESULT attachRawPciDevices(PVM pVM, BusAssignmentManager *BusMgr, PCFGMNODE pDevices);
+ void attachStatusDriver(PCFGMNODE pCtlInst, PPDMLED *papLeds,
+ uint64_t uFirst, uint64_t uLast,
+ Console::MediumAttachmentMap *pmapMediumAttachments,
+ const char *pcszDevice, unsigned uInstance);
+
int configNetwork(const char *pszDevice, unsigned uInstance, unsigned uLun,
INetworkAdapter *aNetworkAdapter, PCFGMNODE pCfg,
PCFGMNODE pLunL0, PCFGMNODE pInst,
@@ -532,15 +567,15 @@ private:
static DECLCALLBACK(int) configGuestControl(void *pvConsole);
static DECLCALLBACK(void) vmstateChangeCallback(PVM aVM, VMSTATE aState,
VMSTATE aOldState, void *aUser);
- static DECLCALLBACK(int) unplugCpu(Console *pThis, unsigned uCpu);
- static DECLCALLBACK(int) plugCpu(Console *pThis, unsigned uCpu);
- HRESULT doMediumChange(IMediumAttachment *aMediumAttachment, bool fForce);
- HRESULT doCPURemove(ULONG aCpu);
- HRESULT doCPUAdd(ULONG aCpu);
+ static DECLCALLBACK(int) unplugCpu(Console *pThis, PVM pVM, unsigned uCpu);
+ static DECLCALLBACK(int) plugCpu(Console *pThis, PVM pVM, unsigned uCpu);
+ HRESULT doMediumChange(IMediumAttachment *aMediumAttachment, bool fForce, PVM pVM);
+ HRESULT doCPURemove(ULONG aCpu, PVM pVM);
+ HRESULT doCPUAdd(ULONG aCpu, PVM pVM);
- HRESULT doNetworkAdapterChange(const char *pszDevice, unsigned uInstance,
+ HRESULT doNetworkAdapterChange(PVM pVM, const char *pszDevice, unsigned uInstance,
unsigned uLun, INetworkAdapter *aNetworkAdapter);
- static DECLCALLBACK(int) changeNetworkAttachment(Console *pThis, const char *pszDevice,
+ static DECLCALLBACK(int) changeNetworkAttachment(Console *pThis, PVM pVM, const char *pszDevice,
unsigned uInstance, unsigned uLun,
INetworkAdapter *aNetworkAdapter);
@@ -548,11 +583,27 @@ private:
HRESULT attachUSBDevice(IUSBDevice *aHostDevice, ULONG aMaskedIfs);
HRESULT detachUSBDevice(USBDeviceList::iterator &aIt);
- static DECLCALLBACK(int) usbAttachCallback(Console *that, IUSBDevice *aHostDevice, PCRTUUID aUuid,
+ static DECLCALLBACK(int) usbAttachCallback(Console *that, PVM pVM, IUSBDevice *aHostDevice, PCRTUUID aUuid,
bool aRemote, const char *aAddress, ULONG aMaskedIfs);
- static DECLCALLBACK(int) usbDetachCallback(Console *that, USBDeviceList::iterator *aIt, PCRTUUID aUuid);
+ static DECLCALLBACK(int) usbDetachCallback(Console *that, PVM pVM, USBDeviceList::iterator *aIt, PCRTUUID aUuid);
#endif
+ static DECLCALLBACK(int) attachStorageDevice(Console *pThis,
+ PVM pVM,
+ const char *pcszDevice,
+ unsigned uInstance,
+ StorageBus_T enmBus,
+ bool fUseHostIOCache,
+ IMediumAttachment *aMediumAtt);
+ static DECLCALLBACK(int) detachStorageDevice(Console *pThis,
+ PVM pVM,
+ const char *pcszDevice,
+ unsigned uInstance,
+ StorageBus_T enmBus,
+ IMediumAttachment *aMediumAtt);
+ HRESULT doStorageDeviceAttach(IMediumAttachment *aMediumAttachment, PVM pVM);
+ HRESULT doStorageDeviceDetach(IMediumAttachment *aMediumAttachment, PVM pVM);
+
static DECLCALLBACK(int) fntTakeSnapshotWorker(RTTHREAD Thread, void *pvUser);
static DECLCALLBACK(int) stateProgressCallback(PVM pVM, unsigned uPercent, void *pvUser);
@@ -560,12 +611,10 @@ private:
static DECLCALLBACK(void) genericVMSetErrorCallback(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL,
const char *pszErrorFmt, va_list va);
- static DECLCALLBACK(void) setVMRuntimeErrorCallbackF(PVM pVM, void *pvUser, uint32_t fFatal,
- const char *pszErrorId,
- const char *pszFormat, ...);
- static DECLCALLBACK(void) setVMRuntimeErrorCallback(PVM pVM, void *pvUser, uint32_t fFatal,
- const char *pszErrorId,
- const char *pszFormat, va_list va);
+ static void setVMRuntimeErrorCallbackF(PVM pVM, void *pvUser, uint32_t fFatal,
+ const char *pszErrorId, const char *pszFormat, ...);
+ static DECLCALLBACK(void) setVMRuntimeErrorCallback(PVM pVM, void *pvUser, uint32_t fFatal,
+ const char *pszErrorId, const char *pszFormat, va_list va);
HRESULT captureUSBDevices(PVM pVM);
void detachAllUSBDevices(bool aDone);
@@ -582,6 +631,7 @@ private:
static DECLCALLBACK(void *) drvStatus_QueryInterface(PPDMIBASE pInterface, const char *pszIID);
static DECLCALLBACK(void) drvStatus_UnitChanged(PPDMILEDCONNECTORS pInterface, unsigned iLUN);
+ static DECLCALLBACK(int) drvStatus_MediumEjected(PPDMIMEDIANOTIFY pInterface, unsigned iLUN);
static DECLCALLBACK(void) drvStatus_Destruct(PPDMDRVINS pDrvIns);
static DECLCALLBACK(int) drvStatus_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
@@ -619,7 +669,7 @@ private:
HRESULT teleporterSrc(TeleporterStateSrc *pState);
HRESULT teleporterSrcReadACK(TeleporterStateSrc *pState, const char *pszWhich, const char *pszNAckMsg = NULL);
HRESULT teleporterSrcSubmitCommand(TeleporterStateSrc *pState, const char *pszCommand, bool fWaitForAck = true);
- HRESULT teleporterTrg(PVM pVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fStartPaused,
+ HRESULT teleporterTrg(PUVM pUVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fStartPaused,
Progress *pProgress, bool *pfPowerOffOnFailure);
static DECLCALLBACK(int) teleporterTrgServeConnection(RTSOCKET Sock, void *pvUser);
/** @} */
@@ -651,8 +701,8 @@ private:
SharedFolderDataMap m_mapMachineSharedFolders;
SharedFolderMap m_mapSharedFolders; // the console instances
- /** The VM instance handle. */
- PVM mpVM;
+ /** The user mode VM handle. */
+ PUVM mpUVM;
/** Holds the number of "readonly" mpVM callers (users) */
uint32_t mVMCallers;
/** Semaphore posted when the number of mpVM callers drops to zero */
@@ -685,12 +735,15 @@ private:
VMMDev * m_pVMMDev;
AudioSniffer * const mAudioSniffer;
+#ifdef VBOX_WITH_USB_VIDEO
+ UsbWebcamInterface * const mUsbWebcamInterface;
+#endif
BusAssignmentManager* mBusMgr;
enum
{
iLedFloppy = 0,
- cLedFloppy = 1,
+ cLedFloppy = 2,
iLedIde = iLedFloppy + cLedFloppy,
cLedIde = 4,
iLedSata = iLedIde + cLedIde,
@@ -706,6 +759,9 @@ private:
PPDMLED mapNetworkLeds[SchemaDefs::NetworkAdapterCount];
PPDMLED mapSharedFolderLed;
PPDMLED mapUSBLed[2];
+
+ MediumAttachmentMap mapMediumAttachments;
+
/* Note: FreeBSD needs this whether netflt is used or not. */
#if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || defined(RT_OS_FREEBSD))
Utf8Str maTAPDeviceName[8];
@@ -714,6 +770,8 @@ private:
bool mVMStateChangeCallbackDisabled;
+ bool mfUseHostClipboard;
+
/** Local machine state value. */
MachineState_T mMachineState;
@@ -773,7 +831,7 @@ private:
}
}
mCallbackData;
- COM_STRUCT_OR_CLASS(IEventListener) *mVmListner;
+ ComPtr<IEventListener> mVmListener;
friend struct VMTask;
};
diff --git a/src/VBox/Main/include/ConsoleVRDPServer.h b/src/VBox/Main/include/ConsoleVRDPServer.h
index 71119c234..ef2af20fd 100644
--- a/src/VBox/Main/include/ConsoleVRDPServer.h
+++ b/src/VBox/Main/include/ConsoleVRDPServer.h
@@ -1,4 +1,4 @@
-/* $Id: ConsoleVRDPServer.h $ */
+/* $Id: ConsoleVRDPServer.h 37282 2011-06-01 02:56:05Z vboxsync $ */
/** @file
* VBox Console VRDE Server Helper class and implementation of IVRDEServerInfo
*/
@@ -23,6 +23,8 @@
#include <VBox/VBoxAuth.h>
+#include <VBox/RemoteDesktop/VRDEImage.h>
+
#include <VBox/HostServices/VBoxClipboardExt.h>
#include "SchemaDefs.h"
@@ -133,6 +135,10 @@ public:
uint32_t cBits);
void SendAudioInputEnd(void *pvUserCtx);
+#ifdef VBOX_WITH_USB_VIDEO
+ int GetVideoFrameDimensions(uint16_t *pu16Heigh, uint16_t *pu16Width);
+ int SendVideoSreamOn(bool fFetch);
+#endif
private:
/* Note: This is not a ComObjPtr here, because the ConsoleVRDPServer object
@@ -150,9 +156,9 @@ private:
static PFNVRDECREATESERVER mpfnVRDECreateServer;
- static VRDEENTRYPOINTS_3 mEntryPoints;
- static VRDEENTRYPOINTS_3 *mpEntryPoints;
- static VRDECALLBACKS_3 mCallbacks;
+ static VRDEENTRYPOINTS_4 mEntryPoints;
+ static VRDEENTRYPOINTS_4 *mpEntryPoints;
+ static VRDECALLBACKS_4 mCallbacks;
static DECLCALLBACK(int) VRDPCallbackQueryProperty (void *pvCallback, uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut);
static DECLCALLBACK(int) VRDPCallbackClientLogon (void *pvCallback, uint32_t u32ClientId, const char *pszUser, const char *pszPassword, const char *pszDomain);
@@ -174,7 +180,7 @@ private:
IFramebuffer *maFramebuffers[SchemaDefs::MaxGuestMonitors];
- IEventListener *mConsoleListener;
+ ComPtr<IEventListener> mConsoleListener;
VRDPInputSynch m_InputSynch;
@@ -223,6 +229,35 @@ private:
PAUTHENTRY3 mpfnAuthEntry3;
uint32_t volatile mu32AudioInputClientId;
+
+ static DECLCALLBACK(void) H3DORBegin(const void *pvContext, void **ppvInstance,
+ const char *pszFormat);
+ static DECLCALLBACK(void) H3DORGeometry(void *pvInstance,
+ int32_t x, int32_t y, uint32_t w, uint32_t h);
+ static DECLCALLBACK(void) H3DORVisibleRegion(void *pvInstance,
+ uint32_t cRects, RTRECT *paRects);
+ static DECLCALLBACK(void) H3DORFrame(void *pvInstance,
+ void *pvData, uint32_t cbData);
+ static DECLCALLBACK(void) H3DOREnd(void *pvInstance);
+ static DECLCALLBACK(int) H3DORContextProperty(const void *pvContext, uint32_t index,
+ void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut);
+
+ void remote3DRedirect(void);
+
+ /*
+ * VRDE server optional interfaces.
+ */
+
+ /* Image update interface. */
+ bool m_fInterfaceImage;
+ VRDEIMAGECALLBACKS m_interfaceCallbacksImage;
+ VRDEIMAGEINTERFACE m_interfaceImage;
+ static DECLCALLBACK(int) VRDEImageCbNotify (void *pvContext,
+ void *pvUser,
+ HVRDEIMAGE hVideo,
+ uint32_t u32Id,
+ void *pvData,
+ uint32_t cbData);
};
@@ -241,9 +276,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(VRDEServerInfo)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IVRDEServerInfo)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IVRDEServerInfo)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (VRDEServerInfo)
diff --git a/src/VBox/Main/include/DHCPServerImpl.h b/src/VBox/Main/include/DHCPServerImpl.h
index 983a2fb5b..044720755 100644
--- a/src/VBox/Main/include/DHCPServerImpl.h
+++ b/src/VBox/Main/include/DHCPServerImpl.h
@@ -1,4 +1,4 @@
-/* $Id: DHCPServerImpl.h $ */
+/* $Id: DHCPServerImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -44,9 +44,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP (DHCPServer)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IDHCPServer)
- COM_INTERFACE_ENTRY (IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IDHCPServer)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (DHCPServer)
diff --git a/src/VBox/Main/include/DHCPServerRunner.h b/src/VBox/Main/include/DHCPServerRunner.h
index b13084555..adc8da713 100644
--- a/src/VBox/Main/include/DHCPServerRunner.h
+++ b/src/VBox/Main/include/DHCPServerRunner.h
@@ -1,4 +1,4 @@
-/* $Id: DHCPServerRunner.h $ */
+/* $Id: DHCPServerRunner.h 33590 2010-10-29 08:55:09Z vboxsync $ */
/** @file
* VirtualBox Main - interface for VBox DHCP server
*/
diff --git a/src/VBox/Main/include/DisplayImpl.h b/src/VBox/Main/include/DisplayImpl.h
index a4f7b31f4..1c5c09b99 100644
--- a/src/VBox/Main/include/DisplayImpl.h
+++ b/src/VBox/Main/include/DisplayImpl.h
@@ -1,4 +1,4 @@
-/* $Id: DisplayImpl.h $ */
+/* $Id: DisplayImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* VirtualBox COM class implementation
*/
@@ -108,9 +108,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(Display)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IDisplay)
- COM_INTERFACE_ENTRY2(IDispatch,IDisplay)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IDisplay)
COM_INTERFACE_ENTRY(IEventListener)
END_COM_MAP()
diff --git a/src/VBox/Main/include/EventImpl.h b/src/VBox/Main/include/EventImpl.h
index f7be39733..ad795595c 100644
--- a/src/VBox/Main/include/EventImpl.h
+++ b/src/VBox/Main/include/EventImpl.h
@@ -33,9 +33,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(VBoxEvent)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IEvent)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IEvent)
END_COM_MAP()
VBoxEvent() {}
@@ -75,10 +73,8 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(VBoxVetoEvent)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY2(IEvent, IVetoEvent)
- COM_INTERFACE_ENTRY(IVetoEvent)
- COM_INTERFACE_ENTRY2(IDispatch, IVetoEvent)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IVetoEvent)
END_COM_MAP()
VBoxVetoEvent() {}
@@ -139,9 +135,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(EventSource)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IEventSource)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IEventSource)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR(EventSource)
diff --git a/src/VBox/Main/include/ExtPackManagerImpl.h b/src/VBox/Main/include/ExtPackManagerImpl.h
index 3e3fece7d..c0c0e57c1 100644
--- a/src/VBox/Main/include/ExtPackManagerImpl.h
+++ b/src/VBox/Main/include/ExtPackManagerImpl.h
@@ -1,4 +1,4 @@
-/* $Id: ExtPackManagerImpl.h $ */
+/* $Id: ExtPackManagerImpl.h 37843 2011-07-08 12:34:18Z vboxsync $ */
/** @file
* VirtualBox Main - interface for Extension Packs, VBoxSVC & VBoxC.
*/
@@ -36,10 +36,8 @@ public:
DECLARE_NOT_AGGREGATABLE(ExtPackFile)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(ExtPackFile)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IExtPackFile)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IExtPackFile)
COM_INTERFACE_ENTRY(IExtPackBase)
- COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR(ExtPackFile)
@@ -101,10 +99,8 @@ public:
DECLARE_NOT_AGGREGATABLE(ExtPack)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(ExtPack)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IExtPack)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IExtPack)
COM_INTERFACE_ENTRY(IExtPackBase)
- COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR(ExtPack)
@@ -192,9 +188,7 @@ class ATL_NO_VTABLE ExtPackManager :
DECLARE_NOT_AGGREGATABLE(ExtPackManager)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(ExtPackManager)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IExtPackManager)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IExtPackManager)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR(ExtPackManager)
@@ -232,6 +226,7 @@ class ATL_NO_VTABLE ExtPackManager :
int getVrdeLibraryPathForExtPack(Utf8Str const *a_pstrExtPack, Utf8Str *a_pstrVrdeLibrary);
HRESULT getDefaultVrdeExtPack(Utf8Str *a_pstrExtPack);
bool isExtPackUsable(const char *a_pszExtPack);
+ void dumpAllToReleaseLog(void);
/** @} */
private:
diff --git a/src/VBox/Main/include/ExtPackUtil.h b/src/VBox/Main/include/ExtPackUtil.h
index 5885aec5e..c2016728e 100644
--- a/src/VBox/Main/include/ExtPackUtil.h
+++ b/src/VBox/Main/include/ExtPackUtil.h
@@ -1,4 +1,4 @@
-/* $Id: ExtPackUtil.h $ */
+/* $Id: ExtPackUtil.h 37843 2011-07-08 12:34:18Z vboxsync $ */
/** @file
* VirtualBox Main - Extension Pack Utilities and definitions, VBoxC, VBoxSVC, ++.
*/
@@ -65,13 +65,13 @@
typedef struct VBOXEXTPACKPLUGINDESC
{
/** The name. */
- iprt::MiniString strName;
+ RTCString strName;
/** The module name. */
- iprt::MiniString strModule;
+ RTCString strModule;
/** The description. */
- iprt::MiniString strDescription;
+ RTCString strDescription;
/** The frontend or component which it plugs into. */
- iprt::MiniString strFrontend;
+ RTCString strFrontend;
} VBOXEXTPACKPLUGINDESC;
/** Pointer to a plug-in descriptor. */
typedef VBOXEXTPACKPLUGINDESC *PVBOXEXTPACKPLUGINDESC;
@@ -84,17 +84,17 @@ typedef VBOXEXTPACKPLUGINDESC *PVBOXEXTPACKPLUGINDESC;
typedef struct VBOXEXTPACKDESC
{
/** The name. */
- iprt::MiniString strName;
+ RTCString strName;
/** The description. */
- iprt::MiniString strDescription;
+ RTCString strDescription;
/** The version string. */
- iprt::MiniString strVersion;
+ RTCString strVersion;
/** The internal revision number. */
uint32_t uRevision;
/** The name of the main module. */
- iprt::MiniString strMainModule;
+ RTCString strMainModule;
/** The name of the VRDE module, empty if none. */
- iprt::MiniString strVrdeModule;
+ RTCString strVrdeModule;
/** The number of plug-in descriptors. */
uint32_t cPlugIns;
/** Pointer to an array of plug-in descriptors. */
@@ -110,14 +110,14 @@ typedef VBOXEXTPACKDESC const *PCVBOXEXTPACKDESC;
void VBoxExtPackInitDesc(PVBOXEXTPACKDESC a_pExtPackDesc);
-iprt::MiniString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo);
-iprt::MiniString *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo);
-iprt::MiniString *VBoxExtPackExtractNameFromTarballPath(const char *pszTarball);
+RTCString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo);
+RTCString *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo);
+RTCString *VBoxExtPackExtractNameFromTarballPath(const char *pszTarball);
void VBoxExtPackFreeDesc(PVBOXEXTPACKDESC a_pExtPackDesc);
bool VBoxExtPackIsValidName(const char *pszName);
bool VBoxExtPackIsValidMangledName(const char *pszMangledName, size_t cchMax = RTSTR_MAX);
-iprt::MiniString *VBoxExtPackMangleName(const char *pszName);
-iprt::MiniString *VBoxExtPackUnmangleName(const char *pszMangledName, size_t cbMax);
+RTCString *VBoxExtPackMangleName(const char *pszName);
+RTCString *VBoxExtPackUnmangleName(const char *pszMangledName, size_t cbMax);
int VBoxExtPackCalcDir(char *pszExtPackDir, size_t cbExtPackDir, const char *pszParentDir, const char *pszName);
bool VBoxExtPackIsValidVersionString(const char *pszName);
bool VBoxExtPackIsValidModuleString(const char *pszModule);
diff --git a/src/VBox/Main/include/FramebufferImpl.h b/src/VBox/Main/include/FramebufferImpl.h
index 89ff1e439..eb13c796c 100644
--- a/src/VBox/Main/include/FramebufferImpl.h
+++ b/src/VBox/Main/include/FramebufferImpl.h
@@ -1,4 +1,4 @@
-/* $Id: FramebufferImpl.h $ */
+/* $Id: FramebufferImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -38,9 +38,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP (Framebuffer)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IFramebuffer)
- COM_INTERFACE_ENTRY (IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (IFramebuffer)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (Framebuffer)
diff --git a/src/VBox/Main/include/Global.h b/src/VBox/Main/include/Global.h
index e43aa7081..011b4bcb1 100644
--- a/src/VBox/Main/include/Global.h
+++ b/src/VBox/Main/include/Global.h
@@ -1,4 +1,4 @@
-/* $Id: Global.h $ */
+/* $Id: Global.h 34244 2010-11-22 14:31:02Z vboxsync $ */
/** @file
* VirtualBox COM API - Global Declarations and Definitions.
*/
diff --git a/src/VBox/Main/include/GuestImpl.h b/src/VBox/Main/include/GuestImpl.h
index ab134b72e..6a5b51986 100644
--- a/src/VBox/Main/include/GuestImpl.h
+++ b/src/VBox/Main/include/GuestImpl.h
@@ -3,7 +3,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;
@@ -19,8 +19,10 @@
#include "VirtualBoxBase.h"
#include <iprt/list.h>
+#include <iprt/time.h>
#include <VBox/ostypes.h>
+#include "AdditionsFacilityImpl.h"
#ifdef VBOX_WITH_GUEST_CONTROL
# include <VBox/HostServices/GuestControlSvc.h>
# include "HGCM.h"
@@ -58,9 +60,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(Guest)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IGuest)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IGuest)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (Guest)
@@ -76,31 +76,38 @@ public:
STDMETHOD(COMGETTER(OSTypeId)) (BSTR *aOSTypeId);
STDMETHOD(COMGETTER(AdditionsRunLevel)) (AdditionsRunLevelType_T *aRunLevel);
STDMETHOD(COMGETTER(AdditionsVersion)) (BSTR *aAdditionsVersion);
- /** @todo Remove later by replacing it by AdditionsFeatureAvailable(). */
- STDMETHOD(COMGETTER(SupportsSeamless)) (BOOL *aSupportsSeamless);
- STDMETHOD(COMGETTER(SupportsGraphics)) (BOOL *aSupportsGraphics);
-#if 0
- /** @todo Will replace SupportsSeamless, SupportsGraphics, ... */
- STDMETHOD(COMGETTER(AdditionsFeatureAvailable)) (LONG64 aFeature, BOOL *aActive, BOOL *aAvailable);
-#endif
+ STDMETHOD(COMGETTER(Facilities)) (ComSafeArrayOut(IAdditionsFacility*, aFacilities));
STDMETHOD(COMGETTER(MemoryBalloonSize)) (ULONG *aMemoryBalloonSize);
STDMETHOD(COMSETTER(MemoryBalloonSize)) (ULONG aMemoryBalloonSize);
STDMETHOD(COMGETTER(StatisticsUpdateInterval)) (ULONG *aUpdateInterval);
STDMETHOD(COMSETTER(StatisticsUpdateInterval)) (ULONG aUpdateInterval);
// IGuest methods
+ STDMETHOD(GetFacilityStatus)(AdditionsFacilityType_T aType, LONG64 *aTimestamp, AdditionsFacilityStatus_T *aStatus);
STDMETHOD(GetAdditionsStatus)(AdditionsRunLevelType_T aLevel, BOOL *aActive);
STDMETHOD(SetCredentials)(IN_BSTR aUserName, IN_BSTR aPassword,
IN_BSTR aDomain, BOOL aAllowInteractiveLogon);
+ // Process execution
STDMETHOD(ExecuteProcess)(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);
STDMETHOD(GetProcessOutput)(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS, LONG64 aSize, ComSafeArrayOut(BYTE, aData));
STDMETHOD(SetProcessInput)(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS, ComSafeArrayIn(BYTE, aData), ULONG *aBytesWritten);
- STDMETHOD(GetProcessStatus)(ULONG aPID, ULONG *aExitCode, ULONG *aFlags, ULONG *aStatus);
+ STDMETHOD(GetProcessStatus)(ULONG aPID, ULONG *aExitCode, ULONG *aFlags, ExecuteProcessStatus_T *aStatus);
+ // File copying
+ STDMETHOD(CopyFromGuest)(IN_BSTR aSource, IN_BSTR aDest, IN_BSTR aUserName, IN_BSTR aPassword, ULONG aFlags, IProgress **aProgress);
STDMETHOD(CopyToGuest)(IN_BSTR aSource, IN_BSTR aDest, IN_BSTR aUserName, IN_BSTR aPassword, ULONG aFlags, IProgress **aProgress);
- STDMETHOD(CreateDirectory)(IN_BSTR aDirectory, IN_BSTR aUserName, IN_BSTR aPassword, ULONG aMode, ULONG aFlags, IProgress **aProgress);
+ // Directory handling
+ STDMETHOD(DirectoryClose)(ULONG aHandle);
+ STDMETHOD(DirectoryCreate)(IN_BSTR aDirectory, IN_BSTR aUserName, IN_BSTR aPassword, ULONG aMode, ULONG aFlags);
+ STDMETHOD(DirectoryOpen)(IN_BSTR aDirectory, IN_BSTR aFilter,
+ ULONG aFlags, IN_BSTR aUserName, IN_BSTR aPassword, ULONG *aHandle);
+ STDMETHOD(DirectoryRead)(ULONG aHandle, IGuestDirEntry **aDirEntry);
+ // File handling
+ STDMETHOD(FileExists)(IN_BSTR aFile, IN_BSTR aUserName, IN_BSTR aPassword, BOOL *aExists);
+ STDMETHOD(FileQuerySize)(IN_BSTR aFile, IN_BSTR aUserName, IN_BSTR aPassword, LONG64 *aSize);
+ // Misc stuff
STDMETHOD(InternalGetStatistics)(ULONG *aCpuUser, ULONG *aCpuKernel, ULONG *aCpuIdle,
ULONG *aMemTotal, ULONG *aMemFree, ULONG *aMemBalloon, ULONG *aMemShared, ULONG *aMemCache,
ULONG *aPageTotal, ULONG *aMemAllocTotal, ULONG *aMemFreeTotal, ULONG *aMemBalloonTotal, ULONG *aMemSharedTotal);
@@ -111,17 +118,19 @@ public:
ComSafeArrayIn(IN_BSTR, aArguments), ComSafeArrayIn(IN_BSTR, aEnvironment),
IN_BSTR aUserName, IN_BSTR aPassword,
ULONG aTimeoutMS, ULONG *aPID, IProgress **aProgress, int *pRC);
- HRESULT createDirectoryInternal(IN_BSTR aDirectory, IN_BSTR aUserName, IN_BSTR aPassword,
- ULONG aMode, ULONG aFlags, IProgress **aProgress, int *pRC);
+ HRESULT directoryCreateInternal(IN_BSTR aDirectory, IN_BSTR aUserName, IN_BSTR aPassword,
+ ULONG aMode, ULONG aFlags, int *pRC);
void setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType);
void setAdditionsInfo2(Bstr aAdditionsVersion, Bstr aVersionName, Bstr aRevision);
- void setAdditionsStatus(VBoxGuestStatusFacility Facility, VBoxGuestStatusCurrent Status, ULONG ulFlags);
- void setSupportedFeatures(uint32_t fCaps, uint32_t fActive);
+ bool facilityIsActive(VBoxGuestFacilityType enmFacility);
+ HRESULT facilityUpdate(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus);
+ void setAdditionsStatus(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus, ULONG aFlags);
+ void setSupportedFeatures(uint32_t aCaps);
HRESULT setStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal);
BOOL isPageFusionEnabled();
# ifdef VBOX_WITH_GUEST_CONTROL
/** Static callback for handling guest notifications. */
- static DECLCALLBACK(int) doGuestCtrlNotification(void *pvExtension, uint32_t u32Function, void *pvParms, uint32_t cbParms);
+ static DECLCALLBACK(int) notifyCtrlDispatcher(void *pvExtension, uint32_t u32Function, void *pvParms, uint32_t cbParms);
# endif
static HRESULT setErrorStatic(HRESULT aResultCode,
const Utf8Str &aText)
@@ -130,14 +139,15 @@ public:
}
private:
-
- // Internal tasks
- struct TaskGuest; /* Worker thread helper. */
#ifdef VBOX_WITH_GUEST_CONTROL
- HRESULT taskCopyFile(TaskGuest *aTask);
+ // Internal tasks.
+ struct TaskGuest; /* Worker thread helper. */
+ HRESULT taskCopyFileToGuest(TaskGuest *aTask);
+ HRESULT taskCopyFileFromGuest(TaskGuest *aTask);
HRESULT taskUpdateGuestAdditions(TaskGuest *aTask);
- struct CallbackContext
+ // Internal guest callback representation.
+ typedef struct VBOXGUESTCTRL_CALLBACK
{
eVBoxGuestCtrlCallbackType mType;
/** Pointer to user-supplied data. */
@@ -146,56 +156,73 @@ private:
uint32_t cbData;
/** Pointer to user-supplied IProgress. */
ComObjPtr<Progress> pProgress;
- };
- /*
- * The map key is the context ID.
- */
- typedef std::map< uint32_t, CallbackContext > CallbackMap;
- typedef std::map< uint32_t, CallbackContext >::iterator CallbackMapIter;
- typedef std::map< uint32_t, CallbackContext >::const_iterator CallbackMapIterConst;
+ } VBOXGUESTCTRL_CALLBACK, *PVBOXGUESTCTRL_CALLBACK;
+ typedef std::map< uint32_t, VBOXGUESTCTRL_CALLBACK > CallbackMap;
+ typedef std::map< uint32_t, VBOXGUESTCTRL_CALLBACK >::iterator CallbackMapIter;
+ typedef std::map< uint32_t, VBOXGUESTCTRL_CALLBACK >::const_iterator CallbackMapIterConst;
+
+ int callbackAdd(const PVBOXGUESTCTRL_CALLBACK pCallbackData, uint32_t *puContextID);
+ void callbackDestroy(uint32_t uContextID);
+ bool callbackExists(uint32_t uContextID);
+ void callbackFreeUserData(void *pvData);
+ int callbackGetUserData(uint32_t uContextID, eVBoxGuestCtrlCallbackType *pEnmType, void **ppvData, size_t *pcbData);
+ void* callbackGetUserDataMutableRaw(uint32_t uContextID, size_t *pcbData);
+ bool callbackIsCanceled(uint32_t uContextID);
+ bool callbackIsComplete(uint32_t uContextID);
+ int callbackMoveForward(uint32_t uContextID, const char *pszMessage);
+ int callbackNotifyEx(uint32_t uContextID, int iRC, const char *pszMessage);
+ int callbackNotifyComplete(uint32_t uContextID);
+ int callbackNotifyAllForPID(uint32_t uPID, int iRC, const char *pszMessage);
+ int callbackWaitForCompletion(uint32_t uContextID, LONG lStage, LONG lTimeout);
- struct GuestProcess
+ int notifyCtrlClientDisconnected(uint32_t u32Function, PCALLBACKDATACLIENTDISCONNECTED pData);
+ int notifyCtrlExecStatus(uint32_t u32Function, PCALLBACKDATAEXECSTATUS pData);
+ int notifyCtrlExecOut(uint32_t u32Function, PCALLBACKDATAEXECOUT pData);
+ int notifyCtrlExecInStatus(uint32_t u32Function, PCALLBACKDATAEXECINSTATUS pData);
+
+ // Internal guest process representation.
+ typedef struct VBOXGUESTCTRL_PROCESS
{
- uint32_t mStatus;
+ ExecuteProcessStatus_T mStatus;
uint32_t mFlags;
uint32_t mExitCode;
- };
- /*
- * The map key is the PID (process identifier).
- */
- typedef std::map< uint32_t, GuestProcess > GuestProcessMap;
- typedef std::map< uint32_t, GuestProcess >::iterator GuestProcessMapIter;
- typedef std::map< uint32_t, GuestProcess >::const_iterator GuestProcessMapIterConst;
+ } VBOXGUESTCTRL_PROCESS, *PVBOXGUESTCTRL_PROCESS;
+ typedef std::map< uint32_t, VBOXGUESTCTRL_PROCESS > GuestProcessMap;
+ 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);
+ // Utility functions.
int directoryEntryAppend(const char *pszPath, PRTLISTNODE pList);
int directoryRead(const char *pszDirectory, const char *pszFilter, ULONG uFlags, ULONG *pcObjects, PRTLISTNODE pList);
-
int prepareExecuteEnv(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnv);
- /** Handler for guest execution control notifications. */
- int notifyCtrlClientDisconnected(uint32_t u32Function, PCALLBACKDATACLIENTDISCONNECTED pData);
- int notifyCtrlExecStatus(uint32_t u32Function, PCALLBACKDATAEXECSTATUS pData);
- int notifyCtrlExecOut(uint32_t u32Function, PCALLBACKDATAEXECOUT pData);
- int notifyCtrlExecInStatus(uint32_t u32Function, PCALLBACKDATAEXECINSTATUS pData);
- CallbackMapIter getCtrlCallbackContextByID(uint32_t u32ContextID);
- GuestProcessMapIter getProcessByPID(uint32_t u32PID);
- void notifyCtrlCallbackContext(Guest::CallbackMapIter it, const char *pszText);
- void destroyCtrlCallbackContext(CallbackMapIter it);
- uint32_t addCtrlCallbackContext(eVBoxGuestCtrlCallbackType enmType, void *pvData, uint32_t cbData, Progress* pProgress);
- HRESULT waitForProcessStatusChange(ULONG uPID, ULONG *puRetStatus, ULONG *puRetExitCode, ULONG uTimeoutMS);
+
+ /*
+ * Handler for guest execution control notifications.
+ */
+ HRESULT handleErrorCompletion(int rc);
+ HRESULT handleErrorHGCM(int rc);
+
+ HRESULT waitForProcessStatusChange(ULONG uPID, ExecuteProcessStatus_T *pRetStatus, ULONG *puRetExitCode, ULONG uTimeoutMS);
+ HRESULT executeProcessResult(const char *pszCommand, const char *pszUser, ULONG ulTimeout, PCALLBACKDATAEXECSTATUS pExecStatus, ULONG *puPID);
# endif
+ typedef std::map< AdditionsFacilityType_T, ComObjPtr<AdditionsFacility> > FacilityMap;
+ typedef std::map< AdditionsFacilityType_T, ComObjPtr<AdditionsFacility> >::iterator FacilityMapIter;
+ typedef std::map< AdditionsFacilityType_T, ComObjPtr<AdditionsFacility> >::const_iterator FacilityMapIterConst;
+
struct Data
{
- Data() : mAdditionsRunLevel (AdditionsRunLevelType_None),
- mSupportsSeamless (FALSE),
- mSupportsGraphics (FALSE) {}
+ Data() : mAdditionsRunLevel (AdditionsRunLevelType_None) {}
Bstr mOSTypeId;
+ FacilityMap mFacilityMap;
AdditionsRunLevelType_T mAdditionsRunLevel;
Bstr mAdditionsVersion;
Bstr mInterfaceVersion;
- BOOL mSupportsSeamless;
- BOOL mSupportsGraphics;
};
ULONG mMemoryBalloonSize;
@@ -209,10 +236,10 @@ private:
# ifdef VBOX_WITH_GUEST_CONTROL
/** General extension callback for guest control. */
HGCMSVCEXTHANDLE mhExtCtrl;
-
+ /** Next upcoming context ID. */
volatile uint32_t mNextContextID;
- CallbackMap mCallbackMap;
- GuestProcessMap mGuestProcessMap;
+ CallbackMap mCallbackMap;
+ GuestProcessMap mGuestProcessMap;
# endif
};
diff --git a/src/VBox/Main/include/GuestOSTypeImpl.h b/src/VBox/Main/include/GuestOSTypeImpl.h
index 00fed7ebc..f1c196a44 100644
--- a/src/VBox/Main/include/GuestOSTypeImpl.h
+++ b/src/VBox/Main/include/GuestOSTypeImpl.h
@@ -35,9 +35,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(GuestOSType)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IGuestOSType)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IGuestOSType)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR(GuestOSType)
diff --git a/src/VBox/Main/include/HostHardwareLinux.h b/src/VBox/Main/include/HostHardwareLinux.h
index 717fb0576..d7dea5cd6 100644
--- a/src/VBox/Main/include/HostHardwareLinux.h
+++ b/src/VBox/Main/include/HostHardwareLinux.h
@@ -1,6 +1,6 @@
-/* $Id: HostHardwareLinux.h $ */
+/* $Id: HostHardwareLinux.h 36527 2011-04-04 13:16:09Z vboxsync $ */
/** @file
- * Classes for handling hardware detection under Linux.
+ * VirtualBox Main - Classes for handling hardware detection under Linux.
*
* Please feel free to expand these to work for other systems (Solaris!) or to
* add new ones for other systems.
@@ -39,18 +39,18 @@ public:
struct DriveInfo
{
/** The device node of the drive. */
- iprt::MiniString mDevice;
+ RTCString mDevice;
/** A unique identifier for the device, if available. This should be
* kept consistent across different probing methods of a given
* platform if at all possible. */
- iprt::MiniString mUdi;
+ RTCString mUdi;
/** A textual description of the drive. */
- iprt::MiniString mDescription;
+ RTCString mDescription;
/** Constructors */
- DriveInfo(const iprt::MiniString &aDevice,
- const iprt::MiniString &aUdi = "",
- const iprt::MiniString &aDescription = "")
+ DriveInfo(const RTCString &aDevice,
+ const RTCString &aUdi = "",
+ const RTCString &aDescription = "")
: mDevice(aDevice),
mUdi(aUdi),
mDescription(aDescription)
diff --git a/src/VBox/Main/include/HostImpl.h b/src/VBox/Main/include/HostImpl.h
index fc8ca003d..757ec7409 100644
--- a/src/VBox/Main/include/HostImpl.h
+++ b/src/VBox/Main/include/HostImpl.h
@@ -1,10 +1,10 @@
-/* $Id: HostImpl.h $ */
+/* $Id: HostImpl.h 36615 2011-04-07 12:45:27Z vboxsync $ */
/** @file
* Implementation of IHost.
*/
/*
- * Copyright (C) 2006-2009 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;
@@ -45,9 +45,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(Host)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IHost)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IHost)
END_COM_MAP()
HRESULT FinalConstruct();
@@ -58,17 +56,17 @@ public:
void uninit();
// IHost properties
- STDMETHOD(COMGETTER(DVDDrives))(ComSafeArrayOut (IMedium *, drives));
- STDMETHOD(COMGETTER(FloppyDrives))(ComSafeArrayOut (IMedium *, drives));
- STDMETHOD(COMGETTER(USBDevices))(ComSafeArrayOut (IHostUSBDevice *, aUSBDevices));
- STDMETHOD(COMGETTER(USBDeviceFilters))(ComSafeArrayOut (IHostUSBDeviceFilter *, aUSBDeviceFilters));
- STDMETHOD(COMGETTER(NetworkInterfaces))(ComSafeArrayOut (IHostNetworkInterface *, aNetworkInterfaces));
+ STDMETHOD(COMGETTER(DVDDrives))(ComSafeArrayOut(IMedium *, drives));
+ STDMETHOD(COMGETTER(FloppyDrives))(ComSafeArrayOut(IMedium *, drives));
+ STDMETHOD(COMGETTER(USBDevices))(ComSafeArrayOut(IHostUSBDevice *, aUSBDevices));
+ STDMETHOD(COMGETTER(USBDeviceFilters))(ComSafeArrayOut(IHostUSBDeviceFilter *, aUSBDeviceFilters));
+ STDMETHOD(COMGETTER(NetworkInterfaces))(ComSafeArrayOut(IHostNetworkInterface *, aNetworkInterfaces));
STDMETHOD(COMGETTER(ProcessorCount))(ULONG *count);
STDMETHOD(COMGETTER(ProcessorOnlineCount))(ULONG *count);
STDMETHOD(COMGETTER(ProcessorCoreCount))(ULONG *count);
STDMETHOD(GetProcessorSpeed)(ULONG cpuId, ULONG *speed);
STDMETHOD(GetProcessorDescription)(ULONG cpuId, BSTR *description);
- STDMETHOD(GetProcessorFeature) (ProcessorFeature_T feature, BOOL *supported);
+ STDMETHOD(GetProcessorFeature)(ProcessorFeature_T feature, BOOL *supported);
STDMETHOD(GetProcessorCPUIDLeaf)(ULONG aCpuId, ULONG aLeaf, ULONG aSubLeaf, ULONG *aValEAX, ULONG *aValEBX, ULONG *aValECX, ULONG *aValEDX);
STDMETHOD(COMGETTER(MemorySize))(ULONG *size);
STDMETHOD(COMGETTER(MemoryAvailable))(ULONG *available);
@@ -78,20 +76,21 @@ public:
STDMETHOD(COMGETTER(Acceleration3DAvailable))(BOOL *aSupported);
// IHost methods
- STDMETHOD(CreateHostOnlyNetworkInterface) (IHostNetworkInterface **aHostNetworkInterface,
- IProgress **aProgress);
- STDMETHOD(RemoveHostOnlyNetworkInterface) (IN_BSTR aId, IProgress **aProgress);
- STDMETHOD(CreateUSBDeviceFilter) (IN_BSTR aName, IHostUSBDeviceFilter **aFilter);
- STDMETHOD(InsertUSBDeviceFilter) (ULONG aPosition, IHostUSBDeviceFilter *aFilter);
- STDMETHOD(RemoveUSBDeviceFilter) (ULONG aPosition);
-
- STDMETHOD(FindHostDVDDrive) (IN_BSTR aName, IMedium **aDrive);
- STDMETHOD(FindHostFloppyDrive) (IN_BSTR aName, IMedium **aDrive);
- STDMETHOD(FindHostNetworkInterfaceByName) (IN_BSTR aName, IHostNetworkInterface **networkInterface);
- STDMETHOD(FindHostNetworkInterfaceById) (IN_BSTR id, IHostNetworkInterface **networkInterface);
- STDMETHOD(FindHostNetworkInterfacesOfType) (HostNetworkInterfaceType_T type, ComSafeArrayOut (IHostNetworkInterface *, aNetworkInterfaces));
- STDMETHOD(FindUSBDeviceByAddress) (IN_BSTR aAddress, IHostUSBDevice **aDevice);
- STDMETHOD(FindUSBDeviceById) (IN_BSTR aId, IHostUSBDevice **aDevice);
+ STDMETHOD(CreateHostOnlyNetworkInterface)(IHostNetworkInterface **aHostNetworkInterface,
+ IProgress **aProgress);
+ STDMETHOD(RemoveHostOnlyNetworkInterface)(IN_BSTR aId, IProgress **aProgress);
+ STDMETHOD(CreateUSBDeviceFilter)(IN_BSTR aName, IHostUSBDeviceFilter **aFilter);
+ STDMETHOD(InsertUSBDeviceFilter)(ULONG aPosition, IHostUSBDeviceFilter *aFilter);
+ STDMETHOD(RemoveUSBDeviceFilter)(ULONG aPosition);
+
+ STDMETHOD(FindHostDVDDrive)(IN_BSTR aName, IMedium **aDrive);
+ STDMETHOD(FindHostFloppyDrive)(IN_BSTR aName, IMedium **aDrive);
+ STDMETHOD(FindHostNetworkInterfaceByName)(IN_BSTR aName, IHostNetworkInterface **networkInterface);
+ STDMETHOD(FindHostNetworkInterfaceById)(IN_BSTR id, IHostNetworkInterface **networkInterface);
+ STDMETHOD(FindHostNetworkInterfacesOfType)(HostNetworkInterfaceType_T type, ComSafeArrayOut(IHostNetworkInterface *, aNetworkInterfaces));
+ STDMETHOD(FindUSBDeviceByAddress)(IN_BSTR aAddress, IHostUSBDevice **aDevice);
+ STDMETHOD(FindUSBDeviceById)(IN_BSTR aId, IHostUSBDevice **aDevice);
+ STDMETHOD(GenerateMACAddress)(BSTR *aAddress);
// public methods only for internal purposes
@@ -126,6 +125,8 @@ public:
HRESULT checkUSBProxyService();
#endif /* !VBOX_WITH_USB */
+ static void generateMACAddress(Utf8Str &mac);
+
private:
HRESULT buildDVDDrivesList(MediaList &list);
@@ -144,8 +145,8 @@ private:
#endif
#ifdef VBOX_WITH_RESOURCE_USAGE_API
- void registerMetrics (PerformanceCollector *aCollector);
- void unregisterMetrics (PerformanceCollector *aCollector);
+ void registerMetrics(PerformanceCollector *aCollector);
+ void unregisterMetrics(PerformanceCollector *aCollector);
#endif /* VBOX_WITH_RESOURCE_USAGE_API */
struct Data; // opaque data structure, defined in HostImpl.cpp
diff --git a/src/VBox/Main/include/HostNetworkInterfaceImpl.h b/src/VBox/Main/include/HostNetworkInterfaceImpl.h
index f582d5f65..0c6f0a72d 100644
--- a/src/VBox/Main/include/HostNetworkInterfaceImpl.h
+++ b/src/VBox/Main/include/HostNetworkInterfaceImpl.h
@@ -1,4 +1,4 @@
-/* $Id: HostNetworkInterfaceImpl.h $ */
+/* $Id: HostNetworkInterfaceImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -42,9 +42,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP (HostNetworkInterface)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IHostNetworkInterface)
- COM_INTERFACE_ENTRY (IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IHostNetworkInterface)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (HostNetworkInterface)
diff --git a/src/VBox/Main/include/HostUSBDeviceImpl.h b/src/VBox/Main/include/HostUSBDeviceImpl.h
index d2e61c295..106ce1274 100644
--- a/src/VBox/Main/include/HostUSBDeviceImpl.h
+++ b/src/VBox/Main/include/HostUSBDeviceImpl.h
@@ -1,4 +1,4 @@
-/* $Id: HostUSBDeviceImpl.h $ */
+/* $Id: HostUSBDeviceImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* VirtualBox IHostUSBDevice COM interface implementation.
*/
@@ -180,10 +180,8 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(HostUSBDevice)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IHostUSBDevice)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IHostUSBDevice)
COM_INTERFACE_ENTRY(IUSBDevice)
- COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (HostUSBDevice)
diff --git a/src/VBox/Main/include/KeyboardImpl.h b/src/VBox/Main/include/KeyboardImpl.h
index 75306c8b3..0225044cc 100644
--- a/src/VBox/Main/include/KeyboardImpl.h
+++ b/src/VBox/Main/include/KeyboardImpl.h
@@ -1,4 +1,4 @@
-/* $Id: KeyboardImpl.h $ */
+/* $Id: KeyboardImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* VirtualBox COM class implementation
*/
@@ -57,9 +57,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(Keyboard)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IKeyboard)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IKeyboard)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR(Keyboard)
diff --git a/src/VBox/Main/include/Logging.h b/src/VBox/Main/include/Logging.h
index 1c3ca5b7e..17ca5e55e 100644
--- a/src/VBox/Main/include/Logging.h
+++ b/src/VBox/Main/include/Logging.h
@@ -1,4 +1,4 @@
-/* $Id: Logging.h $ */
+/* $Id: Logging.h 38037 2011-07-18 17:31:38Z vboxsync $ */
/** @file
*
@@ -6,7 +6,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;
@@ -41,53 +41,10 @@
# define LOG_GROUP LOG_GROUP_MAIN
#endif
-/* Ensure log macros are enabled if release logging is requested */
-#if defined (VBOX_MAIN_RELEASE_LOG) && !defined (DEBUG)
-# ifndef LOG_ENABLED
-# define LOG_ENABLED
-# endif
-#endif
-
#include <VBox/log.h>
-#include <iprt/assert.h>
-/** @def MyLogIt
- * Copy of LogIt that works even when logging is completely disabled (e.g. in
- * release builds) and doesn't interfere with the default release logger
- * instance (which is already in use by the VM process).
- *
- * @warning Logging using MyLog* is intended only as a temporary mean to debug
- * release builds (e.g. in case if the error is not reproducible with
- * the debug builds)! Any MyLog* usage must be removed from the sources
- * after the error has been fixed.
- */
-#if defined(RT_ARCH_AMD64) || defined(LOG_USE_C99)
-# define _MyLogRemoveParentheseis(...) __VA_ARGS__
-# define _MyLogIt(pvInst, fFlags, iGroup, ...) RTLogLoggerEx((PRTLOGGER)pvInst, fFlags, iGroup, __VA_ARGS__)
-# define MyLogIt(pvInst, fFlags, iGroup, fmtargs) _MyLogIt(pvInst, fFlags, iGroup, _MyLogRemoveParentheseis fmtargs)
-#else
-# define MyLogIt(pvInst, fFlags, iGroup, fmtargs) \
- do \
- { \
- register PRTLOGGER LogIt_pLogger = (PRTLOGGER)(pvInst) ? (PRTLOGGER)(pvInst) : RTLogDefaultInstance(); \
- if (LogIt_pLogger) \
- { \
- register unsigned LogIt_fFlags = LogIt_pLogger->afGroups[(unsigned)(iGroup) < LogIt_pLogger->cGroups ? (unsigned)(iGroup) : 0]; \
- if ((LogIt_fFlags & ((fFlags) | RTLOGGRPFLAGS_ENABLED)) == ((fFlags) | RTLOGGRPFLAGS_ENABLED)) \
- LogIt_pLogger->pfnLogger fmtargs; \
- } \
- } while (0)
-#endif
-
-/** @def MyLog
- * Equivalent to LogFlow but uses MyLogIt instead of LogIt.
- *
- * @warning Logging using MyLog* is intended only as a temporary mean to debug
- * release builds (e.g. in case if the error is not reproducible with
- * the debug builds)! Any MyLog* usage must be removed from the sources
- * after the error has been fixed.
- */
-#define MyLog(a) MyLogIt(LOG_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, a)
+int VBoxSVCLogRelCreate(const char *pszLogFile, uint32_t cHistory,
+ uint32_t uHistoryFileTime, uint64_t uHistoryFileSize);
#endif // ____H_LOGGING
/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/MachineDebuggerImpl.h b/src/VBox/Main/include/MachineDebuggerImpl.h
index d16b2049a..3ad95d129 100644
--- a/src/VBox/Main/include/MachineDebuggerImpl.h
+++ b/src/VBox/Main/include/MachineDebuggerImpl.h
@@ -1,4 +1,4 @@
-/* $Id: MachineDebuggerImpl.h $ */
+/* $Id: MachineDebuggerImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -37,9 +37,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(MachineDebugger)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IMachineDebugger)
- COM_INTERFACE_ENTRY (IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (IMachineDebugger)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (MachineDebugger)
diff --git a/src/VBox/Main/include/MachineImpl.h b/src/VBox/Main/include/MachineImpl.h
index 288caac0b..3bb4ffb46 100644
--- a/src/VBox/Main/include/MachineImpl.h
+++ b/src/VBox/Main/include/MachineImpl.h
@@ -1,4 +1,4 @@
-/* $Id: MachineImpl.h $ */
+/* $Id: MachineImpl.h 37851 2011-07-08 17:04:03Z vboxsync $ */
/** @file
* VirtualBox COM class implementation
*/
@@ -199,7 +199,7 @@ public:
*/
struct SSData
{
- Utf8Str mStateFilePath;
+ Utf8Str strStateFilePath;
};
/**
@@ -291,10 +291,13 @@ public:
BOOL mIoCacheEnabled;
ULONG mIoCacheSize;
+
+ typedef std::list< ComObjPtr<PciDeviceAttachment> > PciDeviceAssignmentList;
+ PciDeviceAssignmentList mPciDeviceAssignments;
};
/**
- * Hard disk and other media data.
+ * Hard disk and other media data.
*
* The usage policy is the same as for HWData, but a separate structure
* is necessary because hard disk data requires different procedures when
@@ -318,9 +321,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(Machine)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IMachine)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IMachine)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR(Machine)
@@ -387,6 +388,10 @@ public:
STDMETHOD(COMSETTER(CPUHotPlugEnabled))(BOOL enabled);
STDMETHOD(COMGETTER(CPUExecutionCap))(ULONG *aExecutionCap);
STDMETHOD(COMSETTER(CPUExecutionCap))(ULONG aExecutionCap);
+ STDMETHOD(COMGETTER(EmulatedUSBCardReaderEnabled))(BOOL *enabled);
+ STDMETHOD(COMSETTER(EmulatedUSBCardReaderEnabled))(BOOL enabled);
+ STDMETHOD(COMGETTER(EmulatedUSBWebcameraEnabled))(BOOL *enabled);
+ STDMETHOD(COMSETTER(EmulatedUSBWebcameraEnabled))(BOOL enabled);
STDMETHOD(COMGETTER(HpetEnabled))(BOOL *enabled);
STDMETHOD(COMSETTER(HpetEnabled))(BOOL enabled);
STDMETHOD(COMGETTER(MemoryBalloonSize))(ULONG *memoryBalloonSize);
@@ -458,6 +463,8 @@ public:
STDMETHOD(COMSETTER(IoCacheEnabled)) (BOOL aEnabled);
STDMETHOD(COMGETTER(IoCacheSize)) (ULONG *aIoCacheSize);
STDMETHOD(COMSETTER(IoCacheSize)) (ULONG aIoCacheSize);
+ STDMETHOD(COMGETTER(PciDeviceAssignments))(ComSafeArrayOut(IPciDeviceAttachment *, aAssignments));
+ STDMETHOD(COMGETTER(BandwidthControl))(IBandwidthControl **aBandwidthControl);
// IMachine methods
STDMETHOD(LockMachine)(ISession *aSession, LockType_T lockType);
@@ -469,6 +476,8 @@ public:
LONG aDevice, DeviceType_T aType, IMedium *aMedium);
STDMETHOD(DetachDevice)(IN_BSTR aControllerName, LONG aControllerPort, LONG aDevice);
STDMETHOD(PassthroughDevice)(IN_BSTR aControllerName, LONG aControllerPort, LONG aDevice, BOOL aPassthrough);
+ STDMETHOD(TemporaryEjectDevice)(IN_BSTR aControllerName, LONG aControllerPort, LONG aDevice, BOOL aTempEject);
+ STDMETHOD(NonRotationalDevice)(IN_BSTR aControllerName, LONG aControllerPort, LONG aDevice, BOOL aNonRotational);
STDMETHOD(SetBandwidthGroupForDevice)(IN_BSTR aControllerName, LONG aControllerPort,
LONG aDevice, IBandwidthGroup *aBandwidthGroup);
STDMETHOD(MountMedium)(IN_BSTR aControllerName, LONG aControllerPort,
@@ -523,10 +532,9 @@ public:
STDMETHOD(GetCPUStatus(ULONG aCpu, BOOL *aCpuAttached));
STDMETHOD(QueryLogFilename(ULONG aIdx, BSTR *aName));
STDMETHOD(ReadLog(ULONG aIdx, LONG64 aOffset, LONG64 aSize, ComSafeArrayOut(BYTE, aData)));
- STDMETHOD(AttachHostPciDevice(LONG hostAddress, LONG desiredGuestAddress, IEventContext *eventContext, BOOL tryToUnbind));
+ STDMETHOD(AttachHostPciDevice(LONG hostAddress, LONG desiredGuestAddress, BOOL tryToUnbind));
STDMETHOD(DetachHostPciDevice(LONG hostAddress));
- STDMETHOD(COMGETTER(PciDeviceAssignments))(ComSafeArrayOut(IPciDeviceAttachment *, aAssignments));
- STDMETHOD(COMGETTER(BandwidthControl))(IBandwidthControl **aBandwidthControl);
+ STDMETHOD(CloneTo(IMachine *pTarget, CloneMode_T mode, ComSafeArrayIn(CloneOptions_T, options), IProgress **pProgress));
// public methods only for internal purposes
virtual bool isSnapshotMachine() const
@@ -566,6 +574,16 @@ public:
VirtualBox* getVirtualBox() const { return mParent; }
/**
+ * Checks if this machine is accessible, without attempting to load the
+ * config file.
+ *
+ * @note This method doesn't check this object's readiness. Intended to be
+ * used by ready Machine children (whose readiness is bound to the parent's
+ * one) or after doing addCaller() manually.
+ */
+ bool isAccessible() const { return mData->mAccessible; }
+
+ /**
* Returns this machine ID.
*
* @note This method doesn't check this object's readiness. Intended to be
@@ -618,7 +636,18 @@ public:
IsModified_BandwidthControl = 0x1000
};
+ /**
+ * Checks if this machine is accessible, without attempting to load the
+ * config file.
+ *
+ * @note This method doesn't check this object's readiness. Intended to be
+ * used by ready Machine children (whose readiness is bound to the parent's
+ * one) or after doing addCaller() manually.
+ */
+ ChipsetType_T getChipsetType() const { return mHWData->mChipsetType; }
+
void setModified(uint32_t fl);
+ void setModifiedLock(uint32_t fl);
// callback handlers
virtual HRESULT onNetworkAdapterChange(INetworkAdapter * /* networkAdapter */, BOOL /* changeAdapter */) { return S_OK; }
@@ -634,6 +663,7 @@ public:
virtual HRESULT onMediumChange(IMediumAttachment * /* mediumAttachment */, BOOL /* force */) { return S_OK; }
virtual HRESULT onSharedFolderChange() { return S_OK; }
virtual HRESULT onBandwidthGroupChange(IBandwidthGroup * /* aBandwidthGroup */) { return S_OK; }
+ virtual HRESULT onStorageDeviceChange(IMediumAttachment * /* mediumAttachment */, BOOL /* remove */) { return S_OK; }
HRESULT saveRegistryEntry(settings::MachineRegistryEntry &data);
@@ -643,6 +673,8 @@ public:
void getLogFolder(Utf8Str &aLogFolder);
Utf8Str queryLogFilename(ULONG idx);
+ void composeSavedStateFilename(Utf8Str &strStateFilePath);
+
HRESULT launchVMProcess(IInternalSessionControl *aControl,
const Utf8Str &strType,
const Utf8Str &strEnvironment,
@@ -814,6 +846,7 @@ protected:
AutoWriteLock &writeLock,
Snapshot *pSnapshot,
GuidList *pllRegistriesThatNeedSaving);
+
HRESULT detachAllMedia(AutoWriteLock &writeLock,
Snapshot *pSnapshot,
CleanupMode_T cleanupMode,
@@ -827,6 +860,7 @@ protected:
void rollback(bool aNotify);
void commit();
void copyFrom(Machine *aThat);
+ bool isControllerHotplugCapable(StorageControllerType_T enmCtrlType);
struct DeleteTask;
static DECLCALLBACK(int) deleteThread(RTTHREAD Thread, void *pvUser);
@@ -856,7 +890,7 @@ protected:
#ifdef VBOX_WITH_RESOURCE_USAGE_API
void registerMetrics(PerformanceCollector *aCollector, Machine *aMachine, RTPROCESS pid);
- pm::CollectorGuestHAL *mGuestHAL;
+ pm::CollectorGuest *mCollectorGuest;
#endif /* VBOX_WITH_RESOURCE_USAGE_API */
Machine* const mPeer;
@@ -885,13 +919,12 @@ protected:
typedef std::list< ComObjPtr<StorageController> > StorageControllerList;
Backupable<StorageControllerList> mStorageControllers;
- typedef std::list< ComObjPtr<PciDeviceAttachment> > PciDeviceAssignmentList;
- PciDeviceAssignmentList mPciDeviceAssignments;
-
friend class SessionMachine;
friend class SnapshotMachine;
friend class Appliance;
friend class VirtualBox;
+
+ friend class MachineCloneVM;
};
// SessionMachine class
@@ -917,9 +950,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(SessionMachine)
- COM_INTERFACE_ENTRY2(IDispatch, IMachine)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IMachine)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IMachine)
COM_INTERFACE_ENTRY(IInternalMachineControl)
END_COM_MAP()
@@ -959,7 +990,8 @@ public:
BOOL fTakingSnapshotOnline,
BSTR *aStateFilePath);
STDMETHOD(EndTakingSnapshot)(BOOL aSuccess);
- STDMETHOD(DeleteSnapshot)(IConsole *aInitiator, IN_BSTR aId,
+ STDMETHOD(DeleteSnapshot)(IConsole *aInitiator, IN_BSTR aStartId,
+ IN_BSTR aEndID, BOOL fDeleteAllChildren,
MachineState_T *aMachineState, IProgress **aProgress);
STDMETHOD(FinishOnlineMergeMedium)(IMediumAttachment *aMediumAttachment,
IMedium *aSource, IMedium *aTarget,
@@ -976,6 +1008,8 @@ public:
LONG64 aTimestamp, IN_BSTR aFlags);
STDMETHOD(LockMedia)() { return lockMedia(); }
STDMETHOD(UnlockMedia)() { unlockMedia(); return S_OK; }
+ STDMETHOD(EjectMedium)(IMediumAttachment *aAttachment,
+ IMediumAttachment **aNewAttachment);
// public methods only for internal purposes
@@ -1004,6 +1038,7 @@ public:
IVirtualBoxErrorInfo *aError);
HRESULT onSharedFolderChange();
HRESULT onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup);
+ HRESULT onStorageDeviceChange(IMediumAttachment *aMediumAttachment, BOOL aRemove);
bool hasMatchingUSBFilter(const ComObjPtr<HostUSBDevice> &aDevice, ULONG *aMaskedIfs);
@@ -1011,7 +1046,9 @@ private:
struct ConsoleTaskData
{
- ConsoleTaskData() : mLastState(MachineState_Null) {}
+ ConsoleTaskData()
+ : mLastState(MachineState_Null)
+ { }
MachineState_T mLastState;
ComObjPtr<Progress> mProgress;
@@ -1020,7 +1057,7 @@ private:
ComObjPtr<Snapshot> mSnapshot;
// used when saving state (either as part of a snapshot or separate)
- Utf8Str mStateFilePath;
+ Utf8Str strStateFilePath;
};
struct Uninit
@@ -1038,6 +1075,7 @@ private:
void uninit(Uninit::Reason aReason);
HRESULT endSavingState(HRESULT aRC, const Utf8Str &aErrMsg);
+ void releaseSavedStateFile(const Utf8Str &strSavedStateFile, Snapshot *pSnapshotToIgnore);
void deleteSnapshotHandler(DeleteSnapshotTask &aTask);
void restoreSnapshotHandler(RestoreSnapshotTask &aTask);
@@ -1128,9 +1166,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(SnapshotMachine)
- COM_INTERFACE_ENTRY2(IDispatch, IMachine)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IMachine)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IMachine)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR(SnapshotMachine)
diff --git a/src/VBox/Main/include/MachineImplCloneVM.h b/src/VBox/Main/include/MachineImplCloneVM.h
new file mode 100644
index 000000000..a620ab93c
--- /dev/null
+++ b/src/VBox/Main/include/MachineImplCloneVM.h
@@ -0,0 +1,51 @@
+/** @file
+ * Definition of MachineCloneVM
+ */
+
+/*
+ * 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 ____H_MACHINEIMPLCLONEVM
+#define ____H_MACHINEIMPLCLONEVM
+
+#include "MachineImpl.h"
+#include "ProgressImpl.h"
+
+/* Forward declaration of the d-pointer. */
+struct MachineCloneVMPrivate;
+
+class MachineCloneVM
+{
+public:
+ MachineCloneVM(ComObjPtr<Machine> pSrcMachine, ComObjPtr<Machine> pTrgMachine, CloneMode_T mode, const RTCList<CloneOptions_T> &opts);
+ ~MachineCloneVM();
+
+ HRESULT start(IProgress **pProgress);
+
+protected:
+ HRESULT run();
+ HRESULT createDiffHelper(const ComObjPtr<Medium> &pParent,
+ const Utf8Str &strSnapshotFolder,
+ RTCList<ComObjPtr<Medium> > *pNewMedia,
+ ComObjPtr<Medium> *ppDiff);
+ void destroy();
+
+ /* d-pointer */
+ MachineCloneVM(MachineCloneVMPrivate &d);
+ MachineCloneVMPrivate *d_ptr;
+
+ friend struct MachineCloneVMPrivate;
+};
+
+#endif // ____H_MACHINEIMPLCLONEVM
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
+
diff --git a/src/VBox/Main/include/MediumAttachmentImpl.h b/src/VBox/Main/include/MediumAttachmentImpl.h
index 98727b50d..e367af283 100644
--- a/src/VBox/Main/include/MediumAttachmentImpl.h
+++ b/src/VBox/Main/include/MediumAttachmentImpl.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2009 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;
@@ -33,9 +33,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(MediumAttachment)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IMediumAttachment)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IMediumAttachment)
END_COM_MAP()
MediumAttachment() { };
@@ -48,7 +46,10 @@ public:
LONG aPort,
LONG aDevice,
DeviceType_T aType,
+ bool fImplicit,
bool fPassthrough,
+ bool fTempEject,
+ bool fNonRotational,
const Utf8Str &strBandwidthGroup);
void uninit();
@@ -62,6 +63,9 @@ public:
STDMETHOD(COMGETTER(Device))(LONG *aDevice);
STDMETHOD(COMGETTER(Type))(DeviceType_T *aType);
STDMETHOD(COMGETTER(Passthrough))(BOOL *aPassthrough);
+ STDMETHOD(COMGETTER(TemporaryEject))(BOOL *aTemporaryEject);
+ STDMETHOD(COMGETTER(IsEjected))(BOOL *aIsEjected);
+ STDMETHOD(COMGETTER(NonRotational))(BOOL *aNonRotational);
STDMETHOD(COMGETTER(BandwidthGroup))(IBandwidthGroup **aBwGroup);
// public internal methods
@@ -79,6 +83,8 @@ public:
LONG getDevice() const;
DeviceType_T getType() const;
bool getPassthrough() const;
+ bool getTempEject() const;
+ bool getNonRotational() const;
const Utf8Str& getBandwidthGroup() const;
bool matches(CBSTR aControllerName, LONG aPort, LONG aDevice);
@@ -90,6 +96,15 @@ public:
void updatePassthrough(bool aPassthrough);
/** Must be called from under this object's write lock. */
+ void updateTempEject(bool aTempEject);
+
+ /** Must be called from under this object's write lock. */
+ void updateNonRotational(bool aNonRotational);
+
+ /** Must be called from under this object's write lock. */
+ void updateEjected();
+
+ /** Must be called from under this object's write lock. */
void updateBandwidthGroup(const Utf8Str &aBandwidthGroup);
void updateParentMachine(Machine * const pMachine);
diff --git a/src/VBox/Main/include/MediumFormatImpl.h b/src/VBox/Main/include/MediumFormatImpl.h
index ef091bceb..0220f66e8 100644
--- a/src/VBox/Main/include/MediumFormatImpl.h
+++ b/src/VBox/Main/include/MediumFormatImpl.h
@@ -1,4 +1,4 @@
-/* $Id: MediumFormatImpl.h $ */
+/* $Id: MediumFormatImpl.h 37587 2011-06-22 12:02:13Z vboxsync $ */
/** @file
*
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -58,13 +58,13 @@ public:
struct Data
{
- Data() : capabilities(0) {}
+ Data() : capabilities((MediumFormatCapabilities_T)0) {}
const Utf8Str strId;
const Utf8Str strName;
const StrList llFileExtensions;
const DeviceTypeList llDeviceTypes;
- const uint64_t capabilities;
+ const MediumFormatCapabilities_T capabilities;
const PropertyList llProperties;
};
@@ -75,9 +75,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(MediumFormat)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IMediumFormat)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IMediumFormat)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR(MediumFormat)
@@ -113,7 +111,7 @@ public:
/** Const, no need to lock */
const StrList& getFileExtensions() const { return m.llFileExtensions; }
/** Const, no need to lock */
- uint64_t getCapabilities() const { return m.capabilities; }
+ MediumFormatCapabilities_T getCapabilities() const { return m.capabilities; }
/** Const, no need to lock */
const PropertyList& getProperties() const { return m.llProperties; }
diff --git a/src/VBox/Main/include/MediumImpl.h b/src/VBox/Main/include/MediumImpl.h
index 53b642959..2628cd63e 100644
--- a/src/VBox/Main/include/MediumImpl.h
+++ b/src/VBox/Main/include/MediumImpl.h
@@ -1,4 +1,4 @@
-/* $Id: MediumImpl.h $ */
+/* $Id: MediumImpl.h 37900 2011-07-12 13:31:46Z vboxsync $ */
/** @file
*
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -50,9 +50,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(Medium)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IMedium)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IMedium)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR(Medium)
@@ -79,6 +77,7 @@ public:
HRESULT init(VirtualBox *aVirtualBox,
const Utf8Str &aLocation,
HDDOpenMode enOpenMode,
+ bool fForceNewUuid,
DeviceType_T aDeviceType);
// initializer used when loading settings
@@ -116,6 +115,7 @@ public:
STDMETHOD(COMGETTER(MediumFormat))(IMediumFormat **aMediumFormat);
STDMETHOD(COMGETTER(Type))(MediumType_T *aType);
STDMETHOD(COMSETTER(Type))(MediumType_T aType);
+ STDMETHOD(COMGETTER(AllowedTypes))(ComSafeArrayOut(MediumType_T, aAllowedTypes));
STDMETHOD(COMGETTER(Parent))(IMedium **aParent);
STDMETHOD(COMGETTER(Children))(ComSafeArrayOut(IMedium *, aChildren));
STDMETHOD(COMGETTER(Base))(IMedium **aBase);
@@ -193,6 +193,7 @@ public:
const Guid* getFirstMachineBackrefId() const;
const Guid* getAnyMachineBackref() const;
const Guid* getFirstMachineBackrefSnapshotId() const;
+ size_t getMachineBackRefCount() const;
#ifdef DEBUG
void dumpBackRefs();
@@ -203,6 +204,7 @@ public:
ComObjPtr<Medium> getBase(uint32_t *aLevel = NULL);
bool isReadOnly();
+ void updateId(const Guid &id);
HRESULT saveSettings(settings::Medium &data,
const Utf8Str &strHardDiskFolder);
diff --git a/src/VBox/Main/include/MediumLock.h b/src/VBox/Main/include/MediumLock.h
index eaa12f8b4..b6cd68cf5 100644
--- a/src/VBox/Main/include/MediumLock.h
+++ b/src/VBox/Main/include/MediumLock.h
@@ -1,4 +1,4 @@
-/* $Id: MediumLock.h $ */
+/* $Id: MediumLock.h 36580 2011-04-06 13:52:10Z vboxsync $ */
/** @file
*
diff --git a/src/VBox/Main/include/MouseImpl.h b/src/VBox/Main/include/MouseImpl.h
index 4be4dbd82..ca9725925 100644
--- a/src/VBox/Main/include/MouseImpl.h
+++ b/src/VBox/Main/include/MouseImpl.h
@@ -1,4 +1,4 @@
-/* $Id: MouseImpl.h $ */
+/* $Id: MouseImpl.h 36161 2011-03-04 10:24:58Z vboxsync $ */
/** @file
* VirtualBox COM class implementation
*/
@@ -46,9 +46,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(Mouse)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IMouse)
- COM_INTERFACE_ENTRY2 (IDispatch, IMouse)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IMouse)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (Mouse)
@@ -98,10 +96,10 @@ private:
HRESULT updateVMMDevMouseCaps(uint32_t fCapsAdded, uint32_t fCapsRemoved);
HRESULT reportRelEventToMouseDev(int32_t dx, int32_t dy, int32_t dz,
int32_t dw, uint32_t fButtons);
- HRESULT reportAbsEventToMouseDev(uint32_t mouseXAbs, uint32_t mouseYAbs,
+ HRESULT reportAbsEventToMouseDev(int32_t mouseXAbs, int32_t mouseYAbs,
int32_t dz, int32_t dw, uint32_t fButtons);
- HRESULT reportAbsEventToVMMDev(uint32_t mouseXAbs, uint32_t mouseYAbs);
- HRESULT reportAbsEvent(uint32_t mouseXAbs, uint32_t mouseYAbs,
+ HRESULT reportAbsEventToVMMDev(int32_t mouseXAbs, int32_t mouseYAbs);
+ HRESULT reportAbsEvent(int32_t mouseXAbs, int32_t mouseYAbs,
int32_t dz, int32_t dw, uint32_t fButtons,
bool fUsesVMMDevEvent);
HRESULT convertDisplayRes(LONG x, LONG y, int32_t *pcX, int32_t *pcY,
@@ -124,13 +122,18 @@ private:
struct DRVMAINMOUSE *mpDrv[MOUSE_MAX_DEVICES];
uint32_t mfVMMDevGuestCaps; /** We cache this to avoid access races */
- uint32_t mcLastAbsX;
- uint32_t mcLastAbsY;
+ int32_t mcLastAbsX;
+ int32_t mcLastAbsY;
uint32_t mfLastButtons;
#ifndef VBOXBFE_WITHOUT_COM
const ComObjPtr<EventSource> mEventSource;
VBoxEventDesc mMouseEvent;
+
+ void fireMouseEvent(bool fAbsolute, LONG x, LONG y, LONG dz, LONG dw, LONG Buttons);
+#else
+ void fireMouseEvent(bool fAbsolute, LONG x, LONG y, LONG dz, LONG dw, LONG Buttons)
+ {}
#endif
};
@@ -145,7 +148,7 @@ enum
MouseButtonState_RightButton = 2,
MouseButtonState_MiddleButton = 4,
MouseButtonState_XButton1 = 8,
- MouseButtonState_XButton2 = 16,
+ MouseButtonState_XButton2 = 16
};
#endif
diff --git a/src/VBox/Main/include/NATEngineImpl.h b/src/VBox/Main/include/NATEngineImpl.h
index a8267e679..31fe4a69f 100644
--- a/src/VBox/Main/include/NATEngineImpl.h
+++ b/src/VBox/Main/include/NATEngineImpl.h
@@ -1,4 +1,4 @@
-/* $Id: NATEngineImpl.h $ */
+/* $Id: NATEngineImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -73,9 +73,7 @@ class ATL_NO_VTABLE NATEngine :
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(NATEngine)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (INATEngine)
- COM_INTERFACE_ENTRY2 (IDispatch, INATEngine)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (INATEngine)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (NATEngine)
diff --git a/src/VBox/Main/include/NetworkAdapterImpl.h b/src/VBox/Main/include/NetworkAdapterImpl.h
index 579e91e71..12d45486f 100644
--- a/src/VBox/Main/include/NetworkAdapterImpl.h
+++ b/src/VBox/Main/include/NetworkAdapterImpl.h
@@ -1,4 +1,4 @@
-/* $Id: NetworkAdapterImpl.h $ */
+/* $Id: NetworkAdapterImpl.h 37200 2011-05-24 15:34:06Z vboxsync $ */
/** @file
*
@@ -6,7 +6,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;
@@ -22,6 +22,7 @@
#include "VirtualBoxBase.h"
#include "NATEngineImpl.h"
+#include "BandwidthGroupImpl.h"
class GuestOSType;
@@ -43,11 +44,10 @@ public:
mAttachmentType(NetworkAttachmentType_Null),
mCableConnected(TRUE),
mLineSpeed(0),
+ mPromiscModePolicy(NetworkAdapterPromiscModePolicy_Deny),
mTraceEnabled(FALSE),
- mHostInterface("") /* cannot be null */,
-#ifdef VBOX_WITH_VDE
- mVDENetwork("") /* can be null */,
-#endif
+ mBridgedInterface("") /* cannot be null */,
+ mHostOnlyInterface("") /* cannot be null */,
mNATNetwork("") /* cannot be null */,
mBootPriority(0)
{}
@@ -59,16 +59,17 @@ public:
NetworkAttachmentType_T mAttachmentType;
BOOL mCableConnected;
ULONG mLineSpeed;
+ NetworkAdapterPromiscModePolicy_T mPromiscModePolicy;
BOOL mTraceEnabled;
Bstr mTraceFile;
- Bstr mHostInterface;
+ Bstr mBridgedInterface;
+ Bstr mHostOnlyInterface;
Bstr mInternalNetwork;
-#ifdef VBOX_WITH_VDE
- Bstr mVDENetwork;
-#endif
Bstr mNATNetwork;
+ Bstr mGenericDriver;
+ settings::StringsMap mGenericProperties;
ULONG mBootPriority;
- ULONG mBandwidthLimit;
+ ComObjPtr<BandwidthGroup> mBandwidthGroup;
};
VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(NetworkAdapter, INetworkAdapter)
@@ -78,76 +79,79 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(NetworkAdapter)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (INetworkAdapter)
- COM_INTERFACE_ENTRY2 (IDispatch, INetworkAdapter)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(INetworkAdapter)
END_COM_MAP()
- DECLARE_EMPTY_CTOR_DTOR (NetworkAdapter)
+ DECLARE_EMPTY_CTOR_DTOR(NetworkAdapter)
HRESULT FinalConstruct();
void FinalRelease();
// public initializer/uninitializer for internal purposes only
- HRESULT init (Machine *aParent, ULONG aSlot);
- HRESULT init (Machine *aParent, NetworkAdapter *aThat);
- HRESULT initCopy (Machine *aParent, NetworkAdapter *aThat);
+ HRESULT init(Machine *aParent, ULONG aSlot);
+ HRESULT init(Machine *aParent, NetworkAdapter *aThat);
+ HRESULT initCopy(Machine *aParent, NetworkAdapter *aThat);
void uninit();
// INetworkAdapter properties
STDMETHOD(COMGETTER(AdapterType))(NetworkAdapterType_T *aAdapterType);
STDMETHOD(COMSETTER(AdapterType))(NetworkAdapterType_T aAdapterType);
- STDMETHOD(COMGETTER(Slot)) (ULONG *aSlot);
- STDMETHOD(COMGETTER(Enabled)) (BOOL *aEnabled);
- STDMETHOD(COMSETTER(Enabled)) (BOOL aEnabled);
- STDMETHOD(COMGETTER(MACAddress)) (BSTR *aMACAddress);
- STDMETHOD(COMSETTER(MACAddress)) (IN_BSTR aMACAddress);
- STDMETHOD(COMGETTER(AttachmentType)) (NetworkAttachmentType_T *aAttachmentType);
- STDMETHOD(COMGETTER(HostInterface)) (BSTR *aHostInterface);
- STDMETHOD(COMSETTER(HostInterface)) (IN_BSTR aHostInterface);
- STDMETHOD(COMGETTER(InternalNetwork)) (BSTR *aInternalNetwork);
- STDMETHOD(COMSETTER(InternalNetwork)) (IN_BSTR aInternalNetwork);
- STDMETHOD(COMGETTER(NATNetwork)) (BSTR *aNATNetwork);
- STDMETHOD(COMSETTER(NATNetwork)) (IN_BSTR aNATNetwork);
- STDMETHOD(COMGETTER(VDENetwork)) (BSTR *aVDENetwork);
- STDMETHOD(COMSETTER(VDENetwork)) (IN_BSTR aVDENetwork);
- STDMETHOD(COMGETTER(CableConnected)) (BOOL *aConnected);
- STDMETHOD(COMSETTER(CableConnected)) (BOOL aConnected);
- STDMETHOD(COMGETTER(TraceEnabled)) (BOOL *aEnabled);
- STDMETHOD(COMSETTER(TraceEnabled)) (BOOL aEnabled);
- STDMETHOD(COMGETTER(LineSpeed)) (ULONG *aSpeed);
- STDMETHOD(COMSETTER(LineSpeed)) (ULONG aSpeed);
- STDMETHOD(COMGETTER(TraceFile)) (BSTR *aTraceFile);
- STDMETHOD(COMSETTER(TraceFile)) (IN_BSTR aTraceFile);
- STDMETHOD(COMGETTER(NatDriver)) (INATEngine **aNatDriver);
- STDMETHOD(COMGETTER(BootPriority)) (ULONG *aBootPriority);
- STDMETHOD(COMSETTER(BootPriority)) (ULONG aBootPriority);
- STDMETHOD(COMGETTER(BandwidthLimit)) (ULONG *aLimit);
- STDMETHOD(COMSETTER(BandwidthLimit)) (ULONG aLimit);
+ STDMETHOD(COMGETTER(Slot))(ULONG *aSlot);
+ STDMETHOD(COMGETTER(Enabled))(BOOL *aEnabled);
+ STDMETHOD(COMSETTER(Enabled))(BOOL aEnabled);
+ STDMETHOD(COMGETTER(MACAddress))(BSTR *aMACAddress);
+ STDMETHOD(COMSETTER(MACAddress))(IN_BSTR aMACAddress);
+ STDMETHOD(COMGETTER(AttachmentType))(NetworkAttachmentType_T *aAttachmentType);
+ STDMETHOD(COMSETTER(AttachmentType))(NetworkAttachmentType_T aAttachmentType);
+ STDMETHOD(COMGETTER(BridgedInterface))(BSTR *aBridgedInterface);
+ STDMETHOD(COMSETTER(BridgedInterface))(IN_BSTR aBridgedInterface);
+ STDMETHOD(COMGETTER(HostOnlyInterface))(BSTR *aHostOnlyInterface);
+ STDMETHOD(COMSETTER(HostOnlyInterface))(IN_BSTR aHostOnlyInterface);
+ STDMETHOD(COMGETTER(InternalNetwork))(BSTR *aInternalNetwork);
+ STDMETHOD(COMSETTER(InternalNetwork))(IN_BSTR aInternalNetwork);
+ STDMETHOD(COMGETTER(NATNetwork))(BSTR *aNATNetwork);
+ STDMETHOD(COMSETTER(NATNetwork))(IN_BSTR aNATNetwork);
+ STDMETHOD(COMGETTER(GenericDriver))(BSTR *aGenericDriver);
+ STDMETHOD(COMSETTER(GenericDriver))(IN_BSTR aGenericDriver);
+ STDMETHOD(COMGETTER(CableConnected))(BOOL *aConnected);
+ STDMETHOD(COMSETTER(CableConnected))(BOOL aConnected);
+ STDMETHOD(COMGETTER(TraceEnabled))(BOOL *aEnabled);
+ STDMETHOD(COMSETTER(TraceEnabled))(BOOL aEnabled);
+ STDMETHOD(COMGETTER(LineSpeed))(ULONG *aSpeed);
+ STDMETHOD(COMSETTER(LineSpeed))(ULONG aSpeed);
+ STDMETHOD(COMGETTER(PromiscModePolicy))(NetworkAdapterPromiscModePolicy_T *aPromiscModePolicy);
+ STDMETHOD(COMSETTER(PromiscModePolicy))(NetworkAdapterPromiscModePolicy_T aPromiscModePolicy);
+ STDMETHOD(COMGETTER(TraceFile))(BSTR *aTraceFile);
+ STDMETHOD(COMSETTER(TraceFile))(IN_BSTR aTraceFile);
+ STDMETHOD(COMGETTER(NatDriver))(INATEngine **aNatDriver);
+ STDMETHOD(COMGETTER(BootPriority))(ULONG *aBootPriority);
+ STDMETHOD(COMSETTER(BootPriority))(ULONG aBootPriority);
+ STDMETHOD(COMGETTER(BandwidthGroup))(IBandwidthGroup **aBwGroup);
+ STDMETHOD(COMSETTER(BandwidthGroup))(IBandwidthGroup *aBwGroup);
// INetworkAdapter methods
- STDMETHOD(AttachToNAT)();
- STDMETHOD(AttachToBridgedInterface)();
- STDMETHOD(AttachToInternalNetwork)();
- STDMETHOD(AttachToHostOnlyInterface)();
- STDMETHOD(AttachToVDE)();
- STDMETHOD(Detach)();
+ STDMETHOD(GetProperty)(IN_BSTR aName, BSTR *aValue);
+ STDMETHOD(SetProperty)(IN_BSTR aName, IN_BSTR aValue);
+ STDMETHOD(GetProperties)(IN_BSTR aNames,
+ ComSafeArrayOut(BSTR, aReturnNames),
+ ComSafeArrayOut(BSTR, aReturnValues));
// public methods only for internal purposes
- HRESULT loadSettings(const settings::NetworkAdapter &data);
+ HRESULT loadSettings(BandwidthControl *bwctl, const settings::NetworkAdapter &data);
HRESULT saveSettings(settings::NetworkAdapter &data);
bool isModified();
void rollback();
void commit();
- void copyFrom (NetworkAdapter *aThat);
- void applyDefaults (GuestOSType *aOsType);
+ void copyFrom(NetworkAdapter *aThat);
+ void applyDefaults(GuestOSType *aOsType);
private:
- void detach();
void generateMACAddress();
+ HRESULT updateMacAddress(Utf8Str aMacAddress);
+ void updateBandwidthGroup(BandwidthGroup *aBwGroup);
Machine * const mParent;
const ComObjPtr<NetworkAdapter> mPeer;
diff --git a/src/VBox/Main/include/ParallelPortImpl.h b/src/VBox/Main/include/ParallelPortImpl.h
index aff35ceef..b9e499c01 100644
--- a/src/VBox/Main/include/ParallelPortImpl.h
+++ b/src/VBox/Main/include/ParallelPortImpl.h
@@ -1,4 +1,4 @@
-/* $Id: ParallelPortImpl.h $ */
+/* $Id: ParallelPortImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* VirtualBox COM class implementation.
@@ -38,9 +38,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(ParallelPort)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IParallelPort)
- COM_INTERFACE_ENTRY2 (IDispatch, IParallelPort)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (IParallelPort)
END_COM_MAP()
ParallelPort() {}
diff --git a/src/VBox/Main/include/PciDeviceAttachmentImpl.h b/src/VBox/Main/include/PciDeviceAttachmentImpl.h
index 20f4ff0a8..c2d26b355 100644
--- a/src/VBox/Main/include/PciDeviceAttachmentImpl.h
+++ b/src/VBox/Main/include/PciDeviceAttachmentImpl.h
@@ -1,4 +1,4 @@
-/* $Id: PciDeviceAttachmentImpl.h $ */
+/* $Id: PciDeviceAttachmentImpl.h 35885 2011-02-08 01:20:04Z vboxsync $ */
/** @file
*
@@ -21,6 +21,7 @@
#define ____H_PCIDEVICEATTACHMENTIMPL
#include "VirtualBoxBase.h"
+#include <VBox/settings.h>
class ATL_NO_VTABLE PciAddress :
public VirtualBoxBase,
@@ -34,9 +35,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(PciAddress)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IPciAddress)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IPciAddress)
END_COM_MAP()
PciAddress() { }
@@ -98,22 +97,26 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(PciDeviceAttachment)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IPciDeviceAttachment)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IPciDeviceAttachment)
END_COM_MAP()
PciDeviceAttachment() { }
~PciDeviceAttachment() { }
// public initializer/uninitializer for internal purposes only
- HRESULT init(Machine * aParent,
+ HRESULT init(IMachine * aParent,
const Bstr &aName,
LONG aHostAddess,
LONG aGuestAddress,
BOOL fPhysical);
+
void uninit();
+ // settings
+ HRESULT loadSettings(IMachine * aParent,
+ const settings::HostPciDeviceAttachment& aHpda);
+ HRESULT saveSettings(settings::HostPciDeviceAttachment &data);
+
HRESULT FinalConstruct();
void FinalRelease();
@@ -125,7 +128,7 @@ public:
private:
struct Data;
- Data *m;
+ Data* m;
};
#endif // ____H_PCIDEVICEATTACHMENTIMPL
diff --git a/src/VBox/Main/include/PciRawDevImpl.h b/src/VBox/Main/include/PciRawDevImpl.h
new file mode 100644
index 000000000..89146c256
--- /dev/null
+++ b/src/VBox/Main/include/PciRawDevImpl.h
@@ -0,0 +1,54 @@
+/* $Id: PciRawDevImpl.h 37802 2011-07-06 13:32:15Z vboxsync $ */
+/** @file
+ * VirtualBox Driver interface to raw PCI device
+ */
+
+/*
+ * 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 ____H_PCIRAWDEV
+#define ____H_PCIRAWDEV
+
+#include "VirtualBoxBase.h"
+#include <VBox/vmm/pdmdrv.h>
+
+class Console;
+struct DRVMAINPCIRAWDEV;
+
+class PciRawDev
+{
+ public:
+ PciRawDev(Console *console);
+ virtual ~PciRawDev();
+
+ static const PDMDRVREG DrvReg;
+ struct DRVMAINPCIRAWDEV *mpDrv;
+
+ Console *getParent() const
+ {
+ return mParent;
+ }
+
+ private:
+ static DECLCALLBACK(void *) drvQueryInterface(PPDMIBASE pInterface, const char *pszIID);
+ static DECLCALLBACK(int) drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+ static DECLCALLBACK(void) drvDestruct(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(void) drvReset(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(int) drvDeviceConstructComplete(PPDMIPCIRAWCONNECTOR pInterface, const char *pcszName,
+ uint32_t uHostPciAddress, uint32_t uGuestPciAddress,
+ int rc);
+
+
+ Console * const mParent;
+};
+
+#endif // !____H_PCIRAWDEV
diff --git a/src/VBox/Main/include/Performance.h b/src/VBox/Main/include/Performance.h
index 613d1a887..ee958c81e 100644
--- a/src/VBox/Main/include/Performance.h
+++ b/src/VBox/Main/include/Performance.h
@@ -1,8 +1,6 @@
-/* $Id: Performance.h $ */
-
+/* $Id: Performance.h 36842 2011-04-26 07:54:09Z vboxsync $ */
/** @file
- *
- * VBox Performance Classes declaration.
+ * VirtualBox Main - Performance Classes declaration.
*/
/*
@@ -45,6 +43,7 @@ namespace pm
{
public:
CircularBuffer() : mData(0), mLength(0), mEnd(0), mWrapped(false) {};
+ ~CircularBuffer() { if (mData) RTMemFree(mData); };
void init(ULONG length);
ULONG length();
ULONG getSequenceNumber() { return mSequenceNumber; }
@@ -72,11 +71,11 @@ namespace pm
};
- /* Collector Hardware Abstraction Layer *********************************/
enum {
COLLECT_NONE = 0x0,
COLLECT_CPU_LOAD = 0x1,
- COLLECT_RAM_USAGE = 0x2
+ COLLECT_RAM_USAGE = 0x2,
+ COLLECT_GUEST_STATS = 0x4
};
typedef int HintFlags;
typedef std::pair<RTPROCESS, HintFlags> ProcessFlagsPair;
@@ -91,18 +90,26 @@ namespace pm
{ mHostFlags |= COLLECT_CPU_LOAD; }
void collectHostRamUsage()
{ mHostFlags |= COLLECT_RAM_USAGE; }
+ void collectHostRamVmm()
+ { mHostFlags |= COLLECT_GUEST_STATS; }
void collectProcessCpuLoad(RTPROCESS process)
{ findProcess(process).second |= COLLECT_CPU_LOAD; }
void collectProcessRamUsage(RTPROCESS process)
{ findProcess(process).second |= COLLECT_RAM_USAGE; }
+ void collectGuestStats(RTPROCESS process)
+ { findProcess(process).second |= COLLECT_GUEST_STATS; }
bool isHostCpuLoadCollected() const
{ return (mHostFlags & COLLECT_CPU_LOAD) != 0; }
bool isHostRamUsageCollected() const
{ return (mHostFlags & COLLECT_RAM_USAGE) != 0; }
+ bool isHostRamVmmCollected() const
+ { return (mHostFlags & COLLECT_GUEST_STATS) != 0; }
bool isProcessCpuLoadCollected(RTPROCESS process)
{ return (findProcess(process).second & COLLECT_CPU_LOAD) != 0; }
bool isProcessRamUsageCollected(RTPROCESS process)
{ return (findProcess(process).second & COLLECT_RAM_USAGE) != 0; }
+ bool isGuestStatsCollected(RTPROCESS process)
+ { return (findProcess(process).second & COLLECT_GUEST_STATS) != 0; }
void getProcesses(std::vector<RTPROCESS>& processes) const
{
processes.clear();
@@ -131,10 +138,81 @@ namespace pm
}
};
+ /* Guest Collector Classes *********************************/
+ 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();
+
+ RTPROCESS getProcess() { return mProcess; };
+ ULONG getCpuUser() { return mCpuUser; };
+ ULONG getCpuKernel() { return mCpuKernel; };
+ ULONG getCpuIdle() { return mCpuIdle; };
+ ULONG getMemTotal() { return mMemTotal; };
+ ULONG getMemFree() { return mMemFree; };
+ ULONG getMemBalloon() { return mMemBalloon; };
+ ULONG getMemShared() { return mMemShared; };
+ ULONG getMemCache() { return mMemCache; };
+ ULONG getPageTotal() { return mPageTotal; };
+ ULONG getAllocVMM() { return mAllocVMM; };
+ ULONG getFreeVMM() { return mFreeVMM; };
+ ULONG getBalloonedVMM() { return mBalloonedVMM; };
+ ULONG getSharedVMM() { return mSharedVMM; };
+
+ private:
+ bool mUnregistered;
+ bool mEnabled;
+ bool mValid;
+ Machine *mMachine;
+ RTPROCESS mProcess;
+ ComPtr<IConsole> mConsole;
+ ComPtr<IGuest> mGuest;
+ ULONG mCpuUser;
+ ULONG mCpuKernel;
+ ULONG mCpuIdle;
+ ULONG mMemTotal;
+ ULONG mMemFree;
+ ULONG mMemBalloon;
+ ULONG mMemShared;
+ ULONG mMemCache;
+ ULONG mPageTotal;
+ ULONG mAllocVMM;
+ ULONG mFreeVMM;
+ ULONG mBalloonedVMM;
+ ULONG mSharedVMM;
+ };
+
+ typedef std::list<CollectorGuest*> CollectorGuestList;
+ class CollectorGuestManager
+ {
+ public:
+ CollectorGuestManager() : mVMMStatsProvider(NULL) {};
+ ~CollectorGuestManager() { Assert(mGuests.size() == 0); };
+ void registerGuest(CollectorGuest* pGuest);
+ void unregisterGuest(CollectorGuest* pGuest);
+ CollectorGuest *getVMMStatsProvider() { return mVMMStatsProvider; };
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void destroyUnregistered();
+ private:
+ CollectorGuestList mGuests;
+ CollectorGuest *mVMMStatsProvider;
+ };
+
+ /* Collector Hardware Abstraction Layer *********************************/
class CollectorHAL
{
public:
- CollectorHAL() : mMemAllocVMM(0), mMemFreeVMM(0), mMemBalloonedVMM(0), mMemSharedVMM(0) {};
+ CollectorHAL() {};
virtual ~CollectorHAL() { };
virtual int preCollect(const CollectorHints& /* hints */, uint64_t /* iTick */) { return VINF_SUCCESS; }
/** Returns averaged CPU usage in 1/1000th per cent across all host's CPUs. */
@@ -152,90 +230,6 @@ namespace pm
virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
/** Returns process' CPU usage counter in platform-specific units. */
virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
-
- /** Enable metrics collecting (if applicable) */
- virtual int enable();
- /** Disable metrics collecting (if applicable) */
- virtual int disable();
-
- virtual int setMemHypervisorStats(ULONG memAlloc, ULONG memFree, ULONG memBallooned, ULONG memShared)
- {
- mMemAllocVMM = memAlloc;
- mMemFreeVMM = memFree;
- mMemBalloonedVMM = memBallooned;
- mMemSharedVMM = memShared;
- return S_OK;
- }
-
- virtual void getMemHypervisorStats(ULONG *pMemAlloc, ULONG *pMemFree, ULONG *pMemBallooned, ULONG *pMemShared)
- {
- *pMemAlloc = mMemAllocVMM;
- *pMemFree = mMemFreeVMM;
- *pMemBallooned = mMemBalloonedVMM;
- *pMemShared = mMemSharedVMM;
- }
-
- private:
- ULONG mMemAllocVMM;
- ULONG mMemFreeVMM;
- ULONG mMemBalloonedVMM;
- ULONG mMemSharedVMM;
- };
-
- class CollectorGuestHAL : public CollectorHAL
- {
- public:
- CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL);
- ~CollectorGuestHAL();
-
- virtual int preCollect(const CollectorHints& hints, uint64_t iTick);
-
- /** Enable metrics collecting (if applicable) */
- virtual int enable();
- /** Disable metrics collecting (if applicable) */
- virtual int disable();
-
- /** Return guest cpu absolute load values (0-100). */
- void getGuestCpuLoad(ULONG *pulCpuUser, ULONG *pulCpuKernel, ULONG *pulCpuIdle)
- {
- *pulCpuUser = mCpuUser;
- *pulCpuKernel = mCpuKernel;
- *pulCpuIdle = mCpuIdle;
- }
-
- /** Return guest memory information in KB. */
- void getGuestMemLoad(ULONG *pulMemTotal, ULONG *pulMemFree, ULONG *pulMemBalloon, ULONG *pulMemShared, ULONG *pulMemCache, ULONG *pulPageTotal)
- {
- *pulMemTotal = mMemTotal;
- *pulMemFree = mMemFree;
- *pulMemBalloon = mMemBalloon;
- *pulMemShared = mMemShared;
- *pulMemCache = mMemCache;
- *pulPageTotal = mPageTotal;
- }
-
-
- protected:
- uint32_t cEnabled;
- Machine *mMachine;
- ComPtr<IConsole> mConsole;
- ComPtr<IGuest> mGuest;
- uint64_t mLastTick;
-
- CollectorHAL *mHostHAL;
-
- ULONG mCpuUser;
- ULONG mCpuKernel;
- ULONG mCpuIdle;
- ULONG mMemTotal;
- ULONG mMemFree;
- ULONG mMemBalloon;
- ULONG mMemShared;
- ULONG mMemCache;
- ULONG mPageTotal;
-
- private:
- static uint32_t cVMsEnabled;
};
extern CollectorHAL *createHAL();
@@ -245,7 +239,8 @@ namespace pm
{
public:
BaseMetric(CollectorHAL *hal, const char *name, ComPtr<IUnknown> object)
- : mPeriod(0), mLength(0), mHAL(hal), mName(name), mObject(object), mLastSampleTaken(0), mEnabled(false) {};
+ : mPeriod(0), mLength(0), mHAL(hal), mName(name), mObject(object),
+ mLastSampleTaken(0), mEnabled(false), mUnregistered(false) {};
virtual ~BaseMetric() {};
virtual void init(ULONG period, ULONG length) = 0;
@@ -258,17 +253,11 @@ namespace pm
bool collectorBeat(uint64_t nowAt);
- void enable()
- {
- mEnabled = true;
- mHAL->enable();
- };
- void disable()
- {
- mHAL->disable();
- mEnabled = false;
- };
+ void enable() { mEnabled = true; };
+ void disable() { mEnabled = false; };
+ void unregister() { mUnregistered = true; };
+ bool isUnregistered() { return mUnregistered; };
bool isEnabled() { return mEnabled; };
ULONG getPeriod() { return mPeriod; };
ULONG getLength() { return mLength; };
@@ -284,6 +273,16 @@ namespace pm
ComPtr<IUnknown> mObject;
uint64_t mLastSampleTaken;
bool mEnabled;
+ bool mUnregistered;
+ };
+
+ class BaseGuestMetric : public BaseMetric
+ {
+ public:
+ BaseGuestMetric(CollectorGuest *cguest, const char *name, ComPtr<IUnknown> object)
+ : BaseMetric(NULL, name, object), mCGuest(cguest) {};
+ protected:
+ CollectorGuest *mCGuest;
};
class HostCpuLoad : public BaseMetric
@@ -342,7 +341,7 @@ namespace pm
class HostRamUsage : public BaseMetric
{
public:
- HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
+ HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
: BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available) {};
~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; };
@@ -362,8 +361,10 @@ namespace pm
class HostRamVmm : public BaseMetric
{
public:
- HostRamVmm(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM)
- : BaseMetric(hal, "RAM/VMM", object), mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM) {};
+ HostRamVmm(CollectorGuestManager *gm, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM)
+ : BaseMetric(NULL, "RAM/VMM", object), mCollectorGuestManager(gm),
+ mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM),
+ mAllocCurrent(0), mFreeCurrent(0), mBalloonedCurrent(0), mSharedCurrent(0) {};
~HostRamVmm() { delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; delete mSharedVMM; };
void init(ULONG period, ULONG length);
@@ -373,11 +374,17 @@ namespace pm
ULONG getMinValue() { return 0; };
ULONG getMaxValue() { return INT32_MAX; };
ULONG getScale() { return 1; }
+
private:
- SubMetric *mAllocVMM;
- SubMetric *mFreeVMM;
- SubMetric *mBalloonVMM;
- SubMetric *mSharedVMM;
+ CollectorGuestManager *mCollectorGuestManager;
+ SubMetric *mAllocVMM;
+ SubMetric *mFreeVMM;
+ SubMetric *mBalloonVMM;
+ SubMetric *mSharedVMM;
+ ULONG mAllocCurrent;
+ ULONG mFreeCurrent;
+ ULONG mBalloonedCurrent;
+ ULONG mSharedCurrent;
};
class MachineCpuLoad : public BaseMetric
@@ -433,11 +440,11 @@ namespace pm
};
- class GuestCpuLoad : public BaseMetric
+ class GuestCpuLoad : public BaseGuestMetric
{
public:
- GuestCpuLoad(CollectorGuestHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
- : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle), mGuestHAL(hal) {};
+ GuestCpuLoad(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
+ : BaseGuestMetric(cguest, "Guest/CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
void init(ULONG period, ULONG length);
@@ -451,14 +458,13 @@ namespace pm
SubMetric *mUser;
SubMetric *mKernel;
SubMetric *mIdle;
- CollectorGuestHAL *mGuestHAL;
};
- class GuestRamUsage : public BaseMetric
+ class GuestRamUsage : public BaseGuestMetric
{
public:
- GuestRamUsage(CollectorGuestHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal)
- : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared), mGuestHAL(hal) {};
+ GuestRamUsage(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal)
+ : BaseGuestMetric(cguest, "Guest/RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared) {};
~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mShared; delete mCache; delete mPagedTotal; };
void init(ULONG period, ULONG length);
@@ -470,7 +476,6 @@ namespace pm
ULONG getScale() { return 1; }
private:
SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
- CollectorGuestHAL *mGuestHAL;
};
/* Aggregate Functions **************************************************/
@@ -536,7 +541,7 @@ namespace pm
void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
private:
- iprt::MiniString mName;
+ RTCString mName;
BaseMetric *mBaseMetric;
SubMetric *mSubMetric;
Aggregate *mAggregate;
@@ -551,12 +556,12 @@ namespace pm
ComSafeArrayIn(IUnknown * , objects));
static bool patternMatch(const char *pszPat, const char *pszName,
bool fSeenColon = false);
- bool match(const ComPtr<IUnknown> object, const iprt::MiniString &name) const;
+ bool match(const ComPtr<IUnknown> object, const RTCString &name) const;
private:
void init(ComSafeArrayIn(IN_BSTR, metricNames),
ComSafeArrayIn(IUnknown * , objects));
- typedef std::pair<const ComPtr<IUnknown>, const iprt::MiniString> FilterElement;
+ typedef std::pair<const ComPtr<IUnknown>, const RTCString> FilterElement;
typedef std::list<FilterElement> ElementList;
ElementList mElements;
diff --git a/src/VBox/Main/include/PerformanceImpl.h b/src/VBox/Main/include/PerformanceImpl.h
index b7151faa3..1d6618afd 100644
--- a/src/VBox/Main/include/PerformanceImpl.h
+++ b/src/VBox/Main/include/PerformanceImpl.h
@@ -1,4 +1,4 @@
-/* $Id: PerformanceImpl.h $ */
+/* $Id: PerformanceImpl.h 36128 2011-03-02 05:44:04Z vboxsync $ */
/** @file
*
@@ -35,6 +35,8 @@ namespace pm
class Metric;
class BaseMetric;
class CollectorHAL;
+ class CollectorGuest;
+ class CollectorGuestManager;
}
#undef min
@@ -57,8 +59,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP (PerformanceMetric)
- COM_INTERFACE_ENTRY (IPerformanceMetric)
- COM_INTERFACE_ENTRY (IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (IPerformanceMetric)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (PerformanceMetric)
@@ -125,9 +126,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(PerformanceCollector)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IPerformanceCollector)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IPerformanceCollector)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (PerformanceCollector)
@@ -176,6 +175,8 @@ public:
void registerMetric (pm::Metric *metric);
void unregisterBaseMetricsFor (const ComPtr<IUnknown> &object);
void unregisterMetricsFor (const ComPtr<IUnknown> &object);
+ void registerGuest(pm::CollectorGuest* pGuest);
+ void unregisterGuest(pm::CollectorGuest* pGuest);
void suspendSampling();
void resumeSampling();
@@ -183,7 +184,8 @@ public:
// public methods for internal purposes only
// (ensure there is a caller and a read lock before calling them!)
- pm::CollectorHAL *getHAL() { return m.hal; };
+ pm::CollectorHAL *getHAL() { return m.hal; };
+ pm::CollectorGuestManager *getGuestManager() { return m.gm; };
private:
HRESULT toIPerformanceMetric(pm::Metric *src, IPerformanceMetric **dst);
@@ -206,10 +208,11 @@ private:
{
Data() : hal(0) {};
- BaseMetricList baseMetrics;
- MetricList metrics;
- RTTIMERLR sampler;
- pm::CollectorHAL *hal;
+ BaseMetricList baseMetrics;
+ MetricList metrics;
+ RTTIMERLR sampler;
+ pm::CollectorHAL *hal;
+ pm::CollectorGuestManager *gm;
};
Data m;
diff --git a/src/VBox/Main/include/ProgressCombinedImpl.h b/src/VBox/Main/include/ProgressCombinedImpl.h
index 9faad5487..ab733b759 100644
--- a/src/VBox/Main/include/ProgressCombinedImpl.h
+++ b/src/VBox/Main/include/ProgressCombinedImpl.h
@@ -1,4 +1,4 @@
-/* $Id: ProgressCombinedImpl.h $ */
+/* $Id: ProgressCombinedImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
* VirtualBox COM class implementation
@@ -76,9 +76,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP (CombinedProgress)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IProgress)
- COM_INTERFACE_ENTRY2 (IDispatch, IProgress)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (IProgress)
END_COM_MAP()
HRESULT FinalConstruct();
diff --git a/src/VBox/Main/include/ProgressImpl.h b/src/VBox/Main/include/ProgressImpl.h
index 737e8da58..aefb9f333 100644
--- a/src/VBox/Main/include/ProgressImpl.h
+++ b/src/VBox/Main/include/ProgressImpl.h
@@ -1,4 +1,4 @@
-/* $Id: ProgressImpl.h $ */
+/* $Id: ProgressImpl.h 37069 2011-05-13 12:41:38Z vboxsync $ */
/** @file
*
* VirtualBox COM class implementation
@@ -142,9 +142,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP (Progress)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IProgress)
- COM_INTERFACE_ENTRY2 (IDispatch, IProgress)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (IProgress)
END_COM_MAP()
HRESULT FinalConstruct();
@@ -243,6 +241,7 @@ public:
// IProgress methods
STDMETHOD(WaitForCompletion)(LONG aTimeout);
STDMETHOD(WaitForOperationCompletion)(ULONG aOperation, LONG aTimeout);
+ STDMETHOD(WaitForAsyncProgressCompletion)(IProgress *pProgressAsync);
STDMETHOD(Cancel)();
STDMETHOD(SetCurrentOperationProgress)(ULONG aPercent);
diff --git a/src/VBox/Main/include/ProgressProxyImpl.h b/src/VBox/Main/include/ProgressProxyImpl.h
index 3c64482c9..8271f1cfa 100644
--- a/src/VBox/Main/include/ProgressProxyImpl.h
+++ b/src/VBox/Main/include/ProgressProxyImpl.h
@@ -1,4 +1,4 @@
-/* $Id: ProgressProxyImpl.h $ */
+/* $Id: ProgressProxyImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* IProgress implementation for Machine::openRemoteSession in VBoxSVC.
*/
@@ -37,9 +37,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(ProgressProxy)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IProgress)
- COM_INTERFACE_ENTRY2(IDispatch, IProgress)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (IProgress)
END_COM_MAP()
HRESULT FinalConstruct();
diff --git a/src/VBox/Main/include/RemoteUSBDeviceImpl.h b/src/VBox/Main/include/RemoteUSBDeviceImpl.h
index d25668190..5ac7e40a6 100644
--- a/src/VBox/Main/include/RemoteUSBDeviceImpl.h
+++ b/src/VBox/Main/include/RemoteUSBDeviceImpl.h
@@ -1,4 +1,4 @@
-/* $Id: RemoteUSBDeviceImpl.h $ */
+/* $Id: RemoteUSBDeviceImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -39,10 +39,8 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP (RemoteUSBDevice)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
COM_INTERFACE_ENTRY (IHostUSBDevice)
- COM_INTERFACE_ENTRY (IUSBDevice)
- COM_INTERFACE_ENTRY2 (IDispatch, IUSBDevice)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (IUSBDevice)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (RemoteUSBDevice)
diff --git a/src/VBox/Main/include/SerialPortImpl.h b/src/VBox/Main/include/SerialPortImpl.h
index cf8ba25f4..7b3775d64 100644
--- a/src/VBox/Main/include/SerialPortImpl.h
+++ b/src/VBox/Main/include/SerialPortImpl.h
@@ -1,4 +1,4 @@
-/* $Id: SerialPortImpl.h $ */
+/* $Id: SerialPortImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -41,9 +41,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(SerialPort)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (ISerialPort)
- COM_INTERFACE_ENTRY2 (IDispatch, ISerialPort)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (ISerialPort)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (SerialPort)
diff --git a/src/VBox/Main/include/SessionImpl.h b/src/VBox/Main/include/SessionImpl.h
index cf82f5948..43ed62927 100644
--- a/src/VBox/Main/include/SessionImpl.h
+++ b/src/VBox/Main/include/SessionImpl.h
@@ -33,6 +33,9 @@
# define VBOX_WITH_SYS_V_IPC_SESSION_WATCHER
#endif
+#ifdef RT_OS_WINDOWS
+[threading(free)]
+#endif
class ATL_NO_VTABLE Session :
public VirtualBoxBase,
VBOX_SCRIPTABLE_IMPL(ISession),
@@ -53,11 +56,9 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(Session)
- COM_INTERFACE_ENTRY2(IDispatch, ISession)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(ISession)
COM_INTERFACE_ENTRY2(IDispatch, IInternalSessionControl)
COM_INTERFACE_ENTRY(IInternalSessionControl)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(ISession)
END_COM_MAP()
HRESULT FinalConstruct();
@@ -97,6 +98,7 @@ public:
STDMETHOD(OnUSBDeviceDetach)(IN_BSTR aId, IVirtualBoxErrorInfo *aError);
STDMETHOD(OnShowWindow)(BOOL aCheck, BOOL *aCanShow, LONG64 *aWinId);
STDMETHOD(OnBandwidthGroupChange)(IBandwidthGroup *aBandwidthGroup);
+ STDMETHOD(OnStorageDeviceChange)(IMediumAttachment *aMediumAttachment, BOOL aRemove);
STDMETHOD(AccessGuestProperty)(IN_BSTR aName, IN_BSTR aValue, IN_BSTR aFlags,
BOOL aIsSetter, BSTR *aRetValue, LONG64 *aRetTimestamp, BSTR *aRetFlags);
STDMETHOD(EnumerateGuestProperties)(IN_BSTR aPatterns,
diff --git a/src/VBox/Main/include/SharedFolderImpl.h b/src/VBox/Main/include/SharedFolderImpl.h
index 43ebfaf97..a4ee94acb 100644
--- a/src/VBox/Main/include/SharedFolderImpl.h
+++ b/src/VBox/Main/include/SharedFolderImpl.h
@@ -36,9 +36,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(SharedFolder)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (ISharedFolder)
- COM_INTERFACE_ENTRY2 (IDispatch, ISharedFolder)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (ISharedFolder)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (SharedFolder)
diff --git a/src/VBox/Main/include/SnapshotImpl.h b/src/VBox/Main/include/SnapshotImpl.h
index 0dc5a08ba..f38f6d868 100644
--- a/src/VBox/Main/include/SnapshotImpl.h
+++ b/src/VBox/Main/include/SnapshotImpl.h
@@ -1,4 +1,4 @@
-/* $Id: SnapshotImpl.h $ */
+/* $Id: SnapshotImpl.h 37449 2011-06-14 16:34:16Z vboxsync $ */
/** @file
*
@@ -43,9 +43,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(Snapshot)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (ISnapshot)
- COM_INTERFACE_ENTRY2 (IDispatch, ISnapshot)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (ISnapshot)
END_COM_MAP()
Snapshot()
@@ -84,6 +82,7 @@ public:
STDMETHOD(COMGETTER(Children)) (ComSafeArrayOut (ISnapshot *, aChildren));
// ISnapshot methods
+ STDMETHOD(GetChildrenCount)(ULONG* count);
// public methods only for internal purposes
@@ -99,8 +98,7 @@ public:
const ComObjPtr<Snapshot>& getParent() const;
const ComObjPtr<Snapshot> getFirstChild() const;
- const Utf8Str& stateFilePath() const;
- HRESULT deleteStateFile();
+ const Utf8Str& getStateFilePath() const;
ULONG getChildrenCount();
ULONG getAllChildrenCount();
@@ -120,6 +118,9 @@ public:
void updateSavedStatePathsImpl(const Utf8Str &strOldPath,
const Utf8Str &strNewPath);
+ bool sharesSavedStateFile(const Utf8Str &strPath,
+ Snapshot *pSnapshotToIgnore);
+
HRESULT saveSnapshot(settings::Snapshot &data, bool aAttrsOnly);
HRESULT saveSnapshotImpl(settings::Snapshot &data, bool aAttrsOnly);
diff --git a/src/VBox/Main/include/StorageControllerImpl.h b/src/VBox/Main/include/StorageControllerImpl.h
index 40f44c84e..38cd9ae2a 100644
--- a/src/VBox/Main/include/StorageControllerImpl.h
+++ b/src/VBox/Main/include/StorageControllerImpl.h
@@ -1,4 +1,4 @@
-/* $Id: StorageControllerImpl.h $ */
+/* $Id: StorageControllerImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -35,9 +35,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(StorageController)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IStorageController)
- COM_INTERFACE_ENTRY2 (IDispatch, IStorageController)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (IStorageController)
END_COM_MAP()
StorageController() { };
diff --git a/src/VBox/Main/include/SystemPropertiesImpl.h b/src/VBox/Main/include/SystemPropertiesImpl.h
index 45685e014..1a127bdc7 100644
--- a/src/VBox/Main/include/SystemPropertiesImpl.h
+++ b/src/VBox/Main/include/SystemPropertiesImpl.h
@@ -1,4 +1,4 @@
-/* $Id: SystemPropertiesImpl.h $ */
+/* $Id: SystemPropertiesImpl.h 35761 2011-01-28 13:19:26Z vboxsync $ */
/** @file
*
@@ -45,9 +45,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(SystemProperties)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(ISystemProperties)
- COM_INTERFACE_ENTRY2(IDispatch, ISystemProperties)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (ISystemProperties)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR(SystemProperties)
@@ -68,7 +66,6 @@ public:
STDMETHOD(COMGETTER(MaxGuestCPUCount))(ULONG *maxCPUCount);
STDMETHOD(COMGETTER(MaxGuestMonitors))(ULONG *maxMonitors);
STDMETHOD(COMGETTER(InfoVDSize))(LONG64 *infoVDSize);
- STDMETHOD(COMGETTER(NetworkAdapterCount))(ULONG *count);
STDMETHOD(COMGETTER(SerialPortCount))(ULONG *count);
STDMETHOD(COMGETTER(ParallelPortCount))(ULONG *count);
STDMETHOD(COMGETTER(MaxBootPosition))(ULONG *aMaxBootPosition);
@@ -95,6 +92,8 @@ public:
STDMETHOD(COMSETTER(LogHistoryCount))(ULONG count);
STDMETHOD(COMGETTER(DefaultAudioDriver))(AudioDriverType_T *aAudioDriver);
+ STDMETHOD(GetMaxNetworkAdapters)(ChipsetType_T aChipset, ULONG *aMaxInstances);
+ STDMETHOD(GetMaxNetworkAdaptersOfType)(ChipsetType_T aChipset, NetworkAttachmentType_T aType, ULONG *aMaxInstances);
STDMETHOD(GetMaxDevicesPerPortForStorageBus)(StorageBus_T aBus, ULONG *aMaxDevicesPerPort);
STDMETHOD(GetMinPortCountForStorageBus)(StorageBus_T aBus, ULONG *aMinPortCount);
STDMETHOD(GetMaxPortCountForStorageBus)(StorageBus_T aBus, ULONG *aMaxPortCount);
diff --git a/src/VBox/Main/include/USBControllerImpl.h b/src/VBox/Main/include/USBControllerImpl.h
index c135c4248..b6584b14a 100644
--- a/src/VBox/Main/include/USBControllerImpl.h
+++ b/src/VBox/Main/include/USBControllerImpl.h
@@ -1,4 +1,4 @@
-/* $Id: USBControllerImpl.h $ */
+/* $Id: USBControllerImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -42,9 +42,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(USBController)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IUSBController)
- COM_INTERFACE_ENTRY2 (IDispatch, IUSBController)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (IUSBController)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (USBController)
diff --git a/src/VBox/Main/include/USBDeviceFilterImpl.h b/src/VBox/Main/include/USBDeviceFilterImpl.h
index a6d4c63fe..56cfde57d 100644
--- a/src/VBox/Main/include/USBDeviceFilterImpl.h
+++ b/src/VBox/Main/include/USBDeviceFilterImpl.h
@@ -1,4 +1,4 @@
-/* $Id: USBDeviceFilterImpl.h $ */
+/* $Id: USBDeviceFilterImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* Declaration of USBDeviceFilter and HostUSBDeviceFilter.
*/
@@ -73,9 +73,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(USBDeviceFilter)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IUSBDeviceFilter)
- COM_INTERFACE_ENTRY2 (IDispatch, IUSBDeviceFilter)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (IUSBDeviceFilter)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (USBDeviceFilter)
@@ -179,10 +177,8 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(HostUSBDeviceFilter)
- COM_INTERFACE_ENTRY(IDispatch)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY(IUSBDeviceFilter)
- COM_INTERFACE_ENTRY(IHostUSBDeviceFilter)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IHostUSBDeviceFilter)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (HostUSBDeviceFilter)
diff --git a/src/VBox/Main/include/USBDeviceImpl.h b/src/VBox/Main/include/USBDeviceImpl.h
index d816f34ac..3d66a60c8 100644
--- a/src/VBox/Main/include/USBDeviceImpl.h
+++ b/src/VBox/Main/include/USBDeviceImpl.h
@@ -1,4 +1,4 @@
-/* $Id: USBDeviceImpl.h $ */
+/* $Id: USBDeviceImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* Header file for the OUSBDevice (IUSBDevice) class, VBoxC.
@@ -38,9 +38,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(OUSBDevice)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IUSBDevice)
- COM_INTERFACE_ENTRY2 (IDispatch, IUSBDevice)
+ VBOX_DEFAULT_INTERFACE_ENTRIES (IUSBDevice)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (OUSBDevice)
diff --git a/src/VBox/Main/include/USBGetDevices.h b/src/VBox/Main/include/USBGetDevices.h
index 65f9e6651..082bda9c8 100644
--- a/src/VBox/Main/include/USBGetDevices.h
+++ b/src/VBox/Main/include/USBGetDevices.h
@@ -1,4 +1,4 @@
-/* $Id: USBGetDevices.h $ */
+/* $Id: USBGetDevices.h 37624 2011-06-24 08:57:35Z vboxsync $ */
/** @file
* VirtualBox Linux host USB device enumeration.
*/
@@ -74,38 +74,23 @@ static inline void deviceListFree(PUSBDEVICE *ppHead)
RT_C_DECLS_BEGIN
-/**
- * Check whether a USB device tree root is usable
- * @param pcszRoot the path to the root of the device tree
- * @param fIsDeviceNodes whether this is a device node (or usbfs) tree
- * @note returns a pointer into a static array so it will stay valid
- */
extern bool USBProxyLinuxCheckDeviceRoot(const char *pcszRoot,
bool fIsDeviceNodes);
#ifdef UNIT_TEST
-/**
- * Specify the list of devices that will appear to be available through
- * usbfs during unit testing (of USBProxyLinuxGetDevices)
- * @param pacszDeviceAddresses NULL terminated array of usbfs device addresses
- */
+void TestUSBSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible,
+ const char *pcszDevicesRoot, bool fDevicesAccessible,
+ int rcMethodInitResult);
+void TestUSBSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot);
+#endif
+
+extern int USBProxyLinuxChooseMethod(bool *pfUsingUsbfsDevices,
+ const char **ppcszDevicesRoot);
+#ifdef UNIT_TEST
extern void TestUSBSetAvailableUsbfsDevices(const char **pacszDeviceAddresses);
-/**
- * Specify the list of files that access will report as accessible (at present
- * we only do accessible or not accessible) during unit testing (of
- * USBProxyLinuxGetDevices)
- * @param pacszAccessibleFiles NULL terminated array of file paths to be
- * reported accessible
- */
extern void TestUSBSetAccessibleFiles(const char **pacszAccessibleFiles);
#endif
-/**
- * Get the list of USB devices supported by the system. Should be freed using
- * @a deviceFree or something equivalent.
- * @param pcszDevicesRoot the path to the root of the device tree
- * @param fUseSysfs whether to use sysfs (or usbfs) for enumeration
- */
extern PUSBDEVICE USBProxyLinuxGetDevices(const char *pcszDevicesRoot,
bool fUseSysfs);
diff --git a/src/VBox/Main/include/USBProxyService.h b/src/VBox/Main/include/USBProxyService.h
index 296c11932..3ea4441b0 100644
--- a/src/VBox/Main/include/USBProxyService.h
+++ b/src/VBox/Main/include/USBProxyService.h
@@ -1,4 +1,4 @@
-/* $Id: USBProxyService.h $ */
+/* $Id: USBProxyService.h 37618 2011-06-23 17:16:39Z vboxsync $ */
/** @file
* VirtualBox USB Proxy Service (base) class.
*/
@@ -210,35 +210,6 @@ public:
virtual int captureDevice(HostUSBDevice *aDevice);
virtual int releaseDevice(HostUSBDevice *aDevice);
-# ifdef UNIT_TEST
- /* Functions for setting our unit test mock functions. Not quite sure if
- * it is good form to mix test and production code like this, but it seems
- * cleaner to me than tying the unit test to implementation details of the
- * class. */
- /** Select which access methods will be available to the @a init method
- * during unit testing, and (hack!) what return code it will see from
- * the access method-specific initialisation. */
- void testSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible,
- const char *pcszDevicesRoot, bool fDevicesAccessible,
- int rcMethodInitResult)
- {
- mpcszTestUsbfsRoot = pcszUsbfsRoot;
- mfTestUsbfsAccessible = fUsbfsAccessible;
- mpcszTestDevicesRoot = pcszDevicesRoot;
- mfTestDevicesAccessible = fDevicesAccessible;
- mrcTestMethodInitResult = rcMethodInitResult;
- }
- /** Specify the environment that the @a init method will see during unit
- * testing. */
- void testSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot)
- {
- mpcszTestEnvUsb = pcszEnvUsb;
- mpcszTestEnvUsbRoot = pcszEnvUsbRoot;
- }
- bool testGetUsingUsbfs(void) { return mUsingUsbfsDevices; }
- const char *testGetDevicesRoot(void) { return mDevicesRoot.c_str(); }
-# endif
-
protected:
int initUsbfs(void);
int initSysfs(void);
@@ -255,11 +226,11 @@ private:
private:
/** File handle to the '/proc/bus/usb/devices' file. */
- RTFILE mFile;
+ RTFILE mhFile;
/** Pipe used to interrupt wait(), the read end. */
- RTFILE mWakeupPipeR;
+ RTPIPE mhWakeupPipeR;
/** Pipe used to interrupt wait(), the write end. */
- RTFILE mWakeupPipeW;
+ RTPIPE mhWakeupPipeW;
/** The root of usbfs. */
Utf8Str mDevicesRoot;
/** Whether we're using <mUsbfsRoot>/devices or /sys/whatever. */
@@ -270,22 +241,6 @@ private:
/** Object used for polling for hotplug events from hal. */
VBoxMainHotplugWaiter *mpWaiter;
# endif
-# ifdef UNIT_TEST
- /** The path we pretend the usbfs root is located at, or NULL. */
- const char *mpcszTestUsbfsRoot;
- /** Should usbfs be accessible to the current user? */
- bool mfTestUsbfsAccessible;
- /** The path we pretend the device node tree root is located at, or NULL. */
- const char *mpcszTestDevicesRoot;
- /** Should the device node tree be accessible to the current user? */
- bool mfTestDevicesAccessible;
- /** The result of the usbfs/inotify-specific init */
- int mrcTestMethodInitResult;
- /** The value of the VBOX_USB environment variable. */
- const char *mpcszTestEnvUsb;
- /** The value of the VBOX_USB_ROOT environment variable. */
- const char *mpcszTestEnvUsbRoot;
-# endif
};
# endif /* RT_OS_LINUX */
diff --git a/src/VBox/Main/include/VFSExplorerImpl.h b/src/VBox/Main/include/VFSExplorerImpl.h
index 49f7e5287..3869d7b12 100644
--- a/src/VBox/Main/include/VFSExplorerImpl.h
+++ b/src/VBox/Main/include/VFSExplorerImpl.h
@@ -1,4 +1,4 @@
-/* $Id: VFSExplorerImpl.h $ */
+/* $Id: VFSExplorerImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -33,16 +33,14 @@ class ATL_NO_VTABLE VFSExplorer :
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(VFSExplorer)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IVFSExplorer)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IVFSExplorer)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR(VFSExplorer)
// public initializer/uninitializer for internal purposes only
- HRESULT FinalConstruct() { return S_OK; }
- void FinalRelease() { uninit(); }
+ HRESULT FinalConstruct() { return BaseFinalConstruct(); }
+ void FinalRelease() { uninit(); BaseFinalRelease(); }
HRESULT init(VFSType_T aType, Utf8Str aFilePath, Utf8Str aHostname, Utf8Str aUsername, Utf8Str aPassword, VirtualBox *aVirtualBox);
void uninit();
diff --git a/src/VBox/Main/include/VRDEServerImpl.h b/src/VBox/Main/include/VRDEServerImpl.h
index 5061bdd4d..a876928f6 100644
--- a/src/VBox/Main/include/VRDEServerImpl.h
+++ b/src/VBox/Main/include/VRDEServerImpl.h
@@ -1,4 +1,4 @@
-/* $Id: VRDEServerImpl.h $ */
+/* $Id: VRDEServerImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -50,9 +50,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(VRDEServer)
- COM_INTERFACE_ENTRY (ISupportErrorInfo)
- COM_INTERFACE_ENTRY (IVRDEServer)
- COM_INTERFACE_ENTRY2 (IDispatch, IVRDEServer)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IVRDEServer)
END_COM_MAP()
DECLARE_EMPTY_CTOR_DTOR (VRDEServer)
diff --git a/src/VBox/Main/include/VirtualBoxBase.h b/src/VBox/Main/include/VirtualBoxBase.h
index 98ed8ce58..f16f48e3e 100644
--- a/src/VBox/Main/include/VirtualBoxBase.h
+++ b/src/VBox/Main/include/VirtualBoxBase.h
@@ -323,6 +323,17 @@ public:
} while (0)
/**
+ * Checks that the pointer argument is a valid pointer or NULL and returns
+ * E_INVALIDARG + extended error info on failure.
+ * @param arg Input pointer-type argument (strings, interface pointers...)
+ */
+#define CheckComArgMaybeNull(arg) \
+ do { \
+ if (RT_UNLIKELY(!RT_VALID_PTR(arg) && (arg) != NULL)) \
+ return setError(E_INVALIDARG, tr("Argument %s is an invalid pointer"), #arg); \
+ } while (0)
+
+/**
* Checks that safe array argument is not NULL and returns E_INVALIDARG +
* extended error info on failure.
* @param arg Input safe array argument (strings, interface pointers...)
@@ -637,6 +648,29 @@ class ATL_NO_VTABLE VirtualBoxBase
, public ISupportErrorInfo
#endif
{
+protected:
+#ifdef RT_OS_WINDOWS
+ CComPtr <IUnknown> m_pUnkMarshaler;
+#endif
+
+ HRESULT BaseFinalConstruct()
+ {
+#ifdef RT_OS_WINDOWS
+ return CoCreateFreeThreadedMarshaler(this, //GetControllingUnknown(),
+ &m_pUnkMarshaler.p);
+#else
+ return S_OK;
+#endif
+ }
+
+ void BaseFinalRelease()
+ {
+#ifdef RT_OS_WINDOWS
+ m_pUnkMarshaler.Release();
+#endif
+ }
+
+
public:
enum State { NotReady, Ready, InInit, InUninit, InitFailed, Limited };
diff --git a/src/VBox/Main/include/VirtualBoxClientImpl.h b/src/VBox/Main/include/VirtualBoxClientImpl.h
index 5a30108d8..266c0061d 100644
--- a/src/VBox/Main/include/VirtualBoxClientImpl.h
+++ b/src/VBox/Main/include/VirtualBoxClientImpl.h
@@ -1,4 +1,4 @@
-/* $Id: VirtualBoxClientImpl.h $ */
+/* $Id: VirtualBoxClientImpl.h 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* Header file for the VirtualBoxClient (IVirtualBoxClient) class, VBoxC.
@@ -45,9 +45,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(VirtualBoxClient)
- COM_INTERFACE_ENTRY2(IDispatch, IVirtualBoxClient)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IVirtualBoxClient)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IVirtualBoxClient)
END_COM_MAP()
HRESULT FinalConstruct();
diff --git a/src/VBox/Main/include/VirtualBoxImpl.h b/src/VBox/Main/include/VirtualBoxImpl.h
index 5886c4b2b..2d3efb651 100644
--- a/src/VBox/Main/include/VirtualBoxImpl.h
+++ b/src/VBox/Main/include/VirtualBoxImpl.h
@@ -1,10 +1,10 @@
-/* $Id: VirtualBoxImpl.h $ */
+/* $Id: VirtualBoxImpl.h 37985 2011-07-15 15:04:39Z vboxsync $ */
/** @file
* VirtualBox COM class implementation
*/
/*
- * 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;
@@ -56,7 +56,6 @@ namespace settings
class MainConfigFile;
struct MediaRegistry;
}
-
class ATL_NO_VTABLE VirtualBox :
public VirtualBoxBase,
VBOX_SCRIPTABLE_IMPL(IVirtualBox)
@@ -82,9 +81,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(VirtualBox)
- COM_INTERFACE_ENTRY2(IDispatch, IVirtualBox)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IVirtualBox)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IVirtualBox)
END_COM_MAP()
// to postpone generation of the default ctor/dtor
@@ -106,6 +103,7 @@ public:
STDMETHOD(COMGETTER(Version)) (BSTR *aVersion);
STDMETHOD(COMGETTER(Revision)) (ULONG *aRevision);
STDMETHOD(COMGETTER(PackageType)) (BSTR *aPackageType);
+ STDMETHOD(COMGETTER(APIVersion)) (BSTR *aAPIVersion);
STDMETHOD(COMGETTER(HomeFolder)) (BSTR *aHomeFolder);
STDMETHOD(COMGETTER(SettingsFilePath)) (BSTR *aSettingsFilePath);
STDMETHOD(COMGETTER(Host)) (IHost **aHost);
@@ -121,6 +119,8 @@ public:
STDMETHOD(COMGETTER(DHCPServers)) (ComSafeArrayOut(IDHCPServer *, aDHCPServers));
STDMETHOD(COMGETTER(EventSource)) (IEventSource ** aEventSource);
STDMETHOD(COMGETTER(ExtensionPackManager)) (IExtPackManager **aExtPackManager);
+ STDMETHOD(COMGETTER(InternalNetworks)) (ComSafeArrayOut(BSTR, aInternalNetworks));
+ STDMETHOD(COMGETTER(GenericNetworkDrivers)) (ComSafeArrayOut(BSTR, aGenericNetworkDrivers));
/* IVirtualBox methods */
STDMETHOD(ComposeMachineFilename) (IN_BSTR aName, IN_BSTR aBaseFolder, BSTR *aFilename);
@@ -141,6 +141,7 @@ public:
STDMETHOD(OpenMedium)(IN_BSTR aLocation,
DeviceType_T deviceType,
AccessMode_T accessMode,
+ BOOL fForceNewUuid,
IMedium **aMedium);
STDMETHOD(FindMedium)(IN_BSTR aLocation,
DeviceType_T deviceType,
@@ -191,7 +192,7 @@ public:
void updateClientWatcher();
void onMachineStateChange(const Guid &aId, MachineState_T aState);
- void onMachineDataChange(const Guid &aId);
+ void onMachineDataChange(const Guid &aId, BOOL aTemporary = FALSE);
BOOL onExtraDataCanChange(const Guid &aId, IN_BSTR aKey, IN_BSTR aValue,
Bstr &aError);
void onExtraDataChange(const Guid &aId, IN_BSTR aKey, IN_BSTR aValue);
@@ -277,7 +278,7 @@ public:
const Utf8Str &strMachineFolder);
HRESULT saveSettings();
- void addGuidToListUniquely(GuidList &llRegistriesThatNeedSaving, const Guid &uuid);
+ static void addGuidToListUniquely(GuidList &llRegistriesThatNeedSaving, const Guid &uuid);
HRESULT saveRegistries(const GuidList &llRegistriesThatNeedSaving);
static HRESULT ensureFilePathExists(const Utf8Str &strFileName);
@@ -315,6 +316,7 @@ private:
static Bstr sVersion;
static ULONG sRevision;
static Bstr sPackageType;
+ static Bstr sAPIVersion;
static DECLCALLBACK(int) ClientWatcher (RTTHREAD thread, void *pvUser);
static DECLCALLBACK(int) AsyncEventHandler (RTTHREAD thread, void *pvUser);
diff --git a/src/VBox/Main/include/ovfreader.h b/src/VBox/Main/include/ovfreader.h
index 5ae516504..ee5afb807 100644
--- a/src/VBox/Main/include/ovfreader.h
+++ b/src/VBox/Main/include/ovfreader.h
@@ -1,8 +1,8 @@
-/* $Id: ovfreader.h $ */
+/* $Id: ovfreader.h 36527 2011-04-04 13:16:09Z vboxsync $ */
/** @file
- * OVF reader declarations.
+ * VirtualBox Main - OVF reader declarations.
*
- * Depends only on IPRT, including the iprt::MiniString and IPRT XML classes.
+ * Depends only on IPRT, including the RTCString and IPRT XML classes.
*/
/*
@@ -159,23 +159,23 @@ enum CIMOSType_T
struct DiskImage
{
// fields from /DiskSection/Disk
- iprt::MiniString strDiskId; // value from DiskSection/Disk/@diskId
+ RTCString strDiskId; // value from DiskSection/Disk/@diskId
int64_t iCapacity; // value from DiskSection/Disk/@capacity;
// (maximum size for dynamic images, I guess; we always translate this to bytes)
int64_t iPopulatedSize; // optional value from DiskSection/Disk/@populatedSize
// (actual used size of disk, always in bytes; can be an estimate of used disk
// space, but cannot be larger than iCapacity; -1 if not set)
- iprt::MiniString strFormat; // value from DiskSection/Disk/@format
+ RTCString strFormat; // value from DiskSection/Disk/@format
// typically http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized
- iprt::MiniString uuidVbox; // optional; if the file was exported by VirtualBox >= 3.2,
+ RTCString uuidVbox; // optional; if the file was exported by VirtualBox >= 3.2,
// then this has the UUID with which the disk was registered
// fields from /References/File; the spec says the file reference from disk can be empty,
// so in that case, strFilename will be empty, then a new disk should be created
- iprt::MiniString strHref; // value from /References/File/@href (filename); if empty, then the remaining fields are ignored
+ RTCString strHref; // value from /References/File/@href (filename); if empty, then the remaining fields are ignored
int64_t iSize; // value from /References/File/@size (optional according to spec; then we set -1 here)
int64_t iChunkSize; // value from /References/File/@chunkSize (optional, unsupported)
- iprt::MiniString strCompression; // value from /References/File/@compression (optional, can be "gzip" according to spec)
+ RTCString strCompression; // value from /References/File/@compression (optional, can be "gzip" according to spec)
// additional field which has a descriptive size in megabytes derived from the above; this can be used for progress reports
uint32_t ulSuggestedSizeMB;
@@ -206,39 +206,39 @@ enum ResourceType_T
struct VirtualHardwareItem
{
- iprt::MiniString strDescription;
- iprt::MiniString strCaption;
- iprt::MiniString strElementName;
+ RTCString strDescription;
+ RTCString strCaption;
+ RTCString strElementName;
uint32_t ulInstanceID;
uint32_t ulParent;
ResourceType_T resourceType;
- iprt::MiniString strOtherResourceType;
- iprt::MiniString strResourceSubType;
+ RTCString strOtherResourceType;
+ RTCString strResourceSubType;
bool fResourceRequired;
- iprt::MiniString strHostResource; // "Abstractly specifies how a device shall connect to a resource on the deployment platform.
+ RTCString strHostResource; // "Abstractly specifies how a device shall connect to a resource on the deployment platform.
// Not all devices need a backing." Used with disk items, for which this references a virtual
// disk from the Disks section.
bool fAutomaticAllocation;
bool fAutomaticDeallocation;
- iprt::MiniString strConnection; // "All Ethernet adapters that specify the same abstract network connection name within an OVF
+ RTCString strConnection; // "All Ethernet adapters that specify the same abstract network connection name within an OVF
// package shall be deployed on the same network. The abstract network connection name shall be
// listed in the NetworkSection at the outermost envelope level." We ignore this and only set up
// a network adapter depending on the network name.
- iprt::MiniString strAddress; // "Device-specific. For an Ethernet adapter, this specifies the MAC address."
+ RTCString strAddress; // "Device-specific. For an Ethernet adapter, this specifies the MAC address."
int32_t lAddress; // strAddress as an integer, if applicable.
- iprt::MiniString strAddressOnParent; // "For a device, this specifies its location on the controller."
- iprt::MiniString strAllocationUnits; // "Specifies the units of allocation used. For example, “byte * 2^20â€."
+ RTCString strAddressOnParent; // "For a device, this specifies its location on the controller."
+ RTCString strAllocationUnits; // "Specifies the units of allocation used. For example, “byte * 2^20â€."
uint64_t ullVirtualQuantity; // "Specifies the quantity of resources presented. For example, “256â€."
uint64_t ullReservation; // "Specifies the minimum quantity of resources guaranteed to be available."
uint64_t ullLimit; // "Specifies the maximum quantity of resources that will be granted."
uint64_t ullWeight; // "Specifies a relative priority for this allocation in relation to other allocations."
- iprt::MiniString strConsumerVisibility;
- iprt::MiniString strMappingBehavior;
- iprt::MiniString strPoolID;
+ RTCString strConsumerVisibility;
+ RTCString strMappingBehavior;
+ RTCString strPoolID;
uint32_t ulBusNumber; // seen with IDE controllers, but not listed in OVF spec
uint32_t ulLineNumber; // line number of <Item> element in XML source; cached for error messages
@@ -256,7 +256,7 @@ struct VirtualHardwareItem
{};
};
-typedef std::map<iprt::MiniString, DiskImage> DiskImagesMap;
+typedef std::map<RTCString, DiskImage> DiskImagesMap;
struct VirtualSystem;
@@ -269,7 +269,7 @@ struct HardDiskController
enum ControllerSystemType { IDE, SATA, SCSI };
ControllerSystemType system; // one of IDE, SATA, SCSI
- iprt::MiniString strControllerType;
+ RTCString strControllerType;
// controller subtype (Item/ResourceSubType); e.g. "LsiLogic"; can be empty (esp. for IDE)
// note that we treat LsiLogicSAS as a SCSI controller (system == SCSI) even though VirtualBox
// treats it as a fourth class besides IDE, SATA, SCSI
@@ -295,12 +295,12 @@ struct VirtualDisk
// points into VirtualSystem.mapControllers
uint32_t ulAddressOnParent; // parsed strAddressOnParent of hardware item; will be 0 or 1 for IDE
// and possibly higher for disks attached to SCSI controllers (untested)
- iprt::MiniString strDiskId; // if the hard disk has an ovf:/disk/<id> reference,
+ RTCString strDiskId; // if the hard disk has an ovf:/disk/<id> reference,
// this receives the <id> component; points to one of the
// references in Appliance::Data.mapDisks
};
-typedef std::map<iprt::MiniString, VirtualDisk> VirtualDisksMap;
+typedef std::map<RTCString, VirtualDisk> VirtualDisksMap;
/**
* A list of EthernetAdapters is contained in VirtualSystem, representing the
@@ -308,8 +308,8 @@ typedef std::map<iprt::MiniString, VirtualDisk> VirtualDisksMap;
*/
struct EthernetAdapter
{
- iprt::MiniString strAdapterType; // "PCNet32" or "E1000" or whatever; from <rasd:ResourceSubType>
- iprt::MiniString strNetworkName; // from <rasd:Connection>
+ RTCString strAdapterType; // "PCNet32" or "E1000" or whatever; from <rasd:ResourceSubType>
+ RTCString strNetworkName; // from <rasd:Connection>
};
typedef std::list<EthernetAdapter> EthernetAdaptersList;
@@ -320,15 +320,15 @@ typedef std::list<EthernetAdapter> EthernetAdaptersList;
*/
struct VirtualSystem
{
- iprt::MiniString strName; // copy of VirtualSystem/@id
+ RTCString strName; // copy of VirtualSystem/@id
- iprt::MiniString strDescription; // copy of VirtualSystem/AnnotationSection content, if any
+ RTCString strDescription; // copy of VirtualSystem/AnnotationSection content, if any
CIMOSType_T cimos;
- iprt::MiniString strCimosDesc; // readable description of the cimos type in the case of cimos = 0/1/102
- iprt::MiniString strTypeVbox; // optional type from @vbox:ostype attribute (VirtualBox 4.0 or higher)
+ RTCString strCimosDesc; // readable description of the cimos type in the case of cimos = 0/1/102
+ RTCString strTypeVbox; // optional type from @vbox:ostype attribute (VirtualBox 4.0 or higher)
- iprt::MiniString strVirtualSystemType; // generic hardware description; OVF says this can be something like "vmx-4" or "xen";
+ RTCString strVirtualSystemType; // generic hardware description; OVF says this can be something like "vmx-4" or "xen";
// VMware Workstation 6.5 is "vmx-07"
HardwareItemsMap mapHardwareItems; // map of virtual hardware items, sorted by unique instance ID
@@ -349,16 +349,16 @@ struct VirtualSystem
bool fHasCdromDrive; // true if there's a CD-ROM item in mapHardwareItems; ISO images are not yet supported by OVFtool
bool fHasUsbController; // true if there's a USB controller item in mapHardwareItems
- iprt::MiniString strSoundCardType; // if not empty, then the system wants a soundcard; this then specifies the hardware;
+ RTCString strSoundCardType; // if not empty, then the system wants a soundcard; this then specifies the hardware;
// VMware Workstation 6.5 uses "ensoniq1371" for example
- iprt::MiniString strLicenseText; // license info if any; receives contents of VirtualSystem/EulaSection/License
+ RTCString strLicenseText; // license info if any; receives contents of VirtualSystem/EulaSection/License
- iprt::MiniString strProduct; // product info if any; receives contents of VirtualSystem/ProductSection/Product
- iprt::MiniString strVendor; // product info if any; receives contents of VirtualSystem/ProductSection/Vendor
- iprt::MiniString strVersion; // product info if any; receives contents of VirtualSystem/ProductSection/Version
- iprt::MiniString strProductUrl; // product info if any; receives contents of VirtualSystem/ProductSection/ProductUrl
- iprt::MiniString strVendorUrl; // product info if any; receives contents of VirtualSystem/ProductSection/VendorUrl
+ RTCString strProduct; // product info if any; receives contents of VirtualSystem/ProductSection/Product
+ RTCString strVendor; // product info if any; receives contents of VirtualSystem/ProductSection/Vendor
+ RTCString strVersion; // product info if any; receives contents of VirtualSystem/ProductSection/Version
+ RTCString strProductUrl; // product info if any; receives contents of VirtualSystem/ProductSection/ProductUrl
+ RTCString strVendorUrl; // product info if any; receives contents of VirtualSystem/ProductSection/VendorUrl
const xml::ElementNode // pointer to <vbox:Machine> element under <VirtualSystem> element or NULL if not present
*pelmVboxMachine;
@@ -407,11 +407,11 @@ struct VirtualSystem
class OVFReader
{
public:
- OVFReader(const void *pvBuf, size_t cbSize, const iprt::MiniString &path);
- OVFReader(const iprt::MiniString &path);
+ OVFReader(const void *pvBuf, size_t cbSize, const RTCString &path);
+ OVFReader(const RTCString &path);
// Data fields
- iprt::MiniString m_strPath; // file name given to constructor
+ RTCString m_strPath; // file name given to constructor
DiskImagesMap m_mapDisks; // map of DiskImage structs, sorted by DiskImage.strDiskId
std::list<VirtualSystem> m_llVirtualSystems; // list of virtual systems, created by and valid after read()
diff --git a/src/VBox/Main/src-all/DisplayPNGUtil.cpp b/src/VBox/Main/src-all/DisplayPNGUtil.cpp
index 345becfcc..127b33afb 100644
--- a/src/VBox/Main/src-all/DisplayPNGUtil.cpp
+++ b/src/VBox/Main/src-all/DisplayPNGUtil.cpp
@@ -1,4 +1,4 @@
-/* $Id: DisplayPNGUtil.cpp $ */
+/* $Id: DisplayPNGUtil.cpp 36494 2011-04-01 13:14:47Z vboxsync $ */
/** @file
* PNG utilities
*/
diff --git a/src/VBox/Main/src-all/DisplayUtils.cpp b/src/VBox/Main/src-all/DisplayUtils.cpp
index 691155d78..29cf02553 100644
--- a/src/VBox/Main/src-all/DisplayUtils.cpp
+++ b/src/VBox/Main/src-all/DisplayUtils.cpp
@@ -1,4 +1,4 @@
-/* $Id: DisplayUtils.cpp $ */
+/* $Id: DisplayUtils.cpp 35576 2011-01-14 18:46:03Z vboxsync $ */
/** @file
* Implementation of IDisplay helpers.
*/
diff --git a/src/VBox/Main/src-all/EventImpl.cpp b/src/VBox/Main/src-all/EventImpl.cpp
index ea6c0a38e..5c7ee87be 100644
--- a/src/VBox/Main/src-all/EventImpl.cpp
+++ b/src/VBox/Main/src-all/EventImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: EventImpl.cpp $ */
+/* $Id: EventImpl.cpp 36619 2011-04-08 07:51:31Z vboxsync $ */
/** @file
* VirtualBox COM Event class implementation
*/
@@ -85,7 +85,7 @@ struct VBoxEvent::Data
HRESULT VBoxEvent::FinalConstruct()
{
m = new Data;
- return S_OK;
+ return BaseFinalConstruct();
}
void VBoxEvent::FinalRelease()
@@ -95,6 +95,7 @@ void VBoxEvent::FinalRelease()
uninit();
delete m;
m = 0;
+ BaseFinalRelease();
}
}
@@ -802,6 +803,9 @@ HRESULT ListenerRecord::process(IEvent* aEvent,
{
aAlock.release();
rc = mListener->HandleEvent(aEvent);
+#ifdef RT_OS_WINDOWS
+ Assert(rc != RPC_E_WRONG_THREAD);
+#endif
aAlock.acquire();
}
if (aWaitable)
@@ -909,13 +913,14 @@ EventSource::~EventSource()
HRESULT EventSource::FinalConstruct()
{
m = new Data;
- return S_OK;
+ return BaseFinalConstruct();
}
void EventSource::FinalRelease()
{
uninit();
delete m;
+ BaseFinalRelease();
}
HRESULT EventSource::init(IUnknown *)
@@ -1182,9 +1187,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(PassiveEventListener)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IEventListener)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IEventListener)
END_COM_MAP()
PassiveEventListener()
@@ -1194,10 +1197,12 @@ public:
HRESULT FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void FinalRelease()
- {}
+ {
+ BaseFinalRelease();
+ }
// IEventListener methods
STDMETHOD(HandleEvent)(IEvent *)
@@ -1222,9 +1227,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(ProxyEventListener)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IEventListener)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IEventListener)
END_COM_MAP()
ProxyEventListener()
@@ -1234,10 +1237,12 @@ public:
HRESULT FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void FinalRelease()
- {}
+ {
+ BaseFinalRelease();
+ }
HRESULT init(IEventSource* aSource)
{
@@ -1277,9 +1282,7 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(EventSourceAggregator)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IEventSource)
- COM_INTERFACE_ENTRY(IDispatch)
+ VBOX_DEFAULT_INTERFACE_ENTRIES(IEventSource)
END_COM_MAP()
EventSourceAggregator()
@@ -1289,13 +1292,14 @@ public:
HRESULT FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void FinalRelease()
{
mEventSources.clear();
mListenerProxies.clear();
mSource->uninit();
+ BaseFinalRelease();
}
// internal public
@@ -1503,6 +1507,9 @@ STDMETHODIMP EventSourceAggregator::FireEvent(IEvent * aEvent,
{
ComPtr<IEventSource> es = *it;
rc = es->FireEvent(aEvent, aTimeout, aProcessed);
+ /* Current behavior is that aggregator's FireEvent() always succeeds,
+ so that multiple event sources don't affect each other. */
+ NOREF(rc);
}
return S_OK;
diff --git a/src/VBox/Main/src-all/ExtPackManagerImpl.cpp b/src/VBox/Main/src-all/ExtPackManagerImpl.cpp
index cb904f97c..e541b9061 100644
--- a/src/VBox/Main/src-all/ExtPackManagerImpl.cpp
+++ b/src/VBox/Main/src-all/ExtPackManagerImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: ExtPackManagerImpl.cpp $ */
+/* $Id: ExtPackManagerImpl.cpp 37843 2011-07-08 12:34:18Z vboxsync $ */
/** @file
* VirtualBox Main - interface for Extension Packs, VBoxSVC & VBoxC.
*/
@@ -211,7 +211,7 @@ DEFINE_EMPTY_CTOR_DTOR(ExtPackFile)
HRESULT ExtPackFile::FinalConstruct()
{
m = NULL;
- return S_OK;
+ return BaseFinalConstruct();
}
/**
@@ -241,7 +241,7 @@ HRESULT ExtPackFile::initWithFile(const char *a_pszFile, ExtPackManager *a_pExtP
m->ptrExtPackMgr = a_pExtPackMgr;
m->pVirtualBox = a_pVirtualBox;
- iprt::MiniString *pstrTarName = VBoxExtPackExtractNameFromTarballPath(a_pszFile);
+ RTCString *pstrTarName = VBoxExtPackExtractNameFromTarballPath(a_pszFile);
if (pstrTarName)
{
m->Desc.strName = *pstrTarName;
@@ -283,8 +283,8 @@ HRESULT ExtPackFile::initWithFile(const char *a_pszFile, ExtPackManager *a_pExtP
/*
* Parse the XML.
*/
- iprt::MiniString strSavedName(m->Desc.strName);
- iprt::MiniString *pStrLoadErr = VBoxExtPackLoadDescFromVfsFile(hXmlFile, &m->Desc, &m->ObjInfoDesc);
+ RTCString strSavedName(m->Desc.strName);
+ RTCString *pStrLoadErr = VBoxExtPackLoadDescFromVfsFile(hXmlFile, &m->Desc, &m->ObjInfoDesc);
RTVfsFileRelease(hXmlFile);
if (pStrLoadErr != NULL)
{
@@ -330,6 +330,7 @@ HRESULT ExtPackFile::initFailed(const char *a_pszWhyFmt, ...)
void ExtPackFile::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
/**
@@ -643,7 +644,7 @@ STDMETHODIMP ExtPackFile::Install(BOOL a_fReplace, IN_BSTR a_bstrDisplayInfo, IP
{
pJob = new EXTPACKINSTALLJOB;
pJob->ptrExtPackFile = this;
- pJob->fReplace = a_fReplace;
+ pJob->fReplace = a_fReplace != FALSE;
pJob->strDisplayInfo = a_bstrDisplayInfo;
pJob->ptrExtPackMgr = m->ptrExtPackMgr;
hrc = pJob->ptrProgress.createObject();
@@ -1223,8 +1224,8 @@ void ExtPack::probeAndLoad(void)
/*
* Read the description file.
*/
- iprt::MiniString strSavedName(m->Desc.strName);
- iprt::MiniString *pStrLoadErr = VBoxExtPackLoadDesc(m->strExtPackPath.c_str(), &m->Desc, &m->ObjInfoDesc);
+ RTCString strSavedName(m->Desc.strName);
+ RTCString *pStrLoadErr = VBoxExtPackLoadDesc(m->strExtPackPath.c_str(), &m->Desc, &m->ObjInfoDesc);
if (pStrLoadErr != NULL)
{
m->strWhyUnusable.printf(tr("Failed to load '%s/%s': %s"),
@@ -1901,7 +1902,7 @@ HRESULT ExtPackManager::initExtPackManager(VirtualBox *a_pVirtualBox, VBOXEXTPAC
AssertLogRelRC(vrc);
if (RT_SUCCESS(vrc))
{
- iprt::MiniString *pstrName = VBoxExtPackUnmangleName(Entry.szName, RTSTR_MAX);
+ RTCString *pstrName = VBoxExtPackUnmangleName(Entry.szName, RTSTR_MAX);
AssertLogRel(pstrName);
if (pstrName)
{
@@ -2445,6 +2446,14 @@ HRESULT ExtPackManager::refreshExtPack(const char *a_pszName, bool a_fUnusableIs
else
{
/*
+ * Do this check here, otherwise VBoxExtPackCalcDir() will fail with a strange
+ * error.
+ */
+ bool fValid = VBoxExtPackIsValidName(a_pszName);
+ if (!fValid)
+ return setError(E_FAIL, "Invalid extension pack name specified");
+
+ /*
* Does the dir exist? Make some special effort to deal with case
* sensitivie file systems (a_pszName is case insensitive and mangled).
*/
@@ -2479,7 +2488,7 @@ HRESULT ExtPackManager::refreshExtPack(const char *a_pszName, bool a_fUnusableIs
* Update the name and directory variables.
*/
vrc = RTPathJoin(szDir, sizeof(szDir), m->strBaseDir.c_str(), Entry.szName); /* not really necessary */
- AssertLogRelRCReturnStmt(vrc, E_UNEXPECTED, RTDirClose(pDir));
+ AssertLogRelRCReturnStmt(vrc, RTDirClose(pDir), E_UNEXPECTED);
a_pszName = Entry.szName;
fExists = true;
break;
@@ -2561,8 +2570,8 @@ 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);
- iprt::MiniString const * const pStrName = &a_pExtPackFile->m->Desc.strName;
- iprt::MiniString const * const pStrTarball = &a_pExtPackFile->m->strExtPackFile;
+ RTCString const * const pStrName = &a_pExtPackFile->m->Desc.strName;
+ RTCString const * const pStrTarball = &a_pExtPackFile->m->strExtPackFile;
AutoCaller autoCaller(this);
HRESULT hrc = autoCaller.rc();
@@ -3022,4 +3031,45 @@ bool ExtPackManager::isExtPackUsable(const char *a_pszExtPack)
&& pExtPack->m->fUsable;
}
+/**
+ * Dumps all extension packs to the release log.
+ */
+void ExtPackManager::dumpAllToReleaseLog(void)
+{
+ AutoCaller autoCaller(this);
+ HRESULT hrc = autoCaller.rc();
+ if (FAILED(hrc))
+ return;
+ AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+
+ LogRel(("Installed Extension Packs:\n"));
+ for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
+ it != m->llInstalledExtPacks.end();
+ it++)
+ {
+ ExtPack::Data *pExtPackData = (*it)->m;
+ if (pExtPackData)
+ {
+ if (pExtPackData->fUsable)
+ LogRel((" %s (Version: %s r%u; VRDE Module: %s)\n",
+ pExtPackData->Desc.strName.c_str(),
+ pExtPackData->Desc.strVersion.c_str(),
+ pExtPackData->Desc.uRevision,
+ pExtPackData->Desc.strVrdeModule.c_str() ));
+ else
+ LogRel((" %s (Version: %s r%u; VRDE Module: %s unusable because of '%s')\n",
+ pExtPackData->Desc.strName.c_str(),
+ pExtPackData->Desc.strVersion.c_str(),
+ pExtPackData->Desc.uRevision,
+ pExtPackData->Desc.strVrdeModule.c_str(),
+ pExtPackData->strWhyUnusable.c_str() ));
+ }
+ else
+ LogRel((" pExtPackData is NULL\n"));
+ }
+
+ if (!m->llInstalledExtPacks.size())
+ LogRel((" None installed!\n"));
+}
+
/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/src-all/ExtPackUtil.cpp b/src/VBox/Main/src-all/ExtPackUtil.cpp
index a82bfe8c4..232673ed9 100644
--- a/src/VBox/Main/src-all/ExtPackUtil.cpp
+++ b/src/VBox/Main/src-all/ExtPackUtil.cpp
@@ -1,4 +1,4 @@
-/* $Id: ExtPackUtil.cpp $ */
+/* $Id: ExtPackUtil.cpp 36527 2011-04-04 13:16:09Z vboxsync $ */
/** @file
* VirtualBox Main - Extension Pack Utilities and definitions, VBoxC, VBoxSVC, ++.
*/
@@ -46,7 +46,7 @@
* @param paPlugIns Where to return the plug-in descriptor array.
* (RTMemFree it even on failure)
*/
-static iprt::MiniString *
+static RTCString *
vboxExtPackLoadPlugInDescs(const xml::ElementNode *pVBoxExtPackElm,
uint32_t *pcPlugIns, PVBOXEXTPACKPLUGINDESC *paPlugIns)
{
@@ -97,7 +97,7 @@ void VBoxExtPackInitDesc(PVBOXEXTPACKDESC a_pExtPackDesc)
* @param a_pDoc Pointer to the the XML document.
* @param a_pExtPackDesc Where to store the extension pack descriptor.
*/
-static iprt::MiniString *vboxExtPackLoadDescFromDoc(xml::Document *a_pDoc, PVBOXEXTPACKDESC a_pExtPackDesc)
+static RTCString *vboxExtPackLoadDescFromDoc(xml::Document *a_pDoc, PVBOXEXTPACKDESC a_pExtPackDesc)
{
/*
* Get the main element and check its version.
@@ -105,41 +105,41 @@ static iprt::MiniString *vboxExtPackLoadDescFromDoc(xml::Document *a_pDoc, PVBOX
const xml::ElementNode *pVBoxExtPackElm = a_pDoc->getRootElement();
if ( !pVBoxExtPackElm
|| strcmp(pVBoxExtPackElm->getName(), "VirtualBoxExtensionPack") != 0)
- return new iprt::MiniString("No VirtualBoxExtensionPack element");
+ return new RTCString("No VirtualBoxExtensionPack element");
- iprt::MiniString strFormatVersion;
+ RTCString strFormatVersion;
if (!pVBoxExtPackElm->getAttributeValue("version", strFormatVersion))
- return new iprt::MiniString("Missing format version");
+ return new RTCString("Missing format version");
if (!strFormatVersion.equals("1.0"))
- return &(new iprt::MiniString("Unsupported format version: "))->append(strFormatVersion);
+ return &(new RTCString("Unsupported format version: "))->append(strFormatVersion);
/*
* Read and validate mandatory bits.
*/
const xml::ElementNode *pNameElm = pVBoxExtPackElm->findChildElement("Name");
if (!pNameElm)
- return new iprt::MiniString("The 'Name' element is missing");
+ return new RTCString("The 'Name' element is missing");
const char *pszName = pNameElm->getValue();
if (!VBoxExtPackIsValidName(pszName))
- return &(new iprt::MiniString("Invalid name: "))->append(pszName);
+ return &(new RTCString("Invalid name: "))->append(pszName);
const xml::ElementNode *pDescElm = pVBoxExtPackElm->findChildElement("Description");
if (!pDescElm)
- return new iprt::MiniString("The 'Description' element is missing");
+ return new RTCString("The 'Description' element is missing");
const char *pszDesc = pDescElm->getValue();
if (!pszDesc || *pszDesc == '\0')
- return new iprt::MiniString("The 'Description' element is empty");
+ return new RTCString("The 'Description' element is empty");
if (strpbrk(pszDesc, "\n\r\t\v\b") != NULL)
- return new iprt::MiniString("The 'Description' must not contain control characters");
+ return new RTCString("The 'Description' must not contain control characters");
const xml::ElementNode *pVersionElm = pVBoxExtPackElm->findChildElement("Version");
if (!pVersionElm)
- return new iprt::MiniString("The 'Version' element is missing");
+ return new RTCString("The 'Version' element is missing");
const char *pszVersion = pVersionElm->getValue();
if (!pszVersion || *pszVersion == '\0')
- return new iprt::MiniString("The 'Version' element is empty");
+ return new RTCString("The 'Version' element is empty");
if (!VBoxExtPackIsValidVersionString(pszVersion))
- return &(new iprt::MiniString("Invalid version string: "))->append(pszVersion);
+ return &(new RTCString("Invalid version string: "))->append(pszVersion);
uint32_t uRevision;
if (!pVersionElm->getAttributeValue("revision", uRevision))
@@ -147,12 +147,12 @@ static iprt::MiniString *vboxExtPackLoadDescFromDoc(xml::Document *a_pDoc, PVBOX
const xml::ElementNode *pMainModuleElm = pVBoxExtPackElm->findChildElement("MainModule");
if (!pMainModuleElm)
- return new iprt::MiniString("The 'MainModule' element is missing");
+ return new RTCString("The 'MainModule' element is missing");
const char *pszMainModule = pMainModuleElm->getValue();
if (!pszMainModule || *pszMainModule == '\0')
- return new iprt::MiniString("The 'MainModule' element is empty");
+ return new RTCString("The 'MainModule' element is empty");
if (!VBoxExtPackIsValidModuleString(pszMainModule))
- return &(new iprt::MiniString("Invalid main module string: "))->append(pszMainModule);
+ return &(new RTCString("Invalid main module string: "))->append(pszMainModule);
/*
* The VRDE module, optional.
@@ -166,7 +166,7 @@ static iprt::MiniString *vboxExtPackLoadDescFromDoc(xml::Document *a_pDoc, PVBOX
if (!pszVrdeModule || *pszVrdeModule == '\0')
pszVrdeModule = NULL;
else if (!VBoxExtPackIsValidModuleString(pszVrdeModule))
- return &(new iprt::MiniString("Invalid VRDE module string: "))->append(pszVrdeModule);
+ return &(new RTCString("Invalid VRDE module string: "))->append(pszVrdeModule);
}
/*
@@ -180,7 +180,7 @@ static iprt::MiniString *vboxExtPackLoadDescFromDoc(xml::Document *a_pDoc, PVBOX
*/
uint32_t cPlugIns = 0;
PVBOXEXTPACKPLUGINDESC paPlugIns = NULL;
- iprt::MiniString *pstrRet = vboxExtPackLoadPlugInDescs(pVBoxExtPackElm, &cPlugIns, &paPlugIns);
+ RTCString *pstrRet = vboxExtPackLoadPlugInDescs(pVBoxExtPackElm, &cPlugIns, &paPlugIns);
if (pstrRet)
{
RTMemFree(paPlugIns);
@@ -213,7 +213,7 @@ static iprt::MiniString *vboxExtPackLoadDescFromDoc(xml::Document *a_pDoc, PVBOX
* @param a_pObjInfo Where to store the object info for the file (unix
* attribs). Optional.
*/
-iprt::MiniString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo)
+RTCString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo)
{
vboxExtPackClearDesc(a_pExtPackDesc);
@@ -223,19 +223,19 @@ iprt::MiniString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_p
char szFilePath[RTPATH_MAX];
int vrc = RTPathJoin(szFilePath, sizeof(szFilePath), a_pszDir, VBOX_EXTPACK_DESCRIPTION_NAME);
if (RT_FAILURE(vrc))
- return new iprt::MiniString("RTPathJoin failed with %Rrc", vrc);
+ return new RTCString("RTPathJoin failed with %Rrc", vrc);
RTFSOBJINFO ObjInfo;
vrc = RTPathQueryInfoEx(szFilePath, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
if (RT_FAILURE(vrc))
- return &(new iprt::MiniString())->printf("RTPathQueryInfoEx failed with %Rrc", vrc);
+ return &(new RTCString())->printf("RTPathQueryInfoEx failed with %Rrc", vrc);
if (a_pObjInfo)
*a_pObjInfo = ObjInfo;
if (!RTFS_IS_FILE(ObjInfo.Attr.fMode))
{
if (RTFS_IS_SYMLINK(ObjInfo.Attr.fMode))
- return new iprt::MiniString("The XML file is symlinked, that is not allowed");
- return &(new iprt::MiniString)->printf("The XML file is not a file (fMode=%#x)", ObjInfo.Attr.fMode);
+ return new RTCString("The XML file is symlinked, that is not allowed");
+ return &(new RTCString)->printf("The XML file is not a file (fMode=%#x)", ObjInfo.Attr.fMode);
}
xml::Document Doc;
@@ -247,7 +247,7 @@ iprt::MiniString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_p
}
catch (xml::XmlError Err)
{
- return new iprt::MiniString(Err.what());
+ return new RTCString(Err.what());
}
}
@@ -267,7 +267,7 @@ iprt::MiniString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_p
* @param a_pObjInfo Where to store the object info for the file (unix
* attribs). Optional.
*/
-iprt::MiniString *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo)
+RTCString *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo)
{
vboxExtPackClearDesc(a_pExtPackDesc);
@@ -277,7 +277,7 @@ iprt::MiniString *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPAC
RTFSOBJINFO ObjInfo;
int rc = RTVfsFileQueryInfo(hVfsFile, &ObjInfo, RTFSOBJATTRADD_UNIX);
if (RT_FAILURE(rc))
- return &(new iprt::MiniString)->printf("RTVfsFileQueryInfo failed: %Rrc", rc);
+ return &(new RTCString)->printf("RTVfsFileQueryInfo failed: %Rrc", rc);
if (a_pObjInfo)
*a_pObjInfo = ObjInfo;
@@ -288,23 +288,23 @@ iprt::MiniString *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPAC
/* Check the file size. */
if (ObjInfo.cbObject > _1M || ObjInfo.cbObject < 0)
- return &(new iprt::MiniString)->printf("The XML file is too large (%'RU64 bytes)", ObjInfo.cbObject);
+ return &(new RTCString)->printf("The XML file is too large (%'RU64 bytes)", ObjInfo.cbObject);
size_t const cbFile = (size_t)ObjInfo.cbObject;
/* Rewind to the start of the file. */
rc = RTVfsFileSeek(hVfsFile, 0, RTFILE_SEEK_BEGIN, NULL);
if (RT_FAILURE(rc))
- return &(new iprt::MiniString)->printf("RTVfsFileSeek(,0,BEGIN) failed: %Rrc", rc);
+ return &(new RTCString)->printf("RTVfsFileSeek(,0,BEGIN) failed: %Rrc", rc);
/* Allocate memory and read the file content into it. */
void *pvFile = RTMemTmpAlloc(cbFile);
if (!pvFile)
- return &(new iprt::MiniString)->printf("RTMemTmpAlloc(%zu) failed", cbFile);
+ return &(new RTCString)->printf("RTMemTmpAlloc(%zu) failed", cbFile);
- iprt::MiniString *pstrErr = NULL;
+ RTCString *pstrErr = NULL;
rc = RTVfsFileRead(hVfsFile, pvFile, cbFile, NULL);
if (RT_FAILURE(rc))
- pstrErr = &(new iprt::MiniString)->printf("RTVfsFileRead failed: %Rrc", rc);
+ pstrErr = &(new RTCString)->printf("RTVfsFileRead failed: %Rrc", rc);
/*
* Parse the file.
@@ -313,14 +313,14 @@ iprt::MiniString *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPAC
if (RT_SUCCESS(rc))
{
xml::XmlMemParser Parser;
- iprt::MiniString strFileName = VBOX_EXTPACK_DESCRIPTION_NAME;
+ RTCString strFileName = VBOX_EXTPACK_DESCRIPTION_NAME;
try
{
Parser.read(pvFile, cbFile, strFileName, Doc);
}
catch (xml::XmlError Err)
{
- pstrErr = new iprt::MiniString(Err.what());
+ pstrErr = new RTCString(Err.what());
rc = VERR_PARSE_ERROR;
}
}
@@ -365,7 +365,7 @@ void VBoxExtPackFreeDesc(PVBOXEXTPACKDESC a_pExtPackDesc)
* NULL if no valid name was found or if we ran out of memory.
* @param pszTarball The path to the tarball.
*/
-iprt::MiniString *VBoxExtPackExtractNameFromTarballPath(const char *pszTarball)
+RTCString *VBoxExtPackExtractNameFromTarballPath(const char *pszTarball)
{
/*
* Skip ahead to the filename part and count the number of characters
@@ -469,7 +469,7 @@ bool VBoxExtPackIsValidMangledName(const char *pszMangledName, size_t cchMax /*=
* @param pszName The unmangled name.
* @sa VBoxExtPackUnmangleName, VBoxExtPackIsValidMangledName
*/
-iprt::MiniString *VBoxExtPackMangleName(const char *pszName)
+RTCString *VBoxExtPackMangleName(const char *pszName)
{
AssertReturn(VBoxExtPackIsValidName(pszName), NULL);
@@ -485,7 +485,7 @@ iprt::MiniString *VBoxExtPackMangleName(const char *pszName)
szTmp[off] = '\0';
Assert(VBoxExtPackIsValidMangledName(szTmp));
- return new iprt::MiniString(szTmp, off);
+ return new RTCString(szTmp, off);
}
/**
@@ -497,7 +497,7 @@ iprt::MiniString *VBoxExtPackMangleName(const char *pszName)
* @param cchMax The max name length. RTSTR_MAX is fine.
* @sa VBoxExtPackMangleName, VBoxExtPackIsValidMangledName
*/
-iprt::MiniString *VBoxExtPackUnmangleName(const char *pszMangledName, size_t cchMax)
+RTCString *VBoxExtPackUnmangleName(const char *pszMangledName, size_t cchMax)
{
AssertReturn(VBoxExtPackIsValidMangledName(pszMangledName, cchMax), NULL);
@@ -516,7 +516,7 @@ iprt::MiniString *VBoxExtPackUnmangleName(const char *pszMangledName, size_t cch
szTmp[off] = '\0';
AssertReturn(VBoxExtPackIsValidName(szTmp), NULL);
- return new iprt::MiniString(szTmp, off);
+ return new RTCString(szTmp, off);
}
/**
@@ -534,7 +534,7 @@ int VBoxExtPackCalcDir(char *pszExtPackDir, size_t cbExtPackDir, const char *psz
{
AssertReturn(VBoxExtPackIsValidName(pszName), VERR_INTERNAL_ERROR_5);
- iprt::MiniString *pstrMangledName = VBoxExtPackMangleName(pszName);
+ RTCString *pstrMangledName = VBoxExtPackMangleName(pszName);
if (!pstrMangledName)
return VERR_INTERNAL_ERROR_4;
@@ -664,7 +664,7 @@ static int vboxExtPackVerifyXml(RTVFSFILE hXmlFile, const char *pszExtPackName,
* Load the XML.
*/
VBOXEXTPACKDESC ExtPackDesc;
- iprt::MiniString *pstrErr = VBoxExtPackLoadDescFromVfsFile(hXmlFile, &ExtPackDesc, NULL);
+ RTCString *pstrErr = VBoxExtPackLoadDescFromVfsFile(hXmlFile, &ExtPackDesc, NULL);
if (pstrErr)
{
RTStrCopy(pszError, cbError, pstrErr->c_str());
diff --git a/src/VBox/Main/src-all/Global.cpp b/src/VBox/Main/src-all/Global.cpp
index 2483d6046..48e483802 100644
--- a/src/VBox/Main/src-all/Global.cpp
+++ b/src/VBox/Main/src-all/Global.cpp
@@ -1,4 +1,4 @@
-/* $Id: Global.cpp $ */
+/* $Id: Global.cpp 37722 2011-06-30 22:18:12Z vboxsync $ */
/** @file
*
@@ -287,7 +287,7 @@ const Global::OSType Global::sOSTypes[SchemaDefs::OSTypeId_COUNT] =
ChipsetType_ICH9, AudioControllerType_HDA },
{ "Other", "Other", SchemaDefs_OSTypeId_DOS, "DOS",
VBOXOSTYPE_DOS, VBOXOSHINT_NONE,
- 32, 4, 512 * _1M, NetworkAdapterType_Am79C973, 0, StorageControllerType_PIIX4, StorageBus_IDE,
+ 32, 4, 500 * _1M, NetworkAdapterType_Am79C973, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_SB16 },
{ "Other", "Other", SchemaDefs_OSTypeId_Netware, "Netware",
VBOXOSTYPE_Netware, VBOXOSHINT_HWVIRTEX,
diff --git a/src/VBox/Main/src-all/PciDeviceAttachmentImpl.cpp b/src/VBox/Main/src-all/PciDeviceAttachmentImpl.cpp
index 315b5757e..d3aedbe08 100644
--- a/src/VBox/Main/src-all/PciDeviceAttachmentImpl.cpp
+++ b/src/VBox/Main/src-all/PciDeviceAttachmentImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: PciDeviceAttachmentImpl.cpp $ */
+/* $Id: PciDeviceAttachmentImpl.cpp 36107 2011-02-28 18:24:32Z vboxsync $ */
/** @file
*
@@ -24,23 +24,20 @@
struct PciDeviceAttachment::Data
{
- Data(Machine *aParent,
- const Bstr &aDevName,
+ Data(const Bstr &aDevName,
LONG aHostAddress,
LONG aGuestAddress,
BOOL afPhysical)
- : pMachine(aParent),
- HostAddress(aHostAddress), GuestAddress(aGuestAddress),
+ : HostAddress(aHostAddress), GuestAddress(aGuestAddress),
fPhysical(afPhysical)
{
DevName = aDevName;
}
- Machine * const pMachine;
- Bstr DevName;
- LONG HostAddress;
- LONG GuestAddress;
- BOOL fPhysical;
+ Bstr DevName;
+ LONG HostAddress;
+ LONG GuestAddress;
+ BOOL fPhysical;
};
// constructor / destructor
@@ -49,28 +46,48 @@ struct PciDeviceAttachment::Data
HRESULT PciDeviceAttachment::FinalConstruct()
{
LogFlowThisFunc(("\n"));
- return S_OK;
+ return BaseFinalConstruct();
}
void PciDeviceAttachment::FinalRelease()
{
LogFlowThisFunc(("\n"));
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
/////////////////////////////////////////////////////////////////////////////
-HRESULT PciDeviceAttachment::init(Machine *aParent,
+HRESULT PciDeviceAttachment::init(IMachine *aParent,
const Bstr &aDevName,
LONG aHostAddress,
LONG aGuestAddress,
BOOL fPhysical)
{
- m = new Data(aParent, aDevName, aHostAddress, aGuestAddress, fPhysical);
+ (void)aParent;
+ m = new Data(aDevName, aHostAddress, aGuestAddress, fPhysical);
return m != NULL ? S_OK : E_FAIL;
}
+HRESULT PciDeviceAttachment::loadSettings(IMachine *aParent,
+ const settings::HostPciDeviceAttachment &hpda)
+{
+ Bstr bname(hpda.strDeviceName);
+ return init(aParent, bname, hpda.uHostAddress, hpda.uGuestAddress, TRUE);
+}
+
+
+HRESULT PciDeviceAttachment::saveSettings(settings::HostPciDeviceAttachment &data)
+{
+ Assert(m);
+ data.uHostAddress = m->HostAddress;
+ data.uGuestAddress = m->GuestAddress;
+ data.strDeviceName = m->DevName;
+
+ return S_OK;
+}
+
/**
* Uninitializes the instance.
* Called from FinalRelease().
diff --git a/src/VBox/Main/src-all/ProgressImpl.cpp b/src/VBox/Main/src-all/ProgressImpl.cpp
index 502c0f9b7..63b4767ab 100644
--- a/src/VBox/Main/src-all/ProgressImpl.cpp
+++ b/src/VBox/Main/src-all/ProgressImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: ProgressImpl.cpp $ */
+/* $Id: ProgressImpl.cpp 37069 2011-05-13 12:41:38Z vboxsync $ */
/** @file
*
* VirtualBox Progress COM class implementation
@@ -81,7 +81,7 @@ HRESULT ProgressBase::FinalConstruct()
m_pfnCancelCallback = NULL;
m_pvCancelUserArg = NULL;
- return S_OK;
+ return BaseFinalConstruct();
}
// protected initializer/uninitializer for internal purposes only
@@ -592,6 +592,7 @@ HRESULT Progress::FinalConstruct()
void Progress::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
@@ -914,6 +915,89 @@ STDMETHODIMP Progress::WaitForOperationCompletion(ULONG aOperation, LONG aTimeou
return S_OK;
}
+STDMETHODIMP Progress::WaitForAsyncProgressCompletion(IProgress *pProgressAsync)
+{
+ LogFlowThisFuncEnter();
+
+ CheckComArgNotNull(pProgressAsync);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ /* Note: we don't lock here, cause we just using public methods. */
+
+ HRESULT rc = S_OK;
+ BOOL fCancelable = FALSE;
+ BOOL fCompleted = FALSE;
+ BOOL fCanceled = FALSE;
+ ULONG currentPercent = 0;
+ ULONG cOp = 0;
+ /* Is the async process cancelable? */
+ rc = pProgressAsync->COMGETTER(Cancelable)(&fCancelable);
+ if (FAILED(rc)) return rc;
+ /* Loop as long as the sync process isn't completed. */
+ while (SUCCEEDED(pProgressAsync->COMGETTER(Completed(&fCompleted))))
+ {
+ /* We can forward any cancel request to the async process only when
+ * it is cancelable. */
+ if (fCancelable)
+ {
+ rc = COMGETTER(Canceled)(&fCanceled);
+ if (FAILED(rc)) return rc;
+ if (fCanceled)
+ {
+ rc = pProgressAsync->Cancel();
+ if (FAILED(rc)) return rc;
+ }
+ }
+ /* Even if the user canceled the process, we have to wait until the
+ async task has finished his work (cleanup and such). Otherwise there
+ will be sync trouble (still wrong state, dead locks, ...) on the
+ used objects. So just do nothing, but wait for the complete
+ notification. */
+ if (!fCanceled)
+ {
+ /* Check if the current operation has changed. It is also possible that
+ * in the meantime more than one async operation was finished. So we
+ * have to loop as long as we reached the same operation count. */
+ ULONG curOp;
+ for(;;)
+ {
+ rc = pProgressAsync->COMGETTER(Operation(&curOp));
+ if (FAILED(rc)) return rc;
+ if (cOp != curOp)
+ {
+ Bstr bstr;
+ ULONG currentWeight;
+ rc = pProgressAsync->COMGETTER(OperationDescription(bstr.asOutParam()));
+ if (FAILED(rc)) return rc;
+ rc = pProgressAsync->COMGETTER(OperationWeight(&currentWeight));
+ if (FAILED(rc)) return rc;
+ rc = SetNextOperation(bstr.raw(), currentWeight);
+ if (FAILED(rc)) return rc;
+ ++cOp;
+ }else
+ break;
+ }
+
+ rc = pProgressAsync->COMGETTER(OperationPercent(&currentPercent));
+ if (FAILED(rc)) return rc;
+ rc = SetCurrentOperationProgress(currentPercent);
+ if (FAILED(rc)) return rc;
+ }
+ if (fCompleted)
+ break;
+
+ /* Make sure the loop is not too tight */
+ rc = pProgressAsync->WaitForCompletion(100);
+ if (FAILED(rc)) return rc;
+ }
+
+ LogFlowThisFuncLeave();
+
+ return rc;
+}
+
STDMETHODIMP Progress::Cancel()
{
AutoCaller autoCaller(this);
@@ -1243,12 +1327,13 @@ HRESULT CombinedProgress::FinalConstruct()
mProgress = 0;
mCompletedOperations = 0;
- return S_OK;
+ return BaseFinalConstruct();
}
void CombinedProgress::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-all/SharedFolderImpl.cpp b/src/VBox/Main/src-all/SharedFolderImpl.cpp
index 36511132d..2edf2a2ee 100644
--- a/src/VBox/Main/src-all/SharedFolderImpl.cpp
+++ b/src/VBox/Main/src-all/SharedFolderImpl.cpp
@@ -65,12 +65,13 @@ SharedFolder::~SharedFolder()
HRESULT SharedFolder::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void SharedFolder::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-all/VirtualBoxBase.cpp b/src/VBox/Main/src-all/VirtualBoxBase.cpp
index 808c83c1e..d6265af3a 100644
--- a/src/VBox/Main/src-all/VirtualBoxBase.cpp
+++ b/src/VBox/Main/src-all/VirtualBoxBase.cpp
@@ -1,4 +1,4 @@
-/* $Id: VirtualBoxBase.cpp $ */
+/* $Id: VirtualBoxBase.cpp 36451 2011-03-28 19:40:52Z vboxsync $ */
/** @file
*
@@ -816,6 +816,9 @@ void MultiResult::decCounter()
/*static*/
bool MultiResult::isMultiEnabled()
{
+ if (sCounter == NIL_RTTLS)
+ return false;
+
return ((uintptr_t)RTTlsGet(MultiResult::sCounter)) > 0;
}
diff --git a/src/VBox/Main/src-client/AdditionsFacilityImpl.cpp b/src/VBox/Main/src-client/AdditionsFacilityImpl.cpp
new file mode 100644
index 000000000..da91146ed
--- /dev/null
+++ b/src/VBox/Main/src-client/AdditionsFacilityImpl.cpp
@@ -0,0 +1,213 @@
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * 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.
+ */
+
+#include "AdditionsFacilityImpl.h"
+#include "Global.h"
+
+#include "AutoCaller.h"
+#include "Logging.h"
+
+/* static */
+const AdditionsFacility::FacilityInfo AdditionsFacility::sFacilityInfo[8] =
+{
+ /* NOTE: We assume that unknown is always the first entry! */
+ { "Unknown", AdditionsFacilityType_None, AdditionsFacilityClass_None },
+ { "VirtualBox Base Driver", AdditionsFacilityType_VBoxGuestDriver, AdditionsFacilityClass_Driver },
+ { "VirtualBox System Service", AdditionsFacilityType_VBoxService, AdditionsFacilityClass_Service },
+ { "VirtualBox Desktop Integration", AdditionsFacilityType_VBoxTrayClient, AdditionsFacilityClass_Program },
+ { "Seamless Mode", AdditionsFacilityType_Seamless, AdditionsFacilityClass_Feature },
+ { "Graphics Mode", AdditionsFacilityType_Graphics, AdditionsFacilityClass_Feature },
+};
+
+// constructor / destructor
+/////////////////////////////////////////////////////////////////////////////
+
+DEFINE_EMPTY_CTOR_DTOR(AdditionsFacility)
+
+HRESULT AdditionsFacility::FinalConstruct()
+{
+ LogFlowThisFunc(("\n"));
+ return BaseFinalConstruct();
+}
+
+void AdditionsFacility::FinalRelease()
+{
+ LogFlowThisFuncEnter();
+ uninit();
+ BaseFinalRelease();
+ LogFlowThisFuncLeave();
+}
+
+// public initializer/uninitializer for internal purposes only
+/////////////////////////////////////////////////////////////////////////////
+
+HRESULT AdditionsFacility::init(Guest *aParent, AdditionsFacilityType_T enmFacility, AdditionsFacilityStatus_T enmStatus)
+{
+ LogFlowThisFunc(("aParent=%p\n", aParent));
+
+ /* Enclose the state transition NotReady->InInit->Ready. */
+ AutoInitSpan autoInitSpan(this);
+ AssertReturn(autoInitSpan.isOk(), E_FAIL);
+
+ RTTimeNow(&mData.mLastUpdated);
+ mData.mStatus = enmStatus;
+ mData.mType = enmFacility;
+ /** @todo mClass is not initialized here. */
+
+ /* Confirm a successful initialization when it's the case. */
+ autoInitSpan.setSucceeded();
+
+ return S_OK;
+}
+
+/**
+ * Uninitializes the instance.
+ * Called from FinalRelease().
+ */
+void AdditionsFacility::uninit()
+{
+ LogFlowThisFunc(("\n"));
+
+ /* Enclose the state transition Ready->InUninit->NotReady. */
+ AutoUninitSpan autoUninitSpan(this);
+ if (autoUninitSpan.uninitDone())
+ return;
+}
+
+STDMETHODIMP AdditionsFacility::COMGETTER(ClassType)(AdditionsFacilityClass_T *aClass)
+{
+ LogFlowThisFuncEnter();
+
+ CheckComArgOutPointerValid(aClass);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ *aClass = getClass();
+
+ return S_OK;
+}
+
+STDMETHODIMP AdditionsFacility::COMGETTER(Name)(BSTR *aName)
+{
+ LogFlowThisFuncEnter();
+
+ CheckComArgOutPointerValid(aName);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ Bstr(getName()).cloneTo(aName);
+
+ return S_OK;
+}
+
+STDMETHODIMP AdditionsFacility::COMGETTER(LastUpdated)(LONG64 *aTimestamp)
+{
+ LogFlowThisFuncEnter();
+
+ CheckComArgOutPointerValid(aTimestamp);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ *aTimestamp = getLastUpdated();
+
+ return S_OK;
+}
+
+STDMETHODIMP AdditionsFacility::COMGETTER(Status)(AdditionsFacilityStatus_T *aStatus)
+{
+ LogFlowThisFuncEnter();
+
+ CheckComArgOutPointerValid(aStatus);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ *aStatus = getStatus();
+
+ return S_OK;
+}
+
+STDMETHODIMP AdditionsFacility::COMGETTER(Type)(AdditionsFacilityType_T *aType)
+{
+ LogFlowThisFuncEnter();
+
+ CheckComArgOutPointerValid(aType);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ *aType = getType();
+
+ return S_OK;
+}
+
+const AdditionsFacility::FacilityInfo &AdditionsFacility::typeToInfo(AdditionsFacilityType_T aType)
+{
+ for (size_t i = 0; i < RT_ELEMENTS(sFacilityInfo); ++i)
+ {
+ if (sFacilityInfo[i].mType == aType)
+ return sFacilityInfo[i];
+ }
+ return sFacilityInfo[0]; /* Return unknown type. */
+}
+
+AdditionsFacilityClass_T AdditionsFacility::getClass() const
+{
+ return AdditionsFacility::typeToInfo(mData.mType).mClass;
+}
+
+Bstr AdditionsFacility::getName() const
+{
+ return AdditionsFacility::typeToInfo(mData.mType).mName;
+}
+
+LONG64 AdditionsFacility::getLastUpdated() const
+{
+ return RTTimeSpecGetMilli(&mData.mLastUpdated);
+}
+
+AdditionsFacilityStatus_T AdditionsFacility::getStatus() const
+{
+ return mData.mStatus;
+}
+
+AdditionsFacilityType_T AdditionsFacility::getType() const
+{
+ return mData.mType;
+}
+
+HRESULT AdditionsFacility::update(AdditionsFacilityStatus_T aStatus, RTTIMESPEC aTimestamp)
+{
+ mData.mStatus = aStatus;
+ mData.mLastUpdated = aTimestamp;
+
+ return S_OK;
+}
+
diff --git a/src/VBox/Main/src-client/AudioSnifferInterface.cpp b/src/VBox/Main/src-client/AudioSnifferInterface.cpp
index ee8ea5218..adbf028dd 100644
--- a/src/VBox/Main/src-client/AudioSnifferInterface.cpp
+++ b/src/VBox/Main/src-client/AudioSnifferInterface.cpp
@@ -1,4 +1,4 @@
-/* $Id: AudioSnifferInterface.cpp $ */
+/* $Id: AudioSnifferInterface.cpp 35368 2010-12-30 13:38:23Z vboxsync $ */
/** @file
* VirtualBox Driver Interface to Audio Sniffer device
*/
diff --git a/src/VBox/Main/src-client/BusAssignmentManager.cpp b/src/VBox/Main/src-client/BusAssignmentManager.cpp
index 12b4ab655..3350bd663 100644
--- a/src/VBox/Main/src-client/BusAssignmentManager.cpp
+++ b/src/VBox/Main/src-client/BusAssignmentManager.cpp
@@ -1,4 +1,4 @@
-/* $Id: BusAssignmentManager.cpp $ */
+/* $Id: BusAssignmentManager.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
*
@@ -218,11 +218,18 @@ struct BusAssignmentManager::State
{
struct PciDeviceRecord
{
- char szDevName[32];
+ char szDevName[32];
+ PciBusAddress HostAddress;
+
+ PciDeviceRecord(const char* pszName, PciBusAddress aHostAddress)
+ {
+ RTStrCopy(this->szDevName, sizeof(szDevName), pszName);
+ this->HostAddress = aHostAddress;
+ }
PciDeviceRecord(const char* pszName)
{
- RTStrCopy(szDevName, sizeof(szDevName), pszName);
+ RTStrCopy(this->szDevName, sizeof(szDevName), pszName);
}
bool operator<(const PciDeviceRecord &a) const
@@ -254,7 +261,7 @@ struct BusAssignmentManager::State
HRESULT init(ChipsetType_T chipsetType);
- HRESULT record(const char* pszName, PciBusAddress& Address);
+ HRESULT record(const char* pszName, PciBusAddress& GuestAddress, PciBusAddress HostAddress);
HRESULT autoAssign(const char* pszName, PciBusAddress& Address);
bool checkAvailable(PciBusAddress& Address);
bool findPciAddress(const char* pszDevName, int iInstance, PciBusAddress& Address);
@@ -270,9 +277,9 @@ HRESULT BusAssignmentManager::State::init(ChipsetType_T chipsetType)
return S_OK;
}
-HRESULT BusAssignmentManager::State::record(const char* pszName, PciBusAddress& Address)
+HRESULT BusAssignmentManager::State::record(const char* pszName, PciBusAddress& Address, PciBusAddress HostAddress)
{
- PciDeviceRecord devRec(pszName);
+ PciDeviceRecord devRec(pszName, HostAddress);
/* Remember address -> device mapping */
mPciMap.insert(PciMap::value_type(Address, devRec));
@@ -368,14 +375,14 @@ HRESULT BusAssignmentManager::State::autoAssign(const char* pszName, PciBusAddre
{
const DeviceAssignmentRule* rule = matchingRules[iRule];
- Address.iBus = rule->iBus;
- Address.iDevice = rule->iDevice;
- Address.iFn = rule->iFn;
+ Address.miBus = rule->iBus;
+ Address.miDevice = rule->iDevice;
+ Address.miFn = rule->iFn;
if (checkAvailable(Address))
return S_OK;
}
- AssertMsg(false, ("All possible candidate positions for %s exhausted\n", pszName));
+ AssertMsgFailed(("All possible candidate positions for %s exhausted\n", pszName));
return E_INVALIDARG;
}
@@ -398,7 +405,9 @@ void BusAssignmentManager::State::listAttachedPciDevices(ComSafeArrayOut(IPciDev
{
dev.createObject();
com::Bstr devname(it->second.szDevName);
- dev->init(NULL, devname, -1, it->first.asLong(), FALSE);
+ dev->init(NULL, devname,
+ it->second.HostAddress.valid() ? it->second.HostAddress.asLong() : -1,
+ it->first.asLong(), it->second.HostAddress.valid());
result.setElement(iIndex++, dev);
}
@@ -448,42 +457,45 @@ DECLINLINE(HRESULT) InsertConfigInteger(PCFGMNODE pCfg, const char* pszName, ui
return S_OK;
}
-HRESULT BusAssignmentManager::assignPciDevice(const char* pszDevName, PCFGMNODE pCfg,
- PciBusAddress& Address, bool fAddressRequired)
+HRESULT BusAssignmentManager::assignPciDeviceImpl(const char* pszDevName,
+ PCFGMNODE pCfg,
+ PciBusAddress& GuestAddress,
+ PciBusAddress HostAddress,
+ bool fGuestAddressRequired)
{
HRESULT rc = S_OK;
- if (!Address.valid())
- rc = pState->autoAssign(pszDevName, Address);
+ if (!GuestAddress.valid())
+ rc = pState->autoAssign(pszDevName, GuestAddress);
else
{
- bool fAvailable = pState->checkAvailable(Address);
+ bool fAvailable = pState->checkAvailable(GuestAddress);
if (!fAvailable)
{
- if (fAddressRequired)
+ if (fGuestAddressRequired)
rc = E_ACCESSDENIED;
else
- rc = pState->autoAssign(pszDevName, Address);
+ rc = pState->autoAssign(pszDevName, GuestAddress);
}
}
if (FAILED(rc))
return rc;
- Assert(Address.valid() && pState->checkAvailable(Address));
+ Assert(GuestAddress.valid() && pState->checkAvailable(GuestAddress));
- rc = pState->record(pszDevName, Address);
+ rc = pState->record(pszDevName, GuestAddress, HostAddress);
if (FAILED(rc))
return rc;
- rc = InsertConfigInteger(pCfg, "PCIBusNo", Address.iBus);
+ rc = InsertConfigInteger(pCfg, "PCIBusNo", GuestAddress.miBus);
if (FAILED(rc))
return rc;
- rc = InsertConfigInteger(pCfg, "PCIDeviceNo", Address.iDevice);
+ rc = InsertConfigInteger(pCfg, "PCIDeviceNo", GuestAddress.miDevice);
if (FAILED(rc))
return rc;
- rc = InsertConfigInteger(pCfg, "PCIFunctionNo", Address.iFn);
+ rc = InsertConfigInteger(pCfg, "PCIFunctionNo", GuestAddress.miFn);
if (FAILED(rc))
return rc;
diff --git a/src/VBox/Main/src-client/ConsoleImpl.cpp b/src/VBox/Main/src-client/ConsoleImpl.cpp
index c3d2025b7..126edde3a 100644
--- a/src/VBox/Main/src-client/ConsoleImpl.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: ConsoleImpl.cpp $ */
+/* $Id: ConsoleImpl.cpp 37851 2011-07-08 17:04:03Z vboxsync $ */
/** @file
* VBox Console COM Class implementation
*/
@@ -56,6 +56,9 @@
#include "RemoteUSBDeviceImpl.h"
#include "SharedFolderImpl.h"
#include "AudioSnifferInterface.h"
+#ifdef VBOX_WITH_USB_VIDEO
+# include "UsbWebcamInterface.h"
+#endif
#include "ProgressCombinedImpl.h"
#include "ConsoleVRDPServer.h"
#include "VMMDev.h"
@@ -136,7 +139,7 @@
* callers.
*
* If \a aUsesVMPtr parameter is true, the task structure will also add itself
- * as a Console::mpVM caller with the same meaning as above. See
+ * as a Console::mpUVM caller with the same meaning as above. See
* Console::addVMCaller() for more info.
*/
struct VMTask
@@ -149,7 +152,9 @@ struct VMTask
mConsoleCaller(aConsole),
mProgress(aProgress),
mServerProgress(aServerProgress),
- mVMCallerAdded(false)
+ mpVM(NULL),
+ mRC(E_FAIL),
+ mpSafeVMPtr(NULL)
{
AssertReturnVoid(aConsole);
mRC = mConsoleCaller.rc();
@@ -157,16 +162,17 @@ struct VMTask
return;
if (aUsesVMPtr)
{
- mRC = aConsole->addVMCaller();
- if (SUCCEEDED(mRC))
- mVMCallerAdded = true;
+ mpSafeVMPtr = new Console::SafeVMPtr(aConsole);
+ if (mpSafeVMPtr->isOk())
+ mpVM = mpSafeVMPtr->raw();
+ else
+ mRC = mpSafeVMPtr->rc();
}
}
~VMTask()
{
- if (mVMCallerAdded)
- mConsole->releaseVMCaller();
+ releaseVMCaller();
}
HRESULT rc() const { return mRC; }
@@ -175,21 +181,23 @@ struct VMTask
/** Releases the VM caller before destruction. Not normally necessary. */
void releaseVMCaller()
{
- AssertReturnVoid(mVMCallerAdded);
- mConsole->releaseVMCaller();
- mVMCallerAdded = false;
+ if (mpSafeVMPtr)
+ {
+ delete mpSafeVMPtr;
+ mpSafeVMPtr = NULL;
+ }
}
- const ComObjPtr<Console> mConsole;
- AutoCaller mConsoleCaller;
- const ComObjPtr<Progress> mProgress;
- Utf8Str mErrorMsg;
- const ComPtr<IProgress> mServerProgress;
+ const ComObjPtr<Console> mConsole;
+ AutoCaller mConsoleCaller;
+ const ComObjPtr<Progress> mProgress;
+ Utf8Str mErrorMsg;
+ const ComPtr<IProgress> mServerProgress;
+ PVM mpVM;
private:
-
- HRESULT mRC;
- bool mVMCallerAdded : 1;
+ HRESULT mRC;
+ Console::SafeVMPtr *mpSafeVMPtr;
};
struct VMTakeSnapshotTask : public VMTask
@@ -265,9 +273,18 @@ inline static const char *networkAdapterTypeToName(NetworkAdapterType_T adapterT
class VmEventListener {
public:
- VmEventListener(Console *aConsole)
+ VmEventListener()
+ {}
+
+
+ HRESULT init(Console *aConsole)
{
mConsole = aConsole;
+ return S_OK;
+ }
+
+ void uninit()
+ {
}
virtual ~VmEventListener()
@@ -313,8 +330,15 @@ public:
mConsole->onNATRedirectRuleChange(ulSlot, fRemove, proto, hostIp.raw(), hostPort, guestIp.raw(), guestPort);
}
break;
+
+ case VBoxEventType_OnHostPciDevicePlug:
+ {
+ // handle if needed
+ break;
+ }
+
default:
- AssertFailed();
+ AssertFailed();
}
return S_OK;
}
@@ -334,7 +358,7 @@ VBOX_LISTENER_DECLARE(VmEventListenerImpl)
Console::Console()
: mSavedStateDataLoaded(false)
, mConsoleVRDPServer(NULL)
- , mpVM(NULL)
+ , mpUVM(NULL)
, mVMCallers(0)
, mVMZeroCallersSem(NIL_RTSEMEVENT)
, mVMDestroying(false)
@@ -346,8 +370,12 @@ Console::Console()
, mpVmm2UserMethods(NULL)
, m_pVMMDev(NULL)
, mAudioSniffer(NULL)
+#ifdef VBOX_WITH_USB_VIDEO
+ , mUsbWebcamInterface(NULL)
+#endif
, mBusMgr(NULL)
, mVMStateChangeCallbackDisabled(false)
+ , mfUseHostClipboard(true)
, mMachineState(MachineState_PoweredOff)
{
for (ULONG slot = 0; slot < SchemaDefs::NetworkAdapterCount; ++slot)
@@ -383,7 +411,7 @@ HRESULT Console::FinalConstruct()
pVmm2UserMethods->pConsole = this;
mpVmm2UserMethods = pVmm2UserMethods;
- return S_OK;
+ return BaseFinalConstruct();
}
void Console::FinalRelease()
@@ -391,6 +419,8 @@ void Console::FinalRelease()
LogFlowThisFunc(("\n"));
uninit();
+
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
@@ -480,6 +510,10 @@ HRESULT Console::init(IMachine *aMachine, IInternalMachineControl *aControl)
unconst(mAudioSniffer) = new AudioSniffer(this);
AssertReturn(mAudioSniffer, E_FAIL);
+#ifdef VBOX_WITH_USB_VIDEO
+ unconst(mUsbWebcamInterface) = new UsbWebcamInterface(this);
+ AssertReturn(mUsbWebcamInterface, E_FAIL);
+#endif
/* VirtualBox events registration. */
{
@@ -490,10 +524,14 @@ HRESULT Console::init(IMachine *aMachine, IInternalMachineControl *aControl)
ComPtr<IEventSource> pES;
rc = pVirtualBox->COMGETTER(EventSource)(pES.asOutParam());
AssertComRC(rc);
- mVmListner = new VmEventListenerImpl(this);
+ ComObjPtr<VmEventListenerImpl> aVmListener;
+ aVmListener.createObject();
+ aVmListener->init(new VmEventListener(), this);
+ mVmListener = aVmListener;
com::SafeArray<VBoxEventType_T> eventTypes;
eventTypes.push_back(VBoxEventType_OnNATRedirect);
- rc = pES->RegisterListener(mVmListner, ComSafeArrayAsInParam(eventTypes), true);
+ eventTypes.push_back(VBoxEventType_OnHostPciDevicePlug);
+ rc = pES->RegisterListener(aVmListener, ComSafeArrayAsInParam(eventTypes), true);
AssertComRC(rc);
}
@@ -529,7 +567,7 @@ void Console::uninit()
}
LogFlowThisFunc(("initFailed()=%d\n", autoUninitSpan.initFailed()));
- if (mVmListner)
+ if (mVmListener)
{
ComPtr<IEventSource> pES;
ComPtr<IVirtualBox> pVirtualBox;
@@ -541,18 +579,18 @@ void Console::uninit()
AssertComRC(rc);
if (!pES.isNull())
{
- rc = pES->UnregisterListener(mVmListner);
+ rc = pES->UnregisterListener(mVmListener);
AssertComRC(rc);
}
}
- mVmListner->Release();
+ mVmListener.setNull();
}
/* power down the VM if necessary */
- if (mpVM)
+ if (mpUVM)
{
powerDown();
- Assert(mpVM == NULL);
+ Assert(mpUVM == NULL);
}
if (mVMZeroCallersSem != NIL_RTSEMEVENT)
@@ -567,6 +605,14 @@ void Console::uninit()
mpVmm2UserMethods = NULL;
}
+#ifdef VBOX_WITH_USB_VIDEO
+ if (mUsbWebcamInterface)
+ {
+ delete mUsbWebcamInterface;
+ unconst(mUsbWebcamInterface) = NULL;
+ }
+#endif
+
if (mAudioSniffer)
{
delete mAudioSniffer;
@@ -652,8 +698,13 @@ void Console::uninit()
/**
* Handles guest properties on a VM reset.
- * At the moment we only delete properties which have the flag
- * "TRANSRESET".
+ *
+ * We must delete properties that are flagged TRANSRESET.
+ *
+ * @todo r=bird: Would be more efficient if we added a request to the HGCM
+ * service to do this instead of detouring thru VBoxSVC.
+ * (IMachine::SetGuestProperty ends up in VBoxSVC, which in turns calls
+ * back into the VM process and the HGCM service.)
*/
void Console::guestPropertiesHandleVMReset(void)
{
@@ -1745,7 +1796,39 @@ STDMETHODIMP Console::COMGETTER(AttachedPciDevices)(ComSafeArrayOut(IPciDeviceAt
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- mBusMgr->listAttachedPciDevices(ComSafeArrayOutArg(aAttachments));
+ if (mBusMgr)
+ mBusMgr->listAttachedPciDevices(ComSafeArrayOutArg(aAttachments));
+ else
+ {
+ com::SafeIfaceArray<IPciDeviceAttachment> result((size_t)0);
+ result.detachTo(ComSafeArrayOutArg(aAttachments));
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP Console::COMGETTER(UseHostClipboard)(BOOL *aUseHostClipboard)
+{
+ CheckComArgOutPointerValid(aUseHostClipboard);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ *aUseHostClipboard = mfUseHostClipboard;
+
+ return S_OK;
+}
+
+STDMETHODIMP Console::COMSETTER(UseHostClipboard)(BOOL aUseHostClipboard)
+{
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ mfUseHostClipboard = aUseHostClipboard;
return S_OK;
}
@@ -1913,14 +1996,15 @@ STDMETHODIMP Console::Reset()
)
return setInvalidMachineStateError();
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+ /* protect mpUVM */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
/* leave the lock before a VMR3* call (EMT will call us back)! */
alock.leave();
- int vrc = VMR3Reset(mpVM);
+ int vrc = VMR3Reset(ptrVM);
HRESULT rc = RT_SUCCESS(vrc) ? S_OK :
setError(VBOX_E_VM_ERROR,
@@ -1932,19 +2016,19 @@ STDMETHODIMP Console::Reset()
return rc;
}
-DECLCALLBACK(int) Console::unplugCpu(Console *pThis, unsigned uCpu)
+/*static*/ DECLCALLBACK(int) Console::unplugCpu(Console *pThis, PVM pVM, unsigned uCpu)
{
- LogFlowFunc(("pThis=%p uCpu=%u\n", pThis, uCpu));
+ LogFlowFunc(("pThis=%p pVM=%p uCpu=%u\n", pThis, pVM, uCpu));
AssertReturn(pThis, VERR_INVALID_PARAMETER);
- int vrc = PDMR3DeviceDetach(pThis->mpVM, "acpi", 0, uCpu, 0);
+ int vrc = PDMR3DeviceDetach(pVM, "acpi", 0, uCpu, 0);
Log(("UnplugCpu: rc=%Rrc\n", vrc));
return vrc;
}
-HRESULT Console::doCPURemove(ULONG aCpu)
+HRESULT Console::doCPURemove(ULONG aCpu, PVM pVM)
{
HRESULT rc = S_OK;
@@ -1957,8 +2041,8 @@ HRESULT Console::doCPURemove(ULONG aCpu)
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
AssertReturn(m_pVMMDev, E_FAIL);
- PPDMIVMMDEVPORT pDevPort = m_pVMMDev->getVMMDevPort();
- AssertReturn(pDevPort, E_FAIL);
+ PPDMIVMMDEVPORT pVmmDevPort = m_pVMMDev->getVMMDevPort();
+ AssertReturn(pVmmDevPort, E_FAIL);
if ( mMachineState != MachineState_Running
&& mMachineState != MachineState_Teleporting
@@ -1966,48 +2050,38 @@ HRESULT Console::doCPURemove(ULONG aCpu)
)
return setInvalidMachineStateError();
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
/* Check if the CPU is present */
BOOL fCpuAttached;
rc = mMachine->GetCPUStatus(aCpu, &fCpuAttached);
- if (FAILED(rc)) return rc;
-
+ if (FAILED(rc))
+ return rc;
if (!fCpuAttached)
- return setError(E_FAIL,
- tr("CPU %d is not attached"), aCpu);
+ return setError(E_FAIL, tr("CPU %d is not attached"), aCpu);
/* Leave the lock before any EMT/VMMDev call. */
alock.release();
+ bool fLocked = true;
/* Check if the CPU is unlocked */
PPDMIBASE pBase;
- int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, aCpu, &pBase);
- bool fLocked = true;
+ int vrc = PDMR3QueryDeviceLun(pVM, "acpi", 0, aCpu, &pBase);
if (RT_SUCCESS(vrc))
{
- uint32_t idCpuCore, idCpuPackage;
-
- /* Notify the guest if possible. */
- vrc = VMR3GetCpuCoreAndPackageIdFromCpuId(mpVM, aCpu, &idCpuCore, &idCpuPackage);
- AssertRC(vrc);
-
Assert(pBase);
+ PPDMIACPIPORT pApicPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
- PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
-
- vrc = pDevPort->pfnCpuHotUnplug(pDevPort, idCpuCore, idCpuPackage);
+ /* Notify the guest if possible. */
+ uint32_t idCpuCore, idCpuPackage;
+ vrc = VMR3GetCpuCoreAndPackageIdFromCpuId(pVM, aCpu, &idCpuCore, &idCpuPackage); AssertRC(vrc);
+ if (RT_SUCCESS(vrc))
+ vrc = pVmmDevPort->pfnCpuHotUnplug(pVmmDevPort, idCpuCore, idCpuPackage);
if (RT_SUCCESS(vrc))
{
unsigned cTries = 100;
-
do
{
- /* It will take some time until the event is processed in the guest. Wait */
- vrc = pPort ? pPort->pfnGetCpuStatus(pPort, aCpu, &fLocked) : VERR_INVALID_POINTER;
-
+ /* It will take some time until the event is processed in the guest. Wait... */
+ vrc = pApicPort ? pApicPort->pfnGetCpuStatus(pApicPort, aCpu, &fLocked) : VERR_INVALID_POINTER;
if (RT_SUCCESS(vrc) && !fLocked)
break;
@@ -2018,7 +2092,7 @@ HRESULT Console::doCPURemove(ULONG aCpu)
else if (vrc == VERR_CPU_HOTPLUG_NOT_MONITORED_BY_GUEST)
{
/* Query one time. It is possible that the user ejected the CPU. */
- vrc = pPort ? pPort->pfnGetCpuStatus(pPort, aCpu, &fLocked) : VERR_INVALID_POINTER;
+ vrc = pApicPort ? pApicPort->pfnGetCpuStatus(pApicPort, aCpu, &fLocked) : VERR_INVALID_POINTER;
}
}
@@ -2030,10 +2104,9 @@ HRESULT Console::doCPURemove(ULONG aCpu)
* using VMR3ReqCall.
*/
PVMREQ pReq;
- vrc = VMR3ReqCall(mpVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
- (PFNRT)Console::unplugCpu, 2,
- this, aCpu);
-
+ vrc = VMR3ReqCall(pVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
+ (PFNRT)Console::unplugCpu, 3,
+ this, pVM, aCpu);
if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
{
vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
@@ -2046,7 +2119,7 @@ HRESULT Console::doCPURemove(ULONG aCpu)
if (RT_SUCCESS(vrc))
{
/* Detach it from the VM */
- vrc = VMR3HotUnplugCpu(mpVM, aCpu);
+ vrc = VMR3HotUnplugCpu(pVM, aCpu);
AssertRC(vrc);
}
else
@@ -2062,16 +2135,16 @@ HRESULT Console::doCPURemove(ULONG aCpu)
return rc;
}
-DECLCALLBACK(int) Console::plugCpu(Console *pThis, unsigned uCpu)
+/*static*/ DECLCALLBACK(int) Console::plugCpu(Console *pThis, PVM pVM, unsigned uCpu)
{
LogFlowFunc(("pThis=%p uCpu=%u\n", pThis, uCpu));
AssertReturn(pThis, VERR_INVALID_PARAMETER);
- int rc = VMR3HotPlugCpu(pThis->mpVM, uCpu);
+ int rc = VMR3HotPlugCpu(pVM, uCpu);
AssertRC(rc);
- PCFGMNODE pInst = CFGMR3GetChild(CFGMR3GetRoot(pThis->mpVM), "Devices/acpi/0/");
+ PCFGMNODE pInst = CFGMR3GetChild(CFGMR3GetRoot(pVM), "Devices/acpi/0/");
AssertRelease(pInst);
/* nuke anything which might have been left behind. */
CFGMR3RemoveNode(CFGMR3GetChildF(pInst, "LUN#%d", uCpu));
@@ -2088,7 +2161,7 @@ DECLCALLBACK(int) Console::plugCpu(Console *pThis, unsigned uCpu)
* Attach the driver.
*/
PPDMIBASE pBase;
- rc = PDMR3DeviceAttach(pThis->mpVM, "acpi", 0, uCpu, 0, &pBase); RC_CHECK();
+ rc = PDMR3DeviceAttach(pVM, "acpi", 0, uCpu, 0, &pBase); RC_CHECK();
Log(("PlugCpu: rc=%Rrc\n", rc));
@@ -2099,7 +2172,7 @@ DECLCALLBACK(int) Console::plugCpu(Console *pThis, unsigned uCpu)
return VINF_SUCCESS;
}
-HRESULT Console::doCPUAdd(ULONG aCpu)
+HRESULT Console::doCPUAdd(ULONG aCpu, PVM pVM)
{
HRESULT rc = S_OK;
@@ -2122,10 +2195,6 @@ HRESULT Console::doCPUAdd(ULONG aCpu)
PPDMIVMMDEVPORT pDevPort = m_pVMMDev->getVMMDevPort();
AssertReturn(pDevPort, E_FAIL);
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
/* Check if the CPU is present */
BOOL fCpuAttached;
rc = mMachine->GetCPUStatus(aCpu, &fCpuAttached);
@@ -2141,9 +2210,9 @@ HRESULT Console::doCPUAdd(ULONG aCpu)
* here to make requests from under the lock in order to serialize them.
*/
PVMREQ pReq;
- int vrc = VMR3ReqCall(mpVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
- (PFNRT)Console::plugCpu, 2,
- this, aCpu);
+ int vrc = VMR3ReqCall(pVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
+ (PFNRT)Console::plugCpu, 3,
+ this, pVM, aCpu);
/* leave the lock before a VMR3* call (EMT will call us back)! */
alock.release();
@@ -2164,13 +2233,11 @@ HRESULT Console::doCPUAdd(ULONG aCpu)
if (RT_SUCCESS(vrc))
{
- uint32_t idCpuCore, idCpuPackage;
-
/* Notify the guest if possible. */
- vrc = VMR3GetCpuCoreAndPackageIdFromCpuId(mpVM, aCpu, &idCpuCore, &idCpuPackage);
- AssertRC(vrc);
-
- vrc = pDevPort->pfnCpuHotPlug(pDevPort, idCpuCore, idCpuPackage);
+ uint32_t idCpuCore, idCpuPackage;
+ vrc = VMR3GetCpuCoreAndPackageIdFromCpuId(pVM, aCpu, &idCpuCore, &idCpuPackage); AssertRC(vrc);
+ if (RT_SUCCESS(vrc))
+ vrc = pDevPort->pfnCpuHotPlug(pDevPort, idCpuCore, idCpuPackage);
/** @todo warning if the guest doesn't support it */
}
@@ -2204,16 +2271,17 @@ STDMETHODIMP Console::Pause()
return setInvalidMachineStateError();
}
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+ /* get the VM handle. */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
LogFlowThisFunc(("Sending PAUSE request...\n"));
/* leave the lock before a VMR3* call (EMT will call us back)! */
alock.leave();
- int vrc = VMR3Suspend(mpVM);
+ int vrc = VMR3Suspend(ptrVM);
HRESULT hrc = S_OK;
if (RT_FAILURE(vrc))
@@ -2238,9 +2306,10 @@ STDMETHODIMP Console::Resume()
tr("Cannot resume the machine as it is not paused (machine state: %s)"),
Global::stringifyMachineState(mMachineState));
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+ /* get the VM handle. */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
LogFlowThisFunc(("Sending RESUME request...\n"));
@@ -2248,16 +2317,16 @@ STDMETHODIMP Console::Resume()
alock.leave();
#ifdef VBOX_WITH_EXTPACK
- int vrc = mptrExtPackManager->callAllVmPowerOnHooks(this, mpVM); /** @todo called a few times too many... */
+ int vrc = mptrExtPackManager->callAllVmPowerOnHooks(this, ptrVM); /** @todo called a few times too many... */
#else
int vrc = VINF_SUCCESS;
#endif
if (RT_SUCCESS(vrc))
{
- if (VMR3GetState(mpVM) == VMSTATE_CREATED)
- vrc = VMR3PowerOn(mpVM); /* (PowerUpPaused) */
+ if (VMR3GetState(ptrVM) == VMSTATE_CREATED)
+ vrc = VMR3PowerOn(ptrVM); /* (PowerUpPaused) */
else
- vrc = VMR3Resume(mpVM);
+ vrc = VMR3Resume(ptrVM);
}
HRESULT rc = RT_SUCCESS(vrc) ? S_OK :
@@ -2285,17 +2354,23 @@ STDMETHODIMP Console::PowerButton()
)
return setInvalidMachineStateError();
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+ /* get the VM handle. */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
+/** @todo leave the console lock? */
+ /* get the acpi device interface and press the button. */
PPDMIBASE pBase;
- int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase);
+ int vrc = PDMR3QueryDeviceLun(ptrVM, "acpi", 0, 0, &pBase);
if (RT_SUCCESS(vrc))
{
Assert(pBase);
PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
- vrc = pPort ? pPort->pfnPowerButtonPress(pPort) : VERR_INVALID_POINTER;
+ if (pPort)
+ vrc = pPort->pfnPowerButtonPress(pPort);
+ else
+ vrc = VERR_PDM_MISSING_INTERFACE;
}
HRESULT rc = RT_SUCCESS(vrc) ? S_OK :
@@ -2326,18 +2401,28 @@ STDMETHODIMP Console::GetPowerButtonHandled(BOOL *aHandled)
)
return setInvalidMachineStateError();
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+ /* get the VM handle. */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
+/** @todo leave the console lock? */
+ /* get the acpi device interface and check if the button press was handled. */
PPDMIBASE pBase;
- int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase);
- bool handled = false;
+ int vrc = PDMR3QueryDeviceLun(ptrVM, "acpi", 0, 0, &pBase);
if (RT_SUCCESS(vrc))
{
Assert(pBase);
PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
- vrc = pPort ? pPort->pfnGetPowerButtonHandled(pPort, &handled) : VERR_INVALID_POINTER;
+ if (pPort)
+ {
+ bool fHandled = false;
+ vrc = pPort->pfnGetPowerButtonHandled(pPort, &fHandled);
+ if (RT_SUCCESS(vrc))
+ *aHandled = fHandled;
+ }
+ else
+ vrc = VERR_PDM_MISSING_INTERFACE;
}
HRESULT rc = RT_SUCCESS(vrc) ? S_OK :
@@ -2345,8 +2430,6 @@ STDMETHODIMP Console::GetPowerButtonHandled(BOOL *aHandled)
tr("Checking if the ACPI Power Button event was handled by the guest OS failed (%Rrc)"),
vrc);
- *aHandled = handled;
-
LogFlowThisFunc(("rc=%Rhrc\n", rc));
LogFlowThisFuncLeave();
return rc;
@@ -2372,22 +2455,31 @@ STDMETHODIMP Console::GetGuestEnteredACPIMode(BOOL *aEntered)
tr("Invalid machine state %s when checking if the guest entered the ACPI mode)"),
Global::stringifyMachineState(mMachineState));
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+ /* get the VM handle. */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
+/** @todo leave the console lock? */
+
+ /* get the acpi device interface and query the information. */
PPDMIBASE pBase;
- int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase);
- bool entered = false;
+ int vrc = PDMR3QueryDeviceLun(ptrVM, "acpi", 0, 0, &pBase);
if (RT_SUCCESS(vrc))
{
Assert(pBase);
PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
- vrc = pPort ? pPort->pfnGetGuestEnteredACPIMode(pPort, &entered) : VERR_INVALID_POINTER;
+ if (pPort)
+ {
+ bool fEntered = false;
+ vrc = pPort->pfnGetGuestEnteredACPIMode(pPort, &fEntered);
+ if (RT_SUCCESS(vrc))
+ *aEntered = fEntered;
+ }
+ else
+ vrc = VERR_PDM_MISSING_INTERFACE;
}
- *aEntered = RT_SUCCESS(vrc) ? entered : false;
-
LogFlowThisFuncLeave();
return S_OK;
}
@@ -2404,17 +2496,24 @@ STDMETHODIMP Console::SleepButton()
if (mMachineState != MachineState_Running) /** @todo Live Migration: ??? */
return setInvalidMachineStateError();
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+ /* get the VM handle. */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
+
+/** @todo leave the console lock? */
+ /* get the acpi device interface and press the sleep button. */
PPDMIBASE pBase;
- int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase);
+ int vrc = PDMR3QueryDeviceLun(ptrVM, "acpi", 0, 0, &pBase);
if (RT_SUCCESS(vrc))
{
Assert(pBase);
PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
- vrc = pPort ? pPort->pfnSleepButtonPress(pPort) : VERR_INVALID_POINTER;
+ if (pPort)
+ vrc = pPort->pfnSleepButtonPress(pPort);
+ else
+ vrc = VERR_PDM_MISSING_INTERFACE;
}
HRESULT rc = RT_SUCCESS(vrc) ? S_OK :
@@ -2453,7 +2552,8 @@ STDMETHODIMP Console::SaveState(IProgress **aProgress)
if (mMachineState == MachineState_Running)
{
HRESULT rc = Pause();
- if (FAILED(rc)) return rc;
+ if (FAILED(rc))
+ return rc;
}
HRESULT rc = S_OK;
@@ -2472,7 +2572,8 @@ STDMETHODIMP Console::SaveState(IProgress **aProgress)
*/
rc = mControl->BeginSavingState(pProgress.asOutParam(),
stateFilePath.asOutParam());
- if (FAILED(rc)) break;
+ if (FAILED(rc))
+ break;
fBeganSavingState = true;
@@ -2513,7 +2614,7 @@ STDMETHODIMP Console::SaveState(IProgress **aProgress)
}
/* create a thread to wait until the VM state is saved */
- int vrc = RTThreadCreate(NULL, Console::saveStateThread, (void *) task.get(),
+ int vrc = RTThreadCreate(NULL, Console::saveStateThread, (void *)task.get(),
0, RTTHREADTYPE_MAIN_WORKER, 0, "VMSave");
if (RT_FAILURE(vrc))
{
@@ -2526,8 +2627,7 @@ STDMETHODIMP Console::SaveState(IProgress **aProgress)
/* return the progress to the caller */
pProgress.queryInterfaceTo(aProgress);
- }
- while (0);
+ } while (0);
if (FAILED(rc) && !fTaskCreationFailed)
{
@@ -2699,13 +2799,14 @@ STDMETHODIMP Console::AttachUSBDevice(IN_BSTR aId)
tr("Cannot attach a USB device to the machine which is not running or paused (machine state: %s)"),
Global::stringifyMachineState(mMachineState));
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+ /* Get the VM handle. */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
/* Don't proceed unless we've found the usb controller. */
PPDMIBASE pBase = NULL;
- int vrc = PDMR3QueryLun(mpVM, "usb-ohci", 0, 0, &pBase);
+ int vrc = PDMR3QueryLun(ptrVM, "usb-ohci", 0, 0, &pBase);
if (RT_FAILURE(vrc))
return setError(VBOX_E_PDM_ERROR,
tr("The virtual machine does not have a USB controller"));
@@ -2715,10 +2816,7 @@ STDMETHODIMP Console::AttachUSBDevice(IN_BSTR aId)
alock.leave();
/* Request the device capture */
- HRESULT rc = mControl->CaptureUSBDevice(aId);
- if (FAILED(rc)) return rc;
-
- return rc;
+ return mControl->CaptureUSBDevice(aId);
#else /* !VBOX_WITH_USB */
return setError(VBOX_E_PDM_ERROR,
@@ -2903,29 +3001,27 @@ Console::CreateSharedFolder(IN_BSTR aName, IN_BSTR aHostPath, BOOL aWritable, BO
true /* fFailOnError */);
if (FAILED(rc)) return rc;
- /* protect mpVM (if not NULL) */
- AutoVMCallerQuietWeak autoVMCaller(this);
-
- if ( mpVM
- && autoVMCaller.isOk()
+ /* If the VM is online and supports shared folders, share this folder
+ * under the specified name. (Ignore any failure to obtain the VM handle.) */
+ SafeVMPtrQuiet ptrVM(this);
+ if ( ptrVM.isOk()
&& m_pVMMDev
&& m_pVMMDev->isShFlActive()
)
{
- /* If the VM is online and supports shared folders, share this folder
- * under the specified name. */
-
/* first, remove the machine or the global folder if there is any */
SharedFolderDataMap::const_iterator it;
if (findOtherSharedFolder(aName, it))
{
rc = removeSharedFolder(aName);
- if (FAILED(rc)) return rc;
+ if (FAILED(rc))
+ return rc;
}
/* second, create the given folder */
rc = createSharedFolder(aName, SharedFolderData(aHostPath, aWritable, aAutoMount));
- if (FAILED(rc)) return rc;
+ if (FAILED(rc))
+ return rc;
}
m_mapSharedFolders.insert(std::make_pair(aName, pSharedFolder));
@@ -2969,11 +3065,9 @@ STDMETHODIMP Console::RemoveSharedFolder(IN_BSTR aName)
HRESULT rc = findSharedFolder(aName, pSharedFolder, true /* aSetError */);
if (FAILED(rc)) return rc;
- /* protect mpVM (if not NULL) */
- AutoVMCallerQuietWeak autoVMCaller(this);
-
- if ( mpVM
- && autoVMCaller.isOk()
+ /* protect the VM handle (if not NULL) */
+ SafeVMPtrQuiet ptrVM(this);
+ if ( ptrVM.isOk()
&& m_pVMMDev
&& m_pVMMDev->isShFlActive()
)
@@ -3061,16 +3155,13 @@ STDMETHODIMP Console::TakeSnapshot(IN_BSTR aName,
}
// b) one extra sub-operations for online snapshots OR offline snapshots that have a saved state (needs to be copied)
- bool fTakingSnapshotOnline = ((mMachineState == MachineState_Running) || (mMachineState == MachineState_Paused));
+ bool const fTakingSnapshotOnline = Global::IsOnline(mMachineState);
LogFlowFunc(("fTakingSnapshotOnline = %d, mMachineState = %d\n", fTakingSnapshotOnline, mMachineState));
- if ( fTakingSnapshotOnline
- || mMachineState == MachineState_Saved
- )
+ if (fTakingSnapshotOnline)
{
++cOperations;
-
ulTotalOperationsWeight += ulMemSize;
}
@@ -3115,7 +3206,7 @@ STDMETHODIMP Console::TakeSnapshot(IN_BSTR aName,
int vrc = RTThreadCreate(NULL,
Console::fntTakeSnapshotWorker,
- (void*)pTask,
+ (void *)pTask,
0,
RTTHREADTYPE_MAIN_WORKER,
0,
@@ -3154,9 +3245,55 @@ STDMETHODIMP Console::DeleteSnapshot(IN_BSTR aId, IProgress **aProgress)
tr("Cannot delete a snapshot of the machine while it is changing the state (machine state: %s)"),
Global::stringifyMachineState(mMachineState));
+ MachineState_T machineState = MachineState_Null;
+ HRESULT rc = mControl->DeleteSnapshot(this, aId, aId, FALSE /* fDeleteAllChildren */, &machineState, aProgress);
+ if (FAILED(rc)) return rc;
+
+ setMachineStateLocally(machineState);
+ return S_OK;
+}
+
+STDMETHODIMP Console::DeleteSnapshotAndAllChildren(IN_BSTR aId, IProgress **aProgress)
+{
+ CheckComArgExpr(aId, Guid(aId).isEmpty() == false);
+ CheckComArgOutPointerValid(aProgress);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ if (Global::IsTransient(mMachineState))
+ return setError(VBOX_E_INVALID_VM_STATE,
+ tr("Cannot delete a snapshot of the machine while it is changing the state (machine state: %s)"),
+ Global::stringifyMachineState(mMachineState));
+
+ MachineState_T machineState = MachineState_Null;
+ HRESULT rc = mControl->DeleteSnapshot(this, aId, aId, TRUE /* fDeleteAllChildren */, &machineState, aProgress);
+ if (FAILED(rc)) return rc;
+
+ setMachineStateLocally(machineState);
+ return S_OK;
+}
+
+STDMETHODIMP Console::DeleteSnapshotRange(IN_BSTR aStartId, IN_BSTR aEndId, IProgress **aProgress)
+{
+ CheckComArgExpr(aStartId, Guid(aStartId).isEmpty() == false);
+ CheckComArgExpr(aEndId, Guid(aEndId).isEmpty() == false);
+ CheckComArgOutPointerValid(aProgress);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ if (Global::IsTransient(mMachineState))
+ return setError(VBOX_E_INVALID_VM_STATE,
+ tr("Cannot delete a snapshot of the machine while it is changing the state (machine state: %s)"),
+ Global::stringifyMachineState(mMachineState));
MachineState_T machineState = MachineState_Null;
- HRESULT rc = mControl->DeleteSnapshot(this, aId, &machineState, aProgress);
+ HRESULT rc = mControl->DeleteSnapshot(this, aStartId, aEndId, FALSE /* fDeleteAllChildren */, &machineState, aProgress);
if (FAILED(rc)) return rc;
setMachineStateLocally(machineState);
@@ -3296,10 +3433,11 @@ HRESULT Console::convertBusPortDeviceToLun(StorageBus_T enmBus, LONG port, LONG
*
* @param aMediumAttachment The medium attachment with the new medium state.
* @param fForce Force medium chance, if it is locked or not.
+ * @param pVM Safe VM handle.
*
* @note Locks this object for writing.
*/
-HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForce)
+HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForce, PVM pVM)
{
AutoCaller autoCaller(this);
AssertComRCReturnRC(autoCaller.rc());
@@ -3357,24 +3495,21 @@ HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForc
rc = pStorageController->COMGETTER(UseHostIOCache)(&fUseHostIOCache);
AssertComRC(rc);
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- AssertComRCReturnRC(autoVMCaller.rc());
-
/*
* Call worker in EMT, that's faster and safer than doing everything
* using VMR3ReqCall. Note that we separate VMR3ReqCall from VMR3ReqWait
* here to make requests from under the lock in order to serialize them.
*/
PVMREQ pReq;
- int vrc = VMR3ReqCall(mpVM,
+ int vrc = VMR3ReqCall(pVM,
VMCPUID_ANY,
-&pReq,
+ &pReq,
0 /* no wait! */,
VMREQFLAGS_VBOX_STATUS,
(PFNRT)Console::changeRemovableMedium,
- 7,
+ 8,
this,
+ pVM,
pszDevice,
uInstance,
enmBus,
@@ -3400,7 +3535,7 @@ HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForc
return S_OK;
}
- if (!pMedium)
+ if (pMedium)
return setError(E_FAIL,
tr("Could not mount the media/drive '%ls' (%Rrc)"),
mediumLocation.raw(), vrc);
@@ -3416,6 +3551,7 @@ HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForc
* @returns VBox status code.
*
* @param pThis Pointer to the Console object.
+ * @param pVM The VM handle.
* @param pcszDevice The PDM device name.
* @param uInstance The PDM device instance.
* @param uLun The PDM LUN number of the drive.
@@ -3430,6 +3566,7 @@ HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForc
* @thread EMT
*/
DECLCALLBACK(int) Console::changeRemovableMedium(Console *pConsole,
+ PVM pVM,
const char *pcszDevice,
unsigned uInstance,
StorageBus_T enmBus,
@@ -3445,8 +3582,6 @@ DECLCALLBACK(int) Console::changeRemovableMedium(Console *pConsole,
AutoCaller autoCaller(pConsole);
AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
- PVM pVM = pConsole->mpVM;
-
/*
* Suspend the VM first.
*
@@ -3511,6 +3646,7 @@ DECLCALLBACK(int) Console::changeRemovableMedium(Console *pConsole,
NULL /* phrc */,
true /* fAttachDetach */,
fForce /* fForceUnmount */,
+ false /* fHotplug */,
pVM,
NULL /* paLedDevType */);
/** @todo this dumps everything attached to this device instance, which
@@ -3548,6 +3684,504 @@ DECLCALLBACK(int) Console::changeRemovableMedium(Console *pConsole,
/**
+ * Attach a new storage device to the VM.
+ *
+ * @param aMediumAttachment The medium attachment which is added.
+ * @param pVM Safe VM handle.
+ *
+ * @note Locks this object for writing.
+ */
+HRESULT Console::doStorageDeviceAttach(IMediumAttachment *aMediumAttachment, PVM pVM)
+{
+ AutoCaller autoCaller(this);
+ AssertComRCReturnRC(autoCaller.rc());
+
+ /* We will need to release the write lock before calling EMT */
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ HRESULT rc = S_OK;
+ const char *pszDevice = NULL;
+
+ SafeIfaceArray<IStorageController> ctrls;
+ rc = mMachine->COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(ctrls));
+ AssertComRC(rc);
+ IMedium *pMedium;
+ rc = aMediumAttachment->COMGETTER(Medium)(&pMedium);
+ AssertComRC(rc);
+ Bstr mediumLocation;
+ if (pMedium)
+ {
+ rc = pMedium->COMGETTER(Location)(mediumLocation.asOutParam());
+ AssertComRC(rc);
+ }
+
+ Bstr attCtrlName;
+ rc = aMediumAttachment->COMGETTER(Controller)(attCtrlName.asOutParam());
+ AssertComRC(rc);
+ ComPtr<IStorageController> pStorageController;
+ for (size_t i = 0; i < ctrls.size(); ++i)
+ {
+ Bstr ctrlName;
+ rc = ctrls[i]->COMGETTER(Name)(ctrlName.asOutParam());
+ AssertComRC(rc);
+ if (attCtrlName == ctrlName)
+ {
+ pStorageController = ctrls[i];
+ break;
+ }
+ }
+ if (pStorageController.isNull())
+ return setError(E_FAIL,
+ tr("Could not find storage controller '%ls'"), attCtrlName.raw());
+
+ StorageControllerType_T enmCtrlType;
+ rc = pStorageController->COMGETTER(ControllerType)(&enmCtrlType);
+ AssertComRC(rc);
+ pszDevice = convertControllerTypeToDev(enmCtrlType);
+
+ StorageBus_T enmBus;
+ rc = pStorageController->COMGETTER(Bus)(&enmBus);
+ AssertComRC(rc);
+ ULONG uInstance;
+ rc = pStorageController->COMGETTER(Instance)(&uInstance);
+ AssertComRC(rc);
+ BOOL fUseHostIOCache;
+ rc = pStorageController->COMGETTER(UseHostIOCache)(&fUseHostIOCache);
+ AssertComRC(rc);
+
+ /*
+ * Call worker in EMT, that's faster and safer than doing everything
+ * using VMR3ReqCall. Note that we separate VMR3ReqCall from VMR3ReqWait
+ * here to make requests from under the lock in order to serialize them.
+ */
+ PVMREQ pReq;
+ int vrc = VMR3ReqCall(pVM,
+ VMCPUID_ANY,
+ &pReq,
+ 0 /* no wait! */,
+ VMREQFLAGS_VBOX_STATUS,
+ (PFNRT)Console::attachStorageDevice,
+ 7,
+ this,
+ pVM,
+ pszDevice,
+ uInstance,
+ enmBus,
+ fUseHostIOCache,
+ aMediumAttachment);
+
+ /* leave the lock before waiting for a result (EMT will call us back!) */
+ alock.leave();
+
+ if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
+ {
+ vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
+ AssertRC(vrc);
+ if (RT_SUCCESS(vrc))
+ vrc = pReq->iStatus;
+ }
+ VMR3ReqFree(pReq);
+
+ if (RT_SUCCESS(vrc))
+ {
+ LogFlowThisFunc(("Returns S_OK\n"));
+ return S_OK;
+ }
+
+ if (!pMedium)
+ return setError(E_FAIL,
+ tr("Could not mount the media/drive '%ls' (%Rrc)"),
+ mediumLocation.raw(), vrc);
+
+ return setError(E_FAIL,
+ tr("Could not unmount the currently mounted media/drive (%Rrc)"),
+ vrc);
+}
+
+
+/**
+ * Performs the storage attach operation in EMT.
+ *
+ * @returns VBox status code.
+ *
+ * @param pThis Pointer to the Console object.
+ * @param pVM The VM handle.
+ * @param pcszDevice The PDM device name.
+ * @param uInstance The PDM device instance.
+ *
+ * @thread EMT
+ */
+DECLCALLBACK(int) Console::attachStorageDevice(Console *pConsole,
+ PVM pVM,
+ const char *pcszDevice,
+ unsigned uInstance,
+ StorageBus_T enmBus,
+ bool fUseHostIOCache,
+ IMediumAttachment *aMediumAtt)
+{
+ LogFlowFunc(("pConsole=%p uInstance=%u pszDevice=%p:{%s} enmBus=%u, aMediumAtt=%p\n",
+ pConsole, uInstance, pcszDevice, pcszDevice, enmBus, aMediumAtt));
+
+ AssertReturn(pConsole, VERR_INVALID_PARAMETER);
+
+ AutoCaller autoCaller(pConsole);
+ AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
+
+ /*
+ * Suspend the VM first.
+ *
+ * The VM must not be running since it might have pending I/O to
+ * the drive which is being changed.
+ */
+ bool fResume;
+ VMSTATE enmVMState = VMR3GetState(pVM);
+ switch (enmVMState)
+ {
+ case VMSTATE_RESETTING:
+ case VMSTATE_RUNNING:
+ {
+ LogFlowFunc(("Suspending the VM...\n"));
+ /* disable the callback to prevent Console-level state change */
+ pConsole->mVMStateChangeCallbackDisabled = true;
+ int rc = VMR3Suspend(pVM);
+ pConsole->mVMStateChangeCallbackDisabled = false;
+ AssertRCReturn(rc, rc);
+ fResume = true;
+ break;
+ }
+
+ case VMSTATE_SUSPENDED:
+ case VMSTATE_CREATED:
+ case VMSTATE_OFF:
+ fResume = false;
+ break;
+
+ case VMSTATE_RUNNING_LS:
+ case VMSTATE_RUNNING_FT:
+ return setErrorInternal(VBOX_E_INVALID_VM_STATE,
+ COM_IIDOF(IConsole),
+ getStaticComponentName(),
+ (enmVMState == VMSTATE_RUNNING_LS) ? Utf8Str(tr("Cannot change drive during live migration")) : Utf8Str(tr("Cannot change drive during fault tolerant syncing")),
+ false /*aWarning*/,
+ true /*aLogIt*/);
+
+ default:
+ AssertMsgFailedReturn(("enmVMState=%d\n", enmVMState), VERR_ACCESS_DENIED);
+ }
+
+ /* Determine the base path for the device instance. */
+ PCFGMNODE pCtlInst;
+ pCtlInst = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%u/", pcszDevice, uInstance);
+ AssertReturn(pCtlInst, VERR_INTERNAL_ERROR);
+
+ int rc = VINF_SUCCESS;
+ int rcRet = VINF_SUCCESS;
+
+ rcRet = pConsole->configMediumAttachment(pCtlInst,
+ pcszDevice,
+ uInstance,
+ enmBus,
+ fUseHostIOCache,
+ false /* fSetupMerge */,
+ false /* fBuiltinIoCache */,
+ 0 /* uMergeSource */,
+ 0 /* uMergeTarget */,
+ aMediumAtt,
+ pConsole->mMachineState,
+ NULL /* phrc */,
+ true /* fAttachDetach */,
+ false /* fForceUnmount */,
+ true /* fHotplug */,
+ pVM,
+ NULL /* paLedDevType */);
+ /** @todo this dumps everything attached to this device instance, which
+ * is more than necessary. Dumping the changed LUN would be enough. */
+ CFGMR3Dump(pCtlInst);
+
+ /*
+ * Resume the VM if necessary.
+ */
+ if (fResume)
+ {
+ LogFlowFunc(("Resuming the VM...\n"));
+ /* disable the callback to prevent Console-level state change */
+ pConsole->mVMStateChangeCallbackDisabled = true;
+ rc = VMR3Resume(pVM);
+ pConsole->mVMStateChangeCallbackDisabled = false;
+ AssertRC(rc);
+ if (RT_FAILURE(rc))
+ {
+ /* too bad, we failed. try to sync the console state with the VMM state */
+ vmstateChangeCallback(pVM, VMSTATE_SUSPENDED, enmVMState, pConsole);
+ }
+ /** @todo: if we failed with drive mount, then the VMR3Resume
+ * error (if any) will be hidden from the caller. For proper reporting
+ * of such multiple errors to the caller we need to enhance the
+ * IVirtualBoxError interface. For now, give the first error the higher
+ * priority.
+ */
+ if (RT_SUCCESS(rcRet))
+ rcRet = rc;
+ }
+
+ LogFlowFunc(("Returning %Rrc\n", rcRet));
+ return rcRet;
+}
+
+/**
+ * Attach a new storage device to the VM.
+ *
+ * @param aMediumAttachment The medium attachment which is added.
+ * @param pVM Safe VM handle.
+ *
+ * @note Locks this object for writing.
+ */
+HRESULT Console::doStorageDeviceDetach(IMediumAttachment *aMediumAttachment, PVM pVM)
+{
+ AutoCaller autoCaller(this);
+ AssertComRCReturnRC(autoCaller.rc());
+
+ /* We will need to release the write lock before calling EMT */
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ HRESULT rc = S_OK;
+ const char *pszDevice = NULL;
+
+ SafeIfaceArray<IStorageController> ctrls;
+ rc = mMachine->COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(ctrls));
+ AssertComRC(rc);
+ IMedium *pMedium;
+ rc = aMediumAttachment->COMGETTER(Medium)(&pMedium);
+ AssertComRC(rc);
+ Bstr mediumLocation;
+ if (pMedium)
+ {
+ rc = pMedium->COMGETTER(Location)(mediumLocation.asOutParam());
+ AssertComRC(rc);
+ }
+
+ Bstr attCtrlName;
+ rc = aMediumAttachment->COMGETTER(Controller)(attCtrlName.asOutParam());
+ AssertComRC(rc);
+ ComPtr<IStorageController> pStorageController;
+ for (size_t i = 0; i < ctrls.size(); ++i)
+ {
+ Bstr ctrlName;
+ rc = ctrls[i]->COMGETTER(Name)(ctrlName.asOutParam());
+ AssertComRC(rc);
+ if (attCtrlName == ctrlName)
+ {
+ pStorageController = ctrls[i];
+ break;
+ }
+ }
+ if (pStorageController.isNull())
+ return setError(E_FAIL,
+ tr("Could not find storage controller '%ls'"), attCtrlName.raw());
+
+ StorageControllerType_T enmCtrlType;
+ rc = pStorageController->COMGETTER(ControllerType)(&enmCtrlType);
+ AssertComRC(rc);
+ pszDevice = convertControllerTypeToDev(enmCtrlType);
+
+ StorageBus_T enmBus;
+ rc = pStorageController->COMGETTER(Bus)(&enmBus);
+ AssertComRC(rc);
+ ULONG uInstance;
+ rc = pStorageController->COMGETTER(Instance)(&uInstance);
+ AssertComRC(rc);
+
+ /*
+ * Call worker in EMT, that's faster and safer than doing everything
+ * using VMR3ReqCall. Note that we separate VMR3ReqCall from VMR3ReqWait
+ * here to make requests from under the lock in order to serialize them.
+ */
+ PVMREQ pReq;
+ int vrc = VMR3ReqCall(pVM,
+ VMCPUID_ANY,
+ &pReq,
+ 0 /* no wait! */,
+ VMREQFLAGS_VBOX_STATUS,
+ (PFNRT)Console::detachStorageDevice,
+ 6,
+ this,
+ pVM,
+ pszDevice,
+ uInstance,
+ enmBus,
+ aMediumAttachment);
+
+ /* leave the lock before waiting for a result (EMT will call us back!) */
+ alock.leave();
+
+ if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
+ {
+ vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
+ AssertRC(vrc);
+ if (RT_SUCCESS(vrc))
+ vrc = pReq->iStatus;
+ }
+ VMR3ReqFree(pReq);
+
+ if (RT_SUCCESS(vrc))
+ {
+ LogFlowThisFunc(("Returns S_OK\n"));
+ return S_OK;
+ }
+
+ if (!pMedium)
+ return setError(E_FAIL,
+ tr("Could not mount the media/drive '%ls' (%Rrc)"),
+ mediumLocation.raw(), vrc);
+
+ return setError(E_FAIL,
+ tr("Could not unmount the currently mounted media/drive (%Rrc)"),
+ vrc);
+}
+
+/**
+ * Performs the storage detach operation in EMT.
+ *
+ * @returns VBox status code.
+ *
+ * @param pThis Pointer to the Console object.
+ * @param pVM The VM handle.
+ * @param pcszDevice The PDM device name.
+ * @param uInstance The PDM device instance.
+ *
+ * @thread EMT
+ */
+DECLCALLBACK(int) Console::detachStorageDevice(Console *pConsole,
+ PVM pVM,
+ const char *pcszDevice,
+ unsigned uInstance,
+ StorageBus_T enmBus,
+ IMediumAttachment *pMediumAtt)
+{
+ LogFlowFunc(("pConsole=%p uInstance=%u pszDevice=%p:{%s} enmBus=%u, pMediumAtt=%p\n",
+ pConsole, uInstance, pcszDevice, pcszDevice, enmBus, pMediumAtt));
+
+ AssertReturn(pConsole, VERR_INVALID_PARAMETER);
+
+ AutoCaller autoCaller(pConsole);
+ AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
+
+ /*
+ * Suspend the VM first.
+ *
+ * The VM must not be running since it might have pending I/O to
+ * the drive which is being changed.
+ */
+ bool fResume;
+ VMSTATE enmVMState = VMR3GetState(pVM);
+ switch (enmVMState)
+ {
+ case VMSTATE_RESETTING:
+ case VMSTATE_RUNNING:
+ {
+ LogFlowFunc(("Suspending the VM...\n"));
+ /* disable the callback to prevent Console-level state change */
+ pConsole->mVMStateChangeCallbackDisabled = true;
+ int rc = VMR3Suspend(pVM);
+ pConsole->mVMStateChangeCallbackDisabled = false;
+ AssertRCReturn(rc, rc);
+ fResume = true;
+ break;
+ }
+
+ case VMSTATE_SUSPENDED:
+ case VMSTATE_CREATED:
+ case VMSTATE_OFF:
+ fResume = false;
+ break;
+
+ case VMSTATE_RUNNING_LS:
+ case VMSTATE_RUNNING_FT:
+ return setErrorInternal(VBOX_E_INVALID_VM_STATE,
+ COM_IIDOF(IConsole),
+ getStaticComponentName(),
+ (enmVMState == VMSTATE_RUNNING_LS) ? Utf8Str(tr("Cannot change drive during live migration")) : Utf8Str(tr("Cannot change drive during fault tolerant syncing")),
+ false /*aWarning*/,
+ true /*aLogIt*/);
+
+ default:
+ AssertMsgFailedReturn(("enmVMState=%d\n", enmVMState), VERR_ACCESS_DENIED);
+ }
+
+ /* Determine the base path for the device instance. */
+ PCFGMNODE pCtlInst;
+ pCtlInst = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%u/", pcszDevice, uInstance);
+ AssertReturn(pCtlInst, VERR_INTERNAL_ERROR);
+
+#define H() AssertMsgReturn(!FAILED(hrc), ("hrc=%Rhrc\n", hrc), VERR_GENERAL_FAILURE)
+
+ HRESULT hrc;
+ int rc = VINF_SUCCESS;
+ int rcRet = VINF_SUCCESS;
+ unsigned uLUN;
+ LONG lDev;
+ LONG lPort;
+ DeviceType_T lType;
+ PCFGMNODE pLunL0 = NULL;
+ PCFGMNODE pCfg = NULL;
+
+ hrc = pMediumAtt->COMGETTER(Device)(&lDev); H();
+ hrc = pMediumAtt->COMGETTER(Port)(&lPort); H();
+ hrc = pMediumAtt->COMGETTER(Type)(&lType); H();
+ hrc = Console::convertBusPortDeviceToLun(enmBus, lPort, lDev, uLUN); H();
+
+#undef H
+
+ /* First check if the LUN really exists. */
+ pLunL0 = CFGMR3GetChildF(pCtlInst, "LUN#%u", uLUN);
+ if (pLunL0)
+ {
+ rc = PDMR3DeviceDetach(pVM, pcszDevice, uInstance, uLUN, 0);
+ if (rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
+ rc = VINF_SUCCESS;
+ AssertRCReturn(rc, rc);
+ CFGMR3RemoveNode(pLunL0);
+
+ Utf8Str devicePath = Utf8StrFmt("%s/%u/LUN#%u", pcszDevice, uInstance, uLUN);
+ pConsole->mapMediumAttachments.erase(devicePath);
+
+ }
+ else
+ AssertFailedReturn(VERR_INTERNAL_ERROR);
+
+ CFGMR3Dump(pCtlInst);
+
+ /*
+ * Resume the VM if necessary.
+ */
+ if (fResume)
+ {
+ LogFlowFunc(("Resuming the VM...\n"));
+ /* disable the callback to prevent Console-level state change */
+ pConsole->mVMStateChangeCallbackDisabled = true;
+ rc = VMR3Resume(pVM);
+ pConsole->mVMStateChangeCallbackDisabled = false;
+ AssertRC(rc);
+ if (RT_FAILURE(rc))
+ {
+ /* too bad, we failed. try to sync the console state with the VMM state */
+ vmstateChangeCallback(pVM, VMSTATE_SUSPENDED, enmVMState, pConsole);
+ }
+ /** @todo: if we failed with drive mount, then the VMR3Resume
+ * error (if any) will be hidden from the caller. For proper reporting
+ * of such multiple errors to the caller we need to enhance the
+ * IVirtualBoxError interface. For now, give the first error the higher
+ * priority.
+ */
+ if (RT_SUCCESS(rcRet))
+ rcRet = rc;
+ }
+
+ LogFlowFunc(("Returning %Rrc\n", rcRet));
+ return rcRet;
+}
+
+/**
* Called by IInternalSessionControl::OnNetworkAdapterChange().
*
* @note Locks this object for writing.
@@ -3564,12 +4198,9 @@ HRESULT Console::onNetworkAdapterChange(INetworkAdapter *aNetworkAdapter, BOOL c
HRESULT rc = S_OK;
/* don't trigger network change if the VM isn't running */
- if (mpVM)
+ SafeVMPtrQuiet ptrVM(this);
+ if (ptrVM.isOk())
{
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
/* Get the properties we need from the adapter */
BOOL fCableConnected, fTraceEnabled;
rc = aNetworkAdapter->COMGETTER(CableConnected)(&fCableConnected);
@@ -3595,7 +4226,7 @@ HRESULT Console::onNetworkAdapterChange(INetworkAdapter *aNetworkAdapter, BOOL c
AssertComRC(rc);
const char *pszAdapterName = networkAdapterTypeToName(adapterType);
PPDMIBASE pBase;
- int vrc = PDMR3QueryDeviceLun(mpVM, pszAdapterName, ulInstance, 0, &pBase);
+ int vrc = PDMR3QueryDeviceLun(ptrVM, pszAdapterName, ulInstance, 0, &pBase);
if (RT_SUCCESS(vrc))
{
Assert(pBase);
@@ -3612,7 +4243,7 @@ HRESULT Console::onNetworkAdapterChange(INetworkAdapter *aNetworkAdapter, BOOL c
}
if (RT_SUCCESS(vrc) && changeAdapter)
{
- VMSTATE enmVMState = VMR3GetState(mpVM);
+ VMSTATE enmVMState = VMR3GetState(ptrVM);
if ( enmVMState == VMSTATE_RUNNING /** @todo LiveMigration: Forbid or deal correctly with the _LS variants */
|| enmVMState == VMSTATE_SUSPENDED)
{
@@ -3622,7 +4253,7 @@ HRESULT Console::onNetworkAdapterChange(INetworkAdapter *aNetworkAdapter, BOOL c
ComAssertRC(vrc);
}
- rc = doNetworkAdapterChange(pszAdapterName, ulInstance, 0, aNetworkAdapter);
+ rc = doNetworkAdapterChange(ptrVM, pszAdapterName, ulInstance, 0, aNetworkAdapter);
if (fTraceEnabled && fCableConnected && pINetCfg)
{
@@ -3633,10 +4264,8 @@ HRESULT Console::onNetworkAdapterChange(INetworkAdapter *aNetworkAdapter, BOOL c
}
}
else if (vrc == VERR_PDM_DEVICE_INSTANCE_NOT_FOUND)
- {
return setError(E_FAIL,
tr("The network adapter #%u is not enabled"), ulInstance);
- }
else
ComAssertRC(vrc);
@@ -3644,6 +4273,7 @@ HRESULT Console::onNetworkAdapterChange(INetworkAdapter *aNetworkAdapter, BOOL c
rc = E_FAIL;
}
}
+ ptrVM.release();
}
/* notify console callbacks on success */
@@ -3660,7 +4290,7 @@ HRESULT Console::onNetworkAdapterChange(INetworkAdapter *aNetworkAdapter, BOOL c
* @note Locks this object for writing.
*/
HRESULT Console::onNATRedirectRuleChange(ULONG ulInstance, BOOL aNatRuleRemove,
- NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort)
+ NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort)
{
LogFlowThisFunc(("\n"));
@@ -3670,71 +4300,75 @@ HRESULT Console::onNATRedirectRuleChange(ULONG ulInstance, BOOL aNatRuleRemove,
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
HRESULT rc = S_OK;
- int vrc = VINF_SUCCESS;
- PPDMINETWORKNATCONFIG pNetNatCfg = NULL;
+
/* don't trigger nat engine change if the VM isn't running */
- if (mpVM)
+ SafeVMPtrQuiet ptrVM(this);
+ if (ptrVM.isOk())
{
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
- ComPtr<INetworkAdapter> pNetworkAdapter;
- rc = machine()->GetNetworkAdapter(ulInstance, pNetworkAdapter.asOutParam());
- if ( FAILED(rc)
- || pNetworkAdapter.isNull())
- goto done;
-
- /*
- * Find the adapter instance, get the config interface and update
- * the link state.
- */
- NetworkAdapterType_T adapterType;
- rc = pNetworkAdapter->COMGETTER(AdapterType)(&adapterType);
- AssertComRC(rc);
- if (FAILED(rc))
+ do
{
- rc = E_FAIL;
- goto done;
- }
+ ComPtr<INetworkAdapter> pNetworkAdapter;
+ rc = machine()->GetNetworkAdapter(ulInstance, pNetworkAdapter.asOutParam());
+ if ( FAILED(rc)
+ || pNetworkAdapter.isNull())
+ break;
- const char *pszAdapterName = networkAdapterTypeToName(adapterType);
- PPDMIBASE pBase;
- vrc = PDMR3QueryLun(mpVM, pszAdapterName, ulInstance, 0, &pBase);
- ComAssertRC(vrc);
- if (RT_FAILURE(vrc))
- {
- rc = E_FAIL;
- goto done;
- }
- NetworkAttachmentType_T attachmentType;
- vrc = pNetworkAdapter->COMGETTER(AttachmentType)(&attachmentType);
+ /*
+ * Find the adapter instance, get the config interface and update
+ * the link state.
+ */
+ NetworkAdapterType_T adapterType;
+ rc = pNetworkAdapter->COMGETTER(AdapterType)(&adapterType);
+ if (FAILED(rc))
+ {
+ AssertComRC(rc);
+ rc = E_FAIL;
+ break;
+ }
- if ( RT_FAILURE(vrc)
- || attachmentType != NetworkAttachmentType_NAT)
- {
- rc = (RT_FAILURE(vrc)) ? E_FAIL: rc;
- goto done;
- }
+ const char *pszAdapterName = networkAdapterTypeToName(adapterType);
+ PPDMIBASE pBase;
+ int vrc = PDMR3QueryLun(ptrVM, pszAdapterName, ulInstance, 0, &pBase);
+ if (RT_FAILURE(vrc))
+ {
+ ComAssertRC(vrc);
+ rc = E_FAIL;
+ break;
+ }
- /* look down for PDMINETWORKNATCONFIG interface */
- while (pBase)
- {
- if ((pNetNatCfg = (PPDMINETWORKNATCONFIG)pBase->pfnQueryInterface(pBase, PDMINETWORKNATCONFIG_IID)))
+ NetworkAttachmentType_T attachmentType;
+ rc = pNetworkAdapter->COMGETTER(AttachmentType)(&attachmentType);
+ if ( FAILED(rc)
+ || attachmentType != NetworkAttachmentType_NAT)
+ {
+ rc = E_FAIL;
break;
- PPDMDRVINS drvins = PDMIBASE_2_PDMDRV(pBase);
- pBase = drvins->pDownBase;
- }
- if (!pNetNatCfg)
- goto done;
- bool fUdp = (aProto == NATProtocol_UDP);
- vrc = pNetNatCfg->pfnRedirectRuleCommand(pNetNatCfg, aNatRuleRemove, fUdp,
- Utf8Str(aHostIp).c_str(), aHostPort, Utf8Str(aGuestIp).c_str(),
- aGuestPort);
- if (RT_FAILURE(vrc))
- rc = E_FAIL;
+ }
+
+ /* look down for PDMINETWORKNATCONFIG interface */
+ PPDMINETWORKNATCONFIG pNetNatCfg = NULL;
+ while (pBase)
+ {
+ pNetNatCfg = (PPDMINETWORKNATCONFIG)pBase->pfnQueryInterface(pBase, PDMINETWORKNATCONFIG_IID);
+ if (pNetNatCfg)
+ break;
+ /** @todo r=bird: This stinks! */
+ PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pBase);
+ pBase = pDrvIns->pDownBase;
+ }
+ if (!pNetNatCfg)
+ break;
+
+ bool fUdp = aProto == NATProtocol_UDP;
+ vrc = pNetNatCfg->pfnRedirectRuleCommand(pNetNatCfg, aNatRuleRemove, fUdp,
+ Utf8Str(aHostIp).c_str(), aHostPort, Utf8Str(aGuestIp).c_str(),
+ aGuestPort);
+ if (RT_FAILURE(vrc))
+ rc = E_FAIL;
+ } while (0); /* break loop */
+ ptrVM.release();
}
-done:
+
LogFlowThisFunc(("Leaving rc=%#x\n", rc));
return rc;
}
@@ -3745,6 +4379,7 @@ done:
*
* @returns COM status code.
*
+ * @parma pVM The VM handle (caller hold this safely).
* @param pszDevice The PDM device name.
* @param uInstance The PDM device instance.
* @param uLun The PDM LUN number of the drive.
@@ -3752,7 +4387,8 @@ done:
*
* @note Locks this object for writing.
*/
-HRESULT Console::doNetworkAdapterChange(const char *pszDevice,
+HRESULT Console::doNetworkAdapterChange(PVM pVM,
+ const char *pszDevice,
unsigned uInstance,
unsigned uLun,
INetworkAdapter *aNetworkAdapter)
@@ -3766,9 +4402,10 @@ HRESULT Console::doNetworkAdapterChange(const char *pszDevice,
/* We will need to release the write lock before calling EMT */
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+ /* Get the VM handle. */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
/*
* Call worker in EMT, that's faster and safer than doing everything
@@ -3776,9 +4413,9 @@ HRESULT Console::doNetworkAdapterChange(const char *pszDevice,
* here to make requests from under the lock in order to serialize them.
*/
PVMREQ pReq;
- int vrc = VMR3ReqCall(mpVM, 0 /*idDstCpu*/, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
- (PFNRT) Console::changeNetworkAttachment, 5,
- this, pszDevice, uInstance, uLun, aNetworkAdapter);
+ int vrc = VMR3ReqCall(pVM, 0 /*idDstCpu*/, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
+ (PFNRT) Console::changeNetworkAttachment, 6,
+ this, ptrVM.raw(), pszDevice, uInstance, uLun, aNetworkAdapter);
/* leave the lock before waiting for a result (EMT will call us back!) */
alock.leave();
@@ -3810,6 +4447,7 @@ HRESULT Console::doNetworkAdapterChange(const char *pszDevice,
* @returns VBox status code.
*
* @param pThis Pointer to the Console object.
+ * @param pVM The VM handle.
* @param pszDevice The PDM device name.
* @param uInstance The PDM device instance.
* @param uLun The PDM LUN number of the drive.
@@ -3819,6 +4457,7 @@ HRESULT Console::doNetworkAdapterChange(const char *pszDevice,
* @note Locks the Console object for writing.
*/
DECLCALLBACK(int) Console::changeNetworkAttachment(Console *pThis,
+ PVM pVM,
const char *pszDevice,
unsigned uInstance,
unsigned uLun,
@@ -3832,20 +4471,14 @@ DECLCALLBACK(int) Console::changeNetworkAttachment(Console *pThis,
AssertMsg( ( !strcmp(pszDevice, "pcnet")
|| !strcmp(pszDevice, "e1000")
|| !strcmp(pszDevice, "virtio-net"))
- && (uLun == 0)
- && (uInstance < SchemaDefs::NetworkAdapterCount),
+ && uLun == 0
+ && uInstance < SchemaDefs::NetworkAdapterCount,
("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance));
Log(("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance));
AutoCaller autoCaller(pThis);
AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
- /* protect mpVM */
- AutoVMCaller autoVMCaller(pThis);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
- PVM pVM = pThis->mpVM;
-
/*
* Suspend the VM first.
*
@@ -3937,13 +4570,11 @@ HRESULT Console::onSerialPortChange(ISerialPort *aSerialPort)
HRESULT rc = S_OK;
/* don't trigger serial port change if the VM isn't running */
- if (mpVM)
+ SafeVMPtrQuiet ptrVM(this);
+ if (ptrVM.isOk())
{
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
/* nothing to do so far */
+ ptrVM.release();
}
/* notify console callbacks on success */
@@ -3971,13 +4602,11 @@ HRESULT Console::onParallelPortChange(IParallelPort *aParallelPort)
HRESULT rc = S_OK;
/* don't trigger parallel port change if the VM isn't running */
- if (mpVM)
+ SafeVMPtrQuiet ptrVM(this);
+ if (ptrVM.isOk())
{
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
/* nothing to do so far */
+ ptrVM.release();
}
/* notify console callbacks on success */
@@ -4005,13 +4634,11 @@ HRESULT Console::onStorageControllerChange()
HRESULT rc = S_OK;
/* don't trigger storage controller change if the VM isn't running */
- if (mpVM)
+ SafeVMPtrQuiet ptrVM(this);
+ if (ptrVM.isOk())
{
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
/* nothing to do so far */
+ ptrVM.release();
}
/* notify console callbacks on success */
@@ -4039,13 +4666,11 @@ HRESULT Console::onMediumChange(IMediumAttachment *aMediumAttachment, BOOL aForc
HRESULT rc = S_OK;
/* don't trigger medium change if the VM isn't running */
- if (mpVM)
+ SafeVMPtrQuiet ptrVM(this);
+ if (ptrVM.isOk())
{
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
- rc = doMediumChange(aMediumAttachment, !!aForce);
+ rc = doMediumChange(aMediumAttachment, !!aForce, ptrVM);
+ ptrVM.release();
}
/* notify console callbacks on success */
@@ -4071,12 +4696,14 @@ HRESULT Console::onCPUChange(ULONG aCPU, BOOL aRemove)
HRESULT rc = S_OK;
/* don't trigger CPU change if the VM isn't running */
- if (mpVM)
+ SafeVMPtrQuiet ptrVM(this);
+ if (ptrVM.isOk())
{
if (aRemove)
- rc = doCPURemove(aCPU);
+ rc = doCPURemove(aCPU, ptrVM);
else
- rc = doCPUAdd(aCPU);
+ rc = doCPUAdd(aCPU, ptrVM);
+ ptrVM.release();
}
/* notify console callbacks on success */
@@ -4104,22 +4731,20 @@ HRESULT Console::onCPUExecutionCapChange(ULONG aExecutionCap)
HRESULT rc = S_OK;
/* don't trigger the CPU priority change if the VM isn't running */
- if (mpVM)
+ SafeVMPtrQuiet ptrVM(this);
+ if (ptrVM.isOk())
{
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
if ( mMachineState == MachineState_Running
|| mMachineState == MachineState_Teleporting
|| mMachineState == MachineState_LiveSnapshotting
)
{
/* No need to call in the EMT thread. */
- rc = VMR3SetCpuExecutionCap(mpVM, aExecutionCap);
+ rc = VMR3SetCpuExecutionCap(ptrVM, aExecutionCap);
}
else
rc = setInvalidMachineStateError();
+ ptrVM.release();
}
/* notify console callbacks on success */
@@ -4220,7 +4845,8 @@ HRESULT Console::onUSBControllerChange()
HRESULT rc = S_OK;
/* don't trigger USB controller change if the VM isn't running */
- if (mpVM)
+ SafeVMPtrQuiet ptrVM(this);
+ if (ptrVM.isOk())
{
/// @todo implement one day.
// Anyway, if we want to query the machine's USB Controller we need
@@ -4229,11 +4855,8 @@ HRESULT Console::onUSBControllerChange()
// bird: While the VM supports hot-plugging, I doubt any guest can
// handle it at this time... :-)
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
/* nothing to do so far */
+ ptrVM.release();
}
/* notify console callbacks on success */
@@ -4293,16 +4916,16 @@ HRESULT Console::onUSBDeviceAttach(IUSBDevice *aDevice, IVirtualBoxErrorInfo *aE
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* protect mpVM (we don't need error info, since it's a callback) */
- AutoVMCallerQuiet autoVMCaller(this);
- if (FAILED(autoVMCaller.rc()))
+ /* Get the VM pointer (we don't need error info, since it's a callback). */
+ SafeVMPtrQuiet ptrVM(this);
+ if (!ptrVM.isOk())
{
/* The VM may be no more operational when this message arrives
* (e.g. it may be Saving or Stopping or just PoweredOff) --
* autoVMCaller.rc() will return a failure in this case. */
LogFlowThisFunc(("Attach request ignored (mMachineState=%d).\n",
mMachineState));
- return autoVMCaller.rc();
+ return ptrVM.rc();
}
if (aError != NULL)
@@ -4313,7 +4936,7 @@ HRESULT Console::onUSBDeviceAttach(IUSBDevice *aDevice, IVirtualBoxErrorInfo *aE
}
/* Don't proceed unless there's at least one USB hub. */
- if (!PDMR3USBHasHub(mpVM))
+ if (!PDMR3USBHasHub(ptrVM))
{
LogFlowThisFunc(("Attach request ignored (no USB controller).\n"));
return E_FAIL;
@@ -4442,12 +5065,9 @@ HRESULT Console::onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup)
HRESULT rc = S_OK;
/* don't trigger the CPU priority change if the VM isn't running */
- if (mpVM)
+ SafeVMPtrQuiet ptrVM(this);
+ if (ptrVM.isOk())
{
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
if ( mMachineState == MachineState_Running
|| mMachineState == MachineState_Teleporting
|| mMachineState == MachineState_LiveSnapshotting
@@ -4463,13 +5083,14 @@ HRESULT Console::onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup)
if (SUCCEEDED(rc))
{
int vrc;
- vrc = PDMR3AsyncCompletionBwMgrSetMaxForFile(mpVM, Utf8Str(strName).c_str(),
+ vrc = PDMR3AsyncCompletionBwMgrSetMaxForFile(ptrVM, Utf8Str(strName).c_str(),
cMax * _1M);
AssertRC(vrc);
}
}
else
rc = setInvalidMachineStateError();
+ ptrVM.release();
}
/* notify console callbacks on success */
@@ -4481,6 +5102,41 @@ HRESULT Console::onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup)
}
/**
+ * Called by IInternalSessionControl::OnStorageDeviceChange().
+ *
+ * @note Locks this object for writing.
+ */
+HRESULT Console::onStorageDeviceChange(IMediumAttachment *aMediumAttachment, BOOL aRemove)
+{
+ LogFlowThisFunc(("\n"));
+
+ AutoCaller autoCaller(this);
+ AssertComRCReturnRC(autoCaller.rc());
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ HRESULT rc = S_OK;
+
+ /* don't trigger medium change if the VM isn't running */
+ SafeVMPtrQuiet ptrVM(this);
+ if (ptrVM.isOk())
+ {
+ if (aRemove)
+ rc = doStorageDeviceDetach(aMediumAttachment, ptrVM);
+ else
+ rc = doStorageDeviceAttach(aMediumAttachment, ptrVM);
+ ptrVM.release();
+ }
+
+ /* notify console callbacks on success */
+ if (SUCCEEDED(rc))
+ fireStorageDeviceChangedEvent(mEventSource, aMediumAttachment, aRemove);
+
+ LogFlowThisFunc(("Leaving rc=%#x\n", rc));
+ return rc;
+}
+
+/**
* @note Temporarily locks this object for writing.
*/
HRESULT Console::getGuestProperty(IN_BSTR aName, BSTR *aValue,
@@ -4688,7 +5344,7 @@ static int onlineMergeMediumProgress(void *pvUser, unsigned uPercentage)
}
/**
- * @note Temporarily locks this object for writing.
+ * @note Temporarily locks this object for writing. bird: And/or reading?
*/
HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
ULONG aSourceIdx, ULONG aTargetIdx,
@@ -4703,7 +5359,11 @@ HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
HRESULT rc = S_OK;
int vrc = VINF_SUCCESS;
- PVM pVM = mpVM;
+
+ /* Get the VM - must be done before the read-locking. */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
/* We will need to release the lock before doing the actual merge */
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -4719,6 +5379,8 @@ HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
return setInvalidMachineStateError();
}
+ /** @todo AssertComRC -> AssertComRCReturn! Could potentially end up
+ * using uninitialized variables here. */
BOOL fBuiltinIoCache;
rc = mMachine->COMGETTER(IoCacheEnabled)(&fBuiltinIoCache);
AssertComRC(rc);
@@ -4783,23 +5445,23 @@ HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
alock.release();
/* Pause the VM, as it might have pending IO on this drive */
- VMSTATE enmVMState = VMR3GetState(pVM);
+ VMSTATE enmVMState = VMR3GetState(ptrVM);
if (mMachineState == MachineState_DeletingSnapshotOnline)
{
LogFlowFunc(("Suspending the VM...\n"));
/* disable the callback to prevent Console-level state change */
mVMStateChangeCallbackDisabled = true;
- int vrc2 = VMR3Suspend(pVM);
+ int vrc2 = VMR3Suspend(ptrVM);
mVMStateChangeCallbackDisabled = false;
AssertRCReturn(vrc2, E_FAIL);
}
- vrc = VMR3ReqCallWait(pVM,
+ vrc = VMR3ReqCallWait(ptrVM,
VMCPUID_ANY,
(PFNRT)reconfigureMediumAttachment,
13,
this,
- pVM,
+ ptrVM.raw(),
pcszDevice,
uInstance,
enmBus,
@@ -4818,13 +5480,13 @@ HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
LogFlowFunc(("Resuming the VM...\n"));
/* disable the callback to prevent Console-level state change */
mVMStateChangeCallbackDisabled = true;
- int vrc2 = VMR3Resume(pVM);
+ int vrc2 = VMR3Resume(ptrVM);
mVMStateChangeCallbackDisabled = false;
if (RT_FAILURE(vrc2))
{
/* too bad, we failed. try to sync the console state with the VMM state */
AssertLogRelRC(vrc2);
- vmstateChangeCallback(pVM, VMSTATE_SUSPENDED, enmVMState, this);
+ vmstateChangeCallback(ptrVM, VMSTATE_SUSPENDED, enmVMState, this);
}
}
@@ -4835,7 +5497,7 @@ HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
PPDMIBASE pIBase = NULL;
PPDMIMEDIA pIMedium = NULL;
- vrc = PDMR3QueryDriverOnLun(pVM, pcszDevice, uInstance, uLUN, "VD", &pIBase);
+ vrc = PDMR3QueryDriverOnLun(ptrVM, pcszDevice, uInstance, uLUN, "VD", &pIBase);
if (RT_SUCCESS(vrc))
{
if (pIBase)
@@ -4854,13 +5516,13 @@ HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
return setError(E_FAIL, tr("Failed to perform an online medium merge (%Rrc)"), vrc);
/* Pause the VM, as it might have pending IO on this drive */
- enmVMState = VMR3GetState(pVM);
+ enmVMState = VMR3GetState(ptrVM);
if (mMachineState == MachineState_DeletingSnapshotOnline)
{
LogFlowFunc(("Suspending the VM...\n"));
/* disable the callback to prevent Console-level state change */
mVMStateChangeCallbackDisabled = true;
- int vrc2 = VMR3Suspend(pVM);
+ int vrc2 = VMR3Suspend(ptrVM);
mVMStateChangeCallbackDisabled = false;
AssertRCReturn(vrc2, E_FAIL);
}
@@ -4870,12 +5532,12 @@ HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
aMergeForward, aParentForTarget,
ComSafeArrayInArg(aChildrenToReparent));
- vrc = VMR3ReqCallWait(pVM,
+ vrc = VMR3ReqCallWait(ptrVM,
VMCPUID_ANY,
(PFNRT)reconfigureMediumAttachment,
13,
this,
- pVM,
+ ptrVM.raw(),
pcszDevice,
uInstance,
enmBus,
@@ -4894,13 +5556,13 @@ HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
LogFlowFunc(("Resuming the VM...\n"));
/* disable the callback to prevent Console-level state change */
mVMStateChangeCallbackDisabled = true;
- int vrc2 = VMR3Resume(pVM);
+ int vrc2 = VMR3Resume(ptrVM);
mVMStateChangeCallbackDisabled = false;
AssertRC(vrc2);
if (RT_FAILURE(vrc2))
{
/* too bad, we failed. try to sync the console state with the VMM state */
- vmstateChangeCallback(pVM, VMSTATE_SUSPENDED, enmVMState, this);
+ vmstateChangeCallback(ptrVM, VMSTATE_SUSPENDED, enmVMState, this);
}
}
@@ -5202,7 +5864,7 @@ HRESULT Console::addVMCaller(bool aQuiet /* = false */,
tr("The virtual machine is being powered down"));
}
- if (mpVM == NULL)
+ if (mpUVM == NULL)
{
Assert(aAllowNullVM == true);
@@ -5229,7 +5891,7 @@ void Console::releaseVMCaller()
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- AssertReturnVoid(mpVM != NULL);
+ AssertReturnVoid(mpUVM != NULL);
Assert(mVMCallers > 0);
--mVMCallers;
@@ -5241,6 +5903,62 @@ void Console::releaseVMCaller()
}
}
+
+HRESULT Console::safeVMPtrRetainer(PVM *a_ppVM, PUVM *a_ppUVM, bool a_Quiet)
+{
+ *a_ppVM = NULL;
+ *a_ppUVM = NULL;
+
+ AutoCaller autoCaller(this);
+ AssertComRCReturnRC(autoCaller.rc());
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ /*
+ * Repeat the checks done by addVMCaller.
+ */
+ if (mVMDestroying) /* powerDown() is waiting for all callers to finish */
+ return a_Quiet
+ ? E_ACCESSDENIED
+ : setError(E_ACCESSDENIED, tr("The virtual machine is being powered down"));
+ PUVM pUVM = mpUVM;
+ if (!pUVM)
+ return a_Quiet
+ ? E_ACCESSDENIED
+ : setError(E_ACCESSDENIED, tr("The virtual machine is was powered off"));
+
+ /*
+ * Retain a reference to the user mode VM handle and get the global handle.
+ */
+ uint32_t cRefs = VMR3RetainUVM(pUVM);
+ if (cRefs == UINT32_MAX)
+ return a_Quiet
+ ? E_ACCESSDENIED
+ : setError(E_ACCESSDENIED, tr("The virtual machine is was powered off"));
+
+ PVM pVM = VMR3GetVM(pUVM);
+ if (!pVM)
+ {
+ VMR3ReleaseUVM(pUVM);
+ return a_Quiet
+ ? E_ACCESSDENIED
+ : setError(E_ACCESSDENIED, tr("The virtual machine is was powered off"));
+ }
+
+ /* done */
+ *a_ppVM = pVM;
+ *a_ppUVM = pUVM;
+ return S_OK;
+}
+
+void Console::safeVMPtrReleaser(PVM *a_ppVM, PUVM *a_ppUVM)
+{
+ if (*a_ppVM && *a_ppUVM)
+ VMR3ReleaseUVM(*a_ppUVM);
+ *a_ppVM = NULL;
+ *a_ppUVM = NULL;
+}
+
+
/**
* Initialize the release logging facility. In case something
* goes wrong, there will be no release logging. Maybe in the future
@@ -5302,24 +6020,26 @@ HRESULT Console::consoleInitReleaseLog(const ComPtr<IMachine> aMachine)
}
}
- PRTLOGGER loggerRelease;
- static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
- RTUINT fFlags = RTLOGFLAGS_PREFIX_TIME_PROG;
+ static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
+ char szError[RTPATH_MAX + 128] = "";
+ PRTLOGGER pReleaseLogger;
+ uint32_t fFlags = RTLOGFLAGS_PREFIX_TIME_PROG | RTLOGFLAGS_RESTRICT_GROUPS;
#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
fFlags |= RTLOGFLAGS_USECRLF;
#endif
- char szError[RTPATH_MAX + 128] = "";
- int vrc = RTLogCreateEx(&loggerRelease, fFlags, "all",
+ int vrc = RTLogCreateEx(&pReleaseLogger, fFlags, "all all.restrict default.unrestricted",
"VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_FILE,
NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */,
szError, sizeof(szError), logFile.c_str());
if (RT_SUCCESS(vrc))
{
+ RTLogSetGroupLimit(pReleaseLogger, 32768);
+
/* some introductory information */
RTTIMESPEC timeSpec;
char szTmp[256];
RTTimeSpecToString(RTTimeNow(&timeSpec), szTmp, sizeof(szTmp));
- RTLogRelLogger(loggerRelease, 0, ~0U,
+ RTLogRelLogger(pReleaseLogger, 0, ~0U,
"VirtualBox %s r%u %s (%s %s) release log\n"
#ifdef VBOX_BLEEDING_EDGE
"EXPERIMENTAL build " VBOX_BLEEDING_EDGE "\n"
@@ -5330,22 +6050,22 @@ HRESULT Console::consoleInitReleaseLog(const ComPtr<IMachine> aMachine)
vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp));
if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
- RTLogRelLogger(loggerRelease, 0, ~0U, "OS Product: %s\n", szTmp);
+ RTLogRelLogger(pReleaseLogger, 0, ~0U, "OS Product: %s\n", szTmp);
vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp));
if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
- RTLogRelLogger(loggerRelease, 0, ~0U, "OS Release: %s\n", szTmp);
+ RTLogRelLogger(pReleaseLogger, 0, ~0U, "OS Release: %s\n", szTmp);
vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp));
if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
- RTLogRelLogger(loggerRelease, 0, ~0U, "OS Version: %s\n", szTmp);
+ RTLogRelLogger(pReleaseLogger, 0, ~0U, "OS Version: %s\n", szTmp);
vrc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szTmp, sizeof(szTmp));
if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
- RTLogRelLogger(loggerRelease, 0, ~0U, "OS Service Pack: %s\n", szTmp);
+ RTLogRelLogger(pReleaseLogger, 0, ~0U, "OS Service Pack: %s\n", szTmp);
vrc = RTSystemQueryDmiString(RTSYSDMISTR_PRODUCT_NAME, szTmp, sizeof(szTmp));
if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
- RTLogRelLogger(loggerRelease, 0, ~0U, "DMI Product Name: %s\n", szTmp);
+ RTLogRelLogger(pReleaseLogger, 0, ~0U, "DMI Product Name: %s\n", szTmp);
vrc = RTSystemQueryDmiString(RTSYSDMISTR_PRODUCT_VERSION, szTmp, sizeof(szTmp));
if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
- RTLogRelLogger(loggerRelease, 0, ~0U, "DMI Product Version: %s\n", szTmp);
+ RTLogRelLogger(pReleaseLogger, 0, ~0U, "DMI Product Version: %s\n", szTmp);
ComPtr<IHost> pHost;
pVirtualBox->COMGETTER(Host)(pHost.asOutParam());
@@ -5353,13 +6073,13 @@ HRESULT Console::consoleInitReleaseLog(const ComPtr<IMachine> aMachine)
ULONG cMbHostRamAvail = 0;
pHost->COMGETTER(MemorySize)(&cMbHostRam);
pHost->COMGETTER(MemoryAvailable)(&cMbHostRamAvail);
- RTLogRelLogger(loggerRelease, 0, ~0U, "Host RAM: %uMB RAM, available: %uMB\n",
+ RTLogRelLogger(pReleaseLogger, 0, ~0U, "Host RAM: %uMB RAM, available: %uMB\n",
cMbHostRam, cMbHostRamAvail);
/* the package type is interesting for Linux distributions */
char szExecName[RTPATH_MAX];
char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName));
- RTLogRelLogger(loggerRelease, 0, ~0U,
+ RTLogRelLogger(pReleaseLogger, 0, ~0U,
"Executable: %s\n"
"Process ID: %u\n"
"Package type: %s"
@@ -5372,11 +6092,11 @@ HRESULT Console::consoleInitReleaseLog(const ComPtr<IMachine> aMachine)
VBOX_PACKAGE_STRING);
/* register this logger as the release logger */
- RTLogRelSetDefaultInstance(loggerRelease);
+ RTLogRelSetDefaultInstance(pReleaseLogger);
hrc = S_OK;
/* Explicitly flush the log in case of VBOX_RELEASE_LOG=buffered. */
- RTLogFlush(loggerRelease);
+ RTLogFlush(pReleaseLogger);
}
else
hrc = setError(E_FAIL,
@@ -5562,8 +6282,6 @@ HRESULT Console::powerUp(IProgress **aProgress, bool aPaused)
/* Check all types of shared folders and compose a single list */
SharedFolderDataMap sharedFolders;
{
- // @todo umoeller
-
/* first, insert global folders */
for (SharedFolderDataMap::const_iterator it = m_mapGlobalSharedFolders.begin();
it != m_mapGlobalSharedFolders.end();
@@ -5709,6 +6427,7 @@ HRESULT Console::powerUp(IProgress **aProgress, bool aPaused)
rc = consoleInitReleaseLog(mMachine);
if (FAILED(rc))
throw rc;
+ mptrExtPackManager->dumpAllToReleaseLog();
#ifdef RT_OS_SOLARIS
/* setup host core dumper for the VM */
@@ -5878,7 +6597,8 @@ HRESULT Console::powerDown(IProgress *aProgress /*= NULL*/)
/* sanity */
Assert(mVMDestroying == false);
- Assert(mpVM != NULL);
+ PUVM pUVM = mpUVM; Assert(pUVM != NULL);
+ uint32_t cRefs = VMR3RetainUVM(pUVM); Assert(cRefs != UINT32_MAX);
AssertMsg( mMachineState == MachineState_Running
|| mMachineState == MachineState_Paused
@@ -5994,9 +6714,9 @@ HRESULT Console::powerDown(IProgress *aProgress /*= NULL*/)
{
LogFlowThisFunc(("Powering off the VM...\n"));
alock.leave();
- vrc = VMR3PowerOff(mpVM);
+ vrc = VMR3PowerOff(VMR3GetVM(pUVM));
#ifdef VBOX_WITH_EXTPACK
- mptrExtPackManager->callAllVmPowerOffHooks(this, mpVM);
+ mptrExtPackManager->callAllVmPowerOffHooks(this, VMR3GetVM(pUVM));
#endif
alock.enter();
}
@@ -6036,7 +6756,7 @@ HRESULT Console::powerDown(IProgress *aProgress /*= NULL*/)
bool fHasUSBController = false;
{
PPDMIBASE pBase;
- vrc = PDMR3QueryLun(mpVM, "usb-ohci", 0, 0, &pBase);
+ vrc = PDMR3QueryLun(VMR3GetVM(pUVM), "usb-ohci", 0, 0, &pBase);
if (RT_SUCCESS(vrc))
{
fHasUSBController = true;
@@ -6051,16 +6771,16 @@ HRESULT Console::powerDown(IProgress *aProgress /*= NULL*/)
* instantiating SafeVMPtr to access mpVM). It's safe here because
* mVMDestroying is set which should prevent any activity. */
- /* Set mpVM to NULL early just in case if some old code is not using
- * addVMCaller()/releaseVMCaller(). */
- PVM pVM = mpVM;
- mpVM = NULL;
+ /* Set mpUVM to NULL early just in case if some old code is not using
+ * addVMCaller()/releaseVMCaller(). (We have our own ref on pUVM.) */
+ VMR3ReleaseUVM(mpUVM);
+ mpUVM = NULL;
LogFlowThisFunc(("Destroying the VM...\n"));
alock.leave();
- vrc = VMR3Destroy(pVM);
+ vrc = VMR3Destroy(VMR3GetVM(pUVM));
/* take the lock again */
alock.enter();
@@ -6083,8 +6803,9 @@ HRESULT Console::powerDown(IProgress *aProgress /*= NULL*/)
}
else
{
- /* bad bad bad, but what to do? */
- mpVM = pVM;
+ /* bad bad bad, but what to do? (Give Console our UVM ref.) */
+ mpUVM = pUVM;
+ pUVM = NULL;
rc = setError(VBOX_E_VM_ERROR,
tr("Could not destroy the machine. (Error: %Rrc)"),
vrc);
@@ -6105,11 +6826,17 @@ HRESULT Console::powerDown(IProgress *aProgress /*= NULL*/)
vrc);
}
- /* Finished with destruction. Note that if something impossible happened and
- * we've failed to destroy the VM, mVMDestroying will remain true and
- * mMachineState will be something like Stopping, so most Console methods
- * will return an error to the caller. */
- if (mpVM == NULL)
+ /*
+ * Finished with the destruction.
+ *
+ * Note that if something impossible happened and we've failed to destroy
+ * the VM, mVMDestroying will remain true and mMachineState will be
+ * something like Stopping, so most Console methods will return an error
+ * to the caller.
+ */
+ if (mpUVM != NULL)
+ VMR3ReleaseUVM(pUVM);
+ else
mVMDestroying = false;
if (SUCCEEDED(rc))
@@ -6223,16 +6950,15 @@ HRESULT Console::fetchSharedFolders(BOOL aGlobal)
LogFlowThisFunc(("Entering\n"));
- /* protect mpVM (if not NULL) */
+ /* Check if we're online and keep it that way. */
+ SafeVMPtrQuiet ptrVM(this);
AutoVMCallerQuietWeak autoVMCaller(this);
+ bool const online = ptrVM.isOk()
+ && m_pVMMDev
+ && m_pVMMDev->isShFlActive();
HRESULT rc = S_OK;
- bool online = mpVM
- && autoVMCaller.isOk()
- && m_pVMMDev
- && m_pVMMDev->isShFlActive();
-
try
{
if (aGlobal)
@@ -6278,7 +7004,6 @@ HRESULT Console::fetchSharedFolders(BOOL aGlobal)
SharedFolderData(strHostPath, writable, autoMount)));
/* send changes to HGCM if the VM is running */
- /// @todo umoeller report errors as runtime warnings through VMSetError
if (online)
{
SharedFolderDataMap::iterator it = oldFolders.find(strName);
@@ -6345,7 +7070,7 @@ HRESULT Console::fetchSharedFolders(BOOL aGlobal)
catch (HRESULT rc2)
{
if (online)
- setVMRuntimeErrorCallbackF(mpVM, this, 0, "BrokenSharedFolder",
+ setVMRuntimeErrorCallbackF(ptrVM, this, 0, "BrokenSharedFolder",
N_("Broken shared folder!"));
}
@@ -6398,7 +7123,7 @@ HRESULT Console::createSharedFolder(const Utf8Str &strName, const SharedFolderDa
ComAssertRet(aData.m_strHostPath.isNotEmpty(), E_FAIL);
/* sanity checks */
- AssertReturn(mpVM, E_FAIL);
+ AssertReturn(mpUVM, E_FAIL);
AssertReturn(m_pVMMDev && m_pVMMDev->isShFlActive(), E_FAIL);
VBOXHGCMSVCPARM parms[SHFL_CPARMS_ADD_MAPPING2];
@@ -6503,7 +7228,7 @@ HRESULT Console::removeSharedFolder(const Utf8Str &strName)
ComAssertRet(strName.isNotEmpty(), E_FAIL);
/* sanity checks */
- AssertReturn(mpVM, E_FAIL);
+ AssertReturn(mpUVM, E_FAIL);
AssertReturn(m_pVMMDev && m_pVMMDev->isShFlActive(), E_FAIL);
VBOXHGCMSVCPARM parms;
@@ -6715,10 +7440,10 @@ DECLCALLBACK(void) Console::vmstateChangeCallback(PVM aVM,
case VMSTATE_RESETTING:
{
- #ifdef VBOX_WITH_GUEST_PROPS
+#ifdef VBOX_WITH_GUEST_PROPS
/* Do not take any read/write locks here! */
that->guestPropertiesHandleVMReset();
- #endif
+#endif
break;
}
@@ -6907,9 +7632,10 @@ HRESULT Console::attachUSBDevice(IUSBDevice *aHostDevice, ULONG aMaskedIfs)
hrc = aHostDevice->COMGETTER(Remote)(&fRemote);
ComAssertComRCRetRC(hrc);
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+ /* Get the VM handle. */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
LogFlowThisFunc(("Proxying USB device '%s' {%RTuuid}...\n",
Address.c_str(), uuid.raw()));
@@ -6918,8 +7644,9 @@ HRESULT Console::attachUSBDevice(IUSBDevice *aHostDevice, ULONG aMaskedIfs)
alock.leave();
/** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */
- int vrc = VMR3ReqCallWait(mpVM, VMCPUID_ANY,
- (PFNRT)usbAttachCallback, 6, this, aHostDevice, uuid.raw(), fRemote, Address.c_str(), aMaskedIfs);
+ int vrc = VMR3ReqCallWait(ptrVM, VMCPUID_ANY,
+ (PFNRT)usbAttachCallback, 7,
+ this, ptrVM.raw(), aHostDevice, uuid.raw(), fRemote, Address.c_str(), aMaskedIfs);
/* restore the lock */
alock.enter();
@@ -6929,7 +7656,7 @@ HRESULT Console::attachUSBDevice(IUSBDevice *aHostDevice, ULONG aMaskedIfs)
if (RT_FAILURE(vrc))
{
LogWarningThisFunc(("Failed to create proxy device for '%s' {%RTuuid} (%Rrc)\n",
- Address.c_str(), uuid.raw(), vrc));
+ Address.c_str(), uuid.raw(), vrc));
switch (vrc)
{
@@ -6963,7 +7690,7 @@ HRESULT Console::attachUSBDevice(IUSBDevice *aHostDevice, ULONG aMaskedIfs)
*/
//static
DECLCALLBACK(int)
-Console::usbAttachCallback(Console *that, IUSBDevice *aHostDevice, PCRTUUID aUuid, bool aRemote, const char *aAddress, ULONG aMaskedIfs)
+Console::usbAttachCallback(Console *that, PVM pVM, IUSBDevice *aHostDevice, PCRTUUID aUuid, bool aRemote, const char *aAddress, ULONG aMaskedIfs)
{
LogFlowFuncEnter();
LogFlowFunc(("that={%p}\n", that));
@@ -6986,7 +7713,7 @@ Console::usbAttachCallback(Console *that, IUSBDevice *aHostDevice, PCRTUUID aUui
AssertComRCReturn(hrc, VERR_GENERAL_FAILURE);
Assert(portVersion == 1 || portVersion == 2);
- int vrc = PDMR3USBCreateProxyDevice(that->mpVM, aUuid, aRemote, aAddress, pvRemoteBackend,
+ int vrc = PDMR3USBCreateProxyDevice(pVM, aUuid, aRemote, aAddress, pvRemoteBackend,
portVersion == 1 ? VUSB_STDVER_11 : VUSB_STDVER_20, aMaskedIfs);
if (RT_SUCCESS(vrc))
{
@@ -7026,22 +7753,24 @@ HRESULT Console::detachUSBDevice(USBDeviceList::iterator &aIt)
/* still want a lock object because we need to leave it */
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* protect mpVM */
- AutoVMCaller autoVMCaller(this);
- if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+ /* Get the VM handle. */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
/* if the device is attached, then there must at least one USB hub. */
- AssertReturn(PDMR3USBHasHub(mpVM), E_FAIL);
+ AssertReturn(PDMR3USBHasHub(ptrVM), E_FAIL);
LogFlowThisFunc(("Detaching USB proxy device {%RTuuid}...\n",
- (*aIt)->id().raw()));
+ (*aIt)->id().raw()));
/* leave the lock before a VMR3* call (EMT will call us back)! */
alock.leave();
/** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */
- int vrc = VMR3ReqCallWait(mpVM, VMCPUID_ANY,
- (PFNRT) usbDetachCallback, 4, this, &aIt, (*aIt)->id().raw());
+ int vrc = VMR3ReqCallWait(ptrVM, VMCPUID_ANY,
+ (PFNRT)usbDetachCallback, 5,
+ this, ptrVM.raw(), &aIt, (*aIt)->id().raw());
ComAssertRCRet(vrc, E_FAIL);
return S_OK;
@@ -7058,7 +7787,7 @@ HRESULT Console::detachUSBDevice(USBDeviceList::iterator &aIt)
*/
//static
DECLCALLBACK(int)
-Console::usbDetachCallback(Console *that, USBDeviceList::iterator *aIt, PCRTUUID aUuid)
+Console::usbDetachCallback(Console *that, PVM pVM, USBDeviceList::iterator *aIt, PCRTUUID aUuid)
{
LogFlowFuncEnter();
LogFlowFunc(("that={%p}\n", that));
@@ -7082,7 +7811,7 @@ Console::usbDetachCallback(Console *that, USBDeviceList::iterator *aIt, PCRTUUID
that->consoleVRDPServer()->USBBackendReleasePointer(&guid);
}
- int vrc = PDMR3USBDetachDevice(that->mpVM, aUuid);
+ int vrc = PDMR3USBDetachDevice(pVM, aUuid);
if (RT_SUCCESS(vrc))
{
@@ -7148,7 +7877,7 @@ HRESULT Console::attachToTapInterface(INetworkAdapter *networkAdapter)
memset(&IfReq, 0, sizeof(IfReq));
/* The name of the TAP interface we are using */
Bstr tapDeviceName;
- rc = networkAdapter->COMGETTER(HostInterface)(tapDeviceName.asOutParam());
+ rc = networkAdapter->COMGETTER(BridgedInterface)(tapDeviceName.asOutParam());
if (FAILED(rc))
tapDeviceName.setNull(); /* Is this necessary? */
if (tapDeviceName.isEmpty())
@@ -7226,7 +7955,7 @@ HRESULT Console::attachToTapInterface(INetworkAdapter *networkAdapter)
*/
/* The name of the TAP interface we are using */
Bstr tapDeviceName;
- rc = networkAdapter->COMGETTER(HostInterface)(tapDeviceName.asOutParam());
+ rc = networkAdapter->COMGETTER(BridgedInterface)(tapDeviceName.asOutParam());
if (FAILED(rc))
tapDeviceName.setNull(); /* Is this necessary? */
if (tapDeviceName.isEmpty())
@@ -7313,7 +8042,7 @@ HRESULT Console::detachFromTapInterface(INetworkAdapter *networkAdapter)
*/
Bstr tapDeviceName, tapTerminateApplication;
bool isStatic = true;
- rc = networkAdapter->COMGETTER(HostInterface)(tapDeviceName.asOutParam());
+ rc = networkAdapter->COMGETTER(BridgedInterface)(tapDeviceName.asOutParam());
if (FAILED(rc) || tapDeviceName.isEmpty())
{
/* If the name is empty, this is a dynamic TAP device, so close it now,
@@ -7749,7 +8478,7 @@ DECLCALLBACK(int) Console::powerUpThread(RTTHREAD Thread, void *pvUser)
AutoWriteLock alock(pConsole COMMA_LOCKVAL_SRC_POS);
/* sanity */
- Assert(pConsole->mpVM == NULL);
+ Assert(pConsole->mpUVM == NULL);
try
{
@@ -7972,7 +8701,7 @@ DECLCALLBACK(int) Console::powerUpThread(RTTHREAD Thread, void *pvUser)
{
/* -> ConsoleImplTeleporter.cpp */
bool fPowerOffOnFailure;
- rc = pConsole->teleporterTrg(pVM, pMachine, &task->mErrorMsg, task->mStartPaused,
+ rc = pConsole->teleporterTrg(VMR3GetUVM(pVM), pMachine, &task->mErrorMsg, task->mStartPaused,
task->mProgress, &fPowerOffOnFailure);
if (FAILED(rc) && fPowerOffOnFailure)
{
@@ -8076,7 +8805,8 @@ DECLCALLBACK(int) Console::powerUpThread(RTTHREAD Thread, void *pvUser)
/*
* If VMR3Create() failed it has released the VM memory.
*/
- pConsole->mpVM = NULL;
+ VMR3ReleaseUVM(pConsole->mpUVM);
+ pConsole->mpUVM = NULL;
}
if (SUCCEEDED(rc) && RT_FAILURE(vrc))
@@ -8123,7 +8853,7 @@ DECLCALLBACK(int) Console::powerUpThread(RTTHREAD Thread, void *pvUser)
/* preserve existing error info */
ErrorInfoKeeper eik;
- Assert(pConsole->mpVM == NULL);
+ Assert(pConsole->mpUVM == NULL);
vmstateChangeCallback(NULL, VMSTATE_TERMINATED, VMSTATE_CREATING,
pConsole);
}
@@ -8229,6 +8959,7 @@ DECLCALLBACK(int) Console::reconfigureMediumAttachment(Console *pConsole,
phrc,
true /* fAttachDetach */,
false /* fForceUnmount */,
+ false /* fHotplug */,
pVM,
NULL /* paLedDevType */);
/** @todo this dumps everything attached to this device instance, which
@@ -8248,8 +8979,8 @@ DECLCALLBACK(int) Console::reconfigureMediumAttachment(Console *pConsole,
*/
static void takesnapshotProgressCancelCallback(void *pvUser)
{
- PVM pVM = (PVM)pvUser;
- SSMR3Cancel(pVM);
+ PUVM pUVM = (PUVM)pvUser;
+ SSMR3Cancel(VMR3GetVM(pUVM));
}
/**
@@ -8324,13 +9055,17 @@ DECLCALLBACK(int) Console::fntTakeSnapshotWorker(RTTHREAD Thread, void *pvUser)
{
Utf8Str strSavedStateFile(pTask->bstrSavedStateFile);
+ SafeVMPtr ptrVM(that);
+ if (!ptrVM.isOk())
+ throw ptrVM.rc();
+
pTask->mProgress->SetNextOperation(Bstr(tr("Saving the machine state")).raw(),
pTask->ulMemSize); // operation weight, same as computed when setting up progress object
- pTask->mProgress->setCancelCallback(takesnapshotProgressCancelCallback, that->mpVM);
+ pTask->mProgress->setCancelCallback(takesnapshotProgressCancelCallback, ptrVM.rawUVM());
alock.leave();
LogFlowFunc(("VMR3Save...\n"));
- int vrc = VMR3Save(that->mpVM,
+ int vrc = VMR3Save(ptrVM,
strSavedStateFile.c_str(),
true /*fContinueAfterwards*/,
Console::stateProgressCallback,
@@ -8407,12 +9142,12 @@ DECLCALLBACK(int) Console::fntTakeSnapshotWorker(RTTHREAD Thread, void *pvUser)
* don't leave the lock since reconfigureMediumAttachment
* isn't going to need the Console lock.
*/
- vrc = VMR3ReqCallWait(that->mpVM,
+ vrc = VMR3ReqCallWait(ptrVM,
VMCPUID_ANY,
(PFNRT)reconfigureMediumAttachment,
13,
that,
- that->mpVM,
+ ptrVM.raw(),
pcszDevice,
lInstance,
enmBus,
@@ -8478,8 +9213,9 @@ DECLCALLBACK(int) Console::fntTakeSnapshotWorker(RTTHREAD Thread, void *pvUser)
if (pTask->lastMachineState == MachineState_Running)
{
LogFlowFunc(("VMR3Resume...\n"));
+ SafeVMPtr ptrVM(that);
alock.leave();
- int vrc = VMR3Resume(that->mpVM);
+ int vrc = VMR3Resume(ptrVM);
alock.enter();
if (RT_FAILURE(vrc))
{
@@ -8496,7 +9232,7 @@ DECLCALLBACK(int) Console::fntTakeSnapshotWorker(RTTHREAD Thread, void *pvUser)
{
/** @todo this could probably be made more generic and reused elsewhere. */
/* paranoid cleanup on for a failed online snapshot. */
- VMSTATE enmVMState = VMR3GetState(that->mpVM);
+ VMSTATE enmVMState = VMR3GetStateU(that->mpUVM);
switch (enmVMState)
{
case VMSTATE_RUNNING:
@@ -8535,8 +9271,9 @@ DECLCALLBACK(int) Console::fntTakeSnapshotWorker(RTTHREAD Thread, void *pvUser)
{
Assert(pTask->lastMachineState == MachineState_Running);
LogFlowFunc(("VMR3Resume (on failure)...\n"));
+ SafeVMPtr ptrVM(that);
alock.leave();
- int vrc = VMR3Resume(that->mpVM); AssertLogRelRC(vrc);
+ int vrc = VMR3Resume(ptrVM); AssertLogRelRC(vrc);
alock.enter();
if (RT_FAILURE(vrc))
that->setMachineState(MachineState_Paused);
@@ -8596,7 +9333,7 @@ DECLCALLBACK(int) Console::saveStateThread(RTTHREAD Thread, void *pvUser)
LogFlowFunc(("Saving the state to '%s'...\n", task->mSavedStateFile.c_str()));
bool fSuspenededBySave;
- int vrc = VMR3Save(that->mpVM,
+ int vrc = VMR3Save(task->mpVM,
task->mSavedStateFile.c_str(),
false, /*fContinueAfterwards*/
Console::stateProgressCallback,
@@ -8757,6 +9494,17 @@ typedef struct DRVMAINSTATUS
/** The unit number corresponding to the last entry in the LED array.
* (The size of the LED array is iLastLUN - iFirstLUN + 1.) */
RTUINT iLastLUN;
+ /** Pointer to the driver instance. */
+ PPDMDRVINS pDrvIns;
+ /** The Media Notify interface. */
+ PDMIMEDIANOTIFY IMediaNotify;
+ /** Map for translating PDM storage controller/LUN information to
+ * IMediumAttachment references. */
+ Console::MediumAttachmentMap *pmapMediumAttachments;
+ /** Device name+instance for mapping */
+ char *pszDeviceInstance;
+ /** Pointer to the Console object, for driver triggered activities. */
+ Console *pConsole;
} DRVMAINSTATUS, *PDRVMAINSTATUS;
@@ -8771,7 +9519,7 @@ typedef struct DRVMAINSTATUS
*/
DECLCALLBACK(void) Console::drvStatus_UnitChanged(PPDMILEDCONNECTORS pInterface, unsigned iLUN)
{
- PDRVMAINSTATUS pData = (PDRVMAINSTATUS)(void *)pInterface;
+ PDRVMAINSTATUS pData = (PDRVMAINSTATUS)((uintptr_t)pInterface - RT_OFFSETOF(DRVMAINSTATUS, ILedConnectors));
if (iLUN >= pData->iFirstLUN && iLUN <= pData->iLastLUN)
{
PPDMLED pLed;
@@ -8785,6 +9533,59 @@ DECLCALLBACK(void) Console::drvStatus_UnitChanged(PPDMILEDCONNECTORS pInterface,
/**
+ * Notification about a medium eject.
+ *
+ * @returns VBox status.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param uLUN The unit number.
+ */
+DECLCALLBACK(int) Console::drvStatus_MediumEjected(PPDMIMEDIANOTIFY pInterface, unsigned uLUN)
+{
+ PDRVMAINSTATUS pData = (PDRVMAINSTATUS)((uintptr_t)pInterface - RT_OFFSETOF(DRVMAINSTATUS, IMediaNotify));
+ PPDMDRVINS pDrvIns = pData->pDrvIns;
+ LogFunc(("uLUN=%d\n", uLUN));
+ if (pData->pmapMediumAttachments)
+ {
+ AutoWriteLock alock(pData->pConsole COMMA_LOCKVAL_SRC_POS);
+
+ ComPtr<IMediumAttachment> pMediumAtt;
+ Utf8Str devicePath = Utf8StrFmt("%s/LUN#%u", pData->pszDeviceInstance, uLUN);
+ Console::MediumAttachmentMap::const_iterator end = pData->pmapMediumAttachments->end();
+ Console::MediumAttachmentMap::const_iterator it = pData->pmapMediumAttachments->find(devicePath);
+ if (it != end)
+ pMediumAtt = it->second;
+ Assert(!pMediumAtt.isNull());
+ if (!pMediumAtt.isNull())
+ {
+ IMedium *pMedium;
+ HRESULT rc = pMediumAtt->COMGETTER(Medium)(&pMedium);
+ AssertComRC(rc);
+ BOOL fHostDrive = FALSE;
+ rc = pMedium->COMGETTER(HostDrive)(&fHostDrive);
+ AssertComRC(rc);
+ if (!fHostDrive)
+ {
+ alock.release();
+
+ ComPtr<IMediumAttachment> pNewMediumAtt;
+ rc = pData->pConsole->mControl->EjectMedium(pMediumAtt, pNewMediumAtt.asOutParam());
+ if (SUCCEEDED(rc))
+ fireMediumChangedEvent(pData->pConsole->mEventSource, pNewMediumAtt);
+
+ alock.acquire();
+ if (pNewMediumAtt != pMediumAtt)
+ {
+ pData->pmapMediumAttachments->erase(devicePath);
+ pData->pmapMediumAttachments->insert(std::make_pair(devicePath, pNewMediumAtt));
+ }
+ }
+ }
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
* @interface_method_impl{PDMIBASE,pfnQueryInterface}
*/
DECLCALLBACK(void *) Console::drvStatus_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
@@ -8793,6 +9594,7 @@ DECLCALLBACK(void *) Console::drvStatus_QueryInterface(PPDMIBASE pInterface, co
PDRVMAINSTATUS pThis = PDMINS_2_DATA(pDrvIns, PDRVMAINSTATUS);
PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDCONNECTORS, &pThis->ILedConnectors);
+ PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIANOTIFY, &pThis->IMediaNotify);
return NULL;
}
@@ -8832,7 +9634,7 @@ DECLCALLBACK(int) Console::drvStatus_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCf
/*
* Validate configuration.
*/
- if (!CFGMR3AreValuesValid(pCfg, "papLeds\0First\0Last\0"))
+ if (!CFGMR3AreValuesValid(pCfg, "papLeds\0pmapMediumAttachments\0DeviceInstance\0pConsole\0First\0Last\0"))
return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
("Configuration error: Not possible to attach anything to this driver!\n"),
@@ -8843,6 +9645,9 @@ DECLCALLBACK(int) Console::drvStatus_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCf
*/
pDrvIns->IBase.pfnQueryInterface = Console::drvStatus_QueryInterface;
pData->ILedConnectors.pfnUnitChanged = Console::drvStatus_UnitChanged;
+ pData->IMediaNotify.pfnEjected = Console::drvStatus_MediumEjected;
+ pData->pDrvIns = pDrvIns;
+ pData->pszDeviceInstance = NULL;
/*
* Read config.
@@ -8854,6 +9659,28 @@ DECLCALLBACK(int) Console::drvStatus_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCf
return rc;
}
+ rc = CFGMR3QueryPtrDef(pCfg, "pmapMediumAttachments", (void **)&pData->pmapMediumAttachments, NULL);
+ if (RT_FAILURE(rc))
+ {
+ AssertMsgFailed(("Configuration error: Failed to query the \"pmapMediumAttachments\" value! rc=%Rrc\n", rc));
+ return rc;
+ }
+ if (pData->pmapMediumAttachments)
+ {
+ rc = CFGMR3QueryStringAlloc(pCfg, "DeviceInstance", &pData->pszDeviceInstance);
+ if (RT_FAILURE(rc))
+ {
+ AssertMsgFailed(("Configuration error: Failed to query the \"DeviceInstance\" value! rc=%Rrc\n", rc));
+ return rc;
+ }
+ rc = CFGMR3QueryPtr(pCfg, "pConsole", (void **)&pData->pConsole);
+ if (RT_FAILURE(rc))
+ {
+ AssertMsgFailed(("Configuration error: Failed to query the \"pConsole\" value! rc=%Rrc\n", rc));
+ return rc;
+ }
+ }
+
rc = CFGMR3QueryU32(pCfg, "First", &pData->iFirstLUN);
if (rc == VERR_CFGM_VALUE_NOT_FOUND)
pData->iFirstLUN = 0;
@@ -8893,7 +9720,7 @@ DECLCALLBACK(int) Console::drvStatus_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCf
/**
- * Keyboard driver registration record.
+ * Console status driver (LED) registration record.
*/
const PDMDRVREG Console::DrvStatusReg =
{
diff --git a/src/VBox/Main/src-client/ConsoleImpl2.cpp b/src/VBox/Main/src-client/ConsoleImpl2.cpp
index b81c39423..aae3a5e30 100644
--- a/src/VBox/Main/src-client/ConsoleImpl2.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl2.cpp
@@ -1,4 +1,4 @@
-/* $Id: ConsoleImpl2.cpp $ */
+/* $Id: ConsoleImpl2.cpp 37902 2011-07-12 13:49:32Z vboxsync $ */
/** @file
* VBox Console COM Class implementation
*
@@ -33,6 +33,9 @@
#endif
#include "VMMDev.h"
#include "Global.h"
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+# include "PciRawDevImpl.h"
+#endif
// generated header
#include "SchemaDefs.h"
@@ -96,7 +99,7 @@
# include <net80211/ieee80211_ioctl.h>
# endif
# if defined(RT_OS_WINDOWS)
-# include <VBox/WinNetConfig.h>
+# include <VBox/VBoxNetCfg-win.h>
# include <Ntddndis.h>
# include <devguid.h>
# else
@@ -312,15 +315,17 @@ static int getSmcDeviceKey(IMachine *pMachine, BSTR *aKey, bool *pfGetKeyFromRea
# pragma optimize("g", off)
#endif
+static const char *const g_apszIDEDrives[4] =
+ { "PrimaryMaster", "PrimarySlave", "SecondaryMaster", "SecondarySlave" };
-class ConfigError : public iprt::Error
+class ConfigError : public RTCError
{
public:
ConfigError(const char *pcszFunction,
int vrc,
const char *pcszName)
- : iprt::Error(Utf8StrFmt("%s failed: rc=%Rrc, pcszName=%s", pcszFunction, vrc, pcszName)),
+ : RTCError(Utf8StrFmt("%s failed: rc=%Rrc, pcszName=%s", pcszFunction, vrc, pcszName)),
m_vrc(vrc)
{
AssertMsgFailed(("%s\n", what())); // in strict mode, hit a breakpoint here
@@ -331,7 +336,7 @@ public:
/**
- * Helper that calls CFGMR3InsertString and throws an iprt::Error if that
+ * Helper that calls CFGMR3InsertString and throws an RTCError if that
* fails (C-string variant).
* @param pParent See CFGMR3InsertStringN.
* @param pcszNodeName See CFGMR3InsertStringN.
@@ -349,7 +354,7 @@ static void InsertConfigString(PCFGMNODE pNode,
}
/**
- * Helper that calls CFGMR3InsertString and throws an iprt::Error if that
+ * Helper that calls CFGMR3InsertString and throws an RTCError if that
* fails (Utf8Str variant).
* @param pParent See CFGMR3InsertStringN.
* @param pcszNodeName See CFGMR3InsertStringN.
@@ -368,7 +373,7 @@ static void InsertConfigString(PCFGMNODE pNode,
}
/**
- * Helper that calls CFGMR3InsertString and throws an iprt::Error if that
+ * Helper that calls CFGMR3InsertString and throws an RTCError if that
* fails (Bstr variant).
*
* @param pParent See CFGMR3InsertStringN.
@@ -383,7 +388,7 @@ static void InsertConfigString(PCFGMNODE pNode,
}
/**
- * Helper that calls CFGMR3InsertBytes and throws an iprt::Error if that fails.
+ * Helper that calls CFGMR3InsertBytes and throws an RTCError if that fails.
*
* @param pNode See CFGMR3InsertBytes.
* @param pcszName See CFGMR3InsertBytes.
@@ -404,7 +409,7 @@ static void InsertConfigBytes(PCFGMNODE pNode,
}
/**
- * Helper that calls CFGMR3InsertInteger and throws an iprt::Error if that
+ * Helper that calls CFGMR3InsertInteger and throws an RTCError if that
* fails.
*
* @param pNode See CFGMR3InsertInteger.
@@ -423,7 +428,7 @@ static void InsertConfigInteger(PCFGMNODE pNode,
}
/**
- * Helper that calls CFGMR3InsertNode and throws an iprt::Error if that fails.
+ * Helper that calls CFGMR3InsertNode and throws an RTCError if that fails.
*
* @param pNode See CFGMR3InsertNode.
* @param pcszName See CFGMR3InsertNode.
@@ -439,7 +444,7 @@ static void InsertConfigNode(PCFGMNODE pNode,
}
/**
- * Helper that calls CFGMR3RemoveValue and throws an iprt::Error if that fails.
+ * Helper that calls CFGMR3RemoveValue and throws an RTCError if that fails.
*
* @param pNode See CFGMR3RemoveValue.
* @param pcszName See CFGMR3RemoveValue.
@@ -452,6 +457,172 @@ static void RemoveConfigValue(PCFGMNODE pNode,
throw ConfigError("CFGMR3RemoveValue", vrc, pcszName);
}
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+HRESULT Console::attachRawPciDevices(PVM pVM,
+ BusAssignmentManager *BusMgr,
+ PCFGMNODE pDevices)
+{
+ HRESULT hrc = S_OK;
+ PCFGMNODE pInst, pCfg, pLunL0, pLunL1;
+
+ SafeIfaceArray<IPciDeviceAttachment> assignments;
+ ComPtr<IMachine> aMachine = machine();
+
+ hrc = aMachine->COMGETTER(PciDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
+ if ( hrc != S_OK
+ || assignments.size() < 1)
+ return hrc;
+
+ /*
+ * PCI passthrough is only available if the proper ExtPack is installed.
+ *
+ * Note. Configuring PCI passthrough here and providing messages about
+ * the missing extpack isn't exactly clean, but it is a necessary evil
+ * to patch over legacy compatability issues introduced by the new
+ * distribution model.
+ */
+# ifdef VBOX_WITH_EXTPACK
+ static const char *s_pszPciRawExtPackName = "Oracle VM VirtualBox Extension Pack";
+ if (!mptrExtPackManager->isExtPackUsable(s_pszPciRawExtPackName))
+ {
+ /* Always fatal! */
+ return VMSetError(pVM, VERR_NOT_FOUND, RT_SRC_POS,
+ N_("Implementation of the PCI passthrough framework not found!\n"
+ "The VM cannot be started. To fix this problem, either "
+ "install the '%s' or disable PCI passthrough via VBoxManage"),
+ s_pszPciRawExtPackName);
+ }
+# endif
+
+ PCFGMNODE pBridges = CFGMR3GetChild(pDevices, "ich9pcibridge");
+ Assert(pBridges);
+
+ /* Find required bridges, and add missing ones */
+ for (size_t iDev = 0; iDev < assignments.size(); iDev++)
+ {
+ ComPtr<IPciDeviceAttachment> assignment = assignments[iDev];
+ LONG guest = 0;
+ PciBusAddress GuestPciAddress;
+
+ assignment->COMGETTER(GuestAddress)(&guest);
+ GuestPciAddress.fromLong(guest);
+ Assert(GuestPciAddress.valid());
+
+ if (GuestPciAddress.miBus > 0)
+ {
+ int iBridgesMissed = 0;
+ int iBase = GuestPciAddress.miBus - 1;
+
+ while (!BusMgr->hasPciDevice("ich9pcibridge", iBase) && iBase > 0)
+ {
+ iBridgesMissed++; iBase--;
+ }
+ iBase++;
+
+ for (int iBridge = 0; iBridge < iBridgesMissed; iBridge++)
+ {
+ InsertConfigNode(pBridges, Utf8StrFmt("%d", iBase + iBridge).c_str(), &pInst);
+ InsertConfigInteger(pInst, "Trusted", 1);
+ hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst);
+ }
+ }
+ }
+
+ /* Now actually add devices */
+ PCFGMNODE pPciDevs = NULL;
+
+ if (assignments.size() > 0)
+ {
+ InsertConfigNode(pDevices, "pciraw", &pPciDevs);
+
+ PCFGMNODE pRoot = CFGMR3GetParent(pDevices); Assert(pRoot);
+
+ /* Tell PGM to tell GPciRaw about guest mappings. */
+ CFGMR3InsertNode(pRoot, "PGM", NULL);
+ InsertConfigInteger(CFGMR3GetChild(pRoot, "PGM"), "PciPassThrough", 1);
+
+ /*
+ * Currently, using IOMMU needed for PCI passthrough
+ * requires RAM preallocation.
+ */
+ /** @todo: check if we can lift this requirement */
+ CFGMR3RemoveValue(pRoot, "RamPreAlloc");
+ InsertConfigInteger(pRoot, "RamPreAlloc", 1);
+ }
+
+ for (size_t iDev = 0; iDev < assignments.size(); iDev++)
+ {
+ PciBusAddress HostPciAddress, GuestPciAddress;
+ ComPtr<IPciDeviceAttachment> assignment = assignments[iDev];
+ LONG host, guest;
+ Bstr aDevName;
+
+ assignment->COMGETTER(HostAddress)(&host);
+ assignment->COMGETTER(GuestAddress)(&guest);
+ assignment->COMGETTER(Name)(aDevName.asOutParam());
+
+ InsertConfigNode(pPciDevs, Utf8StrFmt("%d", iDev).c_str(), &pInst);
+ InsertConfigInteger(pInst, "Trusted", 1);
+
+ HostPciAddress.fromLong(host);
+ Assert(HostPciAddress.valid());
+ InsertConfigNode(pInst, "Config", &pCfg);
+ InsertConfigString(pCfg, "DeviceName", aDevName);
+
+ InsertConfigInteger(pCfg, "DetachHostDriver", 1);
+ InsertConfigInteger(pCfg, "HostPCIBusNo", HostPciAddress.miBus);
+ InsertConfigInteger(pCfg, "HostPCIDeviceNo", HostPciAddress.miDevice);
+ InsertConfigInteger(pCfg, "HostPCIFunctionNo", HostPciAddress.miFn);
+
+ GuestPciAddress.fromLong(guest);
+ Assert(GuestPciAddress.valid());
+ hrc = BusMgr->assignHostPciDevice("pciraw", pInst, HostPciAddress, GuestPciAddress, true);
+ if (hrc != S_OK)
+ return hrc;
+
+ InsertConfigInteger(pCfg, "GuestPCIBusNo", GuestPciAddress.miBus);
+ InsertConfigInteger(pCfg, "GuestPCIDeviceNo", GuestPciAddress.miDevice);
+ InsertConfigInteger(pCfg, "GuestPCIFunctionNo", GuestPciAddress.miFn);
+
+ /* the driver */
+ InsertConfigNode(pInst, "LUN#0", &pLunL0);
+ InsertConfigString(pLunL0, "Driver", "pciraw");
+ InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
+
+ /* the Main driver */
+ InsertConfigString(pLunL1, "Driver", "MainPciRaw");
+ InsertConfigNode(pLunL1, "Config", &pCfg);
+ PciRawDev* pMainDev = new PciRawDev(this);
+ InsertConfigInteger(pCfg, "Object", (uintptr_t)pMainDev);
+ }
+
+ return hrc;
+}
+#endif
+
+
+void Console::attachStatusDriver(PCFGMNODE pCtlInst, PPDMLED *papLeds,
+ uint64_t uFirst, uint64_t uLast,
+ Console::MediumAttachmentMap *pmapMediumAttachments,
+ const char *pcszDevice, unsigned uInstance)
+{
+ PCFGMNODE pLunL0, pCfg;
+ InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
+ InsertConfigString(pLunL0, "Driver", "MainStatus");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+ InsertConfigInteger(pCfg, "papLeds", (uintptr_t)papLeds);
+ if (pmapMediumAttachments)
+ {
+ InsertConfigInteger(pCfg, "pmapMediumAttachments", (uintptr_t)pmapMediumAttachments);
+ InsertConfigInteger(pCfg, "pConsole", (uintptr_t)this);
+ AssertPtr(pcszDevice);
+ Utf8Str deviceInstance = Utf8StrFmt("%s/%u", pcszDevice, uInstance);
+ InsertConfigString(pCfg, "DeviceInstance", deviceInstance.c_str());
+ }
+ InsertConfigInteger(pCfg, "First", uFirst);
+ InsertConfigInteger(pCfg, "Last", uLast);
+}
+
/**
* Construct the VM configuration tree (CFGM).
@@ -483,10 +654,14 @@ DECLCALLBACK(int) Console::configConstructor(PVM pVM, void *pvConsole)
* Set the VM handle and do the rest of the job in an worker method so we
* can easily reset the VM handle on failure.
*/
- pConsole->mpVM = pVM;
+ PUVM pUVM = pConsole->mpUVM = VMR3GetUVM(pVM);
+ VMR3RetainUVM(pUVM);
int vrc = pConsole->configConstructorInner(pVM, &alock);
if (RT_FAILURE(vrc))
- pConsole->mpVM = NULL;
+ {
+ pConsole->mpUVM = NULL;
+ VMR3ReleaseUVM(pUVM);
+ }
return vrc;
}
@@ -497,6 +672,9 @@ DECLCALLBACK(int) Console::configConstructor(PVM pVM, void *pvConsole)
*
* @return VBox status code.
* @param pVM The VM handle.
+ * @param pAlock The automatic lock instance. This is for when we have
+ * to leave it in order to avoid deadlocks (ext packs and
+ * more).
*/
int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
{
@@ -515,24 +693,24 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
* Get necessary objects and frequently used parameters.
*/
ComPtr<IVirtualBox> virtualBox;
- hrc = pMachine->COMGETTER(Parent)(virtualBox.asOutParam()); H();
+ hrc = pMachine->COMGETTER(Parent)(virtualBox.asOutParam()); H();
ComPtr<IHost> host;
- hrc = virtualBox->COMGETTER(Host)(host.asOutParam()); H();
+ hrc = virtualBox->COMGETTER(Host)(host.asOutParam()); H();
ComPtr<ISystemProperties> systemProperties;
- hrc = virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam()); H();
+ hrc = virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam()); H();
ComPtr<IBIOSSettings> biosSettings;
- hrc = pMachine->COMGETTER(BIOSSettings)(biosSettings.asOutParam()); H();
+ hrc = pMachine->COMGETTER(BIOSSettings)(biosSettings.asOutParam()); H();
- hrc = pMachine->COMGETTER(HardwareUUID)(bstr.asOutParam()); H();
+ hrc = pMachine->COMGETTER(HardwareUUID)(bstr.asOutParam()); H();
RTUUID HardwareUuid;
rc = RTUuidFromUtf16(&HardwareUuid, bstr.raw());
AssertRCReturn(rc, rc);
ULONG cRamMBs;
- hrc = pMachine->COMGETTER(MemorySize)(&cRamMBs); H();
+ hrc = pMachine->COMGETTER(MemorySize)(&cRamMBs); H();
#if 0 /* enable to play with lots of memory. */
if (RTEnvExist("VBOX_RAM_SIZE"))
cRamMBs = RTStrToUInt64(RTEnvGet("VBOX_RAM_SIZE"));
@@ -543,7 +721,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
uint32_t cbMcfgLength = 0;
ChipsetType_T chipsetType;
- hrc = pMachine->COMGETTER(ChipsetType)(&chipsetType); H();
+ hrc = pMachine->COMGETTER(ChipsetType)(&chipsetType); H();
if (chipsetType == ChipsetType_ICH9)
{
/* We'd better have 0x10000000 region, to cover 256 buses
@@ -556,22 +734,22 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
BusAssignmentManager* BusMgr = mBusMgr = BusAssignmentManager::createInstance(chipsetType);
ULONG cCpus = 1;
- hrc = pMachine->COMGETTER(CPUCount)(&cCpus); H();
+ hrc = pMachine->COMGETTER(CPUCount)(&cCpus); H();
ULONG ulCpuExecutionCap = 100;
- hrc = pMachine->COMGETTER(CPUExecutionCap)(&ulCpuExecutionCap); H();
+ hrc = pMachine->COMGETTER(CPUExecutionCap)(&ulCpuExecutionCap); H();
Bstr osTypeId;
- hrc = pMachine->COMGETTER(OSTypeId)(osTypeId.asOutParam()); H();
+ hrc = pMachine->COMGETTER(OSTypeId)(osTypeId.asOutParam()); H();
BOOL fIOAPIC;
- hrc = biosSettings->COMGETTER(IOAPICEnabled)(&fIOAPIC); H();
+ hrc = biosSettings->COMGETTER(IOAPICEnabled)(&fIOAPIC); H();
ComPtr<IGuestOSType> guestOSType;
- hrc = virtualBox->GetGuestOSType(osTypeId.raw(), guestOSType.asOutParam()); H();
+ hrc = virtualBox->GetGuestOSType(osTypeId.raw(), guestOSType.asOutParam()); H();
Bstr guestTypeFamilyId;
- hrc = guestOSType->COMGETTER(FamilyId)(guestTypeFamilyId.asOutParam()); H();
+ hrc = guestOSType->COMGETTER(FamilyId)(guestTypeFamilyId.asOutParam()); H();
BOOL fOsXGuest = guestTypeFamilyId == Bstr("MacOS");
/*
@@ -919,15 +1097,19 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pDevices, "ich9pcibridge", &pDev);
InsertConfigNode(pDev, "0", &pInst);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst); H();
+ hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst); H();
InsertConfigNode(pDev, "1", &pInst);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst); H();
- }
+ hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst); H();
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ /* Add PCI passthrough devices */
+ hrc = attachRawPciDevices(pVM, BusMgr, pDevices); H();
+#endif
+ }
/*
- * Enable 3 following devices: HPET, SMC, LPC on MacOS X guests
+ * Enable 3 following devices: HPET, SMC, LPC on MacOS X guests or on ICH9 chipset
*/
/*
* High Precision Event Timer (HPET)
@@ -944,6 +1126,8 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pDevices, "hpet", &pDev);
InsertConfigNode(pDev, "0", &pInst);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
+ InsertConfigNode(pInst, "Config", &pCfg);
+ InsertConfigInteger(pCfg, "ICH9", (chipsetType == ChipsetType_ICH9) ? 1 : 0); /* boolean */
}
/*
@@ -977,7 +1161,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
{
InsertConfigNode(pDevices, "lpc", &pDev);
InsertConfigNode(pDev, "0", &pInst);
- hrc = BusMgr->assignPciDevice("lpc", pInst); H();
+ hrc = BusMgr->assignPciDevice("lpc", pInst); H();
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
}
@@ -1053,6 +1237,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pDev, "0", &pInst);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
InsertConfigNode(pInst, "Config", &pCfg);
+ InsertConfigInteger(pCfg, "NumCPUs", cCpus);
}
/*
@@ -1072,7 +1257,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pDev, "0", &pInst);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPciDevice("vga", pInst); H();
+ hrc = BusMgr->assignPciDevice("vga", pInst); H();
InsertConfigNode(pInst, "Config", &pCfg);
ULONG cVRamMBs;
hrc = pMachine->COMGETTER(VRAMSize)(&cVRamMBs); H();
@@ -1343,43 +1528,35 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
{
case StorageControllerType_LsiLogic:
{
- hrc = BusMgr->assignPciDevice("lsilogic", pCtlInst); H();
+ hrc = BusMgr->assignPciDevice("lsilogic", pCtlInst); H();
InsertConfigInteger(pCfg, "Bootable", fBootable);
/* Attach the status driver */
- InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "MainStatus");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&mapStorageLeds[iLedScsi]);
- InsertConfigInteger(pCfg, "First", 0);
Assert(cLedScsi >= 16);
- InsertConfigInteger(pCfg, "Last", 15);
+ attachStatusDriver(pCtlInst, &mapStorageLeds[iLedScsi], 0, 15,
+ &mapMediumAttachments, pszCtrlDev, ulInstance);
paLedDevType = &maStorageDevType[iLedScsi];
break;
}
case StorageControllerType_BusLogic:
{
- hrc = BusMgr->assignPciDevice("buslogic", pCtlInst); H();
+ hrc = BusMgr->assignPciDevice("buslogic", pCtlInst); H();
InsertConfigInteger(pCfg, "Bootable", fBootable);
/* Attach the status driver */
- InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "MainStatus");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&mapStorageLeds[iLedScsi]);
- InsertConfigInteger(pCfg, "First", 0);
Assert(cLedScsi >= 16);
- InsertConfigInteger(pCfg, "Last", 15);
+ attachStatusDriver(pCtlInst, &mapStorageLeds[iLedScsi], 0, 15,
+ &mapMediumAttachments, pszCtrlDev, ulInstance);
paLedDevType = &maStorageDevType[iLedScsi];
break;
}
case StorageControllerType_IntelAhci:
{
- hrc = BusMgr->assignPciDevice("ahci", pCtlInst); H();
+ hrc = BusMgr->assignPciDevice("ahci", pCtlInst); H();
ULONG cPorts = 0;
hrc = ctrls[i]->COMGETTER(PortCount)(&cPorts); H();
@@ -1396,27 +1573,21 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
for (uint32_t j = 0; j < 4; ++j)
{
- static const char * const s_apszConfig[4] =
- { "PrimaryMaster", "PrimarySlave", "SecondaryMaster", "SecondarySlave" };
static const char * const s_apszBiosConfig[4] =
{ "SataPrimaryMasterLUN", "SataPrimarySlaveLUN", "SataSecondaryMasterLUN", "SataSecondarySlaveLUN" };
LONG lPortNumber = -1;
- hrc = ctrls[i]->GetIDEEmulationPort(j, &lPortNumber); H();
- InsertConfigInteger(pCfg, s_apszConfig[j], lPortNumber);
+ hrc = ctrls[i]->GetIDEEmulationPort(j, &lPortNumber); H();
+ InsertConfigInteger(pCfg, g_apszIDEDrives[j], lPortNumber);
if (pBiosCfg)
InsertConfigInteger(pBiosCfg, s_apszBiosConfig[j], lPortNumber);
}
}
/* Attach the status driver */
- InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "MainStatus");
- InsertConfigNode(pLunL0, "Config", &pCfg);
AssertRelease(cPorts <= cLedSata);
- InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&mapStorageLeds[iLedSata]);
- InsertConfigInteger(pCfg, "First", 0);
- InsertConfigInteger(pCfg, "Last", cPorts - 1);
+ attachStatusDriver(pCtlInst, &mapStorageLeds[iLedSata], 0, cPorts - 1,
+ &mapMediumAttachments, pszCtrlDev, ulInstance);
paLedDevType = &maStorageDevType[iLedSata];
break;
}
@@ -1428,17 +1599,12 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
/*
* IDE (update this when the main interface changes)
*/
- hrc = BusMgr->assignPciDevice("piix3ide", pCtlInst); H();
+ hrc = BusMgr->assignPciDevice("piix3ide", pCtlInst); H();
InsertConfigString(pCfg, "Type", controllerString(enmCtrlType));
-
/* Attach the status driver */
- InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "MainStatus");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&mapStorageLeds[iLedIde]);
- InsertConfigInteger(pCfg, "First", 0);
Assert(cLedIde >= 4);
- InsertConfigInteger(pCfg, "Last", 3);
+ attachStatusDriver(pCtlInst, &mapStorageLeds[iLedIde], 0, 3,
+ &mapMediumAttachments, pszCtrlDev, ulInstance);
paLedDevType = &maStorageDevType[iLedIde];
/* IDE flavors */
@@ -1460,32 +1626,24 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigInteger(pCfg, "IOBase", 0x3f0);
/* Attach the status driver */
- InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "MainStatus");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&mapStorageLeds[iLedFloppy]);
- InsertConfigInteger(pCfg, "First", 0);
- Assert(cLedFloppy >= 1);
- InsertConfigInteger(pCfg, "Last", 0);
+ Assert(cLedFloppy >= 2);
+ attachStatusDriver(pCtlInst, &mapStorageLeds[iLedFloppy], 0, 1,
+ &mapMediumAttachments, pszCtrlDev, ulInstance);
paLedDevType = &maStorageDevType[iLedFloppy];
break;
}
case StorageControllerType_LsiLogicSas:
{
- hrc = BusMgr->assignPciDevice("lsilogicsas", pCtlInst); H();
+ hrc = BusMgr->assignPciDevice("lsilogicsas", pCtlInst); H();
InsertConfigString(pCfg, "ControllerType", "SAS1068");
InsertConfigInteger(pCfg, "Bootable", fBootable);
/* Attach the status driver */
- InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "MainStatus");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&mapStorageLeds[iLedSas]);
- InsertConfigInteger(pCfg, "First", 0);
Assert(cLedSas >= 8);
- InsertConfigInteger(pCfg, "Last", 7);
+ attachStatusDriver(pCtlInst, &mapStorageLeds[iLedSas], 0, 7,
+ &mapMediumAttachments, pszCtrlDev, ulInstance);
paLedDevType = &maStorageDevType[iLedSas];
break;
}
@@ -1497,15 +1655,16 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
/* Attach the media to the storage controllers. */
com::SafeIfaceArray<IMediumAttachment> atts;
hrc = pMachine->GetMediumAttachmentsOfController(controllerName.raw(),
- ComSafeArrayAsOutParam(atts)); H();
+ ComSafeArrayAsOutParam(atts)); H();
/* Builtin I/O cache - per device setting. */
BOOL fBuiltinIoCache = true;
- hrc = pMachine->COMGETTER(IoCacheEnabled)(&fBuiltinIoCache); H();
+ hrc = pMachine->COMGETTER(IoCacheEnabled)(&fBuiltinIoCache); H();
for (size_t j = 0; j < atts.size(); ++j)
{
+ IMediumAttachment *pMediumAtt = atts[j];
rc = configMediumAttachment(pCtlInst,
pszCtrlDev,
ulInstance,
@@ -1515,11 +1674,12 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
false /* fSetupMerge */,
0 /* uMergeSource */,
0 /* uMergeTarget */,
- atts[j],
+ pMediumAtt,
mMachineState,
NULL /* phrc */,
false /* fAttachDetach */,
false /* fForceUnmount */,
+ false /* fHotplug */,
pVM,
paLedDevType);
if (RT_FAILURE(rc))
@@ -1624,7 +1784,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
iPciDeviceNo = 3;
#endif
PciBusAddress PciAddr = PciBusAddress(0, iPciDeviceNo, 0);
- hrc = BusMgr->assignPciDevice(pszAdapterName, pInst, PciAddr); H();
+ hrc = BusMgr->assignPciDevice(pszAdapterName, pInst, PciAddr); H();
InsertConfigNode(pInst, "Config", &pCfg);
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE /* not safe here yet. */
@@ -1709,10 +1869,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
/*
* Attach the status driver.
*/
- InsertConfigNode(pInst, "LUN#999", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "MainStatus");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&mapNetworkLeds[ulInstance]);
+ attachStatusDriver(pInst, &mapNetworkLeds[ulInstance], 0, 0, NULL, NULL, 0);
/*
* Configure the network card now
@@ -1751,15 +1908,18 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
achBootIdx[0] = '0' + uBootIdx++; /* Boot device order. */
InsertConfigNode(pNetBootCfg, achBootIdx, &pNetBtDevCfg);
InsertConfigInteger(pNetBtDevCfg, "NIC", it->mInstance);
- InsertConfigInteger(pNetBtDevCfg, "PCIBusNo", it->mPciAddress.iBus);
- InsertConfigInteger(pNetBtDevCfg, "PCIDeviceNo", it->mPciAddress.iDevice);
- InsertConfigInteger(pNetBtDevCfg, "PCIFunctionNo", it->mPciAddress.iFn);
+ InsertConfigInteger(pNetBtDevCfg, "PCIBusNo", it->mPciAddress.miBus);
+ InsertConfigInteger(pNetBtDevCfg, "PCIDeviceNo", it->mPciAddress.miDevice);
+ InsertConfigInteger(pNetBtDevCfg, "PCIFunctionNo", it->mPciAddress.miFn);
}
}
/*
* Serial (UART) Ports
*/
+ /* serial enabled mask to be passed to dev ACPI */
+ uint16_t auSerialIoPortBase[SchemaDefs::SerialPortCount] = {0};
+ uint8_t auSerialIrq[SchemaDefs::SerialPortCount] = {0};
InsertConfigNode(pDevices, "serial", &pDev);
for (ULONG ulInstance = 0; ulInstance < SchemaDefs::SerialPortCount; ++ulInstance)
{
@@ -1777,9 +1937,13 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
ULONG ulIRQ;
hrc = serialPort->COMGETTER(IRQ)(&ulIRQ); H();
InsertConfigInteger(pCfg, "IRQ", ulIRQ);
+ auSerialIrq[ulInstance] = (uint8_t)ulIRQ;
+
ULONG ulIOBase;
hrc = serialPort->COMGETTER(IOBase)(&ulIOBase); H();
InsertConfigInteger(pCfg, "IOBase", ulIOBase);
+ auSerialIoPortBase[ulInstance] = (uint16_t)ulIOBase;
+
BOOL fServer;
hrc = serialPort->COMGETTER(Server)(&fServer); H();
hrc = serialPort->COMGETTER(Path)(bstr.asOutParam()); H();
@@ -1853,7 +2017,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pDev, "0", &pInst);
InsertConfigNode(pInst, "Config", &pCfg);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPciDevice("VMMDev", pInst); H();
+ hrc = BusMgr->assignPciDevice("VMMDev", pInst); H();
Bstr hwVersion;
hrc = pMachine->COMGETTER(HardwareVersion)(hwVersion.asOutParam()); H();
@@ -1861,7 +2025,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
if (hwVersion.compare(Bstr("1").raw()) == 0) /* <= 2.0.x */
InsertConfigInteger(pCfg, "HeapEnabled", 0);
Bstr snapshotFolder;
- hrc = pMachine->COMGETTER(SnapshotFolder)(snapshotFolder.asOutParam()); H();
+ hrc = pMachine->COMGETTER(SnapshotFolder)(snapshotFolder.asOutParam()); H();
InsertConfigString(pCfg, "GuestCoreDumpDir", snapshotFolder);
/* the VMM device's Main driver */
@@ -1873,12 +2037,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
/*
* Attach the status driver.
*/
- InsertConfigNode(pInst, "LUN#999", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "MainStatus");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&mapSharedFolderLed);
- InsertConfigInteger(pCfg, "First", 0);
- InsertConfigInteger(pCfg, "Last", 0);
+ attachStatusDriver(pInst, &mapSharedFolderLed, 0, 0, NULL, NULL, 0);
/*
* Audio Sniffer Device
@@ -1897,7 +2056,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
/*
* AC'97 ICH / SoundBlaster16 audio / Intel HD Audio
*/
- BOOL fAudioEnabled;
+ BOOL fAudioEnabled = FALSE;
ComPtr<IAudioAdapter> audioAdapter;
hrc = pMachine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam()); H();
if (audioAdapter)
@@ -1915,7 +2074,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pDevices, "ichac97", &pDev);
InsertConfigNode(pDev, "0", &pInst);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPciDevice("ichac97", pInst); H();
+ hrc = BusMgr->assignPciDevice("ichac97", pInst); H();
InsertConfigNode(pInst, "Config", &pCfg);
break;
}
@@ -1939,7 +2098,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pDevices, "hda", &pDev);
InsertConfigNode(pDev, "0", &pInst);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPciDevice("hda", pInst); H();
+ hrc = BusMgr->assignPciDevice("hda", pInst); H();
InsertConfigNode(pInst, "Config", &pCfg);
}
}
@@ -2046,12 +2205,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
/*
* Attach the status driver.
*/
- InsertConfigNode(pInst, "LUN#999", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "MainStatus");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&mapUSBLed[0]);
- InsertConfigInteger(pCfg, "First", 0);
- InsertConfigInteger(pCfg, "Last", 0);
+ attachStatusDriver(pInst, &mapUSBLed[0], 0, 0, NULL, NULL, 0);
#ifdef VBOX_WITH_EHCI
BOOL fEhciEnabled;
@@ -2084,12 +2238,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
/*
* Attach the status driver.
*/
- InsertConfigNode(pInst, "LUN#999", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "MainStatus");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&mapUSBLed[1]);
- InsertConfigInteger(pCfg, "First", 0);
- InsertConfigInteger(pCfg, "Last", 0);
+ attachStatusDriver(pInst, &mapUSBLed[1], 0, 0, NULL, NULL, 0);
}
# ifdef VBOX_WITH_EXTPACK
else
@@ -2131,6 +2280,25 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
}
#endif
+#ifdef VBOX_WITH_USB_VIDEO
+
+ InsertConfigNode(pUsbDevices, "Webcam", &pDev);
+ InsertConfigNode(pDev, "0", &pInst);
+ InsertConfigNode(pInst, "Config", &pCfg);
+# if 0 /* Experiments with attaching */
+ InsertConfigInteger(pCfg, "USBVER", RT_BIT(2));
+# endif
+ InsertConfigNode(pInst, "LUN#0", &pLunL0);
+# ifdef VBOX_WITH_USB_VIDEO_TEST
+ InsertConfigString(pLunL0, "Driver", "WebcamFileFeeder");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+ InsertConfigString(pCfg, "DirToFeed", "out");
+# else
+ InsertConfigString(pLunL0, "Driver", "UsbWebcamInterface");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+ InsertConfigInteger(pCfg, "Object", mUsbWebcamInterface);
+# endif
+#endif
# if 0 /* Virtual MSD*/
InsertConfigNode(pUsbDevices, "Msd", &pDev);
@@ -2262,6 +2430,10 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
pVMMDev->hgcmHostCall("VBoxSharedClipboard", VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE, 1, &parm);
+ parm.setUInt32(!useHostClipboard());
+
+ pVMMDev->hgcmHostCall("VBoxSharedClipboard", VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS, 1, &parm);
+
Log(("Set VBoxSharedClipboard mode\n"));
}
}
@@ -2363,7 +2535,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
if (fOsXGuest && !llBootNics.empty())
{
BootNic aNic = llBootNics.front();
- uint32_t u32NicPciAddr = (aNic.mPciAddress.iDevice << 16) | aNic.mPciAddress.iFn;
+ uint32_t u32NicPciAddr = (aNic.mPciAddress.miDevice << 16) | aNic.mPciAddress.miFn;
InsertConfigInteger(pCfg, "NicPciAddress", u32NicPciAddr);
}
if (fOsXGuest && fAudioEnabled)
@@ -2371,7 +2543,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
PciBusAddress Address;
if (BusMgr->findPciAddress("hda", 0, Address))
{
- uint32_t u32AudioPciAddr = (Address.iDevice << 16) | Address.iFn;
+ uint32_t u32AudioPciAddr = (Address.miDevice << 16) | Address.miFn;
InsertConfigInteger(pCfg, "AudioPciAddress", u32AudioPciAddr);
}
}
@@ -2385,6 +2557,12 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigInteger(pCfg, "ShowCpu", fShowCpu);
InsertConfigInteger(pCfg, "CpuHotPlug", fCpuHotPlug);
+ InsertConfigInteger(pCfg, "Serial0IoPortBase", auSerialIoPortBase[0]);
+ InsertConfigInteger(pCfg, "Serial0Irq", auSerialIrq[0]);
+
+ InsertConfigInteger(pCfg, "Serial1IoPortBase", auSerialIoPortBase[1]);
+ InsertConfigInteger(pCfg, "Serial1Irq", auSerialIrq[1]);
+
InsertConfigNode(pInst, "LUN#0", &pLunL0);
InsertConfigString(pLunL0, "Driver", "ACPIHost");
InsertConfigNode(pLunL0, "Config", &pCfg);
@@ -2434,6 +2612,8 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
#undef H
+ pAlock->release(); /* Avoid triggering the lock order inversion check. */
+
/*
* Register VM state change handler.
*/
@@ -2450,6 +2630,8 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
if (RT_SUCCESS(rc))
rc = rc2;
+ pAlock->acquire();
+
LogFlowFunc(("vrc = %Rrc\n", rc));
LogFlowFuncLeave();
@@ -2659,6 +2841,7 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
HRESULT *phrc,
bool fAttachDetach,
bool fForceUnmount,
+ bool fHotplug,
PVM pVM,
DeviceType_T *paLedDevType)
{
@@ -2678,10 +2861,11 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
hrc = pMediumAtt->COMGETTER(Port)(&lPort); H();
DeviceType_T lType;
hrc = pMediumAtt->COMGETTER(Type)(&lType); H();
+ BOOL fNonRotational;
+ hrc = pMediumAtt->COMGETTER(NonRotational)(&fNonRotational); H();
unsigned uLUN;
PCFGMNODE pLunL0 = NULL;
- PCFGMNODE pCfg = NULL;
hrc = Console::convertBusPortDeviceToLun(enmBus, lPort, lDev, uLUN); H();
/* First check if the LUN already exists. */
@@ -2716,7 +2900,7 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
}
}
- rc = PDMR3DeviceDetach(pVM, pcszDevice, 0, uLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG);
+ rc = PDMR3DeviceDetach(pVM, pcszDevice, uInstance, uLUN, fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG);
if (rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
rc = VINF_SUCCESS;
AssertRCReturn(rc, rc);
@@ -2729,11 +2913,42 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
InsertConfigNode(pCtlInst, Utf8StrFmt("LUN#%u", uLUN).c_str(), &pLunL0);
+ PCFGMNODE pCfg = CFGMR3GetChild(pCtlInst, "Config");
+ if (pCfg)
+ {
+ if (!strcmp(pcszDevice, "piix3ide"))
+ {
+ PCFGMNODE pDrive = CFGMR3GetChild(pCfg, g_apszIDEDrives[uLUN]);
+ if (!pDrive)
+ InsertConfigNode(pCfg, g_apszIDEDrives[uLUN], &pDrive);
+ /* Don't use the RemoveConfigValue wrapper above, as we don't
+ * know if the leaf is present or not. */
+ CFGMR3RemoveValue(pDrive, "NonRotationalMedium");
+ InsertConfigInteger(pDrive, "NonRotationalMedium", !!fNonRotational);
+ }
+ else if (!strcmp(pcszDevice, "ahci"))
+ {
+ Utf8Str strPort = Utf8StrFmt("Port%u", uLUN);
+ PCFGMNODE pDrive = CFGMR3GetChild(pCfg, strPort.c_str());
+ if (!pDrive)
+ InsertConfigNode(pCfg, strPort.c_str(), &pDrive);
+ /* Don't use the RemoveConfigValue wrapper above, as we don't
+ * know if the leaf is present or not. */
+ CFGMR3RemoveValue(pDrive, "NonRotationalMedium");
+ InsertConfigInteger(pDrive, "NonRotationalMedium", !!fNonRotational);
+ }
+ }
+ /** @todo add SCSI/SAS support once the SSD support is there */
+
+ Utf8Str devicePath = Utf8StrFmt("%s/%u/LUN#%u", pcszDevice, uInstance, uLUN);
+ mapMediumAttachments[devicePath] = pMediumAtt;
+
/* SCSI has a another driver between device and block. */
if (enmBus == StorageBus_SCSI || enmBus == StorageBus_SAS)
{
InsertConfigString(pLunL0, "Driver", "SCSI");
- InsertConfigNode(pLunL0, "Config", &pCfg);
+ PCFGMNODE pL1Cfg = NULL;
+ InsertConfigNode(pLunL0, "Config", &pL1Cfg);
InsertConfigNode(pLunL0, "AttachedDriver", &pLunL0);
}
@@ -2937,25 +3152,25 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
}
rc = configMedium(pLunL0,
- !!fPassthrough,
- lType,
- fUseHostIOCache,
- fBuiltinIoCache,
- fSetupMerge,
- uMergeSource,
- uMergeTarget,
- strBwGroup.isEmpty() ? NULL : Utf8Str(strBwGroup).c_str(),
- pMedium,
- aMachineState,
- phrc);
+ !!fPassthrough,
+ lType,
+ fUseHostIOCache,
+ fBuiltinIoCache,
+ fSetupMerge,
+ uMergeSource,
+ uMergeTarget,
+ strBwGroup.isEmpty() ? NULL : Utf8Str(strBwGroup).c_str(),
+ pMedium,
+ aMachineState,
+ phrc);
if (RT_FAILURE(rc))
return rc;
if (fAttachDetach)
{
/* Attach the new driver. */
- rc = PDMR3DeviceAttach(pVM, pcszDevice, 0, uLUN,
- PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/);
+ rc = PDMR3DeviceAttach(pVM, pcszDevice, uInstance, uLUN,
+ fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/);
AssertRCReturn(rc, rc);
/* There is no need to handle removable medium mounting, as we
@@ -3065,18 +3280,18 @@ int Console::configMedium(PCFGMNODE pLunL0,
// we failed on startup, but that's not good because the only way out then
// would be to discard the VM state...
MediumState_T mediumState;
- hrc = pMedium->RefreshState(&mediumState); H();
+ hrc = pMedium->RefreshState(&mediumState); H();
if (mediumState == MediumState_Inaccessible)
{
Bstr loc;
- hrc = pMedium->COMGETTER(Location)(loc.asOutParam()); H();
- setVMRuntimeErrorCallbackF(mpVM,
- this,
- 0,
- "DvdOrFloppyImageInaccessible",
- "The image file '%ls' is inaccessible and is being ignored. Please select a different image file for the virtual %s drive.",
- loc.raw(),
- (enmType == DeviceType_DVD) ? "DVD" : "floppy");
+ hrc = pMedium->COMGETTER(Location)(loc.asOutParam()); H();
+ setVMRuntimeErrorCallbackF(VMR3GetVM(mpUVM),
+ this,
+ 0,
+ "DvdOrFloppyImageInaccessible",
+ "The image file '%ls' is inaccessible and is being ignored. Please select a different image file for the virtual %s drive.",
+ loc.raw(),
+ enmType == DeviceType_DVD ? "DVD" : "floppy");
pMedium = NULL;
}
}
@@ -3179,9 +3394,9 @@ int Console::configMedium(PCFGMNODE pLunL0,
bool fHostIP = true;
SafeArray<BSTR> names;
SafeArray<BSTR> values;
- hrc = pMedium->GetProperties(NULL,
- ComSafeArrayAsOutParam(names),
- ComSafeArrayAsOutParam(values)); H();
+ hrc = pMedium->GetProperties(Bstr().raw(),
+ ComSafeArrayAsOutParam(names),
+ ComSafeArrayAsOutParam(values)); H();
if (names.size() != 0)
{
@@ -3231,7 +3446,7 @@ int Console::configMedium(PCFGMNODE pLunL0,
SafeArray<BSTR> aValues;
hrc = pMedium->GetProperties(NULL,
ComSafeArrayAsOutParam(aNames),
- ComSafeArrayAsOutParam(aValues)); H();
+ ComSafeArrayAsOutParam(aValues)); H();
if (aNames.size() != 0)
{
@@ -3292,7 +3507,8 @@ int Console::configMedium(PCFGMNODE pLunL0,
* True if connection failures should be ignored
* (makes only sense for bridged/host-only networks).
*
- * @note Locks this object for writing.
+ * @note Locks this object for writing.
+ * @thread EMT
*/
int Console::configNetwork(const char *pszDevice,
unsigned uInstance,
@@ -3323,28 +3539,31 @@ int Console::configNetwork(const char *pszDevice,
*/
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- PVM pVM = mpVM;
+ PVM pVM = VMR3GetVM(mpUVM); /* We're on an EMT, so this is safe. */
ComPtr<IMachine> pMachine = machine();
ComPtr<IVirtualBox> virtualBox;
- hrc = pMachine->COMGETTER(Parent)(virtualBox.asOutParam());
- H();
+ hrc = pMachine->COMGETTER(Parent)(virtualBox.asOutParam()); H();
ComPtr<IHost> host;
- hrc = virtualBox->COMGETTER(Host)(host.asOutParam());
- H();
+ hrc = virtualBox->COMGETTER(Host)(host.asOutParam()); H();
BOOL fSniffer;
- hrc = aNetworkAdapter->COMGETTER(TraceEnabled)(&fSniffer);
- H();
+ hrc = aNetworkAdapter->COMGETTER(TraceEnabled)(&fSniffer); H();
- hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/AllowPromiscousGuests").raw(), bstr.asOutParam());
- if (SUCCEEDED(hrc) && bstr.isEmpty())
- hrc = virtualBox->GetExtraData(Bstr("VBoxInternal2/AllowPromiscousGuests").raw(), bstr.asOutParam());
- H();
- const char * const pszPromiscuousGuestPolicy = bstr.isNotEmpty() ? "allow-all" : "deny";
+ NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
+ hrc = aNetworkAdapter->COMGETTER(PromiscModePolicy)(&enmPromiscModePolicy); H();
+ const char *pszPromiscuousGuestPolicy;
+ switch (enmPromiscModePolicy)
+ {
+ case NetworkAdapterPromiscModePolicy_Deny: pszPromiscuousGuestPolicy = "deny"; break;
+ case NetworkAdapterPromiscModePolicy_AllowNetwork: pszPromiscuousGuestPolicy = "allow-network"; break;
+ case NetworkAdapterPromiscModePolicy_AllowAll: pszPromiscuousGuestPolicy = "allow-all"; break;
+ default: AssertFailedReturn(VERR_INTERNAL_ERROR_4);
+ }
+ Utf8Str strNetDriver;
if (fAttachDetach && fSniffer)
{
const char *pszNetDriver = "IntNet";
@@ -3354,6 +3573,12 @@ int Console::configNetwork(const char *pszDevice,
if (meAttachmentType[uInstance] == NetworkAttachmentType_Bridged)
pszNetDriver = "HostInterface";
#endif
+ if (meAttachmentType[uInstance] == NetworkAttachmentType_Generic)
+ {
+ hrc = aNetworkAdapter->COMGETTER(GenericDriver)(bstr.asOutParam()); H();
+ strNetDriver = bstr;
+ pszNetDriver = strNetDriver.c_str();
+ }
rc = PDMR3DriverDetach(pVM, pszDevice, uInstance, uLun, pszNetDriver, 0, 0 /*fFlags*/);
if (rc == VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN)
@@ -3604,21 +3829,21 @@ int Console::configNetwork(const char *pszDevice,
InsertConfigNode(pInst, "LUN#0", &pLunL0);
}
- Bstr HifName;
- hrc = aNetworkAdapter->COMGETTER(HostInterface)(HifName.asOutParam());
+ Bstr BridgedIfName;
+ hrc = aNetworkAdapter->COMGETTER(BridgedInterface)(BridgedIfName.asOutParam());
if (FAILED(hrc))
{
- LogRel(("NetworkAttachmentType_Bridged: COMGETTER(HostInterface) failed, hrc (0x%x)", hrc));
+ LogRel(("NetworkAttachmentType_Bridged: COMGETTER(BridgedInterface) failed, hrc (0x%x)", hrc));
H();
}
- Utf8Str HifNameUtf8(HifName);
- const char *pszHifName = HifNameUtf8.c_str();
+ Utf8Str BridgedIfNameUtf8(BridgedIfName);
+ const char *pszBridgedIfName = BridgedIfNameUtf8.c_str();
# if defined(RT_OS_DARWIN)
/* The name is on the form 'ifX: long name', chop it off at the colon. */
char szTrunk[8];
- strncpy(szTrunk, pszHifName, sizeof(szTrunk));
+ RTStrCopy(szTrunk, sizeof(szTrunk), pszBridgedIfName);
char *pszColon = (char *)memchr(szTrunk, ':', sizeof(szTrunk));
// Quick fix for #5633
// if (!pszColon)
@@ -3628,11 +3853,11 @@ int Console::configNetwork(const char *pszDevice,
// * network with invalid host adapter (as it is must be changed before
// * the attachment), calling Detach here will cause a deadlock.
// * See #4750.
-// * hrc = aNetworkAdapter->Detach(); H();
+// * hrc = aNetworkAdapter->Detach(); H();
// */
// return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
// N_("Malformed host interface networking name '%ls'"),
-// HifName.raw());
+// BridgedIfName.raw());
// }
if (pszColon)
*pszColon = '\0';
@@ -3641,7 +3866,7 @@ int Console::configNetwork(const char *pszDevice,
# elif defined(RT_OS_SOLARIS)
/* The name is on the form format 'ifX[:1] - long name, chop it off at space. */
char szTrunk[256];
- strlcpy(szTrunk, pszHifName, sizeof(szTrunk));
+ strlcpy(szTrunk, pszBridgedIfName, sizeof(szTrunk));
char *pszSpace = (char *)memchr(szTrunk, ' ', sizeof(szTrunk));
/*
@@ -3661,14 +3886,14 @@ int Console::configNetwork(const char *pszDevice,
# elif defined(RT_OS_WINDOWS)
ComPtr<IHostNetworkInterface> hostInterface;
- hrc = host->FindHostNetworkInterfaceByName(HifName.raw(),
+ hrc = host->FindHostNetworkInterfaceByName(BridgedIfName.raw(),
hostInterface.asOutParam());
if (!SUCCEEDED(hrc))
{
AssertLogRelMsgFailed(("NetworkAttachmentType_Bridged: FindByName failed, rc=%Rhrc (0x%x)", hrc, hrc));
return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
N_("Nonexistent host networking interface, name '%ls'"),
- HifName.raw());
+ BridgedIfName.raw());
}
HostNetworkInterfaceType_T eIfType;
@@ -3683,7 +3908,7 @@ int Console::configNetwork(const char *pszDevice,
{
return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
N_("Interface ('%ls') is not a Bridged Adapter interface"),
- HifName.raw());
+ BridgedIfName.raw());
}
hrc = hostInterface->COMGETTER(Id)(bstr.asOutParam());
@@ -3694,14 +3919,11 @@ int Console::configNetwork(const char *pszDevice,
}
Guid hostIFGuid(bstr);
- INetCfg *pNc;
+ INetCfg *pNc;
ComPtr<INetCfgComponent> pAdaptorComponent;
- LPWSTR pszApp;
+ LPWSTR pszApp;
- hrc = VBoxNetCfgWinQueryINetCfg(FALSE /*fGetWriteLock*/,
- L"VirtualBox",
- &pNc,
- &pszApp);
+ hrc = VBoxNetCfgWinQueryINetCfg(&pNc, FALSE, L"VirtualBox", 10, &pszApp);
Assert(hrc == S_OK);
if (hrc != S_OK)
{
@@ -3774,7 +3996,7 @@ int Console::configNetwork(const char *pszDevice,
* This works and performs better than bridging a physical
* interface via the current FreeBSD vboxnetflt implementation.
*/
- if (!strncmp(pszHifName, "tap", sizeof "tap" - 1)) {
+ if (!strncmp(pszBridgedIfName, "tap", sizeof "tap" - 1)) {
hrc = attachToTapInterface(aNetworkAdapter);
if (FAILED(hrc))
{
@@ -3786,7 +4008,7 @@ int Console::configNetwork(const char *pszDevice,
"permissions of that node, and that the net.link.tap.user_open "
"sysctl is set. Either run 'chmod 0666 /dev/%s' or "
"change the group of that node to vboxusers and make yourself "
- "a member of that group. Make sure that these changes are permanent."), pszHifName, pszHifName);
+ "a member of that group. Make sure that these changes are permanent."), pszBridgedIfName, pszBridgedIfName);
default:
AssertMsgFailed(("Could not attach to tap interface! Bad!\n"));
return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
@@ -3805,7 +4027,7 @@ int Console::configNetwork(const char *pszDevice,
}
# endif
/** @todo Check for malformed names. */
- const char *pszTrunk = pszHifName;
+ const char *pszTrunk = pszBridgedIfName;
/* Issue a warning if the interface is down */
{
@@ -3813,14 +4035,13 @@ int Console::configNetwork(const char *pszDevice,
if (iSock >= 0)
{
struct ifreq Req;
-
- memset(&Req, 0, sizeof(Req));
- strncpy(Req.ifr_name, pszHifName, sizeof(Req.ifr_name) - 1);
+ RT_ZERO(Req);
+ strncpy(Req.ifr_name, pszBridgedIfName, sizeof(Req.ifr_name) - 1);
if (ioctl(iSock, SIOCGIFFLAGS, &Req) >= 0)
if ((Req.ifr_flags & IFF_UP) == 0)
- {
- setVMRuntimeErrorCallbackF(pVM, this, 0, "BridgedInterfaceDown", "Bridged interface %s is down. Guest will not be able to use this interface", pszHifName);
- }
+ setVMRuntimeErrorCallbackF(pVM, this, 0, "BridgedInterfaceDown",
+ "Bridged interface %s is down. Guest will not be able to use this interface",
+ pszBridgedIfName);
close(iSock);
}
@@ -3837,7 +4058,7 @@ int Console::configNetwork(const char *pszDevice,
InsertConfigInteger(pCfg, "IgnoreConnectFailure", (uint64_t)fIgnoreConnectFailure);
InsertConfigString(pCfg, "IfPolicyPromisc", pszPromiscuousGuestPolicy);
char szNetwork[INTNET_MAX_NETWORK_NAME];
- RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHifName);
+ RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszBridgedIfName);
InsertConfigString(pCfg, "Network", szNetwork);
networkName = Bstr(szNetwork);
trunkName = Bstr(pszTrunk);
@@ -3845,8 +4066,8 @@ int Console::configNetwork(const char *pszDevice,
# if defined(RT_OS_DARWIN)
/** @todo Come up with a better deal here. Problem is that IHostNetworkInterface is completely useless here. */
- if ( strstr(pszHifName, "Wireless")
- || strstr(pszHifName, "AirPort" ))
+ if ( strstr(pszBridgedIfName, "Wireless")
+ || strstr(pszBridgedIfName, "AirPort" ))
InsertConfigInteger(pCfg, "SharedMacOnWire", true);
# elif defined(RT_OS_LINUX)
int iSock = socket(AF_INET, SOCK_DGRAM, 0);
@@ -3855,7 +4076,7 @@ int Console::configNetwork(const char *pszDevice,
struct iwreq WRq;
memset(&WRq, 0, sizeof(WRq));
- strncpy(WRq.ifr_name, pszHifName, IFNAMSIZ);
+ strncpy(WRq.ifr_name, pszBridgedIfName, IFNAMSIZ);
bool fSharedMacOnWire = ioctl(iSock, SIOCGIWNAME, &WRq) >= 0;
close(iSock);
if (fSharedMacOnWire)
@@ -3876,7 +4097,7 @@ int Console::configNetwork(const char *pszDevice,
uint8_t abData[32];
memset(&WReq, 0, sizeof(WReq));
- strncpy(WReq.i_name, pszHifName, sizeof(WReq.i_name));
+ strncpy(WReq.i_name, pszBridgedIfName, sizeof(WReq.i_name));
WReq.i_type = IEEE80211_IOC_SSID;
WReq.i_val = -1;
WReq.i_data = abData;
@@ -4024,29 +4245,29 @@ int Console::configNetwork(const char *pszDevice,
InsertConfigString(pLunL0, "Driver", "IntNet");
InsertConfigNode(pLunL0, "Config", &pCfg);
- Bstr HifName;
- hrc = aNetworkAdapter->COMGETTER(HostInterface)(HifName.asOutParam());
+ Bstr HostOnlyName;
+ hrc = aNetworkAdapter->COMGETTER(HostOnlyInterface)(HostOnlyName.asOutParam());
if (FAILED(hrc))
{
- LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostInterface) failed, hrc (0x%x)\n", hrc));
+ LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostOnlyInterface) failed, hrc (0x%x)\n", hrc));
H();
}
- Utf8Str HifNameUtf8(HifName);
- const char *pszHifName = HifNameUtf8.c_str();
+ Utf8Str HostOnlyNameUtf8(HostOnlyName);
+ const char *pszHostOnlyName = HostOnlyNameUtf8.c_str();
ComPtr<IHostNetworkInterface> hostInterface;
- rc = host->FindHostNetworkInterfaceByName(HifName.raw(),
+ rc = host->FindHostNetworkInterfaceByName(HostOnlyName.raw(),
hostInterface.asOutParam());
if (!SUCCEEDED(rc))
{
LogRel(("NetworkAttachmentType_HostOnly: FindByName failed, rc (0x%x)\n", rc));
return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
N_("Nonexistent host networking interface, name '%ls'"),
- HifName.raw());
+ HostOnlyName.raw());
}
char szNetwork[INTNET_MAX_NETWORK_NAME];
- RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHifName);
+ RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHostOnlyName);
#if defined(RT_OS_WINDOWS)
# ifndef VBOX_WITH_NETFLT
@@ -4067,7 +4288,7 @@ int Console::configNetwork(const char *pszDevice,
if (eIfType != HostNetworkInterfaceType_HostOnly)
return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
N_("Interface ('%ls') is not a Host-Only Adapter interface"),
- HifName.raw());
+ HostOnlyName.raw());
hrc = hostInterface->COMGETTER(Id)(bstr.asOutParam());
if (FAILED(hrc))
@@ -4080,11 +4301,7 @@ int Console::configNetwork(const char *pszDevice,
INetCfg *pNc;
ComPtr<INetCfgComponent> pAdaptorComponent;
LPWSTR pszApp;
-
- hrc = VBoxNetCfgWinQueryINetCfg(FALSE,
- L"VirtualBox",
- &pNc,
- &pszApp);
+ hrc = VBoxNetCfgWinQueryINetCfg(&pNc, FALSE, L"VirtualBox", 10, &pszApp);
Assert(hrc == S_OK);
if (hrc != S_OK)
{
@@ -4162,18 +4379,18 @@ int Console::configNetwork(const char *pszDevice,
trunkType = TRUNKTYPE_NETADP;
# endif /* defined VBOX_WITH_NETFLT*/
#elif defined(RT_OS_DARWIN)
- InsertConfigString(pCfg, "Trunk", pszHifName);
+ InsertConfigString(pCfg, "Trunk", pszHostOnlyName);
InsertConfigString(pCfg, "Network", szNetwork);
InsertConfigInteger(pCfg, "TrunkType", kIntNetTrunkType_NetAdp);
networkName = Bstr(szNetwork);
- trunkName = Bstr(pszHifName);
+ trunkName = Bstr(pszHostOnlyName);
trunkType = TRUNKTYPE_NETADP;
#else
- InsertConfigString(pCfg, "Trunk", pszHifName);
+ InsertConfigString(pCfg, "Trunk", pszHostOnlyName);
InsertConfigString(pCfg, "Network", szNetwork);
InsertConfigInteger(pCfg, "TrunkType", kIntNetTrunkType_NetFlt);
networkName = Bstr(szNetwork);
- trunkName = Bstr(pszHifName);
+ trunkName = Bstr(pszHostOnlyName);
trunkType = TRUNKTYPE_NETFLT;
#endif
InsertConfigString(pCfg, "IfPolicyPromisc", pszPromiscuousGuestPolicy);
@@ -4183,12 +4400,12 @@ int Console::configNetwork(const char *pszDevice,
Bstr tmpAddr, tmpMask;
hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPAddress",
- pszHifName).raw(),
+ pszHostOnlyName).raw(),
tmpAddr.asOutParam());
if (SUCCEEDED(hrc) && !tmpAddr.isEmpty())
{
hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPNetMask",
- pszHifName).raw(),
+ pszHostOnlyName).raw(),
tmpMask.asOutParam());
if (SUCCEEDED(hrc) && !tmpMask.isEmpty())
hrc = hostInterface->EnableStaticIpConfig(tmpAddr.raw(),
@@ -4200,17 +4417,17 @@ int Console::configNetwork(const char *pszDevice,
else
{
/* Grab the IP number from the 'vboxnetX' instance number (see netif.h) */
- hrc = hostInterface->EnableStaticIpConfig(getDefaultIPv4Address(Bstr(pszHifName)).raw(),
+ hrc = hostInterface->EnableStaticIpConfig(getDefaultIPv4Address(Bstr(pszHostOnlyName)).raw(),
Bstr(VBOXNET_IPV4MASK_DEFAULT).raw());
}
ComAssertComRC(hrc); /** @todo r=bird: Why this isn't fatal? (H()) */
hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6Address",
- pszHifName).raw(),
+ pszHostOnlyName).raw(),
tmpAddr.asOutParam());
if (SUCCEEDED(hrc))
- hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6NetMask", pszHifName).raw(),
+ hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6NetMask", pszHostOnlyName).raw(),
tmpMask.asOutParam());
if (SUCCEEDED(hrc) && !tmpAddr.isEmpty() && !tmpMask.isEmpty())
{
@@ -4222,21 +4439,32 @@ int Console::configNetwork(const char *pszDevice,
break;
}
-#if defined(VBOX_WITH_VDE)
- case NetworkAttachmentType_VDE:
+ case NetworkAttachmentType_Generic:
{
- hrc = aNetworkAdapter->COMGETTER(VDENetwork)(bstr.asOutParam()); H();
- InsertConfigNode(pInst, "LUN#0", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "VDE");
+ hrc = aNetworkAdapter->COMGETTER(GenericDriver)(bstr.asOutParam()); H();
+ SafeArray<BSTR> names;
+ SafeArray<BSTR> values;
+ hrc = aNetworkAdapter->GetProperties(Bstr().raw(),
+ ComSafeArrayAsOutParam(names),
+ ComSafeArrayAsOutParam(values)); H();
+
+ if (fSniffer)
+ InsertConfigNode(pLunL0, "AttachedDriver", &pLunL0);
+ else
+ InsertConfigNode(pInst, "LUN#0", &pLunL0);
+ InsertConfigString(pLunL0, "Driver", bstr);
InsertConfigNode(pLunL0, "Config", &pCfg);
- if (!bstr.isEmpty())
+ for (size_t ii = 0; ii < names.size(); ++ii)
{
- InsertConfigString(pCfg, "Network", bstr);
- networkName = bstr;
+ if (values[ii] && *values[ii])
+ {
+ Utf8Str name = names[ii];
+ Utf8Str value = values[ii];
+ InsertConfigString(pCfg, name.c_str(), value);
+ }
}
break;
}
-#endif
default:
AssertMsgFailed(("should not get here!\n"));
@@ -4255,9 +4483,7 @@ int Console::configNetwork(const char *pszDevice,
case NetworkAttachmentType_Internal:
case NetworkAttachmentType_HostOnly:
case NetworkAttachmentType_NAT:
-#if defined(VBOX_WITH_VDE)
- case NetworkAttachmentType_VDE:
-#endif
+ case NetworkAttachmentType_Generic:
{
if (SUCCEEDED(hrc) && SUCCEEDED(rc))
{
@@ -4580,7 +4806,7 @@ int configSetGlobalPropertyFlags(VMMDev * const pVMMDev,
{
HGCMSVCEXTHANDLE hDummy;
rc = HGCMHostRegisterServiceExtension(&hDummy, "VBoxGuestControlSvc",
- &Guest::doGuestCtrlNotification,
+ &Guest::notifyCtrlDispatcher,
pConsole->getGuest());
if (RT_FAILURE(rc))
Log(("Cannot register VBoxGuestControlSvc extension!\n"));
diff --git a/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp b/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp
index cd28a4eb0..80fb44734 100644
--- a/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp
+++ b/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp
@@ -1,4 +1,4 @@
-/* $Id: ConsoleImplTeleporter.cpp $ */
+/* $Id: ConsoleImplTeleporter.cpp 36041 2011-02-21 16:04:53Z vboxsync $ */
/** @file
* VBox Console COM Class implementation, The Teleporter Part.
*/
@@ -53,7 +53,7 @@ class TeleporterState
{
public:
ComPtr<Console> mptrConsole;
- PVM mpVM;
+ PUVM mpUVM;
ComObjPtr<Progress> mptrProgress;
Utf8Str mstrPassword;
bool const mfIsSource;
@@ -68,9 +68,9 @@ public:
bool volatile mfIOError;
/** @} */
- TeleporterState(Console *pConsole, PVM pVM, Progress *pProgress, bool fIsSource)
+ TeleporterState(Console *pConsole, PUVM pUVM, Progress *pProgress, bool fIsSource)
: mptrConsole(pConsole)
- , mpVM(pVM)
+ , mpUVM(pUVM)
, mptrProgress(pProgress)
, mfIsSource(fIsSource)
, mhSocket(NIL_RTSOCKET)
@@ -80,6 +80,13 @@ public:
, mfEndOfStream(false)
, mfIOError(false)
{
+ VMR3RetainUVM(mpUVM);
+ }
+
+ ~TeleporterState()
+ {
+ VMR3ReleaseUVM(mpUVM);
+ mpUVM = NULL;
}
};
@@ -97,8 +104,8 @@ public:
bool mfSuspendedByUs;
bool mfUnlockedMedia;
- TeleporterStateSrc(Console *pConsole, PVM pVM, Progress *pProgress, MachineState_T enmOldMachineState)
- : TeleporterState(pConsole, pVM, pProgress, true /*fIsSource*/)
+ TeleporterStateSrc(Console *pConsole, PUVM pUVM, Progress *pProgress, MachineState_T enmOldMachineState)
+ : TeleporterState(pConsole, pUVM, pProgress, true /*fIsSource*/)
, muPort(UINT32_MAX)
, mcMsMaxDowntime(250)
, menmOldMachineState(enmOldMachineState)
@@ -123,10 +130,10 @@ public:
int mRc;
Utf8Str mErrorText;
- TeleporterStateTrg(Console *pConsole, PVM pVM, Progress *pProgress,
+ TeleporterStateTrg(Console *pConsole, PUVM pUVM, Progress *pProgress,
IMachine *pMachine, IInternalMachineControl *pControl,
PRTTIMERLR phTimerLR, bool fStartPaused)
- : TeleporterState(pConsole, pVM, pProgress, false /*fIsSource*/)
+ : TeleporterState(pConsole, pUVM, pProgress, false /*fIsSource*/)
, mpMachine(pMachine)
, mpControl(pControl)
, mhServer(NULL)
@@ -565,7 +572,7 @@ static SSMSTRMOPS const g_teleporterTcpOps =
static void teleporterProgressCancelCallback(void *pvUser)
{
TeleporterState *pState = (TeleporterState *)pvUser;
- SSMR3Cancel(pState->mpVM);
+ SSMR3Cancel(VMR3GetVM(pState->mpUVM));
if (!pState->mfIsSource)
{
TeleporterStateTrg *pStateTrg = (TeleporterStateTrg *)pState;
@@ -589,7 +596,7 @@ static DECLCALLBACK(int) teleporterProgressCallback(PVM pVM, unsigned uPercent,
hrc = pState->mptrProgress->COMGETTER(Canceled)(&fCanceled);
if (SUCCEEDED(hrc) && fCanceled)
{
- SSMR3Cancel(pState->mpVM);
+ SSMR3Cancel(VMR3GetVM(pState->mpUVM));
return VERR_SSM_CANCELLED;
}
}
@@ -677,9 +684,10 @@ Console::teleporterSrc(TeleporterStateSrc *pState)
RTSocketRetain(pState->mhSocket);
void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState));
- vrc = VMR3Teleport(pState->mpVM, pState->mcMsMaxDowntime,
- &g_teleporterTcpOps, pvUser,
- teleporterProgressCallback, pvUser,
+ vrc = VMR3Teleport(VMR3GetVM(pState->mpUVM),
+ pState->mcMsMaxDowntime,
+ &g_teleporterTcpOps, pvUser,
+ teleporterProgressCallback, pvUser,
&pState->mfSuspendedByUs);
RTSocketRelease(pState->mhSocket);
if (RT_FAILURE(vrc))
@@ -757,8 +765,8 @@ Console::teleporterSrcThreadWrapper(RTTHREAD hThread, void *pvUser)
* Console::teleporterSrc does the work, we just grab onto the VM handle
* and do the cleanups afterwards.
*/
- AutoVMCaller autoVMCaller(pState->mptrConsole);
- HRESULT hrc = autoVMCaller.rc();
+ SafeVMPtr ptrVM(pState->mptrConsole);
+ HRESULT hrc = ptrVM.rc();
if (SUCCEEDED(hrc))
hrc = pState->mptrConsole->teleporterSrc(pState);
@@ -785,7 +793,7 @@ Console::teleporterSrcThreadWrapper(RTTHREAD hThread, void *pvUser)
AutoWriteLock autoLock(pState->mptrConsole COMMA_LOCKVAL_SRC_POS);
pState->mptrConsole->mptrCancelableProgress.setNull();
- VMSTATE const enmVMState = VMR3GetState(pState->mpVM);
+ VMSTATE const enmVMState = VMR3GetStateU(pState->mpUVM);
MachineState_T const enmMachineState = pState->mptrConsole->mMachineState;
if (SUCCEEDED(hrc))
{
@@ -798,7 +806,7 @@ Console::teleporterSrcThreadWrapper(RTTHREAD hThread, void *pvUser)
AssertLogRelMsg(enmVMState == VMSTATE_SUSPENDED, ("%s\n", VMR3GetStateName(enmVMState)));
AssertLogRelMsg(enmMachineState == MachineState_TeleportingPausedVM, ("%s\n", Global::stringifyMachineState(enmMachineState)));
- autoVMCaller.release();
+ ptrVM.release();
pState->mptrConsole->mVMIsAlreadyPoweringOff = true; /* (Make sure we stick in the TeleportingPausedVM state.) */
hrc = pState->mptrConsole->powerDown();
@@ -877,7 +885,7 @@ Console::teleporterSrcThreadWrapper(RTTHREAD hThread, void *pvUser)
if (pState->mfSuspendedByUs)
{
autoLock.leave();
- int rc = VMR3Resume(pState->mpVM);
+ int rc = VMR3Resume(VMR3GetVM(pState->mpUVM));
AssertLogRelMsgRC(rc, ("VMR3Resume -> %Rrc\n", rc));
autoLock.enter();
}
@@ -954,13 +962,14 @@ Console::Teleport(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, ULONG aMaxD
ComObjPtr<Progress> ptrProgress;
HRESULT hrc = ptrProgress.createObject();
- if (FAILED(hrc)) return hrc;
- hrc = ptrProgress->init(static_cast<IConsole *>(this),
- Bstr(tr("Teleporter")).raw(),
- TRUE /*aCancelable*/);
- if (FAILED(hrc)) return hrc;
+ if (SUCCEEDED(hrc))
+ hrc = ptrProgress->init(static_cast<IConsole *>(this),
+ Bstr(tr("Teleporter")).raw(),
+ TRUE /*aCancelable*/);
+ if (FAILED(hrc))
+ return hrc;
- TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpVM, ptrProgress, mMachineState);
+ TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpUVM, ptrProgress, mMachineState);
pState->mstrPassword = aPassword;
pState->mstrHostname = aHostname;
pState->muPort = aPort;
@@ -1001,7 +1010,7 @@ Console::Teleport(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, ULONG aMaxD
* over to Console::teleporterTrgServeConnection().
*
* @returns VBox status code.
- * @param pVM The VM handle
+ * @param pUVM The user-mode VM handle
* @param pMachine The IMachine for the virtual machine.
* @param pErrorMsg Pointer to the error string for VMSetError.
* @param fStartPaused Whether to start it in the Paused (true) or
@@ -1014,10 +1023,10 @@ Console::Teleport(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, ULONG aMaxD
* @todo Check that all the possible failure paths sets error info...
*/
HRESULT
-Console::teleporterTrg(PVM pVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fStartPaused,
+Console::teleporterTrg(PUVM pUVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fStartPaused,
Progress *pProgress, bool *pfPowerOffOnFailure)
{
- LogThisFunc(("pVM=%p pMachine=%p fStartPaused=%RTbool pProgress=%p\n", pVM, pMachine, fStartPaused, pProgress));
+ LogThisFunc(("pUVM=%p pMachine=%p fStartPaused=%RTbool pProgress=%p\n", pUVM, pMachine, fStartPaused, pProgress));
*pfPowerOffOnFailure = true;
@@ -1086,7 +1095,7 @@ Console::teleporterTrg(PVM pVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fSt
/*
* Do the job, when it returns we're done.
*/
- TeleporterStateTrg theState(this, pVM, pProgress, pMachine, mControl, &hTimerLR, fStartPaused);
+ TeleporterStateTrg theState(this, pUVM, pProgress, pMachine, mControl, &hTimerLR, fStartPaused);
theState.mstrPassword = strPassword;
theState.mhServer = hServer;
@@ -1110,7 +1119,7 @@ Console::teleporterTrg(PVM pVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fSt
hrc = S_OK;
else
{
- VMSTATE enmVMState = VMR3GetState(pVM);
+ VMSTATE enmVMState = VMR3GetStateU(pUVM);
if ( enmVMState != VMSTATE_OFF
&& enmVMState != VMSTATE_POWERING_OFF)
*pfPowerOffOnFailure = true;
@@ -1319,16 +1328,18 @@ Console::teleporterTrgServeConnection(RTSOCKET Sock, void *pvUser)
if (RT_FAILURE(vrc))
break;
- int vrc2 = VMR3AtErrorRegister(pState->mpVM, Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
+ int vrc2 = VMR3AtErrorRegisterU(pState->mpUVM,
+ Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
RTSocketRetain(pState->mhSocket); /* For concurrent access by I/O thread and EMT. */
pState->moffStream = 0;
void *pvUser2 = static_cast<void *>(static_cast<TeleporterState *>(pState));
- vrc = VMR3LoadFromStream(pState->mpVM, &g_teleporterTcpOps, pvUser2,
+ vrc = VMR3LoadFromStream(VMR3GetVM(pState->mpUVM),
+ &g_teleporterTcpOps, pvUser2,
teleporterProgressCallback, pvUser2);
RTSocketRelease(pState->mhSocket);
- vrc2 = VMR3AtErrorDeregister(pState->mpVM, Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
+ vrc2 = VMR3AtErrorDeregister(VMR3GetVM(pState->mpUVM), Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
if (RT_FAILURE(vrc))
{
@@ -1391,7 +1402,7 @@ Console::teleporterTrgServeConnection(RTSOCKET Sock, void *pvUser)
if (RT_SUCCESS(vrc))
{
if (!strcmp(szCmd, "hand-over-resume"))
- vrc = VMR3Resume(pState->mpVM);
+ vrc = VMR3Resume(VMR3GetVM(pState->mpUVM));
else
pState->mptrConsole->setMachineState(MachineState_Paused);
fDone = true;
diff --git a/src/VBox/Main/src-client/ConsoleVRDPServer.cpp b/src/VBox/Main/src-client/ConsoleVRDPServer.cpp
index 19c845f1c..9b0b652c9 100644
--- a/src/VBox/Main/src-client/ConsoleVRDPServer.cpp
+++ b/src/VBox/Main/src-client/ConsoleVRDPServer.cpp
@@ -1,4 +1,4 @@
-/* $Id: ConsoleVRDPServer.cpp $ */
+/* $Id: ConsoleVRDPServer.cpp 37809 2011-07-07 08:15:02Z vboxsync $ */
/** @file
* VBox Console VRDP Helper class
*/
@@ -24,6 +24,7 @@
#ifdef VBOX_WITH_EXTPACK
# include "ExtPackManagerImpl.h"
#endif
+#include "VMMDev.h"
#include "Global.h"
#include "AutoCaller.h"
@@ -39,12 +40,22 @@
#include <VBox/err.h>
#include <VBox/RemoteDesktop/VRDEOrders.h>
#include <VBox/com/listeners.h>
+#include <VBox/HostServices/VBoxCrOpenGLSvc.h>
class VRDPConsoleListener
{
public:
- VRDPConsoleListener(ConsoleVRDPServer *server)
- : m_server(server)
+ VRDPConsoleListener()
+ {
+ }
+
+ HRESULT init(ConsoleVRDPServer *server)
+ {
+ m_server = server;
+ return S_OK;
+ }
+
+ void uninit()
{
}
@@ -510,12 +521,12 @@ RTLDRMOD ConsoleVRDPServer::mVRDPLibrary = NIL_RTLDRMOD;
PFNVRDECREATESERVER ConsoleVRDPServer::mpfnVRDECreateServer = NULL;
-VRDEENTRYPOINTS_3 ConsoleVRDPServer::mEntryPoints; /* A copy of the server entry points. */
-VRDEENTRYPOINTS_3 *ConsoleVRDPServer::mpEntryPoints = NULL;
+VRDEENTRYPOINTS_4 ConsoleVRDPServer::mEntryPoints; /* A copy of the server entry points. */
+VRDEENTRYPOINTS_4 *ConsoleVRDPServer::mpEntryPoints = NULL;
-VRDECALLBACKS_3 ConsoleVRDPServer::mCallbacks =
+VRDECALLBACKS_4 ConsoleVRDPServer::mCallbacks =
{
- { VRDE_INTERFACE_VERSION_3, sizeof(VRDECALLBACKS_3) },
+ { VRDE_INTERFACE_VERSION_4, sizeof(VRDECALLBACKS_4) },
ConsoleVRDPServer::VRDPCallbackQueryProperty,
ConsoleVRDPServer::VRDPCallbackClientLogon,
ConsoleVRDPServer::VRDPCallbackClientConnect,
@@ -1289,7 +1300,10 @@ ConsoleVRDPServer::ConsoleVRDPServer(Console *console)
{
ComPtr<IEventSource> es;
console->COMGETTER(EventSource)(es.asOutParam());
- mConsoleListener = new VRDPConsoleListenerImpl(this);
+ ComObjPtr<VRDPConsoleListenerImpl> aConsoleListener;
+ aConsoleListener.createObject();
+ aConsoleListener->init(new VRDPConsoleListener(), this);
+ mConsoleListener = aConsoleListener;
com::SafeArray <VBoxEventType_T> eventTypes;
eventTypes.push_back(VBoxEventType_OnMousePointerShapeChanged);
eventTypes.push_back(VBoxEventType_OnMouseCapabilityChanged);
@@ -1302,6 +1316,13 @@ ConsoleVRDPServer::ConsoleVRDPServer(Console *console)
mAuthLibrary = 0;
mu32AudioInputClientId = 0;
+
+ /*
+ * Optional interfaces.
+ */
+ m_fInterfaceImage = false;
+ memset(&m_interfaceImage, 0, sizeof (m_interfaceImage));
+ memset(&m_interfaceCallbacksImage, 0, sizeof (m_interfaceCallbacksImage));
}
ConsoleVRDPServer::~ConsoleVRDPServer()
@@ -1313,8 +1334,7 @@ ConsoleVRDPServer::~ConsoleVRDPServer()
ComPtr<IEventSource> es;
mConsole->COMGETTER(EventSource)(es.asOutParam());
es->UnregisterListener(mConsoleListener);
- mConsoleListener->Release();
- mConsoleListener = NULL;
+ mConsoleListener.setNull();
}
unsigned i;
@@ -1383,23 +1403,23 @@ int ConsoleVRDPServer::Launch(void)
vrc = loadVRDPLibrary(strVrdeLibrary.c_str());
if (RT_SUCCESS(vrc))
{
- VRDEENTRYPOINTS_3 *pEntryPoints3;
- vrc = mpfnVRDECreateServer(&mCallbacks.header, this, (VRDEINTERFACEHDR **)&pEntryPoints3, &mhServer);
+ VRDEENTRYPOINTS_4 *pEntryPoints4;
+ vrc = mpfnVRDECreateServer(&mCallbacks.header, this, (VRDEINTERFACEHDR **)&pEntryPoints4, &mhServer);
if (RT_SUCCESS(vrc))
{
- mServerInterfaceVersion = 3;
- mEntryPoints = *pEntryPoints3;
+ mServerInterfaceVersion = 4;
+ mEntryPoints = *pEntryPoints4;
mpEntryPoints = &mEntryPoints;
}
else if (vrc == VERR_VERSION_MISMATCH)
{
- /* An older version of VRDE is installed, try version 1. */
- VRDEENTRYPOINTS_1 *pEntryPoints1;
+ /* An older version of VRDE is installed, try version 3. */
+ VRDEENTRYPOINTS_3 *pEntryPoints3;
- static VRDECALLBACKS_1 sCallbacks =
+ static VRDECALLBACKS_3 sCallbacks3 =
{
- { VRDE_INTERFACE_VERSION_1, sizeof(VRDECALLBACKS_1) },
+ { VRDE_INTERFACE_VERSION_3, sizeof(VRDECALLBACKS_3) },
ConsoleVRDPServer::VRDPCallbackQueryProperty,
ConsoleVRDPServer::VRDPCallbackClientLogon,
ConsoleVRDPServer::VRDPCallbackClientConnect,
@@ -1411,37 +1431,111 @@ int ConsoleVRDPServer::Launch(void)
ConsoleVRDPServer::VRDPCallbackFramebufferLock,
ConsoleVRDPServer::VRDPCallbackFramebufferUnlock,
ConsoleVRDPServer::VRDPCallbackInput,
- ConsoleVRDPServer::VRDPCallbackVideoModeHint
+ ConsoleVRDPServer::VRDPCallbackVideoModeHint,
+ ConsoleVRDPServer::VRDECallbackAudioIn
};
- vrc = mpfnVRDECreateServer(&sCallbacks.header, this, (VRDEINTERFACEHDR **)&pEntryPoints1, &mhServer);
+ vrc = mpfnVRDECreateServer(&sCallbacks3.header, this, (VRDEINTERFACEHDR **)&pEntryPoints3, &mhServer);
if (RT_SUCCESS(vrc))
{
- LogRel(("VRDE: loaded an older version of the server.\n"));
-
mServerInterfaceVersion = 3;
- mEntryPoints.header = pEntryPoints1->header;
- mEntryPoints.VRDEDestroy = pEntryPoints1->VRDEDestroy;
- mEntryPoints.VRDEEnableConnections = pEntryPoints1->VRDEEnableConnections;
- mEntryPoints.VRDEDisconnect = pEntryPoints1->VRDEDisconnect;
- mEntryPoints.VRDEResize = pEntryPoints1->VRDEResize;
- mEntryPoints.VRDEUpdate = pEntryPoints1->VRDEUpdate;
- mEntryPoints.VRDEColorPointer = pEntryPoints1->VRDEColorPointer;
- mEntryPoints.VRDEHidePointer = pEntryPoints1->VRDEHidePointer;
- mEntryPoints.VRDEAudioSamples = pEntryPoints1->VRDEAudioSamples;
- mEntryPoints.VRDEAudioVolume = pEntryPoints1->VRDEAudioVolume;
- mEntryPoints.VRDEUSBRequest = pEntryPoints1->VRDEUSBRequest;
- mEntryPoints.VRDEClipboard = pEntryPoints1->VRDEClipboard;
- mEntryPoints.VRDEQueryInfo = pEntryPoints1->VRDEQueryInfo;
- mEntryPoints.VRDERedirect = NULL;
- mEntryPoints.VRDEAudioInOpen = NULL;
- mEntryPoints.VRDEAudioInClose = NULL;
+ mEntryPoints.header = pEntryPoints3->header;
+ mEntryPoints.VRDEDestroy = pEntryPoints3->VRDEDestroy;
+ mEntryPoints.VRDEEnableConnections = pEntryPoints3->VRDEEnableConnections;
+ mEntryPoints.VRDEDisconnect = pEntryPoints3->VRDEDisconnect;
+ mEntryPoints.VRDEResize = pEntryPoints3->VRDEResize;
+ mEntryPoints.VRDEUpdate = pEntryPoints3->VRDEUpdate;
+ mEntryPoints.VRDEColorPointer = pEntryPoints3->VRDEColorPointer;
+ mEntryPoints.VRDEHidePointer = pEntryPoints3->VRDEHidePointer;
+ mEntryPoints.VRDEAudioSamples = pEntryPoints3->VRDEAudioSamples;
+ mEntryPoints.VRDEAudioVolume = pEntryPoints3->VRDEAudioVolume;
+ mEntryPoints.VRDEUSBRequest = pEntryPoints3->VRDEUSBRequest;
+ mEntryPoints.VRDEClipboard = pEntryPoints3->VRDEClipboard;
+ mEntryPoints.VRDEQueryInfo = pEntryPoints3->VRDEQueryInfo;
+ mEntryPoints.VRDERedirect = pEntryPoints3->VRDERedirect;
+ mEntryPoints.VRDEAudioInOpen = pEntryPoints3->VRDEAudioInOpen;
+ mEntryPoints.VRDEAudioInClose = pEntryPoints3->VRDEAudioInClose;
+ mEntryPoints.VRDEGetInterface = NULL;
mpEntryPoints = &mEntryPoints;
}
+ else if (vrc == VERR_VERSION_MISMATCH)
+ {
+ /* An older version of VRDE is installed, try version 1. */
+ VRDEENTRYPOINTS_1 *pEntryPoints1;
+
+ static VRDECALLBACKS_1 sCallbacks1 =
+ {
+ { VRDE_INTERFACE_VERSION_1, sizeof(VRDECALLBACKS_1) },
+ ConsoleVRDPServer::VRDPCallbackQueryProperty,
+ ConsoleVRDPServer::VRDPCallbackClientLogon,
+ ConsoleVRDPServer::VRDPCallbackClientConnect,
+ ConsoleVRDPServer::VRDPCallbackClientDisconnect,
+ ConsoleVRDPServer::VRDPCallbackIntercept,
+ ConsoleVRDPServer::VRDPCallbackUSB,
+ ConsoleVRDPServer::VRDPCallbackClipboard,
+ ConsoleVRDPServer::VRDPCallbackFramebufferQuery,
+ ConsoleVRDPServer::VRDPCallbackFramebufferLock,
+ ConsoleVRDPServer::VRDPCallbackFramebufferUnlock,
+ ConsoleVRDPServer::VRDPCallbackInput,
+ ConsoleVRDPServer::VRDPCallbackVideoModeHint
+ };
+
+ vrc = mpfnVRDECreateServer(&sCallbacks1.header, this, (VRDEINTERFACEHDR **)&pEntryPoints1, &mhServer);
+ if (RT_SUCCESS(vrc))
+ {
+ mServerInterfaceVersion = 1;
+ mEntryPoints.header = pEntryPoints1->header;
+ mEntryPoints.VRDEDestroy = pEntryPoints1->VRDEDestroy;
+ mEntryPoints.VRDEEnableConnections = pEntryPoints1->VRDEEnableConnections;
+ mEntryPoints.VRDEDisconnect = pEntryPoints1->VRDEDisconnect;
+ mEntryPoints.VRDEResize = pEntryPoints1->VRDEResize;
+ mEntryPoints.VRDEUpdate = pEntryPoints1->VRDEUpdate;
+ mEntryPoints.VRDEColorPointer = pEntryPoints1->VRDEColorPointer;
+ mEntryPoints.VRDEHidePointer = pEntryPoints1->VRDEHidePointer;
+ mEntryPoints.VRDEAudioSamples = pEntryPoints1->VRDEAudioSamples;
+ mEntryPoints.VRDEAudioVolume = pEntryPoints1->VRDEAudioVolume;
+ mEntryPoints.VRDEUSBRequest = pEntryPoints1->VRDEUSBRequest;
+ mEntryPoints.VRDEClipboard = pEntryPoints1->VRDEClipboard;
+ mEntryPoints.VRDEQueryInfo = pEntryPoints1->VRDEQueryInfo;
+ mEntryPoints.VRDERedirect = NULL;
+ mEntryPoints.VRDEAudioInOpen = NULL;
+ mEntryPoints.VRDEAudioInClose = NULL;
+ mEntryPoints.VRDEGetInterface = NULL;
+ mpEntryPoints = &mEntryPoints;
+ }
+ }
}
if (RT_SUCCESS(vrc))
{
+ LogRel(("VRDE: loaded version %d of the server.\n", mServerInterfaceVersion));
+
+ if (mServerInterfaceVersion >= 4)
+ {
+ /* The server supports optional interfaces. */
+ Assert(mpEntryPoints->VRDEGetInterface != NULL);
+
+ /* Image interface. */
+ m_interfaceImage.header.u64Version = 1;
+ m_interfaceImage.header.u64Size = sizeof(m_interfaceImage);
+
+ m_interfaceCallbacksImage.header.u64Version = 1;
+ m_interfaceCallbacksImage.header.u64Size = sizeof(m_interfaceCallbacksImage);
+ m_interfaceCallbacksImage.VRDEImageCbNotify = VRDEImageCbNotify;
+
+ vrc = mpEntryPoints->VRDEGetInterface(mhServer,
+ VRDE_IMAGE_INTERFACE_NAME,
+ &m_interfaceImage.header,
+ &m_interfaceCallbacksImage.header,
+ this);
+ if (RT_SUCCESS(vrc))
+ {
+ m_fInterfaceImage = true;
+ }
+
+ /* Since these interfaces are optional, it is always a success here. */
+ vrc = VINF_SUCCESS;
+ }
#ifdef VBOX_WITH_USB
remoteUSBThreadStart();
#endif
@@ -1459,11 +1553,366 @@ int ConsoleVRDPServer::Launch(void)
return vrc;
}
+typedef struct H3DORInstance
+{
+ ConsoleVRDPServer *pThis;
+ HVRDEIMAGE hImageBitmap;
+ int32_t x;
+ int32_t y;
+ uint32_t w;
+ uint32_t h;
+ bool fCreated;
+} H3DORInstance;
+
+/* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORBegin(const void *pvContext, void **ppvInstance,
+ const char *pszFormat)
+{
+ LogFlowFunc(("ctx %p\n", pvContext));
+
+ H3DORInstance *p = (H3DORInstance *)RTMemAlloc(sizeof (H3DORInstance));
+
+ if (p)
+ {
+ p->pThis = (ConsoleVRDPServer *)pvContext;
+ p->hImageBitmap = NULL;
+ p->x = 0;
+ p->y = 0;
+ p->w = 0;
+ p->h = 0;
+ p->fCreated = false;
+
+ /* Host 3D service passes the actual format of data in this redirect instance.
+ * That is what will be in the H3DORFrame's parameters pvData and cbData.
+ */
+ if (RTStrICmp(pszFormat, H3DOR_FMT_RGBA_TOPDOWN) == 0)
+ {
+ /* Accept it. */
+ }
+ else
+ {
+ RTMemFree(p);
+ p = NULL;
+ }
+ }
+
+ /* Caller check this for NULL. */
+ *ppvInstance = p;
+}
+
+/* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORGeometry(void *pvInstance,
+ int32_t x, int32_t y, uint32_t w, uint32_t h)
+{
+ LogFlowFunc(("ins %p %d,%d %dx%d\n", pvInstance, x, y, w, h));
+
+ H3DORInstance *p = (H3DORInstance *)pvInstance;
+ Assert(p);
+ Assert(p->pThis);
+
+ /* @todo find out what to do if size changes to 0x0 from non zero */
+ if (w == 0 || h == 0)
+ {
+ /* Do nothing. */
+ return;
+ }
+
+ RTRECT rect;
+ rect.xLeft = x;
+ rect.yTop = y;
+ rect.xRight = x + w;
+ rect.yBottom = y + h;
+
+ if (p->hImageBitmap)
+ {
+ /* An image handle has been already created,
+ * check if it has the same size as the reported geometry.
+ */
+ if ( p->x == x
+ && p->y == y
+ && p->w == w
+ && p->h == h)
+ {
+ LogFlowFunc(("geometry not changed\n"));
+ /* Do nothing. Continue using the existing handle. */
+ }
+ else
+ {
+ int rc = p->pThis->m_interfaceImage.VRDEImageGeometrySet(p->hImageBitmap, &rect);
+ if (RT_SUCCESS(rc))
+ {
+ p->x = x;
+ p->y = y;
+ p->w = w;
+ p->h = h;
+ }
+ else
+ {
+ /* The handle must be recreated. Delete existing handle here. */
+ p->pThis->m_interfaceImage.VRDEImageHandleClose(p->hImageBitmap);
+ p->hImageBitmap = NULL;
+ }
+ }
+ }
+
+ if (!p->hImageBitmap)
+ {
+ /* Create a new bitmap handle. */
+ uint32_t u32ScreenId = 0; /* @todo clip to corresponding screens.
+ * Clipping can be done here or in VRDP server.
+ * If VRDP does clipping, then uScreenId parameter
+ * is not necessary and coords must be global.
+ * (have to check which coords are used in opengl service).
+ * Since all VRDE API uses a ScreenId,
+ * the clipping must be done here in ConsoleVRDPServer
+ */
+ uint32_t fu32CompletionFlags = 0;
+ int rc = p->pThis->m_interfaceImage.VRDEImageHandleCreate(p->pThis->mhServer,
+ &p->hImageBitmap,
+ p,
+ u32ScreenId,
+ VRDE_IMAGE_F_CREATE_CONTENT_3D
+ | VRDE_IMAGE_F_CREATE_WINDOW,
+ &rect,
+ VRDE_IMAGE_FMT_ID_BITMAP_BGRA8,
+ NULL,
+ 0,
+ &fu32CompletionFlags);
+ if (RT_SUCCESS(rc))
+ {
+ p->x = x;
+ p->y = y;
+ p->w = w;
+ p->h = h;
+
+ if ((fu32CompletionFlags & VRDE_IMAGE_F_COMPLETE_ASYNC) == 0)
+ {
+ p->fCreated = true;
+ }
+ }
+ else
+ {
+ p->hImageBitmap = NULL;
+ p->w = 0;
+ p->h = 0;
+ }
+ }
+}
+
+/* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORVisibleRegion(void *pvInstance,
+ uint32_t cRects, RTRECT *paRects)
+{
+ LogFlowFunc(("ins %p %d\n", pvInstance, cRects));
+
+ H3DORInstance *p = (H3DORInstance *)pvInstance;
+ Assert(p);
+ Assert(p->pThis);
+
+ if (cRects == 0)
+ {
+ /* Complete image is visible. */
+ RTRECT rect;
+ rect.xLeft = p->x;
+ rect.yTop = p->y;
+ rect.xRight = p->x + p->w;
+ rect.yBottom = p->y + p->h;
+ p->pThis->m_interfaceImage.VRDEImageRegionSet (p->hImageBitmap,
+ 1,
+ &rect);
+ }
+ else
+ {
+ p->pThis->m_interfaceImage.VRDEImageRegionSet (p->hImageBitmap,
+ cRects,
+ paRects);
+ }
+}
+
+/* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORFrame(void *pvInstance,
+ void *pvData, uint32_t cbData)
+{
+ LogFlowFunc(("ins %p %p %d\n", pvInstance, pvData, cbData));
+
+ H3DORInstance *p = (H3DORInstance *)pvInstance;
+ Assert(p);
+ Assert(p->pThis);
+
+ /* Currently only a topdown BGR0 bitmap format is supported. */
+ VRDEIMAGEBITMAP image;
+
+ image.cWidth = p->w;
+ image.cHeight = p->h;
+ image.pvData = pvData;
+ image.cbData = cbData;
+ image.pvScanLine0 = (uint8_t *)pvData + (p->h - 1) * p->w * 4;
+ image.iScanDelta = -4 * p->w;
+
+ p->pThis->m_interfaceImage.VRDEImageUpdate (p->hImageBitmap,
+ p->x,
+ p->y,
+ p->w,
+ p->h,
+ &image,
+ sizeof(VRDEIMAGEBITMAP));
+}
+
+/* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DOREnd(void *pvInstance)
+{
+ LogFlowFunc(("ins %p\n", pvInstance));
+
+ H3DORInstance *p = (H3DORInstance *)pvInstance;
+ Assert(p);
+ Assert(p->pThis);
+
+ p->pThis->m_interfaceImage.VRDEImageHandleClose(p->hImageBitmap);
+
+ RTMemFree(p);
+}
+
+/* static */ DECLCALLBACK(int) ConsoleVRDPServer::H3DORContextProperty(const void *pvContext, uint32_t index,
+ void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut)
+{
+ int rc = VINF_SUCCESS;
+
+ if (index == H3DOR_PROP_FORMATS)
+ {
+ /* Return a comma separated list of supported formats. */
+ static const char *pszSupportedFormats = H3DOR_FMT_RGBA_TOPDOWN;
+ uint32_t cbOut = (uint32_t)strlen(pszSupportedFormats) + 1;
+ if (cbOut <= cbBuffer)
+ {
+ memcpy(pvBuffer, pszSupportedFormats, cbOut);
+ }
+ else
+ {
+ rc = VERR_BUFFER_OVERFLOW;
+ }
+ *pcbOut = cbOut;
+ }
+ else
+ {
+ rc = VERR_NOT_SUPPORTED;
+ }
+
+ return rc;
+}
+
+void ConsoleVRDPServer::remote3DRedirect(void)
+{
+ if (!m_fInterfaceImage)
+ {
+ /* No redirect without corresponding interface. */
+ return;
+ }
+
+ /* Check if 3D redirection has been enabled. */
+ com::Bstr bstr;
+ HRESULT hrc = mConsole->getVRDEServer()->GetVRDEProperty(Bstr("H3DRedirect/Enabled").raw(), bstr.asOutParam());
+
+ if (hrc != S_OK)
+ {
+ bstr = "";
+ }
+
+ com::Utf8Str value = bstr;
+
+ bool fEnabled = RTStrICmp(value.c_str(), "true") == 0
+ || RTStrICmp(value.c_str(), "1") == 0;
+
+ if (!fEnabled)
+ {
+ return;
+ }
+
+ /* Tell the host 3D service to redirect output using the ConsoleVRDPServer callbacks. */
+ H3DOUTPUTREDIRECT outputRedirect =
+ {
+ this,
+ H3DORBegin,
+ H3DORGeometry,
+ H3DORVisibleRegion,
+ H3DORFrame,
+ H3DOREnd,
+ H3DORContextProperty
+ };
+
+ VBOXHGCMSVCPARM parm;
+
+ parm.type = VBOX_HGCM_SVC_PARM_PTR;
+ parm.u.pointer.addr = &outputRedirect;
+ parm.u.pointer.size = sizeof(outputRedirect);
+
+ VMMDev *pVMMDev = mConsole->getVMMDev();
+
+ if (!pVMMDev)
+ {
+ AssertMsgFailed(("remote3DRedirect no vmmdev\n"));
+ return;
+ }
+
+ int rc = pVMMDev->hgcmHostCall("VBoxSharedCrOpenGL",
+ SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT,
+ SHCRGL_CPARMS_SET_OUTPUT_REDIRECT,
+ &parm);
+
+ if (!RT_SUCCESS(rc))
+ {
+ AssertMsgFailed(("SHCRGL_HOST_FN_SET_CONSOLE failed with %Rrc\n", rc));
+ return;
+ }
+
+ LogRel(("VRDE: Enabled 3D redirect.\n"));
+
+ return;
+}
+
+/* static */ DECLCALLBACK(int) ConsoleVRDPServer::VRDEImageCbNotify (void *pvContext,
+ void *pvUser,
+ HVRDEIMAGE hVideo,
+ uint32_t u32Id,
+ void *pvData,
+ uint32_t cbData)
+{
+ LogFlowFunc(("pvContext %p, pvUser %p, hVideo %p, u32Id %u, pvData %p, cbData %d\n",
+ pvContext, pvUser, hVideo, u32Id, pvData, cbData));
+
+ ConsoleVRDPServer *pServer = static_cast<ConsoleVRDPServer*>(pvContext);
+ H3DORInstance *p = (H3DORInstance *)pvUser;
+ Assert(p);
+ Assert(p->pThis);
+ Assert(p->pThis == pServer);
+
+ if (u32Id == VRDE_IMAGE_NOTIFY_HANDLE_CREATE)
+ {
+ if (cbData != sizeof(uint32_t))
+ {
+ AssertFailed();
+ return VERR_INVALID_PARAMETER;
+ }
+
+ uint32_t u32StreamId = *(uint32_t *)pvData;
+ LogFlowFunc(("VRDE_IMAGE_NOTIFY_HANDLE_CREATE u32StreamId %d\n",
+ u32StreamId));
+
+ if (u32StreamId != 0)
+ {
+ p->fCreated = true; // @todo not needed?
+ }
+ else
+ {
+ /* The stream has not been created. */
+ }
+ }
+
+ return VINF_SUCCESS;
+}
+
void ConsoleVRDPServer::EnableConnections(void)
{
if (mpEntryPoints && mhServer)
{
mpEntryPoints->VRDEEnableConnections(mhServer, true);
+
+ /* Redirect 3D output if it is enabled. */
+ remote3DRedirect();
}
}
@@ -1688,7 +2137,7 @@ AuthResult ConsoleVRDPServer::Authenticate(const Guid &uuid, AuthGuestJudgement
if (RT_SUCCESS(rc))
{
- typedef struct AuthEntryInfo
+ typedef struct AuthEntryInfoStruct
{
const char *pszName;
void **ppvAddress;
@@ -2321,6 +2770,23 @@ void ConsoleVRDPServer::SendAudioInputEnd(void *pvUserCtx)
}
}
+#ifdef VBOX_WITH_USB_VIDEO
+int ConsoleVRDPServer::GetVideoFrameDimensions(uint16_t *pu16Heigh, uint16_t *pu16Width)
+{
+ *pu16Heigh = 640;
+ *pu16Width = 480;
+ return VINF_SUCCESS;
+}
+
+int ConsoleVRDPServer::SendVideoSreamOn(bool fFetch)
+{
+ /* Here we inform server that guest is starting/stopping
+ * the stream
+ */
+ return VINF_SUCCESS;
+}
+#endif
+
void ConsoleVRDPServer::QueryInfo(uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut) const
@@ -2423,12 +2889,13 @@ VRDEServerInfo::~VRDEServerInfo()
HRESULT VRDEServerInfo::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void VRDEServerInfo::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public methods only for internal purposes
diff --git a/src/VBox/Main/src-client/DisplayImpl.cpp b/src/VBox/Main/src-client/DisplayImpl.cpp
index 8cc30e536..362af1442 100644
--- a/src/VBox/Main/src-client/DisplayImpl.cpp
+++ b/src/VBox/Main/src-client/DisplayImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: DisplayImpl.cpp $ */
+/* $Id: DisplayImpl.cpp 37220 2011-05-26 10:18:39Z vboxsync $ */
/** @file
* VirtualBox COM class implementation
*/
@@ -123,7 +123,7 @@ HRESULT Display::FinalConstruct()
mu32UpdateVBVAFlags = 0;
#endif
- return S_OK;
+ return BaseFinalConstruct();
}
void Display::FinalRelease()
@@ -135,6 +135,7 @@ void Display::FinalRelease()
RTCritSectDelete (&mVBVALock);
memset (&mVBVALock, 0, sizeof (mVBVALock));
}
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
@@ -1048,7 +1049,8 @@ static bool displayIntersectRect(RTRECT *prectResult,
int Display::handleSetVisibleRegion(uint32_t cRect, PRTRECT pRect)
{
- RTRECT *pVisibleRegion = (RTRECT *)RTMemTmpAlloc(cRect * sizeof (RTRECT));
+ RTRECT *pVisibleRegion = (RTRECT *)RTMemTmpAlloc( RT_MAX(cRect, 1)
+ * sizeof (RTRECT));
if (!pVisibleRegion)
{
return VERR_NO_TMP_MEMORY;
@@ -1103,10 +1105,7 @@ int Display::handleSetVisibleRegion(uint32_t cRect, PRTRECT pRect)
}
}
- if (cRectVisibleRegion > 0)
- {
- pFBInfo->pFramebuffer->SetVisibleRegion((BYTE *)pVisibleRegion, cRectVisibleRegion);
- }
+ pFBInfo->pFramebuffer->SetVisibleRegion((BYTE *)pVisibleRegion, cRectVisibleRegion);
}
}
diff --git a/src/VBox/Main/src-client/GuestCtrlImpl.cpp b/src/VBox/Main/src-client/GuestCtrlImpl.cpp
index b2343187b..0d1f6581a 100644
--- a/src/VBox/Main/src-client/GuestCtrlImpl.cpp
+++ b/src/VBox/Main/src-client/GuestCtrlImpl.cpp
@@ -1,10 +1,10 @@
-/* $Id: GuestCtrlImpl.cpp $ */
+/* $Id: GuestCtrlImpl.cpp 37930 2011-07-13 19:56:55Z vboxsync $ */
/** @file
* VirtualBox COM class implementation: Guest
*/
/*
- * 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;
@@ -44,8 +44,10 @@ struct Guest::TaskGuest
{
enum TaskType
{
- /** Copies a file to the guest. */
- CopyFile = 50,
+ /** Copies a file from host to the guest. */
+ CopyFileToGuest = 50,
+ /** Copies a file from guest to the host. */
+ CopyFileFromGuest = 55,
/** Update Guest Additions by directly copying the required installer
* off the .ISO file, transfer it to the guest and execute the installer
@@ -59,7 +61,7 @@ struct Guest::TaskGuest
progress(aProgress),
rc(S_OK)
{}
- ~TaskGuest() {}
+ virtual ~TaskGuest() {}
int startThread();
static int taskThread(RTTHREAD aThread, void *pvUser);
@@ -109,9 +111,14 @@ DECLCALLBACK(int) Guest::TaskGuest::taskThread(RTTHREAD /* aThread */, void *pvU
switch (task->taskType)
{
#ifdef VBOX_WITH_GUEST_CONTROL
- case TaskGuest::CopyFile:
+ case TaskGuest::CopyFileToGuest:
{
- rc = pGuest->taskCopyFile(task.get());
+ rc = pGuest->taskCopyFileToGuest(task.get());
+ break;
+ }
+ case TaskGuest::CopyFileFromGuest:
+ {
+ rc = pGuest->taskCopyFileFromGuest(task.get());
break;
}
case TaskGuest::UpdateGuestAdditions:
@@ -181,7 +188,283 @@ HRESULT Guest::TaskGuest::setProgressErrorInfo(HRESULT hr, ComObjPtr<Progress> p
}
#ifdef VBOX_WITH_GUEST_CONTROL
-HRESULT Guest::taskCopyFile(TaskGuest *aTask)
+HRESULT Guest::taskCopyFileToGuest(TaskGuest *aTask)
+{
+ LogFlowFuncEnter();
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ /*
+ * Do *not* take a write lock here since we don't (and won't)
+ * touch any class-specific data (of IGuest) here - only the member functions
+ * which get called here can do that.
+ */
+
+ HRESULT rc = S_OK;
+
+ try
+ {
+ Guest *pGuest = aTask->pGuest;
+ AssertPtr(pGuest);
+
+ /* Does our source file exist? */
+ if (!RTFileExists(aTask->strSource.c_str()))
+ {
+ rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ Guest::tr("Source file \"%s\" does not exist, or is not a file"),
+ aTask->strSource.c_str());
+ }
+ else
+ {
+ RTFILE fileSource;
+ int vrc = RTFileOpen(&fileSource, aTask->strSource.c_str(),
+ RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
+ if (RT_FAILURE(vrc))
+ {
+ rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ Guest::tr("Could not open source file \"%s\" for reading (%Rrc)"),
+ aTask->strSource.c_str(), vrc);
+ }
+ else
+ {
+ uint64_t cbSize;
+ vrc = RTFileGetSize(fileSource, &cbSize);
+ if (RT_FAILURE(vrc))
+ {
+ rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ Guest::tr("Could not query file size of \"%s\" (%Rrc)"),
+ aTask->strSource.c_str(), vrc);
+ }
+ else
+ {
+ com::SafeArray<IN_BSTR> args;
+ com::SafeArray<IN_BSTR> env;
+
+ /*
+ * Prepare tool command line.
+ */
+ char szOutput[RTPATH_MAX];
+ if (RTStrPrintf(szOutput, sizeof(szOutput), "--output=%s", aTask->strDest.c_str()) <= sizeof(szOutput) - 1)
+ {
+ /*
+ * Normalize path slashes, based on the detected guest.
+ */
+ Utf8Str osType = mData.mOSTypeId;
+ if ( osType.contains("Microsoft", Utf8Str::CaseInsensitive)
+ || osType.contains("Windows", Utf8Str::CaseInsensitive))
+ {
+ /* We have a Windows guest. */
+ RTPathChangeToDosSlashes(szOutput, true /* Force conversion. */);
+ }
+ else /* ... or something which isn't from Redmond ... */
+ {
+ RTPathChangeToUnixSlashes(szOutput, true /* Force conversion. */);
+ }
+
+ args.push_back(Bstr(szOutput).raw()); /* We want to write a file ... */
+ }
+ else
+ {
+ rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ Guest::tr("Error preparing command line"));
+ }
+
+ ComPtr<IProgress> execProgress;
+ ULONG uPID;
+ if (SUCCEEDED(rc))
+ {
+ LogRel(("Copying file \"%s\" to guest \"%s\" (%u bytes) ...\n",
+ aTask->strSource.c_str(), aTask->strDest.c_str(), cbSize));
+ /*
+ * 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());
+ if (FAILED(rc))
+ rc = TaskGuest::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ }
+
+ if (SUCCEEDED(rc))
+ {
+ BOOL fCompleted = FALSE;
+ BOOL fCanceled = FALSE;
+
+ 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
+ {
+ 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 = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ Guest::tr("Could not read from file \"%s\" (%Rrc)"),
+ aTask->strSource.c_str(), vrc);
+ break;
+ }
+ }
+
+ /* Resize buffer to reflect amount we just have read.
+ * Size 0 is allowed! */
+ aInputData.resize(cbRead);
+
+ ULONG uFlags = ProcessInputFlag_None;
+ /* Did we reach the end of the content we want to transfer (last chunk)? */
+ if ( (cbRead < _64K)
+ /* 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)))
+ && fCanceled)
+ )
+ {
+ uFlags |= ProcessInputFlag_EndOfFile;
+ }
+
+ /* Transfer the current chunk ... */
+ ULONG uBytesWritten;
+ rc = pGuest->SetProcessInput(uPID, uFlags,
+ 10 * 1000 /* Wait 10s for getting the input data transfered. */,
+ ComSafeArrayAsInParam(aInputData), &uBytesWritten);
+ if (FAILED(rc))
+ {
+ rc = TaskGuest::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ break;
+ }
+
+ Assert(cbRead <= cbToRead);
+ Assert(cbToRead >= cbRead);
+ cbToRead -= cbRead;
+
+ cbTransfered += uBytesWritten;
+ Assert(cbTransfered <= cbSize);
+ aTask->progress->SetCurrentOperationProgress(cbTransfered / (cbSize / 100.0));
+
+ /* End of file reached? */
+ if (cbToRead == 0)
+ break;
+
+ /* Did the user cancel the operation above? */
+ if (fCanceled)
+ break;
+
+ /* Progress canceled by Main API? */
+ if ( SUCCEEDED(execProgress->COMGETTER(Canceled(&fCanceled)))
+ && fCanceled)
+ {
+ rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ Guest::tr("Copy operation of file \"%s\" was canceled on guest side"),
+ aTask->strSource.c_str());
+ break;
+ }
+ }
+
+ if (SUCCEEDED(rc))
+ {
+ /*
+ * If we got here this means the started process either was completed,
+ * canceled or we simply got all stuff transferred.
+ */
+ ExecuteProcessStatus_T retStatus;
+ ULONG uRetExitCode;
+ rc = pGuest->waitForProcessStatusChange(uPID, &retStatus, &uRetExitCode, 10 * 1000 /* 10s timeout. */);
+ if (FAILED(rc))
+ {
+ rc = TaskGuest::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ }
+ else
+ {
+ if ( uRetExitCode != 0
+ || retStatus != ExecuteProcessStatus_TerminatedNormally)
+ {
+ rc = TaskGuest::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());
+ }
+ }
+ }
+
+ if (SUCCEEDED(rc))
+ {
+ if (fCanceled)
+ {
+ /*
+ * 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,
+ COM_IIDOF(IGuest),
+ Guest::getStaticComponentName(),
+ Guest::tr("Copying file \"%s\" canceled"), aTask->strSource.c_str());
+ }
+ else
+ {
+ /*
+ * Even if we succeeded until here make sure to check whether we really transfered
+ * everything.
+ */
+ if ( cbSize > 0
+ && cbTransfered == 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 = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ Guest::tr("Access denied when copying file \"%s\" to \"%s\""),
+ aTask->strSource.c_str(), aTask->strDest.c_str());
+ }
+ else if (cbTransfered < cbSize)
+ {
+ /* If we did not copy all let the user know. */
+ rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ Guest::tr("Copying file \"%s\" failed (%u/%u bytes transfered)"),
+ aTask->strSource.c_str(), cbTransfered, cbSize);
+ }
+ else /* Yay, all went fine! */
+ aTask->progress->notifyComplete(S_OK);
+ }
+ }
+ }
+ }
+ RTFileClose(fileSource);
+ }
+ }
+ }
+ catch (HRESULT aRC)
+ {
+ rc = aRC;
+ }
+
+ /* Clean up */
+ aTask->rc = rc;
+
+ LogFlowFunc(("rc=%Rhrc\n", rc));
+ LogFlowFuncLeave();
+
+ return VINF_SUCCESS;
+}
+
+HRESULT Guest::taskCopyFileFromGuest(TaskGuest *aTask)
{
LogFlowFuncEnter();
@@ -201,11 +484,14 @@ HRESULT Guest::taskCopyFile(TaskGuest *aTask)
Guest *pGuest = aTask->pGuest;
AssertPtr(pGuest);
+
+
+#if 0
/* Does our source file exist? */
if (!RTFileExists(aTask->strSource.c_str()))
{
rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
- Guest::tr("Source file \"%s\" does not exist"),
+ Guest::tr("Source file \"%s\" does not exist, or is not a file"),
aTask->strSource.c_str());
}
else
@@ -379,8 +665,9 @@ HRESULT Guest::taskCopyFile(TaskGuest *aTask)
* If we got here this means the started process either was completed,
* canceled or we simply got all stuff transferred.
*/
- ULONG uRetStatus, uRetExitCode;
- rc = pGuest->waitForProcessStatusChange(uPID, &uRetStatus, &uRetExitCode, 10 * 1000 /* 10s timeout. */);
+ ExecuteProcessStatus_T retStatus;
+ ULONG uRetExitCode;
+ rc = pGuest->waitForProcessStatusChange(uPID, &retStatus, &uRetExitCode, 10 * 1000 /* 10s timeout. */);
if (FAILED(rc))
{
rc = TaskGuest::setProgressErrorInfo(rc, aTask->progress, pGuest);
@@ -388,7 +675,7 @@ HRESULT Guest::taskCopyFile(TaskGuest *aTask)
else
{
if ( uRetExitCode != 0
- || uRetStatus != PROC_STS_TEN)
+ || retStatus != ExecuteProcessStatus_TerminatedNormally)
{
rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
Guest::tr("Guest reported error %u while copying file \"%s\" to \"%s\""),
@@ -416,9 +703,10 @@ HRESULT Guest::taskCopyFile(TaskGuest *aTask)
* Even if we succeeded until here make sure to check whether we really transfered
* everything.
*/
- if (!cbTransfered)
+ if ( cbSize > 0
+ && cbTransfered == 0)
{
- /* If nothing was transfered this means "vbox_cat" wasn't able to write
+ /* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write
* to the destination -> access denied. */
rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
Guest::tr("Access denied when copying file \"%s\" to \"%s\""),
@@ -440,6 +728,7 @@ HRESULT Guest::taskCopyFile(TaskGuest *aTask)
RTFileClose(fileSource);
}
}
+#endif
}
catch (HRESULT aRC)
{
@@ -613,6 +902,12 @@ HRESULT Guest::taskUpdateGuestAdditions(TaskGuest *aTask)
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 = TaskGuest::setProgressErrorInfo(E_FAIL, aTask->progress,
+ Guest::tr("Guest was unable to start copying the Guest Additions setup within time"));
+ break;
+
default:
rc = TaskGuest::setProgressErrorInfo(E_FAIL, aTask->progress,
Guest::tr("Error copying Guest Additions setup file to guest path \"%s\" (%Rrc)"),
@@ -781,8 +1076,9 @@ HRESULT Guest::taskUpdateGuestAdditions(TaskGuest *aTask)
RTThreadSleep(100);
}
- ULONG uRetStatus, uRetExitCode, uRetFlags;
- rc = pGuest->GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &uRetStatus);
+ ExecuteProcessStatus_T retStatus;
+ ULONG uRetExitCode, uRetFlags;
+ rc = pGuest->GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &retStatus);
if (SUCCEEDED(rc))
{
if (fCompleted)
@@ -797,10 +1093,10 @@ HRESULT Guest::taskUpdateGuestAdditions(TaskGuest *aTask)
else
{
LogRel(("Guest Additions update failed (Exit code=%u, Status=%u, Flags=%u)\n",
- uRetExitCode, uRetStatus, uRetFlags));
+ uRetExitCode, retStatus, uRetFlags));
rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
Guest::tr("Guest Additions update failed with exit code=%u (status=%u, flags=%u)"),
- uRetExitCode, uRetStatus, uRetFlags);
+ uRetExitCode, retStatus, uRetFlags);
}
}
else if ( SUCCEEDED(progressInstaller->COMGETTER(Canceled(&fCanceled)))
@@ -809,7 +1105,7 @@ HRESULT Guest::taskUpdateGuestAdditions(TaskGuest *aTask)
LogRel(("Guest Additions update was canceled\n"));
rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
Guest::tr("Guest Additions update was canceled by the guest with exit code=%u (status=%u, flags=%u)"),
- uRetExitCode, uRetStatus, uRetFlags);
+ uRetExitCode, retStatus, uRetFlags);
}
else
{
@@ -900,6 +1196,421 @@ int Guest::prepareExecuteEnv(const char *pszEnv, void **ppvList, uint32_t *pcbLi
}
/**
+ * Adds a callback with a user provided data block and an optional progress object
+ * to the callback map. A callback is identified by a unique context ID which is used
+ * to identify a callback from the guest side.
+ *
+ * @return IPRT status code.
+ * @param puContextID
+ * @param pCallbackData
+ */
+int Guest::callbackAdd(const PVBOXGUESTCTRL_CALLBACK pCallbackData, uint32_t *puContextID)
+{
+ AssertPtrReturn(pCallbackData, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(puContextID, VERR_INVALID_PARAMETER);
+
+ int rc;
+
+ /* Create a new context ID and assign it. */
+ uint32_t uNewContextID = 0;
+ for (;;)
+ {
+ /* Create a new context ID ... */
+ uNewContextID = ASMAtomicIncU32(&mNextContextID);
+ if (uNewContextID == UINT32_MAX)
+ ASMAtomicUoWriteU32(&mNextContextID, 1000);
+ /* Is the context ID already used? Try next ID ... */
+ if (!callbackExists(uNewContextID))
+ {
+ /* Callback with context ID was not found. This means
+ * we can use this context ID for our new callback we want
+ * to add below. */
+ rc = VINF_SUCCESS;
+ break;
+ }
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ /* Add callback with new context ID to our callback map. */
+ mCallbackMap[uNewContextID] = *pCallbackData;
+ Assert(mCallbackMap.size());
+
+ /* Report back new context ID. */
+ *puContextID = uNewContextID;
+ }
+
+ return rc;
+}
+
+/**
+ * Does not do locking!
+ *
+ * @param uContextID
+ */
+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())
+ {
+ if (it->second.pvData)
+ {
+ callbackFreeUserData(it->second.pvData);
+ it->second.cbData = 0;
+ }
+
+ /* Remove callback context (not used anymore). */
+ mCallbackMap.erase(it);
+ }
+}
+
+bool Guest::callbackExists(uint32_t uContextID)
+{
+ AssertReturn(uContextID, false);
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ CallbackMapIter it = mCallbackMap.find(uContextID);
+ return (it == mCallbackMap.end()) ? false : true;
+}
+
+void Guest::callbackFreeUserData(void *pvData)
+{
+ if (pvData)
+ {
+ RTMemFree(pvData);
+ pvData = NULL;
+ }
+}
+
+int Guest::callbackGetUserData(uint32_t uContextID, eVBoxGuestCtrlCallbackType *pEnmType,
+ void **ppvData, size_t *pcbData)
+{
+ AssertReturn(uContextID, VERR_INVALID_PARAMETER);
+ /* pEnmType is optional. */
+ AssertPtrReturn(ppvData, VERR_INVALID_PARAMETER);
+ /* 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;
+
+ 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;
+}
+
+/* Does not do locking! Caller has to take care of it because the caller needs to
+ * modify the data ...*/
+void* Guest::callbackGetUserDataMutableRaw(uint32_t uContextID, size_t *pcbData)
+{
+ AssertReturn(uContextID, NULL);
+ /* pcbData is optional. */
+
+ CallbackMapIterConst it = mCallbackMap.find(uContextID);
+ if (it != mCallbackMap.end())
+ {
+ if (pcbData)
+ *pcbData = it->second.cbData;
+ return it->second.pvData;
+ }
+
+ return NULL;
+}
+
+bool Guest::callbackIsCanceled(uint32_t uContextID)
+{
+ AssertReturn(uContextID, true);
+
+ Progress *pProgress = NULL;
+ {
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ CallbackMapIterConst it = mCallbackMap.find(uContextID);
+ if (it != mCallbackMap.end())
+ pProgress = it->second.pProgress;
+ }
+
+ if (pProgress)
+ {
+ BOOL fCanceled = FALSE;
+ HRESULT hRC = pProgress->COMGETTER(Canceled)(&fCanceled);
+ if ( SUCCEEDED(hRC)
+ && !fCanceled)
+ {
+ return false;
+ }
+ }
+
+ return true; /* No progress / error means canceled. */
+}
+
+bool Guest::callbackIsComplete(uint32_t uContextID)
+{
+ AssertReturn(uContextID, true);
+
+ Progress *pProgress = NULL;
+ {
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ CallbackMapIterConst it = mCallbackMap.find(uContextID);
+ if (it != mCallbackMap.end())
+ pProgress = it->second.pProgress;
+ }
+
+ if (pProgress)
+ {
+ BOOL fCompleted = FALSE;
+ HRESULT hRC = pProgress->COMGETTER(Completed)(&fCompleted);
+ if ( SUCCEEDED(hRC)
+ && fCompleted)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int Guest::callbackMoveForward(uint32_t uContextID, const char *pszMessage)
+{
+ AssertReturn(uContextID, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pszMessage, VERR_INVALID_PARAMETER);
+
+ Progress *pProgress = NULL;
+ {
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ CallbackMapIterConst it = mCallbackMap.find(uContextID);
+ if (it != mCallbackMap.end())
+ pProgress = it->second.pProgress;
+ }
+
+ if (pProgress)
+ {
+ HRESULT hr = pProgress->SetNextOperation(Bstr(pszMessage).raw(), 1 /* Weight */);
+ if (FAILED(hr))
+ return VERR_CANCELLED;
+
+ return VINF_SUCCESS;
+ }
+
+ return VERR_NOT_FOUND;
+}
+
+/**
+ * TODO
+ *
+ * @return IPRT status code.
+ * @param uContextID
+ * @param iRC
+ * @param pszMessage
+ */
+int Guest::callbackNotifyEx(uint32_t uContextID, int iRC, const char *pszMessage)
+{
+ AssertReturn(uContextID, VERR_INVALID_PARAMETER);
+
+ LogFlowFunc(("Notifying callback with CID=%u, iRC=%d, pszMsg=%s ...\n",
+ uContextID, iRC, pszMessage ? pszMessage : "<No message given>"));
+
+ Progress *pProgress = NULL;
+ {
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ CallbackMapIterConst it = mCallbackMap.find(uContextID);
+ if (it != mCallbackMap.end())
+ pProgress = it->second.pProgress;
+ }
+
+#if 0
+ BOOL fCanceled = FALSE;
+ HRESULT hRC = pProgress->COMGETTER(Canceled)(&fCanceled);
+ if ( SUCCEEDED(hRC)
+ && fCanceled)
+ {
+ /* If progress already canceled do nothing here. */
+ return VINF_SUCCESS;
+ }
+#endif
+
+ if (pProgress)
+ {
+ /*
+ * Assume we didn't complete to make sure we clean up even if the
+ * following call fails.
+ */
+ BOOL fCompleted = FALSE;
+ HRESULT hRC = pProgress->COMGETTER(Completed)(&fCompleted);
+ if ( SUCCEEDED(hRC)
+ && !fCompleted)
+ {
+ /*
+ * 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)
+ * is disconnecting without having the chance to sending a status message before, so we
+ * 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)
+ {
+ 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);
+ }
+ }
+ ComAssertComRC(hRC);
+
+ /*
+ * Do *not* NULL pProgress here, because waiting function like executeProcess()
+ * will still rely on this object for checking whether they have to give up!
+ */
+ }
+ /* If pProgress is not found (anymore) that's fine.
+ * Might be destroyed already. */
+ return S_OK;
+}
+
+/**
+ * TODO
+ *
+ * @return IPRT status code.
+ * @param uPID
+ * @param iRC
+ * @param pszMessage
+ */
+int Guest::callbackNotifyAllForPID(uint32_t uPID, int iRC, const char *pszMessage)
+{
+ AssertReturn(uPID, VERR_INVALID_PARAMETER);
+
+ int vrc = VINF_SUCCESS;
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ CallbackMapIter it;
+ for (it = mCallbackMap.begin(); it != mCallbackMap.end(); it++)
+ {
+ switch (it->second.mType)
+ {
+ case VBOXGUESTCTRLCALLBACKTYPE_EXEC_START:
+ break;
+
+ /* When waiting for process output while the process is destroyed,
+ * make sure we also destroy the actual waiting operation (internal progress object)
+ * in order to not block the caller. */
+ case VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT:
+ {
+ PCALLBACKDATAEXECOUT pItData = (PCALLBACKDATAEXECOUT)it->second.pvData;
+ AssertPtr(pItData);
+ if (pItData->u32PID == uPID)
+ vrc = callbackNotifyEx(it->first, iRC, pszMessage);
+ break;
+ }
+
+ /* When waiting for injecting process input while the process is destroyed,
+ * make sure we also destroy the actual waiting operation (internal progress object)
+ * in order to not block the caller. */
+ case VBOXGUESTCTRLCALLBACKTYPE_EXEC_INPUT_STATUS:
+ {
+ PCALLBACKDATAEXECINSTATUS pItData = (PCALLBACKDATAEXECINSTATUS)it->second.pvData;
+ AssertPtr(pItData);
+ if (pItData->u32PID == uPID)
+ vrc = callbackNotifyEx(it->first, iRC, pszMessage);
+ break;
+ }
+
+ default:
+ vrc = VERR_INVALID_PARAMETER;
+ AssertMsgFailed(("Unknown callback type %d, iRC=%d, message=%s\n",
+ it->second.mType, iRC, pszMessage ? pszMessage : "<No message given>"));
+ break;
+ }
+
+ if (RT_FAILURE(vrc))
+ break;
+ }
+
+ return vrc;
+}
+
+int Guest::callbackNotifyComplete(uint32_t uContextID)
+{
+ return callbackNotifyEx(uContextID, S_OK, NULL /* No message */);
+}
+
+int Guest::callbackWaitForCompletion(uint32_t uContextID, LONG lStage, LONG lTimeout)
+{
+ AssertReturn(uContextID, VERR_INVALID_PARAMETER);
+
+ /*
+ * Wait for the HGCM low level callback until the process
+ * has been started (or something went wrong). This is necessary to
+ * get the PID.
+ */
+
+ int vrc = VINF_SUCCESS;
+ Progress *pProgress = NULL;
+ {
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ CallbackMapIterConst it = mCallbackMap.find(uContextID);
+ if (it != mCallbackMap.end())
+ pProgress = it->second.pProgress;
+ else
+ vrc = VERR_NOT_FOUND;
+ }
+
+ if (RT_SUCCESS(vrc))
+ {
+ HRESULT rc;
+ if (lStage < 0)
+ rc = pProgress->WaitForCompletion(lTimeout);
+ else
+ rc = pProgress->WaitForOperationCompletion((ULONG)lStage, lTimeout);
+ if (SUCCEEDED(rc))
+ {
+ if (!callbackIsComplete(uContextID))
+ vrc = callbackIsCanceled(uContextID)
+ ? VERR_CANCELLED : VINF_SUCCESS;
+ }
+ else
+ vrc = VERR_TIMEOUT;
+ }
+
+ return vrc;
+}
+
+/**
* Static callback function for receiving updates on guest control commands
* from the guest. Acts as a dispatcher for the actual class instance.
*
@@ -908,10 +1619,10 @@ int Guest::prepareExecuteEnv(const char *pszEnv, void **ppvList, uint32_t *pcbLi
* @todo
*
*/
-DECLCALLBACK(int) Guest::doGuestCtrlNotification(void *pvExtension,
- uint32_t u32Function,
- void *pvParms,
- uint32_t cbParms)
+DECLCALLBACK(int) Guest::notifyCtrlDispatcher(void *pvExtension,
+ uint32_t u32Function,
+ void *pvParms,
+ uint32_t cbParms)
{
using namespace guestControl;
@@ -935,7 +1646,7 @@ DECLCALLBACK(int) Guest::doGuestCtrlNotification(void *pvExtension,
PCALLBACKDATACLIENTDISCONNECTED pCBData = reinterpret_cast<PCALLBACKDATACLIENTDISCONNECTED>(pvParms);
AssertPtr(pCBData);
AssertReturn(sizeof(CALLBACKDATACLIENTDISCONNECTED) == cbParms, VERR_INVALID_PARAMETER);
- AssertReturn(CALLBACKDATAMAGICCLIENTDISCONNECTED == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
+ AssertReturn(CALLBACKDATAMAGIC_CLIENT_DISCONNECTED == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
rc = pGuest->notifyCtrlClientDisconnected(u32Function, pCBData);
break;
@@ -948,7 +1659,7 @@ DECLCALLBACK(int) Guest::doGuestCtrlNotification(void *pvExtension,
PCALLBACKDATAEXECSTATUS pCBData = reinterpret_cast<PCALLBACKDATAEXECSTATUS>(pvParms);
AssertPtr(pCBData);
AssertReturn(sizeof(CALLBACKDATAEXECSTATUS) == cbParms, VERR_INVALID_PARAMETER);
- AssertReturn(CALLBACKDATAMAGICEXECSTATUS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
+ AssertReturn(CALLBACKDATAMAGIC_EXEC_STATUS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
rc = pGuest->notifyCtrlExecStatus(u32Function, pCBData);
break;
@@ -961,7 +1672,7 @@ DECLCALLBACK(int) Guest::doGuestCtrlNotification(void *pvExtension,
PCALLBACKDATAEXECOUT pCBData = reinterpret_cast<PCALLBACKDATAEXECOUT>(pvParms);
AssertPtr(pCBData);
AssertReturn(sizeof(CALLBACKDATAEXECOUT) == cbParms, VERR_INVALID_PARAMETER);
- AssertReturn(CALLBACKDATAMAGICEXECOUT == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
+ AssertReturn(CALLBACKDATAMAGIC_EXEC_OUT == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
rc = pGuest->notifyCtrlExecOut(u32Function, pCBData);
break;
@@ -974,7 +1685,7 @@ DECLCALLBACK(int) Guest::doGuestCtrlNotification(void *pvExtension,
PCALLBACKDATAEXECINSTATUS pCBData = reinterpret_cast<PCALLBACKDATAEXECINSTATUS>(pvParms);
AssertPtr(pCBData);
AssertReturn(sizeof(CALLBACKDATAEXECINSTATUS) == cbParms, VERR_INVALID_PARAMETER);
- AssertReturn(CALLBACKDATAMAGICEXECINSTATUS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
+ AssertReturn(CALLBACKDATAMAGIC_EXEC_IN_STATUS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
rc = pGuest->notifyCtrlExecInStatus(u32Function, pCBData);
break;
@@ -989,197 +1700,166 @@ DECLCALLBACK(int) Guest::doGuestCtrlNotification(void *pvExtension,
}
/* Function for handling the execution start/termination notification. */
+/* Callback can be called several times. */
int Guest::notifyCtrlExecStatus(uint32_t u32Function,
PCALLBACKDATAEXECSTATUS pData)
{
- int vrc = VINF_SUCCESS;
+ AssertReturn(u32Function, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pData, VERR_INVALID_PARAMETER);
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ uint32_t uContextID = pData->hdr.u32ContextID;
- AssertPtr(pData);
- CallbackMapIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID);
-
- /* Callback can be called several times. */
- if (it != mCallbackMap.end())
+ /* Scope write locks as much as possible. */
{
- PCALLBACKDATAEXECSTATUS pCBData = (PCALLBACKDATAEXECSTATUS)it->second.pvData;
- AssertPtr(pCBData);
-
- pCBData->u32PID = pData->u32PID;
- pCBData->u32Status = pData->u32Status;
- pCBData->u32Flags = pData->u32Flags;
- /** @todo Copy void* buffer contents! */
-
- Utf8Str errMsg;
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* Was progress canceled before? */
- BOOL fCanceled;
- ComAssert(!it->second.pProgress.isNull());
- if ( SUCCEEDED(it->second.pProgress->COMGETTER(Canceled)(&fCanceled))
- && !fCanceled)
+ PCALLBACKDATAEXECSTATUS pCallbackData =
+ (PCALLBACKDATAEXECSTATUS)callbackGetUserDataMutableRaw(uContextID, NULL /* cbData */);
+ if (pCallbackData)
{
- /* Do progress handling. */
- HRESULT hr;
- switch (pData->u32Status)
- {
- case PROC_STS_STARTED:
- LogRel(("Guest process (PID %u) started\n", pCBData->u32PID)); /** @todo Add process name */
- hr = it->second.pProgress->SetNextOperation(Bstr(tr("Waiting for process to exit ...")).raw(), 1 /* Weight */);
- AssertComRC(hr);
- break;
-
- case PROC_STS_TEN: /* Terminated normally. */
- LogRel(("Guest process (PID %u) exited normally\n", pCBData->u32PID)); /** @todo Add process name */
- if (!it->second.pProgress->getCompleted())
- {
- hr = it->second.pProgress->notifyComplete(S_OK);
- AssertComRC(hr);
+ pCallbackData->u32PID = pData->u32PID;
+ pCallbackData->u32Status = pData->u32Status;
+ pCallbackData->u32Flags = pData->u32Flags;
+ /** @todo Copy void* buffer contents? */
+ }
+ else
+ AssertReleaseMsgFailed(("Process status (PID=%u) does not have allocated callback data!\n",
+ pData->u32PID));
+ }
- LogFlowFunc(("Process (CID=%u, status=%u) terminated successfully\n",
- pData->hdr.u32ContextID, pData->u32Status));
- }
- break;
-
- case PROC_STS_TEA: /* Terminated abnormally. */
- LogRel(("Guest process (PID %u) terminated abnormally with exit code = %u\n",
- pCBData->u32PID, pCBData->u32Flags)); /** @todo Add process name */
- errMsg = Utf8StrFmt(Guest::tr("Process terminated abnormally with status '%u'"),
- pCBData->u32Flags);
- break;
-
- case PROC_STS_TES: /* Terminated through signal. */
- LogRel(("Guest process (PID %u) terminated through signal with exit code = %u\n",
- pCBData->u32PID, pCBData->u32Flags)); /** @todo Add process name */
- errMsg = Utf8StrFmt(Guest::tr("Process terminated via signal with status '%u'"),
- pCBData->u32Flags);
- break;
-
- case PROC_STS_TOK:
- LogRel(("Guest process (PID %u) timed out and was killed\n", pCBData->u32PID)); /** @todo Add process name */
- errMsg = Utf8StrFmt(Guest::tr("Process timed out and was killed"));
- break;
-
- case PROC_STS_TOA:
- LogRel(("Guest process (PID %u) timed out and could not be killed\n", pCBData->u32PID)); /** @todo Add process name */
- errMsg = Utf8StrFmt(Guest::tr("Process timed out and could not be killed"));
- break;
-
- case PROC_STS_DWN:
- LogRel(("Guest process (PID %u) killed because system is shutting down\n", pCBData->u32PID)); /** @todo Add process name */
- /*
- * If u32Flags has ExecuteProcessFlag_IgnoreOrphanedProcesses set, we don't report an error to
- * our progress object. This is helpful for waiters which rely on the success of our progress object
- * even if the executed process was killed because the system/VBoxService is shutting down.
- *
- * In this case u32Flags contains the actual execution flags reached in via Guest::ExecuteProcess().
- */
- if (pData->u32Flags & ExecuteProcessFlag_IgnoreOrphanedProcesses)
- {
- if (!it->second.pProgress->getCompleted())
- {
- hr = it->second.pProgress->notifyComplete(S_OK);
- AssertComRC(hr);
- }
- }
- else
- {
- errMsg = Utf8StrFmt(Guest::tr("Process killed because system is shutting down"));
- }
- break;
+ int vrc = VINF_SUCCESS;
+ Utf8Str errMsg;
- case PROC_STS_ERROR:
- LogRel(("Guest process (PID %u) could not be started because of rc=%Rrc\n",
- pCBData->u32PID, pCBData->u32Flags)); /** @todo Add process name */
- errMsg = Utf8StrFmt(Guest::tr("Process execution failed with rc=%Rrc"), pCBData->u32Flags);
- break;
+ /* Was progress canceled before? */
+ bool fCbCanceled = callbackIsCanceled(uContextID);
+ if (!fCbCanceled)
+ {
+ /* Do progress handling. */
+ switch (pData->u32Status)
+ {
+ case PROC_STS_STARTED:
+ vrc = callbackMoveForward(uContextID, Guest::tr("Waiting for process to exit ..."));
+ LogRel(("Guest process (PID %u) started\n", pData->u32PID)); /** @todo Add process name */
+ break;
+
+ case PROC_STS_TEN: /* Terminated normally. */
+ vrc = callbackNotifyComplete(uContextID);
+ LogRel(("Guest process (PID %u) exited normally\n", pData->u32PID)); /** @todo Add process name */
+ break;
+
+ case PROC_STS_TEA: /* Terminated abnormally. */
+ LogRel(("Guest process (PID %u) terminated abnormally with exit code = %u\n",
+ pData->u32PID, pData->u32Flags)); /** @todo Add process name */
+ errMsg = Utf8StrFmt(Guest::tr("Process terminated abnormally with status '%u'"),
+ pData->u32Flags);
+ break;
+
+ case PROC_STS_TES: /* Terminated through signal. */
+ LogRel(("Guest process (PID %u) terminated through signal with exit code = %u\n",
+ pData->u32PID, pData->u32Flags)); /** @todo Add process name */
+ errMsg = Utf8StrFmt(Guest::tr("Process terminated via signal with status '%u'"),
+ pData->u32Flags);
+ 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"));
+ 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"));
+ break;
+
+ case PROC_STS_DWN:
+ LogRel(("Guest process (PID %u) killed because system is shutting down\n", pData->u32PID)); /** @todo Add process name */
+ /*
+ * If u32Flags has ExecuteProcessFlag_IgnoreOrphanedProcesses set, we don't report an error to
+ * our progress object. This is helpful for waiters which rely on the success of our progress object
+ * even if the executed process was killed because the system/VBoxService is shutting down.
+ *
+ * In this case u32Flags contains the actual execution flags reached in via Guest::ExecuteProcess().
+ */
+ if (pData->u32Flags & ExecuteProcessFlag_IgnoreOrphanedProcesses)
+ {
+ vrc = callbackNotifyComplete(uContextID);
+ }
+ else
+ errMsg = Utf8StrFmt(Guest::tr("Process killed because system is shutting down"));
+ 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 */
+ errMsg = Utf8StrFmt(Guest::tr("Process execution failed with rc=%Rrc"), pData->u32Flags);
+ break;
+
+ default:
+ vrc = VERR_INVALID_PARAMETER;
+ 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);
}
-
- /* Handle process map. */
- /** @todo What happens on/deal with PID reuse? */
- /** @todo How to deal with multiple updates at once? */
- if (pCBData->u32PID > 0)
+ else if (RT_SUCCESS(vrc))
{
- GuestProcessMapIter it_proc = getProcessByPID(pCBData->u32PID);
- if (it_proc == mGuestProcessMap.end())
- {
- /* Not found, add to map. */
- GuestProcess newProcess;
- newProcess.mStatus = pCBData->u32Status;
- newProcess.mExitCode = pCBData->u32Flags; /* Contains exit code. */
- newProcess.mFlags = 0;
-
- mGuestProcessMap[pCBData->u32PID] = newProcess;
- }
- else /* Update map. */
- {
- it_proc->second.mStatus = pCBData->u32Status;
- it_proc->second.mExitCode = pCBData->u32Flags; /* Contains exit code. */
- it_proc->second.mFlags = 0;
- }
+ /* 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"));
+ }
+ else
+ errMsg = Utf8StrFmt(Guest::tr("Process execution canceled"));
- if (!it->second.pProgress->getCompleted())
+ if (!callbackIsComplete(uContextID))
+ {
+ if ( errMsg.length()
+ || fCbCanceled) /* If canceled we have to report E_FAIL! */
{
- if ( errMsg.length()
- || fCanceled) /* 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)
{
- /* Destroy all callbacks which are still waiting on something
- * which is related to the current PID. */
- CallbackMapIter it2;
- for (it2 = mCallbackMap.begin(); it2 != mCallbackMap.end(); it2++)
- {
- switch (it2->second.mType)
- {
- case VBOXGUESTCTRLCALLBACKTYPE_EXEC_START:
- break;
-
- /* When waiting for process output while the process is destroyed,
- * make sure we also destroy the actual waiting operation (internal progress object)
- * in order to not block the caller. */
- case VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT:
- {
- PCALLBACKDATAEXECOUT pItData = (PCALLBACKDATAEXECOUT)it2->second.pvData;
- AssertPtr(pItData);
- if (pItData->u32PID == pCBData->u32PID)
- notifyCtrlCallbackContext(it2, errMsg.c_str());
- break;
- }
-
- /* When waiting for injecting process input while the process is destroyed,
- * make sure we also destroy the actual waiting operation (internal progress object)
- * in order to not block the caller. */
- case VBOXGUESTCTRLCALLBACKTYPE_EXEC_INPUT_STATUS:
- {
- PCALLBACKDATAEXECINSTATUS pItData = (PCALLBACKDATAEXECINSTATUS)it2->second.pvData;
- AssertPtr(pItData);
- if (pItData->u32PID == pCBData->u32PID)
- notifyCtrlCallbackContext(it2, errMsg.c_str());
- break;
- }
-
- default:
- AssertMsgFailed(("Unknown callback type %d\n", it2->second.mType));
- break;
- }
- }
+ 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));
+ }
- /* Let the caller know what went wrong ... */
- notifyCtrlCallbackContext(it, errMsg.c_str());
+ /* Let the caller know what went wrong ... */
+ int rc2 = callbackNotifyEx(uContextID, VERR_GENERAL_FAILURE, errMsg.c_str());
+ if (RT_FAILURE(rc2))
+ {
+ LogFlowFunc(("Failed to notify callback CID=%u for PID=%u\n",
+ uContextID, pData->u32PID));
- LogFlowFunc(("Process (CID=%u, status=%u) reported error: %s\n",
- pData->hdr.u32ContextID, pData->u32Status, errMsg.c_str()));
+ if (RT_SUCCESS(vrc))
+ vrc = rc2;
}
+ LogFlowFunc(("Process (CID=%u, status=%u) reported error: %s\n",
+ uContextID, pData->u32Status, errMsg.c_str()));
}
}
- else
- LogFlowFunc(("Unexpected callback (magic=%u, CID=%u) arrived\n", pData->hdr.u32Magic, pData->hdr.u32ContextID));
LogFlowFunc(("Returned with rc=%Rrc\n", vrc));
return vrc;
}
@@ -1188,244 +1868,207 @@ int Guest::notifyCtrlExecStatus(uint32_t u32Function,
int Guest::notifyCtrlExecOut(uint32_t u32Function,
PCALLBACKDATAEXECOUT pData)
{
- int rc = VINF_SUCCESS;
+ AssertReturn(u32Function, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pData, VERR_INVALID_PARAMETER);
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ uint32_t uContextID = pData->hdr.u32ContextID;
+ Assert(uContextID);
- AssertPtr(pData);
- CallbackMapIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID);
- if (it != mCallbackMap.end())
+ /* Scope write locks as much as possible. */
{
- PCALLBACKDATAEXECOUT pCBData = (PCALLBACKDATAEXECOUT)it->second.pvData;
- AssertPtr(pCBData);
-
- pCBData->u32PID = pData->u32PID;
- pCBData->u32HandleId = pData->u32HandleId;
- pCBData->u32Flags = pData->u32Flags;
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* Make sure we really got something! */
- if ( pData->cbData
- && pData->pvData)
+ PCALLBACKDATAEXECOUT pCallbackData =
+ (PCALLBACKDATAEXECOUT)callbackGetUserDataMutableRaw(uContextID, NULL /* cbData */);
+ if (pCallbackData)
{
- /* Allocate data buffer and copy it */
- pCBData->pvData = RTMemAlloc(pData->cbData);
- pCBData->cbData = pData->cbData;
+ pCallbackData->u32PID = pData->u32PID;
+ pCallbackData->u32HandleId = pData->u32HandleId;
+ pCallbackData->u32Flags = pData->u32Flags;
- AssertReturn(pCBData->pvData, VERR_NO_MEMORY);
- memcpy(pCBData->pvData, pData->pvData, pData->cbData);
- }
- else
- {
- pCBData->pvData = NULL;
- pCBData->cbData = 0;
- }
+ /* Make sure we really got something! */
+ if ( pData->cbData
+ && pData->pvData)
+ {
+ callbackFreeUserData(pCallbackData->pvData);
- /* Was progress canceled before? */
- BOOL fCanceled;
- ComAssert(!it->second.pProgress.isNull());
- if (SUCCEEDED(it->second.pProgress->COMGETTER(Canceled)(&fCanceled)) && fCanceled)
- {
- it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR,
- COM_IIDOF(IGuest),
- Guest::getStaticComponentName(),
- Guest::tr("The output operation was canceled"));
- }
- else
- {
- BOOL fCompleted;
- if ( SUCCEEDED(it->second.pProgress->COMGETTER(Completed)(&fCompleted))
- && !fCompleted)
+ /* Allocate data buffer and copy it */
+ pCallbackData->pvData = RTMemAlloc(pData->cbData);
+ pCallbackData->cbData = pData->cbData;
+
+ AssertReturn(pCallbackData->pvData, VERR_NO_MEMORY);
+ memcpy(pCallbackData->pvData, pData->pvData, pData->cbData);
+ }
+ else /* Nothing received ... */
{
- /* If we previously got completed notification, don't trigger again. */
- it->second.pProgress->notifyComplete(S_OK);
+ pCallbackData->pvData = NULL;
+ pCallbackData->cbData = 0;
}
}
+ else
+ AssertReleaseMsgFailed(("Process output status (PID=%u) does not have allocated callback data!\n",
+ pData->u32PID));
+ }
+
+ int vrc;
+ if (callbackIsCanceled(pData->u32PID))
+ {
+ vrc = callbackNotifyEx(uContextID, VERR_CANCELLED,
+ Guest::tr("The output operation was canceled"));
}
else
- LogFlowFunc(("Unexpected callback (magic=%u, CID=%u) arrived\n", pData->hdr.u32Magic, pData->hdr.u32ContextID));
- return rc;
+ vrc = callbackNotifyComplete(uContextID);
+
+ return vrc;
}
/* Function for handling the execution input status notification. */
int Guest::notifyCtrlExecInStatus(uint32_t u32Function,
PCALLBACKDATAEXECINSTATUS pData)
{
- int rc = VINF_SUCCESS;
+ AssertReturn(u32Function, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pData, VERR_INVALID_PARAMETER);
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ uint32_t uContextID = pData->hdr.u32ContextID;
+ Assert(uContextID);
- AssertPtr(pData);
- CallbackMapIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID);
- if (it != mCallbackMap.end())
+ /* Scope write locks as much as possible. */
{
- PCALLBACKDATAEXECINSTATUS pCBData = (PCALLBACKDATAEXECINSTATUS)it->second.pvData;
- AssertPtr(pCBData);
-
- /* Save bytes processed. */
- pCBData->cbProcessed = pData->cbProcessed;
- pCBData->u32Status = pData->u32Status;
- pCBData->u32Flags = pData->u32Flags;
- pCBData->u32PID = pData->u32PID;
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* Only trigger completion once. */
- BOOL fCompleted;
- if ( SUCCEEDED(it->second.pProgress->COMGETTER(Completed)(&fCompleted))
- && !fCompleted)
+ PCALLBACKDATAEXECINSTATUS pCallbackData =
+ (PCALLBACKDATAEXECINSTATUS)callbackGetUserDataMutableRaw(uContextID, NULL /* cbData */);
+ if (pCallbackData)
{
- it->second.pProgress->notifyComplete(S_OK);
+ /* Save bytes processed. */
+ pCallbackData->cbProcessed = pData->cbProcessed;
+ pCallbackData->u32Status = pData->u32Status;
+ pCallbackData->u32Flags = pData->u32Flags;
+ pCallbackData->u32PID = pData->u32PID;
}
+ else
+ AssertReleaseMsgFailed(("Process input status (PID=%u) does not have allocated callback data!\n",
+ pData->u32PID));
}
- else
- LogFlowFunc(("Unexpected callback (magic=%u, CID=%u) arrived\n", pData->hdr.u32Magic, pData->hdr.u32ContextID));
- return rc;
+
+ return callbackNotifyComplete(uContextID);
}
int Guest::notifyCtrlClientDisconnected(uint32_t u32Function,
PCALLBACKDATACLIENTDISCONNECTED pData)
{
- int rc = VINF_SUCCESS;
+ /* u32Function is 0. */
+ AssertPtrReturn(pData, VERR_INVALID_PARAMETER);
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- CallbackMapIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID);
- if (it != mCallbackMap.end())
- {
- LogFlowFunc(("Client with CID=%u disconnected\n", it->first));
- notifyCtrlCallbackContext(it, Guest::tr("Client disconnected"));
- }
- return rc;
-}
+ uint32_t uContextID = pData->hdr.u32ContextID;
+ Assert(uContextID);
-Guest::CallbackMapIter Guest::getCtrlCallbackContextByID(uint32_t u32ContextID)
-{
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- return mCallbackMap.find(u32ContextID);
+ return callbackNotifyEx(uContextID, S_OK,
+ Guest::tr("Client disconnected"));
}
-Guest::GuestProcessMapIter Guest::getProcessByPID(uint32_t u32PID)
+int Guest::processAdd(uint32_t u32PID, ExecuteProcessStatus_T enmStatus,
+ uint32_t uExitCode, uint32_t uFlags)
{
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- return mGuestProcessMap.find(u32PID);
-}
+ AssertReturn(u32PID, VERR_INVALID_PARAMETER);
-/* No locking here; */
-void Guest::destroyCtrlCallbackContext(Guest::CallbackMapIter it)
-{
- LogFlowFunc(("Destroying callback with CID=%u ...\n", it->first));
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- if (it->second.pvData)
+ GuestProcessMapIterConst it = mGuestProcessMap.find(u32PID);
+ if (it == mGuestProcessMap.end())
{
- RTMemFree(it->second.pvData);
- it->second.pvData = NULL;
- it->second.cbData = 0;
+ VBOXGUESTCTRL_PROCESS process;
+
+ process.mStatus = enmStatus;
+ process.mExitCode = uExitCode;
+ process.mFlags = uFlags;
+
+ mGuestProcessMap[u32PID] = process;
+
+ return VINF_SUCCESS;
}
- /* Remove callback context (not used anymore). */
- mCallbackMap.erase(it);
+ return VERR_ALREADY_EXISTS;
}
-/* No locking here; */
-void Guest::notifyCtrlCallbackContext(Guest::CallbackMapIter it, const char *pszText)
+int Guest::processGetByPID(uint32_t u32PID, PVBOXGUESTCTRL_PROCESS pProcess)
{
- AssertPtr(pszText);
- LogFlowFunc(("Handling callback with CID=%u ...\n", it->first));
+ AssertReturn(u32PID, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pProcess, VERR_INVALID_PARAMETER);
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* Notify outstanding waits for progress ... */
- if ( it->second.pProgress
- && !it->second.pProgress.isNull())
+ GuestProcessMapIterConst it = mGuestProcessMap.find(u32PID);
+ if (it != mGuestProcessMap.end())
{
- LogFlowFunc(("Notifying progress for CID=%u (Reason: %s) ...\n",
- it->first, pszText));
+ pProcess->mStatus = it->second.mStatus;
+ pProcess->mExitCode = it->second.mExitCode;
+ pProcess->mFlags = it->second.mFlags;
- /*
- * Assume we didn't complete to make sure we clean up even if the
- * following call fails.
- */
- BOOL fCompleted = FALSE;
- it->second.pProgress->COMGETTER(Completed)(&fCompleted);
- if (!fCompleted)
- {
- /*
- * 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)
- * is disconnecting without having the chance to sending a status message before, so we
- * have to abort here to make sure the host never hangs/gets stuck while waiting for the
- * progress object to become signalled.
- */
- it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR,
- COM_IIDOF(IGuest),
- Guest::getStaticComponentName(),
- pszText);
- }
- /*
- * Do *not* NULL pProgress here, because waiting function like executeProcess()
- * will still rely on this object for checking whether they have to give up!
- */
+ return VINF_SUCCESS;
}
+
+ return VERR_NOT_FOUND;
}
-/* Adds a callback with a user provided data block and an optional progress object
- * to the callback map. A callback is identified by a unique context ID which is used
- * to identify a callback from the guest side. */
-uint32_t Guest::addCtrlCallbackContext(eVBoxGuestCtrlCallbackType enmType, void *pvData, uint32_t cbData, Progress *pProgress)
+int Guest::processSetStatus(uint32_t u32PID, ExecuteProcessStatus_T enmStatus, uint32_t uExitCode, uint32_t uFlags)
{
- AssertPtr(pProgress);
+ AssertReturn(u32PID, VERR_INVALID_PARAMETER);
- /** @todo Put this stuff into a constructor! */
- CallbackContext context;
- context.mType = enmType;
- context.pvData = pvData;
- context.cbData = cbData;
- context.pProgress = pProgress;
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* Create a new context ID and assign it. */
- CallbackMapIter it;
- uint32_t uNewContext = 0;
- do
+ GuestProcessMapIter it = mGuestProcessMap.find(u32PID);
+ if (it != mGuestProcessMap.end())
{
- /* Create a new context ID ... */
- uNewContext = ASMAtomicIncU32(&mNextContextID);
- if (uNewContext == UINT32_MAX)
- ASMAtomicUoWriteU32(&mNextContextID, 1000);
- /* Is the context ID already used? */
- it = getCtrlCallbackContextByID(uNewContext);
- } while(it != mCallbackMap.end());
+ it->second.mStatus = enmStatus;
+ it->second.mExitCode = uExitCode;
+ it->second.mFlags = uFlags;
- uint32_t nCallbacks = 0;
- if ( it == mCallbackMap.end()
- && uNewContext > 0)
- {
- /* We apparently got an unused context ID, let's use it! */
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- mCallbackMap[uNewContext] = context;
- nCallbacks = mCallbackMap.size();
+ return VINF_SUCCESS;
}
+
+ return VERR_NOT_FOUND;
+}
+
+HRESULT Guest::handleErrorCompletion(int rc)
+{
+ HRESULT hRC;
+ if (rc == VERR_NOT_FOUND)
+ hRC = setErrorNoLog(VBOX_E_VM_ERROR,
+ tr("VMM device is not available (is the VM running?)"));
+ else if (rc == VERR_CANCELLED)
+ hRC = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("Process execution has been canceled"));
+ else if (rc == VERR_TIMEOUT)
+ hRC= setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("The guest did not respond within time"));
else
- {
- /* Should never happen ... */
- {
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- nCallbacks = mCallbackMap.size();
- }
- AssertReleaseMsg(uNewContext, ("No free context ID found! uNewContext=%u, nCallbacks=%u", uNewContext, nCallbacks));
- }
+ hRC = setErrorNoLog(E_UNEXPECTED,
+ tr("Waiting for completion failed with error %Rrc"), rc);
+ return hRC;
+}
-#if 0
- if (nCallbacks > 256) /* Don't let the container size get too big! */
- {
- Guest::CallbackListIter it = mCallbackList.begin();
- destroyCtrlCallbackContext(it);
- {
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- mCallbackList.erase(it);
- }
- }
-#endif
- return uNewContext;
+HRESULT Guest::handleErrorHGCM(int rc)
+{
+ HRESULT hRC;
+ if (rc == VERR_INVALID_VM_HANDLE)
+ hRC = setErrorNoLog(VBOX_E_VM_ERROR,
+ tr("VMM device is not available (is the VM running?)"));
+ else if (rc == VERR_NOT_FOUND)
+ hRC = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("The guest execution service is not ready (yet)"));
+ else if (rc == VERR_HGCM_SERVICE_NOT_FOUND)
+ hRC= setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("The guest execution service is not available"));
+ else /* HGCM call went wrong. */
+ hRC = setErrorNoLog(E_UNEXPECTED,
+ tr("The HGCM call failed with error %Rrc"), rc);
+ return hRC;
}
-HRESULT Guest::waitForProcessStatusChange(ULONG uPID, ULONG *puRetStatus, ULONG *puRetExitCode, ULONG uTimeoutMS)
+HRESULT Guest::waitForProcessStatusChange(ULONG uPID, ExecuteProcessStatus_T *pRetStatus, ULONG *puRetExitCode, ULONG uTimeoutMS)
{
- AssertPtr(puRetStatus);
+ AssertPtr(pRetStatus);
AssertPtr(puRetExitCode);
if (uTimeoutMS == 0)
@@ -1448,13 +2091,95 @@ HRESULT Guest::waitForProcessStatusChange(ULONG uPID, ULONG *puRetStatus, ULONG
uPID, uTimeoutMS);
break;
}
- hRC = GetProcessStatus(uPID, puRetExitCode, &uRetFlagsIgnored, puRetStatus);
+ hRC = GetProcessStatus(uPID, puRetExitCode, &uRetFlagsIgnored, pRetStatus);
if (FAILED(hRC))
break;
RTThreadSleep(100);
- } while(*puRetStatus == PROC_STS_STARTED && SUCCEEDED(hRC));
+ } while(*pRetStatus == ExecuteProcessStatus_Started && SUCCEEDED(hRC));
return hRC;
}
+
+HRESULT Guest::executeProcessResult(const char *pszCommand, const char *pszUser, ULONG ulTimeout,
+ PCALLBACKDATAEXECSTATUS pExecStatus, ULONG *puPID)
+{
+ AssertPtrReturn(pExecStatus, E_INVALIDARG);
+ AssertPtrReturn(puPID, E_INVALIDARG);
+
+ HRESULT rc = S_OK;
+
+ /* Did we get some status? */
+ switch (pExecStatus->u32Status)
+ {
+ case PROC_STS_STARTED:
+ /* Process is (still) running; get PID. */
+ *puPID = pExecStatus->u32PID;
+ break;
+
+ /* In any other case the process either already
+ * terminated or something else went wrong, so no PID ... */
+ case PROC_STS_TEN: /* Terminated normally. */
+ case PROC_STS_TEA: /* Terminated abnormally. */
+ case PROC_STS_TES: /* Terminated through signal. */
+ case PROC_STS_TOK:
+ case PROC_STS_TOA:
+ case PROC_STS_DWN:
+ /*
+ * Process (already) ended, but we want to get the
+ * PID anyway to retrieve the output in a later call.
+ */
+ *puPID = pExecStatus->u32PID;
+ break;
+
+ case PROC_STS_ERROR:
+ {
+ int vrc = pExecStatus->u32Flags; /* u32Flags member contains IPRT error code. */
+ if (vrc == VERR_FILE_NOT_FOUND) /* This is the most likely error. */
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("The file '%s' was not found on guest"), pszCommand);
+ else if (vrc == VERR_PATH_NOT_FOUND)
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("The path to file '%s' was not found on guest"), pszCommand);
+ else if (vrc == VERR_BAD_EXE_FORMAT)
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("The file '%s' is not an executable format on guest"), pszCommand);
+ else if (vrc == VERR_AUTHENTICATION_FAILURE)
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("The specified user '%s' was not able to logon on guest"), pszUser);
+ else if (vrc == VERR_TIMEOUT)
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("The guest did not respond within time (%ums)"), ulTimeout);
+ else if (vrc == VERR_CANCELLED)
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("The execution operation was canceled"));
+ else if (vrc == VERR_PERMISSION_DENIED)
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("Invalid user/password credentials"));
+ else
+ {
+ if (pExecStatus && pExecStatus->u32Status == PROC_STS_ERROR)
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("Process could not be started: %Rrc"), pExecStatus->u32Flags);
+ else
+ rc = setErrorNoLog(E_UNEXPECTED,
+ tr("The service call failed with error %Rrc"), vrc);
+ }
+ }
+ break;
+
+ case PROC_STS_UNDEFINED: /* . */
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("The operation did not complete within time"));
+ break;
+
+ default:
+ AssertReleaseMsgFailed(("Process (PID %u) reported back an undefined state!\n",
+ pExecStatus->u32PID));
+ rc = E_UNEXPECTED;
+ break;
+ }
+
+ return rc;
+}
#endif /* VBOX_WITH_GUEST_CONTROL */
STDMETHODIMP Guest::ExecuteProcess(IN_BSTR aCommand, ULONG aFlags,
@@ -1528,15 +2253,15 @@ HRESULT Guest::executeProcessInternal(IN_BSTR aCommand, ULONG aFlags,
* started and exited normally. In any other case an error/exception
* occurred.
*/
- ComObjPtr <Progress> progress;
- rc = progress.createObject();
+ ComObjPtr <Progress> pProgress;
+ rc = pProgress.createObject();
if (SUCCEEDED(rc))
{
- rc = progress->init(static_cast<IGuest*>(this),
- Bstr(tr("Executing process")).raw(),
- TRUE,
- 2, /* Number of operations. */
- Bstr(tr("Starting process ...")).raw()); /* Description of first stage. */
+ rc = pProgress->init(static_cast<IGuest*>(this),
+ Bstr(tr("Executing process")).raw(),
+ TRUE,
+ 2, /* Number of operations. */
+ Bstr(tr("Starting process ...")).raw()); /* Description of first stage. */
}
ComAssertComRC(rc);
@@ -1573,7 +2298,7 @@ HRESULT Guest::executeProcessInternal(IN_BSTR aCommand, ULONG aFlags,
char *pszArgs = NULL;
if (uNumArgs > 0)
- vrc = RTGetOptArgvToString(&pszArgs, papszArgv, 0);
+ vrc = RTGetOptArgvToString(&pszArgs, papszArgv, RTGETOPTARGV_CNV_QUOTE_MS_CRT);
if (RT_SUCCESS(vrc))
{
uint32_t cbArgs = pszArgs ? strlen(pszArgs) + 1 : 0; /* Include terminating zero. */
@@ -1596,205 +2321,125 @@ HRESULT Guest::executeProcessInternal(IN_BSTR aCommand, ULONG aFlags,
if (RT_SUCCESS(vrc))
{
- PCALLBACKDATAEXECSTATUS pData = (PCALLBACKDATAEXECSTATUS)RTMemAlloc(sizeof(CALLBACKDATAEXECSTATUS));
- AssertReturn(pData, VBOX_E_IPRT_ERROR);
- RT_ZERO(*pData);
- uContextID = addCtrlCallbackContext(VBOXGUESTCTRLCALLBACKTYPE_EXEC_START,
- pData, sizeof(CALLBACKDATAEXECSTATUS), progress);
- Assert(uContextID > 0);
-
- VBOXHGCMSVCPARM paParms[15];
- int i = 0;
- paParms[i++].setUInt32(uContextID);
- paParms[i++].setPointer((void*)Utf8Command.c_str(), (uint32_t)Utf8Command.length() + 1);
- paParms[i++].setUInt32(aFlags);
- paParms[i++].setUInt32(uNumArgs);
- paParms[i++].setPointer((void*)pszArgs, cbArgs);
- paParms[i++].setUInt32(uNumEnv);
- paParms[i++].setUInt32(cbEnv);
- paParms[i++].setPointer((void*)pvEnv, cbEnv);
- paParms[i++].setPointer((void*)Utf8UserName.c_str(), (uint32_t)Utf8UserName.length() + 1);
- paParms[i++].setPointer((void*)Utf8Password.c_str(), (uint32_t)Utf8Password.length() + 1);
+ /* Allocate payload. */
+ PCALLBACKDATAEXECSTATUS pStatus = (PCALLBACKDATAEXECSTATUS)RTMemAlloc(sizeof(CALLBACKDATAEXECSTATUS));
+ AssertReturn(pStatus, VBOX_E_IPRT_ERROR);
+ RT_ZERO(*pStatus);
+
+ /* Create callback. */
+ VBOXGUESTCTRL_CALLBACK callback;
+ callback.mType = VBOXGUESTCTRLCALLBACKTYPE_EXEC_START;
+ callback.cbData = sizeof(CALLBACKDATAEXECSTATUS);
+ callback.pvData = pStatus;
+ callback.pProgress = pProgress;
+
+ vrc = callbackAdd(&callback, &uContextID);
+ if (RT_SUCCESS(vrc))
+ {
+ VBOXHGCMSVCPARM paParms[15];
+ int i = 0;
+ paParms[i++].setUInt32(uContextID);
+ paParms[i++].setPointer((void*)Utf8Command.c_str(), (uint32_t)Utf8Command.length() + 1);
+ paParms[i++].setUInt32(aFlags);
+ paParms[i++].setUInt32(uNumArgs);
+ paParms[i++].setPointer((void*)pszArgs, cbArgs);
+ paParms[i++].setUInt32(uNumEnv);
+ paParms[i++].setUInt32(cbEnv);
+ paParms[i++].setPointer((void*)pvEnv, cbEnv);
+ paParms[i++].setPointer((void*)Utf8UserName.c_str(), (uint32_t)Utf8UserName.length() + 1);
+ paParms[i++].setPointer((void*)Utf8Password.c_str(), (uint32_t)Utf8Password.length() + 1);
- /*
- * If the WaitForProcessStartOnly flag is set, we only want to define and wait for a timeout
- * until the process was started - the process itself then gets an infinite timeout for execution.
- * This is handy when we want to start a process inside a worker thread within a certain timeout
- * but let the started process perform lengthly operations then.
- */
- if (aFlags & ExecuteProcessFlag_WaitForProcessStartOnly)
- paParms[i++].setUInt32(UINT32_MAX /* Infinite timeout */);
- else
- paParms[i++].setUInt32(aTimeoutMS);
+ /*
+ * If the WaitForProcessStartOnly flag is set, we only want to define and wait for a timeout
+ * until the process was started - the process itself then gets an infinite timeout for execution.
+ * This is handy when we want to start a process inside a worker thread within a certain timeout
+ * but let the started process perform lengthly operations then.
+ */
+ if (aFlags & ExecuteProcessFlag_WaitForProcessStartOnly)
+ paParms[i++].setUInt32(UINT32_MAX /* Infinite timeout */);
+ else
+ paParms[i++].setUInt32(aTimeoutMS);
- VMMDev *vmmDev;
- {
- /* Make sure mParent is valid, so set the read lock while using.
- * Do not keep this lock while doing the actual call, because in the meanwhile
- * another thread could request a write lock which would be a bad idea ... */
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ VMMDev *pVMMDev = NULL;
+ {
+ /* Make sure mParent is valid, so set the read lock while using.
+ * Do not keep this lock while doing the actual call, because in the meanwhile
+ * another thread could request a write lock which would be a bad idea ... */
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* Forward the information to the VMM device. */
- AssertPtr(mParent);
- vmmDev = mParent->getVMMDev();
- }
+ /* Forward the information to the VMM device. */
+ AssertPtr(mParent);
+ pVMMDev = mParent->getVMMDev();
+ }
- if (vmmDev)
- {
- LogFlowFunc(("hgcmHostCall numParms=%d\n", i));
- vrc = vmmDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_CMD,
- i, paParms);
+ if (pVMMDev)
+ {
+ LogFlowFunc(("hgcmHostCall numParms=%d\n", i));
+ vrc = pVMMDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_CMD,
+ i, paParms);
+ }
+ else
+ vrc = VERR_INVALID_VM_HANDLE;
}
- else
- vrc = VERR_INVALID_VM_HANDLE;
RTMemFree(pvEnv);
}
RTStrFree(pszArgs);
}
+
if (RT_SUCCESS(vrc))
{
- LogFlowFunc(("Waiting for HGCM callback (timeout=%ldms) ...\n", aTimeoutMS));
+ LogFlowFunc(("Waiting for HGCM callback (timeout=%dms) ...\n", aTimeoutMS));
/*
* Wait for the HGCM low level callback until the process
* has been started (or something went wrong). This is necessary to
* get the PID.
*/
- CallbackMapIter it = getCtrlCallbackContextByID(uContextID);
- BOOL fCanceled = FALSE;
- if (it != mCallbackMap.end())
- {
- ComAssert(!it->second.pProgress.isNull());
-
- /*
- * Wait for the first stage (=0) to complete (that is starting the process).
- */
- PCALLBACKDATAEXECSTATUS pData = NULL;
- rc = it->second.pProgress->WaitForOperationCompletion(0, aTimeoutMS);
- if (SUCCEEDED(rc))
- {
- /* Was the operation canceled by one of the parties? */
- rc = it->second.pProgress->COMGETTER(Canceled)(&fCanceled);
- if (FAILED(rc)) throw rc;
- if (!fCanceled)
- {
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- pData = (PCALLBACKDATAEXECSTATUS)it->second.pvData;
- Assert(it->second.cbData == sizeof(CALLBACKDATAEXECSTATUS));
- AssertPtr(pData);
-
- /* Did we get some status? */
- switch (pData->u32Status)
- {
- case PROC_STS_STARTED:
- /* Process is (still) running; get PID. */
- *aPID = pData->u32PID;
- break;
-
- /* In any other case the process either already
- * terminated or something else went wrong, so no PID ... */
- case PROC_STS_TEN: /* Terminated normally. */
- case PROC_STS_TEA: /* Terminated abnormally. */
- case PROC_STS_TES: /* Terminated through signal. */
- case PROC_STS_TOK:
- case PROC_STS_TOA:
- case PROC_STS_DWN:
- /*
- * Process (already) ended, but we want to get the
- * PID anyway to retrieve the output in a later call.
- */
- *aPID = pData->u32PID;
- break;
-
- case PROC_STS_ERROR:
- vrc = pData->u32Flags; /* u32Flags member contains IPRT error code. */
- break;
-
- case PROC_STS_UNDEFINED:
- vrc = VERR_TIMEOUT; /* Operation did not complete within time. */
- break;
-
- default:
- vrc = VERR_INVALID_PARAMETER; /* Unknown status, should never happen! */
- break;
- }
- }
- else /* Operation was canceled. */
- vrc = VERR_CANCELLED;
- }
- else /* Operation did not complete within time. */
- vrc = VERR_TIMEOUT;
+ PCALLBACKDATAEXECSTATUS pExecStatus = NULL;
- /*
- * Do *not* remove the callback yet - we might wait with the IProgress object on something
- * else (like end of process) ...
- */
- if (RT_FAILURE(vrc))
+ /*
+ * Wait for the first stage (=0) to complete (that is starting the process).
+ */
+ vrc = callbackWaitForCompletion(uContextID, 0 /* Stage */, aTimeoutMS);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = callbackGetUserData(uContextID, NULL /* We know the type. */,
+ (void**)&pExecStatus, NULL /* Don't need the size. */);
+ if (RT_SUCCESS(vrc))
{
- if (vrc == VERR_FILE_NOT_FOUND) /* This is the most likely error. */
- rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
- tr("The file '%s' was not found on guest"), Utf8Command.c_str());
- else if (vrc == VERR_PATH_NOT_FOUND)
- rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
- tr("The path to file '%s' was not found on guest"), Utf8Command.c_str());
- else if (vrc == VERR_BAD_EXE_FORMAT)
- rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
- tr("The file '%s' is not an executable format on guest"), Utf8Command.c_str());
- else if (vrc == VERR_AUTHENTICATION_FAILURE)
- rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
- tr("The specified user '%s' was not able to logon on guest"), Utf8UserName.c_str());
- else if (vrc == VERR_TIMEOUT)
- rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
- tr("The guest did not respond within time (%ums)"), aTimeoutMS);
- else if (vrc == VERR_CANCELLED)
- rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
- tr("The execution operation was canceled"));
- else if (vrc == VERR_PERMISSION_DENIED)
- rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
- tr("Invalid user/password credentials"));
- else
- {
- if (pData && pData->u32Status == PROC_STS_ERROR)
- rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
- tr("Process could not be started: %Rrc"), pData->u32Flags);
- else
- rc = setErrorNoLog(E_UNEXPECTED,
- tr("The service call failed with error %Rrc"), vrc);
- }
+ rc = executeProcessResult(Utf8Command.c_str(), Utf8UserName.c_str(), aTimeoutMS,
+ pExecStatus, aPID);
+ callbackFreeUserData(pExecStatus);
}
- else /* Execution went fine. */
+ else
{
- /* Return the progress to the caller. */
- progress.queryInterfaceTo(aProgress);
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("Unable to retrieve process execution status data"));
}
}
- else /* Callback context not found; should never happen! */
- AssertMsg(it != mCallbackMap.end(), ("Callback context with ID %u not found!", uContextID));
- }
- else /* HGCM related error codes .*/
- {
- if (vrc == VERR_INVALID_VM_HANDLE)
- rc = setErrorNoLog(VBOX_E_VM_ERROR,
- tr("VMM device is not available (is the VM running?)"));
- else if (vrc == VERR_NOT_FOUND)
- rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
- tr("The guest execution service is not ready"));
- else if (vrc == VERR_HGCM_SERVICE_NOT_FOUND)
- rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
- tr("The guest execution service is not available"));
- else /* HGCM call went wrong. */
- rc = setErrorNoLog(E_UNEXPECTED,
- tr("The HGCM call failed with error %Rrc"), vrc);
+ else
+ rc = handleErrorCompletion(vrc);
+
+ /*
+ * Do *not* remove the callback yet - we might wait with the IProgress object on something
+ * else (like end of process) ...
+ */
}
+ else
+ rc = handleErrorHGCM(vrc);
for (unsigned i = 0; i < uNumArgs; i++)
RTMemFree(papszArgv[i]);
RTMemFree(papszArgv);
}
- if (RT_FAILURE(vrc))
+ if (SUCCEEDED(rc))
+ {
+ /* Return the progress to the caller. */
+ pProgress.queryInterfaceTo(aProgress);
+ }
+ else
{
if (!pRC) /* Skip logging internal calls. */
LogRel(("Executing guest process \"%s\" as user \"%s\" failed with %Rrc\n",
@@ -1836,29 +2481,23 @@ STDMETHODIMP Guest::SetProcessInput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
try
{
- /* Init. */
- *aBytesWritten = 0;
-
+ VBOXGUESTCTRL_PROCESS process;
+ int vrc = processGetByPID(aPID, &process);
+ if (RT_SUCCESS(vrc))
{
- /* Take read lock to prevent races. */
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- /* Search for existing PID. */
- GuestProcessMapIterConst itProc = getProcessByPID(aPID);
- if (itProc != mGuestProcessMap.end())
- {
- /* PID exists; check if process is still running. */
- if (itProc->second.mStatus != PROC_STS_STARTED)
- rc = setError(VBOX_E_IPRT_ERROR,
- Guest::tr("Cannot inject input to not running process (PID %u)"), aPID);
- }
- else
+ /* PID exists; check if process is still running. */
+ if (process.mStatus != ExecuteProcessStatus_Started)
rc = setError(VBOX_E_IPRT_ERROR,
- Guest::tr("Cannot inject input to non-existent process (PID %u)"), aPID);
+ Guest::tr("Cannot inject input to not running process (PID %u)"), aPID);
}
+ else
+ rc = setError(VBOX_E_IPRT_ERROR,
+ Guest::tr("Cannot inject input to non-existent process (PID %u)"), aPID);
if (SUCCEEDED(rc))
{
+ uint32_t uContextID = 0;
+
/*
* Create progress object.
* This progress object, compared to the one in executeProgress() above,
@@ -1880,51 +2519,56 @@ STDMETHODIMP Guest::SetProcessInput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
if (aTimeoutMS == 0)
aTimeoutMS = UINT32_MAX;
- PCALLBACKDATAEXECINSTATUS pData = (PCALLBACKDATAEXECINSTATUS)RTMemAlloc(sizeof(CALLBACKDATAEXECINSTATUS));
- if (NULL == pData) throw rc;
- AssertReturn(pData, VBOX_E_IPRT_ERROR);
- RT_ZERO(*pData);
+ /* Construct callback data. */
+ VBOXGUESTCTRL_CALLBACK callback;
+ callback.mType = VBOXGUESTCTRLCALLBACKTYPE_EXEC_INPUT_STATUS;
+ callback.cbData = sizeof(CALLBACKDATAEXECINSTATUS);
- /* Save PID + output flags for later use. */
- pData->u32PID = aPID;
- pData->u32Flags = aFlags;
+ PCALLBACKDATAEXECINSTATUS pStatus = (PCALLBACKDATAEXECINSTATUS)RTMemAlloc(callback.cbData);
+ AssertReturn(pStatus, VBOX_E_IPRT_ERROR);
+ RT_ZERO(*pStatus);
- /* Add job to callback contexts. */
- uint32_t uContextID = addCtrlCallbackContext(VBOXGUESTCTRLCALLBACKTYPE_EXEC_INPUT_STATUS,
- pData, sizeof(CALLBACKDATAEXECINSTATUS), pProgress);
- Assert(uContextID > 0);
+ /* Save PID + output flags for later use. */
+ pStatus->u32PID = aPID;
+ pStatus->u32Flags = aFlags;
- com::SafeArray<BYTE> sfaData(ComSafeArrayInArg(aData));
- uint32_t cbSize = sfaData.size();
+ callback.pvData = pStatus;
+ callback.pProgress = pProgress;
- VBOXHGCMSVCPARM paParms[6];
- int i = 0;
- paParms[i++].setUInt32(uContextID);
- paParms[i++].setUInt32(aPID);
- paParms[i++].setUInt32(aFlags);
- paParms[i++].setPointer(sfaData.raw(), cbSize);
- paParms[i++].setUInt32(cbSize);
+ /* Add the callback. */
+ vrc = callbackAdd(&callback, &uContextID);
+ if (RT_SUCCESS(vrc))
+ {
+ com::SafeArray<BYTE> sfaData(ComSafeArrayInArg(aData));
+ uint32_t cbSize = sfaData.size();
- int vrc = VINF_SUCCESS;
+ VBOXHGCMSVCPARM paParms[6];
+ int i = 0;
+ paParms[i++].setUInt32(uContextID);
+ paParms[i++].setUInt32(aPID);
+ paParms[i++].setUInt32(aFlags);
+ paParms[i++].setPointer(sfaData.raw(), cbSize);
+ paParms[i++].setUInt32(cbSize);
- {
- VMMDev *vmmDev;
{
- /* Make sure mParent is valid, so set the read lock while using.
- * Do not keep this lock while doing the actual call, because in the meanwhile
- * another thread could request a write lock which would be a bad idea ... */
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ VMMDev *pVMMDev = NULL;
+ {
+ /* Make sure mParent is valid, so set the read lock while using.
+ * Do not keep this lock while doing the actual call, because in the meanwhile
+ * another thread could request a write lock which would be a bad idea ... */
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* Forward the information to the VMM device. */
- AssertPtr(mParent);
- vmmDev = mParent->getVMMDev();
- }
+ /* Forward the information to the VMM device. */
+ AssertPtr(mParent);
+ pVMMDev = mParent->getVMMDev();
+ }
- if (vmmDev)
- {
- LogFlowFunc(("hgcmHostCall numParms=%d\n", i));
- vrc = vmmDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_SET_INPUT,
- i, paParms);
+ if (pVMMDev)
+ {
+ LogFlowFunc(("hgcmHostCall numParms=%d\n", i));
+ vrc = pVMMDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_SET_INPUT,
+ i, paParms);
+ }
}
}
@@ -1937,64 +2581,52 @@ STDMETHODIMP Guest::SetProcessInput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
* has been started (or something went wrong). This is necessary to
* get the PID.
*/
- CallbackMapIter it = getCtrlCallbackContextByID(uContextID);
- BOOL fCanceled = FALSE;
- if (it != mCallbackMap.end())
- {
- ComAssert(!it->second.pProgress.isNull());
-
- /* Wait until operation completed. */
- rc = it->second.pProgress->WaitForCompletion(aTimeoutMS);
- if (FAILED(rc)) throw rc;
- /* Was the operation canceled by one of the parties? */
- rc = it->second.pProgress->COMGETTER(Canceled)(&fCanceled);
- if (FAILED(rc)) throw rc;
+ PCALLBACKDATAEXECINSTATUS pExecStatusIn = NULL;
- if (!fCanceled)
+ /*
+ * Wait for the first stage (=0) to complete (that is starting the process).
+ */
+ vrc = callbackWaitForCompletion(uContextID, 0 /* Stage */, aTimeoutMS);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = callbackGetUserData(uContextID, NULL /* We know the type. */,
+ (void**)&pExecStatusIn, NULL /* Don't need the size. */);
+ if (RT_SUCCESS(vrc))
{
- BOOL fCompleted;
- if ( SUCCEEDED(it->second.pProgress->COMGETTER(Completed)(&fCompleted))
- && fCompleted)
+ switch (pExecStatusIn->u32Status)
{
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- PCALLBACKDATAEXECINSTATUS pStatusData = (PCALLBACKDATAEXECINSTATUS)it->second.pvData;
- AssertPtr(pStatusData);
- Assert(it->second.cbData == sizeof(CALLBACKDATAEXECINSTATUS));
-
- switch (pStatusData->u32Status)
- {
- case INPUT_STS_WRITTEN:
- *aBytesWritten = pStatusData->cbProcessed;
- break;
+ case INPUT_STS_WRITTEN:
+ *aBytesWritten = pExecStatusIn->cbProcessed;
+ break;
- default:
- rc = setError(VBOX_E_IPRT_ERROR,
- tr("Client error %u while processing input data"), pStatusData->u32Status);
- break;
- }
+ default:
+ rc = setError(VBOX_E_IPRT_ERROR,
+ tr("Client error %u while processing input data"), pExecStatusIn->u32Status);
+ break;
}
- else
- rc = setError(VBOX_E_IPRT_ERROR,
- tr("The input operation was not acknowledged from guest within time (%ums)"), aTimeoutMS);
+
+ callbackFreeUserData(pExecStatusIn);
}
else
- rc = setError(VBOX_E_IPRT_ERROR,
- tr("The input operation was canceled by the guest"));
{
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* Destroy locally used progress object. */
- destroyCtrlCallbackContext(it);
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("Unable to retrieve process input status data"));
}
}
- else /* PID lookup failed. */
- rc = setError(VBOX_E_IPRT_ERROR,
- tr("Process (PID %u) not found"), aPID);
+ else
+ rc = handleErrorCompletion(vrc);
+ }
+ else
+ rc = handleErrorHGCM(vrc);
+
+ if (SUCCEEDED(rc))
+ {
+ /* Nothing to do here yet. */
}
- else /* HGCM operation failed. */
- rc = setError(E_UNEXPECTED,
- tr("The HGCM call failed (%Rrc)"), vrc);
+
+ /* The callback isn't needed anymore -- just was kept locally. */
+ callbackDestroy(uContextID);
/* Cleanup. */
if (!pProgress.isNull())
@@ -2022,8 +2654,15 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
CheckComArgExpr(aPID, aPID > 0);
if (aSize < 0)
return setError(E_INVALIDARG, tr("The size argument (%lld) is negative"), aSize);
- if (aFlags != 0) /* Flags are not supported at the moment. */
- return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags);
+ if (aSize == 0)
+ return setError(E_INVALIDARG, tr("The size (%lld) is zero"), aSize);
+ if (aFlags)
+ {
+ if (!(aFlags & ProcessOutputFlag_StdErr))
+ {
+ return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags);
+ }
+ }
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -2032,178 +2671,159 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
try
{
- /*
- * Create progress object.
- * This progress object, compared to the one in executeProgress() above
- * is only local and is used to determine whether the operation finished
- * or got canceled.
- */
- ComObjPtr <Progress> progress;
- rc = progress.createObject();
+ VBOXGUESTCTRL_PROCESS process;
+ int vrc = processGetByPID(aPID, &process);
+ if (RT_FAILURE(vrc))
+ rc = setError(VBOX_E_IPRT_ERROR,
+ Guest::tr("Cannot get output from non-existent process (PID %u)"), aPID);
+
if (SUCCEEDED(rc))
{
- rc = progress->init(static_cast<IGuest*>(this),
- Bstr(tr("Getting output of process")).raw(),
- TRUE /* Cancelable */);
- }
- if (FAILED(rc)) return rc;
+ uint32_t uContextID = 0;
- /* Adjust timeout. */
- if (aTimeoutMS == 0)
- aTimeoutMS = UINT32_MAX;
+ /*
+ * Create progress object.
+ * This progress object, compared to the one in executeProgress() above,
+ * is only single-stage local and is used to determine whether the operation
+ * finished or got canceled.
+ */
+ ComObjPtr <Progress> pProgress;
+ rc = pProgress.createObject();
+ if (SUCCEEDED(rc))
+ {
+ rc = pProgress->init(static_cast<IGuest*>(this),
+ Bstr(tr("Setting input for process")).raw(),
+ TRUE /* Cancelable */);
+ }
+ if (FAILED(rc)) throw rc;
+ ComAssert(!pProgress.isNull());
- /* Search for existing PID. */
- PCALLBACKDATAEXECOUT pData = (CALLBACKDATAEXECOUT*)RTMemAlloc(sizeof(CALLBACKDATAEXECOUT));
- AssertReturn(pData, VBOX_E_IPRT_ERROR);
- RT_ZERO(*pData);
- /* Save PID + output flags for later use. */
- pData->u32PID = aPID;
- pData->u32Flags = aFlags;
- /* Add job to callback contexts. */
- uint32_t uContextID = addCtrlCallbackContext(VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT,
- pData, sizeof(CALLBACKDATAEXECOUT), progress);
- Assert(uContextID > 0);
-
- com::SafeArray<BYTE> outputData((size_t)aSize);
-
- VBOXHGCMSVCPARM paParms[5];
- int i = 0;
- paParms[i++].setUInt32(uContextID);
- paParms[i++].setUInt32(aPID);
- paParms[i++].setUInt32(aFlags); /** @todo Should represent stdout and/or stderr. */
+ /* Adjust timeout. */
+ if (aTimeoutMS == 0)
+ aTimeoutMS = UINT32_MAX;
- int vrc = VINF_SUCCESS;
+ /* Set handle ID. */
+ uint32_t uHandleID = OUTPUT_HANDLE_ID_STDOUT; /* Default */
+ if (aFlags & ProcessOutputFlag_StdErr)
+ uHandleID = OUTPUT_HANDLE_ID_STDERR;
- {
- VMMDev *vmmDev;
- {
- /* Make sure mParent is valid, so set the read lock while using.
- * Do not keep this lock while doing the actual call, because in the meanwhile
- * another thread could request a write lock which would be a bad idea ... */
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- /* Forward the information to the VMM device. */
- AssertPtr(mParent);
- vmmDev = mParent->getVMMDev();
- }
+ /* Construct callback data. */
+ VBOXGUESTCTRL_CALLBACK callback;
+ callback.mType = VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT;
+ callback.cbData = sizeof(CALLBACKDATAEXECOUT);
+
+ PCALLBACKDATAEXECOUT pStatus = (PCALLBACKDATAEXECOUT)RTMemAlloc(callback.cbData);
+ AssertReturn(pStatus, VBOX_E_IPRT_ERROR);
+ RT_ZERO(*pStatus);
+
+ /* Save PID + output flags for later use. */
+ pStatus->u32PID = aPID;
+ pStatus->u32Flags = aFlags;
- if (vmmDev)
+ callback.pvData = pStatus;
+ callback.pProgress = pProgress;
+
+ /* Add the callback. */
+ vrc = callbackAdd(&callback, &uContextID);
+ if (RT_SUCCESS(vrc))
{
- LogFlowFunc(("hgcmHostCall numParms=%d\n", i));
- vrc = vmmDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_GET_OUTPUT,
- i, paParms);
- }
- }
+ VBOXHGCMSVCPARM paParms[5];
+ int i = 0;
+ paParms[i++].setUInt32(uContextID);
+ paParms[i++].setUInt32(aPID);
+ paParms[i++].setUInt32(uHandleID);
+ paParms[i++].setUInt32(0 /* Flags, none set yet */);
+
+ VMMDev *pVMMDev = NULL;
+ {
+ /* Make sure mParent is valid, so set the read lock while using.
+ * Do not keep this lock while doing the actual call, because in the meanwhile
+ * another thread could request a write lock which would be a bad idea ... */
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- if (RT_SUCCESS(vrc))
- {
- LogFlowFunc(("Waiting for HGCM callback (timeout=%ldms) ...\n", aTimeoutMS));
+ /* Forward the information to the VMM device. */
+ AssertPtr(mParent);
+ pVMMDev = mParent->getVMMDev();
+ }
- /*
- * Wait for the HGCM low level callback until the process
- * has been started (or something went wrong). This is necessary to
- * get the PID.
- */
- CallbackMapIter it = getCtrlCallbackContextByID(uContextID);
- BOOL fCanceled = FALSE;
- if (it != mCallbackMap.end())
+ if (pVMMDev)
+ {
+ LogFlowFunc(("hgcmHostCall numParms=%d\n", i));
+ vrc = pVMMDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_GET_OUTPUT,
+ i, paParms);
+ }
+ }
+
+ if (RT_SUCCESS(vrc))
{
- ComAssert(!it->second.pProgress.isNull());
+ LogFlowFunc(("Waiting for HGCM callback (timeout=%dms) ...\n", aTimeoutMS));
- /* Wait until operation completed. */
- rc = it->second.pProgress->WaitForCompletion(aTimeoutMS);
- if (FAILED(rc)) throw rc;
+ /*
+ * Wait for the HGCM low level callback until the process
+ * has been started (or something went wrong). This is necessary to
+ * get the PID.
+ */
- /* Was the operation canceled by one of the parties? */
- rc = it->second.pProgress->COMGETTER(Canceled)(&fCanceled);
- if (FAILED(rc)) throw rc;
+ PCALLBACKDATAEXECOUT pExecOut = NULL;
- if (!fCanceled)
+ /*
+ * Wait for the first stage (=0) to complete (that is starting the process).
+ */
+ vrc = callbackWaitForCompletion(uContextID, 0 /* Stage */, aTimeoutMS);
+ if (RT_SUCCESS(vrc))
{
- BOOL fCompleted;
- if ( SUCCEEDED(it->second.pProgress->COMGETTER(Completed)(&fCompleted))
- && fCompleted)
+ vrc = callbackGetUserData(uContextID, NULL /* We know the type. */,
+ (void**)&pExecOut, NULL /* Don't need the size. */);
+ if (RT_SUCCESS(vrc))
{
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- /* Did we get some output? */
- pData = (PCALLBACKDATAEXECOUT)it->second.pvData;
- Assert(it->second.cbData == sizeof(CALLBACKDATAEXECOUT));
- AssertPtr(pData);
+ com::SafeArray<BYTE> outputData((size_t)aSize);
- if (pData->cbData)
+ if (pExecOut->cbData)
{
/* Do we need to resize the array? */
- if (pData->cbData > aSize)
- outputData.resize(pData->cbData);
+ if (pExecOut->cbData > aSize)
+ outputData.resize(pExecOut->cbData);
/* Fill output in supplied out buffer. */
- memcpy(outputData.raw(), pData->pvData, pData->cbData);
- outputData.resize(pData->cbData); /* Shrink to fit actual buffer size. */
+ memcpy(outputData.raw(), pExecOut->pvData, pExecOut->cbData);
+ outputData.resize(pExecOut->cbData); /* Shrink to fit actual buffer size. */
}
else
{
- /* No data within specified timeout available. Use a special
- * error so that we can gently handle that case a bit below. */
- vrc = VERR_NO_DATA;
+ /* No data within specified timeout available. */
+ outputData.resize(0);
}
- }
- else /* If callback not called within time ... well, that's a timeout! */
- vrc = VERR_TIMEOUT;
- }
- else /* Operation was canceled. */
- {
- vrc = VERR_CANCELLED;
- }
- if (RT_FAILURE(vrc))
- {
- if (vrc == VERR_NO_DATA)
- {
- /* If there was no output data then this is no error we want
- * to report to COM. The caller just gets back a size of 0 (zero). */
- rc = S_OK;
- }
- else if (vrc == VERR_TIMEOUT)
- {
- rc = setError(VBOX_E_IPRT_ERROR,
- tr("The guest did not output within time (%ums)"), aTimeoutMS);
- }
- else if (vrc == VERR_CANCELLED)
- {
- rc = setError(VBOX_E_IPRT_ERROR,
- tr("The output operation was canceled"));
+ /* Detach output buffer to output argument. */
+ outputData.detachTo(ComSafeArrayOutArg(aData));
+
+ callbackFreeUserData(pExecOut);
}
else
{
- rc = setError(E_UNEXPECTED,
- tr("The service call failed with error %Rrc"), vrc);
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("Unable to retrieve process output data"));
}
}
+ else
+ rc = handleErrorCompletion(vrc);
+ }
+ else
+ rc = handleErrorHGCM(vrc);
+
+ if (SUCCEEDED(rc))
+ {
- {
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* Destroy locally used progress object. */
- destroyCtrlCallbackContext(it);
- }
}
- else /* PID lookup failed. */
- rc = setError(VBOX_E_IPRT_ERROR,
- tr("Process (PID %u) not found!"), aPID);
+
+ /* The callback isn't needed anymore -- just was kept locally. */
+ callbackDestroy(uContextID);
+
+ /* Cleanup. */
+ if (!pProgress.isNull())
+ pProgress->uninit();
+ pProgress.setNull();
}
- else /* HGCM operation failed. */
- rc = setError(E_UNEXPECTED,
- tr("The HGCM call failed with error %Rrc"), vrc);
-
- /* Cleanup. */
- progress->uninit();
- progress.setNull();
-
- /* If something failed (or there simply was no data, indicated by VERR_NO_DATA,
- * we return an empty array so that the frontend knows when to give up. */
- if (RT_FAILURE(vrc) || FAILED(rc))
- outputData.resize(0);
- outputData.detachTo(ComSafeArrayOutArg(aData));
}
catch (std::bad_alloc &)
{
@@ -2213,12 +2833,14 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
#endif
}
-STDMETHODIMP Guest::GetProcessStatus(ULONG aPID, ULONG *aExitCode, ULONG *aFlags, ULONG *aStatus)
+STDMETHODIMP Guest::GetProcessStatus(ULONG aPID, ULONG *aExitCode, ULONG *aFlags, ExecuteProcessStatus_T *aStatus)
{
#ifndef VBOX_WITH_GUEST_CONTROL
ReturnComNotImplemented();
#else /* VBOX_WITH_GUEST_CONTROL */
- using namespace guestControl;
+ CheckComArgNotNull(aExitCode);
+ CheckComArgNotNull(aFlags);
+ CheckComArgNotNull(aStatus);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -2227,14 +2849,13 @@ STDMETHODIMP Guest::GetProcessStatus(ULONG aPID, ULONG *aExitCode, ULONG *aFlags
try
{
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- GuestProcessMapIterConst it = getProcessByPID(aPID);
- if (it != mGuestProcessMap.end())
+ VBOXGUESTCTRL_PROCESS process;
+ int vrc = processGetByPID(aPID, &process);
+ if (RT_SUCCESS(vrc))
{
- *aExitCode = it->second.mExitCode;
- *aFlags = it->second.mFlags;
- *aStatus = it->second.mStatus;
+ *aExitCode = process.mExitCode;
+ *aFlags = process.mFlags;
+ *aStatus = process.mStatus;
}
else
rc = setError(VBOX_E_IPRT_ERROR,
@@ -2248,6 +2869,13 @@ STDMETHODIMP Guest::GetProcessStatus(ULONG aPID, ULONG *aExitCode, ULONG *aFlags
#endif
}
+STDMETHODIMP Guest::CopyFromGuest(IN_BSTR aSource, IN_BSTR aDest,
+ IN_BSTR aUserName, IN_BSTR aPassword,
+ ULONG aFlags, IProgress **aProgress)
+{
+ ReturnComNotImplemented();
+}
+
STDMETHODIMP Guest::CopyToGuest(IN_BSTR aSource, IN_BSTR aDest,
IN_BSTR aUserName, IN_BSTR aPassword,
ULONG aFlags, IProgress **aProgress)
@@ -2286,12 +2914,12 @@ STDMETHODIMP Guest::CopyToGuest(IN_BSTR aSource, IN_BSTR aDest,
progress.createObject();
rc = progress->init(static_cast<IGuest*>(this),
- Bstr(tr("Copying file")).raw(),
+ Bstr(tr("Copying file from host to guest")).raw(),
TRUE /* aCancelable */);
if (FAILED(rc)) throw rc;
/* Initialize our worker task. */
- TaskGuest *pTask = new TaskGuest(TaskGuest::CopyFile, this, progress);
+ TaskGuest *pTask = new TaskGuest(TaskGuest::CopyFileToGuest, this, progress);
AssertPtr(pTask);
std::auto_ptr<TaskGuest> task(pTask);
@@ -2323,10 +2951,14 @@ STDMETHODIMP Guest::CopyToGuest(IN_BSTR aSource, IN_BSTR aDest,
#endif /* VBOX_WITH_GUEST_CONTROL */
}
-STDMETHODIMP Guest::CreateDirectory(IN_BSTR aDirectory,
+STDMETHODIMP Guest::DirectoryClose(ULONG aHandle)
+{
+ ReturnComNotImplemented();
+}
+
+STDMETHODIMP Guest::DirectoryCreate(IN_BSTR aDirectory,
IN_BSTR aUserName, IN_BSTR aPassword,
- ULONG aMode, ULONG aFlags,
- IProgress **aProgress)
+ ULONG aMode, ULONG aFlags)
{
#ifndef VBOX_WITH_GUEST_CONTROL
ReturnComNotImplemented();
@@ -2342,16 +2974,15 @@ STDMETHODIMP Guest::CreateDirectory(IN_BSTR aDirectory,
LogRel(("Creating guest directory \"%s\" as user \"%s\" ...\n",
Utf8Str(aDirectory).c_str(), Utf8Str(aUserName).c_str()));
- return createDirectoryInternal(aDirectory,
+ return directoryCreateInternal(aDirectory,
aUserName, aPassword,
- aMode, aFlags, aProgress, NULL /* rc */);
+ aMode, aFlags, NULL /* rc */);
#endif
}
-HRESULT Guest::createDirectoryInternal(IN_BSTR aDirectory,
+HRESULT Guest::directoryCreateInternal(IN_BSTR aDirectory,
IN_BSTR aUserName, IN_BSTR aPassword,
- ULONG aMode, ULONG aFlags,
- IProgress **aProgress, int *pRC)
+ ULONG aMode, ULONG aFlags, int *pRC)
{
#ifndef VBOX_WITH_GUEST_CONTROL
ReturnComNotImplemented();
@@ -2359,26 +2990,19 @@ HRESULT Guest::createDirectoryInternal(IN_BSTR aDirectory,
using namespace guestControl;
CheckComArgStrNotEmptyOrNull(aDirectory);
- CheckComArgOutPointerValid(aProgress);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
/* Validate flags. */
- if (aFlags != CreateDirectoryFlag_None)
+ if (aFlags != DirectoryCreateFlag_None)
{
- if (!(aFlags & CreateDirectoryFlag_Parents))
+ if (!(aFlags & DirectoryCreateFlag_Parents))
{
return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags);
}
}
- /**
- * @todo We return a progress object because we maybe later want to
- * process more than one directory (or somewhat lengthly operations)
- * that require having a progress object provided to the caller.
- */
-
HRESULT rc = S_OK;
try
{
@@ -2392,7 +3016,7 @@ HRESULT Guest::createDirectoryInternal(IN_BSTR aDirectory,
/*
* Prepare tool command line.
*/
- if (aFlags & CreateDirectoryFlag_Parents)
+ if (aFlags & DirectoryCreateFlag_Parents)
args.push_back(Bstr("--parents").raw()); /* We also want to create the parent directories. */
if (aMode > 0)
{
@@ -2424,59 +3048,34 @@ HRESULT Guest::createDirectoryInternal(IN_BSTR aDirectory,
if (SUCCEEDED(rc))
{
/* Wait for process to exit ... */
+ rc = progressExec->WaitForCompletion(-1);
+ if (FAILED(rc)) return rc;
+
BOOL fCompleted = FALSE;
BOOL fCanceled = FALSE;
-
- while ( SUCCEEDED(progressExec->COMGETTER(Completed(&fCompleted)))
- && !fCompleted)
- {
- /* Progress canceled by Main API? */
- if ( SUCCEEDED(progressExec->COMGETTER(Canceled(&fCanceled)))
- && fCanceled)
- {
- break;
- }
- }
-
- ComObjPtr<Progress> progressCreate;
- rc = progressCreate.createObject();
- if (SUCCEEDED(rc))
- {
- rc = progressCreate->init(static_cast<IGuest*>(this),
- Bstr(tr("Creating directory")).raw(),
- TRUE);
- }
- if (FAILED(rc)) return rc;
+ progressExec->COMGETTER(Completed)(&fCompleted);
+ if (!fCompleted)
+ progressExec->COMGETTER(Canceled)(&fCanceled);
if (fCompleted)
{
- ULONG uRetStatus, uRetExitCode, uRetFlags;
+ ExecuteProcessStatus_T retStatus;
+ ULONG uRetExitCode, uRetFlags;
if (SUCCEEDED(rc))
{
- rc = GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &uRetStatus);
+ rc = GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &retStatus);
if (SUCCEEDED(rc) && uRetExitCode != 0)
{
rc = setError(VBOX_E_IPRT_ERROR,
- tr("Error %u while creating directory"), uRetExitCode);
+ tr("Error %u while creating guest directory"), uRetExitCode);
}
}
}
else if (fCanceled)
rc = setError(VBOX_E_IPRT_ERROR,
- tr("Directory creation was aborted"));
+ tr("Guest directory creation was aborted"));
else
- AssertReleaseMsgFailed(("Directory creation neither completed nor canceled!?"));
-
- if (SUCCEEDED(rc))
- progressCreate->notifyComplete(S_OK);
- else
- progressCreate->notifyComplete(VBOX_E_IPRT_ERROR,
- COM_IIDOF(IGuest),
- Guest::getStaticComponentName(),
- Guest::tr("Error while executing creation command"));
-
- /* Return the progress to the caller. */
- progressCreate.queryInterfaceTo(aProgress);
+ AssertReleaseMsgFailed(("Guest directory creation neither completed nor canceled!?\n"));
}
}
catch (std::bad_alloc &)
@@ -2487,6 +3086,40 @@ HRESULT Guest::createDirectoryInternal(IN_BSTR aDirectory,
#endif /* VBOX_WITH_GUEST_CONTROL */
}
+STDMETHODIMP Guest::DirectoryOpen(IN_BSTR aDirectory, IN_BSTR aFilter,
+ ULONG aFlags, IN_BSTR aUserName, IN_BSTR aPassword,
+ ULONG *aHandle)
+{
+ ReturnComNotImplemented();
+}
+
+STDMETHODIMP Guest::DirectoryRead(ULONG aHandle, IGuestDirEntry **aDirEntry)
+{
+ ReturnComNotImplemented();
+}
+
+STDMETHODIMP Guest::FileExists(IN_BSTR aFile, IN_BSTR aUserName, IN_BSTR aPassword, BOOL *aExists)
+{
+#ifndef VBOX_WITH_GUEST_CONTROL
+ ReturnComNotImplemented();
+#else /* VBOX_WITH_GUEST_CONTROL */
+ using namespace guestControl;
+
+ return VBOX_E_NOT_SUPPORTED;
+#endif
+}
+
+STDMETHODIMP Guest::FileQuerySize(IN_BSTR aFile, IN_BSTR aUserName, IN_BSTR aPassword, LONG64 *aSize)
+{
+#ifndef VBOX_WITH_GUEST_CONTROL
+ ReturnComNotImplemented();
+#else /* VBOX_WITH_GUEST_CONTROL */
+ using namespace guestControl;
+
+ return VBOX_E_NOT_SUPPORTED;
+#endif
+}
+
STDMETHODIMP Guest::UpdateGuestAdditions(IN_BSTR aSource, ULONG aFlags, IProgress **aProgress)
{
#ifndef VBOX_WITH_GUEST_CONTROL
diff --git a/src/VBox/Main/src-client/GuestImpl.cpp b/src/VBox/Main/src-client/GuestImpl.cpp
index 5ce6e7e10..467036834 100644
--- a/src/VBox/Main/src-client/GuestImpl.cpp
+++ b/src/VBox/Main/src-client/GuestImpl.cpp
@@ -1,10 +1,10 @@
-/* $Id: GuestImpl.cpp $ */
+/* $Id: GuestImpl.cpp 37930 2011-07-13 19:56:55Z vboxsync $ */
/** @file
* VirtualBox COM class implementation: Guest
*/
/*
- * 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;
@@ -43,12 +43,13 @@ DEFINE_EMPTY_CTOR_DTOR (Guest)
HRESULT Guest::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void Guest::FinalRelease()
{
uninit ();
+ BaseFinalRelease();
}
// public methods only for internal purposes
@@ -121,7 +122,7 @@ void Guest::uninit()
/* Clean up callback data. */
CallbackMapIter it;
for (it = mCallbackMap.begin(); it != mCallbackMap.end(); it++)
- destroyCtrlCallbackContext(it);
+ callbackDestroy(it->first);
/* Clear process map. */
mGuestProcessMap.clear();
@@ -235,30 +236,17 @@ STDMETHODIMP Guest::COMGETTER(AdditionsVersion) (BSTR *aAdditionsVersion)
return hr;
}
-STDMETHODIMP Guest::COMGETTER(SupportsSeamless) (BOOL *aSupportsSeamless)
+STDMETHODIMP Guest::COMGETTER(Facilities)(ComSafeArrayOut(IAdditionsFacility*, aFacilities))
{
- CheckComArgOutPointerValid(aSupportsSeamless);
+ CheckComArgOutPointerValid(aFacilities);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- *aSupportsSeamless = mData.mSupportsSeamless;
-
- return S_OK;
-}
-
-STDMETHODIMP Guest::COMGETTER(SupportsGraphics) (BOOL *aSupportsGraphics)
-{
- CheckComArgOutPointerValid(aSupportsGraphics);
-
- AutoCaller autoCaller(this);
- if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- *aSupportsGraphics = mData.mSupportsGraphics;
+ SafeIfaceArray<IAdditionsFacility> fac(mData.mFacilityMap);
+ fac.detachTo(ComSafeArrayOutArg(aFacilities));
return S_OK;
}
@@ -273,7 +261,7 @@ BOOL Guest::isPageFusionEnabled()
return mfPageFusionEnabled;
}
-STDMETHODIMP Guest::COMGETTER(MemoryBalloonSize) (ULONG *aMemoryBalloonSize)
+STDMETHODIMP Guest::COMGETTER(MemoryBalloonSize)(ULONG *aMemoryBalloonSize)
{
CheckComArgOutPointerValid(aMemoryBalloonSize);
@@ -287,7 +275,7 @@ STDMETHODIMP Guest::COMGETTER(MemoryBalloonSize) (ULONG *aMemoryBalloonSize)
return S_OK;
}
-STDMETHODIMP Guest::COMSETTER(MemoryBalloonSize) (ULONG aMemoryBalloonSize)
+STDMETHODIMP Guest::COMSETTER(MemoryBalloonSize)(ULONG aMemoryBalloonSize)
{
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -394,7 +382,7 @@ STDMETHODIMP Guest::InternalGetStatistics(ULONG *aCpuUser, ULONG *aCpuKernel, UL
{
uint64_t uFreeTotal, uAllocTotal, uBalloonedTotal, uSharedTotal;
*aMemFreeTotal = 0;
- int rc = PGMR3QueryVMMMemoryStats(pVM.raw(), &uAllocTotal, &uFreeTotal, &uBalloonedTotal, &uSharedTotal);
+ int rc = PGMR3QueryGlobalMemoryStats(pVM.raw(), &uAllocTotal, &uFreeTotal, &uBalloonedTotal, &uSharedTotal);
AssertRC(rc);
if (rc == VINF_SUCCESS)
{
@@ -403,6 +391,8 @@ STDMETHODIMP Guest::InternalGetStatistics(ULONG *aCpuUser, ULONG *aCpuKernel, UL
*aMemBalloonTotal = (ULONG)(uBalloonedTotal / _1K);
*aMemSharedTotal = (ULONG)(uSharedTotal / _1K);
}
+ else
+ return E_FAIL;
/* Query the missing per-VM memory statistics. */
*aMemShared = 0;
@@ -412,11 +402,17 @@ STDMETHODIMP Guest::InternalGetStatistics(ULONG *aCpuUser, ULONG *aCpuKernel, UL
{
*aMemShared = (ULONG)(uSharedMem / _1K);
}
+ else
+ return E_FAIL;
}
else
{
- *aMemFreeTotal = 0;
- *aMemShared = 0;
+ *aMemAllocTotal = 0;
+ *aMemFreeTotal = 0;
+ *aMemBalloonTotal = 0;
+ *aMemSharedTotal = 0;
+ *aMemShared = 0;
+ return E_FAIL;
}
return S_OK;
@@ -436,6 +432,45 @@ HRESULT Guest::setStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal)
return S_OK;
}
+/**
+ * Returns the status of a specified Guest Additions facility.
+ *
+ * @return aStatus Current status of specified facility.
+ * @param aType Facility to get the status from.
+ * @param aTimestamp Timestamp of last facility status update in ms (optional).
+ */
+STDMETHODIMP Guest::GetFacilityStatus(AdditionsFacilityType_T aType, LONG64 *aTimestamp, AdditionsFacilityStatus_T *aStatus)
+{
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ CheckComArgNotNull(aStatus);
+ /* Not checking for aTimestamp is intentional; it's optional. */
+
+ FacilityMapIterConst it = mData.mFacilityMap.find(aType);
+ if (it != mData.mFacilityMap.end())
+ {
+ AdditionsFacility *pFacility = it->second;
+ ComAssert(pFacility);
+ *aStatus = pFacility->getStatus();
+ if (aTimestamp)
+ *aTimestamp = pFacility->getLastUpdated();
+ }
+ else
+ {
+ /*
+ * Do not fail here -- could be that the facility never has been brought up (yet) but
+ * the host wants to have its status anyway. So just tell we don't know at this point.
+ */
+ *aStatus = AdditionsFacilityStatus_Unknown;
+ if (aTimestamp)
+ *aTimestamp = RTTimeMilliTS();
+ }
+ return S_OK;
+}
+
STDMETHODIMP Guest::GetAdditionsStatus(AdditionsRunLevelType_T aLevel, BOOL *aActive)
{
AutoCaller autoCaller(this);
@@ -541,15 +576,25 @@ void Guest::setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType)
if (aInterfaceVersion.isEmpty())
mData.mAdditionsRunLevel = AdditionsRunLevelType_None;
else
+ {
mData.mAdditionsRunLevel = AdditionsRunLevelType_System;
+
+ /*
+ * To keep it compatible with the old Guest Additions behavior we need to set the
+ * "graphics" (feature) facility to active as soon as we got the Guest Additions
+ * interface version.
+ */
+ facilityUpdate(VBoxGuestFacilityType_Graphics, VBoxGuestFacilityStatus_Active);
+ }
}
/*
* Older Additions didn't have this finer grained capability bit,
- * so enable it by default. Newer Additions will not enable this here
+ * so enable it by default. Newer Additions will not enable this here
* and use the setSupportedFeatures function instead.
*/
- mData.mSupportsGraphics = mData.mAdditionsRunLevel > AdditionsRunLevelType_None;
+ facilityUpdate(VBoxGuestFacilityType_Graphics, facilityIsActive(VBoxGuestFacilityType_VBoxGuestDriver) ?
+ VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive);
/*
* Note! There is a race going on between setting mAdditionsRunLevel and
@@ -583,66 +628,126 @@ void Guest::setAdditionsInfo2(Bstr aAdditionsVersion, Bstr aVersionName, Bstr aR
mData.mAdditionsVersion = aAdditionsVersion;
}
+bool Guest::facilityIsActive(VBoxGuestFacilityType enmFacility)
+{
+ Assert(enmFacility < INT32_MAX);
+ FacilityMapIterConst it = mData.mFacilityMap.find((AdditionsFacilityType_T)enmFacility);
+ if (it != mData.mFacilityMap.end())
+ {
+ AdditionsFacility *pFac = it->second;
+ return (pFac->getStatus() == AdditionsFacilityStatus_Active);
+ }
+ return false;
+}
+
+HRESULT Guest::facilityUpdate(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus)
+{
+ ComAssertRet(enmFacility < INT32_MAX, E_INVALIDARG);
+
+ HRESULT rc;
+ RTTIMESPEC tsNow;
+ RTTimeNow(&tsNow);
+
+ FacilityMapIter it = mData.mFacilityMap.find((AdditionsFacilityType_T)enmFacility);
+ if (it != mData.mFacilityMap.end())
+ {
+ AdditionsFacility *pFac = it->second;
+ rc = pFac->update((AdditionsFacilityStatus_T)enmStatus, tsNow);
+ }
+ 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));
+ }
+
+ LogFlowFunc(("Returned with rc=%Rrc\n"));
+ return rc;
+}
+
/**
* Sets the status of a certain Guest Additions facility.
* Gets called by vmmdevUpdateGuestStatus.
*
- * @param Facility
- * @param Status
- * @param ulFlags
+ * @param enmFacility Facility to set the status for.
+ * @param enmStatus Actual status to set.
+ * @param aFlags
*/
-void Guest::setAdditionsStatus(VBoxGuestStatusFacility Facility, VBoxGuestStatusCurrent Status, ULONG ulFlags)
+void Guest::setAdditionsStatus(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus, ULONG aFlags)
{
AutoCaller autoCaller(this);
AssertComRCReturnVoid(autoCaller.rc());
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- uint32_t uCurFacility = Facility + (Status == VBoxGuestStatusCurrent_Active ? 0 : -1);
+ /*
+ * Set overall additions run level.
+ */
/* First check for disabled status. */
- if ( Facility < VBoxGuestStatusFacility_VBoxGuestDriver
- || ( Facility == VBoxGuestStatusFacility_All
- && ( Status == VBoxGuestStatusCurrent_Inactive
- || Status == VBoxGuestStatusCurrent_Disabled
- )
- )
+ 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 >= VBoxGuestStatusFacility_VBoxTray)
+ else if (uCurFacility >= VBoxGuestFacilityType_VBoxTrayClient)
{
mData.mAdditionsRunLevel = AdditionsRunLevelType_Desktop;
}
- else if (uCurFacility >= VBoxGuestStatusFacility_VBoxService)
+ else if (uCurFacility >= VBoxGuestFacilityType_VBoxService)
{
mData.mAdditionsRunLevel = AdditionsRunLevelType_Userland;
}
- else if (uCurFacility >= VBoxGuestStatusFacility_VBoxGuestDriver)
+ else if (uCurFacility >= VBoxGuestFacilityType_VBoxGuestDriver)
{
mData.mAdditionsRunLevel = AdditionsRunLevelType_System;
}
else /* Should never happen! */
- AssertMsgFailed(("Invalid facility status/run level detected! uCurFacility=%ld\n", uCurFacility));
+ 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);
+ }
}
/**
* Sets the supported features (and whether they are active or not).
*
* @param fCaps Guest capability bit mask (VMMDEV_GUEST_SUPPORTS_XXX).
- * @param fActive No idea what this is supposed to be, it's always 0 and
- * not references by this method.
*/
-void Guest::setSupportedFeatures(uint32_t fCaps, uint32_t fActive)
+void Guest::setSupportedFeatures(uint32_t aCaps)
{
AutoCaller autoCaller(this);
AssertComRCReturnVoid(autoCaller.rc());
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- mData.mSupportsSeamless = (fCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS);
+ facilityUpdate(VBoxGuestFacilityType_Seamless, aCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS ?
+ VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive);
/** @todo Add VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING */
- mData.mSupportsGraphics = (fCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS);
+ facilityUpdate(VBoxGuestFacilityType_Graphics, aCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS ?
+ VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive);
}
/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/src-client/HGCMObjects.cpp b/src/VBox/Main/src-client/HGCMObjects.cpp
index 76de0e72e..c4e01791e 100644
--- a/src/VBox/Main/src-client/HGCMObjects.cpp
+++ b/src/VBox/Main/src-client/HGCMObjects.cpp
@@ -1,4 +1,4 @@
-/* $Id: HGCMObjects.cpp $ */
+/* $Id: HGCMObjects.cpp 35374 2010-12-30 14:42:15Z vboxsync $ */
/** @file
* HGCMObjects - Host-Guest Communication Manager objects
*/
diff --git a/src/VBox/Main/src-client/HGCMThread.cpp b/src/VBox/Main/src-client/HGCMThread.cpp
index 49c3db18e..dfab76ebc 100644
--- a/src/VBox/Main/src-client/HGCMThread.cpp
+++ b/src/VBox/Main/src-client/HGCMThread.cpp
@@ -1,4 +1,4 @@
-/* $Id: HGCMThread.cpp $ */
+/* $Id: HGCMThread.cpp 35909 2011-02-09 11:50:02Z vboxsync $ */
/** @file
* HGCMThread - Host-Guest Communication Manager Threads
*/
diff --git a/src/VBox/Main/src-client/KeyboardImpl.cpp b/src/VBox/Main/src-client/KeyboardImpl.cpp
index f2cddae87..f90414799 100644
--- a/src/VBox/Main/src-client/KeyboardImpl.cpp
+++ b/src/VBox/Main/src-client/KeyboardImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: KeyboardImpl.cpp $ */
+/* $Id: KeyboardImpl.cpp 36724 2011-04-19 08:57:30Z vboxsync $ */
/** @file
* VirtualBox COM class implementation
*/
@@ -81,12 +81,13 @@ HRESULT Keyboard::FinalConstruct()
RT_ZERO(mpDrv);
mpVMMDev = NULL;
mfVMMDevInited = false;
- return S_OK;
+ return BaseFinalConstruct();
}
void Keyboard::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public methods
@@ -239,14 +240,16 @@ STDMETHODIMP Keyboard::PutScancodes(ComSafeArrayIn(LONG, scancodes),
*/
STDMETHODIMP Keyboard::PutCAD()
{
- static com::SafeArray<LONG> cadSequence(6);
+ static com::SafeArray<LONG> cadSequence(8);
cadSequence[0] = 0x1d; // Ctrl down
cadSequence[1] = 0x38; // Alt down
- cadSequence[2] = 0x53; // Del down
- cadSequence[3] = 0xd3; // Del up
- cadSequence[4] = 0xb8; // Alt up
- cadSequence[5] = 0x9d; // Ctrl up
+ cadSequence[2] = 0xe0; // Del down 1
+ cadSequence[3] = 0x53; // Del down 2
+ cadSequence[4] = 0xe0; // Del up 1
+ cadSequence[5] = 0xd3; // Del up 2
+ cadSequence[6] = 0xb8; // Alt up
+ cadSequence[7] = 0x9d; // Ctrl up
return PutScancodes(ComSafeArrayAsInParam(cadSequence), NULL);
}
diff --git a/src/VBox/Main/src-client/MachineDebuggerImpl.cpp b/src/VBox/Main/src-client/MachineDebuggerImpl.cpp
index dc023d4ee..5b5845110 100644
--- a/src/VBox/Main/src-client/MachineDebuggerImpl.cpp
+++ b/src/VBox/Main/src-client/MachineDebuggerImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: MachineDebuggerImpl.cpp $ */
+/* $Id: MachineDebuggerImpl.cpp 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* VBox IMachineDebugger COM class implementation.
*/
@@ -55,12 +55,13 @@ MachineDebugger::~MachineDebugger()
HRESULT MachineDebugger::FinalConstruct()
{
unconst(mParent) = NULL;
- return S_OK;
+ return BaseFinalConstruct();
}
void MachineDebugger::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-client/MouseImpl.cpp b/src/VBox/Main/src-client/MouseImpl.cpp
index 3e693e964..b1620e866 100644
--- a/src/VBox/Main/src-client/MouseImpl.cpp
+++ b/src/VBox/Main/src-client/MouseImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: MouseImpl.cpp $ */
+/* $Id: MouseImpl.cpp 36161 2011-03-04 10:24:58Z vboxsync $ */
/** @file
* VirtualBox COM class implementation
*/
@@ -40,6 +40,17 @@ enum
};
/** @} */
+/** @name Absolute mouse reporting range
+ * @{ */
+enum
+{
+ /** Lower end */
+ MOUSE_RANGE_LOWER = 0,
+ /** Higher end */
+ MOUSE_RANGE_UPPER = 0xFFFF
+};
+/** @} */
+
/**
* Mouse driver instance data.
*/
@@ -78,12 +89,13 @@ HRESULT Mouse::FinalConstruct()
mcLastAbsY = 0x8000;
mfLastButtons = 0;
mfVMMDevGuestCaps = 0;
- return S_OK;
+ return BaseFinalConstruct();
}
void Mouse::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public methods only for internal purposes
@@ -309,9 +321,13 @@ HRESULT Mouse::reportRelEventToMouseDev(int32_t dx, int32_t dy, int32_t dz,
*
* @returns COM status code
*/
-HRESULT Mouse::reportAbsEventToMouseDev(uint32_t mouseXAbs, uint32_t mouseYAbs,
+HRESULT Mouse::reportAbsEventToMouseDev(int32_t mouseXAbs, int32_t mouseYAbs,
int32_t dz, int32_t dw, uint32_t fButtons)
{
+ if (mouseXAbs < MOUSE_RANGE_LOWER || mouseXAbs > MOUSE_RANGE_UPPER)
+ return S_OK;
+ if (mouseYAbs < MOUSE_RANGE_LOWER || mouseYAbs > MOUSE_RANGE_UPPER)
+ return S_OK;
if ( mouseXAbs != mcLastAbsX || mouseYAbs != mcLastAbsY
|| dz || dw || fButtons != mfLastButtons)
{
@@ -347,7 +363,7 @@ HRESULT Mouse::reportAbsEventToMouseDev(uint32_t mouseXAbs, uint32_t mouseYAbs,
*
* @returns COM status code
*/
-HRESULT Mouse::reportAbsEventToVMMDev(uint32_t mouseXAbs, uint32_t mouseYAbs)
+HRESULT Mouse::reportAbsEventToVMMDev(int32_t mouseXAbs, int32_t mouseYAbs)
{
VMMDev *pVMMDev = mParent->getVMMDev();
ComAssertRet(pVMMDev, E_FAIL);
@@ -373,7 +389,7 @@ HRESULT Mouse::reportAbsEventToVMMDev(uint32_t mouseXAbs, uint32_t mouseYAbs)
*
* @returns COM status code
*/
-HRESULT Mouse::reportAbsEvent(uint32_t mouseXAbs, uint32_t mouseYAbs,
+HRESULT Mouse::reportAbsEvent(int32_t mouseXAbs, int32_t mouseYAbs,
int32_t dz, int32_t dw, uint32_t fButtons,
bool fUsesVMMDevEvent)
{
@@ -403,6 +419,26 @@ HRESULT Mouse::reportAbsEvent(uint32_t mouseXAbs, uint32_t mouseYAbs,
return rc;
}
+#ifndef VBOXBFE_WITHOUT_COM
+void Mouse::fireMouseEvent(bool fAbsolute, LONG x, LONG y, LONG dz, LONG dw, LONG Buttons)
+{
+ /* If mouse button is pressed, we generate new event, to avoid reusable events coalescing and thus
+ dropping key press events */
+ if (Buttons != 0)
+ {
+ VBoxEventDesc evDesc;
+ evDesc.init(mEventSource, VBoxEventType_OnGuestMouse, fAbsolute, x, y, dz, dw, Buttons);
+ evDesc.fire(0);
+ }
+ else
+ {
+ mMouseEvent.reinit(VBoxEventType_OnGuestMouse, fAbsolute, x, y, dz, dw, Buttons);
+ mMouseEvent.fire(0);
+ }
+}
+#endif
+
+
/**
* Send a relative mouse event to the guest.
* @note the VMMDev capability change is so that the guest knows we are sending
@@ -431,18 +467,16 @@ STDMETHODIMP Mouse::PutMouseEvent(LONG dx, LONG dy, LONG dz, LONG dw, LONG butto
updateVMMDevMouseCaps(0, VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE);
rc = reportRelEventToMouseDev(dx, dy, dz, dw, fButtons);
-#ifndef VBOXBFE_WITHOUT_COM
- mMouseEvent.reinit(VBoxEventType_OnGuestMouse, false, dx, dy, dz, dw, fButtons);
- mMouseEvent.fire(0);
-#endif
+ fireMouseEvent(false, dx, dy, dz, dw, buttonState);
return rc;
}
/**
* Convert an (X, Y) value pair in screen co-ordinates (starting from 1) to a
- * value from 0 to 0xffff. Sets the optional validity value to false if the
- * pair is not on an active screen and to true otherwise.
+ * value from MOUSE_RANGE_LOWER to MOUSE_RANGE_UPPER. Sets the optional
+ * validity value to false if the pair is not on an active screen and to true
+ * otherwise.
*
* @returns COM status value
*/
@@ -466,17 +500,18 @@ HRESULT Mouse::convertDisplayRes(LONG x, LONG y, int32_t *pcX, int32_t *pcY,
if (FAILED(rc))
return rc;
- *pcX = displayWidth ? ((x - 1) * 0xFFFF) / displayWidth: 0;
- *pcY = displayHeight ? ((y - 1) * 0xFFFF) / displayHeight: 0;
+ *pcX = displayWidth ? ((x - 1) * MOUSE_RANGE_UPPER) / (LONG) displayWidth: 0;
+ *pcY = displayHeight ? ((y - 1) * MOUSE_RANGE_UPPER) / (LONG) displayHeight: 0;
}
else
{
int32_t x1, y1, x2, y2;
/* Takes the display lock */
pDisplay->getFramebufferDimensions(&x1, &y1, &x2, &y2);
- *pcX = x1 != x2 ? (x - 1 - x1) * 0xFFFF / (x2 - x1) : 0;
- *pcY = y1 != y2 ? (y - 1 - y1) * 0xFFFF / (y2 - y1) : 0;
- if (*pcX < 0 || *pcX > 0xFFFF || *pcY < 0 || *pcY > 0xFFFF)
+ *pcX = x1 != x2 ? (x - 1 - x1) * MOUSE_RANGE_UPPER / (x2 - x1) : 0;
+ *pcY = y1 != y2 ? (y - 1 - y1) * MOUSE_RANGE_UPPER / (y2 - y1) : 0;
+ if ( *pcX < MOUSE_RANGE_LOWER || *pcX > MOUSE_RANGE_UPPER
+ || *pcY < MOUSE_RANGE_LOWER || *pcY > MOUSE_RANGE_UPPER)
if (pfValid)
*pfValid = false;
}
@@ -518,13 +553,6 @@ STDMETHODIMP Mouse::PutMouseEventAbsolute(LONG x, LONG y, LONG dz, LONG dw,
HRESULT rc = convertDisplayRes(x, y, &mouseXAbs, &mouseYAbs, &fValid);
if (FAILED(rc)) return rc;
- /** @todo multi-monitor Windows guests expect this to be unbounded.
- * Understand the issues involved and fix for the rest. */
- /* if (mouseXAbs > 0xffff)
- mouseXAbs = mcLastAbsX;
- if (mouseYAbs > 0xffff)
- mouseYAbs = mcLastAbsY; */
-
fButtons = mouseButtonsToPDM(buttonState);
/* If we are doing old-style (IRQ-less) absolute reporting to the VMM
* device then make sure the guest is aware of it, so that it knows to
@@ -536,11 +564,7 @@ STDMETHODIMP Mouse::PutMouseEventAbsolute(LONG x, LONG y, LONG dz, LONG dw,
RT_BOOL( mfVMMDevGuestCaps
& VMMDEV_MOUSE_NEW_PROTOCOL));
-#ifndef VBOXBFE_WITHOUT_COM
- mMouseEvent.reinit(VBoxEventType_OnGuestMouse, true, x, y, dz, dw,
- fButtons);
- mMouseEvent.fire(0);
-#endif
+ fireMouseEvent(true, x, y, dz, dw, buttonState);
}
return rc;
diff --git a/src/VBox/Main/src-client/PciRawDevImpl.cpp b/src/VBox/Main/src-client/PciRawDevImpl.cpp
new file mode 100644
index 000000000..80c644ad7
--- /dev/null
+++ b/src/VBox/Main/src-client/PciRawDevImpl.cpp
@@ -0,0 +1,229 @@
+/* $Id: PciRawDevImpl.cpp 37802 2011-07-06 13:32:15Z vboxsync $ */
+/** @file
+ * VirtualBox Driver Interface to raw PCI device.
+ */
+
+/*
+ * 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.
+ */
+#include "Logging.h"
+#include "PciRawDevImpl.h"
+#include "PciDeviceAttachmentImpl.h"
+#include "ConsoleImpl.h"
+#include "MachineImpl.h"
+
+// generated header for events
+#include "VBoxEvents.h"
+
+/**
+ * PCI raw driver instance data.
+ */
+typedef struct DRVMAINPCIRAWDEV
+{
+ /** Pointer to the real PCI raw object. */
+ PciRawDev *pPciRawDev;
+ /** Pointer to the driver instance structure. */
+ PPDMDRVINS pDrvIns;
+ /** Our PCI device connector interface. */
+ PDMIPCIRAWCONNECTOR IConnector;
+
+} DRVMAINPCIRAWDEV, *PDRVMAINPCIRAWDEV;
+
+//
+// constructor / destructor
+//
+PciRawDev::PciRawDev(Console *console)
+ : mpDrv(NULL),
+ mParent(console)
+{
+}
+
+PciRawDev::~PciRawDev()
+{
+}
+
+/**
+ * @interface_method_impl{PDMIBASE,pfnQueryInterface}
+ */
+DECLCALLBACK(void *) PciRawDev::drvQueryInterface(PPDMIBASE pInterface, const char *pszIID)
+{
+ PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
+ PDRVMAINPCIRAWDEV pThis = PDMINS_2_DATA(pDrvIns, PDRVMAINPCIRAWDEV);
+
+ PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
+ PDMIBASE_RETURN_INTERFACE(pszIID, PDMIPCIRAWCONNECTOR, &pThis->IConnector);
+
+ return NULL;
+}
+
+
+/**
+ * @interface_method_impl{PDMIPCIRAWUP,pfnPciDeviceConstructComplete}
+ */
+DECLCALLBACK(int) PciRawDev::drvDeviceConstructComplete(PPDMIPCIRAWCONNECTOR pInterface, const char *pcszName,
+ uint32_t uHostPciAddress, uint32_t uGuestPciAddress,
+ int rc)
+{
+ PDRVMAINPCIRAWDEV pThis = RT_FROM_CPP_MEMBER(pInterface, DRVMAINPCIRAWDEV, IConnector);
+ Console *pConsole = pThis->pPciRawDev->getParent();
+ const ComPtr<IMachine>& machine = pConsole->machine();
+ ComPtr<IVirtualBox> vbox;
+
+ HRESULT hrc = machine->COMGETTER(Parent)(vbox.asOutParam());
+ Assert(SUCCEEDED(hrc));
+
+ ComPtr<IEventSource> es;
+ hrc = vbox->COMGETTER(EventSource)(es.asOutParam());
+ Assert(SUCCEEDED(hrc));
+
+ Bstr bstrId;
+ hrc = machine->COMGETTER(Id)(bstrId.asOutParam());
+ Assert(SUCCEEDED(hrc));
+
+ ComObjPtr<PciDeviceAttachment> pda;
+ BstrFmt bstrName(pcszName);
+ pda.createObject();
+ pda->init(machine, bstrName, uHostPciAddress, uGuestPciAddress, TRUE);
+
+ Bstr msg("");
+ if (RT_FAILURE(rc))
+ msg = BstrFmt("runtime error %Rrc", rc);
+
+ fireHostPciDevicePlugEvent(es, bstrId.raw(), true /* plugged */, RT_SUCCESS(rc) /* success */, pda, msg.raw());
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Destruct a PCI raw driver instance.
+ *
+ * @returns VBox status.
+ * @param pDrvIns The driver instance data.
+ */
+DECLCALLBACK(void) PciRawDev::drvDestruct(PPDMDRVINS pDrvIns)
+{
+ PDRVMAINPCIRAWDEV pData = PDMINS_2_DATA(pDrvIns, PDRVMAINPCIRAWDEV);
+ PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
+ if (pData->pPciRawDev)
+ pData->pPciRawDev->mpDrv = NULL;
+}
+
+
+/**
+ * Reset notification.
+ *
+ * @returns VBox status.
+ * @param pDrvIns The driver instance data.
+ */
+DECLCALLBACK(void) PciRawDev::drvReset(PPDMDRVINS pDrvIns)
+{
+}
+
+
+/**
+ * Construct a raw PCI driver instance.
+ *
+ * @copydoc FNPDMDRVCONSTRUCT
+ */
+DECLCALLBACK(int) PciRawDev::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
+{
+ PDRVMAINPCIRAWDEV pData = PDMINS_2_DATA(pDrvIns, PDRVMAINPCIRAWDEV);
+ PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
+
+ /*
+ * Validate configuration.
+ */
+ if (!CFGMR3AreValuesValid(pCfgHandle, "Object\0"))
+ return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
+
+ AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
+ ("Configuration error: Not possible to attach anything to this driver!\n"),
+ VERR_PDM_DRVINS_NO_ATTACH);
+
+ /*
+ * IBase.
+ */
+ pDrvIns->IBase.pfnQueryInterface = PciRawDev::drvQueryInterface;
+
+ /*
+ * IConnector.
+ */
+ pData->IConnector.pfnDeviceConstructComplete = PciRawDev::drvDeviceConstructComplete;
+
+ /*
+ * Get the object pointer and update the mpDrv member.
+ */
+ void *pv;
+ int rc = CFGMR3QueryPtr(pCfgHandle, "Object", &pv);
+ if (RT_FAILURE(rc))
+ {
+ AssertMsgFailed(("Configuration error: No \"Object\" value! rc=%Rrc\n", rc));
+ return rc;
+ }
+
+ pData->pPciRawDev = (PciRawDev*)pv;
+ pData->pPciRawDev->mpDrv = pData;
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * Main raw PCI driver registration record.
+ */
+const PDMDRVREG PciRawDev::DrvReg =
+{
+ /* u32Version */
+ PDM_DRVREG_VERSION,
+ /* szName */
+ "MainPciRaw",
+ /* szRCMod */
+ "",
+ /* szR0Mod */
+ "",
+ /* pszDescription */
+ "Main PCI raw driver (Main as in the API).",
+ /* fFlags */
+ PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
+ /* fClass. */
+ PDM_DRVREG_CLASS_PCIRAW,
+ /* cMaxInstances */
+ ~0,
+ /* cbInstance */
+ sizeof(DRVMAINPCIRAWDEV),
+ /* pfnConstruct */
+ PciRawDev::drvConstruct,
+ /* pfnDestruct */
+ PciRawDev::drvDestruct,
+ /* pfnRelocate */
+ NULL,
+ /* pfnIOCtl */
+ NULL,
+ /* pfnPowerOn */
+ NULL,
+ /* pfnReset */
+ PciRawDev::drvReset,
+ /* pfnSuspend */
+ NULL,
+ /* pfnResume */
+ NULL,
+ /* pfnAttach */
+ NULL,
+ /* pfnDetach */
+ NULL,
+ /* pfnPowerOff */
+ NULL,
+ /* pfnSoftReset */
+ NULL,
+ /* u32EndVersion */
+ PDM_DRVREG_VERSION
+};
diff --git a/src/VBox/Main/src-client/RemoteUSBDeviceImpl.cpp b/src/VBox/Main/src-client/RemoteUSBDeviceImpl.cpp
index ab416cd6e..70934fc94 100644
--- a/src/VBox/Main/src-client/RemoteUSBDeviceImpl.cpp
+++ b/src/VBox/Main/src-client/RemoteUSBDeviceImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: RemoteUSBDeviceImpl.cpp $ */
+/* $Id: RemoteUSBDeviceImpl.cpp 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -37,12 +37,13 @@ DEFINE_EMPTY_CTOR_DTOR (RemoteUSBDevice)
HRESULT RemoteUSBDevice::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void RemoteUSBDevice::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-client/SessionImpl.cpp b/src/VBox/Main/src-client/SessionImpl.cpp
index f156246d2..564cf9a59 100644
--- a/src/VBox/Main/src-client/SessionImpl.cpp
+++ b/src/VBox/Main/src-client/SessionImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: SessionImpl.cpp $ */
+/* $Id: SessionImpl.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
* VBox Client Session COM Class implementation in VBoxC.
*/
@@ -56,7 +56,11 @@ HRESULT Session::FinalConstruct()
{
LogFlowThisFunc(("\n"));
- return init();
+ HRESULT rc = init();
+
+ BaseFinalConstruct();
+
+ return rc;
}
void Session::FinalRelease()
@@ -64,6 +68,8 @@ void Session::FinalRelease()
LogFlowThisFunc(("\n"));
uninit();
+
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
@@ -181,9 +187,9 @@ STDMETHODIMP Session::COMGETTER(Machine)(IMachine **aMachine)
HRESULT rc;
if (mConsole)
- rc = mConsole->machine().queryInterfaceTo(aMachine);
+ rc = mConsole->machine().queryInterfaceTo(aMachine);
else
- rc = mRemoteMachine.queryInterfaceTo(aMachine);
+ rc = mRemoteMachine.queryInterfaceTo(aMachine);
if (FAILED(rc))
{
/** @todo VBox 3.3: replace E_FAIL with rc here. */
@@ -214,6 +220,7 @@ STDMETHODIMP Session::COMGETTER(Console)(IConsole **aConsole)
rc = mConsole.queryInterfaceTo(aConsole);
else
rc = mRemoteConsole.queryInterfaceTo(aConsole);
+
if (FAILED(rc))
{
/** @todo VBox 3.3: replace E_FAIL with rc here. */
@@ -719,6 +726,20 @@ STDMETHODIMP Session::OnBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup)
return mConsole->onBandwidthGroupChange(aBandwidthGroup);
}
+STDMETHODIMP Session::OnStorageDeviceChange(IMediumAttachment *aMediumAttachment, BOOL aRemove)
+{
+ LogFlowThisFunc(("\n"));
+
+ AutoCaller autoCaller(this);
+ AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
+ AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
+
+ return mConsole->onStorageDeviceChange(aMediumAttachment, aRemove);
+}
+
STDMETHODIMP Session::AccessGuestProperty(IN_BSTR aName, IN_BSTR aValue, IN_BSTR aFlags,
BOOL aIsSetter, BSTR *aRetValue, LONG64 *aRetTimestamp, BSTR *aRetFlags)
{
diff --git a/src/VBox/Main/src-client/USBDeviceImpl.cpp b/src/VBox/Main/src-client/USBDeviceImpl.cpp
index 8d6c4db26..2600d4069 100644
--- a/src/VBox/Main/src-client/USBDeviceImpl.cpp
+++ b/src/VBox/Main/src-client/USBDeviceImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBDeviceImpl.cpp $ */
+/* $Id: USBDeviceImpl.cpp 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* VirtualBox COM class implementation
*/
@@ -29,12 +29,13 @@ DEFINE_EMPTY_CTOR_DTOR (OUSBDevice)
HRESULT OUSBDevice::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void OUSBDevice::FinalRelease()
{
uninit ();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-client/VBoxDriversRegister.cpp b/src/VBox/Main/src-client/VBoxDriversRegister.cpp
index 0edc3be88..b25ecd8d9 100644
--- a/src/VBox/Main/src-client/VBoxDriversRegister.cpp
+++ b/src/VBox/Main/src-client/VBoxDriversRegister.cpp
@@ -24,7 +24,13 @@
#include "DisplayImpl.h"
#include "VMMDev.h"
#include "AudioSnifferInterface.h"
+#ifdef VBOX_WITH_USB_VIDEO
+# include "UsbWebcamInterface.h"
+#endif
#include "ConsoleImpl.h"
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+# include "PciRawDevImpl.h"
+#endif
#include "Logging.h"
@@ -63,9 +69,22 @@ extern "C" DECLEXPORT(int) VBoxDriversRegister(PCPDMDRVREGCB pCallbacks, uint32_
if (RT_FAILURE(rc))
return rc;
+#ifdef VBOX_WITH_USB_VIDEO
+ rc = pCallbacks->pfnRegister(pCallbacks, &UsbWebcamInterface::DrvReg);
+ if (RT_FAILURE(rc))
+ return rc;
+#endif
+
rc = pCallbacks->pfnRegister(pCallbacks, &Console::DrvStatusReg);
if (RT_FAILURE(rc))
return rc;
+
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ rc = pCallbacks->pfnRegister(pCallbacks, &PciRawDev::DrvReg);
+ if (RT_FAILURE(rc))
+ return rc;
+#endif
+
return VINF_SUCCESS;
}
/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/src-client/VMMDevInterface.cpp b/src/VBox/Main/src-client/VMMDevInterface.cpp
index a4c8a8518..b512da2e2 100644
--- a/src/VBox/Main/src-client/VMMDevInterface.cpp
+++ b/src/VBox/Main/src-client/VMMDevInterface.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMMDevInterface.cpp $ */
+/* $Id: VMMDevInterface.cpp 37175 2011-05-21 20:51:24Z vboxsync $ */
/** @file
* VirtualBox Driver Interface to VMM device.
*/
@@ -232,8 +232,8 @@ DECLCALLBACK(void) vmmdevUpdateGuestInfo(PPDMIVMMDEVCONNECTOR pInterface, const
*/
guest->setAdditionsInfo(Bstr(), guestInfo->osType); /* Clear interface version + OS type. */
guest->setAdditionsInfo2(Bstr(), Bstr(), Bstr()); /* Clear Guest Additions version. */
- guest->setAdditionsStatus(VBoxGuestStatusFacility_All,
- VBoxGuestStatusCurrent_Inactive,
+ guest->setAdditionsStatus(VBoxGuestFacilityType_All,
+ VBoxGuestFacilityStatus_Inactive,
0); /* Flags; not used. */
pConsole->onAdditionsStateChange();
}
@@ -293,18 +293,19 @@ DECLCALLBACK(void) vmmdevUpdateGuestInfo2(PPDMIVMMDEVCONNECTOR pInterface, const
DECLCALLBACK(void) vmmdevUpdateGuestCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities)
{
PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
+ AssertPtr(pDrv);
Console *pConsole = pDrv->pVMMDev->getParent();
/* store that information in IGuest */
- Guest* guest = pConsole->getGuest();
- Assert(guest);
- if (!guest)
+ Guest* pGuest = pConsole->getGuest();
+ AssertPtr(pGuest);
+ if (!pGuest)
return;
/*
* Report our current capabilities (and assume none is active yet).
*/
- guest->setSupportedFeatures(newCapabilities, 0 /* Active capabilities, not used here. */);
+ pGuest->setSupportedFeatures(newCapabilities);
/*
* Tell the console interface about the event
@@ -463,9 +464,6 @@ DECLCALLBACK(int) vmmdevSetVisibleRegion(PPDMIVMMDEVCONNECTOR pInterface, uint32
PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
Console *pConsole = pDrv->pVMMDev->getParent();
- if (!cRect)
- return VERR_INVALID_PARAMETER;
-
/* Forward to Display, which calls corresponding framebuffers. */
pConsole->getDisplay()->handleSetVisibleRegion(cRect, pRect);
diff --git a/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp b/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp
index 913b54849..607512c90 100644
--- a/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp
+++ b/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: VirtualBoxClientImpl.cpp $ */
+/* $Id: VirtualBoxClientImpl.cpp 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* VirtualBox COM class implementation
*/
@@ -41,12 +41,15 @@ uint32_t VirtualBoxClient::g_cInstances = 0;
HRESULT VirtualBoxClient::FinalConstruct()
{
- return init();
+ HRESULT rc = init();
+ BaseFinalConstruct();
+ return rc;
}
void VirtualBoxClient::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-client/win/VBoxC.rc b/src/VBox/Main/src-client/win/VBoxC.rc
index 2adf754b3..3a6602cc5 100644
--- a/src/VBox/Main/src-client/win/VBoxC.rc
+++ b/src/VBox/Main/src-client/win/VBoxC.rc
@@ -1,4 +1,4 @@
-/* $Id: VBoxC.rc $ */
+/* $Id: VBoxC.rc 35368 2010-12-30 13:38:23Z vboxsync $ */
/** @file
* VBoxC - Resource file containing version info and icon.
*/
diff --git a/src/VBox/Main/src-client/xpcom/module.cpp b/src/VBox/Main/src-client/xpcom/module.cpp
index 3d6e59466..291944213 100644
--- a/src/VBox/Main/src-client/xpcom/module.cpp
+++ b/src/VBox/Main/src-client/xpcom/module.cpp
@@ -28,26 +28,26 @@
// generated file
#include "VirtualBox_XPCOM.h"
+#include "AdditionsFacilityImpl.h"
+#include "ConsoleImpl.h"
+#include "ConsoleVRDPServer.h"
+#include "DisplayImpl.h"
+#ifdef VBOX_WITH_EXTPACK
+# include "ExtPackManagerImpl.h"
+#endif
#include "GuestImpl.h"
#include "KeyboardImpl.h"
+#include "MachineDebuggerImpl.h"
#include "MouseImpl.h"
-#include "DisplayImpl.h"
+#include "NATEngineImpl.h"
+#include "NetworkAdapterImpl.h"
#include "ProgressCombinedImpl.h"
-#include "MachineDebuggerImpl.h"
-#include "USBDeviceImpl.h"
+#include "ProgressImpl.h"
#include "RemoteUSBDeviceImpl.h"
+#include "SessionImpl.h"
#include "SharedFolderImpl.h"
-#include "ProgressImpl.h"
-#include "NetworkAdapterImpl.h"
-#include "NATEngineImpl.h"
-#ifdef VBOX_WITH_EXTPACK
-# include "ExtPackManagerImpl.h"
-#endif
-
+#include "USBDeviceImpl.h"
#include "VirtualBoxClientImpl.h"
-#include "SessionImpl.h"
-#include "ConsoleImpl.h"
-#include "ConsoleVRDPServer.h"
#include "Logging.h"
@@ -83,6 +83,8 @@ NS_IMPL_THREADSAFE_ISUPPORTS1_CI(ExtPack, IExtPack)
NS_DECL_CLASSINFO(ExtPackManager)
NS_IMPL_THREADSAFE_ISUPPORTS1_CI(ExtPackManager, IExtPackManager)
#endif
+NS_DECL_CLASSINFO(AdditionsFacility)
+NS_IMPL_THREADSAFE_ISUPPORTS1_CI(AdditionsFacility, IAdditionsFacility)
NS_DECL_CLASSINFO(Session)
NS_IMPL_THREADSAFE_ISUPPORTS2_CI(Session, ISession, IInternalSessionControl)
diff --git a/src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.cpp b/src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.cpp
index 230972050..b5071a37a 100644
--- a/src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.cpp
+++ b/src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxExtPackHelperApp.cpp $ */
+/* $Id: VBoxExtPackHelperApp.cpp 36527 2011-04-04 13:16:09Z vboxsync $ */
/** @file
* VirtualBox Main - Extension Pack Helper Application, usually set-uid-to-root.
*/
@@ -868,7 +868,7 @@ static RTEXITCODE DoInstall(int argc, char **argv)
/*
* Ok, down to business.
*/
- iprt::MiniString *pstrMangledName = VBoxExtPackMangleName(pszName);
+ RTCString *pstrMangledName = VBoxExtPackMangleName(pszName);
if (!pstrMangledName)
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to mangle name ('%s)", pszName);
@@ -954,10 +954,10 @@ static RTEXITCODE DoUninstall(int argc, char **argv)
/*
* Mangle the name so we can construct the directory names.
*/
- iprt::MiniString *pstrMangledName = VBoxExtPackMangleName(pszName);
+ RTCString *pstrMangledName = VBoxExtPackMangleName(pszName);
if (!pstrMangledName)
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to mangle name ('%s)", pszName);
- iprt::MiniString strMangledName(*pstrMangledName);
+ RTCString strMangledName(*pstrMangledName);
delete pstrMangledName;
/*
diff --git a/src/VBox/Main/src-server/ApplianceImpl.cpp b/src/VBox/Main/src-server/ApplianceImpl.cpp
index 25e4ff371..709c0d0cb 100644
--- a/src/VBox/Main/src-server/ApplianceImpl.cpp
+++ b/src/VBox/Main/src-server/ApplianceImpl.cpp
@@ -1,11 +1,11 @@
-/* $Id: ApplianceImpl.cpp $ */
+/* $Id: ApplianceImpl.cpp 37200 2011-05-24 15:34:06Z vboxsync $ */
/** @file
*
* IAppliance and IVirtualSystem COM class implementations.
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -266,7 +266,7 @@ Utf8Str convertNetworkAttachmentTypeToString(NetworkAttachmentType_T type)
case NetworkAttachmentType_Bridged: strType = "Bridged"; break;
case NetworkAttachmentType_Internal: strType = "Internal"; break;
case NetworkAttachmentType_HostOnly: strType = "HostOnly"; break;
- case NetworkAttachmentType_VDE: strType = "VDE"; break;
+ case NetworkAttachmentType_Generic: strType = "Generic"; break;
case NetworkAttachmentType_Null: strType = "Null"; break;
}
return strType;
diff --git a/src/VBox/Main/src-server/ApplianceImplExport.cpp b/src/VBox/Main/src-server/ApplianceImplExport.cpp
index d4a955a85..46fb013f9 100644
--- a/src/VBox/Main/src-server/ApplianceImplExport.cpp
+++ b/src/VBox/Main/src-server/ApplianceImplExport.cpp
@@ -1,4 +1,4 @@
-/* $Id: ApplianceImplExport.cpp $ */
+/* $Id: ApplianceImplExport.cpp 36523 2011-04-04 12:40:10Z vboxsync $ */
/** @file
*
* IAppliance and IVirtualSystem COM class implementations.
@@ -1879,7 +1879,7 @@ HRESULT Appliance::writeFSImpl(TaskOVF *pTask, AutoWriteLockBase& writeLock, PVD
strMfFilePath.c_str(), vrc);
}
}
- catch (iprt::Error &x) // includes all XML exceptions
+ catch (RTCError &x) // includes all XML exceptions
{
rc = setError(VBOX_E_FILE_ERROR,
x.what());
diff --git a/src/VBox/Main/src-server/ApplianceImplIO.cpp b/src/VBox/Main/src-server/ApplianceImplIO.cpp
index 2a5765fec..36dd13552 100644
--- a/src/VBox/Main/src-server/ApplianceImplIO.cpp
+++ b/src/VBox/Main/src-server/ApplianceImplIO.cpp
@@ -1,4 +1,4 @@
-/* $Id: ApplianceImplIO.cpp $ */
+/* $Id: ApplianceImplIO.cpp 36043 2011-02-21 17:04:14Z vboxsync $ */
/** @file
*
* IO helper for IAppliance COM class implementations.
diff --git a/src/VBox/Main/src-server/ApplianceImplImport.cpp b/src/VBox/Main/src-server/ApplianceImplImport.cpp
index 58990066a..b8db14fce 100644
--- a/src/VBox/Main/src-server/ApplianceImplImport.cpp
+++ b/src/VBox/Main/src-server/ApplianceImplImport.cpp
@@ -1,4 +1,4 @@
-/* $Id: ApplianceImplImport.cpp $ */
+/* $Id: ApplianceImplImport.cpp 37862 2011-07-11 10:09:29Z vboxsync $ */
/** @file
*
* IAppliance and IVirtualSystem COM class implementations.
@@ -36,6 +36,7 @@
#include "MediumImpl.h"
#include "MediumFormatImpl.h"
#include "SystemPropertiesImpl.h"
+#include "HostImpl.h"
#include "AutoCaller.h"
#include "Logging.h"
@@ -404,7 +405,7 @@ STDMETHODIMP Appliance::Interpret()
&& (strNetwork.compare("Bridged", Utf8Str::CaseInsensitive))
&& (strNetwork.compare("Internal", Utf8Str::CaseInsensitive))
&& (strNetwork.compare("HostOnly", Utf8Str::CaseInsensitive))
- && (strNetwork.compare("VDE", Utf8Str::CaseInsensitive))
+ && (strNetwork.compare("Generic", Utf8Str::CaseInsensitive))
)
strNetwork = "Bridged"; // VMware assumes this is the default apparently
@@ -664,13 +665,18 @@ STDMETHODIMP Appliance::Interpret()
* @param aProgress
* @return
*/
-STDMETHODIMP Appliance::ImportMachines(IProgress **aProgress)
+STDMETHODIMP Appliance::ImportMachines(ComSafeArrayIn(ImportOptions_T, options), IProgress **aProgress)
{
CheckComArgOutPointerValid(aProgress);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
+ if (options != NULL)
+ m->optList = com::SafeArray<ImportOptions_T>(ComSafeArrayInArg(options)).toList();
+
+ AssertReturn(!(m->optList.contains(ImportOptions_KeepAllMACs) && m->optList.contains(ImportOptions_KeepNATMACs)), E_INVALIDARG);
+
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
// do not allow entering this method if the appliance is busy reading or writing
@@ -931,7 +937,7 @@ HRESULT Appliance::readFSImpl(TaskOVF *pTask, PVDINTERFACEIO pCallbacks, PSHA1ST
/* Read & parse the XML structure of the OVF file */
m->pReader = new ovf::OVFReader(pvTmpBuf, cbSize, pTask->locInfo.strPath);
}
- catch (iprt::Error &x) // includes all XML exceptions
+ catch (RTCError &x) // includes all XML exceptions
{
rc = setError(VBOX_E_FILE_ERROR,
x.what());
@@ -2044,7 +2050,7 @@ void Appliance::importMachineGeneric(const ovf::VirtualSystem &vsysThis,
if (pvsys->strExtraConfigCurrent.endsWith("type=Bridged", Utf8Str::CaseInsensitive))
{
/* Attach to the right interface */
- rc = pNetworkAdapter->AttachToBridgedInterface();
+ rc = pNetworkAdapter->COMSETTER(AttachmentType)(NetworkAttachmentType_Bridged);
if (FAILED(rc)) throw rc;
ComPtr<IHost> host;
rc = mVirtualBox->COMGETTER(Host)(host.asOutParam());
@@ -2067,7 +2073,7 @@ void Appliance::importMachineGeneric(const ovf::VirtualSystem &vsysThis,
rc = nwInterfaces[j]->COMGETTER(Name)(name.asOutParam());
if (FAILED(rc)) throw rc;
/* Set the interface name to attach to */
- pNetworkAdapter->COMSETTER(HostInterface)(name.raw());
+ pNetworkAdapter->COMSETTER(BridgedInterface)(name.raw());
if (FAILED(rc)) throw rc;
break;
}
@@ -2077,7 +2083,7 @@ void Appliance::importMachineGeneric(const ovf::VirtualSystem &vsysThis,
else if (pvsys->strExtraConfigCurrent.endsWith("type=HostOnly", Utf8Str::CaseInsensitive))
{
/* Attach to the right interface */
- rc = pNetworkAdapter->AttachToHostOnlyInterface();
+ rc = pNetworkAdapter->COMSETTER(AttachmentType)(NetworkAttachmentType_HostOnly);
if (FAILED(rc)) throw rc;
ComPtr<IHost> host;
rc = mVirtualBox->COMGETTER(Host)(host.asOutParam());
@@ -2100,7 +2106,7 @@ void Appliance::importMachineGeneric(const ovf::VirtualSystem &vsysThis,
rc = nwInterfaces[j]->COMGETTER(Name)(name.asOutParam());
if (FAILED(rc)) throw rc;
/* Set the interface name to attach to */
- pNetworkAdapter->COMSETTER(HostInterface)(name.raw());
+ pNetworkAdapter->COMSETTER(HostOnlyInterface)(name.raw());
if (FAILED(rc)) throw rc;
break;
}
@@ -2110,14 +2116,14 @@ void Appliance::importMachineGeneric(const ovf::VirtualSystem &vsysThis,
else if (pvsys->strExtraConfigCurrent.endsWith("type=Internal", Utf8Str::CaseInsensitive))
{
/* Attach to the right interface */
- rc = pNetworkAdapter->AttachToInternalNetwork();
+ rc = pNetworkAdapter->COMSETTER(AttachmentType)(NetworkAttachmentType_Internal);
if (FAILED(rc)) throw rc;
}
- /* Next test for VDE interfaces */
- else if (pvsys->strExtraConfigCurrent.endsWith("type=VDE", Utf8Str::CaseInsensitive))
+ /* Next test for Generic interfaces */
+ else if (pvsys->strExtraConfigCurrent.endsWith("type=Generic", Utf8Str::CaseInsensitive))
{
/* Attach to the right interface */
- rc = pNetworkAdapter->AttachToVDE();
+ rc = pNetworkAdapter->COMSETTER(AttachmentType)(NetworkAttachmentType_Generic);
if (FAILED(rc)) throw rc;
}
}
@@ -2526,14 +2532,21 @@ void Appliance::importVBoxMachine(ComObjPtr<VirtualSystemDescription> &vsdescThi
settings::NetworkAdaptersList &llNetworkAdapters = config.hardwareMachine.llNetworkAdapters;
/* First disable all network cards, they will be enabled below again. */
settings::NetworkAdaptersList::iterator it1;
+ bool fKeepAllMACs = m->optList.contains(ImportOptions_KeepAllMACs);
+ bool fKeepNATMACs = m->optList.contains(ImportOptions_KeepNATMACs);
for (it1 = llNetworkAdapters.begin(); it1 != llNetworkAdapters.end(); ++it1)
+ {
it1->fEnabled = false;
+ if (!( fKeepAllMACs
+ || (fKeepNATMACs && it1->mode == NetworkAttachmentType_NAT)))
+ Host::generateMACAddress(it1->strMACAddress);
+ }
/* Now iterate over all network entries. */
std::list<VirtualSystemDescriptionEntry*> avsdeNWs = vsdescThis->findByType(VirtualSystemDescriptionType_NetworkAdapter);
if (avsdeNWs.size() > 0)
{
/* Iterate through all network adapter entries and search for the
- * corrosponding one in the machine config. If one is found, configure
+ * corresponding one in the machine config. If one is found, configure
* it based on the user settings. */
list<VirtualSystemDescriptionEntry*>::const_iterator itNW;
for (itNW = avsdeNWs.begin();
diff --git a/src/VBox/Main/src-server/AudioAdapterImpl.cpp b/src/VBox/Main/src-server/AudioAdapterImpl.cpp
index 02f5b69ed..9b6dbf178 100644
--- a/src/VBox/Main/src-server/AudioAdapterImpl.cpp
+++ b/src/VBox/Main/src-server/AudioAdapterImpl.cpp
@@ -40,12 +40,13 @@ AudioAdapter::~AudioAdapter()
HRESULT AudioAdapter::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void AudioAdapter::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-server/BIOSSettingsImpl.cpp b/src/VBox/Main/src-server/BIOSSettingsImpl.cpp
index 1484cad89..bc40820ba 100644
--- a/src/VBox/Main/src-server/BIOSSettingsImpl.cpp
+++ b/src/VBox/Main/src-server/BIOSSettingsImpl.cpp
@@ -50,12 +50,13 @@ struct BIOSSettings::Data
HRESULT BIOSSettings::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void BIOSSettings::FinalRelease()
{
uninit ();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-server/BandwidthControlImpl.cpp b/src/VBox/Main/src-server/BandwidthControlImpl.cpp
index 18d42ad29..927a8007a 100644
--- a/src/VBox/Main/src-server/BandwidthControlImpl.cpp
+++ b/src/VBox/Main/src-server/BandwidthControlImpl.cpp
@@ -55,12 +55,13 @@ struct BandwidthControl::Data
HRESULT BandwidthControl::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void BandwidthControl::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-server/BandwidthGroupImpl.cpp b/src/VBox/Main/src-server/BandwidthGroupImpl.cpp
index 88725d7fb..b5dd1087c 100644
--- a/src/VBox/Main/src-server/BandwidthGroupImpl.cpp
+++ b/src/VBox/Main/src-server/BandwidthGroupImpl.cpp
@@ -63,12 +63,13 @@ struct BandwidthGroup::Data
HRESULT BandwidthGroup::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void BandwidthGroup::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-server/DHCPServerImpl.cpp b/src/VBox/Main/src-server/DHCPServerImpl.cpp
index dd52c92c9..d0ce36348 100644
--- a/src/VBox/Main/src-server/DHCPServerImpl.cpp
+++ b/src/VBox/Main/src-server/DHCPServerImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: DHCPServerImpl.cpp $ */
+/* $Id: DHCPServerImpl.cpp 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
*
@@ -42,12 +42,14 @@ DHCPServer::~DHCPServer()
HRESULT DHCPServer::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void DHCPServer::FinalRelease()
{
uninit ();
+
+ BaseFinalRelease();
}
void DHCPServer::uninit()
diff --git a/src/VBox/Main/src-server/DHCPServerRunner.cpp b/src/VBox/Main/src-server/DHCPServerRunner.cpp
index 5bb58033a..e1c5e8172 100644
--- a/src/VBox/Main/src-server/DHCPServerRunner.cpp
+++ b/src/VBox/Main/src-server/DHCPServerRunner.cpp
@@ -1,4 +1,4 @@
-/* $Id: DHCPServerRunner.cpp $ */
+/* $Id: DHCPServerRunner.cpp 35368 2010-12-30 13:38:23Z vboxsync $ */
/** @file
* VirtualBox Main - interface for VBox DHCP server
*/
diff --git a/src/VBox/Main/src-server/GuestOSTypeImpl.cpp b/src/VBox/Main/src-server/GuestOSTypeImpl.cpp
index 50f18fabd..bb5308a54 100644
--- a/src/VBox/Main/src-server/GuestOSTypeImpl.cpp
+++ b/src/VBox/Main/src-server/GuestOSTypeImpl.cpp
@@ -45,12 +45,14 @@ GuestOSType::~GuestOSType()
HRESULT GuestOSType::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void GuestOSType::FinalRelease()
{
uninit();
+
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-server/HostImpl.cpp b/src/VBox/Main/src-server/HostImpl.cpp
index a2994f520..a14ca898a 100644
--- a/src/VBox/Main/src-server/HostImpl.cpp
+++ b/src/VBox/Main/src-server/HostImpl.cpp
@@ -1,10 +1,10 @@
-/* $Id: HostImpl.cpp $ */
+/* $Id: HostImpl.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* VirtualBox COM class implementation: Host
*/
/*
- * 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;
@@ -51,7 +51,7 @@
#endif /* VBOX_WITH_RESOURCE_USAGE_API */
#if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT)
-# include <VBox/WinNetConfig.h>
+# include <VBox/VBoxNetCfg-win.h>
#endif /* #if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT) */
#ifdef RT_OS_LINUX
@@ -150,11 +150,11 @@ extern bool is3DAccelerationSupported();
#undef GS
#include <VBox/usb.h>
-#include <VBox/x86.h>
#include <VBox/vmm/hwacc_svm.h>
#include <VBox/err.h>
#include <VBox/settings.h>
#include <VBox/sup.h>
+#include <iprt/x86.h>
#include "VBox/com/MultiResult.h"
@@ -224,12 +224,13 @@ struct Host::Data
HRESULT Host::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void Host::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
/**
@@ -392,8 +393,8 @@ HRESULT Host::init(VirtualBox *aParent)
ComPtr<IHostNetworkInterface> hif;
ComPtr<IProgress> progress;
- int r = NetIfCreateHostOnlyNetworkInterface(m->pParent,
- hif.asOutParam(),
+ int r = NetIfCreateHostOnlyNetworkInterface(m->pParent,
+ hif.asOutParam(),
progress.asOutParam(),
it->c_str());
if (RT_FAILURE(r))
@@ -1512,6 +1513,16 @@ STDMETHODIMP Host::FindUSBDeviceById(IN_BSTR aId,
#endif /* !VBOX_WITH_USB */
}
+STDMETHODIMP Host::GenerateMACAddress(BSTR *aAddress)
+{
+ CheckComArgOutPointerValid(aAddress);
+ // no locking required
+ Utf8Str mac;
+ generateMACAddress(mac);
+ Bstr(mac).cloneTo(aAddress);
+ return S_OK;
+}
+
// public methods only for internal purposes
////////////////////////////////////////////////////////////////////////////////
@@ -1648,8 +1659,9 @@ HRESULT Host::getDrives(DeviceType_T mediumType,
// list was built, and this was a subsequent call: then compare the old and the new lists
// remove drives from the cached list which are no longer present
- MediaList::iterator itCached = pllCached->begin();
- while (itCached != pllCached->end())
+ for (MediaList::iterator itCached = pllCached->begin();
+ itCached != pllCached->end();
+ /*nothing */)
{
Medium *pCached = *itCached;
const Utf8Str strLocationCached = pCached->getLocationFull();
@@ -1680,7 +1692,7 @@ HRESULT Host::getDrives(DeviceType_T mediumType,
Medium *pNew = *itNew;
const Utf8Str strLocationNew = pNew->getLocationFull();
bool fFound = false;
- for (itCached = pllCached->begin();
+ for (MediaList::iterator itCached = pllCached->begin();
itCached != pllCached->end();
++itCached)
{
@@ -2795,7 +2807,7 @@ void Host::registerMetrics(PerformanceCollector *aCollector)
ramUsageUsed,
ramUsageFree);
aCollector->registerBaseMetric (ramUsage);
- pm::BaseMetric *ramVmm = new pm::HostRamVmm(hal, objptr,
+ pm::BaseMetric *ramVmm = new pm::HostRamVmm(aCollector->getGuestManager(), objptr,
ramVMMUsed,
ramVMMFree,
ramVMMBallooned,
@@ -2897,6 +2909,21 @@ void Host::unregisterMetrics (PerformanceCollector *aCollector)
aCollector->unregisterBaseMetricsFor(this);
}
+
+/* static */
+void Host::generateMACAddress(Utf8Str &mac)
+{
+ /*
+ * Our strategy is as follows: the first three bytes are our fixed
+ * vendor ID (080027). The remaining 3 bytes will be taken from the
+ * start of a GUID. This is a fairly safe algorithm.
+ */
+ Guid guid;
+ guid.create();
+ mac = Utf8StrFmt("080027%02X%02X%02X",
+ guid.raw()->au8[0], guid.raw()->au8[1], guid.raw()->au8[2]);
+}
+
#endif /* VBOX_WITH_RESOURCE_USAGE_API */
/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp b/src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp
index 7e2de25af..62ec75d69 100644
--- a/src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp
+++ b/src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: HostNetworkInterfaceImpl.cpp $ */
+/* $Id: HostNetworkInterfaceImpl.cpp 37353 2011-06-07 14:35:02Z vboxsync $ */
/** @file
*
@@ -42,12 +42,13 @@ HostNetworkInterface::~HostNetworkInterface()
HRESULT HostNetworkInterface::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void HostNetworkInterface::FinalRelease()
{
uninit ();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
@@ -550,7 +551,6 @@ STDMETHODIMP HostNetworkInterface::DhcpRediscover ()
HRESULT HostNetworkInterface::setVirtualBox(VirtualBox *pVBox)
{
- HRESULT hrc;
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
unconst(mVBox) = pVBox;
@@ -560,7 +560,7 @@ HRESULT HostNetworkInterface::setVirtualBox(VirtualBox *pVBox)
if (m.IPAddress == 0 && mIfType == HostNetworkInterfaceType_HostOnly)
{
Bstr tmpAddr, tmpMask;
- hrc = mVBox->GetExtraData(BstrFmt("HostOnly/%ls/IPAddress", mInterfaceName.raw()).raw(), tmpAddr.asOutParam());
+ HRESULT hrc = mVBox->GetExtraData(BstrFmt("HostOnly/%ls/IPAddress", mInterfaceName.raw()).raw(), tmpAddr.asOutParam());
hrc = mVBox->GetExtraData(BstrFmt("HostOnly/%ls/IPNetMask", mInterfaceName.raw()).raw(), tmpMask.asOutParam());
if (tmpAddr.isEmpty())
{
@@ -572,7 +572,7 @@ HRESULT HostNetworkInterface::setVirtualBox(VirtualBox *pVBox)
* change the address on host's interface as well and we want to
* postpone the change until VM actually starts.
*/
- hrc = mVBox->SetExtraData(BstrFmt("HostOnly/%ls/IPAddress",
+ hrc = mVBox->SetExtraData(BstrFmt("HostOnly/%ls/IPAddress",
mInterfaceName.raw()).raw(),
tmpAddr.raw());
ComAssertComRCRet(hrc, hrc);
@@ -581,7 +581,7 @@ HRESULT HostNetworkInterface::setVirtualBox(VirtualBox *pVBox)
if (tmpMask.isEmpty())
{
tmpMask = Bstr(VBOXNET_IPV4MASK_DEFAULT);
- hrc = mVBox->SetExtraData(BstrFmt("HostOnly/%ls/IPNetMask",
+ hrc = mVBox->SetExtraData(BstrFmt("HostOnly/%ls/IPNetMask",
mInterfaceName.raw()).raw(),
Bstr(VBOXNET_IPV4MASK_DEFAULT).raw());
ComAssertComRCRet(hrc, hrc);
@@ -593,7 +593,7 @@ HRESULT HostNetworkInterface::setVirtualBox(VirtualBox *pVBox)
if (m.IPV6Address.isEmpty())
{
Bstr tmpPrefixLen;
- hrc = mVBox->GetExtraData(BstrFmt("HostOnly/%ls/IPV6Address", mInterfaceName.raw()).raw(), m.IPV6Address.asOutParam());
+ HRESULT hrc = mVBox->GetExtraData(BstrFmt("HostOnly/%ls/IPV6Address", mInterfaceName.raw()).raw(), m.IPV6Address.asOutParam());
if (!m.IPV6Address.isEmpty())
{
hrc = mVBox->GetExtraData(BstrFmt("HostOnly/%ls/IPV6PrefixLen", mInterfaceName.raw()).raw(), tmpPrefixLen.asOutParam());
diff --git a/src/VBox/Main/src-server/HostPower.cpp b/src/VBox/Main/src-server/HostPower.cpp
index 981af22ed..830729a00 100644
--- a/src/VBox/Main/src-server/HostPower.cpp
+++ b/src/VBox/Main/src-server/HostPower.cpp
@@ -155,11 +155,13 @@ void HostPowerService::notify(HostPowerEvent aEvent)
continue;
/* Wait until the operation has been completed. */
- LONG iRc;
rc = progress->WaitForCompletion(-1);
if (SUCCEEDED(rc))
- progress->COMGETTER(ResultCode) (&iRc);
- rc = iRc;
+ {
+ LONG iRc;
+ progress->COMGETTER(ResultCode)(&iRc);
+ rc = iRc;
+ }
AssertMsg (SUCCEEDED(rc), ("SaveState WaitForCompletion "
"failed with %Rhrc (%#08X)\n", rc, rc));
diff --git a/src/VBox/Main/src-server/HostUSBDeviceImpl.cpp b/src/VBox/Main/src-server/HostUSBDeviceImpl.cpp
index 094df8b68..85b6d66f3 100644
--- a/src/VBox/Main/src-server/HostUSBDeviceImpl.cpp
+++ b/src/VBox/Main/src-server/HostUSBDeviceImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: HostUSBDeviceImpl.cpp $ */
+/* $Id: HostUSBDeviceImpl.cpp 35812 2011-02-01 13:46:37Z vboxsync $ */
/** @file
* VirtualBox IHostUSBDevice COM interface implementation.
*/
@@ -39,12 +39,13 @@ HRESULT HostUSBDevice::FinalConstruct()
mUSBProxyService = NULL;
mUsb = NULL;
- return S_OK;
+ return BaseFinalConstruct();
}
void HostUSBDevice::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-server/Logging.cpp b/src/VBox/Main/src-server/Logging.cpp
new file mode 100644
index 000000000..148a50f5d
--- /dev/null
+++ b/src/VBox/Main/src-server/Logging.cpp
@@ -0,0 +1,133 @@
+/* $Id: Logging.cpp 37666 2011-06-28 12:33:34Z vboxsync $ */
+
+/** @file
+ *
+ * Logging in VBoxSVC.
+ */
+
+/*
+ * 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.
+ */
+
+#include "Logging.h"
+
+#include <package-generated.h>
+
+#include <iprt/buildconfig.h>
+#include <iprt/err.h>
+#include <iprt/message.h>
+#include <iprt/path.h>
+#include <iprt/system.h>
+#include <iprt/process.h>
+#include <VBox/version.h>
+#include <VBox/log.h>
+
+
+static void vboxsvcHeaderFooter(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,
+ "VirtualBox (XP)COM Server %s r%u %s (%s %s) release log\n"
+#ifdef VBOX_BLEEDING_EDGE
+ "EXPERIMENTAL build " VBOX_BLEEDING_EDGE "\n"
+#endif
+ "Log opened %s\n",
+ VBOX_VERSION_STRING, RTBldCfgRevision(), 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 */;
+ }
+}
+
+int VBoxSVCLogRelCreate(const char *pszLogFile, uint32_t cHistory,
+ uint32_t uHistoryFileTime, uint64_t uHistoryFileSize)
+{
+ /* create release logger */
+ PRTLOGGER pLoggerReleaseFile;
+ 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 vrc = RTLogCreateEx(&pLoggerReleaseFile, fFlags, "all",
+ "VBOXSVC_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, 0 /* fDestFlags */,
+ vboxsvcHeaderFooter, cHistory, uHistoryFileSize, uHistoryFileTime,
+ szError, sizeof(szError), pszLogFile);
+ if (RT_SUCCESS(vrc))
+ {
+ /* register this logger as the release logger */
+ RTLogRelSetDefaultInstance(pLoggerReleaseFile);
+
+ /* Explicitly flush the log in case of VBOXWEBSRV_RELEASE_LOG=buffered. */
+ RTLogFlush(pLoggerReleaseFile);
+ }
+ else
+ {
+ /* print a message, but do not fail */
+ RTMsgError("failed to open release log (%s, %Rrc)", szError, vrc);
+ }
+ return vrc;
+}
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/src-server/MachineImpl.cpp b/src/VBox/Main/src-server/MachineImpl.cpp
index ae2b4c76e..8a6f3b139 100644
--- a/src/VBox/Main/src-server/MachineImpl.cpp
+++ b/src/VBox/Main/src-server/MachineImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: MachineImpl.cpp $ */
+/* $Id: MachineImpl.cpp 38056 2011-07-19 09:03:26Z vboxsync $ */
/** @file
* Implementation of IMachine in VBoxSVC.
*/
@@ -49,6 +49,10 @@
#include "DisplayImpl.h"
#include "DisplayUtils.h"
#include "BandwidthControlImpl.h"
+#include "MachineImplCloneVM.h"
+
+// generated header
+#include "VBoxEvents.h"
#ifdef VBOX_WITH_USB
# include "USBProxyService.h"
@@ -68,6 +72,7 @@
#include <iprt/string.h>
#include <VBox/com/array.h>
+#include <VBox/com/list.h>
#include <VBox/err.h>
#include <VBox/param.h>
@@ -153,7 +158,7 @@ Machine::HWData::HWData()
mMonitorCount = 1;
mHWVirtExEnabled = true;
mHWVirtExNestedPagingEnabled = true;
-#if HC_ARCH_BITS == 64 && !defined(RT_OS_LINUX) && !defined(RT_OS_SOLARIS)
+#if HC_ARCH_BITS == 64 && !defined(RT_OS_LINUX)
mHWVirtExLargePagesEnabled = true;
#else
/* Not supported on 32 bits hosts. */
@@ -223,7 +228,7 @@ Machine::MediaData::~MediaData()
/////////////////////////////////////////////////////////////////////////////
Machine::Machine()
- : mGuestHAL(NULL),
+ : mCollectorGuest(NULL),
mPeer(NULL),
mParent(NULL)
{}
@@ -234,13 +239,14 @@ Machine::~Machine()
HRESULT Machine::FinalConstruct()
{
LogFlowThisFunc(("\n"));
- return S_OK;
+ return BaseFinalConstruct();
}
void Machine::FinalRelease()
{
LogFlowThisFunc(("\n"));
uninit();
+ BaseFinalRelease();
}
/**
@@ -787,6 +793,11 @@ void Machine::uninit()
// uninit media from this machine's media registry, if they're still there
Guid uuidMachine(getId());
+
+ /* XXX This will fail with
+ * "cannot be closed because it is still attached to 1 virtual machines"
+ * because at this point we did not call uninitDataAndChildObjects() yet
+ * and therefore also removeBackReference() for all these mediums was not called! */
if (!uuidMachine.isEmpty()) // can be empty if we're called from a failure of Machine::init
mParent->unregisterMachineMedia(uuidMachine);
@@ -933,6 +944,12 @@ STDMETHODIMP Machine::COMSETTER(Name)(IN_BSTR aName)
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
+ // prohibit setting a UUID only as the machine name, or else it can
+ // never be found by findMachine()
+ Guid test(aName);
+ if (test.isNotEmpty())
+ return setError(E_INVALIDARG, tr("A machine cannot have a UUID as its name"));
+
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
HRESULT rc = checkStateDependency(MutableStateDep);
@@ -1305,14 +1322,15 @@ STDMETHODIMP Machine::COMSETTER(CPUCount)(ULONG CPUCount)
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* We cant go below the current number of CPUs if hotplug is enabled*/
+ /* We cant go below the current number of CPUs attached if hotplug is enabled*/
if (mHWData->mCPUHotPlugEnabled)
{
for (unsigned idx = CPUCount; idx < SchemaDefs::MaxCPUCount; idx++)
{
if (mHWData->mCPUAttached[idx])
return setError(E_INVALIDARG,
- tr(": %lu (must be higher than or equal to %lu)"),
+ tr("There is still a CPU attached to socket %lu."
+ "Detach the CPU before removing the socket"),
CPUCount, idx+1);
}
}
@@ -1437,7 +1455,7 @@ STDMETHODIMP Machine::COMSETTER(CPUHotPlugEnabled)(BOOL enabled)
if ( (cCpusAttached != mHWData->mCPUCount)
|| (iHighestId >= mHWData->mCPUCount))
return setError(E_INVALIDARG,
- tr("CPU hotplugging can't be disabled because the maximum number of CPUs is not equal to the amount of CPUs attached\n"));
+ tr("CPU hotplugging can't be disabled because the maximum number of CPUs is not equal to the amount of CPUs attached"));
setModified(IsModified_MachineData);
mHWData.backup();
@@ -1449,6 +1467,30 @@ STDMETHODIMP Machine::COMSETTER(CPUHotPlugEnabled)(BOOL enabled)
return rc;
}
+STDMETHODIMP Machine::COMGETTER(EmulatedUSBCardReaderEnabled)(BOOL *enabled)
+{
+ NOREF(enabled);
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP Machine::COMSETTER(EmulatedUSBCardReaderEnabled)(BOOL enabled)
+{
+ NOREF(enabled);
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP Machine::COMGETTER(EmulatedUSBWebcameraEnabled)(BOOL *enabled)
+{
+ NOREF(enabled);
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP Machine::COMSETTER(EmulatedUSBWebcameraEnabled)(BOOL enabled)
+{
+ NOREF(enabled);
+ return E_NOTIMPL;
+}
+
STDMETHODIMP Machine::COMGETTER(HpetEnabled)(BOOL *enabled)
{
CheckComArgOutPointerValid(enabled);
@@ -1804,7 +1846,7 @@ STDMETHODIMP Machine::GetCPUIDLeaf(ULONG aId, ULONG *aValEax, ULONG *aValEbx, UL
case 0x9:
case 0xA:
if (mHWData->mCpuIdStdLeafs[aId].ulId != aId)
- return setError(E_INVALIDARG, tr("CpuId override leaf %#x is not set"), aId);
+ return E_INVALIDARG;
*aValEax = mHWData->mCpuIdStdLeafs[aId].ulEax;
*aValEbx = mHWData->mCpuIdStdLeafs[aId].ulEbx;
@@ -1824,7 +1866,7 @@ STDMETHODIMP Machine::GetCPUIDLeaf(ULONG aId, ULONG *aValEax, ULONG *aValEbx, UL
case 0x80000009:
case 0x8000000A:
if (mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulId != aId)
- return setError(E_INVALIDARG, tr("CpuId override leaf %#x is not set"), aId);
+ return E_INVALIDARG;
*aValEax = mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulEax;
*aValEbx = mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulEbx;
@@ -2010,6 +2052,9 @@ STDMETHODIMP Machine::GetHWVirtExProperty(HWVirtExPropertyType_T property, BOOL
case HWVirtExPropertyType_LargePages:
*aVal = mHWData->mHWVirtExLargePagesEnabled;
+#if defined(DEBUG_bird) && defined(RT_OS_LINUX) /* This feature is deadly here */
+ *aVal = FALSE;
+#endif
break;
case HWVirtExPropertyType_Force:
@@ -2323,7 +2368,7 @@ STDMETHODIMP Machine::COMGETTER(StateFilePath)(BSTR *aStateFilePath)
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- mSSData->mStateFilePath.cloneTo(aStateFilePath);
+ mSSData->strStateFilePath.cloneTo(aStateFilePath);
return S_OK;
}
@@ -3389,16 +3434,32 @@ STDMETHODIMP Machine::AttachDevice(IN_BSTR aControllerName,
AssertReturn(mData->mMachineState != MachineState_Saved, E_FAIL);
- if (Global::IsOnlineOrTransient(mData->mMachineState))
- return setError(VBOX_E_INVALID_VM_STATE,
- tr("Invalid machine state: %s"),
- Global::stringifyMachineState(mData->mMachineState));
-
/* Check for an existing controller. */
ComObjPtr<StorageController> ctl;
rc = getStorageControllerByName(aControllerName, ctl, true /* aSetError */);
if (FAILED(rc)) return rc;
+ StorageControllerType_T ctrlType;
+ rc = ctl->COMGETTER(ControllerType)(&ctrlType);
+ if (FAILED(rc))
+ return setError(E_FAIL,
+ tr("Could not get type of controller '%ls'"),
+ aControllerName);
+
+ /* Check that the controller can do hotplugging if we detach the device while the VM is running. */
+ bool fHotplug = false;
+ if (Global::IsOnlineOrTransient(mData->mMachineState))
+ fHotplug = true;
+
+ if (fHotplug && !isControllerHotplugCapable(ctrlType))
+ return setError(VBOX_E_INVALID_VM_STATE,
+ tr("Controller '%ls' does not support hotplugging"),
+ aControllerName);
+
+ if (fHotplug && aType == DeviceType_DVD)
+ return setError(VBOX_E_INVALID_VM_STATE,
+ tr("Attaching a DVD drive while the VM is running is not supported"));
+
// check that the port and device are not out of range
rc = ctl->checkPortAndDeviceValid(aControllerPort, aDevice);
if (FAILED(rc)) return rc;
@@ -3745,6 +3806,9 @@ STDMETHODIMP Machine::AttachDevice(IN_BSTR aControllerName,
aDevice,
aType,
fIndirect,
+ false /* fPassthrough */,
+ false /* fTempEject */,
+ false /* fNonRotational */,
Utf8Str::Empty);
if (FAILED(rc)) return rc;
@@ -3769,6 +3833,9 @@ STDMETHODIMP Machine::AttachDevice(IN_BSTR aControllerName,
treeLock.leave();
alock.release();
+ if (fHotplug)
+ rc = onStorageDeviceChange(attachment, FALSE /* aRemove */);
+
mParent->saveRegistries(llRegistriesThatNeedSaving);
return rc;
@@ -3779,7 +3846,7 @@ STDMETHODIMP Machine::DetachDevice(IN_BSTR aControllerName, LONG aControllerPort
{
CheckComArgStrNotEmptyOrNull(aControllerName);
- LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%ld aDevice=%ld\n",
+ LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%d aDevice=%d\n",
aControllerName, aControllerPort, aDevice));
AutoCaller autoCaller(this);
@@ -3794,10 +3861,27 @@ STDMETHODIMP Machine::DetachDevice(IN_BSTR aControllerName, LONG aControllerPort
AssertReturn(mData->mMachineState != MachineState_Saved, E_FAIL);
+ /* Check for an existing controller. */
+ ComObjPtr<StorageController> ctl;
+ rc = getStorageControllerByName(aControllerName, ctl, true /* aSetError */);
+ if (FAILED(rc)) return rc;
+
+ StorageControllerType_T ctrlType;
+ rc = ctl->COMGETTER(ControllerType)(&ctrlType);
+ if (FAILED(rc))
+ return setError(E_FAIL,
+ tr("Could not get type of controller '%ls'"),
+ aControllerName);
+
+ /* Check that the controller can do hotplugging if we detach the device while the VM is running. */
+ bool fHotplug = false;
if (Global::IsOnlineOrTransient(mData->mMachineState))
+ fHotplug = true;
+
+ if (fHotplug && !isControllerHotplugCapable(ctrlType))
return setError(VBOX_E_INVALID_VM_STATE,
- tr("Invalid machine state: %s"),
- Global::stringifyMachineState(mData->mMachineState));
+ tr("Controller '%ls' does not support hotplugging"),
+ aControllerName);
MediumAttachment *pAttach = findAttachment(mMediaData->mAttachments,
aControllerName,
@@ -3808,6 +3892,23 @@ STDMETHODIMP Machine::DetachDevice(IN_BSTR aControllerName, LONG aControllerPort
tr("No storage device attached to device slot %d on port %d of controller '%ls'"),
aDevice, aControllerPort, aControllerName);
+ if (fHotplug && pAttach->getType() == DeviceType_DVD)
+ return setError(VBOX_E_INVALID_VM_STATE,
+ tr("Detaching a DVD drive while the VM is running is not supported"));
+
+ /*
+ * The VM has to detach the device before we delete any implicit diffs.
+ * If this fails we can roll back without loosing data.
+ */
+ if (fHotplug)
+ {
+ alock.leave();
+ rc = onStorageDeviceChange(pAttach, TRUE /* aRemove */);
+ alock.enter();
+ }
+ if (FAILED(rc)) return rc;
+
+ /* If we are here everything went well and we can delete the implicit now. */
rc = detachDevice(pAttach, alock, NULL /* pSnapshot */, &llRegistriesThatNeedSaving);
alock.release();
@@ -3823,7 +3924,7 @@ STDMETHODIMP Machine::PassthroughDevice(IN_BSTR aControllerName, LONG aControlle
{
CheckComArgStrNotEmptyOrNull(aControllerName);
- LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%ld aDevice=%ld aPassthrough=%d\n",
+ LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%d aDevice=%d aPassthrough=%d\n",
aControllerName, aControllerPort, aDevice, aPassthrough));
AutoCaller autoCaller(this);
@@ -3865,12 +3966,99 @@ STDMETHODIMP Machine::PassthroughDevice(IN_BSTR aControllerName, LONG aControlle
return S_OK;
}
+STDMETHODIMP Machine::TemporaryEjectDevice(IN_BSTR aControllerName, LONG aControllerPort,
+ LONG aDevice, BOOL aTemporaryEject)
+{
+ CheckComArgStrNotEmptyOrNull(aControllerName);
+
+ LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%d aDevice=%d aTemporaryEject=%d\n",
+ aControllerName, aControllerPort, aDevice, aTemporaryEject));
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ HRESULT rc = checkStateDependency(MutableStateDep);
+ if (FAILED(rc)) return rc;
+
+ MediumAttachment *pAttach = findAttachment(mMediaData->mAttachments,
+ aControllerName,
+ aControllerPort,
+ aDevice);
+ if (!pAttach)
+ return setError(VBOX_E_OBJECT_NOT_FOUND,
+ tr("No storage device attached to device slot %d on port %d of controller '%ls'"),
+ aDevice, aControllerPort, aControllerName);
+
+
+ setModified(IsModified_Storage);
+ mMediaData.backup();
+
+ AutoWriteLock attLock(pAttach COMMA_LOCKVAL_SRC_POS);
+
+ if (pAttach->getType() != DeviceType_DVD)
+ return setError(E_INVALIDARG,
+ tr("Setting temporary eject flag rejected as the device attached to device slot %d on port %d of controller '%ls' is not a DVD"),
+ aDevice, aControllerPort, aControllerName);
+ pAttach->updateTempEject(!!aTemporaryEject);
+
+ return S_OK;
+}
+
+STDMETHODIMP Machine::NonRotationalDevice(IN_BSTR aControllerName, LONG aControllerPort,
+ LONG aDevice, BOOL aNonRotational)
+{
+ CheckComArgStrNotEmptyOrNull(aControllerName);
+
+ LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%d aDevice=%d aNonRotational=%d\n",
+ aControllerName, aControllerPort, aDevice, aNonRotational));
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ HRESULT rc = checkStateDependency(MutableStateDep);
+ if (FAILED(rc)) return rc;
+
+ AssertReturn(mData->mMachineState != MachineState_Saved, E_FAIL);
+
+ if (Global::IsOnlineOrTransient(mData->mMachineState))
+ return setError(VBOX_E_INVALID_VM_STATE,
+ tr("Invalid machine state: %s"),
+ Global::stringifyMachineState(mData->mMachineState));
+
+ MediumAttachment *pAttach = findAttachment(mMediaData->mAttachments,
+ aControllerName,
+ aControllerPort,
+ aDevice);
+ if (!pAttach)
+ return setError(VBOX_E_OBJECT_NOT_FOUND,
+ tr("No storage device attached to device slot %d on port %d of controller '%ls'"),
+ aDevice, aControllerPort, aControllerName);
+
+
+ setModified(IsModified_Storage);
+ mMediaData.backup();
+
+ AutoWriteLock attLock(pAttach COMMA_LOCKVAL_SRC_POS);
+
+ if (pAttach->getType() != DeviceType_HardDisk)
+ return setError(E_INVALIDARG,
+ tr("Setting the non-rotational medium flag rejected as the device attached to device slot %d on port %d of controller '%ls' is not a hard disk"),
+ aDevice, aControllerPort, aControllerName);
+ pAttach->updateNonRotational(!!aNonRotational);
+
+ return S_OK;
+}
+
STDMETHODIMP Machine::SetBandwidthGroupForDevice(IN_BSTR aControllerName, LONG aControllerPort,
LONG aDevice, IBandwidthGroup *aBandwidthGroup)
{
CheckComArgStrNotEmptyOrNull(aControllerName);
- LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%ld aDevice=%ld\n",
+ LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%d aDevice=%d\n",
aControllerName, aControllerPort, aDevice));
AutoCaller autoCaller(this);
@@ -3936,7 +4124,7 @@ STDMETHODIMP Machine::MountMedium(IN_BSTR aControllerName,
BOOL aForce)
{
int rc = S_OK;
- LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%ld aDevice=%ld aForce=%d\n",
+ LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%d aDevice=%d aForce=%d\n",
aControllerName, aControllerPort, aDevice, aForce));
CheckComArgStrNotEmptyOrNull(aControllerName);
@@ -4054,7 +4242,7 @@ STDMETHODIMP Machine::GetMedium(IN_BSTR aControllerName,
LONG aDevice,
IMedium **aMedium)
{
- LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%ld aDevice=%ld\n",
+ LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%d aDevice=%d\n",
aControllerName, aControllerPort, aDevice));
CheckComArgStrNotEmptyOrNull(aControllerName);
@@ -4356,10 +4544,10 @@ STDMETHODIMP Machine::Unregister(CleanupMode_T cleanupMode,
if (mData->mMachineState == MachineState_Saved)
{
// add the saved state file to the list of files the caller should delete
- Assert(!mSSData->mStateFilePath.isEmpty());
- mData->llFilesToDelete.push_back(mSSData->mStateFilePath);
+ Assert(!mSSData->strStateFilePath.isEmpty());
+ mData->llFilesToDelete.push_back(mSSData->strStateFilePath);
- mSSData->mStateFilePath.setNull();
+ mSSData->strStateFilePath.setNull();
// unconditionally set the machine state to powered off, we now
// know no session has locked the machine
@@ -4450,6 +4638,7 @@ STDMETHODIMP Machine::Unregister(CleanupMode_T cleanupMode,
struct Machine::DeleteTask
{
ComObjPtr<Machine> pMachine;
+ RTCList< ComPtr<IMedium> > llMediums;
std::list<Utf8Str> llFilesToDelete;
ComObjPtr<Progress> pProgress;
GuidList llRegistriesThatNeedSaving;
@@ -4481,20 +4670,17 @@ STDMETHODIMP Machine::Delete(ComSafeArrayIn(IMedium*, aMedia), IProgress **aProg
for (size_t i = 0; i < sfaMedia.size(); ++i)
{
IMedium *pIMedium(sfaMedia[i]);
- Medium *pMedium = static_cast<Medium*>(pIMedium);
- AutoCaller mediumAutoCaller(pMedium);
- if (FAILED(mediumAutoCaller.rc())) return mediumAutoCaller.rc();
-
- Utf8Str bstrLocation = pMedium->getLocationFull();
-
- bool fDoesMediumNeedFileDeletion = pMedium->isMediumFormatFile();
-
- // close the medium now; if that succeeds, then that means the medium is no longer
- // in use and we can add it to the list of files to delete
- rc = pMedium->close(&pTask->llRegistriesThatNeedSaving,
- mediumAutoCaller);
- if (SUCCEEDED(rc) && fDoesMediumNeedFileDeletion)
- pTask->llFilesToDelete.push_back(bstrLocation);
+ ComObjPtr<Medium> pMedium = static_cast<Medium*>(pIMedium);
+ if (pMedium.isNull())
+ return setError(E_INVALIDARG, "The given medium pointer with index %d is invalid", i);
+ SafeArray<BSTR> ids;
+ rc = pMedium->COMGETTER(MachineIds)(ComSafeArrayAsOutParam(ids));
+ if (FAILED(rc)) return rc;
+ /* At this point the medium should not have any back references
+ * anymore. If it has it is attached to another VM and *must* not
+ * deleted. */
+ if (ids.size() < 1)
+ pTask->llMediums.append(pMedium);
}
if (mData->pMachineConfigFile->fileExists())
pTask->llFilesToDelete.push_back(mData->m_strConfigFileFull);
@@ -4504,7 +4690,7 @@ STDMETHODIMP Machine::Delete(ComSafeArrayIn(IMedium*, aMedia), IProgress **aProg
static_cast<IMachine*>(this) /* aInitiator */,
Bstr(tr("Deleting files")).raw(),
true /* fCancellable */,
- pTask->llFilesToDelete.size() + 1, // cOperations
+ pTask->llFilesToDelete.size() + pTask->llMediums.size() + 1, // cOperations
BstrFmt(tr("Deleting '%s'"), pTask->llFilesToDelete.front().c_str()).raw());
int vrc = RTThreadCreate(NULL,
@@ -4569,96 +4755,147 @@ HRESULT Machine::deleteTaskWorker(DeleteTask &task)
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- ULONG uLogHistoryCount = 3;
- ComPtr<ISystemProperties> systemProperties;
- mParent->COMGETTER(SystemProperties)(systemProperties.asOutParam());
- if (!systemProperties.isNull())
- systemProperties->COMGETTER(LogHistoryCount)(&uLogHistoryCount);
+ HRESULT rc = S_OK;
- // delete the files pushed on the task list by Machine::Delete()
- // (this includes saved states of the machine and snapshots and
- // medium storage files from the IMedium list passed in, and the
- // machine XML file)
- std::list<Utf8Str>::const_iterator it = task.llFilesToDelete.begin();
- while (it != task.llFilesToDelete.end())
+ try
{
- const Utf8Str &strFile = *it;
- LogFunc(("Deleting file %s\n", strFile.c_str()));
- RTFileDelete(strFile.c_str());
+ ULONG uLogHistoryCount = 3;
+ ComPtr<ISystemProperties> systemProperties;
+ rc = mParent->COMGETTER(SystemProperties)(systemProperties.asOutParam());
+ if (FAILED(rc)) throw rc;
- ++it;
- if (it == task.llFilesToDelete.end())
+ if (!systemProperties.isNull())
{
- task.pProgress->SetNextOperation(Bstr(tr("Cleaning up machine directory")).raw(), 1);
- break;
+ rc = systemProperties->COMGETTER(LogHistoryCount)(&uLogHistoryCount);
+ if (FAILED(rc)) throw rc;
}
- task.pProgress->SetNextOperation(BstrFmt(tr("Deleting '%s'"), it->c_str()).raw(), 1);
- }
+ MachineState_T oldState = mData->mMachineState;
+ setMachineState(MachineState_SettingUp);
+ alock.release();
+ for (size_t i = 0; i < task.llMediums.size(); ++i)
+ {
+ ComObjPtr<Medium> pMedium = (Medium*)(IMedium*)task.llMediums.at(i);
+ {
+ AutoCaller mac(pMedium);
+ if (FAILED(mac.rc())) throw mac.rc();
+ Utf8Str strLocation = pMedium->getLocationFull();
+ rc = task.pProgress->SetNextOperation(BstrFmt(tr("Deleting '%s'"), strLocation.c_str()).raw(), 1);
+ if (FAILED(rc)) throw rc;
+ LogFunc(("Deleting file %s\n", strLocation.c_str()));
+ }
+ ComPtr<IProgress> pProgress2;
+ rc = pMedium->DeleteStorage(pProgress2.asOutParam());
+ if (FAILED(rc)) throw rc;
+ rc = task.pProgress->WaitForAsyncProgressCompletion(pProgress2);
+ if (FAILED(rc)) throw rc;
+ /* Check the result of the asynchrony process. */
+ LONG iRc;
+ rc = pProgress2->COMGETTER(ResultCode)(&iRc);
+ if (FAILED(rc)) throw rc;
+ if (FAILED(iRc))
+ {
+ /* If the thread of the progress object has an error, then
+ * retrieve the error info from there, or it'll be lost. */
+ ProgressErrorInfo info(pProgress2);
+ throw setError(iRc, Utf8Str(info.getText()).c_str());
+ }
+ }
+ setMachineState(oldState);
+ alock.acquire();
- /* delete the settings only when the file actually exists */
- if (mData->pMachineConfigFile->fileExists())
- {
- /* Delete any backup or uncommitted XML files. Ignore failures.
- See the fSafe parameter of xml::XmlFileWriter::write for details. */
- /** @todo Find a way to avoid referring directly to iprt/xml.h here. */
- Utf8Str otherXml = Utf8StrFmt("%s%s", mData->m_strConfigFileFull.c_str(), xml::XmlFileWriter::s_pszTmpSuff);
- RTFileDelete(otherXml.c_str());
- otherXml = Utf8StrFmt("%s%s", mData->m_strConfigFileFull.c_str(), xml::XmlFileWriter::s_pszPrevSuff);
- RTFileDelete(otherXml.c_str());
-
- /* delete the Logs folder, nothing important should be left
- * there (we don't check for errors because the user might have
- * some private files there that we don't want to delete) */
- Utf8Str logFolder;
- getLogFolder(logFolder);
- Assert(logFolder.length());
- if (RTDirExists(logFolder.c_str()))
- {
- /* Delete all VBox.log[.N] files from the Logs folder
- * (this must be in sync with the rotation logic in
- * Console::powerUpThread()). Also, delete the VBox.png[.N]
- * files that may have been created by the GUI. */
- Utf8Str log = Utf8StrFmt("%s%cVBox.log",
- logFolder.c_str(), RTPATH_DELIMITER);
- RTFileDelete(log.c_str());
- log = Utf8StrFmt("%s%cVBox.png",
- logFolder.c_str(), RTPATH_DELIMITER);
- RTFileDelete(log.c_str());
- for (int i = uLogHistoryCount; i > 0; i--)
+ // delete the files pushed on the task list by Machine::Delete()
+ // (this includes saved states of the machine and snapshots and
+ // medium storage files from the IMedium list passed in, and the
+ // machine XML file)
+ std::list<Utf8Str>::const_iterator it = task.llFilesToDelete.begin();
+ while (it != task.llFilesToDelete.end())
+ {
+ const Utf8Str &strFile = *it;
+ LogFunc(("Deleting file %s\n", strFile.c_str()));
+ int vrc = RTFileDelete(strFile.c_str());
+ if (RT_FAILURE(vrc))
+ throw setError(VBOX_E_IPRT_ERROR,
+ tr("Could not delete file '%s' (%Rrc)"), strFile.c_str(), vrc);
+
+ ++it;
+ if (it == task.llFilesToDelete.end())
{
- log = Utf8StrFmt("%s%cVBox.log.%d",
- logFolder.c_str(), RTPATH_DELIMITER, i);
+ rc = task.pProgress->SetNextOperation(Bstr(tr("Cleaning up machine directory")).raw(), 1);
+ if (FAILED(rc)) throw rc;
+ break;
+ }
+
+ rc = task.pProgress->SetNextOperation(BstrFmt(tr("Deleting '%s'"), it->c_str()).raw(), 1);
+ if (FAILED(rc)) throw rc;
+ }
+
+ /* delete the settings only when the file actually exists */
+ if (mData->pMachineConfigFile->fileExists())
+ {
+ /* Delete any backup or uncommitted XML files. Ignore failures.
+ See the fSafe parameter of xml::XmlFileWriter::write for details. */
+ /** @todo Find a way to avoid referring directly to iprt/xml.h here. */
+ Utf8Str otherXml = Utf8StrFmt("%s%s", mData->m_strConfigFileFull.c_str(), xml::XmlFileWriter::s_pszTmpSuff);
+ RTFileDelete(otherXml.c_str());
+ otherXml = Utf8StrFmt("%s%s", mData->m_strConfigFileFull.c_str(), xml::XmlFileWriter::s_pszPrevSuff);
+ RTFileDelete(otherXml.c_str());
+
+ /* delete the Logs folder, nothing important should be left
+ * there (we don't check for errors because the user might have
+ * some private files there that we don't want to delete) */
+ Utf8Str logFolder;
+ getLogFolder(logFolder);
+ Assert(logFolder.length());
+ if (RTDirExists(logFolder.c_str()))
+ {
+ /* Delete all VBox.log[.N] files from the Logs folder
+ * (this must be in sync with the rotation logic in
+ * Console::powerUpThread()). Also, delete the VBox.png[.N]
+ * files that may have been created by the GUI. */
+ Utf8Str log = Utf8StrFmt("%s%cVBox.log",
+ logFolder.c_str(), RTPATH_DELIMITER);
RTFileDelete(log.c_str());
- log = Utf8StrFmt("%s%cVBox.png.%d",
- logFolder.c_str(), RTPATH_DELIMITER, i);
+ log = Utf8StrFmt("%s%cVBox.png",
+ logFolder.c_str(), RTPATH_DELIMITER);
RTFileDelete(log.c_str());
+ for (int i = uLogHistoryCount; i > 0; i--)
+ {
+ log = Utf8StrFmt("%s%cVBox.log.%d",
+ logFolder.c_str(), RTPATH_DELIMITER, i);
+ RTFileDelete(log.c_str());
+ log = Utf8StrFmt("%s%cVBox.png.%d",
+ logFolder.c_str(), RTPATH_DELIMITER, i);
+ RTFileDelete(log.c_str());
+ }
+
+ RTDirRemove(logFolder.c_str());
}
- RTDirRemove(logFolder.c_str());
+ /* delete the Snapshots folder, nothing important should be left
+ * there (we don't check for errors because the user might have
+ * some private files there that we don't want to delete) */
+ Utf8Str strFullSnapshotFolder;
+ calculateFullPath(mUserData->s.strSnapshotFolder, strFullSnapshotFolder);
+ Assert(!strFullSnapshotFolder.isEmpty());
+ if (RTDirExists(strFullSnapshotFolder.c_str()))
+ RTDirRemove(strFullSnapshotFolder.c_str());
+
+ // delete the directory that contains the settings file, but only
+ // if it matches the VM name
+ Utf8Str settingsDir;
+ if (isInOwnDir(&settingsDir))
+ RTDirRemove(settingsDir.c_str());
}
- /* delete the Snapshots folder, nothing important should be left
- * there (we don't check for errors because the user might have
- * some private files there that we don't want to delete) */
- Utf8Str strFullSnapshotFolder;
- calculateFullPath(mUserData->s.strSnapshotFolder, strFullSnapshotFolder);
- Assert(!strFullSnapshotFolder.isEmpty());
- if (RTDirExists(strFullSnapshotFolder.c_str()))
- RTDirRemove(strFullSnapshotFolder.c_str());
+ alock.release();
- // delete the directory that contains the settings file, but only
- // if it matches the VM name
- Utf8Str settingsDir;
- if (isInOwnDir(&settingsDir))
- RTDirRemove(settingsDir.c_str());
+ rc = mParent->saveRegistries(task.llRegistriesThatNeedSaving);
+ if (FAILED(rc)) throw rc;
}
+ catch (HRESULT aRC) { rc = aRC; }
- alock.release();
-
- mParent->saveRegistries(task.llRegistriesThatNeedSaving);
-
- return S_OK;
+ return rc;
}
STDMETHODIMP Machine::FindSnapshot(IN_BSTR aNameOrId, ISnapshot **aSnapshot)
@@ -5025,30 +5262,22 @@ HRESULT Machine::setGuestPropertyToService(IN_BSTR aName, IN_BSTR aValue,
HRESULT Machine::setGuestPropertyToVM(IN_BSTR aName, IN_BSTR aValue,
IN_BSTR aFlags)
{
- CheckComArgStrNotEmptyOrNull(aName);
- if ((aValue != NULL) && !VALID_PTR(aValue))
- return E_INVALIDARG;
- if ((aFlags != NULL) && !VALID_PTR(aFlags))
- return E_INVALIDARG;
-
HRESULT rc;
- try {
- ComPtr<IInternalSessionControl> directControl =
- mData->mSession.mDirectControl;
+ try
+ {
+ ComPtr<IInternalSessionControl> directControl = mData->mSession.mDirectControl;
BSTR dummy = NULL; /* will not be changed (setter) */
LONG64 dummy64;
if (!directControl)
rc = E_ACCESSDENIED;
else
- rc = directControl->AccessGuestProperty
- (aName,
- /** @todo Fix when adding DeleteGuestProperty(),
- see defect. */
- aValue, aFlags,
- true /* isSetter */,
- &dummy, &dummy64, &dummy);
+ /** @todo Fix when adding DeleteGuestProperty(),
+ see defect. */
+ rc = directControl->AccessGuestProperty(aName, aValue, aFlags,
+ true /* isSetter */,
+ &dummy, &dummy64, &dummy);
}
catch (std::bad_alloc &)
{
@@ -5066,10 +5295,12 @@ STDMETHODIMP Machine::SetGuestProperty(IN_BSTR aName, IN_BSTR aValue,
ReturnComNotImplemented();
#else // VBOX_WITH_GUEST_PROPS
CheckComArgStrNotEmptyOrNull(aName);
- if ((aFlags != NULL) && !VALID_PTR(aFlags))
- return E_INVALIDARG;
+ CheckComArgMaybeNull(aFlags);
+ CheckComArgMaybeNull(aValue);
+
AutoCaller autoCaller(this);
- if (FAILED(autoCaller.rc())) return autoCaller.rc();
+ if (FAILED(autoCaller.rc()))
+ return autoCaller.rc();
HRESULT rc = setGuestPropertyToVM(aName, aValue, aFlags);
if (rc == E_ACCESSDENIED)
@@ -5180,9 +5411,7 @@ STDMETHODIMP Machine::EnumerateGuestProperties(IN_BSTR aPatterns,
#ifndef VBOX_WITH_GUEST_PROPS
ReturnComNotImplemented();
#else // VBOX_WITH_GUEST_PROPS
- if (!VALID_PTR(aPatterns) && (aPatterns != NULL))
- return E_POINTER;
-
+ CheckComArgMaybeNull(aPatterns);
CheckComArgOutSafeArrayPointerValid(aNames);
CheckComArgOutSafeArrayPointerValid(aValues);
CheckComArgOutSafeArrayPointerValid(aTimestamps);
@@ -5468,7 +5697,7 @@ STDMETHODIMP Machine::QuerySavedGuestSize(ULONG uScreenId, ULONG *puWidth, ULONG
uint32_t u32Width = 0;
uint32_t u32Height = 0;
- int vrc = readSavedGuestSize(mSSData->mStateFilePath, uScreenId, &u32Width, &u32Height);
+ int vrc = readSavedGuestSize(mSSData->strStateFilePath, uScreenId, &u32Width, &u32Height);
if (RT_FAILURE(vrc))
return setError(VBOX_E_IPRT_ERROR,
tr("Saved guest size is not available (%Rrc)"),
@@ -5501,7 +5730,7 @@ STDMETHODIMP Machine::QuerySavedThumbnailSize(ULONG aScreenId, ULONG *aSize, ULO
uint32_t u32Width = 0;
uint32_t u32Height = 0;
- int vrc = readSavedDisplayScreenshot(mSSData->mStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
+ int vrc = readSavedDisplayScreenshot(mSSData->strStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
if (RT_FAILURE(vrc))
return setError(VBOX_E_IPRT_ERROR,
@@ -5538,7 +5767,7 @@ STDMETHODIMP Machine::ReadSavedThumbnailToArray(ULONG aScreenId, BOOL aBGR, ULON
uint32_t u32Width = 0;
uint32_t u32Height = 0;
- int vrc = readSavedDisplayScreenshot(mSSData->mStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
+ int vrc = readSavedDisplayScreenshot(mSSData->strStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
if (RT_FAILURE(vrc))
return setError(VBOX_E_IPRT_ERROR,
@@ -5601,7 +5830,7 @@ STDMETHODIMP Machine::ReadSavedThumbnailPNGToArray(ULONG aScreenId, ULONG *aWidt
uint32_t u32Width = 0;
uint32_t u32Height = 0;
- int vrc = readSavedDisplayScreenshot(mSSData->mStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
+ int vrc = readSavedDisplayScreenshot(mSSData->strStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
if (RT_FAILURE(vrc))
return setError(VBOX_E_IPRT_ERROR,
@@ -5650,7 +5879,7 @@ STDMETHODIMP Machine::QuerySavedScreenshotPNGSize(ULONG aScreenId, ULONG *aSize,
uint32_t u32Width = 0;
uint32_t u32Height = 0;
- int vrc = readSavedDisplayScreenshot(mSSData->mStateFilePath, 1 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
+ int vrc = readSavedDisplayScreenshot(mSSData->strStateFilePath, 1 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
if (RT_FAILURE(vrc))
return setError(VBOX_E_IPRT_ERROR,
@@ -5687,7 +5916,7 @@ STDMETHODIMP Machine::ReadSavedScreenshotPNGToArray(ULONG aScreenId, ULONG *aWid
uint32_t u32Width = 0;
uint32_t u32Height = 0;
- int vrc = readSavedDisplayScreenshot(mSSData->mStateFilePath, 1 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
+ int vrc = readSavedDisplayScreenshot(mSSData->strStateFilePath, 1 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
if (RT_FAILURE(vrc))
return setError(VBOX_E_IPRT_ERROR,
@@ -5879,32 +6108,116 @@ STDMETHODIMP Machine::ReadLog(ULONG aIdx, LONG64 aOffset, LONG64 aSize, ComSafeA
}
-STDMETHODIMP Machine::AttachHostPciDevice(LONG hostAddress, LONG desiredGuestAddress, IEventContext * /*eventContext*/, BOOL /*tryToUnbind*/)
+/**
+ * Currently this method doesn't attach device to the running VM,
+ * just makes sure it's plugged on next VM start.
+ */
+STDMETHODIMP Machine::AttachHostPciDevice(LONG hostAddress, LONG desiredGuestAddress, BOOL /*tryToUnbind*/)
{
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- ComObjPtr<PciDeviceAttachment> pda;
- char name[32];
+ // lock scope
+ {
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ HRESULT rc = checkStateDependency(MutableStateDep);
+ if (FAILED(rc)) return rc;
- pda.createObject();
- RTStrPrintf(name, sizeof(name), "host%02x:%02x.%x", (hostAddress>>8) & 0xff, (hostAddress & 0xf8) >> 3, hostAddress & 7);
- Bstr bname(name);
- pda.createObject();
- pda->init(this, bname, hostAddress, desiredGuestAddress, TRUE);
+ ChipsetType_T aChipset = ChipsetType_PIIX3;
+ COMGETTER(ChipsetType)(&aChipset);
+
+ if (aChipset != ChipsetType_ICH9)
+ {
+ return setError(E_INVALIDARG,
+ tr("Host PCI attachment only supported with ICH9 chipset"));
+ }
+
+ // check if device with this host PCI address already attached
+ for (HWData::PciDeviceAssignmentList::iterator it = mHWData->mPciDeviceAssignments.begin();
+ it != mHWData->mPciDeviceAssignments.end();
+ ++it)
+ {
+ LONG iHostAddress = -1;
+ ComPtr<PciDeviceAttachment> pAttach;
+ pAttach = *it;
+ pAttach->COMGETTER(HostAddress)(&iHostAddress);
+ if (iHostAddress == hostAddress)
+ return setError(E_INVALIDARG,
+ tr("Device with host PCI address already attached to this VM"));
+ }
+
+ ComObjPtr<PciDeviceAttachment> pda;
+ char name[32];
+
+ RTStrPrintf(name, sizeof(name), "host%02x:%02x.%x", (hostAddress>>8) & 0xff, (hostAddress & 0xf8) >> 3, hostAddress & 7);
+ Bstr bname(name);
+ pda.createObject();
+ pda->init(this, bname, hostAddress, desiredGuestAddress, TRUE);
+ setModified(IsModified_MachineData);
+ mHWData.backup();
+ mHWData->mPciDeviceAssignments.push_back(pda);
+ }
- mPciDeviceAssignments.push_back(pda);
return S_OK;
}
-STDMETHODIMP Machine::DetachHostPciDevice(LONG /*hostAddress*/)
+/**
+ * Currently this method doesn't detach device from the running VM,
+ * just makes sure it's not plugged on next VM start.
+ */
+STDMETHODIMP Machine::DetachHostPciDevice(LONG hostAddress)
{
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- return E_NOTIMPL;
+ ComObjPtr<PciDeviceAttachment> pAttach;
+ bool fRemoved = false;
+ HRESULT rc;
+
+ // lock scope
+ {
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ rc = checkStateDependency(MutableStateDep);
+ if (FAILED(rc)) return rc;
+
+ for (HWData::PciDeviceAssignmentList::iterator it = mHWData->mPciDeviceAssignments.begin();
+ it != mHWData->mPciDeviceAssignments.end();
+ ++it)
+ {
+ LONG iHostAddress = -1;
+ pAttach = *it;
+ pAttach->COMGETTER(HostAddress)(&iHostAddress);
+ if (iHostAddress != -1 && iHostAddress == hostAddress)
+ {
+ setModified(IsModified_MachineData);
+ mHWData.backup();
+ mHWData->mPciDeviceAssignments.remove(pAttach);
+ fRemoved = true;
+ break;
+ }
+ }
+ }
+
+
+ /* Fire event outside of the lock */
+ if (fRemoved)
+ {
+ Assert(!pAttach.isNull());
+ ComPtr<IEventSource> es;
+ rc = mParent->COMGETTER(EventSource)(es.asOutParam());
+ Assert(SUCCEEDED(rc));
+ Bstr mid;
+ rc = this->COMGETTER(Id)(mid.asOutParam());
+ Assert(SUCCEEDED(rc));
+ fireHostPciDevicePlugEvent(es, mid.raw(), false /* unplugged */, true /* success */, pAttach, NULL);
+ }
+
+ return fRemoved ? S_OK : setError(VBOX_E_OBJECT_NOT_FOUND,
+ tr("No host PCI device %08x attached"),
+ hostAddress
+ );
}
STDMETHODIMP Machine::COMGETTER(PciDeviceAssignments)(ComSafeArrayOut(IPciDeviceAttachment *, aAssignments))
@@ -5916,7 +6229,7 @@ STDMETHODIMP Machine::COMGETTER(PciDeviceAssignments)(ComSafeArrayOut(IPciDevice
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- SafeIfaceArray<IPciDeviceAttachment> assignments(mPciDeviceAssignments);
+ SafeIfaceArray<IPciDeviceAttachment> assignments(mHWData->mPciDeviceAssignments);
assignments.detachTo(ComSafeArrayOutArg(aAssignments));
return S_OK;
@@ -5934,6 +6247,48 @@ STDMETHODIMP Machine::COMGETTER(BandwidthControl)(IBandwidthControl **aBandwidth
return S_OK;
}
+STDMETHODIMP Machine::CloneTo(IMachine *pTarget, CloneMode_T mode, ComSafeArrayIn(CloneOptions_T, options), IProgress **pProgress)
+{
+ LogFlowFuncEnter();
+
+ CheckComArgNotNull(pTarget);
+ CheckComArgOutPointerValid(pProgress);
+
+ /** @todo r=klaus disabled as there are apparently still cases which are
+ * not handled correctly */
+ if (mode == CloneMode_MachineAndChildStates)
+ return setError(VBOX_E_NOT_SUPPORTED,
+ tr("The clone mode \"Machine and child states\" is not yet supported. Please try again in the next VirtualBox maintenance update"));
+
+ /* Convert the options. */
+ RTCList<CloneOptions_T> optList;
+ if (options != NULL)
+ optList = com::SafeArray<CloneOptions_T>(ComSafeArrayInArg(options)).toList();
+
+ if (optList.contains(CloneOptions_Link))
+ {
+ if (!isSnapshotMachine())
+ return setError(E_INVALIDARG,
+ tr("Linked clone can only be created from a snapshot"));
+ if (mode != CloneMode_MachineState)
+ return setError(E_INVALIDARG,
+ tr("Linked clone can only be created for a single machine state"));
+ }
+ AssertReturn(!(optList.contains(CloneOptions_KeepAllMACs) && optList.contains(CloneOptions_KeepNATMACs)), E_INVALIDARG);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+
+ MachineCloneVM *pWorker = new MachineCloneVM(this, static_cast<Machine*>(pTarget), mode, optList);
+
+ HRESULT rc = pWorker->start(pProgress);
+
+ LogFlowFuncLeave();
+
+ return rc;
+}
+
// public methods for internal purposes
/////////////////////////////////////////////////////////////////////////////
@@ -5948,6 +6303,18 @@ void Machine::setModified(uint32_t fl)
}
/**
+ * Adds the given IsModified_* flag to the dirty flags of the machine, taking
+ * care of the write locking.
+ *
+ * @param fModifications The flag to add.
+ */
+void Machine::setModifiedLock(uint32_t fModification)
+{
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ mData->flModifications |= fModification;
+}
+
+/**
* Saves the registry entry of this machine to the given configuration node.
*
* @param aEntryNode Node to save the registry entry to.
@@ -6069,6 +6436,44 @@ Utf8Str Machine::queryLogFilename(ULONG idx)
}
/**
+ * Composes a unique saved state filename based on the current system time. The filename is
+ * granular to the second so this will work so long as no more than one snapshot is taken on
+ * a machine per second.
+ *
+ * Before version 4.1, we used this formula for saved state files:
+ * Utf8StrFmt("%s%c{%RTuuid}.sav", strFullSnapshotFolder.c_str(), RTPATH_DELIMITER, mData->mUuid.raw())
+ * which no longer works because saved state files can now be shared between the saved state of the
+ * "saved" machine and an online snapshot, and the following would cause problems:
+ * 1) save machine
+ * 2) create online snapshot from that machine state --> reusing saved state file
+ * 3) save machine again --> filename would be reused, breaking the online snapshot
+ *
+ * So instead we now use a timestamp.
+ *
+ * @param str
+ */
+void Machine::composeSavedStateFilename(Utf8Str &strStateFilePath)
+{
+ AutoCaller autoCaller(this);
+ AssertComRCReturnVoid(autoCaller.rc());
+
+ {
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ calculateFullPath(mUserData->s.strSnapshotFolder, strStateFilePath);
+ }
+
+ RTTIMESPEC ts;
+ RTTimeNow(&ts);
+ RTTIME time;
+ RTTimeExplode(&time, &ts);
+
+ strStateFilePath += RTPATH_DELIMITER;
+ strStateFilePath += Utf8StrFmt("%04d-%02u-%02uT%02u-%02u-%02u-%09uZ.sav",
+ time.i32Year, time.u8Month, time.u8MonthDay,
+ time.u8Hour, time.u8Minute, time.u8Second, time.u32Nanosecond);
+}
+
+/**
* @note Locks this object for writing, calls the client process
* (inside the lock).
*/
@@ -6199,6 +6604,7 @@ HRESULT Machine::launchVMProcess(IInternalSessionControl *aControl,
Utf8Str idStr = mData->mUuid.toString();
const char * args[] = {szPath, "--comment", mUserData->s.strName.c_str(), "--startvm", idStr.c_str(), 0 };
+ fprintf(stderr, "SDL=%s\n", szPath);
vrc = RTProcCreate(szPath, args, env, 0, &pid);
}
#else /* !VBOX_WITH_VBOXSDL */
@@ -7078,6 +7484,8 @@ HRESULT Machine::findSharedFolder(const Utf8Str &aName,
* ensure that the media listed as attachments in the config (which have
* been imported from the OVF) receive the correct registry ID.
*
+ * -- During VM cloning.
+ *
* @param config Machine settings from XML.
* @param puuidRegistry If != NULL, Medium::setRegistryIdIfFirst() gets called with this registry ID for each attached medium in the config.
* @return
@@ -7096,7 +7504,7 @@ HRESULT Machine::loadMachineDataFromSettings(const settings::MachineConfigFile &
// stateFile (optional)
if (config.strStateFile.isEmpty())
- mSSData->mStateFilePath.setNull();
+ mSSData->strStateFilePath.setNull();
else
{
Utf8Str stateFilePathFull(config.strStateFile);
@@ -7106,13 +7514,18 @@ HRESULT Machine::loadMachineDataFromSettings(const settings::MachineConfigFile &
tr("Invalid saved state file path '%s' (%Rrc)"),
config.strStateFile.c_str(),
vrc);
- mSSData->mStateFilePath = stateFilePathFull;
+ mSSData->strStateFilePath = stateFilePathFull;
}
// snapshot folder needs special processing so set it again
rc = COMSETTER(SnapshotFolder)(Bstr(config.machineUserData.strSnapshotFolder).raw());
if (FAILED(rc)) return rc;
+ /* Copy the extra data items (Not in any case config is already the same as
+ * mData->pMachineConfigFile, like when the xml files are read from disk. So
+ * make sure the extra data map is copied). */
+ mData->pMachineConfigFile->mapExtraDataItems = config.mapExtraDataItems;
+
/* currentStateModified (optional, default is true) */
mData->mCurrentStateModified = config.fCurrentStateModified;
@@ -7172,13 +7585,12 @@ HRESULT Machine::loadMachineDataFromSettings(const settings::MachineConfigFile &
/* set the machine state to Aborted or Saved when appropriate */
if (config.fAborted)
{
- Assert(!mSSData->mStateFilePath.isEmpty());
- mSSData->mStateFilePath.setNull();
+ mSSData->strStateFilePath.setNull();
/* no need to use setMachineState() during init() */
mData->mMachineState = MachineState_Aborted;
}
- else if (!mSSData->mStateFilePath.isEmpty())
+ else if (!mSSData->strStateFilePath.isEmpty())
{
/* no need to use setMachineState() during init() */
mData->mMachineState = MachineState_Saved;
@@ -7385,6 +7797,10 @@ HRESULT Machine::loadHardware(const settings::Hardware &data)
rc = mBIOSSettings->loadSettings(data.biosSettings);
if (FAILED(rc)) return rc;
+ // Bandwidth control (must come before network adapters)
+ rc = mBandwidthControl->loadSettings(data.ioSettings);
+ if (FAILED(rc)) return rc;
+
/* USB Controller */
rc = mUSBController->loadSettings(data.usbController);
if (FAILED(rc)) return rc;
@@ -7398,7 +7814,7 @@ HRESULT Machine::loadHardware(const settings::Hardware &data)
/* slot unicity is guaranteed by XML Schema */
AssertBreak(nic.ulSlot < RT_ELEMENTS(mNetworkAdapters));
- rc = mNetworkAdapters[nic.ulSlot]->loadSettings(nic);
+ rc = mNetworkAdapters[nic.ulSlot]->loadSettings(mBandwidthControl, nic);
if (FAILED(rc)) return rc;
}
@@ -7451,9 +7867,18 @@ HRESULT Machine::loadHardware(const settings::Hardware &data)
mHWData->mIoCacheEnabled = data.ioSettings.fIoCacheEnabled;
mHWData->mIoCacheSize = data.ioSettings.ulIoCacheSize;
- // Bandwidth control
- rc = mBandwidthControl->loadSettings(data.ioSettings);
- if (FAILED(rc)) return rc;
+ // Host PCI devices
+ for (settings::HostPciDeviceAttachmentList::const_iterator it = data.pciAttachments.begin();
+ it != data.pciAttachments.end();
+ ++it)
+ {
+ const settings::HostPciDeviceAttachment &hpda = *it;
+ ComObjPtr<PciDeviceAttachment> pda;
+
+ pda.createObject();
+ pda->loadSettings(this, hpda);
+ mHWData->mPciDeviceAssignments.push_back(pda);
+ }
#ifdef VBOX_WITH_GUEST_PROPS
/* Guest properties (optional) */
@@ -7742,7 +8167,10 @@ HRESULT Machine::loadStorageDevices(StorageController *aStorageController,
dev.lPort,
dev.lDevice,
dev.deviceType,
+ false,
dev.fPassThrough,
+ dev.fTempEject,
+ dev.fNonRotational,
pBwGroup.isNull() ? Utf8Str::Empty : pBwGroup->getName());
if (FAILED(rc)) break;
@@ -8030,16 +8458,11 @@ HRESULT Machine::prepareSaveSettings(bool *pfNeedsGlobalSaveSettings)
*pfNeedsGlobalSaveSettings = true;
}
- /* update the saved state file path */
- Utf8Str path = mSSData->mStateFilePath;
- if (RTPathStartsWith(path.c_str(), configDir.c_str()))
- mSSData->mStateFilePath = Utf8StrFmt("%s%s",
- newConfigDir.c_str(),
- path.c_str() + configDir.length());
+ // in the saved state file path, replace the old directory with the new directory
+ if (RTPathStartsWith(mSSData->strStateFilePath.c_str(), configDir.c_str()))
+ mSSData->strStateFilePath = newConfigDir.append(mSSData->strStateFilePath.c_str() + configDir.length());
- /* Update saved state file paths of all online snapshots.
- * Note that saveSettings() will recognize name change
- * and will save all snapshots in this case. */
+ // and do the same thing for the saved state file paths of all the online snapshots
if (mData->mFirstSnapshot)
mData->mFirstSnapshot->updateSavedStatePaths(configDir.c_str(),
newConfigDir.c_str());
@@ -8275,17 +8698,17 @@ void Machine::copyMachineDataToSettings(settings::MachineConfigFile &config)
|| ( ( mData->mMachineState == MachineState_DeletingSnapshot
|| mData->mMachineState == MachineState_DeletingSnapshotOnline
|| mData->mMachineState == MachineState_DeletingSnapshotPaused)
- && (!mSSData->mStateFilePath.isEmpty())
+ && (!mSSData->strStateFilePath.isEmpty())
)
)
{
- Assert(!mSSData->mStateFilePath.isEmpty());
+ Assert(!mSSData->strStateFilePath.isEmpty());
/* try to make the file name relative to the settings file dir */
- copyPathRelativeToMachine(mSSData->mStateFilePath, config.strStateFile);
+ copyPathRelativeToMachine(mSSData->strStateFilePath, config.strStateFile);
}
else
{
- Assert(mSSData->mStateFilePath.isEmpty());
+ Assert(mSSData->strStateFilePath.isEmpty() || mData->mMachineState == MachineState_Saving);
config.strStateFile.setNull();
}
@@ -8382,7 +8805,7 @@ HRESULT Machine::saveHardware(settings::Hardware &data)
/* The hardware version attribute (optional).
Automatically upgrade from 1 to 2 when there is no saved state. (ugly!) */
if ( mHWData->mHWVersion == "1"
- && mSSData->mStateFilePath.isEmpty()
+ && mSSData->strStateFilePath.isEmpty()
)
mHWData->mHWVersion = "2"; /** @todo Is this safe, to update mHWVersion here? If not some other point needs to be found where this can be done. */
@@ -8550,6 +8973,21 @@ HRESULT Machine::saveHardware(settings::Hardware &data)
rc = mBandwidthControl->saveSettings(data.ioSettings);
if (FAILED(rc)) throw rc;
+ /* Host PCI devices */
+ for (HWData::PciDeviceAssignmentList::const_iterator it = mHWData->mPciDeviceAssignments.begin();
+ it != mHWData->mPciDeviceAssignments.end();
+ ++it)
+ {
+ ComObjPtr<PciDeviceAttachment> pda = *it;
+ settings::HostPciDeviceAttachment hpda;
+
+ rc = pda->saveSettings(hpda);
+ if (FAILED(rc)) throw rc;
+
+ data.pciAttachments.push_back(hpda);
+ }
+
+
// guest properties
data.llGuestProperties.clear();
#ifdef VBOX_WITH_GUEST_PROPS
@@ -8679,6 +9117,8 @@ HRESULT Machine::saveStorageDevices(ComObjPtr<StorageController> aStorageControl
else
dev.uuid = pMedium->getId();
dev.fPassThrough = pAttach->getPassthrough();
+ dev.fTempEject = pAttach->getTempEject();
+ dev.fNonRotational = pAttach->getNonRotational();
}
dev.strBwGroup = pAttach->getBandwidthGroup();
@@ -8720,9 +9160,9 @@ HRESULT Machine::saveStateSettings(int aFlags)
if (aFlags & SaveSTS_StateFilePath)
{
- if (!mSSData->mStateFilePath.isEmpty())
+ if (!mSSData->strStateFilePath.isEmpty())
/* try to make the file name relative to the settings file dir */
- copyPathRelativeToMachine(mSSData->mStateFilePath, mData->pMachineConfigFile->strStateFile);
+ copyPathRelativeToMachine(mSSData->strStateFilePath, mData->pMachineConfigFile->strStateFile);
else
mData->pMachineConfigFile->strStateFile.setNull();
}
@@ -8730,7 +9170,7 @@ HRESULT Machine::saveStateSettings(int aFlags)
if (aFlags & SaveSTS_StateTimeStamp)
{
Assert( mData->mMachineState != MachineState_Aborted
- || mSSData->mStateFilePath.isEmpty());
+ || mSSData->strStateFilePath.isEmpty());
mData->pMachineConfigFile->timeLastStateChange = mData->mLastStateChange;
@@ -8780,7 +9220,7 @@ void Machine::addMediumToRegistry(ComObjPtr<Medium> &pMedium,
if (pMedium->addRegistry(uuid, false /* fRecurse */))
// registry actually changed:
- mParent->addGuidToListUniquely(llRegistriesThatNeedSaving, uuid);
+ VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, uuid);
if (puuid)
*puuid = uuid;
@@ -9000,6 +9440,9 @@ HRESULT Machine::createImplicitDiffs(IProgress *aProgress,
pAtt->getDevice(),
DeviceType_HardDisk,
true /* aImplicit */,
+ false /* aPassthrough */,
+ false /* aTempEject */,
+ false /* aNonRotational */,
pAtt->getBandwidthGroup());
if (FAILED(rc)) throw rc;
@@ -9031,9 +9474,9 @@ HRESULT Machine::createImplicitDiffs(IProgress *aProgress,
/**
* Deletes implicit differencing hard disks created either by
- * #createImplicitDiffs() or by #AttachMedium() and rolls back mMediaData.
+ * #createImplicitDiffs() or by #AttachDevice() and rolls back mMediaData.
*
- * Note that to delete hard disks created by #AttachMedium() this method is
+ * Note that to delete hard disks created by #AttachDevice() this method is
* called from #fixupMedia() when the changes are rolled back.
*
* @param pllRegistriesThatNeedSaving Optional pointer to a list of UUIDs to receive the registry IDs that need saving
@@ -9329,12 +9772,41 @@ HRESULT Machine::detachAllMedia(AutoWriteLock &writeLock,
if (!pMedium.isNull())
{
+ AutoCaller mac(pMedium);
+ if (FAILED(mac.rc())) return mac.rc();
+ AutoReadLock lock(pMedium COMMA_LOCKVAL_SRC_POS);
DeviceType_T devType = pMedium->getDeviceType();
if ( ( cleanupMode == CleanupMode_DetachAllReturnHardDisksOnly
&& devType == DeviceType_HardDisk)
|| (cleanupMode == CleanupMode_Full)
)
+ {
llMedia.push_back(pMedium);
+ ComObjPtr<Medium> pParent = pMedium->getParent();
+ /*
+ * Search for medias which are not attached to any machine, but
+ * in the chain to an attached disk. Mediums are only consided
+ * if they are:
+ * - have only one child
+ * - no references to any machines
+ * - are of normal medium type
+ */
+ while (!pParent.isNull())
+ {
+ AutoCaller mac1(pParent);
+ if (FAILED(mac1.rc())) return mac1.rc();
+ AutoReadLock lock1(pParent COMMA_LOCKVAL_SRC_POS);
+ if (pParent->getChildren().size() == 1)
+ {
+ if ( pParent->getMachineBackRefCount() == 0
+ && pParent->getType() == MediumType_Normal
+ && find(llMedia.begin(), llMedia.end(), pParent) == llMedia.end())
+ llMedia.push_back(pParent);
+ }else
+ break;
+ pParent = pParent->getParent();
+ }
+ }
}
// real machine: then we need to use the proper method
@@ -9508,10 +9980,11 @@ void Machine::commitMedia(bool aOnline /*= false*/)
* This is necessary because the stored parent will point to the
* session machine otherwise and cause crashes or errors later
* when the session machine gets invalid.
- *
- * @todo: Change the MediumAttachment class to behave like any other class
- * in this regard by creating peer MediumAttachment objects for
- * session machines and share the data with the peer machine.
+ */
+ /** @todo Change the MediumAttachment class to behave like any other
+ * class in this regard by creating peer MediumAttachment
+ * objects for session machines and share the data with the peer
+ * machine.
*/
for (MediaData::AttachmentList::const_iterator it = mMediaData->mAttachments.begin();
it != mMediaData->mAttachments.end();
@@ -9537,6 +10010,8 @@ void Machine::commitMedia(bool aOnline /*= false*/)
* by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed.
*
* @note Locks this object for writing!
+ *
+ * @todo r=dj this needs a pllRegistriesThatNeedSaving as well
*/
void Machine::rollbackMedia()
{
@@ -9945,6 +10420,31 @@ void Machine::copyFrom(Machine *aThat)
mParallelPorts[slot]->copyFrom(aThat->mParallelPorts[slot]);
}
+/**
+ * Returns whether the given storage controller is hotplug capable.
+ *
+ * @returns true if the controller supports hotplugging
+ * false otherwise.
+ * @param enmCtrlType The controller type to check for.
+ */
+bool Machine::isControllerHotplugCapable(StorageControllerType_T enmCtrlType)
+{
+ switch (enmCtrlType)
+ {
+ case StorageControllerType_IntelAhci:
+ return true;
+ case StorageControllerType_LsiLogic:
+ case StorageControllerType_LsiLogicSas:
+ case StorageControllerType_BusLogic:
+ case StorageControllerType_PIIX3:
+ case StorageControllerType_PIIX4:
+ case StorageControllerType_ICH6:
+ case StorageControllerType_I82078:
+ default:
+ return false;
+ }
+}
+
#ifdef VBOX_WITH_RESOURCE_USAGE_API
void Machine::registerMetrics(PerformanceCollector *aCollector, Machine *aMachine, RTPROCESS pid)
@@ -9992,8 +10492,11 @@ void Machine::registerMetrics(PerformanceCollector *aCollector, Machine *aMachin
new pm::AggregateMax()));
- /* Guest metrics */
- mGuestHAL = new pm::CollectorGuestHAL(this, hal);
+ /* Guest metrics collector */
+ mCollectorGuest = new pm::CollectorGuest(aMachine, pid);
+ aCollector->registerGuest(mCollectorGuest);
+ LogAleksey(("{%p} " LOG_FN_FMT ": mCollectorGuest=%p\n",
+ this, __PRETTY_FUNCTION__, mCollectorGuest));
/* Create sub metrics */
pm::SubMetric *guestLoadUser = new pm::SubMetric("Guest/CPU/Load/User",
@@ -10013,10 +10516,13 @@ void Machine::registerMetrics(PerformanceCollector *aCollector, Machine *aMachin
pm::SubMetric *guestPagedTotal = new pm::SubMetric("Guest/Pagefile/Usage/Total", "Total amount of space in the page file.");
/* Create and register base metrics */
- pm::BaseMetric *guestCpuLoad = new pm::GuestCpuLoad(mGuestHAL, aMachine, guestLoadUser, guestLoadKernel, guestLoadIdle);
+ pm::BaseMetric *guestCpuLoad = new pm::GuestCpuLoad(mCollectorGuest, aMachine,
+ guestLoadUser, guestLoadKernel, guestLoadIdle);
aCollector->registerBaseMetric(guestCpuLoad);
- pm::BaseMetric *guestCpuMem = new pm::GuestRamUsage(mGuestHAL, aMachine, guestMemTotal, guestMemFree, guestMemBalloon, guestMemShared,
+ pm::BaseMetric *guestCpuMem = new pm::GuestRamUsage(mCollectorGuest, aMachine,
+ guestMemTotal, guestMemFree,
+ guestMemBalloon, guestMemShared,
guestMemCache, guestPagedTotal);
aCollector->registerBaseMetric(guestCpuMem);
@@ -10075,12 +10581,6 @@ void Machine::unregisterMetrics(PerformanceCollector *aCollector, Machine *aMach
aCollector->unregisterMetricsFor(aMachine);
aCollector->unregisterBaseMetricsFor(aMachine);
}
-
- if (mGuestHAL)
- {
- delete mGuestHAL;
- mGuestHAL = NULL;
- }
}
#endif /* VBOX_WITH_RESOURCE_USAGE_API */
@@ -10104,7 +10604,7 @@ HRESULT SessionMachine::FinalConstruct()
# error "Port me!"
#endif
- return S_OK;
+ return BaseFinalConstruct();
}
void SessionMachine::FinalRelease()
@@ -10112,6 +10612,8 @@ void SessionMachine::FinalRelease()
LogFlowThisFunc(("\n"));
uninit(Uninit::Unexpected);
+
+ BaseFinalRelease();
}
/**
@@ -10388,10 +10890,27 @@ void SessionMachine::uninit(Uninit::Reason aReason)
// and others need mParent lock, and USB needs host lock.
AutoMultiWriteLock3 multilock(mParent, mParent->host(), this COMMA_LOCKVAL_SRC_POS);
+ LogAleksey(("{%p} " LOG_FN_FMT ": mCollectorGuest=%p\n",
+ this, __PRETTY_FUNCTION__, mCollectorGuest));
+ if (mCollectorGuest)
+ {
+ mParent->performanceCollector()->unregisterGuest(mCollectorGuest);
+ // delete mCollectorGuest; => CollectorGuestManager::destroyUnregistered()
+ mCollectorGuest = NULL;
+ }
+#if 0
// Trigger async cleanup tasks, avoid doing things here which are not
// vital to be done immediately and maybe need more locks. This calls
// Machine::unregisterMetrics().
mParent->onMachineUninit(mPeer);
+#else
+ /*
+ * It is safe to call Machine::unregisterMetrics() here because
+ * PerformanceCollector::samplerCallback no longer accesses guest methods
+ * holding the lock.
+ */
+ unregisterMetrics(mParent->performanceCollector(), mPeer);
+#endif
if (aReason == Uninit::Abnormal)
{
@@ -10410,8 +10929,9 @@ void SessionMachine::uninit(Uninit::Reason aReason)
rollback(false /* aNotify */);
}
- Assert(mConsoleTaskData.mStateFilePath.isEmpty() || !mConsoleTaskData.mSnapshot);
- if (!mConsoleTaskData.mStateFilePath.isEmpty())
+ Assert( mConsoleTaskData.strStateFilePath.isEmpty()
+ || !mConsoleTaskData.mSnapshot);
+ if (!mConsoleTaskData.strStateFilePath.isEmpty())
{
LogWarningThisFunc(("canceling failed save state request!\n"));
endSavingState(E_FAIL, tr("Machine terminated with pending save state!"));
@@ -10423,11 +10943,13 @@ void SessionMachine::uninit(Uninit::Reason aReason)
/* delete all differencing hard disks created (this will also attach
* their parents back by rolling back mMediaData) */
rollbackMedia();
- /* delete the saved state file (it might have been already created) */
- if (mConsoleTaskData.mSnapshot->stateFilePath().length())
- RTFileDelete(mConsoleTaskData.mSnapshot->stateFilePath().c_str());
+ // delete the saved state file (it might have been already created)
+ // AFTER killing the snapshot so that releaseSavedStateFile() won't
+ // think it's still in use
+ Utf8Str strStateFile = mConsoleTaskData.mSnapshot->getStateFilePath();
mConsoleTaskData.mSnapshot->uninit();
+ releaseSavedStateFile(strStateFile, NULL /* pSnapshotToIgnore */ );
}
if (!mData->mSession.mType.isEmpty())
@@ -11009,7 +11531,7 @@ STDMETHODIMP SessionMachine::BeginSavingState(IProgress **aProgress, BSTR *aStat
AssertReturn( mData->mMachineState == MachineState_Paused
&& mConsoleTaskData.mLastState == MachineState_Null
- && mConsoleTaskData.mStateFilePath.isEmpty(),
+ && mConsoleTaskData.strStateFilePath.isEmpty(),
E_FAIL);
/* create a progress object to track operation completion */
@@ -11020,27 +11542,20 @@ STDMETHODIMP SessionMachine::BeginSavingState(IProgress **aProgress, BSTR *aStat
Bstr(tr("Saving the execution state of the virtual machine")).raw(),
FALSE /* aCancelable */);
- Bstr stateFilePath;
+ Utf8Str strStateFilePath;
/* stateFilePath is null when the machine is not running */
if (mData->mMachineState == MachineState_Paused)
- {
- Utf8Str strFullSnapshotFolder;
- calculateFullPath(mUserData->s.strSnapshotFolder, strFullSnapshotFolder);
- stateFilePath = Utf8StrFmt("%s%c{%RTuuid}.sav",
- strFullSnapshotFolder.c_str(),
- RTPATH_DELIMITER,
- mData->mUuid.raw());
- }
+ composeSavedStateFilename(strStateFilePath);
/* fill in the console task data */
mConsoleTaskData.mLastState = mData->mMachineState;
- mConsoleTaskData.mStateFilePath = stateFilePath;
+ mConsoleTaskData.strStateFilePath = strStateFilePath;
mConsoleTaskData.mProgress = pProgress;
/* set the state to Saving (this is expected by Console::SaveState()) */
setMachineState(MachineState_Saving);
- stateFilePath.cloneTo(aStateFilePath);
+ strStateFilePath.cloneTo(aStateFilePath);
pProgress.queryInterfaceTo(aProgress);
return S_OK;
@@ -11062,7 +11577,7 @@ STDMETHODIMP SessionMachine::EndSavingState(LONG iResult, IN_BSTR aErrMsg)
AssertReturn( ( (SUCCEEDED(iResult) && mData->mMachineState == MachineState_Saved)
|| (FAILED(iResult) && mData->mMachineState == MachineState_Saving))
&& mConsoleTaskData.mLastState != MachineState_Null
- && !mConsoleTaskData.mStateFilePath.isEmpty(),
+ && !mConsoleTaskData.strStateFilePath.isEmpty(),
E_FAIL);
/*
@@ -11104,7 +11619,7 @@ STDMETHODIMP SessionMachine::AdoptSavedState(IN_BSTR aSavedStateFile)
aSavedStateFile,
vrc);
- mSSData->mStateFilePath = stateFilePathFull;
+ mSSData->strStateFilePath = stateFilePathFull;
/* The below setMachineState() will detect the state transition and will
* update the settings file */
@@ -11177,8 +11692,8 @@ STDMETHODIMP SessionMachine::PushGuestProperty(IN_BSTR aName,
using namespace guestProp;
CheckComArgStrNotEmptyOrNull(aName);
- if (aValue != NULL && (!VALID_PTR(aValue) || !VALID_PTR(aFlags)))
- return E_POINTER; /* aValue can be NULL to indicate deletion */
+ CheckComArgMaybeNull(aValue);
+ CheckComArgMaybeNull(aFlags);
try
{
@@ -11280,6 +11795,85 @@ STDMETHODIMP SessionMachine::PushGuestProperty(IN_BSTR aName,
#endif
}
+STDMETHODIMP SessionMachine::EjectMedium(IMediumAttachment *aAttachment,
+ IMediumAttachment **aNewAttachment)
+{
+ CheckComArgNotNull(aAttachment);
+ CheckComArgOutPointerValid(aNewAttachment);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ // request the host lock first, since might be calling Host methods for getting host drives;
+ // next, protect the media tree all the while we're in here, as well as our member variables
+ AutoMultiWriteLock3 multiLock(mParent->host()->lockHandle(),
+ this->lockHandle(),
+ &mParent->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
+
+ ComObjPtr<MediumAttachment> pAttach = static_cast<MediumAttachment *>(aAttachment);
+
+ Bstr ctrlName;
+ LONG lPort;
+ LONG lDevice;
+ bool fTempEject;
+ {
+ AutoCaller autoAttachCaller(this);
+ if (FAILED(autoAttachCaller.rc())) return autoAttachCaller.rc();
+
+ AutoReadLock attLock(pAttach COMMA_LOCKVAL_SRC_POS);
+
+ /* Need to query the details first, as the IMediumAttachment reference
+ * might be to the original settings, which we are going to change. */
+ ctrlName = pAttach->getControllerName();
+ lPort = pAttach->getPort();
+ lDevice = pAttach->getDevice();
+ fTempEject = pAttach->getTempEject();
+ }
+
+ if (!fTempEject)
+ {
+ /* Remember previously mounted medium. The medium before taking the
+ * backup is not necessarily the same thing. */
+ ComObjPtr<Medium> oldmedium;
+ oldmedium = pAttach->getMedium();
+
+ setModified(IsModified_Storage);
+ mMediaData.backup();
+
+ // The backup operation makes the pAttach reference point to the
+ // old settings. Re-get the correct reference.
+ pAttach = findAttachment(mMediaData->mAttachments,
+ ctrlName.raw(),
+ lPort,
+ lDevice);
+
+ {
+ AutoCaller autoAttachCaller(this);
+ if (FAILED(autoAttachCaller.rc())) return autoAttachCaller.rc();
+
+ AutoWriteLock attLock(pAttach COMMA_LOCKVAL_SRC_POS);
+ if (!oldmedium.isNull())
+ oldmedium->removeBackReference(mData->mUuid);
+
+ pAttach->updateMedium(NULL);
+ pAttach->updateEjected();
+ }
+
+ setModified(IsModified_Storage);
+ }
+ else
+ {
+ {
+ AutoWriteLock attLock(pAttach COMMA_LOCKVAL_SRC_POS);
+ pAttach->updateEjected();
+ }
+ }
+
+ pAttach.queryInterfaceTo(aNewAttachment);
+
+ return S_OK;
+}
+
// public methods only for internal purposes
/////////////////////////////////////////////////////////////////////////////
@@ -11648,6 +12242,29 @@ HRESULT SessionMachine::onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup)
}
/**
+ * @note Locks this object for reading.
+ */
+HRESULT SessionMachine::onStorageDeviceChange(IMediumAttachment *aAttachment, BOOL aRemove)
+{
+ LogFlowThisFunc(("\n"));
+
+ AutoCaller autoCaller(this);
+ AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
+
+ ComPtr<IInternalSessionControl> directControl;
+ {
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ directControl = mData->mSession.mDirectControl;
+ }
+
+ /* ignore notifications sent after #OnSessionEnd() is called */
+ if (!directControl)
+ return S_OK;
+
+ return directControl->OnStorageDeviceChange(aAttachment, aRemove);
+}
+
+/**
* Returns @c true if this machine's USB controller reports it has a matching
* filter for the given USB device and @c false otherwise.
*
@@ -11773,7 +12390,7 @@ HRESULT SessionMachine::endSavingState(HRESULT aRc, const Utf8Str &aErrMsg)
if (SUCCEEDED(aRc))
{
- mSSData->mStateFilePath = mConsoleTaskData.mStateFilePath;
+ mSSData->strStateFilePath = mConsoleTaskData.strStateFilePath;
/* save all VM settings */
rc = saveSettings(NULL);
@@ -11782,8 +12399,10 @@ HRESULT SessionMachine::endSavingState(HRESULT aRc, const Utf8Str &aErrMsg)
}
else
{
- /* delete the saved state file (it might have been already created) */
- RTFileDelete(mConsoleTaskData.mStateFilePath.c_str());
+ // delete the saved state file (it might have been already created);
+ // we need not check whether this is shared with a snapshot here because
+ // we certainly created this saved state file here anew
+ RTFileDelete(mConsoleTaskData.strStateFilePath.c_str());
}
/* notify the progress object about operation completion */
@@ -11803,7 +12422,7 @@ HRESULT SessionMachine::endSavingState(HRESULT aRc, const Utf8Str &aErrMsg)
/* clear out the temporary saved state data */
mConsoleTaskData.mLastState = MachineState_Null;
- mConsoleTaskData.mStateFilePath.setNull();
+ mConsoleTaskData.strStateFilePath.setNull();
mConsoleTaskData.mProgress.setNull();
LogFlowThisFuncLeave();
@@ -11811,6 +12430,33 @@ HRESULT SessionMachine::endSavingState(HRESULT aRc, const Utf8Str &aErrMsg)
}
/**
+ * Deletes the given file if it is no longer in use by either the current machine state
+ * (if the machine is "saved") or any of the machine's snapshots.
+ *
+ * Note: This checks mSSData->strStateFilePath, which is shared by the Machine and SessionMachine
+ * but is different for each SnapshotMachine. When calling this, the order of calling this
+ * function on the one hand and changing that variable OR the snapshots tree on the other hand
+ * is therefore critical. I know, it's all rather messy.
+ *
+ * @param strStateFile
+ * @param pSnapshotToIgnore Passed to Snapshot::sharesSavedStateFile(); this snapshot is ignored in the test for whether the saved state file is in use.
+ */
+void SessionMachine::releaseSavedStateFile(const Utf8Str &strStateFile,
+ Snapshot *pSnapshotToIgnore)
+{
+ // it is safe to delete this saved state file if it is not currently in use by the machine ...
+ if ( (strStateFile.isNotEmpty())
+ && (strStateFile != mSSData->strStateFilePath) // session machine's saved state
+ )
+ // ... and it must also not be shared with other snapshots
+ if ( !mData->mFirstSnapshot
+ || !mData->mFirstSnapshot->sharesSavedStateFile(strStateFile, pSnapshotToIgnore)
+ // this checks the SnapshotMachine's state file paths
+ )
+ RTFileDelete(strStateFile.c_str());
+}
+
+/**
* Locks the attached media.
*
* All attached hard disks are locked for writing and DVD/floppy are locked for
@@ -12062,10 +12708,17 @@ HRESULT SessionMachine::setMachineState(MachineState_T aMachineState)
{
if (mRemoveSavedState)
{
- Assert(!mSSData->mStateFilePath.isEmpty());
- RTFileDelete(mSSData->mStateFilePath.c_str());
+ Assert(!mSSData->strStateFilePath.isEmpty());
+
+ // it is safe to delete the saved state file if ...
+ if ( !mData->mFirstSnapshot // ... we have no snapshots or
+ || !mData->mFirstSnapshot->sharesSavedStateFile(mSSData->strStateFilePath, NULL /* pSnapshotToIgnore */)
+ // ... none of the snapshots share the saved state file
+ )
+ RTFileDelete(mSSData->strStateFilePath.c_str());
}
- mSSData->mStateFilePath.setNull();
+
+ mSSData->strStateFilePath.setNull();
stsFlags |= SaveSTS_StateFilePath;
}
@@ -12089,7 +12742,7 @@ HRESULT SessionMachine::setMachineState(MachineState_T aMachineState)
&& aMachineState == MachineState_Saved)
{
/* the saved state file was adopted */
- Assert(!mSSData->mStateFilePath.isEmpty());
+ Assert(!mSSData->strStateFilePath.isEmpty());
stsFlags |= SaveSTS_StateFilePath;
}
diff --git a/src/VBox/Main/src-server/MachineImplCloneVM.cpp b/src/VBox/Main/src-server/MachineImplCloneVM.cpp
new file mode 100644
index 000000000..6fe15036f
--- /dev/null
+++ b/src/VBox/Main/src-server/MachineImplCloneVM.cpp
@@ -0,0 +1,1090 @@
+/* $Id: MachineImplCloneVM.cpp 38061 2011-07-19 09:50:33Z vboxsync $ */
+/** @file
+ * Implementation of MachineCloneVM
+ */
+
+/*
+ * 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.
+ */
+
+#include "MachineImplCloneVM.h"
+
+#include "VirtualBoxImpl.h"
+#include "MediumImpl.h"
+#include "HostImpl.h"
+
+#include <iprt/path.h>
+#include <iprt/dir.h>
+#include <iprt/cpp/utils.h>
+
+#include <VBox/com/list.h>
+#include <VBox/com/MultiResult.h>
+
+// typedefs
+/////////////////////////////////////////////////////////////////////////////
+
+typedef struct
+{
+ Utf8Str strBaseName;
+ ComPtr<IMedium> pMedium;
+ ULONG uWeight;
+} MEDIUMTASK;
+
+typedef struct
+{
+ RTCList<MEDIUMTASK> chain;
+ bool fCreateDiffs;
+ bool fAttachLinked;
+} MEDIUMTASKCHAIN;
+
+typedef struct
+{
+ Guid snapshotUuid;
+ Utf8Str strSaveStateFile;
+ ULONG uWeight;
+} SAVESTATETASK;
+
+// The private class
+/////////////////////////////////////////////////////////////////////////////
+
+struct MachineCloneVMPrivate
+{
+ MachineCloneVMPrivate(MachineCloneVM *a_q, ComObjPtr<Machine> &a_pSrcMachine, ComObjPtr<Machine> &a_pTrgMachine, CloneMode_T a_mode, const RTCList<CloneOptions_T> &opts)
+ : q_ptr(a_q)
+ , p(a_pSrcMachine)
+ , pSrcMachine(a_pSrcMachine)
+ , pTrgMachine(a_pTrgMachine)
+ , mode(a_mode)
+ , options(opts)
+ {}
+
+ /* Thread management */
+ int startWorker()
+ {
+ return RTThreadCreate(NULL,
+ MachineCloneVMPrivate::workerThread,
+ static_cast<void*>(this),
+ 0,
+ RTTHREADTYPE_MAIN_WORKER,
+ 0,
+ "MachineClone");
+ }
+
+ static int workerThread(RTTHREAD /* Thread */, void *pvUser)
+ {
+ MachineCloneVMPrivate *pTask = static_cast<MachineCloneVMPrivate*>(pvUser);
+ AssertReturn(pTask, VERR_INVALID_POINTER);
+
+ HRESULT rc = pTask->q_ptr->run();
+
+ pTask->pProgress->notifyComplete(rc);
+
+ pTask->q_ptr->destroy();
+
+ return VINF_SUCCESS;
+ }
+
+ /* Private helper methods */
+ HRESULT createMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const;
+ settings::Snapshot findSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const;
+ void updateMACAddresses(settings::NetworkAdaptersList &nwl) const;
+ void updateMACAddresses(settings::SnapshotsList &sl) const;
+ void updateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const;
+ void updateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const;
+ void updateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const;
+ static int copyStateFileProgress(unsigned uPercentage, void *pvUser);
+
+ /* Private q and parent pointer */
+ MachineCloneVM *q_ptr;
+ ComObjPtr<Machine> p;
+
+ /* Private helper members */
+ ComObjPtr<Machine> pSrcMachine;
+ ComObjPtr<Machine> pTrgMachine;
+ ComPtr<IMachine> pOldMachineState;
+ ComObjPtr<Progress> pProgress;
+ Guid snapshotId;
+ CloneMode_T mode;
+ RTCList<CloneOptions_T> options;
+ RTCList<MEDIUMTASKCHAIN> llMedias;
+ RTCList<SAVESTATETASK> llSaveStateFiles; /* Snapshot UUID -> File path */
+};
+
+HRESULT MachineCloneVMPrivate::createMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const
+{
+ HRESULT rc = S_OK;
+ Bstr name;
+ rc = pSnapshot->COMGETTER(Name)(name.asOutParam());
+ if (FAILED(rc)) return rc;
+
+ ComPtr<IMachine> pMachine;
+ rc = pSnapshot->COMGETTER(Machine)(pMachine.asOutParam());
+ if (FAILED(rc)) return rc;
+ machineList.append((Machine*)(IMachine*)pMachine);
+
+ SafeIfaceArray<ISnapshot> sfaChilds;
+ rc = pSnapshot->COMGETTER(Children)(ComSafeArrayAsOutParam(sfaChilds));
+ if (FAILED(rc)) return rc;
+ for (size_t i = 0; i < sfaChilds.size(); ++i)
+ {
+ rc = createMachineList(sfaChilds[i], machineList);
+ if (FAILED(rc)) return rc;
+ }
+
+ return rc;
+}
+
+settings::Snapshot MachineCloneVMPrivate::findSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const
+{
+ settings::SnapshotsList::const_iterator it;
+ for (it = snl.begin(); it != snl.end(); ++it)
+ {
+ if (it->uuid == id)
+ return *it;
+ else if (!it->llChildSnapshots.empty())
+ return findSnapshot(pMCF, it->llChildSnapshots, id);
+ }
+ return settings::Snapshot();
+}
+
+void MachineCloneVMPrivate::updateMACAddresses(settings::NetworkAdaptersList &nwl) const
+{
+ const bool fNotNAT = options.contains(CloneOptions_KeepNATMACs);
+ settings::NetworkAdaptersList::iterator it;
+ for (it = nwl.begin(); it != nwl.end(); ++it)
+ {
+ if ( fNotNAT
+ && it->mode == NetworkAttachmentType_NAT)
+ continue;
+ Host::generateMACAddress(it->strMACAddress);
+ }
+}
+
+void MachineCloneVMPrivate::updateMACAddresses(settings::SnapshotsList &sl) const
+{
+ settings::SnapshotsList::iterator it;
+ for (it = sl.begin(); it != sl.end(); ++it)
+ {
+ updateMACAddresses(it->hardware.llNetworkAdapters);
+ if (!it->llChildSnapshots.empty())
+ updateMACAddresses(it->llChildSnapshots);
+ }
+}
+
+void MachineCloneVMPrivate::updateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const
+{
+ settings::StorageControllersList::iterator it3;
+ for (it3 = sc.begin();
+ it3 != sc.end();
+ ++it3)
+ {
+ settings::AttachedDevicesList &llAttachments = it3->llAttachedDevices;
+ settings::AttachedDevicesList::iterator it4;
+ for (it4 = llAttachments.begin();
+ it4 != llAttachments.end();
+ ++it4)
+ {
+ if ( it4->deviceType == DeviceType_HardDisk
+ && it4->uuid == bstrOldId)
+ {
+ it4->uuid = bstrNewId;
+ }
+ }
+ }
+}
+
+void MachineCloneVMPrivate::updateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const
+{
+ settings::SnapshotsList::iterator it;
+ for ( it = sl.begin();
+ it != sl.end();
+ ++it)
+ {
+ updateStorageLists(it->storage.llStorageControllers, bstrOldId, bstrNewId);
+ if (!it->llChildSnapshots.empty())
+ updateSnapshotStorageLists(it->llChildSnapshots, bstrOldId, bstrNewId);
+ }
+}
+
+void MachineCloneVMPrivate::updateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const
+{
+ settings::SnapshotsList::iterator it;
+ for (it = snl.begin(); it != snl.end(); ++it)
+ {
+ if (it->uuid == id)
+ it->strStateFile = strFile;
+ else if (!it->llChildSnapshots.empty())
+ updateStateFile(it->llChildSnapshots, id, strFile);
+ }
+}
+
+/* static */
+int MachineCloneVMPrivate::copyStateFileProgress(unsigned uPercentage, void *pvUser)
+{
+ ComObjPtr<Progress> pProgress = *static_cast< ComObjPtr<Progress>* >(pvUser);
+
+ BOOL fCanceled = false;
+ HRESULT rc = pProgress->COMGETTER(Canceled)(&fCanceled);
+ if (FAILED(rc)) return VERR_GENERAL_FAILURE;
+ /* If canceled by the user tell it to the copy operation. */
+ if (fCanceled) return VERR_CANCELLED;
+ /* Set the new process. */
+ rc = pProgress->SetCurrentOperationProgress(uPercentage);
+ if (FAILED(rc)) return VERR_GENERAL_FAILURE;
+
+ return VINF_SUCCESS;
+}
+
+// The public class
+/////////////////////////////////////////////////////////////////////////////
+
+MachineCloneVM::MachineCloneVM(ComObjPtr<Machine> pSrcMachine, ComObjPtr<Machine> pTrgMachine, CloneMode_T mode, const RTCList<CloneOptions_T> &opts)
+ : d_ptr(new MachineCloneVMPrivate(this, pSrcMachine, pTrgMachine, mode, opts))
+{
+}
+
+MachineCloneVM::~MachineCloneVM()
+{
+ delete d_ptr;
+}
+
+HRESULT MachineCloneVM::start(IProgress **pProgress)
+{
+ DPTR(MachineCloneVM);
+ ComObjPtr<Machine> &p = d->p;
+
+ HRESULT rc;
+ try
+ {
+ /** @todo r=klaus this code cannot deal with someone crazy specifying
+ * IMachine corresponding to a mutable machine as d->pSrcMachine */
+ if (d->pSrcMachine->isSessionMachine())
+ throw E_FAIL;
+
+ /* Handle the special case that someone is requesting a _full_ clone
+ * with all snapshots (and the current state), but uses a snapshot
+ * machine (and not the current one) as source machine. In this case we
+ * just replace the source (snapshot) machine with the current machine. */
+ if ( d->mode == CloneMode_AllStates
+ && d->pSrcMachine->isSnapshotMachine())
+ {
+ Bstr bstrSrcMachineId;
+ rc = d->pSrcMachine->COMGETTER(Id)(bstrSrcMachineId.asOutParam());
+ if (FAILED(rc)) throw rc;
+ ComPtr<IMachine> newSrcMachine;
+ rc = d->pSrcMachine->getVirtualBox()->FindMachine(bstrSrcMachineId.raw(), newSrcMachine.asOutParam());
+ if (FAILED(rc)) throw rc;
+ d->pSrcMachine = (Machine*)(IMachine*)newSrcMachine;
+ }
+
+ bool fSubtreeIncludesCurrent = false;
+ ComObjPtr<Machine> pCurrState;
+ if (d->mode == CloneMode_MachineAndChildStates)
+ {
+ if (d->pSrcMachine->isSnapshotMachine())
+ {
+ /* find machine object for current snapshot of current state */
+ Bstr bstrSrcMachineId;
+ rc = d->pSrcMachine->COMGETTER(Id)(bstrSrcMachineId.asOutParam());
+ if (FAILED(rc)) throw rc;
+ ComPtr<IMachine> pCurr;
+ rc = d->pSrcMachine->getVirtualBox()->FindMachine(bstrSrcMachineId.raw(), pCurr.asOutParam());
+ if (FAILED(rc)) throw rc;
+ if (pCurr.isNull())
+ throw E_FAIL;
+ pCurrState = (Machine *)(IMachine *)pCurr;
+ ComPtr<ISnapshot> pSnapshot;
+ rc = pCurrState->COMGETTER(CurrentSnapshot)(pSnapshot.asOutParam());
+ if (FAILED(rc)) throw rc;
+ if (pSnapshot.isNull())
+ throw E_FAIL;
+ ComPtr<IMachine> pCurrSnapMachine;
+ rc = pSnapshot->COMGETTER(Machine)(pCurrSnapMachine.asOutParam());
+ if (FAILED(rc)) throw rc;
+ if (pCurrSnapMachine.isNull())
+ throw E_FAIL;
+
+ /* now check if there is a parent chain which leads to the
+ * snapshot machine defining the subtree. */
+ while (!pSnapshot.isNull())
+ {
+ ComPtr<IMachine> pSnapMachine;
+ rc = pSnapshot->COMGETTER(Machine)(pSnapMachine.asOutParam());
+ if (FAILED(rc)) throw rc;
+ if (pSnapMachine.isNull())
+ throw E_FAIL;
+ if (pSnapMachine == d->pSrcMachine)
+ {
+ fSubtreeIncludesCurrent = true;
+ break;
+ }
+ rc = pSnapshot->COMGETTER(Parent)(pSnapshot.asOutParam());
+ }
+ }
+ else
+ {
+ /* If the subtree is only the Current State simply use the
+ * 'machine' case for cloning. It is easier to understand. */
+ d->mode = CloneMode_MachineState;
+ }
+ }
+
+ /* Lock the target machine early (so nobody mess around with it in the meantime). */
+ AutoWriteLock trgLock(d->pTrgMachine COMMA_LOCKVAL_SRC_POS);
+
+ if (d->pSrcMachine->isSnapshotMachine())
+ d->snapshotId = d->pSrcMachine->getSnapshotId();
+
+ /* Add the current machine and all snapshot machines below this machine
+ * in a list for further processing. */
+ RTCList< ComObjPtr<Machine> > machineList;
+
+ /* Include current state? */
+ if ( d->mode == CloneMode_MachineState
+ || d->mode == CloneMode_AllStates)
+ machineList.append(d->pSrcMachine);
+ /* Should be done a depth copy with all child snapshots? */
+ if ( d->mode == CloneMode_MachineAndChildStates
+ || d->mode == CloneMode_AllStates)
+ {
+ ULONG cSnapshots = 0;
+ rc = d->pSrcMachine->COMGETTER(SnapshotCount)(&cSnapshots);
+ if (FAILED(rc)) throw rc;
+ if (cSnapshots > 0)
+ {
+ Utf8Str id;
+ if (d->mode == CloneMode_MachineAndChildStates)
+ id = d->snapshotId.toString();
+ ComPtr<ISnapshot> pSnapshot;
+ rc = d->pSrcMachine->FindSnapshot(Bstr(id).raw(), pSnapshot.asOutParam());
+ if (FAILED(rc)) throw rc;
+ rc = d->createMachineList(pSnapshot, machineList);
+ if (FAILED(rc)) throw rc;
+ if (d->mode == CloneMode_MachineAndChildStates)
+ {
+ if (fSubtreeIncludesCurrent)
+ {
+ /* zap d->snapshotId because there is no need to
+ * create a new current state. */
+ d->snapshotId.clear();
+ if (pCurrState.isNull())
+ throw E_FAIL;
+ machineList.append(pCurrState);
+ }
+ else
+ {
+ rc = pSnapshot->COMGETTER(Machine)(d->pOldMachineState.asOutParam());
+ if (FAILED(rc)) throw rc;
+ }
+ }
+ }
+ }
+
+ /* Go over every machine and walk over every attachment this machine has. */
+ ULONG uCount = 2; /* One init task and the machine creation. */
+ ULONG uTotalWeight = 2; /* The init task and the machine creation is worth one. */
+ for (size_t i = 0; i < machineList.size(); ++i)
+ {
+ ComObjPtr<Machine> machine = machineList.at(i);
+ /* If this is the Snapshot Machine we want to clone, we need to
+ * create a new diff file for the new "current state". */
+ bool fCreateDiffs = false;
+ if (machine == d->pOldMachineState)
+ fCreateDiffs = true;
+ /* If we want to create a linked clone just attach the medium
+ * associated with the snapshot. The rest is taken care of by
+ * attach already, so no need to duplicate this. */
+ bool fAttachLinked = false;
+ if (d->options.contains(CloneOptions_Link))
+ fAttachLinked = true;
+ SafeIfaceArray<IMediumAttachment> sfaAttachments;
+ rc = machine->COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(sfaAttachments));
+ if (FAILED(rc)) throw rc;
+ /* Add all attachments (and their parents) of the different
+ * machines to a worker list. */
+ for (size_t a = 0; a < sfaAttachments.size(); ++a)
+ {
+ const ComPtr<IMediumAttachment> &pAtt = sfaAttachments[a];
+ DeviceType_T type;
+ rc = pAtt->COMGETTER(Type)(&type);
+ if (FAILED(rc)) throw rc;
+
+ /* Only harddisk's are of interest. */
+ if (type != DeviceType_HardDisk)
+ continue;
+
+ /* Valid medium attached? */
+ ComPtr<IMedium> pSrcMedium;
+ rc = pAtt->COMGETTER(Medium)(pSrcMedium.asOutParam());
+ if (FAILED(rc)) throw rc;
+ if (pSrcMedium.isNull())
+ continue;
+
+ /* Build up a child->parent list of this attachment. (Note: we are
+ * not interested of any child's not attached to this VM. So this
+ * will not create a full copy of the base/child relationship.) */
+ MEDIUMTASKCHAIN mtc;
+ mtc.fCreateDiffs = fCreateDiffs;
+ mtc.fAttachLinked = fAttachLinked;
+
+ /* If the current state without any snapshots is cloned, we
+ * don't need any diff images in the new clone. Add the last
+ * medium to the list of medias to create only (the clone
+ * operation of IMedium will create a merged copy
+ * automatically). */
+ if (d->mode == CloneMode_MachineState)
+ {
+ /* Refresh the state so that the file size get read. */
+ MediumState_T e;
+ rc = pSrcMedium->RefreshState(&e);
+ if (FAILED(rc)) throw rc;
+ LONG64 lSize;
+ rc = pSrcMedium->COMGETTER(Size)(&lSize);
+ if (FAILED(rc)) throw rc;
+
+ ComPtr<IMedium> pBaseMedium;
+ rc = pSrcMedium->COMGETTER(Base)(pBaseMedium.asOutParam());
+ if (FAILED(rc)) throw rc;
+
+ MEDIUMTASK mt;
+
+ Bstr bstrBaseName;
+ rc = pBaseMedium->COMGETTER(Name)(bstrBaseName.asOutParam());
+ if (FAILED(rc)) throw rc;
+
+ /* Save the base name. */
+ mt.strBaseName = bstrBaseName;
+
+ /* Save the current medium, for later cloning. */
+ mt.pMedium = pSrcMedium;
+ if (fAttachLinked)
+ mt.uWeight = 0; /* dummy */
+ else
+ mt.uWeight = (lSize + _1M - 1) / _1M;
+ mtc.chain.append(mt);
+ }
+ else
+ {
+ /** @todo r=klaus this puts way too many images in the list
+ * when cloning a snapshot (sub)tree, which means that more
+ * images are cloned than necessary. It is just the easiest
+ * way to get a working VM, as getting the image
+ * parent/child relationships right for only the bare
+ * minimum cloning is rather tricky. */
+ while (!pSrcMedium.isNull())
+ {
+ /* Refresh the state so that the file size get read. */
+ MediumState_T e;
+ rc = pSrcMedium->RefreshState(&e);
+ if (FAILED(rc)) throw rc;
+ LONG64 lSize;
+ rc = pSrcMedium->COMGETTER(Size)(&lSize);
+ if (FAILED(rc)) throw rc;
+
+ /* Save the current medium, for later cloning. */
+ MEDIUMTASK mt;
+ mt.pMedium = pSrcMedium;
+ mt.uWeight = (lSize + _1M - 1) / _1M;
+ mtc.chain.append(mt);
+
+ /* Query next parent. */
+ rc = pSrcMedium->COMGETTER(Parent)(pSrcMedium.asOutParam());
+ if (FAILED(rc)) throw rc;
+ }
+ }
+
+ if (fAttachLinked)
+ {
+ /* Implicit diff creation as part of attach is a pretty cheap
+ * operation, and does only need one operation per attachment. */
+ ++uCount;
+ uTotalWeight += 1; /* 1MB per attachment */
+ }
+ else
+ {
+ /* Currently the copying of diff images involves reading at least
+ * the biggest parent in the previous chain. So even if the new
+ * diff image is small in size, it could need some time to create
+ * it. Adding the biggest size in the chain should balance this a
+ * little bit more, i.e. the weight is the sum of the data which
+ * needs to be read and written. */
+ uint64_t uMaxSize = 0;
+ for (size_t e = mtc.chain.size(); e > 0; --e)
+ {
+ MEDIUMTASK &mt = mtc.chain.at(e - 1);
+ mt.uWeight += uMaxSize;
+
+ /* Calculate progress data */
+ ++uCount;
+ uTotalWeight += mt.uWeight;
+
+ /* Save the max size for better weighting of diff image
+ * creation. */
+ uMaxSize = RT_MAX(uMaxSize, mt.uWeight);
+ }
+ }
+ d->llMedias.append(mtc);
+ }
+ Bstr bstrSrcSaveStatePath;
+ rc = machine->COMGETTER(StateFilePath)(bstrSrcSaveStatePath.asOutParam());
+ if (FAILED(rc)) throw rc;
+ if (!bstrSrcSaveStatePath.isEmpty())
+ {
+ SAVESTATETASK sst;
+ sst.snapshotUuid = machine->getSnapshotId();
+ sst.strSaveStateFile = bstrSrcSaveStatePath;
+ uint64_t cbSize;
+ int vrc = RTFileQuerySize(sst.strSaveStateFile.c_str(), &cbSize);
+ if (RT_FAILURE(vrc))
+ throw p->setError(VBOX_E_IPRT_ERROR, p->tr("Could not query file size of '%s' (%Rrc)"), sst.strSaveStateFile.c_str(), vrc);
+ /* same rule as above: count both the data which needs to
+ * be read and written */
+ sst.uWeight = 2 * (cbSize + _1M - 1) / _1M;
+ d->llSaveStateFiles.append(sst);
+ ++uCount;
+ uTotalWeight += sst.uWeight;
+ }
+ }
+
+ rc = d->pProgress.createObject();
+ if (FAILED(rc)) throw rc;
+ rc = d->pProgress->init(p->getVirtualBox(),
+ static_cast<IMachine*>(d->pSrcMachine) /* aInitiator */,
+ Bstr(p->tr("Cloning Machine")).raw(),
+ true /* fCancellable */,
+ uCount,
+ uTotalWeight,
+ Bstr(p->tr("Initialize Cloning")).raw(),
+ 1);
+ if (FAILED(rc)) throw rc;
+
+ int vrc = d->startWorker();
+
+ if (RT_FAILURE(vrc))
+ p->setError(VBOX_E_IPRT_ERROR, "Could not create machine clone thread (%Rrc)", vrc);
+ }
+ catch (HRESULT rc2)
+ {
+ rc = rc2;
+ }
+
+ if (SUCCEEDED(rc))
+ d->pProgress.queryInterfaceTo(pProgress);
+
+ return rc;
+}
+
+HRESULT MachineCloneVM::run()
+{
+ DPTR(MachineCloneVM);
+ ComObjPtr<Machine> &p = d->p;
+
+ AutoCaller autoCaller(p);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock srcLock(p COMMA_LOCKVAL_SRC_POS);
+ AutoWriteLock trgLock(d->pTrgMachine COMMA_LOCKVAL_SRC_POS);
+
+ HRESULT rc = S_OK;
+
+ /*
+ * Todo:
+ * - What about log files?
+ */
+
+ /* Where should all the media go? */
+ Utf8Str strTrgSnapshotFolder;
+ Utf8Str strTrgMachineFolder = d->pTrgMachine->getSettingsFileFull();
+ strTrgMachineFolder.stripFilename();
+
+ RTCList<ComObjPtr<Medium> > newMedia; /* All created images */
+ RTCList<Utf8Str> newFiles; /* All extra created files (save states, ...) */
+ try
+ {
+ /* Copy all the configuration from this machine to an empty
+ * configuration dataset. */
+ settings::MachineConfigFile trgMCF = *d->pSrcMachine->mData->pMachineConfigFile;
+
+ /* Reset media registry. */
+ trgMCF.mediaRegistry.llHardDisks.clear();
+ /* If we got a valid snapshot id, replace the hardware/storage section
+ * with the stuff from the snapshot. */
+ settings::Snapshot sn;
+ if (!d->snapshotId.isEmpty())
+ sn = d->findSnapshot(&trgMCF, trgMCF.llFirstSnapshot, d->snapshotId);
+
+ if (d->mode == CloneMode_MachineState)
+ {
+ if (!sn.uuid.isEmpty())
+ {
+ trgMCF.hardwareMachine = sn.hardware;
+ trgMCF.storageMachine = sn.storage;
+ }
+
+ /* Remove any hint on snapshots. */
+ trgMCF.llFirstSnapshot.clear();
+ trgMCF.uuidCurrentSnapshot.clear();
+ }
+ else if ( d->mode == CloneMode_MachineAndChildStates
+ && !sn.uuid.isEmpty())
+ {
+ /* Copy the snapshot data to the current machine. */
+ trgMCF.hardwareMachine = sn.hardware;
+ trgMCF.storageMachine = sn.storage;
+
+ /* The snapshot will be the root one. */
+ trgMCF.uuidCurrentSnapshot = sn.uuid;
+ trgMCF.llFirstSnapshot.clear();
+ trgMCF.llFirstSnapshot.push_back(sn);
+ }
+
+ /* Generate new MAC addresses for all machines when not forbidden. */
+ if (!d->options.contains(CloneOptions_KeepAllMACs))
+ {
+ d->updateMACAddresses(trgMCF.hardwareMachine.llNetworkAdapters);
+ d->updateMACAddresses(trgMCF.llFirstSnapshot);
+ }
+
+ /* When the current snapshot folder is absolute we reset it to the
+ * default relative folder. */
+ if (RTPathStartsWithRoot(trgMCF.machineUserData.strSnapshotFolder.c_str()))
+ trgMCF.machineUserData.strSnapshotFolder = "Snapshots";
+ trgMCF.strStateFile = "";
+ /* Force writing of setting file. */
+ trgMCF.fCurrentStateModified = true;
+ /* Set the new name. */
+ const Utf8Str strOldVMName = trgMCF.machineUserData.strName;
+ trgMCF.machineUserData.strName = d->pTrgMachine->mUserData->s.strName;
+ trgMCF.uuid = d->pTrgMachine->mData->mUuid;
+
+ Bstr bstrSrcSnapshotFolder;
+ rc = d->pSrcMachine->COMGETTER(SnapshotFolder)(bstrSrcSnapshotFolder.asOutParam());
+ if (FAILED(rc)) throw rc;
+ /* The absolute name of the snapshot folder. */
+ strTrgSnapshotFolder = Utf8StrFmt("%s%c%s", strTrgMachineFolder.c_str(), RTPATH_DELIMITER, trgMCF.machineUserData.strSnapshotFolder.c_str());
+
+ /* Should we rename the disk names. */
+ bool fKeepDiskNames = d->options.contains(CloneOptions_KeepDiskNames);
+
+ /* We need to create a map with the already created medias. This is
+ * necessary, cause different snapshots could have the same
+ * parents/parent chain. If a medium is in this map already, it isn't
+ * cloned a second time, but simply used. */
+ typedef std::map<Utf8Str, ComObjPtr<Medium> > TStrMediumMap;
+ typedef std::pair<Utf8Str, ComObjPtr<Medium> > TStrMediumPair;
+ TStrMediumMap map;
+ GuidList llRegistriesThatNeedSaving;
+ size_t cDisks = 0;
+ for (size_t i = 0; i < d->llMedias.size(); ++i)
+ {
+ const MEDIUMTASKCHAIN &mtc = d->llMedias.at(i);
+ ComObjPtr<Medium> pNewParent;
+ for (size_t a = mtc.chain.size(); a > 0; --a)
+ {
+ const MEDIUMTASK &mt = mtc.chain.at(a - 1);
+ ComPtr<IMedium> pMedium = mt.pMedium;
+
+ Bstr bstrSrcName;
+ rc = pMedium->COMGETTER(Name)(bstrSrcName.asOutParam());
+ if (FAILED(rc)) throw rc;
+
+ rc = d->pProgress->SetNextOperation(BstrFmt(p->tr("Cloning Disk '%ls' ..."), bstrSrcName.raw()).raw(), mt.uWeight);
+ if (FAILED(rc)) throw rc;
+
+ Bstr bstrSrcId;
+ rc = pMedium->COMGETTER(Id)(bstrSrcId.asOutParam());
+ if (FAILED(rc)) throw rc;
+
+ if (mtc.fAttachLinked)
+ {
+ IMedium *pTmp = pMedium;
+ ComObjPtr<Medium> pLMedium = static_cast<Medium*>(pTmp);
+ if (pLMedium.isNull())
+ throw E_POINTER;
+ ComObjPtr<Medium> pBase = pLMedium->getBase();
+ if (pBase->isReadOnly())
+ {
+ ComObjPtr<Medium> pDiff;
+ /* create the diff under the snapshot medium */
+ rc = createDiffHelper(pLMedium, strTrgSnapshotFolder,
+ &newMedia, &pDiff);
+ if (FAILED(rc)) throw rc;
+ map.insert(TStrMediumPair(Utf8Str(bstrSrcId), pDiff));
+ /* diff image has to be used... */
+ pNewParent = pDiff;
+ }
+ else
+ {
+ /* Attach the medium directly, as its type is not
+ * subject to diff creation. */
+ newMedia.append(pLMedium);
+ map.insert(TStrMediumPair(Utf8Str(bstrSrcId), pLMedium));
+ pNewParent = pLMedium;
+ }
+ }
+ else
+ {
+ /* Is a clone already there? */
+ TStrMediumMap::iterator it = map.find(Utf8Str(bstrSrcId));
+ if (it != map.end())
+ pNewParent = it->second;
+ else
+ {
+ ComPtr<IMediumFormat> pSrcFormat;
+ rc = pMedium->COMGETTER(MediumFormat)(pSrcFormat.asOutParam());
+ ULONG uSrcCaps = 0;
+ rc = pSrcFormat->COMGETTER(Capabilities)(&uSrcCaps);
+ if (FAILED(rc)) throw rc;
+
+ /* Default format? */
+ Utf8Str strDefaultFormat;
+ p->mParent->getDefaultHardDiskFormat(strDefaultFormat);
+ Bstr bstrSrcFormat(strDefaultFormat);
+ ULONG srcVar = MediumVariant_Standard;
+ /* Is the source file based? */
+ if ((uSrcCaps & MediumFormatCapabilities_File) == MediumFormatCapabilities_File)
+ {
+ /* Yes, just use the source format. Otherwise the defaults
+ * will be used. */
+ rc = pMedium->COMGETTER(Format)(bstrSrcFormat.asOutParam());
+ if (FAILED(rc)) throw rc;
+ rc = pMedium->COMGETTER(Variant)(&srcVar);
+ if (FAILED(rc)) throw rc;
+ }
+
+ Guid newId;
+ newId.create();
+ Utf8Str strNewName(bstrSrcName);
+ if (!fKeepDiskNames)
+ {
+ Utf8Str strSrcTest = bstrSrcName;
+ /* Check if we have to use another name. */
+ if (!mt.strBaseName.isEmpty())
+ strSrcTest = mt.strBaseName;
+ strSrcTest.stripExt();
+ /* If the old disk name was in {uuid} format we also
+ * want the new name in this format, but with the
+ * updated id of course. If the old disk was called
+ * like the VM name, we change it to the new VM name.
+ * For all other disks we rename them with this
+ * template: "new name-disk1.vdi". */
+ if (strSrcTest == strOldVMName)
+ strNewName = Utf8StrFmt("%s%s", trgMCF.machineUserData.strName.c_str(), RTPathExt(Utf8Str(bstrSrcName).c_str()));
+ else if ( strSrcTest.startsWith("{")
+ && strSrcTest.endsWith("}"))
+ {
+ strSrcTest = strSrcTest.substr(1, strSrcTest.length() - 2);
+ if (isValidGuid(strSrcTest))
+ strNewName = Utf8StrFmt("%s%s", newId.toStringCurly().c_str(), RTPathExt(strNewName.c_str()));
+ }
+ else
+ strNewName = Utf8StrFmt("%s-disk%d%s", trgMCF.machineUserData.strName.c_str(), ++cDisks, RTPathExt(Utf8Str(bstrSrcName).c_str()));
+ }
+
+ /* Check if this medium comes from the snapshot folder, if
+ * so, put it there in the cloned machine as well.
+ * Otherwise it goes to the machine folder. */
+ Bstr bstrSrcPath;
+ Utf8Str strFile = Utf8StrFmt("%s%c%s", strTrgMachineFolder.c_str(), RTPATH_DELIMITER, strNewName.c_str());
+ rc = pMedium->COMGETTER(Location)(bstrSrcPath.asOutParam());
+ if (FAILED(rc)) throw rc;
+ if ( !bstrSrcPath.isEmpty()
+ && RTPathStartsWith(Utf8Str(bstrSrcPath).c_str(), Utf8Str(bstrSrcSnapshotFolder).c_str())
+ && (fKeepDiskNames || mt.strBaseName.isEmpty()))
+ strFile = Utf8StrFmt("%s%c%s", strTrgSnapshotFolder.c_str(), RTPATH_DELIMITER, strNewName.c_str());
+
+ /* Start creating the clone. */
+ ComObjPtr<Medium> pTarget;
+ rc = pTarget.createObject();
+ if (FAILED(rc)) throw rc;
+
+ rc = pTarget->init(p->mParent,
+ Utf8Str(bstrSrcFormat),
+ strFile,
+ Guid::Empty, /* empty media registry */
+ NULL /* llRegistriesThatNeedSaving */);
+ if (FAILED(rc)) throw rc;
+
+ /* Update the new uuid. */
+ pTarget->updateId(newId);
+
+ srcLock.release();
+ /* Do the disk cloning. */
+ ComPtr<IProgress> progress2;
+ rc = pMedium->CloneTo(pTarget,
+ srcVar,
+ pNewParent,
+ progress2.asOutParam());
+ if (FAILED(rc)) throw rc;
+
+ /* Wait until the async process has finished. */
+ rc = d->pProgress->WaitForAsyncProgressCompletion(progress2);
+ srcLock.acquire();
+ if (FAILED(rc)) throw rc;
+
+ /* Check the result of the async process. */
+ LONG iRc;
+ rc = progress2->COMGETTER(ResultCode)(&iRc);
+ if (FAILED(rc)) throw rc;
+ if (FAILED(iRc))
+ {
+ /* If the thread of the progress object has an error, then
+ * retrieve the error info from there, or it'll be lost. */
+ ProgressErrorInfo info(progress2);
+ throw p->setError(iRc, Utf8Str(info.getText()).c_str());
+ }
+ /* Remember created medium. */
+ newMedia.append(pTarget);
+ /* Get the medium type from the source and set it to the
+ * new medium. */
+ MediumType_T type;
+ rc = pMedium->COMGETTER(Type)(&type);
+ if (FAILED(rc)) throw rc;
+ rc = pTarget->COMSETTER(Type)(type);
+ if (FAILED(rc)) throw rc;
+ map.insert(TStrMediumPair(Utf8Str(bstrSrcId), pTarget));
+ /* register the new harddisk */
+ {
+ AutoWriteLock tlock(p->mParent->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
+ rc = p->mParent->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */);
+ if (FAILED(rc)) throw rc;
+ }
+ /* This medium becomes the parent of the next medium in the
+ * chain. */
+ pNewParent = pTarget;
+ }
+ }
+ }
+
+ Bstr bstrSrcId;
+ rc = mtc.chain.first().pMedium->COMGETTER(Id)(bstrSrcId.asOutParam());
+ if (FAILED(rc)) throw rc;
+ Bstr bstrTrgId;
+ rc = pNewParent->COMGETTER(Id)(bstrTrgId.asOutParam());
+ if (FAILED(rc)) throw rc;
+ /* update snapshot configuration */
+ d->updateSnapshotStorageLists(trgMCF.llFirstSnapshot, bstrSrcId, bstrTrgId);
+
+ /* create new 'Current State' diff for caller defined place */
+ if (mtc.fCreateDiffs)
+ {
+ const MEDIUMTASK &mt = mtc.chain.first();
+ ComObjPtr<Medium> pLMedium = static_cast<Medium*>((IMedium*)mt.pMedium);
+ if (pLMedium.isNull())
+ throw E_POINTER;
+ ComObjPtr<Medium> pBase = pLMedium->getBase();
+ if (pBase->isReadOnly())
+ {
+ ComObjPtr<Medium> pDiff;
+ rc = createDiffHelper(pNewParent, strTrgSnapshotFolder,
+ &newMedia, &pDiff);
+ if (FAILED(rc)) throw rc;
+ /* diff image has to be used... */
+ pNewParent = pDiff;
+ }
+ else
+ {
+ /* Attach the medium directly, as its type is not
+ * subject to diff creation. */
+ newMedia.append(pNewParent);
+ }
+
+ rc = pNewParent->COMGETTER(Id)(bstrTrgId.asOutParam());
+ if (FAILED(rc)) throw rc;
+ }
+ /* update 'Current State' configuration */
+ d->updateStorageLists(trgMCF.storageMachine.llStorageControllers, bstrSrcId, bstrTrgId);
+ }
+ /* Make sure all disks know of the new machine uuid. We do this last to
+ * be able to change the medium type above. */
+ for (size_t i = newMedia.size(); i > 0; --i)
+ {
+ const ComObjPtr<Medium> &pMedium = newMedia.at(i - 1);
+ AutoCaller mac(pMedium);
+ if (FAILED(mac.rc())) throw mac.rc();
+ AutoWriteLock mlock(pMedium COMMA_LOCKVAL_SRC_POS);
+ Guid uuid = d->pTrgMachine->mData->mUuid;
+ if (d->options.contains(CloneOptions_Link))
+ {
+ ComObjPtr<Medium> pParent = pMedium->getParent();
+ mlock.release();
+ if (!pParent.isNull())
+ {
+ AutoCaller mac2(pParent);
+ if (FAILED(mac2.rc())) throw mac2.rc();
+ AutoReadLock mlock2(pParent COMMA_LOCKVAL_SRC_POS);
+ if (pParent->getFirstRegistryMachineId(uuid))
+ VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, uuid);
+ }
+ mlock.acquire();
+ }
+ pMedium->addRegistry(uuid, false /* fRecurse */);
+ }
+ /* Check if a snapshot folder is necessary and if so doesn't already
+ * exists. */
+ if ( !d->llSaveStateFiles.isEmpty()
+ && !RTDirExists(strTrgSnapshotFolder.c_str()))
+ {
+ int vrc = RTDirCreateFullPath(strTrgSnapshotFolder.c_str(), 0777);
+ if (RT_FAILURE(vrc))
+ throw p->setError(VBOX_E_IPRT_ERROR,
+ p->tr("Could not create snapshots folder '%s' (%Rrc)"), strTrgSnapshotFolder.c_str(), vrc);
+ }
+ /* Clone all save state files. */
+ for (size_t i = 0; i < d->llSaveStateFiles.size(); ++i)
+ {
+ SAVESTATETASK sst = d->llSaveStateFiles.at(i);
+ const Utf8Str &strTrgSaveState = Utf8StrFmt("%s%c%s", strTrgSnapshotFolder.c_str(), RTPATH_DELIMITER, RTPathFilename(sst.strSaveStateFile.c_str()));
+
+ /* Move to next sub-operation. */
+ rc = d->pProgress->SetNextOperation(BstrFmt(p->tr("Copy save state file '%s' ..."), RTPathFilename(sst.strSaveStateFile.c_str())).raw(), sst.uWeight);
+ if (FAILED(rc)) throw rc;
+ /* Copy the file only if it was not copied already. */
+ if (!newFiles.contains(strTrgSaveState.c_str()))
+ {
+ int vrc = RTFileCopyEx(sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), 0, MachineCloneVMPrivate::copyStateFileProgress, &d->pProgress);
+ if (RT_FAILURE(vrc))
+ throw p->setError(VBOX_E_IPRT_ERROR,
+ p->tr("Could not copy state file '%s' to '%s' (%Rrc)"), sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), vrc);
+ newFiles.append(strTrgSaveState);
+ }
+ /* Update the path in the configuration either for the current
+ * machine state or the snapshots. */
+ if (sst.snapshotUuid.isEmpty())
+ trgMCF.strStateFile = strTrgSaveState;
+ else
+ d->updateStateFile(trgMCF.llFirstSnapshot, sst.snapshotUuid, strTrgSaveState);
+ }
+
+ {
+ rc = d->pProgress->SetNextOperation(BstrFmt(p->tr("Create Machine Clone '%s' ..."), trgMCF.machineUserData.strName.c_str()).raw(), 1);
+ if (FAILED(rc)) throw rc;
+ /* After modifying the new machine config, we can copy the stuff
+ * over to the new machine. The machine have to be mutable for
+ * this. */
+ rc = d->pTrgMachine->checkStateDependency(p->MutableStateDep);
+ if (FAILED(rc)) throw rc;
+ rc = d->pTrgMachine->loadMachineDataFromSettings(trgMCF,
+ &d->pTrgMachine->mData->mUuid);
+ if (FAILED(rc)) throw rc;
+ }
+
+ /* Now save the new configuration to disk. */
+ rc = d->pTrgMachine->SaveSettings();
+ if (FAILED(rc)) throw rc;
+ trgLock.release();
+ if (!llRegistriesThatNeedSaving.empty())
+ {
+ srcLock.release();
+ rc = p->mParent->saveRegistries(llRegistriesThatNeedSaving);
+ if (FAILED(rc)) throw rc;
+ }
+ }
+ catch (HRESULT rc2)
+ {
+ rc = rc2;
+ }
+ catch (...)
+ {
+ rc = VirtualBox::handleUnexpectedExceptions(RT_SRC_POS);
+ }
+
+ MultiResult mrc(rc);
+ /* Cleanup on failure (CANCEL also) */
+ if (FAILED(rc))
+ {
+ int vrc = VINF_SUCCESS;
+ /* Delete all created files. */
+ for (size_t i = 0; i < newFiles.size(); ++i)
+ {
+ vrc = RTFileDelete(newFiles.at(i).c_str());
+ if (RT_FAILURE(vrc))
+ mrc = p->setError(VBOX_E_IPRT_ERROR, p->tr("Could not delete file '%s' (%Rrc)"), newFiles.at(i).c_str(), vrc);
+ }
+ /* Delete all already created medias. (Reverse, cause there could be
+ * parent->child relations.) */
+ for (size_t i = newMedia.size(); i > 0; --i)
+ {
+ const ComObjPtr<Medium> &pMedium = newMedia.at(i - 1);
+ mrc = pMedium->deleteStorage(NULL /* aProgress */,
+ true /* aWait */,
+ NULL /* llRegistriesThatNeedSaving */);
+ pMedium->Close();
+ }
+ /* Delete the snapshot folder when not empty. */
+ if (!strTrgSnapshotFolder.isEmpty())
+ RTDirRemove(strTrgSnapshotFolder.c_str());
+ /* Delete the machine folder when not empty. */
+ RTDirRemove(strTrgMachineFolder.c_str());
+ }
+
+ return mrc;
+}
+
+HRESULT MachineCloneVM::createDiffHelper(const ComObjPtr<Medium> &pParent,
+ const Utf8Str &strSnapshotFolder,
+ RTCList< ComObjPtr<Medium> > *pNewMedia,
+ ComObjPtr<Medium> *ppDiff)
+{
+ DPTR(MachineCloneVM);
+ ComObjPtr<Machine> &p = d->p;
+ HRESULT rc = S_OK;
+
+ try
+ {
+ Bstr bstrSrcId;
+ rc = pParent->COMGETTER(Id)(bstrSrcId.asOutParam());
+ if (FAILED(rc)) throw rc;
+ ComObjPtr<Medium> diff;
+ diff.createObject();
+ rc = diff->init(p->mParent,
+ pParent->getPreferredDiffFormat(),
+ Utf8StrFmt("%s%c", strSnapshotFolder.c_str(), RTPATH_DELIMITER),
+ Guid::Empty, /* empty media registry */
+ NULL); /* pllRegistriesThatNeedSaving */
+ if (FAILED(rc)) throw rc;
+ MediumLockList *pMediumLockList(new MediumLockList());
+ rc = diff->createMediumLockList(true /* fFailIfInaccessible */,
+ true /* fMediumLockWrite */,
+ pParent,
+ *pMediumLockList);
+ if (FAILED(rc)) throw rc;
+ rc = pMediumLockList->Lock();
+ if (FAILED(rc)) throw rc;
+ /* this already registers the new diff image */
+ rc = pParent->createDiffStorage(diff, MediumVariant_Standard,
+ pMediumLockList,
+ NULL /* aProgress */,
+ true /* aWait */,
+ NULL); // pllRegistriesThatNeedSaving
+ delete pMediumLockList;
+ if (FAILED(rc)) throw rc;
+ /* Remember created medium. */
+ pNewMedia->append(diff);
+ *ppDiff = diff;
+ }
+ catch (HRESULT rc2)
+ {
+ rc = rc2;
+ }
+ catch (...)
+ {
+ rc = VirtualBox::handleUnexpectedExceptions(RT_SRC_POS);
+ }
+
+ return rc;
+}
+
+void MachineCloneVM::destroy()
+{
+ delete this;
+}
+
diff --git a/src/VBox/Main/src-server/Matching.cpp b/src/VBox/Main/src-server/Matching.cpp
index 0ccceef7b..83174f928 100644
--- a/src/VBox/Main/src-server/Matching.cpp
+++ b/src/VBox/Main/src-server/Matching.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -21,7 +21,6 @@
#include "Logging.h"
#include <stdlib.h>
-#include <errno.h>
#include <iprt/err.h>
diff --git a/src/VBox/Main/src-server/MediumAttachmentImpl.cpp b/src/VBox/Main/src-server/MediumAttachmentImpl.cpp
index f9b073963..8fb9ab84b 100644
--- a/src/VBox/Main/src-server/MediumAttachmentImpl.cpp
+++ b/src/VBox/Main/src-server/MediumAttachmentImpl.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2009 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;
@@ -39,6 +39,8 @@ struct BackupableMediumAttachmentData
lDevice(0),
type(DeviceType_Null),
fPassthrough(false),
+ fTempEject(false),
+ fNonRotational(false),
fImplicit(false)
{ }
@@ -55,19 +57,24 @@ struct BackupableMediumAttachmentData
const LONG lDevice;
const DeviceType_T type;
bool fPassthrough;
+ bool fTempEject;
+ bool fNonRotational;
bool fImplicit;
};
struct MediumAttachment::Data
{
Data()
- : pMachine(NULL)
+ : pMachine(NULL),
+ fIsEjected(false)
{ }
/** Reference to Machine object, for checking mutable state. */
Machine * const pMachine;
/* later: const ComObjPtr<MediumAttachment> mPeer; */
+ bool fIsEjected;
+
Backupable<BackupableMediumAttachmentData> bd;
};
@@ -77,13 +84,14 @@ struct MediumAttachment::Data
HRESULT MediumAttachment::FinalConstruct()
{
LogFlowThisFunc(("\n"));
- return S_OK;
+ return BaseFinalConstruct();
}
void MediumAttachment::FinalRelease()
{
LogFlowThisFuncEnter();
uninit();
+ BaseFinalRelease();
LogFlowThisFuncLeave();
}
@@ -107,11 +115,14 @@ HRESULT MediumAttachment::init(Machine *aParent,
LONG aPort,
LONG aDevice,
DeviceType_T aType,
+ bool aImplicit,
bool aPassthrough,
+ bool aTempEject,
+ bool aNonRotational,
const Utf8Str &strBandwidthGroup)
{
LogFlowThisFuncEnter();
- LogFlowThisFunc(("aParent=%p aMedium=%p aControllerName=%ls aPort=%d aDevice=%d aType=%d aPassthrough=%d\n", aParent, aMedium, aControllerName.raw(), aPort, aDevice, aType, aPassthrough));
+ LogFlowThisFunc(("aParent=%p aMedium=%p aControllerName=%ls aPort=%d aDevice=%d aType=%d aImplicit=%d aPassthrough=%d aTempEject=%d aNonRotational=%d strBandwithGroup=%s\n", aParent, aMedium, aControllerName.raw(), aPort, aDevice, aType, aImplicit, aPassthrough, aTempEject, aNonRotational, strBandwidthGroup.c_str()));
if (aType == DeviceType_HardDisk)
AssertReturn(aMedium, E_INVALIDARG);
@@ -133,9 +144,9 @@ HRESULT MediumAttachment::init(Machine *aParent,
unconst(m->bd->type) = aType;
m->bd->fPassthrough = aPassthrough;
- /* Newly created attachments never have an implicitly created medium
- * associated with them. Implicit diff image creation happens later. */
- m->bd->fImplicit = false;
+ m->bd->fTempEject = aTempEject;
+ m->bd->fNonRotational = aNonRotational;
+ m->bd->fImplicit = aImplicit;
/* Confirm a successful initialization when it's the case */
autoInitSpan.setSucceeded();
@@ -277,6 +288,57 @@ STDMETHODIMP MediumAttachment::COMGETTER(Passthrough)(BOOL *aPassthrough)
return S_OK;
}
+STDMETHODIMP MediumAttachment::COMGETTER(TemporaryEject)(BOOL *aTemporaryEject)
+{
+ LogFlowThisFuncEnter();
+
+ CheckComArgOutPointerValid(aTemporaryEject);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
+
+ *aTemporaryEject = m->bd->fTempEject;
+
+ LogFlowThisFuncLeave();
+ return S_OK;
+}
+
+STDMETHODIMP MediumAttachment::COMGETTER(IsEjected)(BOOL *aEjected)
+{
+ LogFlowThisFuncEnter();
+
+ CheckComArgOutPointerValid(aEjected);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
+
+ *aEjected = m->fIsEjected;
+
+ LogFlowThisFuncLeave();
+ return S_OK;
+}
+
+STDMETHODIMP MediumAttachment::COMGETTER(NonRotational)(BOOL *aNonRotational)
+{
+ LogFlowThisFuncEnter();
+
+ CheckComArgOutPointerValid(aNonRotational);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
+
+ *aNonRotational = m->bd->fNonRotational;
+
+ LogFlowThisFuncLeave();
+ return S_OK;
+}
+
STDMETHODIMP MediumAttachment::COMGETTER(BandwidthGroup) (IBandwidthGroup **aBwGroup)
{
LogFlowThisFuncEnter();
@@ -381,6 +443,18 @@ bool MediumAttachment::getPassthrough() const
return m->bd->fPassthrough;
}
+bool MediumAttachment::getTempEject() const
+{
+ AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
+ return m->bd->fTempEject;
+}
+
+bool MediumAttachment::getNonRotational() const
+{
+ AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
+ return m->bd->fNonRotational;
+}
+
const Utf8Str& MediumAttachment::getBandwidthGroup() const
{
return m->bd->strBandwidthGroup;
@@ -404,6 +478,7 @@ void MediumAttachment::updateMedium(const ComObjPtr<Medium> &aMedium)
m->bd.backup();
m->bd->pMedium = aMedium;
m->bd->fImplicit = false;
+ m->fIsEjected = false;
}
/** Must be called from under this object's write lock. */
@@ -415,6 +490,32 @@ void MediumAttachment::updatePassthrough(bool aPassthrough)
m->bd->fPassthrough = aPassthrough;
}
+/** Must be called from under this object's write lock. */
+void MediumAttachment::updateTempEject(bool aTempEject)
+{
+ Assert(isWriteLockOnCurrentThread());
+
+ m->bd.backup();
+ m->bd->fTempEject = aTempEject;
+}
+
+/** Must be called from under this object's write lock. */
+void MediumAttachment::updateEjected()
+{
+ Assert(isWriteLockOnCurrentThread());
+
+ m->fIsEjected = true;
+}
+
+/** Must be called from under this object's write lock. */
+void MediumAttachment::updateNonRotational(bool aNonRotational)
+{
+ Assert(isWriteLockOnCurrentThread());
+
+ m->bd.backup();
+ m->bd->fNonRotational = aNonRotational;
+}
+
void MediumAttachment::updateBandwidthGroup(const Utf8Str &aBandwidthGroup)
{
LogFlowThisFuncEnter();
diff --git a/src/VBox/Main/src-server/MediumFormatImpl.cpp b/src/VBox/Main/src-server/MediumFormatImpl.cpp
index 626733977..d830fa2f8 100644
--- a/src/VBox/Main/src-server/MediumFormatImpl.cpp
+++ b/src/VBox/Main/src-server/MediumFormatImpl.cpp
@@ -1,11 +1,11 @@
-/* $Id: MediumFormatImpl.cpp $ */
+/* $Id: MediumFormatImpl.cpp 37587 2011-06-22 12:02:13Z vboxsync $ */
/** @file
*
* VirtualBox COM class implementation
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -31,12 +31,14 @@ DEFINE_EMPTY_CTOR_DTOR(MediumFormat)
HRESULT MediumFormat::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void MediumFormat::FinalRelease()
{
uninit();
+
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
@@ -63,8 +65,8 @@ HRESULT MediumFormat::init(const VDBACKENDINFO *aVDInfo)
/* Use id for now as long as VDBACKENDINFO hasn't any extra
* name/description field. */
unconst(m.strName) = aVDInfo->pszBackend;
- /* The capabilities of the backend */
- unconst(m.capabilities) = aVDInfo->uBackendCaps;
+ /* The capabilities of the backend. Assumes 1:1 mapping! */
+ unconst(m.capabilities) = (MediumFormatCapabilities_T)aVDInfo->uBackendCaps;
/* Save the supported file extensions in a list */
if (aVDInfo->paFileExtensions)
{
@@ -181,7 +183,7 @@ void MediumFormat::uninit()
unconst(m.llProperties).clear();
unconst(m.llFileExtensions).clear();
unconst(m.llDeviceTypes).clear();
- unconst(m.capabilities) = 0;
+ unconst(m.capabilities) = (MediumFormatCapabilities_T)0;
unconst(m.strName).setNull();
unconst(m.strId).setNull();
}
@@ -227,10 +229,11 @@ STDMETHODIMP MediumFormat::COMGETTER(Capabilities)(ULONG *aCaps)
/// @todo add COMGETTER(ExtendedCapabilities) when we reach the 32 bit
/// limit (or make the argument ULONG64 after checking that COM is capable
/// of defining enums (used to represent bit flags) that contain 64-bit
- /// values)
- ComAssertRet(m.capabilities == ((ULONG)m.capabilities), E_FAIL);
+ /// values). Or go away from the enum/ulong hack for bit sets and use
+ /// a safearray like elsewhere.
+ ComAssertRet((uint64_t)m.capabilities == ((ULONG)m.capabilities), E_FAIL);
- *aCaps = (ULONG) m.capabilities;
+ *aCaps = (ULONG)m.capabilities;
return S_OK;
}
diff --git a/src/VBox/Main/src-server/MediumImpl.cpp b/src/VBox/Main/src-server/MediumImpl.cpp
index ab4daf457..f58ac1c6c 100644
--- a/src/VBox/Main/src-server/MediumImpl.cpp
+++ b/src/VBox/Main/src-server/MediumImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: MediumImpl.cpp $ */
+/* $Id: MediumImpl.cpp 37985 2011-07-15 15:04:39Z vboxsync $ */
/** @file
* VirtualBox COM class implementation
*/
@@ -137,7 +137,9 @@ struct Medium::Data
bool autoReset : 1;
+ /** New UUID to be set on the next queryInfo() call. */
const Guid uuidImage;
+ /** New parent UUID to be set on the next queryInfo() call. */
const Guid uuidParentImage;
bool hostDrive : 1;
@@ -896,7 +898,7 @@ HRESULT Medium::FinalConstruct()
vrc = RTSemEventMultiSignal(m->queryInfoSem);
AssertRCReturn(vrc, E_FAIL);
- return S_OK;
+ return BaseFinalConstruct();
}
void Medium::FinalRelease()
@@ -904,6 +906,8 @@ void Medium::FinalRelease()
uninit();
delete m;
+
+ BaseFinalRelease();
}
/**
@@ -918,15 +922,15 @@ void Medium::FinalRelease()
* is set to the registry of the parent image to make sure they all end up in the same
* file.
*
- * For hard disks that don't have the VD_CAP_CREATE_FIXED or
- * VD_CAP_CREATE_DYNAMIC capability (and therefore cannot be created or deleted
+ * For hard disks that don't have the MediumFormatCapabilities_CreateFixed or
+ * MediumFormatCapabilities_CreateDynamic capability (and therefore cannot be created or deleted
* with the means of VirtualBox) the associated storage unit is assumed to be
* ready for use so the state of the hard disk object will be set to Created.
*
* @param aVirtualBox VirtualBox object.
* @param aFormat
* @param aLocation Storage unit location.
- * @param uuidMachineRegistry The registry to which this medium should be added (global registry UUI or medium UUID or empty if none).
+ * @param uuidMachineRegistry The registry to which this medium should be added (global registry UUID or machine UUID or empty if none).
* @param pllRegistriesThatNeedSaving Optional list to receive the UUIDs of the media registries that need saving.
*/
HRESULT Medium::init(VirtualBox *aVirtualBox,
@@ -1009,11 +1013,13 @@ HRESULT Medium::init(VirtualBox *aVirtualBox,
* @param aVirtualBox VirtualBox object.
* @param aLocation Storage unit location.
* @param enOpenMode Whether to open the medium read/write or read-only.
+ * @param fForceNewUuid Whether a new UUID should be set to avoid duplicates.
* @param aDeviceType Device type of medium.
*/
HRESULT Medium::init(VirtualBox *aVirtualBox,
const Utf8Str &aLocation,
HDDOpenMode enOpenMode,
+ bool fForceNewUuid,
DeviceType_T aDeviceType)
{
AssertReturn(aVirtualBox, E_INVALIDARG);
@@ -1048,7 +1054,9 @@ HRESULT Medium::init(VirtualBox *aVirtualBox,
if (FAILED(rc)) return rc;
/* get all the information about the medium from the storage unit */
- rc = queryInfo(false /* fSetImageId */, false /* fSetParentId */);
+ if (fForceNewUuid)
+ unconst(m->uuidImage).create();
+ rc = queryInfo(fForceNewUuid /* fSetImageId */, false /* fSetParentId */);
if (SUCCEEDED(rc))
{
@@ -1086,7 +1094,7 @@ HRESULT Medium::init(VirtualBox *aVirtualBox,
* @param aVirtualBox VirtualBox object.
* @param aParent Parent medium disk or NULL for a root (base) medium.
* @param aDeviceType Device type of the medium.
- * @param uuidMachineRegistry The registry to which this medium should be added (global registry UUI or medium UUID).
+ * @param uuidMachineRegistry The registry to which this medium should be added (global registry UUID or machine UUID).
* @param aNode Configuration settings.
* @param strMachineFolder The machine folder with which to resolve relative paths; if empty, then we use the VirtualBox home directory
*
@@ -1176,24 +1184,29 @@ HRESULT Medium::init(VirtualBox *aVirtualBox,
m->mapProperties[name] = value;
}
- // compose full path of the medium, if it's not fully qualified...
- // slightly convoluted logic here. If the caller has given us a
- // machine folder, then a relative path will be relative to that:
Utf8Str strFull;
- if ( !strMachineFolder.isEmpty()
- && !RTPathStartsWithRoot(data.strLocation.c_str())
- )
+ if (m->formatObj->getCapabilities() & MediumFormatCapabilities_File)
{
- strFull = strMachineFolder;
- strFull += RTPATH_SLASH;
- strFull += data.strLocation;
+ // compose full path of the medium, if it's not fully qualified...
+ // slightly convoluted logic here. If the caller has given us a
+ // machine folder, then a relative path will be relative to that:
+ if ( !strMachineFolder.isEmpty()
+ && !RTPathStartsWithRoot(data.strLocation.c_str())
+ )
+ {
+ strFull = strMachineFolder;
+ strFull += RTPATH_SLASH;
+ strFull += data.strLocation;
+ }
+ else
+ {
+ // Otherwise use the old VirtualBox "make absolute path" logic:
+ rc = m->pVirtualBox->calculateFullPath(data.strLocation, strFull);
+ if (FAILED(rc)) return rc;
+ }
}
else
- {
- // Otherwise use the old VirtualBox "make absolute path" logic:
- rc = m->pVirtualBox->calculateFullPath(data.strLocation, strFull);
- if (FAILED(rc)) return rc;
- }
+ strFull = data.strLocation;
rc = setLocation(strFull);
if (FAILED(rc)) return rc;
@@ -1279,7 +1292,9 @@ HRESULT Medium::init(VirtualBox *aVirtualBox,
unconst(m->pVirtualBox) = aVirtualBox;
- /* fake up a UUID which is unique, but also reproducible */
+ // We do not store host drives in VirtualBox.xml or anywhere else, so if we want
+ // host drives to be identifiable by UUID and not give the drive a different UUID
+ // every time VirtualBox starts, we need to fake a reproducible UUID here:
RTUUID uuid;
RTUuidClear(&uuid);
if (aDeviceType == DeviceType_DVD)
@@ -1754,6 +1769,18 @@ STDMETHODIMP Medium::COMSETTER(Type)(MediumType_T aType)
return rc;
}
+STDMETHODIMP Medium::COMGETTER(AllowedTypes)(ComSafeArrayOut(MediumType_T, aAllowedTypes))
+{
+ CheckComArgOutSafeArrayPointerValid(aAllowedTypes);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ ReturnComNotImplemented();
+}
+
STDMETHODIMP Medium::COMGETTER(Parent)(IMedium **aParent)
{
CheckComArgOutPointerValid(aParent);
@@ -1803,7 +1830,7 @@ STDMETHODIMP Medium::COMGETTER(ReadOnly)(BOOL *aReadOnly)
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
- /* isRadOnly() will do locking */
+ /* isReadOnly() will do locking */
*aReadOnly = isReadOnly();
@@ -1948,12 +1975,22 @@ STDMETHODIMP Medium::SetIDs(BOOL aSetImageId,
Guid imageId, parentId;
if (aSetImageId)
{
- imageId = Guid(aImageId);
- if (imageId.isEmpty())
- return setError(E_INVALIDARG, tr("Argument %s is empty"), "aImageId");
+ if (Bstr(aImageId).isEmpty())
+ imageId.create();
+ else
+ {
+ imageId = Guid(aImageId);
+ if (imageId.isEmpty())
+ return setError(E_INVALIDARG, tr("Argument %s is empty"), "aImageId");
+ }
}
if (aSetParentId)
- parentId = Guid(aParentId);
+ {
+ if (Bstr(aParentId).isEmpty())
+ parentId.create();
+ else
+ parentId = Guid(aParentId);
+ }
unconst(m->uuidImage) = imageId;
unconst(m->uuidParentImage) = parentId;
@@ -3240,7 +3277,7 @@ HRESULT Medium::addToRegistryIDList(GuidList &llRegistryIDs)
it != m->llRegistryIDs.end();
++it)
{
- m->pVirtualBox->addGuidToListUniquely(llRegistryIDs, *it);
+ VirtualBox::addGuidToListUniquely(llRegistryIDs, *it);
}
return S_OK;
@@ -3439,6 +3476,11 @@ const Guid* Medium::getFirstMachineBackrefSnapshotId() const
return &ref.llSnapshotIds.front();
}
+size_t Medium::getMachineBackRefCount() const
+{
+ return m->backRefs.size();
+}
+
#ifdef DEBUG
/**
* Debugging helper that gets called after VirtualBox initialization that writes all
@@ -3600,6 +3642,15 @@ bool Medium::isReadOnly()
}
/**
+ * Internal method to return the medium's size. Must have caller + locking!
+ * @return
+ */
+void Medium::updateId(const Guid &id)
+{
+ unconst(m->id) = id;
+}
+
+/**
* Saves medium data by appending a new child node to the given
* parent XML settings node.
*
@@ -5085,9 +5136,9 @@ HRESULT Medium::queryInfo(bool fSetImageId, bool fSetParentId)
* when opening media of some third-party formats for the first
* time in VirtualBox (such as VMDK for which VDOpen() needs to
* generate an UUID if it is missing) */
- if ( (m->hddOpenMode == OpenReadOnly)
+ if ( m->hddOpenMode == OpenReadOnly
|| m->type == MediumType_Readonly
- || !isImport
+ || (!isImport && !fSetImageId && !fSetParentId)
)
uOpenFlags |= VD_OPEN_FLAGS_READONLY;
@@ -5164,6 +5215,7 @@ HRESULT Medium::queryInfo(bool fSetImageId, bool fSetParentId)
{
vrc = VDSetUuid(hdd, 0, m->uuidImage.raw());
ComAssertRCThrow(vrc, E_FAIL);
+ mediumId = m->uuidImage;
}
if (fSetParentId)
{
@@ -5193,6 +5245,7 @@ HRESULT Medium::queryInfo(bool fSetImageId, bool fSetParentId)
if (mediumId != uuid)
{
+ /** @todo r=klaus this always refers to VirtualBox.xml as the medium registry, even for new VMs */
lastAccessError = Utf8StrFmt(
tr("UUID {%RTuuid} of the medium '%s' does not match the value {%RTuuid} stored in the media registry ('%s')"),
&uuid,
@@ -5208,13 +5261,15 @@ HRESULT Medium::queryInfo(bool fSetImageId, bool fSetParentId)
/* the backend does not support storing UUIDs within the
* underlying storage so use what we store in XML */
- /* generate an UUID for an imported UUID-less medium */
- if (isImport)
+ if (fSetImageId)
{
- if (fSetImageId)
- mediumId = m->uuidImage;
- else
- mediumId.create();
+ /* set the UUID if an API client wants to change it */
+ mediumId = m->uuidImage;
+ }
+ else if (isImport)
+ {
+ /* generate an UUID for an imported UUID-less medium */
+ mediumId.create();
}
}
@@ -5300,6 +5355,7 @@ HRESULT Medium::queryInfo(bool fSetImageId, bool fSetParentId)
&& m->pParent->getState() != MediumState_Inaccessible
&& m->pParent->getId() != parentId)
{
+ /** @todo r=klaus this always refers to VirtualBox.xml as the medium registry, even for new VMs */
lastAccessError = Utf8StrFmt(
tr("Parent UUID {%RTuuid} of the medium '%s' does not match UUID {%RTuuid} of its parent medium stored in the media registry ('%s')"),
&parentId, location.c_str(),
@@ -5333,7 +5389,7 @@ HRESULT Medium::queryInfo(bool fSetImageId, bool fSetParentId)
alock.enter();
- if (isImport)
+ if (isImport || fSetImageId)
unconst(m->id) = mediumId;
if (success)
@@ -5652,8 +5708,10 @@ HRESULT Medium::setLocation(const Utf8Str &aLocation,
}
}
- // we must always have full paths now
- if (!RTPathStartsWithRoot(locationFull.c_str()))
+ // we must always have full paths now (if it refers to a file)
+ if ( ( m->formatObj.isNull()
+ || m->formatObj->getCapabilities() & MediumFormatCapabilities_File)
+ && !RTPathStartsWithRoot(locationFull.c_str()))
return setError(VBOX_E_FILE_ERROR,
tr("The given path '%s' is not fully qualified"),
locationFull.c_str());
@@ -6172,8 +6230,8 @@ HRESULT Medium::taskCreateBaseHandler(Medium::CreateBaseTask &task)
Utf8Str format(m->strFormat);
Utf8Str location(m->strLocationFull);
uint64_t capabilities = m->formatObj->getCapabilities();
- ComAssertThrow(capabilities & ( VD_CAP_CREATE_FIXED
- | VD_CAP_CREATE_DYNAMIC), E_FAIL);
+ ComAssertThrow(capabilities & ( MediumFormatCapabilities_CreateFixed
+ | MediumFormatCapabilities_CreateDynamic), E_FAIL);
Assert(m->state == MediumState_Creating);
PVBOXHDD hdd;
@@ -6186,7 +6244,7 @@ HRESULT Medium::taskCreateBaseHandler(Medium::CreateBaseTask &task)
try
{
/* ensure the directory exists */
- if (capabilities & VD_CAP_FILE)
+ if (capabilities & MediumFormatCapabilities_File)
{
rc = VirtualBox::ensureFilePathExists(location);
if (FAILED(rc))
@@ -6303,7 +6361,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task)
Utf8Str targetFormat(pTarget->m->strFormat);
Utf8Str targetLocation(pTarget->m->strLocationFull);
uint64_t capabilities = pTarget->m->formatObj->getCapabilities();
- ComAssertThrow(capabilities & VD_CAP_CREATE_DYNAMIC, E_FAIL);
+ ComAssertThrow(capabilities & MediumFormatCapabilities_CreateDynamic, E_FAIL);
Assert(pTarget->m->state == MediumState_Creating);
Assert(m->state == MediumState_LockedRead);
@@ -6353,7 +6411,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task)
}
/* ensure the target directory exists */
- if (capabilities & VD_CAP_FILE)
+ if (capabilities & MediumFormatCapabilities_File)
{
HRESULT rc = VirtualBox::ensureFilePathExists(targetLocation);
if (FAILED(rc))
@@ -6856,7 +6914,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task)
thisLock.release();
/* ensure the target directory exists */
- if (capabilities & VD_CAP_FILE)
+ if (capabilities & MediumFormatCapabilities_File)
{
HRESULT rc = VirtualBox::ensureFilePathExists(targetLocation);
if (FAILED(rc))
@@ -7505,7 +7563,7 @@ HRESULT Medium::taskExportHandler(Medium::ExportTask &task)
thisLock.release();
/* ensure the target directory exists */
- if (capabilities & VD_CAP_FILE)
+ if (capabilities & MediumFormatCapabilities_File)
{
rc = VirtualBox::ensureFilePathExists(targetLocation);
if (FAILED(rc))
@@ -7630,7 +7688,7 @@ HRESULT Medium::taskImportHandler(Medium::ImportTask &task)
thisLock.release();
/* ensure the target directory exists */
- if (capabilities & VD_CAP_FILE)
+ if (capabilities & MediumFormatCapabilities_File)
{
HRESULT rc = VirtualBox::ensureFilePathExists(targetLocation);
if (FAILED(rc))
diff --git a/src/VBox/Main/src-server/NATEngineImpl.cpp b/src/VBox/Main/src-server/NATEngineImpl.cpp
index 55dd12cfc..18eb78cf6 100644
--- a/src/VBox/Main/src-server/NATEngineImpl.cpp
+++ b/src/VBox/Main/src-server/NATEngineImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: NATEngineImpl.cpp $ */
+/* $Id: NATEngineImpl.cpp 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* Implementation of INATEngine in VBoxSVC.
*/
@@ -100,13 +100,14 @@ HRESULT NATEngine::initCopy (Machine *aParent, INetworkAdapter *aAdapter, NATEng
unconst(mAdapter) = aAdapter;
unconst(mParent) = aParent;
autoInitSpan.setSucceeded();
- return S_OK;
+ return BaseFinalConstruct();
}
void NATEngine::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
void NATEngine::uninit()
diff --git a/src/VBox/Main/src-server/NetworkAdapterImpl.cpp b/src/VBox/Main/src-server/NetworkAdapterImpl.cpp
index 81459ac05..85bfc08bd 100644
--- a/src/VBox/Main/src-server/NetworkAdapterImpl.cpp
+++ b/src/VBox/Main/src-server/NetworkAdapterImpl.cpp
@@ -1,10 +1,10 @@
-/* $Id: NetworkAdapterImpl.cpp $ */
+/* $Id: NetworkAdapterImpl.cpp 37927 2011-07-13 15:48:41Z vboxsync $ */
/** @file
* Implementation of INetworkAdaptor in VBoxSVC.
*/
/*
- * 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;
@@ -21,6 +21,7 @@
#include "Logging.h"
#include "MachineImpl.h"
#include "GuestOSTypeImpl.h"
+#include "HostImpl.h"
#include <iprt/string.h>
#include <iprt/cpp/utils.h>
@@ -45,12 +46,13 @@ NetworkAdapter::~NetworkAdapter()
HRESULT NetworkAdapter::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void NetworkAdapter::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
@@ -84,9 +86,6 @@ HRESULT NetworkAdapter::init(Machine *aParent, ULONG aSlot)
/* initialize data */
mData->mSlot = aSlot;
- /* Default limit is not capped/unlimited. */
- mData->mBandwidthLimit = 0;
-
/* default to Am79C973 */
mData->mAdapterType = NetworkAdapterType_Am79C973;
@@ -338,47 +337,23 @@ STDMETHODIMP NetworkAdapter::COMGETTER(MACAddress)(BSTR *aMACAddress)
return S_OK;
}
-STDMETHODIMP NetworkAdapter::COMSETTER(MACAddress)(IN_BSTR aMACAddress)
+HRESULT NetworkAdapter::updateMacAddress(Utf8Str aMACAddress)
{
- AutoCaller autoCaller(this);
- if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
- /* the machine needs to be mutable */
- AutoMutableStateDependency adep(mParent);
- if (FAILED(adep.rc())) return adep.rc();
-
HRESULT rc = S_OK;
- bool emitChangeEvent = false;
/*
* Are we supposed to generate a MAC?
*/
- if (!aMACAddress || !*aMACAddress)
- {
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- mData.backup();
-
+ if (aMACAddress.isEmpty())
generateMACAddress();
- emitChangeEvent = true;
-
- m_fModified = true;
- // leave the lock before informing callbacks
- alock.release();
-
- AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
- mParent->setModified(Machine::IsModified_NetworkAdapters);
- mlock.release();
- }
else
{
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
if (mData->mMACAddress != aMACAddress)
{
/*
* Verify given MAC address
*/
- Utf8Str macAddressUtf = aMACAddress;
- char *macAddressStr = macAddressUtf.mutableRaw();
+ char *macAddressStr = aMACAddress.mutableRaw();
int i = 0;
while ((i < 13) && macAddressStr && *macAddressStr && (rc == S_OK))
{
@@ -406,28 +381,37 @@ STDMETHODIMP NetworkAdapter::COMSETTER(MACAddress)(IN_BSTR aMACAddress)
rc = setError(E_INVALIDARG, tr("Invalid MAC address format"));
if (SUCCEEDED(rc))
- {
- mData.backup();
+ mData->mMACAddress = aMACAddress;
+ }
+ }
- mData->mMACAddress = macAddressUtf;
+ return rc;
+}
- emitChangeEvent = true;
+STDMETHODIMP NetworkAdapter::COMSETTER(MACAddress)(IN_BSTR aMACAddress)
+{
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
- m_fModified = true;
- // leave the lock before informing callbacks
- alock.release();
+ /* the machine needs to be mutable */
+ AutoMutableStateDependency adep(mParent);
+ if (FAILED(adep.rc())) return adep.rc();
- AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
- mParent->setModified(Machine::IsModified_NetworkAdapters);
- mlock.release();
- }
- }
- }
- // we have left the lock in any case at this point
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ mData.backup();
- if (emitChangeEvent)
+ HRESULT rc = updateMacAddress(aMACAddress);
+ if (SUCCEEDED(rc))
{
+ m_fModified = true;
+ // leave the lock before informing callbacks
+ alock.release();
+
+ AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
+ mParent->setModified(Machine::IsModified_NetworkAdapters);
+ mlock.release();
+
/* Changing the MAC via the Main API during runtime is not allowed,
* therefore no immediate change in CFGM logic => changeAdapter=FALSE. */
mParent->onNetworkAdapterChange(this, FALSE);
@@ -451,25 +435,116 @@ STDMETHODIMP NetworkAdapter::COMGETTER(AttachmentType)(
return S_OK;
}
-STDMETHODIMP NetworkAdapter::COMGETTER(HostInterface)(BSTR *aHostInterface)
+STDMETHODIMP NetworkAdapter::COMSETTER(AttachmentType)(
+ NetworkAttachmentType_T aAttachmentType)
+{
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ /* the machine needs to be mutable */
+ AutoMutableStateDependency adep(mParent);
+ if (FAILED(adep.rc())) return adep.rc();
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ if (mData->mAttachmentType != aAttachmentType)
+ {
+ mData.backup();
+
+ /* there must an internal network name */
+ if (mData->mInternalNetwork.isEmpty())
+ {
+ Log(("Internal network name not defined, setting to default \"intnet\"\n"));
+ mData->mInternalNetwork = "intnet";
+ }
+
+ mData->mAttachmentType = aAttachmentType;
+
+ m_fModified = true;
+ // leave the lock before informing callbacks
+ alock.release();
+
+ AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
+ mParent->setModified(Machine::IsModified_NetworkAdapters);
+ mlock.release();
+
+ /* Adapt the CFGM logic and notify the guest => changeAdapter=TRUE. */
+ mParent->onNetworkAdapterChange(this, TRUE);
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP NetworkAdapter::COMGETTER(BridgedInterface)(BSTR *aBridgedInterface)
+{
+ CheckComArgOutPointerValid(aBridgedInterface);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ mData->mBridgedInterface.cloneTo(aBridgedInterface);
+
+ return S_OK;
+}
+
+STDMETHODIMP NetworkAdapter::COMSETTER(BridgedInterface)(IN_BSTR aBridgedInterface)
+{
+ Bstr bstrEmpty("");
+ if (!aBridgedInterface)
+ aBridgedInterface = bstrEmpty.raw();
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ /* the machine needs to be mutable */
+ AutoMutableStateDependency adep(mParent);
+ if (FAILED(adep.rc())) return adep.rc();
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ if (mData->mBridgedInterface != aBridgedInterface)
+ {
+ mData.backup();
+ mData->mBridgedInterface = aBridgedInterface;
+
+ m_fModified = true;
+ // leave the lock before informing callbacks
+ alock.release();
+
+ AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
+ mParent->setModified(Machine::IsModified_NetworkAdapters);
+ mlock.release();
+
+ /* When changing the host adapter, adapt the CFGM logic to make this
+ * change immediately effect and to notify the guest that the network
+ * might have changed, therefore changeAdapter=TRUE. */
+ mParent->onNetworkAdapterChange(this, TRUE);
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP NetworkAdapter::COMGETTER(HostOnlyInterface)(BSTR *aHostOnlyInterface)
{
- CheckComArgOutPointerValid(aHostInterface);
+ CheckComArgOutPointerValid(aHostOnlyInterface);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- mData->mHostInterface.cloneTo(aHostInterface);
+ mData->mHostOnlyInterface.cloneTo(aHostOnlyInterface);
return S_OK;
}
-STDMETHODIMP NetworkAdapter::COMSETTER(HostInterface)(IN_BSTR aHostInterface)
+STDMETHODIMP NetworkAdapter::COMSETTER(HostOnlyInterface)(IN_BSTR aHostOnlyInterface)
{
Bstr bstrEmpty("");
- if (!aHostInterface)
- aHostInterface = bstrEmpty.raw();
+ if (!aHostOnlyInterface)
+ aHostOnlyInterface = bstrEmpty.raw();
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -480,10 +555,10 @@ STDMETHODIMP NetworkAdapter::COMSETTER(HostInterface)(IN_BSTR aHostInterface)
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- if (mData->mHostInterface != aHostInterface)
+ if (mData->mHostOnlyInterface != aHostOnlyInterface)
{
mData.backup();
- mData->mHostInterface = aHostInterface;
+ mData->mHostOnlyInterface = aHostOnlyInterface;
m_fModified = true;
// leave the lock before informing callbacks
@@ -608,57 +683,47 @@ STDMETHODIMP NetworkAdapter::COMSETTER(NATNetwork) (IN_BSTR aNATNetwork)
return S_OK;
}
-STDMETHODIMP NetworkAdapter::COMGETTER(VDENetwork) (BSTR *aVDENetwork)
+STDMETHODIMP NetworkAdapter::COMGETTER(GenericDriver)(BSTR *aGenericDriver)
{
-#if defined(VBOX_WITH_VDE)
- CheckComArgOutPointerValid(aVDENetwork);
+ CheckComArgOutPointerValid(aGenericDriver);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- mData->mVDENetwork.cloneTo(aVDENetwork);
+ mData->mGenericDriver.cloneTo(aGenericDriver);
return S_OK;
-#else
- NOREF(aVDENetwork);
- return E_NOTIMPL;
-#endif
}
-STDMETHODIMP NetworkAdapter::COMSETTER(VDENetwork) (IN_BSTR aVDENetwork)
+STDMETHODIMP NetworkAdapter::COMSETTER(GenericDriver)(IN_BSTR aGenericDriver)
{
-#if defined(VBOX_WITH_VDE)
Bstr bstrEmpty("");
- if (!aVDENetwork)
- aVDENetwork = bstrEmpty.raw();
+ if (!aGenericDriver)
+ aGenericDriver = bstrEmpty.raw();
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
/* the machine needs to be mutable */
- AutoMutableStateDependency adep (mParent);
+ AutoMutableStateDependency adep(mParent);
if (FAILED(adep.rc())) return adep.rc();
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- if (mData->mVDENetwork != aVDENetwork)
+ if (mData->mGenericDriver != aGenericDriver)
{
mData.backup();
- mData->mVDENetwork = aVDENetwork;
+ mData->mGenericDriver = aGenericDriver;
/* leave the lock before informing callbacks */
alock.release();
- mParent->onNetworkAdapterChange (this, FALSE);
+ mParent->onNetworkAdapterChange(this, FALSE);
}
return S_OK;
-#else
- NOREF(aVDENetwork);
- return E_NOTIMPL;
-#endif
}
STDMETHODIMP NetworkAdapter::COMGETTER(CableConnected) (BOOL *aConnected)
@@ -751,45 +816,52 @@ STDMETHODIMP NetworkAdapter::COMSETTER(LineSpeed) (ULONG aSpeed)
return S_OK;
}
-STDMETHODIMP NetworkAdapter::COMGETTER(BandwidthLimit) (ULONG *aLimit)
+
+STDMETHODIMP NetworkAdapter::COMGETTER(PromiscModePolicy)(NetworkAdapterPromiscModePolicy_T *aPromiscModePolicy)
{
- CheckComArgOutPointerValid(aLimit);
+ CheckComArgOutPointerValid(aPromiscModePolicy);
AutoCaller autoCaller(this);
- if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- *aLimit = mData->mBandwidthLimit;
- return S_OK;
+ HRESULT hrc = autoCaller.rc();
+ if (SUCCEEDED(hrc))
+ {
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ *aPromiscModePolicy = mData->mPromiscModePolicy;
+ }
+ return hrc;
}
-STDMETHODIMP NetworkAdapter::COMSETTER(BandwidthLimit) (ULONG aLimit)
+STDMETHODIMP NetworkAdapter::COMSETTER(PromiscModePolicy)(NetworkAdapterPromiscModePolicy_T aPromiscModePolicy)
{
- AutoCaller autoCaller(this);
- if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
- /* the machine doesn't need to be mutable */
-
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- if (aLimit != mData->mBandwidthLimit)
+ switch (aPromiscModePolicy)
{
- mData.backup();
- mData->mBandwidthLimit = aLimit;
+ case NetworkAdapterPromiscModePolicy_Deny:
+ case NetworkAdapterPromiscModePolicy_AllowNetwork:
+ case NetworkAdapterPromiscModePolicy_AllowAll:
+ break;
+ default:
+ return setError(E_INVALIDARG, tr("Invalid promiscuous mode policy (%d)"), aPromiscModePolicy);
+ }
- m_fModified = true;
- // leave the lock before informing callbacks
- alock.release();
+ AutoCaller autoCaller(this);
+ HRESULT hrc = autoCaller.rc();
- AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
- mParent->setModified(Machine::IsModified_NetworkAdapters);
- mlock.release();
+ if (SUCCEEDED(hrc))
+ {
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ if (aPromiscModePolicy != mData->mPromiscModePolicy)
+ {
+ mData.backup();
+ mData->mPromiscModePolicy = aPromiscModePolicy;
+ m_fModified = true;
- /* No change in CFGM logic => changeAdapter=FALSE. */
- mParent->onNetworkAdapterChange(this, FALSE);
+ alock.release();
+ mParent->setModifiedLock(Machine::IsModified_NetworkAdapters);
+ mParent->onNetworkAdapterChange(this, TRUE);
+ }
}
- return S_OK;
+
+ return hrc;
}
STDMETHODIMP NetworkAdapter::COMGETTER(TraceEnabled) (BOOL *aEnabled)
@@ -943,280 +1015,116 @@ STDMETHODIMP NetworkAdapter::COMSETTER(BootPriority) (ULONG aBootPriority)
// INetworkAdapter methods
////////////////////////////////////////////////////////////////////////////////
-STDMETHODIMP NetworkAdapter::AttachToNAT()
+STDMETHODIMP NetworkAdapter::GetProperty(IN_BSTR aKey, BSTR *aValue)
{
- AutoCaller autoCaller(this);
- if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
- /* the machine needs to be mutable */
- AutoMutableStateDependency adep(mParent);
- if (FAILED(adep.rc())) return adep.rc();
+ CheckComArgOutPointerValid(aValue);
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- if (mData->mAttachmentType != NetworkAttachmentType_NAT)
- {
- mData.backup();
-
- // Commented this for now as it resets the parameter mData->mNATNetwork
- // which is essential while changing the Attachment dynamically.
- //detach();
-
- mData->mAttachmentType = NetworkAttachmentType_NAT;
-
- m_fModified = true;
- // leave the lock before informing callbacks
- alock.release();
-
- AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
- mParent->setModified(Machine::IsModified_NetworkAdapters);
- mlock.release();
-
- /* Adapt the CFGM logic and notify the guest => changeAdapter=TRUE. */
- HRESULT rc = mParent->onNetworkAdapterChange(this, TRUE);
- if (FAILED(rc))
- {
- /* If changing the attachment failed then we can't assume
- * that the previous attachment will attach correctly
- * and thus return error along with detaching all
- * attachments.
- */
- Detach();
- return rc;
- }
- }
-
- return S_OK;
-}
-
-STDMETHODIMP NetworkAdapter::AttachToBridgedInterface()
-{
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
- /* the machine needs to be mutable */
- AutoMutableStateDependency adep(mParent);
- if (FAILED(adep.rc())) return adep.rc();
+ Bstr key = aKey;
+ Bstr value;
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* don't do anything if we're already host interface attached */
- if (mData->mAttachmentType != NetworkAttachmentType_Bridged)
+ Utf8Str strKey(key);
+ settings::StringsMap::const_iterator it = mData->mGenericProperties.find(strKey);
+ if (it != mData->mGenericProperties.end())
{
- mData.backup();
-
- /* first detach the current attachment */
- // Commented this for now as it reset the parameter mData->mHostInterface
- // which is essential while changing the Attachment dynamically.
- //detach();
-
- mData->mAttachmentType = NetworkAttachmentType_Bridged;
-
- m_fModified = true;
- // leave the lock before informing callbacks
- alock.release();
-
- AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
- mParent->setModified(Machine::IsModified_NetworkAdapters);
- mlock.release();
-
- /* Adapt the CFGM logic and notify the guest => changeAdapter=TRUE. */
- HRESULT rc = mParent->onNetworkAdapterChange(this, TRUE);
- if (FAILED(rc))
- {
- /* If changing the attachment failed then we can't assume that the
- * previous attachment will attach correctly and thus return error
- * along with detaching all attachments.
- */
- Detach();
- return rc;
- }
+ value = it->second; // source is a Utf8Str
+ value.cloneTo(aValue);
}
return S_OK;
}
-STDMETHODIMP NetworkAdapter::AttachToInternalNetwork()
+STDMETHODIMP NetworkAdapter::SetProperty(IN_BSTR aKey, IN_BSTR aValue)
{
+ LogFlowThisFunc(("\n"));
+
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
- /* the machine needs to be mutable */
+ /* The machine needs to be mutable. */
AutoMutableStateDependency adep(mParent);
if (FAILED(adep.rc())) return adep.rc();
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- /* don't do anything if we're already internal network attached */
- if (mData->mAttachmentType != NetworkAttachmentType_Internal)
- {
- mData.backup();
-
- /* first detach the current attachment */
- // Commented this for now as it reset the parameter mData->mInternalNetwork
- // which is essential while changing the Attachment dynamically.
- //detach();
-
- /* there must an internal network name */
- if (mData->mInternalNetwork.isEmpty())
- {
- LogRel (("Internal network name not defined, "
- "setting to default \"intnet\"\n"));
- mData->mInternalNetwork = "intnet";
- }
+ Bstr key = aKey;
- mData->mAttachmentType = NetworkAttachmentType_Internal;
-
- m_fModified = true;
- // leave the lock before informing callbacks
- alock.release();
-
- AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
- mParent->setModified(Machine::IsModified_NetworkAdapters);
- mlock.release();
-
- /* Adapt the CFGM logic and notify the guest => changeAdapter=TRUE. */
- HRESULT rc = mParent->onNetworkAdapterChange(this, TRUE);
- if (FAILED(rc))
- {
- /* If changing the attachment failed then we can't assume
- * that the previous attachment will attach correctly
- * and thus return error along with detaching all
- * attachments.
- */
- Detach();
- return rc;
- }
- }
-
- return S_OK;
-}
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-STDMETHODIMP NetworkAdapter::AttachToHostOnlyInterface()
-{
- AutoCaller autoCaller(this);
- if (FAILED(autoCaller.rc())) return autoCaller.rc();
+ bool fGenericChange = (mData->mAttachmentType == NetworkAttachmentType_Generic);
- /* the machine needs to be mutable */
- AutoMutableStateDependency adep(mParent);
- if (FAILED(adep.rc())) return adep.rc();
+ /* Generic properties processing.
+ * Look up the old value first; if nothing's changed then do nothing.
+ */
+ Utf8Str strValue(aValue);
+ Utf8Str strKey(aKey);
+ Utf8Str strOldValue;
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ settings::StringsMap::const_iterator it = mData->mGenericProperties.find(strKey);
+ if (it != mData->mGenericProperties.end())
+ strOldValue = it->second;
- /* don't do anything if we're already host interface attached */
- if (mData->mAttachmentType != NetworkAttachmentType_HostOnly)
+ if (strOldValue != strValue)
{
- mData.backup();
-
- /* first detach the current attachment */
- // Commented this for now as it reset the parameter mData->mHostInterface
- // which is essential while changing the Attachment dynamically.
- //detach();
-
- mData->mAttachmentType = NetworkAttachmentType_HostOnly;
+ if (strValue.isEmpty())
+ mData->mGenericProperties.erase(strKey);
+ else
+ mData->mGenericProperties[strKey] = strValue;
- m_fModified = true;
- // leave the lock before informing callbacks
+ /* leave the lock before informing callbacks */
alock.release();
- AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
+ AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
mParent->setModified(Machine::IsModified_NetworkAdapters);
mlock.release();
- /* Adapt the CFGM logic and notify the guest => changeAdpater=TRUE. */
- HRESULT rc = mParent->onNetworkAdapterChange(this, TRUE);
- if (FAILED(rc))
- {
- /* If changing the attachment failed then we can't assume
- * that the previous attachment will attach correctly
- * and thus return error along with detaching all
- * attachments.
- */
- Detach();
- return rc;
- }
+ /* Avoid deadlock when the event triggers a call to a method of this
+ * interface. */
+ adep.release();
+
+ mParent->onNetworkAdapterChange(this, fGenericChange);
}
return S_OK;
}
-STDMETHODIMP NetworkAdapter::AttachToVDE()
+STDMETHODIMP NetworkAdapter::GetProperties(IN_BSTR aNames,
+ ComSafeArrayOut(BSTR, aReturnNames),
+ ComSafeArrayOut(BSTR, aReturnValues))
{
-#if defined(VBOX_WITH_VDE)
+ CheckComArgOutSafeArrayPointerValid(aReturnNames);
+ CheckComArgOutSafeArrayPointerValid(aReturnValues);
+
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
- /* the machine needs to be mutable */
- AutoMutableStateDependency adep (mParent);
- if (FAILED(adep.rc())) return adep.rc();
-
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- /* don't do anything if we're already host interface attached */
- if (mData->mAttachmentType != NetworkAttachmentType_VDE)
- {
- mData.backup();
-
- /* first detach the current attachment */
- // Commented this for now as it reset the parameter mData->mHostInterface
- // which is essential while changing the Attachment dynamically.
- //detach();
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- mData->mAttachmentType = NetworkAttachmentType_VDE;
+ /// @todo make use of aNames according to the documentation
+ NOREF(aNames);
- /* leave the lock before informing callbacks */
- alock.release();
+ com::SafeArray<BSTR> names(mData->mGenericProperties.size());
+ com::SafeArray<BSTR> values(mData->mGenericProperties.size());
+ size_t i = 0;
- HRESULT rc = mParent->onNetworkAdapterChange (this, TRUE);
- if (FAILED (rc))
- {
- /* If changing the attachment failed then we can't assume
- * that the previous attachment will attach correctly
- * and thus return error along with detaching all
- * attachments.
- */
- Detach();
- return rc;
- }
+ for (settings::StringsMap::const_iterator it = mData->mGenericProperties.begin();
+ it != mData->mGenericProperties.end();
+ ++it)
+ {
+ it->first.cloneTo(&names[i]);
+ it->second.cloneTo(&values[i]);
+ ++i;
}
+ names.detachTo(ComSafeArrayOutArg(aReturnNames));
+ values.detachTo(ComSafeArrayOutArg(aReturnValues));
+
return S_OK;
-#else /* !VBOX_WITH_VDE */
- return E_NOTIMPL;
-#endif
}
-STDMETHODIMP NetworkAdapter::Detach()
-{
- AutoCaller autoCaller(this);
- if (FAILED(autoCaller.rc())) return autoCaller.rc();
- /* the machine needs to be mutable */
- AutoMutableStateDependency adep(mParent);
- if (FAILED(adep.rc())) return adep.rc();
-
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- if (mData->mAttachmentType != NetworkAttachmentType_Null)
- {
- mData.backup();
-
- detach();
-
- m_fModified = true;
- // leave the lock before informing callbacks
- alock.release();
-
- AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
- mParent->setModified(Machine::IsModified_NetworkAdapters);
- mlock.release();
-
- /* adapt the CFGM logic and notify the guest => changeAdapter=TRUE. */
- mParent->onNetworkAdapterChange(this, TRUE);
- }
-
- return S_OK;
-}
// public methods only for internal purposes
////////////////////////////////////////////////////////////////////////////////
@@ -1229,11 +1137,14 @@ STDMETHODIMP NetworkAdapter::Detach()
*
* @note Locks this object for writing.
*/
-HRESULT NetworkAdapter::loadSettings(const settings::NetworkAdapter &data)
+HRESULT NetworkAdapter::loadSettings(BandwidthControl *bwctl,
+ const settings::NetworkAdapter &data)
{
AutoCaller autoCaller(this);
AssertComRCReturnRC(autoCaller.rc());
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
/* Note: we assume that the default values for attributes of optional
* nodes are assigned in the Data::Data() constructor and don't do it
* here. It implies that this method may only be called after constructing
@@ -1250,67 +1161,40 @@ HRESULT NetworkAdapter::loadSettings(const settings::NetworkAdapter &data)
mData->mAdapterType = data.type;
mData->mEnabled = data.fEnabled;
/* MAC address (can be null) */
- rc = COMSETTER(MACAddress)(Bstr(data.strMACAddress).raw());
+ rc = updateMacAddress(data.strMACAddress);
if (FAILED(rc)) return rc;
/* cable (required) */
mData->mCableConnected = data.fCableConnected;
/* line speed (defaults to 100 Mbps) */
mData->mLineSpeed = data.ulLineSpeed;
+ mData->mPromiscModePolicy = data.enmPromiscModePolicy;
/* tracing (defaults to false) */
mData->mTraceEnabled = data.fTraceEnabled;
mData->mTraceFile = data.strTraceFile;
/* boot priority (defaults to 0, i.e. lowest) */
mData->mBootPriority = data.ulBootPriority;
- /* Bandwidth limit in Mbps. */
- mData->mBandwidthLimit = data.ulBandwidthLimit;
-
- switch (data.mode)
+ /* bandwidth group */
+ if (data.strBandwidthGroup.isEmpty())
+ updateBandwidthGroup(NULL);
+ else
{
- case NetworkAttachmentType_NAT:
- mNATEngine->loadSettings(data.nat);
- rc = AttachToNAT();
- if (FAILED(rc)) return rc;
- break;
-
- case NetworkAttachmentType_Bridged:
- rc = COMSETTER(HostInterface)(Bstr(data.strName).raw());
- if (FAILED(rc)) return rc;
- rc = AttachToBridgedInterface();
- if (FAILED(rc)) return rc;
- break;
-
- case NetworkAttachmentType_Internal:
- mData->mInternalNetwork = data.strName;
- Assert(!mData->mInternalNetwork.isEmpty());
-
- rc = AttachToInternalNetwork();
- if (FAILED(rc)) return rc;
- break;
-
- case NetworkAttachmentType_HostOnly:
-#if defined(VBOX_WITH_NETFLT)
- rc = COMSETTER(HostInterface)(Bstr(data.strName).raw());
- if (FAILED(rc)) return rc;
-#endif
- rc = AttachToHostOnlyInterface();
- if (FAILED(rc)) return rc;
- break;
-
-#if defined(VBOX_WITH_VDE)
- case NetworkAttachmentType_VDE:
- mData->mVDENetwork = data.strName;
- rc = AttachToVDE();
- if (FAILED(rc)) return rc;
- break;
-#endif
-
- case NetworkAttachmentType_Null:
- rc = Detach();
- if (FAILED(rc)) return rc;
- break;
+ ComObjPtr<BandwidthGroup> group;
+ rc = bwctl->getBandwidthGroupByName(data.strBandwidthGroup, group, true);
+ if (FAILED(rc)) return rc;
}
- if (data.fHasDisabledNAT)
- mNATEngine->loadSettings(data.nat);
+
+ mNATEngine->loadSettings(data.nat);
+ mData->mBridgedInterface = data.strBridgedName;
+ mData->mInternalNetwork = data.strInternalNetworkName;
+ mData->mHostOnlyInterface = data.strHostOnlyName;
+ mData->mGenericDriver = data.strGenericDriver;
+ mData->mGenericProperties = data.genericProperties;
+
+ // leave the lock before setting attachment type
+ alock.release();
+
+ rc = COMSETTER(AttachmentType)(data.mode);
+ if (FAILED(rc)) return rc;
// after loading settings, we are no longer different from the XML on disk
m_fModified = false;
@@ -1338,6 +1222,7 @@ HRESULT NetworkAdapter::saveSettings(settings::NetworkAdapter &data)
data.strMACAddress = mData->mMACAddress;
data.fCableConnected = !!mData->mCableConnected;
+ data.enmPromiscModePolicy = mData->mPromiscModePolicy;
data.ulLineSpeed = mData->mLineSpeed;
data.fTraceEnabled = !!mData->mTraceEnabled;
@@ -1346,47 +1231,26 @@ HRESULT NetworkAdapter::saveSettings(settings::NetworkAdapter &data)
data.ulBootPriority = mData->mBootPriority;
- data.ulBandwidthLimit = mData->mBandwidthLimit;
+ if (mData->mBandwidthGroup.isNull())
+ data.strBandwidthGroup = "";
+ else
+ data.strBandwidthGroup = mData->mBandwidthGroup->getName();
data.type = mData->mAdapterType;
- switch (data.mode = mData->mAttachmentType)
- {
- case NetworkAttachmentType_Null:
- data.strName.setNull();
- break;
-
- case NetworkAttachmentType_NAT:
- data.fHasDisabledNAT = 0;
- mNATEngine->commit();
- mNATEngine->saveSettings(data.nat);
- break;
-
- case NetworkAttachmentType_Bridged:
- data.strName = mData->mHostInterface;
- break;
-
- case NetworkAttachmentType_Internal:
- data.strName = mData->mInternalNetwork;
- break;
-
- case NetworkAttachmentType_HostOnly:
- data.strName = mData->mHostInterface;
- break;
-
-#if defined(VBOX_WITH_VDE)
- case NetworkAttachmentType_VDE:
- data.strName = mData->mVDENetwork;
- break;
-#endif
- }
+ data.mode = mData->mAttachmentType;
- if (data.mode != NetworkAttachmentType_NAT)
- {
- data.fHasDisabledNAT = 1; /* ??? */
- mNATEngine->commit();
- mNATEngine->saveSettings(data.nat);
- }
+ mNATEngine->commit();
+ mNATEngine->saveSettings(data.nat);
+
+ data.strBridgedName = mData->mBridgedInterface;
+
+ data.strHostOnlyName = mData->mHostOnlyInterface;
+
+ data.strInternalNetworkName = mData->mInternalNetwork;
+
+ data.strGenericDriver = mData->mGenericDriver;
+ data.genericProperties = mData->mGenericProperties;
// after saving settings, we are no longer different from the XML on disk
m_fModified = false;
@@ -1512,69 +1376,89 @@ void NetworkAdapter::applyDefaults (GuestOSType *aOsType)
////////////////////////////////////////////////////////////////////////////////
/**
- * Worker routine for detach handling. No locking, no notifications.
-
- * @note Must be called from under the object's write lock.
+ * Generates a new unique MAC address based on our vendor ID and
+ * parts of a GUID.
+ *
+ * @note Must be called from under the object's write lock or within the init
+ * span.
*/
-void NetworkAdapter::detach()
+void NetworkAdapter::generateMACAddress()
{
- AssertReturnVoid (isWriteLockOnCurrentThread());
+ Utf8Str mac;
+ Host::generateMACAddress(mac);
+ LogFlowThisFunc(("generated MAC: '%s'\n", mac.c_str()));
+ mData->mMACAddress = mac;
+}
+
+STDMETHODIMP NetworkAdapter::COMGETTER(BandwidthGroup) (IBandwidthGroup **aBwGroup)
+{
+ LogFlowThisFuncEnter();
+ CheckComArgOutPointerValid(aBwGroup);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
- switch (mData->mAttachmentType)
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ mData->mBandwidthGroup.queryInterfaceTo(aBwGroup);
+
+ LogFlowThisFuncLeave();
+ return S_OK;
+}
+
+STDMETHODIMP NetworkAdapter::COMSETTER(BandwidthGroup) (IBandwidthGroup *aBwGroup)
+{
+ LogFlowThisFuncEnter();
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ /* the machine needs to be mutable */
+ AutoMutableStateDependency adep(mParent);
+ if (FAILED(adep.rc())) return adep.rc();
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ if (mData->mBandwidthGroup != aBwGroup)
{
- case NetworkAttachmentType_Null:
- {
- /* nothing to do here */
- break;
- }
- case NetworkAttachmentType_NAT:
- {
- break;
- }
- case NetworkAttachmentType_Bridged:
- {
- /* reset handle and device name */
- mData->mHostInterface = "";
- break;
- }
- case NetworkAttachmentType_Internal:
- {
- mData->mInternalNetwork.setNull();
- break;
- }
- case NetworkAttachmentType_HostOnly:
- {
-#if defined(VBOX_WITH_NETFLT)
- /* reset handle and device name */
- mData->mHostInterface = "";
-#endif
- break;
- }
+ mData.backup();
+
+ updateBandwidthGroup(static_cast<BandwidthGroup*>(aBwGroup));
+
+ m_fModified = true;
+ // leave the lock before informing callbacks
+ alock.release();
+
+ AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
+ mParent->setModified(Machine::IsModified_NetworkAdapters);
+ mlock.release();
+
+ /* TODO: changeAdapter=???. */
+ mParent->onNetworkAdapterChange(this, FALSE);
}
- mData->mAttachmentType = NetworkAttachmentType_Null;
+ LogFlowThisFuncLeave();
+ return S_OK;
}
-/**
- * Generates a new unique MAC address based on our vendor ID and
- * parts of a GUID.
- *
- * @note Must be called from under the object's write lock or within the init
- * span.
- */
-void NetworkAdapter::generateMACAddress()
+void NetworkAdapter::updateBandwidthGroup(BandwidthGroup *aBwGroup)
{
- /*
- * Our strategy is as follows: the first three bytes are our fixed
- * vendor ID (080027). The remaining 3 bytes will be taken from the
- * start of a GUID. This is a fairly safe algorithm.
- */
- char strMAC[13];
- Guid guid;
- guid.create();
- RTStrPrintf (strMAC, sizeof(strMAC), "080027%02X%02X%02X",
- guid.raw()->au8[0], guid.raw()->au8[1], guid.raw()->au8[2]);
- LogFlowThisFunc(("generated MAC: '%s'\n", strMAC));
- mData->mMACAddress = strMAC;
+ LogFlowThisFuncEnter();
+ Assert(isWriteLockOnCurrentThread());
+
+ mData.backup();
+ if (!mData->mBandwidthGroup.isNull())
+ {
+ mData->mBandwidthGroup->release();
+ mData->mBandwidthGroup.setNull();
+ }
+
+ if (aBwGroup)
+ {
+ mData->mBandwidthGroup = aBwGroup;
+ mData->mBandwidthGroup->reference();
+ }
+
+ LogFlowThisFuncLeave();
}
/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/src-server/ParallelPortImpl.cpp b/src/VBox/Main/src-server/ParallelPortImpl.cpp
index 590306311..78574886d 100644
--- a/src/VBox/Main/src-server/ParallelPortImpl.cpp
+++ b/src/VBox/Main/src-server/ParallelPortImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: ParallelPortImpl.cpp $ */
+/* $Id: ParallelPortImpl.cpp 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* VirtualBox COM class implementation
*/
@@ -54,12 +54,13 @@ struct ParallelPort::Data
HRESULT ParallelPort::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void ParallelPort::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-server/Performance.cpp b/src/VBox/Main/src-server/Performance.cpp
index 2c6beef7b..298fdc11d 100644
--- a/src/VBox/Main/src-server/Performance.cpp
+++ b/src/VBox/Main/src-server/Performance.cpp
@@ -1,7 +1,5 @@
-/* $Id: Performance.cpp $ */
-
+/* $Id: Performance.cpp 36839 2011-04-25 17:29:21Z vboxsync $ */
/** @file
- *
* VBox Performance Classes implementation.
*/
@@ -75,16 +73,6 @@ int CollectorHAL::getProcessMemoryUsage(RTPROCESS /* process */, ULONG * /* used
return E_NOTIMPL;
}
-int CollectorHAL::enable()
-{
- return E_NOTIMPL;
-}
-
-int CollectorHAL::disable()
-{
- return E_NOTIMPL;
-}
-
/* Generic implementations */
int CollectorHAL::getHostCpuMHz(ULONG *mhz)
@@ -120,28 +108,27 @@ int CollectorHAL::getHostCpuMHz(ULONG *mhz)
#ifndef VBOX_COLLECTOR_TEST_CASE
-uint32_t CollectorGuestHAL::cVMsEnabled = 0;
-
-CollectorGuestHAL::CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL)
- : CollectorHAL(), cEnabled(0), mMachine(machine), mConsole(NULL),
- mGuest(NULL), mLastTick(0), mHostHAL(hostHAL), mCpuUser(0),
- mCpuKernel(0), mCpuIdle(0), mMemTotal(0), mMemFree(0),
- mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0)
+CollectorGuest::CollectorGuest(Machine *machine, RTPROCESS process) :
+ mUnregistered(false), mEnabled(false), mValid(false), mMachine(machine), mProcess(process),
+ mCpuUser(0), mCpuKernel(0), mCpuIdle(0),
+ mMemTotal(0), mMemFree(0), mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0),
+ mAllocVMM(0), mFreeVMM(0), mBalloonedVMM(0), mSharedVMM(0)
{
Assert(mMachine);
/* cannot use ComObjPtr<Machine> in Performance.h, do it manually */
mMachine->AddRef();
}
-CollectorGuestHAL::~CollectorGuestHAL()
+CollectorGuest::~CollectorGuest()
{
/* cannot use ComObjPtr<Machine> in Performance.h, do it manually */
mMachine->Release();
- Assert(!cEnabled);
+ // Assert(!cEnabled); why?
}
-int CollectorGuestHAL::enable()
+int CollectorGuest::enable()
{
+ 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
@@ -153,59 +140,169 @@ int CollectorGuestHAL::enable()
HRESULT ret = S_OK;
- if (ASMAtomicIncU32(&cEnabled) == 1)
- {
- ASMAtomicIncU32(&cVMsEnabled);
- ComPtr<IInternalSessionControl> directControl;
+ ComPtr<IInternalSessionControl> directControl;
- ret = mMachine->getDirectControl(&directControl);
- if (ret != S_OK)
- return ret;
+ 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;
+ /* 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)
- mGuest->COMSETTER(StatisticsUpdateInterval)(1 /* 1 sec */);
+ 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"));
}
+
return ret;
}
-int CollectorGuestHAL::disable()
+int CollectorGuest::disable()
+{
+ 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 S_OK;
+}
+
+int CollectorGuest::updateStats()
{
- if (ASMAtomicDecU32(&cEnabled) == 0)
+ if (mGuest)
{
- if (ASMAtomicDecU32(&cVMsEnabled) == 0)
+ HRESULT rc;
+ rc = mGuest->InternalGetStatistics(&mCpuUser, &mCpuKernel, &mCpuIdle,
+ &mMemTotal, &mMemFree, &mMemBalloon, &mMemShared, &mMemCache,
+ &mPageTotal, &mAllocVMM, &mFreeVMM, &mBalloonedVMM, &mSharedVMM);
+ if (SUCCEEDED(rc))
{
- if (mHostHAL)
- mHostHAL->setMemHypervisorStats(0 /* ulMemAllocTotal */, 0 /* ulMemFreeTotal */, 0 /* ulMemBalloonTotal */, 0 /* ulMemSharedTotal */);
+ mValid = true;
}
- Assert(mGuest && mConsole);
- mGuest->COMSETTER(StatisticsUpdateInterval)(0 /* off */);
+ 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));
}
+
return S_OK;
}
-int CollectorGuestHAL::preCollect(const CollectorHints& /* hints */, uint64_t iTick)
+void CollectorGuestManager::preCollect(CollectorHints& hints, uint64_t /* iTick */)
{
- if ( mGuest
- && iTick != mLastTick)
+ /*
+ * 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;
+
+ 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++)
{
- ULONG ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemSharedTotal;
+ 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();
+ }
+ }
+}
+
+void CollectorGuestManager::registerGuest(CollectorGuest* pGuest)
+{
+ mGuests.push_back(pGuest);
+ /*
+ * If no VMM stats provider was elected previously than this is our
+ * candidate.
+ */
+ if (!mVMMStatsProvider)
+ mVMMStatsProvider = pGuest;
+ LogAleksey(("{%p} " LOG_FN_FMT ": Registered guest=%p provider=%p\n",
+ this, __PRETTY_FUNCTION__, pGuest, mVMMStatsProvider));
+}
- mGuest->InternalGetStatistics(&mCpuUser, &mCpuKernel, &mCpuIdle,
- &mMemTotal, &mMemFree, &mMemBalloon, &mMemShared, &mMemCache,
- &mPageTotal, &ulMemAllocTotal, &ulMemFreeTotal, &ulMemBalloonTotal, &ulMemSharedTotal);
+void CollectorGuestManager::unregisterGuest(CollectorGuest* pGuest)
+{
+ LogAleksey(("{%p} " LOG_FN_FMT ": About to unregister guest=%p provider=%p\n",
+ this, __PRETTY_FUNCTION__, pGuest, mVMMStatsProvider));
+ //mGuests.remove(pGuest); => destroyUnregistered()
+ pGuest->unregister();
+ if (pGuest == mVMMStatsProvider)
+ {
+ /* This was our VMM stats provider, it is time to re-elect */
+ CollectorGuestList::iterator it;
+ /* Assume that nobody can provide VMM stats */
+ mVMMStatsProvider = NULL;
- if (mHostHAL)
- mHostHAL->setMemHypervisorStats(ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemSharedTotal);
+ for (it = mGuests.begin(); it != mGuests.end(); it++)
+ {
+ /* Skip unregistered as they are about to be destroyed */
+ if ((*it)->isUnregistered())
+ continue;
- mLastTick = iTick;
+ if ((*it)->isEnabled())
+ {
+ /* Found the guest already collecting stats, elect it */
+ mVMMStatsProvider = *it;
+ break;
+ }
+ else if (!mVMMStatsProvider)
+ {
+ /* If nobody collects stats, take the first registered */
+ mVMMStatsProvider = *it;
+ }
+ }
}
- return S_OK;
+ LogAleksey(("{%p} " LOG_FN_FMT ": LEAVE new provider=%p\n",
+ this, __PRETTY_FUNCTION__, mVMMStatsProvider));
+}
+
+void CollectorGuestManager::destroyUnregistered()
+{
+ CollectorGuestList::iterator it;
+
+ for (it = mGuests.begin(); it != mGuests.end();)
+ if ((*it)->isUnregistered())
+ {
+ delete *it;
+ it = mGuests.erase(it);
+ LogAleksey(("{%p} " LOG_FN_FMT ": Number of guests after erasing unregistered is %d\n",
+ this, __PRETTY_FUNCTION__, mGuests.size()));
+ }
+ else
+ ++it;
}
#endif /* !VBOX_COLLECTOR_TEST_CASE */
@@ -225,12 +322,6 @@ bool BaseMetric::collectorBeat(uint64_t nowAt)
return false;
}
-/*bool BaseMetric::associatedWith(ComPtr<IUnknown> object)
-{
- LogFlowThisFunc(("mObject(%p) == object(%p) is %s.\n", mObject, object, mObject == object ? "true" : "false"));
- return mObject == object;
-}*/
-
void HostCpuLoad::init(ULONG period, ULONG length)
{
mPeriod = period;
@@ -346,25 +437,40 @@ void HostRamVmm::init(ULONG period, ULONG length)
void HostRamVmm::preCollect(CollectorHints& hints, uint64_t /* iTick */)
{
- /*
- * This is an ugly ugly hack to force VMM metrics to 0s if no VM is
- * running. The reason it should work is that the VMM stats are
- * stored in CollectorHAL in preCollect methods of guest base metrics
- * which are always added after HostRamVmm. So each pass of collector
- * first clears the metrics then gets new values.
- */
- mHAL->setMemHypervisorStats(0 /* ulMemAllocTotal */, 0 /* ulMemFreeTotal */, 0 /* ulMemBalloonTotal */, 0 /* ulMemSharedTotal */);
+ hints.collectHostRamVmm();
}
void HostRamVmm::collect()
{
- ULONG allocVMM, freeVMM, balloonVMM, sharedVMM;
-
- mHAL->getMemHypervisorStats(&allocVMM, &freeVMM, &balloonVMM, &sharedVMM);
- mAllocVMM->put(allocVMM);
- mFreeVMM->put(freeVMM);
- mBalloonVMM->put(balloonVMM);
- mSharedVMM->put(sharedVMM);
+ CollectorGuest *provider = mCollectorGuestManager->getVMMStatsProvider();
+ if (provider)
+ {
+ 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 is ready, get updated stats */
+ mAllocCurrent = provider->getAllocVMM();
+ mFreeCurrent = provider->getFreeVMM();
+ mBalloonedCurrent = provider->getBalloonedVMM();
+ mSharedCurrent = provider->getSharedVMM();
+ }
+ }
+ else
+ {
+ mAllocCurrent = 0;
+ mFreeCurrent = 0;
+ mBalloonedCurrent = 0;
+ mSharedCurrent = 0;
+ }
+ LogAleksey(("{%p} " LOG_FN_FMT ": mAllocCurrent=%u mFreeCurrent=%u mBalloonedCurrent=%u mSharedCurrent=%u\n",
+ this, __PRETTY_FUNCTION__,
+ mAllocCurrent, mFreeCurrent, mBalloonedCurrent, mSharedCurrent));
+ mAllocVMM->put(mAllocCurrent);
+ mFreeVMM->put(mFreeCurrent);
+ mBalloonVMM->put(mBalloonedCurrent);
+ mSharedVMM->put(mSharedCurrent);
}
@@ -449,19 +555,19 @@ void GuestCpuLoad::init(ULONG period, ULONG length)
mIdle->init(mLength);
}
-void GuestCpuLoad::preCollect(CollectorHints& hints, uint64_t iTick)
+void GuestCpuLoad::preCollect(CollectorHints& hints, uint64_t /* iTick */)
{
- mHAL->preCollect(hints, iTick);
+ hints.collectGuestStats(mCGuest->getProcess());
}
void GuestCpuLoad::collect()
{
- ULONG CpuUser = 0, CpuKernel = 0, CpuIdle = 0;
-
- mGuestHAL->getGuestCpuLoad(&CpuUser, &CpuKernel, &CpuIdle);
- mUser->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * CpuUser) / 100);
- mKernel->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * CpuKernel) / 100);
- mIdle->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * CpuIdle) / 100);
+ if (mCGuest->isValid())
+ {
+ 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);
+ }
}
void GuestRamUsage::init(ULONG period, ULONG length)
@@ -477,22 +583,22 @@ void GuestRamUsage::init(ULONG period, ULONG length)
mPagedTotal->init(mLength);
}
-void GuestRamUsage::preCollect(CollectorHints& hints, uint64_t iTick)
+void GuestRamUsage::preCollect(CollectorHints& hints, uint64_t /* iTick */)
{
- mHAL->preCollect(hints, iTick);
+ hints.collectGuestStats(mCGuest->getProcess());
}
void GuestRamUsage::collect()
{
- ULONG ulMemTotal = 0, ulMemFree = 0, ulMemBalloon = 0, ulMemShared = 0, ulMemCache = 0, ulPageTotal = 0;
-
- mGuestHAL->getGuestMemLoad(&ulMemTotal, &ulMemFree, &ulMemBalloon, &ulMemShared, &ulMemCache, &ulPageTotal);
- mTotal->put(ulMemTotal);
- mFree->put(ulMemFree);
- mBallooned->put(ulMemBalloon);
- mShared->put(ulMemShared);
- mCache->put(ulMemCache);
- mPagedTotal->put(ulPageTotal);
+ if (mCGuest->isValid())
+ {
+ mTotal->put(mCGuest->getMemTotal());
+ mFree->put(mCGuest->getMemFree());
+ mBallooned->put(mCGuest->getMemBalloon());
+ mShared->put(mCGuest->getMemShared());
+ mCache->put(mCGuest->getMemCache());
+ mPagedTotal->put(mCGuest->getPageTotal());
+ }
}
void CircularBuffer::init(ULONG ulLength)
@@ -708,10 +814,10 @@ void Filter::processMetricList(const com::Utf8Str &name, const ComPtr<IUnknown>
pos != com::Utf8Str::npos;
pos = name.find(",", startPos))
{
- mElements.push_back(std::make_pair(object, iprt::MiniString(name.substr(startPos, pos - startPos).c_str())));
+ mElements.push_back(std::make_pair(object, RTCString(name.substr(startPos, pos - startPos).c_str())));
startPos = pos + 1;
}
- mElements.push_back(std::make_pair(object, iprt::MiniString(name.substr(startPos).c_str())));
+ mElements.push_back(std::make_pair(object, RTCString(name.substr(startPos).c_str())));
}
/**
@@ -787,14 +893,14 @@ bool Filter::patternMatch(const char *pszPat, const char *pszName,
return true;
}
-bool Filter::match(const ComPtr<IUnknown> object, const iprt::MiniString &name) const
+bool Filter::match(const ComPtr<IUnknown> object, const RTCString &name) const
{
ElementList::const_iterator it;
- LogAleksey(("Filter::match(%p, %s)\n", static_cast<const IUnknown*> (object), name.c_str()));
+ //LogAleksey(("Filter::match(%p, %s)\n", static_cast<const IUnknown*> (object), name.c_str()));
for (it = mElements.begin(); it != mElements.end(); it++)
{
- LogAleksey(("...matching against(%p, %s)\n", static_cast<const IUnknown*> ((*it).first), (*it).second.c_str()));
+ //LogAleksey(("...matching against(%p, %s)\n", static_cast<const IUnknown*> ((*it).first), (*it).second.c_str()));
if ((*it).first.isNull() || (*it).first == object)
{
// Objects match, compare names
@@ -805,7 +911,7 @@ bool Filter::match(const ComPtr<IUnknown> object, const iprt::MiniString &name)
}
}
}
- LogAleksey(("...no matches!\n"));
+ //LogAleksey(("...no matches!\n"));
return false;
}
/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/src-server/PerformanceImpl.cpp b/src/VBox/Main/src-server/PerformanceImpl.cpp
index 97610bb0f..c8c0a7ebe 100644
--- a/src/VBox/Main/src-server/PerformanceImpl.cpp
+++ b/src/VBox/Main/src-server/PerformanceImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: PerformanceImpl.cpp $ */
+/* $Id: PerformanceImpl.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
*
@@ -17,6 +17,20 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
+/*
+ * Rules of engagement:
+ * 1) All performance objects must be destroyed by PerformanceCollector only!
+ * 2) All public methods of PerformanceCollector must be protected with
+ * read or write lock.
+ * 3) samplerCallback only uses the write lock during the third phase
+ * which pulls data into SubMetric objects. This is where object destruction
+ * and all list modifications are done. The pre-collection phases are
+ * run without any locks which is only possible because:
+ * 4) Public methods of PerformanceCollector as well as pre-collection methods
+ cannot modify lists or destroy objects, and:
+ * 5) Pre-collection methods cannot modify metric data.
+ */
+
#include "PerformanceImpl.h"
#include "AutoCaller.h"
@@ -132,12 +146,13 @@ HRESULT PerformanceCollector::FinalConstruct()
{
LogFlowThisFunc(("\n"));
- return S_OK;
+ return BaseFinalConstruct();
}
void PerformanceCollector::FinalRelease()
{
LogFlowThisFunc(("\n"));
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
@@ -157,6 +172,7 @@ HRESULT PerformanceCollector::init()
HRESULT rc = S_OK;
m.hal = pm::createHAL();
+ m.gm = new pm::CollectorGuestManager;
/* Let the sampler know it gets a valid collector. */
mMagic = MAGIC;
@@ -197,6 +213,24 @@ void PerformanceCollector::uninit()
mMagic = 0;
+ /* Destroy unregistered metrics */
+ BaseMetricList::iterator it;
+ for (it = m.baseMetrics.begin(); it != m.baseMetrics.end();)
+ if ((*it)->isUnregistered())
+ {
+ delete *it;
+ it = m.baseMetrics.erase(it);
+ }
+ else
+ ++it;
+ Assert(m.baseMetrics.size() == 0);
+ /*
+ * Now when we have destroyed all base metrics that could
+ * try to pull data from unregistered CollectorGuest objects
+ * it is safe to destroy them as well.
+ */
+ m.gm->destroyUnregistered();
+
/* Destroy resource usage sampler */
int vrc = RTTimerLRDestroy (m.sampler);
AssertMsgRC (vrc, ("Failed to destroy resource usage "
@@ -206,6 +240,8 @@ void PerformanceCollector::uninit()
//delete m.factory;
//m.factory = NULL;
+ delete m.gm;
+ m.gm = NULL;
delete m.hal;
m.hal = NULL;
@@ -472,6 +508,7 @@ STDMETHODIMP PerformanceCollector::QueryMetricsData(ComSafeArrayIn (IN_BSTR, met
LogFlow (("PerformanceCollector::QueryMetricsData() querying metric %s "
"returned %d values.\n", (*it)->getName(), length));
memcpy(retData.raw() + flatIndex, values, length * sizeof(*values));
+ RTMemFree(values);
Bstr tmp((*it)->getName());
tmp.detachTo(&retNames[i]);
(*it)->getObject().queryInterfaceTo(&retObjects[i]);
@@ -529,17 +566,16 @@ void PerformanceCollector::unregisterBaseMetricsFor(const ComPtr<IUnknown> &aObj
if (!SUCCEEDED(autoCaller.rc())) return;
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- LogAleksey(("{%p} " LOG_FN_FMT ": before remove_if: m.baseMetrics.size()=%d\n", this, __PRETTY_FUNCTION__, m.baseMetrics.size()));
+ int n = 0;
BaseMetricList::iterator it;
- for (it = m.baseMetrics.begin(); it != m.baseMetrics.end();)
+ for (it = m.baseMetrics.begin(); it != m.baseMetrics.end(); ++it)
if ((*it)->associatedWith(aObject))
{
- delete *it;
- it = m.baseMetrics.erase(it);
+ (*it)->unregister();
+ ++n;
}
- else
- ++it;
- LogAleksey(("{%p} " LOG_FN_FMT ": after remove_if: m.baseMetrics.size()=%d\n", this, __PRETTY_FUNCTION__, m.baseMetrics.size()));
+ LogAleksey(("{%p} " LOG_FN_FMT ": obj=%p, marked %d metrics\n",
+ this, __PRETTY_FUNCTION__, (void *)aObject, n));
//LogFlowThisFuncLeave();
}
@@ -563,6 +599,24 @@ void PerformanceCollector::unregisterMetricsFor(const ComPtr<IUnknown> &aObject)
//LogFlowThisFuncLeave();
}
+void PerformanceCollector::registerGuest(pm::CollectorGuest* pGuest)
+{
+ AutoCaller autoCaller(this);
+ if (!SUCCEEDED(autoCaller.rc())) return;
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ m.gm->registerGuest(pGuest);
+}
+
+void PerformanceCollector::unregisterGuest(pm::CollectorGuest* pGuest)
+{
+ AutoCaller autoCaller(this);
+ if (!SUCCEEDED(autoCaller.rc())) return;
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ m.gm->unregisterGuest(pGuest);
+}
+
void PerformanceCollector::suspendSampling()
{
AutoCaller autoCaller(this);
@@ -598,10 +652,26 @@ void PerformanceCollector::staticSamplerCallback(RTTIMERLR hTimerLR, void *pvUse
NOREF (hTimerLR);
}
+/*
+ * Metrics collection is a three stage process:
+ * 1) Pre-collection (hinting)
+ * At this stage we compose the list of all metrics to be collected
+ * If any metrics cannot be collected separately or if it is more
+ * efficient to collect several metric at once, these metrics should
+ * use hints to mark that they will need to be collected.
+ * 2) Pre-collection (bulk)
+ * Using hints set at stage 1 platform-specific HAL
+ * instance collects all marked host-related metrics.
+ * Hinted guest-related metrics then get collected by CollectorGuestManager.
+ * 3) Collection
+ * Metrics that are collected individually get collected and stored. Values
+ * saved in HAL and CollectorGuestManager are extracted and stored to
+ * individual metrics.
+ */
void PerformanceCollector::samplerCallback(uint64_t iTick)
{
Log4(("{%p} " LOG_FN_FMT ": ENTER\n", this, __PRETTY_FUNCTION__));
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ /* No locking until stage 3!*/
pm::CollectorHints hints;
uint64_t timestamp = RTTimeMilliTS();
@@ -616,10 +686,41 @@ void PerformanceCollector::samplerCallback(uint64_t iTick)
}
if (toBeCollected.size() == 0)
+ {
+ Log4(("{%p} " LOG_FN_FMT ": LEAVE (nothing to collect)\n", this, __PRETTY_FUNCTION__));
return;
+ }
/* Let know the platform specific code what is being collected */
m.hal->preCollect(hints, iTick);
+ /* Collect the data in bulk from all hinted guests */
+ m.gm->preCollect(hints, iTick);
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ /*
+ * Before we can collect data we need to go through both lists
+ * again to see if any base metrics are marked as unregistered.
+ * Those should be destroyed now.
+ */
+ LogAleksey(("{%p} " LOG_FN_FMT ": before remove_if: toBeCollected.size()=%d\n", this, __PRETTY_FUNCTION__, toBeCollected.size()));
+ toBeCollected.remove_if(std::mem_fun(&pm::BaseMetric::isUnregistered));
+ LogAleksey(("{%p} " LOG_FN_FMT ": after remove_if: toBeCollected.size()=%d\n", this, __PRETTY_FUNCTION__, toBeCollected.size()));
+ LogAleksey(("{%p} " LOG_FN_FMT ": before remove_if: m.baseMetrics.size()=%d\n", this, __PRETTY_FUNCTION__, m.baseMetrics.size()));
+ for (it = m.baseMetrics.begin(); it != m.baseMetrics.end();)
+ if ((*it)->isUnregistered())
+ {
+ delete *it;
+ it = m.baseMetrics.erase(it);
+ }
+ else
+ ++it;
+ LogAleksey(("{%p} " LOG_FN_FMT ": after remove_if: m.baseMetrics.size()=%d\n", this, __PRETTY_FUNCTION__, m.baseMetrics.size()));
+ /*
+ * Now when we have destroyed all base metrics that could
+ * try to pull data from unregistered CollectorGuest objects
+ * it is safe to destroy them as well.
+ */
+ m.gm->destroyUnregistered();
/* Finally, collect the data */
std::for_each (toBeCollected.begin(), toBeCollected.end(),
@@ -646,7 +747,7 @@ HRESULT PerformanceMetric::FinalConstruct()
{
LogFlowThisFunc(("\n"));
- return S_OK;
+ return BaseFinalConstruct();
}
void PerformanceMetric::FinalRelease()
@@ -654,6 +755,8 @@ void PerformanceMetric::FinalRelease()
LogFlowThisFunc(("\n"));
uninit ();
+
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-server/ProgressProxyImpl.cpp b/src/VBox/Main/src-server/ProgressProxyImpl.cpp
index 4504da603..b4fa20462 100644
--- a/src/VBox/Main/src-server/ProgressProxyImpl.cpp
+++ b/src/VBox/Main/src-server/ProgressProxyImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: ProgressProxyImpl.cpp $ */
+/* $Id: ProgressProxyImpl.cpp 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* IProgress implementation for Machine::openRemoteSession in VBoxSVC.
*/
@@ -134,6 +134,8 @@ void ProgressProxy::FinalRelease()
muOtherProgressStartWeight = 0;
muOtherProgressWeight = 0;
muOtherProgressStartOperation = 0;
+
+ BaseFinalRelease();
}
void ProgressProxy::uninit()
diff --git a/src/VBox/Main/src-server/SerialPortImpl.cpp b/src/VBox/Main/src-server/SerialPortImpl.cpp
index f1d43ce92..81234c490 100644
--- a/src/VBox/Main/src-server/SerialPortImpl.cpp
+++ b/src/VBox/Main/src-server/SerialPortImpl.cpp
@@ -57,12 +57,13 @@ DEFINE_EMPTY_CTOR_DTOR (SerialPort)
HRESULT SerialPort::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void SerialPort::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-server/SnapshotImpl.cpp b/src/VBox/Main/src-server/SnapshotImpl.cpp
index 747641aa6..aa3520f51 100644
--- a/src/VBox/Main/src-server/SnapshotImpl.cpp
+++ b/src/VBox/Main/src-server/SnapshotImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: SnapshotImpl.cpp $ */
+/* $Id: SnapshotImpl.cpp 37985 2011-07-15 15:04:39Z vboxsync $ */
/** @file
*
@@ -44,30 +44,6 @@
////////////////////////////////////////////////////////////////////////////////
//
-// Globals
-//
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Progress callback handler for lengthy operations
- * (corresponds to the FNRTPROGRESS typedef).
- *
- * @param uPercentage Completion percentage (0-100).
- * @param pvUser Pointer to the Progress instance.
- */
-static DECLCALLBACK(int) progressCallback(unsigned uPercentage, void *pvUser)
-{
- IProgress *progress = static_cast<IProgress*>(pvUser);
-
- /* update the progress object */
- if (progress)
- progress->SetCurrentOperationProgress(uPercentage);
-
- return VINF_SUCCESS;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
// Snapshot private data definition
//
////////////////////////////////////////////////////////////////////////////////
@@ -108,13 +84,14 @@ struct Snapshot::Data
HRESULT Snapshot::FinalConstruct()
{
LogFlowThisFunc(("\n"));
- return S_OK;
+ return BaseFinalConstruct();
}
void Snapshot::FinalRelease()
{
LogFlowThisFunc(("\n"));
uninit();
+ BaseFinalRelease();
}
/**
@@ -348,6 +325,12 @@ STDMETHODIMP Snapshot::COMSETTER(Name)(IN_BSTR aName)
HRESULT rc = S_OK;
CheckComArgStrNotEmptyOrNull(aName);
+ // prohibit setting a UUID only as the machine name, or else it can
+ // never be found by findMachine()
+ Guid test(aName);
+ if (test.isNotEmpty())
+ return setError(E_INVALIDARG, tr("A machine cannot have a UUID as its name"));
+
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -420,7 +403,7 @@ STDMETHODIMP Snapshot::COMGETTER(Online)(BOOL *aOnline)
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- *aOnline = !stateFilePath().isEmpty();
+ *aOnline = getStateFilePath().isNotEmpty();
return S_OK;
}
@@ -466,6 +449,15 @@ STDMETHODIMP Snapshot::COMGETTER(Children)(ComSafeArrayOut(ISnapshot *, aChildre
return S_OK;
}
+STDMETHODIMP Snapshot::GetChildrenCount(ULONG* count)
+{
+ CheckComArgOutPointerValid(count);
+
+ *count = getChildrenCount();
+
+ return S_OK;
+}
+
////////////////////////////////////////////////////////////////////////////////
//
// Snapshot public internal methods
@@ -496,21 +488,9 @@ const ComObjPtr<Snapshot> Snapshot::getFirstChild() const
* @note
* Must be called from under the object's lock!
*/
-const Utf8Str& Snapshot::stateFilePath() const
+const Utf8Str& Snapshot::getStateFilePath() const
{
- return m->pMachine->mSSData->mStateFilePath;
-}
-
-/**
- * @note
- * Must be called from under the object's write lock!
- */
-HRESULT Snapshot::deleteStateFile()
-{
- int vrc = RTFileDelete(m->pMachine->mSSData->mStateFilePath.c_str());
- if (RT_SUCCESS(vrc))
- m->pMachine->mSSData->mStateFilePath.setNull();
- return RT_SUCCESS(vrc) ? S_OK : E_FAIL;
+ return m->pMachine->mSSData->strStateFilePath;
}
/**
@@ -680,7 +660,7 @@ void Snapshot::updateSavedStatePathsImpl(const Utf8Str &strOldPath,
{
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- const Utf8Str &path = m->pMachine->mSSData->mStateFilePath;
+ const Utf8Str &path = m->pMachine->mSSData->strStateFilePath;
LogFlowThisFunc(("Snap[%s].statePath={%s}\n", m->strName.c_str(), path.c_str()));
/* state file may be NULL (for offline snapshots) */
@@ -688,9 +668,9 @@ void Snapshot::updateSavedStatePathsImpl(const Utf8Str &strOldPath,
&& RTPathStartsWith(path.c_str(), strOldPath.c_str())
)
{
- m->pMachine->mSSData->mStateFilePath = Utf8StrFmt("%s%s",
- strNewPath.c_str(),
- path.c_str() + strOldPath.length());
+ m->pMachine->mSSData->strStateFilePath = Utf8StrFmt("%s%s",
+ strNewPath.c_str(),
+ path.c_str() + strOldPath.length());
LogFlowThisFunc(("-> updated: {%s}\n", path.c_str()));
}
@@ -704,6 +684,44 @@ void Snapshot::updateSavedStatePathsImpl(const Utf8Str &strOldPath,
}
/**
+ * Returns true if this snapshot or one of its children uses the given file,
+ * whose path must be fully qualified, as its saved state. When invoked on a
+ * machine's first snapshot, this can be used to check if a saved state file
+ * is shared with any snapshots.
+ *
+ * Caller must hold the machine lock, which protects the snapshots tree.
+ *
+ * @param strPath
+ * @param pSnapshotToIgnore If != NULL, this snapshot is ignored during the checks.
+ * @return
+ */
+bool Snapshot::sharesSavedStateFile(const Utf8Str &strPath,
+ Snapshot *pSnapshotToIgnore)
+{
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ const Utf8Str &path = m->pMachine->mSSData->strStateFilePath;
+
+ if (!pSnapshotToIgnore || pSnapshotToIgnore != this)
+ if (path.isNotEmpty())
+ if (path == strPath)
+ return true; // no need to recurse then
+
+ // but otherwise we must check children
+ for (SnapshotsList::const_iterator it = m->llChildren.begin();
+ it != m->llChildren.end();
+ ++it)
+ {
+ Snapshot *pChild = *it;
+ if (!pSnapshotToIgnore || pSnapshotToIgnore != pChild)
+ if (pChild->sharesSavedStateFile(strPath, pSnapshotToIgnore))
+ return true;
+ }
+
+ return false;
+}
+
+
+/**
* Checks if the specified path change affects the saved state file path of
* this snapshot or any of its (grand-)children and updates it accordingly.
*
@@ -749,9 +767,9 @@ HRESULT Snapshot::saveSnapshotImpl(settings::Snapshot &data, bool aAttrsOnly)
if (aAttrsOnly)
return S_OK;
- /* stateFile (optional) */
- if (!stateFilePath().isEmpty())
- m->pMachine->copyPathRelativeToMachine(stateFilePath(), data.strStateFile);
+ // state file (only if this snapshot is online)
+ if (getStateFilePath().isNotEmpty())
+ m->pMachine->copyPathRelativeToMachine(getStateFilePath(), data.strStateFile);
else
data.strStateFile.setNull();
@@ -862,9 +880,24 @@ HRESULT Snapshot::uninitRecursively(AutoWriteLock &writeLock,
if (FAILED(rc))
return rc;
- // now report the saved state file
- if (!m->pMachine->mSSData->mStateFilePath.isEmpty())
- llFilenames.push_back(m->pMachine->mSSData->mStateFilePath);
+ // report the saved state file if it's not on the list yet
+ if (!m->pMachine->mSSData->strStateFilePath.isEmpty())
+ {
+ bool fFound = false;
+ for (std::list<Utf8Str>::const_iterator it = llFilenames.begin();
+ it != llFilenames.end();
+ ++it)
+ {
+ const Utf8Str &str = *it;
+ if (str == m->pMachine->mSSData->strStateFilePath)
+ {
+ fFound = true;
+ break;
+ }
+ }
+ if (!fFound)
+ llFilenames.push_back(m->pMachine->mSSData->strStateFilePath);
+ }
this->beginSnapshotDelete();
this->uninit();
@@ -888,7 +921,7 @@ HRESULT SnapshotMachine::FinalConstruct()
{
LogFlowThisFunc(("\n"));
- return S_OK;
+ return BaseFinalConstruct();
}
void SnapshotMachine::FinalRelease()
@@ -896,6 +929,8 @@ void SnapshotMachine::FinalRelease()
LogFlowThisFunc(("\n"));
uninit();
+
+ BaseFinalRelease();
}
/**
@@ -942,7 +977,7 @@ HRESULT SnapshotMachine::init(SessionMachine *aSessionMachine,
/* SSData is always unique for SnapshotMachine */
mSSData.allocate();
- mSSData->mStateFilePath = aStateFilePath;
+ mSSData->strStateFilePath = aStateFilePath;
HRESULT rc = S_OK;
@@ -1080,7 +1115,7 @@ HRESULT SnapshotMachine::init(Machine *aMachine,
/* SSData is always unique for SnapshotMachine */
mSSData.allocate();
- mSSData->mStateFilePath = aStateFilePath;
+ mSSData->strStateFilePath = aStateFilePath;
/* create all other child objects that will be immutable private copies */
@@ -1252,18 +1287,14 @@ struct SessionMachine::RestoreSnapshotTask
{
RestoreSnapshotTask(SessionMachine *m,
Progress *p,
- Snapshot *s,
- ULONG ulStateFileSizeMB)
- : SnapshotTask(m, p, s),
- m_ulStateFileSizeMB(ulStateFileSizeMB)
+ Snapshot *s)
+ : SnapshotTask(m, p, s)
{}
void handler()
{
pMachine->restoreSnapshotHandler(*this);
}
-
- ULONG m_ulStateFileSizeMB;
};
/** Delete snapshot task */
@@ -1389,16 +1420,16 @@ STDMETHODIMP SessionMachine::BeginTakingSnapshot(IConsole *aInitiator,
Utf8Str strStateFilePath;
/* stateFilePath is null when the machine is not online nor saved */
- if ( fTakingSnapshotOnline
- || mData->mMachineState == MachineState_Saved)
- {
- Utf8Str strFullSnapshotFolder;
- calculateFullPath(mUserData->s.strSnapshotFolder, strFullSnapshotFolder);
- strStateFilePath = Utf8StrFmt("%s%c{%RTuuid}.sav",
- strFullSnapshotFolder.c_str(),
- RTPATH_DELIMITER,
- snapshotId.raw());
- /* ensure the directory for the saved state file exists */
+ if (fTakingSnapshotOnline)
+ // creating a new online snapshot: then we need a fresh saved state file
+ composeSavedStateFilename(strStateFilePath);
+ else if (mData->mMachineState == MachineState_Saved)
+ // taking an online snapshot from machine in "saved" state: then use existing state file
+ strStateFilePath = mSSData->strStateFilePath;
+
+ if (strStateFilePath.isNotEmpty())
+ {
+ // ensure the directory for the saved state file exists
HRESULT rc = VirtualBox::ensureFilePathExists(strStateFilePath);
if (FAILED(rc)) return rc;
}
@@ -1454,38 +1485,6 @@ STDMETHODIMP SessionMachine::BeginTakingSnapshot(IConsole *aInitiator,
if (FAILED(rc))
throw rc;
- if (mConsoleTaskData.mLastState == MachineState_Saved)
- {
- Utf8Str stateFrom = mSSData->mStateFilePath;
- Utf8Str stateTo = mConsoleTaskData.mSnapshot->stateFilePath();
-
- LogFlowThisFunc(("Copying the execution state from '%s' to '%s'...\n",
- stateFrom.c_str(), stateTo.c_str()));
-
- aConsoleProgress->SetNextOperation(Bstr(tr("Copying the execution state")).raw(),
- 1); // weight
-
- /* Leave the lock before a lengthy operation (machine is protected
- * by "Saving" machine state now) */
- alock.release();
-
- /* copy the state file */
- int vrc = RTFileCopyEx(stateFrom.c_str(),
- stateTo.c_str(),
- 0,
- progressCallback,
- aConsoleProgress);
- alock.acquire();
-
- if (RT_FAILURE(vrc))
- /** @todo r=bird: Delete stateTo when appropriate. */
- throw setError(E_FAIL,
- tr("Could not copy the state file '%s' to '%s' (%Rrc)"),
- stateFrom.c_str(),
- stateTo.c_str(),
- vrc);
- }
-
// if we got this far without an error, then save the media registries
// that got modified for the diff images
alock.release();
@@ -1586,8 +1585,6 @@ STDMETHODIMP SessionMachine::EndTakingSnapshot(BOOL aSuccess)
flSaveSettings |= SaveS_ResetCurStateModified;
rc = saveSettings(NULL, flSaveSettings);
- // no need to change for whether VirtualBox.xml needs saving since
- // we'll save the global settings below anyway
}
if (aSuccess && SUCCEEDED(rc))
@@ -1608,9 +1605,12 @@ STDMETHODIMP SessionMachine::EndTakingSnapshot(BOOL aSuccess)
mData->mFirstSnapshot = pOldFirstSnap; // might have been changed above
mData->mCurrentSnapshot = pOldCurrentSnap; // might have been changed above
- /* delete the saved state file (it might have been already created) */
- if (mConsoleTaskData.mSnapshot->stateFilePath().length())
- RTFileDelete(mConsoleTaskData.mSnapshot->stateFilePath().c_str());
+ // delete the saved state file (it might have been already created)
+ if (fOnline)
+ // no need to test for whether the saved state file is shared: an online
+ // snapshot means that a new saved state file was created, which we must
+ // clean up now
+ RTFileDelete(mConsoleTaskData.mSnapshot->getStateFilePath().c_str());
mConsoleTaskData.mSnapshot->uninit();
}
@@ -1619,12 +1619,6 @@ STDMETHODIMP SessionMachine::EndTakingSnapshot(BOOL aSuccess)
mConsoleTaskData.mLastState = MachineState_Null;
mConsoleTaskData.mSnapshot.setNull();
- // save VirtualBox.xml (media registry most probably changed with diff image);
- // for that we should hold only the VirtualBox lock
- machineLock.release();
- AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
- mParent->saveSettings();
-
return rc;
}
@@ -1698,26 +1692,6 @@ STDMETHODIMP SessionMachine::RestoreSnapshot(IConsole *aInitiator,
}
}
- ULONG ulStateFileSizeMB = 0;
- if (pSnapshot->stateFilePath().length())
- {
- ++ulOpCount; // one for the saved state
-
- uint64_t ullSize;
- int irc = RTFileQuerySize(pSnapshot->stateFilePath().c_str(), &ullSize);
- if (!RT_SUCCESS(irc))
- // if we can't access the file here, then we'll be doomed later also, so fail right away
- setError(E_FAIL, tr("Cannot access state file '%s', runtime error, %Rra"), pSnapshot->stateFilePath().c_str(), irc);
- if (ullSize == 0) // avoid division by zero
- ullSize = _1M;
-
- ulStateFileSizeMB = (ULONG)(ullSize / _1M);
- LogFlowThisFunc(("op %d: saved state file '%s' has %RI64 bytes (%d MB)\n",
- ulOpCount, pSnapshot->stateFilePath().c_str(), ullSize, ulStateFileSizeMB));
-
- ulTotalWeight += ulStateFileSizeMB;
- }
-
ComObjPtr<Progress> pProgress;
pProgress.createObject();
pProgress->init(mParent, aInitiator,
@@ -1732,8 +1706,7 @@ STDMETHODIMP SessionMachine::RestoreSnapshot(IConsole *aInitiator,
* start working until we release alock) */
RestoreSnapshotTask *task = new RestoreSnapshotTask(this,
pProgress,
- pSnapshot,
- ulStateFileSizeMB);
+ pSnapshot);
int vrc = RTThreadCreate(NULL,
taskHandler,
(void*)task,
@@ -1812,10 +1785,16 @@ void SessionMachine::restoreSnapshotHandler(RestoreSnapshotTask &aTask)
* operation */
if (aTask.machineStateBackup == MachineState_Saved)
{
- Assert(!mSSData->mStateFilePath.isEmpty());
- RTFileDelete(mSSData->mStateFilePath.c_str());
- mSSData->mStateFilePath.setNull();
+ Assert(!mSSData->strStateFilePath.isEmpty());
+
+ // release the saved state file AFTER unsetting the member variable
+ // so that releaseSavedStateFile() won't think it's still in use
+ Utf8Str strStateFile(mSSData->strStateFilePath);
+ mSSData->strStateFilePath.setNull();
+ releaseSavedStateFile(strStateFile, NULL /* pSnapshotToIgnore */ );
+
aTask.modifyBackedUpState(MachineState_PoweredOff);
+
rc = saveStateSettings(SaveSTS_StateFilePath);
if (FAILED(rc))
throw rc;
@@ -1862,49 +1841,13 @@ void SessionMachine::restoreSnapshotHandler(RestoreSnapshotTask &aTask)
* deleted by #rollback() at the end. */
/* should not have a saved state file associated at this point */
- Assert(mSSData->mStateFilePath.isEmpty());
+ Assert(mSSData->strStateFilePath.isEmpty());
- if (!aTask.pSnapshot->stateFilePath().isEmpty())
- {
- Utf8Str snapStateFilePath = aTask.pSnapshot->stateFilePath();
-
- Utf8Str strFullSnapshotFolder;
- calculateFullPath(mUserData->s.strSnapshotFolder, strFullSnapshotFolder);
- Utf8Str stateFilePath = Utf8StrFmt("%s%c{%RTuuid}.sav",
- strFullSnapshotFolder.c_str(),
- RTPATH_DELIMITER,
- mData->mUuid.raw());
-
- LogFlowThisFunc(("Copying saved state file from '%s' to '%s'...\n",
- snapStateFilePath.c_str(), stateFilePath.c_str()));
-
- aTask.pProgress->SetNextOperation(Bstr(tr("Restoring the execution state")).raw(),
- aTask.m_ulStateFileSizeMB); // weight
-
- /* leave the lock before the potentially lengthy operation */
- snapshotLock.release();
- alock.leave();
-
- /* copy the state file */
- RTFileDelete(stateFilePath.c_str());
- int vrc = RTFileCopyEx(snapStateFilePath.c_str(),
- stateFilePath.c_str(),
- 0,
- progressCallback,
- static_cast<IProgress*>(aTask.pProgress));
-
- alock.enter();
- snapshotLock.acquire();
-
- if (RT_SUCCESS(vrc))
- mSSData->mStateFilePath = stateFilePath;
- else
- throw setError(E_FAIL,
- tr("Could not copy the state file '%s' to '%s' (%Rrc)"),
- snapStateFilePath.c_str(),
- stateFilePath.c_str(),
- vrc);
- }
+ const Utf8Str &strSnapshotStateFile = aTask.pSnapshot->getStateFilePath();
+
+ if (strSnapshotStateFile.isNotEmpty())
+ // online snapshot: then share the state file
+ mSSData->strStateFilePath = strSnapshotStateFile;
LogFlowThisFunc(("Setting new current snapshot {%RTuuid}\n", aTask.pSnapshot->getId().raw()));
/* make the snapshot we restored from the current snapshot */
@@ -1940,7 +1883,7 @@ void SessionMachine::restoreSnapshotHandler(RestoreSnapshotTask &aTask)
/* we have already deleted the current state, so set the execution
* state accordingly no matter of the delete snapshot result */
- if (!mSSData->mStateFilePath.isEmpty())
+ if (mSSData->strStateFilePath.isNotEmpty())
setMachineState(MachineState_Saved);
else
setMachineState(MachineState_PoweredOff);
@@ -1992,7 +1935,7 @@ void SessionMachine::restoreSnapshotHandler(RestoreSnapshotTask &aTask)
throw rc;
// unconditionally add the parent registry. We do similar in SessionMachine::EndTakingSnapshot
// (mParent->saveSettings())
- mParent->addGuidToListUniquely(llRegistriesThatNeedSaving, mParent->getGlobalRegistryId());
+ VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, mParent->getGlobalRegistryId());
// let go of the locks while we're deleting image files below
alock.leave();
@@ -2070,16 +2013,23 @@ void SessionMachine::restoreSnapshotHandler(RestoreSnapshotTask &aTask)
* @note Locks mParent + this + children objects for writing!
*/
STDMETHODIMP SessionMachine::DeleteSnapshot(IConsole *aInitiator,
- IN_BSTR aId,
+ IN_BSTR aStartId,
+ IN_BSTR aEndId,
+ BOOL fDeleteAllChildren,
MachineState_T *aMachineState,
IProgress **aProgress)
{
LogFlowThisFuncEnter();
- Guid id(aId);
- AssertReturn(aInitiator && !id.isEmpty(), E_INVALIDARG);
+ Guid startId(aStartId);
+ Guid endId(aEndId);
+ AssertReturn(aInitiator && !startId.isEmpty() && !endId.isEmpty(), E_INVALIDARG);
AssertReturn(aMachineState && aProgress, E_POINTER);
+ /** @todo implement the "and all children" and "range" variants */
+ if (fDeleteAllChildren || startId != endId)
+ ReturnComNotImplemented();
+
AutoCaller autoCaller(this);
AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
@@ -2098,7 +2048,7 @@ STDMETHODIMP SessionMachine::DeleteSnapshot(IConsole *aInitiator,
Global::stringifyMachineState(mData->mMachineState));
ComObjPtr<Snapshot> pSnapshot;
- HRESULT rc = findSnapshotById(id, pSnapshot, true /* aSetError */);
+ HRESULT rc = findSnapshotById(startId, pSnapshot, true /* aSetError */);
if (FAILED(rc)) return rc;
AutoWriteLock snapshotLock(pSnapshot COMMA_LOCKVAL_SRC_POS);
@@ -2135,7 +2085,7 @@ STDMETHODIMP SessionMachine::DeleteSnapshot(IConsole *aInitiator,
ULONG ulOpCount = 1; // one for preparations
ULONG ulTotalWeight = 1; // one for preparations
- if (pSnapshot->stateFilePath().length())
+ if (pSnapshot->getStateFilePath().length())
{
++ulOpCount;
++ulTotalWeight; // assume 1 MB for deleting the state file
@@ -2420,12 +2370,6 @@ void SessionMachine::deleteSnapshotHandler(DeleteSnapshotTask &aTask)
}
else
fOnlineMergePossible = false;
-/// @todo remove this once the fix for windows/64bit API crashes for
-// SafeIfaceArray has been backported
-#if defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)
- if (fOnlineMergePossible)
- throw setError(E_NOTIMPL, tr("Live snapshot deletion on Windows/x64 is disabled to prevent a crash (will be fixed in the next release)"));
-#endif
}
rc = prepareDeleteSnapshotMedium(pHD, machineId, snapshotId,
fOnlineMergePossible,
@@ -2526,15 +2470,16 @@ void SessionMachine::deleteSnapshotHandler(DeleteSnapshotTask &aTask)
// tree is protected by the machine lock as well
AutoWriteLock machineLock(this COMMA_LOCKVAL_SRC_POS);
- Utf8Str stateFilePath = aTask.pSnapshot->stateFilePath();
+ Utf8Str stateFilePath = aTask.pSnapshot->getStateFilePath();
if (!stateFilePath.isEmpty())
{
aTask.pProgress->SetNextOperation(Bstr(tr("Deleting the execution state")).raw(),
1); // weight
- aTask.pSnapshot->deleteStateFile();
- // machine needs saving now
- mParent->addGuidToListUniquely(llRegistriesThatNeedSaving, getId());
+ releaseSavedStateFile(stateFilePath, aTask.pSnapshot /* pSnapshotToIgnore */);
+
+ // machine will need saving now
+ VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, getId());
}
}
@@ -2709,7 +2654,7 @@ void SessionMachine::deleteSnapshotHandler(DeleteSnapshotTask &aTask)
it->mpSource->uninit();
// One attachment is merged, must save the settings
- mParent->addGuidToListUniquely(llRegistriesThatNeedSaving, getId());
+ VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, getId());
// prevent calling cancelDeleteSnapshotMedium() for this attachment
it = toDelete.erase(it);
@@ -2728,7 +2673,7 @@ void SessionMachine::deleteSnapshotHandler(DeleteSnapshotTask &aTask)
aTask.pSnapshot->beginSnapshotDelete();
aTask.pSnapshot->uninit();
- mParent->addGuidToListUniquely(llRegistriesThatNeedSaving, getId());
+ VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, getId());
}
}
catch (HRESULT aRC) { rc = aRC; }
diff --git a/src/VBox/Main/src-server/StorageControllerImpl.cpp b/src/VBox/Main/src-server/StorageControllerImpl.cpp
index 81387fc44..b51387fca 100644
--- a/src/VBox/Main/src-server/StorageControllerImpl.cpp
+++ b/src/VBox/Main/src-server/StorageControllerImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: StorageControllerImpl.cpp $ */
+/* $Id: StorageControllerImpl.cpp 37926 2011-07-13 15:36:59Z vboxsync $ */
/** @file
*
@@ -104,12 +104,13 @@ struct StorageController::Data
HRESULT StorageController::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void StorageController::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
@@ -474,7 +475,7 @@ STDMETHODIMP StorageController::COMSETTER(PortCount) (ULONG aPortCount)
case StorageBus_SATA:
{
/* AHCI SATA supports a maximum of 30 ports. */
- if ((aPortCount < 1) || (aPortCount > 30))
+ if (aPortCount < 1 || aPortCount > 30)
return setError(E_INVALIDARG,
tr("Invalid port count: %lu (must be in range [%lu, %lu])"),
aPortCount, 1, 30);
@@ -690,9 +691,9 @@ STDMETHODIMP StorageController::SetIDEEmulationPort(LONG DevicePosition, LONG aP
return setError(E_NOTIMPL,
tr("Invalid controller type"));
- if ((aPortNumber < 0) || (aPortNumber >= 30))
+ if (aPortNumber < 0 || aPortNumber >= 30)
return setError(E_INVALIDARG,
- tr("Invalid port number: %l (must be in range [%lu, %lu])"),
+ tr("Invalid port number: %ld (must be in range [%lu, %lu])"),
aPortNumber, 0, 29);
switch (DevicePosition)
@@ -762,15 +763,14 @@ HRESULT StorageController::checkPortAndDeviceValid(LONG aControllerPort,
HRESULT rc = m->pSystemProperties->GetMaxDevicesPerPortForStorageBus(m->bd->mStorageBus, &devicesPerPort);
if (FAILED(rc)) return rc;
- if ( (aControllerPort < 0)
- || (aControllerPort >= (LONG)portCount)
- || (aDevice < 0)
- || (aDevice >= (LONG)devicesPerPort)
+ if ( aControllerPort < 0
+ || aControllerPort >= (LONG)portCount
+ || aDevice < 0
+ || aDevice >= (LONG)devicesPerPort
)
return setError(E_INVALIDARG,
- tr("The port and/or count parameter are out of range [%lu:%lu]"),
- portCount,
- devicesPerPort);
+ tr("The port and/or device parameter are out of range: port=%d (must be in range [0, %d]), device=%d (must be in range [0, %d])"),
+ (int)aControllerPort, (int)portCount-1, (int)aDevice, (int)devicesPerPort-1);
return S_OK;
}
diff --git a/src/VBox/Main/src-server/SystemPropertiesImpl.cpp b/src/VBox/Main/src-server/SystemPropertiesImpl.cpp
index 1dbd8ed83..813bbd53d 100644
--- a/src/VBox/Main/src-server/SystemPropertiesImpl.cpp
+++ b/src/VBox/Main/src-server/SystemPropertiesImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: SystemPropertiesImpl.cpp $ */
+/* $Id: SystemPropertiesImpl.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
*
@@ -61,12 +61,13 @@ SystemProperties::~SystemProperties()
HRESULT SystemProperties::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void SystemProperties::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public methods only for internal purposes
@@ -273,7 +274,7 @@ STDMETHODIMP SystemProperties::COMGETTER(InfoVDSize)(LONG64 *infoVDSize)
return S_OK;
}
-STDMETHODIMP SystemProperties::COMGETTER(NetworkAdapterCount)(ULONG *count)
+STDMETHODIMP SystemProperties::COMGETTER(SerialPortCount)(ULONG *count)
{
CheckComArgOutPointerValid(count);
@@ -281,12 +282,12 @@ STDMETHODIMP SystemProperties::COMGETTER(NetworkAdapterCount)(ULONG *count)
if (FAILED(autoCaller.rc())) return autoCaller.rc();
/* no need to lock, this is const */
- *count = SchemaDefs::NetworkAdapterCount;
+ *count = SchemaDefs::SerialPortCount;
return S_OK;
}
-STDMETHODIMP SystemProperties::COMGETTER(SerialPortCount)(ULONG *count)
+STDMETHODIMP SystemProperties::COMGETTER(ParallelPortCount)(ULONG *count)
{
CheckComArgOutPointerValid(count);
@@ -294,37 +295,87 @@ STDMETHODIMP SystemProperties::COMGETTER(SerialPortCount)(ULONG *count)
if (FAILED(autoCaller.rc())) return autoCaller.rc();
/* no need to lock, this is const */
- *count = SchemaDefs::SerialPortCount;
+ *count = SchemaDefs::ParallelPortCount;
return S_OK;
}
-STDMETHODIMP SystemProperties::COMGETTER(ParallelPortCount)(ULONG *count)
+STDMETHODIMP SystemProperties::COMGETTER(MaxBootPosition)(ULONG *aMaxBootPosition)
{
- CheckComArgOutPointerValid(count);
+ CheckComArgOutPointerValid(aMaxBootPosition);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
/* no need to lock, this is const */
- *count = SchemaDefs::ParallelPortCount;
+ *aMaxBootPosition = SchemaDefs::MaxBootPosition;
return S_OK;
}
-STDMETHODIMP SystemProperties::COMGETTER(MaxBootPosition)(ULONG *aMaxBootPosition)
+
+STDMETHODIMP SystemProperties::GetMaxNetworkAdapters(ChipsetType_T aChipset, ULONG *count)
{
- CheckComArgOutPointerValid(aMaxBootPosition);
+ CheckComArgOutPointerValid(count);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
- /* no need to lock, this is const */
- *aMaxBootPosition = SchemaDefs::MaxBootPosition;
+ ULONG uResult = 0;
+
+ /* no need for locking, no state */
+ switch (aChipset)
+ {
+ case ChipsetType_PIIX3:
+ uResult = SchemaDefs::NetworkAdapterCount; /* == 8 */
+ break;
+ case ChipsetType_ICH9:
+ uResult = 36;
+ break;
+ default:
+ AssertMsgFailed(("Invalid chipset type %d\n", aChipset));
+ }
+
+ *count = uResult;
return S_OK;
}
+STDMETHODIMP SystemProperties::GetMaxNetworkAdaptersOfType(ChipsetType_T aChipset, NetworkAttachmentType_T aType, ULONG *count)
+{
+ CheckComArgOutPointerValid(count);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ ULONG uResult = 0;
+ HRESULT rc = GetMaxNetworkAdapters(aChipset, &uResult);
+ if (FAILED(rc))
+ return rc;
+
+ /* no need for locking, no state */
+ switch (aType)
+ {
+ case NetworkAttachmentType_NAT:
+ case NetworkAttachmentType_Internal:
+ /* chipset default is OK */
+ break;
+ case NetworkAttachmentType_Bridged:
+ /* Maybe use current host interface count here? */
+ break;
+ case NetworkAttachmentType_HostOnly:
+ uResult = 8;
+ break;
+ default:
+ AssertMsgFailed(("Unhandled attachment type %d\n", aType));
+ }
+
+ *count = uResult;
+
+ return S_OK;
+}
+
+
STDMETHODIMP SystemProperties::GetMaxDevicesPerPortForStorageBus(StorageBus_T aBus,
ULONG *aMaxDevicesPerPort)
{
@@ -1084,4 +1135,3 @@ HRESULT SystemProperties::setDefaultVRDEExtPack(const Utf8Str &aExtPack)
return S_OK;
}
-
diff --git a/src/VBox/Main/src-server/USBControllerImpl.cpp b/src/VBox/Main/src-server/USBControllerImpl.cpp
index fafb753eb..fe63e7342 100644
--- a/src/VBox/Main/src-server/USBControllerImpl.cpp
+++ b/src/VBox/Main/src-server/USBControllerImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBControllerImpl.cpp $ */
+/* $Id: USBControllerImpl.cpp 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* Implementation of IUSBController.
*/
@@ -89,12 +89,13 @@ DEFINE_EMPTY_CTOR_DTOR (USBController)
HRESULT USBController::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void USBController::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-server/USBDeviceFilterImpl.cpp b/src/VBox/Main/src-server/USBDeviceFilterImpl.cpp
index 1fa570958..3ad591a0e 100644
--- a/src/VBox/Main/src-server/USBDeviceFilterImpl.cpp
+++ b/src/VBox/Main/src-server/USBDeviceFilterImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBDeviceFilterImpl.cpp $ */
+/* $Id: USBDeviceFilterImpl.cpp 35638 2011-01-19 19:10:49Z vboxsync $ */
/** @file
* Implementation of VirtualBox COM components: USBDeviceFilter and HostUSBDeviceFilter
*/
@@ -186,12 +186,13 @@ USBDeviceFilter::~USBDeviceFilter()
HRESULT USBDeviceFilter::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void USBDeviceFilter::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
diff --git a/src/VBox/Main/src-server/USBProxyService.cpp b/src/VBox/Main/src-server/USBProxyService.cpp
index d6cbefe62..8b76aed9e 100644
--- a/src/VBox/Main/src-server/USBProxyService.cpp
+++ b/src/VBox/Main/src-server/USBProxyService.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyService.cpp $ */
+/* $Id: USBProxyService.cpp 37599 2011-06-22 21:06:38Z vboxsync $ */
/** @file
* VirtualBox USB Proxy Service (base) class.
*/
@@ -44,11 +44,7 @@ USBProxyService::USBProxyService(Host *aHost)
/**
- * Initialize the object.
- *
- * Child classes should override and call this method
- *
- * @returns S_OK on success, or COM error status on fatal error.
+ * Stub needed as long as the class isn't virtual
*/
HRESULT USBProxyService::init(void)
{
diff --git a/src/VBox/Main/src-server/VFSExplorerImpl.cpp b/src/VBox/Main/src-server/VFSExplorerImpl.cpp
index dda5c6e99..3956b57af 100644
--- a/src/VBox/Main/src-server/VFSExplorerImpl.cpp
+++ b/src/VBox/Main/src-server/VFSExplorerImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: VFSExplorerImpl.cpp $ */
+/* $Id: VFSExplorerImpl.cpp 37678 2011-06-29 08:24:09Z vboxsync $ */
/** @file
*
* IVFSExplorer COM class implementations.
@@ -249,7 +249,7 @@ DECLCALLBACK(int) VFSExplorer::TaskVFSExplorer::taskThread(RTTHREAD /* aThread *
break;
}
- LogFlowFunc(("rc=%Rhrc\n", rc));
+ LogFlowFunc(("rc=%Rhrc\n", rc)); NOREF(rc);
LogFlowFuncLeave();
return VINF_SUCCESS;
diff --git a/src/VBox/Main/src-server/VRDEServerImpl.cpp b/src/VBox/Main/src-server/VRDEServerImpl.cpp
index f9645e788..a8c64be2b 100644
--- a/src/VBox/Main/src-server/VRDEServerImpl.cpp
+++ b/src/VBox/Main/src-server/VRDEServerImpl.cpp
@@ -55,12 +55,13 @@ VRDEServer::~VRDEServer()
HRESULT VRDEServer::FinalConstruct()
{
- return S_OK;
+ return BaseFinalConstruct();
}
void VRDEServer::FinalRelease()
{
uninit();
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
@@ -474,10 +475,8 @@ STDMETHODIMP VRDEServer::GetVRDEProperty (IN_BSTR aKey, BSTR *aValue)
Utf8Str strKey(key);
settings::StringsMap::const_iterator it = mData->mProperties.find(strKey);
if (it != mData->mProperties.end())
- {
value = it->second; // source is a Utf8Str
- value.cloneTo(aValue);
- }
+ value.cloneTo(aValue);
return S_OK;
}
diff --git a/src/VBox/Main/src-server/VirtualBoxImpl.cpp b/src/VBox/Main/src-server/VirtualBoxImpl.cpp
index 94376c27a..2770f5205 100644
--- a/src/VBox/Main/src-server/VirtualBoxImpl.cpp
+++ b/src/VBox/Main/src-server/VirtualBoxImpl.cpp
@@ -1,11 +1,11 @@
-/* $Id: VirtualBoxImpl.cpp $ */
+/* $Id: VirtualBoxImpl.cpp 37985 2011-07-15 15:04:39Z vboxsync $ */
/** @file
* Implementation of IVirtualBox in VBoxSVC.
*/
/*
- * 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;
@@ -103,49 +103,8 @@ ULONG VirtualBox::sRevision;
// static
Bstr VirtualBox::sPackageType;
-////////////////////////////////////////////////////////////////////////////////
-//
-// VirtualBoxCallbackRegistration
-//
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Registered IVirtualBoxCallback, used by VirtualBox::CallbackList and
- * VirtualBox::Data::llCallbacks.
- *
- * In addition to keeping the interface pointer this also keeps track of the
- * methods that asked to not be called again. The latter is for reducing
- * unnecessary IPC.
- */
-class VirtualBoxCallbackRegistration
-{
-public:
- /** Callback bit indexes (for bmDisabled). */
- typedef enum
- {
- kOnMachineStateChanged = 0,
- kOnMachineDataChanged,
- kOnExtraDataCanChange,
- kOnExtraDataChanged,
- kOnMediumRegistered,
- kOnMachineRegistered,
- kOnSessionStateChanged,
- kOnSnapshotTaken,
- kOnSnapshotDeleted,
- kOnSnapshotChanged,
- kOnGuestPropertyChanged
- } CallbackBit;
-
- VirtualBoxCallbackRegistration()
- {
- /* nothing */
- }
-
- ~VirtualBoxCallbackRegistration()
- {
- /* nothing */
- }
-};
+// static
+Bstr VirtualBox::sAPIVersion;
////////////////////////////////////////////////////////////////////////////////
//
@@ -167,7 +126,7 @@ class VirtualBox::CallbackEvent : public Event
{
public:
- CallbackEvent(VirtualBox *aVirtualBox, VirtualBoxCallbackRegistration::CallbackBit aWhat)
+ CallbackEvent(VirtualBox *aVirtualBox, VBoxEventType_T aWhat)
: mVirtualBox(aVirtualBox), mWhat(aWhat)
{
Assert(aVirtualBox);
@@ -183,9 +142,9 @@ private:
* Note that this is a weak ref -- the CallbackEvent handler thread
* is bound to the lifetime of the VirtualBox instance, so it's safe.
*/
- VirtualBox *mVirtualBox;
+ VirtualBox *mVirtualBox;
protected:
- VirtualBoxCallbackRegistration::CallbackBit mWhat;
+ VBoxEventType_T mWhat;
};
////////////////////////////////////////////////////////////////////////////////
@@ -343,7 +302,11 @@ HRESULT VirtualBox::FinalConstruct()
{
LogFlowThisFunc(("\n"));
- return init();
+ HRESULT rc = init();
+
+ BaseFinalConstruct();
+
+ return rc;
}
void VirtualBox::FinalRelease()
@@ -351,6 +314,8 @@ void VirtualBox::FinalRelease()
LogFlowThisFunc(("\n"));
uninit();
+
+ BaseFinalRelease();
}
// public initializer/uninitializer for internal purposes only
@@ -383,7 +348,9 @@ HRESULT VirtualBox::init()
sRevision = RTBldCfgRevision();
if (sPackageType.isEmpty())
sPackageType = VBOX_PACKAGE_STRING;
- LogFlowThisFunc(("Version: %ls, Package: %ls\n", sVersion.raw(), sPackageType.raw()));
+ if (sAPIVersion.isEmpty())
+ sAPIVersion = VBOX_API_VERSION_STRING;
+ LogFlowThisFunc(("Version: %ls, Package: %ls, API Version: %ls\n", sVersion.raw(), sPackageType.raw(), sAPIVersion.raw()));
/* Get the VirtualBox home directory. */
{
@@ -881,6 +848,17 @@ STDMETHODIMP VirtualBox::COMGETTER(PackageType)(BSTR *aPackageType)
return S_OK;
}
+STDMETHODIMP VirtualBox::COMGETTER(APIVersion)(BSTR *aAPIVersion)
+{
+ CheckComArgNotNull(aAPIVersion);
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ sAPIVersion.cloneTo(aAPIVersion);
+ return S_OK;
+}
+
STDMETHODIMP VirtualBox::COMGETTER(HomeFolder)(BSTR *aHomeFolder)
{
CheckComArgNotNull(aHomeFolder);
@@ -1102,6 +1080,138 @@ VirtualBox::COMGETTER(ExtensionPackManager)(IExtPackManager **aExtPackManager)
return hrc;
}
+STDMETHODIMP VirtualBox::COMGETTER(InternalNetworks)(ComSafeArrayOut(BSTR, aInternalNetworks))
+{
+ if (ComSafeArrayOutIsNull(aInternalNetworks))
+ return E_POINTER;
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ std::list<Bstr> allInternalNetworks;
+
+ /* get copy of all machine references, to avoid holding the list lock */
+ MachinesOList::MyList allMachines;
+ {
+ AutoReadLock al(m->allMachines.getLockHandle() COMMA_LOCKVAL_SRC_POS);
+ allMachines = m->allMachines.getList();
+ }
+ for (MachinesOList::MyList::const_iterator it = allMachines.begin();
+ it != allMachines.end();
+ ++it)
+ {
+ const ComObjPtr<Machine> &pMachine = *it;
+ AutoCaller autoMachineCaller(pMachine);
+ if (FAILED(autoMachineCaller.rc()))
+ continue;
+ AutoReadLock mlock(pMachine COMMA_LOCKVAL_SRC_POS);
+
+ if (pMachine->isAccessible())
+ {
+ ULONG cNetworkAdapters = 0;
+ HRESULT rc = m->pSystemProperties->GetMaxNetworkAdapters(pMachine->getChipsetType(), &cNetworkAdapters);
+ if (FAILED(rc))
+ continue;
+ cNetworkAdapters = RT_MIN(4, cNetworkAdapters);
+ for (ULONG i = 0; i < cNetworkAdapters; i++)
+ {
+ ComPtr<INetworkAdapter> pNet;
+ rc = pMachine->GetNetworkAdapter(i, pNet.asOutParam());
+ if (FAILED(rc) || pNet.isNull())
+ continue;
+ Bstr strInternalNetwork;
+ rc = pNet->COMGETTER(InternalNetwork)(strInternalNetwork.asOutParam());
+ if (FAILED(rc) || strInternalNetwork.isEmpty())
+ continue;
+
+ allInternalNetworks.push_back(strInternalNetwork);
+ }
+ }
+ }
+
+ /* throw out any duplicates */
+ allInternalNetworks.sort();
+ allInternalNetworks.unique();
+ com::SafeArray<BSTR> internalNetworks(allInternalNetworks.size());
+ size_t i = 0;
+ for (std::list<Bstr>::const_iterator it = allInternalNetworks.begin();
+ it != allInternalNetworks.end();
+ ++it, i++)
+ {
+ const Bstr &tmp = *it;
+ tmp.cloneTo(&internalNetworks[i]);
+ }
+ internalNetworks.detachTo(ComSafeArrayOutArg(aInternalNetworks));
+
+ return S_OK;
+}
+
+STDMETHODIMP VirtualBox::COMGETTER(GenericNetworkDrivers)(ComSafeArrayOut(BSTR, aGenericNetworkDrivers))
+{
+ if (ComSafeArrayOutIsNull(aGenericNetworkDrivers))
+ return E_POINTER;
+
+ AutoCaller autoCaller(this);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ std::list<Bstr> allGenericNetworkDrivers;
+
+ /* get copy of all machine references, to avoid holding the list lock */
+ MachinesOList::MyList allMachines;
+ {
+ AutoReadLock al(m->allMachines.getLockHandle() COMMA_LOCKVAL_SRC_POS);
+ allMachines = m->allMachines.getList();
+ }
+ for (MachinesOList::MyList::const_iterator it = allMachines.begin();
+ it != allMachines.end();
+ ++it)
+ {
+ const ComObjPtr<Machine> &pMachine = *it;
+ AutoCaller autoMachineCaller(pMachine);
+ if (FAILED(autoMachineCaller.rc()))
+ continue;
+ AutoReadLock mlock(pMachine COMMA_LOCKVAL_SRC_POS);
+
+ if (pMachine->isAccessible())
+ {
+ ULONG cNetworkAdapters = 0;
+ HRESULT rc = m->pSystemProperties->GetMaxNetworkAdapters(pMachine->getChipsetType(), &cNetworkAdapters);
+ if (FAILED(rc))
+ continue;
+ cNetworkAdapters = RT_MIN(4, cNetworkAdapters);
+ for (ULONG i = 0; i < cNetworkAdapters; i++)
+ {
+ ComPtr<INetworkAdapter> pNet;
+ rc = pMachine->GetNetworkAdapter(i, pNet.asOutParam());
+ if (FAILED(rc) || pNet.isNull())
+ continue;
+ Bstr strGenericNetworkDriver;
+ rc = pNet->COMGETTER(GenericDriver)(strGenericNetworkDriver.asOutParam());
+ if (FAILED(rc) || strGenericNetworkDriver.isEmpty())
+ continue;
+
+ allGenericNetworkDrivers.push_back(strGenericNetworkDriver);
+ }
+ }
+ }
+
+ /* throw out any duplicates */
+ allGenericNetworkDrivers.sort();
+ allGenericNetworkDrivers.unique();
+ com::SafeArray<BSTR> genericNetworks(allGenericNetworkDrivers.size());
+ size_t i = 0;
+ for (std::list<Bstr>::const_iterator it = allGenericNetworkDrivers.begin();
+ it != allGenericNetworkDrivers.end();
+ ++it, i++)
+ {
+ const Bstr &tmp = *it;
+ tmp.cloneTo(&genericNetworks[i]);
+ }
+ genericNetworks.detachTo(ComSafeArrayOutArg(aGenericNetworkDrivers));
+
+ return S_OK;
+}
+
STDMETHODIMP
VirtualBox::CheckFirmwarePresent(FirmwareType_T aFirmwareType,
IN_BSTR aVersion,
@@ -1114,11 +1224,10 @@ VirtualBox::CheckFirmwarePresent(FirmwareType_T aFirmwareType,
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
- const char *url;
-
NOREF(aVersion);
- static const struct {
+ static const struct
+ {
FirmwareType_T type;
const char* fileName;
const char* url;
@@ -1153,22 +1262,23 @@ VirtualBox::CheckFirmwarePresent(FirmwareType_T aFirmwareType,
}
Utf8Str shortName, fullName;
- int rc;
shortName = Utf8StrFmt("Firmware%c%s",
RTPATH_DELIMITER,
firmwareDesc[i].fileName);
- rc = calculateFullPath(shortName, fullName); AssertRCReturn(rc, rc);
+ int rc = calculateFullPath(shortName, fullName);
+ AssertRCReturn(rc, rc);
if (RTFileExists(fullName.c_str()))
{
*aResult = TRUE;
- if (aFile)
+ if (aFile)
Utf8Str(fullName).cloneTo(aFile);
break;
}
char pszVBoxPath[RTPATH_MAX];
- rc = RTPathExecDir(pszVBoxPath, RTPATH_MAX); AssertRCReturn(rc, rc);
+ rc = RTPathExecDir(pszVBoxPath, RTPATH_MAX);
+ AssertRCReturn(rc, rc);
fullName = Utf8StrFmt("%s%c%s",
pszVBoxPath,
RTPATH_DELIMITER,
@@ -1181,8 +1291,6 @@ VirtualBox::CheckFirmwarePresent(FirmwareType_T aFirmwareType,
break;
}
-
- url = firmwareDesc[i].url;
/** @todo: account for version in the URL */
if (aUrl != NULL)
{
@@ -1461,6 +1569,7 @@ STDMETHODIMP VirtualBox::CreateHardDisk(IN_BSTR aFormat,
STDMETHODIMP VirtualBox::OpenMedium(IN_BSTR aLocation,
DeviceType_T deviceType,
AccessMode_T accessMode,
+ BOOL fForceNewUuid,
IMedium **aMedium)
{
CheckComArgStrNotEmptyOrNull(aLocation);
@@ -1508,6 +1617,7 @@ STDMETHODIMP VirtualBox::OpenMedium(IN_BSTR aLocation,
rc = pMedium->init(this,
aLocation,
(accessMode == AccessMode_ReadWrite) ? Medium::OpenReadWrite : Medium::OpenReadOnly,
+ fForceNewUuid,
deviceType);
if (SUCCEEDED(rc))
@@ -2205,34 +2315,30 @@ void VirtualBox::addProcessToReap(RTPROCESS pid)
/** Event for onMachineStateChange(), onMachineDataChange(), onMachineRegistered() */
struct MachineEvent : public VirtualBox::CallbackEvent
{
- MachineEvent(VirtualBox *aVB, const Guid &aId)
- : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineDataChanged), id(aId.toUtf16())
- {}
-
- MachineEvent(VirtualBox *aVB, const Guid &aId, MachineState_T aState)
- : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineStateChanged), id(aId.toUtf16())
- , state(aState)
- {}
-
- MachineEvent(VirtualBox *aVB, const Guid &aId, BOOL aRegistered)
- : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineRegistered), id(aId.toUtf16())
- , registered(aRegistered)
+ MachineEvent(VirtualBox *aVB, VBoxEventType_T aWhat, const Guid &aId, BOOL aBool)
+ : CallbackEvent(aVB, aWhat), id(aId.toUtf16())
+ , mBool(aBool)
+ { }
+
+ MachineEvent(VirtualBox *aVB, VBoxEventType_T aWhat, const Guid &aId, MachineState_T aState)
+ : CallbackEvent(aVB, aWhat), id(aId.toUtf16())
+ , mState(aState)
{}
virtual HRESULT prepareEventDesc(IEventSource* aSource, VBoxEventDesc& aEvDesc)
{
switch (mWhat)
{
- case VirtualBoxCallbackRegistration::kOnMachineDataChanged:
- aEvDesc.init(aSource, VBoxEventType_OnMachineDataChanged, id.raw());
+ case VBoxEventType_OnMachineDataChanged:
+ aEvDesc.init(aSource, mWhat, id.raw(), mBool);
break;
- case VirtualBoxCallbackRegistration::kOnMachineStateChanged:
- aEvDesc.init(aSource, VBoxEventType_OnMachineStateChanged, id.raw(), state);
+ case VBoxEventType_OnMachineStateChanged:
+ aEvDesc.init(aSource, mWhat, id.raw(), mState);
break;
- case VirtualBoxCallbackRegistration::kOnMachineRegistered:
- aEvDesc.init(aSource, VBoxEventType_OnMachineRegistered, id.raw(), registered);
+ case VBoxEventType_OnMachineRegistered:
+ aEvDesc.init(aSource, mWhat, id.raw(), mBool);
break;
default:
@@ -2242,8 +2348,8 @@ struct MachineEvent : public VirtualBox::CallbackEvent
}
Bstr id;
- MachineState_T state;
- BOOL registered;
+ MachineState_T mState;
+ BOOL mBool;
};
/**
@@ -2251,15 +2357,15 @@ struct MachineEvent : public VirtualBox::CallbackEvent
*/
void VirtualBox::onMachineStateChange(const Guid &aId, MachineState_T aState)
{
- postEvent(new MachineEvent(this, aId, aState));
+ postEvent(new MachineEvent(this, VBoxEventType_OnMachineStateChanged, aId, aState));
}
/**
* @note Doesn't lock any object.
*/
-void VirtualBox::onMachineDataChange(const Guid &aId)
+void VirtualBox::onMachineDataChange(const Guid &aId, BOOL aTemporary)
{
- postEvent(new MachineEvent(this, aId));
+ postEvent(new MachineEvent(this, VBoxEventType_OnMachineDataChanged, aId, aTemporary));
}
/**
@@ -2311,7 +2417,7 @@ struct ExtraDataEvent : public VirtualBox::CallbackEvent
{
ExtraDataEvent(VirtualBox *aVB, const Guid &aMachineId,
IN_BSTR aKey, IN_BSTR aVal)
- : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnExtraDataChanged)
+ : CallbackEvent(aVB, VBoxEventType_OnExtraDataChanged)
, machineId(aMachineId.toUtf16()), key(aKey), val(aVal)
{}
@@ -2336,14 +2442,14 @@ void VirtualBox::onExtraDataChange(const Guid &aId, IN_BSTR aKey, IN_BSTR aValue
*/
void VirtualBox::onMachineRegistered(const Guid &aId, BOOL aRegistered)
{
- postEvent(new MachineEvent(this, aId, aRegistered));
+ postEvent(new MachineEvent(this, VBoxEventType_OnMachineRegistered, aId, aRegistered));
}
/** Event for onSessionStateChange() */
struct SessionEvent : public VirtualBox::CallbackEvent
{
SessionEvent(VirtualBox *aVB, const Guid &aMachineId, SessionState_T aState)
- : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnSessionStateChanged)
+ : CallbackEvent(aVB, VBoxEventType_OnSessionStateChanged)
, machineId(aMachineId.toUtf16()), sessionState(aState)
{}
@@ -2367,7 +2473,7 @@ void VirtualBox::onSessionStateChange(const Guid &aId, SessionState_T aState)
struct SnapshotEvent : public VirtualBox::CallbackEvent
{
SnapshotEvent(VirtualBox *aVB, const Guid &aMachineId, const Guid &aSnapshotId,
- VirtualBoxCallbackRegistration::CallbackBit aWhat)
+ VBoxEventType_T aWhat)
: CallbackEvent(aVB, aWhat)
, machineId(aMachineId), snapshotId(aSnapshotId)
{}
@@ -2388,7 +2494,7 @@ struct SnapshotEvent : public VirtualBox::CallbackEvent
void VirtualBox::onSnapshotTaken(const Guid &aMachineId, const Guid &aSnapshotId)
{
postEvent(new SnapshotEvent(this, aMachineId, aSnapshotId,
- VirtualBoxCallbackRegistration::kOnSnapshotTaken));
+ VBoxEventType_OnSnapshotTaken));
}
/**
@@ -2397,7 +2503,7 @@ void VirtualBox::onSnapshotTaken(const Guid &aMachineId, const Guid &aSnapshotId
void VirtualBox::onSnapshotDeleted(const Guid &aMachineId, const Guid &aSnapshotId)
{
postEvent(new SnapshotEvent(this, aMachineId, aSnapshotId,
- VirtualBoxCallbackRegistration::kOnSnapshotDeleted));
+ VBoxEventType_OnSnapshotDeleted));
}
/**
@@ -2406,7 +2512,7 @@ void VirtualBox::onSnapshotDeleted(const Guid &aMachineId, const Guid &aSnapshot
void VirtualBox::onSnapshotChange(const Guid &aMachineId, const Guid &aSnapshotId)
{
postEvent(new SnapshotEvent(this, aMachineId, aSnapshotId,
- VirtualBoxCallbackRegistration::kOnSnapshotChanged));
+ VBoxEventType_OnSnapshotChanged));
}
/** Event for onGuestPropertyChange() */
@@ -2414,7 +2520,7 @@ struct GuestPropertyEvent : public VirtualBox::CallbackEvent
{
GuestPropertyEvent(VirtualBox *aVBox, const Guid &aMachineId,
IN_BSTR aName, IN_BSTR aValue, IN_BSTR aFlags)
- : CallbackEvent(aVBox, VirtualBoxCallbackRegistration::kOnGuestPropertyChanged),
+ : CallbackEvent(aVBox, VBoxEventType_OnGuestPropertyChanged),
machineId(aMachineId),
name(aName),
value(aValue),
@@ -3731,7 +3837,7 @@ HRESULT VirtualBox::unregisterMachine(Machine *pMachine,
// 2) better registry found: then use that
pMedium->addRegistry(*puuidBetter, true /* fRecurse */);
// 3) and make sure the registry is saved below
- addGuidToListUniquely(llRegistriesThatNeedSaving, *puuidBetter);
+ VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, *puuidBetter);
}
}
}
@@ -3753,6 +3859,7 @@ HRESULT VirtualBox::unregisterMachine(Machine *pMachine,
* @param llRegistriesThatNeedSaving
* @param uuid
*/
+/* static */
void VirtualBox::addGuidToListUniquely(GuidList &llRegistriesThatNeedSaving,
const Guid &uuid)
{
@@ -3883,7 +3990,7 @@ HRESULT VirtualBox::handleUnexpectedExceptions(RT_SRC_POS_DECL)
/* re-throw the current exception */
throw;
}
- catch (const iprt::Error &err) // includes all XML exceptions
+ catch (const RTCError &err) // includes all XML exceptions
{
return setErrorStatic(E_FAIL,
Utf8StrFmt(tr("%s.\n%s[%d] (%s)"),
@@ -4420,6 +4527,8 @@ DECLCALLBACK(int) VirtualBox::AsyncEventHandler(RTTHREAD thread, void *pvUser)
AssertReturn(pvUser, VERR_INVALID_POINTER);
+ com::Initialize();
+
// create an event queue for the current thread
EventQueue *eventQ = new EventQueue();
AssertReturn(eventQ, VERR_NO_MEMORY);
@@ -4434,6 +4543,9 @@ DECLCALLBACK(int) VirtualBox::AsyncEventHandler(RTTHREAD thread, void *pvUser)
delete eventQ;
+ com::Shutdown();
+
+
LogFlowFuncLeave();
return 0;
diff --git a/src/VBox/Main/src-server/darwin/NetIf-darwin.cpp b/src/VBox/Main/src-server/darwin/NetIf-darwin.cpp
index 99cf52e2f..ac8b72ae6 100644
--- a/src/VBox/Main/src-server/darwin/NetIf-darwin.cpp
+++ b/src/VBox/Main/src-server/darwin/NetIf-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: NetIf-darwin.cpp $ */
+/* $Id: NetIf-darwin.cpp 35693 2011-01-24 17:27:05Z vboxsync $ */
/** @file
* Main - NetIfList, Darwin implementation.
*/
diff --git a/src/VBox/Main/src-server/darwin/OpenGLTestDarwin.cpp b/src/VBox/Main/src-server/darwin/OpenGLTestDarwin.cpp
index 74ddedd16..de80f4d34 100644
--- a/src/VBox/Main/src-server/darwin/OpenGLTestDarwin.cpp
+++ b/src/VBox/Main/src-server/darwin/OpenGLTestDarwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: OpenGLTestDarwin.cpp $ */
+/* $Id: OpenGLTestDarwin.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox host opengl support test
diff --git a/src/VBox/Main/src-server/darwin/PerformanceDarwin.cpp b/src/VBox/Main/src-server/darwin/PerformanceDarwin.cpp
index f02581bb0..eda4e5c06 100644
--- a/src/VBox/Main/src-server/darwin/PerformanceDarwin.cpp
+++ b/src/VBox/Main/src-server/darwin/PerformanceDarwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: PerformanceDarwin.cpp $ */
+/* $Id: PerformanceDarwin.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox Darwin-specific Performance Classes implementation.
*/
diff --git a/src/VBox/Main/src-server/darwin/USBProxyServiceDarwin.cpp b/src/VBox/Main/src-server/darwin/USBProxyServiceDarwin.cpp
index 4c9d542ea..41e514eeb 100644
--- a/src/VBox/Main/src-server/darwin/USBProxyServiceDarwin.cpp
+++ b/src/VBox/Main/src-server/darwin/USBProxyServiceDarwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyServiceDarwin.cpp $ */
+/* $Id: USBProxyServiceDarwin.cpp 37599 2011-06-22 21:06:38Z vboxsync $ */
/** @file
* VirtualBox USB Proxy Service (in VBoxSVC), Darwin Specialization.
*/
@@ -52,12 +52,6 @@ USBProxyServiceDarwin::USBProxyServiceDarwin (Host *aHost)
*/
HRESULT USBProxyServiceDarwin::init(void)
{
- /*
- * Call the superclass method first.
- */
- HRESULT hrc = USBProxyService::init();
- AssertComRCReturn(hrc, hrc);
-
#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
/*
* Initialize the USB library.
diff --git a/src/VBox/Main/src-server/darwin/iokit.cpp b/src/VBox/Main/src-server/darwin/iokit.cpp
index 573d0809a..084e01b77 100644
--- a/src/VBox/Main/src-server/darwin/iokit.cpp
+++ b/src/VBox/Main/src-server/darwin/iokit.cpp
@@ -1,4 +1,4 @@
-/* $Id: iokit.cpp $ */
+/* $Id: iokit.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Main - Darwin IOKit Routines.
*
diff --git a/src/VBox/Main/src-server/darwin/iokit.h b/src/VBox/Main/src-server/darwin/iokit.h
index 8cb80a52f..caa40a5bf 100644
--- a/src/VBox/Main/src-server/darwin/iokit.h
+++ b/src/VBox/Main/src-server/darwin/iokit.h
@@ -1,4 +1,4 @@
-/* $Id: iokit.h $ */
+/* $Id: iokit.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Main - Darwin IOKit Routines.
*/
diff --git a/src/VBox/Main/src-server/freebsd/HostHardwareFreeBSD.cpp b/src/VBox/Main/src-server/freebsd/HostHardwareFreeBSD.cpp
index 99ff2675a..efa504940 100644
--- a/src/VBox/Main/src-server/freebsd/HostHardwareFreeBSD.cpp
+++ b/src/VBox/Main/src-server/freebsd/HostHardwareFreeBSD.cpp
@@ -1,4 +1,4 @@
-/* $Id: HostHardwareFreeBSD.cpp $ */
+/* $Id: HostHardwareFreeBSD.cpp 37774 2011-07-04 21:19:27Z vboxsync $ */
/** @file
* Classes for handling hardware detection under FreeBSD.
*/
@@ -35,6 +35,7 @@
#include <iprt/string.h>
#ifdef RT_OS_FREEBSD
+# include <sys/param.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <unistd.h>
@@ -186,11 +187,18 @@ static int getDVDInfoFromCAM(DriveInfoList *pList, bool *pfSuccess)
DeviceMatchPattern.pattern.device_pattern.target_id = CAM_TARGET_WILDCARD;
DeviceMatchPattern.pattern.device_pattern.target_lun = CAM_LUN_WILDCARD;
DeviceMatchPattern.pattern.device_pattern.flags = DEV_MATCH_INQUIRY;
- DeviceMatchPattern.pattern.device_pattern.inq_pat.type = T_CDROM;
- DeviceMatchPattern.pattern.device_pattern.inq_pat.media_type = SIP_MEDIA_REMOVABLE | SIP_MEDIA_FIXED;
- DeviceMatchPattern.pattern.device_pattern.inq_pat.vendor[0] = '*'; /* Matches anything */
- DeviceMatchPattern.pattern.device_pattern.inq_pat.product[0] = '*'; /* Matches anything */
- DeviceMatchPattern.pattern.device_pattern.inq_pat.revision[0] = '*'; /* Matches anything */
+
+#if __FreeBSD_version >= 900000
+# define INQ_PAT data.inq_pat
+#else
+ #define INQ_PAT inq_pat
+#endif
+ DeviceMatchPattern.pattern.device_pattern.INQ_PAT.type = T_CDROM;
+ DeviceMatchPattern.pattern.device_pattern.INQ_PAT.media_type = SIP_MEDIA_REMOVABLE | SIP_MEDIA_FIXED;
+ DeviceMatchPattern.pattern.device_pattern.INQ_PAT.vendor[0] = '*'; /* Matches anything */
+ DeviceMatchPattern.pattern.device_pattern.INQ_PAT.product[0] = '*'; /* Matches anything */
+ DeviceMatchPattern.pattern.device_pattern.INQ_PAT.revision[0] = '*'; /* Matches anything */
+#undef INQ_PAT
DeviceCCB.cdm.num_patterns = 1;
DeviceCCB.cdm.pattern_buf_len = sizeof(struct dev_match_result);
DeviceCCB.cdm.patterns = &DeviceMatchPattern;
diff --git a/src/VBox/Main/src-server/freebsd/NetIf-freebsd.cpp b/src/VBox/Main/src-server/freebsd/NetIf-freebsd.cpp
index 2adfc6415..2fdd2566d 100644
--- a/src/VBox/Main/src-server/freebsd/NetIf-freebsd.cpp
+++ b/src/VBox/Main/src-server/freebsd/NetIf-freebsd.cpp
@@ -1,4 +1,4 @@
-/* $Id: NetIf-freebsd.cpp $ */
+/* $Id: NetIf-freebsd.cpp 36797 2011-04-21 15:46:31Z vboxsync $ */
/** @file
* Main - NetIfList, FreeBSD implementation.
*/
@@ -179,7 +179,7 @@ int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list)
size_t cbNeeded;
char *pBuf, *pNext;
int aiMib[6];
- unsigned short u16DefaultIface;
+ unsigned short u16DefaultIface = 0; /* shut up gcc. */
bool fDefaultIfaceExistent = true;
/* Get the index of the interface associated with default route. */
diff --git a/src/VBox/Main/src-server/freebsd/PerformanceFreeBSD.cpp b/src/VBox/Main/src-server/freebsd/PerformanceFreeBSD.cpp
index 0b8178423..3e38af6fc 100644
--- a/src/VBox/Main/src-server/freebsd/PerformanceFreeBSD.cpp
+++ b/src/VBox/Main/src-server/freebsd/PerformanceFreeBSD.cpp
@@ -1,4 +1,4 @@
-/* $Id: PerformanceFreeBSD.cpp $ */
+/* $Id: PerformanceFreeBSD.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VirtualBox Performance Collector, FreeBSD Specialization.
*/
diff --git a/src/VBox/Main/src-server/freebsd/USBProxyServiceFreeBSD.cpp b/src/VBox/Main/src-server/freebsd/USBProxyServiceFreeBSD.cpp
index 1f088b6ef..8776b5680 100644
--- a/src/VBox/Main/src-server/freebsd/USBProxyServiceFreeBSD.cpp
+++ b/src/VBox/Main/src-server/freebsd/USBProxyServiceFreeBSD.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyServiceFreeBSD.cpp $ */
+/* $Id: USBProxyServiceFreeBSD.cpp 37599 2011-06-22 21:06:38Z vboxsync $ */
/** @file
* VirtualBox USB Proxy Service, FreeBSD Specialization.
*/
@@ -73,12 +73,6 @@ USBProxyServiceFreeBSD::USBProxyServiceFreeBSD(Host *aHost)
HRESULT USBProxyServiceFreeBSD::init(void)
{
/*
- * Call the superclass method first.
- */
- HRESULT hrc = USBProxyService::init();
- AssertComRCReturn(hrc, hrc);
-
- /*
* Create semaphore.
*/
int rc = RTSemEventCreate(&mNotifyEventSem);
diff --git a/src/VBox/Main/src-server/generic/NetIf-generic.cpp b/src/VBox/Main/src-server/generic/NetIf-generic.cpp
index 657a0ba03..00f417f33 100644
--- a/src/VBox/Main/src-server/generic/NetIf-generic.cpp
+++ b/src/VBox/Main/src-server/generic/NetIf-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: NetIf-generic.cpp $ */
+/* $Id: NetIf-generic.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
* VirtualBox Main - Generic NetIf implementation.
*/
@@ -127,7 +127,7 @@ int NetIfEnableDynamicIpConfig(VirtualBox * /* vBox */, HostNetworkInterface * /
int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVBox,
- IHostNetworkInterface **aHostNetworkInterface,
+ IHostNetworkInterface **aHostNetworkInterface,
IProgress **aProgress,
const char *pcszName)
{
diff --git a/src/VBox/Main/src-server/generic/OpenGLTest.cpp b/src/VBox/Main/src-server/generic/OpenGLTest.cpp
index 318583ab0..efc68d1f4 100644
--- a/src/VBox/Main/src-server/generic/OpenGLTest.cpp
+++ b/src/VBox/Main/src-server/generic/OpenGLTest.cpp
@@ -1,4 +1,4 @@
-/* $Id: OpenGLTest.cpp $ */
+/* $Id: OpenGLTest.cpp 29208 2010-05-07 13:09:51Z vboxsync $ */
/** @file
* VBox host opengl support test - generic implementation.
*/
diff --git a/src/VBox/Main/src-server/generic/OpenGLTestApp.cpp b/src/VBox/Main/src-server/generic/OpenGLTestApp.cpp
index 1ca0d7994..1157142f4 100644
--- a/src/VBox/Main/src-server/generic/OpenGLTestApp.cpp
+++ b/src/VBox/Main/src-server/generic/OpenGLTestApp.cpp
@@ -1,4 +1,4 @@
-/* $Id: OpenGLTestApp.cpp $ */
+/* $Id: OpenGLTestApp.cpp 36344 2011-03-22 14:29:37Z vboxsync $ */
/** @file
* VBox host opengl support test application.
*/
diff --git a/src/VBox/Main/src-server/linux/HostHardwareLinux.cpp b/src/VBox/Main/src-server/linux/HostHardwareLinux.cpp
index f29307dac..95646fcd6 100644
--- a/src/VBox/Main/src-server/linux/HostHardwareLinux.cpp
+++ b/src/VBox/Main/src-server/linux/HostHardwareLinux.cpp
@@ -1,4 +1,4 @@
-/* $Id: HostHardwareLinux.cpp $ */
+/* $Id: HostHardwareLinux.cpp 36618 2011-04-08 07:18:11Z vboxsync $ */
/** @file
* Classes for handling hardware detection under Linux. Please feel free to
* expand these to work for other systems (Solaris!) or to add new ones for
@@ -1331,6 +1331,7 @@ int hotplugInotifyImpl::drainWakeupPipe(void)
AssertRCReturn(mStatus, VERR_WRONG_ORDER);
cbRead = read(mhWakeupPipeR, szBuf, sizeof(szBuf));
Assert(cbRead > 0);
+ NOREF(cbRead);
return VINF_SUCCESS;
}
diff --git a/src/VBox/Main/src-server/linux/NetIf-linux.cpp b/src/VBox/Main/src-server/linux/NetIf-linux.cpp
index ebfd9e349..f3befb2c2 100644
--- a/src/VBox/Main/src-server/linux/NetIf-linux.cpp
+++ b/src/VBox/Main/src-server/linux/NetIf-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: NetIf-linux.cpp $ */
+/* $Id: NetIf-linux.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Main - NetIfList, Linux implementation.
*/
diff --git a/src/VBox/Main/src-server/linux/PerformanceLinux.cpp b/src/VBox/Main/src-server/linux/PerformanceLinux.cpp
index 16ef7f81c..75c9a4c77 100644
--- a/src/VBox/Main/src-server/linux/PerformanceLinux.cpp
+++ b/src/VBox/Main/src-server/linux/PerformanceLinux.cpp
@@ -1,4 +1,4 @@
-/* $Id: PerformanceLinux.cpp $ */
+/* $Id: PerformanceLinux.cpp 37713 2011-06-30 15:14:13Z vboxsync $ */
/** @file
*
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -74,9 +74,11 @@ int CollectorLinux::preCollect(const CollectorHints& hints, uint64_t /* iTick */
{
VMProcessStats vmStats;
int rc = getRawProcessStats(*it, &vmStats.cpuUser, &vmStats.cpuKernel, &vmStats.pagesUsed);
- if (RT_FAILURE(rc))
- return rc;
- mProcessStats[*it] = vmStats;
+ /* On failure, do NOT stop. Just skip the entry. Having the stats for
+ * one (probably broken) process frozen/zero is a minor issue compared
+ * to not updating many process stats and the host cpu stats. */
+ if (RT_SUCCESS(rc))
+ mProcessStats[*it] = vmStats;
}
if (hints.isHostCpuLoadCollected() || mProcessStats.size())
{
diff --git a/src/VBox/Main/src-server/linux/USBGetDevices.cpp b/src/VBox/Main/src-server/linux/USBGetDevices.cpp
index 63b45f37f..78d6063d4 100644
--- a/src/VBox/Main/src-server/linux/USBGetDevices.cpp
+++ b/src/VBox/Main/src-server/linux/USBGetDevices.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBGetDevices.cpp $ */
+/* $Id: USBGetDevices.cpp 37624 2011-06-24 08:57:35Z vboxsync $ */
/** @file
* VirtualBox Linux host USB device enumeration.
*/
@@ -22,13 +22,16 @@
#include "USBGetDevices.h"
+#include <VBox/err.h>
#include <VBox/usb.h>
#include <VBox/usblib.h>
#include <iprt/linux/sysfs.h>
#include <iprt/cdefs.h>
#include <iprt/ctype.h>
-#include <iprt/err.h>
+#include <iprt/dir.h>
+#include <iprt/env.h>
+#include <iprt/file.h>
#include <iprt/fs.h>
#include <iprt/log.h>
#include <iprt/mem.h>
@@ -1477,6 +1480,11 @@ static PUSBDEVICE testGetUsbfsDevices(const char *pcszUsbfsRoot, bool testfs)
}
# define getDevicesFromUsbfs testGetUsbfsDevices
+/**
+ * Specify the list of devices that will appear to be available through
+ * usbfs during unit testing (of USBProxyLinuxGetDevices)
+ * @param pacszDeviceAddresses NULL terminated array of usbfs device addresses
+ */
void TestUSBSetAvailableUsbfsDevices(const char **pacszDeviceAddresses)
{
s_pacszUsbfsDeviceAddresses = pacszDeviceAddresses;
@@ -1496,12 +1504,175 @@ static int testAccess(const char *pcszPath, int mode)
}
# define access testAccess
+/**
+ * Specify the list of files that access will report as accessible (at present
+ * we only do accessible or not accessible) during unit testing (of
+ * USBProxyLinuxGetDevices)
+ * @param pacszAccessibleFiles NULL terminated array of file paths to be
+ * reported accessible
+ */
void TestUSBSetAccessibleFiles(const char **pacszAccessibleFiles)
{
s_pacszAccessibleFiles = pacszAccessibleFiles;
}
#endif
+#ifdef UNIT_TEST
+# ifdef UNIT_TEST
+ /** The path we pretend the usbfs root is located at, or NULL. */
+ const char *s_pcszTestUsbfsRoot;
+ /** Should usbfs be accessible to the current user? */
+ bool s_fTestUsbfsAccessible;
+ /** The path we pretend the device node tree root is located at, or NULL. */
+ const char *s_pcszTestDevicesRoot;
+ /** Should the device node tree be accessible to the current user? */
+ bool s_fTestDevicesAccessible;
+ /** The result of the usbfs/inotify-specific init */
+ int s_rcTestMethodInitResult;
+ /** The value of the VBOX_USB environment variable. */
+ const char *s_pcszTestEnvUsb;
+ /** The value of the VBOX_USB_ROOT environment variable. */
+ const char *s_pcszTestEnvUsbRoot;
+# endif
+
+/** Select which access methods will be available to the @a init method
+ * during unit testing, and (hack!) what return code it will see from
+ * the access method-specific initialisation. */
+void TestUSBSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible,
+ const char *pcszDevicesRoot, bool fDevicesAccessible,
+ int rcMethodInitResult)
+{
+ s_pcszTestUsbfsRoot = pcszUsbfsRoot;
+ s_fTestUsbfsAccessible = fUsbfsAccessible;
+ s_pcszTestDevicesRoot = pcszDevicesRoot;
+ s_fTestDevicesAccessible = fDevicesAccessible;
+ s_rcTestMethodInitResult = rcMethodInitResult;
+}
+
+/** Specify the environment that the @a init method will see during unit
+ * testing. */
+void TestUSBSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot)
+{
+ s_pcszTestEnvUsb = pcszEnvUsb;
+ s_pcszTestEnvUsbRoot = pcszEnvUsbRoot;
+}
+
+/* For testing we redefine anything that accesses the outside world to
+ * return test values. */
+# define RTEnvGet(a) \
+ ( !RTStrCmp(a, "VBOX_USB") ? s_pcszTestEnvUsb \
+ : !RTStrCmp(a, "VBOX_USB_ROOT") ? s_pcszTestEnvUsbRoot \
+ : NULL)
+# define USBProxyLinuxCheckDeviceRoot(pcszPath, fUseNodes) \
+ ( ((fUseNodes) && s_fTestDevicesAccessible \
+ && !RTStrCmp(pcszPath, s_pcszTestDevicesRoot)) \
+ || (!(fUseNodes) && s_fTestUsbfsAccessible \
+ && !RTStrCmp(pcszPath, s_pcszTestUsbfsRoot)))
+# define RTDirExists(pcszDir) \
+ ( (pcszDir) \
+ && ( !RTStrCmp(pcszDir, s_pcszTestDevicesRoot) \
+ || !RTStrCmp(pcszDir, s_pcszTestUsbfsRoot)))
+# define RTFileExists(pcszFile) \
+ ( (pcszFile) \
+ && s_pcszTestUsbfsRoot \
+ && !RTStrNCmp(pcszFile, s_pcszTestUsbfsRoot, strlen(s_pcszTestUsbfsRoot)) \
+ && !RTStrCmp(pcszFile + strlen(s_pcszTestUsbfsRoot), "/devices"))
+#endif
+
+/**
+ * Selects the access method that will be used to access USB devices based on
+ * what is available on the host and what if anything the user has specified
+ * in the environment.
+ * @returns iprt status value
+ * @param pfUsingUsbfsDevices on success this will be set to true if
+ * the prefered access method is USBFS-like and to
+ * false if it is sysfs/device node-like
+ * @param ppcszDevicesRoot on success the root of the tree of USBFS-like
+ * device nodes will be stored here
+ */
+int USBProxyLinuxChooseMethod(bool *pfUsingUsbfsDevices,
+ const char **ppcszDevicesRoot)
+{
+ /*
+ * We have two methods available for getting host USB device data - using
+ * USBFS and using sysfs. The default choice is sysfs; if that is not
+ * available we fall back to USBFS.
+ * In the event of both failing, an appropriate error will be returned.
+ * The user may also specify a method and root using the VBOX_USB and
+ * VBOX_USB_ROOT environment variables. In this case we don't check
+ * the root they provide for validity.
+ */
+ bool fUsbfsChosen = false, fSysfsChosen = false;
+ const char *pcszUsbFromEnv = RTEnvGet("VBOX_USB");
+ const char *pcszUsbRoot = NULL;
+ if (pcszUsbFromEnv)
+ {
+ bool fValidVBoxUSB = true;
+
+ pcszUsbRoot = RTEnvGet("VBOX_USB_ROOT");
+ if (!RTStrICmp(pcszUsbFromEnv, "USBFS"))
+ {
+ LogRel(("Default USB access method set to \"usbfs\" from environment\n"));
+ fUsbfsChosen = true;
+ }
+ else if (!RTStrICmp(pcszUsbFromEnv, "SYSFS"))
+ {
+ LogRel(("Default USB method set to \"sysfs\" from environment\n"));
+ fSysfsChosen = true;
+ }
+ else
+ {
+ LogRel(("Invalid VBOX_USB environment variable setting \"%s\"\n",
+ pcszUsbFromEnv));
+ fValidVBoxUSB = false;
+ pcszUsbFromEnv = NULL;
+ }
+ if (!fValidVBoxUSB && pcszUsbRoot)
+ pcszUsbRoot = NULL;
+ }
+ if (!pcszUsbRoot)
+ {
+ if ( !fUsbfsChosen
+ && USBProxyLinuxCheckDeviceRoot("/dev/vboxusb", true))
+ {
+ fSysfsChosen = true;
+ pcszUsbRoot = "/dev/vboxusb";
+ }
+ else if ( !fSysfsChosen
+ && USBProxyLinuxCheckDeviceRoot("/proc/bus/usb", false))
+ {
+ fUsbfsChosen = true;
+ pcszUsbRoot = "/proc/bus/usb";
+ }
+ }
+ else if (!USBProxyLinuxCheckDeviceRoot(pcszUsbRoot, fSysfsChosen))
+ pcszUsbRoot = NULL;
+ if (pcszUsbRoot)
+ {
+ *pfUsingUsbfsDevices = fUsbfsChosen;
+ *ppcszDevicesRoot = pcszUsbRoot;
+ return VINF_SUCCESS;
+ }
+ /* else */
+ return pcszUsbFromEnv ? VERR_NOT_FOUND
+ : RTDirExists("/dev/vboxusb") ? VERR_VUSB_USB_DEVICE_PERMISSION
+ : RTFileExists("/proc/bus/usb/devices") ? VERR_VUSB_USBFS_PERMISSION
+ : VERR_NOT_FOUND;
+}
+
+#ifdef UNIT_TEST
+# undef RTEnvGet
+# undef USBProxyLinuxCheckDeviceRoot
+# undef RTDirExists
+# undef RTFileExists
+#endif
+
+/**
+ * Check whether a USB device tree root is usable
+ * @param pcszRoot the path to the root of the device tree
+ * @param fIsDeviceNodes whether this is a device node (or usbfs) tree
+ * @note returns a pointer into a static array so it will stay valid
+ */
bool USBProxyLinuxCheckDeviceRoot(const char *pcszRoot, bool fIsDeviceNodes)
{
bool fOK = false;
@@ -1535,6 +1706,12 @@ bool USBProxyLinuxCheckDeviceRoot(const char *pcszRoot, bool fIsDeviceNodes)
# undef access
#endif
+/**
+ * Get the list of USB devices supported by the system. Should be freed using
+ * @a deviceFree or something equivalent.
+ * @param pcszDevicesRoot the path to the root of the device tree
+ * @param fUseSysfs whether to use sysfs (or usbfs) for enumeration
+ */
PUSBDEVICE USBProxyLinuxGetDevices(const char *pcszDevicesRoot,
bool fUseSysfs)
{
diff --git a/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp b/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp
index 2a0efc06e..c14eb4b93 100644
--- a/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp
+++ b/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyServiceLinux.cpp $ */
+/* $Id: USBProxyServiceLinux.cpp 37618 2011-06-23 17:16:39Z vboxsync $ */
/** @file
* VirtualBox USB Proxy Service, Linux Specialization.
*/
@@ -38,6 +38,7 @@
#include <iprt/mem.h>
#include <iprt/param.h>
#include <iprt/path.h>
+#include <iprt/pipe.h>
#include <iprt/stream.h>
#include <iprt/linux/sysfs.h>
@@ -59,42 +60,13 @@
* Initialize data members.
*/
USBProxyServiceLinux::USBProxyServiceLinux(Host *aHost)
- : USBProxyService(aHost), mFile(NIL_RTFILE), mWakeupPipeR(NIL_RTFILE),
- mWakeupPipeW(NIL_RTFILE), mUsingUsbfsDevices(true /* see init */),
+ : USBProxyService(aHost), mhFile(NIL_RTFILE), mhWakeupPipeR(NIL_RTPIPE),
+ mhWakeupPipeW(NIL_RTPIPE), mUsingUsbfsDevices(true /* see init */),
mUdevPolls(0), mpWaiter(NULL)
-#ifdef UNIT_TEST
- , mpcszTestUsbfsRoot(NULL), mfTestUsbfsAccessible(false),
- mpcszTestDevicesRoot(NULL), mfTestDevicesAccessible(false),
- mrcTestMethodInitResult(VINF_SUCCESS), mpcszTestEnvUsb(NULL),
- mpcszTestEnvUsbRoot(NULL)
-#endif
{
LogFlowThisFunc(("aHost=%p\n", aHost));
}
-#ifdef UNIT_TEST
-/* For testing we redefine anything that accesses the outside world to
- * return test values. */
-# define RTEnvGet(a) \
- ( !RTStrCmp(a, "VBOX_USB") ? mpcszTestEnvUsb \
- : !RTStrCmp(a, "VBOX_USB_ROOT") ? mpcszTestEnvUsbRoot \
- : NULL)
-# define USBProxyLinuxCheckDeviceRoot(pcszPath, fUseNodes) \
- ( ((fUseNodes) && mfTestDevicesAccessible \
- && !RTStrCmp(pcszPath, mpcszTestDevicesRoot)) \
- || (!(fUseNodes) && mfTestUsbfsAccessible \
- && !RTStrCmp(pcszPath, mpcszTestUsbfsRoot)))
-# define RTDirExists(pcszDir) \
- ( (pcszDir) \
- && ( !RTStrCmp(pcszDir, mpcszTestDevicesRoot) \
- || !RTStrCmp(pcszDir, mpcszTestUsbfsRoot)))
-# define RTFileExists(pcszFile) \
- ( (pcszFile) \
- && mpcszTestUsbfsRoot \
- && !RTStrNCmp(pcszFile, mpcszTestUsbfsRoot, strlen(mpcszTestUsbfsRoot)) \
- && !RTStrCmp(pcszFile + strlen(mpcszTestUsbfsRoot), "/devices"))
-#endif
-
/**
* Initializes the object (called right after construction).
*
@@ -102,96 +74,21 @@ USBProxyServiceLinux::USBProxyServiceLinux(Host *aHost)
*/
HRESULT USBProxyServiceLinux::init(void)
{
- /*
- * Call the superclass method first.
- */
- HRESULT hrc = USBProxyService::init();
- AssertComRCReturn(hrc, hrc);
-
- /*
- * We have two methods available for getting host USB device data - using
- * USBFS and using sysfs. The default choice is sysfs; if that is not
- * available we fall back to USBFS.
- * In the event of both failing, an appropriate error will be returned.
- * The user may also specify a method and root using the VBOX_USB and
- * VBOX_USB_ROOT environment variables. In this case we don't check
- * the root they provide for validity.
- */
- bool fUsbfsChosen = false, fSysfsChosen = false;
- const char *pcszUsbFromEnv = RTEnvGet("VBOX_USB");
- const char *pcszUsbRoot = NULL;
- if (pcszUsbFromEnv)
- {
- bool fValidVBoxUSB = true;
-
- pcszUsbRoot = RTEnvGet("VBOX_USB_ROOT");
- if (!RTStrICmp(pcszUsbFromEnv, "USBFS"))
- {
- LogRel(("Default USB access method set to \"usbfs\" from environment\n"));
- fUsbfsChosen = true;
- }
- else if (!RTStrICmp(pcszUsbFromEnv, "SYSFS"))
- {
- LogRel(("Default USB method set to \"sysfs\" from environment\n"));
- fSysfsChosen = true;
- }
- else
- {
- LogRel(("Invalid VBOX_USB environment variable setting \"%s\"\n",
- pcszUsbFromEnv));
- fValidVBoxUSB = false;
- pcszUsbFromEnv = NULL;
- }
- if (!fValidVBoxUSB && pcszUsbRoot)
- pcszUsbRoot = NULL;
- }
- if (!pcszUsbRoot)
- {
- if ( !fUsbfsChosen
- && USBProxyLinuxCheckDeviceRoot("/dev/vboxusb", true))
- {
- fSysfsChosen = true;
- pcszUsbRoot = "/dev/vboxusb";
- }
- else if ( !fSysfsChosen
- && USBProxyLinuxCheckDeviceRoot("/proc/bus/usb", false))
- {
- fUsbfsChosen = true;
- pcszUsbRoot = "/proc/bus/usb";
- }
- }
- else if (!USBProxyLinuxCheckDeviceRoot(pcszUsbRoot, fSysfsChosen))
- pcszUsbRoot = NULL;
- if (pcszUsbRoot)
+ const char *pcszDevicesRoot;
+ int rc = USBProxyLinuxChooseMethod(&mUsingUsbfsDevices, &pcszDevicesRoot);
+ if (RT_SUCCESS(rc))
{
- mUsingUsbfsDevices = fUsbfsChosen;
- mDevicesRoot = pcszUsbRoot;
-#ifndef UNIT_TEST /* Hack for now */
- int rc = mUsingUsbfsDevices ? initUsbfs() : initSysfs();
-#else
- int rc = mrcTestMethodInitResult;
-#endif
+ mDevicesRoot = pcszDevicesRoot;
+ rc = mUsingUsbfsDevices ? initUsbfs() : initSysfs();
/* For the day when we have VBoxSVC release logging... */
LogRel((RT_SUCCESS(rc) ? "Successfully initialised host USB using %s\n"
: "Failed to initialise host USB using %s\n",
mUsingUsbfsDevices ? "USBFS" : "sysfs"));
- mLastError = rc;
}
- else
- mLastError = pcszUsbFromEnv ? VERR_NOT_FOUND
- : RTDirExists("/dev/vboxusb") ? VERR_VUSB_USB_DEVICE_PERMISSION
- : RTFileExists("/proc/bus/usb/devices") ? VERR_VUSB_USBFS_PERMISSION
- : VERR_NOT_FOUND;
+ mLastError = rc;
return S_OK;
}
-#ifdef UNIT_TEST
-# undef RTEnvGet
-# undef USBProxyLinuxCheckDeviceRoot
-# undef RTDirExists
-# undef RTFileExists
-#endif
-
/**
* Initialization routine for the usbfs based operation.
*
@@ -208,48 +105,30 @@ int USBProxyServiceLinux::initUsbfs(void)
char *pszDevices = RTPathJoinA(mDevicesRoot.c_str(), "devices");
if (pszDevices)
{
- rc = RTFileOpen(&mFile, pszDevices, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ rc = RTFileOpen(&mhFile, pszDevices, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (RT_SUCCESS(rc))
{
- int pipes[2];
- if (!pipe(pipes))
+ rc = RTPipeCreate(&mhWakeupPipeR, &mhWakeupPipeW, 0 /*fFlags*/);
+ if (RT_SUCCESS(rc))
{
- /* Set close on exec (race here!) */
- if ( fcntl(pipes[0], F_SETFD, FD_CLOEXEC) >= 0
- && fcntl(pipes[1], F_SETFD, FD_CLOEXEC) >= 0)
- {
- mWakeupPipeR = pipes[0];
- mWakeupPipeW = pipes[1];
- /*
- * Start the poller thread.
- */
- rc = start();
- if (RT_SUCCESS(rc))
- {
- RTStrFree(pszDevices);
- LogFlowThisFunc(("returns successfully - mWakeupPipeR/W=%d/%d\n",
- mWakeupPipeR, mWakeupPipeW));
- return VINF_SUCCESS;
- }
-
- RTFileClose(mWakeupPipeR);
- RTFileClose(mWakeupPipeW);
- mWakeupPipeW = mWakeupPipeR = NIL_RTFILE;
- }
- else
+ /*
+ * Start the poller thread.
+ */
+ rc = start();
+ if (RT_SUCCESS(rc))
{
- rc = RTErrConvertFromErrno(errno);
- Log(("USBProxyServiceLinux::USBProxyServiceLinux: fcntl failed, errno=%d\n", errno));
- close(pipes[0]);
- close(pipes[1]);
+ RTStrFree(pszDevices);
+ LogFlowThisFunc(("returns successfully\n"));
+ return VINF_SUCCESS;
}
+
+ RTPipeClose(mhWakeupPipeR);
+ RTPipeClose(mhWakeupPipeW);
+ mhWakeupPipeW = mhWakeupPipeR = NIL_RTPIPE;
}
else
- {
- rc = RTErrConvertFromErrno(errno);
- Log(("USBProxyServiceLinux::USBProxyServiceLinux: pipe failed, errno=%d\n", errno));
- }
- RTFileClose(mFile);
+ Log(("USBProxyServiceLinux::USBProxyServiceLinux: RTFilePipe failed with rc=%Rrc\n", rc));
+ RTFileClose(mhFile);
}
RTStrFree(pszDevices);
@@ -331,17 +210,12 @@ void USBProxyServiceLinux::doUsbfsCleanupAsNeeded()
/*
* Free resources.
*/
- if (mFile != NIL_RTFILE)
- {
- RTFileClose(mFile);
- mFile = NIL_RTFILE;
- }
+ RTFileClose(mhFile);
+ mhFile = NIL_RTFILE;
- if (mWakeupPipeR != NIL_RTFILE)
- RTFileClose(mWakeupPipeR);
- if (mWakeupPipeW != NIL_RTFILE)
- RTFileClose(mWakeupPipeW);
- mWakeupPipeW = mWakeupPipeR = NIL_RTFILE;
+ RTPipeClose(mhWakeupPipeR);
+ RTPipeClose(mhWakeupPipeW);
+ mhWakeupPipeW = mhWakeupPipeR = NIL_RTPIPE;
}
@@ -433,9 +307,9 @@ int USBProxyServiceLinux::waitUsbfs(RTMSINTERVAL aMillies)
}
memset(&PollFds, 0, sizeof(PollFds));
- PollFds[0].fd = mFile;
+ PollFds[0].fd = RTFileToNative(mhFile);
PollFds[0].events = POLLIN;
- PollFds[1].fd = mWakeupPipeR;
+ PollFds[1].fd = RTPipeToNative(mhWakeupPipeR);
PollFds[1].events = POLLIN | POLLERR | POLLHUP;
int rc = poll(&PollFds[0], 2, aMillies);
@@ -447,7 +321,7 @@ int USBProxyServiceLinux::waitUsbfs(RTMSINTERVAL aMillies)
if (PollFds[1].revents & POLLIN)
{
char szBuf[WAKE_UP_STRING_LEN];
- rc = RTFileRead(mWakeupPipeR, szBuf, sizeof(szBuf), NULL);
+ rc = RTPipeReadBlocking(mhWakeupPipeR, szBuf, sizeof(szBuf), NULL);
AssertRC(rc);
}
return VINF_SUCCESS;
@@ -483,9 +357,9 @@ int USBProxyServiceLinux::interruptWait(void)
return VINF_SUCCESS;
}
#endif /* VBOX_USB_WITH_SYSFS */
- int rc = RTFileWrite(mWakeupPipeW, WAKE_UP_STRING, WAKE_UP_STRING_LEN, NULL);
+ int rc = RTPipeWriteBlocking(mhWakeupPipeW, WAKE_UP_STRING, WAKE_UP_STRING_LEN, NULL);
if (RT_SUCCESS(rc))
- RTFileFlush(mWakeupPipeW);
+ RTPipeFlush(mhWakeupPipeW);
LogFlowFunc(("returning %Rrc\n", rc));
return rc;
}
diff --git a/src/VBox/Main/src-server/os2/NetIf-os2.cpp b/src/VBox/Main/src-server/os2/NetIf-os2.cpp
index d0c287b52..70162e42b 100644
--- a/src/VBox/Main/src-server/os2/NetIf-os2.cpp
+++ b/src/VBox/Main/src-server/os2/NetIf-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: NetIf-os2.cpp $ */
+/* $Id: NetIf-os2.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Main - NetIfList, OS/2 implementation.
*/
diff --git a/src/VBox/Main/src-server/os2/PerformanceOs2.cpp b/src/VBox/Main/src-server/os2/PerformanceOs2.cpp
index 19e804a93..a741ef02c 100644
--- a/src/VBox/Main/src-server/os2/PerformanceOs2.cpp
+++ b/src/VBox/Main/src-server/os2/PerformanceOs2.cpp
@@ -1,4 +1,4 @@
-/* $Id: PerformanceOs2.cpp $ */
+/* $Id: PerformanceOs2.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
*
diff --git a/src/VBox/Main/src-server/os2/USBProxyServiceOs2.cpp b/src/VBox/Main/src-server/os2/USBProxyServiceOs2.cpp
index 34af0a088..22ba59ba0 100644
--- a/src/VBox/Main/src-server/os2/USBProxyServiceOs2.cpp
+++ b/src/VBox/Main/src-server/os2/USBProxyServiceOs2.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyServiceOs2.cpp $ */
+/* $Id: USBProxyServiceOs2.cpp 31892 2010-08-24 08:00:51Z vboxsync $ */
/** @file
* VirtualBox USB Proxy Service, OS/2 Specialization.
*/
diff --git a/src/VBox/Main/src-server/solaris/DynLoadLibSolaris.cpp b/src/VBox/Main/src-server/solaris/DynLoadLibSolaris.cpp
index 4bd864f16..aea962e58 100644
--- a/src/VBox/Main/src-server/solaris/DynLoadLibSolaris.cpp
+++ b/src/VBox/Main/src-server/solaris/DynLoadLibSolaris.cpp
@@ -1,4 +1,4 @@
-/* $Id: DynLoadLibSolaris.cpp $ */
+/* $Id: DynLoadLibSolaris.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Dynamically load libraries for Solaris hosts.
*/
diff --git a/src/VBox/Main/src-server/solaris/DynLoadLibSolaris.h b/src/VBox/Main/src-server/solaris/DynLoadLibSolaris.h
index 4fc35b8ac..64b91f14c 100644
--- a/src/VBox/Main/src-server/solaris/DynLoadLibSolaris.h
+++ b/src/VBox/Main/src-server/solaris/DynLoadLibSolaris.h
@@ -1,4 +1,4 @@
-/* $Id: DynLoadLibSolaris.h $ */
+/* $Id: DynLoadLibSolaris.h 31340 2010-08-03 14:29:43Z vboxsync $ */
/** @file
* Dynamically loaded libraries for Solaris hosts, Internal header.
*/
diff --git a/src/VBox/Main/src-server/solaris/NetIf-solaris.cpp b/src/VBox/Main/src-server/solaris/NetIf-solaris.cpp
index b9bb415ba..95dc68db4 100644
--- a/src/VBox/Main/src-server/solaris/NetIf-solaris.cpp
+++ b/src/VBox/Main/src-server/solaris/NetIf-solaris.cpp
@@ -1,10 +1,10 @@
-/* $Id: NetIf-solaris.cpp $ */
+/* $Id: NetIf-solaris.cpp 37662 2011-06-28 11:41:49Z vboxsync $ */
/** @file
* Main - NetIfList, Solaris implementation.
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -37,7 +37,6 @@
#include <fcntl.h>
#include <unistd.h>
#include <stropts.h>
-#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <libdevinfo.h>
@@ -61,17 +60,20 @@ static void vboxSolarisAddHostIface(char *pszIface, int Instance, void *pvHostNe
if (SolarisNICMap.empty())
{
SolarisNICMap.insert(NICPair("afe", "ADMtek Centaur/Comet Fast Ethernet"));
+ SolarisNICMap.insert(NICPair("atge", "Atheros/Attansic Gigabit Ethernet"));
SolarisNICMap.insert(NICPair("aggr", "Link Aggregation Interface"));
+ SolarisNICMap.insert(NICPair("bfe", "Broadcom BCM4401 Fast Ethernet"));
SolarisNICMap.insert(NICPair("bge", "Broadcom BCM57xx Gigabit Ethernet"));
SolarisNICMap.insert(NICPair("bnx", "Broadcom NetXtreme Gigabit Ethernet"));
+ SolarisNICMap.insert(NICPair("bnxe", "Broadcom NetXtreme II 10 Gigabit Ethernet"));
SolarisNICMap.insert(NICPair("ce", "Cassini Gigabit Ethernet"));
SolarisNICMap.insert(NICPair("chxge", "Chelsio Ethernet"));
- SolarisNICMap.insert(NICPair("dmfe", "Davicom Fast Ethernet"));
+ SolarisNICMap.insert(NICPair("dmfe", "Davicom 9102 Fast Ethernet"));
SolarisNICMap.insert(NICPair("dnet", "DEC 21040/41 21140 Ethernet"));
SolarisNICMap.insert(NICPair("e1000", "Intel PRO/1000 Gigabit Ethernet"));
SolarisNICMap.insert(NICPair("e1000g", "Intel PRO/1000 Gigabit Ethernet"));
- SolarisNICMap.insert(NICPair("elx", "3COM EtherLink III Ethernet"));
- SolarisNICMap.insert(NICPair("elxl", "3COM Ethernet"));
+ SolarisNICMap.insert(NICPair("elx", "3COM Etherlink III Ethernet"));
+ SolarisNICMap.insert(NICPair("elxl", "3COM Etherlink XL Ethernet"));
SolarisNICMap.insert(NICPair("eri", "eri Fast Ethernet"));
SolarisNICMap.insert(NICPair("ge", "GEM Gigabit Ethernet"));
SolarisNICMap.insert(NICPair("hme", "SUNW,hme Fast-Ethernet"));
@@ -79,6 +81,7 @@ static void vboxSolarisAddHostIface(char *pszIface, int Instance, void *pvHostNe
SolarisNICMap.insert(NICPair("igb", "Intel 82575 PCI-E Gigabit Ethernet"));
SolarisNICMap.insert(NICPair("ipge", "PCI-E Gigabit Ethernet"));
SolarisNICMap.insert(NICPair("iprb", "Intel 82557/58/59 Ethernet"));
+ SolarisNICMap.insert(NICPair("ixgbe", "Intel 10 Gigabit PCI-E Ethernet"));
SolarisNICMap.insert(NICPair("mxfe", "Macronix 98715 Fast Ethernet"));
SolarisNICMap.insert(NICPair("nfo", "Nvidia Gigabit Ethernet"));
SolarisNICMap.insert(NICPair("nge", "Nvidia Gigabit Ethernet"));
@@ -87,13 +90,16 @@ static void vboxSolarisAddHostIface(char *pszIface, int Instance, void *pvHostNe
SolarisNICMap.insert(NICPair("qfe", "SUNW,qfe Quad Fast-Ethernet"));
SolarisNICMap.insert(NICPair("rge", "Realtek Gigabit Ethernet"));
SolarisNICMap.insert(NICPair("rtls", "Realtek 8139 Fast Ethernet"));
+ SolarisNICMap.insert(NICPair("sfe", "SiS900 Fast Ethernet"));
SolarisNICMap.insert(NICPair("skge", "SksKonnect Gigabit Ethernet"));
SolarisNICMap.insert(NICPair("spwr", "SMC EtherPower II 10/100 (9432) Ethernet"));
SolarisNICMap.insert(NICPair("vboxnet", "VirtualBox Host Ethernet"));
SolarisNICMap.insert(NICPair("vboxvnic_template", "VirtualBox Virtual Network Interface Template"));
SolarisNICMap.insert(NICPair("vlan", "Virtual LAN Ethernet"));
+ SolarisNICMap.insert(NICPair("vr", "VIA Rhine Fast Ethernet"));
SolarisNICMap.insert(NICPair("vnic", "Virtual Network Interface Ethernet"));
SolarisNICMap.insert(NICPair("xge", "Neterior Xframe 10Gigabit Ethernet"));
+ SolarisNICMap.insert(NICPair("yge", "Marvell Yukon 2 Fast Ethernet"));
}
/*
diff --git a/src/VBox/Main/src-server/solaris/PerformanceSolaris.cpp b/src/VBox/Main/src-server/solaris/PerformanceSolaris.cpp
index 37d3a9163..035f80d18 100644
--- a/src/VBox/Main/src-server/solaris/PerformanceSolaris.cpp
+++ b/src/VBox/Main/src-server/solaris/PerformanceSolaris.cpp
@@ -1,4 +1,4 @@
-/* $Id: PerformanceSolaris.cpp $ */
+/* $Id: PerformanceSolaris.cpp 36090 2011-02-25 15:53:28Z vboxsync $ */
/** @file
*
@@ -260,4 +260,3 @@ int CollectorSolaris::getProcessMemoryUsage(RTPROCESS process, ULONG *used)
}
}
-
diff --git a/src/VBox/Main/src-server/solaris/USBProxyServiceSolaris.cpp b/src/VBox/Main/src-server/solaris/USBProxyServiceSolaris.cpp
index f1016be6d..dd2764a21 100644
--- a/src/VBox/Main/src-server/solaris/USBProxyServiceSolaris.cpp
+++ b/src/VBox/Main/src-server/solaris/USBProxyServiceSolaris.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyServiceSolaris.cpp $ */
+/* $Id: USBProxyServiceSolaris.cpp 38016 2011-07-18 13:06:11Z vboxsync $ */
/** @file
* VirtualBox USB Proxy Service, Solaris Specialization.
*/
@@ -68,12 +68,6 @@ USBProxyServiceSolaris::USBProxyServiceSolaris (Host *aHost)
HRESULT USBProxyServiceSolaris::init(void)
{
/*
- * Call the superclass method first.
- */
- HRESULT hrc = USBProxyService::init();
- AssertComRCReturn(hrc, hrc);
-
- /*
* Create semaphore.
*/
int rc = RTSemEventCreate(&mNotifyEventSem);
@@ -166,61 +160,6 @@ PUSBDEVICE USBProxyServiceSolaris::getDevices(void)
return DevList.pHead;
}
-#if 0
-static int solarisWalkMinor(di_node_t Node, di_minor_t Minor, void *pvArg)
-{
- char *pszDevFsPath = di_devfs_path(Node);
- char *pszMinorName = di_minor_name(Minor);
- PUSBDEVICE pDev = (PUSBDEVICE)pvArg;
-
- AssertRelease(pDev);
-
- if (!pszDevFsPath || !pszMinorName)
- return DI_WALK_CONTINUE;
-
- RTStrAPrintf(&pDev->pszApId, "/devices%s:%s", pszDevFsPath, pszMinorName);
- di_devfs_path_free(pszDevFsPath);
-
- syslog(LOG_ERR, "VBoxUsbApId:%s\n", pDev->pszApId);
- return DI_WALK_TERMINATE;
-}
-
-static bool solarisGetApId(PUSBDEVICE pDev, char *pszDevicePath, di_node_t RootNode)
-{
- pDev->pszApId = NULL;
-
- /* Skip "/devices" prefix if any */
- char achDevicesDir[] = "/devices/";
- if (strncmp(pszDevicePath, achDevicesDir, sizeof(achDevicesDir)) == 0)
- pszDevicePath += sizeof(achDevicesDir);
-
- char *pszPhysical = RTStrDup(pszDevicePath);
- char *pszTmp = NULL;
-
- /* Remove dynamic component "::" if any */
- if ((pszTmp = strstr(pszPhysical, "::")) != NULL)
- *pszTmp = '\0';
-
- /* Remove minor name if any */
- if ((pszTmp = strrchr(pszPhysical, ':')) != NULL)
- *pszTmp = '\0';
-
- /* Walk device tree */
-// di_node_t RootNode = di_init("/", DINFOCPYALL);
-// if (RootNode != DI_NODE_NIL)
-// {
-// di_node_t MinorNode = di_lookup_node(RootNode, pszPhysical);
-// if (MinorNode != DI_NODE_NIL)
- {
- di_walk_minor(RootNode, NULL, DI_CHECK_ALIAS | DI_CHECK_INTERNAL_PATH, pDev, solarisWalkMinor);
- return true;
- }
-// di_fini(RootNode);
-// }
-
- return false;
-}
-#endif
static int solarisWalkDeviceNode(di_node_t Node, void *pvArg)
{
@@ -321,25 +260,6 @@ static int solarisWalkDeviceNode(di_node_t Node, void *pvArg)
else
pCur->bPort = 0;
-#if 0
- /*
- * Obtain the dev_t of the device.
- */
- di_minor_t Minor = di_minor_next(Node, DI_MINOR_NIL);
- AssertBreak(Minor != DI_MINOR_NIL);
- dev_t DeviceNum = di_minor_devt(Minor);
-
- int DevInstance = 0;
- rc = solarisUSBGetInstance(pszDevicePath, &DevInstance);
-
- char szAddress[PATH_MAX + 128];
- RTStrPrintf(szAddress, sizeof(szAddress), "/dev/usb/%x.%x|%s", pCur->idVendor, pCur->idProduct, pszDevicePath);
- /* @todo after binding ugen we need to append the instance number to the address. Not yet sure how we can update PUSBDEVICE at that time. */
-
- pCur->pszAddress = RTStrDup(szAddress);
- AssertBreak(pCur->pszAddress);
-#endif
-
char pathBuf[PATH_MAX];
RTStrPrintf(pathBuf, sizeof(pathBuf), "%s", pszDevicePath);
RTPathStripFilename(pathBuf);
@@ -373,20 +293,16 @@ static int solarisWalkDeviceNode(di_node_t Node, void *pvArg)
/* Determine state of the USB device. */
pCur->enmState = solarisDetermineUSBDeviceState(pCur, Node);
-// fValidDevice = solarisGetApId(pCur, pszDevicePath, Node);
- fValidDevice = true;
-
/*
* Valid device, add it to the list.
*/
- if (fValidDevice)
- {
- pCur->pPrev = pList->pTail;
- if (pList->pTail)
- pList->pTail = pList->pTail->pNext = pCur;
- else
- pList->pTail = pList->pHead = pCur;
- }
+ fValidDevice = true;
+ pCur->pPrev = pList->pTail;
+ if (pList->pTail)
+ pList->pTail = pList->pTail->pNext = pCur;
+ else
+ pList->pTail = pList->pHead = pCur;
+
rc = DI_WALK_CONTINUE;
} while(0);
diff --git a/src/VBox/Main/src-server/win/NetIf-win.cpp b/src/VBox/Main/src-server/win/NetIf-win.cpp
index ebb8f5312..bbbeaa535 100644
--- a/src/VBox/Main/src-server/win/NetIf-win.cpp
+++ b/src/VBox/Main/src-server/win/NetIf-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: NetIf-win.cpp $ */
+/* $Id: NetIf-win.cpp 36121 2011-03-01 15:25:18Z vboxsync $ */
/** @file
* Main - NetIfList, Windows implementation.
*/
@@ -32,8 +32,8 @@
#include <windows.h>
#ifdef VBOX_WITH_NETFLT
-#include "VBox/WinNetConfig.h"
-#include "devguid.h"
+# include "VBox/VBoxNetCfg-win.h"
+# include "devguid.h"
#endif
#include <iphlpapi.h>
@@ -1000,17 +1000,17 @@ static int netIfListHostAdapters(std::list<ComObjPtr<HostNetworkInterface> > &li
IEnumNetCfgComponent *pEnumComponent;
/* we are using the INetCfg API for getting the list of miniports */
- hr = VBoxNetCfgWinQueryINetCfg(FALSE,
+ hr = VBoxNetCfgWinQueryINetCfg(&pNc, FALSE,
VBOX_APP_NAME,
- &pNc,
+ 10000,
&lpszApp);
Assert(hr == S_OK);
if (hr == S_OK)
{
- hr = VBoxNetCfgWinGetComponentEnum(pNc, &GUID_DEVCLASS_NET, &pEnumComponent);
+ hr = pNc->EnumComponents(&GUID_DEVCLASS_NET, &pEnumComponent);
if (hr == S_OK)
{
- while ((hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pMpNcc)) == S_OK)
+ while ((hr = pEnumComponent->Next(1, &pMpNcc, NULL)) == S_OK)
{
ULONG uComponentStatus;
hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
@@ -1031,15 +1031,15 @@ static int netIfListHostAdapters(std::list<ComObjPtr<HostNetworkInterface> > &li
}
}
}
- VBoxNetCfgWinReleaseRef(pMpNcc);
+ pMpNcc->Release();
}
Assert(hr == S_OK || hr == S_FALSE);
- VBoxNetCfgWinReleaseRef(pEnumComponent);
+ pEnumComponent->Release();
}
else
{
- LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
+ LogRel((__FUNCTION__": EnumComponents error (0x%x)", hr));
}
VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
@@ -1441,9 +1441,9 @@ int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
int iDefault = getDefaultInterfaceIndex();
/* we are using the INetCfg API for getting the list of miniports */
- hr = VBoxNetCfgWinQueryINetCfg(FALSE,
+ hr = VBoxNetCfgWinQueryINetCfg(&pNc, FALSE,
VBOX_APP_NAME,
- &pNc,
+ 10000,
&lpszApp);
Assert(hr == S_OK);
if (hr == S_OK)
@@ -1465,54 +1465,65 @@ int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
if (hr == S_OK)
{
- hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
+ INetCfgComponentBindings *pBindings;
+ hr = pTcpIpNcc->QueryInterface(IID_INetCfgComponentBindings, (PVOID*)&pBindings);
Assert(hr == S_OK);
if (hr == S_OK)
{
- hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
- Assert(hr == S_OK || hr == S_FALSE);
- while (hr == S_OK)
+ hr = pBindings->EnumBindingPaths(EBP_BELOW, &pEnumBp);
+ Assert(hr == S_OK);
+ if (hr == S_OK)
{
- /* S_OK == enabled, S_FALSE == disabled */
- if (pBp->IsEnabled() == S_OK)
+ hr = pEnumBp->Reset();
+ Assert(hr == S_OK);
+ if (hr == S_OK)
{
- hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
- Assert(hr == S_OK);
- if ( hr == S_OK )
+ while ((hr = pEnumBp->Next(1, &pBp, NULL)) == S_OK)
{
- hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
- Assert(hr == S_OK);
- while (hr == S_OK)
+ /* S_OK == enabled, S_FALSE == disabled */
+ if (pBp->IsEnabled() == S_OK)
{
- hr = pBi->GetLowerComponent( &pMpNcc );
+ hr = pBp->EnumBindingInterfaces(&pEnumBi);
Assert(hr == S_OK);
- if (hr == S_OK)
+ if ( hr == S_OK )
{
- ULONG uComponentStatus;
- hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
+ hr = pEnumBi->Reset();
+ Assert(hr == S_OK);
if (hr == S_OK)
{
- if (uComponentStatus == 0)
+ while ((hr = pEnumBi->Next(1, &pBi, NULL)) == S_OK)
{
- vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged, iDefault);
+ hr = pBi->GetLowerComponent( &pMpNcc );
+ Assert(hr == S_OK);
+ if (hr == S_OK)
+ {
+ ULONG uComponentStatus;
+ hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
+ if (hr == S_OK)
+ {
+ if (uComponentStatus == 0)
+ {
+ vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged, iDefault);
+ }
+ }
+ pMpNcc->Release();
+ }
+ pBi->Release();
}
+ Assert(hr == S_OK || hr == S_FALSE);
}
- VBoxNetCfgWinReleaseRef( pMpNcc );
+ pEnumBi->Release();
}
- VBoxNetCfgWinReleaseRef(pBi);
-
- hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
}
- VBoxNetCfgWinReleaseRef(pEnumBi);
+ pBp->Release();
}
+ Assert(hr == S_OK || hr == S_FALSE);
}
- VBoxNetCfgWinReleaseRef(pBp);
-
- hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
+ pEnumBp->Release();
}
- VBoxNetCfgWinReleaseRef(pEnumBp);
+ pBindings->Release();
}
- VBoxNetCfgWinReleaseRef(pTcpIpNcc);
+ pTcpIpNcc->Release();
}
else
{
diff --git a/src/VBox/Main/src-server/win/PerformanceWin.cpp b/src/VBox/Main/src-server/win/PerformanceWin.cpp
index 2fc96b5d8..96ee57d57 100644
--- a/src/VBox/Main/src-server/win/PerformanceWin.cpp
+++ b/src/VBox/Main/src-server/win/PerformanceWin.cpp
@@ -1,4 +1,4 @@
-/* $Id: PerformanceWin.cpp $ */
+/* $Id: PerformanceWin.cpp 35368 2010-12-30 13:38:23Z vboxsync $ */
/** @file
*
diff --git a/src/VBox/Main/src-server/win/USBProxyServiceWindows.cpp b/src/VBox/Main/src-server/win/USBProxyServiceWindows.cpp
index fbb0c4a78..d763e8eb8 100644
--- a/src/VBox/Main/src-server/win/USBProxyServiceWindows.cpp
+++ b/src/VBox/Main/src-server/win/USBProxyServiceWindows.cpp
@@ -1,4 +1,4 @@
-/* $Id: USBProxyServiceWindows.cpp $ */
+/* $Id: USBProxyServiceWindows.cpp 37599 2011-06-22 21:06:38Z vboxsync $ */
/** @file
* VirtualBox USB Proxy Service, Windows Specialization.
*/
@@ -52,12 +52,6 @@ USBProxyServiceWindows::USBProxyServiceWindows(Host *aHost)
HRESULT USBProxyServiceWindows::init(void)
{
/*
- * Call the superclass method first.
- */
- HRESULT hrc = USBProxyService::init();
- AssertComRCReturn(hrc, hrc);
-
- /*
* Create the semaphore (considered fatal).
*/
mhEventInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
@@ -142,49 +136,64 @@ void USBProxyServiceWindows::removeFilter(void *aID)
int USBProxyServiceWindows::captureDevice(HostUSBDevice *aDevice)
{
- AssertReturn(aDevice, VERR_GENERAL_FAILURE);
- AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
- Assert(aDevice->getUnistate() == kHostUSBDeviceState_Capturing);
-
-/** @todo pass up a one-shot filter like on darwin? */
- USHORT vendorId, productId, revision;
-
- HRESULT rc;
-
- rc = aDevice->COMGETTER(VendorId)(&vendorId);
- AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
-
- rc = aDevice->COMGETTER(ProductId)(&productId);
- AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
+ /*
+ * Create a one-shot ignore filter for the device
+ * and trigger a re-enumeration of it.
+ */
+ USBFILTER Filter;
+ USBFilterInit(&Filter, USBFILTERTYPE_ONESHOT_CAPTURE);
+ initFilterFromDevice(&Filter, aDevice);
+ Log(("USBFILTERIDX_PORT=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_PORT)));
+ Log(("USBFILTERIDX_BUS=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_BUS)));
+
+ void *pvId = USBLibAddFilter(&Filter);
+ if (!pvId)
+ {
+ AssertMsgFailed(("Add one-shot Filter failed\n"));
+ return VERR_GENERAL_FAILURE;
+ }
- rc = aDevice->COMGETTER(Revision)(&revision);
- AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
+ int rc = USBLibRunFilters();
+ if (!RT_SUCCESS(rc))
+ {
+ AssertMsgFailed(("Run Filters failed\n"));
+ USBLibRemoveFilter(pvId);
+ return rc;
+ }
- return USBLibCaptureDevice(vendorId, productId, revision);
+ return VINF_SUCCESS;
}
int USBProxyServiceWindows::releaseDevice(HostUSBDevice *aDevice)
{
- AssertReturn(aDevice, VERR_GENERAL_FAILURE);
- AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
- Assert(aDevice->getUnistate() == kHostUSBDeviceState_ReleasingToHost);
-
-/** @todo pass up a one-shot filter like on darwin? */
- USHORT vendorId, productId, revision;
- HRESULT rc;
-
- rc = aDevice->COMGETTER(VendorId)(&vendorId);
- AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
+ /*
+ * Create a one-shot ignore filter for the device
+ * and trigger a re-enumeration of it.
+ */
+ USBFILTER Filter;
+ USBFilterInit(&Filter, USBFILTERTYPE_ONESHOT_IGNORE);
+ initFilterFromDevice(&Filter, aDevice);
+ Log(("USBFILTERIDX_PORT=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_PORT)));
+ Log(("USBFILTERIDX_BUS=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_BUS)));
+
+ void *pvId = USBLibAddFilter(&Filter);
+ if (!pvId)
+ {
+ AssertMsgFailed(("Add one-shot Filter failed\n"));
+ return VERR_GENERAL_FAILURE;
+ }
- rc = aDevice->COMGETTER(ProductId)(&productId);
- AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
+ int rc = USBLibRunFilters();
+ if (!RT_SUCCESS(rc))
+ {
+ AssertMsgFailed(("Run Filters failed\n"));
+ USBLibRemoveFilter(pvId);
+ return rc;
+ }
- rc = aDevice->COMGETTER(Revision)(&revision);
- AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
- Log(("USBProxyServiceWindows::releaseDevice\n"));
- return USBLibReleaseDevice(vendorId, productId, revision);
+ return VINF_SUCCESS;
}
@@ -222,41 +231,15 @@ bool USBProxyServiceWindows::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVIC
int USBProxyServiceWindows::wait(unsigned aMillies)
{
- DWORD rc;
-
- /* Not going to do something fancy where we block in the filter
- * driver and are woken up when the state has changed.
- * Would be better, but this is good enough.
- */
- do
- {
- rc = WaitForSingleObject(mhEventInterrupt, RT_MIN(aMillies, 100));
- if (rc == WAIT_OBJECT_0)
- return VINF_SUCCESS;
- /** @todo handle WAIT_FAILED here */
-
- if (USBLibHasPendingDeviceChanges() == true)
- {
- Log(("wait thread detected usb change\n"));
- return VINF_SUCCESS;
- }
-
- if (aMillies > 100)
- aMillies -= 100;
- }
- while (aMillies > 100);
-
- return VERR_TIMEOUT;
+ return USBLibWaitChange(aMillies);
}
int USBProxyServiceWindows::interruptWait(void)
{
- SetEvent(mhEventInterrupt);
- return VINF_SUCCESS;
+ return USBLibInterruptWaitChange();
}
-
/**
* Gets a list of all devices the VM can grab
*/
diff --git a/src/VBox/Main/src-server/win/VBoxSVC.rc b/src/VBox/Main/src-server/win/VBoxSVC.rc
index b7ac5fdcd..aec838f34 100644
--- a/src/VBox/Main/src-server/win/VBoxSVC.rc
+++ b/src/VBox/Main/src-server/win/VBoxSVC.rc
@@ -1,4 +1,4 @@
-/* $Id: VBoxSVC.rc $ */
+/* $Id: VBoxSVC.rc 35368 2010-12-30 13:38:23Z vboxsync $ */
/** @file
* VBoxSVC - Resource file containing version info and icon.
*/
diff --git a/src/VBox/Main/src-server/win/svcmain.cpp b/src/VBox/Main/src-server/win/svcmain.cpp
index 3b23a8b4c..4021cfabc 100644
--- a/src/VBox/Main/src-server/win/svcmain.cpp
+++ b/src/VBox/Main/src-server/win/svcmain.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -15,10 +15,14 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
+#include <Windows.h>
#include <stdio.h>
+#include <stdlib.h>
#include "VBox/com/defs.h"
+#include "VBox/com/com.h"
+
#include "VBox/com/VirtualBox.h"
#include "VirtualBoxImpl.h"
@@ -27,7 +31,12 @@
#include "svchlp.h"
#include <VBox/err.h>
+#include <iprt/buildconfig.h>
#include <iprt/initterm.h>
+#include <iprt/string.h>
+#include <iprt/uni.h>
+#include <iprt/path.h>
+#include <iprt/getopt.h>
#include <atlbase.h>
#include <atlcom.h>
@@ -145,117 +154,228 @@ static int WordCmpI(LPCTSTR psz1, LPCTSTR psz2) throw()
/////////////////////////////////////////////////////////////////////////////
//
-extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
- HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nShowCmd*/)
{
+ LPCTSTR lpCmdLine = GetCommandLine(); /* this line necessary for _ATL_MIN_CRT */
+
+ /* Need to parse the command line before initializing the VBox runtime. */
+ TCHAR szTokens[] = _T("-/");
+ LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
+ while (lpszToken != NULL)
+ {
+ if (WordCmpI(lpszToken, _T("Embedding")) == 0)
+ {
+ /* %HOMEDRIVE%%HOMEPATH% */
+ wchar_t wszHome[RTPATH_MAX];
+ DWORD cEnv = GetEnvironmentVariable(L"HOMEDRIVE", &wszHome[0], RTPATH_MAX);
+ if (cEnv && cEnv < RTPATH_MAX)
+ {
+ DWORD cwc = cEnv; /* doesn't include NUL */
+ cEnv = GetEnvironmentVariable(L"HOMEPATH", &wszHome[cEnv], RTPATH_MAX - cwc);
+ if (cEnv && cEnv < RTPATH_MAX - cwc)
+ {
+ /* If this fails there is nothing we can do. Ignore. */
+ SetCurrentDirectory(wszHome);
+ }
+ }
+ }
+
+ lpszToken = FindOneOf(lpszToken, szTokens);
+ }
+
/*
* Initialize the VBox runtime without loading
* the support driver.
*/
RTR3Init();
- lpCmdLine = GetCommandLine(); /* this line necessary for _ATL_MIN_CRT */
+ /* Note that all options are given lowercase/camel case/uppercase to
+ * approximate case insensitive matching, which RTGetOpt doesn't offer. */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--embedding", 'e', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
+ { "-embedding", 'e', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
+ { "/embedding", 'e', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
+ { "--unregserver", 'u', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
+ { "-unregserver", 'u', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
+ { "/unregserver", 'u', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
+ { "--regserver", 'r', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
+ { "-regserver", 'r', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
+ { "/regserver", 'r', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
+ { "--reregserver", 'f', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
+ { "-reregserver", 'f', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
+ { "/reregserver", 'f', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
+ { "--helper", 'H', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE },
+ { "-helper", 'H', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE },
+ { "/helper", 'H', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE },
+ { "--logfile", 'F', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE },
+ { "-logfile", 'F', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE },
+ { "/logfile", 'F', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE },
+ { "--logrotate", 'R', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE },
+ { "-logrotate", 'R', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE },
+ { "/logrotate", 'R', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE },
+ { "--logsize", 'S', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_ICASE },
+ { "-logsize", 'S', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_ICASE },
+ { "/logsize", 'S', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_ICASE },
+ { "--loginterval", 'I', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE },
+ { "-loginterval", 'I', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE },
+ { "/loginterval", 'I', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE },
+ };
+
+ bool fRun = true;
+ bool fRegister = false;
+ bool fUnregister = false;
+ const char *pszPipeName = NULL;
+ const char *pszLogFile = NULL;
+ uint32_t cHistory = 10; // enable log rotation, 10 files
+ uint32_t uHistoryFileTime = RT_SEC_1DAY; // max 1 day per file
+ uint64_t uHistoryFileSize = 100 * _1M; // max 100MB per file
+
+ RTGETOPTSTATE GetOptState;
+ int vrc = RTGetOptInit(&GetOptState, __argc, __argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, 0 /*fFlags*/);
+ AssertRC(vrc);
+
+ RTGETOPTUNION ValueUnion;
+ while ((vrc = RTGetOpt(&GetOptState, &ValueUnion)))
+ {
+ switch (vrc)
+ {
+ case 'e':
+ /* already handled above */
+ break;
+
+ case 'u':
+ fUnregister = true;
+ fRun = false;
+ break;
+
+ case 'r':
+ fRegister = true;
+ fRun = false;
+ break;
+
+ case 'f':
+ fUnregister = true;
+ fRegister = true;
+ fRun = false;
+ break;
+
+ case 'H':
+ pszPipeName = ValueUnion.psz;
+ if (!pszPipeName)
+ pszPipeName = "";
+ fRun = false;
+ break;
+
+ case 'F':
+ pszLogFile = ValueUnion.psz;
+ break;
+
+ case 'R':
+ cHistory = ValueUnion.u32;
+ break;
+
+ case 'S':
+ uHistoryFileSize = ValueUnion.u64;
+ break;
+
+ case 'I':
+ uHistoryFileTime = ValueUnion.u32;
+ break;
+
+ case 'h':
+ {
+ TCHAR txt[]= L"Options:\n\n"
+ L"/RegServer:\tregister COM out-of-proc server\n"
+ L"/UnregServer:\tunregister COM out-of-proc server\n"
+ L"/ReregServer:\tunregister and register COM server\n"
+ L"no options:\trun the server";
+ TCHAR title[]=_T("Usage");
+ fRun = false;
+ MessageBox(NULL, txt, title, MB_OK);
+ return 0;
+ }
+
+ case 'V':
+ {
+ char *psz = NULL;
+ RTStrAPrintf(&psz, "%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr());
+ PRTUTF16 txt = NULL;
+ RTStrToUtf16(psz, &txt);
+ TCHAR title[]=_T("Version");
+ fRun = false;
+ MessageBox(NULL, txt, title, MB_OK);
+ RTStrFree(psz);
+ RTUtf16Free(txt);
+ return 0;
+ }
+
+ default:
+ /** @todo this assumes that stderr is visible, which is not
+ * true for standard Windows applications. */
+ /* continue on command line errors... */
+ RTGetOptPrintError(vrc, &ValueUnion);
+ }
+ }
+
+ /* Only create the log file when running VBoxSVC normally, but not when
+ * registering/unregistering or calling the helper functionality. */
+ if (fRun)
+ {
+ if (!pszLogFile)
+ {
+ char szLogFile[RTPATH_MAX];
+ vrc = com::GetVBoxUserHomeDirectory(szLogFile, sizeof(szLogFile));
+ if (RT_SUCCESS(vrc))
+ vrc = RTPathAppend(szLogFile, sizeof(szLogFile), "VBoxSVC.log");
+ if (RT_SUCCESS(vrc))
+ pszLogFile = RTStrDup(szLogFile);
+ }
+ VBoxSVCLogRelCreate(pszLogFile, cHistory, uHistoryFileTime, uHistoryFileSize);
+ }
+
+ int nRet = 0;
+ HRESULT hRes = com::Initialize();
-#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
- HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
-#else
- HRESULT hRes = CoInitialize(NULL);
-#endif
_ASSERTE(SUCCEEDED(hRes));
_Module.Init(ObjectMap, hInstance, &LIBID_VirtualBox);
_Module.dwThreadID = GetCurrentThreadId();
- TCHAR szTokens[] = _T("-/");
- int nRet = 0;
- BOOL bRun = TRUE;
- LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
- while (lpszToken != NULL)
+ if (!fRun)
{
- if (WordCmpI(lpszToken, _T("UnregServer")) == 0)
+ if (fUnregister)
{
_Module.UpdateRegistryFromResource(IDR_VIRTUALBOX, FALSE);
nRet = _Module.UnregisterServer(TRUE);
- bRun = FALSE;
- break;
}
- else if (WordCmpI(lpszToken, _T("RegServer")) == 0)
+ if (fRegister)
{
_Module.UpdateRegistryFromResource(IDR_VIRTUALBOX, TRUE);
nRet = _Module.RegisterServer(TRUE);
- bRun = FALSE;
- break;
}
- else if (WordCmpI(lpszToken, _T("ReregServer")) == 0)
+ if (pszPipeName)
{
- _Module.UpdateRegistryFromResource(IDR_VIRTUALBOX, FALSE);
- nRet = _Module.UnregisterServer(TRUE);
- _Module.UpdateRegistryFromResource(IDR_VIRTUALBOX, TRUE);
- nRet = _Module.RegisterServer(TRUE);
- bRun = FALSE;
- break;
- }
- else if ( (WordCmpI(lpszToken, _T("h")) == 0)
- || (WordCmpI(lpszToken, _T("?")) == 0))
- {
- TCHAR txt[]= L"Options:\n\n"
- L"/RegServer:\tregister COM out-of-proc server\n"
- L"/UnregServer:\tunregister COM out-of-proc server\n"
- L"/ReregServer:\tunregister and register COM server\n"
- L"no options:\trun the server";
- TCHAR title[]=_T("Usage");
- nRet = -1;
- bRun = FALSE;
- MessageBox(NULL, txt, title, MB_OK);
- break;
- }
- else if (WordCmpI (lpszToken, _T("Helper")) == 0)
- {
- Log (("SVCMAIN: Processing Helper request (cmdline=\"%ls\")...\n",
- lpszToken + 6));
-
- TCHAR szTokens[] = _T (" \t");
+ Log(("SVCMAIN: Processing Helper request (cmdline=\"%s\")...\n", pszPipeName));
- int vrc = VINF_SUCCESS;
- Utf8Str pipeName;
-
- lpszToken = FindOneOf (lpszToken, szTokens);
- if (lpszToken)
- {
- while (*lpszToken != NULL &&
- (*lpszToken == ' ' || *lpszToken == '\t'))
- ++ lpszToken;
-
- if (*lpszToken != NULL)
- pipeName = Utf8Str(lpszToken);
- }
-
- if (pipeName.isEmpty())
+ if (!*pszPipeName)
vrc = VERR_INVALID_PARAMETER;
if (RT_SUCCESS(vrc))
{
/* do the helper job */
SVCHlpServer server;
- vrc = server.open(pipeName.c_str());
+ vrc = server.open(pszPipeName);
if (RT_SUCCESS(vrc))
vrc = server.run();
}
if (RT_FAILURE(vrc))
{
- Utf8Str err = Utf8StrFmt (
- "Failed to process Helper request (%Rrc).", vrc);
- Log (("SVCMAIN: %s\n", err.c_str()));
+ Log(("SVCMAIN: Failed to process Helper request (%Rrc).", vrc));
+ nRet = 1;
}
-
- /* don't run the COM server */
- bRun = FALSE;
- break;
}
-
- lpszToken = FindOneOf(lpszToken, szTokens);
}
-
- if (bRun)
+ else
{
_Module.StartMonitor();
#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
@@ -276,7 +396,9 @@ extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
}
_Module.Term();
- CoUninitialize();
+
+ com::Shutdown();
+
Log(("SVCMAIN: Returning, COM server process ends.\n"));
return nRet;
}
diff --git a/src/VBox/Main/src-server/xpcom/server.cpp b/src/VBox/Main/src-server/xpcom/server.cpp
index ee81e4fd9..f521f21d8 100644
--- a/src/VBox/Main/src-server/xpcom/server.cpp
+++ b/src/VBox/Main/src-server/xpcom/server.cpp
@@ -1,4 +1,4 @@
-/* $Id: server.cpp $ */
+/* $Id: server.cpp 37666 2011-06-28 12:33:34Z vboxsync $ */
/** @file
* XPCOM server process (VBoxSVC) start point.
*/
@@ -42,6 +42,7 @@
#include <iprt/critsect.h>
#include <iprt/getopt.h>
#include <iprt/message.h>
+#include <iprt/string.h>
#include <iprt/stream.h>
#include <iprt/path.h>
#include <iprt/timer.h>
@@ -60,42 +61,42 @@
/////////////////////////////////////////////////////////////////////////////
#include <nsIGenericFactory.h>
-
#include <VirtualBox_XPCOM.h>
-#include <VirtualBoxImpl.h>
-#include <MachineImpl.h>
-#include <VFSExplorerImpl.h>
-#include <ApplianceImpl.h>
-#include <SnapshotImpl.h>
-#include <MediumImpl.h>
-#include <MediumFormatImpl.h>
-#include <ProgressCombinedImpl.h>
-#include <ProgressProxyImpl.h>
-#include <VRDEServerImpl.h>
-#include <SharedFolderImpl.h>
-#include <HostImpl.h>
-#include <HostNetworkInterfaceImpl.h>
-#include <GuestOSTypeImpl.h>
-#include <NetworkAdapterImpl.h>
-#include <NATEngineImpl.h>
-#include <SerialPortImpl.h>
-#include <ParallelPortImpl.h>
-#include <USBControllerImpl.h>
+
+#include "ApplianceImpl.h"
+#include "AudioAdapterImpl.h"
+#include "BandwidthControlImpl.h"
+#include "BandwidthGroupImpl.h"
#include "DHCPServerRunner.h"
#include "DHCPServerImpl.h"
+#include "GuestOSTypeImpl.h"
+#include "HostImpl.h"
+#include "HostNetworkInterfaceImpl.h"
+#include "MachineImpl.h"
+#include "MediumFormatImpl.h"
+#include "MediumImpl.h"
+#include "NATEngineImpl.h"
+#include "NetworkAdapterImpl.h"
+#include "ParallelPortImpl.h"
+#include "ProgressCombinedImpl.h"
+#include "ProgressProxyImpl.h"
+#include "SerialPortImpl.h"
+#include "SharedFolderImpl.h"
+#include "SnapshotImpl.h"
+#include "StorageControllerImpl.h"
+#include "SystemPropertiesImpl.h"
+#include "USBControllerImpl.h"
+#include "VFSExplorerImpl.h"
+#include "VirtualBoxImpl.h"
+#include "VRDEServerImpl.h"
#ifdef VBOX_WITH_USB
+# include "HostUSBDeviceImpl.h"
# include "USBDeviceFilterImpl.h"
-# include <HostUSBDeviceImpl.h>
-# include <USBDeviceImpl.h>
+# include "USBDeviceImpl.h"
#endif
-#include <StorageControllerImpl.h>
-#include <AudioAdapterImpl.h>
-#include <SystemPropertiesImpl.h>
#ifdef VBOX_WITH_EXTPACK
-# include <ExtPackManagerImpl.h>
+# include "ExtPackManagerImpl.h"
#endif
-#include <BandwidthGroupImpl.h>
-#include <BandwidthControlImpl.h>
/* implement nsISupports parts of our objects with support for nsIClassInfo */
@@ -791,12 +792,20 @@ int main(int argc, char **argv)
static const RTGETOPTDEF s_aOptions[] =
{
- { "--automate", 'a', RTGETOPT_REQ_NOTHING },
- { "--auto-shutdown", 'A', RTGETOPT_REQ_NOTHING },
- { "--daemonize", 'd', RTGETOPT_REQ_NOTHING },
- { "--pidfile", 'p', RTGETOPT_REQ_STRING },
+ { "--automate", 'a', RTGETOPT_REQ_NOTHING },
+ { "--auto-shutdown", 'A', RTGETOPT_REQ_NOTHING },
+ { "--daemonize", 'd', RTGETOPT_REQ_NOTHING },
+ { "--pidfile", 'p', RTGETOPT_REQ_STRING },
+ { "--logfile", 'F', RTGETOPT_REQ_STRING },
+ { "--logrotate", 'R', RTGETOPT_REQ_UINT32 },
+ { "--logsize", 'S', RTGETOPT_REQ_UINT64 },
+ { "--loginterval", 'I', RTGETOPT_REQ_UINT32 }
};
+ const char *pszLogFile = NULL;
+ uint32_t cHistory = 10; // enable log rotation, 10 files
+ uint32_t uHistoryFileTime = RT_SEC_1DAY; // max 1 day per file
+ uint64_t uHistoryFileSize = 100 * _1M; // max 100MB per file
bool fDaemonize = false;
PRFileDesc *daemon_pipe_wr = nsnull;
@@ -819,7 +828,7 @@ int main(int argc, char **argv)
break;
}
- /* Used together with '-P', see below. Internal use only. */
+ /* --auto-shutdown mode means we're already daemonized. */
case 'A':
{
gAutoShutdown = true;
@@ -838,6 +847,22 @@ int main(int argc, char **argv)
break;
}
+ case 'F':
+ pszLogFile = ValueUnion.psz;
+ break;
+
+ case 'R':
+ cHistory = ValueUnion.u32;
+ break;
+
+ case 'S':
+ uHistoryFileSize = ValueUnion.u64;
+ break;
+
+ case 'I':
+ uHistoryFileTime = ValueUnion.u32;
+ break;
+
case 'h':
{
RTPrintf("no help\n");
@@ -861,7 +886,18 @@ int main(int argc, char **argv)
exit(126);
}
- nsresult rc;
+ nsresult rc;
+
+ if (!pszLogFile)
+ {
+ char szLogFile[RTPATH_MAX];
+ vrc = com::GetVBoxUserHomeDirectory(szLogFile, sizeof(szLogFile));
+ if (RT_SUCCESS(vrc))
+ vrc = RTPathAppend(szLogFile, sizeof(szLogFile), "VBoxSVC.log");
+ if (RT_SUCCESS(vrc))
+ pszLogFile = RTStrDup(szLogFile);
+ }
+ VBoxSVCLogRelCreate(pszLogFile, cHistory, uHistoryFileTime, uHistoryFileSize);
daemon_pipe_wr = PR_GetInheritedFD(VBOXSVC_STARTUP_PIPE_NAME);
RTEnvUnset("NSPR_INHERIT_FDS");
diff --git a/src/VBox/Main/src-server/xpcom/server_module.cpp b/src/VBox/Main/src-server/xpcom/server_module.cpp
index a7cb1835f..0647016c1 100644
--- a/src/VBox/Main/src-server/xpcom/server_module.cpp
+++ b/src/VBox/Main/src-server/xpcom/server_module.cpp
@@ -48,6 +48,7 @@
#include <VBox/err.h>
+#include <iprt/assert.h>
#include <iprt/param.h>
#include <iprt/path.h>
#include <iprt/process.h>
diff --git a/src/VBox/Main/testcase/Makefile.kmk b/src/VBox/Main/testcase/Makefile.kmk
index aca0c05a4..7b7531491 100644
--- a/src/VBox/Main/testcase/Makefile.kmk
+++ b/src/VBox/Main/testcase/Makefile.kmk
@@ -1,10 +1,10 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37883 2011-07-12 09:53:58Z vboxsync $
## @file
# Sub-Makefile for the VBox API testcases.
#
#
-# Copyright (C) 2006-2007 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;
@@ -27,9 +27,9 @@ ifndef VBOX_ONLY_SDK
tstAPI \
$(if $(VBOX_OSE),,tstOVF) \
$(if $(VBOX_WITH_XPCOM),tstVBoxAPILinux,tstVBoxAPIWin) \
- $(if $(VBOX_WITH_RESOURCE_USAGE_API),tstCollector,)
+ $(if $(VBOX_WITH_RESOURCE_USAGE_API),tstCollector,) \
+ $(if $(VBOX_WITH_GUEST_CONTROL),tstGuestCtrlParseBuffer,)
PROGRAMS.linux += \
- $(if $(VBOX_WITH_USB),tstHostHardwareLinux,) \
$(if $(VBOX_WITH_USB),tstUSBProxyLinux,)
endif # !VBOX_WITH_TESTCASES
endif # !VBOX_ONLY_SDK
@@ -143,27 +143,11 @@ tstCollector_LDFLAGS.darwin += -lproc
tstCollector_LDFLAGS.solaris += -lkstat
tstCollector_LDFLAGS.win += psapi.lib powrprof.lib
-
-
#
-# tstHostHardwareLinux
+# tstGuestCtrlParseBuffer
#
-tstHostHardwareLinux_TEMPLATE = VBOXR3TSTNPEXE
-tstHostHardwareLinux_SOURCES = \
- tstHostHardwareLinux.cpp \
- ../src-server/linux/HostHardwareLinux.cpp \
- ../src-server/linux/USBGetDevices.cpp
-tstHostHardwareLinux_INCS = . ../include
-tstHostHardwareLinux_DEFS = \
- VBOX_TEST_USB_LINUX \
- TESTCASE \
- $(if $(VBOX_WITH_LINUX_COMPILER_H),VBOX_WITH_LINUX_COMPILER_H,) \
- $(if $(VBOX_WITH_DBUS),$(if $(VBOX_USB_WITH_DBUS),VBOX_USB_WITH_DBUS,),) \
- $(if $(VBOX_USB_WITH_SYSFS),VBOX_USB_WITH_SYSFS,) \
- $(if $(VBOX_USB_WITH_INOTIFY),VBOX_USB_WITH_INOTIFY,)
-tstHostHardwareLinux_LIBS += \
- $(PATH_OUT)/lib/USBLib.a
-
+tstGuestCtrlParseBuffer_TEMPLATE = VBOXR3TSTNPEXE
+tstGuestCtrlParseBuffer_SOURCES = tstGuestCtrlParseBuffer.cpp
#
# tstUSBProxyLinux
diff --git a/src/VBox/Main/testcase/tstAPI.cpp b/src/VBox/Main/testcase/tstAPI.cpp
index 160bd101d..f388ab272 100644
--- a/src/VBox/Main/testcase/tstAPI.cpp
+++ b/src/VBox/Main/testcase/tstAPI.cpp
@@ -1221,7 +1221,8 @@ int main(int argc, char *argv[])
// Fill base metrics array
- Bstr baseMetricNames[] = { L"CPU/Load,RAM/Usage" };
+ //Bstr baseMetricNames[] = { L"CPU/Load,RAM/Usage" };
+ Bstr baseMetricNames[] = { L"RAM/VMM" };
com::SafeArray<BSTR> baseMetrics(1);
baseMetricNames[0].cloneTo(&baseMetrics[0]);
@@ -1234,27 +1235,26 @@ int main(int argc, char *argv[])
Bstr name = argc > 1 ? argv[1] : "dsl";
Bstr sessionType = argc > 2 ? argv[2] : "headless";
RTPrintf("Getting a machine object named '%ls'...\n", name.raw());
- CHECK_RC_BREAK(virtualBox->FindMachine(name, machine.asOutParam()));
+ CHECK_ERROR_BREAK(virtualBox, FindMachine(name.raw(), machine.asOutParam()));
// Open session
- Guid guid;
- CHECK_RC_BREAK(machine->COMGETTER(Id)(guid.asOutParam()));
- RTPrintf("Opening a remote session for this machine...\n");
ComPtr<IProgress> progress;
- CHECK_RC_BREAK(virtualBox->OpenRemoteSession(session, guid, sessionType,
- NULL, progress.asOutParam()));
- RTPrintf("Waiting for the session to open...\n");
- CHECK_RC_BREAK(progress->WaitForCompletion(-1));
- ComPtr<IMachine> sessionMachine;
- RTPrintf("Getting machine session object...\n");
- CHECK_RC_BREAK(session->COMGETTER(Machine)(sessionMachine.asOutParam()));
+ RTPrintf("Launching VM process...\n");
+ CHECK_ERROR_BREAK(machine, LaunchVMProcess(session, sessionType.raw(),
+ NULL, progress.asOutParam()));
+ RTPrintf("Waiting for the VM to power on...\n");
+ CHECK_ERROR_BREAK(progress, WaitForCompletion(-1));
+
+ // ComPtr<IMachine> sessionMachine;
+ // RTPrintf("Getting machine session object...\n");
+ // CHECK_ERROR_BREAK(session, COMGETTER(Machine)(sessionMachine.asOutParam()));
// Setup base metrics
// Note that one needs to set up metrics after a session is open for a machine.
com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
- com::SafeIfaceArray<IUnknown> objects(2);
+ com::SafeIfaceArray<IUnknown> objects(1);
host.queryInterfaceTo(&objects[0]);
- machine.queryInterfaceTo(&objects[1]);
+ //machine.queryInterfaceTo(&objects[1]);
CHECK_ERROR_BREAK(collector, SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
ComSafeArrayAsInParam(objects), 1u, 10u,
ComSafeArrayAsOutParam(affectedMetrics)));
@@ -1265,7 +1265,7 @@ int main(int argc, char *argv[])
// Get console
ComPtr<IConsole> console;
RTPrintf("Getting console object...\n");
- CHECK_RC_BREAK(session->COMGETTER(Console)(console.asOutParam()));
+ CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));
RTThreadSleep(5000); // Sleep for 5 seconds
@@ -1275,7 +1275,7 @@ int main(int argc, char *argv[])
// Pause
//RTPrintf("Press enter to pause the VM execution in the remote session...");
//getchar();
- CHECK_RC(console->Pause());
+ CHECK_ERROR_BREAK(console, Pause());
RTThreadSleep(5000); // Sleep for 5 seconds
@@ -1320,10 +1320,12 @@ int main(int argc, char *argv[])
// Power off
RTPrintf("Press enter to power off VM...");
getchar();
- CHECK_RC(console->PowerDown());
+ CHECK_ERROR_BREAK(console, PowerDown(progress.asOutParam()));
+ RTPrintf("Waiting for the VM to power down...\n");
+ CHECK_ERROR_BREAK(progress, WaitForCompletion(-1));
RTPrintf("Press enter to close this session...");
getchar();
- session->Close();
+ session->UnlockMachine();
} while (false);
#endif /* VBOX_WITH_RESOURCE_USAGE_API */
#if 0
diff --git a/src/VBox/Main/testcase/tstCollector.cpp b/src/VBox/Main/testcase/tstCollector.cpp
index 32e52ccdc..ab31b42b9 100644
--- a/src/VBox/Main/testcase/tstCollector.cpp
+++ b/src/VBox/Main/testcase/tstCollector.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstCollector.cpp $ */
+/* $Id: tstCollector.cpp 35368 2010-12-30 13:38:23Z vboxsync $ */
/** @file
*
diff --git a/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp b/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp
new file mode 100644
index 000000000..c34c1a154
--- /dev/null
+++ b/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp
@@ -0,0 +1,302 @@
+/* $Id: tstGuestCtrlParseBuffer.cpp 37974 2011-07-15 09:46:23Z vboxsync $ */
+
+/** @file
+ *
+ * Output stream parsing test cases.
+ */
+
+/*
+ * 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.
+ */
+
+#include <map>
+
+#include <iprt/string.h>
+#include <iprt/cpp/ministring.h>
+
+#include <iprt/test.h>
+#include <iprt/stream.h>
+
+#ifndef BYTE
+# define BYTE uint8_t
+#endif
+
+/** @todo Use original source of GuestCtrlImpl.cpp! */
+
+typedef struct VBOXGUESTCTRL_BUFFER_VALUE
+{
+ char *pszValue;
+} VBOXGUESTCTRL_BUFFER_VALUE, *PVBOXGUESTCTRL_BUFFER_VALUE;
+typedef std::map< RTCString, VBOXGUESTCTRL_BUFFER_VALUE > GuestBufferMap;
+typedef std::map< RTCString, VBOXGUESTCTRL_BUFFER_VALUE >::iterator GuestBufferMapIter;
+typedef std::map< RTCString, VBOXGUESTCTRL_BUFFER_VALUE >::const_iterator GuestBufferMapIterConst;
+
+char szUnterm1[] = { 'a', 's', 'd', 'f' };
+char szUnterm2[] = { 'f', 'o', 'o', '3', '=', 'b', 'a', 'r', '3' };
+
+static struct
+{
+ const char *pbData;
+ size_t cbData;
+ uint32_t uOffsetStart;
+ uint32_t uOffsetAfter;
+ uint32_t uMapElements;
+ int iResult;
+} aTests[] =
+{
+ /* Invalid stuff. */
+ { NULL, 0, 0, 0, 0, VERR_INVALID_POINTER },
+ { NULL, 512, 0, 0, 0, VERR_INVALID_POINTER },
+ { "", 0, 0, 0, 0, VERR_INVALID_PARAMETER },
+ { "", 0, 0, 0, 0, VERR_INVALID_PARAMETER },
+ { "foo=bar1", 0, 0, 0, 0, VERR_INVALID_PARAMETER },
+ { "foo=bar2", 0, 50, 50, 0, VERR_INVALID_PARAMETER },
+ /* Incomplete buffer (missing \0 termination). */
+ { "", 1, 0, 0, 0, VERR_MORE_DATA },
+ { "\0", 1, 0, 0, 0, VERR_MORE_DATA },
+ { szUnterm1, 5, 0, 0, 0, VERR_MORE_DATA },
+ { "foo1", sizeof("foo1"), 0, 0, 0, VERR_MORE_DATA },
+ { szUnterm2, 8, 0, 0, 0, VERR_MORE_DATA },
+ /* Incomplete buffer (missing components). */
+ { "=bar\0", sizeof("=bar"), 0, 0, 0, VERR_MORE_DATA },
+ /* Last sequence is incomplete -- new offset should point to it. */
+ { "hug=sub\0incomplete", sizeof("hug=sub\0incomplete"), 0, sizeof("hug=sub"), 1, VERR_MORE_DATA },
+ { "boo=hoo\0baz=boo\0qwer", sizeof("boo=hoo\0baz=boo\0qwer"), 0, sizeof("boo=hoo\0baz=boo"), 2, VERR_MORE_DATA },
+ /* Parsing good stuff. */
+ { "foo2=", sizeof("foo2="), 0, sizeof("foo2="), 1, VINF_SUCCESS },
+ { "har=hor", sizeof("har=hor"), 0, sizeof("har=hor"), 1, VINF_SUCCESS },
+ { "foo=bar\0baz=boo", sizeof("foo=bar\0baz=boo"), 0, sizeof("foo=bar\0baz=boo"), 2, VINF_SUCCESS },
+ /* Parsing until a different block (two terminations, returning offset to next block). */
+ { "off=rab\0\0zab=oob", sizeof("off=rab\0\0zab=oob"), 0, sizeof("zab=oob"), 1, VERR_MORE_DATA }
+};
+
+static struct
+{
+ const char *pbData;
+ size_t cbData;
+ /** Number of data blocks retrieved. These are separated by "\0\0". */
+ uint32_t uNumBlocks;
+ /** Overall result when done parsing. */
+ int iResult;
+} aTests2[] =
+{
+ { "off=rab\0\0zab=oob", sizeof("off=rab\0\0zab=oob"), 2, VINF_SUCCESS },
+ { "\0\0\0soo=foo\0goo=loo\0\0zab=oob", sizeof("\0\0\0soo=foo\0goo=loo\0\0zab=oob"), 2, VINF_SUCCESS },
+ { "qoo=uoo\0\0\0\0asdf=\0\0", sizeof("qoo=uoo\0\0\0\0asdf=\0\0"), 2, VINF_SUCCESS },
+ { "foo=bar\0\0\0\0\0\0", sizeof("foo=bar\0\0\0\0\0\0"), 1, VINF_SUCCESS }
+};
+
+int outputBufferParse(const BYTE *pbData, size_t cbData, uint32_t *puOffset, GuestBufferMap& mapBuf)
+{
+ AssertPtrReturn(pbData, VERR_INVALID_POINTER);
+ AssertReturn(cbData, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(puOffset, VERR_INVALID_POINTER);
+ AssertReturn(*puOffset < cbData, VERR_INVALID_PARAMETER);
+
+ int rc = VINF_SUCCESS;
+
+ size_t uCur = *puOffset;
+ for (;uCur < cbData;)
+ {
+ const char *pszStart = (char*)&pbData[uCur];
+ const char *pszEnd = pszStart;
+
+ /* Search and of current pair (key=value\0). */
+ while (uCur++ < cbData)
+ {
+ if (*pszEnd == '\0')
+ break;
+ pszEnd++;
+ }
+
+ size_t uPairLen = pszEnd - pszStart;
+ if ( *pszEnd != '\0'
+ || !uPairLen)
+ {
+ rc = VERR_MORE_DATA;
+ break;
+ }
+
+ const char *pszSep = pszStart;
+ while ( *pszSep != '='
+ && pszSep != pszEnd)
+ {
+ pszSep++;
+ }
+
+ if ( pszSep == pszStart
+ || pszSep == pszEnd)
+ {
+ rc = VERR_MORE_DATA;
+ break;
+ }
+
+ size_t uKeyLen = pszSep - pszStart;
+ size_t uValLen = pszEnd - (pszSep + 1);
+
+ /* Get key (if present). */
+ if (uKeyLen)
+ {
+ Assert(pszSep > pszStart);
+ char *pszKey = (char*)RTMemAllocZ(uKeyLen + 1);
+ if (!pszKey)
+ {
+ rc = VERR_NO_MEMORY;
+ break;
+ }
+ memcpy(pszKey, pszStart, uKeyLen);
+
+ mapBuf[RTCString(pszKey)].pszValue = NULL;
+
+ /* Get value (if present). */
+ if (uValLen)
+ {
+ Assert(pszEnd > pszSep);
+ char *pszVal = (char*)RTMemAllocZ(uValLen + 1);
+ if (!pszVal)
+ {
+ rc = VERR_NO_MEMORY;
+ break;
+ }
+ memcpy(pszVal, pszSep + 1, uValLen);
+
+ mapBuf[RTCString(pszKey)].pszValue = pszVal;
+ }
+
+ RTMemFree(pszKey);
+
+ *puOffset += uCur - *puOffset;
+ }
+ }
+
+ return rc;
+}
+
+void tstOutputAndDestroyMap(GuestBufferMap &bufMap)
+{
+ for (GuestBufferMapIter it = bufMap.begin(); it != bufMap.end(); it++)
+ {
+ RTTestIPrintf(RTTESTLVL_DEBUG, "\t%s -> %s\n",
+ it->first.c_str(), it->second.pszValue ? it->second.pszValue : "<undefined>");
+
+ if (it->second.pszValue)
+ RTMemFree(it->second.pszValue);
+ }
+
+ bufMap.clear();
+}
+
+int main()
+{
+ RTTEST hTest;
+ int rc = RTTestInitAndCreate("tstParseBuffer", &hTest);
+ if (rc)
+ return rc;
+ RTTestBanner(hTest);
+
+ RTTestIPrintf(RTTESTLVL_INFO, "Doing basic tests ...\n");
+
+ if (sizeof("sizecheck") != 10)
+ RTTestFailed(hTest, "Basic size test failed (%u <-> 10)", sizeof("sizecheck"));
+
+ RTTestIPrintf(RTTESTLVL_INFO, "Doing line tests ...\n");
+
+ for (unsigned iTest = 0; iTest < RT_ELEMENTS(aTests); iTest++)
+ {
+ GuestBufferMap bufMap;
+
+ int iResult = outputBufferParse((BYTE*)aTests[iTest].pbData, aTests[iTest].cbData,
+ &aTests[iTest].uOffsetStart, bufMap);
+
+ RTTestIPrintf(RTTESTLVL_DEBUG, "=> Test #%u\n", iTest);
+
+ if (iResult != aTests[iTest].iResult)
+ {
+ RTTestFailed(hTest, "\tReturned %Rrc, expected %Rrc",
+ iResult, aTests[iTest].iResult);
+ }
+ else if (bufMap.size() != aTests[iTest].uMapElements)
+ {
+ RTTestFailed(hTest, "\tMap has %u elements, expected %u",
+ bufMap.size(), aTests[iTest].uMapElements);
+ }
+ else if (aTests[iTest].uOffsetStart != aTests[iTest].uOffsetAfter)
+ {
+ RTTestFailed(hTest, "\tOffset %u wrong, expected %u",
+ aTests[iTest].uOffsetStart, aTests[iTest].uOffsetAfter);
+ }
+ else if (iResult == VERR_MORE_DATA)
+ {
+ /* There is remaining data left in the buffer (which needs to be merged
+ * with a following buffer) -- print it. */
+ const char *pszRemaining = aTests[iTest].pbData;
+ size_t uOffsetNew = aTests[iTest].uOffsetStart;
+ size_t uToWrite = aTests[iTest].cbData - uOffsetNew;
+ if (pszRemaining && uOffsetNew)
+ {
+ RTTestIPrintf(RTTESTLVL_DEBUG, "\tRemaining (%u):\n", uToWrite);
+ RTStrmWriteEx(g_pStdOut, &aTests[iTest].pbData[uOffsetNew], uToWrite - 1, NULL);
+ RTTestIPrintf(RTTESTLVL_DEBUG, "\n");
+ }
+ }
+
+ tstOutputAndDestroyMap(bufMap);
+ }
+
+ RTTestIPrintf(RTTESTLVL_INFO, "Doing block tests ...\n");
+
+ for (unsigned iTest = 0; iTest < RT_ELEMENTS(aTests2); iTest++)
+ {
+ RTTestIPrintf(RTTESTLVL_DEBUG, "=> Block test #%u\n", iTest);
+
+ int iResult;
+
+ GuestBufferMap bufMap;
+ uint32_t uOffset = 0;
+ uint32_t uNumBlocks = 0;
+
+ while (uOffset < aTests2[iTest].cbData)
+ {
+ iResult = outputBufferParse((BYTE*)aTests2[iTest].pbData, aTests2[iTest].cbData,
+ &uOffset, bufMap);
+ RTTestIPrintf(RTTESTLVL_DEBUG, "\tReturned with %Rrc\n", iResult);
+ if ( iResult == VINF_SUCCESS
+ || iResult == VERR_MORE_DATA)
+ {
+ if (bufMap.size()) /* Only count block which have some valid data. */
+ uNumBlocks++;
+
+ tstOutputAndDestroyMap(bufMap);
+
+ RTTestIPrintf(RTTESTLVL_DEBUG, "\tNext offset %u (total: %u)\n",
+ uOffset, aTests2[iTest].cbData);
+ uOffset++;
+ }
+ else
+ break;
+
+ if (uNumBlocks > 32)
+ break; /* Give up if unreasonable big. */
+ }
+
+ if (uNumBlocks != aTests2[iTest].uNumBlocks)
+ {
+ RTTestFailed(hTest, "\tReturned %u blocks, expected %u\n",
+ uNumBlocks, aTests2[iTest].uNumBlocks);
+ }
+ }
+
+ /*
+ * Summary.
+ */
+ return RTTestSummaryAndDestroy(hTest);
+}
+
diff --git a/src/VBox/Main/testcase/tstHostHardwareLinux.cpp b/src/VBox/Main/testcase/tstHostHardwareLinux.cpp
deleted file mode 100644
index 33069242c..000000000
--- a/src/VBox/Main/testcase/tstHostHardwareLinux.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/* $Id: tstHostHardwareLinux.cpp $ */
-/** @file
- *
- * Test executable for quickly excercising/debugging the Linux host hardware
- * bits.
- */
-
-/*
- * Copyright (C) 2008 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#include <HostHardwareLinux.h>
-#include <USBGetDevices.h>
-
-#include <VBox/err.h>
-
-#include <iprt/initterm.h>
-#include <iprt/param.h>
-#include <iprt/stream.h>
-#include <iprt/thread.h>
-#include <iprt/linux/sysfs.h>
-
-#include <iprt/cdefs.h>
-#include <iprt/types.h>
-
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-int doHotplugEvent(VBoxMainHotplugWaiter *waiter, RTMSINTERVAL cMillies)
-{
- int rc;
- while (true)
- {
- rc = waiter->Wait (cMillies);
- if (rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED)
- break;
- if (RT_FAILURE(rc))
- {
- RTPrintf("Failed!\n");
- exit(1);
- }
- if (RT_SUCCESS(rc))
- break;
- }
- return rc;
-}
-
-void printDevices(PUSBDEVICE pDevices,
- const char *pcszDevices,
- const char *pcszMethod)
-{
- PUSBDEVICE pDevice = pDevices;
-
- RTPrintf("Enumerating usb devices using %s at %s\n", pcszMethod, pcszDevices);
- while (pDevice)
- {
- RTPrintf(" Manufacturer: %s, product: %s, serial number string: %s\n",
- pDevice->pszManufacturer, pDevice->pszProduct,
- pDevice->pszSerialNumber);
- RTPrintf(" Device address: %s\n", pDevice->pszAddress);
- pDevice = pDevice->pNext;
- }
-}
-
-void freeDevices(PUSBDEVICE pDevices)
-{
- PUSBDEVICE pDevice = pDevices, pDeviceNext;
-
- while (pDevice)
- {
- pDeviceNext = pDevice->pNext;
- deviceFree(pDevice);
- pDevice = pDeviceNext;
- }
-}
-
-int main()
-{
- RTR3Init();
- int rc = VINF_SUCCESS;
- VBoxMainDriveInfo driveInfo;
- rc = driveInfo.updateFloppies();
- if (RT_SUCCESS(rc))
- rc = driveInfo.updateDVDs();
- if (RT_FAILURE(rc))
- {
- RTPrintf("Failed to update the host drive information, error %Rrc\n",
- rc);
- return 1;
- }
- RTPrintf ("Listing floppy drives detected:\n");
- for (DriveInfoList::const_iterator it = driveInfo.FloppyBegin();
- it != driveInfo.FloppyEnd(); ++it)
- {
- RTPrintf (" device: %s", it->mDevice.c_str());
- if (!it->mUdi.isEmpty())
- RTPrintf (", udi: %s", it->mUdi.c_str());
- if (!it->mDescription.isEmpty())
- RTPrintf (", description: %s", it->mDescription.c_str());
- RTPrintf ("\n");
- }
- RTPrintf ("Listing DVD drives detected:\n");
- for (DriveInfoList::const_iterator it = driveInfo.DVDBegin();
- it != driveInfo.DVDEnd(); ++it)
- {
- RTPrintf (" device: %s", it->mDevice.c_str());
- if (!it->mUdi.isEmpty())
- RTPrintf (", udi: %s", it->mUdi.c_str());
- if (!it->mDescription.isEmpty())
- RTPrintf (", description: %s", it->mDescription.c_str());
- RTPrintf ("\n");
- }
- RTPrintf("NOTE: checking for usbfs at /dev/bus/usb, not /proc/bus/usb!!!\n");
- if (USBProxyLinuxCheckDeviceRoot("/dev/bus/usb", false))
- {
- PUSBDEVICE pDevice = USBProxyLinuxGetDevices("/dev/bus/usb",
- false);
- printDevices(pDevice, "/dev/bus/usb", "usbfs");
- freeDevices(pDevice);
- }
- else
- RTPrintf("-> not found\n");
-#ifdef VBOX_USB_WITH_SYSFS
- RTPrintf("Testing for USB devices at /dev/vboxusb\n");
- if (USBProxyLinuxCheckDeviceRoot("/dev/vboxusb", true))
- {
- PUSBDEVICE pDevice = USBProxyLinuxGetDevices("/dev/vboxusb",
- true);
- printDevices(pDevice, "/dev/vboxusb", "sysfs");
- freeDevices(pDevice);
- }
- else
- RTPrintf("-> not found\n");
- VBoxMainHotplugWaiter waiter("/dev/vboxusb");
- RTPrintf ("Waiting for a hotplug event for five seconds...\n");
- doHotplugEvent(&waiter, 5000);
- RTPrintf ("Waiting for a hotplug event, Ctrl-C to abort...\n");
- doHotplugEvent(&waiter, RT_INDEFINITE_WAIT);
- RTPrintf ("Testing interrupting a hotplug event...\n");
- waiter.Interrupt();
- rc = doHotplugEvent(&waiter, 5000);
- RTPrintf ("%s\n", rc == VERR_INTERRUPTED ? "Success!" : "Failed!");
-#endif /* VBOX_USB_WITH_SYSFS */
- return 0;
-}
-
diff --git a/src/VBox/Main/testcase/tstOVF.cpp b/src/VBox/Main/testcase/tstOVF.cpp
index 990424eb7..2d7345d19 100644
--- a/src/VBox/Main/testcase/tstOVF.cpp
+++ b/src/VBox/Main/testcase/tstOVF.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstOVF.cpp $ */
+/* $Id: tstOVF.cpp 37862 2011-07-11 10:09:29Z vboxsync $ */
/** @file
*
* tstOVF - testcases for OVF import and export
@@ -232,7 +232,8 @@ void importOVF(const char *pcszPrefix,
}
RTPrintf("%s: importing %d machine(s)...\n", pcszPrefix, aDescriptions.size());
- rc = pAppl->ImportMachines(pProgress.asOutParam());
+ SafeArray<ImportOptions_T> sfaOptions;
+ rc = pAppl->ImportMachines(ComSafeArrayAsInParam(sfaOptions), pProgress.asOutParam());
if (FAILED(rc)) throw MyError(rc, "Appliance::ImportMachines() failed\n");
rc = pProgress->WaitForCompletion(-1);
if (FAILED(rc)) throw MyError(rc, "Progress::WaitForCompletion() failed\n");
diff --git a/src/VBox/Main/testcase/tstUSBLinux.h b/src/VBox/Main/testcase/tstUSBLinux.h
index 5a9491a4c..91880c94f 100644
--- a/src/VBox/Main/testcase/tstUSBLinux.h
+++ b/src/VBox/Main/testcase/tstUSBLinux.h
@@ -1,4 +1,4 @@
-/* $Id: tstUSBLinux.h $ */
+/* $Id: tstUSBLinux.h 30714 2010-07-07 16:20:03Z vboxsync $ */
/** @file
* VirtualBox USB Proxy Service class, test version for Linux hosts.
*/
diff --git a/src/VBox/Main/testcase/tstUSBProxyLinux.cpp b/src/VBox/Main/testcase/tstUSBProxyLinux.cpp
index 4f7802ad0..1f9f916e3 100644
--- a/src/VBox/Main/testcase/tstUSBProxyLinux.cpp
+++ b/src/VBox/Main/testcase/tstUSBProxyLinux.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstUSBProxyLinux.cpp $ */
+/* $Id: tstUSBProxyLinux.cpp 37618 2011-06-23 17:16:39Z vboxsync $ */
/** @file
* USBProxyServiceLinux test case.
*/
@@ -72,7 +72,7 @@ void SysFreeString(BSTR bstr)
Assert(0);
}
-static struct
+static struct
{
const char *pcszEnvUsb;
const char *pcszEnvUsbRoot;
@@ -88,16 +88,12 @@ static struct
{
/* "sysfs" and valid root in the environment */
{ "sysfs", "/dev/bus/usb", "/dev/bus/usb", true, NULL, false, VINF_SUCCESS, "/dev/bus/usb", false, VINF_SUCCESS },
- /* "sysfs" and valid root in the environment, method-specific init failed */
- { "sysfs", "/dev/bus/usb", "/dev/bus/usb", true, NULL, false, VERR_NO_MEMORY, "/dev/bus/usb", false, VERR_NO_MEMORY },
/* "sysfs" and bad root in the environment */
{ "sysfs", "/dev/bus/usb", "/dev/vboxusb", false, "/proc/usb/bus", false, VINF_SUCCESS, "", true, VERR_NOT_FOUND },
/* "sysfs" and no root in the environment */
{ "sysfs", NULL, "/dev/vboxusb", true, NULL, false, VINF_SUCCESS, "/dev/vboxusb", false, VINF_SUCCESS },
/* "usbfs" and valid root in the environment */
{ "usbfs", "/dev/bus/usb", NULL, false, "/dev/bus/usb", true, VINF_SUCCESS, "/dev/bus/usb", true, VINF_SUCCESS },
- /* "usbfs" and valid root in the environment, method-specific init failed */
- { "usbfs", "/dev/bus/usb", NULL, false, "/dev/bus/usb", true, VERR_NO_MEMORY, "/dev/bus/usb", true, VERR_NO_MEMORY },
/* "usbfs" and bad root in the environment */
{ "usbfs", "/dev/bus/usb", "/dev/vboxusb", false, "/proc/usb/bus", false, VINF_SUCCESS, "", true, VERR_NOT_FOUND },
/* "usbfs" and no root in the environment */
@@ -118,42 +114,34 @@ static struct
{ NULL, NULL, "/dev/vboxusb", false, "/proc/bus/usb", true, VINF_SUCCESS, "/proc/bus/usb", true, VINF_SUCCESS },
/* No environment, sysfs available but without access permissions. */
{ NULL, NULL, "/dev/vboxusb", false, NULL, false, VERR_NO_MEMORY, "", true, VERR_VUSB_USB_DEVICE_PERMISSION },
- /* No environment, sysfs available with access permissions, method-specific init failed. */
- { NULL, NULL, "/dev/vboxusb", true, NULL, false, VERR_NO_MEMORY, "/dev/vboxusb", false, VERR_NO_MEMORY },
/* No environment, usbfs available but without access permissions. */
{ NULL, NULL, NULL, false, "/proc/bus/usb", false, VERR_NO_MEMORY, "", true, VERR_VUSB_USBFS_PERMISSION },
- /* No environment, usbfs available with access permissions, method-specific
- * init failed. */
- { NULL, NULL, NULL, false, "/proc/bus/usb", true, VERR_NO_MEMORY, "/proc/bus/usb", true, VERR_NO_MEMORY }
};
static void testInit(RTTEST hTest)
{
- RTTestSub(hTest, "Testing USBProxyServiceLinux initialisation");
+ RTTestSub(hTest, "Testing USBProxyLinuxChooseMethod");
for (unsigned i = 0; i < RT_ELEMENTS(s_testEnvironment); ++i)
{
- USBProxyServiceLinux test(NULL);
- test.testSetEnv(s_testEnvironment[i].pcszEnvUsb,
- s_testEnvironment[i].pcszEnvUsbRoot);
- test.testSetupInit(s_testEnvironment[i].pcszUsbfsRoot,
- s_testEnvironment[i].fUsbfsAccessible,
- s_testEnvironment[i].pcszDevicesRoot,
- s_testEnvironment[i].fDevicesAccessible,
- s_testEnvironment[i].rcMethodInit);
- HRESULT hrc = test.init();
- RTTESTI_CHECK_MSG(hrc == S_OK,
- ("init() returned 0x%x (test index %i)!\n", hrc, i));
- int rc = test.getLastError();
+ bool fUsingUsbfs = true;
+ const char *pcszDevicesRoot = "";
+
+ TestUSBSetEnv(s_testEnvironment[i].pcszEnvUsb,
+ s_testEnvironment[i].pcszEnvUsbRoot);
+ TestUSBSetupInit(s_testEnvironment[i].pcszUsbfsRoot,
+ s_testEnvironment[i].fUsbfsAccessible,
+ s_testEnvironment[i].pcszDevicesRoot,
+ s_testEnvironment[i].fDevicesAccessible,
+ s_testEnvironment[i].rcMethodInit);
+ int rc = USBProxyLinuxChooseMethod(&fUsingUsbfs, &pcszDevicesRoot);
RTTESTI_CHECK_MSG(rc == s_testEnvironment[i].rcExpected,
- ("getLastError() returned %Rrc (test index %i) instead of %Rrc!\n",
+ ("rc=%Rrc (test index %i) instead of %Rrc!\n",
rc, i, s_testEnvironment[i].rcExpected));
- const char *pcszDevicesRoot = test.testGetDevicesRoot();
RTTESTI_CHECK_MSG(!RTStrCmp(pcszDevicesRoot,
s_testEnvironment[i].pcszDevicesRootExpected),
("testGetDevicesRoot() returned %s (test index %i) instead of %s!\n",
pcszDevicesRoot, i,
s_testEnvironment[i].pcszDevicesRootExpected));
- bool fUsingUsbfs = test.testGetUsingUsbfs();
RTTESTI_CHECK_MSG( fUsingUsbfs
== s_testEnvironment[i].fUsingUsbfsExpected,
("testGetUsingUsbfs() returned %RTbool (test index %i) instead of %RTbool!\n",
@@ -162,7 +150,7 @@ static void testInit(RTTEST hTest)
}
}
-static struct
+static struct
{
const char *pacszDeviceAddresses[16];
const char *pacszAccessibleFiles[16];
diff --git a/src/VBox/Main/testcase/tstVBoxAPILinux.cpp b/src/VBox/Main/testcase/tstVBoxAPILinux.cpp
index abf7b20d0..6c7aa0fbe 100644
--- a/src/VBox/Main/testcase/tstVBoxAPILinux.cpp
+++ b/src/VBox/Main/testcase/tstVBoxAPILinux.cpp
@@ -7,7 +7,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;
@@ -62,7 +62,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <iconv.h>
-#include <errno.h>
/*
* Include the XPCOM headers
@@ -358,6 +357,7 @@ void createVM(IVirtualBox *virtualBox)
rc = virtualBox->OpenMedium(NS_LITERAL_STRING("/home/vbox/isos/winnt4ger.iso").get(),
DeviceType_DVD,
AccessMode_ReadOnly,
+ false /* fForceNewUuid */,
getter_AddRefs(dvdImage));
if (NS_FAILED(rc))
printf("Error: could not open CD image! rc=%08X\n", rc);
diff --git a/src/VBox/Main/testcase/tstVBoxAPIWin.cpp b/src/VBox/Main/testcase/tstVBoxAPIWin.cpp
index d3c0839c0..cd0adb485 100644
--- a/src/VBox/Main/testcase/tstVBoxAPIWin.cpp
+++ b/src/VBox/Main/testcase/tstVBoxAPIWin.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstVBoxAPIWin.cpp $ */
+/* $Id: tstVBoxAPIWin.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
*
* tstVBoxAPIWin - sample program to illustrate the VirtualBox
diff --git a/src/VBox/Main/webservice/Makefile.kmk b/src/VBox/Main/webservice/Makefile.kmk
index edebed2ab..7c7fd90a8 100644
--- a/src/VBox/Main/webservice/Makefile.kmk
+++ b/src/VBox/Main/webservice/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37999 2011-07-18 10:14:45Z vboxsync $
## @file
# Sub-Makefile for the VBox web service.
#
@@ -310,7 +310,7 @@ VBOX_JWS_JDEST := $(VBOX_JWS_TARGET)/jdest
VBOX_GLUE_XSLT_DIR := $(PATH_ROOT)/src/VBox/Main/glue
VBOX_JAXLIB_DIR := $(PATH_ROOT)/src/VBox/Main/webservice/jaxlibs
-VBoxJWs-inst-jar_INST = $(INST_SDK)bindings/webservice/java/jax-ws
+VBoxJWs-inst-jar_INST = $(INST_SDK)bindings/webservice/java/jax-ws/
VBoxJWs-inst-jar_SOURCES = \
$(VBOX_JWS_JAR)
VBoxJWs-inst-jar_CLEAN = \
@@ -435,30 +435,6 @@ ifdef VBOX_ONLY_SDK
$(shell find $(1) -name \*.java)
endef
- ifdef VBOX_WITH_OLD_JWS
- VBOX_JAXWS_LIBDIR = $(VBOX_PATH_WEBSERVICE)/jaxlibs
- # well, not really good
- VBOX_JAVA15 = $(firstword $(wildcard \
- /usr/lib/jvm/java-1.5.0-sun/bin/java \
- /usr/jdk/jdk1.5*/bin/java \
- /opt/sun-jdk-1.5*/bin/java \
- /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Commands/java))
- ifeq ($(strip $(VBOX_JAVA15)),)
- $(error Failed to autodetect VBOX_JAVA15, please set it manually)
- endif
- VBOX_JAVA16 = java
- VBOX_JAVAC15 = javac -target 1.5
- VBOX_JAVAC16 = javac -target 1.6
- VBOX_WSIMPORT15 = $(VBOX_JAVA15) -jar $(VBOX_JAXWS_LIBDIR)/jaxws-tools.jar
- VBOX_WSIMPORT16 = $(firstword $(wildcard \
- /usr/jdk/jdk1.6*/bin/wsimport \
- /usr/bin/wsimport \
- /opt/sun-jdk-1.6*/bin/wsimport))
- ifeq ($(strip $(VBOX_WSIMPORT16)),)
- $(error Failed to autodetect VBOX_WSIMPORT16, please set it manually)
- endif
- endif # VBOX_WITH_OLD_JWS
-
VBOXWEB_OTHERS += \
$(VBOXWEB_GLUE_PYTHON) \
$(VBOXWEB_WS_PYTHON) \
@@ -467,14 +443,6 @@ ifdef VBOX_ONLY_SDK
$(VBOXWEB_PYTHONWSSAMPLE) \
$(PATH_ROOT)
- ifdef VBOX_WITH_OLD_JWS
- VBOXWEB_OTHERS += \
- $(VBOXWEB_GLUE_JAVA_TMP) \
- $(VBOXWEB_JAXWSSAMPLE) \
- $(VBOXWEB_METRICSAMPLE) \
- $(VBOXWEB_JAVA15_JAR) \
- $(VBOXWEB_JAVA16_JAR)
- endif
#
# Install sample code.
@@ -494,13 +462,6 @@ ifdef VBOX_ONLY_SDK
samples/python/Makefile.glue=>python/lib/Makefile \
$(PATH_ROOT)/COPYING.LIB=>java/jax-ws/COPYING.LIB
- ifdef VBOX_WITH_OLD_JWS
- vboxwebinst_nox_SOURCES += \
- samples/java/axis/clienttest.java=>java/axis/samples/clienttest.java \
- samples/java/jax-ws/Makefile.glue=>java/jax-ws/src/Makefile \
- samples/java/jax-ws/Makefile=>java/jax-ws/samples/Makefile
- endif
-
endif # VBOX_ONLY_SDK
## @todo VBOXWEB_WSDL and VBOXWEBSERVICE_WSDL should be an install target.
@@ -684,55 +645,6 @@ $(VBOXWEB_METRICSAMPLE): $(VBOX_PATH_WEBSERVICE)/samples/java/jax-ws/metrictest.
$(QUIET)$(MKDIR) -p $(VBOXWEB_SAMPLES_JAXWS_DIR)
$(QUIET)$(SED) -e 's/{VBOX_API_SUFFIX}/$(VBOX_API_SUFFIX)/' < $< > $@
-# generate jax-ws wrapper for java client code
-$(VBOXWEB_GLUE_JAVA_TMP): \
- $(VBOXWEB_IDL_SRC) \
- $(VBOX_PATH_WEBSERVICE)/glue-jaxws.xsl \
- $(VBOX_PATH_WEBSERVICE)/websrv-shared.inc.xsl \
- $(RECOMPILE_ON_MAKEFILE_CURRENT) \
- | $$(dir $$@) \
- $(VBOX_FILESPLIT)
- $(QUIET)$(MKDIR) -p $(@D)
- $(call MSG_GENERATE,,$@,$(VBOXWEB_IDL_SRC) using glue-jaxws.xsl)
- $(QUIET)$(VBOX_XSLTPROC) $(VBOXWEB_XSLTPROC_VERBOSE) \
- --stringparam G_vboxApiSuffix $(VBOX_API_SUFFIX) \
- -o $@ $(VBOX_PATH_WEBSERVICE)/glue-jaxws.xsl $<
- $(call MSG_GENERATE,,java client glue files in $(VBOXWEB_PATH_SDK_GLUE_JAVA))
- $(RM) -R -f $(VBOXWEB_PATH_SDK_GLUE_JAVA)
- $(QUIET)$(MKDIR) -p $(VBOXWEB_PATH_SDK_GLUE_JAVA)
- $(QUIET)$(VBOX_FILESPLIT) $@ $(VBOXWEB_PATH_SDK_GLUE_JAVA)
- $(QUIET)$(CP) -f $(VBOX_PATH_WEBSERVICE)/../../../../COPYING.LIB $(VBOXWEB_PATH_SDK_GLUE_JAVA)
-
-$(VBOXWEB_GLUE_JAVA_TMP).done: $(VBOXWEB_GLUE_JAVA_TMP)
- $(QUIET)$(APPEND) $@ ''
-
-$(VBOXWEB_JAVA15_JAR): $(VBOXWEB_GLUE_JAVA_TMP).done $(VBOXWEB_WSDL) $(VBOXWEBSERVICE_WSDL)
- $(QUIET)$(RM) -Rf $(VBOXWEB_JAVALIB)/gen15
- $(QUIET)$(MKDIR) -p $(VBOXWEB_JAVALIB)/gen15
- $(call MSG_GENERATE,,$@,JAX-WS for Java 1.5 bindings using $(VBOXWEBSERVICE_WSDL))
- $(QUIET)$(VBOX_WSIMPORT15) -p $(VBOX_JAVA_PACKAGE) -d $(VBOXWEB_JAVALIB)/gen15 $(VBOXWEBSERVICE_WSDL)
- $(call MSG_L1,Compiling bridge code)
- $(QUIET)$(VBOX_JAVAC15) -cp \
- $(VBOXWEB_JAVALIB)/gen15:$(VBOX_JAXWS_LIBDIR)/jaxws-api.jar:$(VBOX_JAXWS_LIBDIR)/lib/jaxb-api.jar:$(VBOX_JAXWS_LIBDIR)/jsr181-api.jar \
- $(call find_java_files,$(VBOXWEB_PATH_SDK_GLUE_JAVA)) -d $(VBOXWEB_JAVALIB)/gen15
- $(QUIET)$(SED) -e "s/vboxweb.wsdl/vboxweb$(VBOX_API_SUFFIX).wsdl/" < $(VBOXWEBSERVICE_WSDL) > $(VBOXWEB_JAVALIB)/gen15/vboxwebService$(VBOX_API_SUFFIX).wsdl
- $(QUIET)$(CP) -f $(VBOXWEB_WSDL) $(VBOXWEB_JAVALIB)/gen15/vboxweb$(VBOX_API_SUFFIX).wsdl
- $(QUIET)$(RM) -f $(call find_java_files,$(VBOXWEB_JAVALIB))
- $(QUIET)$(VBOX_JAR) cf $@ -C $(VBOXWEB_JAVALIB)/gen15 .
-
-$(VBOXWEB_JAVA16_JAR): $(VBOXWEB_GLUE_JAVA_TMP).done $(VBOXWEB_WSDL) $(VBOXWEBSERVICE_WSDL)
- $(QUIET)$(RM) -Rf $(VBOXWEB_JAVALIB)/gen16
- $(MKDIR) -p $(VBOXWEB_JAVALIB)/gen16
- $(call MSG_GENERATE,,$@,JAX-WS for Java 1.6 bindings using $(VBOXWEBSERVICE_WSDL))
- $(QUIET)$(VBOX_WSIMPORT16) -p $(VBOX_JAVA_PACKAGE) -d $(VBOXWEB_JAVALIB)/gen16 $(VBOXWEBSERVICE_WSDL)
- $(call MSG_L1,Compiling bridge code)
- $(QUIET)$(VBOX_JAVAC16) -cp $(VBOXWEB_JAVALIB)/gen16 \
- $(VBOXWEB_PATH_SDK_GLUE_JAVA)/*.java -d $(VBOXWEB_JAVALIB)/gen16
- $(QUIET)$(SED) -e "s/vboxweb.wsdl/vboxweb$(VBOX_API_SUFFIX).wsdl/" < $(VBOXWEBSERVICE_WSDL) > $(VBOXWEB_JAVALIB)/gen16/vboxwebService$(VBOX_API_SUFFIX).wsdl
- $(QUIET)$(CP) -f $(VBOXWEB_WSDL) $(VBOXWEB_JAVALIB)/gen16/vboxweb$(VBOX_API_SUFFIX).wsdl
- $(QUIET)$(RM) -f $(call find_java_files,$(VBOXWEB_JAVALIB)/gen16)
- $(QUIET)$(VBOX_JAR) cf $@ -C $(VBOXWEB_JAVALIB)/gen16 .
-
endif # VBOX_ONLY_SDK
include $(KBUILD_PATH)/subfooter.kmk
diff --git a/src/VBox/Main/webservice/glue-jaxws.xsl b/src/VBox/Main/webservice/glue-jaxws.xsl
deleted file mode 100644
index ae871b60f..000000000
--- a/src/VBox/Main/webservice/glue-jaxws.xsl
+++ /dev/null
@@ -1,1353 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
- websrv-jax-ws.xsl:
- XSLT stylesheet that generates virtualbox.java from
- VirtualBox.xidl. This generated Java code contains
- a Java wrapper that allows client code to use the
- webservice in an object-oriented way.
-
- Copyright (C) 2008-2010 Oracle Corporation
-
- This file is part of VirtualBox Open Source Edition (OSE), as
- available from http://www.virtualbox.org. This file is free software;
- you can redistribute it and/or modify it under the terms of the GNU
- General Public License (GPL) as published by the Free Software
- Foundation, in version 2 as it comes in the "COPYING" file of the
- VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
--->
-
-<xsl:stylesheet
- version="1.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:exsl="http://exslt.org/common"
- extension-element-prefixes="exsl">
-
- <xsl:output method="text"/>
-
- <xsl:strip-space elements="*"/>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - -
- global XSLT variables
- - - - - - - - - - - - - - - - - - - - - - - -->
-
-<xsl:variable name="G_xsltFilename" select="'glue-jaxws.xsl'" />
-<!-- Keep in sync with VBOX_JAVA_PACKAGE in webservices/Makefile.kmk -->
-<xsl:variable name="G_virtualBoxPackage" select="concat('org.virtualbox',$G_vboxApiSuffix)" />
-<xsl:variable name="G_virtualBoxPackage2" select="concat('com.sun.xml.ws.commons.virtualbox',$G_vboxApiSuffix)" />
-<xsl:variable name="G_virtualBoxWsdl" select="concat(concat('&quot;vboxwebService',$G_vboxApiSuffix), '.wsdl&quot;')" />
-
-<xsl:include href="websrv-shared.inc.xsl" />
-
-<!-- collect all interfaces with "wsmap='suppress'" in a global variable for
- quick lookup -->
-<xsl:variable name="G_setSuppressedInterfaces"
- select="//interface[@wsmap='suppress']" />
-
-
-<xsl:template name="fileheader">
- <xsl:param name="name" />
- <xsl:text>/**
- * Copyright (C) 2008-2010 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.LIB" 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.
- *
-</xsl:text>
- <xsl:value-of select="concat(' * ',$name)"/>
-<xsl:text>
- *
- * DO NOT EDIT! This is a generated file.
- * Generated from: src/VBox/Main/idl/VirtualBox.xidl (VirtualBox's interface definitions in XML)
- * Generator: src/VBox/Main/webservice/glue-jaxws.xsl
- */
-
-</xsl:text>
-</xsl:template>
-
-<!-- Emits the fully prefixed class name, if necessary, of the given type. This dies
- if $name is not defined in XIDL; in other words, do not call this for built-in types. -->
-<xsl:template name="fullClassName">
- <xsl:param name="name" />
- <xsl:param name="origname" />
- <xsl:param name="collPrefix" />
- <xsl:variable name="coll" select="//collection[@name=$name]" />
- <xsl:choose>
- <xsl:when test="//collection[@name=$name]">
- <!-- for collections and safearrays we return element type -->
- <xsl:call-template name="fullClassName">
- <xsl:with-param name="name" select="concat($collPrefix,//collection[@name=$name]/@type)" />
- <xsl:with-param name="origname" select="//collection[@name=$name]/@type" />
- <xsl:with-param name="collPrefix" select="$collPrefix" />
- </xsl:call-template>
- <!-- <xsl:value-of select="concat('org.virtualbox.', concat($collPrefix,//collection[@name=$name]/@type))" /> -->
- </xsl:when>
- <xsl:when test="//enum[@name=$name] or //enum[@name=$origname]">
- <xsl:value-of select="concat($G_virtualBoxPackage, concat('.', $name))" />
- </xsl:when>
- <xsl:when test="$collPrefix and //interface[@name=$origname]/@wsmap='managed'">
- <xsl:value-of select="concat($G_virtualBoxPackage, concat('.', $name))" />
- </xsl:when>
- <xsl:when test="//interface[@name=$name]">
- <xsl:value-of select="concat($G_virtualBoxPackage2, concat('.', $name))" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="fatalError">
- <xsl:with-param name="msg" select="concat('fullClassName: Type &quot;', $name, '&quot; is not supported.')" />
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<!--
- typeIdl2Glue: converts $type into a type as used by the java glue code.
- For example, for an XIDL IMachineCollection, this will return
- "List<com.sun.xml.ws.commons.virtualbox.IMachine>".
- -->
-<xsl:template name="typeIdl2Glue">
- <xsl:param name="ifname" />
- <xsl:param name="method" />
- <xsl:param name="name" />
- <xsl:param name="type" />
- <xsl:param name="safearray" />
- <xsl:param name="forceelem" />
-
- <xsl:variable name="needarray" select="($safearray='yes' or //collection[@name=$type]) and not($forceelem='yes')" />
-
- <xsl:if test="$needarray">
- <xsl:value-of select="'List&lt;'" />
- </xsl:if>
-
- <!-- look up Java type from IDL type from table array in websrv-shared.inc.xsl -->
- <xsl:variable name="javatypefield" select="exsl:node-set($G_aSharedTypes)/type[@idlname=$type]/@javaname" />
-
- <xsl:choose>
- <xsl:when test="string-length($javatypefield)">
- <xsl:value-of select="$javatypefield" />
- </xsl:when>
- <!-- not a standard type: then it better be one of the types defined in the XIDL -->
- <xsl:when test="$type='$unknown'">IUnknown</xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="fullClassName">
- <xsl:with-param name="name" select="$type" />
- <xsl:with-param name="collPrefix" select="''"/>
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
-
- <xsl:if test="$needarray">
- <xsl:value-of select="'&gt;'" />
- </xsl:if>
-</xsl:template>
-
-<!--
- typeIdl2Java: converts $type into a type as used by the JAX-WS backend.
- For example, for an XIDL IMachineCollection, this will return
- "ArrayOfIMachine".
- -->
-<xsl:template name="typeIdl2Java">
- <xsl:param name="ifname" />
- <xsl:param name="method" />
- <xsl:param name="name" />
- <xsl:param name="type" />
- <xsl:param name="safearray" />
- <xsl:param name="forceelem" />
-
- <xsl:variable name="needarray" select="($safearray='yes') and not($forceelem='yes')" />
-
- <xsl:if test="$needarray">
- <xsl:value-of select="'List&lt;'" />
- </xsl:if>
-
- <!-- look up Java type from IDL type from table array in websrv-shared.inc.xsl -->
- <xsl:variable name="javatypefield" select="exsl:node-set($G_aSharedTypes)/type[@idlname=$type]/@javaname" />
-
- <xsl:choose>
- <xsl:when test="string-length($javatypefield)">
- <xsl:value-of select="$javatypefield" />
- </xsl:when>
- <xsl:when test="$type='$unknown'">String</xsl:when>
- <xsl:when test="//interface[@name=$type]/@wsmap='struct'">
- <xsl:value-of select="concat($G_virtualBoxPackage, '.', $type)" />
- </xsl:when>
- <xsl:when test="//interface[@name=$type]/@wsmap='managed'">String</xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="fullClassName">
- <xsl:with-param name="name" select="$type" />
- <xsl:with-param name="collPrefix" select="'ArrayOf'"/>
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
- <xsl:if test="$needarray">
- <xsl:value-of select="'&gt;'" />
- </xsl:if>
-</xsl:template>
-
-<xsl:template name="cookOutParam">
- <xsl:param name="ifname"/>
- <xsl:param name="methodname"/>
- <xsl:param name="value"/>
- <xsl:param name="idltype"/>
- <xsl:param name="safearray"/>
- <xsl:variable name="isstruct"
- select="//interface[@name=$idltype]/@wsmap='struct'" />
- <xsl:choose>
- <xsl:when test="//collection[@name=$idltype]">
- <xsl:variable name="elemtype">
- <xsl:call-template name="typeIdl2Glue">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$methodname" />
- <xsl:with-param name="name" select="$value" />
- <xsl:with-param name="type" select="$idltype" />
- <xsl:with-param name="forceelem" select="'yes'" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="contains($elemtype, $G_virtualBoxPackage)">
- <xsl:value-of select="concat($value,'.getArray()')" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat('Helper.wrap(', $elemtype, '.class, port, ((',
- $value,' == null)? null : ',$value,'.getArray()))')" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="//interface[@name=$idltype] or $idltype='$unknown'">
- <xsl:choose>
- <xsl:when test="$safearray='yes'">
- <xsl:variable name="elemtype">
- <xsl:call-template name="typeIdl2Glue">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$methodname" />
- <xsl:with-param name="name" select="$value" />
- <xsl:with-param name="type" select="$idltype" />
- <xsl:with-param name="safearray" select="'no'" />
- <xsl:with-param name="forceelem" select="'yes'" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$isstruct">
- <xsl:variable name="javagettertype">
- <xsl:call-template name="typeIdl2Java">
- <xsl:with-param name="method" select="$methodname" />
- <xsl:with-param name="name" select="$value" />
- <xsl:with-param name="type" select="$idltype" />
- <xsl:with-param name="safearray" select="$safearray" />
- <xsl:with-param name="forceelem" select="'yes'" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:value-of select="concat('Helper.wrap2(',$elemtype, '.class, ', $javagettertype, '.class, port, ', $value,')')"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat('Helper.wrap(',$elemtype, '.class, port, ', $value,')')"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:otherwise>
- <xsl:variable name="gluetype">
- <xsl:call-template name="typeIdl2Glue">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$methodname" />
- <xsl:with-param name="name" select="$value" />
- <xsl:with-param name="type" select="$idltype" />
- <xsl:with-param name="safearray" select="$safearray" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$isstruct">
- <xsl:value-of select="concat('(', $value, ' != null) ? new ', $gluetype, '(', $value,', port) : null')" />
- </xsl:when>
- <xsl:otherwise>
- <!-- if the MOR string is empty, that means NULL, so return NULL instead of an object then -->
- <xsl:value-of select="concat('(', $value, '.length() > 0) ? new ', $gluetype, '(', $value,', port) : null')" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$value"/>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template name="genStructWrapper">
- <xsl:param name="ifname" select="@name" />
-
- <xsl:value-of select="concat(' private ', $G_virtualBoxPackage,'.',$ifname, ' real;&#10;')"/>
- <xsl:value-of select="' private VboxPortType port;&#10;&#10;'"/>
-
- <xsl:value-of select="concat(' public ', $ifname, '(', $G_virtualBoxPackage,'.',$ifname,' real, VboxPortType port) {&#10; this.real = real; &#10; this.port = port; &#10; }&#10;')"/>
- <xsl:for-each select="attribute">
- <xsl:variable name="attrname"><xsl:value-of select="@name" /></xsl:variable>
- <xsl:variable name="attrtype"><xsl:value-of select="@type" /></xsl:variable>
- <xsl:variable name="attrreadonly"><xsl:value-of select="@readonly" /></xsl:variable>
- <xsl:variable name="attrsafearray"><xsl:value-of select="@safearray" /></xsl:variable>
- <xsl:choose>
- <xsl:when test="$attrreadonly='yes'">
- <xsl:value-of select="concat('&#10; // read-only attribute ', $ifname, '::', $attrname, ' of type ', $attrtype, '&#10;')" />
-
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat('&#10; // read/write attribute ', $ifname, '::', $attrname, ' of type ', $attrtype, '&#10;')" />
- </xsl:otherwise>
- </xsl:choose>
-
- <!-- emit getter method -->
- <xsl:variable name="gettername">
- <xsl:choose>
- <!-- Stupid, but boolean getters called isFoo(), not getFoo() -->
- <xsl:when test="$attrtype = 'boolean'">
- <xsl:variable name="capsname">
- <xsl:call-template name="capitalize">
- <xsl:with-param name="str" select="$attrname" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:value-of select="concat('is', $capsname)" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="makeGetterName">
- <xsl:with-param name="attrname" select="$attrname" />
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="gluegettertype">
- <xsl:call-template name="typeIdl2Glue">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$gettername" />
- <xsl:with-param name="name" select="$attrname" />
- <xsl:with-param name="type" select="$attrtype" />
- <xsl:with-param name="safearray" select="@safearray" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:variable name="javagettertype">
- <xsl:call-template name="typeIdl2Java">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$gettername" />
- <xsl:with-param name="name" select="$attrname" />
- <xsl:with-param name="type" select="$attrtype" />
- <xsl:with-param name="safearray" select="@safearray" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:value-of select="concat(' public ', $gluegettertype, ' ', $gettername, '() {&#10;')" />
- <xsl:value-of select="concat(' ', $javagettertype, ' retVal = real.', $gettername, '();&#10;')" />
- <xsl:variable name="wrapped">
- <xsl:call-template name="cookOutParam">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$gettername" />
- <xsl:with-param name="value" select="'retVal'" />
- <xsl:with-param name="idltype" select="$attrtype" />
- <xsl:with-param name="safearray" select="@safearray" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:value-of select="concat(' return ', $wrapped, ';&#10;')" />
- <xsl:text> }&#10;</xsl:text>
-
- </xsl:for-each>
-
-</xsl:template>
-
-
-<xsl:template name="emitArgInMethodImpl">
- <xsl:param name="paramname" select="@name" />
- <xsl:param name="paramtype" select="@type" />
- <!-- per-argument special type handling -->
- <xsl:choose>
- <xsl:when test="//interface[@name=$paramtype] or $paramtype='$unknown'">
- <xsl:choose>
- <xsl:when test="@dir='out'">
- <xsl:value-of select="concat('tmp', $paramname)" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:choose>
- <xsl:when test="@safearray='yes'">
- <xsl:value-of select="concat('Helper.unwrap(',$paramname,')')"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat('((', $paramname, ' == null)?null:', $paramname, '.getRef())')" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$paramname" />
- </xsl:otherwise>
- </xsl:choose>
- <xsl:if test="not(position()=last())">
- <xsl:text>, </xsl:text>
- </xsl:if>
-</xsl:template>
-
-<xsl:template name="startFile">
- <xsl:param name="file" />
-
- <xsl:value-of select="concat('&#10;// ##### BEGINFILE &quot;', $file, '&quot;&#10;&#10;')" />
- <xsl:call-template name="fileheader">
- <xsl:with-param name="name" select="$file" />
- </xsl:call-template>
-package <xsl:value-of select="$G_virtualBoxPackage2" />;
-
-import <xsl:value-of select="$G_virtualBoxPackage" />.VboxPortType;
-import <xsl:value-of select="$G_virtualBoxPackage" />.VboxService;
-import <xsl:value-of select="$G_virtualBoxPackage" />.InvalidObjectFaultMsg;
-import <xsl:value-of select="$G_virtualBoxPackage" />.RuntimeFaultMsg;
-import javax.xml.ws.WebServiceException;
-</xsl:template>
-
-<xsl:template name="endFile">
- <xsl:param name="file" />
- <xsl:value-of select="concat('&#10;// ##### ENDFILE &quot;', $file, '&quot;&#10;&#10;')" />
-</xsl:template>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - -
- root match
- - - - - - - - - - - - - - - - - - - - - - - -->
-
-<xsl:template match="/idl">
- <xsl:if test="not($G_vboxApiSuffix)">
- <xsl:call-template name="fatalError">
- <xsl:with-param name="msg" select="'G_vboxApiSuffix must be given'" />
- </xsl:call-template>
- </xsl:if>
- <xsl:call-template name="startFile">
- <xsl:with-param name="file" select="'IUnknown.java'" />
- </xsl:call-template>
-
- <xsl:text><![CDATA[
-public class IUnknown
-{
- protected String _this; /* almost final, could only be set in finalizer */
- protected final VboxPortType port;
-
- public IUnknown(String _this, VboxPortType port)
- {
- this._this = _this;
- this.port = port;
- }
-
- public final String getRef()
- {
- return _this;
- }
-
- public final VboxPortType getRemoteWSPort()
- {
- return port;
- }
-
- public synchronized void releaseRemote() throws WebServiceException
- {
- if (_this == null) {
- return;
- }
- try {
- port.iManagedObjectRefRelease(_this);
- _this = null;
- } catch (InvalidObjectFaultMsg e) {
- throw new WebServiceException(e);
- } catch (RuntimeFaultMsg e) {
- throw new WebServiceException(e);
- }
- }
-
- /*
- protected void finalize()
- {
- try {
- releaseRemote();
- } catch (WebServiceException e) {
- }
- } */
-
- // may need to support some sort of QueryInterface, to make this class useable
- // not only as common baseclass
-}
-]]></xsl:text>
-
- <xsl:call-template name="endFile">
- <xsl:with-param name="file" select="'IUnknown.java'" />
- </xsl:call-template>
-
- <xsl:call-template name="startFile">
- <xsl:with-param name="file" select="'Helper.java'" />
- </xsl:call-template>
-
-<xsl:text><![CDATA[
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-
-class Helper {
- public static <T> List<T> wrap(Class<T> wrapperClass, VboxPortType pt, List<String> thisPtrs) {
- try {
- if(thisPtrs==null) return Collections.emptyList();
-
- Constructor<T> c = wrapperClass.getConstructor(String.class, VboxPortType.class);
- List<T> ret = new ArrayList<T>(thisPtrs.size());
- for (String thisPtr : thisPtrs) {
- ret.add(c.newInstance(thisPtr,pt));
- }
- return ret;
- } catch (NoSuchMethodException e) {
- throw new AssertionError(e);
- } catch (InstantiationException e) {
- throw new AssertionError(e);
- } catch (IllegalAccessException e) {
- throw new AssertionError(e);
- } catch (InvocationTargetException e) {
- throw new AssertionError(e);
- }
- }
-
- public static <T1, T2> List<T1> wrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, VboxPortType pt, List<T2> thisPtrs) {
- try {
- if(thisPtrs==null) return Collections.emptyList();
-
- Constructor<T1> c = wrapperClass1.getConstructor(wrapperClass2, VboxPortType.class);
- List<T1> ret = new ArrayList<T1>(thisPtrs.size());
- for (T2 thisPtr : thisPtrs) {
- ret.add(c.newInstance(thisPtr,pt));
- }
- return ret;
- } catch (NoSuchMethodException e) {
- throw new AssertionError(e);
- } catch (InstantiationException e) {
- throw new AssertionError(e);
- } catch (IllegalAccessException e) {
- throw new AssertionError(e);
- } catch (InvocationTargetException e) {
- throw new AssertionError(e);
- }
- }
-
- public static <T extends IUnknown> List<String> unwrap(List<T> thisPtrs) {
- if (thisPtrs==null) return Collections.emptyList();
-
- List<String> ret = new ArrayList<String>();
- for (T obj : thisPtrs) {
- ret.add(obj.getRef());
- }
- return ret;
- }
-}
-]]></xsl:text>
-
- <xsl:call-template name="endFile">
- <xsl:with-param name="file" select="'Helper.java'" />
- </xsl:call-template>
-
- <xsl:call-template name="startFile">
- <xsl:with-param name="file" select="'IWebsessionManager.java'" />
- </xsl:call-template>
-
-
-import java.net.URL;
-import java.math.BigInteger;
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-import javax.xml.namespace.QName;
-import javax.xml.ws.BindingProvider;
-import javax.xml.ws.Holder;
-import javax.xml.ws.WebServiceException;
-
-class PortPool
-{
- private final static String wsdlFile = <xsl:value-of select="$G_virtualBoxWsdl" />;
-
- <xsl:text><![CDATA[
- private Map<VboxPortType, Integer> known;
- private boolean initStarted;
- private VboxService svc;
-
- PortPool(boolean usePreinit)
- {
- known = new HashMap<VboxPortType, Integer>();
-
- if (usePreinit)
- {
- new Thread(new Runnable()
- {
- public void run()
- {
- // need to sync on something else but 'this'
- synchronized (known)
- {
- initStarted = true;
- known.notify();
- }
-
- preinit();
- }
- }).start();
-
- synchronized (known)
- {
- while (!initStarted)
- {
- try {
- known.wait();
- } catch (InterruptedException e) {
- break;
- }
- }
- }
- }
- }
-
- private synchronized void preinit()
- {
- VboxPortType port = getPort();
- releasePort(port);
- }
-
- synchronized VboxPortType getPort()
- {
- VboxPortType port = null;
- int ttl = 0;
-
- for (VboxPortType cur: known.keySet())
- {
- int value = known.get(cur);
- if ((value & 0x10000) == 0)
- {
- port = cur;
- ttl = value & 0xffff;
- break;
- }
- }
-
- if (port == null)
- {
- if (svc == null) {
- URL wsdl = PortPool.class.getClassLoader().getResource(wsdlFile);
- if (wsdl == null)
- throw new LinkageError(wsdlFile+" not found, but it should have been in the jar");
- svc = new VboxService(wsdl,
- new QName("http://www.virtualbox.org/Service",
- "vboxService"));
- }
- port = svc.getVboxServicePort();
- // reuse this object 0x10 times
- ttl = 0x10;
- }
- // mark as used
- known.put(port, new Integer(0x10000 | ttl));
- return port;
- }
-
- synchronized void releasePort(VboxPortType port)
- {
- Integer val = known.get(port);
- if (val == null || val == 0)
- {
- // know you not
- return;
- }
-
- int v = val;
- int ttl = v & 0xffff;
- // decrement TTL, and throw away port if used too much times
- if (--ttl <= 0)
- {
- known.remove(port);
- }
- else
- {
- v = ttl; // set new TTL and clear busy bit
- known.put(port, v);
- }
- }
-}
-
-public class IWebsessionManager {
-
- private static PortPool pool = new PortPool(true);
- protected VboxPortType port;
-
- public IWebsessionManager(URL url)
- {
- connect(url);
- }
-
- public IWebsessionManager(String url)
- {
- connect(url);
- }
-
- public IWebsessionManager(URL url, Map<String, Object> requestContext, Map<String, Object> responseContext)
- {
- connect(url.toExternalForm(), requestContext, responseContext);
- }
-
- public IWebsessionManager(String url, Map<String, Object> requestContext, Map<String, Object> responseContext)
- {
- connect(url, requestContext, responseContext);
- }
-
- public void connect(URL url)
- {
- connect(url.toExternalForm());
- }
-
- public void connect(String url)
- {
- this.port = pool.getPort();
-
- try {
- ((BindingProvider)port).getRequestContext().
- put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
- } catch (Throwable t) {
- if (this.port != null)
- pool.releasePort(this.port);
- // we have to throw smth derived from RuntimeException
- throw new WebServiceException(t);
- }
- }
-
- public void connect(String url, Map<String, Object> requestContext, Map<String, Object> responseContext)
- {
- this.port = pool.getPort();
-
- try {
- ((BindingProvider)port).getRequestContext();
- if (requestContext != null)
- ((BindingProvider)port).getRequestContext().putAll(requestContext);
-
- if (responseContext != null)
- ((BindingProvider)port).getResponseContext().putAll(responseContext);
-
- ((BindingProvider)port).getRequestContext().
- put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
- } catch (Throwable t) {
- if (this.port != null)
- pool.releasePort(port);
- // we have to throw smth derived from RuntimeException
- throw new WebServiceException(t);
- }
- }
-
-
- public void disconnect(IVirtualBox refIVirtualBox)
- {
- try {
- logoff(refIVirtualBox);
- } finally {
- if (this.port != null) {
- pool.releasePort(this.port);
- this.port = null;
- }
- }
- }
-
- public void cleanupUnused()
- {
- System.gc();
- Runtime.getRuntime().runFinalization();
- }
-
- /* method IWebsessionManager::logon(
- [in] wstring username,
- [in] wstring password,
- [return] IVirtualBox return)
- */
- public IVirtualBox logon(String username, String password) {
- try {
- String retVal = port.iWebsessionManagerLogon(username, password);
- return new IVirtualBox(retVal, port);
- } catch (InvalidObjectFaultMsg e) {
- throw new WebServiceException(e);
- } catch (RuntimeFaultMsg e) {
- throw new WebServiceException(e);
- }
- }
-
- /* method IWebsessionManager::getSessionObject(
- [in] IVirtualBox refIVirtualBox,
- [return] ISession return)
- */
- public ISession getSessionObject(IVirtualBox refIVirtualBox) {
- try {
- String retVal = port.iWebsessionManagerGetSessionObject(((refIVirtualBox == null)?null:refIVirtualBox.getRef()));
- return new ISession(retVal, port);
- } catch (InvalidObjectFaultMsg e) {
- throw new WebServiceException(e);
- } catch (RuntimeFaultMsg e) {
- throw new WebServiceException(e);
- }
- }
-
- /* method IWebsessionManager::logoff(
- [in] IVirtualBox refIVirtualBox)
- */
- public void logoff(IVirtualBox refIVirtualBox) {
- try {
- port.iWebsessionManagerLogoff(((refIVirtualBox == null)?null:refIVirtualBox.getRef()));
- } catch (InvalidObjectFaultMsg e) {
- throw new WebServiceException(e);
- } catch (RuntimeFaultMsg e) {
- throw new WebServiceException(e);
- }
- }
-}
-]]></xsl:text>
- <xsl:call-template name="endFile">
- <xsl:with-param name="file" select="'IWebsessionManager.java'" />
- </xsl:call-template>
-
- <xsl:text>// ######## COLLECTIONS&#10;&#10;</xsl:text>
-
- <xsl:for-each select="//collection">
- <xsl:variable name="type" select="@type" />
- <xsl:variable name="arrayoftype" select="concat('ArrayOf', @type)" />
- <xsl:variable name="filename" select="$arrayoftype" />
-
- <xsl:value-of select="concat('&#10;// ##### BEGINFILE &quot;', $filename, '.java&quot;&#10;&#10;')" />
-
- <xsl:call-template name="startFile">
- <xsl:with-param name="file" select="concat($filename, '.java')" />
- </xsl:call-template>
-
- <xsl:text>import java.util.ArrayList;&#10;</xsl:text>
- <xsl:text>import java.util.List;&#10;</xsl:text>
- <xsl:text>import javax.xml.bind.annotation.XmlAccessType;&#10;</xsl:text>
- <xsl:text>import javax.xml.bind.annotation.XmlAccessorType;&#10;</xsl:text>
- <xsl:text>import javax.xml.bind.annotation.XmlType;&#10;&#10;</xsl:text>
-
- <xsl:text>@XmlAccessorType(XmlAccessType.FIELD)&#10;</xsl:text>
- <xsl:value-of select="concat('@XmlType(name = &quot;', $arrayoftype, '&quot;, propOrder = {&#10;')" />
- <xsl:text> "array"&#10;</xsl:text>
- <xsl:text>})&#10;&#10;</xsl:text>
- <xsl:value-of select="concat('public class ', $arrayoftype, ' {&#10;&#10;')" />
-
- <xsl:text> protected List&lt;String&gt; array;&#10;&#10;</xsl:text>
-
- <xsl:text> public List&lt;String&gt; getArray() {&#10;</xsl:text>
- <xsl:text> if (array == null) {&#10;</xsl:text>
- <xsl:text> array = new ArrayList&lt;String&gt;();&#10;</xsl:text>
- <xsl:text> }&#10;</xsl:text>
- <xsl:text> return this.array;&#10;</xsl:text>
- <xsl:text> }&#10;&#10;</xsl:text>
- <xsl:text>}&#10;</xsl:text>
- <xsl:call-template name="endFile">
- <xsl:with-param name="file" select="concat($filename, '.java')" />
- </xsl:call-template>
-
- </xsl:for-each>
-
- <xsl:text>// ######## ENUMS&#10;&#10;</xsl:text>
-
- <xsl:for-each select="//enum">
- <xsl:variable name="enumname" select="@name" />
- <xsl:variable name="filename" select="$enumname" />
-
- <xsl:call-template name="startFile">
- <xsl:with-param name="file" select="concat($filename, '.java')" />
- </xsl:call-template>
-
- <xsl:text>import javax.xml.bind.annotation.XmlEnum;&#10;</xsl:text>
- <xsl:text>import javax.xml.bind.annotation.XmlEnumValue;&#10;</xsl:text>
- <xsl:text>import javax.xml.bind.annotation.XmlType;&#10;&#10;</xsl:text>
-
- <xsl:value-of select="concat('@XmlType(name = &quot;', $enumname, '&quot;)&#10;')" />
- <xsl:text>@XmlEnum&#10;</xsl:text>
- <xsl:value-of select="concat('public enum ', $enumname, ' {&#10;&#10;')" />
- <xsl:for-each select="const">
- <xsl:variable name="enumconst" select="@name" />
- <xsl:value-of select="concat(' @XmlEnumValue(&quot;', $enumconst, '&quot;)&#10;')" />
- <xsl:value-of select="concat(' ', $enumconst, '(&quot;', $enumconst, '&quot;)')" />
- <xsl:choose>
- <xsl:when test="not(position()=last())">
- <xsl:text>,&#10;</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>;&#10;</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
-
- <xsl:text>&#10;</xsl:text>
- <xsl:text> private final String value;&#10;&#10;</xsl:text>
-
- <xsl:value-of select="concat(' ', $enumname, '(String v) {&#10;')" />
- <xsl:text> value = v;&#10;</xsl:text>
- <xsl:text> }&#10;&#10;</xsl:text>
-
- <xsl:text> public String value() {&#10;</xsl:text>
- <xsl:text> return value;&#10;</xsl:text>
- <xsl:text> }&#10;&#10;</xsl:text>
-
- <xsl:value-of select="concat(' public static ', $enumname, ' fromValue(String v) {&#10;')" />
- <xsl:value-of select="concat(' for (', $enumname, ' c: ', $enumname, '. values()) {&#10;')" />
- <xsl:text> if (c.value.equals(v)) {&#10;</xsl:text>
- <xsl:text> return c;&#10;</xsl:text>
- <xsl:text> }&#10;</xsl:text>
- <xsl:text> }&#10;</xsl:text>
- <xsl:text> throw new IllegalArgumentException(v);&#10;</xsl:text>
- <xsl:text> }&#10;&#10;</xsl:text>
-
- <xsl:text>}&#10;&#10;</xsl:text>
-
- <xsl:call-template name="endFile">
- <xsl:with-param name="file" select="concat($filename, '.java')" />
- </xsl:call-template>
-
- </xsl:for-each>
-
- <xsl:text>// ######## INTERFACES &#10;&#10;</xsl:text>
-
- <xsl:for-each select="//interface">
- <xsl:variable name="ifname" select="@name" />
- <xsl:variable name="filename" select="$ifname" />
- <xsl:variable name="wsmap" select="@wsmap" />
- <xsl:variable name="wscpp" select="@wscpp" />
-
- <xsl:if test="not($wsmap='suppress') and not ($wsmap='global')">
- <xsl:call-template name="startFile">
- <xsl:with-param name="file" select="concat($filename, '.java')" />
- </xsl:call-template>
-
- <xsl:text>import java.math.BigInteger;&#10;</xsl:text>
- <xsl:text>import java.util.List;&#10;</xsl:text>
- <xsl:text>import javax.xml.ws.Holder;&#10;</xsl:text>
- <xsl:text>import javax.xml.ws.WebServiceException;&#10;</xsl:text>
-
- <xsl:choose>
- <xsl:when test="$wsmap='struct'">
- <xsl:value-of select="concat('public class ', $ifname, ' {&#10;&#10;')" />
- <xsl:call-template name="genStructWrapper">
- <xsl:with-param name="name" select="$ifname" />
- </xsl:call-template>
- </xsl:when>
-
- <xsl:otherwise>
- <xsl:variable name="extends" select="//interface[@name=$ifname]/@extends" />
- <xsl:choose>
- <xsl:when test="($extends = '$unknown') or ($extends = '$dispatched') or ($extends = '$errorinfo')">
- <xsl:value-of select="concat('public class ', $ifname, ' extends IUnknown {&#10;&#10;')" />
- </xsl:when>
- <xsl:when test="//interface[@name=$extends]">
- <xsl:value-of select="concat('public class ', $ifname, ' extends ', $extends, ' {&#10;&#10;')" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="fatalError">
- <xsl:with-param name="msg" select="concat('Interface generation: interface &quot;', $ifname, '&quot; has invalid &quot;extends&quot; value ', $extends, '.')" />
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
-
- <!-- interface (class) constructor -->
- <xsl:value-of select="concat(' public static ', $ifname, ' cast(IUnknown other) {&#10;')" />
- <xsl:value-of select="concat(' return new ', $ifname,
- '(other.getRef(), other.getRemoteWSPort());&#10; }&#10;&#10;')"/>
- <xsl:value-of select="concat(' public ', $ifname, '(String _this, VboxPortType port) {&#10;')" />
- <xsl:text> super(_this,port);&#10;</xsl:text>
- <xsl:text> }&#10;</xsl:text>
-
- <!-- attributes -->
- <xsl:for-each select="attribute">
- <xsl:variable name="attrname"><xsl:value-of select="@name" /></xsl:variable>
- <xsl:variable name="attrtype"><xsl:value-of select="@type" /></xsl:variable>
- <xsl:variable name="attrreadonly"><xsl:value-of select="@readonly" /></xsl:variable>
- <xsl:variable name="attrsafearray"><xsl:value-of select="@safearray" /></xsl:variable>
-
- <xsl:choose>
- <xsl:when test="( $attrtype=($G_setSuppressedInterfaces/@name) )">
- <xsl:value-of select="concat('&#10; // Skipping attribute ', $attrtype, ' for it is of suppressed type ', $attrtype, '&#10;')" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:choose>
- <xsl:when test="@readonly='yes'">
- <xsl:value-of select="concat('&#10; // read-only attribute ', $ifname, '::', $attrname, ' of type ', $attrtype, '&#10;')" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat('&#10; // read/write attribute ', $ifname, '::', $attrname, ' of type ', $attrtype, '&#10;')" />
- </xsl:otherwise>
- </xsl:choose>
- <!-- emit getter method -->
- <xsl:variable name="gettername"><xsl:call-template name="makeGetterName"><xsl:with-param name="attrname" select="$attrname" /></xsl:call-template></xsl:variable>
- <xsl:variable name="jaxwsGetter"><xsl:call-template name="makeJaxwsMethod"><xsl:with-param name="ifname" select="$ifname" /><xsl:with-param name="methodname" select="$gettername" /></xsl:call-template></xsl:variable>
- <xsl:variable name="gluegettertype">
- <xsl:call-template name="typeIdl2Glue">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$gettername" />
- <xsl:with-param name="name" select="$attrname" />
- <xsl:with-param name="type" select="$attrtype" />
- <xsl:with-param name="safearray" select="@safearray" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:variable name="javagettertype">
- <xsl:call-template name="typeIdl2Java">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$gettername" />
- <xsl:with-param name="name" select="$attrname" />
- <xsl:with-param name="type" select="$attrtype" />
- <xsl:with-param name="safearray" select="@safearray" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:value-of select="concat(' public ', $gluegettertype, ' ', $gettername, '() {&#10;')" />
- <xsl:text> try {&#10;</xsl:text>
- <xsl:value-of select="concat(' ', $javagettertype, ' retVal = port.', $jaxwsGetter, '(_this);&#10;')" />
- <xsl:variable name="wrapped">
- <xsl:call-template name="cookOutParam">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$gettername" />
- <xsl:with-param name="value" select="'retVal'" />
- <xsl:with-param name="idltype" select="$attrtype" />
- <xsl:with-param name="safearray" select="@safearray" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:value-of select="concat(' return ', $wrapped, ';&#10;')" />
- <xsl:text> } catch (InvalidObjectFaultMsg e) {&#10;</xsl:text>
- <xsl:text> throw new WebServiceException(e);&#10;</xsl:text>
- <xsl:text> } catch (RuntimeFaultMsg e) {&#10;</xsl:text>
- <xsl:text> throw new WebServiceException(e);&#10;</xsl:text>
- <xsl:text> }&#10;</xsl:text>
- <xsl:text> }&#10;</xsl:text>
- <xsl:if test="not(@readonly='yes')">
- <!-- emit setter -->
- <xsl:variable name="settername"><xsl:call-template name="makeSetterName"><xsl:with-param name="attrname" select="$attrname" /></xsl:call-template></xsl:variable>
- <xsl:variable name="jaxwsSetter"><xsl:call-template name="makeJaxwsMethod"><xsl:with-param name="ifname" select="$ifname" /><xsl:with-param name="methodname" select="$settername" /></xsl:call-template></xsl:variable>
- <xsl:variable name="javasettertype">
- <xsl:call-template name="typeIdl2Java">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$settername" />
- <xsl:with-param name="name" select="$attrname" />
- <xsl:with-param name="type" select="$attrtype" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:value-of select="concat(' public void ', $settername, '(', $javasettertype, ' value) {&#10;')" />
- <xsl:text> try {&#10;</xsl:text>
- <xsl:value-of select="concat(' port.', $jaxwsSetter, '(_this, value);&#10;')" />
- <xsl:text> } catch (InvalidObjectFaultMsg e) {&#10;</xsl:text>
- <xsl:text> throw new WebServiceException(e);&#10;</xsl:text>
- <xsl:text> } catch (RuntimeFaultMsg e) {&#10;</xsl:text>
- <xsl:text> throw new WebServiceException(e);&#10;</xsl:text>
- <xsl:text> }&#10;</xsl:text>
- <xsl:text> }&#10;</xsl:text>
- </xsl:if>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each> <!-- attribute -->
-
- <!-- emit real methods -->
- <xsl:for-each select="method">
- <xsl:variable name="methodname"><xsl:value-of select="@name" /></xsl:variable>
- <xsl:variable name="portArg">
- <xsl:if test="not($wsmap='global')">
- <xsl:value-of select="'_this'"/>
- </xsl:if>
- </xsl:variable>
-
- <!-- method header: return value "int", method name, soap arguments -->
- <!-- skip this method if it has parameters of a type that has wsmap="suppress" -->
- <xsl:choose>
- <xsl:when test=" (param[@type=($G_setSuppressedInterfaces/@name)])
- or (param[@mod='ptr'])" >
- <xsl:comment><xsl:value-of select="concat('Skipping method ', $methodname, ' for it has parameters with suppressed types')" /></xsl:comment>
- </xsl:when>
- <xsl:otherwise>
- <xsl:variable name="fHasReturnParms" select="param[@dir='return']" />
- <xsl:variable name="fHasOutParms" select="param[@dir='out']" />
-
- <xsl:value-of select="concat('&#10; /* method ', $ifname, '::', $methodname, '(')" />
- <xsl:for-each select="param">
- <xsl:value-of select="concat('&#10; [', @dir, '] ', @type, ' ', @name)" />
- <xsl:if test="@safearray='yes'">
- <xsl:text>[]</xsl:text>
- </xsl:if>
- <xsl:if test="not(position()=last())">
- <xsl:text>,</xsl:text>
- </xsl:if>
- </xsl:for-each>
- <xsl:text>)&#10; */&#10;</xsl:text>
- <!-- method implementation -->
- <xsl:variable name="returnidltype" select="param[@dir='return']/@type" />
- <xsl:variable name="returnidlsafearray" select="param[@dir='return']/@safearray" />
- <xsl:variable name="returngluetype">
- <xsl:choose>
- <xsl:when test="$returnidltype">
- <xsl:call-template name="typeIdl2Glue">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$methodname" />
- <xsl:with-param name="name" select="@name" />
- <xsl:with-param name="type" select="$returnidltype" />
- <xsl:with-param name="safearray" select="param[@dir='return']/@safearray" />
- </xsl:call-template>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>void</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:value-of select="concat(' public ', $returngluetype, ' ', $methodname, '(')" />
- <!-- make a set of all parameters with in and out direction -->
- <xsl:variable name="paramsinout" select="param[@dir='in' or @dir='out']" />
- <xsl:for-each select="exsl:node-set($paramsinout)">
- <xsl:variable name="paramgluetype">
- <xsl:call-template name="typeIdl2Glue">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$methodname" />
- <xsl:with-param name="name" select="@name" />
- <xsl:with-param name="type" select="@type" />
- <xsl:with-param name="safearray" select="@safearray" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="@dir='out'">
- <xsl:value-of select="concat('Holder&lt;', $paramgluetype, '&gt; ', @name)" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat($paramgluetype, ' ', @name)" />
- </xsl:otherwise>
- </xsl:choose>
- <xsl:if test="not(position()=last())">
- <xsl:text>, </xsl:text>
- </xsl:if>
- </xsl:for-each>
- <xsl:text>) {&#10;</xsl:text>
- <xsl:text> try {&#10;</xsl:text>
- <xsl:if test="param[@dir='out']">
- <xsl:for-each select="param[@dir='out']">
- <xsl:variable name="paramtype" select="@type" />
- <xsl:if test="//interface[@name=$paramtype] or $paramtype='$unknown'">
- <xsl:choose>
- <xsl:when test="@safearray='yes'">
- <xsl:value-of select="concat(' Holder&lt;List&lt;String&gt;&gt; tmp', @name, ' = new Holder&lt;List&lt;String&gt;&gt;(); &#10;')" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat(' Holder&lt;String&gt; tmp', @name, ' = new Holder&lt;String&gt;(); &#10;')" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:for-each>
- </xsl:if>
-
- <xsl:text> </xsl:text>
-
- <!-- make the function call: first have a stack variable for the return value, if any -->
- <!-- XSLT doesn't allow variable override in inner blocks -->
- <xsl:variable name="retValValue">
- <xsl:choose>
- <xsl:when test="param[@dir='out']">
- <xsl:value-of select="'retVal.value'"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="'retVal'"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:if test="$returnidltype">
- <xsl:variable name="javarettype">
- <xsl:call-template name="typeIdl2Java">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$methodname" />
- <xsl:with-param name="name" select="@name" />
- <xsl:with-param name="type" select="$returnidltype" />
- <xsl:with-param name="safearray" select="$returnidlsafearray" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="param[@dir='out']">
- <!-- create a new object for return value -->
- <xsl:value-of select="
- concat('Holder&lt;', $javarettype, '&gt;',
- ' ', 'retVal = new Holder&lt;', $javarettype,
- '&gt;();&#xa; ')"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$javarettype"/>
- <xsl:text> retVal = </xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- <!-- function name and arguments -->
- <xsl:variable name="jaxwsmethod"><xsl:call-template name="makeJaxwsMethod"><xsl:with-param name="ifname" select="$ifname" /><xsl:with-param name="methodname" select="$methodname" /></xsl:call-template></xsl:variable>
- <xsl:value-of select="concat('port.', $jaxwsmethod, '(', $portArg)" />
- <xsl:if test="$paramsinout and not($portArg='')">
- <xsl:text>, </xsl:text>
- </xsl:if>
- <!-- jax-ws has an oddity: if both out params and a return value exist, then the return value is moved to the function's argument list... -->
- <xsl:choose>
- <xsl:when test="param[@dir='out'] and param[@dir='return']">
- <xsl:for-each select="param">
- <xsl:choose>
- <xsl:when test="@dir='return'">
- <xsl:text>retVal</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="emitArgInMethodImpl">
- <xsl:with-param name="paramname" select="@name" />
- <xsl:with-param name="paramtype" select="@type" />
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- </xsl:when>
- <xsl:otherwise>
- <xsl:for-each select="$paramsinout">
- <xsl:call-template name="emitArgInMethodImpl">
- <xsl:with-param name="paramname" select="@name" />
- <xsl:with-param name="paramtype" select="@type" />
- </xsl:call-template>
- </xsl:for-each>
- </xsl:otherwise>
- </xsl:choose>
- <xsl:text>);&#10;</xsl:text>
- <!-- now copy temp out parameters to their actual destination -->
- <xsl:for-each select="param[@dir='out']">
- <xsl:variable name="paramtype" select="@type" />
- <xsl:if test="//interface[@name=$paramtype] or $paramtype='$unknown'">
- <xsl:variable name="paramname" select="@name" />
- <xsl:variable name="wrapped">
- <xsl:call-template name="cookOutParam">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$methodname" />
- <xsl:with-param name="value" select="concat('tmp',@name,'.value')" />
- <xsl:with-param name="idltype" select="@type" />
- <xsl:with-param name="safearray" select="@safearray" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:value-of select="concat(' ',$paramname,'.value = ',
- $wrapped,';&#10;')"/>
- </xsl:if>
- </xsl:for-each>
- <!-- next line with return + glue type -->
- <xsl:if test="$returnidltype">
- <xsl:variable name="retval">
- <xsl:call-template name="cookOutParam">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="method" select="$methodname" />
- <xsl:with-param name="value" select="$retValValue" />
- <xsl:with-param name="idltype" select="$returnidltype" />
- <xsl:with-param name="safearray" select="$returnidlsafearray" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:value-of select="concat(' return ', $retval, ';&#10;')"/>
- </xsl:if>
- <xsl:text> } catch (InvalidObjectFaultMsg e) {&#10;</xsl:text>
- <xsl:text> throw new WebServiceException(e);&#10;</xsl:text>
- <xsl:text> } catch (RuntimeFaultMsg e) {&#10;</xsl:text>
- <xsl:text> throw new WebServiceException(e);&#10;</xsl:text>
- <xsl:text> }&#10;</xsl:text>
- <xsl:text> }&#10;</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
-
- </xsl:otherwise>
- </xsl:choose>
- <!-- end of class -->
- <xsl:text>}&#10;</xsl:text>
- <xsl:value-of select="concat('&#10;// ##### ENDFILE &quot;', $filename, '.java&quot;&#10;&#10;')" />
- <xsl:call-template name="endFile">
- <xsl:with-param name="file" select="concat($filename, '.java')" />
- </xsl:call-template>
- </xsl:if>
- </xsl:for-each>
-
-<!-- <xsl:apply-templates /> -->
-</xsl:template>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - -
- if
- - - - - - - - - - - - - - - - - - - - - - - -->
-
-<!--
- * ignore all |if|s except those for WSDL target
--->
-<xsl:template match="if">
- <xsl:if test="@target='wsdl'">
- <xsl:apply-templates/>
- </xsl:if>
-</xsl:template>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - -
- cpp
- - - - - - - - - - - - - - - - - - - - - - - -->
-
-<xsl:template match="cpp">
-<!-- ignore this -->
-</xsl:template>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - -
- library
- - - - - - - - - - - - - - - - - - - - - - - -->
-
-<xsl:template match="library">
- <xsl:apply-templates />
-</xsl:template>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - -
- class
- - - - - - - - - - - - - - - - - - - - - - - -->
-
-<xsl:template match="module/class">
-<!-- TODO swallow for now -->
-</xsl:template>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - -
- enum
- - - - - - - - - - - - - - - - - - - - - - - -->
-
-<xsl:template match="enum">
-</xsl:template>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - -
- const
- - - - - - - - - - - - - - - - - - - - - - - -->
-
-<!--
-<xsl:template match="const">
- <xsl:apply-templates />
-</xsl:template>
--->
-
-<!-- - - - - - - - - - - - - - - - - - - - - - -
- desc
- - - - - - - - - - - - - - - - - - - - - - - -->
-
-<xsl:template match="desc">
-<!-- TODO swallow for now -->
-</xsl:template>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - -
- note
- - - - - - - - - - - - - - - - - - - - - - - -->
-
-<xsl:template match="note">
-<!-- TODO -->
- <xsl:apply-templates />
-</xsl:template>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - -
- interface
- - - - - - - - - - - - - - - - - - - - - - - -->
-
-<xsl:template match="interface">
-
-</xsl:template>
-
-
-</xsl:stylesheet>
diff --git a/src/VBox/Main/webservice/samples/perl/clienttest.pl b/src/VBox/Main/webservice/samples/perl/clienttest.pl
index a2877962f..a2877962f 100755..100644
--- a/src/VBox/Main/webservice/samples/perl/clienttest.pl
+++ b/src/VBox/Main/webservice/samples/perl/clienttest.pl
diff --git a/src/VBox/Main/webservice/vboxweb.cpp b/src/VBox/Main/webservice/vboxweb.cpp
index e8036ed23..da6114326 100644
--- a/src/VBox/Main/webservice/vboxweb.cpp
+++ b/src/VBox/Main/webservice/vboxweb.cpp
@@ -46,6 +46,7 @@
#include <iprt/time.h>
#include <iprt/path.h>
#include <iprt/system.h>
+#include <iprt/base64.h>
// workaround for compile problems on gcc 4.1
#ifdef __GNUC__
@@ -521,6 +522,16 @@ public:
{
}
+ HRESULT init()
+ {
+ return S_OK;
+ }
+
+ void uninit()
+ {
+ }
+
+
STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent)
{
switch (aType)
@@ -618,11 +629,11 @@ void WebLogSoapError(struct soap *soap)
static void WebLogHeaderFooter(PRTLOGGER pLoggerRelease, RTLOGPHASE enmPhase, PFNRTLOGPHASEMSG pfnLog)
{
/* some introductory information */
- static RTTIMESPEC timeSpec = {0};
+ static RTTIMESPEC s_TimeSpec;
char szTmp[256];
if (enmPhase == RTLOGPHASE_BEGIN)
- RTTimeNow(&timeSpec);
- RTTimeSpecToString(&timeSpec, szTmp, sizeof(szTmp));
+ RTTimeNow(&s_TimeSpec);
+ RTTimeSpecToString(&s_TimeSpec, szTmp, sizeof(szTmp));
switch (enmPhase)
{
@@ -753,6 +764,12 @@ int fntQPumper(RTTHREAD ThreadSelf, void *pvUser)
return 0;
}
+#ifdef RT_OS_WINDOWS
+// Required for ATL
+static CComModule _Module;
+#endif
+
+
/**
* Start up the webservice server. This keeps running and waits
* for incoming SOAP connections; for each request that comes in,
@@ -954,11 +971,14 @@ int main(int argc, char *argv[])
}
/* VirtualBoxClient events registration. */
- IEventListener *vboxClientListener = NULL;
+ ComPtr<IEventListener> vboxClientListener;
{
ComPtr<IEventSource> pES;
CHECK_ERROR(g_pVirtualBoxClient, COMGETTER(EventSource)(pES.asOutParam()));
- vboxClientListener = new VirtualBoxClientEventListenerImpl();
+ ComObjPtr<VirtualBoxClientEventListenerImpl> clientListener;
+ clientListener.createObject();
+ clientListener->init(new VirtualBoxClientEventListener());
+ vboxClientListener = clientListener;
com::SafeArray<VBoxEventType_T> eventTypes;
eventTypes.push_back(VBoxEventType_OnVBoxSVCAvailabilityChanged);
CHECK_ERROR(pES, RegisterListener(vboxClientListener, ComSafeArrayAsInParam(eventTypes), true));
@@ -1014,7 +1034,7 @@ int main(int argc, char *argv[])
CHECK_ERROR(g_pVirtualBoxClient, COMGETTER(EventSource)(pES.asOutParam()));
if (!pES.isNull())
CHECK_ERROR(pES, UnregisterListener(vboxClientListener));
- vboxClientListener->Release();
+ vboxClientListener.setNull();
}
com::Shutdown();
@@ -1170,6 +1190,44 @@ std::string ConvertComString(const com::Guid &uuid)
return ustr.c_str(); // @todo r=dj since the length is known, we can probably use a better std::string allocator
}
+/** Code to handle string <-> byte arrays base64 conversion. */
+std::string Base64EncodeByteArray(ComSafeArrayIn(BYTE, aData))
+{
+
+ com::SafeArray<BYTE> sfaData(ComSafeArrayInArg(aData));
+ ssize_t cbData = sfaData.size();
+
+ if (cbData == 0)
+ return "";
+
+ ssize_t cchOut = RTBase64EncodedLength(cbData);
+
+ RTCString aStr;
+
+ aStr.reserve(cchOut+1);
+ int rc = RTBase64Encode(sfaData.raw(), cbData,
+ aStr.mutableRaw(), aStr.capacity(),
+ NULL);
+ AssertRC(rc);
+ aStr.jolt();
+
+ return aStr.c_str();
+}
+
+void Base64DecodeByteArray(std::string& aStr, ComSafeArrayOut(BYTE, aData))
+{
+ const char* pszStr = aStr.c_str();
+ ssize_t cbOut = RTBase64DecodedSize(pszStr, NULL);
+
+ Assert(cbOut > 0);
+
+ com::SafeArray<BYTE> result(cbOut);
+ int rc = RTBase64Decode(pszStr, result.raw(), cbOut, NULL, NULL);
+ AssertRC(rc);
+
+ result.detachTo(ComSafeArrayOutArg(aData));
+}
+
/**
* Raises a SOAP runtime fault. Implementation for the RaiseSoapRuntimeFault template
* function in vboxweb.h.
@@ -1992,4 +2050,3 @@ int __vbox__IWebsessionManager_USCORElogoff(
return SOAP_FAULT;
return SOAP_OK;
}
-
diff --git a/src/VBox/Main/webservice/vboxweb.h b/src/VBox/Main/webservice/vboxweb.h
index c2824e4b3..e323300e8 100644
--- a/src/VBox/Main/webservice/vboxweb.h
+++ b/src/VBox/Main/webservice/vboxweb.h
@@ -96,6 +96,9 @@ std::string ConvertComString(const com::Bstr &bstr);
std::string ConvertComString(const com::Guid &bstr);
+std::string Base64EncodeByteArray(ComSafeArrayIn(BYTE, aData));
+
+void Base64DecodeByteArray(std::string& aStr, ComSafeArrayOut(BYTE, aData));
/****************************************************************************
*
* managed object reference classes
diff --git a/src/VBox/Main/webservice/websrv-cpp.xsl b/src/VBox/Main/webservice/websrv-cpp.xsl
index 893487521..9f71374d3 100644
--- a/src/VBox/Main/webservice/websrv-cpp.xsl
+++ b/src/VBox/Main/webservice/websrv-cpp.xsl
@@ -411,11 +411,6 @@ const char *g_pcszIUnknown = "IUnknown";
</xsl:otherwise>
</xsl:choose>
</xsl:when>
- <xsl:when test="//collection[@name=$type]">
- <xsl:variable name="thatif" select="//collection[@name=$type]" />
- <xsl:variable name="thatifname" select="$thatif/@name" />
- <xsl:value-of select="concat('ComPtr&lt;', $thatifname, '&gt;')" />
- </xsl:when>
<xsl:otherwise>
<xsl:call-template name="fatalError">
<xsl:with-param name="msg" select="concat('emitCppTypeForIDLType: Type &quot;', $type, '&quot; in method &quot;', $method, '&quot; is not supported.')" />
@@ -542,7 +537,13 @@ const char *g_pcszIUnknown = "IUnknown";
<xsl:value-of select="concat(' // convert input arg ', $name)" />
<xsl:call-template name="emitNewlineIndent8" />
- <xsl:choose>
+ <xsl:choose>
+ <xsl:when test="$safearray='yes' and $type='octet'">
+ <xsl:value-of select="concat('com::SafeArray&lt;BYTE&gt; comcall_',$name, ';')" />
+ <xsl:call-template name="emitNewlineIndent8" />
+ <xsl:value-of select="concat('Base64DecodeByteArray(',$structprefix,$name,', ComSafeArrayAsOutParam(comcall_',$name, '));')" />
+ </xsl:when>
+
<xsl:when test="$safearray='yes'">
<xsl:value-of select="concat('size_t c', $name, ' = ', $structprefix, $name, '.size();')" />
<xsl:call-template name="emitNewlineIndent8" />
@@ -597,11 +598,7 @@ const char *g_pcszIUnknown = "IUnknown";
<xsl:when test="//enum[@name=$type]">
<xsl:call-template name="emitNewlineIndent8" />
<xsl:value-of select="concat(' comcall_', $name, '[i] = ', $G_funcPrefixInputEnumConverter, $type, '(', $structprefix, $name, '[i]);')" />
- </xsl:when>
- <xsl:when test="$type='octet'">
- <xsl:call-template name="emitNewlineIndent8" />
- <xsl:value-of select="concat(' comcall_', $name, '[i] = ', $structprefix, $name, '[i];')" />
- </xsl:when>
+ </xsl:when>
<xsl:otherwise>
<xsl:call-template name="fatalError">
<xsl:with-param name="msg" select="concat('emitInputArgConverter Type &quot;', $type, '&quot; in arg &quot;', $name, '&quot; of method &quot;', $method, '&quot; is not yet supported in safearrays.')" />
@@ -994,6 +991,11 @@ const char *g_pcszIUnknown = "IUnknown";
</xsl:variable>
<xsl:choose>
+ <xsl:when test="$safearray='yes' and $type='octet'">
+ <xsl:value-of select="concat($receiverVariable, ' = Base64EncodeByteArray(ComSafeArrayAsInParam(', $varname,'));')" />
+ <xsl:call-template name="emitNewlineIndent8" />
+ </xsl:when>
+
<xsl:when test="$safearray='yes'">
<xsl:value-of select="concat('for (size_t i = 0; i &lt; ', $varname, '.size(); ++i)')" />
<xsl:call-template name="emitNewlineIndent8" />
diff --git a/src/VBox/Main/webservice/websrv-python.xsl b/src/VBox/Main/webservice/websrv-python.xsl
index 41d5cd502..16affeb3b 100644
--- a/src/VBox/Main/webservice/websrv-python.xsl
+++ b/src/VBox/Main/webservice/websrv-python.xsl
@@ -63,18 +63,25 @@
<xsl:param name="value" />
<xsl:param name="safearray" />
- <xsl:call-template name="emitConvertedType">
- <xsl:with-param name="ifname" select="$ifname" />
- <xsl:with-param name="methodname" select="$methodname" />
- <xsl:with-param name="type" select="$type" />
- </xsl:call-template>
- <xsl:text>(</xsl:text>
- <xsl:text>self.mgr,</xsl:text>
- <xsl:value-of select="$value"/>
- <xsl:if test="$safearray='yes'">
- <xsl:value-of select="', True'"/>
- </xsl:if>
- <xsl:text>)</xsl:text>
+ <xsl:choose>
+ <xsl:when test="$type='octet' and $safearray">
+ <xsl:value-of select="concat('self.mgr.decodebase64(',$value,')')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="emitConvertedType">
+ <xsl:with-param name="ifname" select="$ifname" />
+ <xsl:with-param name="methodname" select="$methodname" />
+ <xsl:with-param name="type" select="$type" />
+ </xsl:call-template>
+ <xsl:text>(</xsl:text>
+ <xsl:text>self.mgr,</xsl:text>
+ <xsl:value-of select="$value"/>
+ <xsl:if test="$safearray='yes'">
+ <xsl:value-of select="', True'"/>
+ </xsl:if>
+ <xsl:text>)</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:template>
@@ -341,11 +348,30 @@ class <xsl:value-of select="$ifname"/>:
</xsl:template>
+<xsl:template name="convertInParam">
+ <xsl:param name="type" />
+ <xsl:param name="safearray" />
+ <xsl:param name="arg" />
+
+ <xsl:choose>
+ <xsl:when test="$type='octet' and $safearray">
+ <xsl:value-of select="concat('self.mgr.encodebase64(',$arg,')')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$arg" />
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
<xsl:template name="genreq">
<xsl:text>req=</xsl:text><xsl:value-of select="../@name"/>_<xsl:value-of select="@name"/>RequestMsg()
req._this=self.handle
<xsl:for-each select="param[@dir='in']">
- req._<xsl:value-of select="@name" />=_arg_<xsl:value-of select="@name" />
+ req._<xsl:value-of select="@name" />=<xsl:call-template name="convertInParam">
+ <xsl:with-param name="type" select="@type" />
+ <xsl:with-param name="safearray" select="@safearray" />
+ <xsl:with-param name="arg" select="concat('_arg_', @name)" />
+ </xsl:call-template>
</xsl:for-each>
val=self.mgr.getPort().<xsl:value-of select="../@name"/>_<xsl:value-of select="@name"/>(req)
<!-- return needs to be the first one -->
@@ -442,7 +468,7 @@ class <xsl:value-of select="@name"/>:
</xsl:template>
<xsl:template match="/">
-<xsl:text># Copyright (C) 2008-2010 Oracle Corporation
+<xsl:text># Copyright (C) 2008-2011 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
@@ -678,26 +704,23 @@ class Number:
else:
return self.handle &gt;= other
-import struct
-
-class Octet(Number):
+class Octet:
def __init__(self, mgr, handle, isarray = False):
- self.handle = handle
self.mgr = mgr
self.isarray = isarray
+ if isarray:
+ self.handle = mgr.decodebase64(handle)
+ else:
+ raise TypeError, "only octet arrays"
def __getitem__(self, index):
- if self.isarray:
- return Octet(self.mgr, self.handle[index])
- raise TypeError, "iteration over non-sequence"
+ return self.handle[index]
def __str__(self):
- if self.isarray:
- # array of octets is binary data
- list = map (None, self.handle)
- return struct.pack("%dB" % (len(list)), *list)
- else:
- return str(self.handle)
+ return str(self.handle)
+
+ def __len__(self):
+ return self.handle.__len__()
class UnsignedInt(Number):
def __init__(self, mgr, handle, isarray = False):
@@ -843,13 +866,12 @@ class IUnknown:
<xsl:for-each select="//interface[@wsmap='struct']">
<xsl:call-template name="interfacestruct"/>
</xsl:for-each>
- <xsl:for-each select="//collection">
- <xsl:call-template name="collection"/>
- </xsl:for-each>
<xsl:for-each select="//enum">
<xsl:call-template name="enum"/>
</xsl:for-each>
+import base64
+
class IWebsessionManager2(IWebsessionManager):
def __init__(self, url):
self.url = url
@@ -865,6 +887,12 @@ class IWebsessionManager2(IWebsessionManager):
self.port = vboxServiceLocator().getvboxServicePort(self.url)
return self.port
+ def decodebase64(self, str):
+ return base64.decodestring(str)
+
+ def encodebase64(self, str):
+ return base64.encodestring(str)
+
</xsl:template>
</xsl:stylesheet>
diff --git a/src/VBox/Main/webservice/websrv-wsdl.xsl b/src/VBox/Main/webservice/websrv-wsdl.xsl
index 1b87792cd..c26db925a 100644
--- a/src/VBox/Main/webservice/websrv-wsdl.xsl
+++ b/src/VBox/Main/webservice/websrv-wsdl.xsl
@@ -210,6 +210,14 @@
<xsl:call-template name="debugMsg"><xsl:with-param name="msg" select="concat('....convertTypeAndEmitPartOrElement: arg name: ', $name)" /></xsl:call-template>
<xsl:choose>
+ <xsl:when test="$safearray='yes' and $type='octet'">
+ <!-- we pass octet arrays as Base64-encoded strings. -->
+ <xsl:element name="{$elname}">
+ <xsl:attribute name="name"><xsl:value-of select="$name" /></xsl:attribute>
+ <xsl:attribute name="type"><xsl:value-of select="'xsd:string'" /></xsl:attribute>
+ </xsl:element>
+ </xsl:when>
+
<xsl:when test="$safearray='yes'">
<xsl:element name="{$elname}"> <!-- <part> or <element> -->
<xsl:attribute name="name"><xsl:value-of select="$name" /></xsl:attribute>
diff --git a/src/VBox/Main/win/samples/VBoxCallbacks.java b/src/VBox/Main/win/samples/VBoxCallbacks.java
deleted file mode 100644
index 254d89674..000000000
--- a/src/VBox/Main/win/samples/VBoxCallbacks.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* $Id: VBoxCallbacks.java $ */
-/*
- * Copyright (C) 2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-import com.jacob.com.*;
-
-public class VBoxCallbacks
-{
- public void OnGuestPropertyChange(Variant[] args)
- {
- String machineId = args[0].getString();
- String name = args[1].getString();
- String value = args[2].getString();
- String flags = args[3].getString();;
- System.out.println("onGuestPropertyChange -- VM: " + machineId + ", " + name + "->" + value);
- }
- public void OnSnapshotChange(String machineId, String snapshotId)
- {
- System.out.println("onGuestSnapshotChange -- VM: " + machineId + ", " + snapshotId);
- }
- public void onSnapshotDeleted(String machineId, String snapshotId)
- {
- System.out.println("onSnapshotDeleted -- VM: " + machineId + ", " + snapshotId);
- }
- public void onSnapshotTaken(String machineId, String snapshotId)
- {
- }
- public void OnSessionStateChange(Variant[] args)
- {
- String machineId = args[0].getString();
- int state = args[1].getInt();
- System.out.println("onSessionStateChange -- VM: " + machineId + ", state: " + state);
- }
- public void onMachineRegistered(String machineId, boolean registered) {}
- public void onMediumRegistered(String mediumId, long mediumType, boolean registered) {}
- public void onExtraDataChange(String machineId, String key, String value)
- {
- System.out.println("onExtraDataChange -- VM: " + machineId + ": " + key+"->"+value);
- }
- public Variant OnExtraDataCanChange(String machineId, String key, String value, String[] error)
- {
- return new Variant(true);
- }
- public void onMachineDataChange(String machineId)
- {}
- public void OnMachineStateChange(Variant[] args)
- {
- String machineId = args[0].getString();
- int state = args[1].getInt();
- System.out.println("onMachineStateChange -- VM: " + machineId + ", state: " + state);
- }
-}
diff --git a/src/VBox/Main/win/samples/VBoxTest.java b/src/VBox/Main/win/samples/VBoxTest.java
deleted file mode 100644
index 09a7b9ab6..000000000
--- a/src/VBox/Main/win/samples/VBoxTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/* $Id: VBoxTest.java $ */
-/*
- * Copyright (C) 2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-import com.jacob.activeX.*;
-import com.jacob.com.ComThread;
-import com.jacob.com.Dispatch;
-import com.jacob.com.Variant;
-import com.jacob.com.SafeArray;
-import com.jacob.com.DispatchEvents;
-
-
-public class VBoxTest {
-
- private ActiveXComponent vbox = null;
-
- public VBoxTest() {
- setUp();
- }
-
- public void setUp() {
- if (vbox == null) {
- ComThread.InitMTA();
- vbox = new ActiveXComponent("VirtualBox.VirtualBox");
- String v = Dispatch.get(vbox, "Version").getString();
- System.out.println("vbox is "+v);
- }
- }
-
- public void startVm(String name)
- {
- Dispatch m = Dispatch.call(vbox, "findMachine", name).toDispatch();
- ActiveXComponent session = new ActiveXComponent("VirtualBox.Session");
- String id = Dispatch.get(m, "Id").getString();
- String type= "gui";
- Dispatch p = Dispatch.call(vbox, "openRemoteSession", session, id, type, "").toDispatch();
- Dispatch.call(p, "waitForCompletion", 10000);
- }
-
- public String list()
- {
- // returns first machine
- SafeArray sa = Dispatch.get(vbox, "Machines").toSafeArray();
- String rv = null;
-
- for (int i = sa.getLBound(); i <= sa.getUBound(); i++)
- {
- Dispatch m = sa.getVariant(i).getDispatch();
- String name = Dispatch.get(m, "Name").getString();
- if (rv == null)
- rv = name;
- String id = Dispatch.get(m, "Id").getString();
- System.out.println("name="+name+" id="+id);
- }
- return rv;
- }
-
- public void tearDown() {
- ComThread.Release();
- }
-
-
- public void testCallbacks()
- {
- VBoxCallbacks cb = new VBoxCallbacks();
- ActiveXDispatchEvents de = new ActiveXDispatchEvents(vbox, cb);
- Dispatch.call(vbox, "registerCallback", de);
- }
-
- public void testCallbacks1()
- {
- ActiveXComponent cbw = new ActiveXComponent("VirtualBox.CallbackWrapper");
- VBoxCallbacks cb = new VBoxCallbacks();
- //Dispatch.call(cbw, "setLocalObject", cb);
- Dispatch.call(vbox, "registerCallback", cbw);
- }
-
- public void testCallbacks2()
- {
- VBoxCallbacks cb = new VBoxCallbacks();
- DispatchEvents de = new DispatchEvents(vbox, cb, "VirtualBox.VirtualBox");
- //Dispatch.call(vbox, "registerCallback", );
-
- }
-
- public static void main(String[] args) {
- VBoxTest vbox = new VBoxTest();
- String first = vbox.list();
- //vbox.startVm(first);
- vbox.testCallbacks2();
- try {
- Thread.sleep(20000);
- } catch (InterruptedException ie) {}
- vbox.tearDown();
- }
-}
diff --git a/src/VBox/Main/win/samples/run.bat b/src/VBox/Main/win/samples/run.bat
deleted file mode 100644
index a271b8260..000000000
--- a/src/VBox/Main/win/samples/run.bat
+++ /dev/null
@@ -1,20 +0,0 @@
-@echo off
-REM Copyright (C) 2010 Oracle Corporation
-REM
-REM This file is part of VirtualBox Open Source Edition (OSE), as
-REM available from http://www.virtualbox.org. This file is free software;
-REM you can redistribute it and/or modify it under the terms of the GNU
-REM General Public License (GPL) as published by the Free Software
-REM Foundation, in version 2 as it comes in the "COPYING" file of the
-REM VirtualBox OSE distribution. VirtualBox OSE is distributed in the
-REM hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-REM
-
-set JAVA_HOME=c:\jdk
-set JAVA=%JAVA_HOME%\bin\java
-set JAVAC=%JAVA_HOME%\bin\javac
-rem use Jacob after 1.15
-set JACOB=s:\jacob-1.15-M3
-
-%JAVAC% -cp %JACOB%\jacob.jar VBoxTest.java VBoxCallbacks.java
-%JAVA% -cp %JACOB%\jacob.jar;. -Djava.library.path=%JACOB% VBoxTest
diff --git a/src/VBox/Main/xml/Settings.cpp b/src/VBox/Main/xml/Settings.cpp
index 5fab71d07..4fe0af5d9 100644
--- a/src/VBox/Main/xml/Settings.cpp
+++ b/src/VBox/Main/xml/Settings.cpp
@@ -1,4 +1,4 @@
-/* $Id: Settings.cpp $ */
+/* $Id: Settings.cpp 37927 2011-07-13 15:48:41Z vboxsync $ */
/** @file
* Settings File Manipulation API.
*
@@ -90,7 +90,7 @@ using namespace settings;
#define VBOX_XML_NAMESPACE "http://www.innotek.de/VirtualBox-settings"
/** VirtualBox XML settings version number substring ("x.y") */
-#define VBOX_XML_VERSION "1.11"
+#define VBOX_XML_VERSION "1.12"
/** VirtualBox XML settings version platform substring */
#if defined (RT_OS_DARWIN)
@@ -141,7 +141,7 @@ struct ConfigFileBase::Data
cleanup();
}
- iprt::MiniString strFilename;
+ RTCString strFilename;
bool fFileExists;
xml::Document *pDoc;
@@ -319,13 +319,15 @@ ConfigFileBase::ConfigFileBase(const com::Utf8Str *pstrFilename)
m->sv = SettingsVersion_v1_10;
else if (ulMinor == 11)
m->sv = SettingsVersion_v1_11;
- else if (ulMinor > 11)
+ else if (ulMinor == 12)
+ m->sv = SettingsVersion_v1_12;
+ else if (ulMinor > 12)
m->sv = SettingsVersion_Future;
}
else if (ulMajor > 1)
m->sv = SettingsVersion_Future;
- LogRel(("Parsed settings version %d.%d to enum value %d\n", ulMajor, ulMinor, m->sv));
+ Log(("Parsed settings version %d.%d to enum value %d\n", ulMajor, ulMinor, m->sv));
}
if (m->sv == SettingsVersion_Null)
@@ -339,10 +341,18 @@ ConfigFileBase::ConfigFileBase(const com::Utf8Str *pstrFilename)
{
// creating new settings file:
m->strSettingsVersionFull = VBOX_XML_VERSION_FULL;
- m->sv = SettingsVersion_v1_11;
+ m->sv = SettingsVersion_v1_12;
}
}
+ConfigFileBase::ConfigFileBase(const ConfigFileBase &other)
+ : m(new Data)
+{
+ copyBaseFrom(other);
+ m->strFilename = "";
+ m->fFileExists = false;
+}
+
/**
* Clean up.
*/
@@ -691,7 +701,7 @@ void ConfigFileBase::readMedium(MediaType t,
// DVD and floppy images before 1.11 had no format attribute. assign the default.
med.strFormat = "RAW";
}
-
+
if (t == DVDImage)
med.hdType = MediumType_Readonly;
else if (t == FloppyImage)
@@ -818,18 +828,22 @@ void ConfigFileBase::setVersionAttribute(xml::ElementNode &elm)
pcszVersion = "1.11";
break;
+ case SettingsVersion_v1_12:
+ pcszVersion = "1.12";
+ break;
+
case SettingsVersion_Future:
// can be set if this code runs on XML files that were created by a future version of VBox;
// in that case, downgrade to current version when writing since we can't write future versions...
- pcszVersion = "1.11";
- m->sv = SettingsVersion_v1_11;
- break;
+ pcszVersion = "1.12";
+ m->sv = SettingsVersion_v1_12;
+ break;
default:
// silently upgrade if this is less than 1.7 because that's the oldest we can write
pcszVersion = "1.7";
m->sv = SettingsVersion_v1_7;
- break;
+ break;
}
elm.setAttribute("version", Utf8StrFmt("%s-%s",
@@ -846,7 +860,7 @@ void ConfigFileBase::setVersionAttribute(xml::ElementNode &elm)
* Before calling this, it is the responsibility of the caller to
* set the "sv" member to the required settings version that is to
* be written. For newly created files, the settings version will be
- * the latest (1.11); for files read in from disk earlier, it will be
+ * the latest (1.12); for files read in from disk earlier, it will be
* the settings version indicated in the file. However, this method
* will silently make sure that the settings version is always
* at least 1.7 and change it if necessary, since there is no write
@@ -1462,19 +1476,23 @@ bool USBController::operator==(const USBController &u) const
bool NetworkAdapter::operator==(const NetworkAdapter &n) const
{
return ( (this == &n)
- || ( (ulSlot == n.ulSlot)
- && (type == n.type)
- && (fEnabled == n.fEnabled)
- && (strMACAddress == n.strMACAddress)
- && (fCableConnected == n.fCableConnected)
- && (ulLineSpeed == n.ulLineSpeed)
- && (fTraceEnabled == n.fTraceEnabled)
- && (strTraceFile == n.strTraceFile)
- && (mode == n.mode)
- && (nat == n.nat)
- && (strName == n.strName)
- && (ulBootPriority == n.ulBootPriority)
- && (fHasDisabledNAT == n.fHasDisabledNAT)
+ || ( (ulSlot == n.ulSlot)
+ && (type == n.type)
+ && (fEnabled == n.fEnabled)
+ && (strMACAddress == n.strMACAddress)
+ && (fCableConnected == n.fCableConnected)
+ && (ulLineSpeed == n.ulLineSpeed)
+ && (enmPromiscModePolicy == n.enmPromiscModePolicy)
+ && (fTraceEnabled == n.fTraceEnabled)
+ && (strTraceFile == n.strTraceFile)
+ && (mode == n.mode)
+ && (nat == n.nat)
+ && (strBridgedName == n.strBridgedName)
+ && (strHostOnlyName == n.strHostOnlyName)
+ && (strInternalNetworkName == n.strInternalNetworkName)
+ && (strGenericDriver == n.strGenericDriver)
+ && (genericProperties == n.genericProperties)
+ && (ulBootPriority == n.ulBootPriority)
)
);
}
@@ -1657,6 +1675,7 @@ bool Hardware::operator==(const Hardware& h) const
&& (llGuestProperties == h.llGuestProperties)
&& (strNotificationPatterns == h.strNotificationPatterns)
&& (ioSettings == h.ioSettings)
+ && (pciAttachments == h.pciAttachments)
)
);
}
@@ -1671,6 +1690,8 @@ bool AttachedDevice::operator==(const AttachedDevice &a) const
return ( (this == &a)
|| ( (deviceType == a.deviceType)
&& (fPassThrough == a.fPassThrough)
+ && (fTempEject == a.fTempEject)
+ && (fNonRotational == a.fNonRotational)
&& (lPort == a.lPort)
&& (lDevice == a.lDevice)
&& (uuid == a.uuid)
@@ -1934,10 +1955,24 @@ void MachineConfigFile::readNetworkAdapters(const xml::ElementNode &elmNetwork,
pelmAdapter->getAttributeValue("MACAddress", nic.strMACAddress);
pelmAdapter->getAttributeValue("cable", nic.fCableConnected);
pelmAdapter->getAttributeValue("speed", nic.ulLineSpeed);
+
+ if (pelmAdapter->getAttributeValue("promiscuousModePolicy", strTemp))
+ {
+ if (strTemp == "Deny")
+ nic.enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_Deny;
+ else if (strTemp == "AllowNetwork")
+ nic.enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowNetwork;
+ else if (strTemp == "AllowAll")
+ nic.enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowAll;
+ else
+ throw ConfigFileError(this, pelmAdapter,
+ N_("Invalid value '%s' in Adapter/@promiscuousModePolicy attribute"), strTemp.c_str());
+ }
+
pelmAdapter->getAttributeValue("trace", nic.fTraceEnabled);
pelmAdapter->getAttributeValue("tracefile", nic.strTraceFile);
pelmAdapter->getAttributeValue("bootPriority", nic.ulBootPriority);
- pelmAdapter->getAttributeValue("bandwidthLimit", nic.ulBandwidthLimit);
+ pelmAdapter->getAttributeValue("bandwidthGroup", nic.strBandwidthGroup);
xml::ElementNodesList llNetworkModes;
pelmAdapter->getChildElements(llNetworkModes);
@@ -1974,13 +2009,12 @@ void MachineConfigFile::readNetworkAdapters(const xml::ElementNode &elmNetwork,
void MachineConfigFile::readAttachedNetworkMode(const xml::ElementNode &elmMode, bool fEnabled, NetworkAdapter &nic)
{
+ NetworkAttachmentType_T enmAttachmentType = NetworkAttachmentType_Null;
+
if (elmMode.nameEquals("NAT"))
{
- if (fEnabled)
- nic.mode = NetworkAttachmentType_NAT;
+ enmAttachmentType = NetworkAttachmentType_NAT;
- nic.fHasDisabledNAT = (nic.mode != NetworkAttachmentType_NAT && !fEnabled);
- elmMode.getAttributeValue("network", nic.nat.strNetwork); // optional network name
elmMode.getAttributeValue("hostip", nic.nat.strBindIP);
elmMode.getAttributeValue("mtu", nic.nat.u32Mtu);
elmMode.getAttributeValue("sockrcv", nic.nat.u32SockRcv);
@@ -2025,36 +2059,62 @@ void MachineConfigFile::readAttachedNetworkMode(const xml::ElementNode &elmMode,
nic.nat.llRules.push_back(rule);
}
}
- else if ( fEnabled
- && ( (elmMode.nameEquals("HostInterface"))
- || (elmMode.nameEquals("BridgedInterface")))
- )
+ else if ( (elmMode.nameEquals("HostInterface"))
+ || (elmMode.nameEquals("BridgedInterface")))
{
- nic.mode = NetworkAttachmentType_Bridged;
- elmMode.getAttributeValue("name", nic.strName); // optional host interface name
+ enmAttachmentType = NetworkAttachmentType_Bridged;
+
+ elmMode.getAttributeValue("name", nic.strBridgedName); // optional bridged interface name
}
- else if ( fEnabled
- && elmMode.nameEquals("InternalNetwork"))
+ else if (elmMode.nameEquals("InternalNetwork"))
{
- nic.mode = NetworkAttachmentType_Internal;
- if (!elmMode.getAttributeValue("name", nic.strName)) // required network name
+ enmAttachmentType = NetworkAttachmentType_Internal;
+
+ if (!elmMode.getAttributeValue("name", nic.strInternalNetworkName)) // required network name
throw ConfigFileError(this, &elmMode, N_("Required InternalNetwork/@name element is missing"));
}
- else if ( fEnabled
- && elmMode.nameEquals("HostOnlyInterface"))
+ else if (elmMode.nameEquals("HostOnlyInterface"))
{
- nic.mode = NetworkAttachmentType_HostOnly;
- if (!elmMode.getAttributeValue("name", nic.strName)) // required network name
+ enmAttachmentType = NetworkAttachmentType_HostOnly;
+
+ if (!elmMode.getAttributeValue("name", nic.strHostOnlyName)) // required network name
throw ConfigFileError(this, &elmMode, N_("Required HostOnlyInterface/@name element is missing"));
}
-#if defined(VBOX_WITH_VDE)
- else if ( fEnabled
- && elmMode.nameEquals("VDE"))
+ else if (elmMode.nameEquals("GenericInterface"))
+ {
+ enmAttachmentType = NetworkAttachmentType_Generic;
+
+ elmMode.getAttributeValue("driver", nic.strGenericDriver); // optional network attachment driver
+
+ // get all properties
+ xml::NodesLoop nl(elmMode);
+ const xml::ElementNode *pelmModeChild;
+ while ((pelmModeChild = nl.forAllNodes()))
+ {
+ if (pelmModeChild->nameEquals("Property"))
+ {
+ Utf8Str strPropName, strPropValue;
+ if ( (pelmModeChild->getAttributeValue("name", strPropName))
+ && (pelmModeChild->getAttributeValue("value", strPropValue))
+ )
+ nic.genericProperties[strPropName] = strPropValue;
+ else
+ throw ConfigFileError(this, pelmModeChild, N_("Required GenericInterface/Property/@name or @value attribute is missing"));
+ }
+ }
+ }
+ else if (elmMode.nameEquals("VDE"))
{
- nic.mode = NetworkAttachmentType_VDE;
- elmMode.getAttributeValue("network", nic.strName); // optional network name
+ enmAttachmentType = NetworkAttachmentType_Generic;
+
+ com::Utf8Str strVDEName;
+ elmMode.getAttributeValue("network", strVDEName); // optional network name
+ nic.strGenericDriver = "VDE";
+ nic.genericProperties["network"] = strVDEName;
}
-#endif
+
+ if (fEnabled && enmAttachmentType != NetworkAttachmentType_Null)
+ nic.mode = enmAttachmentType;
}
/**
@@ -2728,6 +2788,29 @@ void MachineConfigFile::readHardware(const xml::ElementNode &elmHardware,
hw.ioSettings.llBandwidthGroups.push_back(gr);
}
}
+ } else if (pelmHwChild->nameEquals("HostPci")) {
+ const xml::ElementNode *pelmDevices;
+
+ if ((pelmDevices = pelmHwChild->findChildElement("Devices")))
+ {
+ xml::NodesLoop nl2(*pelmDevices, "Device");
+ const xml::ElementNode *pelmDevice;
+ while ((pelmDevice = nl2.forAllNodes()))
+ {
+ HostPciDeviceAttachment hpda;
+
+ if (!pelmDevice->getAttributeValue("host", hpda.uHostAddress))
+ throw ConfigFileError(this, pelmDevice, N_("Missing Device/@host attribute"));
+
+ if (!pelmDevice->getAttributeValue("guest", hpda.uGuestAddress))
+ throw ConfigFileError(this, pelmDevice, N_("Missing Device/@guest attribute"));
+
+ /* name is optional */
+ pelmDevice->getAttributeValue("name", hpda.strDeviceName);
+
+ hw.pciAttachments.push_back(hpda);
+ }
+ }
}
}
@@ -2901,7 +2984,10 @@ void MachineConfigFile::readStorageControllers(const xml::ElementNode &elmStorag
pelmAttached->getAttributeValue("type", strTemp);
if (strTemp == "HardDisk")
+ {
att.deviceType = DeviceType_HardDisk;
+ pelmAttached->getAttributeValue("nonrotational", att.fNonRotational);
+ }
else if (m->sv >= SettingsVersion_v1_9)
{
// starting with 1.9 we list DVD and floppy drive info + attachments under <StorageControllers>
@@ -2909,6 +2995,7 @@ void MachineConfigFile::readStorageControllers(const xml::ElementNode &elmStorag
{
att.deviceType = DeviceType_DVD;
pelmAttached->getAttributeValue("passthrough", att.fPassThrough);
+ pelmAttached->getAttributeValue("tempeject", att.fTempEject);
}
else if (strTemp == "Floppy")
att.deviceType = DeviceType_Floppy;
@@ -2980,6 +3067,7 @@ void MachineConfigFile::readDVDAndFloppies_pre1_9(const xml::ElementNode &elmHar
att.lPort = 1;
att.lDevice = 0;
pelmHwChild->getAttributeValue("passthrough", att.fPassThrough);
+ pelmHwChild->getAttributeValue("tempeject", att.fTempEject);
const xml::ElementNode *pDriveChild;
Utf8Str strTmp;
@@ -3212,6 +3300,8 @@ void MachineConfigFile::readMachine(const xml::ElementNode &elmMachine)
if (elmMachine.getAttributeValue("lastStateChange", str))
parseTimestamp(timeLastStateChange, str);
// constructor has called RTTimeNow(&timeLastStateChange) before
+ if (elmMachine.getAttributeValue("aborted", fAborted))
+ fAborted = true;
// parse Hardware before the other elements because other things depend on it
const xml::ElementNode *pelmHardware;
@@ -3376,11 +3466,11 @@ void MachineConfigFile::buildHardwareXML(xml::ElementNode &elmParent,
switch (hw.firmwareType)
{
- case FirmwareType_EFI: pcszFirmware = "EFI"; break;
- case FirmwareType_EFI32: pcszFirmware = "EFI32"; break;
- case FirmwareType_EFI64: pcszFirmware = "EFI64"; break;
+ case FirmwareType_EFI: pcszFirmware = "EFI"; break;
+ case FirmwareType_EFI32: pcszFirmware = "EFI32"; break;
+ case FirmwareType_EFI64: pcszFirmware = "EFI64"; break;
case FirmwareType_EFIDUAL: pcszFirmware = "EFIDUAL"; break;
- default: pcszFirmware = "None"; break;
+ default: pcszFirmware = "None"; break;
}
pelmFirmware->setAttribute("type", pcszFirmware);
}
@@ -3601,6 +3691,8 @@ void MachineConfigFile::buildHardwareXML(xml::ElementNode &elmParent,
++cDVDs;
pelmDVD->setAttribute("passthrough", att.fPassThrough);
+ if (att.fTempEject)
+ pelmDVD->setAttribute("tempeject", att.fTempEject);
if (!att.uuid.isEmpty())
pelmDVD->createChild("Image")->setAttribute("uuid", att.uuid.toStringCurly());
else if (att.strHostDriveSrc.length())
@@ -3663,8 +3755,19 @@ void MachineConfigFile::buildHardwareXML(xml::ElementNode &elmParent,
pelmAdapter->setAttribute("trace", nic.fTraceEnabled);
pelmAdapter->setAttribute("tracefile", nic.strTraceFile);
}
- if (nic.ulBandwidthLimit)
- pelmAdapter->setAttribute("bandwidthLimit", nic.ulBandwidthLimit);
+ if (nic.strBandwidthGroup.isNotEmpty())
+ pelmAdapter->setAttribute("bandwidthGroup", nic.strBandwidthGroup);
+
+ const char *pszPolicy;
+ switch (nic.enmPromiscModePolicy)
+ {
+ case NetworkAdapterPromiscModePolicy_Deny: pszPolicy = NULL; break;
+ case NetworkAdapterPromiscModePolicy_AllowNetwork: pszPolicy = "AllowNetwork"; break;
+ case NetworkAdapterPromiscModePolicy_AllowAll: pszPolicy = "AllowAll"; break;
+ default: pszPolicy = NULL; AssertFailed(); break;
+ }
+ if (pszPolicy)
+ pelmAdapter->setAttribute("promiscuousModePolicy", pszPolicy);
const char *pcszType;
switch (nic.type)
@@ -3687,39 +3790,40 @@ void MachineConfigFile::buildHardwareXML(xml::ElementNode &elmParent,
pelmNAT = pelmAdapter->createChild("NAT");
if (nic.nat.strNetwork.length())
pelmNAT->setAttribute("network", nic.nat.strNetwork);
- break;
+ break;
case NetworkAttachmentType_Bridged:
- pelmAdapter->createChild("BridgedInterface")->setAttribute("name", nic.strName);
- break;
+ pelmAdapter->createChild("BridgedInterface")->setAttribute("name", nic.strBridgedName);
+ break;
case NetworkAttachmentType_Internal:
- pelmAdapter->createChild("InternalNetwork")->setAttribute("name", nic.strName);
- break;
+ pelmAdapter->createChild("InternalNetwork")->setAttribute("name", nic.strInternalNetworkName);
+ break;
case NetworkAttachmentType_HostOnly:
- pelmAdapter->createChild("HostOnlyInterface")->setAttribute("name", nic.strName);
- break;
-
-#if defined(VBOX_WITH_VDE)
- case NetworkAttachmentType_VDE:
- pelmAdapter->createChild("VDE")->setAttribute("network", nic.strName);
- break;
-#endif
+ pelmAdapter->createChild("HostOnlyInterface")->setAttribute("name", nic.strHostOnlyName);
+ break;
default: /*case NetworkAttachmentType_Null:*/
- break;
+ break;
}
}
else
{
/* m->sv >= SettingsVersion_v1_10 */
- xml::ElementNode *pelmDisabledNode= NULL;
- if (nic.fHasDisabledNAT)
- pelmDisabledNode = pelmAdapter->createChild("DisabledModes");
- if (nic.fHasDisabledNAT)
- buildNetworkXML(NetworkAttachmentType_NAT, *pelmDisabledNode, nic);
- buildNetworkXML(nic.mode, *pelmAdapter, nic);
+ xml::ElementNode *pelmDisabledNode = NULL;
+ pelmDisabledNode = pelmAdapter->createChild("DisabledModes");
+ if (nic.mode != NetworkAttachmentType_NAT)
+ buildNetworkXML(NetworkAttachmentType_NAT, *pelmDisabledNode, false, nic);
+ if (nic.mode != NetworkAttachmentType_Bridged)
+ buildNetworkXML(NetworkAttachmentType_Bridged, *pelmDisabledNode, false, nic);
+ if (nic.mode != NetworkAttachmentType_Internal)
+ buildNetworkXML(NetworkAttachmentType_HostOnly, *pelmDisabledNode, false, nic);
+ if (nic.mode != NetworkAttachmentType_HostOnly)
+ buildNetworkXML(NetworkAttachmentType_HostOnly, *pelmDisabledNode, false, nic);
+ if (nic.mode != NetworkAttachmentType_Generic)
+ buildNetworkXML(NetworkAttachmentType_Generic, *pelmDisabledNode, false, nic);
+ buildNetworkXML(nic.mode, *pelmAdapter, true, nic);
}
}
@@ -3790,7 +3894,8 @@ void MachineConfigFile::buildHardwareXML(xml::ElementNode &elmParent,
/* fall through */
case AudioControllerType_AC97:
default:
- pcszController = "AC97"; break;
+ pcszController = "AC97";
+ break;
}
pelmAudio->setAttribute("controller", pcszController);
@@ -3872,6 +3977,25 @@ void MachineConfigFile::buildHardwareXML(xml::ElementNode &elmParent,
}
}
+ if (m->sv >= SettingsVersion_v1_12)
+ {
+ xml::ElementNode *pelmPci = pelmHardware->createChild("HostPci");
+ xml::ElementNode *pelmPciDevices = pelmPci->createChild("Devices");
+
+ for (HostPciDeviceAttachmentList::const_iterator it = hw.pciAttachments.begin();
+ it != hw.pciAttachments.end();
+ ++it)
+ {
+ const HostPciDeviceAttachment &hpda = *it;
+
+ xml::ElementNode *pelmThis = pelmPciDevices->createChild("Device");
+
+ pelmThis->setAttribute("host", hpda.uHostAddress);
+ pelmThis->setAttribute("guest", hpda.uGuestAddress);
+ pelmThis->setAttribute("name", hpda.strDeviceName);
+ }
+ }
+
xml::ElementNode *pelmGuest = pelmHardware->createChild("Guest");
pelmGuest->setAttribute("memoryBalloonSize", hw.ulMemoryBalloonSize);
@@ -3896,10 +4020,12 @@ void MachineConfigFile::buildHardwareXML(xml::ElementNode &elmParent,
* Fill a <Network> node. Only relevant for XML version >= v1_10.
* @param mode
* @param elmParent
- * @param nice
+ * @param fEnabled
+ * @param nic
*/
void MachineConfigFile::buildNetworkXML(NetworkAttachmentType_T mode,
xml::ElementNode &elmParent,
+ bool fEnabled,
const NetworkAdapter &nic)
{
switch (mode)
@@ -3964,28 +4090,41 @@ void MachineConfigFile::buildNetworkXML(NetworkAttachmentType_T mode,
if ((*rule).u16GuestPort)
pelmPF->setAttribute("guestport", (*rule).u16GuestPort);
}
- break;
+ break;
case NetworkAttachmentType_Bridged:
- elmParent.createChild("BridgedInterface")->setAttribute("name", nic.strName);
- break;
+ if (fEnabled || !nic.strBridgedName.isEmpty())
+ elmParent.createChild("BridgedInterface")->setAttribute("name", nic.strBridgedName);
+ break;
case NetworkAttachmentType_Internal:
- elmParent.createChild("InternalNetwork")->setAttribute("name", nic.strName);
- break;
+ if (fEnabled || !nic.strInternalNetworkName.isEmpty())
+ elmParent.createChild("InternalNetwork")->setAttribute("name", nic.strInternalNetworkName);
+ break;
case NetworkAttachmentType_HostOnly:
- elmParent.createChild("HostOnlyInterface")->setAttribute("name", nic.strName);
- break;
+ if (fEnabled || !nic.strHostOnlyName.isEmpty())
+ elmParent.createChild("HostOnlyInterface")->setAttribute("name", nic.strHostOnlyName);
+ break;
-#ifdef VBOX_WITH_VDE
- case NetworkAttachmentType_VDE:
- elmParent.createChild("VDE")->setAttribute("network", nic.strName);
- break;
-#endif
+ case NetworkAttachmentType_Generic:
+ if (fEnabled || !nic.strGenericDriver.isEmpty() || nic.genericProperties.size())
+ {
+ xml::ElementNode *pelmMode = elmParent.createChild("GenericInterface");
+ pelmMode->setAttribute("driver", nic.strGenericDriver);
+ for (StringsMap::const_iterator it = nic.genericProperties.begin();
+ it != nic.genericProperties.end();
+ ++it)
+ {
+ xml::ElementNode *pelmProp = pelmMode->createChild("Property");
+ pelmProp->setAttribute("name", it->first);
+ pelmProp->setAttribute("value", it->second);
+ }
+ }
+ break;
default: /*case NetworkAttachmentType_Null:*/
- break;
+ break;
}
}
@@ -4094,16 +4233,20 @@ void MachineConfigFile::buildStorageControllersXML(xml::ElementNode &elmParent,
{
case DeviceType_HardDisk:
pcszType = "HardDisk";
- break;
+ if (att.fNonRotational)
+ pelmDevice->setAttribute("nonrotational", att.fNonRotational);
+ break;
case DeviceType_DVD:
pcszType = "DVD";
pelmDevice->setAttribute("passthrough", att.fPassThrough);
- break;
+ if (att.fTempEject)
+ pelmDevice->setAttribute("tempeject", att.fTempEject);
+ break;
case DeviceType_Floppy:
pcszType = "Floppy";
- break;
+ break;
}
pelmDevice->setAttribute("type", pcszType);
@@ -4383,9 +4526,9 @@ AudioDriverType_T MachineConfigFile::getHostDefaultAudioDriver()
return AudioDriverType_SolAudio;
#elif defined(RT_OS_LINUX)
// on Linux, we need to check at runtime what's actually supported...
- static RTLockMtx s_mtx;
+ static RTCLockMtx s_mtx;
static AudioDriverType_T s_linuxDriver = -1;
- RTLock lock(s_mtx);
+ RTCLock lock(s_mtx);
if (s_linuxDriver == (AudioDriverType_T)-1)
{
# if defined(VBOX_WITH_PULSE)
@@ -4397,9 +4540,9 @@ AudioDriverType_T MachineConfigFile::getHostDefaultAudioDriver()
# endif /* VBOX_WITH_PULSE */
# if defined(VBOX_WITH_ALSA)
/* Check if we can load the ALSA library */
- if (RTLdrIsLoadable("libasound.so.2"))
+ if (RTLdrIsLoadable("libasound.so.2"))
s_linuxDriver = AudioDriverType_ALSA;
- else
+ else
# endif /* VBOX_WITH_ALSA */
s_linuxDriver = AudioDriverType_OSS;
}
@@ -4427,6 +4570,34 @@ AudioDriverType_T MachineConfigFile::getHostDefaultAudioDriver()
*/
void MachineConfigFile::bumpSettingsVersionIfNeeded()
{
+ if (m->sv < SettingsVersion_v1_12)
+ {
+ // VirtualBox 4.1 adds PCI passthrough.
+ if (hardwareMachine.pciAttachments.size())
+ m->sv = SettingsVersion_v1_12;
+ }
+
+ if (m->sv < SettingsVersion_v1_12)
+ {
+ // VirtualBox 4.1 adds a promiscuous mode policy to the network
+ // adapters and a generic network driver transport.
+ NetworkAdaptersList::const_iterator netit;
+ for (netit = hardwareMachine.llNetworkAdapters.begin();
+ netit != hardwareMachine.llNetworkAdapters.end();
+ ++netit)
+ {
+ if ( netit->enmPromiscModePolicy != NetworkAdapterPromiscModePolicy_Deny
+ || netit->mode == NetworkAttachmentType_Generic
+ || !netit->strGenericDriver.isEmpty()
+ || netit->genericProperties.size()
+ )
+ {
+ m->sv = SettingsVersion_v1_12;
+ break;
+ }
+ }
+ }
+
if (m->sv < SettingsVersion_v1_11)
{
// VirtualBox 4.0 adds HD audio, CPU priorities, fault tolerance,
@@ -4644,12 +4815,12 @@ void MachineConfigFile::bumpSettingsVersionIfNeeded()
netit != hardwareMachine.llNetworkAdapters.end();
++netit)
{
- if ( (m->sv < SettingsVersion_v1_11)
- && (netit->ulBandwidthLimit)
+ if ( (m->sv < SettingsVersion_v1_12)
+ && (netit->strBandwidthGroup.isNotEmpty())
)
{
- /* New in VirtualBox 4.0 */
- m->sv = SettingsVersion_v1_11;
+ /* New in VirtualBox 4.1 */
+ m->sv = SettingsVersion_v1_12;
break;
}
else if ( (m->sv < SettingsVersion_v1_10)
diff --git a/src/VBox/Main/xml/VirtualBox-settings-common.xsd b/src/VBox/Main/xml/VirtualBox-settings-common.xsd
index 1c602d322..7e596e137 100644
--- a/src/VBox/Main/xml/VirtualBox-settings-common.xsd
+++ b/src/VBox/Main/xml/VirtualBox-settings-common.xsd
@@ -6,7 +6,7 @@
* Oracle VM VirtualBox Settings Schema
* Common definitions
- Copyright (C) 2004-2010 Oracle Corporation
+ Copyright (C) 2004-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;
@@ -766,6 +766,18 @@
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
+ <xsd:element name="Generic">
+ <xsd:complexType>
+ <xsd:attribute name="driver" type="xsd:string" use="required"/>
+ </xsd:complexType>
+ <xsd:element name="Property" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:attribute name="name" type="xsd:token" use="required"/>
+ <xsd:attribute name="value" type="xsd:string" use="required"/>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:element>
+ <!-- The DisabledModes tag is not part of this XSD file right now. -->
</xsd:choice>
<xsd:attribute name="type" type="TNetworkAdapterType" default="Am79C970A"/>
<xsd:attribute name="slot" use="required">
@@ -883,7 +895,7 @@
<xsd:simpleType>
<xsd:restriction base="xsd:unsignedInt">
<xsd:minInclusive value="4"/>
- <xsd:maxInclusive value="16384"/>
+ <xsd:maxInclusive value="2097152"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
diff --git a/src/VBox/Main/xml/ovfreader.cpp b/src/VBox/Main/xml/ovfreader.cpp
index be4a05cbf..0d8af9ceb 100644
--- a/src/VBox/Main/xml/ovfreader.cpp
+++ b/src/VBox/Main/xml/ovfreader.cpp
@@ -1,8 +1,8 @@
-/* $Id: ovfreader.cpp $ */
+/* $Id: ovfreader.cpp 37869 2011-07-11 12:42:46Z vboxsync $ */
/** @file
+ * OVF reader declarations.
*
- * OVF reader declarations. Depends only on IPRT, including the iprt::MiniString
- * and IPRT XML classes.
+ * Depends only on IPRT, including the RTCString and IPRT XML classes.
*/
/*
@@ -20,7 +20,6 @@
#include "ovfreader.h"
using namespace std;
-using namespace iprt;
using namespace ovf;
////////////////////////////////////////////////////////////////////////////////
@@ -36,7 +35,7 @@ using namespace ovf;
* @param cbSize the size of the memory buffer
* @param path path to a filename for error messages.
*/
-OVFReader::OVFReader(const void *pvBuf, size_t cbSize, const MiniString &path)
+OVFReader::OVFReader(const void *pvBuf, size_t cbSize, const RTCString &path)
: m_strPath(path)
{
xml::XmlMemParser parser;
@@ -52,7 +51,7 @@ OVFReader::OVFReader(const void *pvBuf, size_t cbSize, const MiniString &path)
* on XML or OVF invalidity.
* @param path
*/
-OVFReader::OVFReader(const MiniString &path)
+OVFReader::OVFReader(const RTCString &path)
: m_strPath(path)
{
xml::XmlFileParser parser;
@@ -508,7 +507,7 @@ void OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSy
i.ullVirtualQuantity,
UINT16_MAX,
i.ulLineNumber);
- break;
+ break;
case ResourceType_Memory: // 4
if ( (i.strAllocationUnits == "MegaBytes") // found in OVF created by OVF toolkit
@@ -521,7 +520,7 @@ void OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSy
m_strPath.c_str(),
i.strAllocationUnits.c_str(),
i.ulLineNumber);
- break;
+ break;
case ResourceType_IDEController: // 5
{
@@ -570,8 +569,8 @@ void OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSy
vsys.mapControllers[i.ulInstanceID] = hdc;
if (!pPrimaryIDEController)
pPrimaryIDEController = &vsys.mapControllers[i.ulInstanceID];
+ break;
}
- break;
case ResourceType_ParallelSCSIHBA: // 6 SCSI controller
{
@@ -589,8 +588,8 @@ void OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSy
hdc.strControllerType = i.strResourceSubType;
vsys.mapControllers[i.ulInstanceID] = hdc;
+ break;
}
- break;
case ResourceType_EthernetAdapter: // 10
{
@@ -615,12 +614,12 @@ void OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSy
ea.strAdapterType = i.strResourceSubType;
ea.strNetworkName = i.strConnection;
vsys.llEthernetAdapters.push_back(ea);
+ break;
}
- break;
case ResourceType_FloppyDrive: // 14
vsys.fHasFloppyDrive = true; // we have no additional information
- break;
+ break;
case ResourceType_CDDrive: // 15
/* <Item ovf:required="false">
@@ -635,11 +634,11 @@ void OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSy
// but then the ovftool dies with "Device backing not supported". So I guess if
// VMware can't export ISOs, then we don't need to be able to import them right now.
vsys.fHasCdromDrive = true; // we have no additional information
- break;
+ break;
case ResourceType_HardDisk: // 17
// handled separately in second loop below
- break;
+ break;
case ResourceType_OtherStorageDevice: // 20 SATA controller
{
@@ -652,8 +651,8 @@ void OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSy
<rasd:Address>0</rasd:Address>
<rasd:BusNumber>0</rasd:BusNumber>
</Item> */
- if ( i.strCaption.startsWith("sataController", MiniString::CaseInsensitive)
- && !i.strResourceSubType.compare("AHCI", MiniString::CaseInsensitive)
+ if ( i.strCaption.startsWith("sataController", RTCString::CaseInsensitive)
+ && !i.strResourceSubType.compare("AHCI", RTCString::CaseInsensitive)
)
{
HardDiskController hdc;
@@ -668,8 +667,8 @@ void OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSy
m_strPath.c_str(),
ResourceType_OtherStorageDevice,
i.ulLineNumber);
+ break;
}
- break;
case ResourceType_USBController: // 23
/* <Item ovf:required="false">
@@ -681,7 +680,7 @@ void OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSy
<rasd:BusNumber>0</rasd:BusNumber>
</Item> */
vsys.fHasUsbController = true; // we have no additional information
- break;
+ break;
case ResourceType_SoundCard: // 35
/* <Item ovf:required="false">
@@ -694,7 +693,7 @@ void OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSy
<rasd:AddressOnParent>3</rasd:AddressOnParent>
</Item> */
vsys.strSoundCardType = i.strResourceSubType;
- break;
+ break;
default:
{
@@ -767,9 +766,10 @@ void OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSy
i.ulLineNumber);
vsys.mapVirtualDisks[vd.strDiskId] = vd;
+ break;
}
- break;
- default: break;
+ default:
+ break;
}
}
}
diff --git a/src/VBox/Makefile.kmk b/src/VBox/Makefile.kmk
index e3fe32a92..39b7b320d 100644
--- a/src/VBox/Makefile.kmk
+++ b/src/VBox/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 34662 2010-12-02 21:51:17Z vboxsync $
## @file
# Top-level makefile for src/VBox.
#
diff --git a/src/VBox/NetworkServices/DHCP/Makefile.kmk b/src/VBox/NetworkServices/DHCP/Makefile.kmk
index 45db7eceb..981b9cafd 100644
--- a/src/VBox/NetworkServices/DHCP/Makefile.kmk
+++ b/src/VBox/NetworkServices/DHCP/Makefile.kmk
@@ -1,4 +1,4 @@
- # $Id: Makefile.kmk $
+ # $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for VBoxNetDHCP.
#
diff --git a/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp b/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
index 6a7c24dea..e76d4d9ba 100644
--- a/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
+++ b/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetDHCP.cpp $ */
+/* $Id: VBoxNetDHCP.cpp 36469 2011-03-30 08:52:15Z vboxsync $ */
/** @file
* VBoxNetDHCP - DHCP Service for connecting to IntNet.
*/
diff --git a/src/VBox/NetworkServices/DHCP/VBoxNetDHCPHardened.cpp b/src/VBox/NetworkServices/DHCP/VBoxNetDHCPHardened.cpp
index 7d0e1bef3..046c206bd 100644
--- a/src/VBox/NetworkServices/DHCP/VBoxNetDHCPHardened.cpp
+++ b/src/VBox/NetworkServices/DHCP/VBoxNetDHCPHardened.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetDHCPHardened.cpp $ */
+/* $Id: VBoxNetDHCPHardened.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxNetDHCP - Hardened main().
*/
diff --git a/src/VBox/NetworkServices/Makefile.kmk b/src/VBox/NetworkServices/Makefile.kmk
index affd27263..46b2e2004 100644
--- a/src/VBox/NetworkServices/Makefile.kmk
+++ b/src/VBox/NetworkServices/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Top-level makefile for the VBox Network Services.
#
diff --git a/src/VBox/NetworkServices/NAT/Makefile.kmk b/src/VBox/NetworkServices/NAT/Makefile.kmk
index 281cba1f0..34e40539a 100644
--- a/src/VBox/NetworkServices/NAT/Makefile.kmk
+++ b/src/VBox/NetworkServices/NAT/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 36217 2011-03-09 03:22:09Z vboxsync $
## @file
#
@@ -52,7 +52,6 @@ $(foreach file,$(addprefix ../../Devices/, $(VBOX_SLIRP_ALIAS_SOURCES)),$(eval $
VBoxNetNAT_SOURCES += ../NetLib/VBoxNetBaseService.cpp
VBoxNetNAT_LIBS = \
- $(PATH_LIB)/Drivers$(VBOX_SUFF_LIB) \
$(LIB_RUNTIME)
VBoxNetNAT_LDFLAGS.win = /SUBSYSTEM:windows
diff --git a/src/VBox/NetworkServices/NAT/VBoxNetNAT.cpp b/src/VBox/NetworkServices/NAT/VBoxNetNAT.cpp
index b35a40a85..28e5a8db3 100644
--- a/src/VBox/NetworkServices/NAT/VBoxNetNAT.cpp
+++ b/src/VBox/NetworkServices/NAT/VBoxNetNAT.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetNAT.cpp $ */
+/* $Id: VBoxNetNAT.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* VBoxNetNAT - NAT Service for connecting to IntNet.
*/
@@ -34,6 +34,7 @@
#include <iprt/stream.h>
#include <iprt/path.h>
#include <iprt/param.h>
+#include <iprt/pipe.h>
#include <iprt/getopt.h>
#include <iprt/string.h>
#include <iprt/mem.h>
@@ -46,8 +47,8 @@
#include <VBox/sup.h>
#include <VBox/intnet.h>
#include <VBox/intnetinline.h>
-#include <VBox/pdmnetinline.h>
-#include <VBox/vmm.h>
+#include <VBox/vmm/pdmnetinline.h>
+#include <VBox/vmm/vmm.h>
#include <VBox/version.h>
#include <vector>
@@ -89,8 +90,8 @@ public:
#ifdef RT_OS_WINDOWS
HANDLE m_hWakeupEvent;
#else
- RTFILE m_PipeWrite;
- RTFILE m_PipeRead;
+ RTPIPE m_hPipeWrite;
+ RTPIPE m_hPipeRead;
#endif
/** Queue for NAT-thread-external events. */
/** event to wakeup the guest receive thread */
@@ -125,7 +126,8 @@ static void natNotifyNATThread(void)
int rc;
#ifndef RT_OS_WINDOWS
/* kick select() */
- rc = RTFileWrite(g_pNAT->m_PipeWrite, "", 1, NULL);
+ size_t cbIgnored;
+ rc = RTPipeWrite(g_pNAT->m_hPipeWrite, "", 1, &cbIgnored);
#else
/* kick WSAWaitForMultipleEvents */
rc = WSASetEvent(g_pNAT->hWakeupEvent);
@@ -169,17 +171,11 @@ void VBoxNetNAT::init()
/*
* Create the control pipe.
*/
- int fds[2];
- if (pipe(&fds[0]) != 0) /** @todo RTPipeCreate() or something... */
- {
- rc = RTErrConvertFromErrno(errno);
- AssertReleaseRC(rc);
- return;
- }
- m_PipeRead = fds[0];
- m_PipeWrite = fds[1];
+ rc = RTPipeCreate(&m_hPipeRead, &m_hPipeWrite, 0 /*fFlags*/);
+ AssertReleaseRC(rc);
#else
m_hWakeupEvent = CreateEvent(NULL, FALSE, FALSE, NULL); /* auto-reset event */
+ AssertReleaseRC(m_hWakeupEvent != NULL);
slirp_register_external_event(m_pNATState, m_hWakeupEvent, VBOX_WAKEUP_EVENT_INDEX);
#endif
rc = RTReqCreateQueue(&m_pReqQueue);
@@ -298,7 +294,8 @@ void VBoxNetNAT::run()
#ifndef RT_OS_WINDOWS
/* kick select() */
- rc = RTFileWrite(m_PipeWrite, "", 1, NULL);
+ size_t cbIgnored;
+ rc = RTPipeWrite(m_hPipeWrite, "", 1, &cbIgnored);
AssertRC(rc);
#else
/* kick WSAWaitForMultipleEvents */
@@ -369,6 +366,11 @@ extern "C" void slirp_output(void *pvUser, struct mbuf *m, const uint8_t *pu8Buf
AssertReleaseRC(rc);
}
+extern "C" void slirp_output_pending(void *pvUser)
+{
+ AssertMsgFailed(("Unimplemented"));
+}
+
/**
* Worker function for drvNATSend().
* @thread "NAT" thread.
@@ -462,7 +464,7 @@ static DECLCALLBACK(int) AsyncIoThread(RTTHREAD pThread, void *pvUser)
slirp_select_fill(pThis->m_pNATState, &nFDs, &polls[1]);
unsigned int cMsTimeout = slirp_get_timeout_ms(pThis->m_pNATState);
- polls[0].fd = pThis->m_PipeRead;
+ polls[0].fd = RTPipeToNative(pThis->m_hPipeRead);
/* POLLRDBAND usually doesn't used on Linux but seems used on Solaris */
polls[0].events = POLLRDNORM|POLLPRI|POLLRDBAND;
polls[0].revents = 0;
@@ -488,11 +490,9 @@ static DECLCALLBACK(int) AsyncIoThread(RTTHREAD pThread, void *pvUser)
slirp_select_poll(pThis->m_pNATState, &polls[1], nFDs);
if (polls[0].revents & (POLLRDNORM|POLLPRI|POLLRDBAND))
{
- /* drain the pipe */
- char ch[1];
- size_t cbRead;
- int counter = 0;
- /*
+ /* drain the pipe
+ *
+ * Note!
* drvNATSend decoupled so we don't know how many times
* device's thread sends before we've entered multiplex,
* so to avoid false alarm drain pipe here to the very end
@@ -500,9 +500,12 @@ static DECLCALLBACK(int) AsyncIoThread(RTTHREAD pThread, void *pvUser)
* @todo: Probably we should counter drvNATSend to count how
* deep pipe has been filed before drain.
*
- * XXX:Make it reading exactly we need to drain the pipe.
*/
- RTFileRead(pThis->m_PipeRead, &ch, 1, &cbRead);
+ /** @todo XXX: Make it reading exactly we need to drain the
+ * pipe. */
+ char ch;
+ size_t cbRead;
+ RTPipeRead(pThis->m_hPipeRead, &ch, 1, &cbRead);
}
}
/* process _all_ outstanding requests but don't wait */
diff --git a/src/VBox/NetworkServices/NAT/VBoxNetNATHardened.cpp b/src/VBox/NetworkServices/NAT/VBoxNetNATHardened.cpp
index b0d74e735..1d30f8659 100644
--- a/src/VBox/NetworkServices/NAT/VBoxNetNATHardened.cpp
+++ b/src/VBox/NetworkServices/NAT/VBoxNetNATHardened.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetNATHardened.cpp $ */
+/* $Id: VBoxNetNATHardened.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxNetNAT - Hardened main().
*/
diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetARP.cpp b/src/VBox/NetworkServices/NetLib/VBoxNetARP.cpp
index ec5ed275f..82ca1065d 100644
--- a/src/VBox/NetworkServices/NetLib/VBoxNetARP.cpp
+++ b/src/VBox/NetworkServices/NetLib/VBoxNetARP.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetARP.cpp $ */
+/* $Id: VBoxNetARP.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxNetARP - IntNet ARP Client Routines.
*/
diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
index 0fdbc8242..97eafb95a 100644
--- a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
+++ b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetBaseService.cpp $ */
+/* $Id: VBoxNetBaseService.cpp 36217 2011-03-09 03:22:09Z vboxsync $ */
/** @file
* VBoxNetDHCP - DHCP Service for connecting to IntNet.
*/
@@ -41,7 +41,7 @@
#include <VBox/sup.h>
#include <VBox/intnet.h>
-#include <VBox/vmm.h>
+#include <VBox/vmm/vmm.h>
#include <VBox/version.h>
#include <vector>
diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h
index ea24aea71..c12040c88 100644
--- a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h
+++ b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetBaseService.h $ */
+/* $Id: VBoxNetBaseService.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxNetUDP - IntNet Client Library.
*/
diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetIntIf.cpp b/src/VBox/NetworkServices/NetLib/VBoxNetIntIf.cpp
index 74a3998a4..44ffb3c2b 100644
--- a/src/VBox/NetworkServices/NetLib/VBoxNetIntIf.cpp
+++ b/src/VBox/NetworkServices/NetLib/VBoxNetIntIf.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetIntIf.cpp $ */
+/* $Id: VBoxNetIntIf.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBoxNetIntIf - IntNet Interface Client Routines.
*/
diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetLib.h b/src/VBox/NetworkServices/NetLib/VBoxNetLib.h
index e1150bfb1..02ac249c7 100644
--- a/src/VBox/NetworkServices/NetLib/VBoxNetLib.h
+++ b/src/VBox/NetworkServices/NetLib/VBoxNetLib.h
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetLib.h $ */
+/* $Id: VBoxNetLib.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxNetUDP - IntNet Client Library.
*/
diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp b/src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp
index 79c40c277..f660c394f 100644
--- a/src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp
+++ b/src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetUDP.cpp $ */
+/* $Id: VBoxNetUDP.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VBoxNetUDP - IntNet UDP Client Routines.
*/
diff --git a/src/VBox/RDP/client/Makefile.kmk b/src/VBox/RDP/client/Makefile.kmk
index c191c25fc..2ee7d029d 100644
--- a/src/VBox/RDP/client/Makefile.kmk
+++ b/src/VBox/RDP/client/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37224 2011-05-26 13:48:24Z vboxsync $
## @file
# VBox - rdesktop with VRDP enhancements sub-makefile.
#
diff --git a/src/VBox/RDP/client/doc/AUTHORS b/src/VBox/RDP/client/doc/AUTHORS
new file mode 100644
index 000000000..f2e23bdfb
--- /dev/null
+++ b/src/VBox/RDP/client/doc/AUTHORS
@@ -0,0 +1,20 @@
+This is an attempt at a list of people who have made significant
+contributions to the code. If you have been unintentionally omitted
+please let one of the team members know.
+
+Alexi Volkov <alexi@myrealbox.com>
+Erik Forsberg <forsberg@cendio.se>
+GuoJunBo <guojunbo@ict.ac.cn>
+Henrik Andersson <hean01@cendio.se> for Cendio AB
+Hugo Trippaers <spark@ision.nl>
+Jay Sorg <j@american-data.com>
+Jeremy Meng <void.foo@gmail.com>
+Jeroen Meijer <jeroen@oldambt7.com>
+Matrox Graphics Inc.
+Matthew Chapman <matthewc.unsw.edu.au>
+Michael Gernoth <mike@zerfleddert.de>
+Michal Mihalik <mmihalik@sme.sk>
+Norbert Federa <nob@thinstuff.com>
+Peter Astrand <astrand@cendio.se> for Cendio AB
+Peter Kallden <peter.kallden@ub.oru.se>
+Pierre Ossman <ossman@cendio.se> for Cendio AB
diff --git a/src/VBox/RDP/client/doc/ChangeLog b/src/VBox/RDP/client/doc/ChangeLog
new file mode 100644
index 000000000..25314404d
--- /dev/null
+++ b/src/VBox/RDP/client/doc/ChangeLog
@@ -0,0 +1,127 @@
+rdesktop (1.7.0)
+ * Security: Directory traversal vulnerability with disk redirection (disallow /.. requests)
+ * New maintainer: Peter Ã…strand <astrand@cendio.se>
+ * Brush cache support
+ * Removed the hardcoded limit of the username length
+ * Increased domain name length to 255 chars
+ * Improved compatibility with PulseAudio/padsp
+ * Cleaned up and documented the return values
+ * Keyboard fix: avoid stuck keys in certain cases
+ * Support for new pointers
+ * License has been changed to GPLv3
+ * EWMH fixes for 64-bit machines
+ * RandR support: automatically resize session if using relative screen size
+ * Improved support for Windows 2008 Session Broker
+ * Japanese keyboard map has been improved
+ * New keyboard map: fr-bepo
+ * Many stability fixes regarding smart card redirection
+ * Windows 2008 R2 / 7: Fix sound playback when not using other redirections
+ * Windows 2008 R2 / 7: Solve disk redirection read-only issues
+ * Windows 2008 R2 / 7: Solve issue with recursive deletion
+ * Avoid exit when printing, if lpr command terminates early
+
+ -- Peter Ã…strand <astrand@cendio.se> 2011-04-13
+
+rdesktop (1.6.0)
+ * Fix for crash with recent versions of X.Org
+ * Fix for potential vulnerability against compromised/malicious servers (reported by iDefense)
+ * Fix for Windows 2008 Server
+ * ALSA driver added
+ * Sound drivers can now be selected at runtime
+ * Smartcard support (Alexi Volkov <alexi@myrealbox.com>)
+ * Send physical mouse buttons rather than logical ones
+
+ -- Matthew Chapman <matthewc@cse.unsw.edu.au> Sat, 11 May 2008 16:12:20 +1100 (AEDT)
+
+rdesktop (1.5.0)
+ * SeamlessRDP - seamless windows support
+ * Keymap fixes
+ * Fix connection issues with Windows XP RTM
+ * Keyboard handling improvements and fixes
+ * SGI/Irix sound-driver fixes
+ * Support for clipboard INCR protocol
+ * Session Directory support (patch from Brian Chapeau <lheria@users.sourceforge.net>)
+ * Support for long filenames on redirected drives
+ * XOR ellipse drawing fix
+ * Clipboard unicode support (Ilya Konstantinov)
+ * Fix display issues with exotic color depths (30bpp, 32bpp, etc) (Ilya Konstantinov)
+ * Large file support
+ * The default color depth is now the depth of the root window
+ * Basic support for Windows Vista Beta 2
+ * Fix high cpu-usage in OSS-driver
+
+ -- Peter Astrand <astrand@cendio.se> Wed, 13 Sep 2006 15:11:39 +0200 (CEST)
+
+rdesktop (1.4.1)
+ * persistent bitmap cache optimisations
+ * support for more RDP-orders (ellipse, polygon)
+ * libao sound-driver (for Mac OSX and others)
+ * Unicode support for transmitted strings/filenames
+ * Added korean keymap
+ * Xembed fixes to work with krdc correctly
+ * Portability fixes
+ * Support for RDP-compression (all bpps)
+ * process RDP recv queue if send queue is full (Debian bug #246461)
+ * SGI/Irix sound-driver fixes
+
+ -- Michael Gernoth <michael@gernoth.net> Sun, 8 May 2005 19:55:35 +0200 (CEST)
+
+rdesktop (1.4.0)
+ * Basic disk-, parallel-, printer- and serial-redirection
+ * Fix timezone-redirection
+ * Backing-store fixes
+ * Fix client-IP sent to TS
+ * XEmbed support for embedding rdesktop in other applications (KRDC)
+ * Support for setting the RDP5 experience
+ * Keyboard and keymap fixes
+ * Performance improvements
+ * Report disconnect-reason
+ * Support for RDP-compression (currently only for 8bpp)
+ * Support for persistent bitmap caching
+ * Sound-driver for SGI/Irix
+
+ -- Michael Gernoth <michael@gernoth.net> Sun, 6 Mar 2005 22:09:55 +0100 (CET)
+
+rdesktop (1.3.1)
+ * Crypto fixes for RDP5
+ * Keyboard and keymap fixes
+ * some endianess fixes for high color
+ * portability enhancements
+
+ -- Matthew Chapman <matthewc@cse.unsw.edu.au> Tue, 21 Jan 2004 20:34
+
+rdesktop (1.3.0)
+
+ * RDP5
+ * 15, 16 and 24 bit color depths
+ * Basic clipboard redirection
+ * Sound
+ * IPv6
+ * Attaching to console on Windows 2003
+
+ -- Peter Astrand <astrand@cendio.se> Wed, 29 Oct 2003 16:40:58 +0100 (CET)
+
+rdesktop (1.2.0)
+
+ * new - more portable - key mapping code
+ * support for "high" (128-bit) encryption
+ * toggling out of full-screen mode with Ctrl-Alt-Enter
+ * a few extra options including host:port syntax
+ * many, many bug fixes and optimisations
+
+ -- Matthew Chapman <matthewc@cse.unsw.edu.au> Thu, 30 Jan 2003 04:29
+
+rdesktop (1.1.0)
+
+ * solves arith.c licensing issue by taking big number routines from
+ OpenSSL
+ * keyboard support not merged from unified patches yet
+ * still no manpage
+
+ -- Matthew Chapman <matthewc@cse.unsw.edu.au> Mon, 17 Sep 2001 23:14:28 +1000 (AEST)
+
+rdesktop (1.0.0)
+
+ * initial release
+
+ -- Matthew Chapman <matthewc@cse.unsw.edu.au>
diff --git a/src/VBox/RDP/client/doc/HACKING b/src/VBox/RDP/client/doc/HACKING
new file mode 100644
index 000000000..27d8a33b8
--- /dev/null
+++ b/src/VBox/RDP/client/doc/HACKING
@@ -0,0 +1,45 @@
+
+Code style / indentation
+------------------------
+The file indent-all.sh contains information about the current code
+style. Run this script before commits.
+
+
+Variable argument macros
+------------------------
+Variable argument macros are non-portable in general, and should be
+avoided. Either use a second set of parentheses like DEBUG, or create
+a variable argument function like error.
+
+
+Structure
+---------
+The core protocol stack should be system-independent (i.e. ANSI C89
+only) so that it is easy to port. This currently applies to the
+following files:
+
+bitmap.c licence.c orders.c rdp.c rdp5.c cache.c iso.c mcs.c
+secure.c mppc.c channels.c
+rdesktop.c
+
+
+Compiler support
+----------------
+
+The source code should be compatible with ANSI C89. One exception is
+the SeamlessRDP ServerEXE and ClientDLL, which should be compatible
+with ANSI C99.
+
+
+RDP resources
+-------------
+http://dev.remotenetworktechnology.com/refdata.htm
+
+
+Checking for out of memory conditions
+-------------------------------------
+Try to handle out of memory conditions gracefully. Use the xmalloc
+routines from rdesktop.c, instead of calling malloc manually. Also,
+remember that several Xlib functions can return NULL. This includes
+XGetImage. Use exit_if_null to verify returned pointers.
+
diff --git a/src/VBox/RDP/client/doc/TODO b/src/VBox/RDP/client/doc/TODO
new file mode 100644
index 000000000..65232b356
--- /dev/null
+++ b/src/VBox/RDP/client/doc/TODO
@@ -0,0 +1,102 @@
+* General
+
+ * Rework main loop to a generic event handler (i.e. move select() to
+ the top of the stack, not the end). Also means rewriting the connect
+ procedure as a state machine.
+
+ * Stop using static objects for packets and make it more clear when it
+ is in use (explicit allocation and free).
+
+* Clipboard:
+
+ * Support other data types than plain text.
+
+ * Conversion between different character sets.
+
+
+* Drive Redirection:
+
+ * Real support for file locking
+
+ * Handle reconnections correctly.
+
+ * Various deficiencies; see FIXMEs in source code.
+
+
+* Serial Port Redirection:
+
+ * More testing needed.
+
+
+* Printer Redirection:
+
+ * More testing needed.
+
+
+* Keymapping:
+
+
+* Sound redirection
+
+ * Use timestamps in audio packets.
+
+ * Add resampling to supported samplerates of audio-hardware.
+
+ * Lower CPU-usage with an audio thread.
+
+
+* Smartcard redirection
+
+ * Merge patches currently implementing sc-redirection.
+
+
+* Miscellaneous
+
+ * Clean up header files. The current "proto.h" and "xproto.h" is far
+ from optimal.
+
+ * Go through the many trackers (bugs/patches/RFEs) at SourceForge.
+
+ * More fancy homepage.
+
+ * Enhance documentation. Write a FAQ.
+
+
+* SeamlessRDP mode
+
+ * Add a client to server message for starting additional
+ applications.
+
+ * Support cmd.exe.
+
+ * Support for Input Contexts.
+
+ * Enhanced support for WM_DELETE_WINDOW: Instead of terminating
+ rdesktop, close the window on the server side.
+
+ * Systray support.
+
+ * Better support for non-EWMH window managers.
+
+ * Support for non-rectangular windows.
+
+ * The focus handling of menus is a bit crude.
+
+ * Support for sending focus information from client to server.
+
+ * Implement something similiar to explhook.dll - support for running
+ explorer.exe in non-shell mode.
+
+ * Better compatibility with Task Manager.
+
+ * XINERAMA support.
+
+ * When enumerating windows, make sure to send info about windows
+ that are transient for other windows after the referred window.
+
+ * We support topmost windows at creating time, but we do not detect
+ when this property is added or removed. This can be verified with
+ task manager, which has an "Always on top" option.
+
+ * Window icons are not set when reconnecting. get_icon/update_icon
+ needs to be called from enum_cb.
diff --git a/src/VBox/RDP/client/doc/ipv6.txt b/src/VBox/RDP/client/doc/ipv6.txt
new file mode 100644
index 000000000..1d3ef2341
--- /dev/null
+++ b/src/VBox/RDP/client/doc/ipv6.txt
@@ -0,0 +1,29 @@
+
+IPv6 support in rdesktop
+========================
+The IPv6 support was developed by Mike Dawson <mike@dexy.mine.nu>:
+
+ Attached is a patch to tcp.c to enable IPv6 support. Build with
+ 'IPv6' defined to enable it. It's so far only been tested on
+ Linux 2.4.21 connecting to Windows XP SP1.
+
+ Since terminal services doesn't seem to bind to the ipv6 interface
+ on XP I had to run 'netsh interface portproxy add v6tov4
+ listenport=3389 connectport=3389' from the windows command prompt
+ to get it to work.
+
+
+rdesktop now supports numeric IPv6 addresses:
+
+ It checks for two or more colons in an address to decide what it's
+ dealing with so you can now do:
+
+ rdesktop 2001:1:2:3::4
+
+ without it getting confused with an ipv4:port specification. I've
+ also followed the square bracket convention used by browsers
+ (http://www.ietf.org/rfc/rfc2732.txt) so if you want to specify a
+ non-standard port with an ipv6 address you can use the format:
+
+ rdesktop [2001:1:2:3::4]:3390
+
diff --git a/src/VBox/RDP/client/doc/keymap-names.txt b/src/VBox/RDP/client/doc/keymap-names.txt
new file mode 100644
index 000000000..3da698b29
--- /dev/null
+++ b/src/VBox/RDP/client/doc/keymap-names.txt
@@ -0,0 +1,124 @@
+
+0x0436 af Afrikaans
+0x041C sq Albanian
+0x0001 ar Arabic
+0x0401 ar-sa Arabic (Saudi Arabia)
+0x0801 ar-iq Arabic (Iraq)
+0x0C01 ar-eg Arabic (Egypt)
+0x1001 ar-ly Arabic (Libya)
+0x1401 ar-dz Arabic (Algeria)
+0x1801 ar-ma Arabic (Morocco)
+0x1C01 ar-tn Arabic (Tunisia)
+0x2001 ar-om Arabic (Oman)
+0x2401 ar-ye Arabic (Yemen)
+0x2801 ar-sy Arabic (Syria)
+0x2C01 ar-jo Arabic (Jordan)
+0x3001 ar-lb Arabic (Lebanon)
+0x3401 ar-kw Arabic (Kuwait)
+0x3801 ar-ae Arabic (U.A.E.)
+0x3C01 ar-bh Arabic (Bahrain)
+0x4001 ar-qa Arabic (Qatar)
+0x042D eu Basque
+0x0402 bg Bulgarian
+0x0423 be Belarusian
+0x0403 ca Catalan
+0x0004 zh Chinese
+0x0404 zh-tw Chinese (Taiwan)
+0x0804 zh-cn Chinese (China)
+0x0C04 zh-hk Chinese (Hong Kong SAR)
+0x1004 zh-sg Chinese (Singapore)
+0x041A hr Croatian
+0x0405 cs Czech
+0x0406 da Danish
+0x0413 nl Dutch (Netherlands)
+0x0813 nl-be Dutch (Belgium)
+0x0009 en English
+0x0409 en-us English (United States)
+0x0809 en-gb English (United Kingdom)
+0x0C09 en-au English (Australia)
+0x1009 en-ca English (Canada)
+0x1409 en-nz English (New Zealand)
+0x1809 en-ie English (Ireland)
+0x1C09 en-za English (South Africa)
+0x2009 en-jm English (Jamaica)
+0x2809 en-bz English (Belize)
+0x2C09 en-tt English (Trinidad)
+0x0425 et Estonian
+0x0438 fo Faeroese
+0x0429 fa Farsi
+0x040B fi Finnish
+0x040C fr French (France)
+0x080C fr-be French (Belgium)
+0x0C0C fr-ca French (Canada)
+0x100C fr-ch French (Switzerland)
+0x140C fr-lu French (Luxembourg)
+0x043C gd Gaelic
+0x0407 de German (Germany)
+0x0807 de-ch German (Switzerland)
+0x0C07 de-at German (Austria)
+0x1007 de-lu German (Luxembourg)
+0x1407 de-li German (Liechtenstein)
+0x0408 el Greek
+0x040D he Hebrew
+0x0439 hi Hindi
+0x040E hu Hungarian
+0x040F is Icelandic
+0x0421 in Indonesian
+0x0410 it Italian (Italy)
+0x0810 it-ch Italian (Switzerland)
+0x0411 ja Japanese
+0x0412 ko Korean
+0x0426 lv Latvian
+0x0427 lt Lithuanian
+0x042F mk FYRO Macedonian
+0x043E ms Malay (Malaysia)
+0x043A mt Maltese
+0x0414 no Norwegian (Bokmal)
+0x0814 no Norwegian (Nynorsk)
+0x0415 pl Polish
+0x0416 pt-br Portuguese (Brazil)
+0x0816 pt Portuguese (Portugal)
+0x0417 rm Rhaeto-Romanic
+0x0418 ro Romanian
+0x0818 ro-mo Romanian (Moldova)
+0x0419 ru Russian
+0x0819 ru-mo Russian (Moldova)
+0x0C1A sr Serbian (Cyrillic)
+0x081A sr Serbian (Latin)
+0x041B sk Slovak
+0x0424 sl Slovenian
+0x042E sb Sorbian
+0x040A es Spanish (Traditional Sort)
+0x080A es-mx Spanish (Mexico)
+0x0C0A es Spanish (International Sort)
+0x100A es-gt Spanish (Guatemala)
+0x140A es-cr Spanish (Costa Rica)
+0x180A es-pa Spanish (Panama)
+0x1C0A es-do Spanish (Dominican Republic)
+0x200A es-ve Spanish (Venezuela)
+0x240A es-co Spanish (Colombia)
+0x280A es-pe Spanish (Peru)
+0x2C0A es-ar Spanish (Argentina)
+0x300A es-ec Spanish (Ecuador)
+0x340A es-cl Spanish (Chile)
+0x380A es-uy Spanish (Uruguay)
+0x3C0A es-py Spanish (Paraguay)
+0x400A es-bo Spanish (Bolivia)
+0x440A es-sv Spanish (El Salvador)
+0x480A es-hn Spanish (Honduras)
+0x4C0A es-ni Spanish (Nicaragua)
+0x500A es-pr Spanish (Puerto Rico)
+0x0430 sx Sutu
+0x041D sv Swedish
+0x081D sv-fi Swedish (Finland)
+0x041E th Thai
+0x0431 ts Tsonga
+0x0432 tn Tswana
+0x041F tr Turkish
+0x0422 uk Ukrainian
+0x0420 ur Urdu
+0x042A vi Vietnamese
+0x0434 xh Xhosa
+0x043D ji Yiddish
+0x0435 zu Zulu
+
diff --git a/src/VBox/RDP/client/doc/keymapping.txt b/src/VBox/RDP/client/doc/keymapping.txt
new file mode 100644
index 000000000..1a50ae242
--- /dev/null
+++ b/src/VBox/RDP/client/doc/keymapping.txt
@@ -0,0 +1,275 @@
+Keyboard mapping
+================
+This release of rdesktop uses a new, portable keyboard mapping
+implementation. It should hopefully work on all X11 systems. This new
+implementation only looks at X11 keysyms: Not on (nonportable)
+keycodes or modifier status. This means that rdesktop will obey your
+local keyboard configuration. For example, if you have swapped
+CapsLock and Control, rdesktop will use this mapping.
+
+XKB is currently not used. It seems like a good idea to me, but since
+some X servers (like Xvnc) does not support XKB, we still need to use
+the plain old interface as well, at least.
+
+There are still some small problems.
+
+* CapsLock: CapsLock changes are never sent to the RDP
+ server. rdesktop does not know which keys that are modified by
+ CapsLock and which are not. So, the CapsLock indicator in Wordpad
+ etc will always be off.
+
+Composing/Multi_key is supported. For more information, see:
+
+ MIT: $SRC/xc/nls/X11/locale/Compose/iso8859-1
+ XFree86: /usr/X11R6/lib/X11/locale/*/Compose
+ Solaris' Openwin: /usr/openwin/include/X11/Suncompose.h
+ /usr/openwin/lib/locale/*/Compose
+ Irix6: compose(5)
+
+
+Keymap files
+============
+The names of the keymaps follows RFC1766.
+
+(You can find a translation from Windows keyboard layout numbers to
+keymap names by looking at
+HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MIME\Database\RFC1766 in the
+registry.)
+
+
+Contents of keymap files
+========================
+The keymaps are line based. There are four different types of lines:
+
+1) include lines
+Syntax:
+include <another-map-file>
+
+Example:
+include common
+
+
+2) map lines
+Syntax:
+map <hex-number>
+
+Example:
+map 0x41d
+
+Map-lines specifies how the remote RDP server should interpret the
+sent scancodes.
+
+
+3) Translation lines
+Syntax:
+<keysym-name> <scancode> [flags..]
+
+Example:
+onehalf 0x29 shift
+
+The scancode can be found in scancodes.h. Note: The scancode value for
+extended keys can be calculated by OR:ing with 0x80. Example: The
+Delete key have the scancode sequence 0xe0, 0x52. You can get the
+scancode value to put into the map file by running:
+
+python -c "print hex(0x80 | 0x52)"
+
+If flags are "altgr", "shift", the scancode sent for this keysym will
+be prefixed with AltGr, or Shift.
+
+If flags includes "addupper", a translation for this keysyms uppercase
+name will be added as well, in addition to the non-uppercase
+name. Example:
+
+x 2d addupper
+
+...will add an translation for "X" automatically, just like if you
+would specify:
+
+X 2d shift
+
+If flags include "localstate", the modifier to send will be determined
+by the local modifier state.
+
+If flags is "inhibit", nothing will be sent to the server.
+
+If flags is "numlock", rdesktop will make sure that the remote NumLock
+state is on before generating the key event. Otherwise, it will make
+sure NumLock is off.
+
+
+4) enable_compose
+
+If any line starts with the keyword "enable_compose", rdesktop will
+enable local Compose/Multi_key handling. Enabling this will often make
+it impossible to compose characters with dead keys (on the remote
+side). This is because when local compose support is enabled, dead
+keys will not be sent to the remote side.
+
+
+5) sequence lines
+Syntax:
+sequence <event-keysym-name> <keysym-name1> <keysym-name2> ...
+
+Examples:
+sequence eacute dead_acute e
+sequence F12 f o o at e x a m p l e period c o m
+
+Sequence lines allows you to specify that multiple scancodes should be
+sent to the RDP server, in response to one X11 keyboard event. Note:
+The sequence is sent at the X11 KeyPress event. Nothing is sent at
+KeyRelease.
+
+
+6) keyboard_type lines
+Syntax:
+keyboard_type <hex-number>
+
+keyboard_type lines specifies the keyboard type. Default value is 0x4
+(en-us 101/104 keys keyboard).
+
+
+7) keyboard_subtype lines
+Syntax:
+keyboard_subtype <hex-number>
+
+keyboard_subtype lines specifies the keyboard subtype. Default value
+is 0x0 (en-us 101/104 keys keyboard).
+
+
+8) keyboard_functionkeys lines
+Syntax:
+keyboard_functionkeys <hex-number>
+
+keyboard_functionkeys specifies the number of keyboard function
+keys. Default value is 0xc (12, for standard 101/104 keys keyboard).
+
+
+
+
+Suggested X11 keysym mapping on PCs
+===================================
+Unfortunately, there is no standard for which keysyms a given key
+should generate. If you have a PC-keyboard with Windows keys, I suggest this mapping:
+
+Keyboard keys:
+CtrlLeft WinLeft AltLeft Space AltGr WinRight Menu CtrlRight
+
+...should generate keysyms:
+Control_L Super_L Alt_L space Mode_switch Super_R Menu Control_R
+
+Additionally:
+Shift-Alt should produce Meta_L
+Shift-AltGr should produce Multi_Key.
+
+Use a modifier-map like this:
+
+shift Shift_L (0x32), Shift_R (0x3e)
+lock Caps_Lock (0x25)
+control Control_L (0x42), Control_R (0x6d)
+mod1 Alt_L (0x40)
+mod2 Num_Lock (0x4d)
+mod3 Mode_switch (0x71)
+mod4 Super_L (0x73), Super_R (0x74)
+mod5 Scroll_Lock (0x4e)
+
+
+Updating / writing keymap files
+===============================
+When writing new or updating keymap files, please use comments and
+blanks, to increase readability. The "sv" keymap is a good template.
+
+When you need to add a translation to a keymap file, do:
+
+ 1. Get the "key number" for this key, by looking at keynums.png.
+
+ 2. Take a look at scancodes.h, and look for
+ SCANCODE_KEY_<my-key-number>. The scancode value is at the end of
+ the line. If the line contains (SCANCODE_EXTENDED | 0xsomething),
+ then you should OR 0x80 to this value. For example, you can do:
+
+ python -c "print hex(0x80 | 0xsomething)"
+
+ 3. Put the scancode (from step 2) and keysym name (found in the
+ error message) into the keymap file.
+
+
+Special keys
+============
+
+* The combination Ctrl-Alt-Enter toggles between fullscreen and
+ non-fullscreen mode.
+
+* Meta, Hyper and Super are treated as windows keys. RDP4 does not
+ support the windows keys though, so if you are running RDP4, these
+ keys will translate to Ctrl-Esc.
+
+
+Links
+=====
+http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html
+
+
+Test cases
+==========
+When changing the keyboard code, make sure all these tests in Notepad
+works:
+
+1. Ctrl+f should bring up Find dialog, with CapsLock both on and off.
+
+2. Ctrl+Shift+arrows should mark text, with CapsLock both on and off.
+
+3. Test a sequence, like egrave. If you don't have this symbol in your
+ keyboard layout, try something like:
+
+ xmodmap -e "keycode 49 = egrave"
+
+4. Test a char generated with AltGr, such as @ on a swedish keyboard.
+
+5. Test Ctrl-Alt-Delete.
+
+6. Ctrl-Alt-Enter should toggle fullscreen.
+
+7. Test NumLock synchronization using the -N option. Excel is able to
+ indicate the current NumLock state. Verify that the status is
+ updated correctly on reconnects.
+
+8. Test the Windows keys, standalone as well as in combination with,
+ say, E.
+
+9. Make sure the system menu (via Alt-space) cannot be accessed in
+ single app mode.
+
+10. Make sure keymaps can be loaded from ~/.rdesktop/keymaps,
+ KEYMAP_PATH, $CWD/keymaps, and from an absolute path.
+
+11. Press Shift, then press a key modified by shift, the release
+ shift, then release the other key. Do this in a speedy fasion.
+ Make sure the shift state is not stuck down.
+
+12. Test all numpad keys, when not using the -N option.
+
+13. Map a single, un-shifted key (such as F1) to XK_A:
+ xmodmap -e "keycode 67 = A A"
+
+ Perform in Notepad:
+ * Write some text
+ * Press F1
+ * Press b
+ * Release b
+ * Release F1
+
+ Verify that shift is not stuck down, by clicking on the text.
+
+14. Use a keyboard layout where Meta_L can be generated with Shift_R +
+ Alt_L. Then:
+
+ * Start Notepad
+ * Press Shift_R
+ * Press Alt_L
+ * Release Shift_R
+ * Release Alt_L
+ * Press "e"
+
+ Verify that you get an "e" in Notepad, rather than start Windows
+ Explorer.
diff --git a/src/VBox/RDP/client/doc/licensing.txt b/src/VBox/RDP/client/doc/licensing.txt
new file mode 100644
index 000000000..1bf6b0c33
--- /dev/null
+++ b/src/VBox/RDP/client/doc/licensing.txt
@@ -0,0 +1,56 @@
+
+To be able to connect to Microsoft Windows 2000 Terminal Services (and
+probably later versions), you'll need to deal with licensing. This is
+complicated. This file is supposed to contain some information about
+how rdesktop works with Microsofts license systems.
+
+There's a lot of information on the MS web site, for example,
+http://support.microsoft.com/default.aspx?scid=kb;EN-US;287687.
+
+From the rdesktop mailing list:
+
+Peter Ã…strand <astrand@cendio.se>, 2003-02-06
+
+> We are running rdesktop 1.2 on machine A and connects to a Windows 2000
+> Server (machine B). The W2K machine has 5 real licenses installed ("Windows
+> 2000 Terminal Services Client Access License", "Open" type). This can be
+> verifier by using "Terminal Services Licensing". The problem is that all
+> issued licenses have an expire-date. The expire date for the license issued
+> to A was reached today, and no more connections could be made until we
+> changed the client name (by using -n).
+>
+> We also have another similiar systems, with Linux machine C and W2K server
+> D. This server has 200 licenses installed of the type "Select". On this
+> server, the issued licenses seems to be permanent: The expire date is set
+> to "-", and we have no problem with this system.
+>
+> The question of course is why the first system issues license with
+> expiration date, while the second system issues permanent licenses.
+
+
+Darryn Capes-Davis, 2003-02-07
+
+> I have been through the problems and can tell you what is going
+> on. The main difference of Machine B (Server 1) and Machine D (Server
+> 2) is that from what I see Machine B has Service Pack 3 installed and
+> Machine D does not. You see in Service Pack 3 there was a change made
+> to TS Licencing in that Microsoft introduced a licence recovery
+> mechanism. To cut to the point (I don't know the details) rdesktop 1.2
+> with SAVE_LICENCE defined works fine. In the new lic method the
+> terminal server expects a valid licence to be presented to renew
+> it. Otherwise it just expires it - and a day later you will see it
+> actually gone (it does housekeeping once a day)! So if SAVE_LICENCE
+> code is not enabled then it just expires and you can't use the licence
+> until it cleans it away - and this is where a little gotcha is - if
+> you move from using an rdesktop without SAVE_LICENCE to one with
+> SAVE_LICENCE then it still won't recover an 'expired' licence. You
+> have to wait for the daily housekeeping to clean it up - this really
+> had me going for half a day or so! This is exactly what happened to
+> you.
+>
+> The Server pre Spk 3 has the old model where licences never expire. To
+> recover a licence that you never wanted to use again you have to call
+> the Microsoft Clearing House. That's why they introduced the new
+> method. And if you upgrade a Pre Spk3 server to Spk3 then the licences
+> granted still stay with the old method - only new licences granted
+> will use the new expiry method.
diff --git a/src/VBox/RDP/client/doc/patches.txt b/src/VBox/RDP/client/doc/patches.txt
new file mode 100644
index 000000000..08ffe59f7
--- /dev/null
+++ b/src/VBox/RDP/client/doc/patches.txt
@@ -0,0 +1,340 @@
+This file documents some of all patches for rdesktop, floating around
+the net, and how they are related to the current (CVS) version of
+rdesktop. Things left to do are marked with TBD (To Be Done).
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/Makefile.diff
+Description:
+Makefile changes which makes it possible to compile rdesktop on SunOS
+and OSF1.
+Status:
+Applied (slightly modified)
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/assar_19-7-2.hostlen.patch
+Description:
+Fix for hostnames longer than 30 chars.
+Status:
+Applied (revision 1.11 of secure.c)
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/backingstore+privatecolormap-for-19-3-9.patch
+Description:
+This adds support for 1) Private color maps (useful for 8 bpp mode)
+and 2) backingstore selection.
+Status:
+1) is not needed anymore; rdesktop automatically uses Private color
+map in 8 bpp mode. 2) is, as far as I understand, also not
+need. rdesktop automatically uses a software backing store if the
+Xserver does not provide one.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/ben_xwin.c.diff
+Description:
+Fixes for CapsLock and NumLock.
+Status:
+Not needed anymore, with the new keyboard mapping implementation.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/ctrl1nohang.diff
+Description:
+Fixes problem with ctrl1 hangs.
+Status:
+Not needed anymore, with the new keyboard mapping implementation.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/downkeypatch.diff
+Description:
+Seems to keep track of the remote modifier status.
+Status:
+Not needed anymore, with the new keyboard mapping implementation.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/fasttext2+nobackpixmap.patch
+Description:
+(From http://mail.rdesktop.org/archive/2001/msg00218.html):
+
+1) Added --no-backpixmap option to disable the ugly double drawing in
+xwin.c (I have a very robust backing storage in my X, so I don't need
+it ;)
+
+2) More optimizations to text draw (previous fast-text patch was
+included in 192-3-6-2). In text drawing with solid background the
+glyphs are drawn with stippled fill instead of XCopyPlane (runs faster
+on my S3Trio64 with XFree 3.3.6, please test it on other
+configurations to validate this). The WinTach not show any improvement
+with this change, it seems to use all transparent background text
+draws, but with a old PC Magazine Winbench (3.1) doing the scroll text
+test the speed gain is significative.
+
+3) My Previous patch to disable backing storage in fullscreen
+
+Status:
+1) is not relevant any more, since rdesktop only uses backing store if
+the Xserver does not provide backing store.
+Need to examine if 2) and 3) are still useful. TBD.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/francisco_fix_patblt.html
+Description:
+The colors in patterns drawn with "pattern blt" order was inverted (fg
+& bg). (See the background of the yellow help banners)
+Status:
+Applied (in revision 1.29, 2002/07/14)
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/frank_1linerfix.html
+Description:
+ui_create_glyph was not called with ipattern.
+Status:
+Applied (in revision 1.29, 2002/07/14).
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/frank_fasttext.patch.txt
+Description:
+Some kind of performence improvements.
+Status:
+From what I can tell, this patch is no longer necessary.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/hostname-patch
+Description:
+(From http://mail.rdesktop.org/archive/2001/msg00163.html):
+
+rdesktop uses gethostname to figure out the hostname, but gethostname
+under linux returns an error when the hostname is longer than the
+buffer. This hack gives gethostname a 64 char buffer and then strips
+the first 16 chars or upto the first '.' and puts the result in
+hostname[16].
+
+Status:
+Applied in version 1.10 of rdesktop.c.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/hove-19-7-2endian.diff
+Description:
+Includes a program for testing endianness.
+Status:
+rdesktop determines endianness at runtime. This patch is not needed
+anymore.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/mmihalik_19-7-3-keyfix-4.patch
+Description:
+Some kind of new alternative keyboard mapping imlementation.
+Status:
+Not needed anymore, with the new keyboard mapping implementation.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/norbert_fullscreen.patch
+Description:
+Fullscreen mode.
+Status:
+Applied.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/norbert_percent.txt
+Description:
+Makes is possible to specify RDP geometry based a percent value of the
+current desktop size.
+Status:
+Not applied. I don't think many people will need this.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/norbert_rdp_tcp_port.diff
+Description:
+Command line tcp port argument.
+Status:
+Applied.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/patch19-7-2.xyPos.emptyPassword.patch
+Description:
+This patch adds:
+1) Support for empty passwords
+2) Support for asking for password interactively
+3) Support for +<xoff>+<yoff> geometry.
+
+Status:
+1) and 2) can be solved by the -P parameter; patch not needed.
+Functionality for 3) is currently missing.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-1.0.0-19-7-1-mmihalik-3.diff
+Description:
+Defines DO_GLYPH() etc.
+Status:
+As far as I understand, this patch is applied.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-1.0.0-mmihalik-1.diff
+Description:
+Misc drawing changes.
+Status:
+As far as I understand, this patch is applied.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-1.0.0-pl19-7-2-mmihalik-1.diff
+Description:
+Some kind of new alternative keyboard mapping implementation.
+Status:
+Not needed anymore, with the new keyboard mapping implementation.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-gmp.patch
+Description:
+Use GMP for RSA crypto.
+Status:
+Not needed since rdesktop now use OpenSSL for all of the crypto.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-new_kb.patch
+Description:
+Modifies one of the old keyboard mapping implementations in some way.
+Status:
+Not needed anymore, with the new keyboard mapping implementation.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-openssl.patch
+Description:
+Support for linking rdesktop with OpenSSL.
+Status:
+Not needed anymore, rdesktop can optionally use system
+OpenSSL.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop.vncviewer_patch
+Description:
+Hack for making the old (broken) keyboard mapping implementation work
+with the VNC Xserver.
+Status:
+Not needed anymore, with the new keyboard mapping implementation.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop_keymap.patch
+Description:
+Some kind of new alternative keyboard mapping implementation.
+Status:
+Not needed anymore, with the new keyboard mapping implementation.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdp-srvr-19-6-6.diff
+Description:
+Basic RDP server.
+Status:
+Not applied.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/scroll-to-death-patch.txt
+Description:
+Fixes scroll-to-death problem in Excel and other applications.
+Status:
+Not needed; fixed in another way in recent versions of rdesktop.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/spark-manpage-patch-19.4
+Description:
+Adds a manual page.
+Status:
+Not needed; rdesktop contains a manual page now.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/spark-manpage-patch-19.4-1
+Description:
+Adds a manual page.
+Status:
+Not needed; rdesktop contains a manual page now.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/spark_xinerama-patch2
+Description:
+Adds XINERAMA support to rdesktop.
+Status:
+Not applied yet. TBD.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/svenni_dis_wmkeybnds.patch
+Description:
+Commandline flag to disable keyboard grabbing.
+Status:
+Applied.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/svenni_disable_bs_in_x-tiny-patch
+Description:
+Disables backing store for TinyX.
+Status:
+As far as I understand, this patch is not need any longer.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/vincent_19-7-2.license.patch
+Description:
+TBD
+Status:
+Not yet examined.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/vincent_19-7-2.secure.patch
+Description:
+Fixes a problem during the connection to a French NT4 TSE (a French
+NT4 TSE doesn't use encryptation).
+Status:
+Applied.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/vincent_19-7-3_excel.patch
+Description:
+Makes matrixes appear better, such as those found in Excel/toad etc.
+Status:
+Applied.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/vincent_8bpp.patch
+Description:
+Support a 8bpp display (256 colours).
+Status:
+An enhanced version is included in rdesktop; this patch is not needed any more.
+
+
+URL:
+http://bibl4.oru.se/projects/rdesktop/patch19/patches/vpypatch.txt
+Description:
+Various changes for one of the old keyboard stuff.
+Status:
+Not needed anymore, with the new keyboard mapping implementation.
diff --git a/src/VBox/RDP/client/doc/rdesktop.1 b/src/VBox/RDP/client/doc/rdesktop.1
new file mode 100644
index 000000000..95f97d3a4
--- /dev/null
+++ b/src/VBox/RDP/client/doc/rdesktop.1
@@ -0,0 +1,291 @@
+.TH rdesktop 1 "November 2005"
+.SH NAME
+.I rdesktop
+\- Remote Desktop Protocol client
+.SH SYNOPSIS
+.B rdesktop [options] server[:port]
+.br
+.SH DESCRIPTION
+.I rdesktop
+is a client for Remote Desktop Protocol (RDP), used in a number of Microsoft
+products including Windows NT Terminal Server, Windows 2000 Server, Windows XP
+and Windows 2003 Server.
+
+.SH OPTIONS
+.TP
+.BR "-u <username>"
+Username for authentication on the server.
+.TP
+.BR "-d <domain>"
+Domain for authentication.
+.TP
+.BR "-s <shell>"
+Startup shell for the user - starts a specific application instead of Explorer.
+.TP
+.BR "-c <directory>"
+The initial working directory for the user. Often used in combination with -s
+to set up a fixed login environment.
+.TP
+.BR "-p <password>"
+The password to authenticate with. Note that this may have no effect if
+"Always prompt for password" is enabled on the server. WARNING: if you specify
+a password on the command line it may be visible to other users when they use
+tools like ps. Use -p - to make rdesktop request a password at startup (from
+standard input).
+.TP
+.BR "-n <hostname>"
+Client hostname. Normally rdesktop automatically obtains the hostname of the
+client.
+.TP
+.BR "-k <keyboard-map>"
+Keyboard layout to emulate. This requires a corresponding keymap file to be
+installed. The standard keymaps provided with rdesktop follow the RFC1766
+naming scheme: a language code followed by a country code if necessary - e.g.
+en-us, en-gb, de, fr, sv, etc.
+
+The default keyboard map depends on the current locale (LC_* and LANG
+environment variables). If the current locale is unknown, the default
+keyboard map is en-us (a US English keyboard).
+
+The keyboard maps are file names, which means that they are case
+sensitive. The standard keymaps are all in lowercase.
+
+The keyboard maps are searched relative to the directories
+$HOME/.rdesktop/keymaps, KEYMAP_PATH (specified at build time), and
+$CWD/keymaps, in this order. The keyboard-map argument can also be an
+absolute filename.
+
+The special value `none' can be used instead of a keyboard map.
+In this case, rdesktop will guess the scancodes from the X11 event key
+codes using an internal mapping method. This method only supports the
+basic alphanumeric keys and may not work properly on all platforms
+so its use is discouraged.
+.TP
+.BR "-g <geometry>"
+Desktop geometry (WxH). If geometry is the special word "workarea", the geometry
+will be fetched from the extended window manager hints property _NET_WORKAREA, from
+the root window. The geometry can also be specified as a percentage of the whole
+screen, e.g. "-g 80%".
+
+If the specified geometry depends on the screen size, and the screen
+size is changed, rdesktop will automatically reconnect using the new
+screen size. This requires that rdesktop has been compiled with RandR
+support.
+.TP
+.BR "-f"
+Enable fullscreen mode. This overrides the window manager and causes the
+rdesktop window to fully cover the current screen. Fullscreen mode can be
+toggled at any time using Ctrl-Alt-Enter.
+.TP
+.BR "-b"
+Force the server to send screen updates as bitmaps rather than using
+higher-level drawing operations.
+.TP
+.BR "-A"
+Enable SeamlessRDP. In this mode, rdesktop creates a X11 window for
+each window on the server side. This mode requires the SeamlessRDP
+server side component, which is available from
+\fIhttp://www.cendio.com/seamlessrdp/\fR.
+When using this option, you should specify a startup shell which
+launches the desired application through SeamlessRDP.
+
+Example: rdesktop -A -s 'seamlessrdpshell notepad'.
+.TP
+.BR "-B"
+Use the BackingStore of the Xserver instead of the integrated one in
+rdesktop.
+.TP
+.BR "-e"
+Disable encryption. This option is only needed (and will only work) if you
+have a French version of NT TSE.
+.TP
+.BR "-E"
+Disable encryption from client to server. This sends an encrypted login packet,
+but everything after this is unencrypted (including interactive logins).
+.TP
+.BR "-m"
+Do not send mouse motion events. This saves bandwidth, although some Windows
+applications may rely on receiving mouse motion.
+.TP
+.BR "-C"
+Use private colourmap. This will improve colour accuracy on an 8-bit display,
+but rdesktop will appear in false colour when not focused.
+.TP
+.BR "-D"
+Hide window manager decorations, by using MWM hints.
+.TP
+.BR "-K"
+Do not override window manager key bindings. By default rdesktop attempts
+to grab all keyboard input when it is in focus.
+.TP
+.BR "-S <button size>"
+Enable single application mode. This option can be used when running a
+single, maximized application (via -s). When the minimize button of
+the windows application is pressed, the rdesktop window is minimized
+instead of the remote application. The maximize/restore button is
+disabled. For this to work, you must specify the correct button
+size, in pixels. The special word "standard" means 18 pixels.
+.TP
+.BR "-T <title>"
+Sets the window title. The title must be specified using an UTF-8 string.
+.TP
+.BR "-N"
+Enable numlock syncronization between the Xserver and the remote RDP
+session. This is useful with applications that looks at the numlock
+state, but might cause problems with some Xservers like Xvnc.
+.TP
+.BR "-X <windowid>"
+Embed rdesktop-window in another window. The windowid is expected to
+be decimal or hexadecimal (prefixed by 0x).
+.TP
+.BR "-a <bpp>"
+Sets the colour depth for the connection (8, 15, 16 or 24).
+More than 8 bpp are only supported when connecting to Windows XP
+(up to 16 bpp) or newer. Note that the colour depth may also be
+limited by the server configuration. The default value is the depth
+of the root window.
+.TP
+.BR "-z"
+Enable compression of the RDP datastream.
+.TP
+.BR "-x <experience>"
+Changes default bandwidth performance behaviour for RDP5. By default only
+theming is enabled, and all other options are disabled (corresponding
+to modem (56 Kbps)). Setting experience to b[roadband] enables menu
+animations and full window dragging. Setting experience to l[an] will
+also enable the desktop wallpaper. Setting experience to m[odem]
+disables all (including themes). Experience can also be a hexidecimal
+number containing the flags.
+.TP
+.BR "-P"
+Enable caching of bitmaps to disk (persistent bitmap caching). This generally
+improves performance (especially on low bandwidth connections) and reduces
+network traffic at the cost of slightly longer startup and some disk space.
+(10MB for 8-bit colour, 20MB for 15/16-bit colour and 30MB for 24-bit colour
+sessions)
+.TP
+.BR "-r <device>"
+Enable redirection of the specified device on the client, such
+that it appears on the server. Note that the allowed
+redirections may be restricted by the server configuration.
+
+Following devices are currently supported:
+.TP
+.BR "-r comport:<comport>=<device>,..."
+Redirects serial devices on your client to the
+server. Note that if you need to change any settings on the serial device(s),
+do so with an appropriate tool before starting rdesktop. In most
+OSes you would use stty. Bidirectional/Read support requires Windows XP or newer.
+In Windows 2000 it will create a port, but it's not seamless, most
+shell programs will not work with it.
+.TP
+.BR "-r disk:<sharename>=<path>,..."
+Redirects a path to the share \\\\tsclient\\<sharename> on the server
+(requires Windows XP or newer). The share name is limited to 8
+characters.
+.TP
+.BR "-r lptport:<lptport>=<device>,..."
+Redirects parallel devices on your client to the server.
+Bidirectional/Read support requires Windows XP or newer. In Windows 2000
+it will create a port, but it's not seamless, most shell programs will not work with
+it.
+.TP
+.BR "-r printer:<printername>[=<driver>],..."
+Redirects a printer queue on the client to the server. The <printername>
+is the name of the queue in your local system. <driver> defaults to a
+simple PS-driver unless you specify one. Keep in mind that you need a
+100% match in the server environment, or the driver will fail. The first
+printer on the command line will be set as your default printer.
+.TP
+.BR "-r sound:[local|off|remote]"
+Redirects sound generated on the server to the client. "remote" only has
+any effect when you connect to the console with the -0 option. (Requires
+Windows XP or newer).
+.TP
+.BR "-r lspci"
+Activates the lspci channel, which allows the server to enumerate the
+clients PCI devices. See the file lspci-channel.txt in the
+documentation for more information.
+.TP
+.BR "-r scard[:<Scard Name>=<Alias Name>[;<Vendor Name>][,...]]"
+Enables redirection of one or more smart-cards. You can provide
+static name binding between linux and windows. To do this you
+can use optional parameters as described: <Scard Name> - device name in
+Linux/Unix enviroment, <Alias Name> - device name shown in Windows enviroment
+<Vendor Name> - optional device vendor name. For list of examples run
+rdesktop without parameters.
+.TP
+.BR "-0"
+Attach to the console of the server (requires Windows Server 2003
+or newer).
+.TP
+.BR "-4"
+Use RDP version 4.
+.TP
+.BR "-5"
+Use RDP version 5 (default).
+.PP
+.SH "EXIT VALUES"
+.PP
+.IP "\fB0\fP"
+RDP session terminated normally
+.IP "\fB1\fP"
+Server initiated disconnect (also returned for logoff by XP joined to a domain)
+.IP "\fB2\fP"
+Server initiated logoff
+.IP "\fB3\fP"
+Server idle timeout reached
+.IP "\fB4\fP"
+Server logon timeout reached
+.IP "\fB5\fP"
+The session was replaced
+.IP "\fB6\fP"
+The server is out of memory
+.IP "\fB7\fP"
+The server denied the connection
+.IP "\fB8\fP"
+The server denied the connection for security reason
+.IP "\fB16\fP"
+Internal licensing error
+.IP "\fB17\fP"
+No license server available
+.IP "\fB18\fP"
+No valid license available
+.IP "\fB19\fP"
+Invalid licensing message
+.IP "\fB20\fP"
+Hardware id doesn't match software license
+.IP "\fB21\fP"
+Client license error
+.IP "\fB22\fP"
+Network error during licensing protocol
+.IP "\fB23\fP"
+Licensing protocol was not completed
+.IP "\fB24\fP"
+Incorrect client license enryption
+.IP "\fB25\fP"
+Can't upgrade license
+.IP "\fB26\fP"
+The server is not licensed to accept remote connections
+.IP "\fB62\fP"
+The local client window was closed
+.IP "\fB63\fP"
+Some other, unknown error occured
+.IP "\fB64\fP"
+Command line usage error
+.IP "\fB69\fP"
+A service or resource (such as memory) is unavailable
+.IP "\fB70\fP"
+An internal software error has been detected
+.IP "\fB71\fP"
+Operating system error
+.IP "\fB76\fP"
+Protocol error or unable to connect to remote host.
+
+.PP
+.SH LINKS
+Main website of rdesktop
+.br
+\fIhttp://www.rdesktop.org/
+.LP
+.PP
diff --git a/src/VBox/RDP/client/doc/redirection.txt b/src/VBox/RDP/client/doc/redirection.txt
new file mode 100644
index 000000000..026504501
--- /dev/null
+++ b/src/VBox/RDP/client/doc/redirection.txt
@@ -0,0 +1,74 @@
+
+Syntax for configuring RDP redirection modules
+==============================================
+
+General
+-------
+
+All redirection is configured using the -r option. The general syntax
+is:
+
+-r <module>:<string>
+
+<module> is the name of the redirection module. The following names
+are valid: disk, printer, lptport, comport, clipboard, sound.
+
+<string> is interpreted by each redirection module.
+
+The redirection modules are described below.
+
+
+disk mapping
+-------------
+Multiple mappings possible: yes
+Default: no disk redirected
+Syntax: -r disk:<sharename>=<path>
+Example: -r disk:home=/home/johndoe
+
+
+printer mapping
+---------------
+Multiple mappings possible: yes
+Default: no printers redirected
+Syntax: -r printer:<printername>
+Example: -r printer:mydeskjet
+
+
+
+LPT port mapping
+----------------
+Multiple mappings possible: yes
+Default: no LPT ports redirected
+Syntax: -r lptport:<lptport>=<device>
+Example: -r lptport:LPT1=/dev/lp0
+
+
+COM port mapping
+----------------
+Multiple mappings possible: yes
+Default: no COM ports redirected
+Syntax: -r comport:<comport>=<device>
+Example: -r comport:COM1=/dev/ttyS0
+
+
+clipboard mapping
+-----------------
+Multiple mappings possible: no
+Default: yes
+Syntax: -r clipboard:[yes|no]
+Example: -r clipboard:no
+
+
+sound mapping
+-------------
+Multiple mappings possible: no
+Default: off
+Syntax: -r sound:[local|off|remote]
+
+"local" means "Bring to this computer"
+"off" means "Do not play"
+"remote" means "Leave at remote computer"
+
+Example: -r sound:remote
+
+
diff --git a/src/VBox/RDP/client/files_rdesktop-vrdp b/src/VBox/RDP/client/files_rdesktop-vrdp
index 95c9749e9..9572d14af 100644
--- a/src/VBox/RDP/client/files_rdesktop-vrdp
+++ b/src/VBox/RDP/client/files_rdesktop-vrdp
@@ -1,4 +1,4 @@
-# $Id: files_rdesktop-vrdp $
+# $Id: files_rdesktop-vrdp 37955 2011-07-14 12:23:02Z vboxsync $
## @file
# VBox - rdesktop with VRDP enhancements archive file list.
#
@@ -52,6 +52,7 @@ rdesktop-nonbin_SOURCES = \
$(PATH_ROOT)/include/iprt/thread.h=>include/iprt/thread.h \
$(PATH_ROOT)/include/iprt/types.h=>include/iprt/types.h \
$(PATH_ROOT)/include/iprt/uni.h=>include/iprt/uni.h \
+ $(PATH_ROOT)/include/iprt/x86.h=>include/iprt/x86.h \
$(PATH_ROOT)/include/VBox/cdefs.h=>include/VBox/cdefs.h \
$(PATH_ROOT)/include/VBox/err.h=>include/VBox/err.h \
$(PATH_ROOT)/include/VBox/log.h=>include/VBox/log.h \
@@ -62,7 +63,6 @@ rdesktop-nonbin_SOURCES = \
$(PATH_ROOT)/include/VBox/usblib.h=>include/VBox/usblib.h \
$(PATH_ROOT)/include/VBox/version.h=>include/VBox/version.h \
$(PATH_ROOT)/include/VBox/vusb.h=>include/VBox/vusb.h \
- $(PATH_ROOT)/include/VBox/x86.h=>include/VBox/x86.h \
$(PATH_ROOT)/src/VBox/Devices/USB/linux/USBProxyDevice-linux.cpp=>vrdp/linux/USBProxyDevice-linux.cpp \
$(PATH_ROOT)/src/VBox/Devices/USB/USBProxyDevice.h=>vrdp/USBProxyDevice.h \
$(PATH_ROOT)/src/VBox/HostDrivers/VBoxUSB/USBLib.cpp=>vrdp/USBLib.cpp \
diff --git a/src/VBox/RDP/client/keymaps/ar b/src/VBox/RDP/client/keymaps/ar
new file mode 100644
index 000000000..c430c03bb
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/ar
@@ -0,0 +1,98 @@
+# generated from XKB map ar
+include common
+map 0x401
+exclam 0x02 shift
+at 0x03 shift
+numbersign 0x04 shift
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+Arabic_dad 0x10 altgr
+Arabic_fatha 0x10 shift altgr
+Arabic_sad 0x11 altgr
+Arabic_fathatan 0x11 shift altgr
+Arabic_theh 0x12 altgr
+Arabic_damma 0x12 shift altgr
+Arabic_qaf 0x13 altgr
+Arabic_dammatan 0x13 shift altgr
+Arabic_feh 0x14 altgr
+UFEF9 0x14 shift altgr
+Arabic_ghain 0x15 altgr
+Arabic_hamzaunderalef 0x15 shift altgr
+Arabic_ain 0x16 altgr
+grave 0x16 shift altgr
+Arabic_ha 0x17 altgr
+division 0x17 shift altgr
+Arabic_khah 0x18 altgr
+multiply 0x18 shift altgr
+Arabic_hah 0x19 altgr
+Arabic_semicolon 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+Arabic_jeem 0x1a altgr
+bracketright 0x1b
+braceright 0x1b shift
+Arabic_dal 0x1b altgr
+Arabic_sheen 0x1e altgr
+backslash 0x1e shift altgr
+Arabic_seen 0x1f altgr
+Arabic_yeh 0x20 altgr
+bracketleft 0x20 shift altgr
+Arabic_beh 0x21 altgr
+bracketright 0x21 shift altgr
+Arabic_lam 0x22 altgr
+UFEF7 0x22 shift altgr
+Arabic_alef 0x23 altgr
+Arabic_hamzaonalef 0x23 shift altgr
+Arabic_teh 0x24 altgr
+Arabic_tatweel 0x24 shift altgr
+Arabic_noon 0x25 altgr
+Arabic_comma 0x25 shift altgr
+Arabic_meem 0x26 altgr
+slash 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+Arabic_kaf 0x27 altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+Arabic_tah 0x28 altgr
+grave 0x29
+asciitilde 0x29 shift
+Arabic_thal 0x29 altgr
+Arabic_shadda 0x29 shift altgr
+backslash 0x2b
+bar 0x2b shift
+less 0x2b altgr
+greater 0x2b shift altgr
+Arabic_hamzaonyeh 0x2c altgr
+asciitilde 0x2c shift altgr
+Arabic_hamza 0x2d altgr
+Arabic_sukun 0x2d shift altgr
+Arabic_hamzaonwaw 0x2e altgr
+Arabic_kasra 0x2e shift altgr
+Arabic_ra 0x2f altgr
+Arabic_kasratan 0x2f shift altgr
+UFEFB 0x30 altgr
+UFEF5 0x30 shift altgr
+Arabic_alefmaksura 0x31 altgr
+Arabic_maddaonalef 0x31 shift altgr
+Arabic_tehmarbuta 0x32 altgr
+apostrophe 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+Arabic_waw 0x33 altgr
+period 0x34
+greater 0x34 shift
+Arabic_zain 0x34 altgr
+slash 0x35
+question 0x35 shift
+Arabic_zah 0x35 altgr
+Arabic_question_mark 0x35 shift altgr
diff --git a/src/VBox/RDP/client/keymaps/common b/src/VBox/RDP/client/keymaps/common
new file mode 100644
index 000000000..f767b7b01
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/common
@@ -0,0 +1,229 @@
+include modifiers
+
+#
+# Top row
+#
+1 0x2
+2 0x3
+3 0x4
+4 0x5
+5 0x6
+6 0x7
+7 0x8
+8 0x9
+9 0xa
+0 0xb
+BackSpace 0xe
+
+#
+# QWERTY first row
+#
+Tab 0xf localstate
+ISO_Left_Tab 0xf shift
+q 0x10 addupper
+w 0x11 addupper
+e 0x12 addupper
+sequence egrave dead_grave e
+sequence Egrave dead_grave E
+sequence eacute dead_acute e
+sequence Eacute dead_acute E
+sequence ecircumflex dead_circumflex e
+sequence Ecircumflex dead_circumflex E
+sequence ediaeresis dead_diaeresis e
+sequence Ediaeresis dead_diaeresis E
+r 0x13 addupper
+t 0x14 addupper
+y 0x15 addupper
+sequence ygrave dead_grave y
+sequence Ygrave dead_grave Y
+sequence yacute dead_acute y
+sequence Yacute dead_acute Y
+sequence ycircumflex dead_circumflex y
+sequence Ycircumflex dead_circumflex Y
+sequence ydiaeresis dead_diaeresis y
+sequence Ydiaeresis dead_diaeresis Y
+u 0x16 addupper
+sequence ugrave dead_grave u
+sequence Ugrave dead_grave U
+sequence uacute dead_acute u
+sequence Uacute dead_acute U
+sequence ucircumflex dead_circumflex u
+sequence Ucircumflex dead_circumflex U
+sequence udiaeresis dead_diaeresis u
+sequence Udiaeresis dead_diaeresis U
+i 0x17 addupper
+sequence igrave dead_grave i
+sequence Igrave dead_grave I
+sequence iacute dead_acute i
+sequence Iacute dead_acute I
+sequence icircumflex dead_circumflex i
+sequence Icircumflex dead_circumflex I
+sequence idiaeresis dead_diaeresis i
+sequence Idiaeresis dead_diaeresis I
+o 0x18 addupper
+sequence ograve dead_grave o
+sequence Ograve dead_grave O
+sequence oacute dead_acute o
+sequence Oacute dead_acute O
+sequence ocircumflex dead_circumflex o
+sequence Ocircumflex dead_circumflex O
+sequence odiaeresis dead_diaeresis o
+sequence Odiaeresis dead_diaeresis O
+sequence otilde dead_tilde o
+sequence Otilde dead_tilde O
+p 0x19 addupper
+
+#
+# QWERTY second row
+#
+a 0x1e addupper
+sequence agrave dead_grave a
+sequence Agrave dead_grave A
+sequence aacute dead_acute a
+sequence Aacute dead_acute A
+sequence acircumflex dead_circumflex a
+sequence Acircumflex dead_circumflex A
+sequence adiaeresis dead_diaeresis a
+sequence Adiaeresis dead_diaeresis A
+sequence aring dead_abovering a
+sequence Aring dead_abovering A
+sequence atilde dead_tilde a
+sequence Atilde dead_tilde A
+s 0x1f addupper
+d 0x20 addupper
+f 0x21 addupper
+g 0x22 addupper
+h 0x23 addupper
+j 0x24 addupper
+k 0x25 addupper
+l 0x26 addupper
+Return 0x1c localstate
+
+#
+# QWERTY third row
+#
+z 0x2c addupper
+x 0x2d addupper
+c 0x2e addupper
+sequence ccedilla dead_cedilla c
+sequence Ccedilla dead_cedilla C
+v 0x2f addupper
+b 0x30 addupper
+n 0x31 addupper
+sequence ntilde dead_tilde n
+sequence Ntilde dead_tilde N
+m 0x32 addupper
+
+space 0x39 localstate
+
+less 0x56
+greater 0x56 shift
+bar 0x56 altgr
+brokenbar 0x56 shift altgr
+
+#
+# Translations for some other dead keys
+#
+sequence asciitilde dead_tilde space
+sequence diaeresis dead_diaeresis space
+sequence asciicircum dead_circumflex space
+sequence apostrophe dead_acute space
+sequence grave dead_grave space
+sequence acute dead_acute space
+
+#
+# Esc and Function keys
+#
+Escape 0x1 localstate
+F1 0x3b localstate
+F2 0x3c localstate
+F3 0x3d localstate
+F4 0x3e localstate
+F5 0x3f localstate
+F6 0x40 localstate
+F7 0x41 localstate
+F8 0x42 localstate
+F9 0x43 localstate
+F10 0x44 localstate
+F11 0x57 localstate
+SunF36 0x57 localstate
+F12 0x58 localstate
+SunF37 0x58 localstate
+
+# Printscreen, Scrollock and Pause
+# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37),
+# but (0xe0, 0x37) seems to work.
+Print 0xb7 localstate
+Sys_Req 0xb7 localstate
+Execute 0xb7 localstate
+F22 0xb7 localstate
+Scroll_Lock 0x46
+F23 0x46
+
+#
+# Insert - PgDown
+#
+Insert 0xd2 localstate
+Delete 0xd3 localstate
+Home 0xc7 localstate
+End 0xcf localstate
+Page_Up 0xc9 localstate
+Page_Down 0xd1 localstate
+
+#
+# Arrow keys
+#
+Left 0xcb localstate
+Up 0xc8 localstate
+Down 0xd0 localstate
+Right 0xcd localstate
+
+#
+# Numpad
+#
+Num_Lock 0x45
+KP_Divide 0xb5 localstate
+KP_Multiply 0x37 localstate
+KP_Subtract 0x4a localstate
+KP_Add 0x4e localstate
+KP_Enter 0x9c localstate
+
+KP_Decimal 0x53 numlock
+KP_Separator 0x53 numlock
+KP_Delete 0x53
+
+KP_0 0x52 numlock
+KP_Insert 0x52 localstate
+
+KP_1 0x4f numlock
+KP_End 0x4f localstate
+
+KP_2 0x50 numlock
+KP_Down 0x50 localstate
+
+KP_3 0x51 numlock
+KP_Next 0x51 localstate
+
+KP_4 0x4b numlock
+KP_Left 0x4b localstate
+
+KP_5 0x4c numlock
+KP_Begin 0x4c localstate
+
+KP_6 0x4d numlock
+KP_Right 0x4d localstate
+
+KP_7 0x47 numlock
+KP_Home 0x47 localstate
+
+KP_8 0x48 numlock
+KP_Up 0x48 localstate
+
+KP_9 0x49 numlock
+KP_Prior 0x49 localstate
+
+#
+# Inhibited keys
+#
+Caps_Lock 0x0 inhibit
+Multi_key 0x0 inhibit
diff --git a/src/VBox/RDP/client/keymaps/convert-map b/src/VBox/RDP/client/keymaps/convert-map
new file mode 100755
index 000000000..c88c72db0
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/convert-map
@@ -0,0 +1,63 @@
+#!/usr/bin/env python2
+# -*-Python-*-
+#
+#
+# Copyright (C) 2001 Peter Ã…strand <astrand@cendio.se>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sys
+
+def main():
+ f = open(sys.argv[1])
+ while 1:
+ line = f.readline()
+ if not line: break
+
+ if line.startswith("#") or line.startswith("include"):
+ print line,
+ continue
+
+ fields = line.split()
+
+ if line.startswith("map"):
+ print "map 0x%s" % fields[1]
+ continue
+
+ scancode = fields[0]
+ for pos in range(1, len(fields)):
+ keysym = fields[pos]
+
+ if pos == 1:
+ modifiers = ""
+ elif pos == 2:
+ modifiers = "shift"
+ elif pos == 3:
+ modifiers = "altgr"
+ elif pos == 4:
+ modifiers = "shift altgr"
+ else:
+ raise("Invalid line: %s" % line)
+
+ print "%s 0x%s %s" % (keysym, scancode, modifiers)
+
+
+
+if __name__ == "__main__":
+ if len(sys.argv) < 2:
+ print "Convert old-style keymaps to new style"
+ print "Usage: %s <old-style-keymap>" % sys.argv[0]
+ sys.exit(1)
+ else:
+ main()
diff --git a/src/VBox/RDP/client/keymaps/cs b/src/VBox/RDP/client/keymaps/cs
new file mode 100644
index 000000000..5c89b0096
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/cs
@@ -0,0 +1,87 @@
+# Czech keymap
+include common
+map 0x405
+
+# AltGr
+ISO_Level3_Shift 0xb8
+
+#
+# Top row
+#
+
+# `
+grave 0x29
+asciitilde 0x29 shift
+# 1
+exclam 0x2 shift
+# 2
+at 0x3 shift
+ecaron 0x3 altgr
+# 3
+numbersign 0x4 shift
+# 4
+dollar 0x5 shift
+# 5
+percent 0x6 shift
+# 6
+asciicircum 0x7 shift
+# 7
+ampersand 0x8 shift
+# 8
+asterisk 0x9 shift
+# 9
+parenleft 0xa shift
+# 0
+parenright 0xb shift
+# -
+minus 0xc
+underscore 0xc shift
+# =
+equal 0xd
+plus 0xd shift
+
+
+#
+# QWERTZ first row
+#
+
+# q
+q 0x10 altgr
+# e
+e 0x12 altgr
+# [
+bracketleft 0x1a
+braceleft 0x1a shift
+# ]
+bracketright 0x1b
+braceright 0x1b shift
+
+#
+# QWERTZ second row
+#
+
+# ;
+semicolon 0x27
+# ;
+colon 0x27 shift
+# '
+apostrophe 0x28
+# '
+quotedbl 0x28 shift
+
+#
+# QWERTZ third row
+#
+
+# v
+v 0x2f altgr
+# ,
+comma 0x33
+less 0x33 shift
+# .
+period 0x34
+greater 0x34 shift
+# /
+slash 0x35
+question 0x35 shift
+
diff --git a/src/VBox/RDP/client/keymaps/da b/src/VBox/RDP/client/keymaps/da
new file mode 100644
index 000000000..3884dcf14
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/da
@@ -0,0 +1,120 @@
+# generated from XKB map dk
+include common
+map 0x406
+exclam 0x02 shift
+exclamdown 0x02 altgr
+onesuperior 0x02 shift altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+twosuperior 0x03 shift altgr
+numbersign 0x04 shift
+sterling 0x04 altgr
+threesuperior 0x04 shift altgr
+currency 0x05 shift
+dollar 0x05 altgr
+onequarter 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+cent 0x06 shift altgr
+ampersand 0x07 shift
+yen 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+division 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+guillemotleft 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+guillemotright 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+plus 0x0c
+question 0x0c shift
+plusminus 0x0c altgr
+questiondown 0x0c shift altgr
+dead_acute 0x0d
+dead_grave 0x0d shift
+bar 0x0d altgr
+brokenbar 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+registered 0x13 altgr
+thorn 0x14 altgr
+THORN 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oe 0x18 altgr
+OE 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+aring 0x1a
+Aring 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+dead_diaeresis 0x1b
+dead_circumflex 0x1b shift
+dead_tilde 0x1b altgr
+dead_caron 0x1b shift altgr
+ordfeminine 0x1e altgr
+masculine 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+ae 0x27
+AE 0x27 shift
+oslash 0x28
+Ooblique 0x28 shift
+dead_caron 0x28 shift altgr
+onehalf 0x29
+section 0x29 shift
+threequarters 0x29 altgr
+paragraph 0x29 shift altgr
+apostrophe 0x2b
+asterisk 0x2b shift
+dead_doubleacute 0x2b altgr
+multiply 0x2b shift altgr
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+copyright 0x2e altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+dead_cedilla 0x33 altgr
+dead_ogonek 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+dead_abovedot 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+hyphen 0x35 altgr
+macron 0x35 shift altgr
+nobreakspace 0x39 altgr
+less 0x56
+greater 0x56 shift
+backslash 0x56 altgr
+notsign 0x56 shift altgr
diff --git a/src/VBox/RDP/client/keymaps/de b/src/VBox/RDP/client/keymaps/de
new file mode 100644
index 000000000..ed929c743
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/de
@@ -0,0 +1,114 @@
+# generated from XKB map de
+include common
+map 0x407
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+section 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+currency 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+ssharp 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+acute 0x0d
+dead_acute 0x0d
+grave 0x0d shift
+dead_grave 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+udiaeresis 0x1a
+Udiaeresis 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+plus 0x1b
+asterisk 0x1b shift
+asciitilde 0x1b altgr
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+odiaeresis 0x27
+Odiaeresis 0x27 shift
+dead_doubleacute 0x27 altgr
+adiaeresis 0x28
+Adiaeresis 0x28 shift
+dead_caron 0x28 shift altgr
+asciicircum 0x29
+dead_circumflex 0x29
+degree 0x29 shift
+notsign 0x29 altgr
+numbersign 0x2b
+apostrophe 0x2b shift
+dead_breve 0x2b shift altgr
+y 0x2c addupper
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/src/VBox/RDP/client/keymaps/de-ch b/src/VBox/RDP/client/keymaps/de-ch
new file mode 100644
index 000000000..f83837b44
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/de-ch
@@ -0,0 +1,169 @@
+# rdesktop Swiss-German (de-ch) keymap file
+# 2003-06-03 by noldi@tristar.ch
+#
+include common
+map 0x00000807
+#
+# Scan Code 1
+section 0x29
+degree 0x29 shift
+notsign 0x29 altgr inhibit
+#
+# Scan Code 2
+plus 0x2 shift
+brokenbar 0x02 altgr
+#
+# Scan Code 3
+quotedbl 0x03 shift
+at 0x03 altgr
+#
+# Scan Code 4
+asterisk 0x04 shift
+numbersign 0x04 altgr
+#
+# Scan Code 5
+ccedilla 0x05 shift
+onequarter 0x05 altgr inhibit
+#
+# Scan Code 6
+percent 0x06 shift
+onehalf 0x06 altgr inhibit
+#
+# Scan Code 7
+ampersand 0x07 shift
+notsign 0x07 altgr
+#
+# Scan Code 8
+slash 0x08 shift
+bar 0x08 altgr
+#
+# Scan Code 9
+parenleft 0x09 shift
+cent 0x09 altgr
+#
+# Scan Code 10
+parenright 0x0a shift
+#
+# Scan Code 11
+equal 0x0b shift
+braceright 0x0b altgr inhibit
+#
+# Scan Code 12
+apostrophe 0x0c
+question 0x0c shift
+dead_acute 0x0c altgr
+#
+# Scan Code 13
+dead_circumflex 0x0d
+dead_grave 0x0d shift
+dead_tilde 0x0d altgr
+#
+# Scan Code 19
+EuroSign 0x12 altgr
+#
+# Scan Code 22
+z 0x15 addupper
+#
+# Scan Code 27
+udiaeresis 0x1a
+egrave 0x1a shift
+bracketleft 0x1a altgr
+#
+# Scan Code 28
+dead_diaeresis 0x1b
+exclam 0x1b shift
+bracketright 0x1b altgr
+#
+# Scan Code 40
+odiaeresis 0x27
+eacute 0x27 shift
+#
+# Scan Code 41
+adiaeresis 0x28
+agrave 0x28 shift
+braceleft 0x28 altgr
+#
+# Scan Code 42 (only on international keyboards)
+dollar 0x2b
+sterling 0x2b shift
+braceright 0x2b altgr
+#
+# Scan Code 45 (only on international keyboards)
+backslash 0x56 altgr
+#
+# Scan Code 46
+y 0x2c addupper
+#
+# Scan Code 53
+comma 0x33
+semicolon 0x33 shift
+#
+# Scan Code 54
+period 0x34
+colon 0x34 shift
+#
+# Scan Code 55
+minus 0x35
+underscore 0x35 shift
+#
+# Suppress Windows unsupported AltGr keys
+#
+# Scan Code 17
+paragraph 0x10 altgr inhibit
+#
+# Scan Code 21
+tslash 0x14 altgr inhibit
+#
+# Scan Code 22
+leftarrow 0x15 altgr inhibit
+#
+# Scan Code 23
+downarrow 0x16 altgr inhibit
+#
+# Scan Code 24
+rightarrow 0x17 altgr inhibit
+#
+# Scan Code 25
+oslash 0x18 altgr inhibit
+#
+# Scan Code 26
+thorn 0x19 altgr inhibit
+#
+# Scan Code 31
+ae 0x1e altgr inhibit
+#
+# Scan Code 32
+ssharp 0x1f altgr inhibit
+#
+# Scan Code 33
+eth 0x20 altgr inhibit
+#
+# Scan Code 34
+dstroke 0x21 altgr inhibit
+#
+# Scan Code 35
+eng 0x22 altgr inhibit
+#
+# Scan Code 36
+hstroke 0x23 altgr inhibit
+#
+# Scan Code 38
+kra 0x25 altgr inhibit
+#
+# Scan Code 39
+lstroke 0x26 altgr inhibit
+#
+# Scan Code 46
+guillemotleft 0x2c altgr inhibit
+#
+# Scan Code 47
+guillemotright 0x2d altgr inhibit
+#
+# Scan Code 49
+leftdoublequotemark 0x2f altgr inhibit
+#
+# Scan Code 50
+rightdoublequotemark 0x30 altgr inhibit
+#
+# Scan Code 52
+mu 0x32 altgr inhibit
diff --git a/src/VBox/RDP/client/keymaps/en-dv b/src/VBox/RDP/client/keymaps/en-dv
new file mode 100644
index 000000000..720accf6d
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/en-dv
@@ -0,0 +1,216 @@
+# American Dvorak
+map 0x10409
+
+# Note: we are not including the common section
+include modifiers
+
+#
+# Top row
+#
+1 0x2
+2 0x3
+3 0x4
+4 0x5
+5 0x6
+6 0x7
+7 0x8
+8 0x9
+9 0xa
+0 0xb
+BackSpace 0xe
+
+#
+# QWERTY first row
+
+# QWERTY:
+# q w e r t y u i o p
+
+# Dvorak:
+# ' , . p y f g c r l
+
+Tab 0xf localstate
+ISO_Left_Tab 0xf shift
+q 0x2d addupper
+w 0x33 addupper
+e 0x20 addupper
+r 0x18 addupper
+t 0x25 addupper
+y 0x14 addupper
+u 0x21 addupper
+i 0x22 addupper
+o 0x1f addupper
+p 0x13 addupper
+
+#
+# QWERTY second row
+
+# QUERTY:
+# a s d f g h j k l
+
+# Dvorak:
+# a o e u i d h t n
+
+a 0x1e addupper
+s 0x27 addupper
+d 0x23 addupper
+f 0x15 addupper
+g 0x16 addupper
+h 0x24 addupper
+j 0x2e addupper
+k 0x2f addupper
+l 0x19 addupper
+Return 0x1c localstate
+
+#
+# QWERTY third row
+
+# QUERTY:
+# z x c v b n m
+
+# Dvorak:
+# ; q j k x b m
+
+z 0x35 addupper
+x 0x30 addupper
+c 0x17 addupper
+v 0x34 addupper
+b 0x31 addupper
+n 0x26 addupper
+m 0x32 addupper
+
+space 0x39 localstate
+
+less 0x56
+greater 0x56 shift
+bar 0x56 altgr
+brokenbar 0x56 shift altgr
+
+#
+# Esc and Function keys
+#
+Escape 0x1 localstate
+F1 0x3b localstate
+F2 0x3c localstate
+F3 0x3d localstate
+F4 0x3e localstate
+F5 0x3f localstate
+F6 0x40 localstate
+F7 0x41 localstate
+F8 0x42 localstate
+F9 0x43 localstate
+F10 0x44 localstate
+F11 0x57 localstate
+SunF36 0x57 localstate
+F12 0x58 localstate
+SunF37 0x58 localstate
+
+# Printscreen, Scrollock and Pause
+# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37),
+# but (0xe0, 0x37) seems to work.
+Print 0xb7 localstate
+Sys_Req 0xb7 localstate
+Execute 0xb7 localstate
+F22 0xb7 localstate
+Scroll_Lock 0x46
+F23 0x46
+
+#
+# Insert - PgDown
+#
+Insert 0xd2 localstate
+Delete 0xd3 localstate
+Home 0xc7 localstate
+End 0xcf localstate
+Page_Up 0xc9 localstate
+Page_Down 0xd1 localstate
+
+#
+# Arrow keys
+#
+Left 0xcb localstate
+Up 0xc8 localstate
+Down 0xd0 localstate
+Right 0xcd localstate
+
+#
+# Numpad
+#
+Num_Lock 0x45
+KP_Divide 0xb5
+KP_Multiply 0x37
+KP_Subtract 0x4a
+KP_Add 0x4e
+KP_Enter 0x9c
+
+KP_Decimal 0x53 numlock
+KP_Separator 0x53 numlock
+KP_Delete 0x53
+
+KP_0 0x52 numlock
+KP_Insert 0x52
+
+KP_1 0x4f numlock
+KP_End 0x4f
+
+KP_2 0x50 numlock
+KP_Down 0x50
+
+KP_3 0x51 numlock
+KP_Next 0x51
+
+KP_4 0x4b numlock
+KP_Left 0x4b
+
+KP_5 0x4c numlock
+KP_Begin 0x4c
+
+KP_6 0x4d numlock
+KP_Right 0x4d
+
+KP_7 0x47 numlock
+KP_Home 0x47
+
+KP_8 0x48 numlock
+KP_Up 0x48
+
+KP_9 0x49 numlock
+KP_Prior 0x49
+
+#
+# Inhibited keys
+#
+Caps_Lock 0x0 inhibit
+Multi_key 0x0 inhibit
+
+exclam 0x02 shift
+at 0x03 shift
+numbersign 0x04 shift
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x28
+underscore 0x28 shift
+equal 0x1b
+plus 0x1b shift
+bracketleft 0x0c
+braceleft 0x0c shift
+bracketright 0x0d
+braceright 0x0d shift
+semicolon 0x2c
+colon 0x2c shift
+apostrophe 0x10
+quotedbl 0x10 shift
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+comma 0x11
+less 0x11 shift
+period 0x12
+greater 0x12 shift
+slash 0x1a
+question 0x1a shift
diff --git a/src/VBox/RDP/client/keymaps/en-gb b/src/VBox/RDP/client/keymaps/en-gb
new file mode 100644
index 000000000..b45f06c7c
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/en-gb
@@ -0,0 +1,119 @@
+# generated from XKB map gb
+include common
+map 0x809
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+sterling 0x04 shift
+threesuperior 0x04 altgr
+dollar 0x05 shift
+EuroSign 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+asciicircum 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+ampersand 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+asterisk 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenleft 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+parenright 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+minus 0x0c
+underscore 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+equal 0x0d
+plus 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+apostrophe 0x28
+at 0x28 shift
+dead_circumflex 0x28 altgr
+dead_caron 0x28 shift altgr
+grave 0x29
+notsign 0x29 shift
+bar 0x29 altgr
+numbersign 0x2b
+asciitilde 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+guillemotleft 0x2c altgr
+less 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
+backslash 0x56
+bar 0x56 shift
diff --git a/src/VBox/RDP/client/keymaps/en-us b/src/VBox/RDP/client/keymaps/en-us
new file mode 100644
index 000000000..f5784bbb3
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/en-us
@@ -0,0 +1,35 @@
+# generated from XKB map us
+include common
+map 0x409
+exclam 0x02 shift
+at 0x03 shift
+numbersign 0x04 shift
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+bracketleft 0x1a
+braceleft 0x1a shift
+bracketright 0x1b
+braceright 0x1b shift
+semicolon 0x27
+colon 0x27 shift
+apostrophe 0x28
+quotedbl 0x28 shift
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+slash 0x35
+question 0x35 shift
diff --git a/src/VBox/RDP/client/keymaps/es b/src/VBox/RDP/client/keymaps/es
new file mode 100644
index 000000000..0c29eec5a
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/es
@@ -0,0 +1,105 @@
+# generated from XKB map es
+include common
+map 0x40a
+exclam 0x02 shift
+bar 0x02 altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+oneeighth 0x03 shift altgr
+periodcentered 0x04 shift
+numbersign 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+asciitilde 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+notsign 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+trademark 0x09 shift altgr
+parenright 0x0a shift
+plusminus 0x0a shift altgr
+equal 0x0b shift
+degree 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+exclamdown 0x0d
+questiondown 0x0d shift
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+dead_grave 0x1a
+dead_circumflex 0x1a shift
+bracketleft 0x1a altgr
+dead_abovering 0x1a shift altgr
+plus 0x1b
+asterisk 0x1b shift
+bracketright 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+ntilde 0x27
+Ntilde 0x27 shift
+dead_doubleacute 0x27 shift altgr
+dead_acute 0x28
+dead_diaeresis 0x28 shift
+braceleft 0x28 altgr
+masculine 0x29
+ordfeminine 0x29 shift
+backslash 0x29 altgr
+ccedilla 0x2b
+Ccedilla 0x2b shift
+braceright 0x2b altgr
+dead_breve 0x2b shift altgr
+guillemotleft 0x2c altgr
+less 0x56
+greater 0x56 shift
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/src/VBox/RDP/client/keymaps/et b/src/VBox/RDP/client/keymaps/et
new file mode 100644
index 000000000..b5a73fef7
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/et
@@ -0,0 +1,86 @@
+map 0x00000425
+include common
+
+#
+# Top row
+#
+dead_caron 0x29
+dead_tilde 0x29 shift
+
+# 1
+exclam 0x2 shift
+
+# 2
+quotedbl 0x3 shift
+at 0x3 altgr
+
+# 3
+numbersign 0x4 shift
+sterling 0x4 altgr
+# 4
+currency 0x5 shift
+dollar 0x5 altgr
+# 5
+percent 0x6 shift
+# 6
+ampersand 0x7 shift
+# 7
+slash 0x8 shift
+braceleft 0x8 altgr
+# 8
+parenleft 0x9 shift
+bracketleft 0x9 altgr
+# 9
+parenright 0xa shift
+bracketright 0xa altgr
+# 0
+equal 0xb shift
+braceright 0xb altgr
+
+plus 0xc
+question 0xc shift
+backslash 0xc altgr
+
+acute 0xd
+dead_acute 0xd
+grave 0xd shift
+dead_grave 0xd shift
+
+#
+# QWERTY first row
+#
+EuroSign 0x12 altgr
+udiaeresis 0x1a
+Udiaeresis 0x1a shift
+otilde 0x1b
+Otilde 0x1b shift
+section 0x1b altgr
+
+#
+# QWERTY second row
+#
+scaron 0x1f altgr
+Scaron 0x1f altgr shift
+odiaeresis 0x27
+Odiaeresis 0x27 shift
+adiaeresis 0x28
+Adiaeresis 0x28 shift
+asciicircum 0x28 altgr
+apostrophe 0x2b
+asterisk 0x2b shift
+onehalf 0x2b altgr
+#
+# QWERTY third row
+#
+less 0x56
+greater 0x56 shift
+bar 0x56 altgr
+zcaron 0x2c altgr
+Zcaron 0x2c altgr shift
+comma 0x33
+semicolon 0x33 shift
+period 0x34
+colon 0x34 shift
+minus 0x35
+underscore 0x35 shift
+
diff --git a/src/VBox/RDP/client/keymaps/fi b/src/VBox/RDP/client/keymaps/fi
new file mode 100644
index 000000000..e08c69c2c
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/fi
@@ -0,0 +1,122 @@
+# Finnish keyboard layout
+# Originally generated from XKB map se_FI (wrong!), modified afterwards.
+
+include common
+map 0x40b
+
+exclam 0x02 shift
+exclamdown 0x02 altgr
+onesuperior 0x02 shift altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+twosuperior 0x03 shift altgr
+numbersign 0x04 shift
+sterling 0x04 altgr
+threesuperior 0x04 shift altgr
+currency 0x05 shift
+dollar 0x05 altgr
+onequarter 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+cent 0x06 shift altgr
+ampersand 0x07 shift
+yen 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+division 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+guillemotleft 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+guillemotright 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+plus 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+dead_acute 0x0d
+dead_grave 0x0d shift
+plusminus 0x0d altgr
+notsign 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+registered 0x13 altgr
+thorn 0x14 altgr
+THORN 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oe 0x18 altgr
+OE 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+aring 0x1a
+Aring 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+dead_diaeresis 0x1b
+dead_circumflex 0x1b shift
+dead_tilde 0x1b altgr
+dead_caron 0x1b shift altgr
+ordfeminine 0x1e altgr
+masculine 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+odiaeresis 0x27
+Odiaeresis 0x27 shift
+oslash 0x27 altgr
+Ooblique 0x27 shift altgr
+adiaeresis 0x28
+Adiaeresis 0x28 shift
+ae 0x28 altgr
+AE 0x28 shift altgr
+section 0x29
+onehalf 0x29 shift
+paragraph 0x29 altgr
+threequarters 0x29 shift altgr
+apostrophe 0x2b
+asterisk 0x2b shift
+acute 0x2b altgr
+multiply 0x2b shift altgr
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+copyright 0x2e altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+dead_cedilla 0x33 altgr
+dead_ogonek 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+dead_abovedot 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+hyphen 0x35 altgr
+macron 0x35 shift altgr
+nobreakspace 0x39 altgr
diff --git a/src/VBox/RDP/client/keymaps/fo b/src/VBox/RDP/client/keymaps/fo
new file mode 100644
index 000000000..83add423c
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/fo
@@ -0,0 +1,77 @@
+map 0x438
+include common
+
+#
+# Top row
+#
+onehalf 0x29
+section 0x29 shift
+
+# 1
+exclam 0x2 shift
+
+# 2
+quotedbl 0x3 shift
+at 0x3 altgr
+
+# 3
+numbersign 0x4 shift
+sterling 0x4 altgr
+# 4
+currency 0x5 shift
+dollar 0x5 altgr
+# 5
+percent 0x6 shift
+# 6
+ampersand 0x7 shift
+# 7
+slash 0x8 shift
+braceleft 0x8 altgr
+# 8
+parenleft 0x9 shift
+bracketleft 0x9 altgr
+# 9
+parenright 0xa shift
+bracketright 0xa altgr
+# 0
+equal 0xb shift
+braceright 0xb altgr
+
+plus 0xc
+question 0xc shift
+plusminus 0xc altgr
+
+bar 0xd altgr
+dead_acute 0xd
+
+#
+# QWERTY first row
+#
+EuroSign 0x12 altgr
+aring 0x1a
+Aring 0x1a shift
+eth 0x1b addupper
+asciitilde 0x1b altgr
+
+#
+# QWERTY second row
+#
+ae 0x27 addupper
+oslash 0x28
+Ooblique 0x28 shift
+apostrophe 0x2b
+asterisk 0x2b shift
+
+#
+# QWERTY third row
+#
+less 0x56
+greater 0x56 shift
+backslash 0x56 altgr
+comma 0x33
+semicolon 0x33 shift
+period 0x34
+colon 0x34 shift
+minus 0x35
+underscore 0x35 shift
+
diff --git a/src/VBox/RDP/client/keymaps/fr b/src/VBox/RDP/client/keymaps/fr
new file mode 100644
index 000000000..cbb45910f
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/fr
@@ -0,0 +1,181 @@
+include common
+map 0x40c
+#
+# Top row
+#
+twosuperior 0x29
+notsign 0x29 altgr
+
+ampersand 0x02
+1 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+
+eacute 0x03
+2 0x03 shift
+asciitilde 0x03 altgr
+oneeighth 0x03 shift altgr
+
+quotedbl 0x04
+3 0x04 shift
+numbersign 0x04 altgr
+
+apostrophe 0x05
+4 0x05 shift
+braceleft 0x05 altgr
+
+parenleft 0x06
+5 0x06 shift
+bracketleft 0x06 altgr
+threeeighths 0x06 shift altgr
+
+minus 0x07
+6 0x07 shift
+bar 0x07 altgr
+fiveeighths 0x07 shift altgr
+
+egrave 0x08
+7 0x08 shift
+grave 0x08 altgr
+seveneighths 0x08 shift altgr
+
+underscore 0x09
+8 0x09 shift
+backslash 0x09 altgr
+trademark 0x09 shift altgr
+
+ccedilla 0x0a
+9 0x0a shift
+asciicircum 0x0a altgr
+plusminus 0x0a shift altgr
+
+agrave 0x0b
+0 0x0b shift
+at 0x0b altgr
+
+parenright 0x0c
+degree 0x0c shift
+bracketright 0x0c altgr
+questiondown 0x0c shift altgr
+
+equal 0x0d
+plus 0x0d shift
+braceright 0x0d altgr
+dead_ogonek 0x0d shift altgr
+
+#
+# AZERTY first row
+#
+
+a 0x10 addupper
+ae 0x10 altgr
+AE 0x10 shift altgr
+
+z 0x11 addupper
+guillemotleft 0x11 altgr
+
+EuroSign 0x12 altgr
+
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+
+dead_circumflex 0x1a
+dead_diaeresis 0x1a shift
+dead_abovering 0x1a shift altgr
+
+dollar 0x1b
+sterling 0x1b shift
+currency 0x1b altgr
+dead_macron 0x1b shift altgr
+
+#
+# AZERTY second row
+#
+q 0x1e addupper
+Greek_OMEGA 0x1e shift altgr
+
+ssharp 0x1f altgr
+
+eth 0x20 altgr
+ETH 0x20 shift altgr
+
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+
+eng 0x22 altgr
+ENG 0x22 shift altgr
+
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+
+kra 0x25 altgr
+
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+
+m 0x27 addupper
+masculine 0x27 shift altgr
+
+ugrave 0x28
+percent 0x28 shift
+dead_caron 0x28 shift altgr
+
+asterisk 0x2b
+mu 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+
+#
+# AZERTY third row
+#
+less 0x56
+greater 0x56 shift
+
+w 0x2c addupper
+
+guillemotright 0x2d altgr
+
+cent 0x2e altgr
+copyright 0x2e shift altgr
+
+leftdoublequotemark 0x2f altgr
+
+rightdoublequotemark 0x30 altgr
+
+comma 0x32
+question 0x32 shift
+dead_acute 0x32 altgr
+dead_doubleacute 0x32 shift altgr
+
+semicolon 0x33
+period 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+
+colon 0x34
+slash 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+
+exclam 0x35
+section 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/src/VBox/RDP/client/keymaps/fr-be b/src/VBox/RDP/client/keymaps/fr-be
new file mode 100644
index 000000000..89e038398
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/fr-be
@@ -0,0 +1,135 @@
+# generated from XKB map be
+include common
+map 0x80c
+ampersand 0x02
+1 0x02 shift
+bar 0x02 altgr
+exclamdown 0x02 shift altgr
+eacute 0x03
+2 0x03 shift
+at 0x03 altgr
+oneeighth 0x03 shift altgr
+quotedbl 0x04
+3 0x04 shift
+numbersign 0x04 altgr
+sterling 0x04 shift altgr
+apostrophe 0x05
+4 0x05 shift
+onequarter 0x05 altgr
+dollar 0x05 shift altgr
+parenleft 0x06
+5 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+section 0x07
+6 0x07 shift
+asciicircum 0x07 altgr
+fiveeighths 0x07 shift altgr
+egrave 0x08
+7 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+exclam 0x09
+8 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+ccedilla 0x0a
+9 0x0a shift
+braceleft 0x0a altgr
+plusminus 0x0a shift altgr
+agrave 0x0b
+0 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+parenright 0x0c
+degree 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+minus 0x0d
+underscore 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+a 0x10 addupper
+Greek_OMEGA 0x10 shift altgr
+z 0x11 addupper
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+dead_circumflex 0x1a
+dead_diaeresis 0x1a shift
+bracketleft 0x1a altgr
+dead_abovering 0x1a shift altgr
+dollar 0x1b
+asterisk 0x1b shift
+bracketright 0x1b altgr
+dead_macron 0x1b shift altgr
+q 0x1e addupper
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+m 0x27 addupper
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+ugrave 0x28
+percent 0x28 shift
+dead_acute 0x28 altgr
+dead_caron 0x28 shift altgr
+twosuperior 0x29
+threesuperior 0x29 shift
+notsign 0x29 altgr
+mu 0x2b
+sterling 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+w 0x2c addupper
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+comma 0x32
+question 0x32 shift
+dead_cedilla 0x32 altgr
+masculine 0x32 shift altgr
+semicolon 0x33
+period 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+colon 0x34
+slash 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+equal 0x35
+plus 0x35 shift
+dead_tilde 0x35 altgr
+dead_abovedot 0x35 shift altgr
+backslash 0x56 altgr
+
diff --git a/src/VBox/RDP/client/keymaps/fr-ca b/src/VBox/RDP/client/keymaps/fr-ca
new file mode 100644
index 000000000..83c5f3468
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/fr-ca
@@ -0,0 +1,53 @@
+# Canadian French
+# By Simon Germain
+include common
+map 0xc0c
+
+backslash 0x29 altgr
+plusminus 0x2 altgr
+at 0x3 altgr
+sterling 0x4 altgr
+cent 0x5 altgr
+currency 0x6 altgr
+notsign 0x7 altgr
+bar 0x29 shift
+twosuperior 0x9 altgr
+threesuperior 0xa altgr
+onequarter 0xb altgr
+onehalf 0xc altgr
+threequarters 0xd altgr
+section 0x18 altgr
+paragraph 0x19 altgr
+bracketleft 0x1a altgr
+bracketright 0x1b altgr
+asciitilde 0x27 altgr
+braceleft 0x28 altgr
+braceright 0x2b altgr
+less 0x2b
+greater 0x2b shift
+guillemotleft 0x56
+guillemotright 0x56 shift
+degree 0x56 altgr
+mu 0x32 altgr
+eacute 0x35
+dead_acute 0x35 altgr
+dead_grave 0x28
+dead_circumflex 0x1a
+dead_circumflex 0x1a shift
+dead_cedilla 0x1b
+dead_diaeresis 0x1b shift
+exclam 0x2 shift
+quotedbl 0x3 shift
+comma 0x33
+apostrophe 0x33 shift
+period 0x34 shift
+slash 0x4 shift
+dollar 0x5 shift
+percent 0x6 shift
+question 0x7 shift
+ampersand 0x8 shift
+asterisk 0x9 shift
+parenleft 0xa shift
+parenright 0xb shift
+underscore 0xc shift
+plus 0xd shift
diff --git a/src/VBox/RDP/client/keymaps/fr-ch b/src/VBox/RDP/client/keymaps/fr-ch
new file mode 100644
index 000000000..7b7d28cd6
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/fr-ch
@@ -0,0 +1,169 @@
+# rdesktop suisse-french keymap file
+#
+#map 0x00000807
+map 0x0000100C
+include common
+#
+# Scan Code 1
+section 0x29
+degree 0x29 shift
+notsign 0x29 altgr inhibit
+#
+# Scan Code 2
+plus 0x2 shift
+brokenbar 0x02 altgr
+#
+# Scan Code 3
+quotedbl 0x03 shift
+at 0x03 altgr
+#
+# Scan Code 4
+asterisk 0x04 shift
+numbersign 0x04 altgr
+#
+# Scan Code 5
+ccedilla 0x05 shift
+onequarter 0x05 altgr inhibit
+#
+# Scan Code 6
+percent 0x06 shift
+onehalf 0x06 altgr inhibit
+#
+# Scan Code 7
+ampersand 0x07 shift
+notsign 0x07 altgr
+#
+# Scan Code 8
+slash 0x08 shift
+bar 0x08 altgr
+#
+# Scan Code 9
+parenleft 0x09 shift
+cent 0x09 altgr
+#
+# Scan Code 10
+parenright 0x0a shift
+#
+# Scan Code 11
+equal 0x0b shift
+braceright 0x0b altgr inhibit
+#
+# Scan Code 12
+apostrophe 0x0c
+question 0x0c shift
+dead_acute 0x0c altgr
+#
+# Scan Code 13
+dead_circumflex 0x0d
+dead_grave 0x0d shift
+dead_tilde 0x0d altgr
+#
+# Scan Code 19
+EuroSign 0x12 altgr
+#
+# Scan Code 22
+z 0x15 addupper
+#
+# Scan Code 27
+udiaeresis 0x1a shift
+egrave 0x1a
+bracketleft 0x1a altgr
+#
+# Scan Code 28
+dead_diaeresis 0x1b
+exclam 0x1b shift
+bracketright 0x1b altgr
+#
+# Scan Code 40
+odiaeresis 0x27 shift
+eacute 0x27
+#
+# Scan Code 41
+adiaeresis 0x28 shift
+agrave 0x28
+braceleft 0x28 altgr
+#
+# Scan Code 42 (only on international keyboards)
+dollar 0x2b
+sterling 0x2b shift
+braceright 0x2b altgr
+#
+# Scan Code 45 (only on international keyboards)
+backslash 0x56 altgr
+#
+# Scan Code 46
+y 0x2c addupper
+#
+# Scan Code 53
+comma 0x33
+semicolon 0x33 shift
+#
+# Scan Code 54
+period 0x34
+colon 0x34 shift
+#
+# Scan Code 55
+minus 0x35
+underscore 0x35 shift
+#
+# Suppress Windows unsupported AltGr keys
+#
+# Scan Code 17
+paragraph 0x10 altgr inhibit
+#
+# Scan Code 21
+tslash 0x14 altgr inhibit
+#
+# Scan Code 22
+leftarrow 0x15 altgr inhibit
+#
+# Scan Code 23
+downarrow 0x16 altgr inhibit
+#
+# Scan Code 24
+rightarrow 0x17 altgr inhibit
+#
+# Scan Code 25
+oslash 0x18 altgr inhibit
+#
+# Scan Code 26
+thorn 0x19 altgr inhibit
+#
+# Scan Code 31
+ae 0x1e altgr inhibit
+#
+# Scan Code 32
+ssharp 0x1f altgr inhibit
+#
+# Scan Code 33
+eth 0x20 altgr inhibit
+#
+# Scan Code 34
+dstroke 0x21 altgr inhibit
+#
+# Scan Code 35
+eng 0x22 altgr inhibit
+#
+# Scan Code 36
+hstroke 0x23 altgr inhibit
+#
+# Scan Code 38
+kra 0x25 altgr inhibit
+#
+# Scan Code 39
+lstroke 0x26 altgr inhibit
+#
+# Scan Code 46
+guillemotleft 0x2c altgr inhibit
+#
+# Scan Code 47
+guillemotright 0x2d altgr inhibit
+#
+# Scan Code 49
+leftdoublequotemark 0x2f altgr inhibit
+#
+# Scan Code 50
+rightdoublequotemark 0x30 altgr inhibit
+#
+# Scan Code 52
+mu 0x32 altgr inhibit
diff --git a/src/VBox/RDP/client/keymaps/he b/src/VBox/RDP/client/keymaps/he
new file mode 100644
index 000000000..7e282887b
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/he
@@ -0,0 +1,91 @@
+# Generated by Shlomil
+# Please send your comments and corrections to <shlomister@gmail.com>
+include common
+map 0x040D
+
+
+#
+# Top row
+#
+
+slash 0x10 altgr
+apostrophe 0x11 altgr
+hebrew_qoph 0x12 altgr
+hebrew_resh 0x13 altgr
+hebrew_aleph 0x14 altgr
+hebrew_tet 0x15 altgr
+hebrew_waw 0x16 altgr
+hebrew_finalnun 0x17 altgr
+hebrew_finalmem 0x18 altgr
+hebrew_pe 0x19 altgr
+
+#
+# Second row
+#
+
+hebrew_shin 0x1e altgr
+hebrew_dalet 0x1f altgr
+hebrew_gimel 0x20 altgr
+hebrew_kaph 0x21 altgr
+hebrew_ayin 0x22 altgr
+hebrew_yod 0x23 altgr
+hebrew_chet 0x24 altgr
+hebrew_lamed 0x25 altgr
+hebrew_finalkaph 0x26 altgr
+hebrew_finalpe 0x27 altgr
+comma 0x28 altgr
+
+#
+# Third row
+#
+
+hebrew_zain 0x2c altgr
+hebrew_samech 0x2d altgr
+hebrew_bet 0x2e altgr
+hebrew_he 0x2f altgr
+hebrew_nun 0x30 altgr
+hebrew_mem 0x31 altgr
+hebrew_zade 0x32 altgr
+
+hebrew_taw 0x33 altgr
+hebrew_finalzade 0x34 altgr
+period 0x35 altgr
+
+
+#
+# en-us
+#
+
+
+exclam 0x02 shift
+at 0x03 shift
+numbersign 0x04 shift
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+bracketleft 0x1a
+braceleft 0x1a shift
+bracketright 0x1b
+braceright 0x1b shift
+semicolon 0x27
+colon 0x27 shift
+apostrophe 0x28
+quotedbl 0x28 shift
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+slash 0x35
+question 0x35 shift
diff --git a/src/VBox/RDP/client/keymaps/hr b/src/VBox/RDP/client/keymaps/hr
new file mode 100644
index 000000000..613aa6925
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/hr
@@ -0,0 +1,125 @@
+# generated from XKB map hr
+include common
+map 0x41a
+exclam 0x02 shift
+asciitilde 0x02 altgr
+dead_tilde 0x02 shift altgr
+quotedbl 0x03 shift
+dead_caron 0x03 altgr
+caron 0x03 shift altgr
+numbersign 0x04 shift
+asciicircum 0x04 altgr
+dead_circumflex 0x04 shift altgr
+dollar 0x05 shift
+dead_breve 0x05 altgr
+breve 0x05 shift altgr
+percent 0x06 shift
+degree 0x06 altgr
+dead_abovering 0x06 shift altgr
+ampersand 0x07 shift
+dead_ogonek 0x07 altgr
+ogonek 0x07 shift altgr
+slash 0x08 shift
+grave 0x08 altgr
+dead_grave 0x08 shift altgr
+parenleft 0x09 shift
+dead_abovedot 0x09 altgr
+abovedot 0x09 shift altgr
+parenright 0x0a shift
+dead_acute 0x0a altgr
+apostrophe 0x0a shift altgr
+equal 0x0b shift
+dead_doubleacute 0x0b altgr
+doubleacute 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+dead_diaeresis 0x0c altgr
+diaeresis 0x0c shift altgr
+plus 0x0d
+asterisk 0x0d shift
+dead_cedilla 0x0d altgr
+cedilla 0x0d shift altgr
+backslash 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+bar 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+scaron 0x1a
+Scaron 0x1a shift
+division 0x1a altgr
+dead_abovering 0x1a shift altgr
+dstroke 0x1b
+Dstroke 0x1b shift
+multiply 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+bracketleft 0x21 altgr
+ordfeminine 0x21 shift altgr
+bracketright 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+lstroke 0x25 altgr
+ampersand 0x25 shift altgr
+Lstroke 0x26 altgr
+ccaron 0x27
+Ccaron 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+cacute 0x28
+Cacute 0x28 shift
+ssharp 0x28 altgr
+dead_caron 0x28 shift altgr
+dead_cedilla 0x29
+dead_diaeresis 0x29 shift
+notsign 0x29 altgr
+zcaron 0x2b
+Zcaron 0x2b shift
+currency 0x2b altgr
+dead_breve 0x2b shift altgr
+y 0x2c addupper
+guillemotleft 0x2c altgr
+less 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+at 0x2f altgr
+grave 0x2f shift altgr
+braceleft 0x30 altgr
+apostrophe 0x30 shift altgr
+braceright 0x31 altgr
+section 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/src/VBox/RDP/client/keymaps/hu b/src/VBox/RDP/client/keymaps/hu
new file mode 100644
index 000000000..8aba44441
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/hu
@@ -0,0 +1,115 @@
+# Hungarian keyboard layout (QWERTZ)
+# Created by: The NeverGone <never@delfin.klte.hu>
+
+include common
+map 0x40e
+
+
+# AltGr keys:
+notsign 0x29 altgr
+asciitilde 0x02 altgr
+caron 0x03 altgr
+asciicircum 0x04 altgr
+breve 0x05 altgr
+degree 0x06 altgr
+ogonek 0x07 altgr
+grave 0x08 altgr
+abovedot 0x09 altgr
+acute 0x0a altgr
+doubleacute 0x0b altgr
+diaeresis 0x0c altgr
+cedilla 0x0d altgr
+backslash 0x10 altgr
+bar 0x11 altgr
+EuroSign 0x12 altgr
+Iacute 0x17 altgr
+division 0x1a altgr
+multiply 0x1b altgr
+dstroke 0x1f altgr
+Dstroke 0x20 altgr
+bracketleft 0x21 altgr
+bracketright 0x22 altgr
+iacute 0x24 altgr
+lstroke 0x25 altgr
+Lstroke 0x26 altgr
+dollar 0x27 altgr
+ssharp 0x28 altgr
+currency 0x2b altgr
+less 0x56 altgr
+greater 0x2c altgr
+numbersign 0x2d altgr
+ampersand 0x2e altgr
+at 0x2f altgr
+braceleft 0x30 altgr
+braceright 0x31 altgr
+semicolon 0x33 altgr
+asterisk 0x35 altgr
+
+
+# Shift keys:
+section 0x29 shift
+apostrophe 0x02 shift
+quotedbl 0x03 shift
+plus 0x04 shift
+exclam 0x05 shift
+percent 0x06 shift
+slash 0x07 shift
+equal 0x08 shift
+parenleft 0x09 shift
+parenright 0x0a shift
+Odiaeresis 0x0b shift
+Udiaeresis 0x0c shift
+Oacute 0x0d shift
+Z 0x15 shift
+Odoubleacute 0x1a shift
+Uacute 0x1b shift
+Eacute 0x27 shift
+Aacute 0x28 shift
+Udoubleacute 0x2b shift
+Y 0x2c shift
+question 0x33 shift
+colon 0x34 shift
+underscore 0x35 shift
+F13 0x3b shift
+F14 0x3c shift
+F15 0x3d shift
+F16 0x3e shift
+F17 0x3f shift
+F18 0x40 shift
+F19 0x41 shift
+F20 0x42 shift
+F21 0x43 shift
+F22 0x44 shift
+F23 0x57 shift
+F24 0x58 shift
+
+
+# Ctrl keys:
+F25 0x3b ctrl
+F26 0x3c ctrl
+F27 0x3d ctrl
+F28 0x3e ctrl
+F29 0x3f ctrl
+F30 0x40 ctrl
+F31 0x41 ctrl
+F32 0x42 ctrl
+F33 0x43 ctrl
+F34 0x44 ctrl
+F35 0x57 ctrl
+#NoSymbol 0x58 ctrl
+
+
+0 0x29
+odiaeresis 0x0b
+udiaeresis 0x0c
+oacute 0x0d
+z 0x15
+odoubleacute 0x1a
+uacute 0x1b
+eacute 0x27
+aacute 0x28
+udoubleacute 0x2b
+y 0x2c
+comma 0x33
+period 0x34
+minus 0x35
diff --git a/src/VBox/RDP/client/keymaps/is b/src/VBox/RDP/client/keymaps/is
new file mode 100644
index 000000000..eee01979b
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/is
@@ -0,0 +1,140 @@
+# 2004-03-16 Halldór Guðmundsson and Morten Lange
+# Keyboard definition file for the Icelandic keyboard
+# to be used in rdesktop 1.3.x ( See rdesktop.org)
+# generated from XKB map de, and changed manually
+# Location for example /usr/local/share/rdesktop/keymaps/is
+include common
+map 0x40f
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+#section 0x04 shift
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+currency 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+#ssharp 0x0c
+odiaeresis 0x0c
+#question 0x0c shift
+Odiaeresis 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+#acute 0x0d
+minus 0x0d
+#dead_acute 0x0d
+#grave 0x0d shift
+#dead_grave 0x0d shift
+underscore 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+#z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+#thorn 0x19 altgr
+#THORN 0x19 shift altgr
+#udiaeresis 0x1a
+#Udiaeresis 0x1a shift
+#dead_diaeresis 0x1a altgr
+#dead_abovering 0x1a shift altgr
+eth 0x1a
+ETH 0x1a shift
+apostrophe 0x1b
+question 0x1b shift
+#plus 0x1b
+#asterisk 0x1b shift
+asciitilde 0x1b altgr
+#grave 0x1b altgr
+#dead_tilde 0x1b altgr
+#dead_macron 0x1b shift altgr
+#ae 0x1e altgr
+#AE 0x1e shift altgr
+#eth 0x20 altgr
+#eth 0x20
+#ETH 0x20 shift altgr
+#ETH 0x20 shift
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+#adiaeresis 0x27
+#Adiaeresis 0x27 shift
+ae 0x27
+AE 0x27 shift
+dead_doubleacute 0x27 altgr
+#adiaeresis 0x28
+#Adiaeresis 0x28 shift
+#dead_caron 0x28 shift altgr
+#asciicircum 0x29
+acute 0x28
+dead_acute 0x28
+#dead_circumflex 0x29
+#degree 0x29 shift
+#notsign 0x29 altgr
+plus 0x2b
+asterisk 0x2b shift
+grave 0x2b altgr
+#numbersign 0x2b
+#apostrophe 0x2b shift
+#dead_breve 0x2b shift altgr
+#y 0x2c addupper
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+#minus 0x35
+#underscore 0x35 shift
+thorn 0x35
+THORN 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
+
diff --git a/src/VBox/RDP/client/keymaps/it b/src/VBox/RDP/client/keymaps/it
new file mode 100644
index 000000000..00ca73a3e
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/it
@@ -0,0 +1,115 @@
+# generated from XKB map it
+include common
+map 0x410
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+sterling 0x04 shift
+threesuperior 0x04 altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+trademark 0x09 shift altgr
+parenright 0x0a shift
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+grave 0x0c altgr
+questiondown 0x0c shift altgr
+igrave 0x0d
+asciicircum 0x0d shift
+asciitilde 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+egrave 0x1a
+eacute 0x1a shift
+bracketleft 0x1a altgr
+dead_abovering 0x1a shift altgr
+plus 0x1b
+asterisk 0x1b shift
+bracketright 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+ograve 0x27
+ccedilla 0x27 shift
+at 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+agrave 0x28
+degree 0x28 shift
+numbersign 0x28 altgr
+backslash 0x29
+bar 0x29 shift
+notsign 0x29 altgr
+ugrave 0x2b
+section 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/src/VBox/RDP/client/keymaps/ja b/src/VBox/RDP/client/keymaps/ja
new file mode 100644
index 000000000..532b111b5
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/ja
@@ -0,0 +1,119 @@
+# generated from XKB map jp106
+# See OADG Technical reference for official scancodes:
+# http://www.oadg.or.jp/tosho/index.htm#techref
+include common
+map 0xe0010411
+keyboard_type 0x7
+keyboard_subtype 0x2
+keyboard_functionkeys 0xc
+exclam 0x02 shift
+kana_NU 0x02 altgr
+quotedbl 0x03 shift
+kana_FU 0x03 altgr
+numbersign 0x04 shift
+kana_A 0x04 altgr
+kana_a 0x04 shift altgr
+dollar 0x05 shift
+kana_U 0x05 altgr
+kana_u 0x05 shift altgr
+percent 0x06 shift
+kana_E 0x06 altgr
+kana_e 0x06 shift altgr
+ampersand 0x07 shift
+kana_O 0x07 altgr
+kana_o 0x07 shift altgr
+apostrophe 0x08 shift
+kana_YA 0x08 altgr
+kana_ya 0x08 shift altgr
+parenleft 0x09 shift
+kana_YU 0x09 altgr
+kana_yu 0x09 shift altgr
+parenright 0x0a shift
+kana_YO 0x0a altgr
+kana_yo 0x0a shift altgr
+asciitilde 0x0b shift
+kana_WA 0x0b altgr
+kana_WO 0x0b shift altgr
+minus 0x0c
+equal 0x0c shift
+kana_HO 0x0c altgr
+asciicircum 0x0d
+asciitilde 0x0d shift
+kana_HE 0x0d altgr
+kana_TA 0x10 altgr
+kana_TE 0x11 altgr
+kana_I 0x12 altgr
+kana_i 0x12 shift altgr
+kana_SU 0x13 altgr
+kana_KA 0x14 altgr
+kana_N 0x15 altgr
+kana_NA 0x16 altgr
+kana_NI 0x17 altgr
+kana_RA 0x18 altgr
+kana_SE 0x19 altgr
+at 0x1a
+grave 0x1a shift
+voicedsound 0x1a altgr
+bracketleft 0x1b
+braceleft 0x1b shift
+semivoicedsound 0x1b altgr
+kana_openingbracket 0x1b shift altgr
+kana_CHI 0x1e altgr
+kana_TO 0x1f altgr
+kana_SHI 0x20 altgr
+kana_HA 0x21 altgr
+kana_KI 0x22 altgr
+kana_KU 0x23 altgr
+kana_MA 0x24 altgr
+kana_NO 0x25 altgr
+kana_RI 0x26 altgr
+semicolon 0x27
+plus 0x27 shift
+kana_RE 0x27 altgr
+colon 0x28
+asterisk 0x28 shift
+kana_KE 0x28 altgr
+Zenkaku_Hankaku 0x29
+Kanji 0x29
+bracketright 0x2b
+braceright 0x2b shift
+kana_MU 0x2b altgr
+kana_closingbracket 0x2b shift altgr
+kana_TSU 0x2c altgr
+kana_tsu 0x2c shift altgr
+kana_SA 0x2d altgr
+kana_SO 0x2e altgr
+kana_HI 0x2f altgr
+kana_KO 0x30 altgr
+kana_MI 0x31 altgr
+kana_MO 0x32 altgr
+comma 0x33
+less 0x33 shift
+kana_NE 0x33 altgr
+kana_comma 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+kana_RU 0x34 altgr
+kana_fullstop 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+kana_ME 0x35 altgr
+kana_conjunctive 0x35 shift altgr
+Execute 0x54 shift
+backslash 0x73
+bar 0x7d shift
+underscore 0x73 shift
+Henkan_Mode 0x79
+Hiragana_Katakana 0x70 localstate
+Katakana 0x70
+Romaji 0x70
+Muhenkan 0x7b
+# Plain [Eisu_toggle/Caps_Lock] should NOT have shift
+Eisu_toggle 0x3a
+# [Eisu_toggle/Caps_Lock] key will generate Caps_Lock keysym
+# only with shift+capslock stroke. Windows also expect this, so prefix a shift
+Caps_Lock 0x3a shift
+# Windows,Menu
+F13 0xdc
+Menu 0xdd
+#todo: Alt_R+Romaji doesnt romaji the IME (Alt_L+Romaji works)
diff --git a/src/VBox/RDP/client/keymaps/ko b/src/VBox/RDP/client/keymaps/ko
new file mode 100644
index 000000000..89e92a509
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/ko
@@ -0,0 +1,37 @@
+# generated from XKB map ko
+include common
+map 0xe0010412
+exclam 0x02 shift
+at 0x03 shift
+numbersign 0x04 shift
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+bracketleft 0x1a
+braceleft 0x1a shift
+bracketright 0x1b
+braceright 0x1b shift
+semicolon 0x27
+colon 0x27 shift
+apostrophe 0x28
+quotedbl 0x28 shift
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+slash 0x35
+question 0x35 shift
+Hangul 0xf2
+Hangul_Hanja 0xf1
diff --git a/src/VBox/RDP/client/keymaps/lt b/src/VBox/RDP/client/keymaps/lt
new file mode 100644
index 000000000..3d9d619ea
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/lt
@@ -0,0 +1,57 @@
+# generated from XKB map lt
+include common
+map 0x427
+exclam 0x02 shift
+aogonek 0x02 altgr
+Aogonek 0x02 shift altgr
+at 0x03 shift
+ccaron 0x03 altgr
+Ccaron 0x03 shift altgr
+numbersign 0x04 shift
+eogonek 0x04 altgr
+Eogonek 0x04 shift altgr
+dollar 0x05 shift
+eabovedot 0x05 altgr
+Eabovedot 0x05 shift altgr
+percent 0x06 shift
+iogonek 0x06 altgr
+Iogonek 0x06 shift altgr
+asciicircum 0x07 shift
+scaron 0x07 altgr
+Scaron 0x07 shift altgr
+ampersand 0x08 shift
+uogonek 0x08 altgr
+Uogonek 0x08 shift altgr
+asterisk 0x09 shift
+umacron 0x09 altgr
+Umacron 0x09 shift altgr
+parenleft 0x0a shift
+doublelowquotemark 0x0a altgr
+parenright 0x0b shift
+leftdoublequotemark 0x0b altgr
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+zcaron 0x0d altgr
+Zcaron 0x0d shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+bracketright 0x1b
+braceright 0x1b shift
+semicolon 0x27
+colon 0x27 shift
+apostrophe 0x28
+quotedbl 0x28 shift
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+slash 0x35
+question 0x35 shift
+endash 0x56
+EuroSign 0x56 shift
diff --git a/src/VBox/RDP/client/keymaps/lv b/src/VBox/RDP/client/keymaps/lv
new file mode 100644
index 000000000..1d9172791
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/lv
@@ -0,0 +1,128 @@
+# generated from XKB map lv
+include common
+map 0x426
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+at 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+EuroSign 0x05 altgr
+cent 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+asciicircum 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+ampersand 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+asterisk 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenleft 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+parenright 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+minus 0x0c
+underscore 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+equal 0x0d
+plus 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+emacron 0x12 altgr
+Emacron 0x12 shift altgr
+rcedilla 0x13 altgr
+Rcedilla 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+umacron 0x16 altgr
+Umacron 0x16 shift altgr
+imacron 0x17 altgr
+Imacron 0x17 shift altgr
+omacron 0x18 altgr
+Omacron 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ISO_Next_Group 0x1c shift
+amacron 0x1e altgr
+Amacron 0x1e shift altgr
+scaron 0x1f altgr
+Scaron 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+gcedilla 0x22 altgr
+Gcedilla 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kcedilla 0x25 altgr
+Kcedilla 0x25 shift altgr
+lcedilla 0x26 altgr
+Lcedilla 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+leftdoublequotemark 0x28 altgr
+doublelowquotemark 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+notsign 0x29 altgr
+backslash 0x2b
+bar 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+zcaron 0x2c altgr
+Zcaron 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+ccaron 0x2e altgr
+Ccaron 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+apostrophe 0x30 shift altgr
+ncedilla 0x31 altgr
+Ncedilla 0x31 shift altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
+nobreakspace 0x39 altgr
diff --git a/src/VBox/RDP/client/keymaps/mk b/src/VBox/RDP/client/keymaps/mk
new file mode 100644
index 000000000..18c150484
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/mk
@@ -0,0 +1,101 @@
+# generated from XKB map mk
+include common
+map 0x42f
+exclam 0x02 shift
+at 0x03 shift
+doublelowquotemark 0x03 shift altgr
+numbersign 0x04 shift
+leftdoublequotemark 0x04 shift altgr
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+Cyrillic_lje 0x10 altgr
+Cyrillic_LJE 0x10 shift altgr
+Cyrillic_nje 0x11 altgr
+Cyrillic_NJE 0x11 shift altgr
+Cyrillic_ie 0x12 altgr
+Cyrillic_IE 0x12 shift altgr
+Cyrillic_er 0x13 altgr
+Cyrillic_ER 0x13 shift altgr
+Cyrillic_te 0x14 altgr
+Cyrillic_TE 0x14 shift altgr
+Macedonia_dse 0x15 altgr
+Macedonia_DSE 0x15 shift altgr
+Cyrillic_u 0x16 altgr
+Cyrillic_U 0x16 shift altgr
+Cyrillic_i 0x17 altgr
+Cyrillic_I 0x17 shift altgr
+Cyrillic_o 0x18 altgr
+Cyrillic_O 0x18 shift altgr
+Cyrillic_pe 0x19 altgr
+Cyrillic_PE 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+Cyrillic_sha 0x1a altgr
+Cyrillic_SHA 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+Macedonia_gje 0x1b altgr
+Macedonia_GJE 0x1b shift altgr
+Cyrillic_a 0x1e altgr
+Cyrillic_A 0x1e shift altgr
+Cyrillic_es 0x1f altgr
+Cyrillic_ES 0x1f shift altgr
+Cyrillic_de 0x20 altgr
+Cyrillic_DE 0x20 shift altgr
+Cyrillic_ef 0x21 altgr
+Cyrillic_EF 0x21 shift altgr
+Cyrillic_ghe 0x22 altgr
+Cyrillic_GHE 0x22 shift altgr
+Cyrillic_ha 0x23 altgr
+Cyrillic_HA 0x23 shift altgr
+Cyrillic_je 0x24 altgr
+Cyrillic_JE 0x24 shift altgr
+Cyrillic_ka 0x25 altgr
+Cyrillic_KA 0x25 shift altgr
+Cyrillic_el 0x26 altgr
+Cyrillic_EL 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+Cyrillic_che 0x27 altgr
+Cyrillic_CHE 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+Macedonia_kje 0x28 altgr
+Macedonia_KJE 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+Cyrillic_zhe 0x2b altgr
+Cyrillic_ZHE 0x2b shift altgr
+Cyrillic_ze 0x2c altgr
+Cyrillic_ZE 0x2c shift altgr
+Cyrillic_dzhe 0x2d altgr
+Cyrillic_DZHE 0x2d shift altgr
+Cyrillic_tse 0x2e altgr
+Cyrillic_TSE 0x2e shift altgr
+Cyrillic_ve 0x2f altgr
+Cyrillic_VE 0x2f shift altgr
+Cyrillic_be 0x30 altgr
+Cyrillic_BE 0x30 shift altgr
+Cyrillic_en 0x31 altgr
+Cyrillic_EN 0x31 shift altgr
+Cyrillic_em 0x32 altgr
+Cyrillic_EM 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+semicolon 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+colon 0x34 shift altgr
+slash 0x35
+question 0x35 shift
diff --git a/src/VBox/RDP/client/keymaps/modifiers b/src/VBox/RDP/client/keymaps/modifiers
new file mode 100644
index 000000000..c81d9fdef
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/modifiers
@@ -0,0 +1,18 @@
+Shift_R 0x36
+Shift_L 0x2a
+
+Alt_R 0xb8
+Mode_switch 0xb8
+ISO_Level3_Shift 0xb8
+
+Alt_L 0x38
+
+Control_R 0x9d
+Control_L 0x1d
+
+# Translate Meta, Super and Hyper to Windows keys.
+# This is hardcoded. See documentation for details.
+
+# Translate Menu to the Windows Application key.
+# This one does not work either.
+Menu 0xdd
diff --git a/src/VBox/RDP/client/keymaps/nl b/src/VBox/RDP/client/keymaps/nl
new file mode 100644
index 000000000..bc823bd2f
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/nl
@@ -0,0 +1,60 @@
+# Dutch (Netherlands)
+include common
+map 0x413
+
+exclam 0x02 shift
+onesuperior 0x02 altgr
+quotebl 0x03 shift
+twosuperior 0x03 altgr
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+underscore 0x08 shift
+sterling 0x08 altgr
+parenleft 0x09 shift
+braceleft 0x09 altgr
+parenright 0x0a shift
+braceright 0x0a altgr
+apostrophe 0x0b shift
+slash 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+degree 0x0d
+dead_tilde 0x0d shift
+dead_cedilla 0x0d altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+dead_diaeresis 0x1a
+dead_circumflex 0x1a shift
+asterisk 0x1b
+bar 0x1b shift
+ssharp 0x1f altgr
+plus 0x27
+plusminus 0x27 shift
+dead_acute 0x28
+dead_grave 0x28 shift
+at 0x29
+section 0x29 shift
+notsign 0x29 altgr
+less 0x2b
+greater 0x2b shift
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+copyright 0x2e altgr
+mu 0x32 altgr
+comma 0x33
+semicolon 0x33 shift
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+hyphen 0x35
+equal 0x35 shift
+bracketright 0x56
+bracketleft 0x56 shift
+brokenbar 0x56 altgr
+
diff --git a/src/VBox/RDP/client/keymaps/nl-be b/src/VBox/RDP/client/keymaps/nl-be
new file mode 100644
index 000000000..28bbafa41
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/nl-be
@@ -0,0 +1,142 @@
+# Dutch (Belgium)
+map 0x813
+include common
+ampersand 0x02
+1 0x02 shift
+bar 0x02 altgr
+exclamdown 0x02 shift altgr
+eacute 0x03
+2 0x03 shift
+at 0x03 altgr
+oneeighth 0x03 shift altgr
+quotedbl 0x04
+3 0x04 shift
+numbersign 0x04 altgr
+sterling 0x04 shift altgr
+apostrophe 0x05
+4 0x05 shift
+onequarter 0x05 altgr
+dollar 0x05 shift altgr
+parenleft 0x06
+5 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+section 0x07
+6 0x07 shift
+asciicircum 0x07 altgr
+fiveeighths 0x07 shift altgr
+egrave 0x08
+7 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+exclam 0x09
+8 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+ccedilla 0x0a
+9 0x0a shift
+braceleft 0x0a altgr
+plusminus 0x0a shift altgr
+agrave 0x0b
+0 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+parenright 0x0c
+degree 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+minus 0x0d
+underscore 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+a 0x10 addupper
+# at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+z 0x11 addupper
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+dead_circumflex 0x1a
+dead_diaeresis 0x1a shift
+bracketleft 0x1a altgr
+dead_abovering 0x1a shift altgr
+dollar 0x1b
+asterisk 0x1b shift
+bracketright 0x1b altgr
+dead_macron 0x1b shift altgr
+q 0x1e addupper
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+# ampersand 0x25 shift altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+m 0x27 addupper
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+ugrave 0x28
+percent 0x28 shift
+dead_acute 0x28 altgr
+dead_caron 0x28 shift altgr
+twosuperior 0x29
+threesuperior 0x29 shift
+notsign 0x29 altgr
+mu 0x2b
+sterling 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+w 0x2c addupper
+guillemotleft 0x2c altgr
+less 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+# apostrophe 0x30 shift altgr
+comma 0x32
+question 0x32 shift
+dead_cedilla 0x32 altgr
+masculine 0x32 shift altgr
+semicolon 0x33
+period 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+colon 0x34
+slash 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+equal 0x35
+plus 0x35 shift
+dead_tilde 0x35 altgr
+dead_abovedot 0x35 shift altgr
+backslash 0x56 altgr
+less 0x56
+greater 0x56 shift
diff --git a/src/VBox/RDP/client/keymaps/no b/src/VBox/RDP/client/keymaps/no
new file mode 100644
index 000000000..40a64790d
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/no
@@ -0,0 +1,119 @@
+# generated from XKB map no
+include common
+map 0x414
+exclam 0x02 shift
+exclamdown 0x02 altgr
+onesuperior 0x02 shift altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+twosuperior 0x03 shift altgr
+numbersign 0x04 shift
+sterling 0x04 altgr
+threesuperior 0x04 shift altgr
+currency 0x05 shift
+dollar 0x05 altgr
+onequarter 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+cent 0x06 shift altgr
+ampersand 0x07 shift
+yen 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+division 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+guillemotleft 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+guillemotright 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+plus 0x0c
+question 0x0c shift
+plusminus 0x0c altgr
+questiondown 0x0c shift altgr
+backslash 0x0d
+dead_grave 0x0d shift
+dead_acute 0x0d altgr
+notsign 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+registered 0x13 altgr
+thorn 0x14 altgr
+THORN 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oe 0x18 altgr
+OE 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+aring 0x1a
+Aring 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+dead_diaeresis 0x1b
+dead_circumflex 0x1b shift
+asciicircum 0x01b shift
+dead_tilde 0x1b altgr
+asciitilde 0x1b altgr
+dead_caron 0x1b shift altgr
+ordfeminine 0x1e altgr
+masculine 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+oslash 0x27
+Ooblique 0x27 shift
+dead_doubleacute 0x27 shift altgr
+ae 0x28
+AE 0x28 shift
+dead_caron 0x28 shift altgr
+bar 0x29
+section 0x29 shift
+brokenbar 0x29 altgr
+paragraph 0x29 shift altgr
+apostrophe 0x2b
+asterisk 0x2b shift
+multiply 0x2b shift altgr
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+copyright 0x2e altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+dead_cedilla 0x33 altgr
+dead_ogonek 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+dead_abovedot 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+hyphen 0x35 altgr
+macron 0x35 shift altgr
+nobreakspace 0x39 altgr
+onehalf 0x56 altgr
+threequarters 0x56 shift altgr
diff --git a/src/VBox/RDP/client/keymaps/pl b/src/VBox/RDP/client/keymaps/pl
new file mode 100644
index 000000000..09c600d35
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/pl
@@ -0,0 +1,122 @@
+# generated from XKB map pl
+include common
+map 0x415
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+at 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+asciicircum 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+ampersand 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+asterisk 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenleft 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+parenright 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+minus 0x0c
+underscore 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+equal 0x0d
+plus 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+eogonek 0x12 altgr
+Eogonek 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+EuroSign 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oacute 0x18 altgr
+Oacute 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+aogonek 0x1e altgr
+Aogonek 0x1e shift altgr
+sacute 0x1f altgr
+Sacute 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+dead_circumflex 0x28 altgr
+dead_caron 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+notsign 0x29 altgr
+backslash 0x2b
+bar 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+zabovedot 0x2c altgr
+Zabovedot 0x2c shift altgr
+zacute 0x2d altgr
+Zacute 0x2d shift altgr
+cacute 0x2e altgr
+Cacute 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+nacute 0x31 altgr
+Nacute 0x31 shift altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/src/VBox/RDP/client/keymaps/pt b/src/VBox/RDP/client/keymaps/pt
new file mode 100644
index 000000000..c6941f651
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/pt
@@ -0,0 +1,113 @@
+# generated from XKB map pt
+include common
+map 0x816
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+oneeighth 0x03 shift altgr
+numbersign 0x04 shift
+sterling 0x04 altgr
+dollar 0x05 shift
+section 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+guillemotleft 0x0d
+guillemotright 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+plus 0x1a
+asterisk 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+dead_acute 0x1b
+dead_grave 0x1b shift
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+ccedilla 0x27
+Ccedilla 0x27 shift
+dead_doubleacute 0x27 shift altgr
+masculine 0x28
+ordfeminine 0x28 shift
+dead_circumflex 0x28 altgr
+dead_caron 0x28 shift altgr
+backslash 0x29
+bar 0x29 shift
+notsign 0x29 altgr
+dead_tilde 0x2b
+dead_circumflex 0x2b shift
+dead_breve 0x2b shift altgr
+less 0x56
+greater 0x56 shift
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/src/VBox/RDP/client/keymaps/pt-br b/src/VBox/RDP/client/keymaps/pt-br
new file mode 100644
index 000000000..54bafc5dc
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/pt-br
@@ -0,0 +1,69 @@
+# generated from XKB map br
+include common
+map 0x416
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+at 0x03 shift
+twosuperior 0x03 altgr
+onehalf 0x03 shift altgr
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+threequarters 0x04 shift altgr
+dollar 0x05 shift
+sterling 0x05 altgr
+onequarter 0x05 shift altgr
+percent 0x06 shift
+cent 0x06 altgr
+dead_diaeresis 0x07 shift
+notsign 0x07 altgr
+diaeresis 0x07 shift altgr
+ampersand 0x08 shift
+braceleft 0x08 altgr
+asterisk 0x09 shift
+bracketleft 0x09 altgr
+parenleft 0x0a shift
+bracketright 0x0a altgr
+parenright 0x0b shift
+braceright 0x0b altgr
+minus 0x0c
+underscore 0x0c shift
+backslash 0x0c altgr
+equal 0x0d
+plus 0x0d shift
+section 0x0d altgr
+EuroSign 0x12 altgr
+registered 0x13 altgr
+dead_acute 0x1a
+dead_grave 0x1a shift
+acute 0x1a altgr
+grave 0x1a shift altgr
+bracketleft 0x1b
+braceleft 0x1b shift
+ordfeminine 0x1b altgr
+ccedilla 0x27
+Ccedilla 0x27 shift
+dead_tilde 0x28
+dead_circumflex 0x28 shift
+asciitilde 0x28 altgr
+asciicircum 0x28 shift altgr
+apostrophe 0x29
+quotedbl 0x29 shift
+bracketright 0x2b
+braceright 0x2b shift
+masculine 0x2b altgr
+copyright 0x2e altgr
+mu 0x32 altgr
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+semicolon 0x35
+colon 0x35 shift
+comma 0x53 numlock
+backslash 0x56
+bar 0x56 shift
+slash 0x73
+question 0x73 shift
+degree 0x73 altgr
+KP_Decimal 0x34
diff --git a/src/VBox/RDP/client/keymaps/ru b/src/VBox/RDP/client/keymaps/ru
new file mode 100644
index 000000000..b3e7d24de
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/ru
@@ -0,0 +1,109 @@
+# generated from XKB map ru
+include common
+map 0x419
+exclam 0x02 shift
+at 0x03 shift
+quotedbl 0x03 shift altgr
+numbersign 0x04 shift
+dollar 0x05 shift
+asterisk 0x05 shift altgr
+percent 0x06 shift
+colon 0x06 shift altgr
+asciicircum 0x07 shift
+comma 0x07 shift altgr
+ampersand 0x08 shift
+period 0x08 shift altgr
+asterisk 0x09 shift
+semicolon 0x09 shift altgr
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+Cyrillic_shorti 0x10 altgr
+Cyrillic_SHORTI 0x10 shift altgr
+Cyrillic_tse 0x11 altgr
+Cyrillic_TSE 0x11 shift altgr
+Cyrillic_u 0x12 altgr
+Cyrillic_U 0x12 shift altgr
+Cyrillic_ka 0x13 altgr
+Cyrillic_KA 0x13 shift altgr
+Cyrillic_ie 0x14 altgr
+Cyrillic_IE 0x14 shift altgr
+Cyrillic_en 0x15 altgr
+Cyrillic_EN 0x15 shift altgr
+Cyrillic_ghe 0x16 altgr
+Cyrillic_GHE 0x16 shift altgr
+Cyrillic_sha 0x17 altgr
+Cyrillic_SHA 0x17 shift altgr
+Cyrillic_shcha 0x18 altgr
+Cyrillic_SHCHA 0x18 shift altgr
+Cyrillic_ze 0x19 altgr
+Cyrillic_ZE 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+Cyrillic_ha 0x1a altgr
+Cyrillic_HA 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+Cyrillic_hardsign 0x1b altgr
+Cyrillic_HARDSIGN 0x1b shift altgr
+Cyrillic_ef 0x1e altgr
+Cyrillic_EF 0x1e shift altgr
+Cyrillic_yeru 0x1f altgr
+Cyrillic_YERU 0x1f shift altgr
+Cyrillic_ve 0x20 altgr
+Cyrillic_VE 0x20 shift altgr
+Cyrillic_a 0x21 altgr
+Cyrillic_A 0x21 shift altgr
+Cyrillic_pe 0x22 altgr
+Cyrillic_PE 0x22 shift altgr
+Cyrillic_er 0x23 altgr
+Cyrillic_ER 0x23 shift altgr
+Cyrillic_o 0x24 altgr
+Cyrillic_O 0x24 shift altgr
+Cyrillic_el 0x25 altgr
+Cyrillic_EL 0x25 shift altgr
+Cyrillic_de 0x26 altgr
+Cyrillic_DE 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+Cyrillic_zhe 0x27 altgr
+Cyrillic_ZHE 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+Cyrillic_e 0x28 altgr
+Cyrillic_E 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+Cyrillic_io 0x29 altgr
+Cyrillic_IO 0x29 shift altgr
+backslash 0x2b
+bar 0x2b shift
+Cyrillic_ya 0x2c altgr
+Cyrillic_YA 0x2c shift altgr
+Cyrillic_che 0x2d altgr
+Cyrillic_CHE 0x2d shift altgr
+Cyrillic_es 0x2e altgr
+Cyrillic_ES 0x2e shift altgr
+Cyrillic_em 0x2f altgr
+Cyrillic_EM 0x2f shift altgr
+Cyrillic_i 0x30 altgr
+Cyrillic_I 0x30 shift altgr
+Cyrillic_te 0x31 altgr
+Cyrillic_TE 0x31 shift altgr
+Cyrillic_softsign 0x32 altgr
+Cyrillic_SOFTSIGN 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+Cyrillic_be 0x33 altgr
+Cyrillic_BE 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+Cyrillic_yu 0x34 altgr
+Cyrillic_YU 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+slash 0x56 altgr
+bar 0x56 shift altgr
diff --git a/src/VBox/RDP/client/keymaps/sl b/src/VBox/RDP/client/keymaps/sl
new file mode 100644
index 000000000..56835a92c
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/sl
@@ -0,0 +1,110 @@
+# generated from XKB map sl
+include common
+map 0x424
+exclam 0x02 shift
+asciitilde 0x02 altgr
+dead_tilde 0x02 shift altgr
+quotedbl 0x03 shift
+dead_caron 0x03 altgr
+caron 0x03 shift altgr
+numbersign 0x04 shift
+asciicircum 0x04 altgr
+dead_circumflex 0x04 shift altgr
+dollar 0x05 shift
+dead_breve 0x05 altgr
+breve 0x05 shift altgr
+percent 0x06 shift
+degree 0x06 altgr
+dead_abovering 0x06 shift altgr
+ampersand 0x07 shift
+dead_ogonek 0x07 altgr
+ogonek 0x07 shift altgr
+slash 0x08 shift
+grave 0x08 altgr
+dead_grave 0x08 shift altgr
+parenleft 0x09 shift
+dead_abovedot 0x09 altgr
+abovedot 0x09 shift altgr
+parenright 0x0a shift
+dead_acute 0x0a altgr
+equal 0x0b shift
+dead_doubleacute 0x0b altgr
+doubleacute 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+dead_diaeresis 0x0c altgr
+diaeresis 0x0c shift altgr
+plus 0x0d
+asterisk 0x0d shift
+dead_cedilla 0x0d altgr
+cedilla 0x0d shift altgr
+backslash 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+bar 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+scaron 0x1a
+Scaron 0x1a shift
+division 0x1a altgr
+dstroke 0x1b
+Dstroke 0x1b shift
+multiply 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+bracketleft 0x21 altgr
+ordfeminine 0x21 shift altgr
+bracketright 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+lstroke 0x25 altgr
+Lstroke 0x26 altgr
+ccaron 0x27
+Ccaron 0x27 shift
+cacute 0x28
+Cacute 0x28 shift
+ssharp 0x28 altgr
+dead_cedilla 0x29
+notsign 0x29 altgr
+zcaron 0x2b
+Zcaron 0x2b shift
+currency 0x2b altgr
+y 0x2c addupper
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+at 0x2f altgr
+braceleft 0x30 altgr
+braceright 0x31 altgr
+section 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
diff --git a/src/VBox/RDP/client/keymaps/sv b/src/VBox/RDP/client/keymaps/sv
new file mode 100644
index 000000000..0c6571f37
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/sv
@@ -0,0 +1,80 @@
+map 0x0000041d
+include common
+
+#
+# Top row
+#
+section 0x29
+onehalf 0x29 shift
+
+# 1
+exclam 0x2 shift
+
+# 2
+quotedbl 0x3 shift
+at 0x3 altgr
+
+# 3
+numbersign 0x4 shift
+sterling 0x4 altgr
+# 4
+currency 0x5 shift
+dollar 0x5 altgr
+# 5
+percent 0x6 shift
+# 6
+ampersand 0x7 shift
+# 7
+slash 0x8 shift
+braceleft 0x8 altgr
+# 8
+parenleft 0x9 shift
+bracketleft 0x9 altgr
+# 9
+parenright 0xa shift
+bracketright 0xa altgr
+# 0
+equal 0xb shift
+braceright 0xb altgr
+
+plus 0xc
+question 0xc shift
+backslash 0xc altgr
+
+dead_acute 0xd
+dead_grave 0xd shift
+
+#
+# QWERTY first row
+#
+EuroSign 0x12 altgr
+aring 0x1a
+Aring 0x1a shift
+dead_diaeresis 0x1b
+dead_circumflex 0x1b shift
+dead_tilde 0x1b altgr
+
+#
+# QWERTY second row
+#
+odiaeresis 0x27
+Odiaeresis 0x27 shift
+adiaeresis 0x28
+Adiaeresis 0x28 shift
+apostrophe 0x2b
+asterisk 0x2b shift
+
+#
+# QWERTY third row
+#
+less 0x56
+greater 0x56 shift
+bar 0x56 altgr
+mu 0x32 altgr
+comma 0x33
+semicolon 0x33 shift
+period 0x34
+colon 0x34 shift
+minus 0x35
+underscore 0x35 shift
+
diff --git a/src/VBox/RDP/client/keymaps/th b/src/VBox/RDP/client/keymaps/th
new file mode 100644
index 000000000..b65b6da5d
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/th
@@ -0,0 +1,131 @@
+# generated from XKB map th
+include common
+map 0x41e
+exclam 0x02 shift
+Thai_lakkhangyao 0x02 altgr
+plus 0x02 shift altgr
+at 0x03 shift
+slash 0x03 altgr
+Thai_leknung 0x03 shift altgr
+numbersign 0x04 shift
+minus 0x04 altgr
+Thai_leksong 0x04 shift altgr
+dollar 0x05 shift
+Thai_phosamphao 0x05 altgr
+Thai_leksam 0x05 shift altgr
+percent 0x06 shift
+Thai_thothung 0x06 altgr
+Thai_leksi 0x06 shift altgr
+asciicircum 0x07 shift
+Thai_sarau 0x07 altgr
+Thai_sarauu 0x07 shift altgr
+ampersand 0x08 shift
+Thai_saraue 0x08 altgr
+Thai_baht 0x08 shift altgr
+asterisk 0x09 shift
+Thai_khokhwai 0x09 altgr
+Thai_lekha 0x09 shift altgr
+parenleft 0x0a shift
+Thai_totao 0x0a altgr
+Thai_lekhok 0x0a shift altgr
+parenright 0x0b shift
+Thai_chochan 0x0b altgr
+Thai_lekchet 0x0b shift altgr
+minus 0x0c
+underscore 0x0c shift
+Thai_khokhai 0x0c altgr
+Thai_lekpaet 0x0c shift altgr
+equal 0x0d
+plus 0x0d shift
+Thai_chochang 0x0d altgr
+Thai_lekkao 0x0d shift altgr
+Thai_maiyamok 0x10 altgr
+Thai_leksun 0x10 shift altgr
+Thai_saraaimaimalai 0x11 altgr
+quotedbl 0x11 shift altgr
+Thai_saraam 0x12 altgr
+Thai_dochada 0x12 shift altgr
+Thai_phophan 0x13 altgr
+Thai_thonangmontho 0x13 shift altgr
+Thai_saraa 0x14 altgr
+Thai_thothong 0x14 shift altgr
+Thai_maihanakat 0x15 altgr
+Thai_nikhahit 0x15 shift altgr
+Thai_saraii 0x16 altgr
+Thai_maitri 0x16 shift altgr
+Thai_rorua 0x17 altgr
+Thai_nonen 0x17 shift altgr
+Thai_nonu 0x18 altgr
+Thai_paiyannoi 0x18 shift altgr
+Thai_yoyak 0x19 altgr
+Thai_yoying 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+Thai_bobaimai 0x1a altgr
+Thai_thothan 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+Thai_loling 0x1b altgr
+comma 0x1b shift altgr
+Thai_fofan 0x1e altgr
+Thai_ru 0x1e shift altgr
+Thai_hohip 0x1f altgr
+Thai_khorakhang 0x1f shift altgr
+Thai_kokai 0x20 altgr
+Thai_topatak 0x20 shift altgr
+Thai_dodek 0x21 altgr
+Thai_sarao 0x21 shift altgr
+Thai_sarae 0x22 altgr
+Thai_chochoe 0x22 shift altgr
+Thai_maitho 0x23 altgr
+Thai_maitaikhu 0x23 shift altgr
+Thai_maiek 0x24 altgr
+Thai_maichattawa 0x24 shift altgr
+Thai_saraaa 0x25 altgr
+Thai_sorusi 0x25 shift altgr
+Thai_sosua 0x26 altgr
+Thai_sosala 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+Thai_wowaen 0x27 altgr
+Thai_soso 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+Thai_ngongu 0x28 altgr
+period 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+underscore 0x29 altgr
+percent 0x29 shift altgr
+ISO_First_Group 0x2a shift
+backslash 0x2b
+bar 0x2b shift
+Thai_khokhuat 0x2b altgr
+Thai_khokhon 0x2b shift altgr
+Thai_phophung 0x2c altgr
+parenleft 0x2c shift altgr
+Thai_popla 0x2d altgr
+parenright 0x2d shift altgr
+Thai_saraae 0x2e altgr
+Thai_choching 0x2e shift altgr
+Thai_oang 0x2f altgr
+Thai_honokhuk 0x2f shift altgr
+Thai_sarai 0x30 altgr
+Thai_phinthu 0x30 shift altgr
+Thai_sarauee 0x31 altgr
+Thai_thanthakhat 0x31 shift altgr
+Thai_thothahan 0x32 altgr
+question 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+Thai_moma 0x33 altgr
+Thai_thophuthao 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+Thai_saraaimaimuan 0x34 altgr
+Thai_lochula 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+Thai_fofa 0x35 altgr
+Thai_lu 0x35 shift altgr
+ISO_Last_Group 0x36 shift
diff --git a/src/VBox/RDP/client/keymaps/tr b/src/VBox/RDP/client/keymaps/tr
new file mode 100644
index 000000000..16b54c55e
--- /dev/null
+++ b/src/VBox/RDP/client/keymaps/tr
@@ -0,0 +1,138 @@
+# rdesktop Turkish Q Keyboard Layout
+#
+# Modified by Umit Oztosun <umit@liqia.com> 20040328
+#
+# Modified from the original mapping file provided with rdesktop 1.3.1.
+# This version works correctly with the right X settings.
+
+include common
+map 0x41f
+
+# First row
+quotedbl 0x29
+eacute 0x29 shift
+backslash 0x29 altgr
+
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+
+apostrophe 0x03 shift
+sterling 0x03 altgr
+twosuperior 0x03 shift altgr
+
+dead_circumflex 0x04 shift
+numbersign 0x04 altgr
+threesuperior 0x04 shift altgr
+
+plus 0x05 shift
+dollar 0x05 altgr
+onequarter 0x05 shift altgr
+
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+
+ampersand 0x07 shift
+threequarters 0x07 altgr
+
+slash 0x08 shift
+braceleft 0x08 altgr
+
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+
+asterisk 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+
+minus 0x0d
+underscore 0x0d shift
+division 0x0d altgr
+
+at 0x10 altgr
+
+EuroSign 0x12 altgr
+
+trademark 0x14 altgr
+
+ucircumflex 0x16 altgr
+Ucircumflex 0x16 shift altgr
+
+idotless 0x17
+I 0x17 shift
+icircumflex 0x17 altgr
+Icircumflex 0x17 altgr shift
+
+ocircumflex 0x18 altgr
+Ocircumflex 0x18 shift altgr
+
+gbreve 0x1a
+Gbreve 0x1a shift
+
+udiaeresis 0x1b
+Udiaeresis 0x1b shift
+asciitilde 0x1b altgr
+dead_macron 0x1b shift altgr
+
+comma 0x2b
+semicolon 0x2b shift
+grave 0x2b altgr
+dead_grave 0x2b altgr shift
+
+# Second row
+
+acircumflex 0x1e altgr
+Acircumflex 0x1e shift altgr
+
+section 0x1f altgr
+
+ordfeminine 0x21 altgr
+
+scedilla 0x27
+Scedilla 0x27 shift
+acute 0x27 altgr
+dead_acute 0x27 shift altgr
+
+i 0x28
+Iabovedot 0x28 shift
+dead_caron 0x28 shift altgr
+
+less 0x56
+greater 0x56 shift
+bar 0x56 altgr
+brokenbar 0x56 shift altgr
+
+cent 0x2e altgr
+copyright 0x2e shift altgr
+
+leftdoublequotemark 0x2f altgr
+
+rightdoublequotemark 0x30 altgr
+
+mu 0x32 altgr
+masculine 0x32 shift altgr
+
+odiaeresis 0x33
+Odiaeresis 0x33 shift
+multiply 0x33 altgr
+
+ccedilla 0x34
+Ccedilla 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+
+period 0x35
+colon 0x35 shift
+dead_abovedot 0x35 altgr
+dead_abovedot 0x35 shift altgr
+
diff --git a/src/VBox/RDP/client/vrdp/rdpusb.c b/src/VBox/RDP/client/vrdp/rdpusb.c
index b0b1aa22f..028af77d1 100644
--- a/src/VBox/RDP/client/vrdp/rdpusb.c
+++ b/src/VBox/RDP/client/vrdp/rdpusb.c
@@ -887,21 +887,16 @@ rdpusb_check_fds(fd_set * rfds, fd_set * wfds)
RD_BOOL
rdpusb_init(void)
{
- /** @todo re-use the proxy service code */
- if (USBProxyLinuxCheckDeviceRoot("/dev/vboxusb", true))
+ bool fUseUsbfs;
+ if (RT_SUCCESS(USBProxyLinuxChooseMethod(&fUseUsbfs, &g_pcszDevicesRoot)))
{
- g_fUseSysfs = true;
- g_pcszDevicesRoot = "/dev/vboxusb";
+ g_fUseSysfs = !fUseUsbfs;
+ rdpusb_channel =
+ channel_register("vrdpusb", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
+ rdpusb_process);
+ return (rdpusb_channel != NULL);
}
- else
- {
- g_fUseSysfs = false;
- g_pcszDevicesRoot = "/proc/bus/usb";
- }
- rdpusb_channel =
- channel_register("vrdpusb", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
- rdpusb_process);
- return (rdpusb_channel != NULL);
+ return false;
}
void
diff --git a/src/VBox/Resources/darwin/virtualbox-hdd.icns b/src/VBox/Resources/darwin/virtualbox-hdd.icns
new file mode 100644
index 000000000..2b4b38a66
--- /dev/null
+++ b/src/VBox/Resources/darwin/virtualbox-hdd.icns
Binary files differ
diff --git a/src/VBox/Resources/darwin/virtualbox-vdi.icns b/src/VBox/Resources/darwin/virtualbox-vdi.icns
new file mode 100644
index 000000000..98921a470
--- /dev/null
+++ b/src/VBox/Resources/darwin/virtualbox-vdi.icns
Binary files differ
diff --git a/src/VBox/Resources/darwin/virtualbox-vhd.icns b/src/VBox/Resources/darwin/virtualbox-vhd.icns
new file mode 100644
index 000000000..83f7227dd
--- /dev/null
+++ b/src/VBox/Resources/darwin/virtualbox-vhd.icns
Binary files differ
diff --git a/src/VBox/Resources/darwin/virtualbox-vmdk.icns b/src/VBox/Resources/darwin/virtualbox-vmdk.icns
new file mode 100644
index 000000000..0d278f3fc
--- /dev/null
+++ b/src/VBox/Resources/darwin/virtualbox-vmdk.icns
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-128px.png b/src/VBox/Resources/other/virtualbox-hdd-128px.png
new file mode 100644
index 000000000..1ba70c532
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-128px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-16px.png b/src/VBox/Resources/other/virtualbox-hdd-16px.png
new file mode 100644
index 000000000..9c05fdb9d
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-16px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-20px.png b/src/VBox/Resources/other/virtualbox-hdd-20px.png
new file mode 100644
index 000000000..f563cce24
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-20px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-24px.png b/src/VBox/Resources/other/virtualbox-hdd-24px.png
new file mode 100644
index 000000000..efe65fecc
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-24px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-256px.png b/src/VBox/Resources/other/virtualbox-hdd-256px.png
new file mode 100644
index 000000000..e53a2e05e
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-256px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-32px.png b/src/VBox/Resources/other/virtualbox-hdd-32px.png
new file mode 100644
index 000000000..403648bb0
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-32px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-40px.png b/src/VBox/Resources/other/virtualbox-hdd-40px.png
new file mode 100644
index 000000000..5751a056c
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-40px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-48px.png b/src/VBox/Resources/other/virtualbox-hdd-48px.png
new file mode 100644
index 000000000..4d55bfea4
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-48px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-512px.png b/src/VBox/Resources/other/virtualbox-hdd-512px.png
new file mode 100644
index 000000000..83ffca6e2
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-512px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-64px.png b/src/VBox/Resources/other/virtualbox-hdd-64px.png
new file mode 100644
index 000000000..4129c7da5
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-64px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-72px.png b/src/VBox/Resources/other/virtualbox-hdd-72px.png
new file mode 100644
index 000000000..51a2d1286
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-72px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-80px.png b/src/VBox/Resources/other/virtualbox-hdd-80px.png
new file mode 100644
index 000000000..30c925429
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-80px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-hdd-96px.png b/src/VBox/Resources/other/virtualbox-hdd-96px.png
new file mode 100644
index 000000000..75a7d4a94
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-hdd-96px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-128px.png b/src/VBox/Resources/other/virtualbox-vdi-128px.png
new file mode 100644
index 000000000..2224140e0
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-128px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-16px.png b/src/VBox/Resources/other/virtualbox-vdi-16px.png
new file mode 100644
index 000000000..fbf07f02c
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-16px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-20px.png b/src/VBox/Resources/other/virtualbox-vdi-20px.png
new file mode 100644
index 000000000..7e313be1f
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-20px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-24px.png b/src/VBox/Resources/other/virtualbox-vdi-24px.png
new file mode 100644
index 000000000..9c9785013
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-24px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-256px.png b/src/VBox/Resources/other/virtualbox-vdi-256px.png
new file mode 100644
index 000000000..fb7999d5f
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-256px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-32px.png b/src/VBox/Resources/other/virtualbox-vdi-32px.png
new file mode 100644
index 000000000..e3399095f
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-32px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-40px.png b/src/VBox/Resources/other/virtualbox-vdi-40px.png
new file mode 100644
index 000000000..6537cc181
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-40px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-48px.png b/src/VBox/Resources/other/virtualbox-vdi-48px.png
new file mode 100644
index 000000000..f456204b5
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-48px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-512px.png b/src/VBox/Resources/other/virtualbox-vdi-512px.png
new file mode 100644
index 000000000..065ce9e23
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-512px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-64px.png b/src/VBox/Resources/other/virtualbox-vdi-64px.png
new file mode 100644
index 000000000..1221eca34
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-64px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-72px.png b/src/VBox/Resources/other/virtualbox-vdi-72px.png
new file mode 100644
index 000000000..503e02ee1
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-72px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-80px.png b/src/VBox/Resources/other/virtualbox-vdi-80px.png
new file mode 100644
index 000000000..325f905bc
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-80px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vdi-96px.png b/src/VBox/Resources/other/virtualbox-vdi-96px.png
new file mode 100644
index 000000000..ef39644b9
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vdi-96px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-128px.png b/src/VBox/Resources/other/virtualbox-vhd-128px.png
new file mode 100644
index 000000000..ac04cdf3b
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-128px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-16px.png b/src/VBox/Resources/other/virtualbox-vhd-16px.png
new file mode 100644
index 000000000..64234f5c0
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-16px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-20px.png b/src/VBox/Resources/other/virtualbox-vhd-20px.png
new file mode 100644
index 000000000..c644e8da2
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-20px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-24px.png b/src/VBox/Resources/other/virtualbox-vhd-24px.png
new file mode 100644
index 000000000..8583ca530
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-24px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-256px.png b/src/VBox/Resources/other/virtualbox-vhd-256px.png
new file mode 100644
index 000000000..4ffe6a2e6
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-256px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-32px.png b/src/VBox/Resources/other/virtualbox-vhd-32px.png
new file mode 100644
index 000000000..2dc79263d
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-32px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-40px.png b/src/VBox/Resources/other/virtualbox-vhd-40px.png
new file mode 100644
index 000000000..1450b3902
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-40px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-48px.png b/src/VBox/Resources/other/virtualbox-vhd-48px.png
new file mode 100644
index 000000000..263835b52
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-48px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-512px.png b/src/VBox/Resources/other/virtualbox-vhd-512px.png
new file mode 100644
index 000000000..e2b7abfa4
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-512px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-64px.png b/src/VBox/Resources/other/virtualbox-vhd-64px.png
new file mode 100644
index 000000000..58d36a844
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-64px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-72px.png b/src/VBox/Resources/other/virtualbox-vhd-72px.png
new file mode 100644
index 000000000..b13276d2a
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-72px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-80px.png b/src/VBox/Resources/other/virtualbox-vhd-80px.png
new file mode 100644
index 000000000..8caf4ec39
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-80px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vhd-96px.png b/src/VBox/Resources/other/virtualbox-vhd-96px.png
new file mode 100644
index 000000000..ef8426aa3
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vhd-96px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-128px.png b/src/VBox/Resources/other/virtualbox-vmdk-128px.png
new file mode 100644
index 000000000..a168f45d8
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-128px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-16px.png b/src/VBox/Resources/other/virtualbox-vmdk-16px.png
new file mode 100644
index 000000000..d1e80d9c5
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-16px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-20px.png b/src/VBox/Resources/other/virtualbox-vmdk-20px.png
new file mode 100644
index 000000000..e4654370d
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-20px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-24px.png b/src/VBox/Resources/other/virtualbox-vmdk-24px.png
new file mode 100644
index 000000000..43b26c460
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-24px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-256px.png b/src/VBox/Resources/other/virtualbox-vmdk-256px.png
new file mode 100644
index 000000000..750711323
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-256px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-32px.png b/src/VBox/Resources/other/virtualbox-vmdk-32px.png
new file mode 100644
index 000000000..495c965e2
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-32px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-40px.png b/src/VBox/Resources/other/virtualbox-vmdk-40px.png
new file mode 100644
index 000000000..f8533e6cb
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-40px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-48px.png b/src/VBox/Resources/other/virtualbox-vmdk-48px.png
new file mode 100644
index 000000000..f4a3185ce
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-48px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-512px.png b/src/VBox/Resources/other/virtualbox-vmdk-512px.png
new file mode 100644
index 000000000..d9efef6e4
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-512px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-64px.png b/src/VBox/Resources/other/virtualbox-vmdk-64px.png
new file mode 100644
index 000000000..92867fcba
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-64px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-72px.png b/src/VBox/Resources/other/virtualbox-vmdk-72px.png
new file mode 100644
index 000000000..938e03466
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-72px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-80px.png b/src/VBox/Resources/other/virtualbox-vmdk-80px.png
new file mode 100644
index 000000000..931d9ec5a
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-80px.png
Binary files differ
diff --git a/src/VBox/Resources/other/virtualbox-vmdk-96px.png b/src/VBox/Resources/other/virtualbox-vmdk-96px.png
new file mode 100644
index 000000000..eaa20e732
--- /dev/null
+++ b/src/VBox/Resources/other/virtualbox-vmdk-96px.png
Binary files differ
diff --git a/src/VBox/Resources/win/virtualbox-hdd.ico b/src/VBox/Resources/win/virtualbox-hdd.ico
new file mode 100644
index 000000000..c6218c931
--- /dev/null
+++ b/src/VBox/Resources/win/virtualbox-hdd.ico
Binary files differ
diff --git a/src/VBox/Resources/win/virtualbox-vdi.ico b/src/VBox/Resources/win/virtualbox-vdi.ico
new file mode 100644
index 000000000..9e7577710
--- /dev/null
+++ b/src/VBox/Resources/win/virtualbox-vdi.ico
Binary files differ
diff --git a/src/VBox/Resources/win/virtualbox-vhd.ico b/src/VBox/Resources/win/virtualbox-vhd.ico
new file mode 100644
index 000000000..1fb13b8ee
--- /dev/null
+++ b/src/VBox/Resources/win/virtualbox-vhd.ico
Binary files differ
diff --git a/src/VBox/Resources/win/virtualbox-vmdk.ico b/src/VBox/Resources/win/virtualbox-vmdk.ico
new file mode 100644
index 000000000..daabf32f0
--- /dev/null
+++ b/src/VBox/Resources/win/virtualbox-vmdk.ico
Binary files differ
diff --git a/src/VBox/Runtime/.scm-settings b/src/VBox/Runtime/.scm-settings
index 8c5b4f8d4..4d597df34 100644
--- a/src/VBox/Runtime/.scm-settings
+++ b/src/VBox/Runtime/.scm-settings
@@ -1,4 +1,4 @@
-# $Id: .scm-settings $
+# $Id: .scm-settings 32394 2010-09-10 12:13:11Z vboxsync $
## @file
# Source code massager settings for Runtime.
#
diff --git a/src/VBox/Runtime/Doxyfile b/src/VBox/Runtime/Doxyfile
index 2a14b2f10..eb0c1ae46 100644
--- a/src/VBox/Runtime/Doxyfile
+++ b/src/VBox/Runtime/Doxyfile
@@ -192,6 +192,7 @@ ALIASES = \
# Interface method implementation macros.
ALIASES += \
interface_method_impl{2}="Implements \1 method \link \1::\2 \2 \endlink @copydoc \1::\2 "
+ALIASES += \
interface_method_impl{3}="\3. \
\
Implements \1 method \link \1::\2 \2 \endlink @copydoc \1::\2 "
@@ -199,6 +200,7 @@ Implements \1 method \link \1::\2 \2 \endlink @copydoc \1::\2 "
# Callback method implementation macros.
ALIASES += \
callback_method_impl{1}="Implements the callback \link \1 \1 \endlink @copydoc \1 "
+ALIASES += \
callback_method_impl{2}="\2. \
\
Implements the callback \link \1 \1 "
diff --git a/src/VBox/Runtime/Makefile.kmk b/src/VBox/Runtime/Makefile.kmk
index 20fd05443..0bb1ccbe8 100644
--- a/src/VBox/Runtime/Makefile.kmk
+++ b/src/VBox/Runtime/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 38037 2011-07-18 17:31:38Z vboxsync $
## @file
# Sub-Makefile for the IPRT (IPRT).
#
@@ -44,6 +44,7 @@ else ifdef VBOX_ONLY_TESTSUITE
# Only build the testsuite.
#
LIBRARIES += RuntimeGuestR3 RuntimeGuestR3Shared RuntimeR3 RuntimeR0
+ LIBRARIES.solaris += RuntimeR0Stub
LIBRARIES.win += RuntimeR0Stub
else ifdef VBOX_ONLY_DOCS
@@ -58,7 +59,7 @@ else ifdef VBOX_ONLY_EXTPACKS_USE_IMPLIBS
# Build docs only - need just regular R3 runtime.
#
LIBRARIES += RuntimeBldProg
- IMPORT_LIBS += VBoxRTImp
+ LIBRARIES.solaris += RuntimeR0Stub
LIBRARIES.win += RuntimeR0Stub RuntimeRCStub
include $(PATH_SUB_CURRENT)/tools/Makefile.kmk
@@ -73,8 +74,8 @@ else # !VBOX_ONLY_ADDITIONS && !VBOX_ONLY_TESTSUITE && !VBOX_ONLY_DOCS
include $(PATH_SUB_CURRENT)/tools/Makefile.kmk
BLDPROGS += uniread
- IMPORT_LIBS += VBoxRTImp
LIBRARIES += RuntimeR3 RuntimeBldProg RuntimeR0 RuntimeEFCPP RuntimeR3NoCRTGCC
+ LIBRARIES.solaris += RuntimeR0Stub
LIBRARIES.win += RuntimeR0Stub
ifdef VBOX_WITH_RAW_MODE
LIBRARIES += RuntimeRC
@@ -104,6 +105,10 @@ if1of (amd64, $(KBUILD_TARGET_ARCH) $(KBUILD_HOST_ARCH))
endif
+# Always build the import library.
+IMPORT_LIBS += VBoxRTImp
+
+
# Where the generated stuff goes.
IPRT_OUT_DIR := $(PATH_TARGET)/Runtime
BLDDIRS += $(IPRT_OUT_DIR)
@@ -213,9 +218,6 @@ RuntimeR3_DEFS = IN_RT_R3 IN_SUP_R3 LDR_WITH_NATIVE LDR_WITH_ELF32 LDR_
ifdef IPRT_WITH_KSTUFF
RuntimeR3_DEFS += LDR_WITH_KLDR
endif
-ifdef VBOX_MAIN_RELEASE_LOG ## @todo (dmik): temporary, until RTThreadSelf/RTThreadAdopt are properly updated
- RuntimeR3_DEFS += RTCRITSECT_STRICT
-endif
ifdef IPRT_WITH_LZJB
RuntimeR3_DEFS += RTZIP_USE_LZJB
endif
@@ -248,6 +250,7 @@ RuntimeR3_SOURCES = \
common/alloc/heapsimple.cpp \
common/alloc/heapoffset.cpp \
common/alloc/memcache.cpp \
+ common/alloc/memtracker.cpp \
common/checksum/adler32.cpp \
common/checksum/crc32.cpp \
common/checksum/crc64.cpp \
@@ -271,6 +274,10 @@ RuntimeR3_SOURCES = \
common/dbg/dbgmod.cpp \
common/dbg/dbgmodcontainer.cpp \
common/dbg/dbgmodnm.cpp \
+ common/dvm/dvm.cpp \
+ common/dvm/dvmbsdlabel.cpp \
+ common/dvm/dvmgpt.cpp \
+ common/dvm/dvmmbr.cpp \
common/err/errinfo.cpp \
common/err/errmsg.cpp \
common/err/RTErrConvertFromErrno.cpp \
@@ -287,6 +294,8 @@ RuntimeR3_SOURCES = \
common/log/logrelellipsis.cpp \
common/log/logcom.cpp \
common/log/logformat.cpp \
+ common/log/tracebuf.cpp \
+ common/log/tracedefault.cpp \
common/misc/RTAssertMsg1Weak.cpp \
common/misc/RTAssertMsg2.cpp \
common/misc/RTAssertMsg2Add.cpp \
@@ -423,6 +432,7 @@ RuntimeR3_SOURCES = \
generic/critsect-generic.cpp \
generic/env-generic.cpp \
generic/RTDirCreateTemp-generic.cpp \
+ generic/RTDirCreateUniqueNumbered-generic.cpp \
generic/RTEnvDupEx-generic.cpp \
generic/RTFileCopy-generic.cpp \
generic/RTFileQuerySize-generic.cpp \
@@ -456,6 +466,7 @@ RuntimeR3_SOURCES = \
r3/test.cpp \
r3/testi.cpp \
r3/tcp.cpp \
+ r3/udp.cpp \
r3/generic/semspinmutex-r3-generic.cpp
#if1of ($(KBUILD_TARGET_ARCH),amd64 x86)
@@ -519,6 +530,7 @@ RuntimeR3_SOURCES.win = \
generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
generic/RTSemMutexRequest-generic.cpp \
generic/RTSemMutexRequestDebug-generic.cpp \
+ generic/RTThreadSetAffinityToCpu-generic.cpp \
generic/mppresent-generic.cpp \
generic/semrw-$(if-expr defined(VBOX_WITH_LOCKLESS_SEMRW),lockless-,)generic.cpp \
generic/uuid-generic.cpp \
@@ -533,6 +545,7 @@ RuntimeR3_SOURCES.win = \
r3/win/RTSystemQueryTotalRam-win.cpp \
r3/win/alloc-win.cpp \
r3/win/dir-win.cpp \
+ r3/win/errvars-win.cpp \
r3/win/fileio-win.cpp \
r3/win/fs-win.cpp \
r3/win/ldrNative-win.cpp \
@@ -551,6 +564,7 @@ RuntimeR3_SOURCES.win = \
r3/win/symlink-win.cpp \
r3/win/rtFileNativeSetAttributes-win.cpp \
r3/win/thread-win.cpp \
+ r3/win/thread2-win.cpp \
r3/win/time-win.cpp \
r3/win/timer-win.cpp \
r3/win/tls-win.cpp \
@@ -573,6 +587,7 @@ RuntimeR3_SOURCES.linux = \
generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
generic/RTTimeLocalNow-generic.cpp \
generic/RTTimerCreate-generic.cpp \
+ generic/RTThreadSetAffinityToCpu-generic.cpp \
generic/RTUuidCreate-generic.cpp \
generic/mppresent-generic.cpp \
generic/utf16locale-generic.cpp \
@@ -583,6 +598,7 @@ RuntimeR3_SOURCES.linux = \
r3/linux/sched-linux.cpp \
r3/linux/sysfs.cpp \
r3/linux/time-linux.cpp \
+ r3/linux/thread-affinity-linux.cpp \
r3/linux/RTProcIsRunningByName-linux.cpp \
r3/linux/RTSystemQueryDmiString-linux.cpp \
r3/posix/RTFileQueryFsSizes-posix.cpp \
@@ -596,6 +612,7 @@ RuntimeR3_SOURCES.linux = \
r3/posix/rtmempage-exec-mmap-heap-posix.cpp \
r3/posix/dir-posix.cpp \
r3/posix/env-posix.cpp \
+ r3/posix/errvars-posix.cpp \
r3/posix/fileio-posix.cpp \
r3/posix/fileio2-posix.cpp \
r3/posix/filelock-posix.cpp \
@@ -606,6 +623,7 @@ RuntimeR3_SOURCES.linux = \
r3/posix/path-posix.cpp \
r3/posix/path2-posix.cpp \
r3/posix/pathhost-posix.cpp \
+ r3/posix/RTPathUserDocuments-posix.cpp \
r3/posix/pipe-posix.cpp \
r3/posix/poll-posix.cpp \
r3/posix/process-posix.cpp \
@@ -614,6 +632,7 @@ RuntimeR3_SOURCES.linux = \
r3/posix/semrw-posix.cpp \
r3/posix/symlink-posix.cpp \
r3/posix/thread-posix.cpp \
+ r3/posix/thread2-posix.cpp \
r3/posix/timelocal-posix.cpp \
r3/posix/timer-posix.cpp \
r3/posix/tls-posix.cpp \
@@ -651,6 +670,7 @@ RuntimeR3_SOURCES.os2 = \
generic/RTSystemQueryDmiString-generic.cpp \
generic/RTTimeLocalNow-generic.cpp \
generic/RTTimerCreate-generic.cpp \
+ generic/RTThreadSetAffinityToCpu-generic.cpp \
generic/RTUuidCreate-generic.cpp \
generic/mppresent-generic.cpp \
generic/RTSemEventWait-generic.cpp \
@@ -685,6 +705,7 @@ RuntimeR3_SOURCES.os2 = \
r3/posix/rtmempage-exec-mmap-heap-posix.cpp \
r3/posix/dir-posix.cpp \
r3/posix/env-posix.cpp \
+ r3/posix/errvars-posix.cpp \
r3/posix/fileio-posix.cpp \
r3/posix/fileio2-posix.cpp \
r3/posix/fs-posix.cpp \
@@ -694,6 +715,7 @@ RuntimeR3_SOURCES.os2 = \
r3/posix/path-posix.cpp \
r3/posix/path2-posix.cpp \
r3/posix/pathhost-posix.cpp \
+ r3/posix/RTPathUserDocuments-posix.cpp \
r3/posix/process-posix.cpp \
r3/posix/process-creation-posix.cpp \
r3/posix/symlink-posix.cpp \
@@ -710,6 +732,9 @@ RuntimeR3_SOURCES.darwin = \
generic/RTFileMove-generic.cpp \
generic/RTLogWriteDebugger-generic.cpp \
generic/RTProcDaemonize-generic.cpp \
+ generic/RTThreadGetAffinity-stub-generic.cpp \
+ generic/RTThreadSetAffinity-stub-generic.cpp \
+ generic/RTThreadSetAffinityToCpu-generic.cpp \
generic/RTTimeLocalNow-generic.cpp \
generic/RTTimerCreate-generic.cpp \
generic/RTUuidCreate-generic.cpp \
@@ -729,6 +754,7 @@ RuntimeR3_SOURCES.darwin = \
r3/darwin/RTSystemQueryDmiString-darwin.cpp \
r3/darwin/sched-darwin.cpp \
r3/darwin/time-darwin.cpp \
+ r3/darwin/RTPathUserDocuments-darwin.cpp \
r3/posix/RTFileQueryFsSizes-posix.cpp \
r3/posix/RTHandleGetStandard-posix.cpp \
r3/posix/RTMemProtect-posix.cpp \
@@ -738,6 +764,7 @@ RuntimeR3_SOURCES.darwin = \
r3/posix/RTTimeSet-posix.cpp \
r3/posix/dir-posix.cpp \
r3/posix/env-posix.cpp \
+ r3/posix/errvars-posix.cpp \
r3/posix/fileio-posix.cpp \
r3/posix/fileio2-posix.cpp \
r3/posix/fs-posix.cpp \
@@ -757,6 +784,7 @@ RuntimeR3_SOURCES.darwin = \
r3/posix/semmutex-posix.cpp \
r3/posix/symlink-posix.cpp \
r3/posix/thread-posix.cpp \
+ r3/posix/thread2-posix.cpp \
r3/posix/timelocal-posix.cpp \
r3/posix/tls-posix.cpp \
r3/posix/utf8-posix.cpp
@@ -770,6 +798,9 @@ RuntimeR3_SOURCES.freebsd = \
generic/RTSemEventMultiWait-2-ex-generic.cpp \
generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
generic/RTSystemQueryDmiString-generic.cpp \
+ generic/RTThreadGetAffinity-stub-generic.cpp \
+ generic/RTThreadSetAffinity-stub-generic.cpp \
+ generic/RTThreadSetAffinityToCpu-generic.cpp \
generic/RTTimeLocalNow-generic.cpp \
generic/RTTimerCreate-generic.cpp \
generic/RTUuidCreate-generic.cpp \
@@ -793,6 +824,7 @@ RuntimeR3_SOURCES.freebsd = \
r3/posix/RTTimeSet-posix.cpp \
r3/posix/dir-posix.cpp \
r3/posix/env-posix.cpp \
+ r3/posix/errvars-posix.cpp \
r3/posix/fileio-posix.cpp \
r3/posix/fileio2-posix.cpp \
r3/posix/filelock-posix.cpp \
@@ -804,6 +836,7 @@ RuntimeR3_SOURCES.freebsd = \
r3/posix/path-posix.cpp \
r3/posix/path2-posix.cpp \
r3/posix/pathhost-posix.cpp \
+ r3/posix/RTPathUserDocuments-posix.cpp \
r3/posix/pipe-posix.cpp \
r3/posix/poll-posix.cpp \
r3/posix/process-posix.cpp \
@@ -815,6 +848,7 @@ RuntimeR3_SOURCES.freebsd = \
r3/posix/semrw-posix.cpp \
r3/posix/symlink-posix.cpp \
r3/posix/thread-posix.cpp \
+ r3/posix/thread2-posix.cpp \
r3/posix/time-posix.cpp \
r3/posix/timelocal-posix.cpp \
r3/posix/timer-posix.cpp \
@@ -830,6 +864,7 @@ RuntimeR3_SOURCES.solaris = \
generic/RTProcIsRunningByName-generic.cpp \
generic/RTSemEventMultiWait-2-ex-generic.cpp \
generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
+ generic/RTThreadSetAffinityToCpu-generic.cpp \
generic/RTTimeLocalNow-generic.cpp \
generic/RTTimerCreate-generic.cpp \
generic/RTUuidCreate-generic.cpp \
@@ -847,6 +882,7 @@ RuntimeR3_SOURCES.solaris = \
r3/posix/RTTimeSet-posix.cpp \
r3/posix/dir-posix.cpp \
r3/posix/env-posix.cpp \
+ r3/posix/errvars-posix.cpp \
r3/posix/fileio-posix.cpp \
r3/posix/fileio2-posix.cpp \
r3/posix/filelock-posix.cpp \
@@ -858,6 +894,7 @@ RuntimeR3_SOURCES.solaris = \
r3/posix/path-posix.cpp \
r3/posix/path2-posix.cpp \
r3/posix/pathhost-posix.cpp \
+ r3/posix/RTPathUserDocuments-posix.cpp \
r3/posix/pipe-posix.cpp \
r3/posix/poll-posix.cpp \
r3/posix/process-posix.cpp \
@@ -869,13 +906,15 @@ RuntimeR3_SOURCES.solaris = \
r3/posix/semrw-posix.cpp \
r3/posix/symlink-posix.cpp \
r3/posix/thread-posix.cpp \
+ r3/posix/thread2-posix.cpp \
r3/posix/time-posix.cpp \
r3/posix/timelocal-posix.cpp \
r3/posix/timer-posix.cpp \
r3/posix/tls-posix.cpp \
r3/posix/utf8-posix.cpp \
r3/solaris/mp-solaris.cpp \
- r3/solaris/rtProcInitExePath-solaris.cpp
+ r3/solaris/rtProcInitExePath-solaris.cpp \
+ r3/solaris/thread-affinity-solaris.cpp
RuntimeR3_SOURCES.solaris.amd64 = \
r3/solaris/coredumper-solaris.cpp \
r3/solaris/RTSystemQueryDmiString-solaris.cpp
@@ -903,6 +942,7 @@ RuntimeR3L4_INCS = \
$(L4_INCDIR)
RuntimeR3L4_SOURCES = \
+ generic/errvars-generic.cpp \
generic/fs-stubs-generic.cpp \
generic/pathhost-generic.cpp \
generic/RTDirQueryInfo-generic.cpp \
@@ -912,6 +952,9 @@ RuntimeR3L4_SOURCES = \
generic/RTProcDaemonize-generic.cpp \
generic/RTSystemQueryOSInfo-generic.cpp \
generic/RTSystemQueryDmiString-generic.cpp \
+ generic/RTThreadGetAffinity-stub-generic.cpp \
+ generic/RTThreadSetAffinity-stub-generic.cpp \
+ generic/RTThreadSetAffinityToCpu-generic.cpp \
generic/RTTimeLocalNow-generic.cpp \
generic/RTUuidCreate-generic.cpp \
generic/mppresent-generic.cpp \
@@ -946,6 +989,7 @@ RuntimeR3L4_SOURCES = \
r3/posix/ldrNative-posix.cpp \
r3/posix/path-posix.cpp \
r3/posix/path2-posix.cpp \
+ r3/posix/RTPathUserDocuments-posix.cpp \
r3/posix/rand-posix.cpp \
r3/posix/time-posix.cpp \
r3/posix/timelocal-posix.cpp
@@ -1033,7 +1077,7 @@ RuntimeGuestR3Mini_INST := $(INST_ADDITIONS_LIB)
RuntimeGuestR3Mini_SDKS.win := $(RuntimeR3_SDKS.win)
RuntimeGuestR3Mini_DEFS := \
$(filter-out RTCRITSECT_STRICT RT_NO_GIP RT_WITH_ICONV_CACHE, $(RuntimeR3_DEFS)) \
- RT_MINI
+ RT_MINI IN_RT_STATIC RTMEM_NO_WRAP_TO_EF_APIS
RuntimeGuestR3Mini_DEFS.$(KBUILD_TARGET) := $(RuntimeR3_DEFS.$(KBUILD_TARGET))
RuntimeGuestR3Mini_DEFS.$(KBUILD_HOST) := $(RuntimeR3_DEFS.$(KBUILD_HOST))
RuntimeGuestR3Mini_INCS := $(RuntimeR3_INCS)
@@ -1042,7 +1086,6 @@ RuntimeGuestR3Mini_INCS.$(KBUILD_HOST) := $(RuntimeR3_INCS.$(KBUILD_HOST))
RuntimeGuestR3Mini_SOURCES = \
common/alloc/alloc.cpp \
common/err/errmsg.cpp \
- common/err/errmsgxpcom.cpp \
common/err/RTErrConvertFromErrno.cpp \
common/log/logformat.cpp \
common/misc/RTAssertMsg1Weak.cpp \
@@ -1102,6 +1145,7 @@ RuntimeGuestR3Mini_SOURCES = \
generic/critsect-generic.cpp \
generic/pathhost-generic.cpp \
generic/RTAssertShouldPanic-generic.cpp \
+ generic/errvars-generic.cpp \
r3/alloc.cpp \
r3/alloc-ef.cpp \
r3/fileio.cpp \
@@ -1115,7 +1159,9 @@ RuntimeGuestR3Mini_SOURCES.freebsd = \
r3/posix/fileio2-posix.cpp \
r3/posix/path-posix.cpp \
r3/posix/path2-posix.cpp \
- r3/posix/utf8-posix.cpp
+ r3/posix/utf8-posix.cpp \
+ r3/posix/thread2-posix.cpp \
+ common/err/errmsgxpcom.cpp
RuntimeGuestR3Mini_SOURCES.linux = \
r3/posix/RTMemProtect-posix.cpp \
r3/posix/rtmempage-exec-mmap-posix.cpp \
@@ -1125,7 +1171,9 @@ RuntimeGuestR3Mini_SOURCES.linux = \
r3/posix/fileio2-posix.cpp \
r3/posix/path-posix.cpp \
r3/posix/path2-posix.cpp \
- r3/posix/utf8-posix.cpp
+ r3/posix/utf8-posix.cpp \
+ r3/posix/thread2-posix.cpp \
+ common/err/errmsgxpcom.cpp
RuntimeGuestR3Mini_SOURCES.solaris = \
r3/posix/RTMemProtect-posix.cpp \
r3/posix/rtmempage-exec-mmap-posix.cpp \
@@ -1135,12 +1183,15 @@ RuntimeGuestR3Mini_SOURCES.solaris = \
r3/posix/fileio2-posix.cpp \
r3/posix/path-posix.cpp \
r3/posix/path2-posix.cpp \
- r3/posix/utf8-posix.cpp
+ r3/posix/utf8-posix.cpp \
+ r3/posix/thread2-posix.cpp \
+ common/err/errmsgxpcom.cpp
RuntimeGuestR3Mini_SOURCES.win = \
r3/win/alloc-win.cpp \
r3/win/fileio-win.cpp \
r3/win/path-win.cpp \
r3/win/utf8-win.cpp \
+ r3/win/thread2-win.cpp \
win/errmsgwin.cpp \
win/RTErrConvertFromWin32.cpp
@@ -1226,7 +1277,8 @@ ifndef SDK_VBOX_LIBXML2_LIBS
endif
ifndef SDK_VBOX_OPENSSL_LIBS
VBoxRT_LIBS += \
- $(PATH_LIB)/VBox-libcrypto$(VBOX_SUFF_LIB)
+ $(PATH_LIB)/VBox-libcrypto$(VBOX_SUFF_LIB) \
+ $(PATH_LIB)/VBox-libssl$(VBOX_SUFF_LIB)
endif
ifdef IPRT_WITH_LZO
VBoxRT_LIBS += lzo2
@@ -1248,7 +1300,7 @@ endif
VBoxRT_LIBS.win = \
$(PATH_SDK_$(VBOX_WINDDK)_LIB)/vccomsup.lib \
$(PATH_SDK_$(VBOX_WINDDK)_LIB)/wbemuuid.lib
-VBoxRT_LDFLAGS.darwin = -framework IOKit -framework CoreFoundation -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxRT.dylib
+VBoxRT_LDFLAGS.darwin = -framework IOKit -framework CoreFoundation -framework CoreServices -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxRT.dylib
ifdef VBOX_USE_VCC80
VBoxRT_LDFLAGS.win = /MANIFEST
endif
@@ -1299,6 +1351,7 @@ VBoxRT:: VBoxRTDummy
endif # building VBoxRT
endif # linux
+
#
# VBoxRTImp - Import library/hack.
#
@@ -1404,6 +1457,8 @@ RuntimeR0_SOURCES = \
common/log/logrelellipsis.cpp \
common/log/logcom.cpp \
common/log/logformat.cpp \
+ common/log/tracebuf.cpp \
+ common/log/tracedefault.cpp \
common/misc/RTAssertMsg1Weak.cpp \
common/misc/RTAssertMsg2.cpp \
common/misc/RTAssertMsg2Add.cpp \
@@ -1416,6 +1471,7 @@ RuntimeR0_SOURCES = \
common/misc/sanity-c.c \
common/misc/sanity-cpp.cpp \
common/misc/term.cpp \
+ common/path/RTPathFilename.cpp \
common/string/strncmp.cpp \
common/string/strpbrk.cpp \
common/string/RTStrCat.cpp \
@@ -1486,11 +1542,13 @@ RuntimeR0_SOURCES.os2 = \
#
-# RuntimeR0Stub - Ring-0 context startup stub for Windows.
+# RuntimeR0Stub - Ring-0 context startup stub for Windows and Solaris.
#
-RuntimeR0Stub_TEMPLATE = VBoxR0
+RuntimeR0Stub_TEMPLATE = $(if-expr "$(KBUILD_TARGET)" == "solaris",VBOXR0DRV,VBoxR0)
RuntimeR0Stub_SOURCES.win = \
nt/NtProcessStartup-stub.cpp
+RuntimeR0Stub_SOURCES.solaris = \
+ r0drv/solaris/modulestub-r0drv-solaris.c
#
@@ -1526,6 +1584,8 @@ RuntimeR0Drv_SOURCES = \
common/log/logrelellipsis.cpp \
common/log/logcom.cpp \
common/log/logformat.cpp \
+ common/log/tracebuf.cpp \
+ common/log/tracedefault.cpp \
common/misc/RTAssertMsg1Weak.cpp \
common/misc/RTAssertMsg2.cpp \
common/misc/RTAssertMsg2Add.cpp \
@@ -1572,6 +1632,7 @@ RuntimeR0Drv_SOURCES = \
common/string/RTStrNCmp.cpp \
common/string/RTStrNLen.cpp \
common/string/RTStrNLenEx.cpp \
+ common/string/straprintf.cpp \
common/string/strformat.cpp \
common/string/strformatnum.cpp \
common/string/strformatrt.cpp \
@@ -1591,24 +1652,15 @@ RuntimeR0Drv_SOURCES = \
generic/RTSemEventWaitNoResume-2-ex-generic.cpp \
generic/RTSemEventMultiWait-2-ex-generic.cpp \
generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
+ generic/errvars-generic.cpp \
generic/uuid-generic.cpp \
r0drv/alloc-r0drv.cpp \
r0drv/initterm-r0drv.cpp \
r0drv/generic/semspinmutex-r0drv-generic.c \
VBox/log-vbox.cpp \
-## @todo: Linking against RuntimeR0Drv on Linux will result in unresolved external
-## references to several string functions (e.g. strlen). We could include the
-## missing functions here but our own implementations conflict with declarations
-## of some Linux kernels (inline versus not inline, size_t versus unsigned int).
-##
-## The prototypes for the unresolved externals are declared in <linux/string.h>.
-## This file is not included with extern "C" { ... } and therefore the function
-## prototypes are mangled during C++ compilation. That's why we have to provide
-## implementations with mangled function names.
-##
-## bird: Why don't we just extern "C" {} that file then?
RuntimeR0Drv_SOURCES.linux = \
+ common/misc/thread.cpp \
common/string/strpbrk.cpp \
common/err/RTErrConvertToErrno.cpp \
common/err/RTErrConvertFromErrno.cpp \
@@ -1889,6 +1941,8 @@ ifdef VBOX_WITH_RAW_MODE
common/log/logrelellipsis.cpp \
common/log/logcom.cpp \
common/log/logformat.cpp \
+ common/log/tracebuf.cpp \
+ common/log/tracedefault.cpp \
common/misc/RTAssertMsg1Weak.cpp \
common/misc/RTAssertMsg2.cpp \
common/misc/RTAssertMsg2Add.cpp \
@@ -1900,6 +1954,7 @@ ifdef VBOX_WITH_RAW_MODE
common/misc/buildconfig.cpp \
common/misc/sanity-c.c \
common/misc/sanity-cpp.cpp \
+ common/path/RTPathFilename.cpp \
common/string/strformat.cpp \
common/string/strformatnum.cpp \
common/string/strformatrt.cpp \
@@ -1907,6 +1962,8 @@ ifdef VBOX_WITH_RAW_MODE
common/string/strncmp.cpp \
common/string/strpbrk.cpp \
common/string/strprintf.cpp \
+ common/string/RTStrCopy.cpp \
+ common/string/RTStrCopyEx.cpp \
common/table/avllu32.cpp \
common/table/avlou32.cpp \
common/table/avlogcphys.cpp \
@@ -1922,6 +1979,7 @@ ifdef VBOX_WITH_RAW_MODE
common/time/timesup.cpp \
gc/initterm-gc.cpp \
generic/RTAssertShouldPanic-generic.cpp \
+ generic/errvars-generic.cpp \
\
$(RuntimeNoCrt_SOURCES)
@@ -2207,6 +2265,108 @@ test-doxygen::
@echo $(DOXYGEN_OUTPUT_PREV)
@echo $(IPRT_DOXYFILE_INPUT)
+
+#
+# Test mangling.
+#
+if1of ($(LIBRARIES),RuntimeR3 RuntimeR0 RuntimeR0Drv RuntimeRC)
+ test-mangling:: $(IPRT_OUT_DIR)/mangling.run
+ OTHERS += $(IPRT_OUT_DIR)/mangling.run
+ CLEANS += $(IPRT_OUT_DIR)/mangling.run
+ $(IPRT_OUT_DIR)/mangling.run: \
+ $$(RuntimeR3_1_TARGET) \
+ $$(RuntimeR0_1_TARGET) \
+ $$(RuntimeR0Drv_1_TARGET) \
+ $$(RuntimeRC_1_TARGET)
+ if1of ($(KBUILD_TARGET), win os2)
+ $(call MSG_L1,IPRT: skipped mangling test.)
+ else if $(intersects $(KBUILD_TARGET), linux) && "$(VBOX_GCC_fvisibility-hidden)"
+ $(call MSG_L1,IPRT: Testing mangling and visiblity...)
+ rcExit=0; \
+ for fn in ` readelf -Ws $^ \
+ | $(SED) \
+ -e '/^ *[[:digit:]]\+:/!d' \
+ -e 's/^ \+[[:digit:]]\+: \+[[:xdigit:]]\+ \+[[:digit:]]\+ \+//' \
+ -e '/^SECTION/d' \
+ -e '/^FILE/d' \
+ -e 's/^[[:alpha:]]\+ \+//' \
+ -e '/LOCAL/d' \
+ -e 's/^[[:alpha:]]\+ \+//' \
+ -e '/^HIDDEN/d' \
+ -e 's/^[[:alpha:]]\+ \+//' \
+ -e '/^UND/d' \
+ -e 's/^[[:digit:]]\+ \+//' \
+ \
+ -e '/^nocrt_/d' \
+ -e '/^memchr/d' \
+ -e '/^memcmp/d' \
+ -e '/^memcpy/d' \
+ -e '/^mempcpy/d' \
+ -e '/^memmove/d' \
+ -e '/^memset/d' \
+ -e '/^strchr/d' \
+ -e '/^strpbrk/d' \
+ -e '/^_Z7strpbrk/d' \
+ -e '/^strcmp/d' \
+ -e '/^strcpy/d' \
+ -e '/^strlen/d' \
+ -e '/^_Z[[:alpha:]]*[[:digit:]]\+RTC/d' \
+ \
+ -e '/^_ZNSt9bad_allocC1Ev/d' \
+ -e '/^_ZNSt9exceptionC2Ev/d' \
+ \
+ -e '/^_Z[[:digit:]]\+dbus/d' \
+ -e '/^_Z13RTDBusLoadLibv/d' \
+ \
+ -e '/^VBoxHost_/d'\
+ -e '/^VBoxGuest_/d'\
+ | sort -u \
+ `; \
+ do \
+ if $(SED) -ne '/\# *define '"$${fn}"' /q 1' $(PATH_ROOT)/include/iprt/mangling.h; then \
+ echo "mangling.h: Missing # define "$${fn}" RT_MANGLER("$${fn}")"; \
+ rcExit=1;\
+ fi \
+ done; \
+ exit $${rcExit}
+ else
+ $(call MSG_L1,IPRT: Testing mangling...)
+ rcExit=0; \
+ for fn in ` nm $^ \
+ | $(SED) -n \
+ -e 's/^[0-9a-f][0-9a-f]* //' \
+ -e '/^[TUDB] /!d' \
+ -e 's/^. //' \
+ \
+ -e '/^g_cchrt/d'\
+ -e '/^g_frt/d'\
+ -e '/^g_offrt/d'\
+ -e '/^g_pfnrt/d'\
+ -e '/^g_rt/d'\
+ -e '/^g_szrt/d'\
+ -e '/^g_ProcessSelf/d'\
+ -e '/^g_u64ProgramStart/d'\
+ -e '/^g_enmProcessPriority/d'\
+ -e '/^g_hDbgModStrCache/d'\
+ \
+ -e '/^RTDBusLoadLib/d' \
+ \
+ -e '/^RT/p' \
+ -e '/^g_/p' \
+ | sort -u \
+ `; \
+ do \
+ if $(SED) -ne '/\# *define '"$${fn}"' /q 1' $(PATH_ROOT)/include/iprt/mangling.h; then \
+ echo "mangling.h: Missing # define "$${fn}" RT_MANGLER("$${fn}")"; \
+ rcExit=1;\
+ fi \
+ done; \
+ exit $${rcExit}
+ endif
+endif
+ $(QUIET)$(APPEND) -t $@
+
+
#
# Generate the rules (we're the to sub-makefile).
#
diff --git a/src/VBox/Runtime/VBox/RTAssertShouldPanic-vbox.cpp b/src/VBox/Runtime/VBox/RTAssertShouldPanic-vbox.cpp
index 0f4124bd8..603d26d82 100644
--- a/src/VBox/Runtime/VBox/RTAssertShouldPanic-vbox.cpp
+++ b/src/VBox/Runtime/VBox/RTAssertShouldPanic-vbox.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTAssertShouldPanic-vbox.cpp $ */
+/* $Id: RTAssertShouldPanic-vbox.cpp 37233 2011-05-27 13:31:57Z vboxsync $ */
/** @file
* IPRT - Assertions, generic RTAssertShouldPanic.
*/
@@ -30,6 +30,7 @@
*******************************************************************************/
#include <iprt/assert.h>
#include <iprt/env.h>
+#include <iprt/err.h>
#include <iprt/string.h>
/** @def VBOX_RTASSERT_WITH_GDB
@@ -51,15 +52,12 @@
#endif
-RTDECL(bool) RTAssertShouldPanic(void)
+/**
+ * Worker that we can wrap with error variable saving and restoring.
+ */
+static bool rtAssertShouldPanicWorker(void)
{
/*
- * Check if panicing is excluded by the the RTAssert settings first.
- */
- if (!RTAssertMayPanic())
- return false;
-
- /*
* Check for the VBOX_ASSERT variable.
*/
const char *psz = RTEnvGet("VBOX_ASSERT");
@@ -142,3 +140,24 @@ RTDECL(bool) RTAssertShouldPanic(void)
return false;
}
+
+RTDECL(bool) RTAssertShouldPanic(void)
+{
+ /*
+ * Check if panicing is excluded by the the RTAssert settings first.
+ */
+ if (!RTAssertMayPanic())
+ return false;
+
+ /*
+ * Preserve error state variables.
+ */
+ RTERRVARS SavedErrVars;
+ RTErrVarsSave(&SavedErrVars);
+
+ bool fRc = rtAssertShouldPanicWorker();
+
+ RTErrVarsRestore(&SavedErrVars);
+ return fRc;
+}
+
diff --git a/src/VBox/Runtime/VBox/VBoxRTDeps.cpp b/src/VBox/Runtime/VBox/VBoxRTDeps.cpp
index 9437c91b2..d9488dc25 100644
--- a/src/VBox/Runtime/VBox/VBoxRTDeps.cpp
+++ b/src/VBox/Runtime/VBox/VBoxRTDeps.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxRTDeps.cpp $ */
+/* $Id: VBoxRTDeps.cpp 37277 2011-05-31 14:38:12Z vboxsync $ */
/** @file
* IPRT - VBoxRT.dll/so dependencies.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -42,6 +42,7 @@
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/rsa.h>
+#include <openssl/ssl.h>
/*******************************************************************************
@@ -67,6 +68,11 @@ PFNRT g_VBoxRTDeps[] =
(PFNRT)ASMAtomicReadU64,
(PFNRT)ASMAtomicCmpXchgU64,
(PFNRT)RTBldCfgRevision,
+ (PFNRT)SSL_free,
+ (PFNRT)SSL_library_init,
+ (PFNRT)SSL_CTX_free,
+ (PFNRT)SSL_CTX_use_certificate_file,
+ (PFNRT)TLSv1_server_method,
NULL
};
diff --git a/src/VBox/Runtime/VBox/VBoxRTImp.def b/src/VBox/Runtime/VBox/VBoxRTImp.def
index 3b672a047..0630d9651 100644
--- a/src/VBox/Runtime/VBox/VBoxRTImp.def
+++ b/src/VBox/Runtime/VBox/VBoxRTImp.def
@@ -1,4 +1,4 @@
-; $Id: VBoxRTImp.def $
+; $Id: VBoxRTImp.def 35185 2010-12-16 14:10:38Z vboxsync $
;; @file
; VirtualBox Runtime DLL - Stable Interface Definition file.
diff --git a/src/VBox/Runtime/VBox/log-vbox.cpp b/src/VBox/Runtime/VBox/log-vbox.cpp
index ab9007023..039e43e4d 100644
--- a/src/VBox/Runtime/VBox/log-vbox.cpp
+++ b/src/VBox/Runtime/VBox/log-vbox.cpp
@@ -1,4 +1,4 @@
-/* $Id: log-vbox.cpp $ */
+/* $Id: log-vbox.cpp 37217 2011-05-26 08:54:27Z vboxsync $ */
/** @file
* VirtualBox Runtime - Logging configuration.
*/
@@ -461,6 +461,11 @@ RTDECL(PRTLOGGER) RTLogDefaultInit(void)
RTLogFlags(pLogger, "enabled unbuffered");
pLogger->fDestFlags |= RTLOGDEST_DEBUGGER;
# endif
+# if defined(DEBUG_leo) /* Guest ring-0 as well */
+ RTLogGroupSettings(pLogger, "+drv_mouse.e.l.f+drv_miniport.e.l.f+drv_display.e.l.f");
+ RTLogFlags(pLogger, "enabled unbuffered");
+ pLogger->fDestFlags |= RTLOGDEST_DEBUGGER;
+# endif
# if 0 /* vboxdrv logging - ATTENTION: this is what we're referring to guys! Change to '# if 1'. */
RTLogGroupSettings(pLogger, "all=~0 -default.l6.l5.l4.l3");
RTLogFlags(pLogger, "enabled unbuffered tid");
diff --git a/src/VBox/Runtime/VBox/logbackdoor-redirect.cpp b/src/VBox/Runtime/VBox/logbackdoor-redirect.cpp
index 637c4005d..87bbde2bc 100644
--- a/src/VBox/Runtime/VBox/logbackdoor-redirect.cpp
+++ b/src/VBox/Runtime/VBox/logbackdoor-redirect.cpp
@@ -1,4 +1,4 @@
-/* $Id: logbackdoor-redirect.cpp $ */
+/* $Id: logbackdoor-redirect.cpp 36408 2011-03-24 16:25:47Z vboxsync $ */
/** @file
* VirtualBox Runtime - RTLog stubs for the stripped down IPRT used by
* RuntimeGuestR3Shared (X11), output is redirected
diff --git a/src/VBox/Runtime/VBox/logbackdoor.cpp b/src/VBox/Runtime/VBox/logbackdoor.cpp
index 99d4485db..37bb57cbd 100644
--- a/src/VBox/Runtime/VBox/logbackdoor.cpp
+++ b/src/VBox/Runtime/VBox/logbackdoor.cpp
@@ -1,4 +1,4 @@
-/* $Id: logbackdoor.cpp $ */
+/* $Id: logbackdoor.cpp 29250 2010-05-09 17:53:58Z vboxsync $ */
/** @file
* VirtualBox Runtime - Guest Backdoor Logging.
*/
diff --git a/src/VBox/Runtime/common/alloc/alloc.cpp b/src/VBox/Runtime/common/alloc/alloc.cpp
index e4e52c311..ffaff343f 100644
--- a/src/VBox/Runtime/common/alloc/alloc.cpp
+++ b/src/VBox/Runtime/common/alloc/alloc.cpp
@@ -1,4 +1,4 @@
-/* $Id: alloc.cpp $ */
+/* $Id: alloc.cpp 37808 2011-07-07 07:45:50Z vboxsync $ */
/** @file
* IPRT - Memory Allocation.
*/
@@ -28,7 +28,9 @@
/*******************************************************************************
* Header Files *
*******************************************************************************/
-#define RTMEM_NO_WRAP_TO_EF_APIS
+#ifndef RTMEM_NO_WRAP_TO_EF_APIS
+# define RTMEM_NO_WRAP_TO_EF_APIS
+#endif
#include <iprt/mem.h>
#include "internal/iprt.h"
diff --git a/src/VBox/Runtime/common/alloc/heapoffset.cpp b/src/VBox/Runtime/common/alloc/heapoffset.cpp
index 2cd8697a9..fd5d0e96d 100644
--- a/src/VBox/Runtime/common/alloc/heapoffset.cpp
+++ b/src/VBox/Runtime/common/alloc/heapoffset.cpp
@@ -1,4 +1,4 @@
-/* $Id: heapoffset.cpp $ */
+/* $Id: heapoffset.cpp 35525 2011-01-13 14:00:37Z vboxsync $ */
/** @file
* IPRT - An Offset Based Heap.
*/
diff --git a/src/VBox/Runtime/common/alloc/heapsimple.cpp b/src/VBox/Runtime/common/alloc/heapsimple.cpp
index 7e680132d..3377e6597 100644
--- a/src/VBox/Runtime/common/alloc/heapsimple.cpp
+++ b/src/VBox/Runtime/common/alloc/heapsimple.cpp
@@ -1,4 +1,4 @@
-/* $Id: heapsimple.cpp $ */
+/* $Id: heapsimple.cpp 35525 2011-01-13 14:00:37Z vboxsync $ */
/** @file
* IPRT - A Simple Heap.
*/
diff --git a/src/VBox/Runtime/common/alloc/memcache.cpp b/src/VBox/Runtime/common/alloc/memcache.cpp
index f7f41ff65..72349f353 100644
--- a/src/VBox/Runtime/common/alloc/memcache.cpp
+++ b/src/VBox/Runtime/common/alloc/memcache.cpp
@@ -1,4 +1,4 @@
-/* $Id: memcache.cpp $ */
+/* $Id: memcache.cpp 34507 2010-11-30 13:14:14Z vboxsync $ */
/** @file
* IPRT - Memory Object Allocation Cache.
*/
diff --git a/src/VBox/Runtime/common/alloc/memtracker.cpp b/src/VBox/Runtime/common/alloc/memtracker.cpp
index 3abae12b2..61346d98c 100644
--- a/src/VBox/Runtime/common/alloc/memtracker.cpp
+++ b/src/VBox/Runtime/common/alloc/memtracker.cpp
@@ -1,10 +1,10 @@
-/* $Id: memtracker.cpp $ */
+/* $Id: memtracker.cpp 36674 2011-04-14 16:03:06Z vboxsync $ */
/** @file
* IPRT - Memory Tracker & Leak Detector.
*/
/*
- * 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;
@@ -28,12 +28,1310 @@
/*******************************************************************************
* Header Files *
*******************************************************************************/
-#include <iprt/memcache.h>
+#include <iprt/memtracker.h>
#include "internal/iprt.h"
+#include <iprt/asm.h>
#include <iprt/assert.h>
+#include <iprt/avl.h>
+#include <iprt/critsect.h>
+#ifdef IN_RING3
+# include <iprt/file.h>
+#endif
+#include <iprt/err.h>
+#include <iprt/list.h>
+#include <iprt/log.h>
#include <iprt/mem.h>
-#include <iprt/param.h>
+#include <iprt/semaphore.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
+#include "internal/file.h"
#include "internal/magics.h"
+#include "internal/strhash.h"
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/** Pointer to a memory tracker instance */
+typedef struct RTMEMTRACKERINT *PRTMEMTRACKERINT;
+
+/**
+ * Memory tracker statistics.
+ */
+typedef struct RTMEMTRACKERSTATS
+{
+ /** Array of method calls. */
+ uint64_t volatile acMethodCalls[RTMEMTRACKERMETHOD_END];
+ /** The number of times this user freed or reallocated a memory block
+ * orignally allocated by someone else. */
+ uint64_t volatile cUserChanges;
+ /** The total number of bytes allocated ever. */
+ uint64_t volatile cbTotalAllocated;
+ /** The total number of blocks allocated ever. */
+ uint64_t volatile cTotalAllocatedBlocks;
+ /** The number of bytes currently allocated. */
+ size_t volatile cbAllocated;
+ /** The number of blocks currently allocated. */
+ size_t volatile cAllocatedBlocks;
+} RTMEMTRACKERSTATS;
+/** Pointer to memory tracker statistics. */
+typedef RTMEMTRACKERSTATS *PRTMEMTRACKERSTATS;
+
+
+/**
+ * Memory tracker user data.
+ */
+typedef struct RTMEMTRACKERUSER
+{
+ /** Entry in the user list (RTMEMTRACKERINT::UserList). */
+ RTLISTNODE ListEntry;
+ /** Pointer to the tracker. */
+ PRTMEMTRACKERINT pTracker;
+ /** Critical section protecting the memory list. */
+ RTCRITSECT CritSect;
+ /** The list of memory allocated by this user. */
+ RTLISTNODE MemoryList;
+ /** Positive numbers indicates recursion.
+ * Negative numbers are used for the global user since that is shared by
+ * more than one thread. */
+ int32_t volatile cInTracker;
+ /** The user identifier. */
+ uint32_t idUser;
+ /** The statistics for this user. */
+ RTMEMTRACKERSTATS Stats;
+ /** The user (thread) name. */
+ char szName[32];
+} RTMEMTRACKERUSER;
+/** Pointer to memory tracker per user data. */
+typedef RTMEMTRACKERUSER *PRTMEMTRACKERUSER;
+
+
+/**
+ * Memory tracker per tag statistics.
+ */
+typedef struct RTMEMTRACKERTAG
+{
+ /** AVL node core for lookup by hash. */
+ AVLU32NODECORE Core;
+ /** Tag list entry for flat traversal while dumping. */
+ RTLISTNODE ListEntry;
+ /** Pointer to the next tag with the same hash (collisions). */
+ PRTMEMTRACKERTAG pNext;
+ /** The tag statistics. */
+ RTMEMTRACKERSTATS Stats;
+ /** The tag name length. */
+ size_t cchTag;
+ /** The tag string. */
+ char szTag[1];
+} RTMEMTRACKERTAG;
+
+
+/**
+ * The memory tracker instance.
+ */
+typedef struct RTMEMTRACKERINT
+{
+ /** Cross roads semaphore separating dumping and normal operation.
+ * - NS - normal tracking.
+ * - EW - dumping tracking data. */
+ RTSEMXROADS hXRoads;
+
+ /** Critical section protecting the user list and tag database. */
+ RTCRITSECT CritSect;
+ /** List of RTMEMTRACKERUSER records. */
+ RTLISTNODE UserList;
+ /** The next user identifier number. */
+ uint32_t idUserNext;
+ /** The TLS index used for the per thread user records. */
+ RTTLS iTls;
+ /** Cross roads semaphore used to protect the tag database.
+ * - NS - lookup.
+ * - EW + critsect - insertion.
+ * @todo Replaced this by a read-write semaphore. */
+ RTSEMXROADS hXRoadsTagDb;
+ /** The root of the tag lookup database. */
+ AVLU32TREE TagDbRoot;
+ /** List of RTMEMTRACKERTAG records. */
+ RTLISTNODE TagList;
+#if ARCH_BITS == 32
+ /** Alignment padding. */
+ uint32_t u32Alignment;
+#endif
+ /** The global user record (fallback). */
+ RTMEMTRACKERUSER FallbackUser;
+ /** The global statistics. */
+ RTMEMTRACKERSTATS GlobalStats;
+ /** The number of busy (recursive) allocations. */
+ uint64_t volatile cBusyAllocs;
+ /** The number of busy (recursive) frees. */
+ uint64_t volatile cBusyFrees;
+ /** The number of tags. */
+ uint32_t cTags;
+ /** The number of users. */
+ uint32_t cUsers;
+} RTMEMTRACKERINT;
+AssertCompileMemberAlignment(RTMEMTRACKERINT, FallbackUser, 8);
+
+
+/**
+ * Output callback structure.
+ */
+typedef struct RTMEMTRACKEROUTPUT
+{
+ /** The printf like callback. */
+ DECLCALLBACKMEMBER(void, pfnPrintf)(struct RTMEMTRACKEROUTPUT *pThis, const char *pszFormat, ...);
+
+ /** The data. */
+ union
+ {
+ RTFILE hFile;
+ } uData;
+} RTMEMTRACKEROUTPUT;
+/** Pointer to a memory tracker output callback structure. */
+typedef RTMEMTRACKEROUTPUT *PRTMEMTRACKEROUTPUT;
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/** Pointer to the default memory tracker. */
+static PRTMEMTRACKERINT g_pDefaultTracker = NULL;
+
+
+/**
+ * Creates a memory tracker.
+ *
+ * @returns IRPT status code.
+ * @param ppTracker Where to return the tracker instance.
+ */
+static int rtMemTrackerCreate(PRTMEMTRACKERINT *ppTracker)
+{
+ PRTMEMTRACKERINT pTracker = (PRTMEMTRACKERINT)RTMemAllocZ(sizeof(*pTracker));
+ if (!pTracker)
+ return VERR_NO_MEMORY;
+
+ /*
+ * Create locks and stuff.
+ */
+ int rc = RTCritSectInitEx(&pTracker->CritSect,
+ RTCRITSECT_FLAGS_NO_LOCK_VAL | RTCRITSECT_FLAGS_NO_NESTING | RTCRITSECT_FLAGS_BOOTSTRAP_HACK,
+ NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTSemXRoadsCreate(&pTracker->hXRoads);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTSemXRoadsCreate(&pTracker->hXRoadsTagDb);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTTlsAllocEx(&pTracker->iTls, NULL);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTCritSectInitEx(&pTracker->FallbackUser.CritSect,
+ RTCRITSECT_FLAGS_NO_LOCK_VAL | RTCRITSECT_FLAGS_NO_NESTING | RTCRITSECT_FLAGS_BOOTSTRAP_HACK,
+ NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Initialize the rest of the structure.
+ */
+ RTListInit(&pTracker->UserList);
+ RTListInit(&pTracker->TagList);
+ RTListInit(&pTracker->FallbackUser.ListEntry);
+ RTListInit(&pTracker->FallbackUser.MemoryList);
+ pTracker->FallbackUser.pTracker = pTracker;
+ pTracker->FallbackUser.cInTracker = INT32_MIN / 2;
+ pTracker->FallbackUser.idUser = pTracker->idUserNext++;
+ strcpy(pTracker->FallbackUser.szName, "fallback");
+
+ *ppTracker = pTracker;
+ return VINF_SUCCESS;
+ }
+
+ RTTlsFree(pTracker->iTls);
+ }
+ RTSemXRoadsDestroy(pTracker->hXRoadsTagDb);
+ }
+ RTSemXRoadsDestroy(pTracker->hXRoads);
+ }
+ RTCritSectDelete(&pTracker->CritSect);
+ }
+ return rc;
+}
+
+
+/**
+ * Gets the user record to use.
+ *
+ * @returns Pointer to a user record.
+ * @param pTracker The tracker instance.
+ */
+static PRTMEMTRACKERUSER rtMemTrackerGetUser(PRTMEMTRACKERINT pTracker)
+{
+ /* ASSUMES that RTTlsGet and RTTlsSet will not reenter. */
+ PRTMEMTRACKERUSER pUser = (PRTMEMTRACKERUSER)RTTlsGet(pTracker->iTls);
+ if (RT_UNLIKELY(!pUser))
+ {
+ /*
+ * Is the thread currently initializing or terminating?
+ * If so, don't try add any user record for it as RTThread may barf or
+ * we might not get the thread name.
+ */
+ if (!RTThreadIsSelfAlive())
+ return &pTracker->FallbackUser;
+
+ /*
+ * Allocate and initialize a new user record for this thread.
+ *
+ * We install the fallback user record while doing the allocation and
+ * locking so that we can deal with recursions.
+ */
+ int rc = RTTlsSet(pTracker->iTls, &pTracker->FallbackUser);
+ if (RT_SUCCESS(rc))
+ {
+ pUser = (PRTMEMTRACKERUSER)RTMemAllocZ(sizeof(*pUser));
+ if (pUser)
+ {
+ rc = RTCritSectInitEx(&pUser->CritSect,
+ RTCRITSECT_FLAGS_NO_LOCK_VAL | RTCRITSECT_FLAGS_NO_NESTING | RTCRITSECT_FLAGS_BOOTSTRAP_HACK,
+ NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
+ if (RT_SUCCESS(rc))
+ {
+ RTListInit(&pUser->ListEntry);
+ RTListInit(&pUser->MemoryList);
+ pUser->pTracker = pTracker;
+ pUser->cInTracker = 1;
+
+ const char *pszName = RTThreadSelfName();
+ if (pszName)
+ RTStrCopy(pUser->szName, sizeof(pUser->szName), pszName);
+
+ /*
+ * Register the new user record.
+ */
+ rc = RTTlsSet(pTracker->iTls, pUser);
+ if (RT_SUCCESS(rc))
+ {
+ RTCritSectEnter(&pTracker->CritSect);
+
+ pUser->idUser = pTracker->idUserNext++;
+ RTListAppend(&pTracker->UserList, &pUser->ListEntry);
+ pTracker->cUsers++;
+
+ RTCritSectLeave(&pTracker->CritSect);
+ return pUser;
+ }
+
+ RTCritSectDelete(&pUser->CritSect);
+ }
+ RTMemFree(pUser);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ }
+
+ /* Failed, user the fallback. */
+ pUser = &pTracker->FallbackUser;
+ }
+
+ ASMAtomicIncS32(&pUser->cInTracker);
+ return pUser;
+}
+
+
+/**
+ * Counterpart to rtMemTrackerGetUser.
+ *
+ * @param pUser The user record to 'put' back.
+ */
+DECLINLINE(void) rtMemTrackerPutUser(PRTMEMTRACKERUSER pUser)
+{
+ ASMAtomicDecS32(&pUser->cInTracker);
+}
+
+
+/**
+ * Get the tag record corresponding to @a pszTag.
+ *
+ * @returns The tag record. This may be NULL if we're out of memory or
+ * if something goes wrong.
+ *
+ * @param pTracker The tracker instance.
+ * @param pUser The user record of the caller. Must NOT be
+ * NULL. This is used to prevent infinite
+ * recursions when allocating a new tag record.
+ * @param pszTag The tag string. Can be NULL.
+ */
+DECLINLINE(PRTMEMTRACKERTAG) rtMemTrackerGetTag(PRTMEMTRACKERINT pTracker, PRTMEMTRACKERUSER pUser, const char *pszTag)
+{
+ AssertPtr(pTracker);
+ AssertPtr(pUser);
+ if (pUser->cInTracker <= 0)
+ return NULL;
+
+ /*
+ * Hash tag string.
+ */
+ size_t cchTag;
+ uint32_t uHash;
+ if (pszTag)
+ uHash = sdbmN(pszTag, 260, &cchTag);
+ else
+ {
+ pszTag = "";
+ cchTag = 0;
+ uHash = 0;
+ }
+
+ /*
+ * Look up the tag.
+ */
+ RTSemXRoadsNSEnter(pTracker->hXRoadsTagDb);
+ PRTMEMTRACKERTAG pTag = (PRTMEMTRACKERTAG)RTAvlU32Get(&pTracker->TagDbRoot, uHash);
+ while ( pTag
+ && ( pTag->cchTag != cchTag
+ || memcmp(pTag->szTag, pszTag, cchTag)) )
+ pTag = pTag->pNext;
+ RTSemXRoadsNSLeave(pTracker->hXRoadsTagDb);
+
+ /*
+ * Create a new tag record if not found.
+ */
+ if (RT_UNLIKELY(!pTag))
+ {
+ pTag = (PRTMEMTRACKERTAG)RTMemAllocZVar(RT_OFFSETOF(RTMEMTRACKERTAG, szTag[cchTag + 1]));
+ if (pTag)
+ {
+ pTag->Core.Key = uHash;
+ pTag->cchTag = cchTag;
+ memcpy(pTag->szTag, pszTag, cchTag + 1);
+
+ RTSemXRoadsEWEnter(pTracker->hXRoadsTagDb);
+ RTCritSectEnter(&pTracker->CritSect);
+
+ void *pvFreeMe = NULL;
+ PRTMEMTRACKERTAG pHeadTag = (PRTMEMTRACKERTAG)RTAvlU32Get(&pTracker->TagDbRoot, uHash);
+ if (!pHeadTag)
+ {
+ RTAvlU32Insert(&pTracker->TagDbRoot, &pTag->Core);
+ RTListAppend(&pTracker->TagList, &pTag->ListEntry);
+ pTracker->cTags++;
+ }
+ else
+ {
+ PRTMEMTRACKERTAG pTag2 = pHeadTag;
+ while ( pTag2
+ && ( pTag2->cchTag != cchTag
+ || memcmp(pTag2->szTag, pszTag, cchTag)) )
+ pTag2 = pTag2->pNext;
+ if (RT_LIKELY(!pTag2))
+ {
+ pTag->pNext = pHeadTag->pNext;
+ pHeadTag->pNext = pTag;
+ RTListAppend(&pTracker->TagList, &pTag->ListEntry);
+ pTracker->cTags++;
+ }
+ else
+ {
+ pvFreeMe = pTag;
+ pTag = pTag2;
+ }
+ }
+
+ RTCritSectLeave(&pTracker->CritSect);
+ RTSemXRoadsEWLeave(pTracker->hXRoadsTagDb);
+
+ if (RT_LIKELY(pvFreeMe))
+ RTMemFree(pvFreeMe);
+ }
+ }
+
+ return pTag;
+}
+
+
+/**
+ * Counterpart to rtMemTrackerGetTag.
+ *
+ * @param pTag The tag record to 'put' back.
+ */
+DECLINLINE(void) rtMemTrackerPutTag(PRTMEMTRACKERTAG pTag)
+{
+ NOREF(pTag);
+}
+
+
+/**
+ * Record an allocation call.
+ *
+ * @param pStats The statistics record.
+ * @param cbUser The size of the allocation.
+ * @param enmMethod The allocation method.
+ */
+DECLINLINE(void) rtMemTrackerStateRecordAlloc(PRTMEMTRACKERSTATS pStats, size_t cbUser, RTMEMTRACKERMETHOD enmMethod)
+{
+ ASMAtomicAddU64(&pStats->cbTotalAllocated, cbUser);
+ ASMAtomicIncU64(&pStats->cTotalAllocatedBlocks);
+ ASMAtomicAddZ(&pStats->cbAllocated, cbUser);
+ ASMAtomicIncZ(&pStats->cAllocatedBlocks);
+ ASMAtomicIncU64(&pStats->acMethodCalls[enmMethod]);
+}
+
+
+/**
+ * Record a free call.
+ *
+ * @param pStats The statistics record.
+ * @param cbUser The size of the allocation.
+ * @param enmMethod The free method.
+ */
+DECLINLINE(void) rtMemTrackerStateRecordFree(PRTMEMTRACKERSTATS pStats, size_t cbUser, RTMEMTRACKERMETHOD enmMethod)
+{
+ ASMAtomicSubZ(&pStats->cbAllocated, cbUser);
+ ASMAtomicDecZ(&pStats->cAllocatedBlocks);
+ ASMAtomicIncU64(&pStats->acMethodCalls[enmMethod]);
+}
+
+
+/**
+ * Internal RTMemTrackerHdrAlloc and RTMemTrackerHdrAllocEx worker.
+ *
+ * @returns Pointer to the user data allocation.
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param pv The pointer to the allocated memory. This
+ * includes room for the header.
+ * @param cbUser The size requested by the user.
+ * @param pszTag The tag string.
+ * @param enmMethod The allocation method.
+ */
+static void *rtMemTrackerHdrAllocEx(PRTMEMTRACKERINT pTracker, void *pv, size_t cbUser,
+ const char *pszTag, RTMEMTRACKERMETHOD enmMethod)
+{
+ /*
+ * Check input.
+ */
+ if (!pv)
+ return NULL;
+ AssertReturn(enmMethod > RTMEMTRACKERMETHOD_INVALID && enmMethod < RTMEMTRACKERMETHOD_END, NULL);
+
+ /*
+ * Initialize the header.
+ */
+ PRTMEMTRACKERHDR pHdr = (PRTMEMTRACKERHDR)pv;
+
+ pHdr->uMagic = RTMEMTRACKERHDR_MAGIC;
+ pHdr->cbUser = cbUser;
+ RTListInit(&pHdr->ListEntry);
+ pHdr->pUser = NULL;
+ pHdr->pszTag = pszTag;
+ pHdr->pTag = NULL;
+ pHdr->pvUser = pHdr + 1;
+
+ /*
+ * Add it to the tracker if we've got one.
+ */
+ if (pTracker)
+ {
+ PRTMEMTRACKERUSER pUser = rtMemTrackerGetUser(pTracker);
+ if (pUser->cInTracker == 1)
+ {
+ RTSemXRoadsNSEnter(pTracker->hXRoads);
+
+ /* Get the tag and update it's statistics. */
+ PRTMEMTRACKERTAG pTag = rtMemTrackerGetTag(pTracker, pUser, pszTag);
+ if (pTag)
+ {
+ pHdr->pTag = pTag;
+ rtMemTrackerStateRecordAlloc(&pTag->Stats, cbUser, enmMethod);
+ rtMemTrackerPutTag(pTag);
+ }
+
+ /* Link the header and update the user statistics. */
+ RTCritSectEnter(&pUser->CritSect);
+ RTListAppend(&pUser->MemoryList, &pHdr->ListEntry);
+ RTCritSectLeave(&pUser->CritSect);
+
+ pHdr->pUser = pUser;
+ rtMemTrackerStateRecordAlloc(&pUser->Stats, cbUser, enmMethod);
+
+ /* Update the global statistics. */
+ rtMemTrackerStateRecordAlloc(&pTracker->GlobalStats, cbUser, enmMethod);
+
+ RTSemXRoadsNSLeave(pTracker->hXRoads);
+ }
+ else
+ ASMAtomicIncU64(&pTracker->cBusyAllocs);
+ rtMemTrackerPutUser(pUser);
+ }
+
+ return pHdr + 1;
+}
+
+
+/**
+ * Internal worker for rtMemTrackerHdrFreeEx and rtMemTrackerHdrReallocPrep.
+ *
+ * @returns Pointer to the original block.
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param pvUser Pointer to the user memory.
+ * @param cbUser The size of the user memory or 0.
+ * @param pszTag The tag to associate the free with.
+ * @param enmMethod The free method.
+ * @param uDeadMagic The dead magic value to use.
+ */
+static void *rtMemTrackerHdrFreeCommon(PRTMEMTRACKERINT pTracker, void *pvUser, size_t cbUser,
+ const char *pszTag, RTMEMTRACKERMETHOD enmMethod,
+ size_t uDeadMagic)
+{
+ PRTMEMTRACKERHDR pHdr = (PRTMEMTRACKERHDR)pvUser - 1;
+ AssertReturn(pHdr->uMagic == RTMEMTRACKERHDR_MAGIC, NULL);
+ Assert(pHdr->cbUser == cbUser || !cbUser); NOREF(cbUser);
+ Assert(pHdr->pvUser == pvUser);
+
+ AssertReturn(enmMethod > RTMEMTRACKERMETHOD_INVALID && enmMethod < RTMEMTRACKERMETHOD_END, NULL);
+
+ /*
+ * First mark it as free.
+ */
+ pHdr->uMagic = uDeadMagic;
+
+ /*
+ * If there is a association with a user, we need to unlink it and update
+ * the statistics.
+ *
+ * A note on the locking here. We don't take the crossroads semaphore when
+ * reentering the memory tracker on the same thread because we may be
+ * holding it in a different direction and would therefore deadlock.
+ */
+ PRTMEMTRACKERUSER pMemUser = pHdr->pUser;
+ if (pMemUser)
+ {
+ Assert(pMemUser->pTracker == pTracker); Assert(pTracker);
+ PRTMEMTRACKERUSER pCallingUser = rtMemTrackerGetUser(pTracker);
+ bool const fTakeXRoadsLock = pCallingUser->cInTracker <= 1;
+ if (fTakeXRoadsLock)
+ RTSemXRoadsNSEnter(pTracker->hXRoads);
+
+ RTCritSectEnter(&pMemUser->CritSect);
+ RTListNodeRemove(&pHdr->ListEntry);
+ RTCritSectLeave(&pMemUser->CritSect);
+
+ if (pCallingUser == pMemUser)
+ rtMemTrackerStateRecordFree(&pCallingUser->Stats, pHdr->cbUser, enmMethod);
+ else
+ {
+ ASMAtomicIncU64(&pCallingUser->Stats.cUserChanges);
+ ASMAtomicIncU64(&pCallingUser->Stats.acMethodCalls[enmMethod]);
+
+ ASMAtomicSubU64(&pMemUser->Stats.cbTotalAllocated, cbUser);
+ ASMAtomicSubZ(&pMemUser->Stats.cbAllocated, cbUser);
+ }
+
+ rtMemTrackerStateRecordFree(&pTracker->GlobalStats, pHdr->cbUser, enmMethod);
+
+ /** @todo we're currently ignoring pszTag, consider how to correctly
+ * attribute the free operation if the tags differ - it
+ * makes sense at all... */
+ if (pHdr->pTag)
+ rtMemTrackerStateRecordFree(&pHdr->pTag->Stats, pHdr->cbUser, enmMethod);
+
+
+ if (fTakeXRoadsLock)
+ RTSemXRoadsNSLeave(pTracker->hXRoads);
+ rtMemTrackerPutUser(pCallingUser);
+ }
+ else
+ {
+ /*
+ * No tracked. This may happen even when pTracker != NULL when the same
+ * thread reenters the tracker when allocating tracker structures or memory
+ * in some subroutine like threading and locking.
+ */
+ Assert(!pHdr->pTag);
+ if (pTracker)
+ ASMAtomicIncU64(&pTracker->cBusyFrees);
+ }
+
+ return pHdr;
+}
+
+
+/**
+ * Internal worker for RTMemTrackerHdrReallocPrep and
+ * RTMemTrackerHdrReallocPrepEx.
+ *
+ * @returns Pointer to the actual allocation.
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param pvOldUser The user memory.
+ * @param cbOldUser The size of the user memory, 0 if unknown.
+ * @param pszTag The tag string.
+ */
+static void *rtMemTrackerHdrReallocPrepEx(PRTMEMTRACKERINT pTracker, void *pvOldUser, size_t cbOldUser, const char *pszTag)
+{
+ if (!pvOldUser)
+ return NULL;
+ return rtMemTrackerHdrFreeCommon(pTracker, pvOldUser, cbOldUser, pszTag,
+ RTMEMTRACKERMETHOD_REALLOC_PREP, RTMEMTRACKERHDR_MAGIC_REALLOC);
+}
+
+
+/**
+ * Internal worker for RTMemTrackerHdrReallocDone and
+ * RTMemTrackerHdrReallocDoneEx.
+ *
+ * @returns Pointer to the actual allocation.
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param pvNew The new memory chunk. Can be NULL.
+ * @param cbNewUser The size of the new memory chunk.
+ * @param pvOldUser Pointer to the old user memory.
+ * @param pszTag The tag string.
+ */
+static void *rtMemTrackerHdrReallocDoneEx(PRTMEMTRACKERINT pTracker, void *pvNew, size_t cbNewUser,
+ void *pvOldUser, const char *pszTag)
+{
+ /* Succeeded? */
+ if (pvNew)
+ return rtMemTrackerHdrAllocEx(pTracker, pvNew, cbNewUser, pszTag, RTMEMTRACKERMETHOD_REALLOC_DONE);
+
+ /* Failed or just realloc to zero? */
+ if (cbNewUser)
+ {
+ PRTMEMTRACKERHDR pHdr = (PRTMEMTRACKERHDR)pvOldUser - 1;
+ AssertReturn(pHdr->uMagic == RTMEMTRACKERHDR_MAGIC_REALLOC, NULL);
+
+ return rtMemTrackerHdrAllocEx(pTracker, pHdr, pHdr->cbUser, pszTag, RTMEMTRACKERMETHOD_REALLOC_FAILED);
+ }
+
+ /* Tealloc to zero bytes, i.e. free. */
+ return NULL;
+}
+
+
+/**
+ * Internal worker for RTMemTrackerHdrFree and RTMemTrackerHdrFreeEx.
+ *
+ * @returns Pointer to the actual allocation.
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param pvUser The user memory.
+ * @param cbUser The size of the user memory, 0 if unknown.
+ * @param pszTag The tag string.
+ * @param enmMethod The free method.
+ */
+static void *rtMemTrackerHdrFreeEx(PRTMEMTRACKERINT pTracker, void *pvUser, size_t cbUser,
+ const char *pszTag, RTMEMTRACKERMETHOD enmMethod)
+{
+ if (!pvUser)
+ return NULL;
+ return rtMemTrackerHdrFreeCommon(pTracker, pvUser, cbUser, pszTag, enmMethod, RTMEMTRACKERHDR_MAGIC_FREE);
+}
+
+
+/**
+ * Prints a statistics record.
+ *
+ * @param pStats The record.
+ * @param pOutput The output callback table.
+ * @param fVerbose Whether to print in terse or verbose form.
+ */
+DECLINLINE(void) rtMemTrackerDumpOneStatRecord(PRTMEMTRACKERSTATS pStats, PRTMEMTRACKEROUTPUT pOutput, bool fVerbose)
+{
+ if (fVerbose)
+ {
+ pOutput->pfnPrintf(pOutput,
+ " Currently allocated: %7zu blocks, %8zu bytes\n"
+ " Total allocation sum: %7RU64 blocks, %8RU64 bytes\n"
+ ,
+ pStats->cAllocatedBlocks,
+ pStats->cbAllocated,
+ pStats->cTotalAllocatedBlocks,
+ pStats->cbTotalAllocated);
+ pOutput->pfnPrintf(pOutput,
+ " Alloc: %7RU64 AllocZ: %7RU64 Free: %7RU64 User Chg: %7RU64\n"
+ " RPrep: %7RU64 RDone: %7RU64 RFail: %7RU64\n"
+ " New: %7RU64 New[]: %7RU64 Delete: %7RU64 Delete[]: %7RU64\n"
+ ,
+ pStats->acMethodCalls[RTMEMTRACKERMETHOD_ALLOC],
+ pStats->acMethodCalls[RTMEMTRACKERMETHOD_ALLOCZ],
+ pStats->acMethodCalls[RTMEMTRACKERMETHOD_FREE],
+ pStats->cUserChanges,
+ pStats->acMethodCalls[RTMEMTRACKERMETHOD_REALLOC_PREP],
+ pStats->acMethodCalls[RTMEMTRACKERMETHOD_REALLOC_DONE],
+ pStats->acMethodCalls[RTMEMTRACKERMETHOD_REALLOC_FAILED],
+ pStats->acMethodCalls[RTMEMTRACKERMETHOD_NEW],
+ pStats->acMethodCalls[RTMEMTRACKERMETHOD_NEW_ARRAY],
+ pStats->acMethodCalls[RTMEMTRACKERMETHOD_DELETE],
+ pStats->acMethodCalls[RTMEMTRACKERMETHOD_DELETE_ARRAY]);
+ }
+ else
+ {
+ pOutput->pfnPrintf(pOutput, " %zu bytes in %zu blocks\n",
+ pStats->cbAllocated, pStats->cAllocatedBlocks);
+ }
+}
+
+
+/**
+ * Internal worker that dumps all the memory tracking data.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param pOutput The output callback table.
+ */
+static void rtMemTrackerDumpAllWorker(PRTMEMTRACKERINT pTracker, PRTMEMTRACKEROUTPUT pOutput)
+{
+ if (!pTracker)
+ return;
+
+ /*
+ * We use the EW direction to make sure the lists, trees and statistics
+ * does not change while we're working.
+ */
+ PRTMEMTRACKERUSER pUser = rtMemTrackerGetUser(pTracker);
+ RTSemXRoadsEWEnter(pTracker->hXRoads);
+
+ /* Global statistics.*/
+ pOutput->pfnPrintf(pOutput, "*** Global statistics ***\n");
+ rtMemTrackerDumpOneStatRecord(&pTracker->GlobalStats, pOutput, true);
+ pOutput->pfnPrintf(pOutput, " Busy Allocs: %4RU64 Busy Frees: %4RU64 Tags: %3u Users: %3u\n",
+ pTracker->cBusyAllocs, pTracker->cBusyFrees, pTracker->cTags, pTracker->cUsers);
+
+ /* Per tag statistics. */
+ pOutput->pfnPrintf(pOutput, "\n*** Tag statistics ***\n");
+ PRTMEMTRACKERTAG pTag, pNextTag;
+ RTListForEachSafe(&pTracker->TagList, pTag, pNextTag, RTMEMTRACKERTAG, ListEntry)
+ {
+ pOutput->pfnPrintf(pOutput, "Tag: %s\n", pTag->szTag);
+ rtMemTrackerDumpOneStatRecord(&pTag->Stats, pOutput, true);
+ pOutput->pfnPrintf(pOutput, "\n", pTag->szTag);
+ }
+
+ /* Per user statistics & blocks. */
+ pOutput->pfnPrintf(pOutput, "\n*** User statistics ***\n");
+ PRTMEMTRACKERUSER pCurUser, pNextUser;
+ RTListForEachSafe(&pTracker->UserList, pCurUser, pNextUser, RTMEMTRACKERUSER, ListEntry)
+ {
+ pOutput->pfnPrintf(pOutput, "User #%u: %s%s (cInTracker=%d)\n",
+ pCurUser->idUser,
+ pCurUser->szName,
+ pUser == pCurUser ? " (me)" : "",
+ pCurUser->cInTracker);
+ rtMemTrackerDumpOneStatRecord(&pCurUser->Stats, pOutput, true);
+
+ PRTMEMTRACKERHDR pCurHdr, pNextHdr;
+ RTListForEachSafe(&pCurUser->MemoryList, pCurHdr, pNextHdr, RTMEMTRACKERHDR, ListEntry)
+ {
+ if (pCurHdr->pTag)
+ pOutput->pfnPrintf(pOutput,
+ " %zu bytes at %p with tag %s\n"
+ " %.*Rhxd\n"
+ "\n",
+ pCurHdr->cbUser, pCurHdr->pvUser, pCurHdr->pTag->szTag,
+ RT_MIN(pCurHdr->cbUser, 16*3), pCurHdr->pvUser);
+ else
+ pOutput->pfnPrintf(pOutput,
+ " %zu bytes at %p without a tag\n"
+ " %.*Rhxd\n"
+ "\n",
+ pCurHdr->cbUser, pCurHdr->pvUser,
+ RT_MIN(pCurHdr->cbUser, 16*3), pCurHdr->pvUser);
+ }
+ pOutput->pfnPrintf(pOutput, "\n", pTag->szTag);
+ }
+
+ /* Repeat the global statistics. */
+ pOutput->pfnPrintf(pOutput, "*** Global statistics (reprise) ***\n");
+ rtMemTrackerDumpOneStatRecord(&pTracker->GlobalStats, pOutput, true);
+ pOutput->pfnPrintf(pOutput, " Busy Allocs: %4RU64 Busy Frees: %4RU64 Tags: %3u Users: %3u\n",
+ pTracker->cBusyAllocs, pTracker->cBusyFrees, pTracker->cTags, pTracker->cUsers);
+
+ RTSemXRoadsEWLeave(pTracker->hXRoads);
+ rtMemTrackerPutUser(pUser);
+}
+
+
+/**
+ * Internal worker that dumps the memory tracking statistics.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param pOutput The output callback table.
+ * @param fVerbose Whether to the verbose or quiet.
+ */
+static void rtMemTrackerDumpStatsWorker(PRTMEMTRACKERINT pTracker, PRTMEMTRACKEROUTPUT pOutput, bool fVerbose)
+{
+ if (!pTracker)
+ return;
+
+ /*
+ * We use the EW direction to make sure the lists, trees and statistics
+ * does not change while we're working.
+ */
+ PRTMEMTRACKERUSER pUser = rtMemTrackerGetUser(pTracker);
+ RTSemXRoadsEWEnter(pTracker->hXRoads);
+
+ /* Global statistics.*/
+ pOutput->pfnPrintf(pOutput, "*** Global statistics ***\n");
+ rtMemTrackerDumpOneStatRecord(&pTracker->GlobalStats, pOutput, fVerbose);
+ if (fVerbose)
+ pOutput->pfnPrintf(pOutput, " Busy Allocs: %4RU64 Busy Frees: %4RU64 Tags: %3u Users: %3u\n",
+ pTracker->cBusyAllocs, pTracker->cBusyFrees, pTracker->cTags, pTracker->cUsers);
+
+ /* Per tag statistics. */
+ pOutput->pfnPrintf(pOutput, "\n*** Tag statistics ***\n");
+ PRTMEMTRACKERTAG pTag, pNextTag;
+ RTListForEachSafe(&pTracker->TagList, pTag, pNextTag, RTMEMTRACKERTAG, ListEntry)
+ {
+ if ( fVerbose
+ || pTag->Stats.cbAllocated)
+ {
+ pOutput->pfnPrintf(pOutput, "Tag: %s\n", pTag->szTag);
+ rtMemTrackerDumpOneStatRecord(&pTag->Stats, pOutput, fVerbose);
+ if (fVerbose)
+ pOutput->pfnPrintf(pOutput, "\n", pTag->szTag);
+ }
+ }
+
+ /* Per user statistics. */
+ pOutput->pfnPrintf(pOutput, "\n*** User statistics ***\n");
+ PRTMEMTRACKERUSER pCurUser, pNextUser;
+ RTListForEachSafe(&pTracker->UserList, pCurUser, pNextUser, RTMEMTRACKERUSER, ListEntry)
+ {
+ if ( fVerbose
+ || pCurUser->Stats.cbAllocated
+ || pCurUser == pUser)
+ {
+ pOutput->pfnPrintf(pOutput, "User #%u: %s%s (cInTracker=%d)\n",
+ pCurUser->idUser,
+ pCurUser->szName,
+ pUser == pCurUser ? " (me)" : "",
+ pCurUser->cInTracker);
+ rtMemTrackerDumpOneStatRecord(&pCurUser->Stats, pOutput, fVerbose);
+ if (fVerbose)
+ pOutput->pfnPrintf(pOutput, "\n", pTag->szTag);
+ }
+ }
+
+ if (fVerbose)
+ {
+ /* Repeat the global statistics. */
+ pOutput->pfnPrintf(pOutput, "*** Global statistics (reprise) ***\n");
+ rtMemTrackerDumpOneStatRecord(&pTracker->GlobalStats, pOutput, fVerbose);
+ pOutput->pfnPrintf(pOutput, " Busy Allocs: %4RU64 Busy Frees: %4RU64 Tags: %3u Users: %3u\n",
+ pTracker->cBusyAllocs, pTracker->cBusyFrees, pTracker->cTags, pTracker->cUsers);
+ }
+
+ RTSemXRoadsEWLeave(pTracker->hXRoads);
+ rtMemTrackerPutUser(pUser);
+}
+
+
+/**
+ * @callback_method_impl{RTMEMTRACKEROUTPUT::pfnPrintf, Outputting to the release log}
+ */
+static DECLCALLBACK(void) rtMemTrackerDumpLogOutput(PRTMEMTRACKEROUTPUT pThis, const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ RTLogPrintfV(pszFormat, va);
+ va_end(va);
+}
+
+
+/**
+ * Internal worker for RTMemTrackerDumpAllToLog and RTMemTrackerDumpAllToLogEx.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ */
+static void rtMemTrackerDumpAllToLogEx(PRTMEMTRACKERINT pTracker)
+{
+ RTMEMTRACKEROUTPUT Output;
+ Output.pfnPrintf = rtMemTrackerDumpLogOutput;
+ rtMemTrackerDumpAllWorker(pTracker, &Output);
+}
+
+
+/**
+ * Internal worker for RTMemTrackerDumpStatsToLog and
+ * RTMemTrackerDumpStatsToLogEx.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param fVerbose Whether to print all the stats or just the ones
+ * relevant to hunting leaks.
+ */
+static void rtMemTrackerDumpStatsToLogEx(PRTMEMTRACKERINT pTracker, bool fVerbose)
+{
+ RTMEMTRACKEROUTPUT Output;
+ Output.pfnPrintf = rtMemTrackerDumpLogOutput;
+ rtMemTrackerDumpStatsWorker(pTracker, &Output, fVerbose);
+}
+
+
+/**
+ * @callback_method_impl{RTMEMTRACKEROUTPUT::pfnPrintf, Outputting to the release log}
+ */
+static DECLCALLBACK(void) rtMemTrackerDumpLogRelOutput(PRTMEMTRACKEROUTPUT pThis, const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ RTLogRelPrintfV(pszFormat, va);
+ va_end(va);
+}
+
+
+/**
+ * Internal worker for RTMemTrackerDumpStatsToLog and
+ * RTMemTrackerDumpStatsToLogEx.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ */
+static void rtMemTrackerDumpAllToLogRelEx(PRTMEMTRACKERINT pTracker)
+{
+ RTMEMTRACKEROUTPUT Output;
+ Output.pfnPrintf = rtMemTrackerDumpLogRelOutput;
+ rtMemTrackerDumpAllWorker(pTracker, &Output);
+}
+
+
+/**
+ * Internal worker for RTMemTrackerDumpStatsToLogRel and
+ * RTMemTrackerDumpStatsToLogRelEx.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param fVerbose Whether to print all the stats or just the ones
+ * relevant to hunting leaks.
+ */
+static void rtMemTrackerDumpStatsToLogRelEx(PRTMEMTRACKERINT pTracker, bool fVerbose)
+{
+ RTMEMTRACKEROUTPUT Output;
+ Output.pfnPrintf = rtMemTrackerDumpLogRelOutput;
+ rtMemTrackerDumpStatsWorker(pTracker, &Output, fVerbose);
+}
+
+#ifdef IN_RING3
+
+/**
+ * @callback_method_impl{RTMEMTRACKEROUTPUT::pfnPrintf, Outputting to file}
+ */
+static DECLCALLBACK(void) rtMemTrackerDumpFileOutput(PRTMEMTRACKEROUTPUT pThis, const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ char szOutput[_4K];
+ size_t cchOutput = RTStrPrintfV(szOutput, sizeof(szOutput), pszFormat, va);
+ va_end(va);
+ RTFileWrite(pThis->uData.hFile, szOutput, cchOutput, NULL);
+}
+
+
+/**
+ * Internal work that dumps the memory tracking statistics to a file handle.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param fVerbose Whether to print all the stats or just the ones
+ * relevant to hunting leaks.
+ * @param hFile The file handle. Can be NIL_RTFILE.
+ */
+static void rtMemTrackerDumpStatsToFileHandle(PRTMEMTRACKERINT pTracker, bool fVerbose, RTFILE hFile)
+{
+ if (hFile == NIL_RTFILE)
+ return;
+ RTMEMTRACKEROUTPUT Output;
+ Output.pfnPrintf = rtMemTrackerDumpFileOutput;
+ Output.uData.hFile = hFile;
+ rtMemTrackerDumpStatsWorker(pTracker, &Output, fVerbose);
+}
+
+
+/**
+ * Internal work that dumps all the memory tracking information to a file
+ * handle.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param hFile The file handle. Can be NIL_RTFILE.
+ */
+static void rtMemTrackerDumpAllToFileHandle(PRTMEMTRACKERINT pTracker, RTFILE hFile)
+{
+ if (hFile == NIL_RTFILE)
+ return;
+ RTMEMTRACKEROUTPUT Output;
+ Output.pfnPrintf = rtMemTrackerDumpFileOutput;
+ Output.uData.hFile = hFile;
+ rtMemTrackerDumpAllWorker(pTracker, &Output);
+}
+
+
+/**
+ * Internal worker for RTMemTrackerDumpStatsToStdOut and
+ * RTMemTrackerDumpStatsToStdOutEx.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param fVerbose Whether to print all the stats or just the ones
+ * relevant to hunting leaks.
+ */
+static void rtMemTrackerDumpStatsToStdOutEx(PRTMEMTRACKERINT pTracker, bool fVerbose)
+{
+ rtMemTrackerDumpStatsToFileHandle(pTracker, fVerbose, rtFileGetStandard(RTHANDLESTD_OUTPUT));
+}
+
+
+/**
+ * Internal worker for RTMemTrackerDumpAllToStdOut and
+ * RTMemTrackerDumpAllToStdOutEx.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ */
+static void rtMemTrackerDumpAllToStdOutEx(PRTMEMTRACKERINT pTracker)
+{
+ rtMemTrackerDumpAllToFileHandle(pTracker, rtFileGetStandard(RTHANDLESTD_OUTPUT));
+}
+
+
+/**
+ * Internal worker for RTMemTrackerDumpStatsToStdErr and
+ * RTMemTrackerDumpStatsToStdErrEx.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param fVerbose Whether to print all the stats or just the ones
+ * relevant to hunting leaks.
+ */
+static void rtMemTrackerDumpStatsToStdErrEx(PRTMEMTRACKERINT pTracker, bool fVerbose)
+{
+ rtMemTrackerDumpStatsToFileHandle(pTracker, fVerbose, rtFileGetStandard(RTHANDLESTD_ERROR));
+}
+
+
+/**
+ * Internal worker for RTMemTrackerDumpAllToStdErr and
+ * RTMemTrackerDumpAllToStdErrEx.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ */
+static void rtMemTrackerDumpAllToStdErrEx(PRTMEMTRACKERINT pTracker)
+{
+ rtMemTrackerDumpAllToFileHandle(pTracker, rtFileGetStandard(RTHANDLESTD_ERROR));
+}
+
+
+/**
+ * Internal worker for RTMemTrackerDumpStatsToFile and
+ * RTMemTrackerDumpStatsToFileEx.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param fVerbose Whether to print all the stats or just the ones
+ * relevant to hunting leaks.
+ * @param pszFilename The name of the output file.
+ */
+static void rtMemTrackerDumpStatsToFileEx(PRTMEMTRACKERINT pTracker, bool fVerbose, const char *pszFilename)
+{
+ if (!pTracker)
+ return;
+
+ /** @todo this is borked. */
+ RTFILE hFile;
+ int rc = RTFileOpen(&hFile, pszFilename,
+ RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE
+ | (0600 << RTFILE_O_CREATE_MODE_SHIFT));
+ if (RT_FAILURE(rc))
+ return;
+ rtMemTrackerDumpStatsToFileHandle(pTracker, fVerbose, hFile);
+ RTFileClose(hFile);
+}
+
+
+/**
+ * Internal worker for RTMemTrackerDumpAllToFile and
+ * RTMemTrackerDumpAllToFileEx.
+ *
+ * @param pTracker The tracker instance. Can be NULL.
+ * @param pszFilename The name of the output file.
+ */
+static void rtMemTrackerDumpAllToFileEx(PRTMEMTRACKERINT pTracker, const char *pszFilename)
+{
+ if (!pTracker)
+ return;
+
+ RTFILE hFile;
+ int rc = RTFileOpen(&hFile, pszFilename,
+ RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE
+ | (0600 << RTFILE_O_CREATE_MODE_SHIFT));
+ if (RT_FAILURE(rc))
+ return;
+ rtMemTrackerDumpAllToFileHandle(pTracker, hFile);
+ RTFileClose(hFile);
+}
+
+#endif /* IN_RING3 */
+
+
+
+/*
+ *
+ *
+ * Default tracker.
+ * Default tracker.
+ * Default tracker.
+ * Default tracker.
+ * Default tracker.
+ *
+ *
+ */
+
+
+/**
+ * Handles the lazy initialization when g_pDefaultTracker is NULL.
+ *
+ * @returns The newly created default tracker or NULL.
+ */
+static PRTMEMTRACKERINT rtMemTrackerLazyInitDefaultTracker(void)
+{
+ /*
+ * Don't attempt initialize before RTThread has been initialized.
+ */
+ if (!RTThreadIsInitialized())
+ return NULL;
+
+ /*
+ * Only one initialization at a time. For now we'll ASSUME that there
+ * won't be thread ending up here at the same time, only the same
+ * reentering from the allocator when creating the tracker.
+ */
+ static volatile bool s_fInitialized = false;
+ if (ASMAtomicXchgBool(&s_fInitialized, true))
+ return g_pDefaultTracker;
+
+ PRTMEMTRACKERINT pTracker = NULL; /* gcc sucks. */
+ int rc = rtMemTrackerCreate(&pTracker);
+ if (RT_FAILURE(rc))
+ return NULL;
+
+ g_pDefaultTracker = pTracker;
+ return pTracker;
+}
+
+
+
+RTDECL(void *) RTMemTrackerHdrAlloc(void *pv, size_t cb, const char *pszTag, RTMEMTRACKERMETHOD enmMethod)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerHdrAllocEx(pTracker, pv, cb, pszTag, enmMethod);
+}
+
+
+RTDECL(void *) RTMemTrackerHdrReallocPrep(void *pvOldUser, size_t cbOldUser, const char *pszTag)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerHdrReallocPrepEx(pTracker, pvOldUser, cbOldUser, pszTag);
+}
+
+
+RTDECL(void *) RTMemTrackerHdrReallocDone(void *pvNew, size_t cbNewUser, void *pvOld, const char *pszTag)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerHdrReallocDoneEx(pTracker, pvNew, cbNewUser, pvOld, pszTag);
+}
+
+
+RTDECL(void *) RTMemTrackerHdrFree(void *pvUser, size_t cbUser, const char *pszTag, RTMEMTRACKERMETHOD enmMethod)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerHdrFreeEx(pTracker, pvUser, cbUser, pszTag, enmMethod);
+}
+
+
+RTDECL(void) RTMemTrackerDumpAllToLog(void)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerDumpAllToLogEx(pTracker);
+}
+
+
+RTDECL(void) RTMemTrackerDumpAllToLogRel(void)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerDumpAllToLogRelEx(pTracker);
+}
+
+
+RTDECL(void) RTMemTrackerDumpAllToStdOut(void)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerDumpAllToStdOutEx(pTracker);
+}
+
+
+RTDECL(void) RTMemTrackerDumpAllToStdErr(void)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerDumpAllToStdErrEx(pTracker);
+}
+
+
+RTDECL(void) RTMemTrackerDumpAllToFile(const char *pszFilename)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerDumpAllToFileEx(pTracker, pszFilename);
+}
+
+
+RTDECL(void) RTMemTrackerDumpStatsToLog(bool fVerbose)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerDumpStatsToLogEx(pTracker, fVerbose);
+}
+
+
+RTDECL(void) RTMemTrackerDumpStatsToLogRel(bool fVerbose)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerDumpStatsToLogRelEx(pTracker, fVerbose);
+}
+
+
+RTDECL(void) RTMemTrackerDumpStatsToStdOut(bool fVerbose)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerDumpStatsToStdOutEx(pTracker, fVerbose);
+}
+
+
+RTDECL(void) RTMemTrackerDumpStatsToStdErr(bool fVerbose)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerDumpStatsToStdErrEx(pTracker, fVerbose);
+}
+
+
+RTDECL(void) RTMemTrackerDumpStatsToFile(bool fVerbose, const char *pszFilename)
+{
+ PRTMEMTRACKERINT pTracker = g_pDefaultTracker;
+ if (RT_UNLIKELY(!pTracker))
+ pTracker = rtMemTrackerLazyInitDefaultTracker();
+ return rtMemTrackerDumpStatsToFileEx(pTracker, fVerbose, pszFilename);
+}
diff --git a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm
index da71254ef..1e0974623 100644
--- a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm
+++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm
@@ -1,4 +1,4 @@
-; $Id: ASMAtomicCmpXchgExU64.asm $
+; $Id: ASMAtomicCmpXchgExU64.asm 33540 2010-10-28 09:27:05Z vboxsync $
;; @file
; IPRT - ASMAtomicCmpXchgExU64().
;
diff --git a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm
index d6ee4d69c..e0f96d47d 100644
--- a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm
+++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm
@@ -1,4 +1,4 @@
-; $Id: ASMAtomicCmpXchgU64.asm $
+; $Id: ASMAtomicCmpXchgU64.asm 33540 2010-10-28 09:27:05Z vboxsync $
;; @file
; IPRT - ASMAtomicCmpXchgU64().
;
diff --git a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU8.asm b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU8.asm
index 0c57b29d3..86f1af833 100644
--- a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU8.asm
+++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU8.asm
@@ -1,4 +1,4 @@
-; $Id: ASMAtomicCmpXchgU8.asm $
+; $Id: ASMAtomicCmpXchgU8.asm 33540 2010-10-28 09:27:05Z vboxsync $
;; @file
; IPRT - ASMAtomicCmpXchgU8().
;
diff --git a/src/VBox/Runtime/common/asm/ASMAtomicReadU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicReadU64.asm
index 60d01e32a..cf8298e47 100644
--- a/src/VBox/Runtime/common/asm/ASMAtomicReadU64.asm
+++ b/src/VBox/Runtime/common/asm/ASMAtomicReadU64.asm
@@ -1,4 +1,4 @@
-; $Id: ASMAtomicReadU64.asm $
+; $Id: ASMAtomicReadU64.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - ASMAtomicReadU64().
;
diff --git a/src/VBox/Runtime/common/asm/ASMAtomicUoReadU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicUoReadU64.asm
index 8e83ebe7e..0751ba001 100644
--- a/src/VBox/Runtime/common/asm/ASMAtomicUoReadU64.asm
+++ b/src/VBox/Runtime/common/asm/ASMAtomicUoReadU64.asm
@@ -1,4 +1,4 @@
-; $Id: ASMAtomicUoReadU64.asm $
+; $Id: ASMAtomicUoReadU64.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - ASMAtomicUoReadU64().
;
diff --git a/src/VBox/Runtime/common/asm/ASMAtomicXchgU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicXchgU64.asm
index 2530060ec..0545fcc92 100644
--- a/src/VBox/Runtime/common/asm/ASMAtomicXchgU64.asm
+++ b/src/VBox/Runtime/common/asm/ASMAtomicXchgU64.asm
@@ -1,4 +1,4 @@
-; $Id: ASMAtomicXchgU64.asm $
+; $Id: ASMAtomicXchgU64.asm 33540 2010-10-28 09:27:05Z vboxsync $
;; @file
; IPRT - ASMAtomicXchgU64().
;
diff --git a/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32.asm b/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32.asm
index 6155e869a..f5e92a5bc 100644
--- a/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32.asm
+++ b/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32.asm
@@ -1,4 +1,4 @@
-; $Id: ASMMultU64ByU32DivByU32.asm $
+; $Id: ASMMultU64ByU32DivByU32.asm 33540 2010-10-28 09:27:05Z vboxsync $
;; @file
; IPRT - Assembly Functions, ASMMultU64ByU32DivByU32.
;
diff --git a/src/VBox/Runtime/common/asm/ASMNopPause.asm b/src/VBox/Runtime/common/asm/ASMNopPause.asm
index 455bd14d0..25b50a9e6 100644
--- a/src/VBox/Runtime/common/asm/ASMNopPause.asm
+++ b/src/VBox/Runtime/common/asm/ASMNopPause.asm
@@ -1,4 +1,4 @@
-; $Id: ASMNopPause.asm $
+; $Id: ASMNopPause.asm 33540 2010-10-28 09:27:05Z vboxsync $
;; @file
; IPRT - ASMNopPause().
;
diff --git a/src/VBox/Runtime/common/asm/asm-fake.cpp b/src/VBox/Runtime/common/asm/asm-fake.cpp
index 73478a86e..263ad3e22 100644
--- a/src/VBox/Runtime/common/asm/asm-fake.cpp
+++ b/src/VBox/Runtime/common/asm/asm-fake.cpp
@@ -1,4 +1,4 @@
-/* $Id: asm-fake.cpp $ */
+/* $Id: asm-fake.cpp 29278 2010-05-09 23:28:27Z vboxsync $ */
/** @file
* IPRT - Fake asm.h routines for use early in a new port.
*/
diff --git a/src/VBox/Runtime/common/checksum/RTSha1Digest.cpp b/src/VBox/Runtime/common/checksum/RTSha1Digest.cpp
index 70b158be2..4caac022e 100644
--- a/src/VBox/Runtime/common/checksum/RTSha1Digest.cpp
+++ b/src/VBox/Runtime/common/checksum/RTSha1Digest.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSha1Digest.cpp $ */
+/* $Id: RTSha1Digest.cpp 32569 2010-09-16 15:42:51Z vboxsync $ */
/** @file
* IPRT - SHA1 digest creation
*/
diff --git a/src/VBox/Runtime/common/checksum/adler32.cpp b/src/VBox/Runtime/common/checksum/adler32.cpp
index d9e54985b..05fa27736 100644
--- a/src/VBox/Runtime/common/checksum/adler32.cpp
+++ b/src/VBox/Runtime/common/checksum/adler32.cpp
@@ -1,4 +1,4 @@
-/* $Id: adler32.cpp $ */
+/* $Id: adler32.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Adler-32
*/
diff --git a/src/VBox/Runtime/common/checksum/crc32-zlib.cpp b/src/VBox/Runtime/common/checksum/crc32-zlib.cpp
index 650a959b2..6320688b7 100644
--- a/src/VBox/Runtime/common/checksum/crc32-zlib.cpp
+++ b/src/VBox/Runtime/common/checksum/crc32-zlib.cpp
@@ -1,4 +1,4 @@
-/* $Id: crc32-zlib.cpp $ */
+/* $Id: crc32-zlib.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - CRC-32 on top of zlib (very fast).
*/
diff --git a/src/VBox/Runtime/common/checksum/crc32.cpp b/src/VBox/Runtime/common/checksum/crc32.cpp
index c43b2cbbd..998c8f455 100644
--- a/src/VBox/Runtime/common/checksum/crc32.cpp
+++ b/src/VBox/Runtime/common/checksum/crc32.cpp
@@ -1,4 +1,4 @@
-/* $Id: crc32.cpp $ */
+/* $Id: crc32.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - CRC32.
*/
diff --git a/src/VBox/Runtime/common/checksum/crc64.cpp b/src/VBox/Runtime/common/checksum/crc64.cpp
index 74c60070d..586b5c8b4 100644
--- a/src/VBox/Runtime/common/checksum/crc64.cpp
+++ b/src/VBox/Runtime/common/checksum/crc64.cpp
@@ -1,4 +1,4 @@
-/* $Id: crc64.cpp $ */
+/* $Id: crc64.cpp 31847 2010-08-21 20:33:07Z vboxsync $ */
/** @file
* IPRT - CRC64.
*
diff --git a/src/VBox/Runtime/common/checksum/ipv4.cpp b/src/VBox/Runtime/common/checksum/ipv4.cpp
index 4b10b4b00..1dd1ee363 100644
--- a/src/VBox/Runtime/common/checksum/ipv4.cpp
+++ b/src/VBox/Runtime/common/checksum/ipv4.cpp
@@ -1,4 +1,4 @@
-/* $Id: ipv4.cpp $ */
+/* $Id: ipv4.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - IPv4 Checksum calculation and validation.
*/
diff --git a/src/VBox/Runtime/common/checksum/ipv6.cpp b/src/VBox/Runtime/common/checksum/ipv6.cpp
index d33438a0f..c9baf477a 100644
--- a/src/VBox/Runtime/common/checksum/ipv6.cpp
+++ b/src/VBox/Runtime/common/checksum/ipv6.cpp
@@ -1,4 +1,4 @@
-/* $Id: ipv6.cpp $ */
+/* $Id: ipv6.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - IPv6 Checksum calculation and validation.
*/
diff --git a/src/VBox/Runtime/common/checksum/manifest-file.cpp b/src/VBox/Runtime/common/checksum/manifest-file.cpp
index d686022e6..602c99d49 100644
--- a/src/VBox/Runtime/common/checksum/manifest-file.cpp
+++ b/src/VBox/Runtime/common/checksum/manifest-file.cpp
@@ -1,4 +1,4 @@
-/* $Id: manifest-file.cpp $ */
+/* $Id: manifest-file.cpp 35351 2010-12-27 17:04:17Z vboxsync $ */
/** @file
* IPRT - Manifest, the bits with file dependencies
*/
diff --git a/src/VBox/Runtime/common/checksum/manifest.cpp b/src/VBox/Runtime/common/checksum/manifest.cpp
index b1e1152be..69a52ee42 100644
--- a/src/VBox/Runtime/common/checksum/manifest.cpp
+++ b/src/VBox/Runtime/common/checksum/manifest.cpp
@@ -1,4 +1,4 @@
-/* $Id: manifest.cpp $ */
+/* $Id: manifest.cpp 33289 2010-10-21 10:00:15Z vboxsync $ */
/** @file
* IPRT - Manifest file handling.
*/
diff --git a/src/VBox/Runtime/common/checksum/manifest2.cpp b/src/VBox/Runtime/common/checksum/manifest2.cpp
index 534d08d9b..918b67eb8 100644
--- a/src/VBox/Runtime/common/checksum/manifest2.cpp
+++ b/src/VBox/Runtime/common/checksum/manifest2.cpp
@@ -1,4 +1,4 @@
-/* $Id: manifest2.cpp $ */
+/* $Id: manifest2.cpp 34941 2010-12-10 10:58:06Z vboxsync $ */
/** @file
* IPRT - Manifest, the core.
*/
diff --git a/src/VBox/Runtime/common/checksum/manifest3.cpp b/src/VBox/Runtime/common/checksum/manifest3.cpp
index 393c130e6..cf06cd064 100644
--- a/src/VBox/Runtime/common/checksum/manifest3.cpp
+++ b/src/VBox/Runtime/common/checksum/manifest3.cpp
@@ -1,4 +1,4 @@
-/* $Id: manifest3.cpp $ */
+/* $Id: manifest3.cpp 35351 2010-12-27 17:04:17Z vboxsync $ */
/** @file
* IPRT - Manifest, the bits with the most dependencies.
*/
diff --git a/src/VBox/Runtime/common/checksum/md5.cpp b/src/VBox/Runtime/common/checksum/md5.cpp
index 1bc5f97b4..f312d1763 100644
--- a/src/VBox/Runtime/common/checksum/md5.cpp
+++ b/src/VBox/Runtime/common/checksum/md5.cpp
@@ -1,4 +1,4 @@
-/* $Id: md5.cpp $ */
+/* $Id: md5.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - MD5 message digest functions.
*/
diff --git a/src/VBox/Runtime/common/checksum/md5str.cpp b/src/VBox/Runtime/common/checksum/md5str.cpp
index 40dbb8ba9..f85c11783 100644
--- a/src/VBox/Runtime/common/checksum/md5str.cpp
+++ b/src/VBox/Runtime/common/checksum/md5str.cpp
@@ -1,4 +1,4 @@
-/* $Id: md5str.cpp $ */
+/* $Id: md5str.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - MD5 string functions.
*/
diff --git a/src/VBox/Runtime/common/checksum/sha1.cpp b/src/VBox/Runtime/common/checksum/sha1.cpp
index e448a479b..624ce03d2 100644
--- a/src/VBox/Runtime/common/checksum/sha1.cpp
+++ b/src/VBox/Runtime/common/checksum/sha1.cpp
@@ -1,4 +1,4 @@
-/* $Id: sha1.cpp $ */
+/* $Id: sha1.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - SHA-1 hash functions.
*/
diff --git a/src/VBox/Runtime/common/checksum/sha1str.cpp b/src/VBox/Runtime/common/checksum/sha1str.cpp
index 730d0bee9..d50b57cd4 100644
--- a/src/VBox/Runtime/common/checksum/sha1str.cpp
+++ b/src/VBox/Runtime/common/checksum/sha1str.cpp
@@ -1,4 +1,4 @@
-/* $Id: sha1str.cpp $ */
+/* $Id: sha1str.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - SHA-1 string functions.
*/
diff --git a/src/VBox/Runtime/common/checksum/sha256.cpp b/src/VBox/Runtime/common/checksum/sha256.cpp
index c78e22e22..ad1c831af 100644
--- a/src/VBox/Runtime/common/checksum/sha256.cpp
+++ b/src/VBox/Runtime/common/checksum/sha256.cpp
@@ -1,4 +1,4 @@
-/* $Id: sha256.cpp $ */
+/* $Id: sha256.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - SHA-256 hash functions.
*/
diff --git a/src/VBox/Runtime/common/checksum/sha256str.cpp b/src/VBox/Runtime/common/checksum/sha256str.cpp
index 43e668e18..4c683db9a 100644
--- a/src/VBox/Runtime/common/checksum/sha256str.cpp
+++ b/src/VBox/Runtime/common/checksum/sha256str.cpp
@@ -1,4 +1,4 @@
-/* $Id: sha256str.cpp $ */
+/* $Id: sha256str.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - SHA-256 string functions.
*/
diff --git a/src/VBox/Runtime/common/checksum/sha512.cpp b/src/VBox/Runtime/common/checksum/sha512.cpp
index ee38f3686..0befcf7f6 100644
--- a/src/VBox/Runtime/common/checksum/sha512.cpp
+++ b/src/VBox/Runtime/common/checksum/sha512.cpp
@@ -1,4 +1,4 @@
-/* $Id: sha512.cpp $ */
+/* $Id: sha512.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - SHA-512 hash functions.
*/
diff --git a/src/VBox/Runtime/common/checksum/sha512str.cpp b/src/VBox/Runtime/common/checksum/sha512str.cpp
index 133734217..eed48abad 100644
--- a/src/VBox/Runtime/common/checksum/sha512str.cpp
+++ b/src/VBox/Runtime/common/checksum/sha512str.cpp
@@ -1,4 +1,4 @@
-/* $Id: sha512str.cpp $ */
+/* $Id: sha512str.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - SHA-512 string functions.
*/
diff --git a/src/VBox/Runtime/common/dbg/dbg.cpp b/src/VBox/Runtime/common/dbg/dbg.cpp
index 4198ddafe..e17bdcb76 100644
--- a/src/VBox/Runtime/common/dbg/dbg.cpp
+++ b/src/VBox/Runtime/common/dbg/dbg.cpp
@@ -1,4 +1,4 @@
-/* $Id: dbg.cpp $ */
+/* $Id: dbg.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Debug Misc.
*/
diff --git a/src/VBox/Runtime/common/dbg/dbgas.cpp b/src/VBox/Runtime/common/dbg/dbgas.cpp
index dac5ae97e..a5f7c355b 100644
--- a/src/VBox/Runtime/common/dbg/dbgas.cpp
+++ b/src/VBox/Runtime/common/dbg/dbgas.cpp
@@ -1,4 +1,4 @@
-/* $Id: dbgas.cpp $ */
+/* $Id: dbgas.cpp 33663 2010-11-01 15:58:06Z vboxsync $ */
/** @file
* IPRT - Debug Address Space.
*/
diff --git a/src/VBox/Runtime/common/dbg/dbgmod.cpp b/src/VBox/Runtime/common/dbg/dbgmod.cpp
index fc94ffbf7..ecfc58793 100644
--- a/src/VBox/Runtime/common/dbg/dbgmod.cpp
+++ b/src/VBox/Runtime/common/dbg/dbgmod.cpp
@@ -1,4 +1,4 @@
-/* $Id: dbgmod.cpp $ */
+/* $Id: dbgmod.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Debug Module Interpreter.
*/
diff --git a/src/VBox/Runtime/common/dbg/dbgmodcontainer.cpp b/src/VBox/Runtime/common/dbg/dbgmodcontainer.cpp
index 476a39aa5..ed220cba9 100644
--- a/src/VBox/Runtime/common/dbg/dbgmodcontainer.cpp
+++ b/src/VBox/Runtime/common/dbg/dbgmodcontainer.cpp
@@ -1,4 +1,4 @@
-/* $Id: dbgmodcontainer.cpp $ */
+/* $Id: dbgmodcontainer.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Debug Info Container.
*/
diff --git a/src/VBox/Runtime/common/dbg/dbgmodnm.cpp b/src/VBox/Runtime/common/dbg/dbgmodnm.cpp
index f403157ae..ed10ad0de 100644
--- a/src/VBox/Runtime/common/dbg/dbgmodnm.cpp
+++ b/src/VBox/Runtime/common/dbg/dbgmodnm.cpp
@@ -1,4 +1,4 @@
-/* $Id: dbgmodnm.cpp $ */
+/* $Id: dbgmodnm.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Debug Map Reader For NM Like Mapfiles.
*/
@@ -503,7 +503,7 @@ static DECLCALLBACK(int) rtDbgModNm_TryOpen(PRTDBGMODINT pMod)
/** Virtual function table for the NM-like map file reader. */
-DECLHIDDEN(RTDBGMODVTDBG const) g_rtDbgModVtDbgNm =
+DECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbgNm =
{
/*.u32Magic = */ RTDBGMODVTDBG_MAGIC,
/*.fSupports = */ RT_DBGTYPE_MAP,
diff --git a/src/VBox/Runtime/common/dvm/Makefile.kup b/src/VBox/Runtime/common/dvm/Makefile.kup
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/VBox/Runtime/common/dvm/Makefile.kup
diff --git a/src/VBox/Runtime/common/dvm/dvm.cpp b/src/VBox/Runtime/common/dvm/dvm.cpp
new file mode 100644
index 000000000..eb9fe7021
--- /dev/null
+++ b/src/VBox/Runtime/common/dvm/dvm.cpp
@@ -0,0 +1,481 @@
+/* $Id: dvm.cpp 37270 2011-05-30 21:25:42Z vboxsync $ */
+/** @file
+ * IPRT Disk Volume Management API (DVM) - generic code.
+ */
+
+/*
+ * 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.
+ *
+ * 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/types.h>
+#include <iprt/assert.h>
+#include <iprt/mem.h>
+#include <iprt/dvm.h>
+#include <iprt/err.h>
+#include <iprt/asm.h>
+#include <iprt/string.h>
+#include "internal/dvm.h"
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+
+/**
+ * The internal volume manager structure.
+ */
+typedef struct RTDVMINTERNAL
+{
+ /** The DVM magic (RTDVM_MAGIC). */
+ uint32_t u32Magic;
+ /** The disk descriptor. */
+ RTDVMDISK DvmDisk;
+ /** Pointer to the backend operations table after a successful probe. */
+ PCRTDVMFMTOPS pDvmFmtOps;
+ /** The format specific volume manager data. */
+ RTDVMFMT hVolMgrFmt;
+ /** Reference counter. */
+ uint32_t volatile cRefs;
+} RTDVMINTERNAL;
+/** Pointer to an internal volume manager. */
+typedef RTDVMINTERNAL *PRTDVMINTERNAL;
+
+/**
+ * The internal volume structure.
+ */
+typedef struct RTDVMVOLUMEINTERNAL
+{
+ /** The DVM volume magic (RTDVMVOLUME_MAGIC). */
+ uint32_t u32Magic;
+ /** Pointer to the owning volume manager. */
+ PRTDVMINTERNAL pVolMgr;
+ /** Format specific volume data. */
+ RTDVMVOLUMEFMT hVolFmt;
+ /** Reference counter. */
+ uint32_t volatile cRefs;
+} RTDVMVOLUMEINTERNAL;
+/** Pointer to an internal volume. */
+typedef RTDVMVOLUMEINTERNAL *PRTDVMVOLUMEINTERNAL;
+
+/*******************************************************************************
+* Global variables *
+*******************************************************************************/
+extern RTDVMFMTOPS g_rtDvmFmtMbr;
+extern RTDVMFMTOPS g_rtDvmFmtGpt;
+extern RTDVMFMTOPS g_rtDvmFmtBsdLbl;
+
+/**
+ * Supported volume formats.
+ */
+static PCRTDVMFMTOPS g_aDvmFmts[] =
+{
+ &g_rtDvmFmtMbr,
+ &g_rtDvmFmtGpt,
+ &g_rtDvmFmtBsdLbl
+};
+
+/**
+ * Descriptions of the volume types.
+ *
+ * This is indexed by RTDVMVOLTYPE.
+ */
+static const char * g_apcszDvmVolTypes[] =
+{
+ "Invalid",
+ "Unknown",
+ "NTFS",
+ "FAT16",
+ "FAT32",
+ "Linux swap",
+ "Linux native",
+ "Linux LVM",
+ "Linux SoftRaid",
+ "FreeBSD",
+ "NetBSD",
+ "OpenBSD",
+ "Mac OS X HFS or HFS+",
+ "Solaris"
+};
+
+RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead,
+ PFNDVMWRITE pfnWrite, uint64_t cbDisk,
+ uint64_t cbSector, void *pvUser)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMINTERNAL pThis;
+
+ pThis = (PRTDVMINTERNAL)RTMemAllocZ(sizeof(RTDVMINTERNAL));
+ if (VALID_PTR(pThis))
+ {
+ pThis->u32Magic = RTDVM_MAGIC;
+ pThis->DvmDisk.cbDisk = cbDisk;
+ pThis->DvmDisk.cbSector = cbSector;
+ pThis->DvmDisk.pvUser = pvUser;
+ pThis->DvmDisk.pfnRead = pfnRead;
+ pThis->DvmDisk.pfnWrite = pfnWrite;
+ pThis->pDvmFmtOps = NULL;
+ pThis->hVolMgrFmt = NIL_RTDVMFMT;
+ pThis->cRefs = 1;
+ *phVolMgr = pThis;
+ }
+ else
+ rc = VERR_NO_MEMORY;
+
+ return rc;
+}
+
+RTDECL(uint32_t) RTDvmRetain(RTDVM hVolMgr)
+{
+ PRTDVMINTERNAL pThis = hVolMgr;
+ AssertPtrReturn(pThis, UINT32_MAX);
+ AssertReturn(pThis->u32Magic == RTDVM_MAGIC, UINT32_MAX);
+
+ uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
+ AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
+ return cRefs;
+}
+
+/**
+ * Destroys a volume manager handle.
+ *
+ * @param pThis The volume manager to destroy.
+ */
+static void rtDvmDestroy(PRTDVMINTERNAL pThis)
+{
+ if (pThis->hVolMgrFmt != NIL_RTDVMFMT)
+ {
+ AssertPtr(pThis->pDvmFmtOps);
+
+ /* Let the backend do it's own cleanup first. */
+ pThis->pDvmFmtOps->pfnClose(pThis->hVolMgrFmt);
+ pThis->hVolMgrFmt = NIL_RTDVMFMT;
+ }
+
+ pThis->DvmDisk.cbDisk = 0;
+ pThis->DvmDisk.pvUser = NULL;
+ pThis->DvmDisk.pfnRead = NULL;
+ pThis->DvmDisk.pfnWrite = NULL;
+ pThis->u32Magic = RTDVM_MAGIC_DEAD;
+ RTMemFree(pThis);
+}
+
+RTDECL(uint32_t) RTDvmRelease(RTDVM hVolMgr)
+{
+ PRTDVMINTERNAL pThis = hVolMgr;
+ if (pThis == NIL_RTDVM)
+ return 0;
+ AssertPtrReturn(pThis, UINT32_MAX);
+ AssertReturn(pThis->u32Magic == RTDVM_MAGIC, UINT32_MAX);
+
+ uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
+ AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis));
+ if (cRefs == 0)
+ rtDvmDestroy(pThis);
+ return cRefs;
+}
+
+RTDECL(int) RTDvmMapOpen(RTDVM hVolMgr)
+{
+ int rc = VINF_SUCCESS;
+ uint32_t uScoreMax = RTDVM_MATCH_SCORE_UNSUPPORTED;
+ PCRTDVMFMTOPS pDvmFmtOpsMatch = NULL;
+ PRTDVMINTERNAL pThis = hVolMgr;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_INVALID_HANDLE);
+
+ Assert(!pThis->pDvmFmtOps);
+
+ for (unsigned i = 0; i < RT_ELEMENTS(g_aDvmFmts); i++)
+ {
+ uint32_t uScore;
+ PCRTDVMFMTOPS pDvmFmtOps = g_aDvmFmts[i];
+
+ rc = pDvmFmtOps->pfnProbe(&pThis->DvmDisk, &uScore);
+ if ( RT_SUCCESS(rc)
+ && uScore > uScoreMax)
+ {
+ pDvmFmtOpsMatch = pDvmFmtOps;
+ uScoreMax = uScore;
+ }
+ else if (RT_FAILURE(rc))
+ break;
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ if (uScoreMax > RTDVM_MATCH_SCORE_UNSUPPORTED)
+ {
+ AssertPtr(pDvmFmtOpsMatch);
+
+ /* Open the format. */
+ rc = pDvmFmtOpsMatch->pfnOpen(&pThis->DvmDisk, &pThis->hVolMgrFmt);
+ if (RT_SUCCESS(rc))
+ pThis->pDvmFmtOps = pDvmFmtOpsMatch;
+ }
+ else
+ rc = VERR_NOT_SUPPORTED;
+ }
+
+ return rc;
+}
+
+RTDECL(int) RTDvmMapInitialize(RTDVM hVolMgr, const char *pszFmt)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMINTERNAL pThis = hVolMgr;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertPtrReturn(pszFmt, VERR_INVALID_POINTER);
+ AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_INVALID_HANDLE);
+
+ for (unsigned i = 0; i < RT_ELEMENTS(g_aDvmFmts); i++)
+ {
+ PCRTDVMFMTOPS pDvmFmtOps = g_aDvmFmts[i];
+
+ if (!RTStrCmp(pDvmFmtOps->pcszFmt, pszFmt))
+ {
+ rc = pDvmFmtOps->pfnInitialize(&pThis->DvmDisk, &pThis->hVolMgrFmt);
+ if (RT_SUCCESS(rc))
+ pThis->pDvmFmtOps = pDvmFmtOps;
+
+ break;
+ }
+ }
+
+ return rc;
+}
+
+RTDECL(const char *) RTDvmMapGetFormat(RTDVM hVolMgr)
+{
+ PRTDVMINTERNAL pThis = hVolMgr;
+ AssertPtrReturn(pThis, NULL);
+ AssertReturn(pThis->u32Magic == RTDVM_MAGIC, NULL);
+ AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, NULL);
+
+ return pThis->pDvmFmtOps->pcszFmt;
+}
+
+RTDECL(uint32_t) RTDvmMapGetValidVolumes(RTDVM hVolMgr)
+{
+ PRTDVMINTERNAL pThis = hVolMgr;
+ AssertPtrReturn(pThis, UINT32_MAX);
+ AssertReturn(pThis->u32Magic == RTDVM_MAGIC, UINT32_MAX);
+ AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, UINT32_MAX);
+
+ return pThis->pDvmFmtOps->pfnGetValidVolumes(pThis->hVolMgrFmt);
+}
+
+RTDECL(uint32_t) RTDvmMapGetMaxVolumes(RTDVM hVolMgr)
+{
+ PRTDVMINTERNAL pThis = hVolMgr;
+ AssertPtrReturn(pThis, UINT32_MAX);
+ AssertReturn(pThis->u32Magic == RTDVM_MAGIC, UINT32_MAX);
+ AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, UINT32_MAX);
+
+ return pThis->pDvmFmtOps->pfnGetMaxVolumes(pThis->hVolMgrFmt);
+}
+
+static int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt,
+ PRTDVMVOLUME phVol)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMVOLUMEINTERNAL pVol = NULL;
+
+ pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL));
+ if (VALID_PTR(pVol))
+ {
+ pVol->u32Magic = RTDVMVOLUME_MAGIC;
+ pVol->cRefs = 1;
+ pVol->pVolMgr = pThis;
+ pVol->hVolFmt = hVolFmt;
+
+ /* Reference the volume manager. */
+ RTDvmRetain(pThis);
+ *phVol = pVol;
+ }
+ else
+ rc = VERR_NO_MEMORY;
+
+ return rc;
+}
+
+RTDECL(int) RTDvmMapQueryFirstVolume(RTDVM hVolMgr, PRTDVMVOLUME phVol)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMINTERNAL pThis = hVolMgr;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_INVALID_HANDLE);
+ AssertPtrReturn(phVol, VERR_INVALID_POINTER);
+
+ RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT;
+ rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt);
+ if (RT_SUCCESS(rc))
+ {
+ rc = rtDvmVolumeCreate(pThis, hVolFmt, phVol);
+ if (RT_FAILURE(rc))
+ pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
+ }
+
+ return rc;
+}
+
+RTDECL(int) RTDvmMapQueryNextVolume(RTDVM hVolMgr, RTDVMVOLUME hVol, PRTDVMVOLUME phVolNext)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMINTERNAL pThis = hVolMgr;
+ PRTDVMVOLUMEINTERNAL pVol = hVol;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_INVALID_HANDLE);
+ AssertPtrReturn(pVol, VERR_INVALID_HANDLE);
+ AssertReturn(pVol->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
+ AssertPtrReturn(phVolNext, VERR_INVALID_POINTER);
+
+ RTDVMVOLUMEFMT hVolFmtNext = NIL_RTDVMVOLUMEFMT;
+ rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmtNext);
+ if (RT_SUCCESS(rc))
+ {
+ rc = rtDvmVolumeCreate(pThis, hVolFmtNext, phVolNext);
+ if (RT_FAILURE(rc))
+ pThis->pDvmFmtOps->pfnVolumeClose(hVolFmtNext);
+ }
+
+ return rc;
+}
+
+RTDECL(uint32_t) RTDvmVolumeRetain(RTDVMVOLUME hVol)
+{
+ PRTDVMVOLUMEINTERNAL pThis = hVol;
+ AssertPtrReturn(pThis, UINT32_MAX);
+ AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, UINT32_MAX);
+
+ uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
+ AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
+ return cRefs;
+}
+
+/**
+ * Destroys a volume handle.
+ *
+ * @param pThis The volume to destroy.
+ */
+static void rtDvmVolumeDestroy(PRTDVMVOLUMEINTERNAL pThis)
+{
+ PRTDVMINTERNAL pVolMgr = pThis->pVolMgr;
+
+ AssertPtr(pVolMgr);
+
+ /* Close the volume. */
+ pVolMgr->pDvmFmtOps->pfnVolumeClose(pThis->hVolFmt);
+
+ pThis->u32Magic = RTDVMVOLUME_MAGIC_DEAD;
+ pThis->pVolMgr = NULL;
+ pThis->hVolFmt = NIL_RTDVMVOLUMEFMT;
+ RTMemFree(pThis);
+
+ /* Release the reference of the volume manager. */
+ RTDvmRelease(pVolMgr);
+}
+
+RTDECL(uint32_t) RTDvmVolumeRelease(RTDVMVOLUME hVol)
+{
+ PRTDVMVOLUMEINTERNAL pThis = hVol;
+ if (pThis == NIL_RTDVMVOLUME)
+ return 0;
+ AssertPtrReturn(pThis, UINT32_MAX);
+ AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, UINT32_MAX);
+
+ uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
+ AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis));
+ if (cRefs == 0)
+ rtDvmVolumeDestroy(pThis);
+ return cRefs;
+}
+
+RTDECL(uint64_t) RTDvmVolumeGetSize(RTDVMVOLUME hVol)
+{
+ PRTDVMVOLUMEINTERNAL pThis = hVol;
+ AssertPtrReturn(pThis, 0);
+ AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, 0);
+
+ return pThis->pVolMgr->pDvmFmtOps->pfnVolumeGetSize(pThis->hVolFmt);
+}
+
+RTDECL(int) RTDvmVolumeQueryName(RTDVMVOLUME hVol, char **ppszVolName)
+{
+ PRTDVMVOLUMEINTERNAL pThis = hVol;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(ppszVolName, VERR_INVALID_POINTER);
+
+ return pThis->pVolMgr->pDvmFmtOps->pfnVolumeQueryName(pThis->hVolFmt, ppszVolName);
+}
+
+RTDECL(RTDVMVOLTYPE) RTDvmVolumeGetType(RTDVMVOLUME hVol)
+{
+ PRTDVMVOLUMEINTERNAL pThis = hVol;
+ AssertPtrReturn(pThis, RTDVMVOLTYPE_INVALID);
+ AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, RTDVMVOLTYPE_INVALID);
+
+ return pThis->pVolMgr->pDvmFmtOps->pfnVolumeGetType(pThis->hVolFmt);
+}
+
+RTDECL(uint64_t) RTDvmVolumeGetFlags(RTDVMVOLUME hVol)
+{
+ PRTDVMVOLUMEINTERNAL pThis = hVol;
+ AssertPtrReturn(pThis, UINT64_MAX);
+ AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, UINT64_MAX);
+
+ return pThis->pVolMgr->pDvmFmtOps->pfnVolumeGetFlags(pThis->hVolFmt);
+}
+
+RTDECL(int) RTDvmVolumeRead(RTDVMVOLUME hVol, uint64_t off, void *pvBuf, size_t cbRead)
+{
+ PRTDVMVOLUMEINTERNAL pThis = hVol;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(pvBuf, VERR_INVALID_POINTER);
+ AssertReturn(cbRead > 0, VERR_INVALID_PARAMETER);
+
+ return pThis->pVolMgr->pDvmFmtOps->pfnVolumeRead(pThis->hVolFmt, off, pvBuf, cbRead);
+}
+
+RTDECL(int) RTDvmVolumeWrite(RTDVMVOLUME hVol, uint64_t off, const void *pvBuf, size_t cbWrite)
+{
+ PRTDVMVOLUMEINTERNAL pThis = hVol;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(pvBuf, VERR_INVALID_POINTER);
+ AssertReturn(cbWrite > 0, VERR_INVALID_PARAMETER);
+
+ return pThis->pVolMgr->pDvmFmtOps->pfnVolumeWrite(pThis->hVolFmt, off, pvBuf, cbWrite);
+}
+
+RTDECL(const char *) RTDvmVolumeTypeGetDescr(RTDVMVOLTYPE enmVolType)
+{
+ AssertReturn(enmVolType >= RTDVMVOLTYPE_INVALID && enmVolType < RTDVMVOLTYPE_END, NULL);
+
+ return g_apcszDvmVolTypes[enmVolType];
+}
diff --git a/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp b/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp
new file mode 100644
index 000000000..e874178df
--- /dev/null
+++ b/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp
@@ -0,0 +1,517 @@
+/* $Id: dvmbsdlabel.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
+/** @file
+ * IPRT Disk Volume Management API (DVM) - BSD disklabel format backend.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#include <iprt/types.h>
+#include <iprt/assert.h>
+#include <iprt/mem.h>
+#include <iprt/dvm.h>
+#include <iprt/string.h>
+#include "internal/dvm.h"
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+
+/*
+ * Below are the on disk structures of a bsd disklabel as found in
+ * /usr/include/sys/disklabel.h from a FreeBSD system.
+ *
+ * Everything is stored in little endian on the disk.
+ */
+
+/** BSD disklabel magic. */
+#define RTDVM_BSDLBL_MAGIC UINT32_C(0x82564557)
+/** Maximum number of partitions in the label. */
+#define RTDVM_BSDLBL_MAX_PARTITIONS 8
+
+/**
+ * A BSD disk label partition.
+ */
+#pragma pack(1)
+typedef struct BsdLabelPartition
+{
+ /** Number of sectors in the partition. */
+ uint32_t cSectors;
+ /** Start sector. */
+ uint32_t offSectorStart;
+ /** Filesystem fragment size. */
+ uint32_t cbFsFragment;
+ /** Filesystem type. */
+ uint8_t bFsType;
+ /** Filesystem fragments per block. */
+ uint8_t cFsFragmentsPerBlock;
+ /** Filesystem cylinders per group. */
+ uint16_t cFsCylPerGroup;
+} BsdLabelPartition;
+#pragma pack()
+AssertCompileSize(BsdLabelPartition, 16);
+/** Pointer to a BSD disklabel partition structure. */
+typedef BsdLabelPartition *PBsdLabelPartition;
+
+/**
+ * On disk BSD label structure.
+ */
+#pragma pack(1)
+typedef struct BsdLabel
+{
+ /** Magic identifying the BSD disk label. */
+ uint32_t u32Magic;
+ /** Drive type */
+ uint16_t u16DriveType;
+ /** Subtype depending on the drive type above. */
+ uint16_t u16SubType;
+ /** Type name. */
+ uint8_t abTypeName[16];
+ /** Pack identifier. */
+ uint8_t abPackName[16];
+ /** Number of bytes per sector. */
+ uint32_t cbSector;
+ /** Number of sectors per track. */
+ uint32_t cSectorsPerTrack;
+ /** Number of tracks per cylinder. */
+ uint32_t cTracksPerCylinder;
+ /** Number of data cylinders pre unit. */
+ uint32_t cDataCylindersPerUnit;
+ /** Number of data sectors per cylinder. */
+ uint32_t cDataSectorsPerCylinder;
+ /** Number of data sectors per unit (unit as in disk drive?). */
+ uint32_t cSectorsPerUnit;
+ /** Number of spare sectors per track. */
+ uint16_t cSpareSectorsPerTrack;
+ /** Number of spare sectors per cylinder. */
+ uint16_t cSpareSectorsPerCylinder;
+ /** Number of alternate cylinders per unit. */
+ uint32_t cSpareCylindersPerUnit;
+ /** Rotational speed of the disk drive in rotations per minute. */
+ uint16_t cRotationsPerMinute;
+ /** Sector interleave. */
+ uint16_t uSectorInterleave;
+ /** Sector 0 skew, per track. */
+ uint16_t uSectorSkewPerTrack;
+ /** Sector 0 skew, per cylinder. */
+ uint16_t uSectorSkewPerCylinder;
+ /** Head switch time in us. */
+ uint32_t usHeadSwitch;
+ /** Time of a track-to-track seek in us. */
+ uint32_t usTrackSeek;
+ /** Flags. */
+ uint32_t fFlags;
+ /** Drive type sepcific information. */
+ uint32_t au32DriveData[5];
+ /** Reserved. */
+ uint32_t au32Reserved[5];
+ /** The magic number again. */
+ uint32_t u32Magic2;
+ /** Checksum (xor of the whole structure). */
+ uint16_t u16ChkSum;
+ /** Number of partitions in the array. */
+ uint16_t cPartitions;
+ /** Boot area size in bytes. */
+ uint32_t cbBootArea;
+ /** Maximum size of the filesystem super block. */
+ uint32_t cbFsSuperBlock;
+ /** The partition array. */
+ BsdLabelPartition aPartitions[RTDVM_BSDLBL_MAX_PARTITIONS];
+} BsdLabel;
+#pragma pack()
+AssertCompileSize(BsdLabel, 148 + RTDVM_BSDLBL_MAX_PARTITIONS * 16);
+/** Pointer to a BSD disklabel structure. */
+typedef BsdLabel *PBsdLabel;
+
+/**
+ * BSD disk label volume manager data.
+ */
+typedef struct RTDVMFMTINTERNAL
+{
+ /** Pointer to the underlying disk. */
+ PCRTDVMDISK pDisk;
+ /** Number of used partitions. */
+ uint32_t cPartitions;
+ /** Saved BSD disklabel structure. */
+ BsdLabel DiskLabel;
+} RTDVMFMTINTERNAL;
+/** Pointer to the MBR volume manager. */
+typedef RTDVMFMTINTERNAL *PRTDVMFMTINTERNAL;
+
+/**
+ * MBR volume data.
+ */
+typedef struct RTDVMVOLUMEFMTINTERNAL
+{
+ /** Pointer to the volume manager. */
+ PRTDVMFMTINTERNAL pVolMgr;
+ /** Partition table entry index. */
+ uint32_t idxEntry;
+ /** Start offset of the volume. */
+ uint64_t offStart;
+ /** Size of the volume. */
+ uint64_t cbVolume;
+ /** Pointer to the raw partition table entry. */
+ PBsdLabelPartition pBsdPartitionEntry;
+} RTDVMVOLUMEFMTINTERNAL;
+/** Pointer to an MBR volume. */
+typedef RTDVMVOLUMEFMTINTERNAL *PRTDVMVOLUMEFMTINTERNAL;
+
+/** Converts a LBA number to the byte offset. */
+#define RTDVM_BSDLBL_LBA2BYTE(lba, disk) ((lba) * (disk)->cbSector)
+/** Converts a Byte offset to the LBA number. */
+#define RTDVM_BSDLBL_BYTE2LBA(lba, disk) ((lba) / (disk)->cbSector)
+
+/**
+ * Calculates the checksum of the entire bsd disklabel structure.
+ *
+ * @returns The checksum.
+ * @param pBsdLabel BSD disklabel to get teh checksum for.
+ */
+static uint16_t rtDvmFmtBsdLblDiskLabelChkSum(PBsdLabel pBsdLabel)
+{
+ uint16_t uChkSum = 0;
+ uint16_t *pCurr = (uint16_t *)pBsdLabel;
+ uint16_t *pEnd = (uint16_t *)&pBsdLabel->aPartitions[pBsdLabel->cPartitions];
+
+ while (pCurr < pEnd)
+ uChkSum ^= *pCurr++;
+
+ return uChkSum;
+}
+
+/**
+ * Converts a partition entry to the host endianness.
+ *
+ * @returns nothing.
+ * @param pPartition The partition to decode.
+ */
+static void rtDvmFmtBsdLblDiskLabelDecodePartition(PBsdLabelPartition pPartition)
+{
+ pPartition->cSectors = RT_LE2H_U32(pPartition->cSectors);
+ pPartition->offSectorStart = RT_LE2H_U32(pPartition->offSectorStart);
+ pPartition->cbFsFragment = RT_LE2H_U32(pPartition->cbFsFragment);
+ pPartition->cFsCylPerGroup = RT_LE2H_U16(pPartition->cFsCylPerGroup);
+}
+
+/**
+ * Converts the on disk BSD label to the host endianness.
+ *
+ * @returns Whether the given label structure is a valid BSD disklabel.
+ * @param pBsdLabel Pointer to the BSD disklabel to decode.
+ */
+static bool rtDvmFmtBsdLblDiskLabelDecode(PBsdLabel pBsdLabel)
+{
+ pBsdLabel->u32Magic = RT_LE2H_U32(pBsdLabel->u32Magic);
+ pBsdLabel->u16DriveType = RT_LE2H_U16(pBsdLabel->u16DriveType);
+ pBsdLabel->u16SubType = RT_LE2H_U16(pBsdLabel->u16SubType);
+ pBsdLabel->cbSector = RT_LE2H_U32(pBsdLabel->cbSector);
+ pBsdLabel->cSectorsPerTrack = RT_LE2H_U32(pBsdLabel->cSectorsPerTrack);
+ pBsdLabel->cTracksPerCylinder = RT_LE2H_U32(pBsdLabel->cTracksPerCylinder);
+ pBsdLabel->cDataCylindersPerUnit = RT_LE2H_U32(pBsdLabel->cDataCylindersPerUnit);
+ pBsdLabel->cDataSectorsPerCylinder = RT_LE2H_U32(pBsdLabel->cDataSectorsPerCylinder);
+ pBsdLabel->cSectorsPerUnit = RT_LE2H_U32(pBsdLabel->cSectorsPerUnit);
+ pBsdLabel->cSpareSectorsPerTrack = RT_LE2H_U16(pBsdLabel->cSpareSectorsPerTrack);
+ pBsdLabel->cSpareSectorsPerCylinder = RT_LE2H_U16(pBsdLabel->cSpareSectorsPerCylinder);
+ pBsdLabel->cSpareCylindersPerUnit = RT_LE2H_U32(pBsdLabel->cSpareCylindersPerUnit);
+ pBsdLabel->cRotationsPerMinute = RT_LE2H_U16(pBsdLabel->cRotationsPerMinute);
+ pBsdLabel->uSectorInterleave = RT_LE2H_U16(pBsdLabel->uSectorInterleave);
+ pBsdLabel->uSectorSkewPerTrack = RT_LE2H_U16(pBsdLabel->uSectorSkewPerTrack);
+ pBsdLabel->uSectorSkewPerCylinder = RT_LE2H_U16(pBsdLabel->uSectorSkewPerCylinder);
+ pBsdLabel->usHeadSwitch = RT_LE2H_U16(pBsdLabel->usHeadSwitch);
+ pBsdLabel->usTrackSeek = RT_LE2H_U16(pBsdLabel->usTrackSeek);
+ pBsdLabel->fFlags = RT_LE2H_U32(pBsdLabel->fFlags);
+
+ for (unsigned i = 0; i < RT_ELEMENTS(pBsdLabel->au32DriveData); i++)
+ pBsdLabel->au32DriveData[i] = RT_LE2H_U32(pBsdLabel->au32DriveData[i]);
+ for (unsigned i = 0; i < RT_ELEMENTS(pBsdLabel->au32Reserved); i++)
+ pBsdLabel->au32Reserved[i] = RT_LE2H_U32(pBsdLabel->au32Reserved[i]);
+
+ pBsdLabel->u32Magic2 = RT_LE2H_U32(pBsdLabel->u32Magic2);
+ pBsdLabel->u16ChkSum = RT_LE2H_U16(pBsdLabel->u16ChkSum);
+ pBsdLabel->cPartitions = RT_LE2H_U16(pBsdLabel->cPartitions);
+ pBsdLabel->cbBootArea = RT_LE2H_U32(pBsdLabel->cbBootArea);
+ pBsdLabel->cbFsSuperBlock = RT_LE2H_U32(pBsdLabel->cbFsSuperBlock);
+
+ /* Check the magics now. */
+ if ( pBsdLabel->u32Magic != RTDVM_BSDLBL_MAGIC
+ || pBsdLabel->u32Magic2 != RTDVM_BSDLBL_MAGIC
+ || pBsdLabel->cPartitions != RTDVM_BSDLBL_MAX_PARTITIONS)
+ return false;
+
+ /* Convert the partitions array. */
+ for (unsigned i = 0; i < RT_ELEMENTS(pBsdLabel->aPartitions); i++)
+ rtDvmFmtBsdLblDiskLabelDecodePartition(&pBsdLabel->aPartitions[i]);
+
+ /* Check the checksum now. */
+ uint16_t u16ChkSumSaved = pBsdLabel->u16ChkSum;
+
+ pBsdLabel->u16ChkSum = 0;
+ if (u16ChkSumSaved != rtDvmFmtBsdLblDiskLabelChkSum(pBsdLabel))
+ return false;
+
+ pBsdLabel->u16ChkSum = u16ChkSumSaved;
+ return true;
+}
+
+DECLCALLBACK(int) rtDvmFmtBsdLblProbe(PCRTDVMDISK pDisk, uint32_t *puScore)
+{
+ BsdLabel DiskLabel;
+ int rc = VINF_SUCCESS;
+
+ *puScore = RTDVM_MATCH_SCORE_UNSUPPORTED;
+
+ if (pDisk->cbDisk >= sizeof(BsdLabel))
+ {
+ /* Read from the disk and check for the disk label structure. */
+ rc = rtDvmDiskRead(pDisk, RTDVM_BSDLBL_LBA2BYTE(1, pDisk), &DiskLabel, sizeof(BsdLabel));
+ if ( RT_SUCCESS(rc)
+ && rtDvmFmtBsdLblDiskLabelDecode(&DiskLabel))
+ *puScore = RTDVM_MATCH_SCORE_PERFECT;
+ }
+ return rc;
+}
+
+DECLCALLBACK(int) rtDvmFmtBsdLblOpen(PCRTDVMDISK pDisk, PRTDVMFMT phVolMgrFmt)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMFMTINTERNAL pThis = NULL;
+
+ pThis = (PRTDVMFMTINTERNAL)RTMemAllocZ(sizeof(RTDVMFMTINTERNAL));
+ if (VALID_PTR(pThis))
+ {
+ pThis->pDisk = pDisk;
+ pThis->cPartitions = 0;
+
+ /* Read from the disk and check for the disk label structure. */
+ rc = rtDvmDiskRead(pDisk, RTDVM_BSDLBL_LBA2BYTE(1, pDisk), &pThis->DiskLabel, sizeof(BsdLabel));
+ if ( RT_SUCCESS(rc)
+ && rtDvmFmtBsdLblDiskLabelDecode(&pThis->DiskLabel))
+ {
+ /* Count number of used entries. */
+ for (unsigned i = 0; i < pThis->DiskLabel.cPartitions; i++)
+ if (pThis->DiskLabel.aPartitions[i].cSectors)
+ pThis->cPartitions++;
+
+ *phVolMgrFmt = pThis;
+ }
+ else
+ {
+ RTMemFree(pThis);
+ rc = VERR_INVALID_MAGIC;
+ }
+ }
+ else
+ rc = VERR_NO_MEMORY;
+
+ return rc;
+}
+
+DECLCALLBACK(int) rtDvmFmtBsdLblInitialize(PCRTDVMDISK pDisk, PRTDVMFMT phVolMgrFmt)
+{
+ return VERR_NOT_IMPLEMENTED;
+}
+
+DECLCALLBACK(void) rtDvmFmtBsdLblClose(RTDVMFMT hVolMgrFmt)
+{
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+
+ pThis->pDisk = NULL;
+ pThis->cPartitions = 0;
+ memset(&pThis->DiskLabel, 0, sizeof(BsdLabel));
+ RTMemFree(pThis);
+}
+
+DECLCALLBACK(uint32_t) rtDvmFmtBsdLblGetValidVolumes(RTDVMFMT hVolMgrFmt)
+{
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+ return pThis->cPartitions;
+}
+
+DECLCALLBACK(uint32_t) rtDvmFmtBsdLblGetMaxVolumes(RTDVMFMT hVolMgrFmt)
+{
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+ return pThis->DiskLabel.cPartitions;
+}
+
+/**
+ * Creates a new volume.
+ *
+ * @returns IPRT status code.
+ * @param pThis The MBR volume manager data.
+ * @param pbBsdLblEntry The raw MBR entry data.
+ * @param idx The index in the partition table.
+ * @param phVolFmt Where to store the volume data on success.
+ */
+static int rtDvmFmtBsdLblVolumeCreate(PRTDVMFMTINTERNAL pThis, PBsdLabelPartition pBsdPartitionEntry,
+ uint32_t idx, PRTDVMVOLUMEFMT phVolFmt)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMVOLUMEFMTINTERNAL pVol = (PRTDVMVOLUMEFMTINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEFMTINTERNAL));
+
+ if (VALID_PTR(pVol))
+ {
+ pVol->pVolMgr = pThis;
+ pVol->idxEntry = idx;
+ pVol->pBsdPartitionEntry = pBsdPartitionEntry;
+ pVol->offStart = pBsdPartitionEntry->offSectorStart * pThis->DiskLabel.cbSector;
+ pVol->cbVolume = pBsdPartitionEntry->cSectors * pThis->DiskLabel.cbSector;
+
+ *phVolFmt = pVol;
+ }
+ else
+ rc = VERR_NO_MEMORY;
+
+ return rc;
+}
+
+DECLCALLBACK(int) rtDvmFmtBsdLblQueryFirstVolume(RTDVMFMT hVolMgrFmt, PRTDVMVOLUMEFMT phVolFmt)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+
+ if (pThis->cPartitions != 0)
+ {
+ /* Search for the first non empty entry. */
+ for (unsigned i = 0; i < pThis->DiskLabel.cPartitions; i++)
+ {
+ if (pThis->DiskLabel.aPartitions[i].cSectors)
+ {
+ rc = rtDvmFmtBsdLblVolumeCreate(pThis, &pThis->DiskLabel.aPartitions[i],
+ i, phVolFmt);
+ break;
+ }
+ }
+ }
+ else
+ rc = VERR_DVM_MAP_EMPTY;
+
+ return rc;
+}
+
+DECLCALLBACK(int) rtDvmFmtBsdLblQueryNextVolume(RTDVMFMT hVolMgrFmt, RTDVMVOLUMEFMT hVolFmt, PRTDVMVOLUMEFMT phVolFmtNext)
+{
+ int rc = VERR_DVM_MAP_NO_VOLUME;
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+ PBsdLabelPartition pBsdPartitionEntry = pVol->pBsdPartitionEntry + 1;
+
+ for (unsigned i = pVol->idxEntry + 1; i < pThis->DiskLabel.cPartitions; i++)
+ {
+ if (pBsdPartitionEntry->cSectors)
+ {
+ rc = rtDvmFmtBsdLblVolumeCreate(pThis, pBsdPartitionEntry, i, phVolFmtNext);
+ break;
+ }
+ pBsdPartitionEntry++;
+ }
+
+ return rc;
+}
+
+DECLCALLBACK(void) rtDvmFmtBsdLblVolumeClose(RTDVMVOLUMEFMT hVolFmt)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+
+ pVol->pVolMgr = NULL;
+ pVol->offStart = 0;
+ pVol->cbVolume = 0;
+ pVol->pBsdPartitionEntry = NULL;
+
+ RTMemFree(pVol);
+}
+
+DECLCALLBACK(uint64_t) rtDvmFmtBsdLblVolumeGetSize(RTDVMVOLUMEFMT hVolFmt)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+
+ return pVol->cbVolume;
+}
+
+DECLCALLBACK(int) rtDvmFmtBsdLblVolumeQueryName(RTDVMVOLUMEFMT hVolFmt, char **ppszVolName)
+{
+ NOREF(hVolFmt);
+ return VERR_NOT_SUPPORTED;
+}
+
+DECLCALLBACK(RTDVMVOLTYPE) rtDvmFmtBsdLblVolumeGetType(RTDVMVOLUMEFMT hVolFmt)
+{
+ return RTDVMVOLTYPE_UNKNOWN;
+}
+
+DECLCALLBACK(uint64_t) rtDvmFmtBsdLblVolumeGetFlags(RTDVMVOLUMEFMT hVolFmt)
+{
+ NOREF(hVolFmt);
+ return 0;
+}
+
+DECLCALLBACK(int) rtDvmFmtBsdLblVolumeRead(RTDVMVOLUMEFMT hVolFmt, uint64_t off, void *pvBuf, size_t cbRead)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+ AssertReturn(off + cbRead <= pVol->cbVolume, VERR_INVALID_PARAMETER);
+
+ return rtDvmDiskRead(pVol->pVolMgr->pDisk, pVol->offStart + off, pvBuf, cbRead);
+}
+
+DECLCALLBACK(int) rtDvmFmtBsdLblVolumeWrite(RTDVMVOLUMEFMT hVolFmt, uint64_t off, const void *pvBuf, size_t cbWrite)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+ AssertReturn(off + cbWrite <= pVol->cbVolume, VERR_INVALID_PARAMETER);
+
+ return rtDvmDiskWrite(pVol->pVolMgr->pDisk, pVol->offStart + off, pvBuf, cbWrite);
+}
+
+DECLHIDDEN(RTDVMFMTOPS) g_rtDvmFmtBsdLbl =
+{
+ /* pcszFmt */
+ "BsdLabel",
+ /* pfnProbe */
+ rtDvmFmtBsdLblProbe,
+ /* pfnOpen */
+ rtDvmFmtBsdLblOpen,
+ /* pfnInitialize */
+ rtDvmFmtBsdLblInitialize,
+ /* pfnClose */
+ rtDvmFmtBsdLblClose,
+ /* pfnGetValidVolumes */
+ rtDvmFmtBsdLblGetValidVolumes,
+ /* pfnGetMaxVolumes */
+ rtDvmFmtBsdLblGetMaxVolumes,
+ /* pfnQueryFirstVolume */
+ rtDvmFmtBsdLblQueryFirstVolume,
+ /* pfnQueryNextVolume */
+ rtDvmFmtBsdLblQueryNextVolume,
+ /* pfnVolumeClose */
+ rtDvmFmtBsdLblVolumeClose,
+ /* pfnVolumeGetSize */
+ rtDvmFmtBsdLblVolumeGetSize,
+ /* pfnVolumeQueryName */
+ rtDvmFmtBsdLblVolumeQueryName,
+ /* pfnVolumeGetType */
+ rtDvmFmtBsdLblVolumeGetType,
+ /* pfnVolumeGetFlags */
+ rtDvmFmtBsdLblVolumeGetFlags,
+ /* pfnVolumeRead */
+ rtDvmFmtBsdLblVolumeRead,
+ /* pfnVolumeWrite */
+ rtDvmFmtBsdLblVolumeWrite
+};
+
diff --git a/src/VBox/Runtime/common/dvm/dvmgpt.cpp b/src/VBox/Runtime/common/dvm/dvmgpt.cpp
new file mode 100644
index 000000000..e478343de
--- /dev/null
+++ b/src/VBox/Runtime/common/dvm/dvmgpt.cpp
@@ -0,0 +1,536 @@
+/* $Id: dvmgpt.cpp 37024 2011-05-10 11:23:44Z vboxsync $ */
+/** @file
+ * IPRT Disk Volume Management API (DVM) - GPT format backend.
+ */
+
+/*
+ * 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.
+ *
+ * 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/types.h>
+#include <iprt/assert.h>
+#include <iprt/mem.h>
+#include <iprt/dvm.h>
+#include <iprt/string.h>
+#include <iprt/uuid.h>
+#include "internal/dvm.h"
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/** The GPT signature. */
+#define RTDVM_GPT_SIGNATURE "EFI PART"
+
+/**
+ * GPT on disk header.
+ */
+#pragma pack(1)
+typedef struct GptHdr
+{
+ /** Signature ("EFI PART"). */
+ char abSignature[8];
+ /** Revision. */
+ uint32_t u32Revision;
+ /** Header size. */
+ uint32_t cbHeader;
+ /** CRC of header. */
+ uint32_t u32Crc;
+} GptHdr;
+/** Pointer to a GPT header. */
+typedef struct GptHdr *PGptHdr;
+#pragma pack()
+AssertCompileSize(GptHdr, 20);
+
+/**
+ * Complete GPT table header for revision 1.0.
+ */
+#pragma pack(1)
+typedef struct GptHdrRev1
+{
+ /** Header. */
+ GptHdr Hdr;
+ /** Reserved. */
+ uint32_t u32Reserved;
+ /** Current LBA. */
+ uint64_t u64LbaCurrent;
+ /** Backup LBA. */
+ uint64_t u64LbaBackup;
+ /** First usable LBA for partitions. */
+ uint64_t u64LbaFirstPartition;
+ /** Last usable LBA for partitions. */
+ uint64_t u64LbaLastPartition;
+ /** Disk UUID. */
+ RTUUID DiskUuid;
+ /** LBA of first partition entry. */
+ uint64_t u64LbaPartitionEntries;
+ /** Number of partition entries. */
+ uint32_t cPartitionEntries;
+ /** Partition entry size. */
+ uint32_t cbPartitionEntry;
+ /** CRC of partition entries. */
+ uint32_t u32CrcPartitionEntries;
+} GptHdrRev1;
+/** Pointer to a revision 1.0 GPT header. */
+typedef GptHdrRev1 *PGptHdrRev1;
+#pragma pack()
+AssertCompileSize(GptHdrRev1, 92);
+
+/**
+ * GPT partition table entry.
+ */
+#pragma pack(1)
+typedef struct GptEntry
+{
+ /** Partition type UUID. */
+ RTUUID UuidType;
+ /** Partition UUID. */
+ RTUUID UuidPartition;
+ /** First LBA. */
+ uint64_t u64LbaFirst;
+ /** Last LBA. */
+ uint64_t u64LbaLast;
+ /** Attribute flags. */
+ uint64_t u64Flags;
+ /** Partition name (UTF-16LE code units). */
+ RTUTF16 aPartitionName[36];
+} GptEntry;
+/** Pointer to a GPT entry. */
+typedef struct GptEntry *PGptEntry;
+#pragma pack()
+AssertCompileSize(GptEntry, 128);
+
+/** Partition flags - System partition. */
+#define RTDVM_GPT_ENTRY_SYSTEM RT_BIT_64(0)
+/** Partition flags - Partition is readonly. */
+#define RTDVM_GPT_ENTRY_READONLY RT_BIT_64(60)
+/** Partition flags - Partition is hidden. */
+#define RTDVM_GPT_ENTRY_HIDDEN RT_BIT_64(62)
+/** Partition flags - Don't automount this partition. */
+#define RTDVM_GPT_ENTRY_NO_AUTOMOUNT RT_BIT_64(63)
+
+/**
+ * GPT volume manager data.
+ */
+typedef struct RTDVMFMTINTERNAL
+{
+ /** Pointer to the underlying disk. */
+ PCRTDVMDISK pDisk;
+ /** GPT header. */
+ GptHdrRev1 HdrRev1;
+ /** GPT array. */
+ PGptEntry paGptEntries;
+ /** Number of occupied partition entries. */
+ uint32_t cPartitions;
+} RTDVMFMTINTERNAL;
+/** Pointer to the MBR volume manager. */
+typedef RTDVMFMTINTERNAL *PRTDVMFMTINTERNAL;
+
+/**
+ * GPT volume data.
+ */
+typedef struct RTDVMVOLUMEFMTINTERNAL
+{
+ /** Pointer to the volume manager. */
+ PRTDVMFMTINTERNAL pVolMgr;
+ /** Partition table entry index. */
+ uint32_t idxEntry;
+ /** Start offset of the volume. */
+ uint64_t offStart;
+ /** Size of the volume. */
+ uint64_t cbVolume;
+ /** Pointer to the GPT entry in the array. */
+ PGptEntry pGptEntry;
+} RTDVMVOLUMEFMTINTERNAL;
+/** Pointer to an MBR volume. */
+typedef RTDVMVOLUMEFMTINTERNAL *PRTDVMVOLUMEFMTINTERNAL;
+
+/**
+ * GPT partition type to DVM volume type mapping entry.
+ */
+
+typedef struct RTDVMGPTPARTTYPE2VOLTYPE
+{
+ /** Type UUID. */
+ const char *pcszUuid;
+ /** DVM volume type. */
+ RTDVMVOLTYPE enmVolType;
+} RTDVMGPTPARTTYPE2VOLTYPE;
+/** Pointer to a MBR FS Type to volume type mapping entry. */
+typedef RTDVMGPTPARTTYPE2VOLTYPE *PRTDVMGPTPARTTYPE2VOLTYPE;
+
+/** Converts a LBA number to the byte offset. */
+#define RTDVM_GPT_LBA2BYTE(lba, disk) ((lba) * (disk)->cbSector)
+/** Converts a Byte offset to the LBA number. */
+#define RTDVM_GPT_BYTE2LBA(lba, disk) ((lba) / (disk)->cbSector)
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/**
+ * Mapping of partition types to DVM volume types.
+ *
+ * From http://en.wikipedia.org/wiki/GUID_Partition_Table
+ */
+static const RTDVMGPTPARTTYPE2VOLTYPE g_aPartType2DvmVolTypes[] =
+{
+ {"0657FD6D-A4AB-43C4-84E5-0933C84B4F4F", RTDVMVOLTYPE_LINUX_SWAP},
+ {"EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", RTDVMVOLTYPE_LINUX_NATIVE},
+ {"E6D6D379-F507-44C2-A23C-238F2A3DF928", RTDVMVOLTYPE_LINUX_LVM},
+ {"A19D880F-05FC-4D3B-A006-743F0F84911E", RTDVMVOLTYPE_LINUX_SOFTRAID},
+
+ {"83BD6B9D-7F41-11DC-BE0B-001560B84F0F", RTDVMVOLTYPE_FREEBSD}, /* Boot */
+ {"516E7CB4-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD}, /* Data */
+ {"516E7CB5-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD}, /* Swap */
+ {"516E7CB6-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD}, /* UFS */
+ {"516E7CB8-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD}, /* Vinum */
+ {"516E7CBA-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD}, /* ZFS */
+
+ {"49F48D32-B10E-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD}, /* Swap */
+ {"49F48D5A-B10E-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD}, /* FFS */
+ {"49F48D82-B10E-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD}, /* LFS */
+ {"49F48DAA-B10E-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD}, /* Raid */
+ {"2DB519C4-B10F-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD}, /* Concatenated */
+ {"2DB519EC-B10F-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD}, /* Encrypted */
+
+ {"48465300-0000-11AA-AA11-00306543ECAC", RTDVMVOLTYPE_MAC_OSX_HFS},
+
+ {"6A82CB45-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* Boot */
+ {"6A85CF4D-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* Root */
+ {"6A87C46F-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* Swap */
+ {"6A8B642B-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* Backup */
+ {"6A898CC3-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* /usr */
+ {"6A8EF2E9-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* /var */
+ {"6A90BA39-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* /home */
+ {"6A9283A5-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* Alternate sector */
+};
+
+static DECLCALLBACK(int) rtDvmFmtGptProbe(PCRTDVMDISK pDisk, uint32_t *puScore)
+{
+ int rc = VINF_SUCCESS;
+ GptHdr Hdr;
+
+ *puScore = RTDVM_MATCH_SCORE_UNSUPPORTED;
+
+ if (rtDvmDiskGetSectors(pDisk) >= 2)
+ {
+ /* Read from the disk and check for the signature. */
+ rc = rtDvmDiskRead(pDisk, RTDVM_GPT_LBA2BYTE(1, pDisk), &Hdr, sizeof(GptHdr));
+ if ( RT_SUCCESS(rc)
+ && !strncmp(&Hdr.abSignature[0], RTDVM_GPT_SIGNATURE, RT_ELEMENTS(Hdr.abSignature))
+ && RT_LE2H_U32(Hdr.u32Revision) == 0x00010000
+ && RT_LE2H_U32(Hdr.cbHeader) == sizeof(GptHdrRev1))
+ *puScore = RTDVM_MATCH_SCORE_PERFECT;
+ }
+
+ return rc;
+}
+
+static DECLCALLBACK(int) rtDvmFmtGptOpen(PCRTDVMDISK pDisk, PRTDVMFMT phVolMgrFmt)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMFMTINTERNAL pThis = NULL;
+
+ pThis = (PRTDVMFMTINTERNAL)RTMemAllocZ(sizeof(RTDVMFMTINTERNAL));
+ if (VALID_PTR(pThis))
+ {
+ pThis->pDisk = pDisk;
+ pThis->cPartitions = 0;
+
+ /* Read the complete GPT header and convert to host endianess. */
+ rc = rtDvmDiskRead(pDisk, RTDVM_GPT_LBA2BYTE(1, pDisk), &pThis->HdrRev1, sizeof(pThis->HdrRev1));
+ if (RT_SUCCESS(rc))
+ {
+ pThis->HdrRev1.Hdr.u32Revision = RT_LE2H_U32(pThis->HdrRev1.Hdr.u32Revision);
+ pThis->HdrRev1.Hdr.cbHeader = RT_LE2H_U32(pThis->HdrRev1.Hdr.cbHeader);
+ pThis->HdrRev1.Hdr.u32Crc = RT_LE2H_U32(pThis->HdrRev1.Hdr.u32Crc);
+ pThis->HdrRev1.u64LbaCurrent = RT_LE2H_U64(pThis->HdrRev1.u64LbaCurrent);
+ pThis->HdrRev1.u64LbaBackup = RT_LE2H_U64(pThis->HdrRev1.u64LbaBackup);
+ pThis->HdrRev1.u64LbaFirstPartition = RT_LE2H_U64(pThis->HdrRev1.u64LbaFirstPartition);
+ pThis->HdrRev1.u64LbaLastPartition = RT_LE2H_U64(pThis->HdrRev1.u64LbaLastPartition);
+ /** @todo: Disk UUID */
+ pThis->HdrRev1.u64LbaPartitionEntries = RT_LE2H_U64(pThis->HdrRev1.u64LbaPartitionEntries);
+ pThis->HdrRev1.cPartitionEntries = RT_LE2H_U32(pThis->HdrRev1.cPartitionEntries);
+ pThis->HdrRev1.cbPartitionEntry = RT_LE2H_U32(pThis->HdrRev1.cbPartitionEntry);
+ pThis->HdrRev1.u32CrcPartitionEntries = RT_LE2H_U32(pThis->HdrRev1.u32CrcPartitionEntries);
+
+ if (pThis->HdrRev1.cbPartitionEntry == sizeof(GptEntry))
+ {
+ pThis->paGptEntries = (PGptEntry)RTMemAllocZ(pThis->HdrRev1.cPartitionEntries * pThis->HdrRev1.cbPartitionEntry);
+ if (VALID_PTR(pThis->paGptEntries))
+ {
+ rc = rtDvmDiskRead(pDisk, RTDVM_GPT_LBA2BYTE(pThis->HdrRev1.u64LbaPartitionEntries, pDisk),
+ pThis->paGptEntries, pThis->HdrRev1.cPartitionEntries * pThis->HdrRev1.cbPartitionEntry);
+ if (RT_SUCCESS(rc))
+ {
+ /* Count the occupied entries. */
+ for (unsigned i = 0; i < pThis->HdrRev1.cPartitionEntries; i++)
+ if (!RTUuidIsNull(&pThis->paGptEntries[i].UuidType))
+ {
+ /* Convert to host endianess. */
+ /** @todo: Uuids */
+ pThis->paGptEntries[i].u64LbaFirst = RT_LE2H_U64(pThis->paGptEntries[i].u64LbaFirst);
+ pThis->paGptEntries[i].u64LbaLast = RT_LE2H_U64(pThis->paGptEntries[i].u64LbaLast);
+ pThis->paGptEntries[i].u64Flags = RT_LE2H_U64(pThis->paGptEntries[i].u64Flags);
+ for (unsigned cwc = 0; cwc < RT_ELEMENTS(pThis->paGptEntries[i].aPartitionName); cwc++)
+ pThis->paGptEntries[i].aPartitionName[cwc] = RT_LE2H_U16(pThis->paGptEntries[i].aPartitionName[cwc]);
+
+ pThis->cPartitions++;
+ }
+ }
+
+ if (RT_FAILURE(rc))
+ RTMemFree(pThis->paGptEntries);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ }
+ else
+ rc = VERR_NOT_SUPPORTED;
+
+ if (RT_SUCCESS(rc))
+ *phVolMgrFmt = pThis;
+ else
+ RTMemFree(pThis);
+ }
+ }
+ else
+ rc = VERR_NO_MEMORY;
+
+ return rc;
+}
+
+static DECLCALLBACK(int) rtDvmFmtGptInitialize(PCRTDVMDISK pDisk, PRTDVMFMT phVolMgrFmt)
+{
+ return VERR_NOT_IMPLEMENTED;
+}
+
+static DECLCALLBACK(void) rtDvmFmtGptClose(RTDVMFMT hVolMgrFmt)
+{
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+
+ pThis->pDisk = NULL;
+ memset(&pThis->HdrRev1, 0, sizeof(pThis->HdrRev1));
+ RTMemFree(pThis->paGptEntries);
+
+ pThis->paGptEntries = NULL;
+ RTMemFree(pThis);
+}
+
+static DECLCALLBACK(uint32_t) rtDvmFmtGptGetValidVolumes(RTDVMFMT hVolMgrFmt)
+{
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+
+ return pThis->cPartitions;
+}
+
+static DECLCALLBACK(uint32_t) rtDvmFmtGptGetMaxVolumes(RTDVMFMT hVolMgrFmt)
+{
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+
+ return pThis->HdrRev1.cPartitionEntries;
+}
+
+/**
+ * Creates a new volume.
+ *
+ * @returns IPRT status code.
+ * @param pThis The MBR volume manager data.
+ * @param pGptEntry The GPT entry.
+ * @param idx The index in the partition array.
+ * @param phVolFmt Where to store the volume data on success.
+ */
+static int rtDvmFmtMbrVolumeCreate(PRTDVMFMTINTERNAL pThis, PGptEntry pGptEntry,
+ uint32_t idx, PRTDVMVOLUMEFMT phVolFmt)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMVOLUMEFMTINTERNAL pVol = (PRTDVMVOLUMEFMTINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEFMTINTERNAL));
+
+ if (VALID_PTR(pVol))
+ {
+ pVol->pVolMgr = pThis;
+ pVol->idxEntry = idx;
+ pVol->pGptEntry = pGptEntry;
+ pVol->offStart = RTDVM_GPT_LBA2BYTE(pGptEntry->u64LbaFirst, pThis->pDisk);
+ pVol->cbVolume = RTDVM_GPT_LBA2BYTE(pGptEntry->u64LbaLast - pGptEntry->u64LbaFirst + 1, pThis->pDisk);
+
+ *phVolFmt = pVol;
+ }
+ else
+ rc = VERR_NO_MEMORY;
+
+ return rc;
+}
+
+static DECLCALLBACK(int) rtDvmFmtGptQueryFirstVolume(RTDVMFMT hVolMgrFmt, PRTDVMVOLUMEFMT phVolFmt)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+
+ if (pThis->cPartitions != 0)
+ {
+ PGptEntry pGptEntry = &pThis->paGptEntries[0];
+
+ /* Search for the first non empty entry. */
+ for (unsigned i = 0; i < pThis->HdrRev1.cPartitionEntries; i++)
+ {
+ if (!RTUuidIsNull(&pGptEntry->UuidType))
+ {
+ rc = rtDvmFmtMbrVolumeCreate(pThis, pGptEntry, i, phVolFmt);
+ break;
+ }
+ pGptEntry++;
+ }
+ }
+ else
+ rc = VERR_DVM_MAP_EMPTY;
+
+ return rc;
+}
+
+static DECLCALLBACK(int) rtDvmFmtGptQueryNextVolume(RTDVMFMT hVolMgrFmt, RTDVMVOLUMEFMT hVolFmt, PRTDVMVOLUMEFMT phVolFmtNext)
+{
+ int rc = VERR_DVM_MAP_NO_VOLUME;
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+ PGptEntry pGptEntry = pVol->pGptEntry + 1;
+
+ for (unsigned i = pVol->idxEntry + 1; i < pThis->HdrRev1.cPartitionEntries; i++)
+ {
+ if (!RTUuidIsNull(&pGptEntry->UuidType))
+ {
+ rc = rtDvmFmtMbrVolumeCreate(pThis, pGptEntry, i, phVolFmtNext);
+ break;
+ }
+ pGptEntry++;
+ }
+
+ return rc;
+}
+
+static DECLCALLBACK(void) rtDvmFmtGptVolumeClose(RTDVMVOLUMEFMT hVolFmt)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+
+ pVol->pVolMgr = NULL;
+ pVol->offStart = 0;
+ pVol->cbVolume = 0;
+ pVol->pGptEntry = NULL;
+
+ RTMemFree(pVol);
+}
+
+static DECLCALLBACK(uint64_t) rtDvmFmtGptVolumeGetSize(RTDVMVOLUMEFMT hVolFmt)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+
+ return pVol->cbVolume;
+}
+
+static DECLCALLBACK(int) rtDvmFmtGptVolumeQueryName(RTDVMVOLUMEFMT hVolFmt, char **ppszVolName)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+ int rc = VINF_SUCCESS;
+
+ *ppszVolName = NULL;
+ rc = RTUtf16ToUtf8Ex(&pVol->pGptEntry->aPartitionName[0], RT_ELEMENTS(pVol->pGptEntry->aPartitionName),
+ ppszVolName, 0, NULL);
+
+ return rc;
+}
+
+static DECLCALLBACK(RTDVMVOLTYPE) rtDvmFmtGptVolumeGetType(RTDVMVOLUMEFMT hVolFmt)
+{
+ RTDVMVOLTYPE enmVolType = RTDVMVOLTYPE_UNKNOWN;
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+
+ for (unsigned i = 0; i < RT_ELEMENTS(g_aPartType2DvmVolTypes); i++)
+ if (!RTUuidCompareStr(&pVol->pGptEntry->UuidType, g_aPartType2DvmVolTypes[i].pcszUuid))
+ {
+ enmVolType = g_aPartType2DvmVolTypes[i].enmVolType;
+ break;
+ }
+
+ return enmVolType;
+}
+
+static DECLCALLBACK(uint64_t) rtDvmFmtGptVolumeGetFlags(RTDVMVOLUMEFMT hVolFmt)
+{
+ NOREF(hVolFmt); /* No supported flags for now. */
+ return 0;
+}
+
+static DECLCALLBACK(int) rtDvmFmtGptVolumeRead(RTDVMVOLUMEFMT hVolFmt, uint64_t off, void *pvBuf, size_t cbRead)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+ AssertReturn(off + cbRead <= pVol->cbVolume, VERR_INVALID_PARAMETER);
+
+ return rtDvmDiskRead(pVol->pVolMgr->pDisk, pVol->offStart + off, pvBuf, cbRead);
+}
+
+static DECLCALLBACK(int) rtDvmFmtGptVolumeWrite(RTDVMVOLUMEFMT hVolFmt, uint64_t off, const void *pvBuf, size_t cbWrite)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+ AssertReturn(off + cbWrite <= pVol->cbVolume, VERR_INVALID_PARAMETER);
+
+ return rtDvmDiskWrite(pVol->pVolMgr->pDisk, pVol->offStart + off, pvBuf, cbWrite);
+}
+
+RTDVMFMTOPS g_rtDvmFmtGpt =
+{
+ /* pcszFmt */
+ "GPT",
+ /* pfnProbe */
+ rtDvmFmtGptProbe,
+ /* pfnOpen */
+ rtDvmFmtGptOpen,
+ /* pfnInitialize */
+ rtDvmFmtGptInitialize,
+ /* pfnClose */
+ rtDvmFmtGptClose,
+ /* pfnGetValidVolumes */
+ rtDvmFmtGptGetValidVolumes,
+ /* pfnGetMaxVolumes */
+ rtDvmFmtGptGetMaxVolumes,
+ /* pfnQueryFirstVolume */
+ rtDvmFmtGptQueryFirstVolume,
+ /* pfnQueryNextVolume */
+ rtDvmFmtGptQueryNextVolume,
+ /* pfnVolumeClose */
+ rtDvmFmtGptVolumeClose,
+ /* pfnVolumeGetSize */
+ rtDvmFmtGptVolumeGetSize,
+ /* pfnVolumeQueryName */
+ rtDvmFmtGptVolumeQueryName,
+ /* pfnVolumeGetType */
+ rtDvmFmtGptVolumeGetType,
+ /* pfnVolumeGetFlags */
+ rtDvmFmtGptVolumeGetFlags,
+ /* pfnVolumeRead */
+ rtDvmFmtGptVolumeRead,
+ /* pfnVolumeWrite */
+ rtDvmFmtGptVolumeWrite
+};
+
diff --git a/src/VBox/Runtime/common/dvm/dvmmbr.cpp b/src/VBox/Runtime/common/dvm/dvmmbr.cpp
new file mode 100644
index 000000000..38700ad3b
--- /dev/null
+++ b/src/VBox/Runtime/common/dvm/dvmmbr.cpp
@@ -0,0 +1,406 @@
+/* $Id: dvmmbr.cpp 37024 2011-05-10 11:23:44Z vboxsync $ */
+/** @file
+ * IPRT Disk Volume Management API (DVM) - MBR format backend.
+ */
+
+/*
+ * 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.
+ *
+ * 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/types.h>
+#include <iprt/assert.h>
+#include <iprt/mem.h>
+#include <iprt/dvm.h>
+#include <iprt/string.h>
+#include "internal/dvm.h"
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+
+/**
+ * MBR volume manager data.
+ */
+typedef struct RTDVMFMTINTERNAL
+{
+ /** Pointer to the underlying disk. */
+ PCRTDVMDISK pDisk;
+ /** Number of initialized partitions. */
+ uint32_t cPartitions;
+ /** The raw MBR data. */
+ uint8_t abMbr[512];
+} RTDVMFMTINTERNAL;
+/** Pointer to the MBR volume manager. */
+typedef RTDVMFMTINTERNAL *PRTDVMFMTINTERNAL;
+
+/**
+ * MBR volume data.
+ */
+typedef struct RTDVMVOLUMEFMTINTERNAL
+{
+ /** Pointer to the volume manager. */
+ PRTDVMFMTINTERNAL pVolMgr;
+ /** Partition table entry index. */
+ uint32_t idxEntry;
+ /** Start offset of the volume. */
+ uint64_t offStart;
+ /** Size of the volume. */
+ uint64_t cbVolume;
+ /** Pointer to the raw partition table entry. */
+ uint8_t *pbMbrEntry;
+} RTDVMVOLUMEFMTINTERNAL;
+/** Pointer to an MBR volume. */
+typedef RTDVMVOLUMEFMTINTERNAL *PRTDVMVOLUMEFMTINTERNAL;
+
+/**
+ * MBR FS type to DVM volume type mapping entry.
+ */
+
+typedef struct RTDVMMBRFS2VOLTYPE
+{
+ /** MBR FS Id. */
+ uint8_t bFsId;
+ /** DVM volume type. */
+ RTDVMVOLTYPE enmVolType;
+} RTDVMMBRFS2VOLTYPE;
+/** Pointer to a MBR FS Type to volume type mapping entry. */
+typedef RTDVMMBRFS2VOLTYPE *PRTDVMMBRFS2VOLTYPE;
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/**
+ * Mapping of FS types to DVM volume types.
+ *
+ * From http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
+ */
+static const RTDVMMBRFS2VOLTYPE g_aFs2DvmVolTypes[] =
+{
+ { 0x06, RTDVMVOLTYPE_FAT16 },
+ { 0x07, RTDVMVOLTYPE_NTFS }, /* Simplification: Used for HPFS, exFAT, ++, too but NTFS is the more common one. */
+ { 0x0b, RTDVMVOLTYPE_FAT32 },
+ { 0x0c, RTDVMVOLTYPE_FAT32 },
+ { 0x82, RTDVMVOLTYPE_LINUX_SWAP },
+ { 0x83, RTDVMVOLTYPE_LINUX_NATIVE },
+ { 0x8e, RTDVMVOLTYPE_LINUX_LVM },
+ { 0xa5, RTDVMVOLTYPE_FREEBSD },
+ { 0xa9, RTDVMVOLTYPE_NETBSD },
+ { 0xa6, RTDVMVOLTYPE_OPENBSD },
+ { 0xaf, RTDVMVOLTYPE_MAC_OSX_HFS },
+ { 0xbf, RTDVMVOLTYPE_SOLARIS },
+ { 0xfd, RTDVMVOLTYPE_LINUX_SOFTRAID }
+};
+
+static DECLCALLBACK(int) rtDvmFmtMbrProbe(PCRTDVMDISK pDisk, uint32_t *puScore)
+{
+ int rc = VINF_SUCCESS;
+ uint8_t abMbr[512];
+
+ *puScore = RTDVM_MATCH_SCORE_UNSUPPORTED;
+
+ if (pDisk->cbDisk >= 512)
+ {
+ /* Read from the disk and check for the 0x55aa signature at the end. */
+ rc = rtDvmDiskRead(pDisk, 0, &abMbr[0], sizeof(abMbr));
+ if ( RT_SUCCESS(rc)
+ && abMbr[510] == 0x55
+ && abMbr[511] == 0xaa)
+ *puScore = RTDVM_MATCH_SCORE_SUPPORTED; /* Not perfect because GPTs have a protective MBR. */
+ }
+
+ return rc;
+}
+
+static DECLCALLBACK(int) rtDvmFmtMbrOpen(PCRTDVMDISK pDisk, PRTDVMFMT phVolMgrFmt)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMFMTINTERNAL pThis = NULL;
+
+ pThis = (PRTDVMFMTINTERNAL)RTMemAllocZ(sizeof(RTDVMFMTINTERNAL));
+ if (VALID_PTR(pThis))
+ {
+ pThis->pDisk = pDisk;
+ pThis->cPartitions = 0;
+
+ /* Read the MBR and count the valid partition entries. */
+ rc = rtDvmDiskRead(pDisk, 0, &pThis->abMbr[0], sizeof(pThis->abMbr));
+ if (RT_SUCCESS(rc))
+ {
+ uint8_t *pbMbrEntry = &pThis->abMbr[446];
+
+ Assert(pThis->abMbr[510] == 0x55 && pThis->abMbr[511] == 0xaa);
+
+ for (unsigned i = 0; i < 4; i++)
+ {
+ /* The entry is unused if the type contains 0x00. */
+ if (pbMbrEntry[4] != 0x00)
+ pThis->cPartitions++;
+
+ pbMbrEntry += 16;
+ }
+
+ *phVolMgrFmt = pThis;
+ }
+ }
+ else
+ rc = VERR_NO_MEMORY;
+
+ return rc;
+}
+
+static DECLCALLBACK(int) rtDvmFmtMbrInitialize(PCRTDVMDISK pDisk, PRTDVMFMT phVolMgrFmt)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMFMTINTERNAL pThis = NULL;
+
+ pThis = (PRTDVMFMTINTERNAL)RTMemAllocZ(sizeof(RTDVMFMTINTERNAL));
+ if (VALID_PTR(pThis))
+ {
+ /* Setup a new MBR and write it to the disk. */
+ memset(&pThis->abMbr[0], 0, sizeof(pThis->abMbr));
+ pThis->abMbr[510] = 0x55;
+ pThis->abMbr[511] = 0xaa;
+
+ rc = rtDvmDiskWrite(pDisk, 0, &pThis->abMbr[0], sizeof(pThis->abMbr));
+
+ if (RT_SUCCESS(rc))
+ {
+ pThis->pDisk = pDisk;
+ pThis->cPartitions = 0;
+ *phVolMgrFmt = pThis;
+ }
+ else
+ RTMemFree(pThis);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+
+ return rc;
+}
+
+static DECLCALLBACK(void) rtDvmFmtMbrClose(RTDVMFMT hVolMgrFmt)
+{
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+
+ pThis->pDisk = NULL;
+ pThis->cPartitions = 0;
+ memset(&pThis->abMbr[0], 0, sizeof(pThis->abMbr));
+ RTMemFree(pThis);
+}
+
+static DECLCALLBACK(uint32_t) rtDvmFmtMbrGetValidVolumes(RTDVMFMT hVolMgrFmt)
+{
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+
+ return pThis->cPartitions;
+}
+
+static DECLCALLBACK(uint32_t) rtDvmFmtMbrGetMaxVolumes(RTDVMFMT hVolMgrFmt)
+{
+ NOREF(hVolMgrFmt);
+ return 4; /** @todo: Add support for EBR? */
+}
+
+/**
+ * Creates a new volume.
+ *
+ * @returns IPRT status code.
+ * @param pThis The MBR volume manager data.
+ * @param pbMbrEntry The raw MBR entry data.
+ * @param idx The index in the partition table.
+ * @param phVolFmt Where to store the volume data on success.
+ */
+static int rtDvmFmtMbrVolumeCreate(PRTDVMFMTINTERNAL pThis, uint8_t *pbMbrEntry,
+ uint32_t idx, PRTDVMVOLUMEFMT phVolFmt)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMVOLUMEFMTINTERNAL pVol = (PRTDVMVOLUMEFMTINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEFMTINTERNAL));
+
+ if (VALID_PTR(pVol))
+ {
+ pVol->pVolMgr = pThis;
+ pVol->idxEntry = idx;
+ pVol->pbMbrEntry = pbMbrEntry;
+ pVol->offStart = *(uint32_t *)&pbMbrEntry[0x08] * pThis->pDisk->cbSector;
+ pVol->cbVolume = *(uint32_t *)&pbMbrEntry[0x0c] * pThis->pDisk->cbSector;
+
+ *phVolFmt = pVol;
+ }
+ else
+ rc = VERR_NO_MEMORY;
+
+ return rc;
+}
+
+static DECLCALLBACK(int) rtDvmFmtMbrQueryFirstVolume(RTDVMFMT hVolMgrFmt, PRTDVMVOLUMEFMT phVolFmt)
+{
+ int rc = VINF_SUCCESS;
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+
+ if (pThis->cPartitions != 0)
+ {
+ uint8_t *pbMbrEntry = &pThis->abMbr[446];
+
+ /* Search for the first non empty entry. */
+ for (unsigned i = 0; i < 4; i++)
+ {
+ if (pbMbrEntry[0x04] != 0x00)
+ {
+ rc = rtDvmFmtMbrVolumeCreate(pThis, pbMbrEntry, i, phVolFmt);
+ break;
+ }
+ pbMbrEntry += 16;
+ }
+ }
+ else
+ rc = VERR_DVM_MAP_EMPTY;
+
+ return rc;
+}
+
+static DECLCALLBACK(int) rtDvmFmtMbrQueryNextVolume(RTDVMFMT hVolMgrFmt, RTDVMVOLUMEFMT hVolFmt, PRTDVMVOLUMEFMT phVolFmtNext)
+{
+ int rc = VERR_DVM_MAP_NO_VOLUME;
+ PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+ uint8_t *pbMbrEntry = pVol->pbMbrEntry + 16;
+
+ for (unsigned i = pVol->idxEntry + 1; i < 4; i++)
+ {
+ if (pbMbrEntry[0x04] != 0x00)
+ {
+ rc = rtDvmFmtMbrVolumeCreate(pThis, pbMbrEntry, i, phVolFmtNext);
+ break;
+ }
+ pbMbrEntry += 16;
+ }
+
+ return rc;
+}
+
+static DECLCALLBACK(void) rtDvmFmtMbrVolumeClose(RTDVMVOLUMEFMT hVolFmt)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+
+ pVol->pVolMgr = NULL;
+ pVol->offStart = 0;
+ pVol->cbVolume = 0;
+ pVol->pbMbrEntry = NULL;
+
+ RTMemFree(pVol);
+}
+
+static DECLCALLBACK(uint64_t) rtDvmFmtMbrVolumeGetSize(RTDVMVOLUMEFMT hVolFmt)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+
+ return pVol->cbVolume;
+}
+
+static DECLCALLBACK(int) rtDvmFmtMbrVolumeQueryName(RTDVMVOLUMEFMT hVolFmt, char **ppszVolName)
+{
+ NOREF(hVolFmt);
+ return VERR_NOT_SUPPORTED;
+}
+
+static DECLCALLBACK(RTDVMVOLTYPE) rtDvmFmtMbrVolumeGetType(RTDVMVOLUMEFMT hVolFmt)
+{
+ RTDVMVOLTYPE enmVolType = RTDVMVOLTYPE_UNKNOWN;
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+
+ for (unsigned i = 0; i < RT_ELEMENTS(g_aFs2DvmVolTypes); i++)
+ if (pVol->pbMbrEntry[0x04] == g_aFs2DvmVolTypes[i].bFsId)
+ {
+ enmVolType = g_aFs2DvmVolTypes[i].enmVolType;
+ break;
+ }
+
+ return enmVolType;
+}
+
+static DECLCALLBACK(uint64_t) rtDvmFmtMbrVolumeGetFlags(RTDVMVOLUMEFMT hVolFmt)
+{
+ uint64_t fFlags = 0;
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+
+ if (pVol->pbMbrEntry[0x00] & 0x80)
+ fFlags |= DVMVOLUME_FLAGS_BOOTABLE | DVMVOLUME_FLAGS_ACTIVE;
+
+ return fFlags;
+}
+
+static DECLCALLBACK(int) rtDvmFmtMbrVolumeRead(RTDVMVOLUMEFMT hVolFmt, uint64_t off, void *pvBuf, size_t cbRead)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+ AssertReturn(off + cbRead <= pVol->cbVolume, VERR_INVALID_PARAMETER);
+
+ return rtDvmDiskRead(pVol->pVolMgr->pDisk, pVol->offStart + off, pvBuf, cbRead);
+}
+
+static DECLCALLBACK(int) rtDvmFmtMbrVolumeWrite(RTDVMVOLUMEFMT hVolFmt, uint64_t off, const void *pvBuf, size_t cbWrite)
+{
+ PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+ AssertReturn(off + cbWrite <= pVol->cbVolume, VERR_INVALID_PARAMETER);
+
+ return rtDvmDiskWrite(pVol->pVolMgr->pDisk, pVol->offStart + off, pvBuf, cbWrite);
+}
+
+RTDVMFMTOPS g_rtDvmFmtMbr =
+{
+ /* pcszFmt */
+ "MBR",
+ /* pfnProbe */
+ rtDvmFmtMbrProbe,
+ /* pfnOpen */
+ rtDvmFmtMbrOpen,
+ /* pfnInitialize */
+ rtDvmFmtMbrInitialize,
+ /* pfnClose */
+ rtDvmFmtMbrClose,
+ /* pfnGetValidVolumes */
+ rtDvmFmtMbrGetValidVolumes,
+ /* pfnGetMaxVolumes */
+ rtDvmFmtMbrGetMaxVolumes,
+ /* pfnQueryFirstVolume */
+ rtDvmFmtMbrQueryFirstVolume,
+ /* pfnQueryNextVolume */
+ rtDvmFmtMbrQueryNextVolume,
+ /* pfnVolumeClose */
+ rtDvmFmtMbrVolumeClose,
+ /* pfnVolumeGetSize */
+ rtDvmFmtMbrVolumeGetSize,
+ /* pfnVolumeQueryName */
+ rtDvmFmtMbrVolumeQueryName,
+ /* pfnVolumeGetType */
+ rtDvmFmtMbrVolumeGetType,
+ /* pfnVolumeGetFlags */
+ rtDvmFmtMbrVolumeGetFlags,
+ /* pfnVolumeRead */
+ rtDvmFmtMbrVolumeRead,
+ /* pfnVolumeWrite */
+ rtDvmFmtMbrVolumeWrite
+};
+
diff --git a/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp b/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp
index 13f37b776..5cb304854 100644
--- a/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp
+++ b/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTErrConvertFromErrno.cpp $ */
+/* $Id: RTErrConvertFromErrno.cpp 31316 2010-08-02 15:36:30Z vboxsync $ */
/** @file
* IPRT - Convert errno to iprt status codes.
*/
diff --git a/src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp b/src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp
index cadac56fd..11df924fa 100644
--- a/src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp
+++ b/src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTErrConvertToErrno.cpp $ */
+/* $Id: RTErrConvertToErrno.cpp 36284 2011-03-15 13:06:05Z vboxsync $ */
/** @file
* IPRT - Convert iprt status codes to errno.
*/
@@ -176,6 +176,7 @@ RTDECL(int) RTErrConvertToErrno(int iErr)
case VERR_FILE_LOCK_FAILED: return ENOLCK;
#endif
#ifdef ENOSYS
+ case VERR_NOT_IMPLEMENTED:
case VERR_NOT_SUPPORTED: return ENOSYS;
#endif
#ifdef ENOTEMPTY
diff --git a/src/VBox/Runtime/common/err/errinfo.cpp b/src/VBox/Runtime/common/err/errinfo.cpp
index a8db71fcb..aef5a3973 100644
--- a/src/VBox/Runtime/common/err/errinfo.cpp
+++ b/src/VBox/Runtime/common/err/errinfo.cpp
@@ -1,4 +1,4 @@
-/* $Id: errinfo.cpp $ */
+/* $Id: errinfo.cpp 35182 2010-12-16 13:57:44Z vboxsync $ */
/** @file
* IPRT - Error Info.
*/
diff --git a/src/VBox/Runtime/common/err/errmsg.cpp b/src/VBox/Runtime/common/err/errmsg.cpp
index c22927469..b011bf79c 100644
--- a/src/VBox/Runtime/common/err/errmsg.cpp
+++ b/src/VBox/Runtime/common/err/errmsg.cpp
@@ -1,4 +1,4 @@
-/* $Id: errmsg.cpp $ */
+/* $Id: errmsg.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Status code messages.
*/
diff --git a/src/VBox/Runtime/common/err/errmsg.sed b/src/VBox/Runtime/common/err/errmsg.sed
index d4a1acc85..8af8c7c00 100644
--- a/src/VBox/Runtime/common/err/errmsg.sed
+++ b/src/VBox/Runtime/common/err/errmsg.sed
@@ -1,9 +1,10 @@
-# $Id: errmsg.sed $
+# $Id: errmsg.sed 35811 2011-02-01 13:12:08Z vboxsync $
## @file
# IPRT - SED script for converting */err.h.
#
-# Copyright (C) 2006-2009 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;
@@ -93,6 +94,11 @@ s/ { NULL, \"\([^.!?"]*[.!?][.!?]*\)/ { \"\1\",\n \"\1/
# terminate the string
s/[[:space:]]*\*\//\"\,/
+
+# translate empty lines into new-lines (only one, please).
+s/[[:space:]]*[[:space:]]\*[[:space:]][[:space:]]*\*[[:space:]][[:space:]]*/\\n/g
+
+# remove asterics.
s/[[:space:]]*[[:space:]]\*[[:space:]][[:space:]]*/ /g
b end
diff --git a/src/VBox/Runtime/common/err/errmsgcom.sed b/src/VBox/Runtime/common/err/errmsgcom.sed
index b101ad7c9..b1c2096a0 100644
--- a/src/VBox/Runtime/common/err/errmsgcom.sed
+++ b/src/VBox/Runtime/common/err/errmsgcom.sed
@@ -1,4 +1,4 @@
-# $Id: errmsgcom.sed $
+# $Id: errmsgcom.sed 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# IPRT - SED script for converting COM errors
#
diff --git a/src/VBox/Runtime/common/err/errmsgxpcom.cpp b/src/VBox/Runtime/common/err/errmsgxpcom.cpp
index 74071989c..bee0378da 100644
--- a/src/VBox/Runtime/common/err/errmsgxpcom.cpp
+++ b/src/VBox/Runtime/common/err/errmsgxpcom.cpp
@@ -1,4 +1,4 @@
-/* $Id: errmsgxpcom.cpp $ */
+/* $Id: errmsgxpcom.cpp 34654 2010-12-02 19:59:22Z vboxsync $ */
/** @file
* IPRT - Status code messages for XPCOM.
*/
diff --git a/src/VBox/Runtime/common/ldr/ldr.cpp b/src/VBox/Runtime/common/ldr/ldr.cpp
index ada4984c6..bbe54edc2 100644
--- a/src/VBox/Runtime/common/ldr/ldr.cpp
+++ b/src/VBox/Runtime/common/ldr/ldr.cpp
@@ -1,4 +1,4 @@
-/* $Id: ldr.cpp $ */
+/* $Id: ldr.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - Binary Image Loader.
*/
@@ -40,25 +40,6 @@
#include "internal/ldr.h"
-/*******************************************************************************
-* Structures and Typedefs *
-*******************************************************************************/
-typedef struct RTLDRREADERFILE
-{
- /** The core. */
- RTLDRREADER Core;
- /** The file. */
- RTFILE File;
- /** The file size. */
- RTFOFF cbFile;
- /** The current offset. */
- RTFOFF off;
- /** The filename (variable size). */
- char szFilename[1];
-} RTLDRREADERFILE, *PRTLDRREADERFILE;
-
-
-
/**
* Checks if a library is loadable or not.
*
diff --git a/src/VBox/Runtime/common/ldr/ldrELF.cpp b/src/VBox/Runtime/common/ldr/ldrELF.cpp
index 47b45f618..b260fc4c3 100644
--- a/src/VBox/Runtime/common/ldr/ldrELF.cpp
+++ b/src/VBox/Runtime/common/ldr/ldrELF.cpp
@@ -1,4 +1,4 @@
-/* $Id: ldrELF.cpp $ */
+/* $Id: ldrELF.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Binary Image Loader, Executable and Linker Format (ELF).
*/
diff --git a/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h b/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h
index 755ef6a94..f0fff9008 100644
--- a/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h
+++ b/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h
@@ -1,4 +1,4 @@
-/* $Id: ldrELFRelocatable.cpp.h $ */
+/* $Id: ldrELFRelocatable.cpp.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Binary Image Loader, Template for ELF Relocatable Images.
*/
diff --git a/src/VBox/Runtime/common/ldr/ldrEx.cpp b/src/VBox/Runtime/common/ldr/ldrEx.cpp
index 89750586d..ffd59542a 100644
--- a/src/VBox/Runtime/common/ldr/ldrEx.cpp
+++ b/src/VBox/Runtime/common/ldr/ldrEx.cpp
@@ -1,4 +1,4 @@
-/* $Id: ldrEx.cpp $ */
+/* $Id: ldrEx.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Binary Image Loader, Extended Features.
*/
diff --git a/src/VBox/Runtime/common/ldr/ldrFile.cpp b/src/VBox/Runtime/common/ldr/ldrFile.cpp
index 4de2d328b..b0b43f9a8 100644
--- a/src/VBox/Runtime/common/ldr/ldrFile.cpp
+++ b/src/VBox/Runtime/common/ldr/ldrFile.cpp
@@ -1,4 +1,4 @@
-/* $Id: ldrFile.cpp $ */
+/* $Id: ldrFile.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - Binary Image Loader, The File Oriented Parts.
*/
@@ -54,7 +54,7 @@ typedef struct RTLDRREADERFILE
/** The core. */
RTLDRREADER Core;
/** The file. */
- RTFILE File;
+ RTFILE hFile;
/** The file size. */
RTFOFF cbFile;
/** The current offset. */
@@ -78,7 +78,7 @@ static DECLCALLBACK(int) rtldrFileRead(PRTLDRREADER pReader, void *pvBuf, size_t
*/
if (pFileReader->off != off)
{
- int rc = RTFileSeek(pFileReader->File, off, RTFILE_SEEK_BEGIN, NULL);
+ int rc = RTFileSeek(pFileReader->hFile, off, RTFILE_SEEK_BEGIN, NULL);
if (RT_FAILURE(rc))
{
pFileReader->off = -1;
@@ -90,7 +90,7 @@ static DECLCALLBACK(int) rtldrFileRead(PRTLDRREADER pReader, void *pvBuf, size_t
/*
* Read.
*/
- int rc = RTFileRead(pFileReader->File, pvBuf, cb, NULL);
+ int rc = RTFileRead(pFileReader->hFile, pvBuf, cb, NULL);
if (RT_SUCCESS(rc))
pFileReader->off += cb;
else
@@ -184,11 +184,11 @@ static DECLCALLBACK(int) rtldrFileDestroy(PRTLDRREADER pReader)
{
int rc = VINF_SUCCESS;
PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)pReader;
- if (pFileReader->File != NIL_RTFILE)
+ if (pFileReader->hFile != NIL_RTFILE)
{
- rc = RTFileClose(pFileReader->File);
+ rc = RTFileClose(pFileReader->hFile);
AssertRC(rc);
- pFileReader->File = NIL_RTFILE;
+ pFileReader->hFile = NIL_RTFILE;
}
RTMemFree(pFileReader);
return rc;
@@ -210,10 +210,10 @@ static int rtldrFileCreate(PRTLDRREADER *ppReader, const char *pszFilename)
if (pFileReader)
{
memcpy(pFileReader->szFilename, pszFilename, cchFilename + 1);
- rc = RTFileOpen(&pFileReader->File, pszFilename, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+ rc = RTFileOpen(&pFileReader->hFile, pszFilename, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
if (RT_SUCCESS(rc))
{
- rc = RTFileGetSize(pFileReader->File, (uint64_t *)&pFileReader->cbFile);
+ rc = RTFileGetSize(pFileReader->hFile, (uint64_t *)&pFileReader->cbFile);
if (RT_SUCCESS(rc))
{
pFileReader->Core.pfnRead = rtldrFileRead;
@@ -229,7 +229,8 @@ static int rtldrFileCreate(PRTLDRREADER *ppReader, const char *pszFilename)
*ppReader = &pFileReader->Core;
return VINF_SUCCESS;
}
- RTFileClose(pFileReader->File);
+
+ RTFileClose(pFileReader->hFile);
}
RTMemFree(pFileReader);
}
diff --git a/src/VBox/Runtime/common/ldr/ldrNative.cpp b/src/VBox/Runtime/common/ldr/ldrNative.cpp
index 8462e7098..8c25fed4a 100644
--- a/src/VBox/Runtime/common/ldr/ldrNative.cpp
+++ b/src/VBox/Runtime/common/ldr/ldrNative.cpp
@@ -1,4 +1,4 @@
-/* $Id: ldrNative.cpp $ */
+/* $Id: ldrNative.cpp 35191 2010-12-16 15:25:20Z vboxsync $ */
/** @file
* IPRT - Binary Image Loader, Native interface.
*/
diff --git a/src/VBox/Runtime/common/ldr/ldrPE.cpp b/src/VBox/Runtime/common/ldr/ldrPE.cpp
index 82f610b55..47be5429f 100644
--- a/src/VBox/Runtime/common/ldr/ldrPE.cpp
+++ b/src/VBox/Runtime/common/ldr/ldrPE.cpp
@@ -1,4 +1,4 @@
-/* $Id: ldrPE.cpp $ */
+/* $Id: ldrPE.cpp 36969 2011-05-05 08:59:43Z vboxsync $ */
/** @file
* IPRT - Binary Image Loader, Portable Executable (PE).
*/
diff --git a/src/VBox/Runtime/common/ldr/ldrkStuff.cpp b/src/VBox/Runtime/common/ldr/ldrkStuff.cpp
index 96585a61b..09fd971c0 100644
--- a/src/VBox/Runtime/common/ldr/ldrkStuff.cpp
+++ b/src/VBox/Runtime/common/ldr/ldrkStuff.cpp
@@ -1,4 +1,4 @@
-/* $Id: ldrkStuff.cpp $ */
+/* $Id: ldrkStuff.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Binary Image Loader, kLdr Interface.
*/
diff --git a/src/VBox/Runtime/common/log/log.cpp b/src/VBox/Runtime/common/log/log.cpp
index fe2ffa4b0..354b32997 100644
--- a/src/VBox/Runtime/common/log/log.cpp
+++ b/src/VBox/Runtime/common/log/log.cpp
@@ -1,4 +1,4 @@
-/* $Id: log.cpp $ */
+/* $Id: log.cpp 37818 2011-07-07 13:25:03Z vboxsync $ */
/** @file
* Runtime VBox - Logger.
*/
@@ -71,31 +71,64 @@
typedef struct RTLOGOUTPUTPREFIXEDARGS
{
/** The logger instance. */
- PRTLOGGER pLogger;
+ PRTLOGGER pLogger;
/** The flags. (used for prefixing.) */
- unsigned fFlags;
+ unsigned fFlags;
/** The group. (used for prefixing.) */
- unsigned iGroup;
+ unsigned iGroup;
} RTLOGOUTPUTPREFIXEDARGS, *PRTLOGOUTPUTPREFIXEDARGS;
-#ifdef IN_RING3
/**
- * File logging bits for the logger.
+ * Internal logger data.
+ *
+ * @remarks Don't make casual changes to this structure.
*/
-typedef struct RTLOGGERFILE
+typedef struct RTLOGGERINTERNAL
{
+ /** The structure revision (RTLOGGERINTERNAL_REV). */
+ uint32_t uRevision;
+ /** The size of the internal logger structure. */
+ uint32_t cbSelf;
+
+ /** Spinning mutex semaphore. Can be NIL. */
+ RTSEMSPINMUTEX hSpinMtx;
+ /** Pointer to the flush function. */
+ PFNRTLOGFLUSH pfnFlush;
+
+ /** Custom prefix callback. */
+ PFNRTLOGPREFIX pfnPrefix;
+ /** Prefix callback argument. */
+ void *pvPrefixUserArg;
+ /** This is set if a prefix is pending. */
+ bool fPendingPrefix;
+ /** Alignment padding. */
+ bool afPadding1[3];
+
+ /** The max number of groups that there is room for in afGroups and papszGroups.
+ * Used by RTLogCopyGroupAndFlags(). */
+ uint32_t cMaxGroups;
+ /** Pointer to the group name array.
+ * (The data is readonly and provided by the user.) */
+ const char * const *papszGroups;
+
+ /** The number of log entries per group. NULL if
+ * RTLOGFLAGS_RESTRICT_GROUPS is not specified. */
+ uint32_t *pacEntriesPerGroup;
+ /** The max number of entries per group. */
+ uint32_t cMaxEntriesPerGroup;
+ /** Padding. */
+ uint32_t u32Padding2;
+
+#ifdef IN_RING3 /* Note! Must be at the end! */
+ /** @name File logging bits for the logger.
+ * @{ */
/** Pointer to the function called when starting logging, and when
* ending or starting a new log file as part of history rotation.
* This can be NULL. */
PFNRTLOGPHASE pfnPhase;
+
/** Handle to log file (if open). */
- RTFILE File;
- /** Pointer to filename.
- * (The memory is allocated in the same block as RTLOGGER.) */
- char *pszFilename;
- /** Log file history settings: number of older files to keep.
- * 0 means no history. */
- uint32_t cHistory;
+ RTFILE hFile;
/** Log file history settings: maximum amount of data to put in a file. */
uint64_t cbHistoryFileMax;
/** Log file history settings: current amount of data in a file. */
@@ -104,9 +137,24 @@ typedef struct RTLOGGERFILE
uint32_t cSecsHistoryTimeSlot;
/** Log file history settings: in what time slot was the file created. */
uint32_t uHistoryTimeSlotStart;
-} RTLOGGERFILE;
+ /** Log file history settings: number of older files to keep.
+ * 0 means no history. */
+ uint32_t cHistory;
+ /** Pointer to filename. */
+ char szFilename[RTPATH_MAX];
+ /** @} */
#endif /* IN_RING3 */
+} RTLOGGERINTERNAL;
+/** The revision of the internal logger structure. */
+#define RTLOGGERINTERNAL_REV UINT32_C(9)
+
+#ifdef IN_RING3
+/** The size of the RTLOGGERINTERNAL structure in ring-0. */
+# define RTLOGGERINTERNAL_R0_SIZE RT_OFFSETOF(RTLOGGERINTERNAL, pfnPhase)
+AssertCompileMemberAlignment(RTLOGGERINTERNAL, hFile, sizeof(void *));
+AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbHistoryFileMax, sizeof(uint64_t));
+#endif
/*******************************************************************************
* Internal Functions *
@@ -125,6 +173,7 @@ static void rtlogFlush(PRTLOGGER pLogger);
static DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars);
static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars, size_t cbChars);
static void rtlogLoggerExVLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args);
+static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
/*******************************************************************************
@@ -141,6 +190,7 @@ static PRTLOGGER g_pLogger;
/** The RTThreadGetWriteLockCount() change caused by the logger mutex semaphore. */
static uint32_t volatile g_cLoggerLockCount;
#endif
+
#ifdef IN_RING0
/** Number of per-thread loggers. */
static int32_t volatile g_cPerThreadLoggers;
@@ -209,6 +259,7 @@ static struct
{ "msprog", sizeof("msprog" ) - 1, RTLOGFLAGS_PREFIX_MS_PROG, false },
{ "tsc", sizeof("tsc" ) - 1, RTLOGFLAGS_PREFIX_TSC, false }, /* before ts! */
{ "ts", sizeof("ts" ) - 1, RTLOGFLAGS_PREFIX_TS, false },
+ /* We intentionally omit RTLOGFLAGS_RESTRICT_GROUPS. */
};
/**
@@ -243,9 +294,14 @@ static struct
DECLINLINE(int) rtlogLock(PRTLOGGER pLogger)
{
#ifndef IN_RC
- if (pLogger->hSpinMtx != NIL_RTSEMSPINMUTEX)
+ PRTLOGGERINTERNAL pInt = pLogger->pInt;
+ AssertMsgReturn(pInt->uRevision == RTLOGGERINTERNAL_REV, ("%#x != %#x\n", pInt->uRevision, RTLOGGERINTERNAL_REV),
+ VERR_LOG_REVISION_MISMATCH);
+ AssertMsgReturn(pInt->cbSelf == sizeof(*pInt), ("%#x != %#x\n", pInt->cbSelf, sizeof(*pInt)),
+ VERR_LOG_REVISION_MISMATCH);
+ if (pInt->hSpinMtx != NIL_RTSEMSPINMUTEX)
{
- int rc = RTSemSpinMutexRequest(pLogger->hSpinMtx);
+ int rc = RTSemSpinMutexRequest(pInt->hSpinMtx);
if (RT_FAILURE(rc))
return rc;
}
@@ -261,8 +317,8 @@ DECLINLINE(int) rtlogLock(PRTLOGGER pLogger)
DECLINLINE(void) rtlogUnlock(PRTLOGGER pLogger)
{
#ifndef IN_RC
- if (pLogger->hSpinMtx != NIL_RTSEMSPINMUTEX)
- RTSemSpinMutexRelease(pLogger->hSpinMtx);
+ if (pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX)
+ RTSemSpinMutexRelease(pLogger->pInt->hSpinMtx);
#endif
return;
}
@@ -280,7 +336,7 @@ DECLINLINE(void) rtlogUnlock(PRTLOGGER pLogger)
static DECLCALLBACK(size_t) rtlogPhaseWrite(void *pvArg, const char *pachChars, size_t cbChars)
{
PRTLOGGER pLogger = (PRTLOGGER)pvArg;
- RTFileWrite(pLogger->pFile->File, pachChars, cbChars, NULL);
+ RTFileWrite(pLogger->pInt->hFile, pachChars, cbChars, NULL);
return cbChars;
}
@@ -324,8 +380,8 @@ static DECLCALLBACK(void) rtlogPhaseMsgLocked(PRTLOGGER pLogger, const char *psz
{
va_list args;
AssertPtrReturnVoid(pLogger);
- AssertPtrReturnVoid(pLogger->pFile);
- Assert(pLogger->hSpinMtx != NIL_RTSEMSPINMUTEX);
+ AssertPtrReturnVoid(pLogger->pInt);
+ Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
va_start(args, pszFormat);
rtlogLoggerExVLocked(pLogger, 0, ~0, pszFormat, args);
@@ -344,8 +400,8 @@ static DECLCALLBACK(void) rtlogPhaseMsgNormal(PRTLOGGER pLogger, const char *psz
{
va_list args;
AssertPtrReturnVoid(pLogger);
- AssertPtrReturnVoid(pLogger->pFile);
- Assert(pLogger->hSpinMtx != NIL_RTSEMSPINMUTEX);
+ AssertPtrReturnVoid(pLogger->pInt);
+ Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
va_start(args, pszFormat);
RTLogLoggerExV(pLogger, 0, ~0, pszFormat, args);
@@ -355,14 +411,15 @@ static DECLCALLBACK(void) rtlogPhaseMsgNormal(PRTLOGGER pLogger, const char *psz
# endif /* IN_RING3 */
RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
- const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
+ const char *pszEnvVarBase, unsigned cGroups, const char * const *papszGroups,
uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,
uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, va_list args)
{
- int rc;
- size_t cb;
- PRTLOGGER pLogger;
+ int rc;
+ size_t offInternal;
+ size_t cbLogger;
+ PRTLOGGER pLogger;
/*
* Validate input.
@@ -383,45 +440,55 @@ RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *psz
/*
* Allocate a logger instance.
*/
- cb = RT_OFFSETOF(RTLOGGER, afGroups[cGroups + 1]) + RTPATH_MAX;
-#ifdef IN_RING3
- cb += sizeof(RTLOGGERFILE);
-#endif
- pLogger = (PRTLOGGER)RTMemAllocZVar(cb);
+ offInternal = RT_OFFSETOF(RTLOGGER, afGroups[cGroups]);
+ offInternal = RT_ALIGN_Z(offInternal, sizeof(uint64_t));
+ cbLogger = offInternal + sizeof(RTLOGGERINTERNAL);
+ if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
+ cbLogger += cGroups * sizeof(uint32_t);
+ pLogger = (PRTLOGGER)RTMemAllocZVar(cbLogger);
if (pLogger)
{
-#if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
+# if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
uint8_t *pu8Code;
-#endif
-
- pLogger->u32Magic = RTLOGGER_MAGIC;
- pLogger->papszGroups = papszGroups;
- pLogger->cMaxGroups = cGroups;
- pLogger->cGroups = cGroups;
-#ifdef IN_RING3
- pLogger->pFile = (PRTLOGGERFILE)((char *)&pLogger->afGroups[cGroups + 1] + RTPATH_MAX);
- pLogger->pFile->File = NIL_RTFILE;
- pLogger->pFile->pszFilename = (char *)&pLogger->afGroups[cGroups + 1];
- pLogger->pFile->pfnPhase = pfnPhase;
- pLogger->pFile->cHistory = cHistory;
+# endif
+ pLogger->u32Magic = RTLOGGER_MAGIC;
+ pLogger->cGroups = cGroups;
+ pLogger->fFlags = fFlags;
+ pLogger->fDestFlags = fDestFlags;
+ pLogger->pInt = (PRTLOGGERINTERNAL)((uintptr_t)pLogger + offInternal);
+ pLogger->pInt->uRevision = RTLOGGERINTERNAL_REV;
+ pLogger->pInt->cbSelf = sizeof(RTLOGGERINTERNAL);
+ pLogger->pInt->hSpinMtx = NIL_RTSEMSPINMUTEX;
+ pLogger->pInt->pfnFlush = NULL;
+ pLogger->pInt->pfnPrefix = NULL;
+ pLogger->pInt->pvPrefixUserArg = NULL;
+ pLogger->pInt->afPadding1[0] = false;
+ pLogger->pInt->afPadding1[1] = false;
+ pLogger->pInt->afPadding1[2] = false;
+ pLogger->pInt->cMaxGroups = cGroups;
+ pLogger->pInt->papszGroups = papszGroups;
+ if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
+ pLogger->pInt->pacEntriesPerGroup = (uint32_t *)(pLogger->pInt + 1);
+ else
+ pLogger->pInt->pacEntriesPerGroup = NULL;
+ pLogger->pInt->cMaxEntriesPerGroup = UINT32_MAX;
+# ifdef IN_RING3
+ pLogger->pInt->pfnPhase = pfnPhase;
+ pLogger->pInt->hFile = NIL_RTFILE;
+ pLogger->pInt->cHistory = cHistory;
if (cbHistoryFileMax == 0)
- pLogger->pFile->cbHistoryFileMax = UINT64_MAX;
+ pLogger->pInt->cbHistoryFileMax = UINT64_MAX;
else
- pLogger->pFile->cbHistoryFileMax = cbHistoryFileMax;
+ pLogger->pInt->cbHistoryFileMax = cbHistoryFileMax;
if (cSecsHistoryTimeSlot == 0)
- pLogger->pFile->cSecsHistoryTimeSlot = UINT32_MAX;
+ pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
else
- pLogger->pFile->cSecsHistoryTimeSlot = cSecsHistoryTimeSlot;
-#else /* !IN_RING3 */
- pLogger->pFile = NULL;
-#endif /* !IN_RING3 */
- pLogger->fFlags = fFlags;
- pLogger->fDestFlags = fDestFlags;
- pLogger->fPendingPrefix = true;
+ pLogger->pInt->cSecsHistoryTimeSlot = cSecsHistoryTimeSlot;
+# endif /* IN_RING3 */
if (pszGroupSettings)
RTLogGroupSettings(pLogger, pszGroupSettings);
-#if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
+# if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
/*
* Emit wrapper code.
*/
@@ -446,23 +513,23 @@ RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *psz
}
else
{
-# ifdef RT_OS_LINUX
+# ifdef RT_OS_LINUX
if (pszErrorMsg) /* Most probably SELinux causing trouble since the larger RTMemAlloc succeeded. */
RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("mmap(PROT_WRITE | PROT_EXEC) failed -- SELinux?"));
-# endif
+# endif
rc = VERR_NO_MEMORY;
}
if (RT_SUCCESS(rc))
-#endif /* X86 wrapper code*/
+# endif /* X86 wrapper code*/
{
-#ifdef IN_RING3 /* files and env.vars. are only accessible when in R3 at the present time. */
+# ifdef IN_RING3 /* files and env.vars. are only accessible when in R3 at the present time. */
/*
* Format the filename.
*/
if (pszFilenameFmt)
{
/** @todo validate the length, fail on overflow. */
- RTStrPrintfV(pLogger->pFile->pszFilename, RTPATH_MAX, pszFilenameFmt, args);
+ RTStrPrintfV(pLogger->pInt->szFilename, sizeof(pLogger->pInt->szFilename), pszFilenameFmt, args);
pLogger->fDestFlags |= RTLOGDEST_FILE;
}
@@ -500,13 +567,13 @@ RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *psz
if (pszVar)
RTLogGroupSettings(pLogger, pszVar);
}
-#endif /* IN_RING3 */
+# endif /* IN_RING3 */
/*
* Open the destination(s).
*/
rc = VINF_SUCCESS;
-#ifdef IN_RING3
+# ifdef IN_RING3
if (pLogger->fDestFlags & RTLOGDEST_FILE)
{
if (pLogger->fFlags & RTLOGFLAGS_APPEND)
@@ -520,18 +587,18 @@ RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *psz
else
{
/* Force rotation if it is configured. */
- pLogger->pFile->cbHistoryFileWritten = UINT64_MAX;
+ pLogger->pInt->cbHistoryFileWritten = UINT64_MAX;
rtlogRotate(pLogger, 0, true /* fFirst */);
/* If the file is not open then rotation is not set up. */
- if (pLogger->pFile->File == NIL_RTFILE)
+ if (pLogger->pInt->hFile == NIL_RTFILE)
{
- pLogger->pFile->cbHistoryFileWritten = 0;
+ pLogger->pInt->cbHistoryFileWritten = 0;
rc = rtlogFileOpen(pLogger, pszErrorMsg, cchErrorMsg);
}
}
}
-#endif /* IN_RING3 */
+# endif /* IN_RING3 */
/*
* Create mutex and check how much it counts when entering the lock
@@ -539,25 +606,25 @@ RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *psz
*/
if (RT_SUCCESS(rc))
{
- rc = RTSemSpinMutexCreate(&pLogger->hSpinMtx, RTSEMSPINMUTEX_FLAGS_IRQ_SAFE);
+ rc = RTSemSpinMutexCreate(&pLogger->pInt->hSpinMtx, RTSEMSPINMUTEX_FLAGS_IRQ_SAFE);
if (RT_SUCCESS(rc))
{
-#ifdef IN_RING3 /** @todo do counters in ring-0 too? */
+# ifdef IN_RING3 /** @todo do counters in ring-0 too? */
RTTHREAD Thread = RTThreadSelf();
if (Thread != NIL_RTTHREAD)
{
int32_t c = RTLockValidatorWriteLockGetCount(Thread);
- RTSemSpinMutexRequest(pLogger->hSpinMtx);
+ RTSemSpinMutexRequest(pLogger->pInt->hSpinMtx);
c = RTLockValidatorWriteLockGetCount(Thread) - c;
- RTSemSpinMutexRelease(pLogger->hSpinMtx);
+ RTSemSpinMutexRelease(pLogger->pInt->hSpinMtx);
ASMAtomicWriteU32(&g_cLoggerLockCount, c);
}
/* Use the callback to generate some initial log contents. */
- Assert(VALID_PTR(pLogger->pFile->pfnPhase) || pLogger->pFile->pfnPhase == NULL);
- if (pLogger->pFile->pfnPhase)
- pLogger->pFile->pfnPhase(pLogger, RTLOGPHASE_BEGIN, rtlogPhaseMsgNormal);
-#endif
+ Assert(VALID_PTR(pLogger->pInt->pfnPhase) || pLogger->pInt->pfnPhase == NULL);
+ if (pLogger->pInt->pfnPhase)
+ pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_BEGIN, rtlogPhaseMsgNormal);
+# endif
*ppLogger = pLogger;
return VINF_SUCCESS;
}
@@ -565,14 +632,14 @@ RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *psz
if (pszErrorMsg)
RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("failed to create semaphore"));
}
-#ifdef IN_RING3
- RTFileClose(pLogger->pFile->File);
-#endif
-#if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
+# ifdef IN_RING3
+ RTFileClose(pLogger->pInt->hFile);
+# endif
+# if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
RTMemFree(*(void **)&pLogger->pfnLogger);
-#else
+# else
RTMemExecFree(*(void **)&pLogger->pfnLogger, 64);
-#endif
+# endif
}
RTMemFree(pLogger);
}
@@ -639,8 +706,9 @@ RTDECL(int) RTLogDestroy(PRTLOGGER pLogger)
*/
if (!pLogger)
return VINF_SUCCESS;
- AssertReturn(VALID_PTR(pLogger), VERR_INVALID_POINTER);
+ AssertPtrReturn(pLogger, VERR_INVALID_POINTER);
AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
+ AssertPtrReturn(pLogger->pInt, VERR_INVALID_POINTER);
/*
* Acquire logger instance sem and disable all logging. (paranoia)
@@ -658,32 +726,32 @@ RTDECL(int) RTLogDestroy(PRTLOGGER pLogger)
*/
rtlogFlush(pLogger);
-#ifdef IN_RING3
+# ifdef IN_RING3
/*
* Add end of logging message.
*/
if ( (pLogger->fDestFlags & RTLOGDEST_FILE)
- && pLogger->pFile->File != NIL_RTFILE)
- pLogger->pFile->pfnPhase(pLogger, RTLOGPHASE_END, rtlogPhaseMsgLocked);
+ && pLogger->pInt->hFile != NIL_RTFILE)
+ pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_END, rtlogPhaseMsgLocked);
/*
* Close output stuffs.
*/
- if (pLogger->pFile->File != NIL_RTFILE)
+ if (pLogger->pInt->hFile != NIL_RTFILE)
{
- int rc2 = RTFileClose(pLogger->pFile->File);
+ int rc2 = RTFileClose(pLogger->pInt->hFile);
AssertRC(rc2);
if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
rc = rc2;
- pLogger->pFile->File = NIL_RTFILE;
+ pLogger->pInt->hFile = NIL_RTFILE;
}
-#endif
+# endif
/*
* Free the mutex, the wrapper and the instance memory.
*/
- hSpinMtx = pLogger->hSpinMtx;
- pLogger->hSpinMtx = NIL_RTSEMSPINMUTEX;
+ hSpinMtx = pLogger->pInt->hSpinMtx;
+ pLogger->pInt->hSpinMtx = NIL_RTSEMSPINMUTEX;
if (hSpinMtx != NIL_RTSEMSPINMUTEX)
{
int rc2;
@@ -696,11 +764,11 @@ RTDECL(int) RTLogDestroy(PRTLOGGER pLogger)
if (pLogger->pfnLogger)
{
-#if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
+# if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
RTMemFree(*(void **)&pLogger->pfnLogger);
-#else
+# else
RTMemExecFree(*(void **)&pLogger->pfnLogger, 64);
-#endif
+# endif
pLogger->pfnLogger = NULL;
}
RTMemFree(pLogger);
@@ -771,7 +839,7 @@ RTDECL(int) RTLogCloneRC(PRTLOGGER pLogger, PRTLOGGERRC pLoggerRC, size_t cbLogg
if (cbLoggerRC < (size_t)RT_OFFSETOF(RTLOGGERRC, afGroups[pLogger->cGroups]))
{
AssertMsgFailed(("%d req=%d cGroups=%d\n", cbLoggerRC, RT_OFFSETOF(RTLOGGERRC, afGroups[pLogger->cGroups]), pLogger->cGroups));
- return VERR_INVALID_PARAMETER;
+ return VERR_BUFFER_OVERFLOW;
}
memcpy(&pLoggerRC->afGroups[0], &pLogger->afGroups[0], pLogger->cGroups * sizeof(pLoggerRC->afGroups[0]));
pLoggerRC->cGroups = pLogger->cGroups;
@@ -779,7 +847,7 @@ RTDECL(int) RTLogCloneRC(PRTLOGGER pLogger, PRTLOGGERRC pLoggerRC, size_t cbLogg
/*
* Copy bits from the HC instance.
*/
- pLoggerRC->fPendingPrefix = pLogger->fPendingPrefix;
+ pLoggerRC->fPendingPrefix = pLogger->pInt->fPendingPrefix;
pLoggerRC->fFlags |= pLogger->fFlags;
/*
@@ -850,67 +918,85 @@ RTDECL(void) RTLogFlushRC(PRTLOGGER pLogger, PRTLOGGERRC pLoggerRC)
}
RT_EXPORT_SYMBOL(RTLogFlushRC);
+# ifdef IN_RING3
-#ifdef IN_RING3
-/**
- * Create a logger instance for singled threaded ring-0 usage.
- *
- * @returns iprt status code.
- *
- * @param pLogger Where to create the logger instance.
- * @param cbLogger The amount of memory available for the logger instance.
- * @param pfnLogger Pointer to logger wrapper function for the clone.
- * @param pfnFlush Pointer to flush function for the clone.
- * @param fFlags Logger instance flags for the clone, a combination of the RTLOGFLAGS_* values.
- * @param fDestFlags The destination flags.
- */
-RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger, PFNRTLOGGER pfnLogger, PFNRTLOGFLUSH pfnFlush,
+RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger,
+ RTR0PTR pLoggerR0Ptr, RTR0PTR pfnLoggerR0Ptr, RTR0PTR pfnFlushR0Ptr,
uint32_t fFlags, uint32_t fDestFlags)
{
/*
* Validate input.
*/
AssertPtrReturn(pLogger, VERR_INVALID_PARAMETER);
- AssertReturn(cbLogger >= sizeof(*pLogger), VERR_INVALID_PARAMETER);
- AssertReturn(pfnLogger, VERR_INVALID_PARAMETER);
- AssertReturn(pfnFlush, VERR_INVALID_PARAMETER);
+ size_t const cbRequired = sizeof(*pLogger) + RTLOGGERINTERNAL_R0_SIZE;
+ AssertReturn(cbLogger >= cbRequired, VERR_BUFFER_OVERFLOW);
+ AssertReturn(pLoggerR0Ptr != NIL_RTR0PTR, VERR_INVALID_PARAMETER);
+ AssertReturn(pfnLoggerR0Ptr != NIL_RTR0PTR, VERR_INVALID_PARAMETER);
/*
* Initialize the ring-0 instance.
*/
- pLogger->offScratch = 0;
- pLogger->fPendingPrefix = false;
- pLogger->pfnLogger = pfnLogger;
- pLogger->pfnFlush = pfnFlush;
- pLogger->hSpinMtx = NIL_RTSEMSPINMUTEX; /* Not serialized. */
- pLogger->u32Magic = RTLOGGER_MAGIC;
- pLogger->fFlags = fFlags;
- pLogger->fDestFlags = fDestFlags & ~RTLOGDEST_FILE;
- pLogger->pFile = NULL;
- pLogger->papszGroups = NULL;
- pLogger->cMaxGroups = (uint32_t)((cbLogger - RT_OFFSETOF(RTLOGGER, afGroups[0])) / sizeof(pLogger->afGroups[0]));
- pLogger->cGroups = 1;
- pLogger->afGroups[0] = 0;
+ pLogger->achScratch[0] = 0;
+ pLogger->offScratch = 0;
+ pLogger->pfnLogger = (PFNRTLOGGER)pfnLoggerR0Ptr;
+ pLogger->fFlags = fFlags;
+ pLogger->fDestFlags = fDestFlags & ~RTLOGDEST_FILE;
+ pLogger->pInt = NULL;
+ pLogger->cGroups = 1;
+ pLogger->afGroups[0] = 0;
+
+ uint32_t cMaxGroups = (uint32_t)((cbLogger - cbRequired) / sizeof(pLogger->afGroups[0]));
+ if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
+ cMaxGroups /= 2;
+ PRTLOGGERINTERNAL pInt;
+ for (;;)
+ {
+ AssertReturn(cMaxGroups > 0, VERR_BUFFER_OVERFLOW);
+ pInt = (PRTLOGGERINTERNAL)&pLogger->afGroups[cMaxGroups];
+ if (!((uintptr_t)pInt & (sizeof(uint64_t) - 1)))
+ break;
+ cMaxGroups--;
+ }
+ pLogger->pInt = (PRTLOGGERINTERNAL)(pLoggerR0Ptr + (uintptr_t)pInt - (uintptr_t)pLogger);
+ pInt->uRevision = RTLOGGERINTERNAL_REV;
+ pInt->cbSelf = RTLOGGERINTERNAL_R0_SIZE;
+ pInt->hSpinMtx = NIL_RTSEMSPINMUTEX; /* Not serialized. */
+ pInt->pfnFlush = (PFNRTLOGFLUSH)pfnFlushR0Ptr;
+ pInt->pfnPrefix = NULL;
+ pInt->pvPrefixUserArg = NULL;
+ pInt->fPendingPrefix = false;
+ pInt->cMaxGroups = cMaxGroups;
+ pInt->papszGroups = NULL;
+ pInt->cMaxEntriesPerGroup = UINT32_MAX;
+ if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
+ {
+ memset(pInt + 1, 0, sizeof(uint32_t) * cMaxGroups);
+ pInt->pacEntriesPerGroup= (uint32_t *)(pLogger->pInt + 1);
+ }
+ else
+ pInt->pacEntriesPerGroup= NULL;
+
+ pLogger->u32Magic = RTLOGGER_MAGIC;
return VINF_SUCCESS;
}
RT_EXPORT_SYMBOL(RTLogCreateForR0);
-#endif /* IN_RING3 */
-/**
- * Copies the group settings and flags from logger instance to another.
- *
- * @returns IPRT status code.
- * @param pDstLogger The destination logger instance.
- * @param pSrcLogger The source logger instance. If NULL the default one is used.
- * @param fFlagsOr OR mask for the flags.
- * @param fFlagsAnd AND mask for the flags.
- */
-RTDECL(int) RTLogCopyGroupsAndFlags(PRTLOGGER pDstLogger, PCRTLOGGER pSrcLogger, unsigned fFlagsOr, unsigned fFlagsAnd)
+RTDECL(size_t) RTLogCalcSizeForR0(uint32_t cGroups, uint32_t fFlags)
{
- int rc;
- unsigned cGroups;
+ size_t cb = RT_OFFSETOF(RTLOGGER, afGroups[cGroups]);
+ cb = RT_ALIGN_Z(cb, sizeof(uint64_t));
+ cb += sizeof(RTLOGGERINTERNAL);
+ if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
+ cb += sizeof(uint32_t) * cGroups;
+ return cb;
+}
+RT_EXPORT_SYMBOL(RTLogCalcSizeForR0);
+
+RTDECL(int) RTLogCopyGroupsAndFlagsForR0(PRTLOGGER pDstLogger, RTR0PTR pDstLoggerR0Ptr,
+ PCRTLOGGER pSrcLogger, uint32_t fFlagsOr, uint32_t fFlagsAnd)
+{
/*
* Validate input.
*/
@@ -925,7 +1011,7 @@ RTDECL(int) RTLogCopyGroupsAndFlags(PRTLOGGER pDstLogger, PCRTLOGGER pSrcLogger,
pSrcLogger = RTLogDefaultInstance();
if (!pSrcLogger)
{
- pDstLogger->fFlags |= RTLOGFLAGS_DISABLED;
+ pDstLogger->fFlags |= RTLOGFLAGS_DISABLED | fFlagsOr;
pDstLogger->cGroups = 1;
pDstLogger->afGroups[0] = 0;
return VINF_SUCCESS;
@@ -935,23 +1021,92 @@ RTDECL(int) RTLogCopyGroupsAndFlags(PRTLOGGER pDstLogger, PCRTLOGGER pSrcLogger,
/*
* Copy flags and group settings.
*/
- pDstLogger->fFlags = (pSrcLogger->fFlags & fFlagsAnd) | fFlagsOr;
+ pDstLogger->fFlags = (pSrcLogger->fFlags & fFlagsAnd & ~RTLOGFLAGS_RESTRICT_GROUPS) | fFlagsOr;
- rc = VINF_SUCCESS;
- cGroups = pSrcLogger->cGroups;
- if (cGroups < pDstLogger->cMaxGroups)
+ PRTLOGGERINTERNAL pDstInt = (PRTLOGGERINTERNAL)((uintptr_t)pDstLogger->pInt - pDstLoggerR0Ptr + (uintptr_t)pDstLogger);
+ int rc = VINF_SUCCESS;
+ uint32_t cGroups = pSrcLogger->cGroups;
+ if (cGroups > pDstInt->cMaxGroups)
{
- AssertMsgFailed(("cMaxGroups=%zd cGroups=%zd (min size %d)\n", pDstLogger->cMaxGroups,
- pSrcLogger->cGroups, RT_OFFSETOF(RTLOGGER, afGroups[pSrcLogger->cGroups])));
+ AssertMsgFailed(("cMaxGroups=%zd cGroups=%zd (min size %d)\n", pDstInt->cMaxGroups,
+ pSrcLogger->cGroups, RT_OFFSETOF(RTLOGGER, afGroups[pSrcLogger->cGroups]) + RTLOGGERINTERNAL_R0_SIZE));
rc = VERR_INVALID_PARAMETER;
- cGroups = pDstLogger->cMaxGroups;
+ cGroups = pDstInt->cMaxGroups;
}
memcpy(&pDstLogger->afGroups[0], &pSrcLogger->afGroups[0], cGroups * sizeof(pDstLogger->afGroups[0]));
pDstLogger->cGroups = cGroups;
return rc;
}
-RT_EXPORT_SYMBOL(RTLogCopyGroupsAndFlags);
+RT_EXPORT_SYMBOL(RTLogCopyGroupsAndFlagsForR0);
+
+
+RTDECL(int) RTLogSetCustomPrefixCallbackForR0(PRTLOGGER pLogger, RTR0PTR pLoggerR0Ptr,
+ RTR0PTR pfnCallbackR0Ptr, RTR0PTR pvUserR0Ptr)
+{
+ AssertPtrReturn(pLogger, VERR_INVALID_POINTER);
+ AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
+
+ /*
+ * Do the work.
+ */
+ PRTLOGGERINTERNAL pInt = (PRTLOGGERINTERNAL)((uintptr_t)pLogger->pInt - pLoggerR0Ptr + (uintptr_t)pLogger);
+ AssertReturn(pInt->uRevision == RTLOGGERINTERNAL_REV, VERR_LOG_REVISION_MISMATCH);
+ pInt->pvPrefixUserArg = (void *)pvUserR0Ptr;
+ pInt->pfnPrefix = (PFNRTLOGPREFIX)pfnCallbackR0Ptr;
+
+ return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTLogSetCustomPrefixCallbackForR0);
+
+RTDECL(void) RTLogFlushR0(PRTLOGGER pLogger, PRTLOGGER pLoggerR0)
+{
+ /*
+ * Resolve defaults.
+ */
+ if (!pLogger)
+ {
+ pLogger = RTLogDefaultInstance();
+ if (!pLogger)
+ {
+ /* flushing to "/dev/null". */
+ if (pLoggerR0->offScratch)
+ pLoggerR0->offScratch = 0;
+ return;
+ }
+ }
+
+ /*
+ * Any thing to flush?
+ */
+ if ( pLoggerR0->offScratch
+ || pLogger->offScratch)
+ {
+ /*
+ * Acquire logger semaphores.
+ */
+ int rc = rtlogLock(pLogger);
+ if (RT_FAILURE(rc))
+ return;
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Write whatever the GC instance contains to the HC one, and then
+ * flush the HC instance.
+ */
+ if (pLoggerR0->offScratch)
+ {
+ rtLogOutput(pLogger, pLoggerR0->achScratch, pLoggerR0->offScratch);
+ rtLogOutput(pLogger, NULL, 0);
+ pLoggerR0->offScratch = 0;
+ }
+ }
+ rtlogUnlock(pLogger);
+ }
+}
+RT_EXPORT_SYMBOL(RTLogFlushR0);
+
+# endif /* IN_RING3 */
/**
@@ -980,7 +1135,7 @@ RTDECL(void) RTLogFlushToLogger(PRTLOGGER pSrcLogger, PRTLOGGER pDstLogger)
if (RT_SUCCESS(rc))
{
pSrcLogger->offScratch = 0;
- rtlogLock(pSrcLogger);
+ rtlogUnlock(pSrcLogger);
}
}
return;
@@ -1049,8 +1204,8 @@ RTDECL(int) RTLogSetCustomPrefixCallback(PRTLOGGER pLogger, PFNRTLOGPREFIX pfnCa
* Do the work.
*/
rtlogLock(pLogger);
- pLogger->pvPrefixUserArg = pvUser;
- pLogger->pfnPrefix = pfnCallback;
+ pLogger->pInt->pvPrefixUserArg = pvUser;
+ pLogger->pInt->pfnPrefix = pfnCallback;
rtlogUnlock(pLogger);
return VINF_SUCCESS;
@@ -1218,7 +1373,7 @@ RTDECL(int) RTLogGroupSettings(PRTLOGGER pLogger, const char *pszVar)
for (i = 0; i < pLogger->cGroups; i++)
{
const char *psz2 = (const char*)pszStart;
- if (rtlogIsGroupMatching(pLogger->papszGroups[i], &psz2, cch))
+ if (rtlogIsGroupMatching(pLogger->pInt->papszGroups[i], &psz2, cch))
{
unsigned fFlags = RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1;
if (*psz2 == '.' || *psz2 == '=')
@@ -1278,10 +1433,10 @@ static unsigned rtlogGroupFlags(const char *psz)
{ "level6", RTLOGGRPFLAGS_LEVEL_6 },
{ "f", RTLOGGRPFLAGS_FLOW },
{ "flow", RTLOGGRPFLAGS_FLOW },
+ { "restrict", RTLOGGRPFLAGS_RESTRICT },
{ "lelik", RTLOGGRPFLAGS_LELIK },
{ "michael", RTLOGGRPFLAGS_MICHAEL },
- { "dmik", RTLOGGRPFLAGS_DMIK },
{ "sunlover", RTLOGGRPFLAGS_SUNLOVER },
{ "achim", RTLOGGRPFLAGS_ACHIM },
{ "achimha", RTLOGGRPFLAGS_ACHIM },
@@ -1343,9 +1498,9 @@ static unsigned rtlogGroupFlags(const char *psz)
*/
static int rtLogGetGroupSettingsAddOne(const char *pszName, uint32_t fGroup, char **ppszBuf, size_t *pcchBuf, bool *pfNotFirst)
{
-#define APPEND_PSZ(psz,cch) do { memcpy(*ppszBuf, (psz), (cch)); *ppszBuf += (cch); *pcchBuf -= (cch); } while (0)
-#define APPEND_SZ(sz) APPEND_PSZ(sz, sizeof(sz) - 1)
-#define APPEND_CH(ch) do { **ppszBuf = (ch); *ppszBuf += 1; *pcchBuf -= 1; } while (0)
+# define APPEND_PSZ(psz,cch) do { memcpy(*ppszBuf, (psz), (cch)); *ppszBuf += (cch); *pcchBuf -= (cch); } while (0)
+# define APPEND_SZ(sz) APPEND_PSZ(sz, sizeof(sz) - 1)
+# define APPEND_CH(ch) do { **ppszBuf = (ch); *ppszBuf += 1; *pcchBuf -= 1; } while (0)
/*
* Add the name.
@@ -1381,9 +1536,9 @@ static int rtLogGetGroupSettingsAddOne(const char *pszName, uint32_t fGroup, cha
else
return VERR_BUFFER_OVERFLOW;
-#undef APPEND_PSZ
-#undef APPEND_SZ
-#undef APPEND_CH
+# undef APPEND_PSZ
+# undef APPEND_SZ
+# undef APPEND_CH
return VINF_SUCCESS;
}
@@ -1442,7 +1597,7 @@ RTDECL(int) RTLogGetGroupSettings(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf
fGroup = pLogger->afGroups[i];
if (fGroup)
{
- const char *pszName = pLogger->papszGroups[i];
+ const char *pszName = pLogger->pInt->papszGroups[i];
if (pszName)
{
rc = rtLogGetGroupSettingsAddOne(pszName, fGroup, &pszBuf, &cchBuf, &fNotFirst);
@@ -1457,8 +1612,8 @@ RTDECL(int) RTLogGetGroupSettings(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf
return rc;
}
RT_EXPORT_SYMBOL(RTLogGetGroupSettings);
-#endif /* !IN_RC */
+#endif /* !IN_RC */
/**
* Updates the flags for the logger instance using the specified
@@ -1587,6 +1742,29 @@ RTDECL(bool) RTLogSetBuffering(PRTLOGGER pLogger, bool fBuffered)
}
RT_EXPORT_SYMBOL(RTLogSetBuffering);
+
+#ifdef IN_RING3
+RTDECL(uint32_t) RTLogSetGroupLimit(PRTLOGGER pLogger, uint32_t cMaxEntriesPerGroup)
+{
+ /*
+ * Resolve the logger instance.
+ */
+ if (!pLogger)
+ {
+ pLogger = RTLogDefaultInstance();
+ if (!pLogger)
+ return UINT32_MAX;
+ }
+
+ rtlogLock(pLogger);
+ uint32_t cOld = pLogger->pInt->cMaxEntriesPerGroup;
+ pLogger->pInt->cMaxEntriesPerGroup = cMaxEntriesPerGroup;
+ rtlogUnlock(pLogger);
+
+ return cOld;
+}
+#endif
+
#ifndef IN_RC
/**
@@ -1721,27 +1899,27 @@ RTDECL(int) RTLogDestinations(PRTLOGGER pLogger, char const *pszVar)
/* log file name */
if (i == 0 /* file */ && !fNo)
{
- AssertReturn(cch < RTPATH_MAX, VERR_OUT_OF_RANGE);
- memcpy(pLogger->pFile->pszFilename, pszVar, cch);
- pLogger->pFile->pszFilename[cch] = '\0';
+ AssertReturn(cch < sizeof(pLogger->pInt->szFilename), VERR_OUT_OF_RANGE);
+ memcpy(pLogger->pInt->szFilename, pszVar, cch);
+ pLogger->pInt->szFilename[cch] = '\0';
}
/* log directory */
else if (i == 1 /* dir */ && !fNo)
{
- char szTmp[RTPATH_MAX];
- const char *pszFile = RTPathFilename(pLogger->pFile->pszFilename);
+ char szTmp[sizeof(pLogger->pInt->szFilename)];
+ const char *pszFile = RTPathFilename(pLogger->pInt->szFilename);
size_t cchFile = pszFile ? strlen(pszFile) : 0;
- AssertReturn(cchFile + cch + 1 < RTPATH_MAX, VERR_OUT_OF_RANGE);
+ AssertReturn(cchFile + cch + 1 < sizeof(pLogger->pInt->szFilename), VERR_OUT_OF_RANGE);
memcpy(szTmp, cchFile ? pszFile : "", cchFile + 1);
- memcpy(pLogger->pFile->pszFilename, pszVar, cch);
- pLogger->pFile->pszFilename[cch] = '\0';
- RTPathStripTrailingSlash(pLogger->pFile->pszFilename);
+ memcpy(pLogger->pInt->szFilename, pszVar, cch);
+ pLogger->pInt->szFilename[cch] = '\0';
+ RTPathStripTrailingSlash(pLogger->pInt->szFilename);
- cch = strlen(pLogger->pFile->pszFilename);
- pLogger->pFile->pszFilename[cch++] = '/';
- memcpy(&pLogger->pFile->pszFilename[cch], szTmp, cchFile);
- pLogger->pFile->pszFilename[cch+cchFile] = '\0';
+ cch = strlen(pLogger->pInt->szFilename);
+ pLogger->pInt->szFilename[cch++] = '/';
+ memcpy(&pLogger->pInt->szFilename[cch], szTmp, cchFile);
+ pLogger->pInt->szFilename[cch + cchFile] = '\0';
}
else if (i == 2 /* history */)
{
@@ -1753,10 +1931,10 @@ RTDECL(int) RTLogDestinations(PRTLOGGER pLogger, char const *pszVar)
if (RT_SUCCESS(rc))
rc = RTStrToUInt32Full(szTmp, 0, &cHistory);
AssertMsgReturn(RT_SUCCESS(rc) && cHistory < _1M, ("Invalid history value %s (%Rrc)!\n", szTmp, rc), rc);
- pLogger->pFile->cHistory = cHistory;
+ pLogger->pInt->cHistory = cHistory;
}
else
- pLogger->pFile->cHistory = 0;
+ pLogger->pInt->cHistory = 0;
}
else if (i == 3 /* histsize */)
{
@@ -1765,13 +1943,13 @@ RTDECL(int) RTLogDestinations(PRTLOGGER pLogger, char const *pszVar)
char szTmp[32];
int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszVar, cch);
if (RT_SUCCESS(rc))
- rc = RTStrToUInt64Full(szTmp, 0, &pLogger->pFile->cbHistoryFileMax);
+ rc = RTStrToUInt64Full(szTmp, 0, &pLogger->pInt->cbHistoryFileMax);
AssertMsgRCReturn(rc, ("Invalid history file size value %s (%Rrc)!\n", szTmp, rc), rc);
- if (pLogger->pFile->cbHistoryFileMax == 0)
- pLogger->pFile->cbHistoryFileMax = UINT64_MAX;
+ if (pLogger->pInt->cbHistoryFileMax == 0)
+ pLogger->pInt->cbHistoryFileMax = UINT64_MAX;
}
else
- pLogger->pFile->cbHistoryFileMax = UINT64_MAX;
+ pLogger->pInt->cbHistoryFileMax = UINT64_MAX;
}
else if (i == 4 /* histtime */)
{
@@ -1780,13 +1958,13 @@ RTDECL(int) RTLogDestinations(PRTLOGGER pLogger, char const *pszVar)
char szTmp[32];
int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszVar, cch);
if (RT_SUCCESS(rc))
- rc = RTStrToUInt32Full(szTmp, 0, &pLogger->pFile->cSecsHistoryTimeSlot);
+ rc = RTStrToUInt32Full(szTmp, 0, &pLogger->pInt->cSecsHistoryTimeSlot);
AssertMsgRCReturn(rc, ("Invalid history time slot value %s (%Rrc)!\n", szTmp, rc), rc);
- if (pLogger->pFile->cSecsHistoryTimeSlot == 0)
- pLogger->pFile->cSecsHistoryTimeSlot = UINT32_MAX;
+ if (pLogger->pInt->cSecsHistoryTimeSlot == 0)
+ pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
}
else
- pLogger->pFile->cSecsHistoryTimeSlot = UINT32_MAX;
+ pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
}
else
AssertMsgFailedReturn(("Invalid destination value! %s%s doesn't take a value!\n",
@@ -1862,17 +2040,16 @@ RTDECL(int) RTLogGetDestinations(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
fNotFirst = true;
}
-#ifdef IN_RING3
+# ifdef IN_RING3
/*
* Add the filename.
*/
- if ( (fDestFlags & RTLOGDEST_FILE)
- && VALID_PTR(pLogger->pFile->pszFilename))
+ if (fDestFlags & RTLOGDEST_FILE)
{
rc = RTStrCopyP(&pszBuf, &cchBuf, fNotFirst ? " file=" : "file=");
if (RT_FAILURE(rc))
return rc;
- rc = RTStrCopyP(&pszBuf, &cchBuf, pLogger->pFile->pszFilename);
+ rc = RTStrCopyP(&pszBuf, &cchBuf, pLogger->pInt->szFilename);
if (RT_FAILURE(rc))
return rc;
fNotFirst = true;
@@ -1881,29 +2058,29 @@ RTDECL(int) RTLogGetDestinations(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
if (fDestFlags & RTLOGDEST_FILE)
{
char szNum[32];
- if (pLogger->pFile->cHistory)
+ if (pLogger->pInt->cHistory)
{
- RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "history=%u" : " history=%u", pLogger->pFile->cHistory);
+ RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "history=%u" : " history=%u", pLogger->pInt->cHistory);
rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
if (RT_FAILURE(rc))
return rc;
}
- if (pLogger->pFile->cbHistoryFileMax != UINT64_MAX)
+ if (pLogger->pInt->cbHistoryFileMax != UINT64_MAX)
{
- RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "histsize=%llu" : " histsize=%llu", pLogger->pFile->cbHistoryFileMax);
+ RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "histsize=%llu" : " histsize=%llu", pLogger->pInt->cbHistoryFileMax);
rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
if (RT_FAILURE(rc))
return rc;
}
- if (pLogger->pFile->cSecsHistoryTimeSlot != UINT32_MAX)
+ if (pLogger->pInt->cSecsHistoryTimeSlot != UINT32_MAX)
{
- RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "histtime=%llu" : " histtime=%llu", pLogger->pFile->cSecsHistoryTimeSlot);
+ RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "histtime=%llu" : " histtime=%llu", pLogger->pInt->cSecsHistoryTimeSlot);
rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
if (RT_FAILURE(rc))
return rc;
}
}
-#endif /* IN_RING3 */
+# endif /* IN_RING3 */
return VINF_SUCCESS;
}
@@ -2130,7 +2307,7 @@ RTDECL(int) RTLogSetDefaultInstanceThread(PRTLOGGER pLogger, uintptr_t uKey)
return rc;
}
RT_EXPORT_SYMBOL(RTLogSetDefaultInstanceThread);
-#endif
+#endif /* IN_RING0 */
/**
@@ -2208,9 +2385,32 @@ RTDECL(void) RTLogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
}
/*
- * Call worker.
+ * Check restrictions and call worker.
*/
- rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args);
+#ifndef IN_RC
+ if (RT_UNLIKELY( (pLogger->fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
+ && iGroup < pLogger->cGroups
+ && (pLogger->afGroups[iGroup] & RTLOGGRPFLAGS_RESTRICT)
+ && ++pLogger->pInt->pacEntriesPerGroup[iGroup] >= pLogger->pInt->cMaxEntriesPerGroup ))
+ {
+ uint32_t cEntries = pLogger->pInt->pacEntriesPerGroup[iGroup];
+ if (cEntries > pLogger->pInt->cMaxEntriesPerGroup)
+ pLogger->pInt->pacEntriesPerGroup[iGroup] = cEntries - 1;
+ else
+ {
+ rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args);
+ if ( pLogger->pInt->papszGroups
+ && pLogger->pInt->papszGroups[iGroup])
+ rtlogLoggerExFLocked(pLogger, fFlags, iGroup, "%u messages from group %s (#%u), muting it.\n",
+ cEntries, pLogger->pInt->papszGroups[iGroup], iGroup);
+ else
+ rtlogLoggerExFLocked(pLogger, fFlags, iGroup, "%u messages from group #%u, muting it.\n",
+ cEntries, iGroup);
+ }
+ }
+ else
+#endif
+ rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args);
/*
* Release the semaphore.
@@ -2260,10 +2460,10 @@ static void rtR0LogLoggerExFallbackFlush(PRTR0LOGLOGGERFALLBACK pThis)
if (pThis->fDestFlags & RTLOGDEST_STDERR)
RTLogWriteStdErr(pThis->achScratch, pThis->offScratch);
-#ifndef LOG_NO_COM
+# ifndef LOG_NO_COM
if (pThis->fDestFlags & RTLOGDEST_COM)
RTLogWriteCom(pThis->achScratch, pThis->offScratch);
-#endif
+# endif
/* empty the buffer. */
pThis->offScratch = 0;
@@ -2400,20 +2600,20 @@ static int rtlogFileOpen(PRTLOGGER pLogger, char *pszErrorMsg, size_t cchErrorMs
if (pLogger->fFlags & RTLOGFLAGS_WRITE_THROUGH)
fOpen |= RTFILE_O_WRITE_THROUGH;
- int rc = RTFileOpen(&pLogger->pFile->File, pLogger->pFile->pszFilename, fOpen);
+ int rc = RTFileOpen(&pLogger->pInt->hFile, pLogger->pInt->szFilename, fOpen);
if (RT_FAILURE(rc))
{
- pLogger->pFile->File = NIL_RTFILE;
+ pLogger->pInt->hFile = NIL_RTFILE;
if (pszErrorMsg)
- RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("could not open file '%s' (fOpen=%#x)"), pLogger->pFile->pszFilename, fOpen);
+ RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("could not open file '%s' (fOpen=%#x)"), pLogger->pInt->szFilename, fOpen);
}
else
{
- rc = RTFileGetSize(pLogger->pFile->File, &pLogger->pFile->cbHistoryFileWritten);
+ rc = RTFileGetSize(pLogger->pInt->hFile, &pLogger->pInt->cbHistoryFileWritten);
if (RT_FAILURE(rc))
{
/* Don't complain if this fails, assume the file is empty. */
- pLogger->pFile->cbHistoryFileWritten = 0;
+ pLogger->pInt->cbHistoryFileWritten = 0;
rc = VINF_SUCCESS;
}
}
@@ -2435,12 +2635,12 @@ static int rtlogFileOpen(PRTLOGGER pLogger, char *pszErrorMsg, size_t cchErrorMs
static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst)
{
/* Suppress rotating empty log files simply because the time elapsed. */
- if (RT_UNLIKELY(!pLogger->pFile->cbHistoryFileWritten))
- pLogger->pFile->uHistoryTimeSlotStart = uTimeSlot;
+ if (RT_UNLIKELY(!pLogger->pInt->cbHistoryFileWritten))
+ pLogger->pInt->uHistoryTimeSlotStart = uTimeSlot;
/* Check rotation condition: file still small enough and not too old? */
- if (RT_LIKELY( pLogger->pFile->cbHistoryFileWritten < pLogger->pFile->cbHistoryFileMax
- && uTimeSlot == pLogger->pFile->uHistoryTimeSlotStart))
+ if (RT_LIKELY( pLogger->pInt->cbHistoryFileWritten < pLogger->pInt->cbHistoryFileMax
+ && uTimeSlot == pLogger->pInt->uHistoryTimeSlotStart))
return;
/*
@@ -2455,26 +2655,26 @@ static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst)
* Disable log rotation temporarily, otherwise with extreme settings and
* chatty phase logging we could run into endless rotation.
*/
- uint32_t const cSavedHistory = pLogger->pFile->cHistory;
- pLogger->pFile->cHistory = 0;
+ uint32_t const cSavedHistory = pLogger->pInt->cHistory;
+ pLogger->pInt->cHistory = 0;
/*
* Close the old log file.
*/
- if (pLogger->pFile->File != NIL_RTFILE)
+ if (pLogger->pInt->hFile != NIL_RTFILE)
{
/* Use the callback to generate some final log contents, but only if
* this is a rotation with a fully set up logger. Leave the other case
* to the RTLogCreateExV function. */
- if (pLogger->pFile->pfnPhase && !fFirst)
+ if (pLogger->pInt->pfnPhase && !fFirst)
{
uint32_t fODestFlags = pLogger->fDestFlags;
pLogger->fDestFlags &= RTLOGDEST_FILE;
- pLogger->pFile->pfnPhase(pLogger, RTLOGPHASE_PREROTATE, rtlogPhaseMsgLocked);
+ pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_PREROTATE, rtlogPhaseMsgLocked);
pLogger->fDestFlags = fODestFlags;
}
- RTFileClose(pLogger->pFile->File);
- pLogger->pFile->File = NIL_RTFILE;
+ RTFileClose(pLogger->pInt->hFile);
+ pLogger->pInt->hFile = NIL_RTFILE;
}
if (cSavedHistory)
@@ -2484,15 +2684,16 @@ static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst)
*/
for (uint32_t i = cSavedHistory - 1; i + 1 > 0; i--)
{
- char szOldName[RTPATH_MAX];
+ char szOldName[sizeof(pLogger->pInt->szFilename) + 32];
if (i > 0)
- RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLogger->pFile->pszFilename, i);
+ RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLogger->pInt->szFilename, i);
else
- RTStrCopy(szOldName, sizeof(szOldName), pLogger->pFile->pszFilename);
- char szNewName[RTPATH_MAX];
- RTStrPrintf(szNewName, sizeof(szNewName), "%s.%u", pLogger->pFile->pszFilename, i + 1);
- if (RTFileRename(szOldName, szNewName,
- RTFILEMOVE_FLAGS_REPLACE) == VERR_FILE_NOT_FOUND)
+ RTStrCopy(szOldName, sizeof(szOldName), pLogger->pInt->szFilename);
+
+ char szNewName[sizeof(pLogger->pInt->szFilename) + 32];
+ RTStrPrintf(szNewName, sizeof(szNewName), "%s.%u", pLogger->pInt->szFilename, i + 1);
+ if ( RTFileRename(szOldName, szNewName, RTFILEMOVE_FLAGS_REPLACE)
+ == VERR_FILE_NOT_FOUND)
RTFileDelete(szNewName);
}
@@ -2501,8 +2702,8 @@ static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst)
*/
for (uint32_t i = cSavedHistory + 1; ; i++)
{
- char szExcessName[RTPATH_MAX];
- RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLogger->pFile->pszFilename, i);
+ char szExcessName[sizeof(pLogger->pInt->szFilename) + 32];
+ RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLogger->pInt->szFilename, i);
int rc = RTFileDelete(szExcessName);
if (RT_FAILURE(rc))
break;
@@ -2512,8 +2713,8 @@ static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst)
/*
* Update logger state and create new log file.
*/
- pLogger->pFile->cbHistoryFileWritten = 0;
- pLogger->pFile->uHistoryTimeSlotStart = uTimeSlot;
+ pLogger->pInt->cbHistoryFileWritten = 0;
+ pLogger->pInt->uHistoryTimeSlotStart = uTimeSlot;
rtlogFileOpen(pLogger, NULL, 0);
/*
@@ -2521,16 +2722,16 @@ static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst)
* is a rotation with a fully set up logger. Leave the other case to the
* RTLogCreateExV function.
*/
- if (pLogger->pFile->pfnPhase && !fFirst)
+ if (pLogger->pInt->pfnPhase && !fFirst)
{
uint32_t const fSavedDestFlags = pLogger->fDestFlags;
pLogger->fDestFlags &= RTLOGDEST_FILE;
- pLogger->pFile->pfnPhase(pLogger, RTLOGPHASE_POSTROTATE, rtlogPhaseMsgLocked);
+ pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_POSTROTATE, rtlogPhaseMsgLocked);
pLogger->fDestFlags = fSavedDestFlags;
}
/* Restore saved values. */
- pLogger->pFile->cHistory = cSavedHistory;
+ pLogger->pInt->cHistory = cSavedHistory;
pLogger->fFlags = fSavedFlags;
}
@@ -2558,14 +2759,14 @@ static void rtlogFlush(PRTLOGGER pLogger)
# ifdef IN_RING3
if (pLogger->fDestFlags & RTLOGDEST_FILE)
{
- if (pLogger->pFile->File != NIL_RTFILE)
+ if (pLogger->pInt->hFile != NIL_RTFILE)
{
- RTFileWrite(pLogger->pFile->File, pLogger->achScratch, pLogger->offScratch, NULL);
+ RTFileWrite(pLogger->pInt->hFile, pLogger->achScratch, pLogger->offScratch, NULL);
if (pLogger->fFlags & RTLOGFLAGS_FLUSH)
- RTFileFlush(pLogger->pFile->File);
+ RTFileFlush(pLogger->pInt->hFile);
}
- if (pLogger->pFile->cHistory)
- pLogger->pFile->cbHistoryFileWritten += pLogger->offScratch;
+ if (pLogger->pInt->cHistory)
+ pLogger->pInt->cbHistoryFileWritten += pLogger->offScratch;
}
# endif
@@ -2581,8 +2782,13 @@ static void rtlogFlush(PRTLOGGER pLogger)
# endif
#endif /* !IN_RC */
+#ifdef IN_RC
if (pLogger->pfnFlush)
pLogger->pfnFlush(pLogger);
+#else
+ if (pLogger->pInt->pfnFlush)
+ pLogger->pInt->pfnFlush(pLogger);
+#endif
/* empty the buffer. */
pLogger->offScratch = 0;
@@ -2594,10 +2800,8 @@ static void rtlogFlush(PRTLOGGER pLogger)
* and footer messages.
*/
if ( (pLogger->fDestFlags & RTLOGDEST_FILE)
- && pLogger->pFile->cHistory)
- rtlogRotate(pLogger,
- RTTimeProgramSecTS() / pLogger->pFile->cSecsHistoryTimeSlot,
- false /* fFirst */);
+ && pLogger->pInt->cHistory)
+ rtlogRotate(pLogger, RTTimeProgramSecTS() / pLogger->pInt->cSecsHistoryTimeSlot, false /* fFirst */);
#endif
}
@@ -2677,16 +2881,21 @@ static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars,
size_t cbRet = 0;
for (;;)
{
- size_t cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1;
- char *psz;
+ size_t cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1;
const char *pszNewLine;
+ char *psz;
+#ifdef IN_RC
+ bool *pfPendingPrefix = &pLogger->fPendingPrefix;
+#else
+ bool *pfPendingPrefix = &pLogger->pInt->fPendingPrefix;
+#endif
/*
* Pending prefix?
*/
- if (pLogger->fPendingPrefix)
+ if (*pfPendingPrefix)
{
- pLogger->fPendingPrefix = false;
+ *pfPendingPrefix = false;
#if defined(DEBUG) && defined(IN_RING3)
/* sanity */
@@ -2879,9 +3088,9 @@ static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars,
}
#ifndef IN_RC
if ( (pLogger->fFlags & RTLOGFLAGS_PREFIX_CUSTOM)
- && pLogger->pfnPrefix)
+ && pLogger->pInt->pfnPrefix)
{
- psz += pLogger->pfnPrefix(pLogger, psz, 31, pLogger->pvPrefixUserArg);
+ psz += pLogger->pInt->pfnPrefix(pLogger, psz, 31, pLogger->pInt->pvPrefixUserArg);
*psz++ = ' '; /* +32 */
}
#endif
@@ -2916,7 +3125,7 @@ static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars,
if (pLogger->fFlags & RTLOGFLAGS_PREFIX_FLAG)
{
#ifdef IN_RING3
- const char *pszGroup = pArgs->iGroup != ~0U ? pLogger->papszGroups[pArgs->iGroup] : NULL;
+ const char *pszGroup = pArgs->iGroup != ~0U ? pLogger->pInt->papszGroups[pArgs->iGroup] : NULL;
#else
const char *pszGroup = NULL;
#endif
@@ -2965,7 +3174,6 @@ static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars,
/* personal groups */
case RTLOGGRPFLAGS_LELIK: pszGroup = "lelik" ; cch = sizeof("lelik" ) - 1; break;
case RTLOGGRPFLAGS_MICHAEL: pszGroup = "Michael" ; cch = sizeof("Michael" ) - 1; break;
- case RTLOGGRPFLAGS_DMIK: pszGroup = "dmik" ; cch = sizeof("dmik" ) - 1; break;
case RTLOGGRPFLAGS_SUNLOVER: pszGroup = "sunlover"; cch = sizeof("sunlover") - 1; break;
case RTLOGGRPFLAGS_ACHIM: pszGroup = "Achim" ; cch = sizeof("Achim" ) - 1; break;
case RTLOGGRPFLAGS_SANDER: pszGroup = "Sander" ; cch = sizeof("Sander" ) - 1; break;
@@ -3023,7 +3231,7 @@ static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars,
else
{
cb = pszNewLine - pachChars + 1;
- pLogger->fPendingPrefix = true;
+ *pfPendingPrefix = true;
}
}
@@ -3044,7 +3252,7 @@ static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars,
cbRet++;
cbChars--;
cb++;
- pLogger->fPendingPrefix = true;
+ *pfPendingPrefix = true;
}
/* done? */
@@ -3101,3 +3309,23 @@ static void rtlogLoggerExVLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iG
rtlogFlush(pLogger);
}
+
+/**
+ * For calling rtlogLoggerExVLocked.
+ *
+ * @param pLogger The logger.
+ * @param fFlags The logging flags.
+ * @param iGroup The group.
+ * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ * only for internal usage!
+ * @param pszFormat Format string.
+ * @param ... Format arguments.
+ */
+static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, va);
+ va_end(va);
+}
+
diff --git a/src/VBox/Runtime/common/log/logcom.cpp b/src/VBox/Runtime/common/log/logcom.cpp
index ed4f26208..065b1dd4d 100644
--- a/src/VBox/Runtime/common/log/logcom.cpp
+++ b/src/VBox/Runtime/common/log/logcom.cpp
@@ -1,4 +1,4 @@
-/* $Id: logcom.cpp $ */
+/* $Id: logcom.cpp 29271 2010-05-09 21:25:16Z vboxsync $ */
/** @file
* IPRT - Logging to Serial Port.
*/
diff --git a/src/VBox/Runtime/common/log/logellipsis.cpp b/src/VBox/Runtime/common/log/logellipsis.cpp
index 48c05840d..ce490429d 100644
--- a/src/VBox/Runtime/common/log/logellipsis.cpp
+++ b/src/VBox/Runtime/common/log/logellipsis.cpp
@@ -1,4 +1,4 @@
-/* $Id: logellipsis.cpp $ */
+/* $Id: logellipsis.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Runtime VBox - Logger, the ellipsis variants.
*/
diff --git a/src/VBox/Runtime/common/log/logformat.cpp b/src/VBox/Runtime/common/log/logformat.cpp
index 40cd7d144..761844c88 100644
--- a/src/VBox/Runtime/common/log/logformat.cpp
+++ b/src/VBox/Runtime/common/log/logformat.cpp
@@ -1,4 +1,4 @@
-/* $Id: logformat.cpp $ */
+/* $Id: logformat.cpp 33496 2010-10-27 12:15:28Z vboxsync $ */
/** @file
* IPRT - Log Formatter.
*/
diff --git a/src/VBox/Runtime/common/log/logrel.cpp b/src/VBox/Runtime/common/log/logrel.cpp
index 64f7eb2a7..7fb5ec746 100644
--- a/src/VBox/Runtime/common/log/logrel.cpp
+++ b/src/VBox/Runtime/common/log/logrel.cpp
@@ -1,4 +1,4 @@
-/* $Id: logrel.cpp $ */
+/* $Id: logrel.cpp 33704 2010-11-02 18:21:28Z vboxsync $ */
/** @file
* Runtime VBox - Release Logger.
*/
diff --git a/src/VBox/Runtime/common/log/logrelellipsis.cpp b/src/VBox/Runtime/common/log/logrelellipsis.cpp
index 5f1806c6b..dbf5619ac 100644
--- a/src/VBox/Runtime/common/log/logrelellipsis.cpp
+++ b/src/VBox/Runtime/common/log/logrelellipsis.cpp
@@ -1,4 +1,4 @@
-/* $Id: logrelellipsis.cpp $ */
+/* $Id: logrelellipsis.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Runtime VBox - Logger, the release ellipsis variants.
*/
diff --git a/src/VBox/Runtime/common/log/tracebuf.cpp b/src/VBox/Runtime/common/log/tracebuf.cpp
new file mode 100644
index 000000000..6751b4385
--- /dev/null
+++ b/src/VBox/Runtime/common/log/tracebuf.cpp
@@ -0,0 +1,662 @@
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "internal/iprt.h"
+#include <iprt/trace.h>
+
+
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/log.h>
+#ifndef IN_RC
+# include <iprt/mem.h>
+#endif
+#if defined(IN_RING0) || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
+# include <iprt/mp.h>
+#else
+# include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/path.h>
+#include <iprt/string.h>
+#include <iprt/time.h>
+
+#include "internal/magics.h"
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/** Alignment used to place the trace buffer members, this should be a multiple
+ * of the cache line size if possible. (We should dynamically determine it.) */
+#define RTTRACEBUF_ALIGNMENT 64
+AssertCompile(RTTRACEBUF_ALIGNMENT >= sizeof(uint64_t) * 2);
+
+/** The maximum number of entries. */
+#define RTTRACEBUF_MAX_ENTRIES _64K
+/** The minimum number of entries. */
+#define RTTRACEBUF_MIN_ENTRIES 4
+/** The default number of entries. */
+#define RTTRACEBUF_DEF_ENTRIES 256
+
+/** The maximum entry size. */
+#define RTTRACEBUF_MAX_ENTRY_SIZE _1M
+/** The minimum entry size. */
+#define RTTRACEBUF_MIN_ENTRY_SIZE RTTRACEBUF_ALIGNMENT
+/** The default entry size. */
+#define RTTRACEBUF_DEF_ENTRY_SIZE 256
+AssertCompile(!(RTTRACEBUF_DEF_ENTRY_SIZE & (RTTRACEBUF_DEF_ENTRY_SIZE - 1)));
+
+/**
+ * The volatile trace buffer members.
+ */
+typedef struct RTTRACEBUFVOLATILE
+{
+ /** Reference counter. */
+ uint32_t volatile cRefs;
+ /** The next entry to make use of. */
+ uint32_t volatile iEntry;
+} RTTRACEBUFVOLATILE;
+/** Pointer to the volatile parts of a trace buffer. */
+typedef RTTRACEBUFVOLATILE *PRTTRACEBUFVOLATILE;
+
+
+/**
+ * Trace buffer entry.
+ */
+typedef struct RTTRACEBUFENTRY
+{
+ /** The nano second entry time stamp. */
+ uint64_t NanoTS;
+ /** The ID of the CPU the event was recorded. */
+ RTCPUID idCpu;
+ /** The message. */
+ char szMsg[RTTRACEBUF_ALIGNMENT - sizeof(uint64_t) - sizeof(RTCPUID)];
+} RTTRACEBUFENTRY;
+AssertCompile(sizeof(RTTRACEBUFENTRY) <= RTTRACEBUF_ALIGNMENT);
+/** Pointer to a trace buffer entry. */
+typedef RTTRACEBUFENTRY *PRTTRACEBUFENTRY;
+
+
+
+/**
+ * Trace buffer structure.
+ *
+ * @remarks This structure must be context agnostic, i.e. no pointers or
+ * other types that may differ between contexts (R3/R0/RC).
+ */
+typedef struct RTTRACEBUFINT
+{
+ /** Magic value (RTTRACEBUF_MAGIC). */
+ uint32_t u32Magic;
+ /** The entry size. */
+ uint32_t cbEntry;
+ /** The number of entries. */
+ uint32_t cEntries;
+ /** Flags (always zero for now). */
+ uint32_t fFlags;
+ /** The offset to the volatile members (RTTRACEBUFVOLATILE) (relative to
+ * the start of this structure). */
+ uint32_t offVolatile;
+ /** The offset to the entries (relative to the start of this structure). */
+ uint32_t offEntries;
+ /** Reserved entries. */
+ uint32_t au32Reserved[2];
+} RTTRACEBUFINT;
+/** Pointer to a const trace buffer. */
+typedef RTTRACEBUFINT const *PCRTTRACEBUFINT;
+
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+/**
+ * Get the current CPU Id.
+ */
+#if defined(IN_RING0) || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
+# define RTTRACEBUF_CUR_CPU() RTMpCpuId()
+#else
+# define RTTRACEBUF_CUR_CPU() ASMGetApicId()
+#endif
+
+/** Calculates the address of the volatile trace buffer members. */
+#define RTTRACEBUF_TO_VOLATILE(a_pThis) ((PRTTRACEBUFVOLATILE)((uint8_t *)(a_pThis) + (a_pThis)->offVolatile))
+
+/** Calculates the address of a trace buffer entry. */
+#define RTTRACEBUF_TO_ENTRY(a_pThis, a_iEntry) \
+ ((PRTTRACEBUFENTRY)( (uint8_t *)(a_pThis) + (a_pThis)->offEntries + (a_iEntry) * (a_pThis)->cbEntry ))
+
+/** Validates a trace buffer handle and returns rc if not valid. */
+#define RTTRACEBUF_VALID_RETURN_RC(a_pThis, a_rc) \
+ do { \
+ AssertPtrReturn((a_pThis), (a_rc)); \
+ AssertReturn((a_pThis)->u32Magic == RTTRACEBUF_MAGIC, (a_rc)); \
+ AssertReturn((a_pThis)->offVolatile < RTTRACEBUF_ALIGNMENT * 2, (a_rc)); \
+ AssertReturn(RTTRACEBUF_TO_VOLATILE(a_pThis)->cRefs > 0, (a_rc)); \
+ } while (0)
+
+/**
+ * Resolves and validates a trace buffer handle and returns rc if not valid.
+ *
+ * @param a_hTraceBuf The trace buffer handle passed by the user.
+ * @param a_pThis Where to store the trace buffer pointer.
+ */
+#define RTTRACEBUF_RESOLVE_VALIDATE_RETAIN_RETURN(a_hTraceBuf, a_pThis) \
+ do { \
+ uint32_t cRefs; \
+ if ((a_hTraceBuf) == RTTRACEBUF_DEFAULT) \
+ { \
+ (a_pThis) = RTTraceGetDefaultBuf(); \
+ if (!RT_VALID_PTR(a_pThis)) \
+ return VERR_NOT_FOUND; \
+ } \
+ else \
+ { \
+ (a_pThis) = (a_hTraceBuf); \
+ AssertPtrReturn((a_pThis), VERR_INVALID_HANDLE); \
+ } \
+ AssertReturn((a_pThis)->u32Magic == RTTRACEBUF_MAGIC, VERR_INVALID_HANDLE); \
+ AssertReturn((a_pThis)->offVolatile < RTTRACEBUF_ALIGNMENT * 2, VERR_INVALID_HANDLE); \
+ \
+ cRefs = ASMAtomicIncU32(&RTTRACEBUF_TO_VOLATILE(a_pThis)->cRefs); \
+ if (RT_UNLIKELY(cRefs < 1 || cRefs >= _1M)) \
+ { \
+ ASMAtomicDecU32(&RTTRACEBUF_TO_VOLATILE(a_pThis)->cRefs); \
+ AssertFailedReturn(VERR_INVALID_HANDLE); \
+ } \
+ } while (0)
+
+
+/**
+ * Drops a trace buffer reference.
+ *
+ * @param a_pThis Pointer to the trace buffer.
+ */
+#define RTTRACEBUF_DROP_REFERENCE(a_pThis) \
+ do { \
+ uint32_t cRefs = ASMAtomicDecU32(&RTTRACEBUF_TO_VOLATILE(a_pThis)->cRefs); \
+ if (!cRefs) \
+ rtTraceBufDestroy((RTTRACEBUFINT *)a_pThis); \
+ } while (0)
+
+
+/**
+ * The prologue code for a RTTraceAddSomething function.
+ *
+ * Resolves a trace buffer handle, grabs a reference to it and allocates the
+ * next entry. Return with an appropriate error status on failure.
+ *
+ * @param a_hTraceBuf The trace buffer handle passed by the user.
+ *
+ * @remarks This is kind of ugly, sorry.
+ */
+#define RTTRACEBUF_ADD_PROLOGUE(a_hTraceBuf) \
+ int rc; \
+ uint32_t cRefs; \
+ uint32_t iEntry; \
+ PCRTTRACEBUFINT pThis; \
+ PRTTRACEBUFVOLATILE pVolatile; \
+ PRTTRACEBUFENTRY pEntry; \
+ char *pszBuf; \
+ size_t cchBuf; \
+ \
+ /* Resolve and validate the handle. */ \
+ if ((a_hTraceBuf) == RTTRACEBUF_DEFAULT) \
+ { \
+ pThis = RTTraceGetDefaultBuf(); \
+ if (!RT_VALID_PTR(pThis)) \
+ return VERR_NOT_FOUND; \
+ } \
+ else if ((a_hTraceBuf) != NIL_RTTRACEBUF) \
+ { \
+ pThis = (a_hTraceBuf); \
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE); \
+ } \
+ else \
+ return VERR_INVALID_HANDLE; \
+ \
+ AssertReturn(pThis->u32Magic == RTTRACEBUF_MAGIC, VERR_INVALID_HANDLE); \
+ if (pThis->fFlags & RTTRACEBUF_FLAGS_DISABLED) \
+ return VINF_SUCCESS; \
+ AssertReturn(pThis->offVolatile < RTTRACEBUF_ALIGNMENT * 2, VERR_INVALID_HANDLE); \
+ pVolatile = RTTRACEBUF_TO_VOLATILE(pThis); \
+ \
+ /* Grab a reference. */ \
+ cRefs = ASMAtomicIncU32(&pVolatile->cRefs); \
+ if (RT_UNLIKELY(cRefs < 1 || cRefs >= _1M)) \
+ { \
+ ASMAtomicDecU32(&pVolatile->cRefs); \
+ AssertFailedReturn(VERR_INVALID_HANDLE); \
+ } \
+ \
+ /* Grab the next entry and set the time stamp. */ \
+ iEntry = ASMAtomicIncU32(&pVolatile->iEntry) - 1; \
+ iEntry %= pThis->cEntries; \
+ pEntry = RTTRACEBUF_TO_ENTRY(pThis, iEntry); \
+ pEntry->NanoTS = RTTimeNanoTS(); \
+ pEntry->idCpu = RTTRACEBUF_CUR_CPU(); \
+ pszBuf = &pEntry->szMsg[0]; \
+ *pszBuf = '\0'; \
+ cchBuf = pThis->cbEntry - RT_OFFSETOF(RTTRACEBUFENTRY, szMsg) - 1; \
+ rc = VINF_SUCCESS
+
+
+/**
+ * Used by a RTTraceAddPosSomething to store the source position in the entry
+ * prior to adding the actual trace message text.
+ *
+ * Both pszBuf and cchBuf will be adjusted such that pszBuf points and the zero
+ * terminator after the source position part.
+ */
+#define RTTRACEBUF_ADD_STORE_SRC_POS() \
+ do { \
+ /* file(line): - no path */ \
+ size_t cchPos = RTStrPrintf(pszBuf, cchBuf, "%s(%d): ", RTPathFilename(pszFile), iLine); \
+ pszBuf += cchPos; \
+ cchBuf -= cchPos; \
+ } while (0)
+
+
+/**
+ * The epilogue code for a RTTraceAddSomething function.
+ *
+ * This will release the trace buffer reference.
+ */
+#define RTTRACEBUF_ADD_EPILOGUE() \
+ cRefs = ASMAtomicDecU32(&pVolatile->cRefs); \
+ if (!cRefs) \
+ rtTraceBufDestroy((RTTRACEBUFINT *)pThis); \
+ return rc
+
+
+#ifndef IN_RC /* Drop this in RC context (too lazy to split the file). */
+
+RTDECL(int) RTTraceBufCreate(PRTTRACEBUF phTraceBuf, uint32_t cEntries, uint32_t cbEntry, uint32_t fFlags)
+{
+ AssertPtrReturn(phTraceBuf, VERR_INVALID_POINTER);
+ AssertReturn(!(fFlags & ~(RTTRACEBUF_FLAGS_MASK & ~ RTTRACEBUF_FLAGS_FREE_ME)), VERR_INVALID_PARAMETER);
+ AssertMsgReturn(cbEntry <= RTTRACEBUF_MAX_ENTRIES, ("%#x\n", cbEntry), VERR_OUT_OF_RANGE);
+ AssertMsgReturn(cEntries <= RTTRACEBUF_MAX_ENTRY_SIZE, ("%#x\n", cEntries), VERR_OUT_OF_RANGE);
+
+ /*
+ * Apply default and alignment adjustments.
+ */
+ if (!cbEntry)
+ cbEntry = RTTRACEBUF_DEF_ENTRY_SIZE;
+ else
+ cbEntry = RT_ALIGN_32(cbEntry, RTTRACEBUF_ALIGNMENT);
+
+ if (!cEntries)
+ cEntries = RTTRACEBUF_DEF_ENTRIES;
+ else if (cEntries < RTTRACEBUF_MIN_ENTRIES)
+ cEntries = RTTRACEBUF_MIN_ENTRIES;
+
+ /*
+ * Calculate the required buffer size, allocte it and hand it on to the
+ * carver API.
+ */
+ size_t cbBlock = cbEntry * cEntries
+ + RT_ALIGN_Z(sizeof(RTTRACEBUFINT), RTTRACEBUF_ALIGNMENT)
+ + RT_ALIGN_Z(sizeof(RTTRACEBUFVOLATILE), RTTRACEBUF_ALIGNMENT);
+ void *pvBlock = RTMemAlloc(cbBlock);
+ if (!((uintptr_t)pvBlock & (RTTRACEBUF_ALIGNMENT - 1)))
+ {
+ RTMemFree(pvBlock);
+ cbBlock += RTTRACEBUF_ALIGNMENT - 1;
+ pvBlock = RTMemAlloc(cbBlock);
+ }
+ int rc;
+ if (pvBlock)
+ {
+ rc = RTTraceBufCarve(phTraceBuf, cEntries, cbEntry, fFlags, pvBlock, &cbBlock);
+ if (RT_FAILURE(rc))
+ RTMemFree(pvBlock);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ return rc;
+}
+
+
+RTDECL(int) RTTraceBufCarve(PRTTRACEBUF phTraceBuf, uint32_t cEntries, uint32_t cbEntry, uint32_t fFlags,
+ void *pvBlock, size_t *pcbBlock)
+{
+ AssertPtrReturn(phTraceBuf, VERR_INVALID_POINTER);
+ AssertReturn(!(fFlags & ~RTTRACEBUF_FLAGS_MASK), VERR_INVALID_PARAMETER);
+ AssertMsgReturn(cbEntry <= RTTRACEBUF_MAX_ENTRIES, ("%#x\n", cbEntry), VERR_OUT_OF_RANGE);
+ AssertMsgReturn(cEntries <= RTTRACEBUF_MAX_ENTRY_SIZE, ("%#x\n", cEntries), VERR_OUT_OF_RANGE);
+ AssertPtrReturn(pcbBlock, VERR_INVALID_POINTER);
+ size_t const cbBlock = *pcbBlock;
+ AssertReturn(RT_VALID_PTR(pvBlock) || !cbBlock, VERR_INVALID_POINTER);
+
+ /*
+ * Apply defaults, align sizes and check against available buffer space.
+ * This code can be made a bit more clever, if someone feels like it.
+ */
+ size_t const cbHdr = RT_ALIGN_Z(sizeof(RTTRACEBUFINT), RTTRACEBUF_ALIGNMENT)
+ + RT_ALIGN_Z(sizeof(RTTRACEBUFVOLATILE), RTTRACEBUF_ALIGNMENT);
+ size_t const cbEntryBuf = cbBlock > cbHdr ? cbBlock - cbHdr : 0;
+ if (cbEntry)
+ cbEntry = RT_ALIGN_32(cbEntry, RTTRACEBUF_ALIGNMENT);
+ else
+ {
+ if (!cbEntryBuf)
+ {
+ cbEntry = RTTRACEBUF_DEF_ENTRY_SIZE;
+ cEntries = RTTRACEBUF_DEF_ENTRIES;
+ }
+ else if (cEntries)
+ {
+ size_t cbEntryZ = cbBlock / cEntries;
+ cbEntryZ &= ~(RTTRACEBUF_ALIGNMENT - 1);
+ if (cbEntryZ > RTTRACEBUF_MAX_ENTRIES)
+ cbEntryZ = RTTRACEBUF_MAX_ENTRIES;
+ cbEntry = (uint32_t)cbEntryZ;
+ }
+ else if (cbBlock >= RT_ALIGN_32(512, RTTRACEBUF_ALIGNMENT) * 256)
+ cbEntry = RT_ALIGN_32(512, RTTRACEBUF_ALIGNMENT);
+ else if (cbBlock >= RT_ALIGN_32(256, RTTRACEBUF_ALIGNMENT) * 64)
+ cbEntry = RT_ALIGN_32(256, RTTRACEBUF_ALIGNMENT);
+ else if (cbBlock >= RT_ALIGN_32(128, RTTRACEBUF_ALIGNMENT) * 32)
+ cbEntry = RT_ALIGN_32(128, RTTRACEBUF_ALIGNMENT);
+ else
+ cbEntry = sizeof(RTTRACEBUFENTRY);
+ }
+ Assert(RT_ALIGN_32(cbEntry, RTTRACEBUF_ALIGNMENT) == cbEntry);
+
+ if (!cEntries)
+ {
+ size_t cEntriesZ = cbEntryBuf / cbEntry;
+ if (cEntriesZ > RTTRACEBUF_MAX_ENTRIES)
+ cEntriesZ = RTTRACEBUF_MAX_ENTRIES;
+ cEntries = (uint32_t)cEntriesZ;
+ }
+ if (cEntries < RTTRACEBUF_MIN_ENTRIES)
+ cEntries = RTTRACEBUF_MIN_ENTRIES;
+
+ uint32_t offVolatile = RTTRACEBUF_ALIGNMENT - ((uintptr_t)pvBlock & (RTTRACEBUF_ALIGNMENT - 1));
+ if (offVolatile < sizeof(RTTRACEBUFINT))
+ offVolatile += RTTRACEBUF_ALIGNMENT;
+ size_t cbReqBlock = offVolatile
+ + RT_ALIGN_Z(sizeof(RTTRACEBUFVOLATILE), RTTRACEBUF_ALIGNMENT)
+ + cbEntry * cEntries;
+ if (*pcbBlock < cbReqBlock)
+ {
+ *pcbBlock = cbReqBlock;
+ return VERR_BUFFER_OVERFLOW;
+ }
+
+ /*
+ * Do the carving.
+ */
+ memset(pvBlock, 0, cbBlock);
+
+ RTTRACEBUFINT *pThis = (RTTRACEBUFINT *)pvBlock;
+ pThis->u32Magic = RTTRACEBUF_MAGIC;
+ pThis->cbEntry = cbEntry;
+ pThis->cEntries = cEntries;
+ pThis->fFlags = fFlags;
+ pThis->offVolatile = offVolatile;
+ pThis->offEntries = offVolatile + RT_ALIGN_Z(sizeof(RTTRACEBUFVOLATILE), RTTRACEBUF_ALIGNMENT);
+
+ PRTTRACEBUFVOLATILE pVolatile = (PRTTRACEBUFVOLATILE)((uint8_t *)pThis + offVolatile);
+ pVolatile->cRefs = 1;
+ pVolatile->iEntry = 0;
+
+ *pcbBlock = cbBlock - cbReqBlock;
+ *phTraceBuf = pThis;
+ return VINF_SUCCESS;
+}
+
+#endif /* !IN_RC */
+
+
+/**
+ * Destructor.
+ *
+ * @param pThis The trace buffer to destroy.
+ */
+static void rtTraceBufDestroy(RTTRACEBUFINT *pThis)
+{
+ AssertReturnVoid(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTTRACEBUF_MAGIC_DEAD, RTTRACEBUF_MAGIC));
+ if (pThis->fFlags & RTTRACEBUF_FLAGS_FREE_ME)
+ {
+#ifdef IN_RC
+ AssertReleaseFailed();
+#else
+ RTMemFree(pThis);
+#endif
+ }
+}
+
+
+RTDECL(uint32_t)RTTraceBufRetain(RTTRACEBUF hTraceBuf)
+{
+ PCRTTRACEBUFINT pThis = hTraceBuf;
+ RTTRACEBUF_VALID_RETURN_RC(pThis, UINT32_MAX);
+ return ASMAtomicIncU32(&RTTRACEBUF_TO_VOLATILE(pThis)->cRefs);
+}
+
+
+RTDECL(uint32_t) RTTraceBufRelease(RTTRACEBUF hTraceBuf)
+{
+ if (hTraceBuf == NIL_RTTRACEBUF)
+ return 0;
+
+ PCRTTRACEBUFINT pThis = hTraceBuf;
+ RTTRACEBUF_VALID_RETURN_RC(pThis, UINT32_MAX);
+
+ uint32_t cRefs = ASMAtomicDecU32(&RTTRACEBUF_TO_VOLATILE(pThis)->cRefs);
+ if (!cRefs)
+ rtTraceBufDestroy((RTTRACEBUFINT *)pThis);
+ return cRefs;
+}
+
+
+RTDECL(int) RTTraceBufAddMsg(RTTRACEBUF hTraceBuf, const char *pszMsg)
+{
+ RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
+ RTStrCopy(pszBuf, cchBuf, pszMsg);
+ RTTRACEBUF_ADD_EPILOGUE();
+}
+
+
+RTDECL(int) RTTraceBufAddMsgEx( RTTRACEBUF hTraceBuf, const char *pszMsg, size_t cbMaxMsg)
+{
+ RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
+ RTStrCopyEx(pszBuf, cchBuf, pszMsg, cbMaxMsg);
+ RTTRACEBUF_ADD_EPILOGUE();
+}
+
+
+RTDECL(int) RTTraceBufAddMsgF(RTTRACEBUF hTraceBuf, const char *pszMsgFmt, ...)
+{
+ int rc;
+ va_list va;
+ va_start(va, pszMsgFmt);
+ rc = RTTraceBufAddMsgV(hTraceBuf, pszMsgFmt, va);
+ va_end(va);
+ return rc;
+}
+
+
+RTDECL(int) RTTraceBufAddMsgV(RTTRACEBUF hTraceBuf, const char *pszMsgFmt, va_list va)
+{
+ RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
+ RTStrPrintfV(pszBuf, cchBuf, pszMsgFmt, va);
+ RTTRACEBUF_ADD_EPILOGUE();
+}
+
+
+RTDECL(int) RTTraceBufAddPos(RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL)
+{
+ RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
+ RTTRACEBUF_ADD_STORE_SRC_POS();
+ RTTRACEBUF_ADD_EPILOGUE();
+}
+
+
+RTDECL(int) RTTraceBufAddPosMsg(RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsg)
+{
+ RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
+ RTTRACEBUF_ADD_STORE_SRC_POS();
+ RTStrCopy(pszBuf, cchBuf, pszMsg);
+ RTTRACEBUF_ADD_EPILOGUE();
+}
+
+
+RTDECL(int) RTTraceBufAddPosMsgEx(RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsg, size_t cbMaxMsg)
+{
+ RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
+ RTTRACEBUF_ADD_STORE_SRC_POS();
+ RTStrCopyEx(pszBuf, cchBuf, pszMsg, cbMaxMsg);
+ RTTRACEBUF_ADD_EPILOGUE();
+}
+
+
+RTDECL(int) RTTraceBufAddPosMsgF(RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsgFmt, ...)
+{
+ int rc;
+ va_list va;
+ va_start(va, pszMsgFmt);
+ rc = RTTraceBufAddPosMsgV(hTraceBuf, RT_SRC_POS_ARGS, pszMsgFmt, va);
+ va_end(va);
+ return rc;
+}
+
+
+RTDECL(int) RTTraceBufAddPosMsgV(RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsgFmt, va_list va)
+{
+ RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
+ RTTRACEBUF_ADD_STORE_SRC_POS();
+ RTStrPrintfV(pszBuf, cchBuf, pszMsgFmt, va);
+ RTTRACEBUF_ADD_EPILOGUE();
+}
+
+
+RTDECL(int) RTTraceBufEnumEntries(RTTRACEBUF hTraceBuf, PFNRTTRACEBUFCALLBACK pfnCallback, void *pvUser)
+{
+ int rc = VINF_SUCCESS;
+ uint32_t iBase;
+ uint32_t cLeft;
+ PCRTTRACEBUFINT pThis;
+ RTTRACEBUF_RESOLVE_VALIDATE_RETAIN_RETURN(hTraceBuf, pThis);
+
+ iBase = ASMAtomicReadU32(&RTTRACEBUF_TO_VOLATILE(pThis)->iEntry);
+ cLeft = pThis->cEntries;
+ while (cLeft--)
+ {
+ PRTTRACEBUFENTRY pEntry;
+
+ iBase %= pThis->cEntries;
+ pEntry = RTTRACEBUF_TO_ENTRY(pThis, iBase);
+ if (pEntry->NanoTS)
+ {
+ rc = pfnCallback((RTTRACEBUF)pThis, cLeft, pEntry->NanoTS, pEntry->idCpu, pEntry->szMsg, pvUser);
+ if (rc != VINF_SUCCESS)
+ break;
+ }
+
+ /* next */
+ iBase += 1;
+ }
+
+ RTTRACEBUF_DROP_REFERENCE(pThis);
+ return rc;
+}
+
+
+RTDECL(uint32_t) RTTraceBufGetEntrySize(RTTRACEBUF hTraceBuf)
+{
+ PCRTTRACEBUFINT pThis = hTraceBuf;
+ RTTRACEBUF_VALID_RETURN_RC(pThis, 0);
+ return pThis->cbEntry;
+}
+
+
+RTDECL(uint32_t) RTTraceBufGetEntryCount(RTTRACEBUF hTraceBuf)
+{
+ PCRTTRACEBUFINT pThis = hTraceBuf;
+ RTTRACEBUF_VALID_RETURN_RC(pThis, 0);
+ return pThis->cEntries;
+}
+
+
+RTDECL(bool) RTTraceBufDisable(RTTRACEBUF hTraceBuf)
+{
+ PCRTTRACEBUFINT pThis = hTraceBuf;
+ RTTRACEBUF_VALID_RETURN_RC(pThis, false);
+ return !ASMAtomicBitTestAndSet((void volatile *)&pThis->fFlags, RTTRACEBUF_FLAGS_DISABLED_BIT);
+}
+
+
+RTDECL(bool) RTTraceBufEnable(RTTRACEBUF hTraceBuf)
+{
+ PCRTTRACEBUFINT pThis = hTraceBuf;
+ RTTRACEBUF_VALID_RETURN_RC(pThis, false);
+ return !ASMAtomicBitTestAndClear((void volatile *)&pThis->fFlags, RTTRACEBUF_FLAGS_DISABLED_BIT);
+}
+
+
+/*
+ *
+ * Move the following to a separate file, consider using the enumerator.
+ *
+ */
+
+RTDECL(int) RTTraceBufDumpToLog(RTTRACEBUF hTraceBuf)
+{
+ uint32_t iBase;
+ uint32_t cLeft;
+ PCRTTRACEBUFINT pThis;
+ RTTRACEBUF_RESOLVE_VALIDATE_RETAIN_RETURN(hTraceBuf, pThis);
+
+ iBase = ASMAtomicReadU32(&RTTRACEBUF_TO_VOLATILE(pThis)->iEntry);
+ cLeft = pThis->cEntries;
+ while (cLeft--)
+ {
+ PRTTRACEBUFENTRY pEntry;
+
+ iBase %= pThis->cEntries;
+ pEntry = RTTRACEBUF_TO_ENTRY(pThis, iBase);
+ if (pEntry->NanoTS)
+ RTLogPrintf("%04u/%'llu/%02x: %s\n", cLeft, pEntry->NanoTS, pEntry->idCpu, pEntry->szMsg);
+
+ /* next */
+ iBase += 1;
+ }
+
+ RTTRACEBUF_DROP_REFERENCE(pThis);
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(int) RTTraceBufDumpToAssert(RTTRACEBUF hTraceBuf)
+{
+ uint32_t iBase;
+ uint32_t cLeft;
+ PCRTTRACEBUFINT pThis;
+ RTTRACEBUF_RESOLVE_VALIDATE_RETAIN_RETURN(hTraceBuf, pThis);
+
+ iBase = ASMAtomicReadU32(&RTTRACEBUF_TO_VOLATILE(pThis)->iEntry);
+ cLeft = pThis->cEntries;
+ while (cLeft--)
+ {
+ PRTTRACEBUFENTRY pEntry;
+
+ iBase %= pThis->cEntries;
+ pEntry = RTTRACEBUF_TO_ENTRY(pThis, iBase);
+ if (pEntry->NanoTS)
+ RTAssertMsg2AddWeak("%u/%'llu/%02x: %s\n", cLeft, pEntry->NanoTS, pEntry->idCpu, pEntry->szMsg);
+
+ /* next */
+ iBase += 1;
+ }
+
+ RTTRACEBUF_DROP_REFERENCE(pThis);
+ return VINF_SUCCESS;
+}
+
+
+
diff --git a/src/VBox/Runtime/common/log/tracedefault.cpp b/src/VBox/Runtime/common/log/tracedefault.cpp
new file mode 100644
index 000000000..65c7f9398
--- /dev/null
+++ b/src/VBox/Runtime/common/log/tracedefault.cpp
@@ -0,0 +1,57 @@
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "internal/iprt.h"
+#include <iprt/trace.h>
+
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/thread.h>
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/** The default trace buffer handle. */
+static RTTRACEBUF g_hDefaultTraceBuf = NIL_RTTRACEBUF;
+
+
+
+RTDECL(int) RTTraceSetDefaultBuf(RTTRACEBUF hTraceBuf)
+{
+ /* Retain the new buffer. */
+ if (hTraceBuf != NIL_RTTRACEBUF)
+ {
+ uint32_t cRefs = RTTraceBufRetain(hTraceBuf);
+ if (cRefs >= _1M)
+ return VERR_INVALID_HANDLE;
+ }
+
+ RTTRACEBUF hOldTraceBuf;
+#ifdef IN_RC
+ hOldTraceBuf = (RTTRACEBUF)ASMAtomicXchgPtr((void **)&g_hDefaultTraceBuf, hTraceBuf);
+#else
+ ASMAtomicXchgHandle(&g_hDefaultTraceBuf, hTraceBuf, &hOldTraceBuf);
+#endif
+
+ if ( hOldTraceBuf != NIL_RTTRACEBUF
+ && hOldTraceBuf != hTraceBuf)
+ {
+ /* Race prevention kludge. */
+#ifndef IN_RC
+ RTThreadSleep(33);
+#endif
+ RTTraceBufRelease(hOldTraceBuf);
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(RTTRACEBUF) RTTraceGetDefaultBuf(void)
+{
+ return g_hDefaultTraceBuf;
+}
+
+
diff --git a/src/VBox/Runtime/common/math/ceill.asm b/src/VBox/Runtime/common/math/ceill.asm
index 502181cdd..4cd635bad 100644
--- a/src/VBox/Runtime/common/math/ceill.asm
+++ b/src/VBox/Runtime/common/math/ceill.asm
@@ -1,4 +1,4 @@
-; $Id: ceill.asm $
+; $Id: ceill.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT ceill - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/cosl.asm b/src/VBox/Runtime/common/math/cosl.asm
index c37c3c6af..6e46eb70a 100644
--- a/src/VBox/Runtime/common/math/cosl.asm
+++ b/src/VBox/Runtime/common/math/cosl.asm
@@ -1,4 +1,4 @@
-; $Id: cosl.asm $
+; $Id: cosl.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT cosl - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/fabs.asm b/src/VBox/Runtime/common/math/fabs.asm
index 18ca01151..f2e114436 100644
--- a/src/VBox/Runtime/common/math/fabs.asm
+++ b/src/VBox/Runtime/common/math/fabs.asm
@@ -1,4 +1,4 @@
-; $Id: fabs.asm $
+; $Id: fabs.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT fabs - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/fabsf.asm b/src/VBox/Runtime/common/math/fabsf.asm
index c58d2fc4d..550ebc9c6 100644
--- a/src/VBox/Runtime/common/math/fabsf.asm
+++ b/src/VBox/Runtime/common/math/fabsf.asm
@@ -1,4 +1,4 @@
-; $Id: fabsf.asm $
+; $Id: fabsf.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT fabsf - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/fabsl.asm b/src/VBox/Runtime/common/math/fabsl.asm
index 1302b00dd..e6cbd75a7 100644
--- a/src/VBox/Runtime/common/math/fabsl.asm
+++ b/src/VBox/Runtime/common/math/fabsl.asm
@@ -1,4 +1,4 @@
-; $Id: fabsl.asm $
+; $Id: fabsl.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT fabsl - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/floor.asm b/src/VBox/Runtime/common/math/floor.asm
index 7d98b4b4f..49b8accbe 100644
--- a/src/VBox/Runtime/common/math/floor.asm
+++ b/src/VBox/Runtime/common/math/floor.asm
@@ -1,4 +1,4 @@
-; $Id: floor.asm $
+; $Id: floor.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT floor - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/floorf.asm b/src/VBox/Runtime/common/math/floorf.asm
index b54919190..9df9ae551 100644
--- a/src/VBox/Runtime/common/math/floorf.asm
+++ b/src/VBox/Runtime/common/math/floorf.asm
@@ -1,4 +1,4 @@
-; $Id: floorf.asm $
+; $Id: floorf.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT floorf - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/floorl.asm b/src/VBox/Runtime/common/math/floorl.asm
index c27ada71f..8ba748507 100644
--- a/src/VBox/Runtime/common/math/floorl.asm
+++ b/src/VBox/Runtime/common/math/floorl.asm
@@ -1,4 +1,4 @@
-; $Id: floorl.asm $
+; $Id: floorl.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT floorl - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/ldexpl.asm b/src/VBox/Runtime/common/math/ldexpl.asm
index f53a4e439..230f61fde 100644
--- a/src/VBox/Runtime/common/math/ldexpl.asm
+++ b/src/VBox/Runtime/common/math/ldexpl.asm
@@ -1,4 +1,4 @@
-; $Id: ldexpl.asm $
+; $Id: ldexpl.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT ldexpl - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/llrint.asm b/src/VBox/Runtime/common/math/llrint.asm
index c870b9136..edd46105d 100644
--- a/src/VBox/Runtime/common/math/llrint.asm
+++ b/src/VBox/Runtime/common/math/llrint.asm
@@ -1,4 +1,4 @@
-; $Id: llrint.asm $
+; $Id: llrint.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT llrint - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/llrintf.asm b/src/VBox/Runtime/common/math/llrintf.asm
index d0c23db7b..1662c474b 100644
--- a/src/VBox/Runtime/common/math/llrintf.asm
+++ b/src/VBox/Runtime/common/math/llrintf.asm
@@ -1,4 +1,4 @@
-; $Id: llrintf.asm $
+; $Id: llrintf.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT llrintf - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/llrintl.asm b/src/VBox/Runtime/common/math/llrintl.asm
index a0ce49125..f35a4d4e9 100644
--- a/src/VBox/Runtime/common/math/llrintl.asm
+++ b/src/VBox/Runtime/common/math/llrintl.asm
@@ -1,4 +1,4 @@
-; $Id: llrintl.asm $
+; $Id: llrintl.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT llrintl - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/logl.asm b/src/VBox/Runtime/common/math/logl.asm
index 83e7de969..11c19785e 100644
--- a/src/VBox/Runtime/common/math/logl.asm
+++ b/src/VBox/Runtime/common/math/logl.asm
@@ -1,4 +1,4 @@
-; $Id: logl.asm $
+; $Id: logl.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT logl - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/lrint.asm b/src/VBox/Runtime/common/math/lrint.asm
index 270a79f82..7e0f0e0f9 100644
--- a/src/VBox/Runtime/common/math/lrint.asm
+++ b/src/VBox/Runtime/common/math/lrint.asm
@@ -1,4 +1,4 @@
-; $Id: lrint.asm $
+; $Id: lrint.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT lrint - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/lrintf.asm b/src/VBox/Runtime/common/math/lrintf.asm
index 997294971..80a475587 100644
--- a/src/VBox/Runtime/common/math/lrintf.asm
+++ b/src/VBox/Runtime/common/math/lrintf.asm
@@ -1,4 +1,4 @@
-; $Id: lrintf.asm $
+; $Id: lrintf.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT lrintf - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/lrintl.asm b/src/VBox/Runtime/common/math/lrintl.asm
index f336af6ac..777a4a5d8 100644
--- a/src/VBox/Runtime/common/math/lrintl.asm
+++ b/src/VBox/Runtime/common/math/lrintl.asm
@@ -1,4 +1,4 @@
-; $Id: lrintl.asm $
+; $Id: lrintl.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT lrintl - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/remainder.asm b/src/VBox/Runtime/common/math/remainder.asm
index 117aa502e..1ad6af1e1 100644
--- a/src/VBox/Runtime/common/math/remainder.asm
+++ b/src/VBox/Runtime/common/math/remainder.asm
@@ -1,4 +1,4 @@
-; $Id: remainder.asm $
+; $Id: remainder.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT remainder - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/remainderf.asm b/src/VBox/Runtime/common/math/remainderf.asm
index c9b079b70..09e731259 100644
--- a/src/VBox/Runtime/common/math/remainderf.asm
+++ b/src/VBox/Runtime/common/math/remainderf.asm
@@ -1,4 +1,4 @@
-; $Id: remainderf.asm $
+; $Id: remainderf.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT remainderf - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/remainderl.asm b/src/VBox/Runtime/common/math/remainderl.asm
index 922f93a74..3f58e9086 100644
--- a/src/VBox/Runtime/common/math/remainderl.asm
+++ b/src/VBox/Runtime/common/math/remainderl.asm
@@ -1,4 +1,4 @@
-; $Id: remainderl.asm $
+; $Id: remainderl.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT remainderl - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/sinl.asm b/src/VBox/Runtime/common/math/sinl.asm
index 57f5ab8b1..689d33c72 100644
--- a/src/VBox/Runtime/common/math/sinl.asm
+++ b/src/VBox/Runtime/common/math/sinl.asm
@@ -1,4 +1,4 @@
-; $Id: sinl.asm $
+; $Id: sinl.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT sinl - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/tanl.asm b/src/VBox/Runtime/common/math/tanl.asm
index 85e61d04f..fea96200b 100644
--- a/src/VBox/Runtime/common/math/tanl.asm
+++ b/src/VBox/Runtime/common/math/tanl.asm
@@ -1,4 +1,4 @@
-; $Id: tanl.asm $
+; $Id: tanl.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT tanl - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/trunc.asm b/src/VBox/Runtime/common/math/trunc.asm
index 9ea36820f..c079fcc50 100644
--- a/src/VBox/Runtime/common/math/trunc.asm
+++ b/src/VBox/Runtime/common/math/trunc.asm
@@ -1,4 +1,4 @@
-; $Id: trunc.asm $
+; $Id: trunc.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT trunc - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/truncf.asm b/src/VBox/Runtime/common/math/truncf.asm
index 9fb8166c7..e2a57264a 100644
--- a/src/VBox/Runtime/common/math/truncf.asm
+++ b/src/VBox/Runtime/common/math/truncf.asm
@@ -1,4 +1,4 @@
-; $Id: truncf.asm $
+; $Id: truncf.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT truncf - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/math/truncl.asm b/src/VBox/Runtime/common/math/truncl.asm
index 45576833e..ff0fb816a 100644
--- a/src/VBox/Runtime/common/math/truncl.asm
+++ b/src/VBox/Runtime/common/math/truncl.asm
@@ -1,4 +1,4 @@
-; $Id: truncl.asm $
+; $Id: truncl.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT truncl - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/misc/RTAssertMsg1Weak.cpp b/src/VBox/Runtime/common/misc/RTAssertMsg1Weak.cpp
index ef0f35ee7..0621c9620 100644
--- a/src/VBox/Runtime/common/misc/RTAssertMsg1Weak.cpp
+++ b/src/VBox/Runtime/common/misc/RTAssertMsg1Weak.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTAssertMsg1Weak.cpp $ */
+/* $Id: RTAssertMsg1Weak.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTAssertMsg1Weak.
*/
diff --git a/src/VBox/Runtime/common/misc/RTAssertMsg2.cpp b/src/VBox/Runtime/common/misc/RTAssertMsg2.cpp
index 401baac80..d6ee76210 100644
--- a/src/VBox/Runtime/common/misc/RTAssertMsg2.cpp
+++ b/src/VBox/Runtime/common/misc/RTAssertMsg2.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTAssertMsg2.cpp $ */
+/* $Id: RTAssertMsg2.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTAssertMsg2.
*/
diff --git a/src/VBox/Runtime/common/misc/RTAssertMsg2Add.cpp b/src/VBox/Runtime/common/misc/RTAssertMsg2Add.cpp
index e0f3fb23f..6112b1835 100644
--- a/src/VBox/Runtime/common/misc/RTAssertMsg2Add.cpp
+++ b/src/VBox/Runtime/common/misc/RTAssertMsg2Add.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTAssertMsg2Add.cpp $ */
+/* $Id: RTAssertMsg2Add.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTAssertMsg2Add.
*/
diff --git a/src/VBox/Runtime/common/misc/RTAssertMsg2AddWeak.cpp b/src/VBox/Runtime/common/misc/RTAssertMsg2AddWeak.cpp
index 297e60d99..bbf1d998c 100644
--- a/src/VBox/Runtime/common/misc/RTAssertMsg2AddWeak.cpp
+++ b/src/VBox/Runtime/common/misc/RTAssertMsg2AddWeak.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTAssertMsg2AddWeak.cpp $ */
+/* $Id: RTAssertMsg2AddWeak.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTAssertMsg2AddWeak.
*/
diff --git a/src/VBox/Runtime/common/misc/RTAssertMsg2AddWeakV.cpp b/src/VBox/Runtime/common/misc/RTAssertMsg2AddWeakV.cpp
index 99bc5e64c..d1361d99f 100644
--- a/src/VBox/Runtime/common/misc/RTAssertMsg2AddWeakV.cpp
+++ b/src/VBox/Runtime/common/misc/RTAssertMsg2AddWeakV.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTAssertMsg2AddWeakV.cpp $ */
+/* $Id: RTAssertMsg2AddWeakV.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTAssertMsg2AddWeakV.
*/
diff --git a/src/VBox/Runtime/common/misc/RTAssertMsg2Weak.cpp b/src/VBox/Runtime/common/misc/RTAssertMsg2Weak.cpp
index 2b5b9cf6b..f45c1eff9 100644
--- a/src/VBox/Runtime/common/misc/RTAssertMsg2Weak.cpp
+++ b/src/VBox/Runtime/common/misc/RTAssertMsg2Weak.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTAssertMsg2Weak.cpp $ */
+/* $Id: RTAssertMsg2Weak.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTAssertMsg2Weak.
*/
diff --git a/src/VBox/Runtime/common/misc/RTAssertMsg2WeakV.cpp b/src/VBox/Runtime/common/misc/RTAssertMsg2WeakV.cpp
index 2d9b5eff7..8cffc1212 100644
--- a/src/VBox/Runtime/common/misc/RTAssertMsg2WeakV.cpp
+++ b/src/VBox/Runtime/common/misc/RTAssertMsg2WeakV.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTAssertMsg2WeakV.cpp $ */
+/* $Id: RTAssertMsg2WeakV.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTAssertMsg2WeakV.
*/
diff --git a/src/VBox/Runtime/common/misc/RTFileOpenF.cpp b/src/VBox/Runtime/common/misc/RTFileOpenF.cpp
index 39e50e13c..008503f06 100644
--- a/src/VBox/Runtime/common/misc/RTFileOpenF.cpp
+++ b/src/VBox/Runtime/common/misc/RTFileOpenF.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTFileOpenF.cpp $ */
+/* $Id: RTFileOpenF.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - RTFileOpenF.
*/
@@ -32,7 +32,7 @@
#include "internal/iprt.h"
-RTR3DECL(int) RTFileOpenF(PRTFILE pFile, uint32_t fOpen, const char *pszFilenameFmt, ...)
+RTR3DECL(int) RTFileOpenF(PRTFILE pFile, uint64_t fOpen, const char *pszFilenameFmt, ...)
{
va_list va;
va_start(va, pszFilenameFmt);
diff --git a/src/VBox/Runtime/common/misc/RTFileOpenV.cpp b/src/VBox/Runtime/common/misc/RTFileOpenV.cpp
index fe9bb46a2..565c075cb 100644
--- a/src/VBox/Runtime/common/misc/RTFileOpenV.cpp
+++ b/src/VBox/Runtime/common/misc/RTFileOpenV.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTFileOpenV.cpp $ */
+/* $Id: RTFileOpenV.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - RTFileOpenV.
*/
@@ -36,7 +36,7 @@
#include <iprt/string.h>
-RTR3DECL(int) RTFileOpenV(PRTFILE pFile, uint32_t fOpen, const char *pszFilenameFmt, va_list va)
+RTR3DECL(int) RTFileOpenV(PRTFILE pFile, uint64_t fOpen, const char *pszFilenameFmt, va_list va)
{
char szFilename[RTPATH_MAX];
size_t cchFilename = RTStrPrintfV(szFilename, sizeof(szFilename), pszFilenameFmt, va);
diff --git a/src/VBox/Runtime/common/misc/RTMemWipeThoroughly.cpp b/src/VBox/Runtime/common/misc/RTMemWipeThoroughly.cpp
index c5656b46f..c80fea755 100644
--- a/src/VBox/Runtime/common/misc/RTMemWipeThoroughly.cpp
+++ b/src/VBox/Runtime/common/misc/RTMemWipeThoroughly.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMemWipeThoroughly.cpp $ */
+/* $Id: RTMemWipeThoroughly.cpp 30827 2010-07-14 12:49:36Z vboxsync $ */
/** @file
* IPRT - RTMemWipeThoroughly.
*/
diff --git a/src/VBox/Runtime/common/misc/assert.cpp b/src/VBox/Runtime/common/misc/assert.cpp
index fb4165029..ca7d1caf1 100644
--- a/src/VBox/Runtime/common/misc/assert.cpp
+++ b/src/VBox/Runtime/common/misc/assert.cpp
@@ -1,4 +1,4 @@
-/* $Id: assert.cpp $ */
+/* $Id: assert.cpp 37233 2011-05-27 13:31:57Z vboxsync $ */
/** @file
* IPRT - Assertions, common code.
*/
@@ -32,6 +32,7 @@
#include "internal/iprt.h"
#include <iprt/asm.h>
+#include <iprt/err.h>
#include <iprt/log.h>
#include <iprt/string.h>
#include <iprt/stdarg.h>
@@ -121,6 +122,9 @@ RTDECL(void) RTAssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFi
*/
if (!RTAssertAreQuiet())
{
+ RTERRVARS SavedErrVars;
+ RTErrVarsSave(&SavedErrVars);
+
#ifdef IN_RING0
# ifdef IN_GUEST_R0
RTLogBackdoorPrintf("\n!!Assertion Failed!!\n"
@@ -181,6 +185,8 @@ RTDECL(void) RTAssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFi
fflush(stderr);
# endif
#endif /* !IN_RING0 */
+
+ RTErrVarsRestore(&SavedErrVars);
}
}
RT_EXPORT_SYMBOL(RTAssertMsg1);
@@ -225,6 +231,9 @@ static void rtAssertMsg2Worker(bool fInitial, const char *pszFormat, va_list va)
*/
if (!RTAssertAreQuiet())
{
+ RTERRVARS SavedErrVars;
+ RTErrVarsSave(&SavedErrVars);
+
#ifdef IN_RING0
# ifdef IN_GUEST_R0
va_copy(vaCopy, va);
@@ -265,7 +274,7 @@ static void rtAssertMsg2Worker(bool fInitial, const char *pszFormat, va_list va)
# ifdef IN_RING3
/* print to stderr, helps user and gdb debugging. */
- char szMsg[1024];
+ char szMsg[sizeof(g_szRTAssertMsg2)];
va_copy(vaCopy, va);
RTStrPrintfV(szMsg, sizeof(szMsg), pszFormat, vaCopy);
va_end(vaCopy);
@@ -273,8 +282,9 @@ static void rtAssertMsg2Worker(bool fInitial, const char *pszFormat, va_list va)
fflush(stderr);
# endif
#endif /* !IN_RING0 */
- }
+ RTErrVarsRestore(&SavedErrVars);
+ }
}
diff --git a/src/VBox/Runtime/common/misc/buildconfig.cpp b/src/VBox/Runtime/common/misc/buildconfig.cpp
index 54e87b39b..03cedbe03 100644
--- a/src/VBox/Runtime/common/misc/buildconfig.cpp
+++ b/src/VBox/Runtime/common/misc/buildconfig.cpp
@@ -1,4 +1,4 @@
-/* $Id: buildconfig.cpp $ */
+/* $Id: buildconfig.cpp 33680 2010-11-02 11:08:08Z vboxsync $ */
/** @file
* IPRT - Build Configuration Information.
*/
diff --git a/src/VBox/Runtime/common/misc/cidr.cpp b/src/VBox/Runtime/common/misc/cidr.cpp
index d64d8e436..b05ae8a72 100644
--- a/src/VBox/Runtime/common/misc/cidr.cpp
+++ b/src/VBox/Runtime/common/misc/cidr.cpp
@@ -1,4 +1,4 @@
-/* $Id: cidr.cpp $ */
+/* $Id: cidr.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - IPv4 address parsing.
*/
diff --git a/src/VBox/Runtime/common/misc/circbuf.cpp b/src/VBox/Runtime/common/misc/circbuf.cpp
index da6c51f93..0a6f78b07 100644
--- a/src/VBox/Runtime/common/misc/circbuf.cpp
+++ b/src/VBox/Runtime/common/misc/circbuf.cpp
@@ -1,4 +1,4 @@
-/* $Id: circbuf.cpp $ */
+/* $Id: circbuf.cpp 37210 2011-05-25 09:55:16Z vboxsync $ */
/** @file
* IPRT - Lock Free Circular Buffer
*/
@@ -25,18 +25,36 @@
*/
-/******************************************************************************
- * Header Files *
- ******************************************************************************/
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
#include <iprt/circbuf.h>
#include <iprt/mem.h>
#include <iprt/assert.h>
#include <iprt/asm.h>
#include <iprt/err.h>
-/******************************************************************************
- * Public Functions *
- ******************************************************************************/
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/** @todo r=bird: this is missing docs and magic. uXPos should be offX.
+ * cbBufSize should be cbBuf. */
+typedef struct RTCIRCBUF
+{
+ /** The current read position in the buffer. */
+ size_t uReadPos;
+ /** The current write position in the buffer. */
+ size_t uWritePos;
+ /** How much space of the buffer is currently in use. */
+ volatile size_t cbBufUsed;
+ /** How big is the buffer. */
+ size_t cbBufSize;
+ /** The buffer itself. */
+ void *pvBuf;
+} RTCIRCBUF;
+
+
RTDECL(int) RTCircBufCreate(PRTCIRCBUF *ppBuf, size_t cbSize)
{
@@ -49,69 +67,59 @@ RTDECL(int) RTCircBufCreate(PRTCIRCBUF *ppBuf, size_t cbSize)
if (!pTmpBuf)
return VERR_NO_MEMORY;
- int rc = VINF_SUCCESS;
- do
+ pTmpBuf->pvBuf = RTMemAlloc(cbSize);
+ if (pTmpBuf->pvBuf)
{
- pTmpBuf->pvBuf = RTMemAlloc(cbSize);
- if (!pTmpBuf)
- {
- rc = VERR_NO_MEMORY;
- break;
- }
-
pTmpBuf->cbBufSize = cbSize;
*ppBuf = pTmpBuf;
- }while (0);
-
- if (RT_FAILURE(rc))
- RTMemFree(pTmpBuf);
+ return VINF_SUCCESS;
+ }
- return rc;
+ RTMemFree(pTmpBuf);
+ return VERR_NO_MEMORY;
}
+
RTDECL(void) RTCircBufDestroy(PRTCIRCBUF pBuf)
{
/* Validate input. */
- AssertPtrNull(pBuf);
-
- if (pBuf)
- {
- if (pBuf->pvBuf)
- RTMemFree(pBuf->pvBuf);
- RTMemFree(pBuf);
- }
+ if (!pBuf)
+ return;
+ AssertPtr(pBuf);
+ RTMemFree(pBuf->pvBuf);
+ RTMemFree(pBuf);
}
+
RTDECL(void) RTCircBufReset(PRTCIRCBUF pBuf)
{
/* Validate input. */
AssertPtr(pBuf);
- pBuf->uReadPos = 0;
+ pBuf->uReadPos = 0;
pBuf->uWritePos = 0;
pBuf->cbBufUsed = 0;
}
+
RTDECL(size_t) RTCircBufFree(PRTCIRCBUF pBuf)
{
/* Validate input. */
AssertPtrReturn(pBuf, 0);
- size_t cbSize = 0;
- ASMAtomicReadSize(&pBuf->cbBufUsed, &cbSize);
- return pBuf->cbBufSize - cbSize;
+ return pBuf->cbBufSize - ASMAtomicReadZ(&pBuf->cbBufUsed);
}
+
RTDECL(size_t) RTCircBufUsed(PRTCIRCBUF pBuf)
{
/* Validate input. */
AssertPtrReturn(pBuf, 0);
- size_t cbSize = 0;
- ASMAtomicReadSize(&pBuf->cbBufUsed, &cbSize);
- return cbSize;
+ return ASMAtomicReadZ(&pBuf->cbBufUsed);
}
+
RTDECL(size_t) RTCircBufSize(PRTCIRCBUF pBuf)
{
/* Validate input. */
@@ -120,6 +128,7 @@ RTDECL(size_t) RTCircBufSize(PRTCIRCBUF pBuf)
return pBuf->cbBufSize;
}
+
RTDECL(void) RTCircBufAcquireReadBlock(PRTCIRCBUF pBuf, size_t cbReqSize, void **ppvStart, size_t *pcbSize)
{
/* Validate input. */
@@ -128,29 +137,27 @@ RTDECL(void) RTCircBufAcquireReadBlock(PRTCIRCBUF pBuf, size_t cbReqSize, void *
AssertPtr(ppvStart);
AssertPtr(pcbSize);
- size_t uUsed = 0;
- size_t uSize = 0;
-
*ppvStart = 0;
*pcbSize = 0;
/* How much is in use? */
- ASMAtomicReadSize(&pBuf->cbBufUsed, &uUsed);
- if (uUsed > 0)
+ size_t cbUsed = ASMAtomicReadZ(&pBuf->cbBufUsed);
+ if (cbUsed > 0)
{
/* Get the size out of the requested size, the read block till the end
* of the buffer & the currently used size. */
- uSize = RT_MIN(cbReqSize, RT_MIN(pBuf->cbBufSize - pBuf->uReadPos, uUsed));
- if (uSize > 0)
+ size_t cbSize = RT_MIN(cbReqSize, RT_MIN(pBuf->cbBufSize - pBuf->uReadPos, cbUsed));
+ if (cbSize > 0)
{
/* Return the pointer address which point to the current read
* position. */
- *ppvStart = (char*)pBuf->pvBuf + pBuf->uReadPos;
- *pcbSize = uSize;
+ *ppvStart = (char *)pBuf->pvBuf + pBuf->uReadPos;
+ *pcbSize = cbSize;
}
}
}
+
RTDECL(void) RTCircBufReleaseReadBlock(PRTCIRCBUF pBuf, size_t cbSize)
{
/* Validate input. */
@@ -159,10 +166,10 @@ RTDECL(void) RTCircBufReleaseReadBlock(PRTCIRCBUF pBuf, size_t cbSize)
/* Split at the end of the buffer. */
pBuf->uReadPos = (pBuf->uReadPos + cbSize) % pBuf->cbBufSize;
- size_t cbOld = 0;
- ASMAtomicSubSize(&pBuf->cbBufUsed, cbSize, &cbOld);
+ ASMAtomicSubZ(&pBuf->cbBufUsed, cbSize);
}
+
RTDECL(void) RTCircBufAcquireWriteBlock(PRTCIRCBUF pBuf, size_t cbReqSize, void **ppvStart, size_t *pcbSize)
{
/* Validate input. */
@@ -171,31 +178,27 @@ RTDECL(void) RTCircBufAcquireWriteBlock(PRTCIRCBUF pBuf, size_t cbReqSize, void
AssertPtr(ppvStart);
AssertPtr(pcbSize);
- size_t uFree;
- size_t uSize;
-
*ppvStart = 0;
*pcbSize = 0;
/* How much is free? */
- size_t cbSize = 0;
- ASMAtomicReadSize(&pBuf->cbBufUsed, &cbSize);
- uFree = pBuf->cbBufSize - cbSize;
- if (uFree > 0)
+ size_t cbFree = pBuf->cbBufSize - ASMAtomicReadZ(&pBuf->cbBufUsed);
+ if (cbFree > 0)
{
/* Get the size out of the requested size, the write block till the end
* of the buffer & the currently free size. */
- uSize = RT_MIN(cbReqSize, RT_MIN(pBuf->cbBufSize - pBuf->uWritePos, uFree));
- if (uSize > 0)
+ size_t cbSize = RT_MIN(cbReqSize, RT_MIN(pBuf->cbBufSize - pBuf->uWritePos, cbFree));
+ if (cbSize > 0)
{
/* Return the pointer address which point to the current write
* position. */
*ppvStart = (char*)pBuf->pvBuf + pBuf->uWritePos;
- *pcbSize = uSize;
+ *pcbSize = cbSize;
}
}
}
+
RTDECL(void) RTCircBufReleaseWriteBlock(PRTCIRCBUF pBuf, size_t cbSize)
{
/* Validate input. */
@@ -204,7 +207,7 @@ RTDECL(void) RTCircBufReleaseWriteBlock(PRTCIRCBUF pBuf, size_t cbSize)
/* Split at the end of the buffer. */
pBuf->uWritePos = (pBuf->uWritePos + cbSize) % pBuf->cbBufSize;
- size_t cbOld = 0;
- ASMAtomicAddSize(&pBuf->cbBufUsed, cbSize, &cbOld);
+ size_t cbOldIgnored = 0;
+ ASMAtomicAddZ(&pBuf->cbBufUsed, cbSize);
}
diff --git a/src/VBox/Runtime/common/misc/getopt.cpp b/src/VBox/Runtime/common/misc/getopt.cpp
index 7198a94b5..9c186d5d4 100644
--- a/src/VBox/Runtime/common/misc/getopt.cpp
+++ b/src/VBox/Runtime/common/misc/getopt.cpp
@@ -1,10 +1,10 @@
-/* $Id: getopt.cpp $ */
+/* $Id: getopt.cpp 37665 2011-06-28 12:32:13Z vboxsync $ */
/** @file
* IPRT - Command Line Parsing
*/
/*
- * Copyright (C) 2007-2010 Oracle Corporation
+ * Copyright (C) 2007-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;
@@ -216,7 +216,9 @@ static PCRTGETOPTDEF rtGetOptSearchLong(const char *pszOption, PCRTGETOPTDEF paO
* there is no index.
*/
size_t cchLong = strlen(pOpt->pszLong);
- if (!strncmp(pszOption, pOpt->pszLong, cchLong))
+ if ( !strncmp(pszOption, pOpt->pszLong, cchLong)
+ || ( pOpt->fFlags & RTGETOPT_FLAG_ICASE
+ && !RTStrNICmp(pszOption, pOpt->pszLong, cchLong)))
{
if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
while (RT_C_IS_DIGIT(pszOption[cchLong]))
@@ -234,7 +236,9 @@ static PCRTGETOPTDEF rtGetOptSearchLong(const char *pszOption, PCRTGETOPTDEF paO
* As above, we also match where there is no index.
*/
size_t cchLong = strlen(pOpt->pszLong);
- if (!strncmp(pszOption, pOpt->pszLong, cchLong))
+ if ( !strncmp(pszOption, pOpt->pszLong, cchLong)
+ || ( pOpt->fFlags & RTGETOPT_FLAG_ICASE
+ && !RTStrNICmp(pszOption, pOpt->pszLong, cchLong)))
{
while (RT_C_IS_DIGIT(pszOption[cchLong]))
cchLong++;
@@ -242,7 +246,9 @@ static PCRTGETOPTDEF rtGetOptSearchLong(const char *pszOption, PCRTGETOPTDEF paO
return pOpt;
}
}
- else if (!strcmp(pszOption, pOpt->pszLong))
+ else if ( !strcmp(pszOption, pOpt->pszLong)
+ || ( pOpt->fFlags & RTGETOPT_FLAG_ICASE
+ && !RTStrICmp(pszOption, pOpt->pszLong)))
return pOpt;
}
pOpt++;
@@ -250,7 +256,9 @@ static PCRTGETOPTDEF rtGetOptSearchLong(const char *pszOption, PCRTGETOPTDEF paO
if (!(fFlags & RTGETOPTINIT_FLAGS_NO_STD_OPTS))
for (uint32_t i = 0; i < RT_ELEMENTS(g_aStdOptions); i++)
- if (!strcmp(pszOption, g_aStdOptions[i].pszLong))
+ if ( !strcmp(pszOption, g_aStdOptions[i].pszLong)
+ || ( pOpt->fFlags & RTGETOPT_FLAG_ICASE
+ && !RTStrICmp(pszOption, g_aStdOptions[i].pszLong)))
return &g_aStdOptions[i];
return NULL;
diff --git a/src/VBox/Runtime/common/misc/getoptargv.cpp b/src/VBox/Runtime/common/misc/getoptargv.cpp
index 10b1d758b..1ca9ccdb6 100644
--- a/src/VBox/Runtime/common/misc/getoptargv.cpp
+++ b/src/VBox/Runtime/common/misc/getoptargv.cpp
@@ -1,4 +1,4 @@
-/* $Id: getoptargv.cpp $ */
+/* $Id: getoptargv.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Command Line Parsing, Argument Vector.
*/
diff --git a/src/VBox/Runtime/common/misc/handle.cpp b/src/VBox/Runtime/common/misc/handle.cpp
index b4f81e21b..3d71248ae 100644
--- a/src/VBox/Runtime/common/misc/handle.cpp
+++ b/src/VBox/Runtime/common/misc/handle.cpp
@@ -1,4 +1,4 @@
-/* $Id: handle.cpp $ */
+/* $Id: handle.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Generic Handle Manipulation.
*/
diff --git a/src/VBox/Runtime/common/misc/handletable.cpp b/src/VBox/Runtime/common/misc/handletable.cpp
index a4139b003..1a80a3e14 100644
--- a/src/VBox/Runtime/common/misc/handletable.cpp
+++ b/src/VBox/Runtime/common/misc/handletable.cpp
@@ -1,4 +1,4 @@
-/* $Id: handletable.cpp $ */
+/* $Id: handletable.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Handle Tables.
*/
diff --git a/src/VBox/Runtime/common/misc/handletable.h b/src/VBox/Runtime/common/misc/handletable.h
index 5e2eac29d..27ae574ed 100644
--- a/src/VBox/Runtime/common/misc/handletable.h
+++ b/src/VBox/Runtime/common/misc/handletable.h
@@ -1,4 +1,4 @@
-/* $Id: handletable.h $ */
+/* $Id: handletable.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Handle Tables, internal header.
*/
diff --git a/src/VBox/Runtime/common/misc/handletablectx.cpp b/src/VBox/Runtime/common/misc/handletablectx.cpp
index f88363b77..e0511cc2b 100644
--- a/src/VBox/Runtime/common/misc/handletablectx.cpp
+++ b/src/VBox/Runtime/common/misc/handletablectx.cpp
@@ -1,4 +1,4 @@
-/* $Id: handletablectx.cpp $ */
+/* $Id: handletablectx.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Handle Tables.
*/
diff --git a/src/VBox/Runtime/common/misc/handletablesimple.cpp b/src/VBox/Runtime/common/misc/handletablesimple.cpp
index c5d685ffe..7fbd77030 100644
--- a/src/VBox/Runtime/common/misc/handletablesimple.cpp
+++ b/src/VBox/Runtime/common/misc/handletablesimple.cpp
@@ -1,4 +1,4 @@
-/* $Id: handletablesimple.cpp $ */
+/* $Id: handletablesimple.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Handle Tables.
*/
diff --git a/src/VBox/Runtime/common/misc/lockvalidator.cpp b/src/VBox/Runtime/common/misc/lockvalidator.cpp
index 9d29404d7..1542221ae 100644
--- a/src/VBox/Runtime/common/misc/lockvalidator.cpp
+++ b/src/VBox/Runtime/common/misc/lockvalidator.cpp
@@ -1,4 +1,4 @@
-/* $Id: lockvalidator.cpp $ */
+/* $Id: lockvalidator.cpp 36597 2011-04-06 19:46:15Z vboxsync $ */
/** @file
* IPRT - Lock Validator.
*/
@@ -42,6 +42,7 @@
#include "internal/lockvalidator.h"
#include "internal/magics.h"
+#include "internal/strhash.h"
#include "internal/thread.h"
@@ -850,29 +851,6 @@ DECL_FORCE_INLINE(void) rtLockValidatorSrcPosInit(PRTLOCKVALSRCPOS pSrcPos)
}
-/* sdbm:
- This algorithm was created for sdbm (a public-domain reimplementation of
- ndbm) database library. it was found to do well in scrambling bits,
- causing better distribution of the keys and fewer splits. it also happens
- to be a good general hashing function with good distribution. the actual
- function is hash(i) = hash(i - 1) * 65599 + str[i]; what is included below
- is the faster version used in gawk. [there is even a faster, duff-device
- version] the magic constant 65599 was picked out of thin air while
- experimenting with different constants, and turns out to be a prime.
- this is one of the algorithms used in berkeley db (see sleepycat) and
- elsewhere. */
-DECL_FORCE_INLINE(uint32_t) sdbm(const char *str, uint32_t hash)
-{
- uint8_t *pu8 = (uint8_t *)str;
- int c;
-
- while ((c = *pu8++))
- hash = c + (hash << 6) + (hash << 16) - hash;
-
- return hash;
-}
-
-
/**
* Hashes the specified source position.
*
@@ -888,9 +866,9 @@ static uint32_t rtLockValidatorSrcPosHash(PCRTLOCKVALSRCPOS pSrcPos)
{
uHash = 0;
if (pSrcPos->pszFile)
- uHash = sdbm(pSrcPos->pszFile, uHash);
+ uHash = sdbmInc(pSrcPos->pszFile, uHash);
if (pSrcPos->pszFunction)
- uHash = sdbm(pSrcPos->pszFunction, uHash);
+ uHash = sdbmInc(pSrcPos->pszFunction, uHash);
uHash += pSrcPos->uLine;
}
else
diff --git a/src/VBox/Runtime/common/misc/message.cpp b/src/VBox/Runtime/common/misc/message.cpp
index 937858708..a136c84e1 100644
--- a/src/VBox/Runtime/common/misc/message.cpp
+++ b/src/VBox/Runtime/common/misc/message.cpp
@@ -1,4 +1,4 @@
-/* $Id: message.cpp $ */
+/* $Id: message.cpp 37951 2011-07-14 10:13:59Z vboxsync $ */
/** @file
* IPRT - Error reporting to standard error.
*/
@@ -36,6 +36,31 @@
#include "internal/process.h"
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/** The program name we're using. */
+static const char * volatile g_pszProgName = NULL;
+/** Custom program name set via RTMsgSetProgName. */
+static char g_szProgName[128];
+
+
+RTDECL(int) RTMsgSetProgName(const char *pszFormat, ...)
+{
+ g_pszProgName = &g_szrtProcExePath[g_offrtProcName];
+
+ va_list va;
+ va_start(va, pszFormat);
+ RTStrPrintfV(g_szProgName, sizeof(g_szProgName) - 1, pszFormat, va);
+ va_end(va);
+
+ g_pszProgName = g_szProgName;
+
+ return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTMsgSetProgName);
+
+
static int rtMsgWorker(PRTSTREAM pDst, const char *pszPrefix, const char *pszFormat, va_list va)
{
if ( !*pszFormat
@@ -43,6 +68,10 @@ static int rtMsgWorker(PRTSTREAM pDst, const char *pszPrefix, const char *pszFor
RTStrmPrintf(pDst, "\n");
else
{
+ const char *pszProgName = g_pszProgName;
+ if (!pszProgName)
+ g_pszProgName = pszProgName = &g_szrtProcExePath[g_offrtProcName];
+
char *pszMsg;
ssize_t cch = RTStrAPrintfV(&pszMsg, pszFormat, va);
if (cch >= 0)
@@ -54,7 +83,7 @@ static int rtMsgWorker(PRTSTREAM pDst, const char *pszPrefix, const char *pszFor
char *pszEnd = strchr(psz, '\n');
if (!pszEnd)
{
- RTStrmPrintf(pDst, "%s: %s%s\n", &g_szrtProcExePath[g_offrtProcName], pszPrefix, psz);
+ RTStrmPrintf(pDst, "%s: %s%s\n", pszProgName, pszPrefix, psz);
break;
}
if (pszEnd == psz)
@@ -62,7 +91,7 @@ static int rtMsgWorker(PRTSTREAM pDst, const char *pszPrefix, const char *pszFor
else
{
*pszEnd = '\0';
- RTStrmPrintf(pDst, "%s: %s%s\n", &g_szrtProcExePath[g_offrtProcName], pszPrefix, psz);
+ RTStrmPrintf(pDst, "%s: %s%s\n", pszProgName, pszPrefix, psz);
}
psz = pszEnd + 1;
} while (*psz);
@@ -71,7 +100,7 @@ static int rtMsgWorker(PRTSTREAM pDst, const char *pszPrefix, const char *pszFor
else
{
/* Simple fallback for handling out-of-memory conditions. */
- RTStrmPrintf(pDst, "%s: %s", &g_szrtProcExePath[g_offrtProcName], pszPrefix);
+ RTStrmPrintf(pDst, "%s: %s", pszProgName, pszPrefix);
RTStrmPrintfV(pDst, pszFormat, va);
if (!strchr(pszFormat, '\n'))
RTStrmPrintf(pDst, "\n");
diff --git a/src/VBox/Runtime/common/misc/once.cpp b/src/VBox/Runtime/common/misc/once.cpp
index 4b0a31d0b..468d5cb85 100644
--- a/src/VBox/Runtime/common/misc/once.cpp
+++ b/src/VBox/Runtime/common/misc/once.cpp
@@ -1,4 +1,4 @@
-/* $Id: once.cpp $ */
+/* $Id: once.cpp 37316 2011-06-03 12:49:02Z vboxsync $ */
/** @file
* IPRT - Execute Once.
*/
@@ -156,7 +156,7 @@ static int rtOnceOtherThread(PRTONCE pOnce, PRTSEMEVENTMULTI phEvtM)
}
-RTDECL(int) RTOnce(PRTONCE pOnce, PFNRTONCE pfnOnce, void *pvUser1, void *pvUser2)
+RTDECL(int) RTOnceSlow(PRTONCE pOnce, PFNRTONCE pfnOnce, void *pvUser1, void *pvUser2)
{
/*
* Validate input (strict builds only).
@@ -243,7 +243,7 @@ RTDECL(int) RTOnce(PRTONCE pOnce, PFNRTONCE pfnOnce, void *pvUser1, void *pvUser
return rcOnce;
}
-RT_EXPORT_SYMBOL(RTOnce);
+RT_EXPORT_SYMBOL(RTOnceSlow);
RTDECL(void) RTOnceReset(PRTONCE pOnce)
diff --git a/src/VBox/Runtime/common/misc/req.cpp b/src/VBox/Runtime/common/misc/req.cpp
index aff3b447d..60f27c6f3 100644
--- a/src/VBox/Runtime/common/misc/req.cpp
+++ b/src/VBox/Runtime/common/misc/req.cpp
@@ -1,4 +1,4 @@
-/* $Id: req.cpp $ */
+/* $Id: req.cpp 33595 2010-10-29 10:35:00Z vboxsync $ */
/** @file
* IPRT - Request packets
*/
diff --git a/src/VBox/Runtime/common/misc/s3.cpp b/src/VBox/Runtime/common/misc/s3.cpp
index 06e6766a9..963fb3fe8 100644
--- a/src/VBox/Runtime/common/misc/s3.cpp
+++ b/src/VBox/Runtime/common/misc/s3.cpp
@@ -1,4 +1,4 @@
-/* $Id: s3.cpp $ */
+/* $Id: s3.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - S3 communication API.
*/
diff --git a/src/VBox/Runtime/common/misc/sanity-c.c b/src/VBox/Runtime/common/misc/sanity-c.c
index 042cf3839..28cf5475a 100644
--- a/src/VBox/Runtime/common/misc/sanity-c.c
+++ b/src/VBox/Runtime/common/misc/sanity-c.c
@@ -1,4 +1,4 @@
-/* $Id: sanity-c.c $ */
+/* $Id: sanity-c.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Setup Sanity Checks, C.
*/
diff --git a/src/VBox/Runtime/common/misc/sanity-cpp.cpp b/src/VBox/Runtime/common/misc/sanity-cpp.cpp
index ea0202d9f..2bbdf33e0 100644
--- a/src/VBox/Runtime/common/misc/sanity-cpp.cpp
+++ b/src/VBox/Runtime/common/misc/sanity-cpp.cpp
@@ -1,4 +1,4 @@
-/* $Id: sanity-cpp.cpp $ */
+/* $Id: sanity-cpp.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Setup Sanity Checks, C++.
*/
diff --git a/src/VBox/Runtime/common/misc/sanity.h b/src/VBox/Runtime/common/misc/sanity.h
index f0461c425..97c7dc077 100644
--- a/src/VBox/Runtime/common/misc/sanity.h
+++ b/src/VBox/Runtime/common/misc/sanity.h
@@ -1,4 +1,4 @@
-/* $Id: sanity.h $ */
+/* $Id: sanity.h 35512 2011-01-12 17:50:12Z vboxsync $ */
/** @file
* IPRT - Setup Sanity Checks, C and C++.
*/
diff --git a/src/VBox/Runtime/common/misc/semspingpong.cpp b/src/VBox/Runtime/common/misc/semspingpong.cpp
index e13bed820..fa3802fa7 100644
--- a/src/VBox/Runtime/common/misc/semspingpong.cpp
+++ b/src/VBox/Runtime/common/misc/semspingpong.cpp
@@ -1,4 +1,4 @@
-/* $Id: semspingpong.cpp $ */
+/* $Id: semspingpong.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Thread Ping-Pong Construct.
*/
diff --git a/src/VBox/Runtime/common/misc/setjmp.asm b/src/VBox/Runtime/common/misc/setjmp.asm
index 9bacbbc4e..811f03abd 100644
--- a/src/VBox/Runtime/common/misc/setjmp.asm
+++ b/src/VBox/Runtime/common/misc/setjmp.asm
@@ -1,4 +1,4 @@
-; $Id: setjmp.asm $
+; $Id: setjmp.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT setjmp & longjmp - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/misc/sg.cpp b/src/VBox/Runtime/common/misc/sg.cpp
index 4d3192d86..08ef8b632 100644
--- a/src/VBox/Runtime/common/misc/sg.cpp
+++ b/src/VBox/Runtime/common/misc/sg.cpp
@@ -1,4 +1,4 @@
-/* $Id: sg.cpp $ */
+/* $Id: sg.cpp 36312 2011-03-18 12:59:15Z vboxsync $ */
/** @file
* IPRT - S/G buffer handling.
*/
@@ -38,6 +38,13 @@ static void *sgBufGet(PRTSGBUF pSgBuf, size_t *pcbData)
size_t cbData = RT_MIN(*pcbData, pSgBuf->cbSegLeft);
void *pvBuf = pSgBuf->pvSegCur;
+ AssertReleaseMsg( pSgBuf->cbSegLeft <= 5 * _1M
+ && (uintptr_t)pSgBuf->pvSegCur >= (uintptr_t)pSgBuf->paSegs[pSgBuf->idxSeg].pvSeg
+ && (uintptr_t)pSgBuf->pvSegCur + pSgBuf->cbSegLeft <= (uintptr_t)pSgBuf->paSegs[pSgBuf->idxSeg].pvSeg + pSgBuf->paSegs[pSgBuf->idxSeg].cbSeg,
+ ("pSgBuf->idxSeg=%d pSgBuf->cSegs=%d pSgBuf->pvSegCur=%p pSgBuf->cbSegLeft=%zd pSgBuf->paSegs[%d].pvSeg=%p pSgBuf->paSegs[%d].cbSeg=%zd\n",
+ pSgBuf->idxSeg, pSgBuf->cSegs, pSgBuf->pvSegCur, pSgBuf->cbSegLeft,
+ pSgBuf->idxSeg, pSgBuf->paSegs[pSgBuf->idxSeg].pvSeg, pSgBuf->idxSeg, pSgBuf->paSegs[pSgBuf->idxSeg].cbSeg));
+
pSgBuf->cbSegLeft -= cbData;
/* Advance to the next segment if required. */
diff --git a/src/VBox/Runtime/common/misc/term.cpp b/src/VBox/Runtime/common/misc/term.cpp
index 7b789df84..c62953a04 100644
--- a/src/VBox/Runtime/common/misc/term.cpp
+++ b/src/VBox/Runtime/common/misc/term.cpp
@@ -1,4 +1,4 @@
-/* $Id: term.cpp $ */
+/* $Id: term.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Common Termination Code.
*/
diff --git a/src/VBox/Runtime/common/misc/thread.cpp b/src/VBox/Runtime/common/misc/thread.cpp
index 5a61bd8ef..85a2cf114 100644
--- a/src/VBox/Runtime/common/misc/thread.cpp
+++ b/src/VBox/Runtime/common/misc/thread.cpp
@@ -1,4 +1,4 @@
-/* $Id: thread.cpp $ */
+/* $Id: thread.cpp 36951 2011-05-04 07:07:34Z vboxsync $ */
/** @file
* IPRT - Threads, common routines.
*/
@@ -83,13 +83,17 @@ static RTSEMRW g_ThreadRWSem = NIL_RTSEMRW;
/** The spinlocks protecting the tree. */
static RTSPINLOCK g_ThreadSpinlock = NIL_RTSPINLOCK;
#endif
+/** Indicates whether we've been initialized or not. */
+static bool g_frtThreadInitialized;
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
static void rtThreadDestroy(PRTTHREADINT pThread);
+#ifdef IN_RING3
static int rtThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFlags, const char *pszName);
+#endif
static void rtThreadRemoveLocked(PRTTHREADINT pThread);
static PRTTHREADINT rtThreadAlloc(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFlags, const char *pszName);
@@ -126,7 +130,7 @@ static PRTTHREADINT rtThreadAlloc(RTTHREADTYPE enmType, unsigned fFlags, uint32_
*
* @returns iprt status code.
*/
-int rtThreadInit(void)
+DECLHIDDEN(int) rtThreadInit(void)
{
#ifdef IN_RING3
int rc = VINF_ALREADY_INITIALIZED;
@@ -145,7 +149,10 @@ int rtThreadInit(void)
if (RT_SUCCESS(rc))
rc = rtSchedNativeCalcDefaultPriority(RTTHREADTYPE_DEFAULT);
if (RT_SUCCESS(rc))
+ {
+ g_frtThreadInitialized = true;
return VINF_SUCCESS;
+ }
/* failed, clear out */
RTSemRWDestroy(g_ThreadRWSem);
@@ -154,17 +161,20 @@ int rtThreadInit(void)
}
#elif defined(IN_RING0)
-
+ int rc;
/*
* Create the spinlock and to native init.
*/
Assert(g_ThreadSpinlock == NIL_RTSPINLOCK);
- int rc = RTSpinlockCreate(&g_ThreadSpinlock);
+ rc = RTSpinlockCreate(&g_ThreadSpinlock);
if (RT_SUCCESS(rc))
{
rc = rtThreadNativeInit();
if (RT_SUCCESS(rc))
+ {
+ g_frtThreadInitialized = true;
return VINF_SUCCESS;
+ }
/* failed, clear out */
RTSpinlockDestroy(g_ThreadSpinlock);
@@ -180,7 +190,7 @@ int rtThreadInit(void)
/**
* Terminates the thread database.
*/
-void rtThreadTerm(void)
+DECLHIDDEN(void) rtThreadTerm(void)
{
#ifdef IN_RING3
/* we don't cleanup here yet */
@@ -228,8 +238,6 @@ DECLINLINE(void) rtThreadUnLockRD(void)
AssertReleaseRC(rc);
}
-#endif /* IN_RING3 */
-
/**
* Adopts the calling thread.
@@ -237,6 +245,8 @@ DECLINLINE(void) rtThreadUnLockRD(void)
*/
static int rtThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFlags, const char *pszName)
{
+ int rc;
+ PRTTHREADINT pThread;
Assert(!(fFlags & RTTHREADFLAGS_WAITABLE));
fFlags &= ~RTTHREADFLAGS_WAITABLE;
@@ -245,8 +255,8 @@ static int rtThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFla
* (It is vital that rtThreadNativeAdopt updates the TLS before
* we try inserting the thread because of locking.)
*/
- int rc = VERR_NO_MEMORY;
- PRTTHREADINT pThread = rtThreadAlloc(enmType, fFlags, RTTHREADINT_FLAGS_ALIEN | fIntFlags, pszName);
+ rc = VERR_NO_MEMORY;
+ pThread = rtThreadAlloc(enmType, fFlags, RTTHREADINT_FLAGS_ALIEN | fIntFlags, pszName);
if (pThread)
{
RTNATIVETHREAD NativeThread = RTThreadNativeSelf();
@@ -261,7 +271,6 @@ static int rtThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFla
return rc;
}
-
/**
* Adopts a non-IPRT thread.
*
@@ -273,12 +282,15 @@ static int rtThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFla
*/
RTDECL(int) RTThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, const char *pszName, PRTTHREAD pThread)
{
+ int rc;
+ RTTHREAD Thread;
+
AssertReturn(!(fFlags & RTTHREADFLAGS_WAITABLE), VERR_INVALID_PARAMETER);
AssertReturn(!pszName || VALID_PTR(pszName), VERR_INVALID_POINTER);
AssertReturn(!pThread || VALID_PTR(pThread), VERR_INVALID_POINTER);
- int rc = VINF_SUCCESS;
- RTTHREAD Thread = RTThreadSelf();
+ rc = VINF_SUCCESS;
+ Thread = RTThreadSelf();
if (Thread == NIL_RTTHREAD)
{
/* generate a name if none was given. */
@@ -323,6 +335,7 @@ RTDECL(RTTHREAD) RTThreadSelfAutoAdopt(void)
}
RT_EXPORT_SYMBOL(RTThreadSelfAutoAdopt);
+#endif /* IN_RING3 */
/**
* Allocates a per thread data structure and initializes the basic fields.
@@ -340,9 +353,12 @@ PRTTHREADINT rtThreadAlloc(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntF
PRTTHREADINT pThread = (PRTTHREADINT)RTMemAllocZ(sizeof(RTTHREADINT));
if (pThread)
{
+ size_t cchName;
+ int rc;
+
pThread->Core.Key = (void*)NIL_RTTHREAD;
pThread->u32Magic = RTTHREADINT_MAGIC;
- size_t cchName = strlen(pszName);
+ cchName = strlen(pszName);
if (cchName >= RTTHREAD_NAME_LEN)
cchName = RTTHREAD_NAME_LEN - 1;
memcpy(pThread->szName, pszName, cchName);
@@ -360,7 +376,7 @@ PRTTHREADINT rtThreadAlloc(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntF
#ifdef RT_WITH_ICONV_CACHE
rtStrIconvCacheInit(pThread);
#endif
- int rc = RTSemEventMultiCreate(&pThread->EventUser);
+ rc = RTSemEventMultiCreate(&pThread->EventUser);
if (RT_SUCCESS(rc))
{
rc = RTSemEventMultiCreate(&pThread->EventTerminated);
@@ -383,55 +399,58 @@ PRTTHREADINT rtThreadAlloc(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntF
* @param pThread Pointer to thread structure allocated by rtThreadAlloc().
* @param NativeThread The native thread id.
*/
-void rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread)
+DECLHIDDEN(void) rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread)
{
Assert(pThread);
Assert(pThread->u32Magic == RTTHREADINT_MAGIC);
- RT_THREAD_LOCK_TMP(Tmp);
- RT_THREAD_LOCK_RW(Tmp);
-
- /*
- * Do not insert a terminated thread.
- *
- * This may happen if the thread finishes before the RTThreadCreate call
- * gets this far. Since the OS may quickly reuse the native thread ID
- * it should not be reinserted at this point.
- */
- if (rtThreadGetState(pThread) != RTTHREADSTATE_TERMINATED)
{
+ RT_THREAD_LOCK_TMP(Tmp);
+ RT_THREAD_LOCK_RW(Tmp);
+
/*
- * Before inserting we must check if there is a thread with this id
- * in the tree already. We're racing parent and child on insert here
- * so that the handle is valid in both ends when they return / start.
+ * Do not insert a terminated thread.
*
- * If it's not ourself we find, it's a dead alien thread and we will
- * unlink it from the tree. Alien threads will be released at this point.
+ * This may happen if the thread finishes before the RTThreadCreate call
+ * gets this far. Since the OS may quickly reuse the native thread ID
+ * it should not be reinserted at this point.
*/
- PRTTHREADINT pThreadOther = (PRTTHREADINT)RTAvlPVGet(&g_ThreadTree, (void *)NativeThread);
- if (pThreadOther != pThread)
+ if (rtThreadGetState(pThread) != RTTHREADSTATE_TERMINATED)
{
- /* remove dead alien if any */
- if (pThreadOther)
+ /*
+ * Before inserting we must check if there is a thread with this id
+ * in the tree already. We're racing parent and child on insert here
+ * so that the handle is valid in both ends when they return / start.
+ *
+ * If it's not ourself we find, it's a dead alien thread and we will
+ * unlink it from the tree. Alien threads will be released at this point.
+ */
+ PRTTHREADINT pThreadOther = (PRTTHREADINT)RTAvlPVGet(&g_ThreadTree, (void *)NativeThread);
+ if (pThreadOther != pThread)
{
- AssertMsg(pThreadOther->fIntFlags & RTTHREADINT_FLAGS_ALIEN, ("%p:%s; %p:%s\n", pThread, pThread->szName, pThreadOther, pThreadOther->szName));
- ASMAtomicBitClear(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE_BIT);
- rtThreadRemoveLocked(pThreadOther);
- if (pThreadOther->fIntFlags & RTTHREADINT_FLAGS_ALIEN)
+ bool fRc;
+ /* remove dead alien if any */
+ if (pThreadOther)
+ {
+ AssertMsg(pThreadOther->fIntFlags & RTTHREADINT_FLAGS_ALIEN, ("%p:%s; %p:%s\n", pThread, pThread->szName, pThreadOther, pThreadOther->szName));
+ ASMAtomicBitClear(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE_BIT);
+ rtThreadRemoveLocked(pThreadOther);
+ if (pThreadOther->fIntFlags & RTTHREADINT_FLAGS_ALIEN)
rtThreadRelease(pThreadOther);
- }
+ }
- /* insert the thread */
- ASMAtomicWritePtr(&pThread->Core.Key, (void *)NativeThread);
- bool fRc = RTAvlPVInsert(&g_ThreadTree, &pThread->Core);
- ASMAtomicOrU32(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE);
+ /* insert the thread */
+ ASMAtomicWritePtr(&pThread->Core.Key, (void *)NativeThread);
+ fRc = RTAvlPVInsert(&g_ThreadTree, &pThread->Core);
+ ASMAtomicOrU32(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE);
- AssertReleaseMsg(fRc, ("Lock problem? %p (%RTnthrd) %s\n", pThread, NativeThread, pThread->szName));
- NOREF(fRc);
+ AssertReleaseMsg(fRc, ("Lock problem? %p (%RTnthrd) %s\n", pThread, NativeThread, pThread->szName));
+ NOREF(fRc);
+ }
}
- }
- RT_THREAD_UNLOCK_RW(Tmp);
+ RT_THREAD_UNLOCK_RW(Tmp);
+ }
}
@@ -486,14 +505,15 @@ DECLINLINE(bool) rtThreadIsAlive(PRTTHREADINT pThread)
* @returns NULL if not a thread IPRT knows.
* @param NativeThread The native thread id.
*/
-PRTTHREADINT rtThreadGetByNative(RTNATIVETHREAD NativeThread)
+DECLHIDDEN(PRTTHREADINT) rtThreadGetByNative(RTNATIVETHREAD NativeThread)
{
+ PRTTHREADINT pThread;
/*
* Simple tree lookup.
*/
RT_THREAD_LOCK_TMP(Tmp);
RT_THREAD_LOCK_RD(Tmp);
- PRTTHREADINT pThread = (PRTTHREADINT)RTAvlPVGet(&g_ThreadTree, (void *)NativeThread);
+ pThread = (PRTTHREADINT)RTAvlPVGet(&g_ThreadTree, (void *)NativeThread);
RT_THREAD_UNLOCK_RD(Tmp);
return pThread;
}
@@ -507,7 +527,7 @@ PRTTHREADINT rtThreadGetByNative(RTNATIVETHREAD NativeThread)
* @returns NULL if Thread was not found.
* @param Thread Thread id which structure is to be returned.
*/
-PRTTHREADINT rtThreadGet(RTTHREAD Thread)
+DECLHIDDEN(PRTTHREADINT) rtThreadGet(RTTHREAD Thread)
{
if ( Thread != NIL_RTTHREAD
&& VALID_PTR(Thread))
@@ -531,10 +551,11 @@ PRTTHREADINT rtThreadGet(RTTHREAD Thread)
* @returns New reference count.
* @param pThread The thread structure to release.
*/
-uint32_t rtThreadRelease(PRTTHREADINT pThread)
+DECLHIDDEN(uint32_t) rtThreadRelease(PRTTHREADINT pThread)
{
- Assert(pThread);
uint32_t cRefs;
+
+ Assert(pThread);
if (pThread->cRefs >= 1)
{
cRefs = ASMAtomicDecU32(&pThread->cRefs);
@@ -557,6 +578,7 @@ uint32_t rtThreadRelease(PRTTHREADINT pThread)
*/
static void rtThreadDestroy(PRTTHREADINT pThread)
{
+ RTSEMEVENTMULTI hEvt1, hEvt2;
/*
* Remove it from the tree and mark it as dead.
*
@@ -587,9 +609,9 @@ static void rtThreadDestroy(PRTTHREADINT pThread)
ASMAtomicXchgU32(&pThread->u32Magic, RTTHREADINT_MAGIC_DEAD);
ASMAtomicWritePtr(&pThread->Core.Key, (void *)NIL_RTTHREAD);
pThread->enmType = RTTHREADTYPE_INVALID;
- RTSEMEVENTMULTI hEvt1 = pThread->EventUser;
+ hEvt1 = pThread->EventUser;
pThread->EventUser = NIL_RTSEMEVENTMULTI;
- RTSEMEVENTMULTI hEvt2 = pThread->EventTerminated;
+ hEvt2 = pThread->EventTerminated;
pThread->EventTerminated = NIL_RTSEMEVENTMULTI;
#ifdef IN_RING3
@@ -615,7 +637,7 @@ static void rtThreadDestroy(PRTTHREADINT pThread)
* @param pThread The thread structure.
* @param rc The thread result code.
*/
-void rtThreadTerminate(PRTTHREADINT pThread, int rc)
+DECLHIDDEN(void) rtThreadTerminate(PRTTHREADINT pThread, int rc)
{
Assert(pThread->cRefs >= 1);
@@ -654,8 +676,9 @@ void rtThreadTerminate(PRTTHREADINT pThread, int rc)
* @param NativeThread The native thread id.
* @param pszThreadName The name of the thread (purely a dummy for backtrace).
*/
-int rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *pszThreadName)
+DECLHIDDEN(int) rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *pszThreadName)
{
+ int rc;
NOREF(pszThreadName);
rtThreadInsert(pThread, NativeThread);
Log(("rtThreadMain: Starting: pThread=%p NativeThread=%RTnthrd Name=%s pfnThread=%p pvUser=%p\n",
@@ -664,7 +687,7 @@ int rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *
/*
* Change the priority.
*/
- int rc = rtThreadNativeSetPriority(pThread, pThread->enmType);
+ rc = rtThreadNativeSetPriority(pThread, pThread->enmType);
#ifdef IN_RING3
AssertMsgRC(rc, ("Failed to set priority of thread %p (%RTnthrd / %s) to enmType=%d enmPriority=%d rc=%Rrc\n",
pThread, NativeThread, pThread->szName, pThread->enmType, g_enmProcessPriority, rc));
@@ -713,6 +736,9 @@ int rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *
RTDECL(int) RTThreadCreate(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
RTTHREADTYPE enmType, unsigned fFlags, const char *pszName)
{
+ int rc;
+ PRTTHREADINT pThreadInt;
+
LogFlow(("RTThreadCreate: pThread=%p pfnThread=%p pvUser=%p cbStack=%#x enmType=%d fFlags=%#x pszName=%p:{%s}\n",
pThread, pfnThread, pvUser, cbStack, enmType, fFlags, pszName, pszName));
@@ -743,15 +769,15 @@ RTDECL(int) RTThreadCreate(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUse
/*
* Allocate thread argument.
*/
- int rc;
- PRTTHREADINT pThreadInt = rtThreadAlloc(enmType, fFlags, 0, pszName);
+ pThreadInt = rtThreadAlloc(enmType, fFlags, 0, pszName);
if (pThreadInt)
{
+ RTNATIVETHREAD NativeThread;
+
pThreadInt->pfnThread = pfnThread;
pThreadInt->pvUser = pvUser;
pThreadInt->cbStack = cbStack;
- RTNATIVETHREAD NativeThread;
rc = rtThreadNativeCreate(pThreadInt, &NativeThread);
if (RT_SUCCESS(rc))
{
@@ -819,8 +845,9 @@ RTDECL(int) RTThreadCreateF(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUs
RTTHREADTYPE enmType, uint32_t fFlags, const char *pszNameFmt, ...)
{
va_list va;
+ int rc;
va_start(va, pszNameFmt);
- int rc = RTThreadCreateV(pThread, pfnThread, pvUser, cbStack, enmType, fFlags, pszNameFmt, va);
+ rc = RTThreadCreateV(pThread, pfnThread, pvUser, cbStack, enmType, fFlags, pszNameFmt, va);
va_end(va);
return rc;
}
@@ -897,9 +924,10 @@ RT_EXPORT_SYMBOL(RTThreadSelfName);
*/
RTDECL(const char *) RTThreadGetName(RTTHREAD Thread)
{
+ PRTTHREADINT pThread;
if (Thread == NIL_RTTHREAD)
return NULL;
- PRTTHREADINT pThread = rtThreadGet(Thread);
+ pThread = rtThreadGet(Thread);
if (pThread)
{
const char *szName = pThread->szName;
@@ -923,13 +951,14 @@ RTDECL(int) RTThreadSetName(RTTHREAD Thread, const char *pszName)
/*
* Validate input.
*/
+ PRTTHREADINT pThread;
size_t cchName = strlen(pszName);
if (cchName >= RTTHREAD_NAME_LEN)
{
AssertMsgFailed(("pszName=%s is too long, max is %d\n", pszName, RTTHREAD_NAME_LEN - 1));
return VERR_INVALID_PARAMETER;
}
- PRTTHREADINT pThread = rtThreadGet(Thread);
+ pThread = rtThreadGet(Thread);
if (!pThread)
return VERR_INVALID_HANDLE;
@@ -970,6 +999,47 @@ RTDECL(bool) RTThreadIsMain(RTTHREAD hThread)
RT_EXPORT_SYMBOL(RTThreadIsMain);
+RTDECL(bool) RTThreadIsSelfAlive(void)
+{
+ if (g_frtThreadInitialized)
+ {
+ RTTHREAD hSelf = RTThreadSelf();
+ if (hSelf != NIL_RTTHREAD)
+ {
+ /*
+ * Inspect the thread state. ASSUMES thread state order.
+ */
+ RTTHREADSTATE enmState = rtThreadGetState(hSelf);
+ if ( enmState >= RTTHREADSTATE_RUNNING
+ && enmState <= RTTHREADSTATE_END)
+ return true;
+ }
+ }
+ return false;
+}
+RT_EXPORT_SYMBOL(RTThreadIsSelfAlive);
+
+
+RTDECL(bool) RTThreadIsSelfKnown(void)
+{
+ if (g_frtThreadInitialized)
+ {
+ RTTHREAD hSelf = RTThreadSelf();
+ if (hSelf != NIL_RTTHREAD)
+ return true;
+ }
+ return false;
+}
+RT_EXPORT_SYMBOL(RTThreadIsSelfKnown);
+
+
+RTDECL(bool) RTThreadIsInitialized(void)
+{
+ return g_frtThreadInitialized;
+}
+RT_EXPORT_SYMBOL(RTThreadIsInitialized);
+
+
/**
* Signal the user event.
*
@@ -1270,7 +1340,7 @@ static DECLCALLBACK(int) rtThreadSetPriorityOne(PAVLPVNODECORE pNode, void *pvUs
* @returns iprt status code.
* @param enmPriority The new priority.
*/
-int rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority)
+DECLHIDDEN(int) rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority)
{
LogFlow(("rtThreadDoSetProcPriority: enmPriority=%d\n", enmPriority));
@@ -1452,7 +1522,7 @@ static DECLCALLBACK(int) rtThreadClearTlsEntryCallback(PAVLPVNODECORE pNode, voi
*
* @param iTls The TLS entry. (valid)
*/
-void rtThreadClearTlsEntry(RTTLS iTls)
+DECLHIDDEN(void) rtThreadClearTlsEntry(RTTLS iTls)
{
RT_THREAD_LOCK_TMP(Tmp);
RT_THREAD_LOCK_RD(Tmp);
@@ -1461,4 +1531,3 @@ void rtThreadClearTlsEntry(RTTLS iTls)
}
#endif /* IPRT_WITH_GENERIC_TLS */
-
diff --git a/src/VBox/Runtime/common/path/RTPathAbsDup.cpp b/src/VBox/Runtime/common/path/RTPathAbsDup.cpp
index b9f217f99..50572f39f 100644
--- a/src/VBox/Runtime/common/path/RTPathAbsDup.cpp
+++ b/src/VBox/Runtime/common/path/RTPathAbsDup.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathAbsDup.cpp $ */
+/* $Id: RTPathAbsDup.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathAbsDup
*/
diff --git a/src/VBox/Runtime/common/path/RTPathAbsEx.cpp b/src/VBox/Runtime/common/path/RTPathAbsEx.cpp
index c647b5473..bbd4f8095 100644
--- a/src/VBox/Runtime/common/path/RTPathAbsEx.cpp
+++ b/src/VBox/Runtime/common/path/RTPathAbsEx.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathAbsEx.cpp $ */
+/* $Id: RTPathAbsEx.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathAbsEx
*/
diff --git a/src/VBox/Runtime/common/path/RTPathAbsExDup.cpp b/src/VBox/Runtime/common/path/RTPathAbsExDup.cpp
index 8bb8cd176..f756cbb4a 100644
--- a/src/VBox/Runtime/common/path/RTPathAbsExDup.cpp
+++ b/src/VBox/Runtime/common/path/RTPathAbsExDup.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathAbsExDup.cpp $ */
+/* $Id: RTPathAbsExDup.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathAbsExDup
*/
diff --git a/src/VBox/Runtime/common/path/RTPathAppend.cpp b/src/VBox/Runtime/common/path/RTPathAppend.cpp
index 5bad6483e..a66bb3af7 100644
--- a/src/VBox/Runtime/common/path/RTPathAppend.cpp
+++ b/src/VBox/Runtime/common/path/RTPathAppend.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathAppend.cpp $ */
+/* $Id: RTPathAppend.cpp 34214 2010-11-19 17:18:15Z vboxsync $ */
/** @file
* IPRT - RTPathAppend
*/
diff --git a/src/VBox/Runtime/common/path/RTPathAppendEx.cpp b/src/VBox/Runtime/common/path/RTPathAppendEx.cpp
index 159b62558..e29910800 100644
--- a/src/VBox/Runtime/common/path/RTPathAppendEx.cpp
+++ b/src/VBox/Runtime/common/path/RTPathAppendEx.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathAppendEx.cpp $ */
+/* $Id: RTPathAppendEx.cpp 34214 2010-11-19 17:18:15Z vboxsync $ */
/** @file
* IPRT - RTPathAppendEx
*/
diff --git a/src/VBox/Runtime/common/path/RTPathChangeToDosSlashes.cpp b/src/VBox/Runtime/common/path/RTPathChangeToDosSlashes.cpp
index 68b58803e..848759fa1 100644
--- a/src/VBox/Runtime/common/path/RTPathChangeToDosSlashes.cpp
+++ b/src/VBox/Runtime/common/path/RTPathChangeToDosSlashes.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathChangeToDosSlashes.cpp $ */
+/* $Id: RTPathChangeToDosSlashes.cpp 34205 2010-11-19 15:09:08Z vboxsync $ */
/** @file
* IPRT - RTPathChangeToDosSlashes
*/
diff --git a/src/VBox/Runtime/common/path/RTPathChangeToUnixSlashes.cpp b/src/VBox/Runtime/common/path/RTPathChangeToUnixSlashes.cpp
index c8e5e3c3c..823c7ee83 100644
--- a/src/VBox/Runtime/common/path/RTPathChangeToUnixSlashes.cpp
+++ b/src/VBox/Runtime/common/path/RTPathChangeToUnixSlashes.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathChangeToUnixSlashes.cpp $ */
+/* $Id: RTPathChangeToUnixSlashes.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - RTPathChangeToUnixSlashes
*/
diff --git a/src/VBox/Runtime/common/path/RTPathCopyComponents.cpp b/src/VBox/Runtime/common/path/RTPathCopyComponents.cpp
index afe4738cc..55b5f4f86 100644
--- a/src/VBox/Runtime/common/path/RTPathCopyComponents.cpp
+++ b/src/VBox/Runtime/common/path/RTPathCopyComponents.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathCopyComponents.cpp $ */
+/* $Id: RTPathCopyComponents.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathCountComponents
*/
diff --git a/src/VBox/Runtime/common/path/RTPathCountComponents.cpp b/src/VBox/Runtime/common/path/RTPathCountComponents.cpp
index 509614634..63a213bfc 100644
--- a/src/VBox/Runtime/common/path/RTPathCountComponents.cpp
+++ b/src/VBox/Runtime/common/path/RTPathCountComponents.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathCountComponents.cpp $ */
+/* $Id: RTPathCountComponents.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathCountComponents
*/
diff --git a/src/VBox/Runtime/common/path/RTPathExt.cpp b/src/VBox/Runtime/common/path/RTPathExt.cpp
index 292c5f2f7..de33d45e8 100644
--- a/src/VBox/Runtime/common/path/RTPathExt.cpp
+++ b/src/VBox/Runtime/common/path/RTPathExt.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathExt.cpp $ */
+/* $Id: RTPathExt.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathExt
*/
diff --git a/src/VBox/Runtime/common/path/RTPathFilename.cpp b/src/VBox/Runtime/common/path/RTPathFilename.cpp
index a6ef8cf8c..a77835bf0 100644
--- a/src/VBox/Runtime/common/path/RTPathFilename.cpp
+++ b/src/VBox/Runtime/common/path/RTPathFilename.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathFilename.cpp $ */
+/* $Id: RTPathFilename.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathFilename
*/
diff --git a/src/VBox/Runtime/common/path/RTPathHaveExt.cpp b/src/VBox/Runtime/common/path/RTPathHaveExt.cpp
index e5be22e1e..506a53eed 100644
--- a/src/VBox/Runtime/common/path/RTPathHaveExt.cpp
+++ b/src/VBox/Runtime/common/path/RTPathHaveExt.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathHaveExt.cpp $ */
+/* $Id: RTPathHaveExt.cpp 32864 2010-10-01 12:32:06Z vboxsync $ */
/** @file
* IPRT - RTPathHaveExt
*/
diff --git a/src/VBox/Runtime/common/path/RTPathHavePath.cpp b/src/VBox/Runtime/common/path/RTPathHavePath.cpp
index 3e33d4608..0e7188c2d 100644
--- a/src/VBox/Runtime/common/path/RTPathHavePath.cpp
+++ b/src/VBox/Runtime/common/path/RTPathHavePath.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathHavePath.cpp $ */
+/* $Id: RTPathHavePath.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathHavePath
*/
diff --git a/src/VBox/Runtime/common/path/RTPathJoin.cpp b/src/VBox/Runtime/common/path/RTPathJoin.cpp
index 100a7987c..68919a49b 100644
--- a/src/VBox/Runtime/common/path/RTPathJoin.cpp
+++ b/src/VBox/Runtime/common/path/RTPathJoin.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathJoin.cpp $ */
+/* $Id: RTPathJoin.cpp 33450 2010-10-26 09:24:32Z vboxsync $ */
/** @file
* IPRT - RTPathJoin.
*/
diff --git a/src/VBox/Runtime/common/path/RTPathJoinA.cpp b/src/VBox/Runtime/common/path/RTPathJoinA.cpp
index c1b8fbe46..e50c692c7 100644
--- a/src/VBox/Runtime/common/path/RTPathJoinA.cpp
+++ b/src/VBox/Runtime/common/path/RTPathJoinA.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathJoinA.cpp $ */
+/* $Id: RTPathJoinA.cpp 33450 2010-10-26 09:24:32Z vboxsync $ */
/** @file
* IPRT - RTPathJoinA.
*/
diff --git a/src/VBox/Runtime/common/path/RTPathJoinEx.cpp b/src/VBox/Runtime/common/path/RTPathJoinEx.cpp
index d0b43e397..ab8b92172 100644
--- a/src/VBox/Runtime/common/path/RTPathJoinEx.cpp
+++ b/src/VBox/Runtime/common/path/RTPathJoinEx.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathJoinEx.cpp $ */
+/* $Id: RTPathJoinEx.cpp 34214 2010-11-19 17:18:15Z vboxsync $ */
/** @file
* IPRT - RTPathJoinEx.
*/
diff --git a/src/VBox/Runtime/common/path/RTPathParse.cpp b/src/VBox/Runtime/common/path/RTPathParse.cpp
index ce42e3309..fa22539ef 100644
--- a/src/VBox/Runtime/common/path/RTPathParse.cpp
+++ b/src/VBox/Runtime/common/path/RTPathParse.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathParse.cpp $ */
+/* $Id: RTPathParse.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathParse
*/
diff --git a/src/VBox/Runtime/common/path/RTPathRealDup.cpp b/src/VBox/Runtime/common/path/RTPathRealDup.cpp
index 18ce0a821..6d28932b2 100644
--- a/src/VBox/Runtime/common/path/RTPathRealDup.cpp
+++ b/src/VBox/Runtime/common/path/RTPathRealDup.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathRealDup.cpp $ */
+/* $Id: RTPathRealDup.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathRealDup
*/
diff --git a/src/VBox/Runtime/common/path/RTPathStartsWithRoot.cpp b/src/VBox/Runtime/common/path/RTPathStartsWithRoot.cpp
index 52118240a..6a9aeab2f 100644
--- a/src/VBox/Runtime/common/path/RTPathStartsWithRoot.cpp
+++ b/src/VBox/Runtime/common/path/RTPathStartsWithRoot.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathStartsWithRoot.cpp $ */
+/* $Id: RTPathStartsWithRoot.cpp 33245 2010-10-20 09:51:08Z vboxsync $ */
/** @file
* IPRT - RTPathStartsWithRoot
*/
diff --git a/src/VBox/Runtime/common/path/RTPathStripExt.cpp b/src/VBox/Runtime/common/path/RTPathStripExt.cpp
index 789bb3e99..aa8920588 100644
--- a/src/VBox/Runtime/common/path/RTPathStripExt.cpp
+++ b/src/VBox/Runtime/common/path/RTPathStripExt.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathStripExt.cpp $ */
+/* $Id: RTPathStripExt.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathStripExt
*/
diff --git a/src/VBox/Runtime/common/path/RTPathStripFilename.cpp b/src/VBox/Runtime/common/path/RTPathStripFilename.cpp
index 3db34165d..13548445b 100644
--- a/src/VBox/Runtime/common/path/RTPathStripFilename.cpp
+++ b/src/VBox/Runtime/common/path/RTPathStripFilename.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathStripFilename.cpp $ */
+/* $Id: RTPathStripFilename.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathStripFilename
*/
diff --git a/src/VBox/Runtime/common/path/RTPathStripTrailingSlash.cpp b/src/VBox/Runtime/common/path/RTPathStripTrailingSlash.cpp
index 2296e04b7..624409ce8 100644
--- a/src/VBox/Runtime/common/path/RTPathStripTrailingSlash.cpp
+++ b/src/VBox/Runtime/common/path/RTPathStripTrailingSlash.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathStripTrailingSlash.cpp $ */
+/* $Id: RTPathStripTrailingSlash.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathSTripTrailingSlash
*/
diff --git a/src/VBox/Runtime/common/path/RTPathTraverseList.cpp b/src/VBox/Runtime/common/path/RTPathTraverseList.cpp
index daa88dcec..c77d43792 100644
--- a/src/VBox/Runtime/common/path/RTPathTraverseList.cpp
+++ b/src/VBox/Runtime/common/path/RTPathTraverseList.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathTraverseList.cpp $ */
+/* $Id: RTPathTraverseList.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTPathTraverseList
*/
diff --git a/src/VBox/Runtime/common/path/comparepaths.cpp b/src/VBox/Runtime/common/path/comparepaths.cpp
index 7c42db33b..c8cf5e81f 100644
--- a/src/VBox/Runtime/common/path/comparepaths.cpp
+++ b/src/VBox/Runtime/common/path/comparepaths.cpp
@@ -1,4 +1,4 @@
-/* $Id: comparepaths.cpp $ */
+/* $Id: comparepaths.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Path Comparison.
*/
diff --git a/src/VBox/Runtime/common/path/rtPathRootSpecLen.cpp b/src/VBox/Runtime/common/path/rtPathRootSpecLen.cpp
index 92c911361..25db8263c 100644
--- a/src/VBox/Runtime/common/path/rtPathRootSpecLen.cpp
+++ b/src/VBox/Runtime/common/path/rtPathRootSpecLen.cpp
@@ -1,4 +1,4 @@
-/* $Id: rtPathRootSpecLen.cpp $ */
+/* $Id: rtPathRootSpecLen.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - rtPathRootSpecLen (internal).
*/
diff --git a/src/VBox/Runtime/common/path/rtPathVolumeSpecLen.cpp b/src/VBox/Runtime/common/path/rtPathVolumeSpecLen.cpp
index 4a9fcb7aa..e40d5a6f6 100644
--- a/src/VBox/Runtime/common/path/rtPathVolumeSpecLen.cpp
+++ b/src/VBox/Runtime/common/path/rtPathVolumeSpecLen.cpp
@@ -1,4 +1,4 @@
-/* $Id: rtPathVolumeSpecLen.cpp $ */
+/* $Id: rtPathVolumeSpecLen.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - rtPathVolumeSpecLen
*/
diff --git a/src/VBox/Runtime/common/rand/rand.cpp b/src/VBox/Runtime/common/rand/rand.cpp
index f4d1dad4d..8fd1214f6 100644
--- a/src/VBox/Runtime/common/rand/rand.cpp
+++ b/src/VBox/Runtime/common/rand/rand.cpp
@@ -1,4 +1,4 @@
-/* $Id: rand.cpp $ */
+/* $Id: rand.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Random Numbers.
*/
diff --git a/src/VBox/Runtime/common/rand/randadv.cpp b/src/VBox/Runtime/common/rand/randadv.cpp
index 7af090310..cb7fab745 100644
--- a/src/VBox/Runtime/common/rand/randadv.cpp
+++ b/src/VBox/Runtime/common/rand/randadv.cpp
@@ -1,4 +1,4 @@
-/* $Id: randadv.cpp $ */
+/* $Id: randadv.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Random Numbers, Generic Glue.
*/
@@ -213,7 +213,7 @@ RTDECL(uint64_t) RTRandAdvU64(RTRAND hRand) RT_NO_THROW
RT_EXPORT_SYMBOL(RTRandAdvU64);
-DECLCALLBACK(void) rtRandAdvSynthesizeBytesFromU32(PRTRANDINT pThis, uint8_t *pb, size_t cb)
+DECLHIDDEN(DECLCALLBACK(void)) rtRandAdvSynthesizeBytesFromU32(PRTRANDINT pThis, uint8_t *pb, size_t cb)
{
while (cb > 0)
{
@@ -245,7 +245,7 @@ DECLCALLBACK(void) rtRandAdvSynthesizeBytesFromU32(PRTRANDINT pThis, uint8_t *p
}
-DECLCALLBACK(void) rtRandAdvSynthesizeBytesFromU64(PRTRANDINT pThis, uint8_t *pb, size_t cb)
+DECLHIDDEN(DECLCALLBACK(void)) rtRandAdvSynthesizeBytesFromU64(PRTRANDINT pThis, uint8_t *pb, size_t cb)
{
while (cb > 0)
{
@@ -289,7 +289,7 @@ DECLCALLBACK(void) rtRandAdvSynthesizeBytesFromU64(PRTRANDINT pThis, uint8_t *p
}
-DECLCALLBACK(uint32_t) rtRandAdvSynthesizeU32FromBytes(PRTRANDINT pThis, uint32_t u32First, uint32_t u32Last)
+DECLHIDDEN(DECLCALLBACK(uint32_t)) rtRandAdvSynthesizeU32FromBytes(PRTRANDINT pThis, uint32_t u32First, uint32_t u32Last)
{
union
{
@@ -323,13 +323,13 @@ DECLCALLBACK(uint32_t) rtRandAdvSynthesizeU32FromBytes(PRTRANDINT pThis, uint32
}
-DECLCALLBACK(uint32_t) rtRandAdvSynthesizeU32FromU64(PRTRANDINT pThis, uint32_t u32First, uint32_t u32Last)
+DECLHIDDEN(DECLCALLBACK(uint32_t)) rtRandAdvSynthesizeU32FromU64(PRTRANDINT pThis, uint32_t u32First, uint32_t u32Last)
{
return (uint32_t)pThis->pfnGetU64(pThis, u32First, u32Last);
}
-DECLCALLBACK(uint64_t) rtRandAdvSynthesizeU64FromBytes(PRTRANDINT pThis, uint64_t u64First, uint64_t u64Last)
+DECLHIDDEN(DECLCALLBACK(uint64_t)) rtRandAdvSynthesizeU64FromBytes(PRTRANDINT pThis, uint64_t u64First, uint64_t u64Last)
{
union
{
@@ -364,7 +364,7 @@ DECLCALLBACK(uint64_t) rtRandAdvSynthesizeU64FromBytes(PRTRANDINT pThis, uint64
}
-DECLCALLBACK(uint64_t) rtRandAdvSynthesizeU64FromU32(PRTRANDINT pThis, uint64_t u64First, uint64_t u64Last)
+DECLHIDDEN(DECLCALLBACK(uint64_t)) rtRandAdvSynthesizeU64FromU32(PRTRANDINT pThis, uint64_t u64First, uint64_t u64Last)
{
uint64_t off = u64Last - u64First;
if (off <= UINT32_MAX)
@@ -377,7 +377,7 @@ DECLCALLBACK(uint64_t) rtRandAdvSynthesizeU64FromU32(PRTRANDINT pThis, uint64_t
/** @copydoc RTRANDINT::pfnSeed */
-DECLCALLBACK(int) rtRandAdvStubSeed(PRTRANDINT pThis, uint64_t u64Seed)
+DECLHIDDEN(DECLCALLBACK(int)) rtRandAdvStubSeed(PRTRANDINT pThis, uint64_t u64Seed)
{
NOREF(pThis);
NOREF(u64Seed);
@@ -386,7 +386,7 @@ DECLCALLBACK(int) rtRandAdvStubSeed(PRTRANDINT pThis, uint64_t u64Seed)
/** @copydoc RTRANDINT::pfnSaveState */
-DECLCALLBACK(int) rtRandAdvStubSaveState(PRTRANDINT pThis, char *pszState, size_t *pcbState)
+DECLHIDDEN(DECLCALLBACK(int)) rtRandAdvStubSaveState(PRTRANDINT pThis, char *pszState, size_t *pcbState)
{
NOREF(pThis);
NOREF(pszState);
@@ -396,7 +396,7 @@ DECLCALLBACK(int) rtRandAdvStubSaveState(PRTRANDINT pThis, char *pszState, size_
/** @copydoc RTRANDINT::pfnRestoreState */
-DECLCALLBACK(int) rtRandAdvStubRestoreState(PRTRANDINT pThis, char const *pszState)
+DECLHIDDEN(DECLCALLBACK(int)) rtRandAdvStubRestoreState(PRTRANDINT pThis, char const *pszState)
{
NOREF(pThis);
NOREF(pszState);
@@ -405,7 +405,7 @@ DECLCALLBACK(int) rtRandAdvStubRestoreState(PRTRANDINT pThis, char const *pszSta
/** @copydoc RTRANDINT::pfnDestroy */
-DECLCALLBACK(int) rtRandAdvDefaultDestroy(PRTRANDINT pThis)
+DECLHIDDEN(DECLCALLBACK(int)) rtRandAdvDefaultDestroy(PRTRANDINT pThis)
{
pThis->u32Magic = ~RTRANDINT_MAGIC;
RTMemFree(pThis);
diff --git a/src/VBox/Runtime/common/rand/randparkmiller.cpp b/src/VBox/Runtime/common/rand/randparkmiller.cpp
index 4c0f3fd1e..94f118cac 100644
--- a/src/VBox/Runtime/common/rand/randparkmiller.cpp
+++ b/src/VBox/Runtime/common/rand/randparkmiller.cpp
@@ -1,4 +1,4 @@
-/* $Id: randparkmiller.cpp $ */
+/* $Id: randparkmiller.cpp 29250 2010-05-09 17:53:58Z vboxsync $ */
/** @file
* IPRT - Random Numbers, Park-Miller Pseudo Random.
*/
diff --git a/src/VBox/Runtime/common/sort/RTSortApvIsSorted.cpp b/src/VBox/Runtime/common/sort/RTSortApvIsSorted.cpp
index ccf4c62a5..f422f839d 100644
--- a/src/VBox/Runtime/common/sort/RTSortApvIsSorted.cpp
+++ b/src/VBox/Runtime/common/sort/RTSortApvIsSorted.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSortApvIsSorted.cpp $ */
+/* $Id: RTSortApvIsSorted.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTSortApvIsSorted.
*/
diff --git a/src/VBox/Runtime/common/sort/RTSortIsSorted.cpp b/src/VBox/Runtime/common/sort/RTSortIsSorted.cpp
index ff066e4e4..15b1e281b 100644
--- a/src/VBox/Runtime/common/sort/RTSortIsSorted.cpp
+++ b/src/VBox/Runtime/common/sort/RTSortIsSorted.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSortIsSorted.cpp $ */
+/* $Id: RTSortIsSorted.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTSortIsSorted.
*/
diff --git a/src/VBox/Runtime/common/sort/shellsort.cpp b/src/VBox/Runtime/common/sort/shellsort.cpp
index 23f956fec..e40728467 100644
--- a/src/VBox/Runtime/common/sort/shellsort.cpp
+++ b/src/VBox/Runtime/common/sort/shellsort.cpp
@@ -1,4 +1,4 @@
-/* $Id: shellsort.cpp $ */
+/* $Id: shellsort.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTSortIsSorted.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrCat.cpp b/src/VBox/Runtime/common/string/RTStrCat.cpp
index b85a8832a..257552fe0 100644
--- a/src/VBox/Runtime/common/string/RTStrCat.cpp
+++ b/src/VBox/Runtime/common/string/RTStrCat.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrCat.cpp $ */
+/* $Id: RTStrCat.cpp 33678 2010-11-02 10:30:46Z vboxsync $ */
/** @file
* IPRT - RTStrCat.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrCatEx.cpp b/src/VBox/Runtime/common/string/RTStrCatEx.cpp
index 69cb92c3f..32f82f1c6 100644
--- a/src/VBox/Runtime/common/string/RTStrCatEx.cpp
+++ b/src/VBox/Runtime/common/string/RTStrCatEx.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrCatEx.cpp $ */
+/* $Id: RTStrCatEx.cpp 33678 2010-11-02 10:30:46Z vboxsync $ */
/** @file
* IPRT - RTStrCatEx
*/
diff --git a/src/VBox/Runtime/common/string/RTStrCatP.cpp b/src/VBox/Runtime/common/string/RTStrCatP.cpp
index 145fb9c2e..c5139ce2a 100644
--- a/src/VBox/Runtime/common/string/RTStrCatP.cpp
+++ b/src/VBox/Runtime/common/string/RTStrCatP.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrCatP.cpp $ */
+/* $Id: RTStrCatP.cpp 36407 2011-03-24 16:14:57Z vboxsync $ */
/** @file
* IPRT - RTStrCat.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrCatPEx.cpp b/src/VBox/Runtime/common/string/RTStrCatPEx.cpp
index 808773ffa..9a31a0889 100644
--- a/src/VBox/Runtime/common/string/RTStrCatPEx.cpp
+++ b/src/VBox/Runtime/common/string/RTStrCatPEx.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrCatPEx.cpp $ */
+/* $Id: RTStrCatPEx.cpp 36407 2011-03-24 16:14:57Z vboxsync $ */
/** @file
* IPRT - RTStrCatPEx
*/
diff --git a/src/VBox/Runtime/common/string/RTStrCmp.cpp b/src/VBox/Runtime/common/string/RTStrCmp.cpp
index 779675f0b..1348da93f 100644
--- a/src/VBox/Runtime/common/string/RTStrCmp.cpp
+++ b/src/VBox/Runtime/common/string/RTStrCmp.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrCmp.cpp $ */
+/* $Id: RTStrCmp.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTStrCmp.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrConvertHexBytes.cpp b/src/VBox/Runtime/common/string/RTStrConvertHexBytes.cpp
index 841ff4436..4e1c3f17c 100644
--- a/src/VBox/Runtime/common/string/RTStrConvertHexBytes.cpp
+++ b/src/VBox/Runtime/common/string/RTStrConvertHexBytes.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrConvertHexBytes.cpp $ */
+/* $Id: RTStrConvertHexBytes.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTStrConvertHexBytes.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrCopy.cpp b/src/VBox/Runtime/common/string/RTStrCopy.cpp
index b8062cedc..51e67b38f 100644
--- a/src/VBox/Runtime/common/string/RTStrCopy.cpp
+++ b/src/VBox/Runtime/common/string/RTStrCopy.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrCopy.cpp $ */
+/* $Id: RTStrCopy.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTStrCopy.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrCopyEx.cpp b/src/VBox/Runtime/common/string/RTStrCopyEx.cpp
index 2baabd189..2074729fe 100644
--- a/src/VBox/Runtime/common/string/RTStrCopyEx.cpp
+++ b/src/VBox/Runtime/common/string/RTStrCopyEx.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrCopyEx.cpp $ */
+/* $Id: RTStrCopyEx.cpp 33678 2010-11-02 10:30:46Z vboxsync $ */
/** @file
* IPRT - RTStrCopyEx.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrCopyP.cpp b/src/VBox/Runtime/common/string/RTStrCopyP.cpp
index 0e6c166a9..3c7bf68a3 100644
--- a/src/VBox/Runtime/common/string/RTStrCopyP.cpp
+++ b/src/VBox/Runtime/common/string/RTStrCopyP.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrCopyP.cpp $ */
+/* $Id: RTStrCopyP.cpp 36407 2011-03-24 16:14:57Z vboxsync $ */
/** @file
* IPRT - RTStrCopyP.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrCopyPEx.cpp b/src/VBox/Runtime/common/string/RTStrCopyPEx.cpp
index 84919a043..7d3b8e7fe 100644
--- a/src/VBox/Runtime/common/string/RTStrCopyPEx.cpp
+++ b/src/VBox/Runtime/common/string/RTStrCopyPEx.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrCopyPEx.cpp $ */
+/* $Id: RTStrCopyPEx.cpp 36407 2011-03-24 16:14:57Z vboxsync $ */
/** @file
* IPRT - RTStrCopyPEx.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrNCmp.cpp b/src/VBox/Runtime/common/string/RTStrNCmp.cpp
index 5070218aa..c1c3583f5 100644
--- a/src/VBox/Runtime/common/string/RTStrNCmp.cpp
+++ b/src/VBox/Runtime/common/string/RTStrNCmp.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrNCmp.cpp $ */
+/* $Id: RTStrNCmp.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTStrNCmp.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrNLen.cpp b/src/VBox/Runtime/common/string/RTStrNLen.cpp
index d30c9ed51..16349edf9 100644
--- a/src/VBox/Runtime/common/string/RTStrNLen.cpp
+++ b/src/VBox/Runtime/common/string/RTStrNLen.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrNLen.cpp $ */
+/* $Id: RTStrNLen.cpp 30320 2010-06-21 08:35:09Z vboxsync $ */
/** @file
* IPRT - RTStrNLen.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrNLenEx.cpp b/src/VBox/Runtime/common/string/RTStrNLenEx.cpp
index 3764ce353..124e96000 100644
--- a/src/VBox/Runtime/common/string/RTStrNLenEx.cpp
+++ b/src/VBox/Runtime/common/string/RTStrNLenEx.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrNLenEx.cpp $ */
+/* $Id: RTStrNLenEx.cpp 30320 2010-06-21 08:35:09Z vboxsync $ */
/** @file
* IPRT - RTStrNLenEx.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrPrintHexBytes.cpp b/src/VBox/Runtime/common/string/RTStrPrintHexBytes.cpp
index f00298e5f..054ac46b3 100644
--- a/src/VBox/Runtime/common/string/RTStrPrintHexBytes.cpp
+++ b/src/VBox/Runtime/common/string/RTStrPrintHexBytes.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrPrintHexBytes.cpp $ */
+/* $Id: RTStrPrintHexBytes.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTStrPrintHexBytes.
*/
diff --git a/src/VBox/Runtime/common/string/RTStrStr.cpp b/src/VBox/Runtime/common/string/RTStrStr.cpp
index 903826e10..300837a00 100644
--- a/src/VBox/Runtime/common/string/RTStrStr.cpp
+++ b/src/VBox/Runtime/common/string/RTStrStr.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTStrStr.cpp $ */
+/* $Id: RTStrStr.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTStrStr.
*/
diff --git a/src/VBox/Runtime/common/string/base64.cpp b/src/VBox/Runtime/common/string/base64.cpp
index 58869fe38..6aab11dae 100644
--- a/src/VBox/Runtime/common/string/base64.cpp
+++ b/src/VBox/Runtime/common/string/base64.cpp
@@ -1,4 +1,4 @@
-/* $Id: base64.cpp $ */
+/* $Id: base64.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Base64, MIME content transfer encoding.
*/
diff --git a/src/VBox/Runtime/common/string/memchr.asm b/src/VBox/Runtime/common/string/memchr.asm
index 0ee2968d5..d8d0e37d7 100644
--- a/src/VBox/Runtime/common/string/memchr.asm
+++ b/src/VBox/Runtime/common/string/memchr.asm
@@ -1,4 +1,4 @@
-; $Id: memchr.asm $
+; $Id: memchr.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT memchr - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/string/memchr.cpp b/src/VBox/Runtime/common/string/memchr.cpp
index ba2de0958..f6cc7ed56 100644
--- a/src/VBox/Runtime/common/string/memchr.cpp
+++ b/src/VBox/Runtime/common/string/memchr.cpp
@@ -1,4 +1,4 @@
-/* $Id: memchr.cpp $ */
+/* $Id: memchr.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - CRT Strings, memcpy().
*/
diff --git a/src/VBox/Runtime/common/string/memchr_alias.c b/src/VBox/Runtime/common/string/memchr_alias.c
index 0d009c7da..f023eac1d 100644
--- a/src/VBox/Runtime/common/string/memchr_alias.c
+++ b/src/VBox/Runtime/common/string/memchr_alias.c
@@ -1,4 +1,4 @@
-/* $Id: memchr_alias.c $ */
+/* $Id: memchr_alias.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - No-CRT memchr() alias for gcc.
*/
diff --git a/src/VBox/Runtime/common/string/memcmp.asm b/src/VBox/Runtime/common/string/memcmp.asm
index afadf923e..f0695aafd 100644
--- a/src/VBox/Runtime/common/string/memcmp.asm
+++ b/src/VBox/Runtime/common/string/memcmp.asm
@@ -1,4 +1,4 @@
-; $Id: memcmp.asm $
+; $Id: memcmp.asm 30255 2010-06-16 14:55:17Z vboxsync $
;; @file
; IPRT - No-CRT memcmp - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/string/memcmp.cpp b/src/VBox/Runtime/common/string/memcmp.cpp
index 3dea769e6..f7a389271 100644
--- a/src/VBox/Runtime/common/string/memcmp.cpp
+++ b/src/VBox/Runtime/common/string/memcmp.cpp
@@ -1,4 +1,4 @@
-/* $Id: memcmp.cpp $ */
+/* $Id: memcmp.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - CRT Strings, memcmp().
*/
diff --git a/src/VBox/Runtime/common/string/memcmp_alias.c b/src/VBox/Runtime/common/string/memcmp_alias.c
index 30f786375..34f15a586 100644
--- a/src/VBox/Runtime/common/string/memcmp_alias.c
+++ b/src/VBox/Runtime/common/string/memcmp_alias.c
@@ -1,4 +1,4 @@
-/* $Id: memcmp_alias.c $ */
+/* $Id: memcmp_alias.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - No-CRT memcmp() alias for gcc.
*/
diff --git a/src/VBox/Runtime/common/string/memcpy.asm b/src/VBox/Runtime/common/string/memcpy.asm
index 6f1bed22a..cda29d223 100644
--- a/src/VBox/Runtime/common/string/memcpy.asm
+++ b/src/VBox/Runtime/common/string/memcpy.asm
@@ -1,4 +1,4 @@
-; $Id: memcpy.asm $
+; $Id: memcpy.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT memcpy - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/string/memcpy.cpp b/src/VBox/Runtime/common/string/memcpy.cpp
index 56ccdfb28..f799113a5 100644
--- a/src/VBox/Runtime/common/string/memcpy.cpp
+++ b/src/VBox/Runtime/common/string/memcpy.cpp
@@ -1,4 +1,4 @@
-/* $Id: memcpy.cpp $ */
+/* $Id: memcpy.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - CRT Strings, memcpy().
*/
diff --git a/src/VBox/Runtime/common/string/memcpy_alias.c b/src/VBox/Runtime/common/string/memcpy_alias.c
index 5ddc7b8c9..1e4998286 100644
--- a/src/VBox/Runtime/common/string/memcpy_alias.c
+++ b/src/VBox/Runtime/common/string/memcpy_alias.c
@@ -1,4 +1,4 @@
-/* $Id: memcpy_alias.c $ */
+/* $Id: memcpy_alias.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - No-CRT memcpy() alias for gcc.
*/
diff --git a/src/VBox/Runtime/common/string/memmove.asm b/src/VBox/Runtime/common/string/memmove.asm
index b10ede777..02d795f35 100644
--- a/src/VBox/Runtime/common/string/memmove.asm
+++ b/src/VBox/Runtime/common/string/memmove.asm
@@ -1,4 +1,4 @@
-; $Id: memmove.asm $
+; $Id: memmove.asm 33540 2010-10-28 09:27:05Z vboxsync $
;; @file
; IPRT - No-CRT memmove - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/string/memmove_alias.c b/src/VBox/Runtime/common/string/memmove_alias.c
index f30c91497..30c62a666 100644
--- a/src/VBox/Runtime/common/string/memmove_alias.c
+++ b/src/VBox/Runtime/common/string/memmove_alias.c
@@ -1,4 +1,4 @@
-/* $Id: memmove_alias.c $ */
+/* $Id: memmove_alias.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - No-CRT memmove() alias for gcc.
*/
diff --git a/src/VBox/Runtime/common/string/mempcpy.asm b/src/VBox/Runtime/common/string/mempcpy.asm
index b47c43682..849e0acf4 100644
--- a/src/VBox/Runtime/common/string/mempcpy.asm
+++ b/src/VBox/Runtime/common/string/mempcpy.asm
@@ -1,4 +1,4 @@
-; $Id: mempcpy.asm $
+; $Id: mempcpy.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT mempcpy - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/string/memset.asm b/src/VBox/Runtime/common/string/memset.asm
index 96cc48ec8..1f39cd282 100644
--- a/src/VBox/Runtime/common/string/memset.asm
+++ b/src/VBox/Runtime/common/string/memset.asm
@@ -1,4 +1,4 @@
-; $Id: memset.asm $
+; $Id: memset.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT memset - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/string/memset.cpp b/src/VBox/Runtime/common/string/memset.cpp
index 9bf358936..c2fda0b1f 100644
--- a/src/VBox/Runtime/common/string/memset.cpp
+++ b/src/VBox/Runtime/common/string/memset.cpp
@@ -1,4 +1,4 @@
-/* $Id: memset.cpp $ */
+/* $Id: memset.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - CRT Strings, memset().
*/
diff --git a/src/VBox/Runtime/common/string/memset_alias.c b/src/VBox/Runtime/common/string/memset_alias.c
index 49d4abd35..4c6bff270 100644
--- a/src/VBox/Runtime/common/string/memset_alias.c
+++ b/src/VBox/Runtime/common/string/memset_alias.c
@@ -1,4 +1,4 @@
-/* $Id: memset_alias.c $ */
+/* $Id: memset_alias.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - No-CRT memset() alias for gcc.
*/
diff --git a/src/VBox/Runtime/common/string/ministring.cpp b/src/VBox/Runtime/common/string/ministring.cpp
index dc4a429ea..3a7f31565 100644
--- a/src/VBox/Runtime/common/string/ministring.cpp
+++ b/src/VBox/Runtime/common/string/ministring.cpp
@@ -1,4 +1,4 @@
-/* $Id: ministring.cpp $ */
+/* $Id: ministring.cpp 36561 2011-04-05 13:42:59Z vboxsync $ */
/** @file
* IPRT - Mini C++ string class.
*
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (C) 2007-2010 Oracle Corporation
+ * Copyright (C) 2007-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;
@@ -32,13 +32,13 @@
* Header Files *
*******************************************************************************/
#include <iprt/cpp/ministring.h>
-using namespace iprt;
/*******************************************************************************
* Global Variables *
*******************************************************************************/
-const size_t MiniString::npos = ~(size_t)0;
+const size_t RTCString::npos = ~(size_t)0;
+
/*******************************************************************************
* Defined Constants And Macros *
@@ -47,7 +47,7 @@ const size_t MiniString::npos = ~(size_t)0;
#define IPRT_MINISTRING_APPEND_ALIGNMENT 64
-MiniString &MiniString::printf(const char *pszFormat, ...)
+RTCString &RTCString::printf(const char *pszFormat, ...)
{
va_list va;
va_start(va, pszFormat);
@@ -57,7 +57,7 @@ MiniString &MiniString::printf(const char *pszFormat, ...)
}
/**
- * Callback used with RTStrFormatV by MiniString::printfV.
+ * Callback used with RTStrFormatV by RTCString::printfV.
*
* @returns The number of bytes added (not used).
*
@@ -66,9 +66,9 @@ MiniString &MiniString::printf(const char *pszFormat, ...)
* @param cbChars The number of characters. 0 on the final callback.
*/
/*static*/ DECLCALLBACK(size_t)
-MiniString::printfOutputCallback(void *pvArg, const char *pachChars, size_t cbChars)
+RTCString::printfOutputCallback(void *pvArg, const char *pachChars, size_t cbChars)
{
- MiniString *pThis = (MiniString *)pvArg;
+ RTCString *pThis = (RTCString *)pvArg;
if (cbChars)
{
size_t cchBoth = pThis->m_cch + cbChars;
@@ -93,14 +93,14 @@ MiniString::printfOutputCallback(void *pvArg, const char *pachChars, size_t cbCh
return cbChars;
}
-MiniString &MiniString::printfV(const char *pszFormat, va_list va)
+RTCString &RTCString::printfV(const char *pszFormat, va_list va)
{
cleanup();
RTStrFormatV(printfOutputCallback, this, NULL, NULL, pszFormat, va);
return *this;
}
-MiniString &MiniString::append(const MiniString &that)
+RTCString &RTCString::append(const RTCString &that)
{
size_t cchThat = that.length();
if (cchThat)
@@ -124,7 +124,7 @@ MiniString &MiniString::append(const MiniString &that)
return *this;
}
-MiniString &MiniString::append(const char *pszThat)
+RTCString &RTCString::append(const char *pszThat)
{
size_t cchThat = strlen(pszThat);
if (cchThat)
@@ -148,7 +148,7 @@ MiniString &MiniString::append(const char *pszThat)
return *this;
}
-MiniString& MiniString::append(char ch)
+RTCString& RTCString::append(char ch)
{
Assert((unsigned char)ch < 0x80); /* Don't create invalid UTF-8. */
if (ch)
@@ -169,13 +169,13 @@ MiniString& MiniString::append(char ch)
return *this;
}
-MiniString &MiniString::appendCodePoint(RTUNICP uc)
+RTCString &RTCString::appendCodePoint(RTUNICP uc)
{
/*
* Single byte encoding.
*/
if (uc < 0x80)
- return MiniString::append((char)uc);
+ return RTCString::append((char)uc);
/*
* Multibyte encoding.
@@ -199,8 +199,7 @@ MiniString &MiniString::appendCodePoint(RTUNICP uc)
return *this;
}
-size_t MiniString::find(const char *pcszFind, size_t pos /*= 0*/)
- const
+size_t RTCString::find(const char *pcszFind, size_t pos /*= 0*/) const
{
const char *pszThis, *p;
@@ -213,7 +212,7 @@ size_t MiniString::find(const char *pcszFind, size_t pos /*= 0*/)
return npos;
}
-void MiniString::findReplace(char cFind, char cReplace)
+void RTCString::findReplace(char cFind, char cReplace)
{
for (size_t i = 0; i < length(); ++i)
{
@@ -223,10 +222,9 @@ void MiniString::findReplace(char cFind, char cReplace)
}
}
-MiniString MiniString::substrCP(size_t pos /*= 0*/, size_t n /*= npos*/)
- const
+RTCString RTCString::substrCP(size_t pos /*= 0*/, size_t n /*= npos*/) const
{
- MiniString ret;
+ RTCString ret;
if (n)
{
@@ -272,7 +270,7 @@ MiniString MiniString::substrCP(size_t pos /*= 0*/, size_t n /*= npos*/)
return ret;
}
-bool MiniString::endsWith(const MiniString &that, CaseSensitivity cs /*= CaseSensitive*/) const
+bool RTCString::endsWith(const RTCString &that, CaseSensitivity cs /*= CaseSensitive*/) const
{
size_t l1 = length();
if (l1 == 0)
@@ -287,11 +285,10 @@ bool MiniString::endsWith(const MiniString &that, CaseSensitivity cs /*= CaseSen
size_t l = l1 - l2;
if (cs == CaseSensitive)
return ::RTStrCmp(&m_psz[l], that.m_psz) == 0;
- else
- return ::RTStrICmp(&m_psz[l], that.m_psz) == 0;
+ return ::RTStrICmp(&m_psz[l], that.m_psz) == 0;
}
-bool MiniString::startsWith(const MiniString &that, CaseSensitivity cs /*= CaseSensitive*/) const
+bool RTCString::startsWith(const RTCString &that, CaseSensitivity cs /*= CaseSensitive*/) const
{
size_t l1 = length();
size_t l2 = that.length();
@@ -303,31 +300,112 @@ bool MiniString::startsWith(const MiniString &that, CaseSensitivity cs /*= CaseS
if (cs == CaseSensitive)
return ::RTStrNCmp(m_psz, that.m_psz, l2) == 0;
- else
- return ::RTStrNICmp(m_psz, that.m_psz, l2) == 0;
+ return ::RTStrNICmp(m_psz, that.m_psz, l2) == 0;
}
-bool MiniString::contains(const MiniString &that, CaseSensitivity cs /*= CaseSensitive*/) const
+bool RTCString::contains(const RTCString &that, CaseSensitivity cs /*= CaseSensitive*/) const
{
/** @todo r-bird: Not checking for NULL strings like startsWith does (and
* endsWith only does half way). */
if (cs == CaseSensitive)
return ::RTStrStr(m_psz, that.m_psz) != NULL;
- else
- return ::RTStrIStr(m_psz, that.m_psz) != NULL;
+ return ::RTStrIStr(m_psz, that.m_psz) != NULL;
}
-int MiniString::toInt(uint64_t &i) const
+int RTCString::toInt(uint64_t &i) const
{
if (!m_psz)
return VERR_NO_DIGITS;
return RTStrToUInt64Ex(m_psz, NULL, 0, &i);
}
-int MiniString::toInt(uint32_t &i) const
+int RTCString::toInt(uint32_t &i) const
{
if (!m_psz)
return VERR_NO_DIGITS;
return RTStrToUInt32Ex(m_psz, NULL, 0, &i);
}
+RTCList<RTCString, RTCString *>
+RTCString::split(const RTCString &a_rstrSep, SplitMode mode /* = RemoveEmptyParts */)
+{
+ RTCList<RTCString> strRet;
+ if (!m_psz)
+ return strRet;
+ if (a_rstrSep.isEmpty())
+ {
+ strRet.append(RTCString(m_psz));
+ return strRet;
+ }
+
+ size_t cch = m_cch;
+ char const *pszTmp = m_psz;
+ while (cch > 0)
+ {
+ char const *pszNext = strstr(pszTmp, a_rstrSep.c_str());
+ if (!pszNext)
+ {
+ strRet.append(RTCString(pszTmp, cch));
+ break;
+ }
+ size_t cchNext = pszNext - pszTmp;
+ if ( cchNext > 0
+ || mode == KeepEmptyParts)
+ strRet.append(RTCString(pszTmp, cchNext));
+ pszTmp += cchNext + a_rstrSep.length();
+ cch -= cchNext + a_rstrSep.length();
+ }
+
+ return strRet;
+}
+
+/* static */
+RTCString
+RTCString::join(const RTCList<RTCString, RTCString *> &a_rList,
+ const RTCString &a_rstrSep /* = "" */)
+{
+ RTCString strRet;
+ if (a_rList.size() > 1)
+ {
+ /* calc the required size */
+ size_t cbNeeded = a_rstrSep.length() * (a_rList.size() - 1) + 1;
+ for (size_t i = 0; i < a_rList.size(); ++i)
+ cbNeeded += a_rList.at(i).length();
+ strRet.reserve(cbNeeded);
+
+ /* do the appending. */
+ for (size_t i = 0; i < a_rList.size() - 1; ++i)
+ {
+ strRet.append(a_rList.at(i));
+ strRet.append(a_rstrSep);
+ }
+ strRet.append(a_rList.last());
+ }
+ /* special case: one list item. */
+ else if (a_rList.size() > 0)
+ strRet.append(a_rList.last());
+
+ return strRet;
+}
+
+const RTCString operator+(const RTCString &a_rStr1, const RTCString &a_rStr2)
+{
+ RTCString strRet(a_rStr1);
+ strRet += a_rStr2;
+ return strRet;
+}
+
+const RTCString operator+(const RTCString &a_rStr1, const char *a_pszStr2)
+{
+ RTCString strRet(a_rStr1);
+ strRet += a_pszStr2;
+ return strRet;
+}
+
+const RTCString operator+(const char *a_psz1, const RTCString &a_rStr2)
+{
+ RTCString strRet(a_psz1);
+ strRet += a_rStr2;
+ return strRet;
+}
+
diff --git a/src/VBox/Runtime/common/string/simplepattern.cpp b/src/VBox/Runtime/common/string/simplepattern.cpp
index f54d4ce02..607984fd6 100644
--- a/src/VBox/Runtime/common/string/simplepattern.cpp
+++ b/src/VBox/Runtime/common/string/simplepattern.cpp
@@ -1,4 +1,4 @@
-/* $Id: simplepattern.cpp $ */
+/* $Id: simplepattern.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - RTStrSimplePattern.
*/
diff --git a/src/VBox/Runtime/common/string/straprintf.cpp b/src/VBox/Runtime/common/string/straprintf.cpp
index a0ee03502..2df24c9bd 100644
--- a/src/VBox/Runtime/common/string/straprintf.cpp
+++ b/src/VBox/Runtime/common/string/straprintf.cpp
@@ -1,4 +1,4 @@
-/* $Id: straprintf.cpp $ */
+/* $Id: straprintf.cpp 33464 2010-10-26 12:27:50Z vboxsync $ */
/** @file
* IPRT - Allocating String Formatters.
*/
diff --git a/src/VBox/Runtime/common/string/strcache.cpp b/src/VBox/Runtime/common/string/strcache.cpp
index 642d5836d..480a8b37b 100644
--- a/src/VBox/Runtime/common/string/strcache.cpp
+++ b/src/VBox/Runtime/common/string/strcache.cpp
@@ -1,4 +1,4 @@
-/* $Id: strcache.cpp $ */
+/* $Id: strcache.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - String Cache.
*/
diff --git a/src/VBox/Runtime/common/string/strchr.asm b/src/VBox/Runtime/common/string/strchr.asm
index 7163f28c5..55ac28e44 100644
--- a/src/VBox/Runtime/common/string/strchr.asm
+++ b/src/VBox/Runtime/common/string/strchr.asm
@@ -1,4 +1,4 @@
-; $Id: strchr.asm $
+; $Id: strchr.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT strchr - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/string/strchr_alias.c b/src/VBox/Runtime/common/string/strchr_alias.c
index 4b4fe4b10..b0c5ba97a 100644
--- a/src/VBox/Runtime/common/string/strchr_alias.c
+++ b/src/VBox/Runtime/common/string/strchr_alias.c
@@ -1,4 +1,4 @@
-/* $Id: strchr_alias.c $ */
+/* $Id: strchr_alias.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - No-CRT strchr() alias for gcc.
*/
diff --git a/src/VBox/Runtime/common/string/strcmp.asm b/src/VBox/Runtime/common/string/strcmp.asm
index 574e5d140..261cabdd4 100644
--- a/src/VBox/Runtime/common/string/strcmp.asm
+++ b/src/VBox/Runtime/common/string/strcmp.asm
@@ -1,4 +1,4 @@
-; $Id: strcmp.asm $
+; $Id: strcmp.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT strcmp - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/string/strcmp_alias.c b/src/VBox/Runtime/common/string/strcmp_alias.c
index 3c5f7f839..d69b7130d 100644
--- a/src/VBox/Runtime/common/string/strcmp_alias.c
+++ b/src/VBox/Runtime/common/string/strcmp_alias.c
@@ -1,4 +1,4 @@
-/* $Id: strcmp_alias.c $ */
+/* $Id: strcmp_alias.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - No-CRT strcmp() alias for gcc.
*/
diff --git a/src/VBox/Runtime/common/string/strcpy.asm b/src/VBox/Runtime/common/string/strcpy.asm
index bee8738ba..0c9e53377 100644
--- a/src/VBox/Runtime/common/string/strcpy.asm
+++ b/src/VBox/Runtime/common/string/strcpy.asm
@@ -1,4 +1,4 @@
-; $Id: strcpy.asm $
+; $Id: strcpy.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT strcpy - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/string/strcpy.cpp b/src/VBox/Runtime/common/string/strcpy.cpp
index 55da775db..6c67ab319 100644
--- a/src/VBox/Runtime/common/string/strcpy.cpp
+++ b/src/VBox/Runtime/common/string/strcpy.cpp
@@ -1,4 +1,4 @@
-/* $Id: strcpy.cpp $ */
+/* $Id: strcpy.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - CRT Strings, strcpy().
*/
diff --git a/src/VBox/Runtime/common/string/strcpy_alias.c b/src/VBox/Runtime/common/string/strcpy_alias.c
index 517cd801a..096f240a1 100644
--- a/src/VBox/Runtime/common/string/strcpy_alias.c
+++ b/src/VBox/Runtime/common/string/strcpy_alias.c
@@ -1,4 +1,4 @@
-/* $Id: strcpy_alias.c $ */
+/* $Id: strcpy_alias.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - No-CRT strcpy() alias for gcc.
*/
diff --git a/src/VBox/Runtime/common/string/strformat.cpp b/src/VBox/Runtime/common/string/strformat.cpp
index fec8315ec..d6058e6c0 100644
--- a/src/VBox/Runtime/common/string/strformat.cpp
+++ b/src/VBox/Runtime/common/string/strformat.cpp
@@ -1,4 +1,4 @@
-/* $Id: strformat.cpp $ */
+/* $Id: strformat.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - String Formatter.
*/
diff --git a/src/VBox/Runtime/common/string/strformatnum.cpp b/src/VBox/Runtime/common/string/strformatnum.cpp
index db4a810c7..171cd1918 100644
--- a/src/VBox/Runtime/common/string/strformatnum.cpp
+++ b/src/VBox/Runtime/common/string/strformatnum.cpp
@@ -1,4 +1,4 @@
-/* $Id: strformatnum.cpp $ */
+/* $Id: strformatnum.cpp 35585 2011-01-17 14:20:13Z vboxsync $ */
/** @file
* IPRT - String Formatter, Single Numbers.
*/
diff --git a/src/VBox/Runtime/common/string/strformatrt.cpp b/src/VBox/Runtime/common/string/strformatrt.cpp
index b37710bbc..d2409c457 100644
--- a/src/VBox/Runtime/common/string/strformatrt.cpp
+++ b/src/VBox/Runtime/common/string/strformatrt.cpp
@@ -1,4 +1,4 @@
-/* $Id: strformatrt.cpp $ */
+/* $Id: strformatrt.cpp 37996 2011-07-18 10:09:19Z vboxsync $ */
/** @file
* IPRT - IPRT String Formatter Extensions.
*/
@@ -30,6 +30,8 @@
*******************************************************************************/
#define LOG_GROUP RTLOGGROUP_STRING
#include <iprt/string.h>
+#define RT_NO_EXPORT_SYMBOL /* don't slurp <linux/module.h> which then again
+ slurps arch-specific headers defining symbols */
#include "internal/iprt.h"
#include <iprt/log.h>
@@ -44,6 +46,10 @@
#include <iprt/time.h>
#include <iprt/net.h>
#include <iprt/path.h>
+#define STRFORMAT_WITH_X86
+#ifdef STRFORMAT_WITH_X86
+# include <iprt/x86.h>
+#endif
#include "internal/string.h"
@@ -63,10 +69,14 @@
* @param fFlags Flags (RTSTR_NTFS_*).
* @param chArgSize The argument size specifier, 'l' or 'L'.
*/
-size_t rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs, int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize)
+DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs,
+ int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize)
{
const char *pszFormatOrg = *ppszFormat;
- char ch = *(*ppszFormat)++;
+ char ch = *(*ppszFormat)++;
+ size_t cch;
+ char szBuf[80];
+
if (ch == 'R')
{
ch = *(*ppszFormat)++;
@@ -204,8 +214,6 @@ size_t rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **p
PCRTNETADDR pNetAddr;
PCRTUUID pUuid;
} u;
- char szBuf[80];
- unsigned cch;
AssertMsg(!chArgSize, ("Not argument size '%c' for RT types! '%.10s'\n", chArgSize, pszFormatOrg));
@@ -644,8 +652,8 @@ size_t rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **p
*/
case 'd':
{
- size_t cch = 0;
int off = 0;
+ cch = 0;
if (cchWidth <= 0)
cchWidth = 16;
@@ -682,7 +690,7 @@ size_t rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **p
{
if (cchPrecision-- > 0)
{
- size_t cch = RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%02x", *pu8++);
+ cch = RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%02x", *pu8++);
for (; cchPrecision > 0; cchPrecision--, pu8++)
cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, " %02x", *pu8);
return cch;
@@ -984,6 +992,124 @@ size_t rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **p
}
#endif /* IN_RING3 */
+
+ /*
+ * Groups 6 - CPU Architecture Register Formatters.
+ * "%RAarch[reg]"
+ */
+ case 'A':
+ {
+ char const * const pszArch = *ppszFormat;
+ const char *pszReg = pszArch;
+ size_t cchOutput = 0;
+ int cPrinted = 0;
+ size_t cchReg;
+
+ /* Parse out the */
+ while ((ch = *pszReg++) && ch != '[')
+ { /* nothing */ }
+ AssertMsgBreak(ch == '[', ("Malformed IPRT architecture register format type '%.10s'!\n", pszFormatOrg));
+
+ cchReg = 0;
+ while ((ch = pszReg[cchReg]) && ch != ']')
+ cchReg++;
+ AssertMsgBreak(ch == ']', ("Malformed IPRT architecture register format type '%.10s'!\n", pszFormatOrg));
+
+ *ppszFormat = &pszReg[cchReg + 1];
+
+
+#define REG_EQUALS(a_szReg) (sizeof(a_szReg) - 1 == cchReg && !strncmp(a_szReg, pszReg, sizeof(a_szReg) - 1))
+#define REG_OUT_BIT(a_uVal, a_fBitMask, a_szName) \
+ do { \
+ if ((a_uVal) & (a_fBitMask)) \
+ { \
+ if (!cPrinted++) \
+ cchOutput += pfnOutput(pvArgOutput, "{" a_szName, sizeof(a_szName)); \
+ else \
+ cchOutput += pfnOutput(pvArgOutput, "," a_szName, sizeof(a_szName)); \
+ (a_uVal) &= ~(a_fBitMask); \
+ } \
+ } while (0)
+#define REG_OUT_CLOSE(a_uVal) \
+ do { \
+ if ((a_uVal)) \
+ { \
+ cchOutput += pfnOutput(pvArgOutput, !cPrinted ? "{unkn=" : ",unkn=", 6); \
+ cch = RTStrFormatNumber(&szBuf[0], (a_uVal), 16, 1, -1, fFlags); \
+ cchOutput += pfnOutput(pvArgOutput, szBuf, cch); \
+ cPrinted++; \
+ } \
+ if (cPrinted) \
+ cchOutput += pfnOutput(pvArgOutput, "}", 1); \
+ } while (0)
+
+
+ if (0)
+ { /* dummy */ }
+#ifdef STRFORMAT_WITH_X86
+ /*
+ * X86 & AMD64.
+ */
+ else if ( pszReg - pszArch == 3 + 1
+ && pszArch[0] == 'x'
+ && pszArch[1] == '8'
+ && pszArch[2] == '6')
+ {
+ if (REG_EQUALS("cr0"))
+ {
+ uint64_t cr0 = va_arg(*pArgs, uint64_t);
+ fFlags |= RTSTR_F_64BIT;
+ cch = RTStrFormatNumber(&szBuf[0], cr0, 16, 8, -1, fFlags | RTSTR_F_ZEROPAD);
+ cchOutput += pfnOutput(pvArgOutput, szBuf, cch);
+ REG_OUT_BIT(cr0, X86_CR0_PE, "PE");
+ REG_OUT_BIT(cr0, X86_CR0_MP, "MP");
+ REG_OUT_BIT(cr0, X86_CR0_EM, "EM");
+ REG_OUT_BIT(cr0, X86_CR0_TS, "DE");
+ REG_OUT_BIT(cr0, X86_CR0_ET, "ET");
+ REG_OUT_BIT(cr0, X86_CR0_NE, "NE");
+ REG_OUT_BIT(cr0, X86_CR0_WP, "WP");
+ REG_OUT_BIT(cr0, X86_CR0_AM, "AM");
+ REG_OUT_BIT(cr0, X86_CR0_NW, "NW");
+ REG_OUT_BIT(cr0, X86_CR0_CD, "CD");
+ REG_OUT_BIT(cr0, X86_CR0_PG, "PG");
+ REG_OUT_CLOSE(cr0);
+ }
+ else if (REG_EQUALS("cr4"))
+ {
+ uint64_t cr4 = va_arg(*pArgs, uint64_t);
+ fFlags |= RTSTR_F_64BIT;
+ cch = RTStrFormatNumber(&szBuf[0], cr4, 16, 8, -1, fFlags | RTSTR_F_ZEROPAD);
+ cchOutput += pfnOutput(pvArgOutput, szBuf, cch);
+ REG_OUT_BIT(cr4, X86_CR4_VME, "VME");
+ REG_OUT_BIT(cr4, X86_CR4_PVI, "PVI");
+ REG_OUT_BIT(cr4, X86_CR4_TSD, "TSD");
+ REG_OUT_BIT(cr4, X86_CR4_DE, "DE");
+ REG_OUT_BIT(cr4, X86_CR4_PSE, "PSE");
+ REG_OUT_BIT(cr4, X86_CR4_PAE, "PAE");
+ REG_OUT_BIT(cr4, X86_CR4_MCE, "MCE");
+ REG_OUT_BIT(cr4, X86_CR4_PGE, "PGE");
+ REG_OUT_BIT(cr4, X86_CR4_PCE, "PCE");
+ REG_OUT_BIT(cr4, X86_CR4_OSFSXR, "OSFSXR");
+ REG_OUT_BIT(cr4, X86_CR4_OSXMMEEXCPT, "OSXMMEEXCPT");
+ REG_OUT_BIT(cr4, X86_CR4_VMXE, "VMXE");
+ REG_OUT_BIT(cr4, X86_CR4_SMXE, "SMXE");
+ REG_OUT_BIT(cr4, X86_CR4_PCIDE, "PCIDE");
+ REG_OUT_BIT(cr4, X86_CR4_OSXSAVE, "OSXSAVE");
+ REG_OUT_BIT(cr4, X86_CR4_SMEP, "SMPE");
+ REG_OUT_CLOSE(cr4);
+ }
+ else
+ AssertMsgFailed(("Unknown x86 register specified in '%.10s'!\n", pszFormatOrg));
+ }
+#endif
+ else
+ AssertMsgFailed(("Unknown architecture specified in '%.10s'!\n", pszFormatOrg));
+#undef REG_OUT_BIT
+#undef REG_OUT_CLOSE
+#undef REG_EQUALS
+ return cchOutput;
+ }
+
/*
* Invalid/Unknown. Bitch about it.
*/
diff --git a/src/VBox/Runtime/common/string/strformattype.cpp b/src/VBox/Runtime/common/string/strformattype.cpp
index aca496fec..2bd99d91f 100644
--- a/src/VBox/Runtime/common/string/strformattype.cpp
+++ b/src/VBox/Runtime/common/string/strformattype.cpp
@@ -1,4 +1,4 @@
-/* $Id: strformattype.cpp $ */
+/* $Id: strformattype.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - IPRT String Formatter Extensions, Dynamic Types.
*/
@@ -415,7 +415,8 @@ RT_EXPORT_SYMBOL(RTStrFormatTypeSetUser);
* @param fFlags Flags (RTSTR_NTFS_*).
* @param chArgSize The argument size specifier, 'l' or 'L'.
*/
-size_t rtstrFormatType(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs, int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize)
+DECLHIDDEN(size_t) rtstrFormatType(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat,
+ va_list *pArgs, int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize)
{
size_t cch;
int32_t i;
diff --git a/src/VBox/Runtime/common/string/stringalloc.cpp b/src/VBox/Runtime/common/string/stringalloc.cpp
index f5d4ec087..06afd0c55 100644
--- a/src/VBox/Runtime/common/string/stringalloc.cpp
+++ b/src/VBox/Runtime/common/string/stringalloc.cpp
@@ -1,4 +1,4 @@
-/* $Id: stringalloc.cpp $ */
+/* $Id: stringalloc.cpp 34032 2010-11-12 16:20:25Z vboxsync $ */
/** @file
* IPRT - String Manipulation.
*/
diff --git a/src/VBox/Runtime/common/string/strlen.asm b/src/VBox/Runtime/common/string/strlen.asm
index e3ff2f378..90418f5af 100644
--- a/src/VBox/Runtime/common/string/strlen.asm
+++ b/src/VBox/Runtime/common/string/strlen.asm
@@ -1,4 +1,4 @@
-; $Id: strlen.asm $
+; $Id: strlen.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - No-CRT strlen - AMD64 & X86.
;
diff --git a/src/VBox/Runtime/common/string/strlen.cpp b/src/VBox/Runtime/common/string/strlen.cpp
index 173ba2cbc..377ef64ee 100644
--- a/src/VBox/Runtime/common/string/strlen.cpp
+++ b/src/VBox/Runtime/common/string/strlen.cpp
@@ -1,4 +1,4 @@
-/* $Id: strlen.cpp $ */
+/* $Id: strlen.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - CRT Strings, strlen().
*/
diff --git a/src/VBox/Runtime/common/string/strlen_alias.c b/src/VBox/Runtime/common/string/strlen_alias.c
index 8fab3d167..a89c778ae 100644
--- a/src/VBox/Runtime/common/string/strlen_alias.c
+++ b/src/VBox/Runtime/common/string/strlen_alias.c
@@ -1,4 +1,4 @@
-/* $Id: strlen_alias.c $ */
+/* $Id: strlen_alias.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - No-CRT strlen() alias for gcc.
*/
diff --git a/src/VBox/Runtime/common/string/strncmp.cpp b/src/VBox/Runtime/common/string/strncmp.cpp
index 16faf4b1b..37f81e565 100644
--- a/src/VBox/Runtime/common/string/strncmp.cpp
+++ b/src/VBox/Runtime/common/string/strncmp.cpp
@@ -1,4 +1,4 @@
-/* $Id: strncmp.cpp $ */
+/* $Id: strncmp.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - CRT Strings, strncmp().
*/
diff --git a/src/VBox/Runtime/common/string/strpbrk.cpp b/src/VBox/Runtime/common/string/strpbrk.cpp
index e8d49a811..0f2c64b84 100644
--- a/src/VBox/Runtime/common/string/strpbrk.cpp
+++ b/src/VBox/Runtime/common/string/strpbrk.cpp
@@ -1,4 +1,4 @@
-/* $Id: strpbrk.cpp $ */
+/* $Id: strpbrk.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - strpbrk().
*/
diff --git a/src/VBox/Runtime/common/string/strprintf.cpp b/src/VBox/Runtime/common/string/strprintf.cpp
index 13bfd4b7a..40e589f7b 100644
--- a/src/VBox/Runtime/common/string/strprintf.cpp
+++ b/src/VBox/Runtime/common/string/strprintf.cpp
@@ -1,4 +1,4 @@
-/* $Id: strprintf.cpp $ */
+/* $Id: strprintf.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - String Formatters.
*/
diff --git a/src/VBox/Runtime/common/string/strspace.cpp b/src/VBox/Runtime/common/string/strspace.cpp
index 561db74c3..1c8b4655f 100644
--- a/src/VBox/Runtime/common/string/strspace.cpp
+++ b/src/VBox/Runtime/common/string/strspace.cpp
@@ -1,4 +1,4 @@
-/* $Id: strspace.cpp $ */
+/* $Id: strspace.cpp 36597 2011-04-06 19:46:15Z vboxsync $ */
/** @file
* IPRT - Unique String Spaces.
*/
@@ -32,6 +32,7 @@
#include "internal/iprt.h"
#include <iprt/assert.h>
+#include "internal/strhash.h"
/*******************************************************************************
@@ -40,6 +41,7 @@
/*
* AVL configuration.
*/
+#define KAVL_DECL(a_Type) static a_Type
#define KAVL_FN(a) rtstrspace##a
#define KAVL_MAX_STACK 27 /* Up to 2^24 nodes. */
#define KAVL_EQUAL_ALLOWED 1
@@ -72,44 +74,6 @@
-/* sdbm:
- This algorithm was created for sdbm (a public-domain reimplementation of
- ndbm) database library. it was found to do well in scrambling bits,
- causing better distribution of the keys and fewer splits. it also happens
- to be a good general hashing function with good distribution. the actual
- function is hash(i) = hash(i - 1) * 65599 + str[i]; what is included below
- is the faster version used in gawk. [there is even a faster, duff-device
- version] the magic constant 65599 was picked out of thin air while
- experimenting with different constants, and turns out to be a prime.
- this is one of the algorithms used in berkeley db (see sleepycat) and
- elsewhere. */
-DECLINLINE(uint32_t) sdbm(const char *str, size_t *pcch)
-{
- uint8_t *pu8 = (uint8_t *)str;
- uint32_t hash = 0;
- int c;
-
- while ((c = *pu8++))
- hash = c + (hash << 6) + (hash << 16) - hash;
-
- *pcch = (uintptr_t)pu8 - (uintptr_t)str - 1;
- return hash;
-}
-
-DECLINLINE(uint32_t) sdbmN(const char *str, size_t cchMax, size_t *pcch)
-{
- uint8_t *pu8 = (uint8_t *)str;
- uint32_t hash = 0;
- int c;
-
- while ((c = *pu8++) && cchMax-- > 0)
- hash = c + (hash << 6) + (hash << 16) - hash;
-
- *pcch = (uintptr_t)pu8 - (uintptr_t)str - 1;
- return hash;
-}
-
-
/**
* Inserts a string into a unique string space.
*
diff --git a/src/VBox/Runtime/common/string/strstrip.cpp b/src/VBox/Runtime/common/string/strstrip.cpp
index 3f1b28096..909faebe5 100644
--- a/src/VBox/Runtime/common/string/strstrip.cpp
+++ b/src/VBox/Runtime/common/string/strstrip.cpp
@@ -1,4 +1,4 @@
-/* $Id: strstrip.cpp $ */
+/* $Id: strstrip.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - String Stripping and Trimming.
*/
diff --git a/src/VBox/Runtime/common/string/strtonum.cpp b/src/VBox/Runtime/common/string/strtonum.cpp
index 60285fd06..2c96e3db3 100644
--- a/src/VBox/Runtime/common/string/strtonum.cpp
+++ b/src/VBox/Runtime/common/string/strtonum.cpp
@@ -1,4 +1,4 @@
-/* $Id: strtonum.cpp $ */
+/* $Id: strtonum.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - String To Number Conversion.
*/
diff --git a/src/VBox/Runtime/common/string/strversion.cpp b/src/VBox/Runtime/common/string/strversion.cpp
index 7a93bc8d6..bab3a4c20 100644
--- a/src/VBox/Runtime/common/string/strversion.cpp
+++ b/src/VBox/Runtime/common/string/strversion.cpp
@@ -1,4 +1,4 @@
-/* $Id: strversion.cpp $ */
+/* $Id: strversion.cpp 35076 2010-12-14 13:31:41Z vboxsync $ */
/** @file
* IPRT - Version String Parsing.
*/
diff --git a/src/VBox/Runtime/common/string/uni.cpp b/src/VBox/Runtime/common/string/uni.cpp
index 1fe613ecb..1f84b533f 100644
--- a/src/VBox/Runtime/common/string/uni.cpp
+++ b/src/VBox/Runtime/common/string/uni.cpp
@@ -1,4 +1,4 @@
-/* $Id: uni.cpp $ */
+/* $Id: uni.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Unicode.
*/
diff --git a/src/VBox/Runtime/common/string/unidata.cpp b/src/VBox/Runtime/common/string/unidata.cpp
index ea5ce4edc..914a3f3f6 100644
--- a/src/VBox/Runtime/common/string/unidata.cpp
+++ b/src/VBox/Runtime/common/string/unidata.cpp
@@ -1,4 +1,4 @@
-/* $Id: unidata.cpp $ */
+/* $Id: unidata.cpp 33560 2010-10-28 14:25:30Z vboxsync $ */
/** @file
* IPRT - Unicode Tables
*
diff --git a/src/VBox/Runtime/common/string/uniread.cpp b/src/VBox/Runtime/common/string/uniread.cpp
index 6b7fd3bcf..02719fa5e 100644
--- a/src/VBox/Runtime/common/string/uniread.cpp
+++ b/src/VBox/Runtime/common/string/uniread.cpp
@@ -1,4 +1,4 @@
-/* $Id: uniread.cpp $ */
+/* $Id: uniread.cpp 33560 2010-10-28 14:25:30Z vboxsync $ */
/** @file
* IPRT - Unicode Specification Reader.
*/
diff --git a/src/VBox/Runtime/common/string/utf-16.cpp b/src/VBox/Runtime/common/string/utf-16.cpp
index f24e95b74..bf9d3cb3e 100644
--- a/src/VBox/Runtime/common/string/utf-16.cpp
+++ b/src/VBox/Runtime/common/string/utf-16.cpp
@@ -1,4 +1,4 @@
-/* $Id: utf-16.cpp $ */
+/* $Id: utf-16.cpp 31157 2010-07-28 03:15:35Z vboxsync $ */
/** @file
* IPRT - UTF-16.
*/
diff --git a/src/VBox/Runtime/common/string/utf-8-case.cpp b/src/VBox/Runtime/common/string/utf-8-case.cpp
index 7a0bf2ebb..71ea836d2 100644
--- a/src/VBox/Runtime/common/string/utf-8-case.cpp
+++ b/src/VBox/Runtime/common/string/utf-8-case.cpp
@@ -1,4 +1,4 @@
-/* $Id: utf-8-case.cpp $ */
+/* $Id: utf-8-case.cpp 33562 2010-10-28 14:38:50Z vboxsync $ */
/** @file
* IPRT - UTF-8 Case Sensitivity and Folding.
*/
diff --git a/src/VBox/Runtime/common/string/utf-8.cpp b/src/VBox/Runtime/common/string/utf-8.cpp
index 7f95ca999..537e45c66 100644
--- a/src/VBox/Runtime/common/string/utf-8.cpp
+++ b/src/VBox/Runtime/common/string/utf-8.cpp
@@ -1,4 +1,4 @@
-/* $Id: utf-8.cpp $ */
+/* $Id: utf-8.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - UTF-8 Decoding.
*/
@@ -51,7 +51,7 @@
* @param pcchActual Where to store the actual size of the UTF-8 string
* on success (cch = cb again). Optional.
*/
-int rtUtf8Length(const char *psz, size_t cch, size_t *pcuc, size_t *pcchActual)
+DECLHIDDEN(int) rtUtf8Length(const char *psz, size_t cch, size_t *pcuc, size_t *pcchActual)
{
const unsigned char *puch = (const unsigned char *)psz;
size_t cCodePoints = 0;
diff --git a/src/VBox/Runtime/common/table/avl_Base.cpp.h b/src/VBox/Runtime/common/table/avl_Base.cpp.h
index ff69772f1..1c9f0aa36 100644
--- a/src/VBox/Runtime/common/table/avl_Base.cpp.h
+++ b/src/VBox/Runtime/common/table/avl_Base.cpp.h
@@ -1,4 +1,4 @@
-/* $Id: avl_Base.cpp.h $ */
+/* $Id: avl_Base.cpp.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* kAVLBase - basic routines for all AVL trees.
*/
@@ -126,6 +126,12 @@
# define KAVL_R_IS_IDENTICAL(key1B, key2B, key1E, key2E) KAVL_E(key1B, key2B)
#endif
+/** @def KAVL_DECL
+ * Function declation macro in the RTDECL tradition.
+ * @param a_Type The function return type. */
+#ifndef KAVL_DECL
+# define KAVL_DECL(a_Type) RTDECL(a_Type)
+#endif
/*******************************************************************************
@@ -290,15 +296,15 @@ DECLINLINE(void) KAVL_FN(Rebalance)(PKAVLSTACK pStack)
* Fill in leaf node and insert it.
* Rebalance the tree.
*/
-RTDECL(bool) KAVL_FN(Insert)(PPKAVLNODECORE ppTree, PKAVLNODECORE pNode)
+KAVL_DECL(bool) KAVL_FN(Insert)(PPKAVLNODECORE ppTree, PKAVLNODECORE pNode)
{
KAVLSTACK AVLStack;
PPKAVLNODECORE ppCurNode = ppTree;
+ register PKAVLNODECORE pCurNode;
register KAVLKEY Key = pNode->Key; NOREF(Key);
#ifdef KAVL_RANGE
register KAVLKEY KeyLast = pNode->KeyLast; NOREF(KeyLast);
#endif
- register PKAVLNODECORE pCurNode;
AVLStack.cEntries = 0;
@@ -390,7 +396,7 @@ RTDECL(bool) KAVL_FN(Insert)(PPKAVLNODECORE ppTree, PKAVLNODECORE pNode)
* END
* return pointer to the removed node (if found).
*/
-RTDECL(PKAVLNODECORE) KAVL_FN(Remove)(PPKAVLNODECORE ppTree, KAVLKEY Key)
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(Remove)(PPKAVLNODECORE ppTree, KAVLKEY Key)
{
KAVLSTACK AVLStack;
PPKAVLNODECORE ppDeleteNode = ppTree;
diff --git a/src/VBox/Runtime/common/table/avl_Destroy.cpp.h b/src/VBox/Runtime/common/table/avl_Destroy.cpp.h
index 0794d4aa1..9b255ca17 100644
--- a/src/VBox/Runtime/common/table/avl_Destroy.cpp.h
+++ b/src/VBox/Runtime/common/table/avl_Destroy.cpp.h
@@ -1,4 +1,4 @@
-/* $Id: avl_Destroy.cpp.h $ */
+/* $Id: avl_Destroy.cpp.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* kAVLDestroy - Walk the tree calling a callback to destroy all the nodes.
*/
@@ -40,7 +40,7 @@
* @param pfnCallBack Pointer to callback function.
* @param pvUser User parameter passed on to the callback function.
*/
-RTDECL(int) KAVL_FN(Destroy)(PPKAVLNODECORE ppTree, PKAVLCALLBACK pfnCallBack, void *pvUser)
+KAVL_DECL(int) KAVL_FN(Destroy)(PPKAVLNODECORE ppTree, PKAVLCALLBACK pfnCallBack, void *pvUser)
{
unsigned cEntries;
PKAVLNODECORE apEntries[KAVL_MAX_STACK];
diff --git a/src/VBox/Runtime/common/table/avl_DoWithAll.cpp.h b/src/VBox/Runtime/common/table/avl_DoWithAll.cpp.h
index ffc5ef582..233936803 100644
--- a/src/VBox/Runtime/common/table/avl_DoWithAll.cpp.h
+++ b/src/VBox/Runtime/common/table/avl_DoWithAll.cpp.h
@@ -1,4 +1,4 @@
-/* $Id: avl_DoWithAll.cpp.h $ */
+/* $Id: avl_DoWithAll.cpp.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* kAVLDoWithAll - Do with all nodes routine for AVL trees.
*/
@@ -37,7 +37,7 @@
* @param pfnCallBack Pointer to callback function.
* @param pvParam Userparameter passed on to the callback function.
*/
-RTDECL(int) KAVL_FN(DoWithAll)(PPKAVLNODECORE ppTree, int fFromLeft, PKAVLCALLBACK pfnCallBack, void * pvParam)
+KAVL_DECL(int) KAVL_FN(DoWithAll)(PPKAVLNODECORE ppTree, int fFromLeft, PKAVLCALLBACK pfnCallBack, void * pvParam)
{
KAVLSTACK2 AVLStack;
PKAVLNODECORE pNode;
diff --git a/src/VBox/Runtime/common/table/avl_Enum.cpp.h b/src/VBox/Runtime/common/table/avl_Enum.cpp.h
index b9a73092c..d29387bb8 100644
--- a/src/VBox/Runtime/common/table/avl_Enum.cpp.h
+++ b/src/VBox/Runtime/common/table/avl_Enum.cpp.h
@@ -1,4 +1,4 @@
-/* $Id: avl_Enum.cpp.h $ */
+/* $Id: avl_Enum.cpp.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* Enumeration routines for AVL trees.
*/
@@ -36,7 +36,7 @@
*
* @param ppTree Pointer to pointer to the tree root node.
*/
-RTDECL(PKAVLNODECORE) KAVL_FN(GetRoot)(PPKAVLNODECORE ppTree)
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(GetRoot)(PPKAVLNODECORE ppTree)
{
return KAVL_GET_POINTER_NULL(ppTree);
}
@@ -50,7 +50,7 @@ RTDECL(PKAVLNODECORE) KAVL_FN(GetRoot)(PPKAVLNODECORE ppTree)
*
* @param pNode The current node.
*/
-RTDECL(PKAVLNODECORE) KAVL_FN(GetRight)(PKAVLNODECORE pNode)
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(GetRight)(PKAVLNODECORE pNode)
{
if (pNode)
return KAVL_GET_POINTER_NULL(&pNode->pRight);
@@ -66,7 +66,7 @@ RTDECL(PKAVLNODECORE) KAVL_FN(GetRight)(PKAVLNODECORE pNode)
*
* @param pNode The current node.
*/
-RTDECL(PKAVLNODECORE) KAVL_FN(GetLeft)(PKAVLNODECORE pNode)
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(GetLeft)(PKAVLNODECORE pNode)
{
if (pNode)
return KAVL_GET_POINTER_NULL(&pNode->pLeft);
@@ -83,7 +83,7 @@ RTDECL(PKAVLNODECORE) KAVL_FN(GetLeft)(PKAVLNODECORE pNode)
*
* @param pNode The current node.
*/
-RTDECL(PKAVLNODECORE) KAVL_FN(GetNextEqual)(PKAVLNODECORE pNode)
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(GetNextEqual)(PKAVLNODECORE pNode)
{
if (pNode)
return KAVL_GET_POINTER_NULL(&pNode->pList);
diff --git a/src/VBox/Runtime/common/table/avl_Get.cpp.h b/src/VBox/Runtime/common/table/avl_Get.cpp.h
index ea8b66be0..3bb16a1ed 100644
--- a/src/VBox/Runtime/common/table/avl_Get.cpp.h
+++ b/src/VBox/Runtime/common/table/avl_Get.cpp.h
@@ -1,4 +1,4 @@
-/* $Id: avl_Get.cpp.h $ */
+/* $Id: avl_Get.cpp.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* kAVLGet - get routine for AVL trees.
*/
@@ -35,7 +35,7 @@
* @param Key Key value of the node which is to be found.
* @author knut st. osmundsen
*/
-RTDECL(PKAVLNODECORE) KAVL_FN(Get)(PPKAVLNODECORE ppTree, KAVLKEY Key)
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(Get)(PPKAVLNODECORE ppTree, KAVLKEY Key)
{
register PKAVLNODECORE pNode = KAVL_GET_POINTER_NULL(ppTree);
diff --git a/src/VBox/Runtime/common/table/avl_GetBestFit.cpp.h b/src/VBox/Runtime/common/table/avl_GetBestFit.cpp.h
index 10fba6627..4b6ceb72d 100644
--- a/src/VBox/Runtime/common/table/avl_GetBestFit.cpp.h
+++ b/src/VBox/Runtime/common/table/avl_GetBestFit.cpp.h
@@ -1,4 +1,4 @@
-/* $Id: avl_GetBestFit.cpp.h $ */
+/* $Id: avl_GetBestFit.cpp.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* kAVLGetBestFit - Get Best Fit routine for AVL trees.
* Intended specially on heaps. The tree should allow duplicate keys.
@@ -41,7 +41,7 @@
* >= (above): The node where you last turned left.
* <= (below): the node where you last turned right.
*/
-RTDECL(PKAVLNODECORE) KAVL_FN(GetBestFit)(PPKAVLNODECORE ppTree, KAVLKEY Key, bool fAbove)
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(GetBestFit)(PPKAVLNODECORE ppTree, KAVLKEY Key, bool fAbove)
{
register PKAVLNODECORE pNode = KAVL_GET_POINTER_NULL(ppTree);
if (pNode)
diff --git a/src/VBox/Runtime/common/table/avl_Range.cpp.h b/src/VBox/Runtime/common/table/avl_Range.cpp.h
index dcdffea31..fc658838c 100644
--- a/src/VBox/Runtime/common/table/avl_Range.cpp.h
+++ b/src/VBox/Runtime/common/table/avl_Range.cpp.h
@@ -1,4 +1,4 @@
-/* $Id: avl_Range.cpp.h $ */
+/* $Id: avl_Range.cpp.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* kAVLRange - Range routines for AVL trees.
*/
@@ -35,7 +35,7 @@
* @param ppTree Pointer to Pointer to the tree root node.
* @param Key The Key to find matching range for.
*/
-RTDECL(PKAVLNODECORE) KAVL_FN(RangeGet)(PPKAVLNODECORE ppTree, register KAVLKEY Key)
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(RangeGet)(PPKAVLNODECORE ppTree, register KAVLKEY Key)
{
register PKAVLNODECORE pNode = KAVL_GET_POINTER_NULL(ppTree);
if (pNode)
diff --git a/src/VBox/Runtime/common/table/avl_RemoveBestFit.cpp.h b/src/VBox/Runtime/common/table/avl_RemoveBestFit.cpp.h
index 26d5a470f..30e11c15c 100644
--- a/src/VBox/Runtime/common/table/avl_RemoveBestFit.cpp.h
+++ b/src/VBox/Runtime/common/table/avl_RemoveBestFit.cpp.h
@@ -1,4 +1,4 @@
-/* $Id: avl_RemoveBestFit.cpp.h $ */
+/* $Id: avl_RemoveBestFit.cpp.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* kAVLRemoveBestFit - Remove Best Fit routine for AVL trees.
* Intended specially on heaps. The tree should allow duplicate keys.
@@ -43,7 +43,7 @@
* <= (below): the node where you last turned right.
* @remark This implementation should be speeded up slightly!
*/
-RTDECL(PKAVLNODECORE) KAVL_FN(RemoveBestFit)(PPKAVLNODECORE ppTree, KAVLKEY Key, bool fAbove)
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(RemoveBestFit)(PPKAVLNODECORE ppTree, KAVLKEY Key, bool fAbove)
{
/*
* If we find anything we'll have to remove the node and return it.
diff --git a/src/VBox/Runtime/common/table/avlgcphys.cpp b/src/VBox/Runtime/common/table/avlgcphys.cpp
index 7f8566b12..c4f258165 100644
--- a/src/VBox/Runtime/common/table/avlgcphys.cpp
+++ b/src/VBox/Runtime/common/table/avlgcphys.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlgcphys.cpp $ */
+/* $Id: avlgcphys.cpp 32284 2010-09-07 12:29:14Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTGCPHYS, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/avlgcptr.cpp b/src/VBox/Runtime/common/table/avlgcptr.cpp
index 426668609..f1e184493 100644
--- a/src/VBox/Runtime/common/table/avlgcptr.cpp
+++ b/src/VBox/Runtime/common/table/avlgcptr.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlgcptr.cpp $ */
+/* $Id: avlgcptr.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTGCPTR, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/avlhcphys.cpp b/src/VBox/Runtime/common/table/avlhcphys.cpp
index 499c55534..f41088b52 100644
--- a/src/VBox/Runtime/common/table/avlhcphys.cpp
+++ b/src/VBox/Runtime/common/table/avlhcphys.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlhcphys.cpp $ */
+/* $Id: avlhcphys.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTHCPHYS, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/avllu32.cpp b/src/VBox/Runtime/common/table/avllu32.cpp
index 587a5feb3..afc7a8fbf 100644
--- a/src/VBox/Runtime/common/table/avllu32.cpp
+++ b/src/VBox/Runtime/common/table/avllu32.cpp
@@ -1,4 +1,4 @@
-/* $Id: avllu32.cpp $ */
+/* $Id: avllu32.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, uint32_t, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/avlogcphys.cpp b/src/VBox/Runtime/common/table/avlogcphys.cpp
index 01cb5f0ef..fc83a1fbb 100644
--- a/src/VBox/Runtime/common/table/avlogcphys.cpp
+++ b/src/VBox/Runtime/common/table/avlogcphys.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlogcphys.cpp $ */
+/* $Id: avlogcphys.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTGCPHYS, unique keys, offset pointers.
*/
diff --git a/src/VBox/Runtime/common/table/avlogcptr.cpp b/src/VBox/Runtime/common/table/avlogcptr.cpp
index 6602c3097..27f7c5b5f 100644
--- a/src/VBox/Runtime/common/table/avlogcptr.cpp
+++ b/src/VBox/Runtime/common/table/avlogcptr.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlogcptr.cpp $ */
+/* $Id: avlogcptr.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTGCPTR, unique keys, offset pointers.
*/
diff --git a/src/VBox/Runtime/common/table/avlohcphys.cpp b/src/VBox/Runtime/common/table/avlohcphys.cpp
index 9f6dabae7..d3c273553 100644
--- a/src/VBox/Runtime/common/table/avlohcphys.cpp
+++ b/src/VBox/Runtime/common/table/avlohcphys.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlohcphys.cpp $ */
+/* $Id: avlohcphys.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTHCPHYS, unique keys, offset pointers.
*/
diff --git a/src/VBox/Runtime/common/table/avloioport.cpp b/src/VBox/Runtime/common/table/avloioport.cpp
index 38aa69066..4ff60d870 100644
--- a/src/VBox/Runtime/common/table/avloioport.cpp
+++ b/src/VBox/Runtime/common/table/avloioport.cpp
@@ -1,4 +1,4 @@
-/* $Id: avloioport.cpp $ */
+/* $Id: avloioport.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTIOPORT, unique keys, offset pointers.
*/
diff --git a/src/VBox/Runtime/common/table/avlou32.cpp b/src/VBox/Runtime/common/table/avlou32.cpp
index c01cafa1e..3882a5d0d 100644
--- a/src/VBox/Runtime/common/table/avlou32.cpp
+++ b/src/VBox/Runtime/common/table/avlou32.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlou32.cpp $ */
+/* $Id: avlou32.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, uint_32, unique keys, offset pointers.
*/
diff --git a/src/VBox/Runtime/common/table/avlpv.cpp b/src/VBox/Runtime/common/table/avlpv.cpp
index c30680700..a5f82b9d3 100644
--- a/src/VBox/Runtime/common/table/avlpv.cpp
+++ b/src/VBox/Runtime/common/table/avlpv.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlpv.cpp $ */
+/* $Id: avlpv.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, void *, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/avlrfoff.cpp b/src/VBox/Runtime/common/table/avlrfoff.cpp
index dd6391b62..7c9da3b87 100644
--- a/src/VBox/Runtime/common/table/avlrfoff.cpp
+++ b/src/VBox/Runtime/common/table/avlrfoff.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlrfoff.cpp $ */
+/* $Id: avlrfoff.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTFOFF, range, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/avlrgcptr.cpp b/src/VBox/Runtime/common/table/avlrgcptr.cpp
index 4ea64fd2d..aa1c8b380 100644
--- a/src/VBox/Runtime/common/table/avlrgcptr.cpp
+++ b/src/VBox/Runtime/common/table/avlrgcptr.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlrgcptr.cpp $ */
+/* $Id: avlrgcptr.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTGCPTR, range, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/avlrogcphys.cpp b/src/VBox/Runtime/common/table/avlrogcphys.cpp
index f52acdbb2..eb19638e3 100644
--- a/src/VBox/Runtime/common/table/avlrogcphys.cpp
+++ b/src/VBox/Runtime/common/table/avlrogcphys.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlrogcphys.cpp $ */
+/* $Id: avlrogcphys.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTGCPHYS, range, unique keys, offset pointers.
*/
diff --git a/src/VBox/Runtime/common/table/avlrogcptr.cpp b/src/VBox/Runtime/common/table/avlrogcptr.cpp
index 2f4559473..783923815 100644
--- a/src/VBox/Runtime/common/table/avlrogcptr.cpp
+++ b/src/VBox/Runtime/common/table/avlrogcptr.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlrogcptr.cpp $ */
+/* $Id: avlrogcptr.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTGCPTR, range, unique keys, offset pointers.
*/
diff --git a/src/VBox/Runtime/common/table/avlroioport.cpp b/src/VBox/Runtime/common/table/avlroioport.cpp
index 9aa583411..b07e035c6 100644
--- a/src/VBox/Runtime/common/table/avlroioport.cpp
+++ b/src/VBox/Runtime/common/table/avlroioport.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlroioport.cpp $ */
+/* $Id: avlroioport.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTIOPORT, range, unique keys, offset pointers.
*/
diff --git a/src/VBox/Runtime/common/table/avlroogcptr.cpp b/src/VBox/Runtime/common/table/avlroogcptr.cpp
index 6c425d5b5..8b449f6a8 100644
--- a/src/VBox/Runtime/common/table/avlroogcptr.cpp
+++ b/src/VBox/Runtime/common/table/avlroogcptr.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlroogcptr.cpp $ */
+/* $Id: avlroogcptr.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTGCPTR, range, unique keys, overlapping ranges, offset pointers.
*/
diff --git a/src/VBox/Runtime/common/table/avlrpv.cpp b/src/VBox/Runtime/common/table/avlrpv.cpp
index f7e00339f..817dd3822 100644
--- a/src/VBox/Runtime/common/table/avlrpv.cpp
+++ b/src/VBox/Runtime/common/table/avlrpv.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlrpv.cpp $ */
+/* $Id: avlrpv.cpp 33268 2010-10-20 15:37:15Z vboxsync $ */
/** @file
* IPRT - AVL tree, void *, range, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/avlru64.cpp b/src/VBox/Runtime/common/table/avlru64.cpp
index a7476ea5d..b562e9466 100644
--- a/src/VBox/Runtime/common/table/avlru64.cpp
+++ b/src/VBox/Runtime/common/table/avlru64.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlru64.cpp $ */
+/* $Id: avlru64.cpp 34218 2010-11-21 17:00:38Z vboxsync $ */
/** @file
* IPRT - AVL tree, void *, range, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/avlruintptr.cpp b/src/VBox/Runtime/common/table/avlruintptr.cpp
index c267284a9..b9b8bc2cb 100644
--- a/src/VBox/Runtime/common/table/avlruintptr.cpp
+++ b/src/VBox/Runtime/common/table/avlruintptr.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlruintptr.cpp $ */
+/* $Id: avlruintptr.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTUINTPTR, range, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/avlu32.cpp b/src/VBox/Runtime/common/table/avlu32.cpp
index 3bf1283b5..63420e65d 100644
--- a/src/VBox/Runtime/common/table/avlu32.cpp
+++ b/src/VBox/Runtime/common/table/avlu32.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlu32.cpp $ */
+/* $Id: avlu32.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, uint32_t, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/avluintptr.cpp b/src/VBox/Runtime/common/table/avluintptr.cpp
index 08d3eb455..96e2b56a3 100644
--- a/src/VBox/Runtime/common/table/avluintptr.cpp
+++ b/src/VBox/Runtime/common/table/avluintptr.cpp
@@ -1,4 +1,4 @@
-/* $Id: avluintptr.cpp $ */
+/* $Id: avluintptr.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTUINTPTR, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/avlul.cpp b/src/VBox/Runtime/common/table/avlul.cpp
index 62b94f97e..644c23d58 100644
--- a/src/VBox/Runtime/common/table/avlul.cpp
+++ b/src/VBox/Runtime/common/table/avlul.cpp
@@ -1,4 +1,4 @@
-/* $Id: avlul.cpp $ */
+/* $Id: avlul.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, unsigned long, unique keys.
*/
diff --git a/src/VBox/Runtime/common/table/table.cpp b/src/VBox/Runtime/common/table/table.cpp
index b2d7c8b03..a649cb395 100644
--- a/src/VBox/Runtime/common/table/table.cpp
+++ b/src/VBox/Runtime/common/table/table.cpp
@@ -1,4 +1,4 @@
-/* $Id: table.cpp $ */
+/* $Id: table.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - AVL tree, RTHCPHYS, unique keys.
*/
diff --git a/src/VBox/Runtime/common/time/time.cpp b/src/VBox/Runtime/common/time/time.cpp
index 6a04c4216..3a4e7b6bc 100644
--- a/src/VBox/Runtime/common/time/time.cpp
+++ b/src/VBox/Runtime/common/time/time.cpp
@@ -1,4 +1,4 @@
-/* $Id: time.cpp $ */
+/* $Id: time.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Time.
*/
@@ -419,7 +419,7 @@ RT_EXPORT_SYMBOL(RTTimeImplode);
* Internal worker for RTTimeNormalize and RTTimeLocalNormalize.
* It doesn't adjust the UCT offset but leaves that for RTTimeLocalNormalize.
*/
-PRTTIME rtTimeNormalizeInternal(PRTTIME pTime)
+static PRTTIME rtTimeNormalizeInternal(PRTTIME pTime)
{
unsigned uSecond;
unsigned uMinute;
diff --git a/src/VBox/Runtime/common/time/timeprog.cpp b/src/VBox/Runtime/common/time/timeprog.cpp
index 61571d534..c6bdd2380 100644
--- a/src/VBox/Runtime/common/time/timeprog.cpp
+++ b/src/VBox/Runtime/common/time/timeprog.cpp
@@ -1,4 +1,4 @@
-/* $Id: timeprog.cpp $ */
+/* $Id: timeprog.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Time Relative to Program Start.
*/
diff --git a/src/VBox/Runtime/common/time/timesup.cpp b/src/VBox/Runtime/common/time/timesup.cpp
index 197294462..90d659ab7 100644
--- a/src/VBox/Runtime/common/time/timesup.cpp
+++ b/src/VBox/Runtime/common/time/timesup.cpp
@@ -1,4 +1,4 @@
-/* $Id: timesup.cpp $ */
+/* $Id: timesup.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* IPRT - Time using SUPLib.
*/
@@ -38,8 +38,8 @@
#if !defined(IN_GUEST) && !defined(RT_NO_GIP)
# include <iprt/asm.h>
# include <iprt/asm-amd64-x86.h>
+# include <iprt/x86.h>
# include <VBox/sup.h>
-# include <VBox/x86.h>
#endif
#include "internal/time.h"
diff --git a/src/VBox/Runtime/common/time/timesupA.asm b/src/VBox/Runtime/common/time/timesupA.asm
index 9c0449304..c5360fb2e 100644
--- a/src/VBox/Runtime/common/time/timesupA.asm
+++ b/src/VBox/Runtime/common/time/timesupA.asm
@@ -1,4 +1,4 @@
-; $Id: timesupA.asm $
+; $Id: timesupA.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; IPRT - Time using SUPLib, the Assembly Implementation.
;
diff --git a/src/VBox/Runtime/common/time/timesupA.mac b/src/VBox/Runtime/common/time/timesupA.mac
index b146c5a6e..2fc22038c 100644
--- a/src/VBox/Runtime/common/time/timesupA.mac
+++ b/src/VBox/Runtime/common/time/timesupA.mac
@@ -1,4 +1,4 @@
-; $Id: timesupA.mac $
+; $Id: timesupA.mac 36262 2011-03-11 14:50:45Z vboxsync $
;; @file
; IPRT - Time using SUPLib, the Assembly Code Template.
;
diff --git a/src/VBox/Runtime/common/time/timesupref.cpp b/src/VBox/Runtime/common/time/timesupref.cpp
index 12c9bb350..04f68f259 100644
--- a/src/VBox/Runtime/common/time/timesupref.cpp
+++ b/src/VBox/Runtime/common/time/timesupref.cpp
@@ -1,4 +1,4 @@
-/* $Id: timesupref.cpp $ */
+/* $Id: timesupref.cpp 29267 2010-05-09 21:21:36Z vboxsync $ */
/** @file
* IPRT - Time using SUPLib, the C Implementation.
*/
diff --git a/src/VBox/Runtime/common/time/timesupref.h b/src/VBox/Runtime/common/time/timesupref.h
index e7b345132..8aa2beac4 100644
--- a/src/VBox/Runtime/common/time/timesupref.h
+++ b/src/VBox/Runtime/common/time/timesupref.h
@@ -1,4 +1,4 @@
-/* $Id: timesupref.h $ */
+/* $Id: timesupref.h 36262 2011-03-11 14:50:45Z vboxsync $ */
/** @file
* IPRT - Time using SUPLib, the C Code Template.
*/
diff --git a/src/VBox/Runtime/common/time/timesysalias.cpp b/src/VBox/Runtime/common/time/timesysalias.cpp
index 37f65d392..c3f91dcf8 100644
--- a/src/VBox/Runtime/common/time/timesysalias.cpp
+++ b/src/VBox/Runtime/common/time/timesysalias.cpp
@@ -1,4 +1,4 @@
-/* $Id: timesysalias.cpp $ */
+/* $Id: timesysalias.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Time using RTTimeSystem*.
*/
diff --git a/src/VBox/Runtime/common/vfs/vfsbase.cpp b/src/VBox/Runtime/common/vfs/vfsbase.cpp
index cc8cf3198..9c0abf5c5 100644
--- a/src/VBox/Runtime/common/vfs/vfsbase.cpp
+++ b/src/VBox/Runtime/common/vfs/vfsbase.cpp
@@ -1,4 +1,4 @@
-/* $Id: vfsbase.cpp $ */
+/* $Id: vfsbase.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - Virtual File System, Base.
*/
@@ -2297,7 +2297,7 @@ RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fO
}
-RTDECL(int) RTVfsFileOpen(RTVFS hVfs, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile)
+RTDECL(int) RTVfsFileOpen(RTVFS hVfs, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile)
{
/*
* Validate input.
diff --git a/src/VBox/Runtime/common/vfs/vfschain.cpp b/src/VBox/Runtime/common/vfs/vfschain.cpp
index 1a7b37e20..1afbbad91 100644
--- a/src/VBox/Runtime/common/vfs/vfschain.cpp
+++ b/src/VBox/Runtime/common/vfs/vfschain.cpp
@@ -1,4 +1,4 @@
-/* $Id: vfschain.cpp $ */
+/* $Id: vfschain.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - Virtual File System, Chains.
*/
@@ -562,7 +562,7 @@ RTDECL(int) RTVfsChainElementDeregisterProvider(PRTVFSCHAINELEMENTREG pRegRec, b
}
-RTDECL(int) RTVfsChainOpenFile(const char *pszSpec, uint32_t fOpen, PRTVFSFILE phVfsFile, const char **ppszError)
+RTDECL(int) RTVfsChainOpenFile(const char *pszSpec, uint64_t fOpen, PRTVFSFILE phVfsFile, const char **ppszError)
{
AssertPtrReturn(pszSpec, VERR_INVALID_POINTER);
AssertReturn(*pszSpec != '\0', VERR_INVALID_PARAMETER);
@@ -609,7 +609,7 @@ RTDECL(int) RTVfsChainOpenFile(const char *pszSpec, uint32_t fOpen, PRTVFSFILE p
}
-RTDECL(int) RTVfsChainOpenIoStream(const char *pszSpec, uint32_t fOpen, PRTVFSIOSTREAM phVfsIos, const char **ppszError)
+RTDECL(int) RTVfsChainOpenIoStream(const char *pszSpec, uint64_t fOpen, PRTVFSIOSTREAM phVfsIos, const char **ppszError)
{
AssertPtrReturn(pszSpec, VERR_INVALID_POINTER);
AssertReturn(*pszSpec != '\0', VERR_INVALID_PARAMETER);
diff --git a/src/VBox/Runtime/common/vfs/vfsiosmisc.cpp b/src/VBox/Runtime/common/vfs/vfsiosmisc.cpp
index fb9043c09..f7d88c154 100644
--- a/src/VBox/Runtime/common/vfs/vfsiosmisc.cpp
+++ b/src/VBox/Runtime/common/vfs/vfsiosmisc.cpp
@@ -1,4 +1,4 @@
-/* $Id: vfsiosmisc.cpp $ */
+/* $Id: vfsiosmisc.cpp 34967 2010-12-10 17:52:01Z vboxsync $ */
/** @file
* IPRT - Virtual File System, Misc I/O Stream Operations.
*/
diff --git a/src/VBox/Runtime/common/vfs/vfsmemory.cpp b/src/VBox/Runtime/common/vfs/vfsmemory.cpp
index 05b410c4f..82333fbce 100644
--- a/src/VBox/Runtime/common/vfs/vfsmemory.cpp
+++ b/src/VBox/Runtime/common/vfs/vfsmemory.cpp
@@ -1,4 +1,4 @@
-/* $Id: vfsmemory.cpp $ */
+/* $Id: vfsmemory.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Virtual File System, Memory Backed VFS.
*/
@@ -694,7 +694,7 @@ static DECLCALLBACK(int) rtVfsMemFile_QuerySize(void *pvThis, uint64_t *pcbFile)
/**
* Standard file operations.
*/
-DECLHIDDEN(const RTVFSFILEOPS) g_rtVfsStdFileOps =
+DECL_HIDDEN_CONST(const RTVFSFILEOPS) g_rtVfsStdFileOps =
{
{ /* Stream */
{ /* Obj */
diff --git a/src/VBox/Runtime/common/vfs/vfsmisc.cpp b/src/VBox/Runtime/common/vfs/vfsmisc.cpp
index 7fee96945..b50b7c590 100644
--- a/src/VBox/Runtime/common/vfs/vfsmisc.cpp
+++ b/src/VBox/Runtime/common/vfs/vfsmisc.cpp
@@ -1,4 +1,4 @@
-/* $Id: vfsmisc.cpp $ */
+/* $Id: vfsmisc.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - Virtual File System, Misc functions with heavy dependencies.
*/
@@ -38,7 +38,7 @@
-RTDECL(int) RTVfsIoStrmFromStdHandle(RTHANDLESTD enmStdHandle, uint32_t fOpen, bool fLeaveOpen,
+RTDECL(int) RTVfsIoStrmFromStdHandle(RTHANDLESTD enmStdHandle, uint64_t fOpen, bool fLeaveOpen,
PRTVFSIOSTREAM phVfsIos)
{
/*
diff --git a/src/VBox/Runtime/common/vfs/vfsstdfile.cpp b/src/VBox/Runtime/common/vfs/vfsstdfile.cpp
index 29afc485c..070b96d4c 100644
--- a/src/VBox/Runtime/common/vfs/vfsstdfile.cpp
+++ b/src/VBox/Runtime/common/vfs/vfsstdfile.cpp
@@ -1,4 +1,4 @@
-/* $Id: vfsstdfile.cpp $ */
+/* $Id: vfsstdfile.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - Virtual File System, Standard File Implementation.
*/
@@ -380,7 +380,7 @@ static DECLCALLBACK(int) rtVfsStdFile_QuerySize(void *pvThis, uint64_t *pcbFile)
/**
* Standard file operations.
*/
-DECLHIDDEN(const RTVFSFILEOPS) g_rtVfsStdFileOps =
+DECL_HIDDEN_CONST(const RTVFSFILEOPS) g_rtVfsStdFileOps =
{
{ /* Stream */
{ /* Obj */
@@ -418,7 +418,7 @@ DECLHIDDEN(const RTVFSFILEOPS) g_rtVfsStdFileOps =
};
-RTDECL(int) RTVfsFileFromRTFile(RTFILE hFile, uint32_t fOpen, bool fLeaveOpen, PRTVFSFILE phVfsFile)
+RTDECL(int) RTVfsFileFromRTFile(RTFILE hFile, uint64_t fOpen, bool fLeaveOpen, PRTVFSFILE phVfsFile)
{
/*
* Check the handle validity.
@@ -450,7 +450,7 @@ RTDECL(int) RTVfsFileFromRTFile(RTFILE hFile, uint32_t fOpen, bool fLeaveOpen, P
}
-RTDECL(int) RTVfsIoStrmFromRTFile(RTFILE hFile, uint32_t fOpen, bool fLeaveOpen, PRTVFSIOSTREAM phVfsIos)
+RTDECL(int) RTVfsIoStrmFromRTFile(RTFILE hFile, uint64_t fOpen, bool fLeaveOpen, PRTVFSIOSTREAM phVfsIos)
{
RTVFSFILE hVfsFile;
int rc = RTVfsFileFromRTFile(hFile, fOpen, fLeaveOpen, &hVfsFile);
diff --git a/src/VBox/Runtime/common/zip/gzipvfs.cpp b/src/VBox/Runtime/common/zip/gzipvfs.cpp
index e680fae0e..33cb16f0b 100644
--- a/src/VBox/Runtime/common/zip/gzipvfs.cpp
+++ b/src/VBox/Runtime/common/zip/gzipvfs.cpp
@@ -1,4 +1,4 @@
-/* $Id: gzipvfs.cpp $ */
+/* $Id: gzipvfs.cpp 34049 2010-11-13 01:31:07Z vboxsync $ */
/** @file
* IPRT - GZIP Compressor and Decompressor I/O Stream.
*/
diff --git a/src/VBox/Runtime/common/zip/tar.cpp b/src/VBox/Runtime/common/zip/tar.cpp
index 9e1a351f4..d59dcb963 100644
--- a/src/VBox/Runtime/common/zip/tar.cpp
+++ b/src/VBox/Runtime/common/zip/tar.cpp
@@ -1,4 +1,4 @@
-/* $Id: tar.cpp $ */
+/* $Id: tar.cpp 35351 2010-12-27 17:04:17Z vboxsync $ */
/** @file
* IPRT - Tar archive I/O.
*/
diff --git a/src/VBox/Runtime/common/zip/tar.h b/src/VBox/Runtime/common/zip/tar.h
index 4e1be2586..3876300b8 100644
--- a/src/VBox/Runtime/common/zip/tar.h
+++ b/src/VBox/Runtime/common/zip/tar.h
@@ -1,4 +1,4 @@
-/* $Id: tar.h $ */
+/* $Id: tar.h 34179 2010-11-18 15:49:17Z vboxsync $ */
/** @file
* IPRT - TAR Virtual Filesystem.
*/
diff --git a/src/VBox/Runtime/common/zip/tarcmd.cpp b/src/VBox/Runtime/common/zip/tarcmd.cpp
index 6e7f84a99..45a104731 100644
--- a/src/VBox/Runtime/common/zip/tarcmd.cpp
+++ b/src/VBox/Runtime/common/zip/tarcmd.cpp
@@ -1,4 +1,4 @@
-/* $Id: tarcmd.cpp $ */
+/* $Id: tarcmd.cpp 35351 2010-12-27 17:04:17Z vboxsync $ */
/** @file
* IPRT - TAR Command.
*/
diff --git a/src/VBox/Runtime/common/zip/tarvfs.cpp b/src/VBox/Runtime/common/zip/tarvfs.cpp
index ccff3b208..26a350a45 100644
--- a/src/VBox/Runtime/common/zip/tarvfs.cpp
+++ b/src/VBox/Runtime/common/zip/tarvfs.cpp
@@ -1,4 +1,4 @@
-/* $Id: tarvfs.cpp $ */
+/* $Id: tarvfs.cpp 34928 2010-12-09 22:54:17Z vboxsync $ */
/** @file
* IPRT - TAR Virtual Filesystem.
*/
diff --git a/src/VBox/Runtime/common/zip/zip.cpp b/src/VBox/Runtime/common/zip/zip.cpp
index dde89825d..7b9d34acb 100644
--- a/src/VBox/Runtime/common/zip/zip.cpp
+++ b/src/VBox/Runtime/common/zip/zip.cpp
@@ -1,4 +1,4 @@
-/* $Id: zip.cpp $ */
+/* $Id: zip.cpp 33982 2010-11-11 12:37:18Z vboxsync $ */
/** @file
* IPRT - Compression.
*/
diff --git a/src/VBox/Runtime/darwin/RTErrConvertFromDarwin.cpp b/src/VBox/Runtime/darwin/RTErrConvertFromDarwin.cpp
index 082edf8bb..ae3de0b8d 100644
--- a/src/VBox/Runtime/darwin/RTErrConvertFromDarwin.cpp
+++ b/src/VBox/Runtime/darwin/RTErrConvertFromDarwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTErrConvertFromDarwin.cpp $ */
+/* $Id: RTErrConvertFromDarwin.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Convert Darwin Mach returns codes to iprt status codes.
*/
diff --git a/src/VBox/Runtime/darwin/RTErrConvertFromDarwinCOM.cpp b/src/VBox/Runtime/darwin/RTErrConvertFromDarwinCOM.cpp
index 19663e7d5..5a2828cfd 100644
--- a/src/VBox/Runtime/darwin/RTErrConvertFromDarwinCOM.cpp
+++ b/src/VBox/Runtime/darwin/RTErrConvertFromDarwinCOM.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTErrConvertFromDarwinCOM.cpp $ */
+/* $Id: RTErrConvertFromDarwinCOM.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Convert Darwin COM returns codes to iprt status codes.
*/
diff --git a/src/VBox/Runtime/darwin/RTErrConvertFromDarwinIO.cpp b/src/VBox/Runtime/darwin/RTErrConvertFromDarwinIO.cpp
index 2bf4fe7da..f5d14bd1e 100644
--- a/src/VBox/Runtime/darwin/RTErrConvertFromDarwinIO.cpp
+++ b/src/VBox/Runtime/darwin/RTErrConvertFromDarwinIO.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTErrConvertFromDarwinIO.cpp $ */
+/* $Id: RTErrConvertFromDarwinIO.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Convert Darwin IOKit returns codes to iprt status codes.
*/
diff --git a/src/VBox/Runtime/darwin/RTErrConvertFromDarwinKern.cpp b/src/VBox/Runtime/darwin/RTErrConvertFromDarwinKern.cpp
index caeceb245..48d3fc1c2 100644
--- a/src/VBox/Runtime/darwin/RTErrConvertFromDarwinKern.cpp
+++ b/src/VBox/Runtime/darwin/RTErrConvertFromDarwinKern.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTErrConvertFromDarwinKern.cpp $ */
+/* $Id: RTErrConvertFromDarwinKern.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Convert Darwin Mach returns codes to iprt status codes.
*/
diff --git a/src/VBox/Runtime/gc/initterm-gc.cpp b/src/VBox/Runtime/gc/initterm-gc.cpp
index b35ca578b..4210e5049 100644
--- a/src/VBox/Runtime/gc/initterm-gc.cpp
+++ b/src/VBox/Runtime/gc/initterm-gc.cpp
@@ -1,4 +1,4 @@
-/* $Id: initterm-gc.cpp $ */
+/* $Id: initterm-gc.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Init Raw-mode Context.
*/
diff --git a/src/VBox/Runtime/generic/RTAssertShouldPanic-generic.cpp b/src/VBox/Runtime/generic/RTAssertShouldPanic-generic.cpp
index 52ea2eef2..b5d54e39e 100644
--- a/src/VBox/Runtime/generic/RTAssertShouldPanic-generic.cpp
+++ b/src/VBox/Runtime/generic/RTAssertShouldPanic-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTAssertShouldPanic-generic.cpp $ */
+/* $Id: RTAssertShouldPanic-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Assertions, generic RTAssertShouldPanic.
*/
diff --git a/src/VBox/Runtime/generic/RTDirCreateTemp-generic.cpp b/src/VBox/Runtime/generic/RTDirCreateTemp-generic.cpp
index 82214b4fe..afb9aea46 100644
--- a/src/VBox/Runtime/generic/RTDirCreateTemp-generic.cpp
+++ b/src/VBox/Runtime/generic/RTDirCreateTemp-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTDirCreateTemp-generic.cpp $ */
+/* $Id: RTDirCreateTemp-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTDirCreateTemp, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTDirCreateUniqueNumbered-generic.cpp b/src/VBox/Runtime/generic/RTDirCreateUniqueNumbered-generic.cpp
new file mode 100644
index 000000000..7a9c378b5
--- /dev/null
+++ b/src/VBox/Runtime/generic/RTDirCreateUniqueNumbered-generic.cpp
@@ -0,0 +1,102 @@
+/* $Id: RTDirCreateUniqueNumbered-generic.cpp 36604 2011-04-06 23:02:52Z vboxsync $ */
+/** @file
+ * IPRT - RTDirCreateUniqueNumbered, generic implementation.
+ */
+
+/*
+ * 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.
+ *
+ * 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/dir.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/path.h>
+#include <iprt/string.h>
+
+
+RTDECL(int) RTDirCreateUniqueNumbered(char *pszPath, size_t cbSize, RTFMODE fMode, signed int cchDigits, char chSep)
+{
+ /*
+ * Validate input.
+ */
+ AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
+ AssertReturn(cbSize, VERR_BUFFER_OVERFLOW);
+ AssertReturn(cchDigits > 0, VERR_INVALID_PARAMETER);
+
+ /* Check that there is sufficient space. */
+ char *pszEnd = RTStrEnd(pszPath, cbSize);
+ AssertReturn(pszEnd, VERR_BUFFER_OVERFLOW);
+ AssertReturn(cbSize - 1 - (pszEnd - pszPath) >= (size_t)cchDigits + (chSep ? 1 : 0), VERR_BUFFER_OVERFLOW);
+ size_t cbLeft = cbSize - (pszEnd - pszPath);
+
+ /* First try is to create the path without any numbers. */
+ int rc = RTDirCreate(pszPath, fMode);
+ if ( RT_SUCCESS(rc)
+ || rc != VERR_ALREADY_EXISTS)
+ return rc;
+
+ /* If the separator value isn't zero, add it. */
+ if (chSep != '\0')
+ {
+ cbLeft--;
+ *pszEnd++ = chSep;
+ *pszEnd = '\0';
+ }
+
+ /* How many tries? Stay within somewhat sane limits. */
+ uint32_t cMaxTries;
+ if (cchDigits >= 8)
+ cMaxTries = 100 * _1M;
+ else
+ {
+ cMaxTries = 10;
+ for (int a = 0; a < cchDigits - 1; ++a)
+ cMaxTries *= 10;
+ }
+
+ /* Try cMaxTries - 1 times to create a directory with appended numbers. */
+ uint32_t i = 1;
+ while (i < cMaxTries)
+ {
+ /* Format the number with leading zero's. */
+ ssize_t rc2 = RTStrFormatU32(pszEnd, cbLeft, i, 10, cchDigits, 0, RTSTR_F_WIDTH | RTSTR_F_ZEROPAD);
+ if (RT_FAILURE((int) rc2))
+ {
+ *pszPath = '\0';
+ return (int)rc2;
+ }
+ rc = RTDirCreate(pszPath, fMode);
+ if (RT_SUCCESS(rc))
+ return rc;
+ ++i;
+ }
+
+ /* We've given up. */
+ *pszPath = '\0';
+ return VERR_ALREADY_EXISTS;
+}
+RT_EXPORT_SYMBOL(RTDirCreateUniqueNumbered);
+
diff --git a/src/VBox/Runtime/generic/RTDirExists-generic.cpp b/src/VBox/Runtime/generic/RTDirExists-generic.cpp
index 0b5f04a98..f3a4fc1e0 100644
--- a/src/VBox/Runtime/generic/RTDirExists-generic.cpp
+++ b/src/VBox/Runtime/generic/RTDirExists-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTDirExists-generic.cpp $ */
+/* $Id: RTDirExists-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTDirExists, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTDirQueryInfo-generic.cpp b/src/VBox/Runtime/generic/RTDirQueryInfo-generic.cpp
index a01a8d80d..60c2174a8 100644
--- a/src/VBox/Runtime/generic/RTDirQueryInfo-generic.cpp
+++ b/src/VBox/Runtime/generic/RTDirQueryInfo-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTDirQueryInfo-generic.cpp $ */
+/* $Id: RTDirQueryInfo-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTDirQueryInfo, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTDirSetTimes-generic.cpp b/src/VBox/Runtime/generic/RTDirSetTimes-generic.cpp
index b5b781e24..019c61f83 100644
--- a/src/VBox/Runtime/generic/RTDirSetTimes-generic.cpp
+++ b/src/VBox/Runtime/generic/RTDirSetTimes-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTDirSetTimes-generic.cpp $ */
+/* $Id: RTDirSetTimes-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTDirSetTimes, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTEnvDupEx-generic.cpp b/src/VBox/Runtime/generic/RTEnvDupEx-generic.cpp
index 5320cc5f0..c101ca7ed 100644
--- a/src/VBox/Runtime/generic/RTEnvDupEx-generic.cpp
+++ b/src/VBox/Runtime/generic/RTEnvDupEx-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTEnvDupEx-generic.cpp $ */
+/* $Id: RTEnvDupEx-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Environment, RTEnvDupEx, generic.
*/
diff --git a/src/VBox/Runtime/generic/RTFileCopy-generic.cpp b/src/VBox/Runtime/generic/RTFileCopy-generic.cpp
index ea55290cf..b19fb6c88 100644
--- a/src/VBox/Runtime/generic/RTFileCopy-generic.cpp
+++ b/src/VBox/Runtime/generic/RTFileCopy-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTFileCopy-generic.cpp $ */
+/* $Id: RTFileCopy-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTFileCopy, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTFileExists-generic.cpp b/src/VBox/Runtime/generic/RTFileExists-generic.cpp
index f81988165..5c8cffd6d 100644
--- a/src/VBox/Runtime/generic/RTFileExists-generic.cpp
+++ b/src/VBox/Runtime/generic/RTFileExists-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTFileExists-generic.cpp $ */
+/* $Id: RTFileExists-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTFileExists, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTFileMove-generic.cpp b/src/VBox/Runtime/generic/RTFileMove-generic.cpp
index 21556ec70..aa2a37430 100644
--- a/src/VBox/Runtime/generic/RTFileMove-generic.cpp
+++ b/src/VBox/Runtime/generic/RTFileMove-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTFileMove-generic.cpp $ */
+/* $Id: RTFileMove-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTFileMove, Generic.
*/
diff --git a/src/VBox/Runtime/generic/RTFileQuerySize-generic.cpp b/src/VBox/Runtime/generic/RTFileQuerySize-generic.cpp
index a561eea67..3129b7016 100644
--- a/src/VBox/Runtime/generic/RTFileQuerySize-generic.cpp
+++ b/src/VBox/Runtime/generic/RTFileQuerySize-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTFileQuerySize-generic.cpp $ */
+/* $Id: RTFileQuerySize-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTFileQuerySize, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTFileReadAll-generic.cpp b/src/VBox/Runtime/generic/RTFileReadAll-generic.cpp
index 71c0af124..ea8b8dcc9 100644
--- a/src/VBox/Runtime/generic/RTFileReadAll-generic.cpp
+++ b/src/VBox/Runtime/generic/RTFileReadAll-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTFileReadAll-generic.cpp $ */
+/* $Id: RTFileReadAll-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTFileReadAll, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTFileReadAllByHandle-generic.cpp b/src/VBox/Runtime/generic/RTFileReadAllByHandle-generic.cpp
index 2d94160f1..d45ca98d1 100644
--- a/src/VBox/Runtime/generic/RTFileReadAllByHandle-generic.cpp
+++ b/src/VBox/Runtime/generic/RTFileReadAllByHandle-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTFileReadAllByHandle-generic.cpp $ */
+/* $Id: RTFileReadAllByHandle-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTFileReadAllByHandle, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTFileReadAllByHandleEx-generic.cpp b/src/VBox/Runtime/generic/RTFileReadAllByHandleEx-generic.cpp
index 0c41126c6..12b713ea4 100644
--- a/src/VBox/Runtime/generic/RTFileReadAllByHandleEx-generic.cpp
+++ b/src/VBox/Runtime/generic/RTFileReadAllByHandleEx-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTFileReadAllByHandleEx-generic.cpp $ */
+/* $Id: RTFileReadAllByHandleEx-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTFileReadAllByHandleEx, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTFileReadAllEx-generic.cpp b/src/VBox/Runtime/generic/RTFileReadAllEx-generic.cpp
index 2046d7319..fe086addd 100644
--- a/src/VBox/Runtime/generic/RTFileReadAllEx-generic.cpp
+++ b/src/VBox/Runtime/generic/RTFileReadAllEx-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTFileReadAllEx-generic.cpp $ */
+/* $Id: RTFileReadAllEx-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTFileReadAllEx, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTFileReadAllFree-generic.cpp b/src/VBox/Runtime/generic/RTFileReadAllFree-generic.cpp
index 1f1dd2920..8491c323a 100644
--- a/src/VBox/Runtime/generic/RTFileReadAllFree-generic.cpp
+++ b/src/VBox/Runtime/generic/RTFileReadAllFree-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTFileReadAllFree-generic.cpp $ */
+/* $Id: RTFileReadAllFree-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTFileReadAllFree, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTLogDefaultInit-generic.cpp b/src/VBox/Runtime/generic/RTLogDefaultInit-generic.cpp
index 5a1e122c5..f0596f88e 100644
--- a/src/VBox/Runtime/generic/RTLogDefaultInit-generic.cpp
+++ b/src/VBox/Runtime/generic/RTLogDefaultInit-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTLogDefaultInit-generic.cpp $ */
+/* $Id: RTLogDefaultInit-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Default Log Init, Generic Dummy.
*/
diff --git a/src/VBox/Runtime/generic/RTLogWriteDebugger-generic.cpp b/src/VBox/Runtime/generic/RTLogWriteDebugger-generic.cpp
index 116900b57..bb1b35876 100644
--- a/src/VBox/Runtime/generic/RTLogWriteDebugger-generic.cpp
+++ b/src/VBox/Runtime/generic/RTLogWriteDebugger-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTLogWriteDebugger-generic.cpp $ */
+/* $Id: RTLogWriteDebugger-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Log To Debugger, Generic Dummy.
*/
diff --git a/src/VBox/Runtime/generic/RTLogWriteStdErr-generic.cpp b/src/VBox/Runtime/generic/RTLogWriteStdErr-generic.cpp
index fc7af9816..18fdbf84a 100644
--- a/src/VBox/Runtime/generic/RTLogWriteStdErr-generic.cpp
+++ b/src/VBox/Runtime/generic/RTLogWriteStdErr-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTLogWriteStdErr-generic.cpp $ */
+/* $Id: RTLogWriteStdErr-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Log To StdErr, Generic.
*/
diff --git a/src/VBox/Runtime/generic/RTLogWriteStdErr-stub-generic.cpp b/src/VBox/Runtime/generic/RTLogWriteStdErr-stub-generic.cpp
index 4a42187a7..9c3e05161 100644
--- a/src/VBox/Runtime/generic/RTLogWriteStdErr-stub-generic.cpp
+++ b/src/VBox/Runtime/generic/RTLogWriteStdErr-stub-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTLogWriteStdErr-stub-generic.cpp $ */
+/* $Id: RTLogWriteStdErr-stub-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Log To StdErr, Generic Dummy.
*/
diff --git a/src/VBox/Runtime/generic/RTLogWriteStdOut-generic.cpp b/src/VBox/Runtime/generic/RTLogWriteStdOut-generic.cpp
index a358c08d4..9805d180d 100644
--- a/src/VBox/Runtime/generic/RTLogWriteStdOut-generic.cpp
+++ b/src/VBox/Runtime/generic/RTLogWriteStdOut-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTLogWriteStdOut-generic.cpp $ */
+/* $Id: RTLogWriteStdOut-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Log To StdOut, Generic.
*/
diff --git a/src/VBox/Runtime/generic/RTLogWriteStdOut-stub-generic.cpp b/src/VBox/Runtime/generic/RTLogWriteStdOut-stub-generic.cpp
index 99b6b2bb3..54fcd2850 100644
--- a/src/VBox/Runtime/generic/RTLogWriteStdOut-stub-generic.cpp
+++ b/src/VBox/Runtime/generic/RTLogWriteStdOut-stub-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTLogWriteStdOut-stub-generic.cpp $ */
+/* $Id: RTLogWriteStdOut-stub-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Log To StdOut, Generic Dummy.
*/
diff --git a/src/VBox/Runtime/generic/RTLogWriteUser-generic.cpp b/src/VBox/Runtime/generic/RTLogWriteUser-generic.cpp
index 2fe4d0dfb..6ac712221 100644
--- a/src/VBox/Runtime/generic/RTLogWriteUser-generic.cpp
+++ b/src/VBox/Runtime/generic/RTLogWriteUser-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTLogWriteUser-generic.cpp $ */
+/* $Id: RTLogWriteUser-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Log User Specific Output, Generic Dummy.
*/
diff --git a/src/VBox/Runtime/generic/RTMpCpuId-generic.cpp b/src/VBox/Runtime/generic/RTMpCpuId-generic.cpp
index 591d8318c..7ee70e824 100644
--- a/src/VBox/Runtime/generic/RTMpCpuId-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpCpuId-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpCpuId-generic.cpp $ */
+/* $Id: RTMpCpuId-generic.cpp 29500 2010-05-14 21:43:06Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpCpuId.
*/
diff --git a/src/VBox/Runtime/generic/RTMpCpuIdFromSetIndex-generic.cpp b/src/VBox/Runtime/generic/RTMpCpuIdFromSetIndex-generic.cpp
index 2fec3382a..09b6f26f2 100644
--- a/src/VBox/Runtime/generic/RTMpCpuIdFromSetIndex-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpCpuIdFromSetIndex-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpCpuIdFromSetIndex-generic.cpp $ */
+/* $Id: RTMpCpuIdFromSetIndex-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpCpuIdFromSetIndex.
*/
diff --git a/src/VBox/Runtime/generic/RTMpCpuIdToSetIndex-generic.cpp b/src/VBox/Runtime/generic/RTMpCpuIdToSetIndex-generic.cpp
index 894f8f4f7..ce825e471 100644
--- a/src/VBox/Runtime/generic/RTMpCpuIdToSetIndex-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpCpuIdToSetIndex-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpCpuIdToSetIndex-generic.cpp $ */
+/* $Id: RTMpCpuIdToSetIndex-generic.cpp 36232 2011-03-09 16:41:09Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpCpuIdToSetIndex.
*/
diff --git a/src/VBox/Runtime/generic/RTMpGetArraySize-generic.cpp b/src/VBox/Runtime/generic/RTMpGetArraySize-generic.cpp
index eafac57ff..03f30590c 100644
--- a/src/VBox/Runtime/generic/RTMpGetArraySize-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpGetArraySize-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpGetArraySize-generic.cpp $ */
+/* $Id: RTMpGetArraySize-generic.cpp 36254 2011-03-10 17:22:08Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpGetArraySize.
*/
diff --git a/src/VBox/Runtime/generic/RTMpGetCount-generic.cpp b/src/VBox/Runtime/generic/RTMpGetCount-generic.cpp
index f8625e183..52de02d84 100644
--- a/src/VBox/Runtime/generic/RTMpGetCount-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpGetCount-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpGetCount-generic.cpp $ */
+/* $Id: RTMpGetCount-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpGetCount.
*/
diff --git a/src/VBox/Runtime/generic/RTMpGetCurFrequency-generic.cpp b/src/VBox/Runtime/generic/RTMpGetCurFrequency-generic.cpp
index 04c9a68dc..c9f590ee6 100644
--- a/src/VBox/Runtime/generic/RTMpGetCurFrequency-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpGetCurFrequency-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpGetCurFrequency-generic.cpp $ */
+/* $Id: RTMpGetCurFrequency-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpGetCurFrequency.
*/
diff --git a/src/VBox/Runtime/generic/RTMpGetDescription-generic-stub.cpp b/src/VBox/Runtime/generic/RTMpGetDescription-generic-stub.cpp
index a3c176689..3391abb38 100644
--- a/src/VBox/Runtime/generic/RTMpGetDescription-generic-stub.cpp
+++ b/src/VBox/Runtime/generic/RTMpGetDescription-generic-stub.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpGetDescription-generic-stub.cpp $ */
+/* $Id: RTMpGetDescription-generic-stub.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpGetDescription stub.
*/
diff --git a/src/VBox/Runtime/generic/RTMpGetDescription-generic.cpp b/src/VBox/Runtime/generic/RTMpGetDescription-generic.cpp
index dccd40583..cdb41904a 100644
--- a/src/VBox/Runtime/generic/RTMpGetDescription-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpGetDescription-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpGetDescription-generic.cpp $ */
+/* $Id: RTMpGetDescription-generic.cpp 29264 2010-05-09 19:58:37Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpGetDescription.
*/
diff --git a/src/VBox/Runtime/generic/RTMpGetMaxCpuId-generic.cpp b/src/VBox/Runtime/generic/RTMpGetMaxCpuId-generic.cpp
index e79633014..8ef1b8dbf 100644
--- a/src/VBox/Runtime/generic/RTMpGetMaxCpuId-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpGetMaxCpuId-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpGetMaxCpuId-generic.cpp $ */
+/* $Id: RTMpGetMaxCpuId-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpGetMaxCpuId.
*/
diff --git a/src/VBox/Runtime/generic/RTMpGetMaxFrequency-generic.cpp b/src/VBox/Runtime/generic/RTMpGetMaxFrequency-generic.cpp
index 4f468d882..978f439d7 100644
--- a/src/VBox/Runtime/generic/RTMpGetMaxFrequency-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpGetMaxFrequency-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpGetMaxFrequency-generic.cpp $ */
+/* $Id: RTMpGetMaxFrequency-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpGetMaxFrequency.
*/
diff --git a/src/VBox/Runtime/generic/RTMpGetOnlineCount-generic.cpp b/src/VBox/Runtime/generic/RTMpGetOnlineCount-generic.cpp
index e11543e04..36f43f1ed 100644
--- a/src/VBox/Runtime/generic/RTMpGetOnlineCount-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpGetOnlineCount-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpGetOnlineCount-generic.cpp $ */
+/* $Id: RTMpGetOnlineCount-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpGetOnlineCount.
*/
diff --git a/src/VBox/Runtime/generic/RTMpGetOnlineSet-generic.cpp b/src/VBox/Runtime/generic/RTMpGetOnlineSet-generic.cpp
index 753ee62dc..05be2872c 100644
--- a/src/VBox/Runtime/generic/RTMpGetOnlineSet-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpGetOnlineSet-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpGetOnlineSet-generic.cpp $ */
+/* $Id: RTMpGetOnlineSet-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpGetOnlineSet.
*/
diff --git a/src/VBox/Runtime/generic/RTMpGetSet-generic.cpp b/src/VBox/Runtime/generic/RTMpGetSet-generic.cpp
index 01b724965..6a83d70e9 100644
--- a/src/VBox/Runtime/generic/RTMpGetSet-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpGetSet-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpGetSet-generic.cpp $ */
+/* $Id: RTMpGetSet-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpGetSet.
*/
diff --git a/src/VBox/Runtime/generic/RTMpIsCpuOnline-generic.cpp b/src/VBox/Runtime/generic/RTMpIsCpuOnline-generic.cpp
index b53c13ae9..79cfae8b8 100644
--- a/src/VBox/Runtime/generic/RTMpIsCpuOnline-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpIsCpuOnline-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpIsCpuOnline-generic.cpp $ */
+/* $Id: RTMpIsCpuOnline-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpIsCpuOnline.
*/
diff --git a/src/VBox/Runtime/generic/RTMpIsCpuPossible-generic.cpp b/src/VBox/Runtime/generic/RTMpIsCpuPossible-generic.cpp
index 7c57ae831..dfdb48046 100644
--- a/src/VBox/Runtime/generic/RTMpIsCpuPossible-generic.cpp
+++ b/src/VBox/Runtime/generic/RTMpIsCpuPossible-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpIsCpuPossible-generic.cpp $ */
+/* $Id: RTMpIsCpuPossible-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Generic RTMpIsCpuPossible.
*/
diff --git a/src/VBox/Runtime/generic/RTProcDaemonize-generic.cpp b/src/VBox/Runtime/generic/RTProcDaemonize-generic.cpp
index a099fb0a6..9fe36f6f9 100644
--- a/src/VBox/Runtime/generic/RTProcDaemonize-generic.cpp
+++ b/src/VBox/Runtime/generic/RTProcDaemonize-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTProcDaemonize-generic.cpp $ */
+/* $Id: RTProcDaemonize-generic.cpp 33806 2010-11-05 17:20:15Z vboxsync $ */
/** @file
* IPRT - RTProcDaemonize, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTProcIsRunningByName-generic.cpp b/src/VBox/Runtime/generic/RTProcIsRunningByName-generic.cpp
index 89e2b4c82..ff37e079a 100644
--- a/src/VBox/Runtime/generic/RTProcIsRunningByName-generic.cpp
+++ b/src/VBox/Runtime/generic/RTProcIsRunningByName-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTProcIsRunningByName-generic.cpp $ */
+/* $Id: RTProcIsRunningByName-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTProcIsRunningByName, generic stub.
*/
diff --git a/src/VBox/Runtime/generic/RTRandAdvCreateSystemFaster-generic.cpp b/src/VBox/Runtime/generic/RTRandAdvCreateSystemFaster-generic.cpp
index 0b05fa5e8..fb277d4e5 100644
--- a/src/VBox/Runtime/generic/RTRandAdvCreateSystemFaster-generic.cpp
+++ b/src/VBox/Runtime/generic/RTRandAdvCreateSystemFaster-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTRandAdvCreateSystemFaster-generic.cpp $ */
+/* $Id: RTRandAdvCreateSystemFaster-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Random Numbers, generic RTRandAdvCreateSystemFaster.
*/
diff --git a/src/VBox/Runtime/generic/RTRandAdvCreateSystemTruer-generic.cpp b/src/VBox/Runtime/generic/RTRandAdvCreateSystemTruer-generic.cpp
index 375757a77..39c42cbca 100644
--- a/src/VBox/Runtime/generic/RTRandAdvCreateSystemTruer-generic.cpp
+++ b/src/VBox/Runtime/generic/RTRandAdvCreateSystemTruer-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTRandAdvCreateSystemTruer-generic.cpp $ */
+/* $Id: RTRandAdvCreateSystemTruer-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Random Numbers, generic RTRandAdvCreateSystemTruer.
*/
diff --git a/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp b/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp
index 437be6be1..6ce2d195e 100644
--- a/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp
+++ b/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSemEventMultiWait-2-ex-generic.cpp $ */
+/* $Id: RTSemEventMultiWait-2-ex-generic.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - RTSemEventMultiWait, implementation based on RTSemEventMultiWaitEx.
*/
diff --git a/src/VBox/Runtime/generic/RTSemEventMultiWait-generic.cpp b/src/VBox/Runtime/generic/RTSemEventMultiWait-generic.cpp
index 16a9580bf..54b4ba601 100644
--- a/src/VBox/Runtime/generic/RTSemEventMultiWait-generic.cpp
+++ b/src/VBox/Runtime/generic/RTSemEventMultiWait-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSemEventMultiWait-generic.cpp $ */
+/* $Id: RTSemEventMultiWait-generic.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - RTSemEventMultiWait, generic RTSemEventMultiWaitNoResume wrapper.
*/
diff --git a/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp b/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp
index c3eb88db0..651f10109 100644
--- a/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp
+++ b/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSemEventMultiWaitNoResume-2-ex-generic.cpp $ */
+/* $Id: RTSemEventMultiWaitNoResume-2-ex-generic.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - RTSemEventMultiWaitNoResume, generic implementation based
* on RTSemEventMultiWaitEx.
diff --git a/src/VBox/Runtime/generic/RTSemEventWait-2-ex-generic.cpp b/src/VBox/Runtime/generic/RTSemEventWait-2-ex-generic.cpp
index b2e78807d..4cad3116d 100644
--- a/src/VBox/Runtime/generic/RTSemEventWait-2-ex-generic.cpp
+++ b/src/VBox/Runtime/generic/RTSemEventWait-2-ex-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSemEventWait-2-ex-generic.cpp $ */
+/* $Id: RTSemEventWait-2-ex-generic.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - RTSemEventWait, implementation based on RTSemEventWaitEx.
*/
diff --git a/src/VBox/Runtime/generic/RTSemEventWait-generic.cpp b/src/VBox/Runtime/generic/RTSemEventWait-generic.cpp
index ade778085..eea5dc6b3 100644
--- a/src/VBox/Runtime/generic/RTSemEventWait-generic.cpp
+++ b/src/VBox/Runtime/generic/RTSemEventWait-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSemEventWait-generic.cpp $ */
+/* $Id: RTSemEventWait-generic.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - RTSemEventWait, generic RTSemEventWaitNoResume wrapper.
*/
diff --git a/src/VBox/Runtime/generic/RTSemEventWaitNoResume-2-ex-generic.cpp b/src/VBox/Runtime/generic/RTSemEventWaitNoResume-2-ex-generic.cpp
index 3dbe66cdc..d712334f5 100644
--- a/src/VBox/Runtime/generic/RTSemEventWaitNoResume-2-ex-generic.cpp
+++ b/src/VBox/Runtime/generic/RTSemEventWaitNoResume-2-ex-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSemEventWaitNoResume-2-ex-generic.cpp $ */
+/* $Id: RTSemEventWaitNoResume-2-ex-generic.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - RTSemEventWaitNoResume, generic implementation based
* on RTSemEventWaitEx.
diff --git a/src/VBox/Runtime/generic/RTSemMutexRequest-generic.cpp b/src/VBox/Runtime/generic/RTSemMutexRequest-generic.cpp
index 32c3f8760..4c378138a 100644
--- a/src/VBox/Runtime/generic/RTSemMutexRequest-generic.cpp
+++ b/src/VBox/Runtime/generic/RTSemMutexRequest-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSemMutexRequest-generic.cpp $ */
+/* $Id: RTSemMutexRequest-generic.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - RTSemMutexRequest, generic RTSemMutexRequestNoResume wrapper.
*/
diff --git a/src/VBox/Runtime/generic/RTSemMutexRequestDebug-generic.cpp b/src/VBox/Runtime/generic/RTSemMutexRequestDebug-generic.cpp
index 4ba150392..b426a789f 100644
--- a/src/VBox/Runtime/generic/RTSemMutexRequestDebug-generic.cpp
+++ b/src/VBox/Runtime/generic/RTSemMutexRequestDebug-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSemMutexRequestDebug-generic.cpp $ */
+/* $Id: RTSemMutexRequestDebug-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTSemMutexRequestDebug, generic RTSemMutexRequestNoResumeDebug wrapper.
*/
diff --git a/src/VBox/Runtime/generic/RTSystemQueryDmiString-generic.cpp b/src/VBox/Runtime/generic/RTSystemQueryDmiString-generic.cpp
index 723f1aa33..59c064bcc 100644
--- a/src/VBox/Runtime/generic/RTSystemQueryDmiString-generic.cpp
+++ b/src/VBox/Runtime/generic/RTSystemQueryDmiString-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSystemQueryDmiString-generic.cpp $ */
+/* $Id: RTSystemQueryDmiString-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTSystemQueryDmiString, generic stub.
*/
diff --git a/src/VBox/Runtime/generic/RTSystemQueryOSInfo-generic.cpp b/src/VBox/Runtime/generic/RTSystemQueryOSInfo-generic.cpp
index ec52c77d9..c2fe3c6ae 100644
--- a/src/VBox/Runtime/generic/RTSystemQueryOSInfo-generic.cpp
+++ b/src/VBox/Runtime/generic/RTSystemQueryOSInfo-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSystemQueryOSInfo-generic.cpp $ */
+/* $Id: RTSystemQueryOSInfo-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTSystemQueryOSInfo, generic stub.
*/
diff --git a/src/VBox/Runtime/generic/RTThreadGetAffinity-stub-generic.cpp b/src/VBox/Runtime/generic/RTThreadGetAffinity-stub-generic.cpp
new file mode 100644
index 000000000..053db160e
--- /dev/null
+++ b/src/VBox/Runtime/generic/RTThreadGetAffinity-stub-generic.cpp
@@ -0,0 +1,44 @@
+/* $Id: RTThreadGetAffinity-stub-generic.cpp 37154 2011-05-19 12:54:32Z vboxsync $ */
+/** @file
+ * IPRT - Generic RTThreadGetAffinity stub.
+ */
+
+/*
+ * 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.
+ *
+ * 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/thread.h>
+#include "internal/iprt.h"
+
+#include <iprt/cpuset.h>
+#include <iprt/err.h>
+
+
+RTR3DECL(int) RTThreadGetAffinity(PRTCPUSET pCpuSet)
+{
+ RTCpuSetEmpty(pCpuSet);
+ RTCpuSetAddByIndex(pCpuSet, 0);
+ return VINF_SUCCESS;
+}
+
diff --git a/src/VBox/Runtime/generic/RTThreadGetNativeState-generic.cpp b/src/VBox/Runtime/generic/RTThreadGetNativeState-generic.cpp
index ab8229bd7..d776ac8d7 100644
--- a/src/VBox/Runtime/generic/RTThreadGetNativeState-generic.cpp
+++ b/src/VBox/Runtime/generic/RTThreadGetNativeState-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTThreadGetNativeState-generic.cpp $ */
+/* $Id: RTThreadGetNativeState-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTThreadGetNativeState, generic stub implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTThreadSetAffinity-stub-generic.cpp b/src/VBox/Runtime/generic/RTThreadSetAffinity-stub-generic.cpp
new file mode 100644
index 000000000..d442d28d9
--- /dev/null
+++ b/src/VBox/Runtime/generic/RTThreadSetAffinity-stub-generic.cpp
@@ -0,0 +1,46 @@
+/* $Id: RTThreadSetAffinity-stub-generic.cpp 37154 2011-05-19 12:54:32Z vboxsync $ */
+/** @file
+ * IPRT - Generic RTThreadSetAffinity stub.
+ */
+
+/*
+ * 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.
+ *
+ * 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/thread.h>
+#include "internal/iprt.h"
+
+#include <iprt/cpuset.h>
+#include <iprt/err.h>
+
+
+RTR3DECL(int) RTThreadSetAffinity(PCRTCPUSET pCpuSet)
+{
+ RTCPUSET CurSet;
+ RTThreadGetAffinity(&CurSet);
+ if (pCpuSet && !RTCpuSetIsEqual(&CurSet, pCpuSet))
+ return VERR_INVALID_PARAMETER;
+ return VINF_SUCCESS;
+}
+
diff --git a/src/VBox/Runtime/generic/RTThreadSetAffinityToCpu-generic.cpp b/src/VBox/Runtime/generic/RTThreadSetAffinityToCpu-generic.cpp
new file mode 100644
index 000000000..9d728891a
--- /dev/null
+++ b/src/VBox/Runtime/generic/RTThreadSetAffinityToCpu-generic.cpp
@@ -0,0 +1,59 @@
+/* $Id: RTThreadSetAffinityToCpu-generic.cpp 37154 2011-05-19 12:54:32Z vboxsync $ */
+/** @file
+ * IPRT - Generic RTThreadSetAffinityToCpu implementation.
+ */
+
+/*
+ * 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.
+ *
+ * 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/thread.h>
+#include "internal/iprt.h"
+
+#include <iprt/cpuset.h>
+#include <iprt/err.h>
+
+
+
+RTR3DECL(int) RTThreadSetAffinityToCpu(RTCPUID idCpu)
+{
+ int rc;
+ if (idCpu == NIL_RTCPUID)
+ rc = RTThreadSetAffinity(NULL);
+ else
+ {
+ int iCpu = RTMpCpuIdToSetIndex(idCpu);
+ if (iCpu >= 0)
+ {
+ RTCPUSET CpuSet;
+ RTCpuSetEmpty(&CpuSet);
+ RTCpuSetAddByIndex(&CpuSet, iCpu);
+ rc = RTThreadSetAffinity(&CpuSet);
+ }
+ else
+ rc = VERR_CPU_NOT_FOUND;
+ }
+ return rc;
+}
+
diff --git a/src/VBox/Runtime/generic/RTTimeLocalDeltaNano-generic.cpp b/src/VBox/Runtime/generic/RTTimeLocalDeltaNano-generic.cpp
index 92826f0e5..6c55fdaf5 100644
--- a/src/VBox/Runtime/generic/RTTimeLocalDeltaNano-generic.cpp
+++ b/src/VBox/Runtime/generic/RTTimeLocalDeltaNano-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTTimeLocalDeltaNano-generic.cpp $ */
+/* $Id: RTTimeLocalDeltaNano-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Time, generic RTTimeLocalDeltaNano.
*/
diff --git a/src/VBox/Runtime/generic/RTTimeLocalExplode-generic.cpp b/src/VBox/Runtime/generic/RTTimeLocalExplode-generic.cpp
index ae760602d..be65e9b56 100644
--- a/src/VBox/Runtime/generic/RTTimeLocalExplode-generic.cpp
+++ b/src/VBox/Runtime/generic/RTTimeLocalExplode-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTTimeLocalExplode-generic.cpp $ */
+/* $Id: RTTimeLocalExplode-generic.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Time, generic RTTimeLocalExplode.
*/
diff --git a/src/VBox/Runtime/generic/RTTimerCreate-generic.cpp b/src/VBox/Runtime/generic/RTTimerCreate-generic.cpp
index 81c28c537..7dbbe8d6c 100644
--- a/src/VBox/Runtime/generic/RTTimerCreate-generic.cpp
+++ b/src/VBox/Runtime/generic/RTTimerCreate-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTTimerCreate-generic.cpp $ */
+/* $Id: RTTimerCreate-generic.cpp 32504 2010-09-15 10:12:38Z vboxsync $ */
/** @file
* IPRT - Timers, Generic RTTimerCreate() Implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTTimerLRCreate-generic.cpp b/src/VBox/Runtime/generic/RTTimerLRCreate-generic.cpp
index 6af2c79a5..e7d1e3db8 100644
--- a/src/VBox/Runtime/generic/RTTimerLRCreate-generic.cpp
+++ b/src/VBox/Runtime/generic/RTTimerLRCreate-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTTimerLRCreate-generic.cpp $ */
+/* $Id: RTTimerLRCreate-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Low Resolution Timers, Generic RTTimerLRCreate() Implementation.
*/
diff --git a/src/VBox/Runtime/generic/RTUuidCreate-generic.cpp b/src/VBox/Runtime/generic/RTUuidCreate-generic.cpp
index e88ab1ff8..1df1dbf3c 100644
--- a/src/VBox/Runtime/generic/RTUuidCreate-generic.cpp
+++ b/src/VBox/Runtime/generic/RTUuidCreate-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTUuidCreate-generic.cpp $ */
+/* $Id: RTUuidCreate-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - UUID, Generic RTUuidCreate implementation.
*/
diff --git a/src/VBox/Runtime/generic/critsect-generic.cpp b/src/VBox/Runtime/generic/critsect-generic.cpp
index 0cb8a61bc..e11e53d77 100644
--- a/src/VBox/Runtime/generic/critsect-generic.cpp
+++ b/src/VBox/Runtime/generic/critsect-generic.cpp
@@ -1,10 +1,10 @@
-/* $Id: critsect-generic.cpp $ */
+/* $Id: critsect-generic.cpp 37419 2011-06-11 20:25:37Z vboxsync $ */
/** @file
* IPRT - Critical Section, Generic.
*/
/*
- * Copyright (C) 2006-2009 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;
@@ -28,6 +28,7 @@
/*******************************************************************************
* Header Files *
*******************************************************************************/
+#define RTCRITSECT_WITHOUT_REMAPPING
#include <iprt/critsect.h>
#include "internal/iprt.h"
@@ -40,7 +41,6 @@
#include "internal/strict.h"
-#undef RTCritSectInit
RTDECL(int) RTCritSectInit(PRTCRITSECT pCritSect)
{
return RTCritSectInitEx(pCritSect, 0, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, "RTCritSect");
@@ -51,7 +51,7 @@ RT_EXPORT_SYMBOL(RTCritSectInit);
RTDECL(int) RTCritSectInitEx(PRTCRITSECT pCritSect, uint32_t fFlags, RTLOCKVALCLASS hClass, uint32_t uSubClass,
const char *pszNameFmt, ...)
{
- AssertReturn(!(fFlags & ~(RTCRITSECT_FLAGS_NO_NESTING | RTCRITSECT_FLAGS_NO_LOCK_VAL | RTCRITSECT_FLAGS_BOOTSTRAP_HACK)),
+ AssertReturn(!(fFlags & ~(RTCRITSECT_FLAGS_NO_NESTING | RTCRITSECT_FLAGS_NO_LOCK_VAL | RTCRITSECT_FLAGS_BOOTSTRAP_HACK | RTCRITSECT_FLAGS_NOP)),
VERR_INVALID_PARAMETER);
/*
@@ -65,7 +65,7 @@ RTDECL(int) RTCritSectInitEx(PRTCRITSECT pCritSect, uint32_t fFlags, RTLOCKVALCL
pCritSect->pValidatorRec = NULL;
int rc = VINF_SUCCESS;
#ifdef RTCRITSECT_STRICT
- if (!(fFlags & RTCRITSECT_FLAGS_BOOTSTRAP_HACK))
+ if (!(fFlags & (RTCRITSECT_FLAGS_BOOTSTRAP_HACK | RTCRITSECT_FLAGS_NOP)))
{
if (!pszNameFmt)
{
@@ -110,6 +110,7 @@ RTDECL(uint32_t) RTCritSectSetSubClass(PRTCRITSECT pCritSect, uint32_t uSubClass
#ifdef RTCRITSECT_STRICT
AssertPtrReturn(pCritSect, RTLOCKVAL_SUB_CLASS_INVALID);
AssertReturn(pCritSect->u32Magic == RTCRITSECT_MAGIC, RTLOCKVAL_SUB_CLASS_INVALID);
+ AssertReturn(!(pCritSect->fFlags & RTCRITSECT_FLAGS_NOP), RTLOCKVAL_SUB_CLASS_INVALID);
return RTLockValidatorRecExclSetSubClass(pCritSect->pValidatorRec, uSubClass);
#else
return RTLOCKVAL_SUB_CLASS_INVALID;
@@ -121,11 +122,18 @@ DECL_FORCE_INLINE(int) rtCritSectTryEnter(PRTCRITSECT pCritSect, PCRTLOCKVALSRCP
{
Assert(pCritSect);
Assert(pCritSect->u32Magic == RTCRITSECT_MAGIC);
- RTNATIVETHREAD NativeThreadSelf = RTThreadNativeSelf();
+ /*AssertReturn(pCritSect->u32Magic == RTCRITSECT_MAGIC, VERR_SEM_DESTROYED);*/
+
+ /*
+ * Return straight away if NOP.
+ */
+ if (pCritSect->fFlags & RTCRITSECT_FLAGS_NOP)
+ return VINF_SUCCESS;
/*
* Try take the lock. (cLockers is -1 if it's free)
*/
+ RTNATIVETHREAD NativeThreadSelf = RTThreadNativeSelf();
if (!ASMAtomicCmpXchgS32(&pCritSect->cLockers, 0, -1))
{
/*
@@ -163,7 +171,6 @@ DECL_FORCE_INLINE(int) rtCritSectTryEnter(PRTCRITSECT pCritSect, PCRTLOCKVALSRCP
}
-#undef RTCritSectTryEnter
RTDECL(int) RTCritSectTryEnter(PRTCRITSECT pCritSect)
{
#ifndef RTCRTISECT_STRICT
@@ -186,19 +193,24 @@ RT_EXPORT_SYMBOL(RTCritSectTryEnterDebug);
DECL_FORCE_INLINE(int) rtCritSectEnter(PRTCRITSECT pCritSect, PCRTLOCKVALSRCPOS pSrcPos)
{
- Assert(pCritSect);
- Assert(pCritSect->u32Magic == RTCRITSECT_MAGIC);
- RTNATIVETHREAD NativeThreadSelf = RTThreadNativeSelf();
+ AssertPtr(pCritSect);
+ AssertReturn(pCritSect->u32Magic == RTCRITSECT_MAGIC, VERR_SEM_DESTROYED);
- /* If the critical section has already been destroyed, then inform the caller. */
- if (pCritSect->u32Magic != RTCRITSECT_MAGIC)
- return VERR_SEM_DESTROYED;
+ /*
+ * Return straight away if NOP.
+ */
+ if (pCritSect->fFlags & RTCRITSECT_FLAGS_NOP)
+ return VINF_SUCCESS;
+ /*
+ * How is calling and is the order right?
+ */
+ RTNATIVETHREAD NativeThreadSelf = RTThreadNativeSelf();
#ifdef RTCRITSECT_STRICT
- RTTHREAD hThreadSelf = pCritSect->pValidatorRec
- ? RTThreadSelfAutoAdopt()
- : RTThreadSelf();
- int rc9;
+ RTTHREAD hThreadSelf = pCritSect->pValidatorRec
+ ? RTThreadSelfAutoAdopt()
+ : RTThreadSelf();
+ int rc9;
if (pCritSect->pValidatorRec) /* (bootstap) */
{
rc9 = RTLockValidatorRecExclCheckOrder(pCritSect->pValidatorRec, hThreadSelf, pSrcPos, RT_INDEFINITE_WAIT);
@@ -282,7 +294,6 @@ DECL_FORCE_INLINE(int) rtCritSectEnter(PRTCRITSECT pCritSect, PCRTLOCKVALSRCPOS
}
-#undef RTCritSectEnter
RTDECL(int) RTCritSectEnter(PRTCRITSECT pCritSect)
{
#ifndef RTCRITSECT_STRICT
@@ -306,10 +317,16 @@ RT_EXPORT_SYMBOL(RTCritSectEnterDebug);
RTDECL(int) RTCritSectLeave(PRTCRITSECT pCritSect)
{
/*
- * Assert ownership and so on.
+ * Assert sanity and check for NOP.
*/
Assert(pCritSect);
Assert(pCritSect->u32Magic == RTCRITSECT_MAGIC);
+ if (pCritSect->fFlags & RTCRITSECT_FLAGS_NOP)
+ return VINF_SUCCESS;
+
+ /*
+ * Assert ownership and so on.
+ */
Assert(pCritSect->cNestings > 0);
Assert(pCritSect->cLockers >= 0);
Assert(pCritSect->NativeThreadOwner == RTThreadNativeSelf());
@@ -425,7 +442,6 @@ static int rtCritSectEnterMultiple(size_t cCritSects, PRTCRITSECT *papCritSects,
}
-#undef RTCritSectEnterMultiple
RTDECL(int) RTCritSectEnterMultiple(size_t cCritSects, PRTCRITSECT *papCritSects)
{
#ifndef RTCRITSECT_STRICT
diff --git a/src/VBox/Runtime/generic/env-generic.cpp b/src/VBox/Runtime/generic/env-generic.cpp
index f07abc997..0c4911cde 100644
--- a/src/VBox/Runtime/generic/env-generic.cpp
+++ b/src/VBox/Runtime/generic/env-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: env-generic.cpp $ */
+/* $Id: env-generic.cpp 36576 2011-04-06 13:28:12Z vboxsync $ */
/** @file
* IPRT - Environment, Generic.
*/
diff --git a/src/VBox/Runtime/generic/errvars-generic.cpp b/src/VBox/Runtime/generic/errvars-generic.cpp
new file mode 100644
index 000000000..c57abd44c
--- /dev/null
+++ b/src/VBox/Runtime/generic/errvars-generic.cpp
@@ -0,0 +1,66 @@
+/* $Id: errvars-generic.cpp 37233 2011-05-27 13:31:57Z vboxsync $ */
+/** @file
+ * IPRT - Save and Restore Error Variables, generic stub implementation.
+ */
+
+/*
+ * 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.
+ *
+ * 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/err.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include "internal/magics.h"
+
+
+
+RTDECL(PRTERRVARS) RTErrVarsSave(PRTERRVARS pVars)
+{
+ pVars->ai32Vars[0] = RTERRVARS_MAGIC;
+ return pVars;
+}
+
+
+RTDECL(void) RTErrVarsRestore(PCRTERRVARS pVars)
+{
+ Assert(pVars->ai32Vars[0] == RTERRVARS_MAGIC);
+}
+
+
+RTDECL(bool) RTErrVarsAreEqual(PCRTERRVARS pVars1, PCRTERRVARS pVars2)
+{
+ Assert(pVars1->ai32Vars[0] == RTERRVARS_MAGIC);
+ Assert(pVars2->ai32Vars[0] == RTERRVARS_MAGIC);
+
+ return pVars1->ai32Vars[0] == pVars2->ai32Vars[0];
+}
+
+
+RTDECL(bool) RTErrVarsHaveChanged(PCRTERRVARS pVars)
+{
+ Assert(pVars->ai32Vars[0] == RTERRVARS_MAGIC);
+ return false;
+}
+
diff --git a/src/VBox/Runtime/generic/fs-stubs-generic.cpp b/src/VBox/Runtime/generic/fs-stubs-generic.cpp
index 4d4403ad8..193121b50 100644
--- a/src/VBox/Runtime/generic/fs-stubs-generic.cpp
+++ b/src/VBox/Runtime/generic/fs-stubs-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: fs-stubs-generic.cpp $ */
+/* $Id: fs-stubs-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - File System, Generic Stubs.
*/
diff --git a/src/VBox/Runtime/generic/mempool-generic.cpp b/src/VBox/Runtime/generic/mempool-generic.cpp
index 8f53402a0..6d485a6d6 100644
--- a/src/VBox/Runtime/generic/mempool-generic.cpp
+++ b/src/VBox/Runtime/generic/mempool-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: mempool-generic.cpp $ */
+/* $Id: mempool-generic.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Memory Allocation Pool.
*/
diff --git a/src/VBox/Runtime/generic/mppresent-generic.cpp b/src/VBox/Runtime/generic/mppresent-generic.cpp
index 2d345f771..6ebfa08df 100644
--- a/src/VBox/Runtime/generic/mppresent-generic.cpp
+++ b/src/VBox/Runtime/generic/mppresent-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: mppresent-generic.cpp $ */
+/* $Id: mppresent-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Stubs for the RTMp*Present* API.
*/
diff --git a/src/VBox/Runtime/generic/pathhost-generic.cpp b/src/VBox/Runtime/generic/pathhost-generic.cpp
index fa615e1af..b35c7f9ae 100644
--- a/src/VBox/Runtime/generic/pathhost-generic.cpp
+++ b/src/VBox/Runtime/generic/pathhost-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: pathhost-generic.cpp $ */
+/* $Id: pathhost-generic.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Path Conversions, generic pass through.
*/
diff --git a/src/VBox/Runtime/generic/sched-generic.cpp b/src/VBox/Runtime/generic/sched-generic.cpp
index 8ae5b89c0..4905ad62c 100644
--- a/src/VBox/Runtime/generic/sched-generic.cpp
+++ b/src/VBox/Runtime/generic/sched-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: sched-generic.cpp $ */
+/* $Id: sched-generic.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Scheduling, generic stubs.
*/
@@ -45,7 +45,7 @@
* @returns iprt status code.
* @param enmType The thread type to be assumed for the current thread.
*/
-int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
{
Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
return VINF_SUCCESS;
@@ -61,7 +61,7 @@ int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
* @param enmPriority The priority to validate and set.
* @remark Located in sched.
*/
-int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
+DECLHIDDEN(int) rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
{
Assert(enmPriority > RTPROCPRIORITY_INVALID && enmPriority < RTPROCPRIORITY_LAST);
return VINF_SUCCESS;
@@ -80,7 +80,7 @@ int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
* @param enmType The thread type.
* @remark Located in sched.
*/
-int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
{
Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
return VINF_SUCCESS;
diff --git a/src/VBox/Runtime/generic/semfastmutex-generic.cpp b/src/VBox/Runtime/generic/semfastmutex-generic.cpp
index 69de1410e..8c4ac1ee6 100644
--- a/src/VBox/Runtime/generic/semfastmutex-generic.cpp
+++ b/src/VBox/Runtime/generic/semfastmutex-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: semfastmutex-generic.cpp $ */
+/* $Id: semfastmutex-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Fast Mutex, Generic.
*/
diff --git a/src/VBox/Runtime/generic/semrw-generic.cpp b/src/VBox/Runtime/generic/semrw-generic.cpp
index f565119e8..81348fb74 100644
--- a/src/VBox/Runtime/generic/semrw-generic.cpp
+++ b/src/VBox/Runtime/generic/semrw-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: semrw-generic.cpp $ */
+/* $Id: semrw-generic.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Read-Write Semaphore, Generic.
*
diff --git a/src/VBox/Runtime/generic/semrw-lockless-generic.cpp b/src/VBox/Runtime/generic/semrw-lockless-generic.cpp
index 3da9d6fe1..6d1d567f5 100644
--- a/src/VBox/Runtime/generic/semrw-lockless-generic.cpp
+++ b/src/VBox/Runtime/generic/semrw-lockless-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: semrw-lockless-generic.cpp $ */
+/* $Id: semrw-lockless-generic.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT Testcase - RTSemXRoads, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/semxroads-generic.cpp b/src/VBox/Runtime/generic/semxroads-generic.cpp
index 55f9670a3..73c84209f 100644
--- a/src/VBox/Runtime/generic/semxroads-generic.cpp
+++ b/src/VBox/Runtime/generic/semxroads-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: semxroads-generic.cpp $ */
+/* $Id: semxroads-generic.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT Testcase - RTSemXRoads, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/spinlock-generic.cpp b/src/VBox/Runtime/generic/spinlock-generic.cpp
index beac17b0d..f4570ad7b 100644
--- a/src/VBox/Runtime/generic/spinlock-generic.cpp
+++ b/src/VBox/Runtime/generic/spinlock-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: spinlock-generic.cpp $ */
+/* $Id: spinlock-generic.cpp 34239 2010-11-22 13:58:16Z vboxsync $ */
/** @file
* IPRT - Spinlock, generic implementation.
*/
diff --git a/src/VBox/Runtime/generic/strcache-stubs-generic.cpp b/src/VBox/Runtime/generic/strcache-stubs-generic.cpp
index 0b358a461..b45dc5182 100644
--- a/src/VBox/Runtime/generic/strcache-stubs-generic.cpp
+++ b/src/VBox/Runtime/generic/strcache-stubs-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: strcache-stubs-generic.cpp $ */
+/* $Id: strcache-stubs-generic.cpp 30320 2010-06-21 08:35:09Z vboxsync $ */
/** @file
* IPRT - String Cache, stub implementation.
*/
diff --git a/src/VBox/Runtime/generic/timer-generic.cpp b/src/VBox/Runtime/generic/timer-generic.cpp
index fb3c5b501..6c3595e19 100644
--- a/src/VBox/Runtime/generic/timer-generic.cpp
+++ b/src/VBox/Runtime/generic/timer-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: timer-generic.cpp $ */
+/* $Id: timer-generic.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Timers, Generic.
*/
diff --git a/src/VBox/Runtime/generic/timerlr-generic.cpp b/src/VBox/Runtime/generic/timerlr-generic.cpp
index 6019356f7..890bd2fb7 100644
--- a/src/VBox/Runtime/generic/timerlr-generic.cpp
+++ b/src/VBox/Runtime/generic/timerlr-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: timerlr-generic.cpp $ */
+/* $Id: timerlr-generic.cpp 34507 2010-11-30 13:14:14Z vboxsync $ */
/** @file
* IPRT - Low Resolution Timers, Generic.
*
diff --git a/src/VBox/Runtime/generic/tls-generic.cpp b/src/VBox/Runtime/generic/tls-generic.cpp
index d178ed095..0c241d2e3 100644
--- a/src/VBox/Runtime/generic/tls-generic.cpp
+++ b/src/VBox/Runtime/generic/tls-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: tls-generic.cpp $ */
+/* $Id: tls-generic.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Thread Local Storage (TSL), Generic Implementation.
*/
@@ -140,7 +140,7 @@ RTR3DECL(int) RTTlsSet(RTTLS iTls, void *pvValue)
*
* @param pThread The current thread.
*/
-void rtThreadTlsDestruction(PRTTHREADINT pThread)
+DECLHIDDEN(void) rtThreadTlsDestruction(PRTTHREADINT pThread)
{
for (RTTLS iTls = 0; iTls < RTTHREAD_TLS_ENTRIES; iTls++)
{
diff --git a/src/VBox/Runtime/generic/utf16locale-generic.cpp b/src/VBox/Runtime/generic/utf16locale-generic.cpp
index b75ec9d15..22a1b5896 100644
--- a/src/VBox/Runtime/generic/utf16locale-generic.cpp
+++ b/src/VBox/Runtime/generic/utf16locale-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: utf16locale-generic.cpp $ */
+/* $Id: utf16locale-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - UTF-16 Locale Specific Manipulation, Generic.
*/
diff --git a/src/VBox/Runtime/generic/uuid-generic.cpp b/src/VBox/Runtime/generic/uuid-generic.cpp
index 423892ce2..30c83c8d4 100644
--- a/src/VBox/Runtime/generic/uuid-generic.cpp
+++ b/src/VBox/Runtime/generic/uuid-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: uuid-generic.cpp $ */
+/* $Id: uuid-generic.cpp 32995 2010-10-08 08:11:27Z vboxsync $ */
/** @file
* IPRT - UUID, Generic.
*/
diff --git a/src/VBox/Runtime/include/internal/alignmentchecks.h b/src/VBox/Runtime/include/internal/alignmentchecks.h
index 96e96e88e..5ecda8bf9 100644
--- a/src/VBox/Runtime/include/internal/alignmentchecks.h
+++ b/src/VBox/Runtime/include/internal/alignmentchecks.h
@@ -1,4 +1,4 @@
-/* $Id: alignmentchecks.h $ */
+/* $Id: alignmentchecks.h 29250 2010-05-09 17:53:58Z vboxsync $ */
/** @file
* IPRT - Internal header for hacking alignment checks on x86 and AMD64.
*/
diff --git a/src/VBox/Runtime/include/internal/assert.h b/src/VBox/Runtime/include/internal/assert.h
index 8d56b8cf2..a45568b5e 100644
--- a/src/VBox/Runtime/include/internal/assert.h
+++ b/src/VBox/Runtime/include/internal/assert.h
@@ -1,4 +1,4 @@
-/* $Id: assert.h $ */
+/* $Id: assert.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Internal RTAssert header
*/
@@ -42,7 +42,7 @@ RT_C_DECLS_BEGIN
* @param pszFile Location file name.
* @param pszFunction Location function name.
*/
-void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction);
+DECLHIDDEN(void) rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction);
/**
* Print the 2nd (optional) part of an assert message to whatever native
@@ -53,7 +53,7 @@ void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFi
* @param pszFormat Printf like format string.
* @param va Arguments to that string.
*/
-void rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va);
+DECLHIDDEN(void) rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va);
#endif
diff --git a/src/VBox/Runtime/include/internal/dbgmod.h b/src/VBox/Runtime/include/internal/dbgmod.h
index 900052444..ae9c3ca74 100644
--- a/src/VBox/Runtime/include/internal/dbgmod.h
+++ b/src/VBox/Runtime/include/internal/dbgmod.h
@@ -1,4 +1,4 @@
-/* $Id: dbgmod.h $ */
+/* $Id: dbgmod.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Internal Header for RTDbgMod and the associated interpreters.
*/
diff --git a/src/VBox/Runtime/include/internal/dir.h b/src/VBox/Runtime/include/internal/dir.h
index 987fe32a0..57a5d1f14 100644
--- a/src/VBox/Runtime/include/internal/dir.h
+++ b/src/VBox/Runtime/include/internal/dir.h
@@ -1,4 +1,4 @@
-/* $Id: dir.h $ */
+/* $Id: dir.h 28918 2010-04-29 18:30:09Z vboxsync $ */
/** @file
* IPRT - Internal Header for RTDir.
*/
diff --git a/src/VBox/Runtime/include/internal/dvm.h b/src/VBox/Runtime/include/internal/dvm.h
new file mode 100644
index 000000000..6b9cdd612
--- /dev/null
+++ b/src/VBox/Runtime/include/internal/dvm.h
@@ -0,0 +1,286 @@
+/* $Id: dvm.h 37270 2011-05-30 21:25:42Z vboxsync $ */
+/** @file
+ * IPRT - Disk Volume Management Internals.
+ */
+
+/*
+ * Copyright (C) 2006-2007 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.
+ */
+
+#ifndef ___internal_dvm_h
+#define ___internal_dvm_h
+
+#include <iprt/types.h>
+#include <iprt/err.h>
+#include <iprt/assert.h>
+#include "internal/magics.h"
+
+RT_C_DECLS_BEGIN
+
+/** Format specific volume manager handle. */
+typedef struct RTDVMFMTINTERNAL *RTDVMFMT;
+/** Pointer to a format specific volume manager handle. */
+typedef RTDVMFMT *PRTDVMFMT;
+/** NIL volume manager handle. */
+#define NIL_RTDVMFMT ((RTDVMFMT)~0)
+
+/** Format specific volume data handle. */
+typedef struct RTDVMVOLUMEFMTINTERNAL *RTDVMVOLUMEFMT;
+/** Pointer to a format specific volume data handle. */
+typedef RTDVMVOLUMEFMT *PRTDVMVOLUMEFMT;
+/** NIL volume handle. */
+#define NIL_RTDVMVOLUMEFMT ((RTDVMVOLUMEFMT)~0)
+
+/**
+ * Disk descriptor.
+ */
+typedef struct RTDVMDISK
+{
+ /** Size of the disk in bytes. */
+ uint64_t cbDisk;
+ /** Sector size. */
+ uint64_t cbSector;
+ /** Read callback */
+ PFNDVMREAD pfnRead;
+ /** Write callback. */
+ PFNDVMWRITE pfnWrite;
+ /** Opaque user data. */
+ void *pvUser;
+} RTDVMDISK;
+/** Pointer to a disk descriptor. */
+typedef RTDVMDISK *PRTDVMDISK;
+/** Pointer to a const descriptor. */
+typedef const RTDVMDISK *PCRTDVMDISK;
+
+/** Score to indicate that the backend can't handle the format at all */
+#define RTDVM_MATCH_SCORE_UNSUPPORTED 0
+/** Score to indicate that a backend supports the format
+ * but there can be other backends. */
+#define RTDVM_MATCH_SCORE_SUPPORTED (UINT32_MAX/2)
+/** Score to indicate a perfect match. */
+#define RTDVM_MATCH_SCORE_PERFECT UINT32_MAX
+
+/**
+ * Volume format operations.
+ */
+typedef struct RTDVMFMTOPS
+{
+ /** Name of the format. */
+ const char *pcszFmt;
+
+ /**
+ * Probes the given disk for known structures.
+ *
+ * @returns IPRT status code.
+ * @param pDisk Disk descriptor.
+ * @param puScore Where to store the match score on success.
+ */
+ DECLCALLBACKMEMBER(int, pfnProbe)(PCRTDVMDISK pDisk, uint32_t *puScore);
+
+ /**
+ * Opens the format to set up all structures.
+ *
+ * @returns IPRT status code.
+ * @param pDisk The disk descriptor.
+ * @param phVolMgrFmt Where to store the volume format data on success.
+ */
+ DECLCALLBACKMEMBER(int, pfnOpen)(PCRTDVMDISK pDisk, PRTDVMFMT phVolMgrFmt);
+
+ /**
+ * Initializes a new volume map.
+ *
+ * @returns IPRT status code.
+ * @param pDisk The disk descriptor.
+ * @param phVolMgrFmt Where to store the volume format data on success.
+ */
+ DECLCALLBACKMEMBER(int, pfnInitialize)(PCRTDVMDISK pDisk, PRTDVMFMT phVolMgrFmt);
+
+ /**
+ * Closes the volume format.
+ *
+ * @returns nothing.
+ * @param hVolMgrFmt The format specific volume manager handle.
+ */
+ DECLCALLBACKMEMBER(void, pfnClose)(RTDVMFMT hVolMgrFmt);
+
+ /**
+ * Gets the number of valid volumes in the map.
+ *
+ * @returns Number of valid volumes in the map or UINT32_MAX on failure.
+ * @param hVolMgrFmt The format specific volume manager handle.
+ */
+ DECLCALLBACKMEMBER(uint32_t, pfnGetValidVolumes)(RTDVMFMT hVolMgrFmt);
+
+ /**
+ * Gets the maximum number of volumes the map can have.
+ *
+ * @returns Maximum number of volumes in the map or 0 on failure.
+ * @param hVolMgrFmt The format specific volume manager handle.
+ */
+ DECLCALLBACKMEMBER(uint32_t, pfnGetMaxVolumes)(RTDVMFMT hVolMgrFmt);
+
+ /**
+ * Get the first valid volume from a map.
+ *
+ * @returns IPRT status code.
+ * @param hVolMgrFmt The format specific volume manager handle.
+ * @param phVolFmt Where to store the volume handle to the first volume
+ * on success.
+ */
+ DECLCALLBACKMEMBER(int, pfnQueryFirstVolume)(RTDVMFMT hVolMgrFmt, PRTDVMVOLUMEFMT phVolFmt);
+
+ /**
+ * Get the first valid volume from a map.
+ *
+ * @returns IPRT status code.
+ * @param hVolMgrFmt The format specific volume manager handle.
+ * @param hVolFmt The current volume.
+ * @param phVolFmtNext Where to store the handle to the format specific
+ * volume data of the next volume on success.
+ */
+ DECLCALLBACKMEMBER(int, pfnQueryNextVolume)(RTDVMFMT hVolMgrFmt, RTDVMVOLUMEFMT hVolFmt, PRTDVMVOLUMEFMT phVolFmtNext);
+
+ /**
+ * Closes a volume handle.
+ *
+ * @returns nothing.
+ * @param hVolFmt The format specific volume handle.
+ */
+ DECLCALLBACKMEMBER(void, pfnVolumeClose)(RTDVMVOLUMEFMT hVolFmt);
+
+ /**
+ * Gets the size of the given volume.
+ *
+ * @returns Size of the volume in bytes or 0 on failure.
+ * @param hVolFmt The format specific volume handle.
+ */
+ DECLCALLBACKMEMBER(uint64_t, pfnVolumeGetSize)(RTDVMVOLUMEFMT hVolFmt);
+
+ /**
+ * Queries the name of the given volume.
+ *
+ * @returns IPRT status code.
+ * @param hVolFmt The format specific volume handle.
+ * @param ppszVolname Where to store the name of the volume on success.
+ */
+ DECLCALLBACKMEMBER(int, pfnVolumeQueryName)(RTDVMVOLUMEFMT hVolFmt, char **ppszVolName);
+
+ /**
+ * Get the type of the given volume.
+ *
+ * @returns The volume type on success, DVMVOLTYPE_INVALID if hVol is invalid.
+ * @param hVolFmt The format specific volume handle.
+ */
+ DECLCALLBACKMEMBER(RTDVMVOLTYPE, pfnVolumeGetType)(RTDVMVOLUMEFMT hVolFmt);
+
+ /**
+ * Get the flags of the given volume.
+ *
+ * @returns The volume flags or UINT64_MAX on failure.
+ * @param hVolFmt The format specific volume handle.
+ */
+ DECLCALLBACKMEMBER(uint64_t, pfnVolumeGetFlags)(RTDVMVOLUMEFMT hVolFmt);
+
+ /**
+ * Read data from the given volume.
+ *
+ * @returns IPRT status code.
+ * @param hVolFmt The format specific volume handle.
+ * @param off Where to start reading from.
+ * @param pvBuf Where to store the read data.
+ * @param cbRead How many bytes to read.
+ */
+ DECLCALLBACKMEMBER(int, pfnVolumeRead)(RTDVMVOLUMEFMT hVolFmt, uint64_t off, void *pvBuf, size_t cbRead);
+
+ /**
+ * Write data to the given volume.
+ *
+ * @returns IPRT status code.
+ * @param hVolFmt The format specific volume handle.
+ * @param off Where to start writing to.
+ * @param pvBuf The data to write.
+ * @param cbWrite How many bytes to write.
+ */
+ DECLCALLBACKMEMBER(int, pfnVolumeWrite)(RTDVMVOLUMEFMT hVolFmt, uint64_t off, const void *pvBuf, size_t cbWrite);
+
+} RTDVMFMTOPS;
+/** Pointer to a DVM ops table. */
+typedef RTDVMFMTOPS *PRTDVMFMTOPS;
+/** Pointer to a const DVM ops table. */
+typedef const RTDVMFMTOPS *PCRTDVMFMTOPS;
+
+/** Converts a LBA number to the byte offset. */
+#define RTDVM_LBA2BYTE(lba, disk) ((lba) * (disk)->cbSector)
+/** Converts a Byte offset to the LBA number. */
+#define RTDVM_BYTE2LBA(off, disk) ((off) / (disk)->cbSector)
+
+/**
+ * Returns the number of sectors in the disk.
+ *
+ * @returns Number of sectors.
+ * @param pDisk The disk descriptor.
+ */
+DECLINLINE(uint64_t) rtDvmDiskGetSectors(PCRTDVMDISK pDisk)
+{
+ return pDisk->cbDisk / pDisk->cbSector;
+}
+
+/**
+ * Read from the disk at the given offset.
+ *
+ * @returns IPRT status code.
+ * @param pDisk The disk descriptor to read from.
+ * @param off Start offset.
+ * @param pvBuf Destination buffer.
+ * @param cbRead How much to read.
+ */
+DECLINLINE(int) rtDvmDiskRead(PCRTDVMDISK pDisk, uint64_t off, void *pvBuf, size_t cbRead)
+{
+ AssertPtrReturn(pDisk, VERR_INVALID_POINTER);
+ AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
+ AssertReturn(cbRead > 0, VERR_INVALID_PARAMETER);
+ AssertReturn(off + cbRead <= pDisk->cbDisk, VERR_INVALID_PARAMETER);
+
+ return pDisk->pfnRead(pDisk->pvUser, off, pvBuf, cbRead);
+}
+
+/**
+ * Write to the disk at the given offset.
+ *
+ * @returns IPRT status code.
+ * @param pDisk The disk descriptor to write to.
+ * @param off Start offset.
+ * @param pvBuf Source buffer.
+ * @param cbWrite How much to write.
+ */
+DECLINLINE(int) rtDvmDiskWrite(PCRTDVMDISK pDisk, uint64_t off, const void *pvBuf, size_t cbWrite)
+{
+ AssertPtrReturn(pDisk, VERR_INVALID_POINTER);
+ AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
+ AssertReturn(cbWrite > 0, VERR_INVALID_PARAMETER);
+ AssertReturn(off + cbWrite <= pDisk->cbDisk, VERR_INVALID_PARAMETER);
+
+ return pDisk->pfnWrite(pDisk->pvUser, off, pvBuf, cbWrite);
+}
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/src/VBox/Runtime/include/internal/file.h b/src/VBox/Runtime/include/internal/file.h
index c55efb89d..2541d7a73 100644
--- a/src/VBox/Runtime/include/internal/file.h
+++ b/src/VBox/Runtime/include/internal/file.h
@@ -1,4 +1,4 @@
-/* $Id: file.h $ */
+/* $Id: file.h 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - Internal RTFile header.
*/
@@ -41,7 +41,19 @@ RT_C_DECLS_BEGIN
* Updated on successful return.
* @internal
*/
-int rtFileRecalcAndValidateFlags(uint32_t *pfOpen);
+int rtFileRecalcAndValidateFlags(uint64_t *pfOpen);
+
+
+/**
+ * Internal interface for getting the RTFILE handle of stdin, stdout or stderr.
+ *
+ * This interface will not be exposed and is purely for internal IPRT use.
+ *
+ * @returns Handle or NIL_RTFILE.
+ *
+ * @param enmStdHandle The standard handle.
+ */
+RTFILE rtFileGetStandard(RTHANDLESTD enmStdHandle);
RT_C_DECLS_END
diff --git a/src/VBox/Runtime/include/internal/fileaio.h b/src/VBox/Runtime/include/internal/fileaio.h
index 81172acc6..6ff4ced99 100644
--- a/src/VBox/Runtime/include/internal/fileaio.h
+++ b/src/VBox/Runtime/include/internal/fileaio.h
@@ -1,4 +1,4 @@
-/* $Id: fileaio.h $ */
+/* $Id: fileaio.h 29451 2010-05-13 15:38:48Z vboxsync $ */
/** @file
* IPRT - Internal RTFileAio header.
*/
diff --git a/src/VBox/Runtime/include/internal/fs.h b/src/VBox/Runtime/include/internal/fs.h
index f5ba04293..44fe99fd7 100644
--- a/src/VBox/Runtime/include/internal/fs.h
+++ b/src/VBox/Runtime/include/internal/fs.h
@@ -1,4 +1,4 @@
-/* $Id: fs.h $ */
+/* $Id: fs.h 34002 2010-11-11 17:16:37Z vboxsync $ */
/** @file
* IPRT - Internal RTFs header.
*/
diff --git a/src/VBox/Runtime/include/internal/initterm.h b/src/VBox/Runtime/include/internal/initterm.h
index 28817297d..dbd40f042 100644
--- a/src/VBox/Runtime/include/internal/initterm.h
+++ b/src/VBox/Runtime/include/internal/initterm.h
@@ -1,4 +1,4 @@
-/* $Id: initterm.h $ */
+/* $Id: initterm.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Initialization & Termination.
*/
@@ -38,12 +38,12 @@ RT_C_DECLS_BEGIN
*
* @returns IPRT status code.
*/
-int rtR0InitNative(void);
+DECLHIDDEN(int) rtR0InitNative(void);
/**
* Platform specific termination.
*/
-void rtR0TermNative(void);
+DECLHIDDEN(void) rtR0TermNative(void);
#endif /* IN_RING0 */
diff --git a/src/VBox/Runtime/include/internal/iprt.h b/src/VBox/Runtime/include/internal/iprt.h
index 74646cc21..98a8a9452 100644
--- a/src/VBox/Runtime/include/internal/iprt.h
+++ b/src/VBox/Runtime/include/internal/iprt.h
@@ -1,4 +1,4 @@
-/* $Id: iprt.h $ */
+/* $Id: iprt.h 35662 2011-01-20 18:11:08Z vboxsync $ */
/** @file
* IPRT - Internal header for miscellaneous global defs and types.
*/
diff --git a/src/VBox/Runtime/include/internal/ldr.h b/src/VBox/Runtime/include/internal/ldr.h
index cf51bee07..1274f60a1 100644
--- a/src/VBox/Runtime/include/internal/ldr.h
+++ b/src/VBox/Runtime/include/internal/ldr.h
@@ -1,4 +1,4 @@
-/* $Id: ldr.h $ */
+/* $Id: ldr.h 35183 2010-12-16 13:59:44Z vboxsync $ */
/** @file
* IPRT - Loader Internals.
*/
diff --git a/src/VBox/Runtime/include/internal/ldrELF.h b/src/VBox/Runtime/include/internal/ldrELF.h
index c52cd816a..f6d2d4009 100644
--- a/src/VBox/Runtime/include/internal/ldrELF.h
+++ b/src/VBox/Runtime/include/internal/ldrELF.h
@@ -1,4 +1,4 @@
-/* $Id: ldrELF.h $ */
+/* $Id: ldrELF.h 37560 2011-06-20 14:48:32Z vboxsync $ */
/** @file
* ELF types, current architecture.
*/
diff --git a/src/VBox/Runtime/include/internal/ldrELF32.h b/src/VBox/Runtime/include/internal/ldrELF32.h
index 0873357ec..8ad9b5594 100644
--- a/src/VBox/Runtime/include/internal/ldrELF32.h
+++ b/src/VBox/Runtime/include/internal/ldrELF32.h
@@ -1,4 +1,4 @@
-/* $Id: ldrELF32.h $ */
+/* $Id: ldrELF32.h 37560 2011-06-20 14:48:32Z vboxsync $ */
/** @file
* IPRT - ELF 32-bit header.
*/
diff --git a/src/VBox/Runtime/include/internal/ldrELF64.h b/src/VBox/Runtime/include/internal/ldrELF64.h
index 8a60fd9c5..6500731b6 100644
--- a/src/VBox/Runtime/include/internal/ldrELF64.h
+++ b/src/VBox/Runtime/include/internal/ldrELF64.h
@@ -1,4 +1,4 @@
-/* $Id: ldrELF64.h $ */
+/* $Id: ldrELF64.h 37560 2011-06-20 14:48:32Z vboxsync $ */
/** @file
* IPRT - ELF 64-bit header.
*/
diff --git a/src/VBox/Runtime/include/internal/ldrMZ.h b/src/VBox/Runtime/include/internal/ldrMZ.h
index c6c15c163..c598970ff 100644
--- a/src/VBox/Runtime/include/internal/ldrMZ.h
+++ b/src/VBox/Runtime/include/internal/ldrMZ.h
@@ -1,4 +1,4 @@
-/* $Id: ldrMZ.h $ */
+/* $Id: ldrMZ.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT, MZ header.
*/
diff --git a/src/VBox/Runtime/include/internal/ldrMach-O.h b/src/VBox/Runtime/include/internal/ldrMach-O.h
index c75ea6c3f..71b70e585 100644
--- a/src/VBox/Runtime/include/internal/ldrMach-O.h
+++ b/src/VBox/Runtime/include/internal/ldrMach-O.h
@@ -1,4 +1,4 @@
-/* $Id: ldrMach-O.h $ */
+/* $Id: ldrMach-O.h 37560 2011-06-20 14:48:32Z vboxsync $ */
/** @file
* IPRT - Mach-O Structures and Constants.
*/
diff --git a/src/VBox/Runtime/include/internal/ldrPE.h b/src/VBox/Runtime/include/internal/ldrPE.h
index 6b973a2cf..6e008f257 100644
--- a/src/VBox/Runtime/include/internal/ldrPE.h
+++ b/src/VBox/Runtime/include/internal/ldrPE.h
@@ -1,4 +1,4 @@
-/* $Id: ldrPE.h $ */
+/* $Id: ldrPE.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Windows NT PE Structures and Constants.
*/
diff --git a/src/VBox/Runtime/include/internal/lockvalidator.h b/src/VBox/Runtime/include/internal/lockvalidator.h
index 793e3ffff..0cc7796f2 100644
--- a/src/VBox/Runtime/include/internal/lockvalidator.h
+++ b/src/VBox/Runtime/include/internal/lockvalidator.h
@@ -1,4 +1,4 @@
-/* $Id: lockvalidator.h $ */
+/* $Id: lockvalidator.h 35499 2011-01-12 08:33:45Z vboxsync $ */
/** @file
* IPRT - Internal RTLockValidator header.
*/
diff --git a/src/VBox/Runtime/include/internal/magics.h b/src/VBox/Runtime/include/internal/magics.h
index 2ef040054..1afbb9d17 100644
--- a/src/VBox/Runtime/include/internal/magics.h
+++ b/src/VBox/Runtime/include/internal/magics.h
@@ -1,10 +1,10 @@
-/* $Id: magics.h $ */
+/* $Id: magics.h 37396 2011-06-09 15:48:59Z vboxsync $ */
/** @file
* IPRT - Internal header defining The Magic Numbers.
*/
/*
- * Copyright (C) 2007-2008 Oracle Corporation
+ * Copyright (C) 2007-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;
@@ -42,6 +42,14 @@
#define RTDIR_MAGIC UINT32_C(0x19291112)
/** The value of RTDIR::u32Magic after RTDirClose(). */
#define RTDIR_MAGIC_DEAD UINT32_C(0x19950829)
+/** The value of RTDVMINTERNAL::u32Magic. (Dan Brown) */
+#define RTDVM_MAGIC UINT32_C(0x19640622)
+/** The value of RTDVMINTERNAL::u32Magic after close. */
+#define RTDVM_MAGIC_DEAD (~RTDVM_MAGIC)
+/** The value of RTDVMVOLUMEINTERNAL::u32Magic. (Daniel Defoe) */
+#define RTDVMVOLUME_MAGIC UINT32_C(0x16591961)
+/** The value of RTDVMVOLUMEINTERNAL::u32Magic after close. */
+#define RTDVMVOLUME_MAGIC_DEAD UINT32_C(0x17310424)
/** The value of RTFILEAIOCTXINT::u32Magic. (Howard Phillips Lovecraft) */
#define RTFILEAIOCTX_MAGIC UINT32_C(0x18900820)
/** The value of RTFILEAIOCTXINT::u32Magic after RTFileAioCtxDestroy(). */
@@ -50,6 +58,8 @@
#define RTFILEAIOREQ_MAGIC UINT32_C(0x19470921)
/** The value of RTENVINTERNAL::u32Magic. (Rumiko Takahashi) */
#define RTENV_MAGIC UINT32_C(0x19571010)
+/** The value of RTERRVARS::ai32Vars[0]. (Ryuichi Sakamoto) */
+#define RTERRVARS_MAGIC UINT32_C(0x19520117)
/** Magic number for RTHANDLETABLEINT::u32Magic. (Hitomi Kanehara) */
#define RTHANDLETABLE_MAGIC UINT32_C(0x19830808)
/** Magic number for RTHEAPOFFSETINTERNAL::u32Magic. (Neal Town Stephenson) */
@@ -100,6 +110,10 @@
#define RTR0MEMOBJ_MAGIC UINT32_C(0x19611210)
/** RTRANDINT::u32Magic. (Alan Moore) */
#define RTRANDINT_MAGIC UINT32_C(0x19531118)
+/** The value of RTS3::u32Magic. (Edgar Wallace) */
+#define RTS3_MAGIC UINT32_C(0x18750401)
+/** The value of RTS3::u32Magic after RTS3Destroy(). */
+#define RTS3_MAGIC_DEAD UINT32_C(0x19320210)
/** Magic for the event semaphore structure. (Neil Gaiman) */
#define RTSEMEVENT_MAGIC UINT32_C(0x19601110)
/** Magic for the multiple release event semaphore structure. (Isaac Asimov) */
@@ -137,7 +151,17 @@
/** The value of RTSTREAM::u32Magic for a valid stream. */
#define RTSTREAM_MAGIC UINT32_C(0xe44e44ee)
/** Magic value for RTTCPSERVER::u32Magic. (Jan Garbarek) */
-#define RTTCPSERVER_MAGIC UINT32_C(0x19540304)
+#define RTTCPSERVER_MAGIC UINT32_C(0x19470304)
+/** Magic value for RTTCPSERVER::u32Magic. (Harlan Ellison) */
+#define RTUDPSERVER_MAGIC UINT32_C(0x19340527)
+/** The value of RTTAR::u32Magic. (Donald Ervin Knuth) */
+#define RTTAR_MAGIC UINT32_C(0x19380110)
+/** The value of RTTAR::u32Magic after RTTarClose(). */
+#define RTTAR_MAGIC_DEAD ~RTTAR_MAGIC
+/** The value of RTTARFILE::u32Magic. (Abraham Stoker) */
+#define RTTARFILE_MAGIC UINT32_C(0x18471108)
+/** The value of RTTARFILE::u32Magic after RTTarFileClose(). */
+#define RTTARFILE_MAGIC_DEAD UINT32_C(0x19120420)
/** RTTESTINT::u32Magic value. (Daniel Kehlmann) */
#define RTTESTINT_MAGIC UINT32_C(0x19750113)
/** RTTHREADINT::u32Magic value. (Gilbert Keith Chesterton) */
@@ -148,18 +172,10 @@
#define RTTIMER_MAGIC UINT32_C(0x19370910)
/** Magic number for timer low resolution handles. (Saki Hiwatari) */
#define RTTIMERLR_MAGIC UINT32_C(0x19610715)
-/** The value of RTS3::u32Magic. (Edgar Wallace) */
-#define RTS3_MAGIC UINT32_C(0x18750401)
-/** The value of RTS3::u32Magic after RTS3Destroy(). */
-#define RTS3_MAGIC_DEAD UINT32_C(0x19320210)
-/** The value of RTTAR::u32Magic. (Donald Ervin Knuth) */
-#define RTTAR_MAGIC UINT32_C(0x19380110)
-/** The value of RTTAR::u32Magic after RTTarClose(). */
-#define RTTAR_MAGIC_DEAD ~RTTAR_MAGIC
-/** The value of RTTARFILE::u32Magic. (Abraham Stoker) */
-#define RTTARFILE_MAGIC UINT32_C(0x18471108)
-/** The value of RTTARFILE::u32Magic after RTTarFileClose(). */
-#define RTTARFILE_MAGIC_DEAD UINT32_C(0x19120420)
+/** Magic value of RTTRACEBUFINT::u32Magic. (George Orwell) */
+#define RTTRACEBUF_MAGIC UINT32_C(0x19030625)
+/** Magic value of RTTRACEBUFINT::u32Magic after the final release. */
+#define RTTRACEBUF_MAGIC_DEAD UINT32_C(0x19500121)
/** The value of RTVFSOBJINTERNAL::u32Magic. (Yasunari Kawabata) */
#define RTVFSOBJ_MAGIC UINT32_C(0x18990614)
/** The value of RTVFSOBJINTERNAL::u32Magic arter close. */
diff --git a/src/VBox/Runtime/include/internal/mem.h b/src/VBox/Runtime/include/internal/mem.h
index 0db465133..aa9b3c6d4 100644
--- a/src/VBox/Runtime/include/internal/mem.h
+++ b/src/VBox/Runtime/include/internal/mem.h
@@ -1,4 +1,4 @@
-/* $Id: mem.h $ */
+/* $Id: mem.h 33676 2010-11-02 09:48:24Z vboxsync $ */
/** @file
* IPRT - Memory Management.
*/
diff --git a/src/VBox/Runtime/include/internal/memobj.h b/src/VBox/Runtime/include/internal/memobj.h
index 1deff6f9e..a6c0ae997 100644
--- a/src/VBox/Runtime/include/internal/memobj.h
+++ b/src/VBox/Runtime/include/internal/memobj.h
@@ -1,10 +1,10 @@
-/* $Revision: 67140 $ */
+/* $Id: memobj.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Ring-0 Memory Objects.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -287,7 +287,7 @@ DECLINLINE(bool) rtR0MemObjIsRing3(PRTR0MEMOBJINTERNAL pMem)
* @returns IPRT status code. On failure it is assumed that the object remains valid.
* @param pMem The ring-0 memory object handle to the memory which should be freed.
*/
-int rtR0MemObjNativeFree(PRTR0MEMOBJINTERNAL pMem);
+DECLHIDDEN(int) rtR0MemObjNativeFree(PRTR0MEMOBJINTERNAL pMem);
/**
* Allocates page aligned virtual kernel memory.
@@ -299,7 +299,7 @@ int rtR0MemObjNativeFree(PRTR0MEMOBJINTERNAL pMem);
* @param cb Number of bytes to allocate, page aligned.
* @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object.
*/
-int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable);
+DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable);
/**
* Allocates page aligned virtual kernel memory with physical backing below 4GB.
@@ -311,7 +311,7 @@ int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecu
* @param cb Number of bytes to allocate, page aligned.
* @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object.
*/
-int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable);
+DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable);
/**
* Allocates page aligned virtual kernel memory with contiguous physical backing below 4GB.
@@ -323,7 +323,7 @@ int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecut
* @param cb Number of bytes to allocate, page aligned.
* @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object.
*/
-int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable);
+DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable);
/**
* Locks a range of user virtual memory.
@@ -336,7 +336,7 @@ int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecu
* and RTMEM_PROT_WRITE.
* @param R0Process The process to lock pages in.
*/
-int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process);
+DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process);
/**
* Locks a range of kernel virtual memory.
@@ -348,7 +348,7 @@ int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t c
* @param fAccess The desired access, a combination of RTMEM_PROT_READ
* and RTMEM_PROT_WRITE.
*/
-int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess);
+DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess);
/**
* Allocates contiguous page aligned physical memory without (necessarily) any
@@ -362,7 +362,7 @@ int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb,
* @param uAlignment The alignment of the reserved memory.
* Supported values are PAGE_SIZE, _2M, _4M and _1G.
*/
-int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment);
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment);
/**
* Allocates non-contiguous page aligned physical memory without (necessarily) any kernel mapping.
@@ -375,7 +375,7 @@ int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS Ph
* @param PhysHighest The highest permitable address (inclusive).
* NIL_RTHCPHYS if any address is acceptable.
*/
-int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest);
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest);
/**
* Creates a page aligned, contiguous, physical memory object.
@@ -386,7 +386,7 @@ int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS
* @param cb The size of the object in bytes, page aligned.
* @param uCachePolicy One of the RTMEM_CACHE_XXX modes.
*/
-int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy);
+DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy);
/**
* Reserves kernel virtual address space.
@@ -398,7 +398,7 @@ int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t
* @param cb The number of bytes to reserve, page aligned.
* @param uAlignment The alignment of the reserved memory; PAGE_SIZE, _2M or _4M.
*/
-int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment);
+DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment);
/**
* Reserves user virtual address space in the current process.
@@ -410,7 +410,7 @@ int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, siz
* @param uAlignment The alignment of the reserved memory; PAGE_SIZE, _2M or _4M.
* @param R0Process The process to reserve the memory in.
*/
-int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process);
+DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process);
/**
* Maps a memory object into user virtual address space in the current process.
@@ -430,8 +430,8 @@ int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed,
* zero the entire object is mapped. The value must be
* page aligned.
*/
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
- unsigned fProt, size_t offSub, size_t cbSub);
+DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+ unsigned fProt, size_t offSub, size_t cbSub);
/**
* Maps a memory object into user virtual address space in the current process.
@@ -444,7 +444,7 @@ int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap,
* @param fProt Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
* @param R0Process The process to map the memory into.
*/
-int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, PRTR0MEMOBJINTERNAL pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process);
+DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, PRTR0MEMOBJINTERNAL pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process);
/**
* Change the page level protection of one or more pages in a memory object.
@@ -458,7 +458,7 @@ int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, PRTR0MEMOBJINTERNAL pMem
* aligned.
* @param fProt Combination of RTMEM_PROT_* flags.
*/
-int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt);
+DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt);
/**
* Get the physical address of an page in the memory object.
@@ -470,10 +470,10 @@ int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSu
* @param pMem The ring-0 memory object handle.
* @param iPage The page number within the object (valid).
*/
-RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage);
+DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage);
-PRTR0MEMOBJINTERNAL rtR0MemObjNew(size_t cbSelf, RTR0MEMOBJTYPE enmType, void *pv, size_t cb);
-void rtR0MemObjDelete(PRTR0MEMOBJINTERNAL pMem);
+DECLHIDDEN(PRTR0MEMOBJINTERNAL) rtR0MemObjNew(size_t cbSelf, RTR0MEMOBJTYPE enmType, void *pv, size_t cb);
+DECLHIDDEN(void) rtR0MemObjDelete(PRTR0MEMOBJINTERNAL pMem);
/** @} */
diff --git a/src/VBox/Runtime/include/internal/path.h b/src/VBox/Runtime/include/internal/path.h
index a1cdb1eed..4c2d6de1b 100644
--- a/src/VBox/Runtime/include/internal/path.h
+++ b/src/VBox/Runtime/include/internal/path.h
@@ -1,4 +1,4 @@
-/* $Id: path.h $ */
+/* $Id: path.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - RTPath Internal header.
*/
diff --git a/src/VBox/Runtime/include/internal/pipe.h b/src/VBox/Runtime/include/internal/pipe.h
index e5566d4f3..ec40772c8 100644
--- a/src/VBox/Runtime/include/internal/pipe.h
+++ b/src/VBox/Runtime/include/internal/pipe.h
@@ -1,4 +1,4 @@
-/* $Id: pipe.h $ */
+/* $Id: pipe.h 32131 2010-08-31 11:55:27Z vboxsync $ */
/** @file
* IPRT - Internal RTPipe header.
*/
diff --git a/src/VBox/Runtime/include/internal/process.h b/src/VBox/Runtime/include/internal/process.h
index 463368008..915d243af 100644
--- a/src/VBox/Runtime/include/internal/process.h
+++ b/src/VBox/Runtime/include/internal/process.h
@@ -1,4 +1,4 @@
-/* $Id: process.h $ */
+/* $Id: process.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Internal RTProc header.
*/
@@ -32,12 +32,13 @@
RT_C_DECLS_BEGIN
-extern RTPROCESS g_ProcessSelf;
-extern RTPROCPRIORITY g_enmProcessPriority;
-extern char g_szrtProcExePath[RTPATH_MAX];
-extern size_t g_cchrtProcExePath;
-extern size_t g_cchrtProcDir;
-extern size_t g_offrtProcName;
+extern DECLHIDDEN(RTPROCESS) g_ProcessSelf;
+extern DECLHIDDEN(RTPROCPRIORITY) g_enmProcessPriority;
+extern DECLHIDDEN(char) g_szrtProcExePath[RTPATH_MAX];
+extern DECLHIDDEN(size_t) g_cchrtProcExePath;
+extern DECLHIDDEN(size_t) g_cchrtProcDir;
+extern DECLHIDDEN(size_t) g_offrtProcName;
+extern DECLHIDDEN(bool volatile) g_frtAtExitCalled;
/**
* Validates and sets the process priority.
@@ -48,7 +49,7 @@ extern size_t g_offrtProcName;
* @param enmPriority The priority to validate and set.
* @remark Located in sched.
*/
-int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority);
+DECLHIDDEN(int) rtProcNativeSetPriority(RTPROCPRIORITY enmPriority);
/**
* Determines the full path to the executable image.
diff --git a/src/VBox/Runtime/include/internal/rand.h b/src/VBox/Runtime/include/internal/rand.h
index 2a7522c48..f0d0c8ddf 100644
--- a/src/VBox/Runtime/include/internal/rand.h
+++ b/src/VBox/Runtime/include/internal/rand.h
@@ -1,4 +1,4 @@
-/* $Id: rand.h $ */
+/* $Id: rand.h 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - Internal RTRand header
*/
@@ -149,8 +149,8 @@ typedef struct RTRANDINT
struct RTRandFile
{
- /** The file handle. */
- RTFILE hFile;
+ /** The file handle (native). */
+ intptr_t hFile;
} File;
} u;
} RTRANDINT;
@@ -158,32 +158,16 @@ typedef struct RTRANDINT
RT_C_DECLS_BEGIN
-/**
- * Initialize OS facilities for generating random bytes.
- */
-void rtRandLazyInitNative(void);
-
-/**
- * Generate random bytes using OS facilities.
- *
- * @returns VINF_SUCCESS on success, some error status code on failure.
- * @param pv Where to store the random bytes.
- * @param cb How many random bytes to store.
- */
-int rtRandGenBytesNative(void *pv, size_t cb);
-
-void rtRandGenBytesFallback(void *pv, size_t cb) RT_NO_THROW;
-
-DECLCALLBACK(void) rtRandAdvSynthesizeBytesFromU32(PRTRANDINT pThis, uint8_t *pb, size_t cb);
-DECLCALLBACK(void) rtRandAdvSynthesizeBytesFromU64(PRTRANDINT pThis, uint8_t *pb, size_t cb);
-DECLCALLBACK(uint32_t) rtRandAdvSynthesizeU32FromBytes(PRTRANDINT pThis, uint32_t u32First, uint32_t u32Last);
-DECLCALLBACK(uint32_t) rtRandAdvSynthesizeU32FromU64(PRTRANDINT pThis, uint32_t u32First, uint32_t u32Last);
-DECLCALLBACK(uint64_t) rtRandAdvSynthesizeU64FromBytes(PRTRANDINT pThis, uint64_t u64First, uint64_t u64Last);
-DECLCALLBACK(uint64_t) rtRandAdvSynthesizeU64FromU32(PRTRANDINT pThis, uint64_t u64First, uint64_t u64Last);
-DECLCALLBACK(int) rtRandAdvStubSeed(PRTRANDINT pThis, uint64_t u64Seed);
-DECLCALLBACK(int) rtRandAdvStubSaveState(PRTRANDINT pThis, char *pszState, size_t *pcbState);
-DECLCALLBACK(int) rtRandAdvStubRestoreState(PRTRANDINT pThis, char const *pszState);
-DECLCALLBACK(int) rtRandAdvDefaultDestroy(PRTRANDINT pThis);
+DECLHIDDEN(DECLCALLBACK(void)) rtRandAdvSynthesizeBytesFromU32(PRTRANDINT pThis, uint8_t *pb, size_t cb);
+DECLHIDDEN(DECLCALLBACK(void)) rtRandAdvSynthesizeBytesFromU64(PRTRANDINT pThis, uint8_t *pb, size_t cb);
+DECLHIDDEN(DECLCALLBACK(uint32_t)) rtRandAdvSynthesizeU32FromBytes(PRTRANDINT pThis, uint32_t u32First, uint32_t u32Last);
+DECLHIDDEN(DECLCALLBACK(uint32_t)) rtRandAdvSynthesizeU32FromU64(PRTRANDINT pThis, uint32_t u32First, uint32_t u32Last);
+DECLHIDDEN(DECLCALLBACK(uint64_t)) rtRandAdvSynthesizeU64FromBytes(PRTRANDINT pThis, uint64_t u64First, uint64_t u64Last);
+DECLHIDDEN(DECLCALLBACK(uint64_t)) rtRandAdvSynthesizeU64FromU32(PRTRANDINT pThis, uint64_t u64First, uint64_t u64Last);
+DECLHIDDEN(DECLCALLBACK(int)) rtRandAdvStubSeed(PRTRANDINT pThis, uint64_t u64Seed);
+DECLHIDDEN(DECLCALLBACK(int)) rtRandAdvStubSaveState(PRTRANDINT pThis, char *pszState, size_t *pcbState);
+DECLHIDDEN(DECLCALLBACK(int)) rtRandAdvStubRestoreState(PRTRANDINT pThis, char const *pszState);
+DECLHIDDEN(DECLCALLBACK(int)) rtRandAdvDefaultDestroy(PRTRANDINT pThis);
RT_C_DECLS_END
diff --git a/src/VBox/Runtime/include/internal/sched.h b/src/VBox/Runtime/include/internal/sched.h
index af7fe7cfa..6cb62bcc4 100644
--- a/src/VBox/Runtime/include/internal/sched.h
+++ b/src/VBox/Runtime/include/internal/sched.h
@@ -1,4 +1,4 @@
-/* $Id: sched.h $ */
+/* $Id: sched.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Internal RTSched header.
*/
@@ -40,7 +40,7 @@ RT_C_DECLS_BEGIN
* @returns iprt status code.
* @param enmType The thread type to be assumed for the current thread.
*/
-int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType);
+DECLHIDDEN(int) rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType);
RT_C_DECLS_END
diff --git a/src/VBox/Runtime/include/internal/socket.h b/src/VBox/Runtime/include/internal/socket.h
index 3a7882a88..ec6699780 100644
--- a/src/VBox/Runtime/include/internal/socket.h
+++ b/src/VBox/Runtime/include/internal/socket.h
@@ -1,4 +1,4 @@
-/* $Id: socket.h $ */
+/* $Id: socket.h 32131 2010-08-31 11:55:27Z vboxsync $ */
/** @file
* IPRT - Internal Header for RTSocket.
*/
diff --git a/src/VBox/Runtime/include/internal/strhash.h b/src/VBox/Runtime/include/internal/strhash.h
new file mode 100644
index 000000000..b26096489
--- /dev/null
+++ b/src/VBox/Runtime/include/internal/strhash.h
@@ -0,0 +1,94 @@
+/* $Id: strhash.h 36597 2011-04-06 19:46:15Z vboxsync $ */
+/** @file
+ * IPRT - Internal header containing inline string hashing functions.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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.
+ */
+
+#ifndef ___internal_strhash_h
+#define ___internal_strhash_h
+
+#include <iprt/types.h>
+
+
+/* sdbm:
+ This algorithm was created for sdbm (a public-domain reimplementation of
+ ndbm) database library. it was found to do well in scrambling bits,
+ causing better distribution of the keys and fewer splits. it also happens
+ to be a good general hashing function with good distribution. the actual
+ function is hash(i) = hash(i - 1) * 65599 + str[i]; what is included below
+ is the faster version used in gawk. [there is even a faster, duff-device
+ version] the magic constant 65599 was picked out of thin air while
+ experimenting with different constants, and turns out to be a prime.
+ this is one of the algorithms used in berkeley db (see sleepycat) and
+ elsewhere. */
+
+/**
+ * Hash string, return hash + length.
+ */
+DECLINLINE(uint32_t) sdbm(const char *str, size_t *pcch)
+{
+ uint8_t *pu8 = (uint8_t *)str;
+ uint32_t hash = 0;
+ int c;
+
+ while ((c = *pu8++))
+ hash = c + (hash << 6) + (hash << 16) - hash;
+
+ *pcch = (uintptr_t)pu8 - (uintptr_t)str - 1;
+ return hash;
+}
+
+
+/**
+ * Hash up to N bytes, return hash + hashed length.
+ */
+DECLINLINE(uint32_t) sdbmN(const char *str, size_t cchMax, size_t *pcch)
+{
+ uint8_t *pu8 = (uint8_t *)str;
+ uint32_t hash = 0;
+ int c;
+
+ while ((c = *pu8++) && cchMax-- > 0)
+ hash = c + (hash << 6) + (hash << 16) - hash;
+
+ *pcch = (uintptr_t)pu8 - (uintptr_t)str - 1;
+ return hash;
+}
+
+/**
+ * Incremental hashing.
+ */
+DECLINLINE(uint32_t) sdbmInc(const char *str, uint32_t hash)
+{
+ uint8_t *pu8 = (uint8_t *)str;
+ int c;
+
+ while ((c = *pu8++))
+ hash = c + (hash << 6) + (hash << 16) - hash;
+
+ return hash;
+}
+
+
+#endif
+
diff --git a/src/VBox/Runtime/include/internal/strict.h b/src/VBox/Runtime/include/internal/strict.h
index eed9a33c2..7dcd11ba1 100644
--- a/src/VBox/Runtime/include/internal/strict.h
+++ b/src/VBox/Runtime/include/internal/strict.h
@@ -1,4 +1,4 @@
-/* $Id: strict.h $ */
+/* $Id: strict.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Internal Header Defining Strictness Indicators.
*/
diff --git a/src/VBox/Runtime/include/internal/string.h b/src/VBox/Runtime/include/internal/string.h
index 0cf3b54df..eb57f927d 100644
--- a/src/VBox/Runtime/include/internal/string.h
+++ b/src/VBox/Runtime/include/internal/string.h
@@ -1,4 +1,4 @@
-/* $Id: string.h $ */
+/* $Id: string.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Internal RTStr header.
*/
@@ -47,14 +47,14 @@ RT_C_DECLS_BEGIN
# define RTStrAssertMsgReturn(expr, msg, rc) do { if (!(expr)) return rc; } while (0)
#endif
-size_t rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs,
- int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize);
-size_t rtstrFormatType(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs,
- int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize);
+DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs,
+ int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize);
+DECLHIDDEN(size_t) rtstrFormatType(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs,
+ int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize);
#ifdef RT_WITH_ICONV_CACHE
-void rtStrIconvCacheInit(struct RTTHREADINT *pThread);
-void rtStrIconvCacheDestroy(struct RTTHREADINT *pThread);
+DECLHIDDEN(void) rtStrIconvCacheInit(struct RTTHREADINT *pThread);
+DECLHIDDEN(void) rtStrIconvCacheDestroy(struct RTTHREADINT *pThread);
#endif
/**
@@ -74,11 +74,11 @@ typedef enum RTSTRICONV
RTSTRICONV_END
} RTSTRICONV;
-int rtStrConvert(const char *pchInput, size_t cchInput, const char *pszInputCS,
- char **ppszOutput, size_t cbOutput, const char *pszOutputCS,
- unsigned cFactor, RTSTRICONV enmCacheIdx);
-const char *rtStrGetLocaleCodeset(void);
-int rtUtf8Length(const char *psz, size_t cch, size_t *pcuc, size_t *pcchActual);
+DECLHIDDEN(int) rtStrConvert(const char *pchInput, size_t cchInput, const char *pszInputCS,
+ char **ppszOutput, size_t cbOutput, const char *pszOutputCS,
+ unsigned cFactor, RTSTRICONV enmCacheIdx);
+DECLHIDDEN(const char *) rtStrGetLocaleCodeset(void);
+DECLHIDDEN(int) rtUtf8Length(const char *psz, size_t cch, size_t *pcuc, size_t *pcchActual);
RT_C_DECLS_END
diff --git a/src/VBox/Runtime/include/internal/thread.h b/src/VBox/Runtime/include/internal/thread.h
index c39dc8c00..37b3e4719 100644
--- a/src/VBox/Runtime/include/internal/thread.h
+++ b/src/VBox/Runtime/include/internal/thread.h
@@ -1,4 +1,4 @@
-/* $Id: thread.h $ */
+/* $Id: thread.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Internal RTThread header.
*/
@@ -137,7 +137,7 @@ typedef RTTHREADINT *PRTTHREADINT;
*
* @returns iprt status code.
*/
-int rtThreadNativeInit(void);
+DECLHIDDEN(int) rtThreadNativeInit(void);
/**
* Create a native thread.
@@ -147,7 +147,7 @@ int rtThreadNativeInit(void);
* @param pThreadInt The thread data structure for the thread.
* @param pNativeThread Where to store the native thread identifier.
*/
-int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread);
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread);
/**
* Adopts a thread, this is called immediately after allocating the
@@ -155,7 +155,7 @@ int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
*
* @param pThread Pointer to the thread structure.
*/
-int rtThreadNativeAdopt(PRTTHREADINT pThread);
+DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread);
/**
* Called from rtThreadDestroy so that the TLS entry and any native data in the
@@ -163,7 +163,7 @@ int rtThreadNativeAdopt(PRTTHREADINT pThread);
*
* @param pThread The thread structure.
*/
-void rtThreadNativeDestroy(PRTTHREADINT pThread);
+DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread);
/**
* Sets the priority of the thread according to the thread type
@@ -177,7 +177,7 @@ void rtThreadNativeDestroy(PRTTHREADINT pThread);
* @param enmType The thread type.
* @remark Located in sched.
*/
-int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType);
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType);
#ifdef IN_RING3
# ifdef RT_OS_WINDOWS
@@ -187,29 +187,26 @@ int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType);
* It give the Win32/64 backend a chance to terminate alien
* threads properly.
*/
-void rtThreadNativeDetach(void);
+DECLHIDDEN(void) rtThreadNativeDetach(void);
# endif
#endif /* !IN_RING0 */
/* thread.cpp */
-int rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *pszThreadName);
-void rtThreadBlocking(PRTTHREADINT pThread, RTTHREADSTATE enmState, uint64_t u64Block,
- const char *pszFile, unsigned uLine, RTUINTPTR uId);
-void rtThreadUnblocked(PRTTHREADINT pThread, RTTHREADSTATE enmCurState);
-uint32_t rtThreadRelease(PRTTHREADINT pThread);
-void rtThreadTerminate(PRTTHREADINT pThread, int rc);
-PRTTHREADINT rtThreadGetByNative(RTNATIVETHREAD NativeThread);
-PRTTHREADINT rtThreadGet(RTTHREAD Thread);
-int rtThreadInit(void);
-void rtThreadTerm(void);
-void rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread);
+DECLHIDDEN(int) rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *pszThreadName);
+DECLHIDDEN(uint32_t) rtThreadRelease(PRTTHREADINT pThread);
+DECLHIDDEN(void) rtThreadTerminate(PRTTHREADINT pThread, int rc);
+DECLHIDDEN(PRTTHREADINT) rtThreadGetByNative(RTNATIVETHREAD NativeThread);
+DECLHIDDEN(PRTTHREADINT) rtThreadGet(RTTHREAD Thread);
+DECLHIDDEN(int) rtThreadInit(void);
+DECLHIDDEN(void) rtThreadTerm(void);
+DECLHIDDEN(void) rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread);
#ifdef IN_RING3
-int rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority);
+DECLHIDDEN(int) rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority);
#endif /* !IN_RING0 */
#ifdef IPRT_WITH_GENERIC_TLS
-void rtThreadClearTlsEntry(RTTLS iTls);
-void rtThreadTlsDestruction(PRTTHREADINT pThread); /* in tls-generic.cpp */
+DECLHIDDEN(void) rtThreadClearTlsEntry(RTTLS iTls);
+DECLHIDDEN(void) rtThreadTlsDestruction(PRTTHREADINT pThread); /* in tls-generic.cpp */
#endif
#ifdef ___iprt_asm_h
diff --git a/src/VBox/Runtime/include/internal/time.h b/src/VBox/Runtime/include/internal/time.h
index 9d2895fc8..6d6c4c0b8 100644
--- a/src/VBox/Runtime/include/internal/time.h
+++ b/src/VBox/Runtime/include/internal/time.h
@@ -1,10 +1,10 @@
-/* $Id: time.h $ */
+/* $Id: time.h 36549 2011-04-05 09:28:24Z vboxsync $ */
/** @file
* IPRT - Internal RTTime header
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -33,9 +33,9 @@ RT_C_DECLS_BEGIN
#if defined(IN_RING3) || defined(IN_RC)
-extern uint64_t g_u64ProgramStartNanoTS;
-extern uint64_t g_u64ProgramStartMicroTS;
-extern uint64_t g_u64ProgramStartMilliTS;
+extern DECLHIDDEN(uint64_t) g_u64ProgramStartNanoTS;
+extern DECLHIDDEN(uint64_t) g_u64ProgramStartMicroTS;
+extern DECLHIDDEN(uint64_t) g_u64ProgramStartMilliTS;
#endif
diff --git a/src/VBox/Runtime/nt/NtProcessStartup-stub.cpp b/src/VBox/Runtime/nt/NtProcessStartup-stub.cpp
index fcb3bc21c..279b40726 100644
--- a/src/VBox/Runtime/nt/NtProcessStartup-stub.cpp
+++ b/src/VBox/Runtime/nt/NtProcessStartup-stub.cpp
@@ -1,4 +1,4 @@
-/* $Id: NtProcessStartup-stub.cpp $ */
+/* $Id: NtProcessStartup-stub.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - NtProcessStartup stub to make the link happy.
*/
diff --git a/src/VBox/Runtime/nt/RTErrConvertFromNtStatus.cpp b/src/VBox/Runtime/nt/RTErrConvertFromNtStatus.cpp
index 0f74823bd..f3a8b58fb 100644
--- a/src/VBox/Runtime/nt/RTErrConvertFromNtStatus.cpp
+++ b/src/VBox/Runtime/nt/RTErrConvertFromNtStatus.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTErrConvertFromNtStatus.cpp $ */
+/* $Id: RTErrConvertFromNtStatus.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Convert NT status codes to iprt status codes.
*/
diff --git a/src/VBox/Runtime/os2/RTErrConvertFromOS2.cpp b/src/VBox/Runtime/os2/RTErrConvertFromOS2.cpp
index edbfb3315..a87a064f0 100644
--- a/src/VBox/Runtime/os2/RTErrConvertFromOS2.cpp
+++ b/src/VBox/Runtime/os2/RTErrConvertFromOS2.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTErrConvertFromOS2.cpp $ */
+/* $Id: RTErrConvertFromOS2.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Convert OS/2 error codes to iprt status codes.
*/
diff --git a/src/VBox/Runtime/r0drv/alloc-r0drv.cpp b/src/VBox/Runtime/r0drv/alloc-r0drv.cpp
index 17b9e8bcf..fe626d1fa 100644
--- a/src/VBox/Runtime/r0drv/alloc-r0drv.cpp
+++ b/src/VBox/Runtime/r0drv/alloc-r0drv.cpp
@@ -1,4 +1,4 @@
-/* $Id: alloc-r0drv.cpp $ */
+/* $Id: alloc-r0drv.cpp 37672 2011-06-28 19:48:17Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, Ring-0 Driver.
*/
@@ -179,43 +179,64 @@ RT_EXPORT_SYMBOL(RTMemAllocZVarTag);
RTDECL(void *) RTMemReallocTag(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW
{
- if (!cbNew)
+ PRTMEMHDR pHdrOld;
+
+ /* Free. */
+ if (!cbNew && pvOld)
+ {
RTMemFree(pvOld);
- else if (!pvOld)
+ return NULL;
+ }
+
+ /* Alloc. */
+ if (!pvOld)
return RTMemAllocTag(cbNew, pszTag);
- else
+
+ /*
+ * Realloc.
+ */
+ pHdrOld = (PRTMEMHDR)pvOld - 1;
+ RT_ASSERT_PREEMPTIBLE();
+
+ if (pHdrOld->u32Magic == RTMEMHDR_MAGIC)
{
- PRTMEMHDR pHdrOld = (PRTMEMHDR)pvOld - 1;
- RT_ASSERT_PREEMPTIBLE();
+ PRTMEMHDR pHdrNew;
+
+ /* If there is sufficient space in the old block and we don't cause
+ substantial internal fragmentation, reuse the old block. */
+ if ( pHdrOld->cb >= cbNew + RTR0MEM_FENCE_EXTRA
+ && pHdrOld->cb - (cbNew + RTR0MEM_FENCE_EXTRA) <= 128)
+ {
+ pHdrOld->cbReq = (uint32_t)cbNew; Assert(pHdrOld->cbReq == cbNew);
+#ifdef RTR0MEM_STRICT
+ memcpy((uint8_t *)(pHdrOld + 1) + cbNew, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
+#endif
+ return pvOld;
+ }
- if (pHdrOld->u32Magic == RTMEMHDR_MAGIC)
+ /* Allocate a new block and copy over the content. */
+ pHdrNew = rtR0MemAlloc(cbNew + RTR0MEM_FENCE_EXTRA, 0);
+ if (pHdrNew)
{
- PRTMEMHDR pHdrNew;
- if (pHdrOld->cb >= cbNew && pHdrOld->cb - cbNew <= 128)
- return pvOld;
- pHdrNew = rtR0MemAlloc(cbNew + RTR0MEM_FENCE_EXTRA, 0);
- if (pHdrNew)
- {
- size_t cbCopy = RT_MIN(pHdrOld->cb, pHdrNew->cb);
- memcpy(pHdrNew + 1, pvOld, cbCopy);
+ size_t cbCopy = RT_MIN(pHdrOld->cb, pHdrNew->cb);
+ memcpy(pHdrNew + 1, pvOld, cbCopy);
#ifdef RTR0MEM_STRICT
- pHdrNew->cbReq = (uint32_t)cbNew; Assert(pHdrNew->cbReq == cbNew);
- memcpy((uint8_t *)(pHdrNew + 1) + cbNew, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
- AssertReleaseMsg(!memcmp((uint8_t *)(pHdrOld + 1) + pHdrOld->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
- ("pHdr=%p pvOld=%p cb=%zu cbNew=%zu\n"
- "fence: %.*Rhxs\n"
- "expected: %.*Rhxs\n",
- pHdrOld, pvOld, pHdrOld->cb, cbNew,
- RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdrOld + 1) + pHdrOld->cb,
- RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
+ pHdrNew->cbReq = (uint32_t)cbNew; Assert(pHdrNew->cbReq == cbNew);
+ memcpy((uint8_t *)(pHdrNew + 1) + cbNew, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
+ AssertReleaseMsg(!memcmp((uint8_t *)(pHdrOld + 1) + pHdrOld->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
+ ("pHdr=%p pvOld=%p cbReq=%u cb=%u cbNew=%zu fFlags=%#x\n"
+ "fence: %.*Rhxs\n"
+ "expected: %.*Rhxs\n",
+ pHdrOld, pvOld, pHdrOld->cbReq, pHdrOld->cb, cbNew, pHdrOld->fFlags,
+ RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdrOld + 1) + pHdrOld->cbReq,
+ RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
#endif
- rtR0MemFree(pHdrOld);
- return pHdrNew + 1;
- }
+ rtR0MemFree(pHdrOld);
+ return pHdrNew + 1;
}
- else
- AssertMsgFailed(("pHdrOld->u32Magic=%RX32 pvOld=%p cbNew=%#zx\n", pHdrOld->u32Magic, pvOld, cbNew));
}
+ else
+ AssertMsgFailed(("pHdrOld->u32Magic=%RX32 pvOld=%p cbNew=%#zx\n", pHdrOld->u32Magic, pvOld, cbNew));
return NULL;
}
@@ -236,11 +257,11 @@ RTDECL(void) RTMemFree(void *pv) RT_NO_THROW
Assert(!(pHdr->fFlags & RTMEMHDR_FLAG_EXEC));
#ifdef RTR0MEM_STRICT
AssertReleaseMsg(!memcmp((uint8_t *)(pHdr + 1) + pHdr->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
- ("pHdr=%p pv=%p cb=%zu\n"
+ ("pHdr=%p pv=%p cbReq=%u cb=%u fFlags=%#x\n"
"fence: %.*Rhxs\n"
"expected: %.*Rhxs\n",
- pHdr, pv, pHdr->cb,
- RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdr + 1) + pHdr->cb,
+ pHdr, pv, pHdr->cbReq, pHdr->cb, pHdr->fFlags,
+ RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdr + 1) + pHdr->cbReq,
RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
#endif
rtR0MemFree(pHdr);
@@ -291,11 +312,11 @@ RTDECL(void) RTMemExecFree(void *pv, size_t cb) RT_NO_THROW
Assert(!(pHdr->fFlags & RTMEMHDR_FLAG_ALLOC_EX));
#ifdef RTR0MEM_STRICT
AssertReleaseMsg(!memcmp((uint8_t *)(pHdr + 1) + pHdr->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
- ("pHdr=%p pv=%p cb=%zu\n"
+ ("pHdr=%p pv=%p cbReq=%u cb=%u fFlags=%#x\n"
"fence: %.*Rhxs\n"
"expected: %.*Rhxs\n",
- pHdr, pv, pHdr->cb,
- RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdr + 1) + pHdr->cb,
+ pHdr, pv, pHdr->cbReq, pHdr->cb, pHdr->fFlags,
+ RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdr + 1) + pHdr->cbReq,
RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
#endif
rtR0MemFree(pHdr);
@@ -392,11 +413,11 @@ RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW
#ifdef RTR0MEM_STRICT
AssertReleaseMsg(!memcmp((uint8_t *)(pHdr + 1) + pHdr->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
- ("pHdr=%p pv=%p cb=%zu\n"
+ ("pHdr=%p pv=%p cbReq=%u cb=%u fFlags=%#x\n"
"fence: %.*Rhxs\n"
"expected: %.*Rhxs\n",
- pHdr, pv, pHdr->cb,
- RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdr + 1) + pHdr->cb,
+ pHdr, pv, pHdr->cbReq, pHdr->cb, pHdr->fFlags,
+ RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdr + 1) + pHdr->cbReq,
RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
#endif
rtR0MemFree(pHdr);
diff --git a/src/VBox/Runtime/r0drv/alloc-r0drv.h b/src/VBox/Runtime/r0drv/alloc-r0drv.h
index 3843e1cc9..024c64320 100644
--- a/src/VBox/Runtime/r0drv/alloc-r0drv.h
+++ b/src/VBox/Runtime/r0drv/alloc-r0drv.h
@@ -1,4 +1,4 @@
-/* $Id: alloc-r0drv.h $ */
+/* $Id: alloc-r0drv.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, Ring-0 Driver.
*/
@@ -86,13 +86,13 @@ typedef struct RTMEMHDR
* the backend might be using.
* @param ppHdr Where to return the memory header on success.
*/
-int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr);
+DECLHIDDEN(int) rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr);
/**
* Free memory allocated by rtR0MemAllocEx.
* @param pHdr The memory block to free. (Never NULL.)
*/
-void rtR0MemFree(PRTMEMHDR pHdr);
+DECLHIDDEN(void) rtR0MemFree(PRTMEMHDR pHdr);
RT_C_DECLS_END
#endif
diff --git a/src/VBox/Runtime/r0drv/darwin/RTLogWriteDebugger-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/RTLogWriteDebugger-r0drv-darwin.cpp
index 9a65df825..ef63e351f 100644
--- a/src/VBox/Runtime/r0drv/darwin/RTLogWriteDebugger-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/RTLogWriteDebugger-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTLogWriteDebugger-r0drv-darwin.cpp $ */
+/* $Id: RTLogWriteDebugger-r0drv-darwin.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Log To Debugger, Ring-0 Driver, Darwin.
*/
diff --git a/src/VBox/Runtime/r0drv/darwin/RTLogWriteStdOut-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/RTLogWriteStdOut-r0drv-darwin.cpp
index 57da5a760..0946d3b4c 100644
--- a/src/VBox/Runtime/r0drv/darwin/RTLogWriteStdOut-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/RTLogWriteStdOut-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTLogWriteStdOut-r0drv-darwin.cpp $ */
+/* $Id: RTLogWriteStdOut-r0drv-darwin.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Log To StdOut, Ring-0 Driver, Darwin.
*/
diff --git a/src/VBox/Runtime/r0drv/darwin/alloc-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/alloc-r0drv-darwin.cpp
index 21c003279..be2d63145 100644
--- a/src/VBox/Runtime/r0drv/darwin/alloc-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/alloc-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: alloc-r0drv-darwin.cpp $ */
+/* $Id: alloc-r0drv-darwin.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, Ring-0 Driver, Darwin.
*/
@@ -41,7 +41,7 @@
/**
* OS specific allocation function.
*/
-int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
+DECLHIDDEN(int) rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
{
if (RT_UNLIKELY(fFlags & RTMEMHDR_FLAG_ANY_CTX))
return VERR_NOT_SUPPORTED;
@@ -65,7 +65,7 @@ int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
/**
* OS specific free function.
*/
-void rtR0MemFree(PRTMEMHDR pHdr)
+DECLHIDDEN(void) rtR0MemFree(PRTMEMHDR pHdr)
{
pHdr->u32Magic += 1;
IOFree(pHdr, pHdr->cb + sizeof(*pHdr));
diff --git a/src/VBox/Runtime/r0drv/darwin/assert-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/assert-r0drv-darwin.cpp
index 14a40addf..3c9e8c0c5 100644
--- a/src/VBox/Runtime/r0drv/darwin/assert-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/assert-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: assert-r0drv-darwin.cpp $ */
+/* $Id: assert-r0drv-darwin.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Assertion Workers, Ring-0 Drivers, Darwin.
*/
@@ -40,7 +40,7 @@
#include "internal/assert.h"
-void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
+DECLHIDDEN(void) rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
{
printf("\r\n!!Assertion Failed!!\r\n"
"Expression: %s\r\n"
@@ -49,7 +49,7 @@ void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFi
}
-void rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
+DECLHIDDEN(void) rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
{
char szMsg[256];
diff --git a/src/VBox/Runtime/r0drv/darwin/initterm-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/initterm-r0drv-darwin.cpp
index 253adaf35..d3ba0123f 100644
--- a/src/VBox/Runtime/r0drv/darwin/initterm-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/initterm-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: initterm-r0drv-darwin.cpp $ */
+/* $Id: initterm-r0drv-darwin.cpp 37575 2011-06-21 12:40:01Z vboxsync $ */
/** @file
* IPRT - Initialization & Termination, R0 Driver, Darwin.
*/
@@ -49,7 +49,7 @@ PFNR0DARWINASTPENDING g_pfnR0DarwinAstPending = NULL;
PFNR0DARWINCPUINTERRUPT g_pfnR0DarwinCpuInterrupt = NULL;
-int rtR0InitNative(void)
+DECLHIDDEN(int) rtR0InitNative(void)
{
/*
* Create the lock group.
@@ -89,7 +89,7 @@ int rtR0InitNative(void)
}
-void rtR0TermNative(void)
+DECLHIDDEN(void) rtR0TermNative(void)
{
/*
* Preemption hacks before the lock group.
diff --git a/src/VBox/Runtime/r0drv/darwin/mach_kernel-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/mach_kernel-r0drv-darwin.cpp
index e69746daf..bbf3712d4 100644
--- a/src/VBox/Runtime/r0drv/darwin/mach_kernel-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/mach_kernel-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: mach_kernel-r0drv-darwin.cpp $ */
+/* $Id: mach_kernel-r0drv-darwin.cpp 37597 2011-06-22 20:54:05Z vboxsync $ */
/** @file
* IPRT - mach_kernel symbol resolving hack, R0 Driver, Darwin.
*/
@@ -25,7 +25,6 @@
*/
-#define RTMEM_WRAP_TO_EF_APIS
/*******************************************************************************
* Header Files *
*******************************************************************************/
@@ -50,16 +49,6 @@ RT_C_DECLS_END
#include "internal/iprt.h"
#include <iprt/darwin/machkernel.h>
-#ifdef IN_RING0 /* till RTFILE is changed in types.h */
-# include <iprt/types.h>
-typedef struct RTFILENEWINT *RTFILENEW;
-typedef RTFILENEW *PRTFILENEW;
-# undef NIL_RTFILE
-# define RTFILE RTFILENEW
-# define PRTFILE PRTFILENEW
-# define NIL_RTFILE ((RTFILENEW)-1)
-#endif
-
#include <iprt/asm.h>
#include <iprt/assert.h>
#include <iprt/err.h>
@@ -196,7 +185,7 @@ static bool g_fBreakpointOnError = false;
/**
* Darwin kernel file handle data.
*/
-typedef struct RTFILENEWINT
+typedef struct RTFILEINT
{
/** Magic value (RTFILE_MAGIC). */
uint32_t u32Magic;
@@ -208,14 +197,14 @@ typedef struct RTFILENEWINT
vfs_context_t hVfsCtx;
/** The vnode returned by vnode_open. */
vnode_t hVnode;
-} RTFILENEWINT;
-/** Magic number for RTFILENEWINT::u32Magic (To Be Determined). */
+} RTFILEINT;
+/** Magic number for RTFILEINT::u32Magic (To Be Determined). */
#define RTFILE_MAGIC UINT32_C(0x01020304)
-RTDECL(int) RTFileOpen(PRTFILE phFile, const char *pszFilename, uint32_t fOpen)
+RTDECL(int) RTFileOpen(PRTFILE phFile, const char *pszFilename, uint64_t fOpen)
{
- RTFILENEWINT *pThis = (RTFILENEWINT *)RTMemAllocZ(sizeof(*pThis));
+ RTFILEINT *pThis = (RTFILEINT *)RTMemAllocZ(sizeof(*pThis));
if (!pThis)
return VERR_NO_MEMORY;
@@ -285,7 +274,7 @@ RTDECL(int) RTFileClose(RTFILE hFile)
if (hFile == NIL_RTFILE)
return VINF_SUCCESS;
- RTFILENEWINT *pThis = hFile;
+ RTFILEINT *pThis = hFile;
AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
AssertReturn(pThis->u32Magic == RTFILE_MAGIC, VERR_INVALID_HANDLE);
pThis->u32Magic = ~RTFILE_MAGIC;
@@ -299,7 +288,7 @@ RTDECL(int) RTFileClose(RTFILE hFile)
RTDECL(int) RTFileReadAt(RTFILE hFile, RTFOFF off, void *pvBuf, size_t cbToRead, size_t *pcbRead)
{
- RTFILENEWINT *pThis = hFile;
+ RTFILEINT *pThis = hFile;
AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
AssertReturn(pThis->u32Magic == RTFILE_MAGIC, VERR_INVALID_HANDLE);
diff --git a/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp
index 7d7e27f7e..9fad7d833 100644
--- a/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: memobj-r0drv-darwin.cpp $ */
+/* $Id: memobj-r0drv-darwin.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Ring-0 Memory Objects, Darwin.
*/
@@ -225,7 +225,7 @@ static void rtR0MemObjDarwinReadPhys(RTHCPHYS HCPhys, size_t cb, void *pvDst)
* @returns the PTE.
* @param pvPage The virtual address to get the PTE for.
*/
-uint64_t rtR0MemObjDarwinGetPTE(void *pvPage)
+static uint64_t rtR0MemObjDarwinGetPTE(void *pvPage)
{
RTUINT64U u64;
RTCCUINTREG cr3 = ASMGetCR3();
@@ -323,7 +323,7 @@ uint64_t rtR0MemObjDarwinGetPTE(void *pvPage)
#endif /* RT_STRICT */
-int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
+DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
{
PRTR0MEMOBJDARWIN pMemDarwin = (PRTR0MEMOBJDARWIN)pMem;
@@ -523,14 +523,14 @@ static int rtR0MemObjNativeAllocWorker(PPRTR0MEMOBJINTERNAL ppMem, size_t cb,
}
-int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
return rtR0MemObjNativeAllocWorker(ppMem, cb, fExecutable, false /* fContiguous */,
0 /* PhysMask */, UINT64_MAX, RTR0MEMOBJTYPE_PAGE);
}
-int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
/*
* Try IOMallocPhysical/IOMallocAligned first.
@@ -548,7 +548,7 @@ int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecut
}
-int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
int rc = rtR0MemObjNativeAllocWorker(ppMem, cb, fExecutable, true /* fContiguous */,
~(uint32_t)PAGE_OFFSET_MASK, _4G - PAGE_SIZE,
@@ -566,7 +566,7 @@ int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecu
}
-int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
{
/** @todo alignment */
if (uAlignment != PAGE_SIZE)
@@ -595,7 +595,7 @@ int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS Ph
}
-int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
{
/** @todo rtR0MemObjNativeAllocPhys / darwin.
* This might be a bit problematic and may very well require having to create our own
@@ -606,7 +606,7 @@ int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS
}
-int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
+DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
{
AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
@@ -737,32 +737,32 @@ static int rtR0MemObjNativeLock(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb,
}
-int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
{
return rtR0MemObjNativeLock(ppMem, (void *)R3Ptr, cb, fAccess, (task_t)R0Process);
}
-int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
+DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
{
return rtR0MemObjNativeLock(ppMem, pv, cb, fAccess, kernel_task);
}
-int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
+DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
{
return VERR_NOT_SUPPORTED;
}
-int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
{
return VERR_NOT_SUPPORTED;
}
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
- unsigned fProt, size_t offSub, size_t cbSub)
+DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+ unsigned fProt, size_t offSub, size_t cbSub)
{
AssertReturn(pvFixed == (void *)-1, VERR_NOT_SUPPORTED);
@@ -866,7 +866,7 @@ int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap,
}
-int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
{
/*
* Check for unsupported things.
@@ -925,7 +925,7 @@ int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RT
}
-int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
+DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
{
/* Get the map for the object. */
vm_map_t pVmMap = rtR0MemObjDarwinGetMap(pMem);
@@ -971,7 +971,7 @@ int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSu
}
-RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
+DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
{
RTHCPHYS PhysAddr;
PRTR0MEMOBJDARWIN pMemDarwin = (PRTR0MEMOBJDARWIN)pMem;
diff --git a/src/VBox/Runtime/r0drv/darwin/memuserkernel-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/memuserkernel-r0drv-darwin.cpp
index 9918f92ca..4dfbf5e7d 100644
--- a/src/VBox/Runtime/r0drv/darwin/memuserkernel-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/memuserkernel-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: memuserkernel-r0drv-darwin.cpp $ */
+/* $Id: memuserkernel-r0drv-darwin.cpp 36540 2011-04-04 15:58:26Z vboxsync $ */
/** @file
* IPRT - User & Kernel Memory, Ring-0 Driver, Darwin.
*/
@@ -31,6 +31,7 @@
#include "the-darwin-kernel.h"
#include "internal/iprt.h"
#include <iprt/mem.h>
+#include <iprt/assert.h>
#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
# include <iprt/asm-amd64-x86.h>
diff --git a/src/VBox/Runtime/r0drv/darwin/mp-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/mp-r0drv-darwin.cpp
index f5a731661..173aa397b 100644
--- a/src/VBox/Runtime/r0drv/darwin/mp-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/mp-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: mp-r0drv-darwin.cpp $ */
+/* $Id: mp-r0drv-darwin.cpp 37575 2011-06-21 12:40:01Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Ring-0 Driver, Darwin.
*/
diff --git a/src/VBox/Runtime/r0drv/darwin/process-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/process-r0drv-darwin.cpp
index 355420304..215a009a2 100644
--- a/src/VBox/Runtime/r0drv/darwin/process-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/process-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: process-r0drv-darwin.cpp $ */
+/* $Id: process-r0drv-darwin.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Process, Ring-0 Driver, Darwin.
*/
diff --git a/src/VBox/Runtime/r0drv/darwin/semevent-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/semevent-r0drv-darwin.cpp
index a2098bfd2..1d4848b73 100644
--- a/src/VBox/Runtime/r0drv/darwin/semevent-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/semevent-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: semevent-r0drv-darwin.cpp $ */
+/* $Id: semevent-r0drv-darwin.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Single Release Event Semaphores, Ring-0 Driver, Darwin.
*/
diff --git a/src/VBox/Runtime/r0drv/darwin/semeventmulti-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/semeventmulti-r0drv-darwin.cpp
index a77d41d0d..53ea3f258 100644
--- a/src/VBox/Runtime/r0drv/darwin/semeventmulti-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/semeventmulti-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: semeventmulti-r0drv-darwin.cpp $ */
+/* $Id: semeventmulti-r0drv-darwin.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Multiple Release Event Semaphores, Ring-0 Driver, Darwin.
*/
diff --git a/src/VBox/Runtime/r0drv/darwin/semfastmutex-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/semfastmutex-r0drv-darwin.cpp
index 407381ec6..d286362b3 100644
--- a/src/VBox/Runtime/r0drv/darwin/semfastmutex-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/semfastmutex-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: semfastmutex-r0drv-darwin.cpp $ */
+/* $Id: semfastmutex-r0drv-darwin.cpp 29255 2010-05-09 18:11:24Z vboxsync $ */
/** @file
* IPRT - Fast Mutex Semaphores, Ring-0 Driver, Darwin.
*/
diff --git a/src/VBox/Runtime/r0drv/darwin/semmutex-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/semmutex-r0drv-darwin.cpp
index 2b01e760a..009be81d1 100644
--- a/src/VBox/Runtime/r0drv/darwin/semmutex-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/semmutex-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: semmutex-r0drv-darwin.cpp $ */
+/* $Id: semmutex-r0drv-darwin.cpp 36192 2011-03-07 16:33:55Z vboxsync $ */
/** @file
* IPRT - Mutex Semaphores, Ring-0 Driver, Darwin.
*/
diff --git a/src/VBox/Runtime/r0drv/darwin/spinlock-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/spinlock-r0drv-darwin.cpp
index df46ce0d7..2f6986582 100644
--- a/src/VBox/Runtime/r0drv/darwin/spinlock-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/spinlock-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: spinlock-r0drv-darwin.cpp $ */
+/* $Id: spinlock-r0drv-darwin.cpp 29255 2010-05-09 18:11:24Z vboxsync $ */
/** @file
* IPRT - Spinlocks, Ring-0 Driver, Darwin.
*/
diff --git a/src/VBox/Runtime/r0drv/darwin/the-darwin-kernel.h b/src/VBox/Runtime/r0drv/darwin/the-darwin-kernel.h
index 254b1468f..a2bd2b751 100644
--- a/src/VBox/Runtime/r0drv/darwin/the-darwin-kernel.h
+++ b/src/VBox/Runtime/r0drv/darwin/the-darwin-kernel.h
@@ -1,4 +1,4 @@
-/* $Id: the-darwin-kernel.h $ */
+/* $Id: the-darwin-kernel.h 37575 2011-06-21 12:40:01Z vboxsync $ */
/** @file
* IPRT - Include all necessary headers for the Darwing kernel.
*/
diff --git a/src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp
index c71476355..920065af5 100644
--- a/src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: thread-r0drv-darwin.cpp $ */
+/* $Id: thread-r0drv-darwin.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Threads, Ring-0 Driver, Darwin.
*/
diff --git a/src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp
index 41e0f370f..48a10d4ca 100644
--- a/src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: thread2-r0drv-darwin.cpp $ */
+/* $Id: thread2-r0drv-darwin.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Threads (Part 2), Ring-0 Driver, Darwin.
*/
@@ -40,7 +40,7 @@
#include "internal/thread.h"
-int rtThreadNativeInit(void)
+DECLHIDDEN(int) rtThreadNativeInit(void)
{
/* No TLS in Ring-0. :-/ */
return VINF_SUCCESS;
@@ -53,7 +53,7 @@ RTDECL(RTTHREAD) RTThreadSelf(void)
}
-int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
{
/*
* Convert the priority type to scheduling policies.
@@ -130,13 +130,13 @@ int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
}
-int rtThreadNativeAdopt(PRTTHREADINT pThread)
+DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread)
{
return VERR_NOT_IMPLEMENTED;
}
-void rtThreadNativeDestroy(PRTTHREADINT pThread)
+DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread)
{
NOREF(pThread);
}
@@ -162,7 +162,7 @@ static void rtThreadNativeMain(void *pvArg, wait_result_t Ignored)
}
-int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
{
RT_ASSERT_PREEMPTIBLE();
diff --git a/src/VBox/Runtime/r0drv/darwin/threadpreempt-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/threadpreempt-r0drv-darwin.cpp
index 23b28a100..00effbd19 100644
--- a/src/VBox/Runtime/r0drv/darwin/threadpreempt-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/threadpreempt-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: threadpreempt-r0drv-darwin.cpp $ */
+/* $Id: threadpreempt-r0drv-darwin.cpp 37575 2011-06-21 12:40:01Z vboxsync $ */
/** @file
* IPRT - Thread Preemption, Ring-0 Driver, Darwin.
*/
diff --git a/src/VBox/Runtime/r0drv/darwin/time-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/time-r0drv-darwin.cpp
index 913fa711e..487099d07 100644
--- a/src/VBox/Runtime/r0drv/darwin/time-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/time-r0drv-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: time-r0drv-darwin.cpp $ */
+/* $Id: time-r0drv-darwin.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Time, Ring-0 Driver, Darwin.
*/
diff --git a/src/VBox/Runtime/r0drv/freebsd/alloc-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/alloc-r0drv-freebsd.c
index 93de62447..3ebf473a0 100644
--- a/src/VBox/Runtime/r0drv/freebsd/alloc-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/alloc-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: alloc-r0drv-freebsd.c $ */
+/* $Id: alloc-r0drv-freebsd.c 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, Ring-0 Driver, FreeBSD.
*/
@@ -51,7 +51,7 @@ MALLOC_DEFINE(M_IPRTHEAP, "iprtheap", "IPRT - heap");
MALLOC_DEFINE(M_IPRTCONT, "iprtcont", "IPRT - contiguous");
-int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
+DECLHIDDEN(int) rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
{
size_t cbAllocated = cb;
PRTMEMHDR pHdr = NULL;
@@ -121,7 +121,7 @@ int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
}
-void rtR0MemFree(PRTMEMHDR pHdr)
+DECLHIDDEN(void) rtR0MemFree(PRTMEMHDR pHdr)
{
pHdr->u32Magic += 1;
diff --git a/src/VBox/Runtime/r0drv/freebsd/assert-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/assert-r0drv-freebsd.c
index 56f6acaa8..ed8c8f246 100644
--- a/src/VBox/Runtime/r0drv/freebsd/assert-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/assert-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: assert-r0drv-freebsd.c $ */
+/* $Id: assert-r0drv-freebsd.c 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Assertion Workers, Ring-0 Drivers, FreeBSD.
*/
@@ -41,7 +41,7 @@
#include "internal/assert.h"
-void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
+DECLHIDDEN(void) rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
{
printf("\r\n!!Assertion Failed!!\r\n"
"Expression: %s\r\n"
@@ -50,7 +50,7 @@ void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFi
}
-void rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
+DECLHIDDEN(void) rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
{
char szMsg[256];
diff --git a/src/VBox/Runtime/r0drv/freebsd/initterm-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/initterm-r0drv-freebsd.c
index 591b77973..60c50be8f 100644
--- a/src/VBox/Runtime/r0drv/freebsd/initterm-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/initterm-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: initterm-r0drv-freebsd.c $ */
+/* $Id: initterm-r0drv-freebsd.c 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Initialization & Termination, Ring-0 Driver, FreeBSD.
*/
@@ -38,14 +38,14 @@
#include "internal/initterm.h"
-int rtR0InitNative(void)
+DECLHIDDEN(int) rtR0InitNative(void)
{
/* nothing to do */
return VINF_SUCCESS;
}
-void rtR0TermNative(void)
+DECLHIDDEN(void) rtR0TermNative(void)
{
/* nothing to undo */
}
diff --git a/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c
index 7959367f8..1f253f7c1 100644
--- a/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: memobj-r0drv-freebsd.c $ */
+/* $Id: memobj-r0drv-freebsd.c 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Ring-0 Memory Objects, FreeBSD.
*/
@@ -76,9 +76,7 @@ typedef struct RTR0MEMOBJFREEBSD
MALLOC_DEFINE(M_IPRTMOBJ, "iprtmobj", "IPRT - R0MemObj");
-/*******************************************************************************
-* Internal Functions *
-*******************************************************************************/
+
/**
* Gets the virtual memory map the specified object is mapped into.
@@ -119,7 +117,8 @@ static vm_map_t rtR0MemObjFreeBSDGetMap(PRTR0MEMOBJINTERNAL pMem)
}
}
-int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
+
+DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
{
PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)pMem;
int rc;
@@ -220,7 +219,8 @@ int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
return VINF_SUCCESS;
}
-int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+
+DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
int rc;
size_t cPages = cb >> PAGE_SHIFT;
@@ -308,7 +308,8 @@ int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecu
return rc;
}
-int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+
+DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
#ifdef USE_KMEM_ALLOC_ATTR
/*
@@ -360,7 +361,7 @@ int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecut
}
-int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
/* create the object. */
PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)rtR0MemObjNew(sizeof(*pMemFreeBSD), RTR0MEMOBJTYPE_CONT, NULL, cb);
@@ -387,6 +388,7 @@ int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecu
return VERR_NO_MEMORY;
}
+
static void rtR0MemObjFreeBSDPhysPageInit(vm_page_t pPage, vm_pindex_t iPage)
{
pPage->wire_count = 1;
@@ -397,6 +399,7 @@ static void rtR0MemObjFreeBSDPhysPageInit(vm_page_t pPage, vm_pindex_t iPage)
atomic_add_int(&cnt.v_wire_count, 1);
}
+
static int rtR0MemObjFreeBSDAllocPhysPages(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType,
size_t cb,
RTHCPHYS PhysHighest, size_t uAlignment,
@@ -474,7 +477,8 @@ static int rtR0MemObjFreeBSDAllocPhysPages(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOB
return rc;
}
-int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
+
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
{
#if 1
return rtR0MemObjFreeBSDAllocPhysPages(ppMem, RTR0MEMOBJTYPE_PHYS, cb, PhysHighest, uAlignment, true);
@@ -505,7 +509,7 @@ int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS Ph
}
-int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
{
#if 1
return rtR0MemObjFreeBSDAllocPhysPages(ppMem, RTR0MEMOBJTYPE_PHYS_NC, cb, PhysHighest, PAGE_SIZE, false);
@@ -515,7 +519,7 @@ int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS
}
-int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
+DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
{
AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
@@ -567,7 +571,7 @@ static int rtR0MemObjNativeLockInMap(PPRTR0MEMOBJINTERNAL ppMem, vm_map_t pVmMap
}
-int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
{
return rtR0MemObjNativeLockInMap(ppMem,
&((struct proc *)R0Process)->p_vmspace->vm_map,
@@ -579,7 +583,7 @@ int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t c
}
-int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
+DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
{
return rtR0MemObjNativeLockInMap(ppMem,
kernel_map,
@@ -669,21 +673,22 @@ static int rtR0MemObjNativeReserveInMap(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixe
}
-int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
+
+DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
{
return rtR0MemObjNativeReserveInMap(ppMem, pvFixed, cb, uAlignment, NIL_RTR0PROCESS, kernel_map);
}
-int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
{
return rtR0MemObjNativeReserveInMap(ppMem, (void *)R3PtrFixed, cb, uAlignment, R0Process,
&((struct proc *)R0Process)->p_vmspace->vm_map);
}
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
- unsigned fProt, size_t offSub, size_t cbSub)
+DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+ unsigned fProt, size_t offSub, size_t cbSub)
{
AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
@@ -702,7 +707,7 @@ int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap,
/* see http://markmail.org/message/udhq33tefgtyfozs */
-int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
{
/*
* Check for unsupported stuff.
@@ -808,7 +813,7 @@ int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RT
}
-int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
+DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
{
vm_prot_t ProtectionFlags = 0;
vm_offset_t AddrStart = (uintptr_t)pMem->pv + offSub;
@@ -835,7 +840,7 @@ int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSu
}
-RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
+DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
{
PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)pMem;
diff --git a/src/VBox/Runtime/r0drv/freebsd/memuserkernel-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/memuserkernel-r0drv-freebsd.c
index ce24fb5d3..6bd7c45b9 100644
--- a/src/VBox/Runtime/r0drv/freebsd/memuserkernel-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/memuserkernel-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: memuserkernel-r0drv-freebsd.c $ */
+/* $Id: memuserkernel-r0drv-freebsd.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - User & Kernel Memory, Ring-0 Driver, FreeBSD.
*/
diff --git a/src/VBox/Runtime/r0drv/freebsd/mp-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/mp-r0drv-freebsd.c
index a2cffad86..c71c865ad 100644
--- a/src/VBox/Runtime/r0drv/freebsd/mp-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/mp-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: mp-r0drv-freebsd.c $ */
+/* $Id: mp-r0drv-freebsd.c 37774 2011-07-04 21:19:27Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Ring-0 Driver, FreeBSD.
*/
@@ -163,8 +163,10 @@ RTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
/* Will panic if no rendezvousing cpus, so check up front. */
if (RTMpGetOnlineCount() > 1)
{
-#if __FreeBSD_version >= 700000
- cpumask_t Mask = ~(cpumask_t)curcpu;
+#if __FreeBSD_version >= 900000
+ cpuset_t Mask;
+#elif __FreeBSD_version >= 700000
+ cpumask_t Mask;
#endif
RTMPARGS Args;
@@ -174,6 +176,12 @@ RTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
Args.idCpu = RTMpCpuId();
Args.cHits = 0;
#if __FreeBSD_version >= 700000
+# if __FreeBSD_version >= 900000
+ Mask = all_cpus;
+ CPU_CLR(curcpu, &Mask);
+# else
+ Mask = ~(cpumask_t)curcpu;
+# endif
smp_rendezvous_cpus(Mask, NULL, rtmpOnOthersFreeBSDWrapper, smp_no_rendevous_barrier, &Args);
#else
smp_rendezvous(NULL, rtmpOnOthersFreeBSDWrapper, NULL, &Args);
@@ -203,8 +211,10 @@ static void rtmpOnSpecificFreeBSDWrapper(void *pvArg)
RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
{
-#if __FreeBSD_version >= 700000
- cpumask_t Mask = 1 << idCpu;
+#if __FreeBSD_version >= 900000
+ cpuset_t Mask;
+#elif __FreeBSD_version >= 700000
+ cpumask_t Mask;
#endif
RTMPARGS Args;
@@ -218,7 +228,11 @@ RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1
Args.idCpu = idCpu;
Args.cHits = 0;
#if __FreeBSD_version >= 700000
+# if __FreeBSD_version >= 900000
+ CPU_SETOF(idCpu, &Mask);
+# else
Mask = (cpumask_t)1 << idCpu;
+# endif
smp_rendezvous_cpus(Mask, NULL, rtmpOnSpecificFreeBSDWrapper, smp_no_rendevous_barrier, &Args);
#else
smp_rendezvous(NULL, rtmpOnSpecificFreeBSDWrapper, NULL, &Args);
@@ -242,13 +256,21 @@ static void rtmpFreeBSDPokeCallback(void *pvArg)
RTDECL(int) RTMpPokeCpu(RTCPUID idCpu)
{
+#if __FreeBSD_version >= 900000
+ cpuset_t Mask;
+#elif __FreeBSD_version >= 700000
cpumask_t Mask;
+#endif
/* Will panic if no rendezvousing cpus, so make sure the cpu is online. */
if (!RTMpIsCpuOnline(idCpu))
return VERR_CPU_NOT_FOUND;
+# if __FreeBSD_version >= 900000
+ CPU_SETOF(idCpu, &Mask);
+# else
Mask = (cpumask_t)1 << idCpu;
+# endif
smp_rendezvous_cpus(Mask, NULL, rtmpFreeBSDPokeCallback, smp_no_rendevous_barrier, NULL);
return VINF_SUCCESS;
diff --git a/src/VBox/Runtime/r0drv/freebsd/process-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/process-r0drv-freebsd.c
index 96af287aa..ac08c3e94 100644
--- a/src/VBox/Runtime/r0drv/freebsd/process-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/process-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: process-r0drv-freebsd.c $ */
+/* $Id: process-r0drv-freebsd.c 18972 2009-04-16 23:43:08Z vboxsync $ */
/** @file
* IPRT - Process Management, Ring-0 Driver, FreeBSD.
*/
diff --git a/src/VBox/Runtime/r0drv/freebsd/semevent-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/semevent-r0drv-freebsd.c
index b2a9a5c91..435c255ce 100644
--- a/src/VBox/Runtime/r0drv/freebsd/semevent-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/semevent-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: semevent-r0drv-freebsd.c $ */
+/* $Id: semevent-r0drv-freebsd.c 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Single Release Event Semaphores, Ring-0 Driver, FreeBSD.
*/
diff --git a/src/VBox/Runtime/r0drv/freebsd/semeventmulti-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/semeventmulti-r0drv-freebsd.c
index 253a5b01d..f8ed7800f 100644
--- a/src/VBox/Runtime/r0drv/freebsd/semeventmulti-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/semeventmulti-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: semeventmulti-r0drv-freebsd.c $ */
+/* $Id: semeventmulti-r0drv-freebsd.c 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Multiple Release Event Semaphores, Ring-0 Driver, FreeBSD.
*/
diff --git a/src/VBox/Runtime/r0drv/freebsd/semfastmutex-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/semfastmutex-r0drv-freebsd.c
index 2f42336f0..7058b7fd0 100644
--- a/src/VBox/Runtime/r0drv/freebsd/semfastmutex-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/semfastmutex-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: semfastmutex-r0drv-freebsd.c $ */
+/* $Id: semfastmutex-r0drv-freebsd.c 25722 2010-01-11 14:22:03Z vboxsync $ */
/** @file
* IPRT - Fast Mutex Semaphores, Ring-0 Driver, FreeBSD.
*/
diff --git a/src/VBox/Runtime/r0drv/freebsd/semmutex-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/semmutex-r0drv-freebsd.c
index b20b9603f..370f29a75 100644
--- a/src/VBox/Runtime/r0drv/freebsd/semmutex-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/semmutex-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: semmutex-r0drv-freebsd.c $ */
+/* $Id: semmutex-r0drv-freebsd.c 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Mutex Semaphores, Ring-0 Driver, FreeBSD.
*/
diff --git a/src/VBox/Runtime/r0drv/freebsd/sleepqueue-r0drv-freebsd.h b/src/VBox/Runtime/r0drv/freebsd/sleepqueue-r0drv-freebsd.h
index 89e12087b..49d3d5393 100644
--- a/src/VBox/Runtime/r0drv/freebsd/sleepqueue-r0drv-freebsd.h
+++ b/src/VBox/Runtime/r0drv/freebsd/sleepqueue-r0drv-freebsd.h
@@ -1,4 +1,4 @@
-/* $Id: sleepqueue-r0drv-freebsd.h $ */
+/* $Id: sleepqueue-r0drv-freebsd.h 37305 2011-06-02 12:32:20Z vboxsync $ */
/** @file
* IPRT - FreeBSD Ring-0 Driver Helpers for Abstracting Sleep Queues,
*/
diff --git a/src/VBox/Runtime/r0drv/freebsd/spinlock-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/spinlock-r0drv-freebsd.c
index 97a988e6a..f208aea90 100644
--- a/src/VBox/Runtime/r0drv/freebsd/spinlock-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/spinlock-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: spinlock-r0drv-freebsd.c $ */
+/* $Id: spinlock-r0drv-freebsd.c 29500 2010-05-14 21:43:06Z vboxsync $ */
/** @file
* IPRT - Spinlocks, Ring-0 Driver, FreeBSD.
*/
diff --git a/src/VBox/Runtime/r0drv/freebsd/the-freebsd-kernel.h b/src/VBox/Runtime/r0drv/freebsd/the-freebsd-kernel.h
index 718b6741a..4c9fb9261 100644
--- a/src/VBox/Runtime/r0drv/freebsd/the-freebsd-kernel.h
+++ b/src/VBox/Runtime/r0drv/freebsd/the-freebsd-kernel.h
@@ -1,4 +1,4 @@
-/* $Id: the-freebsd-kernel.h $ */
+/* $Id: the-freebsd-kernel.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Ring-0 Driver, The FreeBSD Kernel Headers.
*/
diff --git a/src/VBox/Runtime/r0drv/freebsd/thread-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/thread-r0drv-freebsd.c
index 38474aab3..f58d9dd7d 100644
--- a/src/VBox/Runtime/r0drv/freebsd/thread-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/thread-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: thread-r0drv-freebsd.c $ */
+/* $Id: thread-r0drv-freebsd.c 35960 2011-02-14 14:52:34Z vboxsync $ */
/** @file
* IPRT - Threads (Part 1), Ring-0 Driver, FreeBSD.
*/
diff --git a/src/VBox/Runtime/r0drv/freebsd/thread2-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/thread2-r0drv-freebsd.c
index 0f42760a1..be9191727 100644
--- a/src/VBox/Runtime/r0drv/freebsd/thread2-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/thread2-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: thread2-r0drv-freebsd.c $ */
+/* $Id: thread2-r0drv-freebsd.c 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Threads (Part 2), Ring-0 Driver, FreeBSD.
*/
@@ -40,7 +40,7 @@
#include "internal/thread.h"
-int rtThreadNativeInit(void)
+DECLHIDDEN(int) rtThreadNativeInit(void)
{
return VINF_SUCCESS;
}
@@ -52,7 +52,7 @@ RTDECL(RTTHREAD) RTThreadSelf(void)
}
-int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
{
int iPriority;
@@ -89,7 +89,7 @@ int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
}
-int rtThreadNativeAdopt(PRTTHREADINT pThread)
+DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread)
{
NOREF(pThread);
/* There is nothing special that needs doing here, but the
@@ -98,7 +98,7 @@ int rtThreadNativeAdopt(PRTTHREADINT pThread)
}
-void rtThreadNativeDestroy(PRTTHREADINT pThread)
+DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread)
{
NOREF(pThread);
}
@@ -125,7 +125,7 @@ static void rtThreadNativeMain(void *pvThreadInt)
}
-int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
{
int rc;
struct proc *pProc;
diff --git a/src/VBox/Runtime/r0drv/freebsd/time-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/time-r0drv-freebsd.c
index 7f356a10c..3d1ff7e78 100644
--- a/src/VBox/Runtime/r0drv/freebsd/time-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/time-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: time-r0drv-freebsd.c $ */
+/* $Id: time-r0drv-freebsd.c 18972 2009-04-16 23:43:08Z vboxsync $ */
/** @file
* IPRT - Time, Ring-0 Driver, FreeBSD.
*/
diff --git a/src/VBox/Runtime/r0drv/freebsd/timer-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/timer-r0drv-freebsd.c
index 43f693f48..d8981b9d5 100644
--- a/src/VBox/Runtime/r0drv/freebsd/timer-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/timer-r0drv-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: timer-r0drv-freebsd.c $ */
+/* $Id: timer-r0drv-freebsd.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, Ring-0 Driver, FreeBSD.
*/
diff --git a/src/VBox/Runtime/r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.cpp
index 925842eb4..100e12e29 100644
--- a/src/VBox/Runtime/r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpIsCpuWorkPending-r0drv-generic.cpp $ */
+/* $Id: RTMpIsCpuWorkPending-r0drv-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTMpIsCpuWorkPending, Generic.
*/
diff --git a/src/VBox/Runtime/r0drv/generic/RTMpOn-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTMpOn-r0drv-generic.cpp
index a9844aceb..44114a12a 100644
--- a/src/VBox/Runtime/r0drv/generic/RTMpOn-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTMpOn-r0drv-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpOn-r0drv-generic.cpp $ */
+/* $Id: RTMpOn-r0drv-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Ring-0 Driver, Generic Stubs.
*/
diff --git a/src/VBox/Runtime/r0drv/generic/RTMpPokeCpu-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTMpPokeCpu-r0drv-generic.cpp
index 01835679e..e253d3ecf 100644
--- a/src/VBox/Runtime/r0drv/generic/RTMpPokeCpu-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTMpPokeCpu-r0drv-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpPokeCpu-r0drv-generic.cpp $ */
+/* $Id: RTMpPokeCpu-r0drv-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTMpPokeCpu, Generic Implementation.
*/
diff --git a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp
index 0d943b3b2..afc70a258 100644
--- a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTThreadPreemptDisable-r0drv-generic.cpp $ */
+/* $Id: RTThreadPreemptDisable-r0drv-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTThreadPreemptDisable, Generic ring-0 driver implementation.
*/
diff --git a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp
index 0e00439d0..d496cacfb 100644
--- a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTThreadPreemptIsEnabled-r0drv-generic.cpp $ */
+/* $Id: RTThreadPreemptIsEnabled-r0drv-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTThreadPreemptIsEnabled, Generic ring-0 driver implementation.
*/
diff --git a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPending-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPending-r0drv-generic.cpp
index 1fc9b894f..88e91de25 100644
--- a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPending-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPending-r0drv-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTThreadPreemptIsPending-r0drv-generic.cpp $ */
+/* $Id: RTThreadPreemptIsPending-r0drv-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTThreadPreemptIsPending, Generic ring-0 driver implementation.
*/
diff --git a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPendingTrusty-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPendingTrusty-r0drv-generic.cpp
index fe94d0226..2288b4d8c 100644
--- a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPendingTrusty-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPendingTrusty-r0drv-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTThreadPreemptIsPendingTrusty-r0drv-generic.cpp $ */
+/* $Id: RTThreadPreemptIsPendingTrusty-r0drv-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTThreadPreemptIsPendingTrusty, Generic ring-0 driver implementation.
*/
diff --git a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp
index 9fa8461e1..d327ea6ad 100644
--- a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTThreadPreemptRestore-r0drv-generic.cpp $ */
+/* $Id: RTThreadPreemptRestore-r0drv-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTThreadPreemptRestore, Generic ring-0 driver implementation.
*/
diff --git a/src/VBox/Runtime/r0drv/generic/mpnotification-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/mpnotification-r0drv-generic.cpp
index 0b22a8e57..f4336e557 100644
--- a/src/VBox/Runtime/r0drv/generic/mpnotification-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/mpnotification-r0drv-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: mpnotification-r0drv-generic.cpp $ */
+/* $Id: mpnotification-r0drv-generic.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Multiprocessor Notifications, Ring-0 Driver, Generic Stubs.
*/
@@ -53,13 +53,13 @@ RTDECL(int) RTMpNotificationDeregister(PFNRTMPNOTIFICATION pfnCallback, void *pv
RT_EXPORT_SYMBOL(RTMpNotificationDeregister);
-int rtR0MpNotificationInit(void)
+DECLHIDDEN(int) rtR0MpNotificationInit(void)
{
return VINF_SUCCESS;
}
-void rtR0MpNotificationTerm(void)
+DECLHIDDEN(void) rtR0MpNotificationTerm(void)
{
}
diff --git a/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c b/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c
index 69f29f24a..8bb2f9739 100644
--- a/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c
+++ b/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c
@@ -1,4 +1,4 @@
-/* $Id: semspinmutex-r0drv-generic.c $ */
+/* $Id: semspinmutex-r0drv-generic.c 33393 2010-10-24 16:17:00Z vboxsync $ */
/** @file
* IPRT - Spinning Mutex Semaphores, Ring-0 Driver, Generic.
*/
diff --git a/src/VBox/Runtime/r0drv/initterm-r0drv.cpp b/src/VBox/Runtime/r0drv/initterm-r0drv.cpp
index ba88e54ef..15ce42f88 100644
--- a/src/VBox/Runtime/r0drv/initterm-r0drv.cpp
+++ b/src/VBox/Runtime/r0drv/initterm-r0drv.cpp
@@ -1,4 +1,4 @@
-/* $Id: initterm-r0drv.cpp $ */
+/* $Id: initterm-r0drv.cpp 36233 2011-03-09 17:05:12Z vboxsync $ */
/** @file
* IPRT - Initialization & Termination, R0 Driver, Common.
*/
@@ -78,9 +78,7 @@ RTR0DECL(int) RTR0Init(unsigned fReserved)
rc = rtR0InitNative();
if (RT_SUCCESS(rc))
{
-#if !defined(RT_OS_LINUX) /** @todo implement thread2-r0drv-linux.c */
rc = rtThreadInit();
-#endif
if (RT_SUCCESS(rc))
{
#ifndef IN_GUEST /* play safe for now */
@@ -96,9 +94,7 @@ RTR0DECL(int) RTR0Init(unsigned fReserved)
if (RT_SUCCESS(rc))
return rc;
#endif
-#if !defined(RT_OS_LINUX) /** @todo implement thread2-r0drv-linux.c */
rtThreadTerm();
-#endif
}
rtR0TermNative();
}
@@ -109,9 +105,7 @@ RT_EXPORT_SYMBOL(RTR0Init);
static void rtR0Term(void)
{
-#if !defined(RT_OS_LINUX) /** @todo implement thread2-r0drv-linux.c */
rtThreadTerm();
-#endif
#ifndef IN_GUEST /* play safe for now */
rtR0PowerNotificationTerm();
rtR0MpNotificationTerm();
diff --git a/src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c
index 144d637ea..0bb7b0181 100644
--- a/src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: RTLogWriteDebugger-r0drv-linux.c $ */
+/* $Id: RTLogWriteDebugger-r0drv-linux.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Log To Debugger, Ring-0 Driver, Linux.
*/
diff --git a/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c
index 2534575bb..2300cff8c 100644
--- a/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: alloc-r0drv-linux.c $ */
+/* $Id: alloc-r0drv-linux.c 36962 2011-05-04 17:43:50Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, Ring-0 Driver, Linux.
*/
@@ -76,7 +76,7 @@ static size_t g_cPages;
* API for cleaning up the heap spinlock on IPRT termination.
* This is as RTMemExecDonate specific to AMD64 Linux/GNU.
*/
-void rtR0MemExecCleanup(void)
+DECLHIDDEN(void) rtR0MemExecCleanup(void)
{
# ifdef RTMEMALLOC_EXEC_HEAP_VM_AREA
unsigned i;
@@ -203,7 +203,7 @@ RT_EXPORT_SYMBOL(RTR0MemExecInit);
/**
* OS specific allocation function.
*/
-int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
+DECLHIDDEN(int) rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
{
PRTMEMHDR pHdr;
@@ -239,11 +239,25 @@ int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
}
else
{
- if (cb <= PAGE_SIZE || (fFlags & RTMEMHDR_FLAG_ANY_CTX))
+ if (
+#if 1 /* vmalloc has serious performance issues, avoid it. */
+ cb <= PAGE_SIZE*16 - sizeof(*pHdr)
+#else
+ cb <= PAGE_SIZE
+#endif
+ || (fFlags & RTMEMHDR_FLAG_ANY_CTX)
+ )
{
fFlags |= RTMEMHDR_FLAG_KMALLOC;
pHdr = kmalloc(cb + sizeof(*pHdr),
(fFlags & RTMEMHDR_FLAG_ANY_CTX_ALLOC) ? GFP_ATOMIC : GFP_KERNEL);
+ if (RT_UNLIKELY( !pHdr
+ && cb > PAGE_SIZE
+ && !(fFlags & RTMEMHDR_FLAG_ANY_CTX) ))
+ {
+ fFlags &= ~RTMEMHDR_FLAG_KMALLOC;
+ pHdr = vmalloc(cb + sizeof(*pHdr));
+ }
}
else
pHdr = vmalloc(cb + sizeof(*pHdr));
@@ -267,7 +281,7 @@ int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
/**
* OS specific free function.
*/
-void rtR0MemFree(PRTMEMHDR pHdr)
+DECLHIDDEN(void) rtR0MemFree(PRTMEMHDR pHdr)
{
pHdr->u32Magic += 1;
if (pHdr->fFlags & RTMEMHDR_FLAG_KMALLOC)
diff --git a/src/VBox/Runtime/r0drv/linux/assert-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/assert-r0drv-linux.c
index db9a1257b..0d5351d14 100644
--- a/src/VBox/Runtime/r0drv/linux/assert-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/assert-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: assert-r0drv-linux.c $ */
+/* $Id: assert-r0drv-linux.c 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Assertion Workers, Ring-0 Drivers, Linux.
*/
@@ -40,7 +40,7 @@
#include "internal/assert.h"
-void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
+DECLHIDDEN(void) rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
{
printk(KERN_EMERG
"\r\n!!Assertion Failed!!\r\n"
@@ -50,7 +50,7 @@ void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFi
}
-void rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
+DECLHIDDEN(void) rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
{
char szMsg[256];
diff --git a/src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c
index 0d27c022c..d76a42d4c 100644
--- a/src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: initterm-r0drv-linux.c $ */
+/* $Id: initterm-r0drv-linux.c 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Initialization & Termination, R0 Driver, Linux.
*/
@@ -40,17 +40,17 @@
*******************************************************************************/
#ifdef RT_ARCH_AMD64
/* in alloc-r0drv0-linux.c */
-extern void rtR0MemExecCleanup(void);
+DECLHIDDEN(void) rtR0MemExecCleanup(void);
#endif
-int rtR0InitNative(void)
+DECLHIDDEN(int) rtR0InitNative(void)
{
return VINF_SUCCESS;
}
-void rtR0TermNative(void)
+DECLHIDDEN(void) rtR0TermNative(void)
{
#ifdef RT_ARCH_AMD64
rtR0MemExecCleanup();
diff --git a/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
index 82f938b0b..2db3df78e 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: 69499 $ */
+/* $Revision: 36555 $ */
/** @file
* IPRT - Ring-0 Memory Objects, Linux.
*/
@@ -97,7 +97,7 @@ static void rtR0MemObjLinuxFreePages(PRTR0MEMOBJLNX pMemLnx);
* @returns The corresponding Linux task.
* @param R0Process IPRT ring-0 process handle.
*/
-struct task_struct *rtR0ProcessToLinuxTask(RTR0PROCESS R0Process)
+static struct task_struct *rtR0ProcessToLinuxTask(RTR0PROCESS R0Process)
{
/** @todo fix rtR0ProcessToLinuxTask!! */
return R0Process == RTR0ProcHandleSelf() ? current : NULL;
@@ -442,7 +442,7 @@ static void rtR0MemObjLinuxVUnmap(PRTR0MEMOBJLNX pMemLnx)
}
-int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
+DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
{
PRTR0MEMOBJLNX pMemLnx = (PRTR0MEMOBJLNX)pMem;
@@ -534,7 +534,7 @@ int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
}
-int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
PRTR0MEMOBJLNX pMemLnx;
int rc;
@@ -561,7 +561,7 @@ int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecu
}
-int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
PRTR0MEMOBJLNX pMemLnx;
int rc;
@@ -598,7 +598,7 @@ int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecut
}
-int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
PRTR0MEMOBJLNX pMemLnx;
int rc;
@@ -743,19 +743,19 @@ static int rtR0MemObjLinuxAllocPhysSub(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYP
}
-int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
{
return rtR0MemObjLinuxAllocPhysSub(ppMem, RTR0MEMOBJTYPE_PHYS, cb, uAlignment, PhysHighest);
}
-int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
{
return rtR0MemObjLinuxAllocPhysSub(ppMem, RTR0MEMOBJTYPE_PHYS_NC, cb, PAGE_SIZE, PhysHighest);
}
-int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
+DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
{
/*
* All we need to do here is to validate that we can use
@@ -778,7 +778,7 @@ int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t
}
-int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
{
const int cPages = cb >> PAGE_SHIFT;
struct task_struct *pTask = rtR0ProcessToLinuxTask(R0Process);
@@ -875,7 +875,7 @@ int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t c
}
-int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
+DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
{
void *pvLast = (uint8_t *)pv + cb - 1;
size_t const cPages = cb >> PAGE_SHIFT;
@@ -890,12 +890,26 @@ int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb,
* Classify the memory and check that we can deal with it.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
- fLinearMapping = virt_addr_valid(pvLast) && virt_addr_valid(pv);
+ 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));
#else
# error "not supported"
#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)
@@ -961,7 +975,7 @@ int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb,
}
-int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
+DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
const size_t cPages = cb >> PAGE_SHIFT;
@@ -1076,7 +1090,7 @@ static void *rtR0MemObjLinuxDoMmap(RTR3PTR R3PtrFixed, size_t cb, size_t uAlignm
}
-int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
{
PRTR0MEMOBJLNX pMemLnx;
void *pv;
@@ -1114,8 +1128,9 @@ int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed,
}
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
- unsigned fProt, size_t offSub, size_t cbSub)
+DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap,
+ void *pvFixed, size_t uAlignment,
+ unsigned fProt, size_t offSub, size_t cbSub)
{
int rc = VERR_NO_MEMORY;
PRTR0MEMOBJLNX pMemLnxToMap = (PRTR0MEMOBJLNX)pMemToMap;
@@ -1249,7 +1264,8 @@ static int rtR0MemObjLinuxFixPte(struct mm_struct *mm, unsigned long ulAddr, RTH
#endif /* VBOX_USE_PAE_HACK */
-int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed,
+ size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
{
struct task_struct *pTask = rtR0ProcessToLinuxTask(R0Process);
PRTR0MEMOBJLNX pMemLnxToMap = (PRTR0MEMOBJLNX)pMemToMap;
@@ -1413,7 +1429,7 @@ int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RT
}
-int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
+DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
{
NOREF(pMem);
NOREF(offSub);
@@ -1423,7 +1439,7 @@ int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSu
}
-RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
+DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
{
PRTR0MEMOBJLNX pMemLnx = (PRTR0MEMOBJLNX)pMem;
diff --git a/src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c
index 4517fea98..b9c470049 100644
--- a/src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: memuserkernel-r0drv-linux.c $ */
+/* $Id: memuserkernel-r0drv-linux.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - User & Kernel Memory, Ring-0 Driver, Linux.
*/
diff --git a/src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c
index 8545960ed..58a8a9e08 100644
--- a/src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: mp-r0drv-linux.c $ */
+/* $Id: mp-r0drv-linux.c 37672 2011-06-28 19:48:17Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Ring-0 Driver, Linux.
*/
@@ -35,6 +35,7 @@
#include <iprt/cpuset.h>
#include <iprt/err.h>
#include <iprt/asm.h>
+#include <iprt/thread.h>
#include "r0drv/mp-r0drv.h"
@@ -202,6 +203,9 @@ RTDECL(int) RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
int rc;
RTMPARGS Args;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+ RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
+#endif
Args.pfnWorker = pfnWorker;
Args.pvUser1 = pvUser1;
Args.pvUser2 = pvUser2;
@@ -212,19 +216,13 @@ RTDECL(int) RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
rc = on_each_cpu(rtmpLinuxWrapper, &Args, 1 /* wait */);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
rc = on_each_cpu(rtmpLinuxWrapper, &Args, 0 /* retry */, 1 /* wait */);
-
#else /* older kernels */
-
-# ifdef preempt_disable
- preempt_disable();
-# endif
+ RTThreadPreemptDisable(&PreemptState);
rc = smp_call_function(rtmpLinuxWrapper, &Args, 0 /* retry */, 1 /* wait */);
local_irq_disable();
rtmpLinuxWrapper(&Args);
local_irq_enable();
-# ifdef preempt_enable
- preempt_enable();
-# endif
+ RTThreadPreemptRestore(&PreemptState);
#endif /* older kernels */
Assert(rc == 0); NOREF(rc);
return VINF_SUCCESS;
@@ -237,23 +235,20 @@ RTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
int rc;
RTMPARGS Args;
+ RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
Args.pfnWorker = pfnWorker;
Args.pvUser1 = pvUser1;
Args.pvUser2 = pvUser2;
Args.idCpu = NIL_RTCPUID;
Args.cHits = 0;
-#ifdef preempt_disable
- preempt_disable();
-#endif
+ RTThreadPreemptDisable(&PreemptState);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
rc = smp_call_function(rtmpLinuxWrapper, &Args, 1 /* wait */);
#else /* older kernels */
rc = smp_call_function(rtmpLinuxWrapper, &Args, 0 /* retry */, 1 /* wait */);
#endif /* older kernels */
-#ifdef preempt_enable
- preempt_enable();
-#endif
+ RTThreadPreemptRestore(&PreemptState);
Assert(rc == 0); NOREF(rc);
return VINF_SUCCESS;
@@ -287,6 +282,7 @@ RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1
int rc;
RTMPARGS Args;
+ RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
Args.pfnWorker = pfnWorker;
Args.pvUser1 = pvUser1;
Args.pvUser2 = pvUser2;
@@ -296,9 +292,7 @@ RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1
if (!RTMpIsCpuPossible(idCpu))
return VERR_CPU_NOT_FOUND;
-# ifdef preempt_disable
- preempt_disable();
-# endif
+ RTThreadPreemptDisable(&PreemptState);
if (idCpu != RTMpCpuId())
{
if (RTMpIsCpuOnline(idCpu))
@@ -321,9 +315,7 @@ RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1
rtmpLinuxWrapper(&Args);
rc = VINF_SUCCESS;
}
-# ifdef preempt_enable
- preempt_enable();
-# endif
+ RTThreadPreemptRestore(&PreemptState);;
NOREF(rc);
return rc;
diff --git a/src/VBox/Runtime/r0drv/linux/mpnotification-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/mpnotification-r0drv-linux.c
index dd46f9eba..cd234d239 100644
--- a/src/VBox/Runtime/r0drv/linux/mpnotification-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/mpnotification-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: mpnotification-r0drv-linux.c $ */
+/* $Id: mpnotification-r0drv-linux.c 37672 2011-06-28 19:48:17Z vboxsync $ */
/** @file
* IPRT - Multiprocessor Event Notifications, Ring-0 Driver, Linux.
*/
@@ -34,6 +34,7 @@
#include <iprt/mp.h>
#include <iprt/err.h>
#include <iprt/cpuset.h>
+#include <iprt/thread.h>
#include "r0drv/mp-r0drv.h"
@@ -67,16 +68,63 @@ static RTCPUSET g_MpPendingOfflineSet;
/**
+ * Notification wrapper that updates CPU states and invokes our notification
+ * callbacks.
+ *
+ * @param idCpu The CPU Id.
+ * @param pvUser1 Pointer to the notifier_block (unused).
+ * @param pvUser2 The notification event.
+ * @remarks This can be invoked in interrupt context.
+ */
+static void rtMpNotificationLinuxOnCurrentCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+ unsigned long ulNativeEvent = *(unsigned long *)pvUser2;
+ NOREF(pvUser1);
+
+ AssertRelease(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+ AssertRelease(idCpu == RTMpCpuId()); /* ASSUMES iCpu == RTCPUID */
+
+ switch (ulNativeEvent)
+ {
+# ifdef CPU_DOWN_FAILED
+ case CPU_DOWN_FAILED:
+# if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_FAILED_FROZEN)
+ case CPU_DOWN_FAILED_FROZEN:
+# endif
+# endif
+ case CPU_ONLINE:
+# if defined(CPU_TASKS_FROZEN) && defined(CPU_ONLINE_FROZEN)
+ case CPU_ONLINE_FROZEN:
+# endif
+ rtMpNotificationDoCallbacks(RTMPEVENT_ONLINE, idCpu);
+ break;
+
+# ifdef CPU_DOWN_PREPARE
+ case CPU_DOWN_PREPARE:
+# if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_PREPARE_FROZEN)
+ case CPU_DOWN_PREPARE_FROZEN:
+# endif
+ rtMpNotificationDoCallbacks(RTMPEVENT_OFFLINE, idCpu);
+ break;
+# endif
+ }
+}
+
+
+/**
* The native callback.
*
- * @returns 0.
+ * @returns NOTIFY_DONE.
* @param pNotifierBlock Pointer to g_NotifierBlock.
* @param ulNativeEvent The native event.
* @param pvCpu The cpu id cast into a pointer value.
+ * @remarks This can fire with preemption enabled and on any CPU.
*/
static int rtMpNotificationLinuxCallback(struct notifier_block *pNotifierBlock, unsigned long ulNativeEvent, void *pvCpu)
{
- RTCPUID idCpu = (uintptr_t)pvCpu;
+ int rc;
+ bool fProcessEvent = false;
+ RTCPUID idCpu = (uintptr_t)pvCpu;
NOREF(pNotifierBlock);
/*
@@ -85,8 +133,6 @@ static int rtMpNotificationLinuxCallback(struct notifier_block *pNotifierBlock,
* use them. Thus we have to test for both CPU_TASKS_FROZEN and
* the individual event variants.
*/
-
- /* ASSUMES iCpu == RTCPUID */
switch (ulNativeEvent)
{
/*
@@ -99,7 +145,7 @@ static int rtMpNotificationLinuxCallback(struct notifier_block *pNotifierBlock,
case CPU_DOWN_FAILED_FROZEN:
# endif
if (!RTCpuSetIsMember(&g_MpPendingOfflineSet, idCpu))
- return 0;
+ break; /* fProcessEvents = false */
/* fall thru */
# endif
case CPU_ONLINE:
@@ -109,7 +155,7 @@ static int rtMpNotificationLinuxCallback(struct notifier_block *pNotifierBlock,
# ifdef CPU_DOWN_FAILED
RTCpuSetDel(&g_MpPendingOfflineSet, idCpu);
# endif
- rtMpNotificationDoCallbacks(RTMPEVENT_ONLINE, idCpu);
+ fProcessEvent = true;
break;
/*
@@ -122,24 +168,33 @@ static int rtMpNotificationLinuxCallback(struct notifier_block *pNotifierBlock,
# if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_PREPARE_FROZEN)
case CPU_DOWN_PREPARE_FROZEN:
# endif
+ fProcessEvent = true;
# else
case CPU_DEAD:
# if defined(CPU_TASKS_FROZEN) && defined(CPU_DEAD_FROZEN)
case CPU_DEAD_FROZEN:
# endif
+ /* Don't process CPU_DEAD notifications. */
# endif
- rtMpNotificationDoCallbacks(RTMPEVENT_OFFLINE, idCpu);
# ifdef CPU_DOWN_FAILED
RTCpuSetAdd(&g_MpPendingOfflineSet, idCpu);
# endif
break;
}
+ if (!fProcessEvent)
+ return NOTIFY_DONE;
+
+ /*
+ * Reschedule the callbacks to fire on the specific CPU with preemption disabled.
+ */
+ rc = RTMpOnSpecific(idCpu, rtMpNotificationLinuxOnCurrentCpu, pNotifierBlock, &ulNativeEvent);
+ Assert(RT_SUCCESS(rc)); NOREF(rc);
return NOTIFY_DONE;
}
-int rtR0MpNotificationNativeInit(void)
+DECLHIDDEN(int) rtR0MpNotificationNativeInit(void)
{
int rc;
@@ -153,19 +208,19 @@ int rtR0MpNotificationNativeInit(void)
}
-void rtR0MpNotificationNativeTerm(void)
+DECLHIDDEN(void) rtR0MpNotificationNativeTerm(void)
{
unregister_cpu_notifier(&g_NotifierBlock);
}
#else /* Not supported / Not needed */
-int rtR0MpNotificationNativeInit(void)
+DECLHIDDEN(int) rtR0MpNotificationNativeInit(void)
{
return VINF_SUCCESS;
}
-void rtR0MpNotificationNativeTerm(void)
+DECLHIDDEN(void) rtR0MpNotificationNativeTerm(void)
{
}
diff --git a/src/VBox/Runtime/r0drv/linux/process-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/process-r0drv-linux.c
index e69aeace2..4c838081a 100644
--- a/src/VBox/Runtime/r0drv/linux/process-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/process-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: process-r0drv-linux.c $ */
+/* $Id: process-r0drv-linux.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Process, Ring-0 Driver, Linux.
*/
diff --git a/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c
index 2506adc87..de9b2bd83 100644
--- a/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: semevent-r0drv-linux.c $ */
+/* $Id: semevent-r0drv-linux.c 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Single Release Event Semaphores, Ring-0 Driver, Linux.
*/
diff --git a/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c
index 74cc39002..23a248544 100644
--- a/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: semeventmulti-r0drv-linux.c $ */
+/* $Id: semeventmulti-r0drv-linux.c 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Multiple Release Event Semaphores, Ring-0 Driver, Linux.
*/
diff --git a/src/VBox/Runtime/r0drv/linux/semfastmutex-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/semfastmutex-r0drv-linux.c
index 45d1d5128..e23fdeb0d 100644
--- a/src/VBox/Runtime/r0drv/linux/semfastmutex-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/semfastmutex-r0drv-linux.c
@@ -1,10 +1,10 @@
-/* $Id: semfastmutex-r0drv-linux.c $ */
+/* $Id: semfastmutex-r0drv-linux.c 36979 2011-05-06 11:55:42Z vboxsync $ */
/** @file
* IPRT - Fast Mutex Semaphores, Ring-0 Driver, Linux.
*/
/*
- * Copyright (C) 2006-2007 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,7 +35,7 @@
#include <iprt/assert.h>
#include <iprt/asm.h>
#include <iprt/err.h>
-#ifdef IPRT_DEBUG_SEMS
+#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
# include <iprt/thread.h>
#endif
@@ -54,7 +54,7 @@ typedef struct RTSEMFASTMUTEXINTERNAL
uint32_t u32Magic;
/** the linux semaphore. */
struct semaphore Semaphore;
-#ifdef IPRT_DEBUG_SEMS
+#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
/** For check. */
RTNATIVETHREAD volatile Owner;
#endif
@@ -76,7 +76,7 @@ RTDECL(int) RTSemFastMutexCreate(PRTSEMFASTMUTEX phFastMtx)
*/
pThis->u32Magic = RTSEMFASTMUTEX_MAGIC;
sema_init(&pThis->Semaphore, 1);
-#ifdef IPRT_DEBUG_SEMS
+#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
pThis->Owner = NIL_RTNATIVETHREAD;
#endif
@@ -115,7 +115,7 @@ RTDECL(int) RTSemFastMutexRequest(RTSEMFASTMUTEX hFastMtx)
IPRT_DEBUG_SEMS_STATE(pThis, 'd');
down(&pThis->Semaphore);
-#ifdef IPRT_DEBUG_SEMS
+#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
IPRT_DEBUG_SEMS_STATE(pThis, 'o');
AssertRelease(pThis->Owner == NIL_RTNATIVETHREAD);
ASMAtomicUoWriteSize(&pThis->Owner, RTThreadNativeSelf());
@@ -134,7 +134,7 @@ RTDECL(int) RTSemFastMutexRelease(RTSEMFASTMUTEX hFastMtx)
AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
-#ifdef IPRT_DEBUG_SEMS
+#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
AssertRelease(pThis->Owner == RTThreadNativeSelf());
ASMAtomicUoWriteSize(&pThis->Owner, NIL_RTNATIVETHREAD);
#endif
diff --git a/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c
index de257acc4..f8c6c8928 100644
--- a/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: semmutex-r0drv-linux.c $ */
+/* $Id: semmutex-r0drv-linux.c 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Mutex Semaphores, Ring-0 Driver, Linux.
*/
diff --git a/src/VBox/Runtime/r0drv/linux/spinlock-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/spinlock-r0drv-linux.c
index e3be185f0..e68b5b0c8 100644
--- a/src/VBox/Runtime/r0drv/linux/spinlock-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/spinlock-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: spinlock-r0drv-linux.c $ */
+/* $Id: spinlock-r0drv-linux.c 29250 2010-05-09 17:53:58Z vboxsync $ */
/** @file
* IPRT - Spinlocks, Ring-0 Driver, Linux.
*/
diff --git a/src/VBox/Runtime/r0drv/linux/string.h b/src/VBox/Runtime/r0drv/linux/string.h
index f2f319411..b581ae53a 100644
--- a/src/VBox/Runtime/r0drv/linux/string.h
+++ b/src/VBox/Runtime/r0drv/linux/string.h
@@ -1,4 +1,4 @@
-/* $Id: string.h $ */
+/* $Id: string.h 33012 2010-10-08 15:46:40Z vboxsync $ */
/** @file
* IPRT - wrapper for the linux kernel asm/string.h.
*/
diff --git a/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h b/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
index 5bd9d0132..a993b5b21 100644
--- a/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
+++ b/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
@@ -1,4 +1,4 @@
-/* $Id: the-linux-kernel.h $ */
+/* $Id: the-linux-kernel.h 36233 2011-03-09 17:05:12Z vboxsync $ */
/** @file
* IPRT - Include all necessary headers for the Linux kernel.
*/
@@ -118,6 +118,10 @@
#include <asm/uaccess.h>
#include <asm/div64.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+# include <linux/kthread.h>
+#endif
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
# ifndef page_to_pfn
# define page_to_pfn(page) ((page) - mem_map)
@@ -363,6 +367,4 @@ DECLINLINE(unsigned long) msecs_to_jiffies(unsigned int cMillies)
# define IPRT_LINUX_HAS_HRTIMER
#endif
-
#endif
-
diff --git a/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c
index 44edbc2ac..7ada61e3d 100644
--- a/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: thread-r0drv-linux.c $ */
+/* $Id: thread-r0drv-linux.c 33358 2010-10-22 14:06:43Z vboxsync $ */
/** @file
* IPRT - Threads, Ring-0 Driver, Linux.
*/
diff --git a/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c
index 381bd2e82..1ac95ea52 100644
--- a/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c
@@ -1,10 +1,10 @@
-/* $Id: thread2-r0drv-linux.c $ */
+/* $Id: thread2-r0drv-linux.c 36947 2011-05-03 19:49:12Z vboxsync $ */
/** @file
* IPRT - Threads (Part 2), Ring-0 Driver, Linux.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -37,10 +37,111 @@
#include "internal/thread.h"
-/** @todo Later.
RTDECL(RTTHREAD) RTThreadSelf(void)
{
return rtThreadGetByNative((RTNATIVETHREAD)current);
}
-*/
+
+
+DECLHIDDEN(int) rtThreadNativeInit(void)
+{
+ return VINF_SUCCESS;
+}
+
+
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
+ /* See comment near MAX_RT_PRIO in linux/sched.h for details on
+ sched_priority. */
+ int iSchedClass = SCHED_NORMAL;
+ struct sched_param Param = { .sched_priority = MAX_PRIO - 1 };
+ switch (enmType)
+ {
+ case RTTHREADTYPE_INFREQUENT_POLLER:
+ Param.sched_priority = MAX_RT_PRIO + 5;
+ break;
+
+ case RTTHREADTYPE_EMULATION:
+ Param.sched_priority = MAX_RT_PRIO + 4;
+ break;
+
+ case RTTHREADTYPE_DEFAULT:
+ Param.sched_priority = MAX_RT_PRIO + 3;
+ break;
+
+ case RTTHREADTYPE_MSG_PUMP:
+ Param.sched_priority = MAX_RT_PRIO + 2;
+ break;
+
+ case RTTHREADTYPE_IO:
+ iSchedClass = SCHED_FIFO;
+ Param.sched_priority = MAX_RT_PRIO - 1;
+ break;
+
+ case RTTHREADTYPE_TIMER:
+ iSchedClass = SCHED_FIFO;
+ Param.sched_priority = 1; /* not 0 just in case */
+ break;
+
+ default:
+ AssertMsgFailed(("enmType=%d\n", enmType));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ sched_setscheduler(current, iSchedClass, &Param);
+#endif
+
+ return VINF_SUCCESS;
+}
+
+
+DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread)
+{
+ return VERR_NOT_IMPLEMENTED;
+}
+
+
+DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread)
+{
+ NOREF(pThread);
+}
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 4)
+/**
+ * Native kernel thread wrapper function.
+ *
+ * This will forward to rtThreadMain and do termination upon return.
+ *
+ * @param pvArg Pointer to the argument package.
+ */
+static int rtThreadNativeMain(void *pvArg)
+{
+ PRTTHREADINT pThread = (PRTTHREADINT)pvArg;
+
+ rtThreadMain(pThread, (RTNATIVETHREAD)current, &pThread->szName[0]);
+ return 0;
+}
+#endif
+
+
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 4)
+ struct task_struct *NativeThread;
+
+ RT_ASSERT_PREEMPTIBLE();
+
+ NativeThread = kthread_run(rtThreadNativeMain, pThreadInt, "iprt-%s", pThreadInt->szName);
+
+ if (IS_ERR(NativeThread))
+ return VERR_GENERAL_FAILURE;
+
+ *pNativeThread = (RTNATIVETHREAD)NativeThread;
+ return VINF_SUCCESS;
+#else
+ return VERR_NOT_IMPLEMENTED;
+#endif
+}
diff --git a/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c
index c0fb357f2..28312e17c 100644
--- a/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: time-r0drv-linux.c $ */
+/* $Id: time-r0drv-linux.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Time, Ring-0 Driver, Linux.
*/
diff --git a/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c
index efad6b0a8..1d7042838 100644
--- a/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: timer-r0drv-linux.c $ */
+/* $Id: timer-r0drv-linux.c 33603 2010-10-29 12:42:24Z vboxsync $ */
/** @file
* IPRT - Timers, Ring-0 Driver, Linux.
*/
diff --git a/src/VBox/Runtime/r0drv/linux/waitqueue-r0drv-linux.h b/src/VBox/Runtime/r0drv/linux/waitqueue-r0drv-linux.h
index ba253c680..75c781f9e 100644
--- a/src/VBox/Runtime/r0drv/linux/waitqueue-r0drv-linux.h
+++ b/src/VBox/Runtime/r0drv/linux/waitqueue-r0drv-linux.h
@@ -1,4 +1,4 @@
-/* $Id: waitqueue-r0drv-linux.h $ */
+/* $Id: waitqueue-r0drv-linux.h 33630 2010-10-31 16:00:19Z vboxsync $ */
/** @file
* IPRT - Linux Ring-0 Driver Helpers for Abstracting Wait Queues,
*/
diff --git a/src/VBox/Runtime/r0drv/memobj-r0drv.cpp b/src/VBox/Runtime/r0drv/memobj-r0drv.cpp
index 14a4ed4f5..8ec15a27c 100644
--- a/src/VBox/Runtime/r0drv/memobj-r0drv.cpp
+++ b/src/VBox/Runtime/r0drv/memobj-r0drv.cpp
@@ -1,4 +1,4 @@
-/* $Revision: 67140 $ */
+/* $Revision: 36555 $ */
/** @file
* IPRT - Ring-0 Memory Objects, Common Code.
*/
@@ -54,7 +54,7 @@
* @param pv The memory object mapping.
* @param cb The size of the memory object.
*/
-PRTR0MEMOBJINTERNAL rtR0MemObjNew(size_t cbSelf, RTR0MEMOBJTYPE enmType, void *pv, size_t cb)
+DECLHIDDEN(PRTR0MEMOBJINTERNAL) rtR0MemObjNew(size_t cbSelf, RTR0MEMOBJTYPE enmType, void *pv, size_t cb)
{
PRTR0MEMOBJINTERNAL pNew;
@@ -63,6 +63,7 @@ PRTR0MEMOBJINTERNAL rtR0MemObjNew(size_t cbSelf, RTR0MEMOBJTYPE enmType, void *p
cbSelf = sizeof(*pNew);
Assert(cbSelf >= sizeof(*pNew));
Assert(cbSelf == (uint32_t)cbSelf);
+ AssertMsg(RT_ALIGN_Z(cb, PAGE_SIZE) == cb, ("%#zx\n", cb));
/*
* Allocate and initialize the object.
@@ -88,7 +89,7 @@ PRTR0MEMOBJINTERNAL rtR0MemObjNew(size_t cbSelf, RTR0MEMOBJTYPE enmType, void *p
*
* @param pMem The incomplete memory object to delete.
*/
-void rtR0MemObjDelete(PRTR0MEMOBJINTERNAL pMem)
+DECLHIDDEN(void) rtR0MemObjDelete(PRTR0MEMOBJINTERNAL pMem)
{
if (pMem)
{
@@ -225,7 +226,12 @@ RT_EXPORT_SYMBOL(RTR0MemObjAddressR3);
/**
* Gets the size of a ring-0 memory object.
*
- * @returns The address of the memory object.
+ * The returned value may differ from the one specified to the API creating the
+ * object because of alignment adjustments. The minimal alignment currently
+ * employed by any API is PAGE_SIZE, so the result can safely be shifted by
+ * PAGE_SHIFT to calculate a page count.
+ *
+ * @returns The object size.
* @returns 0 if the handle is invalid (asserts in strict builds) or if there isn't any mapping.
* @param MemObj The ring-0 memory object handle.
*/
@@ -240,6 +246,7 @@ RTR0DECL(size_t) RTR0MemObjSize(RTR0MEMOBJ MemObj)
pMem = (PRTR0MEMOBJINTERNAL)MemObj;
AssertMsgReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, ("%p: %#x\n", pMem, pMem->u32Magic), 0);
AssertMsgReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, ("%p: %d\n", pMem, pMem->enmType), 0);
+ AssertMsg(RT_ALIGN_Z(pMem->cb, PAGE_SIZE) == pMem->cb, ("%#zx\n", pMem->cb));
/* return the size. */
return pMem->cb;
diff --git a/src/VBox/Runtime/r0drv/mp-r0drv.h b/src/VBox/Runtime/r0drv/mp-r0drv.h
index a32ae5d65..81c4b742a 100644
--- a/src/VBox/Runtime/r0drv/mp-r0drv.h
+++ b/src/VBox/Runtime/r0drv/mp-r0drv.h
@@ -1,4 +1,4 @@
-/* $Id: mp-r0drv.h $ */
+/* $Id: mp-r0drv.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Ring-0 Driver, Internal Header.
*/
@@ -58,13 +58,13 @@ typedef struct RTMPARGS
typedef RTMPARGS *PRTMPARGS;
/* Called from initterm-r0drv.cpp: */
-int rtR0MpNotificationInit(void);
-void rtR0MpNotificationTerm(void);
+DECLHIDDEN(int) rtR0MpNotificationInit(void);
+DECLHIDDEN(void) rtR0MpNotificationTerm(void);
/* The following is only relevant when using mpnotifcation-r0drv.cpp: */
-int rtR0MpNotificationNativeInit(void);
-void rtR0MpNotificationNativeTerm(void);
-void rtMpNotificationDoCallbacks(RTMPEVENT enmEvent, RTCPUID idCpu);
+DECLHIDDEN(int) rtR0MpNotificationNativeInit(void);
+DECLHIDDEN(void) rtR0MpNotificationNativeTerm(void);
+DECLHIDDEN(void) rtMpNotificationDoCallbacks(RTMPEVENT enmEvent, RTCPUID idCpu);
RT_C_DECLS_END
diff --git a/src/VBox/Runtime/r0drv/mpnotification-r0drv.c b/src/VBox/Runtime/r0drv/mpnotification-r0drv.c
index ea5a3c11a..d9c7a2422 100644
--- a/src/VBox/Runtime/r0drv/mpnotification-r0drv.c
+++ b/src/VBox/Runtime/r0drv/mpnotification-r0drv.c
@@ -1,4 +1,4 @@
-/* $Id: mpnotification-r0drv.c $ */
+/* $Id: mpnotification-r0drv.c 37211 2011-05-25 11:37:52Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Ring-0 Driver, Event Notifications.
*/
@@ -89,7 +89,7 @@ static uint32_t volatile g_iRTMpGeneration;
* @param idCpu The CPU id the event applies to.
* @param enmEvent The event.
*/
-void rtMpNotificationDoCallbacks(RTMPEVENT enmEvent, RTCPUID idCpu)
+DECLHIDDEN(void) rtMpNotificationDoCallbacks(RTMPEVENT enmEvent, RTCPUID idCpu)
{
PRTMPNOTIFYREG pCur;
RTSPINLOCK hSpinlock;
@@ -277,7 +277,7 @@ RTDECL(int) RTMpNotificationDeregister(PFNRTMPNOTIFICATION pfnCallback, void *pv
RT_EXPORT_SYMBOL(RTMpNotificationDeregister);
-int rtR0MpNotificationInit(void)
+DECLHIDDEN(int) rtR0MpNotificationInit(void)
{
int rc = RTSpinlockCreate((PRTSPINLOCK)&g_hRTMpNotifySpinLock);
if (RT_SUCCESS(rc))
@@ -293,7 +293,7 @@ int rtR0MpNotificationInit(void)
}
-void rtR0MpNotificationTerm(void)
+DECLHIDDEN(void) rtR0MpNotificationTerm(void)
{
PRTMPNOTIFYREG pHead;
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
@@ -304,7 +304,7 @@ void rtR0MpNotificationTerm(void)
/* pick up the list and the spinlock. */
RTSpinlockAcquire(hSpinlock, &Tmp);
- ASMAtomicWriteSize(&g_hRTMpNotifySpinLock, NIL_RTSPINLOCK);
+ ASMAtomicWriteHandle(&g_hRTMpNotifySpinLock, NIL_RTSPINLOCK);
pHead = g_pRTMpCallbackHead;
g_pRTMpCallbackHead = NULL;
ASMAtomicIncU32(&g_iRTMpGeneration);
diff --git a/src/VBox/Runtime/r0drv/nt/RTLogWriteDebugger-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/RTLogWriteDebugger-r0drv-nt.cpp
index 95d6a112b..11c5143b3 100644
--- a/src/VBox/Runtime/r0drv/nt/RTLogWriteDebugger-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/RTLogWriteDebugger-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTLogWriteDebugger-r0drv-nt.cpp $ */
+/* $Id: RTLogWriteDebugger-r0drv-nt.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Log To Debugger, Ring-0 Driver, NT.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/RTTimerGetSystemGranularity-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/RTTimerGetSystemGranularity-r0drv-nt.cpp
index fead7554d..2927d6771 100644
--- a/src/VBox/Runtime/r0drv/nt/RTTimerGetSystemGranularity-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/RTTimerGetSystemGranularity-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTTimerGetSystemGranularity-r0drv-nt.cpp $ */
+/* $Id: RTTimerGetSystemGranularity-r0drv-nt.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - RTTimerGetSystemGranularity, Ring-0 Driver, NT.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/alloc-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/alloc-r0drv-nt.cpp
index 9f7659a84..9f8e9c16b 100644
--- a/src/VBox/Runtime/r0drv/nt/alloc-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/alloc-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: alloc-r0drv-nt.cpp $ */
+/* $Id: alloc-r0drv-nt.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, Ring-0 Driver, NT.
*/
@@ -40,7 +40,7 @@
/**
* OS specific allocation function.
*/
-int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
+DECLHIDDEN(int) rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
{
if (fFlags & RTMEMHDR_FLAG_ANY_CTX)
return VERR_NOT_SUPPORTED;
@@ -61,7 +61,7 @@ int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
/**
* OS specific free function.
*/
-void rtR0MemFree(PRTMEMHDR pHdr)
+DECLHIDDEN(void) rtR0MemFree(PRTMEMHDR pHdr)
{
pHdr->u32Magic += 1;
ExFreePool(pHdr);
diff --git a/src/VBox/Runtime/r0drv/nt/assert-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/assert-r0drv-nt.cpp
index 056eabb7d..065ca9d93 100644
--- a/src/VBox/Runtime/r0drv/nt/assert-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/assert-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: assert-r0drv-nt.cpp $ */
+/* $Id: assert-r0drv-nt.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Assertion Workers, Ring-0 Drivers, NT.
*/
@@ -37,7 +37,7 @@
#include "internal/assert.h"
-void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
+DECLHIDDEN(void) rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
{
DbgPrint("\n!!Assertion Failed!!\n"
"Expression: %s\n"
@@ -46,7 +46,7 @@ void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFi
}
-void rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
+DECLHIDDEN(void) rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
{
char szMsg[256];
diff --git a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
index fc885b288..2c5137d65 100644
--- a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: initterm-r0drv-nt.cpp $ */
+/* $Id: initterm-r0drv-nt.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Initialization & Termination, R0 Driver, NT.
*/
@@ -71,7 +71,7 @@ uint32_t g_offrtNtPbDpcQueueDepth;
-int rtR0InitNative(void)
+DECLHIDDEN(int) rtR0InitNative(void)
{
/*
* Init the Nt cpu set.
@@ -263,7 +263,7 @@ int rtR0InitNative(void)
}
-void rtR0TermNative(void)
+DECLHIDDEN(void) rtR0TermNative(void)
{
}
diff --git a/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h b/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
index e04230faf..2d4c85aeb 100644
--- a/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
+++ b/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
@@ -1,4 +1,4 @@
-/* $Id: internal-r0drv-nt.h $ */
+/* $Id: internal-r0drv-nt.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Internal Header for the NT Ring-0 Driver Code.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp
index 4a28cb726..0ffa3b2ba 100644
--- a/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: memobj-r0drv-nt.cpp $ */
+/* $Id: memobj-r0drv-nt.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Ring-0 Memory Objects, NT.
*/
@@ -78,7 +78,7 @@ typedef struct RTR0MEMOBJNT
} RTR0MEMOBJNT, *PRTR0MEMOBJNT;
-int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
+DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
{
PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)pMem;
@@ -215,7 +215,7 @@ int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
}
-int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
AssertMsgReturn(cb <= _1G, ("%#x\n", cb), VERR_OUT_OF_RANGE); /* for safe size_t -> ULONG */
@@ -257,7 +257,7 @@ int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecu
}
-int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
AssertMsgReturn(cb <= _1G, ("%#x\n", cb), VERR_OUT_OF_RANGE); /* for safe size_t -> ULONG */
@@ -396,13 +396,13 @@ static int rtR0MemObjNativeAllocContEx(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bo
}
-int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
return rtR0MemObjNativeAllocContEx(ppMem, cb, fExecutable, _4G-1, PAGE_SIZE /* alignment */);
}
-int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
{
#ifndef IPRT_TARGET_NT4
/*
@@ -462,7 +462,7 @@ int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS Ph
}
-int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
{
#ifndef IPRT_TARGET_NT4
PHYSICAL_ADDRESS Zero;
@@ -494,7 +494,7 @@ int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS
}
-int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
+DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
{
AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
@@ -640,7 +640,8 @@ static int rtR0MemObjNtLock(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uin
}
-int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess,
+ RTR0PROCESS R0Process)
{
AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
/* (Can use MmProbeAndLockProcessPages if we need to mess with other processes later.) */
@@ -648,13 +649,13 @@ int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t c
}
-int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
+DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
{
return rtR0MemObjNtLock(ppMem, pv, cb, fAccess, NIL_RTR0PROCESS);
}
-int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
+DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
{
/*
* MmCreateSection(SEC_RESERVE) + MmMapViewInSystemSpace perhaps?
@@ -663,7 +664,8 @@ int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, siz
}
-int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment,
+ RTR0PROCESS R0Process)
{
/*
* ZeCreateSection(SEC_RESERVE) + ZwMapViewOfSection perhaps?
@@ -799,7 +801,7 @@ static int rtR0MemObjNtMap(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, voi
}
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
unsigned fProt, size_t offSub, size_t cbSub)
{
AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
@@ -807,14 +809,14 @@ int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap,
}
-int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
{
AssertReturn(R0Process == RTR0ProcHandleSelf(), VERR_NOT_SUPPORTED);
return rtR0MemObjNtMap(ppMem, pMemToMap, (void *)R3PtrFixed, uAlignment, fProt, R0Process);
}
-int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
+DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
{
NOREF(pMem);
NOREF(offSub);
@@ -824,7 +826,7 @@ int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSu
}
-RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
+DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
{
PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)pMem;
diff --git a/src/VBox/Runtime/r0drv/nt/memuserkernel-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/memuserkernel-r0drv-nt.cpp
index 9abfd83f5..02f411a8e 100644
--- a/src/VBox/Runtime/r0drv/nt/memuserkernel-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/memuserkernel-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: memuserkernel-r0drv-nt.cpp $ */
+/* $Id: memuserkernel-r0drv-nt.cpp 29705 2010-05-20 15:58:39Z vboxsync $ */
/** @file
* IPRT - User & Kernel Memory, Ring-0 Driver, NT.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp
index fb7287720..da1dcae96 100644
--- a/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: mp-r0drv-nt.cpp $ */
+/* $Id: mp-r0drv-nt.cpp 37379 2011-06-08 14:21:34Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Ring-0 Driver, NT.
*/
@@ -344,11 +344,13 @@ static VOID rtMpNtPokeCpuDummy(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID
#ifndef IPRT_TARGET_NT4
-ULONG_PTR rtMpIpiGenericCall(ULONG_PTR Argument)
+ULONG_PTR rtMpIpiGenericCall(ULONG_PTR Argument)
{
+ NOREF(Argument);
return 0;
}
+
int rtMpSendIpiVista(RTCPUID idCpu)
{
g_pfnrtKeIpiGenericCall(rtMpIpiGenericCall, 0);
@@ -356,19 +358,23 @@ int rtMpSendIpiVista(RTCPUID idCpu)
return VINF_SUCCESS;
}
+
int rtMpSendIpiWin7(RTCPUID idCpu)
{
g_pfnrtKeIpiGenericCall(rtMpIpiGenericCall, 0);
//// g_pfnrtNtHalSendSoftwareInterrupt(idCpu, DISPATCH_LEVEL);
return VINF_SUCCESS;
}
+
#endif /* IPRT_TARGET_NT4 */
+
int rtMpSendIpiDummy(RTCPUID idCpu)
{
return VERR_NOT_IMPLEMENTED;
}
+
RTDECL(int) RTMpPokeCpu(RTCPUID idCpu)
{
if (!RTMpIsCpuOnline(idCpu))
diff --git a/src/VBox/Runtime/r0drv/nt/mpnotification-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/mpnotification-r0drv-nt.cpp
index 5e7532447..629e1857a 100644
--- a/src/VBox/Runtime/r0drv/nt/mpnotification-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/mpnotification-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: mpnotification-r0drv-nt.cpp $ */
+/* $Id: mpnotification-r0drv-nt.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Multiprocessor Event Notifications, Ring-0 Driver, NT.
*/
@@ -124,7 +124,7 @@ static VOID __stdcall rtMpNotificationNtCallback(PVOID pvUser,
}
-int rtR0MpNotificationNativeInit(void)
+DECLHIDDEN(int) rtR0MpNotificationNativeInit(void)
{
/*
* Try resolve the symbols.
@@ -163,7 +163,7 @@ int rtR0MpNotificationNativeInit(void)
}
-void rtR0MpNotificationNativeTerm(void)
+DECLHIDDEN(void) rtR0MpNotificationNativeTerm(void)
{
if ( g_pfnKeDeregisterProcessorChangeCallback
&& g_hCallback)
@@ -175,12 +175,12 @@ void rtR0MpNotificationNativeTerm(void)
#else /* Not supported */
-int rtR0MpNotificationNativeInit(void)
+DECLHIDDEN(int) rtR0MpNotificationNativeInit(void)
{
return VINF_SUCCESS;
}
-void rtR0MpNotificationNativeTerm(void)
+DECLHIDDEN(void) rtR0MpNotificationNativeTerm(void)
{
}
diff --git a/src/VBox/Runtime/r0drv/nt/process-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/process-r0drv-nt.cpp
index 934887659..30e5be609 100644
--- a/src/VBox/Runtime/r0drv/nt/process-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/process-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: process-r0drv-nt.cpp $ */
+/* $Id: process-r0drv-nt.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Process, Ring-0 Driver, NT.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/semevent-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/semevent-r0drv-nt.cpp
index 8cda329eb..fb64eeb1b 100644
--- a/src/VBox/Runtime/r0drv/nt/semevent-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/semevent-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: semevent-r0drv-nt.cpp $ */
+/* $Id: semevent-r0drv-nt.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Single Release Event Semaphores, Ring-0 Driver, NT.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/semeventmulti-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/semeventmulti-r0drv-nt.cpp
index 50830f754..8da0899b7 100644
--- a/src/VBox/Runtime/r0drv/nt/semeventmulti-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/semeventmulti-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: semeventmulti-r0drv-nt.cpp $ */
+/* $Id: semeventmulti-r0drv-nt.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Multiple Release Event Semaphores, Ring-0 Driver, NT.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/semfastmutex-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/semfastmutex-r0drv-nt.cpp
index bd3efc87c..62d7bc0b2 100644
--- a/src/VBox/Runtime/r0drv/nt/semfastmutex-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/semfastmutex-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: semfastmutex-r0drv-nt.cpp $ */
+/* $Id: semfastmutex-r0drv-nt.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Fast Mutex Semaphores, Ring-0 Driver, NT.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp
index 71e02e35c..f3b1cc21b 100644
--- a/src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: semmutex-r0drv-nt.cpp $ */
+/* $Id: semmutex-r0drv-nt.cpp 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Mutex Semaphores, Ring-0 Driver, NT.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/spinlock-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/spinlock-r0drv-nt.cpp
index 1dc11be23..8f9fdcf65 100644
--- a/src/VBox/Runtime/r0drv/nt/spinlock-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/spinlock-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: spinlock-r0drv-nt.cpp $ */
+/* $Id: spinlock-r0drv-nt.cpp 32463 2010-09-14 07:30:11Z vboxsync $ */
/** @file
* IPRT - Spinlocks, Ring-0 Driver, NT.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/the-nt-kernel.h b/src/VBox/Runtime/r0drv/nt/the-nt-kernel.h
index 3da03794c..ada6354e3 100644
--- a/src/VBox/Runtime/r0drv/nt/the-nt-kernel.h
+++ b/src/VBox/Runtime/r0drv/nt/the-nt-kernel.h
@@ -1,4 +1,4 @@
-/* $Id: the-nt-kernel.h $ */
+/* $Id: the-nt-kernel.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Include all necessary headers for the NT kernel.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp
index f120040fa..36a6ea25a 100644
--- a/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: thread-r0drv-nt.cpp $ */
+/* $Id: thread-r0drv-nt.cpp 30359 2010-06-22 09:21:33Z vboxsync $ */
/** @file
* IPRT - Threads, Ring-0 Driver, NT.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp
index 03a3ffe0e..e9361862c 100644
--- a/src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: thread2-r0drv-nt.cpp $ */
+/* $Id: thread2-r0drv-nt.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Threads (Part 2), Ring-0 Driver, NT.
*/
@@ -36,7 +36,7 @@
#include "internal/thread.h"
-int rtThreadNativeInit(void)
+DECLHIDDEN(int) rtThreadNativeInit(void)
{
/* No TLS in Ring-0. :-/ */
return VINF_SUCCESS;
@@ -49,7 +49,7 @@ RTDECL(RTTHREAD) RTThreadSelf(void)
}
-int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
{
/*
* Convert the IPRT priority type to NT priority.
@@ -81,13 +81,13 @@ int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
}
-int rtThreadNativeAdopt(PRTTHREADINT pThread)
+DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread)
{
return VERR_NOT_IMPLEMENTED;
}
-void rtThreadNativeDestroy(PRTTHREADINT pThread)
+DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread)
{
NOREF(pThread);
}
@@ -111,7 +111,7 @@ static VOID __stdcall rtThreadNativeMain(PVOID pvArg)
}
-int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
{
/*
* PsCreateSysemThread create a thread an give us a handle in return.
diff --git a/src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp
index 965f2cbb9..9545caa23 100644
--- a/src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: time-r0drv-nt.cpp $ */
+/* $Id: time-r0drv-nt.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Time, Ring-0 Driver, Nt.
*/
diff --git a/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp
index 4f7c82db4..44aa52f46 100644
--- a/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp
@@ -1,4 +1,4 @@
-/* $Id: timer-r0drv-nt.cpp $ */
+/* $Id: timer-r0drv-nt.cpp 33155 2010-10-15 12:07:44Z vboxsync $ */
/** @file
* IPRT - Timers, Ring-0 Driver, NT.
*/
diff --git a/src/VBox/Runtime/r0drv/os2/RTR0AssertPanicSystem-r0drv-os2.asm b/src/VBox/Runtime/r0drv/os2/RTR0AssertPanicSystem-r0drv-os2.asm
index 17e370520..dedefeb81 100644
--- a/src/VBox/Runtime/r0drv/os2/RTR0AssertPanicSystem-r0drv-os2.asm
+++ b/src/VBox/Runtime/r0drv/os2/RTR0AssertPanicSystem-r0drv-os2.asm
@@ -1,4 +1,4 @@
-; $Id: RTR0AssertPanicSystem-r0drv-os2.asm $
+; $Id: RTR0AssertPanicSystem-r0drv-os2.asm 13306 2008-10-15 21:17:04Z vboxsync $
;; @file
; IPRT - RTR0AssertPanicSystem, Ring-0 Driver, OS/2.
;
diff --git a/src/VBox/Runtime/r0drv/os2/RTR0Os2DHQueryDOSVar.asm b/src/VBox/Runtime/r0drv/os2/RTR0Os2DHQueryDOSVar.asm
index e0c94b7f2..2ad429f45 100644
--- a/src/VBox/Runtime/r0drv/os2/RTR0Os2DHQueryDOSVar.asm
+++ b/src/VBox/Runtime/r0drv/os2/RTR0Os2DHQueryDOSVar.asm
@@ -1,4 +1,4 @@
-; $Id: RTR0Os2DHQueryDOSVar.asm $
+; $Id: RTR0Os2DHQueryDOSVar.asm 8256 2008-04-21 20:53:28Z vboxsync $
;; @file
; IPRT - DevHelp_GetDOSVar, Ring-0 Driver, OS/2.
;
diff --git a/src/VBox/Runtime/r0drv/os2/RTR0Os2DHVMGlobalToProcess.asm b/src/VBox/Runtime/r0drv/os2/RTR0Os2DHVMGlobalToProcess.asm
index e1b44d42b..82e221123 100644
--- a/src/VBox/Runtime/r0drv/os2/RTR0Os2DHVMGlobalToProcess.asm
+++ b/src/VBox/Runtime/r0drv/os2/RTR0Os2DHVMGlobalToProcess.asm
@@ -1,4 +1,4 @@
-; $Id: RTR0Os2DHVMGlobalToProcess.asm $
+; $Id: RTR0Os2DHVMGlobalToProcess.asm 8256 2008-04-21 20:53:28Z vboxsync $
;; @file
; IPRT - DevHelp_VMGlobalToProcess, Ring-0 Driver, OS/2.
;
diff --git a/src/VBox/Runtime/r0drv/os2/alloc-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/alloc-r0drv-os2.cpp
index 53da24771..c29724032 100644
--- a/src/VBox/Runtime/r0drv/os2/alloc-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/alloc-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: alloc-r0drv-os2.cpp $ */
+/* $Id: alloc-r0drv-os2.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, Ring-0 Driver, OS/2.
*/
@@ -42,7 +42,7 @@
#include "r0drv/alloc-r0drv.h" /** @todo drop the r0drv/alloc-r0drv.cpp stuff on OS/2? */
-int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
+DECLHIDDEN(int) rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
{
if (fFlags & RTMEMHDR_FLAG_ANY_CTX)
return VERR_NOT_SUPPORTED;
@@ -62,7 +62,7 @@ int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
}
-void rtR0MemFree(PRTMEMHDR pHdr)
+DECLHIDDEN(void) rtR0MemFree(PRTMEMHDR pHdr)
{
pHdr->u32Magic += 1;
APIRET rc = KernVMFree(pHdr);
diff --git a/src/VBox/Runtime/r0drv/os2/assert-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/assert-r0drv-os2.cpp
index c3b1a5e00..6eacf9d9a 100644
--- a/src/VBox/Runtime/r0drv/os2/assert-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/assert-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: assert-r0drv-os2.cpp $ */
+/* $Id: assert-r0drv-os2.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Assertion Workers, Ring-0 Drivers, OS/2.
*/
@@ -57,7 +57,7 @@ extern size_t g_cchRTAssertMsg;
static DECLCALLBACK(size_t) rtR0Os2AssertOutputCB(void *pvArg, const char *pachChars, size_t cbChars);
-void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
+DECLHIDDEN(void) rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
{
#if defined(DEBUG_bird)
RTLogComPrintf("\n!!Assertion Failed!!\n"
@@ -74,7 +74,7 @@ void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFi
}
-void rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
+DECLHIDDEN(void) rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
{
#if defined(DEBUG_bird)
va_list vaCopy;
diff --git a/src/VBox/Runtime/r0drv/os2/assertA-r0drv-os2.asm b/src/VBox/Runtime/r0drv/os2/assertA-r0drv-os2.asm
index 0e0808aab..4da5eea74 100644
--- a/src/VBox/Runtime/r0drv/os2/assertA-r0drv-os2.asm
+++ b/src/VBox/Runtime/r0drv/os2/assertA-r0drv-os2.asm
@@ -1,4 +1,4 @@
-; $Id: assertA-r0drv-os2.asm $
+; $Id: assertA-r0drv-os2.asm 8256 2008-04-21 20:53:28Z vboxsync $
;; @file
; IPRT - DevHelp_GetDOSVar, Ring-0 Driver, OS/2.
;
diff --git a/src/VBox/Runtime/r0drv/os2/initterm-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/initterm-r0drv-os2.cpp
index 9a1872a81..6cd80245e 100644
--- a/src/VBox/Runtime/r0drv/os2/initterm-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/initterm-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: initterm-r0drv-os2.cpp $ */
+/* $Id: initterm-r0drv-os2.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Initialization & Termination, Ring-0 Driver, OS/2.
*/
@@ -54,7 +54,7 @@ PGINFOSEG g_pGIS = NULL;
RTFAR16 g_fpLIS = {0, 0};
-int rtR0InitNative(void)
+DECLHIDDEN(int) rtR0InitNative(void)
{
/*
* Get the DOS Tables.
@@ -80,7 +80,7 @@ int rtR0InitNative(void)
}
-void rtR0TermNative(void)
+DECLHIDDEN(void) rtR0TermNative(void)
{
/* nothing to do here yet. */
}
diff --git a/src/VBox/Runtime/r0drv/os2/memobj-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/memobj-r0drv-os2.cpp
index 9dfdae72c..21dd2fe19 100644
--- a/src/VBox/Runtime/r0drv/os2/memobj-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/memobj-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: memobj-r0drv-os2.cpp $ */
+/* $Id: memobj-r0drv-os2.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Ring-0 Memory Objects, OS/2.
*/
@@ -69,7 +69,7 @@ typedef struct RTR0MEMOBJDARWIN
static void rtR0MemObjFixPageList(KernPageList_t *paPages, ULONG cPages, ULONG cPagesRet);
-int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
+DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
{
PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)pMem;
int rc;
@@ -112,7 +112,7 @@ int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
}
-int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
NOREF(fExecutable);
@@ -141,7 +141,7 @@ int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecu
}
-int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
NOREF(fExecutable);
@@ -170,7 +170,7 @@ int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecut
}
-int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
NOREF(fExecutable);
@@ -194,7 +194,7 @@ int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecu
}
-int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
{
AssertMsgReturn(PhysHighest >= 16 *_1M, ("PhysHigest=%RHp\n", PhysHighest), VERR_NOT_SUPPORTED);
@@ -223,14 +223,14 @@ int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS Ph
}
-int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
{
/** @todo rtR0MemObjNativeAllocPhys / darwin. */
return rtR0MemObjNativeAllocPhys(ppMem, cb, PhysHighest, PAGE_SIZE);
}
-int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
+DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
{
AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
@@ -248,7 +248,8 @@ int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t
}
-int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess,
+ RTR0PROCESS R0Process)
{
AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
@@ -276,7 +277,7 @@ int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t c
}
-int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
+DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
{
/* create the object. */
const ULONG cPages = cb >> PAGE_SHIFT;
@@ -300,20 +301,21 @@ int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb,
}
-int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
+DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
{
return VERR_NOT_SUPPORTED;
}
-int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment,
+ RTR0PROCESS R0Process)
{
return VERR_NOT_SUPPORTED;
}
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
- unsigned fProt, size_t offSub, size_t cbSub)
+DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+ unsigned fProt, size_t offSub, size_t cbSub)
{
AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
@@ -393,7 +395,7 @@ int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap,
}
-int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
{
AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
AssertMsgReturn(R3PtrFixed == (RTR3PTR)-1, ("%p\n", R3PtrFixed), VERR_NOT_SUPPORTED);
@@ -483,7 +485,7 @@ int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RT
}
-int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
+DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
{
NOREF(pMem);
NOREF(offSub);
@@ -493,7 +495,7 @@ int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSu
}
-RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
+DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
{
PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)pMem;
diff --git a/src/VBox/Runtime/r0drv/os2/memuserkernel-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/memuserkernel-r0drv-os2.cpp
index 888b5409a..fd742f134 100644
--- a/src/VBox/Runtime/r0drv/os2/memuserkernel-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/memuserkernel-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: memuserkernel-r0drv-os2.cpp $ */
+/* $Id: memuserkernel-r0drv-os2.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - User & Kernel Memory, Ring-0 Driver, OS/2.
*/
diff --git a/src/VBox/Runtime/r0drv/os2/process-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/process-r0drv-os2.cpp
index a05d0617e..eac1e4624 100644
--- a/src/VBox/Runtime/r0drv/os2/process-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/process-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: process-r0drv-os2.cpp $ */
+/* $Id: process-r0drv-os2.cpp 8245 2008-04-21 17:24:28Z vboxsync $ */
/** @file
* IPRT - Process Management, Ring-0 Driver, OS/2.
*/
diff --git a/src/VBox/Runtime/r0drv/os2/semevent-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/semevent-r0drv-os2.cpp
index 74aaa2d26..5da10059b 100644
--- a/src/VBox/Runtime/r0drv/os2/semevent-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/semevent-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: semevent-r0drv-os2.cpp $ */
+/* $Id: semevent-r0drv-os2.cpp 33269 2010-10-20 15:42:28Z vboxsync $ */
/** @file
* IPRT - Single Release Event Semaphores, Ring-0 Driver, OS/2.
*/
diff --git a/src/VBox/Runtime/r0drv/os2/semeventmulti-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/semeventmulti-r0drv-os2.cpp
index fb05a5007..0ef07282e 100644
--- a/src/VBox/Runtime/r0drv/os2/semeventmulti-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/semeventmulti-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: semeventmulti-r0drv-os2.cpp $ */
+/* $Id: semeventmulti-r0drv-os2.cpp 33155 2010-10-15 12:07:44Z vboxsync $ */
/** @file
* IPRT - Multiple Release Event Semaphores, Ring-0 Driver, OS/2.
*/
diff --git a/src/VBox/Runtime/r0drv/os2/semfastmutex-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/semfastmutex-r0drv-os2.cpp
index d2edff5e8..caf6ddc7a 100644
--- a/src/VBox/Runtime/r0drv/os2/semfastmutex-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/semfastmutex-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: semfastmutex-r0drv-os2.cpp $ */
+/* $Id: semfastmutex-r0drv-os2.cpp 25722 2010-01-11 14:22:03Z vboxsync $ */
/** @file
* IPRT - Fast Mutex Semaphores, Ring-0 Driver, OS/2.
*/
diff --git a/src/VBox/Runtime/r0drv/os2/spinlock-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/spinlock-r0drv-os2.cpp
index e239f766a..d2b7b5fc2 100644
--- a/src/VBox/Runtime/r0drv/os2/spinlock-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/spinlock-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: spinlock-r0drv-os2.cpp $ */
+/* $Id: spinlock-r0drv-os2.cpp 8245 2008-04-21 17:24:28Z vboxsync $ */
/** @file
* IPRT - Spinlocks, Ring-0 Driver, OS/2.
*/
diff --git a/src/VBox/Runtime/r0drv/os2/the-os2-kernel.h b/src/VBox/Runtime/r0drv/os2/the-os2-kernel.h
index 2057b50bb..f08bd11bf 100644
--- a/src/VBox/Runtime/r0drv/os2/the-os2-kernel.h
+++ b/src/VBox/Runtime/r0drv/os2/the-os2-kernel.h
@@ -1,4 +1,4 @@
-/* $Id: the-os2-kernel.h $ */
+/* $Id: the-os2-kernel.h 20374 2009-06-08 00:43:21Z vboxsync $ */
/** @file
* IPRT - Ring-0 Driver, The OS/2 Kernel Headers.
*/
diff --git a/src/VBox/Runtime/r0drv/os2/thread-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/thread-r0drv-os2.cpp
index 64c5308a2..bc68b7af0 100644
--- a/src/VBox/Runtime/r0drv/os2/thread-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/thread-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: thread-r0drv-os2.cpp $ */
+/* $Id: thread-r0drv-os2.cpp 33393 2010-10-24 16:17:00Z vboxsync $ */
/** @file
* IPRT - Threads (Part 1), Ring-0 Driver, OS/2.
*/
diff --git a/src/VBox/Runtime/r0drv/os2/thread2-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/thread2-r0drv-os2.cpp
index 29a7c94be..2e209860c 100644
--- a/src/VBox/Runtime/r0drv/os2/thread2-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/thread2-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: thread2-r0drv-os2.cpp $ */
+/* $Id: thread2-r0drv-os2.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Threads (Part 2), Ring-0 Driver, Generic Stubs.
*/
@@ -38,7 +38,7 @@
#include "internal/thread.h"
-int rtThreadNativeInit(void)
+DECLHIDDEN(int) rtThreadNativeInit(void)
{
return VINF_SUCCESS;
}
@@ -50,7 +50,7 @@ RTDECL(RTTHREAD) RTThreadSelf(void)
}
-int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
{
NOREF(pThread);
NOREF(enmType);
@@ -58,20 +58,20 @@ int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
}
-int rtThreadNativeAdopt(PRTTHREADINT pThread)
+DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread)
{
NOREF(pThread);
return VERR_NOT_IMPLEMENTED;
}
-void rtThreadNativeDestroy(PRTTHREADINT pThread)
+DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread)
{
NOREF(pThread);
}
-int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
{
NOREF(pNativeThread);
NOREF(pThreadInt);
diff --git a/src/VBox/Runtime/r0drv/os2/time-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/time-r0drv-os2.cpp
index 778ee2b0a..ab4bf1b9a 100644
--- a/src/VBox/Runtime/r0drv/os2/time-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/time-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: time-r0drv-os2.cpp $ */
+/* $Id: time-r0drv-os2.cpp 8245 2008-04-21 17:24:28Z vboxsync $ */
/** @file
* IPRT - Time, Ring-0 Driver, OS/2.
*/
diff --git a/src/VBox/Runtime/r0drv/os2/timer-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/timer-r0drv-os2.cpp
index ba68fd127..e2d023352 100644
--- a/src/VBox/Runtime/r0drv/os2/timer-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/timer-r0drv-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: timer-r0drv-os2.cpp $ */
+/* $Id: timer-r0drv-os2.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, Ring-0 Driver, OS/2.
*/
diff --git a/src/VBox/Runtime/r0drv/os2/timerA-r0drv-os2.asm b/src/VBox/Runtime/r0drv/os2/timerA-r0drv-os2.asm
index 474f85767..788bcc907 100644
--- a/src/VBox/Runtime/r0drv/os2/timerA-r0drv-os2.asm
+++ b/src/VBox/Runtime/r0drv/os2/timerA-r0drv-os2.asm
@@ -1,4 +1,4 @@
-; $Id: timerA-r0drv-os2.asm $
+; $Id: timerA-r0drv-os2.asm 8256 2008-04-21 20:53:28Z vboxsync $
;; @file
; IPRT - DevHelp_VMGlobalToProcess, Ring-0 Driver, OS/2.
;
diff --git a/src/VBox/Runtime/r0drv/power-r0drv.h b/src/VBox/Runtime/r0drv/power-r0drv.h
index 11f5493be..7dacbc91e 100644
--- a/src/VBox/Runtime/r0drv/power-r0drv.h
+++ b/src/VBox/Runtime/r0drv/power-r0drv.h
@@ -1,4 +1,4 @@
-/* $Id: power-r0drv.h $ */
+/* $Id: power-r0drv.h 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Power Management, Ring-0 Driver, Internal Header.
*/
@@ -32,8 +32,8 @@
RT_C_DECLS_BEGIN
/* Called from initterm-r0drv.cpp: */
-int rtR0PowerNotificationInit(void);
-void rtR0PowerNotificationTerm(void);
+DECLHIDDEN(int) rtR0PowerNotificationInit(void);
+DECLHIDDEN(void) rtR0PowerNotificationTerm(void);
RT_C_DECLS_END
diff --git a/src/VBox/Runtime/r0drv/powernotification-r0drv.c b/src/VBox/Runtime/r0drv/powernotification-r0drv.c
index 9e03da213..4ef59ef46 100644
--- a/src/VBox/Runtime/r0drv/powernotification-r0drv.c
+++ b/src/VBox/Runtime/r0drv/powernotification-r0drv.c
@@ -1,4 +1,4 @@
-/* $Id: powernotification-r0drv.c $ */
+/* $Id: powernotification-r0drv.c 37211 2011-05-25 11:37:52Z vboxsync $ */
/** @file
* IPRT - Power Management, Ring-0 Driver, Event Notifications.
*/
@@ -273,7 +273,7 @@ RTDECL(int) RTPowerNotificationDeregister(PFNRTPOWERNOTIFICATION pfnCallback, vo
RT_EXPORT_SYMBOL(RTPowerNotificationDeregister);
-int rtR0PowerNotificationInit(void)
+DECLHIDDEN(int) rtR0PowerNotificationInit(void)
{
int rc = RTSpinlockCreate((PRTSPINLOCK)&g_hRTPowerNotifySpinLock);
if (RT_SUCCESS(rc))
@@ -289,7 +289,7 @@ int rtR0PowerNotificationInit(void)
}
-void rtR0PowerNotificationTerm(void)
+DECLHIDDEN(void) rtR0PowerNotificationTerm(void)
{
PRTPOWERNOTIFYREG pHead;
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
@@ -300,7 +300,7 @@ void rtR0PowerNotificationTerm(void)
/* pick up the list and the spinlock. */
RTSpinlockAcquire(hSpinlock, &Tmp);
- ASMAtomicWriteSize(&g_hRTPowerNotifySpinLock, NIL_RTSPINLOCK);
+ ASMAtomicWriteHandle(&g_hRTPowerNotifySpinLock, NIL_RTSPINLOCK);
pHead = g_pRTPowerCallbackHead;
g_pRTPowerCallbackHead = NULL;
ASMAtomicIncU32(&g_iRTPowerGeneration);
diff --git a/src/VBox/Runtime/r0drv/solaris/RTLogWriteDebugger-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/RTLogWriteDebugger-r0drv-solaris.c
index 5aa03da81..86b07c181 100644
--- a/src/VBox/Runtime/r0drv/solaris/RTLogWriteDebugger-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/RTLogWriteDebugger-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: RTLogWriteDebugger-r0drv-solaris.c $ */
+/* $Id: RTLogWriteDebugger-r0drv-solaris.c 29281 2010-05-09 23:40:43Z vboxsync $ */
/** @file
* IPRT - Log To Debugger, Ring-0 Driver, Solaris.
*/
diff --git a/src/VBox/Runtime/r0drv/solaris/assert-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/assert-r0drv-solaris.c
index 55befdcaf..7c1876f9e 100644
--- a/src/VBox/Runtime/r0drv/solaris/assert-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/assert-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: assert-r0drv-solaris.c $ */
+/* $Id: assert-r0drv-solaris.c 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Assertion Workers, Ring-0 Drivers, Solaris.
*/
@@ -40,7 +40,7 @@
#include "internal/assert.h"
-void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
+DECLHIDDEN(void) rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
{
uprintf("\r\n!!Assertion Failed!!\r\n"
"Expression: %s\r\n"
@@ -49,7 +49,7 @@ void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFi
}
-void rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
+DECLHIDDEN(void) rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
{
char szMsg[256];
diff --git a/src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c
index fce305c06..fec13e31b 100644
--- a/src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: initterm-r0drv-solaris.c $ */
+/* $Id: initterm-r0drv-solaris.c 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Initialization & Termination, R0 Driver, Solaris.
*/
@@ -53,7 +53,7 @@ PFNSOL_untimeout_generic g_pfnrtR0Sol_untimeout_generic = NULL;
PFNSOL_cyclic_reprogram g_pfnrtR0Sol_cyclic_reprogram = NULL;
-int rtR0InitNative(void)
+DECLHIDDEN(int) rtR0InitNative(void)
{
/*
* Initialize vbi (keeping it separate for now)
@@ -102,7 +102,7 @@ int rtR0InitNative(void)
}
-void rtR0TermNative(void)
+DECLHIDDEN(void) rtR0TermNative(void)
{
}
diff --git a/src/VBox/Runtime/r0drv/solaris/memuserkernel-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/memuserkernel-r0drv-solaris.c
index 11b24bd7a..88d50e4d1 100644
--- a/src/VBox/Runtime/r0drv/solaris/memuserkernel-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/memuserkernel-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: memuserkernel-r0drv-solaris.c $ */
+/* $Id: memuserkernel-r0drv-solaris.c 29284 2010-05-10 00:22:16Z vboxsync $ */
/** @file
* IPRT - User & Kernel Memory, Ring-0 Driver, Solaris.
*/
diff --git a/src/VBox/Runtime/r0drv/solaris/modulestub-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/modulestub-r0drv-solaris.c
new file mode 100644
index 000000000..b3a171a23
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/solaris/modulestub-r0drv-solaris.c
@@ -0,0 +1,55 @@
+
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include <sys/modctl.h>
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+static struct modlmisc g_rtModuleStubMisc =
+{
+ &mod_miscops, /* extern from kernel */
+ "platform agnostic module"
+};
+
+
+static struct modlinkage g_rtModuleStubModLinkage =
+{
+ MODREV_1, /* loadable module system revision */
+ {
+ &g_rtModuleStubMisc,
+ NULL /* terminate array of linkage structures */
+ }
+};
+
+
+
+int _init(void);
+int _init(void)
+{
+ /* Disable auto unloading. */
+ modctl_t *pModCtl = mod_getctl(&g_rtModuleStubModLinkage);
+ if (pModCtl)
+ pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
+
+ return mod_install(&g_rtModuleStubModLinkage);
+}
+
+
+int _fini(void);
+int _fini(void)
+{
+ return mod_remove(&g_rtModuleStubModLinkage);
+}
+
+
+int _info(struct modinfo *pModInfo);
+int _info(struct modinfo *pModInfo)
+{
+ return mod_info(&g_rtModuleStubModLinkage, pModInfo);
+}
+
diff --git a/src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c
index b8921218f..9431c915a 100644
--- a/src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: semevent-r0drv-solaris.c $ */
+/* $Id: semevent-r0drv-solaris.c 36392 2011-03-24 11:20:37Z vboxsync $ */
/** @file
* IPRT - Single Release Event Semaphores, Ring-0 Driver, Solaris.
*/
@@ -131,6 +131,7 @@ DECLINLINE(void) rtR0SemEventSolRetain(PRTSEMEVENTINTERNAL pThis)
{
uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
Assert(cRefs && cRefs < 100000);
+ NOREF(cRefs);
}
diff --git a/src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c
index 6f7fc5ca7..011369fae 100644
--- a/src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: semeventmulti-r0drv-solaris.c $ */
+/* $Id: semeventmulti-r0drv-solaris.c 36392 2011-03-24 11:20:37Z vboxsync $ */
/** @file
* IPRT - Multiple Release Event Semaphores, Ring-0 Driver, Solaris.
*/
@@ -129,6 +129,7 @@ DECLINLINE(void) rtR0SemEventMultiSolRetain(PRTSEMEVENTMULTIINTERNAL pThis)
{
uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
Assert(cRefs && cRefs < 100000);
+ NOREF(cRefs);
}
diff --git a/src/VBox/Runtime/r0drv/solaris/semeventwait-r0drv-solaris.h b/src/VBox/Runtime/r0drv/solaris/semeventwait-r0drv-solaris.h
index 45fd29aac..d06b26bf0 100644
--- a/src/VBox/Runtime/r0drv/solaris/semeventwait-r0drv-solaris.h
+++ b/src/VBox/Runtime/r0drv/solaris/semeventwait-r0drv-solaris.h
@@ -1,4 +1,4 @@
-/* $Id: semeventwait-r0drv-solaris.h $ */
+/* $Id: semeventwait-r0drv-solaris.h 36392 2011-03-24 11:20:37Z vboxsync $ */
/** @file
* IPRT - Solaris Ring-0 Driver Helpers for Event Semaphore Waits.
*/
diff --git a/src/VBox/Runtime/r0drv/solaris/semfastmutex-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/semfastmutex-r0drv-solaris.c
index baeaec2f5..ef0f5b602 100644
--- a/src/VBox/Runtime/r0drv/solaris/semfastmutex-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/semfastmutex-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: semfastmutex-r0drv-solaris.c $ */
+/* $Id: semfastmutex-r0drv-solaris.c 29284 2010-05-10 00:22:16Z vboxsync $ */
/** @file
* IPRT - Fast Mutex Semaphores, Ring-0 Driver, Solaris.
*/
diff --git a/src/VBox/Runtime/r0drv/solaris/semmutex-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/semmutex-r0drv-solaris.c
index 8394c4d3c..65802fe1a 100644
--- a/src/VBox/Runtime/r0drv/solaris/semmutex-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/semmutex-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: semmutex-r0drv-solaris.c $ */
+/* $Id: semmutex-r0drv-solaris.c 36190 2011-03-07 16:28:50Z vboxsync $ */
/** @file
* IPRT - Mutex Semaphores, Ring-0 Driver, Solaris.
*/
diff --git a/src/VBox/Runtime/r0drv/solaris/spinlock-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/spinlock-r0drv-solaris.c
index a66e63b3c..1b37be6b3 100644
--- a/src/VBox/Runtime/r0drv/solaris/spinlock-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/spinlock-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: spinlock-r0drv-solaris.c $ */
+/* $Id: spinlock-r0drv-solaris.c 29281 2010-05-09 23:40:43Z vboxsync $ */
/** @file
* IPRT - Spinlocks, Ring-0 Driver, Solaris.
*/
diff --git a/src/VBox/Runtime/r0drv/solaris/the-solaris-kernel.h b/src/VBox/Runtime/r0drv/solaris/the-solaris-kernel.h
index 7dd607f03..aab14e8fe 100644
--- a/src/VBox/Runtime/r0drv/solaris/the-solaris-kernel.h
+++ b/src/VBox/Runtime/r0drv/solaris/the-solaris-kernel.h
@@ -1,4 +1,4 @@
-/* $Id: the-solaris-kernel.h $ */
+/* $Id: the-solaris-kernel.h 33149 2010-10-15 11:26:24Z vboxsync $ */
/** @file
* IPRT - Include all necessary headers for the Solaris kernel.
*/
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/RTMpPokeCpu-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/vbi/RTMpPokeCpu-r0drv-solaris.c
index 524236571..2dad122b2 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/RTMpPokeCpu-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/RTMpPokeCpu-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: RTMpPokeCpu-r0drv-solaris.c $ */
+/* $Id: RTMpPokeCpu-r0drv-solaris.c 29300 2010-05-10 12:30:43Z vboxsync $ */
/** @file
* IPRT - RTMpPokeCpu, Solaris Implementation.
*/
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/alloc-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/vbi/alloc-r0drv-solaris.c
index e6ee0f1a6..2ab6aba0b 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/alloc-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/alloc-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: alloc-r0drv-solaris.c $ */
+/* $Id: alloc-r0drv-solaris.c 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, Ring-0 Driver, Solaris.
*/
@@ -44,7 +44,7 @@
/**
* OS specific allocation function.
*/
-int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
+DECLHIDDEN(int) rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
{
size_t cbAllocated = cb;
PRTMEMHDR pHdr;
@@ -84,7 +84,7 @@ int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
/**
* OS specific free function.
*/
-void rtR0MemFree(PRTMEMHDR pHdr)
+DECLHIDDEN(void) rtR0MemFree(PRTMEMHDR pHdr)
{
pHdr->u32Magic += 1;
#ifdef RT_ARCH_AMD64
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 4f0304222..69278261d 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010-2011 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -56,6 +56,9 @@
#include <sys/modctl.h>
#include <sys/machparam.h>
#include <sys/utsname.h>
+#include <sys/ctf_api.h>
+
+#include <iprt/assert.h>
#include "vbi.h"
@@ -75,7 +78,7 @@ static void (*p_contig_free)(void *, size_t) = contig_free;
*/
/* Introduced in v9 */
static int use_kflt = 0;
-page_t *vbi_page_get_fromlist(uint_t freelist, caddr_t virtAddr);
+static page_t *vbi_page_get_fromlist(uint_t freelist, caddr_t virtAddr, size_t pgsize);
/*
@@ -141,40 +144,6 @@ static int vbi_verbose = 0;
/* Introduced in v8 */
static int vbi_is_initialized = 0;
-/* Introduced in v6 */
-static int vbi_is_nevada = 0;
-
-#ifdef _LP64
-/* 64-bit Solaris 10 offsets */
-/* CPU */
-static int off_s10_cpu_runrun = 232;
-static int off_s10_cpu_kprunrun = 233;
-/* kthread_t */
-static int off_s10_t_preempt = 42;
-
-/* 64-bit Solaris 11 (Nevada/OpenSolaris) offsets */
-/* CPU */
-static int off_s11_cpu_runrun = 216;
-static int off_s11_cpu_kprunrun = 217;
-/* kthread_t */
-static int off_s11_t_preempt = 42;
-#else
-/* 32-bit Solaris 10 offsets */
-/* CPU */
-static int off_s10_cpu_runrun = 124;
-static int off_s10_cpu_kprunrun = 125;
-/* kthread_t */
-static int off_s10_t_preempt = 26;
-
-/* 32-bit Solaris 11 (Nevada/OpenSolaris) offsets */
-/* CPU */
-static int off_s11_cpu_runrun = 112;
-static int off_s11_cpu_kprunrun = 113;
-/* kthread_t */
-static int off_s11_t_preempt = 26;
-#endif
-
-
/* Which offsets will be used */
static int off_cpu_runrun = -1;
static int off_cpu_kprunrun = -1;
@@ -213,6 +182,35 @@ _init(void)
}
#endif
+static int
+vbi_get_ctf_member_offset(ctf_file_t *ctfp, const char *structname, const char *membername, int *offset)
+{
+ AssertReturn(ctfp, CTF_ERR);
+ AssertReturn(structname, CTF_ERR);
+ AssertReturn(membername, CTF_ERR);
+ AssertReturn(offset, CTF_ERR);
+
+ ctf_id_t typeident = ctf_lookup_by_name(ctfp, structname);
+ if (typeident != CTF_ERR)
+ {
+ ctf_membinfo_t memberinfo;
+ bzero(&memberinfo, sizeof(memberinfo));
+ if (ctf_member_info(ctfp, typeident, membername, &memberinfo) != CTF_ERR)
+ {
+ *offset = (memberinfo.ctm_offset >> 3);
+ cmn_err(CE_NOTE, "%s::%s at %d\n", structname, membername, *offset);
+ return (0);
+ }
+ else
+ cmn_err(CE_NOTE, "ctf_member_info failed for struct %s member %s\n", structname, membername);
+ }
+ else
+ cmn_err(CE_NOTE, "ctf_lookup_by_name failed for struct %s\n", structname);
+
+ return (CTF_ERR);
+}
+
+
int
vbi_init(void)
{
@@ -247,7 +245,7 @@ vbi_init(void)
p_contig_free = (void (*)(void *, size_t))
kobj_getsymvalue("contig_free", 1);
if (p_contig_free == NULL) {
- cmn_err(CE_NOTE, " contig_free() not found in kernel\n");
+ cmn_err(CE_NOTE, "contig_free() not found in kernel\n");
return (EINVAL);
}
}
@@ -266,44 +264,33 @@ vbi_init(void)
}
}
-
/*
- * Check if this is S10 or Nevada
+ * CTF probing for fluid, private members.
*/
- if (!strncmp(utsname.release, "5.11", sizeof("5.11") - 1)) {
- /* Nevada detected... */
- vbi_is_nevada = 1;
-
- off_cpu_runrun = off_s11_cpu_runrun;
- off_cpu_kprunrun = off_s11_cpu_kprunrun;
- off_t_preempt = off_s11_t_preempt;
- } else {
- /* Solaris 10 detected... */
- vbi_is_nevada = 0;
+ int err = 0;
+ modctl_t *genunix_modctl = mod_hold_by_name("genunix");
+ if (genunix_modctl)
+ {
+ ctf_file_t *ctfp = ctf_modopen(genunix_modctl->mod_mp, &err);
+ if (ctfp)
+ {
+ do {
+ err = vbi_get_ctf_member_offset(ctfp, "kthread_t", "t_preempt", &off_t_preempt); AssertBreak(!err);
+ err = vbi_get_ctf_member_offset(ctfp, "cpu_t", "cpu_runrun", &off_cpu_runrun); AssertBreak(!err);
+ err = vbi_get_ctf_member_offset(ctfp, "cpu_t", "cpu_kprunrun", &off_cpu_kprunrun); AssertBreak(!err);
+ } while (0);
+ }
- off_cpu_runrun = off_s10_cpu_runrun;
- off_cpu_kprunrun = off_s10_cpu_kprunrun;
- off_t_preempt = off_s10_t_preempt;
+ mod_release_mod(genunix_modctl);
}
-
- /*
- * Sanity checking...
- */
- /* CPU */
- char crr = VBI_CPU_RUNRUN;
- char krr = VBI_CPU_KPRUNRUN;
- if ( (crr < 0 || crr > 1)
- || (krr < 0 || krr > 1)) {
- cmn_err(CE_NOTE, ":CPU structure sanity check failed! OS version mismatch.\n");
- return EINVAL;
+ else
+ {
+ cmn_err(CE_NOTE, "failed to open module genunix.\n");
+ err = EINVAL;
}
- /* Thread */
- char t_preempt = VBI_T_PREEMPT;
- if (t_preempt < 0 || t_preempt > 32) {
- cmn_err(CE_NOTE, ":Thread structure sanity check failed! OS version mismatch.\n");
- return EINVAL;
- }
+ if (err)
+ return (EINVAL);
vbi_is_initialized = 1;
@@ -366,7 +353,7 @@ vbi_internal_alloc(uint64_t *phys, size_t size, uint64_t alignment, int contig)
ptr = contig_alloc(size, &attr, PAGESIZE, 1);
if (ptr == NULL) {
- cmn_err(CE_NOTE, "vbi_internal_alloc() failure for %lu bytes", size);
+ cmn_err(CE_NOTE, "vbi_internal_alloc() failure for %lu bytes contig=%d", size, contig);
return (NULL);
}
@@ -561,7 +548,7 @@ vbi_set_priority(void *thread, int priority)
}
void *
-vbi_thread_create(void *func, void *arg, size_t len, int priority)
+vbi_thread_create(void (*func)(void *), void *arg, size_t len, int priority)
{
kthread_t *t;
@@ -1012,9 +999,7 @@ vbi_user_map(caddr_t *va, uint_t prot, uint64_t *palist, size_t len)
as_rangelock(as);
map_addr(va, len, 0, 0, MAP_SHARED);
if (*va != NULL)
- {
error = as_map(as, *va, len, segvbi_create, &args);
- }
else
error = ENOMEM;
if (error)
@@ -1029,7 +1014,7 @@ vbi_user_map(caddr_t *va, uint_t prot, uint64_t *palist, size_t len)
*/
struct vbi_cpu_watch {
- void (*vbi_cpu_func)();
+ void (*vbi_cpu_func)(void *, int, int);
void *vbi_cpu_arg;
};
@@ -1050,7 +1035,7 @@ vbi_watcher(cpu_setup_t state, int icpu, void *arg)
}
vbi_cpu_watch_t *
-vbi_watch_cpus(void (*func)(), void *arg, int current_too)
+vbi_watch_cpus(void (*func)(void *, int, int), void *arg, int current_too)
{
int c;
vbi_cpu_watch_t *w;
@@ -1210,7 +1195,7 @@ vbi_gtimer_begin(
t->g_func = func;
t->g_cyclic = CYCLIC_NONE;
- omni.cyo_online = (void (*)())vbi_gtimer_online;
+ omni.cyo_online = (void (*)(void *, cpu_t *, cyc_handler_t *, cyc_time_t *))vbi_gtimer_online;
omni.cyo_offline = NULL;
omni.cyo_arg = t;
@@ -1332,11 +1317,11 @@ vbi_pages_alloc(uint64_t *phys, size_t size)
for (int64_t i = 0; i < npages; i++, virtAddr += PAGESIZE)
{
/* get a page from the freelists */
- page_t *ppage = vbi_page_get_fromlist(1 /* freelist */, virtAddr);
+ page_t *ppage = vbi_page_get_fromlist(1 /* freelist */, virtAddr, PAGESIZE);
if (!ppage)
{
/* try from the cachelists */
- ppage = vbi_page_get_fromlist(2 /* cachelist */, virtAddr);
+ ppage = vbi_page_get_fromlist(2 /* cachelist */, virtAddr, PAGESIZE);
if (!ppage)
{
/* damn */
@@ -1433,25 +1418,21 @@ vbi_page_to_pa(page_t **pp_pages, pgcnt_t i)
}
-/*
- * This is revision 9 of the interface.
- */
-page_t *vbi_page_get_fromlist(uint_t freelist, caddr_t virtAddr)
+static page_t *
+vbi_page_get_fromlist(uint_t freelist, caddr_t virtAddr, size_t pgsize)
{
+ /* pgsize only applies when using the freelist */
seg_t kernseg;
kernseg.s_as = &kas;
page_t *ppage = NULL;
if (freelist == 1)
{
ppage = page_get_freelist(&vbipagevp, 0 /* offset */, &kernseg, virtAddr,
- PAGESIZE, 0 /* flags */, NULL /* local group */);
- if (!ppage)
+ pgsize, 0 /* flags */, NULL /* local group */);
+ if (!ppage && use_kflt)
{
- if (use_kflt)
- {
- ppage = page_get_freelist(&vbipagevp, 0 /* offset */, &kernseg, virtAddr,
- PAGESIZE, 0x0200 /* PG_KFLT */, NULL /* local group */);
- }
+ ppage = page_get_freelist(&vbipagevp, 0 /* offset */, &kernseg, virtAddr,
+ pgsize, 0x0200 /* PG_KFLT */, NULL /* local group */);
}
}
else
@@ -1459,13 +1440,10 @@ page_t *vbi_page_get_fromlist(uint_t freelist, caddr_t virtAddr)
/* cachelist */
ppage = page_get_cachelist(&vbipagevp, 0 /* offset */, &kernseg, virtAddr,
0 /* flags */, NULL /* local group */);
- if (!ppage)
+ if (!ppage && use_kflt)
{
- if (use_kflt)
- {
- ppage = page_get_cachelist(&vbipagevp, 0 /* offset */, &kernseg, virtAddr,
- 0x0200 /* PG_KFLT */, NULL /* local group */);
- }
+ ppage = page_get_cachelist(&vbipagevp, 0 /* offset */, &kernseg, virtAddr,
+ 0x0200 /* PG_KFLT */, NULL /* local group */);
}
}
return ppage;
@@ -1473,9 +1451,140 @@ page_t *vbi_page_get_fromlist(uint_t freelist, caddr_t virtAddr)
/*
+ * Large page code.
+ */
+
+page_t *
+vbi_large_page_alloc(uint64_t *pphys, size_t pgsize)
+{
+ pgcnt_t const npages = pgsize >> PAGESHIFT;
+ page_t *pproot, *pp, *pplist;
+ pgcnt_t ipage;
+ caddr_t vaddr;
+ seg_t kernseg;
+ int rc;
+
+ /*
+ * Reserve available memory for a large page and create it.
+ */
+ rc = page_resv(npages, KM_NOSLEEP);
+ if (!rc)
+ return NULL;
+
+ rc = page_create_wait(npages, 0 /* flags */);
+ if (!rc) {
+ page_unresv(npages);
+ return NULL;
+ }
+
+ /*
+ * Get a page off the free list. We set vaddr to 0 since we don't know
+ * where the memory is going to be mapped.
+ */
+ vaddr = NULL;
+ kernseg.s_as = &kas;
+ pproot = vbi_page_get_fromlist(1 /* freelist */, vaddr, pgsize);
+ if (!pproot)
+ {
+ page_create_putback(npages);
+ page_unresv(npages);
+ return NULL;
+ }
+ AssertMsg(!(page_pptonum(pproot) & (npages - 1)), ("%p:%lx npages=%lx\n", pproot, page_pptonum(pproot), npages));
+
+ /*
+ * Mark all the sub-pages as non-free and not-hashed-in.
+ * It is paramount that we destroy the list (before freeing it).
+ */
+ pplist = pproot;
+ for (ipage = 0; ipage < npages; ipage++) {
+ pp = pplist;
+ AssertPtr(pp);
+ AssertMsg(page_pptonum(pp) == ipage + page_pptonum(pproot),
+ ("%p:%lx %lx+%lx\n", pp, page_pptonum(pp), ipage, page_pptonum(pproot)));
+ page_sub(&pplist, pp);
+ AssertMsg(PP_ISFREE(pp), ("%p\n", pp));
+ AssertMsg(pp->p_szc == pproot->p_szc, ("%p - %d expected %d \n", pp, pp->p_szc, pproot->p_szc));
+
+ PP_CLRFREE(pp);
+ PP_CLRAGED(pp);
+ }
+
+ *pphys = (uint64_t)page_pptonum(pproot) << PAGESHIFT;
+ AssertMsg(!(*pphys & (pgsize - 1)), ("%llx %zx\n", *pphys, pgsize));
+ return pproot;
+}
+
+void
+vbi_large_page_free(page_t *pproot, size_t pgsize)
+{
+ pgcnt_t const npages = pgsize >> PAGESHIFT;
+ pgcnt_t ipage;
+
+ Assert(page_get_pagecnt(pproot->p_szc) == npages);
+ AssertMsg(!(page_pptonum(pproot) & (npages - 1)), ("%p:%lx npages=%lx\n", pproot, page_pptonum(pproot), npages));
+
+ /*
+ * We need to exclusively lock the sub-pages before freeing
+ * the large one.
+ */
+ for (ipage = 0; ipage < npages; ipage++) {
+ page_t *pp = page_nextn(pproot, ipage);
+ AssertMsg(page_pptonum(pp) == ipage + page_pptonum(pproot),
+ ("%p:%lx %lx+%lx\n", pp, page_pptonum(pp), ipage, page_pptonum(pproot)));
+ AssertMsg(!PP_ISFREE(pp), ("%p\n", pp));
+
+ int rc = page_tryupgrade(pp);
+ if (!rc) {
+ page_unlock(pp);
+ while (!page_lock(pp, SE_EXCL, NULL /* mutex */, P_RECLAIM)) {
+ /*nothing*/;
+ }
+ }
+ }
+
+ /*
+ * Free the large page and unreserve the memory.
+ */
+ page_free_pages(pproot);
+ page_unresv(npages);
+}
+
+int
+vbi_large_page_premap(page_t *pproot, size_t pgsize)
+{
+ pgcnt_t const npages = pgsize >> PAGESHIFT;
+ pgcnt_t ipage;
+
+ Assert(page_get_pagecnt(pproot->p_szc) == npages);
+ AssertMsg(!(page_pptonum(pproot) & (npages - 1)), ("%p:%lx npages=%lx\n", pproot, page_pptonum(pproot), npages));
+
+ /*
+ * We need to downgrade the sub-pages from exclusive to shared locking
+ * because otherwise we cannot <you go figure>.
+ */
+ for (ipage = 0; ipage < npages; ipage++) {
+ page_t *pp = page_nextn(pproot, ipage);
+ AssertMsg(page_pptonum(pp) == ipage + page_pptonum(pproot),
+ ("%p:%lx %lx+%lx\n", pp, page_pptonum(pp), ipage, page_pptonum(pproot)));
+ AssertMsg(!PP_ISFREE(pp), ("%p\n", pp));
+
+ if (page_tryupgrade(pp) == 1)
+ page_downgrade(pp);
+ AssertMsg(!PP_ISFREE(pp), ("%p\n", pp));
+ }
+
+ return 0;
+}
+
+
+/*
* As more functions are added, they should start with a comment indicating
* the revision and above this point in the file and the revision level should
* be increased. Also change vbi_modlmisc at the top of the file.
+ *
+ * NOTE! We'll start care about this if anything in here ever makes it into
+ * the solaris kernel proper.
*/
uint_t vbi_revision_level = 9;
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/sys/vbi.h b/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/sys/vbi.h
index f2c412a75..5e4b51ce3 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/sys/vbi.h
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/sys/vbi.h
@@ -137,7 +137,7 @@ extern void *vbi_proc(void);
* thread functions
*/
extern void vbi_set_priority(void *thread, int priority);
-extern void *vbi_thread_create(void *func, void *arg, size_t len, int priority);
+extern void *vbi_thread_create(void (*func)(void *), void *arg, size_t len, int priority);
extern void vbi_thread_exit(void);
/*
@@ -248,7 +248,7 @@ extern uint_t vbi_revision_level;
* Note there is no guarantee about which CPU the function is invoked on.
*/
typedef struct vbi_cpu_watch vbi_cpu_watch_t;
-extern vbi_cpu_watch_t *vbi_watch_cpus(void (*func)(void), void *arg,
+extern vbi_cpu_watch_t *vbi_watch_cpus(void (*func)(void *, int, int), void *arg,
int current_too);
extern void vbi_ignore_cpus(vbi_cpu_watch_t *);
#pragma weak vbi_watch_cpus
@@ -344,7 +344,7 @@ extern int vbi_is_preempt_pending(void);
/* begin interfaces defined for version 7 */
/*
- * Allocate and free physically limited, aligned as specified continuous or non-continuous memory.
+ * Allocate and free physically limited, aligned as specified continuous or non-continuous memory.
*
* return value is a) NULL if memory below "phys" not available or
* b) virtual address of memory in kernel heap
@@ -368,7 +368,7 @@ extern void vbi_phys_free(void *va, size_t size);
*
* phys on input is set to the physical address of the first page allocated.
*
- * size is the amount to allocate and must be a multiple of PAGESIZE
+ * size is the amount to allocate and must be a multiple of PAGESIZE.
*/
extern page_t **vbi_pages_alloc(uint64_t *phys, size_t size);
@@ -399,6 +399,17 @@ extern int vbi_pages_premap(page_t **pp_pages, size_t size, uint64_t *physaddrs)
extern uint64_t vbi_page_to_pa(page_t **pp_pages, pgcnt_t i);
/* end of interfaces defined for version 8 */
+/*
+ * Allocate, free and map one large page.
+ *
+ * The size of the large page is hardware specific and must be specified
+ * correctly or we'll panic. :-)
+ */
+extern page_t *vbi_large_page_alloc(uint64_t *pphys, size_t pgsize);
+extern void vbi_large_page_free(page_t *ppage, size_t pgsize);
+extern int vbi_large_page_premap(page_t *pproot, size_t pgsize);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/memobj-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/vbi/memobj-r0drv-solaris.c
index d16e9ad6c..4ea9e6796 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/memobj-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/memobj-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: memobj-r0drv-solaris.c $ */
+/* $Id: memobj-r0drv-solaris.c 37281 2011-05-31 21:32:44Z vboxsync $ */
/** @file
* IPRT - Ring-0 Memory Objects, Solaris.
*/
@@ -32,6 +32,7 @@
#include "internal/iprt.h"
#include <iprt/memobj.h>
+#include <iprt/asm.h>
#include <iprt/assert.h>
#include <iprt/err.h>
#include <iprt/log.h>
@@ -56,11 +57,14 @@ typedef struct RTR0MEMOBJSOLARIS
void *pvHandle;
/** Access during locking. */
int fAccess;
+ /** Set if large pages are involved in an RTR0MEMOBJTYPE_PHYS
+ * allocation. */
+ bool fLargePage;
} RTR0MEMOBJSOLARIS, *PRTR0MEMOBJSOLARIS;
-int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
+DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
{
PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)pMem;
@@ -70,20 +74,17 @@ int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
vbi_lowmem_free(pMemSolaris->Core.pv, pMemSolaris->Core.cb);
break;
- case RTR0MEMOBJTYPE_CONT:
case RTR0MEMOBJTYPE_PHYS:
- vbi_phys_free(pMemSolaris->Core.pv, pMemSolaris->Core.cb);
+ if (!pMemSolaris->Core.u.Phys.fAllocated)
+ { /* nothing to do here */; }
+ else if (pMemSolaris->fLargePage)
+ vbi_large_page_free(pMemSolaris->pvHandle, pMemSolaris->Core.cb);
+ else
+ vbi_phys_free(pMemSolaris->Core.pv, pMemSolaris->Core.cb);
break;
case RTR0MEMOBJTYPE_PHYS_NC:
-#if 0
- vbi_phys_free(pMemSolaris->Core.pv, pMemSolaris->Core.cb);
-#else
- if (pMemSolaris->Core.u.Phys.fAllocated == true)
- ddi_umem_free(pMemSolaris->Cookie);
- else
- vbi_pages_free(pMemSolaris->pvHandle, pMemSolaris->Core.cb);
-#endif
+ vbi_pages_free(pMemSolaris->pvHandle, pMemSolaris->Core.cb);
break;
case RTR0MEMOBJTYPE_PAGE:
@@ -107,6 +108,7 @@ int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
break;
}
+ case RTR0MEMOBJTYPE_CONT: /* we don't use this type here. */
default:
AssertMsgFailed(("enmType=%d\n", pMemSolaris->Core.enmType));
return VERR_INTERNAL_ERROR;
@@ -116,7 +118,7 @@ int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
}
-int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
/* Create the object. */
PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_PAGE, NULL, cb);
@@ -130,14 +132,14 @@ int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecu
return VERR_NO_PAGE_MEMORY;
}
- pMemSolaris->Core.pv = virtAddr;
+ pMemSolaris->Core.pv = virtAddr;
pMemSolaris->pvHandle = NULL;
*ppMem = &pMemSolaris->Core;
return VINF_SUCCESS;
}
-int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
NOREF(fExecutable);
@@ -161,65 +163,42 @@ int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecut
}
-int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
NOREF(fExecutable);
return rtR0MemObjNativeAllocPhys(ppMem, cb, _4G - 1, PAGE_SIZE /* alignment */);
}
-int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
{
#if HC_ARCH_BITS == 64
PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_PHYS_NC, NULL, cb);
if (!pMemSolaris)
return VERR_NO_MEMORY;
- /* Allocate physically non-contiguous page-aligned memory. */
- uint64_t physAddr = PhysHighest;
-
-# if 0
- /*
- * The contig_alloc() way of allocating NC pages is broken or does not match our semantics. Refer #4716 for details.
- */
-# if 0
- /* caddr_t virtAddr = vbi_phys_alloc(&physAddr, cb, PAGE_SIZE, 0 /* non-contiguous */);
-# endif
- caddr_t virtAddr = ddi_umem_alloc(cb, DDI_UMEM_SLEEP, &pMemSolaris->Cookie);
- if (RT_UNLIKELY(virtAddr == NULL))
- {
- rtR0MemObjDelete(&pMemSolaris->Core);
- return VERR_NO_MEMORY;
- }
- pMemSolaris->Core.pv = virtAddr;
- pMemSolaris->Core.u.Phys.PhysBase = physAddr;
- pMemSolaris->Core.u.Phys.fAllocated = true;
- pMemSolaris->pvHandle = NULL;
-# else
- void *pvPages = vbi_pages_alloc(&physAddr, cb);
+ uint64_t PhysAddr = PhysHighest;
+ void *pvPages = vbi_pages_alloc(&PhysAddr, cb);
if (!pvPages)
{
LogRel(("rtR0MemObjNativeAllocPhysNC: vbi_pages_alloc failed.\n"));
rtR0MemObjDelete(&pMemSolaris->Core);
return VERR_NO_MEMORY;
}
- pMemSolaris->Core.pv = NULL;
- pMemSolaris->Core.u.Phys.PhysBase = physAddr;
- pMemSolaris->Core.u.Phys.fAllocated = false;
- pMemSolaris->pvHandle = pvPages;
-# endif
+ pMemSolaris->Core.pv = NULL;
+ pMemSolaris->pvHandle = pvPages;
- Assert(!(physAddr & PAGE_OFFSET_MASK));
+ Assert(!(PhysAddr & PAGE_OFFSET_MASK));
*ppMem = &pMemSolaris->Core;
return VINF_SUCCESS;
-#else
- /** @todo rtR0MemObjNativeAllocPhysNC / solaris */
+
+#else /* 32 bit: */
return VERR_NOT_SUPPORTED; /* see the RTR0MemObjAllocPhysNC specs */
#endif
}
-int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
{
AssertMsgReturn(PhysHighest >= 16 *_1M, ("PhysHigest=%RHp\n", PhysHighest), VERR_NOT_SUPPORTED);
@@ -227,48 +206,71 @@ int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS Ph
if (!pMemSolaris)
return VERR_NO_MEMORY;
- AssertCompile(NIL_RTHCPHYS == UINT64_MAX);
-
- /* Allocate physically contiguous memory aligned as specified. */
- uint64_t physAddr = PhysHighest;
- caddr_t virtAddr = vbi_phys_alloc(&physAddr, cb, uAlignment, 1 /* contiguous */);
- if (RT_UNLIKELY(virtAddr == NULL))
+ /*
+ * Allocating one large page gets special treatment.
+ */
+ static uint32_t s_cbLargePage = UINT32_MAX;
+ if (s_cbLargePage == UINT32_MAX)
{
- rtR0MemObjDelete(&pMemSolaris->Core);
- return VERR_NO_CONT_MEMORY;
+#if 0 /* currently not entirely stable, so disabled. */
+ if (page_num_pagesizes() > 1)
+ ASMAtomicWriteU32(&s_cbLargePage, page_get_pagesize(1));
+ else
+#endif
+ ASMAtomicWriteU32(&s_cbLargePage, 0);
}
- Assert(!(physAddr & PAGE_OFFSET_MASK));
- Assert(physAddr < PhysHighest);
- Assert(physAddr + cb <= PhysHighest);
-#if 0
- if (uAlignment != PAGE_SIZE)
+ uint64_t PhysAddr;
+ if ( cb == s_cbLargePage
+ && cb == uAlignment
+ && PhysHighest == NIL_RTHCPHYS)
{
- /* uAlignment is always a multiple of PAGE_SIZE */
- pgcnt_t cPages = (cb + uAlignment - 1) >> PAGE_SHIFT;
- void *pvPage = virtAddr;
- while (cPages-- > 0)
+ /*
+ * Allocate one large page.
+ */
+ void *pvPages = vbi_large_page_alloc(&PhysAddr, cb);
+ if (pvPages)
{
- uint64_t u64Page = vbi_va_to_pa(pvPage);
- if (u64Page & (uAlignment - 1))
- {
- LogRel(("rtR0MemObjNativeAllocPhys: alignment mismatch! cb=%u uAlignment=%u physAddr=%#x\n", cb, uAlignment, u64Page));
- vbi_phys_free(virtAddr, cb);
- rtR0MemObjDelete(&pMemSolaris->Core);
- return VERR_NO_MEMORY;
- }
- pvPage = (void *)((uintptr_t)pvPage + PAGE_SIZE);
+ AssertMsg(!(PhysAddr & (cb - 1)), ("%RHp\n", PhysAddr));
+ pMemSolaris->Core.pv = NULL;
+ pMemSolaris->Core.u.Phys.PhysBase = PhysAddr;
+ pMemSolaris->Core.u.Phys.fAllocated = true;
+ pMemSolaris->pvHandle = pvPages;
+ pMemSolaris->fLargePage = true;
+
+ *ppMem = &pMemSolaris->Core;
+ return VINF_SUCCESS;
}
}
-#endif
- pMemSolaris->Core.pv = virtAddr;
- pMemSolaris->Core.u.Cont.Phys = physAddr;
- pMemSolaris->pvHandle = NULL;
- *ppMem = &pMemSolaris->Core;
- return VINF_SUCCESS;
+ else
+ {
+ /*
+ * Allocate physically contiguous memory aligned as specified.
+ */
+ AssertCompile(NIL_RTHCPHYS == UINT64_MAX);
+ PhysAddr = PhysHighest;
+ caddr_t pvMem = vbi_phys_alloc(&PhysAddr, cb, uAlignment, 1 /* contiguous */);
+ if (RT_LIKELY(pvMem))
+ {
+ Assert(!(PhysAddr & PAGE_OFFSET_MASK));
+ Assert(PhysAddr < PhysHighest);
+ Assert(PhysAddr + cb <= PhysHighest);
+
+ pMemSolaris->Core.pv = pvMem;
+ pMemSolaris->Core.u.Phys.PhysBase = PhysAddr;
+ pMemSolaris->Core.u.Phys.fAllocated = true;
+ pMemSolaris->pvHandle = NULL;
+ pMemSolaris->fLargePage = false;
+
+ *ppMem = &pMemSolaris->Core;
+ return VINF_SUCCESS;
+ }
+ }
+ rtR0MemObjDelete(&pMemSolaris->Core);
+ return VERR_NO_CONT_MEMORY;
}
-int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
+DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
{
AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
@@ -278,15 +280,16 @@ int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t
return VERR_NO_MEMORY;
/* There is no allocation here, it needs to be mapped somewhere first. */
- pMemSolaris->Core.u.Phys.fAllocated = false;
- pMemSolaris->Core.u.Phys.PhysBase = Phys;
+ pMemSolaris->Core.u.Phys.fAllocated = false;
+ pMemSolaris->Core.u.Phys.PhysBase = Phys;
pMemSolaris->Core.u.Phys.uCachePolicy = uCachePolicy;
*ppMem = &pMemSolaris->Core;
return VINF_SUCCESS;
}
-int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess,
+ RTR0PROCESS R0Process)
{
AssertReturn(R0Process == RTR0ProcHandleSelf(), VERR_INVALID_PARAMETER);
NOREF(fAccess);
@@ -296,14 +299,13 @@ int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t c
if (!pMemSolaris)
return VERR_NO_MEMORY;
+ /* Lock down user pages. */
int fPageAccess = S_READ;
if (fAccess & RTMEM_PROT_WRITE)
fPageAccess = S_WRITE;
if (fAccess & RTMEM_PROT_EXEC)
fPageAccess = S_EXEC;
void *pvPageList = NULL;
-
- /* Lock down user pages */
int rc = vbi_lock_va((caddr_t)R3Ptr, cb, fPageAccess, &pvPageList);
if (rc != 0)
{
@@ -312,15 +314,16 @@ int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t c
return VERR_LOCK_FAILED;
}
- pMemSolaris->Core.u.Lock.R0Process = (RTR0PROCESS)vbi_proc();
- pMemSolaris->pvHandle = pvPageList;
- pMemSolaris->fAccess = fPageAccess;
+ /* Fill in the object attributes and return successfully. */
+ pMemSolaris->Core.u.Lock.R0Process = R0Process;
+ pMemSolaris->pvHandle = pvPageList;
+ pMemSolaris->fAccess = fPageAccess;
*ppMem = &pMemSolaris->Core;
return VINF_SUCCESS;
}
-int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
+DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
{
NOREF(fAccess);
@@ -328,6 +331,7 @@ int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb,
if (!pMemSolaris)
return VERR_NO_MEMORY;
+ /* Lock down kernel pages. */
int fPageAccess = S_READ;
if (fAccess & RTMEM_PROT_WRITE)
fPageAccess = S_WRITE;
@@ -342,6 +346,7 @@ int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb,
return VERR_LOCK_FAILED;
}
+ /* Fill in the object attributes and return successfully. */
pMemSolaris->Core.u.Lock.R0Process = NIL_RTR0PROCESS;
pMemSolaris->pvHandle = pvPageList;
pMemSolaris->fAccess = fPageAccess;
@@ -350,7 +355,7 @@ int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb,
}
-int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
+DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
{
PRTR0MEMOBJSOLARIS pMemSolaris;
@@ -358,7 +363,7 @@ int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, siz
* Use xalloc.
*/
void *pv = vmem_xalloc(heap_arena, cb, uAlignment, 0 /*phase*/, 0 /*nocross*/,
- NULL /*minaddr*/, NULL /*maxaddr*/, VM_SLEEP);
+ NULL /*minaddr*/, NULL /*maxaddr*/, VM_SLEEP);
if (RT_UNLIKELY(!pv))
return VERR_NO_MEMORY;
@@ -377,94 +382,111 @@ int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, siz
}
-int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
{
return VERR_NOT_SUPPORTED;
}
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
- unsigned fProt, size_t offSub, size_t cbSub)
+
+DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+ unsigned fProt, size_t offSub, size_t cbSub)
{
/** @todo rtR0MemObjNativeMapKernel / Solaris - Should be fairly simple alloc kernel memory and memload it. */
return VERR_NOT_SUPPORTED;
}
-int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, PRTR0MEMOBJINTERNAL pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
+DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, PRTR0MEMOBJINTERNAL pMemToMap, RTR3PTR R3PtrFixed,
+ size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
{
+ /*
+ * Fend off things we cannot do.
+ */
AssertMsgReturn(R3PtrFixed == (RTR3PTR)-1, ("%p\n", R3PtrFixed), VERR_NOT_SUPPORTED);
AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
if (uAlignment != PAGE_SIZE)
return VERR_NOT_SUPPORTED;
- PRTR0MEMOBJSOLARIS pMemToMapSolaris = (PRTR0MEMOBJSOLARIS)pMemToMap;
- size_t cb = pMemToMapSolaris->Core.cb;
- void *pv = pMemToMapSolaris->Core.pv;
- pgcnt_t cPages = (cb + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ /*
+ * Get parameters from the source object.
+ */
+ PRTR0MEMOBJSOLARIS pMemToMapSolaris = (PRTR0MEMOBJSOLARIS)pMemToMap;
+ void *pv = pMemToMapSolaris->Core.pv;
+ size_t cb = pMemToMapSolaris->Core.cb;
+ pgcnt_t cPages = cb >> PAGE_SHIFT;
- /* Create the mapping object */
- PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_MAPPING, pv, cb);
+ /*
+ * Create the mapping object
+ */
+ PRTR0MEMOBJSOLARIS pMemSolaris;
+ pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_MAPPING, pv, cb);
if (RT_UNLIKELY(!pMemSolaris))
return VERR_NO_MEMORY;
+ int rc = VINF_SUCCESS;
uint64_t *paPhysAddrs = kmem_zalloc(sizeof(uint64_t) * cPages, KM_SLEEP);
- if (RT_UNLIKELY(!paPhysAddrs))
- return VERR_NO_MEMORY;
-
- if ( pMemToMapSolaris->Core.enmType == RTR0MEMOBJTYPE_PHYS_NC
- && pMemSolaris->Core.u.Phys.fAllocated == false)
+ if (RT_LIKELY(paPhysAddrs))
{
/*
- * The PhysNC object has no kernel mapping backing it. The call to vbi_pages_premap()
- * prepares the physical pages to be mapped into user or kernel space.
+ * Prepare the pages according to type.
*/
- int rc = vbi_pages_premap(pMemToMapSolaris->pvHandle, cb, paPhysAddrs);
- if (rc)
+ if (pMemToMapSolaris->Core.enmType == RTR0MEMOBJTYPE_PHYS_NC)
+ rc = vbi_pages_premap(pMemToMapSolaris->pvHandle, cb, paPhysAddrs);
+ else if ( pMemToMapSolaris->Core.enmType == RTR0MEMOBJTYPE_PHYS
+ && pMemToMapSolaris->fLargePage)
{
- LogRel(("rtR0MemObjNativeMapUser: vbi_pages_premap failed. rc=%d\n", rc));
- kmem_free(paPhysAddrs, sizeof(uint64_t) * cPages);
- rtR0MemObjDelete(&pMemSolaris->Core);
- return VERR_MAP_FAILED;
+ RTHCPHYS Phys = pMemToMapSolaris->Core.u.Phys.PhysBase;
+ for (pgcnt_t iPage = 0; iPage < cPages; iPage++, Phys += PAGE_SIZE)
+ paPhysAddrs[iPage] = Phys;
+ rc = vbi_large_page_premap(pMemToMapSolaris->pvHandle, cb);
}
- }
- else
- {
- /*
- * All other memory object types have allocated memory with kernel mappings.
- */
- for (pgcnt_t iPage = 0; iPage < cPages; iPage++)
+ else
{
- paPhysAddrs[iPage] = vbi_va_to_pa(pv);
- if (RT_UNLIKELY(paPhysAddrs[iPage] == -(uint64_t)1))
+ /* Have kernel mapping, just translate virtual to physical. */
+ AssertPtr(pv);
+ rc = 0;
+ for (pgcnt_t iPage = 0; iPage < cPages; iPage++)
{
- LogRel(("rtR0MemObjNativeMapUser: no page to map.\n"));
- kmem_free(paPhysAddrs, sizeof(uint64_t) * cPages);
- rtR0MemObjDelete(&pMemSolaris->Core);
- return VERR_MAP_FAILED;
+ paPhysAddrs[iPage] = vbi_va_to_pa(pv);
+ if (RT_UNLIKELY(paPhysAddrs[iPage] == -(uint64_t)1))
+ {
+ LogRel(("rtR0MemObjNativeMapUser: no page to map.\n"));
+ rc = -1;
+ break;
+ }
+ pv = (void *)((uintptr_t)pv + PAGE_SIZE);
}
- pv = (void *)((uintptr_t)pv + PAGE_SIZE);
}
- }
+ if (!rc)
+ {
+ /*
+ * Perform the actual mapping.
+ */
+ caddr_t UserAddr = NULL;
+ rc = vbi_user_map(&UserAddr, fProt, paPhysAddrs, cb);
+ if (!rc)
+ {
+ pMemSolaris->Core.u.Mapping.R0Process = R0Process;
+ pMemSolaris->Core.pv = UserAddr;
- caddr_t virtAddr = NULL;
- int rc = vbi_user_map(&virtAddr, fProt, paPhysAddrs, cb);
- if (rc != 0)
- {
- LogRel(("rtR0MemObjNativeMapUser: vbi mapping failure.\n"));
+ *ppMem = &pMemSolaris->Core;
+ kmem_free(paPhysAddrs, sizeof(uint64_t) * cPages);
+ return VINF_SUCCESS;
+ }
+
+ LogRel(("rtR0MemObjNativeMapUser: vbi_user_map failed.\n"));
+ }
+ rc = VERR_MAP_FAILED;
kmem_free(paPhysAddrs, sizeof(uint64_t) * cPages);
- rtR0MemObjDelete(&pMemSolaris->Core);
- return VERR_MAP_FAILED;
}
-
- pMemSolaris->Core.u.Mapping.R0Process = (RTR0PROCESS)vbi_proc();
- pMemSolaris->Core.pv = virtAddr;
- *ppMem = &pMemSolaris->Core;
- kmem_free(paPhysAddrs, sizeof(uint64_t) * cPages);
- return VINF_SUCCESS;
+ else
+ rc = VERR_NO_MEMORY;
+ rtR0MemObjDelete(&pMemSolaris->Core);
+ return rc;
}
-int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
+DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
{
NOREF(pMem);
NOREF(offSub);
@@ -474,12 +496,20 @@ int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSu
}
-RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
+DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
{
PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)pMem;
switch (pMemSolaris->Core.enmType)
{
+ case RTR0MEMOBJTYPE_PHYS_NC:
+ if (pMemSolaris->Core.u.Phys.fAllocated)
+ {
+ uint8_t *pb = (uint8_t *)pMemSolaris->Core.pv + ((size_t)iPage << PAGE_SHIFT);
+ return vbi_va_to_pa(pb);
+ }
+ return vbi_page_to_pa(pMemSolaris->pvHandle, iPage);
+
case RTR0MEMOBJTYPE_PAGE:
case RTR0MEMOBJTYPE_LOW:
case RTR0MEMOBJTYPE_LOCK:
@@ -497,16 +527,7 @@ RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
case RTR0MEMOBJTYPE_CONT:
case RTR0MEMOBJTYPE_PHYS:
- return pMemSolaris->Core.u.Cont.Phys + (iPage << PAGE_SHIFT);
-
- case RTR0MEMOBJTYPE_PHYS_NC:
- if (pMemSolaris->Core.u.Phys.fAllocated == true)
- {
- uint8_t *pb = (uint8_t *)pMemSolaris->Core.pv + ((size_t)iPage << PAGE_SHIFT);
- return vbi_va_to_pa(pb);
- }
- return vbi_page_to_pa(pMemSolaris->pvHandle, iPage);
-
+ AssertFailed(); /* handled by the caller */
case RTR0MEMOBJTYPE_RES_VIRT:
default:
return NIL_RTHCPHYS;
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/mp-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/vbi/mp-r0drv-solaris.c
index 11106cd54..a281c0011 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/mp-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/mp-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: mp-r0drv-solaris.c $ */
+/* $Id: mp-r0drv-solaris.c 37062 2011-05-13 10:18:29Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Ring-0 Driver, Solaris.
*/
@@ -173,6 +173,13 @@ static int rtmpOnAllSolarisWrapper(void *uArg, void *uIgnored1, void *uIgnored2)
{
PRTMPARGS pArgs = (PRTMPARGS)(uArg);
+ /*
+ * Solaris CPU cross calls execute on offline CPUs too. Check our CPU cache
+ * set and ignore if it's offline.
+ */
+ if (!RTMpIsCpuOnline(RTMpCpuId()))
+ return 0;
+
pArgs->pfnWorker(RTMpCpuId(), pArgs->pvUser1, pArgs->pvUser2);
NOREF(uIgnored1);
@@ -278,6 +285,9 @@ RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1
if (idCpu >= vbi_cpu_count())
return VERR_CPU_NOT_FOUND;
+ if (RT_UNLIKELY(!RTMpIsCpuOnline(idCpu)))
+ return RTMpIsCpuPresent(idCpu) ? VERR_CPU_OFFLINE : VERR_CPU_NOT_FOUND;
+
Args.pfnWorker = pfnWorker;
Args.pvUser1 = pvUser1;
Args.pvUser2 = pvUser2;
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/mpnotification-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/vbi/mpnotification-r0drv-solaris.c
index dc2eb4817..65d31989c 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/mpnotification-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/mpnotification-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: mpnotification-r0drv-solaris.c $ */
+/* $Id: mpnotification-r0drv-solaris.c 37274 2011-05-31 11:47:51Z vboxsync $ */
/** @file
* IPRT - Multiprocessor Event Notifications, Ring-0 Driver, Solaris.
*/
@@ -33,6 +33,8 @@
#include <iprt/err.h>
#include <iprt/mp.h>
#include <iprt/cpuset.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
#include "r0drv/mp-r0drv.h"
@@ -48,28 +50,56 @@ static vbi_cpu_watch_t *g_hVbiCpuWatch = NULL;
RTCPUSET g_rtMpSolarisCpuSet;
-static void rtMpNotificationSolarisCallback(void *pvUser, int iCpu, int online)
+static void rtMpNotificationSolarisOnCurrentCpu(void *pvArgs, void *uIgnored1, void *uIgnored2)
{
- NOREF(pvUser);
+ NOREF(uIgnored1);
+ NOREF(uIgnored2);
+
+ PRTMPARGS pArgs = (PRTMPARGS)(pvArgs);
+ AssertRelease(pArgs && pArgs->idCpu == RTMpCpuId());
+ Assert(pArgs->pvUser2);
+ Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
- /* ASSUMES iCpu == RTCPUID */
+ int online = *(int *)pArgs->pvUser2;
if (online)
{
- RTCpuSetAdd(&g_rtMpSolarisCpuSet, iCpu);
- rtMpNotificationDoCallbacks(RTMPEVENT_ONLINE, iCpu);
+ RTCpuSetAdd(&g_rtMpSolarisCpuSet, pArgs->idCpu);
+ rtMpNotificationDoCallbacks(RTMPEVENT_ONLINE, pArgs->idCpu);
}
else
{
- RTCpuSetDel(&g_rtMpSolarisCpuSet, iCpu);
- rtMpNotificationDoCallbacks(RTMPEVENT_OFFLINE, iCpu);
+ RTCpuSetDel(&g_rtMpSolarisCpuSet, pArgs->idCpu);
+ rtMpNotificationDoCallbacks(RTMPEVENT_OFFLINE, pArgs->idCpu);
}
}
-int rtR0MpNotificationNativeInit(void)
+static void rtMpNotificationSolarisCallback(void *pvUser, int iCpu, int online)
+{
+ vbi_preempt_disable();
+
+ RTMPARGS Args;
+ RT_ZERO(Args);
+ Args.pvUser1 = pvUser;
+ Args.pvUser2 = &online;
+ Args.idCpu = iCpu;
+
+ /*
+ * If we're not on the target CPU, schedule (synchronous) the event notification callback
+ * to run on the target CPU i.e. the one pertaining to the MP event.
+ */
+ bool fRunningOnTargetCpu = iCpu == RTMpCpuId(); /* ASSUMES iCpu == RTCPUID */
+ if (fRunningOnTargetCpu)
+ rtMpNotificationSolarisOnCurrentCpu(&Args, NULL /* pvIgnored1 */, NULL /* pvIgnored2 */);
+ else
+ vbi_execute_on_one(rtMpNotificationSolarisOnCurrentCpu, &Args, iCpu);
+
+ vbi_preempt_enable();
+}
+
+
+DECLHIDDEN(int) rtR0MpNotificationNativeInit(void)
{
- if (vbi_revision_level < 2)
- return VERR_NOT_SUPPORTED;
if (g_hVbiCpuWatch != NULL)
return VERR_WRONG_ORDER;
@@ -84,9 +114,9 @@ int rtR0MpNotificationNativeInit(void)
}
-void rtR0MpNotificationNativeTerm(void)
+DECLHIDDEN(void) rtR0MpNotificationNativeTerm(void)
{
- if (vbi_revision_level >= 2 && g_hVbiCpuWatch != NULL)
+ if (g_hVbiCpuWatch != NULL)
vbi_ignore_cpus(g_hVbiCpuWatch);
g_hVbiCpuWatch = NULL;
}
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/process-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/vbi/process-r0drv-solaris.c
index dbfb639c8..3e3b61179 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/process-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/process-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: process-r0drv-solaris.c $ */
+/* $Id: process-r0drv-solaris.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Process Management, Ring-0 Driver, Solaris.
*/
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/thread-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/vbi/thread-r0drv-solaris.c
index 9fbf4eff5..ab31c4b70 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/thread-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/thread-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: thread-r0drv-solaris.c $ */
+/* $Id: thread-r0drv-solaris.c 29281 2010-05-09 23:40:43Z vboxsync $ */
/** @file
* IPRT - Threads, Ring-0 Driver, Solaris.
*/
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/thread2-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/vbi/thread2-r0drv-solaris.c
index 383e33ac8..90958120d 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/thread2-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/thread2-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: thread2-r0drv-solaris.c $ */
+/* $Id: thread2-r0drv-solaris.c 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Threads (Part 2), Ring-0 Driver, Solaris.
*/
@@ -38,7 +38,7 @@
-int rtThreadNativeInit(void)
+DECLHIDDEN(int) rtThreadNativeInit(void)
{
return VINF_SUCCESS;
}
@@ -50,7 +50,7 @@ RTDECL(RTTHREAD) RTThreadSelf(void)
}
-int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
{
int iPriority;
switch (enmType)
@@ -71,7 +71,7 @@ int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
}
-int rtThreadNativeAdopt(PRTTHREADINT pThread)
+DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread)
{
NOREF(pThread);
/* There is nothing special that needs doing here, but the
@@ -80,7 +80,7 @@ int rtThreadNativeAdopt(PRTTHREADINT pThread)
}
-void rtThreadNativeDestroy(PRTTHREADINT pThread)
+DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread)
{
NOREF(pThread);
}
@@ -100,7 +100,7 @@ static void rtThreadNativeMain(void *pvThreadInt)
}
-int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
{
void *pvKernThread;
RT_ASSERT_PREEMPTIBLE();
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/time-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/vbi/time-r0drv-solaris.c
index d8db73fd1..e0b6f903c 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/time-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/time-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: time-r0drv-solaris.c $ */
+/* $Id: time-r0drv-solaris.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Time, Ring-0 Driver, Solaris.
*/
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/timer-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/vbi/timer-r0drv-solaris.c
index feef551da..da5a41622 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/timer-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/timer-r0drv-solaris.c
@@ -1,4 +1,4 @@
-/* $Id: timer-r0drv-solaris.c $ */
+/* $Id: timer-r0drv-solaris.c 37275 2011-05-31 11:48:14Z vboxsync $ */
/** @file
* IPRT - Timer, Ring-0 Driver, Solaris.
*/
@@ -112,8 +112,6 @@ RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_
*/
if (!RTTIMER_FLAGS_ARE_VALID(fFlags))
return VERR_INVALID_PARAMETER;
- if (vbi_revision_level < 2)
- return VERR_NOT_SUPPORTED;
if ( (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
&& (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL
diff --git a/src/VBox/Runtime/r3/alloc-ef-cpp.cpp b/src/VBox/Runtime/r3/alloc-ef-cpp.cpp
index 43ddf34c4..566e564a7 100644
--- a/src/VBox/Runtime/r3/alloc-ef-cpp.cpp
+++ b/src/VBox/Runtime/r3/alloc-ef-cpp.cpp
@@ -1,4 +1,4 @@
-/* $Id: alloc-ef-cpp.cpp $ */
+/* $Id: alloc-ef-cpp.cpp 31252 2010-07-30 15:38:52Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, C++ electric fence.
*/
diff --git a/src/VBox/Runtime/r3/alloc-ef.cpp b/src/VBox/Runtime/r3/alloc-ef.cpp
index 1c45c35d6..e3d3b892e 100644
--- a/src/VBox/Runtime/r3/alloc-ef.cpp
+++ b/src/VBox/Runtime/r3/alloc-ef.cpp
@@ -1,4 +1,4 @@
-/* $Id: alloc-ef.cpp $ */
+/* $Id: alloc-ef.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, electric fence.
*/
diff --git a/src/VBox/Runtime/r3/alloc-ef.h b/src/VBox/Runtime/r3/alloc-ef.h
index d7f630a01..d90dc6328 100644
--- a/src/VBox/Runtime/r3/alloc-ef.h
+++ b/src/VBox/Runtime/r3/alloc-ef.h
@@ -1,4 +1,4 @@
-/* $Id: alloc-ef.h $ */
+/* $Id: alloc-ef.h 34291 2010-11-23 16:06:11Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, electric fence.
*/
diff --git a/src/VBox/Runtime/r3/alloc.cpp b/src/VBox/Runtime/r3/alloc.cpp
index c8ddb7ea7..e790feabc 100644
--- a/src/VBox/Runtime/r3/alloc.cpp
+++ b/src/VBox/Runtime/r3/alloc.cpp
@@ -1,4 +1,4 @@
-/* $Id: alloc.cpp $ */
+/* $Id: alloc.cpp 36597 2011-04-06 19:46:15Z vboxsync $ */
/** @file
* IPRT - Memory Allocation.
*/
@@ -33,6 +33,12 @@
# define RTALLOC_USE_EFENCE 1
#endif
+/*#define RTMEMALLOC_USE_TRACKER*/
+/* Don't enable the tracker when building the minimal IPRT. */
+#ifdef RT_MINI
+# undef RTMEMALLOC_USE_TRACKER
+#endif
+
/*******************************************************************************
* Header Files *
@@ -72,6 +78,8 @@
#undef RTMemDupEx
#undef RTMemDupExTag
+#undef RTALLOC_USE_EFENCE
+
RTDECL(void *) RTMemTmpAllocTag(size_t cb, const char *pszTag) RT_NO_THROW
{
@@ -177,22 +185,11 @@ RTDECL(void *) RTMemReallocTag(void *pvOld, size_t cbNew, const char *pszTag) R
#else /* !RTALLOC_USE_EFENCE */
-# ifdef RTALLOC_USE_TRACKER
- void *pv;
- if (!pvOld)
- {
- if (cbNew)
- pv = RTMemTrackerHdrAlloc(realloc(pvOld, cbNew + sizeof(RTMEMTRACKERHDR)), cbNew,
- pszTag, RTMEMTRACKERMETHOD_REALLOC);
- else
- pv = NULL;
- }
- else
- {
- RTMemTrackerHdrReallocPrep(pvOld, 0, pszTag, RTMEMTRACKERMETHOD_REALLOC);
- pv = RTMemTrackerHdrRealloc(realloc(pvOld, cbNew + sizeof(RTMEMTRACKERHDR)), cbNew, pvOld,
- pszTag, RTMEMTRACKERMETHOD_REALLOC);
- }
+# ifdef RTMEMALLOC_USE_TRACKER
+ void *pvRealOld = RTMemTrackerHdrReallocPrep(pvOld, 0, pszTag);
+ size_t cbRealNew = cbNew || !pvRealOld ? cbNew + sizeof(RTMEMTRACKERHDR) : 0;
+ void *pvNew = realloc(pvRealOld, cbRealNew);
+ void *pv = RTMemTrackerHdrReallocDone(pvNew, cbNew, pvOld, pszTag);
# else
void *pv = realloc(pvOld, cbNew);
# endif
@@ -212,7 +209,7 @@ RTDECL(void) RTMemFree(void *pv) RT_NO_THROW
#ifdef RTALLOC_USE_EFENCE
rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), NULL, 0, NULL);
#else
-# ifdef RTALLOC_USE_TRACKER
+# ifdef RTMEMALLOC_USE_TRACKER
pv = RTMemTrackerHdrFree(pv, 0, NULL, RTMEMTRACKERMETHOD_FREE);
# endif
free(pv);
diff --git a/src/VBox/Runtime/r3/darwin/RTPathUserDocuments-darwin.cpp b/src/VBox/Runtime/r3/darwin/RTPathUserDocuments-darwin.cpp
new file mode 100644
index 000000000..dd9d11133
--- /dev/null
+++ b/src/VBox/Runtime/r3/darwin/RTPathUserDocuments-darwin.cpp
@@ -0,0 +1,55 @@
+/* $Id: RTPathUserDocuments-darwin.cpp 36611 2011-04-07 10:35:29Z vboxsync $ */
+/** @file
+ * IPRT - RTPathUserDocuments, darwin ring-3.
+ */
+
+/*
+ * 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.
+ *
+ * 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/path.h>
+#include <iprt/err.h>
+#include <iprt/assert.h>
+
+#include <CoreServices/CoreServices.h>
+
+RTDECL(int) RTPathUserDocuments(char *pszPath, size_t cchPath)
+{
+ /*
+ * Validate input
+ */
+ AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
+ AssertReturn(cchPath, VERR_INVALID_PARAMETER);
+
+ FSRef ref;
+ OSErr err = FSFindFolder(kOnAppropriateDisk, kDocumentsFolderType, false /* createFolder */, &ref);
+ if (err != noErr)
+ return VERR_PATH_NOT_FOUND;
+
+ err = FSRefMakePath(&ref, (UInt8*)pszPath, cchPath);
+ if (err != noErr)
+ return VERR_PATH_NOT_FOUND;
+
+ return VINF_SUCCESS;
+}
+
diff --git a/src/VBox/Runtime/r3/darwin/RTSystemQueryDmiString-darwin.cpp b/src/VBox/Runtime/r3/darwin/RTSystemQueryDmiString-darwin.cpp
index 064bdcbf1..bea8c0aec 100644
--- a/src/VBox/Runtime/r3/darwin/RTSystemQueryDmiString-darwin.cpp
+++ b/src/VBox/Runtime/r3/darwin/RTSystemQueryDmiString-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSystemQueryDmiString-darwin.cpp $ */
+/* $Id: RTSystemQueryDmiString-darwin.cpp 29560 2010-05-17 15:08:09Z vboxsync $ */
/** @file
* IPRT - RTSystemQueryDmiString, darwin ring-3.
*/
diff --git a/src/VBox/Runtime/r3/darwin/filelock-darwin.cpp b/src/VBox/Runtime/r3/darwin/filelock-darwin.cpp
index f588963e1..614095074 100644
--- a/src/VBox/Runtime/r3/darwin/filelock-darwin.cpp
+++ b/src/VBox/Runtime/r3/darwin/filelock-darwin.cpp
@@ -1,10 +1,10 @@
-/* $Id: filelock-darwin.cpp $ */
+/* $Id: filelock-darwin.cpp 37597 2011-06-22 20:54:05Z vboxsync $ */
/** @file
* IPRT - File Locking, POSIX.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -49,7 +49,7 @@
-RTR3DECL(int) RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock)
+RTR3DECL(int) RTFileLock(RTFILE hFile, unsigned fLock, int64_t offLock, uint64_t cbLock)
{
Assert(offLock >= 0);
@@ -82,7 +82,7 @@ RTR3DECL(int) RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t
fl.l_pid = 0;
Assert(RTFILE_LOCK_WAIT);
- if (fcntl(File, (fLock & RTFILE_LOCK_WAIT) ? F_SETLKW : F_SETLK, &fl) >= 0)
+ if (fcntl(RTFileToNative(hFile), (fLock & RTFILE_LOCK_WAIT) ? F_SETLKW : F_SETLK, &fl) >= 0)
return VINF_SUCCESS;
int iErr = errno;
if (iErr == ENOTSUP)
@@ -101,7 +101,7 @@ RTR3DECL(int) RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t
f |= LOCK_EX;
else
f |= LOCK_SH;
- if (!flock(File, f))
+ if (!flock(RTFileToNative(hFile), f))
return VINF_SUCCESS;
iErr = errno;
if (iErr == EWOULDBLOCK)
@@ -116,14 +116,14 @@ RTR3DECL(int) RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t
}
-RTR3DECL(int) RTFileChangeLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock)
+RTR3DECL(int) RTFileChangeLock(RTFILE hFile, unsigned fLock, int64_t offLock, uint64_t cbLock)
{
/** @todo We never returns VERR_FILE_NOT_LOCKED for now. */
- return RTFileLock(File, fLock, offLock, cbLock);
+ return RTFileLock(hFile, fLock, offLock, cbLock);
}
-RTR3DECL(int) RTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock)
+RTR3DECL(int) RTFileUnlock(RTFILE hFile, int64_t offLock, uint64_t cbLock)
{
Assert(offLock >= 0);
@@ -147,14 +147,14 @@ RTR3DECL(int) RTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock)
fl.l_len = (off_t)cbLock;
fl.l_pid = 0;
- if (fcntl(File, F_SETLK, &fl) >= 0)
+ if (fcntl(RTFileToNative(hFile), F_SETLK, &fl) >= 0)
return VINF_SUCCESS;
int iErr = errno;
if (iErr == ENOTSUP)
{
/* A SMB hack, see RTFileLock. */
- if (!flock(File, LOCK_UN))
+ if (!flock(RTFileToNative(hFile), LOCK_UN))
return VINF_SUCCESS;
}
diff --git a/src/VBox/Runtime/r3/darwin/mp-darwin.cpp b/src/VBox/Runtime/r3/darwin/mp-darwin.cpp
index a03ca41e5..ec1c158e1 100644
--- a/src/VBox/Runtime/r3/darwin/mp-darwin.cpp
+++ b/src/VBox/Runtime/r3/darwin/mp-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: mp-darwin.cpp $ */
+/* $Id: mp-darwin.cpp 36232 2011-03-09 16:41:09Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Darwin.
*/
diff --git a/src/VBox/Runtime/r3/darwin/pathhost-darwin.cpp b/src/VBox/Runtime/r3/darwin/pathhost-darwin.cpp
index 0f575fbae..33452bfcb 100644
--- a/src/VBox/Runtime/r3/darwin/pathhost-darwin.cpp
+++ b/src/VBox/Runtime/r3/darwin/pathhost-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: pathhost-darwin.cpp $ */
+/* $Id: pathhost-darwin.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Path Conversions, Darwin.
*
diff --git a/src/VBox/Runtime/r3/darwin/rtProcInitExePath-darwin.cpp b/src/VBox/Runtime/r3/darwin/rtProcInitExePath-darwin.cpp
index 103e70b44..e9bb2f278 100644
--- a/src/VBox/Runtime/r3/darwin/rtProcInitExePath-darwin.cpp
+++ b/src/VBox/Runtime/r3/darwin/rtProcInitExePath-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: rtProcInitExePath-darwin.cpp $ */
+/* $Id: rtProcInitExePath-darwin.cpp 28929 2010-04-30 11:26:46Z vboxsync $ */
/** @file
* IPRT - rtProcInitName, Darwin.
*/
diff --git a/src/VBox/Runtime/r3/darwin/sched-darwin.cpp b/src/VBox/Runtime/r3/darwin/sched-darwin.cpp
index cc7dee645..1a7cc421c 100644
--- a/src/VBox/Runtime/r3/darwin/sched-darwin.cpp
+++ b/src/VBox/Runtime/r3/darwin/sched-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: sched-darwin.cpp $ */
+/* $Id: sched-darwin.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Scheduling, Darwin.
*/
@@ -220,7 +220,7 @@ static int rtSchedDarwinGetBasePriority(void)
}
-int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
{
Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
@@ -254,7 +254,7 @@ int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
}
-int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
+DECLHIDDEN(int) rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
{
Assert(enmPriority > RTPROCPRIORITY_INVALID && enmPriority < RTPROCPRIORITY_LAST);
@@ -275,7 +275,7 @@ int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
}
-int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
{
Assert(pThread->Core.Key == pthread_self());
Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
diff --git a/src/VBox/Runtime/r3/darwin/time-darwin.cpp b/src/VBox/Runtime/r3/darwin/time-darwin.cpp
index 38878c634..762c9a0d1 100644
--- a/src/VBox/Runtime/r3/darwin/time-darwin.cpp
+++ b/src/VBox/Runtime/r3/darwin/time-darwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: time-darwin.cpp $ */
+/* $Id: time-darwin.cpp 34921 2010-12-09 19:46:36Z vboxsync $ */
/** @file
* IPRT - Time, Darwin.
*/
diff --git a/src/VBox/Runtime/r3/dir.cpp b/src/VBox/Runtime/r3/dir.cpp
index c3e687881..a901dbb57 100644
--- a/src/VBox/Runtime/r3/dir.cpp
+++ b/src/VBox/Runtime/r3/dir.cpp
@@ -1,4 +1,4 @@
-/* $Id: dir.cpp $ */
+/* $Id: dir.cpp 34015 2010-11-12 00:15:05Z vboxsync $ */
/** @file
* IPRT - Directory Manipulation, Part 1.
*/
diff --git a/src/VBox/Runtime/r3/dir2.cpp b/src/VBox/Runtime/r3/dir2.cpp
index cad6d8763..13369dae4 100644
--- a/src/VBox/Runtime/r3/dir2.cpp
+++ b/src/VBox/Runtime/r3/dir2.cpp
@@ -1,4 +1,4 @@
-/* $Id: dir2.cpp $ */
+/* $Id: dir2.cpp 34015 2010-11-12 00:15:05Z vboxsync $ */
/** @file
* IPRT - Directory Manipulation, Part 2.
*/
diff --git a/src/VBox/Runtime/r3/fileio.cpp b/src/VBox/Runtime/r3/fileio.cpp
index 38ec784f6..dd2b5356b 100644
--- a/src/VBox/Runtime/r3/fileio.cpp
+++ b/src/VBox/Runtime/r3/fileio.cpp
@@ -1,4 +1,4 @@
-/* $Id: fileio.cpp $ */
+/* $Id: fileio.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - File I/O.
*/
@@ -106,7 +106,7 @@ RTR3DECL(int) RTFileSetForceFlags(unsigned fOpenForAccess, unsigned fSet, unsig
* Updated on successful return.
* @internal
*/
-int rtFileRecalcAndValidateFlags(uint32_t *pfOpen)
+int rtFileRecalcAndValidateFlags(uint64_t *pfOpen)
{
/*
* Recalc.
@@ -127,20 +127,20 @@ int rtFileRecalcAndValidateFlags(uint32_t *pfOpen)
fOpen &= ~g_fOpenReadWriteMask;
break;
default:
- AssertMsgFailed(("Invalid RW value, fOpen=%#x\n", fOpen));
+ AssertMsgFailed(("Invalid RW value, fOpen=%#llx\n", fOpen));
return VERR_INVALID_PARAMETER;
}
/*
* Validate .
*/
- AssertMsgReturn(fOpen & RTFILE_O_ACCESS_MASK, ("Missing RTFILE_O_READ/WRITE: fOpen=%#x\n", fOpen), VERR_INVALID_PARAMETER);
+ AssertMsgReturn(fOpen & RTFILE_O_ACCESS_MASK, ("Missing RTFILE_O_READ/WRITE: fOpen=%#llx\n", fOpen), VERR_INVALID_PARAMETER);
#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
- AssertMsgReturn(!(fOpen & (~RTFILE_O_VALID_MASK | RTFILE_O_NON_BLOCK)), ("%#x\n", fOpen), VERR_INVALID_PARAMETER);
+ AssertMsgReturn(!(fOpen & (~(uint64_t)RTFILE_O_VALID_MASK | RTFILE_O_NON_BLOCK)), ("%#llx\n", fOpen), VERR_INVALID_PARAMETER);
#else
- AssertMsgReturn(!(fOpen & ~RTFILE_O_VALID_MASK), ("%#x\n", fOpen), VERR_INVALID_PARAMETER);
+ AssertMsgReturn(!(fOpen & ~(uint64_t)RTFILE_O_VALID_MASK), ("%#llx\n", fOpen), VERR_INVALID_PARAMETER);
#endif
- AssertMsgReturn((fOpen & (RTFILE_O_TRUNCATE | RTFILE_O_WRITE)) != RTFILE_O_TRUNCATE, ("%#x\n", fOpen), VERR_INVALID_PARAMETER);
+ AssertMsgReturn((fOpen & (RTFILE_O_TRUNCATE | RTFILE_O_WRITE)) != RTFILE_O_TRUNCATE, ("%#llx\n", fOpen), VERR_INVALID_PARAMETER);
switch (fOpen & RTFILE_O_ACTION_MASK)
{
@@ -149,13 +149,13 @@ int rtFileRecalcAndValidateFlags(uint32_t *pfOpen)
fOpen |= RTFILE_O_OPEN;
break;
case RTFILE_O_OPEN:
- AssertMsgReturn(!(RTFILE_O_NOT_CONTENT_INDEXED & fOpen), ("%#x\n", fOpen), VERR_INVALID_PARAMETER);
+ AssertMsgReturn(!(RTFILE_O_NOT_CONTENT_INDEXED & fOpen), ("%#llx\n", fOpen), VERR_INVALID_PARAMETER);
case RTFILE_O_OPEN_CREATE:
case RTFILE_O_CREATE:
case RTFILE_O_CREATE_REPLACE:
break;
default:
- AssertMsgFailed(("Invalid action value: fOpen=%#x\n", fOpen));
+ AssertMsgFailed(("Invalid action value: fOpen=%#llx\n", fOpen));
return VERR_INVALID_PARAMETER;
}
@@ -175,7 +175,7 @@ int rtFileRecalcAndValidateFlags(uint32_t *pfOpen)
case RTFILE_O_DENY_NOT_DELETE | RTFILE_O_DENY_WRITE | RTFILE_O_DENY_READ:
break;
default:
- AssertMsgFailed(("Invalid deny value: fOpen=%#x\n", fOpen));
+ AssertMsgFailed(("Invalid deny value: fOpen=%#llx\n", fOpen));
return VERR_INVALID_PARAMETER;
}
diff --git a/src/VBox/Runtime/r3/freebsd/fileaio-freebsd.cpp b/src/VBox/Runtime/r3/freebsd/fileaio-freebsd.cpp
index cb04eaa8d..78eb7fe81 100644
--- a/src/VBox/Runtime/r3/freebsd/fileaio-freebsd.cpp
+++ b/src/VBox/Runtime/r3/freebsd/fileaio-freebsd.cpp
@@ -1,4 +1,4 @@
-/* $Id: fileaio-freebsd.cpp $ */
+/* $Id: fileaio-freebsd.cpp 37774 2011-07-04 21:19:27Z vboxsync $ */
/** @file
* IPRT - File async I/O, native implementation for the FreeBSD host platform.
*/
@@ -199,7 +199,7 @@ DECLINLINE(int) rtFileAioReqPrepareTransfer(RTFILEAIOREQ hReq, RTFILE hFile,
pReqInt->AioCB.aio_sigevent.sigev_notify = SIGEV_KEVENT;
pReqInt->AioCB.aio_sigevent.sigev_value.sival_ptr = pReqInt;
pReqInt->AioCB.aio_lio_opcode = uTransferDirection;
- pReqInt->AioCB.aio_fildes = (int)hFile;
+ pReqInt->AioCB.aio_fildes = RTFileToNative(hFile);
pReqInt->AioCB.aio_offset = off;
pReqInt->AioCB.aio_nbytes = cbTransfer;
pReqInt->AioCB.aio_buf = pvBuf;
@@ -235,7 +235,7 @@ RTDECL(int) RTFileAioReqPrepareFlush(RTFILEAIOREQ hReq, RTFILE hFile, void *pvUs
RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS);
pReqInt->fFlush = true;
- pReqInt->AioCB.aio_fildes = (int)hFile;
+ pReqInt->AioCB.aio_fildes = RTFileToNative(hFile);
pReqInt->AioCB.aio_offset = 0;
pReqInt->AioCB.aio_nbytes = 0;
pReqInt->AioCB.aio_buf = NULL;
diff --git a/src/VBox/Runtime/r3/freebsd/mp-freebsd.cpp b/src/VBox/Runtime/r3/freebsd/mp-freebsd.cpp
index 8296025b0..b6481a30f 100644
--- a/src/VBox/Runtime/r3/freebsd/mp-freebsd.cpp
+++ b/src/VBox/Runtime/r3/freebsd/mp-freebsd.cpp
@@ -1,4 +1,4 @@
-/* $Id: mp-freebsd.cpp $ */
+/* $Id: mp-freebsd.cpp 36232 2011-03-09 16:41:09Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, FreeBSD.
*/
diff --git a/src/VBox/Runtime/r3/freebsd/rtProcInitExePath-freebsd.cpp b/src/VBox/Runtime/r3/freebsd/rtProcInitExePath-freebsd.cpp
index 55112775d..a1f4e6669 100644
--- a/src/VBox/Runtime/r3/freebsd/rtProcInitExePath-freebsd.cpp
+++ b/src/VBox/Runtime/r3/freebsd/rtProcInitExePath-freebsd.cpp
@@ -1,4 +1,4 @@
-/* $Id: rtProcInitExePath-freebsd.cpp $ */
+/* $Id: rtProcInitExePath-freebsd.cpp 28929 2010-04-30 11:26:46Z vboxsync $ */
/** @file
* IPRT - rtProcInitName, FreeBSD.
*/
diff --git a/src/VBox/Runtime/r3/fs.cpp b/src/VBox/Runtime/r3/fs.cpp
index 9dc46b599..5637ecd89 100644
--- a/src/VBox/Runtime/r3/fs.cpp
+++ b/src/VBox/Runtime/r3/fs.cpp
@@ -1,4 +1,4 @@
-/* $Id: fs.cpp $ */
+/* $Id: fs.cpp 34015 2010-11-12 00:15:05Z vboxsync $ */
/** @file
* IPRT - File System.
*/
diff --git a/src/VBox/Runtime/r3/generic/semspinmutex-r3-generic.cpp b/src/VBox/Runtime/r3/generic/semspinmutex-r3-generic.cpp
index 1c0e46037..1efc9b236 100644
--- a/src/VBox/Runtime/r3/generic/semspinmutex-r3-generic.cpp
+++ b/src/VBox/Runtime/r3/generic/semspinmutex-r3-generic.cpp
@@ -1,4 +1,4 @@
-/* $Id: semspinmutex-r3-generic.cpp $ */
+/* $Id: semspinmutex-r3-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Spinning Mutex Semaphores, Ring-3, Generic.
*/
diff --git a/src/VBox/Runtime/r3/init.cpp b/src/VBox/Runtime/r3/init.cpp
index 32d6b55d4..b37c2501b 100644
--- a/src/VBox/Runtime/r3/init.cpp
+++ b/src/VBox/Runtime/r3/init.cpp
@@ -1,4 +1,4 @@
-/* $Id: init.cpp $ */
+/* $Id: init.cpp 36549 2011-04-05 09:28:24Z vboxsync $ */
/** @file
* IPRT - Init Ring-3.
*/
@@ -74,44 +74,50 @@
* Global Variables *
*******************************************************************************/
/** The number of calls to RTR3Init. */
-static int32_t volatile g_cUsers = 0;
+static int32_t volatile g_cUsers = 0;
/** Whether we're currently initializing the IPRT. */
-static bool volatile g_fInitializing = false;
+static bool volatile g_fInitializing = false;
/** The process path.
* This is used by RTPathExecDir and RTProcGetExecutablePath and set by rtProcInitName. */
-char g_szrtProcExePath[RTPATH_MAX];
+DECLHIDDEN(char) g_szrtProcExePath[RTPATH_MAX];
/** The length of g_szrtProcExePath. */
-size_t g_cchrtProcExePath;
+DECLHIDDEN(size_t) g_cchrtProcExePath;
/** The length of directory path component of g_szrtProcExePath. */
-size_t g_cchrtProcDir;
+DECLHIDDEN(size_t) g_cchrtProcDir;
/** The offset of the process name into g_szrtProcExePath. */
-size_t g_offrtProcName;
+DECLHIDDEN(size_t) g_offrtProcName;
/**
* Program start nanosecond TS.
*/
-uint64_t g_u64ProgramStartNanoTS;
+DECLHIDDEN(uint64_t) g_u64ProgramStartNanoTS;
/**
* Program start microsecond TS.
*/
-uint64_t g_u64ProgramStartMicroTS;
+DECLHIDDEN(uint64_t) g_u64ProgramStartMicroTS;
/**
* Program start millisecond TS.
*/
-uint64_t g_u64ProgramStartMilliTS;
+DECLHIDDEN(uint64_t) g_u64ProgramStartMilliTS;
/**
* The process identifier of the running process.
*/
-RTPROCESS g_ProcessSelf = NIL_RTPROCESS;
+DECLHIDDEN(RTPROCESS) g_ProcessSelf = NIL_RTPROCESS;
/**
* The current process priority.
*/
-RTPROCPRIORITY g_enmProcessPriority = RTPROCPRIORITY_DEFAULT;
+DECLHIDDEN(RTPROCPRIORITY) g_enmProcessPriority = RTPROCPRIORITY_DEFAULT;
+
+/**
+ * Set if the atexit callback has been called, i.e. indicating
+ * that the process is terminating.
+ */
+DECLHIDDEN(bool volatile) g_frtAtExitCalled = false;
#ifdef IPRT_WITH_ALIGNMENT_CHECKS
/**
@@ -130,6 +136,8 @@ RTDATADECL(bool) g_fRTAlignmentChecks = false;
*/
static void rtR3ExitCallback(void)
{
+ ASMAtomicWriteBool(&g_frtAtExitCalled, true);
+
if (g_cUsers > 0)
{
PRTLOGGER pLogger = RTLogGetDefaultInstance();
diff --git a/src/VBox/Runtime/r3/isofs.cpp b/src/VBox/Runtime/r3/isofs.cpp
index eca523d26..f783cc674 100644
--- a/src/VBox/Runtime/r3/isofs.cpp
+++ b/src/VBox/Runtime/r3/isofs.cpp
@@ -1,4 +1,4 @@
-/* $Id: isofs.cpp $ */
+/* $Id: isofs.cpp 34406 2010-11-26 16:45:34Z vboxsync $ */
/** @file
* IPRT - ISO 9660 file system handling.
*/
diff --git a/src/VBox/Runtime/r3/linux/RTProcIsRunningByName-linux.cpp b/src/VBox/Runtime/r3/linux/RTProcIsRunningByName-linux.cpp
index 5582cef91..065856c2e 100644
--- a/src/VBox/Runtime/r3/linux/RTProcIsRunningByName-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/RTProcIsRunningByName-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTProcIsRunningByName-linux.cpp $ */
+/* $Id: RTProcIsRunningByName-linux.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTProcIsRunningByName, Linux implementation.
*/
diff --git a/src/VBox/Runtime/r3/linux/RTSystemQueryDmiString-linux.cpp b/src/VBox/Runtime/r3/linux/RTSystemQueryDmiString-linux.cpp
index 056a6ade3..91cfbcd66 100644
--- a/src/VBox/Runtime/r3/linux/RTSystemQueryDmiString-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/RTSystemQueryDmiString-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSystemQueryDmiString-linux.cpp $ */
+/* $Id: RTSystemQueryDmiString-linux.cpp 29642 2010-05-18 14:44:56Z vboxsync $ */
/** @file
* IPRT - RTSystemQueryDmiString, linux ring-3.
*/
diff --git a/src/VBox/Runtime/r3/linux/RTThreadGetNativeState-linux.cpp b/src/VBox/Runtime/r3/linux/RTThreadGetNativeState-linux.cpp
index 2a7c13964..ff65d2575 100644
--- a/src/VBox/Runtime/r3/linux/RTThreadGetNativeState-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/RTThreadGetNativeState-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTThreadGetNativeState-linux.cpp $ */
+/* $Id: RTThreadGetNativeState-linux.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTThreadGetNativeState, linux implementation.
*/
diff --git a/src/VBox/Runtime/r3/linux/fileaio-linux.cpp b/src/VBox/Runtime/r3/linux/fileaio-linux.cpp
index d7e0da480..4a268633e 100644
--- a/src/VBox/Runtime/r3/linux/fileaio-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/fileaio-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: fileaio-linux.cpp $ */
+/* $Id: fileaio-linux.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - File async I/O, native implementation for the Linux host platform.
*/
@@ -104,7 +104,7 @@ typedef struct LNXKAIOIOCB
/** Request priority. */
int16_t i16Priority;
/** The file descriptor. */
- uint32_t File;
+ uint32_t uFileDesc;
/** The userspace pointer to the buffer containing/receiving the data. */
void *pvBuf;
#ifdef RT_ARCH_X86
@@ -378,7 +378,7 @@ DECLINLINE(int) rtFileAioReqPrepareTransfer(RTFILEAIOREQ hReq, RTFILE hFile,
* Setup the control block and clear the finished flag.
*/
pReqInt->AioCB.u16IoOpCode = uTransferDirection;
- pReqInt->AioCB.File = (uint32_t)hFile;
+ pReqInt->AioCB.uFileDesc = RTFileToNative(hFile);
pReqInt->AioCB.off = off;
pReqInt->AioCB.cbTransfer = cbTransfer;
pReqInt->AioCB.pvBuf = pvBuf;
diff --git a/src/VBox/Runtime/r3/linux/mp-linux.cpp b/src/VBox/Runtime/r3/linux/mp-linux.cpp
index 54304abad..fa7001a7c 100644
--- a/src/VBox/Runtime/r3/linux/mp-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/mp-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: mp-linux.cpp $ */
+/* $Id: mp-linux.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Linux.
*/
diff --git a/src/VBox/Runtime/r3/linux/rtProcInitExePath-linux.cpp b/src/VBox/Runtime/r3/linux/rtProcInitExePath-linux.cpp
index 3ab0860b0..50a12f24f 100644
--- a/src/VBox/Runtime/r3/linux/rtProcInitExePath-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/rtProcInitExePath-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: rtProcInitExePath-linux.cpp $ */
+/* $Id: rtProcInitExePath-linux.cpp 28929 2010-04-30 11:26:46Z vboxsync $ */
/** @file
* IPRT - rtProcInitName, Linux.
*/
diff --git a/src/VBox/Runtime/r3/linux/sched-linux.cpp b/src/VBox/Runtime/r3/linux/sched-linux.cpp
index b1d19093c..824f79759 100644
--- a/src/VBox/Runtime/r3/linux/sched-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/sched-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: sched-linux.cpp $ */
+/* $Id: sched-linux.cpp 36912 2011-05-02 14:23:01Z vboxsync $ */
/** @file
* IPRT - Scheduling, POSIX.
*/
@@ -467,7 +467,7 @@ static void *rtSchedNativeProberThread(void *pvUser)
* @returns iprt status code.
* @param enmType The thread type to be assumed for the current thread.
*/
-int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
{
Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
@@ -548,7 +548,7 @@ static void *rtSchedNativeValidatorThread(void *pvUser)
* @returns iprt status code.
* @param enmPriority The priority to validate and set.
*/
-int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
+DECLHIDDEN(int) rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
{
Assert(enmPriority > RTPROCPRIORITY_INVALID && enmPriority < RTPROCPRIORITY_LAST);
@@ -599,7 +599,7 @@ int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
* @param pThread The thread in question.
* @param enmType The thread type.
*/
-int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
{
/* sanity */
Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
diff --git a/src/VBox/Runtime/r3/linux/semevent-linux.cpp b/src/VBox/Runtime/r3/linux/semevent-linux.cpp
index 9982d3e83..a35020fc3 100644
--- a/src/VBox/Runtime/r3/linux/semevent-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/semevent-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: semevent-linux.cpp $ */
+/* $Id: semevent-linux.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Event Semaphore, Linux (2.6.x+).
*/
diff --git a/src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp b/src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp
index c98f4ab26..ac74d4780 100644
--- a/src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: semeventmulti-linux.cpp $ */
+/* $Id: semeventmulti-linux.cpp 37211 2011-05-25 11:37:52Z vboxsync $ */
/** @file
* IPRT - Multiple Release Event Semaphore, Linux (2.6.x+).
*/
@@ -174,7 +174,7 @@ RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI hEventMultiSem)
/*
* Invalidate the semaphore and wake up anyone waiting on it.
*/
- ASMAtomicWriteSize(&pThis->u32Magic, RTSEMEVENTMULTI_MAGIC + 1);
+ ASMAtomicWriteU32(&pThis->u32Magic, RTSEMEVENTMULTI_MAGIC + 1);
if (ASMAtomicXchgS32(&pThis->iState, -1) == 1)
{
sys_futex(&pThis->iState, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
diff --git a/src/VBox/Runtime/r3/linux/semmutex-linux.cpp b/src/VBox/Runtime/r3/linux/semmutex-linux.cpp
index 1be76f4e7..16a28270f 100644
--- a/src/VBox/Runtime/r3/linux/semmutex-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/semmutex-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: semmutex-linux.cpp $ */
+/* $Id: semmutex-linux.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Mutex Semaphore, Linux (2.6.x+).
*/
diff --git a/src/VBox/Runtime/r3/linux/sysfs.cpp b/src/VBox/Runtime/r3/linux/sysfs.cpp
index aa1060ac3..49bba0e5a 100644
--- a/src/VBox/Runtime/r3/linux/sysfs.cpp
+++ b/src/VBox/Runtime/r3/linux/sysfs.cpp
@@ -1,4 +1,4 @@
-/* $Id: sysfs.cpp $ */
+/* $Id: sysfs.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Linux sysfs access.
*/
diff --git a/src/VBox/Runtime/r3/linux/thread-affinity-linux.cpp b/src/VBox/Runtime/r3/linux/thread-affinity-linux.cpp
new file mode 100644
index 000000000..1cbefafc6
--- /dev/null
+++ b/src/VBox/Runtime/r3/linux/thread-affinity-linux.cpp
@@ -0,0 +1,95 @@
+/* $Id: thread-affinity-linux.cpp 37170 2011-05-20 17:15:07Z vboxsync $ */
+/** @file
+ * IPRT - Thread Affinity, Linux ring-3 implementation.
+ */
+
+/*
+ * 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.
+ *
+ * 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 *
+*******************************************************************************/
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+#include <features.h>
+#if __GLIBC_PREREQ(2,4)
+
+#include <sched.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <iprt/thread.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/cpuset.h>
+#include <iprt/err.h>
+#include <iprt/mp.h>
+
+
+
+RTR3DECL(int) RTThreadSetAffinity(PCRTCPUSET pCpuSet)
+{
+ /* convert */
+ cpu_set_t LnxCpuSet;
+ CPU_ZERO(&LnxCpuSet);
+ if (!pCpuSet)
+ for (unsigned iCpu = 0; iCpu < CPU_SETSIZE; iCpu++)
+ CPU_SET(iCpu, &LnxCpuSet);
+ else
+ for (unsigned iCpu = 0; iCpu < RT_MIN(CPU_SETSIZE, RTCPUSET_MAX_CPUS); iCpu++)
+ if (RTCpuSetIsMemberByIndex(pCpuSet, iCpu))
+ CPU_SET(iCpu, &LnxCpuSet);
+
+ int rc = pthread_setaffinity_np(pthread_self(), sizeof(LnxCpuSet), &LnxCpuSet);
+ if (!rc)
+ return VINF_SUCCESS;
+ rc = errno;
+ if (rc == ENOENT)
+ return VERR_CPU_NOT_FOUND;
+ return RTErrConvertFromErrno(errno);
+}
+
+
+RTR3DECL(int) RTThreadGetAffinity(PRTCPUSET pCpuSet)
+{
+ cpu_set_t LnxCpuSet;
+ int rc = pthread_getaffinity_np(pthread_self(), sizeof(LnxCpuSet), &LnxCpuSet);
+ if (rc != 0)
+ return RTErrConvertFromErrno(errno);
+
+ /* convert */
+ RTCpuSetEmpty(pCpuSet);
+ for (unsigned iCpu = 0; iCpu < RT_MIN(CPU_SETSIZE, RTCPUSET_MAX_CPUS); iCpu++)
+ if (CPU_ISSET(iCpu, &LnxCpuSet))
+ RTCpuSetAddByIndex(pCpuSet, iCpu);
+
+ return VINF_SUCCESS;
+}
+
+#else
+# include "../../generic/RTThreadGetAffinity-stub-generic.cpp"
+# include "../../generic/RTThreadSetAffinity-stub-generic.cpp"
+#endif
+
diff --git a/src/VBox/Runtime/r3/linux/time-linux.cpp b/src/VBox/Runtime/r3/linux/time-linux.cpp
index a9de927e7..b9be9e532 100644
--- a/src/VBox/Runtime/r3/linux/time-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/time-linux.cpp
@@ -1,4 +1,4 @@
-/* $Id: time-linux.cpp $ */
+/* $Id: time-linux.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Time, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/os2/filelock-os2.cpp b/src/VBox/Runtime/r3/os2/filelock-os2.cpp
index 734bb1807..c6317f43b 100644
--- a/src/VBox/Runtime/r3/os2/filelock-os2.cpp
+++ b/src/VBox/Runtime/r3/os2/filelock-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: filelock-os2.cpp $ */
+/* $Id: filelock-os2.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - File Locking, OS/2.
*/
diff --git a/src/VBox/Runtime/r3/os2/mp-os2.cpp b/src/VBox/Runtime/r3/os2/mp-os2.cpp
index 00260ca01..ea4b14cc9 100644
--- a/src/VBox/Runtime/r3/os2/mp-os2.cpp
+++ b/src/VBox/Runtime/r3/os2/mp-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: mp-os2.cpp $ */
+/* $Id: mp-os2.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, OS/2.
*/
diff --git a/src/VBox/Runtime/r3/os2/pipe-os2.cpp b/src/VBox/Runtime/r3/os2/pipe-os2.cpp
index b3fbecf1d..b84b3226d 100644
--- a/src/VBox/Runtime/r3/os2/pipe-os2.cpp
+++ b/src/VBox/Runtime/r3/os2/pipe-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: pipe-os2.cpp $ */
+/* $Id: pipe-os2.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Anonymous Pipes, OS/2 Implementation.
*/
diff --git a/src/VBox/Runtime/r3/os2/poll-os2.cpp b/src/VBox/Runtime/r3/os2/poll-os2.cpp
index 890cdc8cd..988cad5d8 100644
--- a/src/VBox/Runtime/r3/os2/poll-os2.cpp
+++ b/src/VBox/Runtime/r3/os2/poll-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: poll-os2.cpp $ */
+/* $Id: poll-os2.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Polling I/O Handles, OS/2 Implementation.
*/
diff --git a/src/VBox/Runtime/r3/os2/rtProcInitExePath-os2.cpp b/src/VBox/Runtime/r3/os2/rtProcInitExePath-os2.cpp
index 26ee5b49f..a991619e7 100644
--- a/src/VBox/Runtime/r3/os2/rtProcInitExePath-os2.cpp
+++ b/src/VBox/Runtime/r3/os2/rtProcInitExePath-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: rtProcInitExePath-os2.cpp $ */
+/* $Id: rtProcInitExePath-os2.cpp 28929 2010-04-30 11:26:46Z vboxsync $ */
/** @file
* IPRT - rtProcInitName, OS/2.
*/
diff --git a/src/VBox/Runtime/r3/os2/sched-os2.cpp b/src/VBox/Runtime/r3/os2/sched-os2.cpp
index 60bd3b83e..b38b5bb42 100644
--- a/src/VBox/Runtime/r3/os2/sched-os2.cpp
+++ b/src/VBox/Runtime/r3/os2/sched-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: sched-os2.cpp $ */
+/* $Id: sched-os2.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Scheduling, OS/2
*/
@@ -189,7 +189,7 @@ static const PROCPRIORITY *g_pProcessPriority = &g_aDefaultPriority;
* @returns iprt status code.
* @param enmType The thread type to be assumed for the current thread.
*/
-int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
{
Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
return VINF_SUCCESS;
@@ -205,7 +205,7 @@ int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
* @param enmPriority The priority to validate and set.
* @remark Located in sched.
*/
-int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
+DECLHIDDEN(int) rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
{
Assert(enmPriority > RTPROCPRIORITY_INVALID && enmPriority < RTPROCPRIORITY_LAST);
return VINF_SUCCESS;
@@ -224,7 +224,7 @@ int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
* @param enmType The thread type.
* @remark Located in sched.
*/
-int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
{
Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
AssertMsg(g_pProcessPriority && g_pProcessPriority->aTypes[enmType].enmType == enmType,
diff --git a/src/VBox/Runtime/r3/os2/sems-os2.cpp b/src/VBox/Runtime/r3/os2/sems-os2.cpp
index 09042b79e..e41511b99 100644
--- a/src/VBox/Runtime/r3/os2/sems-os2.cpp
+++ b/src/VBox/Runtime/r3/os2/sems-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: sems-os2.cpp $ */
+/* $Id: sems-os2.cpp 33393 2010-10-24 16:17:00Z vboxsync $ */
/** @file
* IPRT - Semaphores, OS/2.
*/
diff --git a/src/VBox/Runtime/r3/os2/thread-os2.cpp b/src/VBox/Runtime/r3/os2/thread-os2.cpp
index 76c30288c..8b85f4324 100644
--- a/src/VBox/Runtime/r3/os2/thread-os2.cpp
+++ b/src/VBox/Runtime/r3/os2/thread-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: thread-os2.cpp $ */
+/* $Id: thread-os2.cpp 37154 2011-05-19 12:54:32Z vboxsync $ */
/** @file
* IPRT - Threads, OS/2.
*/
@@ -63,7 +63,7 @@ static PRTTHREADINT *g_ppCurThread;
static void rtThreadNativeMain(void *pvArgs);
-int rtThreadNativeInit(void)
+DECLHIDDEN(int) rtThreadNativeInit(void)
{
/*
* Allocate thread local memory.
@@ -77,7 +77,7 @@ int rtThreadNativeInit(void)
}
-int rtThreadNativeAdopt(PRTTHREADINT pThread)
+DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread)
{
/*
* Block SIGALRM - required for timer-posix.cpp.
@@ -94,7 +94,7 @@ int rtThreadNativeAdopt(PRTTHREADINT pThread)
}
-void rtThreadNativeDestroy(PRTTHREADINT pThread)
+DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread)
{
if (pThread == *g_ppCurThread)
*g_ppCurThread = NULL;
@@ -133,7 +133,7 @@ static void rtThreadNativeMain(void *pvArgs)
}
-int rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
{
/*
* Default stack size.
@@ -198,7 +198,12 @@ RTDECL(bool) RTThreadYield(void)
}
-RTDECL(uint64_t) RTThreadGetAffinity(void)
+RTR3DECL(int) RTThreadGetAffinity(PRTCPUSET pCpuSet)
+{
+ return VINF_SUCCESS;
+}
+
+RTR3DECL(int) RTThreadGetAffinity(PRTCPUSET pCpuSet)
{
union
{
@@ -206,21 +211,24 @@ RTDECL(uint64_t) RTThreadGetAffinity(void)
MPAFFINITY mpaff;
} u;
- int rc = DosQueryThreadAffinity(AFNTY_THREAD, &u.mpaff);
- if (rc)
- u.u64 = 1;
- return u.u64;
+ APIRET rc = DosQueryThreadAffinity(AFNTY_THREAD, &u.mpaff);
+ if (!rc)
+ {
+ RTCpuSetFromU64(pCpuSet, u.u64);
+ return VINF_SUCCESS;
+ }
+ return RTErrConvertFromOS2(rc);
}
-RTDECL(int) RTThreadSetAffinity(uint64_t u64Mask)
+RTR3DECL(int) RTThreadSetAffinity(PCRTCPUSET pCpuSet)
{
union
{
uint64_t u64;
MPAFFINITY mpaff;
} u;
- u.u64 = u64Mask;
+ u.u64 = pCpuSet ? RTCpuSetToU64(pCpuSet) : UINT64_MAX;
int rc = DosSetThreadAffinity(&u.mpaff);
if (!rc)
return VINF_SUCCESS;
diff --git a/src/VBox/Runtime/r3/os2/time-os2.cpp b/src/VBox/Runtime/r3/os2/time-os2.cpp
index 13fcad048..d39e1fc24 100644
--- a/src/VBox/Runtime/r3/os2/time-os2.cpp
+++ b/src/VBox/Runtime/r3/os2/time-os2.cpp
@@ -1,4 +1,4 @@
-/* $Id: time-os2.cpp $ */
+/* $Id: time-os2.cpp 8245 2008-04-21 17:24:28Z vboxsync $ */
/** @file
* IPRT - Time, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/path.cpp b/src/VBox/Runtime/r3/path.cpp
index 591f0556d..28661291e 100644
--- a/src/VBox/Runtime/r3/path.cpp
+++ b/src/VBox/Runtime/r3/path.cpp
@@ -1,4 +1,4 @@
-/* $Id: path.cpp $ */
+/* $Id: path.cpp 35225 2010-12-17 13:54:46Z vboxsync $ */
/** @file
* IPRT - Path Manipulation.
*/
diff --git a/src/VBox/Runtime/r3/posix/RTFileQueryFsSizes-posix.cpp b/src/VBox/Runtime/r3/posix/RTFileQueryFsSizes-posix.cpp
index d87bb4e0a..8d8b92f7d 100644
--- a/src/VBox/Runtime/r3/posix/RTFileQueryFsSizes-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/RTFileQueryFsSizes-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTFileQueryFsSizes-posix.cpp $ */
+/* $Id: RTFileQueryFsSizes-posix.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - File I/O, RTFileFsQuerySizes, POSIX.
*/
@@ -47,7 +47,7 @@ RTR3DECL(int) RTFileQueryFsSizes(RTFILE hFile, PRTFOFF pcbTotal, RTFOFF *pcbFree
{
struct statvfs StatVFS;
RT_ZERO(StatVFS);
- if (fstatvfs(hFile, &StatVFS))
+ if (fstatvfs(RTFileToNative(hFile), &StatVFS))
return RTErrConvertFromErrno(errno);
/*
diff --git a/src/VBox/Runtime/r3/posix/RTHandleGetStandard-posix.cpp b/src/VBox/Runtime/r3/posix/RTHandleGetStandard-posix.cpp
index aa12323b4..31bc53409 100644
--- a/src/VBox/Runtime/r3/posix/RTHandleGetStandard-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/RTHandleGetStandard-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTHandleGetStandard-posix.cpp $ */
+/* $Id: RTHandleGetStandard-posix.cpp 33973 2010-11-11 11:10:10Z vboxsync $ */
/** @file
* IPRT - RTHandleGetStandard, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/RTMemProtect-posix.cpp b/src/VBox/Runtime/r3/posix/RTMemProtect-posix.cpp
index 87055143d..7ea5a44d0 100644
--- a/src/VBox/Runtime/r3/posix/RTMemProtect-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/RTMemProtect-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMemProtect-posix.cpp $ */
+/* $Id: RTMemProtect-posix.cpp 33269 2010-10-20 15:42:28Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/RTMpGetCount-posix.cpp b/src/VBox/Runtime/r3/posix/RTMpGetCount-posix.cpp
index 4e2e116dd..740e437b5 100644
--- a/src/VBox/Runtime/r3/posix/RTMpGetCount-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/RTMpGetCount-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTMpGetCount-posix.cpp $ */
+/* $Id: RTMpGetCount-posix.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTMpGetCount, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/RTPathUserDocuments-posix.cpp b/src/VBox/Runtime/r3/posix/RTPathUserDocuments-posix.cpp
new file mode 100644
index 000000000..d048e3f99
--- /dev/null
+++ b/src/VBox/Runtime/r3/posix/RTPathUserDocuments-posix.cpp
@@ -0,0 +1,52 @@
+/* $Id: RTPathUserDocuments-posix.cpp 36611 2011-04-07 10:35:29Z vboxsync $ */
+/** @file
+ * IPRT - RTPathUserDocuments, posix ring-3.
+ */
+
+/*
+ * 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.
+ *
+ * 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/path.h>
+#include <iprt/err.h>
+#include <iprt/assert.h>
+
+RTDECL(int) RTPathUserDocuments(char *pszPath, size_t cchPath)
+{
+ /*
+ * Validate input
+ */
+ AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
+ AssertReturn(cchPath, VERR_INVALID_PARAMETER);
+
+ int rc = RTPathUserHome(pszPath, cchPath);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ rc = RTPathAppend(pszPath, cchPath, "Documents");
+ if (RT_FAILURE(rc))
+ *pszPath = '\0';
+
+ return rc;
+}
+
diff --git a/src/VBox/Runtime/r3/posix/RTPathUserHome-posix.cpp b/src/VBox/Runtime/r3/posix/RTPathUserHome-posix.cpp
index d39fd6c6b..8111dd987 100644
--- a/src/VBox/Runtime/r3/posix/RTPathUserHome-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/RTPathUserHome-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTPathUserHome-posix.cpp $ */
+/* $Id: RTPathUserHome-posix.cpp 33602 2010-10-29 12:39:54Z vboxsync $ */
/** @file
* IPRT - Path Manipulation, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/RTSystemQueryOSInfo-posix.cpp b/src/VBox/Runtime/r3/posix/RTSystemQueryOSInfo-posix.cpp
index b37d921e0..8e17a976a 100644
--- a/src/VBox/Runtime/r3/posix/RTSystemQueryOSInfo-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/RTSystemQueryOSInfo-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSystemQueryOSInfo-posix.cpp $ */
+/* $Id: RTSystemQueryOSInfo-posix.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTSystemQueryOSInfo, POSIX implementation.
*/
diff --git a/src/VBox/Runtime/r3/posix/RTSystemQueryTotalRam-posix.cpp b/src/VBox/Runtime/r3/posix/RTSystemQueryTotalRam-posix.cpp
index a75d2d54d..a52065855 100644
--- a/src/VBox/Runtime/r3/posix/RTSystemQueryTotalRam-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/RTSystemQueryTotalRam-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSystemQueryTotalRam-posix.cpp $ */
+/* $Id: RTSystemQueryTotalRam-posix.cpp 33503 2010-10-27 13:12:57Z vboxsync $ */
/** @file
* IPRT - RTSystemQueryTotalRam, windows ring-3.
*/
diff --git a/src/VBox/Runtime/r3/posix/RTTimeNow-posix.cpp b/src/VBox/Runtime/r3/posix/RTTimeNow-posix.cpp
index 96915feac..43f628271 100644
--- a/src/VBox/Runtime/r3/posix/RTTimeNow-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/RTTimeNow-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTTimeNow-posix.cpp $ */
+/* $Id: RTTimeNow-posix.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTTimeNow, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/RTTimeSet-posix.cpp b/src/VBox/Runtime/r3/posix/RTTimeSet-posix.cpp
index 3bebb9ac4..32a09a975 100644
--- a/src/VBox/Runtime/r3/posix/RTTimeSet-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/RTTimeSet-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTTimeSet-posix.cpp $ */
+/* $Id: RTTimeSet-posix.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTTimeSet, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/dir-posix.cpp b/src/VBox/Runtime/r3/posix/dir-posix.cpp
index 52a839099..17c67c025 100644
--- a/src/VBox/Runtime/r3/posix/dir-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/dir-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: dir-posix.cpp $ */
+/* $Id: dir-posix.cpp 36167 2011-03-04 12:33:39Z vboxsync $ */
/** @file
* IPRT - Directory manipulation, POSIX.
*/
@@ -90,6 +90,7 @@ RTDECL(int) RTDirCreate(const char *pszPath, RTFMODE fMode)
if (mkdir(pszNativePath, fMode & RTFS_UNIX_MASK))
{
rc = errno;
+ bool fVerifyIsDir = true;
#ifdef RT_OS_SOLARIS
/*
* mkdir on nfs mount points has been/is busted in various
@@ -100,12 +101,31 @@ RTDECL(int) RTDirCreate(const char *pszPath, RTFMODE fMode)
if ( rc == ENOSYS
|| rc == EACCES)
{
+ rc = RTErrConvertFromErrno(rc);
+ fVerifyIsDir = false; /* We'll check if it's a dir ourselves since we're going to stat() anyway. */
struct stat st;
if (!stat(pszNativePath, &st))
- rc = EEXIST;
+ {
+ rc = VERR_ALREADY_EXISTS;
+ if (!S_ISDIR(st.st_mode))
+ rc = VERR_IS_A_FILE;
+ }
}
-#endif
+ else
+ rc = RTErrConvertFromErrno(rc);
+#else
rc = RTErrConvertFromErrno(rc);
+#endif
+ if ( rc == VERR_ALREADY_EXISTS
+ && fVerifyIsDir == true)
+ {
+ /*
+ * Verify that it really exists as a directory.
+ */
+ struct stat st;
+ if (!stat(pszNativePath, &st) && !S_ISDIR(st.st_mode))
+ rc = VERR_IS_A_FILE;
+ }
}
}
@@ -253,7 +273,10 @@ static int rtDirReadMore(PRTDIR pDir)
if (rc)
{
rc = RTErrConvertFromErrno(rc);
- AssertRC(rc);
+ /** @todo Consider translating ENOENT (The current
+ * position of the directory stream is invalid)
+ * differently. */
+ AssertMsg(rc == VERR_FILE_NOT_FOUND, ("%Rrc\n", rc));
return rc;
}
if (!pResult)
diff --git a/src/VBox/Runtime/r3/posix/env-posix.cpp b/src/VBox/Runtime/r3/posix/env-posix.cpp
index 3134d7644..fe30150b5 100644
--- a/src/VBox/Runtime/r3/posix/env-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/env-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: env-posix.cpp $ */
+/* $Id: env-posix.cpp 33464 2010-10-26 12:27:50Z vboxsync $ */
/** @file
* IPRT - Environment, Posix.
*/
diff --git a/src/VBox/Runtime/r3/posix/errvars-posix.cpp b/src/VBox/Runtime/r3/posix/errvars-posix.cpp
new file mode 100644
index 000000000..aa2a2b273
--- /dev/null
+++ b/src/VBox/Runtime/r3/posix/errvars-posix.cpp
@@ -0,0 +1,78 @@
+/* $Id: errvars-posix.cpp 37233 2011-05-27 13:31:57Z vboxsync $ */
+/** @file
+ * IPRT - Save and Restore Error Variables, POSIX Ring-3.
+ */
+
+/*
+ * 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.
+ *
+ * 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 <netdb.h>
+#include <errno.h>
+
+#include <iprt/err.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include "internal/magics.h"
+
+
+
+RTDECL(PRTERRVARS) RTErrVarsSave(PRTERRVARS pVars)
+{
+ pVars->ai32Vars[0] = RTERRVARS_MAGIC;
+ pVars->ai32Vars[1] = errno;
+ pVars->ai32Vars[2] = h_errno;
+ return pVars;
+}
+
+
+RTDECL(void) RTErrVarsRestore(PCRTERRVARS pVars)
+{
+ AssertReturnVoid(pVars->ai32Vars[0] == RTERRVARS_MAGIC);
+ h_errno = pVars->ai32Vars[2];
+ errno = pVars->ai32Vars[1];
+}
+
+
+RTDECL(bool) RTErrVarsAreEqual(PCRTERRVARS pVars1, PCRTERRVARS pVars2)
+{
+ Assert(pVars1->ai32Vars[0] == RTERRVARS_MAGIC);
+ Assert(pVars2->ai32Vars[0] == RTERRVARS_MAGIC);
+
+ return pVars1->ai32Vars[0] == pVars2->ai32Vars[0]
+ && pVars1->ai32Vars[1] == pVars2->ai32Vars[1]
+ && pVars1->ai32Vars[2] == pVars2->ai32Vars[2];
+}
+
+
+RTDECL(bool) RTErrVarsHaveChanged(PCRTERRVARS pVars)
+{
+ Assert(pVars->ai32Vars[0] == RTERRVARS_MAGIC);
+
+ return pVars->ai32Vars[0] != RTERRVARS_MAGIC
+ || pVars->ai32Vars[1] != errno
+ || pVars->ai32Vars[2] != h_errno;
+}
+
diff --git a/src/VBox/Runtime/r3/posix/fileaio-posix.cpp b/src/VBox/Runtime/r3/posix/fileaio-posix.cpp
index 9628da115..d4302f1a5 100644
--- a/src/VBox/Runtime/r3/posix/fileaio-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/fileaio-posix.cpp
@@ -1,10 +1,10 @@
-/* $Id: fileaio-posix.cpp $ */
+/* $Id: fileaio-posix.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - File async I/O, native implementation for POSIX compliant host platforms.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -406,7 +406,7 @@ DECLINLINE(int) rtFileAioReqPrepareTransfer(RTFILEAIOREQ hReq, RTFILE hFile,
memset(&pReqInt->AioCB, 0, sizeof(struct aiocb));
pReqInt->fFlush = false;
pReqInt->AioCB.aio_lio_opcode = uTransferDirection;
- pReqInt->AioCB.aio_fildes = (int)hFile;
+ pReqInt->AioCB.aio_fildes = RTFileToNative(hFile);
pReqInt->AioCB.aio_offset = off;
pReqInt->AioCB.aio_nbytes = cbTransfer;
pReqInt->AioCB.aio_buf = pvBuf;
@@ -444,7 +444,7 @@ RTDECL(int) RTFileAioReqPrepareFlush(RTFILEAIOREQ hReq, RTFILE hFile, void *pvUs
Assert(hFile != NIL_RTFILE);
pReqInt->fFlush = true;
- pReqInt->AioCB.aio_fildes = (int)hFile;
+ pReqInt->AioCB.aio_fildes = RTFileToNative(hFile);
pReqInt->AioCB.aio_offset = 0;
pReqInt->AioCB.aio_nbytes = 0;
pReqInt->AioCB.aio_buf = NULL;
diff --git a/src/VBox/Runtime/r3/posix/fileio-posix.cpp b/src/VBox/Runtime/r3/posix/fileio-posix.cpp
index 3f0a37cfe..83ac8ab06 100644
--- a/src/VBox/Runtime/r3/posix/fileio-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/fileio-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: fileio-posix.cpp $ */
+/* $Id: fileio-posix.cpp 37679 2011-06-29 08:24:44Z vboxsync $ */
/** @file
* IPRT - File I/O, POSIX, Part 1.
*/
@@ -92,7 +92,7 @@ RTDECL(bool) RTFileExists(const char *pszPath)
}
-RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint32_t fOpen)
+RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint64_t fOpen)
{
/*
* Validate input.
@@ -110,7 +110,7 @@ RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint32_t fOpen)
#ifndef O_NONBLOCK
if (fOpen & RTFILE_O_NON_BLOCK)
{
- AssertMsgFailed(("Invalid parameters! fOpen=%#x\n", fOpen));
+ AssertMsgFailed(("Invalid parameters! fOpen=%#llx\n", fOpen));
return VERR_INVALID_PARAMETER;
}
#endif
@@ -176,7 +176,7 @@ RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint32_t fOpen)
fOpenMode |= fOpen & RTFILE_O_APPEND ? O_APPEND | O_RDWR : O_RDWR;
break;
default:
- AssertMsgFailed(("RTFileOpen received an invalid RW value, fOpen=%#x\n", fOpen));
+ AssertMsgFailed(("RTFileOpen received an invalid RW value, fOpen=%#llx\n", fOpen));
return VERR_INVALID_PARAMETER;
}
@@ -321,9 +321,9 @@ RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint32_t fOpen)
*/
if (iErr == 0)
{
- *pFile = (RTFILE)fh;
- Assert((int)*pFile == fh);
- LogFlow(("RTFileOpen(%p:{%RTfile}, %p:{%s}, %#x): returns %Rrc\n",
+ *pFile = (RTFILE)(uintptr_t)fh;
+ Assert((intptr_t)*pFile == fh);
+ LogFlow(("RTFileOpen(%p:{%RTfile}, %p:{%s}, %#llx): returns %Rrc\n",
pFile, *pFile, pszFilename, pszFilename, fOpen, rc));
return VINF_SUCCESS;
}
@@ -334,7 +334,7 @@ RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint32_t fOpen)
}
-RTR3DECL(int) RTFileOpenBitBucket(PRTFILE phFile, uint32_t fAccess)
+RTR3DECL(int) RTFileOpenBitBucket(PRTFILE phFile, uint64_t fAccess)
{
AssertReturn( fAccess == RTFILE_O_READ
|| fAccess == RTFILE_O_WRITE
@@ -344,11 +344,11 @@ RTR3DECL(int) RTFileOpenBitBucket(PRTFILE phFile, uint32_t fAccess)
}
-RTR3DECL(int) RTFileClose(RTFILE File)
+RTR3DECL(int) RTFileClose(RTFILE hFile)
{
- if (File == NIL_RTFILE)
+ if (hFile == NIL_RTFILE)
return VINF_SUCCESS;
- if (close((int)File) == 0)
+ if (close(RTFileToNative(hFile)) == 0)
return VINF_SUCCESS;
return RTErrConvertFromErrno(errno);
}
@@ -356,8 +356,8 @@ RTR3DECL(int) RTFileClose(RTFILE File)
RTR3DECL(int) RTFileFromNative(PRTFILE pFile, RTHCINTPTR uNative)
{
- if ( uNative < 0
- || (RTFILE)uNative != (RTUINTPTR)uNative)
+ AssertCompile(sizeof(uNative) == sizeof(*pFile));
+ if (uNative < 0)
{
AssertMsgFailed(("%p\n", uNative));
*pFile = NIL_RTFILE;
@@ -368,10 +368,31 @@ RTR3DECL(int) RTFileFromNative(PRTFILE pFile, RTHCINTPTR uNative)
}
-RTR3DECL(RTHCINTPTR) RTFileToNative(RTFILE File)
+RTR3DECL(RTHCINTPTR) RTFileToNative(RTFILE hFile)
{
- AssertReturn(File != NIL_RTFILE, -1);
- return (RTHCINTPTR)File;
+ AssertReturn(hFile != NIL_RTFILE, -1);
+ return (intptr_t)hFile;
+}
+
+
+RTFILE rtFileGetStandard(RTHANDLESTD enmStdHandle)
+{
+ int fd;
+ switch (enmStdHandle)
+ {
+ case RTHANDLESTD_INPUT: fd = 0; break;
+ case RTHANDLESTD_OUTPUT: fd = 1; break;
+ case RTHANDLESTD_ERROR: fd = 2; break;
+ break;
+ default:
+ AssertFailedReturn(NIL_RTFILE);
+ }
+
+ struct stat st;
+ int rc = fstat(fd, &st);
+ if (rc == -1)
+ return NIL_RTFILE;
+ return (RTFILE)(intptr_t)fd;
}
@@ -389,7 +410,7 @@ RTR3DECL(int) RTFileDelete(const char *pszFilename)
}
-RTR3DECL(int) RTFileSeek(RTFILE File, int64_t offSeek, unsigned uMethod, uint64_t *poffActual)
+RTR3DECL(int) RTFileSeek(RTFILE hFile, int64_t offSeek, unsigned uMethod, uint64_t *poffActual)
{
static const unsigned aSeekRecode[] =
{
@@ -416,7 +437,7 @@ RTR3DECL(int) RTFileSeek(RTFILE File, int64_t offSeek, unsigned uMethod, uint64
return VERR_NOT_SUPPORTED;
}
- off_t offCurrent = lseek((int)File, (off_t)offSeek, aSeekRecode[uMethod]);
+ off_t offCurrent = lseek(RTFileToNative(hFile), (off_t)offSeek, aSeekRecode[uMethod]);
if (offCurrent != ~0)
{
if (poffActual)
@@ -427,7 +448,7 @@ RTR3DECL(int) RTFileSeek(RTFILE File, int64_t offSeek, unsigned uMethod, uint64
}
-RTR3DECL(int) RTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcbRead)
+RTR3DECL(int) RTFileRead(RTFILE hFile, void *pvBuf, size_t cbToRead, size_t *pcbRead)
{
if (cbToRead <= 0)
return VINF_SUCCESS;
@@ -435,7 +456,7 @@ RTR3DECL(int) RTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcb
/*
* Attempt read.
*/
- ssize_t cbRead = read((int)File, pvBuf, cbToRead);
+ ssize_t cbRead = read(RTFileToNative(hFile), pvBuf, cbToRead);
if (cbRead >= 0)
{
if (pcbRead)
@@ -446,7 +467,7 @@ RTR3DECL(int) RTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcb
/* Caller expects all to be read. */
while ((ssize_t)cbToRead > cbRead)
{
- ssize_t cbReadPart = read((int)File, (char*)pvBuf + cbRead, cbToRead - cbRead);
+ ssize_t cbReadPart = read(RTFileToNative(hFile), (char*)pvBuf + cbRead, cbToRead - cbRead);
if (cbReadPart <= 0)
{
if (cbReadPart == 0)
@@ -463,7 +484,7 @@ RTR3DECL(int) RTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcb
}
-RTR3DECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
+RTR3DECL(int) RTFileWrite(RTFILE hFile, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
{
if (cbToWrite <= 0)
return VINF_SUCCESS;
@@ -471,7 +492,7 @@ RTR3DECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, siz
/*
* Attempt write.
*/
- ssize_t cbWritten = write((int)File, pvBuf, cbToWrite);
+ ssize_t cbWritten = write(RTFileToNative(hFile), pvBuf, cbToWrite);
if (cbWritten >= 0)
{
if (pcbWritten)
@@ -482,7 +503,7 @@ RTR3DECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, siz
/* Caller expects all to be write. */
while ((ssize_t)cbToWrite > cbWritten)
{
- ssize_t cbWrittenPart = write((int)File, (const char *)pvBuf + cbWritten, cbToWrite - cbWritten);
+ ssize_t cbWrittenPart = write(RTFileToNative(hFile), (const char *)pvBuf + cbWritten, cbToWrite - cbWritten);
if (cbWrittenPart <= 0)
return RTErrConvertFromErrno(errno);
cbWritten += cbWrittenPart;
@@ -494,7 +515,7 @@ RTR3DECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, siz
}
-RTR3DECL(int) RTFileSetSize(RTFILE File, uint64_t cbSize)
+RTR3DECL(int) RTFileSetSize(RTFILE hFile, uint64_t cbSize)
{
/*
* Validate offset.
@@ -507,23 +528,23 @@ RTR3DECL(int) RTFileSetSize(RTFILE File, uint64_t cbSize)
}
#if defined(_MSC_VER) || (defined(RT_OS_OS2) && (!defined(__INNOTEK_LIBC__) || __INNOTEK_LIBC__ < 0x006))
- if (chsize((int)File, (off_t)cbSize) == 0)
+ if (chsize(RTFileToNative(hFile), (off_t)cbSize) == 0)
#else
/* This relies on a non-standard feature of FreeBSD, Linux, and OS/2
* LIBC v0.6 and higher. (SuS doesn't define ftruncate() and size bigger
* than the file.)
*/
- if (ftruncate((int)File, (off_t)cbSize) == 0)
+ if (ftruncate(RTFileToNative(hFile), (off_t)cbSize) == 0)
#endif
return VINF_SUCCESS;
return RTErrConvertFromErrno(errno);
}
-RTR3DECL(int) RTFileGetSize(RTFILE File, uint64_t *pcbSize)
+RTR3DECL(int) RTFileGetSize(RTFILE hFile, uint64_t *pcbSize)
{
struct stat st;
- if (!fstat((int)File, &st))
+ if (!fstat(RTFileToNative(hFile), &st))
{
*pcbSize = st.st_size;
return VINF_SUCCESS;
@@ -532,21 +553,13 @@ RTR3DECL(int) RTFileGetSize(RTFILE File, uint64_t *pcbSize)
}
-/**
- * Determine the maximum file size.
- *
- * @returns IPRT status code.
- * @param File Handle to the file.
- * @param pcbMax Where to store the max file size.
- * @see RTFileGetMaxSize.
- */
-RTR3DECL(int) RTFileGetMaxSizeEx(RTFILE File, PRTFOFF pcbMax)
+RTR3DECL(int) RTFileGetMaxSizeEx(RTFILE hFile, PRTFOFF pcbMax)
{
/*
* Save the current location
*/
uint64_t offOld;
- int rc = RTFileSeek(File, 0, RTFILE_SEEK_CURRENT, &offOld);
+ int rc = RTFileSeek(hFile, 0, RTFILE_SEEK_CURRENT, &offOld);
if (RT_FAILURE(rc))
return rc;
@@ -566,10 +579,10 @@ RTR3DECL(int) RTFileGetMaxSizeEx(RTFILE File, PRTFOFF pcbMax)
{
if (pcbMax)
*pcbMax = offLow;
- return RTFileSeek(File, offOld, RTFILE_SEEK_BEGIN, NULL);
+ return RTFileSeek(hFile, offOld, RTFILE_SEEK_BEGIN, NULL);
}
- rc = RTFileSeek(File, offLow + cbInterval, RTFILE_SEEK_BEGIN, NULL);
+ rc = RTFileSeek(hFile, offLow + cbInterval, RTFILE_SEEK_BEGIN, NULL);
if (RT_FAILURE(rc))
offHigh = offLow + cbInterval;
else
@@ -578,11 +591,11 @@ RTR3DECL(int) RTFileGetMaxSizeEx(RTFILE File, PRTFOFF pcbMax)
}
-RTR3DECL(bool) RTFileIsValid(RTFILE File)
+RTR3DECL(bool) RTFileIsValid(RTFILE hFile)
{
- if (File != NIL_RTFILE)
+ if (hFile != NIL_RTFILE)
{
- int fFlags = fcntl(File, F_GETFD);
+ int fFlags = fcntl(RTFileToNative(hFile), F_GETFD);
if (fFlags >= 0)
return true;
}
@@ -590,24 +603,24 @@ RTR3DECL(bool) RTFileIsValid(RTFILE File)
}
-RTR3DECL(int) RTFileFlush(RTFILE File)
+RTR3DECL(int) RTFileFlush(RTFILE hFile)
{
- if (fsync((int)File))
+ if (fsync(RTFileToNative(hFile)))
return RTErrConvertFromErrno(errno);
return VINF_SUCCESS;
}
-RTR3DECL(int) RTFileIoCtl(RTFILE File, unsigned long ulRequest, void *pvData, unsigned cbData, int *piRet)
+RTR3DECL(int) RTFileIoCtl(RTFILE hFile, unsigned long ulRequest, void *pvData, unsigned cbData, int *piRet)
{
- int rc = ioctl((int)File, ulRequest, pvData);
+ int rc = ioctl(RTFileToNative(hFile), ulRequest, pvData);
if (piRet)
*piRet = rc;
return rc >= 0 ? VINF_SUCCESS : RTErrConvertFromErrno(errno);
}
-RTR3DECL(int) RTFileSetMode(RTFILE File, RTFMODE fMode)
+RTR3DECL(int) RTFileSetMode(RTFILE hFile, RTFMODE fMode)
{
/*
* Normalize the mode and call the API.
@@ -616,10 +629,10 @@ RTR3DECL(int) RTFileSetMode(RTFILE File, RTFMODE fMode)
if (!rtFsModeIsValid(fMode))
return VERR_INVALID_PARAMETER;
- if (fchmod((int)File, fMode & RTFS_UNIX_MASK))
+ if (fchmod(RTFileToNative(hFile), fMode & RTFS_UNIX_MASK))
{
int rc = RTErrConvertFromErrno(errno);
- Log(("RTFileSetMode(%RTfile,%RTfmode): returns %Rrc\n", File, fMode, rc));
+ Log(("RTFileSetMode(%RTfile,%RTfmode): returns %Rrc\n", hFile, fMode, rc));
return rc;
}
return VINF_SUCCESS;
diff --git a/src/VBox/Runtime/r3/posix/fileio2-posix.cpp b/src/VBox/Runtime/r3/posix/fileio2-posix.cpp
index 5808300b2..6b6dee219 100644
--- a/src/VBox/Runtime/r3/posix/fileio2-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/fileio2-posix.cpp
@@ -1,10 +1,10 @@
-/* $Id: fileio2-posix.cpp $ */
+/* $Id: fileio2-posix.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - File I/O, POSIX, Part 2.
*/
/*
- * 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;
@@ -68,21 +68,13 @@ extern int futimes(int __fd, __const struct timeval __tvp[2]) __THROW;
-RTR3DECL(int) RTFileQueryInfo(RTFILE File, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
+RTR3DECL(int) RTFileQueryInfo(RTFILE hFile, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
{
/*
* Validate input.
*/
- if (File == NIL_RTFILE)
- {
- AssertMsgFailed(("Invalid File=%RTfile\n", File));
- return VERR_INVALID_PARAMETER;
- }
- if (!pObjInfo)
- {
- AssertMsgFailed(("Invalid pObjInfo=%p\n", pObjInfo));
- return VERR_INVALID_PARAMETER;
- }
+ AssertReturn(hFile != NIL_RTFILE, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pObjInfo, VERR_INVALID_PARAMETER);
if ( enmAdditionalAttribs < RTFSOBJATTRADD_NOTHING
|| enmAdditionalAttribs > RTFSOBJATTRADD_LAST)
{
@@ -94,10 +86,10 @@ RTR3DECL(int) RTFileQueryInfo(RTFILE File, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD
* Query file info.
*/
struct stat Stat;
- if (fstat((int)File, &Stat))
+ if (fstat(RTFileToNative(hFile), &Stat))
{
int rc = RTErrConvertFromErrno(errno);
- Log(("RTFileQueryInfo(%RTfile,,%d): returns %Rrc\n", File, enmAdditionalAttribs, rc));
+ Log(("RTFileQueryInfo(%RTfile,,%d): returns %Rrc\n", hFile, enmAdditionalAttribs, rc));
return rc;
}
@@ -134,12 +126,12 @@ RTR3DECL(int) RTFileQueryInfo(RTFILE File, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD
return VERR_INTERNAL_ERROR;
}
- LogFlow(("RTFileQueryInfo(%RTfile,,%d): returns VINF_SUCCESS\n", File, enmAdditionalAttribs));
+ LogFlow(("RTFileQueryInfo(%RTfile,,%d): returns VINF_SUCCESS\n", hFile, enmAdditionalAttribs));
return VINF_SUCCESS;
}
-RTR3DECL(int) RTFileSetTimes(RTFILE File, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
+RTR3DECL(int) RTFileSetTimes(RTFILE hFile, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
{
/*
@@ -162,17 +154,17 @@ RTR3DECL(int) RTFileSetTimes(RTFILE File, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC
else
{
RTFSOBJINFO ObjInfo;
- int rc = RTFileQueryInfo(File, &ObjInfo, RTFSOBJATTRADD_UNIX);
+ int rc = RTFileQueryInfo(hFile, &ObjInfo, RTFSOBJATTRADD_UNIX);
if (RT_FAILURE(rc))
return rc;
RTTimeSpecGetTimeval(pAccessTime ? pAccessTime : &ObjInfo.AccessTime, &aTimevals[0]);
RTTimeSpecGetTimeval(pModificationTime ? pModificationTime : &ObjInfo.ModificationTime, &aTimevals[1]);
}
- if (futimes((int)File, aTimevals))
+ if (futimes(RTFileToNative(hFile), aTimevals))
{
int rc = RTErrConvertFromErrno(errno);
- Log(("RTFileSetTimes(%RTfile,%p,%p,,): returns %Rrc\n", File, pAccessTime, pModificationTime, rc));
+ Log(("RTFileSetTimes(%RTfile,%p,%p,,): returns %Rrc\n", hFile, pAccessTime, pModificationTime, rc));
return rc;
}
return VINF_SUCCESS;
diff --git a/src/VBox/Runtime/r3/posix/filelock-posix.cpp b/src/VBox/Runtime/r3/posix/filelock-posix.cpp
index 261c41a6f..9b1f3630f 100644
--- a/src/VBox/Runtime/r3/posix/filelock-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/filelock-posix.cpp
@@ -1,10 +1,10 @@
-/* $Id: filelock-posix.cpp $ */
+/* $Id: filelock-posix.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - File Locking, POSIX.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -49,7 +49,7 @@
-RTR3DECL(int) RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock)
+RTR3DECL(int) RTFileLock(RTFILE hFile, unsigned fLock, int64_t offLock, uint64_t cbLock)
{
Assert(offLock >= 0);
@@ -82,7 +82,7 @@ RTR3DECL(int) RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t
fl.l_pid = 0;
Assert(RTFILE_LOCK_WAIT);
- if (fcntl(File, (fLock & RTFILE_LOCK_WAIT) ? F_SETLKW : F_SETLK, &fl) >= 0)
+ if (fcntl(RTFileToNative(hFile), (fLock & RTFILE_LOCK_WAIT) ? F_SETLKW : F_SETLK, &fl) >= 0)
return VINF_SUCCESS;
int iErr = errno;
@@ -94,14 +94,14 @@ RTR3DECL(int) RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t
}
-RTR3DECL(int) RTFileChangeLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock)
+RTR3DECL(int) RTFileChangeLock(RTFILE hFile, unsigned fLock, int64_t offLock, uint64_t cbLock)
{
/** @todo We never returns VERR_FILE_NOT_LOCKED for now. */
- return RTFileLock(File, fLock, offLock, cbLock);
+ return RTFileLock(hFile, fLock, offLock, cbLock);
}
-RTR3DECL(int) RTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock)
+RTR3DECL(int) RTFileUnlock(RTFILE hFile, int64_t offLock, uint64_t cbLock)
{
Assert(offLock >= 0);
@@ -125,7 +125,7 @@ RTR3DECL(int) RTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock)
fl.l_len = (off_t)cbLock;
fl.l_pid = 0;
- if (fcntl(File, F_SETLK, &fl) >= 0)
+ if (fcntl(RTFileToNative(hFile), F_SETLK, &fl) >= 0)
return VINF_SUCCESS;
/* @todo check error codes for non existing lock. */
diff --git a/src/VBox/Runtime/r3/posix/fs-posix.cpp b/src/VBox/Runtime/r3/posix/fs-posix.cpp
index 6354ebeb2..2dcd9ffe3 100644
--- a/src/VBox/Runtime/r3/posix/fs-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/fs-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: fs-posix.cpp $ */
+/* $Id: fs-posix.cpp 35015 2010-12-13 14:36:50Z vboxsync $ */
/** @file
* IPRT - File System, Linux.
*/
diff --git a/src/VBox/Runtime/r3/posix/fs2-posix.cpp b/src/VBox/Runtime/r3/posix/fs2-posix.cpp
index 38dafcf17..63da69235 100644
--- a/src/VBox/Runtime/r3/posix/fs2-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/fs2-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: fs2-posix.cpp $ */
+/* $Id: fs2-posix.cpp 34015 2010-11-12 00:15:05Z vboxsync $ */
/** @file
* IPRT - File System Helpers, POSIX, Part 2.
*/
diff --git a/src/VBox/Runtime/r3/posix/fs3-posix.cpp b/src/VBox/Runtime/r3/posix/fs3-posix.cpp
index 94c3fb5a3..32882521b 100644
--- a/src/VBox/Runtime/r3/posix/fs3-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/fs3-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: fs3-posix.cpp $ */
+/* $Id: fs3-posix.cpp 34015 2010-11-12 00:15:05Z vboxsync $ */
/** @file
* IPRT - File System Helpers, POSIX, Part 3.
*/
diff --git a/src/VBox/Runtime/r3/posix/ldrNative-posix.cpp b/src/VBox/Runtime/r3/posix/ldrNative-posix.cpp
index 61ce35783..62cc939d8 100644
--- a/src/VBox/Runtime/r3/posix/ldrNative-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/ldrNative-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: ldrNative-posix.cpp $ */
+/* $Id: ldrNative-posix.cpp 35191 2010-12-16 15:25:20Z vboxsync $ */
/** @file
* IPRT - Binary Image Loader, POSIX native.
*/
diff --git a/src/VBox/Runtime/r3/posix/path-posix.cpp b/src/VBox/Runtime/r3/posix/path-posix.cpp
index fc3b2cc8a..33fbd9079 100644
--- a/src/VBox/Runtime/r3/posix/path-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/path-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: path-posix.cpp $ */
+/* $Id: path-posix.cpp 36906 2011-05-01 16:35:12Z vboxsync $ */
/** @file
* IPRT - Path Manipulation, POSIX, Part 1.
*/
@@ -335,10 +335,10 @@ RTR3DECL(int) RTPathSetMode(const char *pszPath, RTFMODE fMode)
static bool rtPathSame(const char *pszNativeSrc, const char *pszNativeDst)
{
struct stat SrcStat;
- if (stat(pszNativeSrc, &SrcStat))
+ if (lstat(pszNativeSrc, &SrcStat))
return false;
struct stat DstStat;
- if (stat(pszNativeDst, &DstStat))
+ if (lstat(pszNativeDst, &DstStat))
return false;
Assert(SrcStat.st_dev && DstStat.st_dev);
Assert(SrcStat.st_ino && DstStat.st_ino);
@@ -380,11 +380,11 @@ DECLHIDDEN(int) rtPathPosixRename(const char *pszSrc, const char *pszDst, unsign
* We have to check this first to avoid getting errnous VERR_ALREADY_EXISTS
* errors from the next step.
*
- * There are race conditions here (perhaps unlikely ones but still), but I'm
+ * There are race conditions here (perhaps unlikely ones, but still), but I'm
* afraid there is little with can do to fix that.
*/
struct stat SrcStat;
- if (stat(pszNativeSrc, &SrcStat))
+ if (lstat(pszNativeSrc, &SrcStat))
rc = RTErrConvertFromErrno(errno);
else if (!fFileType)
rc = VINF_SUCCESS;
@@ -402,7 +402,7 @@ DECLHIDDEN(int) rtPathPosixRename(const char *pszSrc, const char *pszDst, unsign
* Another race condition btw.
*/
struct stat DstStat;
- if (stat(pszNativeDst, &DstStat))
+ if (lstat(pszNativeDst, &DstStat))
rc = errno == ENOENT ? VINF_SUCCESS : RTErrConvertFromErrno(errno);
else
{
@@ -445,7 +445,7 @@ DECLHIDDEN(int) rtPathPosixRename(const char *pszSrc, const char *pszDst, unsign
}
else
{
- if (stat(pszNativeDst, &DstStat))
+ if (lstat(pszNativeDst, &DstStat))
rc = errno != ENOENT ? RTErrConvertFromErrno(errno) : VINF_SUCCESS;
else if (S_ISDIR(DstStat.st_mode))
rc = VERR_ALREADY_EXISTS;
diff --git a/src/VBox/Runtime/r3/posix/path2-posix.cpp b/src/VBox/Runtime/r3/posix/path2-posix.cpp
index abc2ce29a..e4a0c7b9c 100644
--- a/src/VBox/Runtime/r3/posix/path2-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/path2-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: path2-posix.cpp $ */
+/* $Id: path2-posix.cpp 34230 2010-11-22 10:06:48Z vboxsync $ */
/** @file
* IPRT - Path Manipulation, POSIX, Part 2 - RTPathQueryInfo.
*/
diff --git a/src/VBox/Runtime/r3/posix/pathhost-posix.cpp b/src/VBox/Runtime/r3/posix/pathhost-posix.cpp
index 39a072441..a5af14150 100644
--- a/src/VBox/Runtime/r3/posix/pathhost-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/pathhost-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: pathhost-posix.cpp $ */
+/* $Id: pathhost-posix.cpp 37563 2011-06-20 19:47:47Z vboxsync $ */
/** @file
* IPRT - Path Conversions, POSIX.
*/
@@ -31,6 +31,7 @@
#define LOG_GROUP RTLOGGROUP_PATH
#include "internal/iprt.h"
#include "internal/path.h"
+#include "internal/string.h"
#include "internal/thread.h"
#include <iprt/env.h>
diff --git a/src/VBox/Runtime/r3/posix/pipe-posix.cpp b/src/VBox/Runtime/r3/posix/pipe-posix.cpp
index e225b1b1f..868849340 100644
--- a/src/VBox/Runtime/r3/posix/pipe-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/pipe-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: pipe-posix.cpp $ */
+/* $Id: pipe-posix.cpp 33104 2010-10-13 12:46:59Z vboxsync $ */
/** @file
* IPRT - Anonymous Pipes, POSIX Implementation.
*/
diff --git a/src/VBox/Runtime/r3/posix/poll-posix.cpp b/src/VBox/Runtime/r3/posix/poll-posix.cpp
index ff1249684..14be608c0 100644
--- a/src/VBox/Runtime/r3/posix/poll-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/poll-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: poll-posix.cpp $ */
+/* $Id: poll-posix.cpp 31453 2010-08-08 13:30:35Z vboxsync $ */
/** @file
* IPRT - Polling I/O Handles, POSIX Implementation.
*/
diff --git a/src/VBox/Runtime/r3/posix/process-creation-posix.cpp b/src/VBox/Runtime/r3/posix/process-creation-posix.cpp
index 6690baf58..ccbba43b6 100644
--- a/src/VBox/Runtime/r3/posix/process-creation-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/process-creation-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: process-creation-posix.cpp $ */
+/* $Id: process-creation-posix.cpp 37499 2011-06-16 14:46:47Z vboxsync $ */
/** @file
* IPRT - Process Creation, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/process-posix.cpp b/src/VBox/Runtime/r3/posix/process-posix.cpp
index 6fff7b0c9..993bff093 100644
--- a/src/VBox/Runtime/r3/posix/process-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/process-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: process-posix.cpp $ */
+/* $Id: process-posix.cpp 33602 2010-10-29 12:39:54Z vboxsync $ */
/** @file
* IPRT - Process, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/rand-posix.cpp b/src/VBox/Runtime/r3/posix/rand-posix.cpp
index 44870e5be..8e02b0a60 100644
--- a/src/VBox/Runtime/r3/posix/rand-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/rand-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: rand-posix.cpp $ */
+/* $Id: rand-posix.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* IPRT - Random Numbers and Byte Streams, POSIX.
*/
@@ -78,7 +78,7 @@ static DECLCALLBACK(int) rtRandAdvPosixDestroy(PRTRANDINT pThis)
{
pThis->u32Magic = ~RTRANDINT_MAGIC;
int fd = pThis->u.File.hFile;
- pThis->u.File.hFile = NIL_RTFILE;
+ pThis->u.File.hFile = -1;
RTMemFree(pThis);
close(fd);
return VINF_SUCCESS;
diff --git a/src/VBox/Runtime/r3/posix/rtmempage-exec-mmap-heap-posix.cpp b/src/VBox/Runtime/r3/posix/rtmempage-exec-mmap-heap-posix.cpp
index 6cc6f888a..4977aab03 100644
--- a/src/VBox/Runtime/r3/posix/rtmempage-exec-mmap-heap-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/rtmempage-exec-mmap-heap-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: rtmempage-exec-mmap-heap-posix.cpp $ */
+/* $Id: rtmempage-exec-mmap-heap-posix.cpp 33279 2010-10-20 21:37:58Z vboxsync $ */
/** @file
* IPRT - RTMemPage*, POSIX with heap.
*/
diff --git a/src/VBox/Runtime/r3/posix/rtmempage-exec-mmap-posix.cpp b/src/VBox/Runtime/r3/posix/rtmempage-exec-mmap-posix.cpp
index 1b2466953..498402d8d 100644
--- a/src/VBox/Runtime/r3/posix/rtmempage-exec-mmap-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/rtmempage-exec-mmap-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: rtmempage-exec-mmap-posix.cpp $ */
+/* $Id: rtmempage-exec-mmap-posix.cpp 33676 2010-11-02 09:48:24Z vboxsync $ */
/** @file
* IPRT - RTMemPage*, POSIX with mmap only.
*/
diff --git a/src/VBox/Runtime/r3/posix/sched-posix.cpp b/src/VBox/Runtime/r3/posix/sched-posix.cpp
index fbc607d02..bf5cde765 100644
--- a/src/VBox/Runtime/r3/posix/sched-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/sched-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: sched-posix.cpp $ */
+/* $Id: sched-posix.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Scheduling, POSIX.
*/
@@ -508,7 +508,7 @@ static void *rtSchedNativeProberThread(void *pvUser)
* @returns iprt status code.
* @param enmType The thread type to be assumed for the current thread.
*/
-int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
{
Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
@@ -643,7 +643,7 @@ static void *rtSchedNativeValidatorThread(void *pvUser)
* @returns iprt status code.
* @param enmPriority The priority to validate and set.
*/
-int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
+DECLHIDDEN(int) rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
{
Assert(enmPriority > RTPROCPRIORITY_INVALID && enmPriority < RTPROCPRIORITY_LAST);
@@ -739,7 +739,7 @@ int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
* @param Thread The thread in question.
* @param enmType The thread type.
*/
-int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
{
Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
Assert(enmType == g_pProcessPriority->paTypes[enmType].enmType);
diff --git a/src/VBox/Runtime/r3/posix/semevent-posix.cpp b/src/VBox/Runtime/r3/posix/semevent-posix.cpp
index ceeab84e6..501ae683c 100644
--- a/src/VBox/Runtime/r3/posix/semevent-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/semevent-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: semevent-posix.cpp $ */
+/* $Id: semevent-posix.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Event Semaphore, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp b/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp
index 0fad8eeec..efe9bdc7f 100644
--- a/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: semeventmulti-posix.cpp $ */
+/* $Id: semeventmulti-posix.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Multiple Release Event Semaphore, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/semmutex-posix.cpp b/src/VBox/Runtime/r3/posix/semmutex-posix.cpp
index e1e82558e..ea845d2ad 100644
--- a/src/VBox/Runtime/r3/posix/semmutex-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/semmutex-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: semmutex-posix.cpp $ */
+/* $Id: semmutex-posix.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Mutex Semaphore, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/semrw-posix.cpp b/src/VBox/Runtime/r3/posix/semrw-posix.cpp
index 86473b522..edca8d669 100644
--- a/src/VBox/Runtime/r3/posix/semrw-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/semrw-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: semrw-posix.cpp $ */
+/* $Id: semrw-posix.cpp 30111 2010-06-09 12:14:59Z vboxsync $ */
/** @file
* IPRT - Read-Write Semaphore, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/symlink-posix.cpp b/src/VBox/Runtime/r3/posix/symlink-posix.cpp
index 61f7c5973..e4c00c0f8 100644
--- a/src/VBox/Runtime/r3/posix/symlink-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/symlink-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: symlink-posix.cpp $ */
+/* $Id: symlink-posix.cpp 33426 2010-10-25 14:32:38Z vboxsync $ */
/** @file
* IPRT - Symbolic Links, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/thread-posix.cpp b/src/VBox/Runtime/r3/posix/thread-posix.cpp
index c7158f4cb..316894532 100644
--- a/src/VBox/Runtime/r3/posix/thread-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/thread-posix.cpp
@@ -1,10 +1,10 @@
-/* $Id: thread-posix.cpp $ */
+/* $Id: thread-posix.cpp 37733 2011-07-01 15:41:37Z vboxsync $ */
/** @file
* IPRT - Threads, POSIX.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -52,9 +52,6 @@
#include <iprt/log.h>
#include <iprt/assert.h>
#include <iprt/asm.h>
-#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
-# include <iprt/asm-amd64-x86.h>
-#endif
#include <iprt/err.h>
#include <iprt/string.h>
#include "internal/thread.h"
@@ -89,7 +86,7 @@ static void rtThreadKeyDestruct(void *pvValue);
static void rtThreadPosixPokeSignal(int iSignal);
-int rtThreadNativeInit(void)
+DECLHIDDEN(int) rtThreadNativeInit(void)
{
/*
* Allocate the TLS (key in posix terms) where we store the pointer to
@@ -188,7 +185,7 @@ static void rtThreadPosixPokeSignal(int iSignal)
*
* @param pThread Pointer to the thread structure.
*/
-int rtThreadNativeAdopt(PRTTHREADINT pThread)
+DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread)
{
/*
* Block SIGALRM - required for timer-posix.cpp.
@@ -211,7 +208,7 @@ int rtThreadNativeAdopt(PRTTHREADINT pThread)
}
-void rtThreadNativeDestroy(PRTTHREADINT pThread)
+DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread)
{
if (pThread == (PRTTHREADINT)pthread_getspecific(g_SelfKey))
pthread_setspecific(g_SelfKey, NULL);
@@ -263,7 +260,7 @@ static void *rtThreadNativeMain(void *pvArgs)
}
-int rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
{
/*
* Set the default stack size.
@@ -314,89 +311,6 @@ RTDECL(RTTHREAD) RTThreadSelf(void)
}
-RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
-{
- return (RTNATIVETHREAD)pthread_self();
-}
-
-
-RTDECL(int) RTThreadSleep(RTMSINTERVAL cMillies)
-{
- LogFlow(("RTThreadSleep: cMillies=%d\n", cMillies));
- if (!cMillies)
- {
- /* pthread_yield() isn't part of SuS, thus this fun. */
-#ifdef RT_OS_DARWIN
- pthread_yield_np();
-#elif defined(RT_OS_FREEBSD) /* void pthread_yield */
- pthread_yield();
-#elif defined(RT_OS_SOLARIS)
- sched_yield();
-#else
- if (!pthread_yield())
-#endif
- {
- LogFlow(("RTThreadSleep: returning %Rrc (cMillies=%d)\n", VINF_SUCCESS, cMillies));
- return VINF_SUCCESS;
- }
- }
- else
- {
- struct timespec ts;
- struct timespec tsrem = {0,0};
-
- ts.tv_nsec = (cMillies % 1000) * 1000000;
- ts.tv_sec = cMillies / 1000;
- if (!nanosleep(&ts, &tsrem))
- {
- LogFlow(("RTThreadSleep: returning %Rrc (cMillies=%d)\n", VINF_SUCCESS, cMillies));
- return VINF_SUCCESS;
- }
- }
-
- int rc = RTErrConvertFromErrno(errno);
- LogFlow(("RTThreadSleep: returning %Rrc (cMillies=%d)\n", rc, cMillies));
- return rc;
-}
-
-
-RTDECL(bool) RTThreadYield(void)
-{
-#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
- uint64_t u64TS = ASMReadTSC();
-#endif
-#ifdef RT_OS_DARWIN
- pthread_yield_np();
-#elif defined(RT_OS_SOLARIS)
- sched_yield();
-#else
- pthread_yield();
-#endif
-#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
- u64TS = ASMReadTSC() - u64TS;
- bool fRc = u64TS > 1500;
- LogFlow(("RTThreadYield: returning %d (%llu ticks)\n", fRc, u64TS));
-#else
- bool fRc = true; /* PORTME: Add heuristics for determining whether the cpus was yielded. */
-#endif
- return fRc;
-}
-
-
-RTR3DECL(uint64_t) RTThreadGetAffinity(void)
-{
- return 1;
-}
-
-
-RTR3DECL(int) RTThreadSetAffinity(uint64_t u64Mask)
-{
- if (u64Mask != 1)
- return VERR_INVALID_PARAMETER;
- return VINF_SUCCESS;
-}
-
-
#ifdef RTTHREAD_POSIX_WITH_POKE
RTDECL(int) RTThreadPoke(RTTHREAD hThread)
{
@@ -432,6 +346,7 @@ RTR3DECL(int) RTThreadGetExecutionTimeMilli(uint64_t *pKernelTime, uint64_t *pUs
return VINF_SUCCESS;
#elif defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
+ /* on Linux, getrusage(RUSAGE_THREAD, ...) is available since 2.6.26 */
struct timespec ts;
int rc = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
if (rc)
diff --git a/src/VBox/Runtime/r3/posix/thread2-posix.cpp b/src/VBox/Runtime/r3/posix/thread2-posix.cpp
new file mode 100644
index 000000000..2a8f5e8b7
--- /dev/null
+++ b/src/VBox/Runtime/r3/posix/thread2-posix.cpp
@@ -0,0 +1,116 @@
+/* $Id: thread2-posix.cpp 37733 2011-07-01 15:41:37Z vboxsync $ */
+/** @file
+ * IPRT - Threads part 2, POSIX.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 *
+*******************************************************************************/
+#define LOG_GROUP RTLOGGROUP_THREAD
+#include <errno.h>
+#include <pthread.h>
+#include <unistd.h>
+#if defined(RT_OS_SOLARIS)
+# include <sched.h>
+#endif
+
+#include <iprt/thread.h>
+#include <iprt/log.h>
+#include <iprt/asm.h>
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+# include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/err.h>
+#include "internal/thread.h"
+
+
+RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
+{
+ return (RTNATIVETHREAD)pthread_self();
+}
+
+
+RTDECL(int) RTThreadSleep(RTMSINTERVAL cMillies)
+{
+ LogFlow(("RTThreadSleep: cMillies=%d\n", cMillies));
+ if (!cMillies)
+ {
+ /* pthread_yield() isn't part of SuS, thus this fun. */
+#ifdef RT_OS_DARWIN
+ pthread_yield_np();
+#elif defined(RT_OS_FREEBSD) /* void pthread_yield */
+ pthread_yield();
+#elif defined(RT_OS_SOLARIS)
+ sched_yield();
+#else
+ if (!pthread_yield())
+#endif
+ {
+ LogFlow(("RTThreadSleep: returning %Rrc (cMillies=%d)\n", VINF_SUCCESS, cMillies));
+ return VINF_SUCCESS;
+ }
+ }
+ else
+ {
+ struct timespec ts;
+ struct timespec tsrem = {0,0};
+
+ ts.tv_nsec = (cMillies % 1000) * 1000000;
+ ts.tv_sec = cMillies / 1000;
+ if (!nanosleep(&ts, &tsrem))
+ {
+ LogFlow(("RTThreadSleep: returning %Rrc (cMillies=%d)\n", VINF_SUCCESS, cMillies));
+ return VINF_SUCCESS;
+ }
+ }
+
+ int rc = RTErrConvertFromErrno(errno);
+ LogFlow(("RTThreadSleep: returning %Rrc (cMillies=%d)\n", rc, cMillies));
+ return rc;
+}
+
+
+RTDECL(bool) RTThreadYield(void)
+{
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+ uint64_t u64TS = ASMReadTSC();
+#endif
+#ifdef RT_OS_DARWIN
+ pthread_yield_np();
+#elif defined(RT_OS_SOLARIS)
+ sched_yield();
+#else
+ pthread_yield();
+#endif
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+ u64TS = ASMReadTSC() - u64TS;
+ bool fRc = u64TS > 1500;
+ LogFlow(("RTThreadYield: returning %d (%llu ticks)\n", fRc, u64TS));
+#else
+ bool fRc = true; /* PORTME: Add heuristics for determining whether the cpus was yielded. */
+#endif
+ return fRc;
+}
+
diff --git a/src/VBox/Runtime/r3/posix/time-posix.cpp b/src/VBox/Runtime/r3/posix/time-posix.cpp
index bdb3dcb72..179911465 100644
--- a/src/VBox/Runtime/r3/posix/time-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/time-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: time-posix.cpp $ */
+/* $Id: time-posix.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Time, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/timer-posix.cpp b/src/VBox/Runtime/r3/posix/timer-posix.cpp
index 3f851e53b..e3644e1e2 100644
--- a/src/VBox/Runtime/r3/posix/timer-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/timer-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: timer-posix.cpp $ */
+/* $Id: timer-posix.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Timer, POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/tls-posix.cpp b/src/VBox/Runtime/r3/posix/tls-posix.cpp
index c8005a59f..17dd255c5 100644
--- a/src/VBox/Runtime/r3/posix/tls-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/tls-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: tls-posix.cpp $ */
+/* $Id: tls-posix.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Thread Local Storage (TLS), POSIX.
*/
diff --git a/src/VBox/Runtime/r3/posix/utf8-posix.cpp b/src/VBox/Runtime/r3/posix/utf8-posix.cpp
index a8a7de617..1c72c4390 100644
--- a/src/VBox/Runtime/r3/posix/utf8-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/utf8-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: utf8-posix.cpp $ */
+/* $Id: utf8-posix.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - UTF-8 helpers, POSIX.
*/
@@ -56,7 +56,7 @@ AssertCompile(sizeof(iconv_t) <= sizeof(void *));
*
* @returns Pointer to read-only string with the codeset name.
*/
-const char *rtStrGetLocaleCodeset(void)
+DECLHIDDEN(const char *) rtStrGetLocaleCodeset(void)
{
return nl_langinfo(CODESET);
}
@@ -69,7 +69,7 @@ const char *rtStrGetLocaleCodeset(void)
*
* @param pThread The thread in question.
*/
-void rtStrIconvCacheInit(PRTTHREADINT pThread)
+DECLHIDDEN(void) rtStrIconvCacheInit(PRTTHREADINT pThread)
{
for (size_t i = 0; i < RT_ELEMENTS(pThread->ahIconvs); i++)
pThread->ahIconvs[i] = (iconv_t)-1;
@@ -80,7 +80,7 @@ void rtStrIconvCacheInit(PRTTHREADINT pThread)
*
* @param pThread The thread in question.
*/
-void rtStrIconvCacheDestroy(PRTTHREADINT pThread)
+DECLHIDDEN(void) rtStrIconvCacheDestroy(PRTTHREADINT pThread)
{
for (size_t i = 0; i < RT_ELEMENTS(pThread->ahIconvs); i++)
{
@@ -408,9 +408,9 @@ DECLINLINE(int) rtStrConvertWrapper(const char *pchInput, size_t cchInput, const
* @param cFactor Input vs. output size factor.
* @param enmCacheIdx The iconv cache index.
*/
-int rtStrConvert(const char *pchInput, size_t cchInput, const char *pszInputCS,
- char **ppszOutput, size_t cbOutput, const char *pszOutputCS,
- unsigned cFactor, RTSTRICONV enmCacheIdx)
+DECLHIDDEN(int) rtStrConvert(const char *pchInput, size_t cchInput, const char *pszInputCS,
+ char **ppszOutput, size_t cbOutput, const char *pszOutputCS,
+ unsigned cFactor, RTSTRICONV enmCacheIdx)
{
Assert(enmCacheIdx >= 0 && enmCacheIdx < RTSTRICONV_END);
return rtStrConvertWrapper(pchInput, cchInput, pszInputCS,
diff --git a/src/VBox/Runtime/r3/process.cpp b/src/VBox/Runtime/r3/process.cpp
index 7be307f32..73607065f 100644
--- a/src/VBox/Runtime/r3/process.cpp
+++ b/src/VBox/Runtime/r3/process.cpp
@@ -1,4 +1,4 @@
-/* $Id: process.cpp $ */
+/* $Id: process.cpp 33806 2010-11-05 17:20:15Z vboxsync $ */
/** @file
* IPRT - Process, Common.
*/
diff --git a/src/VBox/Runtime/r3/socket.cpp b/src/VBox/Runtime/r3/socket.cpp
index b989e28cf..e09ead6df 100644
--- a/src/VBox/Runtime/r3/socket.cpp
+++ b/src/VBox/Runtime/r3/socket.cpp
@@ -1,10 +1,10 @@
-/* $Id: socket.cpp $ */
+/* $Id: socket.cpp 37196 2011-05-24 14:50:05Z vboxsync $ */
/** @file
* IPRT - Network Sockets.
*/
/*
- * 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;
@@ -220,6 +220,83 @@ int rtSocketResolverError(void)
/**
+ * Converts from a native socket address to a generic IPRT network address.
+ *
+ * @returns IPRT status code.
+ * @param pSrc The source address.
+ * @param cbSrc The size of the source address.
+ * @param pAddr Where to return the generic IPRT network
+ * address.
+ */
+static int rtSocketNetAddrFromAddr(RTSOCKADDRUNION const *pSrc, size_t cbSrc, PRTNETADDR pAddr)
+{
+ /*
+ * Convert the address.
+ */
+ if ( cbSrc == sizeof(struct sockaddr_in)
+ && pSrc->Addr.sa_family == AF_INET)
+ {
+ RT_ZERO(*pAddr);
+ pAddr->enmType = RTNETADDRTYPE_IPV4;
+ pAddr->uPort = RT_N2H_U16(pSrc->Ipv4.sin_port);
+ pAddr->uAddr.IPv4.u = pSrc->Ipv4.sin_addr.s_addr;
+ }
+#ifdef IPRT_WITH_TCPIP_V6
+ else if ( cbSrc == sizeof(struct sockaddr_in6)
+ && pSrc->Addr.sa_family == AF_INET6)
+ {
+ RT_ZERO(*pAddr);
+ pAddr->enmType = RTNETADDRTYPE_IPV6;
+ pAddr->uPort = RT_N2H_U16(pSrc->Ipv6.sin6_port);
+ pAddr->uAddr.IPv6.au32[0] = pSrc->Ipv6.sin6_addr.s6_addr32[0];
+ pAddr->uAddr.IPv6.au32[1] = pSrc->Ipv6.sin6_addr.s6_addr32[1];
+ pAddr->uAddr.IPv6.au32[2] = pSrc->Ipv6.sin6_addr.s6_addr32[2];
+ pAddr->uAddr.IPv6.au32[3] = pSrc->Ipv6.sin6_addr.s6_addr32[3];
+ }
+#endif
+ else
+ return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Converts from a generic IPRT network address to a native socket address.
+ *
+ * @returns IPRT status code.
+ * @param pAddr Pointer to the generic IPRT network address.
+ * @param pDst The source address.
+ * @param cbSrc The size of the source address.
+ */
+static int rtSocketAddrFromNetAddr(PCRTNETADDR pAddr, RTSOCKADDRUNION *pDst, size_t cbDst)
+{
+ RT_BZERO(pDst, cbDst);
+ if ( pAddr->enmType == RTNETADDRTYPE_IPV4
+ && cbDst >= sizeof(struct sockaddr_in))
+ {
+ pDst->Addr.sa_family = AF_INET;
+ pDst->Ipv4.sin_port = RT_H2N_U16(pAddr->uPort);
+ pDst->Ipv4.sin_addr.s_addr = pAddr->uAddr.IPv4.u;
+ }
+#ifdef IPRT_WITH_TCPIP_V6
+ else if ( pAddr->enmType == RTNETADDRTYPE_IPV6
+ && cbDst >= sizeof(struct sockaddr_in6))
+ {
+ pDst->Addr.sa_family = AF_INET6;
+ pDst->Ipv6.sin6_port = RT_H2N_U16(pAddr->uPort);
+ pSrc->Ipv6.sin6_addr.s6_addr32[0] = pAddr->uAddr.IPv6.au32[0];
+ pSrc->Ipv6.sin6_addr.s6_addr32[1] = pAddr->uAddr.IPv6.au32[1];
+ pSrc->Ipv6.sin6_addr.s6_addr32[2] = pAddr->uAddr.IPv6.au32[2];
+ pSrc->Ipv6.sin6_addr.s6_addr32[3] = pAddr->uAddr.IPv6.au32[3];
+ }
+#endif
+ else
+ return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
+ return VINF_SUCCESS;
+}
+
+
+/**
* Tries to lock the socket for exclusive usage by the calling thread.
*
* Call rtSocketUnlock() to unlock.
@@ -504,6 +581,64 @@ RTDECL(int) RTSocketSetInheritance(RTSOCKET hSocket, bool fInheritable)
}
+RTDECL(int) RTSocketParseInetAddress(const char *pszAddress, unsigned uPort, PRTNETADDR pAddr)
+{
+ int rc;
+
+ /*
+ * Validate input.
+ */
+ AssertReturn(uPort > 0, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pszAddress, VERR_INVALID_POINTER);
+
+#ifdef RT_OS_WINDOWS
+ /*
+ * Initialize WinSock and check version.
+ */
+ WORD wVersionRequested = MAKEWORD(1, 1);
+ WSADATA wsaData;
+ rc = WSAStartup(wVersionRequested, &wsaData);
+ if (wsaData.wVersion != wVersionRequested)
+ {
+ AssertMsgFailed(("Wrong winsock version\n"));
+ return VERR_NOT_SUPPORTED;
+ }
+#endif
+
+ /*
+ * Resolve the address.
+ */
+ /** @todo this only supports IPv4, and IPv6 support needs to be added.
+ * It probably needs to be converted to getnameinfo(). */
+ struct hostent *pHostEnt = NULL;
+ pHostEnt = gethostbyname(pszAddress);
+ if (!pHostEnt)
+ {
+ struct in_addr InAddr;
+ InAddr.s_addr = inet_addr(pszAddress);
+ pHostEnt = gethostbyaddr((char *)&InAddr, 4, AF_INET);
+ if (!pHostEnt)
+ {
+ rc = rtSocketResolverError();
+ AssertMsgFailed(("Could not resolve '%s', rc=%Rrc\n", pszAddress, rc));
+ return rc;
+ }
+ }
+
+ if (pHostEnt->h_addrtype == AF_INET)
+ {
+ RT_ZERO(*pAddr);
+ pAddr->enmType = RTNETADDRTYPE_IPV4;
+ pAddr->uPort = uPort;
+ pAddr->uAddr.IPv4.u = ((struct in_addr *)pHostEnt->h_addr)->s_addr;
+ }
+ else
+ return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
+
+ return VINF_SUCCESS;
+}
+
+
RTDECL(int) RTSocketRead(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead)
{
/*
@@ -573,6 +708,60 @@ RTDECL(int) RTSocketRead(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size
}
+RTDECL(int) RTSocketReadFrom(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead, PRTNETADDR pSrcAddr)
+{
+ /*
+ * Validate input.
+ */
+ RTSOCKETINT *pThis = hSocket;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(cbBuffer > 0, VERR_INVALID_PARAMETER);
+ AssertPtr(pvBuffer);
+ AssertPtr(pcbRead);
+ AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
+
+ int rc = rtSocketSwitchBlockingMode(pThis, true /* fBlocking */);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ /*
+ * Read data.
+ */
+ size_t cbRead = 0;
+ size_t cbToRead = cbBuffer;
+ rtSocketErrorReset();
+ RTSOCKADDRUNION u;
+#ifdef RT_OS_WINDOWS
+ int cbNow = cbToRead >= INT_MAX/2 ? INT_MAX/2 : (int)cbToRead;
+ int cbAddr = sizeof(u);
+#else
+ size_t cbNow = cbToRead;
+ socklen_t cbAddr = sizeof(u);
+#endif
+ ssize_t cbBytesRead = recvfrom(pThis->hNative, (char *)pvBuffer + cbRead, cbNow, MSG_NOSIGNAL, &u.Addr, &cbAddr);
+ if (cbBytesRead <= 0)
+ {
+ rc = rtSocketError();
+ Assert(RT_FAILURE_NP(rc) || cbBytesRead == 0);
+ if (RT_SUCCESS_NP(rc))
+ {
+ *pcbRead = 0;
+ rc = VINF_SUCCESS;
+ }
+ }
+ else
+ {
+ if (pSrcAddr)
+ rc = rtSocketNetAddrFromAddr(&u, cbAddr, pSrcAddr);
+ *pcbRead = cbBytesRead;
+ }
+
+ rtSocketUnlock(pThis);
+ return rc;
+}
+
+
RTDECL(int) RTSocketWrite(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer)
{
/*
@@ -642,6 +831,60 @@ RTDECL(int) RTSocketWrite(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffe
}
+RTDECL(int) RTSocketWriteTo(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer, PCRTNETADDR pAddr)
+{
+ /*
+ * Validate input.
+ */
+ RTSOCKETINT *pThis = hSocket;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
+
+ /* no locking since UDP reads may be done concurrently to writes, and
+ * this is the normal use case of this code. */
+
+ int rc = rtSocketSwitchBlockingMode(pThis, true /* fBlocking */);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ /* Figure out destination address. */
+ struct sockaddr *pSA = NULL;
+#ifdef RT_OS_WINDOWS
+ int cbSA = 0;
+#else
+ socklen_t cbSA = 0;
+#endif
+ RTSOCKADDRUNION u;
+ if (pAddr)
+ {
+ rc = rtSocketAddrFromNetAddr(pAddr, &u, sizeof(u));
+ if (RT_FAILURE(rc))
+ return rc;
+ pSA = &u.Addr;
+ cbSA = sizeof(u);
+ }
+
+ /*
+ * Must write all at once, otherwise it is a failure.
+ */
+#ifdef RT_OS_WINDOWS
+ int cbNow = cbBuffer >= INT_MAX / 2 ? INT_MAX / 2 : (int)cbBuffer;
+#else
+ size_t cbNow = cbBuffer >= SSIZE_MAX ? SSIZE_MAX : cbBuffer;
+#endif
+ ssize_t cbWritten = sendto(pThis->hNative, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL, pSA, cbSA);
+ if (RT_LIKELY((size_t)cbWritten == cbBuffer && cbWritten >= 0))
+ rc = VINF_SUCCESS;
+ else if (cbWritten < 0)
+ rc = rtSocketError();
+ else
+ rc = VERR_TOO_MUCH_DATA;
+
+ rtSocketUnlock(pThis);
+ return rc;
+}
+
+
RTDECL(int) RTSocketSgWrite(RTSOCKET hSocket, PCRTSGBUF pSgBuf)
{
/*
@@ -1084,47 +1327,6 @@ RTDECL(int) RTSocketShutdown(RTSOCKET hSocket, bool fRead, bool fWrite)
}
-/**
- * Converts from a native socket address to a generic IPRT network address.
- *
- * @returns IPRT status code.
- * @param pSrc The source address.
- * @param cbSrc The size of the source address.
- * @param pAddr Where to return the generic IPRT network
- * address.
- */
-static int rtSocketConvertAddress(RTSOCKADDRUNION const *pSrc, size_t cbSrc, PRTNETADDR pAddr)
-{
- /*
- * Convert the address.
- */
- if ( cbSrc == sizeof(struct sockaddr_in)
- && pSrc->Addr.sa_family == AF_INET)
- {
- RT_ZERO(*pAddr);
- pAddr->enmType = RTNETADDRTYPE_IPV4;
- pAddr->uPort = RT_N2H_U16(pSrc->Ipv4.sin_port);
- pAddr->uAddr.IPv4.u = pSrc->Ipv4.sin_addr.s_addr;
- }
-#ifdef IPRT_WITH_TCPIP_V6
- else if ( cbSrc == sizeof(struct sockaddr_in6)
- && pSrc->Addr.sa_family == AF_INET6)
- {
- RT_ZERO(*pAddr);
- pAddr->enmType = RTNETADDRTYPE_IPV6;
- pAddr->uPort = RT_N2H_U16(pSrc->Ipv6.sin6_port);
- pAddr->uAddr.IPv6.au32[0] = pSrc->Ipv6.sin6_addr.s6_addr32[0];
- pAddr->uAddr.IPv6.au32[1] = pSrc->Ipv6.sin6_addr.s6_addr32[1];
- pAddr->uAddr.IPv6.au32[2] = pSrc->Ipv6.sin6_addr.s6_addr32[2];
- pAddr->uAddr.IPv6.au32[3] = pSrc->Ipv6.sin6_addr.s6_addr32[3];
- }
-#endif
- else
- return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
- return VINF_SUCCESS;
-}
-
-
RTDECL(int) RTSocketGetLocalAddress(RTSOCKET hSocket, PRTNETADDR pAddr)
{
/*
@@ -1147,7 +1349,7 @@ RTDECL(int) RTSocketGetLocalAddress(RTSOCKET hSocket, PRTNETADDR pAddr)
#endif
RT_ZERO(u);
if (getsockname(pThis->hNative, &u.Addr, &cbAddr) == 0)
- rc = rtSocketConvertAddress(&u, cbAddr, pAddr);
+ rc = rtSocketNetAddrFromAddr(&u, cbAddr, pAddr);
else
rc = rtSocketError();
@@ -1177,7 +1379,7 @@ RTDECL(int) RTSocketGetPeerAddress(RTSOCKET hSocket, PRTNETADDR pAddr)
#endif
RT_ZERO(u);
if (getpeername(pThis->hNative, &u.Addr, &cbAddr) == 0)
- rc = rtSocketConvertAddress(&u, cbAddr, pAddr);
+ rc = rtSocketNetAddrFromAddr(&u, cbAddr, pAddr);
else
rc = rtSocketError();
diff --git a/src/VBox/Runtime/r3/solaris/RTSystemQueryDmiString-solaris.cpp b/src/VBox/Runtime/r3/solaris/RTSystemQueryDmiString-solaris.cpp
index 0dc82edbd..3f5634264 100644
--- a/src/VBox/Runtime/r3/solaris/RTSystemQueryDmiString-solaris.cpp
+++ b/src/VBox/Runtime/r3/solaris/RTSystemQueryDmiString-solaris.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSystemQueryDmiString-solaris.cpp $ */
+/* $Id: RTSystemQueryDmiString-solaris.cpp 29560 2010-05-17 15:08:09Z vboxsync $ */
/** @file
* IPRT - RTSystemQueryDmiString, solaris ring-3.
*/
diff --git a/src/VBox/Runtime/r3/solaris/coredumper-solaris.cpp b/src/VBox/Runtime/r3/solaris/coredumper-solaris.cpp
index 6f6b1c7fe..d20d8497a 100644
--- a/src/VBox/Runtime/r3/solaris/coredumper-solaris.cpp
+++ b/src/VBox/Runtime/r3/solaris/coredumper-solaris.cpp
@@ -1,10 +1,10 @@
-/* $Id: coredumper-solaris.cpp $ */
+/* $Id: coredumper-solaris.cpp 37631 2011-06-24 13:25:07Z vboxsync $ */
/** @file
- * IPRT Testcase - Core Dumper.
+ * IPRT - Custom Core Dumper, Solaris.
*/
/*
- * 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;
@@ -24,21 +24,22 @@
* terms and conditions of either the GPL or the CDDL or both.
*/
+
/*******************************************************************************
* Header Files *
*******************************************************************************/
-#define LOG_GROUP LOG_GROUP_CORE_DUMPER
-#include <VBox/log.h>
+#define LOG_GROUP RTLOGGROUP_DEFAULT
#include <iprt/coredumper.h>
-#include <iprt/types.h>
-#include <iprt/file.h>
-#include <iprt/err.h>
+
+#include <iprt/asm.h>
#include <iprt/dir.h>
+#include <iprt/err.h>
+#include <iprt/log.h>
+#include <iprt/param.h>
#include <iprt/path.h>
+#include <iprt/process.h>
#include <iprt/string.h>
#include <iprt/thread.h>
-#include <iprt/param.h>
-#include <iprt/asm.h>
#include "coredumper-solaris.h"
#ifdef RT_OS_SOLARIS
@@ -61,6 +62,7 @@
#include "internal/ldrELF.h"
#include "internal/ldrELF64.h"
+
/*******************************************************************************
* Globals *
*******************************************************************************/
@@ -126,67 +128,96 @@ static bool IsBigEndian()
/**
* Reads from a file making sure an interruption doesn't cause a failure.
*
- * @param hFile Handle to the file to read.
+ * @param fd Handle to the file to read.
* @param pv Where to store the read data.
* @param cbToRead Size of data to read.
*
* @return IPRT status code.
*/
-static int ReadFileNoIntr(RTFILE hFile, void *pv, size_t cbToRead)
+static int ReadFileNoIntr(int fd, void *pv, size_t cbToRead)
{
- int rc = VERR_READ_ERROR;
- while (1)
+ for (;;)
{
- rc = RTFileRead(hFile, pv, cbToRead, NULL /* Read all */);
- if (rc == VERR_INTERRUPTED)
- continue;
- break;
+ ssize_t cbRead = read(fd, pv, cbToRead);
+ if (cbRead < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ return RTErrConvertFromErrno(errno);
+ }
+ if ((size_t)cbRead == cbToRead)
+ return VINF_SUCCESS;
+ if ((size_t)cbRead > cbToRead)
+ return VERR_INTERNAL_ERROR_3;
+ if (cbRead == 0)
+ return VERR_EOF;
+ pv = (uint8_t *)pv + cbRead;
+ cbToRead -= cbRead;
}
- return rc;
}
/**
* Writes to a file making sure an interruption doesn't cause a failure.
*
- * @param hFile Handle to the file to write.
+ * @param fd Handle to the file to write to.
* @param pv Pointer to what to write.
- * @param cbToRead Size of data to write.
+ * @param cbToWrite Size of data to write.
*
* @return IPRT status code.
*/
-static int WriteFileNoIntr(RTFILE hFile, const void *pcv, size_t cbToRead)
+static int WriteFileNoIntr(int fd, const void *pv, size_t cbToWrite)
{
- int rc = VERR_READ_ERROR;
- while (1)
+ for (;;)
{
- rc = RTFileWrite(hFile, pcv, cbToRead, NULL /* Write all */);
- if (rc == VERR_INTERRUPTED)
- continue;
- break;
+ ssize_t cbWritten = write(fd, pv, cbToWrite);
+ if (cbWritten < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ return RTErrConvertFromErrno(errno);
+ }
+ if ((size_t)cbWritten == cbToWrite)
+ return VINF_SUCCESS;
+ if ((size_t)cbWritten > cbToWrite)
+ return VERR_INTERNAL_ERROR_2;
+ pv = (uint8_t const *)pv + cbWritten;
+ cbToWrite -= cbWritten;
}
- return rc;
}
/**
* Read from a given offset in the process' address space.
*
- * @param pVBoxProc Pointer to the VBox process.
+ * @param pSolProc Pointer to the solaris process.
* @param pv Where to read the data into.
* @param cb Size of the read buffer.
* @param off Offset to read from.
*
* @return VINF_SUCCESS, if all the given bytes was read in, otherwise VERR_READ_ERROR.
*/
-static ssize_t ProcReadAddrSpace(PVBOXPROCESS pVBoxProc, RTFOFF off, void *pvBuf, size_t cbToRead)
+static ssize_t ProcReadAddrSpace(PRTSOLCOREPROCESS pSolProc, RTFOFF off, void *pvBuf, size_t cbToRead)
{
- while (1)
+ for (;;)
{
- int rc = RTFileReadAt(pVBoxProc->hAs, off, pvBuf, cbToRead, NULL);
- if (rc == VERR_INTERRUPTED)
- continue;
- return rc;
+ ssize_t cbRead = pread(pSolProc->fdAs, pvBuf, cbToRead, off);
+ if (cbRead < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ return RTErrConvertFromErrno(errno);
+ }
+ if ((size_t)cbRead == cbToRead)
+ return VINF_SUCCESS;
+ if ((size_t)cbRead > cbToRead)
+ return VERR_INTERNAL_ERROR_4;
+ if (cbRead == 0)
+ return VERR_EOF;
+
+ pvBuf = (uint8_t *)pvBuf + cbRead;
+ cbToRead -= cbRead;
+ off += cbRead;
}
}
@@ -194,36 +225,52 @@ static ssize_t ProcReadAddrSpace(PVBOXPROCESS pVBoxProc, RTFOFF off, void *pvBuf
/**
* Determines if the current process' architecture is suitable for dumping core.
*
- * @param pVBoxProc Pointer to the VBox process.
+ * @param pSolProc Pointer to the solaris process.
*
* @return true if the architecture matches the current one.
*/
-static inline bool IsProcessArchNative(PVBOXPROCESS pVBoxProc)
+static inline bool IsProcessArchNative(PRTSOLCOREPROCESS pSolProc)
{
- return pVBoxProc->ProcInfo.pr_dmodel == PR_MODEL_NATIVE;
+ return pSolProc->ProcInfo.pr_dmodel == PR_MODEL_NATIVE;
}
/**
- * Helper function to get the size of a file given it's path.
+ * Helper function to get the size_t compatible file size from a file
+ * descriptor.
*
- * @param pszPath Pointer to the full path of the file.
+ * @return The file size (in bytes).
+ * @param fd The file descriptor.
+ */
+static size_t GetFileSizeByFd(int fd)
+{
+ struct stat st;
+ if (fstat(fd, &st) == 0)
+ return st.st_size < ~(size_t)0 ? (size_t)st.st_size : ~(size_t)0;
+
+ CORELOGRELSYS((CORELOG_NAME "GetFileSizeByFd: fstat failed rc=%Rrc\n", RTErrConvertFromErrno(errno)));
+ return 0;
+}
+
+
+/**
+ * Helper function to get the size_t compatible size of a file given its path.
*
- * @return The size of the file in bytes.
+ * @return The file size (in bytes).
+ * @param pszPath Pointer to the full path of the file.
*/
-static size_t GetFileSize(const char *pszPath)
+static size_t GetFileSizeByName(const char *pszPath)
{
- uint64_t cb = 0;
int fd = open(pszPath, O_RDONLY);
- if (fd >= 0)
+ if (fd < 0)
{
- RTFILE hFile = fd;
- RTFileGetSize(hFile, &cb);
- RTFileClose(hFile);
+ CORELOGRELSYS((CORELOG_NAME "GetFileSizeByName: failed to open %s rc=%Rrc\n", pszPath, RTErrConvertFromErrno(errno)));
+ return 0;
}
- else
- CORELOGRELSYS((CORELOG_NAME "GetFileSize: failed to open %s rc=%Rrc\n", pszPath, RTErrConvertFromErrno(fd)));
- return cb < ~(size_t)0 ? (size_t)cb : ~(size_t)0;
+
+ size_t cb = GetFileSizeByFd(fd);
+ close(fd);
+ return cb;
}
@@ -232,24 +279,25 @@ static size_t GetFileSize(const char *pszPath)
* This is meant to be called once, as a single-large anonymously
* mapped memory area which will be used during the core dumping routines.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @return IPRT status code.
*/
-static int AllocMemoryArea(PVBOXCORE pVBoxCore)
+static int AllocMemoryArea(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore->pvCore == NULL, VERR_ALREADY_EXISTS);
+ AssertReturn(pSolCore->pvCore == NULL, VERR_ALREADY_EXISTS);
- struct VBOXSOLPREALLOCTABLE
+ static struct
{
const char *pszFilePath; /* Proc based path */
size_t cbHeader; /* Size of header */
size_t cbEntry; /* Size of each entry in file */
size_t cbAccounting; /* Size of each accounting entry per entry */
- } aPreAllocTable[] = {
- { "/proc/%d/map", 0, sizeof(prmap_t), sizeof(VBOXSOLMAPINFO) },
+ } const s_aPreAllocTable[] =
+ {
+ { "/proc/%d/map", 0, sizeof(prmap_t), sizeof(RTSOLCOREMAPINFO) },
{ "/proc/%d/auxv", 0, 0, 0 },
- { "/proc/%d/lpsinfo", sizeof(prheader_t), sizeof(lwpsinfo_t), sizeof(VBOXSOLTHREADINFO) },
+ { "/proc/%d/lpsinfo", sizeof(prheader_t), sizeof(lwpsinfo_t), sizeof(RTSOLCORETHREADINFO) },
{ "/proc/%d/lstatus", 0, 0, 0 },
{ "/proc/%d/ldt", 0, 0, 0 },
{ "/proc/%d/cred", sizeof(prcred_t), sizeof(gid_t), 0 },
@@ -257,25 +305,25 @@ static int AllocMemoryArea(PVBOXCORE pVBoxCore)
};
size_t cb = 0;
- for (int i = 0; i < (int)RT_ELEMENTS(aPreAllocTable); i++)
+ for (unsigned i = 0; i < RT_ELEMENTS(s_aPreAllocTable); i++)
{
char szPath[PATH_MAX];
- RTStrPrintf(szPath, sizeof(szPath), aPreAllocTable[i].pszFilePath, (int)pVBoxCore->VBoxProc.Process);
- size_t cbFile = GetFileSize(szPath);
+ RTStrPrintf(szPath, sizeof(szPath), s_aPreAllocTable[i].pszFilePath, (int)pSolCore->SolProc.Process);
+ size_t cbFile = GetFileSizeByName(szPath);
cb += cbFile;
if ( cbFile > 0
- && aPreAllocTable[i].cbEntry > 0)
+ && s_aPreAllocTable[i].cbEntry > 0)
{
- cb += ((cbFile - aPreAllocTable[i].cbHeader) / aPreAllocTable[i].cbEntry) * (aPreAllocTable[i].cbAccounting > 0 ?
- aPreAllocTable[i].cbAccounting : 1);
- cb += aPreAllocTable[i].cbHeader;
+ cb += ((cbFile - s_aPreAllocTable[i].cbHeader) / s_aPreAllocTable[i].cbEntry)
+ * (s_aPreAllocTable[i].cbAccounting > 0 ? s_aPreAllocTable[i].cbAccounting : 1);
+ cb += s_aPreAllocTable[i].cbHeader;
}
}
/*
* Make room for our own mapping accountant entry which will also be included in the core.
*/
- cb += sizeof(VBOXSOLMAPINFO);
+ cb += sizeof(RTSOLCOREMAPINFO);
/*
* Allocate the required space, plus some extra room.
@@ -285,58 +333,55 @@ static int AllocMemoryArea(PVBOXCORE pVBoxCore)
if (pv != MAP_FAILED)
{
CORELOG((CORELOG_NAME "AllocMemoryArea: memory area of %u bytes allocated.\n", cb));
- pVBoxCore->pvCore = pv;
- pVBoxCore->pvFree = pv;
- pVBoxCore->cbCore = cb;
+ pSolCore->pvCore = pv;
+ pSolCore->pvFree = pv;
+ pSolCore->cbCore = cb;
return VINF_SUCCESS;
}
- else
- {
- CORELOGRELSYS((CORELOG_NAME "AllocMemoryArea: failed cb=%u\n", cb));
- return VERR_NO_MEMORY;
- }
+ CORELOGRELSYS((CORELOG_NAME "AllocMemoryArea: failed cb=%u\n", cb));
+ return VERR_NO_MEMORY;
}
/**
* Free memory area used by the core object.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*/
-static void FreeMemoryArea(PVBOXCORE pVBoxCore)
+static void FreeMemoryArea(PRTSOLCORE pSolCore)
{
- AssertReturnVoid(pVBoxCore);
- AssertReturnVoid(pVBoxCore->pvCore);
- AssertReturnVoid(pVBoxCore->cbCore > 0);
+ AssertReturnVoid(pSolCore);
+ AssertReturnVoid(pSolCore->pvCore);
+ AssertReturnVoid(pSolCore->cbCore > 0);
- munmap(pVBoxCore->pvCore, pVBoxCore->cbCore);
- CORELOG((CORELOG_NAME "FreeMemoryArea: memory area of %u bytes freed.\n", pVBoxCore->cbCore));
+ munmap(pSolCore->pvCore, pSolCore->cbCore);
+ CORELOG((CORELOG_NAME "FreeMemoryArea: memory area of %u bytes freed.\n", pSolCore->cbCore));
- pVBoxCore->pvCore = NULL;
- pVBoxCore->pvFree= NULL;
- pVBoxCore->cbCore = 0;
+ pSolCore->pvCore = NULL;
+ pSolCore->pvFree= NULL;
+ pSolCore->cbCore = 0;
}
/**
* Get a chunk from the area of allocated memory.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
* @param cb Size of requested chunk.
*
* @return Pointer to allocated memory, or NULL on failure.
*/
-static void *GetMemoryChunk(PVBOXCORE pVBoxCore, size_t cb)
+static void *GetMemoryChunk(PRTSOLCORE pSolCore, size_t cb)
{
- AssertReturn(pVBoxCore, NULL);
- AssertReturn(pVBoxCore->pvCore, NULL);
- AssertReturn(pVBoxCore->pvFree, NULL);
+ AssertReturn(pSolCore, NULL);
+ AssertReturn(pSolCore->pvCore, NULL);
+ AssertReturn(pSolCore->pvFree, NULL);
- size_t cbAllocated = (char *)pVBoxCore->pvFree - (char *)pVBoxCore->pvCore;
- if (cbAllocated < pVBoxCore->cbCore)
+ size_t cbAllocated = (char *)pSolCore->pvFree - (char *)pSolCore->pvCore;
+ if (cbAllocated < pSolCore->cbCore)
{
- char *pb = (char *)pVBoxCore->pvFree;
- pVBoxCore->pvFree = pb + cb;
+ char *pb = (char *)pSolCore->pvFree;
+ pSolCore->pvFree = pb + cb;
return pb;
}
@@ -347,7 +392,7 @@ static void *GetMemoryChunk(PVBOXCORE pVBoxCore, size_t cb)
/**
* Reads the proc file's content into a newly allocated buffer.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
* @param pszFileFmt Only the name of the file to read from (/proc/<pid> will be prepended)
* @param ppv Where to store the allocated buffer.
* @param pcb Where to store size of the buffer.
@@ -356,25 +401,22 @@ static void *GetMemoryChunk(PVBOXCORE pVBoxCore, size_t cb)
* returned with pointed to values of @c ppv, @c pcb set to NULL and 0
* respectively.
*/
-static int ProcReadFileInto(PVBOXCORE pVBoxCore, const char *pszProcFileName, void **ppv, size_t *pcb)
+static int ProcReadFileInto(PRTSOLCORE pSolCore, const char *pszProcFileName, void **ppv, size_t *pcb)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
char szPath[PATH_MAX];
- RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/%s", (int)pVBoxCore->VBoxProc.Process, pszProcFileName);
+ RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/%s", (int)pSolCore->SolProc.Process, pszProcFileName);
int rc = VINF_SUCCESS;
int fd = open(szPath, O_RDONLY);
if (fd >= 0)
{
- RTFILE hFile = fd;
- uint64_t u64Size;
- RTFileGetSize(hFile, &u64Size);
- *pcb = u64Size < ~(size_t)0 ? u64Size : ~(size_t)0;
+ *pcb = GetFileSizeByFd(fd);
if (*pcb > 0)
{
- *ppv = GetMemoryChunk(pVBoxCore, *pcb);
+ *ppv = GetMemoryChunk(pSolCore, *pcb);
if (*ppv)
- rc = ReadFileNoIntr(hFile, *ppv, *pcb);
+ rc = ReadFileNoIntr(fd, *ppv, *pcb);
else
rc = VERR_NO_MEMORY;
}
@@ -384,7 +426,7 @@ static int ProcReadFileInto(PVBOXCORE pVBoxCore, const char *pszProcFileName, vo
*ppv = NULL;
rc = VINF_SUCCESS;
}
- RTFileClose(hFile);
+ close(fd);
}
else
{
@@ -398,26 +440,25 @@ static int ProcReadFileInto(PVBOXCORE pVBoxCore, const char *pszProcFileName, vo
/**
* Read process information (format psinfo_t) from /proc.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @return IPRT status code.
*/
-static int ProcReadInfo(PVBOXCORE pVBoxCore)
+static int ProcReadInfo(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
char szPath[PATH_MAX];
int rc = VINF_SUCCESS;
- RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/psinfo", (int)pVBoxProc->Process);
+ RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/psinfo", (int)pSolProc->Process);
int fd = open(szPath, O_RDONLY);
if (fd >= 0)
{
- RTFILE hFile = fd;
size_t cbProcInfo = sizeof(psinfo_t);
- rc = ReadFileNoIntr(hFile, &pVBoxProc->ProcInfo, cbProcInfo);
- RTFileClose(hFile);
+ rc = ReadFileNoIntr(fd, &pSolProc->ProcInfo, cbProcInfo);
+ close(fd);
}
else
{
@@ -432,29 +473,27 @@ static int ProcReadInfo(PVBOXCORE pVBoxCore)
/**
* Read process status (format pstatus_t) from /proc.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @return IPRT status code.
*/
-static int ProcReadStatus(PVBOXCORE pVBoxCore)
+static int ProcReadStatus(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
char szPath[PATH_MAX];
int rc = VINF_SUCCESS;
- RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/status", (int)pVBoxProc->Process);
+ RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/status", (int)pSolProc->Process);
int fd = open(szPath, O_RDONLY);
if (fd >= 0)
{
- RTFILE hFile = fd;
- size_t cbRead;
size_t cbProcStatus = sizeof(pstatus_t);
- AssertCompile(sizeof(pstatus_t) == sizeof(pVBoxProc->ProcStatus));
- rc = ReadFileNoIntr(hFile, &pVBoxProc->ProcStatus, cbProcStatus);
- RTFileClose(hFile);
+ AssertCompile(sizeof(pstatus_t) == sizeof(pSolProc->ProcStatus));
+ rc = ReadFileNoIntr(fd, &pSolProc->ProcStatus, cbProcStatus);
+ close(fd);
}
else
{
@@ -468,38 +507,38 @@ static int ProcReadStatus(PVBOXCORE pVBoxCore)
/**
* Read process credential information (format prcred_t + array of guid_t)
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @remarks Should not be called before successful call to @see AllocMemoryArea()
* @return IPRT status code.
*/
-static int ProcReadCred(PVBOXCORE pVBoxCore)
+static int ProcReadCred(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
- return ProcReadFileInto(pVBoxCore, "cred", &pVBoxProc->pvCred, &pVBoxProc->cbCred);
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
+ return ProcReadFileInto(pSolCore, "cred", &pSolProc->pvCred, &pSolProc->cbCred);
}
/**
* Read process privilege information (format prpriv_t + array of priv_chunk_t)
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @remarks Should not be called before successful call to @see AllocMemoryArea()
* @return IPRT status code.
*/
-static int ProcReadPriv(PVBOXCORE pVBoxCore)
+static int ProcReadPriv(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
- int rc = ProcReadFileInto(pVBoxCore, "priv", (void **)&pVBoxProc->pPriv, &pVBoxProc->cbPriv);
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
+ int rc = ProcReadFileInto(pSolCore, "priv", (void **)&pSolProc->pPriv, &pSolProc->cbPriv);
if (RT_FAILURE(rc))
return rc;
- pVBoxProc->pcPrivImpl = getprivimplinfo();
- if (!pVBoxProc->pcPrivImpl)
+ pSolProc->pcPrivImpl = getprivimplinfo();
+ if (!pSolProc->pcPrivImpl)
{
CORELOGRELSYS((CORELOG_NAME "ProcReadPriv: getprivimplinfo returned NULL.\n"));
return VERR_INVALID_STATE;
@@ -511,36 +550,36 @@ static int ProcReadPriv(PVBOXCORE pVBoxCore)
/**
* Read process LDT information (format array of struct ssd) from /proc.
*
- * @param pVBoxProc Pointer to the core object.
+ * @param pSolProc Pointer to the core object.
*
* @remarks Should not be called before successful call to @see AllocMemoryArea()
* @return IPRT status code.
*/
-static int ProcReadLdt(PVBOXCORE pVBoxCore)
+static int ProcReadLdt(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
- return ProcReadFileInto(pVBoxCore, "ldt", &pVBoxProc->pvLdt, &pVBoxProc->cbLdt);
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
+ return ProcReadFileInto(pSolCore, "ldt", &pSolProc->pvLdt, &pSolProc->cbLdt);
}
/**
* Read process auxiliary vectors (format auxv_t) for the process.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @remarks Should not be called before successful call to @see AllocMemoryArea()
* @return IPRT status code.
*/
-static int ProcReadAuxVecs(PVBOXCORE pVBoxCore)
+static int ProcReadAuxVecs(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
char szPath[PATH_MAX];
int rc = VINF_SUCCESS;
- RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/auxv", (int)pVBoxProc->Process);
+ RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/auxv", (int)pSolProc->Process);
int fd = open(szPath, O_RDONLY);
if (fd < 0)
{
@@ -549,40 +588,35 @@ static int ProcReadAuxVecs(PVBOXCORE pVBoxCore)
return rc;
}
- RTFILE hFile = fd;
- uint64_t u64Size;
- RTFileGetSize(hFile, &u64Size);
- size_t cbAuxFile = u64Size < ~(size_t)0 ? u64Size : ~(size_t)0;
+ size_t cbAuxFile = GetFileSizeByFd(fd);
if (cbAuxFile >= sizeof(auxv_t))
{
- pVBoxProc->pAuxVecs = (auxv_t*)GetMemoryChunk(pVBoxCore, cbAuxFile + sizeof(auxv_t));
- if (pVBoxProc->pAuxVecs)
+ pSolProc->pAuxVecs = (auxv_t*)GetMemoryChunk(pSolCore, cbAuxFile + sizeof(auxv_t));
+ if (pSolProc->pAuxVecs)
{
- rc = ReadFileNoIntr(hFile, pVBoxProc->pAuxVecs, cbAuxFile);
+ rc = ReadFileNoIntr(fd, pSolProc->pAuxVecs, cbAuxFile);
if (RT_SUCCESS(rc))
{
/* Terminate list of vectors */
- pVBoxProc->cAuxVecs = cbAuxFile / sizeof(auxv_t);
+ pSolProc->cAuxVecs = cbAuxFile / sizeof(auxv_t);
CORELOG((CORELOG_NAME "ProcReadAuxVecs: cbAuxFile=%u auxv_t size %d cAuxVecs=%u\n", cbAuxFile, sizeof(auxv_t),
- pVBoxProc->cAuxVecs));
- if (pVBoxProc->cAuxVecs > 0)
+ pSolProc->cAuxVecs));
+ if (pSolProc->cAuxVecs > 0)
{
- pVBoxProc->pAuxVecs[pVBoxProc->cAuxVecs].a_type = AT_NULL;
- pVBoxProc->pAuxVecs[pVBoxProc->cAuxVecs].a_un.a_val = 0L;
- RTFileClose(hFile);
+ pSolProc->pAuxVecs[pSolProc->cAuxVecs].a_type = AT_NULL;
+ pSolProc->pAuxVecs[pSolProc->cAuxVecs].a_un.a_val = 0L;
+ close(fd);
return VINF_SUCCESS;
}
- else
- {
- CORELOGRELSYS((CORELOG_NAME "ProcReadAuxVecs: Invalid vector count %u\n", pVBoxProc->cAuxVecs));
- rc = VERR_READ_ERROR;
- }
+
+ CORELOGRELSYS((CORELOG_NAME "ProcReadAuxVecs: Invalid vector count %u\n", pSolProc->cAuxVecs));
+ rc = VERR_READ_ERROR;
}
else
CORELOGRELSYS((CORELOG_NAME "ProcReadAuxVecs: ReadFileNoIntr failed. rc=%Rrc cbAuxFile=%u\n", rc, cbAuxFile));
- pVBoxProc->pAuxVecs = NULL;
- pVBoxProc->cAuxVecs = 0;
+ pSolProc->pAuxVecs = NULL;
+ pSolProc->cAuxVecs = 0;
}
else
{
@@ -596,7 +630,7 @@ static int ProcReadAuxVecs(PVBOXCORE pVBoxCore)
rc = VERR_READ_ERROR;
}
- RTFileClose(hFile);
+ close(fd);
return rc;
}
@@ -604,12 +638,12 @@ static int ProcReadAuxVecs(PVBOXCORE pVBoxCore)
/*
* Find an element in the process' auxiliary vector.
*/
-static long GetAuxVal(PVBOXPROCESS pVBoxProc, int Type)
+static long GetAuxVal(PRTSOLCOREPROCESS pSolProc, int Type)
{
- AssertReturn(pVBoxProc, -1);
- if (pVBoxProc->pAuxVecs)
+ AssertReturn(pSolProc, -1);
+ if (pSolProc->pAuxVecs)
{
- auxv_t *pAuxVec = pVBoxProc->pAuxVecs;
+ auxv_t *pAuxVec = pSolProc->pAuxVecs;
for (; pAuxVec->a_type != AT_NULL; pAuxVec++)
{
if (pAuxVec->a_type == Type)
@@ -623,64 +657,59 @@ static long GetAuxVal(PVBOXPROCESS pVBoxProc, int Type)
/**
* Read the process mappings (format prmap_t array).
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @remarks Should not be called before successful call to @see AllocMemoryArea()
* @return IPRT status code.
*/
-static int ProcReadMappings(PVBOXCORE pVBoxCore)
+static int ProcReadMappings(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
char szPath[PATH_MAX];
int rc = VINF_SUCCESS;
- RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/map", (int)pVBoxProc->Process);
- int fd = open(szPath, O_RDONLY);
- if (fd < 0)
+ RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/map", (int)pSolProc->Process);
+ int fdMap = open(szPath, O_RDONLY);
+ if (fdMap < 0)
{
- rc = RTErrConvertFromErrno(fd);
+ rc = RTErrConvertFromErrno(errno);
CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: failed to open %s. rc=%Rrc\n", szPath, rc));
return rc;
}
- RTFILE hFile = fd;
- RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/as", (int)pVBoxProc->Process);
- fd = open(szPath, O_RDONLY);
- if (fd >= 0)
+ RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/as", (int)pSolProc->Process);
+ pSolProc->fdAs = open(szPath, O_RDONLY);
+ if (pSolProc->fdAs >= 0)
{
- pVBoxProc->hAs = fd;
-
/*
* Allocate and read all the prmap_t objects from proc.
*/
- uint64_t u64Size;
- RTFileGetSize(hFile, &u64Size);
- size_t cbMapFile = u64Size < ~(size_t)0 ? u64Size : ~(size_t)0;
+ size_t cbMapFile = GetFileSizeByFd(fdMap);
if (cbMapFile >= sizeof(prmap_t))
{
- prmap_t *pMap = (prmap_t*)GetMemoryChunk(pVBoxCore, cbMapFile);
+ prmap_t *pMap = (prmap_t*)GetMemoryChunk(pSolCore, cbMapFile);
if (pMap)
{
- rc = ReadFileNoIntr(hFile, pMap, cbMapFile);
+ rc = ReadFileNoIntr(fdMap, pMap, cbMapFile);
if (RT_SUCCESS(rc))
{
- pVBoxProc->cMappings = cbMapFile / sizeof(prmap_t);
- if (pVBoxProc->cMappings > 0)
+ pSolProc->cMappings = cbMapFile / sizeof(prmap_t);
+ if (pSolProc->cMappings > 0)
{
/*
- * Allocate for each prmap_t object, a corresponding VBOXSOLMAPINFO object.
+ * Allocate for each prmap_t object, a corresponding RTSOLCOREMAPINFO object.
*/
- pVBoxProc->pMapInfoHead = (PVBOXSOLMAPINFO)GetMemoryChunk(pVBoxCore, pVBoxProc->cMappings * sizeof(VBOXSOLMAPINFO));
- if (pVBoxProc->pMapInfoHead)
+ pSolProc->pMapInfoHead = (PRTSOLCOREMAPINFO)GetMemoryChunk(pSolCore, pSolProc->cMappings * sizeof(RTSOLCOREMAPINFO));
+ if (pSolProc->pMapInfoHead)
{
/*
* Associate the prmap_t with the mapping info object.
*/
- Assert(pVBoxProc->pMapInfoHead == NULL);
- PVBOXSOLMAPINFO pCur = pVBoxProc->pMapInfoHead;
- PVBOXSOLMAPINFO pPrev = NULL;
- for (uint64_t i = 0; i < pVBoxProc->cMappings; i++, pMap++, pCur++)
+ /*Assert(pSolProc->pMapInfoHead == NULL); - does not make sense */
+ PRTSOLCOREMAPINFO pCur = pSolProc->pMapInfoHead;
+ PRTSOLCOREMAPINFO pPrev = NULL;
+ for (uint64_t i = 0; i < pSolProc->cMappings; i++, pMap++, pCur++)
{
memcpy(&pCur->pMap, pMap, sizeof(pCur->pMap));
if (pPrev)
@@ -696,7 +725,7 @@ static int ProcReadMappings(PVBOXCORE pVBoxCore)
while (k < pCur->pMap.pr_size)
{
size_t cb = RT_MIN(sizeof(achBuf), pCur->pMap.pr_size - k);
- int rc2 = ProcReadAddrSpace(pVBoxProc, pCur->pMap.pr_vaddr + k, &achBuf, cb);
+ int rc2 = ProcReadAddrSpace(pSolProc, pCur->pMap.pr_vaddr + k, &achBuf, cb);
if (RT_FAILURE(rc2))
{
CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: skipping mapping. vaddr=%#x rc=%Rrc\n",
@@ -721,22 +750,20 @@ static int ProcReadMappings(PVBOXCORE pVBoxCore)
if (pPrev)
pPrev->pNext = NULL;
- RTFileClose(hFile);
- RTFileClose(pVBoxProc->hAs);
- pVBoxProc->hAs = NIL_RTFILE;
- CORELOG((CORELOG_NAME "ProcReadMappings: successfully read in %u mappings\n", pVBoxProc->cMappings));
+ close(fdMap);
+ close(pSolProc->fdAs);
+ pSolProc->fdAs = -1;
+ CORELOG((CORELOG_NAME "ProcReadMappings: successfully read in %u mappings\n", pSolProc->cMappings));
return VINF_SUCCESS;
}
- else
- {
- CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: GetMemoryChunk failed %u\n",
- pVBoxProc->cMappings * sizeof(VBOXSOLMAPINFO)));
- rc = VERR_NO_MEMORY;
- }
+
+ CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: GetMemoryChunk failed %u\n",
+ pSolProc->cMappings * sizeof(RTSOLCOREMAPINFO)));
+ rc = VERR_NO_MEMORY;
}
else
{
- CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: Invalid mapping count %u\n", pVBoxProc->cMappings));
+ CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: Invalid mapping count %u\n", pSolProc->cMappings));
rc = VERR_READ_ERROR;
}
}
@@ -750,13 +777,13 @@ static int ProcReadMappings(PVBOXCORE pVBoxCore)
}
}
- RTFileClose(pVBoxProc->hAs);
- pVBoxProc->hAs = NIL_RTFILE;
+ close(pSolProc->fdAs);
+ pSolProc->fdAs = -1;
}
else
CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: failed to open %s. rc=%Rrc\n", szPath, rc));
- RTFileClose(hFile);
+ close(fdMap);
return rc;
}
@@ -764,17 +791,17 @@ static int ProcReadMappings(PVBOXCORE pVBoxCore)
/**
* Reads the thread information for all threads in the process.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @remarks Should not be called before successful call to @see AllocMemoryArea()
* @return IPRT status code.
*/
-static int ProcReadThreads(PVBOXCORE pVBoxCore)
+static int ProcReadThreads(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
- AssertReturn(pVBoxProc->pCurThreadCtx, VERR_NO_DATA);
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
+ AssertReturn(pSolProc->pCurThreadCtx, VERR_NO_DATA);
/*
* Read the information for threads.
@@ -782,7 +809,7 @@ static int ProcReadThreads(PVBOXCORE pVBoxCore)
*/
size_t cbInfoHdrAndData;
void *pvInfoHdr = NULL;
- int rc = ProcReadFileInto(pVBoxCore, "lpsinfo", &pvInfoHdr, &cbInfoHdrAndData);
+ int rc = ProcReadFileInto(pSolCore, "lpsinfo", &pvInfoHdr, &cbInfoHdrAndData);
if (RT_SUCCESS(rc))
{
/*
@@ -791,7 +818,7 @@ static int ProcReadThreads(PVBOXCORE pVBoxCore)
*/
void *pvStatusHdr = NULL;
size_t cbStatusHdrAndData;
- rc = ProcReadFileInto(pVBoxCore, "lstatus", &pvStatusHdr, &cbStatusHdrAndData);
+ rc = ProcReadFileInto(pSolCore, "lstatus", &pvStatusHdr, &cbStatusHdrAndData);
if (RT_SUCCESS(rc))
{
prheader_t *pInfoHdr = (prheader_t *)pvInfoHdr;
@@ -843,12 +870,12 @@ static int ProcReadThreads(PVBOXCORE pVBoxCore)
cInfo = pInfoHdr->pr_nent;
cStatus = pInfoHdr->pr_nent;
- size_t cbThreadInfo = RT_MAX(cStatus, cInfo) * sizeof(VBOXSOLTHREADINFO);
- pVBoxProc->pThreadInfoHead = (PVBOXSOLTHREADINFO)GetMemoryChunk(pVBoxCore, cbThreadInfo);
- if (pVBoxProc->pThreadInfoHead)
+ size_t cbThreadInfo = RT_MAX(cStatus, cInfo) * sizeof(RTSOLCORETHREADINFO);
+ pSolProc->pThreadInfoHead = (PRTSOLCORETHREADINFO)GetMemoryChunk(pSolCore, cbThreadInfo);
+ if (pSolProc->pThreadInfoHead)
{
- PVBOXSOLTHREADINFO pCur = pVBoxProc->pThreadInfoHead;
- PVBOXSOLTHREADINFO pPrev = NULL;
+ PRTSOLCORETHREADINFO pCur = pSolProc->pThreadInfoHead;
+ PRTSOLCORETHREADINFO pPrev = NULL;
for (uint64_t i = 0; i < cInfo; i++, pCur++)
{
pCur->Info = *pInfo;
@@ -860,16 +887,16 @@ static int ProcReadThreads(PVBOXCORE pVBoxCore)
* when the core dump got initiated before whatever signal caused it.
*/
if ( pStatus /* noid droid */
- && pStatus->pr_lwpid == (id_t)pVBoxProc->hCurThread)
+ && pStatus->pr_lwpid == (id_t)pSolProc->hCurThread)
{
- AssertCompile(sizeof(pStatus->pr_reg) == sizeof(pVBoxProc->pCurThreadCtx->uc_mcontext.gregs));
- AssertCompile(sizeof(pStatus->pr_fpreg) == sizeof(pVBoxProc->pCurThreadCtx->uc_mcontext.fpregs));
- memcpy(&pStatus->pr_reg, &pVBoxProc->pCurThreadCtx->uc_mcontext.gregs, sizeof(pStatus->pr_reg));
- memcpy(&pStatus->pr_fpreg, &pVBoxProc->pCurThreadCtx->uc_mcontext.fpregs, sizeof(pStatus->pr_fpreg));
+ AssertCompile(sizeof(pStatus->pr_reg) == sizeof(pSolProc->pCurThreadCtx->uc_mcontext.gregs));
+ AssertCompile(sizeof(pStatus->pr_fpreg) == sizeof(pSolProc->pCurThreadCtx->uc_mcontext.fpregs));
+ memcpy(&pStatus->pr_reg, &pSolProc->pCurThreadCtx->uc_mcontext.gregs, sizeof(pStatus->pr_reg));
+ memcpy(&pStatus->pr_fpreg, &pSolProc->pCurThreadCtx->uc_mcontext.fpregs, sizeof(pStatus->pr_fpreg));
- AssertCompile(sizeof(pStatus->pr_lwphold) == sizeof(pVBoxProc->pCurThreadCtx->uc_sigmask));
- memcpy(&pStatus->pr_lwphold, &pVBoxProc->pCurThreadCtx->uc_sigmask, sizeof(pStatus->pr_lwphold));
- pStatus->pr_ustack = (uintptr_t)&pVBoxProc->pCurThreadCtx->uc_stack;
+ AssertCompile(sizeof(pStatus->pr_lwphold) == sizeof(pSolProc->pCurThreadCtx->uc_sigmask));
+ memcpy(&pStatus->pr_lwphold, &pSolProc->pCurThreadCtx->uc_sigmask, sizeof(pStatus->pr_lwphold));
+ pStatus->pr_ustack = (uintptr_t)&pSolProc->pCurThreadCtx->uc_stack;
CORELOG((CORELOG_NAME "ProcReadThreads: patched dumper thread context with pre-dump time context.\n"));
}
@@ -892,7 +919,7 @@ static int ProcReadThreads(PVBOXCORE pVBoxCore)
pPrev->pNext = NULL;
CORELOG((CORELOG_NAME "ProcReadThreads: successfully read %u threads.\n", cInfo));
- pVBoxProc->cThreads = cInfo;
+ pSolProc->cThreads = cInfo;
return VINF_SUCCESS;
}
else
@@ -926,43 +953,43 @@ static int ProcReadThreads(PVBOXCORE pVBoxCore)
* Reads miscellaneous information that is collected as part of a core file.
* This may include platform name, zone name and other OS-specific information.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @return IPRT status code.
*/
-static int ProcReadMiscInfo(PVBOXCORE pVBoxCore)
+static int ProcReadMiscInfo(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
#ifdef RT_OS_SOLARIS
/*
* Read the platform name, uname string and zone name.
*/
- int rc = sysinfo(SI_PLATFORM, pVBoxProc->szPlatform, sizeof(pVBoxProc->szPlatform));
+ int rc = sysinfo(SI_PLATFORM, pSolProc->szPlatform, sizeof(pSolProc->szPlatform));
if (rc == -1)
{
CORELOGRELSYS((CORELOG_NAME "ProcReadMiscInfo: sysinfo failed. rc=%d errno=%d\n", rc, errno));
return VERR_GENERAL_FAILURE;
}
- pVBoxProc->szPlatform[sizeof(pVBoxProc->szPlatform) - 1] = '\0';
+ pSolProc->szPlatform[sizeof(pSolProc->szPlatform) - 1] = '\0';
- rc = uname(&pVBoxProc->UtsName);
+ rc = uname(&pSolProc->UtsName);
if (rc == -1)
{
CORELOGRELSYS((CORELOG_NAME "ProcReadMiscInfo: uname failed. rc=%d errno=%d\n", rc, errno));
return VERR_GENERAL_FAILURE;
}
- rc = getzonenamebyid(pVBoxProc->ProcInfo.pr_zoneid, pVBoxProc->szZoneName, sizeof(pVBoxProc->szZoneName));
+ rc = getzonenamebyid(pSolProc->ProcInfo.pr_zoneid, pSolProc->szZoneName, sizeof(pSolProc->szZoneName));
if (rc < 0)
{
CORELOGRELSYS((CORELOG_NAME "ProcReadMiscInfo: getzonenamebyid failed. rc=%d errno=%d zoneid=%d\n", rc, errno,
- pVBoxProc->ProcInfo.pr_zoneid));
+ pSolProc->ProcInfo.pr_zoneid));
return VERR_GENERAL_FAILURE;
}
- pVBoxProc->szZoneName[sizeof(pVBoxProc->szZoneName) - 1] = '\0';
+ pSolProc->szZoneName[sizeof(pSolProc->szZoneName) - 1] = '\0';
rc = VINF_SUCCESS;
#else
@@ -976,16 +1003,16 @@ static int ProcReadMiscInfo(PVBOXCORE pVBoxCore)
* On Solaris use the old-style procfs interfaces but the core file still should have this
* info. for backward and GDB compatibility, hence the need for this ugly function.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
* @param pInfo Pointer to the old prpsinfo_t structure to update.
*/
-static void GetOldProcessInfo(PVBOXCORE pVBoxCore, prpsinfo_t *pInfo)
+static void GetOldProcessInfo(PRTSOLCORE pSolCore, prpsinfo_t *pInfo)
{
- AssertReturnVoid(pVBoxCore);
+ AssertReturnVoid(pSolCore);
AssertReturnVoid(pInfo);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
- psinfo_t *pSrc = &pVBoxProc->ProcInfo;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
+ psinfo_t *pSrc = &pSolProc->ProcInfo;
memset(pInfo, 0, sizeof(prpsinfo_t));
pInfo->pr_state = pSrc->pr_lwp.pr_state;
pInfo->pr_zomb = (pInfo->pr_state == SZOMB);
@@ -1032,20 +1059,20 @@ static void GetOldProcessInfo(PVBOXCORE pVBoxCore, prpsinfo_t *pInfo)
* On Solaris use the old-style procfs interfaces but the core file still should have this
* info. for backward and GDB compatibility, hence the need for this ugly function.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
* @param pInfo Pointer to the thread info.
* @param pStatus Pointer to the thread status.
* @param pDst Pointer to the old-style status structure to update.
*
*/
-static void GetOldProcessStatus(PVBOXCORE pVBoxCore, lwpsinfo_t *pInfo, lwpstatus_t *pStatus, prstatus_t *pDst)
+static void GetOldProcessStatus(PRTSOLCORE pSolCore, lwpsinfo_t *pInfo, lwpstatus_t *pStatus, prstatus_t *pDst)
{
- AssertReturnVoid(pVBoxCore);
+ AssertReturnVoid(pSolCore);
AssertReturnVoid(pInfo);
AssertReturnVoid(pStatus);
AssertReturnVoid(pDst);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
memset(pDst, 0, sizeof(prstatus_t));
if (pStatus->pr_flags & PR_STOPPED)
pDst->pr_flags = 0x0001;
@@ -1095,20 +1122,20 @@ static void GetOldProcessStatus(PVBOXCORE pVBoxCore, lwpsinfo_t *pInfo, lwpstatu
memcpy(pDst->pr_sysarg, pStatus->pr_sysarg, sizeof(pDst->pr_sysarg));
RTStrCopy(pDst->pr_clname, sizeof(pDst->pr_clname), pStatus->pr_clname);
- pDst->pr_nlwp = pVBoxProc->ProcStatus.pr_nlwp;
- pDst->pr_sigpend = pVBoxProc->ProcStatus.pr_sigpend;
- pDst->pr_pid = pVBoxProc->ProcStatus.pr_pid;
- pDst->pr_ppid = pVBoxProc->ProcStatus.pr_ppid;
- pDst->pr_pgrp = pVBoxProc->ProcStatus.pr_pgid;
- pDst->pr_sid = pVBoxProc->ProcStatus.pr_sid;
- pDst->pr_utime = pVBoxProc->ProcStatus.pr_utime;
- pDst->pr_stime = pVBoxProc->ProcStatus.pr_stime;
- pDst->pr_cutime = pVBoxProc->ProcStatus.pr_cutime;
- pDst->pr_cstime = pVBoxProc->ProcStatus.pr_cstime;
- pDst->pr_brkbase = (caddr_t)pVBoxProc->ProcStatus.pr_brkbase;
- pDst->pr_brksize = pVBoxProc->ProcStatus.pr_brksize;
- pDst->pr_stkbase = (caddr_t)pVBoxProc->ProcStatus.pr_stkbase;
- pDst->pr_stksize = pVBoxProc->ProcStatus.pr_stksize;
+ pDst->pr_nlwp = pSolProc->ProcStatus.pr_nlwp;
+ pDst->pr_sigpend = pSolProc->ProcStatus.pr_sigpend;
+ pDst->pr_pid = pSolProc->ProcStatus.pr_pid;
+ pDst->pr_ppid = pSolProc->ProcStatus.pr_ppid;
+ pDst->pr_pgrp = pSolProc->ProcStatus.pr_pgid;
+ pDst->pr_sid = pSolProc->ProcStatus.pr_sid;
+ pDst->pr_utime = pSolProc->ProcStatus.pr_utime;
+ pDst->pr_stime = pSolProc->ProcStatus.pr_stime;
+ pDst->pr_cutime = pSolProc->ProcStatus.pr_cutime;
+ pDst->pr_cstime = pSolProc->ProcStatus.pr_cstime;
+ pDst->pr_brkbase = (caddr_t)pSolProc->ProcStatus.pr_brkbase;
+ pDst->pr_brksize = pSolProc->ProcStatus.pr_brksize;
+ pDst->pr_stkbase = (caddr_t)pSolProc->ProcStatus.pr_stkbase;
+ pDst->pr_stksize = pSolProc->ProcStatus.pr_stksize;
pDst->pr_processor = (short)pInfo->pr_onpro;
pDst->pr_bind = (short)pInfo->pr_bindpro;
@@ -1119,19 +1146,19 @@ static void GetOldProcessStatus(PVBOXCORE pVBoxCore, lwpsinfo_t *pInfo, lwpstatu
/**
* Callback for rtCoreDumperForEachThread to suspend a thread.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
* @param pvThreadInfo Opaque pointer to thread information.
*
* @return IPRT status code.
*/
-static int suspendThread(PVBOXCORE pVBoxCore, void *pvThreadInfo)
+static int suspendThread(PRTSOLCORE pSolCore, void *pvThreadInfo)
{
AssertPtrReturn(pvThreadInfo, VERR_INVALID_POINTER);
- NOREF(pVBoxCore);
+ NOREF(pSolCore);
lwpsinfo_t *pThreadInfo = (lwpsinfo_t *)pvThreadInfo;
CORELOG((CORELOG_NAME ":suspendThread %d\n", (lwpid_t)pThreadInfo->pr_lwpid));
- if ((lwpid_t)pThreadInfo->pr_lwpid != pVBoxCore->VBoxProc.hCurThread)
+ if ((lwpid_t)pThreadInfo->pr_lwpid != pSolCore->SolProc.hCurThread)
_lwp_suspend(pThreadInfo->pr_lwpid);
return VINF_SUCCESS;
}
@@ -1140,19 +1167,19 @@ static int suspendThread(PVBOXCORE pVBoxCore, void *pvThreadInfo)
/**
* Callback for rtCoreDumperForEachThread to resume a thread.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
* @param pvThreadInfo Opaque pointer to thread information.
*
* @return IPRT status code.
*/
-static int resumeThread(PVBOXCORE pVBoxCore, void *pvThreadInfo)
+static int resumeThread(PRTSOLCORE pSolCore, void *pvThreadInfo)
{
AssertPtrReturn(pvThreadInfo, VERR_INVALID_POINTER);
- NOREF(pVBoxCore);
+ NOREF(pSolCore);
lwpsinfo_t *pThreadInfo = (lwpsinfo_t *)pvThreadInfo;
CORELOG((CORELOG_NAME ":resumeThread %d\n", (lwpid_t)pThreadInfo->pr_lwpid));
- if ((lwpid_t)pThreadInfo->pr_lwpid != (lwpid_t)pVBoxCore->VBoxProc.hCurThread)
+ if ((lwpid_t)pThreadInfo->pr_lwpid != (lwpid_t)pSolCore->SolProc.hCurThread)
_lwp_continue(pThreadInfo->pr_lwpid);
return VINF_SUCCESS;
}
@@ -1161,44 +1188,42 @@ static int resumeThread(PVBOXCORE pVBoxCore, void *pvThreadInfo)
/**
* Calls a thread worker function for all threads in the process as described by /proc
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
* @param pcThreads Number of threads read.
* @param pfnWorker Callback function for each thread.
*
* @return IPRT status code.
*/
-static int rtCoreDumperForEachThread(PVBOXCORE pVBoxCore, uint64_t *pcThreads, PFNCORETHREADWORKER pfnWorker)
+static int rtCoreDumperForEachThread(PRTSOLCORE pSolCore, uint64_t *pcThreads, PFNRTSOLCORETHREADWORKER pfnWorker)
{
- AssertPtrReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertPtrReturn(pSolCore, VERR_INVALID_POINTER);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
/*
* Read the information for threads.
* Format: prheader_t + array of lwpsinfo_t's.
*/
char szLpsInfoPath[PATH_MAX];
- RTStrPrintf(szLpsInfoPath, sizeof(szLpsInfoPath), "/proc/%d/lpsinfo", (int)pVBoxProc->Process);
+ RTStrPrintf(szLpsInfoPath, sizeof(szLpsInfoPath), "/proc/%d/lpsinfo", (int)pSolProc->Process);
int rc = VINF_SUCCESS;
int fd = open(szLpsInfoPath, O_RDONLY);
if (fd >= 0)
{
- RTFILE hFile = fd;
- uint64_t u64Size;
- RTFileGetSize(hFile, &u64Size);
- size_t cbInfoHdrAndData = u64Size < ~(size_t)0 ? u64Size : ~(size_t)0;
- void *pvInfoHdr = mmap(NULL, cbInfoHdrAndData, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1 /* fd */, 0 /* offset */);
+ size_t cbInfoHdrAndData = GetFileSizeByFd(fd);
+ void *pvInfoHdr = mmap(NULL, cbInfoHdrAndData, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,
+ -1 /* fd */, 0 /* offset */);
if (pvInfoHdr != MAP_FAILED)
{
- rc = RTFileRead(hFile, pvInfoHdr, cbInfoHdrAndData, NULL);
+ rc = ReadFileNoIntr(fd, pvInfoHdr, cbInfoHdrAndData);
if (RT_SUCCESS(rc))
{
prheader_t *pHeader = (prheader_t *)pvInfoHdr;
lwpsinfo_t *pThreadInfo = (lwpsinfo_t *)((uintptr_t)pvInfoHdr + sizeof(prheader_t));
for (long i = 0; i < pHeader->pr_nent; i++)
{
- pfnWorker(pVBoxCore, pThreadInfo);
+ pfnWorker(pSolCore, pThreadInfo);
pThreadInfo = (lwpsinfo_t *)((uintptr_t)pThreadInfo + pHeader->pr_entsize);
}
if (pcThreads)
@@ -1209,7 +1234,7 @@ static int rtCoreDumperForEachThread(PVBOXCORE pVBoxCore, uint64_t *pcThreads,
}
else
rc = VERR_NO_MEMORY;
- RTFileClose(hFile);
+ close(fd);
}
else
rc = RTErrConvertFromErrno(rc);
@@ -1221,26 +1246,26 @@ static int rtCoreDumperForEachThread(PVBOXCORE pVBoxCore, uint64_t *pcThreads,
/**
* Resume all threads of this process.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @return IPRT status code..
*/
-static int rtCoreDumperResumeThreads(PVBOXCORE pVBoxCore)
+static int rtCoreDumperResumeThreads(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
#if 1
uint64_t cThreads;
- return rtCoreDumperForEachThread(pVBoxCore, &cThreads, resumeThread);
+ return rtCoreDumperForEachThread(pSolCore, &cThreads, resumeThread);
#else
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
char szCurThread[128];
char szPath[PATH_MAX];
PRTDIR pDir = NULL;
- RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/lwp", (int)pVBoxProc->Process);
- RTStrPrintf(szCurThread, sizeof(szCurThread), "%d", (int)pVBoxProc->hCurThread);
+ RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/lwp", (int)pSolProc->Process);
+ RTStrPrintf(szCurThread, sizeof(szCurThread), "%d", (int)pSolProc->hCurThread);
int32_t cRunningThreads = 0;
int rc = RTDirOpen(&pDir, szPath);
@@ -1280,13 +1305,13 @@ static int rtCoreDumperResumeThreads(PVBOXCORE pVBoxCore)
/**
* Stop all running threads of this process except the current one.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @return IPRT status code.
*/
-static int rtCoreDumperSuspendThreads(PVBOXCORE pVBoxCore)
+static int rtCoreDumperSuspendThreads(PRTSOLCORE pSolCore)
{
- AssertPtrReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertPtrReturn(pSolCore, VERR_INVALID_POINTER);
/*
* This function tries to ensures while we suspend threads, no newly spawned threads
@@ -1302,7 +1327,7 @@ static int rtCoreDumperSuspendThreads(PVBOXCORE pVBoxCore)
size_t cb = 0;
for (cTries = 0; cTries < RT_ELEMENTS(aThreads); cTries++)
{
- rc = rtCoreDumperForEachThread(pVBoxCore, &aThreads[cTries], suspendThread);
+ rc = rtCoreDumperForEachThread(pSolCore, &aThreads[cTries], suspendThread);
if (RT_FAILURE(rc))
break;
}
@@ -1314,14 +1339,14 @@ static int rtCoreDumperSuspendThreads(PVBOXCORE pVBoxCore)
}
return rc;
#else
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
char szCurThread[128];
char szPath[PATH_MAX];
PRTDIR pDir = NULL;
- RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/lwp", (int)pVBoxProc->Process);
- RTStrPrintf(szCurThread, sizeof(szCurThread), "%d", (int)pVBoxProc->hCurThread);
+ RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/lwp", (int)pSolProc->Process);
+ RTStrPrintf(szCurThread, sizeof(szCurThread), "%d", (int)pSolProc->hCurThread);
int rc = -1;
uint32_t cThreads = 0;
@@ -1390,20 +1415,20 @@ static inline size_t ElfNoteHeaderSize(size_t cb)
/**
* Write an ELF NOTE header into the core file.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
* @param Type Type of this NOTE section.
* @param pcv Opaque pointer to the data, if NULL only computes size.
* @param cb Size of the data.
*
* @return IPRT status code.
*/
-static int ElfWriteNoteHeader(PVBOXCORE pVBoxCore, uint_t Type, const void *pcv, size_t cb)
+static int ElfWriteNoteHeader(PRTSOLCORE pSolCore, uint_t Type, const void *pcv, size_t cb)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
AssertReturn(pcv, VERR_INVALID_POINTER);
AssertReturn(cb > 0, VERR_NO_DATA);
- AssertReturn(pVBoxCore->pfnWriter, VERR_WRITE_ERROR);
- AssertReturn(pVBoxCore->hCoreFile, VERR_INVALID_HANDLE);
+ AssertReturn(pSolCore->pfnWriter, VERR_WRITE_ERROR);
+ AssertReturn(pSolCore->fdCoreFile >= 0, VERR_INVALID_HANDLE);
int rc = VERR_GENERAL_FAILURE;
#ifdef RT_OS_SOLARIS
@@ -1427,14 +1452,14 @@ static int ElfWriteNoteHeader(PVBOXCORE pVBoxCore, uint_t Type, const void *pcv,
/*
* Write note header and description.
*/
- rc = pVBoxCore->pfnWriter(pVBoxCore->hCoreFile, &ElfNoteHdr, sizeof(ElfNoteHdr));
+ rc = pSolCore->pfnWriter(pSolCore->fdCoreFile, &ElfNoteHdr, sizeof(ElfNoteHdr));
if (RT_SUCCESS(rc))
{
- rc = pVBoxCore->pfnWriter(pVBoxCore->hCoreFile, pcv, cb);
+ rc = pSolCore->pfnWriter(pSolCore->fdCoreFile, pcv, cb);
if (RT_SUCCESS(rc))
{
if (cbAlign > cb)
- rc = pVBoxCore->pfnWriter(pVBoxCore->hCoreFile, s_achPad, cbAlign - cb);
+ rc = pSolCore->pfnWriter(pSolCore->fdCoreFile, s_achPad, cbAlign - cb);
}
}
@@ -1451,24 +1476,24 @@ static int ElfWriteNoteHeader(PVBOXCORE pVBoxCore, uint_t Type, const void *pcv,
* Computes the size of NOTE section for the given core type.
* Solaris has two types of program header information (new and old).
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
* @param enmType Type of core file information required.
*
* @return Size of NOTE section.
*/
-static size_t ElfNoteSectionSize(PVBOXCORE pVBoxCore, VBOXSOLCORETYPE enmType)
+static size_t ElfNoteSectionSize(PRTSOLCORE pSolCore, RTSOLCORETYPE enmType)
{
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
size_t cb = 0;
switch (enmType)
{
case enmOldEra:
{
cb += ElfNoteHeaderSize(sizeof(prpsinfo_t));
- cb += ElfNoteHeaderSize(pVBoxProc->cAuxVecs * sizeof(auxv_t));
- cb += ElfNoteHeaderSize(strlen(pVBoxProc->szPlatform));
+ cb += ElfNoteHeaderSize(pSolProc->cAuxVecs * sizeof(auxv_t));
+ cb += ElfNoteHeaderSize(strlen(pSolProc->szPlatform));
- PVBOXSOLTHREADINFO pThreadInfo = pVBoxProc->pThreadInfoHead;
+ PRTSOLCORETHREADINFO pThreadInfo = pSolProc->pThreadInfoHead;
while (pThreadInfo)
{
if (pThreadInfo->pStatus)
@@ -1486,23 +1511,23 @@ static size_t ElfNoteSectionSize(PVBOXCORE pVBoxCore, VBOXSOLCORETYPE enmType)
{
cb += ElfNoteHeaderSize(sizeof(psinfo_t));
cb += ElfNoteHeaderSize(sizeof(pstatus_t));
- cb += ElfNoteHeaderSize(pVBoxProc->cAuxVecs * sizeof(auxv_t));
- cb += ElfNoteHeaderSize(strlen(pVBoxProc->szPlatform) + 1);
+ cb += ElfNoteHeaderSize(pSolProc->cAuxVecs * sizeof(auxv_t));
+ cb += ElfNoteHeaderSize(strlen(pSolProc->szPlatform) + 1);
cb += ElfNoteHeaderSize(sizeof(struct utsname));
cb += ElfNoteHeaderSize(sizeof(core_content_t));
- cb += ElfNoteHeaderSize(pVBoxProc->cbCred);
+ cb += ElfNoteHeaderSize(pSolProc->cbCred);
- if (pVBoxProc->pPriv)
- cb += ElfNoteHeaderSize(PRIV_PRPRIV_SIZE(pVBoxProc->pPriv)); /* Ought to be same as cbPriv!? */
+ if (pSolProc->pPriv)
+ cb += ElfNoteHeaderSize(PRIV_PRPRIV_SIZE(pSolProc->pPriv)); /* Ought to be same as cbPriv!? */
- if (pVBoxProc->pcPrivImpl)
- cb += ElfNoteHeaderSize(PRIV_IMPL_INFO_SIZE(pVBoxProc->pcPrivImpl));
+ if (pSolProc->pcPrivImpl)
+ cb += ElfNoteHeaderSize(PRIV_IMPL_INFO_SIZE(pSolProc->pcPrivImpl));
- cb += ElfNoteHeaderSize(strlen(pVBoxProc->szZoneName) + 1);
- if (pVBoxProc->cbLdt > 0)
- cb += ElfNoteHeaderSize(pVBoxProc->cbLdt);
+ cb += ElfNoteHeaderSize(strlen(pSolProc->szZoneName) + 1);
+ if (pSolProc->cbLdt > 0)
+ cb += ElfNoteHeaderSize(pSolProc->cbLdt);
- PVBOXSOLTHREADINFO pThreadInfo = pVBoxProc->pThreadInfoHead;
+ PRTSOLCORETHREADINFO pThreadInfo = pSolProc->pThreadInfoHead;
while (pThreadInfo)
{
cb += ElfNoteHeaderSize(sizeof(lwpsinfo_t));
@@ -1530,20 +1555,20 @@ static size_t ElfNoteSectionSize(PVBOXCORE pVBoxCore, VBOXSOLCORETYPE enmType)
* Write the note section for the given era into the core file.
* Solaris has two types of program header information (new and old).
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
* @param enmType Type of core file information required.
*
* @return IPRT status code.
*/
-static int ElfWriteNoteSection(PVBOXCORE pVBoxCore, VBOXSOLCORETYPE enmType)
+static int ElfWriteNoteSection(PRTSOLCORE pSolCore, RTSOLCORETYPE enmType)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
int rc = VERR_GENERAL_FAILURE;
#ifdef RT_OS_SOLARIS
- typedef int (*PFNELFWRITENOTEHDR)(PVBOXCORE pVBoxCore, uint_t, const void *pcv, size_t cb);
+ typedef int (*PFNELFWRITENOTEHDR)(PRTSOLCORE pSolCore, uint_t, const void *pcv, size_t cb);
typedef struct ELFWRITENOTE
{
const char *pszType;
@@ -1558,14 +1583,14 @@ static int ElfWriteNoteSection(PVBOXCORE pVBoxCore, VBOXSOLCORETYPE enmType)
{
ELFWRITENOTE aElfNotes[] =
{
- { "NT_PRPSINFO", NT_PRPSINFO, &pVBoxProc->ProcInfoOld, sizeof(prpsinfo_t) },
- { "NT_AUXV", NT_AUXV, pVBoxProc->pAuxVecs, pVBoxProc->cAuxVecs * sizeof(auxv_t) },
- { "NT_PLATFORM", NT_PLATFORM, pVBoxProc->szPlatform, strlen(pVBoxProc->szPlatform) + 1 }
+ { "NT_PRPSINFO", NT_PRPSINFO, &pSolProc->ProcInfoOld, sizeof(prpsinfo_t) },
+ { "NT_AUXV", NT_AUXV, pSolProc->pAuxVecs, pSolProc->cAuxVecs * sizeof(auxv_t) },
+ { "NT_PLATFORM", NT_PLATFORM, pSolProc->szPlatform, strlen(pSolProc->szPlatform) + 1 }
};
for (unsigned i = 0; i < RT_ELEMENTS(aElfNotes); i++)
{
- rc = ElfWriteNoteHeader(pVBoxCore, aElfNotes[i].Type, aElfNotes[i].pcv, aElfNotes[i].cb);
+ rc = ElfWriteNoteHeader(pSolCore, aElfNotes[i].Type, aElfNotes[i].pcv, aElfNotes[i].cb);
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "ElfWriteNoteSection: ElfWriteNoteHeader failed for %s. rc=%Rrc\n", aElfNotes[i].pszType, rc));
@@ -1577,18 +1602,18 @@ static int ElfWriteNoteSection(PVBOXCORE pVBoxCore, VBOXSOLCORETYPE enmType)
* Write old-style thread info., they contain nothing about zombies,
* so we just skip if there is no status information for them.
*/
- PVBOXSOLTHREADINFO pThreadInfo = pVBoxProc->pThreadInfoHead;
+ PRTSOLCORETHREADINFO pThreadInfo = pSolProc->pThreadInfoHead;
for (; pThreadInfo; pThreadInfo = pThreadInfo->pNext)
{
if (!pThreadInfo->pStatus)
continue;
prstatus_t OldProcessStatus;
- GetOldProcessStatus(pVBoxCore, &pThreadInfo->Info, pThreadInfo->pStatus, &OldProcessStatus);
- rc = ElfWriteNoteHeader(pVBoxCore, NT_PRSTATUS, &OldProcessStatus, sizeof(prstatus_t));
+ GetOldProcessStatus(pSolCore, &pThreadInfo->Info, pThreadInfo->pStatus, &OldProcessStatus);
+ rc = ElfWriteNoteHeader(pSolCore, NT_PRSTATUS, &OldProcessStatus, sizeof(prstatus_t));
if (RT_SUCCESS(rc))
{
- rc = ElfWriteNoteHeader(pVBoxCore, NT_PRFPREG, &pThreadInfo->pStatus->pr_fpreg, sizeof(prfpregset_t));
+ rc = ElfWriteNoteHeader(pSolCore, NT_PRFPREG, &pThreadInfo->pStatus->pr_fpreg, sizeof(prfpregset_t));
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "ElfWriteSegment: ElfWriteNote failed for NT_PRFPREF. rc=%Rrc\n", rc));
@@ -1608,21 +1633,21 @@ static int ElfWriteNoteSection(PVBOXCORE pVBoxCore, VBOXSOLCORETYPE enmType)
{
ELFWRITENOTE aElfNotes[] =
{
- { "NT_PSINFO", NT_PSINFO, &pVBoxProc->ProcInfo, sizeof(psinfo_t) },
- { "NT_PSTATUS", NT_PSTATUS, &pVBoxProc->ProcStatus, sizeof(pstatus_t) },
- { "NT_AUXV", NT_AUXV, pVBoxProc->pAuxVecs, pVBoxProc->cAuxVecs * sizeof(auxv_t) },
- { "NT_PLATFORM", NT_PLATFORM, pVBoxProc->szPlatform, strlen(pVBoxProc->szPlatform) + 1 },
- { "NT_UTSNAME", NT_UTSNAME, &pVBoxProc->UtsName, sizeof(struct utsname) },
- { "NT_CONTENT", NT_CONTENT, &pVBoxProc->CoreContent, sizeof(core_content_t) },
- { "NT_PRCRED", NT_PRCRED, pVBoxProc->pvCred, pVBoxProc->cbCred },
- { "NT_PRPRIV", NT_PRPRIV, pVBoxProc->pPriv, PRIV_PRPRIV_SIZE(pVBoxProc->pPriv) },
- { "NT_PRPRIVINFO", NT_PRPRIVINFO, pVBoxProc->pcPrivImpl, PRIV_IMPL_INFO_SIZE(pVBoxProc->pcPrivImpl) },
- { "NT_ZONENAME", NT_ZONENAME, pVBoxProc->szZoneName, strlen(pVBoxProc->szZoneName) + 1 }
+ { "NT_PSINFO", NT_PSINFO, &pSolProc->ProcInfo, sizeof(psinfo_t) },
+ { "NT_PSTATUS", NT_PSTATUS, &pSolProc->ProcStatus, sizeof(pstatus_t) },
+ { "NT_AUXV", NT_AUXV, pSolProc->pAuxVecs, pSolProc->cAuxVecs * sizeof(auxv_t) },
+ { "NT_PLATFORM", NT_PLATFORM, pSolProc->szPlatform, strlen(pSolProc->szPlatform) + 1 },
+ { "NT_UTSNAME", NT_UTSNAME, &pSolProc->UtsName, sizeof(struct utsname) },
+ { "NT_CONTENT", NT_CONTENT, &pSolProc->CoreContent, sizeof(core_content_t) },
+ { "NT_PRCRED", NT_PRCRED, pSolProc->pvCred, pSolProc->cbCred },
+ { "NT_PRPRIV", NT_PRPRIV, pSolProc->pPriv, PRIV_PRPRIV_SIZE(pSolProc->pPriv) },
+ { "NT_PRPRIVINFO", NT_PRPRIVINFO, pSolProc->pcPrivImpl, PRIV_IMPL_INFO_SIZE(pSolProc->pcPrivImpl) },
+ { "NT_ZONENAME", NT_ZONENAME, pSolProc->szZoneName, strlen(pSolProc->szZoneName) + 1 }
};
for (unsigned i = 0; i < RT_ELEMENTS(aElfNotes); i++)
{
- rc = ElfWriteNoteHeader(pVBoxCore, aElfNotes[i].Type, aElfNotes[i].pcv, aElfNotes[i].cb);
+ rc = ElfWriteNoteHeader(pSolCore, aElfNotes[i].Type, aElfNotes[i].pcv, aElfNotes[i].cb);
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "ElfWriteNoteSection: ElfWriteNoteHeader failed for %s. rc=%Rrc\n", aElfNotes[i].pszType, rc));
@@ -1634,10 +1659,10 @@ static int ElfWriteNoteSection(PVBOXCORE pVBoxCore, VBOXSOLCORETYPE enmType)
* Write new-style thread info., missing lwpstatus_t indicates it's a zombie thread
* we only dump the lwpsinfo_t in that case.
*/
- PVBOXSOLTHREADINFO pThreadInfo = pVBoxProc->pThreadInfoHead;
+ PRTSOLCORETHREADINFO pThreadInfo = pSolProc->pThreadInfoHead;
for (; pThreadInfo; pThreadInfo = pThreadInfo->pNext)
{
- rc = ElfWriteNoteHeader(pVBoxCore, NT_LWPSINFO, &pThreadInfo->Info, sizeof(lwpsinfo_t));
+ rc = ElfWriteNoteHeader(pSolCore, NT_LWPSINFO, &pThreadInfo->Info, sizeof(lwpsinfo_t));
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "ElfWriteNoteSection: ElfWriteNoteHeader for NT_LWPSINFO failed. rc=%Rrc\n", rc));
@@ -1646,7 +1671,7 @@ static int ElfWriteNoteSection(PVBOXCORE pVBoxCore, VBOXSOLCORETYPE enmType)
if (pThreadInfo->pStatus)
{
- rc = ElfWriteNoteHeader(pVBoxCore, NT_LWPSTATUS, pThreadInfo->pStatus, sizeof(lwpstatus_t));
+ rc = ElfWriteNoteHeader(pSolCore, NT_LWPSTATUS, pThreadInfo->pStatus, sizeof(lwpstatus_t));
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "ElfWriteNoteSection: ElfWriteNoteHeader for NT_LWPSTATUS failed. rc=%Rrc\n", rc));
@@ -1674,16 +1699,16 @@ static int ElfWriteNoteSection(PVBOXCORE pVBoxCore, VBOXSOLCORETYPE enmType)
/**
* Write mappings into the core file.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @return IPRT status code.
*/
-static int ElfWriteMappings(PVBOXCORE pVBoxCore)
+static int ElfWriteMappings(PRTSOLCORE pSolCore)
{
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
int rc = VERR_GENERAL_FAILURE;
- PVBOXSOLMAPINFO pMapInfo = pVBoxProc->pMapInfoHead;
+ PRTSOLCOREMAPINFO pMapInfo = pSolProc->pMapInfoHead;
while (pMapInfo)
{
if (!pMapInfo->fError)
@@ -1693,14 +1718,14 @@ static int ElfWriteMappings(PVBOXCORE pVBoxCore)
while (k < pMapInfo->pMap.pr_size)
{
size_t cb = RT_MIN(sizeof(achBuf), pMapInfo->pMap.pr_size - k);
- int rc2 = ProcReadAddrSpace(pVBoxProc, pMapInfo->pMap.pr_vaddr + k, &achBuf, cb);
+ int rc2 = ProcReadAddrSpace(pSolProc, pMapInfo->pMap.pr_vaddr + k, &achBuf, cb);
if (RT_FAILURE(rc2))
{
CORELOGRELSYS((CORELOG_NAME "ElfWriteMappings: Failed to read mapping, can't recover. Bye. rc=%Rrc\n", rc));
return VERR_INVALID_STATE;
}
- rc = pVBoxCore->pfnWriter(pVBoxCore->hCoreFile, achBuf, sizeof(achBuf));
+ rc = pSolCore->pfnWriter(pSolCore->fdCoreFile, achBuf, sizeof(achBuf));
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "ElfWriteMappings: pfnWriter failed. rc=%Rrc\n", rc));
@@ -1716,7 +1741,7 @@ static int ElfWriteMappings(PVBOXCORE pVBoxCore)
memcpy(achBuf, &pMapInfo->fError, sizeof(pMapInfo->fError));
if (sizeof(achBuf) != pMapInfo->pMap.pr_size)
CORELOGRELSYS((CORELOG_NAME "ElfWriteMappings: Huh!? something is wrong!\n"));
- rc = pVBoxCore->pfnWriter(pVBoxCore->hCoreFile, &achBuf, sizeof(achBuf));
+ rc = pSolCore->pfnWriter(pSolCore->fdCoreFile, &achBuf, sizeof(achBuf));
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "ElfWriteMappings: pfnWriter(2) failed. rc=%Rrc\n", rc));
@@ -1734,25 +1759,25 @@ static int ElfWriteMappings(PVBOXCORE pVBoxCore)
/**
* Write program headers for all mappings into the core file.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @return IPRT status code.
*/
-static int ElfWriteMappingHeaders(PVBOXCORE pVBoxCore)
+static int ElfWriteMappingHeaders(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
Elf_Phdr ProgHdr;
RT_ZERO(ProgHdr);
ProgHdr.p_type = PT_LOAD;
int rc = VERR_GENERAL_FAILURE;
- PVBOXSOLMAPINFO pMapInfo = pVBoxProc->pMapInfoHead;
+ PRTSOLCOREMAPINFO pMapInfo = pSolProc->pMapInfoHead;
while (pMapInfo)
{
ProgHdr.p_vaddr = pMapInfo->pMap.pr_vaddr; /* Virtual address of this mapping in the process address space */
- ProgHdr.p_offset = pVBoxCore->offWrite; /* Where this mapping is located in the core file */
+ ProgHdr.p_offset = pSolCore->offWrite; /* Where this mapping is located in the core file */
ProgHdr.p_memsz = pMapInfo->pMap.pr_size; /* Size of the memory image of the mapping */
ProgHdr.p_filesz = pMapInfo->pMap.pr_size; /* Size of the file image of the mapping */
@@ -1767,14 +1792,14 @@ static int ElfWriteMappingHeaders(PVBOXCORE pVBoxCore)
if (pMapInfo->fError)
ProgHdr.p_flags |= PF_SUNW_FAILURE;
- rc = pVBoxCore->pfnWriter(pVBoxCore->hCoreFile, &ProgHdr, sizeof(ProgHdr));
+ rc = pSolCore->pfnWriter(pSolCore->fdCoreFile, &ProgHdr, sizeof(ProgHdr));
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "ElfWriteMappingHeaders: pfnWriter failed. rc=%Rrc\n", rc));
return rc;
}
- pVBoxCore->offWrite += ProgHdr.p_filesz;
+ pSolCore->offWrite += ProgHdr.p_filesz;
pMapInfo = pMapInfo->pNext;
}
return rc;
@@ -1785,31 +1810,31 @@ static int ElfWriteMappingHeaders(PVBOXCORE pVBoxCore)
* Write a prepared core file using a user-passed in writer function, requires all threads
* to be in suspended state (i.e. called after CreateCore).
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
* @param pfnWriter Pointer to the writer function to override default writer (NULL uses default).
*
* @remarks Resumes all suspended threads, unless it's an invalid core. This
* function must be called only -after- rtCoreDumperCreateCore().
- * @return VBox status.
+ * @return IPRT status.
*/
-static int rtCoreDumperWriteCore(PVBOXCORE pVBoxCore, PFNCOREWRITER pfnWriter)
+static int rtCoreDumperWriteCore(PRTSOLCORE pSolCore, PFNRTCOREWRITER pfnWriter)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
- if (!pVBoxCore->fIsValid)
+ if (!pSolCore->fIsValid)
return VERR_INVALID_STATE;
if (pfnWriter)
- pVBoxCore->pfnWriter = pfnWriter;
+ pSolCore->pfnWriter = pfnWriter;
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
char szPath[PATH_MAX];
int rc = VINF_SUCCESS;
/*
* Open the process address space file.
*/
- RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/as", (int)pVBoxProc->Process);
+ RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/as", (int)pSolProc->Process);
int fd = open(szPath, O_RDONLY);
if (fd < 0)
{
@@ -1818,23 +1843,23 @@ static int rtCoreDumperWriteCore(PVBOXCORE pVBoxCore, PFNCOREWRITER pfnWriter)
goto WriteCoreDone;
}
- pVBoxProc->hAs = fd;
+ pSolProc->fdAs = fd;
/*
* Create the core file.
*/
- fd = open(pVBoxCore->szCorePath, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR);
+ fd = open(pSolCore->szCorePath, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR);
if (fd < 0)
{
rc = RTErrConvertFromErrno(fd);
- CORELOGRELSYS((CORELOG_NAME "WriteCore: failed to open %s. rc=%Rrc\n", pVBoxCore->szCorePath, rc));
+ CORELOGRELSYS((CORELOG_NAME "WriteCore: failed to open %s. rc=%Rrc\n", pSolCore->szCorePath, rc));
goto WriteCoreDone;
}
- pVBoxCore->hCoreFile = fd;
+ pSolCore->fdCoreFile = fd;
- pVBoxCore->offWrite = 0;
- uint32_t cProgHdrs = pVBoxProc->cMappings + 2; /* two PT_NOTE program headers (old, new style) */
+ pSolCore->offWrite = 0;
+ uint32_t cProgHdrs = pSolProc->cMappings + 2; /* two PT_NOTE program headers (old, new style) */
/*
* Write the ELF header.
@@ -1863,7 +1888,7 @@ static int rtCoreDumperWriteCore(PVBOXCORE pVBoxCore, PFNCOREWRITER pfnWriter)
ElfHdr.e_phoff = sizeof(ElfHdr);
ElfHdr.e_phentsize = sizeof(Elf_Phdr);
ElfHdr.e_shentsize = sizeof(Elf_Shdr);
- rc = pVBoxCore->pfnWriter(pVBoxCore->hCoreFile, &ElfHdr, sizeof(ElfHdr));
+ rc = pSolCore->pfnWriter(pSolCore->fdCoreFile, &ElfHdr, sizeof(ElfHdr));
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "WriteCore: pfnWriter failed writing ELF header. rc=%Rrc\n", rc));
@@ -1881,10 +1906,10 @@ static int rtCoreDumperWriteCore(PVBOXCORE pVBoxCore, PFNCOREWRITER pfnWriter)
/*
* Write old-style NOTE program header.
*/
- pVBoxCore->offWrite += sizeof(ElfHdr) + cProgHdrs * sizeof(ProgHdr);
- ProgHdr.p_offset = pVBoxCore->offWrite;
- ProgHdr.p_filesz = ElfNoteSectionSize(pVBoxCore, enmOldEra);
- rc = pVBoxCore->pfnWriter(pVBoxCore->hCoreFile, &ProgHdr, sizeof(ProgHdr));
+ pSolCore->offWrite += sizeof(ElfHdr) + cProgHdrs * sizeof(ProgHdr);
+ ProgHdr.p_offset = pSolCore->offWrite;
+ ProgHdr.p_filesz = ElfNoteSectionSize(pSolCore, enmOldEra);
+ rc = pSolCore->pfnWriter(pSolCore->fdCoreFile, &ProgHdr, sizeof(ProgHdr));
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "WriteCore: pfnWriter failed writing old-style ELF program Header. rc=%Rrc\n", rc));
@@ -1894,10 +1919,10 @@ static int rtCoreDumperWriteCore(PVBOXCORE pVBoxCore, PFNCOREWRITER pfnWriter)
/*
* Write new-style NOTE program header.
*/
- pVBoxCore->offWrite += ProgHdr.p_filesz;
- ProgHdr.p_offset = pVBoxCore->offWrite;
- ProgHdr.p_filesz = ElfNoteSectionSize(pVBoxCore, enmNewEra);
- rc = pVBoxCore->pfnWriter(pVBoxCore->hCoreFile, &ProgHdr, sizeof(ProgHdr));
+ pSolCore->offWrite += ProgHdr.p_filesz;
+ ProgHdr.p_offset = pSolCore->offWrite;
+ ProgHdr.p_filesz = ElfNoteSectionSize(pSolCore, enmNewEra);
+ rc = pSolCore->pfnWriter(pSolCore->fdCoreFile, &ProgHdr, sizeof(ProgHdr));
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "WriteCore: pfnWriter failed writing new-style ELF program header. rc=%Rrc\n", rc));
@@ -1907,8 +1932,8 @@ static int rtCoreDumperWriteCore(PVBOXCORE pVBoxCore, PFNCOREWRITER pfnWriter)
/*
* Write program headers per mapping.
*/
- pVBoxCore->offWrite += ProgHdr.p_filesz;
- rc = ElfWriteMappingHeaders(pVBoxCore);
+ pSolCore->offWrite += ProgHdr.p_filesz;
+ rc = ElfWriteMappingHeaders(pSolCore);
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "Write: ElfWriteMappings failed. rc=%Rrc\n", rc));
@@ -1918,7 +1943,7 @@ static int rtCoreDumperWriteCore(PVBOXCORE pVBoxCore, PFNCOREWRITER pfnWriter)
/*
* Write old-style note section.
*/
- rc = ElfWriteNoteSection(pVBoxCore, enmOldEra);
+ rc = ElfWriteNoteSection(pSolCore, enmOldEra);
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "WriteCore: ElfWriteNoteSection old-style failed. rc=%Rrc\n", rc));
@@ -1928,7 +1953,7 @@ static int rtCoreDumperWriteCore(PVBOXCORE pVBoxCore, PFNCOREWRITER pfnWriter)
/*
* Write new-style section.
*/
- rc = ElfWriteNoteSection(pVBoxCore, enmNewEra);
+ rc = ElfWriteNoteSection(pSolCore, enmNewEra);
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "WriteCore: ElfWriteNoteSection new-style failed. rc=%Rrc\n", rc));
@@ -1938,7 +1963,7 @@ static int rtCoreDumperWriteCore(PVBOXCORE pVBoxCore, PFNCOREWRITER pfnWriter)
/*
* Write all mappings.
*/
- rc = ElfWriteMappings(pVBoxCore);
+ rc = ElfWriteMappings(pSolCore);
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "WriteCore: ElfWriteMappings failed. rc=%Rrc\n", rc));
@@ -1947,19 +1972,19 @@ static int rtCoreDumperWriteCore(PVBOXCORE pVBoxCore, PFNCOREWRITER pfnWriter)
WriteCoreDone:
- if (pVBoxCore->hCoreFile != NIL_RTFILE) /* Initialized in rtCoreDumperCreateCore() */
+ if (pSolCore->fdCoreFile != -1) /* Initialized in rtCoreDumperCreateCore() */
{
- RTFileClose(pVBoxCore->hCoreFile);
- pVBoxCore->hCoreFile = NIL_RTFILE;
+ close(pSolCore->fdCoreFile);
+ pSolCore->fdCoreFile = -1;
}
- if (pVBoxProc->hAs != NIL_RTFILE) /* Initialized in rtCoreDumperCreateCore() */
+ if (pSolProc->fdAs != -1) /* Initialized in rtCoreDumperCreateCore() */
{
- RTFileClose(pVBoxProc->hAs);
- pVBoxProc->hAs = NIL_RTFILE;
+ close(pSolProc->fdAs);
+ pSolProc->fdAs = -1;
}
- rtCoreDumperResumeThreads(pVBoxCore);
+ rtCoreDumperResumeThreads(pSolCore);
return rc;
}
@@ -1969,7 +1994,7 @@ WriteCoreDone:
* all threads which can lead to things like spurious wakeups of threads (if and when threads
* are ultimately resumed en-masse) already suspended while calling this function.
*
- * @param pVBoxCore Pointer to a core object.
+ * @param pSolCore Pointer to a core object.
* @param pContext Pointer to the caller context thread.
* @param pszCoreFilePath Path to the core file. If NULL is passed, the global
* path specified in RTCoreDumperSetup() would be used.
@@ -1977,29 +2002,29 @@ WriteCoreDone:
* @remarks Halts all threads.
* @return IPRT status code.
*/
-static int rtCoreDumperCreateCore(PVBOXCORE pVBoxCore, ucontext_t *pContext, const char *pszCoreFilePath)
+static int rtCoreDumperCreateCore(PRTSOLCORE pSolCore, ucontext_t *pContext, const char *pszCoreFilePath)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
AssertReturn(pContext, VERR_INVALID_POINTER);
/*
* Initialize core structures.
*/
- memset(pVBoxCore, 0, sizeof(VBOXCORE));
- pVBoxCore->pfnReader = &ReadFileNoIntr;
- pVBoxCore->pfnWriter = &WriteFileNoIntr;
- pVBoxCore->fIsValid = false;
- pVBoxCore->hCoreFile = NIL_RTFILE;
-
- PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
- pVBoxProc->Process = RTProcSelf();
- pVBoxProc->hCurThread = _lwp_self(); /* thr_self() */
- pVBoxProc->hAs = NIL_RTFILE;
- pVBoxProc->pCurThreadCtx = pContext;
- pVBoxProc->CoreContent = CC_CONTENT_DEFAULT;
-
- RTProcGetExecutablePath(pVBoxProc->szExecPath, sizeof(pVBoxProc->szExecPath)); /* this gets full path not just name */
- pVBoxProc->pszExecName = RTPathFilename(pVBoxProc->szExecPath);
+ memset(pSolCore, 0, sizeof(RTSOLCORE));
+ pSolCore->pfnReader = &ReadFileNoIntr;
+ pSolCore->pfnWriter = &WriteFileNoIntr;
+ pSolCore->fIsValid = false;
+ pSolCore->fdCoreFile = -1;
+
+ PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
+ pSolProc->Process = RTProcSelf();
+ pSolProc->hCurThread = _lwp_self(); /* thr_self() */
+ pSolProc->fdAs = -1;
+ pSolProc->pCurThreadCtx = pContext;
+ pSolProc->CoreContent = CC_CONTENT_DEFAULT;
+
+ RTProcGetExecutablePath(pSolProc->szExecPath, sizeof(pSolProc->szExecPath)); /* this gets full path not just name */
+ pSolProc->pszExecName = RTPathFilename(pSolProc->szExecPath);
/*
* If a path has been specified, use it. Otherwise use the global path.
@@ -2015,42 +2040,42 @@ static int rtCoreDumperCreateCore(PVBOXCORE pVBoxCore, ucontext_t *pContext, con
if (g_szCoreDumpFile[0] == '\0')
{
/* We cannot call RTPathAbs*() as they call getcwd() which calls malloc. */
- RTStrPrintf(pVBoxCore->szCorePath, sizeof(pVBoxCore->szCorePath), "%s/core.vb.%s.%d",
- g_szCoreDumpDir, pVBoxProc->pszExecName, (int)pVBoxProc->Process);
+ RTStrPrintf(pSolCore->szCorePath, sizeof(pSolCore->szCorePath), "%s/core.vb.%s.%d",
+ g_szCoreDumpDir, pSolProc->pszExecName, (int)pSolProc->Process);
}
else
- RTStrPrintf(pVBoxCore->szCorePath, sizeof(pVBoxCore->szCorePath), "%s/core.vb.%s", g_szCoreDumpDir, g_szCoreDumpFile);
+ RTStrPrintf(pSolCore->szCorePath, sizeof(pSolCore->szCorePath), "%s/core.vb.%s", g_szCoreDumpDir, g_szCoreDumpFile);
}
else
- RTStrCopy(pVBoxCore->szCorePath, sizeof(pVBoxCore->szCorePath), pszCoreFilePath);
+ RTStrCopy(pSolCore->szCorePath, sizeof(pSolCore->szCorePath), pszCoreFilePath);
- CORELOG((CORELOG_NAME "CreateCore: Taking Core %s from Thread %d\n", pVBoxCore->szCorePath, (int)pVBoxProc->hCurThread));
+ CORELOG((CORELOG_NAME "CreateCore: Taking Core %s from Thread %d\n", pSolCore->szCorePath, (int)pSolProc->hCurThread));
/*
* Quiesce the process.
*/
- int rc = rtCoreDumperSuspendThreads(pVBoxCore);
+ int rc = rtCoreDumperSuspendThreads(pSolCore);
if (RT_SUCCESS(rc))
{
- rc = ProcReadInfo(pVBoxCore);
+ rc = ProcReadInfo(pSolCore);
if (RT_SUCCESS(rc))
{
- GetOldProcessInfo(pVBoxCore, &pVBoxProc->ProcInfoOld);
- if (IsProcessArchNative(pVBoxProc))
+ GetOldProcessInfo(pSolCore, &pSolProc->ProcInfoOld);
+ if (IsProcessArchNative(pSolProc))
{
/*
* Read process status, information such as number of active LWPs will be invalid since we just quiesced the process.
*/
- rc = ProcReadStatus(pVBoxCore);
+ rc = ProcReadStatus(pSolCore);
if (RT_SUCCESS(rc))
{
- rc = AllocMemoryArea(pVBoxCore);
+ rc = AllocMemoryArea(pSolCore);
if (RT_SUCCESS(rc))
{
struct COREACCUMULATOR
{
const char *pszName;
- PFNCOREACCUMULATOR pfnAcc;
+ PFNRTSOLCOREACCUMULATOR pfnAcc;
bool fOptional;
} aAccumulators[] =
{
@@ -2065,7 +2090,7 @@ static int rtCoreDumperCreateCore(PVBOXCORE pVBoxCore, ucontext_t *pContext, con
for (unsigned i = 0; i < RT_ELEMENTS(aAccumulators); i++)
{
- rc = aAccumulators[i].pfnAcc(pVBoxCore);
+ rc = aAccumulators[i].pfnAcc(pSolCore);
if (RT_FAILURE(rc))
{
CORELOGRELSYS((CORELOG_NAME "CreateCore: %s failed. rc=%Rrc\n", aAccumulators[i].pszName, rc));
@@ -2076,11 +2101,11 @@ static int rtCoreDumperCreateCore(PVBOXCORE pVBoxCore, ucontext_t *pContext, con
if (RT_SUCCESS(rc))
{
- pVBoxCore->fIsValid = true;
+ pSolCore->fIsValid = true;
return VINF_SUCCESS;
}
- FreeMemoryArea(pVBoxCore);
+ FreeMemoryArea(pSolCore);
}
else
CORELOGRELSYS((CORELOG_NAME "CreateCore: AllocMemoryArea failed. rc=%Rrc\n", rc));
@@ -2100,7 +2125,7 @@ static int rtCoreDumperCreateCore(PVBOXCORE pVBoxCore, ucontext_t *pContext, con
/*
* Resume threads on failure.
*/
- rtCoreDumperResumeThreads(pVBoxCore);
+ rtCoreDumperResumeThreads(pSolCore);
}
else
CORELOG((CORELOG_NAME "CreateCore: SuspendAllThreads failed. Thread bomb!?! rc=%Rrc\n", rc));
@@ -2112,18 +2137,18 @@ static int rtCoreDumperCreateCore(PVBOXCORE pVBoxCore, ucontext_t *pContext, con
/**
* Destroy an existing core object.
*
- * @param pVBoxCore Pointer to the core object.
+ * @param pSolCore Pointer to the core object.
*
* @return IPRT status code.
*/
-static int rtCoreDumperDestroyCore(PVBOXCORE pVBoxCore)
+static int rtCoreDumperDestroyCore(PRTSOLCORE pSolCore)
{
- AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
- if (!pVBoxCore->fIsValid)
+ AssertReturn(pSolCore, VERR_INVALID_POINTER);
+ if (!pSolCore->fIsValid)
return VERR_INVALID_STATE;
- FreeMemoryArea(pVBoxCore);
- pVBoxCore->fIsValid = false;
+ FreeMemoryArea(pSolCore);
+ pSolCore->fIsValid = false;
return VINF_SUCCESS;
}
@@ -2151,18 +2176,18 @@ static int rtCoreDumperTakeDump(ucontext_t *pContext, const char *pszOutputFile)
* from before taking the snapshot until writing the core is completely finished.
* Any errors would resume all threads if they were halted.
*/
- VBOXCORE VBoxCore;
- RT_ZERO(VBoxCore);
- int rc = rtCoreDumperCreateCore(&VBoxCore, pContext, pszOutputFile);
+ RTSOLCORE SolCore;
+ RT_ZERO(SolCore);
+ int rc = rtCoreDumperCreateCore(&SolCore, pContext, pszOutputFile);
if (RT_SUCCESS(rc))
{
- rc = rtCoreDumperWriteCore(&VBoxCore, &WriteFileNoIntr);
+ rc = rtCoreDumperWriteCore(&SolCore, &WriteFileNoIntr);
if (RT_SUCCESS(rc))
- CORELOGRELSYS((CORELOG_NAME "Core dumped in %s\n", VBoxCore.szCorePath));
+ CORELOGRELSYS((CORELOG_NAME "Core dumped in %s\n", SolCore.szCorePath));
else
- CORELOGRELSYS((CORELOG_NAME "TakeDump: WriteCore failed. szCorePath=%s rc=%Rrc\n", VBoxCore.szCorePath, rc));
+ CORELOGRELSYS((CORELOG_NAME "TakeDump: WriteCore failed. szCorePath=%s rc=%Rrc\n", SolCore.szCorePath, rc));
- rtCoreDumperDestroyCore(&VBoxCore);
+ rtCoreDumperDestroyCore(&SolCore);
}
else
CORELOGRELSYS((CORELOG_NAME "TakeDump: CreateCore failed. rc=%Rrc\n", rc));
@@ -2320,6 +2345,18 @@ RTDECL(int) RTCoreDumperSetup(const char *pszOutputDir, uint32_t fFlags)
| RTCOREDUMPER_FLAGS_LIVE_CORE)),
VERR_INVALID_PARAMETER);
+
+ /*
+ * Setup/change the core dump directory if specified.
+ */
+ RT_ZERO(g_szCoreDumpDir);
+ if (pszOutputDir)
+ {
+ if (!RTDirExists(pszOutputDir))
+ return VERR_NOT_A_DIRECTORY;
+ RTStrCopy(g_szCoreDumpDir, sizeof(g_szCoreDumpDir), pszOutputDir);
+ }
+
/*
* Install core dump signal handler only if the flags changed or if it's the first time.
*/
@@ -2352,10 +2389,6 @@ RTDECL(int) RTCoreDumperSetup(const char *pszOutputDir, uint32_t fFlags)
ASMAtomicWriteBool(&g_fCoreDumpSignalSetup, true);
}
- RT_ZERO(g_szCoreDumpDir);
- if (pszOutputDir)
- RTStrCopy(g_szCoreDumpDir, sizeof(g_szCoreDumpDir), pszOutputDir);
-
return VINF_SUCCESS;
}
diff --git a/src/VBox/Runtime/r3/solaris/coredumper-solaris.h b/src/VBox/Runtime/r3/solaris/coredumper-solaris.h
index 92626cd8d..f18c90d0f 100644
--- a/src/VBox/Runtime/r3/solaris/coredumper-solaris.h
+++ b/src/VBox/Runtime/r3/solaris/coredumper-solaris.h
@@ -1,10 +1,10 @@
-/* $Id: coredumper-solaris.h $ */
+/* $Id: coredumper-solaris.h 37631 2011-06-24 13:25:07Z vboxsync $ */
/** @file
- * IPRT Testcase - Core dump, header.
+ * IPRT - Custom Core Dumper, Solaris.
*/
/*
- * 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;
@@ -24,8 +24,7 @@
* terms and conditions of either the GPL or the CDDL or both.
*/
-#include <iprt/process.h>
-#include <iprt/file.h>
+#include <iprt/types.h>
#ifdef RT_OS_SOLARIS
# if defined(RT_ARCH_X86) && _FILE_OFFSET_BITS==64
@@ -61,98 +60,99 @@
#ifdef RT_OS_SOLARIS
/**
- * VBOXSOLMAPINFO: Memory mapping description.
+ * Memory mapping descriptor employed by the solaris core dumper.
*/
-typedef struct VBOXSOLMAPINFO
+typedef struct RTSOLCOREMAPINFO
{
- prmap_t pMap; /* Proc description of this mapping */
- int fError; /* Any error reading this mapping (errno) */
- struct VBOXSOLMAPINFO *pNext; /* Pointer to the next mapping */
-} VBOXSOLMAPINFO;
-typedef VBOXSOLMAPINFO *PVBOXSOLMAPINFO;
+ prmap_t pMap; /**< Proc description of this mapping */
+ int fError; /**< Any error reading this mapping (errno) */
+ struct RTSOLCOREMAPINFO *pNext; /**< Pointer to the next mapping */
+} RTSOLCOREMAPINFO;
+/** Pointer to a solaris memory mapping descriptor. */
+typedef RTSOLCOREMAPINFO *PRTSOLCOREMAPINFO;
/**
- * VBOXSOLCORETYPE: Whether this is an old or new style core.
+ * Whether this is an old or new style solaris core.
*/
-typedef enum VBOXSOLCORETYPE
+typedef enum RTSOLCORETYPE
{
- enmOldEra = 0x01d, /* old */
- enmNewEra = 0x5c1f1 /* sci-fi */
-} VBOXSOLCORETYPE;
+ enmOldEra = 0x01d, /**< old */
+ enmNewEra = 0x5c1f1 /**< sci-fi */
+} RTSOLCORETYPE;
/**
- * VBOXSOLTHREADINFO: Per-Thread information.
+ * Per-Thread information employed by the solaris core dumper.
*/
-typedef struct VBOXSOLTHREADINFO
+typedef struct RTSOLCORETHREADINFO
{
- lwpsinfo_t Info; /* Proc description of this thread */
- lwpstatus_t *pStatus; /* Proc description of this thread's status (can be NULL, zombie lwp) */
- struct VBOXSOLTHREADINFO *pNext; /* Pointer to the next thread */
-} VBOXSOLTHREADINFO;
-typedef VBOXSOLTHREADINFO *PVBOXSOLTHREADINFO;
+ lwpsinfo_t Info; /**< Proc description of this thread */
+ lwpstatus_t *pStatus; /**< Proc description of this thread's status (can be NULL, zombie lwp) */
+ struct RTSOLCORETHREADINFO *pNext; /**< Pointer to the next thread */
+} RTSOLCORETHREADINFO;
+typedef RTSOLCORETHREADINFO *PRTSOLCORETHREADINFO;
#endif
/**
- * VBOXPROCESS: Current (also the core target) process information.
+ * Current (also the core target) process information.
*/
-typedef struct VBOXPROCESS
+typedef struct RTSOLCOREPROCESS
{
- RTPROCESS Process; /* The pid of the process */
- char szExecPath[PATH_MAX]; /* Path of the executable */
- char *pszExecName; /* Name of the executable file */
+ RTPROCESS Process; /**< The pid of the process */
+ char szExecPath[PATH_MAX]; /**< Path of the executable */
+ char *pszExecName; /**< Name of the executable file */
#ifdef RT_OS_SOLARIS
- psinfo_t ProcInfo; /* Process info. */
- prpsinfo_t ProcInfoOld; /* Process info. Older version (for GDB compat.) */
- pstatus_t ProcStatus; /* Process status info. */
- thread_t hCurThread; /* The current thread */
- ucontext_t *pCurThreadCtx; /* Context info. of current thread before starting to dump */
- RTFILE hAs; /* proc/<pid/as file handle */
- auxv_t *pAuxVecs; /* Aux vector of process */
- int cAuxVecs; /* Number of aux vector entries */
- PVBOXSOLMAPINFO pMapInfoHead; /* Pointer to the head of list of mappings */
- uint32_t cMappings; /* Number of mappings (count of pMapInfoHead list) */
- PVBOXSOLTHREADINFO pThreadInfoHead; /* Pointer to the head of list of threads */
- uint64_t cThreads; /* Number of threads (count of pThreadInfoHead list) */
- char szPlatform[SYS_NMLN]; /* Platform name */
- char szZoneName[ZONENAME_MAX]; /* Zone name */
- struct utsname UtsName; /* UTS name */
- void *pvCred; /* Process credential info. */
- size_t cbCred; /* Size of process credential info. */
- void *pvLdt; /* Process LDT info. */
- size_t cbLdt; /* Size of the LDT info. */
- prpriv_t *pPriv; /* Process privilege info. */
- size_t cbPriv; /* Size of process privilege info. */
- const priv_impl_info_t *pcPrivImpl; /* Process privilege implementation info. (opaque handle) */
- core_content_t CoreContent; /* What information goes in the core */
+ psinfo_t ProcInfo; /**< Process info. */
+ prpsinfo_t ProcInfoOld; /**< Process info. Older version (for GDB compat.) */
+ pstatus_t ProcStatus; /**< Process status info. */
+ thread_t hCurThread; /**< The current thread */
+ ucontext_t *pCurThreadCtx; /**< Context info. of current thread before starting to dump */
+ int fdAs; /**< proc/pid/as file handle */
+ auxv_t *pAuxVecs; /**< Aux vector of process */
+ int cAuxVecs; /**< Number of aux vector entries */
+ PRTSOLCOREMAPINFO pMapInfoHead; /**< Pointer to the head of list of mappings */
+ uint32_t cMappings; /**< Number of mappings (count of pMapInfoHead list) */
+ PRTSOLCORETHREADINFO pThreadInfoHead; /**< Pointer to the head of list of threads */
+ uint64_t cThreads; /**< Number of threads (count of pThreadInfoHead list) */
+ char szPlatform[SYS_NMLN]; /**< Platform name */
+ char szZoneName[ZONENAME_MAX]; /**< Zone name */
+ struct utsname UtsName; /**< UTS name */
+ void *pvCred; /**< Process credential info. */
+ size_t cbCred; /**< Size of process credential info. */
+ void *pvLdt; /**< Process LDT info. */
+ size_t cbLdt; /**< Size of the LDT info. */
+ prpriv_t *pPriv; /**< Process privilege info. */
+ size_t cbPriv; /**< Size of process privilege info. */
+ const priv_impl_info_t *pcPrivImpl; /**< Process privilege implementation info. (opaque handle) */
+ core_content_t CoreContent; /**< What information goes in the core */
#else
# error Port Me!
#endif
-} VBOXPROCESS;
-typedef VBOXPROCESS *PVBOXPROCESS;
+} RTSOLCOREPROCESS;
+typedef RTSOLCOREPROCESS *PRTSOLCOREPROCESS;
-typedef int (*PFNCOREREADER)(RTFILE hFile, void *pv, size_t cb);
-typedef int (*PFNCOREWRITER)(RTFILE hFile, const void *pcv, size_t cb);
+typedef int (*PFNRTCOREREADER)(int fdFile, void *pv, size_t cb);
+typedef int (*PFNRTCOREWRITER)(int fdhFile, const void *pcv, size_t cb);
/**
- * VBOXCORE: Core file object.
+ * The solaris core file object.
*/
-typedef struct VBOXCORE
+typedef struct RTSOLCORE
{
- char szCorePath[PATH_MAX]; /* Path of the core file */
- VBOXPROCESS VBoxProc; /* Current process information */
- void *pvCore; /* Pointer to memory area during dumping */
- size_t cbCore; /* Size of memory area during dumping */
- void *pvFree; /* Pointer to base of free range in preallocated memory area */
- bool fIsValid; /* Whether core information has been fully collected */
- PFNCOREREADER pfnReader; /* Reader function */
- PFNCOREWRITER pfnWriter; /* Writer function */
- RTFILE hCoreFile; /* Core file (used only while writing the core) */
- RTFOFF offWrite; /* Segment/section offset (used only while writing the core) */
-} VBOXCORE;
-typedef VBOXCORE *PVBOXCORE;
+ char szCorePath[PATH_MAX]; /**< Path of the core file */
+ RTSOLCOREPROCESS SolProc; /**< Current process information */
+ void *pvCore; /**< Pointer to memory area during dumping */
+ size_t cbCore; /**< Size of memory area during dumping */
+ void *pvFree; /**< Pointer to base of free range in preallocated memory area */
+ bool fIsValid; /**< Whether core information has been fully collected */
+ PFNRTCOREREADER pfnReader; /**< Reader function */
+ PFNRTCOREWRITER pfnWriter; /**< Writer function */
+ int fdCoreFile; /**< Core file (used only while writing the core) */
+ RTFOFF offWrite; /**< Segment/section offset (used only while writing the core) */
+} RTSOLCORE;
+typedef RTSOLCORE *PRTSOLCORE;
-typedef int (*PFNCOREACCUMULATOR)(PVBOXCORE pVBoxCore);
-typedef int (*PFNCORETHREADWORKER)(PVBOXCORE pVBoxCore, void *pvThreadInfo);
+typedef int (*PFNRTSOLCOREACCUMULATOR)(PRTSOLCORE pSolCore);
+typedef int (*PFNRTSOLCORETHREADWORKER)(PRTSOLCORE pSolCore, void *pvThreadInfo);
diff --git a/src/VBox/Runtime/r3/solaris/fileaio-solaris.cpp b/src/VBox/Runtime/r3/solaris/fileaio-solaris.cpp
index d8b6fb416..152ebee68 100644
--- a/src/VBox/Runtime/r3/solaris/fileaio-solaris.cpp
+++ b/src/VBox/Runtime/r3/solaris/fileaio-solaris.cpp
@@ -1,4 +1,4 @@
-/* $Id: fileaio-solaris.cpp $ */
+/* $Id: fileaio-solaris.cpp 30238 2010-06-16 11:34:44Z vboxsync $ */
/** @file
* IPRT - File async I/O, native implementation for the Solaris host platform.
*/
diff --git a/src/VBox/Runtime/r3/solaris/mp-solaris.cpp b/src/VBox/Runtime/r3/solaris/mp-solaris.cpp
index 0f2c6fdf0..5101f20bc 100644
--- a/src/VBox/Runtime/r3/solaris/mp-solaris.cpp
+++ b/src/VBox/Runtime/r3/solaris/mp-solaris.cpp
@@ -1,4 +1,4 @@
-/* $Id: mp-solaris.cpp $ */
+/* $Id: mp-solaris.cpp 29269 2010-05-09 21:24:06Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Solaris.
*/
diff --git a/src/VBox/Runtime/r3/solaris/rtProcInitExePath-solaris.cpp b/src/VBox/Runtime/r3/solaris/rtProcInitExePath-solaris.cpp
index 40baf8c25..f14a3404b 100644
--- a/src/VBox/Runtime/r3/solaris/rtProcInitExePath-solaris.cpp
+++ b/src/VBox/Runtime/r3/solaris/rtProcInitExePath-solaris.cpp
@@ -1,4 +1,4 @@
-/* $Id: rtProcInitExePath-solaris.cpp $ */
+/* $Id: rtProcInitExePath-solaris.cpp 28929 2010-04-30 11:26:46Z vboxsync $ */
/** @file
* IPRT - rtProcInitName, Solaris.
*/
diff --git a/src/VBox/Runtime/r3/solaris/thread-affinity-solaris.cpp b/src/VBox/Runtime/r3/solaris/thread-affinity-solaris.cpp
new file mode 100644
index 000000000..b2bd2b4c5
--- /dev/null
+++ b/src/VBox/Runtime/r3/solaris/thread-affinity-solaris.cpp
@@ -0,0 +1,94 @@
+/* $Id: thread-affinity-solaris.cpp 37156 2011-05-19 13:11:14Z vboxsync $ */
+/** @file
+ * IPRT - Thread Affinity, Solaris ring-3 implementation.
+ */
+
+/*
+ * 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.
+ *
+ * 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/thread.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/cpuset.h>
+#include <iprt/err.h>
+#include <iprt/mp.h>
+
+#include <sys/types.h>
+#include <sys/processor.h>
+#include <sys/procset.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+/* Note! The current implementation can only bind to a single CPU. */
+
+
+RTR3DECL(int) RTThreadSetAffinity(PCRTCPUSET pCpuSet)
+{
+ int rc;
+ if (pCpuSet == NULL)
+ rc = processor_bind(P_LWPID, P_MYID, PBIND_NONE, NULL);
+ else
+ {
+ RTCPUSET PresentSet;
+ int cCpusInSet = RTCpuSetCount(pCpuSet);
+ if (cCpusInSet == 1)
+ {
+ unsigned iCpu = 0;
+ while ( iCpu < RTCPUSET_MAX_CPUS
+ && !RTCpuSetIsMemberByIndex(pCpuSet, iCpu))
+ iCpu++;
+ rc = processor_bind(P_LWPID, P_MYID, iCpu, NULL);
+ }
+ else if ( cCpusInSet == RTCPUSET_MAX_CPUS
+ || RTCpuSetIsEqual(pCpuSet, RTMpGetPresentSet(&PresentSet)))
+ rc = processor_bind(P_LWPID, P_MYID, PBIND_NONE, NULL);
+ else
+ return VERR_NOT_SUPPORTED;
+ }
+ if (!rc)
+ return VINF_SUCCESS;
+ return RTErrConvertFromErrno(errno);
+}
+
+
+RTR3DECL(int) RTThreadGetAffinity(PRTCPUSET pCpuSet)
+{
+ processorid_t iOldCpu;
+ int rc = processor_bind(P_LWPID, P_MYID, PBIND_QUERY, &iOldCpu);
+ if (rc)
+ return RTErrConvertFromErrno(errno);
+ if (iOldCpu == PBIND_NONE)
+ RTMpGetPresentSet(pCpuSet);
+ else
+ {
+ RTCpuSetEmpty(pCpuSet);
+ if (RTCpuSetAdd(pCpuSet, iOldCpu) != 0)
+ return VERR_INTERNAL_ERROR_5;
+ }
+ return VINF_SUCCESS;
+}
+
diff --git a/src/VBox/Runtime/r3/stream.cpp b/src/VBox/Runtime/r3/stream.cpp
index a3af65d40..52c997397 100644
--- a/src/VBox/Runtime/r3/stream.cpp
+++ b/src/VBox/Runtime/r3/stream.cpp
@@ -1,4 +1,4 @@
-/* $Id: stream.cpp $ */
+/* $Id: stream.cpp 32464 2010-09-14 08:48:32Z vboxsync $ */
/** @file
* IPRT - I/O Stream.
*/
diff --git a/src/VBox/Runtime/r3/tcp.cpp b/src/VBox/Runtime/r3/tcp.cpp
index 8f47eda56..9f96f71f8 100644
--- a/src/VBox/Runtime/r3/tcp.cpp
+++ b/src/VBox/Runtime/r3/tcp.cpp
@@ -1,4 +1,4 @@
-/* $Id: tcp.cpp $ */
+/* $Id: tcp.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - TCP/IP.
*/
diff --git a/src/VBox/Runtime/r3/test.cpp b/src/VBox/Runtime/r3/test.cpp
index d3e850f63..c7ce69f03 100644
--- a/src/VBox/Runtime/r3/test.cpp
+++ b/src/VBox/Runtime/r3/test.cpp
@@ -1,4 +1,4 @@
-/* $Id: test.cpp $ */
+/* $Id: test.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Testcase Framework.
*/
diff --git a/src/VBox/Runtime/r3/testi.cpp b/src/VBox/Runtime/r3/testi.cpp
index e143e3c1e..e6db79d6b 100644
--- a/src/VBox/Runtime/r3/testi.cpp
+++ b/src/VBox/Runtime/r3/testi.cpp
@@ -1,4 +1,4 @@
-/* $Id: testi.cpp $ */
+/* $Id: testi.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Testcase Framework, the implicit test handle API variation.
*/
diff --git a/src/VBox/Runtime/r3/udp.cpp b/src/VBox/Runtime/r3/udp.cpp
new file mode 100644
index 000000000..de9016e93
--- /dev/null
+++ b/src/VBox/Runtime/r3/udp.cpp
@@ -0,0 +1,726 @@
+/* $Id: udp.cpp 37197 2011-05-24 14:56:02Z vboxsync $ */
+/** @file
+ * IPRT - UDP/IP.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 *
+*******************************************************************************/
+#ifdef RT_OS_WINDOWS
+# include <winsock2.h>
+#else
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <errno.h>
+# include <netinet/in.h>
+# include <netinet/udp.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+#endif
+#include <limits.h>
+
+#include "internal/iprt.h"
+#include <iprt/udp.h>
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/mempool.h>
+#include <iprt/mem.h>
+#include <iprt/string.h>
+#include <iprt/socket.h>
+#include <iprt/thread.h>
+#include <iprt/time.h>
+
+#include "internal/magics.h"
+#include "internal/socket.h"
+
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+/* fixup backlevel OSes. */
+#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
+# define socklen_t int
+#endif
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * UDP Server state.
+ */
+typedef enum RTUDPSERVERSTATE
+{
+ /** Invalid. */
+ RTUDPSERVERSTATE_INVALID = 0,
+ /** Created. */
+ RTUDPSERVERSTATE_CREATED,
+ /** Thread for incoming datagrams is starting up. */
+ RTUDPSERVERSTATE_STARTING,
+ /** Waiting for incoming datagrams. */
+ RTUDPSERVERSTATE_WAITING,
+ /** Handling an incoming datagram. */
+ RTUDPSERVERSTATE_RECEIVING,
+ /** Thread terminating. */
+ RTUDPSERVERSTATE_STOPPING,
+ /** Thread terminated. */
+ RTUDPSERVERSTATE_STOPPED,
+ /** Final cleanup before being unusable. */
+ RTUDPSERVERSTATE_DESTROYING
+} RTUDPSERVERSTATE;
+
+/*
+ * Internal representation of the UDP Server handle.
+ */
+typedef struct RTUDPSERVER
+{
+ /** The magic value (RTUDPSERVER_MAGIC). */
+ uint32_t volatile u32Magic;
+ /** The server state. */
+ RTUDPSERVERSTATE volatile enmState;
+ /** The server thread. */
+ RTTHREAD Thread;
+ /** The server socket. */
+ RTSOCKET volatile hSocket;
+ /** The datagram receiver function. */
+ PFNRTUDPSERVE pfnServe;
+ /** Argument to pfnServer. */
+ void *pvUser;
+} RTUDPSERVER;
+
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+static DECLCALLBACK(int) rtUdpServerThread(RTTHREAD ThreadSelf, void *pvServer);
+static int rtUdpServerListen(PRTUDPSERVER pServer);
+static int rtUdpServerListenCleanup(PRTUDPSERVER pServer);
+static int rtUdpServerDestroySocket(RTSOCKET volatile *pSock, const char *pszMsg);
+static int rtUdpClose(RTSOCKET Sock, const char *pszMsg);
+
+
+/**
+ * Atomicly updates a socket variable.
+ * @returns The old handle value.
+ * @param phSock The socket handle variable to update.
+ * @param hSock The new socket handle value.
+ */
+DECLINLINE(RTSOCKET) rtUdpAtomicXchgSock(RTSOCKET volatile *phSock, const RTSOCKET hNew)
+{
+ RTSOCKET hRet;
+ ASMAtomicXchgHandle(phSock, hNew, &hRet);
+ return hRet;
+}
+
+
+/**
+ * Tries to change the UDP server state.
+ */
+DECLINLINE(bool) rtUdpServerTrySetState(PRTUDPSERVER pServer, RTUDPSERVERSTATE enmStateNew, RTUDPSERVERSTATE enmStateOld)
+{
+ bool fRc;
+ ASMAtomicCmpXchgSize(&pServer->enmState, enmStateNew, enmStateOld, fRc);
+ return fRc;
+}
+
+/**
+ * Changes the UDP server state.
+ */
+DECLINLINE(void) rtUdpServerSetState(PRTUDPSERVER pServer, RTUDPSERVERSTATE enmStateNew, RTUDPSERVERSTATE enmStateOld)
+{
+ bool fRc;
+ ASMAtomicCmpXchgSize(&pServer->enmState, enmStateNew, enmStateOld, fRc);
+ Assert(fRc); NOREF(fRc);
+}
+
+
+/**
+ * Closes a socket.
+ *
+ * @returns IPRT status code.
+ */
+static int rtUdpServerDestroySocket(RTSOCKET volatile *pSock, const char *pszMsg)
+{
+ RTSOCKET hSocket = rtUdpAtomicXchgSock(pSock, NIL_RTSOCKET);
+ if (hSocket != NIL_RTSOCKET)
+ {
+ return rtUdpClose(hSocket, pszMsg);
+ }
+ return VINF_UDP_SERVER_NO_CLIENT;
+}
+
+
+/**
+ * Create single datagram at a time UDP Server in a separate thread.
+ *
+ * The thread will loop waiting for datagrams and call pfnServe for
+ * each of the incoming datagrams in turn. The pfnServe function can
+ * return VERR_UDP_SERVER_STOP too terminate this loop. RTUdpServerDestroy()
+ * should be used to terminate the server.
+ *
+ * @returns iprt status code.
+ * @param pszAddress The address for creating a datagram socket.
+ * If NULL or empty string the server is bound to all interfaces.
+ * @param uPort The port for creating a datagram socket.
+ * @param enmType The thread type.
+ * @param pszThrdName The name of the worker thread.
+ * @param pfnServe The function which will handle incoming datagrams.
+ * @param pvUser User argument passed to pfnServe.
+ * @param ppServer Where to store the serverhandle.
+ */
+RTR3DECL(int) RTUdpServerCreate(const char *pszAddress, unsigned uPort, RTTHREADTYPE enmType, const char *pszThrdName,
+ PFNRTUDPSERVE pfnServe, void *pvUser, PPRTUDPSERVER ppServer)
+{
+ /*
+ * Validate input.
+ */
+ AssertReturn(uPort > 0, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pfnServe, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszThrdName, VERR_INVALID_POINTER);
+ AssertPtrReturn(ppServer, VERR_INVALID_POINTER);
+
+ /*
+ * Create the server.
+ */
+ PRTUDPSERVER pServer;
+ int rc = RTUdpServerCreateEx(pszAddress, uPort, &pServer);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Create the listener thread.
+ */
+ RTMemPoolRetain(pServer);
+ pServer->enmState = RTUDPSERVERSTATE_STARTING;
+ pServer->pvUser = pvUser;
+ pServer->pfnServe = pfnServe;
+ rc = RTThreadCreate(&pServer->Thread, rtUdpServerThread, pServer, 0, enmType, /*RTTHREADFLAGS_WAITABLE*/0, pszThrdName);
+ if (RT_SUCCESS(rc))
+ {
+ /* done */
+ if (ppServer)
+ *ppServer = pServer;
+ else
+ RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
+ return rc;
+ }
+ RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
+
+ /*
+ * Destroy the server.
+ */
+ rtUdpServerSetState(pServer, RTUDPSERVERSTATE_CREATED, RTUDPSERVERSTATE_STARTING);
+ RTUdpServerDestroy(pServer);
+ }
+
+ return rc;
+}
+
+
+/**
+ * Server thread, loops waiting for datagrams until it's terminated.
+ *
+ * @returns iprt status code. (ignored).
+ * @param ThreadSelf Thread handle.
+ * @param pvServer Server handle.
+ */
+static DECLCALLBACK(int) rtUdpServerThread(RTTHREAD ThreadSelf, void *pvServer)
+{
+ PRTUDPSERVER pServer = (PRTUDPSERVER)pvServer;
+ int rc;
+ if (rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_WAITING, RTUDPSERVERSTATE_STARTING))
+ rc = rtUdpServerListen(pServer);
+ else
+ rc = rtUdpServerListenCleanup(pServer);
+ RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
+ NOREF(ThreadSelf);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Create single datagram at a time UDP Server.
+ * The caller must call RTUdpServerReceive() to actually start the server.
+ *
+ * @returns iprt status code.
+ * @param pszAddress The address for creating a datagram socket.
+ * If NULL the server is bound to all interfaces.
+ * @param uPort The port for creating a datagram socket.
+ * @param ppServer Where to store the serverhandle.
+ */
+RTR3DECL(int) RTUdpServerCreateEx(const char *pszAddress, uint32_t uPort, PPRTUDPSERVER ppServer)
+{
+ int rc;
+
+ /*
+ * Validate input.
+ */
+ AssertReturn(uPort > 0, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(ppServer, VERR_INVALID_PARAMETER);
+
+#ifdef RT_OS_WINDOWS
+ /*
+ * Initialize WinSock and check version.
+ */
+ WORD wVersionRequested = MAKEWORD(1, 1);
+ WSADATA wsaData;
+ rc = WSAStartup(wVersionRequested, &wsaData);
+ if (wsaData.wVersion != wVersionRequested)
+ {
+ AssertMsgFailed(("Wrong winsock version\n"));
+ return VERR_NOT_SUPPORTED;
+ }
+#endif
+
+ /*
+ * Get host listening address.
+ */
+ struct hostent *pHostEnt = NULL;
+ if (pszAddress != NULL && *pszAddress)
+ {
+ pHostEnt = gethostbyname(pszAddress);
+ if (!pHostEnt)
+ {
+ struct in_addr InAddr;
+ InAddr.s_addr = inet_addr(pszAddress);
+ pHostEnt = gethostbyaddr((char *)&InAddr, 4, AF_INET);
+ if (!pHostEnt)
+ {
+ rc = rtSocketResolverError();
+ return rc;
+ }
+ }
+ }
+
+ /*
+ * Setting up socket.
+ */
+ RTSOCKET Sock;
+ rc = rtSocketCreate(&Sock, AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (RT_SUCCESS(rc))
+ {
+ RTSocketSetInheritance(Sock, false /*fInheritable*/);
+
+ /*
+ * Set socket options.
+ */
+ int fFlag = 1;
+ if (!rtSocketSetOpt(Sock, SOL_SOCKET, SO_REUSEADDR, &fFlag, sizeof(fFlag)))
+ {
+ /*
+ * Set socket family, address and port.
+ */
+ struct sockaddr_in LocalAddr;
+ RT_ZERO(LocalAddr);
+ LocalAddr.sin_family = AF_INET;
+ LocalAddr.sin_port = htons(uPort);
+ /* if address not specified, use INADDR_ANY. */
+ if (!pHostEnt)
+ LocalAddr.sin_addr.s_addr = INADDR_ANY;
+ else
+ LocalAddr.sin_addr = *((struct in_addr *)pHostEnt->h_addr);
+
+ /*
+ * Bind a name to the socket.
+ */
+ rc = rtSocketBind(Sock, (struct sockaddr *)&LocalAddr, sizeof(LocalAddr));
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Create the server handle.
+ */
+ PRTUDPSERVER pServer = (PRTUDPSERVER)RTMemPoolAlloc(RTMEMPOOL_DEFAULT, sizeof(*pServer));
+ if (pServer)
+ {
+ pServer->u32Magic = RTUDPSERVER_MAGIC;
+ pServer->enmState = RTUDPSERVERSTATE_CREATED;
+ pServer->Thread = NIL_RTTHREAD;
+ pServer->hSocket = Sock;
+ pServer->pfnServe = NULL;
+ pServer->pvUser = NULL;
+ *ppServer = pServer;
+ return VINF_SUCCESS;
+ }
+
+ /* bail out */
+ rc = VERR_NO_MEMORY;
+ }
+ }
+ else
+ AssertMsgFailed(("rtSocketSetOpt: %Rrc\n", rc));
+ rtUdpClose(Sock, "RTServerCreateEx");
+ }
+
+ return rc;
+}
+
+
+/**
+ * Listen for incoming datagrams.
+ *
+ * The function will loop waiting for datagrams and call pfnServe for
+ * each of the incoming datagrams in turn. The pfnServe function can
+ * return VERR_UDP_SERVER_STOP too terminate this loop. A stopped server
+ * can only be destroyed.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_UDP_SERVER_STOP if stopped by pfnServe.
+ * @retval VERR_UDP_SERVER_SHUTDOWN if shut down by RTUdpServerShutdown.
+ *
+ * @param pServer The server handle as returned from RTUdpServerCreateEx().
+ * @param pfnServe The function which will handle incoming datagrams.
+ * @param pvUser User argument passed to pfnServe.
+ */
+RTR3DECL(int) RTUdpServerListen(PRTUDPSERVER pServer, PFNRTUDPSERVE pfnServe, void *pvUser)
+{
+ /*
+ * Validate input and retain the instance.
+ */
+ AssertPtrReturn(pfnServe, VERR_INVALID_POINTER);
+ AssertPtrReturn(pServer, VERR_INVALID_HANDLE);
+ AssertReturn(pServer->u32Magic == RTUDPSERVER_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE);
+
+ int rc = VERR_INVALID_STATE;
+ if (rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_WAITING, RTUDPSERVERSTATE_CREATED))
+ {
+ Assert(!pServer->pfnServe);
+ Assert(!pServer->pvUser);
+ Assert(pServer->Thread == NIL_RTTHREAD);
+
+ pServer->pfnServe = pfnServe;
+ pServer->pvUser = pvUser;
+ pServer->Thread = RTThreadSelf();
+ Assert(pServer->Thread != NIL_RTTHREAD);
+ rc = rtUdpServerListen(pServer);
+ }
+ else
+ {
+ AssertMsgFailed(("enmState=%d\n", pServer->enmState));
+ rc = VERR_INVALID_STATE;
+ }
+ RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
+ return rc;
+}
+
+
+/**
+ * Internal worker common for RTUdpServerListen and the thread created by
+ * RTUdpServerCreate().
+ *
+ * The caller makes sure it has its own memory reference and releases it upon
+ * return.
+ */
+static int rtUdpServerListen(PRTUDPSERVER pServer)
+{
+ /*
+ * Wait for incoming datagrams loop.
+ */
+ for (;;)
+ {
+ /*
+ * Change state, getting an extra reference to the socket so we can
+ * allow others to close it while we're stuck in rtSocketAccept.
+ */
+ RTUDPSERVERSTATE enmState = pServer->enmState;
+ RTSOCKET hSocket;
+ ASMAtomicReadHandle(&pServer->hSocket, &hSocket);
+ if (hSocket != NIL_RTSOCKET)
+ RTSocketRetain(hSocket);
+ if ( enmState != RTUDPSERVERSTATE_WAITING
+ && enmState != RTUDPSERVERSTATE_RECEIVING)
+ {
+ RTSocketRelease(hSocket);
+ return rtUdpServerListenCleanup(pServer);
+ }
+ if (!rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_WAITING, enmState))
+ {
+ RTSocketRelease(hSocket);
+ continue;
+ }
+
+ /*
+ * Wait for incoming datagrams or errors.
+ */
+ uint32_t fEvents;
+ int rc = RTSocketSelectOneEx(hSocket, RTSOCKET_EVT_READ | RTSOCKET_EVT_ERROR, &fEvents, 1000);
+ RTSocketRelease(hSocket);
+ if (rc == VERR_TIMEOUT)
+ continue;
+ if (RT_FAILURE(rc))
+ {
+ /* These are typical for what can happen during destruction. */
+ if ( rc == VERR_INVALID_HANDLE
+ || rc == VERR_INVALID_PARAMETER
+ || rc == VERR_NET_NOT_SOCKET)
+ return rtUdpServerListenCleanup(pServer);
+ continue;
+ }
+ if (fEvents & RTSOCKET_EVT_ERROR)
+ return rtUdpServerListenCleanup(pServer);
+
+ /*
+ * Run a pfnServe callback.
+ */
+ if (!rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_RECEIVING, RTUDPSERVERSTATE_WAITING))
+ return rtUdpServerListenCleanup(pServer);
+ rc = pServer->pfnServe(hSocket, pServer->pvUser);
+
+ /*
+ * Stop the server?
+ */
+ if (rc == VERR_UDP_SERVER_STOP)
+ {
+ if (rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_STOPPING, RTUDPSERVERSTATE_RECEIVING))
+ {
+ /*
+ * Reset the server socket and change the state to stopped. After that state change
+ * we cannot safely access the handle so we'll have to return here.
+ */
+ hSocket = rtUdpAtomicXchgSock(&pServer->hSocket, NIL_RTSOCKET);
+ rtUdpServerSetState(pServer, RTUDPSERVERSTATE_STOPPED, RTUDPSERVERSTATE_STOPPING);
+ rtUdpClose(hSocket, "Listener: server stopped");
+ }
+ else
+ rtUdpServerListenCleanup(pServer); /* ignore rc */
+ return rc;
+ }
+ }
+}
+
+
+/**
+ * Clean up after listener.
+ */
+static int rtUdpServerListenCleanup(PRTUDPSERVER pServer)
+{
+ /*
+ * Close the server socket.
+ */
+ rtUdpServerDestroySocket(&pServer->hSocket, "ListenCleanup");
+
+ /*
+ * Figure the return code and make sure the state is OK.
+ */
+ RTUDPSERVERSTATE enmState = pServer->enmState;
+ switch (enmState)
+ {
+ case RTUDPSERVERSTATE_STOPPING:
+ case RTUDPSERVERSTATE_STOPPED:
+ return VERR_UDP_SERVER_SHUTDOWN;
+
+ case RTUDPSERVERSTATE_WAITING:
+ rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_STOPPED, enmState);
+ return VERR_UDP_SERVER_DESTROYED;
+
+ case RTUDPSERVERSTATE_DESTROYING:
+ return VERR_UDP_SERVER_DESTROYED;
+
+ case RTUDPSERVERSTATE_STARTING:
+ case RTUDPSERVERSTATE_RECEIVING:
+ default:
+ AssertMsgFailedReturn(("pServer=%p enmState=%d\n", pServer, enmState), VERR_INTERNAL_ERROR_4);
+ }
+}
+
+
+/**
+ * Shuts down the server.
+ *
+ * @returns IPRT status code.
+ * @param pServer Handle to the server.
+ */
+RTR3DECL(int) RTUdpServerShutdown(PRTUDPSERVER pServer)
+{
+ /*
+ * Validate input and retain the instance.
+ */
+ AssertPtrReturn(pServer, VERR_INVALID_HANDLE);
+ AssertReturn(pServer->u32Magic == RTUDPSERVER_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE);
+
+ /*
+ * Try change the state to stopping, then replace and destroy the server socket.
+ */
+ for (;;)
+ {
+ RTUDPSERVERSTATE enmState = pServer->enmState;
+ if ( enmState != RTUDPSERVERSTATE_WAITING
+ && enmState != RTUDPSERVERSTATE_RECEIVING)
+ {
+ RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
+ switch (enmState)
+ {
+ case RTUDPSERVERSTATE_CREATED:
+ case RTUDPSERVERSTATE_STARTING:
+ default:
+ AssertMsgFailed(("%d\n", enmState));
+ return VERR_INVALID_STATE;
+
+ case RTUDPSERVERSTATE_STOPPING:
+ case RTUDPSERVERSTATE_STOPPED:
+ return VINF_SUCCESS;
+
+ case RTUDPSERVERSTATE_DESTROYING:
+ return VERR_UDP_SERVER_DESTROYED;
+ }
+ }
+ if (rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_STOPPING, enmState))
+ {
+ rtUdpServerDestroySocket(&pServer->hSocket, "RTUdpServerShutdown");
+ rtUdpServerSetState(pServer, RTUDPSERVERSTATE_STOPPED, RTUDPSERVERSTATE_STOPPING);
+
+ RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
+ return VINF_SUCCESS;
+ }
+ }
+}
+
+
+/**
+ * Closes down and frees a UDP Server.
+ *
+ * @returns iprt status code.
+ * @param pServer Handle to the server.
+ */
+RTR3DECL(int) RTUdpServerDestroy(PRTUDPSERVER pServer)
+{
+ /*
+ * Validate input and retain the instance.
+ */
+ AssertPtrReturn(pServer, VERR_INVALID_HANDLE);
+ AssertReturn(pServer->u32Magic == RTUDPSERVER_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE); /* paranoia */
+
+ /*
+ * Move the state along so the listener can figure out what's going on.
+ */
+ for (;;)
+ {
+ bool fDestroyable;
+ RTUDPSERVERSTATE enmState = pServer->enmState;
+ switch (enmState)
+ {
+ case RTUDPSERVERSTATE_STARTING:
+ case RTUDPSERVERSTATE_WAITING:
+ case RTUDPSERVERSTATE_RECEIVING:
+ case RTUDPSERVERSTATE_CREATED:
+ case RTUDPSERVERSTATE_STOPPED:
+ fDestroyable = rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_DESTROYING, enmState);
+ break;
+
+ /* destroyable states */
+ case RTUDPSERVERSTATE_STOPPING:
+ fDestroyable = true;
+ break;
+
+ /*
+ * Everything else means user or internal misbehavior.
+ */
+ default:
+ AssertMsgFailed(("pServer=%p enmState=%d\n", pServer, enmState));
+ RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
+ return VERR_INTERNAL_ERROR;
+ }
+ if (fDestroyable)
+ break;
+ }
+
+ /*
+ * Destroy it.
+ */
+ ASMAtomicWriteU32(&pServer->u32Magic, ~RTUDPSERVER_MAGIC);
+ rtUdpServerDestroySocket(&pServer->hSocket, "Destroyer: server");
+
+ /*
+ * Release it.
+ */
+ RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
+ RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Internal close function which does all the proper bitching.
+ */
+static int rtUdpClose(RTSOCKET Sock, const char *pszMsg)
+{
+ /* ignore nil handles. */
+ if (Sock == NIL_RTSOCKET)
+ return VINF_SUCCESS;
+
+ /*
+ * Close the socket handle (drops our reference to it).
+ */
+ return RTSocketClose(Sock);
+}
+
+
+RTR3DECL(int) RTUdpRead(RTSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead, PRTNETADDR pSrcAddr)
+{
+ if (!RT_VALID_PTR(pcbRead))
+ return VERR_INVALID_POINTER;
+ return RTSocketReadFrom(Sock, pvBuffer, cbBuffer, pcbRead, pSrcAddr);
+}
+
+
+RTR3DECL(int) RTUdpWrite(PRTUDPSERVER pServer, const void *pvBuffer, size_t cbBuffer, PCRTNETADDR pDstAddr)
+{
+ /*
+ * Validate input and retain the instance.
+ */
+ AssertPtrReturn(pServer, VERR_INVALID_HANDLE);
+ AssertReturn(pServer->u32Magic == RTUDPSERVER_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE);
+
+ RTSOCKET hSocket;
+ ASMAtomicReadHandle(&pServer->hSocket, &hSocket);
+ if (hSocket == NIL_RTSOCKET)
+ {
+ RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
+ return VERR_INVALID_HANDLE;
+ }
+ RTSocketRetain(hSocket);
+
+ int rc = VINF_SUCCESS;
+ RTUDPSERVERSTATE enmState = pServer->enmState;
+ if ( enmState != RTUDPSERVERSTATE_CREATED
+ && enmState != RTUDPSERVERSTATE_STARTING
+ && enmState != RTUDPSERVERSTATE_WAITING
+ && enmState != RTUDPSERVERSTATE_RECEIVING
+ && enmState != RTUDPSERVERSTATE_STOPPING)
+ rc = VERR_INVALID_STATE;
+
+ if (RT_SUCCESS(rc))
+ rc = RTSocketWriteTo(hSocket, pvBuffer, cbBuffer, pDstAddr);
+
+ RTSocketRelease(hSocket);
+ RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
+
+ return rc;
+}
+
diff --git a/src/VBox/Runtime/r3/win/RTHandleGetStandard-win.cpp b/src/VBox/Runtime/r3/win/RTHandleGetStandard-win.cpp
index a0a1e5fa3..42e6953c6 100644
--- a/src/VBox/Runtime/r3/win/RTHandleGetStandard-win.cpp
+++ b/src/VBox/Runtime/r3/win/RTHandleGetStandard-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTHandleGetStandard-win.cpp $ */
+/* $Id: RTHandleGetStandard-win.cpp 36123 2011-03-01 15:38:35Z vboxsync $ */
/** @file
* IPRT - RTHandleGetStandard, Windows.
*/
@@ -63,7 +63,7 @@ RTDECL(int) RTHandleGetStandard(RTHANDLESTD enmStdHandle, PRTHANDLE ph)
* best map on to?
*/
HANDLE hNative = GetStdHandle(dwStdHandle);
- if (hNative)
+ if (hNative == INVALID_HANDLE_VALUE)
return RTErrConvertFromWin32(GetLastError());
DWORD dwInfo;
diff --git a/src/VBox/Runtime/r3/win/RTLogWriteDebugger-win.cpp b/src/VBox/Runtime/r3/win/RTLogWriteDebugger-win.cpp
index 2f3c16c03..faff04b90 100644
--- a/src/VBox/Runtime/r3/win/RTLogWriteDebugger-win.cpp
+++ b/src/VBox/Runtime/r3/win/RTLogWriteDebugger-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTLogWriteDebugger-win.cpp $ */
+/* $Id: RTLogWriteDebugger-win.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Log To Debugger, Win32.
*/
diff --git a/src/VBox/Runtime/r3/win/RTSystemQueryDmiString-win.cpp b/src/VBox/Runtime/r3/win/RTSystemQueryDmiString-win.cpp
index 578319106..a37fd76fc 100644
--- a/src/VBox/Runtime/r3/win/RTSystemQueryDmiString-win.cpp
+++ b/src/VBox/Runtime/r3/win/RTSystemQueryDmiString-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSystemQueryDmiString-win.cpp $ */
+/* $Id: RTSystemQueryDmiString-win.cpp 36440 2011-03-25 16:21:57Z vboxsync $ */
/** @file
* IPRT - RTSystemQueryDmiString, windows ring-3.
*/
diff --git a/src/VBox/Runtime/r3/win/RTSystemQueryOSInfo-win.cpp b/src/VBox/Runtime/r3/win/RTSystemQueryOSInfo-win.cpp
index 194e3ee23..a87892ac9 100644
--- a/src/VBox/Runtime/r3/win/RTSystemQueryOSInfo-win.cpp
+++ b/src/VBox/Runtime/r3/win/RTSystemQueryOSInfo-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSystemQueryOSInfo-win.cpp $ */
+/* $Id: RTSystemQueryOSInfo-win.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTSystemQueryOSInfo, generic stub.
*/
diff --git a/src/VBox/Runtime/r3/win/RTSystemQueryTotalRam-win.cpp b/src/VBox/Runtime/r3/win/RTSystemQueryTotalRam-win.cpp
index 5e31869c4..36482d824 100644
--- a/src/VBox/Runtime/r3/win/RTSystemQueryTotalRam-win.cpp
+++ b/src/VBox/Runtime/r3/win/RTSystemQueryTotalRam-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTSystemQueryTotalRam-win.cpp $ */
+/* $Id: RTSystemQueryTotalRam-win.cpp 33503 2010-10-27 13:12:57Z vboxsync $ */
/** @file
* IPRT - RTSystemQueryTotalRam, windows ring-3.
*/
diff --git a/src/VBox/Runtime/r3/win/RTUuidCreate-win.cpp b/src/VBox/Runtime/r3/win/RTUuidCreate-win.cpp
index 8083f98de..e979fa18c 100644
--- a/src/VBox/Runtime/r3/win/RTUuidCreate-win.cpp
+++ b/src/VBox/Runtime/r3/win/RTUuidCreate-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTUuidCreate-win.cpp $ */
+/* $Id: RTUuidCreate-win.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - UUID, Windows RTUuidCreate implementation.
*/
diff --git a/src/VBox/Runtime/r3/win/VBoxRT-openssl-ose.def b/src/VBox/Runtime/r3/win/VBoxRT-openssl-ose.def
index b296ca6a9..8bdd5da8d 100644
--- a/src/VBox/Runtime/r3/win/VBoxRT-openssl-ose.def
+++ b/src/VBox/Runtime/r3/win/VBoxRT-openssl-ose.def
@@ -1,4 +1,4 @@
-; $Id: VBoxRT-openssl-ose.def $
+; $Id: VBoxRT-openssl-ose.def 38036 2011-07-18 16:36:29Z vboxsync $
;; @file
; IPRT - Windows OpenSSL exports.
;
@@ -9,7 +9,7 @@
;
;
-; Copyright (C) 2009 Oracle Corporation
+; Copyright (C) 2009-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;
@@ -224,6 +224,7 @@
BIO_dump_indent_cb
BIO_dump_indent_fp
BIO_dup_chain
+ BIO_f_buffer
BIO_find_type
BIO_free
BIO_free_all
@@ -241,6 +242,7 @@
BIO_new
BIO_new_file
BIO_new_fp
+ BIO_new_socket
BIO_next
BIO_number_read
BIO_number_written
@@ -250,6 +252,7 @@
BIO_puts
BIO_read
BIO_s_file
+ BIO_s_socket
BIO_set
BIO_set_callback
BIO_set_callback_arg
@@ -533,6 +536,7 @@
d2i_BASIC_CONSTRAINTS
d2i_CERTIFICATEPOLICIES
d2i_CRL_DIST_POINTS
+ d2i_DHparams
d2i_DIRECTORYSTRING
d2i_DISPLAYTEXT
d2i_DIST_POINT
@@ -759,6 +763,7 @@
ECDSA_sign_ex
ECDSA_sign_setup
ECDSA_size
+ ECDSA_verify
ECParameters_print
ECParameters_print_fp
ECPKParameters_print
@@ -799,6 +804,9 @@
ERR_unload_strings
EVP_add_cipher
EVP_add_digest
+ EVP_aes_128_cbc
+ EVP_aes_192_cbc
+ EVP_aes_256_cbc
EVP_BytesToKey
EVP_Cipher
EVP_CIPHER_asn1_to_param
@@ -851,6 +859,8 @@
EVP_DigestInit
EVP_DigestInit_ex
EVP_DigestUpdate
+ EVP_ecdsa
+ EVP_enc_null
EVP_EncodeBlock
EVP_EncodeFinal
EVP_EncodeInit
@@ -910,6 +920,7 @@
EVP_PKEY_set1_RSA
EVP_PKEY_size
EVP_PKEY_type
+ EVP_rc4
EVP_read_pw_string
EVP_set_pw_prompt
EVP_sha1
@@ -971,6 +982,7 @@
i2d_BASIC_CONSTRAINTS
i2d_CERTIFICATEPOLICIES
i2d_CRL_DIST_POINTS
+ i2d_DHparams
i2d_DIRECTORYSTRING
i2d_DISPLAYTEXT
i2d_DIST_POINT
@@ -1181,7 +1193,9 @@
PEM_proc_type
PEM_read_bio
PEM_read_bio_PrivateKey
+ PEM_read_bio_RSAPrivateKey
PEM_read_bio_X509
+ PEM_read_bio_X509_AUX
PEM_write_bio
PEM_write_bio_X509
PKCS7_DIGEST_free
@@ -1319,6 +1333,22 @@
sk_zero
SSLeay
SSLeay_version
+ SSL_accept
+ SSL_CTX_free
+ SSL_CTX_load_verify_locations
+ SSL_CTX_new
+ SSL_CTX_set_verify
+ SSL_CTX_use_certificate_file
+ SSL_CTX_use_PrivateKey_file
+ SSL_free
+ SSL_get_certificate
+ SSL_library_init
+ SSL_new
+ SSL_pending
+ SSL_read
+ SSL_set_bio
+ SSL_set_read_ahead
+ SSL_write
string_to_hex
SXNET_add_id_asc
SXNET_add_id_INTEGER
@@ -1330,6 +1360,7 @@
SXNET_new
SXNETID_free
SXNETID_new
+ TLSv1_server_method
UI_add_error_string
UI_add_info_string
UI_add_input_boolean
@@ -1416,6 +1447,7 @@
X509_CERT_AUX_print
X509_CERT_PAIR_free
X509_CERT_PAIR_new
+ X509_certificate_type
X509_check_ca
X509_check_issued
X509_check_private_key
@@ -1582,6 +1614,17 @@
X509_SIG_new
X509_sign
X509_signature_print
+ X509_STORE_CTX_cleanup
+ X509_STORE_CTX_get_ex_new_index
+ X509_STORE_CTX_get0_param
+ X509_STORE_CTX_init
+ X509_STORE_CTX_set_default
+ X509_STORE_CTX_set_ex_data
+ X509_STORE_CTX_set_verify_cb
+ X509_STORE_free
+ X509_STORE_load_locations
+ X509_STORE_new
+ X509_STORE_set_default_paths
X509_subject_name_cmp
X509_subject_name_hash
X509_supported_extension
@@ -1590,6 +1633,15 @@
X509_VAL_free
X509_VAL_new
X509_verify
+ X509_verify_cert
+ X509_VERIFY_PARAM_free
+ X509_VERIFY_PARAM_get_depth
+ X509_VERIFY_PARAM_inherit
+ X509_VERIFY_PARAM_new
+ X509_VERIFY_PARAM_set_depth
+ X509_VERIFY_PARAM_set_purpose
+ X509_VERIFY_PARAM_set_trust
+ X509_VERIFY_PARAM_set1
X509at_add1_attr
X509at_add1_attr_by_NID
X509at_add1_attr_by_OBJ
diff --git a/src/VBox/Runtime/r3/win/VBoxRT-openssl.def b/src/VBox/Runtime/r3/win/VBoxRT-openssl.def
index 875c1b481..713a993d0 100644
--- a/src/VBox/Runtime/r3/win/VBoxRT-openssl.def
+++ b/src/VBox/Runtime/r3/win/VBoxRT-openssl.def
@@ -1,4 +1,4 @@
-; $Id: VBoxRT-openssl.def $
+; $Id: VBoxRT-openssl.def 37254 2011-05-30 12:09:59Z vboxsync $
;; @file
; IPRT - Windows OpenSSL exports.
;
@@ -30,7 +30,7 @@
;
;
- ; OpenSSL symbols
+ ; OpenSSL crypto symbols
;
_CONF_add_string
_CONF_free_data
@@ -47,6 +47,20 @@
a2i_IPADDRESS_NC
ACCESS_DESCRIPTION_free
ACCESS_DESCRIPTION_new
+ AES_cbc_encrypt
+ AES_cfb1_encrypt
+ AES_cfb128_encrypt
+ AES_cfb8_encrypt
+ AES_cfbr_encrypt_block
+ AES_ctr128_encrypt
+ AES_decrypt
+ AES_ecb_encrypt
+ AES_encrypt
+ AES_ofb128_encrypt
+ AES_options
+ AES_set_decrypt_key
+ AES_set_encrypt_key
+ asc2uni
asn1_add_error
ASN1_BIT_STRING_free
ASN1_BIT_STRING_get_bit
@@ -162,10 +176,10 @@
ASN1_STRING_print_ex
ASN1_STRING_print_ex_fp
ASN1_STRING_set
- ASN1_STRING_set0
ASN1_STRING_set_by_NID
ASN1_STRING_set_default_mask
ASN1_STRING_set_default_mask_asc
+ ASN1_STRING_set0
ASN1_STRING_TABLE_add
ASN1_STRING_TABLE_cleanup
ASN1_STRING_TABLE_get
@@ -192,9 +206,9 @@
ASN1_TYPE_get_octetstring
ASN1_TYPE_new
ASN1_TYPE_set
- ASN1_TYPE_set1
ASN1_TYPE_set_int_octetstring
ASN1_TYPE_set_octetstring
+ ASN1_TYPE_set1
ASN1_UNIVERSALSTRING_free
ASN1_UNIVERSALSTRING_new
ASN1_UNIVERSALSTRING_to_string
@@ -217,8 +231,11 @@
AUTHORITY_KEYID_new
BASIC_CONSTRAINTS_free
BASIC_CONSTRAINTS_new
+ BIO_accept
BIO_callback_ctrl
BIO_clear_flags
+ BIO_CONNECT_free
+ BIO_CONNECT_new
BIO_copy_next_retry
BIO_ctrl
BIO_ctrl_pending
@@ -230,23 +247,30 @@
BIO_dump_indent_cb
BIO_dump_indent_fp
BIO_dup_chain
+ BIO_f_buffer
BIO_find_type
BIO_free
BIO_free_all
+ BIO_get_accept_socket
BIO_get_callback
BIO_get_callback_arg
BIO_get_ex_data
BIO_get_ex_new_index
+ BIO_get_host_ip
+ BIO_get_port
BIO_get_retry_BIO
BIO_get_retry_reason
+ BIO_gethostbyname
BIO_gets
BIO_indent
BIO_int_ctrl
BIO_method_name
BIO_method_type
BIO_new
+ BIO_new_connect
BIO_new_file
BIO_new_fp
+ BIO_new_socket
BIO_next
BIO_number_read
BIO_number_written
@@ -255,12 +279,22 @@
BIO_push
BIO_puts
BIO_read
+ BIO_s_connect
BIO_s_file
+ BIO_s_socket
BIO_set
BIO_set_callback
BIO_set_callback_arg
BIO_set_ex_data
BIO_set_flags
+ BIO_set_tcp_ndelay
+ BIO_sock_cleanup
+ BIO_sock_error
+ BIO_sock_init
+ BIO_sock_non_fatal_error
+ BIO_sock_should_retry
+ BIO_socket_ioctl
+ BIO_socket_nbio
BIO_test_flags
BIO_vfree
BIO_write
@@ -312,13 +346,13 @@
BN_gcd
BN_GENCB_call
BN_generate_prime_ex
+ BN_get_params
+ BN_get_word
BN_get0_nist_prime_192
BN_get0_nist_prime_224
BN_get0_nist_prime_256
BN_get0_nist_prime_384
BN_get0_nist_prime_521
- BN_get_params
- BN_get_word
BN_GF2m_add
BN_GF2m_arr2poly
BN_GF2m_mod
@@ -357,9 +391,9 @@
BN_mod_exp_simple
BN_mod_inverse
BN_mod_lshift
+ BN_mod_lshift_quick
BN_mod_lshift1
BN_mod_lshift1_quick
- BN_mod_lshift_quick
BN_mod_mul
BN_mod_mul_montgomery
BN_mod_mul_reciprocal
@@ -442,6 +476,11 @@
c2i_ASN1_OBJECT
CERTIFICATEPOLICIES_free
CERTIFICATEPOLICIES_new
+ COMP_compress_block
+ COMP_CTX_free
+ COMP_CTX_new
+ COMP_expand_block
+ COMP_zlib
CONF_dump_bio
CONF_dump_fp
CONF_free
@@ -555,6 +594,7 @@
d2i_BASIC_CONSTRAINTS
d2i_CERTIFICATEPOLICIES
d2i_CRL_DIST_POINTS
+ d2i_DHparams
d2i_DIRECTORYSTRING
d2i_DISPLAYTEXT
d2i_DIST_POINT
@@ -562,16 +602,19 @@
d2i_EC_PRIVATEKEY
d2i_EC_PUBKEY
d2i_EC_PUBKEY_bio
+ d2i_EC_PUBKEY_fp
d2i_ECDSA_SIG
d2i_ECParameters
- d2i_ECPKPARAMETERS
d2i_ECPKParameters
+ d2i_ECPKPARAMETERS
d2i_ECPrivateKey
d2i_ECPrivateKey_bio
+ d2i_ECPrivateKey_fp
d2i_EDIPARTYNAME
d2i_EXTENDED_KEY_USAGE
d2i_GENERAL_NAME
d2i_GENERAL_NAMES
+ d2i_NETSCAPE_CERT_SEQUENCE
d2i_NETSCAPE_SPKAC
d2i_NETSCAPE_SPKI
d2i_NOTICEREF
@@ -591,36 +634,52 @@
d2i_OCSP_SIGNATURE
d2i_OCSP_SINGLERESP
d2i_OTHERNAME
+ d2i_PBE2PARAM
+ d2i_PBEPARAM
+ d2i_PBKDF2PARAM
+ d2i_PKCS12
+ d2i_PKCS12_BAGS
+ d2i_PKCS12_bio
+ d2i_PKCS12_MAC_DATA
+ d2i_PKCS12_SAFEBAG
d2i_PKCS7
d2i_PKCS7_bio
d2i_PKCS7_DIGEST
d2i_PKCS7_ENC_CONTENT
d2i_PKCS7_ENCRYPT
d2i_PKCS7_ENVELOPE
+ d2i_PKCS7_fp
d2i_PKCS7_ISSUER_AND_SERIAL
d2i_PKCS7_RECIP_INFO
d2i_PKCS7_SIGN_ENVELOPE
d2i_PKCS7_SIGNED
d2i_PKCS7_SIGNER_INFO
d2i_PKCS8_bio
+ d2i_PKCS8_fp
d2i_PKCS8_PRIV_KEY_INFO
d2i_PKCS8_PRIV_KEY_INFO_bio
+ d2i_PKCS8_PRIV_KEY_INFO_fp
d2i_PKEY_USAGE_PERIOD
d2i_POLICYINFO
d2i_POLICYQUALINFO
d2i_PrivateKey
d2i_PrivateKey_bio
+ d2i_PrivateKey_fp
d2i_PROXY_CERT_INFO_EXTENSION
d2i_PROXY_POLICY
d2i_PUBKEY
d2i_PUBKEY_bio
+ d2i_PUBKEY_fp
d2i_PublicKey
d2i_RSA_PUBKEY
d2i_RSA_PUBKEY_bio
+ d2i_RSA_PUBKEY_fp
d2i_RSAPrivateKey
d2i_RSAPrivateKey_bio
+ d2i_RSAPrivateKey_fp
d2i_RSAPublicKey
d2i_RSAPublicKey_bio
+ d2i_RSAPublicKey_fp
d2i_SXNET
d2i_SXNETID
d2i_USERNOTICE
@@ -635,14 +694,18 @@
d2i_X509_CINF
d2i_X509_CRL
d2i_X509_CRL_bio
+ d2i_X509_CRL_fp
d2i_X509_CRL_INFO
d2i_X509_EXTENSION
d2i_X509_EXTENSIONS
+ d2i_X509_fp
d2i_X509_NAME
d2i_X509_NAME_ENTRY
+ d2i_X509_PKEY
d2i_X509_PUBKEY
d2i_X509_REQ
d2i_X509_REQ_bio
+ d2i_X509_REQ_fp
d2i_X509_REQ_INFO
d2i_X509_REVOKED
d2i_X509_SIG
@@ -703,7 +766,6 @@
EC_GF2m_simple_method
ec_GF2m_simple_mul
ec_GF2m_simple_oct2point
- ec_GF2m_simple_point2oct
ec_GF2m_simple_point_clear_finish
ec_GF2m_simple_point_copy
ec_GF2m_simple_point_finish
@@ -711,6 +773,7 @@
ec_GF2m_simple_point_init
ec_GF2m_simple_point_set_affine_coordinates
ec_GF2m_simple_point_set_to_infinity
+ ec_GF2m_simple_point2oct
ec_GF2m_simple_points_make_affine
ec_GF2m_simple_set_compressed_coordinates
ec_GFp_mont_field_decode
@@ -749,7 +812,6 @@
ec_GFp_simple_make_affine
EC_GFp_simple_method
ec_GFp_simple_oct2point
- ec_GFp_simple_point2oct
ec_GFp_simple_point_clear_finish
ec_GFp_simple_point_copy
ec_GFp_simple_point_finish
@@ -757,6 +819,7 @@
ec_GFp_simple_point_init
ec_GFp_simple_point_set_affine_coordinates
ec_GFp_simple_point_set_to_infinity
+ ec_GFp_simple_point2oct
ec_GFp_simple_points_make_affine
ec_GFp_simple_set_compressed_coordinates
ec_GFp_simple_set_Jprojective_coordinates_GFp
@@ -766,8 +829,6 @@
EC_GROUP_copy
EC_GROUP_dup
EC_GROUP_free
- EC_GROUP_get0_generator
- EC_GROUP_get0_seed
EC_GROUP_get_asn1_flag
EC_GROUP_get_basis_type
EC_GROUP_get_cofactor
@@ -780,6 +841,8 @@
EC_GROUP_get_point_conversion_form
EC_GROUP_get_seed_len
EC_GROUP_get_trinomial_basis
+ EC_GROUP_get0_generator
+ EC_GROUP_get0_seed
EC_GROUP_have_precompute_mult
EC_GROUP_method_of
EC_GROUP_new
@@ -799,12 +862,12 @@
EC_KEY_dup
EC_KEY_free
EC_KEY_generate_key
- EC_KEY_get0_group
- EC_KEY_get0_private_key
- EC_KEY_get0_public_key
EC_KEY_get_conv_form
EC_KEY_get_enc_flags
EC_KEY_get_key_method_data
+ EC_KEY_get0_group
+ EC_KEY_get0_private_key
+ EC_KEY_get0_public_key
EC_KEY_insert_key_method_data
EC_KEY_new
EC_KEY_new_by_curve_name
@@ -858,6 +921,7 @@
ecdsa_check
ECDSA_do_sign
ECDSA_do_sign_ex
+ ECDSA_do_verify
ECDSA_get_default_method
ECDSA_get_ex_data
ECDSA_get_ex_new_index
@@ -871,6 +935,7 @@
ECDSA_sign_ex
ECDSA_sign_setup
ECDSA_size
+ ECDSA_verify
ECPARAMETERS_free
ECPARAMETERS_new
ECParameters_print
@@ -915,6 +980,24 @@
ERR_unload_strings
EVP_add_cipher
EVP_add_digest
+ EVP_aes_128_cbc
+ EVP_aes_128_cfb1
+ EVP_aes_128_cfb128
+ EVP_aes_128_cfb8
+ EVP_aes_128_ecb
+ EVP_aes_128_ofb
+ EVP_aes_192_cbc
+ EVP_aes_192_cfb1
+ EVP_aes_192_cfb128
+ EVP_aes_192_cfb8
+ EVP_aes_192_ecb
+ EVP_aes_192_ofb
+ EVP_aes_256_cbc
+ EVP_aes_256_cfb1
+ EVP_aes_256_cfb128
+ EVP_aes_256_cfb8
+ EVP_aes_256_ecb
+ EVP_aes_256_ofb
EVP_BytesToKey
EVP_Cipher
EVP_CIPHER_asn1_to_param
@@ -967,6 +1050,8 @@
EVP_DigestInit
EVP_DigestInit_ex
EVP_DigestUpdate
+ EVP_ecdsa
+ EVP_enc_null
EVP_EncodeBlock
EVP_EncodeFinal
EVP_EncodeInit
@@ -979,7 +1064,6 @@
EVP_get_cipherbyname
EVP_get_digestbyname
EVP_get_pw_prompt
- EVP_md5
EVP_MD_block_size
EVP_MD_CTX_cleanup
EVP_MD_CTX_clear_flags
@@ -994,12 +1078,11 @@
EVP_MD_pkey_type
EVP_MD_size
EVP_MD_type
+ EVP_md5
EVP_PBE_alg_add
EVP_PBE_CipherInit
EVP_PBE_cleanup
EVP_PKCS82PKEY
- EVP_PKEY2PKCS8
- EVP_PKEY2PKCS8_broken
EVP_PKEY_add1_attr
EVP_PKEY_add1_attr_by_NID
EVP_PKEY_add1_attr_by_OBJ
@@ -1011,13 +1094,13 @@
EVP_PKEY_copy_parameters
EVP_PKEY_delete_attr
EVP_PKEY_free
- EVP_PKEY_get1_DH
- EVP_PKEY_get1_EC_KEY
- EVP_PKEY_get1_RSA
EVP_PKEY_get_attr
EVP_PKEY_get_attr_by_NID
EVP_PKEY_get_attr_by_OBJ
EVP_PKEY_get_attr_count
+ EVP_PKEY_get1_DH
+ EVP_PKEY_get1_EC_KEY
+ EVP_PKEY_get1_RSA
EVP_PKEY_missing_parameters
EVP_PKEY_new
EVP_PKEY_save_parameters
@@ -1026,6 +1109,10 @@
EVP_PKEY_set1_RSA
EVP_PKEY_size
EVP_PKEY_type
+ EVP_PKEY2PKCS8
+ EVP_PKEY2PKCS8_broken
+ EVP_rc4
+ EVP_rc4_40
EVP_read_pw_string
EVP_set_pw_prompt
EVP_sha1
@@ -1087,6 +1174,7 @@
i2d_BASIC_CONSTRAINTS
i2d_CERTIFICATEPOLICIES
i2d_CRL_DIST_POINTS
+ i2d_DHparams
i2d_DIRECTORYSTRING
i2d_DISPLAYTEXT
i2d_DIST_POINT
@@ -1094,16 +1182,19 @@
i2d_EC_PRIVATEKEY
i2d_EC_PUBKEY
i2d_EC_PUBKEY_bio
+ i2d_EC_PUBKEY_fp
i2d_ECDSA_SIG
i2d_ECParameters
- i2d_ECPKPARAMETERS
i2d_ECPKParameters
+ i2d_ECPKPARAMETERS
i2d_ECPrivateKey
i2d_ECPrivateKey_bio
+ i2d_ECPrivateKey_fp
i2d_EDIPARTYNAME
i2d_EXTENDED_KEY_USAGE
i2d_GENERAL_NAME
i2d_GENERAL_NAMES
+ i2d_NETSCAPE_CERT_SEQUENCE
i2d_NETSCAPE_SPKAC
i2d_NETSCAPE_SPKI
i2d_NOTICEREF
@@ -1123,12 +1214,21 @@
i2d_OCSP_SIGNATURE
i2d_OCSP_SINGLERESP
i2d_OTHERNAME
+ i2d_PBE2PARAM
+ i2d_PBEPARAM
+ i2d_PBKDF2PARAM
+ i2d_PKCS12
+ i2d_PKCS12_BAGS
+ i2d_PKCS12_bio
+ i2d_PKCS12_MAC_DATA
+ i2d_PKCS12_SAFEBAG
i2d_PKCS7
i2d_PKCS7_bio
i2d_PKCS7_DIGEST
i2d_PKCS7_ENC_CONTENT
i2d_PKCS7_ENCRYPT
i2d_PKCS7_ENVELOPE
+ i2d_PKCS7_fp
i2d_PKCS7_ISSUER_AND_SERIAL
i2d_PKCS7_NDEF
i2d_PKCS7_RECIP_INFO
@@ -1136,25 +1236,33 @@
i2d_PKCS7_SIGNED
i2d_PKCS7_SIGNER_INFO
i2d_PKCS8_bio
+ i2d_PKCS8_fp
i2d_PKCS8_PRIV_KEY_INFO
i2d_PKCS8_PRIV_KEY_INFO_bio
+ i2d_PKCS8_PRIV_KEY_INFO_fp
i2d_PKCS8PrivateKeyInfo_bio
+ i2d_PKCS8PrivateKeyInfo_fp
i2d_PKEY_USAGE_PERIOD
i2d_POLICYINFO
i2d_POLICYQUALINFO
i2d_PrivateKey
i2d_PrivateKey_bio
+ i2d_PrivateKey_fp
i2d_PROXY_CERT_INFO_EXTENSION
i2d_PROXY_POLICY
i2d_PUBKEY
i2d_PUBKEY_bio
+ i2d_PUBKEY_fp
i2d_PublicKey
i2d_RSA_PUBKEY
i2d_RSA_PUBKEY_bio
+ i2d_RSA_PUBKEY_fp
i2d_RSAPrivateKey
i2d_RSAPrivateKey_bio
+ i2d_RSAPrivateKey_fp
i2d_RSAPublicKey
i2d_RSAPublicKey_bio
+ i2d_RSAPublicKey_fp
i2d_SXNET
i2d_SXNETID
i2d_USERNOTICE
@@ -1169,14 +1277,18 @@
i2d_X509_CINF
i2d_X509_CRL
i2d_X509_CRL_bio
+ i2d_X509_CRL_fp
i2d_X509_CRL_INFO
i2d_X509_EXTENSION
i2d_X509_EXTENSIONS
+ i2d_X509_fp
i2d_X509_NAME
i2d_X509_NAME_ENTRY
+ i2d_X509_PKEY
i2d_X509_PUBKEY
i2d_X509_REQ
i2d_X509_REQ_bio
+ i2d_X509_REQ_fp
i2d_X509_REQ_INFO
i2d_X509_REVOKED
i2d_X509_SIG
@@ -1190,6 +1302,8 @@
i2v_ASN1_BIT_STRING
i2v_GENERAL_NAME
i2v_GENERAL_NAMES
+ level_add_node
+ level_find_node
lh_delete
lh_doall
lh_doall_arg
@@ -1204,6 +1318,7 @@
MD5_Init
MD5_Transform
MD5_Update
+ MGF1
name_cmp
NAME_CONSTRAINTS_free
NAME_CONSTRAINTS_new
@@ -1220,6 +1335,8 @@
NCONF_load_fp
NCONF_new
NCONF_WIN32
+ NETSCAPE_CERT_SEQUENCE_free
+ NETSCAPE_CERT_SEQUENCE_new
NETSCAPE_SPKAC_free
NETSCAPE_SPKAC_new
NETSCAPE_SPKI_free
@@ -1285,12 +1402,21 @@
OCSP_SIGNATURE_new
OCSP_SINGLERESP_free
OCSP_SINGLERESP_new
+ OpenSSL_add_all_ciphers
OPENSSL_cleanse
+ OPENSSL_DIR_end
+ OPENSSL_DIR_read
OPENSSL_gmtime
OPENSSL_isservice
OpenSSLDie
OTHERNAME_free
OTHERNAME_new
+ PBE2PARAM_free
+ PBE2PARAM_new
+ PBEPARAM_free
+ PBEPARAM_new
+ PBKDF2PARAM_free
+ PBKDF2PARAM_new
PEM_ASN1_read_bio
PEM_ASN1_write_bio
PEM_bytes_read_bio
@@ -1300,10 +1426,89 @@
PEM_get_EVP_CIPHER_INFO
PEM_proc_type
PEM_read_bio
+ PEM_read_bio_DHparams
+ PEM_read_bio_EC_PUBKEY
+ PEM_read_bio_ECPKParameters
+ PEM_read_bio_ECPrivateKey
+ PEM_read_bio_NETSCAPE_CERT_SEQUENCE
+ PEM_read_bio_PKCS7
PEM_read_bio_PrivateKey
+ PEM_read_bio_PUBKEY
+ PEM_read_bio_RSA_PUBKEY
+ PEM_read_bio_RSAPrivateKey
+ PEM_read_bio_RSAPublicKey
PEM_read_bio_X509
+ PEM_read_bio_X509_AUX
+ PEM_read_bio_X509_CERT_PAIR
+ PEM_read_bio_X509_CRL
+ PEM_read_bio_X509_REQ
PEM_write_bio
+ PEM_write_bio_DHparams
+ PEM_write_bio_EC_PUBKEY
+ PEM_write_bio_ECPKParameters
+ PEM_write_bio_ECPrivateKey
+ PEM_write_bio_NETSCAPE_CERT_SEQUENCE
+ PEM_write_bio_PKCS7
+ PEM_write_bio_PrivateKey
+ PEM_write_bio_PUBKEY
+ PEM_write_bio_RSA_PUBKEY
+ PEM_write_bio_RSAPrivateKey
+ PEM_write_bio_RSAPublicKey
PEM_write_bio_X509
+ PEM_write_bio_X509_AUX
+ PEM_write_bio_X509_CERT_PAIR
+ PEM_write_bio_X509_CRL
+ PEM_write_bio_X509_REQ
+ PEM_write_bio_X509_REQ_NEW
+ PEM_X509_INFO_read_bio
+ PEM_X509_INFO_write_bio
+ pitem_free
+ pitem_new
+ PKCS1_MGF1
+ PKCS12_BAGS_free
+ PKCS12_BAGS_new
+ PKCS12_certbag2x509
+ PKCS12_certbag2x509crl
+ PKCS12_decrypt_skey
+ PKCS12_free
+ PKCS12_item_decrypt_d2i
+ PKCS12_item_i2d_encrypt
+ PKCS12_item_pack_safebag
+ PKCS12_key_gen_asc
+ PKCS12_key_gen_uni
+ PKCS12_MAC_DATA_free
+ PKCS12_MAC_DATA_new
+ PKCS12_MAKE_KEYBAG
+ PKCS12_MAKE_SHKEYBAG
+ PKCS12_new
+ PKCS12_pack_authsafes
+ PKCS12_pack_p7data
+ PKCS12_pack_p7encdata
+ PKCS12_PBE_add
+ PKCS12_pbe_crypt
+ PKCS12_PBE_keyivgen
+ PKCS12_SAFEBAG_free
+ PKCS12_SAFEBAG_new
+ PKCS12_unpack_authsafes
+ PKCS12_unpack_p7data
+ PKCS12_unpack_p7encdata
+ PKCS12_x5092certbag
+ PKCS12_x509crl2certbag
+ PKCS5_PBE_add
+ PKCS5_PBE_keyivgen
+ PKCS5_pbe_set
+ PKCS5_pbe2_set
+ PKCS5_PBKDF2_HMAC_SHA1
+ PKCS5_v2_PBE_keyivgen
+ PKCS7_add_certificate
+ PKCS7_add_crl
+ PKCS7_add_recipient
+ PKCS7_add_recipient_info
+ PKCS7_add_signature
+ PKCS7_add_signer
+ PKCS7_cert_from_signer_info
+ PKCS7_content_new
+ PKCS7_ctrl
PKCS7_DIGEST_free
PKCS7_DIGEST_new
PKCS7_dup
@@ -1314,18 +1519,28 @@
PKCS7_ENVELOPE_free
PKCS7_ENVELOPE_new
PKCS7_free
+ PKCS7_get_signer_info
PKCS7_ISSUER_AND_SERIAL_digest
PKCS7_ISSUER_AND_SERIAL_free
PKCS7_ISSUER_AND_SERIAL_new
PKCS7_new
PKCS7_RECIP_INFO_free
PKCS7_RECIP_INFO_new
+ PKCS7_RECIP_INFO_set
+ PKCS7_set_cipher
+ PKCS7_set_content
+ PKCS7_set_digest
+ PKCS7_set_type
+ PKCS7_set0_type_other
PKCS7_SIGN_ENVELOPE_free
PKCS7_SIGN_ENVELOPE_new
PKCS7_SIGNED_free
PKCS7_SIGNED_new
PKCS7_SIGNER_INFO_free
PKCS7_SIGNER_INFO_new
+ PKCS7_SIGNER_INFO_set
+ PKCS8_decrypt
+ PKCS8_encrypt
PKCS8_PRIV_KEY_INFO_free
PKCS8_PRIV_KEY_INFO_new
PKCS8_set_broken
@@ -1341,10 +1556,21 @@
policy_data_new
POLICY_MAPPING_free
POLICY_MAPPING_new
+ policy_node_cmp_new
+ policy_node_free
POLICYINFO_free
POLICYINFO_new
POLICYQUALINFO_free
POLICYQUALINFO_new
+ pqueue_find
+ pqueue_free
+ pqueue_insert
+ pqueue_iterator
+ pqueue_new
+ pqueue_next
+ pqueue_peek
+ pqueue_pop
+ pqueue_size
PROXY_CERT_INFO_EXTENSION_free
PROXY_CERT_INFO_EXTENSION_new
PROXY_POLICY_free
@@ -1381,6 +1607,19 @@
RSA_new
RSA_new_method
RSA_null_method
+ RSA_padding_add_none
+ RSA_padding_add_PKCS1_OAEP
+ RSA_padding_add_PKCS1_type_1
+ RSA_padding_add_PKCS1_type_2
+ RSA_padding_add_SSLv23
+ RSA_padding_add_X931
+ RSA_padding_check_none
+ RSA_padding_check_PKCS1_OAEP
+ RSA_padding_check_PKCS1_type_1
+ RSA_padding_check_PKCS1_type_2
+ RSA_padding_check_SSLv23
+ RSA_padding_check_X931
+ RSA_PKCS1_SSLeay
RSA_print
RSA_print_fp
RSA_private_decrypt
@@ -1395,6 +1634,7 @@
RSA_size
RSA_up_ref
RSA_verify
+ RSA_X931_hash_id
RSAPrivateKey_asn1_meth
RSAPrivateKey_dup
RSAPublicKey_dup
@@ -1457,6 +1697,7 @@
SXNET_new
SXNETID_free
SXNETID_new
+ tree_find_sk
UI_add_error_string
UI_add_info_string
UI_add_input_boolean
@@ -1473,12 +1714,6 @@
UI_dup_input_string
UI_dup_verify_string
UI_free
- UI_get0_action_string
- UI_get0_output_string
- UI_get0_result
- UI_get0_result_string
- UI_get0_test_string
- UI_get0_user_data
UI_get_default_method
UI_get_ex_data
UI_get_ex_new_index
@@ -1487,6 +1722,12 @@
UI_get_result_maxsize
UI_get_result_minsize
UI_get_string_type
+ UI_get0_action_string
+ UI_get0_output_string
+ UI_get0_result
+ UI_get0_result_string
+ UI_get0_test_string
+ UI_get0_user_data
UI_method_get_closer
UI_method_get_flusher
UI_method_get_opener
@@ -1505,6 +1746,7 @@
UI_set_ex_data
UI_set_method
UI_set_result
+ uni2asc
USERNOTICE_free
USERNOTICE_new
UTF8_getc
@@ -1513,10 +1755,10 @@
v2i_GENERAL_NAME
v2i_GENERAL_NAME_ex
v2i_GENERAL_NAMES
+ X509_add_ext
X509_add1_ext_i2d
X509_add1_reject_object
X509_add1_trust_object
- X509_add_ext
X509_ALGOR_dup
X509_ALGOR_free
X509_ALGOR_get0
@@ -1543,16 +1785,20 @@
X509_CERT_AUX_print
X509_CERT_PAIR_free
X509_CERT_PAIR_new
+ X509_certificate_type
X509_check_ca
X509_check_issued
X509_check_private_key
X509_check_purpose
+ X509_check_trust
X509_CINF_free
X509_CINF_new
X509_cmp
+ X509_cmp_current_time
+ X509_cmp_time
+ X509_CRL_add_ext
X509_CRL_add0_revoked
X509_CRL_add1_ext_i2d
- X509_CRL_add_ext
X509_CRL_cmp
X509_CRL_delete_ext
X509_CRL_digest
@@ -1587,9 +1833,12 @@
X509_find_by_issuer_and_serial
X509_find_by_subject
X509_free
- X509_get0_pubkey_bitstr
- X509_get1_email
- X509_get1_ocsp
+ X509_get_default_cert_area
+ X509_get_default_cert_dir
+ X509_get_default_cert_dir_env
+ X509_get_default_cert_file
+ X509_get_default_cert_file_env
+ X509_get_default_private_dir
X509_get_ex_data
X509_get_ex_new_index
X509_get_ext
@@ -1600,14 +1849,35 @@
X509_get_ext_d2i
X509_get_issuer_name
X509_get_pubkey
+ X509_get_pubkey_parameters
X509_get_serialNumber
X509_get_subject_name
+ X509_get0_pubkey_bitstr
+ X509_get1_email
+ X509_get1_ocsp
+ X509_gmtime_adj
+ X509_INFO_free
+ X509_INFO_new
X509_issuer_and_serial_cmp
X509_issuer_and_serial_hash
X509_issuer_name_cmp
X509_issuer_name_hash
X509_keyid_get0
X509_keyid_set1
+ X509_load_cert_crl_file
+ X509_load_cert_file
+ X509_load_crl_file
+ X509_LOOKUP_by_alias
+ X509_LOOKUP_by_fingerprint
+ X509_LOOKUP_by_issuer_serial
+ X509_LOOKUP_by_subject
+ X509_LOOKUP_ctrl
+ X509_LOOKUP_file
+ X509_LOOKUP_free
+ X509_LOOKUP_hash_dir
+ X509_LOOKUP_init
+ X509_LOOKUP_new
+ X509_LOOKUP_shutdown
X509_NAME_add_entry
X509_NAME_add_entry_by_NID
X509_NAME_add_entry_by_OBJ
@@ -1641,8 +1911,26 @@
X509_NAME_print_ex_fp
X509_NAME_set
X509_new
+ X509_OBJECT_free_contents
+ X509_OBJECT_idx_by_subject
+ X509_OBJECT_retrieve_by_subject
+ X509_OBJECT_retrieve_match
+ X509_OBJECT_up_ref_count
X509_ocspid_print
+ X509_PKEY_free
+ X509_PKEY_new
+ X509_policy_check
+ X509_policy_level_get0_node
+ X509_policy_level_node_count
+ X509_policy_node_get0_parent
+ X509_policy_node_get0_policy
+ X509_policy_node_get0_qualifiers
X509_POLICY_NODE_print
+ X509_policy_tree_free
+ X509_policy_tree_get0_level
+ X509_policy_tree_get0_policies
+ X509_policy_tree_get0_user_policies
+ X509_policy_tree_level_count
X509_print
X509_print_ex
X509_print_ex_fp
@@ -1654,29 +1942,28 @@
X509_PUBKEY_set
X509_PURPOSE_add
X509_PURPOSE_cleanup
- X509_PURPOSE_get0
- X509_PURPOSE_get0_name
- X509_PURPOSE_get0_sname
X509_PURPOSE_get_by_id
X509_PURPOSE_get_by_sname
X509_PURPOSE_get_count
X509_PURPOSE_get_id
X509_PURPOSE_get_trust
+ X509_PURPOSE_get0
+ X509_PURPOSE_get0_name
+ X509_PURPOSE_get0_sname
X509_PURPOSE_set
X509_reject_clear
+ X509_REQ_add_extensions
+ X509_REQ_add_extensions_nid
X509_REQ_add1_attr
X509_REQ_add1_attr_by_NID
X509_REQ_add1_attr_by_OBJ
X509_REQ_add1_attr_by_txt
- X509_REQ_add_extensions
- X509_REQ_add_extensions_nid
X509_REQ_check_private_key
X509_REQ_delete_attr
X509_REQ_digest
X509_REQ_dup
X509_REQ_extension_nid
X509_REQ_free
- X509_REQ_get1_email
X509_REQ_get_attr
X509_REQ_get_attr_by_NID
X509_REQ_get_attr_by_OBJ
@@ -1684,6 +1971,7 @@
X509_REQ_get_extension_nids
X509_REQ_get_extensions
X509_REQ_get_pubkey
+ X509_REQ_get1_email
X509_REQ_INFO_free
X509_REQ_INFO_new
X509_REQ_new
@@ -1693,8 +1981,8 @@
X509_REQ_set_version
X509_REQ_sign
X509_REQ_verify
- X509_REVOKED_add1_ext_i2d
X509_REVOKED_add_ext
+ X509_REVOKED_add1_ext_i2d
X509_REVOKED_delete_ext
X509_REVOKED_free
X509_REVOKED_get_ext
@@ -1709,25 +1997,98 @@
X509_SIG_new
X509_sign
X509_signature_print
+ X509_STORE_add_cert
+ X509_STORE_add_crl
+ X509_STORE_add_lookup
+ X509_STORE_CTX_cleanup
+ X509_STORE_CTX_free
+ X509_STORE_CTX_get_chain
+ X509_STORE_CTX_get_current_cert
+ X509_STORE_CTX_get_error
+ X509_STORE_CTX_get_error_depth
+ X509_STORE_CTX_get_ex_data
+ X509_STORE_CTX_get_ex_new_index
+ X509_STORE_CTX_get_explicit_policy
+ X509_STORE_CTX_get0_param
+ X509_STORE_CTX_get0_policy_tree
+ X509_STORE_CTX_get1_chain
+ X509_STORE_CTX_get1_issuer
+ X509_STORE_CTX_init
+ X509_STORE_CTX_new
+ X509_STORE_CTX_purpose_inherit
+ X509_STORE_CTX_set_cert
+ X509_STORE_CTX_set_chain
+ X509_STORE_CTX_set_default
+ X509_STORE_CTX_set_depth
+ X509_STORE_CTX_set_error
+ X509_STORE_CTX_set_ex_data
+ X509_STORE_CTX_set_flags
+ X509_STORE_CTX_set_purpose
+ X509_STORE_CTX_set_time
+ X509_STORE_CTX_set_trust
+ X509_STORE_CTX_set_verify_cb
+ X509_STORE_CTX_set0_crls
+ X509_STORE_CTX_set0_param
+ X509_STORE_CTX_trusted_stack
+ X509_STORE_free
+ X509_STORE_get_by_subject
+ X509_STORE_load_locations
+ X509_STORE_new
+ X509_STORE_set_default_paths
+ X509_STORE_set_depth
+ X509_STORE_set_flags
+ X509_STORE_set_purpose
+ X509_STORE_set_trust
+ X509_STORE_set1_param
X509_subject_name_cmp
X509_subject_name_hash
X509_supported_extension
+ X509_time_adj
X509_to_X509_REQ
+ X509_TRUST_add
+ X509_TRUST_cleanup
X509_trust_clear
+ X509_TRUST_get_by_id
+ X509_TRUST_get_count
+ X509_TRUST_get_flags
+ X509_TRUST_get_trust
+ X509_TRUST_get0
+ X509_TRUST_get0_name
+ X509_TRUST_set
+ X509_TRUST_set_default
X509_VAL_free
X509_VAL_new
X509_verify
+ X509_verify_cert
+ X509_verify_cert_error_string
+ X509_VERIFY_PARAM_add0_policy
+ X509_VERIFY_PARAM_add0_table
+ X509_VERIFY_PARAM_clear_flags
+ X509_VERIFY_PARAM_free
+ X509_VERIFY_PARAM_get_depth
+ X509_VERIFY_PARAM_get_flags
+ X509_VERIFY_PARAM_inherit
+ X509_VERIFY_PARAM_lookup
+ X509_VERIFY_PARAM_new
+ X509_VERIFY_PARAM_set_depth
+ X509_VERIFY_PARAM_set_flags
+ X509_VERIFY_PARAM_set_purpose
+ X509_VERIFY_PARAM_set_time
+ X509_VERIFY_PARAM_set_trust
+ X509_VERIFY_PARAM_set1
+ X509_VERIFY_PARAM_set1_name
+ X509_VERIFY_PARAM_set1_policies
+ X509_VERIFY_PARAM_table_cleanup
X509at_add1_attr
X509at_add1_attr_by_NID
X509at_add1_attr_by_OBJ
X509at_add1_attr_by_txt
X509at_delete_attr
- X509at_get0_data_by_OBJ
X509at_get_attr
X509at_get_attr_by_NID
X509at_get_attr_by_OBJ
X509at_get_attr_count
- X509V3_add1_i2d
+ X509at_get0_data_by_OBJ
X509v3_add_ext
X509V3_add_standard_extensions
X509V3_add_value
@@ -1735,6 +2096,7 @@
X509V3_add_value_bool_nf
X509V3_add_value_int
X509V3_add_value_uchar
+ X509V3_add1_i2d
X509V3_conf_free
X509v3_delete_ext
X509V3_EXT_add
@@ -1781,3 +2143,454 @@
X9_62_CHARACTERISTIC_TWO_new
X9_62_PENTANOMIAL_free
X9_62_PENTANOMIAL_new
+
+ ;
+ ; OpenSSL ssl symbols
+ ;
+ BIO_f_ssl
+ BIO_new_buffer_ssl_connect
+ BIO_new_ssl
+ BIO_new_ssl_connect
+ BIO_ssl_copy_session_id
+ BIO_ssl_shutdown
+ check_srvr_ecc_cert_and_alg
+ d2i_SSL_SESSION
+ do_dtls1_write
+ dtls1_accept
+ dtls1_buffer_message
+ dtls1_clear
+ dtls1_clear_record_buffer
+ dtls1_client_hello
+ dtls1_connect
+ dtls1_ctrl
+ dtls1_default_timeout
+ dtls1_dispatch_alert
+ dtls1_do_write
+ dtls1_double_timeout
+ dtls1_enc
+ dtls1_free
+ dtls1_get_ccs_header
+ dtls1_get_cipher
+ dtls1_get_message
+ dtls1_get_message_header
+ dtls1_get_queue_priority
+ dtls1_get_record
+ dtls1_get_timeout
+ dtls1_handle_timeout
+ dtls1_is_timer_expired
+ dtls1_listen
+ dtls1_new
+ dtls1_output_cert_chain
+ dtls1_read_bytes
+ dtls1_read_failed
+ dtls1_reset_seq_numbers
+ dtls1_retransmit_buffered_messages
+ dtls1_retransmit_message
+ dtls1_send_certificate_request
+ dtls1_send_change_cipher_spec
+ dtls1_send_client_certificate
+ dtls1_send_client_key_exchange
+ dtls1_send_client_verify
+ dtls1_send_finished
+ dtls1_send_hello_request
+ dtls1_send_newsession_ticket
+ dtls1_send_server_certificate
+ dtls1_send_server_done
+ dtls1_send_server_hello
+ dtls1_send_server_key_exchange
+ dtls1_set_message_header
+ dtls1_start_timer
+ dtls1_stop_timer
+ dtls1_write_app_data_bytes
+ dtls1_write_bytes
+ dtlsv1_base_method
+ DTLSv1_client_method
+ DTLSv1_method
+ DTLSv1_server_method
+ ERR_load_SSL_strings
+ i2d_SSL_SESSION
+ SSL_accept
+ SSL_add_client_CA
+ ssl_add_clienthello_renegotiate_ext
+ ssl_add_clienthello_tlsext
+ SSL_add_dir_cert_subjects_to_stack
+ SSL_add_file_cert_subjects_to_stack
+ ssl_add_serverhello_renegotiate_ext
+ ssl_add_serverhello_tlsext
+ SSL_alert_desc_string
+ SSL_alert_desc_string_long
+ SSL_alert_type_string
+ SSL_alert_type_string_long
+ ssl_bad_method
+ ssl_bytes_to_cipher_list
+ SSL_callback_ctrl
+ ssl_cert_dup
+ ssl_cert_free
+ ssl_cert_inst
+ ssl_cert_new
+ ssl_cert_type
+ ssl_check_clienthello_tlsext
+ SSL_check_private_key
+ ssl_check_serverhello_tlsext
+ SSL_CIPHER_description
+ SSL_CIPHER_get_bits
+ ssl_cipher_get_evp
+ SSL_CIPHER_get_name
+ SSL_CIPHER_get_version
+ ssl_cipher_id_cmp
+ ssl_cipher_list_to_bytes
+ ssl_cipher_ptr_id_cmp
+ SSL_clear
+ ssl_clear_bad_session
+ ssl_clear_cipher_ctx
+ SSL_COMP_add_compression_method
+ SSL_COMP_get_compression_methods
+ SSL_COMP_get_name
+ SSL_connect
+ SSL_copy_session_id
+ ssl_create_cipher_list
+ SSL_ctrl
+ SSL_CTX_add_client_CA
+ SSL_CTX_add_session
+ SSL_CTX_callback_ctrl
+ SSL_CTX_check_private_key
+ SSL_CTX_ctrl
+ SSL_CTX_flush_sessions
+ SSL_CTX_free
+ SSL_CTX_get_cert_store
+ SSL_CTX_get_client_CA_list
+ SSL_CTX_get_client_cert_cb
+ SSL_CTX_get_ex_data
+ SSL_CTX_get_ex_new_index
+ SSL_CTX_get_info_callback
+ SSL_CTX_get_quiet_shutdown
+ SSL_CTX_get_timeout
+ SSL_CTX_get_verify_callback
+ SSL_CTX_get_verify_depth
+ SSL_CTX_get_verify_mode
+ SSL_CTX_load_verify_locations
+ SSL_CTX_new
+ SSL_CTX_remove_session
+ SSL_CTX_sess_get_get_cb
+ SSL_CTX_sess_get_new_cb
+ SSL_CTX_sess_get_remove_cb
+ SSL_CTX_sess_set_get_cb
+ SSL_CTX_sess_set_new_cb
+ SSL_CTX_sess_set_remove_cb
+ SSL_CTX_sessions
+ SSL_CTX_set_cert_store
+ SSL_CTX_set_cert_verify_callback
+ SSL_CTX_set_cipher_list
+ SSL_CTX_set_client_CA_list
+ SSL_CTX_set_client_cert_cb
+ SSL_CTX_set_cookie_generate_cb
+ SSL_CTX_set_cookie_verify_cb
+ SSL_CTX_set_default_passwd_cb
+ SSL_CTX_set_default_passwd_cb_userdata
+ SSL_CTX_set_default_verify_paths
+ SSL_CTX_set_ex_data
+ SSL_CTX_set_generate_session_id
+ SSL_CTX_set_info_callback
+ SSL_CTX_set_msg_callback
+ SSL_CTX_set_purpose
+ SSL_CTX_set_quiet_shutdown
+ SSL_CTX_set_session_id_context
+ SSL_CTX_set_ssl_version
+ SSL_CTX_set_timeout
+ SSL_CTX_set_tmp_dh_callback
+ SSL_CTX_set_tmp_rsa_callback
+ SSL_CTX_set_trust
+ SSL_CTX_set_verify
+ SSL_CTX_set_verify_depth
+ SSL_CTX_use_certificate
+ SSL_CTX_use_certificate_ASN1
+ SSL_CTX_use_certificate_chain_file
+ SSL_CTX_use_certificate_file
+ SSL_CTX_use_PrivateKey
+ SSL_CTX_use_PrivateKey_ASN1
+ SSL_CTX_use_PrivateKey_file
+ SSL_CTX_use_RSAPrivateKey
+ SSL_CTX_use_RSAPrivateKey_ASN1
+ SSL_CTX_use_RSAPrivateKey_file
+ ssl_do_client_cert_cb
+ SSL_do_handshake
+ SSL_dup
+ SSL_dup_CA_list
+ SSL_free
+ ssl_free_wbio_buffer
+ SSL_get_certificate
+ SSL_get_cipher_list
+ SSL_get_ciphers
+ ssl_get_ciphers_by_id
+ SSL_get_client_CA_list
+ SSL_get_current_cipher
+ SSL_get_current_compression
+ SSL_get_current_expansion
+ SSL_get_default_timeout
+ SSL_get_error
+ SSL_get_ex_data
+ SSL_get_ex_data_X509_STORE_CTX_idx
+ SSL_get_ex_new_index
+ SSL_get_fd
+ SSL_get_finished
+ SSL_get_info_callback
+ ssl_get_new_session
+ SSL_get_peer_cert_chain
+ SSL_get_peer_certificate
+ SSL_get_peer_finished
+ ssl_get_prev_session
+ SSL_get_privatekey
+ SSL_get_quiet_shutdown
+ SSL_get_rbio
+ SSL_get_read_ahead
+ SSL_get_rfd
+ ssl_get_server_send_cert
+ SSL_get_servername
+ SSL_get_servername_type
+ SSL_get_session
+ SSL_get_shared_ciphers
+ SSL_get_shutdown
+ ssl_get_sign_pkey
+ SSL_get_SSL_CTX
+ SSL_get_ssl_method
+ SSL_get_verify_callback
+ SSL_get_verify_depth
+ SSL_get_verify_mode
+ SSL_get_verify_result
+ SSL_get_version
+ SSL_get_wbio
+ SSL_get_wfd
+ SSL_get1_session
+ SSL_has_matching_session_id
+ ssl_init_wbio_buffer
+ SSL_library_init
+ ssl_load_ciphers
+ SSL_load_client_CA_file
+ SSL_load_error_strings
+ SSL_new
+ ssl_ok
+ ssl_parse_clienthello_renegotiate_ext
+ ssl_parse_clienthello_tlsext
+ ssl_parse_serverhello_renegotiate_ext
+ ssl_parse_serverhello_tlsext
+ SSL_peek
+ SSL_pending
+ SSL_read
+ SSL_renegotiate
+ SSL_renegotiate_pending
+ SSL_rstate_string
+ SSL_rstate_string_long
+ ssl_sess_cert_free
+ ssl_sess_cert_new
+ SSL_SESSION_cmp
+ SSL_SESSION_free
+ SSL_SESSION_get_ex_data
+ SSL_SESSION_get_ex_new_index
+ SSL_SESSION_get_id
+ SSL_SESSION_get_time
+ SSL_SESSION_get_timeout
+ SSL_SESSION_hash
+ SSL_SESSION_new
+ SSL_SESSION_print
+ SSL_SESSION_print_fp
+ SSL_SESSION_set_ex_data
+ SSL_SESSION_set_time
+ SSL_SESSION_set_timeout
+ SSL_set_accept_state
+ SSL_set_bio
+ ssl_set_cert_masks
+ SSL_set_cipher_list
+ SSL_set_client_CA_list
+ SSL_set_connect_state
+ SSL_set_ex_data
+ SSL_set_fd
+ SSL_set_generate_session_id
+ SSL_set_info_callback
+ SSL_set_msg_callback
+ ssl_set_peer_cert_type
+ SSL_set_purpose
+ SSL_set_quiet_shutdown
+ SSL_set_read_ahead
+ SSL_set_rfd
+ SSL_set_session
+ SSL_set_session_id_context
+ SSL_set_shutdown
+ SSL_set_SSL_CTX
+ SSL_set_ssl_method
+ SSL_set_tmp_dh_callback
+ SSL_set_tmp_rsa_callback
+ SSL_set_trust
+ SSL_set_verify
+ SSL_set_verify_depth
+ SSL_set_verify_result
+ SSL_set_wfd
+ SSL_shutdown
+ SSL_state
+ SSL_state_string
+ SSL_state_string_long
+ ssl_undefined_const_function
+ ssl_undefined_function
+ ssl_undefined_void_function
+ ssl_update_cache
+ SSL_use_certificate
+ SSL_use_certificate_ASN1
+ SSL_use_certificate_file
+ SSL_use_PrivateKey
+ SSL_use_PrivateKey_ASN1
+ SSL_use_PrivateKey_file
+ SSL_use_RSAPrivateKey
+ SSL_use_RSAPrivateKey_ASN1
+ SSL_use_RSAPrivateKey_file
+ ssl_verify_alarm_type
+ ssl_verify_cert_chain
+ SSL_version
+ SSL_want
+ SSL_write
+ ssl2_accept
+ ssl2_callback_ctrl
+ ssl2_clear
+ ssl2_connect
+ ssl2_ctrl
+ ssl2_ctx_callback_ctrl
+ ssl2_ctx_ctrl
+ ssl2_default_timeout
+ ssl2_do_write
+ ssl2_enc
+ ssl2_enc_init
+ ssl2_free
+ ssl2_generate_key_material
+ ssl2_get_cipher
+ ssl2_get_cipher_by_char
+ ssl2_mac
+ ssl2_new
+ ssl2_num_ciphers
+ ssl2_part_read
+ ssl2_peek
+ ssl2_pending
+ ssl2_put_cipher_by_char
+ ssl2_read
+ ssl2_return_error
+ ssl2_set_certificate
+ ssl2_shutdown
+ ssl2_write
+ ssl2_write_error
+ ssl23_accept
+ ssl23_connect
+ ssl23_default_timeout
+ ssl23_get_cipher
+ ssl23_get_cipher_by_char
+ ssl23_get_client_hello
+ ssl23_num_ciphers
+ ssl23_peek
+ ssl23_put_cipher_by_char
+ ssl23_read
+ ssl23_read_bytes
+ ssl23_write
+ ssl23_write_bytes
+ ssl3_accept
+ ssl3_alert_code
+ ssl3_callback_ctrl
+ ssl3_cert_verify_mac
+ ssl3_change_cipher_state
+ ssl3_check_cert_and_algorithm
+ ssl3_check_client_hello
+ ssl3_check_finished
+ ssl3_choose_cipher
+ ssl3_cleanup_key_block
+ ssl3_clear
+ ssl3_client_hello
+ ssl3_comp_find
+ ssl3_connect
+ ssl3_ctrl
+ ssl3_ctx_callback_ctrl
+ ssl3_ctx_ctrl
+ ssl3_default_timeout
+ ssl3_dispatch_alert
+ ssl3_do_change_cipher_spec
+ ssl3_do_compress
+ ssl3_do_uncompress
+ ssl3_do_write
+ ssl3_enc
+ ssl3_final_finish_mac
+ ssl3_finish_mac
+ ssl3_free
+ ssl3_generate_master_secret
+ ssl3_get_cert_status
+ ssl3_get_cert_verify
+ ssl3_get_certificate_request
+ ssl3_get_cipher
+ ssl3_get_cipher_by_char
+ ssl3_get_client_certificate
+ ssl3_get_client_hello
+ ssl3_get_client_key_exchange
+ ssl3_get_finished
+ ssl3_get_key_exchange
+ ssl3_get_message
+ ssl3_get_new_session_ticket
+ ssl3_get_req_cert_type
+ ssl3_get_server_certificate
+ ssl3_get_server_done
+ ssl3_get_server_hello
+ ssl3_init_finished_mac
+ ssl3_mac
+ ssl3_new
+ ssl3_num_ciphers
+ ssl3_output_cert_chain
+ ssl3_peek
+ ssl3_pending
+ ssl3_put_cipher_by_char
+ ssl3_read
+ ssl3_read_bytes
+ ssl3_read_n
+ ssl3_record_sequence_update
+ ssl3_renegotiate
+ ssl3_renegotiate_check
+ ssl3_send_alert
+ ssl3_send_cert_status
+ ssl3_send_certificate_request
+ ssl3_send_change_cipher_spec
+ ssl3_send_client_certificate
+ ssl3_send_client_key_exchange
+ ssl3_send_client_verify
+ ssl3_send_finished
+ ssl3_send_hello_request
+ ssl3_send_newsession_ticket
+ ssl3_send_server_certificate
+ ssl3_send_server_done
+ ssl3_send_server_hello
+ ssl3_send_server_key_exchange
+ ssl3_setup_buffers
+ ssl3_setup_key_block
+ ssl3_shutdown
+ ssl3_write
+ ssl3_write_bytes
+ ssl3_write_pending
+ sslv2_base_method
+ SSLv2_client_method
+ SSLv2_method
+ SSLv2_server_method
+ sslv23_base_method
+ SSLv23_client_method
+ SSLv23_method
+ SSLv23_server_method
+ sslv3_base_method
+ SSLv3_client_method
+ SSLv3_method
+ SSLv3_server_method
+ tls1_alert_code
+ tls1_cert_verify_mac
+ tls1_change_cipher_state
+ tls1_clear
+ tls1_default_timeout
+ tls1_enc
+ tls1_final_finish_mac
+ tls1_free
+ tls1_generate_master_secret
+ tls1_mac
+ tls1_new
+ tls1_process_ticket
+ tls1_setup_key_block
+ tlsv1_base_method
+ TLSv1_client_method
+ TLSv1_method
+ TLSv1_server_method
diff --git a/src/VBox/Runtime/r3/win/VBoxRT-win32.def b/src/VBox/Runtime/r3/win/VBoxRT-win32.def
index ae6e5cdcb..1395665f8 100644
--- a/src/VBox/Runtime/r3/win/VBoxRT-win32.def
+++ b/src/VBox/Runtime/r3/win/VBoxRT-win32.def
@@ -1,4 +1,4 @@
-; $Id: VBoxRT-win32.def $
+; $Id: VBoxRT-win32.def 32404 2010-09-10 13:17:42Z vboxsync $
;; @file
; IPRT - Win32 ASM exports.
;
diff --git a/src/VBox/Runtime/r3/win/VBoxRT-win64.def b/src/VBox/Runtime/r3/win/VBoxRT-win64.def
index f0ad7c4e4..fbc41c243 100644
--- a/src/VBox/Runtime/r3/win/VBoxRT-win64.def
+++ b/src/VBox/Runtime/r3/win/VBoxRT-win64.def
@@ -1,4 +1,4 @@
-; $Id: VBoxRT-win64.def $
+; $Id: VBoxRT-win64.def 32404 2010-09-10 13:17:42Z vboxsync $
;; @file
; IPRT - Win64 ASM exports.
;
diff --git a/src/VBox/Runtime/r3/win/alloc-win.cpp b/src/VBox/Runtime/r3/win/alloc-win.cpp
index 01a0a359f..b7b3f75f4 100644
--- a/src/VBox/Runtime/r3/win/alloc-win.cpp
+++ b/src/VBox/Runtime/r3/win/alloc-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: alloc-win.cpp $ */
+/* $Id: alloc-win.cpp 33269 2010-10-20 15:42:28Z vboxsync $ */
/** @file
* IPRT - Memory Allocation, Windows.
*/
diff --git a/src/VBox/Runtime/r3/win/dir-win.cpp b/src/VBox/Runtime/r3/win/dir-win.cpp
index b5640696c..930d16acd 100644
--- a/src/VBox/Runtime/r3/win/dir-win.cpp
+++ b/src/VBox/Runtime/r3/win/dir-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: dir-win.cpp $ */
+/* $Id: dir-win.cpp 34507 2010-11-30 13:14:14Z vboxsync $ */
/** @file
* IPRT - Directory, win32.
*/
diff --git a/src/VBox/Runtime/r3/win/dllmain-win.cpp b/src/VBox/Runtime/r3/win/dllmain-win.cpp
index 9b553f6dc..953a95c80 100644
--- a/src/VBox/Runtime/r3/win/dllmain-win.cpp
+++ b/src/VBox/Runtime/r3/win/dllmain-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: dllmain-win.cpp $ */
+/* $Id: dllmain-win.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
/** @file
* IPRT - Win32 DllMain (Ring-3).
*/
@@ -30,6 +30,7 @@
*******************************************************************************/
#include <Windows.h>
#include <iprt/thread.h>
+#include <iprt/param.h>
#include "internal/thread.h"
@@ -41,7 +42,24 @@ BOOL __stdcall DllMain(HANDLE hModule, DWORD dwReason, PVOID pvReserved)
{
switch (dwReason)
{
+ /*
+ * When attaching to a process, we'd like to make sure IPRT stays put
+ * and doesn't get unloaded.
+ */
case DLL_PROCESS_ATTACH:
+ {
+ WCHAR wszName[RTPATH_MAX];
+ SetLastError(NO_ERROR);
+ if ( GetModuleFileNameW((HMODULE)hModule, wszName, RT_ELEMENTS(wszName)) > 0
+ && GetLastError() == NO_ERROR)
+ {
+ int cExtraLoads = 32;
+ while (cExtraLoads-- > 0)
+ LoadLibraryW(wszName);
+ }
+ break;
+ }
+
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
default:
@@ -54,3 +72,4 @@ BOOL __stdcall DllMain(HANDLE hModule, DWORD dwReason, PVOID pvReserved)
}
return TRUE;
}
+
diff --git a/src/VBox/Runtime/r3/win/errvars-win.cpp b/src/VBox/Runtime/r3/win/errvars-win.cpp
new file mode 100644
index 000000000..ef00e62a6
--- /dev/null
+++ b/src/VBox/Runtime/r3/win/errvars-win.cpp
@@ -0,0 +1,83 @@
+/* $Id: errvars-win.cpp 37233 2011-05-27 13:31:57Z vboxsync $ */
+/** @file
+ * IPRT - Save and Restore Error Variables, Windows Ring-3.
+ */
+
+/*
+ * 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.
+ *
+ * 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 <Winsock2.h>
+#include <errno.h>
+
+#include <iprt/err.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include "internal/magics.h"
+
+
+
+RTDECL(PRTERRVARS) RTErrVarsSave(PRTERRVARS pVars)
+{
+ pVars->ai32Vars[0] = RTERRVARS_MAGIC;
+ pVars->ai32Vars[1] = GetLastError();
+ pVars->ai32Vars[2] = WSAGetLastError();
+ pVars->ai32Vars[3] = errno;
+ return pVars;
+}
+
+
+RTDECL(void) RTErrVarsRestore(PCRTERRVARS pVars)
+{
+ AssertReturnVoid(pVars->ai32Vars[0] == RTERRVARS_MAGIC);
+ errno = pVars->ai32Vars[3];
+ if (pVars->ai32Vars[2] != WSANOTINITIALISED) /* just an idea... */
+ WSASetLastError(pVars->ai32Vars[2]);
+ SetLastError(pVars->ai32Vars[1]);
+}
+
+
+RTDECL(bool) RTErrVarsAreEqual(PCRTERRVARS pVars1, PCRTERRVARS pVars2)
+{
+ Assert(pVars1->ai32Vars[0] == RTERRVARS_MAGIC);
+ Assert(pVars2->ai32Vars[0] == RTERRVARS_MAGIC);
+
+ return pVars1->ai32Vars[0] == pVars2->ai32Vars[0]
+ && pVars1->ai32Vars[1] == pVars2->ai32Vars[1]
+ && pVars1->ai32Vars[2] == pVars2->ai32Vars[2]
+ && pVars1->ai32Vars[3] == pVars2->ai32Vars[3];
+}
+
+
+RTDECL(bool) RTErrVarsHaveChanged(PCRTERRVARS pVars)
+{
+ Assert(pVars->ai32Vars[0] == RTERRVARS_MAGIC);
+
+ return pVars->ai32Vars[0] != RTERRVARS_MAGIC
+ || pVars->ai32Vars[1] != GetLastError()
+ || pVars->ai32Vars[2] != WSAGetLastError()
+ || pVars->ai32Vars[3] != errno;
+}
+
diff --git a/src/VBox/Runtime/r3/win/fileaio-win.cpp b/src/VBox/Runtime/r3/win/fileaio-win.cpp
index cb32f3c72..6dc7f5fbf 100644
--- a/src/VBox/Runtime/r3/win/fileaio-win.cpp
+++ b/src/VBox/Runtime/r3/win/fileaio-win.cpp
@@ -1,10 +1,10 @@
-/* $Id: fileaio-win.cpp $ */
+/* $Id: fileaio-win.cpp 37607 2011-06-23 10:42:42Z vboxsync $ */
/** @file
* IPRT - File async I/O, native implementation for the Windows host platform.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -188,7 +188,7 @@ DECLINLINE(int) rtFileAioReqPrepareTransfer(RTFILEAIOREQ hReq, RTFILE hFile,
Assert(cbTransfer > 0);
pReqInt->enmTransferDirection = enmTransferDirection;
- pReqInt->hFile = (HANDLE)hFile;
+ pReqInt->hFile = (HANDLE)RTFileToNative(hFile);
pReqInt->Overlapped.Offset = (DWORD)(off & 0xffffffff);
pReqInt->Overlapped.OffsetHigh = (DWORD)(off >> 32);
pReqInt->cbTransfer = cbTransfer;
@@ -317,7 +317,7 @@ RTDECL(int) RTFileAioCtxAssociateWithFile(RTFILEAIOCTX hAioCtx, RTFILE hFile)
PRTFILEAIOCTXINTERNAL pCtxInt = hAioCtx;
RTFILEAIOCTX_VALID_RETURN(pCtxInt);
- HANDLE hTemp = CreateIoCompletionPort((HANDLE)hFile, pCtxInt->hIoCompletionPort, 0, 1);
+ HANDLE hTemp = CreateIoCompletionPort((HANDLE)RTFileToNative(hFile), pCtxInt->hIoCompletionPort, 0, 1);
if (hTemp != pCtxInt->hIoCompletionPort)
rc = RTErrConvertFromWin32(GetLastError());
diff --git a/src/VBox/Runtime/r3/win/fileio-win.cpp b/src/VBox/Runtime/r3/win/fileio-win.cpp
index de9f2b011..af09fc6b2 100644
--- a/src/VBox/Runtime/r3/win/fileio-win.cpp
+++ b/src/VBox/Runtime/r3/win/fileio-win.cpp
@@ -1,10 +1,10 @@
-/* $Id: fileio-win.cpp $ */
+/* $Id: fileio-win.cpp 37598 2011-06-22 20:58:35Z vboxsync $ */
/** @file
* IPRT - File I/O, native implementation for the Windows host platform.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -54,12 +54,12 @@
* it not being present in NT4 GA.
*
* @returns Success indicator. Extended error information obtainable using GetLastError().
- * @param File Filehandle.
+ * @param hFile Filehandle.
* @param offSeek Offset to seek.
* @param poffNew Where to store the new file offset. NULL allowed.
* @param uMethod Seek method. (The windows one!)
*/
-DECLINLINE(bool) MySetFilePointer(RTFILE File, uint64_t offSeek, uint64_t *poffNew, unsigned uMethod)
+DECLINLINE(bool) MySetFilePointer(RTFILE hFile, uint64_t offSeek, uint64_t *poffNew, unsigned uMethod)
{
bool fRc;
LARGE_INTEGER off;
@@ -68,17 +68,17 @@ DECLINLINE(bool) MySetFilePointer(RTFILE File, uint64_t offSeek, uint64_t *poffN
#if 1
if (off.LowPart != INVALID_SET_FILE_POINTER)
{
- off.LowPart = SetFilePointer((HANDLE)File, off.LowPart, &off.HighPart, uMethod);
+ off.LowPart = SetFilePointer((HANDLE)RTFileToNative(hFile), off.LowPart, &off.HighPart, uMethod);
fRc = off.LowPart != INVALID_SET_FILE_POINTER;
}
else
{
SetLastError(NO_ERROR);
- off.LowPart = SetFilePointer((HANDLE)File, off.LowPart, &off.HighPart, uMethod);
+ off.LowPart = SetFilePointer((HANDLE)RTFileToNative(hFile), off.LowPart, &off.HighPart, uMethod);
fRc = GetLastError() == NO_ERROR;
}
#else
- fRc = SetFilePointerEx((HANDLE)File, off, &off, uMethod);
+ fRc = SetFilePointerEx((HANDLE)RTFileToNative(hFile), off, &off, uMethod);
#endif
if (fRc && poffNew)
*poffNew = off.QuadPart;
@@ -91,11 +91,11 @@ DECLINLINE(bool) MySetFilePointer(RTFILE File, uint64_t offSeek, uint64_t *poffN
* limit of the filesystem.
*
* @returns true for file size limit exceeded.
- * @param File Filehandle.
+ * @param hFile Filehandle.
* @param offSeek Offset to seek.
* @param uMethod The seek method.
*/
-DECLINLINE(bool) IsBeyondLimit(RTFILE File, uint64_t offSeek, unsigned uMethod)
+DECLINLINE(bool) IsBeyondLimit(RTFILE hFile, uint64_t offSeek, unsigned uMethod)
{
bool fIsBeyondLimit = false;
@@ -107,12 +107,12 @@ DECLINLINE(bool) IsBeyondLimit(RTFILE File, uint64_t offSeek, unsigned uMethod)
* this supposedly works. The fastfat sources in the latest WDK makes no limit checks during
* file seeking, only at the time of writing (and some other odd ones we cannot make use of). */
uint64_t offCurrent;
- if (MySetFilePointer(File, 0, &offCurrent, FILE_CURRENT))
+ if (MySetFilePointer(hFile, 0, &offCurrent, FILE_CURRENT))
{
- if (!MySetFilePointer(File, offSeek, NULL, uMethod))
+ if (!MySetFilePointer(hFile, offSeek, NULL, uMethod))
fIsBeyondLimit = GetLastError() == ERROR_SEEK;
else /* Restore file pointer on success. */
- MySetFilePointer(File, offCurrent, NULL, FILE_BEGIN);
+ MySetFilePointer(hFile, offCurrent, NULL, FILE_BEGIN);
}
return fIsBeyondLimit;
@@ -122,8 +122,8 @@ DECLINLINE(bool) IsBeyondLimit(RTFILE File, uint64_t offSeek, unsigned uMethod)
RTR3DECL(int) RTFileFromNative(PRTFILE pFile, RTHCINTPTR uNative)
{
HANDLE h = (HANDLE)uNative;
- if ( h == INVALID_HANDLE_VALUE
- || (RTFILE)uNative != uNative)
+ AssertCompile(sizeof(h) == sizeof(uNative));
+ if (h == INVALID_HANDLE_VALUE)
{
AssertMsgFailed(("%p\n", uNative));
*pFile = NIL_RTFILE;
@@ -134,14 +134,14 @@ RTR3DECL(int) RTFileFromNative(PRTFILE pFile, RTHCINTPTR uNative)
}
-RTR3DECL(RTHCINTPTR) RTFileToNative(RTFILE File)
+RTR3DECL(RTHCINTPTR) RTFileToNative(RTFILE hFile)
{
- AssertReturn(File != NIL_RTFILE, (RTHCINTPTR)INVALID_HANDLE_VALUE);
- return (RTHCINTPTR)File;
+ AssertReturn(hFile != NIL_RTFILE, (RTHCINTPTR)INVALID_HANDLE_VALUE);
+ return (RTHCINTPTR)hFile;
}
-RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint32_t fOpen)
+RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint64_t fOpen)
{
/*
* Validate input.
@@ -185,7 +185,7 @@ RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint32_t fOpen)
dwCreationDisposition = CREATE_ALWAYS;
break;
default:
- AssertMsgFailed(("Impossible fOpen=%#x\n", fOpen));
+ AssertMsgFailed(("Impossible fOpen=%#llx\n", fOpen));
return VERR_INVALID_PARAMETER;
}
@@ -206,7 +206,7 @@ RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint32_t fOpen)
: FILE_GENERIC_READ | FILE_GENERIC_WRITE;
break;
default:
- AssertMsgFailed(("Impossible fOpen=%#x\n", fOpen));
+ AssertMsgFailed(("Impossible fOpen=%#llx\n", fOpen));
return VERR_INVALID_PARAMETER;
}
if (dwCreationDisposition == TRUNCATE_EXISTING)
@@ -227,7 +227,7 @@ RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint32_t fOpen)
case RTFILE_O_WRITE: dwDesiredAccess |= FILE_WRITE_ATTRIBUTES | SYNCHRONIZE; break;
case RTFILE_O_READWRITE: dwDesiredAccess |= FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE; break;
default:
- AssertMsgFailed(("Impossible fOpen=%#x\n", fOpen));
+ AssertMsgFailed(("Impossible fOpen=%#llx\n", fOpen));
return VERR_INVALID_PARAMETER;
}
}
@@ -245,7 +245,7 @@ RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint32_t fOpen)
case RTFILE_O_DENY_NOT_DELETE | RTFILE_O_DENY_WRITE: dwShareMode = FILE_SHARE_DELETE | FILE_SHARE_READ; break;
case RTFILE_O_DENY_NOT_DELETE | RTFILE_O_DENY_READWRITE:dwShareMode = FILE_SHARE_DELETE; break;
default:
- AssertMsgFailed(("Impossible fOpen=%#x\n", fOpen));
+ AssertMsgFailed(("Impossible fOpen=%#llx\n", fOpen));
return VERR_INVALID_PARAMETER;
}
@@ -328,7 +328,7 @@ RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint32_t fOpen)
}
-RTR3DECL(int) RTFileOpenBitBucket(PRTFILE phFile, uint32_t fAccess)
+RTR3DECL(int) RTFileOpenBitBucket(PRTFILE phFile, uint64_t fAccess)
{
AssertReturn( fAccess == RTFILE_O_READ
|| fAccess == RTFILE_O_WRITE
@@ -338,17 +338,40 @@ RTR3DECL(int) RTFileOpenBitBucket(PRTFILE phFile, uint32_t fAccess)
}
-RTR3DECL(int) RTFileClose(RTFILE File)
+RTR3DECL(int) RTFileClose(RTFILE hFile)
{
- if (File == NIL_RTFILE)
+ if (hFile == NIL_RTFILE)
return VINF_SUCCESS;
- if (CloseHandle((HANDLE)File))
+ if (CloseHandle((HANDLE)RTFileToNative(hFile)))
return VINF_SUCCESS;
return RTErrConvertFromWin32(GetLastError());
}
-RTR3DECL(int) RTFileSeek(RTFILE File, int64_t offSeek, unsigned uMethod, uint64_t *poffActual)
+RTFILE rtFileGetStandard(RTHANDLESTD enmStdHandle)
+{
+ DWORD dwStdHandle;
+ switch (enmStdHandle)
+ {
+ case RTHANDLESTD_INPUT: dwStdHandle = STD_INPUT_HANDLE; break;
+ case RTHANDLESTD_OUTPUT: dwStdHandle = STD_OUTPUT_HANDLE; break;
+ case RTHANDLESTD_ERROR: dwStdHandle = STD_ERROR_HANDLE; break;
+ break;
+ default:
+ AssertFailedReturn(NIL_RTFILE);
+ }
+
+ HANDLE hNative = GetStdHandle(dwStdHandle);
+ if (hNative == INVALID_HANDLE_VALUE)
+ return NIL_RTFILE;
+
+ RTFILE hFile = (RTFILE)(uintptr_t)hNative;
+ AssertReturn((HANDLE)(uintptr_t)hFile == hNative, NIL_RTFILE);
+ return hFile;
+}
+
+
+RTR3DECL(int) RTFileSeek(RTFILE hFile, int64_t offSeek, unsigned uMethod, uint64_t *poffActual)
{
static ULONG aulSeekRecode[] =
{
@@ -369,13 +392,13 @@ RTR3DECL(int) RTFileSeek(RTFILE File, int64_t offSeek, unsigned uMethod, uint64
/*
* Execute the seek.
*/
- if (MySetFilePointer(File, offSeek, poffActual, aulSeekRecode[uMethod]))
+ if (MySetFilePointer(hFile, offSeek, poffActual, aulSeekRecode[uMethod]))
return VINF_SUCCESS;
return RTErrConvertFromWin32(GetLastError());
}
-RTR3DECL(int) RTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcbRead)
+RTR3DECL(int) RTFileRead(RTFILE hFile, void *pvBuf, size_t cbToRead, size_t *pcbRead)
{
if (cbToRead <= 0)
return VINF_SUCCESS;
@@ -383,7 +406,7 @@ RTR3DECL(int) RTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcb
AssertReturn(cbToReadAdj == cbToRead, VERR_NUMBER_TOO_BIG);
ULONG cbRead = 0;
- if (ReadFile((HANDLE)File, pvBuf, cbToReadAdj, &cbRead, NULL))
+ if (ReadFile((HANDLE)RTFileToNative(hFile), pvBuf, cbToReadAdj, &cbRead, NULL))
{
if (pcbRead)
/* Caller can handle partial reads. */
@@ -394,7 +417,7 @@ RTR3DECL(int) RTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcb
while (cbToReadAdj > cbRead)
{
ULONG cbReadPart = 0;
- if (!ReadFile((HANDLE)File, (char*)pvBuf + cbRead, cbToReadAdj - cbRead, &cbReadPart, NULL))
+ if (!ReadFile((HANDLE)RTFileToNative(hFile), (char*)pvBuf + cbRead, cbToReadAdj - cbRead, &cbReadPart, NULL))
return RTErrConvertFromWin32(GetLastError());
if (cbReadPart == 0)
return VERR_EOF;
@@ -404,9 +427,9 @@ RTR3DECL(int) RTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcb
return VINF_SUCCESS;
}
- /*
- * If it's a console, we might bump into out of memory conditions in the
- * ReadConsole call.
+ /*
+ * If it's a console, we might bump into out of memory conditions in the
+ * ReadConsole call.
*/
DWORD dwErr = GetLastError();
if (dwErr == ERROR_NOT_ENOUGH_MEMORY)
@@ -422,7 +445,7 @@ RTR3DECL(int) RTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcb
{
ULONG cbToRead = RT_MIN(cbChunk, cbToReadAdj - cbRead);
ULONG cbReadPart = 0;
- if (!ReadFile((HANDLE)File, (char *)pvBuf + cbRead, cbToRead, &cbReadPart, NULL))
+ if (!ReadFile((HANDLE)RTFileToNative(hFile), (char *)pvBuf + cbRead, cbToRead, &cbReadPart, NULL))
{
/* If we failed because the buffer is too big, shrink it and
try again. */
@@ -449,12 +472,12 @@ RTR3DECL(int) RTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcb
}
return VINF_SUCCESS;
}
-
+
return RTErrConvertFromWin32(dwErr);
}
-RTR3DECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
+RTR3DECL(int) RTFileWrite(RTFILE hFile, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
{
if (cbToWrite <= 0)
return VINF_SUCCESS;
@@ -462,7 +485,7 @@ RTR3DECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, siz
AssertReturn(cbToWriteAdj == cbToWrite, VERR_NUMBER_TOO_BIG);
ULONG cbWritten = 0;
- if (WriteFile((HANDLE)File, pvBuf, cbToWriteAdj, &cbWritten, NULL))
+ if (WriteFile((HANDLE)RTFileToNative(hFile), pvBuf, cbToWriteAdj, &cbWritten, NULL))
{
if (pcbWritten)
/* Caller can handle partial writes. */
@@ -473,11 +496,12 @@ RTR3DECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, siz
while (cbToWriteAdj > cbWritten)
{
ULONG cbWrittenPart = 0;
- if (!WriteFile((HANDLE)File, (char*)pvBuf + cbWritten, cbToWriteAdj - cbWritten, &cbWrittenPart, NULL))
+ if (!WriteFile((HANDLE)RTFileToNative(hFile), (char*)pvBuf + cbWritten,
+ cbToWriteAdj - cbWritten, &cbWrittenPart, NULL))
{
int rc = RTErrConvertFromWin32(GetLastError());
if ( rc == VERR_DISK_FULL
- && IsBeyondLimit(File, cbToWriteAdj - cbWritten, FILE_CURRENT)
+ && IsBeyondLimit(hFile, cbToWriteAdj - cbWritten, FILE_CURRENT)
)
rc = VERR_FILE_TOO_BIG;
return rc;
@@ -490,9 +514,9 @@ RTR3DECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, siz
return VINF_SUCCESS;
}
- /*
- * If it's a console, we might bump into out of memory conditions in the
- * WriteConsole call.
+ /*
+ * If it's a console, we might bump into out of memory conditions in the
+ * WriteConsole call.
*/
DWORD dwErr = GetLastError();
if (dwErr == ERROR_NOT_ENOUGH_MEMORY)
@@ -508,7 +532,7 @@ RTR3DECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, siz
{
ULONG cbToWrite = RT_MIN(cbChunk, cbToWriteAdj - cbWritten);
ULONG cbWrittenPart = 0;
- if (!WriteFile((HANDLE)File, (const char *)pvBuf + cbWritten, cbToWrite, &cbWrittenPart, NULL))
+ if (!WriteFile((HANDLE)RTFileToNative(hFile), (const char *)pvBuf + cbWritten, cbToWrite, &cbWrittenPart, NULL))
{
/* If we failed because the buffer is too big, shrink it and
try again. */
@@ -521,7 +545,7 @@ RTR3DECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, siz
}
int rc = RTErrConvertFromWin32(dwErr);
if ( rc == VERR_DISK_FULL
- && IsBeyondLimit(File, cbToWriteAdj - cbWritten, FILE_CURRENT))
+ && IsBeyondLimit(hFile, cbToWriteAdj - cbWritten, FILE_CURRENT))
rc = VERR_FILE_TOO_BIG;
return rc;
}
@@ -542,15 +566,15 @@ RTR3DECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, siz
int rc = RTErrConvertFromWin32(dwErr);
if ( rc == VERR_DISK_FULL
- && IsBeyondLimit(File, cbToWriteAdj - cbWritten, FILE_CURRENT))
+ && IsBeyondLimit(hFile, cbToWriteAdj - cbWritten, FILE_CURRENT))
rc = VERR_FILE_TOO_BIG;
return rc;
}
-RTR3DECL(int) RTFileFlush(RTFILE File)
+RTR3DECL(int) RTFileFlush(RTFILE hFile)
{
- if (!FlushFileBuffers((HANDLE)File))
+ if (!FlushFileBuffers((HANDLE)RTFileToNative(hFile)))
{
int rc = GetLastError();
Log(("FlushFileBuffers failed with %d\n", rc));
@@ -560,28 +584,28 @@ RTR3DECL(int) RTFileFlush(RTFILE File)
}
-RTR3DECL(int) RTFileSetSize(RTFILE File, uint64_t cbSize)
+RTR3DECL(int) RTFileSetSize(RTFILE hFile, uint64_t cbSize)
{
/*
* Get current file pointer.
*/
int rc;
uint64_t offCurrent;
- if (MySetFilePointer(File, 0, &offCurrent, FILE_CURRENT))
+ if (MySetFilePointer(hFile, 0, &offCurrent, FILE_CURRENT))
{
/*
* Set new file pointer.
*/
- if (MySetFilePointer(File, cbSize, NULL, FILE_BEGIN))
+ if (MySetFilePointer(hFile, cbSize, NULL, FILE_BEGIN))
{
/* set file pointer */
- if (SetEndOfFile((HANDLE)File))
+ if (SetEndOfFile((HANDLE)RTFileToNative(hFile)))
{
/*
* Restore file pointer and return.
* If the old pointer was beyond the new file end, ignore failure.
*/
- if ( MySetFilePointer(File, offCurrent, NULL, FILE_BEGIN)
+ if ( MySetFilePointer(hFile, offCurrent, NULL, FILE_BEGIN)
|| offCurrent > cbSize)
return VINF_SUCCESS;
}
@@ -590,7 +614,7 @@ RTR3DECL(int) RTFileSetSize(RTFILE File, uint64_t cbSize)
* Failed, try restoring the file pointer.
*/
rc = GetLastError();
- MySetFilePointer(File, offCurrent, NULL, FILE_BEGIN);
+ MySetFilePointer(hFile, offCurrent, NULL, FILE_BEGIN);
}
else
rc = GetLastError();
@@ -602,10 +626,10 @@ RTR3DECL(int) RTFileSetSize(RTFILE File, uint64_t cbSize)
}
-RTR3DECL(int) RTFileGetSize(RTFILE File, uint64_t *pcbSize)
+RTR3DECL(int) RTFileGetSize(RTFILE hFile, uint64_t *pcbSize)
{
ULARGE_INTEGER Size;
- Size.LowPart = GetFileSize((HANDLE)File, &Size.HighPart);
+ Size.LowPart = GetFileSize((HANDLE)RTFileToNative(hFile), &Size.HighPart);
if (Size.LowPart != INVALID_FILE_SIZE)
{
*pcbSize = Size.QuadPart;
@@ -617,7 +641,7 @@ RTR3DECL(int) RTFileGetSize(RTFILE File, uint64_t *pcbSize)
}
-RTR3DECL(int) RTFileGetMaxSizeEx(RTFILE File, PRTFOFF pcbMax)
+RTR3DECL(int) RTFileGetMaxSizeEx(RTFILE hFile, PRTFOFF pcbMax)
{
/** @todo r=bird:
* We might have to make this code OS specific...
@@ -629,11 +653,11 @@ RTR3DECL(int) RTFileGetMaxSizeEx(RTFILE File, PRTFOFF pcbMax)
}
-RTR3DECL(bool) RTFileIsValid(RTFILE File)
+RTR3DECL(bool) RTFileIsValid(RTFILE hFile)
{
- if (File != NIL_RTFILE)
+ if (hFile != NIL_RTFILE)
{
- DWORD dwType = GetFileType((HANDLE)File);
+ DWORD dwType = GetFileType((HANDLE)RTFileToNative(hFile));
switch (dwType)
{
case FILE_TYPE_CHAR:
@@ -655,7 +679,7 @@ RTR3DECL(bool) RTFileIsValid(RTFILE File)
#define LOW_DWORD(u64) ((DWORD)u64)
#define HIGH_DWORD(u64) (((DWORD *)&u64)[1])
-RTR3DECL(int) RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock)
+RTR3DECL(int) RTFileLock(RTFILE hFile, unsigned fLock, int64_t offLock, uint64_t cbLock)
{
Assert(offLock >= 0);
@@ -680,14 +704,14 @@ RTR3DECL(int) RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t
Overlapped.OffsetHigh = HIGH_DWORD(offLock);
/* Note: according to Microsoft, LockFileEx API call is available starting from NT 3.5 */
- if (LockFileEx((HANDLE)File, dwFlags, 0, LOW_DWORD(cbLock), HIGH_DWORD(cbLock), &Overlapped))
+ if (LockFileEx((HANDLE)RTFileToNative(hFile), dwFlags, 0, LOW_DWORD(cbLock), HIGH_DWORD(cbLock), &Overlapped))
return VINF_SUCCESS;
return RTErrConvertFromWin32(GetLastError());
}
-RTR3DECL(int) RTFileChangeLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock)
+RTR3DECL(int) RTFileChangeLock(RTFILE hFile, unsigned fLock, int64_t offLock, uint64_t cbLock)
{
Assert(offLock >= 0);
@@ -699,18 +723,18 @@ RTR3DECL(int) RTFileChangeLock(RTFILE File, unsigned fLock, int64_t offLock, ui
}
/* Remove old lock. */
- int rc = RTFileUnlock(File, offLock, cbLock);
+ int rc = RTFileUnlock(hFile, offLock, cbLock);
if (RT_FAILURE(rc))
return rc;
/* Set new lock. */
- rc = RTFileLock(File, fLock, offLock, cbLock);
+ rc = RTFileLock(hFile, fLock, offLock, cbLock);
if (RT_SUCCESS(rc))
return rc;
/* Try to restore old lock. */
unsigned fLockOld = (fLock & RTFILE_LOCK_WRITE) ? fLock & ~RTFILE_LOCK_WRITE : fLock | RTFILE_LOCK_WRITE;
- rc = RTFileLock(File, fLockOld, offLock, cbLock);
+ rc = RTFileLock(hFile, fLockOld, offLock, cbLock);
if (RT_SUCCESS(rc))
return VERR_FILE_LOCK_VIOLATION;
else
@@ -718,11 +742,13 @@ RTR3DECL(int) RTFileChangeLock(RTFILE File, unsigned fLock, int64_t offLock, ui
}
-RTR3DECL(int) RTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock)
+RTR3DECL(int) RTFileUnlock(RTFILE hFile, int64_t offLock, uint64_t cbLock)
{
Assert(offLock >= 0);
- if (UnlockFile((HANDLE)File, LOW_DWORD(offLock), HIGH_DWORD(offLock), LOW_DWORD(cbLock), HIGH_DWORD(cbLock)))
+ if (UnlockFile((HANDLE)RTFileToNative(hFile),
+ LOW_DWORD(offLock), HIGH_DWORD(offLock),
+ LOW_DWORD(cbLock), HIGH_DWORD(cbLock)))
return VINF_SUCCESS;
return RTErrConvertFromWin32(GetLastError());
@@ -730,14 +756,14 @@ RTR3DECL(int) RTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock)
-RTR3DECL(int) RTFileQueryInfo(RTFILE File, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
+RTR3DECL(int) RTFileQueryInfo(RTFILE hFile, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
{
/*
* Validate input.
*/
- if (File == NIL_RTFILE)
+ if (hFile == NIL_RTFILE)
{
- AssertMsgFailed(("Invalid File=%RTfile\n", File));
+ AssertMsgFailed(("Invalid hFile=%RTfile\n", hFile));
return VERR_INVALID_PARAMETER;
}
if (!pObjInfo)
@@ -756,8 +782,14 @@ RTR3DECL(int) RTFileQueryInfo(RTFILE File, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD
* Query file info.
*/
BY_HANDLE_FILE_INFORMATION Data;
- if (!GetFileInformationByHandle((HANDLE)File, &Data))
- return RTErrConvertFromWin32(GetLastError());
+ if (!GetFileInformationByHandle((HANDLE)RTFileToNative(hFile), &Data))
+ {
+ DWORD dwErr = GetLastError();
+ /* Only return if we *really* don't have a valid handle value,
+ * everything else is fine here ... */
+ if (dwErr != ERROR_INVALID_HANDLE)
+ return RTErrConvertFromWin32(dwErr);
+ }
/*
* Setup the returned data.
@@ -821,7 +853,7 @@ RTR3DECL(int) RTFileQueryInfo(RTFILE File, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD
}
-RTR3DECL(int) RTFileSetTimes(RTFILE File, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
+RTR3DECL(int) RTFileSetTimes(RTFILE hFile, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
{
if (!pAccessTime && !pModificationTime && !pBirthTime)
@@ -843,12 +875,12 @@ RTR3DECL(int) RTFileSetTimes(RTFILE File, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC
pLastWriteTimeFT = RTTimeSpecGetNtFileTime(pModificationTime, &LastWriteTimeFT);
int rc = VINF_SUCCESS;
- if (!SetFileTime((HANDLE)File, pCreationTimeFT, pLastAccessTimeFT, pLastWriteTimeFT))
+ if (!SetFileTime((HANDLE)RTFileToNative(hFile), pCreationTimeFT, pLastAccessTimeFT, pLastWriteTimeFT))
{
DWORD Err = GetLastError();
rc = RTErrConvertFromWin32(Err);
Log(("RTFileSetTimes(%RTfile, %p, %p, %p, %p): SetFileTime failed with lasterr %d (%Rrc)\n",
- File, pAccessTime, pModificationTime, pChangeTime, pBirthTime, Err, rc));
+ hFile, pAccessTime, pModificationTime, pChangeTime, pBirthTime, Err, rc));
}
return rc;
}
@@ -860,7 +892,7 @@ RTR3DECL(int) RTFileSetTimes(RTFILE File, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC
extern int rtFileNativeSetAttributes(HANDLE FileHandle, ULONG FileAttributes);
-RTR3DECL(int) RTFileSetMode(RTFILE File, RTFMODE fMode)
+RTR3DECL(int) RTFileSetMode(RTFILE hFile, RTFMODE fMode)
{
/*
* Normalize the mode and call the API.
@@ -870,12 +902,12 @@ RTR3DECL(int) RTFileSetMode(RTFILE File, RTFMODE fMode)
return VERR_INVALID_PARAMETER;
ULONG FileAttributes = (fMode & RTFS_DOS_MASK) >> RTFS_DOS_SHIFT;
- int Err = rtFileNativeSetAttributes((HANDLE)File, FileAttributes);
+ int Err = rtFileNativeSetAttributes((HANDLE)hFile, FileAttributes);
if (Err != ERROR_SUCCESS)
{
int rc = RTErrConvertFromWin32(Err);
Log(("RTFileSetMode(%RTfile, %RTfmode): rtFileNativeSetAttributes (0x%08X) failed with err %d (%Rrc)\n",
- File, fMode, FileAttributes, Err, rc));
+ hFile, fMode, FileAttributes, Err, rc));
return rc;
}
return VINF_SUCCESS;
diff --git a/src/VBox/Runtime/r3/win/fs-win.cpp b/src/VBox/Runtime/r3/win/fs-win.cpp
index c0fa65c32..14e2fea69 100644
--- a/src/VBox/Runtime/r3/win/fs-win.cpp
+++ b/src/VBox/Runtime/r3/win/fs-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: fs-win.cpp $ */
+/* $Id: fs-win.cpp 32431 2010-09-11 18:02:17Z vboxsync $ */
/** @file
* IPRT - File System, Win32.
*/
diff --git a/src/VBox/Runtime/r3/win/ldrNative-win.cpp b/src/VBox/Runtime/r3/win/ldrNative-win.cpp
index 540169588..058bde3a4 100644
--- a/src/VBox/Runtime/r3/win/ldrNative-win.cpp
+++ b/src/VBox/Runtime/r3/win/ldrNative-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: ldrNative-win.cpp $ */
+/* $Id: ldrNative-win.cpp 35183 2010-12-16 13:59:44Z vboxsync $ */
/** @file
* IPRT - Binary Image Loader, Win32 native.
*/
diff --git a/src/VBox/Runtime/r3/win/localipc-win.cpp b/src/VBox/Runtime/r3/win/localipc-win.cpp
index 15ff6f8bb..13d17076c 100644
--- a/src/VBox/Runtime/r3/win/localipc-win.cpp
+++ b/src/VBox/Runtime/r3/win/localipc-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: localipc-win.cpp $ */
+/* $Id: localipc-win.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Local IPC, Windows Implementation Using Named Pipes.
*/
diff --git a/src/VBox/Runtime/r3/win/mp-win.cpp b/src/VBox/Runtime/r3/win/mp-win.cpp
index fed1152ba..970900de8 100644
--- a/src/VBox/Runtime/r3/win/mp-win.cpp
+++ b/src/VBox/Runtime/r3/win/mp-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: mp-win.cpp $ */
+/* $Id: mp-win.cpp 36262 2011-03-11 14:50:45Z vboxsync $ */
/** @file
* IPRT - Multiprocessor, Windows.
*/
diff --git a/src/VBox/Runtime/r3/win/ntdll-mini-implib.c b/src/VBox/Runtime/r3/win/ntdll-mini-implib.c
index 74094221d..b6c683932 100644
--- a/src/VBox/Runtime/r3/win/ntdll-mini-implib.c
+++ b/src/VBox/Runtime/r3/win/ntdll-mini-implib.c
@@ -1,4 +1,4 @@
-/* $Id: ntdll-mini-implib.c $ */
+/* $Id: ntdll-mini-implib.c 35018 2010-12-13 14:46:17Z vboxsync $ */
/** @file
* IPRT - Minimal NTDLL import library defintion file.
*/
diff --git a/src/VBox/Runtime/r3/win/ntdll-mini-implib.def b/src/VBox/Runtime/r3/win/ntdll-mini-implib.def
index a0d39ee48..8793f742f 100644
--- a/src/VBox/Runtime/r3/win/ntdll-mini-implib.def
+++ b/src/VBox/Runtime/r3/win/ntdll-mini-implib.def
@@ -1,4 +1,4 @@
-; $Id: ntdll-mini-implib.def $
+; $Id: ntdll-mini-implib.def 35020 2010-12-13 14:53:16Z vboxsync $
;; @file
; IPRT - Minimal NTDLL import library defintion file.
;
diff --git a/src/VBox/Runtime/r3/win/path-win.cpp b/src/VBox/Runtime/r3/win/path-win.cpp
index df85a2121..9f24ad5f4 100644
--- a/src/VBox/Runtime/r3/win/path-win.cpp
+++ b/src/VBox/Runtime/r3/win/path-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: path-win.cpp $ */
+/* $Id: path-win.cpp 36879 2011-04-29 09:15:52Z vboxsync $ */
/** @file
* IPRT - Path manipulation.
*/
@@ -30,11 +30,13 @@
*******************************************************************************/
#define LOG_GROUP RTLOGGROUP_PATH
#include <Windows.h>
+#include <Shlobj.h>
#include <iprt/path.h>
#include <iprt/assert.h>
#include <iprt/string.h>
#include <iprt/time.h>
+#include <iprt/ldr.h>
#include <iprt/mem.h>
#include <iprt/param.h>
#include <iprt/log.h>
@@ -42,6 +44,9 @@
#include "internal/path.h"
#include "internal/fs.h"
+/* Needed for lazy loading SHGetFolderPathW in RTPathUserDocuments(). */
+typedef HRESULT FNSHGETFOLDERPATHW(HWND, int, HANDLE, DWORD, LPWSTR);
+typedef FNSHGETFOLDERPATHW *PFNSHGETFOLDERPATHW;
/**
* Get the real (no symlinks, no . or .. components) path, must exist.
@@ -181,6 +186,40 @@ RTDECL(int) RTPathUserHome(char *pszPath, size_t cchPath)
}
+RTDECL(int) RTPathUserDocuments(char *pszPath, size_t cchPath)
+{
+ /*
+ * Validate input
+ */
+ AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
+ AssertReturn(cchPath, VERR_INVALID_PARAMETER);
+
+ RTLDRMOD hShell32;
+ int rc = RTLdrLoad("Shell32.dll", &hShell32);
+ if (RT_SUCCESS(rc))
+ {
+ PFNSHGETFOLDERPATHW pfnSHGetFolderPathW;
+ rc = RTLdrGetSymbol(hShell32, "SHGetFolderPathW", (void**)&pfnSHGetFolderPathW);
+ if (RT_SUCCESS(rc))
+ {
+ RTUTF16 wszPath[RTPATH_MAX];
+ HRESULT hrc = pfnSHGetFolderPathW(0, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, wszPath);
+ if ( hrc == S_OK /* Found */
+ || hrc == S_FALSE) /* Found, but doesn't exist */
+ {
+ /*
+ * Convert and return.
+ */
+ RTLdrClose(hShell32);
+ return RTUtf16ToUtf8Ex(&wszPath[0], RTSTR_MAX, &pszPath, cchPath, NULL);
+ }
+ }
+ RTLdrClose(hShell32);
+ }
+ return VERR_PATH_NOT_FOUND;
+}
+
+
RTR3DECL(int) RTPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
{
return RTPathQueryInfoEx(pszPath, pObjInfo, enmAdditionalAttribs, RTPATH_F_ON_LINK);
diff --git a/src/VBox/Runtime/r3/win/pipe-win.cpp b/src/VBox/Runtime/r3/win/pipe-win.cpp
index 6c12768e2..4e4193322 100644
--- a/src/VBox/Runtime/r3/win/pipe-win.cpp
+++ b/src/VBox/Runtime/r3/win/pipe-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: pipe-win.cpp $ */
+/* $Id: pipe-win.cpp 34119 2010-11-16 15:33:25Z vboxsync $ */
/** @file
* IPRT - Anonymous Pipes, Windows Implementation.
*/
diff --git a/src/VBox/Runtime/r3/win/poll-win.cpp b/src/VBox/Runtime/r3/win/poll-win.cpp
index 0f3b187ff..54641a99d 100644
--- a/src/VBox/Runtime/r3/win/poll-win.cpp
+++ b/src/VBox/Runtime/r3/win/poll-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: poll-win.cpp $ */
+/* $Id: poll-win.cpp 32431 2010-09-11 18:02:17Z vboxsync $ */
/** @file
* IPRT - Polling I/O Handles, Windows Implementation.
*
diff --git a/src/VBox/Runtime/r3/win/process-win.cpp b/src/VBox/Runtime/r3/win/process-win.cpp
index f616baf9f..567b3f196 100644
--- a/src/VBox/Runtime/r3/win/process-win.cpp
+++ b/src/VBox/Runtime/r3/win/process-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: process-win.cpp $ */
+/* $Id: process-win.cpp 37448 2011-06-14 16:06:06Z vboxsync $ */
/** @file
* IPRT - Process, Windows.
*/
@@ -29,6 +29,7 @@
* Header Files *
*******************************************************************************/
#define LOG_GROUP RTLOGGROUP_PROCESS
+#include <iprt/asm.h> /* hack */
#include <Userenv.h>
#include <Windows.h>
diff --git a/src/VBox/Runtime/r3/win/rtFileNativeSetAttributes-win.cpp b/src/VBox/Runtime/r3/win/rtFileNativeSetAttributes-win.cpp
index 5c8a1b71f..7965eb31f 100644
--- a/src/VBox/Runtime/r3/win/rtFileNativeSetAttributes-win.cpp
+++ b/src/VBox/Runtime/r3/win/rtFileNativeSetAttributes-win.cpp
@@ -1,10 +1,10 @@
-/* $Id: rtFileNativeSetAttributes-win.cpp $ */
+/* $Id: rtFileNativeSetAttributes-win.cpp 37600 2011-06-22 22:05:01Z vboxsync $ */
/** @file
* IPRT - NtSetInformationFile wrapper.
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-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;
diff --git a/src/VBox/Runtime/r3/win/rtProcInitExePath-win.cpp b/src/VBox/Runtime/r3/win/rtProcInitExePath-win.cpp
index 3b056cde1..d285a8052 100644
--- a/src/VBox/Runtime/r3/win/rtProcInitExePath-win.cpp
+++ b/src/VBox/Runtime/r3/win/rtProcInitExePath-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: rtProcInitExePath-win.cpp $ */
+/* $Id: rtProcInitExePath-win.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - rtProcInitName, Windows.
*/
diff --git a/src/VBox/Runtime/r3/win/sched-win.cpp b/src/VBox/Runtime/r3/win/sched-win.cpp
index 1f4a985c9..53dacd577 100644
--- a/src/VBox/Runtime/r3/win/sched-win.cpp
+++ b/src/VBox/Runtime/r3/win/sched-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: sched-win.cpp $ */
+/* $Id: sched-win.cpp 36555 2011-04-05 12:34:09Z vboxsync $ */
/** @file
* IPRT - Scheduling, Win32.
*/
@@ -256,7 +256,7 @@ static const PROCPRIORITY *g_pProcessPriority = &g_aDefaultPriority;
* @returns iprt status code.
* @param enmType The thread type to be assumed for the current thread.
*/
-int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
{
Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
return VINF_SUCCESS;
@@ -272,7 +272,7 @@ int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
* @param enmPriority The priority to validate and set.
* @remark Located in sched.
*/
-int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
+DECLHIDDEN(int) rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
{
Assert(enmPriority > RTPROCPRIORITY_INVALID && enmPriority < RTPROCPRIORITY_LAST);
return VINF_SUCCESS;
@@ -285,7 +285,7 @@ int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
* @returns Valid win32 handle for the specified thread.
* @param pThread The thread.
*/
-inline HANDLE rtThreadNativeGetHandle(PRTTHREADINT pThread)
+DECLINLINE(HANDLE) rtThreadNativeGetHandle(PRTTHREADINT pThread)
{
if ((uintptr_t)pThread->Core.Key == GetCurrentThreadId())
return GetCurrentThread();
@@ -305,7 +305,7 @@ inline HANDLE rtThreadNativeGetHandle(PRTTHREADINT pThread)
* @param enmType The thread type.
* @remark Located in sched.
*/
-int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
{
Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
AssertMsg(g_pProcessPriority && g_pProcessPriority->aTypes[enmType].enmType == enmType,
diff --git a/src/VBox/Runtime/r3/win/semevent-win.cpp b/src/VBox/Runtime/r3/win/semevent-win.cpp
index 13d715bfc..59558abfb 100644
--- a/src/VBox/Runtime/r3/win/semevent-win.cpp
+++ b/src/VBox/Runtime/r3/win/semevent-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: semevent-win.cpp $ */
+/* $Id: semevent-win.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Event Semaphore, Windows.
*/
diff --git a/src/VBox/Runtime/r3/win/semeventmulti-win.cpp b/src/VBox/Runtime/r3/win/semeventmulti-win.cpp
index b7f9febbe..5fa6d648c 100644
--- a/src/VBox/Runtime/r3/win/semeventmulti-win.cpp
+++ b/src/VBox/Runtime/r3/win/semeventmulti-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: semeventmulti-win.cpp $ */
+/* $Id: semeventmulti-win.cpp 32970 2010-10-07 10:08:00Z vboxsync $ */
/** @file
* IPRT - Multiple Release Event Semaphore, Windows.
*
diff --git a/src/VBox/Runtime/r3/win/semmutex-win.cpp b/src/VBox/Runtime/r3/win/semmutex-win.cpp
index 7cdab20b8..b86ec5fc5 100644
--- a/src/VBox/Runtime/r3/win/semmutex-win.cpp
+++ b/src/VBox/Runtime/r3/win/semmutex-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: semmutex-win.cpp $ */
+/* $Id: semmutex-win.cpp 30111 2010-06-09 12:14:59Z vboxsync $ */
/** @file
* IPRT - Mutex Semaphores, Windows.
*/
diff --git a/src/VBox/Runtime/r3/win/symlink-win.cpp b/src/VBox/Runtime/r3/win/symlink-win.cpp
index c30245e45..5a02d9ea3 100644
--- a/src/VBox/Runtime/r3/win/symlink-win.cpp
+++ b/src/VBox/Runtime/r3/win/symlink-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: symlink-win.cpp $ */
+/* $Id: symlink-win.cpp 33437 2010-10-25 16:28:14Z vboxsync $ */
/** @file
* IPRT - Symbolic Links, Windows.
*/
diff --git a/src/VBox/Runtime/r3/win/thread-win.cpp b/src/VBox/Runtime/r3/win/thread-win.cpp
index 1d9c00163..9280729b0 100644
--- a/src/VBox/Runtime/r3/win/thread-win.cpp
+++ b/src/VBox/Runtime/r3/win/thread-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: thread-win.cpp $ */
+/* $Id: thread-win.cpp 37733 2011-07-01 15:41:37Z vboxsync $ */
/** @file
* IPRT - Threads, Windows.
*/
@@ -35,11 +35,14 @@
#include <process.h>
#include <iprt/thread.h>
-#include <iprt/log.h>
-#include <iprt/assert.h>
-#include <iprt/alloc.h>
+#include "internal/iprt.h"
+
#include <iprt/asm-amd64-x86.h>
+#include <iprt/assert.h>
+#include <iprt/cpuset.h>
#include <iprt/err.h>
+#include <iprt/log.h>
+#include <iprt/mem.h>
#include "internal/thread.h"
@@ -56,7 +59,7 @@ static DWORD g_dwSelfTLS = TLS_OUT_OF_INDEXES;
static unsigned __stdcall rtThreadNativeMain(void *pvArgs);
-int rtThreadNativeInit(void)
+DECLHIDDEN(int) rtThreadNativeInit(void)
{
g_dwSelfTLS = TlsAlloc();
if (g_dwSelfTLS == TLS_OUT_OF_INDEXES)
@@ -65,7 +68,7 @@ int rtThreadNativeInit(void)
}
-void rtThreadNativeDetach(void)
+DECLHIDDEN(void) rtThreadNativeDetach(void)
{
/*
* Deal with alien threads.
@@ -80,7 +83,7 @@ void rtThreadNativeDetach(void)
}
-void rtThreadNativeDestroy(PRTTHREADINT pThread)
+DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread)
{
if (pThread == (PRTTHREADINT)TlsGetValue(g_dwSelfTLS))
TlsSetValue(g_dwSelfTLS, NULL);
@@ -93,7 +96,7 @@ void rtThreadNativeDestroy(PRTTHREADINT pThread)
}
-int rtThreadNativeAdopt(PRTTHREADINT pThread)
+DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread)
{
if (!TlsSetValue(g_dwSelfTLS, pThread))
return VERR_FAILED_TO_SET_SELF_TLS;
@@ -102,9 +105,9 @@ int rtThreadNativeAdopt(PRTTHREADINT pThread)
/**
- * Bitch about dangling COM and OLE references, dispose of them
- * afterwards so we don't end up deadlocked somewhere below
- * OLE32!DllMain.
+ * Bitch about dangling COM and OLE references, dispose of them
+ * afterwards so we don't end up deadlocked somewhere below
+ * OLE32!DllMain.
*/
static void rtThreadNativeUninitComAndOle(void)
{
@@ -142,14 +145,14 @@ static void rtThreadNativeUninitComAndOle(void)
cComInits = pOleTlsData->cComInits;
cOleInits = pOleTlsData->cOleInits;
}
- }
+ }
__except(EXCEPTION_EXECUTE_HANDLER)
{
AssertFailedReturnVoid();
}
-
+
/*
- * Assert sanity. If any of these breaks, the structure layout above is
+ * Assert sanity. If any of these breaks, the structure layout above is
* probably not correct any longer.
*/
AssertMsgReturnVoid(cComInits < 1000, ("%u (%#x)\n", cComInits, cComInits));
@@ -161,7 +164,7 @@ static void rtThreadNativeUninitComAndOle(void)
*/
if (cComInits)
{
- AssertMsgFailed(("cComInits=%u (%#x) cOleInits=%u (%#x) - dangling COM/OLE inits!\n",
+ AssertMsgFailed(("cComInits=%u (%#x) cOleInits=%u (%#x) - dangling COM/OLE inits!\n",
cComInits, cComInits, cOleInits, cOleInits));
HMODULE hOle32 = GetModuleHandle("OLE32");
@@ -208,7 +211,7 @@ static unsigned __stdcall rtThreadNativeMain(void *pvArgs)
}
-int rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
{
AssertReturn(pThread->cbStack < ~(unsigned)0, VERR_INVALID_PARAMETER);
@@ -236,32 +239,6 @@ RTDECL(RTTHREAD) RTThreadSelf(void)
}
-RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
-{
- return (RTNATIVETHREAD)GetCurrentThreadId();
-}
-
-
-RTR3DECL(int) RTThreadSleep(RTMSINTERVAL cMillies)
-{
- LogFlow(("RTThreadSleep: cMillies=%d\n", cMillies));
- Sleep(cMillies);
- LogFlow(("RTThreadSleep: returning %Rrc (cMillies=%d)\n", VINF_SUCCESS, cMillies));
- return VINF_SUCCESS;
-}
-
-
-RTR3DECL(bool) RTThreadYield(void)
-{
- uint64_t u64TS = ASMReadTSC();
- Sleep(0);
- u64TS = ASMReadTSC() - u64TS;
- bool fRc = u64TS > 1500;
- LogFlow(("RTThreadYield: returning %d (%llu ticks)\n", fRc, u64TS));
- return fRc;
-}
-
-
#if 0 /* noone is using this ... */
/**
* Returns the processor number the current thread was running on during this call
@@ -286,10 +263,10 @@ static int rtThreadGetCurrentProcessorNumber(void)
#endif
-RTR3DECL(int) RTThreadSetAffinity(uint64_t u64Mask)
+RTR3DECL(int) RTThreadSetAffinity(PCRTCPUSET pCpuSet)
{
- Assert((DWORD_PTR)u64Mask == u64Mask || u64Mask == ~(uint64_t)0);
- DWORD_PTR dwRet = SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR)u64Mask);
+ DWORD_PTR fNewMask = pCpuSet ? RTCpuSetToU64(pCpuSet) : ~(DWORD_PTR)0;
+ DWORD_PTR dwRet = SetThreadAffinityMask(GetCurrentThread(), fNewMask);
if (dwRet)
return VINF_SUCCESS;
@@ -299,7 +276,7 @@ RTR3DECL(int) RTThreadSetAffinity(uint64_t u64Mask)
}
-RTR3DECL(uint64_t) RTThreadGetAffinity(void)
+RTR3DECL(int) RTThreadGetAffinity(PRTCPUSET pCpuSet)
{
/*
* Haven't found no query api, but the set api returns the old mask, so let's use that.
@@ -314,7 +291,9 @@ RTR3DECL(uint64_t) RTThreadGetAffinity(void)
{
DWORD_PTR dwSet = SetThreadAffinityMask(hThread, dwRet);
Assert(dwSet == dwProcAff); NOREF(dwRet);
- return dwRet;
+
+ RTCpuSetFromU64(pCpuSet, (uint64_t)dwSet);
+ return VINF_SUCCESS;
}
}
diff --git a/src/VBox/Runtime/r0drv/solaris/mpnotification-r0drv-solaris.c b/src/VBox/Runtime/r3/win/thread2-win.cpp
index 1b5c736cf..3970c0b4d 100644
--- a/src/VBox/Runtime/r0drv/solaris/mpnotification-r0drv-solaris.c
+++ b/src/VBox/Runtime/r3/win/thread2-win.cpp
@@ -1,10 +1,10 @@
-/* $Id: mpnotification-r0drv-solaris.c $ */
+/* $Id: thread2-win.cpp 37733 2011-07-01 15:41:37Z vboxsync $ */
/** @file
- * IPRT - Multiprocessor Event Notifications, Ring-0 Driver, Solaris.
+ * IPRT - Threads part 2, Windows.
*/
/*
- * Copyright (C) 2008 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;
@@ -28,56 +28,41 @@
/*******************************************************************************
* Header Files *
*******************************************************************************/
-#include "the-solaris-kernel.h"
+#define LOG_GROUP RTLOGGROUP_THREAD
+#include <Windows.h>
+
+#include <iprt/thread.h>
#include "internal/iprt.h"
-#include <iprt/mp.h>
+#include <iprt/asm-amd64-x86.h>
#include <iprt/err.h>
-#include "r0drv/mp-r0drv.h"
+#include <iprt/log.h>
+#include "internal/thread.h"
-static int rtMpNotificationSolarisCallback(cpu_setup_t enmSolarisEvent, int iCpu, void *pvUser)
+RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
{
- NOREF(pvUser);
-
- /* ASSUMES iCpu == RTCPUID */
- switch (enmSolarisEvent)
- {
- case CPU_INIT:
- case CPU_CONFIG:
- case CPU_UNCONFIG:
- break;
-
- case CPU_ON:
- rtMpNotificationDoCallbacks(RTMPEVENT_ONLINE, iCpu);
- break;
-
- case CPU_OFF:
- rtMpNotificationDoCallbacks(RTMPEVENT_OFFLINE, iCpu);
- break;
-
- case CPU_CPUPART_IN:
- case CPU_CPUPART_OUT:
- /** @todo are these relevant? */
- break;
- }
- return 0;
+ return (RTNATIVETHREAD)GetCurrentThreadId();
}
-int rtR0MpNotificationNativeInit(void)
+RTR3DECL(int) RTThreadSleep(RTMSINTERVAL cMillies)
{
- mutex_enter(&cpu_lock);
- register_cpu_setup_func(rtMpNotificationSolarisCallback, NULL);
- mutex_exit(&cpu_lock);
+ LogFlow(("RTThreadSleep: cMillies=%d\n", cMillies));
+ Sleep(cMillies);
+ LogFlow(("RTThreadSleep: returning %Rrc (cMillies=%d)\n", VINF_SUCCESS, cMillies));
return VINF_SUCCESS;
}
-void rtR0MpNotificationNativeTerm(void)
+RTR3DECL(bool) RTThreadYield(void)
{
- mutex_enter(&cpu_lock);
- unregister_cpu_setup_func(rtMpNotificationSolarisCallback, NULL);
- mutex_exit(&cpu_lock);
+ uint64_t u64TS = ASMReadTSC();
+ Sleep(0);
+ u64TS = ASMReadTSC() - u64TS;
+ bool fRc = u64TS > 1500;
+ LogFlow(("RTThreadYield: returning %d (%llu ticks)\n", fRc, u64TS));
+ return fRc;
}
+
diff --git a/src/VBox/Runtime/r3/win/time-win.cpp b/src/VBox/Runtime/r3/win/time-win.cpp
index bd4e768a7..517589c09 100644
--- a/src/VBox/Runtime/r3/win/time-win.cpp
+++ b/src/VBox/Runtime/r3/win/time-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: time-win.cpp $ */
+/* $Id: time-win.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Time, Windows.
*/
diff --git a/src/VBox/Runtime/r3/win/timer-win.cpp b/src/VBox/Runtime/r3/win/timer-win.cpp
index 08ed4ec1f..868d1d371 100644
--- a/src/VBox/Runtime/r3/win/timer-win.cpp
+++ b/src/VBox/Runtime/r3/win/timer-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: timer-win.cpp $ */
+/* $Id: timer-win.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Timer.
*/
diff --git a/src/VBox/Runtime/r3/win/tls-win.cpp b/src/VBox/Runtime/r3/win/tls-win.cpp
index 2bc332b76..01a5e581f 100644
--- a/src/VBox/Runtime/r3/win/tls-win.cpp
+++ b/src/VBox/Runtime/r3/win/tls-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: tls-win.cpp $ */
+/* $Id: tls-win.cpp 34507 2010-11-30 13:14:14Z vboxsync $ */
/** @file
* IPRT - Thread Local Storage (TLS), Win32.
*/
diff --git a/src/VBox/Runtime/r3/win/utf16locale-win.cpp b/src/VBox/Runtime/r3/win/utf16locale-win.cpp
index 40d99bb2b..1831a5088 100644
--- a/src/VBox/Runtime/r3/win/utf16locale-win.cpp
+++ b/src/VBox/Runtime/r3/win/utf16locale-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: utf16locale-win.cpp $ */
+/* $Id: utf16locale-win.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - UTF-16 Locale Specific Manipulation, Win32.
*/
diff --git a/src/VBox/Runtime/r3/win/utf8-win.cpp b/src/VBox/Runtime/r3/win/utf8-win.cpp
index 58a6e3957..bef381b85 100644
--- a/src/VBox/Runtime/r3/win/utf8-win.cpp
+++ b/src/VBox/Runtime/r3/win/utf8-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: utf8-win.cpp $ */
+/* $Id: utf8-win.cpp 31157 2010-07-28 03:15:35Z vboxsync $ */
/** @file
* IPRT - UTF8 helpers.
*/
diff --git a/src/VBox/Runtime/r3/win/uuid-win.cpp b/src/VBox/Runtime/r3/win/uuid-win.cpp
index 0d91df790..203b81594 100644
--- a/src/VBox/Runtime/r3/win/uuid-win.cpp
+++ b/src/VBox/Runtime/r3/win/uuid-win.cpp
@@ -1,4 +1,4 @@
-/* $Id: uuid-win.cpp $ */
+/* $Id: uuid-win.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - UUID, Windows implementation.
*/
diff --git a/src/VBox/Runtime/r3/xml.cpp b/src/VBox/Runtime/r3/xml.cpp
index c1007a4da..ecf63bc70 100644
--- a/src/VBox/Runtime/r3/xml.cpp
+++ b/src/VBox/Runtime/r3/xml.cpp
@@ -1,4 +1,4 @@
-/* $Id: xml.cpp $ */
+/* $Id: xml.cpp 37493 2011-06-16 13:18:11Z vboxsync $ */
/** @file
* IPRT - XML Manipulation API.
*/
@@ -90,7 +90,7 @@ public:
/** Used to provide some thread safety missing in libxml2 (see e.g.
* XmlTreeBackend::read()) */
- RTLockMtx lock;
+ RTCLockMtx lock;
}
sxml; /* XXX naming this xml will break with gcc-3.3 */
}
@@ -108,7 +108,7 @@ namespace xml
////////////////////////////////////////////////////////////////////////////////
LogicError::LogicError(RT_SRC_POS_DECL)
- : Error(NULL)
+ : RTCError(NULL)
{
char *msg = NULL;
RTStrAPrintf(&msg, "In '%s', '%s' at #%d",
@@ -174,7 +174,7 @@ struct File::Data
: handle(NIL_RTFILE), opened(false)
{ }
- iprt::MiniString strFileName;
+ RTCString strFileName;
RTFILE handle;
bool opened : 1;
bool flushOnClose : 1;
@@ -386,7 +386,7 @@ int MemoryBuf::read (char *aBuf, int aLen)
struct GlobalLock::Data
{
PFNEXTERNALENTITYLOADER pOldLoader;
- RTLock lock;
+ RTCLock lock;
Data()
: pOldLoader(NULL),
@@ -824,7 +824,7 @@ bool ElementNode::getAttributeValue(const char *pcszMatch, const char *&ppcsz) c
* @param str out: attribute value; overwritten only if attribute was found
* @return TRUE if attribute was found and str was thus updated.
*/
-bool ElementNode::getAttributeValue(const char *pcszMatch, iprt::MiniString &str) const
+bool ElementNode::getAttributeValue(const char *pcszMatch, RTCString &str) const
{
const Node* pAttr;
if ((pAttr = findAttribute(pcszMatch)))
@@ -843,7 +843,7 @@ bool ElementNode::getAttributeValue(const char *pcszMatch, iprt::MiniString &str
* @param str
* @return
*/
-bool ElementNode::getAttributeValuePath(const char *pcszMatch, iprt::MiniString &str) const
+bool ElementNode::getAttributeValuePath(const char *pcszMatch, RTCString &str) const
{
if (getAttributeValue(pcszMatch, str))
{
@@ -1077,9 +1077,9 @@ AttributeNode* ElementNode::setAttribute(const char *pcszName, const char *pcszV
* @param strValue
* @return
*/
-AttributeNode* ElementNode::setAttributePath(const char *pcszName, const iprt::MiniString &strValue)
+AttributeNode* ElementNode::setAttributePath(const char *pcszName, const RTCString &strValue)
{
- iprt::MiniString strTemp(strValue);
+ RTCString strTemp(strValue);
strTemp.findReplace('\\', '/');
return setAttribute(pcszName, strTemp.c_str());
}
@@ -1333,6 +1333,11 @@ struct Document::Data
delete pRootElement;
pRootElement = NULL;
}
+ if (pComment)
+ {
+ delete pComment;
+ pComment = NULL;
+ }
}
void copyFrom(const Document::Data *p)
@@ -1481,7 +1486,7 @@ XmlMemParser::~XmlMemParser()
* @param doc out: document to be reset and filled with data according to file contents.
*/
void XmlMemParser::read(const void* pvBuf, size_t cbSize,
- const iprt::MiniString &strFilename,
+ const RTCString &strFilename,
Document &doc)
{
GlobalLock lock;
@@ -1539,7 +1544,7 @@ void XmlMemWriter::write(const Document &doc, void **ppvBuf, size_t *pcbSize)
struct XmlFileParser::Data
{
- iprt::MiniString strXmlFilename;
+ RTCString strXmlFilename;
Data()
{
@@ -1565,14 +1570,14 @@ XmlFileParser::~XmlFileParser()
struct IOContext
{
File file;
- iprt::MiniString error;
+ RTCString error;
IOContext(const char *pcszFilename, File::Mode mode, bool fFlush = false)
: file(mode, pcszFilename, fFlush)
{
}
- void setError(const iprt::Error &x)
+ void setError(const RTCError &x)
{
error = x.what();
}
@@ -1608,7 +1613,7 @@ struct WriteContext : IOContext
* @param strFilename in: name fo file to parse.
* @param doc out: document to be reset and filled with data according to file contents.
*/
-void XmlFileParser::read(const iprt::MiniString &strFilename,
+void XmlFileParser::read(const RTCString &strFilename,
Document &doc)
{
GlobalLock lock;
@@ -1644,7 +1649,7 @@ int XmlFileParser::ReadCallback(void *aCtxt, char *aBuf, int aLen)
return pContext->file.read(aBuf, aLen);
}
catch (const xml::EIPRTFailure &err) { pContext->setError(err); }
- catch (const iprt::Error &err) { pContext->setError(err); }
+ catch (const RTCError &err) { pContext->setError(err); }
catch (const std::exception &err) { pContext->setError(err); }
catch (...) { pContext->setError(xml::LogicError(RT_SRC_POS)); }
@@ -1769,7 +1774,7 @@ int XmlFileWriter::WriteCallback(void *aCtxt, const char *aBuf, int aLen)
return pContext->file.write(aBuf, aLen);
}
catch (const xml::EIPRTFailure &err) { pContext->setError(err); }
- catch (const iprt::Error &err) { pContext->setError(err); }
+ catch (const RTCError &err) { pContext->setError(err); }
catch (const std::exception &err) { pContext->setError(err); }
catch (...) { pContext->setError(xml::LogicError(RT_SRC_POS)); }
diff --git a/src/VBox/Runtime/testcase/Makefile.kmk b/src/VBox/Runtime/testcase/Makefile.kmk
index 1aabc736f..7b48c2f70 100644
--- a/src/VBox/Runtime/testcase/Makefile.kmk
+++ b/src/VBox/Runtime/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37720 2011-06-30 20:27:48Z vboxsync $
## @file
# Sub-Makefile for the IPRT testcases.
#
@@ -54,6 +54,7 @@ PROGRAMS += \
tstDir \
tstDir-2 \
tstDir-3 \
+ tstRTDvm \
tstEnv \
tstErrUnique \
tstFile \
@@ -67,6 +68,7 @@ PROGRAMS += \
tstRTHeapOffset \
tstRTHeapSimple \
tstRTInlineAsm \
+ tstIprtList \
tstIprtMiniString \
tstLdr \
tstLdrLoad \
@@ -106,6 +108,7 @@ PROGRAMS += \
tstRTSystemQueryOsInfo \
tstRTTcp-1 \
tstRTTemp \
+ tstRTDirCreateUniqueNumbered \
tstTermCallbacks \
tstThread-1 \
tstRTThreadPoke \
@@ -120,7 +123,8 @@ PROGRAMS += \
tstUtf8 \
tstRTUuid \
tstRTCircBuf \
- tstRTManifest
+ tstRTManifest \
+ tstVector
PROGRAMS.win += \
tstRTProcWait \
@@ -211,6 +215,8 @@ tstDir-2_SOURCES = tstDir-2.cpp
tstDir-3_SOURCES = tstDir-3.cpp
+tstRTDvm_SOURCES = tstRTDvm.cpp
+
tstEnv_SOURCES = tstEnv.cpp
# Note: tstErrUnique.cpp depends on a header generated by the makefile above us.
@@ -261,6 +267,9 @@ tstRTInlineAsmPIC3_SOURCES = tstRTInlineAsm.cpp
tstRTInlineAsmPIC3_CXXFLAGS = -fPIC -fomit-frame-pointer -O3
tstRTInlineAsmPIC3_DEFS = PIC
+tstIprtList_TEMPLATE = VBOXR3TSTEXE
+tstIprtList_SOURCES = tstIprtList.cpp
+
tstIprtMiniString_TEMPLATE = VBOXR3TSTEXE
tstIprtMiniString_SOURCES = tstIprtMiniString.cpp
@@ -459,6 +468,9 @@ tstRTTcp-1_SOURCES = tstRTTcp-1.cpp
tstRTTemp_TEMPLATE = VBOXR3TSTEXE
tstRTTemp_SOURCES = tstRTTemp.cpp
+tstRTDirCreateUniqueNumbered_TEMPLATE = VBOXR3TSTEXE
+tstRTDirCreateUniqueNumbered_SOURCES = tstRTDirCreateUniqueNumbered.cpp
+
tstTermCallbacks_SOURCES = tstTermCallbacks.cpp
tstThread-1_SOURCES = tstThread-1.cpp
@@ -501,6 +513,9 @@ tstRTManifest_SOURCES = tstRTManifest.cpp
tstRTCoreDump_TEMPLACE = VBOXR3TSTEXE
tstRTCoreDump_SOURCES = tstRTCoreDump.cpp
+tstVector_TEMPLATE = VBOXR3TSTEXE
+tstVector_SOURCES = tstVector.cpp
+
#
# Ring-0 testcases.
diff --git a/src/VBox/Runtime/testcase/ioctl.h b/src/VBox/Runtime/testcase/ioctl.h
index f9a5273ec..57732e44b 100644
--- a/src/VBox/Runtime/testcase/ioctl.h
+++ b/src/VBox/Runtime/testcase/ioctl.h
@@ -1,4 +1,4 @@
-/* $Id: ioctl.h $ */
+/* $Id: ioctl.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox L4/OSS audio - header for Linux IoCtls.
*/
diff --git a/src/VBox/Runtime/testcase/ntGetTimerResolution.cpp b/src/VBox/Runtime/testcase/ntGetTimerResolution.cpp
index 7e12327c6..c25551be1 100644
--- a/src/VBox/Runtime/testcase/ntGetTimerResolution.cpp
+++ b/src/VBox/Runtime/testcase/ntGetTimerResolution.cpp
@@ -1,4 +1,4 @@
-/* $Id: ntGetTimerResolution.cpp $ */
+/* $Id: ntGetTimerResolution.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Win32 (NT) testcase for getting the timer resolution.
*/
diff --git a/src/VBox/Runtime/testcase/tstDir-2.cpp b/src/VBox/Runtime/testcase/tstDir-2.cpp
index 27c4edc5e..39e8e76b2 100644
--- a/src/VBox/Runtime/testcase/tstDir-2.cpp
+++ b/src/VBox/Runtime/testcase/tstDir-2.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstDir-2.cpp $ */
+/* $Id: tstDir-2.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Directory listing & filtering .
*/
diff --git a/src/VBox/Runtime/testcase/tstDir-3.cpp b/src/VBox/Runtime/testcase/tstDir-3.cpp
index 9f3623833..c9b6cf167 100644
--- a/src/VBox/Runtime/testcase/tstDir-3.cpp
+++ b/src/VBox/Runtime/testcase/tstDir-3.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstDir-3.cpp $ */
+/* $Id: tstDir-3.cpp 33464 2010-10-26 12:27:50Z vboxsync $ */
/** @file
* IPRT Testcase - Directory listing & filtering (no parameters needed).
*/
diff --git a/src/VBox/Runtime/testcase/tstDir.cpp b/src/VBox/Runtime/testcase/tstDir.cpp
index 154231068..225258add 100644
--- a/src/VBox/Runtime/testcase/tstDir.cpp
+++ b/src/VBox/Runtime/testcase/tstDir.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstDir.cpp $ */
+/* $Id: tstDir.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Directory listing.
*/
diff --git a/src/VBox/Runtime/testcase/tstEnv.cpp b/src/VBox/Runtime/testcase/tstEnv.cpp
index b21bdc77f..3fe9e37de 100644
--- a/src/VBox/Runtime/testcase/tstEnv.cpp
+++ b/src/VBox/Runtime/testcase/tstEnv.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstEnv.cpp $ */
+/* $Id: tstEnv.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Environment.
*/
diff --git a/src/VBox/Runtime/testcase/tstErrUnique.cpp b/src/VBox/Runtime/testcase/tstErrUnique.cpp
index 41386e6f2..d3f802482 100644
--- a/src/VBox/Runtime/testcase/tstErrUnique.cpp
+++ b/src/VBox/Runtime/testcase/tstErrUnique.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstErrUnique.cpp $ */
+/* $Id: tstErrUnique.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Error Messages.
*/
diff --git a/src/VBox/Runtime/testcase/tstFile.cpp b/src/VBox/Runtime/testcase/tstFile.cpp
index 8da4c1693..1a38ddec6 100644
--- a/src/VBox/Runtime/testcase/tstFile.cpp
+++ b/src/VBox/Runtime/testcase/tstFile.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstFile.cpp $ */
+/* $Id: tstFile.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - File I/O.
*/
diff --git a/src/VBox/Runtime/testcase/tstFileAppendWin-1.cpp b/src/VBox/Runtime/testcase/tstFileAppendWin-1.cpp
index 7ffd7fe1a..6714aec30 100644
--- a/src/VBox/Runtime/testcase/tstFileAppendWin-1.cpp
+++ b/src/VBox/Runtime/testcase/tstFileAppendWin-1.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstFileAppendWin-1.cpp $ */
+/* $Id: tstFileAppendWin-1.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Exploration of File Appending on Windows.
*/
diff --git a/src/VBox/Runtime/testcase/tstFileLock.cpp b/src/VBox/Runtime/testcase/tstFileLock.cpp
index 950ce1268..6b577fc8d 100644
--- a/src/VBox/Runtime/testcase/tstFileLock.cpp
+++ b/src/VBox/Runtime/testcase/tstFileLock.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstFileLock.cpp $ */
+/* $Id: tstFileLock.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - File Locks.
*/
diff --git a/src/VBox/Runtime/testcase/tstFork.cpp b/src/VBox/Runtime/testcase/tstFork.cpp
index 8d511f7c2..7cc4d63c1 100644
--- a/src/VBox/Runtime/testcase/tstFork.cpp
+++ b/src/VBox/Runtime/testcase/tstFork.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstFork.cpp $ */
+/* $Id: tstFork.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT Testcase - fork() issues.
*/
diff --git a/src/VBox/Runtime/testcase/tstHandleTable.cpp b/src/VBox/Runtime/testcase/tstHandleTable.cpp
index 6dfec0828..b5791f7ba 100644
--- a/src/VBox/Runtime/testcase/tstHandleTable.cpp
+++ b/src/VBox/Runtime/testcase/tstHandleTable.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstHandleTable.cpp $ */
+/* $Id: tstHandleTable.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Handle Tables.
*/
diff --git a/src/VBox/Runtime/testcase/tstIoCtl.cpp b/src/VBox/Runtime/testcase/tstIoCtl.cpp
index 31e901ef8..0f592b90b 100644
--- a/src/VBox/Runtime/testcase/tstIoCtl.cpp
+++ b/src/VBox/Runtime/testcase/tstIoCtl.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstIoCtl.cpp $ */
+/* $Id: tstIoCtl.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - file IoCtl.
*/
diff --git a/src/VBox/Runtime/testcase/tstIprtList.cpp b/src/VBox/Runtime/testcase/tstIprtList.cpp
new file mode 100644
index 000000000..31acd089e
--- /dev/null
+++ b/src/VBox/Runtime/testcase/tstIprtList.cpp
@@ -0,0 +1,612 @@
+/* $Id: tstIprtList.cpp 37861 2011-07-11 10:03:22Z vboxsync $ */
+/** @file
+ * IPRT Testcase - RTCList/RTCMTList.
+ */
+
+/*
+ * 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.
+ *
+ * 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/cpp/mtlist.h>
+
+#include <iprt/cpp/ministring.h>
+#include <iprt/test.h>
+#include <iprt/rand.h>
+#include <iprt/thread.h>
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/** Used for the string test. */
+static const char *g_apszTestStrings[] =
+{
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
+ "Vestibulum non turpis vel metus pellentesque tincidunt at id massa.",
+ "Cras quis erat sed nulla ullamcorper molestie.",
+ "Mauris ac elit turpis, id pulvinar diam.",
+ "Nulla quis dolor dolor, in ultrices diam.",
+ "Vivamus ac quam non ipsum vehicula tempor ac ac arcu.",
+ "Aenean posuere lacus blandit erat semper eu iaculis ante eleifend.",
+ "Donec quis quam a lacus interdum sollicitudin quis eu est.",
+ "Morbi sed nisi a arcu commodo convallis.",
+ "Aenean molestie condimentum velit, non mattis magna ultricies quis.",
+ "Nulla id velit at mauris gravida mattis.",
+ "Phasellus viverra velit eu urna semper in porta arcu sollicitudin.",
+ "Pellentesque consequat turpis et tortor hendrerit id tempor ipsum lacinia.",
+ "Cras iaculis nulla quis risus pulvinar eget tempor lectus placerat.",
+ "Nullam in nulla sed sapien euismod euismod.",
+ "Morbi in tortor at magna sagittis fermentum ut eu nunc.",
+ "Nulla vitae ante sit amet dui molestie sagittis lacinia quis tellus.",
+ "Proin iaculis lorem ultricies metus bibendum tincidunt.",
+ "Sed gravida purus id risus sollicitudin ac porta orci vestibulum.",
+ "Duis quis purus non ligula consectetur cursus eu interdum erat.",
+ "Nullam non nunc in elit volutpat tempor in nec metus.",
+ "Aliquam id purus eget enim luctus molestie.",
+ "Sed id elit nec elit luctus scelerisque.",
+ "Suspendisse viverra leo non ligula congue ac luctus nisl vulputate.",
+ "Nulla dignissim lobortis nunc, eu tempus ipsum luctus sed.",
+ "Integer vel lacus lacus, quis condimentum felis.",
+ "Nulla ut lacus ac lacus gravida ultrices id sed ipsum.",
+ "Etiam non purus ut augue fermentum consequat.",
+ "Nam sit amet eros quis nibh blandit lacinia non posuere lectus.",
+ "Sed sit amet ipsum et dolor sagittis facilisis.",
+ "Ut congue nisi lacus, vel ultrices est.",
+ "Donec vel erat ut justo hendrerit sodales eu eget libero.",
+ "Integer a ipsum ac nunc eleifend congue convallis a urna.",
+ "Sed vel eros eu lectus imperdiet vehicula.",
+ "Vivamus eget turpis sed erat dapibus varius eget eu nulla.",
+ "Nam id nulla non elit eleifend commodo sed ac est.",
+ "Integer pulvinar dolor sodales velit pulvinar et facilisis eros scelerisque.",
+ "Ut mattis arcu ut libero imperdiet in rhoncus augue sodales.",
+ "Ut luctus turpis ligula, id dapibus felis.",
+ "Nullam sit amet sapien eget tellus hendrerit vestibulum eget in odio.",
+ "Phasellus non orci vitae mi placerat semper.",
+ "Quisque pharetra aliquet velit, quis tempor magna porttitor nec.",
+ "Praesent porta neque felis, vehicula facilisis odio.",
+ "Maecenas ultricies ipsum eu velit laoreet faucibus.",
+ "Mauris et nunc leo, et euismod quam.",
+ "Phasellus a felis et justo fringilla lacinia.",
+ "Vestibulum eget augue ante, ac viverra neque.",
+ "Mauris pellentesque ligula quis metus elementum venenatis.",
+ "Curabitur eu neque tellus, non porta sapien.",
+ "Ut mattis metus id enim aliquam laoreet et sed tortor.",
+ "Aenean quis nulla vitae nulla auctor lobortis a egestas turpis.",
+ "Praesent vitae ante a urna porta placerat non nec eros.",
+ "Donec quis neque eros, placerat adipiscing turpis.",
+ "Cras sit amet sapien risus, quis euismod arcu.",
+ "Integer volutpat massa eros, ac gravida mi.",
+ "Nunc vitae nunc sagittis diam vulputate suscipit.",
+ "Suspendisse quis mauris bibendum mauris aliquet pulvinar.",
+ "Donec volutpat vestibulum ligula, eget interdum tortor malesuada sit amet.",
+ "Mauris hendrerit dui non nibh varius sit amet fringilla orci pretium.",
+ "Phasellus a quam tellus, auctor lacinia sapien.",
+ "Sed dapibus leo vitae neque faucibus id porttitor sapien ultricies.",
+ "Maecenas euismod elit nec tortor sagittis pretium.",
+ "Ut tincidunt risus at erat fermentum sit amet molestie ante lacinia.",
+ "Nulla non leo nec lacus sollicitudin lobortis a a nisl.",
+ "Nunc vulputate erat vel libero elementum a interdum turpis malesuada.",
+ "Morbi id libero turpis, a lobortis dolor.",
+ "Donec vehicula imperdiet lorem, non pretium nulla tempus ut.",
+ "Morbi lacinia massa id nunc tempus in blandit risus blandit.",
+ "Sed feugiat orci id ipsum suscipit quis fringilla enim rutrum.",
+ "Mauris suscipit lobortis urna, vel dictum justo iaculis ac.",
+ "In rhoncus lectus tristique nunc blandit gravida placerat turpis rutrum.",
+ "Aliquam pellentesque ornare justo, sed hendrerit metus mattis a.",
+ "Nam aliquet lorem congue nisl blandit posuere.",
+ "Sed lobortis interdum ipsum, ac cursus erat lacinia in.",
+ "Maecenas vel tortor vel lorem facilisis interdum.",
+ "Aenean porttitor massa enim, eget dignissim est.",
+ "Nullam id libero lacus, mattis feugiat risus.",
+ "Fusce et dolor at eros ornare auctor malesuada vel ipsum.",
+ "Donec at massa sit amet lorem pellentesque interdum at ac lacus.",
+ "Praesent suscipit velit at justo suscipit eu vestibulum ligula interdum.",
+ "Aenean id justo nulla, vitae vulputate diam.",
+ "Fusce pellentesque leo quis orci pulvinar at pellentesque tellus dictum.",
+ "Ut facilisis purus at enim varius vulputate.",
+ "Donec malesuada bibendum sapien, sed pretium nisi cursus quis.",
+ "Mauris porttitor diam ut sapien pretium egestas.",
+ "Vestibulum ut justo eu libero semper convallis vitae et velit.",
+ "Quisque eleifend dapibus ligula, eu tincidunt massa rutrum at.",
+ "Sed euismod diam eget enim suscipit dictum.",
+ "Mauris fermentum orci eu nunc venenatis in sollicitudin tellus vestibulum.",
+ "Vivamus faucibus consequat turpis, lobortis vehicula lectus gravida eget.",
+ "Curabitur eu erat eu mi interdum scelerisque.",
+ "Morbi consequat molestie nulla, imperdiet elementum augue sagittis vel.",
+ "Sed ullamcorper velit suscipit arcu egestas quis commodo est hendrerit.",
+ "Proin vitae velit ut enim sollicitudin ultrices.",
+ "Curabitur posuere euismod lacus, sed volutpat erat adipiscing sit amet.",
+ "Cras sit amet sem lorem, in cursus augue.",
+ "Sed fermentum ultricies orci, quis hendrerit risus imperdiet et.",
+ "Proin nec arcu interdum ipsum molestie vestibulum.",
+ "Nulla quis quam non sem pretium scelerisque et eu velit.",
+ "Donec eu tellus nisl, ac vehicula tortor."
+};
+
+
+/**
+ * Does a list test.
+ *
+ * @param T1 The list type.
+ * @param T2 The input type
+ * @param pcszDesc The test description.
+ * @param paTestData Pointer to the array with the test input data.
+ * @param cTestItems The size of the input data.
+ */
+template<template <class, typename> class L, typename T1, typename T2, typename T3>
+static void test1(const char *pcszDesc, T3 paTestData[], size_t cTestItems)
+{
+ RTTestISubF("%s with size of %u (items=%u)", pcszDesc, sizeof(T1), cTestItems);
+
+ /*
+ * Construction
+ */
+
+ /* Create a test list */
+ L<T1, T2> testList;
+
+ const size_t defCap = L<T1, T2>::DefaultCapacity;
+ RTTESTI_CHECK(testList.isEmpty());
+ RTTESTI_CHECK(testList.size() == 0);
+ RTTESTI_CHECK(testList.capacity() == defCap);
+
+ /*
+ * Adding
+ */
+
+ /* Add the second half of the test data */
+ size_t cAdded = 1;
+
+ /* Start adding the second half of our test list */
+ for (size_t i = cTestItems / 2; i < cTestItems; ++i, ++cAdded)
+ {
+ testList.append(paTestData[i]);
+ RTTESTI_CHECK_RETV(testList.size() == cAdded);
+ RTTESTI_CHECK(testList.at(0) == paTestData[cTestItems / 2]);
+ RTTESTI_CHECK(testList[0] == paTestData[cTestItems / 2]);
+ RTTESTI_CHECK(testList.first() == paTestData[cTestItems / 2]);
+ RTTESTI_CHECK(testList.at(cAdded - 1) == paTestData[i]);
+ RTTESTI_CHECK(testList[cAdded - 1] == paTestData[i]);
+ RTTESTI_CHECK(testList.last() == paTestData[i]);
+ }
+
+ /* Check that all is correctly appended. */
+ RTTESTI_CHECK_RETV(testList.size() == cTestItems / 2);
+ RTTESTI_CHECK_RETV(testList.isEmpty() == false);
+ for (size_t i = 0; i < testList.size(); ++i)
+ RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);
+
+ /* Start prepending the first half of our test list. Iterate reverse to get
+ * the correct sorting back. */
+ for (size_t i = cTestItems / 2; i > 0; --i, ++cAdded)
+ {
+ testList.prepend(paTestData[i - 1]);
+ RTTESTI_CHECK_RETV(testList.size() == cAdded);
+ RTTESTI_CHECK(testList.at(0) == paTestData[i - 1]);
+ RTTESTI_CHECK(testList[0] == paTestData[i - 1]);
+ RTTESTI_CHECK(testList.first() == paTestData[i - 1]);
+ RTTESTI_CHECK(testList.at(cAdded - 1) == paTestData[cTestItems - 1]);
+ RTTESTI_CHECK(testList[cAdded - 1] == paTestData[cTestItems - 1]);
+ RTTESTI_CHECK(testList.last() == paTestData[cTestItems - 1]);
+ }
+
+ /* Check that all is correctly prepended. */
+ RTTESTI_CHECK_RETV(testList.size() == cTestItems);
+ RTTESTI_CHECK_RETV(testList.isEmpty() == false);
+ for (size_t i = 0; i < testList.size(); ++i)
+ RTTESTI_CHECK(testList.at(i) == paTestData[i]);
+
+ /*
+ * Contains
+ */
+ L<T1, T2> testList2;
+
+ /* Check full list. */
+ RTTESTI_CHECK( testList.contains(paTestData[0]));
+ RTTESTI_CHECK( testList.contains(paTestData[cTestItems / 2]));
+ RTTESTI_CHECK( testList.contains(paTestData[cTestItems - 1]));
+ RTTESTI_CHECK(!testList.contains(T1()));
+ /* Check empty list. */
+ RTTESTI_CHECK(!testList2.contains(paTestData[0]));
+ RTTESTI_CHECK(!testList2.contains(paTestData[cTestItems / 2]));
+ RTTESTI_CHECK(!testList2.contains(paTestData[cTestItems - 1]));
+ RTTESTI_CHECK(!testList2.contains(T1()));
+
+ /*
+ * Copy operator
+ */
+ L<T1, T2> testList3(testList);
+
+ /* Check that all is correctly appended. */
+ RTTESTI_CHECK_RETV(testList3.size() == cTestItems);
+ for (size_t i = 0; i < testList3.size(); ++i)
+ RTTESTI_CHECK(testList3.at(i) == paTestData[i]);
+
+ /*
+ * "=" operator
+ */
+ L<T1, T2> testList4;
+ testList4 = testList;
+
+ /* Check that all is correctly appended. */
+ RTTESTI_CHECK_RETV(testList4.size() == cTestItems);
+ for (size_t i = 0; i < testList4.size(); ++i)
+ RTTESTI_CHECK(testList4.at(i) == paTestData[i]);
+
+ /*
+ * Append list
+ */
+ testList3.append(testList4);
+
+ /* Check that all is correctly appended. */
+ RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 2);
+ for (size_t i = 0; i < testList3.size(); ++i)
+ RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);
+
+ /*
+ * Prepend list
+ */
+ testList3.prepend(testList4);
+
+ /* Check that all is correctly appended. */
+ RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 3);
+ for (size_t i = 0; i < testList3.size(); ++i)
+ RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);
+
+ /*
+ * "value" method
+ */
+ for (size_t i = 0; i < testList3.size(); ++i)
+ RTTESTI_CHECK(testList3.value(i) == paTestData[i % cTestItems]);
+ for (size_t i = 0; i < testList3.size(); ++i)
+ RTTESTI_CHECK(testList3.value(i, T1()) == paTestData[i % cTestItems]);
+ RTTESTI_CHECK(testList3.value(testList3.size() + 1) == T1()); /* Invalid index */
+ RTTESTI_CHECK(testList3.value(testList3.size() + 1, T1()) == T1()); /* Invalid index */
+
+ /*
+ * operator[] (reading)
+ */
+ for (size_t i = 0; i < testList.size(); ++i)
+ RTTESTI_CHECK(testList[i] == paTestData[i]);
+
+ /*
+ * operator[] (writing)
+ *
+ * Replace with inverted array.
+ */
+ for (size_t i = 0; i < cTestItems; ++i)
+ testList[i] = paTestData[cTestItems - i - 1];
+ RTTESTI_CHECK_RETV(testList.size() == cTestItems);
+ for (size_t i = 0; i < testList.size(); ++i)
+ RTTESTI_CHECK(testList[i] == paTestData[cTestItems - i - 1]);
+
+ /*
+ * Replace
+ *
+ * Replace with inverted array (Must be original array when finished).
+ */
+ for (size_t i = 0; i < cTestItems; ++i)
+ testList.replace(i, paTestData[i]);
+ RTTESTI_CHECK_RETV(testList.size() == cTestItems);
+ for (size_t i = 0; i < testList.size(); ++i)
+ RTTESTI_CHECK(testList[i] == paTestData[i]);
+
+ /*
+ * Removing
+ */
+
+ /* Remove Range */
+ testList3.removeRange(cTestItems, cTestItems * 2);
+ RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 2);
+ for (size_t i = 0; i < testList3.size(); ++i)
+ RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);
+
+ /* Remove the first half (reverse) */
+ size_t cRemoved = 1;
+ for (size_t i = cTestItems / 2; i > 0; --i, ++cRemoved)
+ {
+ testList.removeAt(i - 1);
+ RTTESTI_CHECK_RETV(testList.size() == cTestItems - cRemoved);
+ }
+ RTTESTI_CHECK_RETV(testList.size() == cTestItems / 2);
+
+ /* Check that all is correctly removed and only the second part of the list
+ * is still there. */
+ for (size_t i = 0; i < testList.size(); ++i)
+ RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);
+
+ /*
+ * setCapacitiy
+ */
+ testList.setCapacity(cTestItems * 5);
+ RTTESTI_CHECK(testList.capacity() == cTestItems * 5);
+ RTTESTI_CHECK_RETV(testList.size() == cTestItems / 2);
+
+ /* As the capacity just increased, we should still have all entries from
+ * the previous list. */
+ for (size_t i = 0; i < testList.size(); ++i)
+ RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);
+
+ /* Decrease the capacity so it will be smaller than the count of items in
+ * the list. The list should be shrink automatically, but the remaining
+ * items should be still valid. */
+ testList.setCapacity(cTestItems / 4);
+ RTTESTI_CHECK_RETV(testList.size() == cTestItems / 4);
+ RTTESTI_CHECK(testList.capacity() == cTestItems / 4);
+ for (size_t i = 0; i < testList.size(); ++i)
+ RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);
+
+ /* Clear all */
+ testList.clear();
+ RTTESTI_CHECK_RETV(testList.isEmpty());
+ RTTESTI_CHECK_RETV(testList.size() == 0);
+ RTTESTI_CHECK(testList.capacity() == defCap);
+
+
+ /* Copy empty lists. */
+ L<T1, T2> testList5(testList);
+ RTTESTI_CHECK_RETV(testList5.isEmpty());
+ RTTESTI_CHECK_RETV(testList5.size() == 0);
+ RTTESTI_CHECK(testList5.capacity() == 0);
+
+ testList5.append(paTestData[0]);
+ testList5 = testList;
+ RTTESTI_CHECK_RETV(testList5.isEmpty());
+ RTTESTI_CHECK_RETV(testList5.size() == 0);
+ RTTESTI_CHECK(testList5.capacity() == 0);
+
+}
+
+/* define RTCList here to see what happens without MT support ;)
+ * (valgrind is the preferred tool to check). */
+#define MTTESTLISTTYPE RTCMTList
+#define MTTESTTYPE uint32_t
+#define MTTESTITEMS 1000
+
+/**
+ * Thread for prepending items to a shared list.
+ *
+ * @param hSelf The thread handle.
+ * @param pvUser The provided user data.
+ */
+DECLCALLBACK(int) mttest1(RTTHREAD hSelf, void *pvUser)
+{
+ MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser;
+
+ /* Prepend new items at the start of the list. */
+ for (size_t i = 0; i < MTTESTITEMS; ++i)
+ pTestList->prepend(0x0);
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * Thread for appending items to a shared list.
+ *
+ * @param hSelf The thread handle.
+ * @param pvUser The provided user data.
+ */
+DECLCALLBACK(int) mttest2(RTTHREAD hSelf, void *pvUser)
+{
+ MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser;
+
+ /* Append new items at the end of the list. */
+ for (size_t i = 0; i < MTTESTITEMS; ++i)
+ pTestList->append(0xFFFFFFFF);
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * Thread for inserting items to a shared list.
+ *
+ * @param hSelf The thread handle.
+ * @param pvUser The provided user data.
+ */
+DECLCALLBACK(int) mttest3(RTTHREAD hSelf, void *pvUser)
+{
+ MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser;
+
+ /* Insert new items in the middle of the list. */
+ for (size_t i = 0; i < MTTESTITEMS; ++i)
+ pTestList->insert(pTestList->size() / 2, 0xF0F0F0F0);
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * Thread for reading items from a shared list.
+ *
+ * @param hSelf The thread handle.
+ * @param pvUser The provided user data.
+ */
+DECLCALLBACK(int) mttest4(RTTHREAD hSelf, void *pvUser)
+{
+ MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser;
+
+ MTTESTTYPE a;
+ /* Try to read C items from random places. */
+ for (size_t i = 0; i < MTTESTITEMS; ++i)
+ {
+ /* Make sure there is at least one item in the list. */
+ while (pTestList->isEmpty()) {};
+ a = pTestList->at(RTRandU32Ex(0, (uint32_t)pTestList->size() - 1));
+ }
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * Thread for replacing items in a shared list.
+ *
+ * @param hSelf The thread handle.
+ * @param pvUser The provided user data.
+ */
+DECLCALLBACK(int) mttest5(RTTHREAD hSelf, void *pvUser)
+{
+ MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser;
+
+ /* Try to replace C items from random places. */
+ for (size_t i = 0; i < MTTESTITEMS; ++i)
+ {
+ /* Make sure there is at least one item in the list. */
+ while (pTestList->isEmpty()) {};
+ pTestList->replace(RTRandU32Ex(0, (uint32_t)pTestList->size() - 1), 0xFF00FF00);
+ }
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * Thread for erasing items from a shared list.
+ *
+ * @param hSelf The thread handle.
+ * @param pvUser The provided user data.
+ */
+DECLCALLBACK(int) mttest6(RTTHREAD hSelf, void *pvUser)
+{
+ MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser;
+
+ /* Try to delete items from random places. */
+ for (size_t i = 0; i < MTTESTITEMS; ++i)
+ {
+ /* Make sure there is at least one item in the list. */
+ while (pTestList->isEmpty()) {};
+ pTestList->removeAt(RTRandU32Ex(0, (uint32_t)pTestList->size() - 1));
+ }
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * Does a multi-threading list test. Several list additions, reading, replacing
+ * and erasing are done simultaneous.
+ *
+ */
+static void test2()
+{
+ RTTestISubF("MT test with 6 threads (%u tests per thread).", MTTESTITEMS);
+
+ RTTHREAD hThread1, hThread2, hThread3, hThread4, hThread5, hThread6;
+ int rc = VINF_SUCCESS;
+
+ MTTESTLISTTYPE<MTTESTTYPE> testList;
+ rc = RTThreadCreate(&hThread1, &mttest1, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest1");
+ AssertRC(rc);
+ rc = RTThreadCreate(&hThread2, &mttest2, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest2");
+ AssertRC(rc);
+ rc = RTThreadCreate(&hThread3, &mttest3, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest3");
+ AssertRC(rc);
+ rc = RTThreadCreate(&hThread4, &mttest4, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest4");
+ AssertRC(rc);
+ rc = RTThreadCreate(&hThread5, &mttest5, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest5");
+ AssertRC(rc);
+ rc = RTThreadCreate(&hThread6, &mttest6, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest6");
+ AssertRC(rc);
+
+ rc = RTThreadWait(hThread1, RT_INDEFINITE_WAIT, 0);
+ AssertRC(rc);
+ rc = RTThreadWait(hThread2, RT_INDEFINITE_WAIT, 0);
+ AssertRC(rc);
+ rc = RTThreadWait(hThread3, RT_INDEFINITE_WAIT, 0);
+ AssertRC(rc);
+ rc = RTThreadWait(hThread4, RT_INDEFINITE_WAIT, 0);
+ AssertRC(rc);
+ rc = RTThreadWait(hThread5, RT_INDEFINITE_WAIT, 0);
+ AssertRC(rc);
+ rc = RTThreadWait(hThread6, RT_INDEFINITE_WAIT, 0);
+ AssertRC(rc);
+
+ RTTESTI_CHECK_RETV(testList.size() == MTTESTITEMS * 2);
+ for (size_t i = 0; i < testList.size(); ++i)
+ {
+ uint32_t a = testList.at(i);
+ RTTESTI_CHECK(a == 0x0 || a == 0xFFFFFFFF || a == 0xF0F0F0F0 || a == 0xFF00FF00);
+ }
+}
+
+int main()
+{
+ /* How many integer test items should be created. */
+ static const size_t s_cTestCount = 1000;
+
+ RTTEST hTest;
+ RTEXITCODE rcExit = RTTestInitAndCreate("tstIprtList", &hTest);
+ if (rcExit)
+ return rcExit;
+ RTTestBanner(hTest);
+
+ /* Some host info. */
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "sizeof(void*)=%d", sizeof(void*));
+
+ /*
+ * The tests.
+ */
+
+ /*
+ * Native types.
+ */
+ uint8_t au8TestInts[s_cTestCount];
+ for (size_t i = 0; i < RT_ELEMENTS(au8TestInts); ++i)
+ au8TestInts[i] = (uint8_t)RTRandU32Ex(1, UINT8_MAX);
+ test1<RTCList, uint8_t, uint8_t, uint8_t>("ST: Native type", au8TestInts, RT_ELEMENTS(au8TestInts));
+ test1<RTCMTList, uint8_t, uint8_t, uint8_t>("MT: Native type", au8TestInts, RT_ELEMENTS(au8TestInts));
+
+ uint16_t au16TestInts[s_cTestCount];
+ for (size_t i = 0; i < RT_ELEMENTS(au16TestInts); ++i)
+ au16TestInts[i] = (uint16_t)RTRandU32Ex(1, UINT16_MAX);
+ test1<RTCList, uint16_t, uint16_t, uint16_t>("ST: Native type", au16TestInts, RT_ELEMENTS(au16TestInts));
+ test1<RTCMTList, uint16_t, uint16_t, uint16_t>("MT: Native type", au16TestInts, RT_ELEMENTS(au16TestInts));
+
+ uint32_t au32TestInts[s_cTestCount];
+ for (size_t i = 0; i < RT_ELEMENTS(au32TestInts); ++i)
+ au32TestInts[i] = RTRandU32Ex(1, UINT32_MAX);
+ test1<RTCList, uint32_t, uint32_t, uint32_t>("ST: Native type", au32TestInts, RT_ELEMENTS(au32TestInts));
+ test1<RTCMTList, uint32_t, uint32_t, uint32_t>("MT: Native type", au32TestInts, RT_ELEMENTS(au32TestInts));
+
+ /*
+ * Specialized type.
+ */
+ uint64_t au64TestInts[s_cTestCount];
+ for (size_t i = 0; i < RT_ELEMENTS(au64TestInts); ++i)
+ au64TestInts[i] = RTRandU64Ex(1, UINT64_MAX);
+ test1<RTCList, uint64_t, uint64_t, uint64_t>("ST: Specialized type", au64TestInts, RT_ELEMENTS(au64TestInts));
+ test1<RTCMTList, uint64_t, uint64_t, uint64_t>("MT: Specialized type", au64TestInts, RT_ELEMENTS(au64TestInts));
+
+ /*
+ * Big size type (translate to internal pointer list).
+ */
+ test1<RTCList, RTCString, RTCString *, const char *>("ST: Class type", g_apszTestStrings, RT_ELEMENTS(g_apszTestStrings));
+ test1<RTCMTList, RTCString, RTCString *, const char *>("MT: Class type", g_apszTestStrings, RT_ELEMENTS(g_apszTestStrings));
+
+ /*
+ * Multi-threading test.
+ */
+ test2();
+
+ /*
+ * Summary.
+ */
+ return RTTestSummaryAndDestroy(hTest);
+}
+
diff --git a/src/VBox/Runtime/testcase/tstIprtMiniString.cpp b/src/VBox/Runtime/testcase/tstIprtMiniString.cpp
index c945d5dbf..b4d58e8ab 100644
--- a/src/VBox/Runtime/testcase/tstIprtMiniString.cpp
+++ b/src/VBox/Runtime/testcase/tstIprtMiniString.cpp
@@ -1,6 +1,6 @@
-/* $Id: tstIprtMiniString.cpp $ */
+/* $Id: tstIprtMiniString.cpp 36561 2011-04-05 13:42:59Z vboxsync $ */
/** @file
- * IPRT Testcase - iprt::MiniString.
+ * IPRT Testcase - RTCString.
*/
/*
@@ -41,7 +41,7 @@ static void test1Hlp1(const char *pszExpect, const char *pszFormat, ...)
#if 0
va_list va;
va_start(va, pszFormat);
- iprt::MiniString strTst(pszFormat, va);
+ RTCString strTst(pszFormat, va);
va_end(va);
RTTESTI_CHECK_MSG(strTst.equals(pszExpect), ("strTst='%s' expected='%s'\n", strTst.c_str(), pszExpect));
#endif
@@ -69,15 +69,15 @@ static void test1(RTTEST hTest)
RTTestIFailed("line %u: expected \"%s\" got \"%s\"", __LINE__, szExpect, (Str).c_str()); \
} while (0)
- iprt::MiniString empty;
+ RTCString empty;
CHECK(empty.length() == 0);
CHECK(empty.capacity() == 0);
- iprt::MiniString sixbytes("12345");
+ RTCString sixbytes("12345");
CHECK(sixbytes.length() == 5);
CHECK(sixbytes.capacity() == 6);
- sixbytes.append(iprt::MiniString("678"));
+ sixbytes.append(RTCString("678"));
CHECK(sixbytes.length() == 8);
CHECK(sixbytes.capacity() >= 9);
@@ -94,20 +94,20 @@ static void test1(RTTEST hTest)
CHECK(sixbytes.length() == 6);
CHECK(sixbytes.capacity() == 7);
- iprt::MiniString morebytes("tobereplaced");
+ RTCString morebytes("tobereplaced");
morebytes = "newstring ";
morebytes.append(sixbytes);
CHECK_DUMP(morebytes == "newstring 123456", morebytes.c_str());
- iprt::MiniString third(morebytes);
+ RTCString third(morebytes);
third.reserve(100 * 1024); // 100 KB
CHECK_DUMP(third == "newstring 123456", morebytes.c_str() );
CHECK(third.capacity() == 100 * 1024);
CHECK(third.length() == morebytes.length()); // must not have changed
- iprt::MiniString copy1(morebytes);
- iprt::MiniString copy2 = morebytes;
+ RTCString copy1(morebytes);
+ RTCString copy2 = morebytes;
CHECK(copy1 == copy2);
copy1 = NULL;
@@ -116,38 +116,38 @@ static void test1(RTTEST hTest)
copy1 = "";
CHECK(copy1.length() == 0);
- CHECK(iprt::MiniString("abc") < iprt::MiniString("def"));
- CHECK(iprt::MiniString("") < iprt::MiniString("def"));
- CHECK(iprt::MiniString("abc") > iprt::MiniString(""));
- CHECK(iprt::MiniString("abc") != iprt::MiniString("def"));
- CHECK_DUMP_I(iprt::MiniString("def") > iprt::MiniString("abc"));
- CHECK(iprt::MiniString("abc") == iprt::MiniString("abc"));
- CHECK(iprt::MiniString("").compare("") == 0);
- CHECK(iprt::MiniString("").compare(NULL) == 0);
- CHECK(iprt::MiniString("").compare("a") < 0);
- CHECK(iprt::MiniString("a").compare("") > 0);
- CHECK(iprt::MiniString("a").compare(NULL) > 0);
-
- CHECK(iprt::MiniString("abc") < "def");
- CHECK(iprt::MiniString("abc") != "def");
- CHECK_DUMP_I(iprt::MiniString("def") > "abc");
- CHECK(iprt::MiniString("abc") == "abc");
-
- CHECK(iprt::MiniString("abc").equals("abc"));
- CHECK(!iprt::MiniString("abc").equals("def"));
- CHECK(iprt::MiniString("abc").equalsIgnoreCase("Abc"));
- CHECK(iprt::MiniString("abc").equalsIgnoreCase("ABc"));
- CHECK(iprt::MiniString("abc").equalsIgnoreCase("ABC"));
- CHECK(!iprt::MiniString("abc").equalsIgnoreCase("dBC"));
- CHECK(iprt::MiniString("").equals(""));
- CHECK(iprt::MiniString("").equals(NULL));
- CHECK(!iprt::MiniString("").equals("a"));
- CHECK(!iprt::MiniString("a").equals(""));
- CHECK(!iprt::MiniString("a").equals(NULL));
- CHECK(iprt::MiniString("").equalsIgnoreCase(""));
- CHECK(iprt::MiniString("").equalsIgnoreCase(NULL));
- CHECK(!iprt::MiniString("").equalsIgnoreCase("a"));
- CHECK(!iprt::MiniString("a").equalsIgnoreCase(""));
+ CHECK(RTCString("abc") < RTCString("def"));
+ CHECK(RTCString("") < RTCString("def"));
+ CHECK(RTCString("abc") > RTCString(""));
+ CHECK(RTCString("abc") != RTCString("def"));
+ CHECK_DUMP_I(RTCString("def") > RTCString("abc"));
+ CHECK(RTCString("abc") == RTCString("abc"));
+ CHECK(RTCString("").compare("") == 0);
+ CHECK(RTCString("").compare(NULL) == 0);
+ CHECK(RTCString("").compare("a") < 0);
+ CHECK(RTCString("a").compare("") > 0);
+ CHECK(RTCString("a").compare(NULL) > 0);
+
+ CHECK(RTCString("abc") < "def");
+ CHECK(RTCString("abc") != "def");
+ CHECK_DUMP_I(RTCString("def") > "abc");
+ CHECK(RTCString("abc") == "abc");
+
+ CHECK(RTCString("abc").equals("abc"));
+ CHECK(!RTCString("abc").equals("def"));
+ CHECK(RTCString("abc").equalsIgnoreCase("Abc"));
+ CHECK(RTCString("abc").equalsIgnoreCase("ABc"));
+ CHECK(RTCString("abc").equalsIgnoreCase("ABC"));
+ CHECK(!RTCString("abc").equalsIgnoreCase("dBC"));
+ CHECK(RTCString("").equals(""));
+ CHECK(RTCString("").equals(NULL));
+ CHECK(!RTCString("").equals("a"));
+ CHECK(!RTCString("a").equals(""));
+ CHECK(!RTCString("a").equals(NULL));
+ CHECK(RTCString("").equalsIgnoreCase(""));
+ CHECK(RTCString("").equalsIgnoreCase(NULL));
+ CHECK(!RTCString("").equalsIgnoreCase("a"));
+ CHECK(!RTCString("a").equalsIgnoreCase(""));
copy2.setNull();
for (int i = 0; i < 100; ++i)
@@ -166,7 +166,7 @@ static void test1(RTTEST hTest)
CHECK(copy2.length() == 100);
/* printf */
- iprt::MiniString StrFmt;
+ RTCString StrFmt;
CHECK(StrFmt.printf("%s-%s-%d", "abc", "def", 42).equals("abc-def-42"));
test1Hlp1("abc-42-def", "%s-%d-%s", "abc", 42, "def");
test1Hlp1("", "");
@@ -174,44 +174,44 @@ static void test1(RTTEST hTest)
test1Hlp1("foobar", "%s", "foobar");
/* substring constructors */
- iprt::MiniString SubStr1("", (size_t)0);
+ RTCString SubStr1("", (size_t)0);
CHECK_EQUAL(SubStr1, "");
- iprt::MiniString SubStr2("abcdef", 2);
+ RTCString SubStr2("abcdef", 2);
CHECK_EQUAL(SubStr2, "ab");
- iprt::MiniString SubStr3("abcdef", 1);
+ RTCString SubStr3("abcdef", 1);
CHECK_EQUAL(SubStr3, "a");
- iprt::MiniString SubStr4("abcdef", 6);
+ RTCString SubStr4("abcdef", 6);
CHECK_EQUAL(SubStr4, "abcdef");
- iprt::MiniString SubStr5("abcdef", 7);
+ RTCString SubStr5("abcdef", 7);
CHECK_EQUAL(SubStr5, "abcdef");
- iprt::MiniString SubStrBase("abcdef");
+ RTCString SubStrBase("abcdef");
- iprt::MiniString SubStr10(SubStrBase, 0);
+ RTCString SubStr10(SubStrBase, 0);
CHECK_EQUAL(SubStr10, "abcdef");
- iprt::MiniString SubStr11(SubStrBase, 1);
+ RTCString SubStr11(SubStrBase, 1);
CHECK_EQUAL(SubStr11, "bcdef");
- iprt::MiniString SubStr12(SubStrBase, 1, 1);
+ RTCString SubStr12(SubStrBase, 1, 1);
CHECK_EQUAL(SubStr12, "b");
- iprt::MiniString SubStr13(SubStrBase, 2, 3);
+ RTCString SubStr13(SubStrBase, 2, 3);
CHECK_EQUAL(SubStr13, "cde");
- iprt::MiniString SubStr14(SubStrBase, 2, 4);
+ RTCString SubStr14(SubStrBase, 2, 4);
CHECK_EQUAL(SubStr14, "cdef");
- iprt::MiniString SubStr15(SubStrBase, 2, 5);
+ RTCString SubStr15(SubStrBase, 2, 5);
CHECK_EQUAL(SubStr15, "cdef");
/* substr() and substrCP() functions */
- iprt::MiniString strTest("");
+ RTCString strTest("");
CHECK_EQUAL(strTest.substr(0), "");
CHECK_EQUAL(strTest.substrCP(0), "");
CHECK_EQUAL(strTest.substr(1), "");
@@ -255,26 +255,68 @@ static void test1(RTTEST hTest)
size_t pos = strTest.find("ß");
CHECK_EQUAL(strTest.substr(pos), "ßäbcdef");
+ /* split */
+ RTCList<RTCString> spList1 = RTCString("##abcdef##abcdef####abcdef##").split("##", RTCString::RemoveEmptyParts);
+ RTTESTI_CHECK(spList1.size() == 3);
+ for (size_t i = 0; i < spList1.size(); ++i)
+ RTTESTI_CHECK(spList1.at(i) == "abcdef");
+ RTCList<RTCString> spList2 = RTCString("##abcdef##abcdef####abcdef##").split("##", RTCString::KeepEmptyParts);
+ RTTESTI_CHECK_RETV(spList2.size() == 5);
+ RTTESTI_CHECK(spList2.at(0) == "");
+ RTTESTI_CHECK(spList2.at(1) == "abcdef");
+ RTTESTI_CHECK(spList2.at(2) == "abcdef");
+ RTTESTI_CHECK(spList2.at(3) == "");
+ RTTESTI_CHECK(spList2.at(4) == "abcdef");
+ RTCList<RTCString> spList3 = RTCString().split("##", RTCString::KeepEmptyParts);
+ RTTESTI_CHECK(spList3.size() == 0);
+ RTCList<RTCString> spList4 = RTCString().split("");
+ RTTESTI_CHECK(spList4.size() == 0);
+ RTCList<RTCString> spList5 = RTCString("abcdef").split("");
+ RTTESTI_CHECK_RETV(spList5.size() == 1);
+ RTTESTI_CHECK(spList5.at(0) == "abcdef");
+
+ /* join */
+ RTCList<RTCString> jnList;
+ strTest = RTCString::join(jnList);
+ RTTESTI_CHECK(strTest == "");
+ strTest = RTCString::join(jnList, "##");
+ RTTESTI_CHECK(strTest == "");
+
+ jnList.append("abcdef");
+ strTest = RTCString::join(jnList, "##");
+ RTTESTI_CHECK(strTest == "abcdef");
+
+ jnList.append("abcdef");
+ strTest = RTCString::join(jnList, ";");
+ RTTESTI_CHECK(strTest == "abcdef;abcdef");
+
+ for (size_t i = 0; i < 3; ++i)
+ jnList.append("abcdef");
+ strTest = RTCString::join(jnList);
+ RTTESTI_CHECK(strTest == "abcdefabcdefabcdefabcdefabcdef");
+ strTest = RTCString::join(jnList, "##");
+ RTTESTI_CHECK(strTest == "abcdef##abcdef##abcdef##abcdef##abcdef");
+
/* special constructor and assignment arguments */
- iprt::MiniString StrCtor1("");
+ RTCString StrCtor1("");
RTTESTI_CHECK(StrCtor1.isEmpty());
RTTESTI_CHECK(StrCtor1.length() == 0);
- iprt::MiniString StrCtor2(NULL);
+ RTCString StrCtor2(NULL);
RTTESTI_CHECK(StrCtor2.isEmpty());
RTTESTI_CHECK(StrCtor2.length() == 0);
- iprt::MiniString StrCtor1d(StrCtor1);
+ RTCString StrCtor1d(StrCtor1);
RTTESTI_CHECK(StrCtor1d.isEmpty());
RTTESTI_CHECK(StrCtor1d.length() == 0);
- iprt::MiniString StrCtor2d(StrCtor2);
+ RTCString StrCtor2d(StrCtor2);
RTTESTI_CHECK(StrCtor2d.isEmpty());
RTTESTI_CHECK(StrCtor2d.length() == 0);
for (unsigned i = 0; i < 2; i++)
{
- iprt::MiniString StrAssign;
+ RTCString StrAssign;
if (i) StrAssign = "abcdef";
StrAssign = (char *)NULL;
RTTESTI_CHECK(StrAssign.isEmpty());
@@ -328,14 +370,14 @@ static void test2(RTTEST hTest)
RTTESTI_CHECK(mymemcmp((str1).c_str(), (str2).c_str(), (str2).length() + 1) == 0); \
} while (0)
- iprt::MiniString strTmp;
+ RTCString strTmp;
char szDst[16];
/* Collect all upper and lower case code points. */
- iprt::MiniString strLower("");
+ RTCString strLower("");
strLower.reserve(_4M);
- iprt::MiniString strUpper("");
+ RTCString strUpper("");
strUpper.reserve(_4M);
for (RTUNICP uc = 1; uc <= 0x10fffd; uc++)
@@ -358,7 +400,7 @@ static void test2(RTTEST hTest)
into the same or less number of bytes. */
size_t cch = 0;
const char *pszCur = strLower.c_str();
- iprt::MiniString strUpper2("");
+ RTCString strUpper2("");
strUpper2.reserve(strLower.length() + 64);
for (;;)
{
@@ -402,7 +444,7 @@ static void test2(RTTEST hTest)
/* Ditto for the upper case string. */
cch = 0;
pszCur = strUpper.c_str();
- iprt::MiniString strLower2("");
+ RTCString strLower2("");
strLower2.reserve(strUpper.length() + 64);
for (;;)
{
diff --git a/src/VBox/Runtime/testcase/tstLdr-2.cpp b/src/VBox/Runtime/testcase/tstLdr-2.cpp
index 9dcb2ca7e..dbeb310e6 100644
--- a/src/VBox/Runtime/testcase/tstLdr-2.cpp
+++ b/src/VBox/Runtime/testcase/tstLdr-2.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstLdr-2.cpp $ */
+/* $Id: tstLdr-2.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Testcase for parts of RTLdr*, manual inspection.
*/
diff --git a/src/VBox/Runtime/testcase/tstLdr-3.cpp b/src/VBox/Runtime/testcase/tstLdr-3.cpp
index cfda66ac9..f8fb66880 100644
--- a/src/VBox/Runtime/testcase/tstLdr-3.cpp
+++ b/src/VBox/Runtime/testcase/tstLdr-3.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstLdr-3.cpp $ */
+/* $Id: tstLdr-3.cpp 32878 2010-10-03 20:30:49Z vboxsync $ */
/** @file
* IPRT - Testcase for parts of RTLdr*, manual inspection.
*/
diff --git a/src/VBox/Runtime/testcase/tstLdr-4.cpp b/src/VBox/Runtime/testcase/tstLdr-4.cpp
index bfe1959f8..c385f3ca9 100644
--- a/src/VBox/Runtime/testcase/tstLdr-4.cpp
+++ b/src/VBox/Runtime/testcase/tstLdr-4.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstLdr-4.cpp $ */
+/* $Id: tstLdr-4.cpp 33269 2010-10-20 15:42:28Z vboxsync $ */
/** @file
* IPRT - Testcase for RTLdrOpen using ldrLdrObjR0.r0.
*/
diff --git a/src/VBox/Runtime/testcase/tstLdr.cpp b/src/VBox/Runtime/testcase/tstLdr.cpp
index 8003bdc2f..9b2a0ae4c 100644
--- a/src/VBox/Runtime/testcase/tstLdr.cpp
+++ b/src/VBox/Runtime/testcase/tstLdr.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstLdr.cpp $ */
+/* $Id: tstLdr.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - Testcase for parts of RTLdr*.
*/
diff --git a/src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp b/src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp
index ad50e9ad2..aaa75b836 100644
--- a/src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp
+++ b/src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstLdrDisasmTest.cpp $ */
+/* $Id: tstLdrDisasmTest.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTLdr test object.
*
diff --git a/src/VBox/Runtime/testcase/tstLdrLoad.cpp b/src/VBox/Runtime/testcase/tstLdrLoad.cpp
index ce9b283f4..7d794e222 100644
--- a/src/VBox/Runtime/testcase/tstLdrLoad.cpp
+++ b/src/VBox/Runtime/testcase/tstLdrLoad.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstLdrLoad.cpp $ */
+/* $Id: tstLdrLoad.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Native Loader.
*/
diff --git a/src/VBox/Runtime/testcase/tstLdrObj.cpp b/src/VBox/Runtime/testcase/tstLdrObj.cpp
index 6d7783d00..747c3ee57 100644
--- a/src/VBox/Runtime/testcase/tstLdrObj.cpp
+++ b/src/VBox/Runtime/testcase/tstLdrObj.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstLdrObj.cpp $ */
+/* $Id: tstLdrObj.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* IPRT - RTLdr test object.
*
diff --git a/src/VBox/Runtime/testcase/tstLdrObjR0.cpp b/src/VBox/Runtime/testcase/tstLdrObjR0.cpp
index 23c220d4e..93e96389b 100644
--- a/src/VBox/Runtime/testcase/tstLdrObjR0.cpp
+++ b/src/VBox/Runtime/testcase/tstLdrObjR0.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstLdrObjR0.cpp $ */
+/* $Id: tstLdrObjR0.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTLdr test object.
*
diff --git a/src/VBox/Runtime/testcase/tstLog.cpp b/src/VBox/Runtime/testcase/tstLog.cpp
index 1e1366c7b..d1a31f810 100644
--- a/src/VBox/Runtime/testcase/tstLog.cpp
+++ b/src/VBox/Runtime/testcase/tstLog.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstLog.cpp $ */
+/* $Id: tstLog.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Log Formatting.
*/
diff --git a/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp b/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp
index 9a4474c8a..946194944 100644
--- a/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp
+++ b/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp
@@ -1,6 +1,6 @@
-/* $Id: tstMemAutoPtr.cpp $ */
+/* $Id: tstMemAutoPtr.cpp 36529 2011-04-04 13:54:13Z vboxsync $ */
/** @file
- * IPRT - Testcase the RTMemAutoPtr template.
+ * IPRT - Testcase the RTCMemAutoPtr template.
*/
/*
@@ -27,7 +27,7 @@
/*******************************************************************************
* Header Files *
*******************************************************************************/
-#include <iprt/mem.h>
+#include <iprt/cpp/mem.h>
#include <iprt/stream.h>
#include <iprt/initterm.h>
#include <iprt/string.h>
@@ -60,7 +60,7 @@ static unsigned g_cFrees;
*/
extern "C" int tstMemAutoPtrDisas1(void **ppv)
{
- RTMemAutoPtr<TSTMEMAUTOPTRSTRUCT> Handle(1);
+ RTCMemAutoPtr<TSTMEMAUTOPTRSTRUCT> Handle(1);
if (!Handle)
{
Handle->a = RTRandU32();
@@ -134,7 +134,7 @@ int main()
* Some simple stuff.
*/
{
- RTMemAutoPtr<char> NilObj;
+ RTCMemAutoPtr<char> NilObj;
CHECK_EXPR(!NilObj);
CHECK_EXPR(NilObj.get() == NULL);
CHECK_EXPR(NilObj.release() == NULL);
@@ -142,13 +142,13 @@ int main()
}
{
- RTMemAutoPtr<char> Alloc(10);
+ RTCMemAutoPtr<char> Alloc(10);
CHECK_EXPR(Alloc.get() != NULL);
char *pch = Alloc.release();
CHECK_EXPR(pch != NULL);
CHECK_EXPR(Alloc.get() == NULL);
- RTMemAutoPtr<char> Manage(pch);
+ RTCMemAutoPtr<char> Manage(pch);
CHECK_EXPR(Manage.get() == pch);
CHECK_EXPR(&Manage[0] == pch);
CHECK_EXPR(&Manage[1] == &pch[1]);
@@ -160,7 +160,7 @@ int main()
* arguments and also check some subscript / reference limit thing.
*/
{
- RTMemAutoPtr<char, RTMemEfAutoFree<char>, RTMemEfReallocNP> Electric(10);
+ RTCMemAutoPtr<char, RTCMemEfAutoFree<char>, RTMemEfReallocNP> Electric(10);
CHECK_EXPR(Electric.get() != NULL);
Electric[0] = '0';
CHECK_EXPR(Electric[0] == '0');
@@ -177,14 +177,14 @@ int main()
*/
g_cFrees = 0;
{
- RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt(128);
+ RTCMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt(128);
FreeIt[127] = '0';
}
CHECK_EXPR(g_cFrees == 1);
g_cFrees = 0;
{
- RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt2(128);
+ RTCMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt2(128);
FreeIt2[127] = '1';
FreeIt2.reset();
FreeIt2.alloc(128);
@@ -195,7 +195,7 @@ int main()
g_cFrees = 0;
{
- RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> DontFreeIt(256);
+ RTCMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> DontFreeIt(256);
DontFreeIt[255] = '0';
RTMemEfFreeNP(DontFreeIt.release());
}
@@ -203,7 +203,7 @@ int main()
g_cFrees = 0;
{
- RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt3(128);
+ RTCMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt3(128);
FreeIt3[127] = '0';
CHECK_EXPR(FreeIt3.realloc(128));
FreeIt3[127] = '0';
@@ -218,7 +218,7 @@ int main()
g_cFrees = 0;
{
- RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt4;
+ RTCMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt4;
CHECK_EXPR(FreeIt4.alloc(123));
CHECK_EXPR(FreeIt4.realloc(543));
FreeIt4 = (char *)NULL;
@@ -230,7 +230,7 @@ int main()
* Check the ->, [] and * (unary) operators with some useful struct.
*/
{
- RTMemAutoPtr<TSTMEMAUTOPTRSTRUCT> Struct1(1);
+ RTCMemAutoPtr<TSTMEMAUTOPTRSTRUCT> Struct1(1);
Struct1->a = 0x11223344;
Struct1->b = 0x55667788;
Struct1->c = 0x99aabbcc;
@@ -265,12 +265,12 @@ int main()
* Check the zeroing of memory.
*/
{
- RTMemAutoPtr<uint64_t, RTMemAutoDestructor<uint64_t>, tstMemAutoPtrAllocatorNoZero> Zeroed1(1, true);
+ RTCMemAutoPtr<uint64_t, RTCMemAutoDestructor<uint64_t>, tstMemAutoPtrAllocatorNoZero> Zeroed1(1, true);
CHECK_EXPR(*Zeroed1 == 0);
}
{
- RTMemAutoPtr<uint64_t, RTMemAutoDestructor<uint64_t>, tstMemAutoPtrAllocatorNoZero> Zeroed2;
+ RTCMemAutoPtr<uint64_t, RTCMemAutoDestructor<uint64_t>, tstMemAutoPtrAllocatorNoZero> Zeroed2;
Zeroed2.alloc(5, true);
CHECK_EXPR(Zeroed2[0] == 0);
CHECK_EXPR(Zeroed2[1] == 0);
diff --git a/src/VBox/Runtime/testcase/tstMove.cpp b/src/VBox/Runtime/testcase/tstMove.cpp
index ad8d9870c..a2589795e 100644
--- a/src/VBox/Runtime/testcase/tstMove.cpp
+++ b/src/VBox/Runtime/testcase/tstMove.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstMove.cpp $ */
+/* $Id: tstMove.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - RTFileMove & RTDirMove test program.
*/
diff --git a/src/VBox/Runtime/testcase/tstMp-1.cpp b/src/VBox/Runtime/testcase/tstMp-1.cpp
index 736f5181d..1de62c71b 100644
--- a/src/VBox/Runtime/testcase/tstMp-1.cpp
+++ b/src/VBox/Runtime/testcase/tstMp-1.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstMp-1.cpp $ */
+/* $Id: tstMp-1.cpp 33814 2010-11-05 21:28:14Z vboxsync $ */
/** @file
* IPRT Testcase - RTMp.
*/
diff --git a/src/VBox/Runtime/testcase/tstNoCrt-1.cpp b/src/VBox/Runtime/testcase/tstNoCrt-1.cpp
index 84afa1c53..fc8db47c7 100644
--- a/src/VBox/Runtime/testcase/tstNoCrt-1.cpp
+++ b/src/VBox/Runtime/testcase/tstNoCrt-1.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstNoCrt-1.cpp $ */
+/* $Id: tstNoCrt-1.cpp 30320 2010-06-21 08:35:09Z vboxsync $ */
/** @file
* IPRT Testcase - Testcase for the No-CRT assembly bits.
*/
diff --git a/src/VBox/Runtime/testcase/tstOnce.cpp b/src/VBox/Runtime/testcase/tstOnce.cpp
index bd48bcf96..15c717e73 100644
--- a/src/VBox/Runtime/testcase/tstOnce.cpp
+++ b/src/VBox/Runtime/testcase/tstOnce.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstOnce.cpp $ */
+/* $Id: tstOnce.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - RTOnce.
*/
diff --git a/src/VBox/Runtime/testcase/tstPrfRT.cpp b/src/VBox/Runtime/testcase/tstPrfRT.cpp
index 68be5fe59..0a8c1003b 100644
--- a/src/VBox/Runtime/testcase/tstPrfRT.cpp
+++ b/src/VBox/Runtime/testcase/tstPrfRT.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstPrfRT.cpp $ */
+/* $Id: tstPrfRT.cpp 29250 2010-05-09 17:53:58Z vboxsync $ */
/** @file
* IPRT testcase - profile some of the important functions.
*/
diff --git a/src/VBox/Runtime/testcase/tstR0ThreadPreemption.cpp b/src/VBox/Runtime/testcase/tstR0ThreadPreemption.cpp
index 0c0cfd8d6..ca91925c9 100644
--- a/src/VBox/Runtime/testcase/tstR0ThreadPreemption.cpp
+++ b/src/VBox/Runtime/testcase/tstR0ThreadPreemption.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstR0ThreadPreemption.cpp $ */
+/* $Id: tstR0ThreadPreemption.cpp 29250 2010-05-09 17:53:58Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Thread Preemption.
*/
diff --git a/src/VBox/Runtime/testcase/tstR0ThreadPreemption.h b/src/VBox/Runtime/testcase/tstR0ThreadPreemption.h
index f37376428..a5b993662 100644
--- a/src/VBox/Runtime/testcase/tstR0ThreadPreemption.h
+++ b/src/VBox/Runtime/testcase/tstR0ThreadPreemption.h
@@ -1,4 +1,4 @@
-/* $Id: tstR0ThreadPreemption.h $ */
+/* $Id: tstR0ThreadPreemption.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Thread Preemption, common header.
*/
diff --git a/src/VBox/Runtime/testcase/tstR0ThreadPreemptionDriver.cpp b/src/VBox/Runtime/testcase/tstR0ThreadPreemptionDriver.cpp
index 921269391..b09a08dc3 100644
--- a/src/VBox/Runtime/testcase/tstR0ThreadPreemptionDriver.cpp
+++ b/src/VBox/Runtime/testcase/tstR0ThreadPreemptionDriver.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstR0ThreadPreemptionDriver.cpp $ */
+/* $Id: tstR0ThreadPreemptionDriver.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Thread Preemption, driver program.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTAssertCompile.cpp b/src/VBox/Runtime/testcase/tstRTAssertCompile.cpp
index 7c8e7bd96..dd3e5538d 100644
--- a/src/VBox/Runtime/testcase/tstRTAssertCompile.cpp
+++ b/src/VBox/Runtime/testcase/tstRTAssertCompile.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTAssertCompile.cpp $ */
+/* $Id: tstRTAssertCompile.cpp 37809 2011-07-07 08:15:02Z vboxsync $ */
/** @file
* IPRT Testcase - AssertCompile* - A Compile Time Testcase.
*/
@@ -60,7 +60,7 @@ int main(int argc, char **argv)
AssertCompileSizeAlignment(u64, 4);
AssertCompileSizeAlignment(u64, 8);
- typedef struct STRUCT1
+ typedef struct STRUCT12S
{
uint8_t u8;
uint8_t au8[8];
@@ -112,7 +112,7 @@ int main(int argc, char **argv)
AssertCompileMemberOffset(STRUCT1, au8[8], 9);
#endif
- typedef union UNION1
+ typedef union UNION1U
{
STRUCT1 s1;
STRUCT2 s2;
diff --git a/src/VBox/Runtime/testcase/tstRTAvl.cpp b/src/VBox/Runtime/testcase/tstRTAvl.cpp
index e77f68113..067ef9816 100644
--- a/src/VBox/Runtime/testcase/tstRTAvl.cpp
+++ b/src/VBox/Runtime/testcase/tstRTAvl.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTAvl.cpp $ */
+/* $Id: tstRTAvl.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT Testcase - AVL trees.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTBase64.cpp b/src/VBox/Runtime/testcase/tstRTBase64.cpp
index bbb2c38d9..41f905c5e 100644
--- a/src/VBox/Runtime/testcase/tstRTBase64.cpp
+++ b/src/VBox/Runtime/testcase/tstRTBase64.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTBase64.cpp $ */
+/* $Id: tstRTBase64.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Base64.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTBitOperations.cpp b/src/VBox/Runtime/testcase/tstRTBitOperations.cpp
index f7a0c5a10..a962ec69e 100644
--- a/src/VBox/Runtime/testcase/tstRTBitOperations.cpp
+++ b/src/VBox/Runtime/testcase/tstRTBitOperations.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTBitOperations.cpp $ */
+/* $Id: tstRTBitOperations.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Inlined Bit Operations.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTCidr.cpp b/src/VBox/Runtime/testcase/tstRTCidr.cpp
index 48c5ed375..270ac2549 100644
--- a/src/VBox/Runtime/testcase/tstRTCidr.cpp
+++ b/src/VBox/Runtime/testcase/tstRTCidr.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTCidr.cpp $ */
+/* $Id: tstRTCidr.cpp 29845 2010-05-27 11:29:36Z vboxsync $ */
/** @file
* IPRT Testcase - IPv4.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTCircBuf.cpp b/src/VBox/Runtime/testcase/tstRTCircBuf.cpp
index 0a6971228..7cb8ef81e 100644
--- a/src/VBox/Runtime/testcase/tstRTCircBuf.cpp
+++ b/src/VBox/Runtime/testcase/tstRTCircBuf.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTCircBuf.cpp $ */
+/* $Id: tstRTCircBuf.cpp 37210 2011-05-25 09:55:16Z vboxsync $ */
/** @file
* IPRT Testcase - Lock free circular buffers.
*/
@@ -29,8 +29,8 @@
*******************************************************************************/
#include <iprt/circbuf.h>
-#include <iprt/string.h>
#include <iprt/err.h>
+#include <iprt/string.h>
#include <iprt/test.h>
@@ -39,8 +39,8 @@
*/
static void tst1(void)
{
- void *pvBuf = NULL;
- size_t cbSize = 0;
+ void *pvBuf;
+ size_t cbSize;
char pcTestPattern1[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9 };
char pcTestPattern2[] = { 0x8, 0x9, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9 };
@@ -61,7 +61,7 @@ static void tst1(void)
RTCircBufReleaseWriteBlock(pBuf, 10);
RTTESTI_CHECK(RTCircBufFree(pBuf) == 0);
RTTESTI_CHECK(RTCircBufUsed(pBuf) == 10);
- RTTESTI_CHECK(memcmp(pBuf->pvBuf, pcTestPattern1, 10) == 0); /* Check the internal state */
+// RTTESTI_CHECK(memcmp(pBuf->pvBuf, pcTestPattern1, 10) == 0); /* Check the internal state */
/* Half read */
RTTestISub("Half read");
@@ -80,7 +80,7 @@ static void tst1(void)
RTCircBufReleaseWriteBlock(pBuf, 2);
RTTESTI_CHECK(RTCircBufFree(pBuf) == 3);
RTTESTI_CHECK(RTCircBufUsed(pBuf) == 7);
- RTTESTI_CHECK(memcmp(pBuf->pvBuf, pcTestPattern2, 10) == 0); /* Check the internal state */
+// RTTESTI_CHECK(memcmp(pBuf->pvBuf, pcTestPattern2, 10) == 0); /* Check the internal state */
/* Split tests */
/* Split read */
@@ -112,7 +112,7 @@ static void tst1(void)
RTCircBufReleaseWriteBlock(pBuf, 2);
RTTESTI_CHECK(RTCircBufFree(pBuf) == 0);
RTTESTI_CHECK(RTCircBufUsed(pBuf) == 10);
- RTTESTI_CHECK(memcmp(pBuf->pvBuf, pcTestPattern3, 10) == 0); /* Check the internal state */
+// RTTESTI_CHECK(memcmp(pBuf->pvBuf, pcTestPattern3, 10) == 0); /* Check the internal state */
/* Destroy */
RTCircBufDestroy(pBuf);
diff --git a/src/VBox/Runtime/testcase/tstRTCoreDump.cpp b/src/VBox/Runtime/testcase/tstRTCoreDump.cpp
index d4942358b..dd5b2ddf9 100644
--- a/src/VBox/Runtime/testcase/tstRTCoreDump.cpp
+++ b/src/VBox/Runtime/testcase/tstRTCoreDump.cpp
@@ -1,10 +1,10 @@
-/* $Id: tstRTCoreDump.cpp $ */
+/* $Id: tstRTCoreDump.cpp 37631 2011-06-24 13:25:07Z vboxsync $ */
/** @file
* IPRT Testcase - Core Dumper.
*/
/*
- * 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;
@@ -27,80 +27,72 @@
/*******************************************************************************
* Header Files *
*******************************************************************************/
-#include <iprt/types.h>
+#include <iprt/coredumper.h>
+
+#include <iprt/test.h>
#include <iprt/err.h>
#include <iprt/initterm.h>
#include <iprt/thread.h>
-#include <iprt/stream.h>
-#include <iprt/coredumper.h>
/*******************************************************************************
* Globals *
*******************************************************************************/
-static unsigned volatile g_cErrors = 0;
-
-static DECLCALLBACK(int) SleepyThread(RTTHREAD Thread, void *pvUser)
+static DECLCALLBACK(int) SleepyThread(RTTHREAD hThread, void *pvUser)
{
NOREF(pvUser);
- RTThreadSleep(90000000);
+ RTThreadUserWait(hThread, 90000000);
return VINF_SUCCESS;
}
int main()
{
- RTR3Init();
- RTPrintf("tstRTCoreDump: TESTING...\n");
+ RTTEST hTest;
+ RTEXITCODE rcExit = RTTestInitAndCreate("tstRTCoreDump", &hTest);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ RTTestBanner(hTest);
/*
* Setup core dumping.
*/
- int rc = RTCoreDumperSetup(NULL, RTCOREDUMPER_FLAGS_REPLACE_SYSTEM_DUMP | RTCOREDUMPER_FLAGS_LIVE_CORE);
+ int rc;
+ RTTESTI_CHECK_RC(rc = RTCoreDumperSetup(NULL, RTCOREDUMPER_FLAGS_REPLACE_SYSTEM_DUMP | RTCOREDUMPER_FLAGS_LIVE_CORE),
+ VINF_SUCCESS);
if (RT_SUCCESS(rc))
{
/*
* Spawn a few threads.
*/
RTTHREAD ahThreads[5];
- unsigned i = 0;
- for (; i < RT_ELEMENTS(ahThreads); i++)
+ unsigned i;
+ for (i = 0; i < RT_ELEMENTS(ahThreads); i++)
{
- rc = RTThreadCreate(&ahThreads[i], SleepyThread, &ahThreads[i], 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "TEST1");
- if (RT_FAILURE(rc))
- {
- RTPrintf("tstRTCoreDump: FAILURE(%d) - %d RTThreadCreate failed, rc=%Rrc\n", __LINE__, i, rc);
- g_cErrors++;
- ahThreads[i] = NIL_RTTHREAD;
- break;
- }
+ RTTESTI_CHECK_RC_BREAK(RTThreadCreate(&ahThreads[i], SleepyThread, &ahThreads[i], 0, RTTHREADTYPE_DEFAULT,
+ RTTHREADFLAGS_WAITABLE, "TEST1"),
+ VINF_SUCCESS);
}
- RTPrintf("Spawned %d threads.\n", i);
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "Spawned %d threads.\n", i);
/*
* Write the core to disk.
*/
- rc = RTCoreDumperTakeDump(NULL, false /* fLiveCore*/);
- if (RT_FAILURE(rc))
+ RTTESTI_CHECK_RC(RTCoreDumperTakeDump(NULL, true /* fLiveCore*/), VINF_SUCCESS);
+
+ /*
+ * Clean up.
+ */
+ RTTESTI_CHECK_RC(RTCoreDumperDisable(), VINF_SUCCESS);
+ while (i-- > 0)
{
- g_cErrors++;
- RTPrintf("RTCoreDumperTakeDump failed. rc=%Rrc\n", rc);
+ RTTESTI_CHECK_RC(RTThreadUserSignal(ahThreads[i]), VINF_SUCCESS);
+ RTTESTI_CHECK_RC(RTThreadWait(ahThreads[i], 60*1000, NULL), VINF_SUCCESS);
}
- RTCoreDumperDisable();
- }
- else
- {
- g_cErrors++;
- RTPrintf("RTCoreDumperSetup failed. rc=%Rrc\n", rc);
}
/*
* Summary.
*/
- if (!g_cErrors)
- RTPrintf("tstRTCoreDump: SUCCESS\n");
- else
- RTPrintf("tstRTCoreDump: FAILURE - %d errors\n", g_cErrors);
-
- return !!g_cErrors;
+ return RTTestSummaryAndDestroy(hTest);
}
diff --git a/src/VBox/Runtime/testcase/tstRTCoreDump.h b/src/VBox/Runtime/testcase/tstRTCoreDump.h
index 524db6628..9220a0873 100644
--- a/src/VBox/Runtime/testcase/tstRTCoreDump.h
+++ b/src/VBox/Runtime/testcase/tstRTCoreDump.h
@@ -1,4 +1,4 @@
-/* $Id: tstRTCoreDump.h $ */
+/* $Id: tstRTCoreDump.h 31796 2010-08-19 16:18:42Z vboxsync $ */
/** @file
* IPRT Testcase - Core dump, header.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTCritSect.cpp b/src/VBox/Runtime/testcase/tstRTCritSect.cpp
index b6ae874a0..697fa8f81 100644
--- a/src/VBox/Runtime/testcase/tstRTCritSect.cpp
+++ b/src/VBox/Runtime/testcase/tstRTCritSect.cpp
@@ -1,10 +1,10 @@
-/* $Id: tstRTCritSect.cpp $ */
+/* $Id: tstRTCritSect.cpp 36492 2011-04-01 12:53:59Z vboxsync $ */
/** @file
* IPRT Testcase - Critical Sections.
*/
/*
- * Copyright (C) 2006-2009 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;
@@ -30,6 +30,7 @@
#ifdef TRY_WIN32_CRIT
# include <Windows.h>
#endif
+#define RTCRITSECT_WITHOUT_REMAPPING
#include <iprt/critsect.h>
#include <iprt/asm.h>
@@ -58,14 +59,12 @@
#define PRTCRITSECT LPCRITICAL_SECTION
#define LOCKERS(sect) (*(LONG volatile *)&(sect).LockCount)
-#undef RTCritSectInit
DECLINLINE(int) RTCritSectInit(PCRITICAL_SECTION pCritSect)
{
InitializeCriticalSection(pCritSect);
return VINF_SUCCESS;
}
-#undef RTCritSectEnter
DECLINLINE(int) RTCritSectEnter(PCRITICAL_SECTION pCritSect)
{
EnterCriticalSection(pCritSect);
diff --git a/src/VBox/Runtime/testcase/tstRTDarwinMachKernel.cpp b/src/VBox/Runtime/testcase/tstRTDarwinMachKernel.cpp
index 789578023..aee8ee7d0 100644
--- a/src/VBox/Runtime/testcase/tstRTDarwinMachKernel.cpp
+++ b/src/VBox/Runtime/testcase/tstRTDarwinMachKernel.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTDarwinMachKernel.cpp $ */
+/* $Id: tstRTDarwinMachKernel.cpp 37573 2011-06-21 11:40:11Z vboxsync $ */
/** @file
* IPRT Testcase - mach_kernel symbol resolving hack.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTDigest.cpp b/src/VBox/Runtime/testcase/tstRTDigest.cpp
index 4be63c1ea..ecad8301d 100644
--- a/src/VBox/Runtime/testcase/tstRTDigest.cpp
+++ b/src/VBox/Runtime/testcase/tstRTDigest.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTDigest.cpp $ */
+/* $Id: tstRTDigest.cpp 33806 2010-11-05 17:20:15Z vboxsync $ */
/** @file
* IPRT Testcase - RTSha*, RTMd5, RTCrc*.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTDirCreateUniqueNumbered.cpp b/src/VBox/Runtime/testcase/tstRTDirCreateUniqueNumbered.cpp
new file mode 100644
index 000000000..0b723d6eb
--- /dev/null
+++ b/src/VBox/Runtime/testcase/tstRTDirCreateUniqueNumbered.cpp
@@ -0,0 +1,129 @@
+/* $Id: tstRTDirCreateUniqueNumbered.cpp 36577 2011-04-06 13:35:17Z vboxsync $ */
+/** @file
+ * IPRT Testcase - Unique directory creation.
+ */
+
+/*
+ * 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.
+ *
+ * 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/dir.h>
+
+#include <iprt/path.h>
+#include <iprt/mem.h>
+#include <iprt/string.h>
+#include <iprt/test.h>
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+static char g_szTempPath[RTPATH_MAX - 50];
+
+
+static void tst1(size_t cTest, size_t cchDigits, char chSep)
+{
+ RTTestISubF("tst #%u (digits: %u; sep: %c)", cTest, cchDigits, chSep ? chSep : ' ');
+
+ /* We try to create max possible + one. */
+ size_t cTimes = 1;
+ for (size_t i = 0; i < cchDigits; ++i)
+ cTimes *= 10;
+
+ /* Allocate the result array. */
+ char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *));
+ RTTESTI_CHECK_RETV(papszNames != NULL);
+
+ int rc;
+ /* The test loop. */
+ size_t i;
+ for (i = 0; i < cTimes; i++)
+ {
+ char szName[RTPATH_MAX];
+ RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), "RTDirCreateUniqueNumbered"), VINF_SUCCESS);
+ if (RT_FAILURE(rc))
+ break;
+
+ RTTESTI_CHECK_RC(rc = RTDirCreateUniqueNumbered(szName, sizeof(szName), 0700, cchDigits, chSep), VINF_SUCCESS);
+ if (RT_FAILURE(rc))
+ {
+ RTTestIFailed("RTDirCreateUniqueNumbered(%s) call #%u -> %Rrc\n", szName, i, rc);
+ break;
+ }
+
+ RTTESTI_CHECK(papszNames[i] = RTStrDup(szName));
+ if (!papszNames[i])
+ break;
+
+ RTTestIPrintf(RTTESTLVL_DEBUG, "%s\n", papszNames[i]);
+ }
+
+ /* Try to create one more, which shouldn't be possible. */
+ if (RT_SUCCESS(rc))
+ {
+ char szName[RTPATH_MAX];
+ RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), "RTDirCreateUniqueNumbered"), VINF_SUCCESS);
+ if (RT_SUCCESS(rc))
+ RTTESTI_CHECK_RC(rc = RTDirCreateUniqueNumbered(szName, sizeof(szName), 0700, cchDigits, chSep), VERR_ALREADY_EXISTS);
+ }
+
+ /* cleanup */
+ while (i-- > 0)
+ {
+ RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS);
+ RTStrFree(papszNames[i]);
+ }
+ RTMemTmpFree(papszNames);
+}
+
+
+int main()
+{
+ RTTEST hTest;
+ RTEXITCODE rcExit = RTTestInitAndCreate("tstRTDirCreateUniqueNumbered", &hTest);
+ if (rcExit)
+ return rcExit;
+ RTTestBanner(hTest);
+
+ /*
+ * Get the temp directory (this is essential to the testcase).
+ */
+ int rc;
+ RTTESTI_CHECK_RC(rc = RTPathTemp(g_szTempPath, sizeof(g_szTempPath)), VINF_SUCCESS);
+ if (RT_FAILURE(rc))
+ return RTTestSummaryAndDestroy(hTest);
+
+ /*
+ * Create some test directories.
+ */
+ tst1(1, 1, 0 );
+ tst1(2, 1, '-');
+ tst1(3, 2, 0 );
+ tst1(4, 2, '-');
+
+ /*
+ * Summary.
+ */
+ return RTTestSummaryAndDestroy(hTest);
+}
+
diff --git a/src/VBox/Runtime/testcase/tstRTDvm.cpp b/src/VBox/Runtime/testcase/tstRTDvm.cpp
new file mode 100644
index 000000000..ecfa2fa71
--- /dev/null
+++ b/src/VBox/Runtime/testcase/tstRTDvm.cpp
@@ -0,0 +1,221 @@
+/* $Id: tstRTDvm.cpp 37270 2011-05-30 21:25:42Z vboxsync $ */
+/** @file
+ * IPRT Testcase - IPRT Disk Volume Management (DVM)
+ */
+
+/*
+ * Copyright (C) 2009 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/initterm.h>
+#include <iprt/err.h>
+#include <iprt/test.h>
+#include <iprt/dvm.h>
+#include <iprt/file.h>
+#include <iprt/string.h>
+
+/**
+ * Disk structure.
+ */
+typedef struct TSTRTDVMDISK
+{
+ /** Flag whether this disk uses the image file or a volume. */
+ bool fUseImage;
+ /** Data dependent on the flag. */
+ union
+ {
+ /** File handle of the image. */
+ RTFILE hImage;
+ /** Handle of the volume. */
+ RTDVMVOLUME hVol;
+ };
+} TSTRTDVMDISK, *PTSTRTDVMDISK;
+
+static int dvmDiskRead(void *pvUser, uint64_t off, void *pvBuf, size_t cbRead)
+{
+ PTSTRTDVMDISK pDisk = (PTSTRTDVMDISK)pvUser;
+
+ if (pDisk->fUseImage)
+ return RTFileReadAt(pDisk->hImage, off, pvBuf, cbRead, NULL);
+ else
+ return RTDvmVolumeRead(pDisk->hVol, off, pvBuf, cbRead);
+}
+
+static int dvmDiskWrite(void *pvUser, uint64_t off, const void *pvBuf, size_t cbWrite)
+{
+ PTSTRTDVMDISK pDisk = (PTSTRTDVMDISK)pvUser;
+
+ if (pDisk->fUseImage)
+ return RTFileWriteAt(pDisk->hImage, off, pvBuf, cbWrite, NULL);
+ else
+ return RTDvmVolumeWrite(pDisk->hVol, off, pvBuf, cbWrite);
+}
+
+static int tstRTDvmVolume(RTTEST hTest, PTSTRTDVMDISK pDisk, uint64_t cb, unsigned cNesting)
+{
+ char szPrefix[100];
+ int rc = VINF_SUCCESS;
+
+ memset(szPrefix, 0, sizeof(szPrefix));
+
+ if (cNesting < sizeof(szPrefix) - 1)
+ {
+ for (unsigned i = 0; i < cNesting; i++)
+ szPrefix[i] = '\t';
+ }
+
+ RTTestSubF(hTest, "Create DVM");
+ RTDVM hVolMgr;
+ rc = RTDvmCreate(&hVolMgr, dvmDiskRead, dvmDiskWrite, cb, 512, pDisk);
+ if (RT_FAILURE(rc))
+ {
+ RTTestIFailed("RTDvmCreate -> %Rrc", rc);
+ return RTTestSummaryAndDestroy(hTest);
+ }
+
+ RTTestSubF(hTest, "Open volume map");
+ rc = RTDvmMapOpen(hVolMgr);
+ if ( RT_FAILURE(rc)
+ && rc != VERR_NOT_SUPPORTED)
+ {
+ RTTestIFailed("RTDvmOpen -> %Rrc", rc);
+ return RTTestSummaryAndDestroy(hTest);
+ }
+ else if (rc == VERR_NOT_SUPPORTED)
+ return VINF_SUCCESS;
+
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Successfully opened map with format: %s.\n", szPrefix, RTDvmMapGetFormat(hVolMgr));
+
+ /* Dump all volumes. */
+ RTTestSubF(hTest, "Dump volumes");
+ uint32_t cVolume = 0;
+ RTDVMVOLUME hVol;
+
+ rc = RTDvmMapQueryFirstVolume(hVolMgr, &hVol);
+
+ while (RT_SUCCESS(rc))
+ {
+ char *pszVolName = NULL;
+ RTDVMVOLTYPE enmVolType = RTDvmVolumeGetType(hVol);
+ uint64_t fVolFlags = RTDvmVolumeGetFlags(hVol);
+
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume %u:\n", szPrefix, cVolume);
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume type %s\n", szPrefix, RTDvmVolumeTypeGetDescr(enmVolType));
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume size %llu\n", szPrefix, RTDvmVolumeGetSize(hVol));
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume flags %s %s\n\n", szPrefix,
+ fVolFlags & DVMVOLUME_FLAGS_BOOTABLE ? "Bootable" : "",
+ fVolFlags & DVMVOLUME_FLAGS_ACTIVE ? "Active" : "");
+
+ rc = RTDvmVolumeQueryName(hVol, &pszVolName);
+ if (RT_SUCCESS(rc))
+ {
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume name %s.\n", szPrefix, pszVolName);
+ RTStrFree(pszVolName);
+ }
+ else if (rc != VERR_NOT_SUPPORTED)
+ RTTestIFailed("RTDvmVolumeQueryName -> %Rrc", rc);
+ else
+ rc = VINF_SUCCESS;
+
+ /*
+ * Query all volumes which might be inside this.
+ * (think of MBR partitions with a bsdlabel inside)
+ */
+ TSTRTDVMDISK Disk;
+ Disk.fUseImage = false;
+ Disk.hVol = hVol;
+ rc = tstRTDvmVolume(hTest, &Disk, RTDvmVolumeGetSize(hVol), cNesting + 1);
+
+ RTDVMVOLUME hVolNext;
+ rc = RTDvmMapQueryNextVolume(hVolMgr, hVol, &hVolNext);
+ RTDvmVolumeRelease(hVol);
+ hVol = hVolNext;
+ cVolume++;
+ }
+
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Dumped %u volumes\n", szPrefix, cVolume);
+
+ if ( rc == VERR_DVM_MAP_EMPTY
+ || rc == VERR_DVM_MAP_NO_VOLUME)
+ rc = VINF_SUCCESS;
+
+ RTTESTI_CHECK(rc == VINF_SUCCESS);
+
+ RTDvmRelease(hVolMgr);
+
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ /*
+ * Initialize IPRT and create the test.
+ */
+ RTTEST hTest;
+ int rc = RTTestInitAndCreate("tstRTDvm", &hTest);
+ if (rc)
+ return rc;
+ RTTestBanner(hTest);
+
+ /*
+ * If no args, display usage.
+ */
+ if (argc < 2)
+ {
+ RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "Syntax: %s <image>\n", argv[0]);
+ return RTTestSkipAndDestroy(hTest, "Missing required arguments\n");
+ }
+
+ /* Open image. */
+ RTFILE hFile;
+ uint64_t cb = 0;
+ rc = RTFileOpen(&hFile, argv[1], RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READWRITE);
+ if (RT_FAILURE(rc))
+ {
+ RTTestIFailed("RTFileOpen -> %Rrc", rc);
+ return RTTestSummaryAndDestroy(hTest);
+ }
+
+ rc = RTFileGetSize(hFile, &cb);
+ if ( RT_FAILURE(rc)
+ || cb % 512 != 0) /* Assume 512 byte sector size. */
+ {
+ RTTestIFailed("RTFileGetSize -> %Rrc", rc);
+ return RTTestSummaryAndDestroy(hTest);
+ }
+
+ TSTRTDVMDISK Disk;
+
+ Disk.fUseImage = true;
+ Disk.hImage = hFile;
+ rc = tstRTDvmVolume(hTest, &Disk, cb, 0);
+
+ RTTESTI_CHECK(rc == VINF_SUCCESS);
+
+ /*
+ * Summary
+ */
+ return RTTestSummaryAndDestroy(hTest);
+}
+
diff --git a/src/VBox/Runtime/testcase/tstRTFileAio.cpp b/src/VBox/Runtime/testcase/tstRTFileAio.cpp
index b164083f2..9e3da3d83 100644
--- a/src/VBox/Runtime/testcase/tstRTFileAio.cpp
+++ b/src/VBox/Runtime/testcase/tstRTFileAio.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTFileAio.cpp $ */
+/* $Id: tstRTFileAio.cpp 29393 2010-05-12 00:20:38Z vboxsync $ */
/** @file
* IPRT Testcase - File Async I/O.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTFileAppend-1.cpp b/src/VBox/Runtime/testcase/tstRTFileAppend-1.cpp
index c18940b3a..d9a977eb4 100644
--- a/src/VBox/Runtime/testcase/tstRTFileAppend-1.cpp
+++ b/src/VBox/Runtime/testcase/tstRTFileAppend-1.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTFileAppend-1.cpp $ */
+/* $Id: tstRTFileAppend-1.cpp 29393 2010-05-12 00:20:38Z vboxsync $ */
/** @file
* IPRT Testcase - File Appending.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTFsQueries.cpp b/src/VBox/Runtime/testcase/tstRTFsQueries.cpp
index 42320d797..276a5464d 100644
--- a/src/VBox/Runtime/testcase/tstRTFsQueries.cpp
+++ b/src/VBox/Runtime/testcase/tstRTFsQueries.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTFsQueries.cpp $ */
+/* $Id: tstRTFsQueries.cpp 30365 2010-06-22 12:08:20Z vboxsync $ */
/** @file
* IPRT Testcase - RTFs Queries..
*/
diff --git a/src/VBox/Runtime/testcase/tstRTGetOpt.cpp b/src/VBox/Runtime/testcase/tstRTGetOpt.cpp
index 9505f80e3..07a249027 100644
--- a/src/VBox/Runtime/testcase/tstRTGetOpt.cpp
+++ b/src/VBox/Runtime/testcase/tstRTGetOpt.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTGetOpt.cpp $ */
+/* $Id: tstRTGetOpt.cpp 34542 2010-11-30 22:57:21Z vboxsync $ */
/** @file
* IPRT Testcase - RTGetOpt
*/
diff --git a/src/VBox/Runtime/testcase/tstRTGetOptArgv.cpp b/src/VBox/Runtime/testcase/tstRTGetOptArgv.cpp
index 27c067683..baaab0318 100644
--- a/src/VBox/Runtime/testcase/tstRTGetOptArgv.cpp
+++ b/src/VBox/Runtime/testcase/tstRTGetOptArgv.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTGetOptArgv.cpp $ */
+/* $Id: tstRTGetOptArgv.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - RTGetOptArgv*.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTHeapOffset.cpp b/src/VBox/Runtime/testcase/tstRTHeapOffset.cpp
index 467619a2a..d017f5c27 100644
--- a/src/VBox/Runtime/testcase/tstRTHeapOffset.cpp
+++ b/src/VBox/Runtime/testcase/tstRTHeapOffset.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTHeapOffset.cpp $ */
+/* $Id: tstRTHeapOffset.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Offset Based Heap.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTHeapSimple.cpp b/src/VBox/Runtime/testcase/tstRTHeapSimple.cpp
index ef763466f..7921a1482 100644
--- a/src/VBox/Runtime/testcase/tstRTHeapSimple.cpp
+++ b/src/VBox/Runtime/testcase/tstRTHeapSimple.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTHeapSimple.cpp $ */
+/* $Id: tstRTHeapSimple.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Simple Heap.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp b/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp
index 925b23b51..87287ec6d 100644
--- a/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp
+++ b/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTInlineAsm.cpp $ */
+/* $Id: tstRTInlineAsm.cpp 33207 2010-10-18 15:02:47Z vboxsync $ */
/** @file
* IPRT Testcase - inline assembly.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTList.cpp b/src/VBox/Runtime/testcase/tstRTList.cpp
index fdbba25da..4306f3018 100644
--- a/src/VBox/Runtime/testcase/tstRTList.cpp
+++ b/src/VBox/Runtime/testcase/tstRTList.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTList.cpp $ */
+/* $Id: tstRTList.cpp 34406 2010-11-26 16:45:34Z vboxsync $ */
/** @file
* IPRT Testcase - List interface.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTLockValidator.cpp b/src/VBox/Runtime/testcase/tstRTLockValidator.cpp
index 575a97fa6..b295d7922 100644
--- a/src/VBox/Runtime/testcase/tstRTLockValidator.cpp
+++ b/src/VBox/Runtime/testcase/tstRTLockValidator.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTLockValidator.cpp $ */
+/* $Id: tstRTLockValidator.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT Testcase - RTLockValidator.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTManifest.cpp b/src/VBox/Runtime/testcase/tstRTManifest.cpp
index 629815d8d..61d3cf143 100644
--- a/src/VBox/Runtime/testcase/tstRTManifest.cpp
+++ b/src/VBox/Runtime/testcase/tstRTManifest.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTManifest.cpp $ */
+/* $Id: tstRTManifest.cpp 34464 2010-11-29 13:45:37Z vboxsync $ */
/** @file
* IPRT Testcase - Manifest files.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTMemCache.cpp b/src/VBox/Runtime/testcase/tstRTMemCache.cpp
index 73c481460..2b4499788 100644
--- a/src/VBox/Runtime/testcase/tstRTMemCache.cpp
+++ b/src/VBox/Runtime/testcase/tstRTMemCache.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTMemCache.cpp $ */
+/* $Id: tstRTMemCache.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - RTMemCache.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTMemEf.cpp b/src/VBox/Runtime/testcase/tstRTMemEf.cpp
index e4761dd0c..ca73b1f9f 100644
--- a/src/VBox/Runtime/testcase/tstRTMemEf.cpp
+++ b/src/VBox/Runtime/testcase/tstRTMemEf.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTMemEf.cpp $ */
+/* $Id: tstRTMemEf.cpp 36580 2011-04-06 13:52:10Z vboxsync $ */
/** @file
* IPRT - Testcase for the RTMemEf* functions.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTMemPool.cpp b/src/VBox/Runtime/testcase/tstRTMemPool.cpp
index 2956eb0f4..c04f734c5 100644
--- a/src/VBox/Runtime/testcase/tstRTMemPool.cpp
+++ b/src/VBox/Runtime/testcase/tstRTMemPool.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTMemPool.cpp $ */
+/* $Id: tstRTMemPool.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT Testcase - MemPool.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTPath.cpp b/src/VBox/Runtime/testcase/tstRTPath.cpp
index 06009aa75..b91555bbd 100644
--- a/src/VBox/Runtime/testcase/tstRTPath.cpp
+++ b/src/VBox/Runtime/testcase/tstRTPath.cpp
@@ -1,10 +1,10 @@
-/* $Id: tstRTPath.cpp $ */
+/* $Id: tstRTPath.cpp 36881 2011-04-29 09:17:05Z vboxsync $ */
/** @file
* IPRT Testcase - Test various path functions.
*/
/*
- * 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;
@@ -55,7 +55,7 @@ int main()
* RTPathExecDir, RTPathUserHome and RTProcGetExecutablePath.
*/
RTTestSub(hTest, "RTPathExecDir");
- RTTESTI_CHECK_RC(RTPathExecDir(szPath, sizeof(szPath)), VINF_SUCCESS);
+ RTTESTI_CHECK_RC(rc = RTPathExecDir(szPath, sizeof(szPath)), VINF_SUCCESS);
if (RT_SUCCESS(rc))
RTTestIPrintf(RTTESTLVL_INFO, "ExecDir={%s}\n", szPath);
@@ -66,12 +66,17 @@ int main()
RTTestIFailed("RTProcGetExecutablePath -> NULL");
RTTestSub(hTest, "RTPathUserHome");
- RTTESTI_CHECK_RC(RTPathUserHome(szPath, sizeof(szPath)), VINF_SUCCESS);
+ RTTESTI_CHECK_RC(rc = RTPathUserHome(szPath, sizeof(szPath)), VINF_SUCCESS);
if (RT_SUCCESS(rc))
RTTestIPrintf(RTTESTLVL_INFO, "UserHome={%s}\n", szPath);
+ RTTestSub(hTest, "RTPathUserDocuments");
+ RTTESTI_CHECK_RC(rc = RTPathUserDocuments(szPath, sizeof(szPath)), VINF_SUCCESS);
+ if (RT_SUCCESS(rc))
+ RTTestIPrintf(RTTESTLVL_INFO, "UserDocuments={%s}\n", szPath);
+
RTTestSub(hTest, "RTPathTemp");
- RTTESTI_CHECK_RC(RTPathTemp(szPath, sizeof(szPath)), VINF_SUCCESS);
+ RTTESTI_CHECK_RC(rc = RTPathTemp(szPath, sizeof(szPath)), VINF_SUCCESS);
if (RT_SUCCESS(rc))
RTTestIPrintf(RTTESTLVL_INFO, "PathTemp={%s}\n", szPath);
size_t cch = strlen(szPath);
diff --git a/src/VBox/Runtime/testcase/tstRTPipe.cpp b/src/VBox/Runtime/testcase/tstRTPipe.cpp
index dfb73685d..74862c227 100644
--- a/src/VBox/Runtime/testcase/tstRTPipe.cpp
+++ b/src/VBox/Runtime/testcase/tstRTPipe.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTPipe.cpp $ */
+/* $Id: tstRTPipe.cpp 33806 2010-11-05 17:20:15Z vboxsync $ */
/** @file
* IPRT Testcase - RTPipe.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTPoll.cpp b/src/VBox/Runtime/testcase/tstRTPoll.cpp
index 8e14c23d7..9b9e09d93 100644
--- a/src/VBox/Runtime/testcase/tstRTPoll.cpp
+++ b/src/VBox/Runtime/testcase/tstRTPoll.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTPoll.cpp $ */
+/* $Id: tstRTPoll.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - RTPoll.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTPrfIO.cpp b/src/VBox/Runtime/testcase/tstRTPrfIO.cpp
index 7b2bfe11d..9c3a516d8 100644
--- a/src/VBox/Runtime/testcase/tstRTPrfIO.cpp
+++ b/src/VBox/Runtime/testcase/tstRTPrfIO.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTPrfIO.cpp $ */
+/* $Id: tstRTPrfIO.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT Testcase - Profile IPRT I/O APIs.
*/
@@ -210,7 +210,7 @@ int main(int argc, char **argv)
break;
case 'V':
- RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "$Revision: 67140 $\n");
+ RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "$Revision: 33540 $\n");
return RTTestSummaryAndDestroy(g_hTest);
case 'h':
diff --git a/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp b/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp
index 0e3019ac4..ef0a8c008 100644
--- a/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp
+++ b/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTProcCreateEx.cpp $ */
+/* $Id: tstRTProcCreateEx.cpp 33806 2010-11-05 17:20:15Z vboxsync $ */
/** @file
* IPRT Testcase - RTProcCreateEx.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTProcIsRunningByName.cpp b/src/VBox/Runtime/testcase/tstRTProcIsRunningByName.cpp
index 578985eae..a872808ce 100644
--- a/src/VBox/Runtime/testcase/tstRTProcIsRunningByName.cpp
+++ b/src/VBox/Runtime/testcase/tstRTProcIsRunningByName.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTProcIsRunningByName.cpp $ */
+/* $Id: tstRTProcIsRunningByName.cpp 33806 2010-11-05 17:20:15Z vboxsync $ */
/** @file
* IPRT Testcase - RTProcIsRunningByName
*/
diff --git a/src/VBox/Runtime/testcase/tstRTProcWait.cpp b/src/VBox/Runtime/testcase/tstRTProcWait.cpp
index 210988a8d..6217521e9 100644
--- a/src/VBox/Runtime/testcase/tstRTProcWait.cpp
+++ b/src/VBox/Runtime/testcase/tstRTProcWait.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTProcWait.cpp $ */
+/* $Id: tstRTProcWait.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - RTProcWait.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTR0Common.h b/src/VBox/Runtime/testcase/tstRTR0Common.h
index 196e5f9de..2b246e466 100644
--- a/src/VBox/Runtime/testcase/tstRTR0Common.h
+++ b/src/VBox/Runtime/testcase/tstRTR0Common.h
@@ -1,4 +1,4 @@
-/* $Id: tstRTR0Common.h $ */
+/* $Id: tstRTR0Common.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Common header.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTR0CommonDriver.h b/src/VBox/Runtime/testcase/tstRTR0CommonDriver.h
index b381383c6..1bacfba26 100644
--- a/src/VBox/Runtime/testcase/tstRTR0CommonDriver.h
+++ b/src/VBox/Runtime/testcase/tstRTR0CommonDriver.h
@@ -1,4 +1,4 @@
-/* $Id: tstRTR0CommonDriver.h $ */
+/* $Id: tstRTR0CommonDriver.h 32736 2010-09-23 16:19:46Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Common header for the testcase drivers.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTR0CommonReq.h b/src/VBox/Runtime/testcase/tstRTR0CommonReq.h
index b32e174d2..54924d79b 100644
--- a/src/VBox/Runtime/testcase/tstRTR0CommonReq.h
+++ b/src/VBox/Runtime/testcase/tstRTR0CommonReq.h
@@ -1,4 +1,4 @@
-/* $Id: tstRTR0CommonReq.h $ */
+/* $Id: tstRTR0CommonReq.h 32648 2010-09-20 16:17:03Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Common header defining the request packet.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.cpp b/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.cpp
index 4fc007651..4f504b6b3 100644
--- a/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.cpp
+++ b/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTR0MemUserKernel.cpp $ */
+/* $Id: tstRTR0MemUserKernel.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Thread Preemption.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.h b/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.h
index 7efbeed55..f1d09aba0 100644
--- a/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.h
+++ b/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.h
@@ -1,4 +1,4 @@
-/* $Id: tstRTR0MemUserKernel.h $ */
+/* $Id: tstRTR0MemUserKernel.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT R0 Testcase - User & Kernel Memory, common header.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTR0MemUserKernelDriver.cpp b/src/VBox/Runtime/testcase/tstRTR0MemUserKernelDriver.cpp
index dddcb775c..3f5e9de6d 100644
--- a/src/VBox/Runtime/testcase/tstRTR0MemUserKernelDriver.cpp
+++ b/src/VBox/Runtime/testcase/tstRTR0MemUserKernelDriver.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTR0MemUserKernelDriver.cpp $ */
+/* $Id: tstRTR0MemUserKernelDriver.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Thread Preemption, driver program.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp b/src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp
index 944180755..26368f9eb 100644
--- a/src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp
+++ b/src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTR0SemMutex.cpp $ */
+/* $Id: tstRTR0SemMutex.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Mutex Semaphores.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTR0SemMutex.h b/src/VBox/Runtime/testcase/tstRTR0SemMutex.h
index ee5cf4d5e..020383c60 100644
--- a/src/VBox/Runtime/testcase/tstRTR0SemMutex.h
+++ b/src/VBox/Runtime/testcase/tstRTR0SemMutex.h
@@ -1,4 +1,4 @@
-/* $Id: tstRTR0SemMutex.h $ */
+/* $Id: tstRTR0SemMutex.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Mutex Semaphores, common header.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp b/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp
index 6ac25ff1f..10c5054d3 100644
--- a/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp
+++ b/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTR0SemMutexDriver.cpp $ */
+/* $Id: tstRTR0SemMutexDriver.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Thread Preemption, driver program.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTR0Timer.cpp b/src/VBox/Runtime/testcase/tstRTR0Timer.cpp
index 4700ad5a7..21992a5ea 100644
--- a/src/VBox/Runtime/testcase/tstRTR0Timer.cpp
+++ b/src/VBox/Runtime/testcase/tstRTR0Timer.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTR0Timer.cpp $ */
+/* $Id: tstRTR0Timer.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Timers.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTR0Timer.h b/src/VBox/Runtime/testcase/tstRTR0Timer.h
index 8699490f0..5ecddd4cf 100644
--- a/src/VBox/Runtime/testcase/tstRTR0Timer.h
+++ b/src/VBox/Runtime/testcase/tstRTR0Timer.h
@@ -1,4 +1,4 @@
-/* $Id: tstRTR0Timer.h $ */
+/* $Id: tstRTR0Timer.h 32736 2010-09-23 16:19:46Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Timers, common header.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTR0TimerDriver.cpp b/src/VBox/Runtime/testcase/tstRTR0TimerDriver.cpp
index 8b34cbd1a..f0d190f8c 100644
--- a/src/VBox/Runtime/testcase/tstRTR0TimerDriver.cpp
+++ b/src/VBox/Runtime/testcase/tstRTR0TimerDriver.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTR0TimerDriver.cpp $ */
+/* $Id: tstRTR0TimerDriver.cpp 32753 2010-09-24 09:57:49Z vboxsync $ */
/** @file
* IPRT R0 Testcase - Timers, driver program.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTS3.cpp b/src/VBox/Runtime/testcase/tstRTS3.cpp
index 6dda00540..a5456df1b 100644
--- a/src/VBox/Runtime/testcase/tstRTS3.cpp
+++ b/src/VBox/Runtime/testcase/tstRTS3.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTS3.cpp $ */
+/* $Id: tstRTS3.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Simple Storage Service (S3) Communication API
*/
diff --git a/src/VBox/Runtime/testcase/tstRTSemEventMulti.cpp b/src/VBox/Runtime/testcase/tstRTSemEventMulti.cpp
index 3857a4c3e..598ae803b 100644
--- a/src/VBox/Runtime/testcase/tstRTSemEventMulti.cpp
+++ b/src/VBox/Runtime/testcase/tstRTSemEventMulti.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTSemEventMulti.cpp $ */
+/* $Id: tstRTSemEventMulti.cpp 32970 2010-10-07 10:08:00Z vboxsync $ */
/** @file
* IPRT Testcase - Multiple Release Event Semaphores.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTSemRW.cpp b/src/VBox/Runtime/testcase/tstRTSemRW.cpp
index 06575bce2..7032f240b 100644
--- a/src/VBox/Runtime/testcase/tstRTSemRW.cpp
+++ b/src/VBox/Runtime/testcase/tstRTSemRW.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTSemRW.cpp $ */
+/* $Id: tstRTSemRW.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Reader/Writer Semaphore.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTSemXRoads.cpp b/src/VBox/Runtime/testcase/tstRTSemXRoads.cpp
index 86169536c..30aea892f 100644
--- a/src/VBox/Runtime/testcase/tstRTSemXRoads.cpp
+++ b/src/VBox/Runtime/testcase/tstRTSemXRoads.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTSemXRoads.cpp $ */
+/* $Id: tstRTSemXRoads.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - RTSemXRoads.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTSort.cpp b/src/VBox/Runtime/testcase/tstRTSort.cpp
index 0bc0e8371..dff8aec79 100644
--- a/src/VBox/Runtime/testcase/tstRTSort.cpp
+++ b/src/VBox/Runtime/testcase/tstRTSort.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTSort.cpp $ */
+/* $Id: tstRTSort.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Sorting.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTStrAlloc.cpp b/src/VBox/Runtime/testcase/tstRTStrAlloc.cpp
index 6f49cb0eb..2ebcef989 100644
--- a/src/VBox/Runtime/testcase/tstRTStrAlloc.cpp
+++ b/src/VBox/Runtime/testcase/tstRTStrAlloc.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTStrAlloc.cpp $ */
+/* $Id: tstRTStrAlloc.cpp 33285 2010-10-21 09:41:51Z vboxsync $ */
/** @file
* IPRT Testcase - String allocation APIs and related manipulators.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTStrCache.cpp b/src/VBox/Runtime/testcase/tstRTStrCache.cpp
index ef466554b..6078eb90b 100644
--- a/src/VBox/Runtime/testcase/tstRTStrCache.cpp
+++ b/src/VBox/Runtime/testcase/tstRTStrCache.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTStrCache.cpp $ */
+/* $Id: tstRTStrCache.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - StrCache.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTStrCatCopy.cpp b/src/VBox/Runtime/testcase/tstRTStrCatCopy.cpp
index 36ab67683..3b1f09e8d 100644
--- a/src/VBox/Runtime/testcase/tstRTStrCatCopy.cpp
+++ b/src/VBox/Runtime/testcase/tstRTStrCatCopy.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTStrCatCopy.cpp $ */
+/* $Id: tstRTStrCatCopy.cpp 33678 2010-11-02 10:30:46Z vboxsync $ */
/** @file
* IPRT Testcase - String Concatenation and Copy.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTStrFormat.cpp b/src/VBox/Runtime/testcase/tstRTStrFormat.cpp
index ae67d8c06..37bb36976 100644
--- a/src/VBox/Runtime/testcase/tstRTStrFormat.cpp
+++ b/src/VBox/Runtime/testcase/tstRTStrFormat.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTStrFormat.cpp $ */
+/* $Id: tstRTStrFormat.cpp 37966 2011-07-14 13:39:15Z vboxsync $ */
/** @file
* IPRT Testcase - String formatting.
*/
@@ -589,6 +589,17 @@ int main()
CHECKSTR(pszBuf2);
/*
+ * x86 register formatting.
+ */
+ RTTestSub(hTest, "x86 register format types (%RAx86[*])");
+ CHECK42("%RAx86[cr0]", UINT64_C(0x80000011), "80000011{PE,ET,PG}");
+ CHECK42("%RAx86[cr0]", UINT64_C(0x80000001), "80000001{PE,PG}");
+ CHECK42("%RAx86[cr0]", UINT64_C(0x00000001), "00000001{PE}");
+ CHECK42("%RAx86[cr0]", UINT64_C(0x80000000), "80000000{PG}");
+ CHECK42("%RAx86[cr4]", UINT64_C(0x80000001), "80000001{VME,unkn=80000000}");
+ CHECK42("%#RAx86[cr4]", UINT64_C(0x80000001), "0x80000001{VME,unkn=0x80000000}");
+
+ /*
* Custom types.
*/
RTTestSub(hTest, "Custom format types (%R[*])");
diff --git a/src/VBox/Runtime/testcase/tstRTStrVersion.cpp b/src/VBox/Runtime/testcase/tstRTStrVersion.cpp
index 6f7ee8209..fe85f0c5f 100644
--- a/src/VBox/Runtime/testcase/tstRTStrVersion.cpp
+++ b/src/VBox/Runtime/testcase/tstRTStrVersion.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTStrVersion.cpp $ */
+/* $Id: tstRTStrVersion.cpp 37016 2011-05-09 17:48:43Z vboxsync $ */
/** @file
* IPRT Testcase - Version String Comparison.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTSymlink.cpp b/src/VBox/Runtime/testcase/tstRTSymlink.cpp
index 007db683a..c284f368e 100644
--- a/src/VBox/Runtime/testcase/tstRTSymlink.cpp
+++ b/src/VBox/Runtime/testcase/tstRTSymlink.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTSymlink.cpp $ */
+/* $Id: tstRTSymlink.cpp 33806 2010-11-05 17:20:15Z vboxsync $ */
/** @file
* IPRT Testcase - Symbolic Links.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTSystemQueryDmi.cpp b/src/VBox/Runtime/testcase/tstRTSystemQueryDmi.cpp
index a92b22ba1..7e23ec58a 100644
--- a/src/VBox/Runtime/testcase/tstRTSystemQueryDmi.cpp
+++ b/src/VBox/Runtime/testcase/tstRTSystemQueryDmi.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTSystemQueryDmi.cpp $ */
+/* $Id: tstRTSystemQueryDmi.cpp 30320 2010-06-21 08:35:09Z vboxsync $ */
/** @file
* IPRT Testcase - RTSystemQueryDmi*.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTSystemQueryOsInfo.cpp b/src/VBox/Runtime/testcase/tstRTSystemQueryOsInfo.cpp
index d2febda33..ec22f4095 100644
--- a/src/VBox/Runtime/testcase/tstRTSystemQueryOsInfo.cpp
+++ b/src/VBox/Runtime/testcase/tstRTSystemQueryOsInfo.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTSystemQueryOsInfo.cpp $ */
+/* $Id: tstRTSystemQueryOsInfo.cpp 30320 2010-06-21 08:35:09Z vboxsync $ */
/** @file
* IPRT Testcase - RTSystemQueryOSInfo.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTTemp.cpp b/src/VBox/Runtime/testcase/tstRTTemp.cpp
index 1b3b31a1d..c3d107296 100644
--- a/src/VBox/Runtime/testcase/tstRTTemp.cpp
+++ b/src/VBox/Runtime/testcase/tstRTTemp.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTTemp.cpp $ */
+/* $Id: tstRTTemp.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Temporary files and directories.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTThreadExecutionTime.cpp b/src/VBox/Runtime/testcase/tstRTThreadExecutionTime.cpp
index 4050791c9..b5a814c53 100644
--- a/src/VBox/Runtime/testcase/tstRTThreadExecutionTime.cpp
+++ b/src/VBox/Runtime/testcase/tstRTThreadExecutionTime.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTThreadExecutionTime.cpp $ */
+/* $Id: tstRTThreadExecutionTime.cpp 34629 2010-12-02 17:09:09Z vboxsync $ */
/** @file
* IPRT Testcase - RTThreadGetExecution.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTThreadPoke.cpp b/src/VBox/Runtime/testcase/tstRTThreadPoke.cpp
index 47588db89..2e2938e4d 100644
--- a/src/VBox/Runtime/testcase/tstRTThreadPoke.cpp
+++ b/src/VBox/Runtime/testcase/tstRTThreadPoke.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTThreadPoke.cpp $ */
+/* $Id: tstRTThreadPoke.cpp 35351 2010-12-27 17:04:17Z vboxsync $ */
/** @file
* IPRT Testcase - RTThreadPoke.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTTimeSpec.cpp b/src/VBox/Runtime/testcase/tstRTTimeSpec.cpp
index 08f5cc90b..27ce88943 100644
--- a/src/VBox/Runtime/testcase/tstRTTimeSpec.cpp
+++ b/src/VBox/Runtime/testcase/tstRTTimeSpec.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTTimeSpec.cpp $ */
+/* $Id: tstRTTimeSpec.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT - RTTimeSpec and PRTTIME tests.
*/
diff --git a/src/VBox/Runtime/testcase/tstRTUuid.cpp b/src/VBox/Runtime/testcase/tstRTUuid.cpp
index 692bcb941..10bd5ecaf 100644
--- a/src/VBox/Runtime/testcase/tstRTUuid.cpp
+++ b/src/VBox/Runtime/testcase/tstRTUuid.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRTUuid.cpp $ */
+/* $Id: tstRTUuid.cpp 32996 2010-10-08 08:12:41Z vboxsync $ */
/** @file
* IPRT Testcase - UUID.
*/
diff --git a/src/VBox/Runtime/testcase/tstRand.cpp b/src/VBox/Runtime/testcase/tstRand.cpp
index cf82e6e74..5f9277045 100644
--- a/src/VBox/Runtime/testcase/tstRand.cpp
+++ b/src/VBox/Runtime/testcase/tstRand.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRand.cpp $ */
+/* $Id: tstRand.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - Testcase for the RTRand API.
*/
diff --git a/src/VBox/Runtime/testcase/tstSemMutex.cpp b/src/VBox/Runtime/testcase/tstSemMutex.cpp
index d3b6722c7..d99c75829 100644
--- a/src/VBox/Runtime/testcase/tstSemMutex.cpp
+++ b/src/VBox/Runtime/testcase/tstSemMutex.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstSemMutex.cpp $ */
+/* $Id: tstSemMutex.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Simple Mutex Semaphore Smoke Test.
*/
diff --git a/src/VBox/Runtime/testcase/tstSemPingPong.cpp b/src/VBox/Runtime/testcase/tstSemPingPong.cpp
index c35564731..3a6032e81 100644
--- a/src/VBox/Runtime/testcase/tstSemPingPong.cpp
+++ b/src/VBox/Runtime/testcase/tstSemPingPong.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstSemPingPong.cpp $ */
+/* $Id: tstSemPingPong.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - RTSemPing/RTSemPong.
*/
diff --git a/src/VBox/Runtime/testcase/tstStrSimplePattern.cpp b/src/VBox/Runtime/testcase/tstStrSimplePattern.cpp
index f9f11cc64..8525cd9cb 100644
--- a/src/VBox/Runtime/testcase/tstStrSimplePattern.cpp
+++ b/src/VBox/Runtime/testcase/tstStrSimplePattern.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstStrSimplePattern.cpp $ */
+/* $Id: tstStrSimplePattern.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - RTStrSimplePattern.
*/
diff --git a/src/VBox/Runtime/testcase/tstStrToNum.cpp b/src/VBox/Runtime/testcase/tstStrToNum.cpp
index 4f73c7aad..4cb516a04 100644
--- a/src/VBox/Runtime/testcase/tstStrToNum.cpp
+++ b/src/VBox/Runtime/testcase/tstStrToNum.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstStrToNum.cpp $ */
+/* $Id: tstStrToNum.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - String To Number Conversion.
*/
diff --git a/src/VBox/Runtime/testcase/tstTSC.cpp b/src/VBox/Runtime/testcase/tstTSC.cpp
index eeee218a7..b9d21f04d 100644
--- a/src/VBox/Runtime/testcase/tstTSC.cpp
+++ b/src/VBox/Runtime/testcase/tstTSC.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstTSC.cpp $ */
+/* $Id: tstTSC.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* IPRT Testcase - SMP TSC testcase.
*/
diff --git a/src/VBox/Runtime/testcase/tstTermCallbacks.cpp b/src/VBox/Runtime/testcase/tstTermCallbacks.cpp
index e72e16b55..7405145a3 100644
--- a/src/VBox/Runtime/testcase/tstTermCallbacks.cpp
+++ b/src/VBox/Runtime/testcase/tstTermCallbacks.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstTermCallbacks.cpp $ */
+/* $Id: tstTermCallbacks.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Termination Callbacks.
*/
diff --git a/src/VBox/Runtime/testcase/tstThread-1.cpp b/src/VBox/Runtime/testcase/tstThread-1.cpp
index b83d2fa83..3fa81fafc 100644
--- a/src/VBox/Runtime/testcase/tstThread-1.cpp
+++ b/src/VBox/Runtime/testcase/tstThread-1.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstThread-1.cpp $ */
+/* $Id: tstThread-1.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Thread Testcase no.1.
*/
diff --git a/src/VBox/Runtime/testcase/tstTime-2.cpp b/src/VBox/Runtime/testcase/tstTime-2.cpp
index 52277e253..db46c5268 100644
--- a/src/VBox/Runtime/testcase/tstTime-2.cpp
+++ b/src/VBox/Runtime/testcase/tstTime-2.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstTime-2.cpp $ */
+/* $Id: tstTime-2.cpp 29279 2010-05-09 23:29:11Z vboxsync $ */
/** @file
* IPRT Testcase - Simple RTTime test.
*/
diff --git a/src/VBox/Runtime/testcase/tstTime-3.cpp b/src/VBox/Runtime/testcase/tstTime-3.cpp
index e5ba1e803..36936f30c 100644
--- a/src/VBox/Runtime/testcase/tstTime-3.cpp
+++ b/src/VBox/Runtime/testcase/tstTime-3.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstTime-3.cpp $ */
+/* $Id: tstTime-3.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Simple RTTime test.
*/
diff --git a/src/VBox/Runtime/testcase/tstTime-4.cpp b/src/VBox/Runtime/testcase/tstTime-4.cpp
index 06895b858..41b2857c9 100644
--- a/src/VBox/Runtime/testcase/tstTime-4.cpp
+++ b/src/VBox/Runtime/testcase/tstTime-4.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstTime-4.cpp $ */
+/* $Id: tstTime-4.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Simple RTTime vs. RTTimeSystem test.
*/
diff --git a/src/VBox/Runtime/testcase/tstTime.cpp b/src/VBox/Runtime/testcase/tstTime.cpp
index 6396e4d04..8ff537a50 100644
--- a/src/VBox/Runtime/testcase/tstTime.cpp
+++ b/src/VBox/Runtime/testcase/tstTime.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstTime.cpp $ */
+/* $Id: tstTime.cpp 29279 2010-05-09 23:29:11Z vboxsync $ */
/** @file
* IPRT Testcase - Simple RTTime tests.
*/
diff --git a/src/VBox/Runtime/testcase/tstTimer.cpp b/src/VBox/Runtime/testcase/tstTimer.cpp
index 81175de86..c2295987c 100644
--- a/src/VBox/Runtime/testcase/tstTimer.cpp
+++ b/src/VBox/Runtime/testcase/tstTimer.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstTimer.cpp $ */
+/* $Id: tstTimer.cpp 32431 2010-09-11 18:02:17Z vboxsync $ */
/** @file
* IPRT Testcase - Timers.
*/
diff --git a/src/VBox/Runtime/testcase/tstTimerLR.cpp b/src/VBox/Runtime/testcase/tstTimerLR.cpp
index e8584fb25..5afca3c54 100644
--- a/src/VBox/Runtime/testcase/tstTimerLR.cpp
+++ b/src/VBox/Runtime/testcase/tstTimerLR.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstTimerLR.cpp $ */
+/* $Id: tstTimerLR.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Testcase - Low Resolution Timers.
*/
diff --git a/src/VBox/Runtime/testcase/tstUtf8.cpp b/src/VBox/Runtime/testcase/tstUtf8.cpp
index 453115dc1..f68586002 100644
--- a/src/VBox/Runtime/testcase/tstUtf8.cpp
+++ b/src/VBox/Runtime/testcase/tstUtf8.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstUtf8.cpp $ */
+/* $Id: tstUtf8.cpp 33595 2010-10-29 10:35:00Z vboxsync $ */
/** @file
* IPRT Testcase - UTF-8 and UTF-16 string conversions.
*/
diff --git a/src/VBox/Runtime/testcase/tstVector.cpp b/src/VBox/Runtime/testcase/tstVector.cpp
new file mode 100644
index 000000000..ecc07e6ab
--- /dev/null
+++ b/src/VBox/Runtime/testcase/tstVector.cpp
@@ -0,0 +1,234 @@
+/* $Id: tstVector.cpp 37829 2011-07-08 08:35:47Z vboxsync $ */
+/** @file
+ * IPRT Testcase - Vector container structure.
+ */
+
+/*
+ * 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.
+ *
+ * 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/test.h>
+#include <iprt/vector.h>
+
+#include <stdlib.h> /* For realloc */
+
+/** Counter of the number of delete calls made so far */
+static unsigned s_cDeleteCalls = 0;
+
+/** Record the argument of the delete function here. */
+static void *s_apvDeleteArg[10];
+
+/** Dummy delete function for vector-of-void pointer elements */
+static void deletePVoid(void **ppv)
+{
+ if (s_cDeleteCalls < RT_ELEMENTS(s_apvDeleteArg))
+ s_apvDeleteArg[s_cDeleteCalls] = *ppv;
+ ++s_cDeleteCalls;
+}
+
+/** Dummy delete by value function for vector-of-void pointer elements */
+static void deletePVoidValue(void *pv)
+{
+ if (s_cDeleteCalls < RT_ELEMENTS(s_apvDeleteArg))
+ s_apvDeleteArg[s_cDeleteCalls] = pv;
+ ++s_cDeleteCalls;
+}
+
+/* Start by instantiating each function once for syntax checking */
+RTVEC_DECL_STRUCT(tstInstance, void *)
+RTVEC_DECL_STRUCT(tstInstance2, void *)
+
+RTVEC_DECLFN_DELETE_ADAPTER_ID(tstInstance, void *)
+RTVEC_DECLFN_DELETE_ADAPTER_TO_VALUE(tstInstance, void *)
+
+RTVEC_DECLFN_SIZE(tstInstance, void *)
+RTVEC_DECLFN_RESERVE(tstInstance, void *, rtvecReallocDefTag)
+RTVEC_DECLFN_BEGIN(tstInstance, void *)
+RTVEC_DECLFN_END(tstInstance, void *)
+RTVEC_DECLFN_PUSHBACK(tstInstance, void *)
+RTVEC_DECLFN_POPBACK(tstInstance)
+RTVEC_DECLFN_POPBACK_DELETE(tstInstance2, void *, deletePVoid,
+ tstInstanceDeleteAdapterId)
+RTVEC_DECLFN_CLEAR(tstInstance)
+RTVEC_DECLFN_CLEAR_DELETE(tstInstance2, deletePVoid,
+ tstInstanceDeleteAdapterId)
+RTVEC_DECLFN_DETACH(tstInstance, void *)
+
+RTVEC_DECL(tstSimple, void *)
+
+static void testVectorSimple(RTTEST hTest)
+{
+ RTTestISub("Vector structure, no cleanup callback");
+
+ struct tstSimple myVec = RTVEC_INITIALIZER;
+ void **ppvVal;
+
+ RTTESTI_CHECK(tstSimpleSize(&myVec) == 0);
+
+ ppvVal = tstSimplePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ RTTESTI_CHECK(ppvVal == tstSimpleBegin(&myVec));
+ RTTESTI_CHECK(ppvVal + 1 == tstSimpleEnd(&myVec));
+ RTTESTI_CHECK(tstSimpleSize(&myVec) == 1);
+ *ppvVal = (void *)1;
+
+ ppvVal = tstSimplePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ RTTESTI_CHECK(ppvVal - 1 == tstSimpleBegin(&myVec));
+ RTTESTI_CHECK(ppvVal + 1 == tstSimpleEnd(&myVec));
+ RTTESTI_CHECK(tstSimpleSize(&myVec) == 2);
+ RTTESTI_CHECK(ppvVal[-1] == (void *)1);
+
+ *ppvVal = (void *)3;
+ ppvVal = tstSimplePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ RTTESTI_CHECK(ppvVal - 2 == tstSimpleBegin(&myVec));
+ RTTESTI_CHECK(ppvVal + 1 == tstSimpleEnd(&myVec));
+ RTTESTI_CHECK(tstSimpleSize(&myVec) == 3);
+ RTTESTI_CHECK(ppvVal[-2] == (void *)1);
+ RTTESTI_CHECK(ppvVal[-1] == (void *)3);
+
+ tstSimplePopBack(&myVec);
+ RTTESTI_CHECK(tstSimpleBegin(&myVec) + 2 == tstSimpleEnd(&myVec));
+ RTTESTI_CHECK(*tstSimpleBegin(&myVec) == (void *)1);
+ RTTESTI_CHECK(*(tstSimpleEnd(&myVec) - 1) == (void *)3);
+
+ tstSimpleClear(&myVec);
+ RTTESTI_CHECK(tstSimpleBegin(&myVec) == tstSimpleEnd(&myVec));
+ ppvVal = tstSimplePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ RTTESTI_CHECK(ppvVal == tstSimpleBegin(&myVec));
+ RTTESTI_CHECK(ppvVal + 1 == tstSimpleEnd(&myVec));
+
+ tstSimpleClear(&myVec);
+ ppvVal = tstSimplePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ *ppvVal = (void *)1;
+ ppvVal = tstSimplePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ *ppvVal = (void *)3;
+ ppvVal = tstSimplePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ *ppvVal = (void *)2;
+ ppvVal = tstSimpleDetach(&myVec);
+ RTTESTI_CHECK(tstSimpleBegin(&myVec) == NULL);
+ RTTESTI_CHECK(tstSimpleSize(&myVec) == 0);
+ RTTESTI_CHECK(ppvVal[0] == (void *)1);
+ RTTESTI_CHECK(ppvVal[1] == (void *)3);
+ RTTESTI_CHECK(ppvVal[2] == (void *)2);
+}
+
+RTVEC_DECL_DELETE(tstDelete, void *, deletePVoid)
+
+static void testVectorDelete(RTTEST hTest)
+{
+ RTTestISub("Vector structure with cleanup by pointer callback");
+
+ struct tstDelete myVec = RTVEC_INITIALIZER;
+ void **ppvVal;
+
+ ppvVal = tstDeletePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ *ppvVal = (void *)1;
+ ppvVal = tstDeletePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ *ppvVal = (void *)3;
+ ppvVal = tstDeletePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ *ppvVal = (void *)2;
+
+ s_cDeleteCalls = 0;
+ tstDeletePopBack(&myVec);
+ RTTESTI_CHECK(s_cDeleteCalls == 1);
+ RTTESTI_CHECK(s_apvDeleteArg[0] == (void *)2);
+ RTTESTI_CHECK(tstDeleteBegin(&myVec) + 2 == tstDeleteEnd(&myVec));
+ RTTESTI_CHECK(*tstDeleteBegin(&myVec) == (void *)1);
+ RTTESTI_CHECK(*(tstDeleteEnd(&myVec) - 1) == (void *)3);
+
+ s_cDeleteCalls = 0;
+ tstDeleteClear(&myVec);
+ RTTESTI_CHECK(s_cDeleteCalls == 2);
+ RTTESTI_CHECK(s_apvDeleteArg[0] == (void *)1);
+ RTTESTI_CHECK(s_apvDeleteArg[1] == (void *)3);
+ RTTESTI_CHECK(tstDeleteBegin(&myVec) == tstDeleteEnd(&myVec));
+ ppvVal = tstDeletePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ RTTESTI_CHECK(ppvVal == tstDeleteBegin(&myVec));
+ RTTESTI_CHECK(ppvVal + 1 == tstDeleteEnd(&myVec));
+}
+
+RTVEC_DECL_DELETE_BY_VALUE(tstDeleteValue, void *, deletePVoidValue)
+
+static void testVectorDeleteValue(RTTEST hTest)
+{
+ RTTestISub("Vector structure with cleanup by value callback");
+
+ struct tstDeleteValue myVec = RTVEC_INITIALIZER;
+ void **ppvVal;
+
+ ppvVal = tstDeleteValuePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ *ppvVal = (void *)1;
+ ppvVal = tstDeleteValuePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ *ppvVal = (void *)3;
+ ppvVal = tstDeleteValuePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ *ppvVal = (void *)2;
+
+ s_cDeleteCalls = 0;
+ tstDeleteValuePopBack(&myVec);
+ RTTESTI_CHECK(s_cDeleteCalls == 1);
+ RTTESTI_CHECK(s_apvDeleteArg[0] == (void *)2);
+ RTTESTI_CHECK( tstDeleteValueBegin(&myVec) + 2
+ == tstDeleteValueEnd(&myVec));
+ RTTESTI_CHECK(*tstDeleteValueBegin(&myVec) == (void *)1);
+ RTTESTI_CHECK(*(tstDeleteValueEnd(&myVec) - 1) == (void *)3);
+
+ s_cDeleteCalls = 0;
+ tstDeleteValueClear(&myVec);
+ RTTESTI_CHECK(s_cDeleteCalls == 2);
+ RTTESTI_CHECK(s_apvDeleteArg[0] == (void *)1);
+ RTTESTI_CHECK(s_apvDeleteArg[1] == (void *)3);
+ RTTESTI_CHECK(tstDeleteValueBegin(&myVec) == tstDeleteValueEnd(&myVec));
+ ppvVal = tstDeleteValuePushBack(&myVec);
+ /* AssertPtrReturnVoid(ppvVal); */
+ RTTESTI_CHECK(ppvVal == tstDeleteValueBegin(&myVec));
+ RTTESTI_CHECK(ppvVal + 1 == tstDeleteValueEnd(&myVec));
+}
+
+
+
+int main()
+{
+ RTTEST hTest;
+ RTEXITCODE rcExit = RTTestInitAndCreate("tstVector", &hTest);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+ testVectorSimple(hTest);
+ testVectorDelete(hTest);
+ testVectorDeleteValue(hTest);
+
+ return RTTestSummaryAndDestroy(hTest);
+}
diff --git a/src/VBox/Runtime/tools/Makefile.kmk b/src/VBox/Runtime/tools/Makefile.kmk
index 684ecc244..51b953cac 100644
--- a/src/VBox/Runtime/tools/Makefile.kmk
+++ b/src/VBox/Runtime/tools/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 34673 2010-12-03 00:51:42Z vboxsync $
## @file
# Sub-Makefile for the IPRT tools.
#
diff --git a/src/VBox/Runtime/tools/RTGzip.cpp b/src/VBox/Runtime/tools/RTGzip.cpp
index 197a74f63..0f771229c 100644
--- a/src/VBox/Runtime/tools/RTGzip.cpp
+++ b/src/VBox/Runtime/tools/RTGzip.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTGzip.cpp $ */
+/* $Id: RTGzip.cpp 34464 2010-11-29 13:45:37Z vboxsync $ */
/** @file
* IPRT - GZIP Utility.
*/
diff --git a/src/VBox/Runtime/tools/RTLdrFlt.cpp b/src/VBox/Runtime/tools/RTLdrFlt.cpp
index 9e3876da5..993475cef 100644
--- a/src/VBox/Runtime/tools/RTLdrFlt.cpp
+++ b/src/VBox/Runtime/tools/RTLdrFlt.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTLdrFlt.cpp $ */
+/* $Id: RTLdrFlt.cpp 34464 2010-11-29 13:45:37Z vboxsync $ */
/** @file
* IPRT - Utility for translating addresses into symbols+offset.
*/
@@ -149,7 +149,7 @@ int main(int argc, char **argv)
break;
case 'V':
- RTPrintf("$Revision: 68240 $");
+ RTPrintf("$Revision: 34464 $");
return RTEXITCODE_SUCCESS;
case VINF_GETOPT_NOT_OPTION:
diff --git a/src/VBox/Runtime/tools/RTManifest.cpp b/src/VBox/Runtime/tools/RTManifest.cpp
index 385d271b9..e31133f49 100644
--- a/src/VBox/Runtime/tools/RTManifest.cpp
+++ b/src/VBox/Runtime/tools/RTManifest.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTManifest.cpp $ */
+/* $Id: RTManifest.cpp 34466 2010-11-29 15:00:56Z vboxsync $ */
/** @file
* IPRT - Manifest Utility.
*/
diff --git a/src/VBox/Runtime/tools/RTTar.cpp b/src/VBox/Runtime/tools/RTTar.cpp
index 34e53ca9d..a44d4f5b9 100644
--- a/src/VBox/Runtime/tools/RTTar.cpp
+++ b/src/VBox/Runtime/tools/RTTar.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTTar.cpp $ */
+/* $Id: RTTar.cpp 34464 2010-11-29 13:45:37Z vboxsync $ */
/** @file
* IPRT - TAR Utility.
*/
diff --git a/src/VBox/Runtime/win/RTErrConvertFromWin32.cpp b/src/VBox/Runtime/win/RTErrConvertFromWin32.cpp
index 0da4c41a0..c4cbd2356 100644
--- a/src/VBox/Runtime/win/RTErrConvertFromWin32.cpp
+++ b/src/VBox/Runtime/win/RTErrConvertFromWin32.cpp
@@ -1,4 +1,4 @@
-/* $Id: RTErrConvertFromWin32.cpp $ */
+/* $Id: RTErrConvertFromWin32.cpp 33437 2010-10-25 16:28:14Z vboxsync $ */
/** @file
* IPRT - Convert win32 error codes to iprt status codes.
*/
diff --git a/src/VBox/Runtime/win/errmsgwin.cpp b/src/VBox/Runtime/win/errmsgwin.cpp
index 0f5c54466..fed8a0a82 100644
--- a/src/VBox/Runtime/win/errmsgwin.cpp
+++ b/src/VBox/Runtime/win/errmsgwin.cpp
@@ -1,4 +1,4 @@
-/* $Id: errmsgwin.cpp $ */
+/* $Id: errmsgwin.cpp 35445 2011-01-10 11:05:23Z vboxsync $ */
/** @file
* IPRT - Status code messages.
*/
diff --git a/src/VBox/Storage/DMG.cpp b/src/VBox/Storage/DMG.cpp
index 665028e59..8a8afd353 100644
--- a/src/VBox/Storage/DMG.cpp
+++ b/src/VBox/Storage/DMG.cpp
@@ -1,4 +1,4 @@
-/* $Id: DMG.cpp $ */
+/* $Id: DMG.cpp 36633 2011-04-08 21:43:41Z vboxsync $ */
/** @file
* VBoxDMG - Interpreter for Apple Disk Images (DMG).
*/
@@ -1693,7 +1693,8 @@ static int dmgOpen(const char *pszFilename, unsigned uOpenFlags,
* simple backend and can expect the caller to be the only user and already
* have validate what it passes thru to us.
*/
- if (!(uOpenFlags & VD_OPEN_FLAGS_READONLY))
+ if ( !(uOpenFlags & VD_OPEN_FLAGS_READONLY)
+ || (uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO))
{
rc = VERR_NOT_SUPPORTED;
goto out;
@@ -2424,8 +2425,6 @@ VBOXHDDBACKEND g_DmgBackend =
NULL,
/* pfnSetParentFilename */
NULL,
- /* pfnIsAsyncIOSupported */
- NULL,
/* pfnAsyncRead */
NULL,
/* pfnAsyncWrite */
diff --git a/src/VBox/Storage/ISCSI.cpp b/src/VBox/Storage/ISCSI.cpp
index a89cb1df8..172c4f379 100644
--- a/src/VBox/Storage/ISCSI.cpp
+++ b/src/VBox/Storage/ISCSI.cpp
@@ -1,10 +1,10 @@
-/* $Id: ISCSI.cpp $ */
+/* $Id: ISCSI.cpp 37688 2011-06-29 15:26:05Z vboxsync $ */
/** @file
* iSCSI initiator driver, VD backend.
*/
/*
- * 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;
@@ -584,7 +584,7 @@ typedef struct ISCSIIMAGE
/** Pointer to the target hostname. */
char *pszHostname;
- /** Pointer to the target hostname. */
+ /** Port to use on the target host. */
uint32_t uPort;
/** Socket handle of the TCP connection. */
VDSOCKET Socket;
@@ -910,10 +910,28 @@ static int iscsiTransportConnect(PISCSIIMAGE pImage)
if (!pImage->pszInitiatorName)
return VERR_NO_MEMORY;
}
+ LogRel(("iSCSI: connect from initiator %s with source port %u\n", pImage->pszInitiatorName, pImage->ISID & 65535));
return VINF_SUCCESS;
}
+static int iscsiTransportClose(PISCSIIMAGE pImage)
+{
+ int rc;
+
+ LogFlowFunc(("(%s:%d)\n", pImage->pszHostname, pImage->uPort));
+ if (iscsiIsClientConnected(pImage))
+ {
+ LogRel(("iSCSI: disconnect from initiator %s with source port %u\n", pImage->pszInitiatorName, pImage->ISID & 65535));
+ rc = pImage->pInterfaceNetCallbacks->pfnClientClose(pImage->Socket);
+ }
+ else
+ rc = VINF_SUCCESS;
+ LogFlowFunc(("returns %Rrc\n", rc));
+ return rc;
+}
+
+
static int iscsiTransportRead(PISCSIIMAGE pImage, PISCSIRES paResponse, unsigned int cnResponse)
{
int rc = VINF_SUCCESS;
@@ -957,7 +975,7 @@ static int iscsiTransportRead(PISCSIIMAGE pImage, PISCSIRES paResponse, unsigned
if (cbActuallyRead == 0)
{
/* The other end has closed the connection. */
- pImage->pInterfaceNetCallbacks->pfnClientClose(pImage->Socket);
+ iscsiTransportClose(pImage);
pImage->state = ISCSISTATE_FREE;
rc = VERR_NET_CONNECTION_RESET;
break;
@@ -1115,10 +1133,7 @@ static int iscsiTransportOpen(PISCSIIMAGE pImage)
uint16_t uPort;
/* Clean up previous connection data. */
- if (iscsiIsClientConnected(pImage))
- {
- pImage->pInterfaceNetCallbacks->pfnClientClose(pImage->Socket);
- }
+ iscsiTransportClose(pImage);
if (pImage->pszHostname)
{
RTMemFree(pImage->pszHostname);
@@ -1211,22 +1226,6 @@ static int iscsiTransportOpen(PISCSIIMAGE pImage)
}
-static int iscsiTransportClose(PISCSIIMAGE pImage)
-{
- int rc;
-
- LogFlowFunc(("(%s:%d)\n", pImage->pszHostname, pImage->uPort));
- if (iscsiIsClientConnected(pImage))
- {
- rc = pImage->pInterfaceNetCallbacks->pfnClientClose(pImage->Socket);
- }
- else
- rc = VINF_SUCCESS;
- LogFlowFunc(("returns %Rrc\n", rc));
- return rc;
-}
-
-
/**
* Attach to an iSCSI target. Performs all operations necessary to enter
* Full Feature Phase.
@@ -1977,6 +1976,7 @@ out_release:
* about 30-40 seconds, or the guest will lose its patience. */
iscsiTransportClose(pImage);
pImage->state = ISCSISTATE_FREE;
+ rc = VERR_BROKEN_PIPE;
}
RTSemMutexRelease(pImage->Mutex);
@@ -2238,7 +2238,7 @@ static void iscsiPDUTxAdd(PISCSIIMAGE pImage, PISCSIPDUTX pIScsiPDUTx, bool fFro
{
if (!fFront)
{
- /* Link the PDU at the tail of the list. */
+ /* Insert PDU at the tail of the list. */
if (!pImage->pIScsiPDUTxHead)
pImage->pIScsiPDUTxHead = pIScsiPDUTx;
else
@@ -2247,7 +2247,7 @@ static void iscsiPDUTxAdd(PISCSIIMAGE pImage, PISCSIPDUTX pIScsiPDUTx, bool fFro
}
else
{
- /* Link PDU to at the front of the list. */
+ /* Insert PDU at the beginning of the list. */
pIScsiPDUTx->pNext = pImage->pIScsiPDUTxHead;
pImage->pIScsiPDUTxHead = pIScsiPDUTx;
if (!pImage->pIScsiPDUTxTail)
@@ -2503,8 +2503,13 @@ static int iscsiRecvPDUProcess(PISCSIIMAGE pImage, PISCSIRES paRes, uint32_t cnR
pIScsiPDUTx->cbSgLeft = sizeof(pIScsiPDUTx->aBHS);
RTSgBufInit(&pIScsiPDUTx->SgBuf, pIScsiPDUTx->aISCSIReq, cnISCSIReq);
- /* Link the PDU to the list. */
- iscsiPDUTxAdd(pImage, pIScsiPDUTx, false /* fFront */);
+ /*
+ * Link the PDU to the list.
+ * Insert at the front of the list to send the response as soon as possible
+ * to avoid frequent reconnects for a slow connection when there are many PDUs
+ * waiting.
+ */
+ iscsiPDUTxAdd(pImage, pIScsiPDUTx, true /* fFront */);
/* Start transfer of a PDU if there is no one active at the moment. */
if (!pImage->pIScsiPDUTxCur)
@@ -3239,6 +3244,9 @@ static void iscsiReattach(PISCSIIMAGE pImage)
RTMemFree(pIScsiPDUTx);
}
+ /* Clear the tail pointer (safety precaution). */
+ pImage->pIScsiPDUTxTail = NULL;
+
/* Clear the current PDU too. */
if (pImage->pIScsiPDUTxCur)
{
@@ -5167,13 +5175,6 @@ static void iscsiDump(void *pBackendData)
}
}
-/** @copydoc VBOXHDDBACKEND::pfnIsAsyncIOSupported */
-static bool iscsiIsAsyncIOSupported(void *pBackendData)
-{
- PISCSIIMAGE pImage = (PISCSIIMAGE)pBackendData;
- return pImage->fCmdQueuingSupported;
-}
-
/** @copydoc VBOXHDDBACKEND::pfnAsyncRead */
static int iscsiAsyncRead(void *pBackendData, uint64_t uOffset, size_t cbToRead,
PVDIOCTX pIoCtx, size_t *pcbActuallyRead)
@@ -5620,8 +5621,6 @@ VBOXHDDBACKEND g_ISCSIBackend =
NULL,
/* pfnSetParentFilename */
NULL,
- /* pfnIsAsyncIOSupported */
- iscsiIsAsyncIOSupported,
/* pfnAsyncRead */
iscsiAsyncRead,
/* pfnAsyncWrite */
diff --git a/src/VBox/Storage/Makefile.kmk b/src/VBox/Storage/Makefile.kmk
index 41978c061..b4850d183 100644
--- a/src/VBox/Storage/Makefile.kmk
+++ b/src/VBox/Storage/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 33586 2010-10-28 22:00:52Z vboxsync $
## @file
# Sub-Makefile for the Storage library.
#
diff --git a/src/VBox/Storage/Parallels.cpp b/src/VBox/Storage/Parallels.cpp
index d835cf5f0..be787cd3c 100644
--- a/src/VBox/Storage/Parallels.cpp
+++ b/src/VBox/Storage/Parallels.cpp
@@ -1,4 +1,4 @@
-/* $Id: Parallels.cpp $ */
+/* $Id: Parallels.cpp 37739 2011-07-03 20:42:12Z vboxsync $ */
/** @file
*
* Parallels hdd disk image, core code.
@@ -649,7 +649,8 @@ static int parallelsRead(void *pBackendData, uint64_t uOffset, void *pvBuf,
}
}
- if (RT_SUCCESS(rc))
+ if ( RT_SUCCESS(rc)
+ || rc == VERR_VD_BLOCK_FREE)
{
if (pcbActuallyRead)
*pcbActuallyRead = cbBuf;
@@ -1195,16 +1196,6 @@ static void parallelsDump(void *pBackendData)
}
}
-/** @copydoc VBOXHDDBACKEND::pfnIsAsyncIOSupported */
-static bool parallelsIsAsyncIOSupported(void *pBackendData)
-{
-#if 0 /** @todo: Remove when tested */
- return true;
-#else
- return false;
-#endif
-}
-
/** @copydoc VBOXHDDBACKEND::pfnAsyncRead */
static int parallelsAsyncRead(void *pBackendData, uint64_t uOffset, size_t cbToRead,
PVDIOCTX pIoCtx, size_t *pcbActuallyRead)
@@ -1431,8 +1422,6 @@ VBOXHDDBACKEND g_ParallelsBackend =
NULL,
/* pfnSetParentFilename */
NULL,
- /* pfnIsAsyncIOSupported */
- parallelsIsAsyncIOSupported,
/* pfnAsyncRead */
parallelsAsyncRead,
/* pfnAsyncWrite */
diff --git a/src/VBox/Storage/RAW.cpp b/src/VBox/Storage/RAW.cpp
index 20231f246..b6eb76988 100644
--- a/src/VBox/Storage/RAW.cpp
+++ b/src/VBox/Storage/RAW.cpp
@@ -1,4 +1,4 @@
-/* $Id: RAW.cpp $ */
+/* $Id: RAW.cpp 36633 2011-04-08 21:43:41Z vboxsync $ */
/** @file
* RawHDDCore - Raw Disk image, Core Code.
*/
@@ -1299,12 +1299,6 @@ static void rawDump(void *pBackendData)
}
}
-/** @copydoc VBOXHDDBACKEND::pfnIsAsyncIOSupported */
-static bool rawIsAsyncIOSupported(void *pBackendData)
-{
- return true;
-}
-
/** @copydoc VBOXHDDBACKEND::pfnAsyncRead */
static int rawAsyncRead(void *pBackendData, uint64_t uOffset, size_t cbRead,
PVDIOCTX pIoCtx, size_t *pcbActuallyRead)
@@ -1434,8 +1428,6 @@ VBOXHDDBACKEND g_RawBackend =
NULL,
/* pfnSetParentFilename */
NULL,
- /* pfnIsAsyncIOSupported */
- rawIsAsyncIOSupported,
/* pfnAsyncRead */
rawAsyncRead,
/* pfnAsyncWrite */
diff --git a/src/VBox/Storage/VCICache.cpp b/src/VBox/Storage/VCICache.cpp
index 2b84e1837..de60fd04b 100644
--- a/src/VBox/Storage/VCICache.cpp
+++ b/src/VBox/Storage/VCICache.cpp
@@ -1,4 +1,4 @@
-/* $Id: VCICache.cpp $ */
+/* $Id: VCICache.cpp 33745 2010-11-03 18:31:53Z vboxsync $ */
/** @file
* VCICacheCore - VirtualBox Cache Image, Core Code.
*/
diff --git a/src/VBox/Storage/VD.cpp b/src/VBox/Storage/VD.cpp
index a4f95a10d..ef0cdfb4d 100644
--- a/src/VBox/Storage/VD.cpp
+++ b/src/VBox/Storage/VD.cpp
@@ -1,4 +1,4 @@
-/* $Id: VD.cpp $ */
+/* $Id: VD.cpp 37329 2011-06-06 15:43:39Z vboxsync $ */
/** @file
* VBoxHDD - VBox HDD Container implementation.
*/
@@ -4226,6 +4226,18 @@ VBOXDDU_DECL(int) VDOpen(PVBOXHDD pDisk, const char *pszBackend,
break;
}
+ /*
+ * Fail if the the backend can't do async I/O but the
+ * flag is set.
+ */
+ if ( !(pImage->Backend->uBackendCaps & VD_CAP_ASYNC)
+ && (uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO))
+ {
+ rc = vdError(pDisk, VERR_NOT_SUPPORTED, RT_SRC_POS,
+ N_("VD: Backend '%s' does not support async I/O"), pszBackend);
+ break;
+ }
+
/* Set up the I/O interface. */
pImage->VDIo.pInterfaceIO = VDInterfaceGet(pVDIfsImage, VDINTERFACETYPE_IO);
if (pImage->VDIo.pInterfaceIO)
@@ -8069,56 +8081,6 @@ VBOXDDU_DECL(void) VDDumpImages(PVBOXHDD pDisk)
}
}
-/**
- * Query if asynchronous operations are supported for this disk.
- *
- * @returns VBox status code.
- * @returns VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
- * @param pDisk Pointer to the HDD container.
- * @param nImage Image number, counts from 0. 0 is always base image of container.
- * @param pfAIOSupported Where to store if async IO is supported.
- */
-VBOXDDU_DECL(int) VDImageIsAsyncIOSupported(PVBOXHDD pDisk, unsigned nImage, bool *pfAIOSupported)
-{
- int rc = VINF_SUCCESS;
- int rc2;
- bool fLockRead = false;
-
- LogFlowFunc(("pDisk=%#p nImage=%u pfAIOSupported=%#p\n", pDisk, nImage, pfAIOSupported));
- do
- {
- /* sanity check */
- AssertPtrBreakStmt(pDisk, rc = VERR_INVALID_PARAMETER);
- AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
-
- /* Check arguments. */
- AssertMsgBreakStmt(VALID_PTR(pfAIOSupported),
- ("pfAIOSupported=%#p\n", pfAIOSupported),
- rc = VERR_INVALID_PARAMETER);
-
- rc2 = vdThreadStartRead(pDisk);
- AssertRC(rc2);
- fLockRead = true;
-
- PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
- AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
-
- if (pImage->Backend->uBackendCaps & VD_CAP_ASYNC)
- *pfAIOSupported = pImage->Backend->pfnIsAsyncIOSupported(pImage->pBackendData);
- else
- *pfAIOSupported = false;
- } while (0);
-
- if (RT_UNLIKELY(fLockRead))
- {
- rc2 = vdThreadFinishRead(pDisk);
- AssertRC(rc2);
- }
-
- LogFlowFunc(("returns %Rrc, fAIOSupported=%u\n", rc, *pfAIOSupported));
- return rc;
-}
-
VBOXDDU_DECL(int) VDAsyncRead(PVBOXHDD pDisk, uint64_t uOffset, size_t cbRead,
PCRTSGBUF pcSgBuf,
diff --git a/src/VBox/Storage/VDI.cpp b/src/VBox/Storage/VDI.cpp
index c10508262..a3d31ec67 100644
--- a/src/VBox/Storage/VDI.cpp
+++ b/src/VBox/Storage/VDI.cpp
@@ -1106,7 +1106,7 @@ static int vdiCreate(const char *pszFilename, uint64_t cbSize,
pfnProgress = pCbProgress->pfnProgress;
pvUser = pIfProgress->pvUser;
}
-
+
/* Check the image flags. */
if ((uImageFlags & ~VD_VDI_IMAGE_FLAGS_MASK) != 0)
{
@@ -1354,7 +1354,8 @@ static int vdiWrite(void *pBackendData, uint64_t uOffset, const void *pvBuf,
}
}
- if (cbToWrite == getImageBlockSize(&pImage->Header))
+ if ( cbToWrite == getImageBlockSize(&pImage->Header)
+ && !(fWrite & VD_WRITE_NO_ALLOC))
{
/* Full block write to previously unallocated block.
* Allocate block and write data. */
@@ -2028,11 +2029,6 @@ static void vdiDump(void *pBackendData)
}
}
-static bool vdiIsAsyncIOSupported(void *pBackendData)
-{
- return true;
-}
-
static int vdiAsyncRead(void *pBackendData, uint64_t uOffset, size_t cbToRead,
PVDIOCTX pIoCtx, size_t *pcbActuallyRead)
{
@@ -2740,8 +2736,6 @@ VBOXHDDBACKEND g_VDIBackend =
NULL,
/* pfnSetParentFilename */
NULL,
- /* pfnIsAsyncIOSupported */
- vdiIsAsyncIOSupported,
/* pfnAsyncRead */
vdiAsyncRead,
/* pfnAsyncWrite */
diff --git a/src/VBox/Storage/VDICore.h b/src/VBox/Storage/VDICore.h
index 1ae42ed89..0240db2ea 100644
--- a/src/VBox/Storage/VDICore.h
+++ b/src/VBox/Storage/VDICore.h
@@ -1,4 +1,4 @@
-/* $Id: VDICore.h $ */
+/* $Id: VDICore.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* Virtual Disk Image (VDI), Core Code Header (internal).
*/
diff --git a/src/VBox/Storage/VHD.cpp b/src/VBox/Storage/VHD.cpp
index 03868388e..f136b272c 100644
--- a/src/VBox/Storage/VHD.cpp
+++ b/src/VBox/Storage/VHD.cpp
@@ -1,4 +1,4 @@
-/* $Id: VHD.cpp $ */
+/* $Id: VHD.cpp 37737 2011-07-02 20:12:28Z vboxsync $ */
/** @file
* VHD Disk image, Core Code.
*/
@@ -1627,7 +1627,7 @@ static int vhdClose(void *pBackendData, bool fDelete)
static int vhdRead(void *pBackendData, uint64_t uOffset, void *pvBuf,
size_t cbBuf, size_t *pcbActuallyRead)
{
- LogFlowFunc(("pBackendData=%p uOffset=%#llx pvBuf=%p cbBuf=%u pcbActuallyRead=%p\n", pBackendData, uOffset, pvBuf, cbBuf, pcbActuallyRead));
+ LogFlowFunc(("pBackendData=%p uOffset=%#llu pvBuf=%p cbBuf=%u pcbActuallyRead=%p\n", pBackendData, uOffset, pvBuf, cbBuf, pcbActuallyRead));
PVHDIMAGE pImage = (PVHDIMAGE)pBackendData;
int rc = VINF_SUCCESS;
@@ -1735,7 +1735,8 @@ static int vhdRead(void *pBackendData, uint64_t uOffset, void *pvBuf,
rc = vhdFileReadSync(pImage, uOffset, pvBuf, cbBuf, NULL);
}
- if (RT_SUCCESS(rc))
+ if ( RT_SUCCESS(rc)
+ || rc == VERR_VD_BLOCK_FREE)
{
if (pcbActuallyRead)
*pcbActuallyRead = cbBuf;
@@ -2459,12 +2460,6 @@ static int vhdSetParentFilename(void *pBackendData, const char *pszParentFilenam
return rc;
}
-/** @copydoc VBOXHDDBACKEND::pfnIsAsyncIOSupported */
-static bool vhdIsAsyncIOSupported(void *pBackendData)
-{
- return true;
-}
-
/** @copydoc VBOXHDDBACKEND::pfnAsyncRead */
static int vhdAsyncRead(void *pBackendData, uint64_t uOffset, size_t cbRead,
PVDIOCTX pIoCtx, size_t *pcbActuallyRead)
@@ -2827,6 +2822,249 @@ static int vhdAsyncFlush(void *pBackendData, PVDIOCTX pIoCtx)
return vhdFileFlushAsync(pImage, pIoCtx, NULL, NULL);
}
+/** @copydoc VBOXHDDBACKEND::pfnCompact */
+static int vhdCompact(void *pBackendData, unsigned uPercentStart,
+ unsigned uPercentSpan, PVDINTERFACE pVDIfsDisk,
+ PVDINTERFACE pVDIfsImage, PVDINTERFACE pVDIfsOperation)
+{
+ PVHDIMAGE pImage = (PVHDIMAGE)pBackendData;
+ int rc = VINF_SUCCESS;
+ void *pvBuf = NULL, *pvReplace = NULL;
+ uint32_t *paBlocks = NULL;
+
+ int (*pfnParentRead)(void *, uint64_t, void *, size_t) = NULL;
+ void *pvParent = NULL;
+ PVDINTERFACE pIfParentState = VDInterfaceGet(pVDIfsOperation,
+ VDINTERFACETYPE_PARENTSTATE);
+ PVDINTERFACEPARENTSTATE pCbParentState = NULL;
+ if (pIfParentState)
+ {
+ pCbParentState = VDGetInterfaceParentState(pIfParentState);
+ if (pCbParentState)
+ pfnParentRead = pCbParentState->pfnParentRead;
+ pvParent = pIfParentState->pvUser;
+ }
+
+ PFNVDPROGRESS pfnProgress = NULL;
+ void *pvUser = NULL;
+ PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation,
+ VDINTERFACETYPE_PROGRESS);
+ PVDINTERFACEPROGRESS pCbProgress = NULL;
+ if (pIfProgress)
+ {
+ pCbProgress = VDGetInterfaceProgress(pIfProgress);
+ if (pCbProgress)
+ pfnProgress = pCbProgress->pfnProgress;
+ pvUser = pIfProgress->pvUser;
+ }
+
+ do
+ {
+ AssertBreakStmt(pImage, rc = VERR_INVALID_PARAMETER);
+
+ AssertBreakStmt(!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY),
+ rc = VERR_VD_IMAGE_READ_ONLY);
+
+ /* Reject fixed images as they don't have a BAT. */
+ if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED)
+ {
+ rc = VERR_NOT_SUPPORTED;
+ break;
+ }
+
+ if (pfnParentRead)
+ {
+ pvParent = RTMemTmpAlloc(pImage->cbDataBlock);
+ AssertBreakStmt(VALID_PTR(pvBuf), rc = VERR_NO_MEMORY);
+ }
+ pvBuf = RTMemTmpAlloc(pImage->cbDataBlock);
+ AssertBreakStmt(VALID_PTR(pvBuf), rc = VERR_NO_MEMORY);
+
+ unsigned cBlocksAllocated = 0;
+ unsigned cBlocksToMove = 0;
+ unsigned cBlocks = pImage->cBlockAllocationTableEntries;
+ uint32_t offBlocksStart = ~0U; /* Start offset of data blocks in sectors. */
+ uint32_t *paBat = pImage->pBlockAllocationTable;
+
+ /* Count the number of allocated blocks and find the start offset for the data blocks. */
+ for (unsigned i = 0; i < cBlocks; i++)
+ if (paBat[i] != ~0U)
+ {
+ cBlocksAllocated++;
+ if (paBat[i] < offBlocksStart)
+ offBlocksStart = paBat[i];
+ }
+
+ if (!cBlocksAllocated)
+ {
+ /* Nothing to do. */
+ rc = VINF_SUCCESS;
+ break;
+ }
+
+ paBlocks = (uint32_t *)RTMemTmpAllocZ(cBlocksAllocated * sizeof(uint32_t));
+ AssertBreakStmt(VALID_PTR(paBlocks), rc = VERR_NO_MEMORY);
+
+ /* Invalidate the back resolving array. */
+ for (unsigned i = 0; i < cBlocksAllocated; i++)
+ paBlocks[i] = ~0U;
+
+ /* Fill the back resolving table. */
+ for (unsigned i = 0; i < cBlocks; i++)
+ if (paBat[i] != ~0U)
+ {
+ unsigned idxBlock = (paBat[i] - offBlocksStart) / pImage->cSectorsPerDataBlock;
+ if ( idxBlock < cBlocksAllocated
+ && paBlocks[idxBlock] == ~0U)
+ paBlocks[idxBlock] = i;
+ else
+ {
+ /* The image is in an inconsistent state. Don't go further. */
+ rc = VERR_INVALID_STATE;
+ break;
+ }
+ }
+
+ if (RT_FAILURE(rc))
+ break;
+
+ /* Find redundant information and update the block pointers
+ * accordingly, creating bubbles. Keep disk up to date, as this
+ * enables cancelling. */
+ for (unsigned i = 0; i < cBlocks; i++)
+ {
+ if (paBat[i] != ~0U)
+ {
+ unsigned idxBlock = (paBat[i] - offBlocksStart) / pImage->cSectorsPerDataBlock;
+
+ /* Block present in image file, read relevant data. */
+ uint64_t u64Offset = ((uint64_t)paBat[i] + pImage->cDataBlockBitmapSectors) * VHD_SECTOR_SIZE;
+ rc = vhdFileReadSync(pImage, u64Offset, pvBuf, pImage->cbDataBlock, NULL);
+ if (RT_FAILURE(rc))
+ break;
+
+ if (ASMBitFirstSet((volatile void *)pvBuf, (uint32_t)pImage->cbDataBlock * 8) == -1)
+ {
+ paBat[i] = ~0;
+ paBlocks[idxBlock] = ~0U;
+ /* Adjust progress info, one block to be relocated. */
+ cBlocksToMove++;
+ }
+ else if (pfnParentRead)
+ {
+ rc = pfnParentRead(pvParent, i * pImage->cbDataBlock, pvParent, pImage->cbDataBlock);
+ if (RT_FAILURE(rc))
+ break;
+ if (!memcmp(pvParent, pvBuf, pImage->cbDataBlock))
+ {
+ paBat[i] = ~0U;
+ paBlocks[idxBlock] = ~0U;
+ /* Adjust progress info, one block to be relocated. */
+ cBlocksToMove++;
+ }
+ }
+ }
+
+ if (pCbProgress && pCbProgress->pfnProgress)
+ {
+ rc = pCbProgress->pfnProgress(pIfProgress->pvUser,
+ (uint64_t)i * uPercentSpan / (cBlocks + cBlocksToMove) + uPercentStart);
+ if (RT_FAILURE(rc))
+ break;
+ }
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ /* Fill bubbles with other data (if available). */
+ unsigned cBlocksMoved = 0;
+ unsigned uBlockUsedPos = cBlocksAllocated;
+ size_t cbBlock = pImage->cbDataBlock + pImage->cbDataBlockBitmap; /** < Size of whole block containing the bitmap and the user data. */
+
+ /* Allocate data buffer to hold the data block and allocation bitmap in front of the actual data. */
+ RTMemTmpFree(pvBuf);
+ pvBuf = RTMemTmpAllocZ(cbBlock);
+ AssertBreakStmt(VALID_PTR(pvBuf), rc = VERR_NO_MEMORY);
+
+ for (unsigned i = 0; i < cBlocksAllocated; i++)
+ {
+ unsigned uBlock = paBlocks[i];
+ if (uBlock == ~0U)
+ {
+ unsigned uBlockData = ~0U;
+ while (uBlockUsedPos > i && uBlockData == ~0U)
+ {
+ uBlockUsedPos--;
+ uBlockData = paBlocks[uBlockUsedPos];
+ }
+ /* Terminate early if there is no block which needs copying. */
+ if (uBlockUsedPos == i)
+ break;
+ uint64_t u64Offset = (uint64_t)uBlockUsedPos * cbBlock
+ + (offBlocksStart * VHD_SECTOR_SIZE);
+ rc = vhdFileReadSync(pImage, u64Offset, pvBuf, cbBlock, NULL);
+ if (RT_FAILURE(rc))
+ break;
+
+ u64Offset = (uint64_t)i * cbBlock
+ + (offBlocksStart * VHD_SECTOR_SIZE);
+ rc = vhdFileWriteSync(pImage, u64Offset, pvBuf, cbBlock, NULL);
+ if (RT_FAILURE(rc))
+ break;
+
+ paBat[uBlockData] = i*(pImage->cSectorsPerDataBlock + pImage->cDataBlockBitmapSectors) + offBlocksStart;
+
+ /* Truncate the file but leave enough room for the footer to avoid
+ * races if other processes fill the whole harddisk. */
+ rc = vhdFileSetSize(pImage, pImage->uCurrentEndOfFile - cbBlock + VHD_SECTOR_SIZE);
+ if (RT_FAILURE(rc))
+ break;
+
+ /* Update pointers and write footer. */
+ pImage->uCurrentEndOfFile -= cbBlock;
+
+ /* We're kinda screwed if this failes. */
+ rc = vhdUpdateFooter(pImage);
+ if (RT_FAILURE(rc))
+ break;
+
+ paBlocks[i] = uBlockData;
+ paBlocks[uBlockUsedPos] = ~0U;
+ cBlocksMoved++;
+ }
+
+ if (pCbProgress && pCbProgress->pfnProgress)
+ {
+ rc = pCbProgress->pfnProgress(pIfProgress->pvUser,
+ (uint64_t)(cBlocks + cBlocksMoved) * uPercentSpan / (cBlocks + cBlocksToMove) + uPercentStart);
+
+ if (RT_FAILURE(rc))
+ break;
+ }
+ }
+ }
+
+ /* Write the new BAT in any case. */
+ rc = vhdFlushImage(pImage);
+ } while (0);
+
+ if (paBlocks)
+ RTMemTmpFree(paBlocks);
+ if (pvParent)
+ RTMemTmpFree(pvParent);
+ if (pvBuf)
+ RTMemTmpFree(pvBuf);
+
+ if (RT_SUCCESS(rc) && pCbProgress && pCbProgress->pfnProgress)
+ {
+ pCbProgress->pfnProgress(pIfProgress->pvUser,
+ uPercentStart + uPercentSpan);
+ }
+
+ LogFlowFunc(("returns %Rrc\n", rc));
+ return rc;
+}
+
/** @copydoc VBOXHDDBACKEND::pfnResize */
static int vhdResize(void *pBackendData, uint64_t cbSize,
PCVDGEOMETRY pPCHSGeometry, PCVDGEOMETRY pLCHSGeometry,
@@ -3095,8 +3333,6 @@ VBOXHDDBACKEND g_VhdBackend =
vhdGetParentFilename,
/* pfnSetParentFilename */
vhdSetParentFilename,
- /* pfnIsAsyncIOSupported */
- vhdIsAsyncIOSupported,
/* pfnAsyncRead */
vhdAsyncRead,
/* pfnAsyncWrite */
@@ -3108,7 +3344,7 @@ VBOXHDDBACKEND g_VhdBackend =
/* pfnComposeName */
genericFileComposeName,
/* pfnCompact */
- NULL,
+ vhdCompact,
/* pfnResize */
vhdResize
};
diff --git a/src/VBox/Storage/VMDK.cpp b/src/VBox/Storage/VMDK.cpp
index 59e86b6fb..d0be1bbfa 100644
--- a/src/VBox/Storage/VMDK.cpp
+++ b/src/VBox/Storage/VMDK.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMDK.cpp $ */
+/* $Id: VMDK.cpp 38030 2011-07-18 15:42:12Z vboxsync $ */
/** @file
* VMDK disk image, core code.
*/
@@ -3311,6 +3311,13 @@ static int vmdkOpenImage(PVMDKIMAGE pImage, unsigned uOpenFlags)
if (RT_FAILURE(rc))
goto out;
+ if ( pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED
+ && uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO)
+ {
+ rc = VERR_NOT_SUPPORTED;
+ goto out;
+ }
+
rc = vmdkReadMetaExtent(pImage, pExtent);
if (RT_FAILURE(rc))
goto out;
@@ -4690,76 +4697,6 @@ out:
}
/**
- * Internal. Flush image data (and metadata) to disk - async version.
- */
-static int vmdkFlushImageAsync(PVMDKIMAGE pImage, PVDIOCTX pIoCtx)
-{
- PVMDKEXTENT pExtent;
- int rc = VINF_SUCCESS;
-
- /* Update descriptor if changed. */
- if (pImage->Descriptor.fDirty)
- {
- rc = vmdkWriteDescriptorAsync(pImage, pIoCtx);
- if ( RT_FAILURE(rc)
- && rc != VERR_VD_ASYNC_IO_IN_PROGRESS)
- goto out;
- }
-
- for (unsigned i = 0; i < pImage->cExtents; i++)
- {
- pExtent = &pImage->pExtents[i];
- if (pExtent->pFile != NULL && pExtent->fMetaDirty)
- {
- switch (pExtent->enmType)
- {
- case VMDKETYPE_HOSTED_SPARSE:
- AssertMsgFailed(("Async I/O not supported for sparse images\n"));
- break;
-#ifdef VBOX_WITH_VMDK_ESX
- case VMDKETYPE_ESX_SPARSE:
- /** @todo update the header. */
- break;
-#endif /* VBOX_WITH_VMDK_ESX */
- case VMDKETYPE_VMFS:
- case VMDKETYPE_FLAT:
- /* Nothing to do. */
- break;
- case VMDKETYPE_ZERO:
- default:
- AssertMsgFailed(("extent with type %d marked as dirty\n",
- pExtent->enmType));
- break;
- }
- }
- switch (pExtent->enmType)
- {
- case VMDKETYPE_HOSTED_SPARSE:
-#ifdef VBOX_WITH_VMDK_ESX
- case VMDKETYPE_ESX_SPARSE:
-#endif /* VBOX_WITH_VMDK_ESX */
- case VMDKETYPE_VMFS:
- case VMDKETYPE_FLAT:
- /** @todo implement proper path absolute check. */
- if ( pExtent->pFile != NULL
- && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
- && !(pExtent->pszBasename[0] == RTPATH_SLASH))
- rc = vmdkFileFlushAsync(pImage, pExtent->pFile, pIoCtx);
- break;
- case VMDKETYPE_ZERO:
- /* No need to do anything for this extent. */
- break;
- default:
- AssertMsgFailed(("unknown extent type %d\n", pExtent->enmType));
- break;
- }
- }
-
-out:
- return rc;
-}
-
-/**
* Internal. Find extent corresponding to the sector number in the disk.
*/
static int vmdkFindExtent(PVMDKIMAGE pImage, uint64_t offSector,
@@ -5823,7 +5760,7 @@ static int vmdkCreate(const char *pszFilename, uint64_t cbSize,
PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage,
PVDINTERFACE pVDIfsOperation, void **ppBackendData)
{
- LogFlowFunc(("pszFilename=\"%s\" cbSize=%llu uImageFlags=%#x pszComment=\"%s\" pPCHSGeometry=%#p pLCHSGeometry=%#p Uuid=%RTuuid uOpenFlags=%#x uPercentStart=%u uPercentSpan=%u pVDIfsDisk=%#p pVDIfsImage=%#p pVDIfsOperation=%#p ppBackendData=%#p", pszFilename, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, ppBackendData));
+ LogFlowFunc(("pszFilename=\"%s\" cbSize=%llu uImageFlags=%#x pszComment=\"%s\" pPCHSGeometry=%#p pLCHSGeometry=%#p Uuid=%RTuuid uOpenFlags=%#x uPercentStart=%u uPercentSpan=%u pVDIfsDisk=%#p pVDIfsImage=%#p pVDIfsOperation=%#p ppBackendData=%#p\n", pszFilename, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, ppBackendData));
int rc;
PVMDKIMAGE pImage;
@@ -6699,7 +6636,7 @@ static unsigned vmdkGetOpenFlags(void *pBackendData)
/** @copydoc VBOXHDDBACKEND::pfnSetOpenFlags */
static int vmdkSetOpenFlags(void *pBackendData, unsigned uOpenFlags)
{
- LogFlowFunc(("pBackendData=%#p\n uOpenFlags=%#x", pBackendData, uOpenFlags));
+ LogFlowFunc(("pBackendData=%#p uOpenFlags=%#x\n", pBackendData, uOpenFlags));
PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
int rc;
@@ -7046,15 +6983,6 @@ static void vmdkDump(void *pBackendData)
}
}
-/** @copydoc VBOXHDDBACKEND::pfnIsAsyncIOSupported */
-static bool vmdkIsAsyncIOSupported(void *pBackendData)
-{
- PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
-
- /* We do not support async I/O for stream optimized VMDK images. */
- return (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED) == 0;
-}
-
/** @copydoc VBOXHDDBACKEND::pfnAsyncRead */
static int vmdkAsyncRead(void *pBackendData, uint64_t uOffset, size_t cbRead,
PVDIOCTX pIoCtx, size_t *pcbActuallyRead)
@@ -7271,6 +7199,20 @@ static int vmdkAsyncFlush(void *pBackendData, PVDIOCTX pIoCtx)
PVMDKEXTENT pExtent;
int rc = VINF_SUCCESS;
+ /* Update descriptor if changed. */
+ /** @todo: The descriptor is never updated because
+ * it remains unchanged during normal operation (only vmdkRename updates it).
+ * So this part is actually not tested so far and requires testing as soon
+ * as the descriptor might change during async I/O.
+ */
+ if (pImage->Descriptor.fDirty)
+ {
+ rc = vmdkWriteDescriptorAsync(pImage, pIoCtx);
+ if ( RT_FAILURE(rc)
+ && rc != VERR_VD_ASYNC_IO_IN_PROGRESS)
+ goto out;
+ }
+
for (unsigned i = 0; i < pImage->cExtents; i++)
{
pExtent = &pImage->pExtents[i];
@@ -7427,8 +7369,6 @@ VBOXHDDBACKEND g_VmdkBackend =
NULL,
/* pfnSetParentFilename */
NULL,
- /* pfnIsAsyncIOSupported */
- vmdkIsAsyncIOSupported,
/* pfnAsyncRead */
vmdkAsyncRead,
/* pfnAsyncWrite */
diff --git a/src/VBox/Storage/testcase/Makefile.kmk b/src/VBox/Storage/testcase/Makefile.kmk
index 4e023a10d..455406dc0 100644
--- a/src/VBox/Storage/testcase/Makefile.kmk
+++ b/src/VBox/Storage/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37235 2011-05-27 14:50:02Z vboxsync $
## @file
# Sub-Makefile for the storage device & driver testcases.
#
@@ -25,7 +25,7 @@ include $(KBUILD_PATH)/subheader.kmk
ifdef VBOX_WITH_TESTCASES
PROGRAMS += vditool
vditool_TEMPLATE = VBOXR3TSTEXE
- vditool_LIBS = $(LIB_DDU) $(LIB_RUNTIME)
+ vditool_LIBS = $(LIB_DDU)
vditool_SOURCES = vditool.cpp
endif
@@ -34,20 +34,53 @@ endif
#
ifdef VBOX_WITH_TESTCASES
PROGRAMS += tstVD tstVD-2 tstVDCopy tstVDSnap tstVDShareable vbox-img tstVDIo
+
tstVD_TEMPLATE = VBOXR3TSTEXE
+ tstVD_SOURCES = tstVD.cpp
+ tstVD_LIBS = $(LIB_DDU)
+
tstVD-2_TEMPLATE = VBOXR3TSTEXE
+ tstVD-2_SOURCES = tstVD-2.cpp
+ tstVD-2_LIBS = $(LIB_DDU)
+
tstVDCopy_TEMPLATE = VBOXR3TSTEXE
- tstVDSnap_TEMPLATE = VBOXR3TSTEXE
- tstVDShareable_TEMPLATE = VBOXR3TSTEXE
+ tstVDCopy_SOURCES = tstVDCopy.cpp
+ tstVDCopy_LIBS = $(LIB_DDU)
+
tstVDIo_TEMPLATE = VBOXR3TSTEXE
+ tstVDIo_SOURCES = tstVDIo.cpp \
+ VDIoBackendMem.cpp \
+ VDMemDisk.cpp \
+ VDIoRnd.cpp
+ tstVDIo_LIBS = $(LIB_DDU)
+
+ tstVDSetUuid_TEMPLATE = VBOXR3TSTEXE
+ tstVDSetUuid_LIBS = $(LIB_DDU)
+
+ tstVDShareable_TEMPLATE = VBOXR3TSTEXE
+ tstVDShareable_LIBS = $(LIB_DDU)
+ tstVDShareable_SOURCES = tstVDShareable.cpp
+
+ tstVDSnap_TEMPLATE = VBOXR3TSTEXE
+ tstVDSnap_LIBS = $(LIB_DDU)
+ tstVDSnap_SOURCES = tstVDSnap.cpp
+
+ #
+ # vbox-img - static because it migth be used as at standalone tool.
+ #
vbox-img_TEMPLATE = VBOXR3STATIC
- tstVD_LIBS = $(LIB_DDU) $(LIB_RUNTIME)
- tstVD-2_LIBS = $(LIB_DDU) $(LIB_RUNTIME)
- tstVDCopy_LIBS = $(LIB_DDU) $(LIB_RUNTIME)
- tstVDSnap_LIBS = $(LIB_DDU) $(LIB_RUNTIME)
- tstVDShareable_LIBS = $(LIB_DDU) $(LIB_RUNTIME)
- tstVDSetUuid_LIBS = $(LIB_DDU) $(LIB_RUNTIME)
- tstVDIo_LIBS = $(LIB_DDU) $(LIB_RUNTIME)
+ vbox-img_DEFS += IN_VBOXDDU IN_VBOXDDU_STATIC VBOX_HDD_NO_DYNAMIC_BACKENDS IN_RT_R3
+ vbox-img_SOURCES = \
+ vbox-img.cpp \
+ $(VBOX_PATH_STORAGE_SRC)/VD.cpp \
+ $(VBOX_PATH_STORAGE_SRC)/VDI.cpp \
+ $(VBOX_PATH_STORAGE_SRC)/VMDK.cpp \
+ $(VBOX_PATH_STORAGE_SRC)/VHD.cpp \
+ $(VBOX_PATH_STORAGE_SRC)/DMG.cpp \
+ $(VBOX_PATH_STORAGE_SRC)/Parallels.cpp \
+ $(VBOX_PATH_STORAGE_SRC)/ISCSI.cpp \
+ $(VBOX_PATH_STORAGE_SRC)/RAW.cpp \
+ $(VBOX_PATH_STORAGE_SRC)/VCICache.cpp
vbox-img_LIBS = \
$(VBOX_LIB_RUNTIME_STATIC)
if1of ($(KBUILD_TARGET),os2 win)
@@ -66,29 +99,7 @@ ifdef VBOX_WITH_TESTCASES
else ifeq ($(KBUILD_TARGET),win)
vbox-img_SDKS.win = VBOX_NTDLL
endif
- tstVD_SOURCES = tstVD.cpp
- tstVD-2_SOURCES = tstVD-2.cpp
- tstVDCopy_SOURCES = tstVDCopy.cpp
- tstVDSnap_SOURCES = tstVDSnap.cpp
- tstVDShareable_SOURCES = tstVDShareable.cpp
-
- vbox-img_SOURCES = \
- vbox-img.cpp \
- $(VBOX_PATH_STORAGE_SRC)/VD.cpp \
- $(VBOX_PATH_STORAGE_SRC)/VDI.cpp \
- $(VBOX_PATH_STORAGE_SRC)/VMDK.cpp \
- $(VBOX_PATH_STORAGE_SRC)/VHD.cpp \
- $(VBOX_PATH_STORAGE_SRC)/DMG.cpp \
- $(VBOX_PATH_STORAGE_SRC)/Parallels.cpp \
- $(VBOX_PATH_STORAGE_SRC)/ISCSI.cpp \
- $(VBOX_PATH_STORAGE_SRC)/RAW.cpp \
- $(VBOX_PATH_STORAGE_SRC)/VCICache.cpp
- vbox-img_DEFS += IN_VBOXDDU IN_VBOXDDU_STATIC VBOX_HDD_NO_DYNAMIC_BACKENDS IN_RT_R3
- tstVDIo_SOURCES = tstVDIo.cpp \
- VDIoBackendMem.cpp \
- VDMemDisk.cpp \
- VDIoRnd.cpp
endif
include $(KBUILD_PATH)/subfooter.kmk
diff --git a/src/VBox/Storage/testcase/VDIoBackendMem.cpp b/src/VBox/Storage/testcase/VDIoBackendMem.cpp
index 70696d4d3..ccd3bfd27 100644
--- a/src/VBox/Storage/testcase/VDIoBackendMem.cpp
+++ b/src/VBox/Storage/testcase/VDIoBackendMem.cpp
@@ -1,4 +1,4 @@
-/** $Id: VDIoBackendMem.cpp $ */
+/** $Id: VDIoBackendMem.cpp 36131 2011-03-02 21:56:42Z vboxsync $ */
/** @file
*
* VBox HDD container test utility, async I/O memory backend
@@ -53,6 +53,8 @@ typedef struct VDIOBACKENDREQ
RTSGSEG aSegs[1];
} VDIOBACKENDREQ, *PVDIOBACKENDREQ;
+typedef PVDIOBACKENDREQ *PPVDIOBACKENDREQ;
+
/**
* I/O memory backend
*/
@@ -68,6 +70,8 @@ typedef struct VDIOBACKENDMEM
RTSEMEVENT EventSem;
/** Flag whether the the server should be still running. */
volatile bool fRunning;
+ /** Number of requests waiting in the request buffer. */
+ volatile uint32_t cReqsWaiting;
} VDIOBACKENDMEM;
static int vdIoBackendMemThread(RTTHREAD hThread, void *pvUser);
@@ -92,7 +96,7 @@ int VDIoBackendMemCreate(PPVDIOBACKENDMEM ppIoBackend)
pIoBackend = (PVDIOBACKENDMEM)RTMemAllocZ(sizeof(VDIOBACKENDMEM));
if (pIoBackend)
{
- rc = RTCircBufCreate(&pIoBackend->pRequestRing, VDMEMIOBACKEND_REQS * sizeof(VDIOBACKENDREQ));
+ rc = RTCircBufCreate(&pIoBackend->pRequestRing, VDMEMIOBACKEND_REQS * sizeof(PVDIOBACKENDREQ));
if (RT_SUCCESS(rc))
{
pIoBackend->cReqsRing = VDMEMIOBACKEND_REQS * sizeof(VDIOBACKENDREQ);
@@ -142,13 +146,23 @@ int VDIoBackendMemTransfer(PVDIOBACKENDMEM pIoBackend, PVDMEMDISK pMemDisk,
unsigned cSegs, PFNVDIOCOMPLETE pfnComplete, void *pvUser)
{
PVDIOBACKENDREQ pReq = NULL;
+ PPVDIOBACKENDREQ ppReq = NULL;
size_t cbData;
- RTCircBufAcquireWriteBlock(pIoBackend->pRequestRing, RT_OFFSETOF(VDIOBACKENDREQ, aSegs[cSegs]), (void **)&pReq, &cbData);
+ LogFlowFunc(("Queuing request\n"));
+
+ pReq = (PVDIOBACKENDREQ)RTMemAlloc(RT_OFFSETOF(VDIOBACKENDREQ, aSegs[cSegs]));
if (!pReq)
return VERR_NO_MEMORY;
- Assert(cbData == sizeof(VDIOBACKENDREQ));
+ RTCircBufAcquireWriteBlock(pIoBackend->pRequestRing, sizeof(PVDIOBACKENDREQ), (void **)&ppReq, &cbData);
+ if (!pReq)
+ {
+ RTMemFree(pReq);
+ return VERR_NO_MEMORY;
+ }
+
+ Assert(cbData == sizeof(PVDIOBACKENDREQ));
pReq->enmTxDir = enmTxDir;
pReq->cbTransfer = cbTransfer;
pReq->off = off;
@@ -161,8 +175,12 @@ int VDIoBackendMemTransfer(PVDIOBACKENDMEM pIoBackend, PVDMEMDISK pMemDisk,
pReq->aSegs[i].pvSeg = paSegs[i].pvSeg;
pReq->aSegs[i].cbSeg = paSegs[i].cbSeg;
}
- RTCircBufReleaseWriteBlock(pIoBackend->pRequestRing, sizeof(VDIOBACKENDREQ));
- vdIoBackendMemThreadPoke(pIoBackend);
+
+ *ppReq = pReq;
+ RTCircBufReleaseWriteBlock(pIoBackend->pRequestRing, sizeof(PVDIOBACKENDREQ));
+ uint32_t cReqsWaiting = ASMAtomicIncU32(&pIoBackend->cReqsWaiting);
+ if (cReqsWaiting == 1)
+ vdIoBackendMemThreadPoke(pIoBackend);
return VINF_SUCCESS;
}
@@ -186,15 +204,23 @@ static int vdIoBackendMemThread(RTTHREAD hThread, void *pvUser)
break;
PVDIOBACKENDREQ pReq;
+ PPVDIOBACKENDREQ ppReq;
size_t cbData;
+ uint32_t cReqsWaiting = ASMAtomicXchgU32(&pIoBackend->cReqsWaiting, 0);
- RTCircBufAcquireReadBlock(pIoBackend->pRequestRing, sizeof(VDIOBACKENDREQ), (void **)&pReq, &cbData);
- Assert(!pReq || cbData == sizeof(VDIOBACKENDREQ));
-
- while (pReq)
+ while (cReqsWaiting)
{
int rcReq = VINF_SUCCESS;
+ /* Do we have another request? */
+ RTCircBufAcquireReadBlock(pIoBackend->pRequestRing, sizeof(PVDIOBACKENDREQ), (void **)&ppReq, &cbData);
+ Assert(!ppReq || cbData == sizeof(PVDIOBACKENDREQ));
+ RTCircBufReleaseReadBlock(pIoBackend->pRequestRing, cbData);
+
+ pReq = *ppReq;
+ cReqsWaiting--;
+
+ LogFlowFunc(("Processing request\n"));
switch (pReq->enmTxDir)
{
case VDIOTXDIR_READ:
@@ -219,12 +245,7 @@ static int vdIoBackendMemThread(RTTHREAD hThread, void *pvUser)
/* Notify completion. */
pReq->pfnComplete(pReq->pvUser, rcReq);
-
- RTCircBufReleaseReadBlock(pIoBackend->pRequestRing, cbData);
-
- /* Do we have another request? */
- RTCircBufAcquireReadBlock(pIoBackend->pRequestRing, sizeof(VDIOBACKENDREQ), (void **)&pReq, &cbData);
- Assert(!pReq || cbData == sizeof(VDIOBACKENDREQ));
+ RTMemFree(pReq);
}
}
diff --git a/src/VBox/Storage/testcase/VDIoBackendMem.h b/src/VBox/Storage/testcase/VDIoBackendMem.h
index 89b16dc10..fc65972c3 100644
--- a/src/VBox/Storage/testcase/VDIoBackendMem.h
+++ b/src/VBox/Storage/testcase/VDIoBackendMem.h
@@ -1,4 +1,4 @@
-/** $Id: VDIoBackendMem.h $ */
+/** $Id: VDIoBackendMem.h 35471 2011-01-10 21:10:19Z vboxsync $ */
/** @file
*
* VBox HDD container test utility, async I/O memory backend
diff --git a/src/VBox/Storage/testcase/VDIoRnd.cpp b/src/VBox/Storage/testcase/VDIoRnd.cpp
index e3a50358f..e5f915dd9 100644
--- a/src/VBox/Storage/testcase/VDIoRnd.cpp
+++ b/src/VBox/Storage/testcase/VDIoRnd.cpp
@@ -1,5 +1,5 @@
+/* $Id: VDIoRnd.cpp 36529 2011-04-04 13:54:13Z vboxsync $ */
/** @file
- *
* VBox HDD container test utility - I/O data generator.
*/
@@ -14,11 +14,13 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
+
#define LOGGROUP LOGGROUP_DEFAULT
#include <iprt/log.h>
#include <iprt/err.h>
#include <iprt/mem.h>
#include <iprt/rand.h>
+#include <iprt/assert.h>
#include "VDIoRnd.h"
diff --git a/src/VBox/Storage/testcase/VDMemDisk.cpp b/src/VBox/Storage/testcase/VDMemDisk.cpp
index 12f4b1efb..29e8872ee 100644
--- a/src/VBox/Storage/testcase/VDMemDisk.cpp
+++ b/src/VBox/Storage/testcase/VDMemDisk.cpp
@@ -1,4 +1,4 @@
-/** $Id: VDMemDisk.cpp $ */
+/** $Id: VDMemDisk.cpp 36635 2011-04-08 23:25:37Z vboxsync $ */
/** @file
*
* VBox HDD container test utility, memory disk/file.
@@ -249,10 +249,15 @@ int VDMemDiskSetSize(PVDMEMDISK pMemDisk, uint64_t cbSize)
PVDMEMDISKSEG pSeg = (PVDMEMDISKSEG)RTAvlrU64Get(pMemDisk->pTreeSegments, cbSize);
if (pSeg)
{
+ RTAvlrU64Remove(pMemDisk->pTreeSegments, pSeg->Core.Key);
if (pSeg->Core.Key < cbSize)
{
/* Cut off the part which is not in the file anymore. */
pSeg->pvSeg = RTMemRealloc(pSeg->pvSeg, pSeg->Core.KeyLast - cbSize + 1);
+ pSeg->Core.KeyLast = cbSize - pSeg->Core.Key - 1;
+
+ bool fInserted = RTAvlrU64Insert(pMemDisk->pTreeSegments, &pSeg->Core);
+ AssertMsg(fInserted, ("Bug!\n"));
}
else
{
@@ -337,3 +342,65 @@ int VDMemDiskReadFromFile(PVDMEMDISK pMemDisk, const char *pcszFilename)
return VERR_NOT_IMPLEMENTED;
}
+int VDMemDiskCmp(PVDMEMDISK pMemDisk, uint64_t off, size_t cbCmp, PRTSGBUF pSgBuf)
+{
+ LogFlowFunc(("pMemDisk=%#p off=%llx cbCmp=%u pSgBuf=%#p\n",
+ pMemDisk, off, cbCmp, pSgBuf));
+
+ /* Compare data */
+ size_t cbLeft = cbCmp;
+ uint64_t offCurr = off;
+
+ while (cbLeft)
+ {
+ PVDMEMDISKSEG pSeg = (PVDMEMDISKSEG)RTAvlrU64Get(pMemDisk->pTreeSegments, offCurr);
+ size_t cbRange = 0;
+ bool fCmp = false;
+ unsigned offSeg = 0;
+
+ if (!pSeg)
+ {
+ /* Get next segment */
+ pSeg = (PVDMEMDISKSEG)RTAvlrU64GetBestFit(pMemDisk->pTreeSegments, offCurr, true);
+ if (!pSeg)
+ {
+ /* No data in the tree for this read. Assume everything is ok. */
+ cbRange = cbLeft;
+ }
+ else if (offCurr + cbLeft <= pSeg->Core.Key)
+ cbRange = cbLeft;
+ else
+ cbRange = pSeg->Core.Key - offCurr;
+ }
+ else
+ {
+ fCmp = true;
+ offSeg = offCurr - pSeg->Core.Key;
+ cbRange = RT_MIN(cbLeft, (size_t)(pSeg->Core.KeyLast + 1 - offCurr));
+ }
+
+ if (fCmp)
+ {
+ RTSGSEG Seg;
+ RTSGBUF SgBufCmp;
+ size_t cbOff = 0;
+ int rc = 0;
+
+ Seg.cbSeg = cbRange;
+ Seg.pvSeg = (uint8_t *)pSeg->pvSeg + offSeg;
+
+ RTSgBufInit(&SgBufCmp, &Seg, 1);
+ rc = RTSgBufCmpEx(pSgBuf, &SgBufCmp, cbRange, &cbOff, true);
+ if (rc)
+ return rc;
+ }
+ else
+ RTSgBufAdvance(pSgBuf, cbRange);
+
+ offCurr += cbRange;
+ cbLeft -= cbRange;
+ }
+
+ return 0;
+}
+
diff --git a/src/VBox/Storage/testcase/VDMemDisk.h b/src/VBox/Storage/testcase/VDMemDisk.h
index 01a144f89..5947abbe3 100644
--- a/src/VBox/Storage/testcase/VDMemDisk.h
+++ b/src/VBox/Storage/testcase/VDMemDisk.h
@@ -114,4 +114,16 @@ int VDMemDiskWriteToFile(PVDMEMDISK pMemDisk, const char *pcszFilename);
*/
int VDMemDiskReadFromFile(PVDMEMDISK pMemDisk, const char *pcszFilename);
+/**
+ * Compares the given range of the memory disk with a provided S/G buffer.
+ *
+ * @returns whatever memcmp returns.
+ *
+ * @param pMemDisk The memory disk handle.
+ * @param off Where to start comparing.
+ * @param cbCmp How many bytes to compare.
+ * @param pSgBuf The S/G buffer to compare with.
+ */
+int VDMemDiskCmp(PVDMEMDISK pMemDisk, uint64_t off, size_t cbCmp, PRTSGBUF pSgBuf);
+
#endif /* __VDMemDisk_h__ */
diff --git a/src/VBox/Storage/testcase/tstVD.cpp b/src/VBox/Storage/testcase/tstVD.cpp
index 0ec5d4e58..4e3a63b27 100644
--- a/src/VBox/Storage/testcase/tstVD.cpp
+++ b/src/VBox/Storage/testcase/tstVD.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstVD.cpp $ */
+/* $Id: tstVD.cpp 33567 2010-10-28 15:37:21Z vboxsync $ */
/** @file
* Simple VBox HDD container test utility.
*/
diff --git a/src/VBox/Storage/testcase/tstVDCompact.vd b/src/VBox/Storage/testcase/tstVDCompact.vd
new file mode 100644
index 000000000..8c5eed189
--- /dev/null
+++ b/src/VBox/Storage/testcase/tstVDCompact.vd
@@ -0,0 +1,77 @@
+# $Id: tstVDCompact.vd 36637 2011-04-09 12:17:40Z vboxsync $
+#
+# Storage: Testcase for compacting disks.
+#
+
+#
+# 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.
+#
+
+# Init I/O RNG for generating random data for writes
+iorngcreate size=10M mode=manual seed=1234567890
+
+# Create zero pattern
+iopatterncreatefromnumber name=zero size=1M pattern=0
+
+print msg=Testing_VDI
+# Create disk containers, read verification is on.
+createdisk name=disk verify=yes
+# Create the disk.
+create disk=disk mode=base name=tstCompact.vdi type=dynamic backend=VDI size=200M
+# Fill the disk with random data
+io disk=disk async=no mode=seq blocksize=64k off=0-200M size=200M writes=100
+# Read the data to verify it once.
+io disk=disk async=no mode=seq blocksize=64k off=0-200M size=200M writes=0
+# Fill a part with 0's
+io disk=disk async=no mode=seq blocksize=64k off=100M-150M size=50M writes=100 pattern=zero
+# Now compact
+compact disk=disk image=0
+# Read again to verify that the content hasn't changed
+io disk=disk async=no mode=seq blocksize=64k off=0-200M size=200M writes=0
+# Fill everything with 0
+io disk=disk async=no mode=seq blocksize=64k off=0M-200M size=200M writes=100 pattern=zero
+# Now compact
+compact disk=disk image=0
+# Read again to verify that the content hasn't changed
+io disk=disk async=no mode=seq blocksize=64k off=0-200M size=200M writes=0
+# Cleanup
+close disk=disk mode=single delete=yes
+destroydisk name=disk
+
+print msg=Testing_VHD
+# Create disk containers, read verification is on.
+createdisk name=disk verify=yes
+# Create the disk.
+create disk=disk mode=base name=tstCompact.vhd type=dynamic backend=VHD size=200M
+# Fill the disk with random data
+io disk=disk async=no mode=seq blocksize=64k off=0-200M size=200M writes=100
+# Read the data to verify it once.
+io disk=disk async=no mode=seq blocksize=64k off=0-200M size=200M writes=0
+# Fill a part with 0's
+io disk=disk async=no mode=seq blocksize=64k off=100M-150M size=50M writes=100 pattern=zero
+# Now compact
+compact disk=disk image=0
+# Read again to verify that the content hasn't changed
+io disk=disk async=no mode=seq blocksize=64k off=0-200M size=200M writes=0
+# Fill everything with 0
+io disk=disk async=no mode=seq blocksize=64k off=0M-200M size=200M writes=100 pattern=zero
+# Now compact
+compact disk=disk image=0
+# Read again to verify that the content hasn't changed
+io disk=disk async=no mode=seq blocksize=64k off=0-200M size=200M writes=0
+# Cleanup
+close disk=disk mode=single delete=yes
+destroydisk name=disk
+
+# Destroy RNG and pattern
+iopatterndestroy name=zero
+iorngdestroy
+
diff --git a/src/VBox/Storage/testcase/tstVDIo.cpp b/src/VBox/Storage/testcase/tstVDIo.cpp
index 236711091..c8c1286f9 100644
--- a/src/VBox/Storage/testcase/tstVDIo.cpp
+++ b/src/VBox/Storage/testcase/tstVDIo.cpp
@@ -1,3 +1,4 @@
+/* $Id: tstVDIo.cpp 37308 2011-06-02 12:53:10Z vboxsync $ */
/** @file
*
* VBox HDD container test utility - I/O replay.
@@ -28,6 +29,8 @@
#include <iprt/ctype.h>
#include <iprt/semaphore.h>
#include <iprt/thread.h>
+#include <iprt/rand.h>
+#include <iprt/critsect.h>
#include "VDMemDisk.h"
#include "VDIoBackendMem.h"
@@ -44,19 +47,70 @@ typedef struct VDFILE
char *pszName;
/** Memory file baking the file. */
PVDMEMDISK pMemDisk;
+ /** Flag whether the file is read locked. */
+ bool fReadLock;
+ /** Flag whether the file is write locked. */
+ bool fWriteLock;
+} VDFILE, *PVDFILE;
+
+/**
+ * VD storage object.
+ */
+typedef struct VDSTORAGE
+{
+ /** Pointer to the file. */
+ PVDFILE pFile;
/** Completion callback of the VD layer. */
PFNVDCOMPLETED pfnComplete;
-} VDFILE, *PVDFILE;
+} VDSTORAGE, *PVDSTORAGE;
+
+/**
+ * A virtual disk.
+ */
+typedef struct VDDISK
+{
+ /** List node. */
+ RTLISTNODE ListNode;
+ /** Name of the disk handle for identification. */
+ char *pszName;
+ /** HDD handle to operate on. */
+ PVBOXHDD pVD;
+ /** Memory disk used for data verification. */
+ PVDMEMDISK pMemDiskVerify;
+ /** Critical section to serialize access to the memory disk. */
+ RTCRITSECT CritSectVerify;
+ /** Physical CHS Geometry. */
+ VDGEOMETRY PhysGeom;
+ /** Logical CHS geometry. */
+ VDGEOMETRY LogicalGeom;
+} VDDISK, *PVDDISK;
+
+/**
+ * A data buffer with a pattern.
+ */
+typedef struct VDPATTERN
+{
+ /** List node. */
+ RTLISTNODE ListNode;
+ /** Name of the pattern. */
+ char *pszName;
+ /** Size of the pattern. */
+ size_t cbPattern;
+ /** Pointer to the buffer containing the pattern. */
+ void *pvPattern;
+} VDPATTERN, *PVDPATTERN;
/**
* Global VD test state.
*/
typedef struct VDTESTGLOB
{
- /** HDD handle to operate on. */
- PVBOXHDD pVD;
+ /** List of active virtual disks. */
+ RTLISTNODE ListDisks;
/** Head of the active file list. */
RTLISTNODE ListFiles;
+ /** Head of the pattern list. */
+ RTLISTNODE ListPatterns;
/** Memory I/O backend. */
PVDIOBACKENDMEM pIoBackend;
/** Error interface. */
@@ -71,10 +125,6 @@ typedef struct VDTESTGLOB
VDINTERFACEIO VDIIoCallbacks;
/** Pointer to the per image interface list. */
PVDINTERFACE pInterfacesImages;
- /** Physical CHS Geometry. */
- VDGEOMETRY PhysGeom;
- /** Logical CHS geometry. */
- VDGEOMETRY LogicalGeom;
/** I/O RNG handle. */
PVDIORND pIoRnd;
} VDTESTGLOB, *PVDTESTGLOB;
@@ -108,6 +158,10 @@ typedef struct VDIOREQ
RTSGSEG DataSeg;
/** Flag whether the request is outstanding or not. */
volatile bool fOutstanding;
+ /** Buffer to use for reads. */
+ void *pvBufRead;
+ /** Opaque user data. */
+ void *pvUser;
} VDIOREQ, *PVDIOREQ;
/**
@@ -124,10 +178,29 @@ typedef struct VDIOTEST
/** Block size. */
size_t cbBlkIo;
/** Number of bytes to transfer. */
- size_t cbIo;
+ uint64_t cbIo;
+ /** Chance in percent to get a write. */
unsigned uWriteChance;
+ /** Pointer to the I/O data generator. */
PVDIORND pIoRnd;
- uint64_t offNext;
+ /** Pointer to the data pattern to use. */
+ PVDPATTERN pPattern;
+ /** Data dependent on the I/O mode (sequential or random). */
+ union
+ {
+ /** Next offset for sequential access. */
+ uint64_t offNext;
+ /** Data for random acess. */
+ struct
+ {
+ /** Number of valid entries in the bitmap. */
+ uint32_t cBlocks;
+ /** Pointer to the bitmap marking accessed blocks. */
+ uint8_t *pbMapAccessed;
+ /** Number of unaccessed blocks. */
+ uint32_t cBlocksLeft;
+ } Rnd;
+ } u;
} VDIOTEST, *PVDIOTEST;
/**
@@ -225,92 +298,200 @@ static DECLCALLBACK(int) vdScriptHandlerOpen(PVDTESTGLOB pGlob, PVDSCRIPTARG paS
static DECLCALLBACK(int) vdScriptHandlerIo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
static DECLCALLBACK(int) vdScriptHandlerFlush(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
static DECLCALLBACK(int) vdScriptHandlerMerge(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
+static DECLCALLBACK(int) vdScriptHandlerCompact(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
static DECLCALLBACK(int) vdScriptHandlerClose(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
static DECLCALLBACK(int) vdScriptHandlerIoRngCreate(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
static DECLCALLBACK(int) vdScriptHandlerIoRngDestroy(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
+static DECLCALLBACK(int) vdScriptHandlerIoPatternCreateFromNumber(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
+static DECLCALLBACK(int) vdScriptHandlerIoPatternCreateFromFile(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
+static DECLCALLBACK(int) vdScriptHandlerIoPatternDestroy(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
static DECLCALLBACK(int) vdScriptHandlerSleep(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
+static DECLCALLBACK(int) vdScriptHandlerDumpFile(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
+static DECLCALLBACK(int) vdScriptHandlerCreateDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
+static DECLCALLBACK(int) vdScriptHandlerDestroyDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
+static DECLCALLBACK(int) vdScriptHandlerCompareDisks(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
+static DECLCALLBACK(int) vdScriptHandlerDumpDiskInfo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
+static DECLCALLBACK(int) vdScriptHandlerPrintMsg(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
/* create action */
const VDSCRIPTARGDESC g_aArgCreate[] =
{
- /* pcszName chId enmType fFlags */
- {"mode", 'm', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
- {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
- {"backend", 'b', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
- {"size", 's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
+ /* pcszName chId enmType fFlags */
+ {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"mode", 'm', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"type", 't', VDSCRIPTARGTYPE_STRING, 0},
+ {"backend", 'b', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"size", 's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX}
};
/* open action */
const VDSCRIPTARGDESC g_aArgOpen[] =
{
- /* pcszName chId enmType fFlags */
- {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
- {"backend", 'b', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}
+ /* pcszName chId enmType fFlags */
+ {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"backend", 'b', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"shareable", 's', VDSCRIPTARGTYPE_BOOL, 0},
+ {"readonly", 'r', VDSCRIPTARGTYPE_BOOL, 0}
};
-/* write action */
+/* I/O action */
const VDSCRIPTARGDESC g_aArgIo[] =
{
/* pcszName chId enmType fFlags */
+ {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
{"async", 'a', VDSCRIPTARGTYPE_BOOL, 0},
{"max-reqs", 'l', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, 0},
{"mode", 'm', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
{"size", 's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
{"blocksize", 'b', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
{"off", 'o', VDSCRIPTARGTYPE_UNSIGNED_RANGE, VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
- {"reads", 'r', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
- {"writes", 'w', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY}
+ {"writes", 'w', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"pattern", 'p', VDSCRIPTARGTYPE_STRING, 0},
};
/* flush action */
const VDSCRIPTARGDESC g_aArgFlush[] =
{
- /* pcszName chId enmType fFlags */
- {"async", 'a', VDSCRIPTARGTYPE_BOOL, 0}
+ /* pcszName chId enmType fFlags */
+ {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"async", 'a', VDSCRIPTARGTYPE_BOOL, 0}
};
/* merge action */
const VDSCRIPTARGDESC g_aArgMerge[] =
{
- /* pcszName chId enmType fFlags */
- {"forward", 'f', VDSCRIPTARGTYPE_BOOL, VDSCRIPTARGDESC_FLAG_MANDATORY}
+ /* pcszName chId enmType fFlags */
+ {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"from", 'f', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"to", 't', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
+};
+
+/* Compact a disk */
+const VDSCRIPTARGDESC g_aArgCompact[] =
+{
+ /* pcszName chId enmType fFlags */
+ {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"image", 'i', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
};
/* close action */
const VDSCRIPTARGDESC g_aArgClose[] =
{
- /* pcszName chId enmType fFlags */
- {"mode", 'm', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
- {"delete", 'd', VDSCRIPTARGTYPE_BOOL, VDSCRIPTARGDESC_FLAG_MANDATORY}
+ /* pcszName chId enmType fFlags */
+ {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"mode", 'm', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"delete", 'r', VDSCRIPTARGTYPE_BOOL, VDSCRIPTARGDESC_FLAG_MANDATORY}
};
/* I/O RNG create action */
const VDSCRIPTARGDESC g_aArgIoRngCreate[] =
{
- /* pcszName chId enmType fFlags */
- {"size", 'd', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
- {"seed", 's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY}
+ /* pcszName chId enmType fFlags */
+ {"size", 'd', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
+ {"mode", 'm', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"seed", 's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, 0}
+};
+
+/* I/O pattern create action */
+const VDSCRIPTARGDESC g_aArgIoPatternCreateFromNumber[] =
+{
+ /* pcszName chId enmType fFlags */
+ {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"size", 's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
+ {"pattern", 'p', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
+};
+
+/* I/O pattern create action */
+const VDSCRIPTARGDESC g_aArgIoPatternCreateFromFile[] =
+{
+ /* pcszName chId enmType fFlags */
+ {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"file", 'f', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+};
+
+/* I/O pattern destroy action */
+const VDSCRIPTARGDESC g_aArgIoPatternDestroy[] =
+{
+ /* pcszName chId enmType fFlags */
+ {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}
};
/* Sleep */
const VDSCRIPTARGDESC g_aArgSleep[] =
{
- /* pcszName chId enmType fFlags */
- {"time", 't', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ /* pcszName chId enmType fFlags */
+ {"time", 't', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY}
+};
+
+/* Dump memory file */
+const VDSCRIPTARGDESC g_aArgDumpFile[] =
+{
+ /* pcszName chId enmType fFlags */
+ {"file", 'f', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"path", 'p', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}
+};
+
+/* Create virtual disk handle */
+const VDSCRIPTARGDESC g_aArgCreateDisk[] =
+{
+ /* pcszName chId enmType fFlags */
+ {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"verify", 'v', VDSCRIPTARGTYPE_BOOL, 0}
+};
+
+/* Create virtual disk handle */
+const VDSCRIPTARGDESC g_aArgDestroyDisk[] =
+{
+ /* pcszName chId enmType fFlags */
+ {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}
+};
+
+/* Compare virtual disks */
+const VDSCRIPTARGDESC g_aArgCompareDisks[] =
+{
+ /* pcszName chId enmType fFlags */
+ {"disk1", '1', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+ {"disk2", '2', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}
+};
+
+/* Dump disk info */
+const VDSCRIPTARGDESC g_aArgDumpDiskInfo[] =
+{
+ /* pcszName chId enmType fFlags */
+ {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
+};
+
+/* Print message */
+const VDSCRIPTARGDESC g_aArgPrintMsg[] =
+{
+ /* pcszName chId enmType fFlags */
+ {"msg", 'm', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY},
};
const VDSCRIPTACTION g_aScriptActions[] =
{
- /* pcszAction paArgDesc cArgDescs pfnHandler */
- {"create", g_aArgCreate, RT_ELEMENTS(g_aArgCreate), vdScriptHandlerCreate},
- {"open", g_aArgOpen, RT_ELEMENTS(g_aArgOpen), vdScriptHandlerOpen},
- {"io", g_aArgIo, RT_ELEMENTS(g_aArgIo), vdScriptHandlerIo},
- {"flush", g_aArgFlush, RT_ELEMENTS(g_aArgFlush), vdScriptHandlerFlush},
- {"close", g_aArgClose, RT_ELEMENTS(g_aArgClose), vdScriptHandlerClose},
- {"merge", g_aArgMerge, RT_ELEMENTS(g_aArgMerge), vdScriptHandlerMerge},
- {"iorngcreate", g_aArgIoRngCreate, RT_ELEMENTS(g_aArgIoRngCreate), vdScriptHandlerIoRngCreate},
- {"iorngdestroy", NULL, 0, vdScriptHandlerIoRngDestroy},
- {"sleep", g_aArgSleep, RT_ELEMENTS(g_aArgSleep), vdScriptHandlerSleep},
+ /* pcszAction paArgDesc cArgDescs pfnHandler */
+ {"create", g_aArgCreate, RT_ELEMENTS(g_aArgCreate), vdScriptHandlerCreate},
+ {"open", g_aArgOpen, RT_ELEMENTS(g_aArgOpen), vdScriptHandlerOpen},
+ {"io", g_aArgIo, RT_ELEMENTS(g_aArgIo), vdScriptHandlerIo},
+ {"flush", g_aArgFlush, RT_ELEMENTS(g_aArgFlush), vdScriptHandlerFlush},
+ {"close", g_aArgClose, RT_ELEMENTS(g_aArgClose), vdScriptHandlerClose},
+ {"merge", g_aArgMerge, RT_ELEMENTS(g_aArgMerge), vdScriptHandlerMerge},
+ {"compact", g_aArgCompact, RT_ELEMENTS(g_aArgCompact), vdScriptHandlerCompact},
+ {"iorngcreate", g_aArgIoRngCreate, RT_ELEMENTS(g_aArgIoRngCreate), vdScriptHandlerIoRngCreate},
+ {"iorngdestroy", NULL, 0, vdScriptHandlerIoRngDestroy},
+ {"iopatterncreatefromnumber", g_aArgIoPatternCreateFromNumber, RT_ELEMENTS(g_aArgIoPatternCreateFromNumber), vdScriptHandlerIoPatternCreateFromNumber},
+ {"iopatterncreatefromfile", g_aArgIoPatternCreateFromFile, RT_ELEMENTS(g_aArgIoPatternCreateFromFile), vdScriptHandlerIoPatternCreateFromFile},
+ {"iopatterndestroy", g_aArgIoPatternDestroy, RT_ELEMENTS(g_aArgIoPatternDestroy), vdScriptHandlerIoPatternDestroy},
+ {"sleep", g_aArgSleep, RT_ELEMENTS(g_aArgSleep), vdScriptHandlerSleep},
+ {"dumpfile", g_aArgDumpFile, RT_ELEMENTS(g_aArgDumpFile), vdScriptHandlerDumpFile},
+ {"createdisk", g_aArgCreateDisk, RT_ELEMENTS(g_aArgCreateDisk), vdScriptHandlerCreateDisk},
+ {"destroydisk", g_aArgDestroyDisk, RT_ELEMENTS(g_aArgDestroyDisk), vdScriptHandlerDestroyDisk},
+ {"comparedisks", g_aArgCompareDisks, RT_ELEMENTS(g_aArgCompareDisks), vdScriptHandlerCompareDisks},
+ {"dumpdiskinfo", g_aArgDumpDiskInfo, RT_ELEMENTS(g_aArgDumpDiskInfo), vdScriptHandlerDumpDiskInfo},
+ {"print", g_aArgPrintMsg, RT_ELEMENTS(g_aArgPrintMsg), vdScriptHandlerPrintMsg}
};
const unsigned g_cScriptActions = RT_ELEMENTS(g_aScriptActions);
@@ -330,26 +511,40 @@ static int tstVDMessage(void *pvUser, const char *pszFormat, va_list va)
return VINF_SUCCESS;
}
-static int tstVDIoTestInit(PVDIOTEST pIoTest, PVDTESTGLOB pGlob, bool fRandomAcc, size_t cbIo,
+static int tstVDIoTestInit(PVDIOTEST pIoTest, PVDTESTGLOB pGlob, bool fRandomAcc, uint64_t cbIo,
size_t cbBlkSize, uint64_t offStart, uint64_t offEnd,
- unsigned uWriteChance, unsigned uReadChance);
+ unsigned uWriteChance, PVDPATTERN pPattern);
static bool tstVDIoTestRunning(PVDIOTEST pIoTest);
+static void tstVDIoTestDestroy(PVDIOTEST pIoTest);
static bool tstVDIoTestReqOutstanding(PVDIOREQ pIoReq);
-static int tstVDIoTestReqInit(PVDIOTEST pIoTest, PVDIOREQ pIoReq);
+static int tstVDIoTestReqInit(PVDIOTEST pIoTest, PVDIOREQ pIoReq, void *pvUser);
static void tstVDIoTestReqComplete(void *pvUser1, void *pvUser2, int rcReq);
+static PVDDISK tstVDIoGetDiskByName(PVDTESTGLOB pGlob, const char *pcszDisk);
+static PVDPATTERN tstVDIoGetPatternByName(PVDTESTGLOB pGlob, const char *pcszName);
+static PVDPATTERN tstVDIoPatternCreate(const char *pcszName, size_t cbPattern);
+static int tstVDIoPatternGetBuffer(PVDPATTERN pPattern, void **ppv, size_t cb);
+
static DECLCALLBACK(int) vdScriptHandlerCreate(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
{
int rc = VINF_SUCCESS;
uint64_t cbSize = 0;
const char *pcszBackend = NULL;
const char *pcszImage = NULL;
+ const char *pcszDisk = NULL;
+ PVDDISK pDisk = NULL;
bool fBase = false;
+ bool fDynamic = true;
for (unsigned i = 0; i < cScriptArgs; i++)
{
switch (paScriptArgs[i].chId)
{
+ case 'd':
+ {
+ pcszDisk = paScriptArgs[i].u.pcszString;
+ break;
+ }
case 'm':
{
if (!RTStrICmp(paScriptArgs[i].u.pcszString, "base"))
@@ -378,6 +573,19 @@ static DECLCALLBACK(int) vdScriptHandlerCreate(PVDTESTGLOB pGlob, PVDSCRIPTARG p
cbSize = paScriptArgs[i].u.u64;
break;
}
+ case 't':
+ {
+ if (!RTStrICmp(paScriptArgs[i].u.pcszString, "fixed"))
+ fDynamic = false;
+ else if (!RTStrICmp(paScriptArgs[i].u.pcszString, "dynamic"))
+ fDynamic = true;
+ else
+ {
+ RTPrintf("Invalid image type '%s' given\n", paScriptArgs[i].u.pcszString);
+ rc = VERR_INVALID_PARAMETER;
+ }
+ break;
+ }
default:
AssertMsgFailed(("Invalid argument given!\n"));
}
@@ -388,13 +596,24 @@ static DECLCALLBACK(int) vdScriptHandlerCreate(PVDTESTGLOB pGlob, PVDSCRIPTARG p
if (RT_SUCCESS(rc))
{
- if (fBase)
- rc = VDCreateBase(pGlob->pVD, pcszBackend, pcszImage, cbSize, 0, NULL,
- &pGlob->PhysGeom, &pGlob->LogicalGeom,
- NULL, VD_OPEN_FLAGS_ASYNC_IO, pGlob->pInterfacesImages, NULL);
+ pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
+ if (pDisk)
+ {
+ unsigned fImageFlags = VD_IMAGE_FLAGS_NONE;
+
+ if (!fDynamic)
+ fImageFlags |= VD_IMAGE_FLAGS_FIXED;
+
+ if (fBase)
+ rc = VDCreateBase(pDisk->pVD, pcszBackend, pcszImage, cbSize, fImageFlags, NULL,
+ &pDisk->PhysGeom, &pDisk->LogicalGeom,
+ NULL, VD_OPEN_FLAGS_ASYNC_IO, pGlob->pInterfacesImages, NULL);
+ else
+ rc = VDCreateDiff(pDisk->pVD, pcszBackend, pcszImage, fImageFlags, NULL, NULL, NULL, VD_OPEN_FLAGS_ASYNC_IO,
+ pGlob->pInterfacesImages, NULL);
+ }
else
- rc = VDCreateDiff(pGlob->pVD, pcszBackend, pcszImage, 0, NULL, NULL, NULL, VD_OPEN_FLAGS_ASYNC_IO,
- pGlob->pInterfacesImages, NULL);
+ rc = VERR_NOT_FOUND;
}
return rc;
@@ -405,11 +624,20 @@ static DECLCALLBACK(int) vdScriptHandlerOpen(PVDTESTGLOB pGlob, PVDSCRIPTARG paS
int rc = VINF_SUCCESS;
const char *pcszBackend = NULL;
const char *pcszImage = NULL;
+ const char *pcszDisk = NULL;
+ PVDDISK pDisk = NULL;
+ bool fShareable = false;
+ bool fReadonly = false;
for (unsigned i = 0; i < cScriptArgs; i++)
{
switch (paScriptArgs[i].chId)
{
+ case 'd':
+ {
+ pcszDisk = paScriptArgs[i].u.pcszString;
+ break;
+ }
case 'n':
{
pcszImage = paScriptArgs[i].u.pcszString;
@@ -420,6 +648,16 @@ static DECLCALLBACK(int) vdScriptHandlerOpen(PVDTESTGLOB pGlob, PVDSCRIPTARG paS
pcszBackend = paScriptArgs[i].u.pcszString;
break;
}
+ case 's':
+ {
+ fShareable = paScriptArgs[i].u.fFlag;
+ break;
+ }
+ case 'r':
+ {
+ fReadonly = paScriptArgs[i].u.fFlag;
+ break;
+ }
default:
AssertMsgFailed(("Invalid argument given!\n"));
}
@@ -430,7 +668,20 @@ static DECLCALLBACK(int) vdScriptHandlerOpen(PVDTESTGLOB pGlob, PVDSCRIPTARG paS
if (RT_SUCCESS(rc))
{
- rc = VDOpen(pGlob->pVD, pcszBackend, pcszImage, VD_OPEN_FLAGS_ASYNC_IO, pGlob->pInterfacesImages);
+ pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
+ if (pDisk)
+ {
+ unsigned fOpenFlags = VD_OPEN_FLAGS_ASYNC_IO;
+
+ if (fShareable)
+ fOpenFlags |= VD_OPEN_FLAGS_SHAREABLE;
+ if (fReadonly)
+ fOpenFlags |= VD_OPEN_FLAGS_READONLY;
+
+ rc = VDOpen(pDisk->pVD, pcszBackend, pcszImage, fOpenFlags, pGlob->pInterfacesImages);
+ }
+ else
+ rc = VERR_NOT_FOUND;
}
return rc;
@@ -449,17 +700,20 @@ static DECLCALLBACK(int) vdScriptHandlerIo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScr
uint64_t offEnd = 0;
unsigned cMaxReqs = 0;
uint8_t uWriteChance = 0;
- uint8_t uReadChance = 0;
-
- offEnd = VDGetSize(pGlob->pVD, VD_LAST_IMAGE);
- if (offEnd == 0)
- return VERR_INVALID_STATE;
- cbIo = offEnd;
+ const char *pcszDisk = NULL;
+ const char *pcszPattern = NULL;
+ PVDDISK pDisk = NULL;
+ PVDPATTERN pPattern = NULL;
for (unsigned i = 0; i < cScriptArgs; i++)
{
switch (paScriptArgs[i].chId)
{
+ case 'd':
+ {
+ pcszDisk = paScriptArgs[i].u.pcszString;
+ break;
+ }
case 'a':
{
fAsync = paScriptArgs[i].u.fFlag;
@@ -499,14 +753,14 @@ static DECLCALLBACK(int) vdScriptHandlerIo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScr
offEnd = paScriptArgs[i].u.Range.End;
break;
}
- case 'r':
+ case 'w':
{
- uReadChance = (uint8_t)paScriptArgs[i].u.u64;
+ uWriteChance = (uint8_t)paScriptArgs[i].u.u64;
break;
}
- case 'w':
+ case 'p':
{
- uWriteChance = (uint8_t)paScriptArgs[i].u.u64;
+ pcszPattern = paScriptArgs[i].u.pcszString;
break;
}
default:
@@ -519,9 +773,38 @@ static DECLCALLBACK(int) vdScriptHandlerIo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScr
if (RT_SUCCESS(rc))
{
+ pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
+ if (!pDisk)
+ rc = VERR_NOT_FOUND;
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ /* Set defaults if not set by the user. */
+ if (offStart == 0 && offEnd == 0)
+ {
+ offEnd = VDGetSize(pDisk->pVD, VD_LAST_IMAGE);
+ if (offEnd == 0)
+ return VERR_INVALID_STATE;
+ }
+
+ if (!cbIo)
+ cbIo = offEnd;
+ }
+
+ if ( RT_SUCCESS(rc)
+ && pcszPattern)
+ {
+ pPattern = tstVDIoGetPatternByName(pGlob, pcszPattern);
+ if (!pPattern)
+ rc = VERR_NOT_FOUND;
+ }
+
+ if (RT_SUCCESS(rc))
+ {
VDIOTEST IoTest;
- rc = tstVDIoTestInit(&IoTest, pGlob, fRandomAcc, cbIo, cbBlkSize, offStart, offEnd, uWriteChance, uReadChance);
+ rc = tstVDIoTestInit(&IoTest, pGlob, fRandomAcc, cbIo, cbBlkSize, offStart, offEnd, uWriteChance, pPattern);
if (RT_SUCCESS(rc))
{
PVDIOREQ paIoReq = NULL;
@@ -532,10 +815,22 @@ static DECLCALLBACK(int) vdScriptHandlerIo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScr
paIoReq = (PVDIOREQ)RTMemAllocZ(cMaxTasksOutstanding * sizeof(VDIOREQ));
if (paIoReq && RT_SUCCESS(rc))
{
+ uint64_t NanoTS = RTTimeNanoTS();
+
+ /* Init requests. */
for (unsigned i = 0; i < cMaxTasksOutstanding; i++)
+ {
paIoReq[i].idx = i;
+ paIoReq[i].pvBufRead = RTMemAlloc(cbBlkSize);
+ if (!paIoReq[i].pvBufRead)
+ {
+ rc = VERR_NO_MEMORY;
+ break;
+ }
+ }
- while (tstVDIoTestRunning(&IoTest))
+ while ( tstVDIoTestRunning(&IoTest)
+ && RT_SUCCESS(rc))
{
bool fTasksOutstanding = false;
unsigned idx = 0;
@@ -546,7 +841,7 @@ static DECLCALLBACK(int) vdScriptHandlerIo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScr
{
if (!tstVDIoTestReqOutstanding(&paIoReq[idx]))
{
- rc = tstVDIoTestReqInit(&IoTest, &paIoReq[idx]);
+ rc = tstVDIoTestReqInit(&IoTest, &paIoReq[idx], pDisk);
AssertRC(rc);
if (RT_SUCCESS(rc))
@@ -557,45 +852,66 @@ static DECLCALLBACK(int) vdScriptHandlerIo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScr
{
case VDIOREQTXDIR_READ:
{
- rc = VDRead(pGlob->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq);
- RTMemFree(paIoReq[idx].DataSeg.pvSeg);
+ rc = VDRead(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq);
+
+ if (RT_SUCCESS(rc)
+ && pDisk->pMemDiskVerify)
+ {
+ RTSGBUF SgBuf;
+ RTSgBufInit(&SgBuf, &paIoReq[idx].DataSeg, 1);
+
+ if (VDMemDiskCmp(pDisk->pMemDiskVerify, paIoReq[idx].off, paIoReq[idx].cbReq, &SgBuf))
+ {
+ RTPrintf("Corrupted disk at offset %llu!\n", paIoReq[idx].off);
+ rc = VERR_INVALID_STATE;
+ }
+ }
break;
}
case VDIOREQTXDIR_WRITE:
{
- rc = VDWrite(pGlob->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq);
+ rc = VDWrite(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq);
+
+ if (RT_SUCCESS(rc)
+ && pDisk->pMemDiskVerify)
+ {
+ RTSGBUF SgBuf;
+ RTSgBufInit(&SgBuf, &paIoReq[idx].DataSeg, 1);
+ rc = VDMemDiskWrite(pDisk->pMemDiskVerify, paIoReq[idx].off, paIoReq[idx].cbReq, &SgBuf);
+ }
break;
}
case VDIOREQTXDIR_FLUSH:
{
- rc = VDFlush(pGlob->pVD);
+ rc = VDFlush(pDisk->pVD);
break;
}
}
+
+ ASMAtomicXchgBool(&paIoReq[idx].fOutstanding, false);
if (RT_SUCCESS(rc))
idx++;
}
else
{
+ LogFlow(("Queuing request %d\n", idx));
switch (paIoReq[idx].enmTxDir)
{
case VDIOREQTXDIR_READ:
{
- rc = VDAsyncRead(pGlob->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf,
+ rc = VDAsyncRead(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf,
tstVDIoTestReqComplete, &paIoReq[idx], EventSem);
- if (rc == VINF_VD_ASYNC_IO_FINISHED)
- RTMemFree(paIoReq[idx].DataSeg.pvSeg);
break;
}
case VDIOREQTXDIR_WRITE:
{
- rc = VDAsyncWrite(pGlob->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf,
+ rc = VDAsyncWrite(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf,
tstVDIoTestReqComplete, &paIoReq[idx], EventSem);
break;
}
case VDIOREQTXDIR_FLUSH:
{
- rc = VDAsyncFlush(pGlob->pVD, tstVDIoTestReqComplete, &paIoReq[idx], EventSem);
+ rc = VDAsyncFlush(pDisk->pVD, tstVDIoTestReqComplete, &paIoReq[idx], EventSem);
break;
}
}
@@ -608,8 +924,46 @@ static DECLCALLBACK(int) vdScriptHandlerIo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScr
}
else if (rc == VINF_VD_ASYNC_IO_FINISHED)
{
+ LogFlow(("Request %d completed\n", idx));
+ switch (paIoReq[idx].enmTxDir)
+ {
+ case VDIOREQTXDIR_READ:
+ {
+ if (pDisk->pMemDiskVerify)
+ {
+ RTCritSectEnter(&pDisk->CritSectVerify);
+ RTSgBufReset(&paIoReq[idx].SgBuf);
+
+ if (VDMemDiskCmp(pDisk->pMemDiskVerify, paIoReq[idx].off, paIoReq[idx].cbReq,
+ &paIoReq[idx].SgBuf))
+ {
+ RTPrintf("Corrupted disk at offset %llu!\n", paIoReq[idx].off);
+ rc = VERR_INVALID_STATE;
+ }
+ RTCritSectLeave(&pDisk->CritSectVerify);
+ }
+ break;
+ }
+ case VDIOREQTXDIR_WRITE:
+ {
+ if (pDisk->pMemDiskVerify)
+ {
+ RTCritSectEnter(&pDisk->CritSectVerify);
+ RTSgBufReset(&paIoReq[idx].SgBuf);
+
+ rc = VDMemDiskWrite(pDisk->pMemDiskVerify, paIoReq[idx].off, paIoReq[idx].cbReq,
+ &paIoReq[idx].SgBuf);
+ RTCritSectLeave(&pDisk->CritSectVerify);
+ }
+ break;
+ }
+ case VDIOREQTXDIR_FLUSH:
+ break;
+ }
+
ASMAtomicXchgBool(&paIoReq[idx].fOutstanding, false);
- rc = VINF_SUCCESS;
+ if (rc != VERR_INVALID_STATE)
+ rc = VINF_SUCCESS;
}
}
@@ -653,11 +1007,17 @@ static DECLCALLBACK(int) vdScriptHandlerIo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScr
break;
}
+ NanoTS = RTTimeNanoTS() - NanoTS;
+ uint64_t SpeedKBs = (uint64_t)(cbIo / (NanoTS / 1000000000.0) / 1024);
+ RTPrintf("I/O Test: Throughput %lld kb/s\n", SpeedKBs);
+
RTSemEventDestroy(EventSem);
RTMemFree(paIoReq);
}
else
rc = VERR_NO_MEMORY;
+
+ tstVDIoTestDestroy(&IoTest);
}
}
@@ -668,24 +1028,166 @@ static DECLCALLBACK(int) vdScriptHandlerFlush(PVDTESTGLOB pGlob, PVDSCRIPTARG pa
{
int rc = VINF_SUCCESS;
bool fAsync = false;
+ const char *pcszDisk = NULL;
+ PVDDISK pDisk = NULL;
- if (cScriptArgs == 1 && paScriptArgs[0].chId == 'a')
- fAsync = paScriptArgs[0].u.fFlag;
+ for (unsigned i = 0; i < cScriptArgs; i++)
+ {
+ switch (paScriptArgs[i].chId)
+ {
+ case 'd':
+ {
+ pcszDisk = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ case 'a':
+ {
+ fAsync = paScriptArgs[i].u.fFlag;
+ break;
+ }
- if (fAsync)
+ default:
+ AssertMsgFailed(("Invalid argument given!\n"));
+ }
+
+ if (RT_FAILURE(rc))
+ break;
+ }
+
+ if (RT_SUCCESS(rc))
{
- /** @todo */
- rc = VERR_NOT_IMPLEMENTED;
+ pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
+ if (!pDisk)
+ rc = VERR_NOT_FOUND;
+ else if (fAsync)
+ {
+ VDIOREQ IoReq;
+ RTSEMEVENT EventSem;
+
+ rc = RTSemEventCreate(&EventSem);
+ if (RT_SUCCESS(rc))
+ {
+ memset(&IoReq, 0, sizeof(VDIOREQ));
+ IoReq.enmTxDir = VDIOREQTXDIR_FLUSH;
+ IoReq.pvUser = pDisk;
+ IoReq.idx = 0;
+ rc = VDAsyncFlush(pDisk->pVD, tstVDIoTestReqComplete, &IoReq, EventSem);
+ if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
+ {
+ rc = RTSemEventWait(EventSem, RT_INDEFINITE_WAIT);
+ AssertRC(rc);
+ }
+ else if (rc == VINF_VD_ASYNC_IO_FINISHED)
+ rc = VINF_SUCCESS;
+
+ RTSemEventDestroy(EventSem);
+ }
+ }
+ else
+ rc = VDFlush(pDisk->pVD);
}
- else
- rc = VDFlush(pGlob->pVD);
return rc;
}
static DECLCALLBACK(int) vdScriptHandlerMerge(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
{
- return VERR_NOT_IMPLEMENTED;
+ int rc = VINF_SUCCESS;
+ const char *pcszDisk = NULL;
+ PVDDISK pDisk = NULL;
+ unsigned nImageFrom = 0;
+ unsigned nImageTo = 0;
+
+ for (unsigned i = 0; i < cScriptArgs; i++)
+ {
+ switch (paScriptArgs[i].chId)
+ {
+ case 'd':
+ {
+ pcszDisk = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ case 'f':
+ {
+ nImageFrom = (unsigned)paScriptArgs[i].u.u64;
+ break;
+ }
+ case 't':
+ {
+ nImageTo = (unsigned)paScriptArgs[i].u.u64;
+ break;
+ }
+
+ default:
+ AssertMsgFailed(("Invalid argument given!\n"));
+ }
+
+ if (RT_FAILURE(rc))
+ break;
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
+ if (!pDisk)
+ rc = VERR_NOT_FOUND;
+ else
+ {
+ /** @todo: Provide progress interface to test that cancelation
+ * doesn't corrupt the data.
+ */
+ rc = VDMerge(pDisk->pVD, nImageFrom, nImageTo, NULL);
+ }
+ }
+
+ return rc;
+}
+
+static DECLCALLBACK(int) vdScriptHandlerCompact(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
+{
+ int rc = VINF_SUCCESS;
+ const char *pcszDisk = NULL;
+ PVDDISK pDisk = NULL;
+ unsigned nImage = 0;
+
+ for (unsigned i = 0; i < cScriptArgs; i++)
+ {
+ switch (paScriptArgs[i].chId)
+ {
+ case 'd':
+ {
+ pcszDisk = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ case 'i':
+ {
+ nImage = (unsigned)paScriptArgs[i].u.u64;
+ break;
+ }
+
+ default:
+ AssertMsgFailed(("Invalid argument given!\n"));
+ }
+
+ if (RT_FAILURE(rc))
+ break;
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
+ if (!pDisk)
+ rc = VERR_NOT_FOUND;
+ else
+ {
+ /** @todo: Provide progress interface to test that cancelation
+ * doesn't corrupt the data.
+ */
+ rc = VDCompact(pDisk->pVD, nImage, NULL);
+ }
+ }
+
+ return rc;
}
static DECLCALLBACK(int) vdScriptHandlerClose(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
@@ -693,11 +1195,18 @@ static DECLCALLBACK(int) vdScriptHandlerClose(PVDTESTGLOB pGlob, PVDSCRIPTARG pa
int rc = VINF_SUCCESS;
bool fAll = false;
bool fDelete = false;
+ const char *pcszDisk = NULL;
+ PVDDISK pDisk = NULL;
for (unsigned i = 0; i < cScriptArgs; i++)
{
switch (paScriptArgs[i].chId)
{
+ case 'd':
+ {
+ pcszDisk = paScriptArgs[i].u.pcszString;
+ break;
+ }
case 'm':
{
if (!RTStrICmp(paScriptArgs[i].u.pcszString, "all"))
@@ -711,7 +1220,7 @@ static DECLCALLBACK(int) vdScriptHandlerClose(PVDTESTGLOB pGlob, PVDSCRIPTARG pa
}
break;
}
- case 'd':
+ case 'r':
{
fDelete = paScriptArgs[i].u.fFlag;
break;
@@ -734,10 +1243,16 @@ static DECLCALLBACK(int) vdScriptHandlerClose(PVDTESTGLOB pGlob, PVDSCRIPTARG pa
if (RT_SUCCESS(rc))
{
- if (fAll)
- rc = VDCloseAll(pGlob->pVD);
+ pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
+ if (pDisk)
+ {
+ if (fAll)
+ rc = VDCloseAll(pDisk->pVD);
+ else
+ rc = VDClose(pDisk->pVD, fDelete);
+ }
else
- rc = VDClose(pGlob->pVD, fDelete);
+ rc = VERR_NOT_FOUND;
}
return rc;
}
@@ -748,6 +1263,7 @@ static DECLCALLBACK(int) vdScriptHandlerIoRngCreate(PVDTESTGLOB pGlob, PVDSCRIPT
int rc = VINF_SUCCESS;
size_t cbPattern = 0;
uint64_t uSeed = 0;
+ const char *pcszSeeder = NULL;
for (unsigned i = 0; i < cScriptArgs; i++)
{
@@ -763,6 +1279,11 @@ static DECLCALLBACK(int) vdScriptHandlerIoRngCreate(PVDTESTGLOB pGlob, PVDSCRIPT
uSeed = paScriptArgs[i].u.u64;
break;
}
+ case 'm':
+ {
+ pcszSeeder = paScriptArgs[i].u.pcszString;
+ break;
+ }
default:
AssertMsgFailed(("Invalid argument given!\n"));
}
@@ -774,7 +1295,27 @@ static DECLCALLBACK(int) vdScriptHandlerIoRngCreate(PVDTESTGLOB pGlob, PVDSCRIPT
rc = VERR_INVALID_STATE;
}
else
- rc = VDIoRndCreate(&pGlob->pIoRnd, cbPattern, uSeed);
+ {
+ uint64_t uSeedToUse = 0;
+
+ if (!RTStrICmp(pcszSeeder, "manual"))
+ uSeedToUse = uSeed;
+ else if (!RTStrICmp(pcszSeeder, "time"))
+ uSeedToUse = RTTimeSystemMilliTS();
+ else if (!RTStrICmp(pcszSeeder, "system"))
+ {
+ RTRAND hRand;
+ rc = RTRandAdvCreateSystemTruer(&hRand);
+ if (RT_SUCCESS(rc))
+ {
+ RTRandAdvBytes(hRand, &uSeedToUse, sizeof(uSeedToUse));
+ RTRandAdvDestroy(hRand);
+ }
+ }
+
+ if (RT_SUCCESS(rc))
+ rc = VDIoRndCreate(&pGlob->pIoRnd, cbPattern, uSeed);
+ }
return rc;
}
@@ -792,6 +1333,160 @@ static DECLCALLBACK(int) vdScriptHandlerIoRngDestroy(PVDTESTGLOB pGlob, PVDSCRIP
return VINF_SUCCESS;
}
+static DECLCALLBACK(int) vdScriptHandlerIoPatternCreateFromNumber(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
+{
+ int rc = VINF_SUCCESS;
+ size_t cbPattern = 0;
+ const char *pcszName = NULL;
+ uint64_t u64Pattern = 0;
+
+ for (unsigned i = 0; i < cScriptArgs; i++)
+ {
+ switch (paScriptArgs[i].chId)
+ {
+ case 'n':
+ {
+ pcszName = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ case 's':
+ {
+ cbPattern = paScriptArgs[i].u.u64;
+ break;
+ }
+ case 'p':
+ {
+ u64Pattern = paScriptArgs[i].u.u64;
+ break;
+ }
+ default:
+ AssertMsgFailed(("Invalid argument given!\n"));
+ }
+ }
+
+ PVDPATTERN pPattern = tstVDIoGetPatternByName(pGlob, pcszName);
+ if (!pPattern)
+ {
+ pPattern = tstVDIoPatternCreate(pcszName, RT_ALIGN_Z(cbPattern, sizeof(uint64_t)));
+ if (pPattern)
+ {
+ /* Fill the buffer. */
+ void *pv = pPattern->pvPattern;
+
+ while (pPattern->cbPattern > 0)
+ {
+ *((uint64_t*)pv) = u64Pattern;
+ pPattern->cbPattern -= sizeof(uint64_t);
+ pv = (uint64_t *)pv + 1;
+ }
+ pPattern->cbPattern = cbPattern; /* Set to the desired size. (could be unaligned) */
+
+ RTListAppend(&pGlob->ListPatterns, &pPattern->ListNode);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ }
+ else
+ rc = VERR_ALREADY_EXISTS;
+
+ return rc;
+}
+
+static DECLCALLBACK(int) vdScriptHandlerIoPatternCreateFromFile(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
+{
+ int rc = VINF_SUCCESS;
+ const char *pcszName = NULL;
+ const char *pcszFile = NULL;
+
+ for (unsigned i = 0; i < cScriptArgs; i++)
+ {
+ switch (paScriptArgs[i].chId)
+ {
+ case 'n':
+ {
+ pcszName = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ case 'f':
+ {
+ pcszFile = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ default:
+ AssertMsgFailed(("Invalid argument given!\n"));
+ }
+ }
+
+ PVDPATTERN pPattern = tstVDIoGetPatternByName(pGlob, pcszName);
+ if (!pPattern)
+ {
+ RTFILE hFile;
+ uint64_t cbPattern = 0;
+
+ rc = RTFileOpen(&hFile, pcszFile, RTFILE_O_DENY_NONE | RTFILE_O_OPEN | RTFILE_O_READ);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTFileGetSize(hFile, &cbPattern);
+ if (RT_SUCCESS(rc))
+ {
+ pPattern = tstVDIoPatternCreate(pcszName, (size_t)cbPattern);
+ if (pPattern)
+ {
+ rc = RTFileRead(hFile, pPattern->pvPattern, (size_t)cbPattern, NULL);
+ if (RT_SUCCESS(rc))
+ RTListAppend(&pGlob->ListPatterns, &pPattern->ListNode);
+ else
+ {
+ RTMemFree(pPattern->pvPattern);
+ RTStrFree(pPattern->pszName);
+ RTMemFree(pPattern);
+ }
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ }
+ RTFileClose(hFile);
+ }
+ }
+ else
+ rc = VERR_ALREADY_EXISTS;
+
+ return rc;
+}
+
+static DECLCALLBACK(int) vdScriptHandlerIoPatternDestroy(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
+{
+ int rc = VINF_SUCCESS;
+ const char *pcszName = NULL;
+
+ for (unsigned i = 0; i < cScriptArgs; i++)
+ {
+ switch (paScriptArgs[i].chId)
+ {
+ case 'n':
+ {
+ pcszName = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ default:
+ AssertMsgFailed(("Invalid argument given!\n"));
+ }
+ }
+
+ PVDPATTERN pPattern = tstVDIoGetPatternByName(pGlob, pcszName);
+ if (pPattern)
+ {
+ RTListNodeRemove(&pPattern->ListNode);
+ RTMemFree(pPattern->pvPattern);
+ RTStrFree(pPattern->pszName);
+ RTMemFree(pPattern);
+ }
+ else
+ rc = VERR_NOT_FOUND;
+
+ return rc;
+}
+
static DECLCALLBACK(int) vdScriptHandlerSleep(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
{
int rc = VINF_SUCCESS;
@@ -815,6 +1510,299 @@ static DECLCALLBACK(int) vdScriptHandlerSleep(PVDTESTGLOB pGlob, PVDSCRIPTARG pa
return rc;
}
+static DECLCALLBACK(int) vdScriptHandlerDumpFile(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
+{
+ int rc = VINF_SUCCESS;
+ const char *pcszFile = NULL;
+ const char *pcszPathToDump = NULL;
+
+ for (unsigned i = 0; i < cScriptArgs; i++)
+ {
+ switch (paScriptArgs[i].chId)
+ {
+ case 'f':
+ {
+ pcszFile = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ case 'p':
+ {
+ pcszPathToDump = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ default:
+ AssertMsgFailed(("Invalid argument given!\n"));
+ }
+ }
+
+ /* Check for the file. */
+ PVDFILE pIt = NULL;
+ bool fFound = false;
+ RTListForEach(&pGlob->ListFiles, pIt, VDFILE, Node)
+ {
+ if (!RTStrCmp(pIt->pszName, pcszFile))
+ {
+ fFound = true;
+ break;
+ }
+ }
+
+ if (fFound)
+ {
+ RTPrintf("Dumping memory file %s to %s, this might take some time\n", pcszFile, pcszPathToDump);
+ rc = VDMemDiskWriteToFile(pIt->pMemDisk, pcszPathToDump);
+ }
+ else
+ rc = VERR_FILE_NOT_FOUND;
+
+ return rc;
+}
+
+static DECLCALLBACK(int) vdScriptHandlerCreateDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
+{
+ int rc = VINF_SUCCESS;
+ const char *pcszDisk = NULL;
+ PVDDISK pDisk = NULL;
+ bool fVerify = false;
+
+ for (unsigned i = 0; i < cScriptArgs; i++)
+ {
+ switch (paScriptArgs[i].chId)
+ {
+ case 'n':
+ {
+ pcszDisk = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ case 'v':
+ {
+ fVerify = paScriptArgs[i].u.fFlag;
+ break;
+ }
+ default:
+ AssertMsgFailed(("Invalid argument given!\n"));
+ }
+ }
+
+ pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
+ if (pDisk)
+ rc = VERR_ALREADY_EXISTS;
+ else
+ {
+ pDisk = (PVDDISK)RTMemAllocZ(sizeof(VDDISK));
+ if (pDisk)
+ {
+ pDisk->pszName = RTStrDup(pcszDisk);
+ if (pDisk->pszName)
+ {
+ rc = VINF_SUCCESS;
+
+ if (fVerify)
+ {
+ rc = VDMemDiskCreate(&pDisk->pMemDiskVerify, 0 /* Growing */);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTCritSectInit(&pDisk->CritSectVerify);
+ if (RT_FAILURE(rc))
+ VDMemDiskDestroy(pDisk->pMemDiskVerify);
+ }
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ rc = VDCreate(pGlob->pInterfacesDisk, VDTYPE_HDD, &pDisk->pVD);
+
+ if (RT_SUCCESS(rc))
+ RTListAppend(&pGlob->ListDisks, &pDisk->ListNode);
+ else
+ {
+ if (fVerify)
+ {
+ RTCritSectDelete(&pDisk->CritSectVerify);
+ VDMemDiskDestroy(pDisk->pMemDiskVerify);
+ }
+ RTStrFree(pDisk->pszName);
+ }
+ }
+ }
+ else
+ rc = VERR_NO_MEMORY;
+
+ if (RT_FAILURE(rc))
+ RTMemFree(pDisk);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ }
+ return rc;
+}
+
+static DECLCALLBACK(int) vdScriptHandlerDestroyDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
+{
+ int rc = VINF_SUCCESS;
+ const char *pcszDisk = NULL;
+ PVDDISK pDisk = NULL;
+
+ for (unsigned i = 0; i < cScriptArgs; i++)
+ {
+ switch (paScriptArgs[i].chId)
+ {
+ case 'n':
+ {
+ pcszDisk = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ default:
+ AssertMsgFailed(("Invalid argument given!\n"));
+ }
+ }
+
+ pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
+ if (pDisk)
+ {
+ RTListNodeRemove(&pDisk->ListNode);
+ VDDestroy(pDisk->pVD);
+ if (pDisk->pMemDiskVerify)
+ {
+ VDMemDiskDestroy(pDisk->pMemDiskVerify);
+ RTCritSectDelete(&pDisk->CritSectVerify);
+ }
+ RTStrFree(pDisk->pszName);
+ RTMemFree(pDisk);
+ }
+ else
+ rc = VERR_NOT_FOUND;
+
+ return rc;
+}
+
+static DECLCALLBACK(int) vdScriptHandlerCompareDisks(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
+{
+ int rc = VINF_SUCCESS;
+ const char *pcszDisk1 = NULL;
+ PVDDISK pDisk1 = NULL;
+ const char *pcszDisk2 = NULL;
+ PVDDISK pDisk2 = NULL;
+
+ for (unsigned i = 0; i < cScriptArgs; i++)
+ {
+ switch (paScriptArgs[i].chId)
+ {
+ case '1':
+ {
+ pcszDisk1 = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ case '2':
+ {
+ pcszDisk2 = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ default:
+ AssertMsgFailed(("Invalid argument given!\n"));
+ }
+ }
+
+ pDisk1 = tstVDIoGetDiskByName(pGlob, pcszDisk1);
+ pDisk2 = tstVDIoGetDiskByName(pGlob, pcszDisk2);
+
+ if (pDisk1 && pDisk2)
+ {
+ uint8_t *pbBuf1 = (uint8_t *)RTMemAllocZ(16 * _1M);
+ uint8_t *pbBuf2 = (uint8_t *)RTMemAllocZ(16 * _1M);
+ if (pbBuf1 && pbBuf2)
+ {
+ uint64_t cbDisk1, cbDisk2;
+ uint64_t uOffCur = 0;
+
+ cbDisk1 = VDGetSize(pDisk1->pVD, VD_LAST_IMAGE);
+ cbDisk2 = VDGetSize(pDisk2->pVD, VD_LAST_IMAGE);
+
+ if (cbDisk1 != cbDisk2)
+ RTPrintf("Disks differ in size %llu vs %llu\n", cbDisk1, cbDisk2);
+ else
+ {
+ while (uOffCur < cbDisk1)
+ {
+ size_t cbRead = RT_MIN(cbDisk1, 16 * _1M);
+
+ rc = VDRead(pDisk1->pVD, uOffCur, pbBuf1, cbRead);
+ if (RT_SUCCESS(rc))
+ rc = VDRead(pDisk2->pVD, uOffCur, pbBuf2, cbRead);
+
+ if (RT_SUCCESS(rc))
+ {
+ if (memcmp(pbBuf1, pbBuf2, cbRead))
+ {
+ RTPrintf("Disks differ at offset %llu\n", uOffCur);
+ rc = VERR_DEV_IO_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ RTPrintf("Reading one disk at offset %llu failed\n", uOffCur);
+ break;
+ }
+
+ uOffCur += cbRead;
+ cbDisk1 -= cbRead;
+ }
+ }
+ RTMemFree(pbBuf1);
+ RTMemFree(pbBuf2);
+ }
+ else
+ {
+ if (pbBuf1)
+ RTMemFree(pbBuf1);
+ if (pbBuf2)
+ RTMemFree(pbBuf2);
+ rc = VERR_NO_MEMORY;
+ }
+ }
+ else
+ rc = VERR_NOT_FOUND;
+
+ return rc;
+}
+
+static DECLCALLBACK(int) vdScriptHandlerDumpDiskInfo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
+{
+ int rc = VINF_SUCCESS;
+ const char *pcszDisk = NULL;
+ PVDDISK pDisk = NULL;
+
+ for (unsigned i = 0; i < cScriptArgs; i++)
+ {
+ switch (paScriptArgs[i].chId)
+ {
+ case 'd':
+ {
+ pcszDisk = paScriptArgs[i].u.pcszString;
+ break;
+ }
+ default:
+ AssertMsgFailed(("Invalid argument given!\n"));
+ }
+ }
+
+ pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
+
+ if (pDisk)
+ VDDumpImages(pDisk->pVD);
+ else
+ rc = VERR_NOT_FOUND;
+
+ return rc;
+}
+
+static DECLCALLBACK(int) vdScriptHandlerPrintMsg(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
+{
+ RTPrintf("%s\n", paScriptArgs[0].u.pcszString);
+ return VINF_SUCCESS;
+}
+
static DECLCALLBACK(int) tstVDIoFileOpen(void *pvUser, const char *pszLocation,
uint32_t fOpen,
PFNVDCOMPLETED pfnCompleted,
@@ -824,6 +1812,16 @@ static DECLCALLBACK(int) tstVDIoFileOpen(void *pvUser, const char *pszLocation,
PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
bool fFound = false;
+ /*
+ * Some backends use ./ for paths, strip it.
+ * @todo: Implement proper directory support for the
+ * memory filesystem.
+ */
+ if ( strlen(pszLocation) >= 2
+ && *pszLocation == '.'
+ && pszLocation[1] == '/')
+ pszLocation += 2;
+
/* Check if the file exists. */
PVDFILE pIt = NULL;
RTListForEach(&pGlob->ListFiles, pIt, VDFILE, Node)
@@ -835,9 +1833,7 @@ static DECLCALLBACK(int) tstVDIoFileOpen(void *pvUser, const char *pszLocation,
}
}
- if (fFound && pIt->pfnComplete)
- rc = VERR_FILE_LOCK_FAILED;
- else if ((fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE)
+ if ((fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE)
{
/* If the file exists delete the memory disk. */
if (fFound)
@@ -848,8 +1844,7 @@ static DECLCALLBACK(int) tstVDIoFileOpen(void *pvUser, const char *pszLocation,
pIt = (PVDFILE)RTMemAllocZ(sizeof(VDFILE));
if (pIt)
{
- pIt->pfnComplete = pfnCompleted;
- pIt->pszName = RTStrDup(pszLocation);
+ pIt->pszName = RTStrDup(pszLocation);
if (pIt->pszName)
{
@@ -875,8 +1870,6 @@ static DECLCALLBACK(int) tstVDIoFileOpen(void *pvUser, const char *pszLocation,
{
if (!fFound)
rc = VERR_FILE_NOT_FOUND;
- else
- pIt->pfnComplete = pfnCompleted;
}
else
rc = VERR_INVALID_PARAMETER;
@@ -884,7 +1877,13 @@ static DECLCALLBACK(int) tstVDIoFileOpen(void *pvUser, const char *pszLocation,
if (RT_SUCCESS(rc))
{
AssertPtr(pIt);
- *ppStorage = pIt;
+ PVDSTORAGE pStorage = (PVDSTORAGE)RTMemAllocZ(sizeof(VDSTORAGE));
+ if (!pStorage)
+ rc = VERR_NO_MEMORY;
+
+ pStorage->pFile = pIt;
+ pStorage->pfnComplete = pfnCompleted;
+ *ppStorage = pStorage;
}
return rc;
@@ -892,10 +1891,9 @@ static DECLCALLBACK(int) tstVDIoFileOpen(void *pvUser, const char *pszLocation,
static DECLCALLBACK(int) tstVDIoFileClose(void *pvUser, void *pStorage)
{
- PVDFILE pFile = (PVDFILE)pStorage;
+ PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
- /* Mark as not busy. */
- pFile->pfnComplete = NULL;
+ RTMemFree(pIoStorage);
return VINF_SUCCESS;
}
@@ -905,6 +1903,16 @@ static DECLCALLBACK(int) tstVDIoFileDelete(void *pvUser, const char *pcszFilenam
PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
bool fFound = false;
+ /*
+ * Some backends use ./ for paths, strip it.
+ * @todo: Implement proper directory support for the
+ * memory filesystem.
+ */
+ if ( strlen(pcszFilename) >= 2
+ && *pcszFilename == '.'
+ && pcszFilename[1] == '/')
+ pcszFilename += 2;
+
/* Check if the file exists. */
PVDFILE pIt = NULL;
RTListForEach(&pGlob->ListFiles, pIt, VDFILE, Node)
@@ -981,23 +1989,23 @@ static DECLCALLBACK(int) tstVDIoFileGetModificationTime(void *pvUser, const char
static DECLCALLBACK(int) tstVDIoFileGetSize(void *pvUser, void *pStorage, uint64_t *pcbSize)
{
- PVDFILE pFile = (PVDFILE)pStorage;
+ PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
- return VDMemDiskGetSize(pFile->pMemDisk, pcbSize);
+ return VDMemDiskGetSize(pIoStorage->pFile->pMemDisk, pcbSize);
}
static DECLCALLBACK(int) tstVDIoFileSetSize(void *pvUser, void *pStorage, uint64_t cbSize)
{
- PVDFILE pFile = (PVDFILE)pStorage;
+ PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
- return VDMemDiskSetSize(pFile->pMemDisk, cbSize);
+ return VDMemDiskSetSize(pIoStorage->pFile->pMemDisk, cbSize);
}
static DECLCALLBACK(int) tstVDIoFileWriteSync(void *pvUser, void *pStorage, uint64_t uOffset,
const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten)
{
int rc = VINF_SUCCESS;
- PVDFILE pFile = (PVDFILE)pStorage;
+ PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
RTSGBUF SgBuf;
RTSGSEG Seg;
@@ -1005,7 +2013,7 @@ static DECLCALLBACK(int) tstVDIoFileWriteSync(void *pvUser, void *pStorage, uint
Seg.pvSeg = (void *)pvBuffer;
Seg.cbSeg = cbBuffer;
RTSgBufInit(&SgBuf, &Seg, 1);
- rc = VDMemDiskWrite(pFile->pMemDisk, uOffset, cbBuffer, &SgBuf);
+ rc = VDMemDiskWrite(pIoStorage->pFile->pMemDisk, uOffset, cbBuffer, &SgBuf);
if (RT_SUCCESS(rc) && pcbWritten)
*pcbWritten = cbBuffer;
@@ -1016,7 +2024,7 @@ static DECLCALLBACK(int) tstVDIoFileReadSync(void *pvUser, void *pStorage, uint6
void *pvBuffer, size_t cbBuffer, size_t *pcbRead)
{
int rc = VINF_SUCCESS;
- PVDFILE pFile = (PVDFILE)pStorage;
+ PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
RTSGBUF SgBuf;
RTSGSEG Seg;
@@ -1024,7 +2032,7 @@ static DECLCALLBACK(int) tstVDIoFileReadSync(void *pvUser, void *pStorage, uint6
Seg.pvSeg = pvBuffer;
Seg.cbSeg = cbBuffer;
RTSgBufInit(&SgBuf, &Seg, 1);
- rc = VDMemDiskRead(pFile->pMemDisk, uOffset, cbBuffer, &SgBuf);
+ rc = VDMemDiskRead(pIoStorage->pFile->pMemDisk, uOffset, cbBuffer, &SgBuf);
if (RT_SUCCESS(rc) && pcbRead)
*pcbRead = cbBuffer;
@@ -1044,10 +2052,10 @@ static DECLCALLBACK(int) tstVDIoFileReadAsync(void *pvUser, void *pStorage, uint
{
int rc = VINF_SUCCESS;
PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
- PVDFILE pFile = (PVDFILE)pStorage;
+ PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
- rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pFile->pMemDisk, VDIOTXDIR_READ, uOffset,
- cbRead, paSegments, cSegments, pFile->pfnComplete, pvCompletion);
+ rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pIoStorage->pFile->pMemDisk, VDIOTXDIR_READ, uOffset,
+ cbRead, paSegments, cSegments, pIoStorage->pfnComplete, pvCompletion);
if (RT_SUCCESS(rc))
rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
@@ -1061,10 +2069,10 @@ static DECLCALLBACK(int) tstVDIoFileWriteAsync(void *pvUser, void *pStorage, uin
{
int rc = VINF_SUCCESS;
PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
- PVDFILE pFile = (PVDFILE)pStorage;
+ PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
- rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pFile->pMemDisk, VDIOTXDIR_WRITE, uOffset,
- cbWrite, paSegments, cSegments, pFile->pfnComplete, pvCompletion);
+ rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pIoStorage->pFile->pMemDisk, VDIOTXDIR_WRITE, uOffset,
+ cbWrite, paSegments, cSegments, pIoStorage->pfnComplete, pvCompletion);
if (RT_SUCCESS(rc))
rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
@@ -1076,20 +2084,22 @@ static DECLCALLBACK(int) tstVDIoFileFlushAsync(void *pvUser, void *pStorage, voi
{
int rc = VINF_SUCCESS;
PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
- PVDFILE pFile = (PVDFILE)pStorage;
+ PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
- rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pFile->pMemDisk, VDIOTXDIR_FLUSH, 0,
- 0, NULL, 0, pFile->pfnComplete, pvCompletion);
+ rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pIoStorage->pFile->pMemDisk, VDIOTXDIR_FLUSH, 0,
+ 0, NULL, 0, pIoStorage->pfnComplete, pvCompletion);
if (RT_SUCCESS(rc))
rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
return rc;
}
-static int tstVDIoTestInit(PVDIOTEST pIoTest, PVDTESTGLOB pGlob, bool fRandomAcc, size_t cbIo,
+static int tstVDIoTestInit(PVDIOTEST pIoTest, PVDTESTGLOB pGlob, bool fRandomAcc, uint64_t cbIo,
size_t cbBlkSize, uint64_t offStart, uint64_t offEnd,
- unsigned uWriteChance, unsigned uReadChance)
+ unsigned uWriteChance, PVDPATTERN pPattern)
{
+ int rc = VINF_SUCCESS;
+
pIoTest->fRandomAccess = fRandomAcc;
pIoTest->cbIo = cbIo;
pIoTest->cbBlkIo = cbBlkSize;
@@ -1097,8 +2107,33 @@ static int tstVDIoTestInit(PVDIOTEST pIoTest, PVDTESTGLOB pGlob, bool fRandomAcc
pIoTest->offEnd = offEnd;
pIoTest->uWriteChance = uWriteChance;
pIoTest->pIoRnd = pGlob->pIoRnd;
- pIoTest->offNext = pIoTest->offEnd < pIoTest->offStart ? pIoTest->offEnd - cbBlkSize : 0;
- return VINF_SUCCESS;
+ pIoTest->pPattern = pPattern;
+
+ if (fRandomAcc)
+ {
+ uint64_t cbRange = pIoTest->offEnd < pIoTest->offStart
+ ? pIoTest->offStart - pIoTest->offEnd
+ : pIoTest->offEnd - pIoTest->offStart;
+
+ pIoTest->u.Rnd.cBlocks = cbRange / cbBlkSize + ((cbRange % cbBlkSize) ? 1 : 0);
+ pIoTest->u.Rnd.cBlocksLeft = pIoTest->u.Rnd.cBlocks;
+ pIoTest->u.Rnd.pbMapAccessed = (uint8_t *)RTMemAllocZ(pIoTest->u.Rnd.cBlocks / 8
+ + ((pIoTest->u.Rnd.cBlocks % 8)
+ ? 1
+ : 0));
+ if (!pIoTest->u.Rnd.pbMapAccessed)
+ rc = VERR_NO_MEMORY;
+ }
+ else
+ pIoTest->u.offNext = pIoTest->offEnd < pIoTest->offStart ? pIoTest->offStart - cbBlkSize : 0;
+
+ return rc;
+}
+
+static void tstVDIoTestDestroy(PVDIOTEST pIoTest)
+{
+ if (pIoTest->fRandomAccess)
+ RTMemFree(pIoTest->u.Rnd.pbMapAccessed);
}
static bool tstVDIoTestRunning(PVDIOTEST pIoTest)
@@ -1121,10 +2156,10 @@ static bool tstVDIoTestIsTrue(PVDIOTEST pIoTest, int iPercentage)
{
int uRnd = VDIoRndGetU32Ex(pIoTest->pIoRnd, 0, 100);
- return (uRnd <= iPercentage); /* This should be enough for our purpose */
+ return (uRnd < iPercentage); /* This should be enough for our purpose */
}
-static int tstVDIoTestReqInit(PVDIOTEST pIoTest, PVDIOREQ pIoReq)
+static int tstVDIoTestReqInit(PVDIOTEST pIoTest, PVDIOREQ pIoReq, void *pvUser)
{
int rc = VINF_SUCCESS;
@@ -1135,19 +2170,19 @@ static int tstVDIoTestReqInit(PVDIOTEST pIoTest, PVDIOREQ pIoReq)
pIoReq->cbReq = RT_MIN(pIoTest->cbBlkIo, pIoTest->cbIo);
pIoTest->cbIo -= pIoReq->cbReq;
pIoReq->DataSeg.cbSeg = pIoReq->cbReq;
- pIoReq->off = pIoTest->offNext;
if (pIoReq->enmTxDir == VDIOREQTXDIR_WRITE)
{
- rc = VDIoRndGetBuffer(pIoTest->pIoRnd, &pIoReq->DataSeg.pvSeg, pIoReq->cbReq);
+ if (pIoTest->pPattern)
+ rc = tstVDIoPatternGetBuffer(pIoTest->pPattern, &pIoReq->DataSeg.pvSeg, pIoReq->cbReq);
+ else
+ rc = VDIoRndGetBuffer(pIoTest->pIoRnd, &pIoReq->DataSeg.pvSeg, pIoReq->cbReq);
AssertRC(rc);
}
else
{
/* Read */
- pIoReq->DataSeg.pvSeg = RTMemAlloc(pIoReq->cbReq);
- if (!pIoReq->DataSeg.pvSeg)
- rc = VERR_NO_MEMORY;
+ pIoReq->DataSeg.pvSeg = pIoReq->pvBufRead;
}
if (RT_SUCCESS(rc))
@@ -1156,14 +2191,59 @@ static int tstVDIoTestReqInit(PVDIOTEST pIoTest, PVDIOREQ pIoReq)
if (pIoTest->fRandomAccess)
{
- /** @todo */
+ int idx = -1;
+
+ idx = ASMBitFirstClear(pIoTest->u.Rnd.pbMapAccessed, pIoTest->u.Rnd.cBlocks);
+
+ /* In case this is the last request we don't need to search further. */
+ if (pIoTest->u.Rnd.cBlocksLeft > 1)
+ {
+ int idxIo;
+ idxIo = VDIoRndGetU32Ex(pIoTest->pIoRnd, idx, pIoTest->u.Rnd.cBlocks - 1);
+
+ /*
+ * If the bit is marked free use it, otherwise search for the next free bit
+ * and if that doesn't work use the first free bit.
+ */
+ if (ASMBitTest(pIoTest->u.Rnd.pbMapAccessed, idxIo))
+ {
+ idxIo = ASMBitNextClear(pIoTest->u.Rnd.pbMapAccessed, pIoTest->u.Rnd.cBlocks, idxIo);
+ if (idxIo != -1)
+ idx = idxIo;
+ }
+ else
+ idx = idxIo;
+ }
+
+ Assert(idx != -1);
+ pIoReq->off = idx * pIoTest->cbBlkIo;
+ pIoTest->u.Rnd.cBlocksLeft--;
+ if (!pIoTest->u.Rnd.cBlocksLeft)
+ {
+ /* New round, clear everything. */
+ ASMBitClearRange(pIoTest->u.Rnd.pbMapAccessed, 0, pIoTest->u.Rnd.cBlocks);
+ pIoTest->u.Rnd.cBlocksLeft = pIoTest->u.Rnd.cBlocks;
+ }
+ else
+ ASMBitSet(pIoTest->u.Rnd.pbMapAccessed, idx);
}
else
{
- pIoTest->offNext = pIoTest->offEnd < pIoTest->offStart
- ? RT_MAX(pIoTest->offEnd, pIoTest->offNext - pIoTest->cbBlkIo)
- : RT_MIN(pIoTest->offEnd, pIoTest->offNext + pIoTest->cbBlkIo);
+ pIoReq->off = pIoTest->u.offNext;
+ if (pIoTest->offEnd < pIoTest->offStart)
+ {
+ pIoTest->u.offNext = pIoTest->u.offNext == 0
+ ? pIoTest->offEnd - pIoTest->cbBlkIo
+ : RT_MAX(pIoTest->offEnd, pIoTest->u.offNext - pIoTest->cbBlkIo);
+ }
+ else
+ {
+ pIoTest->u.offNext = pIoTest->u.offNext + pIoTest->cbBlkIo >= pIoTest->offEnd
+ ? 0
+ : RT_MIN(pIoTest->offEnd, pIoTest->u.offNext + pIoTest->cbBlkIo);
+ }
}
+ pIoReq->pvUser = pvUser;
pIoReq->fOutstanding = true;
}
}
@@ -1177,6 +2257,39 @@ static void tstVDIoTestReqComplete(void *pvUser1, void *pvUser2, int rcReq)
{
PVDIOREQ pIoReq = (PVDIOREQ)pvUser1;
RTSEMEVENT hEventSem = (RTSEMEVENT)pvUser2;
+ PVDDISK pDisk = (PVDDISK)pIoReq->pvUser;
+
+ LogFlow(("Request %d completed\n", pIoReq->idx));
+
+ if (pDisk->pMemDiskVerify)
+ {
+ switch (pIoReq->enmTxDir)
+ {
+ case VDIOREQTXDIR_READ:
+ {
+ RTCritSectEnter(&pDisk->CritSectVerify);
+ RTSgBufReset(&pIoReq->SgBuf);
+
+ if (VDMemDiskCmp(pDisk->pMemDiskVerify, pIoReq->off, pIoReq->cbReq,
+ &pIoReq->SgBuf))
+ RTPrintf("Corrupted disk at offset %llu!\n", pIoReq->off);
+ RTCritSectLeave(&pDisk->CritSectVerify);
+ }
+ case VDIOREQTXDIR_WRITE:
+ {
+ RTCritSectEnter(&pDisk->CritSectVerify);
+ RTSgBufReset(&pIoReq->SgBuf);
+
+ int rc = VDMemDiskWrite(pDisk->pMemDiskVerify, pIoReq->off, pIoReq->cbReq,
+ &pIoReq->SgBuf);
+ AssertRC(rc);
+ RTCritSectLeave(&pDisk->CritSectVerify);
+ break;
+ }
+ case VDIOREQTXDIR_FLUSH:
+ break;
+ }
+ }
ASMAtomicXchgBool(&pIoReq->fOutstanding, false);
RTSemEventSignal(hEventSem);
@@ -1184,6 +2297,112 @@ static void tstVDIoTestReqComplete(void *pvUser1, void *pvUser2, int rcReq)
}
/**
+ * Returns the disk handle by name or NULL if not found
+ *
+ * @returns Disk handle or NULL if the disk could not be found.
+ *
+ * @param pGlob Global test state.
+ * @param pcszDisk Name of the disk to get.
+ */
+static PVDDISK tstVDIoGetDiskByName(PVDTESTGLOB pGlob, const char *pcszDisk)
+{
+ PVDDISK pIt = NULL;
+ bool fFound = false;
+
+ LogFlowFunc(("pGlob=%#p pcszDisk=%s\n", pGlob, pcszDisk));
+
+ RTListForEach(&pGlob->ListDisks, pIt, VDDISK, ListNode)
+ {
+ if (!RTStrCmp(pIt->pszName, pcszDisk))
+ {
+ fFound = true;
+ break;
+ }
+ }
+
+ LogFlowFunc(("return %#p\n", fFound ? pIt : NULL));
+ return fFound ? pIt : NULL;
+}
+
+/**
+ * Returns the I/O pattern handle by name of NULL if not found.
+ *
+ * @returns I/O pattern handle or NULL if the pattern could not be found.
+ *
+ * @param pGlob Global test state.
+ * @param pcszName Name of the pattern.
+ */
+static PVDPATTERN tstVDIoGetPatternByName(PVDTESTGLOB pGlob, const char *pcszName)
+{
+ PVDPATTERN pIt = NULL;
+ bool fFound = false;
+
+ LogFlowFunc(("pGlob=%#p pcszName=%s\n", pGlob, pcszName));
+
+ RTListForEach(&pGlob->ListPatterns, pIt, VDPATTERN, ListNode)
+ {
+ if (!RTStrCmp(pIt->pszName, pcszName))
+ {
+ fFound = true;
+ break;
+ }
+ }
+
+ LogFlowFunc(("return %#p\n", fFound ? pIt : NULL));
+ return fFound ? pIt : NULL;
+}
+
+/**
+ * Creates a new pattern with the given name and an
+ * allocated pattern buffer.
+ *
+ * @returns Pointer to a new pattern buffer or NULL on failure.
+ * @param pcszName Name of the pattern.
+ * @param cbPattern Size of the pattern buffer.
+ */
+static PVDPATTERN tstVDIoPatternCreate(const char *pcszName, size_t cbPattern)
+{
+ PVDPATTERN pPattern = (PVDPATTERN)RTMemAllocZ(sizeof(VDPATTERN));
+ char *pszName = RTStrDup(pcszName);
+ void *pvPattern = RTMemAllocZ(cbPattern);
+
+ if (pPattern && pszName && pvPattern)
+ {
+ pPattern->pszName = pszName;
+ pPattern->pvPattern = pvPattern;
+ pPattern->cbPattern = cbPattern;
+ }
+ else
+ {
+ if (pPattern)
+ RTMemFree(pPattern);
+ if (pszName)
+ RTStrFree(pszName);
+ if (pvPattern)
+ RTMemFree(pvPattern);
+
+ pPattern = NULL;
+ pszName = NULL;
+ pvPattern = NULL;
+ }
+
+ return pPattern;
+}
+
+static int tstVDIoPatternGetBuffer(PVDPATTERN pPattern, void **ppv, size_t cb)
+{
+ AssertPtrReturn(pPattern, VERR_INVALID_POINTER);
+ AssertPtrReturn(ppv, VERR_INVALID_POINTER);
+ AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+
+ if (cb > pPattern->cbPattern)
+ return VERR_INVALID_PARAMETER;
+
+ *ppv = pPattern->pvPattern;
+ return VINF_SUCCESS;
+}
+
+/**
* Skips the characters until the given character is reached.
*
* @returns Start of the string with the given character
@@ -1237,6 +2456,21 @@ static char *tstVDIoScriptSkipNonSpace(char *psz)
}
/**
+ * Returns true if the first character of the given string
+ * contains a character marking a line end (comment or \0
+ * terminator).
+ *
+ * @returns true if the line contains no more characters of
+ * interest and false otherwise.
+ *
+ * @param psz The string to check for.
+ */
+static bool tstVDIoIsLineEnd(const char *psz)
+{
+ return *psz == '\0' || *psz == '#';
+}
+
+/**
* Parses one argument name, value pair.
*
* @returns IPRT status code.
@@ -1364,6 +2598,8 @@ static int tstVDIoScriptArgumentParse(PCVDSCRIPTACTION pVDScriptAction, const ch
rc = VERR_INVALID_PARAMETER;
}
}
+ if (RT_SUCCESS(rc))
+ pszSuffix++;
}
if (*pszSuffix == '-')
@@ -1456,40 +2692,42 @@ static int tstVDIoScriptArgumentListParse(char *psz, PCVDSCRIPTACTION pVDScriptA
*pcScriptArgs = 0;
while ( psz
- && *psz != '\0')
+ && !tstVDIoIsLineEnd(psz))
{
const char *pcszName = psz;
psz = tstVDIoScriptSkipUntil(psz, '=');
- if (psz != '\0')
+ if (!tstVDIoIsLineEnd(psz))
{
*psz = '\0'; /* Overwrite */
psz++;
const char *pcszValue = psz;
psz = tstVDIoScriptSkipNonSpace(psz);
- if (psz != '\0')
+ if (!tstVDIoIsLineEnd(psz))
{
*psz = '\0'; /* Overwrite */
psz++;
psz = tstVDIoScriptSkipSpace(psz);
-
- /* We have the name and value pair now. */
- bool fMandatory;
- rc = tstVDIoScriptArgumentParse(pVDScriptAction, pcszName, pcszValue, &paScriptArgs[cScriptArgs], &fMandatory);
- if (RT_SUCCESS(rc))
- {
- if (fMandatory)
- cMandatoryArgsReq--;
- cScriptArgs++;
- }
}
- else
+
+ pcszValue = tstVDIoScriptSkipSpace((char *)pcszValue);
+ if (*pcszValue == '\0')
{
RTPrintf("Value missing for argument '%s'\n", pcszName);
rc = VERR_INVALID_STATE;
break;
}
+
+ /* We have the name and value pair now. */
+ bool fMandatory = false; /* Shut up gcc */
+ rc = tstVDIoScriptArgumentParse(pVDScriptAction, pcszName, pcszValue, &paScriptArgs[cScriptArgs], &fMandatory);
+ if (RT_SUCCESS(rc))
+ {
+ if (fMandatory)
+ cMandatoryArgsReq--;
+ cScriptArgs++;
+ }
}
else
{
@@ -1539,7 +2777,7 @@ static int tstVDIoScriptExecute(PRTSTREAM pStrm, PVDTESTGLOB pGlob)
/* Skip space */
psz = tstVDIoScriptSkipSpace(psz);
- if (psz != '\0')
+ if (!tstVDIoIsLineEnd(psz))
{
PCVDSCRIPTACTION pVDScriptAction = NULL;
@@ -1547,7 +2785,7 @@ static int tstVDIoScriptExecute(PRTSTREAM pStrm, PVDTESTGLOB pGlob)
pcszAction = psz;
psz = tstVDIoScriptSkipNonSpace(psz);
- if (psz != '\0')
+ if (!tstVDIoIsLineEnd(psz))
{
Assert(RT_C_IS_SPACE(*psz));
*psz++ = '\0';
@@ -1599,11 +2837,7 @@ static int tstVDIoScriptExecute(PRTSTREAM pStrm, PVDTESTGLOB pGlob)
rc = VERR_NOT_FOUND;
}
}
- else
- {
- RTPrintf("Missing action name\n");
- rc = VERR_INVALID_STATE;
- }
+ /* else empty line, just continue */
}
} while(RT_SUCCESS(rc));
@@ -1630,6 +2864,8 @@ static void tstVDIoScriptRun(const char *pcszFilename)
memset(&GlobTest, 0, sizeof(VDTESTGLOB));
RTListInit(&GlobTest.ListFiles);
+ RTListInit(&GlobTest.ListDisks);
+ RTListInit(&GlobTest.ListPatterns);
rc = RTStrmOpen(pcszFilename, "r", &pScriptStrm);
if (RT_SUCCESS(rc))
@@ -1669,18 +2905,12 @@ static void tstVDIoScriptRun(const char *pcszFilename)
rc = VDIoBackendMemCreate(&GlobTest.pIoBackend);
if (RT_SUCCESS(rc))
{
- rc = VDCreate(GlobTest.pInterfacesDisk, VDTYPE_HDD, &GlobTest.pVD);
- if (RT_SUCCESS(rc))
+ /* Execute the script. */
+ rc = tstVDIoScriptExecute(pScriptStrm, &GlobTest);
+ if (RT_FAILURE(rc))
{
- /* Execute the script. */
- rc = tstVDIoScriptExecute(pScriptStrm, &GlobTest);
- if (RT_FAILURE(rc))
- {
- RTPrintf("Executing the script stream failed rc=%Rrc\n", rc);
- }
+ RTPrintf("Executing the script stream failed rc=%Rrc\n", rc);
}
- else
- RTPrintf("Failed to create disk container rc=%Rrc\n", rc);
VDIoBackendMemDestroy(GlobTest.pIoBackend);
}
else
diff --git a/src/VBox/Storage/testcase/tstVDIo.vd b/src/VBox/Storage/testcase/tstVDIo.vd
new file mode 100644
index 000000000..9505e710e
--- /dev/null
+++ b/src/VBox/Storage/testcase/tstVDIo.vd
@@ -0,0 +1,67 @@
+# $Id: tstVDIo.vd 36135 2011-03-02 23:43:51Z vboxsync $
+#
+# Storage: Simple I/O testing for most backends.
+#
+
+#
+# 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.
+#
+
+# Init I/O RNG for generating random data for writes
+iorngcreate size=10M mode=manual seed=1234567890
+
+# VMDK disk
+print msg=Testing_VMDK
+createdisk name=test verify=yes
+create disk=test mode=base name=tstShared.vmdk type=dynamic backend=VMDK size=200M
+io disk=test async=yes max-reqs=32 mode=seq blocksize=64k off=0-200M size=200M writes=100
+io disk=test async=yes max-reqs=32 mode=seq blocksize=64k off=0-200M size=200M writes=0
+create disk=test mode=diff name=tstShared2.vmdk type=dynamic backend=VMDK size=20M
+io disk=test async=yes max-reqs=32 mode=rnd blocksize=64k off=0-200M size=200M writes=50
+create disk=test mode=diff name=tstShared3.vmdk type=dynamic backend=VMDK size=20M
+io disk=test async=yes max-reqs=32 mode=rnd blocksize=64k off=0-200M size=200M writes=50
+close disk=test mode=single delete=yes
+close disk=test mode=single delete=yes
+close disk=test mode=single delete=yes
+destroydisk name=test
+
+# VDI disk
+print msg=Testing_VDI
+createdisk name=test verify=yes
+create disk=test mode=base name=tstShared.vdi type=dynamic backend=VDI size=200M
+io disk=test async=yes max-reqs=32 mode=seq blocksize=64k off=0-200M size=200M writes=100
+io disk=test async=yes max-reqs=32 mode=seq blocksize=64k off=0-200M size=200M writes=0
+create disk=test mode=diff name=tstShared2.vdi type=dynamic backend=VDI size=20M
+io disk=test async=yes max-reqs=32 mode=rnd blocksize=64k off=0-200M size=200M writes=50
+create disk=test mode=diff name=tstShared3.vdi type=dynamic backend=VDI size=20M
+io disk=test async=yes max-reqs=32 mode=rnd blocksize=64k off=0-200M size=200M writes=50
+close disk=test mode=single delete=yes
+close disk=test mode=single delete=yes
+close disk=test mode=single delete=yes
+destroydisk name=test
+
+# VHD disk
+print msg=Testing_VHD
+createdisk name=test verify=yes
+create disk=test mode=base name=tstShared.vhd type=dynamic backend=VHD size=200M
+io disk=test async=yes max-reqs=32 mode=seq blocksize=64k off=0-200M size=200M writes=100
+io disk=test async=yes max-reqs=32 mode=seq blocksize=64k off=0-200M size=200M writes=0
+create disk=test mode=diff name=tstShared2.vhd type=dynamic backend=VHD size=20M
+io disk=test async=yes max-reqs=32 mode=rnd blocksize=64k off=0-200M size=200M writes=50
+create disk=test mode=diff name=tstShared3.vhd type=dynamic backend=VHD size=20M
+io disk=test async=yes max-reqs=32 mode=rnd blocksize=64k off=0-200M size=200M writes=50
+close disk=test mode=single delete=yes
+close disk=test mode=single delete=yes
+close disk=test mode=single delete=yes
+destroydisk name=test
+
+iorngdestroy
+
diff --git a/src/VBox/Storage/testcase/tstVDShareable.cpp b/src/VBox/Storage/testcase/tstVDShareable.cpp
index 328b6522e..137952909 100644
--- a/src/VBox/Storage/testcase/tstVDShareable.cpp
+++ b/src/VBox/Storage/testcase/tstVDShareable.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstVDShareable.cpp $ */
+/* $Id: tstVDShareable.cpp 33567 2010-10-28 15:37:21Z vboxsync $ */
/** @file
* Simple VBox HDD container test utility for shareable images.
*/
diff --git a/src/VBox/Storage/testcase/tstVDShareable.vd b/src/VBox/Storage/testcase/tstVDShareable.vd
new file mode 100644
index 000000000..103a9a453
--- /dev/null
+++ b/src/VBox/Storage/testcase/tstVDShareable.vd
@@ -0,0 +1,53 @@
+# $Id: tstVDShareable.vd 36131 2011-03-02 21:56:42Z vboxsync $
+#
+# Storage: Testcase for shareable disks.
+#
+
+#
+# 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.
+#
+
+# Init I/O RNG for generating random data for writes
+iorngcreate size=10M mode=manual seed=1234567890
+
+# Create disk containers.
+createdisk name=shared1
+createdisk name=shared2
+
+# Create the disk and close it.
+create disk=shared1 mode=base name=tstShared.vdi type=fixed backend=VDI size=20M
+close disk=shared1 mode=all delete=no
+
+# Open the disk with sharing enabled.
+open disk=shared1 name=tstShared.vdi backend=VDI shareable=yes
+open disk=shared2 name=tstShared.vdi backend=VDI shareable=yes
+
+# Write to one disk and verify that the other disk can see the content.
+io disk=shared1 async=yes max-reqs=32 mode=seq blocksize=64k off=0-20M size=20M writes=100
+comparedisks disk1=shared1 disk2=shared2
+
+# Write to the second disk and verify that the first can see the content.
+io disk=shared2 async=yes max-reqs=64 mode=seq blocksize=8k off=0-20M size=20M writes=50
+comparedisks disk1=shared1 disk2=shared2
+
+# Close but don't delete yet.
+close disk=shared1 mode=all delete=no
+close disk=shared2 mode=all delete=no
+
+# Open and delete
+open disk=shared1 name=tstShared.vdi backend=VDI shareable=no
+close disk=shared1 mode=single delete=yes
+
+# Cleanup
+destroydisk name=shared1
+destroydisk name=shared2
+iorngdestroy
+
diff --git a/src/VBox/Storage/testcase/vbox-img.cpp b/src/VBox/Storage/testcase/vbox-img.cpp
index c77447fe8..9130de614 100644
--- a/src/VBox/Storage/testcase/vbox-img.cpp
+++ b/src/VBox/Storage/testcase/vbox-img.cpp
@@ -1,4 +1,4 @@
-/* $Id: vbox-img.cpp $ */
+/* $Id: vbox-img.cpp 33745 2010-11-03 18:31:53Z vboxsync $ */
/** @file
* Standalone image manipulation tool
*/
diff --git a/src/VBox/VMM/Docs-CodingGuidelines.cpp b/src/VBox/VMM/Docs-CodingGuidelines.cpp
index e35ae72f9..9a5d4f2c5 100644
--- a/src/VBox/VMM/Docs-CodingGuidelines.cpp
+++ b/src/VBox/VMM/Docs-CodingGuidelines.cpp
@@ -1,4 +1,4 @@
-/* $Id: Docs-CodingGuidelines.cpp $ */
+/* $Id: Docs-CodingGuidelines.cpp 35350 2010-12-27 16:57:10Z vboxsync $ */
/** @file
* VMM - Coding Guidelines.
*/
diff --git a/src/VBox/VMM/Docs-RawMode.cpp b/src/VBox/VMM/Docs-RawMode.cpp
index 662ea93d6..54ca7fdb3 100644
--- a/src/VBox/VMM/Docs-RawMode.cpp
+++ b/src/VBox/VMM/Docs-RawMode.cpp
@@ -1,4 +1,4 @@
-/* $Id: Docs-RawMode.cpp $ */
+/* $Id: Docs-RawMode.cpp 35350 2010-12-27 16:57:10Z vboxsync $ */
/** @file
* This file contains the documentation of the raw-mode execution.
*/
diff --git a/src/VBox/VMM/Makefile.kmk b/src/VBox/VMM/Makefile.kmk
index 700ca3931..420d9bdf4 100644
--- a/src/VBox/VMM/Makefile.kmk
+++ b/src/VBox/VMM/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37581 2011-06-21 19:18:46Z vboxsync $
## @file
# Top-level makefile for the VMM.
#
@@ -41,8 +41,16 @@ endif
ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
VMM_COMMON_DEFS += VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
endif
+ifdef VBOX_WITH_PCI_PASSTHROUGH
+ VMM_COMMON_DEFS += VBOX_WITH_PCI_PASSTHROUGH
+endif
# VMM_COMMON_DEFS += VBOX_WITH_NS_ACCOUNTING_STATS
+# Special IEM debug mode which compares the result with REM.
+ifdef IEM_VERIFICATION_MODE
+ VMM_COMMON_DEFS += IEM_VERIFICATION_MODE
+endif
+
#
# VMMR3.dll
@@ -92,10 +100,12 @@ VMMR3_SOURCES = \
VMMR3/DBGFReg.cpp \
VMMR3/DBGFStack.cpp \
VMMR3/DBGFSym.cpp \
+ VMMR3/DBGFR3Trace.cpp \
VMMR3/EM.cpp \
VMMR3/EMRaw.cpp \
VMMR3/EMHwaccm.cpp \
VMMR3/FTM.cpp \
+ VMMR3/IEMR3.cpp \
VMMR3/IOM.cpp \
VMMR3/GMM.cpp \
VMMR3/MM.cpp \
@@ -162,6 +172,9 @@ VMMR3_SOURCES = \
VMMAll/EMAll.cpp \
VMMAll/EMAllA.asm \
VMMAll/FTMAll.cpp \
+ VMMAll/IEMAll.cpp \
+ VMMAll/IEMAllAImpl.asm \
+ VMMAll/IEMAllAImplC.cpp \
VMMAll/TMAll.cpp \
VMMAll/TMAllCpu.cpp \
VMMAll/TMAllReal.cpp \
@@ -436,6 +449,9 @@ ifndef VBOX_ONLY_EXTPACKS
ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
VMMR0_DEFS += VBOX_WITH_VMMR0_DISABLE_PREEMPTION
endif
+ ifdef VBOX_WITH_PCI_PASSTHROUGH
+ VMMR0_DEFS += IN_PCIRAW_R0
+ endif
VMMR0_DEFS.darwin = VMM_R0_SWITCH_STACK
VMMR0_DEFS.darwin.x86 = \
VBOX_WITH_2X_4GB_ADDR_SPACE VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 \
@@ -545,6 +561,18 @@ VMMAll/VMMAll.cpp_DEFS = VBOX_SVN_REV=$(VBOX_SVN_REV)
VMMR3/PGMPool.cpp_CXXFLAGS = $(if-expr $(KBUILD_TARGET) == "win",,$(VBOX_GCC_Wno-array_bounds))
VMMAll/PGMAllPool.cpp_CXXFLAGS = $(if-expr $(KBUILD_TARGET) == "win",,$(VBOX_GCC_Wno-array_bounds))
+#
+# Always optimize the interpreter.
+#
+if1of ($(KBUILD_TARGET), win)
+#VMMAll/IEMAll.cpp_CXXFLAGS = TODO
+#else if1of ($(KBUILD_TARGET_ARCH), amd64)
+# VMMAll/IEMAll.cpp_CXXFLAGS = -O2 -fomit-frame-pointer
+else
+ VMMAll/IEMAll.cpp_CXXFLAGS = -O2 #-fomit-frame-pointer - latter causes trouble on mac.
+endif
+
+
include $(KBUILD_PATH)/subfooter.kmk
@@ -563,3 +591,9 @@ PGMPhysRWTmpl.o PGMPhysRWTmpl.obj: PGMPhys.o
PGMInline.o PGMInline.obj: PGMDbg.o
+# Alias the IEM templates to the object in which they are instantiated.
+IEMInternal.o \
+IEMAllInstructions.cpp.o IEMAllInstructions.cpp.obj \
+IEMAllCImpl.cpp.o IEMAllCImpl.cpp.obj \
+IEMAllCImplStrInstr.cpp.o IEMAllCImplStrInstr.cpp.obj: IEMAll.o
+
diff --git a/src/VBox/VMM/VMMAll/CPUMAllA.asm b/src/VBox/VMM/VMMAll/CPUMAllA.asm
index 7282deaf1..58515c358 100644
--- a/src/VBox/VMM/VMMAll/CPUMAllA.asm
+++ b/src/VBox/VMM/VMMAll/CPUMAllA.asm
@@ -1,4 +1,4 @@
-; $Id: CPUMAllA.asm $
+; $Id: CPUMAllA.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; CPUM - Guest Context Assembly Routines.
;
@@ -23,7 +23,7 @@
%include "VBox/err.mac"
%include "VBox/vmm/stam.mac"
%include "CPUMInternal.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "VBox/vmm/cpum.mac"
%ifdef IN_RING3
diff --git a/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp b/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
index 37c06b739..72a505b11 100644
--- a/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
+++ b/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
@@ -1,4 +1,4 @@
-/* $Id: CPUMAllRegs.cpp $ */
+/* $Id: CPUMAllRegs.cpp 37136 2011-05-18 14:45:47Z vboxsync $ */
/** @file
* CPUM - CPU Monitor(/Manager) - Getters and Setters.
*/
@@ -474,26 +474,24 @@ VMMDECL(PCPUMCTX) CPUMQueryGuestCtxPtr(PVMCPU pVCpu)
return &pVCpu->cpum.s.Guest;
}
-VMMDECL(int) CPUMSetGuestGDTR(PVMCPU pVCpu, uint32_t addr, uint16_t limit)
+VMMDECL(int) CPUMSetGuestGDTR(PVMCPU pVCpu, uint64_t GCPtrBase, uint16_t cbLimit)
{
- pVCpu->cpum.s.Guest.gdtr.cbGdt = limit;
- pVCpu->cpum.s.Guest.gdtr.pGdt = addr;
+ pVCpu->cpum.s.Guest.gdtr.cbGdt = cbLimit;
+ pVCpu->cpum.s.Guest.gdtr.pGdt = GCPtrBase;
pVCpu->cpum.s.fChanged |= CPUM_CHANGED_GDTR;
return VINF_SUCCESS;
}
-VMMDECL(int) CPUMSetGuestIDTR(PVMCPU pVCpu, uint32_t addr, uint16_t limit)
+VMMDECL(int) CPUMSetGuestIDTR(PVMCPU pVCpu, uint64_t GCPtrBase, uint16_t cbLimit)
{
- pVCpu->cpum.s.Guest.idtr.cbIdt = limit;
- pVCpu->cpum.s.Guest.idtr.pIdt = addr;
+ pVCpu->cpum.s.Guest.idtr.cbIdt = cbLimit;
+ pVCpu->cpum.s.Guest.idtr.pIdt = GCPtrBase;
pVCpu->cpum.s.fChanged |= CPUM_CHANGED_IDTR;
return VINF_SUCCESS;
}
VMMDECL(int) CPUMSetGuestTR(PVMCPU pVCpu, uint16_t tr)
{
- AssertMsgFailed(("Need to load the hidden bits too!\n"));
-
pVCpu->cpum.s.Guest.tr = tr;
pVCpu->cpum.s.fChanged |= CPUM_CHANGED_TR;
return VINF_SUCCESS;
@@ -865,7 +863,13 @@ VMMDECL(int) CPUMQueryGuestMsr(PVMCPU pVCpu, uint32_t idMsr, uint64_t *puValue)
/* Needs to be tested more before enabling. */
*puValue = pVCpu->cpum.s.GuestMsr.msr.miscEnable;
#else
- *puValue = 0;
+ /* Currenty we don't allow guests to modify enable MSRs. */
+ *puValue = MSR_IA32_MISC_ENABLE_FAST_STRINGS /* by default */;
+
+ if ((pVCpu->CTX_SUFF(pVM)->cpum.s.aGuestCpuIdStd[1].ecx & X86_CPUID_FEATURE_ECX_MONITOR) != 0)
+
+ *puValue |= MSR_IA32_MISC_ENABLE_MONITOR /* if mwait/monitor available */;
+ /** @todo: add more cpuid-controlled features this way. */
#endif
break;
@@ -1641,6 +1645,15 @@ VMMDECL(void) CPUMSetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature)
break;
}
+ /*
+ * Set the Hypervisor Present bit in the standard feature mask.
+ */
+ case CPUMCPUIDFEATURE_HVP:
+ if (pVM->cpum.s.aGuestCpuIdStd[0].eax >= 1)
+ pVM->cpum.s.aGuestCpuIdStd[1].ecx |= X86_CPUID_FEATURE_ECX_HVP;
+ LogRel(("CPUMSetGuestCpuIdFeature: Enabled Hypervisor Present bit\n"));
+ break;
+
default:
AssertMsgFailed(("enmFeature=%d\n", enmFeature));
break;
@@ -1766,6 +1779,11 @@ VMMDECL(void) CPUMClearGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature)
break;
}
+ case CPUMCPUIDFEATURE_HVP:
+ if (pVM->cpum.s.aGuestCpuIdExt[0].eax >= 1)
+ pVM->cpum.s.aGuestCpuIdExt[1].ecx &= ~X86_CPUID_FEATURE_ECX_HVP;
+ break;
+
default:
AssertMsgFailed(("enmFeature=%d\n", enmFeature));
break;
@@ -2052,6 +2070,19 @@ VMMDECL(bool) CPUMIsGuestInRealMode(PVMCPU pVCpu)
/**
+ * Tests if the guest is running in real or virtual 8086 mode.
+ *
+ * @returns @c true if it is, @c false if not.
+ * @param pVCpu The virtual CPU handle.
+ */
+VMMDECL(bool) CPUMIsGuestInRealOrV86Mode(PVMCPU pVCpu)
+{
+ return !(pVCpu->cpum.s.Guest.cr0 & X86_CR0_PE)
+ || pVCpu->cpum.s.Guest.eflags.Bits.u1VM; /** @todo verify that this cannot be set in long mode. */
+}
+
+
+/**
* Tests if the guest is running in protected or not.
*
* @returns true if in protected mode, otherwise false.
diff --git a/src/VBox/VMM/VMMAll/CPUMStack.cpp b/src/VBox/VMM/VMMAll/CPUMStack.cpp
index 31506e4b7..12112a228 100644
--- a/src/VBox/VMM/VMMAll/CPUMStack.cpp
+++ b/src/VBox/VMM/VMMAll/CPUMStack.cpp
@@ -1,4 +1,4 @@
-/* $Id: CPUMStack.cpp $ */
+/* $Id: CPUMStack.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* CPUM - CPU Monitor(/Manager) - Stack manipulation.
*/
diff --git a/src/VBox/VMM/VMMAll/CSAMAll.cpp b/src/VBox/VMM/VMMAll/CSAMAll.cpp
index 8f5b4742a..73a10ee1a 100644
--- a/src/VBox/VMM/VMMAll/CSAMAll.cpp
+++ b/src/VBox/VMM/VMMAll/CSAMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: CSAMAll.cpp $ */
+/* $Id: CSAMAll.cpp 35348 2010-12-27 16:35:23Z vboxsync $ */
/** @file
* CSAM - Guest OS Code Scanning and Analysis Manager - Any Context
*/
diff --git a/src/VBox/VMM/VMMAll/DBGFAll.cpp b/src/VBox/VMM/VMMAll/DBGFAll.cpp
index 090a78598..f5742250b 100644
--- a/src/VBox/VMM/VMMAll/DBGFAll.cpp
+++ b/src/VBox/VMM/VMMAll/DBGFAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFAll.cpp $ */
+/* $Id: DBGFAll.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, All Context Code.
*/
diff --git a/src/VBox/VMM/VMMAll/EMAll.cpp b/src/VBox/VMM/VMMAll/EMAll.cpp
index 0fc0c7d3c..a3859175f 100644
--- a/src/VBox/VMM/VMMAll/EMAll.cpp
+++ b/src/VBox/VMM/VMMAll/EMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: EMAll.cpp $ */
+/* $Id: EMAll.cpp 37731 2011-07-01 13:51:57Z vboxsync $ */
/** @file
* EM - Execution Monitor(/Manager) - All contexts
*/
@@ -659,7 +659,7 @@ static int emInterpretIncDec(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXC
pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->param1, pParam1);
#ifdef IN_RC
/* Safety check (in theory it could cross a page boundary and fault there though) */
- AssertReturn(pParam1 == pvFault, VERR_EM_INTERPRETER);
+ EM_ASSERT_FAULT_RETURN(pParam1 == pvFault, VERR_EM_INTERPRETER);
#endif
rc = emRamRead(pVM, pVCpu, pRegFrame, &valpar1, pParam1, param1.size);
if (RT_FAILURE(rc))
@@ -2665,7 +2665,7 @@ static const char *emMSRtoString(uint32_t uMsr)
case MSR_IA32_TSC:
return "MSR_IA32_TSC";
case MSR_IA32_MISC_ENABLE:
- return "Unsupported MSR_IA32_MISC_ENABLE";
+ return "MSR_IA32_MISC_ENABLE";
case MSR_IA32_MTRR_CAP:
return "Unsupported MSR_IA32_MTRR_CAP";
case MSR_IA32_MCP_CAP:
@@ -3109,7 +3109,8 @@ VMMDECL(void) EMRemLock(PVM pVM)
if (!PDMCritSectIsInitialized(&pVM->em.s.CritSectREM))
return; /* early init */
- Assert(!PGMIsLockOwner(pVM) && !IOMIsLockOwner(pVM));
+ Assert(!PGMIsLockOwner(pVM));
+ Assert(!IOMIsLockOwner(pVM));
int rc = PDMCritSectEnter(&pVM->em.s.CritSectREM, VERR_SEM_BUSY);
AssertMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc));
}
@@ -3135,6 +3136,9 @@ VMMDECL(void) EMRemUnlock(PVM pVM)
*/
VMMDECL(bool) EMRemIsLockOwner(PVM pVM)
{
+ if (!PDMCritSectIsInitialized(&pVM->em.s.CritSectREM))
+ return true; /* early init */
+
return PDMCritSectIsOwner(&pVM->em.s.CritSectREM);
}
@@ -3144,8 +3148,11 @@ VMMDECL(bool) EMRemIsLockOwner(PVM pVM)
* @returns VBox status code
* @param pVM The VM to operate on.
*/
-VMMDECL(int) EMTryEnterRemLock(PVM pVM)
+VMMDECL(int) EMRemTryLock(PVM pVM)
{
+ if (!PDMCritSectIsInitialized(&pVM->em.s.CritSectREM))
+ return VINF_SUCCESS; /* early init */
+
return PDMCritSectTryEnter(&pVM->em.s.CritSectREM);
}
diff --git a/src/VBox/VMM/VMMAll/EMAllA.asm b/src/VBox/VMM/VMMAll/EMAllA.asm
index f4b652c1a..39ea98787 100644
--- a/src/VBox/VMM/VMMAll/EMAllA.asm
+++ b/src/VBox/VMM/VMMAll/EMAllA.asm
@@ -1,4 +1,4 @@
-; $Id: EMAllA.asm $
+; $Id: EMAllA.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; EM Assembly Routines.
;
@@ -20,7 +20,7 @@
;*******************************************************************************
%include "VBox/asmdefs.mac"
%include "VBox/err.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
;; @def MY_PTR_REG
; The register we use for value pointers (And,Or,Dec,Inc,XAdd).
diff --git a/src/VBox/VMM/VMMAll/FTMAll.cpp b/src/VBox/VMM/VMMAll/FTMAll.cpp
index 943dadb54..e90326239 100644
--- a/src/VBox/VMM/VMMAll/FTMAll.cpp
+++ b/src/VBox/VMM/VMMAll/FTMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: FTMAll.cpp $ */
+/* $Id: FTMAll.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* FTM - Fault Tolerance Manager - All contexts
*/
diff --git a/src/VBox/VMM/VMMAll/HWACCMAll.cpp b/src/VBox/VMM/VMMAll/HWACCMAll.cpp
index 5e1f1a9c8..bafe3666b 100644
--- a/src/VBox/VMM/VMMAll/HWACCMAll.cpp
+++ b/src/VBox/VMM/VMMAll/HWACCMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: HWACCMAll.cpp $ */
+/* $Id: HWACCMAll.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* HWACCM - All contexts.
*/
@@ -24,7 +24,6 @@
#include <VBox/vmm/pgm.h>
#include "HWACCMInternal.h"
#include <VBox/vmm/vm.h>
-#include <VBox/x86.h>
#include <VBox/vmm/hwacc_vmx.h>
#include <VBox/vmm/hwacc_svm.h>
#include <VBox/err.h>
@@ -33,6 +32,7 @@
#include <iprt/assert.h>
#include <iprt/asm.h>
#include <iprt/string.h>
+#include <iprt/x86.h>
/**
* Queues a page for invalidation
@@ -96,6 +96,7 @@ VMMDECL(int) HWACCMFlushTLB(PVMCPU pVCpu)
}
#ifdef IN_RING0
+
/**
* Dummy RTMpOnSpecific handler since RTMpPokeCpu couldn't be used.
*
@@ -106,19 +107,18 @@ static DECLCALLBACK(void) hwaccmFlushHandler(RTCPUID idCpu, void *pvUser1, void
}
/**
- * Wrapper for RTMpPokeCpu to deal with VERR_NOT_SUPPORTED
- *
+ * Wrapper for RTMpPokeCpu to deal with VERR_NOT_SUPPORTED.
*/
-void hwaccmMpPokeCpu(PVMCPU pVCpu, RTCPUID idHostCpu)
+static void hmR0PokeCpu(PVMCPU pVCpu, RTCPUID idHostCpu)
{
- uint32_t cWorldSwitchExit = pVCpu->hwaccm.s.cWorldSwitchExit;
-
- Assert(idHostCpu == pVCpu->idHostCpu);
+ uint32_t cWorldSwitchExits = ASMAtomicUoReadU32(&pVCpu->hwaccm.s.cWorldSwitchExits);
STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatPoke, x);
int rc = RTMpPokeCpu(idHostCpu);
STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatPoke, x);
- /* Not implemented on some platforms (Darwin, Linux kernel < 2.6.19); fall back to a less efficient implementation (broadcast). */
+
+ /* Not implemented on some platforms (Darwin, Linux kernel < 2.6.19); fall
+ back to a less efficient implementation (broadcast). */
if (rc == VERR_NOT_SUPPORTED)
{
STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatSpinPoke, z);
@@ -133,21 +133,54 @@ void hwaccmMpPokeCpu(PVMCPU pVCpu, RTCPUID idHostCpu)
else
STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatSpinPokeFailed, z);
- /* Spin until the VCPU has switched back. */
- while ( pVCpu->hwaccm.s.fCheckedTLBFlush
- && cWorldSwitchExit == pVCpu->hwaccm.s.cWorldSwitchExit)
- {
+/** @todo If more than one CPU is going to be poked, we could optimize this
+ * operation by poking them first and wait afterwards. Would require
+ * recording who to poke and their current cWorldSwitchExits values,
+ * that's something not suitable for stack... So, pVCpu->hm.s.something
+ * then. */
+ /* Spin until the VCPU has switched back (poking is async). */
+ while ( ASMAtomicUoReadBool(&pVCpu->hwaccm.s.fCheckedTLBFlush)
+ && cWorldSwitchExits == ASMAtomicUoReadU32(&pVCpu->hwaccm.s.cWorldSwitchExits))
ASMNopPause();
- }
+
if (rc == VINF_SUCCESS)
STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatSpinPoke, z);
else
STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatSpinPokeFailed, z);
}
}
-#endif
+#endif /* IN_RING0 */
#ifndef IN_RC
+
+/**
+ * Poke an EMT so it can perform the appropriate TLB shootdowns.
+ *
+ * @param pVCpu The handle of the virtual CPU to poke.
+ * @param fAccountFlushStat Whether to account the call to
+ * StatTlbShootdownFlush or StatTlbShootdown.
+ */
+static void hmPokeCpuForTlbFlush(PVMCPU pVCpu, bool fAccountFlushStat)
+{
+ if (ASMAtomicUoReadBool(&pVCpu->hwaccm.s.fCheckedTLBFlush))
+ {
+ if (fAccountFlushStat)
+ STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdownFlush);
+ else
+ STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdown);
+#ifdef IN_RING0
+ RTCPUID idHostCpu = pVCpu->hwaccm.s.idEnteredCpu;
+ if (idHostCpu != NIL_RTCPUID)
+ hmR0PokeCpu(pVCpu, idHostCpu);
+#else
+ VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_POKE);
+#endif
+ }
+ else
+ STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushPageManual);
+}
+
+
/**
* Invalidates a guest page on all VCPUs.
*
@@ -158,37 +191,23 @@ void hwaccmMpPokeCpu(PVMCPU pVCpu, RTCPUID idHostCpu)
VMMDECL(int) HWACCMInvalidatePageOnAllVCpus(PVM pVM, RTGCPTR GCPtr)
{
VMCPUID idCurCpu = VMMGetCpuId(pVM);
-
STAM_COUNTER_INC(&pVM->aCpus[idCurCpu].hwaccm.s.StatFlushPage);
for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
{
PVMCPU pVCpu = &pVM->aCpus[idCpu];
- /* Nothing to do if a TLB flush is already pending; the VCPU should have already been poked if it were active */
+ /* Nothing to do if a TLB flush is already pending; the VCPU should
+ have already been poked if it were active. */
if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH))
continue;
if (pVCpu->idCpu == idCurCpu)
- {
HWACCMInvalidatePage(pVCpu, GCPtr);
- }
else
{
hwaccmQueueInvlPage(pVCpu, GCPtr);
- if (pVCpu->hwaccm.s.fCheckedTLBFlush)
- {
- STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdown);
-#ifdef IN_RING0
- RTCPUID idHostCpu = pVCpu->hwaccm.s.idEnteredCpu;
- if (idHostCpu != NIL_RTCPUID)
- hwaccmMpPokeCpu(pVCpu, idHostCpu);
-#else
- VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_POKE);
-#endif
- }
- else
- STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushPageManual);
+ hmPokeCpuForTlbFlush(pVCpu, false /*fAccountFlushStat*/);
}
}
@@ -215,31 +234,20 @@ VMMDECL(int) HWACCMFlushTLBOnAllVCpus(PVM pVM)
{
PVMCPU pVCpu = &pVM->aCpus[idCpu];
- /* Nothing to do if a TLB flush is already pending; the VCPU should have already been poked if it were active */
- if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH))
- continue;
-
- VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
- if (idThisCpu == idCpu)
- continue;
-
- if (pVCpu->hwaccm.s.fCheckedTLBFlush)
+ /* Nothing to do if a TLB flush is already pending; the VCPU should
+ have already been poked if it were active. */
+ if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH))
{
- STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdownFlush);
-#ifdef IN_RING0
- RTCPUID idHostCpu = pVCpu->hwaccm.s.idEnteredCpu;
- if (idHostCpu != NIL_RTCPUID)
- hwaccmMpPokeCpu(pVCpu, idHostCpu);
-#else
- VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_POKE);
-#endif
+ VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
+ if (idThisCpu != idCpu)
+ hmPokeCpuForTlbFlush(pVCpu, true /*fAccountFlushStat*/);
}
- else
- STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushTLBManual);
}
+
return VINF_SUCCESS;
}
-#endif
+
+#endif /* !IN_RC */
/**
* Checks if nested paging is enabled
@@ -292,35 +300,22 @@ VMMDECL(int) HWACCMInvalidatePhysPage(PVM pVM, RTGCPHYS GCPhys)
PVMCPU pVCpu = &pVM->aCpus[idCpu];
if (idThisCpu == idCpu)
- {
VMXR0InvalidatePhysPage(pVM, pVCpu, GCPhys);
- continue;
- }
-
- VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
- if (pVCpu->hwaccm.s.fCheckedTLBFlush)
+ else
{
- STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdownFlush);
-# ifdef IN_RING0
- RTCPUID idHostCpu = pVCpu->hwaccm.s.idEnteredCpu;
- if (idHostCpu != NIL_RTCPUID)
- hwaccmMpPokeCpu(pVCpu, idHostCpu);
-# else
- VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_POKE);
-# endif
+ VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
+ hmPokeCpuForTlbFlush(pVCpu, true /*fAccountFlushStat*/);
}
- else
- STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushTLBManual);
}
return VINF_SUCCESS;
}
+ /* AMD-V doesn't support invalidation with guest physical addresses; see
+ comment in SVMR0InvalidatePhysPage. */
Assert(pVM->hwaccm.s.svm.fSupported);
- /* AMD-V doesn't support invalidation with guest physical addresses; see comment in SVMR0InvalidatePhysPage. */
- HWACCMFlushTLBOnAllVCpus(pVM);
-#else
- HWACCMFlushTLBOnAllVCpus(pVM);
#endif
+
+ HWACCMFlushTLBOnAllVCpus(pVM);
return VINF_SUCCESS;
}
@@ -335,3 +330,4 @@ VMMDECL(bool) HWACCMHasPendingIrq(PVM pVM)
PVMCPU pVCpu = VMMGetCpu(pVM);
return !!pVCpu->hwaccm.s.Event.fPending;
}
+
diff --git a/src/VBox/VMM/VMMAll/IEMAll.cpp b/src/VBox/VMM/VMMAll/IEMAll.cpp
new file mode 100644
index 000000000..7ae8ea6b6
--- /dev/null
+++ b/src/VBox/VMM/VMMAll/IEMAll.cpp
@@ -0,0 +1,6254 @@
+/* $Id: IEMAll.cpp 38018 2011-07-18 13:43:36Z vboxsync $ */
+/** @file
+ * IEM - Interpreted Execution Manager - All Contexts.
+ */
+
+/*
+ * 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.
+ */
+
+
+/** @page pg_iem IEM - Interpreted Execution Manager
+ *
+ * The interpreted exeuction manager (IEM) is for executing short guest code
+ * sequences that are causing too many exits / virtualization traps. It will
+ * also be used to interpret single instructions, thus replacing the selective
+ * interpreters in EM and IOM.
+ *
+ * Design goals:
+ * - Relatively small footprint, although we favour speed and correctness
+ * over size.
+ * - Reasonably fast.
+ * - Correctly handle lock prefixed instructions.
+ * - Complete instruction set - eventually.
+ * - Refactorable into a recompiler, maybe.
+ * - Replace EMInterpret*.
+ *
+ * Using the existing disassembler has been considered, however this is thought
+ * to conflict with speed as the disassembler chews things a bit too much while
+ * leaving us with a somewhat complicated state to interpret afterwards.
+ *
+ *
+ * The current code is very much work in progress. You've been warned!
+ *
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_IEM
+#include <VBox/vmm/iem.h>
+#include <VBox/vmm/pgm.h>
+#include <VBox/vmm/iom.h>
+#include <VBox/vmm/em.h>
+#include <VBox/vmm/tm.h>
+#include <VBox/vmm/dbgf.h>
+#ifdef IEM_VERIFICATION_MODE
+# include <VBox/vmm/rem.h>
+# include <VBox/vmm/mm.h>
+#endif
+#include "IEMInternal.h"
+#include <VBox/vmm/vm.h>
+#include <VBox/log.h>
+#include <VBox/err.h>
+#include <VBox/param.h>
+#include <iprt/assert.h>
+#include <iprt/string.h>
+#include <iprt/x86.h>
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Generic pointer union.
+ * @todo move me to iprt/types.h
+ */
+typedef union RTPTRUNION
+{
+ /** Pointer into the void... */
+ void *pv;
+ /** Pointer to a 8-bit unsigned value. */
+ uint8_t *pu8;
+ /** Pointer to a 16-bit unsigned value. */
+ uint16_t *pu16;
+ /** Pointer to a 32-bit unsigned value. */
+ uint32_t *pu32;
+ /** Pointer to a 64-bit unsigned value. */
+ uint64_t *pu64;
+} RTPTRUNION;
+/** Pointer to a pointer union. */
+typedef RTPTRUNION *PRTPTRUNION;
+
+/**
+ * Generic const pointer union.
+ * @todo move me to iprt/types.h
+ */
+typedef union RTCPTRUNION
+{
+ /** Pointer into the void... */
+ void const *pv;
+ /** Pointer to a 8-bit unsigned value. */
+ uint8_t const *pu8;
+ /** Pointer to a 16-bit unsigned value. */
+ uint16_t const *pu16;
+ /** Pointer to a 32-bit unsigned value. */
+ uint32_t const *pu32;
+ /** Pointer to a 64-bit unsigned value. */
+ uint64_t const *pu64;
+} RTCPTRUNION;
+/** Pointer to a const pointer union. */
+typedef RTCPTRUNION *PRTCPTRUNION;
+
+/** @typedef PFNIEMOP
+ * Pointer to an opcode decoder function.
+ */
+
+/** @def FNIEMOP_DEF
+ * Define an opcode decoder function.
+ *
+ * We're using macors for this so that adding and removing parameters as well as
+ * tweaking compiler specific attributes becomes easier. See FNIEMOP_CALL
+ *
+ * @param a_Name The function name.
+ */
+
+
+#if defined(__GNUC__) && defined(RT_ARCH_X86)
+typedef VBOXSTRICTRC (__attribute__((__fastcall__)) * PFNIEMOP)(PIEMCPU pIemCpu);
+# define FNIEMOP_DEF(a_Name) \
+ static VBOXSTRICTRC __attribute__((__fastcall__, __nothrow__)) a_Name (PIEMCPU pIemCpu)
+# define FNIEMOP_DEF_1(a_Name, a_Type0, a_Name0) \
+ static VBOXSTRICTRC __attribute__((__fastcall__, __nothrow__)) a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0)
+# define FNIEMOP_DEF_2(a_Name, a_Type0, a_Name0, a_Type1, a_Name1) \
+ static VBOXSTRICTRC __attribute__((__fastcall__, __nothrow__)) a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0, a_Type1 a_Name1)
+
+#elif defined(_MSC_VER) && defined(RT_ARCH_X86)
+typedef VBOXSTRICTRC (__fastcall * PFNIEMOP)(PIEMCPU pIemCpu);
+# define FNIEMOP_DEF(a_Name) \
+ static /*__declspec(naked)*/ VBOXSTRICTRC __fastcall a_Name(PIEMCPU pIemCpu) RT_NO_THROW
+# define FNIEMOP_DEF_1(a_Name, a_Type0, a_Name0) \
+ static /*__declspec(naked)*/ VBOXSTRICTRC __fastcall a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0) RT_NO_THROW
+# define FNIEMOP_DEF_2(a_Name, a_Type0, a_Name0, a_Type1, a_Name1) \
+ static /*__declspec(naked)*/ VBOXSTRICTRC __fastcall a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0, a_Type1 a_Name1) RT_NO_THROW
+
+#elif defined(__GNUC__)
+typedef VBOXSTRICTRC (* PFNIEMOP)(PIEMCPU pIemCpu);
+# define FNIEMOP_DEF(a_Name) \
+ static VBOXSTRICTRC __attribute__((__nothrow__)) a_Name(PIEMCPU pIemCpu)
+# define FNIEMOP_DEF_1(a_Name, a_Type0, a_Name0) \
+ static VBOXSTRICTRC __attribute__((__nothrow__)) a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0)
+# define FNIEMOP_DEF_2(a_Name, a_Type0, a_Name0, a_Type1, a_Name1) \
+ static VBOXSTRICTRC __attribute__((__nothrow__)) a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0, a_Type1 a_Name1)
+
+#else
+typedef VBOXSTRICTRC (* PFNIEMOP)(PIEMCPU pIemCpu);
+# define FNIEMOP_DEF(a_Name) \
+ static VBOXSTRICTRC a_Name(PIEMCPU pIemCpu) RT_NO_THROW
+# define FNIEMOP_DEF_1(a_Name, a_Type0, a_Name0) \
+ static VBOXSTRICTRC a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0) RT_NO_THROW
+# define FNIEMOP_DEF_2(a_Name, a_Type0, a_Name0, a_Type1, a_Name1) \
+ static VBOXSTRICTRC a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0, a_Type1 a_Name1) RT_NO_THROW
+
+#endif
+
+
+/**
+ * Selector descriptor table entry as fetched by iemMemFetchSelDesc.
+ */
+typedef union IEMSELDESC
+{
+ /** The legacy view. */
+ X86DESC Legacy;
+ /** The long mode view. */
+ X86DESC64 Long;
+} IEMSELDESC;
+/** Pointer to a selector descriptor table entry. */
+typedef IEMSELDESC *PIEMSELDESC;
+
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+/** @name IEM status codes.
+ *
+ * Not quite sure how this will play out in the end, just aliasing safe status
+ * codes for now.
+ *
+ * @{ */
+#define VINF_IEM_RAISED_XCPT VINF_EM_RESCHEDULE
+/** @} */
+
+/** Temporary hack to disable the double execution. Will be removed in favor
+ * of a dedicated execution mode in EM. */
+//#define IEM_VERIFICATION_MODE_NO_REM
+
+/** Used to shut up GCC warnings about variables that 'may be used uninitialized'
+ * due to GCC lacking knowledge about the value range of a switch. */
+#define IEM_NOT_REACHED_DEFAULT_CASE_RET() default: AssertFailedReturn(VERR_INTERNAL_ERROR_4)
+
+/**
+ * Call an opcode decoder function.
+ *
+ * We're using macors for this so that adding and removing parameters can be
+ * done as we please. See FNIEMOP_DEF.
+ */
+#define FNIEMOP_CALL(a_pfn) (a_pfn)(pIemCpu)
+
+/**
+ * Call a common opcode decoder function taking one extra argument.
+ *
+ * We're using macors for this so that adding and removing parameters can be
+ * done as we please. See FNIEMOP_DEF_1.
+ */
+#define FNIEMOP_CALL_1(a_pfn, a0) (a_pfn)(pIemCpu, a0)
+
+/**
+ * Call a common opcode decoder function taking one extra argument.
+ *
+ * We're using macors for this so that adding and removing parameters can be
+ * done as we please. See FNIEMOP_DEF_1.
+ */
+#define FNIEMOP_CALL_2(a_pfn, a0, a1) (a_pfn)(pIemCpu, a0, a1)
+
+/**
+ * Check if we're currently executing in real or virtual 8086 mode.
+ *
+ * @returns @c true if it is, @c false if not.
+ * @param a_pIemCpu The IEM state of the current CPU.
+ */
+#define IEM_IS_REAL_OR_V86_MODE(a_pIemCpu) (CPUMIsGuestInRealOrV86ModeEx((a_pIemCpu)->CTX_SUFF(pCtx)))
+
+/**
+ * Check if we're currently executing in long mode.
+ *
+ * @returns @c true if it is, @c false if not.
+ * @param a_pIemCpu The IEM state of the current CPU.
+ */
+#define IEM_IS_LONG_MODE(a_pIemCpu) (CPUMIsGuestInLongModeEx((a_pIemCpu)->CTX_SUFF(pCtx)))
+
+/**
+ * Check if we're currently executing in real mode.
+ *
+ * @returns @c true if it is, @c false if not.
+ * @param a_pIemCpu The IEM state of the current CPU.
+ */
+#define IEM_IS_REAL_MODE(a_pIemCpu) (CPUMIsGuestInRealModeEx((a_pIemCpu)->CTX_SUFF(pCtx)))
+
+/**
+ * Tests if an AMD CPUID feature (extended) is marked present - ECX.
+ */
+#define IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(a_fEcx) iemRegIsAmdCpuIdFeaturePresent(pIemCpu, 0, (a_fEcx))
+
+/**
+ * Checks if a intel CPUID feature is present.
+ */
+#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(a_fEdx) \
+ ( ((a_fEdx) & (X86_CPUID_FEATURE_EDX_TSC | 0)) \
+ || iemRegIsIntelCpuIdFeaturePresent(pIemCpu, (a_fEdx), 0) )
+
+/**
+ * Check if the address is canonical.
+ */
+#define IEM_IS_CANONICAL(a_u64Addr) ((uint64_t)(a_u64Addr) + UINT64_C(0x800000000000) < UINT64_C(0x1000000000000))
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+extern const PFNIEMOP g_apfnOneByteMap[256]; /* not static since we need to forward declare it. */
+
+
+/** Function table for the ADD instruction. */
+static const IEMOPBINSIZES g_iemAImpl_add =
+{
+ iemAImpl_add_u8, iemAImpl_add_u8_locked,
+ iemAImpl_add_u16, iemAImpl_add_u16_locked,
+ iemAImpl_add_u32, iemAImpl_add_u32_locked,
+ iemAImpl_add_u64, iemAImpl_add_u64_locked
+};
+
+/** Function table for the ADC instruction. */
+static const IEMOPBINSIZES g_iemAImpl_adc =
+{
+ iemAImpl_adc_u8, iemAImpl_adc_u8_locked,
+ iemAImpl_adc_u16, iemAImpl_adc_u16_locked,
+ iemAImpl_adc_u32, iemAImpl_adc_u32_locked,
+ iemAImpl_adc_u64, iemAImpl_adc_u64_locked
+};
+
+/** Function table for the SUB instruction. */
+static const IEMOPBINSIZES g_iemAImpl_sub =
+{
+ iemAImpl_sub_u8, iemAImpl_sub_u8_locked,
+ iemAImpl_sub_u16, iemAImpl_sub_u16_locked,
+ iemAImpl_sub_u32, iemAImpl_sub_u32_locked,
+ iemAImpl_sub_u64, iemAImpl_sub_u64_locked
+};
+
+/** Function table for the SBB instruction. */
+static const IEMOPBINSIZES g_iemAImpl_sbb =
+{
+ iemAImpl_sbb_u8, iemAImpl_sbb_u8_locked,
+ iemAImpl_sbb_u16, iemAImpl_sbb_u16_locked,
+ iemAImpl_sbb_u32, iemAImpl_sbb_u32_locked,
+ iemAImpl_sbb_u64, iemAImpl_sbb_u64_locked
+};
+
+/** Function table for the OR instruction. */
+static const IEMOPBINSIZES g_iemAImpl_or =
+{
+ iemAImpl_or_u8, iemAImpl_or_u8_locked,
+ iemAImpl_or_u16, iemAImpl_or_u16_locked,
+ iemAImpl_or_u32, iemAImpl_or_u32_locked,
+ iemAImpl_or_u64, iemAImpl_or_u64_locked
+};
+
+/** Function table for the XOR instruction. */
+static const IEMOPBINSIZES g_iemAImpl_xor =
+{
+ iemAImpl_xor_u8, iemAImpl_xor_u8_locked,
+ iemAImpl_xor_u16, iemAImpl_xor_u16_locked,
+ iemAImpl_xor_u32, iemAImpl_xor_u32_locked,
+ iemAImpl_xor_u64, iemAImpl_xor_u64_locked
+};
+
+/** Function table for the AND instruction. */
+static const IEMOPBINSIZES g_iemAImpl_and =
+{
+ iemAImpl_and_u8, iemAImpl_and_u8_locked,
+ iemAImpl_and_u16, iemAImpl_and_u16_locked,
+ iemAImpl_and_u32, iemAImpl_and_u32_locked,
+ iemAImpl_and_u64, iemAImpl_and_u64_locked
+};
+
+/** Function table for the CMP instruction.
+ * @remarks Making operand order ASSUMPTIONS.
+ */
+static const IEMOPBINSIZES g_iemAImpl_cmp =
+{
+ iemAImpl_cmp_u8, NULL,
+ iemAImpl_cmp_u16, NULL,
+ iemAImpl_cmp_u32, NULL,
+ iemAImpl_cmp_u64, NULL
+};
+
+/** Function table for the TEST instruction.
+ * @remarks Making operand order ASSUMPTIONS.
+ */
+static const IEMOPBINSIZES g_iemAImpl_test =
+{
+ iemAImpl_test_u8, NULL,
+ iemAImpl_test_u16, NULL,
+ iemAImpl_test_u32, NULL,
+ iemAImpl_test_u64, NULL
+};
+
+/** Function table for the BT instruction. */
+static const IEMOPBINSIZES g_iemAImpl_bt =
+{
+ NULL, NULL,
+ iemAImpl_bt_u16, NULL,
+ iemAImpl_bt_u32, NULL,
+ iemAImpl_bt_u64, NULL
+};
+
+/** Function table for the BTC instruction. */
+static const IEMOPBINSIZES g_iemAImpl_btc =
+{
+ NULL, NULL,
+ iemAImpl_btc_u16, iemAImpl_btc_u16_locked,
+ iemAImpl_btc_u32, iemAImpl_btc_u32_locked,
+ iemAImpl_btc_u64, iemAImpl_btc_u64_locked
+};
+
+/** Function table for the BTR instruction. */
+static const IEMOPBINSIZES g_iemAImpl_btr =
+{
+ NULL, NULL,
+ iemAImpl_btr_u16, iemAImpl_btr_u16_locked,
+ iemAImpl_btr_u32, iemAImpl_btr_u32_locked,
+ iemAImpl_btr_u64, iemAImpl_btr_u64_locked
+};
+
+/** Function table for the BTS instruction. */
+static const IEMOPBINSIZES g_iemAImpl_bts =
+{
+ NULL, NULL,
+ iemAImpl_bts_u16, iemAImpl_bts_u16_locked,
+ iemAImpl_bts_u32, iemAImpl_bts_u32_locked,
+ iemAImpl_bts_u64, iemAImpl_bts_u64_locked
+};
+
+/** Function table for the BSF instruction. */
+static const IEMOPBINSIZES g_iemAImpl_bsf =
+{
+ NULL, NULL,
+ iemAImpl_bsf_u16, NULL,
+ iemAImpl_bsf_u32, NULL,
+ iemAImpl_bsf_u64, NULL
+};
+
+/** Function table for the BSR instruction. */
+static const IEMOPBINSIZES g_iemAImpl_bsr =
+{
+ NULL, NULL,
+ iemAImpl_bsr_u16, NULL,
+ iemAImpl_bsr_u32, NULL,
+ iemAImpl_bsr_u64, NULL
+};
+
+/** Function table for the IMUL instruction. */
+static const IEMOPBINSIZES g_iemAImpl_imul_two =
+{
+ NULL, NULL,
+ iemAImpl_imul_two_u16, NULL,
+ iemAImpl_imul_two_u32, NULL,
+ iemAImpl_imul_two_u64, NULL
+};
+
+/** Group 1 /r lookup table. */
+static const PCIEMOPBINSIZES g_apIemImplGrp1[8] =
+{
+ &g_iemAImpl_add,
+ &g_iemAImpl_or,
+ &g_iemAImpl_adc,
+ &g_iemAImpl_sbb,
+ &g_iemAImpl_and,
+ &g_iemAImpl_sub,
+ &g_iemAImpl_xor,
+ &g_iemAImpl_cmp
+};
+
+/** Function table for the INC instruction. */
+static const IEMOPUNARYSIZES g_iemAImpl_inc =
+{
+ iemAImpl_inc_u8, iemAImpl_inc_u8_locked,
+ iemAImpl_inc_u16, iemAImpl_inc_u16_locked,
+ iemAImpl_inc_u32, iemAImpl_inc_u32_locked,
+ iemAImpl_inc_u64, iemAImpl_inc_u64_locked
+};
+
+/** Function table for the DEC instruction. */
+static const IEMOPUNARYSIZES g_iemAImpl_dec =
+{
+ iemAImpl_dec_u8, iemAImpl_dec_u8_locked,
+ iemAImpl_dec_u16, iemAImpl_dec_u16_locked,
+ iemAImpl_dec_u32, iemAImpl_dec_u32_locked,
+ iemAImpl_dec_u64, iemAImpl_dec_u64_locked
+};
+
+/** Function table for the NEG instruction. */
+static const IEMOPUNARYSIZES g_iemAImpl_neg =
+{
+ iemAImpl_neg_u8, iemAImpl_neg_u8_locked,
+ iemAImpl_neg_u16, iemAImpl_neg_u16_locked,
+ iemAImpl_neg_u32, iemAImpl_neg_u32_locked,
+ iemAImpl_neg_u64, iemAImpl_neg_u64_locked
+};
+
+/** Function table for the NOT instruction. */
+static const IEMOPUNARYSIZES g_iemAImpl_not =
+{
+ iemAImpl_not_u8, iemAImpl_not_u8_locked,
+ iemAImpl_not_u16, iemAImpl_not_u16_locked,
+ iemAImpl_not_u32, iemAImpl_not_u32_locked,
+ iemAImpl_not_u64, iemAImpl_not_u64_locked
+};
+
+
+/** Function table for the ROL instruction. */
+static const IEMOPSHIFTSIZES g_iemAImpl_rol =
+{
+ iemAImpl_rol_u8,
+ iemAImpl_rol_u16,
+ iemAImpl_rol_u32,
+ iemAImpl_rol_u64
+};
+
+/** Function table for the ROR instruction. */
+static const IEMOPSHIFTSIZES g_iemAImpl_ror =
+{
+ iemAImpl_ror_u8,
+ iemAImpl_ror_u16,
+ iemAImpl_ror_u32,
+ iemAImpl_ror_u64
+};
+
+/** Function table for the RCL instruction. */
+static const IEMOPSHIFTSIZES g_iemAImpl_rcl =
+{
+ iemAImpl_rcl_u8,
+ iemAImpl_rcl_u16,
+ iemAImpl_rcl_u32,
+ iemAImpl_rcl_u64
+};
+
+/** Function table for the RCR instruction. */
+static const IEMOPSHIFTSIZES g_iemAImpl_rcr =
+{
+ iemAImpl_rcr_u8,
+ iemAImpl_rcr_u16,
+ iemAImpl_rcr_u32,
+ iemAImpl_rcr_u64
+};
+
+/** Function table for the SHL instruction. */
+static const IEMOPSHIFTSIZES g_iemAImpl_shl =
+{
+ iemAImpl_shl_u8,
+ iemAImpl_shl_u16,
+ iemAImpl_shl_u32,
+ iemAImpl_shl_u64
+};
+
+/** Function table for the SHR instruction. */
+static const IEMOPSHIFTSIZES g_iemAImpl_shr =
+{
+ iemAImpl_shr_u8,
+ iemAImpl_shr_u16,
+ iemAImpl_shr_u32,
+ iemAImpl_shr_u64
+};
+
+/** Function table for the SAR instruction. */
+static const IEMOPSHIFTSIZES g_iemAImpl_sar =
+{
+ iemAImpl_sar_u8,
+ iemAImpl_sar_u16,
+ iemAImpl_sar_u32,
+ iemAImpl_sar_u64
+};
+
+
+/** Function table for the MUL instruction. */
+static const IEMOPMULDIVSIZES g_iemAImpl_mul =
+{
+ iemAImpl_mul_u8,
+ iemAImpl_mul_u16,
+ iemAImpl_mul_u32,
+ iemAImpl_mul_u64
+};
+
+/** Function table for the IMUL instruction working implicitly on rAX. */
+static const IEMOPMULDIVSIZES g_iemAImpl_imul =
+{
+ iemAImpl_imul_u8,
+ iemAImpl_imul_u16,
+ iemAImpl_imul_u32,
+ iemAImpl_imul_u64
+};
+
+/** Function table for the DIV instruction. */
+static const IEMOPMULDIVSIZES g_iemAImpl_div =
+{
+ iemAImpl_div_u8,
+ iemAImpl_div_u16,
+ iemAImpl_div_u32,
+ iemAImpl_div_u64
+};
+
+/** Function table for the MUL instruction. */
+static const IEMOPMULDIVSIZES g_iemAImpl_idiv =
+{
+ iemAImpl_idiv_u8,
+ iemAImpl_idiv_u16,
+ iemAImpl_idiv_u32,
+ iemAImpl_idiv_u64
+};
+
+/** Function table for the SHLD instruction */
+static const IEMOPSHIFTDBLSIZES g_iemAImpl_shld =
+{
+ iemAImpl_shld_u16,
+ iemAImpl_shld_u32,
+ iemAImpl_shld_u64,
+};
+
+/** Function table for the SHRD instruction */
+static const IEMOPSHIFTDBLSIZES g_iemAImpl_shrd =
+{
+ iemAImpl_shrd_u16,
+ iemAImpl_shrd_u32,
+ iemAImpl_shrd_u64,
+};
+
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+static VBOXSTRICTRC iemRaiseTaskSwitchFaultCurrentTSS(PIEMCPU pIemCpu);
+static VBOXSTRICTRC iemRaiseSelectorNotPresent(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
+static VBOXSTRICTRC iemRaiseSelectorNotPresentBySelector(PIEMCPU pIemCpu, uint16_t uSel);
+static VBOXSTRICTRC iemRaiseSelectorNotPresentWithErr(PIEMCPU pIemCpu, uint16_t uErr);
+static VBOXSTRICTRC iemRaiseGeneralProtectionFault(PIEMCPU pIemCpu, uint16_t uErr);
+static VBOXSTRICTRC iemRaiseGeneralProtectionFault0(PIEMCPU pIemCpu);
+static VBOXSTRICTRC iemRaiseGeneralProtectionFaultBySelector(PIEMCPU pIemCpu, RTSEL uSel);
+static VBOXSTRICTRC iemRaiseSelectorBounds(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
+static VBOXSTRICTRC iemRaiseSelectorBoundsBySelector(PIEMCPU pIemCpu, RTSEL Sel);
+static VBOXSTRICTRC iemRaiseSelectorInvalidAccess(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
+static VBOXSTRICTRC iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc);
+static VBOXSTRICTRC iemMemMap(PIEMCPU pIemCpu, void **ppvMem, size_t cbMem, uint8_t iSegReg, RTGCPTR GCPtrMem, uint32_t fAccess);
+static VBOXSTRICTRC iemMemCommitAndUnmap(PIEMCPU pIemCpu, void *pvMem, uint32_t fAccess);
+static VBOXSTRICTRC iemMemFetchDataU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
+static VBOXSTRICTRC iemMemFetchDataU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
+static VBOXSTRICTRC iemMemFetchSelDesc(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel);
+static VBOXSTRICTRC iemMemStackPushCommitSpecial(PIEMCPU pIemCpu, void *pvMem, uint64_t uNewRsp);
+static VBOXSTRICTRC iemMemStackPushBeginSpecial(PIEMCPU pIemCpu, size_t cbMem, void **ppvMem, uint64_t *puNewRsp);
+static VBOXSTRICTRC iemMemMarkSelDescAccessed(PIEMCPU pIemCpu, uint16_t uSel);
+static uint16_t iemSRegFetchU16(PIEMCPU pIemCpu, uint8_t iSegReg);
+
+#ifdef IEM_VERIFICATION_MODE
+static PIEMVERIFYEVTREC iemVerifyAllocRecord(PIEMCPU pIemCpu);
+#endif
+static VBOXSTRICTRC iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue);
+static VBOXSTRICTRC iemVerifyFakeIOPortWrite(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
+
+
+/**
+ * Initializes the decoder state.
+ *
+ * @param pIemCpu The per CPU IEM state.
+ */
+DECLINLINE(void) iemInitDecode(PIEMCPU pIemCpu)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ pIemCpu->uCpl = CPUMGetGuestCPL(IEMCPU_TO_VMCPU(pIemCpu), CPUMCTX2CORE(pCtx));
+ IEMMODE enmMode = CPUMIsGuestIn64BitCodeEx(pCtx)
+ ? IEMMODE_64BIT
+ : pCtx->csHid.Attr.n.u1DefBig /** @todo check if this is correct... */
+ ? IEMMODE_32BIT
+ : IEMMODE_16BIT;
+ pIemCpu->enmCpuMode = enmMode;
+ pIemCpu->enmDefAddrMode = enmMode; /** @todo check if this is correct... */
+ pIemCpu->enmEffAddrMode = enmMode;
+ pIemCpu->enmDefOpSize = enmMode; /** @todo check if this is correct... */
+ pIemCpu->enmEffOpSize = enmMode;
+ pIemCpu->fPrefixes = 0;
+ pIemCpu->uRexReg = 0;
+ pIemCpu->uRexB = 0;
+ pIemCpu->uRexIndex = 0;
+ pIemCpu->iEffSeg = X86_SREG_DS;
+ pIemCpu->offOpcode = 0;
+ pIemCpu->cbOpcode = 0;
+ pIemCpu->cActiveMappings = 0;
+ pIemCpu->iNextMapping = 0;
+}
+
+
+/**
+ * Prefetch opcodes the first time when starting executing.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ */
+static VBOXSTRICTRC iemInitDecoderAndPrefetchOpcodes(PIEMCPU pIemCpu)
+{
+#ifdef IEM_VERIFICATION_MODE
+ uint8_t const cbOldOpcodes = pIemCpu->cbOpcode;
+#endif
+ iemInitDecode(pIemCpu);
+
+ /*
+ * What we're doing here is very similar to iemMemMap/iemMemBounceBufferMap.
+ *
+ * First translate CS:rIP to a physical address.
+ */
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint32_t cbToTryRead;
+ RTGCPTR GCPtrPC;
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ cbToTryRead = PAGE_SIZE;
+ GCPtrPC = pCtx->rip;
+ if (!IEM_IS_CANONICAL(GCPtrPC))
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ cbToTryRead = PAGE_SIZE - (GCPtrPC & PAGE_OFFSET_MASK);
+ }
+ else
+ {
+ uint32_t GCPtrPC32 = pCtx->eip;
+ Assert(!(GCPtrPC32 & ~(uint32_t)UINT16_MAX) || pIemCpu->enmCpuMode == IEMMODE_32BIT);
+ if (GCPtrPC32 > pCtx->csHid.u32Limit)
+ return iemRaiseSelectorBounds(pIemCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
+ cbToTryRead = pCtx->csHid.u32Limit - GCPtrPC32 + 1;
+ GCPtrPC = pCtx->csHid.u64Base + GCPtrPC32;
+ }
+
+ RTGCPHYS GCPhys;
+ uint64_t fFlags;
+ int rc = PGMGstGetPage(IEMCPU_TO_VMCPU(pIemCpu), GCPtrPC, &fFlags, &GCPhys);
+ if (RT_FAILURE(rc))
+ return iemRaisePageFault(pIemCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, rc);
+ if ((fFlags & X86_PTE_US) && pIemCpu->uCpl == 2)
+ return iemRaisePageFault(pIemCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
+ if ((fFlags & X86_PTE_PAE_NX) && (pCtx->msrEFER & MSR_K6_EFER_NXE))
+ return iemRaisePageFault(pIemCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
+ GCPhys |= GCPtrPC & PAGE_OFFSET_MASK;
+ /** @todo Check reserved bits and such stuff. PGM is better at doing
+ * that, so do it when implementing the guest virtual address
+ * TLB... */
+
+#ifdef IEM_VERIFICATION_MODE
+ /*
+ * Optimistic optimization: Use unconsumed opcode bytes from the previous
+ * instruction.
+ */
+ /** @todo optimize this differently by not using PGMPhysRead. */
+ RTGCPHYS const offPrevOpcodes = GCPhys - pIemCpu->GCPhysOpcodes;
+ pIemCpu->GCPhysOpcodes = GCPhys;
+ if ( offPrevOpcodes < cbOldOpcodes
+ && PAGE_SIZE - (GCPhys & PAGE_OFFSET_MASK) > sizeof(pIemCpu->abOpcode))
+ {
+ uint8_t cbNew = cbOldOpcodes - (uint8_t)offPrevOpcodes;
+ memmove(&pIemCpu->abOpcode[0], &pIemCpu->abOpcode[offPrevOpcodes], cbNew);
+ pIemCpu->cbOpcode = cbNew;
+ return VINF_SUCCESS;
+ }
+#endif
+
+ /*
+ * Read the bytes at this address.
+ */
+ uint32_t cbLeftOnPage = PAGE_SIZE - (GCPtrPC & PAGE_OFFSET_MASK);
+ if (cbToTryRead > cbLeftOnPage)
+ cbToTryRead = cbLeftOnPage;
+ if (cbToTryRead > sizeof(pIemCpu->abOpcode))
+ cbToTryRead = sizeof(pIemCpu->abOpcode);
+ /** @todo patch manager */
+ if (!pIemCpu->fByPassHandlers)
+ rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhys, pIemCpu->abOpcode, cbToTryRead);
+ else
+ rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), pIemCpu->abOpcode, GCPhys, cbToTryRead);
+ if (rc != VINF_SUCCESS)
+ return rc;
+ pIemCpu->cbOpcode = cbToTryRead;
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Try fetch at least @a cbMin bytes more opcodes, raise the appropriate
+ * exception if it fails.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param cbMin Where to return the opcode byte.
+ */
+static VBOXSTRICTRC iemOpcodeFetchMoreBytes(PIEMCPU pIemCpu, size_t cbMin)
+{
+ /*
+ * What we're doing here is very similar to iemMemMap/iemMemBounceBufferMap.
+ *
+ * First translate CS:rIP to a physical address.
+ */
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint8_t cbLeft = pIemCpu->cbOpcode - pIemCpu->offOpcode; Assert(cbLeft < cbMin);
+ uint32_t cbToTryRead;
+ RTGCPTR GCPtrNext;
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ cbToTryRead = PAGE_SIZE;
+ GCPtrNext = pCtx->rip + pIemCpu->cbOpcode;
+ if (!IEM_IS_CANONICAL(GCPtrNext))
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ cbToTryRead = PAGE_SIZE - (GCPtrNext & PAGE_OFFSET_MASK);
+ Assert(cbToTryRead >= cbMin - cbLeft); /* ASSUMPTION based on iemInitDecoderAndPrefetchOpcodes. */
+ }
+ else
+ {
+ uint32_t GCPtrNext32 = pCtx->eip;
+ Assert(!(GCPtrNext32 & ~(uint32_t)UINT16_MAX) || pIemCpu->enmCpuMode == IEMMODE_32BIT);
+ GCPtrNext32 += pIemCpu->cbOpcode;
+ if (GCPtrNext32 > pCtx->csHid.u32Limit)
+ return iemRaiseSelectorBounds(pIemCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
+ cbToTryRead = pCtx->csHid.u32Limit - GCPtrNext32 + 1;
+ if (cbToTryRead < cbMin - cbLeft)
+ return iemRaiseSelectorBounds(pIemCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
+ GCPtrNext = pCtx->csHid.u64Base + GCPtrNext32;
+ }
+
+ RTGCPHYS GCPhys;
+ uint64_t fFlags;
+ int rc = PGMGstGetPage(IEMCPU_TO_VMCPU(pIemCpu), GCPtrNext, &fFlags, &GCPhys);
+ if (RT_FAILURE(rc))
+ return iemRaisePageFault(pIemCpu, GCPtrNext, IEM_ACCESS_INSTRUCTION, rc);
+ if ((fFlags & X86_PTE_US) && pIemCpu->uCpl == 2)
+ return iemRaisePageFault(pIemCpu, GCPtrNext, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
+ if ((fFlags & X86_PTE_PAE_NX) && (pCtx->msrEFER & MSR_K6_EFER_NXE))
+ return iemRaisePageFault(pIemCpu, GCPtrNext, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
+ GCPhys |= GCPtrNext & PAGE_OFFSET_MASK;
+ //Log(("GCPtrNext=%RGv GCPhys=%RGp cbOpcodes=%#x\n", GCPtrNext, GCPhys, pIemCpu->cbOpcode));
+ /** @todo Check reserved bits and such stuff. PGM is better at doing
+ * that, so do it when implementing the guest virtual address
+ * TLB... */
+
+ /*
+ * Read the bytes at this address.
+ */
+ uint32_t cbLeftOnPage = PAGE_SIZE - (GCPtrNext & PAGE_OFFSET_MASK);
+ if (cbToTryRead > cbLeftOnPage)
+ cbToTryRead = cbLeftOnPage;
+ if (cbToTryRead > sizeof(pIemCpu->abOpcode) - pIemCpu->cbOpcode)
+ cbToTryRead = sizeof(pIemCpu->abOpcode) - pIemCpu->cbOpcode;
+ Assert(cbToTryRead >= cbMin - cbLeft);
+ if (!pIemCpu->fByPassHandlers)
+ rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhys, &pIemCpu->abOpcode[pIemCpu->cbOpcode], cbToTryRead);
+ else
+ rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), &pIemCpu->abOpcode[pIemCpu->cbOpcode], GCPhys, cbToTryRead);
+ if (rc != VINF_SUCCESS)
+ return rc;
+ pIemCpu->cbOpcode += cbToTryRead;
+ //Log(("%.*Rhxs\n", pIemCpu->cbOpcode, pIemCpu->abOpcode));
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Deals with the problematic cases that iemOpcodeGetNextByte doesn't like.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pb Where to return the opcode byte.
+ */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextByteSlow(PIEMCPU pIemCpu, uint8_t *pb)
+{
+ VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 1);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ uint8_t offOpcode = pIemCpu->offOpcode;
+ *pb = pIemCpu->abOpcode[offOpcode];
+ pIemCpu->offOpcode = offOpcode + 1;
+ }
+ else
+ *pb = 0;
+ return rcStrict;
+}
+
+
+/**
+ * Deals with the problematic cases that iemOpcodeGetNextS8SxU16 doesn't like.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pu16 Where to return the opcode dword.
+ */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextS8SxU16Slow(PIEMCPU pIemCpu, uint16_t *pu16)
+{
+ uint8_t u8;
+ VBOXSTRICTRC rcStrict = iemOpcodeGetNextByteSlow(pIemCpu, &u8);
+ if (rcStrict == VINF_SUCCESS)
+ *pu16 = (int8_t)u8;
+ return rcStrict;
+}
+
+
+/**
+ * Deals with the problematic cases that iemOpcodeGetNextU16 doesn't like.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pu16 Where to return the opcode word.
+ */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU16Slow(PIEMCPU pIemCpu, uint16_t *pu16)
+{
+ VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 2);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ uint8_t offOpcode = pIemCpu->offOpcode;
+ *pu16 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
+ pIemCpu->offOpcode = offOpcode + 2;
+ }
+ else
+ *pu16 = 0;
+ return rcStrict;
+}
+
+
+/**
+ * Deals with the problematic cases that iemOpcodeGetNextU32 doesn't like.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pu32 Where to return the opcode dword.
+ */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU32Slow(PIEMCPU pIemCpu, uint32_t *pu32)
+{
+ VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 4);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ uint8_t offOpcode = pIemCpu->offOpcode;
+ *pu32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
+ pIemCpu->abOpcode[offOpcode + 1],
+ pIemCpu->abOpcode[offOpcode + 2],
+ pIemCpu->abOpcode[offOpcode + 3]);
+ pIemCpu->offOpcode = offOpcode + 4;
+ }
+ else
+ *pu32 = 0;
+ return rcStrict;
+}
+
+
+/**
+ * Deals with the problematic cases that iemOpcodeGetNextS32SxU64 doesn't like.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pu64 Where to return the opcode qword.
+ */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextS32SxU64Slow(PIEMCPU pIemCpu, uint64_t *pu64)
+{
+ VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 4);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ uint8_t offOpcode = pIemCpu->offOpcode;
+ *pu64 = (int32_t)RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
+ pIemCpu->abOpcode[offOpcode + 1],
+ pIemCpu->abOpcode[offOpcode + 2],
+ pIemCpu->abOpcode[offOpcode + 3]);
+ pIemCpu->offOpcode = offOpcode + 4;
+ }
+ else
+ *pu64 = 0;
+ return rcStrict;
+}
+
+
+/**
+ * Deals with the problematic cases that iemOpcodeGetNextU64 doesn't like.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pu64 Where to return the opcode qword.
+ */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU64Slow(PIEMCPU pIemCpu, uint64_t *pu64)
+{
+ VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 8);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ uint8_t offOpcode = pIemCpu->offOpcode;
+ *pu64 = RT_MAKE_U64_FROM_U8(pIemCpu->abOpcode[offOpcode],
+ pIemCpu->abOpcode[offOpcode + 1],
+ pIemCpu->abOpcode[offOpcode + 2],
+ pIemCpu->abOpcode[offOpcode + 3],
+ pIemCpu->abOpcode[offOpcode + 4],
+ pIemCpu->abOpcode[offOpcode + 5],
+ pIemCpu->abOpcode[offOpcode + 6],
+ pIemCpu->abOpcode[offOpcode + 7]);
+ pIemCpu->offOpcode = offOpcode + 8;
+ }
+ else
+ *pu64 = 0;
+ return rcStrict;
+}
+
+
+/**
+ * Fetches the next opcode byte.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pu8 Where to return the opcode byte.
+ */
+DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU8(PIEMCPU pIemCpu, uint8_t *pu8)
+{
+ uint8_t const offOpcode = pIemCpu->offOpcode;
+ if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode))
+ return iemOpcodeGetNextByteSlow(pIemCpu, pu8);
+
+ *pu8 = pIemCpu->abOpcode[offOpcode];
+ pIemCpu->offOpcode = offOpcode + 1;
+ return VINF_SUCCESS;
+}
+
+/**
+ * Fetches the next opcode byte, returns automatically on failure.
+ *
+ * @param a_pu8 Where to return the opcode byte.
+ * @remark Implicitly references pIemCpu.
+ */
+#define IEM_OPCODE_GET_NEXT_U8(a_pu8) \
+ do \
+ { \
+ VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU8(pIemCpu, (a_pu8)); \
+ if (rcStrict2 != VINF_SUCCESS) \
+ return rcStrict2; \
+ } while (0)
+
+
+/**
+ * Fetches the next signed byte from the opcode stream.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pi8 Where to return the signed byte.
+ */
+DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8(PIEMCPU pIemCpu, int8_t *pi8)
+{
+ return iemOpcodeGetNextU8(pIemCpu, (uint8_t *)pi8);
+}
+
+/**
+ * Fetches the next signed byte from the opcode stream, returning automatically
+ * on failure.
+ *
+ * @param pi8 Where to return the signed byte.
+ * @remark Implicitly references pIemCpu.
+ */
+#define IEM_OPCODE_GET_NEXT_S8(a_pi8) \
+ do \
+ { \
+ VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8(pIemCpu, (a_pi8)); \
+ if (rcStrict2 != VINF_SUCCESS) \
+ return rcStrict2; \
+ } while (0)
+
+
+/**
+ * Fetches the next signed byte from the opcode stream, extending it to
+ * unsigned 16-bit.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pu16 Where to return the unsigned word.
+ */
+DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU16(PIEMCPU pIemCpu, uint16_t *pu16)
+{
+ uint8_t const offOpcode = pIemCpu->offOpcode;
+ if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode))
+ return iemOpcodeGetNextS8SxU16Slow(pIemCpu, pu16);
+
+ *pu16 = (int8_t)pIemCpu->abOpcode[offOpcode];
+ pIemCpu->offOpcode = offOpcode + 1;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Fetches the next signed byte from the opcode stream and sign-extending it to
+ * a word, returning automatically on failure.
+ *
+ * @param pu16 Where to return the word.
+ * @remark Implicitly references pIemCpu.
+ */
+#define IEM_OPCODE_GET_NEXT_S8_SX_U16(a_pu16) \
+ do \
+ { \
+ VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU16(pIemCpu, (a_pu16)); \
+ if (rcStrict2 != VINF_SUCCESS) \
+ return rcStrict2; \
+ } while (0)
+
+
+/**
+ * Fetches the next opcode word.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pu16 Where to return the opcode word.
+ */
+DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16(PIEMCPU pIemCpu, uint16_t *pu16)
+{
+ uint8_t const offOpcode = pIemCpu->offOpcode;
+ if (RT_UNLIKELY(offOpcode + 2 > pIemCpu->cbOpcode))
+ return iemOpcodeGetNextU16Slow(pIemCpu, pu16);
+
+ *pu16 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
+ pIemCpu->offOpcode = offOpcode + 2;
+ return VINF_SUCCESS;
+}
+
+/**
+ * Fetches the next opcode word, returns automatically on failure.
+ *
+ * @param a_pu16 Where to return the opcode word.
+ * @remark Implicitly references pIemCpu.
+ */
+#define IEM_OPCODE_GET_NEXT_U16(a_pu16) \
+ do \
+ { \
+ VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16(pIemCpu, (a_pu16)); \
+ if (rcStrict2 != VINF_SUCCESS) \
+ return rcStrict2; \
+ } while (0)
+
+
+/**
+ * Fetches the next signed word from the opcode stream.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pi16 Where to return the signed word.
+ */
+DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS16(PIEMCPU pIemCpu, int16_t *pi16)
+{
+ return iemOpcodeGetNextU16(pIemCpu, (uint16_t *)pi16);
+}
+
+/**
+ * Fetches the next signed word from the opcode stream, returning automatically
+ * on failure.
+ *
+ * @param pi16 Where to return the signed word.
+ * @remark Implicitly references pIemCpu.
+ */
+#define IEM_OPCODE_GET_NEXT_S16(a_pi16) \
+ do \
+ { \
+ VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS16(pIemCpu, (a_pi16)); \
+ if (rcStrict2 != VINF_SUCCESS) \
+ return rcStrict2; \
+ } while (0)
+
+
+/**
+ * Fetches the next opcode dword.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pu32 Where to return the opcode double word.
+ */
+DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32(PIEMCPU pIemCpu, uint32_t *pu32)
+{
+ uint8_t const offOpcode = pIemCpu->offOpcode;
+ if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode))
+ return iemOpcodeGetNextU32Slow(pIemCpu, pu32);
+
+ *pu32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
+ pIemCpu->abOpcode[offOpcode + 1],
+ pIemCpu->abOpcode[offOpcode + 2],
+ pIemCpu->abOpcode[offOpcode + 3]);
+ pIemCpu->offOpcode = offOpcode + 4;
+ return VINF_SUCCESS;
+}
+
+/**
+ * Fetches the next opcode dword, returns automatically on failure.
+ *
+ * @param a_u32 Where to return the opcode dword.
+ * @remark Implicitly references pIemCpu.
+ */
+#define IEM_OPCODE_GET_NEXT_U32(a_pu32) \
+ do \
+ { \
+ VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32(pIemCpu, (a_pu32)); \
+ if (rcStrict2 != VINF_SUCCESS) \
+ return rcStrict2; \
+ } while (0)
+
+
+/**
+ * Fetches the next signed double word from the opcode stream.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pi32 Where to return the signed double word.
+ */
+DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32(PIEMCPU pIemCpu, int32_t *pi32)
+{
+ return iemOpcodeGetNextU32(pIemCpu, (uint32_t *)pi32);
+}
+
+/**
+ * Fetches the next signed double word from the opcode stream, returning
+ * automatically on failure.
+ *
+ * @param pi32 Where to return the signed double word.
+ * @remark Implicitly references pIemCpu.
+ */
+#define IEM_OPCODE_GET_NEXT_S32(a_pi32) \
+ do \
+ { \
+ VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32(pIemCpu, (a_pi32)); \
+ if (rcStrict2 != VINF_SUCCESS) \
+ return rcStrict2; \
+ } while (0)
+
+
+/**
+ * Fetches the next opcode dword, sign extending it into a quad word.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pu64 Where to return the opcode quad word.
+ */
+DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32SxU64(PIEMCPU pIemCpu, uint64_t *pu64)
+{
+ uint8_t const offOpcode = pIemCpu->offOpcode;
+ if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode))
+ return iemOpcodeGetNextS32SxU64Slow(pIemCpu, pu64);
+
+ int32_t i32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
+ pIemCpu->abOpcode[offOpcode + 1],
+ pIemCpu->abOpcode[offOpcode + 2],
+ pIemCpu->abOpcode[offOpcode + 3]);
+ *pu64 = i32;
+ pIemCpu->offOpcode = offOpcode + 4;
+ return VINF_SUCCESS;
+}
+
+/**
+ * Fetches the next opcode double word and sign extends it to a quad word,
+ * returns automatically on failure.
+ *
+ * @param a_pu64 Where to return the opcode quad word.
+ * @remark Implicitly references pIemCpu.
+ */
+#define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) \
+ do \
+ { \
+ VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32SxU64(pIemCpu, (a_pu64)); \
+ if (rcStrict2 != VINF_SUCCESS) \
+ return rcStrict2; \
+ } while (0)
+
+
+/**
+ * Fetches the next opcode qword.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM state.
+ * @param pu64 Where to return the opcode qword.
+ */
+DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU64(PIEMCPU pIemCpu, uint64_t *pu64)
+{
+ uint8_t const offOpcode = pIemCpu->offOpcode;
+ if (RT_UNLIKELY(offOpcode + 8 > pIemCpu->cbOpcode))
+ return iemOpcodeGetNextU64Slow(pIemCpu, pu64);
+
+ *pu64 = RT_MAKE_U64_FROM_U8(pIemCpu->abOpcode[offOpcode],
+ pIemCpu->abOpcode[offOpcode + 1],
+ pIemCpu->abOpcode[offOpcode + 2],
+ pIemCpu->abOpcode[offOpcode + 3],
+ pIemCpu->abOpcode[offOpcode + 4],
+ pIemCpu->abOpcode[offOpcode + 5],
+ pIemCpu->abOpcode[offOpcode + 6],
+ pIemCpu->abOpcode[offOpcode + 7]);
+ pIemCpu->offOpcode = offOpcode + 8;
+ return VINF_SUCCESS;
+}
+
+/**
+ * Fetches the next opcode quad word, returns automatically on failure.
+ *
+ * @param a_pu64 Where to return the opcode quad word.
+ * @remark Implicitly references pIemCpu.
+ */
+#define IEM_OPCODE_GET_NEXT_U64(a_pu64) \
+ do \
+ { \
+ VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU64(pIemCpu, (a_pu64)); \
+ if (rcStrict2 != VINF_SUCCESS) \
+ return rcStrict2; \
+ } while (0)
+
+
+/** @name Misc Worker Functions.
+ * @{
+ */
+
+
+/**
+ * Validates a new SS segment.
+ *
+ * @returns VBox strict status code.
+ * @param pIemCpu The IEM per CPU instance data.
+ * @param pCtx The CPU context.
+ * @param NewSS The new SS selctor.
+ * @param uCpl The CPL to load the stack for.
+ * @param pDesc Where to return the descriptor.
+ */
+static VBOXSTRICTRC iemMiscValidateNewSS(PIEMCPU pIemCpu, PCCPUMCTX pCtx, RTSEL NewSS, uint8_t uCpl, PIEMSELDESC pDesc)
+{
+ /* Null selectors are not allowed (we're not called for dispatching
+ interrupts with SS=0 in long mode). */
+ if (!(NewSS & (X86_SEL_MASK | X86_SEL_LDT)))
+ {
+ Log(("iemMiscValidateNewSSandRsp: #x - null selector -> #GP(0)\n", NewSS));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ /*
+ * Read the descriptor.
+ */
+ VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, pDesc, NewSS);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /*
+ * Perform the descriptor validation documented for LSS, POP SS and MOV SS.
+ */
+ if (!pDesc->Legacy.Gen.u1DescType)
+ {
+ Log(("iemMiscValidateNewSSandRsp: %#x - system selector -> #GP\n", NewSS, pDesc->Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
+ }
+
+ if ( (pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_CODE)
+ || !(pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_WRITE) )
+ {
+ Log(("iemMiscValidateNewSSandRsp: %#x - code or read only (%#x) -> #GP\n", NewSS, pDesc->Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
+ }
+ if ( (pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_CODE)
+ || !(pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_WRITE) )
+ {
+ Log(("iemMiscValidateNewSSandRsp: %#x - code or read only (%#x) -> #GP\n", NewSS, pDesc->Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
+ }
+ /** @todo testcase: check if the TSS.ssX RPL is checked. */
+ if ((NewSS & X86_SEL_RPL) != uCpl)
+ {
+ Log(("iemMiscValidateNewSSandRsp: %#x - RPL and CPL (%d) differs -> #GP\n", NewSS, uCpl));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
+ }
+ if (pDesc->Legacy.Gen.u2Dpl != uCpl)
+ {
+ Log(("iemMiscValidateNewSSandRsp: %#x - DPL (%d) and CPL (%d) differs -> #GP\n", NewSS, pDesc->Legacy.Gen.u2Dpl, uCpl));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
+ }
+
+ /* Is it there? */
+ /** @todo testcase: Is this checked before the canonical / limit check below? */
+ if (!pDesc->Legacy.Gen.u1Present)
+ {
+ Log(("iemMiscValidateNewSSandRsp: %#x - segment not present -> #NP\n", NewSS));
+ return iemRaiseSelectorNotPresentBySelector(pIemCpu, NewSS);
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/** @} */
+
+/** @name Raising Exceptions.
+ *
+ * @{
+ */
+
+/** @name IEM_XCPT_FLAGS_XXX - flags for iemRaiseXcptOrInt.
+ * @{ */
+/** CPU exception. */
+#define IEM_XCPT_FLAGS_T_CPU_XCPT RT_BIT_32(0)
+/** External interrupt (from PIC, APIC, whatever). */
+#define IEM_XCPT_FLAGS_T_EXT_INT RT_BIT_32(1)
+/** Software interrupt (int, into or bound). */
+#define IEM_XCPT_FLAGS_T_SOFT_INT RT_BIT_32(2)
+/** Takes an error code. */
+#define IEM_XCPT_FLAGS_ERR RT_BIT_32(3)
+/** Takes a CR2. */
+#define IEM_XCPT_FLAGS_CR2 RT_BIT_32(4)
+/** Generated by the breakpoint instruction. */
+#define IEM_XCPT_FLAGS_BP_INSTR RT_BIT_32(5)
+/** @} */
+
+/**
+ * Loads the specified stack far pointer from the TSS.
+ *
+ * @returns VBox strict status code.
+ * @param pIemCpu The IEM per CPU instance data.
+ * @param pCtx The CPU context.
+ * @param uCpl The CPL to load the stack for.
+ * @param pSelSS Where to return the new stack segment.
+ * @param puEsp Where to return the new stack pointer.
+ */
+static VBOXSTRICTRC iemRaiseLoadStackFromTss32Or16(PIEMCPU pIemCpu, PCCPUMCTX pCtx, uint8_t uCpl,
+ PRTSEL pSelSS, uint32_t *puEsp)
+{
+ VBOXSTRICTRC rcStrict;
+ Assert(uCpl < 4);
+ *puEsp = 0; /* make gcc happy */
+ *pSelSS = 0; /* make gcc happy */
+
+ switch (pCtx->trHid.Attr.n.u4Type)
+ {
+ /*
+ * 16-bit TSS (X86TSS16).
+ */
+ case X86_SEL_TYPE_SYS_286_TSS_AVAIL: AssertFailed();
+ case X86_SEL_TYPE_SYS_286_TSS_BUSY:
+ {
+ uint32_t off = uCpl * 4 + 2;
+ if (off + 4 > pCtx->trHid.u32Limit)
+ {
+ Log(("LoadStackFromTss32Or16: out of bounds! uCpl=%d, u32Limit=%#x TSS16\n", uCpl, pCtx->trHid.u32Limit));
+ return iemRaiseTaskSwitchFaultCurrentTSS(pIemCpu);
+ }
+
+ uint32_t u32Tmp;
+ rcStrict = iemMemFetchDataU32(pIemCpu, &u32Tmp, UINT8_MAX, pCtx->trHid.u64Base + off);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ *puEsp = RT_LOWORD(u32Tmp);
+ *pSelSS = RT_HIWORD(u32Tmp);
+ return VINF_SUCCESS;
+ }
+ break;
+ }
+
+ /*
+ * 32-bit TSS (X86TSS32).
+ */
+ case X86_SEL_TYPE_SYS_386_TSS_AVAIL: AssertFailed();
+ case X86_SEL_TYPE_SYS_386_TSS_BUSY:
+ {
+ uint32_t off = uCpl * 8 + 4;
+ if (off + 7 > pCtx->trHid.u32Limit)
+ {
+ Log(("LoadStackFromTss32Or16: out of bounds! uCpl=%d, u32Limit=%#x TSS16\n", uCpl, pCtx->trHid.u32Limit));
+ return iemRaiseTaskSwitchFaultCurrentTSS(pIemCpu);
+ }
+
+ uint64_t u64Tmp;
+ rcStrict = iemMemFetchDataU64(pIemCpu, &u64Tmp, UINT8_MAX, pCtx->trHid.u64Base + off);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ *puEsp = u64Tmp & UINT32_MAX;
+ *pSelSS = (RTSEL)(u64Tmp >> 32);
+ return VINF_SUCCESS;
+ }
+ break;
+ }
+
+ default:
+ AssertFailedReturn(VERR_INTERNAL_ERROR_2);
+ }
+ return rcStrict;
+}
+
+
+/**
+ * Adjust the CPU state according to the exception being raised.
+ *
+ * @param pCtx The CPU context.
+ * @param u8Vector The exception that has been raised.
+ */
+DECLINLINE(void) iemRaiseXcptAdjustState(PCPUMCTX pCtx, uint8_t u8Vector)
+{
+ switch (u8Vector)
+ {
+ case X86_XCPT_DB:
+ pCtx->dr[7] &= ~X86_DR7_GD;
+ break;
+ /** @todo Read the AMD and Intel exception reference... */
+ }
+}
+
+
+/**
+ * Implements exceptions and interrupts for real mode.
+ *
+ * @returns VBox strict status code.
+ * @param pIemCpu The IEM per CPU instance data.
+ * @param pCtx The CPU context.
+ * @param cbInstr The number of bytes to offset rIP by in the return
+ * address.
+ * @param u8Vector The interrupt / exception vector number.
+ * @param fFlags The flags.
+ * @param uErr The error value if IEM_XCPT_FLAGS_ERR is set.
+ * @param uCr2 The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
+ */
+static VBOXSTRICTRC
+iemRaiseXcptOrIntInRealMode(PIEMCPU pIemCpu,
+ PCPUMCTX pCtx,
+ uint8_t cbInstr,
+ uint8_t u8Vector,
+ uint32_t fFlags,
+ uint16_t uErr,
+ uint64_t uCr2)
+{
+ AssertReturn(pIemCpu->enmCpuMode == IEMMODE_16BIT, VERR_INTERNAL_ERROR_3);
+
+ /*
+ * Read the IDT entry.
+ */
+ if (pCtx->idtr.cbIdt < UINT32_C(4) * u8Vector + 3)
+ {
+ Log(("RaiseXcptOrIntInRealMode: %#x is out of bounds (%#x)\n", u8Vector, pCtx->idtr.cbIdt));
+ return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
+ }
+ RTFAR16 Idte;
+ VBOXSTRICTRC rcStrict = iemMemFetchDataU32(pIemCpu, (uint32_t *)&Idte, UINT8_MAX,
+ pCtx->idtr.pIdt + UINT32_C(4) * u8Vector);
+ if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
+ return rcStrict;
+
+ /*
+ * Push the stack frame.
+ */
+ uint16_t *pu16Frame;
+ uint64_t uNewRsp;
+ rcStrict = iemMemStackPushBeginSpecial(pIemCpu, 6, (void **)&pu16Frame, &uNewRsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ pu16Frame[2] = (uint16_t)pCtx->eflags.u;
+ pu16Frame[1] = (uint16_t)pCtx->cs;
+ pu16Frame[0] = pCtx->ip + cbInstr;
+ rcStrict = iemMemStackPushCommitSpecial(pIemCpu, pu16Frame, uNewRsp);
+ if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
+ return rcStrict;
+
+ /*
+ * Load the vector address into cs:ip and make exception specific state
+ * adjustments.
+ */
+ pCtx->cs = Idte.sel;
+ pCtx->csHid.u64Base = (uint32_t)Idte.sel << 4;
+ /** @todo do we load attribs and limit as well? Should we check against limit like far jump? */
+ pCtx->rip = Idte.off;
+ pCtx->eflags.Bits.u1IF = 0;
+
+ /** @todo do we actually do this in real mode? */
+ if (fFlags & IEM_XCPT_FLAGS_T_CPU_XCPT)
+ iemRaiseXcptAdjustState(pCtx, u8Vector);
+
+ return fFlags & IEM_XCPT_FLAGS_T_CPU_XCPT ? VINF_IEM_RAISED_XCPT : VINF_SUCCESS;
+}
+
+
+/**
+ * Implements exceptions and interrupts for protected mode.
+ *
+ * @returns VBox strict status code.
+ * @param pIemCpu The IEM per CPU instance data.
+ * @param pCtx The CPU context.
+ * @param cbInstr The number of bytes to offset rIP by in the return
+ * address.
+ * @param u8Vector The interrupt / exception vector number.
+ * @param fFlags The flags.
+ * @param uErr The error value if IEM_XCPT_FLAGS_ERR is set.
+ * @param uCr2 The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
+ */
+static VBOXSTRICTRC
+iemRaiseXcptOrIntInProtMode(PIEMCPU pIemCpu,
+ PCPUMCTX pCtx,
+ uint8_t cbInstr,
+ uint8_t u8Vector,
+ uint32_t fFlags,
+ uint16_t uErr,
+ uint64_t uCr2)
+{
+ /*
+ * Read the IDT entry.
+ */
+ if (pCtx->idtr.cbIdt < UINT32_C(8) * u8Vector + 7)
+ {
+ Log(("RaiseXcptOrIntInProtMode: %#x is out of bounds (%#x)\n", u8Vector, pCtx->idtr.cbIdt));
+ return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
+ }
+ X86DESC Idte;
+ VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pIemCpu, &Idte.u, UINT8_MAX,
+ pCtx->idtr.pIdt + UINT32_C(8) * u8Vector);
+ if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
+ return rcStrict;
+
+ /*
+ * Check the descriptor type, DPL and such.
+ * ASSUMES this is done in the same order as described for call-gate calls.
+ */
+ if (Idte.Gate.u1DescType)
+ {
+ Log(("RaiseXcptOrIntInProtMode %#x - not system selector (%#x) -> #GP\n", u8Vector, Idte.Gate.u4Type));
+ return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
+ }
+ uint32_t fEflToClear = X86_EFL_TF | X86_EFL_NT | X86_EFL_RF | X86_EFL_VM;
+ switch (Idte.Gate.u4Type)
+ {
+ case X86_SEL_TYPE_SYS_UNDEFINED:
+ case X86_SEL_TYPE_SYS_286_TSS_AVAIL:
+ case X86_SEL_TYPE_SYS_LDT:
+ case X86_SEL_TYPE_SYS_286_TSS_BUSY:
+ case X86_SEL_TYPE_SYS_286_CALL_GATE:
+ case X86_SEL_TYPE_SYS_UNDEFINED2:
+ case X86_SEL_TYPE_SYS_386_TSS_AVAIL:
+ case X86_SEL_TYPE_SYS_UNDEFINED3:
+ case X86_SEL_TYPE_SYS_386_TSS_BUSY:
+ case X86_SEL_TYPE_SYS_386_CALL_GATE:
+ case X86_SEL_TYPE_SYS_UNDEFINED4:
+ {
+ /** @todo check what actually happens when the type is wrong...
+ * esp. call gates. */
+ Log(("RaiseXcptOrIntInProtMode %#x - invalid type (%#x) -> #GP\n", u8Vector, Idte.Gate.u4Type));
+ return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
+ }
+
+ case X86_SEL_TYPE_SYS_286_INT_GATE:
+ case X86_SEL_TYPE_SYS_386_INT_GATE:
+ fEflToClear |= X86_EFL_IF;
+ break;
+
+ case X86_SEL_TYPE_SYS_TASK_GATE:
+ /** @todo task gates. */
+ AssertFailedReturn(VERR_NOT_SUPPORTED);
+
+ case X86_SEL_TYPE_SYS_286_TRAP_GATE:
+ case X86_SEL_TYPE_SYS_386_TRAP_GATE:
+ break;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+
+ /* Check DPL against CPL if applicable. */
+ if (fFlags & IEM_XCPT_FLAGS_T_SOFT_INT)
+ {
+ if (pIemCpu->uCpl > Idte.Gate.u2Dpl)
+ {
+ Log(("RaiseXcptOrIntInProtMode %#x - CPL (%d) > DPL (%d) -> #GP\n", u8Vector, pIemCpu->uCpl, Idte.Gate.u2Dpl));
+ return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
+ }
+ }
+
+ /* Is it there? */
+ if (!Idte.Gate.u1Present)
+ {
+ Log(("RaiseXcptOrIntInProtMode %#x - not present -> #NP\n", u8Vector));
+ return iemRaiseSelectorNotPresentWithErr(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
+ }
+
+ /* A null CS is bad. */
+ RTSEL NewCS = Idte.Gate.u16Sel;
+ if (!(NewCS & (X86_SEL_MASK | X86_SEL_LDT)))
+ {
+ Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x -> #GP\n", u8Vector, NewCS));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ /* Fetch the descriptor for the new CS. */
+ IEMSELDESC DescCS;
+ rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /* Must be a code segment. */
+ if (!DescCS.Legacy.Gen.u1DescType)
+ {
+ Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - system selector (%#x) -> #GP\n", u8Vector, NewCS, DescCS.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & (X86_SEL_MASK | X86_SEL_LDT));
+ }
+ if (!(DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CODE))
+ {
+ Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - data selector (%#x) -> #GP\n", u8Vector, NewCS, DescCS.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & (X86_SEL_MASK | X86_SEL_LDT));
+ }
+
+ /* Don't allow lowering the privilege level. */
+ /** @todo Does the lowering of privileges apply to software interrupts
+ * only? This has bearings on the more-privileged or
+ * same-privilege stack behavior further down. A testcase would
+ * be nice. */
+ if (DescCS.Legacy.Gen.u2Dpl > pIemCpu->uCpl)
+ {
+ Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - DPL (%d) > CPL (%d) -> #GP\n",
+ u8Vector, NewCS, DescCS.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
+ return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & (X86_SEL_MASK | X86_SEL_LDT));
+ }
+ /** @todo is the RPL of the interrupt/trap gate descriptor checked? */
+
+ /* Check the new EIP against the new CS limit. */
+ uint32_t const uNewEip = Idte.Gate.u4Type == X86_SEL_TYPE_SYS_286_INT_GATE
+ || Idte.Gate.u4Type == X86_SEL_TYPE_SYS_286_TRAP_GATE
+ ? Idte.Gate.u16OffsetLow
+ : Idte.Gate.u16OffsetLow | ((uint32_t)Idte.Gate.u16OffsetHigh << 16);
+ uint32_t cbLimitCS = X86DESC_LIMIT(DescCS.Legacy);
+ if (DescCS.Legacy.Gen.u1Granularity)
+ cbLimitCS = (cbLimitCS << PAGE_SHIFT) | PAGE_OFFSET_MASK;
+ if (uNewEip > cbLimitCS)
+ {
+ Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - DPL (%d) > CPL (%d) -> #GP\n",
+ u8Vector, NewCS, DescCS.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
+ return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & (X86_SEL_MASK | X86_SEL_LDT));
+ }
+
+ /* Make sure the selector is present. */
+ if (!DescCS.Legacy.Gen.u1Present)
+ {
+ Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - segment not present -> #NP\n", u8Vector, NewCS));
+ return iemRaiseSelectorNotPresentBySelector(pIemCpu, NewCS);
+ }
+
+ /*
+ * If the privilege level changes, we need to get a new stack from the TSS.
+ * This in turns means validating the new SS and ESP...
+ */
+ uint8_t const uNewCpl = DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CONF
+ ? pIemCpu->uCpl : DescCS.Legacy.Gen.u2Dpl;
+ if (uNewCpl != pIemCpu->uCpl)
+ {
+ RTSEL NewSS;
+ uint32_t uNewEsp;
+ rcStrict = iemRaiseLoadStackFromTss32Or16(pIemCpu, pCtx, uNewCpl, &NewSS, &uNewEsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ IEMSELDESC DescSS;
+ rcStrict = iemMiscValidateNewSS(pIemCpu, pCtx, NewSS, uNewCpl, &DescSS);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /* Check that there is sufficient space for the stack frame. */
+ uint32_t cbLimitSS = X86DESC_LIMIT(DescSS.Legacy);
+ if (DescSS.Legacy.Gen.u1Granularity)
+ cbLimitSS = (cbLimitSS << PAGE_SHIFT) | PAGE_OFFSET_MASK;
+ AssertReturn(!(DescSS.Legacy.Gen.u4Type & X86_SEL_TYPE_DOWN), VERR_NOT_IMPLEMENTED);
+
+ uint8_t const cbStackFrame = fFlags & IEM_XCPT_FLAGS_ERR ? 24 : 20;
+ if ( uNewEsp - 1 > cbLimitSS
+ || uNewEsp < cbStackFrame)
+ {
+ Log(("RaiseXcptOrIntInProtMode: %#x - SS=%#x ESP=%#x cbStackFrame=%#x is out of bounds -> #GP\n",
+ u8Vector, NewSS, uNewEsp, cbStackFrame));
+ return iemRaiseSelectorBoundsBySelector(pIemCpu, NewSS);
+ }
+
+ /*
+ * Start making changes.
+ */
+
+ /* Create the stack frame. */
+ RTPTRUNION uStackFrame;
+ rcStrict = iemMemMap(pIemCpu, &uStackFrame.pv, cbStackFrame, UINT8_MAX,
+ uNewEsp - cbStackFrame + X86DESC_BASE(DescSS.Legacy), IEM_ACCESS_STACK_W);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ void * const pvStackFrame = uStackFrame.pv;
+
+ if (fFlags & IEM_XCPT_FLAGS_ERR)
+ *uStackFrame.pu32++ = uErr;
+ uStackFrame.pu32[0] = pCtx->eip;
+ uStackFrame.pu32[1] = (pCtx->cs & ~X86_SEL_RPL) | pIemCpu->uCpl;
+ uStackFrame.pu32[2] = pCtx->eflags.u;
+ uStackFrame.pu32[3] = pCtx->esp;
+ uStackFrame.pu32[4] = pCtx->ss;
+ rcStrict = iemMemCommitAndUnmap(pIemCpu, pvStackFrame, IEM_ACCESS_STACK_W);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /* Mark the selectors 'accessed' (hope this is the correct time). */
+ /** @todo testcase: excatly _when_ are the accessed bits set - before or
+ * after pushing the stack frame? (Write protect the gdt + stack to
+ * find out.) */
+ if (!(DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_ACCESSED))
+ {
+ rcStrict = iemMemMarkSelDescAccessed(pIemCpu, NewCS);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ DescCS.Legacy.Gen.u4Type |= X86_SEL_TYPE_ACCESSED;
+ }
+
+ if (!(DescSS.Legacy.Gen.u4Type & X86_SEL_TYPE_ACCESSED))
+ {
+ rcStrict = iemMemMarkSelDescAccessed(pIemCpu, NewSS);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ DescSS.Legacy.Gen.u4Type |= X86_SEL_TYPE_ACCESSED;
+ }
+
+ /*
+ * Start commint the register changes (joins with the DPL=CPL branch).
+ */
+ pCtx->ss = NewSS;
+ pCtx->ssHid.u32Limit = cbLimitSS;
+ pCtx->ssHid.u64Base = X86DESC_BASE(DescSS.Legacy);
+ pCtx->ssHid.Attr.u = X86DESC_GET_HID_ATTR(DescSS.Legacy);
+ pCtx->rsp = uNewEsp - cbStackFrame; /** @todo Is the high word cleared for 16-bit stacks and/or interrupt handlers? */
+ pIemCpu->uCpl = uNewCpl;
+ }
+ /*
+ * Same privilege, no stack change and smaller stack frame.
+ */
+ else
+ {
+ uint64_t uNewRsp;
+ RTPTRUNION uStackFrame;
+ uint8_t const cbStackFrame = fFlags & IEM_XCPT_FLAGS_ERR ? 16 : 12;
+ rcStrict = iemMemStackPushBeginSpecial(pIemCpu, cbStackFrame, &uStackFrame.pv, &uNewRsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ void * const pvStackFrame = uStackFrame.pv;
+
+ if (fFlags & IEM_XCPT_FLAGS_ERR)
+ *uStackFrame.pu32++ = uErr;
+ uStackFrame.pu32[0] = pCtx->eip;
+ uStackFrame.pu32[1] = (pCtx->cs & ~X86_SEL_RPL) | pIemCpu->uCpl;
+ uStackFrame.pu32[2] = pCtx->eflags.u;
+ rcStrict = iemMemCommitAndUnmap(pIemCpu, pvStackFrame, IEM_ACCESS_STACK_W); /* don't use the commit here */
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /* Mark the CS selector as 'accessed'. */
+ if (!(DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_ACCESSED))
+ {
+ rcStrict = iemMemMarkSelDescAccessed(pIemCpu, NewCS);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ DescCS.Legacy.Gen.u4Type |= X86_SEL_TYPE_ACCESSED;
+ }
+
+ /*
+ * Start committing the register changes (joins with the other branch).
+ */
+ pCtx->rsp = uNewRsp;
+ }
+
+ /* ... register committing continues. */
+ pCtx->cs = (NewCS & ~X86_SEL_RPL) | uNewCpl;
+ pCtx->csHid.u32Limit = cbLimitCS;
+ pCtx->csHid.u64Base = X86DESC_BASE(DescCS.Legacy);
+ pCtx->csHid.Attr.u = X86DESC_GET_HID_ATTR(DescCS.Legacy);
+
+ pCtx->rip = uNewEip;
+ pCtx->rflags.u &= ~fEflToClear;
+
+ if (fFlags & IEM_XCPT_FLAGS_T_CPU_XCPT)
+ iemRaiseXcptAdjustState(pCtx, u8Vector);
+
+ return fFlags & IEM_XCPT_FLAGS_T_CPU_XCPT ? VINF_IEM_RAISED_XCPT : VINF_SUCCESS;
+}
+
+
+/**
+ * Implements exceptions and interrupts for V8086 mode.
+ *
+ * @returns VBox strict status code.
+ * @param pIemCpu The IEM per CPU instance data.
+ * @param pCtx The CPU context.
+ * @param cbInstr The number of bytes to offset rIP by in the return
+ * address.
+ * @param u8Vector The interrupt / exception vector number.
+ * @param fFlags The flags.
+ * @param uErr The error value if IEM_XCPT_FLAGS_ERR is set.
+ * @param uCr2 The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
+ */
+static VBOXSTRICTRC
+iemRaiseXcptOrIntInV8086Mode(PIEMCPU pIemCpu,
+ PCPUMCTX pCtx,
+ uint8_t cbInstr,
+ uint8_t u8Vector,
+ uint32_t fFlags,
+ uint16_t uErr,
+ uint64_t uCr2)
+{
+ AssertMsgFailed(("V8086 exception / interrupt dispatching\n"));
+ return VERR_NOT_IMPLEMENTED;
+}
+
+
+/**
+ * Implements exceptions and interrupts for long mode.
+ *
+ * @returns VBox strict status code.
+ * @param pIemCpu The IEM per CPU instance data.
+ * @param pCtx The CPU context.
+ * @param cbInstr The number of bytes to offset rIP by in the return
+ * address.
+ * @param u8Vector The interrupt / exception vector number.
+ * @param fFlags The flags.
+ * @param uErr The error value if IEM_XCPT_FLAGS_ERR is set.
+ * @param uCr2 The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
+ */
+static VBOXSTRICTRC
+iemRaiseXcptOrIntInLongMode(PIEMCPU pIemCpu,
+ PCPUMCTX pCtx,
+ uint8_t cbInstr,
+ uint8_t u8Vector,
+ uint32_t fFlags,
+ uint16_t uErr,
+ uint64_t uCr2)
+{
+ AssertMsgFailed(("long mode exception / interrupt dispatching\n"));
+ return VERR_NOT_IMPLEMENTED;
+}
+
+
+/**
+ * Implements exceptions and interrupts.
+ *
+ * All exceptions and interrupts goes thru this function!
+ *
+ * @returns VBox strict status code.
+ * @param pIemCpu The IEM per CPU instance data.
+ * @param cbInstr The number of bytes to offset rIP by in the return
+ * address.
+ * @param u8Vector The interrupt / exception vector number.
+ * @param fFlags The flags.
+ * @param uErr The error value if IEM_XCPT_FLAGS_ERR is set.
+ * @param uCr2 The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
+ */
+DECL_NO_INLINE(static, VBOXSTRICTRC)
+iemRaiseXcptOrInt(PIEMCPU pIemCpu,
+ uint8_t cbInstr,
+ uint8_t u8Vector,
+ uint32_t fFlags,
+ uint16_t uErr,
+ uint64_t uCr2)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Do recursion accounting.
+ */
+ uint8_t const uPrevXcpt = pIemCpu->uCurXcpt;
+ uint32_t const fPrevXcpt = pIemCpu->fCurXcpt;
+ if (pIemCpu->cXcptRecursions == 0)
+ Log(("iemRaiseXcptOrInt: %#x at %04x:%RGv cbInstr=%#x fFlags=%#x uErr=%#x uCr2=%llx\n",
+ u8Vector, pCtx->cs, pCtx->rip, cbInstr, fFlags, uErr, uCr2));
+ else
+ {
+ Log(("iemRaiseXcptOrInt: %#x at %04x:%RGv cbInstr=%#x fFlags=%#x uErr=%#x uCr2=%llx; prev=%#x depth=%d flags=%#x\n",
+ u8Vector, pCtx->cs, pCtx->rip, cbInstr, fFlags, uErr, uCr2, pIemCpu->uCurXcpt, pIemCpu->cXcptRecursions + 1, fPrevXcpt));
+
+ /** @todo double and tripple faults. */
+ AssertReturn(pIemCpu->cXcptRecursions < 3, VERR_NOT_IMPLEMENTED);
+
+ /** @todo set X86_TRAP_ERR_EXTERNAL when appropriate.
+ if (fPrevXcpt & IEM_XCPT_FLAGS_T_EXT_INT)
+ {
+ ....
+ } */
+ }
+ pIemCpu->cXcptRecursions++;
+ pIemCpu->uCurXcpt = u8Vector;
+ pIemCpu->fCurXcpt = fFlags;
+
+ /*
+ * Extensive logging.
+ */
+#ifdef LOG_ENABLED
+ if (LogIs3Enabled())
+ {
+ PVM pVM = IEMCPU_TO_VM(pIemCpu);
+ PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
+ char szRegs[4096];
+ DBGFR3RegPrintf(pVM, pVCpu->idCpu, &szRegs[0], sizeof(szRegs),
+ "rax=%016VR{rax} rbx=%016VR{rbx} rcx=%016VR{rcx} rdx=%016VR{rdx}\n"
+ "rsi=%016VR{rsi} rdi=%016VR{rdi} r8 =%016VR{r8} r9 =%016VR{r9}\n"
+ "r10=%016VR{r10} r11=%016VR{r11} r12=%016VR{r12} r13=%016VR{r13}\n"
+ "r14=%016VR{r14} r15=%016VR{r15} %VRF{rflags}\n"
+ "rip=%016VR{rip} rsp=%016VR{rsp} rbp=%016VR{rbp}\n"
+ "cs={%04VR{cs} base=%016VR{cs_base} limit=%08VR{cs_lim} flags=%04VR{cs_attr}} cr0=%016VR{cr0}\n"
+ "ds={%04VR{ds} base=%016VR{ds_base} limit=%08VR{ds_lim} flags=%04VR{ds_attr}} cr2=%016VR{cr2}\n"
+ "es={%04VR{es} base=%016VR{es_base} limit=%08VR{es_lim} flags=%04VR{es_attr}} cr3=%016VR{cr3}\n"
+ "fs={%04VR{fs} base=%016VR{fs_base} limit=%08VR{fs_lim} flags=%04VR{fs_attr}} cr4=%016VR{cr4}\n"
+ "gs={%04VR{gs} base=%016VR{gs_base} limit=%08VR{gs_lim} flags=%04VR{gs_attr}} cr8=%016VR{cr8}\n"
+ "ss={%04VR{ss} base=%016VR{ss_base} limit=%08VR{ss_lim} flags=%04VR{ss_attr}}\n"
+ "dr0=%016VR{dr0} dr1=%016VR{dr1} dr2=%016VR{dr2} dr3=%016VR{dr3}\n"
+ "dr6=%016VR{dr6} dr7=%016VR{dr7}\n"
+ "gdtr=%016VR{gdtr_base}:%04VR{gdtr_lim} idtr=%016VR{idtr_base}:%04VR{idtr_lim} rflags=%08VR{rflags}\n"
+ "ldtr={%04VR{ldtr} base=%016VR{ldtr_base} limit=%08VR{ldtr_lim} flags=%08VR{ldtr_attr}}\n"
+ "tr ={%04VR{tr} base=%016VR{tr_base} limit=%08VR{tr_lim} flags=%08VR{tr_attr}}\n"
+ " sysenter={cs=%04VR{sysenter_cs} eip=%08VR{sysenter_eip} esp=%08VR{sysenter_esp}}\n"
+ " efer=%016VR{efer}\n"
+ " pat=%016VR{pat}\n"
+ " sf_mask=%016VR{sf_mask}\n"
+ "krnl_gs_base=%016VR{krnl_gs_base}\n"
+ " lstar=%016VR{lstar}\n"
+ " star=%016VR{star} cstar=%016VR{cstar}\n"
+ "fcw=%04VR{fcw} fsw=%04VR{fsw} ftw=%04VR{ftw} mxcsr=%04VR{mxcsr} mxcsr_mask=%04VR{mxcsr_mask}\n"
+ );
+
+ char szInstr[256];
+ DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, 0, 0,
+ DBGF_DISAS_FLAGS_CURRENT_GUEST | DBGF_DISAS_FLAGS_DEFAULT_MODE,
+ szInstr, sizeof(szInstr), NULL);
+ Log3(("%s%s\n", szRegs, szInstr));
+ }
+#endif /* LOG_ENABLED */
+
+ /*
+ * Call the mode specific worker function.
+ */
+ VBOXSTRICTRC rcStrict;
+ if (!(pCtx->cr0 & X86_CR0_PE))
+ rcStrict = iemRaiseXcptOrIntInRealMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
+ else if (pCtx->msrEFER & MSR_K6_EFER_LMA)
+ rcStrict = iemRaiseXcptOrIntInLongMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
+ else if (!pCtx->eflags.Bits.u1VM)
+ rcStrict = iemRaiseXcptOrIntInProtMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
+ else
+ rcStrict = iemRaiseXcptOrIntInV8086Mode(pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
+
+ /*
+ * Unwind.
+ */
+ pIemCpu->cXcptRecursions--;
+ pIemCpu->uCurXcpt = uPrevXcpt;
+ pIemCpu->fCurXcpt = fPrevXcpt;
+ Log(("iemRaiseXcptOrInt: returns %Rrc (vec=%#x); cs:rip=%04x:%RGv ss:rsp=%04x:%RGv\n",
+ VBOXSTRICTRC_VAL(rcStrict), u8Vector, pCtx->cs, pCtx->rip, pCtx->ss, pCtx->esp));
+ return rcStrict;
+}
+
+
+/** \#DE - 00. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseDivideError(PIEMCPU pIemCpu)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_DE, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
+}
+
+
+/** \#DB - 01. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseDebugException(PIEMCPU pIemCpu)
+{
+ /** @todo set/clear RF. */
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_DB, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
+}
+
+
+/** \#UD - 06. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseUndefinedOpcode(PIEMCPU pIemCpu)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_UD, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
+}
+
+
+/** \#NM - 07. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseDeviceNotAvailable(PIEMCPU pIemCpu)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_NM, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
+}
+
+
+/** \#TS(err) - 0a. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseTaskSwitchFaultWithErr(PIEMCPU pIemCpu, uint16_t uErr)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_TS, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, uErr, 0);
+}
+
+
+/** \#TS(tr) - 0a. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseTaskSwitchFaultCurrentTSS(PIEMCPU pIemCpu)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_TS, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
+ pIemCpu->CTX_SUFF(pCtx)->tr, 0);
+}
+
+
+/** \#NP(err) - 0b. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseSelectorNotPresentWithErr(PIEMCPU pIemCpu, uint16_t uErr)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_NP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, uErr, 0);
+}
+
+
+/** \#NP(seg) - 0b. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseSelectorNotPresentBySegReg(PIEMCPU pIemCpu, uint32_t iSegReg)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_NP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
+ iemSRegFetchU16(pIemCpu, iSegReg) & ~X86_SEL_RPL, 0);
+}
+
+
+/** \#NP(sel) - 0b. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseSelectorNotPresentBySelector(PIEMCPU pIemCpu, uint16_t uSel)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_NP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
+ uSel & ~X86_SEL_RPL, 0);
+}
+
+
+/** \#GP(n) - 0d. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseGeneralProtectionFault(PIEMCPU pIemCpu, uint16_t uErr)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, uErr, 0);
+}
+
+
+/** \#GP(0) - 0d. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseGeneralProtectionFault0(PIEMCPU pIemCpu)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
+}
+
+
+/** \#GP(sel) - 0d. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseGeneralProtectionFaultBySelector(PIEMCPU pIemCpu, RTSEL Sel)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
+ Sel & ~X86_SEL_RPL, 0);
+}
+
+
+/** \#GP(0) - 0d. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseNotCanonical(PIEMCPU pIemCpu)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
+}
+
+
+/** \#GP(sel) - 0d. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseSelectorBounds(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess)
+{
+ NOREF(iSegReg); NOREF(fAccess);
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
+}
+
+
+/** \#GP(sel) - 0d. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseSelectorBoundsBySelector(PIEMCPU pIemCpu, RTSEL Sel)
+{
+ NOREF(Sel);
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
+}
+
+
+/** \#GP(sel) - 0d. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseSelectorInvalidAccess(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess)
+{
+ NOREF(iSegReg); NOREF(fAccess);
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
+}
+
+
+/** \#PF(n) - 0e. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc)
+{
+ uint16_t uErr;
+ switch (rc)
+ {
+ case VERR_PAGE_NOT_PRESENT:
+ case VERR_PAGE_TABLE_NOT_PRESENT:
+ case VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT:
+ case VERR_PAGE_MAP_LEVEL4_NOT_PRESENT:
+ uErr = 0;
+ break;
+
+ default:
+ AssertMsgFailed(("%Rrc\n", rc));
+ case VERR_ACCESS_DENIED:
+ uErr = X86_TRAP_PF_P;
+ break;
+
+ /** @todo reserved */
+ }
+
+ if (pIemCpu->uCpl == 3)
+ uErr |= X86_TRAP_PF_US;
+
+ if ( (fAccess & IEM_ACCESS_WHAT_MASK) == IEM_ACCESS_WHAT_CODE
+ && ( (pIemCpu->CTX_SUFF(pCtx)->cr4 & X86_CR4_PAE)
+ && (pIemCpu->CTX_SUFF(pCtx)->msrEFER & MSR_K6_EFER_NXE) ) )
+ uErr |= X86_TRAP_PF_ID;
+
+ if (fAccess & IEM_ACCESS_TYPE_WRITE)
+ uErr |= X86_TRAP_PF_RW;
+
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_PF, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR | IEM_XCPT_FLAGS_CR2,
+ uErr, GCPtrWhere);
+}
+
+
+/** \#MF(n) - 10. */
+DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseMathFault(PIEMCPU pIemCpu)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_MF, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
+}
+
+
+/**
+ * Macro for calling iemCImplRaiseInvalidLockPrefix().
+ *
+ * This enables us to add/remove arguments and force different levels of
+ * inlining as we wish.
+ *
+ * @return Strict VBox status code.
+ */
+#define IEMOP_RAISE_INVALID_LOCK_PREFIX() IEM_MC_DEFER_TO_CIMPL_0(iemCImplRaiseInvalidLockPrefix)
+IEM_CIMPL_DEF_0(iemCImplRaiseInvalidLockPrefix)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_UD, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
+}
+
+
+/**
+ * Macro for calling iemCImplRaiseInvalidOpcode().
+ *
+ * This enables us to add/remove arguments and force different levels of
+ * inlining as we wish.
+ *
+ * @return Strict VBox status code.
+ */
+#define IEMOP_RAISE_INVALID_OPCODE() IEM_MC_DEFER_TO_CIMPL_0(iemCImplRaiseInvalidOpcode)
+IEM_CIMPL_DEF_0(iemCImplRaiseInvalidOpcode)
+{
+ return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_UD, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
+}
+
+
+/** @} */
+
+
+/*
+ *
+ * Helpers routines.
+ * Helpers routines.
+ * Helpers routines.
+ *
+ */
+
+/**
+ * Recalculates the effective operand size.
+ *
+ * @param pIemCpu The IEM state.
+ */
+static void iemRecalEffOpSize(PIEMCPU pIemCpu)
+{
+ switch (pIemCpu->enmCpuMode)
+ {
+ case IEMMODE_16BIT:
+ pIemCpu->enmEffOpSize = pIemCpu->fPrefixes & IEM_OP_PRF_SIZE_OP ? IEMMODE_32BIT : IEMMODE_16BIT;
+ break;
+ case IEMMODE_32BIT:
+ pIemCpu->enmEffOpSize = pIemCpu->fPrefixes & IEM_OP_PRF_SIZE_OP ? IEMMODE_16BIT : IEMMODE_32BIT;
+ break;
+ case IEMMODE_64BIT:
+ switch (pIemCpu->fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP))
+ {
+ case 0:
+ pIemCpu->enmEffOpSize = pIemCpu->enmDefOpSize;
+ break;
+ case IEM_OP_PRF_SIZE_OP:
+ pIemCpu->enmEffOpSize = IEMMODE_16BIT;
+ break;
+ case IEM_OP_PRF_SIZE_REX_W:
+ case IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP:
+ pIemCpu->enmEffOpSize = IEMMODE_64BIT;
+ break;
+ }
+ break;
+ default:
+ AssertFailed();
+ }
+}
+
+
+/**
+ * Sets the default operand size to 64-bit and recalculates the effective
+ * operand size.
+ *
+ * @param pIemCpu The IEM state.
+ */
+static void iemRecalEffOpSize64Default(PIEMCPU pIemCpu)
+{
+ Assert(pIemCpu->enmCpuMode == IEMMODE_64BIT);
+ pIemCpu->enmDefOpSize = IEMMODE_64BIT;
+ if ((pIemCpu->fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP)) != IEM_OP_PRF_SIZE_OP)
+ pIemCpu->enmEffOpSize = IEMMODE_64BIT;
+ else
+ pIemCpu->enmEffOpSize = IEMMODE_16BIT;
+}
+
+
+/*
+ *
+ * Common opcode decoders.
+ * Common opcode decoders.
+ * Common opcode decoders.
+ *
+ */
+#include <iprt/mem.h>
+
+/**
+ * Used to add extra details about a stub case.
+ * @param pIemCpu The IEM per CPU state.
+ */
+static void iemOpStubMsg2(PIEMCPU pIemCpu)
+{
+ PVM pVM = IEMCPU_TO_VM(pIemCpu);
+ PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
+ char szRegs[4096];
+ DBGFR3RegPrintf(pVM, pVCpu->idCpu, &szRegs[0], sizeof(szRegs),
+ "rax=%016VR{rax} rbx=%016VR{rbx} rcx=%016VR{rcx} rdx=%016VR{rdx}\n"
+ "rsi=%016VR{rsi} rdi=%016VR{rdi} r8 =%016VR{r8} r9 =%016VR{r9}\n"
+ "r10=%016VR{r10} r11=%016VR{r11} r12=%016VR{r12} r13=%016VR{r13}\n"
+ "r14=%016VR{r14} r15=%016VR{r15} %VRF{rflags}\n"
+ "rip=%016VR{rip} rsp=%016VR{rsp} rbp=%016VR{rbp}\n"
+ "cs={%04VR{cs} base=%016VR{cs_base} limit=%08VR{cs_lim} flags=%04VR{cs_attr}} cr0=%016VR{cr0}\n"
+ "ds={%04VR{ds} base=%016VR{ds_base} limit=%08VR{ds_lim} flags=%04VR{ds_attr}} cr2=%016VR{cr2}\n"
+ "es={%04VR{es} base=%016VR{es_base} limit=%08VR{es_lim} flags=%04VR{es_attr}} cr3=%016VR{cr3}\n"
+ "fs={%04VR{fs} base=%016VR{fs_base} limit=%08VR{fs_lim} flags=%04VR{fs_attr}} cr4=%016VR{cr4}\n"
+ "gs={%04VR{gs} base=%016VR{gs_base} limit=%08VR{gs_lim} flags=%04VR{gs_attr}} cr8=%016VR{cr8}\n"
+ "ss={%04VR{ss} base=%016VR{ss_base} limit=%08VR{ss_lim} flags=%04VR{ss_attr}}\n"
+ "dr0=%016VR{dr0} dr1=%016VR{dr1} dr2=%016VR{dr2} dr3=%016VR{dr3}\n"
+ "dr6=%016VR{dr6} dr7=%016VR{dr7}\n"
+ "gdtr=%016VR{gdtr_base}:%04VR{gdtr_lim} idtr=%016VR{idtr_base}:%04VR{idtr_lim} rflags=%08VR{rflags}\n"
+ "ldtr={%04VR{ldtr} base=%016VR{ldtr_base} limit=%08VR{ldtr_lim} flags=%08VR{ldtr_attr}}\n"
+ "tr ={%04VR{tr} base=%016VR{tr_base} limit=%08VR{tr_lim} flags=%08VR{tr_attr}}\n"
+ " sysenter={cs=%04VR{sysenter_cs} eip=%08VR{sysenter_eip} esp=%08VR{sysenter_esp}}\n"
+ " efer=%016VR{efer}\n"
+ " pat=%016VR{pat}\n"
+ " sf_mask=%016VR{sf_mask}\n"
+ "krnl_gs_base=%016VR{krnl_gs_base}\n"
+ " lstar=%016VR{lstar}\n"
+ " star=%016VR{star} cstar=%016VR{cstar}\n"
+ "fcw=%04VR{fcw} fsw=%04VR{fsw} ftw=%04VR{ftw} mxcsr=%04VR{mxcsr} mxcsr_mask=%04VR{mxcsr_mask}\n"
+ );
+
+ char szInstr[256];
+ DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, 0, 0,
+ DBGF_DISAS_FLAGS_CURRENT_GUEST | DBGF_DISAS_FLAGS_DEFAULT_MODE,
+ szInstr, sizeof(szInstr), NULL);
+
+ RTAssertMsg2Weak("%s%s\n", szRegs, szInstr);
+}
+
+
+/** Stubs an opcode. */
+#define FNIEMOP_STUB(a_Name) \
+ FNIEMOP_DEF(a_Name) \
+ { \
+ RTAssertMsg1(NULL, __LINE__, __FILE__, __FUNCTION__); \
+ iemOpStubMsg2(pIemCpu); \
+ RTAssertPanic(); \
+ return VERR_NOT_IMPLEMENTED; \
+ } \
+ typedef int ignore_semicolon
+
+/** Stubs an opcode. */
+#define FNIEMOP_STUB_1(a_Name, a_Type0, a_Name0) \
+ FNIEMOP_DEF_1(a_Name, a_Type0, a_Name0) \
+ { \
+ RTAssertMsg1(NULL, __LINE__, __FILE__, __FUNCTION__); \
+ iemOpStubMsg2(pIemCpu); \
+ RTAssertPanic(); \
+ return VERR_NOT_IMPLEMENTED; \
+ } \
+ typedef int ignore_semicolon
+
+
+
+/** @name Register Access.
+ * @{
+ */
+
+/**
+ * Gets a reference (pointer) to the specified hidden segment register.
+ *
+ * @returns Hidden register reference.
+ * @param pIemCpu The per CPU data.
+ * @param iSegReg The segment register.
+ */
+static PCPUMSELREGHID iemSRegGetHid(PIEMCPU pIemCpu, uint8_t iSegReg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ switch (iSegReg)
+ {
+ case X86_SREG_ES: return &pCtx->esHid;
+ case X86_SREG_CS: return &pCtx->csHid;
+ case X86_SREG_SS: return &pCtx->ssHid;
+ case X86_SREG_DS: return &pCtx->dsHid;
+ case X86_SREG_FS: return &pCtx->fsHid;
+ case X86_SREG_GS: return &pCtx->gsHid;
+ }
+ AssertFailedReturn(NULL);
+}
+
+
+/**
+ * Gets a reference (pointer) to the specified segment register (the selector
+ * value).
+ *
+ * @returns Pointer to the selector variable.
+ * @param pIemCpu The per CPU data.
+ * @param iSegReg The segment register.
+ */
+static uint16_t *iemSRegRef(PIEMCPU pIemCpu, uint8_t iSegReg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ switch (iSegReg)
+ {
+ case X86_SREG_ES: return &pCtx->es;
+ case X86_SREG_CS: return &pCtx->cs;
+ case X86_SREG_SS: return &pCtx->ss;
+ case X86_SREG_DS: return &pCtx->ds;
+ case X86_SREG_FS: return &pCtx->fs;
+ case X86_SREG_GS: return &pCtx->gs;
+ }
+ AssertFailedReturn(NULL);
+}
+
+
+/**
+ * Fetches the selector value of a segment register.
+ *
+ * @returns The selector value.
+ * @param pIemCpu The per CPU data.
+ * @param iSegReg The segment register.
+ */
+static uint16_t iemSRegFetchU16(PIEMCPU pIemCpu, uint8_t iSegReg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ switch (iSegReg)
+ {
+ case X86_SREG_ES: return pCtx->es;
+ case X86_SREG_CS: return pCtx->cs;
+ case X86_SREG_SS: return pCtx->ss;
+ case X86_SREG_DS: return pCtx->ds;
+ case X86_SREG_FS: return pCtx->fs;
+ case X86_SREG_GS: return pCtx->gs;
+ }
+ AssertFailedReturn(0xffff);
+}
+
+
+/**
+ * Gets a reference (pointer) to the specified general register.
+ *
+ * @returns Register reference.
+ * @param pIemCpu The per CPU data.
+ * @param iReg The general register.
+ */
+static void *iemGRegRef(PIEMCPU pIemCpu, uint8_t iReg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ switch (iReg)
+ {
+ case X86_GREG_xAX: return &pCtx->rax;
+ case X86_GREG_xCX: return &pCtx->rcx;
+ case X86_GREG_xDX: return &pCtx->rdx;
+ case X86_GREG_xBX: return &pCtx->rbx;
+ case X86_GREG_xSP: return &pCtx->rsp;
+ case X86_GREG_xBP: return &pCtx->rbp;
+ case X86_GREG_xSI: return &pCtx->rsi;
+ case X86_GREG_xDI: return &pCtx->rdi;
+ case X86_GREG_x8: return &pCtx->r8;
+ case X86_GREG_x9: return &pCtx->r9;
+ case X86_GREG_x10: return &pCtx->r10;
+ case X86_GREG_x11: return &pCtx->r11;
+ case X86_GREG_x12: return &pCtx->r12;
+ case X86_GREG_x13: return &pCtx->r13;
+ case X86_GREG_x14: return &pCtx->r14;
+ case X86_GREG_x15: return &pCtx->r15;
+ }
+ AssertFailedReturn(NULL);
+}
+
+
+/**
+ * Gets a reference (pointer) to the specified 8-bit general register.
+ *
+ * Because of AH, CH, DH and BH we cannot use iemGRegRef directly here.
+ *
+ * @returns Register reference.
+ * @param pIemCpu The per CPU data.
+ * @param iReg The register.
+ */
+static uint8_t *iemGRegRefU8(PIEMCPU pIemCpu, uint8_t iReg)
+{
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_REX)
+ return (uint8_t *)iemGRegRef(pIemCpu, iReg);
+
+ uint8_t *pu8Reg = (uint8_t *)iemGRegRef(pIemCpu, iReg & 3);
+ if (iReg >= 4)
+ pu8Reg++;
+ return pu8Reg;
+}
+
+
+/**
+ * Fetches the value of a 8-bit general register.
+ *
+ * @returns The register value.
+ * @param pIemCpu The per CPU data.
+ * @param iReg The register.
+ */
+static uint8_t iemGRegFetchU8(PIEMCPU pIemCpu, uint8_t iReg)
+{
+ uint8_t const *pbSrc = iemGRegRefU8(pIemCpu, iReg);
+ return *pbSrc;
+}
+
+
+/**
+ * Fetches the value of a 16-bit general register.
+ *
+ * @returns The register value.
+ * @param pIemCpu The per CPU data.
+ * @param iReg The register.
+ */
+static uint16_t iemGRegFetchU16(PIEMCPU pIemCpu, uint8_t iReg)
+{
+ return *(uint16_t *)iemGRegRef(pIemCpu, iReg);
+}
+
+
+/**
+ * Fetches the value of a 32-bit general register.
+ *
+ * @returns The register value.
+ * @param pIemCpu The per CPU data.
+ * @param iReg The register.
+ */
+static uint32_t iemGRegFetchU32(PIEMCPU pIemCpu, uint8_t iReg)
+{
+ return *(uint32_t *)iemGRegRef(pIemCpu, iReg);
+}
+
+
+/**
+ * Fetches the value of a 64-bit general register.
+ *
+ * @returns The register value.
+ * @param pIemCpu The per CPU data.
+ * @param iReg The register.
+ */
+static uint64_t iemGRegFetchU64(PIEMCPU pIemCpu, uint8_t iReg)
+{
+ return *(uint64_t *)iemGRegRef(pIemCpu, iReg);
+}
+
+
+/**
+ * Is the FPU state in FXSAVE format or not.
+ *
+ * @returns true if it is, false if it's in FNSAVE.
+ * @param pVCpu The virtual CPU handle.
+ */
+DECLINLINE(bool) iemFRegIsFxSaveFormat(PIEMCPU pIemCpu)
+{
+#ifdef RT_ARCH_AMD64
+ return true;
+#else
+/// @todo return pVCpu->pVMR3->cpum.s.CPUFeatures.edx.u1FXSR;
+ return true;
+#endif
+}
+
+
+/**
+ * Gets the FPU status word.
+ *
+ * @returns FPU status word
+ * @param pIemCpu The per CPU data.
+ */
+static uint16_t iemFRegFetchFsw(PIEMCPU pIemCpu)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint16_t u16Fsw;
+ if (iemFRegIsFxSaveFormat(pIemCpu))
+ u16Fsw = pCtx->fpu.FSW;
+ else
+ {
+ PX86FPUSTATE pFpu = (PX86FPUSTATE)&pCtx->fpu;
+ u16Fsw = pFpu->FSW;
+ }
+ return u16Fsw;
+}
+
+/**
+ * Adds a 8-bit signed jump offset to RIP/EIP/IP.
+ *
+ * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
+ * segment limit.
+ *
+ * @param pIemCpu The per CPU data.
+ * @param offNextInstr The offset of the next instruction.
+ */
+static VBOXSTRICTRC iemRegRipRelativeJumpS8(PIEMCPU pIemCpu, int8_t offNextInstr)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ uint16_t uNewIp = pCtx->ip + offNextInstr + pIemCpu->offOpcode;
+ if ( uNewIp > pCtx->csHid.u32Limit
+ && pIemCpu->enmCpuMode != IEMMODE_64BIT) /* no need to check for non-canonical. */
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ pCtx->rip = uNewIp;
+ break;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ Assert(pCtx->rip <= UINT32_MAX);
+ Assert(pIemCpu->enmCpuMode != IEMMODE_64BIT);
+
+ uint32_t uNewEip = pCtx->eip + offNextInstr + pIemCpu->offOpcode;
+ if (uNewEip > pCtx->csHid.u32Limit)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ pCtx->rip = uNewEip;
+ break;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ Assert(pIemCpu->enmCpuMode == IEMMODE_64BIT);
+
+ uint64_t uNewRip = pCtx->rip + offNextInstr + pIemCpu->offOpcode;
+ if (!IEM_IS_CANONICAL(uNewRip))
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ pCtx->rip = uNewRip;
+ break;
+ }
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Adds a 16-bit signed jump offset to RIP/EIP/IP.
+ *
+ * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
+ * segment limit.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The per CPU data.
+ * @param offNextInstr The offset of the next instruction.
+ */
+static VBOXSTRICTRC iemRegRipRelativeJumpS16(PIEMCPU pIemCpu, int16_t offNextInstr)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ Assert(pIemCpu->enmEffOpSize == IEMMODE_16BIT);
+
+ uint16_t uNewIp = pCtx->ip + offNextInstr + pIemCpu->offOpcode;
+ if ( uNewIp > pCtx->csHid.u32Limit
+ && pIemCpu->enmCpuMode != IEMMODE_64BIT) /* no need to check for non-canonical. */
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ /** @todo Test 16-bit jump in 64-bit mode. */
+ pCtx->rip = uNewIp;
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Adds a 32-bit signed jump offset to RIP/EIP/IP.
+ *
+ * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
+ * segment limit.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The per CPU data.
+ * @param offNextInstr The offset of the next instruction.
+ */
+static VBOXSTRICTRC iemRegRipRelativeJumpS32(PIEMCPU pIemCpu, int32_t offNextInstr)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ Assert(pIemCpu->enmEffOpSize != IEMMODE_16BIT);
+
+ if (pIemCpu->enmEffOpSize == IEMMODE_32BIT)
+ {
+ Assert(pCtx->rip <= UINT32_MAX); Assert(pIemCpu->enmCpuMode != IEMMODE_64BIT);
+
+ uint32_t uNewEip = pCtx->eip + offNextInstr + pIemCpu->offOpcode;
+ if (uNewEip > pCtx->csHid.u32Limit)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ pCtx->rip = uNewEip;
+ }
+ else
+ {
+ Assert(pIemCpu->enmCpuMode == IEMMODE_64BIT);
+
+ uint64_t uNewRip = pCtx->rip + offNextInstr + pIemCpu->offOpcode;
+ if (!IEM_IS_CANONICAL(uNewRip))
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ pCtx->rip = uNewRip;
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Performs a near jump to the specified address.
+ *
+ * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
+ * segment limit.
+ *
+ * @param pIemCpu The per CPU data.
+ * @param uNewRip The new RIP value.
+ */
+static VBOXSTRICTRC iemRegRipJump(PIEMCPU pIemCpu, uint64_t uNewRip)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ Assert(uNewRip <= UINT16_MAX);
+ if ( uNewRip > pCtx->csHid.u32Limit
+ && pIemCpu->enmCpuMode != IEMMODE_64BIT) /* no need to check for non-canonical. */
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ /** @todo Test 16-bit jump in 64-bit mode. */
+ pCtx->rip = uNewRip;
+ break;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ Assert(uNewRip <= UINT32_MAX);
+ Assert(pCtx->rip <= UINT32_MAX);
+ Assert(pIemCpu->enmCpuMode != IEMMODE_64BIT);
+
+ if (uNewRip > pCtx->csHid.u32Limit)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ pCtx->rip = uNewRip;
+ break;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ Assert(pIemCpu->enmCpuMode == IEMMODE_64BIT);
+
+ if (!IEM_IS_CANONICAL(uNewRip))
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ pCtx->rip = uNewRip;
+ break;
+ }
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Get the address of the top of the stack.
+ *
+ * @param pCtx The CPU context which SP/ESP/RSP should be
+ * read.
+ */
+DECLINLINE(RTGCPTR) iemRegGetEffRsp(PCCPUMCTX pCtx)
+{
+ if (pCtx->ssHid.Attr.n.u1Long)
+ return pCtx->rsp;
+ if (pCtx->ssHid.Attr.n.u1DefBig)
+ return pCtx->esp;
+ return pCtx->sp;
+}
+
+
+/**
+ * Updates the RIP/EIP/IP to point to the next instruction.
+ *
+ * @param pIemCpu The per CPU data.
+ * @param cbInstr The number of bytes to add.
+ */
+static void iemRegAddToRip(PIEMCPU pIemCpu, uint8_t cbInstr)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ switch (pIemCpu->enmCpuMode)
+ {
+ case IEMMODE_16BIT:
+ Assert(pCtx->rip <= UINT16_MAX);
+ pCtx->eip += cbInstr;
+ pCtx->eip &= UINT32_C(0xffff);
+ break;
+
+ case IEMMODE_32BIT:
+ pCtx->eip += cbInstr;
+ Assert(pCtx->rip <= UINT32_MAX);
+ break;
+
+ case IEMMODE_64BIT:
+ pCtx->rip += cbInstr;
+ break;
+ default: AssertFailed();
+ }
+}
+
+
+/**
+ * Updates the RIP/EIP/IP to point to the next instruction.
+ *
+ * @param pIemCpu The per CPU data.
+ */
+static void iemRegUpdateRip(PIEMCPU pIemCpu)
+{
+ return iemRegAddToRip(pIemCpu, pIemCpu->offOpcode);
+}
+
+
+/**
+ * Adds to the stack pointer.
+ *
+ * @param pCtx The CPU context which SP/ESP/RSP should be
+ * updated.
+ * @param cbToAdd The number of bytes to add.
+ */
+DECLINLINE(void) iemRegAddToRsp(PCPUMCTX pCtx, uint8_t cbToAdd)
+{
+ if (pCtx->ssHid.Attr.n.u1Long)
+ pCtx->rsp += cbToAdd;
+ else if (pCtx->ssHid.Attr.n.u1DefBig)
+ pCtx->esp += cbToAdd;
+ else
+ pCtx->sp += cbToAdd;
+}
+
+
+/**
+ * Subtracts from the stack pointer.
+ *
+ * @param pCtx The CPU context which SP/ESP/RSP should be
+ * updated.
+ * @param cbToSub The number of bytes to subtract.
+ */
+DECLINLINE(void) iemRegSubFromRsp(PCPUMCTX pCtx, uint8_t cbToSub)
+{
+ if (pCtx->ssHid.Attr.n.u1Long)
+ pCtx->rsp -= cbToSub;
+ else if (pCtx->ssHid.Attr.n.u1DefBig)
+ pCtx->esp -= cbToSub;
+ else
+ pCtx->sp -= cbToSub;
+}
+
+
+/**
+ * Adds to the temporary stack pointer.
+ *
+ * @param pTmpRsp The temporary SP/ESP/RSP to update.
+ * @param cbToAdd The number of bytes to add.
+ * @param pCtx Where to get the current stack mode.
+ */
+DECLINLINE(void) iemRegAddToRspEx(PRTUINT64U pTmpRsp, uint8_t cbToAdd, PCCPUMCTX pCtx)
+{
+ if (pCtx->ssHid.Attr.n.u1Long)
+ pTmpRsp->u += cbToAdd;
+ else if (pCtx->ssHid.Attr.n.u1DefBig)
+ pTmpRsp->DWords.dw0 += cbToAdd;
+ else
+ pTmpRsp->Words.w0 += cbToAdd;
+}
+
+
+/**
+ * Subtracts from the temporary stack pointer.
+ *
+ * @param pTmpRsp The temporary SP/ESP/RSP to update.
+ * @param cbToSub The number of bytes to subtract.
+ * @param pCtx Where to get the current stack mode.
+ */
+DECLINLINE(void) iemRegSubFromRspEx(PRTUINT64U pTmpRsp, uint8_t cbToSub, PCCPUMCTX pCtx)
+{
+ if (pCtx->ssHid.Attr.n.u1Long)
+ pTmpRsp->u -= cbToSub;
+ else if (pCtx->ssHid.Attr.n.u1DefBig)
+ pTmpRsp->DWords.dw0 -= cbToSub;
+ else
+ pTmpRsp->Words.w0 -= cbToSub;
+}
+
+
+/**
+ * Calculates the effective stack address for a push of the specified size as
+ * well as the new RSP value (upper bits may be masked).
+ *
+ * @returns Effective stack addressf for the push.
+ * @param pCtx Where to get the current stack mode.
+ * @param cbItem The size of the stack item to pop.
+ * @param puNewRsp Where to return the new RSP value.
+ */
+DECLINLINE(RTGCPTR) iemRegGetRspForPush(PCCPUMCTX pCtx, uint8_t cbItem, uint64_t *puNewRsp)
+{
+ RTUINT64U uTmpRsp;
+ RTGCPTR GCPtrTop;
+ uTmpRsp.u = pCtx->rsp;
+
+ if (pCtx->ssHid.Attr.n.u1Long)
+ GCPtrTop = uTmpRsp.u -= cbItem;
+ else if (pCtx->ssHid.Attr.n.u1DefBig)
+ GCPtrTop = uTmpRsp.DWords.dw0 -= cbItem;
+ else
+ GCPtrTop = uTmpRsp.Words.w0 -= cbItem;
+ *puNewRsp = uTmpRsp.u;
+ return GCPtrTop;
+}
+
+
+/**
+ * Gets the current stack pointer and calculates the value after a pop of the
+ * specified size.
+ *
+ * @returns Current stack pointer.
+ * @param pCtx Where to get the current stack mode.
+ * @param cbItem The size of the stack item to pop.
+ * @param puNewRsp Where to return the new RSP value.
+ */
+DECLINLINE(RTGCPTR) iemRegGetRspForPop(PCCPUMCTX pCtx, uint8_t cbItem, uint64_t *puNewRsp)
+{
+ RTUINT64U uTmpRsp;
+ RTGCPTR GCPtrTop;
+ uTmpRsp.u = pCtx->rsp;
+
+ if (pCtx->ssHid.Attr.n.u1Long)
+ {
+ GCPtrTop = uTmpRsp.u;
+ uTmpRsp.u += cbItem;
+ }
+ else if (pCtx->ssHid.Attr.n.u1DefBig)
+ {
+ GCPtrTop = uTmpRsp.DWords.dw0;
+ uTmpRsp.DWords.dw0 += cbItem;
+ }
+ else
+ {
+ GCPtrTop = uTmpRsp.Words.w0;
+ uTmpRsp.Words.w0 += cbItem;
+ }
+ *puNewRsp = uTmpRsp.u;
+ return GCPtrTop;
+}
+
+
+/**
+ * Calculates the effective stack address for a push of the specified size as
+ * well as the new temporary RSP value (upper bits may be masked).
+ *
+ * @returns Effective stack addressf for the push.
+ * @param pTmpRsp The temporary stack pointer. This is updated.
+ * @param cbItem The size of the stack item to pop.
+ * @param puNewRsp Where to return the new RSP value.
+ */
+DECLINLINE(RTGCPTR) iemRegGetRspForPushEx(PRTUINT64U pTmpRsp, uint8_t cbItem, PCCPUMCTX pCtx)
+{
+ RTGCPTR GCPtrTop;
+
+ if (pCtx->ssHid.Attr.n.u1Long)
+ GCPtrTop = pTmpRsp->u -= cbItem;
+ else if (pCtx->ssHid.Attr.n.u1DefBig)
+ GCPtrTop = pTmpRsp->DWords.dw0 -= cbItem;
+ else
+ GCPtrTop = pTmpRsp->Words.w0 -= cbItem;
+ return GCPtrTop;
+}
+
+
+/**
+ * Gets the effective stack address for a pop of the specified size and
+ * calculates and updates the temporary RSP.
+ *
+ * @returns Current stack pointer.
+ * @param pTmpRsp The temporary stack pointer. This is updated.
+ * @param pCtx Where to get the current stack mode.
+ * @param cbItem The size of the stack item to pop.
+ */
+DECLINLINE(RTGCPTR) iemRegGetRspForPopEx(PRTUINT64U pTmpRsp, uint8_t cbItem, PCCPUMCTX pCtx)
+{
+ RTGCPTR GCPtrTop;
+ if (pCtx->ssHid.Attr.n.u1Long)
+ {
+ GCPtrTop = pTmpRsp->u;
+ pTmpRsp->u += cbItem;
+ }
+ else if (pCtx->ssHid.Attr.n.u1DefBig)
+ {
+ GCPtrTop = pTmpRsp->DWords.dw0;
+ pTmpRsp->DWords.dw0 += cbItem;
+ }
+ else
+ {
+ GCPtrTop = pTmpRsp->Words.w0;
+ pTmpRsp->Words.w0 += cbItem;
+ }
+ return GCPtrTop;
+}
+
+
+/**
+ * Checks if an Intel CPUID feature bit is set.
+ *
+ * @returns true / false.
+ *
+ * @param pIemCpu The IEM per CPU data.
+ * @param fEdx The EDX bit to test, or 0 if ECX.
+ * @param fEcx The ECX bit to test, or 0 if EDX.
+ * @remarks Used via IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX,
+ * IEM_IS_INTEL_CPUID_FEATURE_PRESENT_ECX and others.
+ */
+static bool iemRegIsIntelCpuIdFeaturePresent(PIEMCPU pIemCpu, uint32_t fEdx, uint32_t fEcx)
+{
+ uint32_t uEax, uEbx, uEcx, uEdx;
+ CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), 0x00000001, &uEax, &uEbx, &uEcx, &uEdx);
+ return (fEcx && (uEcx & fEcx))
+ || (fEdx && (uEdx & fEdx));
+}
+
+
+/**
+ * Checks if an AMD CPUID feature bit is set.
+ *
+ * @returns true / false.
+ *
+ * @param pIemCpu The IEM per CPU data.
+ * @param fEdx The EDX bit to test, or 0 if ECX.
+ * @param fEcx The ECX bit to test, or 0 if EDX.
+ * @remarks Used via IEM_IS_AMD_CPUID_FEATURE_PRESENT_EDX,
+ * IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX and others.
+ */
+static bool iemRegIsAmdCpuIdFeaturePresent(PIEMCPU pIemCpu, uint32_t fEdx, uint32_t fEcx)
+{
+ uint32_t uEax, uEbx, uEcx, uEdx;
+ CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), 0x80000001, &uEax, &uEbx, &uEcx, &uEdx);
+ return (fEcx && (uEcx & fEcx))
+ || (fEdx && (uEdx & fEdx));
+}
+
+/** @} */
+
+
+/** @name Memory access.
+ *
+ * @{
+ */
+
+
+/**
+ * Checks if the given segment can be written to, raise the appropriate
+ * exception if not.
+ *
+ * @returns VBox strict status code.
+ *
+ * @param pIemCpu The IEM per CPU data.
+ * @param pHid Pointer to the hidden register.
+ * @param iSegReg The register number.
+ */
+static VBOXSTRICTRC iemMemSegCheckWriteAccessEx(PIEMCPU pIemCpu, PCCPUMSELREGHID pHid, uint8_t iSegReg)
+{
+ if (!pHid->Attr.n.u1Present)
+ return iemRaiseSelectorNotPresentBySegReg(pIemCpu, iSegReg);
+
+ if ( ( (pHid->Attr.n.u4Type & X86_SEL_TYPE_CODE)
+ || !(pHid->Attr.n.u4Type & X86_SEL_TYPE_WRITE) )
+ && pIemCpu->enmCpuMode != IEMMODE_64BIT )
+ return iemRaiseSelectorInvalidAccess(pIemCpu, iSegReg, IEM_ACCESS_DATA_W);
+
+ /** @todo DPL/RPL/CPL? */
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Checks if the given segment can be read from, raise the appropriate
+ * exception if not.
+ *
+ * @returns VBox strict status code.
+ *
+ * @param pIemCpu The IEM per CPU data.
+ * @param pHid Pointer to the hidden register.
+ * @param iSegReg The register number.
+ */
+static VBOXSTRICTRC iemMemSegCheckReadAccessEx(PIEMCPU pIemCpu, PCCPUMSELREGHID pHid, uint8_t iSegReg)
+{
+ if (!pHid->Attr.n.u1Present)
+ return iemRaiseSelectorNotPresentBySegReg(pIemCpu, iSegReg);
+
+ if ( (pHid->Attr.n.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ)) == X86_SEL_TYPE_CODE
+ && pIemCpu->enmCpuMode != IEMMODE_64BIT )
+ return iemRaiseSelectorInvalidAccess(pIemCpu, iSegReg, IEM_ACCESS_DATA_R);
+
+ /** @todo DPL/RPL/CPL? */
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Applies the segment limit, base and attributes.
+ *
+ * This may raise a \#GP or \#SS.
+ *
+ * @returns VBox strict status code.
+ *
+ * @param pIemCpu The IEM per CPU data.
+ * @param fAccess The kind of access which is being performed.
+ * @param iSegReg The index of the segment register to apply.
+ * This is UINT8_MAX if none (for IDT, GDT, LDT,
+ * TSS, ++).
+ * @param pGCPtrMem Pointer to the guest memory address to apply
+ * segmentation to. Input and output parameter.
+ */
+static VBOXSTRICTRC iemMemApplySegment(PIEMCPU pIemCpu, uint32_t fAccess, uint8_t iSegReg,
+ size_t cbMem, PRTGCPTR pGCPtrMem)
+{
+ if (iSegReg == UINT8_MAX)
+ return VINF_SUCCESS;
+
+ PCPUMSELREGHID pSel = iemSRegGetHid(pIemCpu, iSegReg);
+ switch (pIemCpu->enmCpuMode)
+ {
+ case IEMMODE_16BIT:
+ case IEMMODE_32BIT:
+ {
+ RTGCPTR32 GCPtrFirst32 = (RTGCPTR32)*pGCPtrMem;
+ RTGCPTR32 GCPtrLast32 = GCPtrFirst32 + (uint32_t)cbMem - 1;
+
+ Assert(pSel->Attr.n.u1Present);
+ Assert(pSel->Attr.n.u1DescType);
+ if (!(pSel->Attr.n.u4Type & X86_SEL_TYPE_CODE))
+ {
+ if ( (fAccess & IEM_ACCESS_TYPE_WRITE)
+ && !(pSel->Attr.n.u4Type & X86_SEL_TYPE_WRITE) )
+ return iemRaiseSelectorInvalidAccess(pIemCpu, iSegReg, fAccess);
+
+ if (!IEM_IS_REAL_OR_V86_MODE(pIemCpu))
+ {
+ /** @todo CPL check. */
+ }
+
+ /*
+ * There are two kinds of data selectors, normal and expand down.
+ */
+ if (!(pSel->Attr.n.u4Type & X86_SEL_TYPE_DOWN))
+ {
+ if ( GCPtrFirst32 > pSel->u32Limit
+ || GCPtrLast32 > pSel->u32Limit) /* yes, in real mode too (since 80286). */
+ return iemRaiseSelectorBounds(pIemCpu, iSegReg, fAccess);
+
+ *pGCPtrMem = GCPtrFirst32 += (uint32_t)pSel->u64Base;
+ }
+ else
+ {
+ /** @todo implement expand down segments. */
+ AssertFailed(/** @todo implement this */);
+ return VERR_NOT_IMPLEMENTED;
+ }
+ }
+ else
+ {
+
+ /*
+ * Code selector and usually be used to read thru, writing is
+ * only permitted in real and V8086 mode.
+ */
+ if ( ( (fAccess & IEM_ACCESS_TYPE_WRITE)
+ || ( (fAccess & IEM_ACCESS_TYPE_READ)
+ && !(pSel->Attr.n.u4Type & X86_SEL_TYPE_READ)) )
+ && !IEM_IS_REAL_OR_V86_MODE(pIemCpu) )
+ return iemRaiseSelectorInvalidAccess(pIemCpu, iSegReg, fAccess);
+
+ if ( GCPtrFirst32 > pSel->u32Limit
+ || GCPtrLast32 > pSel->u32Limit) /* yes, in real mode too (since 80286). */
+ return iemRaiseSelectorBounds(pIemCpu, iSegReg, fAccess);
+
+ if (!IEM_IS_REAL_OR_V86_MODE(pIemCpu))
+ {
+ /** @todo CPL check. */
+ }
+
+ *pGCPtrMem = GCPtrFirst32 += (uint32_t)pSel->u64Base;
+ }
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_64BIT:
+ if (iSegReg == X86_SREG_GS || iSegReg == X86_SREG_FS)
+ *pGCPtrMem += pSel->u64Base;
+ return VINF_SUCCESS;
+
+ default:
+ AssertFailedReturn(VERR_INTERNAL_ERROR_5);
+ }
+}
+
+
+/**
+ * Translates a virtual address to a physical physical address and checks if we
+ * can access the page as specified.
+ *
+ * @param pIemCpu The IEM per CPU data.
+ * @param GCPtrMem The virtual address.
+ * @param fAccess The intended access.
+ * @param pGCPhysMem Where to return the physical address.
+ */
+static VBOXSTRICTRC iemMemPageTranslateAndCheckAccess(PIEMCPU pIemCpu, RTGCPTR GCPtrMem, uint32_t fAccess,
+ PRTGCPHYS pGCPhysMem)
+{
+ /** @todo Need a different PGM interface here. We're currently using
+ * generic / REM interfaces. this won't cut it for R0 & RC. */
+ RTGCPHYS GCPhys;
+ uint64_t fFlags;
+ int rc = PGMGstGetPage(IEMCPU_TO_VMCPU(pIemCpu), GCPtrMem, &fFlags, &GCPhys);
+ if (RT_FAILURE(rc))
+ {
+ /** @todo Check unassigned memory in unpaged mode. */
+ *pGCPhysMem = NIL_RTGCPHYS;
+ return iemRaisePageFault(pIemCpu, GCPtrMem, fAccess, rc);
+ }
+
+ if ( (fFlags & (X86_PTE_RW | X86_PTE_US | X86_PTE_PAE_NX)) != (X86_PTE_RW | X86_PTE_US)
+ && ( ( (fAccess & IEM_ACCESS_TYPE_WRITE) /* Write to read only memory? */
+ && !(fFlags & X86_PTE_RW)
+ && ( pIemCpu->uCpl != 0
+ || (pIemCpu->CTX_SUFF(pCtx)->cr0 & X86_CR0_WP)) )
+ || ( !(fFlags & X86_PTE_US) /* Kernel memory */
+ && pIemCpu->uCpl == 3)
+ || ( (fAccess & IEM_ACCESS_TYPE_EXEC) /* Executing non-executable memory? */
+ && (fFlags & X86_PTE_PAE_NX)
+ && (pIemCpu->CTX_SUFF(pCtx)->msrEFER & MSR_K6_EFER_NXE) )
+ )
+ )
+ {
+ *pGCPhysMem = NIL_RTGCPHYS;
+ return iemRaisePageFault(pIemCpu, GCPtrMem, fAccess, VERR_ACCESS_DENIED);
+ }
+
+ GCPhys |= GCPtrMem & PAGE_OFFSET_MASK;
+ *pGCPhysMem = GCPhys;
+ return VINF_SUCCESS;
+}
+
+
+
+/**
+ * Maps a physical page.
+ *
+ * @returns VBox status code (see PGMR3PhysTlbGCPhys2Ptr).
+ * @param pIemCpu The IEM per CPU data.
+ * @param GCPhysMem The physical address.
+ * @param fAccess The intended access.
+ * @param ppvMem Where to return the mapping address.
+ */
+static int iemMemPageMap(PIEMCPU pIemCpu, RTGCPHYS GCPhysMem, uint32_t fAccess, void **ppvMem)
+{
+#ifdef IEM_VERIFICATION_MODE
+ /* Force the alternative path so we can ignore writes. */
+ if ((fAccess & IEM_ACCESS_TYPE_WRITE) && !pIemCpu->fNoRem)
+ return VERR_PGM_PHYS_TLB_CATCH_ALL;
+#endif
+
+ /*
+ * If we can map the page without trouble, do a block processing
+ * until the end of the current page.
+ */
+ /** @todo need some better API. */
+ return PGMR3PhysTlbGCPhys2Ptr(IEMCPU_TO_VM(pIemCpu),
+ GCPhysMem,
+ RT_BOOL(fAccess & IEM_ACCESS_TYPE_WRITE),
+ ppvMem);
+}
+
+
+/**
+ * Looks up a memory mapping entry.
+ *
+ * @returns The mapping index (positive) or VERR_NOT_FOUND (negative).
+ * @param pIemCpu The IEM per CPU data.
+ * @param pvMem The memory address.
+ * @param fAccess The access to.
+ */
+DECLINLINE(int) iemMapLookup(PIEMCPU pIemCpu, void *pvMem, uint32_t fAccess)
+{
+ fAccess &= IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_MASK;
+ if ( pIemCpu->aMemMappings[0].pv == pvMem
+ && (pIemCpu->aMemMappings[0].fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_MASK)) == fAccess)
+ return 0;
+ if ( pIemCpu->aMemMappings[1].pv == pvMem
+ && (pIemCpu->aMemMappings[1].fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_MASK)) == fAccess)
+ return 1;
+ if ( pIemCpu->aMemMappings[2].pv == pvMem
+ && (pIemCpu->aMemMappings[2].fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_MASK)) == fAccess)
+ return 2;
+ return VERR_NOT_FOUND;
+}
+
+
+/**
+ * Finds a free memmap entry when using iNextMapping doesn't work.
+ *
+ * @returns Memory mapping index, 1024 on failure.
+ * @param pIemCpu The IEM per CPU data.
+ */
+static unsigned iemMemMapFindFree(PIEMCPU pIemCpu)
+{
+ /*
+ * The easy case.
+ */
+ if (pIemCpu->cActiveMappings == 0)
+ {
+ pIemCpu->iNextMapping = 1;
+ return 0;
+ }
+
+ /* There should be enough mappings for all instructions. */
+ AssertReturn(pIemCpu->cActiveMappings < RT_ELEMENTS(pIemCpu->aMemMappings), 1024);
+
+ for (unsigned i = 0; i < RT_ELEMENTS(pIemCpu->aMemMappings); i++)
+ if (pIemCpu->aMemMappings[i].fAccess == IEM_ACCESS_INVALID)
+ return i;
+
+ AssertFailedReturn(1024);
+}
+
+
+/**
+ * Commits a bounce buffer that needs writing back and unmaps it.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param iMemMap The index of the buffer to commit.
+ */
+static VBOXSTRICTRC iemMemBounceBufferCommitAndUnmap(PIEMCPU pIemCpu, unsigned iMemMap)
+{
+ Assert(pIemCpu->aMemMappings[iMemMap].fAccess & IEM_ACCESS_BOUNCE_BUFFERED);
+ Assert(pIemCpu->aMemMappings[iMemMap].fAccess & IEM_ACCESS_TYPE_WRITE);
+
+ /*
+ * Do the writing.
+ */
+ int rc;
+ if ( !pIemCpu->aMemBbMappings[iMemMap].fUnassigned
+ && !IEM_VERIFICATION_ENABLED(pIemCpu))
+ {
+ uint16_t const cbFirst = pIemCpu->aMemBbMappings[iMemMap].cbFirst;
+ uint16_t const cbSecond = pIemCpu->aMemBbMappings[iMemMap].cbSecond;
+ uint8_t const *pbBuf = &pIemCpu->aBounceBuffers[iMemMap].ab[0];
+ if (!pIemCpu->fByPassHandlers)
+ {
+ rc = PGMPhysWrite(IEMCPU_TO_VM(pIemCpu),
+ pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst,
+ pbBuf,
+ cbFirst);
+ if (cbSecond && rc == VINF_SUCCESS)
+ rc = PGMPhysWrite(IEMCPU_TO_VM(pIemCpu),
+ pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond,
+ pbBuf + cbFirst,
+ cbSecond);
+ }
+ else
+ {
+ rc = PGMPhysSimpleWriteGCPhys(IEMCPU_TO_VM(pIemCpu),
+ pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst,
+ pbBuf,
+ cbFirst);
+ if (cbSecond && rc == VINF_SUCCESS)
+ rc = PGMPhysSimpleWriteGCPhys(IEMCPU_TO_VM(pIemCpu),
+ pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond,
+ pbBuf + cbFirst,
+ cbSecond);
+ }
+ }
+ else
+ rc = VINF_SUCCESS;
+
+#ifdef IEM_VERIFICATION_MODE
+ /*
+ * Record the write(s).
+ */
+ if (!pIemCpu->fNoRem)
+ {
+ PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
+ if (pEvtRec)
+ {
+ pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_WRITE;
+ pEvtRec->u.RamWrite.GCPhys = pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst;
+ pEvtRec->u.RamWrite.cb = pIemCpu->aMemBbMappings[iMemMap].cbFirst;
+ memcpy(pEvtRec->u.RamWrite.ab, &pIemCpu->aBounceBuffers[iMemMap].ab[0], pIemCpu->aMemBbMappings[iMemMap].cbFirst);
+ pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
+ *pIemCpu->ppIemEvtRecNext = pEvtRec;
+ }
+ if (pIemCpu->aMemBbMappings[iMemMap].cbSecond)
+ {
+ pEvtRec = iemVerifyAllocRecord(pIemCpu);
+ if (pEvtRec)
+ {
+ pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_WRITE;
+ pEvtRec->u.RamWrite.GCPhys = pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond;
+ pEvtRec->u.RamWrite.cb = pIemCpu->aMemBbMappings[iMemMap].cbSecond;
+ memcpy(pEvtRec->u.RamWrite.ab,
+ &pIemCpu->aBounceBuffers[iMemMap].ab[pIemCpu->aMemBbMappings[iMemMap].cbFirst],
+ pIemCpu->aMemBbMappings[iMemMap].cbSecond);
+ pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
+ *pIemCpu->ppIemEvtRecNext = pEvtRec;
+ }
+ }
+ }
+#endif
+
+ /*
+ * Free the mapping entry.
+ */
+ pIemCpu->aMemMappings[iMemMap].fAccess = IEM_ACCESS_INVALID;
+ Assert(pIemCpu->cActiveMappings != 0);
+ pIemCpu->cActiveMappings--;
+ return rc;
+}
+
+
+/**
+ * iemMemMap worker that deals with a request crossing pages.
+ */
+static VBOXSTRICTRC iemMemBounceBufferMapCrossPage(PIEMCPU pIemCpu, int iMemMap, void **ppvMem,
+ size_t cbMem, RTGCPTR GCPtrFirst, uint32_t fAccess)
+{
+ /*
+ * Do the address translations.
+ */
+ RTGCPHYS GCPhysFirst;
+ VBOXSTRICTRC rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, GCPtrFirst, fAccess, &GCPhysFirst);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ RTGCPHYS GCPhysSecond;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, GCPtrFirst + (cbMem - 1), fAccess, &GCPhysSecond);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ GCPhysSecond &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
+
+ /*
+ * Read in the current memory content if it's a read of execute access.
+ */
+ uint8_t *pbBuf = &pIemCpu->aBounceBuffers[iMemMap].ab[0];
+ uint32_t const cbFirstPage = PAGE_SIZE - (GCPhysFirst & PAGE_OFFSET_MASK);
+ uint32_t const cbSecondPage = (uint32_t)(cbMem - cbFirstPage);
+
+ if (fAccess & (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_EXEC))
+ {
+ int rc;
+ if (!pIemCpu->fByPassHandlers)
+ {
+ rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhysFirst, pbBuf, cbFirstPage);
+ if (rc != VINF_SUCCESS)
+ return rc;
+ rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhysSecond, pbBuf + cbFirstPage, cbSecondPage);
+ if (rc != VINF_SUCCESS)
+ return rc;
+ }
+ else
+ {
+ rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), pbBuf, GCPhysFirst, cbFirstPage);
+ if (rc != VINF_SUCCESS)
+ return rc;
+ rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), pbBuf + cbFirstPage, GCPhysSecond, cbSecondPage);
+ if (rc != VINF_SUCCESS)
+ return rc;
+ }
+
+#ifdef IEM_VERIFICATION_MODE
+ if (!pIemCpu->fNoRem)
+ {
+ /*
+ * Record the reads.
+ */
+ PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
+ if (pEvtRec)
+ {
+ pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
+ pEvtRec->u.RamRead.GCPhys = GCPhysFirst;
+ pEvtRec->u.RamRead.cb = cbFirstPage;
+ pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
+ *pIemCpu->ppIemEvtRecNext = pEvtRec;
+ }
+ pEvtRec = iemVerifyAllocRecord(pIemCpu);
+ if (pEvtRec)
+ {
+ pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
+ pEvtRec->u.RamRead.GCPhys = GCPhysSecond;
+ pEvtRec->u.RamRead.cb = cbSecondPage;
+ pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
+ *pIemCpu->ppIemEvtRecNext = pEvtRec;
+ }
+ }
+#endif
+ }
+#ifdef VBOX_STRICT
+ else
+ memset(pbBuf, 0xcc, cbMem);
+#endif
+#ifdef VBOX_STRICT
+ if (cbMem < sizeof(pIemCpu->aBounceBuffers[iMemMap].ab))
+ memset(pbBuf + cbMem, 0xaa, sizeof(pIemCpu->aBounceBuffers[iMemMap].ab) - cbMem);
+#endif
+
+ /*
+ * Commit the bounce buffer entry.
+ */
+ pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst = GCPhysFirst;
+ pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond = GCPhysSecond;
+ pIemCpu->aMemBbMappings[iMemMap].cbFirst = (uint16_t)cbFirstPage;
+ pIemCpu->aMemBbMappings[iMemMap].cbSecond = (uint16_t)cbSecondPage;
+ pIemCpu->aMemBbMappings[iMemMap].fUnassigned = false;
+ pIemCpu->aMemMappings[iMemMap].pv = pbBuf;
+ pIemCpu->aMemMappings[iMemMap].fAccess = fAccess | IEM_ACCESS_BOUNCE_BUFFERED;
+ pIemCpu->cActiveMappings++;
+
+ *ppvMem = pbBuf;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * iemMemMap woker that deals with iemMemPageMap failures.
+ */
+static VBOXSTRICTRC iemMemBounceBufferMapPhys(PIEMCPU pIemCpu, unsigned iMemMap, void **ppvMem, size_t cbMem,
+ RTGCPHYS GCPhysFirst, uint32_t fAccess, VBOXSTRICTRC rcMap)
+{
+ /*
+ * Filter out conditions we can handle and the ones which shouldn't happen.
+ */
+ if ( rcMap != VINF_PGM_PHYS_TLB_CATCH_WRITE
+ && rcMap != VERR_PGM_PHYS_TLB_CATCH_ALL
+ && rcMap != VERR_PGM_PHYS_TLB_UNASSIGNED)
+ {
+ AssertReturn(RT_FAILURE_NP(rcMap), VERR_INTERNAL_ERROR_3);
+ return rcMap;
+ }
+ pIemCpu->cPotentialExits++;
+
+ /*
+ * Read in the current memory content if it's a read of execute access.
+ */
+ uint8_t *pbBuf = &pIemCpu->aBounceBuffers[iMemMap].ab[0];
+ if (fAccess & (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_EXEC))
+ {
+ if (rcMap == VERR_PGM_PHYS_TLB_UNASSIGNED)
+ memset(pbBuf, 0xff, cbMem);
+ else
+ {
+ int rc;
+ if (!pIemCpu->fByPassHandlers)
+ rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhysFirst, pbBuf, cbMem);
+ else
+ rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), pbBuf, GCPhysFirst, cbMem);
+ if (rc != VINF_SUCCESS)
+ return rc;
+ }
+
+#ifdef IEM_VERIFICATION_MODE
+ if (!pIemCpu->fNoRem)
+ {
+ /*
+ * Record the read.
+ */
+ PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
+ if (pEvtRec)
+ {
+ pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
+ pEvtRec->u.RamRead.GCPhys = GCPhysFirst;
+ pEvtRec->u.RamRead.cb = (uint32_t)cbMem;
+ pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
+ *pIemCpu->ppIemEvtRecNext = pEvtRec;
+ }
+ }
+#endif
+ }
+#ifdef VBOX_STRICT
+ else
+ memset(pbBuf, 0xcc, cbMem);
+#endif
+#ifdef VBOX_STRICT
+ if (cbMem < sizeof(pIemCpu->aBounceBuffers[iMemMap].ab))
+ memset(pbBuf + cbMem, 0xaa, sizeof(pIemCpu->aBounceBuffers[iMemMap].ab) - cbMem);
+#endif
+
+ /*
+ * Commit the bounce buffer entry.
+ */
+ pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst = GCPhysFirst;
+ pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond = NIL_RTGCPHYS;
+ pIemCpu->aMemBbMappings[iMemMap].cbFirst = (uint16_t)cbMem;
+ pIemCpu->aMemBbMappings[iMemMap].cbSecond = 0;
+ pIemCpu->aMemBbMappings[iMemMap].fUnassigned = rcMap == VERR_PGM_PHYS_TLB_UNASSIGNED;
+ pIemCpu->aMemMappings[iMemMap].pv = pbBuf;
+ pIemCpu->aMemMappings[iMemMap].fAccess = fAccess | IEM_ACCESS_BOUNCE_BUFFERED;
+ pIemCpu->cActiveMappings++;
+
+ *ppvMem = pbBuf;
+ return VINF_SUCCESS;
+}
+
+
+
+/**
+ * Maps the specified guest memory for the given kind of access.
+ *
+ * This may be using bounce buffering of the memory if it's crossing a page
+ * boundary or if there is an access handler installed for any of it. Because
+ * of lock prefix guarantees, we're in for some extra clutter when this
+ * happens.
+ *
+ * This may raise a \#GP, \#SS, \#PF or \#AC.
+ *
+ * @returns VBox strict status code.
+ *
+ * @param pIemCpu The IEM per CPU data.
+ * @param ppvMem Where to return the pointer to the mapped
+ * memory.
+ * @param cbMem The number of bytes to map. This is usually 1,
+ * 2, 4, 6, 8, 12, 16 or 32. When used by string
+ * operations it can be up to a page.
+ * @param iSegReg The index of the segment register to use for
+ * this access. The base and limits are checked.
+ * Use UINT8_MAX to indicate that no segmentation
+ * is required (for IDT, GDT and LDT accesses).
+ * @param GCPtrMem The address of the guest memory.
+ * @param a_fAccess How the memory is being accessed. The
+ * IEM_ACCESS_TYPE_XXX bit is used to figure out
+ * how to map the memory, while the
+ * IEM_ACCESS_WHAT_XXX bit is used when raising
+ * exceptions.
+ */
+static VBOXSTRICTRC iemMemMap(PIEMCPU pIemCpu, void **ppvMem, size_t cbMem, uint8_t iSegReg, RTGCPTR GCPtrMem, uint32_t fAccess)
+{
+ /*
+ * Check the input and figure out which mapping entry to use.
+ */
+ Assert(cbMem <= 32);
+ Assert(~(fAccess & ~(IEM_ACCESS_TYPE_MASK | IEM_ACCESS_WHAT_MASK)));
+
+ unsigned iMemMap = pIemCpu->iNextMapping;
+ if (iMemMap >= RT_ELEMENTS(pIemCpu->aMemMappings))
+ {
+ iMemMap = iemMemMapFindFree(pIemCpu);
+ AssertReturn(iMemMap < RT_ELEMENTS(pIemCpu->aMemMappings), VERR_INTERNAL_ERROR_3);
+ }
+
+ /*
+ * Map the memory, checking that we can actually access it. If something
+ * slightly complicated happens, fall back on bounce buffering.
+ */
+ VBOXSTRICTRC rcStrict = iemMemApplySegment(pIemCpu, fAccess, iSegReg, cbMem, &GCPtrMem);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ if ((GCPtrMem & PAGE_OFFSET_MASK) + cbMem > PAGE_SIZE) /* Crossing a page boundary? */
+ return iemMemBounceBufferMapCrossPage(pIemCpu, iMemMap, ppvMem, cbMem, GCPtrMem, fAccess);
+
+ RTGCPHYS GCPhysFirst;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, GCPtrMem, fAccess, &GCPhysFirst);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ void *pvMem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysFirst, fAccess, &pvMem);
+ if (rcStrict != VINF_SUCCESS)
+ return iemMemBounceBufferMapPhys(pIemCpu, iMemMap, ppvMem, cbMem, GCPhysFirst, fAccess, rcStrict);
+
+ /*
+ * Fill in the mapping table entry.
+ */
+ pIemCpu->aMemMappings[iMemMap].pv = pvMem;
+ pIemCpu->aMemMappings[iMemMap].fAccess = fAccess;
+ pIemCpu->iNextMapping = iMemMap + 1;
+ pIemCpu->cActiveMappings++;
+
+ *ppvMem = pvMem;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Commits the guest memory if bounce buffered and unmaps it.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pvMem The mapping.
+ * @param fAccess The kind of access.
+ */
+static VBOXSTRICTRC iemMemCommitAndUnmap(PIEMCPU pIemCpu, void *pvMem, uint32_t fAccess)
+{
+ int iMemMap = iemMapLookup(pIemCpu, pvMem, fAccess);
+ AssertReturn(iMemMap >= 0, iMemMap);
+
+ /*
+ * If it's bounce buffered, we need to write back the buffer.
+ */
+ if ( (pIemCpu->aMemMappings[iMemMap].fAccess & (IEM_ACCESS_BOUNCE_BUFFERED | IEM_ACCESS_TYPE_WRITE))
+ == (IEM_ACCESS_BOUNCE_BUFFERED | IEM_ACCESS_TYPE_WRITE))
+ return iemMemBounceBufferCommitAndUnmap(pIemCpu, iMemMap);
+
+ /* Free the entry. */
+ pIemCpu->aMemMappings[iMemMap].fAccess = IEM_ACCESS_INVALID;
+ Assert(pIemCpu->cActiveMappings != 0);
+ pIemCpu->cActiveMappings--;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Fetches a data byte.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pu8Dst Where to return the byte.
+ * @param iSegReg The index of the segment register to use for
+ * this access. The base and limits are checked.
+ * @param GCPtrMem The address of the guest memory.
+ */
+static VBOXSTRICTRC iemMemFetchDataU8(PIEMCPU pIemCpu, uint8_t *pu8Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
+{
+ /* The lazy approach for now... */
+ uint8_t const *pu8Src;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu8Src, sizeof(*pu8Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu8Dst = *pu8Src;
+ rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu8Src, IEM_ACCESS_DATA_R);
+ }
+ return rc;
+}
+
+
+/**
+ * Fetches a data word.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pu16Dst Where to return the word.
+ * @param iSegReg The index of the segment register to use for
+ * this access. The base and limits are checked.
+ * @param GCPtrMem The address of the guest memory.
+ */
+static VBOXSTRICTRC iemMemFetchDataU16(PIEMCPU pIemCpu, uint16_t *pu16Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
+{
+ /* The lazy approach for now... */
+ uint16_t const *pu16Src;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Src, sizeof(*pu16Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu16Dst = *pu16Src;
+ rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu16Src, IEM_ACCESS_DATA_R);
+ }
+ return rc;
+}
+
+
+/**
+ * Fetches a data dword.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pu32Dst Where to return the dword.
+ * @param iSegReg The index of the segment register to use for
+ * this access. The base and limits are checked.
+ * @param GCPtrMem The address of the guest memory.
+ */
+static VBOXSTRICTRC iemMemFetchDataU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
+{
+ /* The lazy approach for now... */
+ uint32_t const *pu32Src;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Src, sizeof(*pu32Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu32Dst = *pu32Src;
+ rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu32Src, IEM_ACCESS_DATA_R);
+ }
+ return rc;
+}
+
+
+/**
+ * Fetches a data dword and sign extends it to a qword.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pu64Dst Where to return the sign extended value.
+ * @param iSegReg The index of the segment register to use for
+ * this access. The base and limits are checked.
+ * @param GCPtrMem The address of the guest memory.
+ */
+static VBOXSTRICTRC iemMemFetchDataS32SxU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
+{
+ /* The lazy approach for now... */
+ int32_t const *pi32Src;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pi32Src, sizeof(*pi32Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu64Dst = *pi32Src;
+ rc = iemMemCommitAndUnmap(pIemCpu, (void *)pi32Src, IEM_ACCESS_DATA_R);
+ }
+#ifdef __GNUC__ /* warning: GCC may be a royal pain */
+ else
+ *pu64Dst = 0;
+#endif
+ return rc;
+}
+
+
+/**
+ * Fetches a data qword.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pu64Dst Where to return the qword.
+ * @param iSegReg The index of the segment register to use for
+ * this access. The base and limits are checked.
+ * @param GCPtrMem The address of the guest memory.
+ */
+static VBOXSTRICTRC iemMemFetchDataU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
+{
+ /* The lazy approach for now... */
+ uint64_t const *pu64Src;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Src, sizeof(*pu64Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu64Dst = *pu64Src;
+ rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu64Src, IEM_ACCESS_DATA_R);
+ }
+ return rc;
+}
+
+
+/**
+ * Fetches a descriptor register (lgdt, lidt).
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pcbLimit Where to return the limit.
+ * @param pGCPTrBase Where to return the base.
+ * @param iSegReg The index of the segment register to use for
+ * this access. The base and limits are checked.
+ * @param GCPtrMem The address of the guest memory.
+ * @param enmOpSize The effective operand size.
+ */
+static VBOXSTRICTRC iemMemFetchDataXdtr(PIEMCPU pIemCpu, uint16_t *pcbLimit, PRTGCPTR pGCPtrBase,
+ uint8_t iSegReg, RTGCPTR GCPtrMem, IEMMODE enmOpSize)
+{
+ uint8_t const *pu8Src;
+ VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu,
+ (void **)&pu8Src,
+ enmOpSize == IEMMODE_64BIT
+ ? 2 + 8
+ : enmOpSize == IEMMODE_32BIT
+ ? 2 + 4
+ : 2 + 3,
+ iSegReg,
+ GCPtrMem,
+ IEM_ACCESS_DATA_R);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ *pcbLimit = RT_MAKE_U16(pu8Src[0], pu8Src[1]);
+ switch (enmOpSize)
+ {
+ case IEMMODE_16BIT:
+ *pGCPtrBase = RT_MAKE_U32_FROM_U8(pu8Src[2], pu8Src[3], pu8Src[4], 0);
+ break;
+ case IEMMODE_32BIT:
+ *pGCPtrBase = RT_MAKE_U32_FROM_U8(pu8Src[2], pu8Src[3], pu8Src[4], pu8Src[5]);
+ break;
+ case IEMMODE_64BIT:
+ *pGCPtrBase = RT_MAKE_U64_FROM_U8(pu8Src[2], pu8Src[3], pu8Src[4], pu8Src[5],
+ pu8Src[6], pu8Src[7], pu8Src[8], pu8Src[9]);
+ break;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)pu8Src, IEM_ACCESS_DATA_R);
+ }
+ return rcStrict;
+}
+
+
+
+/**
+ * Stores a data byte.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param iSegReg The index of the segment register to use for
+ * this access. The base and limits are checked.
+ * @param GCPtrMem The address of the guest memory.
+ * @param u8Value The value to store.
+ */
+static VBOXSTRICTRC iemMemStoreDataU8(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint8_t u8Value)
+{
+ /* The lazy approach for now... */
+ uint8_t *pu8Dst;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu8Dst, sizeof(*pu8Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu8Dst = u8Value;
+ rc = iemMemCommitAndUnmap(pIemCpu, pu8Dst, IEM_ACCESS_DATA_W);
+ }
+ return rc;
+}
+
+
+/**
+ * Stores a data word.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param iSegReg The index of the segment register to use for
+ * this access. The base and limits are checked.
+ * @param GCPtrMem The address of the guest memory.
+ * @param u16Value The value to store.
+ */
+static VBOXSTRICTRC iemMemStoreDataU16(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint16_t u16Value)
+{
+ /* The lazy approach for now... */
+ uint16_t *pu16Dst;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Dst, sizeof(*pu16Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu16Dst = u16Value;
+ rc = iemMemCommitAndUnmap(pIemCpu, pu16Dst, IEM_ACCESS_DATA_W);
+ }
+ return rc;
+}
+
+
+/**
+ * Stores a data dword.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param iSegReg The index of the segment register to use for
+ * this access. The base and limits are checked.
+ * @param GCPtrMem The address of the guest memory.
+ * @param u32Value The value to store.
+ */
+static VBOXSTRICTRC iemMemStoreDataU32(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint32_t u32Value)
+{
+ /* The lazy approach for now... */
+ uint32_t *pu32Dst;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Dst, sizeof(*pu32Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu32Dst = u32Value;
+ rc = iemMemCommitAndUnmap(pIemCpu, pu32Dst, IEM_ACCESS_DATA_W);
+ }
+ return rc;
+}
+
+
+/**
+ * Stores a data qword.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param iSegReg The index of the segment register to use for
+ * this access. The base and limits are checked.
+ * @param GCPtrMem The address of the guest memory.
+ * @param u64Value The value to store.
+ */
+static VBOXSTRICTRC iemMemStoreDataU64(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint64_t u64Value)
+{
+ /* The lazy approach for now... */
+ uint64_t *pu64Dst;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Dst, sizeof(*pu64Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu64Dst = u64Value;
+ rc = iemMemCommitAndUnmap(pIemCpu, pu64Dst, IEM_ACCESS_DATA_W);
+ }
+ return rc;
+}
+
+
+/**
+ * Pushes a word onto the stack.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param u16Value The value to push.
+ */
+static VBOXSTRICTRC iemMemStackPushU16(PIEMCPU pIemCpu, uint16_t u16Value)
+{
+ /* Increment the stack pointer. */
+ uint64_t uNewRsp;
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTGCPTR GCPtrTop = iemRegGetRspForPush(pCtx, 2, &uNewRsp);
+
+ /* Write the word the lazy way. */
+ uint16_t *pu16Dst;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Dst, sizeof(*pu16Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu16Dst = u16Value;
+ rc = iemMemCommitAndUnmap(pIemCpu, pu16Dst, IEM_ACCESS_STACK_W);
+ }
+
+ /* Commit the new RSP value unless we an access handler made trouble. */
+ if (rc == VINF_SUCCESS)
+ pCtx->rsp = uNewRsp;
+
+ return rc;
+}
+
+
+/**
+ * Pushes a dword onto the stack.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param u32Value The value to push.
+ */
+static VBOXSTRICTRC iemMemStackPushU32(PIEMCPU pIemCpu, uint32_t u32Value)
+{
+ /* Increment the stack pointer. */
+ uint64_t uNewRsp;
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTGCPTR GCPtrTop = iemRegGetRspForPush(pCtx, 4, &uNewRsp);
+
+ /* Write the word the lazy way. */
+ uint32_t *pu32Dst;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Dst, sizeof(*pu32Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu32Dst = u32Value;
+ rc = iemMemCommitAndUnmap(pIemCpu, pu32Dst, IEM_ACCESS_STACK_W);
+ }
+
+ /* Commit the new RSP value unless we an access handler made trouble. */
+ if (rc == VINF_SUCCESS)
+ pCtx->rsp = uNewRsp;
+
+ return rc;
+}
+
+
+/**
+ * Pushes a qword onto the stack.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param u64Value The value to push.
+ */
+static VBOXSTRICTRC iemMemStackPushU64(PIEMCPU pIemCpu, uint64_t u64Value)
+{
+ /* Increment the stack pointer. */
+ uint64_t uNewRsp;
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTGCPTR GCPtrTop = iemRegGetRspForPush(pCtx, 8, &uNewRsp);
+
+ /* Write the word the lazy way. */
+ uint64_t *pu64Dst;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Dst, sizeof(*pu64Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu64Dst = u64Value;
+ rc = iemMemCommitAndUnmap(pIemCpu, pu64Dst, IEM_ACCESS_STACK_W);
+ }
+
+ /* Commit the new RSP value unless we an access handler made trouble. */
+ if (rc == VINF_SUCCESS)
+ pCtx->rsp = uNewRsp;
+
+ return rc;
+}
+
+
+/**
+ * Pops a word from the stack.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pu16Value Where to store the popped value.
+ */
+static VBOXSTRICTRC iemMemStackPopU16(PIEMCPU pIemCpu, uint16_t *pu16Value)
+{
+ /* Increment the stack pointer. */
+ uint64_t uNewRsp;
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTGCPTR GCPtrTop = iemRegGetRspForPop(pCtx, 2, &uNewRsp);
+
+ /* Write the word the lazy way. */
+ uint16_t const *pu16Src;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Src, sizeof(*pu16Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu16Value = *pu16Src;
+ rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu16Src, IEM_ACCESS_STACK_R);
+
+ /* Commit the new RSP value. */
+ if (rc == VINF_SUCCESS)
+ pCtx->rsp = uNewRsp;
+ }
+
+ return rc;
+}
+
+
+/**
+ * Pops a dword from the stack.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pu32Value Where to store the popped value.
+ */
+static VBOXSTRICTRC iemMemStackPopU32(PIEMCPU pIemCpu, uint32_t *pu32Value)
+{
+ /* Increment the stack pointer. */
+ uint64_t uNewRsp;
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTGCPTR GCPtrTop = iemRegGetRspForPop(pCtx, 4, &uNewRsp);
+
+ /* Write the word the lazy way. */
+ uint32_t const *pu32Src;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Src, sizeof(*pu32Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu32Value = *pu32Src;
+ rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu32Src, IEM_ACCESS_STACK_R);
+
+ /* Commit the new RSP value. */
+ if (rc == VINF_SUCCESS)
+ pCtx->rsp = uNewRsp;
+ }
+
+ return rc;
+}
+
+
+/**
+ * Pops a qword from the stack.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pu64Value Where to store the popped value.
+ */
+static VBOXSTRICTRC iemMemStackPopU64(PIEMCPU pIemCpu, uint64_t *pu64Value)
+{
+ /* Increment the stack pointer. */
+ uint64_t uNewRsp;
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTGCPTR GCPtrTop = iemRegGetRspForPop(pCtx, 8, &uNewRsp);
+
+ /* Write the word the lazy way. */
+ uint64_t const *pu64Src;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Src, sizeof(*pu64Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu64Value = *pu64Src;
+ rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu64Src, IEM_ACCESS_STACK_R);
+
+ /* Commit the new RSP value. */
+ if (rc == VINF_SUCCESS)
+ pCtx->rsp = uNewRsp;
+ }
+
+ return rc;
+}
+
+
+/**
+ * Pushes a word onto the stack, using a temporary stack pointer.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param u16Value The value to push.
+ * @param pTmpRsp Pointer to the temporary stack pointer.
+ */
+static VBOXSTRICTRC iemMemStackPushU16Ex(PIEMCPU pIemCpu, uint16_t u16Value, PRTUINT64U pTmpRsp)
+{
+ /* Increment the stack pointer. */
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTUINT64U NewRsp = *pTmpRsp;
+ RTGCPTR GCPtrTop = iemRegGetRspForPushEx(&NewRsp, 2, pCtx);
+
+ /* Write the word the lazy way. */
+ uint16_t *pu16Dst;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Dst, sizeof(*pu16Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu16Dst = u16Value;
+ rc = iemMemCommitAndUnmap(pIemCpu, pu16Dst, IEM_ACCESS_STACK_W);
+ }
+
+ /* Commit the new RSP value unless we an access handler made trouble. */
+ if (rc == VINF_SUCCESS)
+ *pTmpRsp = NewRsp;
+
+ return rc;
+}
+
+
+/**
+ * Pushes a dword onto the stack, using a temporary stack pointer.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param u32Value The value to push.
+ * @param pTmpRsp Pointer to the temporary stack pointer.
+ */
+static VBOXSTRICTRC iemMemStackPushU32Ex(PIEMCPU pIemCpu, uint32_t u32Value, PRTUINT64U pTmpRsp)
+{
+ /* Increment the stack pointer. */
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTUINT64U NewRsp = *pTmpRsp;
+ RTGCPTR GCPtrTop = iemRegGetRspForPushEx(&NewRsp, 4, pCtx);
+
+ /* Write the word the lazy way. */
+ uint32_t *pu32Dst;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Dst, sizeof(*pu32Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu32Dst = u32Value;
+ rc = iemMemCommitAndUnmap(pIemCpu, pu32Dst, IEM_ACCESS_STACK_W);
+ }
+
+ /* Commit the new RSP value unless we an access handler made trouble. */
+ if (rc == VINF_SUCCESS)
+ *pTmpRsp = NewRsp;
+
+ return rc;
+}
+
+
+/**
+ * Pushes a dword onto the stack, using a temporary stack pointer.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param u64Value The value to push.
+ * @param pTmpRsp Pointer to the temporary stack pointer.
+ */
+static VBOXSTRICTRC iemMemStackPushU64Ex(PIEMCPU pIemCpu, uint64_t u64Value, PRTUINT64U pTmpRsp)
+{
+ /* Increment the stack pointer. */
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTUINT64U NewRsp = *pTmpRsp;
+ RTGCPTR GCPtrTop = iemRegGetRspForPushEx(&NewRsp, 8, pCtx);
+
+ /* Write the word the lazy way. */
+ uint64_t *pu64Dst;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Dst, sizeof(*pu64Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu64Dst = u64Value;
+ rc = iemMemCommitAndUnmap(pIemCpu, pu64Dst, IEM_ACCESS_STACK_W);
+ }
+
+ /* Commit the new RSP value unless we an access handler made trouble. */
+ if (rc == VINF_SUCCESS)
+ *pTmpRsp = NewRsp;
+
+ return rc;
+}
+
+
+/**
+ * Pops a word from the stack, using a temporary stack pointer.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pu16Value Where to store the popped value.
+ * @param pTmpRsp Pointer to the temporary stack pointer.
+ */
+static VBOXSTRICTRC iemMemStackPopU16Ex(PIEMCPU pIemCpu, uint16_t *pu16Value, PRTUINT64U pTmpRsp)
+{
+ /* Increment the stack pointer. */
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTUINT64U NewRsp = *pTmpRsp;
+ RTGCPTR GCPtrTop = iemRegGetRspForPopEx(&NewRsp, 2, pCtx);
+
+ /* Write the word the lazy way. */
+ uint16_t const *pu16Src;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Src, sizeof(*pu16Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu16Value = *pu16Src;
+ rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu16Src, IEM_ACCESS_STACK_R);
+
+ /* Commit the new RSP value. */
+ if (rc == VINF_SUCCESS)
+ *pTmpRsp = NewRsp;
+ }
+
+ return rc;
+}
+
+
+/**
+ * Pops a dword from the stack, using a temporary stack pointer.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pu32Value Where to store the popped value.
+ * @param pTmpRsp Pointer to the temporary stack pointer.
+ */
+static VBOXSTRICTRC iemMemStackPopU32Ex(PIEMCPU pIemCpu, uint32_t *pu32Value, PRTUINT64U pTmpRsp)
+{
+ /* Increment the stack pointer. */
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTUINT64U NewRsp = *pTmpRsp;
+ RTGCPTR GCPtrTop = iemRegGetRspForPopEx(&NewRsp, 4, pCtx);
+
+ /* Write the word the lazy way. */
+ uint32_t const *pu32Src;
+ VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Src, sizeof(*pu32Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
+ if (rc == VINF_SUCCESS)
+ {
+ *pu32Value = *pu32Src;
+ rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu32Src, IEM_ACCESS_STACK_R);
+
+ /* Commit the new RSP value. */
+ if (rc == VINF_SUCCESS)
+ *pTmpRsp = NewRsp;
+ }
+
+ return rc;
+}
+
+
+/**
+ * Pops a qword from the stack, using a temporary stack pointer.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pu64Value Where to store the popped value.
+ * @param pTmpRsp Pointer to the temporary stack pointer.
+ */
+static VBOXSTRICTRC iemMemStackPopU64Ex(PIEMCPU pIemCpu, uint64_t *pu64Value, PRTUINT64U pTmpRsp)
+{
+ /* Increment the stack pointer. */
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTUINT64U NewRsp = *pTmpRsp;
+ RTGCPTR GCPtrTop = iemRegGetRspForPopEx(&NewRsp, 8, pCtx);
+
+ /* Write the word the lazy way. */
+ uint64_t const *pu64Src;
+ VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, (void **)&pu64Src, sizeof(*pu64Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ *pu64Value = *pu64Src;
+ rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)pu64Src, IEM_ACCESS_STACK_R);
+
+ /* Commit the new RSP value. */
+ if (rcStrict == VINF_SUCCESS)
+ *pTmpRsp = NewRsp;
+ }
+
+ return rcStrict;
+}
+
+
+/**
+ * Begin a special stack push (used by interrupt, exceptions and such).
+ *
+ * This will raise #SS or #PF if appropriate.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param cbMem The number of bytes to push onto the stack.
+ * @param ppvMem Where to return the pointer to the stack memory.
+ * As with the other memory functions this could be
+ * direct access or bounce buffered access, so
+ * don't commit register until the commit call
+ * succeeds.
+ * @param puNewRsp Where to return the new RSP value. This must be
+ * passed unchanged to
+ * iemMemStackPushCommitSpecial().
+ */
+static VBOXSTRICTRC iemMemStackPushBeginSpecial(PIEMCPU pIemCpu, size_t cbMem, void **ppvMem, uint64_t *puNewRsp)
+{
+ Assert(cbMem < UINT8_MAX);
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTGCPTR GCPtrTop = iemRegGetRspForPush(pCtx, (uint8_t)cbMem, puNewRsp);
+ return iemMemMap(pIemCpu, ppvMem, cbMem, X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
+}
+
+
+/**
+ * Commits a special stack push (started by iemMemStackPushBeginSpecial).
+ *
+ * This will update the rSP.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pvMem The pointer returned by
+ * iemMemStackPushBeginSpecial().
+ * @param uNewRsp The new RSP value returned by
+ * iemMemStackPushBeginSpecial().
+ */
+static VBOXSTRICTRC iemMemStackPushCommitSpecial(PIEMCPU pIemCpu, void *pvMem, uint64_t uNewRsp)
+{
+ VBOXSTRICTRC rcStrict = iemMemCommitAndUnmap(pIemCpu, pvMem, IEM_ACCESS_STACK_W);
+ if (rcStrict == VINF_SUCCESS)
+ pIemCpu->CTX_SUFF(pCtx)->rsp = uNewRsp;
+ return rcStrict;
+}
+
+
+/**
+ * Begin a special stack pop (used by iret, retf and such).
+ *
+ * This will raise #SS or #PF if appropriate.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param cbMem The number of bytes to push onto the stack.
+ * @param ppvMem Where to return the pointer to the stack memory.
+ * @param puNewRsp Where to return the new RSP value. This must be
+ * passed unchanged to
+ * iemMemStackPopCommitSpecial().
+ */
+static VBOXSTRICTRC iemMemStackPopBeginSpecial(PIEMCPU pIemCpu, size_t cbMem, void const **ppvMem, uint64_t *puNewRsp)
+{
+ Assert(cbMem < UINT8_MAX);
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTGCPTR GCPtrTop = iemRegGetRspForPop(pCtx, (uint8_t)cbMem, puNewRsp);
+ return iemMemMap(pIemCpu, (void **)ppvMem, cbMem, X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
+}
+
+
+/**
+ * Commits a special stack pop (started by iemMemStackPopBeginSpecial).
+ *
+ * This will update the rSP.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param pvMem The pointer returned by
+ * iemMemStackPopBeginSpecial().
+ * @param uNewRsp The new RSP value returned by
+ * iemMemStackPopBeginSpecial().
+ */
+static VBOXSTRICTRC iemMemStackPopCommitSpecial(PIEMCPU pIemCpu, void const *pvMem, uint64_t uNewRsp)
+{
+ VBOXSTRICTRC rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)pvMem, IEM_ACCESS_STACK_R);
+ if (rcStrict == VINF_SUCCESS)
+ pIemCpu->CTX_SUFF(pCtx)->rsp = uNewRsp;
+ return rcStrict;
+}
+
+
+/**
+ * Fetches a descriptor table entry.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU.
+ * @param pDesc Where to return the descriptor table entry.
+ * @param uSel The selector which table entry to fetch.
+ */
+static VBOXSTRICTRC iemMemFetchSelDesc(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /** @todo did the 286 require all 8 bytes to be accessible? */
+ /*
+ * Get the selector table base and check bounds.
+ */
+ RTGCPTR GCPtrBase;
+ if (uSel & X86_SEL_LDT)
+ {
+ if ( !pCtx->ldtrHid.Attr.n.u1Present
+ || (uSel | 0x7U) > pCtx->ldtrHid.u32Limit )
+ {
+ Log(("iemMemFetchSelDesc: LDT selector %#x is out of bounds (%3x) or ldtr is NP (%#x)\n",
+ uSel, pCtx->ldtrHid.u32Limit, pCtx->ldtr));
+ /** @todo is this the right exception? */
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+
+ Assert(pCtx->ldtrHid.Attr.n.u1Present);
+ GCPtrBase = pCtx->ldtrHid.u64Base;
+ }
+ else
+ {
+ if ((uSel | 0x7U) > pCtx->gdtr.cbGdt)
+ {
+ Log(("iemMemFetchSelDesc: GDT selector %#x is out of bounds (%3x)\n", uSel, pCtx->gdtr.cbGdt));
+ /** @todo is this the right exception? */
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ GCPtrBase = pCtx->gdtr.pGdt;
+ }
+
+ /*
+ * Read the legacy descriptor and maybe the long mode extensions if
+ * required.
+ */
+ VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pIemCpu, &pDesc->Legacy.u, UINT8_MAX, GCPtrBase + (uSel & X86_SEL_MASK));
+ if (rcStrict == VINF_SUCCESS)
+ {
+ if ( !IEM_IS_LONG_MODE(pIemCpu)
+ || pDesc->Legacy.Gen.u1DescType)
+ pDesc->Long.au64[1] = 0;
+ else if ((uint32_t)(uSel & X86_SEL_MASK) + 15 < (uSel & X86_SEL_LDT ? pCtx->ldtrHid.u32Limit : pCtx->gdtr.cbGdt))
+ rcStrict = iemMemFetchDataU64(pIemCpu, &pDesc->Legacy.u, UINT8_MAX, GCPtrBase + (uSel & X86_SEL_MASK));
+ else
+ {
+ Log(("iemMemFetchSelDesc: system selector %#x is out of bounds\n", uSel));
+ /** @todo is this the right exception? */
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ }
+ return rcStrict;
+}
+
+
+/**
+ * Marks the selector descriptor as accessed (only non-system descriptors).
+ *
+ * This function ASSUMES that iemMemFetchSelDesc has be called previously and
+ * will therefore skip the limit checks.
+ *
+ * @returns Strict VBox status code.
+ * @param pIemCpu The IEM per CPU.
+ * @param uSel The selector.
+ */
+static VBOXSTRICTRC iemMemMarkSelDescAccessed(PIEMCPU pIemCpu, uint16_t uSel)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Get the selector table base and calculate the entry address.
+ */
+ RTGCPTR GCPtr = uSel & X86_SEL_LDT
+ ? pCtx->ldtrHid.u64Base
+ : pCtx->gdtr.pGdt;
+ GCPtr += uSel & X86_SEL_MASK;
+
+ /*
+ * ASMAtomicBitSet will assert if the address is misaligned, so do some
+ * ugly stuff to avoid this. This will make sure it's an atomic access
+ * as well more or less remove any question about 8-bit or 32-bit accesss.
+ */
+ VBOXSTRICTRC rcStrict;
+ uint32_t volatile *pu32;
+ if ((GCPtr & 3) == 0)
+ {
+ /* The normal case, map the 32-bit bits around the accessed bit (40). */
+ GCPtr += 2 + 2;
+ rcStrict = iemMemMap(pIemCpu, (void **)&pu32, 4, UINT8_MAX, GCPtr, IEM_ACCESS_DATA_RW);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ ASMAtomicBitSet(pu32, 8); /* X86_SEL_TYPE_ACCESSED is 1, but it is preceeded by u8BaseHigh1. */
+ }
+ else
+ {
+ /* The misaligned GDT/LDT case, map the whole thing. */
+ rcStrict = iemMemMap(pIemCpu, (void **)&pu32, 8, UINT8_MAX, GCPtr, IEM_ACCESS_DATA_RW);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ switch ((uintptr_t)pu32 & 3)
+ {
+ case 0: ASMAtomicBitSet(pu32, 40 + 0 - 0); break;
+ case 1: ASMAtomicBitSet((uint8_t volatile *)pu32 + 3, 40 + 0 - 24); break;
+ case 2: ASMAtomicBitSet((uint8_t volatile *)pu32 + 2, 40 + 0 - 16); break;
+ case 3: ASMAtomicBitSet((uint8_t volatile *)pu32 + 1, 40 + 0 - 8); break;
+ }
+ }
+
+ return iemMemCommitAndUnmap(pIemCpu, (void *)pu32, IEM_ACCESS_DATA_RW);
+}
+
+/** @} */
+
+
+/*
+ * Include the C/C++ implementation of instruction.
+ */
+#include "IEMAllCImpl.cpp.h"
+
+
+
+/** @name "Microcode" macros.
+ *
+ * The idea is that we should be able to use the same code to interpret
+ * instructions as well as recompiler instructions. Thus this obfuscation.
+ *
+ * @{
+ */
+#define IEM_MC_BEGIN(a_cArgs, a_cLocals) {
+#define IEM_MC_END() }
+#define IEM_MC_PAUSE() do {} while (0)
+#define IEM_MC_CONTINUE() do {} while (0)
+
+/** Internal macro. */
+#define IEM_MC_RETURN_ON_FAILURE(a_Expr) \
+ do \
+ { \
+ VBOXSTRICTRC rcStrict2 = a_Expr; \
+ if (rcStrict2 != VINF_SUCCESS) \
+ return rcStrict2; \
+ } while (0)
+
+#define IEM_MC_ADVANCE_RIP() iemRegUpdateRip(pIemCpu)
+#define IEM_MC_REL_JMP_S8(a_i8) IEM_MC_RETURN_ON_FAILURE(iemRegRipRelativeJumpS8(pIemCpu, a_i8))
+#define IEM_MC_REL_JMP_S16(a_i16) IEM_MC_RETURN_ON_FAILURE(iemRegRipRelativeJumpS16(pIemCpu, a_i16))
+#define IEM_MC_REL_JMP_S32(a_i32) IEM_MC_RETURN_ON_FAILURE(iemRegRipRelativeJumpS32(pIemCpu, a_i32))
+#define IEM_MC_SET_RIP_U16(a_u16NewIP) IEM_MC_RETURN_ON_FAILURE(iemRegRipJump((pIemCpu), (a_u16NewIP)))
+#define IEM_MC_SET_RIP_U32(a_u32NewIP) IEM_MC_RETURN_ON_FAILURE(iemRegRipJump((pIemCpu), (a_u32NewIP)))
+#define IEM_MC_SET_RIP_U64(a_u64NewIP) IEM_MC_RETURN_ON_FAILURE(iemRegRipJump((pIemCpu), (a_u64NewIP)))
+
+#define IEM_MC_RAISE_DIVIDE_ERROR() return iemRaiseDivideError(pIemCpu)
+#define IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE() \
+ do { \
+ if ((pIemCpu)->CTX_SUFF(pCtx)->cr0 & (X86_CR0_EM | X86_CR0_TS)) \
+ return iemRaiseDeviceNotAvailable(pIemCpu); \
+ } while (0)
+#define IEM_MC_MAYBE_RAISE_FPU_XCPT() \
+ do { \
+ if (iemFRegFetchFsw(pIemCpu) & X86_FSW_ES) \
+ return iemRaiseMathFault(pIemCpu); \
+ } while (0)
+#define IEM_MC_RAISE_GP0_IF_CPL_NOT_ZERO() \
+ do { \
+ if (pIemCpu->uCpl != 0) \
+ return iemRaiseGeneralProtectionFault0(pIemCpu); \
+ } while (0)
+
+
+#define IEM_MC_LOCAL(a_Type, a_Name) a_Type a_Name
+#define IEM_MC_LOCAL_CONST(a_Type, a_Name, a_Value) a_Type const a_Name = (a_Value)
+#define IEM_MC_REF_LOCAL(a_pRefArg, a_Local) (a_pRefArg) = &(a_Local)
+#define IEM_MC_ARG(a_Type, a_Name, a_iArg) a_Type a_Name
+#define IEM_MC_ARG_CONST(a_Type, a_Name, a_Value, a_iArg) a_Type const a_Name = (a_Value)
+#define IEM_MC_ARG_LOCAL_EFLAGS(a_pName, a_Name, a_iArg) \
+ uint32_t a_Name; \
+ uint32_t *a_pName = &a_Name
+#define IEM_MC_COMMIT_EFLAGS(a_EFlags) \
+ do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u = (a_EFlags); Assert((pIemCpu)->CTX_SUFF(pCtx)->eflags.u & X86_EFL_1); } while (0)
+
+#define IEM_MC_ASSIGN(a_VarOrArg, a_CVariableOrConst) (a_VarOrArg) = (a_CVariableOrConst)
+#define IEM_MC_ASSIGN_TO_SMALLER IEM_MC_ASSIGN
+
+#define IEM_MC_FETCH_GREG_U8(a_u8Dst, a_iGReg) (a_u8Dst) = iemGRegFetchU8(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U8_ZX_U16(a_u16Dst, a_iGReg) (a_u16Dst) = iemGRegFetchU8(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U8_ZX_U32(a_u32Dst, a_iGReg) (a_u32Dst) = iemGRegFetchU8(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U8_ZX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = iemGRegFetchU8(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U8_SX_U16(a_u16Dst, a_iGReg) (a_u16Dst) = (int8_t)iemGRegFetchU8(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U8_SX_U32(a_u32Dst, a_iGReg) (a_u32Dst) = (int8_t)iemGRegFetchU8(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U8_SX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = (int8_t)iemGRegFetchU8(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U16(a_u16Dst, a_iGReg) (a_u16Dst) = iemGRegFetchU16(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U16_ZX_U32(a_u32Dst, a_iGReg) (a_u32Dst) = iemGRegFetchU16(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U16_ZX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = iemGRegFetchU16(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U16_SX_U32(a_u32Dst, a_iGReg) (a_u32Dst) = (int16_t)iemGRegFetchU16(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U16_SX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = (int16_t)iemGRegFetchU16(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U32(a_u32Dst, a_iGReg) (a_u32Dst) = iemGRegFetchU32(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U32_ZX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = iemGRegFetchU32(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U32_SX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = (int32_t)iemGRegFetchU32(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U64(a_u64Dst, a_iGReg) (a_u64Dst) = iemGRegFetchU64(pIemCpu, (a_iGReg))
+#define IEM_MC_FETCH_GREG_U64_ZX_U64 IEM_MC_FETCH_GREG_U64
+#define IEM_MC_FETCH_SREG_U16(a_u16Dst, a_iSReg) (a_u16Dst) = iemSRegFetchU16(pIemCpu, (a_iSReg))
+#define IEM_MC_FETCH_SREG_ZX_U32(a_u32Dst, a_iSReg) (a_u32Dst) = iemSRegFetchU16(pIemCpu, (a_iSReg))
+#define IEM_MC_FETCH_SREG_ZX_U64(a_u64Dst, a_iSReg) (a_u64Dst) = iemSRegFetchU16(pIemCpu, (a_iSReg))
+#define IEM_MC_FETCH_CR0_U16(a_u16Dst) (a_u16Dst) = (uint16_t)(pIemCpu)->CTX_SUFF(pCtx)->cr0
+#define IEM_MC_FETCH_CR0_U32(a_u32Dst) (a_u32Dst) = (uint32_t)(pIemCpu)->CTX_SUFF(pCtx)->cr0
+#define IEM_MC_FETCH_CR0_U64(a_u64Dst) (a_u64Dst) = (pIemCpu)->CTX_SUFF(pCtx)->cr0
+#define IEM_MC_FETCH_EFLAGS(a_EFlags) (a_EFlags) = (pIemCpu)->CTX_SUFF(pCtx)->eflags.u
+#define IEM_MC_FETCH_FSW(a_u16Fsw) (a_u16Fsw) = iemFRegFetchFsw(pIemCpu)
+
+#define IEM_MC_STORE_GREG_U8(a_iGReg, a_u8Value) *iemGRegRefU8(pIemCpu, (a_iGReg)) = (a_u8Value)
+#define IEM_MC_STORE_GREG_U16(a_iGReg, a_u16Value) *(uint16_t *)iemGRegRef(pIemCpu, (a_iGReg)) = (a_u16Value)
+#define IEM_MC_STORE_GREG_U32(a_iGReg, a_u32Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) = (uint32_t)(a_u32Value) /* clear high bits. */
+#define IEM_MC_STORE_GREG_U64(a_iGReg, a_u64Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) = (a_u64Value)
+#define IEM_MC_STORE_GREG_U8_CONST IEM_MC_STORE_GREG_U8
+#define IEM_MC_STORE_GREG_U16_CONST IEM_MC_STORE_GREG_U16
+#define IEM_MC_STORE_GREG_U32_CONST IEM_MC_STORE_GREG_U32
+#define IEM_MC_STORE_GREG_U64_CONST IEM_MC_STORE_GREG_U64
+#define IEM_MC_CLEAR_HIGH_GREG_U64(a_iGReg) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) &= UINT32_MAX
+
+#define IEM_MC_REF_GREG_U8(a_pu8Dst, a_iGReg) (a_pu8Dst) = iemGRegRefU8(pIemCpu, (a_iGReg))
+#define IEM_MC_REF_GREG_U16(a_pu16Dst, a_iGReg) (a_pu16Dst) = (uint16_t *)iemGRegRef(pIemCpu, (a_iGReg))
+/** @todo User of IEM_MC_REF_GREG_U32 needs to clear the high bits on
+ * commit. */
+#define IEM_MC_REF_GREG_U32(a_pu32Dst, a_iGReg) (a_pu32Dst) = (uint32_t *)iemGRegRef(pIemCpu, (a_iGReg))
+#define IEM_MC_REF_GREG_U64(a_pu64Dst, a_iGReg) (a_pu64Dst) = (uint64_t *)iemGRegRef(pIemCpu, (a_iGReg))
+#define IEM_MC_REF_EFLAGS(a_pEFlags) (a_pEFlags) = &(pIemCpu)->CTX_SUFF(pCtx)->eflags.u
+
+#define IEM_MC_ADD_GREG_U8(a_iGReg, a_u8Value) *(uint8_t *)iemGRegRef(pIemCpu, (a_iGReg)) += (a_u8Value)
+#define IEM_MC_ADD_GREG_U16(a_iGReg, a_u16Value) *(uint16_t *)iemGRegRef(pIemCpu, (a_iGReg)) += (a_u16Value)
+#define IEM_MC_ADD_GREG_U32(a_iGReg, a_u32Value) \
+ do { \
+ uint32_t *pu32Reg = (uint32_t *)iemGRegRef(pIemCpu, (a_iGReg)); \
+ *pu32Reg += (a_u32Value); \
+ pu32Reg[1] = 0; /* implicitly clear the high bit. */ \
+ } while (0)
+#define IEM_MC_ADD_GREG_U64(a_iGReg, a_u64Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) += (a_u64Value)
+
+#define IEM_MC_SUB_GREG_U8(a_iGReg, a_u8Value) *(uint8_t *)iemGRegRef(pIemCpu, (a_iGReg)) -= (a_u8Value)
+#define IEM_MC_SUB_GREG_U16(a_iGReg, a_u16Value) *(uint16_t *)iemGRegRef(pIemCpu, (a_iGReg)) -= (a_u16Value)
+#define IEM_MC_SUB_GREG_U32(a_iGReg, a_u32Value) \
+ do { \
+ uint32_t *pu32Reg = (uint32_t *)iemGRegRef(pIemCpu, (a_iGReg)); \
+ *pu32Reg -= (a_u32Value); \
+ pu32Reg[1] = 0; /* implicitly clear the high bit. */ \
+ } while (0)
+#define IEM_MC_SUB_GREG_U64(a_iGReg, a_u64Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) -= (a_u64Value)
+
+#define IEM_MC_ADD_GREG_U8_TO_LOCAL(a_u8Value, a_iGReg) do { (a_u8Value) += iemGRegFetchU8( pIemCpu, (a_iGReg)); } while (0)
+#define IEM_MC_ADD_GREG_U16_TO_LOCAL(a_u16Value, a_iGReg) do { (a_u16Value) += iemGRegFetchU16(pIemCpu, (a_iGReg)); } while (0)
+#define IEM_MC_ADD_GREG_U32_TO_LOCAL(a_u32Value, a_iGReg) do { (a_u32Value) += iemGRegFetchU32(pIemCpu, (a_iGReg)); } while (0)
+#define IEM_MC_ADD_GREG_U64_TO_LOCAL(a_u64Value, a_iGReg) do { (a_u64Value) += iemGRegFetchU64(pIemCpu, (a_iGReg)); } while (0)
+#define IEM_MC_ADD_LOCAL_S16_TO_EFF_ADDR(a_EffAddr, a_i16) do { (a_EffAddr) += (a_i16); } while (0)
+#define IEM_MC_ADD_LOCAL_S32_TO_EFF_ADDR(a_EffAddr, a_i32) do { (a_EffAddr) += (a_i32); } while (0)
+#define IEM_MC_ADD_LOCAL_S64_TO_EFF_ADDR(a_EffAddr, a_i64) do { (a_EffAddr) += (a_i64); } while (0)
+
+#define IEM_MC_AND_LOCAL_U16(a_u16Local, a_u16Mask) do { (a_u16Local) &= (a_u16Mask); } while (0)
+#define IEM_MC_AND_LOCAL_U32(a_u32Local, a_u32Mask) do { (a_u32Local) &= (a_u32Mask); } while (0)
+#define IEM_MC_AND_LOCAL_U64(a_u64Local, a_u64Mask) do { (a_u64Local) &= (a_u64Mask); } while (0)
+
+#define IEM_MC_AND_ARG_U16(a_u16Arg, a_u16Mask) do { (a_u16Arg) &= (a_u16Mask); } while (0)
+#define IEM_MC_AND_ARG_U32(a_u32Arg, a_u32Mask) do { (a_u32Arg) &= (a_u32Mask); } while (0)
+#define IEM_MC_AND_ARG_U64(a_u64Arg, a_u64Mask) do { (a_u64Arg) &= (a_u64Mask); } while (0)
+
+#define IEM_MC_SAR_LOCAL_S16(a_i16Local, a_cShift) do { (a_i16Local) >>= (a_cShift); } while (0)
+#define IEM_MC_SAR_LOCAL_S32(a_i32Local, a_cShift) do { (a_i32Local) >>= (a_cShift); } while (0)
+#define IEM_MC_SAR_LOCAL_S64(a_i64Local, a_cShift) do { (a_i64Local) >>= (a_cShift); } while (0)
+
+#define IEM_MC_SHL_LOCAL_S16(a_i16Local, a_cShift) do { (a_i16Local) <<= (a_cShift); } while (0)
+#define IEM_MC_SHL_LOCAL_S32(a_i32Local, a_cShift) do { (a_i32Local) <<= (a_cShift); } while (0)
+#define IEM_MC_SHL_LOCAL_S64(a_i64Local, a_cShift) do { (a_i64Local) <<= (a_cShift); } while (0)
+
+
+#define IEM_MC_SET_EFL_BIT(a_fBit) do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u |= (a_fBit); } while (0)
+#define IEM_MC_CLEAR_EFL_BIT(a_fBit) do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u &= ~(a_fBit); } while (0)
+
+
+
+#define IEM_MC_FETCH_MEM_U8(a_u8Dst, a_iSeg, a_GCPtrMem) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &(a_u8Dst), (a_iSeg), (a_GCPtrMem)))
+#define IEM_MC_FETCH_MEM16_U8(a_u8Dst, a_iSeg, a_GCPtrMem16) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &(a_u8Dst), (a_iSeg), (a_GCPtrMem16)))
+#define IEM_MC_FETCH_MEM32_U8(a_u8Dst, a_iSeg, a_GCPtrMem32) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &(a_u8Dst), (a_iSeg), (a_GCPtrMem32)))
+
+#define IEM_MC_FETCH_MEM_U16(a_u16Dst, a_iSeg, a_GCPtrMem) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, &(a_u16Dst), (a_iSeg), (a_GCPtrMem)))
+#define IEM_MC_FETCH_MEM_U16_DISP(a_u16Dst, a_iSeg, a_GCPtrMem, a_offDisp) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, &(a_u16Dst), (a_iSeg), (a_GCPtrMem) + (a_offDisp)))
+
+#define IEM_MC_FETCH_MEM_U32(a_u32Dst, a_iSeg, a_GCPtrMem) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU32(pIemCpu, &(a_u32Dst), (a_iSeg), (a_GCPtrMem)))
+#define IEM_MC_FETCH_MEM_U32_DISP(a_u32Dst, a_iSeg, a_GCPtrMem, a_offDisp) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU32(pIemCpu, &(a_u32Dst), (a_iSeg), (a_GCPtrMem) + (a_offDisp)))
+
+#define IEM_MC_FETCH_MEM_S32_SX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataS32SxU64(pIemCpu, &(a_u64Dst), (a_iSeg), (a_GCPtrMem)))
+
+#define IEM_MC_FETCH_MEM_U64(a_u64Dst, a_iSeg, a_GCPtrMem) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU64(pIemCpu, &(a_u64Dst), (a_iSeg), (a_GCPtrMem)))
+#define IEM_MC_FETCH_MEM_U64_DISP(a_u64Dst, a_iSeg, a_GCPtrMem, a_offDisp) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU64(pIemCpu, &(a_u64Dst), (a_iSeg), (a_GCPtrMem) + (a_offDisp)))
+
+#define IEM_MC_FETCH_MEM_U8_ZX_U16(a_u16Dst, a_iSeg, a_GCPtrMem) \
+ do { \
+ uint8_t u8Tmp; \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &u8Tmp, (a_iSeg), (a_GCPtrMem))); \
+ (a_u16Dst) = u8Tmp; \
+ } while (0)
+#define IEM_MC_FETCH_MEM_U8_ZX_U32(a_u32Dst, a_iSeg, a_GCPtrMem) \
+ do { \
+ uint8_t u8Tmp; \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &u8Tmp, (a_iSeg), (a_GCPtrMem))); \
+ (a_u32Dst) = u8Tmp; \
+ } while (0)
+#define IEM_MC_FETCH_MEM_U8_ZX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) \
+ do { \
+ uint8_t u8Tmp; \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &u8Tmp, (a_iSeg), (a_GCPtrMem))); \
+ (a_u64Dst) = u8Tmp; \
+ } while (0)
+#define IEM_MC_FETCH_MEM_U16_ZX_U32(a_u32Dst, a_iSeg, a_GCPtrMem) \
+ do { \
+ uint16_t u16Tmp; \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, &u16Tmp, (a_iSeg), (a_GCPtrMem))); \
+ (a_u32Dst) = u16Tmp; \
+ } while (0)
+#define IEM_MC_FETCH_MEM_U16_ZX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) \
+ do { \
+ uint16_t u16Tmp; \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, &u16Tmp, (a_iSeg), (a_GCPtrMem))); \
+ (a_u64Dst) = u16Tmp; \
+ } while (0)
+#define IEM_MC_FETCH_MEM_U32_ZX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) \
+ do { \
+ uint32_t u32Tmp; \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU32(pIemCpu, &u32Tmp, (a_iSeg), (a_GCPtrMem))); \
+ (a_u64Dst) = u32Tmp; \
+ } while (0)
+
+#define IEM_MC_FETCH_MEM_U8_SX_U16(a_u16Dst, a_iSeg, a_GCPtrMem) \
+ do { \
+ uint8_t u8Tmp; \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &u8Tmp, (a_iSeg), (a_GCPtrMem))); \
+ (a_u16Dst) = (int8_t)u8Tmp; \
+ } while (0)
+#define IEM_MC_FETCH_MEM_U8_SX_U32(a_u32Dst, a_iSeg, a_GCPtrMem) \
+ do { \
+ uint8_t u8Tmp; \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &u8Tmp, (a_iSeg), (a_GCPtrMem))); \
+ (a_u32Dst) = (int8_t)u8Tmp; \
+ } while (0)
+#define IEM_MC_FETCH_MEM_U8_SX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) \
+ do { \
+ uint8_t u8Tmp; \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &u8Tmp, (a_iSeg), (a_GCPtrMem))); \
+ (a_u64Dst) = (int8_t)u8Tmp; \
+ } while (0)
+#define IEM_MC_FETCH_MEM_U16_SX_U32(a_u32Dst, a_iSeg, a_GCPtrMem) \
+ do { \
+ uint16_t u16Tmp; \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, &u16Tmp, (a_iSeg), (a_GCPtrMem))); \
+ (a_u32Dst) = (int16_t)u16Tmp; \
+ } while (0)
+#define IEM_MC_FETCH_MEM_U16_SX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) \
+ do { \
+ uint16_t u16Tmp; \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, &u16Tmp, (a_iSeg), (a_GCPtrMem))); \
+ (a_u64Dst) = (int16_t)u16Tmp; \
+ } while (0)
+#define IEM_MC_FETCH_MEM_U32_SX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) \
+ do { \
+ uint32_t u32Tmp; \
+ IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU32(pIemCpu, &u32Tmp, (a_iSeg), (a_GCPtrMem))); \
+ (a_u64Dst) = (int32_t)u32Tmp; \
+ } while (0)
+
+#define IEM_MC_STORE_MEM_U8(a_iSeg, a_GCPtrMem, a_u8Value) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU8(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u8Value)))
+#define IEM_MC_STORE_MEM_U16(a_iSeg, a_GCPtrMem, a_u16Value) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU16(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u16Value)))
+#define IEM_MC_STORE_MEM_U32(a_iSeg, a_GCPtrMem, a_u32Value) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU32(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u32Value)))
+#define IEM_MC_STORE_MEM_U64(a_iSeg, a_GCPtrMem, a_u64Value) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU64(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u64Value)))
+
+#define IEM_MC_STORE_MEM_U8_CONST(a_iSeg, a_GCPtrMem, a_u8C) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU8(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u8C)))
+
+#define IEM_MC_PUSH_U16(a_u16Value) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU16(pIemCpu, (a_u16Value)))
+#define IEM_MC_PUSH_U32(a_u32Value) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU32(pIemCpu, (a_u32Value)))
+#define IEM_MC_PUSH_U64(a_u64Value) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU64(pIemCpu, (a_u64Value)))
+
+#define IEM_MC_POP_U16(a_pu16Value) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU16(pIemCpu, (a_pu16Value)))
+#define IEM_MC_POP_U32(a_pu32Value) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU32(pIemCpu, (a_pu32Value)))
+#define IEM_MC_POP_U64(a_pu64Value) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU64(pIemCpu, (a_pu64Value)))
+
+/** Maps guest memory for direct or bounce buffered access.
+ * The purpose is to pass it to an operand implementation, thus the a_iArg.
+ * @remarks May return.
+ */
+#define IEM_MC_MEM_MAP(a_pMem, a_fAccess, a_iSeg, a_GCPtrMem, a_iArg) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemMap(pIemCpu, (void **)&(a_pMem), sizeof(*(a_pMem)), (a_iSeg), (a_GCPtrMem), (a_fAccess)))
+
+/** Maps guest memory for direct or bounce buffered access.
+ * The purpose is to pass it to an operand implementation, thus the a_iArg.
+ * @remarks May return.
+ */
+#define IEM_MC_MEM_MAP_EX(a_pvMem, a_fAccess, a_cbMem, a_iSeg, a_GCPtrMem, a_iArg) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemMap(pIemCpu, (void **)&(a_pvMem), (a_cbMem), (a_iSeg), (a_GCPtrMem), (a_fAccess)))
+
+/** Commits the memory and unmaps the guest memory.
+ * @remarks May return.
+ */
+#define IEM_MC_MEM_COMMIT_AND_UNMAP(a_pvMem, a_fAccess) \
+ IEM_MC_RETURN_ON_FAILURE(iemMemCommitAndUnmap(pIemCpu, (a_pvMem), (a_fAccess)))
+
+/** Calculate efficient address from R/M. */
+#define IEM_MC_CALC_RM_EFF_ADDR(a_GCPtrEff, bRm) \
+ IEM_MC_RETURN_ON_FAILURE(iemOpHlpCalcRmEffAddr(pIemCpu, (bRm), &(a_GCPtrEff)))
+
+#define IEM_MC_CALL_VOID_AIMPL_2(a_pfn, a0, a1) (a_pfn)((a0), (a1))
+#define IEM_MC_CALL_VOID_AIMPL_3(a_pfn, a0, a1, a2) (a_pfn)((a0), (a1), (a2))
+#define IEM_MC_CALL_VOID_AIMPL_4(a_pfn, a0, a1, a2, a3) (a_pfn)((a0), (a1), (a2), (a3))
+#define IEM_MC_CALL_AIMPL_4(a_rc, a_pfn, a0, a1, a2, a3) (a_rc) = (a_pfn)((a0), (a1), (a2), (a3))
+
+/**
+ * Defers the rest of the instruction emulation to a C implementation routine
+ * and returns, only taking the standard parameters.
+ *
+ * @param a_pfnCImpl The pointer to the C routine.
+ * @sa IEM_DECL_IMPL_C_TYPE_0 and IEM_CIMPL_DEF_0.
+ */
+#define IEM_MC_CALL_CIMPL_0(a_pfnCImpl) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode)
+
+/**
+ * Defers the rest of instruction emulation to a C implementation routine and
+ * returns, taking one argument in addition to the standard ones.
+ *
+ * @param a_pfnCImpl The pointer to the C routine.
+ * @param a0 The argument.
+ */
+#define IEM_MC_CALL_CIMPL_1(a_pfnCImpl, a0) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0)
+
+/**
+ * Defers the rest of the instruction emulation to a C implementation routine
+ * and returns, taking two arguments in addition to the standard ones.
+ *
+ * @param a_pfnCImpl The pointer to the C routine.
+ * @param a0 The first extra argument.
+ * @param a1 The second extra argument.
+ */
+#define IEM_MC_CALL_CIMPL_2(a_pfnCImpl, a0, a1) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1)
+
+/**
+ * Defers the rest of the instruction emulation to a C implementation routine
+ * and returns, taking two arguments in addition to the standard ones.
+ *
+ * @param a_pfnCImpl The pointer to the C routine.
+ * @param a0 The first extra argument.
+ * @param a1 The second extra argument.
+ * @param a2 The third extra argument.
+ */
+#define IEM_MC_CALL_CIMPL_3(a_pfnCImpl, a0, a1, a2) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1, a2)
+
+/**
+ * Defers the rest of the instruction emulation to a C implementation routine
+ * and returns, taking two arguments in addition to the standard ones.
+ *
+ * @param a_pfnCImpl The pointer to the C routine.
+ * @param a0 The first extra argument.
+ * @param a1 The second extra argument.
+ * @param a2 The third extra argument.
+ * @param a3 The fourth extra argument.
+ * @param a4 The fifth extra argument.
+ */
+#define IEM_MC_CALL_CIMPL_5(a_pfnCImpl, a0, a1, a2, a3, a4) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1, a2, a3, a4)
+
+/**
+ * Defers the entire instruction emulation to a C implementation routine and
+ * returns, only taking the standard parameters.
+ *
+ * This shall be used without any IEM_MC_BEGIN or IEM_END macro surrounding it.
+ *
+ * @param a_pfnCImpl The pointer to the C routine.
+ * @sa IEM_DECL_IMPL_C_TYPE_0 and IEM_CIMPL_DEF_0.
+ */
+#define IEM_MC_DEFER_TO_CIMPL_0(a_pfnCImpl) (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode)
+
+/**
+ * Defers the entire instruction emulation to a C implementation routine and
+ * returns, taking one argument in addition to the standard ones.
+ *
+ * This shall be used without any IEM_MC_BEGIN or IEM_END macro surrounding it.
+ *
+ * @param a_pfnCImpl The pointer to the C routine.
+ * @param a0 The argument.
+ */
+#define IEM_MC_DEFER_TO_CIMPL_1(a_pfnCImpl, a0) (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0)
+
+/**
+ * Defers the entire instruction emulation to a C implementation routine and
+ * returns, taking two arguments in addition to the standard ones.
+ *
+ * This shall be used without any IEM_MC_BEGIN or IEM_END macro surrounding it.
+ *
+ * @param a_pfnCImpl The pointer to the C routine.
+ * @param a0 The first extra argument.
+ * @param a1 The second extra argument.
+ */
+#define IEM_MC_DEFER_TO_CIMPL_2(a_pfnCImpl, a0, a1) (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1)
+
+/**
+ * Defers the entire instruction emulation to a C implementation routine and
+ * returns, taking three arguments in addition to the standard ones.
+ *
+ * This shall be used without any IEM_MC_BEGIN or IEM_END macro surrounding it.
+ *
+ * @param a_pfnCImpl The pointer to the C routine.
+ * @param a0 The first extra argument.
+ * @param a1 The second extra argument.
+ * @param a2 The third extra argument.
+ */
+#define IEM_MC_DEFER_TO_CIMPL_3(a_pfnCImpl, a0, a1, a2) (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1, a2)
+
+#define IEM_MC_IF_EFL_BIT_SET(a_fBit) if (pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit)) {
+#define IEM_MC_IF_EFL_BIT_NOT_SET(a_fBit) if (!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit))) {
+#define IEM_MC_IF_EFL_ANY_BITS_SET(a_fBits) if (pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBits)) {
+#define IEM_MC_IF_EFL_NO_BITS_SET(a_fBits) if (!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBits))) {
+#define IEM_MC_IF_EFL_BITS_NE(a_fBit1, a_fBit2) \
+ if ( !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit1)) \
+ != !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit2)) ) {
+#define IEM_MC_IF_EFL_BITS_EQ(a_fBit1, a_fBit2) \
+ if ( !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit1)) \
+ == !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit2)) ) {
+#define IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(a_fBit, a_fBit1, a_fBit2) \
+ if ( (pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit)) \
+ || !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit1)) \
+ != !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit2)) ) {
+#define IEM_MC_IF_EFL_BIT_NOT_SET_AND_BITS_EQ(a_fBit, a_fBit1, a_fBit2) \
+ if ( !(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit)) \
+ && !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit1)) \
+ == !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit2)) ) {
+#define IEM_MC_IF_CX_IS_NZ() if (pIemCpu->CTX_SUFF(pCtx)->cx != 0) {
+#define IEM_MC_IF_ECX_IS_NZ() if (pIemCpu->CTX_SUFF(pCtx)->ecx != 0) {
+#define IEM_MC_IF_RCX_IS_NZ() if (pIemCpu->CTX_SUFF(pCtx)->rcx != 0) {
+#define IEM_MC_IF_CX_IS_NZ_AND_EFL_BIT_SET(a_fBit) \
+ if ( pIemCpu->CTX_SUFF(pCtx)->cx != 0 \
+ && (pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
+#define IEM_MC_IF_ECX_IS_NZ_AND_EFL_BIT_SET(a_fBit) \
+ if ( pIemCpu->CTX_SUFF(pCtx)->ecx != 0 \
+ && (pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
+#define IEM_MC_IF_RCX_IS_NZ_AND_EFL_BIT_SET(a_fBit) \
+ if ( pIemCpu->CTX_SUFF(pCtx)->rcx != 0 \
+ && (pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
+#define IEM_MC_IF_CX_IS_NZ_AND_EFL_BIT_NOT_SET(a_fBit) \
+ if ( pIemCpu->CTX_SUFF(pCtx)->cx != 0 \
+ && !(pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
+#define IEM_MC_IF_ECX_IS_NZ_AND_EFL_BIT_NOT_SET(a_fBit) \
+ if ( pIemCpu->CTX_SUFF(pCtx)->ecx != 0 \
+ && !(pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
+#define IEM_MC_IF_RCX_IS_NZ_AND_EFL_BIT_NOT_SET(a_fBit) \
+ if ( pIemCpu->CTX_SUFF(pCtx)->rcx != 0 \
+ && !(pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
+#define IEM_MC_IF_LOCAL_IS_Z(a_Local) if ((a_Local) == 0) {
+#define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo) if (*(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) & RT_BIT_64(a_iBitNo)) {
+#define IEM_MC_ELSE() } else {
+#define IEM_MC_ENDIF() } do {} while (0)
+
+/** @} */
+
+
+/** @name Opcode Debug Helpers.
+ * @{
+ */
+#ifdef DEBUG
+# define IEMOP_MNEMONIC(a_szMnemonic) \
+ Log2(("decode - %04x:%RGv %s%s [#%u]\n", pIemCpu->CTX_SUFF(pCtx)->cs, pIemCpu->CTX_SUFF(pCtx)->rip, \
+ pIemCpu->fPrefixes & IEM_OP_PRF_LOCK ? "lock " : "", a_szMnemonic, pIemCpu->cInstructions))
+# define IEMOP_MNEMONIC2(a_szMnemonic, a_szOps) \
+ Log2(("decode - %04x:%RGv %s%s %s [#%u]\n", pIemCpu->CTX_SUFF(pCtx)->cs, pIemCpu->CTX_SUFF(pCtx)->rip, \
+ pIemCpu->fPrefixes & IEM_OP_PRF_LOCK ? "lock " : "", a_szMnemonic, a_szOps, pIemCpu->cInstructions))
+#else
+# define IEMOP_MNEMONIC(a_szMnemonic) do { } while (0)
+# define IEMOP_MNEMONIC2(a_szMnemonic, a_szOps) do { } while (0)
+#endif
+
+/** @} */
+
+
+/** @name Opcode Helpers.
+ * @{
+ */
+
+/** The instruction allows no lock prefixing (in this encoding), throw #UD if
+ * lock prefixed. */
+#define IEMOP_HLP_NO_LOCK_PREFIX() \
+ do \
+ { \
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_LOCK) \
+ return IEMOP_RAISE_INVALID_LOCK_PREFIX(); \
+ } while (0)
+
+/** The instruction is not available in 64-bit mode, throw #UD if we're in
+ * 64-bit mode. */
+#define IEMOP_HLP_NO_64BIT() \
+ do \
+ { \
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT) \
+ return IEMOP_RAISE_INVALID_OPCODE(); \
+ } while (0)
+
+/** The instruction defaults to 64-bit operand size if 64-bit mode. */
+#define IEMOP_HLP_DEFAULT_64BIT_OP_SIZE() \
+ do \
+ { \
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT) \
+ iemRecalEffOpSize64Default(pIemCpu); \
+ } while (0)
+
+
+
+/**
+ * Calculates the effective address of a ModR/M memory operand.
+ *
+ * Meant to be used via IEM_MC_CALC_RM_EFF_ADDR.
+ *
+ * @return Strict VBox status code.
+ * @param pIemCpu The IEM per CPU data.
+ * @param bRm The ModRM byte.
+ * @param pGCPtrEff Where to return the effective address.
+ */
+static VBOXSTRICTRC iemOpHlpCalcRmEffAddr(PIEMCPU pIemCpu, uint8_t bRm, PRTGCPTR pGCPtrEff)
+{
+ LogFlow(("iemOpHlpCalcRmEffAddr: bRm=%#x\n", bRm));
+ PCCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+#define SET_SS_DEF() \
+ do \
+ { \
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_SEG_MASK)) \
+ pIemCpu->iEffSeg = X86_SREG_SS; \
+ } while (0)
+
+/** @todo Check the effective address size crap! */
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT:
+ {
+ uint16_t u16EffAddr;
+
+ /* Handle the disp16 form with no registers first. */
+ if ((bRm & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 6)
+ IEM_OPCODE_GET_NEXT_U16(&u16EffAddr);
+ else
+ {
+ /* Get the displacment. */
+ switch ((bRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK)
+ {
+ case 0: u16EffAddr = 0; break;
+ case 1: IEM_OPCODE_GET_NEXT_S8_SX_U16(&u16EffAddr); break;
+ case 2: IEM_OPCODE_GET_NEXT_U16(&u16EffAddr); break;
+ default: AssertFailedReturn(VERR_INTERNAL_ERROR_2); /* (caller checked for these) */
+ }
+
+ /* Add the base and index registers to the disp. */
+ switch (bRm & X86_MODRM_RM_MASK)
+ {
+ case 0: u16EffAddr += pCtx->bx + pCtx->si; break;
+ case 1: u16EffAddr += pCtx->bx + pCtx->di; break;
+ case 2: u16EffAddr += pCtx->bp + pCtx->si; SET_SS_DEF(); break;
+ case 3: u16EffAddr += pCtx->bp + pCtx->di; SET_SS_DEF(); break;
+ case 4: u16EffAddr += pCtx->si; break;
+ case 5: u16EffAddr += pCtx->di; break;
+ case 6: u16EffAddr += pCtx->bp; SET_SS_DEF(); break;
+ case 7: u16EffAddr += pCtx->bx; break;
+ }
+ }
+
+ *pGCPtrEff = u16EffAddr;
+ LogFlow(("iemOpHlpCalcRmEffAddr: EffAddr=%#06RGv\n", *pGCPtrEff));
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ uint32_t u32EffAddr;
+
+ /* Handle the disp32 form with no registers first. */
+ if ((bRm & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5)
+ IEM_OPCODE_GET_NEXT_U32(&u32EffAddr);
+ else
+ {
+ /* Get the register (or SIB) value. */
+ switch ((bRm & X86_MODRM_RM_MASK))
+ {
+ case 0: u32EffAddr = pCtx->eax; break;
+ case 1: u32EffAddr = pCtx->ecx; break;
+ case 2: u32EffAddr = pCtx->edx; break;
+ case 3: u32EffAddr = pCtx->ebx; break;
+ case 4: /* SIB */
+ {
+ uint8_t bSib; IEM_OPCODE_GET_NEXT_U8(&bSib);
+
+ /* Get the index and scale it. */
+ switch ((bSib >> X86_SIB_INDEX_SHIFT) & X86_SIB_INDEX_SMASK)
+ {
+ case 0: u32EffAddr = pCtx->eax; break;
+ case 1: u32EffAddr = pCtx->ecx; break;
+ case 2: u32EffAddr = pCtx->edx; break;
+ case 3: u32EffAddr = pCtx->ebx; break;
+ case 4: u32EffAddr = 0; /*none */ break;
+ case 5: u32EffAddr = pCtx->ebp; break;
+ case 6: u32EffAddr = pCtx->esi; break;
+ case 7: u32EffAddr = pCtx->edi; break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ u32EffAddr <<= (bSib >> X86_SIB_SCALE_SHIFT) & X86_SIB_SCALE_SMASK;
+
+ /* add base */
+ switch (bSib & X86_SIB_BASE_MASK)
+ {
+ case 0: u32EffAddr += pCtx->eax; break;
+ case 1: u32EffAddr += pCtx->ecx; break;
+ case 2: u32EffAddr += pCtx->edx; break;
+ case 3: u32EffAddr += pCtx->ebx; break;
+ case 4: u32EffAddr += pCtx->esp; SET_SS_DEF(); break;
+ case 5:
+ if ((bRm & X86_MODRM_MOD_MASK) != 0)
+ {
+ u32EffAddr += pCtx->ebp;
+ SET_SS_DEF();
+ }
+ else
+ {
+ uint32_t u32Disp;
+ IEM_OPCODE_GET_NEXT_U32(&u32Disp);
+ u32EffAddr += u32Disp;
+ }
+ break;
+ case 6: u32EffAddr += pCtx->esi; break;
+ case 7: u32EffAddr += pCtx->edi; break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ }
+ case 5: u32EffAddr = pCtx->ebp; SET_SS_DEF(); break;
+ case 6: u32EffAddr = pCtx->esi; break;
+ case 7: u32EffAddr = pCtx->edi; break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+
+ /* Get and add the displacement. */
+ switch ((bRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK)
+ {
+ case 0:
+ break;
+ case 1:
+ {
+ int8_t i8Disp; IEM_OPCODE_GET_NEXT_S8(&i8Disp);
+ u32EffAddr += i8Disp;
+ break;
+ }
+ case 2:
+ {
+ uint32_t u32Disp; IEM_OPCODE_GET_NEXT_U32(&u32Disp);
+ u32EffAddr += u32Disp;
+ break;
+ }
+ default:
+ AssertFailedReturn(VERR_INTERNAL_ERROR_2); /* (caller checked for these) */
+ }
+
+ }
+ if (pIemCpu->enmEffAddrMode == IEMMODE_32BIT)
+ *pGCPtrEff = u32EffAddr;
+ else
+ {
+ Assert(pIemCpu->enmEffAddrMode == IEMMODE_16BIT);
+ *pGCPtrEff = u32EffAddr & UINT16_MAX;
+ }
+ LogFlow(("iemOpHlpCalcRmEffAddr: EffAddr=%#010RGv\n", *pGCPtrEff));
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ uint64_t u64EffAddr;
+
+ /* Handle the rip+disp32 form with no registers first. */
+ if ((bRm & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5)
+ {
+ IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64EffAddr);
+ u64EffAddr += pCtx->rip + pIemCpu->offOpcode;
+ }
+ else
+ {
+ /* Get the register (or SIB) value. */
+ switch ((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB)
+ {
+ case 0: u64EffAddr = pCtx->rax; break;
+ case 1: u64EffAddr = pCtx->rcx; break;
+ case 2: u64EffAddr = pCtx->rdx; break;
+ case 3: u64EffAddr = pCtx->rbx; break;
+ case 5: u64EffAddr = pCtx->rbp; SET_SS_DEF(); break;
+ case 6: u64EffAddr = pCtx->rsi; break;
+ case 7: u64EffAddr = pCtx->rdi; break;
+ case 8: u64EffAddr = pCtx->r8; break;
+ case 9: u64EffAddr = pCtx->r9; break;
+ case 10: u64EffAddr = pCtx->r10; break;
+ case 11: u64EffAddr = pCtx->r11; break;
+ case 13: u64EffAddr = pCtx->r13; break;
+ case 14: u64EffAddr = pCtx->r14; break;
+ case 15: u64EffAddr = pCtx->r15; break;
+ /* SIB */
+ case 4:
+ case 12:
+ {
+ uint8_t bSib; IEM_OPCODE_GET_NEXT_U8(&bSib);
+
+ /* Get the index and scale it. */
+ switch (((bSib & X86_SIB_INDEX_SHIFT) >> X86_SIB_INDEX_SMASK) | pIemCpu->uRexIndex)
+ {
+ case 0: u64EffAddr = pCtx->rax; break;
+ case 1: u64EffAddr = pCtx->rcx; break;
+ case 2: u64EffAddr = pCtx->rdx; break;
+ case 3: u64EffAddr = pCtx->rbx; break;
+ case 4: u64EffAddr = 0; /*none */ break;
+ case 5: u64EffAddr = pCtx->rbp; break;
+ case 6: u64EffAddr = pCtx->rsi; break;
+ case 7: u64EffAddr = pCtx->rdi; break;
+ case 8: u64EffAddr = pCtx->r8; break;
+ case 9: u64EffAddr = pCtx->r9; break;
+ case 10: u64EffAddr = pCtx->r10; break;
+ case 11: u64EffAddr = pCtx->r11; break;
+ case 12: u64EffAddr = pCtx->r12; break;
+ case 13: u64EffAddr = pCtx->r13; break;
+ case 14: u64EffAddr = pCtx->r14; break;
+ case 15: u64EffAddr = pCtx->r15; break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ u64EffAddr <<= (bSib >> X86_SIB_SCALE_SHIFT) & X86_SIB_SCALE_SMASK;
+
+ /* add base */
+ switch ((bSib & X86_SIB_BASE_MASK) | pIemCpu->uRexB)
+ {
+ case 0: u64EffAddr += pCtx->rax; break;
+ case 1: u64EffAddr += pCtx->rcx; break;
+ case 2: u64EffAddr += pCtx->rdx; break;
+ case 3: u64EffAddr += pCtx->rbx; break;
+ case 4: u64EffAddr += pCtx->rsp; SET_SS_DEF(); break;
+ case 6: u64EffAddr += pCtx->rsi; break;
+ case 7: u64EffAddr += pCtx->rdi; break;
+ case 8: u64EffAddr += pCtx->r8; break;
+ case 9: u64EffAddr += pCtx->r9; break;
+ case 10: u64EffAddr += pCtx->r10; break;
+ case 11: u64EffAddr += pCtx->r11; break;
+ case 14: u64EffAddr += pCtx->r14; break;
+ case 15: u64EffAddr += pCtx->r15; break;
+ /* complicated encodings */
+ case 5:
+ case 13:
+ if ((bRm & X86_MODRM_MOD_MASK) != 0)
+ {
+ if (!pIemCpu->uRexB)
+ {
+ u64EffAddr += pCtx->rbp;
+ SET_SS_DEF();
+ }
+ else
+ u64EffAddr += pCtx->r13;
+ }
+ else
+ {
+ uint32_t u32Disp;
+ IEM_OPCODE_GET_NEXT_U32(&u32Disp);
+ u64EffAddr += (int32_t)u32Disp;
+ }
+ break;
+ }
+ break;
+ }
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+
+ /* Get and add the displacement. */
+ switch ((bRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK)
+ {
+ case 0:
+ break;
+ case 1:
+ {
+ int8_t i8Disp;
+ IEM_OPCODE_GET_NEXT_S8(&i8Disp);
+ u64EffAddr += i8Disp;
+ break;
+ }
+ case 2:
+ {
+ uint32_t u32Disp;
+ IEM_OPCODE_GET_NEXT_U32(&u32Disp);
+ u64EffAddr += (int32_t)u32Disp;
+ break;
+ }
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* (caller checked for these) */
+ }
+
+ }
+ if (pIemCpu->enmEffAddrMode == IEMMODE_64BIT)
+ *pGCPtrEff = u64EffAddr;
+ else
+ *pGCPtrEff = u64EffAddr & UINT16_MAX;
+ LogFlow(("iemOpHlpCalcRmEffAddr: EffAddr=%#010RGv\n", *pGCPtrEff));
+ return VINF_SUCCESS;
+ }
+ }
+
+ AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+}
+
+/** @} */
+
+
+
+/*
+ * Include the instructions
+ */
+#include "IEMAllInstructions.cpp.h"
+
+
+
+
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
+
+/**
+ * Sets up execution verification mode.
+ */
+static void iemExecVerificationModeSetup(PIEMCPU pIemCpu)
+{
+ PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
+ PCPUMCTX pOrgCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Enable verification and/or logging.
+ */
+ pIemCpu->fNoRem = !LogIs6Enabled(); /* logging triggers the no-rem/rem verification stuff */
+ if ( pIemCpu->fNoRem
+#if 0 /* auto enable on first paged protected mode interrupt */
+ && pOrgCtx->eflags.Bits.u1IF
+ && (pOrgCtx->cr0 & (X86_CR0_PE | X86_CR0_PG)) == (X86_CR0_PE | X86_CR0_PG)
+ && TRPMHasTrap(pVCpu)
+ && EMGetInhibitInterruptsPC(pVCpu) != pOrgCtx->rip)
+#endif
+#if 0
+ && pOrgCtx->cs == 0x10
+ && ( pOrgCtx->rip == 0x90119e3e
+ || pOrgCtx->rip == 0x901d9810
+ )
+#endif
+#if 0 /* Auto enable; DSL. */
+ && pOrgCtx->cs == 0x10
+ && ( pOrgCtx->rip == 0x00100fc7
+ || pOrgCtx->rip == 0x00100ffc
+ || pOrgCtx->rip == 0x00100ffe
+ )
+#endif
+#if 0
+ && 0
+#endif
+ )
+ {
+ RTLogGroupSettings(NULL, "iem.eo.l6.l2");
+ RTLogFlags(NULL, "enabled");
+ pIemCpu->fNoRem = false;
+ }
+
+ /*
+ * Switch state.
+ */
+ if (IEM_VERIFICATION_ENABLED(pIemCpu))
+ {
+ static CPUMCTX s_DebugCtx; /* Ugly! */
+
+ s_DebugCtx = *pOrgCtx;
+ pIemCpu->CTX_SUFF(pCtx) = &s_DebugCtx;
+ }
+
+ /*
+ * See if there is an interrupt pending in TRPM and inject it if we can.
+ */
+ if ( pOrgCtx->eflags.Bits.u1IF
+ && TRPMHasTrap(pVCpu)
+ && EMGetInhibitInterruptsPC(pVCpu) != pOrgCtx->rip)
+ {
+ uint8_t u8TrapNo;
+ TRPMEVENT enmType;
+ RTGCUINT uErrCode;
+ RTGCPTR uCr2;
+ int rc2 = TRPMQueryTrapAll(pVCpu, &u8TrapNo, &enmType, &uErrCode, &uCr2); AssertRC(rc2);
+ IEMInjectTrap(pVCpu, u8TrapNo, enmType, (uint16_t)uErrCode, uCr2);
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ TRPMResetTrap(pVCpu);
+ }
+
+ /*
+ * Reset the counters.
+ */
+ pIemCpu->cIOReads = 0;
+ pIemCpu->cIOWrites = 0;
+ pIemCpu->fUndefinedEFlags = 0;
+
+ if (IEM_VERIFICATION_ENABLED(pIemCpu))
+ {
+ /*
+ * Free all verification records.
+ */
+ PIEMVERIFYEVTREC pEvtRec = pIemCpu->pIemEvtRecHead;
+ pIemCpu->pIemEvtRecHead = NULL;
+ pIemCpu->ppIemEvtRecNext = &pIemCpu->pIemEvtRecHead;
+ do
+ {
+ while (pEvtRec)
+ {
+ PIEMVERIFYEVTREC pNext = pEvtRec->pNext;
+ pEvtRec->pNext = pIemCpu->pFreeEvtRec;
+ pIemCpu->pFreeEvtRec = pEvtRec;
+ pEvtRec = pNext;
+ }
+ pEvtRec = pIemCpu->pOtherEvtRecHead;
+ pIemCpu->pOtherEvtRecHead = NULL;
+ pIemCpu->ppOtherEvtRecNext = &pIemCpu->pOtherEvtRecHead;
+ } while (pEvtRec);
+ }
+}
+
+
+/**
+ * Allocate an event record.
+ * @returns Poitner to a record.
+ */
+static PIEMVERIFYEVTREC iemVerifyAllocRecord(PIEMCPU pIemCpu)
+{
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ return NULL;
+
+ PIEMVERIFYEVTREC pEvtRec = pIemCpu->pFreeEvtRec;
+ if (pEvtRec)
+ pIemCpu->pFreeEvtRec = pEvtRec->pNext;
+ else
+ {
+ if (!pIemCpu->ppIemEvtRecNext)
+ return NULL; /* Too early (fake PCIBIOS), ignore notification. */
+
+ pEvtRec = (PIEMVERIFYEVTREC)MMR3HeapAlloc(IEMCPU_TO_VM(pIemCpu), MM_TAG_EM /* lazy bird*/, sizeof(*pEvtRec));
+ if (!pEvtRec)
+ return NULL;
+ }
+ pEvtRec->enmEvent = IEMVERIFYEVENT_INVALID;
+ pEvtRec->pNext = NULL;
+ return pEvtRec;
+}
+
+
+/**
+ * IOMMMIORead notification.
+ */
+VMM_INT_DECL(void) IEMNotifyMMIORead(PVM pVM, RTGCPHYS GCPhys, size_t cbValue)
+{
+ PVMCPU pVCpu = VMMGetCpu(pVM);
+ if (!pVCpu)
+ return;
+ PIEMCPU pIemCpu = &pVCpu->iem.s;
+ PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
+ if (!pEvtRec)
+ return;
+ pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
+ pEvtRec->u.RamRead.GCPhys = GCPhys;
+ pEvtRec->u.RamRead.cb = (uint32_t)cbValue;
+ pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
+ *pIemCpu->ppOtherEvtRecNext = pEvtRec;
+}
+
+
+/**
+ * IOMMMIOWrite notification.
+ */
+VMM_INT_DECL(void) IEMNotifyMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue)
+{
+ PVMCPU pVCpu = VMMGetCpu(pVM);
+ if (!pVCpu)
+ return;
+ PIEMCPU pIemCpu = &pVCpu->iem.s;
+ PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
+ if (!pEvtRec)
+ return;
+ pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_WRITE;
+ pEvtRec->u.RamWrite.GCPhys = GCPhys;
+ pEvtRec->u.RamWrite.cb = (uint32_t)cbValue;
+ pEvtRec->u.RamWrite.ab[0] = RT_BYTE1(u32Value);
+ pEvtRec->u.RamWrite.ab[1] = RT_BYTE2(u32Value);
+ pEvtRec->u.RamWrite.ab[2] = RT_BYTE3(u32Value);
+ pEvtRec->u.RamWrite.ab[3] = RT_BYTE4(u32Value);
+ pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
+ *pIemCpu->ppOtherEvtRecNext = pEvtRec;
+}
+
+
+/**
+ * IOMIOPortRead notification.
+ */
+VMM_INT_DECL(void) IEMNotifyIOPortRead(PVM pVM, RTIOPORT Port, size_t cbValue)
+{
+ PVMCPU pVCpu = VMMGetCpu(pVM);
+ if (!pVCpu)
+ return;
+ PIEMCPU pIemCpu = &pVCpu->iem.s;
+ PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
+ if (!pEvtRec)
+ return;
+ pEvtRec->enmEvent = IEMVERIFYEVENT_IOPORT_READ;
+ pEvtRec->u.IOPortRead.Port = Port;
+ pEvtRec->u.IOPortRead.cbValue = (uint32_t)cbValue;
+ pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
+ *pIemCpu->ppOtherEvtRecNext = pEvtRec;
+}
+
+/**
+ * IOMIOPortWrite notification.
+ */
+VMM_INT_DECL(void) IEMNotifyIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
+{
+ PVMCPU pVCpu = VMMGetCpu(pVM);
+ if (!pVCpu)
+ return;
+ PIEMCPU pIemCpu = &pVCpu->iem.s;
+ PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
+ if (!pEvtRec)
+ return;
+ pEvtRec->enmEvent = IEMVERIFYEVENT_IOPORT_WRITE;
+ pEvtRec->u.IOPortWrite.Port = Port;
+ pEvtRec->u.IOPortWrite.cbValue = (uint32_t)cbValue;
+ pEvtRec->u.IOPortWrite.u32Value = u32Value;
+ pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
+ *pIemCpu->ppOtherEvtRecNext = pEvtRec;
+}
+
+
+VMM_INT_DECL(void) IEMNotifyIOPortReadString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrDst, RTGCUINTREG cTransfers, size_t cbValue)
+{
+ AssertFailed();
+}
+
+
+VMM_INT_DECL(void) IEMNotifyIOPortWriteString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrSrc, RTGCUINTREG cTransfers, size_t cbValue)
+{
+ AssertFailed();
+}
+
+
+/**
+ * Fakes and records an I/O port read.
+ *
+ * @returns VINF_SUCCESS.
+ * @param pIemCpu The IEM per CPU data.
+ * @param Port The I/O port.
+ * @param pu32Value Where to store the fake value.
+ * @param cbValue The size of the access.
+ */
+static VBOXSTRICTRC iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue)
+{
+ PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
+ if (pEvtRec)
+ {
+ pEvtRec->enmEvent = IEMVERIFYEVENT_IOPORT_READ;
+ pEvtRec->u.IOPortRead.Port = Port;
+ pEvtRec->u.IOPortRead.cbValue = (uint32_t)cbValue;
+ pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
+ *pIemCpu->ppIemEvtRecNext = pEvtRec;
+ }
+ pIemCpu->cIOReads++;
+ *pu32Value = 0xffffffff;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Fakes and records an I/O port write.
+ *
+ * @returns VINF_SUCCESS.
+ * @param pIemCpu The IEM per CPU data.
+ * @param Port The I/O port.
+ * @param u32Value The value being written.
+ * @param cbValue The size of the access.
+ */
+static VBOXSTRICTRC iemVerifyFakeIOPortWrite(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
+{
+ PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
+ if (pEvtRec)
+ {
+ pEvtRec->enmEvent = IEMVERIFYEVENT_IOPORT_WRITE;
+ pEvtRec->u.IOPortWrite.Port = Port;
+ pEvtRec->u.IOPortWrite.cbValue = (uint32_t)cbValue;
+ pEvtRec->u.IOPortWrite.u32Value = u32Value;
+ pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
+ *pIemCpu->ppIemEvtRecNext = pEvtRec;
+ }
+ pIemCpu->cIOWrites++;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Used to add extra details about a stub case.
+ * @param pIemCpu The IEM per CPU state.
+ */
+static void iemVerifyAssertMsg2(PIEMCPU pIemCpu)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ PVM pVM = IEMCPU_TO_VM(pIemCpu);
+ PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
+ char szRegs[4096];
+ DBGFR3RegPrintf(pVM, pVCpu->idCpu, &szRegs[0], sizeof(szRegs),
+ "rax=%016VR{rax} rbx=%016VR{rbx} rcx=%016VR{rcx} rdx=%016VR{rdx}\n"
+ "rsi=%016VR{rsi} rdi=%016VR{rdi} r8 =%016VR{r8} r9 =%016VR{r9}\n"
+ "r10=%016VR{r10} r11=%016VR{r11} r12=%016VR{r12} r13=%016VR{r13}\n"
+ "r14=%016VR{r14} r15=%016VR{r15} %VRF{rflags}\n"
+ "rip=%016VR{rip} rsp=%016VR{rsp} rbp=%016VR{rbp}\n"
+ "cs={%04VR{cs} base=%016VR{cs_base} limit=%08VR{cs_lim} flags=%04VR{cs_attr}} cr0=%016VR{cr0}\n"
+ "ds={%04VR{ds} base=%016VR{ds_base} limit=%08VR{ds_lim} flags=%04VR{ds_attr}} cr2=%016VR{cr2}\n"
+ "es={%04VR{es} base=%016VR{es_base} limit=%08VR{es_lim} flags=%04VR{es_attr}} cr3=%016VR{cr3}\n"
+ "fs={%04VR{fs} base=%016VR{fs_base} limit=%08VR{fs_lim} flags=%04VR{fs_attr}} cr4=%016VR{cr4}\n"
+ "gs={%04VR{gs} base=%016VR{gs_base} limit=%08VR{gs_lim} flags=%04VR{gs_attr}} cr8=%016VR{cr8}\n"
+ "ss={%04VR{ss} base=%016VR{ss_base} limit=%08VR{ss_lim} flags=%04VR{ss_attr}}\n"
+ "dr0=%016VR{dr0} dr1=%016VR{dr1} dr2=%016VR{dr2} dr3=%016VR{dr3}\n"
+ "dr6=%016VR{dr6} dr7=%016VR{dr7}\n"
+ "gdtr=%016VR{gdtr_base}:%04VR{gdtr_lim} idtr=%016VR{idtr_base}:%04VR{idtr_lim} rflags=%08VR{rflags}\n"
+ "ldtr={%04VR{ldtr} base=%016VR{ldtr_base} limit=%08VR{ldtr_lim} flags=%08VR{ldtr_attr}}\n"
+ "tr ={%04VR{tr} base=%016VR{tr_base} limit=%08VR{tr_lim} flags=%08VR{tr_attr}}\n"
+ " sysenter={cs=%04VR{sysenter_cs} eip=%08VR{sysenter_eip} esp=%08VR{sysenter_esp}}\n"
+ " efer=%016VR{efer}\n"
+ " pat=%016VR{pat}\n"
+ " sf_mask=%016VR{sf_mask}\n"
+ "krnl_gs_base=%016VR{krnl_gs_base}\n"
+ " lstar=%016VR{lstar}\n"
+ " star=%016VR{star} cstar=%016VR{cstar}\n"
+ "fcw=%04VR{fcw} fsw=%04VR{fsw} ftw=%04VR{ftw} mxcsr=%04VR{mxcsr} mxcsr_mask=%04VR{mxcsr_mask}\n"
+ );
+
+ char szInstr1[256];
+ DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, pCtx->cs, pCtx->rip - pIemCpu->offOpcode,
+ DBGF_DISAS_FLAGS_DEFAULT_MODE,
+ szInstr1, sizeof(szInstr1), NULL);
+ char szInstr2[256];
+ DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, 0, 0,
+ DBGF_DISAS_FLAGS_CURRENT_GUEST | DBGF_DISAS_FLAGS_DEFAULT_MODE,
+ szInstr2, sizeof(szInstr2), NULL);
+
+ RTAssertMsg2Weak("%s%s\n%s\n", szRegs, szInstr1, szInstr2);
+}
+
+
+/**
+ * Used by iemVerifyAssertRecord and iemVerifyAssertRecords to add a record
+ * dump to the assertion info.
+ *
+ * @param pEvtRec The record to dump.
+ */
+static void iemVerifyAssertAddRecordDump(PIEMVERIFYEVTREC pEvtRec)
+{
+ switch (pEvtRec->enmEvent)
+ {
+ case IEMVERIFYEVENT_IOPORT_READ:
+ RTAssertMsg2Add("I/O PORT READ from %#6x, %d bytes\n",
+ pEvtRec->u.IOPortWrite.Port,
+ pEvtRec->u.IOPortWrite.cbValue);
+ break;
+ case IEMVERIFYEVENT_IOPORT_WRITE:
+ RTAssertMsg2Add("I/O PORT WRITE to %#6x, %d bytes, value %#x\n",
+ pEvtRec->u.IOPortWrite.Port,
+ pEvtRec->u.IOPortWrite.cbValue,
+ pEvtRec->u.IOPortWrite.u32Value);
+ break;
+ case IEMVERIFYEVENT_RAM_READ:
+ RTAssertMsg2Add("RAM READ at %RGp, %#4zx bytes\n",
+ pEvtRec->u.RamRead.GCPhys,
+ pEvtRec->u.RamRead.cb);
+ break;
+ case IEMVERIFYEVENT_RAM_WRITE:
+ RTAssertMsg2Add("RAM WRITE at %RGp, %#4zx bytes: %.*RHxs\n",
+ pEvtRec->u.RamWrite.GCPhys,
+ pEvtRec->u.RamWrite.cb,
+ (int)pEvtRec->u.RamWrite.cb,
+ pEvtRec->u.RamWrite.ab);
+ break;
+ default:
+ AssertMsgFailed(("Invalid event type %d\n", pEvtRec->enmEvent));
+ break;
+ }
+}
+
+
+/**
+ * Raises an assertion on the specified record, showing the given message with
+ * a record dump attached.
+ *
+ * @param pIemCpu The IEM per CPU data.
+ * @param pEvtRec1 The first record.
+ * @param pEvtRec2 The second record.
+ * @param pszMsg The message explaining why we're asserting.
+ */
+static void iemVerifyAssertRecords(PIEMCPU pIemCpu, PIEMVERIFYEVTREC pEvtRec1, PIEMVERIFYEVTREC pEvtRec2, const char *pszMsg)
+{
+ RTAssertMsg1(pszMsg, __LINE__, __FILE__, __PRETTY_FUNCTION__);
+ iemVerifyAssertAddRecordDump(pEvtRec1);
+ iemVerifyAssertAddRecordDump(pEvtRec2);
+ iemVerifyAssertMsg2(pIemCpu);
+ RTAssertPanic();
+}
+
+
+/**
+ * Raises an assertion on the specified record, showing the given message with
+ * a record dump attached.
+ *
+ * @param pIemCpu The IEM per CPU data.
+ * @param pEvtRec1 The first record.
+ * @param pszMsg The message explaining why we're asserting.
+ */
+static void iemVerifyAssertRecord(PIEMCPU pIemCpu, PIEMVERIFYEVTREC pEvtRec, const char *pszMsg)
+{
+ RTAssertMsg1(pszMsg, __LINE__, __FILE__, __PRETTY_FUNCTION__);
+ iemVerifyAssertAddRecordDump(pEvtRec);
+ iemVerifyAssertMsg2(pIemCpu);
+ RTAssertPanic();
+}
+
+
+/**
+ * Verifies a write record.
+ *
+ * @param pIemCpu The IEM per CPU data.
+ * @param pEvtRec The write record.
+ */
+static void iemVerifyWriteRecord(PIEMCPU pIemCpu, PIEMVERIFYEVTREC pEvtRec)
+{
+ uint8_t abBuf[sizeof(pEvtRec->u.RamWrite.ab)]; RT_ZERO(abBuf);
+ int rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), abBuf, pEvtRec->u.RamWrite.GCPhys, pEvtRec->u.RamWrite.cb);
+ if ( RT_FAILURE(rc)
+ || memcmp(abBuf, pEvtRec->u.RamWrite.ab, pEvtRec->u.RamWrite.cb) )
+ {
+ /* fend off ins */
+ if ( !pIemCpu->cIOReads
+ || pEvtRec->u.RamWrite.ab[0] != 0xcc
+ || ( pEvtRec->u.RamWrite.cb != 1
+ && pEvtRec->u.RamWrite.cb != 2
+ && pEvtRec->u.RamWrite.cb != 4) )
+ {
+ /* fend off ROMs */
+ if ( pEvtRec->u.RamWrite.GCPhys - UINT32_C(0x000c0000) > UINT32_C(0x8000)
+ && pEvtRec->u.RamWrite.GCPhys - UINT32_C(0x000e0000) > UINT32_C(0x20000)
+ && pEvtRec->u.RamWrite.GCPhys - UINT32_C(0xfffc0000) > UINT32_C(0x40000) )
+ {
+ RTAssertMsg1(NULL, __LINE__, __FILE__, __PRETTY_FUNCTION__);
+ RTAssertMsg2Weak("Memory at %RGv differs\n", pEvtRec->u.RamWrite.GCPhys);
+ RTAssertMsg2Add("REM: %.*Rhxs\n"
+ "IEM: %.*Rhxs\n",
+ pEvtRec->u.RamWrite.cb, abBuf,
+ pEvtRec->u.RamWrite.cb, pEvtRec->u.RamWrite.ab);
+ iemVerifyAssertAddRecordDump(pEvtRec);
+ iemVerifyAssertMsg2(pIemCpu);
+ RTAssertPanic();
+ }
+ }
+ }
+
+}
+
+/**
+ * Performs the post-execution verfication checks.
+ */
+static void iemExecVerificationModeCheck(PIEMCPU pIemCpu)
+{
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ return;
+
+ /*
+ * Switch back the state.
+ */
+ PCPUMCTX pOrgCtx = CPUMQueryGuestCtxPtr(IEMCPU_TO_VMCPU(pIemCpu));
+ PCPUMCTX pDebugCtx = pIemCpu->CTX_SUFF(pCtx);
+ Assert(pOrgCtx != pDebugCtx);
+ pIemCpu->CTX_SUFF(pCtx) = pOrgCtx;
+
+ /*
+ * Execute the instruction in REM.
+ */
+ PVM pVM = IEMCPU_TO_VM(pIemCpu);
+ EMRemLock(pVM);
+ int rc = REMR3EmulateInstruction(pVM, IEMCPU_TO_VMCPU(pIemCpu));
+ AssertRC(rc);
+ EMRemUnlock(pVM);
+
+ /*
+ * Compare the register states.
+ */
+ unsigned cDiffs = 0;
+ if (memcmp(pOrgCtx, pDebugCtx, sizeof(*pDebugCtx)))
+ {
+ Log(("REM and IEM ends up with different registers!\n"));
+
+# define CHECK_FIELD(a_Field) \
+ do \
+ { \
+ if (pOrgCtx->a_Field != pDebugCtx->a_Field) \
+ { \
+ switch (sizeof(pOrgCtx->a_Field)) \
+ { \
+ case 1: RTAssertMsg2Weak(" %8s differs - iem=%02x - rem=%02x\n", #a_Field, pDebugCtx->a_Field, pOrgCtx->a_Field); break; \
+ case 2: RTAssertMsg2Weak(" %8s differs - iem=%04x - rem=%04x\n", #a_Field, pDebugCtx->a_Field, pOrgCtx->a_Field); break; \
+ case 4: RTAssertMsg2Weak(" %8s differs - iem=%08x - rem=%08x\n", #a_Field, pDebugCtx->a_Field, pOrgCtx->a_Field); break; \
+ case 8: RTAssertMsg2Weak(" %8s differs - iem=%016llx - rem=%016llx\n", #a_Field, pDebugCtx->a_Field, pOrgCtx->a_Field); break; \
+ default: RTAssertMsg2Weak(" %8s differs\n", #a_Field); break; \
+ } \
+ cDiffs++; \
+ } \
+ } while (0)
+
+# define CHECK_BIT_FIELD(a_Field) \
+ do \
+ { \
+ if (pOrgCtx->a_Field != pDebugCtx->a_Field) \
+ { \
+ RTAssertMsg2Weak(" %8s differs - iem=%02x - rem=%02x\n", #a_Field, pDebugCtx->a_Field, pOrgCtx->a_Field); \
+ cDiffs++; \
+ } \
+ } while (0)
+
+# define CHECK_SEL(a_Sel) \
+ do \
+ { \
+ CHECK_FIELD(a_Sel); \
+ if ( pOrgCtx->a_Sel##Hid.Attr.u != pDebugCtx->a_Sel##Hid.Attr.u \
+ && (pOrgCtx->a_Sel##Hid.Attr.u | X86_SEL_TYPE_ACCESSED) != pDebugCtx->a_Sel##Hid.Attr.u) \
+ { \
+ RTAssertMsg2Weak(" %8sHid.Attr differs - iem=%02x - rem=%02x\n", #a_Sel, pDebugCtx->a_Sel##Hid.Attr.u, pOrgCtx->a_Sel##Hid.Attr.u); \
+ cDiffs++; \
+ } \
+ CHECK_FIELD(a_Sel##Hid.u64Base); \
+ CHECK_FIELD(a_Sel##Hid.u32Limit); \
+ } while (0)
+
+ if (memcmp(&pOrgCtx->fpu, &pDebugCtx->fpu, sizeof(pDebugCtx->fpu)))
+ {
+ RTAssertMsg2Weak(" the FPU state differs\n");
+ cDiffs++;
+ CHECK_FIELD(fpu.FCW);
+ CHECK_FIELD(fpu.FSW);
+ CHECK_FIELD(fpu.FTW);
+ CHECK_FIELD(fpu.FOP);
+ CHECK_FIELD(fpu.FPUIP);
+ CHECK_FIELD(fpu.CS);
+ CHECK_FIELD(fpu.Rsrvd1);
+ CHECK_FIELD(fpu.FPUDP);
+ CHECK_FIELD(fpu.DS);
+ CHECK_FIELD(fpu.Rsrvd2);
+ CHECK_FIELD(fpu.MXCSR);
+ CHECK_FIELD(fpu.MXCSR_MASK);
+ CHECK_FIELD(fpu.aRegs[0].au64[0]); CHECK_FIELD(fpu.aRegs[0].au64[1]);
+ CHECK_FIELD(fpu.aRegs[1].au64[0]); CHECK_FIELD(fpu.aRegs[1].au64[1]);
+ CHECK_FIELD(fpu.aRegs[2].au64[0]); CHECK_FIELD(fpu.aRegs[2].au64[1]);
+ CHECK_FIELD(fpu.aRegs[3].au64[0]); CHECK_FIELD(fpu.aRegs[3].au64[1]);
+ CHECK_FIELD(fpu.aRegs[4].au64[0]); CHECK_FIELD(fpu.aRegs[4].au64[1]);
+ CHECK_FIELD(fpu.aRegs[5].au64[0]); CHECK_FIELD(fpu.aRegs[5].au64[1]);
+ CHECK_FIELD(fpu.aRegs[6].au64[0]); CHECK_FIELD(fpu.aRegs[6].au64[1]);
+ CHECK_FIELD(fpu.aRegs[7].au64[0]); CHECK_FIELD(fpu.aRegs[7].au64[1]);
+ CHECK_FIELD(fpu.aXMM[ 0].au64[0]); CHECK_FIELD(fpu.aXMM[ 0].au64[1]);
+ CHECK_FIELD(fpu.aXMM[ 1].au64[0]); CHECK_FIELD(fpu.aXMM[ 1].au64[1]);
+ CHECK_FIELD(fpu.aXMM[ 2].au64[0]); CHECK_FIELD(fpu.aXMM[ 2].au64[1]);
+ CHECK_FIELD(fpu.aXMM[ 3].au64[0]); CHECK_FIELD(fpu.aXMM[ 3].au64[1]);
+ CHECK_FIELD(fpu.aXMM[ 4].au64[0]); CHECK_FIELD(fpu.aXMM[ 4].au64[1]);
+ CHECK_FIELD(fpu.aXMM[ 5].au64[0]); CHECK_FIELD(fpu.aXMM[ 5].au64[1]);
+ CHECK_FIELD(fpu.aXMM[ 6].au64[0]); CHECK_FIELD(fpu.aXMM[ 6].au64[1]);
+ CHECK_FIELD(fpu.aXMM[ 7].au64[0]); CHECK_FIELD(fpu.aXMM[ 7].au64[1]);
+ CHECK_FIELD(fpu.aXMM[ 8].au64[0]); CHECK_FIELD(fpu.aXMM[ 8].au64[1]);
+ CHECK_FIELD(fpu.aXMM[ 9].au64[0]); CHECK_FIELD(fpu.aXMM[ 9].au64[1]);
+ CHECK_FIELD(fpu.aXMM[10].au64[0]); CHECK_FIELD(fpu.aXMM[10].au64[1]);
+ CHECK_FIELD(fpu.aXMM[11].au64[0]); CHECK_FIELD(fpu.aXMM[11].au64[1]);
+ CHECK_FIELD(fpu.aXMM[12].au64[0]); CHECK_FIELD(fpu.aXMM[12].au64[1]);
+ CHECK_FIELD(fpu.aXMM[13].au64[0]); CHECK_FIELD(fpu.aXMM[13].au64[1]);
+ CHECK_FIELD(fpu.aXMM[14].au64[0]); CHECK_FIELD(fpu.aXMM[14].au64[1]);
+ CHECK_FIELD(fpu.aXMM[15].au64[0]); CHECK_FIELD(fpu.aXMM[15].au64[1]);
+ for (unsigned i = 0; i < RT_ELEMENTS(pOrgCtx->fpu.au32RsrvdRest); i++)
+ CHECK_FIELD(fpu.au32RsrvdRest[i]);
+ }
+ CHECK_FIELD(rip);
+ uint32_t fFlagsMask = UINT32_MAX & ~pIemCpu->fUndefinedEFlags;
+ if ((pOrgCtx->rflags.u & fFlagsMask) != (pDebugCtx->rflags.u & fFlagsMask))
+ {
+ RTAssertMsg2Weak(" rflags differs - iem=%08llx rem=%08llx\n", pDebugCtx->rflags.u, pOrgCtx->rflags.u);
+ CHECK_BIT_FIELD(rflags.Bits.u1CF);
+ CHECK_BIT_FIELD(rflags.Bits.u1Reserved0);
+ CHECK_BIT_FIELD(rflags.Bits.u1PF);
+ CHECK_BIT_FIELD(rflags.Bits.u1Reserved1);
+ CHECK_BIT_FIELD(rflags.Bits.u1AF);
+ CHECK_BIT_FIELD(rflags.Bits.u1Reserved2);
+ CHECK_BIT_FIELD(rflags.Bits.u1ZF);
+ CHECK_BIT_FIELD(rflags.Bits.u1SF);
+ CHECK_BIT_FIELD(rflags.Bits.u1TF);
+ CHECK_BIT_FIELD(rflags.Bits.u1IF);
+ CHECK_BIT_FIELD(rflags.Bits.u1DF);
+ CHECK_BIT_FIELD(rflags.Bits.u1OF);
+ CHECK_BIT_FIELD(rflags.Bits.u2IOPL);
+ CHECK_BIT_FIELD(rflags.Bits.u1NT);
+ CHECK_BIT_FIELD(rflags.Bits.u1Reserved3);
+ CHECK_BIT_FIELD(rflags.Bits.u1RF);
+ CHECK_BIT_FIELD(rflags.Bits.u1VM);
+ CHECK_BIT_FIELD(rflags.Bits.u1AC);
+ CHECK_BIT_FIELD(rflags.Bits.u1VIF);
+ CHECK_BIT_FIELD(rflags.Bits.u1VIP);
+ CHECK_BIT_FIELD(rflags.Bits.u1ID);
+ }
+
+ if (pIemCpu->cIOReads != 1 && !pIemCpu->fIgnoreRaxRdx)
+ CHECK_FIELD(rax);
+ CHECK_FIELD(rcx);
+ if (!pIemCpu->fIgnoreRaxRdx)
+ CHECK_FIELD(rdx);
+ CHECK_FIELD(rbx);
+ CHECK_FIELD(rsp);
+ CHECK_FIELD(rbp);
+ CHECK_FIELD(rsi);
+ CHECK_FIELD(rdi);
+ CHECK_FIELD(r8);
+ CHECK_FIELD(r9);
+ CHECK_FIELD(r10);
+ CHECK_FIELD(r11);
+ CHECK_FIELD(r12);
+ CHECK_FIELD(r13);
+ CHECK_SEL(cs);
+ CHECK_SEL(ss);
+ CHECK_SEL(ds);
+ CHECK_SEL(es);
+ CHECK_SEL(fs);
+ CHECK_SEL(gs);
+ CHECK_FIELD(cr0);
+ CHECK_FIELD(cr2);
+ CHECK_FIELD(cr3);
+ CHECK_FIELD(cr4);
+ CHECK_FIELD(dr[0]);
+ CHECK_FIELD(dr[1]);
+ CHECK_FIELD(dr[2]);
+ CHECK_FIELD(dr[3]);
+ CHECK_FIELD(dr[6]);
+ CHECK_FIELD(dr[7]);
+ CHECK_FIELD(gdtr.cbGdt);
+ CHECK_FIELD(gdtr.pGdt);
+ CHECK_FIELD(idtr.cbIdt);
+ CHECK_FIELD(idtr.pIdt);
+ CHECK_FIELD(ldtr);
+ CHECK_FIELD(ldtrHid.u64Base);
+ CHECK_FIELD(ldtrHid.u32Limit);
+ CHECK_FIELD(ldtrHid.Attr.u);
+ CHECK_FIELD(tr);
+ CHECK_FIELD(trHid.u64Base);
+ CHECK_FIELD(trHid.u32Limit);
+ CHECK_FIELD(trHid.Attr.u);
+ CHECK_FIELD(SysEnter.cs);
+ CHECK_FIELD(SysEnter.eip);
+ CHECK_FIELD(SysEnter.esp);
+ CHECK_FIELD(msrEFER);
+ CHECK_FIELD(msrSTAR);
+ CHECK_FIELD(msrPAT);
+ CHECK_FIELD(msrLSTAR);
+ CHECK_FIELD(msrCSTAR);
+ CHECK_FIELD(msrSFMASK);
+ CHECK_FIELD(msrKERNELGSBASE);
+
+ if (cDiffs != 0)
+ {
+ RTAssertMsg1(NULL, __LINE__, __FILE__, __FUNCTION__);
+ iemVerifyAssertMsg2(pIemCpu);
+ RTAssertPanic();
+ }
+# undef CHECK_FIELD
+# undef CHECK_BIT_FIELD
+ }
+
+ /*
+ * If the register state compared fine, check the verification event
+ * records.
+ */
+ if (cDiffs == 0)
+ {
+ /*
+ * Compare verficiation event records.
+ * - I/O port accesses should be a 1:1 match.
+ */
+ PIEMVERIFYEVTREC pIemRec = pIemCpu->pIemEvtRecHead;
+ PIEMVERIFYEVTREC pOtherRec = pIemCpu->pOtherEvtRecHead;
+ while (pIemRec && pOtherRec)
+ {
+ /* Since we might miss RAM writes and reads, ignore reads and check
+ that any written memory is the same extra ones. */
+ while ( IEMVERIFYEVENT_IS_RAM(pIemRec->enmEvent)
+ && !IEMVERIFYEVENT_IS_RAM(pOtherRec->enmEvent)
+ && pIemRec->pNext)
+ {
+ if (pIemRec->enmEvent == IEMVERIFYEVENT_RAM_WRITE)
+ iemVerifyWriteRecord(pIemCpu, pIemRec);
+ pIemRec = pIemRec->pNext;
+ }
+
+ /* Do the compare. */
+ if (pIemRec->enmEvent != pOtherRec->enmEvent)
+ {
+ iemVerifyAssertRecords(pIemCpu, pIemRec, pOtherRec, "Type mismatches");
+ break;
+ }
+ bool fEquals;
+ switch (pIemRec->enmEvent)
+ {
+ case IEMVERIFYEVENT_IOPORT_READ:
+ fEquals = pIemRec->u.IOPortRead.Port == pOtherRec->u.IOPortRead.Port
+ && pIemRec->u.IOPortRead.cbValue == pOtherRec->u.IOPortRead.cbValue;
+ break;
+ case IEMVERIFYEVENT_IOPORT_WRITE:
+ fEquals = pIemRec->u.IOPortWrite.Port == pOtherRec->u.IOPortWrite.Port
+ && pIemRec->u.IOPortWrite.cbValue == pOtherRec->u.IOPortWrite.cbValue
+ && pIemRec->u.IOPortWrite.u32Value == pOtherRec->u.IOPortWrite.u32Value;
+ break;
+ case IEMVERIFYEVENT_RAM_READ:
+ fEquals = pIemRec->u.RamRead.GCPhys == pOtherRec->u.RamRead.GCPhys
+ && pIemRec->u.RamRead.cb == pOtherRec->u.RamRead.cb;
+ break;
+ case IEMVERIFYEVENT_RAM_WRITE:
+ fEquals = pIemRec->u.RamWrite.GCPhys == pOtherRec->u.RamWrite.GCPhys
+ && pIemRec->u.RamWrite.cb == pOtherRec->u.RamWrite.cb
+ && !memcmp(pIemRec->u.RamWrite.ab, pOtherRec->u.RamWrite.ab, pIemRec->u.RamWrite.cb);
+ break;
+ default:
+ fEquals = false;
+ break;
+ }
+ if (!fEquals)
+ {
+ iemVerifyAssertRecords(pIemCpu, pIemRec, pOtherRec, "Mismatch");
+ break;
+ }
+
+ /* advance */
+ pIemRec = pIemRec->pNext;
+ pOtherRec = pOtherRec->pNext;
+ }
+
+ /* Ignore extra writes and reads. */
+ while (pIemRec && IEMVERIFYEVENT_IS_RAM(pIemRec->enmEvent))
+ {
+ if (pIemRec->enmEvent == IEMVERIFYEVENT_RAM_WRITE)
+ iemVerifyWriteRecord(pIemCpu, pIemRec);
+ pIemRec = pIemRec->pNext;
+ }
+ if (pIemRec != NULL)
+ iemVerifyAssertRecord(pIemCpu, pIemRec, "Extra IEM record!");
+ else if (pOtherRec != NULL)
+ iemVerifyAssertRecord(pIemCpu, pIemRec, "Extra Other record!");
+ }
+ pIemCpu->CTX_SUFF(pCtx) = pOrgCtx;
+
+#if 0
+ /*
+ * HACK ALERT! You don't normally want to verify a whole boot sequence.
+ */
+ if (pIemCpu->cInstructions == 1)
+ RTLogFlags(NULL, "disabled");
+#endif
+}
+
+#else /* !IEM_VERIFICATION_MODE || !IN_RING3 */
+
+/* stubs */
+static VBOXSTRICTRC iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+static VBOXSTRICTRC iemVerifyFakeIOPortWrite(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+#endif /* !IEM_VERIFICATION_MODE || !IN_RING3 */
+
+
+/**
+ * Execute one instruction.
+ *
+ * @return Strict VBox status code.
+ * @param pVCpu The current virtual CPU.
+ */
+VMMDECL(VBOXSTRICTRC) IEMExecOne(PVMCPU pVCpu)
+{
+ PIEMCPU pIemCpu = &pVCpu->iem.s;
+
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
+ iemExecVerificationModeSetup(pIemCpu);
+#endif
+#ifdef LOG_ENABLED
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ if (LogIs2Enabled())
+ {
+ char szInstr[256];
+ uint32_t cbInstr = 0;
+ DBGFR3DisasInstrEx(pVCpu->pVMR3, pVCpu->idCpu, 0, 0,
+ DBGF_DISAS_FLAGS_CURRENT_GUEST | DBGF_DISAS_FLAGS_DEFAULT_MODE,
+ szInstr, sizeof(szInstr), &cbInstr);
+
+ Log2(("**** "
+ " eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n"
+ " eip=%08x esp=%08x ebp=%08x iopl=%d\n"
+ " cs=%04x ss=%04x ds=%04x es=%04x fs=%04x gs=%04x efl=%08x\n"
+ " %s\n"
+ ,
+ pCtx->eax, pCtx->ebx, pCtx->ecx, pCtx->edx, pCtx->esi, pCtx->edi,
+ pCtx->eip, pCtx->esp, pCtx->ebp, pCtx->eflags.Bits.u2IOPL,
+ (RTSEL)pCtx->cs, (RTSEL)pCtx->ss, (RTSEL)pCtx->ds, (RTSEL)pCtx->es,
+ (RTSEL)pCtx->fs, (RTSEL)pCtx->gs, pCtx->eflags.u,
+ szInstr));
+ }
+#endif
+
+ /*
+ * Do the decoding and emulation.
+ */
+ VBOXSTRICTRC rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ if (rcStrict == VINF_SUCCESS)
+ pIemCpu->cInstructions++;
+//#ifdef DEBUG
+// AssertMsg(pIemCpu->offOpcode == cbInstr || rcStrict != VINF_SUCCESS, ("%u %u\n", pIemCpu->offOpcode, cbInstr));
+//#endif
+
+ /* Execute the next instruction as well if a cli, pop ss or
+ mov ss, Gr has just completed successfully. */
+ if ( rcStrict == VINF_SUCCESS
+ && VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
+ && EMGetInhibitInterruptsPC(pVCpu) == pIemCpu->CTX_SUFF(pCtx)->rip )
+ {
+ rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ b; IEM_OPCODE_GET_NEXT_U8(&b);
+ rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ if (rcStrict == VINF_SUCCESS)
+ pIemCpu->cInstructions++;
+ }
+ EMSetInhibitInterruptsPC(pVCpu, UINT64_C(0x7777555533331111));
+ }
+
+ /*
+ * Assert some sanity.
+ */
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
+ iemExecVerificationModeCheck(pIemCpu);
+#endif
+ return rcStrict;
+}
+
+
+/**
+ * Injects a trap, fault, abort, software interrupt or external interrupt.
+ *
+ * The parameter list matches TRPMQueryTrapAll pretty closely.
+ *
+ * @returns Strict VBox status code.
+ * @param pVCpu The current virtual CPU.
+ * @param u8TrapNo The trap number.
+ * @param enmType What type is it (trap/fault/abort), software
+ * interrupt or hardware interrupt.
+ * @param uErrCode The error code if applicable.
+ * @param uCr2 The CR2 value if applicable.
+ */
+VMM_INT_DECL(VBOXSTRICTRC) IEMInjectTrap(PVMCPU pVCpu, uint8_t u8TrapNo, TRPMEVENT enmType, uint16_t uErrCode, RTGCPTR uCr2)
+{
+ uint32_t fFlags;
+ switch (enmType)
+ {
+ case TRPM_HARDWARE_INT:
+ Log(("IEMInjectTrap: %#4x ext\n", u8TrapNo));
+ fFlags = IEM_XCPT_FLAGS_T_EXT_INT;
+ uErrCode = uCr2 = 0;
+ break;
+
+ case TRPM_SOFTWARE_INT:
+ Log(("IEMInjectTrap: %#4x soft\n", u8TrapNo));
+ fFlags = IEM_XCPT_FLAGS_T_SOFT_INT;
+ uErrCode = uCr2 = 0;
+ break;
+
+ case TRPM_TRAP:
+ Log(("IEMInjectTrap: %#4x trap err=%#x cr2=%#RGv\n", u8TrapNo, uErrCode, uCr2));
+ fFlags = IEM_XCPT_FLAGS_T_CPU_XCPT;
+ if (u8TrapNo == X86_XCPT_PF)
+ fFlags |= IEM_XCPT_FLAGS_CR2;
+ switch (u8TrapNo)
+ {
+ case X86_XCPT_DF:
+ case X86_XCPT_TS:
+ case X86_XCPT_NP:
+ case X86_XCPT_SS:
+ case X86_XCPT_PF:
+ case X86_XCPT_AC:
+ fFlags |= IEM_XCPT_FLAGS_ERR;
+ break;
+ }
+ break;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+
+ return iemRaiseXcptOrInt(&pVCpu->iem.s, 0, u8TrapNo, fFlags, uErrCode, uCr2);
+}
+
diff --git a/src/VBox/VMM/VMMAll/IEMAllAImpl.asm b/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
new file mode 100644
index 000000000..6bd173d6f
--- /dev/null
+++ b/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
@@ -0,0 +1,1235 @@
+; $Id: IEMAllAImpl.asm 38026 2011-07-18 15:02:15Z vboxsync $
+;; @file
+; IEM - Instruction Implementation in Assembly.
+;
+
+; 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 "VBox/asmdefs.mac"
+%include "VBox/err.mac"
+%include "iprt/x86.mac"
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Defined Constants And Macros ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;
+; RET XX / RET wrapper for fastcall.
+;
+%macro RET_FASTCALL 1
+%ifdef RT_ARCH_X86
+ %ifdef RT_OS_WINDOWS
+ ret %1
+ %else
+ ret
+ %endif
+%else
+ ret
+%endif
+%endmacro
+
+;;
+; NAME for fastcall functions.
+;
+;; @todo 'global @fastcall@12' is still broken in yasm and requires dollar
+; escaping (or whatever the dollar is good for here). Thus the ugly
+; prefix argument.
+;
+%define NAME_FASTCALL(a_Name, a_cbArgs, a_Dollar) NAME(a_Name)
+%ifdef RT_ARCH_X86
+ %ifdef RT_OS_WINDOWS
+ %undef NAME_FASTCALL
+ %define NAME_FASTCALL(a_Name, a_cbArgs, a_Prefix) a_Prefix %+ a_Name %+ @ %+ a_cbArgs
+ %endif
+%endif
+
+;;
+; BEGINPROC for fastcall functions.
+;
+; @param 1 The function name (C).
+; @param 2 The argument size on x86.
+;
+%macro BEGINPROC_FASTCALL 2
+ %ifdef ASM_FORMAT_PE
+ export %1=NAME_FASTCALL(%1,%2,$@)
+ %endif
+ %ifdef __NASM__
+ %ifdef ASM_FORMAT_OMF
+ export NAME(%1) NAME_FASTCALL(%1,%2,$@)
+ %endif
+ %endif
+ %ifndef ASM_FORMAT_BIN
+ global NAME_FASTCALL(%1,%2,$@)
+ %endif
+NAME_FASTCALL(%1,%2,@):
+%endmacro
+
+
+;
+; We employ some macro assembly here to hid the calling convention differences.
+;
+%ifdef RT_ARCH_AMD64
+ %macro PROLOGUE_1_ARGS 0
+ %endmacro
+ %macro EPILOGUE_1_ARGS 1
+ ret
+ %endmacro
+
+ %macro PROLOGUE_2_ARGS 0
+ %endmacro
+ %macro EPILOGUE_2_ARGS 1
+ ret
+ %endmacro
+
+ %macro PROLOGUE_3_ARGS 0
+ %endmacro
+ %macro EPILOGUE_3_ARGS 1
+ ret
+ %endmacro
+
+ %macro PROLOGUE_4_ARGS 0
+ %endmacro
+ %macro EPILOGUE_4_ARGS 1
+ ret
+ %endmacro
+
+ %ifdef ASM_CALL64_GCC
+ %define A0 rdi
+ %define A0_32 edi
+ %define A0_16 di
+ %define A0_8 dil
+
+ %define A1 rsi
+ %define A1_32 esi
+ %define A1_16 si
+ %define A1_8 sil
+
+ %define A2 rdx
+ %define A2_32 edx
+ %define A2_16 dx
+ %define A2_8 dl
+
+ %define A3 rcx
+ %define A3_32 ecx
+ %define A3_16 cx
+ %endif
+
+ %ifdef ASM_CALL64_MSC
+ %define A0 rcx
+ %define A0_32 ecx
+ %define A0_16 cx
+ %define A0_8 cl
+
+ %define A1 rdx
+ %define A1_32 edx
+ %define A1_16 dx
+ %define A1_8 dl
+
+ %define A2 r8
+ %define A2_32 r8d
+ %define A2_16 r8w
+ %define A2_8 r8b
+
+ %define A3 r9
+ %define A3_32 r9d
+ %define A3_16 r9w
+ %endif
+
+ %define T0 rax
+ %define T0_32 eax
+ %define T0_16 ax
+ %define T0_8 al
+
+ %define T1 r11
+ %define T1_32 r11d
+ %define T1_16 r11w
+ %define T1_8 r11b
+
+%else
+ ; x86
+ %macro PROLOGUE_1_ARGS 0
+ push edi
+ %endmacro
+ %macro EPILOGUE_1_ARGS 1
+ pop edi
+ ret %1
+ %endmacro
+
+ %macro PROLOGUE_2_ARGS 0
+ push edi
+ %endmacro
+ %macro EPILOGUE_2_ARGS 1
+ pop edi
+ ret %1
+ %endmacro
+
+ %macro PROLOGUE_3_ARGS 0
+ push ebx
+ mov ebx, [esp + 4 + 4]
+ push edi
+ %endmacro
+ %macro EPILOGUE_3_ARGS 1
+ pop edi
+ pop ebx
+ ret %1
+ %endmacro
+
+ %macro PROLOGUE_4_ARGS 0
+ push ebx
+ push edi
+ push esi
+ mov ebx, [esp + 12 + 4 + 0]
+ mov esi, [esp + 12 + 4 + 4]
+ %endmacro
+ %macro EPILOGUE_4_ARGS 1
+ pop esi
+ pop edi
+ pop ebx
+ ret %1
+ %endmacro
+
+ %define A0 ecx
+ %define A0_32 ecx
+ %define A0_16 cx
+ %define A0_8 cl
+
+ %define A1 edx
+ %define A1_32 edx
+ %define A1_16 dx
+ %define A1_8 dl
+
+ %define A2 ebx
+ %define A2_32 ebx
+ %define A2_16 bx
+ %define A2_8 bl
+
+ %define A3 esi
+ %define A3_32 esi
+ %define A3_16 si
+
+ %define T0 eax
+ %define T0_32 eax
+ %define T0_16 ax
+ %define T0_8 al
+
+ %define T1 edi
+ %define T1_32 edi
+ %define T1_16 di
+%endif
+
+
+;;
+; Load the relevant flags from [%1] if there are undefined flags (%3).
+;
+; @remarks Clobbers T0, stack. Changes EFLAGS.
+; @param A2 The register pointing to the flags.
+; @param 1 The parameter (A0..A3) pointing to the eflags.
+; @param 2 The set of modified flags.
+; @param 3 The set of undefined flags.
+;
+%macro IEM_MAYBE_LOAD_FLAGS 3
+ ;%if (%3) != 0
+ pushf ; store current flags
+ mov T0_32, [%1] ; load the guest flags
+ and dword [xSP], ~(%2 | %3) ; mask out the modified and undefined flags
+ and T0_32, (%2 | %3) ; select the modified and undefined flags.
+ or [xSP], T0 ; merge guest flags with host flags.
+ popf ; load the mixed flags.
+ ;%endif
+%endmacro
+
+;;
+; Update the flag.
+;
+; @remarks Clobbers T0, T1, stack.
+; @param 1 The register pointing to the EFLAGS.
+; @param 2 The mask of modified flags to save.
+; @param 3 The mask of undefined flags to (maybe) save.
+;
+%macro IEM_SAVE_FLAGS 3
+ %if (%2 | %3) != 0
+ pushf
+ pop T1
+ mov T0_32, [%1] ; flags
+ and T0_32, ~(%2 | %3) ; clear the modified & undefined flags.
+ and T1_32, (%2 | %3) ; select the modified and undefined flags.
+ or T0_32, T1_32 ; combine the flags.
+ mov [%1], T0_32 ; save the flags.
+ %endif
+%endmacro
+
+
+;;
+; Macro for implementing a binary operator.
+;
+; This will generate code for the 8, 16, 32 and 64 bit accesses with locked
+; variants, except on 32-bit system where the 64-bit accesses requires hand
+; coding.
+;
+; All the functions takes a pointer to the destination memory operand in A0,
+; the source register operand in A1 and a pointer to eflags in A2.
+;
+; @param 1 The instruction mnemonic.
+; @param 2 Non-zero if there should be a locked version.
+; @param 3 The modified flags.
+; @param 4 The undefined flags.
+;
+%macro IEMIMPL_BIN_OP 4
+BEGINCODE
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ %1 byte [A0], A1_8
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u8
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ %1 word [A0], A1_16
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u16
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ %1 dword [A0], A1_32
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u32
+
+ %ifdef RT_ARCH_AMD64
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ %1 qword [A0], A1
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 8
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %else ; stub it for now - later, replace with hand coded stuff.
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
+ int3
+ ret
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %endif ; !RT_ARCH_AMD64
+
+ %if %2 != 0 ; locked versions requested?
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8_locked, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ lock %1 byte [A0], A1_8
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u8_locked
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_locked, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ lock %1 word [A0], A1_16
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u16_locked
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_locked, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ lock %1 dword [A0], A1_32
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u32_locked
+
+ %ifdef RT_ARCH_AMD64
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 16
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ lock %1 qword [A0], A1
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 8
+ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
+ %else ; stub it for now - later, replace with hand coded stuff.
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 16
+ int3
+ ret 8
+ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
+ %endif ; !RT_ARCH_AMD64
+ %endif ; locked
+%endmacro
+
+; instr,lock,modified-flags.
+IEMIMPL_BIN_OP add, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+IEMIMPL_BIN_OP adc, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+IEMIMPL_BIN_OP sub, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+IEMIMPL_BIN_OP sbb, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+IEMIMPL_BIN_OP or, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
+IEMIMPL_BIN_OP xor, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
+IEMIMPL_BIN_OP and, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
+IEMIMPL_BIN_OP cmp, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+IEMIMPL_BIN_OP test, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
+
+
+;;
+; Macro for implementing a bit operator.
+;
+; This will generate code for the 16, 32 and 64 bit accesses with locked
+; variants, except on 32-bit system where the 64-bit accesses requires hand
+; coding.
+;
+; All the functions takes a pointer to the destination memory operand in A0,
+; the source register operand in A1 and a pointer to eflags in A2.
+;
+; @param 1 The instruction mnemonic.
+; @param 2 Non-zero if there should be a locked version.
+; @param 3 The modified flags.
+; @param 4 The undefined flags.
+;
+%macro IEMIMPL_BIT_OP 4
+BEGINCODE
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ %1 word [A0], A1_16
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u16
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ %1 dword [A0], A1_32
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u32
+
+ %ifdef RT_ARCH_AMD64
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ %1 qword [A0], A1
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 8
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %else ; stub it for now - later, replace with hand coded stuff.
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
+ int3
+ ret 8
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %endif ; !RT_ARCH_AMD64
+
+ %if %2 != 0 ; locked versions requested?
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_locked, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ lock %1 word [A0], A1_16
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u16_locked
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_locked, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ lock %1 dword [A0], A1_32
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u32_locked
+
+ %ifdef RT_ARCH_AMD64
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 16
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %3, %4
+ lock %1 qword [A0], A1
+ IEM_SAVE_FLAGS A2, %3, %4
+ EPILOGUE_3_ARGS 8
+ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
+ %else ; stub it for now - later, replace with hand coded stuff.
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 16
+ int3
+ ret 8
+ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
+ %endif ; !RT_ARCH_AMD64
+ %endif ; locked
+%endmacro
+IEMIMPL_BIT_OP bt, 0, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
+IEMIMPL_BIT_OP btc, 1, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
+IEMIMPL_BIT_OP bts, 1, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
+IEMIMPL_BIT_OP btr, 1, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
+
+;;
+; Macro for implementing a bit search operator.
+;
+; This will generate code for the 16, 32 and 64 bit accesses, except on 32-bit
+; system where the 64-bit accesses requires hand coding.
+;
+; All the functions takes a pointer to the destination memory operand in A0,
+; the source register operand in A1 and a pointer to eflags in A2.
+;
+; @param 1 The instruction mnemonic.
+; @param 2 The modified flags.
+; @param 3 The undefined flags.
+;
+%macro IEMIMPL_BIT_OP 3
+BEGINCODE
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %2, %3
+ %1 T0_16, A1_16
+ mov [A0], T0_16
+ IEM_SAVE_FLAGS A2, %2, %3
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u16
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %2, %3
+ %1 T0_32, A1_32
+ mov [A0], T0_32
+ IEM_SAVE_FLAGS A2, %2, %3
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u32
+
+ %ifdef RT_ARCH_AMD64
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %2, %3
+ %1 T0, A1
+ mov [A0], T0
+ IEM_SAVE_FLAGS A2, %2, %3
+ EPILOGUE_3_ARGS 8
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %else ; stub it for now - later, replace with hand coded stuff.
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
+ int3
+ ret 8
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %endif ; !RT_ARCH_AMD64
+%endmacro
+IEMIMPL_BIT_OP bsf, (X86_EFL_ZF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF)
+IEMIMPL_BIT_OP bsr, (X86_EFL_ZF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF)
+
+
+;
+; IMUL is also a similar but yet different case (no lock, no mem dst).
+; The rDX:rAX variant of imul is handled together with mul further down.
+;
+BEGINCODE
+BEGINPROC_FASTCALL iemAImpl_imul_two_u16, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
+ imul A1_16, word [A0]
+ mov [A0], A1_16
+ IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_imul_two_u16
+
+BEGINPROC_FASTCALL iemAImpl_imul_two_u32, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
+ imul A1_32, dword [A0]
+ mov [A0], A1_32
+ IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_imul_two_u32
+
+BEGINPROC_FASTCALL iemAImpl_imul_two_u64, 16
+ PROLOGUE_3_ARGS
+%ifdef RT_ARCH_AMD64
+ IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
+ imul A1, qword [A0]
+ mov [A0], A1
+ IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
+%else
+ int3 ;; @todo implement me
+%endif
+ EPILOGUE_3_ARGS 8
+ENDPROC iemAImpl_imul_two_u64
+
+
+;
+; XCHG for memory operands. This implies locking. No flag changes.
+;
+; Each function takes two arguments, first the pointer to the memory,
+; then the pointer to the register. They all return void.
+;
+BEGINCODE
+BEGINPROC_FASTCALL iemAImpl_xchg_u8, 8
+ PROLOGUE_2_ARGS
+ mov T0_8, [A1]
+ xchg [A0], T0_8
+ mov [A1], T0_8
+ EPILOGUE_2_ARGS 0
+ENDPROC iemAImpl_xchg_u8
+
+BEGINPROC_FASTCALL iemAImpl_xchg_u16, 8
+ PROLOGUE_2_ARGS
+ mov T0_16, [A1]
+ xchg [A0], T0_16
+ mov [A1], T0_16
+ EPILOGUE_2_ARGS 0
+ENDPROC iemAImpl_xchg_u16
+
+BEGINPROC_FASTCALL iemAImpl_xchg_u32, 8
+ PROLOGUE_2_ARGS
+ mov T0_32, [A1]
+ xchg [A0], T0_32
+ mov [A1], T0_32
+ EPILOGUE_2_ARGS 0
+ENDPROC iemAImpl_xchg_u32
+
+BEGINPROC_FASTCALL iemAImpl_xchg_u64, 8
+%ifdef RT_ARCH_AMD64
+ PROLOGUE_2_ARGS
+ mov T0, [A1]
+ xchg [A0], T0
+ mov [A1], T0
+ EPILOGUE_2_ARGS 0
+%else
+ int3
+ ret 0
+%endif
+ENDPROC iemAImpl_xchg_u64
+
+
+;
+; XADD for memory operands.
+;
+; Each function takes three arguments, first the pointer to the
+; memory/register, then the pointer to the register, and finally a pointer to
+; eflags. They all return void.
+;
+BEGINCODE
+BEGINPROC_FASTCALL iemAImpl_xadd_u8, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ mov T0_8, [A1]
+ xadd [A0], T0_8
+ mov [A1], T0_8
+ IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_xadd_u8
+
+BEGINPROC_FASTCALL iemAImpl_xadd_u16, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ mov T0_16, [A1]
+ xadd [A0], T0_16
+ mov [A1], T0_16
+ IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_xadd_u16
+
+BEGINPROC_FASTCALL iemAImpl_xadd_u32, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ mov T0_32, [A1]
+ xadd [A0], T0_32
+ mov [A1], T0_32
+ IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_xadd_u32
+
+BEGINPROC_FASTCALL iemAImpl_xadd_u64, 12
+%ifdef RT_ARCH_AMD64
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ mov T0, [A1]
+ xadd [A0], T0
+ mov [A1], T0
+ IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ EPILOGUE_3_ARGS 4
+%else
+ int3
+ ret 4
+%endif
+ENDPROC iemAImpl_xadd_u64
+
+BEGINPROC_FASTCALL iemAImpl_xadd_u8_locked, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ mov T0_8, [A1]
+ lock xadd [A0], T0_8
+ mov [A1], T0_8
+ IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_xadd_u8_locked
+
+BEGINPROC_FASTCALL iemAImpl_xadd_u16_locked, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ mov T0_16, [A1]
+ lock xadd [A0], T0_16
+ mov [A1], T0_16
+ IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_xadd_u16_locked
+
+BEGINPROC_FASTCALL iemAImpl_xadd_u32_locked, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ mov T0_32, [A1]
+ lock xadd [A0], T0_32
+ mov [A1], T0_32
+ IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_xadd_u32_locked
+
+BEGINPROC_FASTCALL iemAImpl_xadd_u64_locked, 12
+%ifdef RT_ARCH_AMD64
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ mov T0, [A1]
+ lock xadd [A0], T0
+ mov [A1], T0
+ IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+ EPILOGUE_3_ARGS 4
+%else
+ int3
+ ret 4
+%endif
+ENDPROC iemAImpl_xadd_u64_locked
+
+
+;;
+; Macro for implementing a unary operator.
+;
+; This will generate code for the 8, 16, 32 and 64 bit accesses with locked
+; variants, except on 32-bit system where the 64-bit accesses requires hand
+; coding.
+;
+; All the functions takes a pointer to the destination memory operand in A0,
+; the source register operand in A1 and a pointer to eflags in A2.
+;
+; @param 1 The instruction mnemonic.
+; @param 2 The modified flags.
+; @param 3 The undefined flags.
+;
+%macro IEMIMPL_UNARY_OP 3
+BEGINCODE
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 8
+ PROLOGUE_2_ARGS
+ IEM_MAYBE_LOAD_FLAGS A1, %2, %3
+ %1 byte [A0]
+ IEM_SAVE_FLAGS A1, %2, %3
+ EPILOGUE_2_ARGS 0
+ENDPROC iemAImpl_ %+ %1 %+ _u8
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8_locked, 8
+ PROLOGUE_2_ARGS
+ IEM_MAYBE_LOAD_FLAGS A1, %2, %3
+ lock %1 byte [A0]
+ IEM_SAVE_FLAGS A1, %2, %3
+ EPILOGUE_2_ARGS 0
+ENDPROC iemAImpl_ %+ %1 %+ _u8_locked
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 8
+ PROLOGUE_2_ARGS
+ IEM_MAYBE_LOAD_FLAGS A1, %2, %3
+ %1 word [A0]
+ IEM_SAVE_FLAGS A1, %2, %3
+ EPILOGUE_2_ARGS 0
+ENDPROC iemAImpl_ %+ %1 %+ _u16
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_locked, 8
+ PROLOGUE_2_ARGS
+ IEM_MAYBE_LOAD_FLAGS A1, %2, %3
+ lock %1 word [A0]
+ IEM_SAVE_FLAGS A1, %2, %3
+ EPILOGUE_2_ARGS 0
+ENDPROC iemAImpl_ %+ %1 %+ _u16_locked
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 8
+ PROLOGUE_2_ARGS
+ IEM_MAYBE_LOAD_FLAGS A1, %2, %3
+ %1 dword [A0]
+ IEM_SAVE_FLAGS A1, %2, %3
+ EPILOGUE_2_ARGS 0
+ENDPROC iemAImpl_ %+ %1 %+ _u32
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_locked, 8
+ PROLOGUE_2_ARGS
+ IEM_MAYBE_LOAD_FLAGS A1, %2, %3
+ lock %1 dword [A0]
+ IEM_SAVE_FLAGS A1, %2, %3
+ EPILOGUE_2_ARGS 0
+ENDPROC iemAImpl_ %+ %1 %+ _u32_locked
+
+ %ifdef RT_ARCH_AMD64
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 8
+ PROLOGUE_2_ARGS
+ IEM_MAYBE_LOAD_FLAGS A1, %2, %3
+ %1 qword [A0]
+ IEM_SAVE_FLAGS A1, %2, %3
+ EPILOGUE_2_ARGS 0
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 8
+ PROLOGUE_2_ARGS
+ IEM_MAYBE_LOAD_FLAGS A1, %2, %3
+ lock %1 qword [A0]
+ IEM_SAVE_FLAGS A1, %2, %3
+ EPILOGUE_2_ARGS 0
+ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
+ %else
+ ; stub them for now.
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 8
+ int3
+ ret 0
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 8
+ int3
+ ret 0
+ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
+ %endif
+
+%endmacro
+
+IEMIMPL_UNARY_OP inc, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF), 0
+IEMIMPL_UNARY_OP dec, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF), 0
+IEMIMPL_UNARY_OP neg, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
+IEMIMPL_UNARY_OP not, 0, 0
+
+
+
+;;
+; Macro for implementing a shift operation.
+;
+; This will generate code for the 8, 16, 32 and 64 bit accesses, except on
+; 32-bit system where the 64-bit accesses requires hand coding.
+;
+; All the functions takes a pointer to the destination memory operand in A0,
+; the shift count in A1 and a pointer to eflags in A2.
+;
+; @param 1 The instruction mnemonic.
+; @param 2 The modified flags.
+; @param 3 The undefined flags.
+;
+; Makes ASSUMPTIONS about A0, A1 and A2 assignments.
+;
+%macro IEMIMPL_SHIFT_OP 3
+BEGINCODE
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %2, %3
+ %ifdef ASM_CALL64_GCC
+ mov cl, A1_8
+ %1 byte [A0], cl
+ %else
+ xchg A1, A0
+ %1 byte [A1], cl
+ %endif
+ IEM_SAVE_FLAGS A2, %2, %3
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u8
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %2, %3
+ %ifdef ASM_CALL64_GCC
+ mov cl, A1_8
+ %1 word [A0], cl
+ %else
+ xchg A1, A0
+ %1 word [A1], cl
+ %endif
+ IEM_SAVE_FLAGS A2, %2, %3
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u16
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %2, %3
+ %ifdef ASM_CALL64_GCC
+ mov cl, A1_8
+ %1 dword [A0], cl
+ %else
+ xchg A1, A0
+ %1 dword [A1], cl
+ %endif
+ IEM_SAVE_FLAGS A2, %2, %3
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u32
+
+ %ifdef RT_ARCH_AMD64
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %2, %3
+ %ifdef ASM_CALL64_GCC
+ mov cl, A1_8
+ %1 qword [A0], cl
+ %else
+ xchg A1, A0
+ %1 qword [A1], cl
+ %endif
+ IEM_SAVE_FLAGS A2, %2, %3
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %else ; stub it for now - later, replace with hand coded stuff.
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 12
+ int3
+ ret 4
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %endif ; !RT_ARCH_AMD64
+
+%endmacro
+
+IEMIMPL_SHIFT_OP rol, (X86_EFL_OF | X86_EFL_CF), 0
+IEMIMPL_SHIFT_OP ror, (X86_EFL_OF | X86_EFL_CF), 0
+IEMIMPL_SHIFT_OP rcl, (X86_EFL_OF | X86_EFL_CF), 0
+IEMIMPL_SHIFT_OP rcr, (X86_EFL_OF | X86_EFL_CF), 0
+IEMIMPL_SHIFT_OP shl, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
+IEMIMPL_SHIFT_OP shr, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
+IEMIMPL_SHIFT_OP sar, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
+
+
+;;
+; Macro for implementing a double precision shift operation.
+;
+; This will generate code for the 16, 32 and 64 bit accesses, except on
+; 32-bit system where the 64-bit accesses requires hand coding.
+;
+; The functions takes the destination operand (r/m) in A0, the source (reg) in
+; A1, the shift count in A2 and a pointer to the eflags variable/register in A3.
+;
+; @param 1 The instruction mnemonic.
+; @param 2 The modified flags.
+; @param 3 The undefined flags.
+;
+; Makes ASSUMPTIONS about A0, A1, A2 and A3 assignments.
+;
+%macro IEMIMPL_SHIFT_DBL_OP 3
+BEGINCODE
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 16
+ PROLOGUE_4_ARGS
+ IEM_MAYBE_LOAD_FLAGS A3, %2, %3
+ %ifdef ASM_CALL64_GCC
+ xchg A3, A2
+ %1 [A0], A1_16, cl
+ xchg A3, A2
+ %else
+ xchg A0, A2
+ %1 [A2], A1_16, cl
+ %endif
+ IEM_SAVE_FLAGS A3, %2, %3
+ EPILOGUE_4_ARGS 8
+ENDPROC iemAImpl_ %+ %1 %+ _u16
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
+ PROLOGUE_4_ARGS
+ IEM_MAYBE_LOAD_FLAGS A3, %2, %3
+ %ifdef ASM_CALL64_GCC
+ xchg A3, A2
+ %1 [A0], A1_32, cl
+ xchg A3, A2
+ %else
+ xchg A0, A2
+ %1 [A2], A1_32, cl
+ %endif
+ IEM_SAVE_FLAGS A3, %2, %3
+ EPILOGUE_4_ARGS 8
+ENDPROC iemAImpl_ %+ %1 %+ _u32
+
+ %ifdef RT_ARCH_AMD64
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
+ PROLOGUE_4_ARGS
+ IEM_MAYBE_LOAD_FLAGS A3, %2, %3
+ %ifdef ASM_CALL64_GCC
+ xchg A3, A2
+ %1 [A0], A1, cl
+ xchg A3, A2
+ %else
+ xchg A0, A2
+ %1 [A2], A1, cl
+ %endif
+ IEM_SAVE_FLAGS A3, %2, %3
+ EPILOGUE_4_ARGS 12
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %else ; stub it for now - later, replace with hand coded stuff.
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
+ int3
+ ret 12
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %endif ; !RT_ARCH_AMD64
+
+%endmacro
+
+IEMIMPL_SHIFT_DBL_OP shld, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
+IEMIMPL_SHIFT_DBL_OP shrd, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
+
+
+;;
+; Macro for implementing a multiplication operations.
+;
+; This will generate code for the 8, 16, 32 and 64 bit accesses, except on
+; 32-bit system where the 64-bit accesses requires hand coding.
+;
+; The 8-bit function only operates on AX, so it takes no DX pointer. The other
+; functions takes a pointer to rAX in A0, rDX in A1, the operand in A2 and a
+; pointer to eflags in A3.
+;
+; The functions all return 0 so the caller can be used for div/idiv as well as
+; for the mul/imul implementation.
+;
+; @param 1 The instruction mnemonic.
+; @param 2 The modified flags.
+; @param 3 The undefined flags.
+;
+; Makes ASSUMPTIONS about A0, A1, A2, A3, T0 and T1 assignments.
+;
+%macro IEMIMPL_MUL_OP 3
+BEGINCODE
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
+ PROLOGUE_3_ARGS
+ IEM_MAYBE_LOAD_FLAGS A2, %2, %3
+ mov al, [A0]
+ %1 A1_8
+ mov [A0], ax
+ IEM_SAVE_FLAGS A2, %2, %3
+ xor eax, eax
+ EPILOGUE_3_ARGS 4
+ENDPROC iemAImpl_ %+ %1 %+ _u8
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 16
+ PROLOGUE_4_ARGS
+ IEM_MAYBE_LOAD_FLAGS A3, %2, %3
+ mov ax, [A0]
+ %ifdef ASM_CALL64_GCC
+ %1 A2_16
+ mov [A0], ax
+ mov [A1], dx
+ %else
+ mov T1, A1
+ %1 A2_16
+ mov [A0], ax
+ mov [T1], dx
+ %endif
+ IEM_SAVE_FLAGS A3, %2, %3
+ xor eax, eax
+ EPILOGUE_4_ARGS 8
+ENDPROC iemAImpl_ %+ %1 %+ _u16
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
+ PROLOGUE_4_ARGS
+ IEM_MAYBE_LOAD_FLAGS A3, %2, %3
+ mov eax, [A0]
+ %ifdef ASM_CALL64_GCC
+ %1 A2_32
+ mov [A0], eax
+ mov [A1], edx
+ %else
+ mov T1, A1
+ %1 A2_32
+ mov [A0], eax
+ mov [T1], edx
+ %endif
+ IEM_SAVE_FLAGS A3, %2, %3
+ xor eax, eax
+ EPILOGUE_4_ARGS 8
+ENDPROC iemAImpl_ %+ %1 %+ _u32
+
+ %ifdef RT_ARCH_AMD64
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
+ PROLOGUE_4_ARGS
+ IEM_MAYBE_LOAD_FLAGS A3, %2, %3
+ mov rax, [A0]
+ %ifdef ASM_CALL64_GCC
+ %1 A2
+ mov [A0], rax
+ mov [A1], rdx
+ %else
+ mov T1, A1
+ %1 A2
+ mov [A0], rax
+ mov [T1], rdx
+ %endif
+ IEM_SAVE_FLAGS A3, %2, %3
+ xor eax, eax
+ EPILOGUE_4_ARGS 12
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %else ; stub it for now - later, replace with hand coded stuff.
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
+ int3
+ ret 12
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %endif ; !RT_ARCH_AMD64
+
+%endmacro
+
+IEMIMPL_MUL_OP mul, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
+IEMIMPL_MUL_OP imul, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
+
+
+;;
+; Macro for implementing a division operations.
+;
+; This will generate code for the 8, 16, 32 and 64 bit accesses, except on
+; 32-bit system where the 64-bit accesses requires hand coding.
+;
+; The 8-bit function only operates on AX, so it takes no DX pointer. The other
+; functions takes a pointer to rAX in A0, rDX in A1, the operand in A2 and a
+; pointer to eflags in A3.
+;
+; The functions all return 0 on success and -1 if a divide error should be
+; raised by the caller.
+;
+; @param 1 The instruction mnemonic.
+; @param 2 The modified flags.
+; @param 3 The undefined flags.
+;
+; Makes ASSUMPTIONS about A0, A1, A2, A3, T0 and T1 assignments.
+;
+%macro IEMIMPL_DIV_OP 3
+BEGINCODE
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
+ PROLOGUE_3_ARGS
+
+ test A1_8, A1_8
+ jz .div_zero
+ ;; @todo test for overflow
+
+ IEM_MAYBE_LOAD_FLAGS A2, %2, %3
+ mov ax, [A0]
+ %1 A1_8
+ mov [A0], ax
+ IEM_SAVE_FLAGS A2, %2, %3
+ xor eax, eax
+
+.return:
+ EPILOGUE_3_ARGS 4
+
+.div_zero:
+ mov eax, -1
+ jmp .return
+ENDPROC iemAImpl_ %+ %1 %+ _u8
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 16
+ PROLOGUE_4_ARGS
+
+ test A1_16, A1_16
+ jz .div_zero
+ ;; @todo test for overflow
+
+ IEM_MAYBE_LOAD_FLAGS A3, %2, %3
+ %ifdef ASM_CALL64_GCC
+ mov T1, A2
+ mov ax, [A0]
+ mov dx, [A1]
+ %1 T1_16
+ mov [A0], ax
+ mov [A1], dx
+ %else
+ mov T1, A1
+ mov ax, [A0]
+ mov dx, [T1]
+ %1 A2_16
+ mov [A0], ax
+ mov [T1], dx
+ %endif
+ IEM_SAVE_FLAGS A3, %2, %3
+ xor eax, eax
+
+.return:
+ EPILOGUE_4_ARGS 8
+
+.div_zero:
+ mov eax, -1
+ jmp .return
+ENDPROC iemAImpl_ %+ %1 %+ _u16
+
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
+ PROLOGUE_4_ARGS
+
+ test A1_32, A1_32
+ jz .div_zero
+ ;; @todo test for overflow
+
+ IEM_MAYBE_LOAD_FLAGS A3, %2, %3
+ mov eax, [A0]
+ %ifdef ASM_CALL64_GCC
+ mov T1, A2
+ mov eax, [A0]
+ mov edx, [A1]
+ %1 T1_32
+ mov [A0], eax
+ mov [A1], edx
+ %else
+ mov T1, A1
+ mov eax, [A0]
+ mov edx, [T1]
+ %1 A2_32
+ mov [A0], eax
+ mov [T1], edx
+ %endif
+ IEM_SAVE_FLAGS A3, %2, %3
+ xor eax, eax
+
+.return:
+ EPILOGUE_4_ARGS 8
+
+.div_zero:
+ mov eax, -1
+ jmp .return
+ENDPROC iemAImpl_ %+ %1 %+ _u32
+
+ %ifdef RT_ARCH_AMD64
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
+ PROLOGUE_4_ARGS
+
+ test A1, A1
+ jz .div_zero
+ ;; @todo test for overflow
+
+ IEM_MAYBE_LOAD_FLAGS A3, %2, %3
+ mov rax, [A0]
+ %ifdef ASM_CALL64_GCC
+ mov T1, A2
+ mov rax, [A0]
+ mov rdx, [A1]
+ %1 T1
+ mov [A0], rax
+ mov [A1], rdx
+ %else
+ mov T1, A1
+ mov rax, [A0]
+ mov rdx, [T1]
+ %1 A2
+ mov [A0], rax
+ mov [T1], rdx
+ %endif
+ IEM_SAVE_FLAGS A3, %2, %3
+ xor eax, eax
+
+.return:
+ EPILOGUE_4_ARGS 12
+
+.div_zero:
+ mov eax, -1
+ jmp .return
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %else ; stub it for now - later, replace with hand coded stuff.
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
+ int3
+ ret
+ENDPROC iemAImpl_ %+ %1 %+ _u64
+ %endif ; !RT_ARCH_AMD64
+
+%endmacro
+
+IEMIMPL_DIV_OP div, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF)
+IEMIMPL_DIV_OP idiv, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF)
+
diff --git a/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp b/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
new file mode 100644
index 000000000..45fc1e871
--- /dev/null
+++ b/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
@@ -0,0 +1,48 @@
+/* $Id: IEMAllAImplC.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
+/** @file
+ * IEM - Instruction Implementation in Assembly, portable C variant.
+ */
+
+/*
+ * 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 "IEMInternal.h"
+#include <VBox/vmm/vm.h>
+#include <iprt/x86.h>
+
+#if 0
+
+
+IEM_DECL_IMPL_DEF(void, iemImpl_add_u8,(uint8_t *pu8Dst, uint8_t u8Src, uint32_t *pEFlags))
+{
+ /* incorrect sketch (testing fastcall + gcc) */
+ uint8_t u8Dst = *pu8Dst;
+ uint8_t u8Res = u8Dst + u8Src;
+ *pu8Dst = u8Res;
+
+ if (u8Res)
+ *pEFlags &= X86_EFL_ZF;
+ else
+ *pEFlags |= X86_EFL_ZF;
+}
+
+IEM_DECL_IMPL_DEF(void, iemImpl_add_u8_locked,(uint8_t *pu8Dst, uint8_t u8Src, uint32_t *pEFlags))
+{
+ iemImpl_add_u8(pu8Dst, u8Src, pEFlags);
+}
+
+
+#endif
+
diff --git a/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h b/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
new file mode 100644
index 000000000..fc880350c
--- /dev/null
+++ b/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
@@ -0,0 +1,3045 @@
+/* $Id: IEMAllCImpl.cpp.h 37918 2011-07-13 13:38:33Z vboxsync $ */
+/** @file
+ * IEM - Instruction Implementation in C/C++ (code include).
+ */
+
+/*
+ * 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.
+ */
+
+
+/** @name Misc Helpers
+ * @{
+ */
+
+/**
+ * Checks if we are allowed to access the given I/O port, raising the
+ * appropriate exceptions if we aren't (or if the I/O bitmap is not
+ * accessible).
+ *
+ * @returns Strict VBox status code.
+ *
+ * @param pIemCpu The IEM per CPU data.
+ * @param pCtx The register context.
+ * @param u16Port The port number.
+ * @param cbOperand The operand size.
+ */
+DECLINLINE(VBOXSTRICTRC) iemHlpCheckPortIOPermission(PIEMCPU pIemCpu, PCCPUMCTX pCtx, uint16_t u16Port, uint8_t cbOperand)
+{
+ if ( (pCtx->cr0 & X86_CR0_PE)
+ && ( pIemCpu->uCpl > pCtx->eflags.Bits.u2IOPL
+ || pCtx->eflags.Bits.u1VM) )
+ {
+ /** @todo I/O port permission bitmap check */
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+ }
+ return VINF_SUCCESS;
+}
+
+
+#if 0
+/**
+ * Calculates the parity bit.
+ *
+ * @returns true if the bit is set, false if not.
+ * @param u8Result The least significant byte of the result.
+ */
+static bool iemHlpCalcParityFlag(uint8_t u8Result)
+{
+ /*
+ * Parity is set if the number of bits in the least significant byte of
+ * the result is even.
+ */
+ uint8_t cBits;
+ cBits = u8Result & 1; /* 0 */
+ u8Result >>= 1;
+ cBits += u8Result & 1;
+ u8Result >>= 1;
+ cBits += u8Result & 1;
+ u8Result >>= 1;
+ cBits += u8Result & 1;
+ u8Result >>= 1;
+ cBits += u8Result & 1; /* 4 */
+ u8Result >>= 1;
+ cBits += u8Result & 1;
+ u8Result >>= 1;
+ cBits += u8Result & 1;
+ u8Result >>= 1;
+ cBits += u8Result & 1;
+ return !(cBits & 1);
+}
+#endif /* not used */
+
+
+/**
+ * Updates the specified flags according to a 8-bit result.
+ *
+ * @param pIemCpu The.
+ * @param u8Result The result to set the flags according to.
+ * @param fToUpdate The flags to update.
+ * @param fUndefined The flags that are specified as undefined.
+ */
+static void iemHlpUpdateArithEFlagsU8(PIEMCPU pIemCpu, uint8_t u8Result, uint32_t fToUpdate, uint32_t fUndefined)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ uint32_t fEFlags = pCtx->eflags.u;
+ iemAImpl_test_u8(&u8Result, u8Result, &fEFlags);
+ pCtx->eflags.u &= ~(fToUpdate | fUndefined);
+ pCtx->eflags.u |= (fToUpdate | fUndefined) & fEFlags;
+}
+
+
+/** @} */
+
+/** @name C Implementations
+ * @{
+ */
+
+/**
+ * Implements a 16-bit popa.
+ */
+IEM_CIMPL_DEF_0(iemCImpl_popa_16)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTGCPTR GCPtrStart = iemRegGetEffRsp(pCtx);
+ RTGCPTR GCPtrLast = GCPtrStart + 15;
+ VBOXSTRICTRC rcStrict;
+
+ /*
+ * The docs are a bit hard to comprehend here, but it looks like we wrap
+ * around in real mode as long as none of the individual "popa" crosses the
+ * end of the stack segment. In protected mode we check the whole access
+ * in one go. For efficiency, only do the word-by-word thing if we're in
+ * danger of wrapping around.
+ */
+ /** @todo do popa boundary / wrap-around checks. */
+ if (RT_UNLIKELY( IEM_IS_REAL_OR_V86_MODE(pIemCpu)
+ && (pCtx->csHid.u32Limit < GCPtrLast)) ) /* ASSUMES 64-bit RTGCPTR */
+ {
+ /* word-by-word */
+ RTUINT64U TmpRsp;
+ TmpRsp.u = pCtx->rsp;
+ rcStrict = iemMemStackPopU16Ex(pIemCpu, &pCtx->di, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPopU16Ex(pIemCpu, &pCtx->si, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPopU16Ex(pIemCpu, &pCtx->bp, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ iemRegAddToRspEx(&TmpRsp, 2, pCtx); /* sp */
+ rcStrict = iemMemStackPopU16Ex(pIemCpu, &pCtx->bx, &TmpRsp);
+ }
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPopU16Ex(pIemCpu, &pCtx->dx, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPopU16Ex(pIemCpu, &pCtx->cx, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPopU16Ex(pIemCpu, &pCtx->ax, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ pCtx->rsp = TmpRsp.u;
+ iemRegAddToRip(pIemCpu, cbInstr);
+ }
+ }
+ else
+ {
+ uint16_t const *pa16Mem = NULL;
+ rcStrict = iemMemMap(pIemCpu, (void **)&pa16Mem, 16, X86_SREG_SS, GCPtrStart, IEM_ACCESS_STACK_R);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ pCtx->di = pa16Mem[7 - X86_GREG_xDI];
+ pCtx->si = pa16Mem[7 - X86_GREG_xSI];
+ pCtx->bp = pa16Mem[7 - X86_GREG_xBP];
+ /* skip sp */
+ pCtx->bx = pa16Mem[7 - X86_GREG_xBX];
+ pCtx->dx = pa16Mem[7 - X86_GREG_xDX];
+ pCtx->cx = pa16Mem[7 - X86_GREG_xCX];
+ pCtx->ax = pa16Mem[7 - X86_GREG_xAX];
+ rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)pa16Mem, IEM_ACCESS_STACK_R);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ iemRegAddToRsp(pCtx, 16);
+ iemRegAddToRip(pIemCpu, cbInstr);
+ }
+ }
+ }
+ return rcStrict;
+}
+
+
+/**
+ * Implements a 32-bit popa.
+ */
+IEM_CIMPL_DEF_0(iemCImpl_popa_32)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTGCPTR GCPtrStart = iemRegGetEffRsp(pCtx);
+ RTGCPTR GCPtrLast = GCPtrStart + 31;
+ VBOXSTRICTRC rcStrict;
+
+ /*
+ * The docs are a bit hard to comprehend here, but it looks like we wrap
+ * around in real mode as long as none of the individual "popa" crosses the
+ * end of the stack segment. In protected mode we check the whole access
+ * in one go. For efficiency, only do the word-by-word thing if we're in
+ * danger of wrapping around.
+ */
+ /** @todo do popa boundary / wrap-around checks. */
+ if (RT_UNLIKELY( IEM_IS_REAL_OR_V86_MODE(pIemCpu)
+ && (pCtx->csHid.u32Limit < GCPtrLast)) ) /* ASSUMES 64-bit RTGCPTR */
+ {
+ /* word-by-word */
+ RTUINT64U TmpRsp;
+ TmpRsp.u = pCtx->rsp;
+ rcStrict = iemMemStackPopU32Ex(pIemCpu, &pCtx->edi, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPopU32Ex(pIemCpu, &pCtx->esi, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPopU32Ex(pIemCpu, &pCtx->ebp, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ iemRegAddToRspEx(&TmpRsp, 2, pCtx); /* sp */
+ rcStrict = iemMemStackPopU32Ex(pIemCpu, &pCtx->ebx, &TmpRsp);
+ }
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPopU32Ex(pIemCpu, &pCtx->edx, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPopU32Ex(pIemCpu, &pCtx->ecx, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPopU32Ex(pIemCpu, &pCtx->eax, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ {
+#if 1 /** @todo what actually happens with the high bits when we're in 16-bit mode? */
+ pCtx->rdi &= UINT32_MAX;
+ pCtx->rsi &= UINT32_MAX;
+ pCtx->rbp &= UINT32_MAX;
+ pCtx->rbx &= UINT32_MAX;
+ pCtx->rdx &= UINT32_MAX;
+ pCtx->rcx &= UINT32_MAX;
+ pCtx->rax &= UINT32_MAX;
+#endif
+ pCtx->rsp = TmpRsp.u;
+ iemRegAddToRip(pIemCpu, cbInstr);
+ }
+ }
+ else
+ {
+ uint32_t const *pa32Mem;
+ rcStrict = iemMemMap(pIemCpu, (void **)&pa32Mem, 32, X86_SREG_SS, GCPtrStart, IEM_ACCESS_STACK_R);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ pCtx->rdi = pa32Mem[7 - X86_GREG_xDI];
+ pCtx->rsi = pa32Mem[7 - X86_GREG_xSI];
+ pCtx->rbp = pa32Mem[7 - X86_GREG_xBP];
+ /* skip esp */
+ pCtx->rbx = pa32Mem[7 - X86_GREG_xBX];
+ pCtx->rdx = pa32Mem[7 - X86_GREG_xDX];
+ pCtx->rcx = pa32Mem[7 - X86_GREG_xCX];
+ pCtx->rax = pa32Mem[7 - X86_GREG_xAX];
+ rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)pa32Mem, IEM_ACCESS_STACK_R);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ iemRegAddToRsp(pCtx, 32);
+ iemRegAddToRip(pIemCpu, cbInstr);
+ }
+ }
+ }
+ return rcStrict;
+}
+
+
+/**
+ * Implements a 16-bit pusha.
+ */
+IEM_CIMPL_DEF_0(iemCImpl_pusha_16)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTGCPTR GCPtrTop = iemRegGetEffRsp(pCtx);
+ RTGCPTR GCPtrBottom = GCPtrTop - 15;
+ VBOXSTRICTRC rcStrict;
+
+ /*
+ * The docs are a bit hard to comprehend here, but it looks like we wrap
+ * around in real mode as long as none of the individual "pushd" crosses the
+ * end of the stack segment. In protected mode we check the whole access
+ * in one go. For efficiency, only do the word-by-word thing if we're in
+ * danger of wrapping around.
+ */
+ /** @todo do pusha boundary / wrap-around checks. */
+ if (RT_UNLIKELY( GCPtrBottom > GCPtrTop
+ && IEM_IS_REAL_OR_V86_MODE(pIemCpu) ) )
+ {
+ /* word-by-word */
+ RTUINT64U TmpRsp;
+ TmpRsp.u = pCtx->rsp;
+ rcStrict = iemMemStackPushU16Ex(pIemCpu, pCtx->ax, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU16Ex(pIemCpu, pCtx->cx, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU16Ex(pIemCpu, pCtx->dx, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU16Ex(pIemCpu, pCtx->bx, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU16Ex(pIemCpu, pCtx->sp, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU16Ex(pIemCpu, pCtx->bp, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU16Ex(pIemCpu, pCtx->si, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU16Ex(pIemCpu, pCtx->di, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ pCtx->rsp = TmpRsp.u;
+ iemRegAddToRip(pIemCpu, cbInstr);
+ }
+ }
+ else
+ {
+ GCPtrBottom--;
+ uint16_t *pa16Mem = NULL;
+ rcStrict = iemMemMap(pIemCpu, (void **)&pa16Mem, 16, X86_SREG_SS, GCPtrBottom, IEM_ACCESS_STACK_W);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ pa16Mem[7 - X86_GREG_xDI] = pCtx->di;
+ pa16Mem[7 - X86_GREG_xSI] = pCtx->si;
+ pa16Mem[7 - X86_GREG_xBP] = pCtx->bp;
+ pa16Mem[7 - X86_GREG_xSP] = pCtx->sp;
+ pa16Mem[7 - X86_GREG_xBX] = pCtx->bx;
+ pa16Mem[7 - X86_GREG_xDX] = pCtx->dx;
+ pa16Mem[7 - X86_GREG_xCX] = pCtx->cx;
+ pa16Mem[7 - X86_GREG_xAX] = pCtx->ax;
+ rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)pa16Mem, IEM_ACCESS_STACK_W);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ iemRegSubFromRsp(pCtx, 16);
+ iemRegAddToRip(pIemCpu, cbInstr);
+ }
+ }
+ }
+ return rcStrict;
+}
+
+
+/**
+ * Implements a 32-bit pusha.
+ */
+IEM_CIMPL_DEF_0(iemCImpl_pusha_32)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ RTGCPTR GCPtrTop = iemRegGetEffRsp(pCtx);
+ RTGCPTR GCPtrBottom = GCPtrTop - 31;
+ VBOXSTRICTRC rcStrict;
+
+ /*
+ * The docs are a bit hard to comprehend here, but it looks like we wrap
+ * around in real mode as long as none of the individual "pusha" crosses the
+ * end of the stack segment. In protected mode we check the whole access
+ * in one go. For efficiency, only do the word-by-word thing if we're in
+ * danger of wrapping around.
+ */
+ /** @todo do pusha boundary / wrap-around checks. */
+ if (RT_UNLIKELY( GCPtrBottom > GCPtrTop
+ && IEM_IS_REAL_OR_V86_MODE(pIemCpu) ) )
+ {
+ /* word-by-word */
+ RTUINT64U TmpRsp;
+ TmpRsp.u = pCtx->rsp;
+ rcStrict = iemMemStackPushU32Ex(pIemCpu, pCtx->eax, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU32Ex(pIemCpu, pCtx->ecx, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU32Ex(pIemCpu, pCtx->edx, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU32Ex(pIemCpu, pCtx->ebx, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU32Ex(pIemCpu, pCtx->esp, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU32Ex(pIemCpu, pCtx->ebp, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU32Ex(pIemCpu, pCtx->esi, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStackPushU32Ex(pIemCpu, pCtx->edi, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ pCtx->rsp = TmpRsp.u;
+ iemRegAddToRip(pIemCpu, cbInstr);
+ }
+ }
+ else
+ {
+ GCPtrBottom--;
+ uint32_t *pa32Mem;
+ rcStrict = iemMemMap(pIemCpu, (void **)&pa32Mem, 32, X86_SREG_SS, GCPtrBottom, IEM_ACCESS_STACK_W);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ pa32Mem[7 - X86_GREG_xDI] = pCtx->edi;
+ pa32Mem[7 - X86_GREG_xSI] = pCtx->esi;
+ pa32Mem[7 - X86_GREG_xBP] = pCtx->ebp;
+ pa32Mem[7 - X86_GREG_xSP] = pCtx->esp;
+ pa32Mem[7 - X86_GREG_xBX] = pCtx->ebx;
+ pa32Mem[7 - X86_GREG_xDX] = pCtx->edx;
+ pa32Mem[7 - X86_GREG_xCX] = pCtx->ecx;
+ pa32Mem[7 - X86_GREG_xAX] = pCtx->eax;
+ rcStrict = iemMemCommitAndUnmap(pIemCpu, pa32Mem, IEM_ACCESS_STACK_W);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ iemRegSubFromRsp(pCtx, 32);
+ iemRegAddToRip(pIemCpu, cbInstr);
+ }
+ }
+ }
+ return rcStrict;
+}
+
+
+/**
+ * Implements pushf.
+ *
+ *
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_pushf, IEMMODE, enmEffOpSize)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * If we're in V8086 mode some care is required (which is why we're in
+ * doing this in a C implementation).
+ */
+ uint32_t fEfl = pCtx->eflags.u;
+ if ( (fEfl & X86_EFL_VM)
+ && X86_EFL_GET_IOPL(fEfl) != 3 )
+ {
+ Assert(pCtx->cr0 & X86_CR0_PE);
+ if ( enmEffOpSize != IEMMODE_16BIT
+ || !(pCtx->cr4 & X86_CR4_VME))
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ fEfl &= ~X86_EFL_IF; /* (RF and VM are out of range) */
+ fEfl |= (fEfl & X86_EFL_VIF) >> (19 - 9);
+ return iemMemStackPushU16(pIemCpu, (uint16_t)fEfl);
+ }
+
+ /*
+ * Ok, clear RF and VM and push the flags.
+ */
+ fEfl &= ~(X86_EFL_RF | X86_EFL_VM);
+
+ VBOXSTRICTRC rcStrict;
+ switch (enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ rcStrict = iemMemStackPushU16(pIemCpu, (uint16_t)fEfl);
+ break;
+ case IEMMODE_32BIT:
+ rcStrict = iemMemStackPushU32(pIemCpu, fEfl);
+ break;
+ case IEMMODE_64BIT:
+ rcStrict = iemMemStackPushU64(pIemCpu, fEfl);
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements popf.
+ *
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_popf, IEMMODE, enmEffOpSize)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint32_t const fEflOld = pCtx->eflags.u;
+ VBOXSTRICTRC rcStrict;
+ uint32_t fEflNew;
+
+ /*
+ * V8086 is special as usual.
+ */
+ if (fEflOld & X86_EFL_VM)
+ {
+ /*
+ * Almost anything goes if IOPL is 3.
+ */
+ if (X86_EFL_GET_IOPL(fEflOld) == 3)
+ {
+ switch (enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ uint16_t u16Value;
+ rcStrict = iemMemStackPopU16(pIemCpu, &u16Value);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ fEflNew = u16Value | (fEflOld & UINT32_C(0xffff0000));
+ break;
+ }
+ case IEMMODE_32BIT:
+ rcStrict = iemMemStackPopU32(pIemCpu, &fEflNew);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+
+ fEflNew &= X86_EFL_POPF_BITS & ~(X86_EFL_IOPL);
+ fEflNew |= ~(X86_EFL_POPF_BITS & ~(X86_EFL_IOPL)) & fEflOld;
+ }
+ /*
+ * Interrupt flag virtualization with CR4.VME=1.
+ */
+ else if ( enmEffOpSize == IEMMODE_16BIT
+ && (pCtx->cr4 & X86_CR4_VME) )
+ {
+ uint16_t u16Value;
+ RTUINT64U TmpRsp;
+ TmpRsp.u = pCtx->rsp;
+ rcStrict = iemMemStackPopU16Ex(pIemCpu, &u16Value, &TmpRsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /** @todo Is the popf VME #GP(0) delivered after updating RSP+RIP
+ * or before? */
+ if ( ( (u16Value & X86_EFL_IF)
+ && (fEflOld & X86_EFL_VIP))
+ || (u16Value & X86_EFL_TF) )
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+
+ fEflNew = u16Value | (fEflOld & UINT32_C(0xffff0000) & ~X86_EFL_VIF);
+ fEflNew |= (fEflNew & X86_EFL_IF) << (19 - 9);
+ fEflNew &= X86_EFL_POPF_BITS & ~(X86_EFL_IOPL | X86_EFL_IF);
+ fEflNew |= ~(X86_EFL_POPF_BITS & ~(X86_EFL_IOPL | X86_EFL_IF)) & fEflOld;
+
+ pCtx->rsp = TmpRsp.u;
+ }
+ else
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+
+ }
+ /*
+ * Not in V8086 mode.
+ */
+ else
+ {
+ /* Pop the flags. */
+ switch (enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ uint16_t u16Value;
+ rcStrict = iemMemStackPopU16(pIemCpu, &u16Value);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ fEflNew = u16Value | (fEflOld & UINT32_C(0xffff0000));
+ break;
+ }
+ case IEMMODE_32BIT:
+ case IEMMODE_64BIT:
+ rcStrict = iemMemStackPopU32(pIemCpu, &fEflNew);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+
+ /* Merge them with the current flags. */
+ if ( (fEflNew & (X86_EFL_IOPL | X86_EFL_IF)) == (fEflOld & (X86_EFL_IOPL | X86_EFL_IF))
+ || pIemCpu->uCpl == 0)
+ {
+ fEflNew &= X86_EFL_POPF_BITS;
+ fEflNew |= ~X86_EFL_POPF_BITS & fEflOld;
+ }
+ else if (pIemCpu->uCpl <= X86_EFL_GET_IOPL(fEflOld))
+ {
+ fEflNew &= X86_EFL_POPF_BITS & ~(X86_EFL_IOPL);
+ fEflNew |= ~(X86_EFL_POPF_BITS & ~(X86_EFL_IOPL)) & fEflOld;
+ }
+ else
+ {
+ fEflNew &= X86_EFL_POPF_BITS & ~(X86_EFL_IOPL | X86_EFL_IF);
+ fEflNew |= ~(X86_EFL_POPF_BITS & ~(X86_EFL_IOPL | X86_EFL_IF)) & fEflOld;
+ }
+ }
+
+ /*
+ * Commit the flags.
+ */
+ Assert(fEflNew & RT_BIT_32(1));
+ pCtx->eflags.u = fEflNew;
+ iemRegAddToRip(pIemCpu, cbInstr);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements an indirect call.
+ *
+ * @param uNewPC The new program counter (RIP) value (loaded from the
+ * operand).
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_call_16, uint16_t, uNewPC)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint16_t uOldPC = pCtx->ip + cbInstr;
+ if (uNewPC > pCtx->csHid.u32Limit)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+
+ VBOXSTRICTRC rcStrict = iemMemStackPushU16(pIemCpu, uOldPC);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ pCtx->rip = uNewPC;
+ return VINF_SUCCESS;
+
+}
+
+
+/**
+ * Implements a 16-bit relative call.
+ *
+ * @param offDisp The displacment offset.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_call_rel_16, int16_t, offDisp)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint16_t uOldPC = pCtx->ip + cbInstr;
+ uint16_t uNewPC = uOldPC + offDisp;
+ if (uNewPC > pCtx->csHid.u32Limit)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+
+ VBOXSTRICTRC rcStrict = iemMemStackPushU16(pIemCpu, uOldPC);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ pCtx->rip = uNewPC;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements a 32-bit indirect call.
+ *
+ * @param uNewPC The new program counter (RIP) value (loaded from the
+ * operand).
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_call_32, uint32_t, uNewPC)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint32_t uOldPC = pCtx->eip + cbInstr;
+ if (uNewPC > pCtx->csHid.u32Limit)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+
+ VBOXSTRICTRC rcStrict = iemMemStackPushU32(pIemCpu, uOldPC);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ pCtx->rip = uNewPC;
+ return VINF_SUCCESS;
+
+}
+
+
+/**
+ * Implements a 32-bit relative call.
+ *
+ * @param offDisp The displacment offset.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_call_rel_32, int32_t, offDisp)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint32_t uOldPC = pCtx->eip + cbInstr;
+ uint32_t uNewPC = uOldPC + offDisp;
+ if (uNewPC > pCtx->csHid.u32Limit)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+
+ VBOXSTRICTRC rcStrict = iemMemStackPushU32(pIemCpu, uOldPC);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ pCtx->rip = uNewPC;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements a 64-bit indirect call.
+ *
+ * @param uNewPC The new program counter (RIP) value (loaded from the
+ * operand).
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_call_64, uint64_t, uNewPC)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint64_t uOldPC = pCtx->rip + cbInstr;
+ if (!IEM_IS_CANONICAL(uNewPC))
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+
+ VBOXSTRICTRC rcStrict = iemMemStackPushU64(pIemCpu, uOldPC);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ pCtx->rip = uNewPC;
+ return VINF_SUCCESS;
+
+}
+
+
+/**
+ * Implements a 64-bit relative call.
+ *
+ * @param offDisp The displacment offset.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_call_rel_64, int64_t, offDisp)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint64_t uOldPC = pCtx->rip + cbInstr;
+ uint64_t uNewPC = uOldPC + offDisp;
+ if (!IEM_IS_CANONICAL(uNewPC))
+ return iemRaiseNotCanonical(pIemCpu);
+
+ VBOXSTRICTRC rcStrict = iemMemStackPushU64(pIemCpu, uOldPC);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ pCtx->rip = uNewPC;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements far jumps.
+ *
+ * @param uSel The selector.
+ * @param offSeg The segment offset.
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_3(iemCImpl_FarJmp, uint16_t, uSel, uint32_t, offSeg, IEMMODE, enmEffOpSize)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Real mode and V8086 mode are easy. The only snag seems to be that
+ * CS.limit doesn't change and the limit check is done against the current
+ * limit.
+ */
+ if ( pIemCpu->enmCpuMode == IEMMODE_16BIT
+ && IEM_IS_REAL_OR_V86_MODE(pIemCpu))
+ {
+ if (offSeg > pCtx->csHid.u32Limit)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+
+ if (enmEffOpSize == IEMMODE_16BIT) /** @todo WRONG, must pass this. */
+ pCtx->rip = offSeg;
+ else
+ pCtx->rip = offSeg & UINT16_MAX;
+ pCtx->cs = uSel;
+ pCtx->csHid.u64Base = (uint32_t)uSel << 4;
+ /** @todo REM reset the accessed bit (see on jmp far16 after disabling
+ * PE. Check with VT-x and AMD-V. */
+#ifdef IEM_VERIFICATION_MODE
+ pCtx->csHid.Attr.u &= ~X86_SEL_TYPE_ACCESSED;
+#endif
+ return VINF_SUCCESS;
+ }
+
+ /*
+ * Protected mode. Need to parse the specified descriptor...
+ */
+ if (!(uSel & (X86_SEL_MASK | X86_SEL_LDT)))
+ {
+ Log(("jmpf %04x:%08x -> invalid selector, #GP(0)\n", uSel, offSeg));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ /* Fetch the descriptor. */
+ IEMSELDESC Desc;
+ VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /* Is it there? */
+ if (!Desc.Legacy.Gen.u1Present) /** @todo this is probably checked too early. Testcase! */
+ {
+ Log(("jmpf %04x:%08x -> segment not present\n", uSel, offSeg));
+ return iemRaiseSelectorNotPresentBySelector(pIemCpu, uSel);
+ }
+
+ /*
+ * Deal with it according to its type.
+ */
+ if (Desc.Legacy.Gen.u1DescType)
+ {
+ /* Only code segments. */
+ if (!(Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_CODE))
+ {
+ Log(("jmpf %04x:%08x -> not a code selector (u4Type=%#x).\n", uSel, offSeg, Desc.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+
+ /* L vs D. */
+ if ( Desc.Legacy.Gen.u1Long
+ && Desc.Legacy.Gen.u1DefBig
+ && IEM_IS_LONG_MODE(pIemCpu))
+ {
+ Log(("jmpf %04x:%08x -> both L and D are set.\n", uSel, offSeg));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+
+ /* DPL/RPL/CPL check, where conforming segments makes a difference. */
+ if (!(Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_CONF))
+ {
+ if (Desc.Legacy.Gen.u2Dpl > pIemCpu->uCpl)
+ {
+ Log(("jmpf %04x:%08x -> DPL violation (conforming); DPL=%d CPL=%u\n",
+ uSel, offSeg, Desc.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ }
+ else
+ {
+ if (Desc.Legacy.Gen.u2Dpl != pIemCpu->uCpl)
+ {
+ Log(("jmpf %04x:%08x -> CPL != DPL; DPL=%d CPL=%u\n", uSel, offSeg, Desc.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ if ((uSel & X86_SEL_RPL) > pIemCpu->uCpl)
+ {
+ Log(("jmpf %04x:%08x -> RPL > DPL; RPL=%d CPL=%u\n", uSel, offSeg, (uSel & X86_SEL_RPL), pIemCpu->uCpl));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ }
+
+ /* Limit check. (Should alternatively check for non-canonical addresses
+ here, but that is ruled out by offSeg being 32-bit, right?) */
+ uint64_t u64Base;
+ uint32_t cbLimit = X86DESC_LIMIT(Desc.Legacy);
+ if (Desc.Legacy.Gen.u1Granularity)
+ cbLimit = (cbLimit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ u64Base = 0;
+ else
+ {
+ if (offSeg > cbLimit)
+ {
+ Log(("jmpf %04x:%08x -> out of bounds (%#x)\n", uSel, offSeg, cbLimit));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ u64Base = X86DESC_BASE(Desc.Legacy);
+ }
+
+ /*
+ * Ok, everything checked out fine. Now set the accessed bit before
+ * committing the result into CS, CSHID and RIP.
+ */
+ if (!(Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_ACCESSED))
+ {
+ rcStrict = iemMemMarkSelDescAccessed(pIemCpu, uSel);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+#ifdef IEM_VERIFICATION_MODE /** @todo check what VT-x and AMD-V does. */
+ Desc.Legacy.Gen.u4Type |= X86_SEL_TYPE_ACCESSED;
+#endif
+ }
+
+ /* commit */
+ pCtx->rip = offSeg;
+ pCtx->cs = uSel & (X86_SEL_MASK | X86_SEL_LDT);
+ pCtx->cs |= pIemCpu->uCpl; /** @todo is this right for conforming segs? or in general? */
+ pCtx->csHid.Attr.u = (Desc.Legacy.u >> (16+16+8)) & UINT32_C(0xf0ff);
+ pCtx->csHid.u32Limit = cbLimit;
+ pCtx->csHid.u64Base = u64Base;
+ /** @todo check if the hidden bits are loaded correctly for 64-bit
+ * mode. */
+ return VINF_SUCCESS;
+ }
+
+ /*
+ * System selector.
+ */
+ if (IEM_IS_LONG_MODE(pIemCpu))
+ switch (Desc.Legacy.Gen.u4Type)
+ {
+ case AMD64_SEL_TYPE_SYS_LDT:
+ case AMD64_SEL_TYPE_SYS_TSS_AVAIL:
+ case AMD64_SEL_TYPE_SYS_TSS_BUSY:
+ case AMD64_SEL_TYPE_SYS_CALL_GATE:
+ case AMD64_SEL_TYPE_SYS_INT_GATE:
+ case AMD64_SEL_TYPE_SYS_TRAP_GATE:
+ /* Call various functions to do the work. */
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+ default:
+ Log(("jmpf %04x:%08x -> wrong sys selector (64-bit): %d\n", uSel, offSeg, Desc.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+
+ }
+ switch (Desc.Legacy.Gen.u4Type)
+ {
+ case X86_SEL_TYPE_SYS_286_TSS_AVAIL:
+ case X86_SEL_TYPE_SYS_LDT:
+ case X86_SEL_TYPE_SYS_286_CALL_GATE:
+ case X86_SEL_TYPE_SYS_TASK_GATE:
+ case X86_SEL_TYPE_SYS_286_INT_GATE:
+ case X86_SEL_TYPE_SYS_286_TRAP_GATE:
+ case X86_SEL_TYPE_SYS_386_TSS_AVAIL:
+ case X86_SEL_TYPE_SYS_386_CALL_GATE:
+ case X86_SEL_TYPE_SYS_386_INT_GATE:
+ case X86_SEL_TYPE_SYS_386_TRAP_GATE:
+ /* Call various functions to do the work. */
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+
+ case X86_SEL_TYPE_SYS_286_TSS_BUSY:
+ case X86_SEL_TYPE_SYS_386_TSS_BUSY:
+ /* Call various functions to do the work. */
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+
+ default:
+ Log(("jmpf %04x:%08x -> wrong sys selector (32-bit): %d\n", uSel, offSeg, Desc.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+}
+
+
+/**
+ * Implements far calls.
+ *
+ * @param uSel The selector.
+ * @param offSeg The segment offset.
+ * @param enmOpSize The operand size (in case we need it).
+ */
+IEM_CIMPL_DEF_3(iemCImpl_callf, uint16_t, uSel, uint64_t, offSeg, IEMMODE, enmOpSize)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ VBOXSTRICTRC rcStrict;
+ uint64_t uNewRsp;
+ void *pvRet;
+
+ /*
+ * Real mode and V8086 mode are easy. The only snag seems to be that
+ * CS.limit doesn't change and the limit check is done against the current
+ * limit.
+ */
+ if ( pIemCpu->enmCpuMode == IEMMODE_16BIT
+ && IEM_IS_REAL_OR_V86_MODE(pIemCpu))
+ {
+ Assert(enmOpSize == IEMMODE_16BIT || enmOpSize == IEMMODE_32BIT);
+
+ /* Check stack first - may #SS(0). */
+ rcStrict = iemMemStackPushBeginSpecial(pIemCpu, enmOpSize == IEMMODE_32BIT ? 6 : 4,
+ &pvRet, &uNewRsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /* Check the target address range. */
+ if (offSeg > UINT32_MAX)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+
+ /* Everything is fine, push the return address. */
+ if (enmOpSize == IEMMODE_16BIT)
+ {
+ ((uint16_t *)pvRet)[0] = pCtx->ip + cbInstr;
+ ((uint16_t *)pvRet)[1] = pCtx->cs;
+ }
+ else
+ {
+ ((uint32_t *)pvRet)[0] = pCtx->eip + cbInstr;
+ ((uint16_t *)pvRet)[3] = pCtx->cs;
+ }
+ rcStrict = iemMemStackPushCommitSpecial(pIemCpu, pvRet, uNewRsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /* Branch. */
+ pCtx->rip = offSeg;
+ pCtx->cs = uSel;
+ pCtx->csHid.u64Base = (uint32_t)uSel << 4;
+ /** @todo Does REM reset the accessed bit here to? (See on jmp far16
+ * after disabling PE.) Check with VT-x and AMD-V. */
+#ifdef IEM_VERIFICATION_MODE
+ pCtx->csHid.Attr.u &= ~X86_SEL_TYPE_ACCESSED;
+#endif
+ return VINF_SUCCESS;
+ }
+
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+}
+
+
+/**
+ * Implements retf.
+ *
+ * @param enmEffOpSize The effective operand size.
+ * @param cbPop The amount of arguments to pop from the stack
+ * (bytes).
+ */
+IEM_CIMPL_DEF_2(iemCImpl_retf, IEMMODE, enmEffOpSize, uint16_t, cbPop)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ VBOXSTRICTRC rcStrict;
+ uint64_t uNewRsp;
+
+ /*
+ * Real mode and V8086 mode are easy.
+ */
+ if ( pIemCpu->enmCpuMode == IEMMODE_16BIT
+ && IEM_IS_REAL_OR_V86_MODE(pIemCpu))
+ {
+ Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
+ uint16_t const *pu16Frame;
+ rcStrict = iemMemStackPopBeginSpecial(pIemCpu, enmEffOpSize == IEMMODE_32BIT ? 8 : 4,
+ (void const **)&pu16Frame, &uNewRsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ uint32_t uNewEip;
+ uint16_t uNewCS;
+ if (enmEffOpSize == IEMMODE_32BIT)
+ {
+ uNewCS = pu16Frame[2];
+ uNewEip = RT_MAKE_U32(pu16Frame[0], pu16Frame[1]);
+ }
+ else
+ {
+ uNewCS = pu16Frame[1];
+ uNewEip = pu16Frame[0];
+ }
+ /** @todo check how this is supposed to work if sp=0xfffe. */
+
+ /* Check the limit of the new EIP. */
+ /** @todo Intel pseudo code only does the limit check for 16-bit
+ * operands, AMD does not make any distinction. What is right? */
+ if (uNewEip > pCtx->csHid.u32Limit)
+ return iemRaiseSelectorBounds(pIemCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
+
+ /* commit the operation. */
+ rcStrict = iemMemStackPopCommitSpecial(pIemCpu, pu16Frame, uNewRsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ pCtx->rip = uNewEip;
+ pCtx->cs = uNewCS;
+ pCtx->csHid.u64Base = (uint32_t)uNewCS << 4;
+ /** @todo do we load attribs and limit as well? */
+ if (cbPop)
+ iemRegAddToRsp(pCtx, cbPop);
+ return VINF_SUCCESS;
+ }
+
+ AssertFailed();
+ return VERR_NOT_IMPLEMENTED;
+}
+
+
+/**
+ * Implements retn.
+ *
+ * We're doing this in C because of the \#GP that might be raised if the popped
+ * program counter is out of bounds.
+ *
+ * @param enmEffOpSize The effective operand size.
+ * @param cbPop The amount of arguments to pop from the stack
+ * (bytes).
+ */
+IEM_CIMPL_DEF_2(iemCImpl_retn, IEMMODE, enmEffOpSize, uint16_t, cbPop)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /* Fetch the RSP from the stack. */
+ VBOXSTRICTRC rcStrict;
+ RTUINT64U NewRip;
+ RTUINT64U NewRsp;
+ NewRsp.u = pCtx->rsp;
+ switch (enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ NewRip.u = 0;
+ rcStrict = iemMemStackPopU16Ex(pIemCpu, &NewRip.Words.w0, &NewRsp);
+ break;
+ case IEMMODE_32BIT:
+ NewRip.u = 0;
+ rcStrict = iemMemStackPopU32Ex(pIemCpu, &NewRip.DWords.dw0, &NewRsp);
+ break;
+ case IEMMODE_64BIT:
+ rcStrict = iemMemStackPopU64Ex(pIemCpu, &NewRip.u, &NewRsp);
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /* Check the new RSP before loading it. */
+ /** @todo Should test this as the intel+amd pseudo code doesn't mention half
+ * of it. The canonical test is performed here and for call. */
+ if (enmEffOpSize != IEMMODE_64BIT)
+ {
+ if (NewRip.DWords.dw0 > pCtx->csHid.u32Limit)
+ {
+ Log(("retn newrip=%llx - out of bounds (%x) -> #GP\n", NewRip.u, pCtx->csHid.u32Limit));
+ return iemRaiseSelectorBounds(pIemCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
+ }
+ }
+ else
+ {
+ if (!IEM_IS_CANONICAL(NewRip.u))
+ {
+ Log(("retn newrip=%llx - not canonical -> #GP\n", NewRip.u));
+ return iemRaiseNotCanonical(pIemCpu);
+ }
+ }
+
+ /* Commit it. */
+ pCtx->rip = NewRip.u;
+ pCtx->rsp = NewRsp.u;
+ if (cbPop)
+ iemRegAddToRsp(pCtx, cbPop);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements leave.
+ *
+ * We're doing this in C because messing with the stack registers is annoying
+ * since they depends on SS attributes.
+ *
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_leave, IEMMODE, enmEffOpSize)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /* Calculate the intermediate RSP from RBP and the stack attributes. */
+ RTUINT64U NewRsp;
+ if (pCtx->ssHid.Attr.n.u1Long)
+ {
+ /** @todo Check that LEAVE actually preserve the high EBP bits. */
+ NewRsp.u = pCtx->rsp;
+ NewRsp.Words.w0 = pCtx->bp;
+ }
+ else if (pCtx->ssHid.Attr.n.u1DefBig)
+ NewRsp.u = pCtx->ebp;
+ else
+ NewRsp.u = pCtx->rbp;
+
+ /* Pop RBP according to the operand size. */
+ VBOXSTRICTRC rcStrict;
+ RTUINT64U NewRbp;
+ switch (enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ NewRbp.u = pCtx->rbp;
+ rcStrict = iemMemStackPopU16Ex(pIemCpu, &NewRbp.Words.w0, &NewRsp);
+ break;
+ case IEMMODE_32BIT:
+ NewRbp.u = 0;
+ rcStrict = iemMemStackPopU32Ex(pIemCpu, &NewRbp.DWords.dw0, &NewRsp);
+ break;
+ case IEMMODE_64BIT:
+ rcStrict = iemMemStackPopU64Ex(pIemCpu, &NewRbp.u, &NewRsp);
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+
+ /* Commit it. */
+ pCtx->rbp = NewRbp.u;
+ pCtx->rsp = NewRsp.u;
+ iemRegAddToRip(pIemCpu, cbInstr);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements int3 and int XX.
+ *
+ * @param u8Int The interrupt vector number.
+ * @param fIsBpInstr Is it the breakpoint instruction.
+ */
+IEM_CIMPL_DEF_2(iemCImpl_int, uint8_t, u8Int, bool, fIsBpInstr)
+{
+ Assert(pIemCpu->cXcptRecursions == 0);
+ return iemRaiseXcptOrInt(pIemCpu,
+ cbInstr,
+ u8Int,
+ (fIsBpInstr ? IEM_XCPT_FLAGS_BP_INSTR : 0) | IEM_XCPT_FLAGS_T_SOFT_INT,
+ 0,
+ 0);
+}
+
+
+/**
+ * Implements iret for real mode and V8086 mode.
+ *
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_iret_real_v8086, IEMMODE, enmEffOpSize)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * iret throws an exception if VME isn't enabled.
+ */
+ if ( pCtx->eflags.Bits.u1VM
+ && !(pCtx->cr4 & X86_CR4_VME))
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+
+ /*
+ * Do the stack bits, but don't commit RSP before everything checks
+ * out right.
+ */
+ Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
+ VBOXSTRICTRC rcStrict;
+ RTCPTRUNION uFrame;
+ uint16_t uNewCS;
+ uint32_t uNewEip;
+ uint32_t uNewFlags;
+ uint64_t uNewRsp;
+ if (enmEffOpSize == IEMMODE_32BIT)
+ {
+ rcStrict = iemMemStackPopBeginSpecial(pIemCpu, 12, &uFrame.pv, &uNewRsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ uNewEip = uFrame.pu32[0];
+ uNewCS = (uint16_t)uFrame.pu32[1];
+ uNewFlags = uFrame.pu32[2];
+ uNewFlags &= X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF
+ | X86_EFL_TF | X86_EFL_IF | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT
+ | X86_EFL_RF /*| X86_EFL_VM*/ | X86_EFL_AC /*|X86_EFL_VIF*/ /*|X86_EFL_VIP*/
+ | X86_EFL_ID;
+ uNewFlags |= pCtx->eflags.u & (X86_EFL_VM | X86_EFL_VIF | X86_EFL_VIP | X86_EFL_1);
+ }
+ else
+ {
+ rcStrict = iemMemStackPopBeginSpecial(pIemCpu, 6, &uFrame.pv, &uNewRsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ uNewEip = uFrame.pu16[0];
+ uNewCS = uFrame.pu16[1];
+ uNewFlags = uFrame.pu16[2];
+ uNewFlags &= X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF
+ | X86_EFL_TF | X86_EFL_IF | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT;
+ uNewFlags |= pCtx->eflags.u & (UINT32_C(0xffff0000) | X86_EFL_1);
+ /** @todo The intel pseudo code does not indicate what happens to
+ * reserved flags. We just ignore them. */
+ }
+ /** @todo Check how this is supposed to work if sp=0xfffe. */
+
+ /*
+ * Check the limit of the new EIP.
+ */
+ /** @todo Only the AMD pseudo code check the limit here, what's
+ * right? */
+ if (uNewEip > pCtx->csHid.u32Limit)
+ return iemRaiseSelectorBounds(pIemCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
+
+ /*
+ * V8086 checks and flag adjustments
+ */
+ if (pCtx->eflags.Bits.u1VM)
+ {
+ if (pCtx->eflags.Bits.u2IOPL == 3)
+ {
+ /* Preserve IOPL and clear RF. */
+ uNewFlags &= ~(X86_EFL_IOPL | X86_EFL_RF);
+ uNewFlags |= pCtx->eflags.u & (X86_EFL_IOPL);
+ }
+ else if ( enmEffOpSize == IEMMODE_16BIT
+ && ( !(uNewFlags & X86_EFL_IF)
+ || !pCtx->eflags.Bits.u1VIP )
+ && !(uNewFlags & X86_EFL_TF) )
+ {
+ /* Move IF to VIF, clear RF and preserve IF and IOPL.*/
+ uNewFlags &= ~X86_EFL_VIF;
+ uNewFlags |= (uNewFlags & X86_EFL_IF) << (19 - 9);
+ uNewFlags &= ~(X86_EFL_IF | X86_EFL_IOPL | X86_EFL_RF);
+ uNewFlags |= pCtx->eflags.u & (X86_EFL_IF | X86_EFL_IOPL);
+ }
+ else
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ /*
+ * Commit the operation.
+ */
+ rcStrict = iemMemStackPopCommitSpecial(pIemCpu, uFrame.pv, uNewRsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ pCtx->rip = uNewEip;
+ pCtx->cs = uNewCS;
+ pCtx->csHid.u64Base = (uint32_t)uNewCS << 4;
+ /** @todo do we load attribs and limit as well? */
+ Assert(uNewFlags & X86_EFL_1);
+ pCtx->eflags.u = uNewFlags;
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements iret for protected mode
+ *
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_iret_prot, IEMMODE, enmEffOpSize)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Nested task return.
+ */
+ if (pCtx->eflags.Bits.u1NT)
+ {
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+ }
+ /*
+ * Normal return.
+ */
+ else
+ {
+ /*
+ * Do the stack bits, but don't commit RSP before everything checks
+ * out right.
+ */
+ Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
+ VBOXSTRICTRC rcStrict;
+ RTCPTRUNION uFrame;
+ uint16_t uNewCS;
+ uint32_t uNewEip;
+ uint32_t uNewFlags;
+ uint64_t uNewRsp;
+ if (enmEffOpSize == IEMMODE_32BIT)
+ {
+ rcStrict = iemMemStackPopBeginSpecial(pIemCpu, 12, &uFrame.pv, &uNewRsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ uNewEip = uFrame.pu32[0];
+ uNewCS = (uint16_t)uFrame.pu32[1];
+ uNewFlags = uFrame.pu32[2];
+ }
+ else
+ {
+ rcStrict = iemMemStackPopBeginSpecial(pIemCpu, 6, &uFrame.pv, &uNewRsp);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ uNewEip = uFrame.pu16[0];
+ uNewCS = uFrame.pu16[1];
+ uNewFlags = uFrame.pu16[2];
+ }
+ rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)uFrame.pv, IEM_ACCESS_STACK_R); /* don't use iemMemStackPopCommitSpecial here. */
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /*
+ * What are we returning to?
+ */
+ if ( (uNewFlags & X86_EFL_VM)
+ && pIemCpu->uCpl == 0)
+ {
+ /* V8086 mode! */
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+ }
+ else
+ {
+ /*
+ * Protected mode.
+ */
+ /* Read the CS descriptor. */
+ if (!(uNewCS & (X86_SEL_MASK | X86_SEL_LDT)))
+ {
+ Log(("iret %04x:%08x -> invalid CS selector, #GP(0)\n", uNewCS, uNewEip));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ IEMSELDESC DescCS;
+ rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, uNewCS);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /* Must be a code descriptor. */
+ if (!DescCS.Legacy.Gen.u1DescType)
+ {
+ Log(("iret %04x:%08x - CS is system segment (%#x) -> #GP\n", uNewCS, uNewEip, DescCS.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewCS);
+ }
+ if (!(DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CODE))
+ {
+ Log(("iret %04x:%08x - not code segment (%#x) -> #GP\n", uNewCS, uNewEip, DescCS.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewCS);
+ }
+
+ /* Privilege checks. */
+ if ((uNewCS & X86_SEL_RPL) < pIemCpu->uCpl)
+ {
+ Log(("iret %04x:%08x - RPL < CPL (%d) -> #GP\n", uNewCS, uNewEip, pIemCpu->uCpl));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewCS);
+ }
+ if ( (DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CONF)
+ && (uNewCS & X86_SEL_RPL) < DescCS.Legacy.Gen.u2Dpl)
+ {
+ Log(("iret %04x:%08x - RPL < DPL (%d) -> #GP\n", uNewCS, uNewEip, DescCS.Legacy.Gen.u2Dpl));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewCS);
+ }
+
+ /* Present? */
+ if (!DescCS.Legacy.Gen.u1Present)
+ {
+ Log(("iret %04x:%08x - CS not present -> #NP\n", uNewCS, uNewEip));
+ return iemRaiseSelectorNotPresentBySelector(pIemCpu, uNewCS);
+ }
+
+ uint32_t cbLimitCS = X86DESC_LIMIT(DescCS.Legacy);
+ if (DescCS.Legacy.Gen.u1Granularity)
+ cbLimitCS = (cbLimitCS << PAGE_SHIFT) | PAGE_OFFSET_MASK;
+
+ /*
+ * Different level?
+ */
+ if ((uNewCS & X86_SEL_RPL) != pIemCpu->uCpl)
+ {
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+ }
+ /*
+ * Same level.
+ */
+ else
+ {
+ /* Check EIP. */
+ if (uNewEip > cbLimitCS)
+ {
+ Log(("iret %04x:%08x - EIP is out of bounds (%#x) -> #GP(0)\n", uNewCS, uNewEip, cbLimitCS));
+ return iemRaiseSelectorBoundsBySelector(pIemCpu, uNewCS);
+ }
+
+ /*
+ * Commit the changes, marking CS first since it may fail.
+ */
+ if (!(DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_ACCESSED))
+ {
+ rcStrict = iemMemMarkSelDescAccessed(pIemCpu, uNewCS);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ DescCS.Legacy.Gen.u4Type |= X86_SEL_TYPE_ACCESSED;
+ }
+
+ pCtx->rip = uNewEip;
+ pCtx->cs = uNewCS;
+ pCtx->csHid.Attr.u = X86DESC_GET_HID_ATTR(DescCS.Legacy);
+ pCtx->csHid.u32Limit = cbLimitCS;
+ pCtx->csHid.u64Base = X86DESC_BASE(DescCS.Legacy);
+ pCtx->rsp = uNewRsp;
+
+ uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF
+ | X86_EFL_TF | X86_EFL_DF | X86_EFL_OF | X86_EFL_NT;
+ if (enmEffOpSize != IEMMODE_16BIT)
+ fEFlagsMask |= X86_EFL_RF | X86_EFL_AC | X86_EFL_ID;
+ if (pIemCpu->uCpl == 0)
+ fEFlagsMask |= X86_EFL_IF | X86_EFL_IOPL | X86_EFL_VIF | X86_EFL_VIP; /* VM is 0 */
+ else if (pIemCpu->uCpl <= pCtx->eflags.Bits.u2IOPL)
+ fEFlagsMask |= X86_EFL_IF;
+ pCtx->eflags.u &= ~fEFlagsMask;
+ pCtx->eflags.u |= fEFlagsMask & uNewFlags;
+ /* Done! */
+ }
+ }
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements iret for long mode
+ *
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_iret_long, IEMMODE, enmEffOpSize)
+{
+ //PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ //VBOXSTRICTRC rcStrict;
+ //uint64_t uNewRsp;
+
+ return VERR_NOT_IMPLEMENTED;
+}
+
+
+/**
+ * Implements iret.
+ *
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_iret, IEMMODE, enmEffOpSize)
+{
+ /*
+ * Call a mode specific worker.
+ */
+ if ( pIemCpu->enmCpuMode == IEMMODE_16BIT
+ && IEM_IS_REAL_OR_V86_MODE(pIemCpu))
+ return IEM_CIMPL_CALL_1(iemCImpl_iret_real_v8086, enmEffOpSize);
+ if (IEM_IS_LONG_MODE(pIemCpu))
+ return IEM_CIMPL_CALL_1(iemCImpl_iret_long, enmEffOpSize);
+
+ return IEM_CIMPL_CALL_1(iemCImpl_iret_prot, enmEffOpSize);
+}
+
+
+/**
+ * Common worker for 'pop SReg', 'mov SReg, GReg' and 'lXs GReg, reg/mem'.
+ *
+ * @param iSegReg The segment register number (valid).
+ * @param uSel The new selector value.
+ */
+IEM_CIMPL_DEF_2(iemCImpl_LoadSReg, uint8_t, iSegReg, uint16_t, uSel)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint16_t *pSel = iemSRegRef(pIemCpu, iSegReg);
+ PCPUMSELREGHID pHid = iemSRegGetHid(pIemCpu, iSegReg);
+
+ Assert(iSegReg <= X86_SREG_GS && iSegReg != X86_SREG_CS);
+
+ /*
+ * Real mode and V8086 mode are easy.
+ */
+ if ( pIemCpu->enmCpuMode == IEMMODE_16BIT
+ && IEM_IS_REAL_OR_V86_MODE(pIemCpu))
+ {
+ *pSel = uSel;
+ pHid->u64Base = (uint32_t)uSel << 4;
+ /** @todo Does the CPU actually load limits and attributes in the
+ * real/V8086 mode segment load case? It doesn't for CS in far
+ * jumps... Affects unreal mode. */
+ pHid->u32Limit = 0xffff;
+ pHid->Attr.u = 0;
+ pHid->Attr.n.u1Present = 1;
+ pHid->Attr.n.u1DescType = 1;
+ pHid->Attr.n.u4Type = iSegReg != X86_SREG_CS
+ ? X86_SEL_TYPE_RW
+ : X86_SEL_TYPE_READ | X86_SEL_TYPE_CODE;
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ /*
+ * Protected mode.
+ *
+ * Check if it's a null segment selector value first, that's OK for DS, ES,
+ * FS and GS. If not null, then we have to load and parse the descriptor.
+ */
+ if (!(uSel & (X86_SEL_MASK | X86_SEL_LDT)))
+ {
+ if (iSegReg == X86_SREG_SS)
+ {
+ if ( pIemCpu->enmCpuMode != IEMMODE_64BIT
+ || pIemCpu->uCpl != 0
+ || uSel != 0) /** @todo We cannot 'mov ss, 3' in 64-bit kernel mode, can we? */
+ {
+ Log(("load sreg -> invalid stack selector, #GP(0)\n", uSel));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ /* In 64-bit kernel mode, the stack can be 0 because of the way
+ interrupts are dispatched when in kernel ctx. Just load the
+ selector value into the register and leave the hidden bits
+ as is. */
+ *pSel = uSel;
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ *pSel = uSel; /* Not RPL, remember :-) */
+ if ( pIemCpu->enmCpuMode == IEMMODE_64BIT
+ && iSegReg != X86_SREG_FS
+ && iSegReg != X86_SREG_GS)
+ {
+ /** @todo figure out what this actually does, it works. Needs
+ * testcase! */
+ pHid->Attr.u = 0;
+ pHid->Attr.n.u1Present = 1;
+ pHid->Attr.n.u1Long = 1;
+ pHid->Attr.n.u4Type = X86_SEL_TYPE_RW;
+ pHid->Attr.n.u2Dpl = 3;
+ pHid->u32Limit = 0;
+ pHid->u64Base = 0;
+ }
+ else
+ {
+ pHid->Attr.u = 0;
+ pHid->u32Limit = 0;
+ pHid->u64Base = 0;
+ }
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ /* Fetch the descriptor. */
+ IEMSELDESC Desc;
+ VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /* Check GPs first. */
+ if (!Desc.Legacy.Gen.u1DescType)
+ {
+ Log(("load sreg %d - system selector (%#x) -> #GP\n", iSegReg, uSel, Desc.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ if (iSegReg == X86_SREG_SS) /* SS gets different treatment */
+ {
+ if ( (Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_CODE)
+ || !(Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_WRITE) )
+ {
+ Log(("load sreg SS, %#x - code or read only (%#x) -> #GP\n", uSel, Desc.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ if ( (Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_CODE)
+ || !(Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_WRITE) )
+ {
+ Log(("load sreg SS, %#x - code or read only (%#x) -> #GP\n", uSel, Desc.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ if ((uSel & X86_SEL_RPL) != pIemCpu->uCpl)
+ {
+ Log(("load sreg SS, %#x - RPL and CPL (%d) differs -> #GP\n", uSel, pIemCpu->uCpl));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ if (Desc.Legacy.Gen.u2Dpl != pIemCpu->uCpl)
+ {
+ Log(("load sreg SS, %#x - DPL (%d) and CPL (%d) differs -> #GP\n", uSel, Desc.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ }
+ else
+ {
+ if ((Desc.Legacy.Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ)) == X86_SEL_TYPE_CODE)
+ {
+ Log(("load sreg%u, %#x - execute only segment -> #GP\n", iSegReg, uSel));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ if ( (Desc.Legacy.Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))
+ != (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))
+ {
+#if 0 /* this is what intel says. */
+ if ( (uSel & X86_SEL_RPL) > Desc.Legacy.Gen.u2Dpl
+ && pIemCpu->uCpl > Desc.Legacy.Gen.u2Dpl)
+ {
+ Log(("load sreg%u, %#x - both RPL (%d) and CPL (%d) are greater than DPL (%d) -> #GP\n",
+ iSegReg, uSel, (uSel & X86_SEL_RPL), pIemCpu->uCpl, Desc.Legacy.Gen.u2Dpl));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+#else /* this is what makes more sense. */
+ if ((unsigned)(uSel & X86_SEL_RPL) > Desc.Legacy.Gen.u2Dpl)
+ {
+ Log(("load sreg%u, %#x - RPL (%d) is greater than DPL (%d) -> #GP\n",
+ iSegReg, uSel, (uSel & X86_SEL_RPL), Desc.Legacy.Gen.u2Dpl));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+ if (pIemCpu->uCpl > Desc.Legacy.Gen.u2Dpl)
+ {
+ Log(("load sreg%u, %#x - CPL (%d) is greater than DPL (%d) -> #GP\n",
+ iSegReg, uSel, pIemCpu->uCpl, Desc.Legacy.Gen.u2Dpl));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
+ }
+#endif
+ }
+ }
+
+ /* Is it there? */
+ if (!Desc.Legacy.Gen.u1Present)
+ {
+ Log(("load sreg%d,%#x - segment not present -> #NP\n", iSegReg, uSel));
+ return iemRaiseSelectorNotPresentBySelector(pIemCpu, uSel);
+ }
+
+ /* The the base and limit. */
+ uint64_t u64Base;
+ uint32_t cbLimit = X86DESC_LIMIT(Desc.Legacy);
+ if (Desc.Legacy.Gen.u1Granularity)
+ cbLimit = (cbLimit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
+
+ if ( pIemCpu->enmCpuMode == IEMMODE_64BIT
+ && iSegReg < X86_SREG_FS)
+ u64Base = 0;
+ else
+ u64Base = X86DESC_BASE(Desc.Legacy);
+
+ /*
+ * Ok, everything checked out fine. Now set the accessed bit before
+ * committing the result into the registers.
+ */
+ if (!(Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_ACCESSED))
+ {
+ rcStrict = iemMemMarkSelDescAccessed(pIemCpu, uSel);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ Desc.Legacy.Gen.u4Type |= X86_SEL_TYPE_ACCESSED;
+ }
+
+ /* commit */
+ *pSel = uSel;
+ pHid->Attr.u = (Desc.Legacy.u >> (16+16+8)) & UINT32_C(0xf0ff); /** @todo do we have a define for 0xf0ff? */
+ pHid->u32Limit = cbLimit;
+ pHid->u64Base = u64Base;
+
+ /** @todo check if the hidden bits are loaded correctly for 64-bit
+ * mode. */
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements 'mov SReg, r/m'.
+ *
+ * @param iSegReg The segment register number (valid).
+ * @param uSel The new selector value.
+ */
+IEM_CIMPL_DEF_2(iemCImpl_load_SReg, uint8_t, iSegReg, uint16_t, uSel)
+{
+ VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_2(iemCImpl_LoadSReg, iSegReg, uSel);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ if (iSegReg == X86_SREG_SS)
+ {
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ EMSetInhibitInterruptsPC(IEMCPU_TO_VMCPU(pIemCpu), pCtx->rip);
+ }
+ }
+ return rcStrict;
+}
+
+
+/**
+ * Implements 'pop SReg'.
+ *
+ * @param iSegReg The segment register number (valid).
+ * @param enmEffOpSize The efficient operand size (valid).
+ */
+IEM_CIMPL_DEF_2(iemCImpl_pop_Sreg, uint8_t, iSegReg, IEMMODE, enmEffOpSize)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ VBOXSTRICTRC rcStrict;
+
+ /*
+ * Read the selector off the stack and join paths with mov ss, reg.
+ */
+ RTUINT64U TmpRsp;
+ TmpRsp.u = pCtx->rsp;
+ switch (enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ uint16_t uSel;
+ rcStrict = iemMemStackPopU16Ex(pIemCpu, &uSel, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = IEM_CIMPL_CALL_2(iemCImpl_LoadSReg, iSegReg, uSel);
+ break;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ uint32_t u32Value;
+ rcStrict = iemMemStackPopU32Ex(pIemCpu, &u32Value, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = IEM_CIMPL_CALL_2(iemCImpl_LoadSReg, iSegReg, (uint16_t)u32Value);
+ break;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ uint64_t u64Value;
+ rcStrict = iemMemStackPopU64Ex(pIemCpu, &u64Value, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = IEM_CIMPL_CALL_2(iemCImpl_LoadSReg, iSegReg, (uint16_t)u64Value);
+ break;
+ }
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+
+ /*
+ * Commit the stack on success.
+ */
+ if (rcStrict == VINF_SUCCESS)
+ {
+ pCtx->rsp = TmpRsp.u;
+ if (iSegReg == X86_SREG_SS)
+ EMSetInhibitInterruptsPC(IEMCPU_TO_VMCPU(pIemCpu), pCtx->rip);
+ }
+ return rcStrict;
+}
+
+
+/**
+ * Implements lgs, lfs, les, lds & lss.
+ */
+IEM_CIMPL_DEF_5(iemCImpl_load_SReg_Greg,
+ uint16_t, uSel,
+ uint64_t, offSeg,
+ uint8_t, iSegReg,
+ uint8_t, iGReg,
+ IEMMODE, enmEffOpSize)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ VBOXSTRICTRC rcStrict;
+
+ /*
+ * Use iemCImpl_LoadSReg to do the tricky segment register loading.
+ */
+ /** @todo verify and test that mov, pop and lXs works the segment
+ * register loading in the exact same way. */
+ rcStrict = IEM_CIMPL_CALL_2(iemCImpl_LoadSReg, iSegReg, uSel);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ switch (enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ *(uint16_t *)iemGRegRef(pIemCpu, iGReg) = offSeg;
+ break;
+ case IEMMODE_32BIT:
+ *(uint64_t *)iemGRegRef(pIemCpu, iGReg) = offSeg;
+ break;
+ case IEMMODE_64BIT:
+ *(uint64_t *)iemGRegRef(pIemCpu, iGReg) = offSeg;
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+
+ return rcStrict;
+}
+
+
+/**
+ * Implements lgdt.
+ *
+ * @param iEffSeg The segment of the new ldtr contents
+ * @param GCPtrEffSrc The address of the new ldtr contents.
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_3(iemCImpl_lgdt, uint8_t, iEffSeg, RTGCPTR, GCPtrEffSrc, IEMMODE, enmEffOpSize)
+{
+ if (pIemCpu->uCpl != 0)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ Assert(!pIemCpu->CTX_SUFF(pCtx)->eflags.Bits.u1VM);
+
+ /*
+ * Fetch the limit and base address.
+ */
+ uint16_t cbLimit;
+ RTGCPTR GCPtrBase;
+ VBOXSTRICTRC rcStrict = iemMemFetchDataXdtr(pIemCpu, &cbLimit, &GCPtrBase, iEffSeg, GCPtrEffSrc, enmEffOpSize);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ rcStrict = CPUMSetGuestGDTR(IEMCPU_TO_VMCPU(pIemCpu), GCPtrBase, cbLimit);
+ else
+ {
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ pCtx->gdtr.cbGdt = cbLimit;
+ pCtx->gdtr.pGdt = GCPtrBase;
+ }
+ if (rcStrict == VINF_SUCCESS)
+ iemRegAddToRip(pIemCpu, cbInstr);
+ }
+ return rcStrict;
+}
+
+
+/**
+ * Implements lidt.
+ *
+ * @param iEffSeg The segment of the new ldtr contents
+ * @param GCPtrEffSrc The address of the new ldtr contents.
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_3(iemCImpl_lidt, uint8_t, iEffSeg, RTGCPTR, GCPtrEffSrc, IEMMODE, enmEffOpSize)
+{
+ if (pIemCpu->uCpl != 0)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ Assert(!pIemCpu->CTX_SUFF(pCtx)->eflags.Bits.u1VM);
+
+ /*
+ * Fetch the limit and base address.
+ */
+ uint16_t cbLimit;
+ RTGCPTR GCPtrBase;
+ VBOXSTRICTRC rcStrict = iemMemFetchDataXdtr(pIemCpu, &cbLimit, &GCPtrBase, iEffSeg, GCPtrEffSrc, enmEffOpSize);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ rcStrict = CPUMSetGuestIDTR(IEMCPU_TO_VMCPU(pIemCpu), GCPtrBase, cbLimit);
+ else
+ {
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ pCtx->idtr.cbIdt = cbLimit;
+ pCtx->idtr.pIdt = GCPtrBase;
+ }
+ if (rcStrict == VINF_SUCCESS)
+ iemRegAddToRip(pIemCpu, cbInstr);
+ }
+ return rcStrict;
+}
+
+
+/**
+ * Implements lldt.
+ *
+ * @param uNewLdt The new LDT selector value.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_lldt, uint16_t, uNewLdt)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Check preconditions.
+ */
+ if (IEM_IS_REAL_OR_V86_MODE(pIemCpu))
+ {
+ Log(("lldt %04x - real or v8086 mode -> #GP(0)\n", uNewLdt));
+ return iemRaiseUndefinedOpcode(pIemCpu);
+ }
+ if (pIemCpu->uCpl != 0)
+ {
+ Log(("lldt %04x - CPL is %d -> #GP(0)\n", uNewLdt, pIemCpu->uCpl));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+ if (uNewLdt & X86_SEL_LDT)
+ {
+ Log(("lldt %04x - LDT selector -> #GP\n", uNewLdt));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewLdt);
+ }
+
+ /*
+ * Now, loading a NULL selector is easy.
+ */
+ if ((uNewLdt & X86_SEL_MASK) == 0)
+ {
+ Log(("lldt %04x: Loading NULL selector.\n", uNewLdt));
+ /** @todo check if the actual value is loaded or if it's always 0. */
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ CPUMSetGuestLDTR(IEMCPU_TO_VMCPU(pIemCpu), 0);
+ else
+ pCtx->ldtr = 0;
+ pCtx->ldtrHid.Attr.u = 0;
+ pCtx->ldtrHid.u64Base = 0;
+ pCtx->ldtrHid.u32Limit = 0;
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ /*
+ * Read the descriptor.
+ */
+ IEMSELDESC Desc;
+ VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uNewLdt);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /* Check GPs first. */
+ if (Desc.Legacy.Gen.u1DescType)
+ {
+ Log(("lldt %#x - not system selector (type %x) -> #GP\n", uNewLdt, Desc.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & X86_SEL_MASK);
+ }
+ if (Desc.Legacy.Gen.u4Type != X86_SEL_TYPE_SYS_LDT)
+ {
+ Log(("lldt %#x - not LDT selector (type %x) -> #GP\n", uNewLdt, Desc.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & X86_SEL_MASK);
+ }
+ uint64_t u64Base;
+ if (!IEM_IS_LONG_MODE(pIemCpu))
+ u64Base = X86DESC_BASE(Desc.Legacy);
+ else
+ {
+ if (Desc.Long.Gen.u5Zeros)
+ {
+ Log(("lldt %#x - u5Zeros=%#x -> #GP\n", uNewLdt, Desc.Long.Gen.u5Zeros));
+ return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & X86_SEL_MASK);
+ }
+
+ u64Base = X86DESC64_BASE(Desc.Long);
+ if (!IEM_IS_CANONICAL(u64Base))
+ {
+ Log(("lldt %#x - non-canonical base address %#llx -> #GP\n", uNewLdt, u64Base));
+ return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & X86_SEL_MASK);
+ }
+ }
+
+ /* NP */
+ if (!Desc.Legacy.Gen.u1Present)
+ {
+ Log(("lldt %#x - segment not present -> #NP\n", uNewLdt));
+ return iemRaiseSelectorNotPresentBySelector(pIemCpu, uNewLdt);
+ }
+
+ /*
+ * It checks out alright, update the registers.
+ */
+/** @todo check if the actual value is loaded or if the RPL is dropped */
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ CPUMSetGuestLDTR(IEMCPU_TO_VMCPU(pIemCpu), uNewLdt & X86_SEL_MASK);
+ else
+ pCtx->ldtr = uNewLdt & X86_SEL_MASK;
+ pCtx->ldtrHid.Attr.u = X86DESC_GET_HID_ATTR(Desc.Legacy);
+ pCtx->ldtrHid.u32Limit = X86DESC_LIMIT(Desc.Legacy);
+ pCtx->ldtrHid.u64Base = u64Base;
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements lldt.
+ *
+ * @param uNewLdt The new LDT selector value.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_ltr, uint16_t, uNewTr)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Check preconditions.
+ */
+ if (IEM_IS_REAL_OR_V86_MODE(pIemCpu))
+ {
+ Log(("ltr %04x - real or v8086 mode -> #GP(0)\n", uNewTr));
+ return iemRaiseUndefinedOpcode(pIemCpu);
+ }
+ if (pIemCpu->uCpl != 0)
+ {
+ Log(("ltr %04x - CPL is %d -> #GP(0)\n", uNewTr, pIemCpu->uCpl));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+ if (uNewTr & X86_SEL_LDT)
+ {
+ Log(("ltr %04x - LDT selector -> #GP\n", uNewTr));
+ return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewTr);
+ }
+ if ((uNewTr & X86_SEL_MASK) == 0)
+ {
+ Log(("ltr %04x - NULL selector -> #GP(0)\n", uNewTr));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ /*
+ * Read the descriptor.
+ */
+ IEMSELDESC Desc;
+ VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uNewTr);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /* Check GPs first. */
+ if (Desc.Legacy.Gen.u1DescType)
+ {
+ Log(("ltr %#x - not system selector (type %x) -> #GP\n", uNewTr, Desc.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & X86_SEL_MASK);
+ }
+ if ( Desc.Legacy.Gen.u4Type != X86_SEL_TYPE_SYS_386_TSS_AVAIL /* same as AMD64_SEL_TYPE_SYS_TSS_AVAIL */
+ && ( Desc.Legacy.Gen.u4Type != X86_SEL_TYPE_SYS_286_TSS_AVAIL
+ || IEM_IS_LONG_MODE(pIemCpu)) )
+ {
+ Log(("ltr %#x - not an available TSS selector (type %x) -> #GP\n", uNewTr, Desc.Legacy.Gen.u4Type));
+ return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & X86_SEL_MASK);
+ }
+ uint64_t u64Base;
+ if (!IEM_IS_LONG_MODE(pIemCpu))
+ u64Base = X86DESC_BASE(Desc.Legacy);
+ else
+ {
+ if (Desc.Long.Gen.u5Zeros)
+ {
+ Log(("ltr %#x - u5Zeros=%#x -> #GP\n", uNewTr, Desc.Long.Gen.u5Zeros));
+ return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & X86_SEL_MASK);
+ }
+
+ u64Base = X86DESC64_BASE(Desc.Long);
+ if (!IEM_IS_CANONICAL(u64Base))
+ {
+ Log(("ltr %#x - non-canonical base address %#llx -> #GP\n", uNewTr, u64Base));
+ return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & X86_SEL_MASK);
+ }
+ }
+
+ /* NP */
+ if (!Desc.Legacy.Gen.u1Present)
+ {
+ Log(("ltr %#x - segment not present -> #NP\n", uNewTr));
+ return iemRaiseSelectorNotPresentBySelector(pIemCpu, uNewTr);
+ }
+
+ /*
+ * Set it busy.
+ * Note! Intel says this should lock down the whole descriptor, but we'll
+ * restrict our selves to 32-bit for now due to lack of inline
+ * assembly and such.
+ */
+ void *pvDesc;
+ rcStrict = iemMemMap(pIemCpu, &pvDesc, 8, UINT8_MAX, pCtx->gdtr.pGdt, IEM_ACCESS_DATA_RW);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ switch ((uintptr_t)pvDesc & 3)
+ {
+ case 0: ASMAtomicBitSet(pvDesc, 40 + 1); break;
+ case 1: ASMAtomicBitSet((uint8_t *)pvDesc + 3, 40 + 1 - 24); break;
+ case 2: ASMAtomicBitSet((uint8_t *)pvDesc + 3, 40 + 1 - 16); break;
+ case 3: ASMAtomicBitSet((uint8_t *)pvDesc + 3, 40 + 1 - 8); break;
+ }
+ rcStrict = iemMemMap(pIemCpu, &pvDesc, 8, UINT8_MAX, pCtx->gdtr.pGdt, IEM_ACCESS_DATA_RW);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ Desc.Legacy.Gen.u4Type |= X86_SEL_TYPE_SYS_TSS_BUSY_MASK;
+
+ /*
+ * It checks out alright, update the registers.
+ */
+/** @todo check if the actual value is loaded or if the RPL is dropped */
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ CPUMSetGuestTR(IEMCPU_TO_VMCPU(pIemCpu), uNewTr & X86_SEL_MASK);
+ else
+ pCtx->tr = uNewTr & X86_SEL_MASK;
+ pCtx->trHid.Attr.u = X86DESC_GET_HID_ATTR(Desc.Legacy);
+ pCtx->trHid.u32Limit = X86DESC_LIMIT(Desc.Legacy);
+ pCtx->trHid.u64Base = u64Base;
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements mov GReg,CRx.
+ *
+ * @param iGReg The general register to store the CRx value in.
+ * @param iCrReg The CRx register to read (valid).
+ */
+IEM_CIMPL_DEF_2(iemCImpl_mov_Rd_Cd, uint8_t, iGReg, uint8_t, iCrReg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ if (pIemCpu->uCpl != 0)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ Assert(!pCtx->eflags.Bits.u1VM);
+
+ /* read it */
+ uint64_t crX;
+ switch (iCrReg)
+ {
+ case 0: crX = pCtx->cr0; break;
+ case 2: crX = pCtx->cr2; break;
+ case 3: crX = pCtx->cr3; break;
+ case 4: crX = pCtx->cr4; break;
+ case 8:
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED); /** @todo implement CR8 reading and writing. */
+ else
+ crX = 0xff;
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* call checks */
+ }
+
+ /* store it */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ *(uint64_t *)iemGRegRef(pIemCpu, iGReg) = crX;
+ else
+ *(uint64_t *)iemGRegRef(pIemCpu, iGReg) = (uint32_t)crX;
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Used to implemented 'mov CRx,GReg' and 'lmsw r/m16'.
+ *
+ * @param iCrReg The CRx register to write (valid).
+ * @param uNewCrX The new value.
+ */
+IEM_CIMPL_DEF_2(iemCImpl_load_CrX, uint8_t, iCrReg, uint64_t, uNewCrX)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
+ VBOXSTRICTRC rcStrict;
+ int rc;
+
+ /*
+ * Try store it.
+ * Unfortunately, CPUM only does a tiny bit of the work.
+ */
+ switch (iCrReg)
+ {
+ case 0:
+ {
+ /*
+ * Perform checks.
+ */
+ uint64_t const uOldCrX = pCtx->cr0;
+ uNewCrX |= X86_CR0_ET; /* hardcoded */
+
+ /* Check for reserved bits. */
+ uint32_t const fValid = X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS
+ | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM
+ | X86_CR0_NW | X86_CR0_CD | X86_CR0_PG;
+ if (uNewCrX & ~(uint64_t)fValid)
+ {
+ Log(("Trying to set reserved CR0 bits: NewCR0=%#llx InvalidBits=%#llx\n", uNewCrX, uNewCrX & ~(uint64_t)fValid));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ /* Check for invalid combinations. */
+ if ( (uNewCrX & X86_CR0_PG)
+ && !(uNewCrX & X86_CR0_PE) )
+ {
+ Log(("Trying to set CR0.PG without CR0.PE\n"));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ if ( !(uNewCrX & X86_CR0_CD)
+ && (uNewCrX & X86_CR0_NW) )
+ {
+ Log(("Trying to clear CR0.CD while leaving CR0.NW set\n"));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ /* Long mode consistency checks. */
+ if ( (uNewCrX & X86_CR0_PG)
+ && !(uOldCrX & X86_CR0_PG)
+ && (pCtx->msrEFER & MSR_K6_EFER_LME) )
+ {
+ if (!(pCtx->cr4 & X86_CR4_PAE))
+ {
+ Log(("Trying to enabled long mode paging without CR4.PAE set\n"));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+ if (pCtx->csHid.Attr.n.u1Long)
+ {
+ Log(("Trying to enabled long mode paging with a long CS descriptor loaded.\n"));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+ }
+
+ /** @todo check reserved PDPTR bits as AMD states. */
+
+ /*
+ * Change CR0.
+ */
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ {
+ rc = CPUMSetGuestCR0(pVCpu, uNewCrX);
+ AssertRCSuccessReturn(rc, RT_FAILURE_NP(rc) ? rc : VERR_INTERNAL_ERROR_3);
+ }
+ else
+ pCtx->cr0 = uNewCrX;
+ Assert(pCtx->cr0 == uNewCrX);
+
+ /*
+ * Change EFER.LMA if entering or leaving long mode.
+ */
+ if ( (uNewCrX & X86_CR0_PG) != (uOldCrX & X86_CR0_PG)
+ && (pCtx->msrEFER & MSR_K6_EFER_LME) )
+ {
+ uint64_t NewEFER = pCtx->msrEFER;
+ if (uNewCrX & X86_CR0_PG)
+ NewEFER |= MSR_K6_EFER_LME;
+ else
+ NewEFER &= ~MSR_K6_EFER_LME;
+
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ CPUMSetGuestEFER(pVCpu, NewEFER);
+ else
+ pCtx->msrEFER = NewEFER;
+ Assert(pCtx->msrEFER == NewEFER);
+ }
+
+ /*
+ * Inform PGM.
+ */
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ {
+ if ( (uNewCrX & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE))
+ != (uOldCrX & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE)) )
+ {
+ rc = PGMFlushTLB(pVCpu, pCtx->cr3, true /* global */);
+ AssertRCReturn(rc, rc);
+ /* ignore informational status codes */
+ }
+ rcStrict = PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
+ /** @todo Status code management. */
+ }
+ else
+ rcStrict = VINF_SUCCESS;
+ break;
+ }
+
+ /*
+ * CR2 can be changed without any restrictions.
+ */
+ case 2:
+ pCtx->cr2 = uNewCrX;
+ rcStrict = VINF_SUCCESS;
+ break;
+
+ /*
+ * CR3 is relatively simple, although AMD and Intel have different
+ * accounts of how setting reserved bits are handled. We take intel's
+ * word for the lower bits and AMD's for the high bits (63:52).
+ */
+ /** @todo Testcase: Setting reserved bits in CR3, especially before
+ * enabling paging. */
+ case 3:
+ {
+ /* check / mask the value. */
+ if (uNewCrX & UINT64_C(0xfff0000000000000))
+ {
+ Log(("Trying to load CR3 with invalid high bits set: %#llx\n", uNewCrX));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ uint64_t fValid;
+ if ( (pCtx->cr4 & X86_CR4_PAE)
+ && (pCtx->msrEFER & MSR_K6_EFER_LME))
+ fValid = UINT64_C(0x000ffffffffff014);
+ else if (pCtx->cr4 & X86_CR4_PAE)
+ fValid = UINT64_C(0xfffffff4);
+ else
+ fValid = UINT64_C(0xfffff014);
+ if (uNewCrX & ~fValid)
+ {
+ Log(("Automatically clearing reserved bits in CR3 load: NewCR3=%#llx ClearedBits=%#llx\n",
+ uNewCrX, uNewCrX & ~fValid));
+ uNewCrX &= fValid;
+ }
+
+ /** @todo If we're in PAE mode we should check the PDPTRs for
+ * invalid bits. */
+
+ /* Make the change. */
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ {
+ rc = CPUMSetGuestCR3(pVCpu, uNewCrX);
+ AssertRCSuccessReturn(rc, rc);
+ }
+ else
+ pCtx->cr3 = uNewCrX;
+
+ /* Inform PGM. */
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ {
+ if (pCtx->cr0 & X86_CR0_PG)
+ {
+ rc = PGMFlushTLB(pVCpu, pCtx->cr3, !(pCtx->cr3 & X86_CR4_PGE));
+ AssertRCReturn(rc, rc);
+ /* ignore informational status codes */
+ /** @todo status code management */
+ }
+ }
+ rcStrict = VINF_SUCCESS;
+ break;
+ }
+
+ /*
+ * CR4 is a bit more tedious as there are bits which cannot be cleared
+ * under some circumstances and such.
+ */
+ case 4:
+ {
+ uint64_t const uOldCrX = pCtx->cr0;
+
+ /* reserved bits */
+ uint32_t fValid = X86_CR4_VME | X86_CR4_PVI
+ | X86_CR4_TSD | X86_CR4_DE
+ | X86_CR4_PSE | X86_CR4_PAE
+ | X86_CR4_MCE | X86_CR4_PGE
+ | X86_CR4_PCE | X86_CR4_OSFSXR
+ | X86_CR4_OSXMMEEXCPT;
+ //if (xxx)
+ // fValid |= X86_CR4_VMXE;
+ //if (xxx)
+ // fValid |= X86_CR4_OSXSAVE;
+ if (uNewCrX & ~(uint64_t)fValid)
+ {
+ Log(("Trying to set reserved CR4 bits: NewCR4=%#llx InvalidBits=%#llx\n", uNewCrX, uNewCrX & ~(uint64_t)fValid));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ /* long mode checks. */
+ if ( (uOldCrX & X86_CR4_PAE)
+ && !(uNewCrX & X86_CR4_PAE)
+ && (pCtx->msrEFER & MSR_K6_EFER_LMA) )
+ {
+ Log(("Trying to set clear CR4.PAE while long mode is active\n"));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+
+ /*
+ * Change it.
+ */
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ {
+ rc = CPUMSetGuestCR4(pVCpu, uNewCrX);
+ AssertRCSuccessReturn(rc, rc);
+ }
+ else
+ pCtx->cr4 = uNewCrX;
+ Assert(pCtx->cr4 == uNewCrX);
+
+ /*
+ * Notify SELM and PGM.
+ */
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ {
+ /* SELM - VME may change things wrt to the TSS shadowing. */
+ if ((uNewCrX ^ uOldCrX) & X86_CR4_VME)
+ VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+
+ /* PGM - flushing and mode. */
+ if ( (uNewCrX & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE))
+ != (uOldCrX & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE)) )
+ {
+ rc = PGMFlushTLB(pVCpu, pCtx->cr3, true /* global */);
+ AssertRCReturn(rc, rc);
+ /* ignore informational status codes */
+ }
+ rcStrict = PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
+ /** @todo Status code management. */
+ }
+ else
+ rcStrict = VINF_SUCCESS;
+ break;
+ }
+
+ /*
+ * CR8 maps to the APIC TPR.
+ */
+ case 8:
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED); /** @todo implement CR8 reading and writing. */
+ else
+ rcStrict = VINF_SUCCESS;
+ break;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* call checks */
+ }
+
+ /*
+ * Advance the RIP on success.
+ */
+ /** @todo Status code management. */
+ if (rcStrict == VINF_SUCCESS)
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return rcStrict;
+
+}
+
+
+/**
+ * Implements mov CRx,GReg.
+ *
+ * @param iCrReg The CRx register to write (valid).
+ * @param iGReg The general register to load the DRx value from.
+ */
+IEM_CIMPL_DEF_2(iemCImpl_mov_Cd_Rd, uint8_t, iCrReg, uint8_t, iGReg)
+{
+ if (pIemCpu->uCpl != 0)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ Assert(!pIemCpu->CTX_SUFF(pCtx)->eflags.Bits.u1VM);
+
+ /*
+ * Read the new value from the source register and call common worker.
+ */
+ uint64_t uNewCrX;
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ uNewCrX = iemGRegFetchU64(pIemCpu, iGReg);
+ else
+ uNewCrX = iemGRegFetchU32(pIemCpu, iGReg);
+ return IEM_CIMPL_CALL_2(iemCImpl_load_CrX, iCrReg, uNewCrX);
+}
+
+
+/**
+ * Implements 'LMSW r/m16'
+ *
+ * @param u16NewMsw The new value.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_lmsw, uint16_t, u16NewMsw)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ if (pIemCpu->uCpl != 0)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ Assert(!pCtx->eflags.Bits.u1VM);
+
+ /*
+ * Compose the new CR0 value and call common worker.
+ */
+ uint64_t uNewCr0 = pCtx->cr0 & ~(X86_CR0_MP | X86_CR0_EM | X86_CR0_TS);
+ uNewCr0 |= u16NewMsw & (X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS);
+ return IEM_CIMPL_CALL_2(iemCImpl_load_CrX, /*cr*/ 0, uNewCr0);
+}
+
+
+/**
+ * Implements 'CLTS'.
+ */
+IEM_CIMPL_DEF_0(iemCImpl_clts)
+{
+ if (pIemCpu->uCpl != 0)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint64_t uNewCr0 = pCtx->cr0;
+ uNewCr0 &= ~X86_CR0_TS;
+ return IEM_CIMPL_CALL_2(iemCImpl_load_CrX, /*cr*/ 0, uNewCr0);
+}
+
+
+/**
+ * Implements mov GReg,DRx.
+ *
+ * @param iGReg The general register to store the DRx value in.
+ * @param iDrReg The DRx register to read (0-7).
+ */
+IEM_CIMPL_DEF_2(iemCImpl_mov_Rd_Dd, uint8_t, iGReg, uint8_t, iDrReg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Check preconditions.
+ */
+
+ /* Raise GPs. */
+ if (pIemCpu->uCpl != 0)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ Assert(!pCtx->eflags.Bits.u1VM);
+
+ if ( (iDrReg == 4 || iDrReg == 5)
+ && (pCtx->cr4 & X86_CR4_DE) )
+ {
+ Log(("mov r%u,dr%u: CR4.DE=1 -> #GP(0)\n", iGReg, iDrReg));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ /* Raise #DB if general access detect is enabled. */
+ if (pCtx->dr[7] & X86_DR7_GD)
+ {
+ Log(("mov r%u,dr%u: DR7.GD=1 -> #DB\n", iGReg, iDrReg));
+ return iemRaiseDebugException(pIemCpu);
+ }
+
+ /*
+ * Read the debug register and store it in the specified general register.
+ */
+ uint64_t drX;
+ switch (iDrReg)
+ {
+ case 0: drX = pCtx->dr[0]; break;
+ case 1: drX = pCtx->dr[1]; break;
+ case 2: drX = pCtx->dr[2]; break;
+ case 3: drX = pCtx->dr[3]; break;
+ case 6:
+ case 4:
+ drX = pCtx->dr[6];
+ drX &= ~RT_BIT_32(12);
+ drX |= UINT32_C(0xffff0ff0);
+ break;
+ case 7:
+ case 5:
+ drX = pCtx->dr[7];
+ drX &= ~(RT_BIT_32(11) | RT_BIT_32(12) | RT_BIT_32(14) | RT_BIT_32(15));
+ drX |= RT_BIT_32(10);
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* call checks */
+ }
+
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ *(uint64_t *)iemGRegRef(pIemCpu, iGReg) = drX;
+ else
+ *(uint64_t *)iemGRegRef(pIemCpu, iGReg) = (uint32_t)drX;
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements mov DRx,GReg.
+ *
+ * @param iDrReg The DRx register to write (valid).
+ * @param iGReg The general register to load the DRx value from.
+ */
+IEM_CIMPL_DEF_2(iemCImpl_mov_Dd_Rd, uint8_t, iDrReg, uint8_t, iGReg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Check preconditions.
+ */
+ if (pIemCpu->uCpl != 0)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ Assert(!pCtx->eflags.Bits.u1VM);
+
+ if ( (iDrReg == 4 || iDrReg == 5)
+ && (pCtx->cr4 & X86_CR4_DE) )
+ {
+ Log(("mov dr%u,r%u: CR4.DE=1 -> #GP(0)\n", iDrReg, iGReg));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ /* Raise #DB if general access detect is enabled. */
+ /** @todo is \#DB/DR7.GD raised before any reserved high bits in DR7/DR6
+ * \#GP? */
+ if (pCtx->dr[7] & X86_DR7_GD)
+ {
+ Log(("mov dr%u,r%u: DR7.GD=1 -> #DB\n", iDrReg, iGReg));
+ return iemRaiseDebugException(pIemCpu);
+ }
+
+ /*
+ * Read the new value from the source register.
+ */
+ uint64_t uNewDrX;
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ uNewDrX = iemGRegFetchU64(pIemCpu, iGReg);
+ else
+ uNewDrX = iemGRegFetchU32(pIemCpu, iGReg);
+
+ /*
+ * Adjust it.
+ */
+ switch (iDrReg)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ /* nothing to adjust */
+ break;
+
+ case 6:
+ case 4:
+ if (uNewDrX & UINT64_C(0xffffffff00000000))
+ {
+ Log(("mov dr%u,%#llx: DR6 high bits are not zero -> #GP(0)\n", iDrReg, uNewDrX));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+ uNewDrX &= ~RT_BIT_32(12);
+ uNewDrX |= UINT32_C(0xffff0ff0);
+ break;
+
+ case 7:
+ case 5:
+ if (uNewDrX & UINT64_C(0xffffffff00000000))
+ {
+ Log(("mov dr%u,%#llx: DR7 high bits are not zero -> #GP(0)\n", iDrReg, uNewDrX));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+ uNewDrX &= ~(RT_BIT_32(11) | RT_BIT_32(12) | RT_BIT_32(14) | RT_BIT_32(15));
+ uNewDrX |= RT_BIT_32(10);
+ break;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+
+ /*
+ * Do the actual setting.
+ */
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ {
+ int rc = CPUMSetGuestDRx(IEMCPU_TO_VMCPU(pIemCpu), iDrReg, uNewDrX);
+ AssertRCSuccessReturn(rc, RT_SUCCESS_NP(rc) ? VERR_INTERNAL_ERROR : rc);
+ }
+ else
+ pCtx->dr[iDrReg] = uNewDrX;
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements RDTSC.
+ */
+IEM_CIMPL_DEF_0(iemCImpl_rdtsc)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Check preconditions.
+ */
+ if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_TSC))
+ return iemRaiseUndefinedOpcode(pIemCpu);
+
+ if ( (pCtx->cr4 & X86_CR4_TSD)
+ && pIemCpu->uCpl != 0)
+ {
+ Log(("rdtsc: CR4.TSD and CPL=%u -> #GP(0)\n", pIemCpu->uCpl));
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+
+ /*
+ * Do the job.
+ */
+ uint64_t uTicks = TMCpuTickGet(IEMCPU_TO_VMCPU(pIemCpu));
+ pCtx->rax = (uint32_t)uTicks;
+ pCtx->rdx = uTicks >> 32;
+#ifdef IEM_VERIFICATION_MODE
+ pIemCpu->fIgnoreRaxRdx = true;
+#endif
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements 'IN eAX, port'.
+ *
+ * @param u16Port The source port.
+ * @param cbReg The register size.
+ */
+IEM_CIMPL_DEF_2(iemCImpl_in, uint16_t, u16Port, uint8_t, cbReg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * CPL check
+ */
+ VBOXSTRICTRC rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, u16Port, cbReg);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ /*
+ * Perform the I/O.
+ */
+ uint32_t u32Value;
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ rcStrict = IOMIOPortRead(IEMCPU_TO_VM(pIemCpu), u16Port, &u32Value, cbReg);
+ else
+ rcStrict = iemVerifyFakeIOPortRead(pIemCpu, u16Port, &u32Value, cbReg);
+ if (IOM_SUCCESS(rcStrict))
+ {
+ switch (cbReg)
+ {
+ case 1: pCtx->al = (uint8_t)u32Value; break;
+ case 2: pCtx->ax = (uint16_t)u32Value; break;
+ case 4: pCtx->rax = u32Value; break;
+ default: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+ }
+ iemRegAddToRip(pIemCpu, cbInstr);
+ pIemCpu->cPotentialExits++;
+ }
+ /** @todo massage rcStrict. */
+ return rcStrict;
+}
+
+
+/**
+ * Implements 'IN eAX, DX'.
+ *
+ * @param cbReg The register size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_in_eAX_DX, uint8_t, cbReg)
+{
+ return IEM_CIMPL_CALL_2(iemCImpl_in, pIemCpu->CTX_SUFF(pCtx)->dx, cbReg);
+}
+
+
+/**
+ * Implements 'OUT port, eAX'.
+ *
+ * @param u16Port The destination port.
+ * @param cbReg The register size.
+ */
+IEM_CIMPL_DEF_2(iemCImpl_out, uint16_t, u16Port, uint8_t, cbReg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * CPL check
+ */
+ if ( (pCtx->cr0 & X86_CR0_PE)
+ && ( pIemCpu->uCpl > pCtx->eflags.Bits.u2IOPL
+ || pCtx->eflags.Bits.u1VM) )
+ {
+ /** @todo I/O port permission bitmap check */
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+ }
+
+ /*
+ * Perform the I/O.
+ */
+ uint32_t u32Value;
+ switch (cbReg)
+ {
+ case 1: u32Value = pCtx->al; break;
+ case 2: u32Value = pCtx->ax; break;
+ case 4: u32Value = pCtx->eax; break;
+ default: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+ }
+ VBOXSTRICTRC rc;
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ rc = IOMIOPortWrite(IEMCPU_TO_VM(pIemCpu), u16Port, u32Value, cbReg);
+ else
+ rc = iemVerifyFakeIOPortWrite(pIemCpu, u16Port, u32Value, cbReg);
+ if (IOM_SUCCESS(rc))
+ {
+ iemRegAddToRip(pIemCpu, cbInstr);
+ pIemCpu->cPotentialExits++;
+ /** @todo massage rc. */
+ }
+ return rc;
+}
+
+
+/**
+ * Implements 'OUT DX, eAX'.
+ *
+ * @param cbReg The register size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_out_DX_eAX, uint8_t, cbReg)
+{
+ return IEM_CIMPL_CALL_2(iemCImpl_out, pIemCpu->CTX_SUFF(pCtx)->dx, cbReg);
+}
+
+
+/**
+ * Implements 'CLI'.
+ */
+IEM_CIMPL_DEF_0(iemCImpl_cli)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ if (pCtx->cr0 & X86_CR0_PE)
+ {
+ uint8_t const uIopl = pCtx->eflags.Bits.u2IOPL;
+ if (!pCtx->eflags.Bits.u1VM)
+ {
+ if (pIemCpu->uCpl <= uIopl)
+ pCtx->eflags.Bits.u1IF = 0;
+ else if ( pIemCpu->uCpl == 3
+ && (pCtx->cr4 & X86_CR4_PVI) )
+ pCtx->eflags.Bits.u1VIF = 0;
+ else
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+ /* V8086 */
+ else if (uIopl == 3)
+ pCtx->eflags.Bits.u1IF = 0;
+ else if ( uIopl < 3
+ && (pCtx->cr4 & X86_CR4_VME) )
+ pCtx->eflags.Bits.u1VIF = 0;
+ else
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+ /* real mode */
+ else
+ pCtx->eflags.Bits.u1IF = 0;
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements 'STI'.
+ */
+IEM_CIMPL_DEF_0(iemCImpl_sti)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ if (pCtx->cr0 & X86_CR0_PE)
+ {
+ uint8_t const uIopl = pCtx->eflags.Bits.u2IOPL;
+ if (!pCtx->eflags.Bits.u1VM)
+ {
+ if (pIemCpu->uCpl <= uIopl)
+ pCtx->eflags.Bits.u1IF = 1;
+ else if ( pIemCpu->uCpl == 3
+ && (pCtx->cr4 & X86_CR4_PVI)
+ && !pCtx->eflags.Bits.u1VIP )
+ pCtx->eflags.Bits.u1VIF = 1;
+ else
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+ /* V8086 */
+ else if (uIopl == 3)
+ pCtx->eflags.Bits.u1IF = 1;
+ else if ( uIopl < 3
+ && (pCtx->cr4 & X86_CR4_VME)
+ && !pCtx->eflags.Bits.u1VIP )
+ pCtx->eflags.Bits.u1VIF = 1;
+ else
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ }
+ /* real mode */
+ else
+ pCtx->eflags.Bits.u1IF = 1;
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ EMSetInhibitInterruptsPC(IEMCPU_TO_VMCPU(pIemCpu), pCtx->rip);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements 'HLT'.
+ */
+IEM_CIMPL_DEF_0(iemCImpl_hlt)
+{
+ if (pIemCpu->uCpl != 0)
+ return iemRaiseGeneralProtectionFault0(pIemCpu);
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_EM_HALT;
+}
+
+
+/**
+ * Implements 'CPUID'.
+ */
+IEM_CIMPL_DEF_0(iemCImpl_cpuid)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), pCtx->eax, &pCtx->eax, &pCtx->ebx, &pCtx->ecx, &pCtx->edx);
+ pCtx->rax &= UINT32_C(0xffffffff);
+ pCtx->rbx &= UINT32_C(0xffffffff);
+ pCtx->rcx &= UINT32_C(0xffffffff);
+ pCtx->rdx &= UINT32_C(0xffffffff);
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Implements 'AAD'.
+ *
+ * @param enmEffOpSize The effective operand size.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_aad, uint8_t, bImm)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ uint16_t const ax = pCtx->ax;
+ uint8_t const al = (uint8_t)ax + (uint8_t)(ax >> 8) * bImm;
+ pCtx->ax = al;
+ iemHlpUpdateArithEFlagsU8(pIemCpu, al,
+ X86_EFL_SF | X86_EFL_SF | X86_EFL_PF,
+ X86_EFL_OF | X86_EFL_AF | X86_EFL_CF);
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+}
+
+
+
+
+/*
+ * Instantiate the various string operation combinations.
+ */
+#define OP_SIZE 8
+#define ADDR_SIZE 16
+#include "IEMAllCImplStrInstr.cpp.h"
+#define OP_SIZE 8
+#define ADDR_SIZE 32
+#include "IEMAllCImplStrInstr.cpp.h"
+#define OP_SIZE 8
+#define ADDR_SIZE 64
+#include "IEMAllCImplStrInstr.cpp.h"
+
+#define OP_SIZE 16
+#define ADDR_SIZE 16
+#include "IEMAllCImplStrInstr.cpp.h"
+#define OP_SIZE 16
+#define ADDR_SIZE 32
+#include "IEMAllCImplStrInstr.cpp.h"
+#define OP_SIZE 16
+#define ADDR_SIZE 64
+#include "IEMAllCImplStrInstr.cpp.h"
+
+#define OP_SIZE 32
+#define ADDR_SIZE 16
+#include "IEMAllCImplStrInstr.cpp.h"
+#define OP_SIZE 32
+#define ADDR_SIZE 32
+#include "IEMAllCImplStrInstr.cpp.h"
+#define OP_SIZE 32
+#define ADDR_SIZE 64
+#include "IEMAllCImplStrInstr.cpp.h"
+
+#define OP_SIZE 64
+#define ADDR_SIZE 32
+#include "IEMAllCImplStrInstr.cpp.h"
+#define OP_SIZE 64
+#define ADDR_SIZE 64
+#include "IEMAllCImplStrInstr.cpp.h"
+
+
+/**
+ * Implements 'FINIT' and 'FNINIT'.
+ *
+ * @param fCheckXcpts Whether to check for umasked pending exceptions or
+ * not.
+ */
+IEM_CIMPL_DEF_1(iemCImpl_finit, bool, fCheckXcpts)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ if (pCtx->cr0 & (X86_CR0_EM | X86_CR0_TS))
+ return iemRaiseDeviceNotAvailable(pIemCpu);
+ /** @todo trigger pending exceptions:
+ if (fCheckXcpts && TODO )
+ return iemRaiseMathFault(pIemCpu);
+ */
+
+ if (iemFRegIsFxSaveFormat(pIemCpu))
+ {
+ pCtx->fpu.FCW = 0x37f;
+ pCtx->fpu.FSW = 0;
+ pCtx->fpu.FTW = 0x00; /* 0 - empty. */
+ pCtx->fpu.FPUDP = 0;
+ pCtx->fpu.DS = 0; //??
+ pCtx->fpu.FPUIP = 0;
+ pCtx->fpu.CS = 0; //??
+ pCtx->fpu.FOP = 0;
+ }
+ else
+ {
+ PX86FPUSTATE pFpu = (PX86FPUSTATE)&pCtx->fpu;
+ pFpu->FCW = 0x37f;
+ pFpu->FSW = 0;
+ pFpu->FTW = 0xffff; /* 11 - empty */
+ pFpu->FPUOO = 0; //??
+ pFpu->FPUOS = 0; //??
+ pFpu->FPUIP = 0;
+ pFpu->CS = 0; //??
+ pFpu->FOP = 0;
+ }
+
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+}
+
+
+/** @} */
+
diff --git a/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h b/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h
new file mode 100644
index 000000000..91a13cbea
--- /dev/null
+++ b/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h
@@ -0,0 +1,1403 @@
+/* $Id: IEMAllCImplStrInstr.cpp.h 36849 2011-04-26 15:41:32Z vboxsync $ */
+/** @file
+ * IEM - String Instruction Implementation Code Template.
+ */
+
+/*
+ * 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.
+ */
+
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+#if OP_SIZE == 8
+# define OP_rAX al
+#elif OP_SIZE == 16
+# define OP_rAX ax
+#elif OP_SIZE == 32
+# define OP_rAX eax
+#elif OP_SIZE == 64
+# define OP_rAX rax
+#else
+# error "Bad OP_SIZE."
+#endif
+#define OP_TYPE RT_CONCAT3(uint,OP_SIZE,_t)
+
+#if ADDR_SIZE == 16
+# define ADDR_rDI di
+# define ADDR_rSI si
+# define ADDR_rCX cx
+# define ADDR2_TYPE uint32_t
+#elif ADDR_SIZE == 32
+# define ADDR_rDI edi
+# define ADDR_rSI esi
+# define ADDR_rCX ecx
+# define ADDR2_TYPE uint32_t
+#elif ADDR_SIZE == 64
+# define ADDR_rDI rdi
+# define ADDR_rSI rsi
+# define ADDR_rCX rcx
+# define ADDR2_TYPE uint64_t
+#else
+# error "Bad ADDR_SIZE."
+#endif
+#define ADDR_TYPE RT_CONCAT3(uint,ADDR_SIZE,_t)
+
+
+/**
+ * Implements 'REPE CMPS'.
+ */
+IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_repe_cmps_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Setup.
+ */
+ ADDR_TYPE uCounterReg = pCtx->ADDR_rCX;
+ if (uCounterReg == 0)
+ {
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ PCCPUMSELREGHID pSrc1Hid = iemSRegGetHid(pIemCpu, iEffSeg);
+ VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, pSrc1Hid, iEffSeg);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, &pCtx->esHid, X86_SREG_ES);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ int8_t const cbIncr = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+ ADDR_TYPE uSrc1AddrReg = pCtx->ADDR_rSI;
+ ADDR_TYPE uSrc2AddrReg = pCtx->ADDR_rDI;
+ uint32_t uEFlags = pCtx->eflags.u;
+
+ /*
+ * The loop.
+ */
+ do
+ {
+ /*
+ * Do segmentation and virtual page stuff.
+ */
+#if ADDR_SIZE != 64
+ ADDR2_TYPE uVirtSrc1Addr = (uint32_t)pSrc1Hid->u64Base + uSrc1AddrReg;
+ ADDR2_TYPE uVirtSrc2Addr = (uint32_t)pCtx->esHid.u64Base + uSrc2AddrReg;
+#else
+ uint64_t uVirtSrc1Addr = uSrc1AddrReg;
+ uint64_t uVirtSrc2Addr = uSrc2AddrReg;
+#endif
+ uint32_t cLeftSrc1Page = (PAGE_SIZE - (uVirtSrc1Addr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+ if (cLeftSrc1Page > uCounterReg)
+ cLeftSrc1Page = uCounterReg;
+ uint32_t cLeftSrc2Page = (PAGE_SIZE - (uVirtSrc2Addr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+ uint32_t cLeftPage = RT_MIN(cLeftSrc1Page, cLeftSrc2Page);
+
+ if ( cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+ && cbIncr > 0 /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+ && uSrc1AddrReg < pSrc1Hid->u32Limit
+ && uSrc1AddrReg + (cLeftPage * (OP_SIZE / 8)) <= pSrc1Hid->u32Limit
+ && uSrc2AddrReg < pCtx->esHid.u32Limit
+ && uSrc2AddrReg + (cLeftPage * (OP_SIZE / 8)) <= pCtx->esHid.u32Limit
+#endif
+ )
+ {
+ RTGCPHYS GCPhysSrc1Mem;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtSrc1Addr, IEM_ACCESS_DATA_R, &GCPhysSrc1Mem);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ RTGCPHYS GCPhysSrc2Mem;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtSrc2Addr, IEM_ACCESS_DATA_R, &GCPhysSrc2Mem);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ /*
+ * If we can map the page without trouble, do a block processing
+ * until the end of the current page.
+ */
+ OP_TYPE const *puSrc2Mem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysSrc2Mem, IEM_ACCESS_DATA_R, (void **)&puSrc2Mem);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ OP_TYPE const *puSrc1Mem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysSrc1Mem, IEM_ACCESS_DATA_R, (void **)&puSrc1Mem);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ if (!memcmp(puSrc2Mem, puSrc1Mem, cLeftPage * (OP_SIZE / 8)))
+ {
+ /* All matches, only compare the last itme to get the right eflags. */
+ RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)&puSrc1Mem[cLeftPage-1], puSrc2Mem[cLeftPage-1], &uEFlags);
+ uSrc1AddrReg += cLeftPage * cbIncr;
+ uSrc2AddrReg += cLeftPage * cbIncr;
+ uCounterReg -= cLeftPage;
+ }
+ else
+ {
+ /* Some mismatch, compare each item (and keep volatile
+ memory in mind). */
+ do
+ {
+ RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)puSrc1Mem, *puSrc2Mem, &uEFlags);
+ uSrc1AddrReg += cbIncr;
+ uSrc2AddrReg += cbIncr;
+ uCounterReg--;
+ puSrc1Mem++;
+ puSrc2Mem++;
+ cLeftPage--;
+ } while ( (int32_t)cLeftPage > 0
+ && (uEFlags & X86_EFL_ZF));
+ }
+ continue;
+ }
+ }
+ }
+
+ /*
+ * Fallback - slow processing till the end of the current page.
+ * In the cross page boundrary case we will end up here with cLeftPage
+ * as 0, we execute one loop then.
+ */
+ do
+ {
+ OP_TYPE uValue1;
+ rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue1, iEffSeg, uSrc1AddrReg);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ OP_TYPE uValue2;
+ rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue2, X86_SREG_ES, uSrc2AddrReg);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)(&uValue1, uValue2, &uEFlags);
+
+ uSrc1AddrReg += cbIncr;
+ uSrc2AddrReg += cbIncr;
+ uCounterReg--;
+ cLeftPage--;
+ } while ( (int32_t)cLeftPage > 0
+ && (uEFlags & X86_EFL_ZF));
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ } while ( uCounterReg != 0
+ && (uEFlags & X86_EFL_ZF));
+
+ /*
+ * Update the registers.
+ */
+ pCtx->ADDR_rCX = uCounterReg;
+ pCtx->ADDR_rSI = uSrc1AddrReg;
+ pCtx->ADDR_rDI = uSrc2AddrReg;
+ pCtx->eflags.u = uEFlags;
+ if (rcStrict == VINF_SUCCESS)
+ iemRegAddToRip(pIemCpu, cbInstr);
+
+ return rcStrict;
+}
+
+
+/**
+ * Implements 'REPNE CMPS'.
+ */
+IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_repne_cmps_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Setup.
+ */
+ ADDR_TYPE uCounterReg = pCtx->ADDR_rCX;
+ if (uCounterReg == 0)
+ {
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ PCCPUMSELREGHID pSrc1Hid = iemSRegGetHid(pIemCpu, iEffSeg);
+ VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, pSrc1Hid, iEffSeg);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, &pCtx->esHid, X86_SREG_ES);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ int8_t const cbIncr = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+ ADDR_TYPE uSrc1AddrReg = pCtx->ADDR_rSI;
+ ADDR_TYPE uSrc2AddrReg = pCtx->ADDR_rDI;
+ uint32_t uEFlags = pCtx->eflags.u;
+
+ /*
+ * The loop.
+ */
+ do
+ {
+ /*
+ * Do segmentation and virtual page stuff.
+ */
+#if ADDR_SIZE != 64
+ ADDR2_TYPE uVirtSrc1Addr = (uint32_t)pSrc1Hid->u64Base + uSrc1AddrReg;
+ ADDR2_TYPE uVirtSrc2Addr = (uint32_t)pCtx->esHid.u64Base + uSrc2AddrReg;
+#else
+ uint64_t uVirtSrc1Addr = uSrc1AddrReg;
+ uint64_t uVirtSrc2Addr = uSrc2AddrReg;
+#endif
+ uint32_t cLeftSrc1Page = (PAGE_SIZE - (uVirtSrc1Addr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+ if (cLeftSrc1Page > uCounterReg)
+ cLeftSrc1Page = uCounterReg;
+ uint32_t cLeftSrc2Page = (PAGE_SIZE - (uVirtSrc2Addr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+ uint32_t cLeftPage = RT_MIN(cLeftSrc1Page, cLeftSrc2Page);
+
+ if ( cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+ && cbIncr > 0 /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+ && uSrc1AddrReg < pSrc1Hid->u32Limit
+ && uSrc1AddrReg + (cLeftPage * (OP_SIZE / 8)) <= pSrc1Hid->u32Limit
+ && uSrc2AddrReg < pCtx->esHid.u32Limit
+ && uSrc2AddrReg + (cLeftPage * (OP_SIZE / 8)) <= pCtx->esHid.u32Limit
+#endif
+ )
+ {
+ RTGCPHYS GCPhysSrc1Mem;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtSrc1Addr, IEM_ACCESS_DATA_R, &GCPhysSrc1Mem);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ RTGCPHYS GCPhysSrc2Mem;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtSrc2Addr, IEM_ACCESS_DATA_R, &GCPhysSrc2Mem);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ /*
+ * If we can map the page without trouble, do a block processing
+ * until the end of the current page.
+ */
+ OP_TYPE const *puSrc2Mem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysSrc2Mem, IEM_ACCESS_DATA_R, (void **)&puSrc2Mem);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ OP_TYPE const *puSrc1Mem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysSrc1Mem, IEM_ACCESS_DATA_R, (void **)&puSrc1Mem);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ if (memcmp(puSrc2Mem, puSrc1Mem, cLeftPage * (OP_SIZE / 8)))
+ {
+ /* All matches, only compare the last itme to get the right eflags. */
+ RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)&puSrc1Mem[cLeftPage-1], puSrc2Mem[cLeftPage-1], &uEFlags);
+ uSrc1AddrReg += cLeftPage * cbIncr;
+ uSrc2AddrReg += cLeftPage * cbIncr;
+ uCounterReg -= cLeftPage;
+ }
+ else
+ {
+ /* Some mismatch, compare each item (and keep volatile
+ memory in mind). */
+ do
+ {
+ RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)puSrc1Mem, *puSrc2Mem, &uEFlags);
+ uSrc1AddrReg += cbIncr;
+ uSrc2AddrReg += cbIncr;
+ uCounterReg--;
+ puSrc1Mem++;
+ puSrc2Mem++;
+ cLeftPage--;
+ } while ( (int32_t)cLeftPage > 0
+ && !(uEFlags & X86_EFL_ZF));
+ }
+ continue;
+ }
+ }
+ }
+
+ /*
+ * Fallback - slow processing till the end of the current page.
+ * In the cross page boundrary case we will end up here with cLeftPage
+ * as 0, we execute one loop then.
+ */
+ do
+ {
+ OP_TYPE uValue1;
+ rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue1, iEffSeg, uSrc1AddrReg);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ OP_TYPE uValue2;
+ rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue2, X86_SREG_ES, uSrc2AddrReg);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)(&uValue1, uValue2, &uEFlags);
+
+ uSrc1AddrReg += cbIncr;
+ uSrc2AddrReg += cbIncr;
+ uCounterReg--;
+ cLeftPage--;
+ } while ( (int32_t)cLeftPage > 0
+ && !(uEFlags & X86_EFL_ZF));
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ } while ( uCounterReg != 0
+ && !(uEFlags & X86_EFL_ZF));
+
+ /*
+ * Update the registers.
+ */
+ pCtx->ADDR_rCX = uCounterReg;
+ pCtx->ADDR_rSI = uSrc1AddrReg;
+ pCtx->ADDR_rDI = uSrc2AddrReg;
+ pCtx->eflags.u = uEFlags;
+ if (rcStrict == VINF_SUCCESS)
+ iemRegAddToRip(pIemCpu, cbInstr);
+
+ return rcStrict;
+}
+
+
+/**
+ * Implements 'REPE SCAS'.
+ */
+IEM_CIMPL_DEF_0(RT_CONCAT4(iemCImpl_repe_scas_,OP_rAX,_m,ADDR_SIZE))
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Setup.
+ */
+ ADDR_TYPE uCounterReg = pCtx->ADDR_rCX;
+ if (uCounterReg == 0)
+ {
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, &pCtx->esHid, X86_SREG_ES);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ int8_t const cbIncr = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+ OP_TYPE const uValueReg = pCtx->OP_rAX;
+ ADDR_TYPE uAddrReg = pCtx->ADDR_rDI;
+ uint32_t uEFlags = pCtx->eflags.u;
+
+ /*
+ * The loop.
+ */
+ do
+ {
+ /*
+ * Do segmentation and virtual page stuff.
+ */
+#if ADDR_SIZE != 64
+ ADDR2_TYPE uVirtAddr = (uint32_t)pCtx->esHid.u64Base + uAddrReg;
+#else
+ uint64_t uVirtAddr = uAddrReg;
+#endif
+ uint32_t cLeftPage = (PAGE_SIZE - (uVirtAddr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+ if (cLeftPage > uCounterReg)
+ cLeftPage = uCounterReg;
+ if ( cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+ && cbIncr > 0 /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+ && uAddrReg < pCtx->esHid.u32Limit
+ && uAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pCtx->esHid.u32Limit
+#endif
+ )
+ {
+ RTGCPHYS GCPhysMem;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtAddr, IEM_ACCESS_DATA_R, &GCPhysMem);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ /*
+ * If we can map the page without trouble, do a block processing
+ * until the end of the current page.
+ */
+ OP_TYPE const *puMem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_R, (void **)&puMem);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ /* Search till we find a mismatching item. */
+ OP_TYPE uTmpValue;
+ bool fQuit;
+ uint32_t i = 0;
+ do
+ {
+ uTmpValue = puMem[i++];
+ fQuit = uTmpValue != uValueReg;
+ } while (i < cLeftPage && !fQuit);
+
+ /* Update the regs. */
+ RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)&uValueReg, uTmpValue, &uEFlags);
+ uCounterReg -= i;
+ uAddrReg += i * cbIncr;
+ Assert(!(uEFlags & X86_EFL_ZF) == (i < cLeftPage));
+ if (fQuit)
+ break;
+
+
+ /* If unaligned, we drop thru and do the page crossing access
+ below. Otherwise, do the next page. */
+ if (!(uVirtAddr & (OP_SIZE - 1)))
+ continue;
+ if (uCounterReg == 0)
+ break;
+ cLeftPage = 0;
+ }
+ }
+
+ /*
+ * Fallback - slow processing till the end of the current page.
+ * In the cross page boundrary case we will end up here with cLeftPage
+ * as 0, we execute one loop then.
+ */
+ do
+ {
+ OP_TYPE uTmpValue;
+ rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uTmpValue, X86_SREG_ES, uAddrReg);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)&uValueReg, uTmpValue, &uEFlags);
+
+ uAddrReg += cbIncr;
+ uCounterReg--;
+ cLeftPage--;
+ } while ( (int32_t)cLeftPage > 0
+ && (uEFlags & X86_EFL_ZF));
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ } while ( uCounterReg != 0
+ && (uEFlags & X86_EFL_ZF));
+
+ /*
+ * Update the registers.
+ */
+ pCtx->ADDR_rCX = uCounterReg;
+ pCtx->ADDR_rDI = uAddrReg;
+ pCtx->eflags.u = uEFlags;
+ if (rcStrict == VINF_SUCCESS)
+ iemRegAddToRip(pIemCpu, cbInstr);
+
+ return rcStrict;
+}
+
+
+/**
+ * Implements 'REPNE SCAS'.
+ */
+IEM_CIMPL_DEF_0(RT_CONCAT4(iemCImpl_repne_scas_,OP_rAX,_m,ADDR_SIZE))
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Setup.
+ */
+ ADDR_TYPE uCounterReg = pCtx->ADDR_rCX;
+ if (uCounterReg == 0)
+ {
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, &pCtx->esHid, X86_SREG_ES);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ int8_t const cbIncr = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+ OP_TYPE const uValueReg = pCtx->OP_rAX;
+ ADDR_TYPE uAddrReg = pCtx->ADDR_rDI;
+ uint32_t uEFlags = pCtx->eflags.u;
+
+ /*
+ * The loop.
+ */
+ do
+ {
+ /*
+ * Do segmentation and virtual page stuff.
+ */
+#if ADDR_SIZE != 64
+ ADDR2_TYPE uVirtAddr = (uint32_t)pCtx->esHid.u64Base + uAddrReg;
+#else
+ uint64_t uVirtAddr = uAddrReg;
+#endif
+ uint32_t cLeftPage = (PAGE_SIZE - (uVirtAddr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+ if (cLeftPage > uCounterReg)
+ cLeftPage = uCounterReg;
+ if ( cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+ && cbIncr > 0 /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+ && uAddrReg < pCtx->esHid.u32Limit
+ && uAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pCtx->esHid.u32Limit
+#endif
+ )
+ {
+ RTGCPHYS GCPhysMem;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtAddr, IEM_ACCESS_DATA_R, &GCPhysMem);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ /*
+ * If we can map the page without trouble, do a block processing
+ * until the end of the current page.
+ */
+ OP_TYPE const *puMem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_R, (void **)&puMem);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ /* Search till we find a mismatching item. */
+ OP_TYPE uTmpValue;
+ bool fQuit;
+ uint32_t i = 0;
+ do
+ {
+ uTmpValue = puMem[i++];
+ fQuit = uTmpValue == uValueReg;
+ } while (i < cLeftPage && !fQuit);
+
+ /* Update the regs. */
+ RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)&uValueReg, uTmpValue, &uEFlags);
+ uCounterReg -= i;
+ uAddrReg += i * cbIncr;
+ Assert(!(uEFlags & X86_EFL_ZF) != (i < cLeftPage));
+ if (fQuit)
+ break;
+
+
+ /* If unaligned, we drop thru and do the page crossing access
+ below. Otherwise, do the next page. */
+ if (!(uVirtAddr & (OP_SIZE - 1)))
+ continue;
+ if (uCounterReg == 0)
+ break;
+ cLeftPage = 0;
+ }
+ }
+
+ /*
+ * Fallback - slow processing till the end of the current page.
+ * In the cross page boundrary case we will end up here with cLeftPage
+ * as 0, we execute one loop then.
+ */
+ do
+ {
+ OP_TYPE uTmpValue;
+ rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uTmpValue, X86_SREG_ES, uAddrReg);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)&uValueReg, uTmpValue, &uEFlags);
+
+ uAddrReg += cbIncr;
+ uCounterReg--;
+ cLeftPage--;
+ } while ( (int32_t)cLeftPage > 0
+ && !(uEFlags & X86_EFL_ZF));
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ } while ( uCounterReg != 0
+ && !(uEFlags & X86_EFL_ZF));
+
+ /*
+ * Update the registers.
+ */
+ pCtx->ADDR_rCX = uCounterReg;
+ pCtx->ADDR_rDI = uAddrReg;
+ pCtx->eflags.u = uEFlags;
+ if (rcStrict == VINF_SUCCESS)
+ iemRegAddToRip(pIemCpu, cbInstr);
+
+ return rcStrict;
+}
+
+
+
+
+/**
+ * Implements 'REP MOVS'.
+ */
+IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_rep_movs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Setup.
+ */
+ ADDR_TYPE uCounterReg = pCtx->ADDR_rCX;
+ if (uCounterReg == 0)
+ {
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ PCCPUMSELREGHID pSrcHid = iemSRegGetHid(pIemCpu, iEffSeg);
+ VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, pSrcHid, iEffSeg);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ rcStrict = iemMemSegCheckWriteAccessEx(pIemCpu, &pCtx->esHid, X86_SREG_ES);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ int8_t const cbIncr = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+ ADDR_TYPE uSrcAddrReg = pCtx->ADDR_rSI;
+ ADDR_TYPE uDstAddrReg = pCtx->ADDR_rDI;
+
+ /*
+ * The loop.
+ */
+ do
+ {
+ /*
+ * Do segmentation and virtual page stuff.
+ */
+#if ADDR_SIZE != 64
+ ADDR2_TYPE uVirtSrcAddr = (uint32_t)pSrcHid->u64Base + uSrcAddrReg;
+ ADDR2_TYPE uVirtDstAddr = (uint32_t)pCtx->esHid.u64Base + uDstAddrReg;
+#else
+ uint64_t uVirtSrcAddr = uSrcAddrReg;
+ uint64_t uVirtDstAddr = uDstAddrReg;
+#endif
+ uint32_t cLeftSrcPage = (PAGE_SIZE - (uVirtSrcAddr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+ if (cLeftSrcPage > uCounterReg)
+ cLeftSrcPage = uCounterReg;
+ uint32_t cLeftDstPage = (PAGE_SIZE - (uVirtDstAddr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+ uint32_t cLeftPage = RT_MIN(cLeftSrcPage, cLeftDstPage);
+
+ if ( cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+ && cbIncr > 0 /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+ && uSrcAddrReg < pSrcHid->u32Limit
+ && uSrcAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pSrcHid->u32Limit
+ && uDstAddrReg < pCtx->esHid.u32Limit
+ && uDstAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pCtx->esHid.u32Limit
+#endif
+ )
+ {
+ RTGCPHYS GCPhysSrcMem;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtSrcAddr, IEM_ACCESS_DATA_R, &GCPhysSrcMem);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ RTGCPHYS GCPhysDstMem;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtDstAddr, IEM_ACCESS_DATA_W, &GCPhysDstMem);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ /*
+ * If we can map the page without trouble, do a block processing
+ * until the end of the current page.
+ */
+ OP_TYPE *puDstMem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysDstMem, IEM_ACCESS_DATA_W, (void **)&puDstMem);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ OP_TYPE const *puSrcMem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysSrcMem, IEM_ACCESS_DATA_R, (void **)&puSrcMem);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ /* Perform the operation. */
+ memcpy(puDstMem, puSrcMem, cLeftPage * (OP_SIZE / 8));
+
+ /* Update the registers. */
+ uSrcAddrReg += cLeftPage * cbIncr;
+ uDstAddrReg += cLeftPage * cbIncr;
+ uCounterReg -= cLeftPage;
+ continue;
+ }
+ }
+ }
+
+ /*
+ * Fallback - slow processing till the end of the current page.
+ * In the cross page boundrary case we will end up here with cLeftPage
+ * as 0, we execute one loop then.
+ */
+ do
+ {
+ OP_TYPE uValue;
+ rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue, iEffSeg, uSrcAddrReg);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ rcStrict = RT_CONCAT(iemMemStoreDataU,OP_SIZE)(pIemCpu, X86_SREG_ES, uDstAddrReg, uValue);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ uSrcAddrReg += cbIncr;
+ uDstAddrReg += cbIncr;
+ uCounterReg--;
+ cLeftPage--;
+ } while ((int32_t)cLeftPage > 0);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ } while (uCounterReg != 0);
+
+ /*
+ * Update the registers.
+ */
+ pCtx->ADDR_rCX = uCounterReg;
+ pCtx->ADDR_rDI = uDstAddrReg;
+ pCtx->ADDR_rSI = uSrcAddrReg;
+ if (rcStrict == VINF_SUCCESS)
+ iemRegAddToRip(pIemCpu, cbInstr);
+
+ return rcStrict;
+}
+
+
+/**
+ * Implements 'REP STOS'.
+ */
+IEM_CIMPL_DEF_0(RT_CONCAT4(iemCImpl_stos_,OP_rAX,_m,ADDR_SIZE))
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Setup.
+ */
+ ADDR_TYPE uCounterReg = pCtx->ADDR_rCX;
+ if (uCounterReg == 0)
+ {
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ VBOXSTRICTRC rcStrict = iemMemSegCheckWriteAccessEx(pIemCpu, &pCtx->esHid, X86_SREG_ES);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ int8_t const cbIncr = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+ OP_TYPE const uValue = pCtx->OP_rAX;
+ ADDR_TYPE uAddrReg = pCtx->ADDR_rDI;
+
+ /*
+ * The loop.
+ */
+ do
+ {
+ /*
+ * Do segmentation and virtual page stuff.
+ */
+#if ADDR_SIZE != 64
+ ADDR2_TYPE uVirtAddr = (uint32_t)pCtx->esHid.u64Base + uAddrReg;
+#else
+ uint64_t uVirtAddr = uAddrReg;
+#endif
+ uint32_t cLeftPage = (PAGE_SIZE - (uVirtAddr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+ if (cLeftPage > uCounterReg)
+ cLeftPage = uCounterReg;
+ if ( cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+ && cbIncr > 0 /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+ && uAddrReg < pCtx->esHid.u32Limit
+ && uAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pCtx->esHid.u32Limit
+#endif
+ )
+ {
+ RTGCPHYS GCPhysMem;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtAddr, IEM_ACCESS_DATA_W, &GCPhysMem);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ /*
+ * If we can map the page without trouble, do a block processing
+ * until the end of the current page.
+ */
+ OP_TYPE *puMem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_W, (void **)&puMem);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ /* Update the regs first so we can loop on cLeftPage. */
+ uCounterReg -= cLeftPage;
+ uAddrReg += cLeftPage * cbIncr;
+
+ /* Do the memsetting. */
+#if OP_SIZE == 8
+ memset(puMem, uValue, cLeftPage);
+/*#elif OP_SIZE == 32
+ ASMMemFill32(puMem, cLeftPage * (OP_SIZE / 8), uValue);*/
+#else
+ while (cLeftPage-- > 0)
+ *puMem++ = uValue;
+#endif
+
+ /* If unaligned, we drop thru and do the page crossing access
+ below. Otherwise, do the next page. */
+ if (!(uVirtAddr & (OP_SIZE - 1)))
+ continue;
+ if (uCounterReg == 0)
+ break;
+ cLeftPage = 0;
+ }
+ }
+
+ /*
+ * Fallback - slow processing till the end of the current page.
+ * In the cross page boundrary case we will end up here with cLeftPage
+ * as 0, we execute one loop then.
+ */
+ do
+ {
+ rcStrict = RT_CONCAT(iemMemStoreDataU,OP_SIZE)(pIemCpu, X86_SREG_ES, uAddrReg, uValue);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ uAddrReg += cbIncr;
+ uCounterReg--;
+ cLeftPage--;
+ } while ((int32_t)cLeftPage > 0);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ } while (uCounterReg != 0);
+
+ /*
+ * Update the registers.
+ */
+ pCtx->ADDR_rCX = uCounterReg;
+ pCtx->ADDR_rDI = uAddrReg;
+ if (rcStrict == VINF_SUCCESS)
+ iemRegAddToRip(pIemCpu, cbInstr);
+
+ return rcStrict;
+}
+
+
+/**
+ * Implements 'REP LODS'.
+ */
+IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_lods_,OP_rAX,_m,ADDR_SIZE), int8_t, iEffSeg)
+{
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Setup.
+ */
+ ADDR_TYPE uCounterReg = pCtx->ADDR_rCX;
+ if (uCounterReg == 0)
+ {
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ PCCPUMSELREGHID pSrcHid = iemSRegGetHid(pIemCpu, iEffSeg);
+ VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, pSrcHid, iEffSeg);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ int8_t const cbIncr = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+ OP_TYPE uValueReg = pCtx->OP_rAX;
+ ADDR_TYPE uAddrReg = pCtx->ADDR_rSI;
+
+ /*
+ * The loop.
+ */
+ do
+ {
+ /*
+ * Do segmentation and virtual page stuff.
+ */
+#if ADDR_SIZE != 64
+ ADDR2_TYPE uVirtAddr = (uint32_t)pSrcHid->u64Base + uAddrReg;
+#else
+ uint64_t uVirtAddr = uAddrReg;
+#endif
+ uint32_t cLeftPage = (PAGE_SIZE - (uVirtAddr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+ if (cLeftPage > uCounterReg)
+ cLeftPage = uCounterReg;
+ if ( cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+ && cbIncr > 0 /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+ && uAddrReg < pSrcHid->u32Limit
+ && uAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pSrcHid->u32Limit
+#endif
+ )
+ {
+ RTGCPHYS GCPhysMem;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtAddr, IEM_ACCESS_DATA_R, &GCPhysMem);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ /*
+ * If we can map the page without trouble, we can get away with
+ * just reading the last value on the page.
+ */
+ OP_TYPE const *puMem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_R, (void **)&puMem);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ /* Only get the last byte, the rest doesn't matter in direct access mode. */
+ uValueReg = puMem[cLeftPage - 1];
+
+ /* Update the regs. */
+ uCounterReg -= cLeftPage;
+ uAddrReg += cLeftPage * cbIncr;
+
+ /* If unaligned, we drop thru and do the page crossing access
+ below. Otherwise, do the next page. */
+ if (!(uVirtAddr & (OP_SIZE - 1)))
+ continue;
+ if (uCounterReg == 0)
+ break;
+ cLeftPage = 0;
+ }
+ }
+
+ /*
+ * Fallback - slow processing till the end of the current page.
+ * In the cross page boundrary case we will end up here with cLeftPage
+ * as 0, we execute one loop then.
+ */
+ do
+ {
+ OP_TYPE uTmpValue;
+ rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uTmpValue, iEffSeg, uAddrReg);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ uValueReg = uTmpValue;
+ uAddrReg += cbIncr;
+ uCounterReg--;
+ cLeftPage--;
+ } while ((int32_t)cLeftPage > 0);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ } while (uCounterReg != 0);
+
+ /*
+ * Update the registers.
+ */
+ pCtx->ADDR_rCX = uCounterReg;
+ pCtx->ADDR_rDI = uAddrReg;
+#if OP_SIZE == 32
+ pCtx->rax = uValueReg;
+#else
+ pCtx->OP_rAX = uValueReg;
+#endif
+ if (rcStrict == VINF_SUCCESS)
+ iemRegAddToRip(pIemCpu, cbInstr);
+
+ return rcStrict;
+}
+
+
+#if OP_SIZE != 64
+
+/**
+ * Implements 'INS' (no rep)
+ */
+IEM_CIMPL_DEF_0(RT_CONCAT4(iemCImpl_ins_op,OP_SIZE,_addr,ADDR_SIZE))
+{
+ PVM pVM = IEMCPU_TO_VM(pIemCpu);
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ VBOXSTRICTRC rcStrict;
+
+ /*
+ * ASSUMES the #GP for I/O permission is taken first, then any #GP for
+ * segmentation and finally any #PF due to virtual address translation.
+ * ASSUMES nothing is read from the I/O port before traps are taken.
+ */
+ rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, pCtx->dx, OP_SIZE / 8);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ OP_TYPE *puMem;
+ rcStrict = iemMemMap(pIemCpu, (void **)&puMem, OP_SIZE / 8, X86_SREG_ES, pCtx->ADDR_rDI, IEM_ACCESS_DATA_W);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ uint32_t u32Value;
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ rcStrict = IOMIOPortRead(pVM, pCtx->dx, &u32Value, OP_SIZE / 8);
+ else
+ rcStrict = iemVerifyFakeIOPortRead(pIemCpu, pCtx->dx, &u32Value, OP_SIZE / 8);
+ if (IOM_SUCCESS(rcStrict))
+ {
+ VBOXSTRICTRC rcStrict2 = iemMemCommitAndUnmap(pIemCpu, puMem, IEM_ACCESS_DATA_W);
+ if (RT_LIKELY(rcStrict2 == VINF_SUCCESS))
+ {
+ if (!pCtx->eflags.Bits.u1DF)
+ pCtx->ADDR_rDI += OP_SIZE / 8;
+ else
+ pCtx->ADDR_rDI -= OP_SIZE / 8;
+ iemRegAddToRip(pIemCpu, cbInstr);
+ }
+ /* iemMemMap already check permissions, so this may only be real errors
+ or access handlers medling. The access handler case is going to
+ cause misbehavior if the instruction is re-interpreted or smth. So,
+ we fail with an internal error here instead. */
+ else
+ AssertLogRelFailedReturn(VERR_INTERNAL_ERROR_3);
+ }
+ return rcStrict;
+}
+
+
+/**
+ * Implements 'REP INS'.
+ */
+IEM_CIMPL_DEF_0(RT_CONCAT4(iemCImpl_rep_ins_op,OP_SIZE,_addr,ADDR_SIZE))
+{
+ PVM pVM = IEMCPU_TO_VM(pIemCpu);
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Setup.
+ */
+ uint16_t const u16Port = pCtx->dx;
+ VBOXSTRICTRC rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, u16Port, OP_SIZE / 8);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ ADDR_TYPE uCounterReg = pCtx->ADDR_rCX;
+ if (uCounterReg == 0)
+ {
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ rcStrict = iemMemSegCheckWriteAccessEx(pIemCpu, &pCtx->esHid, X86_SREG_ES);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ int8_t const cbIncr = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+ ADDR_TYPE uAddrReg = pCtx->ADDR_rDI;
+
+ /*
+ * The loop.
+ */
+ do
+ {
+ /*
+ * Do segmentation and virtual page stuff.
+ */
+#if ADDR_SIZE != 64
+ ADDR2_TYPE uVirtAddr = (uint32_t)pCtx->esHid.u64Base + uAddrReg;
+#else
+ uint64_t uVirtAddr = uAddrReg;
+#endif
+ uint32_t cLeftPage = (PAGE_SIZE - (uVirtAddr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+ if (cLeftPage > uCounterReg)
+ cLeftPage = uCounterReg;
+ if ( cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+ && cbIncr > 0 /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+ && uAddrReg < pCtx->esHid.u32Limit
+ && uAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pCtx->esHid.u32Limit
+#endif
+ )
+ {
+ RTGCPHYS GCPhysMem;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtAddr, IEM_ACCESS_DATA_W, &GCPhysMem);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ /*
+ * If we can map the page without trouble, we would've liked to use
+ * an string I/O method to do the work, but the current IOM
+ * interface doesn't match our current approach. So, do a regular
+ * loop instead.
+ */
+ /** @todo Change the I/O manager interface to make use of
+ * mapped buffers instead of leaving those bits to the
+ * device implementation? */
+ OP_TYPE *puMem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_W, (void **)&puMem);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ while (cLeftPage-- > 0)
+ {
+ uint32_t u32Value;
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ rcStrict = IOMIOPortRead(pVM, u16Port, &u32Value, OP_SIZE / 8);
+ else
+ rcStrict = iemVerifyFakeIOPortRead(pIemCpu, u16Port, &u32Value, OP_SIZE / 8);
+ if (!IOM_SUCCESS(rcStrict))
+ break;
+ *puMem++ = (OP_TYPE)u32Value;
+ uAddrReg += cbIncr;
+ uCounterReg -= 1;
+
+ if (rcStrict != VINF_SUCCESS)
+ {
+ /** @todo massage rc */
+ break;
+ }
+ }
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ /* If unaligned, we drop thru and do the page crossing access
+ below. Otherwise, do the next page. */
+ if (!(uVirtAddr & (OP_SIZE - 1)))
+ continue;
+ if (uCounterReg == 0)
+ break;
+ cLeftPage = 0;
+ }
+ }
+
+ /*
+ * Fallback - slow processing till the end of the current page.
+ * In the cross page boundrary case we will end up here with cLeftPage
+ * as 0, we execute one loop then.
+ *
+ * Note! We ASSUME the CPU will raise #PF or #GP before access the
+ * I/O port, otherwise it wouldn't really be restartable.
+ */
+ /** @todo investigate what the CPU actually does with \#PF/\#GP
+ * during INS. */
+ do
+ {
+ OP_TYPE *puMem;
+ rcStrict = iemMemMap(pIemCpu, (void **)&puMem, OP_SIZE / 8, X86_SREG_ES, uAddrReg, IEM_ACCESS_DATA_W);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ uint32_t u32Value;
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ rcStrict = IOMIOPortRead(pVM, u16Port, &u32Value, OP_SIZE / 8);
+ else
+ rcStrict = iemVerifyFakeIOPortRead(pIemCpu, u16Port, &u32Value, OP_SIZE / 8);
+ if (!IOM_SUCCESS(rcStrict))
+ break;
+
+ VBOXSTRICTRC rcStrict2 = iemMemCommitAndUnmap(pIemCpu, puMem, IEM_ACCESS_DATA_W);
+ AssertLogRelBreakStmt(rcStrict2 == VINF_SUCCESS, rcStrict = VERR_INTERNAL_ERROR_3); /* See non-rep version. */
+
+ uAddrReg += cbIncr;
+ uCounterReg--;
+ cLeftPage--;
+ if (rcStrict != VINF_SUCCESS)
+ {
+ /** @todo massage IOM status codes! */
+ break;
+ }
+ } while ((int32_t)cLeftPage > 0);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ } while (uCounterReg != 0);
+
+ /*
+ * Update the registers.
+ */
+ pCtx->ADDR_rCX = uCounterReg;
+ pCtx->ADDR_rDI = uAddrReg;
+ if (rcStrict == VINF_SUCCESS)
+ iemRegAddToRip(pIemCpu, cbInstr);
+
+ return rcStrict;
+}
+
+
+/**
+ * Implements 'OUTS' (no rep)
+ */
+IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_outs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)
+{
+ PVM pVM = IEMCPU_TO_VM(pIemCpu);
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ VBOXSTRICTRC rcStrict;
+
+ /*
+ * ASSUMES the #GP for I/O permission is taken first, then any #GP for
+ * segmentation and finally any #PF due to virtual address translation.
+ * ASSUMES nothing is read from the I/O port before traps are taken.
+ */
+ rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, pCtx->dx, OP_SIZE / 8);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ OP_TYPE uValue;
+ rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue, iEffSeg, pCtx->ADDR_rSI);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ rcStrict = IOMIOPortWrite(pVM, pCtx->dx, uValue, OP_SIZE / 8);
+ else
+ rcStrict = iemVerifyFakeIOPortWrite(pIemCpu, pCtx->dx, uValue, OP_SIZE / 8);
+ if (IOM_SUCCESS(rcStrict))
+ {
+ if (!pCtx->eflags.Bits.u1DF)
+ pCtx->ADDR_rSI += OP_SIZE / 8;
+ else
+ pCtx->ADDR_rSI -= OP_SIZE / 8;
+ iemRegAddToRip(pIemCpu, cbInstr);
+ /** @todo massage IOM status codes. */
+ }
+ }
+ return rcStrict;
+}
+
+
+/**
+ * Implements 'REP OUTS'.
+ */
+IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_rep_outs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)
+{
+ PVM pVM = IEMCPU_TO_VM(pIemCpu);
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+ /*
+ * Setup.
+ */
+ uint16_t const u16Port = pCtx->dx;
+ VBOXSTRICTRC rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, u16Port, OP_SIZE / 8);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ ADDR_TYPE uCounterReg = pCtx->ADDR_rCX;
+ if (uCounterReg == 0)
+ {
+ iemRegAddToRip(pIemCpu, cbInstr);
+ return VINF_SUCCESS;
+ }
+
+ PCCPUMSELREGHID pHid = iemSRegGetHid(pIemCpu, iEffSeg);
+ rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, pHid, iEffSeg);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+
+ int8_t const cbIncr = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+ ADDR_TYPE uAddrReg = pCtx->ADDR_rSI;
+
+ /*
+ * The loop.
+ */
+ do
+ {
+ /*
+ * Do segmentation and virtual page stuff.
+ */
+#if ADDR_SIZE != 64
+ ADDR2_TYPE uVirtAddr = (uint32_t)pHid->u64Base + uAddrReg;
+#else
+ uint64_t uVirtAddr = uAddrReg;
+#endif
+ uint32_t cLeftPage = (PAGE_SIZE - (uVirtAddr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+ if (cLeftPage > uCounterReg)
+ cLeftPage = uCounterReg;
+ if ( cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+ && cbIncr > 0 /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+ && uAddrReg < pHid->u32Limit
+ && uAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pHid->u32Limit
+#endif
+ )
+ {
+ RTGCPHYS GCPhysMem;
+ rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtAddr, IEM_ACCESS_DATA_R, &GCPhysMem);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ /*
+ * If we can map the page without trouble, we would've liked to use
+ * an string I/O method to do the work, but the current IOM
+ * interface doesn't match our current approach. So, do a regular
+ * loop instead.
+ */
+ /** @todo Change the I/O manager interface to make use of
+ * mapped buffers instead of leaving those bits to the
+ * device implementation? */
+ OP_TYPE const *puMem;
+ rcStrict = iemMemPageMap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_R, (void **)&puMem);
+ if (rcStrict == VINF_SUCCESS)
+ {
+ while (cLeftPage-- > 0)
+ {
+ uint32_t u32Value = *puMem++;
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ rcStrict = IOMIOPortWrite(pVM, u16Port, u32Value, OP_SIZE / 8);
+ else
+ rcStrict = iemVerifyFakeIOPortWrite(pIemCpu, u16Port, u32Value, OP_SIZE / 8);
+ if (!IOM_SUCCESS(rcStrict))
+ break;
+ uAddrReg += cbIncr;
+ uCounterReg -= 1;
+
+ if (rcStrict != VINF_SUCCESS)
+ {
+ /** @todo massage IOM rc */
+ break;
+ }
+ }
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ /* If unaligned, we drop thru and do the page crossing access
+ below. Otherwise, do the next page. */
+ if (!(uVirtAddr & (OP_SIZE - 1)))
+ continue;
+ if (uCounterReg == 0)
+ break;
+ cLeftPage = 0;
+ }
+ }
+
+ /*
+ * Fallback - slow processing till the end of the current page.
+ * In the cross page boundrary case we will end up here with cLeftPage
+ * as 0, we execute one loop then.
+ *
+ * Note! We ASSUME the CPU will raise #PF or #GP before access the
+ * I/O port, otherwise it wouldn't really be restartable.
+ */
+ /** @todo investigate what the CPU actually does with \#PF/\#GP
+ * during INS. */
+ do
+ {
+ OP_TYPE uValue;
+ rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue, iEffSeg, uAddrReg);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+
+ if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+ rcStrict = IOMIOPortWrite(pVM, u16Port, uValue, OP_SIZE / 8);
+ else
+ rcStrict = iemVerifyFakeIOPortWrite(pIemCpu, u16Port, uValue, OP_SIZE / 8);
+ if (!IOM_SUCCESS(rcStrict))
+ break;
+
+ uAddrReg += cbIncr;
+ uCounterReg--;
+ cLeftPage--;
+ if (rcStrict != VINF_SUCCESS)
+ {
+ /** @todo massage IOM status codes! */
+ break;
+ }
+ } while ((int32_t)cLeftPage > 0);
+ if (rcStrict != VINF_SUCCESS)
+ break;
+ } while (uCounterReg != 0);
+
+ /*
+ * Update the registers.
+ */
+ pCtx->ADDR_rCX = uCounterReg;
+ pCtx->ADDR_rSI = uAddrReg;
+ if (rcStrict == VINF_SUCCESS)
+ iemRegAddToRip(pIemCpu, cbInstr);
+
+ return rcStrict;
+}
+
+#endif /* OP_SIZE != 64-bit */
+
+
+#undef OP_rAX
+#undef OP_SIZE
+#undef ADDR_SIZE
+#undef ADDR_rDI
+#undef ADDR_rSI
+#undef ADDR_rCX
+#undef ADDR_rIP
+#undef ADDR2_TYPE
+#undef ADDR_TYPE
+#undef ADDR2_TYPE
+
diff --git a/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h b/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
new file mode 100644
index 000000000..e75cf157a
--- /dev/null
+++ b/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
@@ -0,0 +1,11607 @@
+/* $Id: IEMAllInstructions.cpp.h 37934 2011-07-13 22:58:03Z vboxsync $ */
+/** @file
+ * IEM - Instruction Decoding and Emulation.
+ */
+
+/*
+ * 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.
+ */
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+extern const PFNIEMOP g_apfnOneByteMap[256]; /* not static since we need to forward declare it. */
+
+
+/**
+ * Common worker for instructions like ADD, AND, OR, ++ with a byte
+ * memory/register as the destination.
+ *
+ * @param pImpl Pointer to the instruction implementation (assembly).
+ */
+FNIEMOP_DEF_1(iemOpHlpBinaryOperator_rm_r8, PCIEMOPBINSIZES, pImpl)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG(uint8_t, u8Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_FETCH_GREG_U8(u8Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /*
+ * We're accessing memory.
+ * Note! We're putting the eflags on the stack here so we can commit them
+ * after the memory.
+ */
+ uint32_t const fAccess = pImpl->pfnLockedU8 ? IEM_ACCESS_DATA_RW : IEM_ACCESS_DATA_R; /* CMP,TEST */
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG(uint8_t, u8Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu8Dst, fAccess, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_GREG_U8(u8Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU8, pu8Dst, u8Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, fAccess);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Common worker for word/dword/qword instructions like ADD, AND, OR, ++ with
+ * memory/register as the destination.
+ *
+ * @param pImpl Pointer to the instruction implementation (assembly).
+ */
+FNIEMOP_DEF_1(iemOpHlpBinaryOperator_rm_rv, PCIEMOPBINSIZES, pImpl)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ }
+ else
+ {
+ /*
+ * We're accessing memory.
+ * Note! We're putting the eflags on the stack here so we can commit them
+ * after the memory.
+ */
+ uint32_t const fAccess = pImpl->pfnLockedU8 ? IEM_ACCESS_DATA_RW : IEM_ACCESS_DATA_R /* CMP,TEST */;
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu16Dst, fAccess, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU16, pu16Dst, u16Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, fAccess);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu32Dst, fAccess, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU32, pu32Dst, u32Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, fAccess);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu64Dst, fAccess, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU64, pu64Dst, u64Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, fAccess);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Common worker for byte instructions like ADD, AND, OR, ++ with a register as
+ * the destination.
+ *
+ * @param pImpl Pointer to the instruction implementation (assembly).
+ */
+FNIEMOP_DEF_1(iemOpHlpBinaryOperator_r8_rm, PCIEMOPBINSIZES, pImpl)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG(uint8_t, u8Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_FETCH_GREG_U8(u8Src, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_GREG_U8(pu8Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /*
+ * We're accessing memory.
+ */
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG(uint8_t, u8Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U8(u8Src, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_GREG_U8(pu8Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Common worker for word/dword/qword instructions like ADD, AND, OR, ++ with a
+ * register as the destination.
+ *
+ * @param pImpl Pointer to the instruction implementation (assembly).
+ */
+FNIEMOP_DEF_1(iemOpHlpBinaryOperator_rv_rm, PCIEMOPBINSIZES, pImpl)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_FETCH_GREG_U16(u16Src, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_GREG_U16(pu16Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_FETCH_GREG_U32(u32Src, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_GREG_U32(pu32Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_FETCH_GREG_U64(u64Src, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_GREG_U64(pu64Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ }
+ else
+ {
+ /*
+ * We're accessing memory.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U16(u16Src, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_GREG_U16(pu16Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U32(u32Src, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_GREG_U32(pu32Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U64(u64Src, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_GREG_U64(pu64Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Common worker for instructions like ADD, AND, OR, ++ with working on AL with
+ * a byte immediate.
+ *
+ * @param pImpl Pointer to the instruction implementation (assembly).
+ */
+FNIEMOP_DEF_1(iemOpHlpBinaryOperator_AL_Ib, PCIEMOPBINSIZES, pImpl)
+{
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, u8Src,/*=*/ u8Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U8(pu8Dst, X86_GREG_xAX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Common worker for instructions like ADD, AND, OR, ++ with working on
+ * AX/EAX/RAX with a word/dword immediate.
+ *
+ * @param pImpl Pointer to the instruction implementation (assembly).
+ */
+FNIEMOP_DEF_1(iemOpHlpBinaryOperator_rAX_Iz, PCIEMOPBINSIZES, pImpl)
+{
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/ u16Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U16(pu16Dst, X86_GREG_xAX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/ u32Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U32(pu32Dst, X86_GREG_xAX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/ u64Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U64(pu64Dst, X86_GREG_xAX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcodes 0xf1, 0xd6. */
+FNIEMOP_DEF(iemOp_Invalid)
+{
+ IEMOP_MNEMONIC("Invalid");
+ return IEMOP_RAISE_INVALID_OPCODE();
+}
+
+
+
+/** @name ..... opcodes.
+ *
+ * @{
+ */
+
+/** @} */
+
+
+/** @name Two byte opcodes (first byte 0x0f).
+ *
+ * @{
+ */
+
+/** Opcode 0x0f 0x00 /0. */
+FNIEMOP_STUB_1(iemOp_Grp6_sldt, uint8_t, bRm);
+
+
+/** Opcode 0x0f 0x00 /1. */
+FNIEMOP_STUB_1(iemOp_Grp6_str, uint8_t, bRm);
+
+
+/** Opcode 0x0f 0x00 /2. */
+FNIEMOP_DEF_1(iemOp_Grp6_lldt, uint8_t, bRm)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEM_MC_BEGIN(1, 0);
+ IEM_MC_ARG(uint16_t, u16Sel, 0);
+ IEM_MC_FETCH_GREG_U16(u16Sel, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_CALL_CIMPL_1(iemCImpl_lldt, u16Sel);
+ IEM_MC_END();
+ }
+ else
+ {
+ IEM_MC_BEGIN(1, 1);
+ IEM_MC_ARG(uint16_t, u16Sel, 0);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_RAISE_GP0_IF_CPL_NOT_ZERO();
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U16(u16Sel, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_CALL_CIMPL_1(iemCImpl_lldt, u16Sel);
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x00 /3. */
+FNIEMOP_DEF_1(iemOp_Grp6_ltr, uint8_t, bRm)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEM_MC_BEGIN(1, 0);
+ IEM_MC_ARG(uint16_t, u16Sel, 0);
+ IEM_MC_FETCH_GREG_U16(u16Sel, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_CALL_CIMPL_1(iemCImpl_ltr, u16Sel);
+ IEM_MC_END();
+ }
+ else
+ {
+ IEM_MC_BEGIN(1, 1);
+ IEM_MC_ARG(uint16_t, u16Sel, 0);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_RAISE_GP0_IF_CPL_NOT_ZERO();
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U16(u16Sel, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_CALL_CIMPL_1(iemCImpl_ltr, u16Sel);
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x00 /4. */
+FNIEMOP_STUB_1(iemOp_Grp6_verr, uint8_t, bRm);
+
+
+/** Opcode 0x0f 0x00 /5. */
+FNIEMOP_STUB_1(iemOp_Grp6_verw, uint8_t, bRm);
+
+
+/** Opcode 0x0f 0x00. */
+FNIEMOP_DEF(iemOp_Grp6)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0: return FNIEMOP_CALL_1(iemOp_Grp6_sldt, bRm);
+ case 1: return FNIEMOP_CALL_1(iemOp_Grp6_str, bRm);
+ case 2: return FNIEMOP_CALL_1(iemOp_Grp6_lldt, bRm);
+ case 3: return FNIEMOP_CALL_1(iemOp_Grp6_ltr, bRm);
+ case 4: return FNIEMOP_CALL_1(iemOp_Grp6_verr, bRm);
+ case 5: return FNIEMOP_CALL_1(iemOp_Grp6_verw, bRm);
+ case 6: return IEMOP_RAISE_INVALID_OPCODE();
+ case 7: return IEMOP_RAISE_INVALID_OPCODE();
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+
+}
+
+
+/** Opcode 0x0f 0x01 /0. */
+FNIEMOP_DEF_1(iemOp_Grp7_sgdt, uint8_t, bRm)
+{
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+}
+
+
+/** Opcode 0x0f 0x01 /0. */
+FNIEMOP_DEF(iemOp_Grp7_vmcall)
+{
+ AssertFailed();
+ return IEMOP_RAISE_INVALID_OPCODE();
+}
+
+
+/** Opcode 0x0f 0x01 /0. */
+FNIEMOP_DEF(iemOp_Grp7_vmlaunch)
+{
+ AssertFailed();
+ return IEMOP_RAISE_INVALID_OPCODE();
+}
+
+
+/** Opcode 0x0f 0x01 /0. */
+FNIEMOP_DEF(iemOp_Grp7_vmresume)
+{
+ AssertFailed();
+ return IEMOP_RAISE_INVALID_OPCODE();
+}
+
+
+/** Opcode 0x0f 0x01 /0. */
+FNIEMOP_DEF(iemOp_Grp7_vmxoff)
+{
+ AssertFailed();
+ return IEMOP_RAISE_INVALID_OPCODE();
+}
+
+
+/** Opcode 0x0f 0x01 /1. */
+FNIEMOP_DEF_1(iemOp_Grp7_sidt, uint8_t, bRm)
+{
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+}
+
+
+/** Opcode 0x0f 0x01 /1. */
+FNIEMOP_DEF(iemOp_Grp7_monitor)
+{
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+}
+
+
+/** Opcode 0x0f 0x01 /1. */
+FNIEMOP_DEF(iemOp_Grp7_mwait)
+{
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+}
+
+
+/** Opcode 0x0f 0x01 /2. */
+FNIEMOP_DEF_1(iemOp_Grp7_lgdt, uint8_t, bRm)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEMMODE enmEffOpSize = pIemCpu->enmCpuMode == IEMMODE_64BIT
+ ? IEMMODE_64BIT
+ : pIemCpu->enmEffOpSize;
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG_CONST(uint8_t, iEffSeg, /*=*/pIemCpu->iEffSeg, 0);
+ IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 1);
+ IEM_MC_ARG_CONST(IEMMODE, enmEffOpSizeArg,/*=*/enmEffOpSize, 2);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_CALL_CIMPL_3(iemCImpl_lgdt, iEffSeg, GCPtrEffSrc, enmEffOpSizeArg);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x01 /2. */
+FNIEMOP_DEF(iemOp_Grp7_xgetbv)
+{
+ AssertFailed();
+ return IEMOP_RAISE_INVALID_OPCODE();
+}
+
+
+/** Opcode 0x0f 0x01 /2. */
+FNIEMOP_DEF(iemOp_Grp7_xsetbv)
+{
+ AssertFailed();
+ return IEMOP_RAISE_INVALID_OPCODE();
+}
+
+
+/** Opcode 0x0f 0x01 /3. */
+FNIEMOP_DEF_1(iemOp_Grp7_lidt, uint8_t, bRm)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEMMODE enmEffOpSize = pIemCpu->enmCpuMode == IEMMODE_64BIT
+ ? IEMMODE_64BIT
+ : pIemCpu->enmEffOpSize;
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG_CONST(uint8_t, iEffSeg, /*=*/pIemCpu->iEffSeg, 0);
+ IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 1);
+ IEM_MC_ARG_CONST(IEMMODE, enmEffOpSizeArg,/*=*/enmEffOpSize, 2);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_CALL_CIMPL_3(iemCImpl_lidt, iEffSeg, GCPtrEffSrc, enmEffOpSizeArg);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x01 /4. */
+FNIEMOP_DEF_1(iemOp_Grp7_smsw, uint8_t, bRm)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint16_t, u16Tmp);
+ IEM_MC_FETCH_CR0_U16(u16Tmp);
+ IEM_MC_STORE_GREG_U16((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u16Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint32_t, u32Tmp);
+ IEM_MC_FETCH_CR0_U32(u32Tmp);
+ IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u32Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint64_t, u64Tmp);
+ IEM_MC_FETCH_CR0_U64(u64Tmp);
+ IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u64Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /* Ignore operand size here, memory refs are always 16-bit. */
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint16_t, u16Tmp);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_CR0_U16(u16Tmp);
+ IEM_MC_STORE_MEM_U16(pIemCpu->iEffSeg, GCPtrEffDst, u16Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+}
+
+
+/** Opcode 0x0f 0x01 /6. */
+FNIEMOP_DEF_1(iemOp_Grp7_lmsw, uint8_t, bRm)
+{
+ /* The operand size is effectively ignored, all is 16-bit and only the
+ lower 3-bits are used. */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEM_MC_BEGIN(1, 0);
+ IEM_MC_ARG(uint16_t, u16Tmp, 0);
+ IEM_MC_FETCH_GREG_U16(u16Tmp, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_CALL_CIMPL_1(iemCImpl_lmsw, u16Tmp);
+ IEM_MC_END();
+ }
+ else
+ {
+ IEM_MC_BEGIN(1, 1);
+ IEM_MC_ARG(uint16_t, u16Tmp, 0);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U16(u16Tmp, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_CALL_CIMPL_1(iemCImpl_lmsw, u16Tmp);
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x01 /7. */
+FNIEMOP_DEF_1(iemOp_Grp7_invlpg, uint8_t, bRm)
+{
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+}
+
+
+/** Opcode 0x0f 0x01 /7. */
+FNIEMOP_DEF(iemOp_Grp7_swapgs)
+{
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+}
+
+
+/** Opcode 0x0f 0x01 /7. */
+FNIEMOP_DEF(iemOp_Grp7_rdtscp)
+{
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+}
+
+
+/** Opcode 0x0f 0x01. */
+FNIEMOP_DEF(iemOp_Grp7)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0:
+ if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
+ return FNIEMOP_CALL_1(iemOp_Grp7_sgdt, bRm);
+ switch (bRm & X86_MODRM_RM_MASK)
+ {
+ case 1: return FNIEMOP_CALL(iemOp_Grp7_vmcall);
+ case 2: return FNIEMOP_CALL(iemOp_Grp7_vmlaunch);
+ case 3: return FNIEMOP_CALL(iemOp_Grp7_vmresume);
+ case 4: return FNIEMOP_CALL(iemOp_Grp7_vmxoff);
+ }
+ return IEMOP_RAISE_INVALID_OPCODE();
+
+ case 1:
+ if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
+ return FNIEMOP_CALL_1(iemOp_Grp7_sidt, bRm);
+ switch (bRm & X86_MODRM_RM_MASK)
+ {
+ case 0: return FNIEMOP_CALL(iemOp_Grp7_monitor);
+ case 1: return FNIEMOP_CALL(iemOp_Grp7_mwait);
+ }
+ return IEMOP_RAISE_INVALID_OPCODE();
+
+ case 2:
+ if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
+ return FNIEMOP_CALL_1(iemOp_Grp7_lgdt, bRm);
+ switch (bRm & X86_MODRM_RM_MASK)
+ {
+ case 0: return FNIEMOP_CALL(iemOp_Grp7_xgetbv);
+ case 1: return FNIEMOP_CALL(iemOp_Grp7_xsetbv);
+ }
+ return IEMOP_RAISE_INVALID_OPCODE();
+
+ case 3:
+ if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
+ return FNIEMOP_CALL_1(iemOp_Grp7_lidt, bRm);
+ return IEMOP_RAISE_INVALID_OPCODE();
+
+ case 4:
+ return FNIEMOP_CALL_1(iemOp_Grp7_smsw, bRm);
+
+ case 5:
+ return IEMOP_RAISE_INVALID_OPCODE();
+
+ case 6:
+ return FNIEMOP_CALL_1(iemOp_Grp7_lmsw, bRm);
+
+ case 7:
+ if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
+ return FNIEMOP_CALL_1(iemOp_Grp7_invlpg, bRm);
+ switch (bRm & X86_MODRM_RM_MASK)
+ {
+ case 0: return FNIEMOP_CALL(iemOp_Grp7_swapgs);
+ case 1: return FNIEMOP_CALL(iemOp_Grp7_rdtscp);
+ }
+ return IEMOP_RAISE_INVALID_OPCODE();
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0x0f 0x02. */
+FNIEMOP_STUB(iemOp_lar_Gv_Ew);
+/** Opcode 0x0f 0x03. */
+FNIEMOP_STUB(iemOp_lsl_Gv_Ew);
+/** Opcode 0x0f 0x04. */
+FNIEMOP_STUB(iemOp_syscall);
+
+
+/** Opcode 0x0f 0x05. */
+FNIEMOP_DEF(iemOp_clts)
+{
+ IEMOP_MNEMONIC("clts");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_clts);
+}
+
+
+/** Opcode 0x0f 0x06. */
+FNIEMOP_STUB(iemOp_sysret);
+/** Opcode 0x0f 0x08. */
+FNIEMOP_STUB(iemOp_invd);
+/** Opcode 0x0f 0x09. */
+FNIEMOP_STUB(iemOp_wbinvd);
+/** Opcode 0x0f 0x0b. */
+FNIEMOP_STUB(iemOp_ud2);
+/** Opcode 0x0f 0x0d. */
+FNIEMOP_STUB(iemOp_nop_Ev_prefetch);
+/** Opcode 0x0f 0x0e. */
+FNIEMOP_STUB(iemOp_femms);
+/** Opcode 0x0f 0x0f. */
+FNIEMOP_STUB(iemOp_3Dnow);
+/** Opcode 0x0f 0x10. */
+FNIEMOP_STUB(iemOp_movups_Vps_Wps__movupd_Vpd_Wpd__movss_Vss_Wss__movsd_Vsd_Wsd);
+/** Opcode 0x0f 0x11. */
+FNIEMOP_STUB(iemOp_movups_Wps_Vps__movupd_Wpd_Vpd__movss_Wss_Vss__movsd_Vsd_Wsd);
+/** Opcode 0x0f 0x12. */
+FNIEMOP_STUB(iemOp_movlps_Vq_Mq__movhlps_Vq_Uq__movlpd_Vq_Mq__movsldup_Vq_Wq__movddup_Vq_Wq);
+/** Opcode 0x0f 0x13. */
+FNIEMOP_STUB(iemOp_movlps_Mq_Vq__movlpd_Mq_Vq);
+/** Opcode 0x0f 0x14. */
+FNIEMOP_STUB(iemOp_unpckhlps_Vps_Wq__unpcklpd_Vpd_Wq);
+/** Opcode 0x0f 0x15. */
+FNIEMOP_STUB(iemOp_unpckhps_Vps_Wq__unpckhpd_Vpd_Wq);
+/** Opcode 0x0f 0x16. */
+FNIEMOP_STUB(iemOp_movhps_Vq_Mq__movlhps_Vq_Uq__movhpd_Vq_Mq__movshdup_Vq_Wq);
+/** Opcode 0x0f 0x17. */
+FNIEMOP_STUB(iemOp_movhps_Mq_Vq__movhpd_Mq_Vq);
+/** Opcode 0x0f 0x18. */
+FNIEMOP_STUB(iemOp_prefetch_Grp16);
+
+
+/** Opcode 0x0f 0x20. */
+FNIEMOP_DEF(iemOp_mov_Rd_Cd)
+{
+ /* mod is ignored, as is operand size overrides. */
+ IEMOP_MNEMONIC("mov Rd,Cd");
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ pIemCpu->enmEffOpSize = pIemCpu->enmDefOpSize = IEMMODE_64BIT;
+ else
+ pIemCpu->enmEffOpSize = pIemCpu->enmDefOpSize = IEMMODE_32BIT;
+
+ /** @todo Verify that the the invalid lock sequence exception (\#UD) is raised
+ * before the privilege level violation (\#GP). */
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ uint8_t iCrReg = ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg;
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_LOCK)
+ {
+ /* The lock prefix can be used to encode CR8 accesses on some CPUs. */
+ if (!IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(X86_CPUID_AMD_FEATURE_ECX_CR8L))
+ return IEMOP_RAISE_INVALID_LOCK_PREFIX();
+ iCrReg |= 8;
+ }
+ switch (iCrReg)
+ {
+ case 0: case 2: case 3: case 4: case 8:
+ break;
+ default:
+ return IEMOP_RAISE_INVALID_OPCODE();
+ }
+
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_mov_Rd_Cd, (X86_MODRM_RM_MASK & bRm) | pIemCpu->uRexB, iCrReg);
+}
+
+
+/** Opcode 0x0f 0x21. */
+FNIEMOP_DEF(iemOp_mov_Rd_Dd)
+{
+ IEMOP_MNEMONIC("mov Rd,Dd");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_REX_R)
+ return IEMOP_RAISE_INVALID_OPCODE();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_mov_Rd_Dd,
+ (X86_MODRM_RM_MASK & bRm) | pIemCpu->uRexB,
+ ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK));
+}
+
+
+/** Opcode 0x0f 0x22. */
+FNIEMOP_DEF(iemOp_mov_Cd_Rd)
+{
+ /* mod is ignored, as is operand size overrides. */
+ IEMOP_MNEMONIC("mov Cd,Rd");
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ pIemCpu->enmEffOpSize = pIemCpu->enmDefOpSize = IEMMODE_64BIT;
+ else
+ pIemCpu->enmEffOpSize = pIemCpu->enmDefOpSize = IEMMODE_32BIT;
+
+ /** @todo Verify that the the invalid lock sequence exception (\#UD) is raised
+ * before the privilege level violation (\#GP). */
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ uint8_t iCrReg = ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg;
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_LOCK)
+ {
+ /* The lock prefix can be used to encode CR8 accesses on some CPUs. */
+ if (!IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(X86_CPUID_AMD_FEATURE_ECX_CR8L))
+ return IEMOP_RAISE_INVALID_LOCK_PREFIX();
+ iCrReg |= 8;
+ }
+ switch (iCrReg)
+ {
+ case 0: case 2: case 3: case 4: case 8:
+ break;
+ default:
+ return IEMOP_RAISE_INVALID_OPCODE();
+ }
+
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_mov_Cd_Rd, iCrReg, (X86_MODRM_RM_MASK & bRm) | pIemCpu->uRexB);
+}
+
+
+/** Opcode 0x0f 0x23. */
+FNIEMOP_DEF(iemOp_mov_Dd_Rd)
+{
+ IEMOP_MNEMONIC("mov Dd,Rd");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_REX_R)
+ return IEMOP_RAISE_INVALID_OPCODE();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_mov_Dd_Rd,
+ ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK),
+ (X86_MODRM_RM_MASK & bRm) | pIemCpu->uRexB);
+}
+
+
+/** Opcode 0x0f 0x24. */
+FNIEMOP_DEF(iemOp_mov_Rd_Td)
+{
+ IEMOP_MNEMONIC("mov Rd,Td");
+/** @todo Is the invalid opcode raise before parsing any R/M byte? */
+ return IEMOP_RAISE_INVALID_OPCODE();
+}
+
+
+
+/** Opcode 0x0f 0x26. */
+FNIEMOP_DEF(iemOp_mov_Td_Rd)
+{
+ IEMOP_MNEMONIC("mov Td,Rd");
+ return IEMOP_RAISE_INVALID_OPCODE();
+}
+
+
+/** Opcode 0x0f 0x28. */
+FNIEMOP_STUB(iemOp_movaps_Vps_Wps__movapd_Vpd_Wpd);
+/** Opcode 0x0f 0x29. */
+FNIEMOP_STUB(iemOp_movaps_Wps_Vps__movapd_Wpd_Vpd);
+/** Opcode 0x0f 0x2a. */
+FNIEMOP_STUB(iemOp_cvtpi2ps_Vps_Qpi__cvtpi2pd_Vpd_Qpi__cvtsi2ss_Vss_Ey__cvtsi2sd_Vsd_Ey);
+/** Opcode 0x0f 0x2b. */
+FNIEMOP_STUB(iemOp_movntps_Mps_Vps__movntpd_Mpd_Vpd);
+/** Opcode 0x0f 0x2c. */
+FNIEMOP_STUB(iemOp_cvttps2pi_Ppi_Wps__cvttpd2pi_Ppi_Wpd__cvttss2si_Gy_Wss__cvttsd2si_Yu_Wsd);
+/** Opcode 0x0f 0x2d. */
+FNIEMOP_STUB(iemOp_cvtps2pi_Ppi_Wps__cvtpd2pi_QpiWpd__cvtss2si_Gy_Wss__cvtsd2si_Gy_Wsd);
+/** Opcode 0x0f 0x2e. */
+FNIEMOP_STUB(iemOp_ucomiss_Vss_Wss__ucomisd_Vsd_Wsd);
+/** Opcode 0x0f 0x2f. */
+FNIEMOP_STUB(iemOp_comiss_Vss_Wss__comisd_Vsd_Wsd);
+/** Opcode 0x0f 0x30. */
+FNIEMOP_STUB(iemOp_wrmsr);
+
+
+/** Opcode 0x0f 0x31. */
+FNIEMOP_DEF(iemOp_rdtsc)
+{
+ IEMOP_MNEMONIC("rdtsc");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rdtsc);
+}
+
+
+/** Opcode 0x0f 0x33. */
+FNIEMOP_STUB(iemOp_rdmsr);
+/** Opcode 0x0f 0x34. */
+FNIEMOP_STUB(iemOp_rdpmc);
+/** Opcode 0x0f 0x34. */
+FNIEMOP_STUB(iemOp_sysenter);
+/** Opcode 0x0f 0x35. */
+FNIEMOP_STUB(iemOp_sysexit);
+/** Opcode 0x0f 0x37. */
+FNIEMOP_STUB(iemOp_getsec);
+/** Opcode 0x0f 0x38. */
+FNIEMOP_STUB(iemOp_3byte_Esc_A4);
+/** Opcode 0x0f 0x39. */
+FNIEMOP_STUB(iemOp_3byte_Esc_A5);
+/** Opcode 0x0f 0x3c (?). */
+FNIEMOP_STUB(iemOp_movnti_Gv_Ev);
+
+/**
+ * Implements a conditional move.
+ *
+ * Wish there was an obvious way to do this where we could share and reduce
+ * code bloat.
+ *
+ * @param a_Cnd The conditional "microcode" operation.
+ */
+#define CMOV_X(a_Cnd) \
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); \
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT)) \
+ { \
+ switch (pIemCpu->enmEffOpSize) \
+ { \
+ case IEMMODE_16BIT: \
+ IEM_MC_BEGIN(0, 1); \
+ IEM_MC_LOCAL(uint16_t, u16Tmp); \
+ a_Cnd { \
+ IEM_MC_FETCH_GREG_U16(u16Tmp, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB); \
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Tmp); \
+ } IEM_MC_ENDIF(); \
+ IEM_MC_ADVANCE_RIP(); \
+ IEM_MC_END(); \
+ return VINF_SUCCESS; \
+ \
+ case IEMMODE_32BIT: \
+ IEM_MC_BEGIN(0, 1); \
+ IEM_MC_LOCAL(uint32_t, u32Tmp); \
+ a_Cnd { \
+ IEM_MC_FETCH_GREG_U32(u32Tmp, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB); \
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Tmp); \
+ } IEM_MC_ELSE() { \
+ IEM_MC_CLEAR_HIGH_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg); \
+ } IEM_MC_ENDIF(); \
+ IEM_MC_ADVANCE_RIP(); \
+ IEM_MC_END(); \
+ return VINF_SUCCESS; \
+ \
+ case IEMMODE_64BIT: \
+ IEM_MC_BEGIN(0, 1); \
+ IEM_MC_LOCAL(uint64_t, u64Tmp); \
+ a_Cnd { \
+ IEM_MC_FETCH_GREG_U64(u64Tmp, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB); \
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Tmp); \
+ } IEM_MC_ENDIF(); \
+ IEM_MC_ADVANCE_RIP(); \
+ IEM_MC_END(); \
+ return VINF_SUCCESS; \
+ \
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
+ } \
+ } \
+ else \
+ { \
+ switch (pIemCpu->enmEffOpSize) \
+ { \
+ case IEMMODE_16BIT: \
+ IEM_MC_BEGIN(0, 2); \
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc); \
+ IEM_MC_LOCAL(uint16_t, u16Tmp); \
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm); \
+ IEM_MC_FETCH_MEM_U16(u16Tmp, pIemCpu->iEffSeg, GCPtrEffSrc); \
+ a_Cnd { \
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Tmp); \
+ } IEM_MC_ENDIF(); \
+ IEM_MC_ADVANCE_RIP(); \
+ IEM_MC_END(); \
+ return VINF_SUCCESS; \
+ \
+ case IEMMODE_32BIT: \
+ IEM_MC_BEGIN(0, 2); \
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc); \
+ IEM_MC_LOCAL(uint32_t, u32Tmp); \
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm); \
+ IEM_MC_FETCH_MEM_U32(u32Tmp, pIemCpu->iEffSeg, GCPtrEffSrc); \
+ a_Cnd { \
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Tmp); \
+ } IEM_MC_ELSE() { \
+ IEM_MC_CLEAR_HIGH_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg); \
+ } IEM_MC_ENDIF(); \
+ IEM_MC_ADVANCE_RIP(); \
+ IEM_MC_END(); \
+ return VINF_SUCCESS; \
+ \
+ case IEMMODE_64BIT: \
+ IEM_MC_BEGIN(0, 2); \
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc); \
+ IEM_MC_LOCAL(uint64_t, u64Tmp); \
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm); \
+ IEM_MC_FETCH_MEM_U64(u64Tmp, pIemCpu->iEffSeg, GCPtrEffSrc); \
+ a_Cnd { \
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Tmp); \
+ } IEM_MC_ENDIF(); \
+ IEM_MC_ADVANCE_RIP(); \
+ IEM_MC_END(); \
+ return VINF_SUCCESS; \
+ \
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
+ } \
+ } do {} while (0)
+
+
+
+/** Opcode 0x0f 0x40. */
+FNIEMOP_DEF(iemOp_cmovo_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovo Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF));
+}
+
+
+/** Opcode 0x0f 0x41. */
+FNIEMOP_DEF(iemOp_cmovno_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovno Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_OF));
+}
+
+
+/** Opcode 0x0f 0x42. */
+FNIEMOP_DEF(iemOp_cmovc_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovc Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF));
+}
+
+
+/** Opcode 0x0f 0x43. */
+FNIEMOP_DEF(iemOp_cmovnc_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovnc Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_CF));
+}
+
+
+/** Opcode 0x0f 0x44. */
+FNIEMOP_DEF(iemOp_cmove_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmove Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF));
+}
+
+
+/** Opcode 0x0f 0x45. */
+FNIEMOP_DEF(iemOp_cmovne_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovne Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_ZF));
+}
+
+
+/** Opcode 0x0f 0x46. */
+FNIEMOP_DEF(iemOp_cmovbe_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovbe Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF));
+}
+
+
+/** Opcode 0x0f 0x47. */
+FNIEMOP_DEF(iemOp_cmovnbe_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovnbe Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_NO_BITS_SET(X86_EFL_CF | X86_EFL_ZF));
+}
+
+
+/** Opcode 0x0f 0x48. */
+FNIEMOP_DEF(iemOp_cmovs_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovs Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF));
+}
+
+
+/** Opcode 0x0f 0x49. */
+FNIEMOP_DEF(iemOp_cmovns_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovns Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_SF));
+}
+
+
+/** Opcode 0x0f 0x4a. */
+FNIEMOP_DEF(iemOp_cmovp_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovp Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF));
+}
+
+
+/** Opcode 0x0f 0x4b. */
+FNIEMOP_DEF(iemOp_cmovnp_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovnp Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_PF));
+}
+
+
+/** Opcode 0x0f 0x4c. */
+FNIEMOP_DEF(iemOp_cmovl_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovl Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF));
+}
+
+
+/** Opcode 0x0f 0x4d. */
+FNIEMOP_DEF(iemOp_cmovnl_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovnl Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BITS_EQ(X86_EFL_SF, X86_EFL_OF));
+}
+
+
+/** Opcode 0x0f 0x4e. */
+FNIEMOP_DEF(iemOp_cmovle_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovle Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF));
+}
+
+
+/** Opcode 0x0f 0x4f. */
+FNIEMOP_DEF(iemOp_cmovnle_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmovnle Gv,Ev");
+ CMOV_X(IEM_MC_IF_EFL_BIT_NOT_SET_AND_BITS_EQ(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF));
+}
+
+#undef CMOV_X
+
+/** Opcode 0x0f 0x50. */
+FNIEMOP_STUB(iemOp_movmskps_Gy_Ups__movmskpd_Gy_Upd);
+/** Opcode 0x0f 0x51. */
+FNIEMOP_STUB(iemOp_sqrtps_Wps_Vps__sqrtpd_Wpd_Vpd__sqrtss_Vss_Wss__sqrtsd_Vsd_Wsd);
+/** Opcode 0x0f 0x52. */
+FNIEMOP_STUB(iemOp_rsqrtps_Wps_Vps__rsqrtss_Vss_Wss);
+/** Opcode 0x0f 0x53. */
+FNIEMOP_STUB(iemOp_rcpps_Wps_Vps__rcpss_Vs_Wss);
+/** Opcode 0x0f 0x54. */
+FNIEMOP_STUB(iemOp_andps_Vps_Wps__andpd_Wpd_Vpd);
+/** Opcode 0x0f 0x55. */
+FNIEMOP_STUB(iemOp_andnps_Vps_Wps__andnpd_Wpd_Vpd);
+/** Opcode 0x0f 0x56. */
+FNIEMOP_STUB(iemOp_orps_Wpd_Vpd__orpd_Wpd_Vpd);
+/** Opcode 0x0f 0x57. */
+FNIEMOP_STUB(iemOp_xorps_Vps_Wps__xorpd_Wpd_Vpd);
+/** Opcode 0x0f 0x58. */
+FNIEMOP_STUB(iemOp_addps_Vps_Wps__addpd_Vpd_Wpd__addss_Vss_Wss__addsd_Vsd_Wsd);
+/** Opcode 0x0f 0x59. */
+FNIEMOP_STUB(iemOp_mulps_Vps_Wps__mulpd_Vpd_Wpd__mulss_Vss__Wss__mulsd_Vsd_Wsd);
+/** Opcode 0x0f 0x5a. */
+FNIEMOP_STUB(iemOp_cvtps2pd_Vpd_Wps__cvtpd2ps_Vps_Wpd__cvtss2sd_Vsd_Wss__cvtsd2ss_Vss_Wsd);
+/** Opcode 0x0f 0x5b. */
+FNIEMOP_STUB(iemOp_cvtdq2ps_Vps_Wdq__cvtps2dq_Vdq_Wps__cvtps2dq_Vdq_Wps);
+/** Opcode 0x0f 0x5c. */
+FNIEMOP_STUB(iemOp_subps_Vps_Wps__subpd_Vps_Wdp__subss_Vss_Wss__subsd_Vsd_Wsd);
+/** Opcode 0x0f 0x5d. */
+FNIEMOP_STUB(iemOp_minps_Vps_Wps__minpd_Vpd_Wpd__minss_Vss_Wss__minsd_Vsd_Wsd);
+/** Opcode 0x0f 0x5e. */
+FNIEMOP_STUB(iemOp_divps_Vps_Wps__divpd_Vpd_Wpd__divss_Vss_Wss__divsd_Vsd_Wsd);
+/** Opcode 0x0f 0x5f. */
+FNIEMOP_STUB(iemOp_maxps_Vps_Wps__maxpd_Vpd_Wpd__maxss_Vss_Wss__maxsd_Vsd_Wsd);
+/** Opcode 0x0f 0x60. */
+FNIEMOP_STUB(iemOp_punpcklbw_Pq_Qd__punpcklbw_Vdq_Wdq);
+/** Opcode 0x0f 0x61. */
+FNIEMOP_STUB(iemOp_punpcklwd_Pq_Qd__punpcklwd_Vdq_Wdq);
+/** Opcode 0x0f 0x62. */
+FNIEMOP_STUB(iemOp_punpckldq_Pq_Qd__punpckldq_Vdq_Wdq);
+/** Opcode 0x0f 0x63. */
+FNIEMOP_STUB(iemOp_packsswb_Pq_Qq__packsswb_Vdq_Wdq);
+/** Opcode 0x0f 0x64. */
+FNIEMOP_STUB(iemOp_pcmpgtb_Pq_Qq__pcmpgtb_Vdq_Wdq);
+/** Opcode 0x0f 0x65. */
+FNIEMOP_STUB(iemOp_pcmpgtw_Pq_Qq__pcmpgtw_Vdq_Wdq);
+/** Opcode 0x0f 0x66. */
+FNIEMOP_STUB(iemOp_pcmpgtd_Pq_Qq__pcmpgtd_Vdq_Wdq);
+/** Opcode 0x0f 0x67. */
+FNIEMOP_STUB(iemOp_packuswb_Pq_Qq__packuswb_Vdq_Wdq);
+/** Opcode 0x0f 0x68. */
+FNIEMOP_STUB(iemOp_punpckhbw_Pq_Qq__punpckhbw_Vdq_Wdq);
+/** Opcode 0x0f 0x69. */
+FNIEMOP_STUB(iemOp_punpckhwd_Pq_Qd__punpckhwd_Vdq_Wdq);
+/** Opcode 0x0f 0x6a. */
+FNIEMOP_STUB(iemOp_punpckhdq_Pq_Qd__punpckhdq_Vdq_Wdq);
+/** Opcode 0x0f 0x6b. */
+FNIEMOP_STUB(iemOp_packssdw_Pq_Qd__packssdq_Vdq_Wdq);
+/** Opcode 0x0f 0x6c. */
+FNIEMOP_STUB(iemOp_punpcklqdq_Vdq_Wdq);
+/** Opcode 0x0f 0x6d. */
+FNIEMOP_STUB(iemOp_punpckhqdq_Vdq_Wdq);
+/** Opcode 0x0f 0x6e. */
+FNIEMOP_STUB(iemOp_movd_q_Pd_Ey__movd_q_Vy_Ey);
+/** Opcode 0x0f 0x6f. */
+FNIEMOP_STUB(iemOp_movq_Pq_Qq__movdqa_Vdq_Wdq__movdqu_Vdq_Wdq);
+/** Opcode 0x0f 0x70. */
+FNIEMOP_STUB(iemOp_pshufw_Pq_Qq_Ib__pshufd_Vdq_Wdq_Ib__pshufhw_Vdq_Wdq_Ib__pshuflq_Vdq_Wdq_Ib);
+/** Opcode 0x0f 0x71. */
+FNIEMOP_STUB(iemOp_Grp12);
+/** Opcode 0x0f 0x72. */
+FNIEMOP_STUB(iemOp_Grp13);
+/** Opcode 0x0f 0x73. */
+FNIEMOP_STUB(iemOp_Grp14);
+/** Opcode 0x0f 0x74. */
+FNIEMOP_STUB(iemOp_pcmpeqb_Pq_Qq__pcmpeqb_Vdq_Wdq);
+/** Opcode 0x0f 0x75. */
+FNIEMOP_STUB(iemOp_pcmpeqw_Pq_Qq__pcmpeqw_Vdq_Wdq);
+/** Opcode 0x0f 0x76. */
+FNIEMOP_STUB(iemOp_pcmped_Pq_Qq__pcmpeqd_Vdq_Wdq);
+/** Opcode 0x0f 0x77. */
+FNIEMOP_STUB(iemOp_emms);
+/** Opcode 0x0f 0x78. */
+FNIEMOP_STUB(iemOp_vmread);
+/** Opcode 0x0f 0x79. */
+FNIEMOP_STUB(iemOp_vmwrite);
+/** Opcode 0x0f 0x7c. */
+FNIEMOP_STUB(iemOp_haddpd_Vdp_Wpd__haddps_Vps_Wps);
+/** Opcode 0x0f 0x7d. */
+FNIEMOP_STUB(iemOp_hsubpd_Vpd_Wpd__hsubps_Vps_Wps);
+/** Opcode 0x0f 0x7e. */
+FNIEMOP_STUB(iemOp_movd_q_Ey_Pd__movd_q_Ey_Vy__movq_Vq_Wq);
+/** Opcode 0x0f 0x7f. */
+FNIEMOP_STUB(iemOp_movq_Qq_Pq__movq_movdqa_Wdq_Vdq__movdqu_Wdq_Vdq);
+
+
+/** Opcode 0x0f 0x80. */
+FNIEMOP_DEF(iemOp_jo_Jv)
+{
+ IEMOP_MNEMONIC("jo Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x81. */
+FNIEMOP_DEF(iemOp_jno_Jv)
+{
+ IEMOP_MNEMONIC("jno Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x82. */
+FNIEMOP_DEF(iemOp_jc_Jv)
+{
+ IEMOP_MNEMONIC("jc/jb/jnae Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x83. */
+FNIEMOP_DEF(iemOp_jnc_Jv)
+{
+ IEMOP_MNEMONIC("jnc/jnb/jae Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x84. */
+FNIEMOP_DEF(iemOp_je_Jv)
+{
+ IEMOP_MNEMONIC("je/jz Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x85. */
+FNIEMOP_DEF(iemOp_jne_Jv)
+{
+ IEMOP_MNEMONIC("jne/jnz Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x86. */
+FNIEMOP_DEF(iemOp_jbe_Jv)
+{
+ IEMOP_MNEMONIC("jbe/jna Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x87. */
+FNIEMOP_DEF(iemOp_jnbe_Jv)
+{
+ IEMOP_MNEMONIC("jnbe/ja Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x88. */
+FNIEMOP_DEF(iemOp_js_Jv)
+{
+ IEMOP_MNEMONIC("js Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x89. */
+FNIEMOP_DEF(iemOp_jns_Jv)
+{
+ IEMOP_MNEMONIC("jns Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x8a. */
+FNIEMOP_DEF(iemOp_jp_Jv)
+{
+ IEMOP_MNEMONIC("jp Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x8b. */
+FNIEMOP_DEF(iemOp_jnp_Jv)
+{
+ IEMOP_MNEMONIC("jo Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x8c. */
+FNIEMOP_DEF(iemOp_jl_Jv)
+{
+ IEMOP_MNEMONIC("jl/jnge Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x8d. */
+FNIEMOP_DEF(iemOp_jnl_Jv)
+{
+ IEMOP_MNEMONIC("jnl/jge Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x8e. */
+FNIEMOP_DEF(iemOp_jle_Jv)
+{
+ IEMOP_MNEMONIC("jle/jng Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x8f. */
+FNIEMOP_DEF(iemOp_jnle_Jv)
+{
+ IEMOP_MNEMONIC("jnle/jg Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S16(i16Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ else
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S32(i32Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x90. */
+FNIEMOP_DEF(iemOp_seto_Eb)
+{
+ IEMOP_MNEMONIC("seto Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x91. */
+FNIEMOP_DEF(iemOp_setno_Eb)
+{
+ IEMOP_MNEMONIC("setno Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x92. */
+FNIEMOP_DEF(iemOp_setc_Eb)
+{
+ IEMOP_MNEMONIC("setc Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x93. */
+FNIEMOP_DEF(iemOp_setnc_Eb)
+{
+ IEMOP_MNEMONIC("setnc Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x94. */
+FNIEMOP_DEF(iemOp_sete_Eb)
+{
+ IEMOP_MNEMONIC("sete Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x95. */
+FNIEMOP_DEF(iemOp_setne_Eb)
+{
+ IEMOP_MNEMONIC("setne Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x96. */
+FNIEMOP_DEF(iemOp_setbe_Eb)
+{
+ IEMOP_MNEMONIC("setbe Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x97. */
+FNIEMOP_DEF(iemOp_setnbe_Eb)
+{
+ IEMOP_MNEMONIC("setnbe Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x98. */
+FNIEMOP_DEF(iemOp_sets_Eb)
+{
+ IEMOP_MNEMONIC("sets Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x99. */
+FNIEMOP_DEF(iemOp_setns_Eb)
+{
+ IEMOP_MNEMONIC("setns Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x9a. */
+FNIEMOP_DEF(iemOp_setp_Eb)
+{
+ IEMOP_MNEMONIC("setnp Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x9b. */
+FNIEMOP_DEF(iemOp_setnp_Eb)
+{
+ IEMOP_MNEMONIC("setnp Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x9c. */
+FNIEMOP_DEF(iemOp_setl_Eb)
+{
+ IEMOP_MNEMONIC("setl Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x9d. */
+FNIEMOP_DEF(iemOp_setnl_Eb)
+{
+ IEMOP_MNEMONIC("setnl Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x9e. */
+FNIEMOP_DEF(iemOp_setle_Eb)
+{
+ IEMOP_MNEMONIC("setle Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0x9f. */
+FNIEMOP_DEF(iemOp_setnle_Eb)
+{
+ IEMOP_MNEMONIC("setnle Eb");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+ * any way. AMD says it's "unused", whatever that means. We're
+ * ignoring for now. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_MEM_U8_CONST(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Common 'push segment-register' helper.
+ */
+FNIEMOP_DEF_1(iemOpCommonPushSReg, uint8_t, iReg)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if (iReg < X86_SREG_FS)
+ IEMOP_HLP_NO_64BIT();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint16_t, u16Value);
+ IEM_MC_FETCH_SREG_U16(u16Value, iReg);
+ IEM_MC_PUSH_U16(u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_FETCH_SREG_ZX_U32(u32Value, iReg);
+ IEM_MC_PUSH_U32(u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_FETCH_SREG_ZX_U64(u64Value, iReg);
+ IEM_MC_PUSH_U64(u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0xa0. */
+FNIEMOP_DEF(iemOp_push_fs)
+{
+ IEMOP_MNEMONIC("push fs");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_FS);
+}
+
+
+/** Opcode 0x0f 0xa1. */
+FNIEMOP_DEF(iemOp_pop_fs)
+{
+ IEMOP_MNEMONIC("pop fs");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_pop_Sreg, X86_SREG_FS, pIemCpu->enmEffOpSize);
+}
+
+
+/** Opcode 0x0f 0xa2. */
+FNIEMOP_DEF(iemOp_cpuid)
+{
+ IEMOP_MNEMONIC("cpuid");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_cpuid);
+}
+
+
+/**
+ * Common worker for iemOp_bt_Ev_Gv, iemOp_btc_Ev_Gv, iemOp_btr_Ev_Gv and
+ * iemOp_bts_Ev_Gv.
+ */
+FNIEMOP_DEF_1(iemOpCommonBit_Ev_Gv, PCIEMOPBINSIZES, pImpl)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register destination. */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_AND_LOCAL_U16(u16Src, 0xf);
+ IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_AND_LOCAL_U32(u32Src, 0x1f);
+ IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_AND_LOCAL_U64(u64Src, 0x3f);
+ IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /* memory destination. */
+
+ uint32_t fAccess;
+ if (pImpl->pfnLockedU16)
+ fAccess = IEM_ACCESS_DATA_RW;
+ else /* BT */
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ fAccess = IEM_ACCESS_DATA_R;
+ }
+
+ /** @todo test negative bit offsets! */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_LOCAL(int16_t, i16AddrAdj);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_ASSIGN(i16AddrAdj, u16Src);
+ IEM_MC_AND_ARG_U16(u16Src, 0x0f);
+ IEM_MC_SAR_LOCAL_S16(i16AddrAdj, 4);
+ IEM_MC_SAR_LOCAL_S16(i16AddrAdj, 1);
+ IEM_MC_ADD_LOCAL_S16_TO_EFF_ADDR(GCPtrEffDst, i16AddrAdj);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+
+ IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU16, pu16Dst, u16Src, pEFlags);
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
+
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_LOCAL(int32_t, i32AddrAdj);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_ASSIGN(i32AddrAdj, u32Src);
+ IEM_MC_AND_ARG_U32(u32Src, 0x1f);
+ IEM_MC_SAR_LOCAL_S32(i32AddrAdj, 5);
+ IEM_MC_SHL_LOCAL_S32(i32AddrAdj, 2);
+ IEM_MC_ADD_LOCAL_S32_TO_EFF_ADDR(GCPtrEffDst, i32AddrAdj);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+
+ IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU32, pu32Dst, u32Src, pEFlags);
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
+
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_LOCAL(int64_t, i64AddrAdj);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_ASSIGN(i64AddrAdj, u64Src);
+ IEM_MC_AND_ARG_U64(u64Src, 0x3f);
+ IEM_MC_SAR_LOCAL_S64(i64AddrAdj, 6);
+ IEM_MC_SHL_LOCAL_S64(i64AddrAdj, 3);
+ IEM_MC_ADD_LOCAL_S64_TO_EFF_ADDR(GCPtrEffDst, i64AddrAdj);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+
+ IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU64, pu64Dst, u64Src, pEFlags);
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
+
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/** Opcode 0x0f 0xa3. */
+FNIEMOP_DEF(iemOp_bt_Ev_Gv)
+{
+ IEMOP_MNEMONIC("bt Gv,Mp");
+ return FNIEMOP_CALL_1(iemOpCommonBit_Ev_Gv, &g_iemAImpl_bt);
+}
+
+
+/**
+ * Common worker for iemOp_shrd_Ev_Gv_Ib and iemOp_shld_Ev_Gv_Ib.
+ */
+FNIEMOP_DEF_1(iemOpCommonShldShrd_Ib, PCIEMOPSHIFTDBLSIZES, pImpl)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF | X86_EFL_OF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(4, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg, /*=*/cShift, 2);
+ IEM_MC_ARG(uint32_t *, pEFlags, 3);
+
+ IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU16, pu16Dst, u16Src, cShiftArg, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(4, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg, /*=*/cShift, 2);
+ IEM_MC_ARG(uint32_t *, pEFlags, 3);
+
+ IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU32, pu32Dst, u32Src, cShiftArg, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(4, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg, /*=*/cShift, 2);
+ IEM_MC_ARG(uint32_t *, pEFlags, 3);
+
+ IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU64, pu64Dst, u64Src, cShiftArg, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(4, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG(uint8_t, cShiftArg, 2);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
+ IEM_MC_ASSIGN(cShiftArg, cShift);
+ IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU16, pu16Dst, u16Src, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(4, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG(uint8_t, cShiftArg, 2);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
+ IEM_MC_ASSIGN(cShiftArg, cShift);
+ IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU32, pu32Dst, u32Src, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(4, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG(uint8_t, cShiftArg, 2);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
+ IEM_MC_ASSIGN(cShiftArg, cShift);
+ IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU64, pu64Dst, u64Src, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/**
+ * Common worker for iemOp_shrd_Ev_Gv_CL and iemOp_shld_Ev_Gv_CL.
+ */
+FNIEMOP_DEF_1(iemOpCommonShldShrd_CL, PCIEMOPSHIFTDBLSIZES, pImpl)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF | X86_EFL_OF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(4, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG(uint8_t, cShiftArg, 2);
+ IEM_MC_ARG(uint32_t *, pEFlags, 3);
+
+ IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU16, pu16Dst, u16Src, cShiftArg, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(4, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG(uint8_t, cShiftArg, 2);
+ IEM_MC_ARG(uint32_t *, pEFlags, 3);
+
+ IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU32, pu32Dst, u32Src, cShiftArg, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(4, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG(uint8_t, cShiftArg, 2);
+ IEM_MC_ARG(uint32_t *, pEFlags, 3);
+
+ IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU64, pu64Dst, u64Src, cShiftArg, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(4, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG(uint8_t, cShiftArg, 2);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU16, pu16Dst, u16Src, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(4, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG(uint8_t, cShiftArg, 2);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU32, pu32Dst, u32Src, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(4, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG(uint8_t, cShiftArg, 2);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU64, pu64Dst, u64Src, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+
+/** Opcode 0x0f 0xa4. */
+FNIEMOP_DEF(iemOp_shld_Ev_Gv_Ib)
+{
+ IEMOP_MNEMONIC("shld Ev,Gv,Ib");
+ return FNIEMOP_CALL_1(iemOpCommonShldShrd_Ib, &g_iemAImpl_shld);
+}
+
+
+/** Opcode 0x0f 0xa7. */
+FNIEMOP_DEF(iemOp_shld_Ev_Gv_CL)
+{
+ IEMOP_MNEMONIC("shld Ev,Gv,CL");
+ return FNIEMOP_CALL_1(iemOpCommonShldShrd_CL, &g_iemAImpl_shld);
+}
+
+
+/** Opcode 0x0f 0xa8. */
+FNIEMOP_DEF(iemOp_push_gs)
+{
+ IEMOP_MNEMONIC("push gs");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_GS);
+}
+
+
+/** Opcode 0x0f 0xa9. */
+FNIEMOP_DEF(iemOp_pop_gs)
+{
+ IEMOP_MNEMONIC("pop gs");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_pop_Sreg, X86_SREG_GS, pIemCpu->enmEffOpSize);
+}
+
+
+/** Opcode 0x0f 0xaa. */
+FNIEMOP_STUB(iemOp_rsm);
+
+
+/** Opcode 0x0f 0xab. */
+FNIEMOP_DEF(iemOp_bts_Ev_Gv)
+{
+ IEMOP_MNEMONIC("bts Gv,Mp");
+ return FNIEMOP_CALL_1(iemOpCommonBit_Ev_Gv, &g_iemAImpl_bts);
+}
+
+
+/** Opcode 0x0f 0xac. */
+FNIEMOP_DEF(iemOp_shrd_Ev_Gv_Ib)
+{
+ IEMOP_MNEMONIC("shrd Ev,Gv,Ib");
+ return FNIEMOP_CALL_1(iemOpCommonShldShrd_Ib, &g_iemAImpl_shrd);
+}
+
+
+/** Opcode 0x0f 0xad. */
+FNIEMOP_DEF(iemOp_shrd_Ev_Gv_CL)
+{
+ IEMOP_MNEMONIC("shrd Ev,Gv,CL");
+ return FNIEMOP_CALL_1(iemOpCommonShldShrd_CL, &g_iemAImpl_shrd);
+}
+
+
+/** Opcode 0x0f 0xae. */
+FNIEMOP_STUB(iemOp_Grp15);
+
+
+/** Opcode 0x0f 0xaf. */
+FNIEMOP_DEF(iemOp_imul_Gv_Ev)
+{
+ IEMOP_MNEMONIC("imul Gv,Ev");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_imul_two);
+}
+
+
+/** Opcode 0x0f 0xb0. */
+FNIEMOP_STUB(iemOp_cmpxchg_Eb_Gb);
+/** Opcode 0x0f 0xb1. */
+FNIEMOP_STUB(iemOp_cmpxchg_Ev_Gv);
+
+
+FNIEMOP_DEF_1(iemOpCommonLoadSRegAndGreg, uint8_t, iSegReg)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /* The source cannot be a register. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ return IEMOP_RAISE_INVALID_OPCODE();
+ uint8_t const iGReg = ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg;
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(5, 1);
+ IEM_MC_ARG(uint16_t, uSel, 0);
+ IEM_MC_ARG(uint16_t, offSeg, 1);
+ IEM_MC_ARG_CONST(uint8_t, iSegRegArg,/*=*/iSegReg, 2);
+ IEM_MC_ARG_CONST(uint8_t, iGRegArg, /*=*/iGReg, 3);
+ IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 4);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEff);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm);
+ IEM_MC_FETCH_MEM_U16(offSeg, pIemCpu->iEffSeg, GCPtrEff);
+ IEM_MC_FETCH_MEM_U16_DISP(uSel, pIemCpu->iEffSeg, GCPtrEff, 2);
+ IEM_MC_CALL_CIMPL_5(iemCImpl_load_SReg_Greg, uSel, offSeg, iSegRegArg, iGRegArg, enmEffOpSize);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(5, 1);
+ IEM_MC_ARG(uint16_t, uSel, 0);
+ IEM_MC_ARG(uint32_t, offSeg, 1);
+ IEM_MC_ARG_CONST(uint8_t, iSegRegArg,/*=*/iSegReg, 2);
+ IEM_MC_ARG_CONST(uint8_t, iGRegArg, /*=*/iGReg, 3);
+ IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 4);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEff);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm);
+ IEM_MC_FETCH_MEM_U32(offSeg, pIemCpu->iEffSeg, GCPtrEff);
+ IEM_MC_FETCH_MEM_U16_DISP(uSel, pIemCpu->iEffSeg, GCPtrEff, 4);
+ IEM_MC_CALL_CIMPL_5(iemCImpl_load_SReg_Greg, uSel, offSeg, iSegRegArg, iGRegArg, enmEffOpSize);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(5, 1);
+ IEM_MC_ARG(uint16_t, uSel, 0);
+ IEM_MC_ARG(uint64_t, offSeg, 1);
+ IEM_MC_ARG_CONST(uint8_t, iSegRegArg,/*=*/iSegReg, 2);
+ IEM_MC_ARG_CONST(uint8_t, iGRegArg, /*=*/iGReg, 3);
+ IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 4);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEff);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm);
+ IEM_MC_FETCH_MEM_U64(offSeg, pIemCpu->iEffSeg, GCPtrEff);
+ IEM_MC_FETCH_MEM_U16_DISP(uSel, pIemCpu->iEffSeg, GCPtrEff, 8);
+ IEM_MC_CALL_CIMPL_5(iemCImpl_load_SReg_Greg, uSel, offSeg, iSegRegArg, iGRegArg, enmEffOpSize);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0x0f 0xb2. */
+FNIEMOP_DEF(iemOp_lss_Gv_Mp)
+{
+ IEMOP_MNEMONIC("lss Gv,Mp");
+ return FNIEMOP_CALL_1(iemOpCommonLoadSRegAndGreg, X86_SREG_SS);
+}
+
+
+/** Opcode 0x0f 0xb3. */
+FNIEMOP_DEF(iemOp_btr_Ev_Gv)
+{
+ IEMOP_MNEMONIC("btr Gv,Mp");
+ return FNIEMOP_CALL_1(iemOpCommonBit_Ev_Gv, &g_iemAImpl_btr);
+}
+
+
+/** Opcode 0x0f 0xb4. */
+FNIEMOP_DEF(iemOp_lfs_Gv_Mp)
+{
+ IEMOP_MNEMONIC("lfs Gv,Mp");
+ return FNIEMOP_CALL_1(iemOpCommonLoadSRegAndGreg, X86_SREG_FS);
+}
+
+
+/** Opcode 0x0f 0xb5. */
+FNIEMOP_DEF(iemOp_lgs_Gv_Mp)
+{
+ IEMOP_MNEMONIC("lgs Gv,Mp");
+ return FNIEMOP_CALL_1(iemOpCommonLoadSRegAndGreg, X86_SREG_GS);
+}
+
+
+/** Opcode 0x0f 0xb6. */
+FNIEMOP_DEF(iemOp_movzx_Gv_Eb)
+{
+ IEMOP_MNEMONIC("movzx Gv,Eb");
+
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint16_t, u16Value);
+ IEM_MC_FETCH_GREG_U8_ZX_U16(u16Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_FETCH_GREG_U8_ZX_U32(u32Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_FETCH_GREG_U8_ZX_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /*
+ * We're loading a register from memory.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint16_t, u16Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U8_ZX_U16(u16Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U8_ZX_U32(u32Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U8_ZX_U64(u64Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/** Opcode 0x0f 0xb7. */
+FNIEMOP_DEF(iemOp_movzx_Gv_Ew)
+{
+ IEMOP_MNEMONIC("movzx Gv,Ew");
+
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /** @todo Not entirely sure how the operand size prefix is handled here,
+ * assuming that it will be ignored. Would be nice to have a few
+ * test for this. */
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ if (pIemCpu->enmEffOpSize != IEMMODE_64BIT)
+ {
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_FETCH_GREG_U16_ZX_U32(u32Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_FETCH_GREG_U16_ZX_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ }
+ else
+ {
+ /*
+ * We're loading a register from memory.
+ */
+ if (pIemCpu->enmEffOpSize != IEMMODE_64BIT)
+ {
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U16_ZX_U32(u32Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U16_ZX_U64(u64Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0xb8. */
+FNIEMOP_STUB(iemOp_popcnt_Gv_Ev_jmpe);
+/** Opcode 0x0f 0xb9. */
+FNIEMOP_STUB(iemOp_Grp10);
+
+
+/** Opcode 0x0f 0xba. */
+FNIEMOP_DEF(iemOp_Grp8)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ PCIEMOPBINSIZES pImpl;
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0: case 1: case 2: case 3:
+ return IEMOP_RAISE_INVALID_OPCODE();
+ case 4: pImpl = &g_iemAImpl_bt; IEMOP_MNEMONIC("bt Ev,Ib"); break;
+ case 5: pImpl = &g_iemAImpl_bts; IEMOP_MNEMONIC("bts Ev,Ib"); break;
+ case 6: pImpl = &g_iemAImpl_btr; IEMOP_MNEMONIC("btr Ev,Ib"); break;
+ case 7: pImpl = &g_iemAImpl_btc; IEMOP_MNEMONIC("btc Ev,Ib"); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register destination. */
+ uint8_t u8Bit; IEM_OPCODE_GET_NEXT_U8(&u8Bit);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_CONST(uint16_t, u16Src, /*=*/ u8Bit & 0x0f, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_CONST(uint32_t, u32Src, /*=*/ u8Bit & 0x1f, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ u8Bit & 0x3f, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /* memory destination. */
+
+ uint32_t fAccess;
+ if (pImpl->pfnLockedU16)
+ fAccess = IEM_ACCESS_DATA_RW;
+ else /* BT */
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ fAccess = IEM_ACCESS_DATA_R;
+ }
+
+ /** @todo test negative bit offsets! */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t u8Bit; IEM_OPCODE_GET_NEXT_U8(&u8Bit);
+ IEM_MC_ASSIGN(u16Src, u8Bit & 0x0f);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU16, pu16Dst, u16Src, pEFlags);
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
+
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t u8Bit; IEM_OPCODE_GET_NEXT_U8(&u8Bit);
+ IEM_MC_ASSIGN(u32Src, u8Bit & 0x1f);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU32, pu32Dst, u32Src, pEFlags);
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
+
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t u8Bit; IEM_OPCODE_GET_NEXT_U8(&u8Bit);
+ IEM_MC_ASSIGN(u64Src, u8Bit & 0x3f);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU64, pu64Dst, u64Src, pEFlags);
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
+
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+
+}
+
+
+/** Opcode 0x0f 0xbb. */
+FNIEMOP_DEF(iemOp_btc_Ev_Gv)
+{
+ IEMOP_MNEMONIC("btc Gv,Mp");
+ return FNIEMOP_CALL_1(iemOpCommonBit_Ev_Gv, &g_iemAImpl_btc);
+}
+
+
+/** Opcode 0x0f 0xbc. */
+FNIEMOP_DEF(iemOp_bsf_Gv_Ev)
+{
+ IEMOP_MNEMONIC("bsf Gv,Ev");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_bsf);
+}
+
+
+/** Opcode 0x0f 0xbd. */
+FNIEMOP_DEF(iemOp_bsr_Gv_Ev)
+{
+ IEMOP_MNEMONIC("bsr Gv,Ev");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_bsr);
+}
+
+
+/** Opcode 0x0f 0xbe. */
+FNIEMOP_DEF(iemOp_movsx_Gv_Eb)
+{
+ IEMOP_MNEMONIC("movsx Gv,Eb");
+
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint16_t, u16Value);
+ IEM_MC_FETCH_GREG_U8_SX_U16(u16Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_FETCH_GREG_U8_SX_U32(u32Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_FETCH_GREG_U8_SX_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /*
+ * We're loading a register from memory.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint16_t, u16Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U8_SX_U16(u16Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U8_SX_U32(u32Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U8_SX_U64(u64Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/** Opcode 0x0f 0xbf. */
+FNIEMOP_DEF(iemOp_movsx_Gv_Ew)
+{
+ IEMOP_MNEMONIC("movsx Gv,Ew");
+
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /** @todo Not entirely sure how the operand size prefix is handled here,
+ * assuming that it will be ignored. Would be nice to have a few
+ * test for this. */
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ if (pIemCpu->enmEffOpSize != IEMMODE_64BIT)
+ {
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_FETCH_GREG_U16_SX_U32(u32Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_FETCH_GREG_U16_SX_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ }
+ else
+ {
+ /*
+ * We're loading a register from memory.
+ */
+ if (pIemCpu->enmEffOpSize != IEMMODE_64BIT)
+ {
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U16_SX_U32(u32Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U16_SX_U64(u64Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0xc0. */
+FNIEMOP_DEF(iemOp_xadd_Eb_Gb)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_MNEMONIC("xadd Eb,Gb");
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG(uint8_t *, pu8Reg, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U8(pu8Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U8(pu8Reg, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u8, pu8Dst, pu8Reg, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /*
+ * We're accessing memory.
+ */
+ IEM_MC_BEGIN(3, 3);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG(uint8_t *, pu8Reg, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(uint8_t, u8RegCopy);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_GREG_U8(u8RegCopy, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_LOCAL(pu8Reg, u8RegCopy);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u8, pu8Dst, pu8Reg, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u8_locked, pu8Dst, pu8Reg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u8RegCopy);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x0f 0xc1. */
+FNIEMOP_DEF(iemOp_xadd_Ev_Gv)
+{
+ IEMOP_MNEMONIC("xadd Ev,Gv");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t *, pu16Reg, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U16(pu16Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U16(pu16Reg, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u16, pu16Dst, pu16Reg, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t *, pu32Reg, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U32(pu32Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U32(pu32Reg, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u32, pu32Dst, pu32Reg, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t *, pu64Reg, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U64(pu64Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_REF_GREG_U64(pu64Reg, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u64, pu64Dst, pu64Reg, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /*
+ * We're accessing memory.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 3);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t *, pu16Reg, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(uint16_t, u16RegCopy);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_GREG_U16(u16RegCopy, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_LOCAL(pu16Reg, u16RegCopy);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u16, pu16Dst, pu16Reg, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u16_locked, pu16Dst, pu16Reg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_STORE_GREG_U16((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u16RegCopy);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 3);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t *, pu32Reg, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(uint32_t, u32RegCopy);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_GREG_U32(u32RegCopy, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_LOCAL(pu32Reg, u32RegCopy);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u32, pu32Dst, pu32Reg, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u32_locked, pu32Dst, pu32Reg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u32RegCopy);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 3);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t *, pu64Reg, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(uint64_t, u64RegCopy);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_GREG_U64(u64RegCopy, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_LOCAL(pu64Reg, u64RegCopy);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u64, pu64Dst, pu64Reg, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u64_locked, pu64Dst, pu64Reg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u64RegCopy);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+/** Opcode 0x0f 0xc2. */
+FNIEMOP_STUB(iemOp_cmpps_Vps_Wps_Ib__cmppd_Vpd_Wpd_Ib__cmpss_Vss_Wss_Ib__cmpsd_Vsd_Wsd_Ib);
+/** Opcode 0x0f 0xc3. */
+FNIEMOP_STUB(iemOp_movnti_My_Gy);
+/** Opcode 0x0f 0xc4. */
+FNIEMOP_STUB(iemOp_pinsrw_Pq_Ry_Mw_Ib__pinsrw_Vdq_Ry_Mw_Ib);
+/** Opcode 0x0f 0xc5. */
+FNIEMOP_STUB(iemOp_pextrw_Gd_Nq_Ib__pextrw_Gd_Udq_Ib);
+/** Opcode 0x0f 0xc6. */
+FNIEMOP_STUB(iemOp_shufps_Vps_Wps_Ib__shufdp_Vpd_Wpd_Ib);
+/** Opcode 0x0f 0xc7. */
+FNIEMOP_STUB(iemOp_Grp9);
+/** Opcode 0x0f 0xc8. */
+FNIEMOP_STUB(iemOp_bswap_rAX_r8);
+/** Opcode 0x0f 0xc9. */
+FNIEMOP_STUB(iemOp_bswap_rCX_r9);
+/** Opcode 0x0f 0xca. */
+FNIEMOP_STUB(iemOp_bswap_rDX_r10);
+/** Opcode 0x0f 0xcb. */
+FNIEMOP_STUB(iemOp_bswap_rBX_r11);
+/** Opcode 0x0f 0xcc. */
+FNIEMOP_STUB(iemOp_bswap_rSP_r12);
+/** Opcode 0x0f 0xcd. */
+FNIEMOP_STUB(iemOp_bswap_rBP_r13);
+/** Opcode 0x0f 0xce. */
+FNIEMOP_STUB(iemOp_bswap_rSI_r14);
+/** Opcode 0x0f 0xcf. */
+FNIEMOP_STUB(iemOp_bswap_rDI_r15);
+/** Opcode 0x0f 0xd0. */
+FNIEMOP_STUB(iemOp_addsubpd_Vpd_Wpd__addsubps_Vps_Wps);
+/** Opcode 0x0f 0xd1. */
+FNIEMOP_STUB(iemOp_psrlw_Pp_Qp__psrlw_Vdp_Wdq);
+/** Opcode 0x0f 0xd2. */
+FNIEMOP_STUB(iemOp_psrld_Pq_Qq__psrld_Vdq_Wdq);
+/** Opcode 0x0f 0xd3. */
+FNIEMOP_STUB(iemOp_psrlq_Pq_Qq__psrlq_Vdq_Wdq);
+/** Opcode 0x0f 0xd4. */
+FNIEMOP_STUB(iemOp_paddq_Pq_Qq__paddq_Vdq_Wdq);
+/** Opcode 0x0f 0xd5. */
+FNIEMOP_STUB(iemOp_pmulq_Pq_Qq__pmullw_Vdq_Wdq);
+/** Opcode 0x0f 0xd6. */
+FNIEMOP_STUB(iemOp_movq_Wq_Vq__movq2dq_Vdq_Nq__movdq2q_Pq_Uq);
+/** Opcode 0x0f 0xd7. */
+FNIEMOP_STUB(iemOp_pmovmskb_Gd_Nq__pmovmskb_Gd_Udq);
+/** Opcode 0x0f 0xd8. */
+FNIEMOP_STUB(iemOp_psubusb_Pq_Qq__psubusb_Vdq_Wdq);
+/** Opcode 0x0f 0xd9. */
+FNIEMOP_STUB(iemOp_psubusw_Pq_Qq__psubusw_Vdq_Wdq);
+/** Opcode 0x0f 0xda. */
+FNIEMOP_STUB(iemOp_pminub_Pq_Qq__pminub_Vdq_Wdq);
+/** Opcode 0x0f 0xdb. */
+FNIEMOP_STUB(iemOp_pand_Pq_Qq__pand_Vdq_Wdq);
+/** Opcode 0x0f 0xdc. */
+FNIEMOP_STUB(iemOp_paddusb_Pq_Qq__paddusb_Vdq_Wdq);
+/** Opcode 0x0f 0xdd. */
+FNIEMOP_STUB(iemOp_paddusw_Pq_Qq__paddusw_Vdq_Wdq);
+/** Opcode 0x0f 0xde. */
+FNIEMOP_STUB(iemOp_pmaxub_Pq_Qq__pamxub_Vdq_Wdq);
+/** Opcode 0x0f 0xdf. */
+FNIEMOP_STUB(iemOp_pandn_Pq_Qq__pandn_Vdq_Wdq);
+/** Opcode 0x0f 0xe0. */
+FNIEMOP_STUB(iemOp_pavgb_Pq_Qq__pavgb_Vdq_Wdq);
+/** Opcode 0x0f 0xe1. */
+FNIEMOP_STUB(iemOp_psraw_Pq_Qq__psraw_Vdq_Wdq);
+/** Opcode 0x0f 0xe2. */
+FNIEMOP_STUB(iemOp_psrad_Pq_Qq__psrad_Vdq_Wdq);
+/** Opcode 0x0f 0xe3. */
+FNIEMOP_STUB(iemOp_pavgw_Pq_Qq__pavgw_Vdq_Wdq);
+/** Opcode 0x0f 0xe4. */
+FNIEMOP_STUB(iemOp_pmulhuw_Pq_Qq__pmulhuw_Vdq_Wdq);
+/** Opcode 0x0f 0xe5. */
+FNIEMOP_STUB(iemOp_pmulhw_Pq_Qq__pmulhw_Vdq_Wdq);
+/** Opcode 0x0f 0xe6. */
+FNIEMOP_STUB(iemOp_cvttpd2dq_Vdq_Wdp__cvtdq2pd_Vdq_Wpd__cvtpd2dq_Vdq_Wpd);
+/** Opcode 0x0f 0xe7. */
+FNIEMOP_STUB(iemOp_movntq_Mq_Pq__movntdq_Mdq_Vdq);
+/** Opcode 0x0f 0xe8. */
+FNIEMOP_STUB(iemOp_psubsb_Pq_Qq__psubsb_Vdq_Wdq);
+/** Opcode 0x0f 0xe9. */
+FNIEMOP_STUB(iemOp_psubsw_Pq_Qq__psubsw_Vdq_Wdq);
+/** Opcode 0x0f 0xea. */
+FNIEMOP_STUB(iemOp_pminsw_Pq_Qq__pminsw_Vdq_Wdq);
+/** Opcode 0x0f 0xeb. */
+FNIEMOP_STUB(iemOp_por_Pq_Qq__por_Vdq_Wdq);
+/** Opcode 0x0f 0xec. */
+FNIEMOP_STUB(iemOp_paddsb_Pq_Qq__paddsb_Vdq_Wdq);
+/** Opcode 0x0f 0xed. */
+FNIEMOP_STUB(iemOp_paddsw_Pq_Qq__paddsw_Vdq_Wdq);
+/** Opcode 0x0f 0xee. */
+FNIEMOP_STUB(iemOp_pmaxsw_Pq_Qq__pmaxsw_Vdq_Wdq);
+/** Opcode 0x0f 0xef. */
+FNIEMOP_STUB(iemOp_pxor_Pq_Qq__pxor_Vdq_Wdq);
+/** Opcode 0x0f 0xf0. */
+FNIEMOP_STUB(iemOp_lddqu_Vdq_Mdq);
+/** Opcode 0x0f 0xf1. */
+FNIEMOP_STUB(iemOp_psllw_Pq_Qq__pslw_Vdq_Wdq);
+/** Opcode 0x0f 0xf2. */
+FNIEMOP_STUB(iemOp_psld_Pq_Qq__pslld_Vdq_Wdq);
+/** Opcode 0x0f 0xf3. */
+FNIEMOP_STUB(iemOp_psllq_Pq_Qq__pslq_Vdq_Wdq);
+/** Opcode 0x0f 0xf4. */
+FNIEMOP_STUB(iemOp_pmuludq_Pq_Qq__pmuludq_Vdq_Wdq);
+/** Opcode 0x0f 0xf5. */
+FNIEMOP_STUB(iemOp_pmaddwd_Pq_Qq__pmaddwd_Vdq_Wdq);
+/** Opcode 0x0f 0xf6. */
+FNIEMOP_STUB(iemOp_psadbw_Pq_Qq__psadbw_Vdq_Wdq);
+/** Opcode 0x0f 0xf7. */
+FNIEMOP_STUB(iemOp_maskmovq_Pq_Nq__maskmovdqu_Vdq_Udq);
+/** Opcode 0x0f 0xf8. */
+FNIEMOP_STUB(iemOp_psubb_Pq_Qq_psubb_Vdq_Wdq);
+/** Opcode 0x0f 0xf9. */
+FNIEMOP_STUB(iemOp_psubw_Pq_Qq__psubw_Vdq_Wdq);
+/** Opcode 0x0f 0xfa. */
+FNIEMOP_STUB(iemOp_psubd_Pq_Qq__psubd_Vdq_Wdq);
+/** Opcode 0x0f 0xfb. */
+FNIEMOP_STUB(iemOp_psubq_Pq_Qq__psbuq_Vdq_Wdq);
+/** Opcode 0x0f 0xfc. */
+FNIEMOP_STUB(iemOp_paddb_Pq_Qq__paddb_Vdq_Wdq);
+/** Opcode 0x0f 0xfd. */
+FNIEMOP_STUB(iemOp_paddw_Pq_Qq__paddw_Vdq_Wdq);
+/** Opcode 0x0f 0xfe. */
+FNIEMOP_STUB(iemOp_paddd_Pq_Qq__paddd_Vdq_Wdq);
+
+
+const PFNIEMOP g_apfnTwoByteMap[256] =
+{
+ /* 0x00 */ iemOp_Grp6, iemOp_Grp7, iemOp_lar_Gv_Ew, iemOp_lsl_Gv_Ew,
+ /* 0x04 */ iemOp_Invalid, iemOp_syscall, iemOp_clts, iemOp_sysret,
+ /* 0x08 */ iemOp_invd, iemOp_wbinvd, iemOp_Invalid, iemOp_ud2,
+ /* 0x0c */ iemOp_Invalid, iemOp_nop_Ev_prefetch, iemOp_femms, iemOp_3Dnow,
+ /* 0x10 */ iemOp_movups_Vps_Wps__movupd_Vpd_Wpd__movss_Vss_Wss__movsd_Vsd_Wsd,
+ /* 0x11 */ iemOp_movups_Wps_Vps__movupd_Wpd_Vpd__movss_Wss_Vss__movsd_Vsd_Wsd,
+ /* 0x12 */ iemOp_movlps_Vq_Mq__movhlps_Vq_Uq__movlpd_Vq_Mq__movsldup_Vq_Wq__movddup_Vq_Wq,
+ /* 0x13 */ iemOp_movlps_Mq_Vq__movlpd_Mq_Vq,
+ /* 0x14 */ iemOp_unpckhlps_Vps_Wq__unpcklpd_Vpd_Wq,
+ /* 0x15 */ iemOp_unpckhps_Vps_Wq__unpckhpd_Vpd_Wq,
+ /* 0x16 */ iemOp_movhps_Vq_Mq__movlhps_Vq_Uq__movhpd_Vq_Mq__movshdup_Vq_Wq,
+ /* 0x17 */ iemOp_movhps_Mq_Vq__movhpd_Mq_Vq,
+ /* 0x18 */ iemOp_prefetch_Grp16, iemOp_Invalid, iemOp_Invalid, iemOp_Invalid,
+ /* 0x1c */ iemOp_Invalid, iemOp_Invalid, iemOp_Invalid, iemOp_Invalid,
+ /* 0x20 */ iemOp_mov_Rd_Cd, iemOp_mov_Rd_Dd, iemOp_mov_Cd_Rd, iemOp_mov_Dd_Rd,
+ /* 0x24 */ iemOp_mov_Rd_Td, iemOp_Invalid, iemOp_mov_Td_Rd, iemOp_Invalid,
+ /* 0x28 */ iemOp_movaps_Vps_Wps__movapd_Vpd_Wpd,
+ /* 0x29 */ iemOp_movaps_Wps_Vps__movapd_Wpd_Vpd,
+ /* 0x2a */ iemOp_cvtpi2ps_Vps_Qpi__cvtpi2pd_Vpd_Qpi__cvtsi2ss_Vss_Ey__cvtsi2sd_Vsd_Ey,
+ /* 0x2b */ iemOp_movntps_Mps_Vps__movntpd_Mpd_Vpd,
+ /* 0x2c */ iemOp_cvttps2pi_Ppi_Wps__cvttpd2pi_Ppi_Wpd__cvttss2si_Gy_Wss__cvttsd2si_Yu_Wsd,
+ /* 0x2d */ iemOp_cvtps2pi_Ppi_Wps__cvtpd2pi_QpiWpd__cvtss2si_Gy_Wss__cvtsd2si_Gy_Wsd,
+ /* 0x2e */ iemOp_ucomiss_Vss_Wss__ucomisd_Vsd_Wsd,
+ /* 0x2f */ iemOp_comiss_Vss_Wss__comisd_Vsd_Wsd,
+ /* 0x30 */ iemOp_wrmsr, iemOp_rdtsc, iemOp_rdmsr, iemOp_rdpmc,
+ /* 0x34 */ iemOp_sysenter, iemOp_sysexit, iemOp_Invalid, iemOp_getsec,
+ /* 0x38 */ iemOp_3byte_Esc_A4, iemOp_Invalid, iemOp_3byte_Esc_A5, iemOp_Invalid,
+ /* 0x3c */ iemOp_movnti_Gv_Ev/*?*/,iemOp_Invalid, iemOp_Invalid, iemOp_Invalid,
+ /* 0x40 */ iemOp_cmovo_Gv_Ev, iemOp_cmovno_Gv_Ev, iemOp_cmovc_Gv_Ev, iemOp_cmovnc_Gv_Ev,
+ /* 0x44 */ iemOp_cmove_Gv_Ev, iemOp_cmovne_Gv_Ev, iemOp_cmovbe_Gv_Ev, iemOp_cmovnbe_Gv_Ev,
+ /* 0x48 */ iemOp_cmovs_Gv_Ev, iemOp_cmovns_Gv_Ev, iemOp_cmovp_Gv_Ev, iemOp_cmovnp_Gv_Ev,
+ /* 0x4c */ iemOp_cmovl_Gv_Ev, iemOp_cmovnl_Gv_Ev, iemOp_cmovle_Gv_Ev, iemOp_cmovnle_Gv_Ev,
+ /* 0x50 */ iemOp_movmskps_Gy_Ups__movmskpd_Gy_Upd,
+ /* 0x51 */ iemOp_sqrtps_Wps_Vps__sqrtpd_Wpd_Vpd__sqrtss_Vss_Wss__sqrtsd_Vsd_Wsd,
+ /* 0x52 */ iemOp_rsqrtps_Wps_Vps__rsqrtss_Vss_Wss,
+ /* 0x53 */ iemOp_rcpps_Wps_Vps__rcpss_Vs_Wss,
+ /* 0x54 */ iemOp_andps_Vps_Wps__andpd_Wpd_Vpd,
+ /* 0x55 */ iemOp_andnps_Vps_Wps__andnpd_Wpd_Vpd,
+ /* 0x56 */ iemOp_orps_Wpd_Vpd__orpd_Wpd_Vpd,
+ /* 0x57 */ iemOp_xorps_Vps_Wps__xorpd_Wpd_Vpd,
+ /* 0x58 */ iemOp_addps_Vps_Wps__addpd_Vpd_Wpd__addss_Vss_Wss__addsd_Vsd_Wsd,
+ /* 0x59 */ iemOp_mulps_Vps_Wps__mulpd_Vpd_Wpd__mulss_Vss__Wss__mulsd_Vsd_Wsd,
+ /* 0x5a */ iemOp_cvtps2pd_Vpd_Wps__cvtpd2ps_Vps_Wpd__cvtss2sd_Vsd_Wss__cvtsd2ss_Vss_Wsd,
+ /* 0x5b */ iemOp_cvtdq2ps_Vps_Wdq__cvtps2dq_Vdq_Wps__cvtps2dq_Vdq_Wps,
+ /* 0x5c */ iemOp_subps_Vps_Wps__subpd_Vps_Wdp__subss_Vss_Wss__subsd_Vsd_Wsd,
+ /* 0x5d */ iemOp_minps_Vps_Wps__minpd_Vpd_Wpd__minss_Vss_Wss__minsd_Vsd_Wsd,
+ /* 0x5e */ iemOp_divps_Vps_Wps__divpd_Vpd_Wpd__divss_Vss_Wss__divsd_Vsd_Wsd,
+ /* 0x5f */ iemOp_maxps_Vps_Wps__maxpd_Vpd_Wpd__maxss_Vss_Wss__maxsd_Vsd_Wsd,
+ /* 0x60 */ iemOp_punpcklbw_Pq_Qd__punpcklbw_Vdq_Wdq,
+ /* 0x61 */ iemOp_punpcklwd_Pq_Qd__punpcklwd_Vdq_Wdq,
+ /* 0x62 */ iemOp_punpckldq_Pq_Qd__punpckldq_Vdq_Wdq,
+ /* 0x63 */ iemOp_packsswb_Pq_Qq__packsswb_Vdq_Wdq,
+ /* 0x64 */ iemOp_pcmpgtb_Pq_Qq__pcmpgtb_Vdq_Wdq,
+ /* 0x65 */ iemOp_pcmpgtw_Pq_Qq__pcmpgtw_Vdq_Wdq,
+ /* 0x66 */ iemOp_pcmpgtd_Pq_Qq__pcmpgtd_Vdq_Wdq,
+ /* 0x67 */ iemOp_packuswb_Pq_Qq__packuswb_Vdq_Wdq,
+ /* 0x68 */ iemOp_punpckhbw_Pq_Qq__punpckhbw_Vdq_Wdq,
+ /* 0x69 */ iemOp_punpckhwd_Pq_Qd__punpckhwd_Vdq_Wdq,
+ /* 0x6a */ iemOp_punpckhdq_Pq_Qd__punpckhdq_Vdq_Wdq,
+ /* 0x6b */ iemOp_packssdw_Pq_Qd__packssdq_Vdq_Wdq,
+ /* 0x6c */ iemOp_punpcklqdq_Vdq_Wdq,
+ /* 0x6d */ iemOp_punpckhqdq_Vdq_Wdq,
+ /* 0x6e */ iemOp_movd_q_Pd_Ey__movd_q_Vy_Ey,
+ /* 0x6f */ iemOp_movq_Pq_Qq__movdqa_Vdq_Wdq__movdqu_Vdq_Wdq,
+ /* 0x70 */ iemOp_pshufw_Pq_Qq_Ib__pshufd_Vdq_Wdq_Ib__pshufhw_Vdq_Wdq_Ib__pshuflq_Vdq_Wdq_Ib,
+ /* 0x71 */ iemOp_Grp12,
+ /* 0x72 */ iemOp_Grp13,
+ /* 0x73 */ iemOp_Grp14,
+ /* 0x74 */ iemOp_pcmpeqb_Pq_Qq__pcmpeqb_Vdq_Wdq,
+ /* 0x75 */ iemOp_pcmpeqw_Pq_Qq__pcmpeqw_Vdq_Wdq,
+ /* 0x76 */ iemOp_pcmped_Pq_Qq__pcmpeqd_Vdq_Wdq,
+ /* 0x77 */ iemOp_emms,
+ /* 0x78 */ iemOp_vmread, iemOp_vmwrite, iemOp_Invalid, iemOp_Invalid,
+ /* 0x7c */ iemOp_haddpd_Vdp_Wpd__haddps_Vps_Wps,
+ /* 0x7d */ iemOp_hsubpd_Vpd_Wpd__hsubps_Vps_Wps,
+ /* 0x7e */ iemOp_movd_q_Ey_Pd__movd_q_Ey_Vy__movq_Vq_Wq,
+ /* 0x7f */ iemOp_movq_Qq_Pq__movq_movdqa_Wdq_Vdq__movdqu_Wdq_Vdq,
+ /* 0x80 */ iemOp_jo_Jv, iemOp_jno_Jv, iemOp_jc_Jv, iemOp_jnc_Jv,
+ /* 0x84 */ iemOp_je_Jv, iemOp_jne_Jv, iemOp_jbe_Jv, iemOp_jnbe_Jv,
+ /* 0x88 */ iemOp_js_Jv, iemOp_jns_Jv, iemOp_jp_Jv, iemOp_jnp_Jv,
+ /* 0x8c */ iemOp_jl_Jv, iemOp_jnl_Jv, iemOp_jle_Jv, iemOp_jnle_Jv,
+ /* 0x90 */ iemOp_seto_Eb, iemOp_setno_Eb, iemOp_setc_Eb, iemOp_setnc_Eb,
+ /* 0x94 */ iemOp_sete_Eb, iemOp_setne_Eb, iemOp_setbe_Eb, iemOp_setnbe_Eb,
+ /* 0x98 */ iemOp_sets_Eb, iemOp_setns_Eb, iemOp_setp_Eb, iemOp_setnp_Eb,
+ /* 0x9c */ iemOp_setl_Eb, iemOp_setnl_Eb, iemOp_setle_Eb, iemOp_setnle_Eb,
+ /* 0xa0 */ iemOp_push_fs, iemOp_pop_fs, iemOp_cpuid, iemOp_bt_Ev_Gv,
+ /* 0xa4 */ iemOp_shld_Ev_Gv_Ib, iemOp_shld_Ev_Gv_CL, iemOp_Invalid, iemOp_Invalid,
+ /* 0xa8 */ iemOp_push_gs, iemOp_pop_gs, iemOp_rsm, iemOp_bts_Ev_Gv,
+ /* 0xac */ iemOp_shrd_Ev_Gv_Ib, iemOp_shrd_Ev_Gv_CL, iemOp_Grp15, iemOp_imul_Gv_Ev,
+ /* 0xb0 */ iemOp_cmpxchg_Eb_Gb, iemOp_cmpxchg_Ev_Gv, iemOp_lss_Gv_Mp, iemOp_btr_Ev_Gv,
+ /* 0xb4 */ iemOp_lfs_Gv_Mp, iemOp_lgs_Gv_Mp, iemOp_movzx_Gv_Eb, iemOp_movzx_Gv_Ew,
+ /* 0xb8 */ iemOp_popcnt_Gv_Ev_jmpe,iemOp_Grp10, iemOp_Grp8, iemOp_btc_Ev_Gv,
+ /* 0xbc */ iemOp_bsf_Gv_Ev, iemOp_bsr_Gv_Ev, iemOp_movsx_Gv_Eb, iemOp_movsx_Gv_Ew,
+ /* 0xc0 */ iemOp_xadd_Eb_Gb,
+ /* 0xc1 */ iemOp_xadd_Ev_Gv,
+ /* 0xc2 */ iemOp_cmpps_Vps_Wps_Ib__cmppd_Vpd_Wpd_Ib__cmpss_Vss_Wss_Ib__cmpsd_Vsd_Wsd_Ib,
+ /* 0xc3 */ iemOp_movnti_My_Gy,
+ /* 0xc4 */ iemOp_pinsrw_Pq_Ry_Mw_Ib__pinsrw_Vdq_Ry_Mw_Ib,
+ /* 0xc5 */ iemOp_pextrw_Gd_Nq_Ib__pextrw_Gd_Udq_Ib,
+ /* 0xc6 */ iemOp_shufps_Vps_Wps_Ib__shufdp_Vpd_Wpd_Ib,
+ /* 0xc7 */ iemOp_Grp9,
+ /* 0xc8 */ iemOp_bswap_rAX_r8, iemOp_bswap_rCX_r9, iemOp_bswap_rDX_r10, iemOp_bswap_rBX_r11,
+ /* 0xcc */ iemOp_bswap_rSP_r12, iemOp_bswap_rBP_r13, iemOp_bswap_rSI_r14, iemOp_bswap_rDI_r15,
+ /* 0xd0 */ iemOp_addsubpd_Vpd_Wpd__addsubps_Vps_Wps,
+ /* 0xd1 */ iemOp_psrlw_Pp_Qp__psrlw_Vdp_Wdq,
+ /* 0xd2 */ iemOp_psrld_Pq_Qq__psrld_Vdq_Wdq,
+ /* 0xd3 */ iemOp_psrlq_Pq_Qq__psrlq_Vdq_Wdq,
+ /* 0xd4 */ iemOp_paddq_Pq_Qq__paddq_Vdq_Wdq,
+ /* 0xd5 */ iemOp_pmulq_Pq_Qq__pmullw_Vdq_Wdq,
+ /* 0xd6 */ iemOp_movq_Wq_Vq__movq2dq_Vdq_Nq__movdq2q_Pq_Uq,
+ /* 0xd7 */ iemOp_pmovmskb_Gd_Nq__pmovmskb_Gd_Udq,
+ /* 0xd8 */ iemOp_psubusb_Pq_Qq__psubusb_Vdq_Wdq,
+ /* 0xd9 */ iemOp_psubusw_Pq_Qq__psubusw_Vdq_Wdq,
+ /* 0xda */ iemOp_pminub_Pq_Qq__pminub_Vdq_Wdq,
+ /* 0xdb */ iemOp_pand_Pq_Qq__pand_Vdq_Wdq,
+ /* 0xdc */ iemOp_paddusb_Pq_Qq__paddusb_Vdq_Wdq,
+ /* 0xdd */ iemOp_paddusw_Pq_Qq__paddusw_Vdq_Wdq,
+ /* 0xde */ iemOp_pmaxub_Pq_Qq__pamxub_Vdq_Wdq,
+ /* 0xdf */ iemOp_pandn_Pq_Qq__pandn_Vdq_Wdq,
+ /* 0xe0 */ iemOp_pavgb_Pq_Qq__pavgb_Vdq_Wdq,
+ /* 0xe1 */ iemOp_psraw_Pq_Qq__psraw_Vdq_Wdq,
+ /* 0xe2 */ iemOp_psrad_Pq_Qq__psrad_Vdq_Wdq,
+ /* 0xe3 */ iemOp_pavgw_Pq_Qq__pavgw_Vdq_Wdq,
+ /* 0xe4 */ iemOp_pmulhuw_Pq_Qq__pmulhuw_Vdq_Wdq,
+ /* 0xe5 */ iemOp_pmulhw_Pq_Qq__pmulhw_Vdq_Wdq,
+ /* 0xe6 */ iemOp_cvttpd2dq_Vdq_Wdp__cvtdq2pd_Vdq_Wpd__cvtpd2dq_Vdq_Wpd,
+ /* 0xe7 */ iemOp_movntq_Mq_Pq__movntdq_Mdq_Vdq,
+ /* 0xe8 */ iemOp_psubsb_Pq_Qq__psubsb_Vdq_Wdq,
+ /* 0xe9 */ iemOp_psubsw_Pq_Qq__psubsw_Vdq_Wdq,
+ /* 0xea */ iemOp_pminsw_Pq_Qq__pminsw_Vdq_Wdq,
+ /* 0xeb */ iemOp_por_Pq_Qq__por_Vdq_Wdq,
+ /* 0xec */ iemOp_paddsb_Pq_Qq__paddsb_Vdq_Wdq,
+ /* 0xed */ iemOp_paddsw_Pq_Qq__paddsw_Vdq_Wdq,
+ /* 0xee */ iemOp_pmaxsw_Pq_Qq__pmaxsw_Vdq_Wdq,
+ /* 0xef */ iemOp_pxor_Pq_Qq__pxor_Vdq_Wdq,
+ /* 0xf0 */ iemOp_lddqu_Vdq_Mdq,
+ /* 0xf1 */ iemOp_psllw_Pq_Qq__pslw_Vdq_Wdq,
+ /* 0xf2 */ iemOp_psld_Pq_Qq__pslld_Vdq_Wdq,
+ /* 0xf3 */ iemOp_psllq_Pq_Qq__pslq_Vdq_Wdq,
+ /* 0xf4 */ iemOp_pmuludq_Pq_Qq__pmuludq_Vdq_Wdq,
+ /* 0xf5 */ iemOp_pmaddwd_Pq_Qq__pmaddwd_Vdq_Wdq,
+ /* 0xf6 */ iemOp_psadbw_Pq_Qq__psadbw_Vdq_Wdq,
+ /* 0xf7 */ iemOp_maskmovq_Pq_Nq__maskmovdqu_Vdq_Udq,
+ /* 0xf8 */ iemOp_psubb_Pq_Qq_psubb_Vdq_Wdq,
+ /* 0xf9 */ iemOp_psubw_Pq_Qq__psubw_Vdq_Wdq,
+ /* 0xfa */ iemOp_psubd_Pq_Qq__psubd_Vdq_Wdq,
+ /* 0xfb */ iemOp_psubq_Pq_Qq__psbuq_Vdq_Wdq,
+ /* 0xfc */ iemOp_paddb_Pq_Qq__paddb_Vdq_Wdq,
+ /* 0xfd */ iemOp_paddw_Pq_Qq__paddw_Vdq_Wdq,
+ /* 0xfe */ iemOp_paddd_Pq_Qq__paddd_Vdq_Wdq,
+ /* 0xff */ iemOp_Invalid
+};
+
+/** @} */
+
+
+/** @name One byte opcodes.
+ *
+ * @{
+ */
+
+/** Opcode 0x00. */
+FNIEMOP_DEF(iemOp_add_Eb_Gb)
+{
+ IEMOP_MNEMONIC("add Eb,Gb");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_add);
+}
+
+
+/** Opcode 0x01. */
+FNIEMOP_DEF(iemOp_add_Ev_Gv)
+{
+ IEMOP_MNEMONIC("add Ev,Gv");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_add);
+}
+
+
+/** Opcode 0x02. */
+FNIEMOP_DEF(iemOp_add_Gb_Eb)
+{
+ IEMOP_MNEMONIC("add Gb,Eb");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_add);
+}
+
+
+/** Opcode 0x03. */
+FNIEMOP_DEF(iemOp_add_Gv_Ev)
+{
+ IEMOP_MNEMONIC("add Gv,Ev");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_add);
+}
+
+
+/** Opcode 0x04. */
+FNIEMOP_DEF(iemOp_add_Al_Ib)
+{
+ IEMOP_MNEMONIC("add al,Ib");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_add);
+}
+
+
+/** Opcode 0x05. */
+FNIEMOP_DEF(iemOp_add_eAX_Iz)
+{
+ IEMOP_MNEMONIC("add rAX,Iz");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_add);
+}
+
+
+/** Opcode 0x06. */
+FNIEMOP_DEF(iemOp_push_ES)
+{
+ IEMOP_MNEMONIC("push es");
+ return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_ES);
+}
+
+
+/** Opcode 0x07. */
+FNIEMOP_DEF(iemOp_pop_ES)
+{
+ IEMOP_MNEMONIC("pop es");
+ IEMOP_HLP_NO_64BIT();
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_pop_Sreg, X86_SREG_ES, pIemCpu->enmEffOpSize);
+}
+
+
+/** Opcode 0x08. */
+FNIEMOP_DEF(iemOp_or_Eb_Gb)
+{
+ IEMOP_MNEMONIC("or Eb,Gb");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_or);
+}
+
+
+/** Opcode 0x09. */
+FNIEMOP_DEF(iemOp_or_Ev_Gv)
+{
+ IEMOP_MNEMONIC("or Ev,Gv ");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_or);
+}
+
+
+/** Opcode 0x0a. */
+FNIEMOP_DEF(iemOp_or_Gb_Eb)
+{
+ IEMOP_MNEMONIC("or Gb,Eb");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_or);
+}
+
+
+/** Opcode 0x0b. */
+FNIEMOP_DEF(iemOp_or_Gv_Ev)
+{
+ IEMOP_MNEMONIC("or Gv,Ev");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_or);
+}
+
+
+/** Opcode 0x0c. */
+FNIEMOP_DEF(iemOp_or_Al_Ib)
+{
+ IEMOP_MNEMONIC("or al,Ib");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_or);
+}
+
+
+/** Opcode 0x0d. */
+FNIEMOP_DEF(iemOp_or_eAX_Iz)
+{
+ IEMOP_MNEMONIC("or rAX,Iz");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_or);
+}
+
+
+/** Opcode 0x0e. */
+FNIEMOP_DEF(iemOp_push_CS)
+{
+ IEMOP_MNEMONIC("push cs");
+ return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_CS);
+}
+
+
+/** Opcode 0x0f. */
+FNIEMOP_DEF(iemOp_2byteEscape)
+{
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnTwoByteMap[b]);
+}
+
+/** Opcode 0x10. */
+FNIEMOP_DEF(iemOp_adc_Eb_Gb)
+{
+ IEMOP_MNEMONIC("adc Eb,Gb");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_adc);
+}
+
+
+/** Opcode 0x11. */
+FNIEMOP_DEF(iemOp_adc_Ev_Gv)
+{
+ IEMOP_MNEMONIC("adc Ev,Gv");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_adc);
+}
+
+
+/** Opcode 0x12. */
+FNIEMOP_DEF(iemOp_adc_Gb_Eb)
+{
+ IEMOP_MNEMONIC("adc Gb,Eb");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_adc);
+}
+
+
+/** Opcode 0x13. */
+FNIEMOP_DEF(iemOp_adc_Gv_Ev)
+{
+ IEMOP_MNEMONIC("adc Gv,Ev");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_adc);
+}
+
+
+/** Opcode 0x14. */
+FNIEMOP_DEF(iemOp_adc_Al_Ib)
+{
+ IEMOP_MNEMONIC("adc al,Ib");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_adc);
+}
+
+
+/** Opcode 0x15. */
+FNIEMOP_DEF(iemOp_adc_eAX_Iz)
+{
+ IEMOP_MNEMONIC("adc rAX,Iz");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_adc);
+}
+
+
+/** Opcode 0x16. */
+FNIEMOP_DEF(iemOp_push_SS)
+{
+ IEMOP_MNEMONIC("push ss");
+ return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_SS);
+}
+
+
+/** Opcode 0x17. */
+FNIEMOP_DEF(iemOp_pop_SS)
+{
+ IEMOP_MNEMONIC("pop ss"); /** @todo implies instruction fusing? */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_NO_64BIT();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_pop_Sreg, X86_SREG_SS, pIemCpu->enmEffOpSize);
+}
+
+
+/** Opcode 0x18. */
+FNIEMOP_DEF(iemOp_sbb_Eb_Gb)
+{
+ IEMOP_MNEMONIC("sbb Eb,Gb");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_sbb);
+}
+
+
+/** Opcode 0x19. */
+FNIEMOP_DEF(iemOp_sbb_Ev_Gv)
+{
+ IEMOP_MNEMONIC("sbb Ev,Gv");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_sbb);
+}
+
+
+/** Opcode 0x1a. */
+FNIEMOP_DEF(iemOp_sbb_Gb_Eb)
+{
+ IEMOP_MNEMONIC("sbb Gb,Eb");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_sbb);
+}
+
+
+/** Opcode 0x1b. */
+FNIEMOP_DEF(iemOp_sbb_Gv_Ev)
+{
+ IEMOP_MNEMONIC("sbb Gv,Ev");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_sbb);
+}
+
+
+/** Opcode 0x1c. */
+FNIEMOP_DEF(iemOp_sbb_Al_Ib)
+{
+ IEMOP_MNEMONIC("sbb al,Ib");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_sbb);
+}
+
+
+/** Opcode 0x1d. */
+FNIEMOP_DEF(iemOp_sbb_eAX_Iz)
+{
+ IEMOP_MNEMONIC("sbb rAX,Iz");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_sbb);
+}
+
+
+/** Opcode 0x1e. */
+FNIEMOP_DEF(iemOp_push_DS)
+{
+ IEMOP_MNEMONIC("push ds");
+ return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_DS);
+}
+
+
+/** Opcode 0x1f. */
+FNIEMOP_DEF(iemOp_pop_DS)
+{
+ IEMOP_MNEMONIC("pop ds");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_NO_64BIT();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_pop_Sreg, X86_SREG_DS, pIemCpu->enmEffOpSize);
+}
+
+
+/** Opcode 0x20. */
+FNIEMOP_DEF(iemOp_and_Eb_Gb)
+{
+ IEMOP_MNEMONIC("and Eb,Gb");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_and);
+}
+
+
+/** Opcode 0x21. */
+FNIEMOP_DEF(iemOp_and_Ev_Gv)
+{
+ IEMOP_MNEMONIC("and Ev,Gv");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_and);
+}
+
+
+/** Opcode 0x22. */
+FNIEMOP_DEF(iemOp_and_Gb_Eb)
+{
+ IEMOP_MNEMONIC("and Gb,Eb");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_and);
+}
+
+
+/** Opcode 0x23. */
+FNIEMOP_DEF(iemOp_and_Gv_Ev)
+{
+ IEMOP_MNEMONIC("and Gv,Ev");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_and);
+}
+
+
+/** Opcode 0x24. */
+FNIEMOP_DEF(iemOp_and_Al_Ib)
+{
+ IEMOP_MNEMONIC("and al,Ib");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_and);
+}
+
+
+/** Opcode 0x25. */
+FNIEMOP_DEF(iemOp_and_eAX_Iz)
+{
+ IEMOP_MNEMONIC("and rAX,Iz");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_and);
+}
+
+
+/** Opcode 0x26. */
+FNIEMOP_DEF(iemOp_seg_ES)
+{
+ pIemCpu->fPrefixes |= IEM_OP_PRF_SEG_ES;
+ pIemCpu->iEffSeg = X86_SREG_ES;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+}
+
+
+/** Opcode 0x27. */
+FNIEMOP_STUB(iemOp_daa);
+
+
+/** Opcode 0x28. */
+FNIEMOP_DEF(iemOp_sub_Eb_Gb)
+{
+ IEMOP_MNEMONIC("sub Eb,Gb");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_sub);
+}
+
+
+/** Opcode 0x29. */
+FNIEMOP_DEF(iemOp_sub_Ev_Gv)
+{
+ IEMOP_MNEMONIC("sub Ev,Gv");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_sub);
+}
+
+
+/** Opcode 0x2a. */
+FNIEMOP_DEF(iemOp_sub_Gb_Eb)
+{
+ IEMOP_MNEMONIC("sub Gb,Eb");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_sub);
+}
+
+
+/** Opcode 0x2b. */
+FNIEMOP_DEF(iemOp_sub_Gv_Ev)
+{
+ IEMOP_MNEMONIC("sub Gv,Ev");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_sub);
+}
+
+
+/** Opcode 0x2c. */
+FNIEMOP_DEF(iemOp_sub_Al_Ib)
+{
+ IEMOP_MNEMONIC("sub al,Ib");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_sub);
+}
+
+
+/** Opcode 0x2d. */
+FNIEMOP_DEF(iemOp_sub_eAX_Iz)
+{
+ IEMOP_MNEMONIC("sub rAX,Iz");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_sub);
+}
+
+
+/** Opcode 0x2e. */
+FNIEMOP_DEF(iemOp_seg_CS)
+{
+ pIemCpu->fPrefixes |= IEM_OP_PRF_SEG_CS;
+ pIemCpu->iEffSeg = X86_SREG_CS;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+}
+
+
+/** Opcode 0x2f. */
+FNIEMOP_STUB(iemOp_das);
+
+
+/** Opcode 0x30. */
+FNIEMOP_DEF(iemOp_xor_Eb_Gb)
+{
+ IEMOP_MNEMONIC("xor Eb,Gb");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_xor);
+}
+
+
+/** Opcode 0x31. */
+FNIEMOP_DEF(iemOp_xor_Ev_Gv)
+{
+ IEMOP_MNEMONIC("xor Ev,Gv");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_xor);
+}
+
+
+/** Opcode 0x32. */
+FNIEMOP_DEF(iemOp_xor_Gb_Eb)
+{
+ IEMOP_MNEMONIC("xor Gb,Eb");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_xor);
+}
+
+
+/** Opcode 0x33. */
+FNIEMOP_DEF(iemOp_xor_Gv_Ev)
+{
+ IEMOP_MNEMONIC("xor Gv,Ev");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_xor);
+}
+
+
+/** Opcode 0x34. */
+FNIEMOP_DEF(iemOp_xor_Al_Ib)
+{
+ IEMOP_MNEMONIC("xor al,Ib");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_xor);
+}
+
+
+/** Opcode 0x35. */
+FNIEMOP_DEF(iemOp_xor_eAX_Iz)
+{
+ IEMOP_MNEMONIC("xor rAX,Iz");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_xor);
+}
+
+
+/** Opcode 0x36. */
+FNIEMOP_DEF(iemOp_seg_SS)
+{
+ pIemCpu->fPrefixes |= IEM_OP_PRF_SEG_SS;
+ pIemCpu->iEffSeg = X86_SREG_SS;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+}
+
+
+/** Opcode 0x37. */
+FNIEMOP_STUB(iemOp_aaa);
+
+
+/** Opcode 0x38. */
+FNIEMOP_DEF(iemOp_cmp_Eb_Gb)
+{
+ IEMOP_MNEMONIC("cmp Eb,Gb");
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo do we have to decode the whole instruction first? */
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_cmp);
+}
+
+
+/** Opcode 0x39. */
+FNIEMOP_DEF(iemOp_cmp_Ev_Gv)
+{
+ IEMOP_MNEMONIC("cmp Ev,Gv");
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo do we have to decode the whole instruction first? */
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_cmp);
+}
+
+
+/** Opcode 0x3a. */
+FNIEMOP_DEF(iemOp_cmp_Gb_Eb)
+{
+ IEMOP_MNEMONIC("cmp Gb,Eb");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_cmp);
+}
+
+
+/** Opcode 0x3b. */
+FNIEMOP_DEF(iemOp_cmp_Gv_Ev)
+{
+ IEMOP_MNEMONIC("cmp Gv,Ev");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_cmp);
+}
+
+
+/** Opcode 0x3c. */
+FNIEMOP_DEF(iemOp_cmp_Al_Ib)
+{
+ IEMOP_MNEMONIC("cmp al,Ib");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_cmp);
+}
+
+
+/** Opcode 0x3d. */
+FNIEMOP_DEF(iemOp_cmp_eAX_Iz)
+{
+ IEMOP_MNEMONIC("cmp rAX,Iz");
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_cmp);
+}
+
+
+/** Opcode 0x3e. */
+FNIEMOP_DEF(iemOp_seg_DS)
+{
+ pIemCpu->fPrefixes |= IEM_OP_PRF_SEG_DS;
+ pIemCpu->iEffSeg = X86_SREG_DS;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+}
+
+
+/** Opcode 0x3f. */
+FNIEMOP_STUB(iemOp_aas);
+
+/**
+ * Common 'inc/dec/not/neg register' helper.
+ */
+FNIEMOP_DEF_2(iemOpCommonUnaryGReg, PCIEMOPUNARYSIZES, pImpl, uint8_t, iReg)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(2, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint32_t *, pEFlags, 1);
+ IEM_MC_REF_GREG_U16(pu16Dst, iReg);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU16, pu16Dst, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(2, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t *, pEFlags, 1);
+ IEM_MC_REF_GREG_U32(pu32Dst, iReg);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU32, pu32Dst, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(2, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint32_t *, pEFlags, 1);
+ IEM_MC_REF_GREG_U64(pu64Dst, iReg);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU64, pu64Dst, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x40. */
+FNIEMOP_DEF(iemOp_inc_eAX)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("inc eAX");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xAX);
+}
+
+
+/** Opcode 0x41. */
+FNIEMOP_DEF(iemOp_inc_eCX)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_B;
+ pIemCpu->uRexB = 1 << 3;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("inc eCX");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xCX);
+}
+
+
+/** Opcode 0x42. */
+FNIEMOP_DEF(iemOp_inc_eDX)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_X;
+ pIemCpu->uRexIndex = 1 << 3;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("inc eDX");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xDX);
+}
+
+
+
+/** Opcode 0x43. */
+FNIEMOP_DEF(iemOp_inc_eBX)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X;
+ pIemCpu->uRexB = 1 << 3;
+ pIemCpu->uRexIndex = 1 << 3;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("inc eBX");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xBX);
+}
+
+
+/** Opcode 0x44. */
+FNIEMOP_DEF(iemOp_inc_eSP)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R;
+ pIemCpu->uRexReg = 1 << 3;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("inc eSP");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xSP);
+}
+
+
+/** Opcode 0x45. */
+FNIEMOP_DEF(iemOp_inc_eBP)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B;
+ pIemCpu->uRexReg = 1 << 3;
+ pIemCpu->uRexB = 1 << 3;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("inc eBP");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xBP);
+}
+
+
+/** Opcode 0x46. */
+FNIEMOP_DEF(iemOp_inc_eSI)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_X;
+ pIemCpu->uRexReg = 1 << 3;
+ pIemCpu->uRexIndex = 1 << 3;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("inc eSI");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xSI);
+}
+
+
+/** Opcode 0x47. */
+FNIEMOP_DEF(iemOp_inc_eDI)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X;
+ pIemCpu->uRexReg = 1 << 3;
+ pIemCpu->uRexB = 1 << 3;
+ pIemCpu->uRexIndex = 1 << 3;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("inc eDI");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xDI);
+}
+
+
+/** Opcode 0x48. */
+FNIEMOP_DEF(iemOp_dec_eAX)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_SIZE_REX_W;
+ iemRecalEffOpSize(pIemCpu);
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("dec eAX");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xAX);
+}
+
+
+/** Opcode 0x49. */
+FNIEMOP_DEF(iemOp_dec_eCX)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_B | IEM_OP_PRF_SIZE_REX_W;
+ pIemCpu->uRexB = 1 << 3;
+ iemRecalEffOpSize(pIemCpu);
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("dec eCX");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xCX);
+}
+
+
+/** Opcode 0x4a. */
+FNIEMOP_DEF(iemOp_dec_eDX)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W;
+ pIemCpu->uRexIndex = 1 << 3;
+ iemRecalEffOpSize(pIemCpu);
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("dec eDX");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xDX);
+}
+
+
+/** Opcode 0x4b. */
+FNIEMOP_DEF(iemOp_dec_eBX)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W;
+ pIemCpu->uRexB = 1 << 3;
+ pIemCpu->uRexIndex = 1 << 3;
+ iemRecalEffOpSize(pIemCpu);
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("dec eBX");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xBX);
+}
+
+
+/** Opcode 0x4c. */
+FNIEMOP_DEF(iemOp_dec_eSP)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_SIZE_REX_W;
+ pIemCpu->uRexReg = 1 << 3;
+ iemRecalEffOpSize(pIemCpu);
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("dec eSP");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xSP);
+}
+
+
+/** Opcode 0x4d. */
+FNIEMOP_DEF(iemOp_dec_eBP)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B | IEM_OP_PRF_SIZE_REX_W;
+ pIemCpu->uRexReg = 1 << 3;
+ pIemCpu->uRexB = 1 << 3;
+ iemRecalEffOpSize(pIemCpu);
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("dec eBP");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xBP);
+}
+
+
+/** Opcode 0x4e. */
+FNIEMOP_DEF(iemOp_dec_eSI)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W;
+ pIemCpu->uRexReg = 1 << 3;
+ pIemCpu->uRexIndex = 1 << 3;
+ iemRecalEffOpSize(pIemCpu);
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("dec eSI");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xSI);
+}
+
+
+/** Opcode 0x4f. */
+FNIEMOP_DEF(iemOp_dec_eDI)
+{
+ /*
+ * This is a REX prefix in 64-bit mode.
+ */
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W;
+ pIemCpu->uRexReg = 1 << 3;
+ pIemCpu->uRexB = 1 << 3;
+ pIemCpu->uRexIndex = 1 << 3;
+ iemRecalEffOpSize(pIemCpu);
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+ }
+
+ IEMOP_MNEMONIC("dec eDI");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xDI);
+}
+
+
+/**
+ * Common 'push register' helper.
+ */
+FNIEMOP_DEF_1(iemOpCommonPushGReg, uint8_t, iReg)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ iReg |= pIemCpu->uRexB;
+ pIemCpu->enmDefOpSize = IEMMODE_64BIT;
+ pIemCpu->enmEffOpSize = !(pIemCpu->fPrefixes & IEM_OP_PRF_SIZE_OP) ? IEMMODE_64BIT : IEMMODE_16BIT;
+ }
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint16_t, u16Value);
+ IEM_MC_FETCH_GREG_U16(u16Value, iReg);
+ IEM_MC_PUSH_U16(u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_FETCH_GREG_U32(u32Value, iReg);
+ IEM_MC_PUSH_U32(u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_FETCH_GREG_U64(u64Value, iReg);
+ IEM_MC_PUSH_U64(u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x50. */
+FNIEMOP_DEF(iemOp_push_eAX)
+{
+ IEMOP_MNEMONIC("push rAX");
+ return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xAX);
+}
+
+
+/** Opcode 0x51. */
+FNIEMOP_DEF(iemOp_push_eCX)
+{
+ IEMOP_MNEMONIC("push rCX");
+ return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xCX);
+}
+
+
+/** Opcode 0x52. */
+FNIEMOP_DEF(iemOp_push_eDX)
+{
+ IEMOP_MNEMONIC("push rDX");
+ return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xDX);
+}
+
+
+/** Opcode 0x53. */
+FNIEMOP_DEF(iemOp_push_eBX)
+{
+ IEMOP_MNEMONIC("push rBX");
+ return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xBX);
+}
+
+
+/** Opcode 0x54. */
+FNIEMOP_DEF(iemOp_push_eSP)
+{
+ IEMOP_MNEMONIC("push rSP");
+ return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xSP);
+}
+
+
+/** Opcode 0x55. */
+FNIEMOP_DEF(iemOp_push_eBP)
+{
+ IEMOP_MNEMONIC("push rBP");
+ return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xBP);
+}
+
+
+/** Opcode 0x56. */
+FNIEMOP_DEF(iemOp_push_eSI)
+{
+ IEMOP_MNEMONIC("push rSI");
+ return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xSI);
+}
+
+
+/** Opcode 0x57. */
+FNIEMOP_DEF(iemOp_push_eDI)
+{
+ IEMOP_MNEMONIC("push rDI");
+ return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xDI);
+}
+
+
+/**
+ * Common 'pop register' helper.
+ */
+FNIEMOP_DEF_1(iemOpCommonPopGReg, uint8_t, iReg)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
+ {
+ iReg |= pIemCpu->uRexB;
+ pIemCpu->enmDefOpSize = IEMMODE_64BIT;
+ pIemCpu->enmEffOpSize = !(pIemCpu->fPrefixes & IEM_OP_PRF_SIZE_OP) ? IEMMODE_64BIT : IEMMODE_16BIT;
+ }
+
+/** @todo How does this code handle iReg==X86_GREG_xSP. How does a real CPU
+ * handle it, for that matter (Intel pseudo code hints that the popped
+ * value is incremented by the stack item size.) Test it, both encodings
+ * and all three register sizes. */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint16_t, *pu16Dst);
+ IEM_MC_REF_GREG_U16(pu16Dst, iReg);
+ IEM_MC_POP_U16(pu16Dst);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint32_t, *pu32Dst);
+ IEM_MC_REF_GREG_U32(pu32Dst, iReg);
+ IEM_MC_POP_U32(pu32Dst);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint64_t, *pu64Dst);
+ IEM_MC_REF_GREG_U64(pu64Dst, iReg);
+ IEM_MC_POP_U64(pu64Dst);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x58. */
+FNIEMOP_DEF(iemOp_pop_eAX)
+{
+ IEMOP_MNEMONIC("pop rAX");
+ return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xAX);
+}
+
+
+/** Opcode 0x59. */
+FNIEMOP_DEF(iemOp_pop_eCX)
+{
+ IEMOP_MNEMONIC("pop rCX");
+ return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xCX);
+}
+
+
+/** Opcode 0x5a. */
+FNIEMOP_DEF(iemOp_pop_eDX)
+{
+ IEMOP_MNEMONIC("pop rDX");
+ return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xDX);
+}
+
+
+/** Opcode 0x5b. */
+FNIEMOP_DEF(iemOp_pop_eBX)
+{
+ IEMOP_MNEMONIC("pop rBX");
+ return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xBX);
+}
+
+
+/** Opcode 0x5c. */
+FNIEMOP_DEF(iemOp_pop_eSP)
+{
+ IEMOP_MNEMONIC("pop rSP");
+ return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xSP);
+}
+
+
+/** Opcode 0x5d. */
+FNIEMOP_DEF(iemOp_pop_eBP)
+{
+ IEMOP_MNEMONIC("pop rBP");
+ return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xBP);
+}
+
+
+/** Opcode 0x5e. */
+FNIEMOP_DEF(iemOp_pop_eSI)
+{
+ IEMOP_MNEMONIC("pop rSI");
+ return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xSI);
+}
+
+
+/** Opcode 0x5f. */
+FNIEMOP_DEF(iemOp_pop_eDI)
+{
+ IEMOP_MNEMONIC("pop rDI");
+ return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xDI);
+}
+
+
+/** Opcode 0x60. */
+FNIEMOP_DEF(iemOp_pusha)
+{
+ IEMOP_MNEMONIC("pusha");
+ IEMOP_HLP_NO_64BIT();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_pusha_16);
+ Assert(pIemCpu->enmEffOpSize == IEMMODE_32BIT);
+ return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_pusha_32);
+}
+
+
+/** Opcode 0x61. */
+FNIEMOP_DEF(iemOp_popa)
+{
+ IEMOP_MNEMONIC("popa");
+ IEMOP_HLP_NO_64BIT();
+ if (pIemCpu->enmEffOpSize == IEMMODE_16BIT)
+ return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_popa_16);
+ Assert(pIemCpu->enmEffOpSize == IEMMODE_32BIT);
+ return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_popa_32);
+}
+
+
+/** Opcode 0x62. */
+FNIEMOP_STUB(iemOp_bound_Gv_Ma);
+/** Opcode 0x63. */
+FNIEMOP_STUB(iemOp_arpl_Ew_Gw);
+
+
+/** Opcode 0x64. */
+FNIEMOP_DEF(iemOp_seg_FS)
+{
+ pIemCpu->fPrefixes |= IEM_OP_PRF_SEG_FS;
+ pIemCpu->iEffSeg = X86_SREG_FS;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+}
+
+
+/** Opcode 0x65. */
+FNIEMOP_DEF(iemOp_seg_GS)
+{
+ pIemCpu->fPrefixes |= IEM_OP_PRF_SEG_GS;
+ pIemCpu->iEffSeg = X86_SREG_GS;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+}
+
+
+/** Opcode 0x66. */
+FNIEMOP_DEF(iemOp_op_size)
+{
+ pIemCpu->fPrefixes |= IEM_OP_PRF_SIZE_OP;
+ iemRecalEffOpSize(pIemCpu);
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+}
+
+
+/** Opcode 0x67. */
+FNIEMOP_DEF(iemOp_addr_size)
+{
+ pIemCpu->fPrefixes |= IEM_OP_PRF_SIZE_ADDR;
+ switch (pIemCpu->enmDefAddrMode)
+ {
+ case IEMMODE_16BIT: pIemCpu->enmEffAddrMode = IEMMODE_32BIT; break;
+ case IEMMODE_32BIT: pIemCpu->enmEffAddrMode = IEMMODE_16BIT; break;
+ case IEMMODE_64BIT: pIemCpu->enmEffAddrMode = IEMMODE_32BIT; break;
+ default: AssertFailed();
+ }
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+}
+
+
+/** Opcode 0x68. */
+FNIEMOP_DEF(iemOp_push_Iz)
+{
+ IEMOP_MNEMONIC("push Iz");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_PUSH_U16(u16Imm);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_PUSH_U32(u32Imm);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_PUSH_U64(u64Imm);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0x69. */
+FNIEMOP_DEF(iemOp_imul_Gv_Ev_Iz)
+{
+ IEMOP_MNEMONIC("imul Gv,Ev,Iz"); /* Gv = Ev * Iz; */
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register operand */
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/ u16Imm,1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(uint16_t, u16Tmp);
+
+ IEM_MC_FETCH_GREG_U16(u16Tmp, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_LOCAL(pu16Dst, u16Tmp);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u16, pu16Dst, u16Src, pEFlags);
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Tmp);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory operand */
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/ u16Imm,1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(uint16_t, u16Tmp);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U16(u16Tmp, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_LOCAL(pu16Dst, u16Tmp);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u16, pu16Dst, u16Src, pEFlags);
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Tmp);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register operand */
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/ u32Imm,1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(uint32_t, u32Tmp);
+
+ IEM_MC_FETCH_GREG_U32(u32Tmp, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_LOCAL(pu32Dst, u32Tmp);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u32, pu32Dst, u32Src, pEFlags);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Tmp);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory operand */
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/ u32Imm,1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(uint32_t, u32Tmp);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U32(u32Tmp, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_LOCAL(pu32Dst, u32Tmp);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u32, pu32Dst, u32Src, pEFlags);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Tmp);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register operand */
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/ u64Imm,1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(uint64_t, u64Tmp);
+
+ IEM_MC_FETCH_GREG_U64(u64Tmp, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_LOCAL(pu64Dst, u64Tmp);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u64, pu64Dst, u64Src, pEFlags);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Tmp);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory operand */
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/ u64Imm,1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(uint64_t, u64Tmp);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U64(u64Tmp, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_LOCAL(pu64Dst, u64Tmp);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u64, pu64Dst, u64Src, pEFlags);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Tmp);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+ }
+ }
+ AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+}
+
+
+/** Opcode 0x6a. */
+FNIEMOP_DEF(iemOp_push_Ib)
+{
+ IEMOP_MNEMONIC("push Ib");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0,0);
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_PUSH_U16(i8Imm);
+ break;
+ case IEMMODE_32BIT:
+ IEM_MC_PUSH_U32(i8Imm);
+ break;
+ case IEMMODE_64BIT:
+ IEM_MC_PUSH_U64(i8Imm);
+ break;
+ }
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x6b. */
+FNIEMOP_DEF(iemOp_imul_Gv_Ev_Ib)
+{
+ IEMOP_MNEMONIC("imul Gv,Ev,Ib"); /* Gv = Ev * Iz; */
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register operand */
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/ (int8_t)u8Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(uint16_t, u16Tmp);
+
+ IEM_MC_FETCH_GREG_U16(u16Tmp, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_LOCAL(pu16Dst, u16Tmp);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u16, pu16Dst, u16Src, pEFlags);
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Tmp);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory operand */
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/ (int8_t)u8Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(uint16_t, u16Tmp);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U16(u16Tmp, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_LOCAL(pu16Dst, u16Tmp);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u16, pu16Dst, u16Src, pEFlags);
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Tmp);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register operand */
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/ (int8_t)u8Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(uint32_t, u32Tmp);
+
+ IEM_MC_FETCH_GREG_U32(u32Tmp, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_LOCAL(pu32Dst, u32Tmp);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u32, pu32Dst, u32Src, pEFlags);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Tmp);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory operand */
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/ (int8_t)u8Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(uint32_t, u32Tmp);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U32(u32Tmp, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_LOCAL(pu32Dst, u32Tmp);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u32, pu32Dst, u32Src, pEFlags);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Tmp);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register operand */
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/ (int8_t)u8Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(uint64_t, u64Tmp);
+
+ IEM_MC_FETCH_GREG_U64(u64Tmp, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_LOCAL(pu64Dst, u64Tmp);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u64, pu64Dst, u64Src, pEFlags);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Tmp);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory operand */
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/ (int8_t)u8Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(uint64_t, u64Tmp);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U64(u64Tmp, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_LOCAL(pu64Dst, u64Tmp);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u64, pu64Dst, u64Src, pEFlags);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Tmp);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+ }
+ AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+}
+
+
+/** Opcode 0x6c. */
+FNIEMOP_DEF(iemOp_insb_Yb_DX)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
+ {
+ IEMOP_MNEMONIC("rep ins Yb,DX");
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op8_addr16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op8_addr32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op8_addr64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ IEMOP_MNEMONIC("ins Yb,DX");
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op8_addr16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op8_addr32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op8_addr64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/** Opcode 0x6d. */
+FNIEMOP_DEF(iemOp_inswd_Yv_DX)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ))
+ {
+ IEMOP_MNEMONIC("rep ins Yv,DX");
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op16_addr16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op16_addr32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op16_addr64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ case IEMMODE_64BIT:
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op32_addr16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op32_addr32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op32_addr64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ IEMOP_MNEMONIC("ins Yv,DX");
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op16_addr16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op16_addr32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op16_addr64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ case IEMMODE_64BIT:
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op32_addr16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op32_addr32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op32_addr64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/** Opcode 0x6e. */
+FNIEMOP_DEF(iemOp_outsb_Yb_DX)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
+ {
+ IEMOP_MNEMONIC("rep out DX,Yb");
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op8_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op8_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op8_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ IEMOP_MNEMONIC("out DX,Yb");
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op8_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op8_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op8_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/** Opcode 0x6f. */
+FNIEMOP_DEF(iemOp_outswd_Yv_DX)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ))
+ {
+ IEMOP_MNEMONIC("rep outs DX,Yv");
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op16_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op16_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op16_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ case IEMMODE_64BIT:
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op32_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op32_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op32_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ IEMOP_MNEMONIC("outs DX,Yv");
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op16_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op16_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op16_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ case IEMMODE_64BIT:
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op32_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op32_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op32_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/** Opcode 0x70. */
+FNIEMOP_DEF(iemOp_jo_Jb)
+{
+ IEMOP_MNEMONIC("jo Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x71. */
+FNIEMOP_DEF(iemOp_jno_Jb)
+{
+ IEMOP_MNEMONIC("jno Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+/** Opcode 0x72. */
+FNIEMOP_DEF(iemOp_jc_Jb)
+{
+ IEMOP_MNEMONIC("jc/jnae Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x73. */
+FNIEMOP_DEF(iemOp_jnc_Jb)
+{
+ IEMOP_MNEMONIC("jnc/jnb Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x74. */
+FNIEMOP_DEF(iemOp_je_Jb)
+{
+ IEMOP_MNEMONIC("je/jz Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x75. */
+FNIEMOP_DEF(iemOp_jne_Jb)
+{
+ IEMOP_MNEMONIC("jne/jnz Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x76. */
+FNIEMOP_DEF(iemOp_jbe_Jb)
+{
+ IEMOP_MNEMONIC("jbe/jna Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x77. */
+FNIEMOP_DEF(iemOp_jnbe_Jb)
+{
+ IEMOP_MNEMONIC("jnbe/ja Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x78. */
+FNIEMOP_DEF(iemOp_js_Jb)
+{
+ IEMOP_MNEMONIC("js Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x79. */
+FNIEMOP_DEF(iemOp_jns_Jb)
+{
+ IEMOP_MNEMONIC("jns Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x7a. */
+FNIEMOP_DEF(iemOp_jp_Jb)
+{
+ IEMOP_MNEMONIC("jp Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x7b. */
+FNIEMOP_DEF(iemOp_jnp_Jb)
+{
+ IEMOP_MNEMONIC("jnp Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x7c. */
+FNIEMOP_DEF(iemOp_jl_Jb)
+{
+ IEMOP_MNEMONIC("jl/jnge Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x7d. */
+FNIEMOP_DEF(iemOp_jnl_Jb)
+{
+ IEMOP_MNEMONIC("jnl/jge Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x7e. */
+FNIEMOP_DEF(iemOp_jle_Jb)
+{
+ IEMOP_MNEMONIC("jle/jng Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x7f. */
+FNIEMOP_DEF(iemOp_jnle_Jb)
+{
+ IEMOP_MNEMONIC("jnle/jg Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x80. */
+FNIEMOP_DEF(iemOp_Grp1_Eb_Ib_80)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_MNEMONIC2("add\0or\0\0adc\0sbb\0and\0sub\0xor\0cmp" + ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)*4, "Eb,Ib");
+ PCIEMOPBINSIZES pImpl = g_apIemImplGrp1[(bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK];
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, u8Src, /*=*/ u8Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ uint32_t fAccess;
+ if (pImpl->pfnLockedU8)
+ fAccess = IEM_ACCESS_DATA_RW;
+ else
+ { /* CMP */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ fAccess = IEM_ACCESS_DATA_R;
+ }
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEM_MC_ARG_CONST(uint8_t, u8Src, /*=*/ u8Imm, 1);
+
+ IEM_MC_MEM_MAP(pu8Dst, fAccess, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU8, pu8Dst, u8Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, fAccess);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x81. */
+FNIEMOP_DEF(iemOp_Grp1_Ev_Iz)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_MNEMONIC2("add\0or\0\0adc\0sbb\0and\0sub\0xor\0cmp" + ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)*4, "Ev,Iz");
+ PCIEMOPBINSIZES pImpl = g_apIemImplGrp1[(bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK];
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_CONST(uint16_t, u16Src, /*=*/ u16Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ uint32_t fAccess;
+ if (pImpl->pfnLockedU16)
+ fAccess = IEM_ACCESS_DATA_RW;
+ else
+ { /* CMP, TEST */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ fAccess = IEM_ACCESS_DATA_R;
+ }
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ IEM_MC_ASSIGN(u16Src, u16Imm);
+ IEM_MC_MEM_MAP(pu16Dst, fAccess, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU16, pu16Dst, u16Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, fAccess);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ break;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_CONST(uint32_t, u32Src, /*=*/ u32Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ uint32_t fAccess;
+ if (pImpl->pfnLockedU32)
+ fAccess = IEM_ACCESS_DATA_RW;
+ else
+ { /* CMP, TEST */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ fAccess = IEM_ACCESS_DATA_R;
+ }
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
+ IEM_MC_ASSIGN(u32Src, u32Imm);
+ IEM_MC_MEM_MAP(pu32Dst, fAccess, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU32, pu32Dst, u32Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, fAccess);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ break;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register target */
+ uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ u64Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory target */
+ uint32_t fAccess;
+ if (pImpl->pfnLockedU64)
+ fAccess = IEM_ACCESS_DATA_RW;
+ else
+ { /* CMP */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ fAccess = IEM_ACCESS_DATA_R;
+ }
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
+ IEM_MC_ASSIGN(u64Src, u64Imm);
+ IEM_MC_MEM_MAP(pu64Dst, fAccess, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU64, pu64Dst, u64Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, fAccess);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ break;
+ }
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x82. */
+ FNIEMOP_DEF(iemOp_Grp1_Eb_Ib_82)
+{
+ IEMOP_HLP_NO_64BIT(); /** @todo do we need to decode the whole instruction or is this ok? */
+ return FNIEMOP_CALL(iemOp_Grp1_Eb_Ib_80);
+}
+
+
+/** Opcode 0x83. */
+FNIEMOP_DEF(iemOp_Grp1_Ev_Ib)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_MNEMONIC2("add\0or\0\0adc\0sbb\0and\0sub\0xor\0cmp" + ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)*4, "Ev,Ib");
+ PCIEMOPBINSIZES pImpl = g_apIemImplGrp1[(bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK];
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /*
+ * Register target
+ */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_CONST(uint16_t, u16Src, /*=*/ (int8_t)u8Imm,1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_CONST(uint32_t, u32Src, /*=*/ (int8_t)u8Imm,1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ (int8_t)u8Imm,1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+
+ IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Memory target.
+ */
+ uint32_t fAccess;
+ if (pImpl->pfnLockedU16)
+ fAccess = IEM_ACCESS_DATA_RW;
+ else
+ { /* CMP */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ fAccess = IEM_ACCESS_DATA_R;
+ }
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEM_MC_ASSIGN(u16Src, (int8_t)u8Imm);
+ IEM_MC_MEM_MAP(pu16Dst, fAccess, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU16, pu16Dst, u16Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, fAccess);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEM_MC_ASSIGN(u32Src, (int8_t)u8Imm);
+ IEM_MC_MEM_MAP(pu32Dst, fAccess, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU32, pu32Dst, u32Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, fAccess);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEM_MC_ASSIGN(u64Src, (int8_t)u8Imm);
+ IEM_MC_MEM_MAP(pu64Dst, fAccess, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU64, pu64Dst, u64Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, fAccess);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ }
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x84. */
+FNIEMOP_DEF(iemOp_test_Eb_Gb)
+{
+ IEMOP_MNEMONIC("test Eb,Gb");
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo do we have to decode the whole instruction first? */
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_test);
+}
+
+
+/** Opcode 0x85. */
+FNIEMOP_DEF(iemOp_test_Ev_Gv)
+{
+ IEMOP_MNEMONIC("test Ev,Gv");
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo do we have to decode the whole instruction first? */
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_test);
+}
+
+
+/** Opcode 0x86. */
+FNIEMOP_DEF(iemOp_xchg_Eb_Gb)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_MNEMONIC("xchg Eb,Gb");
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint8_t, uTmp1);
+ IEM_MC_LOCAL(uint8_t, uTmp2);
+
+ IEM_MC_FETCH_GREG_U8(uTmp1, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_GREG_U8(uTmp2, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, uTmp1);
+ IEM_MC_STORE_GREG_U8(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, uTmp2);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /*
+ * We're accessing memory.
+ */
+/** @todo the register must be committed separately! */
+ IEM_MC_BEGIN(2, 2);
+ IEM_MC_ARG(uint8_t *, pu8Mem, 0);
+ IEM_MC_ARG(uint8_t *, pu8Reg, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu8Mem, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_REF_GREG_U8(pu8Reg, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_CALL_VOID_AIMPL_2(iemAImpl_xchg_u8, pu8Mem, pu8Reg);
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Mem, IEM_ACCESS_DATA_RW);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x87. */
+FNIEMOP_DEF(iemOp_xchg_Ev_Gv)
+{
+ IEMOP_MNEMONIC("xchg Ev,Gv");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint16_t, uTmp1);
+ IEM_MC_LOCAL(uint16_t, uTmp2);
+
+ IEM_MC_FETCH_GREG_U16(uTmp1, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_GREG_U16(uTmp2, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U16((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, uTmp1);
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, uTmp2);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint32_t, uTmp1);
+ IEM_MC_LOCAL(uint32_t, uTmp2);
+
+ IEM_MC_FETCH_GREG_U32(uTmp1, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_GREG_U32(uTmp2, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, uTmp1);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, uTmp2);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint64_t, uTmp1);
+ IEM_MC_LOCAL(uint64_t, uTmp2);
+
+ IEM_MC_FETCH_GREG_U64(uTmp1, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_FETCH_GREG_U64(uTmp2, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, uTmp1);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, uTmp2);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /*
+ * We're accessing memory.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+/** @todo the register must be committed separately! */
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(2, 2);
+ IEM_MC_ARG(uint16_t *, pu16Mem, 0);
+ IEM_MC_ARG(uint16_t *, pu16Reg, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu16Mem, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_REF_GREG_U16(pu16Reg, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_CALL_VOID_AIMPL_2(iemAImpl_xchg_u16, pu16Mem, pu16Reg);
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Mem, IEM_ACCESS_DATA_RW);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(2, 2);
+ IEM_MC_ARG(uint32_t *, pu32Mem, 0);
+ IEM_MC_ARG(uint32_t *, pu32Reg, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu32Mem, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_REF_GREG_U32(pu32Reg, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_CALL_VOID_AIMPL_2(iemAImpl_xchg_u32, pu32Mem, pu32Reg);
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Mem, IEM_ACCESS_DATA_RW);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(2, 2);
+ IEM_MC_ARG(uint64_t *, pu64Mem, 0);
+ IEM_MC_ARG(uint64_t *, pu64Reg, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu64Mem, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_REF_GREG_U64(pu64Reg, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_CALL_VOID_AIMPL_2(iemAImpl_xchg_u64, pu64Mem, pu64Reg);
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Mem, IEM_ACCESS_DATA_RW);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/** Opcode 0x88. */
+FNIEMOP_DEF(iemOp_mov_Eb_Gb)
+{
+ IEMOP_MNEMONIC("mov Eb,Gb");
+
+ uint8_t bRm;
+ IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint8_t, u8Value);
+ IEM_MC_FETCH_GREG_U8(u8Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u8Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /*
+ * We're writing a register to memory.
+ */
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint8_t, u8Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U8(u8Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, u8Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+
+}
+
+
+/** Opcode 0x89. */
+FNIEMOP_DEF(iemOp_mov_Ev_Gv)
+{
+ IEMOP_MNEMONIC("mov Ev,Gv");
+
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint16_t, u16Value);
+ IEM_MC_FETCH_GREG_U16(u16Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_STORE_GREG_U16((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_FETCH_GREG_U32(u32Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_FETCH_GREG_U64(u64Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ }
+ else
+ {
+ /*
+ * We're writing a register to memory.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint16_t, u16Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U16(u16Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_STORE_MEM_U16(pIemCpu->iEffSeg, GCPtrEffDst, u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U32(u32Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_STORE_MEM_U32(pIemCpu->iEffSeg, GCPtrEffDst, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U64(u64Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg);
+ IEM_MC_STORE_MEM_U64(pIemCpu->iEffSeg, GCPtrEffDst, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x8a. */
+FNIEMOP_DEF(iemOp_mov_Gb_Eb)
+{
+ IEMOP_MNEMONIC("mov Gb,Eb");
+
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint8_t, u8Value);
+ IEM_MC_FETCH_GREG_U8(u8Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U8(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u8Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /*
+ * We're loading a register from memory.
+ */
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint8_t, u8Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U8(u8Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U8(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u8Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x8b. */
+FNIEMOP_DEF(iemOp_mov_Gv_Ev)
+{
+ IEMOP_MNEMONIC("mov Gv,Ev");
+
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint16_t, u16Value);
+ IEM_MC_FETCH_GREG_U16(u16Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_FETCH_GREG_U32(u32Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_FETCH_GREG_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ }
+ else
+ {
+ /*
+ * We're loading a register from memory.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint16_t, u16Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U16(u16Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U32(u32Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U64(u64Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x8c. */
+FNIEMOP_DEF(iemOp_mov_Ev_Sw)
+{
+ IEMOP_MNEMONIC("mov Ev,Sw");
+
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /*
+ * Check that the destination register exists. The REX.R prefix is ignored.
+ */
+ uint8_t const iSegReg = ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
+ if ( iSegReg > X86_SREG_GS)
+ return IEMOP_RAISE_INVALID_OPCODE(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ * In that case, the operand size is respected and the upper bits are
+ * cleared (starting with some pentium).
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint16_t, u16Value);
+ IEM_MC_FETCH_SREG_U16(u16Value, iSegReg);
+ IEM_MC_STORE_GREG_U16((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint32_t, u32Value);
+ IEM_MC_FETCH_SREG_ZX_U32(u32Value, iSegReg);
+ IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint64_t, u64Value);
+ IEM_MC_FETCH_SREG_ZX_U64(u64Value, iSegReg);
+ IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ }
+ else
+ {
+ /*
+ * We're saving the register to memory. The access is word sized
+ * regardless of operand size prefixes.
+ */
+#if 0 /* not necessary */
+ pIemCpu->enmEffOpSize = pIemCpu->enmDefOpSize = IEMMODE_16BIT;
+#endif
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint16_t, u16Value);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_SREG_U16(u16Value, iSegReg);
+ IEM_MC_STORE_MEM_U16(pIemCpu->iEffSeg, GCPtrEffDst, u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+
+
+/** Opcode 0x8d. */
+FNIEMOP_DEF(iemOp_lea_Gv_M)
+{
+ IEMOP_MNEMONIC("lea Gv,M");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ return IEMOP_RAISE_INVALID_LOCK_PREFIX(); /* no register form */
+
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_LOCAL(uint16_t, u16Cast);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_ASSIGN_TO_SMALLER(u16Cast, GCPtrEffSrc);
+ IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u16Cast);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_LOCAL(uint32_t, u32Cast);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_ASSIGN_TO_SMALLER(u32Cast, GCPtrEffSrc);
+ IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, u32Cast);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg, GCPtrEffSrc);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+ AssertFailedReturn(VERR_INTERNAL_ERROR_5);
+}
+
+
+/** Opcode 0x8e. */
+FNIEMOP_DEF(iemOp_mov_Sw_Ev)
+{
+ IEMOP_MNEMONIC("mov Sw,Ev");
+
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /*
+ * The practical operand size is 16-bit.
+ */
+#if 0 /* not necessary */
+ pIemCpu->enmEffOpSize = pIemCpu->enmDefOpSize = IEMMODE_16BIT;
+#endif
+
+ /*
+ * Check that the destination register exists and can be used with this
+ * instruction. The REX.R prefix is ignored.
+ */
+ uint8_t const iSegReg = ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
+ if ( iSegReg == X86_SREG_CS
+ || iSegReg > X86_SREG_GS)
+ return IEMOP_RAISE_INVALID_OPCODE(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /*
+ * If rm is denoting a register, no more instruction bytes.
+ */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ IEM_MC_BEGIN(2, 0);
+ IEM_MC_ARG_CONST(uint8_t, iSRegArg, iSegReg, 0);
+ IEM_MC_ARG(uint16_t, u16Value, 1);
+ IEM_MC_FETCH_GREG_U16(u16Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_CALL_CIMPL_2(iemCImpl_load_SReg, iSRegArg, u16Value);
+ IEM_MC_END();
+ }
+ else
+ {
+ /*
+ * We're loading the register from memory. The access is word sized
+ * regardless of operand size prefixes.
+ */
+ IEM_MC_BEGIN(2, 1);
+ IEM_MC_ARG_CONST(uint8_t, iSRegArg, iSegReg, 0);
+ IEM_MC_ARG(uint16_t, u16Value, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U16(u16Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_CALL_CIMPL_2(iemCImpl_load_SReg, iSRegArg, u16Value);
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x8f. */
+FNIEMOP_DEF(iemOp_pop_Ev)
+{
+ /* This bugger is rather annoying as it requires rSP to be updated before
+ doing the effective address calculations. Will eventually require a
+ split between the R/M+SIB decoding and the effective address
+ calculation - which is something that is required for any attempt at
+ reusing this code for a recompiler. It may also be good to have if we
+ need to delay #UD exception caused by invalid lock prefixes.
+
+ For now, we'll do a mostly safe interpreter-only implementation here. */
+ /** @todo What's the deal with the 'reg' field and pop Ev? Ignorning it for
+ * now until tests show it's checked.. */
+ IEMOP_MNEMONIC("pop Ev");
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ /* Register access is relatively easy and can share code. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ return FNIEMOP_CALL_1(iemOpCommonPopGReg, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+
+ /*
+ * Memory target.
+ *
+ * Intel says that RSP is incremented before it's used in any effective
+ * address calcuations. This means some serious extra annoyance here since
+ * we decode and caclulate the effective address in one step and like to
+ * delay committing registers till everything is done.
+ *
+ * So, we'll decode and calculate the effective address twice. This will
+ * require some recoding if turned into a recompiler.
+ */
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE(); /* The common code does this differently. */
+
+#ifndef TST_IEM_CHECK_MC
+ /* Calc effective address with modified ESP. */
+ uint8_t const offOpcodeSaved = pIemCpu->offOpcode;
+ RTGCPTR GCPtrEff;
+ VBOXSTRICTRC rcStrict;
+ rcStrict = iemOpHlpCalcRmEffAddr(pIemCpu, bRm, &GCPtrEff);
+ if (rcStrict != VINF_SUCCESS)
+ return rcStrict;
+ pIemCpu->offOpcode = offOpcodeSaved;
+
+ PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+ uint64_t const RspSaved = pCtx->rsp;
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT: iemRegAddToRsp(pCtx, 2); break;
+ case IEMMODE_32BIT: iemRegAddToRsp(pCtx, 4); break;
+ case IEMMODE_64BIT: iemRegAddToRsp(pCtx, 8); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ rcStrict = iemOpHlpCalcRmEffAddr(pIemCpu, bRm, &GCPtrEff);
+ Assert(rcStrict == VINF_SUCCESS);
+ pCtx->rsp = RspSaved;
+
+ /* Perform the operation - this should be CImpl. */
+ RTUINT64U TmpRsp;
+ TmpRsp.u = pCtx->rsp;
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ uint16_t u16Value;
+ rcStrict = iemMemStackPopU16Ex(pIemCpu, &u16Value, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStoreDataU16(pIemCpu, pIemCpu->iEffSeg, GCPtrEff, u16Value);
+ break;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ uint32_t u32Value;
+ rcStrict = iemMemStackPopU32Ex(pIemCpu, &u32Value, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStoreDataU32(pIemCpu, pIemCpu->iEffSeg, GCPtrEff, u32Value);
+ break;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ uint64_t u64Value;
+ rcStrict = iemMemStackPopU64Ex(pIemCpu, &u64Value, &TmpRsp);
+ if (rcStrict == VINF_SUCCESS)
+ rcStrict = iemMemStoreDataU16(pIemCpu, pIemCpu->iEffSeg, GCPtrEff, u64Value);
+ break;
+ }
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ if (rcStrict == VINF_SUCCESS)
+ {
+ pCtx->rsp = TmpRsp.u;
+ iemRegUpdateRip(pIemCpu);
+ }
+ return rcStrict;
+
+#else
+ return VERR_NOT_IMPLEMENTED;
+#endif
+}
+
+
+/**
+ * Common 'xchg reg,rAX' helper.
+ */
+FNIEMOP_DEF_1(iemOpCommonXchgGRegRax, uint8_t, iReg)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ iReg |= pIemCpu->uRexB;
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint16_t, u16Tmp1);
+ IEM_MC_LOCAL(uint16_t, u16Tmp2);
+ IEM_MC_FETCH_GREG_U16(u16Tmp1, iReg);
+ IEM_MC_FETCH_GREG_U16(u16Tmp2, X86_GREG_xAX);
+ IEM_MC_STORE_GREG_U16(X86_GREG_xAX, u16Tmp1);
+ IEM_MC_STORE_GREG_U16(iReg, u16Tmp2);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint32_t, u32Tmp1);
+ IEM_MC_LOCAL(uint32_t, u32Tmp2);
+ IEM_MC_FETCH_GREG_U32(u32Tmp1, iReg);
+ IEM_MC_FETCH_GREG_U32(u32Tmp2, X86_GREG_xAX);
+ IEM_MC_STORE_GREG_U32(X86_GREG_xAX, u32Tmp1);
+ IEM_MC_STORE_GREG_U32(iReg, u32Tmp2);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint64_t, u64Tmp1);
+ IEM_MC_LOCAL(uint64_t, u64Tmp2);
+ IEM_MC_FETCH_GREG_U64(u64Tmp1, iReg);
+ IEM_MC_FETCH_GREG_U64(u64Tmp2, X86_GREG_xAX);
+ IEM_MC_STORE_GREG_U64(X86_GREG_xAX, u64Tmp1);
+ IEM_MC_STORE_GREG_U64(iReg, u64Tmp2);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0x90. */
+FNIEMOP_DEF(iemOp_nop)
+{
+ /* R8/R8D and RAX/EAX can be exchanged. */
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_REX_B)
+ {
+ IEMOP_MNEMONIC("xchg r8,rAX");
+ return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xAX);
+ }
+
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_LOCK)
+ IEMOP_MNEMONIC("pause");
+ else
+ IEMOP_MNEMONIC("nop");
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x91. */
+FNIEMOP_DEF(iemOp_xchg_eCX_eAX)
+{
+ IEMOP_MNEMONIC("xchg rCX,rAX");
+ return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xCX);
+}
+
+
+/** Opcode 0x92. */
+FNIEMOP_DEF(iemOp_xchg_eDX_eAX)
+{
+ IEMOP_MNEMONIC("xchg rDX,rAX");
+ return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xDX);
+}
+
+
+/** Opcode 0x93. */
+FNIEMOP_DEF(iemOp_xchg_eBX_eAX)
+{
+ IEMOP_MNEMONIC("xchg rBX,rAX");
+ return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xBX);
+}
+
+
+/** Opcode 0x94. */
+FNIEMOP_DEF(iemOp_xchg_eSP_eAX)
+{
+ IEMOP_MNEMONIC("xchg rSX,rAX");
+ return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xSP);
+}
+
+
+/** Opcode 0x95. */
+FNIEMOP_DEF(iemOp_xchg_eBP_eAX)
+{
+ IEMOP_MNEMONIC("xchg rBP,rAX");
+ return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xBP);
+}
+
+
+/** Opcode 0x96. */
+FNIEMOP_DEF(iemOp_xchg_eSI_eAX)
+{
+ IEMOP_MNEMONIC("xchg rSI,rAX");
+ return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xSI);
+}
+
+
+/** Opcode 0x97. */
+FNIEMOP_DEF(iemOp_xchg_eDI_eAX)
+{
+ IEMOP_MNEMONIC("xchg rDI,rAX");
+ return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xDI);
+}
+
+
+/** Opcode 0x98. */
+FNIEMOP_STUB(iemOp_cbw);
+
+
+/** Opcode 0x99. */
+FNIEMOP_DEF(iemOp_cwd)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEMOP_MNEMONIC("cwd");
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 15) {
+ IEM_MC_STORE_GREG_U16_CONST(X86_GREG_xDX, UINT16_C(0xffff));
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U16_CONST(X86_GREG_xDX, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEMOP_MNEMONIC("cwq");
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 31) {
+ IEM_MC_STORE_GREG_U32_CONST(X86_GREG_xDX, UINT32_C(0xffffffff));
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U32_CONST(X86_GREG_xDX, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEMOP_MNEMONIC("cqo");
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 63) {
+ IEM_MC_STORE_GREG_U64_CONST(X86_GREG_xDX, UINT64_C(0xffffffffffffffff));
+ } IEM_MC_ELSE() {
+ IEM_MC_STORE_GREG_U64_CONST(X86_GREG_xDX, 0);
+ } IEM_MC_ENDIF();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0x9a. */
+FNIEMOP_STUB(iemOp_call_Ap);
+
+
+/** Opcode 0x9b. (aka fwait) */
+FNIEMOP_DEF(iemOp_wait)
+{
+ IEMOP_MNEMONIC("wait");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
+ IEM_MC_MAYBE_RAISE_FPU_XCPT();
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0x9c. */
+FNIEMOP_DEF(iemOp_pushf_Fv)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_pushf, pIemCpu->enmEffOpSize);
+}
+
+
+/** Opcode 0x9d. */
+FNIEMOP_DEF(iemOp_popf_Fv)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_popf, pIemCpu->enmEffOpSize);
+}
+
+
+/** Opcode 0x9e. */
+FNIEMOP_STUB(iemOp_sahf);
+/** Opcode 0x9f. */
+FNIEMOP_STUB(iemOp_lahf);
+
+/**
+ * Macro used by iemOp_mov_Al_Ob, iemOp_mov_rAX_Ov, iemOp_mov_Ob_AL and
+ * iemOp_mov_Ov_rAX to fetch the moffsXX bit of the opcode and fend of lock
+ * prefixes. Will return on failures.
+ * @param a_GCPtrMemOff The variable to store the offset in.
+ */
+#define IEMOP_FETCH_MOFFS_XX(a_GCPtrMemOff) \
+ do \
+ { \
+ switch (pIemCpu->enmEffAddrMode) \
+ { \
+ case IEMMODE_16BIT: \
+ { \
+ uint16_t u16Off; IEM_OPCODE_GET_NEXT_U16(&u16Off); \
+ (a_GCPtrMemOff) = u16Off; \
+ break; \
+ } \
+ case IEMMODE_32BIT: \
+ { \
+ uint32_t u32Off; IEM_OPCODE_GET_NEXT_U32(&u32Off); \
+ (a_GCPtrMemOff) = u32Off; \
+ break; \
+ } \
+ case IEMMODE_64BIT: \
+ IEM_OPCODE_GET_NEXT_U64(&(a_GCPtrMemOff)); \
+ break; \
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
+ } \
+ IEMOP_HLP_NO_LOCK_PREFIX(); \
+ } while (0)
+
+/** Opcode 0xa0. */
+FNIEMOP_DEF(iemOp_mov_Al_Ob)
+{
+ /*
+ * Get the offset and fend of lock prefixes.
+ */
+ RTGCPTR GCPtrMemOff;
+ IEMOP_FETCH_MOFFS_XX(GCPtrMemOff);
+
+ /*
+ * Fetch AL.
+ */
+ IEM_MC_BEGIN(0,1);
+ IEM_MC_LOCAL(uint8_t, u8Tmp);
+ IEM_MC_FETCH_MEM_U8(u8Tmp, pIemCpu->iEffSeg, GCPtrMemOff);
+ IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xa1. */
+FNIEMOP_DEF(iemOp_mov_rAX_Ov)
+{
+ /*
+ * Get the offset and fend of lock prefixes.
+ */
+ IEMOP_MNEMONIC("mov rAX,Ov");
+ RTGCPTR GCPtrMemOff;
+ IEMOP_FETCH_MOFFS_XX(GCPtrMemOff);
+
+ /*
+ * Fetch rAX.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0,1);
+ IEM_MC_LOCAL(uint16_t, u16Tmp);
+ IEM_MC_FETCH_MEM_U16(u16Tmp, pIemCpu->iEffSeg, GCPtrMemOff);
+ IEM_MC_STORE_GREG_U16(X86_GREG_xAX, u16Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0,1);
+ IEM_MC_LOCAL(uint32_t, u32Tmp);
+ IEM_MC_FETCH_MEM_U32(u32Tmp, pIemCpu->iEffSeg, GCPtrMemOff);
+ IEM_MC_STORE_GREG_U32(X86_GREG_xAX, u32Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0,1);
+ IEM_MC_LOCAL(uint64_t, u64Tmp);
+ IEM_MC_FETCH_MEM_U64(u64Tmp, pIemCpu->iEffSeg, GCPtrMemOff);
+ IEM_MC_STORE_GREG_U64(X86_GREG_xAX, u64Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0xa2. */
+FNIEMOP_DEF(iemOp_mov_Ob_AL)
+{
+ /*
+ * Get the offset and fend of lock prefixes.
+ */
+ RTGCPTR GCPtrMemOff;
+ IEMOP_FETCH_MOFFS_XX(GCPtrMemOff);
+
+ /*
+ * Store AL.
+ */
+ IEM_MC_BEGIN(0,1);
+ IEM_MC_LOCAL(uint8_t, u8Tmp);
+ IEM_MC_FETCH_GREG_U8(u8Tmp, X86_GREG_xAX);
+ IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrMemOff, u8Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xa3. */
+FNIEMOP_DEF(iemOp_mov_Ov_rAX)
+{
+ /*
+ * Get the offset and fend of lock prefixes.
+ */
+ RTGCPTR GCPtrMemOff;
+ IEMOP_FETCH_MOFFS_XX(GCPtrMemOff);
+
+ /*
+ * Store rAX.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0,1);
+ IEM_MC_LOCAL(uint16_t, u16Tmp);
+ IEM_MC_FETCH_GREG_U16(u16Tmp, X86_GREG_xAX);
+ IEM_MC_STORE_MEM_U16(pIemCpu->iEffSeg, GCPtrMemOff, u16Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0,1);
+ IEM_MC_LOCAL(uint32_t, u32Tmp);
+ IEM_MC_FETCH_GREG_U32(u32Tmp, X86_GREG_xAX);
+ IEM_MC_STORE_MEM_U32(pIemCpu->iEffSeg, GCPtrMemOff, u32Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0,1);
+ IEM_MC_LOCAL(uint64_t, u64Tmp);
+ IEM_MC_FETCH_GREG_U64(u64Tmp, X86_GREG_xAX);
+ IEM_MC_STORE_MEM_U64(pIemCpu->iEffSeg, GCPtrMemOff, u64Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+/** Macro used by iemOp_movsb_Xb_Yb and iemOp_movswd_Xv_Yv */
+#define IEM_MOVS_CASE(ValBits, AddrBits) \
+ IEM_MC_BEGIN(0, 2); \
+ IEM_MC_LOCAL(uint##ValBits##_t, uValue); \
+ IEM_MC_LOCAL(RTGCPTR, uAddr); \
+ IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xSI); \
+ IEM_MC_FETCH_MEM_U##ValBits(uValue, pIemCpu->iEffSeg, uAddr); \
+ IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xDI); \
+ IEM_MC_STORE_MEM_U##ValBits(X86_SREG_ES, uAddr, uValue); \
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
+ IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
+ IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
+ } IEM_MC_ELSE() { \
+ IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
+ IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
+ } IEM_MC_ENDIF(); \
+ IEM_MC_ADVANCE_RIP(); \
+ IEM_MC_END();
+
+/** Opcode 0xa4. */
+FNIEMOP_DEF(iemOp_movsb_Xb_Yb)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ /*
+ * Use the C implementation if a repeat prefix is encountered.
+ */
+ if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
+ {
+ IEMOP_MNEMONIC("rep movsb Xb,Yb");
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op8_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op8_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op8_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ IEMOP_MNEMONIC("movsb Xb,Yb");
+
+ /*
+ * Sharing case implementation with movs[wdq] below.
+ */
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_MOVS_CASE(8, 16); break;
+ case IEMMODE_32BIT: IEM_MOVS_CASE(8, 32); break;
+ case IEMMODE_64BIT: IEM_MOVS_CASE(8, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xa5. */
+FNIEMOP_DEF(iemOp_movswd_Xv_Yv)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ /*
+ * Use the C implementation if a repeat prefix is encountered.
+ */
+ if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
+ {
+ IEMOP_MNEMONIC("rep movs Xv,Yv");
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op16_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op16_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op16_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op32_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op32_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op32_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ case IEMMODE_64BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op64_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op64_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ IEMOP_MNEMONIC("movs Xv,Yv");
+
+ /*
+ * Annoying double switch here.
+ * Using ugly macro for implementing the cases, sharing it with movsb.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_MOVS_CASE(16, 16); break;
+ case IEMMODE_32BIT: IEM_MOVS_CASE(16, 32); break;
+ case IEMMODE_64BIT: IEM_MOVS_CASE(16, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_MOVS_CASE(32, 16); break;
+ case IEMMODE_32BIT: IEM_MOVS_CASE(32, 32); break;
+ case IEMMODE_64BIT: IEM_MOVS_CASE(32, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+
+ case IEMMODE_64BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* cannot be encoded */ break;
+ case IEMMODE_32BIT: IEM_MOVS_CASE(64, 32); break;
+ case IEMMODE_64BIT: IEM_MOVS_CASE(64, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ return VINF_SUCCESS;
+}
+
+#undef IEM_MOVS_CASE
+
+/** Macro used by iemOp_cmpsb_Xb_Yb and iemOp_cmpswd_Xv_Yv */
+#define IEM_CMPS_CASE(ValBits, AddrBits) \
+ IEM_MC_BEGIN(3, 3); \
+ IEM_MC_ARG(uint##ValBits##_t *, puValue1, 0); \
+ IEM_MC_ARG(uint##ValBits##_t, uValue2, 1); \
+ IEM_MC_ARG(uint32_t *, pEFlags, 2); \
+ IEM_MC_LOCAL(uint##ValBits##_t, uValue1); \
+ IEM_MC_LOCAL(RTGCPTR, uAddr); \
+ \
+ IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xSI); \
+ IEM_MC_FETCH_MEM_U##ValBits(uValue1, pIemCpu->iEffSeg, uAddr); \
+ IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xDI); \
+ IEM_MC_FETCH_MEM_U##ValBits(uValue2, X86_SREG_ES, uAddr); \
+ IEM_MC_REF_LOCAL(puValue1, uValue1); \
+ IEM_MC_REF_EFLAGS(pEFlags); \
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_cmp_u##ValBits, puValue1, uValue2, pEFlags); \
+ \
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
+ IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
+ IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
+ } IEM_MC_ELSE() { \
+ IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
+ IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
+ } IEM_MC_ENDIF(); \
+ IEM_MC_ADVANCE_RIP(); \
+ IEM_MC_END(); \
+
+/** Opcode 0xa6. */
+FNIEMOP_DEF(iemOp_cmpsb_Xb_Yb)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ /*
+ * Use the C implementation if a repeat prefix is encountered.
+ */
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_REPZ)
+ {
+ IEMOP_MNEMONIC("repe cmps Xb,Yb");
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op8_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op8_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op8_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_REPNZ)
+ {
+ IEMOP_MNEMONIC("repe cmps Xb,Yb");
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op8_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op8_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op8_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ IEMOP_MNEMONIC("cmps Xb,Yb");
+
+ /*
+ * Sharing case implementation with cmps[wdq] below.
+ */
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_CMPS_CASE(8, 16); break;
+ case IEMMODE_32BIT: IEM_CMPS_CASE(8, 32); break;
+ case IEMMODE_64BIT: IEM_CMPS_CASE(8, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ return VINF_SUCCESS;
+
+}
+
+
+/** Opcode 0xa7. */
+FNIEMOP_DEF(iemOp_cmpswd_Xv_Yv)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ /*
+ * Use the C implementation if a repeat prefix is encountered.
+ */
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_REPZ)
+ {
+ IEMOP_MNEMONIC("repe cmps Xv,Yv");
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op16_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op16_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op16_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op32_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op32_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op32_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ case IEMMODE_64BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op64_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op64_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_REPNZ)
+ {
+ IEMOP_MNEMONIC("repne cmps Xv,Yv");
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op16_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op16_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op16_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op32_addr16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op32_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op32_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ case IEMMODE_64BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op64_addr32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op64_addr64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+
+ IEMOP_MNEMONIC("cmps Xv,Yv");
+
+ /*
+ * Annoying double switch here.
+ * Using ugly macro for implementing the cases, sharing it with cmpsb.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_CMPS_CASE(16, 16); break;
+ case IEMMODE_32BIT: IEM_CMPS_CASE(16, 32); break;
+ case IEMMODE_64BIT: IEM_CMPS_CASE(16, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_CMPS_CASE(32, 16); break;
+ case IEMMODE_32BIT: IEM_CMPS_CASE(32, 32); break;
+ case IEMMODE_64BIT: IEM_CMPS_CASE(32, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+
+ case IEMMODE_64BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* cannot be encoded */ break;
+ case IEMMODE_32BIT: IEM_CMPS_CASE(64, 32); break;
+ case IEMMODE_64BIT: IEM_CMPS_CASE(64, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ return VINF_SUCCESS;
+
+}
+
+#undef IEM_CMPS_CASE
+
+/** Opcode 0xa8. */
+FNIEMOP_DEF(iemOp_test_AL_Ib)
+{
+ IEMOP_MNEMONIC("test al,Ib");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_test);
+}
+
+
+/** Opcode 0xa9. */
+FNIEMOP_DEF(iemOp_test_eAX_Iz)
+{
+ IEMOP_MNEMONIC("test rAX,Iz");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+ return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_test);
+}
+
+
+/** Macro used by iemOp_stosb_Yb_AL and iemOp_stoswd_Yv_eAX */
+#define IEM_STOS_CASE(ValBits, AddrBits) \
+ IEM_MC_BEGIN(0, 2); \
+ IEM_MC_LOCAL(uint##ValBits##_t, uValue); \
+ IEM_MC_LOCAL(RTGCPTR, uAddr); \
+ IEM_MC_FETCH_GREG_U##ValBits(uValue, X86_GREG_xAX); \
+ IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xDI); \
+ IEM_MC_STORE_MEM_U##ValBits(X86_SREG_ES, uAddr, uValue); \
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
+ IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
+ } IEM_MC_ELSE() { \
+ IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
+ } IEM_MC_ENDIF(); \
+ IEM_MC_ADVANCE_RIP(); \
+ IEM_MC_END(); \
+
+/** Opcode 0xaa. */
+FNIEMOP_DEF(iemOp_stosb_Yb_AL)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ /*
+ * Use the C implementation if a repeat prefix is encountered.
+ */
+ if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
+ {
+ IEMOP_MNEMONIC("rep stos Yb,al");
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_al_m16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_al_m32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_al_m64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ IEMOP_MNEMONIC("stos Yb,al");
+
+ /*
+ * Sharing case implementation with stos[wdq] below.
+ */
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_STOS_CASE(8, 16); break;
+ case IEMMODE_32BIT: IEM_STOS_CASE(8, 32); break;
+ case IEMMODE_64BIT: IEM_STOS_CASE(8, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xab. */
+FNIEMOP_DEF(iemOp_stoswd_Yv_eAX)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ /*
+ * Use the C implementation if a repeat prefix is encountered.
+ */
+ if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
+ {
+ IEMOP_MNEMONIC("rep stos Yv,rAX");
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_ax_m16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_ax_m32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_ax_m64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_eax_m16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_eax_m32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_eax_m64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ case IEMMODE_64BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_rax_m32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_rax_m64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ IEMOP_MNEMONIC("stos Yv,rAX");
+
+ /*
+ * Annoying double switch here.
+ * Using ugly macro for implementing the cases, sharing it with stosb.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_STOS_CASE(16, 16); break;
+ case IEMMODE_32BIT: IEM_STOS_CASE(16, 32); break;
+ case IEMMODE_64BIT: IEM_STOS_CASE(16, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_STOS_CASE(32, 16); break;
+ case IEMMODE_32BIT: IEM_STOS_CASE(32, 32); break;
+ case IEMMODE_64BIT: IEM_STOS_CASE(32, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+
+ case IEMMODE_64BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* cannot be encoded */ break;
+ case IEMMODE_32BIT: IEM_STOS_CASE(64, 32); break;
+ case IEMMODE_64BIT: IEM_STOS_CASE(64, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ return VINF_SUCCESS;
+}
+
+#undef IEM_STOS_CASE
+
+/** Macro used by iemOp_lodsb_AL_Xb and iemOp_lodswd_eAX_Xv */
+#define IEM_LODS_CASE(ValBits, AddrBits) \
+ IEM_MC_BEGIN(0, 2); \
+ IEM_MC_LOCAL(uint##ValBits##_t, uValue); \
+ IEM_MC_LOCAL(RTGCPTR, uAddr); \
+ IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xSI); \
+ IEM_MC_FETCH_MEM_U##ValBits(uValue, pIemCpu->iEffSeg, uAddr); \
+ IEM_MC_STORE_GREG_U##ValBits(X86_GREG_xAX, uValue); \
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
+ IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
+ } IEM_MC_ELSE() { \
+ IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
+ } IEM_MC_ENDIF(); \
+ IEM_MC_ADVANCE_RIP(); \
+ IEM_MC_END();
+
+/** Opcode 0xac. */
+FNIEMOP_DEF(iemOp_lodsb_AL_Xb)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ /*
+ * Use the C implementation if a repeat prefix is encountered.
+ */
+ if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
+ {
+ IEMOP_MNEMONIC("rep lodsb al,Xb");
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_al_m16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_al_m32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_al_m64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ IEMOP_MNEMONIC("lodsb al,Xb");
+
+ /*
+ * Sharing case implementation with stos[wdq] below.
+ */
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_LODS_CASE(8, 16); break;
+ case IEMMODE_32BIT: IEM_LODS_CASE(8, 32); break;
+ case IEMMODE_64BIT: IEM_LODS_CASE(8, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xad. */
+FNIEMOP_DEF(iemOp_lodswd_eAX_Xv)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ /*
+ * Use the C implementation if a repeat prefix is encountered.
+ */
+ if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
+ {
+ IEMOP_MNEMONIC("rep lods rAX,Xv");
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_ax_m16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_ax_m32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_ax_m64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_eax_m16, pIemCpu->iEffSeg);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_eax_m32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_eax_m64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ case IEMMODE_64BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_rax_m32, pIemCpu->iEffSeg);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_rax_m64, pIemCpu->iEffSeg);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ IEMOP_MNEMONIC("lods rAX,Xv");
+
+ /*
+ * Annoying double switch here.
+ * Using ugly macro for implementing the cases, sharing it with lodsb.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_LODS_CASE(16, 16); break;
+ case IEMMODE_32BIT: IEM_LODS_CASE(16, 32); break;
+ case IEMMODE_64BIT: IEM_LODS_CASE(16, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_LODS_CASE(32, 16); break;
+ case IEMMODE_32BIT: IEM_LODS_CASE(32, 32); break;
+ case IEMMODE_64BIT: IEM_LODS_CASE(32, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+
+ case IEMMODE_64BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* cannot be encoded */ break;
+ case IEMMODE_32BIT: IEM_LODS_CASE(64, 32); break;
+ case IEMMODE_64BIT: IEM_LODS_CASE(64, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ return VINF_SUCCESS;
+}
+
+#undef IEM_LODS_CASE
+
+/** Macro used by iemOp_scasb_AL_Xb and iemOp_scaswd_eAX_Xv */
+#define IEM_SCAS_CASE(ValBits, AddrBits) \
+ IEM_MC_BEGIN(3, 2); \
+ IEM_MC_ARG(uint##ValBits##_t *, puRax, 0); \
+ IEM_MC_ARG(uint##ValBits##_t, uValue, 1); \
+ IEM_MC_ARG(uint32_t *, pEFlags, 2); \
+ IEM_MC_LOCAL(RTGCPTR, uAddr); \
+ \
+ IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xDI); \
+ IEM_MC_FETCH_MEM_U##ValBits(uValue, X86_SREG_ES, uAddr); \
+ IEM_MC_REF_GREG_U##ValBits(puRax, X86_GREG_xAX); \
+ IEM_MC_REF_EFLAGS(pEFlags); \
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_cmp_u##ValBits, puRax, uValue, pEFlags); \
+ \
+ IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
+ IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
+ } IEM_MC_ELSE() { \
+ IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
+ } IEM_MC_ENDIF(); \
+ IEM_MC_ADVANCE_RIP(); \
+ IEM_MC_END();
+
+/** Opcode 0xae. */
+FNIEMOP_DEF(iemOp_scasb_AL_Xb)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ /*
+ * Use the C implementation if a repeat prefix is encountered.
+ */
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_REPZ)
+ {
+ IEMOP_MNEMONIC("repe scasb al,Xb");
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_al_m16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_al_m32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_al_m64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_REPNZ)
+ {
+ IEMOP_MNEMONIC("repne scasb al,Xb");
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_al_m16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_al_m32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_al_m64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ IEMOP_MNEMONIC("scasb al,Xb");
+
+ /*
+ * Sharing case implementation with stos[wdq] below.
+ */
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_SCAS_CASE(8, 16); break;
+ case IEMMODE_32BIT: IEM_SCAS_CASE(8, 32); break;
+ case IEMMODE_64BIT: IEM_SCAS_CASE(8, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xaf. */
+FNIEMOP_DEF(iemOp_scaswd_eAX_Xv)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ /*
+ * Use the C implementation if a repeat prefix is encountered.
+ */
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_REPZ)
+ {
+ IEMOP_MNEMONIC("repe scas rAX,Xv");
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ case IEMMODE_64BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_3); /** @todo It's this wrong, we can do 16-bit addressing in 64-bit mode, but not 32-bit. right? */
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_rax_m32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_rax_m64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ if (pIemCpu->fPrefixes & IEM_OP_PRF_REPNZ)
+ {
+ IEMOP_MNEMONIC("repne scas rAX,Xv");
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m16);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ case IEMMODE_64BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+ case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_rax_m32);
+ case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_rax_m64);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ IEMOP_MNEMONIC("scas rAX,Xv");
+
+ /*
+ * Annoying double switch here.
+ * Using ugly macro for implementing the cases, sharing it with scasb.
+ */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_SCAS_CASE(16, 16); break;
+ case IEMMODE_32BIT: IEM_SCAS_CASE(16, 32); break;
+ case IEMMODE_64BIT: IEM_SCAS_CASE(16, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+
+ case IEMMODE_32BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: IEM_SCAS_CASE(32, 16); break;
+ case IEMMODE_32BIT: IEM_SCAS_CASE(32, 32); break;
+ case IEMMODE_64BIT: IEM_SCAS_CASE(32, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+
+ case IEMMODE_64BIT:
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* cannot be encoded */ break;
+ case IEMMODE_32BIT: IEM_SCAS_CASE(64, 32); break;
+ case IEMMODE_64BIT: IEM_SCAS_CASE(64, 64); break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ break;
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ return VINF_SUCCESS;
+}
+
+#undef IEM_SCAS_CASE
+
+/**
+ * Common 'mov r8, imm8' helper.
+ */
+FNIEMOP_DEF_1(iemOpCommonMov_r8_Ib, uint8_t, iReg)
+{
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL_CONST(uint8_t, u8Value,/*=*/ u8Imm);
+ IEM_MC_STORE_GREG_U8(iReg, u8Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xb0. */
+FNIEMOP_DEF(iemOp_mov_AL_Ib)
+{
+ IEMOP_MNEMONIC("mov AL,Ib");
+ return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xAX);
+}
+
+
+/** Opcode 0xb1. */
+FNIEMOP_DEF(iemOp_CL_Ib)
+{
+ IEMOP_MNEMONIC("mov CL,Ib");
+ return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xCX);
+}
+
+
+/** Opcode 0xb2. */
+FNIEMOP_DEF(iemOp_DL_Ib)
+{
+ IEMOP_MNEMONIC("mov DL,Ib");
+ return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xDX);
+}
+
+
+/** Opcode 0xb3. */
+FNIEMOP_DEF(iemOp_BL_Ib)
+{
+ IEMOP_MNEMONIC("mov BL,Ib");
+ return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xBX);
+}
+
+
+/** Opcode 0xb4. */
+FNIEMOP_DEF(iemOp_mov_AH_Ib)
+{
+ IEMOP_MNEMONIC("mov AH,Ib");
+ return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xSP);
+}
+
+
+/** Opcode 0xb5. */
+FNIEMOP_DEF(iemOp_CH_Ib)
+{
+ IEMOP_MNEMONIC("mov CH,Ib");
+ return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xBP);
+}
+
+
+/** Opcode 0xb6. */
+FNIEMOP_DEF(iemOp_DH_Ib)
+{
+ IEMOP_MNEMONIC("mov DH,Ib");
+ return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xSI);
+}
+
+
+/** Opcode 0xb7. */
+FNIEMOP_DEF(iemOp_BH_Ib)
+{
+ IEMOP_MNEMONIC("mov BH,Ib");
+ return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xDI);
+}
+
+
+/**
+ * Common 'mov regX,immX' helper.
+ */
+FNIEMOP_DEF_1(iemOpCommonMov_Rv_Iv, uint8_t, iReg)
+{
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL_CONST(uint16_t, u16Value,/*=*/ u16Imm);
+ IEM_MC_STORE_GREG_U16(iReg, u16Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL_CONST(uint32_t, u32Value,/*=*/ u32Imm);
+ IEM_MC_STORE_GREG_U32(iReg, u32Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ case IEMMODE_64BIT:
+ {
+ uint64_t u64Imm; IEM_OPCODE_GET_NEXT_U64(&u64Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL_CONST(uint64_t, u64Value,/*=*/ u64Imm);
+ IEM_MC_STORE_GREG_U64(iReg, u64Value);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ break;
+ }
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xb8. */
+FNIEMOP_DEF(iemOp_eAX_Iv)
+{
+ IEMOP_MNEMONIC("mov rAX,IV");
+ return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xAX);
+}
+
+
+/** Opcode 0xb9. */
+FNIEMOP_DEF(iemOp_eCX_Iv)
+{
+ IEMOP_MNEMONIC("mov rCX,IV");
+ return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xCX);
+}
+
+
+/** Opcode 0xba. */
+FNIEMOP_DEF(iemOp_eDX_Iv)
+{
+ IEMOP_MNEMONIC("mov rDX,IV");
+ return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xDX);
+}
+
+
+/** Opcode 0xbb. */
+FNIEMOP_DEF(iemOp_eBX_Iv)
+{
+ IEMOP_MNEMONIC("mov rBX,IV");
+ return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xBX);
+}
+
+
+/** Opcode 0xbc. */
+FNIEMOP_DEF(iemOp_eSP_Iv)
+{
+ IEMOP_MNEMONIC("mov rSP,IV");
+ return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xSP);
+}
+
+
+/** Opcode 0xbd. */
+FNIEMOP_DEF(iemOp_eBP_Iv)
+{
+ IEMOP_MNEMONIC("mov rBP,IV");
+ return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xBP);
+}
+
+
+/** Opcode 0xbe. */
+FNIEMOP_DEF(iemOp_eSI_Iv)
+{
+ IEMOP_MNEMONIC("mov rSI,IV");
+ return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xSI);
+}
+
+
+/** Opcode 0xbf. */
+FNIEMOP_DEF(iemOp_eDI_Iv)
+{
+ IEMOP_MNEMONIC("mov rDI,IV");
+ return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xDI);
+}
+
+
+/** Opcode 0xc0. */
+FNIEMOP_DEF(iemOp_Grp2_Eb_Ib)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ PCIEMOPSHIFTSIZES pImpl;
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0: pImpl = &g_iemAImpl_rol; IEMOP_MNEMONIC("rol Eb,Ib"); break;
+ case 1: pImpl = &g_iemAImpl_ror; IEMOP_MNEMONIC("ror Eb,Ib"); break;
+ case 2: pImpl = &g_iemAImpl_rcl; IEMOP_MNEMONIC("rcl Eb,Ib"); break;
+ case 3: pImpl = &g_iemAImpl_rcr; IEMOP_MNEMONIC("rcr Eb,Ib"); break;
+ case 4: pImpl = &g_iemAImpl_shl; IEMOP_MNEMONIC("shl Eb,Ib"); break;
+ case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC("shr Eb,Ib"); break;
+ case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC("sar Eb,Ib"); break;
+ case 6: return IEMOP_RAISE_INVALID_LOCK_PREFIX();
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe stupid */
+ }
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register */
+ uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory */
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG(uint8_t, cShiftArg, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
+ IEM_MC_ASSIGN(cShiftArg, cShift);
+ IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xc1. */
+FNIEMOP_DEF(iemOp_Grp2_Ev_Ib)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ PCIEMOPSHIFTSIZES pImpl;
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0: pImpl = &g_iemAImpl_rol; IEMOP_MNEMONIC("rol Ev,Ib"); break;
+ case 1: pImpl = &g_iemAImpl_ror; IEMOP_MNEMONIC("ror Ev,Ib"); break;
+ case 2: pImpl = &g_iemAImpl_rcl; IEMOP_MNEMONIC("rcl Ev,Ib"); break;
+ case 3: pImpl = &g_iemAImpl_rcr; IEMOP_MNEMONIC("rcr Ev,Ib"); break;
+ case 4: pImpl = &g_iemAImpl_shl; IEMOP_MNEMONIC("shl Ev,Ib"); break;
+ case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC("shr Ev,Ib"); break;
+ case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC("sar Ev,Ib"); break;
+ case 6: return IEMOP_RAISE_INVALID_LOCK_PREFIX();
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe stupid */
+ }
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register */
+ uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /* memory */
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint8_t, cShiftArg, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
+ IEM_MC_ASSIGN(cShiftArg, cShift);
+ IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint8_t, cShiftArg, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
+ IEM_MC_ASSIGN(cShiftArg, cShift);
+ IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint8_t, cShiftArg, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
+ IEM_MC_ASSIGN(cShiftArg, cShift);
+ IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/** Opcode 0xc2. */
+FNIEMOP_DEF(iemOp_retn_Iw)
+{
+ IEMOP_MNEMONIC("retn Iw");
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_retn, pIemCpu->enmEffOpSize, u16Imm);
+}
+
+
+/** Opcode 0xc3. */
+FNIEMOP_DEF(iemOp_retn)
+{
+ IEMOP_MNEMONIC("retn");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_retn, pIemCpu->enmEffOpSize, 0);
+}
+
+
+/** Opcode 0xc4. */
+FNIEMOP_DEF(iemOp_les_Gv_Mp)
+{
+ IEMOP_MNEMONIC("les Gv,Mp");
+ return FNIEMOP_CALL_1(iemOpCommonLoadSRegAndGreg, X86_SREG_ES);
+}
+
+
+/** Opcode 0xc5. */
+FNIEMOP_DEF(iemOp_lds_Gv_Mp)
+{
+ IEMOP_MNEMONIC("lds Gv,Mp");
+ return FNIEMOP_CALL_1(iemOpCommonLoadSRegAndGreg, X86_SREG_DS);
+}
+
+
+/** Opcode 0xc6. */
+FNIEMOP_DEF(iemOp_Grp11_Eb_Ib)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+ if ((bRm & X86_MODRM_REG_MASK) != (0 << X86_MODRM_REG_SHIFT)) /* only mov Eb,Ib in this group. */
+ return IEMOP_RAISE_INVALID_LOCK_PREFIX();
+ IEMOP_MNEMONIC("mov Eb,Ib");
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register access */
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u8Imm);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory access. */
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, u8Imm);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xc7. */
+FNIEMOP_DEF(iemOp_Grp11_Ev_Iz)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+ if ((bRm & X86_MODRM_REG_MASK) != (0 << X86_MODRM_REG_SHIFT)) /* only mov Eb,Ib in this group. */
+ return IEMOP_RAISE_INVALID_LOCK_PREFIX();
+ IEMOP_MNEMONIC("mov Ev,Iz");
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register access */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 0);
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ IEM_MC_STORE_GREG_U16((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u16Imm);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 0);
+ uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
+ IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u32Imm);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 0);
+ uint64_t u64Imm; IEM_OPCODE_GET_NEXT_U64(&u64Imm);
+ IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u64Imm);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /* memory access. */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ IEM_MC_STORE_MEM_U16(pIemCpu->iEffSeg, GCPtrEffDst, u16Imm);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
+ IEM_MC_STORE_MEM_U32(pIemCpu->iEffSeg, GCPtrEffDst, u32Imm);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint64_t u64Imm; IEM_OPCODE_GET_NEXT_U64(&u64Imm);
+ IEM_MC_STORE_MEM_U64(pIemCpu->iEffSeg, GCPtrEffDst, u64Imm);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+
+
+/** Opcode 0xc8. */
+FNIEMOP_STUB(iemOp_enter_Iw_Ib);
+
+
+/** Opcode 0xc9. */
+FNIEMOP_DEF(iemOp_leave)
+{
+ IEMOP_MNEMONIC("retn");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_leave, pIemCpu->enmEffOpSize);
+}
+
+
+/** Opcode 0xca. */
+FNIEMOP_DEF(iemOp_retf_Iw)
+{
+ IEMOP_MNEMONIC("retf Iw");
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_retf, pIemCpu->enmEffOpSize, u16Imm);
+}
+
+
+/** Opcode 0xcb. */
+FNIEMOP_DEF(iemOp_retf)
+{
+ IEMOP_MNEMONIC("retf");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_retf, pIemCpu->enmEffOpSize, 0);
+}
+
+
+/** Opcode 0xcc. */
+FNIEMOP_DEF(iemOp_int_3)
+{
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_int, X86_XCPT_BP, true /*fIsBpInstr*/);
+}
+
+
+/** Opcode 0xcd. */
+FNIEMOP_DEF(iemOp_int_Ib)
+{
+ uint8_t u8Int; IEM_OPCODE_GET_NEXT_U8(&u8Int);
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_int, u8Int, false /*fIsBpInstr*/);
+}
+
+
+/** Opcode 0xce. */
+FNIEMOP_DEF(iemOp_into)
+{
+ IEM_MC_BEGIN(2, 0);
+ IEM_MC_ARG_CONST(uint8_t, u8Int, /*=*/ X86_XCPT_OF, 0);
+ IEM_MC_ARG_CONST(bool, fIsBpInstr, /*=*/ false, 1);
+ IEM_MC_CALL_CIMPL_2(iemCImpl_int, u8Int, fIsBpInstr);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xcf. */
+FNIEMOP_DEF(iemOp_iret)
+{
+ IEMOP_MNEMONIC("iret");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_iret, pIemCpu->enmEffOpSize);
+}
+
+
+/** Opcode 0xd0. */
+FNIEMOP_DEF(iemOp_Grp2_Eb_1)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ PCIEMOPSHIFTSIZES pImpl;
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0: pImpl = &g_iemAImpl_rol; IEMOP_MNEMONIC("rol Eb,1"); break;
+ case 1: pImpl = &g_iemAImpl_ror; IEMOP_MNEMONIC("ror Eb,1"); break;
+ case 2: pImpl = &g_iemAImpl_rcl; IEMOP_MNEMONIC("rcl Eb,1"); break;
+ case 3: pImpl = &g_iemAImpl_rcr; IEMOP_MNEMONIC("rcr Eb,1"); break;
+ case 4: pImpl = &g_iemAImpl_shl; IEMOP_MNEMONIC("shl Eb,1"); break;
+ case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC("shr Eb,1"); break;
+ case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC("sar Eb,1"); break;
+ case 6: return IEMOP_RAISE_INVALID_LOCK_PREFIX();
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe, well... */
+ }
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=*/1, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory */
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=*/1, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+
+/** Opcode 0xd1. */
+FNIEMOP_DEF(iemOp_Grp2_Ev_1)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ PCIEMOPSHIFTSIZES pImpl;
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0: pImpl = &g_iemAImpl_rol; IEMOP_MNEMONIC("rol Ev,1"); break;
+ case 1: pImpl = &g_iemAImpl_ror; IEMOP_MNEMONIC("ror Ev,1"); break;
+ case 2: pImpl = &g_iemAImpl_rcl; IEMOP_MNEMONIC("rcl Ev,1"); break;
+ case 3: pImpl = &g_iemAImpl_rcr; IEMOP_MNEMONIC("rcr Ev,1"); break;
+ case 4: pImpl = &g_iemAImpl_shl; IEMOP_MNEMONIC("shl Ev,1"); break;
+ case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC("shr Ev,1"); break;
+ case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC("sar Ev,1"); break;
+ case 6: return IEMOP_RAISE_INVALID_LOCK_PREFIX();
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe, well... */
+ }
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /* memory */
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/** Opcode 0xd2. */
+FNIEMOP_DEF(iemOp_Grp2_Eb_CL)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ PCIEMOPSHIFTSIZES pImpl;
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0: pImpl = &g_iemAImpl_rol; IEMOP_MNEMONIC("rol Eb,CL"); break;
+ case 1: pImpl = &g_iemAImpl_ror; IEMOP_MNEMONIC("ror Eb,CL"); break;
+ case 2: pImpl = &g_iemAImpl_rcl; IEMOP_MNEMONIC("rcl Eb,CL"); break;
+ case 3: pImpl = &g_iemAImpl_rcr; IEMOP_MNEMONIC("rcr Eb,CL"); break;
+ case 4: pImpl = &g_iemAImpl_shl; IEMOP_MNEMONIC("shl Eb,CL"); break;
+ case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC("shr Eb,CL"); break;
+ case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC("sar Eb,CL"); break;
+ case 6: return IEMOP_RAISE_INVALID_LOCK_PREFIX();
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc, grr. */
+ }
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG(uint8_t, cShiftArg, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory */
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG(uint8_t, cShiftArg, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xd3. */
+FNIEMOP_DEF(iemOp_Grp2_Ev_CL)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ PCIEMOPSHIFTSIZES pImpl;
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0: pImpl = &g_iemAImpl_rol; IEMOP_MNEMONIC("rol Ev,CL"); break;
+ case 1: pImpl = &g_iemAImpl_ror; IEMOP_MNEMONIC("ror Ev,CL"); break;
+ case 2: pImpl = &g_iemAImpl_rcl; IEMOP_MNEMONIC("rcl Ev,CL"); break;
+ case 3: pImpl = &g_iemAImpl_rcr; IEMOP_MNEMONIC("rcr Ev,CL"); break;
+ case 4: pImpl = &g_iemAImpl_shl; IEMOP_MNEMONIC("shl Ev,CL"); break;
+ case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC("shr Ev,CL"); break;
+ case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC("sar Ev,CL"); break;
+ case 6: return IEMOP_RAISE_INVALID_OPCODE();
+ IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe stupid */
+ }
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint8_t, cShiftArg, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint8_t, cShiftArg, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint8_t, cShiftArg, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /* memory */
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint8_t, cShiftArg, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint8_t, cShiftArg, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint8_t, cShiftArg, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
+ IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+/** Opcode 0xd4. */
+FNIEMOP_STUB(iemOp_aam_Ib);
+
+
+/** Opcode 0xd5. */
+FNIEMOP_DEF(iemOp_aad_Ib)
+{
+ IEMOP_MNEMONIC("aad Ib");
+ uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_NO_64BIT();
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_aad, bImm);
+}
+
+
+/** Opcode 0xd7. */
+FNIEMOP_DEF(iemOp_xlat)
+{
+ IEMOP_MNEMONIC("xlat");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(2, 0);
+ IEM_MC_LOCAL(uint8_t, u8Tmp);
+ IEM_MC_LOCAL(uint16_t, u16Addr);
+ IEM_MC_FETCH_GREG_U8_ZX_U16(u16Addr, X86_GREG_xAX);
+ IEM_MC_ADD_GREG_U16_TO_LOCAL(u16Addr, X86_GREG_xBX);
+ IEM_MC_FETCH_MEM16_U8(u8Tmp, pIemCpu->iEffSeg, u16Addr);
+ IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(2, 0);
+ IEM_MC_LOCAL(uint8_t, u8Tmp);
+ IEM_MC_LOCAL(uint32_t, u32Addr);
+ IEM_MC_FETCH_GREG_U8_ZX_U32(u32Addr, X86_GREG_xAX);
+ IEM_MC_ADD_GREG_U32_TO_LOCAL(u32Addr, X86_GREG_xBX);
+ IEM_MC_FETCH_MEM32_U8(u8Tmp, pIemCpu->iEffSeg, u32Addr);
+ IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(2, 0);
+ IEM_MC_LOCAL(uint8_t, u8Tmp);
+ IEM_MC_LOCAL(uint64_t, u64Addr);
+ IEM_MC_FETCH_GREG_U8_ZX_U64(u64Addr, X86_GREG_xAX);
+ IEM_MC_ADD_GREG_U64_TO_LOCAL(u64Addr, X86_GREG_xBX);
+ IEM_MC_FETCH_MEM_U8(u8Tmp, pIemCpu->iEffSeg, u64Addr);
+ IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0xd8. */
+FNIEMOP_STUB(iemOp_EscF0);
+/** Opcode 0xd9. */
+FNIEMOP_STUB(iemOp_EscF1);
+/** Opcode 0xda. */
+FNIEMOP_STUB(iemOp_EscF2);
+
+
+/** Opcode 0xdb /0. */
+FNIEMOP_STUB_1(iemOp_fild_dw, uint8_t, bRm);
+/** Opcode 0xdb /1. */
+FNIEMOP_STUB_1(iemOp_fisttp_dw, uint8_t, bRm);
+/** Opcode 0xdb /2. */
+FNIEMOP_STUB_1(iemOp_fist_dw, uint8_t, bRm);
+/** Opcode 0xdb /3. */
+FNIEMOP_STUB_1(iemOp_fistp_dw, uint8_t, bRm);
+/** Opcode 0xdb /5. */
+FNIEMOP_STUB_1(iemOp_fld_xr, uint8_t, bRm);
+/** Opcode 0xdb /7. */
+FNIEMOP_STUB_1(iemOp_fstp_xr, uint8_t, bRm);
+
+
+/** Opcode 0xdb 0xe0. */
+FNIEMOP_DEF(iemOp_fneni)
+{
+ IEMOP_MNEMONIC("fneni (8087/ign)");
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xdb 0xe1. */
+FNIEMOP_DEF(iemOp_fndisi)
+{
+ IEMOP_MNEMONIC("fndisi (8087/ign)");
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xdb 0xe2. */
+FNIEMOP_STUB(iemOp_fnclex);
+
+
+/** Opcode 0xdb 0xe3. */
+FNIEMOP_DEF(iemOp_fninit)
+{
+ IEMOP_MNEMONIC("fninit");
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_finit, false /*fCheckXcpts*/);
+}
+
+
+/** Opcode 0xdb 0xe4. */
+FNIEMOP_DEF(iemOp_fnsetpm)
+{
+ IEMOP_MNEMONIC("fnsetpm (80287/ign)"); /* set protected mode on fpu. */
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xdb 0xe5. */
+FNIEMOP_DEF(iemOp_frstpm)
+{
+ IEMOP_MNEMONIC("frstpm (80287XL/ign)"); /* reset pm, back to real mode. */
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xdb. */
+FNIEMOP_DEF(iemOp_EscF3)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ switch (bRm & 0xf8)
+ {
+ case 0xc0: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fcmovnb
+ case 0xc8: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fcmovne
+ case 0xd0: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fcmovnbe
+ case 0xd8: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fcmovnu
+ case 0xe0:
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ switch (bRm)
+ {
+ case 0xe0: return FNIEMOP_CALL(iemOp_fneni);
+ case 0xe1: return FNIEMOP_CALL(iemOp_fndisi);
+ case 0xe2: return FNIEMOP_CALL(iemOp_fnclex);
+ case 0xe3: return FNIEMOP_CALL(iemOp_fninit);
+ case 0xe4: return FNIEMOP_CALL(iemOp_fnsetpm);
+ case 0xe5: return FNIEMOP_CALL(iemOp_frstpm);
+ default: return IEMOP_RAISE_INVALID_OPCODE();
+ }
+ break;
+ case 0xe8: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fucomi
+ case 0xf0: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fcomi
+ case 0xf8: return IEMOP_RAISE_INVALID_OPCODE();
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0: return FNIEMOP_CALL_1(iemOp_fild_dw, bRm);
+ case 1: return FNIEMOP_CALL_1(iemOp_fisttp_dw,bRm);
+ case 2: return FNIEMOP_CALL_1(iemOp_fist_dw, bRm);
+ case 3: return FNIEMOP_CALL_1(iemOp_fistp_dw, bRm);
+ case 4: return IEMOP_RAISE_INVALID_OPCODE();
+ case 5: return FNIEMOP_CALL_1(iemOp_fld_xr, bRm);
+ case 6: return IEMOP_RAISE_INVALID_OPCODE();
+ case 7: return FNIEMOP_CALL_1(iemOp_fstp_xr, bRm);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+/** Opcode 0xdc. */
+FNIEMOP_STUB(iemOp_EscF4);
+/** Opcode 0xdd. */
+FNIEMOP_STUB(iemOp_EscF5);
+
+/** Opcode 0xde 0xd9. */
+FNIEMOP_STUB(iemOp_fcompp);
+
+/** Opcode 0xde. */
+FNIEMOP_DEF(iemOp_EscF6)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ switch (bRm & 0xf8)
+ {
+ case 0xc0: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fiaddp
+ case 0xc8: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fimulp
+ case 0xd0: return IEMOP_RAISE_INVALID_OPCODE();
+ case 0xd8:
+ switch (bRm)
+ {
+ case 0xd9: return FNIEMOP_CALL(iemOp_fcompp);
+ default: return IEMOP_RAISE_INVALID_OPCODE();
+ }
+ case 0xe0: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fsubrp
+ case 0xe8: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fsubp
+ case 0xf0: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fdivrp
+ case 0xf8: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fdivp
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+#if 0
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0: return FNIEMOP_CALL_1(iemOp_fiadd_w, bRm);
+ case 1: return FNIEMOP_CALL_1(iemOp_fimul_w, bRm);
+ case 2: return FNIEMOP_CALL_1(iemOp_ficom_w, bRm);
+ case 3: return FNIEMOP_CALL_1(iemOp_ficomp_w, bRm);
+ case 4: return FNIEMOP_CALL_1(iemOp_fisub_w, bRm);
+ case 5: return FNIEMOP_CALL_1(iemOp_fisubr_w, bRm);
+ case 6: return FNIEMOP_CALL_1(iemOp_fidiv_w, bRm);
+ case 7: return FNIEMOP_CALL_1(iemOp_fidivr_w, bRm);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+#endif
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+ }
+}
+
+
+/** Opcode 0xdf 0xe0. */
+FNIEMOP_DEF(iemOp_fnstsw_ax)
+{
+ IEMOP_MNEMONIC("fnstsw ax");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint16_t, u16Tmp);
+ IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
+ IEM_MC_FETCH_FSW(u16Tmp);
+ IEM_MC_STORE_GREG_U16(X86_GREG_xAX, u16Tmp);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xdf. */
+FNIEMOP_DEF(iemOp_EscF7)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ switch (bRm & 0xf8)
+ {
+ case 0xc0: return IEMOP_RAISE_INVALID_OPCODE();
+ case 0xc8: return IEMOP_RAISE_INVALID_OPCODE();
+ case 0xd0: return IEMOP_RAISE_INVALID_OPCODE();
+ case 0xd8: return IEMOP_RAISE_INVALID_OPCODE();
+ case 0xe0:
+ switch (bRm)
+ {
+ case 0xe0: return FNIEMOP_CALL(iemOp_fnstsw_ax);
+ default: return IEMOP_RAISE_INVALID_OPCODE();
+ }
+ case 0xe8: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fucomip
+ case 0xf0: AssertFailedReturn(VERR_NOT_IMPLEMENTED); // fcomip
+ case 0xf8: return IEMOP_RAISE_INVALID_OPCODE();
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+ }
+}
+
+
+/** Opcode 0xe0. */
+FNIEMOP_DEF(iemOp_loopne_Jb)
+{
+ IEMOP_MNEMONIC("loopne Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_SUB_GREG_U16(X86_GREG_xCX, 1);
+ IEM_MC_IF_CX_IS_NZ_AND_EFL_BIT_NOT_SET(X86_EFL_ZF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_SUB_GREG_U32(X86_GREG_xCX, 1);
+ IEM_MC_IF_ECX_IS_NZ_AND_EFL_BIT_NOT_SET(X86_EFL_ZF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_SUB_GREG_U64(X86_GREG_xCX, 1);
+ IEM_MC_IF_RCX_IS_NZ_AND_EFL_BIT_NOT_SET(X86_EFL_ZF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0xe1. */
+FNIEMOP_DEF(iemOp_loope_Jb)
+{
+ IEMOP_MNEMONIC("loope Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_SUB_GREG_U16(X86_GREG_xCX, 1);
+ IEM_MC_IF_CX_IS_NZ_AND_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_SUB_GREG_U32(X86_GREG_xCX, 1);
+ IEM_MC_IF_ECX_IS_NZ_AND_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_SUB_GREG_U64(X86_GREG_xCX, 1);
+ IEM_MC_IF_RCX_IS_NZ_AND_EFL_BIT_SET(X86_EFL_ZF) {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0xe2. */
+FNIEMOP_DEF(iemOp_loop_Jb)
+{
+ IEMOP_MNEMONIC("loop Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ /** @todo Check out the #GP case if EIP < CS.Base or EIP > CS.Limit when
+ * using the 32-bit operand size override. How can that be restarted? See
+ * weird pseudo code in intel manual. */
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_SUB_GREG_U16(X86_GREG_xCX, 1);
+ IEM_MC_IF_CX_IS_NZ() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_SUB_GREG_U32(X86_GREG_xCX, 1);
+ IEM_MC_IF_ECX_IS_NZ() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_SUB_GREG_U64(X86_GREG_xCX, 1);
+ IEM_MC_IF_RCX_IS_NZ() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ELSE() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0xe3. */
+FNIEMOP_DEF(iemOp_jecxz_Jb)
+{
+ IEMOP_MNEMONIC("jecxz Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ switch (pIemCpu->enmEffAddrMode)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_IF_CX_IS_NZ() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_IF_ECX_IS_NZ() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0,0);
+ IEM_MC_IF_RCX_IS_NZ() {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_REL_JMP_S8(i8Imm);
+ } IEM_MC_ENDIF();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0xe4 */
+FNIEMOP_DEF(iemOp_in_AL_Ib)
+{
+ IEMOP_MNEMONIC("in eAX,Ib");
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_in, u8Imm, 1);
+}
+
+
+/** Opcode 0xe5 */
+FNIEMOP_DEF(iemOp_in_eAX_Ib)
+{
+ IEMOP_MNEMONIC("in eAX,Ib");
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_in, u8Imm, pIemCpu->enmEffOpSize == IEMMODE_16BIT ? 2 : 4);
+}
+
+
+/** Opcode 0xe6 */
+FNIEMOP_DEF(iemOp_out_Ib_AL)
+{
+ IEMOP_MNEMONIC("out Ib,AL");
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_out, u8Imm, 1);
+}
+
+
+/** Opcode 0xe7 */
+FNIEMOP_DEF(iemOp_out_Ib_eAX)
+{
+ IEMOP_MNEMONIC("out Ib,eAX");
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_out, u8Imm, pIemCpu->enmEffOpSize == IEMMODE_16BIT ? 2 : 4);
+}
+
+
+/** Opcode 0xe8. */
+FNIEMOP_DEF(iemOp_call_Jv)
+{
+ IEMOP_MNEMONIC("call Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_call_rel_16, (int32_t)u16Imm);
+ }
+
+ case IEMMODE_32BIT:
+ {
+ uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_call_rel_32, (int32_t)u32Imm);
+ }
+
+ case IEMMODE_64BIT:
+ {
+ uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_call_rel_64, u64Imm);
+ }
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0xe9. */
+FNIEMOP_DEF(iemOp_jmp_Jv)
+{
+ IEMOP_MNEMONIC("jmp Jv");
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_REL_JMP_S16(i16Imm);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_64BIT:
+ case IEMMODE_32BIT:
+ {
+ int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_REL_JMP_S32(i32Imm);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0xea. */
+FNIEMOP_DEF(iemOp_jmp_Ap)
+{
+ IEMOP_MNEMONIC("jmp Ap");
+ IEMOP_HLP_NO_64BIT();
+
+ /* Decode the far pointer address and pass it on to the far call C implementation. */
+ uint32_t offSeg;
+ if (pIemCpu->enmEffOpSize != IEMMODE_16BIT)
+ IEM_OPCODE_GET_NEXT_U32(&offSeg);
+ else
+ {
+ uint16_t offSeg16; IEM_OPCODE_GET_NEXT_U16(&offSeg16);
+ offSeg = offSeg16;
+ }
+ uint16_t uSel; IEM_OPCODE_GET_NEXT_U16(&uSel);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_FarJmp, uSel, offSeg, pIemCpu->enmEffOpSize);
+}
+
+
+/** Opcode 0xeb. */
+FNIEMOP_DEF(iemOp_jmp_Jb)
+{
+ IEMOP_MNEMONIC("jmp Jb");
+ int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_REL_JMP_S8(i8Imm);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xec */
+FNIEMOP_DEF(iemOp_in_AL_DX)
+{
+ IEMOP_MNEMONIC("in AL,DX");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_in_eAX_DX, 1);
+}
+
+
+/** Opcode 0xed */
+FNIEMOP_DEF(iemOp_eAX_DX)
+{
+ IEMOP_MNEMONIC("in eAX,DX");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_in_eAX_DX, pIemCpu->enmEffOpSize == IEMMODE_16BIT ? 2 : 4);
+}
+
+
+/** Opcode 0xee */
+FNIEMOP_DEF(iemOp_out_DX_AL)
+{
+ IEMOP_MNEMONIC("out DX,AL");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_out_DX_eAX, 1);
+}
+
+
+/** Opcode 0xef */
+FNIEMOP_DEF(iemOp_out_DX_eAX)
+{
+ IEMOP_MNEMONIC("out DX,eAX");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_out_DX_eAX, pIemCpu->enmEffOpSize == IEMMODE_16BIT ? 2 : 4);
+}
+
+
+/** Opcode 0xf0. */
+FNIEMOP_DEF(iemOp_lock)
+{
+ pIemCpu->fPrefixes |= IEM_OP_PRF_LOCK;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+}
+
+
+/** Opcode 0xf2. */
+FNIEMOP_DEF(iemOp_repne)
+{
+ /* This overrides any previous REPE prefix. */
+ pIemCpu->fPrefixes &= ~IEM_OP_PRF_REPZ;
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REPNZ;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+}
+
+
+/** Opcode 0xf3. */
+FNIEMOP_DEF(iemOp_repe)
+{
+ /* This overrides any previous REPNE prefix. */
+ pIemCpu->fPrefixes &= ~IEM_OP_PRF_REPNZ;
+ pIemCpu->fPrefixes |= IEM_OP_PRF_REPZ;
+
+ uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
+ return FNIEMOP_CALL(g_apfnOneByteMap[b]);
+}
+
+
+/** Opcode 0xf4. */
+FNIEMOP_DEF(iemOp_hlt)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_hlt);
+}
+
+
+/** Opcode 0xf5. */
+FNIEMOP_STUB(iemOp_cmc);
+
+
+/**
+ * Common implementation of 'inc/dec/not/neg Eb'.
+ *
+ * @param bRm The RM byte.
+ * @param pImpl The instruction implementation.
+ */
+FNIEMOP_DEF_2(iemOpCommonUnaryEb, uint8_t, bRm, PCIEMOPUNARYSIZES, pImpl)
+{
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register access */
+ IEM_MC_BEGIN(2, 0);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG(uint32_t *, pEFlags, 1);
+ IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU8, pu8Dst, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory access. */
+ IEM_MC_BEGIN(2, 2);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU8, pu8Dst, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnLockedU8, pu8Dst, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Common implementation of 'inc/dec/not/neg Ev'.
+ *
+ * @param bRm The RM byte.
+ * @param pImpl The instruction implementation.
+ */
+FNIEMOP_DEF_2(iemOpCommonUnaryEv, uint8_t, bRm, PCIEMOPUNARYSIZES, pImpl)
+{
+ /* Registers are handled by a common worker. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, pImpl, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+
+ /* Memory we do here. */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(2, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU16, pu16Dst, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnLockedU16, pu16Dst, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(2, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU32, pu32Dst, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnLockedU32, pu32Dst, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(2, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ if (!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))
+ IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU64, pu64Dst, pEFlags);
+ else
+ IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnLockedU64, pu64Dst, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0xf6 /0. */
+FNIEMOP_DEF_1(iemOp_grp3_test_Eb, uint8_t, bRm)
+{
+ IEMOP_MNEMONIC("test Eb,Ib");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register access */
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEMOP_HLP_NO_LOCK_PREFIX();
+
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG_CONST(uint8_t, u8Src,/*=*/u8Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u8, pu8Dst, u8Src, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory access. */
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint8_t *, pu8Dst, 0);
+ IEM_MC_ARG(uint8_t, u8Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
+ IEM_MC_ASSIGN(u8Src, u8Imm);
+ IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_R, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u8, pu8Dst, u8Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_R);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xf7 /0. */
+FNIEMOP_DEF_1(iemOp_grp3_test_Ev, uint8_t, bRm)
+{
+ IEMOP_MNEMONIC("test Ev,Iv");
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register access */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/u16Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u16, pu16Dst, u16Src, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/u32Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u32, pu32Dst, u32Src, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/u64Imm, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u64, pu64Dst, u64Src, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /* memory access. */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+ IEM_MC_ARG(uint16_t, u16Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
+ IEM_MC_ASSIGN(u16Src, u16Imm);
+ IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_R, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u16, pu16Dst, u16Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_R);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+ IEM_MC_ARG(uint32_t, u32Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
+ IEM_MC_ASSIGN(u32Src, u32Imm);
+ IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_R, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u32, pu32Dst, u32Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_R);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ IEM_MC_BEGIN(3, 2);
+ IEM_MC_ARG(uint64_t *, pu64Dst, 0);
+ IEM_MC_ARG(uint64_t, u64Src, 1);
+ IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
+ IEM_MC_ASSIGN(u64Src, u64Imm);
+ IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_R, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
+ IEM_MC_FETCH_EFLAGS(EFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u64, pu64Dst, u64Src, pEFlags);
+
+ IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_R);
+ IEM_MC_COMMIT_EFLAGS(EFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/** Opcode 0xf6 /4, /5, /6 and /7. */
+FNIEMOP_DEF_2(iemOpCommonGrp3MulDivEb, uint8_t, bRm, PFNIEMAIMPLMULDIVU8, pfnU8)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register access */
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(3, 0);
+ IEM_MC_ARG(uint16_t *, pu16AX, 0);
+ IEM_MC_ARG(uint8_t, u8Value, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_FETCH_GREG_U8(u8Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pfnU8, pu16AX, u8Value, pEFlags);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /* memory access. */
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint16_t *, pu16AX, 0);
+ IEM_MC_ARG(uint8_t, u8Value, 1);
+ IEM_MC_ARG(uint32_t *, pEFlags, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U8(u8Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_3(pfnU8, pu16AX, u8Value, pEFlags);
+
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xf7 /4, /5, /6 and /7. */
+FNIEMOP_DEF_2(iemOpCommonGrp3MulDivEv, uint8_t, bRm, PCIEMOPMULDIVSIZES, pImpl)
+{
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* register access */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(4, 1);
+ IEM_MC_ARG(uint16_t *, pu16AX, 0);
+ IEM_MC_ARG(uint16_t *, pu16DX, 1);
+ IEM_MC_ARG(uint16_t, u16Value, 2);
+ IEM_MC_ARG(uint32_t *, pEFlags, 3);
+ IEM_MC_LOCAL(int32_t, rc);
+
+ IEM_MC_FETCH_GREG_U16(u16Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
+ IEM_MC_REF_GREG_U16(pu16DX, X86_GREG_xDX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU16, pu16AX, pu16DX, u16Value, pEFlags);
+ IEM_MC_IF_LOCAL_IS_Z(rc) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_RAISE_DIVIDE_ERROR();
+ } IEM_MC_ENDIF();
+
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(4, 1);
+ IEM_MC_ARG(uint32_t *, pu32AX, 0);
+ IEM_MC_ARG(uint32_t *, pu32DX, 1);
+ IEM_MC_ARG(uint32_t, u32Value, 2);
+ IEM_MC_ARG(uint32_t *, pEFlags, 3);
+ IEM_MC_LOCAL(int32_t, rc);
+
+ IEM_MC_FETCH_GREG_U32(u32Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_GREG_U32(pu32AX, X86_GREG_xAX);
+ IEM_MC_REF_GREG_U32(pu32DX, X86_GREG_xDX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU32, pu32AX, pu32DX, u32Value, pEFlags);
+ IEM_MC_IF_LOCAL_IS_Z(rc) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_RAISE_DIVIDE_ERROR();
+ } IEM_MC_ENDIF();
+
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(4, 1);
+ IEM_MC_ARG(uint64_t *, pu64AX, 0);
+ IEM_MC_ARG(uint64_t *, pu64DX, 1);
+ IEM_MC_ARG(uint64_t, u64Value, 2);
+ IEM_MC_ARG(uint32_t *, pEFlags, 3);
+ IEM_MC_LOCAL(int32_t, rc);
+
+ IEM_MC_FETCH_GREG_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_REF_GREG_U64(pu64AX, X86_GREG_xAX);
+ IEM_MC_REF_GREG_U64(pu64DX, X86_GREG_xDX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU64, pu64AX, pu64DX, u64Value, pEFlags);
+ IEM_MC_IF_LOCAL_IS_Z(rc) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_RAISE_DIVIDE_ERROR();
+ } IEM_MC_ENDIF();
+
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /* memory access. */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(4, 2);
+ IEM_MC_ARG(uint16_t *, pu16AX, 0);
+ IEM_MC_ARG(uint16_t *, pu16DX, 1);
+ IEM_MC_ARG(uint16_t, u16Value, 2);
+ IEM_MC_ARG(uint32_t *, pEFlags, 3);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_LOCAL(int32_t, rc);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U16(u16Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
+ IEM_MC_REF_GREG_U16(pu16DX, X86_GREG_xDX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU16, pu16AX, pu16DX, u16Value, pEFlags);
+ IEM_MC_IF_LOCAL_IS_Z(rc) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_RAISE_DIVIDE_ERROR();
+ } IEM_MC_ENDIF();
+
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_32BIT:
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(4, 2);
+ IEM_MC_ARG(uint32_t *, pu32AX, 0);
+ IEM_MC_ARG(uint32_t *, pu32DX, 1);
+ IEM_MC_ARG(uint32_t, u32Value, 2);
+ IEM_MC_ARG(uint32_t *, pEFlags, 3);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_LOCAL(int32_t, rc);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U32(u32Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_GREG_U32(pu32AX, X86_GREG_xAX);
+ IEM_MC_REF_GREG_U32(pu32DX, X86_GREG_xDX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU32, pu32AX, pu32DX, u32Value, pEFlags);
+ IEM_MC_IF_LOCAL_IS_Z(rc) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_RAISE_DIVIDE_ERROR();
+ } IEM_MC_ENDIF();
+
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ case IEMMODE_64BIT:
+ {
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(4, 2);
+ IEM_MC_ARG(uint64_t *, pu64AX, 0);
+ IEM_MC_ARG(uint64_t *, pu64DX, 1);
+ IEM_MC_ARG(uint64_t, u64Value, 2);
+ IEM_MC_ARG(uint32_t *, pEFlags, 3);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+ IEM_MC_LOCAL(int32_t, rc);
+
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+ IEM_MC_FETCH_MEM_U64(u64Value, pIemCpu->iEffSeg, GCPtrEffDst);
+ IEM_MC_REF_GREG_U64(pu64AX, X86_GREG_xAX);
+ IEM_MC_REF_GREG_U64(pu64DX, X86_GREG_xDX);
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU64, pu64AX, pu64DX, u64Value, pEFlags);
+ IEM_MC_IF_LOCAL_IS_Z(rc) {
+ IEM_MC_ADVANCE_RIP();
+ } IEM_MC_ELSE() {
+ IEM_MC_RAISE_DIVIDE_ERROR();
+ } IEM_MC_ENDIF();
+
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+/** Opcode 0xf6. */
+FNIEMOP_DEF(iemOp_Grp3_Eb)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0:
+ return FNIEMOP_CALL_1(iemOp_grp3_test_Eb, bRm);
+ case 1:
+ return IEMOP_RAISE_INVALID_LOCK_PREFIX();
+ case 2:
+ IEMOP_MNEMONIC("not Eb");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryEb, bRm, &g_iemAImpl_not);
+ case 3:
+ IEMOP_MNEMONIC("neg Eb");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryEb, bRm, &g_iemAImpl_neg);
+ case 4:
+ IEMOP_MNEMONIC("mul Eb");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
+ return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, iemAImpl_mul_u8);
+ case 5:
+ IEMOP_MNEMONIC("imul Eb");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
+ return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, iemAImpl_imul_u8);
+ case 6:
+ IEMOP_MNEMONIC("div Eb");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
+ return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, iemAImpl_div_u8);
+ case 7:
+ IEMOP_MNEMONIC("idiv Eb");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
+ return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, iemAImpl_idiv_u8);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0xf7. */
+FNIEMOP_DEF(iemOp_Grp3_Ev)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0:
+ return FNIEMOP_CALL_1(iemOp_grp3_test_Ev, bRm);
+ case 1:
+ return IEMOP_RAISE_INVALID_LOCK_PREFIX();
+ case 2:
+ IEMOP_MNEMONIC("not Ev");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryEv, bRm, &g_iemAImpl_not);
+ case 3:
+ IEMOP_MNEMONIC("neg Ev");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryEv, bRm, &g_iemAImpl_neg);
+ case 4:
+ IEMOP_MNEMONIC("mul Ev");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
+ return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, &g_iemAImpl_mul);
+ case 5:
+ IEMOP_MNEMONIC("imul Ev");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
+ return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, &g_iemAImpl_imul);
+ case 6:
+ IEMOP_MNEMONIC("div Ev");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
+ return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, &g_iemAImpl_div);
+ case 7:
+ IEMOP_MNEMONIC("idiv Ev");
+ IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
+ return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, &g_iemAImpl_idiv);
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/** Opcode 0xf8. */
+FNIEMOP_DEF(iemOp_clc)
+{
+ IEMOP_MNEMONIC("clc");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_CLEAR_EFL_BIT(X86_EFL_CF);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xf9. */
+FNIEMOP_DEF(iemOp_stc)
+{
+ IEMOP_MNEMONIC("slc");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_SET_EFL_BIT(X86_EFL_CF);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xfa. */
+FNIEMOP_DEF(iemOp_cli)
+{
+ IEMOP_MNEMONIC("cli");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_cli);
+}
+
+
+FNIEMOP_DEF(iemOp_sti)
+{
+ IEMOP_MNEMONIC("sti");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_sti);
+}
+
+
+/** Opcode 0xfc. */
+FNIEMOP_DEF(iemOp_cld)
+{
+ IEMOP_MNEMONIC("cld");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_CLEAR_EFL_BIT(X86_EFL_DF);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xfd. */
+FNIEMOP_DEF(iemOp_std)
+{
+ IEMOP_MNEMONIC("std");
+ IEMOP_HLP_NO_LOCK_PREFIX();
+ IEM_MC_BEGIN(0, 0);
+ IEM_MC_SET_EFL_BIT(X86_EFL_DF);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+}
+
+
+/** Opcode 0xfe. */
+FNIEMOP_DEF(iemOp_Grp4)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0:
+ IEMOP_MNEMONIC("inc Ev");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryEb, bRm, &g_iemAImpl_inc);
+ case 1:
+ IEMOP_MNEMONIC("dec Ev");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryEb, bRm, &g_iemAImpl_dec);
+ default:
+ IEMOP_MNEMONIC("grp4-ud");
+ return IEMOP_RAISE_INVALID_OPCODE();
+ }
+}
+
+
+/**
+ * Opcode 0xff /2.
+ * @param bRm The RM byte.
+ */
+FNIEMOP_DEF_1(iemOp_Grp5_calln_Ev, uint8_t, bRm)
+{
+ IEMOP_MNEMONIC("calln Ev");
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo Too early? */
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* The new RIP is taken from a register. */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(1, 0);
+ IEM_MC_ARG(uint16_t, u16Target, 0);
+ IEM_MC_FETCH_GREG_U16(u16Target, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_CALL_CIMPL_1(iemCImpl_call_16, u16Target);
+ IEM_MC_END()
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(1, 0);
+ IEM_MC_ARG(uint32_t, u32Target, 0);
+ IEM_MC_FETCH_GREG_U32(u32Target, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_CALL_CIMPL_1(iemCImpl_call_32, u32Target);
+ IEM_MC_END()
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(1, 0);
+ IEM_MC_ARG(uint64_t, u64Target, 0);
+ IEM_MC_FETCH_GREG_U64(u64Target, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_CALL_CIMPL_1(iemCImpl_call_64, u64Target);
+ IEM_MC_END()
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /* The new RIP is taken from a register. */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(1, 1);
+ IEM_MC_ARG(uint16_t, u16Target, 0);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U16(u16Target, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_CALL_CIMPL_1(iemCImpl_call_16, u16Target);
+ IEM_MC_END()
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(1, 1);
+ IEM_MC_ARG(uint32_t, u32Target, 0);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U32(u32Target, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_CALL_CIMPL_1(iemCImpl_call_32, u32Target);
+ IEM_MC_END()
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(1, 1);
+ IEM_MC_ARG(uint64_t, u64Target, 0);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U64(u64Target, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_CALL_CIMPL_1(iemCImpl_call_64, u64Target);
+ IEM_MC_END()
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/**
+ * Opcode 0xff /3.
+ * @param bRm The RM byte.
+ */
+FNIEMOP_DEF_1(iemOp_Grp5_callf_Ep, uint8_t, bRm)
+{
+ IEMOP_MNEMONIC("callf Ep");
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo Too early? */
+
+ /* Registers? How?? */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /** @todo How the heck does a 'callf eax' work? Probably just have to
+ * search the docs... */
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+ }
+
+ /* Far pointer loaded from memory. */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint16_t, u16Sel, 0);
+ IEM_MC_ARG(uint16_t, offSeg, 1);
+ IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, IEMMODE_16BIT, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U16(offSeg, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_FETCH_MEM_U16_DISP(u16Sel, pIemCpu->iEffSeg, GCPtrEffSrc, 2);
+ IEM_MC_CALL_CIMPL_3(iemCImpl_callf, u16Sel, offSeg, enmEffOpSize);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint16_t, u16Sel, 0);
+ IEM_MC_ARG(uint32_t, offSeg, 1);
+ IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, IEMMODE_32BIT, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U32(offSeg, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_FETCH_MEM_U16_DISP(u16Sel, pIemCpu->iEffSeg, GCPtrEffSrc, 4);
+ IEM_MC_CALL_CIMPL_3(iemCImpl_callf, u16Sel, offSeg, enmEffOpSize);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint16_t, u16Sel, 0);
+ IEM_MC_ARG(uint64_t, offSeg, 1);
+ IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, IEMMODE_16BIT, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U64(offSeg, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_FETCH_MEM_U16_DISP(u16Sel, pIemCpu->iEffSeg, GCPtrEffSrc, 8);
+ IEM_MC_CALL_CIMPL_3(iemCImpl_callf, u16Sel, offSeg, enmEffOpSize);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/**
+ * Opcode 0xff /4.
+ * @param bRm The RM byte.
+ */
+FNIEMOP_DEF_1(iemOp_Grp5_jmpn_Ev, uint8_t, bRm)
+{
+ IEMOP_MNEMONIC("jmpn Ev");
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo Too early? */
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /* The new RIP is taken from a register. */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint16_t, u16Target);
+ IEM_MC_FETCH_GREG_U16(u16Target, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_SET_RIP_U16(u16Target);
+ IEM_MC_END()
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint32_t, u32Target);
+ IEM_MC_FETCH_GREG_U32(u32Target, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_SET_RIP_U32(u32Target);
+ IEM_MC_END()
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 1);
+ IEM_MC_LOCAL(uint64_t, u64Target);
+ IEM_MC_FETCH_GREG_U64(u64Target, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+ IEM_MC_SET_RIP_U64(u64Target);
+ IEM_MC_END()
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+ else
+ {
+ /* The new RIP is taken from a register. */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint16_t, u16Target);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U16(u16Target, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_SET_RIP_U16(u16Target);
+ IEM_MC_END()
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint32_t, u32Target);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U32(u32Target, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_SET_RIP_U32(u32Target);
+ IEM_MC_END()
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint32_t, u32Target);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U32(u32Target, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_SET_RIP_U32(u32Target);
+ IEM_MC_END()
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+ }
+}
+
+
+/**
+ * Opcode 0xff /5.
+ * @param bRm The RM byte.
+ */
+FNIEMOP_DEF_1(iemOp_Grp5_jmpf_Ep, uint8_t, bRm)
+{
+ IEMOP_MNEMONIC("jmp Ep");
+ IEMOP_HLP_NO_64BIT();
+ /** @todo could share all the decoding with iemOp_Grp5_callf_Ep. */
+
+ /* Decode the far pointer address and pass it on to the far call C
+ implementation. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ {
+ /** @todo How the heck does a 'callf eax' work? Probably just have to
+ * search the docs... */
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+ }
+
+ /* Far pointer loaded from memory. */
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint16_t, u16Sel, 0);
+ IEM_MC_ARG(uint16_t, offSeg, 1);
+ IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, IEMMODE_16BIT, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U16(offSeg, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_FETCH_MEM_U16_DISP(u16Sel, pIemCpu->iEffSeg, GCPtrEffSrc, 2);
+ IEM_MC_CALL_CIMPL_3(iemCImpl_FarJmp, u16Sel, offSeg, enmEffOpSize);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint16_t, u16Sel, 0);
+ IEM_MC_ARG(uint32_t, offSeg, 1);
+ IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, IEMMODE_32BIT, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U32(offSeg, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_FETCH_MEM_U16_DISP(u16Sel, pIemCpu->iEffSeg, GCPtrEffSrc, 4);
+ IEM_MC_CALL_CIMPL_3(iemCImpl_FarJmp, u16Sel, offSeg, enmEffOpSize);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(3, 1);
+ IEM_MC_ARG(uint16_t, u16Sel, 0);
+ IEM_MC_ARG(uint64_t, offSeg, 1);
+ IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, IEMMODE_16BIT, 2);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U64(offSeg, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_FETCH_MEM_U16_DISP(u16Sel, pIemCpu->iEffSeg, GCPtrEffSrc, 8);
+ IEM_MC_CALL_CIMPL_3(iemCImpl_FarJmp, u16Sel, offSeg, enmEffOpSize);
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ IEM_NOT_REACHED_DEFAULT_CASE_RET();
+ }
+}
+
+
+/**
+ * Opcode 0xff /6.
+ * @param bRm The RM byte.
+ */
+FNIEMOP_DEF_1(iemOp_Grp5_push_Ev, uint8_t, bRm)
+{
+ IEMOP_MNEMONIC("push Ev");
+ IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo Too early? */
+
+ /* Registers are handled by a common worker. */
+ if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+ return FNIEMOP_CALL_1(iemOpCommonPushGReg, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);
+
+ /* Memory we do here. */
+ IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+ switch (pIemCpu->enmEffOpSize)
+ {
+ case IEMMODE_16BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint16_t, u16Src);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U16(u16Src, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_PUSH_U16(u16Src);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_32BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint32_t, u32Src);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U32(u32Src, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_PUSH_U32(u32Src);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+
+ case IEMMODE_64BIT:
+ IEM_MC_BEGIN(0, 2);
+ IEM_MC_LOCAL(uint64_t, u64Src);
+ IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
+ IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
+ IEM_MC_FETCH_MEM_U64(u64Src, pIemCpu->iEffSeg, GCPtrEffSrc);
+ IEM_MC_PUSH_U64(u64Src);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ return VINF_SUCCESS;
+ }
+ AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+}
+
+
+/** Opcode 0xff. */
+FNIEMOP_DEF(iemOp_Grp5)
+{
+ uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+ switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
+ {
+ case 0:
+ IEMOP_MNEMONIC("inc Ev");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryEv, bRm, &g_iemAImpl_inc);
+ case 1:
+ IEMOP_MNEMONIC("dec Ev");
+ return FNIEMOP_CALL_2(iemOpCommonUnaryEv, bRm, &g_iemAImpl_dec);
+ case 2:
+ return FNIEMOP_CALL_1(iemOp_Grp5_calln_Ev, bRm);
+ case 3:
+ return FNIEMOP_CALL_1(iemOp_Grp5_callf_Ep, bRm);
+ case 4:
+ return FNIEMOP_CALL_1(iemOp_Grp5_jmpn_Ev, bRm);
+ case 5:
+ return FNIEMOP_CALL_1(iemOp_Grp5_jmpf_Ep, bRm);
+ case 6:
+ return FNIEMOP_CALL_1(iemOp_Grp5_push_Ev, bRm);
+ case 7:
+ IEMOP_MNEMONIC("grp5-ud");
+ return IEMOP_RAISE_INVALID_OPCODE();
+ }
+ AssertFailedReturn(VERR_INTERNAL_ERROR_2);
+}
+
+
+
+const PFNIEMOP g_apfnOneByteMap[256] =
+{
+ /* 0x00 */ iemOp_add_Eb_Gb, iemOp_add_Ev_Gv, iemOp_add_Gb_Eb, iemOp_add_Gv_Ev,
+ /* 0x04 */ iemOp_add_Al_Ib, iemOp_add_eAX_Iz, iemOp_push_ES, iemOp_pop_ES,
+ /* 0x08 */ iemOp_or_Eb_Gb, iemOp_or_Ev_Gv, iemOp_or_Gb_Eb, iemOp_or_Gv_Ev,
+ /* 0x0c */ iemOp_or_Al_Ib, iemOp_or_eAX_Iz, iemOp_push_CS, iemOp_2byteEscape,
+ /* 0x10 */ iemOp_adc_Eb_Gb, iemOp_adc_Ev_Gv, iemOp_adc_Gb_Eb, iemOp_adc_Gv_Ev,
+ /* 0x14 */ iemOp_adc_Al_Ib, iemOp_adc_eAX_Iz, iemOp_push_SS, iemOp_pop_SS,
+ /* 0x18 */ iemOp_sbb_Eb_Gb, iemOp_sbb_Ev_Gv, iemOp_sbb_Gb_Eb, iemOp_sbb_Gv_Ev,
+ /* 0x1c */ iemOp_sbb_Al_Ib, iemOp_sbb_eAX_Iz, iemOp_push_DS, iemOp_pop_DS,
+ /* 0x20 */ iemOp_and_Eb_Gb, iemOp_and_Ev_Gv, iemOp_and_Gb_Eb, iemOp_and_Gv_Ev,
+ /* 0x24 */ iemOp_and_Al_Ib, iemOp_and_eAX_Iz, iemOp_seg_ES, iemOp_daa,
+ /* 0x28 */ iemOp_sub_Eb_Gb, iemOp_sub_Ev_Gv, iemOp_sub_Gb_Eb, iemOp_sub_Gv_Ev,
+ /* 0x2c */ iemOp_sub_Al_Ib, iemOp_sub_eAX_Iz, iemOp_seg_CS, iemOp_das,
+ /* 0x30 */ iemOp_xor_Eb_Gb, iemOp_xor_Ev_Gv, iemOp_xor_Gb_Eb, iemOp_xor_Gv_Ev,
+ /* 0x34 */ iemOp_xor_Al_Ib, iemOp_xor_eAX_Iz, iemOp_seg_SS, iemOp_aaa,
+ /* 0x38 */ iemOp_cmp_Eb_Gb, iemOp_cmp_Ev_Gv, iemOp_cmp_Gb_Eb, iemOp_cmp_Gv_Ev,
+ /* 0x3c */ iemOp_cmp_Al_Ib, iemOp_cmp_eAX_Iz, iemOp_seg_DS, iemOp_aas,
+ /* 0x40 */ iemOp_inc_eAX, iemOp_inc_eCX, iemOp_inc_eDX, iemOp_inc_eBX,
+ /* 0x44 */ iemOp_inc_eSP, iemOp_inc_eBP, iemOp_inc_eSI, iemOp_inc_eDI,
+ /* 0x48 */ iemOp_dec_eAX, iemOp_dec_eCX, iemOp_dec_eDX, iemOp_dec_eBX,
+ /* 0x4c */ iemOp_dec_eSP, iemOp_dec_eBP, iemOp_dec_eSI, iemOp_dec_eDI,
+ /* 0x50 */ iemOp_push_eAX, iemOp_push_eCX, iemOp_push_eDX, iemOp_push_eBX,
+ /* 0x54 */ iemOp_push_eSP, iemOp_push_eBP, iemOp_push_eSI, iemOp_push_eDI,
+ /* 0x58 */ iemOp_pop_eAX, iemOp_pop_eCX, iemOp_pop_eDX, iemOp_pop_eBX,
+ /* 0x5c */ iemOp_pop_eSP, iemOp_pop_eBP, iemOp_pop_eSI, iemOp_pop_eDI,
+ /* 0x60 */ iemOp_pusha, iemOp_popa, iemOp_bound_Gv_Ma, iemOp_arpl_Ew_Gw,
+ /* 0x64 */ iemOp_seg_FS, iemOp_seg_GS, iemOp_op_size, iemOp_addr_size,
+ /* 0x68 */ iemOp_push_Iz, iemOp_imul_Gv_Ev_Iz, iemOp_push_Ib, iemOp_imul_Gv_Ev_Ib,
+ /* 0x6c */ iemOp_insb_Yb_DX, iemOp_inswd_Yv_DX, iemOp_outsb_Yb_DX, iemOp_outswd_Yv_DX,
+ /* 0x70 */ iemOp_jo_Jb, iemOp_jno_Jb, iemOp_jc_Jb, iemOp_jnc_Jb,
+ /* 0x74 */ iemOp_je_Jb, iemOp_jne_Jb, iemOp_jbe_Jb, iemOp_jnbe_Jb,
+ /* 0x78 */ iemOp_js_Jb, iemOp_jns_Jb, iemOp_jp_Jb, iemOp_jnp_Jb,
+ /* 0x7c */ iemOp_jl_Jb, iemOp_jnl_Jb, iemOp_jle_Jb, iemOp_jnle_Jb,
+ /* 0x80 */ iemOp_Grp1_Eb_Ib_80, iemOp_Grp1_Ev_Iz, iemOp_Grp1_Eb_Ib_82, iemOp_Grp1_Ev_Ib,
+ /* 0x84 */ iemOp_test_Eb_Gb, iemOp_test_Ev_Gv, iemOp_xchg_Eb_Gb, iemOp_xchg_Ev_Gv,
+ /* 0x88 */ iemOp_mov_Eb_Gb, iemOp_mov_Ev_Gv, iemOp_mov_Gb_Eb, iemOp_mov_Gv_Ev,
+ /* 0x8c */ iemOp_mov_Ev_Sw, iemOp_lea_Gv_M, iemOp_mov_Sw_Ev, iemOp_pop_Ev,
+ /* 0x90 */ iemOp_nop, iemOp_xchg_eCX_eAX, iemOp_xchg_eDX_eAX, iemOp_xchg_eBX_eAX,
+ /* 0x94 */ iemOp_xchg_eSP_eAX, iemOp_xchg_eBP_eAX, iemOp_xchg_eSI_eAX, iemOp_xchg_eDI_eAX,
+ /* 0x98 */ iemOp_cbw, iemOp_cwd, iemOp_call_Ap, iemOp_wait,
+ /* 0x9c */ iemOp_pushf_Fv, iemOp_popf_Fv, iemOp_sahf, iemOp_lahf,
+ /* 0xa0 */ iemOp_mov_Al_Ob, iemOp_mov_rAX_Ov, iemOp_mov_Ob_AL, iemOp_mov_Ov_rAX,
+ /* 0xa4 */ iemOp_movsb_Xb_Yb, iemOp_movswd_Xv_Yv, iemOp_cmpsb_Xb_Yb, iemOp_cmpswd_Xv_Yv,
+ /* 0xa8 */ iemOp_test_AL_Ib, iemOp_test_eAX_Iz, iemOp_stosb_Yb_AL, iemOp_stoswd_Yv_eAX,
+ /* 0xac */ iemOp_lodsb_AL_Xb, iemOp_lodswd_eAX_Xv, iemOp_scasb_AL_Xb, iemOp_scaswd_eAX_Xv,
+ /* 0xb0 */ iemOp_mov_AL_Ib, iemOp_CL_Ib, iemOp_DL_Ib, iemOp_BL_Ib,
+ /* 0xb4 */ iemOp_mov_AH_Ib, iemOp_CH_Ib, iemOp_DH_Ib, iemOp_BH_Ib,
+ /* 0xb8 */ iemOp_eAX_Iv, iemOp_eCX_Iv, iemOp_eDX_Iv, iemOp_eBX_Iv,
+ /* 0xbc */ iemOp_eSP_Iv, iemOp_eBP_Iv, iemOp_eSI_Iv, iemOp_eDI_Iv,
+ /* 0xc0 */ iemOp_Grp2_Eb_Ib, iemOp_Grp2_Ev_Ib, iemOp_retn_Iw, iemOp_retn,
+ /* 0xc4 */ iemOp_les_Gv_Mp, iemOp_lds_Gv_Mp, iemOp_Grp11_Eb_Ib, iemOp_Grp11_Ev_Iz,
+ /* 0xc8 */ iemOp_enter_Iw_Ib, iemOp_leave, iemOp_retf_Iw, iemOp_retf,
+ /* 0xcc */ iemOp_int_3, iemOp_int_Ib, iemOp_into, iemOp_iret,
+ /* 0xd0 */ iemOp_Grp2_Eb_1, iemOp_Grp2_Ev_1, iemOp_Grp2_Eb_CL, iemOp_Grp2_Ev_CL,
+ /* 0xd4 */ iemOp_aam_Ib, iemOp_aad_Ib, iemOp_Invalid, iemOp_xlat,
+ /* 0xd8 */ iemOp_EscF0, iemOp_EscF1, iemOp_EscF2, iemOp_EscF3,
+ /* 0xdc */ iemOp_EscF4, iemOp_EscF5, iemOp_EscF6, iemOp_EscF7,
+ /* 0xe0 */ iemOp_loopne_Jb, iemOp_loope_Jb, iemOp_loop_Jb, iemOp_jecxz_Jb,
+ /* 0xe4 */ iemOp_in_AL_Ib, iemOp_in_eAX_Ib, iemOp_out_Ib_AL, iemOp_out_Ib_eAX,
+ /* 0xe8 */ iemOp_call_Jv, iemOp_jmp_Jv, iemOp_jmp_Ap, iemOp_jmp_Jb,
+ /* 0xec */ iemOp_in_AL_DX, iemOp_eAX_DX, iemOp_out_DX_AL, iemOp_out_DX_eAX,
+ /* 0xf0 */ iemOp_lock, iemOp_Invalid, iemOp_repne, iemOp_repe, /** @todo 0xf1 is INT1 / ICEBP. */
+ /* 0xf4 */ iemOp_hlt, iemOp_cmc, iemOp_Grp3_Eb, iemOp_Grp3_Ev,
+ /* 0xf8 */ iemOp_clc, iemOp_stc, iemOp_cli, iemOp_sti,
+ /* 0xfc */ iemOp_cld, iemOp_std, iemOp_Grp4, iemOp_Grp5,
+};
+
+
+/** @} */
+
diff --git a/src/VBox/VMM/VMMAll/IOMAll.cpp b/src/VBox/VMM/VMMAll/IOMAll.cpp
index c8578284d..07dbcd59d 100644
--- a/src/VBox/VMM/VMMAll/IOMAll.cpp
+++ b/src/VBox/VMM/VMMAll/IOMAll.cpp
@@ -1,10 +1,10 @@
-/* $Id: IOMAll.cpp $ */
+/* $Id: IOMAll.cpp 37467 2011-06-15 13:08:45Z vboxsync $ */
/** @file
* IOM - Input / Output Monitor - Any Context.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -21,6 +21,9 @@
#define LOG_GROUP LOG_GROUP_IOM
#include <VBox/vmm/iom.h>
#include <VBox/vmm/mm.h>
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
+# include <VBox/vmm/iem.h>
+#endif
#include <VBox/param.h>
#include "IOMInternal.h"
#include <VBox/vmm/vm.h>
@@ -33,49 +36,7 @@
#include <VBox/err.h>
#include <VBox/log.h>
#include <iprt/assert.h>
-
-
-
-/**
- * Try take the EMT/IOM lock, wait in ring-3 return VERR_SEM_BUSY in R0/RC.
- *
- * @retval VINF_SUCCESS on success (always in ring-3).
- * @retval VERR_SEM_BUSY in RC and R0 if the semaphore is busy.
- *
- * @param pVM VM handle.
- */
-int iomLock(PVM pVM)
-{
- Assert(pVM->cCpus == 1 || !PGMIsLockOwner(pVM));
- int rc = PDMCritSectEnter(&pVM->iom.s.EmtLock, VERR_SEM_BUSY);
- return rc;
-}
-
-
-/**
- * Try take the EMT/IOM lock, no waiting.
- *
- * @retval VINF_SUCCESS on success.
- * @retval VERR_SEM_BUSY if busy.
- *
- * @param pVM VM handle.
- */
-int iomTryLock(PVM pVM)
-{
- int rc = PDMCritSectTryEnter(&pVM->iom.s.EmtLock);
- return rc;
-}
-
-
-/**
- * Release EMT/IOM lock.
- *
- * @param pVM VM handle.
- */
-void iomUnlock(PVM pVM)
-{
- PDMCritSectLeave(&pVM->iom.s.EmtLock);
-}
+#include "IOMInline.h"
/**
@@ -86,9 +47,10 @@ void iomUnlock(PVM pVM)
*/
VMMDECL(bool) IOMIsLockOwner(PVM pVM)
{
- return PDMCritSectIsOwner(&pVM->iom.s.EmtLock);
+ return PDMCritSectIsOwner(&pVM->iom.s.CritSect);
}
+
/**
* Returns the contents of register or immediate data of instruction's parameter.
*
@@ -257,13 +219,18 @@ bool iomSaveDataToReg(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRe
*/
VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue)
{
+/** @todo should initialize *pu32Value here because it can happen that some
+ * handle is buggy and doesn't handle all cases. */
/* Take the IOM lock before performing any device I/O. */
- int rc2 = iomLock(pVM);
+ int rc2 = IOM_LOCK(pVM);
#ifndef IN_RING3
if (rc2 == VERR_SEM_BUSY)
return VINF_IOM_HC_IOPORT_READ;
#endif
AssertRC(rc2);
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
+ IEMNotifyIOPortRead(pVM, Port, cbValue);
+#endif
#ifdef VBOX_WITH_STATISTICS
/*
@@ -285,7 +252,7 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value,
if ( !pRange
|| (unsigned)Port - (unsigned)pRange->Port >= (unsigned)pRange->cPorts)
{
- pRange = iomIOPortGetRange(&pVM->iom.s, Port);
+ pRange = iomIOPortGetRange(pVM, Port);
if (pRange)
pVM->iom.s.CTX_SUFF(pRangeLastRead) = pRange;
}
@@ -300,52 +267,35 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value,
if (!pfnInCallback)
{
STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->InRZToR3); });
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_IOPORT_READ;
}
#endif
void *pvUser = pRange->pvUser;
PPDMDEVINS pDevIns = pRange->pDevIns;
- PPDMCRITSECT pCritSect = pDevIns->CTX_SUFF(pCritSect);
+ IOM_UNLOCK(pVM);
/*
- * Call the device - 4 variations.
+ * Call the device.
*/
- VBOXSTRICTRC rcStrict;
- if (pCritSect)
+ VBOXSTRICTRC rcStrict = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_HC_IOPORT_READ);
+ if (rcStrict != VINF_SUCCESS)
{
- iomUnlock(pVM);
- rcStrict = PDMCritSectEnter(pCritSect, VINF_IOM_HC_IOPORT_READ);
- if (rcStrict != VINF_SUCCESS)
- {
- STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->InRZToR3); });
- return rcStrict;
- }
+ STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->InRZToR3); });
+ return rcStrict;
+ }
#ifdef VBOX_WITH_STATISTICS
- if (pStats)
- {
- STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfIn), a);
- rcStrict = pfnInCallback(pDevIns, pvUser, Port, pu32Value, (unsigned)cbValue);
- STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfIn), a);
- }
- else
-#endif
- rcStrict = pfnInCallback(pDevIns, pvUser, Port, pu32Value, (unsigned)cbValue);
- PDMCritSectLeave(pCritSect);
+ if (pStats)
+ {
+ STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfIn), a);
+ rcStrict = pfnInCallback(pDevIns, pvUser, Port, pu32Value, (unsigned)cbValue);
+ STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfIn), a);
}
else
- {
-#ifdef VBOX_WITH_STATISTICS
- if (pStats)
- {
- STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfIn), a);
- rcStrict = pfnInCallback(pDevIns, pvUser, Port, pu32Value, (unsigned)cbValue);
- STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfIn), a);
- }
- else
#endif
- rcStrict = pfnInCallback(pDevIns, pvUser, Port, pu32Value, (unsigned)cbValue);
- }
+ rcStrict = pfnInCallback(pDevIns, pvUser, Port, pu32Value, (unsigned)cbValue);
+ PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
+
#ifdef VBOX_WITH_STATISTICS
if (rcStrict == VINF_SUCCESS && pStats)
STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(In));
@@ -365,14 +315,10 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value,
case 4: *(uint32_t *)pu32Value = UINT32_C(0xffffffff); break;
default:
AssertMsgFailed(("Invalid I/O port size %d. Port=%d\n", cbValue, Port));
- if (!pCritSect)
- iomUnlock(pVM);
return VERR_IOM_INVALID_IOPORT_SIZE;
}
}
Log3(("IOMIOPortRead: Port=%RTiop *pu32=%08RX32 cb=%d rc=%Rrc\n", Port, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rcStrict)));
- if (!pCritSect)
- iomUnlock(pVM);
return rcStrict;
}
@@ -380,14 +326,14 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value,
/*
* Handler in ring-3?
*/
- PIOMIOPORTRANGER3 pRangeR3 = iomIOPortGetRangeR3(&pVM->iom.s, Port);
+ PIOMIOPORTRANGER3 pRangeR3 = iomIOPortGetRangeR3(pVM, Port);
if (pRangeR3)
{
# ifdef VBOX_WITH_STATISTICS
if (pStats)
STAM_COUNTER_INC(&pStats->InRZToR3);
# endif
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_IOPORT_READ;
}
#endif
@@ -402,7 +348,7 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value,
{
# ifndef IN_RING3
/* Ring-3 will have to create the statistics record. */
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_IOPORT_READ;
# else
pStats = iomR3IOPortStatsCreate(pVM, Port, NULL);
@@ -420,11 +366,11 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value,
case 4: *(uint32_t *)pu32Value = UINT32_C(0xffffffff); break;
default:
AssertMsgFailed(("Invalid I/O port size %d. Port=%d\n", cbValue, Port));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VERR_IOM_INVALID_IOPORT_SIZE;
}
Log3(("IOMIOPortRead: Port=%RTiop *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", Port, *pu32Value, cbValue));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
@@ -448,12 +394,15 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value,
VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb)
{
/* Take the IOM lock before performing any device I/O. */
- int rc2 = iomLock(pVM);
+ int rc2 = IOM_LOCK(pVM);
#ifndef IN_RING3
if (rc2 == VERR_SEM_BUSY)
return VINF_IOM_HC_IOPORT_READ;
#endif
AssertRC(rc2);
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
+ IEMNotifyIOPortReadString(pVM, Port, *pGCPtrDst, *pcTransfers, cb);
+#endif
#ifdef LOG_ENABLED
const RTGCUINTREG cTransfers = *pcTransfers;
@@ -478,7 +427,7 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPt
if ( !pRange
|| (unsigned)Port - (unsigned)pRange->Port >= (unsigned)pRange->cPorts)
{
- pRange = iomIOPortGetRange(&pVM->iom.s, Port);
+ pRange = iomIOPortGetRange(pVM, Port);
if (pRange)
pVM->iom.s.CTX_SUFF(pRangeLastRead) = pRange;
}
@@ -493,52 +442,34 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPt
if (!pfnInStrCallback)
{
STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->InRZToR3); });
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_IOPORT_READ;
}
#endif
void *pvUser = pRange->pvUser;
PPDMDEVINS pDevIns = pRange->pDevIns;
- PPDMCRITSECT pCritSect = pDevIns->CTX_SUFF(pCritSect);
+ IOM_UNLOCK(pVM);
/*
- * Call the device - 4 variations.
+ * Call the device.
*/
- VBOXSTRICTRC rcStrict;
- if (pCritSect)
+ VBOXSTRICTRC rcStrict = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_HC_IOPORT_READ);
+ if (rcStrict != VINF_SUCCESS)
{
- iomUnlock(pVM);
- rcStrict = PDMCritSectEnter(pCritSect, VINF_IOM_HC_IOPORT_READ);
- if (rcStrict != VINF_SUCCESS)
- {
- STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->InRZToR3); });
- return rcStrict;
- }
+ STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->InRZToR3); });
+ return rcStrict;
+ }
#ifdef VBOX_WITH_STATISTICS
- if (pStats)
- {
- STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfIn), a);
- rcStrict = pfnInStrCallback(pDevIns, pvUser, Port, pGCPtrDst, pcTransfers, cb);
- STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfIn), a);
- }
- else
-#endif
- rcStrict = pfnInStrCallback(pDevIns, pvUser, Port, pGCPtrDst, pcTransfers, cb);
- PDMCritSectLeave(pCritSect);
+ if (pStats)
+ {
+ STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfIn), a);
+ rcStrict = pfnInStrCallback(pDevIns, pvUser, Port, pGCPtrDst, pcTransfers, cb);
+ STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfIn), a);
}
else
- {
-#ifdef VBOX_WITH_STATISTICS
- if (pStats)
- {
- STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfIn), a);
- rcStrict = pfnInStrCallback(pDevIns, pvUser, Port, pGCPtrDst, pcTransfers, cb);
- STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfIn), a);
- }
- else
#endif
- rcStrict = pfnInStrCallback(pDevIns, pvUser, Port, pGCPtrDst, pcTransfers, cb);
- }
+ rcStrict = pfnInStrCallback(pDevIns, pvUser, Port, pGCPtrDst, pcTransfers, cb);
+ PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
#ifdef VBOX_WITH_STATISTICS
if (rcStrict == VINF_SUCCESS && pStats)
@@ -550,8 +481,6 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPt
#endif
Log3(("IOMIOPortReadStr: Port=%RTiop pGCPtrDst=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=%Rrc\n",
Port, pGCPtrDst, pcTransfers, cTransfers, *pcTransfers, cb, VBOXSTRICTRC_VAL(rcStrict)));
- if (!pCritSect)
- iomUnlock(pVM);
return rcStrict;
}
@@ -559,14 +488,14 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPt
/*
* Handler in ring-3?
*/
- PIOMIOPORTRANGER3 pRangeR3 = iomIOPortGetRangeR3(&pVM->iom.s, Port);
+ PIOMIOPORTRANGER3 pRangeR3 = iomIOPortGetRangeR3(pVM, Port);
if (pRangeR3)
{
# ifdef VBOX_WITH_STATISTICS
if (pStats)
STAM_COUNTER_INC(&pStats->InRZToR3);
# endif
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_IOPORT_READ;
}
#endif
@@ -581,7 +510,7 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPt
{
# ifndef IN_RING3
/* Ring-3 will have to create the statistics record. */
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_IOPORT_READ;
# else
pStats = iomR3IOPortStatsCreate(pVM, Port, NULL);
@@ -593,7 +522,7 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPt
Log3(("IOMIOPortReadStr: Port=%RTiop pGCPtrDst=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=VINF_SUCCESS\n",
Port, pGCPtrDst, pcTransfers, cTransfers, *pcTransfers, cb));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
@@ -616,12 +545,15 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPt
VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
{
/* Take the IOM lock before performing any device I/O. */
- int rc2 = iomLock(pVM);
+ int rc2 = IOM_LOCK(pVM);
#ifndef IN_RING3
if (rc2 == VERR_SEM_BUSY)
return VINF_IOM_HC_IOPORT_WRITE;
#endif
AssertRC(rc2);
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
+ IEMNotifyIOPortWrite(pVM, Port, u32Value, cbValue);
+#endif
/** @todo bird: When I get time, I'll remove the RC/R0 trees and link the RC/R0
* entries to the ring-3 node. */
@@ -645,7 +577,7 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value,
if ( !pRange
|| (unsigned)Port - (unsigned)pRange->Port >= (unsigned)pRange->cPorts)
{
- pRange = iomIOPortGetRange(&pVM->iom.s, Port);
+ pRange = iomIOPortGetRange(pVM, Port);
if (pRange)
pVM->iom.s.CTX_SUFF(pRangeLastWrite) = pRange;
}
@@ -660,52 +592,34 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value,
if (!pfnOutCallback)
{
STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->OutRZToR3); });
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_IOPORT_WRITE;
}
#endif
- void *pvUser = pRange->pvUser;
+ void *pvUser = pRange->pvUser;
PPDMDEVINS pDevIns = pRange->pDevIns;
- PPDMCRITSECT pCritSect = pDevIns->CTX_SUFF(pCritSect);
+ IOM_UNLOCK(pVM);
/*
- * Call the device - 4 variations.
+ * Call the device.
*/
- VBOXSTRICTRC rcStrict;
- if (pCritSect)
+ VBOXSTRICTRC rcStrict = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_HC_IOPORT_WRITE);
+ if (rcStrict != VINF_SUCCESS)
{
- iomUnlock(pVM);
- rcStrict = PDMCritSectEnter(pCritSect, VINF_IOM_HC_IOPORT_WRITE);
- if (rcStrict != VINF_SUCCESS)
- {
- STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->OutRZToR3); });
- return rcStrict;
- }
+ STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->OutRZToR3); });
+ return rcStrict;
+ }
#ifdef VBOX_WITH_STATISTICS
- if (pStats)
- {
- STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfOut), a);
- rcStrict = pfnOutCallback(pDevIns, pvUser, Port, u32Value, (unsigned)cbValue);
- STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfOut), a);
- }
- else
-#endif
- rcStrict = pfnOutCallback(pDevIns, pvUser, Port, u32Value, (unsigned)cbValue);
- PDMCritSectLeave(pCritSect);
+ if (pStats)
+ {
+ STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfOut), a);
+ rcStrict = pfnOutCallback(pDevIns, pvUser, Port, u32Value, (unsigned)cbValue);
+ STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfOut), a);
}
else
- {
-#ifdef VBOX_WITH_STATISTICS
- if (pStats)
- {
- STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfOut), a);
- rcStrict = pfnOutCallback(pDevIns, pvUser, Port, u32Value, (unsigned)cbValue);
- STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfOut), a);
- }
- else
#endif
- rcStrict = pfnOutCallback(pDevIns, pvUser, Port, u32Value, (unsigned)cbValue);
- }
+ rcStrict = pfnOutCallback(pDevIns, pvUser, Port, u32Value, (unsigned)cbValue);
+ PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
#ifdef VBOX_WITH_STATISTICS
if (rcStrict == VINF_SUCCESS && pStats)
@@ -716,8 +630,6 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value,
# endif
#endif
Log3(("IOMIOPortWrite: Port=%RTiop u32=%08RX32 cb=%d rc=%Rrc\n", Port, u32Value, cbValue, VBOXSTRICTRC_VAL(rcStrict)));
- if (!pCritSect)
- iomUnlock(pVM);
return rcStrict;
}
@@ -725,14 +637,14 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value,
/*
* Handler in ring-3?
*/
- PIOMIOPORTRANGER3 pRangeR3 = iomIOPortGetRangeR3(&pVM->iom.s, Port);
+ PIOMIOPORTRANGER3 pRangeR3 = iomIOPortGetRangeR3(pVM, Port);
if (pRangeR3)
{
# ifdef VBOX_WITH_STATISTICS
if (pStats)
STAM_COUNTER_INC(&pStats->OutRZToR3);
# endif
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_IOPORT_WRITE;
}
#endif
@@ -748,7 +660,7 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value,
{
# ifndef IN_RING3
/* R3 will have to create the statistics record. */
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_IOPORT_WRITE;
# else
pStats = iomR3IOPortStatsCreate(pVM, Port, NULL);
@@ -758,7 +670,7 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value,
}
#endif
Log3(("IOMIOPortWrite: Port=%RTiop u32=%08RX32 cb=%d nop\n", Port, u32Value, cbValue));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
@@ -782,12 +694,15 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value,
VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb)
{
/* Take the IOM lock before performing any device I/O. */
- int rc2 = iomLock(pVM);
+ int rc2 = IOM_LOCK(pVM);
#ifndef IN_RING3
if (rc2 == VERR_SEM_BUSY)
return VINF_IOM_HC_IOPORT_WRITE;
#endif
AssertRC(rc2);
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
+ IEMNotifyIOPortWriteString(pVM, Port, *pGCPtrSrc, *pcTransfers, cb);
+#endif
#ifdef LOG_ENABLED
const RTGCUINTREG cTransfers = *pcTransfers;
@@ -812,7 +727,7 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCP
if ( !pRange
|| (unsigned)Port - (unsigned)pRange->Port >= (unsigned)pRange->cPorts)
{
- pRange = iomIOPortGetRange(&pVM->iom.s, Port);
+ pRange = iomIOPortGetRange(pVM, Port);
if (pRange)
pVM->iom.s.CTX_SUFF(pRangeLastWrite) = pRange;
}
@@ -827,52 +742,34 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCP
if (!pfnOutStrCallback)
{
STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->OutRZToR3); });
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_IOPORT_WRITE;
}
#endif
void *pvUser = pRange->pvUser;
PPDMDEVINS pDevIns = pRange->pDevIns;
- PPDMCRITSECT pCritSect = pDevIns->CTX_SUFF(pCritSect);
+ IOM_UNLOCK(pVM);
/*
- * Call the device - 4 variations.
+ * Call the device.
*/
- VBOXSTRICTRC rcStrict;
- if (pCritSect)
+ VBOXSTRICTRC rcStrict = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_HC_IOPORT_WRITE);
+ if (rcStrict != VINF_SUCCESS)
{
- iomUnlock(pVM);
- rcStrict = PDMCritSectEnter(pCritSect, VINF_IOM_HC_IOPORT_WRITE);
- if (rcStrict != VINF_SUCCESS)
- {
- STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->OutRZToR3); });
- return rcStrict;
- }
+ STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->OutRZToR3); });
+ return rcStrict;
+ }
#ifdef VBOX_WITH_STATISTICS
- if (pStats)
- {
- STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfOut), a);
- rcStrict = pfnOutStrCallback(pDevIns, pvUser, Port, pGCPtrSrc, pcTransfers, cb);
- STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfOut), a);
- }
- else
-#endif
- rcStrict = pfnOutStrCallback(pDevIns, pvUser, Port, pGCPtrSrc, pcTransfers, cb);
- PDMCritSectLeave(pCritSect);
+ if (pStats)
+ {
+ STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfOut), a);
+ rcStrict = pfnOutStrCallback(pDevIns, pvUser, Port, pGCPtrSrc, pcTransfers, cb);
+ STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfOut), a);
}
else
- {
-#ifdef VBOX_WITH_STATISTICS
- if (pStats)
- {
- STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfOut), a);
- rcStrict = pfnOutStrCallback(pDevIns, pvUser, Port, pGCPtrSrc, pcTransfers, cb);
- STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfOut), a);
- }
- else
#endif
- rcStrict = pfnOutStrCallback(pDevIns, pvUser, Port, pGCPtrSrc, pcTransfers, cb);
- }
+ rcStrict = pfnOutStrCallback(pDevIns, pvUser, Port, pGCPtrSrc, pcTransfers, cb);
+ PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
#ifdef VBOX_WITH_STATISTICS
if (rcStrict == VINF_SUCCESS && pStats)
@@ -884,8 +781,6 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCP
#endif
Log3(("IOMIOPortWriteStr: Port=%RTiop pGCPtrSrc=%p pcTransfer=%p:{%#x->%#x} cb=%d rcStrict=%Rrc\n",
Port, pGCPtrSrc, pcTransfers, cTransfers, *pcTransfers, cb, VBOXSTRICTRC_VAL(rcStrict)));
- if (!pCritSect)
- iomUnlock(pVM);
return rcStrict;
}
@@ -893,14 +788,14 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCP
/*
* Handler in ring-3?
*/
- PIOMIOPORTRANGER3 pRangeR3 = iomIOPortGetRangeR3(&pVM->iom.s, Port);
+ PIOMIOPORTRANGER3 pRangeR3 = iomIOPortGetRangeR3(pVM, Port);
if (pRangeR3)
{
# ifdef VBOX_WITH_STATISTICS
if (pStats)
STAM_COUNTER_INC(&pStats->OutRZToR3);
# endif
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_IOPORT_WRITE;
}
#endif
@@ -915,7 +810,7 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCP
{
# ifndef IN_RING3
/* Ring-3 will have to create the statistics record. */
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_IOPORT_WRITE;
# else
pStats = iomR3IOPortStatsCreate(pVM, Port, NULL);
@@ -927,7 +822,7 @@ VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCP
Log3(("IOMIOPortWriteStr: Port=%RTiop pGCPtrSrc=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=VINF_SUCCESS\n",
Port, pGCPtrSrc, pcTransfers, cTransfers, *pcTransfers, cb));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
@@ -1140,3 +1035,16 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretOUT(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUST
AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
return rcStrict;
}
+
+
+/**
+ * Fress an MMIO range after the reference counter has become zero.
+ *
+ * @param pVM The VM handle.
+ * @param pRange The range to free.
+ */
+void iomMmioFreeRange(PVM pVM, PIOMMMIORANGE pRange)
+{
+ MMHyperFree(pVM, pRange);
+}
+
diff --git a/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp b/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
index e9b59d856..a6aa548fb 100644
--- a/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
+++ b/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
@@ -1,4 +1,4 @@
-/* $Id: IOMAllMMIO.cpp $ */
+/* $Id: IOMAllMMIO.cpp 37467 2011-06-15 13:08:45Z vboxsync $ */
/** @file
* IOM - Input / Output Monitor - Any Context, MMIO & String I/O.
*/
@@ -28,10 +28,14 @@
#include <VBox/vmm/em.h>
#include <VBox/vmm/pgm.h>
#include <VBox/vmm/trpm.h>
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
+# include <VBox/vmm/iem.h>
+#endif
#include "IOMInternal.h"
#include <VBox/vmm/vm.h>
#include <VBox/vmm/vmm.h>
#include <VBox/vmm/hwaccm.h>
+#include "IOMInline.h"
#include <VBox/dis.h>
#include <VBox/disopcode.h>
@@ -74,17 +78,18 @@ static const unsigned g_aSize2Shift[] =
* Wrapper which does the write and updates range statistics when such are enabled.
* @warning RT_SUCCESS(rc=VINF_IOM_HC_MMIO_WRITE) is TRUE!
*/
-DECLINLINE(int) iomMMIODoWrite(PVM pVM, PIOMMMIORANGE pRange, RTGCPHYS GCPhysFault, const void *pvData, unsigned cb)
+static int iomMMIODoWrite(PVM pVM, PIOMMMIORANGE pRange, RTGCPHYS GCPhysFault, const void *pvData, unsigned cb)
{
#ifdef VBOX_WITH_STATISTICS
- PIOMMMIOSTATS pStats = iomMMIOGetStats(&pVM->iom.s, GCPhysFault, pRange);
+ PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, GCPhysFault, pRange);
Assert(pStats);
#endif
STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfWrite), a);
int rc;
if (RT_LIKELY(pRange->CTX_SUFF(pfnWriteCallback)))
- rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), GCPhysFault, (void *)pvData, cb); /** @todo fix const!! */
+ rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
+ GCPhysFault, (void *)pvData, cb); /** @todo fix const!! */
else
rc = VINF_SUCCESS;
STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a);
@@ -99,7 +104,7 @@ DECLINLINE(int) iomMMIODoWrite(PVM pVM, PIOMMMIORANGE pRange, RTGCPHYS GCPhysFau
DECLINLINE(int) iomMMIODoRead(PVM pVM, PIOMMMIORANGE pRange, RTGCPHYS GCPhys, void *pvValue, unsigned cbValue)
{
#ifdef VBOX_WITH_STATISTICS
- PIOMMMIOSTATS pStats = iomMMIOGetStats(&pVM->iom.s, GCPhys, pRange);
+ PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, GCPhys, pRange);
Assert(pStats);
#endif
@@ -298,7 +303,7 @@ DECLINLINE(int) iomRamWrite(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDs
}
-#ifdef IOM_WITH_MOVS_SUPPORT
+#if defined(IOM_WITH_MOVS_SUPPORT) && 0 /* locking prevents this from working */
/**
* [REP] MOVSB
* [REP] MOVSW
@@ -317,7 +322,8 @@ DECLINLINE(int) iomRamWrite(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDs
* @param pRange Pointer MMIO range.
* @param ppStat Which sub-sample to attribute this call to.
*/
-static int iomInterpretMOVS(PVM pVM, bool fWriteAccess, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, PIOMMMIORANGE pRange, PSTAMPROFILE *ppStat)
+static int iomInterpretMOVS(PVM pVM, bool fWriteAccess, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, PIOMMMIORANGE pRange,
+ PSTAMPROFILE *ppStat)
{
/*
* We do not support segment prefixes or REPNE.
@@ -451,7 +457,7 @@ static int iomInterpretMOVS(PVM pVM, bool fWriteAccess, PCPUMCTXCORE pRegFrame,
rc = PGMGstGetPage(pVCpu, (RTGCPTR)pu8Virt, NULL, &PhysDst);
PhysDst |= (RTGCUINTPTR)pu8Virt & PAGE_OFFSET_MASK;
if ( RT_SUCCESS(rc)
- && (pMMIODst = iomMMIOGetRange(&pVM->iom.s, PhysDst)))
+ && (pMMIODst = iomMmioGetRangeWithRef(pVM, PhysDst)))
{
/** @todo implement per-device locks for MMIO access. */
Assert(!pMMIODst->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSect));
@@ -461,7 +467,10 @@ static int iomInterpretMOVS(PVM pVM, bool fWriteAccess, PCPUMCTXCORE pRegFrame,
*/
STAM_STATS({ *ppStat = &pVM->iom.s.StatRZInstMovsMMIO; });
if (!pMMIODst->CTX_SUFF(pfnWriteCallback) && pMMIODst->pfnWriteCallbackR3)
+ {
+ iomMmioReleaseRange(pVM, pRange);
return VINF_IOM_HC_MMIO_READ_WRITE;
+ }
/* copy loop. */
while (cTransfers)
@@ -480,6 +489,7 @@ static int iomInterpretMOVS(PVM pVM, bool fWriteAccess, PCPUMCTXCORE pRegFrame,
pRegFrame->rdi += offIncrement;
cTransfers--;
}
+ iomMmioReleaseRange(pVM, pRange);
}
else
{
@@ -1059,7 +1069,7 @@ static int iomInterpretXCHG(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFaul
static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault, void *pvUser)
{
/* Take the IOM lock before performing any MMIO. */
- int rc = iomLock(pVM);
+ int rc = IOM_LOCK(pVM);
#ifndef IN_RING3
if (rc == VERR_SEM_BUSY)
return VINF_IOM_HC_MMIO_READ_WRITE;
@@ -1072,27 +1082,22 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
PIOMMMIORANGE pRange = (PIOMMMIORANGE)pvUser;
Assert(pRange);
- Assert(pRange == iomMMIOGetRange(&pVM->iom.s, GCPhysFault));
- /** @todo implement per-device locks for MMIO access. It can replace the IOM
- * lock for most of the code, provided that we retake the lock while
- * deregistering PIOMMMIORANGE to deal with remapping/access races
- * (unlikely, but an SMP guest shouldn't cause us to crash). */
- Assert(!pRange->CTX_SUFF(pDevIns) || !pRange->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSect));
+ Assert(pRange == iomMmioGetRange(pVM, GCPhysFault));
#ifdef VBOX_WITH_STATISTICS
/*
* Locate the statistics, if > PAGE_SIZE we'll use the first byte for everything.
*/
- PIOMMMIOSTATS pStats = iomMMIOGetStats(&pVM->iom.s, GCPhysFault, pRange);
+ PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, GCPhysFault, pRange);
if (!pStats)
{
# ifdef IN_RING3
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VERR_NO_MEMORY;
# else
STAM_PROFILE_STOP(&pVM->iom.s.StatRZMMIOHandler, a);
STAM_COUNTER_INC(&pVM->iom.s.StatRZMMIOFailures);
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_MMIO_READ_WRITE;
# endif
}
@@ -1121,12 +1126,25 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
STAM_PROFILE_STOP(&pVM->iom.s.StatRZMMIOHandler, a);
STAM_COUNTER_INC(&pVM->iom.s.StatRZMMIOFailures);
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_MMIO_READ_WRITE;
}
#endif /* !IN_RING3 */
/*
+ * Retain the range and do locking.
+ */
+ iomMmioRetainRange(pRange);
+ PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
+ IOM_UNLOCK(pVM);
+ rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_HC_MMIO_READ_WRITE);
+ if (rc != VINF_SUCCESS)
+ {
+ iomMmioReleaseRange(pVM, pRange);
+ return rc;
+ }
+
+ /*
* Disassemble the instruction and interpret it.
*/
PVMCPU pVCpu = VMMGetCpu(pVM);
@@ -1136,7 +1154,8 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
AssertRC(rc);
if (RT_FAILURE(rc))
{
- iomUnlock(pVM);
+ iomMmioReleaseRange(pVM, pRange);
+ PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
return rc;
}
switch (pDis->pCurInstr->opcode)
@@ -1163,11 +1182,14 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
case OP_MOVSWD:
{
if (uErrorCode == UINT32_MAX)
- return VINF_IOM_HC_MMIO_READ_WRITE;
- STAM_PROFILE_ADV_START(&pVM->iom.s.StatRZInstMovs, c);
- PSTAMPROFILE pStat = NULL;
- rc = iomInterpretMOVS(pVM, !!(uErrorCode & X86_TRAP_PF_RW), pCtxCore, GCPhysFault, pDis, pRange, &pStat);
- STAM_PROFILE_ADV_STOP_EX(&pVM->iom.s.StatRZInstMovs, pStat, c);
+ rc = VINF_IOM_HC_MMIO_READ_WRITE;
+ else
+ {
+ STAM_PROFILE_ADV_START(&pVM->iom.s.StatRZInstMovs, c);
+ PSTAMPROFILE pStat = NULL;
+ rc = iomInterpretMOVS(pVM, !!(uErrorCode & X86_TRAP_PF_RW), pCtxCore, GCPhysFault, pDis, pRange, &pStat);
+ STAM_PROFILE_ADV_STOP_EX(&pVM->iom.s.StatRZInstMovs, pStat, c);
+ }
break;
}
#endif
@@ -1266,7 +1288,8 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
}
STAM_PROFILE_STOP(&pVM->iom.s.StatRZMMIOHandler, a);
- iomUnlock(pVM);
+ iomMmioReleaseRange(pVM, pRange);
+ PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
return rc;
}
@@ -1300,16 +1323,17 @@ VMMDECL(int) IOMMMIOHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore,
*/
VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault)
{
- int rc2 = iomLock(pVM);
+ int rc2 = IOM_LOCK(pVM);
#ifndef IN_RING3
if (rc2 == VERR_SEM_BUSY)
return VINF_IOM_HC_MMIO_READ_WRITE;
#endif
- VBOXSTRICTRC rcStrict = iomMMIOHandler(pVM, (uint32_t)uErrorCode, pCtxCore, GCPhysFault, iomMMIOGetRange(&pVM->iom.s, GCPhysFault));
- iomUnlock(pVM);
+ VBOXSTRICTRC rcStrict = iomMMIOHandler(pVM, (uint32_t)uErrorCode, pCtxCore, GCPhysFault, iomMmioGetRange(pVM, GCPhysFault));
+ IOM_UNLOCK(pVM);
return VBOXSTRICTRC_VAL(rcStrict);
}
+
#ifdef IN_RING3
/**
* \#PF Handler callback for MMIO ranges.
@@ -1324,36 +1348,51 @@ VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXC
* @param enmAccessType The access type.
* @param pvUser Pointer to the MMIO range entry.
*/
-DECLCALLBACK(int) IOMR3MMIOHandler(PVM pVM, RTGCPHYS GCPhysFault, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
+DECLCALLBACK(int) IOMR3MMIOHandler(PVM pVM, RTGCPHYS GCPhysFault, void *pvPhys, void *pvBuf, size_t cbBuf,
+ PGMACCESSTYPE enmAccessType, void *pvUser)
{
PIOMMMIORANGE pRange = (PIOMMMIORANGE)pvUser;
STAM_COUNTER_INC(&pVM->iom.s.StatR3MMIOHandler);
- /* Take the IOM lock before performing any MMIO. */
- int rc = iomLock(pVM);
- AssertRC(rc);
-
AssertMsg(cbBuf == 1 || cbBuf == 2 || cbBuf == 4 || cbBuf == 8, ("%zu\n", cbBuf));
+ AssertPtr(pRange);
- Assert(pRange);
- Assert(pRange == iomMMIOGetRange(&pVM->iom.s, GCPhysFault));
- /** @todo implement per-device locks for MMIO access. It can replace the IOM
- * lock for most of the code, provided that we retake the lock while
- * deregistering PIOMMMIORANGE to deal with remapping/access races
- * (unlikely, but an SMP guest shouldn't cause us to crash). */
- Assert(!pRange->CTX_SUFF(pDevIns) || !pRange->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSect));
+ /*
+ * Validate the range.
+ */
+ int rc = IOM_LOCK(pVM);
+ AssertRC(rc);
+ Assert(pRange == iomMmioGetRange(pVM, GCPhysFault));
+
+ /*
+ * Perform locking.
+ */
+ iomMmioRetainRange(pRange);
+ PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
+ IOM_UNLOCK(pVM);
+ rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_HC_MMIO_READ_WRITE);
+ if (rc != VINF_SUCCESS)
+ {
+ iomMmioReleaseRange(pVM, pRange);
+ return rc;
+ }
+ /*
+ * Perform the access.
+ */
if (enmAccessType == PGMACCESSTYPE_READ)
rc = iomMMIODoRead(pVM, pRange, GCPhysFault, pvBuf, (unsigned)cbBuf);
else
rc = iomMMIODoWrite(pVM, pRange, GCPhysFault, pvBuf, (unsigned)cbBuf);
AssertRC(rc);
- iomUnlock(pVM);
+ iomMmioReleaseRange(pVM, pRange);
+ PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
return rc;
}
#endif /* IN_RING3 */
+
/**
* Reads a MMIO register.
*
@@ -1367,30 +1406,31 @@ DECLCALLBACK(int) IOMR3MMIOHandler(PVM pVM, RTGCPHYS GCPhysFault, void *pvPhys,
VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue)
{
/* Take the IOM lock before performing any MMIO. */
- int rc = iomLock(pVM);
+ int rc = IOM_LOCK(pVM);
#ifndef IN_RING3
if (rc == VERR_SEM_BUSY)
return VINF_IOM_HC_MMIO_WRITE;
#endif
AssertRC(rc);
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
+ IEMNotifyMMIORead(pVM, GCPhys, cbValue);
+#endif
/*
* Lookup the current context range node and statistics.
*/
- PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhys);
+ PIOMMMIORANGE pRange = iomMmioGetRange(pVM, GCPhys);
AssertMsg(pRange, ("Handlers and page tables are out of sync or something! GCPhys=%RGp cbValue=%d\n", GCPhys, cbValue));
if (!pRange)
{
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VERR_INTERNAL_ERROR;
}
- /** @todo implement per-device locks for MMIO access. */
- Assert(!pRange->CTX_SUFF(pDevIns) || !pRange->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSect));
#ifdef VBOX_WITH_STATISTICS
- PIOMMMIOSTATS pStats = iomMMIOGetStats(&pVM->iom.s, GCPhys, pRange);
+ PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, GCPhys, pRange);
if (!pStats)
{
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
# ifdef IN_RING3
return VERR_NO_MEMORY;
# else
@@ -1403,6 +1443,19 @@ VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value,
if (pRange->CTX_SUFF(pfnReadCallback))
{
/*
+ * Perform locking.
+ */
+ iomMmioRetainRange(pRange);
+ PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
+ IOM_UNLOCK(pVM);
+ rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_HC_MMIO_WRITE);
+ if (rc != VINF_SUCCESS)
+ {
+ iomMmioReleaseRange(pVM, pRange);
+ return rc;
+ }
+
+ /*
* Perform the read and deal with the result.
*/
STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfRead), a);
@@ -1412,7 +1465,8 @@ VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value,
{
case VINF_SUCCESS:
Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", GCPhys, *pu32Value, cbValue));
- iomUnlock(pVM);
+ iomMmioReleaseRange(pVM, pRange);
+ PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
return rc;
#ifndef IN_RING3
case VINF_IOM_HC_MMIO_READ:
@@ -1421,61 +1475,64 @@ VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value,
#endif
default:
Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, rc));
- iomUnlock(pVM);
+ iomMmioReleaseRange(pVM, pRange);
+ PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
return rc;
case VINF_IOM_MMIO_UNUSED_00:
switch (cbValue)
{
- case 1: *(uint8_t *)pu32Value = UINT8_C(0x00); break;
+ case 1: *(uint8_t *)pu32Value = UINT8_C(0x00); break;
case 2: *(uint16_t *)pu32Value = UINT16_C(0x0000); break;
case 4: *(uint32_t *)pu32Value = UINT32_C(0x00000000); break;
case 8: *(uint64_t *)pu32Value = UINT64_C(0x0000000000000000); break;
default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break;
}
Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, rc));
- iomUnlock(pVM);
+ iomMmioReleaseRange(pVM, pRange);
+ PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
return VINF_SUCCESS;
case VINF_IOM_MMIO_UNUSED_FF:
switch (cbValue)
{
- case 1: *(uint8_t *)pu32Value = UINT8_C(0xff); break;
+ case 1: *(uint8_t *)pu32Value = UINT8_C(0xff); break;
case 2: *(uint16_t *)pu32Value = UINT16_C(0xffff); break;
case 4: *(uint32_t *)pu32Value = UINT32_C(0xffffffff); break;
case 8: *(uint64_t *)pu32Value = UINT64_C(0xffffffffffffffff); break;
default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break;
}
Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, rc));
- iomUnlock(pVM);
+ iomMmioReleaseRange(pVM, pRange);
+ PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
return VINF_SUCCESS;
}
+ /* not reached */
}
#ifndef IN_RING3
if (pRange->pfnReadCallbackR3)
{
STAM_COUNTER_INC(&pStats->CTX_MID_Z(Read,ToR3));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_MMIO_READ;
}
#endif
/*
- * Lookup the ring-3 range.
+ * Unassigned memory - this is actually not supposed t happen...
*/
STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfRead), a); /** @todo STAM_PROFILE_ADD_ZERO_PERIOD */
STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfRead), a);
- /* Unassigned memory; this is actually not supposed to happen. */
switch (cbValue)
{
- case 1: *(uint8_t *)pu32Value = UINT8_C(0xff); break;
+ case 1: *(uint8_t *)pu32Value = UINT8_C(0xff); break;
case 2: *(uint16_t *)pu32Value = UINT16_C(0xffff); break;
case 4: *(uint32_t *)pu32Value = UINT32_C(0xffffffff); break;
case 8: *(uint64_t *)pu32Value = UINT64_C(0xffffffffffffffff); break;
default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break;
}
Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", GCPhys, *pu32Value, cbValue));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
@@ -1493,30 +1550,31 @@ VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value,
VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue)
{
/* Take the IOM lock before performing any MMIO. */
- int rc = iomLock(pVM);
+ int rc = IOM_LOCK(pVM);
#ifndef IN_RING3
if (rc == VERR_SEM_BUSY)
return VINF_IOM_HC_MMIO_WRITE;
#endif
AssertRC(rc);
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
+ IEMNotifyMMIOWrite(pVM, GCPhys, u32Value, cbValue);
+#endif
/*
* Lookup the current context range node.
*/
- PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhys);
+ PIOMMMIORANGE pRange = iomMmioGetRange(pVM, GCPhys);
AssertMsg(pRange, ("Handlers and page tables are out of sync or something! GCPhys=%RGp cbValue=%d\n", GCPhys, cbValue));
if (!pRange)
{
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VERR_INTERNAL_ERROR;
}
- /** @todo implement per-device locks for MMIO access. */
- Assert(!pRange->CTX_SUFF(pDevIns) || !pRange->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSect));
#ifdef VBOX_WITH_STATISTICS
- PIOMMMIOSTATS pStats = iomMMIOGetStats(&pVM->iom.s, GCPhys, pRange);
+ PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, GCPhys, pRange);
if (!pStats)
{
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
# ifdef IN_RING3
return VERR_NO_MEMORY;
# else
@@ -1526,14 +1584,27 @@ VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value,
STAM_COUNTER_INC(&pStats->Accesses);
#endif /* VBOX_WITH_STATISTICS */
- /*
- * Perform the write if there's a write handler. R0/GC may have
- * to defer it to ring-3.
- */
if (pRange->CTX_SUFF(pfnWriteCallback))
{
+ /*
+ * Perform locking.
+ */
+ iomMmioRetainRange(pRange);
+ PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
+ IOM_UNLOCK(pVM);
+ rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_HC_MMIO_READ);
+ if (rc != VINF_SUCCESS)
+ {
+ iomMmioReleaseRange(pVM, pRange);
+ return rc;
+ }
+
+ /*
+ * Perform the write.
+ */
STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfWrite), a);
- rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), GCPhys, &u32Value, (unsigned)cbValue);
+ rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
+ GCPhys, &u32Value, (unsigned)cbValue);
STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a);
#ifndef IN_RING3
if ( rc == VINF_IOM_HC_MMIO_WRITE
@@ -1541,14 +1612,15 @@ VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value,
STAM_COUNTER_INC(&pStats->CTX_MID_Z(Write,ToR3));
#endif
Log4(("IOMMMIOWrite: GCPhys=%RGp u32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, u32Value, cbValue, rc));
- iomUnlock(pVM);
+ iomMmioReleaseRange(pVM, pRange);
+ PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
return rc;
}
#ifndef IN_RING3
if (pRange->pfnWriteCallbackR3)
{
STAM_COUNTER_INC(&pStats->CTX_MID_Z(Write,ToR3));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_IOM_HC_MMIO_WRITE;
}
#endif
@@ -1559,10 +1631,11 @@ VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value,
STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfWrite), a);
STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a);
Log4(("IOMMMIOWrite: GCPhys=%RGp u32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, u32Value, cbValue, VINF_SUCCESS));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
+
/**
* [REP*] INSB/INSW/INSD
* ES:EDI,DX[,ECX]
@@ -1890,8 +1963,8 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUS
return IOMInterpretOUTSEx(pVM, pRegFrame, Port, pCpu->prefix, cb);
}
-
#ifndef IN_RC
+
/**
* Mapping an MMIO2 page in place of an MMIO page for direct access.
*
@@ -1908,11 +1981,8 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUS
VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapped, uint64_t fPageFlags)
{
/* Currently only called from the VGA device during MMIO. */
- Assert(IOMIsLockOwner(pVM));
Log(("IOMMMIOMapMMIO2Page %RGp -> %RGp flags=%RX64\n", GCPhys, GCPhysRemapped, fPageFlags));
-
AssertReturn(fPageFlags == (X86_PTE_RW | X86_PTE_P), VERR_INVALID_PARAMETER);
-
PVMCPU pVCpu = VMMGetCpu(pVM);
/* This currently only works in real mode, protected mode without paging or with nested paging. */
@@ -1921,10 +1991,12 @@ VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapp
&& !HWACCMIsNestedPagingActive(pVM)))
return VINF_SUCCESS; /* ignore */
+ IOM_LOCK(pVM);
+
/*
* Lookup the context range node the page belongs to.
*/
- PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhys);
+ PIOMMMIORANGE pRange = iomMmioGetRange(pVM, GCPhys);
AssertMsgReturn(pRange,
("Handlers and page tables are out of sync or something! GCPhys=%RGp\n", GCPhys), VERR_IOM_MMIO_RANGE_NOT_FOUND);
@@ -1938,6 +2010,8 @@ VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapp
GCPhysRemapped &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
int rc = PGMHandlerPhysicalPageAlias(pVM, pRange->GCPhys, GCPhys, GCPhysRemapped);
+
+ IOM_UNLOCK(pVM);
AssertRCReturn(rc, rc);
/*
@@ -1959,6 +2033,7 @@ VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapp
return VINF_SUCCESS;
}
+
/**
* Mapping a HC page in place of an MMIO page for direct access.
*
@@ -1987,7 +2062,7 @@ VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uin
*/
#ifdef VBOX_STRICT
/* Can't lock IOM here due to potential deadlocks in the VGA device; not safe to access. */
- PIOMMMIORANGE pRange = iomMMIOGetRangeUnsafe(&pVM->iom.s, GCPhys);
+ PIOMMMIORANGE pRange = iomMMIOGetRangeUnsafe(pVM, GCPhys);
AssertMsgReturn(pRange,
("Handlers and page tables are out of sync or something! GCPhys=%RGp\n", GCPhys), VERR_IOM_MMIO_RANGE_NOT_FOUND);
Assert((pRange->GCPhys & PAGE_OFFSET_MASK) == 0);
@@ -2014,6 +2089,7 @@ VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uin
return VINF_SUCCESS;
}
+
/**
* Reset a previously modified MMIO region; restore the access flags.
*
@@ -2039,7 +2115,7 @@ VMMDECL(int) IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys)
*/
#ifdef VBOX_STRICT
/* Can't lock IOM here due to potential deadlocks in the VGA device; not safe to access. */
- PIOMMMIORANGE pRange = iomMMIOGetRangeUnsafe(&pVM->iom.s, GCPhys);
+ PIOMMMIORANGE pRange = iomMMIOGetRangeUnsafe(pVM, GCPhys);
AssertMsgReturn(pRange,
("Handlers and page tables are out of sync or something! GCPhys=%RGp\n", GCPhys), VERR_IOM_MMIO_RANGE_NOT_FOUND);
Assert((pRange->GCPhys & PAGE_OFFSET_MASK) == 0);
@@ -2073,5 +2149,6 @@ VMMDECL(int) IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys)
#endif
return rc;
}
+
#endif /* !IN_RC */
diff --git a/src/VBox/VMM/VMMAll/MMAll.cpp b/src/VBox/VMM/VMMAll/MMAll.cpp
index 7057700e8..4620cdbb2 100644
--- a/src/VBox/VMM/VMMAll/MMAll.cpp
+++ b/src/VBox/VMM/VMMAll/MMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: MMAll.cpp $ */
+/* $Id: MMAll.cpp 35410 2011-01-05 17:21:11Z vboxsync $ */
/** @file
* MM - Memory Manager - Any Context.
*/
diff --git a/src/VBox/VMM/VMMAll/MMAllHyper.cpp b/src/VBox/VMM/VMMAll/MMAllHyper.cpp
index 88d1a1449..52010a2e9 100644
--- a/src/VBox/VMM/VMMAll/MMAllHyper.cpp
+++ b/src/VBox/VMM/VMMAll/MMAllHyper.cpp
@@ -1,4 +1,4 @@
-/* $Id: MMAllHyper.cpp $ */
+/* $Id: MMAllHyper.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* MM - Memory Manager - Hypervisor Memory Area, All Contexts.
*/
diff --git a/src/VBox/VMM/VMMAll/MMAllPagePool.cpp b/src/VBox/VMM/VMMAll/MMAllPagePool.cpp
index af56bd2a9..4357f7d28 100644
--- a/src/VBox/VMM/VMMAll/MMAllPagePool.cpp
+++ b/src/VBox/VMM/VMMAll/MMAllPagePool.cpp
@@ -1,4 +1,4 @@
-/* $Id: MMAllPagePool.cpp $ */
+/* $Id: MMAllPagePool.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* MM - Memory Manager - Page Pool.
*
diff --git a/src/VBox/VMM/VMMAll/PATMAll.cpp b/src/VBox/VMM/VMMAll/PATMAll.cpp
index f7b7b11ec..1e975f11e 100644
--- a/src/VBox/VMM/VMMAll/PATMAll.cpp
+++ b/src/VBox/VMM/VMMAll/PATMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: PATMAll.cpp $ */
+/* $Id: PATMAll.cpp 35348 2010-12-27 16:35:23Z vboxsync $ */
/** @file
* PATM - The Patch Manager, all contexts.
*/
diff --git a/src/VBox/VMM/VMMAll/PDMAll.cpp b/src/VBox/VMM/VMMAll/PDMAll.cpp
index 4291441c0..3a385f3f1 100644
--- a/src/VBox/VMM/VMMAll/PDMAll.cpp
+++ b/src/VBox/VMM/VMMAll/PDMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMAll.cpp $ */
+/* $Id: PDMAll.cpp 37475 2011-06-15 16:42:55Z vboxsync $ */
/** @file
* PDM Critical Sections
*/
@@ -45,7 +45,7 @@ VMMDECL(int) PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt)
pdmLock(pVM);
/*
- * The local APIC has a higer priority than the PIC.
+ * The local APIC has a higher priority than the PIC.
*/
if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC))
{
@@ -300,8 +300,9 @@ VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending)
return VERR_PDM_NO_APIC_INSTANCE;
}
+
/**
- * Write MSR in APIC range.
+ * Write a MSR in APIC range.
*
* @returns VBox status code.
* @param pVM VM handle.
@@ -313,17 +314,15 @@ VMMDECL(int) PDMApicWriteMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u6
{
if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
{
- Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMSR));
- pdmLock(pVM);
- pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, u64Value);
- pdmUnlock(pVM);
- return VINF_SUCCESS;
+ AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMSR));
+ return pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, u64Value);
}
return VERR_PDM_NO_APIC_INSTANCE;
}
+
/**
- * Read MSR in APIC range.
+ * Read a MSR in APIC range.
*
* @returns VBox status code.
* @param pVM VM handle.
@@ -335,11 +334,11 @@ VMMDECL(int) PDMApicReadMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu
{
if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
{
- Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR));
+ AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR));
pdmLock(pVM);
- pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, pu64Value);
+ int rc = pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, pu64Value);
pdmUnlock(pVM);
- return VINF_SUCCESS;
+ return rc;
}
return VERR_PDM_NO_APIC_INSTANCE;
}
diff --git a/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp b/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp
index 1b3c6fb0e..48049db29 100644
--- a/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp
+++ b/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMAllCritSect.cpp $ */
+/* $Id: PDMAllCritSect.cpp 38059 2011-07-19 09:34:44Z vboxsync $ */
/** @file
* PDM - Critical Sections, All Contexts.
*/
@@ -194,8 +194,12 @@ DECL_FORCE_INLINE(int) pdmCritSectEnter(PPDMCRITSECT pCritSect, int rcBusy, PCRT
/*
* See if we're lucky.
*/
+ /* NOP ... */
+ if (pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NOP)
+ return VINF_SUCCESS;
+
RTNATIVETHREAD hNativeSelf = pdmCritSectGetNativeSelf(pCritSect);
- /* Not owned ... */
+ /* ... not owned ... */
if (ASMAtomicCmpXchgS32(&pCritSect->s.Core.cLockers, 0, -1))
return pdmCritSectEnterFirst(pCritSect, hNativeSelf, pSrcPos);
@@ -205,7 +209,6 @@ DECL_FORCE_INLINE(int) pdmCritSectEnter(PPDMCRITSECT pCritSect, int rcBusy, PCRT
ASMAtomicIncS32(&pCritSect->s.Core.cLockers);
ASMAtomicIncS32(&pCritSect->s.Core.cNestings);
Assert(pCritSect->s.Core.cNestings > 1);
- ASMAtomicAndU32(&pCritSect->s.Core.fFlags, ~PDMCRITSECT_FLAGS_PENDING_UNLOCK);
return VINF_SUCCESS;
}
@@ -233,14 +236,15 @@ DECL_FORCE_INLINE(int) pdmCritSectEnter(PPDMCRITSECT pCritSect, int rcBusy, PCRT
*/
return pdmR3R0CritSectEnterContended(pCritSect, hNativeSelf, pSrcPos);
-#elif defined(IN_RING0)
+#else
+# ifdef IN_RING0
/** @todo If preemption is disabled it means we're in VT-x/AMD-V context
* and would be better off switching out of that while waiting for
* the lock. Several of the locks jumps back to ring-3 just to
* get the lock, the ring-3 code will then call the kernel to do
* the lock wait and when the call return it will call ring-0
* again and resume via in setjmp style. Not very efficient. */
-# if 0
+# if 0
if (ASMIntAreEnabled()) /** @todo this can be handled as well by changing
* callers not prepared for longjmp/blocking to
* use PDMCritSectTryEnter. */
@@ -269,27 +273,34 @@ DECL_FORCE_INLINE(int) pdmCritSectEnter(PPDMCRITSECT pCritSect, int rcBusy, PCRT
}
return rc;
}
-# else
+# else
/*
* We preemption hasn't been disabled, we can block here in ring-0.
*/
if ( RTThreadPreemptIsEnabled(NIL_RTTHREAD)
&& ASMIntAreEnabled())
return pdmR3R0CritSectEnterContended(pCritSect, hNativeSelf, pSrcPos);
-# endif
+# endif
+#endif /* IN_RING0 */
STAM_REL_COUNTER_INC(&pCritSect->s.StatContentionRZLock);
- LogFlow(("PDMCritSectEnter: locked => R3 (%Rrc)\n", rcBusy));
- return rcBusy;
-#else /* IN_RC */
+ /*
+ * Call ring-3 to acquire the critical section?
+ */
+ if (rcBusy == VINF_SUCCESS)
+ {
+ PVM pVM = pCritSect->s.CTX_SUFF(pVM); AssertPtr(pVM);
+ PVMCPU pVCpu = VMMGetCpu(pVM); AssertPtr(pVCpu);
+ return VMMRZCallRing3(pVM, pVCpu, VMMCALLRING3_PDM_CRIT_SECT_ENTER, MMHyperCCToR3(pVM, pCritSect));
+ }
+
/*
* Return busy.
*/
- STAM_REL_COUNTER_INC(&pCritSect->s.StatContentionRZLock);
LogFlow(("PDMCritSectEnter: locked => R3 (%Rrc)\n", rcBusy));
return rcBusy;
-#endif /* IN_RC */
+#endif /* !IN_RING3 */
}
@@ -302,7 +313,9 @@ DECL_FORCE_INLINE(int) pdmCritSectEnter(PPDMCRITSECT pCritSect, int rcBusy, PCRT
*
* @param pCritSect The PDM critical section to enter.
* @param rcBusy The status code to return when we're in GC or R0
- * and the section is busy.
+ * and the section is busy. Pass VINF_SUCCESS to
+ * acquired the critical section thru a ring-3
+ * call if necessary.
*/
VMMDECL(int) PDMCritSectEnter(PPDMCRITSECT pCritSect, int rcBusy)
{
@@ -324,7 +337,9 @@ VMMDECL(int) PDMCritSectEnter(PPDMCRITSECT pCritSect, int rcBusy)
*
* @param pCritSect The PDM critical section to enter.
* @param rcBusy The status code to return when we're in GC or R0
- * and the section is busy.
+ * and the section is busy. Pass VINF_SUCCESS to
+ * acquired the critical section thru a ring-3
+ * call if necessary.
* @param uId Some kind of locking location ID. Typically a
* return address up the stack. Optional (0).
* @param pszFile The file where the lock is being acquired from.
@@ -366,8 +381,12 @@ static int pdmCritSectTryEnter(PPDMCRITSECT pCritSect, PCRTLOCKVALSRCPOS pSrcPos
/*
* See if we're lucky.
*/
+ /* NOP ... */
+ if (pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NOP)
+ return VINF_SUCCESS;
+
RTNATIVETHREAD hNativeSelf = pdmCritSectGetNativeSelf(pCritSect);
- /* Not owned ... */
+ /* ... not owned ... */
if (ASMAtomicCmpXchgS32(&pCritSect->s.Core.cLockers, 0, -1))
return pdmCritSectEnterFirst(pCritSect, hNativeSelf, pSrcPos);
@@ -377,7 +396,6 @@ static int pdmCritSectTryEnter(PPDMCRITSECT pCritSect, PCRTLOCKVALSRCPOS pSrcPos
ASMAtomicIncS32(&pCritSect->s.Core.cLockers);
ASMAtomicIncS32(&pCritSect->s.Core.cNestings);
Assert(pCritSect->s.Core.cNestings > 1);
- ASMAtomicAndU32(&pCritSect->s.Core.fFlags, ~PDMCRITSECT_FLAGS_PENDING_UNLOCK);
return VINF_SUCCESS;
}
@@ -478,7 +496,28 @@ VMMDECL(void) PDMCritSectLeave(PPDMCRITSECT pCritSect)
{
AssertMsg(pCritSect->s.Core.u32Magic == RTCRITSECT_MAGIC, ("%p %RX32\n", pCritSect, pCritSect->s.Core.u32Magic));
Assert(pCritSect->s.Core.u32Magic == RTCRITSECT_MAGIC);
- Assert(pCritSect->s.Core.NativeThreadOwner == pdmCritSectGetNativeSelf(pCritSect));
+
+ /* Check for NOP sections before asserting ownership. */
+ if (pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NOP)
+ return;
+
+ /*
+ * Always check that the caller is the owner (screw performance).
+ */
+ RTNATIVETHREAD const hNativeSelf = pdmCritSectGetNativeSelf(pCritSect);
+ if (RT_UNLIKELY(pCritSect->s.Core.NativeThreadOwner != hNativeSelf))
+ {
+#if 1
+ AssertMsgFailed(("%p %s: %p != %p; cLockers=%d cNestings=%d\n", pCritSect, R3STRING(pCritSect->s.pszName),
+ pCritSect->s.Core.NativeThreadOwner, hNativeSelf,
+ pCritSect->s.Core.cLockers, pCritSect->s.Core.cNestings));
+#else
+ AssertReleaseMsgFailed(("%p %s: %p != %p; cLockers=%d cNestings=%d\n", pCritSect, R3STRING(pCritSect->s.pszName),
+ pCritSect->s.Core.NativeThreadOwner, hNativeSelf,
+ pCritSect->s.Core.cLockers, pCritSect->s.Core.cNestings));
+#endif
+ return;
+ }
Assert(pCritSect->s.Core.cNestings >= 1);
/*
@@ -489,6 +528,7 @@ VMMDECL(void) PDMCritSectLeave(PPDMCRITSECT pCritSect)
ASMAtomicDecS32(&pCritSect->s.Core.cNestings);
Assert(pCritSect->s.Core.cNestings >= 1);
ASMAtomicDecS32(&pCritSect->s.Core.cLockers);
+ Assert(pCritSect->s.Core.cLockers >= 0);
return;
}
@@ -636,7 +676,8 @@ VMMDECL(bool) PDMCritSectIsOwner(PCPDMCRITSECT pCritSect)
PVMCPU pVCpu = VMMGetCpu(pVM); AssertPtr(pVCpu);
if (pCritSect->s.Core.NativeThreadOwner != pVCpu->hNativeThread)
return false;
- return (pCritSect->s.Core.fFlags & PDMCRITSECT_FLAGS_PENDING_UNLOCK) == 0;
+ return (pCritSect->s.Core.fFlags & PDMCRITSECT_FLAGS_PENDING_UNLOCK) == 0
+ || pCritSect->s.Core.cNestings > 1;
#endif
}
@@ -647,42 +688,24 @@ VMMDECL(bool) PDMCritSectIsOwner(PCPDMCRITSECT pCritSect)
* @returns true if owner.
* @returns false if not owner.
* @param pCritSect The critical section.
- * @param idCpu VCPU id
+ * @param pVCpu The virtual CPU handle.
*/
-VMMDECL(bool) PDMCritSectIsOwnerEx(PCPDMCRITSECT pCritSect, VMCPUID idCpu)
+VMMDECL(bool) PDMCritSectIsOwnerEx(PCPDMCRITSECT pCritSect, PVMCPU pVCpu)
{
#ifdef IN_RING3
- NOREF(idCpu);
+ NOREF(pVCpu);
return RTCritSectIsOwner(&pCritSect->s.Core);
#else
- PVM pVM = pCritSect->s.CTX_SUFF(pVM);
- AssertPtr(pVM);
- Assert(idCpu < pVM->cCpus);
- return pCritSect->s.Core.NativeThreadOwner == pVM->aCpus[idCpu].hNativeThread
- && (pCritSect->s.Core.fFlags & PDMCRITSECT_FLAGS_PENDING_UNLOCK) == 0;
+ Assert(&pVCpu->CTX_SUFF(pVM)->aCpus[pVCpu->idCpu] == pVCpu);
+ if (pCritSect->s.Core.NativeThreadOwner != pVCpu->hNativeThread)
+ return false;
+ return (pCritSect->s.Core.fFlags & PDMCRITSECT_FLAGS_PENDING_UNLOCK) == 0
+ || pCritSect->s.Core.cNestings > 1;
#endif
}
/**
- * Checks if somebody currently owns the critical section.
- *
- * @returns true if locked.
- * @returns false if not locked.
- *
- * @param pCritSect The critical section.
- *
- * @remarks This doesn't prove that no deadlocks will occur later on; it's
- * just a debugging tool
- */
-VMMDECL(bool) PDMCritSectIsOwned(PCPDMCRITSECT pCritSect)
-{
- return pCritSect->s.Core.NativeThreadOwner != NIL_RTNATIVETHREAD
- && (pCritSect->s.Core.fFlags & PDMCRITSECT_FLAGS_PENDING_UNLOCK) == 0;
-}
-
-
-/**
* Checks if anyone is waiting on the critical section we own.
*
* @returns true if someone is waiting.
diff --git a/src/VBox/VMM/VMMAll/PDMAllQueue.cpp b/src/VBox/VMM/VMMAll/PDMAllQueue.cpp
index e81b49b57..824f54ce3 100644
--- a/src/VBox/VMM/VMMAll/PDMAllQueue.cpp
+++ b/src/VBox/VMM/VMMAll/PDMAllQueue.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMAllQueue.cpp $ */
+/* $Id: PDMAllQueue.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* PDM Queue - Transport data and tasks to EMT and R3.
*/
diff --git a/src/VBox/VMM/VMMAll/PGMAll.cpp b/src/VBox/VMM/VMMAll/PGMAll.cpp
index e1aed7136..620dab8a1 100644
--- a/src/VBox/VMM/VMMAll/PGMAll.cpp
+++ b/src/VBox/VMM/VMMAll/PGMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMAll.cpp $ */
+/* $Id: PGMAll.cpp 37452 2011-06-14 18:13:48Z vboxsync $ */
/** @file
* PGM - Page Manager and Monitor - All context code.
*/
@@ -456,7 +456,7 @@ VMMDECL(int) PGMTrap0eHandler(PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFram
int rc = PGM_BTH_PFN(Trap0eHandler, pVCpu)(pVCpu, uErr, pRegFrame, pvFault, &fLockTaken);
if (fLockTaken)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
pgmUnlock(pVM);
}
LogFlow(("PGMTrap0eHandler: uErr=%RGx pvFault=%RGv rc=%Rrc\n", uErr, pvFault, rc));
@@ -733,7 +733,7 @@ VMMDECL(int) PGMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCPtrPage)
/*
* Check for conflicts and pending CR3 monitoring updates.
*/
- if (pgmMapAreMappingsFloating(&pVM->pgm.s))
+ if (pgmMapAreMappingsFloating(pVM))
{
if ( pgmGetMapping(pVM, GCPtrPage)
&& PGMGstGetPage(pVCpu, GCPtrPage, NULL, NULL) != VERR_PAGE_TABLE_NOT_PRESENT)
@@ -932,7 +932,7 @@ int pgmShwSyncPaePDPtr(PVMCPU pVCpu, RTGCPTR GCPtr, X86PGPAEUINT uGstPdpe, PX86P
PPGMPOOLPAGE pShwPage;
int rc;
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/* Allocate page directory if not present. */
if ( !pPdpe->n.u1Present
@@ -1019,7 +1019,7 @@ DECLINLINE(int) pgmShwGetPaePoolPagePD(PVMCPU pVCpu, RTGCPTR GCPtr, PPGMPOOLPAGE
PX86PDPT pPdpt = pgmShwGetPaePDPTPtr(pVCpu);
PVM pVM = pVCpu->CTX_SUFF(pVM);
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
AssertReturn(pPdpt, VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT); /* can't happen */
if (!pPdpt->a[iPdPt].n.u1Present)
@@ -1065,7 +1065,7 @@ static int pgmShwSyncLongModePDPtr(PVMCPU pVCpu, RTGCPTR64 GCPtr, X86PGPAEUINT u
PPGMPOOLPAGE pShwPage;
int rc;
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/* Allocate page directory pointer table if not present. */
if ( !pPml4e->n.u1Present
@@ -1159,7 +1159,7 @@ DECLINLINE(int) pgmShwGetLongModePDPtr(PVMCPU pVCpu, RTGCPTR64 GCPtr, PX86PML4E
const unsigned iPml4 = (GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK;
PCX86PML4E pPml4e = pgmShwGetLongModePML4EPtr(pVCpu, iPml4);
- Assert(PGMIsLockOwner(PGMCPU2VM(pPGM)));
+ PGM_LOCK_ASSERT_OWNER(PGMCPU2VM(pPGM));
AssertReturn(pPml4e, VERR_INTERNAL_ERROR);
if (ppPml4e)
@@ -1210,7 +1210,7 @@ static int pgmShwGetEPTPDPtr(PVMCPU pVCpu, RTGCPTR64 GCPtr, PEPTPDPT *ppPdpt, PE
int rc;
Assert(pVM->pgm.s.fNestedPaging);
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
pPml4 = (PEPTPML4)PGMPOOL_PAGE_2_PTR_V2(pVM, pVCpu, pVCpu->pgm.s.CTX_SUFF(pShwPageCR3));
Assert(pPml4);
@@ -1288,7 +1288,7 @@ static int pgmShwGetEPTPDPtr(PVMCPU pVCpu, RTGCPTR64 GCPtr, PEPTPDPT *ppPdpt, PE
*/
int pgmShwSyncNestedPageLocked(PVMCPU pVCpu, RTGCPHYS GCPhysFault, uint32_t cPages, PGMMODE enmShwPagingMode)
{
- Assert(PGMIsLockOwner(pVCpu->CTX_SUFF(pVM)));
+ PGM_LOCK_ASSERT_OWNER(pVCpu->CTX_SUFF(pVM));
int rc;
switch (enmShwPagingMode)
@@ -1340,7 +1340,7 @@ int pgmShwSyncNestedPageLocked(PVMCPU pVCpu, RTGCPHYS GCPhysFault, uint32_t cPag
* purpose.
*
* @returns VBox status.
- * @param pVCpu VMCPU handle.
+ * @param pVCpu The current CPU.
* @param GCPtr Guest Context virtual address of the page.
* @param pfFlags Where to store the flags. These are X86_PTE_*, even for big pages.
* @param pGCPhys Where to store the GC physical address of the page.
@@ -1348,6 +1348,7 @@ int pgmShwSyncNestedPageLocked(PVMCPU pVCpu, RTGCPHYS GCPhysFault, uint32_t cPag
*/
VMMDECL(int) PGMGstGetPage(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys)
{
+ VMCPU_ASSERT_EMT(pVCpu);
return PGM_GST_PFN(GetPage, pVCpu)(pVCpu, GCPtr, pfFlags, pGCPhys);
}
@@ -1362,6 +1363,7 @@ VMMDECL(int) PGMGstGetPage(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGC
*/
VMMDECL(bool) PGMGstIsPagePresent(PVMCPU pVCpu, RTGCPTR GCPtr)
{
+ VMCPU_ASSERT_EMT(pVCpu);
int rc = PGMGstGetPage(pVCpu, GCPtr, NULL, NULL);
return RT_SUCCESS(rc);
}
@@ -1378,6 +1380,7 @@ VMMDECL(bool) PGMGstIsPagePresent(PVMCPU pVCpu, RTGCPTR GCPtr)
*/
VMMDECL(int) PGMGstSetPage(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags)
{
+ VMCPU_ASSERT_EMT(pVCpu);
return PGMGstModifyPage(pVCpu, GCPtr, cb, fFlags, 0);
}
@@ -1398,6 +1401,7 @@ VMMDECL(int) PGMGstSetPage(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFl
VMMDECL(int) PGMGstModifyPage(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask)
{
STAM_PROFILE_START(&pVCpu->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,GstModifyPage), a);
+ VMCPU_ASSERT_EMT(pVCpu);
/*
* Validate input.
@@ -1443,7 +1447,7 @@ int pgmGstLazyMap32BitPD(PVMCPU pVCpu, PX86PD *ppPd)
RTGCPHYS GCPhysCR3 = pVCpu->pgm.s.GCPhysCR3 & X86_CR3_PAGE_MASK;
PPGMPAGE pPage;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhysCR3, &pPage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhysCR3, &pPage);
if (RT_SUCCESS(rc))
{
RTHCPTR HCPtrGuestCR3;
@@ -1485,7 +1489,7 @@ int pgmGstLazyMapPaePDPT(PVMCPU pVCpu, PX86PDPT *ppPdpt)
RTGCPHYS GCPhysCR3 = pVCpu->pgm.s.GCPhysCR3 & X86_CR3_PAE_PAGE_MASK;
PPGMPAGE pPage;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhysCR3, &pPage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhysCR3, &pPage);
if (RT_SUCCESS(rc))
{
RTHCPTR HCPtrGuestCR3;
@@ -1533,7 +1537,7 @@ int pgmGstLazyMapPaePD(PVMCPU pVCpu, uint32_t iPdpt, PX86PDPAE *ppPd)
bool const fChanged = pVCpu->pgm.s.aGCPhysGstPaePDs[iPdpt] != GCPhys;
PPGMPAGE pPage;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhys, &pPage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
if (RT_SUCCESS(rc))
{
RTRCPTR RCPtr = NIL_RTRCPTR;
@@ -1595,7 +1599,7 @@ int pgmGstLazyMapPml4(PVMCPU pVCpu, PX86PML4 *ppPml4)
RTGCPHYS GCPhysCR3 = pVCpu->pgm.s.GCPhysCR3 & X86_CR3_AMD64_PAGE_MASK;
PPGMPAGE pPage;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhysCR3, &pPage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhysCR3, &pPage);
if (RT_SUCCESS(rc))
{
RTHCPTR HCPtrGuestCR3;
@@ -1626,10 +1630,14 @@ int pgmGstLazyMapPml4(PVMCPU pVCpu, PX86PML4 *ppPml4)
* @param pVCpu VMCPU handle.
* @param iPdpt PDPT index
*/
-VMMDECL(X86PDPE) PGMGstGetPaePDPtr(PVMCPU pVCpu, unsigned iPdpt)
+VMMDECL(int) PGMGstQueryPaePDPtr(PVMCPU pVCpu, unsigned iPdpt, PX86PDPE pPdpe)
{
Assert(iPdpt <= 3);
- return pgmGstGetPaePDPTPtr(pVCpu)->a[iPdpt & 3];
+ PX86PDPT pPdpt;
+ int rc = pgmGstGetPaePDPTPtrEx(pVCpu, &pPdpt);
+ if (RT_SUCCESS(rc))
+ *pPdpe = pPdpt->a[iPdpt & 3];
+ return rc;
}
@@ -1769,9 +1777,10 @@ VMMDECL(RTHCPHYS) PGMGetInterAmd64CR3(PVM pVM)
*/
VMMDECL(int) PGMFlushTLB(PVMCPU pVCpu, uint64_t cr3, bool fGlobal)
{
+ STAM_PROFILE_START(&pVCpu->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,FlushTLB), a);
PVM pVM = pVCpu->CTX_SUFF(pVM);
- STAM_PROFILE_START(&pVCpu->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,FlushTLB), a);
+ VMCPU_ASSERT_EMT(pVCpu);
/*
* Always flag the necessary updates; necessary for hardware acceleration
@@ -1809,7 +1818,7 @@ VMMDECL(int) PGMFlushTLB(PVMCPU pVCpu, uint64_t cr3, bool fGlobal)
rc = PGM_BTH_PFN(MapCR3, pVCpu)(pVCpu, GCPhysCR3);
if (RT_LIKELY(rc == VINF_SUCCESS))
{
- if (pgmMapAreMappingsFloating(&pVM->pgm.s))
+ if (pgmMapAreMappingsFloating(pVM))
pVCpu->pgm.s.fSyncFlags &= ~PGM_SYNC_MONITOR_CR3;
}
else
@@ -1818,7 +1827,7 @@ VMMDECL(int) PGMFlushTLB(PVMCPU pVCpu, uint64_t cr3, bool fGlobal)
Assert(VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_PGM_SYNC_CR3));
pVCpu->pgm.s.GCPhysCR3 = GCPhysOldCR3;
pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_MAP_CR3;
- if (pgmMapAreMappingsFloating(&pVM->pgm.s))
+ if (pgmMapAreMappingsFloating(pVM))
pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_MONITOR_CR3;
}
@@ -1878,6 +1887,7 @@ VMMDECL(int) PGMUpdateCR3(PVMCPU pVCpu, uint64_t cr3)
{
PVM pVM = pVCpu->CTX_SUFF(pVM);
+ VMCPU_ASSERT_EMT(pVCpu);
LogFlow(("PGMUpdateCR3: cr3=%RX64 OldCr3=%RX64\n", cr3, pVCpu->pgm.s.GCPhysCR3));
/* We assume we're only called in nested paging mode. */
@@ -1892,17 +1902,17 @@ VMMDECL(int) PGMUpdateCR3(PVMCPU pVCpu, uint64_t cr3)
RTGCPHYS GCPhysCR3;
switch (pVCpu->pgm.s.enmGuestMode)
{
- case PGMMODE_PAE:
- case PGMMODE_PAE_NX:
- GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_PAE_PAGE_MASK);
- break;
- case PGMMODE_AMD64:
- case PGMMODE_AMD64_NX:
- GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_AMD64_PAGE_MASK);
- break;
- default:
- GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_PAGE_MASK);
- break;
+ case PGMMODE_PAE:
+ case PGMMODE_PAE_NX:
+ GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_PAE_PAGE_MASK);
+ break;
+ case PGMMODE_AMD64:
+ case PGMMODE_AMD64_NX:
+ GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_AMD64_PAGE_MASK);
+ break;
+ default:
+ GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_PAGE_MASK);
+ break;
}
if (pVCpu->pgm.s.GCPhysCR3 != GCPhysCR3)
{
@@ -1933,6 +1943,8 @@ VMMDECL(int) PGMSyncCR3(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4,
PVM pVM = pVCpu->CTX_SUFF(pVM);
int rc;
+ VMCPU_ASSERT_EMT(pVCpu);
+
/*
* The pool may have pending stuff and even require a return to ring-3 to
* clear the whole thing.
@@ -1976,17 +1988,17 @@ VMMDECL(int) PGMSyncCR3(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4,
RTGCPHYS GCPhysCR3;
switch (pVCpu->pgm.s.enmGuestMode)
{
- case PGMMODE_PAE:
- case PGMMODE_PAE_NX:
- GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_PAE_PAGE_MASK);
- break;
- case PGMMODE_AMD64:
- case PGMMODE_AMD64_NX:
- GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_AMD64_PAGE_MASK);
- break;
- default:
- GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_PAGE_MASK);
- break;
+ case PGMMODE_PAE:
+ case PGMMODE_PAE_NX:
+ GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_PAE_PAGE_MASK);
+ break;
+ case PGMMODE_AMD64:
+ case PGMMODE_AMD64_NX:
+ GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_AMD64_PAGE_MASK);
+ break;
+ default:
+ GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_PAGE_MASK);
+ break;
}
if (pVCpu->pgm.s.GCPhysCR3 != GCPhysCR3)
@@ -1994,6 +2006,7 @@ VMMDECL(int) PGMSyncCR3(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4,
pVCpu->pgm.s.GCPhysCR3 = GCPhysCR3;
rc = PGM_BTH_PFN(MapCR3, pVCpu)(pVCpu, GCPhysCR3);
}
+
/* Make sure we check for pending pgm pool syncs as we clear VMCPU_FF_PGM_SYNC_CR3 later on! */
if ( rc == VINF_PGM_SYNC_CR3
|| (pVCpu->pgm.s.fSyncFlags & PGM_SYNC_CLEAR_PGM_POOL))
@@ -2072,6 +2085,8 @@ VMMDECL(int) PGMChangeMode(PVMCPU pVCpu, uint64_t cr0, uint64_t cr4, uint64_t ef
PVM pVM = pVCpu->CTX_SUFF(pVM);
PGMMODE enmGuestMode;
+ VMCPU_ASSERT_EMT(pVCpu);
+
/*
* Calc the new guest mode.
*/
@@ -2145,6 +2160,7 @@ VMMDECL(PGMMODE) PGMGetShadowMode(PVMCPU pVCpu)
return pVCpu->pgm.s.enmShadowMode;
}
+
/**
* Gets the current host paging mode.
*
@@ -2215,7 +2231,9 @@ VMMDECL(const char *) PGMGetModeName(PGMMODE enmMode)
*/
VMM_INT_DECL(void) PGMNotifyNxeChanged(PVMCPU pVCpu, bool fNxe)
{
+/** @todo VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu); */
Log(("PGMNotifyNxeChanged: fNxe=%RTbool\n", fNxe));
+
pVCpu->pgm.s.fNoExecuteEnabled = fNxe;
if (fNxe)
{
@@ -2273,17 +2291,6 @@ VMMDECL(bool) PGMHasDirtyPages(PVM pVM)
return pVM->pgm.s.CTX_SUFF(pPool)->cDirtyPages != 0;
}
-/**
- * Check if the PGM lock is currently taken.
- *
- * @returns bool locked/not locked
- * @param pVM The VM to operate on.
- */
-VMMDECL(bool) PGMIsLocked(PVM pVM)
-{
- return PDMCritSectIsOwned(&pVM->pgm.s.CritSect);
-}
-
/**
* Check if this VCPU currently owns the PGM lock.
@@ -2300,14 +2307,19 @@ VMMDECL(bool) PGMIsLockOwner(PVM pVM)
/**
* Enable or disable large page usage
*
+ * @returns VBox status code.
* @param pVM The VM to operate on.
* @param fUseLargePages Use/not use large pages
*/
-VMMDECL(void) PGMSetLargePageUsage(PVM pVM, bool fUseLargePages)
+VMMDECL(int) PGMSetLargePageUsage(PVM pVM, bool fUseLargePages)
{
+ VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
+
pVM->fUseLargePages = fUseLargePages;
+ return VINF_SUCCESS;
}
+
/**
* Acquire the PGM lock.
*
@@ -2357,7 +2369,7 @@ int pgmRZDynMapGCPageCommon(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void **ppv R
* Convert it to a writable page and it on to the dynamic mapper.
*/
int rc;
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
if (RT_LIKELY(pPage))
{
rc = pgmPhysPageMakeWritable(pVM, pPage, GCPhys);
@@ -2401,7 +2413,7 @@ static DECLCALLBACK(size_t) pgmFormatTypeHandlerPage(PFNRTSTROUTPUT pfnOutput, v
/* The single char state stuff. */
static const char s_achPageStates[4] = { 'Z', 'A', 'W', 'S' };
- szTmp[cch++] = s_achPageStates[PGM_PAGE_GET_STATE(pPage)];
+ szTmp[cch++] = s_achPageStates[PGM_PAGE_GET_STATE_NA(pPage)];
#define IS_PART_INCLUDED(lvl) ( !(fFlags & RTSTR_F_PRECISION) || cchPrecision == (lvl) || cchPrecision >= (lvl)+10 )
if (IS_PART_INCLUDED(5))
@@ -2416,16 +2428,16 @@ static DECLCALLBACK(size_t) pgmFormatTypeHandlerPage(PFNRTSTROUTPUT pfnOutput, v
{
szTmp[cch++] = ':';
static const char s_achPageTypes[8][4] = { "INV", "RAM", "MI2", "M2A", "SHA", "ROM", "MIO", "BAD" };
- szTmp[cch++] = s_achPageTypes[PGM_PAGE_GET_TYPE(pPage)][0];
- szTmp[cch++] = s_achPageTypes[PGM_PAGE_GET_TYPE(pPage)][1];
- szTmp[cch++] = s_achPageTypes[PGM_PAGE_GET_TYPE(pPage)][2];
+ szTmp[cch++] = s_achPageTypes[PGM_PAGE_GET_TYPE_NA(pPage)][0];
+ szTmp[cch++] = s_achPageTypes[PGM_PAGE_GET_TYPE_NA(pPage)][1];
+ szTmp[cch++] = s_achPageTypes[PGM_PAGE_GET_TYPE_NA(pPage)][2];
}
/* The numbers. */
if (IS_PART_INCLUDED(3))
{
szTmp[cch++] = ':';
- cch += RTStrFormatNumber(&szTmp[cch], PGM_PAGE_GET_HCPHYS(pPage), 16, 12, 0, RTSTR_F_ZEROPAD | RTSTR_F_64BIT);
+ cch += RTStrFormatNumber(&szTmp[cch], PGM_PAGE_GET_HCPHYS_NA(pPage), 16, 12, 0, RTSTR_F_ZEROPAD | RTSTR_F_64BIT);
}
if (IS_PART_INCLUDED(2))
@@ -2438,8 +2450,8 @@ static DECLCALLBACK(size_t) pgmFormatTypeHandlerPage(PFNRTSTROUTPUT pfnOutput, v
{
szTmp[cch++] = ':';
static const char s_achRefs[4] = { '-', 'U', '!', 'L' };
- szTmp[cch++] = s_achRefs[PGM_PAGE_GET_TD_CREFS(pPage)];
- cch += RTStrFormatNumber(&szTmp[cch], PGM_PAGE_GET_TD_IDX(pPage), 16, 4, 0, RTSTR_F_ZEROPAD | RTSTR_F_16BIT);
+ szTmp[cch++] = s_achRefs[PGM_PAGE_GET_TD_CREFS_NA(pPage)];
+ cch += RTStrFormatNumber(&szTmp[cch], PGM_PAGE_GET_TD_IDX_NA(pPage), 16, 4, 0, RTSTR_F_ZEROPAD | RTSTR_F_16BIT);
}
#undef IS_PART_INCLUDED
diff --git a/src/VBox/VMM/VMMAll/PGMAllBth.h b/src/VBox/VMM/VMMAll/PGMAllBth.h
index 016028140..bd0b981be 100644
--- a/src/VBox/VMM/VMMAll/PGMAllBth.h
+++ b/src/VBox/VMM/VMMAll/PGMAllBth.h
@@ -1,4 +1,4 @@
-/* $Id: PGMAllBth.h $ */
+/* $Id: PGMAllBth.h 37354 2011-06-07 15:05:32Z vboxsync $ */
/** @file
* VBox - Page Manager, Shadow+Guest Paging Template - All context code.
*
@@ -549,13 +549,13 @@ PGM_BTH_DECL(int, Trap0eHandler)(PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegF
Assert(uErr & X86_TRAP_PF_P);
PPGMPAGE pPage;
# if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
- rc = pgmPhysGetPageEx(&pVM->pgm.s, GstWalk.Core.GCPhys, &pPage);
+ rc = pgmPhysGetPageEx(pVM, GstWalk.Core.GCPhys, &pPage);
if (RT_SUCCESS(rc) && PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage))
return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerDoAccessHandlers)(pVCpu, uErr, pRegFrame, pvFault, pPage,
pfLockTaken, &GstWalk));
rc = PGM_BTH_NAME(SyncPage)(pVCpu, GstWalk.Pde, pvFault, 1, uErr);
# else
- rc = pgmPhysGetPageEx(&pVM->pgm.s, (RTGCPHYS)pvFault, &pPage);
+ rc = pgmPhysGetPageEx(pVM, (RTGCPHYS)pvFault, &pPage);
if (RT_SUCCESS(rc) && PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage))
return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerDoAccessHandlers)(pVCpu, uErr, pRegFrame, pvFault, pPage,
pfLockTaken));
@@ -674,7 +674,7 @@ PGM_BTH_DECL(int, Trap0eHandler)(PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegF
* us from screwing ourself with MMIO2 pages which have a GC Mapping (VRam).
* (BTW, it's impossible to have physical access handlers in a mapping.)
*/
- if (pgmMapAreMappingsEnabled(&pVM->pgm.s))
+ if (pgmMapAreMappingsEnabled(pVM))
{
PPGMMAPPING pMapping = pVM->pgm.s.CTX_SUFF(pMappings);
for ( ; pMapping; pMapping = pMapping->CTX_SUFF(pNext))
@@ -686,7 +686,7 @@ PGM_BTH_DECL(int, Trap0eHandler)(PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegF
/*
* The first thing we check is if we've got an undetected conflict.
*/
- if (pgmMapAreMappingsFloating(&pVM->pgm.s))
+ if (pgmMapAreMappingsFloating(pVM))
{
unsigned iPT = pMapping->cb >> GST_PD_SHIFT;
while (iPT-- > 0)
@@ -750,7 +750,7 @@ PGM_BTH_DECL(int, Trap0eHandler)(PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegF
RTGCPHYS GCPhys = (RTGCPHYS)pvFault & ~(RTGCPHYS)PAGE_OFFSET_MASK;
# endif /* PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) */
PPGMPAGE pPage;
- rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhys, &pPage);
+ rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
if (RT_FAILURE(rc))
{
/*
@@ -1119,7 +1119,7 @@ PGM_BTH_DECL(int, InvalidatePage)(PVMCPU pVCpu, RTGCPTR GCPtrPage)
PVM pVM = pVCpu->CTX_SUFF(pVM);
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
LogFlow(("InvalidatePage %RGv\n", GCPtrPage));
@@ -1260,7 +1260,7 @@ PGM_BTH_DECL(int, InvalidatePage)(PVMCPU pVCpu, RTGCPTR GCPtrPage)
/*
* Conflict - Let SyncPT deal with it to avoid duplicate code.
*/
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
Assert(PGMGetGuestMode(pVCpu) <= PGMMODE_PAE);
rc = PGM_BTH_NAME(SyncPT)(pVCpu, iPDSrc, pPDSrc, GCPtrPage);
}
@@ -1372,7 +1372,7 @@ PGM_BTH_DECL(int, InvalidatePage)(PVMCPU pVCpu, RTGCPTR GCPtrPage)
}
else
{
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,InvalidatePagePDMappings));
}
}
@@ -1412,7 +1412,7 @@ DECLINLINE(void) PGM_BTH_NAME(SyncPageWorkerTrackDeref)(PVMCPU pVCpu, PPGMPOOLPA
pShwPage->cPresent--;
pPool->cPresent--;
- PPGMPAGE pPhysPage = pgmPhysGetPage(&pVM->pgm.s, GCPhysPage);
+ PPGMPAGE pPhysPage = pgmPhysGetPage(pVM, GCPhysPage);
AssertRelease(pPhysPage);
pgmTrackDerefGCPhys(pPool, pShwPage, pPhysPage, iPte);
return;
@@ -1431,7 +1431,7 @@ DECLINLINE(void) PGM_BTH_NAME(SyncPageWorkerTrackDeref)(PVMCPU pVCpu, PPGMPOOLPA
/*
* Find the guest address.
*/
- for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
pRam;
pRam = pRam->CTX_SUFF(pNext))
{
@@ -1480,14 +1480,14 @@ DECLINLINE(void) PGM_BTH_NAME(SyncPageWorkerTrackAddref)(PVMCPU pVCpu, PPGMPOOLP
STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->StatTrackVirgin);
u16 = PGMPOOL_TD_MAKE(1, pShwPage->idx);
/* Save the page table index. */
- PGM_PAGE_SET_PTE_INDEX(pPage, iPTDst);
+ PGM_PAGE_SET_PTE_INDEX(pVM, pPage, iPTDst);
}
else
u16 = pgmPoolTrackPhysExtAddref(pVM, pPage, u16, pShwPage->idx, iPTDst);
/* write back */
Log2(("SyncPageWorkerTrackAddRef: u16=%#x->%#x iPTDst=%#x\n", u16, PGM_PAGE_GET_TRACKING(pPage), iPTDst));
- PGM_PAGE_SET_TRACKING(pPage, u16);
+ PGM_PAGE_SET_TRACKING(pVM, pPage, u16);
/* update statistics. */
pVM->pgm.s.CTX_SUFF(pPool)->cPresent++;
@@ -1624,7 +1624,7 @@ static void PGM_BTH_NAME(SyncPageWorker)(PVMCPU pVCpu, PSHWPTE pPteDst, RTGCPHYS
* Find the ram range.
*/
PPGMPAGE pPage;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhysPage, &pPage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhysPage, &pPage);
if (RT_SUCCESS(rc))
{
/* Ignore ballooned pages.
@@ -1805,7 +1805,7 @@ static int PGM_BTH_NAME(SyncPage)(PVMCPU pVCpu, GSTPDE PdeSrc, RTGCPTR GCPtrPage
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
LogFlow(("SyncPage: GCPtrPage=%RGv cPages=%u uErr=%#x\n", GCPtrPage, cPages, uErr));
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
#if ( PGM_GST_TYPE == PGM_TYPE_32BIT \
|| PGM_GST_TYPE == PGM_TYPE_PAE \
@@ -1982,7 +1982,7 @@ static int PGM_BTH_NAME(SyncPage)(PVMCPU pVCpu, GSTPDE PdeSrc, RTGCPTR GCPtrPage
if ( ((PdeSrc.u & pPteSrc->u) & (X86_PTE_RW | X86_PTE_US))
|| iPTDst == ((GCPtrPage >> SHW_PT_SHIFT) & SHW_PT_MASK) /* always sync GCPtrPage */
|| !CSAMDoesPageNeedScanning(pVM, GCPtrCurPage)
- || ( (pPage = pgmPhysGetPage(&pVM->pgm.s, pPteSrc->u & GST_PTE_PG_MASK))
+ || ( (pPage = pgmPhysGetPage(pVM, pPteSrc->u & GST_PTE_PG_MASK))
&& PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage))
)
#endif /* else: CSAM not active */
@@ -2029,7 +2029,7 @@ static int PGM_BTH_NAME(SyncPage)(PVMCPU pVCpu, GSTPDE PdeSrc, RTGCPTR GCPtrPage
GCPhys = GST_GET_BIG_PDE_GCPHYS(pVM, PdeSrc) | (GCPtrPage & GST_BIG_PAGE_OFFSET_MASK);
/* Find ram range. */
PPGMPAGE pPage;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhys, &pPage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
if (RT_SUCCESS(rc))
{
AssertFatalMsg(!PGM_PAGE_IS_BALLOONED(pPage), ("Unexpected ballooned page at %RGp\n", GCPhys));
@@ -2353,7 +2353,7 @@ static int PGM_BTH_NAME(CheckDirtyPageFault)(PVMCPU pVCpu, uint32_t uErr, PSHWPD
PVM pVM = pVCpu->CTX_SUFF(pVM);
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/*
* Handle big page.
@@ -2441,7 +2441,7 @@ static int PGM_BTH_NAME(CheckDirtyPageFault)(PVMCPU pVCpu, uint32_t uErr, PSHWPD
{
if (SHW_PTE_IS_TRACK_DIRTY(*pPteDst))
{
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GST_GET_PTE_GCPHYS(*pPteSrc));
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GST_GET_PTE_GCPHYS(*pPteSrc));
SHWPTE PteDst = *pPteDst;
LogFlow(("DIRTY page trap addr=%RGv\n", GCPtrPage));
@@ -2544,7 +2544,7 @@ static int PGM_BTH_NAME(SyncPT)(PVMCPU pVCpu, unsigned iPDSrc, PGSTPD pPDSrc, RT
#endif
LogFlow(("SyncPT: GCPtrPage=%RGv\n", GCPtrPage));
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
#if ( PGM_GST_TYPE == PGM_TYPE_32BIT \
|| PGM_GST_TYPE == PGM_TYPE_PAE \
@@ -2612,7 +2612,7 @@ static int PGM_BTH_NAME(SyncPT)(PVMCPU pVCpu, unsigned iPDSrc, PGSTPD pPDSrc, RT
*/
if (PdeDst.u & PGM_PDFLAGS_MAPPING)
{
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
# ifndef IN_RING3
Log(("SyncPT: Conflict at %RGv\n", GCPtrPage));
STAM_PROFILE_STOP(&pVCpu->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,SyncPT), a);
@@ -2816,7 +2816,7 @@ static int PGM_BTH_NAME(SyncPT)(PVMCPU pVCpu, unsigned iPDSrc, PGSTPD pPDSrc, RT
PPGMPAGE pPage;
if ( ((PdeSrc.u & pPTSrc->a[iPTSrc].u) & (X86_PTE_RW | X86_PTE_US))
|| !CSAMDoesPageNeedScanning(pVM, GCPtrCur)
- || ( (pPage = pgmPhysGetPage(&pVM->pgm.s, GST_GET_PTE_GCPHYS(PteSrc)))
+ || ( (pPage = pgmPhysGetPage(pVM, GST_GET_PTE_GCPHYS(PteSrc)))
&& PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage))
)
# endif
@@ -2840,7 +2840,7 @@ static int PGM_BTH_NAME(SyncPT)(PVMCPU pVCpu, unsigned iPDSrc, PGSTPD pPDSrc, RT
* Big page - 2/4MB.
*
* We'll walk the ram range list in parallel and optimize lookups.
- * We will only sync on shadow page table at a time.
+ * We will only sync one shadow page table at a time.
*/
STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,SyncPT4M));
@@ -2887,14 +2887,11 @@ static int PGM_BTH_NAME(SyncPT)(PVMCPU pVCpu, unsigned iPDSrc, PGSTPD pPDSrc, RT
Log2(("SyncPT: BIG %RGv PdeSrc:{P=%d RW=%d U=%d raw=%08llx} Shw=%RGv GCPhys=%RGp %s\n",
GCPtrPage, PdeSrc.b.u1Present, PdeSrc.b.u1Write, PdeSrc.b.u1User, (uint64_t)PdeSrc.u, GCPtr,
GCPhys, PdeDst.u & PGM_PDFLAGS_TRACK_DIRTY ? " Track-Dirty" : ""));
- PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+ PPGMRAMRANGE pRam = pgmPhysGetRangeAtOrAbove(pVM, GCPhys);
unsigned iPTDst = 0;
while ( iPTDst < RT_ELEMENTS(pPTDst->a)
&& !VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY))
{
- /* Advance ram range list. */
- while (pRam && GCPhys > pRam->GCPhysLast)
- pRam = pRam->CTX_SUFF(pNext);
if (pRam && GCPhys >= pRam->GCPhys)
{
unsigned iHCPage = (GCPhys - pRam->GCPhys) >> PAGE_SHIFT;
@@ -2969,6 +2966,10 @@ static int PGM_BTH_NAME(SyncPT)(PVMCPU pVCpu, unsigned iPDSrc, PGSTPD pPDSrc, RT
iPTDst++;
} while ( iPTDst < RT_ELEMENTS(pPTDst->a)
&& GCPhys <= pRam->GCPhysLast);
+
+ /* Advance ram range list. */
+ while (pRam && GCPhys > pRam->GCPhysLast)
+ pRam = pRam->CTX_SUFF(pNext);
}
else if (pRam)
{
@@ -3075,7 +3076,7 @@ static int PGM_BTH_NAME(SyncPT)(PVMCPU pVCpu, unsigned iPDSrc, PGSTPD pPDSrc, RT
{
/* Check if we allocated a big page before for this 2 MB range. */
PPGMPAGE pPage;
- rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPtrPage & X86_PDE2M_PAE_PG_MASK, &pPage);
+ rc = pgmPhysGetPageEx(pVM, GCPtrPage & X86_PDE2M_PAE_PG_MASK, &pPage);
if (RT_SUCCESS(rc))
{
RTHCPHYS HCPhys = NIL_RTHCPHYS;
@@ -3584,7 +3585,7 @@ PGM_BTH_DECL(int, SyncCR3)(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr
/*
* Nested / EPT - almost no work.
*/
- Assert(!pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(!pgmMapAreMappingsEnabled(pVM));
return VINF_SUCCESS;
#elif PGM_SHW_TYPE == PGM_TYPE_AMD64
@@ -3592,7 +3593,7 @@ PGM_BTH_DECL(int, SyncCR3)(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr
* AMD64 (Shw & Gst) - No need to check all paging levels; we zero
* out the shadow parts when the guest modifies its tables.
*/
- Assert(!pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(!pgmMapAreMappingsEnabled(pVM));
return VINF_SUCCESS;
#else /* PGM_SHW_TYPE != PGM_TYPE_NESTED && PGM_SHW_TYPE != PGM_TYPE_EPT && PGM_SHW_TYPE != PGM_TYPE_AMD64 */
@@ -3602,7 +3603,7 @@ PGM_BTH_DECL(int, SyncCR3)(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr
* Check for and resolve conflicts with our guest mappings if they
* are enabled and not fixed.
*/
- if (pgmMapAreMappingsFloating(&pVM->pgm.s))
+ if (pgmMapAreMappingsFloating(pVM))
{
int rc = pgmMapResolveConflicts(pVM);
Assert(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3);
@@ -3613,7 +3614,7 @@ PGM_BTH_DECL(int, SyncCR3)(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr
}
}
# else
- Assert(!pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(!pgmMapAreMappingsEnabled(pVM));
# endif
return VINF_SUCCESS;
#endif /* PGM_SHW_TYPE != PGM_TYPE_NESTED && PGM_SHW_TYPE != PGM_TYPE_EPT && PGM_SHW_TYPE != PGM_TYPE_AMD64 */
@@ -3680,7 +3681,7 @@ PGM_BTH_DECL(unsigned, AssertCR3)(PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGC
# endif
AssertRCReturn(rc, 1);
HCPhys = NIL_RTHCPHYS;
- rc = pgmRamGCPhys2HCPhys(&pVM->pgm.s, cr3 & GST_CR3_PAGE_MASK, &HCPhys);
+ rc = pgmRamGCPhys2HCPhys(pVM, cr3 & GST_CR3_PAGE_MASK, &HCPhys);
AssertMsgReturn(HCPhys == HCPhysShw, ("HCPhys=%RHp HCPhyswShw=%RHp (cr3)\n", HCPhys, HCPhysShw), false);
# if PGM_GST_TYPE == PGM_TYPE_32BIT && defined(IN_RING3)
pgmGstGet32bitPDPtr(pVCpu);
@@ -3868,7 +3869,7 @@ PGM_BTH_DECL(unsigned, AssertCR3)(PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGC
# endif
if (PdeDst.u & PGM_PDFLAGS_MAPPING)
{
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
if ((PdeDst.u & X86_PDE_AVL_MASK) != PGM_PDFLAGS_MAPPING)
{
AssertMsgFailed(("Mapping shall only have PGM_PDFLAGS_MAPPING set! PdeDst.u=%#RX64\n", (uint64_t)PdeDst.u));
@@ -3947,7 +3948,7 @@ PGM_BTH_DECL(unsigned, AssertCR3)(PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGC
cErrors++;
}
- PPGMPAGE pPhysPage = pgmPhysGetPage(&pVM->pgm.s, GCPhysGst);
+ PPGMPAGE pPhysPage = pgmPhysGetPage(pVM, GCPhysGst);
if (!pPhysPage)
{
AssertMsgFailed(("Cannot find guest physical address %RGp in the PDE at %RGv! PdeSrc=%#RX64\n",
@@ -4061,7 +4062,7 @@ PGM_BTH_DECL(unsigned, AssertCR3)(PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGC
}
# endif
- pPhysPage = pgmPhysGetPage(&pVM->pgm.s, GCPhysGst);
+ pPhysPage = pgmPhysGetPage(pVM, GCPhysGst);
if (!pPhysPage)
{
# ifdef IN_RING3 /** @todo make MMR3PageDummyHCPhys an 'All' function! */
@@ -4293,7 +4294,7 @@ PGM_BTH_DECL(unsigned, AssertCR3)(PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGC
continue;
}
# endif
- pPhysPage = pgmPhysGetPage(&pVM->pgm.s, GCPhysGst);
+ pPhysPage = pgmPhysGetPage(pVM, GCPhysGst);
if (!pPhysPage)
{
# ifdef IN_RING3 /** @todo make MMR3PageDummyHCPhys an 'All' function! */
@@ -4415,7 +4416,7 @@ PGM_BTH_DECL(int, MapCR3)(PVMCPU pVCpu, RTGCPHYS GCPhysCR3)
RTHCPTR HCPtrGuestCR3;
RTHCPHYS HCPhysGuestCR3;
pgmLock(pVM);
- PPGMPAGE pPageCR3 = pgmPhysGetPage(&pVM->pgm.s, GCPhysCR3);
+ PPGMPAGE pPageCR3 = pgmPhysGetPage(pVM, GCPhysCR3);
AssertReturn(pPageCR3, VERR_INTERNAL_ERROR_2);
HCPhysGuestCR3 = PGM_PAGE_GET_HCPHYS(pPageCR3);
/** @todo this needs some reworking wrt. locking? */
@@ -4463,7 +4464,7 @@ PGM_BTH_DECL(int, MapCR3)(PVMCPU pVCpu, RTGCPHYS GCPhysCR3)
RTHCPHYS HCPhys;
RTGCPHYS GCPhys = pGuestPDPT->a[i].u & X86_PDPE_PG_MASK;
pgmLock(pVM);
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
AssertReturn(pPage, VERR_INTERNAL_ERROR_2);
HCPhys = PGM_PAGE_GET_HCPHYS(pPage);
# if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
diff --git a/src/VBox/VMM/VMMAll/PGMAllGst.h b/src/VBox/VMM/VMMAll/PGMAllGst.h
index 8e02dda53..d16279817 100644
--- a/src/VBox/VMM/VMMAll/PGMAllGst.h
+++ b/src/VBox/VMM/VMMAll/PGMAllGst.h
@@ -1,4 +1,4 @@
-/* $Id: PGMAllGst.h $ */
+/* $Id: PGMAllGst.h 36891 2011-04-29 13:22:57Z vboxsync $ */
/** @file
* VBox - Page Manager, Guest Paging Template - All context code.
*/
@@ -516,7 +516,7 @@ static DECLCALLBACK(int) PGM_GST_NAME(VirtHandlerUpdateOne)(PAVLROGCPTRNODECORE
if (pCur->aPhysToVirt[iPage].Core.Key != GCPhysNew)
{
if (pCur->aPhysToVirt[iPage].Core.Key != NIL_RTGCPHYS)
- pgmHandlerVirtualClearPage(&pVM->pgm.s, pCur, iPage);
+ pgmHandlerVirtualClearPage(pVM, pCur, iPage);
#ifdef VBOX_STRICT_PGM_HANDLER_VIRTUAL
AssertReleaseMsg(!pCur->aPhysToVirt[iPage].offNextAlias,
("{.Core.Key=%RGp, .Core.KeyLast=%RGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32} GCPhysNew=%RGp\n",
@@ -539,7 +539,7 @@ static DECLCALLBACK(int) PGM_GST_NAME(VirtHandlerUpdateOne)(PAVLROGCPTRNODECORE
{
if (pCur->aPhysToVirt[iPage].Core.Key != NIL_RTGCPHYS)
{
- pgmHandlerVirtualClearPage(&pVM->pgm.s, pCur, iPage);
+ pgmHandlerVirtualClearPage(pVM, pCur, iPage);
#ifdef VBOX_STRICT_PGM_HANDLER_VIRTUAL
AssertReleaseMsg(!pCur->aPhysToVirt[iPage].offNextAlias,
("{.Core.Key=%RGp, .Core.KeyLast=%RGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n",
@@ -566,7 +566,7 @@ static DECLCALLBACK(int) PGM_GST_NAME(VirtHandlerUpdateOne)(PAVLROGCPTRNODECORE
if (pCur->aPhysToVirt[iPage].Core.Key != GCPhysNew)
{
if (pCur->aPhysToVirt[iPage].Core.Key != NIL_RTGCPHYS)
- pgmHandlerVirtualClearPage(&pVM->pgm.s, pCur, iPage);
+ pgmHandlerVirtualClearPage(pVM, pCur, iPage);
#ifdef VBOX_STRICT_PGM_HANDLER_VIRTUAL
AssertReleaseMsg(!pCur->aPhysToVirt[iPage].offNextAlias,
("{.Core.Key=%RGp, .Core.KeyLast=%RGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32} GCPhysNew=%RGp\n",
@@ -589,7 +589,7 @@ static DECLCALLBACK(int) PGM_GST_NAME(VirtHandlerUpdateOne)(PAVLROGCPTRNODECORE
{
if (pCur->aPhysToVirt[iPage].Core.Key != NIL_RTGCPHYS)
{
- pgmHandlerVirtualClearPage(&pVM->pgm.s, pCur, iPage);
+ pgmHandlerVirtualClearPage(pVM, pCur, iPage);
pCur->aPhysToVirt[iPage].Core.Key = NIL_RTGCPHYS;
pState->fTodo |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;
}
diff --git a/src/VBox/VMM/VMMAll/PGMAllHandler.cpp b/src/VBox/VMM/VMMAll/PGMAllHandler.cpp
index fd32d2311..16943f082 100644
--- a/src/VBox/VMM/VMMAll/PGMAllHandler.cpp
+++ b/src/VBox/VMM/VMMAll/PGMAllHandler.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMAllHandler.cpp $ */
+/* $Id: PGMAllHandler.cpp 37354 2011-06-07 15:05:32Z vboxsync $ */
/** @file
* PGM - Page Manager / Monitor, Access Handlers.
*/
@@ -119,12 +119,10 @@ VMMDECL(int) PGMHandlerPhysicalRegisterEx(PVM pVM, PGMPHYSHANDLERTYPE enmType, R
* We require the range to be within registered ram.
* There is no apparent need to support ranges which cover more than one ram range.
*/
- PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
- while (pRam && GCPhys > pRam->GCPhysLast)
- pRam = pRam->CTX_SUFF(pNext);
- if ( !pRam
- || GCPhysLast < pRam->GCPhys
- || GCPhys > pRam->GCPhysLast)
+ PPGMRAMRANGE pRam = pgmPhysGetRange(pVM, GCPhys);
+ if ( !pRam
+ || GCPhysLast < pRam->GCPhys
+ || GCPhys > pRam->GCPhysLast)
{
#ifdef IN_RING3
DBGFR3Info(pVM, "phys", NULL, NULL);
@@ -305,7 +303,7 @@ static void pgmHandlerPhysicalDeregisterNotifyREM(PVM pVM, PPGMPHYSHANDLER pCur)
if (GCPhysStart & PAGE_OFFSET_MASK)
{
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhysStart);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhysStart);
if ( pPage
&& PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) != PGM_PAGE_HNDL_PHYS_STATE_NONE)
{
@@ -322,7 +320,7 @@ static void pgmHandlerPhysicalDeregisterNotifyREM(PVM pVM, PPGMPHYSHANDLER pCur)
if (GCPhysLast & PAGE_OFFSET_MASK)
{
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhysLast);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhysLast);
if ( pPage
&& PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) != PGM_PAGE_HNDL_PHYS_STATE_NONE)
{
@@ -386,7 +384,7 @@ DECLINLINE(void) pgmHandlerPhysicalRecalcPageState(PVM pVM, RTGCPHYS GCPhys, boo
if (uState != PGM_PAGE_HNDL_PHYS_STATE_NONE)
{
PPGMPAGE pPage;
- int rc = pgmPhysGetPageWithHintEx(&pVM->pgm.s, GCPhys, &pPage, ppRamHint);
+ int rc = pgmPhysGetPageWithHintEx(pVM, GCPhys, &pPage, ppRamHint);
if ( RT_SUCCESS(rc)
&& PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) < uState)
{
@@ -436,14 +434,14 @@ void pgmHandlerPhysicalResetAliasedPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys
/*
* Make it an MMIO/Zero page.
*/
- PGM_PAGE_SET_HCPHYS(pPage, pVM->pgm.s.HCPhysZeroPg);
- PGM_PAGE_SET_TYPE(pPage, PGMPAGETYPE_MMIO);
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ZERO);
- PGM_PAGE_SET_PAGEID(pPage, NIL_GMM_PAGEID);
+ PGM_PAGE_SET_HCPHYS(pVM, pPage, pVM->pgm.s.HCPhysZeroPg);
+ PGM_PAGE_SET_TYPE(pVM, pPage, PGMPAGETYPE_MMIO);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ZERO);
+ PGM_PAGE_SET_PAGEID(pVM, pPage, NIL_GMM_PAGEID);
PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, PGM_PAGE_HNDL_PHYS_STATE_ALL);
/* Flush its TLB entry. */
- PGMPhysInvalidatePageMapTLBEntry(pVM, GCPhysPage);
+ pgmPhysInvalidatePageMapTLBEntry(pVM, GCPhysPage);
/*
* Do accounting for pgmR3PhysRamReset.
@@ -479,14 +477,13 @@ static void pgmHandlerPhysicalResetRamFlags(PVM pVM, PPGMPHYSHANDLER pCur)
/*
* Iterate the guest ram pages updating the state.
*/
- RTUINT cPages = pCur->cPages;
- RTGCPHYS GCPhys = pCur->Core.Key;
+ RTUINT cPages = pCur->cPages;
+ RTGCPHYS GCPhys = pCur->Core.Key;
PPGMRAMRANGE pRamHint = NULL;
- PPGM pPGM = &pVM->pgm.s;
for (;;)
{
PPGMPAGE pPage;
- int rc = pgmPhysGetPageWithHintEx(pPGM, GCPhys, &pPage, &pRamHint);
+ int rc = pgmPhysGetPageWithHintEx(pVM, GCPhys, &pPage, &pRamHint);
if (RT_SUCCESS(rc))
{
/* Reset MMIO2 for MMIO pages to MMIO, since this aliasing is our business.
@@ -561,12 +558,10 @@ VMMDECL(int) PGMHandlerPhysicalModify(PVM pVM, RTGCPHYS GCPhysCurrent, RTGCPHYS
* We require the range to be within registered ram.
* There is no apparent need to support ranges which cover more than one ram range.
*/
- PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
- while (pRam && GCPhys > pRam->GCPhysLast)
- pRam = pRam->CTX_SUFF(pNext);
- if ( pRam
- && GCPhys <= pRam->GCPhysLast
- && GCPhysLast >= pRam->GCPhys)
+ PPGMRAMRANGE pRam = pgmPhysGetRange(pVM, GCPhys);
+ if ( pRam
+ && GCPhys <= pRam->GCPhysLast
+ && GCPhysLast >= pRam->GCPhys)
{
pCur->Core.Key = GCPhys;
pCur->Core.KeyLast = GCPhysLast;
@@ -864,7 +859,7 @@ VMMDECL(int) PGMHandlerPhysicalReset(PVM pVM, RTGCPHYS GCPhys)
case PGMPHYSHANDLERTYPE_MMIO: /* NOTE: Only use when clearing MMIO ranges with aliased MMIO2 pages! */
{
STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,PhysHandlerReset)); /**@Todo move out of switch */
- PPGMRAMRANGE pRam = pgmPhysGetRange(&pVM->pgm.s, GCPhys);
+ PPGMRAMRANGE pRam = pgmPhysGetRange(pVM, GCPhys);
Assert(pRam);
Assert(pRam->GCPhys <= pCur->Core.Key);
Assert(pRam->GCPhysLast >= pCur->Core.KeyLast);
@@ -978,7 +973,7 @@ VMMDECL(int) PGMHandlerPhysicalPageTempOff(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS G
* Change the page status.
*/
PPGMPAGE pPage;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhysPage, &pPage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhysPage, &pPage);
AssertReturnStmt(RT_SUCCESS_NP(rc), pgmUnlock(pVM), rc);
if (PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) != PGM_PAGE_HNDL_PHYS_STATE_DISABLED)
{
@@ -1061,14 +1056,14 @@ VMMDECL(int) PGMHandlerPhysicalPageAlias(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCP
* Get and validate the two pages.
*/
PPGMPAGE pPageRemap;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhysPageRemap, &pPageRemap);
+ int rc = pgmPhysGetPageEx(pVM, GCPhysPageRemap, &pPageRemap);
AssertReturnStmt(RT_SUCCESS_NP(rc), pgmUnlock(pVM), rc);
AssertMsgReturnStmt(PGM_PAGE_GET_TYPE(pPageRemap) == PGMPAGETYPE_MMIO2,
("GCPhysPageRemap=%RGp %R[pgmpage]\n", GCPhysPageRemap, pPageRemap),
pgmUnlock(pVM), VERR_PGM_PHYS_NOT_MMIO2);
PPGMPAGE pPage;
- rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhysPage, &pPage);
+ rc = pgmPhysGetPageEx(pVM, GCPhysPage, &pPage);
AssertReturnStmt(RT_SUCCESS_NP(rc), pgmUnlock(pVM), rc);
if (PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_MMIO)
{
@@ -1098,16 +1093,16 @@ VMMDECL(int) PGMHandlerPhysicalPageAlias(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCP
*/
LogFlow(("PGMHandlerPhysicalPageAlias: %RGp (%R[pgmpage]) alias for %RGp (%R[pgmpage])\n",
GCPhysPage, pPage, GCPhysPageRemap, pPageRemap ));
- PGM_PAGE_SET_HCPHYS(pPage, PGM_PAGE_GET_HCPHYS(pPageRemap));
- PGM_PAGE_SET_TYPE(pPage, PGMPAGETYPE_MMIO2_ALIAS_MMIO);
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ALLOCATED);
- PGM_PAGE_SET_PAGEID(pPage, PGM_PAGE_GET_PAGEID(pPageRemap));
+ PGM_PAGE_SET_HCPHYS(pVM, pPage, PGM_PAGE_GET_HCPHYS(pPageRemap));
+ PGM_PAGE_SET_TYPE(pVM, pPage, PGMPAGETYPE_MMIO2_ALIAS_MMIO);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ALLOCATED);
+ PGM_PAGE_SET_PAGEID(pVM, pPage, PGM_PAGE_GET_PAGEID(pPageRemap));
PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, PGM_PAGE_HNDL_PHYS_STATE_DISABLED);
pCur->cAliasedPages++;
Assert(pCur->cAliasedPages <= pCur->cPages);
/* Flush its TLB entry. */
- PGMPhysInvalidatePageMapTLBEntry(pVM, GCPhysPage);
+ pgmPhysInvalidatePageMapTLBEntry(pVM, GCPhysPage);
LogFlow(("PGMHandlerPhysicalPageAlias: => %R[pgmpage]\n", pPage));
pgmUnlock(pVM);
@@ -1181,7 +1176,7 @@ VMMDECL(int) PGMHandlerPhysicalPageAliasHC(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS G
* Get and validate the pages.
*/
PPGMPAGE pPage;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhysPage, &pPage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhysPage, &pPage);
AssertReturnStmt(RT_SUCCESS_NP(rc), pgmUnlock(pVM), rc);
if (PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_MMIO)
{
@@ -1199,20 +1194,20 @@ VMMDECL(int) PGMHandlerPhysicalPageAliasHC(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS G
*/
LogFlow(("PGMHandlerPhysicalPageAlias: %RGp (%R[pgmpage]) alias for %RHp\n",
GCPhysPage, pPage, HCPhysPageRemap));
- PGM_PAGE_SET_HCPHYS(pPage, HCPhysPageRemap);
- PGM_PAGE_SET_TYPE(pPage, PGMPAGETYPE_MMIO2_ALIAS_MMIO);
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ALLOCATED);
+ PGM_PAGE_SET_HCPHYS(pVM, pPage, HCPhysPageRemap);
+ PGM_PAGE_SET_TYPE(pVM, pPage, PGMPAGETYPE_MMIO2_ALIAS_MMIO);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ALLOCATED);
/** @todo hack alert
* This needs to be done properly. Currently we get away with it as the recompiler directly calls
* IOM read and write functions. Access through PGMPhysRead/Write will crash the process.
*/
- PGM_PAGE_SET_PAGEID(pPage, NIL_GMM_PAGEID);
+ PGM_PAGE_SET_PAGEID(pVM, pPage, NIL_GMM_PAGEID);
PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, PGM_PAGE_HNDL_PHYS_STATE_DISABLED);
pCur->cAliasedPages++;
Assert(pCur->cAliasedPages <= pCur->cPages);
/* Flush its TLB entry. */
- PGMPhysInvalidatePageMapTLBEntry(pVM, GCPhysPage);
+ pgmPhysInvalidatePageMapTLBEntry(pVM, GCPhysPage);
LogFlow(("PGMHandlerPhysicalPageAliasHC: => %R[pgmpage]\n", pPage));
pgmUnlock(pVM);
@@ -1416,7 +1411,8 @@ DECLCALLBACK(int) pgmHandlerVirtualResetOne(PAVLROGCPTRNODECORE pNode, void *pvU
PPGMVIRTHANDLER pCur = (PPGMVIRTHANDLER)pNode;
PVM pVM = (PVM)pvUser;
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
+
/*
* Iterate the pages and apply the new state.
*/
@@ -1433,7 +1429,7 @@ DECLCALLBACK(int) pgmHandlerVirtualResetOne(PAVLROGCPTRNODECORE pNode, void *pvU
* Update the page state wrt virtual handlers.
*/
PPGMPAGE pPage;
- int rc = pgmPhysGetPageWithHintEx(&pVM->pgm.s, pPhys2Virt->Core.Key, &pPage, &pRamHint);
+ int rc = pgmPhysGetPageWithHintEx(pVM, pPhys2Virt->Core.Key, &pPage, &pRamHint);
if ( RT_SUCCESS(rc)
&& PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) < uState)
PGM_PAGE_SET_HNDL_VIRT_STATE(pPage, uState);
@@ -1642,7 +1638,7 @@ static DECLCALLBACK(int) pgmHandlerVirtualVerifyOne(PAVLROGCPTRNODECORE pNode, v
continue;
}
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhysGst);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhysGst);
if (!pPage)
{
AssertMsgFailed(("virt handler getting ram flags. GCPhysGst=%RGp iPage=%#x %RGv %s\n",
@@ -1682,15 +1678,15 @@ VMMDECL(unsigned) PGMAssertHandlerAndFlagsInSync(PVM pVM)
State.cErrors = 0;
State.pVM = pVM;
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/*
* Check the RAM flags against the handlers.
*/
- for (PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges); pRam; pRam = pRam->CTX_SUFF(pNext))
+ for (PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRangesX); pRam; pRam = pRam->CTX_SUFF(pNext))
{
- const unsigned cPages = pRam->cb >> PAGE_SHIFT;
- for (unsigned iPage = 0; iPage < cPages; iPage++)
+ const uint32_t cPages = pRam->cb >> PAGE_SHIFT;
+ for (uint32_t iPage = 0; iPage < cPages; iPage++)
{
PGMPAGE const *pPage = &pRam->aPages[iPage];
if (PGM_PAGE_HAS_ANY_HANDLERS(pPage))
diff --git a/src/VBox/VMM/VMMAll/PGMAllMap.cpp b/src/VBox/VMM/VMMAll/PGMAllMap.cpp
index 9d158651a..22601cfe9 100644
--- a/src/VBox/VMM/VMMAll/PGMAllMap.cpp
+++ b/src/VBox/VMM/VMMAll/PGMAllMap.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMAllMap.cpp $ */
+/* $Id: PGMAllMap.cpp 36891 2011-04-29 13:22:57Z vboxsync $ */
/** @file
* PGM - Page Manager and Monitor - All context code.
*/
@@ -269,9 +269,9 @@ VMMDECL(int) PGMMapGetPage(PVM pVM, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS
*/
void pgmMapSetShadowPDEs(PVM pVM, PPGMMAPPING pMap, unsigned iNewPDE)
{
- Log4(("pgmMapSetShadowPDEs new pde %x (mappings enabled %d)\n", iNewPDE, pgmMapAreMappingsEnabled(&pVM->pgm.s)));
+ Log4(("pgmMapSetShadowPDEs new pde %x (mappings enabled %d)\n", iNewPDE, pgmMapAreMappingsEnabled(pVM)));
- if ( !pgmMapAreMappingsEnabled(&pVM->pgm.s)
+ if ( !pgmMapAreMappingsEnabled(pVM)
|| pVM->cCpus > 1)
return;
@@ -353,7 +353,7 @@ void pgmMapSetShadowPDEs(PVM pVM, PPGMMAPPING pMap, unsigned iNewPDE)
*/
PPGMPOOLPAGE pPoolPagePd = pgmPoolGetPage(pPool, pShwPdpt->a[iPdPt].u & X86_PDPE_PG_MASK);
AssertFatal(pPoolPagePd);
- if (!pgmPoolIsPageLocked(&pVM->pgm.s, pPoolPagePd))
+ if (!pgmPoolIsPageLocked(pPoolPagePd))
pgmPoolLockPage(pPool, pPoolPagePd);
#ifdef VBOX_STRICT
else if (pShwPaePd->a[iPaePde].u & PGM_PDFLAGS_MAPPING)
@@ -423,12 +423,12 @@ void pgmMapSetShadowPDEs(PVM pVM, PPGMMAPPING pMap, unsigned iNewPDE)
*/
void pgmMapClearShadowPDEs(PVM pVM, PPGMPOOLPAGE pShwPageCR3, PPGMMAPPING pMap, unsigned iOldPDE, bool fDeactivateCR3)
{
- Log(("pgmMapClearShadowPDEs: old pde %x (cPTs=%x) (mappings enabled %d) fDeactivateCR3=%RTbool\n", iOldPDE, pMap->cPTs, pgmMapAreMappingsEnabled(&pVM->pgm.s), fDeactivateCR3));
+ Log(("pgmMapClearShadowPDEs: old pde %x (cPTs=%x) (mappings enabled %d) fDeactivateCR3=%RTbool\n", iOldPDE, pMap->cPTs, pgmMapAreMappingsEnabled(pVM), fDeactivateCR3));
/*
* Skip this if disabled or if it doesn't apply.
*/
- if ( !pgmMapAreMappingsEnabled(&pVM->pgm.s)
+ if ( !pgmMapAreMappingsEnabled(pVM)
|| pVM->cCpus > 1)
return;
@@ -525,7 +525,7 @@ void pgmMapClearShadowPDEs(PVM pVM, PPGMPOOLPAGE pShwPageCR3, PPGMMAPPING pMap,
{
PPGMPOOLPAGE pPoolPagePd = pgmPoolGetPage(pPool, pShwPdpt->a[iPdpt].u & X86_PDPE_PG_MASK);
AssertFatal(pPoolPagePd);
- if (pgmPoolIsPageLocked(&pVM->pgm.s, pPoolPagePd))
+ if (pgmPoolIsPageLocked(pPoolPagePd))
pgmPoolUnlockPage(pPool, pPoolPagePd);
}
break;
@@ -629,7 +629,7 @@ VMMDECL(void) PGMMapCheck(PVM pVM)
/*
* Can skip this if mappings are disabled.
*/
- if (!pgmMapAreMappingsEnabled(&pVM->pgm.s))
+ if (!pgmMapAreMappingsEnabled(pVM))
return;
/* This only applies to raw mode where we only support 1 VCPU. */
@@ -664,7 +664,7 @@ int pgmMapActivateCR3(PVM pVM, PPGMPOOLPAGE pShwPageCR3)
/*
* Skip this if disabled or if it doesn't apply.
*/
- if ( !pgmMapAreMappingsEnabled(&pVM->pgm.s)
+ if ( !pgmMapAreMappingsEnabled(pVM)
|| pVM->cCpus > 1)
return VINF_SUCCESS;
@@ -701,7 +701,7 @@ int pgmMapDeactivateCR3(PVM pVM, PPGMPOOLPAGE pShwPageCR3)
/*
* Skip this if disabled or if it doesn't apply.
*/
- if ( !pgmMapAreMappingsEnabled(&pVM->pgm.s)
+ if ( !pgmMapAreMappingsEnabled(pVM)
|| pVM->cCpus > 1)
return VINF_SUCCESS;
@@ -732,7 +732,7 @@ VMMDECL(bool) PGMMapHasConflicts(PVM pVM)
/*
* Can skip this if mappings are safely fixed.
*/
- if (!pgmMapAreMappingsFloating(&pVM->pgm.s))
+ if (!pgmMapAreMappingsFloating(pVM))
return false;
Assert(pVM->cCpus == 1);
diff --git a/src/VBox/VMM/VMMAll/PGMAllPhys.cpp b/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
index 336e294ed..b3a6b0b58 100644
--- a/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
+++ b/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMAllPhys.cpp $ */
+/* $Id: PGMAllPhys.cpp 37360 2011-06-07 17:28:20Z vboxsync $ */
/** @file
* PGM - Page Manager and Monitor, Physical Memory Addressing.
*/
@@ -142,6 +142,185 @@ VMMDECL(int) pgmPhysRomWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE p
#endif /* IN_RING3 */
/**
+ * Invalidates the RAM range TLBs.
+ *
+ * @param pVM The VM handle.
+ */
+void pgmPhysInvalidRamRangeTlbs(PVM pVM)
+{
+ pgmLock(pVM);
+ for (uint32_t i = 0; i < PGM_RAMRANGE_TLB_ENTRIES; i++)
+ {
+ pVM->pgm.s.apRamRangesTlbR3[i] = NIL_RTR3PTR;
+ pVM->pgm.s.apRamRangesTlbR0[i] = NIL_RTR0PTR;
+ pVM->pgm.s.apRamRangesTlbRC[i] = NIL_RTRCPTR;
+ }
+ pgmUnlock(pVM);
+}
+
+
+/**
+ * Tests if a value of type RTGCPHYS is negative if the type had been signed
+ * instead of unsigned.
+ *
+ * @returns @c true if negative, @c false if positive or zero.
+ * @param a_GCPhys The value to test.
+ * @todo Move me to iprt/types.h.
+ */
+#define RTGCPHYS_IS_NEGATIVE(a_GCPhys) ((a_GCPhys) & ((RTGCPHYS)1 << (sizeof(RTGCPHYS)*8 - 1)))
+
+
+/**
+ * Slow worker for pgmPhysGetRange.
+ *
+ * @copydoc pgmPhysGetRange
+ */
+PPGMRAMRANGE pgmPhysGetRangeSlow(PVM pVM, RTGCPHYS GCPhys)
+{
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbMisses));
+
+ PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangeTree);
+ while (pRam)
+ {
+ RTGCPHYS off = GCPhys - pRam->GCPhys;
+ if (off < pRam->cb)
+ {
+ pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)] = pRam;
+ return pRam;
+ }
+ if (RTGCPHYS_IS_NEGATIVE(off))
+ pRam = pRam->CTX_SUFF(pLeft);
+ else
+ pRam = pRam->CTX_SUFF(pRight);
+ }
+ return NULL;
+}
+
+
+/**
+ * Slow worker for pgmPhysGetRangeAtOrAbove.
+ *
+ * @copydoc pgmPhysGetRangeAtOrAbove
+ */
+PPGMRAMRANGE pgmPhysGetRangeAtOrAboveSlow(PVM pVM, RTGCPHYS GCPhys)
+{
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbMisses));
+
+ PPGMRAMRANGE pLastLeft = NULL;
+ PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangeTree);
+ while (pRam)
+ {
+ RTGCPHYS off = GCPhys - pRam->GCPhys;
+ if (off < pRam->cb)
+ {
+ pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)] = pRam;
+ return pRam;
+ }
+ if (RTGCPHYS_IS_NEGATIVE(off))
+ {
+ pLastLeft = pRam;
+ pRam = pRam->CTX_SUFF(pLeft);
+ }
+ else
+ pRam = pRam->CTX_SUFF(pRight);
+ }
+ return pLastLeft;
+}
+
+
+/**
+ * Slow worker for pgmPhysGetPage.
+ *
+ * @copydoc pgmPhysGetPage
+ */
+PPGMPAGE pgmPhysGetPageSlow(PVM pVM, RTGCPHYS GCPhys)
+{
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbMisses));
+
+ PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangeTree);
+ while (pRam)
+ {
+ RTGCPHYS off = GCPhys - pRam->GCPhys;
+ if (off < pRam->cb)
+ {
+ pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)] = pRam;
+ return &pRam->aPages[off >> PAGE_SHIFT];
+ }
+
+ if (RTGCPHYS_IS_NEGATIVE(off))
+ pRam = pRam->CTX_SUFF(pLeft);
+ else
+ pRam = pRam->CTX_SUFF(pRight);
+ }
+ return NULL;
+}
+
+
+/**
+ * Slow worker for pgmPhysGetPageEx.
+ *
+ * @copydoc pgmPhysGetPageEx
+ */
+int pgmPhysGetPageExSlow(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage)
+{
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbMisses));
+
+ PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangeTree);
+ while (pRam)
+ {
+ RTGCPHYS off = GCPhys - pRam->GCPhys;
+ if (off < pRam->cb)
+ {
+ pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)] = pRam;
+ *ppPage = &pRam->aPages[off >> PAGE_SHIFT];
+ return VINF_SUCCESS;
+ }
+
+ if (RTGCPHYS_IS_NEGATIVE(off))
+ pRam = pRam->CTX_SUFF(pLeft);
+ else
+ pRam = pRam->CTX_SUFF(pRight);
+ }
+
+ *ppPage = NULL;
+ return VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS;
+}
+
+
+/**
+ * Slow worker for pgmPhysGetPageAndRangeEx.
+ *
+ * @copydoc pgmPhysGetPageAndRangeEx
+ */
+int pgmPhysGetPageAndRangeExSlow(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRam)
+{
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbMisses));
+
+ PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangeTree);
+ while (pRam)
+ {
+ RTGCPHYS off = GCPhys - pRam->GCPhys;
+ if (off < pRam->cb)
+ {
+ pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)] = pRam;
+ *ppRam = pRam;
+ *ppPage = &pRam->aPages[off >> PAGE_SHIFT];
+ return VINF_SUCCESS;
+ }
+
+ if (RTGCPHYS_IS_NEGATIVE(off))
+ pRam = pRam->CTX_SUFF(pLeft);
+ else
+ pRam = pRam->CTX_SUFF(pRight);
+ }
+
+ *ppRam = NULL;
+ *ppPage = NULL;
+ return VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS;
+}
+
+
+/**
* Checks if Address Gate 20 is enabled or not.
*
* @returns true if enabled.
@@ -165,7 +344,7 @@ VMMDECL(bool) PGMPhysIsA20Enabled(PVMCPU pVCpu)
*/
VMMDECL(bool) PGMPhysIsGCPhysValid(PVM pVM, RTGCPHYS GCPhys)
{
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
return pPage != NULL;
}
@@ -181,7 +360,7 @@ VMMDECL(bool) PGMPhysIsGCPhysValid(PVM pVM, RTGCPHYS GCPhys)
*/
VMMDECL(bool) PGMPhysIsGCPhysNormal(PVM pVM, RTGCPHYS GCPhys)
{
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
return pPage
&& PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_RAM;
}
@@ -204,7 +383,7 @@ VMMDECL(int) PGMPhysGCPhys2HCPhys(PVM pVM, RTGCPHYS GCPhys, PRTHCPHYS pHCPhys)
{
pgmLock(pVM);
PPGMPAGE pPage;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhys, &pPage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
if (RT_SUCCESS(rc))
*pHCPhys = PGM_PAGE_GET_HCPHYS(pPage) | (GCPhys & PAGE_OFFSET_MASK);
pgmUnlock(pVM);
@@ -217,10 +396,11 @@ VMMDECL(int) PGMPhysGCPhys2HCPhys(PVM pVM, RTGCPHYS GCPhys, PRTHCPHYS pHCPhys)
*
* @param pVM The VM handle.
*/
-VMMDECL(void) PGMPhysInvalidatePageMapTLB(PVM pVM)
+void pgmPhysInvalidatePageMapTLB(PVM pVM)
{
pgmLock(pVM);
STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->StatPageMapTlbFlushes);
+
/* Clear the shared R0/R3 TLB completely. */
for (unsigned i = 0; i < RT_ELEMENTS(pVM->pgm.s.PhysTlbHC.aEntries); i++)
{
@@ -229,22 +409,25 @@ VMMDECL(void) PGMPhysInvalidatePageMapTLB(PVM pVM)
pVM->pgm.s.PhysTlbHC.aEntries[i].pMap = 0;
pVM->pgm.s.PhysTlbHC.aEntries[i].pv = 0;
}
+
/** @todo clear the RC TLB whenever we add it. */
+
pgmUnlock(pVM);
}
+
/**
* Invalidates a page mapping TLB entry
*
* @param pVM The VM handle.
* @param GCPhys GCPhys entry to flush
*/
-VMMDECL(void) PGMPhysInvalidatePageMapTLBEntry(PVM pVM, RTGCPHYS GCPhys)
+void pgmPhysInvalidatePageMapTLBEntry(PVM pVM, RTGCPHYS GCPhys)
{
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->StatPageMapTlbFlushEntry);
- /* Clear the shared R0/R3 TLB entry. */
+
#ifdef IN_RC
unsigned idx = PGM_PAGER3MAPTLB_IDX(GCPhys);
pVM->pgm.s.PhysTlbHC.aEntries[idx].GCPhys = NIL_RTGCPHYS;
@@ -252,13 +435,15 @@ VMMDECL(void) PGMPhysInvalidatePageMapTLBEntry(PVM pVM, RTGCPHYS GCPhys)
pVM->pgm.s.PhysTlbHC.aEntries[idx].pMap = 0;
pVM->pgm.s.PhysTlbHC.aEntries[idx].pv = 0;
#else
+ /* Clear the shared R0/R3 TLB entry. */
PPGMPAGEMAPTLBE pTlbe = &pVM->pgm.s.CTXSUFF(PhysTlb).aEntries[PGM_PAGEMAPTLB_IDX(GCPhys)];
pTlbe->GCPhys = NIL_RTGCPHYS;
pTlbe->pPage = 0;
pTlbe->pMap = 0;
pTlbe->pv = 0;
#endif
- /* @todo clear the RC TLB whenever we add it. */
+
+ /** @todo clear the RC TLB whenever we add it. */
}
/**
@@ -377,7 +562,7 @@ int pgmPhysAllocPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys)
/*
* Prereqs.
*/
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
AssertMsg(PGM_PAGE_IS_ZERO(pPage) || PGM_PAGE_IS_SHARED(pPage), ("%R[pgmpage] %RGp\n", pPage, GCPhys));
Assert(!PGM_PAGE_IS_MMIO(pPage));
@@ -391,7 +576,7 @@ int pgmPhysAllocPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys)
RTGCPHYS GCPhysBase = GCPhys & X86_PDE2M_PAE_PG_MASK;
PPGMPAGE pBasePage;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhysBase, &pBasePage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhysBase, &pBasePage);
AssertRCReturn(rc, rc); /* paranoia; can't happen. */
if (PGM_PAGE_GET_PDE_TYPE(pBasePage) == PGM_PAGE_PDE_TYPE_DONTCARE)
{
@@ -400,7 +585,7 @@ int pgmPhysAllocPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys)
return rc;
}
/* Mark the base as type page table, so we don't check over and over again. */
- PGM_PAGE_SET_PDE_TYPE(pBasePage, PGM_PAGE_PDE_TYPE_PT);
+ PGM_PAGE_SET_PDE_TYPE(pVM, pBasePage, PGM_PAGE_PDE_TYPE_PT);
/* fall back to 4KB pages. */
}
@@ -426,7 +611,7 @@ int pgmPhysAllocPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys)
return rc2;
}
/* re-assert preconditions since pgmPhysEnsureHandyPage may do a context switch. */
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
AssertMsg(PGM_PAGE_IS_ZERO(pPage) || PGM_PAGE_IS_SHARED(pPage), ("%R[pgmpage] %RGp\n", pPage, GCPhys));
Assert(!PGM_PAGE_IS_MMIO(pPage));
@@ -474,11 +659,11 @@ int pgmPhysAllocPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys)
* Do the PGMPAGE modifications.
*/
pVM->pgm.s.cPrivatePages++;
- PGM_PAGE_SET_HCPHYS(pPage, HCPhys);
- PGM_PAGE_SET_PAGEID(pPage, pVM->pgm.s.aHandyPages[iHandyPage].idPage);
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ALLOCATED);
- PGM_PAGE_SET_PDE_TYPE(pPage, PGM_PAGE_PDE_TYPE_PT);
- PGMPhysInvalidatePageMapTLBEntry(pVM, GCPhys);
+ PGM_PAGE_SET_HCPHYS(pVM, pPage, HCPhys);
+ PGM_PAGE_SET_PAGEID(pVM, pPage, pVM->pgm.s.aHandyPages[iHandyPage].idPage);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ALLOCATED);
+ PGM_PAGE_SET_PDE_TYPE(pVM, pPage, PGM_PAGE_PDE_TYPE_PT);
+ pgmPhysInvalidatePageMapTLBEntry(pVM, GCPhys);
/* Copy the shared page contents to the replacement page. */
if (pvSharedPage)
@@ -526,11 +711,11 @@ int pgmPhysAllocLargePage(PVM pVM, RTGCPHYS GCPhys)
/*
* Prereqs.
*/
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
Assert(PGMIsUsingLargePages(pVM));
PPGMPAGE pFirstPage;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhysBase, &pFirstPage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhysBase, &pFirstPage);
if ( RT_SUCCESS(rc)
&& PGM_PAGE_GET_TYPE(pFirstPage) == PGMPAGETYPE_RAM)
{
@@ -543,13 +728,13 @@ int pgmPhysAllocLargePage(PVM pVM, RTGCPHYS GCPhys)
&& PGM_PAGE_GET_STATE(pFirstPage) == PGM_PAGE_STATE_ZERO)
{
/* Lazy approach: check all pages in the 2 MB range.
- * The whole range must be ram and unallocated. */
+ * The whole range must be ram and unallocated. */
GCPhys = GCPhysBase;
unsigned iPage;
for (iPage = 0; iPage < _2M/PAGE_SIZE; iPage++)
{
PPGMPAGE pSubPage;
- rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhys, &pSubPage);
+ rc = pgmPhysGetPageEx(pVM, GCPhys, &pSubPage);
if ( RT_FAILURE(rc)
|| PGM_PAGE_GET_TYPE(pSubPage) != PGMPAGETYPE_RAM /* Anything other than ram implies monitoring. */
|| PGM_PAGE_GET_STATE(pSubPage) != PGM_PAGE_STATE_ZERO) /* Allocated, monitored or shared means we can't use a large page here */
@@ -564,7 +749,7 @@ int pgmPhysAllocLargePage(PVM pVM, RTGCPHYS GCPhys)
{
/* Failed. Mark as requiring a PT so we don't check the whole thing again in the future. */
STAM_REL_COUNTER_INC(&pVM->pgm.s.StatLargePageRefused);
- PGM_PAGE_SET_PDE_TYPE(pFirstPage, PGM_PAGE_PDE_TYPE_PT);
+ PGM_PAGE_SET_PDE_TYPE(pVM, pFirstPage, PGM_PAGE_PDE_TYPE_PT);
return VERR_PGM_INVALID_LARGE_PAGE_RANGE;
}
@@ -628,7 +813,7 @@ int pgmPhysRecheckLargePage(PVM pVM, RTGCPHYS GCPhys, PPGMPAGE pLargePage)
for (i = 1; i < _2M/PAGE_SIZE; i++)
{
PPGMPAGE pPage;
- int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhys, &pPage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
AssertRCBreak(rc);
if ( PGM_PAGE_GET_STATE(pPage) != PGM_PAGE_STATE_ALLOCATED
@@ -646,7 +831,7 @@ int pgmPhysRecheckLargePage(PVM pVM, RTGCPHYS GCPhys, PPGMPAGE pLargePage)
if (i == _2M/PAGE_SIZE)
{
- PGM_PAGE_SET_PDE_TYPE(pLargePage, PGM_PAGE_PDE_TYPE_PDE);
+ PGM_PAGE_SET_PDE_TYPE(pVM, pLargePage, PGM_PAGE_PDE_TYPE_PDE);
pVM->pgm.s.cLargePagesDisabled--;
Log(("pgmPhysRecheckLargePage: page %RGp can be reused!\n", GCPhys - _2M));
return VINF_SUCCESS;
@@ -670,8 +855,8 @@ int pgmPhysRecheckLargePage(PVM pVM, RTGCPHYS GCPhys, PPGMPAGE pLargePage)
void pgmPhysPageMakeWriteMonitoredWritable(PVM pVM, PPGMPAGE pPage)
{
Assert(PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_WRITE_MONITORED);
- PGM_PAGE_SET_WRITTEN_TO(pPage);
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ALLOCATED);
+ PGM_PAGE_SET_WRITTEN_TO(pVM, pPage);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ALLOCATED);
Assert(pVM->pgm.s.cMonitoredPages > 0);
pVM->pgm.s.cMonitoredPages--;
pVM->pgm.s.cWrittenToPages++;
@@ -694,7 +879,7 @@ void pgmPhysPageMakeWriteMonitoredWritable(PVM pVM, PPGMPAGE pPage)
*/
int pgmPhysPageMakeWritable(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
switch (PGM_PAGE_GET_STATE(pPage))
{
case PGM_PAGE_STATE_WRITE_MONITORED:
@@ -743,7 +928,7 @@ int pgmPhysPageMapByPageID(PVM pVM, uint32_t idPage, RTHCPHYS HCPhys, void **ppv
/*
* Validation.
*/
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
AssertReturn(HCPhys && !(HCPhys & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
const uint32_t idChunk = idPage >> GMM_CHUNKID_SHIFT;
AssertReturn(idChunk != NIL_GMM_CHUNKID, VERR_INVALID_PARAMETER);
@@ -819,7 +1004,7 @@ int pgmPhysPageMapByPageID(PVM pVM, uint32_t idPage, RTHCPHYS HCPhys, void **ppv
*/
static int pgmPhysPageMapCommon(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPPGMPAGEMAP ppMap, void **ppv)
{
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
/*
@@ -844,7 +1029,7 @@ static int pgmPhysPageMapCommon(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPPGMP
if (PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_MMIO2)
{
/* Lookup the MMIO2 range and use pvR3 to calc the address. */
- PPGMRAMRANGE pRam = pgmPhysGetRange(&pVM->pgm.s, GCPhys);
+ PPGMRAMRANGE pRam = pgmPhysGetRange(pVM, GCPhys);
AssertMsgReturn(pRam || !pRam->pvR3, ("pRam=%p pPage=%R[pgmpage]\n", pRam, pPage), VERR_INTERNAL_ERROR_2);
*ppv = (void *)((uintptr_t)pRam->pvR3 + (uintptr_t)((GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK) - pRam->GCPhys));
}
@@ -1006,8 +1191,8 @@ int pgmPhysPageMapReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void const
return pgmPhysPageMapCommon(pVM, pPage, GCPhys, &pMapIgnore, (void **)ppv);
}
-
#if !defined(IN_RC) && !defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
+
/**
* Load a guest page into the ring-3 physical TLB.
*
@@ -1017,31 +1202,22 @@ int pgmPhysPageMapReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void const
* @param pPGM The PGM instance pointer.
* @param GCPhys The guest physical address in question.
*/
-int pgmPhysPageLoadIntoTlb(PPGM pPGM, RTGCPHYS GCPhys)
+int pgmPhysPageLoadIntoTlb(PVM pVM, RTGCPHYS GCPhys)
{
- Assert(PGMIsLocked(PGM2VM(pPGM)));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/*
* Find the ram range and page and hand it over to the with-page function.
* 99.8% of requests are expected to be in the first range.
*/
- PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges);
- RTGCPHYS off = GCPhys - pRam->GCPhys;
- if (RT_UNLIKELY(off >= pRam->cb))
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
+ if (!pPage)
{
- do
- {
- pRam = pRam->CTX_SUFF(pNext);
- if (!pRam)
- {
- STAM_COUNTER_INC(&pPGM->CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbMisses));
- return VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS;
- }
- off = GCPhys - pRam->GCPhys;
- } while (off >= pRam->cb);
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbMisses));
+ return VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS;
}
- return pgmPhysPageLoadIntoTlbWithPage(pPGM, &pRam->aPages[off >> PAGE_SHIFT], GCPhys);
+ return pgmPhysPageLoadIntoTlbWithPage(pVM, pPage, GCPhys);
}
@@ -1052,27 +1228,27 @@ int pgmPhysPageLoadIntoTlb(PPGM pPGM, RTGCPHYS GCPhys)
* @retval VINF_SUCCESS on success
* @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
*
- * @param pPGM The PGM instance pointer.
+ * @param pVM The VM handle.
* @param pPage Pointer to the PGMPAGE structure corresponding to
* GCPhys.
* @param GCPhys The guest physical address in question.
*/
-int pgmPhysPageLoadIntoTlbWithPage(PPGM pPGM, PPGMPAGE pPage, RTGCPHYS GCPhys)
+int pgmPhysPageLoadIntoTlbWithPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys)
{
- Assert(PGMIsLocked(PGM2VM(pPGM)));
- STAM_COUNTER_INC(&pPGM->CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbMisses));
+ PGM_LOCK_ASSERT_OWNER(pVM);
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbMisses));
/*
* Map the page.
* Make a special case for the zero page as it is kind of special.
*/
- PPGMPAGEMAPTLBE pTlbe = &pPGM->CTXSUFF(PhysTlb).aEntries[PGM_PAGEMAPTLB_IDX(GCPhys)];
+ PPGMPAGEMAPTLBE pTlbe = &pVM->pgm.s.CTXSUFF(PhysTlb).aEntries[PGM_PAGEMAPTLB_IDX(GCPhys)];
if ( !PGM_PAGE_IS_ZERO(pPage)
&& !PGM_PAGE_IS_BALLOONED(pPage))
{
void *pv;
PPGMPAGEMAP pMap;
- int rc = pgmPhysPageMapCommon(PGM2VM(pPGM), pPage, GCPhys, &pMap, &pv);
+ int rc = pgmPhysPageMapCommon(pVM, pPage, GCPhys, &pMap, &pv);
if (RT_FAILURE(rc))
return rc;
pTlbe->pMap = pMap;
@@ -1081,9 +1257,9 @@ int pgmPhysPageLoadIntoTlbWithPage(PPGM pPGM, PPGMPAGE pPage, RTGCPHYS GCPhys)
}
else
{
- Assert(PGM_PAGE_GET_HCPHYS(pPage) == pPGM->HCPhysZeroPg);
+ AssertMsg(PGM_PAGE_GET_HCPHYS(pPage) == pVM->pgm.s.HCPhysZeroPg, ("%RGp/%R[pgmpage]\n", GCPhys, pPage));
pTlbe->pMap = NULL;
- pTlbe->pv = pPGM->CTXALLSUFF(pvZeroPg);
+ pTlbe->pv = pVM->pgm.s.CTXALLSUFF(pvZeroPg);
}
#ifdef PGM_WITH_PHYS_TLB
if ( PGM_PAGE_GET_TYPE(pPage) < PGMPAGETYPE_ROM_SHADOW
@@ -1097,8 +1273,8 @@ int pgmPhysPageLoadIntoTlbWithPage(PPGM pPGM, PPGMPAGE pPage, RTGCPHYS GCPhys)
pTlbe->pPage = pPage;
return VINF_SUCCESS;
}
-#endif /* !IN_RC && !VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 */
+#endif /* !IN_RC && !VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 */
/**
* Internal version of PGMPhysGCPhys2CCPtr that expects the caller to
@@ -1120,7 +1296,7 @@ int pgmPhysGCPhys2CCPtrInternal(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void *
{
int rc;
AssertReturn(pPage, VERR_INTERNAL_ERROR);
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/*
* Make sure the page is writable.
@@ -1148,7 +1324,7 @@ int pgmPhysGCPhys2CCPtrInternal(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void *
*ppv = (void *)((uintptr_t)pv | (uintptr_t)(GCPhys & PAGE_OFFSET_MASK));
#else
PPGMPAGEMAPTLBE pTlbe;
- rc = pgmPhysPageQueryTlbeWithPage(&pVM->pgm.s, pPage, GCPhys, &pTlbe);
+ rc = pgmPhysPageQueryTlbeWithPage(pVM, pPage, GCPhys, &pTlbe);
if (RT_FAILURE(rc))
return rc;
*ppv = (void *)((uintptr_t)pTlbe->pv | (uintptr_t)(GCPhys & PAGE_OFFSET_MASK));
@@ -1176,7 +1352,7 @@ int pgmPhysGCPhys2CCPtrInternal(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void *
int pgmPhysGCPhys2CCPtrInternalReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, const void **ppv)
{
AssertReturn(pPage, VERR_INTERNAL_ERROR);
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
Assert(PGM_PAGE_GET_HCPHYS(pPage) != 0);
/*
@@ -1193,7 +1369,7 @@ int pgmPhysGCPhys2CCPtrInternalReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys
*ppv = (void *)((uintptr_t)pv | (uintptr_t)(GCPhys & PAGE_OFFSET_MASK));
#else
PPGMPAGEMAPTLBE pTlbe;
- int rc = pgmPhysPageQueryTlbeWithPage(&pVM->pgm.s, pPage, GCPhys, &pTlbe);
+ int rc = pgmPhysPageQueryTlbeWithPage(pVM, pPage, GCPhys, &pTlbe);
if (RT_FAILURE(rc))
return rc;
*ppv = (void *)((uintptr_t)pTlbe->pv | (uintptr_t)(GCPhys & PAGE_OFFSET_MASK));
@@ -1241,7 +1417,7 @@ VMMDECL(int) PGMPhysGCPhys2CCPtr(PVM pVM, RTGCPHYS GCPhys, void **ppv, PPGMPAGEM
* Find the page and make sure it's writable.
*/
PPGMPAGE pPage;
- rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhys, &pPage);
+ rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
if (RT_SUCCESS(rc))
{
if (RT_UNLIKELY(PGM_PAGE_GET_STATE(pPage) != PGM_PAGE_STATE_ALLOCATED))
@@ -1277,7 +1453,7 @@ VMMDECL(int) PGMPhysGCPhys2CCPtr(PVM pVM, RTGCPHYS GCPhys, void **ppv, PPGMPAGEM
* Query the Physical TLB entry for the page (may fail).
*/
PPGMPAGEMAPTLBE pTlbe;
- rc = pgmPhysPageQueryTlbe(&pVM->pgm.s, GCPhys, &pTlbe);
+ rc = pgmPhysPageQueryTlbe(pVM, GCPhys, &pTlbe);
if (RT_SUCCESS(rc))
{
/*
@@ -1291,7 +1467,7 @@ VMMDECL(int) PGMPhysGCPhys2CCPtr(PVM pVM, RTGCPHYS GCPhys, void **ppv, PPGMPAGEM
if (RT_SUCCESS(rc))
{
AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 /* not returned */, ("%Rrc\n", rc));
- rc = pgmPhysPageQueryTlbeWithPage(&pVM->pgm.s, pPage, GCPhys, &pTlbe);
+ rc = pgmPhysPageQueryTlbeWithPage(pVM, pPage, GCPhys, &pTlbe);
}
}
if (RT_SUCCESS(rc))
@@ -1364,7 +1540,7 @@ VMMDECL(int) PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void const **
* Find the page and make sure it's readable.
*/
PPGMPAGE pPage;
- rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhys, &pPage);
+ rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
if (RT_SUCCESS(rc))
{
if (RT_UNLIKELY(PGM_PAGE_IS_MMIO(pPage)))
@@ -1399,7 +1575,7 @@ VMMDECL(int) PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void const **
* Query the Physical TLB entry for the page (may fail).
*/
PPGMPAGEMAPTLBE pTlbe;
- rc = pgmPhysPageQueryTlbe(&pVM->pgm.s, GCPhys, &pTlbe);
+ rc = pgmPhysPageQueryTlbe(pVM, GCPhys, &pTlbe);
if (RT_SUCCESS(rc))
{
/* MMIO pages doesn't have any readable backing. */
@@ -1557,8 +1733,8 @@ VMMDECL(void) PGMPhysReleasePageMappingLock(PVM pVM, PPGMPAGEMAPLOCK pLock)
if (PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_WRITE_MONITORED)
{
- PGM_PAGE_SET_WRITTEN_TO(pPage);
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ALLOCATED);
+ PGM_PAGE_SET_WRITTEN_TO(pVM, pPage);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ALLOCATED);
Assert(pVM->pgm.s.cMonitoredPages > 0);
pVM->pgm.s.cMonitoredPages--;
pVM->pgm.s.cWrittenToPages++;
@@ -1623,7 +1799,7 @@ VMMDECL(int) PGMPhysGCPhys2R3Ptr(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange, PRTR3
PPGMRAMRANGE pRam;
PPGMPAGE pPage;
- int rc = pgmPhysGetPageAndRangeEx(&pVM->pgm.s, GCPhys, &pPage, &pRam);
+ int rc = pgmPhysGetPageAndRangeEx(pVM, GCPhys, &pPage, &pRam);
if (RT_SUCCESS(rc))
rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, (void **)pR3Ptr);
@@ -1784,7 +1960,7 @@ static int pgmPhysReadHandler(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void *pv
Log5(("pgmPhysReadHandler: GCPhys=%RGp cb=%#x pPage=%R[pgmpage] phys %s\n", GCPhys, cb, pPage, R3STRING(pPhys->pszDesc) ));
STAM_PROFILE_START(&pPhys->Stat, h);
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/* Release the PGM lock as MMIO handlers take the IOM lock. (deadlock prevention) */
pgmUnlock(pVM);
rc = pfnHandler(pVM, GCPhys, (void *)pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, pvUser);
@@ -1882,12 +2058,9 @@ VMMDECL(int) PGMPhysRead(PVM pVM, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
/*
* Copy loop on ram ranges.
*/
- PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+ PPGMRAMRANGE pRam = pgmPhysGetRangeAtOrAbove(pVM, GCPhys);
for (;;)
{
- /* Find range. */
- while (pRam && GCPhys > pRam->GCPhysLast)
- pRam = pRam->CTX_SUFF(pNext);
/* Inside range or not? */
if (pRam && GCPhys >= pRam->GCPhys)
{
@@ -1952,9 +2125,7 @@ VMMDECL(int) PGMPhysRead(PVM pVM, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
/*
* Unassigned address space.
*/
- if (!pRam)
- break;
- size_t cb = pRam->GCPhys - GCPhys;
+ size_t cb = pRam ? pRam->GCPhys - GCPhys : ~(size_t)0;
if (cb >= cbRead)
{
memset(pvBuf, 0xff, cbRead);
@@ -1966,6 +2137,10 @@ VMMDECL(int) PGMPhysRead(PVM pVM, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
pvBuf = (char *)pvBuf + cb;
GCPhys += cb;
}
+
+ /* Advance range if necessary. */
+ while (pRam && GCPhys > pRam->GCPhysLast)
+ pRam = pRam->CTX_SUFF(pNext);
} /* Ram range walk */
pgmUnlock(pVM);
@@ -2029,7 +2204,7 @@ static int pgmPhysWriteHandler(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void co
void *pvUser = pCur->CTX_SUFF(pvUser);
STAM_PROFILE_START(&pCur->Stat, h);
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/* Release the PGM lock as MMIO handlers take the IOM lock. (deadlock prevention) */
pgmUnlock(pVM);
rc = pfnHandler(pVM, GCPhys, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE, pvUser);
@@ -2241,7 +2416,7 @@ static int pgmPhysWriteHandler(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void co
Log5(("pgmPhysWriteHandler: GCPhys=%RGp cbRange=%#x pPage=%R[pgmpage] phys %s\n", GCPhys, cbRange, pPage, R3STRING(pPhys->pszDesc) ));
STAM_PROFILE_START(&pPhys->Stat, h);
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/* Release the PGM lock as MMIO handlers take the IOM lock. (deadlock prevention) */
pgmUnlock(pVM);
rc = pfnHandler(pVM, GCPhys, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE, pvUser);
@@ -2310,7 +2485,7 @@ static int pgmPhysWriteHandler(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void co
void *pvUser = pPhys->CTX_SUFF(pvUser);
STAM_PROFILE_START(&pPhys->Stat, h);
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/* Release the PGM lock as MMIO handlers take the IOM lock. (deadlock prevention) */
pgmUnlock(pVM);
rc = pfnHandler(pVM, GCPhys, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE, pvUser);
@@ -2397,12 +2572,9 @@ VMMDECL(int) PGMPhysWrite(PVM pVM, RTGCPHYS GCPhys, const void *pvBuf, size_t cb
/*
* Copy loop on ram ranges.
*/
- PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+ PPGMRAMRANGE pRam = pgmPhysGetRangeAtOrAbove(pVM, GCPhys);
for (;;)
{
- /* Find range. */
- while (pRam && GCPhys > pRam->GCPhysLast)
- pRam = pRam->CTX_SUFF(pNext);
/* Inside range or not? */
if (pRam && GCPhys >= pRam->GCPhys)
{
@@ -2477,6 +2649,10 @@ VMMDECL(int) PGMPhysWrite(PVM pVM, RTGCPHYS GCPhys, const void *pvBuf, size_t cb
pvBuf = (const char *)pvBuf + cb;
GCPhys += cb;
}
+
+ /* Advance range if necessary. */
+ while (pRam && GCPhys > pRam->GCPhysLast)
+ pRam = pRam->CTX_SUFF(pNext);
} /* Ram range walk */
pgmUnlock(pVM);
@@ -2635,7 +2811,7 @@ VMMDECL(int) PGMPhysSimpleWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *p
* bypass access handlers and not set any accessed bits.
*
* @returns VBox status.
- * @param pVCpu The VMCPU handle.
+ * @param pVCpu Handle to the current virtual CPU.
* @param pvDst The destination address.
* @param GCPtrSrc The source address (GC pointer).
* @param cb The number of bytes to read.
@@ -2643,6 +2819,7 @@ VMMDECL(int) PGMPhysSimpleWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *p
VMMDECL(int) PGMPhysSimpleReadGCPtr(PVMCPU pVCpu, void *pvDst, RTGCPTR GCPtrSrc, size_t cb)
{
PVM pVM = pVCpu->CTX_SUFF(pVM);
+/** @todo fix the macro / state handling: VMCPU_ASSERT_EMT_OR_GURU(pVCpu); */
/*
* Treat the first page as a special case.
@@ -2725,7 +2902,7 @@ VMMDECL(int) PGMPhysSimpleReadGCPtr(PVMCPU pVCpu, void *pvDst, RTGCPTR GCPtrSrc,
* bypass access handlers and not set dirty or accessed bits.
*
* @returns VBox status.
- * @param pVCpu The VMCPU handle.
+ * @param pVCpu Handle to the current virtual CPU.
* @param GCPtrDst The destination address (GC pointer).
* @param pvSrc The source address.
* @param cb The number of bytes to write.
@@ -2733,6 +2910,7 @@ VMMDECL(int) PGMPhysSimpleReadGCPtr(PVMCPU pVCpu, void *pvDst, RTGCPTR GCPtrSrc,
VMMDECL(int) PGMPhysSimpleWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb)
{
PVM pVM = pVCpu->CTX_SUFF(pVM);
+ VMCPU_ASSERT_EMT(pVCpu);
/*
* Treat the first page as a special case.
@@ -2804,7 +2982,7 @@ VMMDECL(int) PGMPhysSimpleWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst, const void
* If you don't want to set the dirty bit, use PGMPhysSimpleWriteGCPtr().
*
* @returns VBox status.
- * @param pVCpu The VMCPU handle.
+ * @param pVCpu Handle to the current virtual CPU.
* @param GCPtrDst The destination address (GC pointer).
* @param pvSrc The source address.
* @param cb The number of bytes to write.
@@ -2812,6 +2990,7 @@ VMMDECL(int) PGMPhysSimpleWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst, const void
VMMDECL(int) PGMPhysSimpleDirtyWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb)
{
PVM pVM = pVCpu->CTX_SUFF(pVM);
+ VMCPU_ASSERT_EMT(pVCpu);
/*
* Treat the first page as a special case.
@@ -2883,7 +3062,7 @@ VMMDECL(int) PGMPhysSimpleDirtyWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst, const
* respect access handlers and set accessed bits.
*
* @returns VBox status.
- * @param pVCpu The VMCPU handle.
+ * @param pVCpu Handle to the current virtual CPU.
* @param pvDst The destination address.
* @param GCPtrSrc The source address (GC pointer).
* @param cb The number of bytes to read.
@@ -2895,6 +3074,7 @@ VMMDECL(int) PGMPhysReadGCPtr(PVMCPU pVCpu, void *pvDst, RTGCPTR GCPtrSrc, size_
uint64_t fFlags;
int rc;
PVM pVM = pVCpu->CTX_SUFF(pVM);
+ VMCPU_ASSERT_EMT(pVCpu);
/*
* Anything to do?
@@ -2965,7 +3145,7 @@ VMMDECL(int) PGMPhysReadGCPtr(PVMCPU pVCpu, void *pvDst, RTGCPTR GCPtrSrc, size_
* @retval VINF_SUCCESS.
* @retval VERR_PGM_PHYS_WR_HIT_HANDLER in R0 and GC, NEVER in R3.
*
- * @param pVCpu The VMCPU handle.
+ * @param pVCpu Handle to the current virtual CPU.
* @param GCPtrDst The destination address (GC pointer).
* @param pvSrc The source address.
* @param cb The number of bytes to write.
@@ -2976,6 +3156,7 @@ VMMDECL(int) PGMPhysWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst, const void *pvSrc
uint64_t fFlags;
int rc;
PVM pVM = pVCpu->CTX_SUFF(pVM);
+ VMCPU_ASSERT_EMT(pVCpu);
/*
* Anything to do?
@@ -3058,7 +3239,7 @@ VMMDECL(int) PGMPhysWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst, const void *pvSrc
* @retval VINF_EM_RAW_GUEST_TRAP if an exception was raised but not dispatched yet.
* @retval VINF_TRPM_XCPT_DISPATCHED if an exception was raised and dispatched.
*
- * @param pVCpu The VMCPU handle.
+ * @param pVCpu Handle to the current virtual CPU.
* @param pCtxCore The context core.
* @param pvDst Where to put the bytes we've read.
* @param GCPtrSrc The source address.
@@ -3071,6 +3252,7 @@ VMMDECL(int) PGMPhysInterpretedRead(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *p
{
PVM pVM = pVCpu->CTX_SUFF(pVM);
Assert(cb <= PAGE_SIZE);
+ VMCPU_ASSERT_EMT(pVCpu);
/** @todo r=bird: This isn't perfect!
* -# It's not checking for reserved bits being 1.
@@ -3221,7 +3403,7 @@ VMMDECL(int) PGMPhysInterpretedRead(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *p
* @retval VINF_EM_RAW_GUEST_TRAP if an exception was raised but not dispatched yet.
* @retval VINF_TRPM_XCPT_DISPATCHED if an exception was raised and dispatched.
*
- * @param pVCpu The VMCPU handle.
+ * @param pVCpu Handle to the current virtual CPU.
* @param pCtxCore The context core.
* @param pvDst Where to put the bytes we've read.
* @param GCPtrSrc The source address.
@@ -3238,10 +3420,12 @@ VMMDECL(int) PGMPhysInterpretedRead(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *p
* @remarks This function will dynamically map physical pages in GC. This may
* unmap mappings done by the caller. Be careful!
*/
-VMMDECL(int) PGMPhysInterpretedReadNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCUINTPTR GCPtrSrc, size_t cb, bool fRaiseTrap)
+VMMDECL(int) PGMPhysInterpretedReadNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCUINTPTR GCPtrSrc, size_t cb,
+ bool fRaiseTrap)
{
PVM pVM = pVCpu->CTX_SUFF(pVM);
Assert(cb <= PAGE_SIZE);
+ VMCPU_ASSERT_EMT(pVCpu);
/*
* 1. Translate virtual to physical. This may fault.
@@ -3413,7 +3597,7 @@ VMMDECL(int) PGMPhysInterpretedReadNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCor
* @retval VINF_EM_RAW_GUEST_TRAP if an exception was raised but not dispatched yet.
* @retval VINF_TRPM_XCPT_DISPATCHED if an exception was raised and dispatched.
*
- * @param pVCpu The VMCPU handle.
+ * @param pVCpu Handle to the current virtual CPU.
* @param pCtxCore The context core.
* @param GCPtrDst The destination address.
* @param pvSrc What to write.
@@ -3429,10 +3613,12 @@ VMMDECL(int) PGMPhysInterpretedReadNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCor
* @remarks This function will dynamically map physical pages in GC. This may
* unmap mappings done by the caller. Be careful!
*/
-VMMDECL(int) PGMPhysInterpretedWriteNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb, bool fRaiseTrap)
+VMMDECL(int) PGMPhysInterpretedWriteNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDst, const void *pvSrc,
+ size_t cb, bool fRaiseTrap)
{
Assert(cb <= PAGE_SIZE);
PVM pVM = pVCpu->CTX_SUFF(pVM);
+ VMCPU_ASSERT_EMT(pVCpu);
/*
* 1. Translate virtual to physical. This may fault.
@@ -3607,19 +3793,21 @@ VMMDECL(int) PGMPhysInterpretedWriteNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCo
return rc;
}
+
/**
- * Return the page type of the specified physical address
+ * Return the page type of the specified physical address.
*
+ * @returns The page type.
* @param pVM VM Handle.
* @param GCPhys Guest physical address
*/
VMMDECL(PGMPAGETYPE) PGMPhysGetPageType(PVM pVM, RTGCPHYS GCPhys)
{
- PPGMPAGE pPage;
-
- pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
- if (pPage)
- return (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage);
+ pgmLock(pVM);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
+ PGMPAGETYPE enmPgType = pPage ? (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage) : PGMPAGETYPE_INVALID;
+ pgmUnlock(pVM);
- return PGMPAGETYPE_INVALID;
+ return enmPgType;
}
+
diff --git a/src/VBox/VMM/VMMAll/PGMAllPool.cpp b/src/VBox/VMM/VMMAll/PGMAllPool.cpp
index 6f18b2b04..6aec28541 100644
--- a/src/VBox/VMM/VMMAll/PGMAllPool.cpp
+++ b/src/VBox/VMM/VMMAll/PGMAllPool.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMAllPool.cpp $ */
+/* $Id: PGMAllPool.cpp 37354 2011-06-07 15:05:32Z vboxsync $ */
/** @file
* PGM Shadow Page Pool.
*/
@@ -264,7 +264,7 @@ void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPag
# ifndef IN_RING0
if ((uShw.pPDPae->a[iShw + i].u & (PGM_PDFLAGS_MAPPING | X86_PDE_P)) == (PGM_PDFLAGS_MAPPING | X86_PDE_P))
{
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShwPdpt=%#x iShw=%#x!\n", iShwPdpt, iShw+i));
break;
@@ -291,7 +291,7 @@ void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPag
# ifndef IN_RING0
if ((uShw.pPDPae->a[iShw2].u & (PGM_PDFLAGS_MAPPING | X86_PDE_P)) == (PGM_PDFLAGS_MAPPING | X86_PDE_P))
{
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShwPdpt=%#x iShw2=%#x!\n", iShwPdpt, iShw2));
break;
@@ -370,7 +370,7 @@ void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPag
# ifndef IN_RING0
if (uShw.pPD->a[iShw].u & PGM_PDFLAGS_MAPPING)
{
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
STAM_COUNTER_INC(&(pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZGuestCR3WriteConflict));
LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShw=%#x!\n", iShw));
@@ -402,7 +402,7 @@ void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPag
# ifndef IN_RING0
if (uShw.pPD->a[iShw2].u & PGM_PDFLAGS_MAPPING)
{
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
STAM_COUNTER_INC(&(pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZGuestCR3WriteConflict));
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShw2=%#x!\n", iShw2));
@@ -448,7 +448,7 @@ void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPag
#ifndef IN_RING0
if (uShw.pPDPae->a[iShw].u & PGM_PDFLAGS_MAPPING)
{
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
STAM_COUNTER_INC(&(pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZGuestCR3WriteConflict));
LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShw=%#x!\n", iShw));
@@ -485,7 +485,7 @@ void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPag
if ( iShw2 != iShw
&& uShw.pPDPae->a[iShw2].u & PGM_PDFLAGS_MAPPING)
{
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
STAM_COUNTER_INC(&(pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZGuestCR3WriteConflict));
LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShw2=%#x!\n", iShw2));
@@ -526,7 +526,7 @@ void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPag
# ifndef IN_RING0
if (uShw.pPDPT->a[iShw].u & PGM_PLXFLAGS_MAPPING)
{
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
STAM_COUNTER_INC(&(pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZGuestCR3WriteConflict));
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
LogFlow(("pgmPoolMonitorChainChanging: Detected pdpt conflict at iShw=%#x!\n", iShw));
@@ -557,7 +557,7 @@ void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPag
# ifndef IN_RING0
if (uShw.pPDPT->a[iShw2].u & PGM_PLXFLAGS_MAPPING)
{
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
STAM_COUNTER_INC(&(pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZGuestCR3WriteConflict));
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShw2=%#x!\n", iShw2));
@@ -1124,7 +1124,7 @@ DECLEXPORT(int) pgmPoolAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE
&& pvFault == (pPage->pvLastAccessHandlerFault + pDis->param1.size)
&& pVCpu->pgm.s.cPoolAccessHandler == (pPage->cLastAccessHandlerCount + 1))
{
- Log(("Possible page reuse cMods=%d -> %d (locked=%d type=%s)\n", pPage->cModifications, pPage->cModifications * 2, pgmPoolIsPageLocked(&pVM->pgm.s, pPage), pgmPoolPoolKindToStr(pPage->enmKind)));
+ Log(("Possible page reuse cMods=%d -> %d (locked=%d type=%s)\n", pPage->cModifications, pPage->cModifications * 2, pgmPoolIsPageLocked(pPage), pgmPoolPoolKindToStr(pPage->enmKind)));
Assert(pPage->cModifications < 32000);
pPage->cModifications = pPage->cModifications * 2;
pPage->pvLastAccessHandlerFault = pvFault;
@@ -1137,7 +1137,7 @@ DECLEXPORT(int) pgmPoolAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE
}
if (pPage->cModifications >= cMaxModifications)
- Log(("Mod overflow %RGv cMods=%d (locked=%d type=%s)\n", pvFault, pPage->cModifications, pgmPoolIsPageLocked(&pVM->pgm.s, pPage), pgmPoolPoolKindToStr(pPage->enmKind)));
+ Log(("Mod overflow %RGv cMods=%d (locked=%d type=%s)\n", pvFault, pPage->cModifications, pgmPoolIsPageLocked(pPage), pgmPoolPoolKindToStr(pPage->enmKind)));
/*
* Check if it's worth dealing with.
@@ -1145,7 +1145,7 @@ DECLEXPORT(int) pgmPoolAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE
bool fReused = false;
bool fNotReusedNotForking = false;
if ( ( pPage->cModifications < cMaxModifications /** @todo #define */ /** @todo need to check that it's not mapping EIP. */ /** @todo adjust this! */
- || pgmPoolIsPageLocked(&pVM->pgm.s, pPage)
+ || pgmPoolIsPageLocked(pPage)
)
&& !(fReused = pgmPoolMonitorIsReused(pVM, pVCpu, pRegFrame, pDis, pvFault))
&& !pgmPoolMonitorIsForking(pPool, pDis, GCPhysFault & PAGE_OFFSET_MASK))
@@ -1254,7 +1254,7 @@ DECLEXPORT(int) pgmPoolAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE
)
)
{
- Assert(!pgmPoolIsPageLocked(&pVM->pgm.s, pPage));
+ Assert(!pgmPoolIsPageLocked(pPage));
Assert(pPage->fDirty == false);
/* Flush any monitored duplicates as we will disable write protection. */
@@ -1716,7 +1716,7 @@ void pgmPoolAddDirtyPage(PVM pVM, PPGMPOOL pPool, PPGMPOOLPAGE pPage)
{
unsigned idxFree;
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
AssertCompile(RT_ELEMENTS(pPool->aDirtyPages) == 8 || RT_ELEMENTS(pPool->aDirtyPages) == 16);
Assert(!pPage->fDirty);
@@ -1790,7 +1790,7 @@ void pgmPoolAddDirtyPage(PVM pVM, PPGMPOOL pPool, PPGMPOOLPAGE pPage)
bool pgmPoolIsDirtyPage(PVM pVM, RTGCPHYS GCPhys)
{
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
if (!pPool->cDirtyPages)
return false;
@@ -1819,7 +1819,7 @@ bool pgmPoolIsDirtyPage(PVM pVM, RTGCPHYS GCPhys)
void pgmPoolResetDirtyPages(PVM pVM)
{
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
Assert(pPool->cDirtyPages <= RT_ELEMENTS(pPool->aDirtyPages));
if (!pPool->cDirtyPages)
@@ -1858,7 +1858,7 @@ void pgmPoolResetDirtyPages(PVM pVM)
void pgmPoolResetDirtyPage(PVM pVM, RTGCPTR GCPtrPage)
{
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
Assert(pPool->cDirtyPages <= RT_ELEMENTS(pPool->aDirtyPages));
if (!pPool->cDirtyPages)
@@ -1879,7 +1879,7 @@ void pgmPoolResetDirtyPage(PVM pVM, RTGCPTR GCPtrPage)
void pgmPoolInvalidateDirtyPage(PVM pVM, RTGCPHYS GCPhysPT)
{
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
- Assert(PGMIsLocked(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
Assert(pPool->cDirtyPages <= RT_ELEMENTS(pPool->aDirtyPages));
unsigned idxDirtyPage = RT_ELEMENTS(pPool->aDirtyPages);
@@ -2022,7 +2022,7 @@ static int pgmPoolCacheFreeOne(PPGMPOOL pPool, uint16_t iUser)
* Reject any attempts at flushing the currently active shadow CR3 mapping.
* Call pgmPoolCacheUsed to move the page to the head of the age list.
*/
- if (!pgmPoolIsPageLocked(&pPool->CTX_SUFF(pVM)->pgm.s, pPage))
+ if (!pgmPoolIsPageLocked(pPage))
break;
LogFlow(("pgmPoolCacheFreeOne: refuse CR3 mapping\n"));
pgmPoolCacheUsed(pPool, pPage);
@@ -3354,7 +3354,7 @@ static void pgmPoolTrackFlushGCPhysPT(PVM pVM, PPGMPAGE pPhysPage, bool fFlushPT
STAM_PROFILE_START(&pPool->StatTrackFlushGCPhysPT, f);
bool fKeptPTEs = pgmPoolTrackFlushGCPhysPTInt(pVM, pPhysPage, fFlushPTEs, iShw, PGM_PAGE_GET_PTE_INDEX(pPhysPage));
if (!fKeptPTEs)
- PGM_PAGE_SET_TRACKING(pPhysPage, 0);
+ PGM_PAGE_SET_TRACKING(pVM, pPhysPage, 0);
STAM_PROFILE_STOP(&pPool->StatTrackFlushGCPhysPT, f);
}
@@ -3369,7 +3369,7 @@ static void pgmPoolTrackFlushGCPhysPT(PVM pVM, PPGMPAGE pPhysPage, bool fFlushPT
*/
static void pgmPoolTrackFlushGCPhysPTs(PVM pVM, PPGMPAGE pPhysPage, bool fFlushPTEs, uint16_t iPhysExt)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
bool fKeepList = false;
@@ -3406,7 +3406,7 @@ static void pgmPoolTrackFlushGCPhysPTs(PVM pVM, PPGMPAGE pPhysPage, bool fFlushP
pPhysExt->iNext = pPool->iPhysExtFreeHead;
pPool->iPhysExtFreeHead = iPhysExtStart;
/* Invalidate the tracking data. */
- PGM_PAGE_SET_TRACKING(pPhysPage, 0);
+ PGM_PAGE_SET_TRACKING(pVM, pPhysPage, 0);
}
STAM_PROFILE_STOP(&pPool->StatTrackFlushGCPhysPTs, f);
@@ -3450,7 +3450,7 @@ int pgmPoolTrackUpdateGCPhys(PVM pVM, RTGCPHYS GCPhysPage, PPGMPAGE pPhysPage, b
PPGMPAGE pLargePage;
if (GCPhysBase != GCPhysPage)
{
- pLargePage = pgmPhysGetPage(&pVM->pgm.s, GCPhysBase);
+ pLargePage = pgmPhysGetPage(pVM, GCPhysBase);
AssertFatal(pLargePage);
}
else
@@ -3461,7 +3461,7 @@ int pgmPoolTrackUpdateGCPhys(PVM pVM, RTGCPHYS GCPhysPage, PPGMPAGE pPhysPage, b
if (PGM_PAGE_GET_PDE_TYPE(pLargePage) == PGM_PAGE_PDE_TYPE_PDE)
{
/* Mark the large page as disabled as we need to break it up to change a single page in the 2 MB range. */
- PGM_PAGE_SET_PDE_TYPE(pLargePage, PGM_PAGE_PDE_TYPE_PDE_DISABLED);
+ PGM_PAGE_SET_PDE_TYPE(pVM, pLargePage, PGM_PAGE_PDE_TYPE_PDE_DISABLED);
pVM->pgm.s.cLargePagesDisabled++;
/* Update the base as that *only* that one has a reference and there's only one PDE to clear. */
@@ -3665,7 +3665,7 @@ int pgmPoolTrackFlushGCPhysPTsSlow(PVM pVM, PPGMPAGE pPhysPage)
}
}
- PGM_PAGE_SET_TRACKING(pPhysPage, 0);
+ PGM_PAGE_SET_TRACKING(pVM, pPhysPage, 0);
STAM_PROFILE_STOP(&pPool->StatTrackFlushGCPhysPTsSlow, s);
/*
@@ -3706,7 +3706,7 @@ static void pgmPoolTrackClearPageUser(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PCPGMP
LogFlow(("pgmPoolTrackClearPageUser: clear %x in %s (%RGp) (flushing %s)\n", iUserTable, pgmPoolPoolKindToStr(pUserPage->enmKind), pUserPage->Core.Key, pgmPoolPoolKindToStr(pPage->enmKind)));
/* Safety precaution in case we change the paging for other modes too in the future. */
- Assert(!pgmPoolIsPageLocked(&pPool->CTX_SUFF(pVM)->pgm.s, pPage));
+ Assert(!pgmPoolIsPageLocked(pPage));
#ifdef VBOX_STRICT
/*
@@ -3851,7 +3851,7 @@ static void pgmPoolTrackClearPageUsers(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
*/
PPGMPOOLPHYSEXT pgmPoolTrackPhysExtAlloc(PVM pVM, uint16_t *piPhysExt)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
uint16_t iPhysExt = pPool->iPhysExtFreeHead;
if (iPhysExt == NIL_PGMPOOL_PHYSEXT_INDEX)
@@ -3875,7 +3875,7 @@ PPGMPOOLPHYSEXT pgmPoolTrackPhysExtAlloc(PVM pVM, uint16_t *piPhysExt)
*/
void pgmPoolTrackPhysExtFree(PVM pVM, uint16_t iPhysExt)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
Assert(iPhysExt < pPool->cMaxPhysExts);
PPGMPOOLPHYSEXT pPhysExt = &pPool->CTX_SUFF(paPhysExts)[iPhysExt];
@@ -3897,7 +3897,7 @@ void pgmPoolTrackPhysExtFree(PVM pVM, uint16_t iPhysExt)
*/
void pgmPoolTrackPhysExtFreeList(PVM pVM, uint16_t iPhysExt)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
const uint16_t iPhysExtStart = iPhysExt;
@@ -3934,7 +3934,7 @@ void pgmPoolTrackPhysExtFreeList(PVM pVM, uint16_t iPhysExt)
*/
static uint16_t pgmPoolTrackPhysExtInsert(PVM pVM, uint16_t iPhysExt, uint16_t iShwPT, uint16_t iPte)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
PPGMPOOLPHYSEXT paPhysExts = pPool->CTX_SUFF(paPhysExts);
@@ -4068,13 +4068,13 @@ uint16_t pgmPoolTrackPhysExtAddref(PVM pVM, PPGMPAGE pPhysPage, uint16_t u16, ui
*/
void pgmPoolTrackPhysExtDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMPAGE pPhysPage, uint16_t iPte)
{
+ PVM pVM = pPool->CTX_SUFF(pVM);
const unsigned cRefs = PGM_PAGE_GET_TD_CREFS(pPhysPage);
AssertFatalMsg(cRefs == PGMPOOL_TD_CREFS_PHYSEXT, ("cRefs=%d pPhysPage=%R[pgmpage] pPage=%p:{.idx=%d}\n", cRefs, pPhysPage, pPage, pPage->idx));
uint16_t iPhysExt = PGM_PAGE_GET_TD_IDX(pPhysPage);
if (iPhysExt != PGMPOOL_TD_IDX_OVERFLOWED)
{
- PVM pVM = pPool->CTX_SUFF(pVM);
pgmLock(pVM);
uint16_t iPhysExtPrev = NIL_PGMPOOL_PHYSEXT_INDEX;
@@ -4110,13 +4110,13 @@ void pgmPoolTrackPhysExtDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMPAGE
/* lonely node */
pgmPoolTrackPhysExtFree(pVM, iPhysExt);
Log2(("pgmPoolTrackPhysExtDerefGCPhys: pPhysPage=%R[pgmpage] idx=%d lonely\n", pPhysPage, pPage->idx));
- PGM_PAGE_SET_TRACKING(pPhysPage, 0);
+ PGM_PAGE_SET_TRACKING(pVM, pPhysPage, 0);
}
else if (iPhysExtPrev == NIL_PGMPOOL_PHYSEXT_INDEX)
{
/* head */
Log2(("pgmPoolTrackPhysExtDerefGCPhys: pPhysPage=%R[pgmpage] idx=%d head\n", pPhysPage, pPage->idx));
- PGM_PAGE_SET_TRACKING(pPhysPage, PGMPOOL_TD_MAKE(PGMPOOL_TD_CREFS_PHYSEXT, iPhysExtNext));
+ PGM_PAGE_SET_TRACKING(pVM, pPhysPage, PGMPOOL_TD_MAKE(PGMPOOL_TD_CREFS_PHYSEXT, iPhysExtNext));
pgmPoolTrackPhysExtFree(pVM, iPhysExt);
}
else
@@ -4147,9 +4147,9 @@ void pgmPoolTrackPhysExtDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMPAGE
/**
* Clear references to guest physical memory.
*
- * This is the same as pgmPoolTracDerefGCPhys except that the guest physical address
- * is assumed to be correct, so the linear search can be skipped and we can assert
- * at an earlier point.
+ * This is the same as pgmPoolTracDerefGCPhysHint except that the guest
+ * physical address is assumed to be correct, so the linear search can be
+ * skipped and we can assert at an earlier point.
*
* @param pPool The pool.
* @param pPage The page.
@@ -4160,34 +4160,29 @@ void pgmPoolTrackPhysExtDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMPAGE
static void pgmPoolTracDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTHCPHYS HCPhys, RTGCPHYS GCPhys, uint16_t iPte)
{
/*
- * Walk range list.
+ * Lookup the page and check if it checks out before derefing it.
*/
- PPGMRAMRANGE pRam = pPool->CTX_SUFF(pVM)->pgm.s.CTX_SUFF(pRamRanges);
- while (pRam)
+ PVM pVM = pPool->CTX_SUFF(pVM);
+ PPGMPAGE pPhysPage = pgmPhysGetPage(pVM, GCPhys);
+ if (pPhysPage)
{
- RTGCPHYS off = GCPhys - pRam->GCPhys;
- if (off < pRam->cb)
- {
- /* does it match? */
- const unsigned iPage = off >> PAGE_SHIFT;
- Assert(PGM_PAGE_GET_HCPHYS(&pRam->aPages[iPage]));
+ Assert(PGM_PAGE_GET_HCPHYS(pPhysPage));
#ifdef LOG_ENABLED
- RTHCPHYS HCPhysPage = PGM_PAGE_GET_HCPHYS(&pRam->aPages[iPage]);
- Log2(("pgmPoolTracDerefGCPhys %RHp vs %RHp\n", HCPhysPage, HCPhys));
+ RTHCPHYS HCPhysPage = PGM_PAGE_GET_HCPHYS(pPhysPage);
+ Log2(("pgmPoolTracDerefGCPhys %RHp vs %RHp\n", HCPhysPage, HCPhys));
#endif
- if (PGM_PAGE_GET_HCPHYS(&pRam->aPages[iPage]) == HCPhys)
- {
- Assert(pPage->cPresent);
- Assert(pPool->cPresent);
- pPage->cPresent--;
- pPool->cPresent--;
- pgmTrackDerefGCPhys(pPool, pPage, &pRam->aPages[iPage], iPte);
- return;
- }
- AssertFatalMsgFailed(("HCPhys=%RHp GCPhys=%RGp; found page index %x HCPhys=%RHp\n", HCPhys, GCPhys, iPage, PGM_PAGE_GET_HCPHYS(&pRam->aPages[iPage])));
- break;
+ if (PGM_PAGE_GET_HCPHYS(pPhysPage) == HCPhys)
+ {
+ Assert(pPage->cPresent);
+ Assert(pPool->cPresent);
+ pPage->cPresent--;
+ pPool->cPresent--;
+ pgmTrackDerefGCPhys(pPool, pPage, pPhysPage, iPte);
+ return;
}
- pRam = pRam->CTX_SUFF(pNext);
+
+ AssertFatalMsgFailed(("HCPhys=%RHp GCPhys=%RGp; found page has HCPhys=%RHp\n",
+ HCPhys, GCPhys, PGM_PAGE_GET_HCPHYS(pPhysPage)));
}
AssertFatalMsgFailed(("HCPhys=%RHp GCPhys=%RGp\n", HCPhys, GCPhys));
}
@@ -4204,42 +4199,36 @@ static void pgmPoolTracDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTHCPHYS
*/
void pgmPoolTracDerefGCPhysHint(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTHCPHYS HCPhys, RTGCPHYS GCPhysHint, uint16_t iPte)
{
- RTHCPHYS HCPhysExpected = 0xDEADBEEFDEADBEEFULL;
-
Log4(("pgmPoolTracDerefGCPhysHint %RHp %RGp\n", HCPhys, GCPhysHint));
/*
- * Walk range list.
+ * Try the hint first.
*/
- PPGMRAMRANGE pRam = pPool->CTX_SUFF(pVM)->pgm.s.CTX_SUFF(pRamRanges);
- while (pRam)
+ RTHCPHYS HCPhysHinted;
+ PVM pVM = pPool->CTX_SUFF(pVM);
+ PPGMPAGE pPhysPage = pgmPhysGetPage(pVM, GCPhysHint);
+ if (pPhysPage)
{
- RTGCPHYS off = GCPhysHint - pRam->GCPhys;
- if (off < pRam->cb)
+ HCPhysHinted = PGM_PAGE_GET_HCPHYS(pPhysPage);
+ Assert(HCPhysHinted);
+ if (HCPhysHinted == HCPhys)
{
- /* does it match? */
- const unsigned iPage = off >> PAGE_SHIFT;
- Assert(PGM_PAGE_GET_HCPHYS(&pRam->aPages[iPage]));
- if (PGM_PAGE_GET_HCPHYS(&pRam->aPages[iPage]) == HCPhys)
- {
- Assert(pPage->cPresent);
- Assert(pPool->cPresent);
- pPage->cPresent--;
- pPool->cPresent--;
- pgmTrackDerefGCPhys(pPool, pPage, &pRam->aPages[iPage], iPte);
- return;
- }
- HCPhysExpected = PGM_PAGE_GET_HCPHYS(&pRam->aPages[iPage]);
- break;
+ Assert(pPage->cPresent);
+ Assert(pPool->cPresent);
+ pPage->cPresent--;
+ pPool->cPresent--;
+ pgmTrackDerefGCPhys(pPool, pPage, pPhysPage, iPte);
+ return;
}
- pRam = pRam->CTX_SUFF(pNext);
}
+ else
+ HCPhysHinted = UINT64_C(0xdeadbeefdeadbeef);
/*
- * Damn, the hint didn't work. We'll have to do an expensive linear search.
+ * Damn, the hint didn't work. We'll have to do an expensive linear search.
*/
STAM_COUNTER_INC(&pPool->StatTrackLinearRamSearches);
- pRam = pPool->CTX_SUFF(pVM)->pgm.s.CTX_SUFF(pRamRanges);
+ PPGMRAMRANGE pRam = pPool->CTX_SUFF(pVM)->pgm.s.CTX_SUFF(pRamRangesX);
while (pRam)
{
unsigned iPage = pRam->cb >> PAGE_SHIFT;
@@ -4260,7 +4249,7 @@ void pgmPoolTracDerefGCPhysHint(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTHCPHYS HCP
pRam = pRam->CTX_SUFF(pNext);
}
- AssertFatalMsgFailed(("HCPhys=%RHp GCPhysHint=%RGp (Expected HCPhys with hint = %RHp)\n", HCPhys, GCPhysHint, HCPhysExpected));
+ AssertFatalMsgFailed(("HCPhys=%RHp GCPhysHint=%RGp (Hinted page has HCPhys = %RHp)\n", HCPhys, GCPhysHint, HCPhysHinted));
}
@@ -4777,7 +4766,7 @@ int pgmPoolFlushPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage, bool fFlush)
/*
* Quietly reject any attempts at flushing the currently active shadow CR3 mapping
*/
- if (pgmPoolIsPageLocked(&pVM->pgm.s, pPage))
+ if (pgmPoolIsPageLocked(pPage))
{
AssertMsg( pPage->enmKind == PGMPOOLKIND_64BIT_PML4
|| pPage->enmKind == PGMPOOLKIND_PAE_PDPT
@@ -5106,8 +5095,7 @@ void pgmPoolFree(PVM pVM, RTHCPHYS HCPhys, uint16_t iUser, uint32_t iUserTable)
PPGMPOOLPAGE pgmPoolGetPage(PPGMPOOL pPool, RTHCPHYS HCPhys)
{
PVM pVM = pPool->CTX_SUFF(pVM);
-
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/*
* Look up the page.
@@ -5129,7 +5117,7 @@ PPGMPOOLPAGE pgmPoolGetPage(PPGMPOOL pPool, RTHCPHYS HCPhys)
PPGMPOOLPAGE pgmPoolQueryPageForDbg(PPGMPOOL pPool, RTHCPHYS HCPhys)
{
PVM pVM = pPool->CTX_SUFF(pVM);
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
return (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, HCPhys & X86_PTE_PAE_PG_MASK);
}
@@ -5183,7 +5171,7 @@ void pgmPoolFlushPageByGCPhys(PVM pVM, RTGCPHYS GCPhys)
else
#endif
STAM_COUNTER_INC(&pPool->StatForceFlushPage);
- Assert(!pgmPoolIsPageLocked(&pVM->pgm.s, pPage));
+ Assert(!pgmPoolIsPageLocked(pPage));
pgmPoolMonitorChainFlush(pPool, pPage);
return;
}
@@ -5249,7 +5237,7 @@ void pgmR3PoolReset(PVM pVM)
{
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
STAM_PROFILE_START(&pPool->StatR3Reset, a);
LogFlow(("pgmR3PoolReset:\n"));
@@ -5327,13 +5315,13 @@ void pgmR3PoolReset(PVM pVM)
/*
* Clear all the GCPhys links and rebuild the phys ext free list.
*/
- for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
pRam;
pRam = pRam->CTX_SUFF(pNext))
{
unsigned iPage = pRam->cb >> PAGE_SHIFT;
while (iPage-- > 0)
- PGM_PAGE_SET_TRACKING(&pRam->aPages[iPage], 0);
+ PGM_PAGE_SET_TRACKING(pVM, &pRam->aPages[iPage], 0);
}
pPool->iPhysExtFreeHead = 0;
diff --git a/src/VBox/VMM/VMMAll/PGMAllShw.h b/src/VBox/VMM/VMMAll/PGMAllShw.h
index 51e6ce166..a5f43b39d 100644
--- a/src/VBox/VMM/VMMAll/PGMAllShw.h
+++ b/src/VBox/VMM/VMMAll/PGMAllShw.h
@@ -1,4 +1,4 @@
-/* $Id: PGMAllShw.h $ */
+/* $Id: PGMAllShw.h 37354 2011-06-07 15:05:32Z vboxsync $ */
/** @file
* VBox - Page Manager, Shadow Paging Template - All context code.
*/
@@ -201,7 +201,7 @@ PGM_SHW_DECL(int, GetPage)(PVMCPU pVCpu, RTGCUINTPTR GCPtr, uint64_t *pfFlags, P
#else /* PGM_SHW_TYPE != PGM_TYPE_NESTED && PGM_SHW_TYPE != PGM_TYPE_EPT */
PVM pVM = pVCpu->CTX_SUFF(pVM);
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/*
* Get the PDE.
@@ -300,7 +300,7 @@ PGM_SHW_DECL(int, GetPage)(PVMCPU pVCpu, RTGCUINTPTR GCPtr, uint64_t *pfFlags, P
|| PGM_SHW_TYPE == PGM_TYPE_EPT
AssertFailed(); /* can't happen */
# else
- Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
+ Assert(pgmMapAreMappingsEnabled(pVM));
PPGMMAPPING pMap = pgmGetMapping(pVM, (RTGCPTR)GCPtr);
AssertMsgReturn(pMap, ("GCPtr=%RGv\n", GCPtr), VERR_INTERNAL_ERROR);
@@ -364,7 +364,8 @@ PGM_SHW_DECL(int, ModifyPage)(PVMCPU pVCpu, RTGCUINTPTR GCPtr, size_t cb, uint64
PVM pVM = pVCpu->CTX_SUFF(pVM);
int rc;
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
+
/*
* Walk page tables and pages till we're done.
*/
@@ -461,7 +462,7 @@ PGM_SHW_DECL(int, ModifyPage)(PVMCPU pVCpu, RTGCUINTPTR GCPtr, size_t cb, uint64
if (RT_SUCCESS(rc))
{
Assert(fGstPte & X86_PTE_RW);
- PPGMPAGE pPage = pgmPhysGetPage(&pVCpu->CTX_SUFF(pVM)->pgm.s, GCPhys);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
Assert(pPage);
if (pPage)
{
diff --git a/src/VBox/VMM/VMMAll/REMAll.cpp b/src/VBox/VMM/VMMAll/REMAll.cpp
index ebdf58c3c..b0d633737 100644
--- a/src/VBox/VMM/VMMAll/REMAll.cpp
+++ b/src/VBox/VMM/VMMAll/REMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: REMAll.cpp $ */
+/* $Id: REMAll.cpp 37702 2011-06-30 10:09:59Z vboxsync $ */
/** @file
* REM - Recompiled Execution Monitor, all Contexts part.
*/
@@ -46,7 +46,7 @@ VMMDECL(void) REMNotifyInvalidatePage(PVM pVM, RTGCPTR GCPtrPage)
* Try take the REM lock and push the address onto the array.
*/
if ( pVM->rem.s.cInvalidatedPages < RT_ELEMENTS(pVM->rem.s.aGCPtrInvalidatedPages)
- && EMTryEnterRemLock(pVM) == VINF_SUCCESS)
+ && EMRemTryLock(pVM) == VINF_SUCCESS)
{
uint32_t iPage = pVM->rem.s.cInvalidatedPages;
if (iPage < RT_ELEMENTS(pVM->rem.s.aGCPtrInvalidatedPages))
diff --git a/src/VBox/VMM/VMMAll/SELMAll.cpp b/src/VBox/VMM/VMMAll/SELMAll.cpp
index f28411c84..3e2506524 100644
--- a/src/VBox/VMM/VMMAll/SELMAll.cpp
+++ b/src/VBox/VMM/VMMAll/SELMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: SELMAll.cpp $ */
+/* $Id: SELMAll.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* SELM All contexts.
*/
@@ -26,12 +26,12 @@
#include <VBox/vmm/pgm.h>
#include "SELMInternal.h"
#include <VBox/vmm/vm.h>
-#include <VBox/x86.h>
#include <VBox/err.h>
#include <VBox/param.h>
#include <iprt/assert.h>
#include <VBox/log.h>
#include <VBox/vmm/vmm.h>
+#include <iprt/x86.h>
diff --git a/src/VBox/VMM/VMMAll/TMAll.cpp b/src/VBox/VMM/VMMAll/TMAll.cpp
index 897d1e49a..e9d1763ac 100644
--- a/src/VBox/VMM/VMMAll/TMAll.cpp
+++ b/src/VBox/VMM/VMMAll/TMAll.cpp
@@ -1,10 +1,10 @@
-/* $Id: TMAll.cpp $ */
+/* $Id: TMAll.cpp 37527 2011-06-17 10:18:02Z vboxsync $ */
/** @file
* TM - Timeout Manager, all contexts.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -22,6 +22,7 @@
#define LOG_GROUP LOG_GROUP_TM
#include <VBox/vmm/tm.h>
#include <VBox/vmm/mm.h>
+#include <VBox/vmm/dbgftrace.h>
#ifdef IN_RING3
# include <VBox/vmm/rem.h>
#endif
@@ -40,6 +41,8 @@
# include <iprt/thread.h>
#endif
+#include "TMInline.h"
+
/*******************************************************************************
* Defined Constants And Macros *
@@ -52,9 +55,15 @@
do { \
if ((pTimer)->pCritSect) \
{ \
+ VMSTATE enmState; \
PPDMCRITSECT pCritSect = (PPDMCRITSECT)MMHyperR3ToCC((pTimer)->CTX_SUFF(pVM), (pTimer)->pCritSect); \
- AssertMsg(pCritSect && PDMCritSectIsOwner(pCritSect), \
- ("pTimer=%p (%s) pCritSect=%p\n", pTimer, R3STRING(pTimer->pszDesc), (pTimer)->pCritSect)); \
+ AssertMsg( pCritSect \
+ && ( PDMCritSectIsOwner(pCritSect) \
+ || (enmState = (pTimer)->CTX_SUFF(pVM)->enmVMState) == VMSTATE_CREATING \
+ || enmState == VMSTATE_RESETTING \
+ || enmState == VMSTATE_RESETTING_LS ),\
+ ("pTimer=%p (%s) pCritSect=%p (%s)\n", pTimer, R3STRING(pTimer->pszDesc), \
+ (pTimer)->pCritSect, R3STRING(PDMR3CritSectName((pTimer)->pCritSect)) )); \
} \
} while (0)
#else
@@ -62,95 +71,17 @@
#endif
-#ifndef tmTimerLock
-
-/**
- * Try take the timer lock, wait in ring-3 return VERR_SEM_BUSY in R0/RC.
- *
- * @retval VINF_SUCCESS on success (always in ring-3).
- * @retval VERR_SEM_BUSY in RC and R0 if the semaphore is busy.
- *
- * @param pVM The VM handle.
- *
- * @thread EMTs for the time being.
- */
-int tmTimerLock(PVM pVM)
-{
- VM_ASSERT_EMT(pVM);
- int rc = PDMCritSectEnter(&pVM->tm.s.TimerCritSect, VERR_SEM_BUSY);
- return rc;
-}
-
-
-/**
- * Try take the timer lock, no waiting.
- *
- * @retval VINF_SUCCESS on success.
- * @retval VERR_SEM_BUSY if busy.
- *
- * @param pVM The VM handle.
- */
-int tmTimerTryLock(PVM pVM)
-{
- int rc = PDMCritSectTryEnter(&pVM->tm.s.TimerCritSect);
- return rc;
-}
-
-
/**
- * Release the EMT/TM lock.
- *
- * @param pVM The VM handle.
- */
-void tmTimerUnlock(PVM pVM)
-{
- PDMCritSectLeave(&pVM->tm.s.TimerCritSect);
-}
-
-
-/**
- * Try take the VirtualSync lock, wait in ring-3 return VERR_SEM_BUSY in R0/RC.
- *
- * @retval VINF_SUCCESS on success (always in ring-3).
- * @retval VERR_SEM_BUSY in RC and R0 if the semaphore is busy.
- *
- * @param pVM The VM handle.
- */
-int tmVirtualSyncLock(PVM pVM)
-{
- VM_ASSERT_EMT(pVM);
- int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_SEM_BUSY);
- return rc;
-}
-
-
-/**
- * Try take the VirtualSync lock, no waiting.
- *
- * @retval VINF_SUCCESS on success.
- * @retval VERR_SEM_BUSY if busy.
- *
- * @param pVM The VM handle.
- */
-int tmVirtualSyncTryLock(PVM pVM)
-{
- VM_ASSERT_EMT(pVM);
- int rc = PDMCritSectTryEnter(&pVM->tm.s.VirtualSyncLock);
- return rc;
-}
-
-
-/**
- * Release the VirtualSync lock.
+ * Gets the current warp drive percent.
*
+ * @returns The warp drive percent.
* @param pVM The VM handle.
*/
-void tmVirtualSyncUnlock(PVM pVM)
+VMMDECL(uint32_t) TMGetWarpDrive(PVM pVM)
{
- PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
+ return pVM->tm.s.u32VirtualWarpDrivePercentage;
}
-#endif /* ! macros */
/**
* Notification that execution is about to start.
@@ -317,7 +248,7 @@ DECLINLINE(void) tmSchedule(PTMTIMER pTimer)
{
PVM pVM = pTimer->CTX_SUFF(pVM);
if ( VM_IS_EMT(pVM)
- && RT_SUCCESS(tmTimerTryLock(pVM)))
+ && RT_SUCCESS(TM_TRY_LOCK_TIMERS(pVM)))
{
STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatScheduleOne), a);
Log3(("tmSchedule: tmTimerQueueSchedule\n"));
@@ -326,7 +257,7 @@ DECLINLINE(void) tmSchedule(PTMTIMER pTimer)
tmTimerQueuesSanityChecks(pVM, "tmSchedule");
#endif
STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatScheduleOne), a);
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
}
else
{
@@ -366,7 +297,7 @@ DECLINLINE(bool) tmTimerTry(PTMTIMER pTimer, TMTIMERSTATE enmStateNew, TMTIMERST
* @todo FIXME: Look into potential race with the thread running the queues
* and stuff.
*/
-DECLINLINE(void) tmTimerLink(PTMTIMERQUEUE pQueue, PTMTIMER pTimer)
+DECLINLINE(void) tmTimerLinkSchedule(PTMTIMERQUEUE pQueue, PTMTIMER pTimer)
{
Assert(!pTimer->offScheduleNext);
const int32_t offHeadNew = (intptr_t)pTimer - (intptr_t)pQueue;
@@ -395,13 +326,316 @@ DECLINLINE(bool) tmTimerTryWithLink(PTMTIMER pTimer, TMTIMERSTATE enmStateNew, T
{
if (tmTimerTry(pTimer, enmStateNew, enmStateOld))
{
- tmTimerLink(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF(paTimerQueues)[pTimer->enmClock], pTimer);
+ tmTimerLinkSchedule(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF(paTimerQueues)[pTimer->enmClock], pTimer);
return true;
}
return false;
}
+/**
+ * Links a timer into the active list of a timer queue.
+ *
+ * @param pQueue The queue.
+ * @param pTimer The timer.
+ * @param u64Expire The timer expiration time.
+ *
+ * @remarks Called while owning the relevant queue lock.
+ */
+DECL_FORCE_INLINE(void) tmTimerQueueLinkActive(PTMTIMERQUEUE pQueue, PTMTIMER pTimer, uint64_t u64Expire)
+{
+ Assert(!pTimer->offNext);
+ Assert(!pTimer->offPrev);
+ Assert(pTimer->enmState == TMTIMERSTATE_ACTIVE || pTimer->enmClock != TMCLOCK_VIRTUAL_SYNC); /* (active is not a stable state) */
+
+ PTMTIMER pCur = TMTIMER_GET_HEAD(pQueue);
+ if (pCur)
+ {
+ for (;; pCur = TMTIMER_GET_NEXT(pCur))
+ {
+ if (pCur->u64Expire > u64Expire)
+ {
+ const PTMTIMER pPrev = TMTIMER_GET_PREV(pCur);
+ TMTIMER_SET_NEXT(pTimer, pCur);
+ TMTIMER_SET_PREV(pTimer, pPrev);
+ if (pPrev)
+ TMTIMER_SET_NEXT(pPrev, pTimer);
+ else
+ {
+ TMTIMER_SET_HEAD(pQueue, pTimer);
+ ASMAtomicWriteU64(&pQueue->u64Expire, u64Expire);
+ DBGFTRACE_U64_TAG2(pTimer->CTX_SUFF(pVM), u64Expire, "tmTimerQueueLinkActive head", R3STRING(pTimer->pszDesc));
+ }
+ TMTIMER_SET_PREV(pCur, pTimer);
+ return;
+ }
+ if (!pCur->offNext)
+ {
+ TMTIMER_SET_NEXT(pCur, pTimer);
+ TMTIMER_SET_PREV(pTimer, pCur);
+ DBGFTRACE_U64_TAG2(pTimer->CTX_SUFF(pVM), u64Expire, "tmTimerQueueLinkActive tail", R3STRING(pTimer->pszDesc));
+ return;
+ }
+ }
+ }
+ else
+ {
+ TMTIMER_SET_HEAD(pQueue, pTimer);
+ ASMAtomicWriteU64(&pQueue->u64Expire, u64Expire);
+ DBGFTRACE_U64_TAG2(pTimer->CTX_SUFF(pVM), u64Expire, "tmTimerQueueLinkActive empty", R3STRING(pTimer->pszDesc));
+ }
+}
+
+
+
+/**
+ * Schedules the given timer on the given queue.
+ *
+ * @param pQueue The timer queue.
+ * @param pTimer The timer that needs scheduling.
+ *
+ * @remarks Called while owning the lock.
+ */
+DECLINLINE(void) tmTimerQueueScheduleOne(PTMTIMERQUEUE pQueue, PTMTIMER pTimer)
+{
+ Assert(pQueue->enmClock != TMCLOCK_VIRTUAL_SYNC);
+
+ /*
+ * Processing.
+ */
+ unsigned cRetries = 2;
+ do
+ {
+ TMTIMERSTATE enmState = pTimer->enmState;
+ switch (enmState)
+ {
+ /*
+ * Reschedule timer (in the active list).
+ */
+ case TMTIMERSTATE_PENDING_RESCHEDULE:
+ if (RT_UNLIKELY(!tmTimerTry(pTimer, TMTIMERSTATE_PENDING_SCHEDULE, TMTIMERSTATE_PENDING_RESCHEDULE)))
+ break; /* retry */
+ tmTimerQueueUnlinkActive(pQueue, pTimer);
+ /* fall thru */
+
+ /*
+ * Schedule timer (insert into the active list).
+ */
+ case TMTIMERSTATE_PENDING_SCHEDULE:
+ Assert(!pTimer->offNext); Assert(!pTimer->offPrev);
+ if (RT_UNLIKELY(!tmTimerTry(pTimer, TMTIMERSTATE_ACTIVE, TMTIMERSTATE_PENDING_SCHEDULE)))
+ break; /* retry */
+ tmTimerQueueLinkActive(pQueue, pTimer, pTimer->u64Expire);
+ return;
+
+ /*
+ * Stop the timer in active list.
+ */
+ case TMTIMERSTATE_PENDING_STOP:
+ if (RT_UNLIKELY(!tmTimerTry(pTimer, TMTIMERSTATE_PENDING_STOP_SCHEDULE, TMTIMERSTATE_PENDING_STOP)))
+ break; /* retry */
+ tmTimerQueueUnlinkActive(pQueue, pTimer);
+ /* fall thru */
+
+ /*
+ * Stop the timer (not on the active list).
+ */
+ case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
+ Assert(!pTimer->offNext); Assert(!pTimer->offPrev);
+ if (RT_UNLIKELY(!tmTimerTry(pTimer, TMTIMERSTATE_STOPPED, TMTIMERSTATE_PENDING_STOP_SCHEDULE)))
+ break;
+ return;
+
+ /*
+ * The timer is pending destruction by TMR3TimerDestroy, our caller.
+ * Nothing to do here.
+ */
+ case TMTIMERSTATE_DESTROY:
+ break;
+
+ /*
+ * Postpone these until they get into the right state.
+ */
+ case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
+ case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
+ tmTimerLinkSchedule(pQueue, pTimer);
+ STAM_COUNTER_INC(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatPostponed));
+ return;
+
+ /*
+ * None of these can be in the schedule.
+ */
+ case TMTIMERSTATE_FREE:
+ case TMTIMERSTATE_STOPPED:
+ case TMTIMERSTATE_ACTIVE:
+ case TMTIMERSTATE_EXPIRED_GET_UNLINK:
+ case TMTIMERSTATE_EXPIRED_DELIVER:
+ default:
+ AssertMsgFailed(("Timer (%p) in the scheduling list has an invalid state %s (%d)!",
+ pTimer, tmTimerState(pTimer->enmState), pTimer->enmState));
+ return;
+ }
+ } while (cRetries-- > 0);
+}
+
+
+/**
+ * Schedules the specified timer queue.
+ *
+ * @param pVM The VM to run the timers for.
+ * @param pQueue The queue to schedule.
+ *
+ * @remarks Called while owning the lock.
+ */
+void tmTimerQueueSchedule(PVM pVM, PTMTIMERQUEUE pQueue)
+{
+ TM_ASSERT_TIMER_LOCK_OWNERSHIP(pVM);
+
+ /*
+ * Dequeue the scheduling list and iterate it.
+ */
+ int32_t offNext = ASMAtomicXchgS32(&pQueue->offSchedule, 0);
+ Log2(("tmTimerQueueSchedule: pQueue=%p:{.enmClock=%d, offNext=%RI32, .u64Expired=%'RU64}\n", pQueue, pQueue->enmClock, offNext, pQueue->u64Expire));
+ if (!offNext)
+ return;
+ PTMTIMER pNext = (PTMTIMER)((intptr_t)pQueue + offNext);
+ while (pNext)
+ {
+ /*
+ * Unlink the head timer and find the next one.
+ */
+ PTMTIMER pTimer = pNext;
+ pNext = pNext->offScheduleNext ? (PTMTIMER)((intptr_t)pNext + pNext->offScheduleNext) : NULL;
+ pTimer->offScheduleNext = 0;
+
+ /*
+ * Do the scheduling.
+ */
+ Log2(("tmTimerQueueSchedule: %p:{.enmState=%s, .enmClock=%d, .enmType=%d, .pszDesc=%s}\n",
+ pTimer, tmTimerState(pTimer->enmState), pTimer->enmClock, pTimer->enmType, R3STRING(pTimer->pszDesc)));
+ tmTimerQueueScheduleOne(pQueue, pTimer);
+ Log2(("tmTimerQueueSchedule: %p: new %s\n", pTimer, tmTimerState(pTimer->enmState)));
+ } /* foreach timer in current schedule batch. */
+ Log2(("tmTimerQueueSchedule: u64Expired=%'RU64\n", pQueue->u64Expire));
+}
+
+
+#ifdef VBOX_STRICT
+/**
+ * Checks that the timer queues are sane.
+ *
+ * @param pVM VM handle.
+ *
+ * @remarks Called while owning the lock.
+ */
+void tmTimerQueuesSanityChecks(PVM pVM, const char *pszWhere)
+{
+ TM_ASSERT_TIMER_LOCK_OWNERSHIP(pVM);
+
+ /*
+ * Check the linking of the active lists.
+ */
+ bool fHaveVirtualSyncLock = false;
+ for (int i = 0; i < TMCLOCK_MAX; i++)
+ {
+ PTMTIMERQUEUE pQueue = &pVM->tm.s.CTX_SUFF(paTimerQueues)[i];
+ Assert((int)pQueue->enmClock == i);
+ if (pQueue->enmClock == TMCLOCK_VIRTUAL_SYNC)
+ {
+ if (PDMCritSectTryEnter(&pVM->tm.s.VirtualSyncLock) != VINF_SUCCESS)
+ continue;
+ fHaveVirtualSyncLock = true;
+ }
+ PTMTIMER pPrev = NULL;
+ for (PTMTIMER pCur = TMTIMER_GET_HEAD(pQueue); pCur; pPrev = pCur, pCur = TMTIMER_GET_NEXT(pCur))
+ {
+ AssertMsg((int)pCur->enmClock == i, ("%s: %d != %d\n", pszWhere, pCur->enmClock, i));
+ AssertMsg(TMTIMER_GET_PREV(pCur) == pPrev, ("%s: %p != %p\n", pszWhere, TMTIMER_GET_PREV(pCur), pPrev));
+ TMTIMERSTATE enmState = pCur->enmState;
+ switch (enmState)
+ {
+ case TMTIMERSTATE_ACTIVE:
+ AssertMsg( !pCur->offScheduleNext
+ || pCur->enmState != TMTIMERSTATE_ACTIVE,
+ ("%s: %RI32\n", pszWhere, pCur->offScheduleNext));
+ break;
+ case TMTIMERSTATE_PENDING_STOP:
+ case TMTIMERSTATE_PENDING_RESCHEDULE:
+ case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
+ break;
+ default:
+ AssertMsgFailed(("%s: Invalid state enmState=%d %s\n", pszWhere, enmState, tmTimerState(enmState)));
+ break;
+ }
+ }
+ }
+
+
+# ifdef IN_RING3
+ /*
+ * Do the big list and check that active timers all are in the active lists.
+ */
+ PTMTIMERR3 pPrev = NULL;
+ for (PTMTIMERR3 pCur = pVM->tm.s.pCreated; pCur; pPrev = pCur, pCur = pCur->pBigNext)
+ {
+ Assert(pCur->pBigPrev == pPrev);
+ Assert((unsigned)pCur->enmClock < (unsigned)TMCLOCK_MAX);
+
+ TMTIMERSTATE enmState = pCur->enmState;
+ switch (enmState)
+ {
+ case TMTIMERSTATE_ACTIVE:
+ case TMTIMERSTATE_PENDING_STOP:
+ case TMTIMERSTATE_PENDING_RESCHEDULE:
+ case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
+ if (fHaveVirtualSyncLock || pCur->enmClock != TMCLOCK_VIRTUAL_SYNC)
+ {
+ PTMTIMERR3 pCurAct = TMTIMER_GET_HEAD(&pVM->tm.s.CTX_SUFF(paTimerQueues)[pCur->enmClock]);
+ Assert(pCur->offPrev || pCur == pCurAct);
+ while (pCurAct && pCurAct != pCur)
+ pCurAct = TMTIMER_GET_NEXT(pCurAct);
+ Assert(pCurAct == pCur);
+ }
+ break;
+
+ case TMTIMERSTATE_PENDING_SCHEDULE:
+ case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
+ case TMTIMERSTATE_STOPPED:
+ case TMTIMERSTATE_EXPIRED_DELIVER:
+ if (fHaveVirtualSyncLock || pCur->enmClock != TMCLOCK_VIRTUAL_SYNC)
+ {
+ Assert(!pCur->offNext);
+ Assert(!pCur->offPrev);
+ for (PTMTIMERR3 pCurAct = TMTIMER_GET_HEAD(&pVM->tm.s.CTX_SUFF(paTimerQueues)[pCur->enmClock]);
+ pCurAct;
+ pCurAct = TMTIMER_GET_NEXT(pCurAct))
+ {
+ Assert(pCurAct != pCur);
+ Assert(TMTIMER_GET_NEXT(pCurAct) != pCur);
+ Assert(TMTIMER_GET_PREV(pCurAct) != pCur);
+ }
+ }
+ break;
+
+ /* ignore */
+ case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
+ break;
+
+ /* shouldn't get here! */
+ case TMTIMERSTATE_EXPIRED_GET_UNLINK:
+ case TMTIMERSTATE_DESTROY:
+ default:
+ AssertMsgFailed(("Invalid state enmState=%d %s\n", enmState, tmTimerState(enmState)));
+ break;
+ }
+ }
+# endif /* IN_RING3 */
+
+ if (fHaveVirtualSyncLock)
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
+}
+#endif /* !VBOX_STRICT */
+
#ifdef VBOX_HIGH_RES_TIMERS_HACK
/**
@@ -799,49 +1033,50 @@ VMMDECL(PTMTIMERRC) TMTimerRCPtr(PTMTIMER pTimer)
/**
- * Links a timer into the active list of a timer queue.
+ * Locks the timer clock.
*
- * The caller must have taken the TM semaphore before calling this function.
+ * @returns VINF_SUCCESS on success, @a rcBusy if busy, and VERR_NOT_SUPPORTED
+ * if the clock does not have a lock.
+ * @param pTimer The timer which clock lock we wish to take.
+ * @param rcBusy What to return in ring-0 and raw-mode context
+ * if the lock is busy. Pass VINF_SUCCESS to
+ * acquired the critical section thru a ring-3
+ call if necessary.
*
- * @param pQueue The queue.
- * @param pTimer The timer.
- * @param u64Expire The timer expiration time.
+ * @remarks Currently only supported on timers using the virtual sync clock.
*/
-DECL_FORCE_INLINE(void) tmTimerActiveLink(PTMTIMERQUEUE pQueue, PTMTIMER pTimer, uint64_t u64Expire)
+VMMDECL(int) TMTimerLock(PTMTIMER pTimer, int rcBusy)
{
- PTMTIMER pCur = TMTIMER_GET_HEAD(pQueue);
- if (pCur)
- {
- for (;; pCur = TMTIMER_GET_NEXT(pCur))
- {
- if (pCur->u64Expire > u64Expire)
- {
- const PTMTIMER pPrev = TMTIMER_GET_PREV(pCur);
- TMTIMER_SET_NEXT(pTimer, pCur);
- TMTIMER_SET_PREV(pTimer, pPrev);
- if (pPrev)
- TMTIMER_SET_NEXT(pPrev, pTimer);
- else
- {
- TMTIMER_SET_HEAD(pQueue, pTimer);
- pQueue->u64Expire = u64Expire;
- }
- TMTIMER_SET_PREV(pCur, pTimer);
- return;
- }
- if (!pCur->offNext)
- {
- TMTIMER_SET_NEXT(pCur, pTimer);
- TMTIMER_SET_PREV(pTimer, pCur);
- return;
- }
- }
- }
- else
- {
- TMTIMER_SET_HEAD(pQueue, pTimer);
- pQueue->u64Expire = u64Expire;
- }
+ AssertPtr(pTimer);
+ AssertReturn(pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC, VERR_NOT_SUPPORTED);
+ return PDMCritSectEnter(&pTimer->CTX_SUFF(pVM)->tm.s.VirtualSyncLock, rcBusy);
+}
+
+
+/**
+ * Unlocks a timer clock locked by TMTimerLock.
+ *
+ * @param pTimer The timer which clock to unlock.
+ */
+VMMDECL(void) TMTimerUnlock(PTMTIMER pTimer)
+{
+ AssertPtr(pTimer);
+ AssertReturnVoid(pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC);
+ PDMCritSectLeave(&pTimer->CTX_SUFF(pVM)->tm.s.VirtualSyncLock);
+}
+
+
+/**
+ * Checks if the current thread owns the timer clock lock.
+ *
+ * @returns @c true if its the owner, @c false if not.
+ * @param pTimer The timer handle.
+ */
+VMMDECL(bool) TMTimerIsLockOwner(PTMTIMER pTimer)
+{
+ AssertPtr(pTimer);
+ AssertReturn(pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC, false);
+ return PDMCritSectIsOwner(&pTimer->CTX_SUFF(pVM)->tm.s.VirtualSyncLock);
}
@@ -860,25 +1095,101 @@ static int tmTimerSetOptimizedStart(PVM pVM, PTMTIMER pTimer, uint64_t u64Expire
Assert(!pTimer->offNext);
Assert(pTimer->enmState == TMTIMERSTATE_ACTIVE);
+ TMCLOCK const enmClock = pTimer->enmClock;
+
/*
* Calculate and set the expiration time.
*/
- pTimer->u64Expire = u64Expire;
+ if (enmClock == TMCLOCK_VIRTUAL_SYNC)
+ {
+ uint64_t u64Last = ASMAtomicReadU64(&pVM->tm.s.u64VirtualSync);
+ AssertMsgStmt(u64Expire >= u64Last,
+ ("exp=%#llx last=%#llx\n", u64Expire, u64Last),
+ u64Expire = u64Last);
+ }
+ ASMAtomicWriteU64(&pTimer->u64Expire, u64Expire);
Log2(("tmTimerSetOptimizedStart: %p:{.pszDesc='%s', .u64Expire=%'RU64}\n", pTimer, R3STRING(pTimer->pszDesc), u64Expire));
/*
* Link the timer into the active list.
*/
- TMCLOCK const enmClock = pTimer->enmClock;
- tmTimerActiveLink(&pVM->tm.s.CTX_SUFF(paTimerQueues)[enmClock], pTimer, u64Expire);
+ tmTimerQueueLinkActive(&pVM->tm.s.CTX_SUFF(paTimerQueues)[enmClock], pTimer, u64Expire);
STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetOpt);
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
return VINF_SUCCESS;
}
+/**
+ * TMTimerSet for the virtual sync timer queue.
+ *
+ * This employs a greatly simplified state machine by always acquiring the
+ * queue lock and bypassing the scheduling list.
+ *
+ * @returns VBox status code
+ * @param pVM The VM handle.
+ * @param pTimer The timer handle.
+ * @param u64Expire The expiration time.
+ */
+static int tmTimerVirtualSyncSet(PVM pVM, PTMTIMER pTimer, uint64_t u64Expire)
+{
+ STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatTimerSetVs), a);
+ VM_ASSERT_EMT(pVM);
+ Assert(PDMCritSectIsOwner(&pVM->tm.s.VirtualSyncLock));
+ int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VINF_SUCCESS);
+ AssertRCReturn(rc, rc);
+
+ PTMTIMERQUEUE pQueue = &pVM->tm.s.CTX_SUFF(paTimerQueues)[TMCLOCK_VIRTUAL_SYNC];
+ TMTIMERSTATE enmState = pTimer->enmState;
+ switch (enmState)
+ {
+ case TMTIMERSTATE_EXPIRED_DELIVER:
+ case TMTIMERSTATE_STOPPED:
+ if (enmState == TMTIMERSTATE_EXPIRED_DELIVER)
+ STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetVsStExpDeliver);
+ else
+ STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetVsStStopped);
+
+ AssertMsg(u64Expire >= pVM->tm.s.u64VirtualSync,
+ ("%'RU64 < %'RU64 %s\n", u64Expire, pVM->tm.s.u64VirtualSync, R3STRING(pTimer->pszDesc)));
+ pTimer->u64Expire = u64Expire;
+ TM_SET_STATE(pTimer, TMTIMERSTATE_ACTIVE);
+ tmTimerQueueLinkActive(pQueue, pTimer, u64Expire);
+ rc = VINF_SUCCESS;
+ break;
+
+ case TMTIMERSTATE_ACTIVE:
+ STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetVsStActive);
+ tmTimerQueueUnlinkActive(pQueue, pTimer);
+ pTimer->u64Expire = u64Expire;
+ tmTimerQueueLinkActive(pQueue, pTimer, u64Expire);
+ rc = VINF_SUCCESS;
+ break;
+
+ case TMTIMERSTATE_PENDING_RESCHEDULE:
+ case TMTIMERSTATE_PENDING_STOP:
+ case TMTIMERSTATE_PENDING_SCHEDULE:
+ case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
+ case TMTIMERSTATE_EXPIRED_GET_UNLINK:
+ case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
+ case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
+ case TMTIMERSTATE_DESTROY:
+ case TMTIMERSTATE_FREE:
+ AssertLogRelMsgFailed(("Invalid timer state %s: %s\n", tmTimerState(enmState), R3STRING(pTimer->pszDesc)));
+ rc = VERR_TM_INVALID_STATE;
+ break;
+ default:
+ AssertMsgFailed(("Unknown timer state %d: %s\n", enmState, R3STRING(pTimer->pszDesc)));
+ rc = VERR_TM_UNKNOWN_STATE;
+ break;
+ }
+
+ STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatTimerSetVs), a);
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
+ return rc;
+}
/**
@@ -891,11 +1202,20 @@ static int tmTimerSetOptimizedStart(PVM pVM, PTMTIMER pTimer, uint64_t u64Expire
VMMDECL(int) TMTimerSet(PTMTIMER pTimer, uint64_t u64Expire)
{
PVM pVM = pTimer->CTX_SUFF(pVM);
+
+ /* Treat virtual sync timers specially. */
+ if (pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC)
+ return tmTimerVirtualSyncSet(pVM, pTimer, u64Expire);
+
STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatTimerSet), a);
TMTIMER_ASSERT_CRITSECT(pTimer);
+ DBGFTRACE_U64_TAG2(pVM, u64Expire, "TMTimerSet", R3STRING(pTimer->pszDesc));
+
#ifdef VBOX_WITH_STATISTICS
- /* Gather optimization info. */
+ /*
+ * Gather optimization info.
+ */
STAM_COUNTER_INC(&pVM->tm.s.StatTimerSet);
TMTIMERSTATE enmOrgState = pTimer->enmState;
switch (enmOrgState)
@@ -922,15 +1242,15 @@ VMMDECL(int) TMTimerSet(PTMTIMER pTimer, uint64_t u64Expire)
&& pTimer->pCritSect))
{
/* Try take the TM lock and check the state again. */
- if (RT_SUCCESS_NP(tmTimerTryLock(pVM)))
+ if (RT_SUCCESS_NP(TM_TRY_LOCK_TIMERS(pVM)))
{
if (RT_LIKELY(tmTimerTry(pTimer, TMTIMERSTATE_ACTIVE, enmState1)))
{
tmTimerSetOptimizedStart(pVM, pTimer, u64Expire);
- STAM_PROFILE_STOP(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatTimerSetRelative), a);
+ STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatTimerSet), a);
return VINF_SUCCESS;
}
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
}
}
#endif
@@ -955,10 +1275,6 @@ VMMDECL(int) TMTimerSet(PTMTIMER pTimer, uint64_t u64Expire)
{
Assert(!pTimer->offPrev);
Assert(!pTimer->offNext);
- AssertMsg( pTimer->enmClock != TMCLOCK_VIRTUAL_SYNC
- || pVM->tm.s.fVirtualSyncTicking
- || u64Expire >= pVM->tm.s.u64VirtualSync,
- ("%'RU64 < %'RU64 %s\n", u64Expire, pVM->tm.s.u64VirtualSync, R3STRING(pTimer->pszDesc)));
pTimer->u64Expire = u64Expire;
TM_SET_STATE(pTimer, TMTIMERSTATE_PENDING_SCHEDULE);
tmSchedule(pTimer);
@@ -1094,15 +1410,92 @@ static int tmTimerSetRelativeOptimizedStart(PVM pVM, PTMTIMER pTimer, uint64_t c
/*
* Link the timer into the active list.
*/
- tmTimerActiveLink(&pVM->tm.s.CTX_SUFF(paTimerQueues)[enmClock], pTimer, u64Expire);
+ DBGFTRACE_U64_TAG2(pVM, u64Expire, "tmTimerSetRelativeOptimizedStart", R3STRING(pTimer->pszDesc));
+ tmTimerQueueLinkActive(&pVM->tm.s.CTX_SUFF(paTimerQueues)[enmClock], pTimer, u64Expire);
STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetRelativeOpt);
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
return VINF_SUCCESS;
}
/**
+ * TMTimerSetRelative for the virtual sync timer queue.
+ *
+ * This employs a greatly simplified state machine by always acquiring the
+ * queue lock and bypassing the scheduling list.
+ *
+ * @returns VBox status code
+ * @param pVM The VM handle.
+ * @param cTicksToNext Clock ticks until the next time expiration.
+ * @param pu64Now Where to return the current time stamp used.
+ * Optional.
+ */
+static int tmTimerVirtualSyncSetRelative(PVM pVM, PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
+{
+ STAM_PROFILE_START(pVM->tm.s.CTX_SUFF_Z(StatTimerSetRelativeVs), a);
+ VM_ASSERT_EMT(pVM);
+ Assert(PDMCritSectIsOwner(&pVM->tm.s.VirtualSyncLock));
+ int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VINF_SUCCESS);
+ AssertRCReturn(rc, rc);
+
+ /* Calculate the expiration tick. */
+ uint64_t u64Expire = TMVirtualSyncGetNoCheck(pVM);
+ if (pu64Now)
+ *pu64Now = u64Expire;
+ u64Expire += cTicksToNext;
+
+ /* Update the timer. */
+ PTMTIMERQUEUE pQueue = &pVM->tm.s.CTX_SUFF(paTimerQueues)[TMCLOCK_VIRTUAL_SYNC];
+ TMTIMERSTATE enmState = pTimer->enmState;
+ switch (enmState)
+ {
+ case TMTIMERSTATE_EXPIRED_DELIVER:
+ case TMTIMERSTATE_STOPPED:
+ if (enmState == TMTIMERSTATE_EXPIRED_DELIVER)
+ STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetRelativeVsStExpDeliver);
+ else
+ STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetRelativeVsStStopped);
+ pTimer->u64Expire = u64Expire;
+ TM_SET_STATE(pTimer, TMTIMERSTATE_ACTIVE);
+ tmTimerQueueLinkActive(pQueue, pTimer, u64Expire);
+ rc = VINF_SUCCESS;
+ break;
+
+ case TMTIMERSTATE_ACTIVE:
+ STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetRelativeVsStActive);
+ tmTimerQueueUnlinkActive(pQueue, pTimer);
+ pTimer->u64Expire = u64Expire;
+ tmTimerQueueLinkActive(pQueue, pTimer, u64Expire);
+ rc = VINF_SUCCESS;
+ break;
+
+ case TMTIMERSTATE_PENDING_RESCHEDULE:
+ case TMTIMERSTATE_PENDING_STOP:
+ case TMTIMERSTATE_PENDING_SCHEDULE:
+ case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
+ case TMTIMERSTATE_EXPIRED_GET_UNLINK:
+ case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
+ case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
+ case TMTIMERSTATE_DESTROY:
+ case TMTIMERSTATE_FREE:
+ AssertLogRelMsgFailed(("Invalid timer state %s: %s\n", tmTimerState(enmState), R3STRING(pTimer->pszDesc)));
+ rc = VERR_TM_INVALID_STATE;
+ break;
+
+ default:
+ AssertMsgFailed(("Unknown timer state %d: %s\n", enmState, R3STRING(pTimer->pszDesc)));
+ rc = VERR_TM_UNKNOWN_STATE;
+ break;
+ }
+
+ STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatTimerSetRelativeVs), a);
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
+ return rc;
+}
+
+
+/**
* Arm a timer with a expire time relative to the current time.
*
* @returns VBox status.
@@ -1113,13 +1506,21 @@ static int tmTimerSetRelativeOptimizedStart(PVM pVM, PTMTIMER pTimer, uint64_t c
*/
VMMDECL(int) TMTimerSetRelative(PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
{
- STAM_PROFILE_START(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatTimerSetRelative), a);
+ PVM pVM = pTimer->CTX_SUFF(pVM);
+
+ /* Treat virtual sync timers specially. */
+ if (pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC)
+ return tmTimerVirtualSyncSetRelative(pVM, pTimer, cTicksToNext, pu64Now);
+
+ STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatTimerSetRelative), a);
TMTIMER_ASSERT_CRITSECT(pTimer);
- PVM pVM = pTimer->CTX_SUFF(pVM);
- int rc;
+
+ DBGFTRACE_U64_TAG2(pVM, cTicksToNext, "TMTimerSetRelative", R3STRING(pTimer->pszDesc));
#ifdef VBOX_WITH_STATISTICS
- /* Gather optimization info. */
+ /*
+ * Gather optimization info.
+ */
STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetRelative);
TMTIMERSTATE enmOrgState = pTimer->enmState;
switch (enmOrgState)
@@ -1148,7 +1549,7 @@ VMMDECL(int) TMTimerSetRelative(PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t
* Note! Lock ordering doesn't apply when we only tries to
* get the innermost locks.
*/
- bool fOwnTMLock = RT_SUCCESS_NP(tmTimerTryLock(pVM));
+ bool fOwnTMLock = RT_SUCCESS_NP(TM_TRY_LOCK_TIMERS(pVM));
#if 1
if ( fOwnTMLock
&& pTimer->pCritSect)
@@ -1170,11 +1571,8 @@ VMMDECL(int) TMTimerSetRelative(PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t
/*
* Unoptimized path.
*/
+ int rc;
TMCLOCK const enmClock = pTimer->enmClock;
- bool fOwnVirtSyncLock;
- fOwnVirtSyncLock = !fOwnTMLock
- && enmClock == TMCLOCK_VIRTUAL_SYNC
- && RT_SUCCESS(tmVirtualSyncTryLock(pVM));
for (int cRetries = 1000; ; cRetries--)
{
/*
@@ -1303,28 +1701,15 @@ VMMDECL(int) TMTimerSetRelative(PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t
* Retry to gain locks.
*/
if (!fOwnTMLock)
- {
- fOwnTMLock = RT_SUCCESS_NP(tmTimerTryLock(pVM));
- if ( !fOwnTMLock
- && enmClock == TMCLOCK_VIRTUAL_SYNC
- && !fOwnVirtSyncLock)
- fOwnVirtSyncLock = RT_SUCCESS_NP(tmVirtualSyncTryLock(pVM));
- }
+ fOwnTMLock = RT_SUCCESS_NP(TM_TRY_LOCK_TIMERS(pVM));
} /* for (;;) */
/*
* Clean up and return.
*/
- if (fOwnVirtSyncLock)
- tmVirtualSyncUnlock(pVM);
if (fOwnTMLock)
- tmTimerUnlock(pVM);
-
- if ( !fOwnTMLock
- && !fOwnVirtSyncLock
- && enmClock == TMCLOCK_VIRTUAL_SYNC)
- STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetRelativeRacyVirtSync);
+ TM_UNLOCK_TIMERS(pVM);
STAM_PROFILE_STOP(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatTimerSetRelative), a);
return rc;
@@ -1332,105 +1717,6 @@ VMMDECL(int) TMTimerSetRelative(PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t
/**
- * Arm a timer with a (new) expire time relative to current time.
- *
- * @returns VBox status.
- * @param pTimer Timer handle as returned by one of the create functions.
- * @param cMilliesToNext Number of milliseconds to the next tick.
- */
-VMMDECL(int) TMTimerSetMillies(PTMTIMER pTimer, uint32_t cMilliesToNext)
-{
- PVM pVM = pTimer->CTX_SUFF(pVM);
- PVMCPU pVCpu = &pVM->aCpus[0]; /* just take the first VCPU */
-
- switch (pTimer->enmClock)
- {
- case TMCLOCK_VIRTUAL:
- AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
- return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
-
- case TMCLOCK_VIRTUAL_SYNC:
- AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
- return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
-
- case TMCLOCK_REAL:
- AssertCompile(TMCLOCK_FREQ_REAL == 1000);
- return TMTimerSetRelative(pTimer, cMilliesToNext, NULL);
-
- default:
- AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
- return VERR_INTERNAL_ERROR;
- }
-}
-
-
-/**
- * Arm a timer with a (new) expire time relative to current time.
- *
- * @returns VBox status.
- * @param pTimer Timer handle as returned by one of the create functions.
- * @param cMicrosToNext Number of microseconds to the next tick.
- */
-VMMDECL(int) TMTimerSetMicro(PTMTIMER pTimer, uint64_t cMicrosToNext)
-{
- PVM pVM = pTimer->CTX_SUFF(pVM);
- PVMCPU pVCpu = &pVM->aCpus[0]; /* just take the first VCPU */
-
- switch (pTimer->enmClock)
- {
- case TMCLOCK_VIRTUAL:
- AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
- return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL);
-
- case TMCLOCK_VIRTUAL_SYNC:
- AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
- return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL);
-
- case TMCLOCK_REAL:
- AssertCompile(TMCLOCK_FREQ_REAL == 1000);
- return TMTimerSetRelative(pTimer, cMicrosToNext / 1000, NULL);
-
- default:
- AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
- return VERR_INTERNAL_ERROR;
- }
-}
-
-
-/**
- * Arm a timer with a (new) expire time relative to current time.
- *
- * @returns VBox status.
- * @param pTimer Timer handle as returned by one of the create functions.
- * @param cNanosToNext Number of nanoseconds to the next tick.
- */
-VMMDECL(int) TMTimerSetNano(PTMTIMER pTimer, uint64_t cNanosToNext)
-{
- PVM pVM = pTimer->CTX_SUFF(pVM);
- PVMCPU pVCpu = &pVM->aCpus[0]; /* just take the first VCPU */
-
- switch (pTimer->enmClock)
- {
- case TMCLOCK_VIRTUAL:
- AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
- return TMTimerSetRelative(pTimer, cNanosToNext, NULL);
-
- case TMCLOCK_VIRTUAL_SYNC:
- AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
- return TMTimerSetRelative(pTimer, cNanosToNext, NULL);
-
- case TMCLOCK_REAL:
- AssertCompile(TMCLOCK_FREQ_REAL == 1000);
- return TMTimerSetRelative(pTimer, cNanosToNext / 1000000, NULL);
-
- default:
- AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
- return VERR_INTERNAL_ERROR;
- }
-}
-
-
-/**
* Drops a hint about the frequency of the timer.
*
* This is used by TM and the VMM to calculate how often guest execution needs
@@ -1463,6 +1749,77 @@ VMMDECL(int) TMTimerSetFrequencyHint(PTMTIMER pTimer, uint32_t uHzHint)
/**
+ * TMTimerStop for the virtual sync timer queue.
+ *
+ * This employs a greatly simplified state machine by always acquiring the
+ * queue lock and bypassing the scheduling list.
+ *
+ * @returns VBox status code
+ * @param pVM The VM handle.
+ * @param pTimer The timer handle.
+ */
+static int tmTimerVirtualSyncStop(PVM pVM, PTMTIMER pTimer)
+{
+ STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatTimerStopVs), a);
+ VM_ASSERT_EMT(pVM);
+ Assert(PDMCritSectIsOwner(&pVM->tm.s.VirtualSyncLock));
+ int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VINF_SUCCESS);
+ AssertRCReturn(rc, rc);
+
+ /* Reset the HZ hint. */
+ if (pTimer->uHzHint)
+ {
+ if (pTimer->uHzHint >= pVM->tm.s.uMaxHzHint)
+ ASMAtomicWriteBool(&pVM->tm.s.fHzHintNeedsUpdating, true);
+ pTimer->uHzHint = 0;
+ }
+
+ /* Update the timer state. */
+ PTMTIMERQUEUE pQueue = &pVM->tm.s.CTX_SUFF(paTimerQueues)[TMCLOCK_VIRTUAL_SYNC];
+ TMTIMERSTATE enmState = pTimer->enmState;
+ switch (enmState)
+ {
+ case TMTIMERSTATE_ACTIVE:
+ tmTimerQueueUnlinkActive(pQueue, pTimer);
+ TM_SET_STATE(pTimer, TMTIMERSTATE_STOPPED);
+ rc = VINF_SUCCESS;
+ break;
+
+ case TMTIMERSTATE_EXPIRED_DELIVER:
+ TM_SET_STATE(pTimer, TMTIMERSTATE_STOPPED);
+ rc = VINF_SUCCESS;
+ break;
+
+ case TMTIMERSTATE_STOPPED:
+ rc = VINF_SUCCESS;
+ break;
+
+ case TMTIMERSTATE_PENDING_RESCHEDULE:
+ case TMTIMERSTATE_PENDING_STOP:
+ case TMTIMERSTATE_PENDING_SCHEDULE:
+ case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
+ case TMTIMERSTATE_EXPIRED_GET_UNLINK:
+ case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
+ case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
+ case TMTIMERSTATE_DESTROY:
+ case TMTIMERSTATE_FREE:
+ AssertLogRelMsgFailed(("Invalid timer state %s: %s\n", tmTimerState(enmState), R3STRING(pTimer->pszDesc)));
+ rc = VERR_TM_INVALID_STATE;
+ break;
+
+ default:
+ AssertMsgFailed(("Unknown timer state %d: %s\n", enmState, R3STRING(pTimer->pszDesc)));
+ rc = VERR_TM_UNKNOWN_STATE;
+ break;
+ }
+
+ STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatTimerStopVs), a);
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
+ return rc;
+}
+
+
+/**
* Stop the timer.
* Use TMR3TimerArm() to "un-stop" the timer.
*
@@ -1471,13 +1828,20 @@ VMMDECL(int) TMTimerSetFrequencyHint(PTMTIMER pTimer, uint32_t uHzHint)
*/
VMMDECL(int) TMTimerStop(PTMTIMER pTimer)
{
- STAM_PROFILE_START(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatTimerStop), a);
+ PVM pVM = pTimer->CTX_SUFF(pVM);
+
+ /* Treat virtual sync timers specially. */
+ if (pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC)
+ return tmTimerVirtualSyncStop(pVM, pTimer);
+
+ STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatTimerStop), a);
TMTIMER_ASSERT_CRITSECT(pTimer);
- /* Reset the HZ hint. */
+ /*
+ * Reset the HZ hint.
+ */
if (pTimer->uHzHint)
{
- PVM pVM = pTimer->CTX_SUFF(pVM);
if (pTimer->uHzHint >= pVM->tm.s.uMaxHzHint)
ASMAtomicWriteBool(&pVM->tm.s.fHzHintNeedsUpdating, true);
pTimer->uHzHint = 0;
@@ -1502,14 +1866,14 @@ VMMDECL(int) TMTimerStop(PTMTIMER pTimer)
case TMTIMERSTATE_STOPPED:
case TMTIMERSTATE_PENDING_STOP:
case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
- STAM_PROFILE_STOP(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatTimerStop), a);
+ STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatTimerStop), a);
return VINF_SUCCESS;
case TMTIMERSTATE_PENDING_SCHEDULE:
if (tmTimerTry(pTimer, TMTIMERSTATE_PENDING_STOP_SCHEDULE, enmState))
{
tmSchedule(pTimer);
- STAM_PROFILE_STOP(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatTimerStop), a);
+ STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatTimerStop), a);
return VINF_SUCCESS;
}
@@ -1517,7 +1881,7 @@ VMMDECL(int) TMTimerStop(PTMTIMER pTimer)
if (tmTimerTry(pTimer, TMTIMERSTATE_PENDING_STOP, enmState))
{
tmSchedule(pTimer);
- STAM_PROFILE_STOP(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatTimerStop), a);
+ STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatTimerStop), a);
return VINF_SUCCESS;
}
break;
@@ -1526,7 +1890,7 @@ VMMDECL(int) TMTimerStop(PTMTIMER pTimer)
if (tmTimerTryWithLink(pTimer, TMTIMERSTATE_PENDING_STOP, enmState))
{
tmSchedule(pTimer);
- STAM_PROFILE_STOP(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatTimerStop), a);
+ STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatTimerStop), a);
return VINF_SUCCESS;
}
break;
@@ -1556,7 +1920,7 @@ VMMDECL(int) TMTimerStop(PTMTIMER pTimer)
} while (cRetries-- > 0);
AssertMsgFailed(("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, R3STRING(pTimer->pszDesc)));
- STAM_PROFILE_STOP(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatTimerStop), a);
+ STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatTimerStop), a);
return VERR_INTERNAL_ERROR;
}
@@ -1570,9 +1934,9 @@ VMMDECL(int) TMTimerStop(PTMTIMER pTimer)
*/
VMMDECL(uint64_t) TMTimerGet(PTMTIMER pTimer)
{
- uint64_t u64;
- PVM pVM = pTimer->CTX_SUFF(pVM);
+ PVM pVM = pTimer->CTX_SUFF(pVM);
+ uint64_t u64;
switch (pTimer->enmClock)
{
case TMCLOCK_VIRTUAL:
@@ -1586,7 +1950,7 @@ VMMDECL(uint64_t) TMTimerGet(PTMTIMER pTimer)
break;
default:
AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
- return ~(uint64_t)0;
+ return UINT64_MAX;
}
//Log2(("TMTimerGet: returns %'RU64 (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
// u64, pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
@@ -1619,6 +1983,216 @@ VMMDECL(uint64_t) TMTimerGetFreq(PTMTIMER pTimer)
/**
+ * Get the expire time of the timer.
+ * Only valid for active timers.
+ *
+ * @returns Expire time of the timer.
+ * @param pTimer Timer handle as returned by one of the create functions.
+ */
+VMMDECL(uint64_t) TMTimerGetExpire(PTMTIMER pTimer)
+{
+ TMTIMER_ASSERT_CRITSECT(pTimer);
+ int cRetries = 1000;
+ do
+ {
+ TMTIMERSTATE enmState = pTimer->enmState;
+ switch (enmState)
+ {
+ case TMTIMERSTATE_EXPIRED_GET_UNLINK:
+ case TMTIMERSTATE_EXPIRED_DELIVER:
+ case TMTIMERSTATE_STOPPED:
+ case TMTIMERSTATE_PENDING_STOP:
+ case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
+ Log2(("TMTimerGetExpire: returns ~0 (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
+ pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
+ return ~(uint64_t)0;
+
+ case TMTIMERSTATE_ACTIVE:
+ case TMTIMERSTATE_PENDING_RESCHEDULE:
+ case TMTIMERSTATE_PENDING_SCHEDULE:
+ Log2(("TMTimerGetExpire: returns %'RU64 (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
+ pTimer->u64Expire, pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
+ return pTimer->u64Expire;
+
+ case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
+ case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
+#ifdef IN_RING3
+ if (!RTThreadYield())
+ RTThreadSleep(1);
+#endif
+ break;
+
+ /*
+ * Invalid states.
+ */
+ case TMTIMERSTATE_DESTROY:
+ case TMTIMERSTATE_FREE:
+ AssertMsgFailed(("Invalid timer state %d (%s)\n", enmState, R3STRING(pTimer->pszDesc)));
+ Log2(("TMTimerGetExpire: returns ~0 (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
+ pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
+ return ~(uint64_t)0;
+ default:
+ AssertMsgFailed(("Unknown timer state %d (%s)\n", enmState, R3STRING(pTimer->pszDesc)));
+ return ~(uint64_t)0;
+ }
+ } while (cRetries-- > 0);
+
+ AssertMsgFailed(("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, R3STRING(pTimer->pszDesc)));
+ Log2(("TMTimerGetExpire: returns ~0 (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
+ pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
+ return ~(uint64_t)0;
+}
+
+
+/**
+ * Checks if a timer is active or not.
+ *
+ * @returns True if active.
+ * @returns False if not active.
+ * @param pTimer Timer handle as returned by one of the create functions.
+ */
+VMMDECL(bool) TMTimerIsActive(PTMTIMER pTimer)
+{
+ TMTIMERSTATE enmState = pTimer->enmState;
+ switch (enmState)
+ {
+ case TMTIMERSTATE_STOPPED:
+ case TMTIMERSTATE_EXPIRED_GET_UNLINK:
+ case TMTIMERSTATE_EXPIRED_DELIVER:
+ case TMTIMERSTATE_PENDING_STOP:
+ case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
+ Log2(("TMTimerIsActive: returns false (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
+ pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
+ return false;
+
+ case TMTIMERSTATE_ACTIVE:
+ case TMTIMERSTATE_PENDING_RESCHEDULE:
+ case TMTIMERSTATE_PENDING_SCHEDULE:
+ case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
+ case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
+ Log2(("TMTimerIsActive: returns true (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
+ pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
+ return true;
+
+ /*
+ * Invalid states.
+ */
+ case TMTIMERSTATE_DESTROY:
+ case TMTIMERSTATE_FREE:
+ AssertMsgFailed(("Invalid timer state %s (%s)\n", tmTimerState(enmState), R3STRING(pTimer->pszDesc)));
+ Log2(("TMTimerIsActive: returns false (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
+ pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
+ return false;
+ default:
+ AssertMsgFailed(("Unknown timer state %d (%s)\n", enmState, R3STRING(pTimer->pszDesc)));
+ return false;
+ }
+}
+
+
+/* -=-=-=-=-=-=- Convenience APIs -=-=-=-=-=-=- */
+
+
+/**
+ * Arm a timer with a (new) expire time relative to current time.
+ *
+ * @returns VBox status.
+ * @param pTimer Timer handle as returned by one of the create functions.
+ * @param cMilliesToNext Number of milliseconds to the next tick.
+ */
+VMMDECL(int) TMTimerSetMillies(PTMTIMER pTimer, uint32_t cMilliesToNext)
+{
+ PVM pVM = pTimer->CTX_SUFF(pVM);
+ PVMCPU pVCpu = &pVM->aCpus[0]; /* just take the first VCPU */
+
+ switch (pTimer->enmClock)
+ {
+ case TMCLOCK_VIRTUAL:
+ AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+ return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
+
+ case TMCLOCK_VIRTUAL_SYNC:
+ AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+ return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
+
+ case TMCLOCK_REAL:
+ AssertCompile(TMCLOCK_FREQ_REAL == 1000);
+ return TMTimerSetRelative(pTimer, cMilliesToNext, NULL);
+
+ default:
+ AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+ return VERR_INTERNAL_ERROR;
+ }
+}
+
+
+/**
+ * Arm a timer with a (new) expire time relative to current time.
+ *
+ * @returns VBox status.
+ * @param pTimer Timer handle as returned by one of the create functions.
+ * @param cMicrosToNext Number of microseconds to the next tick.
+ */
+VMMDECL(int) TMTimerSetMicro(PTMTIMER pTimer, uint64_t cMicrosToNext)
+{
+ PVM pVM = pTimer->CTX_SUFF(pVM);
+ PVMCPU pVCpu = &pVM->aCpus[0]; /* just take the first VCPU */
+
+ switch (pTimer->enmClock)
+ {
+ case TMCLOCK_VIRTUAL:
+ AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+ return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL);
+
+ case TMCLOCK_VIRTUAL_SYNC:
+ AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+ return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL);
+
+ case TMCLOCK_REAL:
+ AssertCompile(TMCLOCK_FREQ_REAL == 1000);
+ return TMTimerSetRelative(pTimer, cMicrosToNext / 1000, NULL);
+
+ default:
+ AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+ return VERR_INTERNAL_ERROR;
+ }
+}
+
+
+/**
+ * Arm a timer with a (new) expire time relative to current time.
+ *
+ * @returns VBox status.
+ * @param pTimer Timer handle as returned by one of the create functions.
+ * @param cNanosToNext Number of nanoseconds to the next tick.
+ */
+VMMDECL(int) TMTimerSetNano(PTMTIMER pTimer, uint64_t cNanosToNext)
+{
+ PVM pVM = pTimer->CTX_SUFF(pVM);
+ PVMCPU pVCpu = &pVM->aCpus[0]; /* just take the first VCPU */
+
+ switch (pTimer->enmClock)
+ {
+ case TMCLOCK_VIRTUAL:
+ AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+ return TMTimerSetRelative(pTimer, cNanosToNext, NULL);
+
+ case TMCLOCK_VIRTUAL_SYNC:
+ AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+ return TMTimerSetRelative(pTimer, cNanosToNext, NULL);
+
+ case TMCLOCK_REAL:
+ AssertCompile(TMCLOCK_FREQ_REAL == 1000);
+ return TMTimerSetRelative(pTimer, cNanosToNext / 1000000, NULL);
+
+ default:
+ AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+ return VERR_INTERNAL_ERROR;
+ }
+}
+
+
+/**
* Get the current clock time as nanoseconds.
*
* @returns The timer clock as nanoseconds.
@@ -1746,21 +2320,21 @@ VMMDECL(uint64_t) TMTimerToMilli(PTMTIMER pTimer, uint64_t u64Ticks)
*
* @returns timer clock ticks.
* @param pTimer Timer handle as returned by one of the create functions.
- * @param u64NanoTS The nanosecond value ticks to convert.
+ * @param cNanoSecs The nanosecond value ticks to convert.
* @remark There could be rounding and overflow errors here.
*/
-VMMDECL(uint64_t) TMTimerFromNano(PTMTIMER pTimer, uint64_t u64NanoTS)
+VMMDECL(uint64_t) TMTimerFromNano(PTMTIMER pTimer, uint64_t cNanoSecs)
{
switch (pTimer->enmClock)
{
case TMCLOCK_VIRTUAL:
case TMCLOCK_VIRTUAL_SYNC:
AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
- return u64NanoTS;
+ return cNanoSecs;
case TMCLOCK_REAL:
AssertCompile(TMCLOCK_FREQ_REAL == 1000);
- return u64NanoTS / 1000000;
+ return cNanoSecs / 1000000;
default:
AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
@@ -1774,21 +2348,21 @@ VMMDECL(uint64_t) TMTimerFromNano(PTMTIMER pTimer, uint64_t u64NanoTS)
*
* @returns timer clock ticks.
* @param pTimer Timer handle as returned by one of the create functions.
- * @param u64MicroTS The microsecond value ticks to convert.
+ * @param cMicroSecs The microsecond value ticks to convert.
* @remark There could be rounding and overflow errors here.
*/
-VMMDECL(uint64_t) TMTimerFromMicro(PTMTIMER pTimer, uint64_t u64MicroTS)
+VMMDECL(uint64_t) TMTimerFromMicro(PTMTIMER pTimer, uint64_t cMicroSecs)
{
switch (pTimer->enmClock)
{
case TMCLOCK_VIRTUAL:
case TMCLOCK_VIRTUAL_SYNC:
AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
- return u64MicroTS * 1000;
+ return cMicroSecs * 1000;
case TMCLOCK_REAL:
AssertCompile(TMCLOCK_FREQ_REAL == 1000);
- return u64MicroTS / 1000;
+ return cMicroSecs / 1000;
default:
AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
@@ -1802,21 +2376,21 @@ VMMDECL(uint64_t) TMTimerFromMicro(PTMTIMER pTimer, uint64_t u64MicroTS)
*
* @returns timer clock ticks.
* @param pTimer Timer handle as returned by one of the create functions.
- * @param u64MilliTS The millisecond value ticks to convert.
+ * @param cMilliSecs The millisecond value ticks to convert.
* @remark There could be rounding and overflow errors here.
*/
-VMMDECL(uint64_t) TMTimerFromMilli(PTMTIMER pTimer, uint64_t u64MilliTS)
+VMMDECL(uint64_t) TMTimerFromMilli(PTMTIMER pTimer, uint64_t cMilliSecs)
{
switch (pTimer->enmClock)
{
case TMCLOCK_VIRTUAL:
case TMCLOCK_VIRTUAL_SYNC:
AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
- return u64MilliTS * 1000000;
+ return cMilliSecs * 1000000;
case TMCLOCK_REAL:
AssertCompile(TMCLOCK_FREQ_REAL == 1000);
- return u64MilliTS;
+ return cMilliSecs;
default:
AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
@@ -1826,114 +2400,6 @@ VMMDECL(uint64_t) TMTimerFromMilli(PTMTIMER pTimer, uint64_t u64MilliTS)
/**
- * Get the expire time of the timer.
- * Only valid for active timers.
- *
- * @returns Expire time of the timer.
- * @param pTimer Timer handle as returned by one of the create functions.
- */
-VMMDECL(uint64_t) TMTimerGetExpire(PTMTIMER pTimer)
-{
- TMTIMER_ASSERT_CRITSECT(pTimer);
- int cRetries = 1000;
- do
- {
- TMTIMERSTATE enmState = pTimer->enmState;
- switch (enmState)
- {
- case TMTIMERSTATE_EXPIRED_GET_UNLINK:
- case TMTIMERSTATE_EXPIRED_DELIVER:
- case TMTIMERSTATE_STOPPED:
- case TMTIMERSTATE_PENDING_STOP:
- case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
- Log2(("TMTimerGetExpire: returns ~0 (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
- pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
- return ~(uint64_t)0;
-
- case TMTIMERSTATE_ACTIVE:
- case TMTIMERSTATE_PENDING_RESCHEDULE:
- case TMTIMERSTATE_PENDING_SCHEDULE:
- Log2(("TMTimerGetExpire: returns %'RU64 (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
- pTimer->u64Expire, pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
- return pTimer->u64Expire;
-
- case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
- case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
-#ifdef IN_RING3
- if (!RTThreadYield())
- RTThreadSleep(1);
-#endif
- break;
-
- /*
- * Invalid states.
- */
- case TMTIMERSTATE_DESTROY:
- case TMTIMERSTATE_FREE:
- AssertMsgFailed(("Invalid timer state %d (%s)\n", enmState, R3STRING(pTimer->pszDesc)));
- Log2(("TMTimerGetExpire: returns ~0 (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
- pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
- return ~(uint64_t)0;
- default:
- AssertMsgFailed(("Unknown timer state %d (%s)\n", enmState, R3STRING(pTimer->pszDesc)));
- return ~(uint64_t)0;
- }
- } while (cRetries-- > 0);
-
- AssertMsgFailed(("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, R3STRING(pTimer->pszDesc)));
- Log2(("TMTimerGetExpire: returns ~0 (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
- pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
- return ~(uint64_t)0;
-}
-
-
-/**
- * Checks if a timer is active or not.
- *
- * @returns True if active.
- * @returns False if not active.
- * @param pTimer Timer handle as returned by one of the create functions.
- */
-VMMDECL(bool) TMTimerIsActive(PTMTIMER pTimer)
-{
- TMTIMERSTATE enmState = pTimer->enmState;
- switch (enmState)
- {
- case TMTIMERSTATE_STOPPED:
- case TMTIMERSTATE_EXPIRED_GET_UNLINK:
- case TMTIMERSTATE_EXPIRED_DELIVER:
- case TMTIMERSTATE_PENDING_STOP:
- case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
- Log2(("TMTimerIsActive: returns false (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
- pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
- return false;
-
- case TMTIMERSTATE_ACTIVE:
- case TMTIMERSTATE_PENDING_RESCHEDULE:
- case TMTIMERSTATE_PENDING_SCHEDULE:
- case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
- case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
- Log2(("TMTimerIsActive: returns true (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
- pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
- return true;
-
- /*
- * Invalid states.
- */
- case TMTIMERSTATE_DESTROY:
- case TMTIMERSTATE_FREE:
- AssertMsgFailed(("Invalid timer state %s (%s)\n", tmTimerState(enmState), R3STRING(pTimer->pszDesc)));
- Log2(("TMTimerIsActive: returns false (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
- pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
- return false;
- default:
- AssertMsgFailed(("Unknown timer state %d (%s)\n", enmState, R3STRING(pTimer->pszDesc)));
- return false;
- }
-}
-
-
-/**
* Convert state to string.
*
* @returns Readonly status name.
@@ -1968,319 +2434,6 @@ const char *tmTimerState(TMTIMERSTATE enmState)
/**
- * Schedules the given timer on the given queue.
- *
- * @param pQueue The timer queue.
- * @param pTimer The timer that needs scheduling.
- *
- * @remarks Called while owning the lock.
- */
-DECLINLINE(void) tmTimerQueueScheduleOne(PTMTIMERQUEUE pQueue, PTMTIMER pTimer)
-{
- /*
- * Processing.
- */
- unsigned cRetries = 2;
- do
- {
- TMTIMERSTATE enmState = pTimer->enmState;
- switch (enmState)
- {
- /*
- * Reschedule timer (in the active list).
- */
- case TMTIMERSTATE_PENDING_RESCHEDULE:
- {
- if (RT_UNLIKELY(!tmTimerTry(pTimer, TMTIMERSTATE_PENDING_SCHEDULE, TMTIMERSTATE_PENDING_RESCHEDULE)))
- break; /* retry */
-
- const PTMTIMER pPrev = TMTIMER_GET_PREV(pTimer);
- const PTMTIMER pNext = TMTIMER_GET_NEXT(pTimer);
- if (pPrev)
- TMTIMER_SET_NEXT(pPrev, pNext);
- else
- {
- TMTIMER_SET_HEAD(pQueue, pNext);
- pQueue->u64Expire = pNext ? pNext->u64Expire : INT64_MAX;
- }
- if (pNext)
- TMTIMER_SET_PREV(pNext, pPrev);
- pTimer->offNext = 0;
- pTimer->offPrev = 0;
- /* fall thru */
- }
-
- /*
- * Schedule timer (insert into the active list).
- */
- case TMTIMERSTATE_PENDING_SCHEDULE:
- {
- Assert(!pTimer->offNext); Assert(!pTimer->offPrev);
- if (RT_UNLIKELY(!tmTimerTry(pTimer, TMTIMERSTATE_ACTIVE, TMTIMERSTATE_PENDING_SCHEDULE)))
- break; /* retry */
-
- PTMTIMER pCur = TMTIMER_GET_HEAD(pQueue);
- if (pCur)
- {
- const uint64_t u64Expire = pTimer->u64Expire;
- for (;; pCur = TMTIMER_GET_NEXT(pCur))
- {
- if (pCur->u64Expire > u64Expire)
- {
- const PTMTIMER pPrev = TMTIMER_GET_PREV(pCur);
- TMTIMER_SET_NEXT(pTimer, pCur);
- TMTIMER_SET_PREV(pTimer, pPrev);
- if (pPrev)
- TMTIMER_SET_NEXT(pPrev, pTimer);
- else
- {
- TMTIMER_SET_HEAD(pQueue, pTimer);
- pQueue->u64Expire = u64Expire;
- }
- TMTIMER_SET_PREV(pCur, pTimer);
- return;
- }
- if (!pCur->offNext)
- {
- TMTIMER_SET_NEXT(pCur, pTimer);
- TMTIMER_SET_PREV(pTimer, pCur);
- return;
- }
- }
- }
- else
- {
- TMTIMER_SET_HEAD(pQueue, pTimer);
- pQueue->u64Expire = pTimer->u64Expire;
- }
- return;
- }
-
- /*
- * Stop the timer in active list.
- */
- case TMTIMERSTATE_PENDING_STOP:
- {
- if (RT_UNLIKELY(!tmTimerTry(pTimer, TMTIMERSTATE_PENDING_STOP_SCHEDULE, TMTIMERSTATE_PENDING_STOP)))
- break; /* retry */
-
- const PTMTIMER pPrev = TMTIMER_GET_PREV(pTimer);
- const PTMTIMER pNext = TMTIMER_GET_NEXT(pTimer);
- if (pPrev)
- TMTIMER_SET_NEXT(pPrev, pNext);
- else
- {
- TMTIMER_SET_HEAD(pQueue, pNext);
- pQueue->u64Expire = pNext ? pNext->u64Expire : INT64_MAX;
- }
- if (pNext)
- TMTIMER_SET_PREV(pNext, pPrev);
- pTimer->offNext = 0;
- pTimer->offPrev = 0;
- /* fall thru */
- }
-
- /*
- * Stop the timer (not on the active list).
- */
- case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
- Assert(!pTimer->offNext); Assert(!pTimer->offPrev);
- if (RT_UNLIKELY(!tmTimerTry(pTimer, TMTIMERSTATE_STOPPED, TMTIMERSTATE_PENDING_STOP_SCHEDULE)))
- break;
- return;
-
- /*
- * The timer is pending destruction by TMR3TimerDestroy, our caller.
- * Nothing to do here.
- */
- case TMTIMERSTATE_DESTROY:
- break;
-
- /*
- * Postpone these until they get into the right state.
- */
- case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
- case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
- tmTimerLink(pQueue, pTimer);
- STAM_COUNTER_INC(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatPostponed));
- return;
-
- /*
- * None of these can be in the schedule.
- */
- case TMTIMERSTATE_FREE:
- case TMTIMERSTATE_STOPPED:
- case TMTIMERSTATE_ACTIVE:
- case TMTIMERSTATE_EXPIRED_GET_UNLINK:
- case TMTIMERSTATE_EXPIRED_DELIVER:
- default:
- AssertMsgFailed(("Timer (%p) in the scheduling list has an invalid state %s (%d)!",
- pTimer, tmTimerState(pTimer->enmState), pTimer->enmState));
- return;
- }
- } while (cRetries-- > 0);
-}
-
-
-/**
- * Schedules the specified timer queue.
- *
- * @param pVM The VM to run the timers for.
- * @param pQueue The queue to schedule.
- *
- * @remarks Called while owning the lock.
- */
-void tmTimerQueueSchedule(PVM pVM, PTMTIMERQUEUE pQueue)
-{
- TM_ASSERT_LOCK(pVM);
-
- /*
- * Dequeue the scheduling list and iterate it.
- */
- int32_t offNext = ASMAtomicXchgS32(&pQueue->offSchedule, 0);
- Log2(("tmTimerQueueSchedule: pQueue=%p:{.enmClock=%d, offNext=%RI32, .u64Expired=%'RU64}\n", pQueue, pQueue->enmClock, offNext, pQueue->u64Expire));
- if (!offNext)
- return;
- PTMTIMER pNext = (PTMTIMER)((intptr_t)pQueue + offNext);
- while (pNext)
- {
- /*
- * Unlink the head timer and find the next one.
- */
- PTMTIMER pTimer = pNext;
- pNext = pNext->offScheduleNext ? (PTMTIMER)((intptr_t)pNext + pNext->offScheduleNext) : NULL;
- pTimer->offScheduleNext = 0;
-
- /*
- * Do the scheduling.
- */
- Log2(("tmTimerQueueSchedule: %p:{.enmState=%s, .enmClock=%d, .enmType=%d, .pszDesc=%s}\n",
- pTimer, tmTimerState(pTimer->enmState), pTimer->enmClock, pTimer->enmType, R3STRING(pTimer->pszDesc)));
- tmTimerQueueScheduleOne(pQueue, pTimer);
- Log2(("tmTimerQueueSchedule: %p: new %s\n", pTimer, tmTimerState(pTimer->enmState)));
- } /* foreach timer in current schedule batch. */
- Log2(("tmTimerQueueSchedule: u64Expired=%'RU64\n", pQueue->u64Expire));
-}
-
-
-#ifdef VBOX_STRICT
-/**
- * Checks that the timer queues are sane.
- *
- * @param pVM VM handle.
- *
- * @remarks Called while owning the lock.
- */
-void tmTimerQueuesSanityChecks(PVM pVM, const char *pszWhere)
-{
- TM_ASSERT_LOCK(pVM);
-
- /*
- * Check the linking of the active lists.
- */
- for (int i = 0; i < TMCLOCK_MAX; i++)
- {
- PTMTIMERQUEUE pQueue = &pVM->tm.s.CTX_SUFF(paTimerQueues)[i];
- Assert((int)pQueue->enmClock == i);
- PTMTIMER pPrev = NULL;
- for (PTMTIMER pCur = TMTIMER_GET_HEAD(pQueue); pCur; pPrev = pCur, pCur = TMTIMER_GET_NEXT(pCur))
- {
- AssertMsg((int)pCur->enmClock == i, ("%s: %d != %d\n", pszWhere, pCur->enmClock, i));
- AssertMsg(TMTIMER_GET_PREV(pCur) == pPrev, ("%s: %p != %p\n", pszWhere, TMTIMER_GET_PREV(pCur), pPrev));
- TMTIMERSTATE enmState = pCur->enmState;
- switch (enmState)
- {
- case TMTIMERSTATE_ACTIVE:
- AssertMsg( !pCur->offScheduleNext
- || pCur->enmState != TMTIMERSTATE_ACTIVE,
- ("%s: %RI32\n", pszWhere, pCur->offScheduleNext));
- break;
- case TMTIMERSTATE_PENDING_STOP:
- case TMTIMERSTATE_PENDING_RESCHEDULE:
- case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
- break;
- default:
- AssertMsgFailed(("%s: Invalid state enmState=%d %s\n", pszWhere, enmState, tmTimerState(enmState)));
- break;
- }
- }
- }
-
-
-# ifdef IN_RING3
- /*
- * Do the big list and check that active timers all are in the active lists.
- */
- PTMTIMERR3 pPrev = NULL;
- for (PTMTIMERR3 pCur = pVM->tm.s.pCreated; pCur; pPrev = pCur, pCur = pCur->pBigNext)
- {
- Assert(pCur->pBigPrev == pPrev);
- Assert((unsigned)pCur->enmClock < (unsigned)TMCLOCK_MAX);
-
- TMTIMERSTATE enmState = pCur->enmState;
- switch (enmState)
- {
- case TMTIMERSTATE_ACTIVE:
- case TMTIMERSTATE_PENDING_STOP:
- case TMTIMERSTATE_PENDING_RESCHEDULE:
- case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
- {
- PTMTIMERR3 pCurAct = TMTIMER_GET_HEAD(&pVM->tm.s.CTX_SUFF(paTimerQueues)[pCur->enmClock]);
- Assert(pCur->offPrev || pCur == pCurAct);
- while (pCurAct && pCurAct != pCur)
- pCurAct = TMTIMER_GET_NEXT(pCurAct);
- Assert(pCurAct == pCur);
- break;
- }
-
- case TMTIMERSTATE_PENDING_SCHEDULE:
- case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
- case TMTIMERSTATE_STOPPED:
- case TMTIMERSTATE_EXPIRED_DELIVER:
- {
- Assert(!pCur->offNext);
- Assert(!pCur->offPrev);
- for (PTMTIMERR3 pCurAct = TMTIMER_GET_HEAD(&pVM->tm.s.CTX_SUFF(paTimerQueues)[pCur->enmClock]);
- pCurAct;
- pCurAct = TMTIMER_GET_NEXT(pCurAct))
- {
- Assert(pCurAct != pCur);
- Assert(TMTIMER_GET_NEXT(pCurAct) != pCur);
- Assert(TMTIMER_GET_PREV(pCurAct) != pCur);
- }
- break;
- }
-
- /* ignore */
- case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
- break;
-
- /* shouldn't get here! */
- case TMTIMERSTATE_EXPIRED_GET_UNLINK:
- case TMTIMERSTATE_DESTROY:
- default:
- AssertMsgFailed(("Invalid state enmState=%d %s\n", enmState, tmTimerState(enmState)));
- break;
- }
- }
-# endif /* IN_RING3 */
-}
-#endif /* !VBOX_STRICT */
-
-
-/**
- * Gets the current warp drive percent.
- *
- * @returns The warp drive percent.
- * @param pVM The VM handle.
- */
-VMMDECL(uint32_t) TMGetWarpDrive(PVM pVM)
-{
- return pVM->tm.s.u32VirtualWarpDrivePercentage;
-}
-
-
-/**
* Gets the highest frequency hint for all the important timers.
*
* @returns The highest frequency. 0 if no timers care.
@@ -2297,7 +2450,7 @@ static uint32_t tmGetFrequencyHint(PVM pVM)
uint32_t uMaxHzHint = ASMAtomicUoReadU32(&pVM->tm.s.uMaxHzHint);
if (RT_UNLIKELY(ASMAtomicReadBool(&pVM->tm.s.fHzHintNeedsUpdating)))
{
- if (RT_SUCCESS(tmTimerTryLock(pVM)))
+ if (RT_SUCCESS(TM_TRY_LOCK_TIMERS(pVM)))
{
ASMAtomicWriteBool(&pVM->tm.s.fHzHintNeedsUpdating, false);
@@ -2338,7 +2491,7 @@ static uint32_t tmGetFrequencyHint(PVM pVM)
}
ASMAtomicWriteU32(&pVM->tm.s.uMaxHzHint, uMaxHzHint);
Log(("tmGetFrequencyHint: New value %u Hz\n", uMaxHzHint));
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
}
}
return uMaxHzHint;
diff --git a/src/VBox/VMM/VMMAll/TMAllCpu.cpp b/src/VBox/VMM/VMMAll/TMAllCpu.cpp
index f16cb6330..69c3fa64c 100644
--- a/src/VBox/VMM/VMMAll/TMAllCpu.cpp
+++ b/src/VBox/VMM/VMMAll/TMAllCpu.cpp
@@ -1,4 +1,4 @@
-/* $Id: TMAllCpu.cpp $ */
+/* $Id: TMAllCpu.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* TM - Timeout Manager, CPU Time, All Contexts.
*/
diff --git a/src/VBox/VMM/VMMAll/TMAllReal.cpp b/src/VBox/VMM/VMMAll/TMAllReal.cpp
index ecd02f163..bb3412982 100644
--- a/src/VBox/VMM/VMMAll/TMAllReal.cpp
+++ b/src/VBox/VMM/VMMAll/TMAllReal.cpp
@@ -1,4 +1,4 @@
-/* $Id: TMAllReal.cpp $ */
+/* $Id: TMAllReal.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* TM - Timeout Manager, Real Time, All Contexts.
*/
diff --git a/src/VBox/VMM/VMMAll/TMAllVirtual.cpp b/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
index 76f591728..c312f65df 100644
--- a/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
+++ b/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
@@ -1,4 +1,4 @@
-/* $Id: TMAllVirtual.cpp $ */
+/* $Id: TMAllVirtual.cpp 37527 2011-06-17 10:18:02Z vboxsync $ */
/** @file
* TM - Timeout Manager, Virtual Time, All Contexts.
*/
@@ -21,6 +21,7 @@
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_TM
#include <VBox/vmm/tm.h>
+#include <VBox/vmm/dbgftrace.h>
#ifdef IN_RING3
# include <VBox/vmm/rem.h>
# include <iprt/thread.h>
@@ -82,15 +83,16 @@ DECLEXPORT(uint64_t) tmVirtualNanoTSRediscover(PRTTIMENANOTSDATA pData)
*/
DECLINLINE(uint64_t) tmVirtualGetRawNanoTS(PVM pVM)
{
-#ifdef IN_RING3
- return CTXALLSUFF(pVM->tm.s.pfnVirtualGetRaw)(&CTXALLSUFF(pVM->tm.s.VirtualGetRawData));
+# ifdef IN_RING3
+ uint64_t u64 = CTXALLSUFF(pVM->tm.s.pfnVirtualGetRaw)(&CTXALLSUFF(pVM->tm.s.VirtualGetRawData));
# else /* !IN_RING3 */
uint32_t cPrevSteps = pVM->tm.s.CTX_SUFF(VirtualGetRawData).c1nsSteps;
uint64_t u64 = pVM->tm.s.CTX_SUFF(pfnVirtualGetRaw)(&pVM->tm.s.CTX_SUFF(VirtualGetRawData));
if (cPrevSteps != pVM->tm.s.CTX_SUFF(VirtualGetRawData).c1nsSteps)
VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_TO_R3);
- return u64;
# endif /* !IN_RING3 */
+ /*DBGFTRACE_POS_U64(pVM, u64);*/
+ return u64;
}
#else
@@ -459,9 +461,18 @@ DECLINLINE(uint64_t) tmVirtualSyncGetHandleCatchUpLocked(PVM pVM, uint64_t u64,
* set the timer pending flag.
*/
u64 -= off;
+
+ uint64_t u64Last = ASMAtomicUoReadU64(&pVM->tm.s.u64VirtualSync);
+ if (u64Last > u64)
+ {
+ u64 = u64Last + 1;
+ STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGetAdjLast);
+ }
+
uint64_t u64Expire = ASMAtomicReadU64(&pVM->tm.s.CTX_SUFF(paTimerQueues)[TMCLOCK_VIRTUAL_SYNC].u64Expire);
if (u64 < u64Expire)
{
+ ASMAtomicWriteU64(&pVM->tm.s.u64VirtualSync, u64);
if (fUpdateOff)
ASMAtomicWriteU64(&pVM->tm.s.offVirtualSync, off);
if (fStop)
@@ -476,7 +487,7 @@ DECLINLINE(uint64_t) tmVirtualSyncGetHandleCatchUpLocked(PVM pVM, uint64_t u64,
pVM->tm.s.u32VirtualSyncCatchUpPercentage + 100);
*pcNsToDeadline = tmVirtualVirtToNsDeadline(pVM, cNsToDeadline);
}
- tmVirtualSyncUnlock(pVM);
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
}
else
{
@@ -489,7 +500,7 @@ DECLINLINE(uint64_t) tmVirtualSyncGetHandleCatchUpLocked(PVM pVM, uint64_t u64,
VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
Log5(("TMAllVirtual(%u): FF: %d -> 1\n", __LINE__, VMCPU_FF_ISPENDING(pVCpuDst, VMCPU_FF_TIMER)));
Log4(("TM: %'RU64/-%'8RU64: exp tmr=>ff [vsghcul]\n", u64, pVM->tm.s.offVirtualSync - pVM->tm.s.offVirtualSyncGivenUp));
- tmVirtualSyncUnlock(pVM);
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
if (pcNsToDeadline)
*pcNsToDeadline = 0;
@@ -503,6 +514,7 @@ DECLINLINE(uint64_t) tmVirtualSyncGetHandleCatchUpLocked(PVM pVM, uint64_t u64,
STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGetLocked);
Log6(("tmVirtualSyncGetHandleCatchUpLocked -> %'RU64\n", u64));
+ DBGFTRACE_U64_TAG(pVM, u64, "tmVirtualSyncGetHandleCatchUpLocked");
return u64;
}
@@ -525,11 +537,12 @@ DECLINLINE(uint64_t) tmVirtualSyncGetLocked(PVM pVM, uint64_t u64, uint64_t *pcN
if (!pVM->tm.s.fVirtualSyncTicking)
{
u64 = ASMAtomicUoReadU64(&pVM->tm.s.u64VirtualSync);
- tmVirtualSyncUnlock(pVM);
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
if (pcNsToDeadline)
*pcNsToDeadline = 0;
STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGetLocked);
Log6(("tmVirtualSyncGetLocked -> %'RU64 [stopped]\n", u64));
+ DBGFTRACE_U64_TAG(pVM, u64, "tmVirtualSyncGetLocked-stopped");
return u64;
}
@@ -546,10 +559,19 @@ DECLINLINE(uint64_t) tmVirtualSyncGetLocked(PVM pVM, uint64_t u64, uint64_t *pcN
* set the timer pending flag.
*/
u64 -= off;
+
+ uint64_t u64Last = ASMAtomicUoReadU64(&pVM->tm.s.u64VirtualSync);
+ if (u64Last > u64)
+ {
+ u64 = u64Last + 1;
+ STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGetAdjLast);
+ }
+
uint64_t u64Expire = ASMAtomicReadU64(&pVM->tm.s.CTX_SUFF(paTimerQueues)[TMCLOCK_VIRTUAL_SYNC].u64Expire);
if (u64 < u64Expire)
{
- tmVirtualSyncUnlock(pVM);
+ ASMAtomicWriteU64(&pVM->tm.s.u64VirtualSync, u64);
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
if (pcNsToDeadline)
*pcNsToDeadline = tmVirtualVirtToNsDeadline(pVM, u64Expire - u64);
}
@@ -564,7 +586,7 @@ DECLINLINE(uint64_t) tmVirtualSyncGetLocked(PVM pVM, uint64_t u64, uint64_t *pcN
VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
Log5(("TMAllVirtual(%u): FF: %d -> 1\n", __LINE__, !!VMCPU_FF_ISPENDING(pVCpuDst, VMCPU_FF_TIMER)));
Log4(("TM: %'RU64/-%'8RU64: exp tmr=>ff [vsgl]\n", u64, pVM->tm.s.offVirtualSync - pVM->tm.s.offVirtualSyncGivenUp));
- tmVirtualSyncUnlock(pVM);
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
#ifdef IN_RING3
REMR3NotifyTimerPending(pVM, pVCpuDst);
@@ -577,6 +599,7 @@ DECLINLINE(uint64_t) tmVirtualSyncGetLocked(PVM pVM, uint64_t u64, uint64_t *pcN
}
STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGetLocked);
Log6(("tmVirtualSyncGetLocked -> %'RU64\n", u64));
+ DBGFTRACE_U64_TAG(pVM, u64, "tmVirtualSyncGetLocked");
return u64;
}
@@ -596,18 +619,21 @@ DECLINLINE(uint64_t) tmVirtualSyncGetEx(PVM pVM, bool fCheckTimers, uint64_t *pc
{
STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGet);
+ uint64_t u64;
if (!pVM->tm.s.fVirtualSyncTicking)
{
if (pcNsToDeadline)
*pcNsToDeadline = 0;
- return pVM->tm.s.u64VirtualSync;
+ u64 = pVM->tm.s.u64VirtualSync;
+ DBGFTRACE_U64_TAG(pVM, u64, "tmVirtualSyncGetEx-stopped1");
+ return u64;
}
/*
* Query the virtual clock and do the usual expired timer check.
*/
Assert(pVM->tm.s.cVirtualTicking);
- uint64_t u64 = tmVirtualGetRaw(pVM);
+ u64 = tmVirtualGetRaw(pVM);
if (fCheckTimers)
{
PVMCPU pVCpuDst = &pVM->aCpus[pVM->tm.s.idTimerCpu];
@@ -625,6 +651,16 @@ DECLINLINE(uint64_t) tmVirtualSyncGetEx(PVM pVM, bool fCheckTimers, uint64_t *pc
}
/*
+ * If we can get the lock, get it. The result is much more reliable.
+ *
+ * Note! This is where all clock source devices branch off because they
+ * will be owning the lock already. The 'else' is taken by code
+ * which is less picky or hasn't been adjusted yet
+ */
+ if (PDMCritSectTryEnter(&pVM->tm.s.VirtualSyncLock) == VINF_SUCCESS)
+ return tmVirtualSyncGetLocked(pVM, u64, pcNsToDeadline);
+
+ /*
* When the clock is ticking, not doing catch ups and not running into an
* expired time, we can get away without locking. Try this first.
*/
@@ -646,6 +682,7 @@ DECLINLINE(uint64_t) tmVirtualSyncGetEx(PVM pVM, bool fCheckTimers, uint64_t *pc
*pcNsToDeadline = tmVirtualVirtToNsDeadline(pVM, u64Expire - off);
STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGetLockless);
Log6(("tmVirtualSyncGetEx -> %'RU64 [lockless]\n", off));
+ DBGFTRACE_U64_TAG(pVM, off, "tmVirtualSyncGetEx-lockless");
return off;
}
}
@@ -660,6 +697,7 @@ DECLINLINE(uint64_t) tmVirtualSyncGetEx(PVM pVM, bool fCheckTimers, uint64_t *pc
*pcNsToDeadline = 0;
STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGetLockless);
Log6(("tmVirtualSyncGetEx -> %'RU64 [lockless/stopped]\n", off));
+ DBGFTRACE_U64_TAG(pVM, off, "tmVirtualSyncGetEx-stopped2");
return off;
}
}
@@ -687,7 +725,7 @@ DECLINLINE(uint64_t) tmVirtualSyncGetEx(PVM pVM, bool fCheckTimers, uint64_t *pc
for (;; cOuterTries--)
{
/* Try grab the lock, things get simpler when owning the lock. */
- int rcLock = tmVirtualSyncTryLock(pVM);
+ int rcLock = PDMCritSectTryEnter(&pVM->tm.s.VirtualSyncLock);
if (RT_SUCCESS_NP(rcLock))
return tmVirtualSyncGetLocked(pVM, u64, pcNsToDeadline);
@@ -701,6 +739,7 @@ DECLINLINE(uint64_t) tmVirtualSyncGetEx(PVM pVM, bool fCheckTimers, uint64_t *pc
if (pcNsToDeadline)
*pcNsToDeadline = 0;
Log6(("tmVirtualSyncGetEx -> %'RU64 [stopped]\n", off));
+ DBGFTRACE_U64_TAG(pVM, off, "tmVirtualSyncGetEx-stopped3");
return off;
}
@@ -761,6 +800,7 @@ DECLINLINE(uint64_t) tmVirtualSyncGetEx(PVM pVM, bool fCheckTimers, uint64_t *pc
* set the timer pending flag.
*/
u64 -= off;
+/** @todo u64VirtualSyncLast */
uint64_t u64Expire = ASMAtomicReadU64(&pVM->tm.s.CTX_SUFF(paTimerQueues)[TMCLOCK_VIRTUAL_SYNC].u64Expire);
if (u64 >= u64Expire)
{
@@ -793,6 +833,7 @@ DECLINLINE(uint64_t) tmVirtualSyncGetEx(PVM pVM, bool fCheckTimers, uint64_t *pc
}
Log6(("tmVirtualSyncGetEx -> %'RU64\n", u64));
+ DBGFTRACE_U64_TAG(pVM, u64, "tmVirtualSyncGetEx-nolock");
return u64;
}
diff --git a/src/VBox/VMM/VMMAll/TRPMAll.cpp b/src/VBox/VMM/VMMAll/TRPMAll.cpp
index 4c2bdf237..a8353bfac 100644
--- a/src/VBox/VMM/VMMAll/TRPMAll.cpp
+++ b/src/VBox/VMM/VMMAll/TRPMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: TRPMAll.cpp $ */
+/* $Id: TRPMAll.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* TRPM - Trap Monitor - Any Context.
*/
@@ -29,13 +29,13 @@
#include "TRPMInternal.h"
#include <VBox/vmm/vm.h>
#include <VBox/err.h>
-#include <VBox/x86.h>
#include <VBox/vmm/em.h>
#include <VBox/log.h>
#include <iprt/assert.h>
#include <iprt/asm.h>
#include <iprt/asm-amd64-x86.h>
#include <iprt/param.h>
+#include <iprt/x86.h>
#include "internal/pgm.h"
diff --git a/src/VBox/VMM/VMMAll/VMAll.cpp b/src/VBox/VMM/VMMAll/VMAll.cpp
index 1d8623af2..272b819af 100644
--- a/src/VBox/VMM/VMMAll/VMAll.cpp
+++ b/src/VBox/VMM/VMMAll/VMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMAll.cpp $ */
+/* $Id: VMAll.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VM - Virtual Machine All Contexts.
*/
diff --git a/src/VBox/VMM/VMMAll/VMMAll.cpp b/src/VBox/VMM/VMMAll/VMMAll.cpp
index 6aa4cfbd1..65e839cc1 100644
--- a/src/VBox/VMM/VMMAll/VMMAll.cpp
+++ b/src/VBox/VMM/VMMAll/VMMAll.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMMAll.cpp $ */
+/* $Id: VMMAll.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VMM All Contexts.
*/
diff --git a/src/VBox/VMM/VMMAll/VMMAllA.asm b/src/VBox/VMM/VMMAll/VMMAllA.asm
index dae37ada3..7c9e5e361 100644
--- a/src/VBox/VMM/VMMAll/VMMAllA.asm
+++ b/src/VBox/VMM/VMMAll/VMMAllA.asm
@@ -1,4 +1,4 @@
-; $Id: VMMAllA.asm $
+; $Id: VMMAllA.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VMM - All Contexts Assembly Routines.
;
diff --git a/src/VBox/VMM/VMMR0/CPUMR0.cpp b/src/VBox/VMM/VMMR0/CPUMR0.cpp
index e3e889816..758ad1d0a 100644
--- a/src/VBox/VMM/VMMR0/CPUMR0.cpp
+++ b/src/VBox/VMM/VMMR0/CPUMR0.cpp
@@ -1,4 +1,4 @@
-/* $Id: CPUMR0.cpp $ */
+/* $Id: CPUMR0.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* CPUM - Host Context Ring 0.
*/
@@ -23,7 +23,6 @@
#include <VBox/vmm/cpum.h>
#include "CPUMInternal.h"
#include <VBox/vmm/vm.h>
-#include <VBox/x86.h>
#include <VBox/err.h>
#include <VBox/log.h>
#include <VBox/vmm/hwaccm.h>
@@ -34,6 +33,7 @@
# include <iprt/memobj.h>
# include <VBox/apic.h>
#endif
+#include <iprt/x86.h>
#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
diff --git a/src/VBox/VMM/VMMR0/CPUMR0A.asm b/src/VBox/VMM/VMMR0/CPUMR0A.asm
index e3d99e495..13d791185 100644
--- a/src/VBox/VMM/VMMR0/CPUMR0A.asm
+++ b/src/VBox/VMM/VMMR0/CPUMR0A.asm
@@ -1,4 +1,4 @@
-; $Id: CPUMR0A.asm $
+; $Id: CPUMR0A.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; CPUM - Guest Context Assembly Routines.
;
@@ -23,7 +23,7 @@
%include "VBox/err.mac"
%include "VBox/vmm/stam.mac"
%include "CPUMInternal.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "VBox/vmm/cpum.mac"
%ifdef IN_RING3
diff --git a/src/VBox/VMM/VMMR0/CPUMR0UnusedA.asm b/src/VBox/VMM/VMMR0/CPUMR0UnusedA.asm
index 1568be7b1..c16d489d4 100644
--- a/src/VBox/VMM/VMMR0/CPUMR0UnusedA.asm
+++ b/src/VBox/VMM/VMMR0/CPUMR0UnusedA.asm
@@ -1,4 +1,4 @@
-; $Id: CPUMR0UnusedA.asm $
+; $Id: CPUMR0UnusedA.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; CPUM - Guest Context Assembly Routines.
;
@@ -23,7 +23,7 @@
%include "VBox/err.mac"
%include "VBox/vmm/stam.mac"
%include "CPUMInternal.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "VBox/vmm/cpum.mac"
%ifdef IN_RING3
diff --git a/src/VBox/VMM/VMMR0/GMMR0.cpp b/src/VBox/VMM/VMMR0/GMMR0.cpp
index e1feefaad..474cb7fa4 100644
--- a/src/VBox/VMM/VMMR0/GMMR0.cpp
+++ b/src/VBox/VMM/VMMR0/GMMR0.cpp
@@ -1,10 +1,10 @@
-/* $Id: GMMR0.cpp $ */
+/* $Id: GMMR0.cpp 37805 2011-07-06 15:00:19Z vboxsync $ */
/** @file
* GMM - Global Memory Manager.
*/
/*
- * Copyright (C) 2007 Oracle Corporation
+ * Copyright (C) 2007-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;
@@ -133,7 +133,7 @@
*
*
*
- * @section sec_gmm_numa NUMA
+ * @section sec_gmm_numa NUMA
*
* NUMA considerations will be designed and implemented a bit later.
*
@@ -150,6 +150,7 @@
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_GMM
+#include <VBox/rawpci.h>
#include <VBox/vmm/vm.h>
#include <VBox/vmm/gmm.h>
#include "GMMR0Internal.h"
@@ -160,10 +161,13 @@
#include <VBox/err.h>
#include <iprt/asm.h>
#include <iprt/avl.h>
+#include <iprt/list.h>
#include <iprt/mem.h>
#include <iprt/memobj.h>
+#include <iprt/mp.h>
#include <iprt/semaphore.h>
#include <iprt/string.h>
+#include <iprt/time.h>
/*******************************************************************************
@@ -172,9 +176,6 @@
/** Pointer to set of free chunks. */
typedef struct GMMCHUNKFREESET *PGMMCHUNKFREESET;
-/** Pointer to a GMM allocation chunk. */
-typedef struct GMMCHUNK *PGMMCHUNK;
-
/**
* The per-page tracking structure employed by the GMM.
*
@@ -360,21 +361,13 @@ AssertCompile(GMM_PAGE_PFN_UNSHAREABLE == (GMM_GCPHYS_UNSHAREABLE >> PAGE_SHIFT)
typedef struct GMMCHUNKMAP
{
/** The mapping object. */
- RTR0MEMOBJ MapObj;
+ RTR0MEMOBJ hMapObj;
/** The VM owning the mapping. */
- PGVM pGVM;
+ PGVM pGVM;
} GMMCHUNKMAP;
/** Pointer to a GMM allocation chunk mapping. */
typedef struct GMMCHUNKMAP *PGMMCHUNKMAP;
-typedef enum GMMCHUNKTYPE
-{
- GMMCHUNKTYPE_INVALID = 0,
- GMMCHUNKTYPE_NON_CONTINUOUS = 1, /* 4 kb pages */
- GMMCHUNKTYPE_CONTINUOUS = 2, /* one 2 MB continuous physical range. */
- GMMCHUNKTYPE_32BIT_HACK = 0x7fffffff
-} GMMCHUNKTYPE;
-
/**
* A GMM allocation chunk.
@@ -382,41 +375,62 @@ typedef enum GMMCHUNKTYPE
typedef struct GMMCHUNK
{
/** The AVL node core.
- * The Key is the chunk ID. */
+ * The Key is the chunk ID. (Giant mtx.) */
AVLU32NODECORE Core;
/** The memory object.
* Either from RTR0MemObjAllocPhysNC or RTR0MemObjLockUser depending on
- * what the host can dish up with. */
- RTR0MEMOBJ MemObj;
- /** Pointer to the next chunk in the free list. */
+ * what the host can dish up with. (Chunk mtx protects mapping accesses
+ * and related frees.) */
+ RTR0MEMOBJ hMemObj;
+ /** Pointer to the next chunk in the free list. (Giant mtx.) */
PGMMCHUNK pFreeNext;
- /** Pointer to the previous chunk in the free list. */
+ /** Pointer to the previous chunk in the free list. (Giant mtx.) */
PGMMCHUNK pFreePrev;
- /** Pointer to the free set this chunk belongs to. NULL for
- * chunks with no free pages. */
+ /** Pointer to the free set this chunk belongs to. NULL for
+ * chunks with no free pages. (Giant mtx.) */
PGMMCHUNKFREESET pSet;
- /** Pointer to an array of mappings. */
- PGMMCHUNKMAP paMappings;
- /** The number of mappings. */
- uint16_t cMappings;
- /** The head of the list of free pages. UINT16_MAX is the NIL value. */
+ /** List node in the chunk list (GMM::ChunkList). (Giant mtx.) */
+ RTLISTNODE ListNode;
+ /** Pointer to an array of mappings. (Chunk mtx.) */
+ PGMMCHUNKMAP paMappingsX;
+ /** The number of mappings. (Chunk mtx.) */
+ uint16_t cMappingsX;
+ /** The mapping lock this chunk is using using. UINT16_MAX if nobody is
+ * mapping or freeing anything. (Giant mtx.) */
+ uint8_t volatile iChunkMtx;
+ /** Flags field reserved for future use (like eliminating enmType).
+ * (Giant mtx.) */
+ uint8_t fFlags;
+ /** The head of the list of free pages. UINT16_MAX is the NIL value.
+ * (Giant mtx.) */
uint16_t iFreeHead;
- /** The number of free pages. */
+ /** The number of free pages. (Giant mtx.) */
uint16_t cFree;
/** The GVM handle of the VM that first allocated pages from this chunk, this
* is used as a preference when there are several chunks to choose from.
- * When in bound memory mode this isn't a preference any longer. */
+ * When in bound memory mode this isn't a preference any longer. (Giant
+ * mtx.) */
uint16_t hGVM;
- /** The number of private pages. */
+ /** The ID of the NUMA node the memory mostly resides on. (Reserved for
+ * future use.) (Giant mtx.) */
+ uint16_t idNumaNode;
+ /** The number of private pages. (Giant mtx.) */
uint16_t cPrivate;
- /** The number of shared pages. */
+ /** The number of shared pages. (Giant mtx.) */
uint16_t cShared;
- /** Chunk type */
- GMMCHUNKTYPE enmType;
- /** The pages. */
+ /** The pages. (Giant mtx.) */
GMMPAGE aPages[GMM_CHUNK_SIZE >> PAGE_SHIFT];
} GMMCHUNK;
+/** Indicates that the NUMA properies of the memory is unknown. */
+#define GMM_CHUNK_NUMA_ID_UNKNOWN UINT16_C(0xfffe)
+
+/** @name GMM_CHUNK_FLAGS_XXX - chunk flags.
+ * @{ */
+/** Indicates that the chunk is a large page (2MB). */
+#define GMM_CHUNK_FLAGS_LARGE_PAGE UINT16_C(0x0001)
+/** @} */
+
/**
* An allocation chunk TLB entry.
@@ -424,9 +438,9 @@ typedef struct GMMCHUNK
typedef struct GMMCHUNKTLBE
{
/** The chunk id. */
- uint32_t idChunk;
+ uint32_t idChunk;
/** Pointer to the chunk. */
- PGMMCHUNK pChunk;
+ PGMMCHUNK pChunk;
} GMMCHUNKTLBE;
/** Pointer to an allocation chunk TLB entry. */
typedef GMMCHUNKTLBE *PGMMCHUNKTLBE;
@@ -449,25 +463,6 @@ typedef struct GMMCHUNKTLB
typedef GMMCHUNKTLB *PGMMCHUNKTLB;
-/** The GMMCHUNK::cFree shift count. */
-#define GMM_CHUNK_FREE_SET_SHIFT 4
-/** The GMMCHUNK::cFree mask for use when considering relinking a chunk. */
-#define GMM_CHUNK_FREE_SET_MASK 15
-/** The number of lists in set. */
-#define GMM_CHUNK_FREE_SET_LISTS (GMM_CHUNK_NUM_PAGES >> GMM_CHUNK_FREE_SET_SHIFT)
-
-/**
- * A set of free chunks.
- */
-typedef struct GMMCHUNKFREESET
-{
- /** The number of free pages in the set. */
- uint64_t cFreePages;
- /** Chunks ordered by increasing number of free pages. */
- PGMMCHUNK apLists[GMM_CHUNK_FREE_SET_LISTS];
-} GMMCHUNKFREESET;
-
-
/**
* The GMM instance data.
*/
@@ -475,15 +470,21 @@ typedef struct GMM
{
/** Magic / eye catcher. GMM_MAGIC */
uint32_t u32Magic;
+ /** The number of threads waiting on the mutex. */
+ uint32_t cMtxContenders;
/** The fast mutex protecting the GMM.
* More fine grained locking can be implemented later if necessary. */
- RTSEMFASTMUTEX Mtx;
+ RTSEMFASTMUTEX hMtx;
+#ifdef VBOX_STRICT
+ /** The current mutex owner. */
+ RTNATIVETHREAD hMtxOwner;
+#endif
/** The chunk tree. */
PAVLU32NODECORE pChunks;
/** The chunk TLB. */
GMMCHUNKTLB ChunkTLB;
/** The private free set. */
- GMMCHUNKFREESET Private;
+ GMMCHUNKFREESET PrivateX;
/** The shared free set. */
GMMCHUNKFREESET Shared;
@@ -491,6 +492,9 @@ typedef struct GMM
/** @todo separate trees for distinctly different guest OSes. */
PAVLGCPTRNODECORE pGlobalSharedModuleTree;
+ /** The chunk list. For simplifying the cleanup process. */
+ RTLISTNODE ChunkList;
+
/** The maximum number of pages we're allowed to allocate.
* @gcfgm 64-bit GMM/MaxPages Direct.
* @gcfgm 32-bit GMM/PctPages Relative to the number of host pages. */
@@ -526,6 +530,9 @@ typedef struct GMM
/** The number of registered VMs. */
uint16_t cRegisteredVMs;
+ /** The number of freed chunks ever. This is used a list generation to
+ * avoid restarting the cleanup scanning when the list wasn't modified. */
+ uint32_t cFreedChunks;
/** The previous allocated Chunk ID.
* Used as a hint to avoid scanning the whole bitmap. */
uint32_t idChunkPrev;
@@ -533,12 +540,51 @@ typedef struct GMM
* Bits of allocated IDs are set, free ones are clear.
* The NIL id (0) is marked allocated. */
uint32_t bmChunkId[(GMM_CHUNKID_LAST + 1 + 31) / 32];
+
+ /** The index of the next mutex to use. */
+ uint32_t iNextChunkMtx;
+ /** Chunk locks for reducing lock contention without having to allocate
+ * one lock per chunk. */
+ struct
+ {
+ /** The mutex */
+ RTSEMFASTMUTEX hMtx;
+ /** The number of threads currently using this mutex. */
+ uint32_t volatile cUsers;
+ } aChunkMtx[64];
} GMM;
/** Pointer to the GMM instance. */
typedef GMM *PGMM;
/** The value of GMM::u32Magic (Katsuhiro Otomo). */
-#define GMM_MAGIC 0x19540414
+#define GMM_MAGIC UINT32_C(0x19540414)
+
+
+/**
+ * GMM chunk mutex state.
+ *
+ * This is returned by gmmR0ChunkMutexAcquire and is used by the other
+ * gmmR0ChunkMutex* methods.
+ */
+typedef struct GMMR0CHUNKMTXSTATE
+{
+ PGMM pGMM;
+ /** The index of the chunk mutex. */
+ uint8_t iChunkMtx;
+ /** The relevant flags (GMMR0CHUNK_MTX_XXX). */
+ uint8_t fFlags;
+} GMMR0CHUNKMTXSTATE;
+/** Pointer to a chunk mutex state. */
+typedef GMMR0CHUNKMTXSTATE *PGMMR0CHUNKMTXSTATE;
+
+/** @name GMMR0CHUNK_MTX_XXX
+ * @{ */
+#define GMMR0CHUNK_MTX_INVALID UINT32_C(0)
+#define GMMR0CHUNK_MTX_KEEP_GIANT UINT32_C(1)
+#define GMMR0CHUNK_MTX_RETAKE_GIANT UINT32_C(2)
+#define GMMR0CHUNK_MTX_DROP_GIANT UINT32_C(3)
+#define GMMR0CHUNK_MTX_END UINT32_C(4)
+/** @} */
/*******************************************************************************
@@ -620,16 +666,17 @@ static PGMM g_pGMM = NULL;
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
-static DECLCALLBACK(int) gmmR0TermDestroyChunk(PAVLU32NODECORE pNode, void *pvGMM);
-static DECLCALLBACK(int) gmmR0CleanupVMScanChunk(PAVLU32NODECORE pNode, void *pvGMM);
-static DECLCALLBACK(int) gmmR0CleanupSharedModule(PAVLGCPTRNODECORE pNode, void *pvGVM);
-/*static*/ DECLCALLBACK(int) gmmR0CleanupVMDestroyChunk(PAVLU32NODECORE pNode, void *pvGVM);
-DECLINLINE(void) gmmR0LinkChunk(PGMMCHUNK pChunk, PGMMCHUNKFREESET pSet);
-DECLINLINE(void) gmmR0UnlinkChunk(PGMMCHUNK pChunk);
-static uint32_t gmmR0SanityCheck(PGMM pGMM, const char *pszFunction, unsigned uLineNo);
-static void gmmR0FreeChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk);
-static void gmmR0FreeSharedPage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage);
-static int gmmR0UnmapChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk);
+static DECLCALLBACK(int) gmmR0TermDestroyChunk(PAVLU32NODECORE pNode, void *pvGMM);
+static bool gmmR0CleanupVMScanChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk);
+DECLINLINE(void) gmmR0UnlinkChunk(PGMMCHUNK pChunk);
+DECLINLINE(void) gmmR0LinkChunk(PGMMCHUNK pChunk, PGMMCHUNKFREESET pSet);
+DECLINLINE(void) gmmR0SelectSetAndLinkChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk);
+static uint32_t gmmR0SanityCheck(PGMM pGMM, const char *pszFunction, unsigned uLineNo);
+static bool gmmR0FreeChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, bool fRelaxedSem);
+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);
+static void gmmR0SharedModuleCleanup(PGMM pGMM, PGVM pGVM);
@@ -646,59 +693,80 @@ GMMR0DECL(int) GMMR0Init(void)
LogFlow(("GMMInit:\n"));
/*
- * Allocate the instance data and the lock(s).
+ * Allocate the instance data and the locks.
*/
PGMM pGMM = (PGMM)RTMemAllocZ(sizeof(*pGMM));
if (!pGMM)
return VERR_NO_MEMORY;
+
pGMM->u32Magic = GMM_MAGIC;
for (unsigned i = 0; i < RT_ELEMENTS(pGMM->ChunkTLB.aEntries); i++)
pGMM->ChunkTLB.aEntries[i].idChunk = NIL_GMM_CHUNKID;
+ RTListInit(&pGMM->ChunkList);
ASMBitSet(&pGMM->bmChunkId[0], NIL_GMM_CHUNKID);
- int rc = RTSemFastMutexCreate(&pGMM->Mtx);
+ int rc = RTSemFastMutexCreate(&pGMM->hMtx);
if (RT_SUCCESS(rc))
{
- /*
- * Check and see if RTR0MemObjAllocPhysNC works.
- */
-#if 0 /* later, see #3170. */
- RTR0MEMOBJ MemObj;
- rc = RTR0MemObjAllocPhysNC(&MemObj, _64K, NIL_RTHCPHYS);
- if (RT_SUCCESS(rc))
+ unsigned iMtx;
+ for (iMtx = 0; iMtx < RT_ELEMENTS(pGMM->aChunkMtx); iMtx++)
{
- rc = RTR0MemObjFree(MemObj, true);
- AssertRC(rc);
+ rc = RTSemFastMutexCreate(&pGMM->aChunkMtx[iMtx].hMtx);
+ if (RT_FAILURE(rc))
+ break;
}
- else if (rc == VERR_NOT_SUPPORTED)
- pGMM->fLegacyAllocationMode = pGMM->fBoundMemoryMode = true;
- else
- SUPR0Printf("GMMR0Init: RTR0MemObjAllocPhysNC(,64K,Any) -> %d!\n", rc);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Check and see if RTR0MemObjAllocPhysNC works.
+ */
+#if 0 /* later, see #3170. */
+ RTR0MEMOBJ MemObj;
+ rc = RTR0MemObjAllocPhysNC(&MemObj, _64K, NIL_RTHCPHYS);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTR0MemObjFree(MemObj, true);
+ AssertRC(rc);
+ }
+ else if (rc == VERR_NOT_SUPPORTED)
+ pGMM->fLegacyAllocationMode = pGMM->fBoundMemoryMode = true;
+ else
+ SUPR0Printf("GMMR0Init: RTR0MemObjAllocPhysNC(,64K,Any) -> %d!\n", rc);
#else
# if defined(RT_OS_WINDOWS) || (defined(RT_OS_SOLARIS) && ARCH_BITS == 64) || defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
- pGMM->fLegacyAllocationMode = false;
+ pGMM->fLegacyAllocationMode = false;
# if ARCH_BITS == 32
- /* Don't reuse possibly partial chunks because of the virtual address space limitation. */
- pGMM->fBoundMemoryMode = true;
+ /* Don't reuse possibly partial chunks because of the virtual
+ address space limitation. */
+ pGMM->fBoundMemoryMode = true;
# else
- pGMM->fBoundMemoryMode = false;
+ pGMM->fBoundMemoryMode = false;
# endif
# else
- pGMM->fLegacyAllocationMode = true;
- pGMM->fBoundMemoryMode = true;
+ pGMM->fLegacyAllocationMode = true;
+ pGMM->fBoundMemoryMode = true;
# endif
#endif
+ /*
+ * Query system page count and guess a reasonable cMaxPages value.
+ */
+ pGMM->cMaxPages = UINT32_MAX; /** @todo IPRT function for query ram size and such. */
+
+ g_pGMM = pGMM;
+ LogFlow(("GMMInit: pGMM=%p fLegacyAllocationMode=%RTbool fBoundMemoryMode=%RTbool\n", pGMM, pGMM->fLegacyAllocationMode, pGMM->fBoundMemoryMode));
+ return VINF_SUCCESS;
+ }
+
/*
- * Query system page count and guess a reasonable cMaxPages value.
+ * Bail out.
*/
- pGMM->cMaxPages = UINT32_MAX; /** @todo IPRT function for query ram size and such. */
-
- g_pGMM = pGMM;
- LogFlow(("GMMInit: pGMM=%p fLegacyAllocationMode=%RTbool fBoundMemoryMode=%RTbool\n", pGMM, pGMM->fLegacyAllocationMode, pGMM->fBoundMemoryMode));
- return VINF_SUCCESS;
+ while (iMtx-- > 0)
+ RTSemFastMutexDestroy(pGMM->aChunkMtx[iMtx].hMtx);
+ RTSemFastMutexDestroy(pGMM->hMtx);
}
+ pGMM->u32Magic = 0;
RTMemFree(pGMM);
SUPR0Printf("GMMR0Init: failed! rc=%d\n", rc);
return rc;
@@ -729,14 +797,22 @@ GMMR0DECL(void) GMMR0Term(void)
*/
/* Destroy the fundamentals. */
g_pGMM = NULL;
- pGMM->u32Magic++;
- RTSemFastMutexDestroy(pGMM->Mtx);
- pGMM->Mtx = NIL_RTSEMFASTMUTEX;
+ pGMM->u32Magic = ~GMM_MAGIC;
+ RTSemFastMutexDestroy(pGMM->hMtx);
+ pGMM->hMtx = NIL_RTSEMFASTMUTEX;
- /* free any chunks still hanging around. */
+ /* Free any chunks still hanging around. */
RTAvlU32Destroy(&pGMM->pChunks, gmmR0TermDestroyChunk, pGMM);
- /* finally the instance data itself. */
+ /* Destroy the chunk locks. */
+ for (unsigned iMtx = 0; iMtx++ < RT_ELEMENTS(pGMM->aChunkMtx); iMtx++)
+ {
+ Assert(pGMM->aChunkMtx[iMtx].cUsers == 0);
+ RTSemFastMutexDestroy(pGMM->aChunkMtx[iMtx].hMtx);
+ pGMM->aChunkMtx[iMtx].hMtx = NIL_RTSEMFASTMUTEX;
+ }
+
+ /* Finally the instance data itself. */
RTMemFree(pGMM);
LogFlow(("GMMTerm: done\n"));
}
@@ -755,19 +831,19 @@ static DECLCALLBACK(int) gmmR0TermDestroyChunk(PAVLU32NODECORE pNode, void *pvGM
if (pChunk->cFree != (GMM_CHUNK_SIZE >> PAGE_SHIFT))
SUPR0Printf("GMMR0Term: %p/%#x: cFree=%d cPrivate=%d cShared=%d cMappings=%d\n", pChunk,
- pChunk->Core.Key, pChunk->cFree, pChunk->cPrivate, pChunk->cShared, pChunk->cMappings);
+ pChunk->Core.Key, pChunk->cFree, pChunk->cPrivate, pChunk->cShared, pChunk->cMappingsX);
- int rc = RTR0MemObjFree(pChunk->MemObj, true /* fFreeMappings */);
+ int rc = RTR0MemObjFree(pChunk->hMemObj, true /* fFreeMappings */);
if (RT_FAILURE(rc))
{
SUPR0Printf("GMMR0Term: %p/%#x: RTRMemObjFree(%p,true) -> %d (cMappings=%d)\n", pChunk,
- pChunk->Core.Key, pChunk->MemObj, rc, pChunk->cMappings);
+ pChunk->Core.Key, pChunk->hMemObj, rc, pChunk->cMappingsX);
AssertRC(rc);
}
- pChunk->MemObj = NIL_RTR0MEMOBJ;
+ pChunk->hMemObj = NIL_RTR0MEMOBJ;
- RTMemFree(pChunk->paMappings);
- pChunk->paMappings = NULL;
+ RTMemFree(pChunk->paMappingsX);
+ pChunk->paMappingsX = NULL;
RTMemFree(pChunk);
NOREF(pvGMM);
@@ -796,6 +872,252 @@ GMMR0DECL(void) GMMR0InitPerVMData(PGVM pGVM)
/**
+ * Acquires the GMM giant lock.
+ *
+ * @returns Assert status code from RTSemFastMutexRequest.
+ * @param pGMM Pointer to the GMM instance.
+ */
+static int gmmR0MutexAcquire(PGMM pGMM)
+{
+ ASMAtomicIncU32(&pGMM->cMtxContenders);
+ int rc = RTSemFastMutexRequest(pGMM->hMtx);
+ ASMAtomicDecU32(&pGMM->cMtxContenders);
+ AssertRC(rc);
+#ifdef VBOX_STRICT
+ pGMM->hMtxOwner = RTThreadNativeSelf();
+#endif
+ return rc;
+}
+
+
+/**
+ * Releases the GMM giant lock.
+ *
+ * @returns Assert status code from RTSemFastMutexRequest.
+ * @param pGMM Pointer to the GMM instance.
+ */
+static int gmmR0MutexRelease(PGMM pGMM)
+{
+#ifdef VBOX_STRICT
+ pGMM->hMtxOwner = NIL_RTNATIVETHREAD;
+#endif
+ int rc = RTSemFastMutexRelease(pGMM->hMtx);
+ AssertRC(rc);
+ return rc;
+}
+
+
+/**
+ * Yields the GMM giant lock if there is contention and a certain minimum time
+ * has elapsed since we took it.
+ *
+ * @returns @c true if the mutex was yielded, @c false if not.
+ * @param pGMM Pointer to the GMM instance.
+ * @param puLockNanoTS Where the lock acquisition time stamp is kept
+ * (in/out).
+ */
+static bool gmmR0MutexYield(PGMM pGMM, uint64_t *puLockNanoTS)
+{
+ /*
+ * If nobody is contending the mutex, don't bother checking the time.
+ */
+ if (ASMAtomicReadU32(&pGMM->cMtxContenders) == 0)
+ return false;
+
+ /*
+ * Don't yield if we haven't executed for at least 2 milliseconds.
+ */
+ uint64_t uNanoNow = RTTimeSystemNanoTS();
+ if (uNanoNow - *puLockNanoTS < UINT32_C(2000000))
+ return false;
+
+ /*
+ * Yield the mutex.
+ */
+#ifdef VBOX_STRICT
+ pGMM->hMtxOwner = NIL_RTNATIVETHREAD;
+#endif
+ ASMAtomicIncU32(&pGMM->cMtxContenders);
+ int rc1 = RTSemFastMutexRelease(pGMM->hMtx); AssertRC(rc1);
+
+ RTThreadYield();
+
+ int rc2 = RTSemFastMutexRequest(pGMM->hMtx); AssertRC(rc2);
+ *puLockNanoTS = RTTimeSystemNanoTS();
+ ASMAtomicDecU32(&pGMM->cMtxContenders);
+#ifdef VBOX_STRICT
+ pGMM->hMtxOwner = RTThreadNativeSelf();
+#endif
+
+ return true;
+}
+
+
+/**
+ * Acquires a chunk lock.
+ *
+ * The caller must own the giant lock.
+ *
+ * @returns Assert status code from RTSemFastMutexRequest.
+ * @param pMtxState The chunk mutex state info. (Avoids
+ * passing the same flags and stuff around
+ * for subsequent release and drop-giant
+ * calls.)
+ * @param pGMM Pointer to the GMM instance.
+ * @param pChunk Pointer to the chunk.
+ * @param fFlags Flags regarding the giant lock, GMMR0CHUNK_MTX_XXX.
+ */
+static int gmmR0ChunkMutexAcquire(PGMMR0CHUNKMTXSTATE pMtxState, PGMM pGMM, PGMMCHUNK pChunk, uint32_t fFlags)
+{
+ Assert(fFlags > GMMR0CHUNK_MTX_INVALID && fFlags < GMMR0CHUNK_MTX_END);
+ Assert(pGMM->hMtxOwner == RTThreadNativeSelf());
+
+ pMtxState->pGMM = pGMM;
+ pMtxState->fFlags = (uint8_t)fFlags;
+
+ /*
+ * Get the lock index and reference the lock.
+ */
+ Assert(pGMM->hMtxOwner == RTThreadNativeSelf());
+ uint32_t iChunkMtx = pChunk->iChunkMtx;
+ if (iChunkMtx == UINT8_MAX)
+ {
+ iChunkMtx = pGMM->iNextChunkMtx++;
+ iChunkMtx %= RT_ELEMENTS(pGMM->aChunkMtx);
+
+ /* Try get an unused one... */
+ if (pGMM->aChunkMtx[iChunkMtx].cUsers)
+ {
+ iChunkMtx = pGMM->iNextChunkMtx++;
+ iChunkMtx %= RT_ELEMENTS(pGMM->aChunkMtx);
+ if (pGMM->aChunkMtx[iChunkMtx].cUsers)
+ {
+ iChunkMtx = pGMM->iNextChunkMtx++;
+ iChunkMtx %= RT_ELEMENTS(pGMM->aChunkMtx);
+ if (pGMM->aChunkMtx[iChunkMtx].cUsers)
+ {
+ iChunkMtx = pGMM->iNextChunkMtx++;
+ iChunkMtx %= RT_ELEMENTS(pGMM->aChunkMtx);
+ }
+ }
+ }
+
+ pChunk->iChunkMtx = iChunkMtx;
+ }
+ AssertCompile(RT_ELEMENTS(pGMM->aChunkMtx) < UINT8_MAX);
+ pMtxState->iChunkMtx = (uint8_t)iChunkMtx;
+ ASMAtomicIncU32(&pGMM->aChunkMtx[iChunkMtx].cUsers);
+
+ /*
+ * Drop the giant?
+ */
+ if (fFlags != GMMR0CHUNK_MTX_KEEP_GIANT)
+ {
+ /** @todo GMM life cycle cleanup (we may race someone
+ * destroying and cleaning up GMM)? */
+ gmmR0MutexRelease(pGMM);
+ }
+
+ /*
+ * Take the chunk mutex.
+ */
+ int rc = RTSemFastMutexRequest(pGMM->aChunkMtx[iChunkMtx].hMtx);
+ AssertRC(rc);
+ return rc;
+}
+
+
+/**
+ * Releases the GMM giant lock.
+ *
+ * @returns Assert status code from RTSemFastMutexRequest.
+ * @param pGMM Pointer to the GMM instance.
+ * @param pChunk Pointer to the chunk if it's still
+ * alive, NULL if it isn't. This is used to deassociate
+ * the chunk from the mutex on the way out so a new one
+ * can be selected next time, thus avoiding contented
+ * mutexes.
+ */
+static int gmmR0ChunkMutexRelease(PGMMR0CHUNKMTXSTATE pMtxState, PGMMCHUNK pChunk)
+{
+ PGMM pGMM = pMtxState->pGMM;
+
+ /*
+ * Release the chunk mutex and reacquire the giant if requested.
+ */
+ int rc = RTSemFastMutexRelease(pGMM->aChunkMtx[pMtxState->iChunkMtx].hMtx);
+ AssertRC(rc);
+ if (pMtxState->fFlags == GMMR0CHUNK_MTX_RETAKE_GIANT)
+ rc = gmmR0MutexAcquire(pGMM);
+ else
+ Assert((pMtxState->fFlags != GMMR0CHUNK_MTX_DROP_GIANT) == (pGMM->hMtxOwner == RTThreadNativeSelf()));
+
+ /*
+ * Drop the chunk mutex user reference and deassociate it from the chunk
+ * when possible.
+ */
+ if ( ASMAtomicDecU32(&pGMM->aChunkMtx[pMtxState->iChunkMtx].cUsers) == 0
+ && pChunk
+ && RT_SUCCESS(rc) )
+ {
+ if (pMtxState->fFlags != GMMR0CHUNK_MTX_DROP_GIANT)
+ pChunk->iChunkMtx = UINT8_MAX;
+ else
+ {
+ rc = gmmR0MutexAcquire(pGMM);
+ if (RT_SUCCESS(rc))
+ {
+ if (pGMM->aChunkMtx[pMtxState->iChunkMtx].cUsers == 0)
+ pChunk->iChunkMtx = UINT8_MAX;
+ rc = gmmR0MutexRelease(pGMM);
+ }
+ }
+ }
+
+ pMtxState->pGMM = NULL;
+ return rc;
+}
+
+
+/**
+ * Drops the giant GMM lock we kept in gmmR0ChunkMutexAcquire while keeping the
+ * chunk locked.
+ *
+ * This only works if gmmR0ChunkMutexAcquire was called with
+ * GMMR0CHUNK_MTX_KEEP_GIANT. gmmR0ChunkMutexRelease will retake the giant
+ * mutex, i.e. behave as if GMMR0CHUNK_MTX_RETAKE_GIANT was used.
+ *
+ * @returns VBox status code (assuming success is ok).
+ * @param pMtxState Pointer to the chunk mutex state.
+ */
+static int gmmR0ChunkMutexDropGiant(PGMMR0CHUNKMTXSTATE pMtxState)
+{
+ AssertReturn(pMtxState->fFlags == GMMR0CHUNK_MTX_KEEP_GIANT, VERR_INTERNAL_ERROR_2);
+ Assert(pMtxState->pGMM->hMtxOwner == RTThreadNativeSelf());
+ pMtxState->fFlags = GMMR0CHUNK_MTX_RETAKE_GIANT;
+ /** @todo GMM life cycle cleanup (we may race someone
+ * destroying and cleaning up GMM)? */
+ return gmmR0MutexRelease(pMtxState->pGMM);
+}
+
+
+/**
+ * For experimenting with NUMA affinity and such.
+ *
+ * @returns The current NUMA Node ID.
+ */
+static uint16_t gmmR0GetCurrentNumaNodeId(void)
+{
+#if 1
+ return GMM_CHUNK_NUMA_ID_UNKNOWN;
+#else
+ return RTMpCpuId() / 16;
+#endif
+}
+
+
+
+/**
* Cleans up when a VM is terminating.
*
* @param pGVM Pointer to the Global VM structure.
@@ -807,15 +1129,17 @@ GMMR0DECL(void) GMMR0CleanupVM(PGVM pGVM)
PGMM pGMM;
GMM_GET_VALID_INSTANCE_VOID(pGMM);
- int rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
- GMM_CHECK_SANITY_UPON_ENTERING(pGMM);
-
#ifdef VBOX_WITH_PAGE_SHARING
- /* Clean up all registered shared modules. */
- RTAvlGCPtrDestroy(&pGVM->gmm.s.pSharedModuleTree, gmmR0CleanupSharedModule, pGVM);
+ /*
+ * Clean up all registered shared modules first.
+ */
+ gmmR0SharedModuleCleanup(pGMM, pGVM);
#endif
+ gmmR0MutexAcquire(pGMM);
+ uint64_t uLockNanoTS = RTTimeSystemNanoTS();
+ GMM_CHECK_SANITY_UPON_ENTERING(pGMM);
+
/*
* The policy is 'INVALID' until the initial reservation
* request has been serviced.
@@ -832,89 +1156,118 @@ GMMR0DECL(void) GMMR0CleanupVM(PGVM pGVM)
*/
Assert(pGMM->cRegisteredVMs);
pGMM->cRegisteredVMs--;
-#if 0 /* disabled so it won't hide bugs. */
- if (!pGMM->cRegisteredVMs)
- {
- RTAvlU32Destroy(&pGMM->pChunks, gmmR0CleanupVMDestroyChunk, pGMM);
- for (unsigned i = 0; i < RT_ELEMENTS(pGMM->ChunkTLB.aEntries); i++)
+ /*
+ * Walk the entire pool looking for pages that belong to this VM
+ * and leftover mappings. (This'll only catch private pages,
+ * shared pages will be 'left behind'.)
+ */
+ uint64_t cPrivatePages = pGVM->gmm.s.cPrivatePages; /* save */
+
+ unsigned iCountDown = 64;
+ bool fRedoFromStart;
+ PGMMCHUNK pChunk;
+ do
+ {
+ fRedoFromStart = false;
+ RTListForEachReverse(&pGMM->ChunkList, pChunk, GMMCHUNK, ListNode)
{
- pGMM->ChunkTLB.aEntries[i].idChunk = NIL_GMM_CHUNKID;
- pGMM->ChunkTLB.aEntries[i].pChunk = NULL;
+ uint32_t const cFreeChunksOld = pGMM->cFreedChunks;
+ if (gmmR0CleanupVMScanChunk(pGMM, pGVM, pChunk))
+ {
+ /* We left the giant mutex, so reset the yield counters. */
+ uLockNanoTS = RTTimeSystemNanoTS();
+ iCountDown = 64;
+ }
+ else
+ {
+ /* Didn't leave it, so do normal yielding. */
+ if (!iCountDown)
+ gmmR0MutexYield(pGMM, &uLockNanoTS);
+ else
+ iCountDown--;
+ }
+ if (pGMM->cFreedChunks != cFreeChunksOld)
+ break;
}
+ } while (fRedoFromStart);
- memset(&pGMM->Private, 0, sizeof(pGMM->Private));
- memset(&pGMM->Shared, 0, sizeof(pGMM->Shared));
+ if (pGVM->gmm.s.cPrivatePages)
+ SUPR0Printf("GMMR0CleanupVM: hGVM=%#x has %#x private pages that cannot be found!\n", pGVM->hSelf, pGVM->gmm.s.cPrivatePages);
- memset(&pGMM->bmChunkId[0], 0, sizeof(pGMM->bmChunkId));
- ASMBitSet(&pGMM->bmChunkId[0], NIL_GMM_CHUNKID);
+ pGMM->cAllocatedPages -= cPrivatePages;
- pGMM->cReservedPages = 0;
- pGMM->cOverCommittedPages = 0;
- pGMM->cAllocatedPages = 0;
- pGMM->cSharedPages = 0;
- pGMM->cDuplicatePages = 0;
- pGMM->cLeftBehindSharedPages = 0;
- pGMM->cChunks = 0;
- pGMM->cBalloonedPages = 0;
- }
- else
-#endif
+ /*
+ * Free empty chunks.
+ */
+ PGMMCHUNKFREESET pPrivateSet = pGMM->fBoundMemoryMode ? &pGVM->gmm.s.Private : &pGMM->PrivateX;
+ do
{
- /*
- * Walk the entire pool looking for pages that belong to this VM
- * and left over mappings. (This'll only catch private pages, shared
- * pages will be 'left behind'.)
- */
- /** @todo this might be kind of expensive with a lot of VMs and
- * memory hanging around... */
- uint64_t cPrivatePages = pGVM->gmm.s.cPrivatePages; /* save */
- RTAvlU32DoWithAll(&pGMM->pChunks, true /* fFromLeft */, gmmR0CleanupVMScanChunk, pGVM);
- if (pGVM->gmm.s.cPrivatePages)
- SUPR0Printf("GMMR0CleanupVM: hGVM=%#x has %#x private pages that cannot be found!\n", pGVM->hSelf, pGVM->gmm.s.cPrivatePages);
- pGMM->cAllocatedPages -= cPrivatePages;
-
- /* free empty chunks. */
- if (cPrivatePages)
+ fRedoFromStart = false;
+ iCountDown = 10240;
+ pChunk = pPrivateSet->apLists[GMM_CHUNK_FREE_SET_UNUSED_LIST];
+ while (pChunk)
{
- PGMMCHUNK pCur = pGMM->Private.apLists[RT_ELEMENTS(pGMM->Private.apLists) - 1];
- while (pCur)
+ PGMMCHUNK pNext = pChunk->pFreeNext;
+ Assert(pChunk->cFree == GMM_CHUNK_NUM_PAGES);
+ if ( !pGMM->fBoundMemoryMode
+ || pChunk->hGVM == pGVM->hSelf)
{
- PGMMCHUNK pNext = pCur->pFreeNext;
- if ( pCur->cFree == GMM_CHUNK_NUM_PAGES
- && ( !pGMM->fBoundMemoryMode
- || pCur->hGVM == pGVM->hSelf))
- gmmR0FreeChunk(pGMM, pGVM, pCur);
- pCur = pNext;
+ uint64_t const idGenerationOld = pPrivateSet->idGeneration;
+ if (gmmR0FreeChunk(pGMM, pGVM, pChunk, true /*fRelaxedSem*/))
+ {
+ /* We've left the giant mutex, restart? (+1 for our unlink) */
+ fRedoFromStart = pPrivateSet->idGeneration != idGenerationOld + 1;
+ if (fRedoFromStart)
+ break;
+ uLockNanoTS = RTTimeSystemNanoTS();
+ iCountDown = 10240;
+ }
}
- }
- /* account for shared pages that weren't freed. */
- if (pGVM->gmm.s.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;
+ /* Advance and maybe yield the lock. */
+ pChunk = pNext;
+ if (--iCountDown == 0)
+ {
+ uint64_t const idGenerationOld = pPrivateSet->idGeneration;
+ fRedoFromStart = gmmR0MutexYield(pGMM, &uLockNanoTS)
+ && pPrivateSet->idGeneration != idGenerationOld;
+ if (fRedoFromStart)
+ break;
+ iCountDown = 10240;
+ }
}
+ } while (fRedoFromStart);
- /* Clean up balloon statistics in case the VM process crashed. */
- Assert(pGMM->cBalloonedPages >= pGVM->gmm.s.cBalloonedPages);
- pGMM->cBalloonedPages -= pGVM->gmm.s.cBalloonedPages;
+ /*
+ * Account for shared pages that weren't freed.
+ */
+ if (pGVM->gmm.s.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;
+ }
- /*
- * 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)
- {
- case GMMOCPOLICY_NO_OC:
- break;
- default:
- /** @todo Update GMM->cOverCommittedPages */
- break;
- }
+ /*
+ * Clean up balloon statistics in case the VM process crashed.
+ */
+ Assert(pGMM->cBalloonedPages >= pGVM->gmm.s.cBalloonedPages);
+ pGMM->cBalloonedPages -= pGVM->gmm.s.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)
+ {
+ case GMMOCPOLICY_NO_OC:
+ break;
+ default:
+ /** @todo Update GMM->cOverCommittedPages */
+ break;
}
}
@@ -924,24 +1277,25 @@ GMMR0DECL(void) GMMR0CleanupVM(PGVM pGVM)
pGVM->gmm.s.fMayAllocate = false;
GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
LogFlow(("GMMR0CleanupVM: returns\n"));
}
/**
- * RTAvlU32DoWithAll callback.
+ * Scan one chunk for private pages belonging to the specified VM.
*
- * @returns 0
- * @param pNode The node to search.
- * @param pvGVM Pointer to the shared VM structure.
+ * @note This function may drop the gian mutex!
+ *
+ * @returns @c true if we've temporarily dropped the giant mutex, @c false if
+ * we didn't.
+ * @param pGMM Pointer to the GMM instance.
+ * @param pGVM The global VM handle.
+ * @param pChunk The chunk to scan.
*/
-static DECLCALLBACK(int) gmmR0CleanupVMScanChunk(PAVLU32NODECORE pNode, void *pvGVM)
+static bool gmmR0CleanupVMScanChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk)
{
- PGMMCHUNK pChunk = (PGMMCHUNK)pNode;
- PGVM pGVM = (PGVM)pvGVM;
-
/*
* Look for pages belonging to the VM.
* (Perform some internal checks while we're scanning.)
@@ -987,7 +1341,7 @@ static DECLCALLBACK(int) gmmR0CleanupVMScanChunk(PAVLU32NODECORE pNode, void *pv
else
cShared++;
- gmmR0LinkChunk(pChunk, pChunk->cShared ? &g_pGMM->Shared : &g_pGMM->Private);
+ gmmR0SelectSetAndLinkChunk(pGMM, pGVM, pChunk);
/*
* Did it add up?
@@ -1005,30 +1359,6 @@ static DECLCALLBACK(int) gmmR0CleanupVMScanChunk(PAVLU32NODECORE pNode, void *pv
}
/*
- * Look for the mapping belonging to the terminating VM.
- */
- for (unsigned i = 0; i < pChunk->cMappings; i++)
- if (pChunk->paMappings[i].pGVM == pGVM)
- {
- RTR0MEMOBJ MemObj = pChunk->paMappings[i].MapObj;
-
- pChunk->cMappings--;
- if (i < pChunk->cMappings)
- pChunk->paMappings[i] = pChunk->paMappings[pChunk->cMappings];
- pChunk->paMappings[pChunk->cMappings].pGVM = NULL;
- pChunk->paMappings[pChunk->cMappings].MapObj = NIL_RTR0MEMOBJ;
-
- int rc = RTR0MemObjFree(MemObj, false /* fFreeMappings (NA) */);
- if (RT_FAILURE(rc))
- {
- SUPR0Printf("gmmR0CleanupVMScanChunk: %p/%#x: mapping #%x: RTRMemObjFree(%p,false) -> %d \n",
- pChunk, pChunk->Core.Key, i, MemObj, rc);
- AssertRC(rc);
- }
- break;
- }
-
- /*
* If not in bound memory mode, we should reset the hGVM field
* if it has our handle in it.
*/
@@ -1044,54 +1374,45 @@ static DECLCALLBACK(int) gmmR0CleanupVMScanChunk(PAVLU32NODECORE pNode, void *pv
gmmR0UnlinkChunk(pChunk);
pChunk->cFree = GMM_CHUNK_NUM_PAGES;
- gmmR0LinkChunk(pChunk, pChunk->cShared ? &g_pGMM->Shared : &g_pGMM->Private);
+ gmmR0SelectSetAndLinkChunk(pGMM, pGVM, pChunk);
}
}
- return 0;
-}
+ /*
+ * Look for a mapping belonging to the terminating VM.
+ */
+ GMMR0CHUNKMTXSTATE MtxState;
+ gmmR0ChunkMutexAcquire(&MtxState, pGMM, pChunk, GMMR0CHUNK_MTX_KEEP_GIANT);
+ unsigned cMappings = pChunk->cMappingsX;
+ for (unsigned i = 0; i < cMappings; i++)
+ if (pChunk->paMappingsX[i].pGVM == pGVM)
+ {
+ gmmR0ChunkMutexDropGiant(&MtxState);
+ RTR0MEMOBJ hMemObj = pChunk->paMappingsX[i].hMapObj;
-/**
- * RTAvlU32Destroy callback for GMMR0CleanupVM.
- *
- * @returns 0
- * @param pNode The node (allocation chunk) to destroy.
- * @param pvGVM Pointer to the shared VM structure.
- */
-/*static*/ DECLCALLBACK(int) gmmR0CleanupVMDestroyChunk(PAVLU32NODECORE pNode, void *pvGVM)
-{
- PGMMCHUNK pChunk = (PGMMCHUNK)pNode;
- PGVM pGVM = (PGVM)pvGVM;
+ cMappings--;
+ if (i < cMappings)
+ pChunk->paMappingsX[i] = pChunk->paMappingsX[cMappings];
+ pChunk->paMappingsX[cMappings].pGVM = NULL;
+ pChunk->paMappingsX[cMappings].hMapObj = NIL_RTR0MEMOBJ;
+ Assert(pChunk->cMappingsX - 1U == cMappings);
+ pChunk->cMappingsX = cMappings;
- for (unsigned i = 0; i < pChunk->cMappings; i++)
- {
- if (pChunk->paMappings[i].pGVM != pGVM)
- SUPR0Printf("gmmR0CleanupVMDestroyChunk: %p/%#x: mapping #%x: pGVM=%p exepcted %p\n", pChunk,
- pChunk->Core.Key, i, pChunk->paMappings[i].pGVM, pGVM);
- int rc = RTR0MemObjFree(pChunk->paMappings[i].MapObj, false /* fFreeMappings (NA) */);
- if (RT_FAILURE(rc))
- {
- SUPR0Printf("gmmR0CleanupVMDestroyChunk: %p/%#x: mapping #%x: RTRMemObjFree(%p,false) -> %d \n", pChunk,
- pChunk->Core.Key, i, pChunk->paMappings[i].MapObj, rc);
- AssertRC(rc);
- }
- }
-
- int rc = RTR0MemObjFree(pChunk->MemObj, true /* fFreeMappings */);
- if (RT_FAILURE(rc))
- {
- SUPR0Printf("gmmR0CleanupVMDestroyChunk: %p/%#x: RTRMemObjFree(%p,true) -> %d (cMappings=%d)\n", pChunk,
- pChunk->Core.Key, pChunk->MemObj, rc, pChunk->cMappings);
- AssertRC(rc);
- }
- pChunk->MemObj = NIL_RTR0MEMOBJ;
+ int rc = RTR0MemObjFree(hMemObj, false /* fFreeMappings (NA) */);
+ if (RT_FAILURE(rc))
+ {
+ SUPR0Printf("gmmR0CleanupVMScanChunk: %p/%#x: mapping #%x: RTRMemObjFree(%p,false) -> %d \n",
+ pChunk, pChunk->Core.Key, i, hMemObj, rc);
+ AssertRC(rc);
+ }
- RTMemFree(pChunk->paMappings);
- pChunk->paMappings = NULL;
+ gmmR0ChunkMutexRelease(&MtxState, pChunk);
+ return true;
+ }
- RTMemFree(pChunk);
- return 0;
+ gmmR0ChunkMutexRelease(&MtxState, pChunk);
+ return false;
}
@@ -1144,8 +1465,7 @@ GMMR0DECL(int) GMMR0InitialReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePag
AssertReturn(enmPolicy > GMMOCPOLICY_INVALID && enmPolicy < GMMOCPOLICY_END, VERR_INVALID_PARAMETER);
AssertReturn(enmPriority > GMMPRIORITY_INVALID && enmPriority < GMMPRIORITY_END, VERR_INVALID_PARAMETER);
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
if ( !pGVM->gmm.s.Reserved.cBasePages
@@ -1178,7 +1498,7 @@ GMMR0DECL(int) GMMR0InitialReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePag
}
else
rc = VERR_INTERNAL_ERROR_5;
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
LogFlow(("GMMR0InitialReservation: returns %Rrc\n", rc));
return rc;
}
@@ -1240,8 +1560,7 @@ GMMR0DECL(int) GMMR0UpdateReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePage
AssertReturn(cShadowPages, VERR_INVALID_PARAMETER);
AssertReturn(cFixedPages, VERR_INVALID_PARAMETER);
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
if ( pGVM->gmm.s.Reserved.cBasePages
@@ -1273,7 +1592,7 @@ GMMR0DECL(int) GMMR0UpdateReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePage
}
else
rc = VERR_INTERNAL_ERROR_5;
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
LogFlow(("GMMR0UpdateReservation: returns %Rrc\n", rc));
return rc;
}
@@ -1352,8 +1671,8 @@ static uint32_t gmmR0SanityCheck(PGMM pGMM, const char *pszFunction, unsigned uL
{
uint32_t cErrors = 0;
- cErrors += gmmR0SanityCheckSet(pGMM, &pGMM->Private, "private", pszFunction, uLineNo);
- cErrors += gmmR0SanityCheckSet(pGMM, &pGMM->Shared, "shared", pszFunction, uLineNo);
+ cErrors += gmmR0SanityCheckSet(pGMM, &pGMM->PrivateX, "private", pszFunction, uLineNo);
+ cErrors += gmmR0SanityCheckSet(pGMM, &pGMM->Shared, "shared", pszFunction, uLineNo);
/** @todo add more sanity checks. */
return cErrors;
@@ -1421,6 +1740,37 @@ DECLINLINE(PGMMPAGE) gmmR0GetPage(PGMM pGMM, uint32_t idPage)
/**
+ * Gets the host physical address for a page given by it's ID.
+ *
+ * @returns The host physical address or NIL_RTHCPHYS.
+ * @param pGMM Pointer to the GMM instance.
+ * @param idPage The ID of the page to find.
+ */
+DECLINLINE(RTHCPHYS) gmmR0GetPageHCPhys(PGMM pGMM, uint32_t idPage)
+{
+ PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, idPage >> GMM_CHUNKID_SHIFT);
+ if (RT_LIKELY(pChunk))
+ return RTR0MemObjGetPagePhysAddr(pChunk->hMemObj, idPage & GMM_PAGEID_IDX_MASK);
+ return NIL_RTHCPHYS;
+}
+
+
+/**
+ * Selects the appropriate free list given the number of free pages.
+ *
+ * @returns Free list index.
+ * @param cFree The number of free pages in the chunk.
+ */
+DECLINLINE(unsigned) gmmR0SelectFreeSetList(unsigned cFree)
+{
+ unsigned iList = cFree >> GMM_CHUNK_FREE_SET_SHIFT;
+ AssertMsg(iList < RT_SIZEOFMEMB(GMMCHUNKFREESET, apLists) / RT_SIZEOFMEMB(GMMCHUNKFREESET, apLists[0]),
+ ("%d (%u)\n", iList, cFree));
+ return iList;
+}
+
+
+/**
* Unlinks the chunk from the free list it's currently on (if any).
*
* @param pChunk The allocation chunk.
@@ -1431,13 +1781,14 @@ DECLINLINE(void) gmmR0UnlinkChunk(PGMMCHUNK pChunk)
if (RT_LIKELY(pSet))
{
pSet->cFreePages -= pChunk->cFree;
+ pSet->idGeneration++;
PGMMCHUNK pPrev = pChunk->pFreePrev;
PGMMCHUNK pNext = pChunk->pFreeNext;
if (pPrev)
pPrev->pFreeNext = pNext;
else
- pSet->apLists[(pChunk->cFree - 1) >> GMM_CHUNK_FREE_SET_SHIFT] = pNext;
+ pSet->apLists[gmmR0SelectFreeSetList(pChunk->cFree)] = pNext;
if (pNext)
pNext->pFreePrev = pPrev;
@@ -1472,18 +1823,39 @@ DECLINLINE(void) gmmR0LinkChunk(PGMMCHUNK pChunk, PGMMCHUNKFREESET pSet)
{
pChunk->pSet = pSet;
pChunk->pFreePrev = NULL;
- unsigned iList = (pChunk->cFree - 1) >> GMM_CHUNK_FREE_SET_SHIFT;
+ unsigned const iList = gmmR0SelectFreeSetList(pChunk->cFree);
pChunk->pFreeNext = pSet->apLists[iList];
if (pChunk->pFreeNext)
pChunk->pFreeNext->pFreePrev = pChunk;
pSet->apLists[iList] = pChunk;
pSet->cFreePages += pChunk->cFree;
+ pSet->idGeneration++;
}
}
/**
+ * Links the chunk onto the appropriate free list in the specified free set.
+ *
+ * If no free entries, it's not linked into any list.
+ *
+ * @param pChunk The allocation chunk.
+ */
+DECLINLINE(void) gmmR0SelectSetAndLinkChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk)
+{
+ PGMMCHUNKFREESET pSet;
+ if (pGMM->fBoundMemoryMode)
+ pSet = &pGVM->gmm.s.Private;
+ else if (pChunk->cShared)
+ pSet = &pGMM->Shared;
+ else
+ pSet = &pGMM->PrivateX;
+ gmmR0LinkChunk(pChunk, pSet);
+}
+
+
+/**
* Frees a Chunk ID.
*
* @param pGMM Pointer to the GMM instance.
@@ -1512,7 +1884,7 @@ static uint32_t gmmR0AllocateChunkId(PGMM pGMM)
* Try the next sequential one.
*/
int32_t idChunk = ++pGMM->idChunkPrev;
-#if 0 /* test the fallback first */
+#if 0 /** @todo enable this code */
if ( idChunk <= GMM_CHUNKID_LAST
&& idChunk > NIL_GMM_CHUNKID
&& !ASMAtomicBitTestAndSet(&pVMM->bmChunkId[0], idChunk))
@@ -1546,23 +1918,103 @@ static uint32_t gmmR0AllocateChunkId(PGMM pGMM)
/**
+ * Allocates one private page.
+ *
+ * Worker for gmmR0AllocatePages.
+ *
+ * @param pGMM Pointer to the GMM instance data.
+ * @param hGVM The GVM handle of the VM requesting memory.
+ * @param pChunk The chunk to allocate it from.
+ * @param pPageDesc The page descriptor.
+ */
+static void gmmR0AllocatePage(PGMM pGMM, uint32_t hGVM, PGMMCHUNK pChunk, PGMMPAGEDESC pPageDesc)
+{
+ /* update the chunk stats. */
+ if (pChunk->hGVM == NIL_GVM_HANDLE)
+ pChunk->hGVM = hGVM;
+ Assert(pChunk->cFree);
+ pChunk->cFree--;
+ pChunk->cPrivate++;
+
+ /* unlink the first free page. */
+ const uint32_t iPage = pChunk->iFreeHead;
+ AssertReleaseMsg(iPage < RT_ELEMENTS(pChunk->aPages), ("%d\n", iPage));
+ PGMMPAGE pPage = &pChunk->aPages[iPage];
+ Assert(GMM_PAGE_IS_FREE(pPage));
+ pChunk->iFreeHead = pPage->Free.iNext;
+ Log3(("A pPage=%p iPage=%#x/%#x u2State=%d iFreeHead=%#x iNext=%#x\n",
+ pPage, iPage, (pChunk->Core.Key << GMM_CHUNKID_SHIFT) | iPage,
+ pPage->Common.u2State, pChunk->iFreeHead, pPage->Free.iNext));
+
+ /* make the page private. */
+ pPage->u = 0;
+ AssertCompile(GMM_PAGE_STATE_PRIVATE == 0);
+ pPage->Private.hGVM = hGVM;
+ AssertCompile(NIL_RTHCPHYS >= GMM_GCPHYS_LAST);
+ AssertCompile(GMM_GCPHYS_UNSHAREABLE >= GMM_GCPHYS_LAST);
+ if (pPageDesc->HCPhysGCPhys <= GMM_GCPHYS_LAST)
+ pPage->Private.pfn = pPageDesc->HCPhysGCPhys >> PAGE_SHIFT;
+ else
+ pPage->Private.pfn = GMM_PAGE_PFN_UNSHAREABLE; /* unshareable / unassigned - same thing. */
+
+ /* update the page descriptor. */
+ pPageDesc->HCPhysGCPhys = RTR0MemObjGetPagePhysAddr(pChunk->hMemObj, iPage);
+ Assert(pPageDesc->HCPhysGCPhys != NIL_RTHCPHYS);
+ pPageDesc->idPage = (pChunk->Core.Key << GMM_CHUNKID_SHIFT) | iPage;
+ pPageDesc->idSharedPage = NIL_GMM_PAGEID;
+}
+
+
+/**
+ * Picks the free pages from a chunk.
+ *
+ * @returns The new page descriptor table index.
+ * @param pGMM Pointer to the GMM instance data.
+ * @param hGVM The VM handle.
+ * @param pChunk The chunk.
+ * @param iPage The current page descriptor table index.
+ * @param cPages The total number of pages to allocate.
+ * @param paPages The page descriptor table (input + ouput).
+ */
+static uint32_t gmmR0AllocatePagesFromChunk(PGMM pGMM, uint16_t const hGVM, PGMMCHUNK pChunk, uint32_t iPage, uint32_t cPages,
+ PGMMPAGEDESC paPages)
+{
+ PGMMCHUNKFREESET pSet = pChunk->pSet; Assert(pSet);
+ gmmR0UnlinkChunk(pChunk);
+
+ for (; pChunk->cFree && iPage < cPages; iPage++)
+ gmmR0AllocatePage(pGMM, hGVM, pChunk, &paPages[iPage]);
+
+ gmmR0LinkChunk(pChunk, pSet);
+ return iPage;
+}
+
+
+/**
* Registers a new chunk of memory.
*
- * This is called by both gmmR0AllocateOneChunk and GMMR0SeedChunk. The caller
- * must own the global lock.
+ * This is called by both gmmR0AllocateOneChunk and GMMR0SeedChunk.
*
- * @returns VBox status code.
+ * @returns VBox status code. On success, the giant GMM lock will be held, the
+ * caller must release it (ugly).
* @param pGMM Pointer to the GMM instance.
* @param pSet Pointer to the set.
* @param MemObj The memory object for the chunk.
* @param hGVM The affinity of the chunk. NIL_GVM_HANDLE for no
* affinity.
- * @param enmChunkType Chunk type (continuous or non-continuous)
- * @param ppChunk Chunk address (out)
+ * @param fChunkFlags The chunk flags, GMM_CHUNK_FLAGS_XXX.
+ * @param ppChunk Chunk address (out). Optional.
+ *
+ * @remarks The caller must not own the giant GMM mutex.
+ * The giant GMM mutex will be acquired and returned acquired in
+ * the success path. On failure, no locks will be held.
*/
-static int gmmR0RegisterChunk(PGMM pGMM, PGMMCHUNKFREESET pSet, RTR0MEMOBJ MemObj, uint16_t hGVM, GMMCHUNKTYPE enmChunkType, PGMMCHUNK *ppChunk = NULL)
+static int gmmR0RegisterChunk(PGMM pGMM, PGMMCHUNKFREESET pSet, RTR0MEMOBJ MemObj, uint16_t hGVM, uint16_t fChunkFlags,
+ PGMMCHUNK *ppChunk)
{
+ Assert(pGMM->hMtxOwner != RTThreadNativeSelf());
Assert(hGVM != NIL_GVM_HANDLE || pGMM->fBoundMemoryMode);
+ Assert(fChunkFlags == 0 || fChunkFlags == GMM_CHUNK_FLAGS_LARGE_PAGE);
int rc;
PGMMCHUNK pChunk = (PGMMCHUNK)RTMemAllocZ(sizeof(*pChunk));
@@ -1571,46 +2023,53 @@ static int gmmR0RegisterChunk(PGMM pGMM, PGMMCHUNKFREESET pSet, RTR0MEMOBJ MemOb
/*
* Initialize it.
*/
- pChunk->MemObj = MemObj;
- pChunk->cFree = GMM_CHUNK_NUM_PAGES;
- pChunk->hGVM = hGVM;
- pChunk->iFreeHead = 0;
- pChunk->enmType = enmChunkType;
+ pChunk->hMemObj = MemObj;
+ pChunk->cFree = GMM_CHUNK_NUM_PAGES;
+ pChunk->hGVM = hGVM;
+ /*pChunk->iFreeHead = 0;*/
+ pChunk->idNumaNode = gmmR0GetCurrentNumaNodeId();
+ pChunk->iChunkMtx = UINT8_MAX;
+ pChunk->fFlags = fChunkFlags;
for (unsigned iPage = 0; iPage < RT_ELEMENTS(pChunk->aPages) - 1; iPage++)
{
pChunk->aPages[iPage].Free.u2State = GMM_PAGE_STATE_FREE;
pChunk->aPages[iPage].Free.iNext = iPage + 1;
}
pChunk->aPages[RT_ELEMENTS(pChunk->aPages) - 1].Free.u2State = GMM_PAGE_STATE_FREE;
- pChunk->aPages[RT_ELEMENTS(pChunk->aPages) - 1].Free.iNext = UINT16_MAX;
+ pChunk->aPages[RT_ELEMENTS(pChunk->aPages) - 1].Free.iNext = UINT16_MAX;
/*
* Allocate a Chunk ID and insert it into the tree.
* This has to be done behind the mutex of course.
*/
- if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
+ rc = gmmR0MutexAcquire(pGMM);
+ if (RT_SUCCESS(rc))
{
- pChunk->Core.Key = gmmR0AllocateChunkId(pGMM);
- if ( pChunk->Core.Key != NIL_GMM_CHUNKID
- && pChunk->Core.Key <= GMM_CHUNKID_LAST
- && RTAvlU32Insert(&pGMM->pChunks, &pChunk->Core))
+ if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
- pGMM->cChunks++;
- gmmR0LinkChunk(pChunk, pSet);
- LogFlow(("gmmR0RegisterChunk: pChunk=%p id=%#x cChunks=%d\n", pChunk, pChunk->Core.Key, pGMM->cChunks));
-
- if (ppChunk)
- *ppChunk = pChunk;
+ pChunk->Core.Key = gmmR0AllocateChunkId(pGMM);
+ if ( pChunk->Core.Key != NIL_GMM_CHUNKID
+ && pChunk->Core.Key <= GMM_CHUNKID_LAST
+ && RTAvlU32Insert(&pGMM->pChunks, &pChunk->Core))
+ {
+ pGMM->cChunks++;
+ RTListAppend(&pGMM->ChunkList, &pChunk->ListNode);
+ gmmR0LinkChunk(pChunk, pSet);
+ LogFlow(("gmmR0RegisterChunk: pChunk=%p id=%#x cChunks=%d\n", pChunk, pChunk->Core.Key, pGMM->cChunks));
+
+ if (ppChunk)
+ *ppChunk = pChunk;
+ GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
+ return VINF_SUCCESS;
+ }
- GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
- return VINF_SUCCESS;
+ /* bail out */
+ rc = VERR_INTERNAL_ERROR;
}
-
- /* bail out */
- rc = VERR_INTERNAL_ERROR;
+ else
+ rc = VERR_INTERNAL_ERROR_5;
+ gmmR0MutexRelease(pGMM);
}
- else
- rc = VERR_INTERNAL_ERROR_5;
RTMemFree(pChunk);
}
@@ -1621,185 +2080,278 @@ static int gmmR0RegisterChunk(PGMM pGMM, PGMMCHUNKFREESET pSet, RTR0MEMOBJ MemOb
/**
- * Allocate one new chunk and add it to the specified free set.
+ * Allocate a new chunk, immediately pick the requested pages from it, and adds
+ * what's remaining to the specified free set.
*
- * @returns VBox status code.
- * @param pGMM Pointer to the GMM instance.
- * @param pSet Pointer to the set.
- * @param hGVM The affinity of the new chunk.
- * @param enmChunkType Chunk type (continuous or non-continuous)
- * @param ppChunk Chunk address (out)
+ * @note This will leave the giant mutex while allocating the new chunk!
*
- * @remarks Called without owning the mutex.
+ * @returns VBox status code.
+ * @param pGMM Pointer to the GMM instance data.
+ * @param pGVM Pointer to the kernel-only VM instace data.
+ * @param pSet Pointer to the free set.
+ * @param cPages The number of pages requested.
+ * @param paPages The page descriptor table (input + output).
+ * @param piPage The pointer to the page descriptor table index
+ * variable. This will be updated.
*/
-static int gmmR0AllocateOneChunk(PGMM pGMM, PGMMCHUNKFREESET pSet, uint16_t hGVM, GMMCHUNKTYPE enmChunkType, PGMMCHUNK *ppChunk = NULL)
+static int gmmR0AllocateChunkNew(PGMM pGMM, PGVM pGVM, PGMMCHUNKFREESET pSet, uint32_t cPages,
+ PGMMPAGEDESC paPages, uint32_t *piPage)
{
- /*
- * Allocate the memory.
- */
- RTR0MEMOBJ MemObj;
- int rc;
-
- AssertCompile(GMM_CHUNK_SIZE == _2M);
- AssertReturn(enmChunkType == GMMCHUNKTYPE_NON_CONTINUOUS || enmChunkType == GMMCHUNKTYPE_CONTINUOUS, VERR_INVALID_PARAMETER);
-
- /* Leave the lock temporarily as the allocation might take long. */
- RTSemFastMutexRelease(pGMM->Mtx);
- if (enmChunkType == GMMCHUNKTYPE_NON_CONTINUOUS)
- rc = RTR0MemObjAllocPhysNC(&MemObj, GMM_CHUNK_SIZE, NIL_RTHCPHYS);
- else
- rc = RTR0MemObjAllocPhysEx(&MemObj, GMM_CHUNK_SIZE, NIL_RTHCPHYS, GMM_CHUNK_SIZE);
-
- /* Grab the lock again. */
- int rc2 = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRCReturn(rc2, rc2);
+ gmmR0MutexRelease(pGMM);
+ RTR0MEMOBJ hMemObj;
+ int rc = RTR0MemObjAllocPhysNC(&hMemObj, GMM_CHUNK_SIZE, NIL_RTHCPHYS);
if (RT_SUCCESS(rc))
{
- rc = gmmR0RegisterChunk(pGMM, pSet, MemObj, hGVM, enmChunkType, ppChunk);
- if (RT_FAILURE(rc))
- RTR0MemObjFree(MemObj, false /* fFreeMappings */);
+/** @todo Duplicate gmmR0RegisterChunk here so we can avoid chaining up the
+ * free pages first and then unchaining them right afterwards. Instead
+ * do as much work as possible without holding the giant lock. */
+ PGMMCHUNK pChunk;
+ rc = gmmR0RegisterChunk(pGMM, pSet, hMemObj, pGVM->hSelf, 0 /*fChunkFlags*/, &pChunk);
+ if (RT_SUCCESS(rc))
+ {
+ *piPage = gmmR0AllocatePagesFromChunk(pGMM, pGVM->hSelf, pChunk, *piPage, cPages, paPages);
+ return VINF_SUCCESS;
+ }
+
+ /* bail out */
+ RTR0MemObjFree(hMemObj, false /* fFreeMappings */);
}
- /** @todo Check that RTR0MemObjAllocPhysNC always returns VERR_NO_MEMORY on
- * allocation failure. */
+
+ int rc2 = gmmR0MutexAcquire(pGMM);
+ AssertRCReturn(rc2, RT_FAILURE(rc) ? rc : rc2);
return rc;
+
}
/**
- * Attempts to allocate more pages until the requested amount is met.
+ * As a last restort we'll pick any page we can get.
*
- * @returns VBox status code.
- * @param pGMM Pointer to the GMM instance data.
- * @param pGVM The calling VM.
- * @param pSet Pointer to the free set to grow.
- * @param cPages The number of pages needed.
+ * @returns The new page descriptor table index.
+ * @param pGMM Pointer to the GMM instance data.
+ * @param pGVM Pointer to the global VM structure.
+ * @param pSet The set to pick from.
+ * @param iPage The current page descriptor table index.
+ * @param cPages The total number of pages to allocate.
+ * @param paPages The page descriptor table (input + ouput).
+ */
+static uint32_t gmmR0AllocatePagesIndiscriminately(PGMM pGMM, PGVM pGVM, PGMMCHUNKFREESET pSet,
+ uint32_t iPage, uint32_t cPages, PGMMPAGEDESC paPages)
+{
+ unsigned iList = RT_ELEMENTS(pSet->apLists);
+ while (iList-- > 0)
+ {
+ PGMMCHUNK pChunk = pSet->apLists[iList];
+ while (pChunk)
+ {
+ PGMMCHUNK pNext = pChunk->pFreeNext;
+
+ iPage = gmmR0AllocatePagesFromChunk(pGMM, pGVM->hSelf, pChunk, iPage, cPages, paPages);
+ if (iPage >= cPages)
+ return iPage;
+
+ pChunk = pNext;
+ }
+ }
+ return iPage;
+}
+
+
+/**
+ * Pick pages from empty chunks on the same NUMA node.
*
- * @remarks Called owning the mutex, but will leave it temporarily while
- * allocating the memory!
+ * @returns The new page descriptor table index.
+ * @param pGMM Pointer to the GMM instance data.
+ * @param pGVM Pointer to the global VM structure.
+ * @param pSet The set to pick from.
+ * @param iPage The current page descriptor table index.
+ * @param cPages The total number of pages to allocate.
+ * @param paPages The page descriptor table (input + ouput).
*/
-static int gmmR0AllocateMoreChunks(PGMM pGMM, PGVM pGVM, PGMMCHUNKFREESET pSet, uint32_t cPages)
+static uint32_t gmmR0AllocatePagesFromEmptyChunksOnSameNode(PGMM pGMM, PGVM pGVM, PGMMCHUNKFREESET pSet,
+ uint32_t iPage, uint32_t cPages, PGMMPAGEDESC paPages)
{
- Assert(!pGMM->fLegacyAllocationMode);
+ PGMMCHUNK pChunk = pSet->apLists[GMM_CHUNK_FREE_SET_UNUSED_LIST];
+ if (pChunk)
+ {
+ uint16_t const idNumaNode = gmmR0GetCurrentNumaNodeId();
+ while (pChunk)
+ {
+ PGMMCHUNK pNext = pChunk->pFreeNext;
- if (!GMM_CHECK_SANITY_IN_LOOPS(pGMM))
- return VERR_INTERNAL_ERROR_4;
+ if (pChunk->idNumaNode == idNumaNode)
+ {
+ pChunk->hGVM = pGVM->hSelf;
+ iPage = gmmR0AllocatePagesFromChunk(pGMM, pGVM->hSelf, pChunk, iPage, cPages, paPages);
+ if (iPage >= cPages)
+ {
+ pGVM->gmm.s.idLastChunkHint = pChunk->cFree ? pChunk->Core.Key : NIL_GMM_CHUNKID;
+ return iPage;
+ }
+ }
- if (!pGMM->fBoundMemoryMode)
+ pChunk = pNext;
+ }
+ }
+ return iPage;
+}
+
+
+/**
+ * Pick pages from non-empty chunks on the same NUMA node.
+ *
+ * @returns The new page descriptor table index.
+ * @param pGMM Pointer to the GMM instance data.
+ * @param pGVM Pointer to the global VM structure.
+ * @param pSet The set to pick from.
+ * @param iPage The current page descriptor table index.
+ * @param cPages The total number of pages to allocate.
+ * @param paPages The page descriptor table (input + ouput).
+ */
+static uint32_t gmmR0AllocatePagesFromSameNode(PGMM pGMM, PGVM pGVM, PGMMCHUNKFREESET pSet,
+ uint32_t iPage, uint32_t cPages, PGMMPAGEDESC paPages)
+{
+ /** @todo start by picking from chunks with about the right size first? */
+ uint16_t const idNumaNode = gmmR0GetCurrentNumaNodeId();
+ unsigned iList = GMM_CHUNK_FREE_SET_UNUSED_LIST;
+ while (iList-- > 0)
{
- /*
- * Try steal free chunks from the other set first. (Only take 100% free chunks.)
- */
- PGMMCHUNKFREESET pOtherSet = pSet == &pGMM->Private ? &pGMM->Shared : &pGMM->Private;
- while ( pSet->cFreePages < cPages
- && pOtherSet->cFreePages >= GMM_CHUNK_NUM_PAGES)
+ PGMMCHUNK pChunk = pSet->apLists[iList];
+ while (pChunk)
{
- PGMMCHUNK pChunk = pOtherSet->apLists[GMM_CHUNK_FREE_SET_LISTS - 1];
- while (pChunk && pChunk->cFree != GMM_CHUNK_NUM_PAGES)
- pChunk = pChunk->pFreeNext;
- if (!pChunk)
- break;
+ PGMMCHUNK pNext = pChunk->pFreeNext;
- gmmR0UnlinkChunk(pChunk);
- gmmR0LinkChunk(pChunk, pSet);
+ if (pChunk->idNumaNode == idNumaNode)
+ {
+ iPage = gmmR0AllocatePagesFromChunk(pGMM, pGVM->hSelf, pChunk, iPage, cPages, paPages);
+ if (iPage >= cPages)
+ {
+ pGVM->gmm.s.idLastChunkHint = pChunk->cFree ? pChunk->Core.Key : NIL_GMM_CHUNKID;
+ return iPage;
+ }
+ }
+
+ pChunk = pNext;
}
+ }
+ return iPage;
+}
- /*
- * If we need still more pages, allocate new chunks.
- * Note! We will leave the mutex while doing the allocation,
- */
- while (pSet->cFreePages < cPages)
+
+/**
+ * Pick pages that are in chunks already associated with the VM.
+ *
+ * @returns The new page descriptor table index.
+ * @param pGMM Pointer to the GMM instance data.
+ * @param pGVM Pointer to the global VM structure.
+ * @param pSet The set to pick from.
+ * @param iPage The current page descriptor table index.
+ * @param cPages The total number of pages to allocate.
+ * @param paPages The page descriptor table (input + ouput).
+ */
+static uint32_t gmmR0AllocatePagesAssociatedWithVM(PGMM pGMM, PGVM pGVM, PGMMCHUNKFREESET pSet,
+ uint32_t iPage, uint32_t cPages, PGMMPAGEDESC paPages)
+{
+ uint16_t const hGVM = pGVM->hSelf;
+
+ /* Hint. */
+ if (pGVM->gmm.s.idLastChunkHint != NIL_GMM_CHUNKID)
+ {
+ PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, pGVM->gmm.s.idLastChunkHint);
+ if (pChunk && pChunk->cFree)
{
- int rc = gmmR0AllocateOneChunk(pGMM, pSet, pGVM->hSelf, GMMCHUNKTYPE_NON_CONTINUOUS);
- if (RT_FAILURE(rc))
- return rc;
- if (!GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
- return VERR_INTERNAL_ERROR_5;
+ iPage = gmmR0AllocatePagesFromChunk(pGMM, hGVM, pChunk, iPage, cPages, paPages);
+ if (iPage >= cPages)
+ return iPage;
}
}
- else
+
+ /* Scan. */
+ for (unsigned iList = 0; iList < RT_ELEMENTS(pSet->apLists); iList++)
{
- /*
- * The memory is bound to the VM allocating it, so we have to count
- * the free pages carefully as well as making sure we brand them with
- * our VM handle.
- *
- * Note! We will leave the mutex while doing the allocation,
- */
- uint16_t const hGVM = pGVM->hSelf;
- for (;;)
+ PGMMCHUNK pChunk = pSet->apLists[iList];
+ while (pChunk)
{
- /* Count and see if we've reached the goal. */
- uint32_t cPagesFound = 0;
- for (unsigned i = 0; i < RT_ELEMENTS(pSet->apLists); i++)
- for (PGMMCHUNK pCur = pSet->apLists[i]; pCur; pCur = pCur->pFreeNext)
- if (pCur->hGVM == hGVM)
- {
- cPagesFound += pCur->cFree;
- if (cPagesFound >= cPages)
- break;
- }
- if (cPagesFound >= cPages)
- break;
+ PGMMCHUNK pNext = pChunk->pFreeNext;
- /* Allocate more. */
- int rc = gmmR0AllocateOneChunk(pGMM, pSet, hGVM, GMMCHUNKTYPE_NON_CONTINUOUS);
- if (RT_FAILURE(rc))
- return rc;
- if (!GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
- return VERR_INTERNAL_ERROR_5;
+ if (pChunk->hGVM == hGVM)
+ {
+ iPage = gmmR0AllocatePagesFromChunk(pGMM, hGVM, pChunk, iPage, cPages, paPages);
+ if (iPage >= cPages)
+ {
+ pGVM->gmm.s.idLastChunkHint = pChunk->cFree ? pChunk->Core.Key : NIL_GMM_CHUNKID;
+ return iPage;
+ }
+ }
+
+ pChunk = pNext;
}
}
-
- return VINF_SUCCESS;
+ return iPage;
}
+
/**
- * Allocates one private page.
+ * Pick pages in bound memory mode.
*
- * Worker for gmmR0AllocatePages.
- *
- * @param pGMM Pointer to the GMM instance data.
- * @param hGVM The GVM handle of the VM requesting memory.
- * @param pChunk The chunk to allocate it from.
- * @param pPageDesc The page descriptor.
+ * @returns The new page descriptor table index.
+ * @param pGMM Pointer to the GMM instance data.
+ * @param pGVM Pointer to the global VM structure.
+ * @param iPage The current page descriptor table index.
+ * @param cPages The total number of pages to allocate.
+ * @param paPages The page descriptor table (input + ouput).
*/
-static void gmmR0AllocatePage(PGMM pGMM, uint32_t hGVM, PGMMCHUNK pChunk, PGMMPAGEDESC pPageDesc)
+static uint32_t gmmR0AllocatePagesInBoundMode(PGMM pGMM, PGVM pGVM, uint32_t iPage, uint32_t cPages, PGMMPAGEDESC paPages)
{
- /* update the chunk stats. */
- if (pChunk->hGVM == NIL_GVM_HANDLE)
- pChunk->hGVM = hGVM;
- Assert(pChunk->cFree);
- pChunk->cFree--;
- pChunk->cPrivate++;
+ for (unsigned iList = 0; iList < RT_ELEMENTS(pGVM->gmm.s.Private.apLists); iList++)
+ {
+ PGMMCHUNK pChunk = pGVM->gmm.s.Private.apLists[iList];
+ while (pChunk)
+ {
+ Assert(pChunk->hGVM == pGVM->hSelf);
+ PGMMCHUNK pNext = pChunk->pFreeNext;
+ iPage = gmmR0AllocatePagesFromChunk(pGMM, pGVM->hSelf, pChunk, iPage, cPages, paPages);
+ if (iPage >= cPages)
+ return iPage;
+ pChunk = pNext;
+ }
+ }
+ return iPage;
+}
- /* unlink the first free page. */
- const uint32_t iPage = pChunk->iFreeHead;
- AssertReleaseMsg(iPage < RT_ELEMENTS(pChunk->aPages), ("%d\n", iPage));
- PGMMPAGE pPage = &pChunk->aPages[iPage];
- Assert(GMM_PAGE_IS_FREE(pPage));
- pChunk->iFreeHead = pPage->Free.iNext;
- Log3(("A pPage=%p iPage=%#x/%#x u2State=%d iFreeHead=%#x iNext=%#x\n",
- pPage, iPage, (pChunk->Core.Key << GMM_CHUNKID_SHIFT) | iPage,
- pPage->Common.u2State, pChunk->iFreeHead, pPage->Free.iNext));
- /* make the page private. */
- pPage->u = 0;
- AssertCompile(GMM_PAGE_STATE_PRIVATE == 0);
- pPage->Private.hGVM = hGVM;
- AssertCompile(NIL_RTHCPHYS >= GMM_GCPHYS_LAST);
- AssertCompile(GMM_GCPHYS_UNSHAREABLE >= GMM_GCPHYS_LAST);
- if (pPageDesc->HCPhysGCPhys <= GMM_GCPHYS_LAST)
- pPage->Private.pfn = pPageDesc->HCPhysGCPhys >> PAGE_SHIFT;
- else
- pPage->Private.pfn = GMM_PAGE_PFN_UNSHAREABLE; /* unshareable / unassigned - same thing. */
+/**
+ * Checks if we should start picking pages from chunks of other VMs.
+ *
+ * @returns @c true if we should, @c false if we should first try allocate more
+ * chunks.
+ */
+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
+ /** @todo what about shared pages? */;
+ uint64_t cPgAllocated = pGVM->gmm.s.Allocated.cBasePages
+ + pGVM->gmm.s.Allocated.cFixedPages;
+ uint64_t cPgDelta = cPgReserved - cPgAllocated;
+ if (cPgDelta < GMM_CHUNK_NUM_PAGES * 4)
+ return true;
+ /** @todo make the threshold configurable, also test the code to see if
+ * this ever kicks in (we might be reserving too much or smth). */
- /* update the page descriptor. */
- pPageDesc->HCPhysGCPhys = RTR0MemObjGetPagePhysAddr(pChunk->MemObj, iPage);
- Assert(pPageDesc->HCPhysGCPhys != NIL_RTHCPHYS);
- pPageDesc->idPage = (pChunk->Core.Key << GMM_CHUNKID_SHIFT) | iPage;
- pPageDesc->idSharedPage = NIL_GMM_PAGEID;
+ /*
+ * Check how close we're to the max memory limit and how many fragments
+ * there are?...
+ */
+ /** @todo. */
+
+ return false;
}
@@ -1820,9 +2372,13 @@ static void gmmR0AllocatePage(PGMM pGMM, uint32_t hGVM, PGMMCHUNK pChunk, PGMMPA
* @param paPages Pointer to the page descriptors.
* See GMMPAGEDESC for details on what is expected on input.
* @param enmAccount The account to charge.
+ *
+ * @remarks Call takes the giant GMM lock.
*/
-static int gmmR0AllocatePages(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMPAGEDESC paPages, GMMACCOUNT enmAccount)
+static int gmmR0AllocatePagesNew(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMPAGEDESC paPages, GMMACCOUNT enmAccount)
{
+ Assert(pGMM->hMtxOwner == RTThreadNativeSelf());
+
/*
* Check allocation limits.
*/
@@ -1832,7 +2388,8 @@ static int gmmR0AllocatePages(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMPAGEDES
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.Allocated.cBasePages + pGVM->gmm.s.cBalloonedPages + cPages
+ > pGVM->gmm.s.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));
@@ -1842,7 +2399,7 @@ static int gmmR0AllocatePages(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMPAGEDES
case GMMACCOUNT_SHADOW:
if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cShadowPages + cPages > pGVM->gmm.s.Reserved.cShadowPages))
{
- Log(("gmmR0AllocatePages:Shadow: Reserved=%#llx Allocated+Requested=%#llx+%#x!\n",
+ Log(("gmmR0AllocatePages:Shadow: Reserved=%#x Allocated+Requested=%#x+%#x!\n",
pGVM->gmm.s.Reserved.cShadowPages, pGVM->gmm.s.Allocated.cShadowPages, cPages));
return VERR_GMM_HIT_VM_ACCOUNT_LIMIT;
}
@@ -1850,7 +2407,7 @@ static int gmmR0AllocatePages(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMPAGEDES
case GMMACCOUNT_FIXED:
if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cFixedPages + cPages > pGVM->gmm.s.Reserved.cFixedPages))
{
- Log(("gmmR0AllocatePages:Fixed: Reserved=%#llx Allocated+Requested=%#llx+%#x!\n",
+ Log(("gmmR0AllocatePages:Fixed: Reserved=%#x Allocated+Requested=%#x+%#x!\n",
pGVM->gmm.s.Reserved.cFixedPages, pGVM->gmm.s.Allocated.cFixedPages, cPages));
return VERR_GMM_HIT_VM_ACCOUNT_LIMIT;
}
@@ -1860,128 +2417,140 @@ static int gmmR0AllocatePages(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMPAGEDES
}
/*
- * Check if we need to allocate more memory or not. In bound memory mode this
- * is a bit extra work but it's easier to do it upfront than bailing out later.
+ * If we're in legacy memory mode, it's easy to figure if we have
+ * sufficient number of pages up-front.
*/
- PGMMCHUNKFREESET pSet = &pGMM->Private;
- if (pSet->cFreePages < cPages)
+ if ( pGMM->fLegacyAllocationMode
+ && pGVM->gmm.s.Private.cFreePages < cPages)
+ {
+ Assert(pGMM->fBoundMemoryMode);
return VERR_GMM_SEED_ME;
- if (pGMM->fBoundMemoryMode)
+ }
+
+ /*
+ * Update the accounts before we proceed because we might be leaving the
+ * protection of the global mutex and thus run the risk of permitting
+ * too much memory to be allocated.
+ */
+ switch (enmAccount)
{
- uint16_t hGVM = pGVM->hSelf;
- uint32_t cPagesFound = 0;
- for (unsigned i = 0; i < RT_ELEMENTS(pSet->apLists); i++)
- for (PGMMCHUNK pCur = pSet->apLists[i]; pCur; pCur = pCur->pFreeNext)
- if (pCur->hGVM == hGVM)
- {
- cPagesFound += pCur->cFree;
- if (cPagesFound >= cPages)
- break;
- }
- if (cPagesFound < cPages)
- return VERR_GMM_SEED_ME;
+ 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;
+ default: AssertMsgFailedReturn(("enmAccount=%d\n", enmAccount), VERR_INTERNAL_ERROR);
}
+ pGVM->gmm.s.cPrivatePages += cPages;
+ pGMM->cAllocatedPages += cPages;
/*
- * Pick the pages.
- * Try make some effort keeping VMs sharing private chunks.
+ * Part two of it's-easy-in-legacy-memory-mode.
*/
- uint16_t hGVM = pGVM->hSelf;
uint32_t iPage = 0;
-
- /* first round, pick from chunks with an affinity to the VM. */
- for (unsigned i = 0; i < RT_ELEMENTS(pSet->apLists) && iPage < cPages; i++)
+ if (pGMM->fLegacyAllocationMode)
{
- PGMMCHUNK pCurFree = NULL;
- PGMMCHUNK pCur = pSet->apLists[i];
- while (pCur && iPage < cPages)
- {
- PGMMCHUNK pNext = pCur->pFreeNext;
-
- if ( pCur->hGVM == hGVM
- && pCur->cFree < GMM_CHUNK_NUM_PAGES)
- {
- gmmR0UnlinkChunk(pCur);
- for (; pCur->cFree && iPage < cPages; iPage++)
- gmmR0AllocatePage(pGMM, hGVM, pCur, &paPages[iPage]);
- gmmR0LinkChunk(pCur, pSet);
- }
-
- pCur = pNext;
- }
+ iPage = gmmR0AllocatePagesInBoundMode(pGMM, pGVM, iPage, cPages, paPages);
+ AssertReleaseReturn(iPage == cPages, VERR_INTERNAL_ERROR_3);
+ return VINF_SUCCESS;
}
- if (iPage < cPages)
+ /*
+ * Bound mode is also relatively straightforward.
+ */
+ int rc = VINF_SUCCESS;
+ if (pGMM->fBoundMemoryMode)
{
- /* second round, pick pages from the 100% empty chunks we just skipped above. */
- PGMMCHUNK pCurFree = NULL;
- PGMMCHUNK pCur = pSet->apLists[RT_ELEMENTS(pSet->apLists) - 1];
- while (pCur && iPage < cPages)
- {
- PGMMCHUNK pNext = pCur->pFreeNext;
-
- if ( pCur->cFree == GMM_CHUNK_NUM_PAGES
- && ( pCur->hGVM == hGVM
- || !pGMM->fBoundMemoryMode))
- {
- gmmR0UnlinkChunk(pCur);
- for (; pCur->cFree && iPage < cPages; iPage++)
- gmmR0AllocatePage(pGMM, hGVM, pCur, &paPages[iPage]);
- gmmR0LinkChunk(pCur, pSet);
- }
-
- pCur = pNext;
- }
+ iPage = gmmR0AllocatePagesInBoundMode(pGMM, pGVM, iPage, cPages, paPages);
+ if (iPage < cPages)
+ do
+ rc = gmmR0AllocateChunkNew(pGMM, pGVM, &pGVM->gmm.s.Private, cPages, paPages, &iPage);
+ while (iPage < cPages && RT_SUCCESS(rc));
}
-
- if ( iPage < cPages
- && !pGMM->fBoundMemoryMode)
+ /*
+ * Shared mode is trickier as we should try archive the same locality as
+ * in bound mode, but smartly make use of non-full chunks allocated by
+ * other VMs if we're low on memory.
+ */
+ else
{
- /* third round, disregard affinity. */
- unsigned i = RT_ELEMENTS(pSet->apLists);
- while (i-- > 0 && iPage < cPages)
+ /* Pick the most optimal pages first. */
+ iPage = gmmR0AllocatePagesAssociatedWithVM(pGMM, pGVM, &pGMM->PrivateX, iPage, cPages, paPages);
+ if (iPage < cPages)
{
- PGMMCHUNK pCurFree = NULL;
- PGMMCHUNK pCur = pSet->apLists[i];
- while (pCur && iPage < cPages)
- {
- PGMMCHUNK pNext = pCur->pFreeNext;
+ /* Maybe we should try getting pages from chunks "belonging" to
+ other VMs before allocating more chunks? */
+ if (gmmR0ShouldAllocatePagesInOtherChunks(pGVM))
+ iPage = gmmR0AllocatePagesFromSameNode(pGMM, pGVM, &pGMM->PrivateX, iPage, cPages, paPages);
- if ( pCur->cFree > GMM_CHUNK_NUM_PAGES / 2
- && cPages >= GMM_CHUNK_NUM_PAGES / 2)
- pCur->hGVM = hGVM; /* change chunk affinity */
+ /* Allocate memory from empty chunks. */
+ if (iPage < cPages)
+ iPage = gmmR0AllocatePagesFromEmptyChunksOnSameNode(pGMM, pGVM, &pGMM->PrivateX, iPage, cPages, paPages);
- gmmR0UnlinkChunk(pCur);
- for (; pCur->cFree && iPage < cPages; iPage++)
- gmmR0AllocatePage(pGMM, hGVM, pCur, &paPages[iPage]);
- gmmR0LinkChunk(pCur, pSet);
+ /* Grab empty shared chunks. */
+ if (iPage < cPages)
+ iPage = gmmR0AllocatePagesFromEmptyChunksOnSameNode(pGMM, pGVM, &pGMM->Shared, iPage, cPages, paPages);
- pCur = pNext;
+ /*
+ * Ok, try allocate new chunks.
+ */
+ if (iPage < cPages)
+ {
+ do
+ rc = gmmR0AllocateChunkNew(pGMM, pGVM, &pGMM->PrivateX, cPages, paPages, &iPage);
+ while (iPage < cPages && RT_SUCCESS(rc));
+
+ /* If the host is out of memory, take whatever we can get. */
+ if ( rc == VERR_NO_MEMORY
+ && pGMM->PrivateX.cFreePages + pGMM->Shared.cFreePages >= cPages - iPage)
+ {
+ iPage = gmmR0AllocatePagesIndiscriminately(pGMM, pGVM, &pGMM->PrivateX, iPage, cPages, paPages);
+ if (iPage < cPages)
+ iPage = gmmR0AllocatePagesIndiscriminately(pGMM, pGVM, &pGMM->Shared, iPage, cPages, paPages);
+ AssertRelease(iPage == cPages);
+ rc = VINF_SUCCESS;
+ }
}
}
}
/*
- * Update the account.
+ * Clean up on failure. Since this is bound to be a low-memory condition
+ * we will give back any empty chunks that might be hanging around.
*/
- switch (enmAccount)
+ if (RT_FAILURE(rc))
{
- 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;
- default:
- AssertMsgFailedReturn(("enmAccount=%d\n", enmAccount), VERR_INTERNAL_ERROR);
- }
- pGVM->gmm.s.cPrivatePages += iPage;
- pGMM->cAllocatedPages += iPage;
+ /* Update the statistics. */
+ pGVM->gmm.s.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;
+ default: AssertMsgFailedReturn(("enmAccount=%d\n", enmAccount), VERR_INTERNAL_ERROR);
+ }
- AssertMsgReturn(iPage == cPages, ("%u != %u\n", iPage, cPages), VERR_INTERNAL_ERROR);
+ /* Release the pages. */
+ while (iPage-- > 0)
+ {
+ uint32_t idPage = paPages[iPage].idPage;
+ PGMMPAGE pPage = gmmR0GetPage(pGMM, idPage);
+ if (RT_LIKELY(pPage))
+ {
+ Assert(GMM_PAGE_IS_PRIVATE(pPage));
+ Assert(pPage->Private.hGVM == pGVM->hSelf);
+ gmmR0FreePrivatePage(pGMM, pGVM, idPage, pPage);
+ }
+ else
+ AssertMsgFailed(("idPage=%#x\n", idPage));
- /*
- * Check if we've reached some threshold and should kick one or two VMs and tell
- * them to inflate their balloons a bit more... later.
- */
+ paPages[iPage].idPage = NIL_GMM_PAGEID;
+ paPages[iPage].idSharedPage = NIL_GMM_PAGEID;
+ paPages[iPage].HCPhysGCPhys = NIL_RTHCPHYS;
+ }
+ /* Free empty chunks. */
+ /** @todo */
+ }
return VINF_SUCCESS;
}
@@ -2061,8 +2630,7 @@ GMMR0DECL(int) GMMR0AllocateHandyPages(PVM pVM, VMCPUID idCpu, uint32_t cPagesTo
AssertMsgReturn(paPages[iPage].idSharedPage == NIL_GMM_PAGEID, ("#%#x: %#x\n", iPage, paPages[iPage].idSharedPage), VERR_INVALID_PARAMETER);
}
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
/* No allocations before the initial reservation has been made! */
@@ -2092,7 +2660,7 @@ GMMR0DECL(int) GMMR0AllocateHandyPages(PVM pVM, VMCPUID idCpu, uint32_t cPagesTo
pPage->Private.pfn = GMM_PAGE_PFN_UNSHAREABLE;
/* else: NIL_RTHCPHYS nothing */
- paPages[iPage].idPage = NIL_GMM_PAGEID;
+ paPages[iPage].idPage = NIL_GMM_PAGEID;
paPages[iPage].HCPhysGCPhys = NIL_RTHCPHYS;
}
else
@@ -2134,9 +2702,7 @@ GMMR0DECL(int) GMMR0AllocateHandyPages(PVM pVM, VMCPUID idCpu, uint32_t cPagesTo
pGVM->gmm.s.cSharedPages--;
pGVM->gmm.s.Allocated.cBasePages--;
if (!--pPage->Shared.cRefs)
- {
- gmmR0FreeSharedPage(pGMM, paPages[iPage].idSharedPage, pPage);
- }
+ gmmR0FreeSharedPage(pGMM, pGVM, paPages[iPage].idSharedPage, pPage);
else
{
Assert(pGMM->cDuplicatePages);
@@ -2159,19 +2725,24 @@ GMMR0DECL(int) GMMR0AllocateHandyPages(PVM pVM, VMCPUID idCpu, uint32_t cPagesTo
break;
}
}
- }
+ } /* for each page to update */
- /*
- * Join paths with GMMR0AllocatePages for the allocation.
- * Note! gmmR0AllocateMoreChunks may leave the protection of the mutex!
- */
- while (RT_SUCCESS(rc))
+ if (RT_SUCCESS(rc))
{
- rc = gmmR0AllocatePages(pGMM, pGVM, cPagesToAlloc, paPages, GMMACCOUNT_BASE);
- if ( rc != VERR_GMM_SEED_ME
- || pGMM->fLegacyAllocationMode)
- break;
- rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->Private, cPagesToAlloc);
+#if defined(VBOX_STRICT) && 0 /** @todo re-test this later. Appeared to be a PGM init bug. */
+ for (iPage = 0; iPage < cPagesToAlloc; iPage++)
+ {
+ Assert(paPages[iPage].HCPhysGCPhys == NIL_RTHCPHYS);
+ Assert(paPages[iPage].idPage == NIL_GMM_PAGEID);
+ Assert(paPages[iPage].idSharedPage == NIL_GMM_PAGEID);
+ }
+#endif
+
+ /*
+ * Join paths with GMMR0AllocatePages for the allocation.
+ * Note! gmmR0AllocateMoreChunks may leave the protection of the mutex!
+ */
+ rc = gmmR0AllocatePagesNew(pGMM, pGVM, cPagesToAlloc, paPages, GMMACCOUNT_BASE);
}
}
else
@@ -2180,7 +2751,7 @@ GMMR0DECL(int) GMMR0AllocateHandyPages(PVM pVM, VMCPUID idCpu, uint32_t cPagesTo
}
else
rc = VERR_INTERNAL_ERROR_5;
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
LogFlow(("GMMR0AllocateHandyPages: returns %Rrc\n", rc));
return rc;
}
@@ -2240,8 +2811,7 @@ GMMR0DECL(int) GMMR0AllocatePages(PVM pVM, VMCPUID idCpu, uint32_t cPages, PGMMP
AssertMsgReturn(paPages[iPage].idSharedPage == NIL_GMM_PAGEID, ("#%#x: %#x\n", iPage, paPages[iPage].idSharedPage), VERR_INVALID_PARAMETER);
}
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
@@ -2249,27 +2819,14 @@ GMMR0DECL(int) GMMR0AllocatePages(PVM pVM, VMCPUID idCpu, uint32_t cPages, PGMMP
if (RT_LIKELY( pGVM->gmm.s.Reserved.cBasePages
&& pGVM->gmm.s.Reserved.cFixedPages
&& pGVM->gmm.s.Reserved.cShadowPages))
- {
- /*
- * gmmR0AllocatePages seed loop.
- * Note! gmmR0AllocateMoreChunks may leave the protection of the mutex!
- */
- while (RT_SUCCESS(rc))
- {
- rc = gmmR0AllocatePages(pGMM, pGVM, cPages, paPages, enmAccount);
- if ( rc != VERR_GMM_SEED_ME
- || pGMM->fLegacyAllocationMode)
- break;
- rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->Private, cPages);
- }
- }
+ rc = gmmR0AllocatePagesNew(pGMM, pGVM, cPages, paPages, enmAccount);
else
rc = VERR_WRONG_ORDER;
GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
}
else
rc = VERR_INTERNAL_ERROR_5;
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
LogFlow(("GMMR0AllocatePages: returns %Rrc\n", rc));
return rc;
}
@@ -2300,6 +2857,7 @@ GMMR0DECL(int) GMMR0AllocatePagesReq(PVM pVM, VMCPUID idCpu, PGMMALLOCATEPAGESRE
return GMMR0AllocatePages(pVM, idCpu, pReq->cPages, &pReq->aPages[0], pReq->enmAccount);
}
+
/**
* Allocate a large page to represent guest RAM
*
@@ -2342,53 +2900,73 @@ GMMR0DECL(int) GMMR0AllocateLargePage(PVM pVM, VMCPUID idCpu, uint32_t cbPage,
*pHCPhys = NIL_RTHCPHYS;
*pIdPage = NIL_GMM_PAGEID;
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRCReturn(rc, rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
const unsigned cPages = (GMM_CHUNK_SIZE >> PAGE_SHIFT);
- PGMMCHUNK pChunk;
- GMMPAGEDESC PageDesc;
-
- if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cBasePages + pGVM->gmm.s.cBalloonedPages + cPages > pGVM->gmm.s.Reserved.cBasePages))
+ if (RT_UNLIKELY( pGVM->gmm.s.Allocated.cBasePages + pGVM->gmm.s.cBalloonedPages + cPages
+ > pGVM->gmm.s.Reserved.cBasePages))
{
Log(("GMMR0AllocateLargePage: Reserved=%#llx Allocated+Requested=%#llx+%#x!\n",
pGVM->gmm.s.Reserved.cBasePages, pGVM->gmm.s.Allocated.cBasePages, cPages));
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
return VERR_GMM_HIT_VM_ACCOUNT_LIMIT;
}
- /* Allocate a new continuous chunk. */
- rc = gmmR0AllocateOneChunk(pGMM, &pGMM->Private, pGVM->hSelf, GMMCHUNKTYPE_CONTINUOUS, &pChunk);
- if (RT_FAILURE(rc))
+ /*
+ * Allocate a new large page chunk.
+ *
+ * Note! We leave the giant GMM lock temporarily as the allocation might
+ * take a long time. gmmR0RegisterChunk will retake it (ugly).
+ */
+ AssertCompile(GMM_CHUNK_SIZE == _2M);
+ gmmR0MutexRelease(pGMM);
+
+ RTR0MEMOBJ hMemObj;
+ rc = RTR0MemObjAllocPhysEx(&hMemObj, GMM_CHUNK_SIZE, NIL_RTHCPHYS, GMM_CHUNK_SIZE);
+ if (RT_SUCCESS(rc))
{
- RTSemFastMutexRelease(pGMM->Mtx);
- return rc;
- }
+ PGMMCHUNKFREESET pSet = pGMM->fBoundMemoryMode ? &pGVM->gmm.s.Private : &pGMM->PrivateX;
+ PGMMCHUNK pChunk;
+ rc = gmmR0RegisterChunk(pGMM, pSet, hMemObj, pGVM->hSelf, GMM_CHUNK_FLAGS_LARGE_PAGE, &pChunk);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Allocate all the pages in the chunk.
+ */
+ /* Unlink the new chunk from the free list. */
+ gmmR0UnlinkChunk(pChunk);
- /* Unlink the new chunk from the free list. */
- gmmR0UnlinkChunk(pChunk);
+ /** @todo rewrite this to skip the looping. */
+ /* Allocate all pages. */
+ GMMPAGEDESC PageDesc;
+ gmmR0AllocatePage(pGMM, pGVM->hSelf, pChunk, &PageDesc);
- /* Allocate all pages. */
- gmmR0AllocatePage(pGMM, pGVM->hSelf, pChunk, &PageDesc);
- /* Return the first page as we'll use the whole chunk as one big page. */
- *pIdPage = PageDesc.idPage;
- *pHCPhys = PageDesc.HCPhysGCPhys;
+ /* Return the first page as we'll use the whole chunk as one big page. */
+ *pIdPage = PageDesc.idPage;
+ *pHCPhys = PageDesc.HCPhysGCPhys;
- for (unsigned i = 1; i < cPages; i++)
- gmmR0AllocatePage(pGMM, pGVM->hSelf, pChunk, &PageDesc);
+ for (unsigned i = 1; i < cPages; i++)
+ gmmR0AllocatePage(pGMM, pGVM->hSelf, pChunk, &PageDesc);
- /* Update accounting. */
- pGVM->gmm.s.Allocated.cBasePages += cPages;
- pGVM->gmm.s.cPrivatePages += cPages;
- pGMM->cAllocatedPages += cPages;
+ /* Update accounting. */
+ pGVM->gmm.s.Allocated.cBasePages += cPages;
+ pGVM->gmm.s.cPrivatePages += cPages;
+ pGMM->cAllocatedPages += cPages;
- gmmR0LinkChunk(pChunk, &pGMM->Private);
+ gmmR0LinkChunk(pChunk, pSet);
+ gmmR0MutexRelease(pGMM);
+ }
+ else
+ RTR0MemObjFree(hMemObj, false /* fFreeMappings */);
+ }
}
else
+ {
+ gmmR0MutexRelease(pGMM);
rc = VERR_INTERNAL_ERROR_5;
+ }
- RTSemFastMutexRelease(pGMM->Mtx);
LogFlow(("GMMR0AllocateLargePage: returns %Rrc\n", rc));
return rc;
}
@@ -2420,8 +2998,7 @@ GMMR0DECL(int) GMMR0FreeLargePage(PVM pVM, VMCPUID idCpu, uint32_t idPage)
if (pGMM->fLegacyAllocationMode)
return VERR_NOT_SUPPORTED;
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
const unsigned cPages = (GMM_CHUNK_SIZE >> PAGE_SHIFT);
@@ -2429,26 +3006,26 @@ GMMR0DECL(int) GMMR0FreeLargePage(PVM pVM, VMCPUID idCpu, uint32_t idPage)
if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cBasePages < cPages))
{
Log(("GMMR0FreeLargePage: allocated=%#llx cPages=%#x!\n", pGVM->gmm.s.Allocated.cBasePages, cPages));
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
return VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH;
}
PGMMPAGE pPage = gmmR0GetPage(pGMM, idPage);
- if ( RT_LIKELY(pPage)
- && RT_LIKELY(GMM_PAGE_IS_PRIVATE(pPage)))
+ if (RT_LIKELY( pPage
+ && GMM_PAGE_IS_PRIVATE(pPage)))
{
- PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, idPage >> GMM_CHUNKID_SHIFT);
- Assert(pChunk);
- Assert(pChunk->cFree < GMM_CHUNK_NUM_PAGES);
- Assert(pChunk->cPrivate > 0);
-
- /* Release the memory immediately. */
- gmmR0FreeChunk(pGMM, NULL, pChunk);
-
- /* Update accounting. */
- pGVM->gmm.s.Allocated.cBasePages -= cPages;
- pGVM->gmm.s.cPrivatePages -= cPages;
- pGMM->cAllocatedPages -= cPages;
+ PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, idPage >> GMM_CHUNKID_SHIFT);
+ Assert(pChunk);
+ Assert(pChunk->cFree < GMM_CHUNK_NUM_PAGES);
+ Assert(pChunk->cPrivate > 0);
+
+ /* Release the memory immediately. */
+ 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;
}
else
rc = VERR_GMM_PAGE_NOT_FOUND;
@@ -2456,7 +3033,7 @@ GMMR0DECL(int) GMMR0FreeLargePage(PVM pVM, VMCPUID idCpu, uint32_t idPage)
else
rc = VERR_INTERNAL_ERROR_5;
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
LogFlow(("GMMR0FreeLargePage: returns %Rrc\n", rc));
return rc;
}
@@ -2484,6 +3061,7 @@ GMMR0DECL(int) GMMR0FreeLargePageReq(PVM pVM, VMCPUID idCpu, PGMMFREELARGEPAGERE
return GMMR0FreeLargePage(pVM, idCpu, pReq->idPage);
}
+
/**
* Frees a chunk, giving it back to the host OS.
*
@@ -2491,71 +3069,89 @@ GMMR0DECL(int) GMMR0FreeLargePageReq(PVM pVM, VMCPUID idCpu, PGMMFREELARGEPAGERE
* @param pGVM This is set when called from GMMR0CleanupVM so we can
* unmap and free the chunk in one go.
* @param pChunk The chunk to free.
+ * @param fRelaxedSem Whether we can release the semaphore while doing the
+ * freeing (@c true) or not.
*/
-static void gmmR0FreeChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk)
+static bool gmmR0FreeChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, bool fRelaxedSem)
{
Assert(pChunk->Core.Key != NIL_GMM_CHUNKID);
+ GMMR0CHUNKMTXSTATE MtxState;
+ gmmR0ChunkMutexAcquire(&MtxState, pGMM, pChunk, GMMR0CHUNK_MTX_KEEP_GIANT);
+
/*
* Cleanup hack! Unmap the chunk from the callers address space.
+ * This shouldn't happen, so screw lock contention...
*/
- if ( pChunk->cMappings
+ if ( pChunk->cMappingsX
+ && !pGMM->fLegacyAllocationMode
&& pGVM)
- gmmR0UnmapChunk(pGMM, pGVM, pChunk);
+ gmmR0UnmapChunkLocked(pGMM, pGVM, pChunk);
/*
* If there are current mappings of the chunk, then request the
* VMs to unmap them. Reposition the chunk in the free list so
* it won't be a likely candidate for allocations.
*/
- if (pChunk->cMappings)
+ if (pChunk->cMappingsX)
{
/** @todo R0 -> VM request */
- /* The chunk can be owned by more than one VM if fBoundMemoryMode is false! */
- Log(("gmmR0FreeChunk: chunk still has %d mappings; don't free!\n", pChunk->cMappings));
+ /* The chunk can be mapped by more than one VM if fBoundMemoryMode is false! */
+ Log(("gmmR0FreeChunk: chunk still has %d/%d mappings; don't free!\n", pChunk->cMappingsX));
+ gmmR0ChunkMutexRelease(&MtxState, pChunk);
+ return false;
}
- else
+
+
+ /*
+ * Save and trash the handle.
+ */
+ RTR0MEMOBJ const hMemObj = pChunk->hMemObj;
+ pChunk->hMemObj = NIL_RTR0MEMOBJ;
+
+ /*
+ * Unlink it from everywhere.
+ */
+ gmmR0UnlinkChunk(pChunk);
+
+ RTListNodeRemove(&pChunk->ListNode);
+
+ PAVLU32NODECORE pCore = RTAvlU32Remove(&pGMM->pChunks, pChunk->Core.Key);
+ Assert(pCore == &pChunk->Core); NOREF(pCore);
+
+ PGMMCHUNKTLBE pTlbe = &pGMM->ChunkTLB.aEntries[GMM_CHUNKTLB_IDX(pChunk->Core.Key)];
+ if (pTlbe->pChunk == pChunk)
{
- /*
- * Try free the memory object.
- */
- int rc = RTR0MemObjFree(pChunk->MemObj, false /* fFreeMappings */);
- if (RT_SUCCESS(rc))
- {
- pChunk->MemObj = NIL_RTR0MEMOBJ;
+ pTlbe->idChunk = NIL_GMM_CHUNKID;
+ pTlbe->pChunk = NULL;
+ }
- /*
- * Unlink it from everywhere.
- */
- gmmR0UnlinkChunk(pChunk);
+ Assert(pGMM->cChunks > 0);
+ pGMM->cChunks--;
- PAVLU32NODECORE pCore = RTAvlU32Remove(&pGMM->pChunks, pChunk->Core.Key);
- Assert(pCore == &pChunk->Core); NOREF(pCore);
+ /*
+ * Free the Chunk ID before dropping the locks and freeing the rest.
+ */
+ gmmR0FreeChunkId(pGMM, pChunk->Core.Key);
+ pChunk->Core.Key = NIL_GMM_CHUNKID;
- PGMMCHUNKTLBE pTlbe = &pGMM->ChunkTLB.aEntries[GMM_CHUNKTLB_IDX(pChunk->Core.Key)];
- if (pTlbe->pChunk == pChunk)
- {
- pTlbe->idChunk = NIL_GMM_CHUNKID;
- pTlbe->pChunk = NULL;
- }
+ pGMM->cFreedChunks++;
- Assert(pGMM->cChunks > 0);
- pGMM->cChunks--;
+ gmmR0ChunkMutexRelease(&MtxState, NULL);
+ if (fRelaxedSem)
+ gmmR0MutexRelease(pGMM);
- /*
- * Free the Chunk ID and struct.
- */
- gmmR0FreeChunkId(pGMM, pChunk->Core.Key);
- pChunk->Core.Key = NIL_GMM_CHUNKID;
+ RTMemFree(pChunk->paMappingsX);
+ pChunk->paMappingsX = NULL;
- RTMemFree(pChunk->paMappings);
- pChunk->paMappings = NULL;
+ RTMemFree(pChunk);
- RTMemFree(pChunk);
- }
- else
- AssertRC(rc);
- }
+ int rc = RTR0MemObjFree(hMemObj, false /* fFreeMappings */);
+ AssertLogRelRC(rc);
+
+ if (fRelaxedSem)
+ gmmR0MutexAcquire(pGMM);
+ return fRelaxedSem;
}
@@ -2565,11 +3161,12 @@ static void gmmR0FreeChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk)
* The caller does all the statistic decrementing, we do all the incrementing.
*
* @param pGMM Pointer to the GMM instance data.
+ * @param pGVM Pointer to the GVM instance.
* @param pChunk Pointer to the chunk this page belongs to.
* @param idPage The Page ID.
* @param pPage Pointer to the page.
*/
-static void gmmR0FreePageWorker(PGMM pGMM, PGMMCHUNK pChunk, uint32_t idPage, PGMMPAGE pPage)
+static void gmmR0FreePageWorker(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, uint32_t idPage, PGMMPAGE pPage)
{
Log3(("F pPage=%p iPage=%#x/%#x u2State=%d iFreeHead=%#x\n",
pPage, pPage - &pChunk->aPages[0], idPage, pPage->Common.u2State, pChunk->iFreeHead)); NOREF(idPage);
@@ -2587,32 +3184,36 @@ static void gmmR0FreePageWorker(PGMM pGMM, PGMMCHUNK pChunk, uint32_t idPage, PG
* Update statistics (the cShared/cPrivate stats are up to date already),
* and relink the chunk if necessary.
*/
- if ((pChunk->cFree & GMM_CHUNK_FREE_SET_MASK) == 0)
+ unsigned const cFree = pChunk->cFree;
+ if ( !cFree
+ || gmmR0SelectFreeSetList(cFree) != gmmR0SelectFreeSetList(cFree + 1))
{
gmmR0UnlinkChunk(pChunk);
pChunk->cFree++;
- gmmR0LinkChunk(pChunk, pChunk->cShared ? &pGMM->Shared : &pGMM->Private);
+ gmmR0SelectSetAndLinkChunk(pGMM, pGVM, pChunk);
}
else
{
- pChunk->cFree++;
+ pChunk->cFree = cFree + 1;
pChunk->pSet->cFreePages++;
-
- /*
- * If the chunk becomes empty, consider giving memory back to the host OS.
- *
- * The current strategy is to try give it back if there are other chunks
- * in this free list, meaning if there are at least 240 free pages in this
- * category. Note that since there are probably mappings of the chunk,
- * it won't be freed up instantly, which probably screws up this logic
- * a bit...
- */
- if (RT_UNLIKELY( pChunk->cFree == GMM_CHUNK_NUM_PAGES
- && pChunk->pFreeNext
- && pChunk->pFreePrev
- && !pGMM->fLegacyAllocationMode))
- gmmR0FreeChunk(pGMM, NULL, pChunk);
}
+
+ /*
+ * If the chunk becomes empty, consider giving memory back to the host OS.
+ *
+ * The current strategy is to try give it back if there are other chunks
+ * in this free list, meaning if there are at least 240 free pages in this
+ * category. Note that since there are probably mappings of the chunk,
+ * it won't be freed up instantly, which probably screws up this logic
+ * a bit...
+ */
+ /** @todo Do this on the way out. */
+ if (RT_UNLIKELY( pChunk->cFree == GMM_CHUNK_NUM_PAGES
+ && pChunk->pFreeNext
+ && pChunk->pFreePrev /** @todo this is probably misfiring, see reset... */
+ && !pGMM->fLegacyAllocationMode))
+ gmmR0FreeChunk(pGMM, NULL, pChunk, false);
+
}
@@ -2620,10 +3221,11 @@ static void gmmR0FreePageWorker(PGMM pGMM, PGMMCHUNK pChunk, uint32_t idPage, PG
* Frees a shared page, the page is known to exist and be valid and such.
*
* @param pGMM Pointer to the GMM instance.
+ * @param pGVM Pointer to the GVM instance.
* @param idPage The Page ID
* @param pPage The page structure.
*/
-DECLINLINE(void) gmmR0FreeSharedPage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage)
+DECLINLINE(void) gmmR0FreeSharedPage(PGMM pGMM, PGVM pGVM, uint32_t idPage, PGMMPAGE pPage)
{
PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, idPage >> GMM_CHUNKID_SHIFT);
Assert(pChunk);
@@ -2636,68 +3238,19 @@ DECLINLINE(void) gmmR0FreeSharedPage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage)
pChunk->cShared--;
pGMM->cAllocatedPages--;
pGMM->cSharedPages--;
- gmmR0FreePageWorker(pGMM, pChunk, idPage, pPage);
-}
-
-#ifdef VBOX_WITH_PAGE_SHARING
-/**
- * Converts a private page to a shared page, the page is known to exist and be valid and such.
- *
- * @param pGMM Pointer to the GMM instance.
- * @param pGVM Pointer to the GVM instance.
- * @param HCPhys Host physical address
- * @param idPage The Page ID
- * @param pPage The page structure.
- */
-DECLINLINE(void) gmmR0ConvertToSharedPage(PGMM pGMM, PGVM pGVM, RTHCPHYS HCPhys, uint32_t idPage, PGMMPAGE pPage)
-{
- PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, idPage >> GMM_CHUNKID_SHIFT);
- Assert(pChunk);
- Assert(pChunk->cFree < GMM_CHUNK_NUM_PAGES);
- Assert(GMM_PAGE_IS_PRIVATE(pPage));
-
- pChunk->cPrivate--;
- pChunk->cShared++;
-
- pGMM->cSharedPages++;
-
- pGVM->gmm.s.cSharedPages++;
- pGVM->gmm.s.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;
+ gmmR0FreePageWorker(pGMM, pGVM, pChunk, idPage, pPage);
}
-/**
- * Increase the use count of a shared page, the page is known to exist and be valid and such.
- *
- * @param pGMM Pointer to the GMM instance.
- * @param pGVM Pointer to the GVM instance.
- * @param pPage The page structure.
- */
-DECLINLINE(void) gmmR0UseSharedPage(PGMM pGMM, PGVM pGVM, PGMMPAGE pPage)
-{
- Assert(pGMM->cSharedPages > 0);
- Assert(pGMM->cAllocatedPages > 0);
-
- pGMM->cDuplicatePages++;
-
- pPage->Shared.cRefs++;
- pGVM->gmm.s.cSharedPages++;
- pGVM->gmm.s.Allocated.cBasePages++;
-}
-#endif
/**
* Frees a private page, the page is known to exist and be valid and such.
*
* @param pGMM Pointer to the GMM instance.
+ * @param pGVM Pointer to the GVM instance.
* @param idPage The Page ID
* @param pPage The page structure.
*/
-DECLINLINE(void) gmmR0FreePrivatePage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage)
+DECLINLINE(void) gmmR0FreePrivatePage(PGMM pGMM, PGVM pGVM, uint32_t idPage, PGMMPAGE pPage)
{
PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, idPage >> GMM_CHUNKID_SHIFT);
Assert(pChunk);
@@ -2707,9 +3260,10 @@ DECLINLINE(void) gmmR0FreePrivatePage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage
pChunk->cPrivate--;
pGMM->cAllocatedPages--;
- gmmR0FreePageWorker(pGMM, pChunk, idPage, pPage);
+ gmmR0FreePageWorker(pGMM, pGVM, pChunk, idPage, pPage);
}
+
/**
* Common worker for GMMR0FreePages and GMMR0BalloonedPages.
*
@@ -2774,7 +3328,7 @@ static int gmmR0FreePages(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMFREEPAGEDES
{
Assert(pGVM->gmm.s.cPrivatePages);
pGVM->gmm.s.cPrivatePages--;
- gmmR0FreePrivatePage(pGMM, idPage, pPage);
+ gmmR0FreePrivatePage(pGMM, pGVM, idPage, pPage);
}
else
{
@@ -2790,9 +3344,7 @@ static int gmmR0FreePages(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMFREEPAGEDES
pGVM->gmm.s.cSharedPages--;
Assert(pPage->Shared.cRefs);
if (!--pPage->Shared.cRefs)
- {
- gmmR0FreeSharedPage(pGMM, idPage, pPage);
- }
+ gmmR0FreeSharedPage(pGMM, pGVM, idPage, pPage);
else
{
Assert(pGMM->cDuplicatePages);
@@ -2876,8 +3428,7 @@ GMMR0DECL(int) GMMR0FreePages(PVM pVM, VMCPUID idCpu, uint32_t cPages, PGMMFREEP
/*
* Take the semaphore and call the worker function.
*/
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
rc = gmmR0FreePages(pGMM, pGVM, cPages, paPages, enmAccount);
@@ -2885,7 +3436,7 @@ GMMR0DECL(int) GMMR0FreePages(PVM pVM, VMCPUID idCpu, uint32_t cPages, PGMMFREEP
}
else
rc = VERR_INTERNAL_ERROR_5;
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
LogFlow(("GMMR0FreePages: returns %Rrc\n", rc));
return rc;
}
@@ -2960,8 +3511,7 @@ GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, GMMBALLOONACTION enmA
/*
* Take the semaphore and do some more validations.
*/
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
switch (enmAction)
@@ -2992,7 +3542,11 @@ GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, GMMBALLOONACTION enmA
}
}
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));
rc = VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH;
+ }
break;
}
@@ -3023,7 +3577,10 @@ GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, GMMBALLOONACTION enmA
cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages));
}
else
+ {
+ Log(("GMMR0BalloonedPages: Total=%#llx cBalloonedPages=%#llx\n", pGVM->gmm.s.cBalloonedPages, cBalloonedPages));
rc = VERR_GMM_ATTEMPT_TO_DEFLATE_TOO_MUCH;
+ }
break;
}
@@ -3046,7 +3603,7 @@ GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, GMMBALLOONACTION enmA
else
rc = VERR_INTERNAL_ERROR_5;
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
LogFlow(("GMMR0BalloonedPages: returns %Rrc\n", rc));
return rc;
}
@@ -3139,8 +3696,7 @@ GMMR0DECL(int) GMMR0QueryMemoryStatsReq(PVM pVM, VMCPUID idCpu, PGMMMEMSTATSREQ
/*
* Take the semaphore and do some more validations.
*/
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
pReq->cAllocPages = pGVM->gmm.s.Allocated.cBasePages;
@@ -3151,11 +3707,58 @@ GMMR0DECL(int) GMMR0QueryMemoryStatsReq(PVM pVM, VMCPUID idCpu, PGMMMEMSTATSREQ
else
rc = VERR_INTERNAL_ERROR_5;
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
LogFlow(("GMMR3QueryVMMemoryStats: returns %Rrc\n", rc));
return rc;
}
+
+/**
+ * Worker for gmmR0UnmapChunk and gmmr0FreeChunk.
+ *
+ * Don't call this in legacy allocation mode!
+ *
+ * @returns VBox status code.
+ * @param pGMM Pointer to the GMM instance data.
+ * @param pGVM Pointer to the Global VM structure.
+ * @param pChunk Pointer to the chunk to be unmapped.
+ */
+static int gmmR0UnmapChunkLocked(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk)
+{
+ Assert(!pGMM->fLegacyAllocationMode);
+
+ /*
+ * Find the mapping and try unmapping it.
+ */
+ uint32_t cMappings = pChunk->cMappingsX;
+ for (uint32_t i = 0; i < cMappings; i++)
+ {
+ Assert(pChunk->paMappingsX[i].pGVM && pChunk->paMappingsX[i].hMapObj != NIL_RTR0MEMOBJ);
+ if (pChunk->paMappingsX[i].pGVM == pGVM)
+ {
+ /* unmap */
+ int rc = RTR0MemObjFree(pChunk->paMappingsX[i].hMapObj, false /* fFreeMappings (NA) */);
+ if (RT_SUCCESS(rc))
+ {
+ /* update the record. */
+ cMappings--;
+ if (i < cMappings)
+ pChunk->paMappingsX[i] = pChunk->paMappingsX[cMappings];
+ pChunk->paMappingsX[cMappings].hMapObj = NIL_RTR0MEMOBJ;
+ pChunk->paMappingsX[cMappings].pGVM = NULL;
+ Assert(pChunk->cMappingsX - 1U == cMappings);
+ pChunk->cMappingsX = cMappings;
+ }
+
+ return rc;
+ }
+ }
+
+ Log(("gmmR0UnmapChunk: Chunk %#x is not mapped into pGVM=%p/%#x\n", pChunk->Core.Key, pGVM, pGVM->hSelf));
+ return VERR_GMM_CHUNK_NOT_MAPPED;
+}
+
+
/**
* Unmaps a chunk previously mapped into the address space of the current process.
*
@@ -3164,43 +3767,34 @@ GMMR0DECL(int) GMMR0QueryMemoryStatsReq(PVM pVM, VMCPUID idCpu, PGMMMEMSTATSREQ
* @param pGVM Pointer to the Global VM structure.
* @param pChunk Pointer to the chunk to be unmapped.
*/
-static int gmmR0UnmapChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk)
+static int gmmR0UnmapChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, bool fRelaxedSem)
{
if (!pGMM->fLegacyAllocationMode)
{
/*
- * Find the mapping and try unmapping it.
+ * Lock the chunk and if possible leave the giant GMM lock.
*/
- for (uint32_t i = 0; i < pChunk->cMappings; i++)
+ GMMR0CHUNKMTXSTATE MtxState;
+ int rc = gmmR0ChunkMutexAcquire(&MtxState, pGMM, pChunk,
+ fRelaxedSem ? GMMR0CHUNK_MTX_RETAKE_GIANT : GMMR0CHUNK_MTX_KEEP_GIANT);
+ if (RT_SUCCESS(rc))
{
- Assert(pChunk->paMappings[i].pGVM && pChunk->paMappings[i].MapObj != NIL_RTR0MEMOBJ);
- if (pChunk->paMappings[i].pGVM == pGVM)
- {
- /* unmap */
- int rc = RTR0MemObjFree(pChunk->paMappings[i].MapObj, false /* fFreeMappings (NA) */);
- if (RT_SUCCESS(rc))
- {
- /* update the record. */
- pChunk->cMappings--;
- if (i < pChunk->cMappings)
- pChunk->paMappings[i] = pChunk->paMappings[pChunk->cMappings];
- pChunk->paMappings[pChunk->cMappings].MapObj = NIL_RTR0MEMOBJ;
- pChunk->paMappings[pChunk->cMappings].pGVM = NULL;
- }
- return rc;
- }
+ rc = gmmR0UnmapChunkLocked(pGMM, pGVM, pChunk);
+ gmmR0ChunkMutexRelease(&MtxState, pChunk);
}
+ return rc;
}
- else if (pChunk->hGVM == pGVM->hSelf)
+
+ if (pChunk->hGVM == pGVM->hSelf)
return VINF_SUCCESS;
- Log(("gmmR0UnmapChunk: Chunk %#x is not mapped into pGVM=%p/%#x\n", pChunk->Core.Key, pGVM, pGVM->hSelf));
+ Log(("gmmR0UnmapChunk: Chunk %#x is not mapped into pGVM=%p/%#x (legacy)\n", pChunk->Core.Key, pGVM, pGVM->hSelf));
return VERR_GMM_CHUNK_NOT_MAPPED;
}
/**
- * Maps a chunk into the user address space of the current process.
+ * Worker for gmmR0MapChunk.
*
* @returns VBox status code.
* @param pGMM Pointer to the GMM instance data.
@@ -3210,7 +3804,7 @@ static int gmmR0UnmapChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk)
* In the VERR_GMM_CHUNK_ALREADY_MAPPED case, this will be
* contain the address of the existing mapping.
*/
-static int gmmR0MapChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, PRTR3PTR ppvR3)
+static int gmmR0MapChunkLocked(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, PRTR3PTR ppvR3)
{
/*
* If we're in legacy mode this is simple.
@@ -3223,19 +3817,19 @@ static int gmmR0MapChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, PRTR3PTR ppvR3)
return VERR_GMM_CHUNK_NOT_FOUND;
}
- *ppvR3 = RTR0MemObjAddressR3(pChunk->MemObj);
+ *ppvR3 = RTR0MemObjAddressR3(pChunk->hMemObj);
return VINF_SUCCESS;
}
/*
* Check to see if the chunk is already mapped.
*/
- for (uint32_t i = 0; i < pChunk->cMappings; i++)
+ for (uint32_t i = 0; i < pChunk->cMappingsX; i++)
{
- Assert(pChunk->paMappings[i].pGVM && pChunk->paMappings[i].MapObj != NIL_RTR0MEMOBJ);
- if (pChunk->paMappings[i].pGVM == pGVM)
+ Assert(pChunk->paMappingsX[i].pGVM && pChunk->paMappingsX[i].hMapObj != NIL_RTR0MEMOBJ);
+ if (pChunk->paMappingsX[i].pGVM == pGVM)
{
- *ppvR3 = RTR0MemObjAddressR3(pChunk->paMappings[i].MapObj);
+ *ppvR3 = RTR0MemObjAddressR3(pChunk->paMappingsX[i].hMapObj);
Log(("gmmR0MapChunk: chunk %#x is already mapped at %p!\n", pChunk->Core.Key, *ppvR3));
#ifdef VBOX_WITH_PAGE_SHARING
/* The ring-3 chunk cache can be out of sync; don't fail. */
@@ -3249,60 +3843,109 @@ static int gmmR0MapChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, PRTR3PTR ppvR3)
/*
* Do the mapping.
*/
- RTR0MEMOBJ MapObj;
- int rc = RTR0MemObjMapUser(&MapObj, pChunk->MemObj, (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS);
+ RTR0MEMOBJ hMapObj;
+ int rc = RTR0MemObjMapUser(&hMapObj, pChunk->hMemObj, (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS);
if (RT_SUCCESS(rc))
{
- /* reallocate the array? */
- if ((pChunk->cMappings & 1 /*7*/) == 0)
+ /* reallocate the array? assumes few users per chunk (usually one). */
+ unsigned iMapping = pChunk->cMappingsX;
+ if ( iMapping <= 3
+ || (iMapping & 3) == 0)
{
- void *pvMappings = RTMemRealloc(pChunk->paMappings, (pChunk->cMappings + 2 /*8*/) * sizeof(pChunk->paMappings[0]));
+ unsigned cNewSize = iMapping <= 3
+ ? iMapping + 1
+ : iMapping + 4;
+ Assert(cNewSize < 4 || RT_ALIGN_32(cNewSize, 4) == cNewSize);
+ if (RT_UNLIKELY(cNewSize > UINT16_MAX))
+ {
+ rc = RTR0MemObjFree(hMapObj, false /* fFreeMappings (NA) */); AssertRC(rc);
+ return VERR_GMM_TOO_MANY_CHUNK_MAPPINGS;
+ }
+
+ void *pvMappings = RTMemRealloc(pChunk->paMappingsX, cNewSize * sizeof(pChunk->paMappingsX[0]));
if (RT_UNLIKELY(!pvMappings))
{
- rc = RTR0MemObjFree(MapObj, false /* fFreeMappings (NA) */);
- AssertRC(rc);
+ rc = RTR0MemObjFree(hMapObj, false /* fFreeMappings (NA) */); AssertRC(rc);
return VERR_NO_MEMORY;
}
- pChunk->paMappings = (PGMMCHUNKMAP)pvMappings;
+ pChunk->paMappingsX = (PGMMCHUNKMAP)pvMappings;
}
/* insert new entry */
- pChunk->paMappings[pChunk->cMappings].MapObj = MapObj;
- pChunk->paMappings[pChunk->cMappings].pGVM = pGVM;
- pChunk->cMappings++;
+ pChunk->paMappingsX[iMapping].hMapObj = hMapObj;
+ pChunk->paMappingsX[iMapping].pGVM = pGVM;
+ Assert(pChunk->cMappingsX == iMapping);
+ pChunk->cMappingsX = iMapping + 1;
- *ppvR3 = RTR0MemObjAddressR3(MapObj);
+ *ppvR3 = RTR0MemObjAddressR3(hMapObj);
}
return rc;
}
+
/**
- * Check if a chunk is mapped into the specified VM
+ * Maps a chunk into the user address space of the current process.
*
- * @returns mapped yes/no
+ * @returns VBox status code.
+ * @param pGMM Pointer to the GMM instance data.
* @param pGVM Pointer to the Global VM structure.
* @param pChunk Pointer to the chunk to be mapped.
+ * @param fRelaxedSem Whether we can release the semaphore while doing the
+ * mapping (@c true) or not.
* @param ppvR3 Where to store the ring-3 address of the mapping.
+ * In the VERR_GMM_CHUNK_ALREADY_MAPPED case, this will be
+ * contain the address of the existing mapping.
*/
-static int gmmR0IsChunkMapped(PGVM pGVM, PGMMCHUNK pChunk, PRTR3PTR ppvR3)
+static int gmmR0MapChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, bool fRelaxedSem, PRTR3PTR ppvR3)
{
/*
- * Check to see if the chunk is already mapped.
+ * Take the chunk lock and leave the giant GMM lock when possible, then
+ * call the worker function.
*/
- for (uint32_t i = 0; i < pChunk->cMappings; i++)
+ GMMR0CHUNKMTXSTATE MtxState;
+ int rc = gmmR0ChunkMutexAcquire(&MtxState, pGMM, pChunk,
+ fRelaxedSem ? GMMR0CHUNK_MTX_RETAKE_GIANT : GMMR0CHUNK_MTX_KEEP_GIANT);
+ if (RT_SUCCESS(rc))
+ {
+ rc = gmmR0MapChunkLocked(pGMM, pGVM, pChunk, ppvR3);
+ gmmR0ChunkMutexRelease(&MtxState, pChunk);
+ }
+
+ return rc;
+}
+
+
+
+/**
+ * Check if a chunk is mapped into the specified VM
+ *
+ * @returns mapped yes/no
+ * @param pGMM Pointer to the GMM instance.
+ * @param pGVM Pointer to the Global VM structure.
+ * @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)
+{
+ GMMR0CHUNKMTXSTATE MtxState;
+ gmmR0ChunkMutexAcquire(&MtxState, pGMM, pChunk, GMMR0CHUNK_MTX_KEEP_GIANT);
+ for (uint32_t i = 0; i < pChunk->cMappingsX; i++)
{
- Assert(pChunk->paMappings[i].pGVM && pChunk->paMappings[i].MapObj != NIL_RTR0MEMOBJ);
- if (pChunk->paMappings[i].pGVM == pGVM)
+ Assert(pChunk->paMappingsX[i].pGVM && pChunk->paMappingsX[i].hMapObj != NIL_RTR0MEMOBJ);
+ if (pChunk->paMappingsX[i].pGVM == pGVM)
{
- *ppvR3 = RTR0MemObjAddressR3(pChunk->paMappings[i].MapObj);
+ *ppvR3 = RTR0MemObjAddressR3(pChunk->paMappingsX[i].hMapObj);
+ gmmR0ChunkMutexRelease(&MtxState, pChunk);
return true;
}
}
*ppvR3 = NULL;
+ gmmR0ChunkMutexRelease(&MtxState, pChunk);
return false;
}
+
/**
* Map a chunk and/or unmap another chunk.
*
@@ -3355,8 +3998,7 @@ GMMR0DECL(int) GMMR0MapUnmapChunk(PVM pVM, uint32_t idChunkMap, uint32_t idChunk
* that it pushes the user virtual address space to within a chunk of
* it it's limits, so, no problem here.
*/
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
PGMMCHUNK pMap = NULL;
@@ -3364,20 +4006,22 @@ GMMR0DECL(int) GMMR0MapUnmapChunk(PVM pVM, uint32_t idChunkMap, uint32_t idChunk
{
pMap = gmmR0GetChunk(pGMM, idChunkMap);
if (RT_LIKELY(pMap))
- rc = gmmR0MapChunk(pGMM, pGVM, pMap, ppvR3);
+ rc = gmmR0MapChunk(pGMM, pGVM, pMap, true /*fRelaxedSem*/, ppvR3);
else
{
Log(("GMMR0MapUnmapChunk: idChunkMap=%#x\n", idChunkMap));
rc = VERR_GMM_CHUNK_NOT_FOUND;
}
}
+/** @todo split this operation, the bail out might (theoretcially) not be
+ * entirely safe. */
if ( idChunkUnmap != NIL_GMM_CHUNKID
&& RT_SUCCESS(rc))
{
PGMMCHUNK pUnmap = gmmR0GetChunk(pGMM, idChunkUnmap);
if (RT_LIKELY(pUnmap))
- rc = gmmR0UnmapChunk(pGMM, pGVM, pUnmap);
+ rc = gmmR0UnmapChunk(pGMM, pGVM, pUnmap, true /*fRelaxedSem*/);
else
{
Log(("GMMR0MapUnmapChunk: idChunkUnmap=%#x\n", idChunkUnmap));
@@ -3385,14 +4029,14 @@ GMMR0DECL(int) GMMR0MapUnmapChunk(PVM pVM, uint32_t idChunkMap, uint32_t idChunk
}
if (RT_FAILURE(rc) && pMap)
- gmmR0UnmapChunk(pGMM, pGVM, pMap);
+ gmmR0UnmapChunk(pGMM, pGVM, pMap, false /*fRelaxedSem*/);
}
GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
}
else
rc = VERR_INTERNAL_ERROR_5;
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
LogFlow(("GMMR0MapUnmapChunk: returns %Rrc\n", rc));
return rc;
@@ -3452,25 +4096,17 @@ GMMR0DECL(int) GMMR0SeedChunk(PVM pVM, VMCPUID idCpu, RTR3PTR pvR3)
}
/*
- * Lock the memory before taking the semaphore.
+ * Lock the memory and add it as new chunk with our hGVM.
+ * (The GMM locking is done inside gmmR0RegisterChunk.)
*/
RTR0MEMOBJ MemObj;
rc = RTR0MemObjLockUser(&MemObj, pvR3, GMM_CHUNK_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS);
if (RT_SUCCESS(rc))
{
- /* Grab the lock. */
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ rc = gmmR0RegisterChunk(pGMM, &pGVM->gmm.s.Private, MemObj, pGVM->hSelf, 0 /*fChunkFlags*/, NULL);
if (RT_SUCCESS(rc))
- {
- /*
- * Add a new chunk with our hGVM.
- */
- rc = gmmR0RegisterChunk(pGMM, &pGMM->Private, MemObj, pGVM->hSelf, GMMCHUNKTYPE_NON_CONTINUOUS);
- RTSemFastMutexRelease(pGMM->Mtx);
- }
-
- if (RT_FAILURE(rc))
+ gmmR0MutexRelease(pGMM);
+ else
RTR0MemObjFree(MemObj, false /* fFreeMappings */);
}
@@ -3478,6 +4114,7 @@ GMMR0DECL(int) GMMR0SeedChunk(PVM pVM, VMCPUID idCpu, RTR3PTR pvR3)
return rc;
}
+
typedef struct
{
PAVLGCPTRNODECORE pNode;
@@ -3540,8 +4177,7 @@ GMMR0DECL(int) GMMR0RegisterSharedModule(PVM pVM, VMCPUID idCpu, VBOXOSFAMILY en
/*
* Take the semaphore and do some more validations.
*/
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
bool fNewModule = false;
@@ -3681,7 +4317,7 @@ GMMR0DECL(int) GMMR0RegisterSharedModule(PVM pVM, VMCPUID idCpu, VBOXOSFAMILY en
rc = VERR_INTERNAL_ERROR_5;
end:
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
return rc;
#else
return VERR_NOT_IMPLEMENTED;
@@ -3711,6 +4347,7 @@ GMMR0DECL(int) GMMR0RegisterSharedModuleReq(PVM pVM, VMCPUID idCpu, PGMMREGISTE
return VINF_SUCCESS;
}
+
/**
* Unregisters a shared module for the VM
*
@@ -3740,8 +4377,7 @@ GMMR0DECL(int) GMMR0UnregisterSharedModule(PVM pVM, VMCPUID idCpu, char *pszModu
/*
* Take the semaphore and do some more validations.
*/
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
PGMMSHAREDMODULEPERVM pRecVM = (PGMMSHAREDMODULEPERVM)RTAvlGCPtrGet(&pGVM->gmm.s.pSharedModuleTree, GCBaseAddr);
@@ -3797,13 +4433,14 @@ GMMR0DECL(int) GMMR0UnregisterSharedModule(PVM pVM, VMCPUID idCpu, char *pszModu
else
rc = VERR_INTERNAL_ERROR_5;
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
return rc;
#else
return VERR_NOT_IMPLEMENTED;
#endif
}
+
/**
* VMMR0 request wrapper for GMMR0UnregisterSharedModule.
*
@@ -3824,8 +4461,59 @@ GMMR0DECL(int) GMMR0UnregisterSharedModuleReq(PVM pVM, VMCPUID idCpu, PGMMUNREG
return GMMR0UnregisterSharedModule(pVM, idCpu, pReq->szName, pReq->szVersion, pReq->GCBaseAddr, pReq->cbModule);
}
-
#ifdef VBOX_WITH_PAGE_SHARING
+
+/**
+ * Increase the use count of a shared page, the page is known to exist and be valid and such.
+ *
+ * @param pGMM Pointer to the GMM instance.
+ * @param pGVM Pointer to the GVM instance.
+ * @param pPage The page structure.
+ */
+DECLINLINE(void) gmmR0UseSharedPage(PGMM pGMM, PGVM pGVM, PGMMPAGE pPage)
+{
+ Assert(pGMM->cSharedPages > 0);
+ Assert(pGMM->cAllocatedPages > 0);
+
+ pGMM->cDuplicatePages++;
+
+ pPage->Shared.cRefs++;
+ pGVM->gmm.s.cSharedPages++;
+ pGVM->gmm.s.Allocated.cBasePages++;
+}
+
+
+/**
+ * Converts a private page to a shared page, the page is known to exist and be valid and such.
+ *
+ * @param pGMM Pointer to the GMM instance.
+ * @param pGVM Pointer to the GVM instance.
+ * @param HCPhys Host physical address
+ * @param idPage The Page ID
+ * @param pPage The page structure.
+ */
+DECLINLINE(void) gmmR0ConvertToSharedPage(PGMM pGMM, PGVM pGVM, RTHCPHYS HCPhys, uint32_t idPage, PGMMPAGE pPage)
+{
+ PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, idPage >> GMM_CHUNKID_SHIFT);
+ Assert(pChunk);
+ Assert(pChunk->cFree < GMM_CHUNK_NUM_PAGES);
+ Assert(GMM_PAGE_IS_PRIVATE(pPage));
+
+ pChunk->cPrivate--;
+ pChunk->cShared++;
+
+ pGMM->cSharedPages++;
+
+ pGVM->gmm.s.cSharedPages++;
+ pGVM->gmm.s.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;
+}
+
+
/**
* Checks specified shared module range for changes
*
@@ -3935,7 +4623,7 @@ new_shared_page:
pChunk = gmmR0GetChunk(pGMM, pPageDesc->uHCPhysPageId >> GMM_CHUNKID_SHIFT);
if (pChunk)
{
- if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk))
+ if (!gmmR0IsChunkMapped(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk))
{
Log(("GMMR0SharedModuleCheckPage: Invalid idPage=%#x #3\n", pPageDesc->uHCPhysPageId));
AssertFailed();
@@ -3957,10 +4645,10 @@ new_shared_page:
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(pGVM, pChunk, (PRTR3PTR)&pbChunk))
+ if (!gmmR0IsChunkMapped(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk))
{
Log(("Map chunk into process!\n"));
- rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk);
+ rc = gmmR0MapChunk(pGMM, pGVM, pChunk, false /*fRelaxedSem*/, (PRTR3PTR)&pbChunk);
if (rc != VINF_SUCCESS)
{
AssertRC(rc);
@@ -3995,36 +4683,37 @@ end:
return rc;
}
+
/**
- * RTAvlU32Destroy callback.
+ * RTAvlGCPtrDestroy callback.
*
- * @returns 0
+ * @returns 0 or VERR_INTERNAL_ERROR.
* @param pNode The node to destroy.
* @param pvGVM The GVM handle.
*/
static DECLCALLBACK(int) gmmR0CleanupSharedModule(PAVLGCPTRNODECORE pNode, void *pvGVM)
{
- PGVM pGVM = (PGVM)pvGVM;
- PGMMSHAREDMODULEPERVM pRecVM = (PGMMSHAREDMODULEPERVM)pNode;
- PGMM pGMM;
- GMM_GET_VALID_INSTANCE(pGMM, VERR_INTERNAL_ERROR);
+ PGVM pGVM = (PGVM)pvGVM;
+ PGMMSHAREDMODULEPERVM pRecVM = (PGMMSHAREDMODULEPERVM)pNode;
Assert(pRecVM->pGlobalModule || pRecVM->fCollision);
if (pRecVM->pGlobalModule)
{
PGMMSHAREDMODULE pRec = pRecVM->pGlobalModule;
- Assert(pRec);
+ 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 (unsigned i = 0; i < pRec->cRegions; i++)
+ 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_INTERNAL_ERROR);
RTAvlGCPtrRemove(&pGMM->pGlobalSharedModuleTree, pRec->Core.Key);
RTMemFree(pRec);
}
@@ -4032,7 +4721,28 @@ static DECLCALLBACK(int) gmmR0CleanupSharedModule(PAVLGCPTRNODECORE pNode, void
RTMemFree(pRecVM);
return 0;
}
-#endif
+
+
+/**
+ * Used by GMMR0CleanupVM to clean up shared modules.
+ *
+ * This is called without taking the GMM lock so that it can be yielded as
+ * needed here.
+ *
+ * @param pGMM The GMM handle.
+ * @param pGVM The global VM handle.
+ */
+static void gmmR0SharedModuleCleanup(PGMM pGMM, PGVM pGVM)
+{
+ gmmR0MutexAcquire(pGMM);
+ GMM_CHECK_SANITY_UPON_ENTERING(pGMM);
+
+ RTAvlGCPtrDestroy(&pGVM->gmm.s.pSharedModuleTree, gmmR0CleanupSharedModule, pGVM);
+
+ gmmR0MutexRelease(pGMM);
+}
+
+#endif /* VBOX_WITH_PAGE_SHARING */
/**
* Removes all shared modules for the specified VM
@@ -4057,8 +4767,7 @@ GMMR0DECL(int) GMMR0ResetSharedModules(PVM pVM, VMCPUID idCpu)
/*
* Take the semaphore and do some more validations.
*/
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
Log(("GMMR0ResetSharedModules\n"));
@@ -4070,7 +4779,7 @@ GMMR0DECL(int) GMMR0ResetSharedModules(PVM pVM, VMCPUID idCpu)
else
rc = VERR_INTERNAL_ERROR_5;
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
return rc;
#else
return VERR_NOT_IMPLEMENTED;
@@ -4078,6 +4787,7 @@ GMMR0DECL(int) GMMR0ResetSharedModules(PVM pVM, VMCPUID idCpu)
}
#ifdef VBOX_WITH_PAGE_SHARING
+
typedef struct
{
PGVM pGVM;
@@ -4104,9 +4814,10 @@ DECLCALLBACK(int) gmmR0CheckSharedModule(PAVLGCPTRNODECORE pNode, void *pvUser)
}
return 0;
}
-#endif
+#endif /* VBOX_WITH_PAGE_SHARING */
#ifdef DEBUG_sandervl
+
/**
* Setup for a GMMR0CheckSharedModules call (to allow log flush jumps back to ring 3)
*
@@ -4124,8 +4835,7 @@ GMMR0DECL(int) GMMR0CheckSharedModulesStart(PVM pVM)
/*
* Take the semaphore and do some more validations.
*/
- int rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
if (!GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
rc = VERR_INTERNAL_ERROR_5;
else
@@ -4148,10 +4858,11 @@ GMMR0DECL(int) GMMR0CheckSharedModulesEnd(PVM pVM)
PGMM pGMM;
GMM_GET_VALID_INSTANCE(pGMM, VERR_INTERNAL_ERROR);
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
return VINF_SUCCESS;
}
-#endif
+
+#endif /* DEBUG_sandervl */
/**
* Check all shared modules for the specified VM
@@ -4177,8 +4888,7 @@ GMMR0DECL(int) GMMR0CheckSharedModules(PVM pVM, PVMCPU pVCpu)
/*
* Take the semaphore and do some more validations.
*/
- rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ gmmR0MutexAcquire(pGMM);
# endif
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
@@ -4201,7 +4911,7 @@ GMMR0DECL(int) GMMR0CheckSharedModules(PVM pVM, PVMCPU pVCpu)
rc = VERR_INTERNAL_ERROR_5;
# ifndef DEBUG_sandervl
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
# endif
return rc;
#else
@@ -4210,6 +4920,7 @@ GMMR0DECL(int) GMMR0CheckSharedModules(PVM pVM, PVMCPU pVCpu)
}
#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
+
typedef struct
{
PGVM pGVM;
@@ -4228,44 +4939,41 @@ typedef struct
static DECLCALLBACK(int) gmmR0FindDupPageInChunk(PAVLU32NODECORE pNode, void *pvInfo)
{
PGMMCHUNK pChunk = (PGMMCHUNK)pNode;
- PGMMFINDDUPPAGEINFO pInfo = (PGMMFINDDUPPAGEINFO)pvInfo;
- PGVM pGVM = pInfo->pGVM;
- PGMM pGMM = pInfo->pGMM;
+ PGMMFINDDUPPAGEINFO pInfo = (PGMMFINDDUPPAGEINFO)pvInfo;
+ PGVM pGVM = pInfo->pGVM;
+ PGMM pGMM = pInfo->pGMM;
uint8_t *pbChunk;
/* Only take chunks not mapped into this VM process; not entirely correct. */
- if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk))
+ if (!gmmR0IsChunkMapped(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk))
{
- int rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk);
- if (rc != VINF_SUCCESS)
- goto end;
-
- /*
- * Look for duplicate pages
- */
- unsigned iPage = (GMM_CHUNK_SIZE >> PAGE_SHIFT);
- while (iPage-- > 0)
+ int rc = gmmR0MapChunk(pGMM, pGVM, pChunk, false /*fRelaxedSem*/, (PRTR3PTR)&pbChunk);
+ if (RT_SUCCESS(rc))
{
- if (GMM_PAGE_IS_PRIVATE(&pChunk->aPages[iPage]))
+ /*
+ * Look for duplicate pages
+ */
+ unsigned iPage = (GMM_CHUNK_SIZE >> PAGE_SHIFT);
+ while (iPage-- > 0)
{
- uint8_t *pbDestPage = pbChunk + (iPage << PAGE_SHIFT);
-
- if (!memcmp(pInfo->pSourcePage, pbDestPage, PAGE_SIZE))
+ if (GMM_PAGE_IS_PRIVATE(&pChunk->aPages[iPage]))
{
- pInfo->fFoundDuplicate = true;
- break;
+ uint8_t *pbDestPage = pbChunk + (iPage << PAGE_SHIFT);
+
+ if (!memcmp(pInfo->pSourcePage, pbDestPage, PAGE_SIZE))
+ {
+ pInfo->fFoundDuplicate = true;
+ break;
+ }
}
}
+ gmmR0UnmapChunk(pGMM, pGVM, pChunk, false /*fRelaxedSem*/);
}
- gmmR0UnmapChunk(pGMM, pGVM, pChunk);
}
-end:
- if (pInfo->fFoundDuplicate)
- return 1; /* stop search */
- else
- return 0;
+ return pInfo->fFoundDuplicate; /* (stops search if true) */
}
+
/**
* Find a duplicate of the specified page in other active VMs
*
@@ -4285,56 +4993,52 @@ GMMR0DECL(int) GMMR0FindDuplicatePageReq(PVM pVM, PGMMFINDDUPLICATEPAGEREQ pReq)
PGMM pGMM;
GMM_GET_VALID_INSTANCE(pGMM, VERR_INTERNAL_ERROR);
+ PGVM pGVM;
+ int rc = GVMMR0ByVM(pVM, &pGVM);
+ if (RT_FAILURE(rc))
+ return rc;
+
/*
* Take the semaphore and do some more validations.
*/
- int rc = RTSemFastMutexRequest(pGMM->Mtx);
- AssertRC(rc);
+ rc = gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
- PGVM pGVM;
- rc = GVMMR0ByVM(pVM, &pGVM);
- if (RT_FAILURE(rc))
- goto end;
-
uint8_t *pbChunk;
PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, pReq->idPage >> GMM_CHUNKID_SHIFT);
- if (!pChunk)
- {
- AssertFailed();
- goto end;
- }
-
- if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk))
+ if (pChunk)
{
- AssertFailed();
- goto end;
+ if (gmmR0IsChunkMapped(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk))
+ {
+ uint8_t *pbSourcePage = pbChunk + ((pReq->idPage & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
+ 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;
+ }
+ else
+ {
+ AssertFailed();
+ rc = VERR_PGM_PHYS_INVALID_PAGE_ID;
+ }
+ }
+ else
+ AssertFailed();
}
-
- uint8_t *pbSourcePage = pbChunk + ((pReq->idPage & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
-
- PGMMPAGE pPage = gmmR0GetPage(pGMM, pReq->idPage);
- if (!pPage)
- {
+ else
AssertFailed();
- rc = VERR_PGM_PHYS_INVALID_PAGE_ID;
- goto end;
- }
- 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;
}
else
rc = VERR_INTERNAL_ERROR_5;
-end:
- RTSemFastMutexRelease(pGMM->Mtx);
+ gmmR0MutexRelease(pGMM);
return rc;
}
diff --git a/src/VBox/VMM/VMMR0/GMMR0Internal.h b/src/VBox/VMM/VMMR0/GMMR0Internal.h
index 9cc9d0b7a..8c4b2d867 100644
--- a/src/VBox/VMM/VMMR0/GMMR0Internal.h
+++ b/src/VBox/VMM/VMMR0/GMMR0Internal.h
@@ -1,4 +1,4 @@
-/* $Id: GMMR0Internal.h $ */
+/* $Id: GMMR0Internal.h 37248 2011-05-30 10:02:24Z vboxsync $ */
/** @file
* GMM - The Global Memory Manager, Internal Header.
*/
@@ -63,11 +63,42 @@ typedef struct GMMSHAREDMODULEPERVM
/** Pointer to a GMMSHAREDMODULEPERVM. */
typedef GMMSHAREDMODULEPERVM *PGMMSHAREDMODULEPERVM;
+
+/** Pointer to a GMM allocation chunk. */
+typedef struct GMMCHUNK *PGMMCHUNK;
+
+
+/** The GMMCHUNK::cFree shift count employed by gmmR0SelectFreeSetList. */
+#define GMM_CHUNK_FREE_SET_SHIFT 4
+/** Index of the list containing completely unused chunks.
+ * The code ASSUMES this is the last list. */
+#define GMM_CHUNK_FREE_SET_UNUSED_LIST (GMM_CHUNK_NUM_PAGES >> GMM_CHUNK_FREE_SET_SHIFT)
+
+/**
+ * A set of free chunks.
+ */
+typedef struct GMMCHUNKFREESET
+{
+ /** The number of free pages in the set. */
+ uint64_t cFreePages;
+ /** The generation ID for the set. This is incremented whenever
+ * something is linked or unlinked from this set. */
+ uint64_t idGeneration;
+ /** Chunks ordered by increasing number of free pages.
+ * In the final list the chunks are completely unused. */
+ PGMMCHUNK apLists[GMM_CHUNK_FREE_SET_UNUSED_LIST + 1];
+} GMMCHUNKFREESET;
+
+
+
/**
* The per-VM GMM data.
*/
typedef struct GMMPERVM
{
+ /** Free set for use in bound mode. */
+ GMMCHUNKFREESET Private;
+
/** The reservations. */
GMMVMSIZES Reserved;
/** The actual allocations.
@@ -83,6 +114,8 @@ typedef struct GMMPERVM
/** 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;
diff --git a/src/VBox/VMM/VMMR0/GVMMR0.cpp b/src/VBox/VMM/VMMR0/GVMMR0.cpp
index 725eae6a3..e08830329 100644
--- a/src/VBox/VMM/VMMR0/GVMMR0.cpp
+++ b/src/VBox/VMM/VMMR0/GVMMR0.cpp
@@ -1,4 +1,4 @@
-/* $Id: GVMMR0.cpp $ */
+/* $Id: GVMMR0.cpp 37465 2011-06-15 10:07:58Z vboxsync $ */
/** @file
* GVMM - Global VM Manager.
*/
@@ -99,6 +99,9 @@ typedef struct GVMHANDLE
uint16_t volatile iNext;
/** Our own index / handle value. */
uint16_t iSelf;
+ /** The process ID of the handle owner.
+ * This is used for access checks. */
+ RTPROCESS ProcId;
/** The pointer to the ring-0 only (aka global) VM structure. */
PGVM pGVM;
/** The ring-0 mapping of the shared VM instance data. */
@@ -111,16 +114,13 @@ typedef struct GVMHANDLE
* This is used for ownership checks as well as looking up a VM handle by thread
* at times like assertions. */
RTNATIVETHREAD hEMT0;
- /** The process ID of the handle owner.
- * This is used for access checks. */
- RTPROCESS ProcId;
} GVMHANDLE;
/** Pointer to a global VM handle. */
typedef GVMHANDLE *PGVMHANDLE;
/** Number of GVM handles (including the NIL handle). */
#if HC_ARCH_BITS == 64
-# define GVMM_MAX_HANDLES 1024
+# define GVMM_MAX_HANDLES 8192
#else
# define GVMM_MAX_HANDLES 128
#endif
@@ -833,6 +833,9 @@ GVMMR0DECL(int) GVMMR0CreateVM(PSUPDRVSESSION pSession, uint32_t cCpus, PVM *ppV
pVM->cCpus = cCpus;
pVM->uCpuExecutionCap = 100; /* default is no cap. */
pVM->offVMCPU = RT_UOFFSETOF(VM, aCpus);
+ AssertCompileMemberAlignment(VM, cpum, 64);
+ AssertCompileMemberAlignment(VM, tm, 64);
+ AssertCompileMemberAlignment(VM, aCpus, PAGE_SIZE);
rc = RTR0MemObjAllocPage(&pGVM->gvmm.s.VMPagesMemObj, cPages * sizeof(SUPPAGE), false /* fExecutable */);
if (RT_SUCCESS(rc))
@@ -1293,7 +1296,7 @@ static DECLCALLBACK(void) gvmmR0HandleObjDestructor(void *pvObj, void *pvGVMM, v
ASMAtomicWriteNullPtr(&pHandle->pVM);
ASMAtomicWriteNullPtr(&pHandle->pvObj);
ASMAtomicWriteNullPtr(&pHandle->pSession);
- ASMAtomicWriteSize(&pHandle->hEMT0, NIL_RTNATIVETHREAD);
+ ASMAtomicWriteHandle(&pHandle->hEMT0, NIL_RTNATIVETHREAD);
ASMAtomicWriteSize(&pHandle->ProcId, NIL_RTPROCESS);
gvmmR0UsedUnlock(pGVMM);
diff --git a/src/VBox/VMM/VMMR0/GVMMR0Internal.h b/src/VBox/VMM/VMMR0/GVMMR0Internal.h
index 40b1b0003..053257206 100644
--- a/src/VBox/VMM/VMMR0/GVMMR0Internal.h
+++ b/src/VBox/VMM/VMMR0/GVMMR0Internal.h
@@ -1,4 +1,4 @@
-/* $Id: GVMMR0Internal.h $ */
+/* $Id: GVMMR0Internal.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* GVMM - The Global VM Manager, Internal header.
*/
diff --git a/src/VBox/VMM/VMMR0/HWACCMR0.cpp b/src/VBox/VMM/VMMR0/HWACCMR0.cpp
index 03352180e..b7a0120eb 100644
--- a/src/VBox/VMM/VMMR0/HWACCMR0.cpp
+++ b/src/VBox/VMM/VMMR0/HWACCMR0.cpp
@@ -1,10 +1,10 @@
-/* $Id: HWACCMR0.cpp $ */
+/* $Id: HWACCMR0.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
- * HWACCM - Host Context Ring 0.
+ * Hardware Assisted Virtualization Manager - Host Context Ring-0.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -24,7 +24,6 @@
#include <VBox/vmm/pgm.h>
#include "HWACCMInternal.h"
#include <VBox/vmm/vm.h>
-#include <VBox/x86.h>
#include <VBox/vmm/hwacc_vmx.h>
#include <VBox/vmm/hwacc_svm.h>
#include <VBox/err.h>
@@ -35,45 +34,73 @@
#include <iprt/cpuset.h>
#include <iprt/mem.h>
#include <iprt/memobj.h>
+#include <iprt/once.h>
#include <iprt/param.h>
#include <iprt/power.h>
#include <iprt/string.h>
#include <iprt/thread.h>
+#include <iprt/x86.h>
#include "HWVMXR0.h"
#include "HWSVMR0.h"
+
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
-static DECLCALLBACK(void) hwaccmR0EnableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2);
-static DECLCALLBACK(void) hwaccmR0DisableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2);
-static DECLCALLBACK(void) hwaccmR0InitCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2);
-static bool hwaccmR0IsSubjectToVmxPreemptionTimerErratum(void);
-static DECLCALLBACK(void) hwaccmR0PowerCallback(RTPOWEREVENT enmEvent, void *pvUser);
+static DECLCALLBACK(void) hmR0EnableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2);
+static DECLCALLBACK(void) hmR0DisableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2);
+static DECLCALLBACK(void) hmR0InitIntelCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2);
+static DECLCALLBACK(void) hmR0InitAmdCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2);
+static DECLCALLBACK(void) hmR0PowerCallback(RTPOWEREVENT enmEvent, void *pvUser);
+static DECLCALLBACK(void) hmR0MpEventCallback(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvData);
+
/*******************************************************************************
-* Global Variables *
+* Structures and Typedefs *
*******************************************************************************/
+/**
+ * This is used to manage the status code of a RTMpOnAll in HM.
+ */
+typedef struct HMR0FIRSTRC
+{
+ /** The status code. */
+ int32_t volatile rc;
+ /** The ID of the CPU reporting the first failure. */
+ RTCPUID volatile idCpu;
+} HMR0FIRSTRC;
+/** Pointer to a first return code structure. */
+typedef HMR0FIRSTRC *PHMR0FIRSTRC;
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/**
+ * Global data.
+ */
static struct
{
- HWACCM_CPUINFO aCpuInfo[RTCPUSET_MAX_CPUS];
+ /** Per CPU globals. */
+ HMGLOBLCPUINFO aCpuInfo[RTCPUSET_MAX_CPUS];
- /** Ring 0 handlers for VT-x and AMD-V. */
- DECLR0CALLBACKMEMBER(int, pfnEnterSession,(PVM pVM, PVMCPU pVCpu, PHWACCM_CPUINFO pCpu));
+ /** @name Ring-0 method table for AMD-V and VT-x specific operations.
+ * @{ */
+ DECLR0CALLBACKMEMBER(int, pfnEnterSession,(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu));
DECLR0CALLBACKMEMBER(int, pfnLeaveSession,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx));
DECLR0CALLBACKMEMBER(int, pfnSaveHostState,(PVM pVM, PVMCPU pVCpu));
DECLR0CALLBACKMEMBER(int, pfnLoadGuestState,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx));
DECLR0CALLBACKMEMBER(int, pfnRunGuestCode,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx));
- DECLR0CALLBACKMEMBER(int, pfnEnableCpu, (PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys));
- DECLR0CALLBACKMEMBER(int, pfnDisableCpu, (PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys));
- DECLR0CALLBACKMEMBER(int, pfnInitVM, (PVM pVM));
- DECLR0CALLBACKMEMBER(int, pfnTermVM, (PVM pVM));
- DECLR0CALLBACKMEMBER(int, pfnSetupVM, (PVM pVM));
+ DECLR0CALLBACKMEMBER(int, pfnEnableCpu,(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage));
+ DECLR0CALLBACKMEMBER(int, pfnDisableCpu,(PHMGLOBLCPUINFO pCpu, void *pvCpuPage, RTHCPHYS HCPhysCpuPage));
+ DECLR0CALLBACKMEMBER(int, pfnInitVM,(PVM pVM));
+ DECLR0CALLBACKMEMBER(int, pfnTermVM,(PVM pVM));
+ DECLR0CALLBACKMEMBER(int, pfnSetupVM,(PVM pVM));
+ /** @} */
/** Maximum ASID allowed. */
uint32_t uMaxASID;
+ /** VT-x data. */
struct
{
/** Set to by us to indicate VMX is supported by the CPU. */
@@ -112,6 +139,8 @@ static struct
/* Last instruction error */
uint32_t ulLastInstrError;
} vmx;
+
+ /** AMD-V information. */
struct
{
/* HWCR msr (for diagnostics) */
@@ -135,25 +164,22 @@ static struct
uint32_t u32AMDFeatureEDX;
} cpuid;
- HWACCMSTATE enmHwAccmState;
-
+ /** If set, VT-x/AMD-V is enabled globally at init time, otherwise it's
+ * enabled and disabled each time it's used to execute guest code. */
bool fGlobalInit;
+ /** Indicates whether the host is suspending or not. We'll refuse a few
+ * actions when the host is being suspended to speed up the suspending and
+ * avoid trouble. */
volatile bool fSuspended;
-} HWACCMR0Globals;
+ /** Whether we've already initialized all CPUs.
+ * @remarks We could check the EnableAllCpusOnce state, but this is
+ * simpler and hopefully easier to understand. */
+ bool fEnabled;
+ /** Serialize initialization in HWACCMR0EnableAllCpus. */
+ RTONCE EnableAllCpusOnce;
+} g_HvmR0;
-/**
- * This is used to manage the status code of a RTMpOnAll in HWACCM.
- */
-typedef struct HWACCMR0FIRSTRC
-{
- /** The status code. */
- int32_t volatile rc;
- /** The ID of the CPU reporting the first failure. */
- RTCPUID volatile idCpu;
-} HWACCMR0FIRSTRC;
-/** Pointer to a first return code structure. */
-typedef HWACCMR0FIRSTRC *PHWACCMR0FIRSTRC;
/**
@@ -161,7 +187,7 @@ typedef HWACCMR0FIRSTRC *PHWACCMR0FIRSTRC;
*
* @param pFirstRc The structure to init.
*/
-static void hwaccmR0FirstRcInit(PHWACCMR0FIRSTRC pFirstRc)
+static void hmR0FirstRcInit(PHMR0FIRSTRC pFirstRc)
{
pFirstRc->rc = VINF_SUCCESS;
pFirstRc->idCpu = NIL_RTCPUID;
@@ -174,7 +200,7 @@ static void hwaccmR0FirstRcInit(PHWACCMR0FIRSTRC pFirstRc)
* @param pFirstRc The first return code structure.
* @param rc The status code.
*/
-static void hwaccmR0FirstRcSetStatus(PHWACCMR0FIRSTRC pFirstRc, int rc)
+static void hmR0FirstRcSetStatus(PHMR0FIRSTRC pFirstRc, int rc)
{
if ( RT_FAILURE(rc)
&& ASMAtomicCmpXchgS32(&pFirstRc->rc, rc, VINF_SUCCESS))
@@ -189,7 +215,7 @@ static void hwaccmR0FirstRcSetStatus(PHWACCMR0FIRSTRC pFirstRc, int rc)
* warning errors.
* @param pFirstRc The first return code structure.
*/
-static int hwaccmR0FirstRcGetStatus(PHWACCMR0FIRSTRC pFirstRc)
+static int hmR0FirstRcGetStatus(PHMR0FIRSTRC pFirstRc)
{
return pFirstRc->rc;
}
@@ -201,309 +227,67 @@ static int hwaccmR0FirstRcGetStatus(PHWACCMR0FIRSTRC pFirstRc)
* @returns The CPU ID, NIL_RTCPUID if no failure was reported.
* @param pFirstRc The first return code structure.
*/
-static RTCPUID hwaccmR0FirstRcGetCpuId(PHWACCMR0FIRSTRC pFirstRc)
+static RTCPUID hmR0FirstRcGetCpuId(PHMR0FIRSTRC pFirstRc)
{
return pFirstRc->idCpu;
}
-/**
- * Does global Ring-0 HWACCM initialization.
- *
- * @returns VBox status code.
- */
-VMMR0DECL(int) HWACCMR0Init(void)
-{
- int rc;
- bool fAMDVPresent = false;
-
- HWACCMR0Globals.enmHwAccmState = HWACCMSTATE_UNINITIALIZED;
- for (unsigned i = 0; i < RT_ELEMENTS(HWACCMR0Globals.aCpuInfo); i++)
- HWACCMR0Globals.aCpuInfo[i].pMemObj = NIL_RTR0MEMOBJ;
-
- /* Fill in all callbacks with placeholders. */
- HWACCMR0Globals.pfnEnterSession = HWACCMR0DummyEnter;
- HWACCMR0Globals.pfnLeaveSession = HWACCMR0DummyLeave;
- HWACCMR0Globals.pfnSaveHostState = HWACCMR0DummySaveHostState;
- HWACCMR0Globals.pfnLoadGuestState = HWACCMR0DummyLoadGuestState;
- HWACCMR0Globals.pfnRunGuestCode = HWACCMR0DummyRunGuestCode;
- HWACCMR0Globals.pfnEnableCpu = HWACCMR0DummyEnableCpu;
- HWACCMR0Globals.pfnDisableCpu = HWACCMR0DummyDisableCpu;
- HWACCMR0Globals.pfnInitVM = HWACCMR0DummyInitVM;
- HWACCMR0Globals.pfnTermVM = HWACCMR0DummyTermVM;
- HWACCMR0Globals.pfnSetupVM = HWACCMR0DummySetupVM;
-
- /* Default is global VT-x/AMD-V init */
- HWACCMR0Globals.fGlobalInit = true;
-
- /*
- * Make sure aCpuInfo is big enough for all the CPUs on this system.
- */
- if (RTMpGetArraySize() > RT_ELEMENTS(HWACCMR0Globals.aCpuInfo))
- {
- LogRel(("HWACCM: Too many real CPUs/cores/threads - %u, max %u\n", RTMpGetArraySize(), RT_ELEMENTS(HWACCMR0Globals.aCpuInfo)));
- return VERR_TOO_MANY_CPUS;
- }
-
- /*
- * Check for VT-x and AMD-V capabilities
- */
- if (ASMHasCpuId())
- {
- uint32_t u32FeaturesECX;
- uint32_t u32Dummy;
- uint32_t u32FeaturesEDX;
- uint32_t u32VendorEBX, u32VendorECX, u32VendorEDX;
+/** @name Dummy callback handlers.
+ * @{ */
- ASMCpuId(0, &u32Dummy, &u32VendorEBX, &u32VendorECX, &u32VendorEDX);
- ASMCpuId(1, &u32Dummy, &u32Dummy, &u32FeaturesECX, &u32FeaturesEDX);
- /* Query AMD features. */
- ASMCpuId(0x80000001, &u32Dummy, &u32Dummy, &HWACCMR0Globals.cpuid.u32AMDFeatureECX, &HWACCMR0Globals.cpuid.u32AMDFeatureEDX);
+static DECLCALLBACK(int) hmR0DummyEnter(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu)
+{
+ return VINF_SUCCESS;
+}
- if ( u32VendorEBX == X86_CPUID_VENDOR_INTEL_EBX
- && u32VendorECX == X86_CPUID_VENDOR_INTEL_ECX
- && u32VendorEDX == X86_CPUID_VENDOR_INTEL_EDX
- )
- {
- /*
- * Read all VMX MSRs if VMX is available. (same goes for RDMSR/WRMSR)
- * We also assume all VMX-enabled CPUs support fxsave/fxrstor.
- */
- if ( (u32FeaturesECX & X86_CPUID_FEATURE_ECX_VMX)
- && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
- && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
- )
- {
- HWACCMR0Globals.vmx.msr.feature_ctrl = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+static DECLCALLBACK(int) hmR0DummyLeave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+ return VINF_SUCCESS;
+}
- /*
- * First try use native kernel API for controlling VT-x.
- * (This is only supported by some Mac OS X kernels atm.)
- */
- HWACCMR0Globals.lLastError = rc = SUPR0EnableVTx(true /* fEnable */);
- if (rc != VERR_NOT_SUPPORTED)
- {
- AssertMsg(rc == VINF_SUCCESS || rc == VERR_VMX_IN_VMX_ROOT_MODE || rc == VERR_VMX_NO_VMX, ("%Rrc\n", rc));
- HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx = true;
- if (RT_SUCCESS(rc))
- {
- HWACCMR0Globals.vmx.fSupported = true;
- rc = SUPR0EnableVTx(false /* fEnable */);
- AssertRC(rc);
- }
- }
- else
- {
- HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx = false;
-
- /* We need to check if VT-x has been properly initialized on all CPUs. Some BIOSes do a lousy job. */
- HWACCMR0FIRSTRC FirstRc;
- hwaccmR0FirstRcInit(&FirstRc);
- HWACCMR0Globals.lLastError = RTMpOnAll(hwaccmR0InitCpu, (void *)(uintptr_t)u32VendorEBX, &FirstRc);
- if (RT_SUCCESS(HWACCMR0Globals.lLastError))
- HWACCMR0Globals.lLastError = hwaccmR0FirstRcGetStatus(&FirstRc);
- }
- if (RT_SUCCESS(HWACCMR0Globals.lLastError))
- {
- /* Reread in case we've changed it. */
- HWACCMR0Globals.vmx.msr.feature_ctrl = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+static DECLCALLBACK(int) hmR0DummyEnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
+{
+ return VINF_SUCCESS;
+}
- if ( (HWACCMR0Globals.vmx.msr.feature_ctrl & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK))
- == (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK))
- {
- RTR0MEMOBJ pScatchMemObj;
- void *pvScatchPage;
- RTHCPHYS pScatchPagePhys;
-
- HWACCMR0Globals.vmx.msr.vmx_basic_info = ASMRdMsr(MSR_IA32_VMX_BASIC_INFO);
- HWACCMR0Globals.vmx.msr.vmx_pin_ctls.u = ASMRdMsr(MSR_IA32_VMX_PINBASED_CTLS);
- HWACCMR0Globals.vmx.msr.vmx_proc_ctls.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS);
- HWACCMR0Globals.vmx.msr.vmx_exit.u = ASMRdMsr(MSR_IA32_VMX_EXIT_CTLS);
- HWACCMR0Globals.vmx.msr.vmx_entry.u = ASMRdMsr(MSR_IA32_VMX_ENTRY_CTLS);
- HWACCMR0Globals.vmx.msr.vmx_misc = ASMRdMsr(MSR_IA32_VMX_MISC);
- HWACCMR0Globals.vmx.msr.vmx_cr0_fixed0 = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED0);
- HWACCMR0Globals.vmx.msr.vmx_cr0_fixed1 = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED1);
- HWACCMR0Globals.vmx.msr.vmx_cr4_fixed0 = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED0);
- HWACCMR0Globals.vmx.msr.vmx_cr4_fixed1 = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED1);
- HWACCMR0Globals.vmx.msr.vmx_vmcs_enum = ASMRdMsr(MSR_IA32_VMX_VMCS_ENUM);
- /* VPID 16 bits ASID. */
- HWACCMR0Globals.uMaxASID = 0x10000; /* exclusive */
-
- if (HWACCMR0Globals.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
- {
- HWACCMR0Globals.vmx.msr.vmx_proc_ctls2.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS2);
- if (HWACCMR0Globals.vmx.msr.vmx_proc_ctls2.n.allowed1 & (VMX_VMCS_CTRL_PROC_EXEC2_EPT|VMX_VMCS_CTRL_PROC_EXEC2_VPID))
- HWACCMR0Globals.vmx.msr.vmx_eptcaps = ASMRdMsr(MSR_IA32_VMX_EPT_CAPS);
- }
+static DECLCALLBACK(int) hmR0DummyDisableCpu(PHMGLOBLCPUINFO pCpu, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
+{
+ return VINF_SUCCESS;
+}
- if (!HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx)
- {
- HWACCMR0Globals.vmx.hostCR4 = ASMGetCR4();
- HWACCMR0Globals.vmx.hostEFER = ASMRdMsr(MSR_K6_EFER);
-
- rc = RTR0MemObjAllocCont(&pScatchMemObj, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
- if (RT_FAILURE(rc))
- return rc;
-
- pvScatchPage = RTR0MemObjAddress(pScatchMemObj);
- pScatchPagePhys = RTR0MemObjGetPagePhysAddr(pScatchMemObj, 0);
- memset(pvScatchPage, 0, PAGE_SIZE);
-
- /* Set revision dword at the beginning of the structure. */
- *(uint32_t *)pvScatchPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(HWACCMR0Globals.vmx.msr.vmx_basic_info);
-
- /* Make sure we don't get rescheduled to another cpu during this probe. */
- RTCCUINTREG fFlags = ASMIntDisableFlags();
-
- /*
- * Check CR4.VMXE
- */
- if (!(HWACCMR0Globals.vmx.hostCR4 & X86_CR4_VMXE))
- {
- /* In theory this bit could be cleared behind our back. Which would cause #UD faults when we
- * try to execute the VMX instructions...
- */
- ASMSetCR4(HWACCMR0Globals.vmx.hostCR4 | X86_CR4_VMXE);
- }
-
- /* Enter VMX Root Mode */
- rc = VMXEnable(pScatchPagePhys);
- if (RT_FAILURE(rc))
- {
- /* KVM leaves the CPU in VMX root mode. Not only is this not allowed, it will crash the host when we enter raw mode, because
- * (a) clearing X86_CR4_VMXE in CR4 causes a #GP (we no longer modify this bit)
- * (b) turning off paging causes a #GP (unavoidable when switching from long to 32 bits mode or 32 bits to PAE)
- *
- * They should fix their code, but until they do we simply refuse to run.
- */
- HWACCMR0Globals.lLastError = VERR_VMX_IN_VMX_ROOT_MODE;
- }
- else
- {
- HWACCMR0Globals.vmx.fSupported = true;
- VMXDisable();
-
- /*
- * Check for the VMX-Preemption Timer and adjust for the
- * "VMX-Preemption Timer Does Not Count Down at the Rate Specified" erratum.
- */
- if ( HWACCMR0Globals.vmx.msr.vmx_pin_ctls.n.allowed1
- & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
- {
- HWACCMR0Globals.vmx.fUsePreemptTimer = true;
- HWACCMR0Globals.vmx.cPreemptTimerShift = MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(HWACCMR0Globals.vmx.msr.vmx_misc);
- if (hwaccmR0IsSubjectToVmxPreemptionTimerErratum())
- HWACCMR0Globals.vmx.cPreemptTimerShift = 0; /* This is about right most of the time here. */
- }
- }
-
- /* Restore CR4 again; don't leave the X86_CR4_VMXE flag set if it wasn't so before (some software could incorrectly think it's in VMX mode) */
- ASMSetCR4(HWACCMR0Globals.vmx.hostCR4);
- ASMSetFlags(fFlags);
-
- RTR0MemObjFree(pScatchMemObj, false);
- if (RT_FAILURE(HWACCMR0Globals.lLastError))
- return HWACCMR0Globals.lLastError;
- }
- }
- else
- {
- AssertFailed(); /* can't hit this case anymore */
- HWACCMR0Globals.lLastError = VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR;
- }
- }
-#ifdef LOG_ENABLED
- else
- SUPR0Printf("hwaccmR0InitCpu failed with rc=%d\n", HWACCMR0Globals.lLastError);
-#endif
- }
- else
- HWACCMR0Globals.lLastError = VERR_VMX_NO_VMX;
- }
- else
- if ( u32VendorEBX == X86_CPUID_VENDOR_AMD_EBX
- && u32VendorECX == X86_CPUID_VENDOR_AMD_ECX
- && u32VendorEDX == X86_CPUID_VENDOR_AMD_EDX
- )
- {
- /*
- * Read all SVM MSRs if SVM is available. (same goes for RDMSR/WRMSR)
- * We also assume all SVM-enabled CPUs support fxsave/fxrstor.
- */
- if ( (HWACCMR0Globals.cpuid.u32AMDFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM)
- && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
- && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
- )
- {
- fAMDVPresent = true;
+static DECLCALLBACK(int) hmR0DummyInitVM(PVM pVM)
+{
+ return VINF_SUCCESS;
+}
- /* Query AMD features. */
- ASMCpuId(0x8000000A, &HWACCMR0Globals.svm.u32Rev, &HWACCMR0Globals.uMaxASID, &u32Dummy, &HWACCMR0Globals.svm.u32Features);
+static DECLCALLBACK(int) hmR0DummyTermVM(PVM pVM)
+{
+ return VINF_SUCCESS;
+}
- /* We need to check if AMD-V has been properly initialized on all CPUs. Some BIOSes might do a poor job. */
- HWACCMR0FIRSTRC FirstRc;
- hwaccmR0FirstRcInit(&FirstRc);
- rc = RTMpOnAll(hwaccmR0InitCpu, (void *)(uintptr_t)u32VendorEBX, &FirstRc); AssertRC(rc);
- if (RT_SUCCESS(rc))
- rc = hwaccmR0FirstRcGetStatus(&FirstRc);
-#ifndef DEBUG_bird
- AssertMsg(rc == VINF_SUCCESS || rc == VERR_SVM_IN_USE, ("hwaccmR0InitCpu failed for cpu %d with rc=%d\n", hwaccmR0FirstRcGetCpuId(&FirstRc), rc));
-#endif
- if (RT_SUCCESS(rc))
- {
- /* Read the HWCR msr for diagnostics. */
- HWACCMR0Globals.svm.msrHWCR = ASMRdMsr(MSR_K8_HWCR);
- HWACCMR0Globals.svm.fSupported = true;
- }
- else
- HWACCMR0Globals.lLastError = rc;
- }
- else
- HWACCMR0Globals.lLastError = VERR_SVM_NO_SVM;
- }
- else
- HWACCMR0Globals.lLastError = VERR_HWACCM_UNKNOWN_CPU;
- }
- else
- HWACCMR0Globals.lLastError = VERR_HWACCM_NO_CPUID;
+static DECLCALLBACK(int) hmR0DummySetupVM(PVM pVM)
+{
+ return VINF_SUCCESS;
+}
- if (HWACCMR0Globals.vmx.fSupported)
- {
- HWACCMR0Globals.pfnEnterSession = VMXR0Enter;
- HWACCMR0Globals.pfnLeaveSession = VMXR0Leave;
- HWACCMR0Globals.pfnSaveHostState = VMXR0SaveHostState;
- HWACCMR0Globals.pfnLoadGuestState = VMXR0LoadGuestState;
- HWACCMR0Globals.pfnRunGuestCode = VMXR0RunGuestCode;
- HWACCMR0Globals.pfnEnableCpu = VMXR0EnableCpu;
- HWACCMR0Globals.pfnDisableCpu = VMXR0DisableCpu;
- HWACCMR0Globals.pfnInitVM = VMXR0InitVM;
- HWACCMR0Globals.pfnTermVM = VMXR0TermVM;
- HWACCMR0Globals.pfnSetupVM = VMXR0SetupVM;
- }
- else
- if (fAMDVPresent)
- {
- HWACCMR0Globals.pfnEnterSession = SVMR0Enter;
- HWACCMR0Globals.pfnLeaveSession = SVMR0Leave;
- HWACCMR0Globals.pfnSaveHostState = SVMR0SaveHostState;
- HWACCMR0Globals.pfnLoadGuestState = SVMR0LoadGuestState;
- HWACCMR0Globals.pfnRunGuestCode = SVMR0RunGuestCode;
- HWACCMR0Globals.pfnEnableCpu = SVMR0EnableCpu;
- HWACCMR0Globals.pfnDisableCpu = SVMR0DisableCpu;
- HWACCMR0Globals.pfnInitVM = SVMR0InitVM;
- HWACCMR0Globals.pfnTermVM = SVMR0TermVM;
- HWACCMR0Globals.pfnSetupVM = SVMR0SetupVM;
- }
+static DECLCALLBACK(int) hmR0DummyRunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+ return VINF_SUCCESS;
+}
- if (!HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx)
- {
- rc = RTPowerNotificationRegister(hwaccmR0PowerCallback, 0);
- AssertRC(rc);
- }
+static DECLCALLBACK(int) hmR0DummySaveHostState(PVM pVM, PVMCPU pVCpu)
+{
+ return VINF_SUCCESS;
+}
+static DECLCALLBACK(int) hmR0DummyLoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
return VINF_SUCCESS;
}
+/** @} */
+
/**
* Checks if the CPU is subject to the "VMX-Preemption Timer Does Not Count
@@ -526,7 +310,7 @@ VMMR0DECL(int) HWACCMR0Init(void)
*
* @returns true if subject to it, false if not.
*/
-static bool hwaccmR0IsSubjectToVmxPreemptionTimerErratum(void)
+static bool hmR0InitIntelIsSubjectToVmxPreemptionTimerErratum(void)
{
uint32_t u = ASMCpuId_EAX(1);
u &= ~(RT_BIT_32(14) | RT_BIT_32(15) | RT_BIT_32(28) | RT_BIT_32(29) | RT_BIT_32(30) | RT_BIT_32(31));
@@ -551,222 +335,505 @@ static bool hwaccmR0IsSubjectToVmxPreemptionTimerErratum(void)
/**
- * Does global Ring-0 HWACCM termination.
+ * Intel specific initialization code.
*
- * @returns VBox status code.
+ * @returns VBox status code (will only fail if out of memory).
*/
-VMMR0DECL(int) HWACCMR0Term(void)
+static int hmR0InitIntel(uint32_t u32FeaturesECX, uint32_t u32FeaturesEDX)
{
- int rc;
- if ( HWACCMR0Globals.vmx.fSupported
- && HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx)
+ /*
+ * Check that all the required VT-x features are present.
+ * We also assume all VT-x-enabled CPUs support fxsave/fxrstor.
+ */
+ if ( (u32FeaturesECX & X86_CPUID_FEATURE_ECX_VMX)
+ && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
+ && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
+ )
{
- Assert(HWACCMR0Globals.fGlobalInit);
- rc = SUPR0EnableVTx(false /* fEnable */);
- for (unsigned iCpu = 0; iCpu < RT_ELEMENTS(HWACCMR0Globals.aCpuInfo); iCpu++)
+ /** @todo move this into a separate function. */
+ g_HvmR0.vmx.msr.feature_ctrl = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+
+ /*
+ * First try use native kernel API for controlling VT-x.
+ * (This is only supported by some Mac OS X kernels atm.)
+ */
+ int rc = g_HvmR0.lLastError = SUPR0EnableVTx(true /* fEnable */);
+ g_HvmR0.vmx.fUsingSUPR0EnableVTx = rc != VERR_NOT_SUPPORTED;
+ if (g_HvmR0.vmx.fUsingSUPR0EnableVTx)
{
- HWACCMR0Globals.aCpuInfo[iCpu].fConfigured = false;
- Assert(HWACCMR0Globals.aCpuInfo[iCpu].pMemObj == NIL_RTR0MEMOBJ);
+ AssertMsg(rc == VINF_SUCCESS || rc == VERR_VMX_IN_VMX_ROOT_MODE || rc == VERR_VMX_NO_VMX, ("%Rrc\n", rc));
+ if (RT_SUCCESS(rc))
+ {
+ g_HvmR0.vmx.fSupported = true;
+ rc = SUPR0EnableVTx(false /* fEnable */);
+ AssertRC(rc);
+ }
}
- }
- else
- {
- Assert(!HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx);
- if (!HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx)
+ else
{
- rc = RTPowerNotificationDeregister(hwaccmR0PowerCallback, 0);
- AssertRC(rc);
+ /* We need to check if VT-x has been properly initialized on all
+ CPUs. Some BIOSes do a lousy job. */
+ HMR0FIRSTRC FirstRc;
+ hmR0FirstRcInit(&FirstRc);
+ g_HvmR0.lLastError = RTMpOnAll(hmR0InitIntelCpu, &FirstRc, NULL);
+ if (RT_SUCCESS(g_HvmR0.lLastError))
+ g_HvmR0.lLastError = hmR0FirstRcGetStatus(&FirstRc);
}
- else
- rc = VINF_SUCCESS;
-
- /* Only disable VT-x/AMD-V on all CPUs if we enabled it before. */
- if (HWACCMR0Globals.fGlobalInit)
+ if (RT_SUCCESS(g_HvmR0.lLastError))
{
- HWACCMR0FIRSTRC FirstRc;
- hwaccmR0FirstRcInit(&FirstRc);
- rc = RTMpOnAll(hwaccmR0DisableCpuCallback, NULL, &FirstRc);
- Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
- if (RT_SUCCESS(rc))
+ /* Reread in case we've changed it. */
+ g_HvmR0.vmx.msr.feature_ctrl = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+
+ if ( (g_HvmR0.vmx.msr.feature_ctrl & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+ == (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+ {
+ /*
+ * Read all relevant MSR.
+ */
+ g_HvmR0.vmx.msr.vmx_basic_info = ASMRdMsr(MSR_IA32_VMX_BASIC_INFO);
+ g_HvmR0.vmx.msr.vmx_pin_ctls.u = ASMRdMsr(MSR_IA32_VMX_PINBASED_CTLS);
+ g_HvmR0.vmx.msr.vmx_proc_ctls.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS);
+ g_HvmR0.vmx.msr.vmx_exit.u = ASMRdMsr(MSR_IA32_VMX_EXIT_CTLS);
+ g_HvmR0.vmx.msr.vmx_entry.u = ASMRdMsr(MSR_IA32_VMX_ENTRY_CTLS);
+ g_HvmR0.vmx.msr.vmx_misc = ASMRdMsr(MSR_IA32_VMX_MISC);
+ g_HvmR0.vmx.msr.vmx_cr0_fixed0 = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED0);
+ g_HvmR0.vmx.msr.vmx_cr0_fixed1 = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED1);
+ g_HvmR0.vmx.msr.vmx_cr4_fixed0 = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED0);
+ g_HvmR0.vmx.msr.vmx_cr4_fixed1 = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED1);
+ g_HvmR0.vmx.msr.vmx_vmcs_enum = ASMRdMsr(MSR_IA32_VMX_VMCS_ENUM);
+ g_HvmR0.vmx.hostCR4 = ASMGetCR4();
+ g_HvmR0.vmx.hostEFER = ASMRdMsr(MSR_K6_EFER);
+ /* VPID 16 bits ASID. */
+ g_HvmR0.uMaxASID = 0x10000; /* exclusive */
+
+ if (g_HvmR0.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
+ {
+ g_HvmR0.vmx.msr.vmx_proc_ctls2.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS2);
+ if ( g_HvmR0.vmx.msr.vmx_proc_ctls2.n.allowed1
+ & (VMX_VMCS_CTRL_PROC_EXEC2_EPT | VMX_VMCS_CTRL_PROC_EXEC2_VPID))
+ g_HvmR0.vmx.msr.vmx_eptcaps = ASMRdMsr(MSR_IA32_VMX_EPT_CAPS);
+ }
+
+ if (!g_HvmR0.vmx.fUsingSUPR0EnableVTx)
+ {
+ /*
+ * Enter root mode
+ */
+ RTR0MEMOBJ hScatchMemObj;
+ rc = RTR0MemObjAllocCont(&hScatchMemObj, PAGE_SIZE, true /* executable R0 mapping */);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ void *pvScatchPage = RTR0MemObjAddress(hScatchMemObj);
+ RTHCPHYS HCPhysScratchPage = RTR0MemObjGetPagePhysAddr(hScatchMemObj, 0);
+ ASMMemZeroPage(pvScatchPage);
+
+ /* Set revision dword at the beginning of the structure. */
+ *(uint32_t *)pvScatchPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(g_HvmR0.vmx.msr.vmx_basic_info);
+
+ /* Make sure we don't get rescheduled to another cpu during this probe. */
+ RTCCUINTREG fFlags = ASMIntDisableFlags();
+
+ /*
+ * Check CR4.VMXE
+ */
+ g_HvmR0.vmx.hostCR4 = ASMGetCR4();
+ if (!(g_HvmR0.vmx.hostCR4 & X86_CR4_VMXE))
+ {
+ /* In theory this bit could be cleared behind our back. Which would cause
+ #UD faults when we try to execute the VMX instructions... */
+ ASMSetCR4(g_HvmR0.vmx.hostCR4 | X86_CR4_VMXE);
+ }
+
+ /* Enter VMX Root Mode */
+ rc = VMXEnable(HCPhysScratchPage);
+ if (RT_SUCCESS(rc))
+ {
+ g_HvmR0.vmx.fSupported = true;
+ VMXDisable();
+
+ /*
+ * Check for the VMX-Preemption Timer and adjust for the * "VMX-Preemption
+ * Timer Does Not Count Down at the Rate Specified" erratum.
+ */
+ if ( g_HvmR0.vmx.msr.vmx_pin_ctls.n.allowed1
+ & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
+ {
+ g_HvmR0.vmx.fUsePreemptTimer = true;
+ g_HvmR0.vmx.cPreemptTimerShift = MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(g_HvmR0.vmx.msr.vmx_misc);
+ if (hmR0InitIntelIsSubjectToVmxPreemptionTimerErratum())
+ g_HvmR0.vmx.cPreemptTimerShift = 0; /* This is about right most of the time here. */
+ }
+ }
+ else
+ {
+ /*
+ * KVM leaves the CPU in VMX root mode. Not only is this not allowed,
+ * it will crash the host when we enter raw mode, because:
+ *
+ * (a) clearing X86_CR4_VMXE in CR4 causes a #GP (we no longer modify
+ * this bit), and
+ * (b) turning off paging causes a #GP (unavoidable when switching
+ * from long to 32 bits mode or 32 bits to PAE).
+ *
+ * They should fix their code, but until they do we simply refuse to run.
+ */
+ g_HvmR0.lLastError = VERR_VMX_IN_VMX_ROOT_MODE;
+ }
+
+ /* Restore CR4 again; don't leave the X86_CR4_VMXE flag set
+ if it wasn't so before (some software could incorrectly
+ think it's in VMX mode). */
+ ASMSetCR4(g_HvmR0.vmx.hostCR4);
+ ASMSetFlags(fFlags);
+
+ RTR0MemObjFree(hScatchMemObj, false);
+ }
+ }
+ else
{
- rc = hwaccmR0FirstRcGetStatus(&FirstRc);
- AssertMsgRC(rc, ("%u: %Rrc\n", hwaccmR0FirstRcGetCpuId(&FirstRc), rc));
+ AssertFailed(); /* can't hit this case anymore */
+ g_HvmR0.lLastError = VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR;
}
- }
- /* Free the per-cpu pages used for VT-x and AMD-V */
- for (unsigned i=0;i<RT_ELEMENTS(HWACCMR0Globals.aCpuInfo);i++)
- {
- if (HWACCMR0Globals.aCpuInfo[i].pMemObj != NIL_RTR0MEMOBJ)
+ /*
+ * Install the VT-x methods.
+ */
+ if (g_HvmR0.vmx.fSupported)
{
- RTR0MemObjFree(HWACCMR0Globals.aCpuInfo[i].pMemObj, false);
- HWACCMR0Globals.aCpuInfo[i].pMemObj = NIL_RTR0MEMOBJ;
+ g_HvmR0.pfnEnterSession = VMXR0Enter;
+ g_HvmR0.pfnLeaveSession = VMXR0Leave;
+ g_HvmR0.pfnSaveHostState = VMXR0SaveHostState;
+ g_HvmR0.pfnLoadGuestState = VMXR0LoadGuestState;
+ g_HvmR0.pfnRunGuestCode = VMXR0RunGuestCode;
+ g_HvmR0.pfnEnableCpu = VMXR0EnableCpu;
+ g_HvmR0.pfnDisableCpu = VMXR0DisableCpu;
+ g_HvmR0.pfnInitVM = VMXR0InitVM;
+ g_HvmR0.pfnTermVM = VMXR0TermVM;
+ g_HvmR0.pfnSetupVM = VMXR0SetupVM;
}
}
+#ifdef LOG_ENABLED
+ else
+ SUPR0Printf("hmR0InitIntelCpu failed with rc=%d\n", g_HvmR0.lLastError);
+#endif
}
- return rc;
+ else
+ g_HvmR0.lLastError = VERR_VMX_NO_VMX;
+ return VINF_SUCCESS;
}
/**
- * Worker function passed to RTMpOnAll, RTMpOnOthers and RTMpOnSpecific that
- * is to be called on the target cpus.
- *
- * @param idCpu The identifier for the CPU the function is called on.
- * @param pvUser1 The 1st user argument.
- * @param pvUser2 The 2nd user argument.
+ * AMD specific initialization code.
*/
-static DECLCALLBACK(void) hwaccmR0InitCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+static void hmR0InitAmd(uint32_t u32FeaturesEDX)
{
- unsigned u32VendorEBX = (uintptr_t)pvUser1;
- PHWACCMR0FIRSTRC pFirstRc = (PHWACCMR0FIRSTRC)pvUser2;
- uint64_t val;
- int rc;
-
- Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
-
- if (u32VendorEBX == X86_CPUID_VENDOR_INTEL_EBX)
+ /*
+ * Read all SVM MSRs if SVM is available. (same goes for RDMSR/WRMSR)
+ * We also assume all SVM-enabled CPUs support fxsave/fxrstor.
+ */
+ if ( (g_HvmR0.cpuid.u32AMDFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM)
+ && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
+ && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
+ )
{
- val = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+ g_HvmR0.pfnEnterSession = SVMR0Enter;
+ g_HvmR0.pfnLeaveSession = SVMR0Leave;
+ g_HvmR0.pfnSaveHostState = SVMR0SaveHostState;
+ g_HvmR0.pfnLoadGuestState = SVMR0LoadGuestState;
+ g_HvmR0.pfnRunGuestCode = SVMR0RunGuestCode;
+ g_HvmR0.pfnEnableCpu = SVMR0EnableCpu;
+ g_HvmR0.pfnDisableCpu = SVMR0DisableCpu;
+ g_HvmR0.pfnInitVM = SVMR0InitVM;
+ g_HvmR0.pfnTermVM = SVMR0TermVM;
+ g_HvmR0.pfnSetupVM = SVMR0SetupVM;
+
+ /* Query AMD features. */
+ uint32_t u32Dummy;
+ ASMCpuId(0x8000000A, &g_HvmR0.svm.u32Rev, &g_HvmR0.uMaxASID,
+ &u32Dummy, &g_HvmR0.svm.u32Features);
/*
- * Both the LOCK and VMXON bit must be set; otherwise VMXON will generate a #GP.
- * Once the lock bit is set, this MSR can no longer be modified.
+ * We need to check if AMD-V has been properly initialized on all CPUs.
+ * Some BIOSes might do a poor job.
*/
- if ( !(val & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK))
- || ((val & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK)) == MSR_IA32_FEATURE_CONTROL_VMXON) /* Some BIOSes forget to set the locked bit. */
- )
+ HMR0FIRSTRC FirstRc;
+ hmR0FirstRcInit(&FirstRc);
+ int rc = RTMpOnAll(hmR0InitAmdCpu, &FirstRc, NULL);
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ rc = hmR0FirstRcGetStatus(&FirstRc);
+#ifndef DEBUG_bird
+ AssertMsg(rc == VINF_SUCCESS || rc == VERR_SVM_IN_USE,
+ ("hmR0InitAmdCpu failed for cpu %d with rc=%Rrc\n", hmR0FirstRcGetCpuId(&FirstRc), rc));
+#endif
+ if (RT_SUCCESS(rc))
{
- /* MSR is not yet locked; we can change it ourselves here */
- ASMWrMsr(MSR_IA32_FEATURE_CONTROL, HWACCMR0Globals.vmx.msr.feature_ctrl | MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK);
- val = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+ /* Read the HWCR msr for diagnostics. */
+ g_HvmR0.svm.msrHWCR = ASMRdMsr(MSR_K8_HWCR);
+ g_HvmR0.svm.fSupported = true;
}
- if ( (val & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK))
- == (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK))
- rc = VINF_SUCCESS;
else
- rc = VERR_VMX_MSR_LOCKED_OR_DISABLED;
+ g_HvmR0.lLastError = rc;
}
- else if (u32VendorEBX == X86_CPUID_VENDOR_AMD_EBX)
+ else
+ g_HvmR0.lLastError = VERR_SVM_NO_SVM;
+}
+
+
+/**
+ * Does global Ring-0 HM initialization (at module init).
+ *
+ * @returns VBox status code.
+ */
+VMMR0DECL(int) HWACCMR0Init(void)
+{
+ /*
+ * Initialize the globals.
+ */
+ g_HvmR0.fEnabled = false;
+ static RTONCE s_OnceInit = RTONCE_INITIALIZER;
+ g_HvmR0.EnableAllCpusOnce = s_OnceInit;
+ for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++)
+ g_HvmR0.aCpuInfo[i].hMemObj = NIL_RTR0MEMOBJ;
+
+ /* Fill in all callbacks with placeholders. */
+ g_HvmR0.pfnEnterSession = hmR0DummyEnter;
+ g_HvmR0.pfnLeaveSession = hmR0DummyLeave;
+ g_HvmR0.pfnSaveHostState = hmR0DummySaveHostState;
+ g_HvmR0.pfnLoadGuestState = hmR0DummyLoadGuestState;
+ g_HvmR0.pfnRunGuestCode = hmR0DummyRunGuestCode;
+ g_HvmR0.pfnEnableCpu = hmR0DummyEnableCpu;
+ g_HvmR0.pfnDisableCpu = hmR0DummyDisableCpu;
+ g_HvmR0.pfnInitVM = hmR0DummyInitVM;
+ g_HvmR0.pfnTermVM = hmR0DummyTermVM;
+ g_HvmR0.pfnSetupVM = hmR0DummySetupVM;
+
+ /* Default is global VT-x/AMD-V init */
+ g_HvmR0.fGlobalInit = true;
+
+ /*
+ * Make sure aCpuInfo is big enough for all the CPUs on this system.
+ */
+ if (RTMpGetArraySize() > RT_ELEMENTS(g_HvmR0.aCpuInfo))
{
- /* Check if SVM is disabled */
- val = ASMRdMsr(MSR_K8_VM_CR);
- if (!(val & MSR_K8_VM_CR_SVM_DISABLE))
- {
- /* Turn on SVM in the EFER MSR. */
- val = ASMRdMsr(MSR_K6_EFER);
- if (val & MSR_K6_EFER_SVME)
- rc = VERR_SVM_IN_USE;
- else
- {
- ASMWrMsr(MSR_K6_EFER, val | MSR_K6_EFER_SVME);
+ LogRel(("HM: Too many real CPUs/cores/threads - %u, max %u\n", RTMpGetArraySize(), RT_ELEMENTS(g_HvmR0.aCpuInfo)));
+ return VERR_TOO_MANY_CPUS;
+ }
- /* Paranoia. */
- val = ASMRdMsr(MSR_K6_EFER);
- if (val & MSR_K6_EFER_SVME)
- {
- /* Restore previous value. */
- ASMWrMsr(MSR_K6_EFER, val & ~MSR_K6_EFER_SVME);
- rc = VINF_SUCCESS;
- }
- else
- rc = VERR_SVM_ILLEGAL_EFER_MSR;
- }
+ /*
+ * Check for VT-x and AMD-V capabilities
+ */
+ int rc;
+ if (ASMHasCpuId())
+ {
+ uint32_t u32FeaturesECX, u32FeaturesEDX;
+ uint32_t u32VendorEBX, u32VendorECX, u32VendorEDX;
+ uint32_t u32Dummy;
+
+ /* Standard features. */
+ ASMCpuId(0, &u32Dummy, &u32VendorEBX, &u32VendorECX, &u32VendorEDX);
+ ASMCpuId(1, &u32Dummy, &u32Dummy, &u32FeaturesECX, &u32FeaturesEDX);
+
+ /* Query AMD features. */
+ ASMCpuId(0x80000001, &u32Dummy, &u32Dummy,
+ &g_HvmR0.cpuid.u32AMDFeatureECX,
+ &g_HvmR0.cpuid.u32AMDFeatureEDX);
+
+ /* Go to CPU specific initialization code. */
+ if ( u32VendorEBX == X86_CPUID_VENDOR_INTEL_EBX
+ && u32VendorECX == X86_CPUID_VENDOR_INTEL_ECX
+ && u32VendorEDX == X86_CPUID_VENDOR_INTEL_EDX)
+ {
+ rc = hmR0InitIntel(u32FeaturesECX, u32FeaturesEDX);
+ if (RT_FAILURE(rc))
+ return rc;
}
+ else if ( u32VendorEBX == X86_CPUID_VENDOR_AMD_EBX
+ && u32VendorECX == X86_CPUID_VENDOR_AMD_ECX
+ && u32VendorEDX == X86_CPUID_VENDOR_AMD_EDX)
+ hmR0InitAmd(u32FeaturesEDX);
else
- rc = VERR_SVM_DISABLED;
+ g_HvmR0.lLastError = VERR_HWACCM_UNKNOWN_CPU;
}
else
+ g_HvmR0.lLastError = VERR_HWACCM_NO_CPUID;
+
+ /*
+ * Register notification callbacks that we can use to disable/enable CPUs
+ * when brought offline/online or suspending/resuming.
+ */
+ if (!g_HvmR0.vmx.fUsingSUPR0EnableVTx)
{
- AssertFailed(); /* can't happen */
- rc = VERR_INTERNAL_ERROR_5;
+ rc = RTMpNotificationRegister(hmR0MpEventCallback, NULL);
+ AssertRC(rc);
+
+ rc = RTPowerNotificationRegister(hmR0PowerCallback, NULL);
+ AssertRC(rc);
}
- hwaccmR0FirstRcSetStatus(pFirstRc, rc);
+ /* We return success here because module init shall not fail if HM
+ fails to initialize. */
+ return VINF_SUCCESS;
}
/**
- * Sets up HWACCM on all cpus.
+ * Does global Ring-0 HM termination (at module termination).
*
* @returns VBox status code.
- * @param pVM The VM to operate on.
- *
*/
-VMMR0DECL(int) HWACCMR0EnableAllCpus(PVM pVM)
+VMMR0DECL(int) HWACCMR0Term(void)
{
- AssertCompile(sizeof(HWACCMR0Globals.enmHwAccmState) == sizeof(uint32_t));
-
- /* Make sure we don't touch hwaccm after we've disabled hwaccm in preparation of a suspend. */
- if (ASMAtomicReadBool(&HWACCMR0Globals.fSuspended))
- return VERR_HWACCM_SUSPEND_PENDING;
-
- if (ASMAtomicCmpXchgU32((volatile uint32_t *)&HWACCMR0Globals.enmHwAccmState, HWACCMSTATE_ENABLED, HWACCMSTATE_UNINITIALIZED))
+ int rc;
+ if ( g_HvmR0.vmx.fSupported
+ && g_HvmR0.vmx.fUsingSUPR0EnableVTx)
{
- int rc;
+ /*
+ * Simple if the host OS manages VT-x.
+ */
+ Assert(g_HvmR0.fGlobalInit);
+ rc = SUPR0EnableVTx(false /* fEnable */);
- HWACCMR0Globals.fGlobalInit = pVM->hwaccm.s.fGlobalInit;
+ for (unsigned iCpu = 0; iCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo); iCpu++)
+ {
+ g_HvmR0.aCpuInfo[iCpu].fConfigured = false;
+ Assert(g_HvmR0.aCpuInfo[iCpu].hMemObj == NIL_RTR0MEMOBJ);
+ }
+ }
+ else
+ {
+ Assert(!g_HvmR0.vmx.fUsingSUPR0EnableVTx);
+ if (!g_HvmR0.vmx.fUsingSUPR0EnableVTx)
+ {
+ /* Doesn't really matter if this fails. */
+ rc = RTMpNotificationDeregister(hmR0MpEventCallback, NULL); AssertRC(rc);
+ rc = RTPowerNotificationDeregister(hmR0PowerCallback, NULL); AssertRC(rc);
+ }
+ else
+ rc = VINF_SUCCESS;
- if ( HWACCMR0Globals.vmx.fSupported
- && HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx)
+ /*
+ * Disable VT-x/AMD-V on all CPUs if we enabled it before.
+ */
+ if (g_HvmR0.fGlobalInit)
{
- rc = SUPR0EnableVTx(true /* fEnable */);
+ HMR0FIRSTRC FirstRc;
+ hmR0FirstRcInit(&FirstRc);
+ rc = RTMpOnAll(hmR0DisableCpuCallback, NULL, &FirstRc);
+ Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
if (RT_SUCCESS(rc))
{
- for (unsigned iCpu = 0; iCpu < RT_ELEMENTS(HWACCMR0Globals.aCpuInfo); iCpu++)
- {
- HWACCMR0Globals.aCpuInfo[iCpu].fConfigured = true;
- Assert(HWACCMR0Globals.aCpuInfo[iCpu].pMemObj == NIL_RTR0MEMOBJ);
- }
- /* If the host provides a VT-x init API, then we'll rely on that for global init. */
- HWACCMR0Globals.fGlobalInit = pVM->hwaccm.s.fGlobalInit = true;
+ rc = hmR0FirstRcGetStatus(&FirstRc);
+ AssertMsgRC(rc, ("%u: %Rrc\n", hmR0FirstRcGetCpuId(&FirstRc), rc));
}
- else
- AssertMsgFailed(("HWACCMR0EnableAllCpus/SUPR0EnableVTx: rc=%Rrc\n", rc));
}
- else
+
+ /*
+ * Free the per-cpu pages used for VT-x and AMD-V.
+ */
+ for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++)
{
- /* Allocate one page per cpu for the global vt-x and amd-v pages */
- for (unsigned i=0;i<RT_ELEMENTS(HWACCMR0Globals.aCpuInfo);i++)
+ if (g_HvmR0.aCpuInfo[i].hMemObj != NIL_RTR0MEMOBJ)
{
- Assert(!HWACCMR0Globals.aCpuInfo[i].pMemObj);
+ RTR0MemObjFree(g_HvmR0.aCpuInfo[i].hMemObj, false);
+ g_HvmR0.aCpuInfo[i].hMemObj = NIL_RTR0MEMOBJ;
+ }
+ }
+ }
+ return rc;
+}
- /** @todo this is rather dangerous if cpus can be taken offline; we don't care for now */
- if (RTMpIsCpuOnline(i))
- {
- rc = RTR0MemObjAllocCont(&HWACCMR0Globals.aCpuInfo[i].pMemObj, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
- AssertRC(rc);
- if (RT_FAILURE(rc))
- return rc;
- void *pvR0 = RTR0MemObjAddress(HWACCMR0Globals.aCpuInfo[i].pMemObj);
- Assert(pvR0);
- ASMMemZeroPage(pvR0);
+/**
+ * Worker function used by hmR0PowerCallback and HWACCMR0Init to initalize
+ * VT-x on a CPU.
+ *
+ * @param idCpu The identifier for the CPU the function is called on.
+ * @param pvUser1 Pointer to the first RC structure.
+ * @param pvUser2 Ignored.
+ */
+static DECLCALLBACK(void) hmR0InitIntelCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+ PHMR0FIRSTRC pFirstRc = (PHMR0FIRSTRC)pvUser1;
+ Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
+ NOREF(pvUser2);
-#if defined(LOG_ENABLED) && !defined(DEBUG_bird)
- SUPR0Printf("address %x phys %x\n", pvR0, (uint32_t)RTR0MemObjGetPagePhysAddr(HWACCMR0Globals.aCpuInfo[i].pMemObj, 0));
-#endif
- }
- }
- if (HWACCMR0Globals.fGlobalInit)
+ /*
+ * Both the LOCK and VMXON bit must be set; otherwise VMXON will generate a #GP.
+ * Once the lock bit is set, this MSR can no longer be modified.
+ */
+ uint64_t fFC = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+ if ( !(fFC & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+ || ( (fFC & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+ == MSR_IA32_FEATURE_CONTROL_VMXON ) /* Some BIOSes forget to set the locked bit. */
+ )
+ {
+ /* MSR is not yet locked; we can change it ourselves here */
+ ASMWrMsr(MSR_IA32_FEATURE_CONTROL,
+ g_HvmR0.vmx.msr.feature_ctrl | MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK);
+ fFC = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+ }
+
+ int rc;
+ if ( (fFC & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+ == (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+ rc = VINF_SUCCESS;
+ else
+ rc = VERR_VMX_MSR_LOCKED_OR_DISABLED;
+
+ hmR0FirstRcSetStatus(pFirstRc, rc);
+}
+
+
+/**
+ * Worker function used by hmR0PowerCallback and HWACCMR0Init to initalize
+ * VT-x / AMD-V on a CPU.
+ *
+ * @param idCpu The identifier for the CPU the function is called on.
+ * @param pvUser1 Pointer to the first RC structure.
+ * @param pvUser2 Ignored.
+ */
+static DECLCALLBACK(void) hmR0InitAmdCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+ PHMR0FIRSTRC pFirstRc = (PHMR0FIRSTRC)pvUser1;
+ Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
+ NOREF(pvUser2);
+
+ /* Check if SVM is disabled. */
+ int rc;
+ uint64_t fVmCr = ASMRdMsr(MSR_K8_VM_CR);
+ if (!(fVmCr & MSR_K8_VM_CR_SVM_DISABLE))
+ {
+ /* Turn on SVM in the EFER MSR. */
+ uint64_t fEfer = ASMRdMsr(MSR_K6_EFER);
+ if (fEfer & MSR_K6_EFER_SVME)
+ rc = VERR_SVM_IN_USE;
+ else
+ {
+ ASMWrMsr(MSR_K6_EFER, fEfer | MSR_K6_EFER_SVME);
+
+ /* Paranoia. */
+ fEfer = ASMRdMsr(MSR_K6_EFER);
+ if (fEfer & MSR_K6_EFER_SVME)
{
- /* First time, so initialize each cpu/core */
- HWACCMR0FIRSTRC FirstRc;
- hwaccmR0FirstRcInit(&FirstRc);
- rc = RTMpOnAll(hwaccmR0EnableCpuCallback, (void *)pVM, &FirstRc);
- if (RT_SUCCESS(rc))
- rc = hwaccmR0FirstRcGetStatus(&FirstRc);
- AssertMsgRC(rc, ("HWACCMR0EnableAllCpus failed for cpu %d with rc=%d\n", hwaccmR0FirstRcGetCpuId(&FirstRc), rc));
+ /* Restore previous value. */
+ ASMWrMsr(MSR_K6_EFER, fEfer & ~MSR_K6_EFER_SVME);
+ rc = VINF_SUCCESS;
}
else
- rc = VINF_SUCCESS;
+ rc = VERR_SVM_ILLEGAL_EFER_MSR;
}
-
- return rc;
}
- return VINF_SUCCESS;
+ else
+ rc = VERR_SVM_DISABLED;
+
+ hmR0FirstRcSetStatus(pFirstRc, rc);
}
+
+
/**
* Disable VT-x or AMD-V on the current CPU
*
@@ -774,37 +841,35 @@ VMMR0DECL(int) HWACCMR0EnableAllCpus(PVM pVM)
* @param pVM VM handle (can be 0!)
* @param idCpu The identifier for the CPU the function is called on.
*/
-static int hwaccmR0EnableCpu(PVM pVM, RTCPUID idCpu)
+static int hmR0EnableCpu(PVM pVM, RTCPUID idCpu)
{
- void *pvPageCpu;
- RTHCPHYS pPageCpuPhys;
- PHWACCM_CPUINFO pCpu = &HWACCMR0Globals.aCpuInfo[idCpu];
+ PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[idCpu];
- Assert(!HWACCMR0Globals.vmx.fSupported || !HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx);
+ Assert(!g_HvmR0.vmx.fSupported || !g_HvmR0.vmx.fUsingSUPR0EnableVTx);
Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
- Assert(idCpu < RT_ELEMENTS(HWACCMR0Globals.aCpuInfo));
+ Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
Assert(!pCpu->fConfigured);
- Assert(!HWACCMR0Globals.fGlobalInit || ASMAtomicReadBool(&pCpu->fInUse) == false);
+ Assert(!g_HvmR0.fGlobalInit || ASMAtomicReadBool(&pCpu->fInUse) == false);
- pCpu->idCpu = idCpu;
+ pCpu->idCpu = idCpu;
/* Make sure we start with a clean TLB. */
- pCpu->fFlushTLB = true;
+ pCpu->fFlushTLB = true;
- pCpu->uCurrentASID = 0; /* we'll aways increment this the first time (host uses ASID 0) */
- pCpu->cTLBFlushes = 0;
+ pCpu->uCurrentASID = 0; /* we'll aways increment this the first time (host uses ASID 0) */
+ pCpu->cTLBFlushes = 0;
/* Should never happen */
- if (!pCpu->pMemObj)
+ if (pCpu->hMemObj == NIL_RTR0MEMOBJ)
{
- AssertFailed();
+ AssertLogRelMsgFailed(("hmR0EnableCpu failed idCpu=%u.\n", idCpu));
return VERR_INTERNAL_ERROR;
}
- pvPageCpu = RTR0MemObjAddress(pCpu->pMemObj);
- pPageCpuPhys = RTR0MemObjGetPagePhysAddr(pCpu->pMemObj, 0);
+ void *pvCpuPage = RTR0MemObjAddress(pCpu->hMemObj);
+ RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
- int rc = HWACCMR0Globals.pfnEnableCpu(pCpu, pVM, pvPageCpu, pPageCpuPhys);
+ int rc = g_HvmR0.pfnEnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage);
AssertRC(rc);
if (RT_SUCCESS(rc))
pCpu->fConfigured = true;
@@ -821,12 +886,116 @@ static int hwaccmR0EnableCpu(PVM pVM, RTCPUID idCpu)
* @param pvUser1 The 1st user argument.
* @param pvUser2 The 2nd user argument.
*/
-static DECLCALLBACK(void) hwaccmR0EnableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+static DECLCALLBACK(void) hmR0EnableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+ PVM pVM = (PVM)pvUser1; /* can be NULL! */
+ PHMR0FIRSTRC pFirstRc = (PHMR0FIRSTRC)pvUser2;
+ AssertReturnVoid(g_HvmR0.fGlobalInit);
+ hmR0FirstRcSetStatus(pFirstRc, hmR0EnableCpu(pVM, idCpu));
+}
+
+
+/**
+ * RTOnce callback employed by HWACCMR0EnableAllCpus.
+ *
+ * @returns VBox status code
+ * @param pvUser The VM handle.
+ * @param pvUserIgnore NULL, ignored.
+ */
+static DECLCALLBACK(int32_t) hmR0EnableAllCpuOnce(void *pvUser, void *pvUserIgnore)
+{
+ PVM pVM = (PVM)pvUser;
+ NOREF(pvUserIgnore);
+
+ /*
+ * Indicate that we've initialized.
+ *
+ * Note! There is a potential race between this function and the suspend
+ * notification. Kind of unlikely though, so ignored for now.
+ */
+ AssertReturn(!g_HvmR0.fEnabled, VERR_INTERNAL_ERROR_3);
+ ASMAtomicWriteBool(&g_HvmR0.fEnabled, true);
+
+ /*
+ * The global init variable is set by the first VM.
+ */
+ g_HvmR0.fGlobalInit = pVM->hwaccm.s.fGlobalInit;
+
+ int rc;
+ if ( g_HvmR0.vmx.fSupported
+ && g_HvmR0.vmx.fUsingSUPR0EnableVTx)
+ {
+ /*
+ * Global VT-x initialization API (only darwin for now).
+ */
+ rc = SUPR0EnableVTx(true /* fEnable */);
+ if (RT_SUCCESS(rc))
+ {
+ for (unsigned iCpu = 0; iCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo); iCpu++)
+ {
+ g_HvmR0.aCpuInfo[iCpu].fConfigured = true;
+ Assert(g_HvmR0.aCpuInfo[iCpu].hMemObj == NIL_RTR0MEMOBJ);
+ }
+
+ /* If the host provides a VT-x init API, then we'll rely on that for global init. */
+ g_HvmR0.fGlobalInit = pVM->hwaccm.s.fGlobalInit = true;
+ }
+ else
+ AssertMsgFailed(("HWACCMR0EnableAllCpus/SUPR0EnableVTx: rc=%Rrc\n", rc));
+ }
+ else
+ {
+ /*
+ * We're doing the job ourselves.
+ */
+ /* Allocate one page per cpu for the global vt-x and amd-v pages */
+ for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++)
+ {
+ Assert(g_HvmR0.aCpuInfo[i].hMemObj == NIL_RTR0MEMOBJ);
+
+ if (RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(i)))
+ {
+ rc = RTR0MemObjAllocCont(&g_HvmR0.aCpuInfo[i].hMemObj, PAGE_SIZE, true /* executable R0 mapping */);
+ AssertLogRelRCReturn(rc, rc);
+
+ void *pvR0 = RTR0MemObjAddress(g_HvmR0.aCpuInfo[i].hMemObj); Assert(pvR0);
+ ASMMemZeroPage(pvR0);
+ }
+ g_HvmR0.aCpuInfo[i].fConfigured = false;
+ }
+
+ if (g_HvmR0.fGlobalInit)
+ {
+ /* First time, so initialize each cpu/core. */
+ HMR0FIRSTRC FirstRc;
+ hmR0FirstRcInit(&FirstRc);
+ rc = RTMpOnAll(hmR0EnableCpuCallback, (void *)pVM, &FirstRc);
+ if (RT_SUCCESS(rc))
+ rc = hmR0FirstRcGetStatus(&FirstRc);
+ AssertMsgRC(rc, ("HWACCMR0EnableAllCpus failed for cpu %d with rc=%d\n", hmR0FirstRcGetCpuId(&FirstRc), rc));
+ }
+ else
+ rc = VINF_SUCCESS;
+ }
+
+ return rc;
+}
+
+
+/**
+ * Sets up HWACCM on all cpus.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM handle.
+ */
+VMMR0DECL(int) HWACCMR0EnableAllCpus(PVM pVM)
{
- PVM pVM = (PVM)pvUser1; /* can be NULL! */
- PHWACCMR0FIRSTRC pFirstRc = (PHWACCMR0FIRSTRC)pvUser2;
- AssertReturnVoid(HWACCMR0Globals.fGlobalInit);
- hwaccmR0FirstRcSetStatus(pFirstRc, hwaccmR0EnableCpu(pVM, idCpu));
+ /* Make sure we don't touch hwaccm after we've disabled hwaccm in
+ preparation of a suspend. */
+ if (ASMAtomicReadBool(&g_HvmR0.fSuspended))
+ return VERR_HWACCM_SUSPEND_PENDING;
+
+ return RTOnce(&g_HvmR0.EnableAllCpusOnce, hmR0EnableAllCpuOnce, pVM, NULL);
}
@@ -836,28 +1005,25 @@ static DECLCALLBACK(void) hwaccmR0EnableCpuCallback(RTCPUID idCpu, void *pvUser1
* @returns VBox status code.
* @param idCpu The identifier for the CPU the function is called on.
*/
-static int hwaccmR0DisableCpu(RTCPUID idCpu)
+static int hmR0DisableCpu(RTCPUID idCpu)
{
- void *pvPageCpu;
- RTHCPHYS pPageCpuPhys;
- int rc;
- PHWACCM_CPUINFO pCpu = &HWACCMR0Globals.aCpuInfo[idCpu];
+ PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[idCpu];
- Assert(!HWACCMR0Globals.vmx.fSupported || !HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx);
+ Assert(!g_HvmR0.vmx.fSupported || !g_HvmR0.vmx.fUsingSUPR0EnableVTx);
Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
- Assert(idCpu < RT_ELEMENTS(HWACCMR0Globals.aCpuInfo));
- Assert(!HWACCMR0Globals.fGlobalInit || ASMAtomicReadBool(&pCpu->fInUse) == false);
- Assert(!pCpu->fConfigured || pCpu->pMemObj);
+ Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
+ Assert(!g_HvmR0.fGlobalInit || ASMAtomicReadBool(&pCpu->fInUse) == false);
+ Assert(!pCpu->fConfigured || pCpu->hMemObj != NIL_RTR0MEMOBJ);
- if (!pCpu->pMemObj)
- return (pCpu->fConfigured) ? VERR_NO_MEMORY : VINF_SUCCESS /* not initialized. */;
-
- pvPageCpu = RTR0MemObjAddress(pCpu->pMemObj);
- pPageCpuPhys = RTR0MemObjGetPagePhysAddr(pCpu->pMemObj, 0);
+ if (pCpu->hMemObj == NIL_RTR0MEMOBJ)
+ return pCpu->fConfigured ? VERR_NO_MEMORY : VINF_SUCCESS /* not initialized. */;
+ int rc;
if (pCpu->fConfigured)
{
- rc = HWACCMR0Globals.pfnDisableCpu(pCpu, pvPageCpu, pPageCpuPhys);
+ void *pvCpuPage = RTR0MemObjAddress(pCpu->hMemObj);
+ RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
+ rc = g_HvmR0.pfnDisableCpu(pCpu, pvCpuPage, HCPhysCpuPage);
AssertRC(rc);
pCpu->fConfigured = false;
}
@@ -868,6 +1034,7 @@ static int hwaccmR0DisableCpu(RTCPUID idCpu)
return rc;
}
+
/**
* Worker function passed to RTMpOnAll, RTMpOnOthers and RTMpOnSpecific that
* is to be called on the target cpus.
@@ -876,90 +1043,122 @@ static int hwaccmR0DisableCpu(RTCPUID idCpu)
* @param pvUser1 The 1st user argument.
* @param pvUser2 The 2nd user argument.
*/
-static DECLCALLBACK(void) hwaccmR0DisableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+static DECLCALLBACK(void) hmR0DisableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2)
{
- PHWACCMR0FIRSTRC pFirstRc = (PHWACCMR0FIRSTRC)pvUser2;
- AssertReturnVoid(HWACCMR0Globals.fGlobalInit);
- hwaccmR0FirstRcSetStatus(pFirstRc, hwaccmR0DisableCpu(idCpu));
+ PHMR0FIRSTRC pFirstRc = (PHMR0FIRSTRC)pvUser2;
+ AssertReturnVoid(g_HvmR0.fGlobalInit);
+ hmR0FirstRcSetStatus(pFirstRc, hmR0DisableCpu(idCpu));
}
+
+/**
+ * Callback function invoked when a cpu goes online or offline.
+ *
+ * @param enmEvent The Mp event.
+ * @param idCpu The identifier for the CPU the function is called on.
+ * @param pvData Opaque data (PVM pointer).
+ */
+static DECLCALLBACK(void) hmR0MpEventCallback(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvData)
+{
+ /*
+ * We only care about uninitializing a CPU that is going offline. When a
+ * CPU comes online, the initialization is done lazily in HWACCMR0Enter().
+ */
+ AssertRelease(idCpu == RTMpCpuId());
+ Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+ switch (enmEvent)
+ {
+ case RTMPEVENT_OFFLINE:
+ {
+ int rc = hmR0DisableCpu(idCpu);
+ AssertRC(rc);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
/**
* Called whenever a system power state change occurs.
*
* @param enmEvent Power event
* @param pvUser User argument
*/
-static DECLCALLBACK(void) hwaccmR0PowerCallback(RTPOWEREVENT enmEvent, void *pvUser)
+static DECLCALLBACK(void) hmR0PowerCallback(RTPOWEREVENT enmEvent, void *pvUser)
{
NOREF(pvUser);
- Assert(!HWACCMR0Globals.vmx.fSupported || !HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx);
+ Assert(!g_HvmR0.vmx.fSupported || !g_HvmR0.vmx.fUsingSUPR0EnableVTx);
#ifdef LOG_ENABLED
if (enmEvent == RTPOWEREVENT_SUSPEND)
- SUPR0Printf("hwaccmR0PowerCallback RTPOWEREVENT_SUSPEND\n");
+ SUPR0Printf("hmR0PowerCallback RTPOWEREVENT_SUSPEND\n");
else
- SUPR0Printf("hwaccmR0PowerCallback RTPOWEREVENT_RESUME\n");
+ SUPR0Printf("hmR0PowerCallback RTPOWEREVENT_RESUME\n");
#endif
if (enmEvent == RTPOWEREVENT_SUSPEND)
- ASMAtomicWriteBool(&HWACCMR0Globals.fSuspended, true);
+ ASMAtomicWriteBool(&g_HvmR0.fSuspended, true);
- if (HWACCMR0Globals.enmHwAccmState == HWACCMSTATE_ENABLED)
+ if (g_HvmR0.fEnabled)
{
- int rc;
- HWACCMR0FIRSTRC FirstRc;
- hwaccmR0FirstRcInit(&FirstRc);
+ int rc;
+ HMR0FIRSTRC FirstRc;
+ hmR0FirstRcInit(&FirstRc);
if (enmEvent == RTPOWEREVENT_SUSPEND)
{
- if (HWACCMR0Globals.fGlobalInit)
+ if (g_HvmR0.fGlobalInit)
{
/* Turn off VT-x or AMD-V on all CPUs. */
- rc = RTMpOnAll(hwaccmR0DisableCpuCallback, NULL, &FirstRc);
+ rc = RTMpOnAll(hmR0DisableCpuCallback, NULL, &FirstRc);
Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
}
/* else nothing to do here for the local init case */
}
else
{
- /* Reinit the CPUs from scratch as the suspend state might have messed with the MSRs. (lousy BIOSes as usual) */
- uintptr_t uFirstArg = HWACCMR0Globals.vmx.fSupported ? X86_CPUID_VENDOR_INTEL_EBX : X86_CPUID_VENDOR_AMD_EBX;
- rc = RTMpOnAll(hwaccmR0InitCpu, (void *)uFirstArg , &FirstRc);
+ /* Reinit the CPUs from scratch as the suspend state might have
+ messed with the MSRs. (lousy BIOSes as usual) */
+ if (g_HvmR0.vmx.fSupported)
+ rc = RTMpOnAll(hmR0InitIntelCpu, &FirstRc, NULL);
+ else
+ rc = RTMpOnAll(hmR0InitAmdCpu, &FirstRc, NULL);
Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
if (RT_SUCCESS(rc))
- rc = hwaccmR0FirstRcGetStatus(&FirstRc);
+ rc = hmR0FirstRcGetStatus(&FirstRc);
#ifdef LOG_ENABLED
if (RT_FAILURE(rc))
- SUPR0Printf("hwaccmR0PowerCallback hwaccmR0InitCpu failed with %Rc\n", rc);
+ SUPR0Printf("hmR0PowerCallback hmR0InitXxxCpu failed with %Rc\n", rc);
#endif
-
- if (HWACCMR0Globals.fGlobalInit)
+ if (g_HvmR0.fGlobalInit)
{
/* Turn VT-x or AMD-V back on on all CPUs. */
- rc = RTMpOnAll(hwaccmR0EnableCpuCallback, NULL, &FirstRc /* output ignored */);
+ rc = RTMpOnAll(hmR0EnableCpuCallback, NULL, &FirstRc /* output ignored */);
Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
}
/* else nothing to do here for the local init case */
}
}
+
if (enmEvent == RTPOWEREVENT_RESUME)
- ASMAtomicWriteBool(&HWACCMR0Globals.fSuspended, false);
+ ASMAtomicWriteBool(&g_HvmR0.fSuspended, false);
}
/**
- * Does Ring-0 per VM HWACCM initialization.
+ * Does Ring-0 per VM HM initialization.
*
- * This is mainly to check that the Host CPU mode is compatible
- * with VMX.
+ * This will copy HM global into the VM structure and call the CPU specific
+ * init routine which will allocate resources for each virtual CPU and such.
*
* @returns VBox status code.
* @param pVM The VM to operate on.
*/
VMMR0DECL(int) HWACCMR0InitVM(PVM pVM)
{
- int rc;
-
AssertReturn(pVM, VERR_INVALID_PARAMETER);
#ifdef LOG_ENABLED
@@ -967,38 +1166,41 @@ VMMR0DECL(int) HWACCMR0InitVM(PVM pVM)
#endif
/* Make sure we don't touch hwaccm after we've disabled hwaccm in preparation of a suspend. */
- if (ASMAtomicReadBool(&HWACCMR0Globals.fSuspended))
+ if (ASMAtomicReadBool(&g_HvmR0.fSuspended))
return VERR_HWACCM_SUSPEND_PENDING;
- pVM->hwaccm.s.vmx.fSupported = HWACCMR0Globals.vmx.fSupported;
- pVM->hwaccm.s.svm.fSupported = HWACCMR0Globals.svm.fSupported;
-
- pVM->hwaccm.s.vmx.fUsePreemptTimer = HWACCMR0Globals.vmx.fUsePreemptTimer;
- pVM->hwaccm.s.vmx.cPreemptTimerShift = HWACCMR0Globals.vmx.cPreemptTimerShift;
- pVM->hwaccm.s.vmx.msr.feature_ctrl = HWACCMR0Globals.vmx.msr.feature_ctrl;
- pVM->hwaccm.s.vmx.hostCR4 = HWACCMR0Globals.vmx.hostCR4;
- pVM->hwaccm.s.vmx.hostEFER = HWACCMR0Globals.vmx.hostEFER;
- pVM->hwaccm.s.vmx.msr.vmx_basic_info = HWACCMR0Globals.vmx.msr.vmx_basic_info;
- pVM->hwaccm.s.vmx.msr.vmx_pin_ctls = HWACCMR0Globals.vmx.msr.vmx_pin_ctls;
- pVM->hwaccm.s.vmx.msr.vmx_proc_ctls = HWACCMR0Globals.vmx.msr.vmx_proc_ctls;
- pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2 = HWACCMR0Globals.vmx.msr.vmx_proc_ctls2;
- pVM->hwaccm.s.vmx.msr.vmx_exit = HWACCMR0Globals.vmx.msr.vmx_exit;
- pVM->hwaccm.s.vmx.msr.vmx_entry = HWACCMR0Globals.vmx.msr.vmx_entry;
- pVM->hwaccm.s.vmx.msr.vmx_misc = HWACCMR0Globals.vmx.msr.vmx_misc;
- pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed0 = HWACCMR0Globals.vmx.msr.vmx_cr0_fixed0;
- pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed1 = HWACCMR0Globals.vmx.msr.vmx_cr0_fixed1;
- pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed0 = HWACCMR0Globals.vmx.msr.vmx_cr4_fixed0;
- pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed1 = HWACCMR0Globals.vmx.msr.vmx_cr4_fixed1;
- pVM->hwaccm.s.vmx.msr.vmx_vmcs_enum = HWACCMR0Globals.vmx.msr.vmx_vmcs_enum;
- pVM->hwaccm.s.vmx.msr.vmx_eptcaps = HWACCMR0Globals.vmx.msr.vmx_eptcaps;
- pVM->hwaccm.s.svm.msrHWCR = HWACCMR0Globals.svm.msrHWCR;
- pVM->hwaccm.s.svm.u32Rev = HWACCMR0Globals.svm.u32Rev;
- pVM->hwaccm.s.svm.u32Features = HWACCMR0Globals.svm.u32Features;
- pVM->hwaccm.s.cpuid.u32AMDFeatureECX = HWACCMR0Globals.cpuid.u32AMDFeatureECX;
- pVM->hwaccm.s.cpuid.u32AMDFeatureEDX = HWACCMR0Globals.cpuid.u32AMDFeatureEDX;
- pVM->hwaccm.s.lLastError = HWACCMR0Globals.lLastError;
-
- pVM->hwaccm.s.uMaxASID = HWACCMR0Globals.uMaxASID;
+ /*
+ * Copy globals to the VM structure.
+ */
+ pVM->hwaccm.s.vmx.fSupported = g_HvmR0.vmx.fSupported;
+ pVM->hwaccm.s.svm.fSupported = g_HvmR0.svm.fSupported;
+
+ pVM->hwaccm.s.vmx.fUsePreemptTimer = g_HvmR0.vmx.fUsePreemptTimer;
+ pVM->hwaccm.s.vmx.cPreemptTimerShift = g_HvmR0.vmx.cPreemptTimerShift;
+ pVM->hwaccm.s.vmx.msr.feature_ctrl = g_HvmR0.vmx.msr.feature_ctrl;
+ pVM->hwaccm.s.vmx.hostCR4 = g_HvmR0.vmx.hostCR4;
+ pVM->hwaccm.s.vmx.hostEFER = g_HvmR0.vmx.hostEFER;
+ pVM->hwaccm.s.vmx.msr.vmx_basic_info = g_HvmR0.vmx.msr.vmx_basic_info;
+ pVM->hwaccm.s.vmx.msr.vmx_pin_ctls = g_HvmR0.vmx.msr.vmx_pin_ctls;
+ pVM->hwaccm.s.vmx.msr.vmx_proc_ctls = g_HvmR0.vmx.msr.vmx_proc_ctls;
+ pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2 = g_HvmR0.vmx.msr.vmx_proc_ctls2;
+ pVM->hwaccm.s.vmx.msr.vmx_exit = g_HvmR0.vmx.msr.vmx_exit;
+ pVM->hwaccm.s.vmx.msr.vmx_entry = g_HvmR0.vmx.msr.vmx_entry;
+ pVM->hwaccm.s.vmx.msr.vmx_misc = g_HvmR0.vmx.msr.vmx_misc;
+ pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed0 = g_HvmR0.vmx.msr.vmx_cr0_fixed0;
+ pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed1 = g_HvmR0.vmx.msr.vmx_cr0_fixed1;
+ pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed0 = g_HvmR0.vmx.msr.vmx_cr4_fixed0;
+ pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed1 = g_HvmR0.vmx.msr.vmx_cr4_fixed1;
+ pVM->hwaccm.s.vmx.msr.vmx_vmcs_enum = g_HvmR0.vmx.msr.vmx_vmcs_enum;
+ pVM->hwaccm.s.vmx.msr.vmx_eptcaps = g_HvmR0.vmx.msr.vmx_eptcaps;
+ pVM->hwaccm.s.svm.msrHWCR = g_HvmR0.svm.msrHWCR;
+ pVM->hwaccm.s.svm.u32Rev = g_HvmR0.svm.u32Rev;
+ pVM->hwaccm.s.svm.u32Features = g_HvmR0.svm.u32Features;
+ pVM->hwaccm.s.cpuid.u32AMDFeatureECX = g_HvmR0.cpuid.u32AMDFeatureECX;
+ pVM->hwaccm.s.cpuid.u32AMDFeatureEDX = g_HvmR0.cpuid.u32AMDFeatureEDX;
+ pVM->hwaccm.s.lLastError = g_HvmR0.lLastError;
+
+ pVM->hwaccm.s.uMaxASID = g_HvmR0.uMaxASID;
if (!pVM->hwaccm.s.cMaxResumeLoops) /* allow ring-3 overrides */
@@ -1010,28 +1212,36 @@ VMMR0DECL(int) HWACCMR0InitVM(PVM pVM)
#endif
}
+ /*
+ * Initialize some per CPU fields.
+ */
for (VMCPUID i = 0; i < pVM->cCpus; i++)
{
PVMCPU pVCpu = &pVM->aCpus[i];
- pVCpu->hwaccm.s.idEnteredCpu = NIL_RTCPUID;
+ pVCpu->hwaccm.s.idEnteredCpu = NIL_RTCPUID;
/* Invalidate the last cpu we were running on. */
- pVCpu->hwaccm.s.idLastCpu = NIL_RTCPUID;
+ pVCpu->hwaccm.s.idLastCpu = NIL_RTCPUID;
/* we'll aways increment this the first time (host uses ASID 0) */
- pVCpu->hwaccm.s.uCurrentASID = 0;
+ pVCpu->hwaccm.s.uCurrentASID = 0;
}
+ /*
+ * Call the hardware specific initialization method.
+ *
+ * Note! The fInUse handling here isn't correct as we can we can be
+ * rescheduled to a different cpu, but the fInUse case is mostly for
+ * debugging... Disabling preemption isn't an option when allocating
+ * memory, so we'll let it slip for now.
+ */
RTCCUINTREG fFlags = ASMIntDisableFlags();
- PHWACCM_CPUINFO pCpu = HWACCMR0GetCurrentCpu();
-
- /* Note: Not correct as we can be rescheduled to a different cpu, but the fInUse case is mostly for debugging. */
+ PHMGLOBLCPUINFO pCpu = HWACCMR0GetCurrentCpu();
ASMAtomicWriteBool(&pCpu->fInUse, true);
ASMSetFlags(fFlags);
- /* Init a VT-x or AMD-V VM. */
- rc = HWACCMR0Globals.pfnInitVM(pVM);
+ int rc = g_HvmR0.pfnInitVM(pVM);
ASMAtomicWriteBool(&pCpu->fInUse, false);
return rc;
@@ -1039,33 +1249,35 @@ VMMR0DECL(int) HWACCMR0InitVM(PVM pVM)
/**
- * Does Ring-0 per VM HWACCM termination.
+ * Does Ring-0 per VM HM termination.
*
* @returns VBox status code.
* @param pVM The VM to operate on.
*/
VMMR0DECL(int) HWACCMR0TermVM(PVM pVM)
{
- int rc;
-
+ Log(("HWACCMR0TermVM: %p\n", pVM));
AssertReturn(pVM, VERR_INVALID_PARAMETER);
-#ifdef LOG_ENABLED
- SUPR0Printf("HWACCMR0TermVM: %p\n", pVM);
-#endif
-
- /* Make sure we don't touch hwaccm after we've disabled hwaccm in preparation of a suspend. */
- AssertReturn(!ASMAtomicReadBool(&HWACCMR0Globals.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
+ /* Make sure we don't touch hm after we've disabled hwaccm in preparation
+ of a suspend. */
+ /** @todo r=bird: This cannot be right, the termination functions are
+ * just freeing memory and resetting pVM/pVCpu members...
+ * ==> memory leak. */
+ AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
- /* @note Not correct as we can be rescheduled to a different cpu, but the fInUse case is mostly for debugging. */
+ /*
+ * Call the hardware specific method.
+ *
+ * Note! Not correct as we can be rescheduled to a different cpu, but the
+ * fInUse case is mostly for debugging.
+ */
RTCCUINTREG fFlags = ASMIntDisableFlags();
- PHWACCM_CPUINFO pCpu = HWACCMR0GetCurrentCpu();
-
+ PHMGLOBLCPUINFO pCpu = HWACCMR0GetCurrentCpu();
ASMAtomicWriteBool(&pCpu->fInUse, true);
ASMSetFlags(fFlags);
- /* Terminate a VT-x or AMD-V VM. */
- rc = HWACCMR0Globals.pfnTermVM(pVM);
+ int rc = g_HvmR0.pfnTermVM(pVM);
ASMAtomicWriteBool(&pCpu->fInUse, false);
return rc;
@@ -1073,52 +1285,56 @@ VMMR0DECL(int) HWACCMR0TermVM(PVM pVM)
/**
- * Sets up a VT-x or AMD-V session
+ * Sets up a VT-x or AMD-V session.
+ *
+ * This is mostly about setting up the hardware VM state.
*
* @returns VBox status code.
* @param pVM The VM to operate on.
*/
VMMR0DECL(int) HWACCMR0SetupVM(PVM pVM)
{
- int rc;
- RTCPUID idCpu = RTMpCpuId();
- PHWACCM_CPUINFO pCpu = &HWACCMR0Globals.aCpuInfo[idCpu];
-
+ Log(("HWACCMR0SetupVM: %p\n", pVM));
AssertReturn(pVM, VERR_INVALID_PARAMETER);
- /* Make sure we don't touch hwaccm after we've disabled hwaccm in preparation of a suspend. */
- AssertReturn(!ASMAtomicReadBool(&HWACCMR0Globals.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
+ /* Make sure we don't touch hwaccm after we've disabled hwaccm in
+ preparation of a suspend. */
+ AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
-#ifdef LOG_ENABLED
- SUPR0Printf("HWACCMR0SetupVM: %p\n", pVM);
-#endif
+ /*
+ * Call the hardware specific setup VM method. This requires the CPU to be
+ * enabled for AMD-V/VT-x and preemption to be prevented.
+ */
+ RTCCUINTREG fFlags = ASMIntDisableFlags();
+ RTCPUID idCpu = RTMpCpuId();
+ PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[idCpu];
ASMAtomicWriteBool(&pCpu->fInUse, true);
+ /* On first entry we'll sync everything. */
for (VMCPUID i = 0; i < pVM->cCpus; i++)
- {
- /* On first entry we'll sync everything. */
pVM->aCpus[i].hwaccm.s.fContextUseFlags = HWACCM_CHANGED_ALL;
- }
/* Enable VT-x or AMD-V if local init is required. */
- if (!HWACCMR0Globals.fGlobalInit)
+ int rc;
+ if (!g_HvmR0.fGlobalInit)
{
- rc = hwaccmR0EnableCpu(pVM, idCpu);
- AssertRCReturn(rc, rc);
+ rc = hmR0EnableCpu(pVM, idCpu);
+ AssertReturnStmt(RT_SUCCESS_NP(rc), ASMSetFlags(fFlags), rc);
}
/* Setup VT-x or AMD-V. */
- rc = HWACCMR0Globals.pfnSetupVM(pVM);
+ rc = g_HvmR0.pfnSetupVM(pVM);
/* Disable VT-x or AMD-V if local init was done before. */
- if (!HWACCMR0Globals.fGlobalInit)
+ if (!g_HvmR0.fGlobalInit)
{
- rc = hwaccmR0DisableCpu(idCpu);
- AssertRC(rc);
+ int rc2 = hmR0DisableCpu(idCpu);
+ AssertRC(rc2);
}
ASMAtomicWriteBool(&pCpu->fInUse, false);
+ ASMSetFlags(fFlags);
return rc;
}
@@ -1128,24 +1344,24 @@ VMMR0DECL(int) HWACCMR0SetupVM(PVM pVM)
* Enters the VT-x or AMD-V session
*
* @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pVCpu VMCPUD id.
+ * @param pVM The VM to operate on.
+ * @param pVCpu VMCPU handle.
+ *
+ * @remarks This is called with preemption disabled.
*/
VMMR0DECL(int) HWACCMR0Enter(PVM pVM, PVMCPU pVCpu)
{
- PCPUMCTX pCtx;
- int rc;
RTCPUID idCpu = RTMpCpuId();
- PHWACCM_CPUINFO pCpu = &HWACCMR0Globals.aCpuInfo[idCpu];
+ PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[idCpu];
- /* Make sure we can't enter a session after we've disabled hwaccm in preparation of a suspend. */
- AssertReturn(!ASMAtomicReadBool(&HWACCMR0Globals.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
+ /* Make sure we can't enter a session after we've disabled HM in preparation of a suspend. */
+ AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
ASMAtomicWriteBool(&pCpu->fInUse, true);
AssertMsg(pVCpu->hwaccm.s.idEnteredCpu == NIL_RTCPUID, ("%d", (int)pVCpu->hwaccm.s.idEnteredCpu));
pVCpu->hwaccm.s.idEnteredCpu = idCpu;
- pCtx = CPUMQueryGuestCtxPtr(pVCpu);
+ PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
/* Always load the guest's FPU/XMM state on-demand. */
CPUMDeactivateGuestFPUState(pVCpu);
@@ -1162,10 +1378,13 @@ VMMR0DECL(int) HWACCMR0Enter(PVM pVM, PVMCPU pVCpu)
else
pVM->hwaccm.s.u64RegisterMask = UINT64_C(0xFFFFFFFF);
- /* Enable VT-x or AMD-V if local init is required. */
- if (!HWACCMR0Globals.fGlobalInit)
+ /* Enable VT-x or AMD-V if local init is required, or enable if it's a
+ freshly onlined CPU. */
+ int rc;
+ if ( !pCpu->fConfigured
+ || !g_HvmR0.fGlobalInit)
{
- rc = hwaccmR0EnableCpu(pVM, idCpu);
+ rc = hmR0EnableCpu(pVM, idCpu);
AssertRCReturn(rc, rc);
}
@@ -1173,12 +1392,13 @@ VMMR0DECL(int) HWACCMR0Enter(PVM pVM, PVMCPU pVCpu)
bool fStartedSet = PGMR0DynMapStartOrMigrateAutoSet(pVCpu);
#endif
- rc = HWACCMR0Globals.pfnEnterSession(pVM, pVCpu, pCpu);
+ rc = g_HvmR0.pfnEnterSession(pVM, pVCpu, pCpu);
AssertRC(rc);
- /* We must save the host context here (VT-x) as we might be rescheduled on a different cpu after a long jump back to ring 3. */
- rc |= HWACCMR0Globals.pfnSaveHostState(pVM, pVCpu);
+ /* We must save the host context here (VT-x) as we might be rescheduled on
+ a different cpu after a long jump back to ring 3. */
+ rc |= g_HvmR0.pfnSaveHostState(pVM, pVCpu);
AssertRC(rc);
- rc |= HWACCMR0Globals.pfnLoadGuestState(pVM, pVCpu, pCtx);
+ rc |= g_HvmR0.pfnLoadGuestState(pVM, pVCpu, pCtx);
AssertRC(rc);
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
@@ -1186,7 +1406,8 @@ VMMR0DECL(int) HWACCMR0Enter(PVM pVM, PVMCPU pVCpu)
PGMRZDynMapReleaseAutoSet(pVCpu);
#endif
- /* keep track of the CPU owning the VMCS for debugging scheduling weirdness and ring-3 calls. */
+ /* Keep track of the CPU owning the VMCS for debugging scheduling weirdness
+ and ring-3 calls. */
if (RT_FAILURE(rc))
pVCpu->hwaccm.s.idEnteredCpu = NIL_RTCPUID;
return rc;
@@ -1197,25 +1418,30 @@ VMMR0DECL(int) HWACCMR0Enter(PVM pVM, PVMCPU pVCpu)
* Leaves the VT-x or AMD-V session
*
* @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pVCpu VMCPUD id.
+ * @param pVM The VM to operate on.
+ * @param pVCpu VMCPU handle.
+ *
+ * @remarks Called with preemption disabled just like HWACCMR0Enter, our
+ * counterpart.
*/
VMMR0DECL(int) HWACCMR0Leave(PVM pVM, PVMCPU pVCpu)
{
- PCPUMCTX pCtx;
int rc;
RTCPUID idCpu = RTMpCpuId();
- PHWACCM_CPUINFO pCpu = &HWACCMR0Globals.aCpuInfo[idCpu];
-
- AssertReturn(!ASMAtomicReadBool(&HWACCMR0Globals.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
+ PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[idCpu];
+ PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
- pCtx = CPUMQueryGuestCtxPtr(pVCpu);
+ /** @todo r=bird: This can't be entirely right? */
+ AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
- /* Note: It's rather tricky with longjmps done by e.g. Log statements or the page fault handler.
- * We must restore the host FPU here to make absolutely sure we don't leave the guest FPU state active
- * or trash somebody else's FPU state.
+ /*
+ * Save the guest FPU and XMM state if necessary.
+ *
+ * Note! It's rather tricky with longjmps done by e.g. Log statements or
+ * the page fault handler. We must restore the host FPU here to make
+ * absolutely sure we don't leave the guest FPU state active or trash
+ * somebody else's FPU state.
*/
- /* Save the guest FPU and XMM state if necessary. */
if (CPUMIsGuestFPUStateActive(pVCpu))
{
Log2(("CPUMR0SaveGuestFPU\n"));
@@ -1225,21 +1451,20 @@ VMMR0DECL(int) HWACCMR0Leave(PVM pVM, PVMCPU pVCpu)
Assert(!CPUMIsGuestFPUStateActive(pVCpu));
}
- rc = HWACCMR0Globals.pfnLeaveSession(pVM, pVCpu, pCtx);
+ rc = g_HvmR0.pfnLeaveSession(pVM, pVCpu, pCtx);
- /* We don't pass on invlpg information to the recompiler for nested paging guests, so we must make sure the recompiler flushes its TLB
- * the next time it executes code.
- */
+ /* We don't pass on invlpg information to the recompiler for nested paging
+ guests, so we must make sure the recompiler flushes its TLB the next
+ time it executes code. */
if ( pVM->hwaccm.s.fNestedPaging
&& CPUMIsGuestInPagedProtectedModeEx(pCtx))
- {
CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_GLOBAL_TLB_FLUSH);
- }
- /* keep track of the CPU owning the VMCS for debugging scheduling weirdness and ring-3 calls. */
+ /* Keep track of the CPU owning the VMCS for debugging scheduling weirdness
+ and ring-3 calls. */
#ifdef RT_STRICT
- if (RT_UNLIKELY( pVCpu->hwaccm.s.idEnteredCpu != idCpu
- && RT_FAILURE(rc)))
+ if (RT_UNLIKELY( pVCpu->hwaccm.s.idEnteredCpu != idCpu
+ && RT_FAILURE(rc)))
{
AssertMsgFailed(("Owner is %d, I'm %d", (int)pVCpu->hwaccm.s.idEnteredCpu, (int)idCpu));
rc = VERR_INTERNAL_ERROR;
@@ -1247,10 +1472,12 @@ VMMR0DECL(int) HWACCMR0Leave(PVM pVM, PVMCPU pVCpu)
#endif
pVCpu->hwaccm.s.idEnteredCpu = NIL_RTCPUID;
- /* Disable VT-x or AMD-V if local init was done before. */
- if (!HWACCMR0Globals.fGlobalInit)
+ /*
+ * Disable VT-x or AMD-V if local init was done before.
+ */
+ if (!g_HvmR0.fGlobalInit)
{
- rc = hwaccmR0DisableCpu(idCpu);
+ rc = hmR0DisableCpu(idCpu);
AssertRC(rc);
/* Reset these to force a TLB flush for the next entry. (-> EXPENSIVE) */
@@ -1263,34 +1490,32 @@ VMMR0DECL(int) HWACCMR0Leave(PVM pVM, PVMCPU pVCpu)
return rc;
}
+
/**
* Runs guest code in a hardware accelerated VM.
*
* @returns VBox status code.
* @param pVM The VM to operate on.
- * @param pVCpu VMCPUD id.
+ * @param pVCpu VMCPUD id.
+ *
+ * @remarks Called with preemption disabled and after first having called
+ * HWACCMR0Enter.
*/
VMMR0DECL(int) HWACCMR0RunGuestCode(PVM pVM, PVMCPU pVCpu)
{
- CPUMCTX *pCtx;
- int rc;
#ifdef VBOX_STRICT
- RTCPUID idCpu = RTMpCpuId(); NOREF(idCpu);
- PHWACCM_CPUINFO pCpu = &HWACCMR0Globals.aCpuInfo[idCpu];
-#endif
-
+ PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[RTMpCpuId()];
Assert(!VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL));
- Assert(HWACCMR0Globals.aCpuInfo[idCpu].fConfigured);
- AssertReturn(!ASMAtomicReadBool(&HWACCMR0Globals.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
+ Assert(pCpu->fConfigured);
+ AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
Assert(ASMAtomicReadBool(&pCpu->fInUse) == true);
+#endif
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
PGMRZDynMapStartAutoSet(pVCpu);
#endif
- pCtx = CPUMQueryGuestCtxPtr(pVCpu);
-
- rc = HWACCMR0Globals.pfnRunGuestCode(pVM, pVCpu, pCtx);
+ int rc = g_HvmR0.pfnRunGuestCode(pVM, pVCpu, CPUMQueryGuestCtxPtr(pVCpu));
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
PGMRZDynMapReleaseAutoSet(pVCpu);
@@ -1298,8 +1523,8 @@ VMMR0DECL(int) HWACCMR0RunGuestCode(PVM pVM, PVMCPU pVCpu)
return rc;
}
-
#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+
/**
* Save guest FPU/XMM state (64 bits guest mode & 32 bits host only)
*
@@ -1313,10 +1538,10 @@ VMMR0DECL(int) HWACCMR0SaveFPUState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFpu64SwitchBack);
if (pVM->hwaccm.s.vmx.fSupported)
return VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnSaveGuestFPU64, 0, NULL);
-
return SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnSaveGuestFPU64, 0, NULL);
}
+
/**
* Save guest debug state (64 bits guest mode & 32 bits host only)
*
@@ -1330,10 +1555,10 @@ VMMR0DECL(int) HWACCMR0SaveDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatDebug64SwitchBack);
if (pVM->hwaccm.s.vmx.fSupported)
return VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnSaveGuestDebug64, 0, NULL);
-
return SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnSaveGuestDebug64, 0, NULL);
}
+
/**
* Test the 32->64 bits switcher
*
@@ -1343,18 +1568,17 @@ VMMR0DECL(int) HWACCMR0SaveDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
VMMR0DECL(int) HWACCMR0TestSwitcher3264(PVM pVM)
{
PVMCPU pVCpu = &pVM->aCpus[0];
- CPUMCTX *pCtx;
+ PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
uint32_t aParam[5] = {0, 1, 2, 3, 4};
int rc;
- pCtx = CPUMQueryGuestCtxPtr(pVCpu);
-
STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatWorldSwitch3264, z);
if (pVM->hwaccm.s.vmx.fSupported)
rc = VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnTest64, 5, &aParam[0]);
else
rc = SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnTest64, 5, &aParam[0]);
STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatWorldSwitch3264, z);
+
return rc;
}
@@ -1365,24 +1589,26 @@ VMMR0DECL(int) HWACCMR0TestSwitcher3264(PVM pVM)
*
* @returns Suspend pending or not
*/
-VMMR0DECL(bool) HWACCMR0SuspendPending()
+VMMR0DECL(bool) HWACCMR0SuspendPending(void)
{
- return ASMAtomicReadBool(&HWACCMR0Globals.fSuspended);
+ return ASMAtomicReadBool(&g_HvmR0.fSuspended);
}
+
/**
* Returns the cpu structure for the current cpu.
* Keep in mind that there is no guarantee it will stay the same (long jumps to ring 3!!!).
*
* @returns cpu structure pointer
*/
-VMMR0DECL(PHWACCM_CPUINFO) HWACCMR0GetCurrentCpu()
+VMMR0DECL(PHMGLOBLCPUINFO) HWACCMR0GetCurrentCpu(void)
{
- RTCPUID idCpu = RTMpCpuId();
-
- return &HWACCMR0Globals.aCpuInfo[idCpu];
+ RTCPUID idCpu = RTMpCpuId();
+ Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
+ return &g_HvmR0.aCpuInfo[idCpu];
}
+
/**
* Returns the cpu structure for the current cpu.
* Keep in mind that there is no guarantee it will stay the same (long jumps to ring 3!!!).
@@ -1390,11 +1616,13 @@ VMMR0DECL(PHWACCM_CPUINFO) HWACCMR0GetCurrentCpu()
* @returns cpu structure pointer
* @param idCpu id of the VCPU
*/
-VMMR0DECL(PHWACCM_CPUINFO) HWACCMR0GetCurrentCpuEx(RTCPUID idCpu)
+VMMR0DECL(PHMGLOBLCPUINFO) HWACCMR0GetCurrentCpuEx(RTCPUID idCpu)
{
- return &HWACCMR0Globals.aCpuInfo[idCpu];
+ Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
+ return &g_HvmR0.aCpuInfo[idCpu];
}
+
/**
* Save a pending IO read.
*
@@ -1416,6 +1644,7 @@ VMMR0DECL(void) HWACCMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRip, RT
return;
}
+
/**
* Save a pending IO write.
*
@@ -1436,12 +1665,14 @@ VMMR0DECL(void) HWACCMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRip, R
return;
}
+
/**
- * Disable VT-x if it's active *and* the current switcher turns off paging
+ * Raw-mode switcher hook - disable VT-x if it's active *and* the current
+ * switcher turns off paging.
*
* @returns VBox status code.
* @param pVM VM handle.
- * @param pfVTxDisabled VT-x was disabled or not (out)
+ * @param pfVTxDisabled VT-x was disabled or not (out).
*/
VMMR0DECL(int) HWACCMR0EnterSwitcher(PVM pVM, bool *pfVTxDisabled)
{
@@ -1449,46 +1680,45 @@ VMMR0DECL(int) HWACCMR0EnterSwitcher(PVM pVM, bool *pfVTxDisabled)
*pfVTxDisabled = false;
- if ( HWACCMR0Globals.enmHwAccmState != HWACCMSTATE_ENABLED
- || !HWACCMR0Globals.vmx.fSupported /* no such issues with AMD-V */
- || !HWACCMR0Globals.fGlobalInit /* Local init implies the CPU is currently not in VMX root mode. */)
+ if ( !g_HvmR0.fEnabled
+ || !g_HvmR0.vmx.fSupported /* no such issues with AMD-V */
+ || !g_HvmR0.fGlobalInit /* Local init implies the CPU is currently not in VMX root mode. */)
return VINF_SUCCESS; /* nothing to do */
- switch(VMMGetSwitcher(pVM))
+ switch (VMMGetSwitcher(pVM))
{
- case VMMSWITCHER_32_TO_32:
- case VMMSWITCHER_PAE_TO_PAE:
- return VINF_SUCCESS; /* safe switchers as they don't turn off paging */
-
- case VMMSWITCHER_32_TO_PAE:
- case VMMSWITCHER_PAE_TO_32: /* is this one actually used?? */
- case VMMSWITCHER_AMD64_TO_32:
- case VMMSWITCHER_AMD64_TO_PAE:
- break; /* unsafe switchers */
-
- default:
- AssertFailed();
- return VERR_INTERNAL_ERROR;
+ case VMMSWITCHER_32_TO_32:
+ case VMMSWITCHER_PAE_TO_PAE:
+ return VINF_SUCCESS; /* safe switchers as they don't turn off paging */
+
+ case VMMSWITCHER_32_TO_PAE:
+ case VMMSWITCHER_PAE_TO_32: /* is this one actually used?? */
+ case VMMSWITCHER_AMD64_TO_32:
+ case VMMSWITCHER_AMD64_TO_PAE:
+ break; /* unsafe switchers */
+
+ default:
+ AssertFailed();
+ return VERR_INTERNAL_ERROR;
}
- PHWACCM_CPUINFO pCpu = HWACCMR0GetCurrentCpu();
- void *pvPageCpu;
- RTHCPHYS pPageCpuPhys;
-
- AssertReturn(pCpu && pCpu->pMemObj, VERR_INTERNAL_ERROR);
- pvPageCpu = RTR0MemObjAddress(pCpu->pMemObj);
- pPageCpuPhys = RTR0MemObjGetPagePhysAddr(pCpu->pMemObj, 0);
+ PHMGLOBLCPUINFO pCpu = HWACCMR0GetCurrentCpu();
+ AssertReturn(pCpu && pCpu->hMemObj != NIL_RTR0MEMOBJ, VERR_INTERNAL_ERROR);
*pfVTxDisabled = true;
- return VMXR0DisableCpu(pCpu, pvPageCpu, pPageCpuPhys);
+ void *pvCpuPage = RTR0MemObjAddress(pCpu->hMemObj);
+ RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
+ return VMXR0DisableCpu(pCpu, pvCpuPage, HCPhysCpuPage);
}
+
/**
- * Enable VT-x if was active *and* the current switcher turned off paging
+ * Raw-mode switcher hook - re-enable VT-x if was active *and* the current
+ * switcher turned off paging.
*
* @returns VBox status code.
- * @param pVM VM handle.
- * @param fVTxDisabled VT-x was disabled or not
+ * @param pVM VM handle.
+ * @param fVTxDisabled VT-x was disabled or not.
*/
VMMR0DECL(int) HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled)
{
@@ -1497,22 +1727,20 @@ VMMR0DECL(int) HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled)
if (!fVTxDisabled)
return VINF_SUCCESS; /* nothing to do */
- Assert( HWACCMR0Globals.enmHwAccmState == HWACCMSTATE_ENABLED
- && HWACCMR0Globals.vmx.fSupported
- && HWACCMR0Globals.fGlobalInit);
+ Assert(g_HvmR0.fEnabled);
+ Assert(g_HvmR0.vmx.fSupported);
+ Assert(g_HvmR0.fGlobalInit);
- PHWACCM_CPUINFO pCpu = HWACCMR0GetCurrentCpu();
- void *pvPageCpu;
- RTHCPHYS pPageCpuPhys;
+ PHMGLOBLCPUINFO pCpu = HWACCMR0GetCurrentCpu();
+ AssertReturn(pCpu && pCpu->hMemObj != NIL_RTR0MEMOBJ, VERR_INTERNAL_ERROR);
- AssertReturn(pCpu && pCpu->pMemObj, VERR_INTERNAL_ERROR);
- pvPageCpu = RTR0MemObjAddress(pCpu->pMemObj);
- pPageCpuPhys = RTR0MemObjGetPagePhysAddr(pCpu->pMemObj, 0);
-
- return VMXR0EnableCpu(pCpu, pVM, pvPageCpu, pPageCpuPhys);
+ void *pvCpuPage = RTR0MemObjAddress(pCpu->hMemObj);
+ RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
+ return VMXR0EnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage);
}
#ifdef VBOX_STRICT
+
/**
* Dumps a descriptor.
*
@@ -1635,6 +1863,7 @@ VMMR0DECL(void) HWACCMR0DumpDescriptor(PCX86DESCHC pDesc, RTSEL Sel, const char
# endif
}
+
/**
* Formats a full register dump.
*
@@ -1755,11 +1984,11 @@ VMMR0DECL(void) HWACCMDumpRegs(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
Log(("FPU:\n"
"FCW=%04x FSW=%04x FTW=%02x\n"
- "FOP=%04x FPUIP=%08x CS=%04x Rsvrd1=%04x\n"
+ "FOP=%04x FPUIP=%08x CS=%04x Rsrvd1=%04x\n"
"FPUDP=%04x DS=%04x Rsvrd2=%04x MXCSR=%08x MXCSR_MASK=%08x\n"
,
pCtx->fpu.FCW, pCtx->fpu.FSW, pCtx->fpu.FTW,
- pCtx->fpu.FOP, pCtx->fpu.FPUIP, pCtx->fpu.CS, pCtx->fpu.Rsvrd1,
+ pCtx->fpu.FOP, pCtx->fpu.FPUIP, pCtx->fpu.CS, pCtx->fpu.Rsrvd1,
pCtx->fpu.FPUDP, pCtx->fpu.DS, pCtx->fpu.Rsrvd2,
pCtx->fpu.MXCSR, pCtx->fpu.MXCSR_MASK));
@@ -1781,55 +2010,6 @@ VMMR0DECL(void) HWACCMDumpRegs(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
pCtx->msrKERNELGSBASE));
}
-#endif /* VBOX_STRICT */
-
-/* Dummy callback handlers. */
-VMMR0DECL(int) HWACCMR0DummyEnter(PVM pVM, PVMCPU pVCpu, PHWACCM_CPUINFO pCpu)
-{
- return VINF_SUCCESS;
-}
-VMMR0DECL(int) HWACCMR0DummyLeave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
- return VINF_SUCCESS;
-}
-
-VMMR0DECL(int) HWACCMR0DummyEnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
-{
- return VINF_SUCCESS;
-}
-
-VMMR0DECL(int) HWACCMR0DummyDisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
-{
- return VINF_SUCCESS;
-}
-
-VMMR0DECL(int) HWACCMR0DummyInitVM(PVM pVM)
-{
- return VINF_SUCCESS;
-}
-
-VMMR0DECL(int) HWACCMR0DummyTermVM(PVM pVM)
-{
- return VINF_SUCCESS;
-}
-
-VMMR0DECL(int) HWACCMR0DummySetupVM(PVM pVM)
-{
- return VINF_SUCCESS;
-}
-
-VMMR0DECL(int) HWACCMR0DummyRunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
- return VINF_SUCCESS;
-}
-
-VMMR0DECL(int) HWACCMR0DummySaveHostState(PVM pVM, PVMCPU pVCpu)
-{
- return VINF_SUCCESS;
-}
+#endif /* VBOX_STRICT */
-VMMR0DECL(int) HWACCMR0DummyLoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
- return VINF_SUCCESS;
-}
diff --git a/src/VBox/VMM/VMMR0/HWACCMR0A.asm b/src/VBox/VMM/VMMR0/HWACCMR0A.asm
index 4420e2c98..1804b457b 100644
--- a/src/VBox/VMM/VMMR0/HWACCMR0A.asm
+++ b/src/VBox/VMM/VMMR0/HWACCMR0A.asm
@@ -1,4 +1,4 @@
-; $Id: HWACCMR0A.asm $
+; $Id: HWACCMR0A.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; VMXM - R0 vmx helpers
;
@@ -22,7 +22,7 @@
%include "VBox/err.mac"
%include "VBox/vmm/hwacc_vmx.mac"
%include "VBox/vmm/cpum.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "HWACCMInternal.mac"
%ifdef RT_OS_OS2 ;; @todo fix OMF support in yasm and kick nasm out completely.
diff --git a/src/VBox/VMM/VMMR0/HWACCMR0Mixed.mac b/src/VBox/VMM/VMMR0/HWACCMR0Mixed.mac
index 13a9e1bbf..7e301d03a 100644
--- a/src/VBox/VMM/VMMR0/HWACCMR0Mixed.mac
+++ b/src/VBox/VMM/VMMR0/HWACCMR0Mixed.mac
@@ -1,4 +1,4 @@
-; $Id: HWACCMR0Mixed.mac $
+; $Id: HWACCMR0Mixed.mac 30414 2010-06-24 08:46:18Z vboxsync $
;; @file
; HWACCMR0Mixed.mac - Stuff that darwin needs to build two versions of.
;
diff --git a/src/VBox/VMM/VMMR0/HWSVMR0.cpp b/src/VBox/VMM/VMMR0/HWSVMR0.cpp
index f70e6db92..057ec4e22 100644
--- a/src/VBox/VMM/VMMR0/HWSVMR0.cpp
+++ b/src/VBox/VMM/VMMR0/HWSVMR0.cpp
@@ -1,4 +1,4 @@
-/* $Id: HWSVMR0.cpp $ */
+/* $Id: HWSVMR0.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* HWACCM SVM - Host Context Ring 0.
*/
@@ -28,7 +28,6 @@
#include <VBox/vmm/pdmapi.h>
#include "HWACCMInternal.h"
#include <VBox/vmm/vm.h>
-#include <VBox/x86.h>
#include <VBox/vmm/hwacc_svm.h>
#include <VBox/err.h>
#include <VBox/log.h>
@@ -44,6 +43,7 @@
#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
# include <iprt/thread.h>
#endif
+#include <iprt/x86.h>
#include "HWSVMR0.h"
/*******************************************************************************
@@ -63,34 +63,34 @@ static void svmR0SetMSRPermission(PVMCPU pVCpu, unsigned ulMSR, bool fRead, bool
* @returns VBox status code.
* @param pCpu CPU info struct
* @param pVM The VM to operate on. (can be NULL after a resume!!)
- * @param pvPageCpu Pointer to the global cpu page
- * @param pPageCpuPhys Physical address of the global cpu page
+ * @param pvCpuPage Pointer to the global cpu page.
+ * @param HCPhysCpuPage Physical address of the global cpu page.
*/
-VMMR0DECL(int) SVMR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
+VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
{
- AssertReturn(pPageCpuPhys, VERR_INVALID_PARAMETER);
- AssertReturn(pvPageCpu, VERR_INVALID_PARAMETER);
+ AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
+ AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
- /* We must turn on AMD-V and setup the host state physical address, as those MSRs are per-cpu/core. */
- uint64_t val = ASMRdMsr(MSR_K6_EFER);
- if (val & MSR_K6_EFER_SVME)
+ /* We must turn on AMD-V and setup the host state physical address, as
+ those MSRs are per-cpu/core. */
+ uint64_t fEfer = ASMRdMsr(MSR_K6_EFER);
+ if (fEfer & MSR_K6_EFER_SVME)
{
- /* If the VBOX_HWVIRTEX_IGNORE_SVM_IN_USE hack is active, then we blindly use AMD-V. */
+ /* If the VBOX_HWVIRTEX_IGNORE_SVM_IN_USE hack is active, then we
+ blindly use AMD-V. */
if ( pVM
&& pVM->hwaccm.s.svm.fIgnoreInUseError)
- {
pCpu->fIgnoreAMDVInUseError = true;
- }
-
if (!pCpu->fIgnoreAMDVInUseError)
return VERR_SVM_IN_USE;
}
/* Turn on AMD-V in the EFER MSR. */
- ASMWrMsr(MSR_K6_EFER, val | MSR_K6_EFER_SVME);
+ ASMWrMsr(MSR_K6_EFER, fEfer | MSR_K6_EFER_SVME);
- /* Write the physical page address where the CPU will store the host state while executing the VM. */
- ASMWrMsr(MSR_K8_VM_HSAVE_PA, pPageCpuPhys);
+ /* Write the physical page address where the CPU will store the host state
+ while executing the VM. */
+ ASMWrMsr(MSR_K8_VM_HSAVE_PA, HCPhysCpuPage);
return VINF_SUCCESS;
}
@@ -100,17 +100,17 @@ VMMR0DECL(int) SVMR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RT
*
* @returns VBox status code.
* @param pCpu CPU info struct
- * @param pvPageCpu Pointer to the global cpu page
- * @param pPageCpuPhys Physical address of the global cpu page
+ * @param pvCpuPage Pointer to the global cpu page.
+ * @param HCPhysCpuPage Physical address of the global cpu page.
*/
-VMMR0DECL(int) SVMR0DisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
+VMMR0DECL(int) SVMR0DisableCpu(PHMGLOBLCPUINFO pCpu, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
{
- AssertReturn(pPageCpuPhys, VERR_INVALID_PARAMETER);
- AssertReturn(pvPageCpu, VERR_INVALID_PARAMETER);
+ AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
+ AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
/* Turn off AMD-V in the EFER MSR. */
- uint64_t val = ASMRdMsr(MSR_K6_EFER);
- ASMWrMsr(MSR_K6_EFER, val & ~MSR_K6_EFER_SVME);
+ uint64_t fEfer = ASMRdMsr(MSR_K6_EFER);
+ ASMWrMsr(MSR_K6_EFER, fEfer & ~MSR_K6_EFER_SVME);
/* Invalidate host state physical address. */
ASMWrMsr(MSR_K8_VM_HSAVE_PA, 0);
@@ -966,7 +966,7 @@ VMMR0DECL(int) SVMR0RunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
bool fSyncTPR = false;
unsigned cResume = 0;
uint8_t u8LastTPR;
- PHWACCM_CPUINFO pCpu = 0;
+ PHMGLOBLCPUINFO pCpu = 0;
RTCCUINTREG uOldEFlags = ~(RTCCUINTREG)0;
#ifdef VBOX_STRICT
RTCPUID idCpuCheck;
@@ -1214,14 +1214,16 @@ ResumeExecution:
pVCpu->hwaccm.s.idLastCpu = pCpu->idCpu;
- /** Set TLB flush state as checked until we return from the world switch. */
- ASMAtomicWriteU8(&pVCpu->hwaccm.s.fCheckedTLBFlush, true);
+ /* Set TLB flush state as checked until we return from the world switch. */
+ ASMAtomicWriteBool(&pVCpu->hwaccm.s.fCheckedTLBFlush, true);
/* Check for tlb shootdown flushes. */
if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_TLB_FLUSH))
pVCpu->hwaccm.s.fForceTLBFlush = true;
- /* Make sure we flush the TLB when required. Switch ASID to achieve the same thing, but without actually flushing the whole TLB (which is expensive). */
+ /* Make sure we flush the TLB when required. Switch ASID to achieve the
+ same thing, but without actually flushing the whole TLB (which is
+ expensive). */
if ( pVCpu->hwaccm.s.fForceTLBFlush
&& !pVM->hwaccm.s.svm.fAlwaysFlushTLB)
{
@@ -1293,8 +1295,8 @@ ResumeExecution:
#else
pVCpu->hwaccm.s.svm.pfnVMRun(pVCpu->hwaccm.s.svm.pVMCBHostPhys, pVCpu->hwaccm.s.svm.pVMCBPhys, pCtx, pVM, pVCpu);
#endif
- ASMAtomicWriteU8(&pVCpu->hwaccm.s.fCheckedTLBFlush, false);
- ASMAtomicIncU32(&pVCpu->hwaccm.s.cWorldSwitchExit);
+ ASMAtomicWriteBool(&pVCpu->hwaccm.s.fCheckedTLBFlush, false);
+ ASMAtomicIncU32(&pVCpu->hwaccm.s.cWorldSwitchExits);
/* Possibly the last TSC value seen by the guest (too high) (only when we're in tsc offset mode). */
if (!(pVMCB->ctrl.u32InterceptCtrl1 & SVM_CTRL1_INTERCEPT_RDTSC))
TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVMCB->ctrl.u64TSCOffset - 0x400 /* guestimate of world switch overhead in clock ticks */);
@@ -2621,7 +2623,7 @@ static int svmR0EmulateTprVMMCall(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
* @param pVCpu The VM CPU to operate on.
* @param pCpu CPU info struct
*/
-VMMR0DECL(int) SVMR0Enter(PVM pVM, PVMCPU pVCpu, PHWACCM_CPUINFO pCpu)
+VMMR0DECL(int) SVMR0Enter(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu)
{
Assert(pVM->hwaccm.s.svm.fSupported);
diff --git a/src/VBox/VMM/VMMR0/HWSVMR0.h b/src/VBox/VMM/VMMR0/HWSVMR0.h
index 97463bef6..7562d6370 100644
--- a/src/VBox/VMM/VMMR0/HWSVMR0.h
+++ b/src/VBox/VMM/VMMR0/HWSVMR0.h
@@ -1,4 +1,4 @@
-/* $Id: HWSVMR0.h $ */
+/* $Id: HWSVMR0.h 37320 2011-06-03 15:05:36Z vboxsync $ */
/** @file
* HWACCM AMD-V - Internal header file.
*/
@@ -45,7 +45,7 @@ RT_C_DECLS_BEGIN
* @param pVCpu The VMCPU to operate on.
* @param pCpu CPU info struct
*/
-VMMR0DECL(int) SVMR0Enter(PVM pVM, PVMCPU pVCpu, PHWACCM_CPUINFO pCpu);
+VMMR0DECL(int) SVMR0Enter(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu);
/**
* Leaves the AMD-V session
@@ -66,7 +66,7 @@ VMMR0DECL(int) SVMR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
* @param pvPageCpu Pointer to the global cpu page
* @param pPageCpuPhys Physical address of the global cpu page
*/
-VMMR0DECL(int) SVMR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
+VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS HCPhysCpuPage);
/**
* Deactivates AMD-V on the current CPU
@@ -76,7 +76,7 @@ VMMR0DECL(int) SVMR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RT
* @param pvPageCpu Pointer to the global cpu page
* @param pPageCpuPhys Physical address of the global cpu page
*/
-VMMR0DECL(int) SVMR0DisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
+VMMR0DECL(int) SVMR0DisableCpu(PHMGLOBLCPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
/**
* Does Ring-0 per VM AMD-V init.
diff --git a/src/VBox/VMM/VMMR0/HWVMXR0.cpp b/src/VBox/VMM/VMMR0/HWVMXR0.cpp
index 27b2d0530..6bb9dc772 100644
--- a/src/VBox/VMM/VMMR0/HWVMXR0.cpp
+++ b/src/VBox/VMM/VMMR0/HWVMXR0.cpp
@@ -1,4 +1,4 @@
-/* $Id: HWVMXR0.cpp $ */
+/* $Id: HWVMXR0.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* HWACCM VMX - Host Context Ring 0.
*/
@@ -30,7 +30,6 @@
#include <VBox/vmm/tm.h>
#include "HWACCMInternal.h"
#include <VBox/vmm/vm.h>
-#include <VBox/x86.h>
#include <VBox/vmm/pdmapi.h>
#include <VBox/err.h>
#include <VBox/log.h>
@@ -41,6 +40,7 @@
#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
# include <iprt/thread.h>
#endif
+#include <iprt/x86.h>
#include "HWVMXR0.h"
/*******************************************************************************
@@ -100,18 +100,18 @@ static void VMXR0CheckError(PVM pVM, PVMCPU pVCpu, int rc)
* @returns VBox status code.
* @param pCpu CPU info struct
* @param pVM The VM to operate on. (can be NULL after a resume!!)
- * @param pvPageCpu Pointer to the global cpu page
- * @param pPageCpuPhys Physical address of the global cpu page
+ * @param pvCpuPage Pointer to the global cpu page.
+ * @param HCPhysCpuPage Physical address of the global cpu page.
*/
-VMMR0DECL(int) VMXR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
+VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
{
- AssertReturn(pPageCpuPhys, VERR_INVALID_PARAMETER);
- AssertReturn(pvPageCpu, VERR_INVALID_PARAMETER);
+ AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
+ AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
if (pVM)
{
/* Set revision dword at the beginning of the VMXON structure. */
- *(uint32_t *)pvPageCpu = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info);
+ *(uint32_t *)pvCpuPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info);
}
/** @todo we should unmap the two pages from the virtual address space in order to prevent accidental corruption.
@@ -124,8 +124,8 @@ VMMR0DECL(int) VMXR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RT
/* Make sure the VMX instructions don't cause #UD faults. */
ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE);
- /* Enter VMX Root Mode */
- int rc = VMXEnable(pPageCpuPhys);
+ /* Enter VMX Root Mode. */
+ int rc = VMXEnable(HCPhysCpuPage);
if (RT_FAILURE(rc))
{
ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
@@ -139,13 +139,13 @@ VMMR0DECL(int) VMXR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RT
*
* @returns VBox status code.
* @param pCpu CPU info struct
- * @param pvPageCpu Pointer to the global cpu page
- * @param pPageCpuPhys Physical address of the global cpu page
+ * @param pvCpuPage Pointer to the global cpu page.
+ * @param HCPhysCpuPage Physical address of the global cpu page.
*/
-VMMR0DECL(int) VMXR0DisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
+VMMR0DECL(int) VMXR0DisableCpu(PHMGLOBLCPUINFO pCpu, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
{
- AssertReturn(pPageCpuPhys, VERR_INVALID_PARAMETER);
- AssertReturn(pvPageCpu, VERR_INVALID_PARAMETER);
+ AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
+ AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
/* If we're somehow not in VMX root mode, then we shouldn't dare leaving it. */
if (!(ASMGetCR4() & X86_CR4_VMXE))
@@ -154,7 +154,7 @@ VMMR0DECL(int) VMXR0DisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS p
/* Leave VMX Root Mode. */
VMXDisable();
- /* And clear the X86_CR4_VMXE bit */
+ /* And clear the X86_CR4_VMXE bit. */
ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
return VINF_SUCCESS;
}
@@ -178,7 +178,7 @@ VMMR0DECL(int) VMXR0InitVM(PVM pVM)
if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
{
/* Allocate one page for the APIC physical page (serves for filtering accesses). */
- rc = RTR0MemObjAllocCont(&pVM->hwaccm.s.vmx.pMemObjAPIC, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
+ rc = RTR0MemObjAllocCont(&pVM->hwaccm.s.vmx.pMemObjAPIC, PAGE_SIZE, true /* executable R0 mapping */);
AssertRC(rc);
if (RT_FAILURE(rc))
return rc;
@@ -196,7 +196,7 @@ VMMR0DECL(int) VMXR0InitVM(PVM pVM)
#ifdef VBOX_WITH_CRASHDUMP_MAGIC
{
- rc = RTR0MemObjAllocCont(&pVM->hwaccm.s.vmx.pMemObjScratch, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
+ rc = RTR0MemObjAllocCont(&pVM->hwaccm.s.vmx.pMemObjScratch, PAGE_SIZE, true /* executable R0 mapping */);
AssertRC(rc);
if (RT_FAILURE(rc))
return rc;
@@ -215,35 +215,35 @@ VMMR0DECL(int) VMXR0InitVM(PVM pVM)
{
PVMCPU pVCpu = &pVM->aCpus[i];
- pVCpu->hwaccm.s.vmx.pMemObjVMCS = NIL_RTR0MEMOBJ;
+ pVCpu->hwaccm.s.vmx.hMemObjVMCS = NIL_RTR0MEMOBJ;
/* Allocate one page for the VM control structure (VMCS). */
- rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjVMCS, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
+ rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.hMemObjVMCS, PAGE_SIZE, true /* executable R0 mapping */);
AssertRC(rc);
if (RT_FAILURE(rc))
return rc;
- pVCpu->hwaccm.s.vmx.pVMCS = RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.pMemObjVMCS);
- pVCpu->hwaccm.s.vmx.pVMCSPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.pMemObjVMCS, 0);
- ASMMemZero32(pVCpu->hwaccm.s.vmx.pVMCS, PAGE_SIZE);
+ pVCpu->hwaccm.s.vmx.pvVMCS = RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.hMemObjVMCS);
+ pVCpu->hwaccm.s.vmx.HCPhysVMCS = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.hMemObjVMCS, 0);
+ ASMMemZeroPage(pVCpu->hwaccm.s.vmx.pvVMCS);
pVCpu->hwaccm.s.vmx.cr0_mask = 0;
pVCpu->hwaccm.s.vmx.cr4_mask = 0;
/* Allocate one page for the virtual APIC page for TPR caching. */
- rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjVAPIC, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
+ rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.hMemObjVAPIC, PAGE_SIZE, true /* executable R0 mapping */);
AssertRC(rc);
if (RT_FAILURE(rc))
return rc;
- pVCpu->hwaccm.s.vmx.pVAPIC = (uint8_t *)RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.pMemObjVAPIC);
- pVCpu->hwaccm.s.vmx.pVAPICPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.pMemObjVAPIC, 0);
- ASMMemZero32(pVCpu->hwaccm.s.vmx.pVAPIC, PAGE_SIZE);
+ pVCpu->hwaccm.s.vmx.pbVAPIC = (uint8_t *)RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.hMemObjVAPIC);
+ pVCpu->hwaccm.s.vmx.HCPhysVAPIC = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.hMemObjVAPIC, 0);
+ ASMMemZeroPage(pVCpu->hwaccm.s.vmx.pbVAPIC);
/* Allocate the MSR bitmap if this feature is supported. */
if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
{
- rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
+ rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap, PAGE_SIZE, true /* executable R0 mapping */);
AssertRC(rc);
if (RT_FAILURE(rc))
return rc;
@@ -255,7 +255,7 @@ VMMR0DECL(int) VMXR0InitVM(PVM pVM)
#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
/* Allocate one page for the guest MSR load area (for preloading guest MSRs during the world switch). */
- rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjGuestMSR, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
+ rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjGuestMSR, PAGE_SIZE, true /* executable R0 mapping */);
AssertRC(rc);
if (RT_FAILURE(rc))
return rc;
@@ -265,7 +265,7 @@ VMMR0DECL(int) VMXR0InitVM(PVM pVM)
memset(pVCpu->hwaccm.s.vmx.pGuestMSR, 0, PAGE_SIZE);
/* Allocate one page for the host MSR load area (for restoring host MSRs after the world switch back). */
- rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjHostMSR, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
+ rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjHostMSR, PAGE_SIZE, true /* executable R0 mapping */);
AssertRC(rc);
if (RT_FAILURE(rc))
return rc;
@@ -279,7 +279,7 @@ VMMR0DECL(int) VMXR0InitVM(PVM pVM)
pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode = PGMMODE_REAL;
#ifdef LOG_ENABLED
- SUPR0Printf("VMXR0InitVM %x VMCS=%x (%x)\n", pVM, pVCpu->hwaccm.s.vmx.pVMCS, (uint32_t)pVCpu->hwaccm.s.vmx.pVMCSPhys);
+ SUPR0Printf("VMXR0InitVM %x VMCS=%x (%x)\n", pVM, pVCpu->hwaccm.s.vmx.pvVMCS, (uint32_t)pVCpu->hwaccm.s.vmx.HCPhysVMCS);
#endif
}
@@ -298,19 +298,19 @@ VMMR0DECL(int) VMXR0TermVM(PVM pVM)
{
PVMCPU pVCpu = &pVM->aCpus[i];
- if (pVCpu->hwaccm.s.vmx.pMemObjVMCS != NIL_RTR0MEMOBJ)
+ if (pVCpu->hwaccm.s.vmx.hMemObjVMCS != NIL_RTR0MEMOBJ)
{
- RTR0MemObjFree(pVCpu->hwaccm.s.vmx.pMemObjVMCS, false);
- pVCpu->hwaccm.s.vmx.pMemObjVMCS = NIL_RTR0MEMOBJ;
- pVCpu->hwaccm.s.vmx.pVMCS = 0;
- pVCpu->hwaccm.s.vmx.pVMCSPhys = 0;
+ RTR0MemObjFree(pVCpu->hwaccm.s.vmx.hMemObjVMCS, false);
+ pVCpu->hwaccm.s.vmx.hMemObjVMCS = NIL_RTR0MEMOBJ;
+ pVCpu->hwaccm.s.vmx.pvVMCS = 0;
+ pVCpu->hwaccm.s.vmx.HCPhysVMCS = 0;
}
- if (pVCpu->hwaccm.s.vmx.pMemObjVAPIC != NIL_RTR0MEMOBJ)
+ if (pVCpu->hwaccm.s.vmx.hMemObjVAPIC != NIL_RTR0MEMOBJ)
{
- RTR0MemObjFree(pVCpu->hwaccm.s.vmx.pMemObjVAPIC, false);
- pVCpu->hwaccm.s.vmx.pMemObjVAPIC = NIL_RTR0MEMOBJ;
- pVCpu->hwaccm.s.vmx.pVAPIC = 0;
- pVCpu->hwaccm.s.vmx.pVAPICPhys = 0;
+ RTR0MemObjFree(pVCpu->hwaccm.s.vmx.hMemObjVAPIC, false);
+ pVCpu->hwaccm.s.vmx.hMemObjVAPIC = NIL_RTR0MEMOBJ;
+ pVCpu->hwaccm.s.vmx.pbVAPIC = 0;
+ pVCpu->hwaccm.s.vmx.HCPhysVAPIC = 0;
}
if (pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap != NIL_RTR0MEMOBJ)
{
@@ -373,19 +373,19 @@ VMMR0DECL(int) VMXR0SetupVM(PVM pVM)
{
PVMCPU pVCpu = &pVM->aCpus[i];
- Assert(pVCpu->hwaccm.s.vmx.pVMCS);
+ AssertPtr(pVCpu->hwaccm.s.vmx.pvVMCS);
/* Set revision dword at the beginning of the VMCS structure. */
- *(uint32_t *)pVCpu->hwaccm.s.vmx.pVMCS = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info);
+ *(uint32_t *)pVCpu->hwaccm.s.vmx.pvVMCS = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info);
/* Clear VM Control Structure. */
- Log(("pVMCSPhys = %RHp\n", pVCpu->hwaccm.s.vmx.pVMCSPhys));
- rc = VMXClearVMCS(pVCpu->hwaccm.s.vmx.pVMCSPhys);
+ Log(("HCPhysVMCS = %RHp\n", pVCpu->hwaccm.s.vmx.HCPhysVMCS));
+ rc = VMXClearVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
if (RT_FAILURE(rc))
goto vmx_end;
/* Activate the VM Control Structure. */
- rc = VMXActivateVMCS(pVCpu->hwaccm.s.vmx.pVMCSPhys);
+ rc = VMXActivateVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
if (RT_FAILURE(rc))
goto vmx_end;
@@ -560,7 +560,7 @@ VMMR0DECL(int) VMXR0SetupVM(PVM pVM)
Assert(pVM->hwaccm.s.vmx.pMemObjAPIC);
/* Optional */
rc = VMXWriteVMCS(VMX_VMCS_CTRL_TPR_THRESHOLD, 0);
- rc |= VMXWriteVMCS64(VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL, pVCpu->hwaccm.s.vmx.pVAPICPhys);
+ rc |= VMXWriteVMCS64(VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL, pVCpu->hwaccm.s.vmx.HCPhysVAPIC);
if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
rc |= VMXWriteVMCS64(VMX_VMCS_CTRL_APIC_ACCESSADDR_FULL, pVM->hwaccm.s.vmx.pAPICPhys);
@@ -573,7 +573,7 @@ VMMR0DECL(int) VMXR0SetupVM(PVM pVM)
AssertRC(rc);
/* Clear VM Control Structure. Marking it inactive, clearing implementation specific data and writing back VMCS data to memory. */
- rc = VMXClearVMCS(pVCpu->hwaccm.s.vmx.pVMCSPhys);
+ rc = VMXClearVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
AssertRC(rc);
/* Configure the VMCS read cache. */
@@ -1236,23 +1236,26 @@ VMMR0DECL(int) VMXR0SaveHostState(PVM pVM, PVMCPU pVCpu)
/**
* Prefetch the 4 PDPT pointers (PAE and nested paging only)
*
+ * @returns VINF_SUCCESS or fatal error.
* @param pVM The VM to operate on.
* @param pVCpu The VMCPU to operate on.
* @param pCtx Guest context
*/
-static void vmxR0PrefetchPAEPdptrs(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+static int vmxR0PrefetchPAEPdptrs(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
{
if (CPUMIsGuestInPAEModeEx(pCtx))
{
- X86PDPE Pdpe;
-
for (unsigned i=0;i<4;i++)
{
- Pdpe = PGMGstGetPaePDPtr(pVCpu, i);
- int rc = VMXWriteVMCS64(VMX_VMCS_GUEST_PDPTR0_FULL + i*2, Pdpe.u);
+ X86PDPE Pdpe;
+ int rc = PGMGstQueryPaePDPtr(pVCpu, i, &Pdpe);
+ AssertRCReturn(rc, rc);
+
+ rc = VMXWriteVMCS64(VMX_VMCS_GUEST_PDPTR0_FULL + i*2, Pdpe.u);
AssertRC(rc);
}
}
+ return VINF_SUCCESS;
}
/**
@@ -1532,13 +1535,16 @@ VMMR0DECL(int) VMXR0LoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
val = pCtx->trHid.Attr.u;
- /* The TSS selector must be busy. */
- if ((val & 0xD) == X86_SEL_TYPE_SYS_286_TSS_AVAIL)
- val = (val & ~0xF) | X86_SEL_TYPE_SYS_286_TSS_BUSY;
- else
- /* Default even if no TR selector has been set (otherwise vmlaunch will fail!) */
- val = (val & ~0xF) | X86_SEL_TYPE_SYS_386_TSS_BUSY;
-
+ /* The TSS selector must be busy (REM bugs? see defect #XXXX). */
+ if (!(val & X86_SEL_TYPE_SYS_TSS_BUSY_MASK))
+ {
+ if (val & 0xf)
+ val |= X86_SEL_TYPE_SYS_TSS_BUSY_MASK;
+ else
+ /* Default if no TR selector has been set (otherwise vmlaunch will fail!) */
+ val = (val & ~0xF) | X86_SEL_TYPE_SYS_386_TSS_BUSY;
+ }
+ AssertMsg((val & 0xf) == X86_SEL_TYPE_SYS_386_TSS_BUSY || (val & 0xf) == X86_SEL_TYPE_SYS_286_TSS_BUSY, ("%#x\n", val));
}
rc |= VMXWriteVMCS(VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS, val);
AssertRC(rc);
@@ -1746,7 +1752,8 @@ VMMR0DECL(int) VMXR0LoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
/* Save the real guest CR3 in VMX_VMCS_GUEST_CR3 */
val = pCtx->cr3;
/* Prefetch the four PDPT entries in PAE mode. */
- vmxR0PrefetchPAEPdptrs(pVM, pVCpu, pCtx);
+ rc = vmxR0PrefetchPAEPdptrs(pVM, pVCpu, pCtx);
+ AssertRCReturn(rc, rc);
}
}
else
@@ -2020,7 +2027,8 @@ DECLINLINE(int) VMXR0SaveGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
PGMUpdateCR3(pVCpu, val);
}
/* Prefetch the four PDPT entries in PAE mode. */
- vmxR0PrefetchPAEPdptrs(pVM, pVCpu, pCtx);
+ rc = vmxR0PrefetchPAEPdptrs(pVM, pVCpu, pCtx);
+ AssertRCReturn(rc, rc);
}
/* Sync back DR7 here. */
@@ -2135,7 +2143,7 @@ static void vmxR0SetupTLBDummy(PVM pVM, PVMCPU pVCpu)
*/
static void vmxR0SetupTLBEPT(PVM pVM, PVMCPU pVCpu)
{
- PHWACCM_CPUINFO pCpu;
+ PHMGLOBLCPUINFO pCpu;
Assert(pVM->hwaccm.s.fNestedPaging);
Assert(!pVM->hwaccm.s.vmx.fVPID);
@@ -2198,7 +2206,7 @@ static void vmxR0SetupTLBEPT(PVM pVM, PVMCPU pVCpu)
*/
static void vmxR0SetupTLBVPID(PVM pVM, PVMCPU pVCpu)
{
- PHWACCM_CPUINFO pCpu;
+ PHMGLOBLCPUINFO pCpu;
Assert(pVM->hwaccm.s.vmx.fVPID);
Assert(!pVM->hwaccm.s.fNestedPaging);
@@ -2250,7 +2258,7 @@ static void vmxR0SetupTLBVPID(PVM pVM, PVMCPU pVCpu)
{
/* Deal with pending TLB shootdown actions which were queued when we were not executing code. */
STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdown);
- for (unsigned i=0;i<pVCpu->hwaccm.s.TlbShootdown.cPages;i++)
+ for (unsigned i = 0; i < pVCpu->hwaccm.s.TlbShootdown.cPages; i++)
vmxR0FlushVPID(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushPage, pVCpu->hwaccm.s.TlbShootdown.aPages[i]);
}
}
@@ -2267,12 +2275,12 @@ static void vmxR0SetupTLBVPID(PVM pVM, PVMCPU pVCpu)
if (pVCpu->hwaccm.s.fForceTLBFlush)
vmxR0FlushVPID(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushContext, 0);
-#ifdef VBOX_WITH_STATISTICS
+# ifdef VBOX_WITH_STATISTICS
if (pVCpu->hwaccm.s.fForceTLBFlush)
STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushTLBWorldSwitch);
else
STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatNoFlushTLBWorldSwitch);
-#endif
+# endif
}
#endif /* HWACCM_VTX_WITH_VPID */
@@ -2311,7 +2319,7 @@ VMMR0DECL(int) VMXR0RunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
uint64_t u64LastTime = RTTimeMilliTS();
#endif
- Assert(!(pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) || (pVCpu->hwaccm.s.vmx.pVAPIC && pVM->hwaccm.s.vmx.pAPIC));
+ Assert(!(pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) || (pVCpu->hwaccm.s.vmx.pbVAPIC && pVM->hwaccm.s.vmx.pAPIC));
/* Check if we need to use TPR shadowing. */
if ( CPUMIsGuestInLongModeEx(pCtx)
@@ -2542,7 +2550,7 @@ ResumeExecution:
rc2 = PDMApicGetTPR(pVCpu, &u8LastTPR, &fPending);
AssertRC(rc2);
/* The TPR can be found at offset 0x80 in the APIC mmio page. */
- pVCpu->hwaccm.s.vmx.pVAPIC[0x80] = u8LastTPR;
+ pVCpu->hwaccm.s.vmx.pbVAPIC[0x80] = u8LastTPR;
/* Two options here:
* - external interrupt pending, but masked by the TPR value.
@@ -2581,7 +2589,7 @@ ResumeExecution:
# endif /* HWACCM_VTX_WITH_VPID */
)
{
- PHWACCM_CPUINFO pCpu;
+ PHMGLOBLCPUINFO pCpu;
pCpu = HWACCMR0GetCurrentCpu();
if ( pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu
@@ -2654,8 +2662,8 @@ ResumeExecution:
rc2 = VMXWriteVMCS(VMX_VMCS32_GUEST_ACTIVITY_STATE, VMX_CMS_GUEST_ACTIVITY_ACTIVE);
AssertRC(rc2);
- /** Set TLB flush state as checked until we return from the world switch. */
- ASMAtomicWriteU8(&pVCpu->hwaccm.s.fCheckedTLBFlush, true);
+ /* Set TLB flush state as checked until we return from the world switch. */
+ ASMAtomicWriteBool(&pVCpu->hwaccm.s.fCheckedTLBFlush, true);
/* Deal with tagged TLB setup and invalidation. */
pVM->hwaccm.s.vmx.pfnSetupTaggedTLB(pVM, pVCpu);
@@ -2694,8 +2702,8 @@ ResumeExecution:
#else
rc = pVCpu->hwaccm.s.vmx.pfnStartVM(pVCpu->hwaccm.s.fResumeVM, pCtx, &pVCpu->hwaccm.s.vmx.VMCSCache, pVM, pVCpu);
#endif
- ASMAtomicWriteU8(&pVCpu->hwaccm.s.fCheckedTLBFlush, false);
- ASMAtomicIncU32(&pVCpu->hwaccm.s.cWorldSwitchExit);
+ ASMAtomicWriteBool(&pVCpu->hwaccm.s.fCheckedTLBFlush, false);
+ ASMAtomicIncU32(&pVCpu->hwaccm.s.cWorldSwitchExits);
/* Possibly the last TSC value seen by the guest (too high) (only when we're in tsc offset mode). */
if (!(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT))
TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVCpu->hwaccm.s.vmx.u64TSCOffset - 0x400 /* guestimate of world switch overhead in clock ticks */);
@@ -2708,7 +2716,7 @@ ResumeExecution:
if (pVM->hwaccm.s.fTPRPatchingActive)
{
Assert(pVM->hwaccm.s.fTPRPatchingActive);
- pVCpu->hwaccm.s.vmx.pVAPIC[0x80] = pCtx->msrLSTAR = ASMRdMsr(MSR_K8_LSTAR);
+ pVCpu->hwaccm.s.vmx.pbVAPIC[0x80] = pCtx->msrLSTAR = ASMRdMsr(MSR_K8_LSTAR);
ASMWrMsr(MSR_K8_LSTAR, u64OldLSTAR);
}
@@ -2808,9 +2816,9 @@ ResumeExecution:
/* Sync back the TPR if it was changed. */
if ( fSetupTPRCaching
- && u8LastTPR != pVCpu->hwaccm.s.vmx.pVAPIC[0x80])
+ && u8LastTPR != pVCpu->hwaccm.s.vmx.pbVAPIC[0x80])
{
- rc2 = PDMApicSetTPR(pVCpu, pVCpu->hwaccm.s.vmx.pVAPIC[0x80]);
+ rc2 = PDMApicSetTPR(pVCpu, pVCpu->hwaccm.s.vmx.pbVAPIC[0x80]);
AssertRC(rc2);
}
@@ -4227,7 +4235,7 @@ end:
if (rc == VERR_VMX_INVALID_VMCS_PTR)
{
VMXGetActivateVMCS(&pVCpu->hwaccm.s.vmx.lasterror.u64VMCSPhys);
- pVCpu->hwaccm.s.vmx.lasterror.ulVMCSRevision = *(uint32_t *)pVCpu->hwaccm.s.vmx.pVMCS;
+ pVCpu->hwaccm.s.vmx.lasterror.ulVMCSRevision = *(uint32_t *)pVCpu->hwaccm.s.vmx.pvVMCS;
pVCpu->hwaccm.s.vmx.lasterror.idEnteredCpu = pVCpu->hwaccm.s.idEnteredCpu;
pVCpu->hwaccm.s.vmx.lasterror.idCurrentCpu = RTMpCpuId();
}
@@ -4257,7 +4265,7 @@ end:
* @param pVCpu The VMCPU to operate on.
* @param pCpu CPU info struct
*/
-VMMR0DECL(int) VMXR0Enter(PVM pVM, PVMCPU pVCpu, PHWACCM_CPUINFO pCpu)
+VMMR0DECL(int) VMXR0Enter(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu)
{
Assert(pVM->hwaccm.s.vmx.fSupported);
@@ -4269,7 +4277,7 @@ VMMR0DECL(int) VMXR0Enter(PVM pVM, PVMCPU pVCpu, PHWACCM_CPUINFO pCpu)
}
/* Activate the VM Control Structure. */
- int rc = VMXActivateVMCS(pVCpu->hwaccm.s.vmx.pVMCSPhys);
+ int rc = VMXActivateVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
if (RT_FAILURE(rc))
return rc;
@@ -4315,7 +4323,7 @@ VMMR0DECL(int) VMXR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
Assert(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT);
/* Clear VM Control Structure. Marking it inactive, clearing implementation specific data and writing back VMCS data to memory. */
- int rc = VMXClearVMCS(pVCpu->hwaccm.s.vmx.pVMCSPhys);
+ int rc = VMXClearVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
AssertRC(rc);
return VINF_SUCCESS;
@@ -4606,12 +4614,12 @@ static void VMXR0ReportWorldSwitchError(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc,
DECLASM(int) VMXR0SwitcherStartVM64(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu)
{
uint32_t aParam[6];
- PHWACCM_CPUINFO pCpu;
- RTHCPHYS pPageCpuPhys;
+ PHMGLOBLCPUINFO pCpu;
+ RTHCPHYS HCPhysCpuPage;
int rc;
pCpu = HWACCMR0GetCurrentCpu();
- pPageCpuPhys = RTR0MemObjGetPagePhysAddr(pCpu->pMemObj, 0);
+ HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
#ifdef VBOX_WITH_CRASHDUMP_MAGIC
pCache->uPos = 1;
@@ -4620,19 +4628,19 @@ DECLASM(int) VMXR0SwitcherStartVM64(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE
#endif
#ifdef DEBUG
- pCache->TestIn.pPageCpuPhys = 0;
- pCache->TestIn.pVMCSPhys = 0;
+ pCache->TestIn.HCPhysCpuPage= 0;
+ pCache->TestIn.HCPhysVMCS = 0;
pCache->TestIn.pCache = 0;
- pCache->TestOut.pVMCSPhys = 0;
+ pCache->TestOut.HCPhysVMCS = 0;
pCache->TestOut.pCache = 0;
pCache->TestOut.pCtx = 0;
pCache->TestOut.eflags = 0;
#endif
- aParam[0] = (uint32_t)(pPageCpuPhys); /* Param 1: VMXON physical address - Lo. */
- aParam[1] = (uint32_t)(pPageCpuPhys >> 32); /* Param 1: VMXON physical address - Hi. */
- aParam[2] = (uint32_t)(pVCpu->hwaccm.s.vmx.pVMCSPhys); /* Param 2: VMCS physical address - Lo. */
- aParam[3] = (uint32_t)(pVCpu->hwaccm.s.vmx.pVMCSPhys >> 32); /* Param 2: VMCS physical address - Hi. */
+ aParam[0] = (uint32_t)(HCPhysCpuPage); /* Param 1: VMXON physical address - Lo. */
+ aParam[1] = (uint32_t)(HCPhysCpuPage >> 32); /* Param 1: VMXON physical address - Hi. */
+ aParam[2] = (uint32_t)(pVCpu->hwaccm.s.vmx.HCPhysVMCS); /* Param 2: VMCS physical address - Lo. */
+ aParam[3] = (uint32_t)(pVCpu->hwaccm.s.vmx.HCPhysVMCS >> 32); /* Param 2: VMCS physical address - Hi. */
aParam[4] = VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hwaccm.s.vmx.VMCSCache);
aParam[5] = 0;
@@ -4649,9 +4657,9 @@ DECLASM(int) VMXR0SwitcherStartVM64(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE
#endif
#ifdef DEBUG
- AssertMsg(pCache->TestIn.pPageCpuPhys == pPageCpuPhys, ("%RHp vs %RHp\n", pCache->TestIn.pPageCpuPhys, pPageCpuPhys));
- AssertMsg(pCache->TestIn.pVMCSPhys == pVCpu->hwaccm.s.vmx.pVMCSPhys, ("%RHp vs %RHp\n", pCache->TestIn.pVMCSPhys, pVCpu->hwaccm.s.vmx.pVMCSPhys));
- AssertMsg(pCache->TestIn.pVMCSPhys == pCache->TestOut.pVMCSPhys, ("%RHp vs %RHp\n", pCache->TestIn.pVMCSPhys, pCache->TestOut.pVMCSPhys));
+ AssertMsg(pCache->TestIn.HCPhysCpuPage== HCPhysCpuPage, ("%RHp vs %RHp\n", pCache->TestIn.HCPhysCpuPage, HCPhysCpuPage));
+ AssertMsg(pCache->TestIn.HCPhysVMCS == pVCpu->hwaccm.s.vmx.HCPhysVMCS, ("%RHp vs %RHp\n", pCache->TestIn.HCPhysVMCS, pVCpu->hwaccm.s.vmx.HCPhysVMCS));
+ AssertMsg(pCache->TestIn.HCPhysVMCS == pCache->TestOut.HCPhysVMCS, ("%RHp vs %RHp\n", pCache->TestIn.HCPhysVMCS, pCache->TestOut.HCPhysVMCS));
AssertMsg(pCache->TestIn.pCache == pCache->TestOut.pCache, ("%RGv vs %RGv\n", pCache->TestIn.pCache, pCache->TestOut.pCache));
AssertMsg(pCache->TestIn.pCache == VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hwaccm.s.vmx.VMCSCache), ("%RGv vs %RGv\n", pCache->TestIn.pCache, VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hwaccm.s.vmx.VMCSCache)));
AssertMsg(pCache->TestIn.pCtx == pCache->TestOut.pCtx, ("%RGv vs %RGv\n", pCache->TestIn.pCtx, pCache->TestOut.pCtx));
@@ -4674,8 +4682,8 @@ DECLASM(int) VMXR0SwitcherStartVM64(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE
VMMR0DECL(int) VMXR0Execute64BitsHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTRCPTR pfnHandler, uint32_t cbParam, uint32_t *paParam)
{
int rc, rc2;
- PHWACCM_CPUINFO pCpu;
- RTHCPHYS pPageCpuPhys;
+ PHMGLOBLCPUINFO pCpu;
+ RTHCPHYS HCPhysCpuPage;
RTHCUINTREG uOldEFlags;
AssertReturn(pVM->hwaccm.s.pfnHost32ToGuest64R0, VERR_INTERNAL_ERROR);
@@ -4695,10 +4703,10 @@ VMMR0DECL(int) VMXR0Execute64BitsHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, R
uOldEFlags = ASMIntDisableFlags();
pCpu = HWACCMR0GetCurrentCpu();
- pPageCpuPhys = RTR0MemObjGetPagePhysAddr(pCpu->pMemObj, 0);
+ HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
/* Clear VM Control Structure. Marking it inactive, clearing implementation specific data and writing back VMCS data to memory. */
- VMXClearVMCS(pVCpu->hwaccm.s.vmx.pVMCSPhys);
+ VMXClearVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
/* Leave VMX Root Mode. */
VMXDisable();
@@ -4719,7 +4727,7 @@ VMMR0DECL(int) VMXR0Execute64BitsHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, R
ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE);
/* Enter VMX Root Mode */
- rc2 = VMXEnable(pPageCpuPhys);
+ rc2 = VMXEnable(HCPhysCpuPage);
if (RT_FAILURE(rc2))
{
ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
@@ -4727,7 +4735,7 @@ VMMR0DECL(int) VMXR0Execute64BitsHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, R
return VERR_VMX_VMXON_FAILED;
}
- rc2 = VMXActivateVMCS(pVCpu->hwaccm.s.vmx.pVMCSPhys);
+ rc2 = VMXActivateVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
AssertRC(rc2);
Assert(!(ASMGetFlags() & X86_EFL_IF));
ASMSetFlags(uOldEFlags);
diff --git a/src/VBox/VMM/VMMR0/HWVMXR0.h b/src/VBox/VMM/VMMR0/HWVMXR0.h
index 87f432de7..f37c4eaa9 100644
--- a/src/VBox/VMM/VMMR0/HWVMXR0.h
+++ b/src/VBox/VMM/VMMR0/HWVMXR0.h
@@ -1,4 +1,4 @@
-/* $Id: HWVMXR0.h $ */
+/* $Id: HWVMXR0.h 37320 2011-06-03 15:05:36Z vboxsync $ */
/** @file
* HWACCM VT-x - Internal header file.
*/
@@ -109,7 +109,7 @@ RT_C_DECLS_BEGIN
* @param pVCpu The VMCPU to operate on.
* @param pCpu CPU info struct
*/
-VMMR0DECL(int) VMXR0Enter(PVM pVM, PVMCPU pVCpu, PHWACCM_CPUINFO pCpu);
+VMMR0DECL(int) VMXR0Enter(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu);
/**
* Leaves the VT-x session
@@ -131,7 +131,7 @@ VMMR0DECL(int) VMXR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
* @param pvPageCpu Pointer to the global cpu page
* @param pPageCpuPhys Physical address of the global cpu page
*/
-VMMR0DECL(int) VMXR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
+VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
/**
* Deactivates VT-x on the current CPU
@@ -141,7 +141,7 @@ VMMR0DECL(int) VMXR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RT
* @param pvPageCpu Pointer to the global cpu page
* @param pPageCpuPhys Physical address of the global cpu page
*/
-VMMR0DECL(int) VMXR0DisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
+VMMR0DECL(int) VMXR0DisableCpu(PHMGLOBLCPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
/**
* Does Ring-0 per VM VT-x init.
diff --git a/src/VBox/VMM/VMMR0/PDMR0Device.cpp b/src/VBox/VMM/VMMR0/PDMR0Device.cpp
index 244754a8e..f81aed729 100644
--- a/src/VBox/VMM/VMMR0/PDMR0Device.cpp
+++ b/src/VBox/VMM/VMMR0/PDMR0Device.cpp
@@ -1,10 +1,10 @@
-/* $Id: PDMR0Device.cpp $ */
+/* $Id: PDMR0Device.cpp 37410 2011-06-10 15:11:40Z vboxsync $ */
/** @file
* PDM - Pluggable Device and Driver Manager, R0 Device parts.
*/
/*
- * 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;
@@ -47,6 +47,7 @@ extern DECLEXPORT(const PDMAPICHLPR0) g_pdmR0ApicHlp;
extern DECLEXPORT(const PDMIOAPICHLPR0) g_pdmR0IoApicHlp;
extern DECLEXPORT(const PDMPCIHLPR0) g_pdmR0PciHlp;
extern DECLEXPORT(const PDMHPETHLPR0) g_pdmR0HpetHlp;
+extern DECLEXPORT(const PDMPCIRAWHLPR0) g_pdmR0PciRawHlp;
extern DECLEXPORT(const PDMDRVHLPR0) g_pdmR0DrvHlp;
RT_C_DECLS_END
@@ -278,6 +279,16 @@ static DECLCALLBACK(uint64_t) pdmR0DevHlp_TMTimeVirtGetNano(PPDMDEVINS pDevIns)
}
+/** @interface_method_impl{PDMDEVHLPR0,pfnDBGFTraceBuf} */
+static DECLCALLBACK(RTTRACEBUF) pdmR0DevHlp_DBGFTraceBuf(PPDMDEVINS pDevIns)
+{
+ PDMDEV_ASSERT_DEVINS(pDevIns);
+ RTTRACEBUF hTraceBuf = pDevIns->Internal.s.pVMR0->hTraceBufR0;
+ LogFlow(("pdmR3DevHlp_DBGFTraceBuf: caller='%p'/%d: returns %p\n", pDevIns, pDevIns->iInstance, hTraceBuf));
+ return hTraceBuf;
+}
+
+
/**
* The Ring-0 Device Helper Callbacks.
*/
@@ -301,6 +312,7 @@ extern DECLEXPORT(const PDMDEVHLPR0) g_pdmR0DevHlp =
pdmR0DevHlp_TMTimeVirtGet,
pdmR0DevHlp_TMTimeVirtGetFreq,
pdmR0DevHlp_TMTimeVirtGetNano,
+ pdmR0DevHlp_DBGFTraceBuf,
PDM_DEVHLPR0_VERSION
};
@@ -667,6 +679,7 @@ extern DECLEXPORT(const PDMPCIHLPR0) g_pdmR0PciHlp =
/** @name HPET Ring-0 Helpers
* @{
*/
+/* none */
/**
* The Ring-0 HPET Helper Callbacks.
@@ -680,6 +693,21 @@ extern DECLEXPORT(const PDMHPETHLPR0) g_pdmR0HpetHlp =
/** @} */
+/** @name Raw PCI Ring-0 Helpers
+ * @{
+ */
+/* none */
+
+/**
+ * The Ring-0 PCI raw Helper Callbacks.
+ */
+extern DECLEXPORT(const PDMPCIRAWHLPR0) g_pdmR0PciRawHlp =
+{
+ PDM_PCIRAWHLPR0_VERSION,
+ PDM_PCIRAWHLPR0_VERSION, /* the end */
+};
+
+/** @} */
/** @name Ring-0 Context Driver Helpers
@@ -899,4 +927,3 @@ static void pdmR0IoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue)
pdmUnlock(pVM);
}
}
-
diff --git a/src/VBox/VMM/VMMR0/PDMR0Driver.cpp b/src/VBox/VMM/VMMR0/PDMR0Driver.cpp
index 728712c5d..8d0e704a7 100644
--- a/src/VBox/VMM/VMMR0/PDMR0Driver.cpp
+++ b/src/VBox/VMM/VMMR0/PDMR0Driver.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMR0Driver.cpp $ */
+/* $Id: PDMR0Driver.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* PDM - Pluggable Device and Driver Manager, R0 Driver parts.
*/
diff --git a/src/VBox/VMM/VMMR0/PGMR0.cpp b/src/VBox/VMM/VMMR0/PGMR0.cpp
index 80aa597e8..c2b2ced20 100644
--- a/src/VBox/VMM/VMMR0/PGMR0.cpp
+++ b/src/VBox/VMM/VMMR0/PGMR0.cpp
@@ -1,10 +1,10 @@
-/* $Id: PGMR0.cpp $ */
+/* $Id: PGMR0.cpp 37950 2011-07-14 10:13:39Z vboxsync $ */
/** @file
* PGM - Page Manager and Monitor, Ring-0.
*/
/*
- * Copyright (C) 2007-2010 Oracle Corporation
+ * Copyright (C) 2007-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;
@@ -19,8 +19,10 @@
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_PGM
+#include <VBox/rawpci.h>
#include <VBox/vmm/pgm.h>
#include <VBox/vmm/gmm.h>
+#include <VBox/vmm/gvm.h>
#include "PGMInternal.h"
#include <VBox/vmm/vm.h>
#include "PGMInline.h"
@@ -65,7 +67,7 @@
*/
VMMR0DECL(int) PGMR0PhysAllocateHandyPages(PVM pVM, PVMCPU pVCpu)
{
- Assert(PDMCritSectIsOwnerEx(&pVM->pgm.s.CritSect, pVCpu->idCpu));
+ Assert(PDMCritSectIsOwnerEx(&pVM->pgm.s.CritSect, pVCpu));
/*
* Check for error injection.
@@ -84,6 +86,7 @@ VMMR0DECL(int) PGMR0PhysAllocateHandyPages(PVM pVM, PVMCPU pVCpu)
int rc = GMMR0AllocateHandyPages(pVM, pVCpu->idCpu, cPages, cPages, &pVM->pgm.s.aHandyPages[iFirst]);
if (RT_SUCCESS(rc))
{
+#ifdef VBOX_STRICT
for (uint32_t i = 0; i < RT_ELEMENTS(pVM->pgm.s.aHandyPages); i++)
{
Assert(pVM->pgm.s.aHandyPages[i].idPage != NIL_GMM_PAGEID);
@@ -92,6 +95,7 @@ VMMR0DECL(int) PGMR0PhysAllocateHandyPages(PVM pVM, PVMCPU pVCpu)
Assert(pVM->pgm.s.aHandyPages[i].HCPhysGCPhys != NIL_RTHCPHYS);
Assert(!(pVM->pgm.s.aHandyPages[i].HCPhysGCPhys & ~X86_PTE_PAE_PG_MASK));
}
+#endif
pVM->pgm.s.cHandyPages = RT_ELEMENTS(pVM->pgm.s.aHandyPages);
}
@@ -118,10 +122,10 @@ VMMR0DECL(int) PGMR0PhysAllocateHandyPages(PVM pVM, PVMCPU pVCpu)
*/
do
{
- cPages >>= 2;
+ cPages >>= 1;
if (cPages + iFirst < PGM_HANDY_PAGES_MIN)
cPages = PGM_HANDY_PAGES_MIN - iFirst;
- rc = GMMR0AllocateHandyPages(pVM, pVCpu->idCpu, cPages, cPages, &pVM->pgm.s.aHandyPages[iFirst]);
+ rc = GMMR0AllocateHandyPages(pVM, pVCpu->idCpu, 0, cPages, &pVM->pgm.s.aHandyPages[iFirst]);
} while ( ( rc == VERR_GMM_HIT_GLOBAL_LIMIT
|| rc == VERR_GMM_HIT_VM_ACCOUNT_LIMIT)
&& cPages + iFirst > PGM_HANDY_PAGES_MIN);
@@ -178,7 +182,7 @@ VMMR0DECL(int) PGMR0PhysAllocateHandyPages(PVM pVM, PVMCPU pVCpu)
*/
VMMR0DECL(int) PGMR0PhysAllocateLargeHandyPage(PVM pVM, PVMCPU pVCpu)
{
- Assert(PDMCritSectIsOwnerEx(&pVM->pgm.s.CritSect, pVCpu->idCpu));
+ Assert(PDMCritSectIsOwnerEx(&pVM->pgm.s.CritSect, pVCpu));
Assert(!pVM->pgm.s.cLargeHandyPages);
int rc = GMMR0AllocateLargePage(pVM, pVCpu->idCpu, _2M, &pVM->pgm.s.aLargeHandyPage[0].idPage, &pVM->pgm.s.aLargeHandyPage[0].HCPhysGCPhys);
@@ -189,6 +193,182 @@ VMMR0DECL(int) PGMR0PhysAllocateLargeHandyPage(PVM pVM, PVMCPU pVCpu)
}
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+/* Interface sketch. The interface belongs to a global PCI pass-through
+ manager. It shall use the global VM handle, not the user VM handle to
+ store the per-VM info (domain) since that is all ring-0 stuff, thus
+ passing pGVM here. I've tentitively prefixed the functions 'GPciRawR0',
+ we can discuss the PciRaw code re-organtization when I'm back from
+ vacation.
+
+ I've implemented the initial IOMMU set up below. For things to work
+ reliably, we will probably need add a whole bunch of checks and
+ GPciRawR0GuestPageUpdate call to the PGM code. For the present,
+ assuming nested paging (enforced) and prealloc (enforced), no
+ ballooning (check missing), page sharing (check missing) or live
+ migration (check missing), it might work fine. At least if some
+ VM power-off hook is present and can tear down the IOMMU page tables. */
+
+/**
+ * Tells the global PCI pass-through manager that we are about to set up the
+ * guest page to host page mappings for the specfied VM.
+ *
+ * @returns VBox status code.
+ *
+ * @param pGVM The ring-0 VM structure.
+ */
+VMMR0_INT_DECL(int) GPciRawR0GuestPageBeginAssignments(PGVM pGVM)
+{
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Assigns a host page mapping for a guest page.
+ *
+ * This is only used when setting up the mappings, i.e. between
+ * GPciRawR0GuestPageBeginAssignments and GPciRawR0GuestPageEndAssignments.
+ *
+ * @returns VBox status code.
+ * @param pGVM The ring-0 VM structure.
+ * @param GCPhys The address of the guest page (page aligned).
+ * @param HCPhys The address of the host page (page aligned).
+ */
+VMMR0_INT_DECL(int) GPciRawR0GuestPageAssign(PGVM pGVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys)
+{
+ AssertReturn(!(GCPhys & PAGE_OFFSET_MASK), VERR_INTERNAL_ERROR_3);
+ AssertReturn(!(HCPhys & PAGE_OFFSET_MASK), VERR_INTERNAL_ERROR_3);
+
+ if (pGVM->rawpci.s.pfnContigMemInfo)
+ /** @todo: what do we do on failure? */
+ pGVM->rawpci.s.pfnContigMemInfo(&pGVM->rawpci.s, HCPhys, GCPhys, PAGE_SIZE, PCIRAW_MEMINFO_MAP);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Indicates that the specified guest page doesn't exists but doesn't have host
+ * page mapping we trust PCI pass-through with.
+ *
+ * This is only used when setting up the mappings, i.e. between
+ * GPciRawR0GuestPageBeginAssignments and GPciRawR0GuestPageEndAssignments.
+ *
+ * @returns VBox status code.
+ * @param pGVM The ring-0 VM structure.
+ * @param GCPhys The address of the guest page (page aligned).
+ * @param HCPhys The address of the host page (page aligned).
+ */
+VMMR0_INT_DECL(int) GPciRawR0GuestPageUnassign(PGVM pGVM, RTGCPHYS GCPhys)
+{
+ AssertReturn(!(GCPhys & PAGE_OFFSET_MASK), VERR_INTERNAL_ERROR_3);
+
+ if (pGVM->rawpci.s.pfnContigMemInfo)
+ /** @todo: what do we do on failure? */
+ pGVM->rawpci.s.pfnContigMemInfo(&pGVM->rawpci.s, 0, GCPhys, PAGE_SIZE, PCIRAW_MEMINFO_UNMAP);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Tells the global PCI pass-through manager that we have completed setting up
+ * the guest page to host page mappings for the specfied VM.
+ *
+ * This complements GPciRawR0GuestPageBeginAssignments and will be called even
+ * if some page assignment failed.
+ *
+ * @returns VBox status code.
+ *
+ * @param pGVM The ring-0 VM structure.
+ */
+VMMR0_INT_DECL(int) GPciRawR0GuestPageEndAssignments(PGVM pGVM)
+{
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Tells the global PCI pass-through manager that a guest page mapping has
+ * changed after the initial setup.
+ *
+ * @returns VBox status code.
+ * @param pGVM The ring-0 VM structure.
+ * @param GCPhys The address of the guest page (page aligned).
+ * @param HCPhys The new host page address or NIL_RTHCPHYS if
+ * now unassigned.
+ */
+VMMR0_INT_DECL(int) GPciRawR0GuestPageUpdate(PGVM pGVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys)
+{
+ AssertReturn(!(GCPhys & PAGE_OFFSET_MASK), VERR_INTERNAL_ERROR_4);
+ AssertReturn(!(HCPhys & PAGE_OFFSET_MASK) || HCPhys == NIL_RTHCPHYS, VERR_INTERNAL_ERROR_4);
+ return VINF_SUCCESS;
+}
+
+#endif /* VBOX_WITH_PCI_PASSTHROUGH */
+
+
+/**
+ * Sets up the IOMMU when raw PCI device is enabled.
+ *
+ * @note This is a hack that will probably be remodelled and refined later!
+ *
+ * @returns VBox status code.
+ *
+ * @param pVM The VM handle.
+ */
+VMMR0_INT_DECL(int) PGMR0PhysSetupIommu(PVM pVM)
+{
+ PGVM pGVM;
+ int rc = GVMMR0ByVM(pVM, &pGVM);
+ if (RT_FAILURE(rc))
+ return rc;
+
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ if (pVM->pgm.s.fPciPassthrough)
+ {
+ /*
+ * The Simplistic Approach - Enumerate all the pages and call tell the
+ * IOMMU about each of them.
+ */
+ pgmLock(pVM);
+ rc = GPciRawR0GuestPageBeginAssignments(pGVM);
+ if (RT_SUCCESS(rc))
+ {
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR0; RT_SUCCESS(rc) && pRam; pRam = pRam->pNextR0)
+ {
+ PPGMPAGE pPage = &pRam->aPages[0];
+ RTGCPHYS GCPhys = pRam->GCPhys;
+ uint32_t cLeft = pRam->cb >> PAGE_SHIFT;
+ while (cLeft-- > 0)
+ {
+ /* Only expose pages that are 100% safe for now. */
+ if ( PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_RAM
+ && PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED
+ && !PGM_PAGE_HAS_ANY_HANDLERS(pPage))
+ rc = GPciRawR0GuestPageAssign(pGVM, GCPhys, PGM_PAGE_GET_HCPHYS(pPage));
+ else
+ rc = GPciRawR0GuestPageUnassign(pGVM, GCPhys);
+
+ /* next */
+ pPage++;
+ GCPhys += PAGE_SIZE;
+ }
+ }
+
+ int rc2 = GPciRawR0GuestPageEndAssignments(pGVM);
+ if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
+ rc = rc2;
+ }
+ pgmUnlock(pVM);
+ }
+ else
+#endif
+ rc = VERR_NOT_SUPPORTED;
+ return rc;
+}
+
+
/**
* #PF Handler for nested paging.
*
@@ -287,7 +467,7 @@ VMMR0DECL(int) PGMR0Trap0eHandlerNestedPaging(PVM pVM, PVMCPU pVCpu, PGMMODE enm
}
if (fLockTaken)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
pgmUnlock(pVM);
}
@@ -347,7 +527,7 @@ VMMR0DECL(VBOXSTRICTRC) PGMR0Trap0eHandlerNPMisconfig(PVM pVM, PVMCPU pVCpu, PGM
PPGMPAGE pPage;
if ( ( pHandler->cAliasedPages
|| pHandler->cTmpOffPages)
- && ( (pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhysFault)) == NULL
+ && ( (pPage = pgmPhysGetPage(pVM, GCPhysFault)) == NULL
|| PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) == PGM_PAGE_HNDL_PHYS_STATE_DISABLED)
)
{
diff --git a/src/VBox/VMM/VMMR0/PGMR0Bth.h b/src/VBox/VMM/VMMR0/PGMR0Bth.h
index 6c0bb8de3..6ec721147 100644
--- a/src/VBox/VMM/VMMR0/PGMR0Bth.h
+++ b/src/VBox/VMM/VMMR0/PGMR0Bth.h
@@ -1,4 +1,4 @@
-/* $Id: PGMR0Bth.h $ */
+/* $Id: PGMR0Bth.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBox - Page Manager / Monitor, Shadow+Guest Paging Template.
*/
diff --git a/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp b/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp
index 32a549184..2156e2242 100644
--- a/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp
+++ b/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMR0SharedPage.cpp $ */
+/* $Id: PGMR0SharedPage.cpp 37354 2011-06-07 15:05:32Z vboxsync $ */
/** @file
* PGM - Page Manager and Monitor, Page Sharing, Ring-0.
*/
@@ -52,7 +52,7 @@ VMMR0DECL(int) PGMR0SharedModuleCheck(PVM pVM, PGVM pGVM, VMCPUID idCpu, PGMMSHA
Log(("PGMR0SharedModuleCheck: check %s %s base=%RGv size=%x\n", pModule->szName, pModule->szVersion, pModule->Core.Key, pModule->cbModule));
- Assert(PGMIsLockOwner(pVM)); /* This cannot fail as we grab the lock in pgmR3SharedModuleRegRendezvous before calling into ring-0. */
+ 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++)
@@ -60,9 +60,9 @@ VMMR0DECL(int) PGMR0SharedModuleCheck(PVM pVM, PGVM pGVM, VMCPUID idCpu, PGMMSHA
Assert((pRegions[idxRegion].cbRegion & 0xfff) == 0);
Assert((pRegions[idxRegion].GCRegionAddr & 0xfff) == 0);
- RTGCPTR GCRegion = pRegions[idxRegion].GCRegionAddr;
+ RTGCPTR GCRegion = pRegions[idxRegion].GCRegionAddr;
unsigned cbRegion = pRegions[idxRegion].cbRegion & ~0xfff;
- unsigned idxPage = 0;
+ unsigned idxPage = 0;
while (cbRegion)
{
@@ -74,7 +74,7 @@ VMMR0DECL(int) PGMR0SharedModuleCheck(PVM pVM, PGVM pGVM, VMCPUID idCpu, PGMMSHA
if ( rc == VINF_SUCCESS
&& !(fFlags & X86_PTE_RW)) /* important as we make assumptions about this below! */
{
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
Assert(!pPage || !PGM_PAGE_IS_BALLOONED(pPage));
if ( pPage
&& PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED)
@@ -103,18 +103,18 @@ VMMR0DECL(int) PGMR0SharedModuleCheck(PVM pVM, PGVM pGVM, VMCPUID idCpu, PGMMSHA
fFlushTLBs |= fFlush;
/* Update the physical address and page id now. */
- PGM_PAGE_SET_HCPHYS(pPage, PageDesc.HCPhys);
- PGM_PAGE_SET_PAGEID(pPage, PageDesc.uHCPhysPageId);
+ 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);
+ 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(pPage, PGM_PAGE_STATE_SHARED);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_SHARED);
}
}
else
@@ -142,5 +142,5 @@ VMMR0DECL(int) PGMR0SharedModuleCheck(PVM pVM, PGVM pGVM, VMCPUID idCpu, PGMMSHA
return rc;
}
-#endif
+#endif /* VBOX_WITH_PAGE_SHARING */
diff --git a/src/VBox/VMM/VMMR0/TRPMR0.cpp b/src/VBox/VMM/VMMR0/TRPMR0.cpp
index 9255772ed..c3b5e7a74 100644
--- a/src/VBox/VMM/VMMR0/TRPMR0.cpp
+++ b/src/VBox/VMM/VMMR0/TRPMR0.cpp
@@ -1,4 +1,4 @@
-/* $Id: TRPMR0.cpp $ */
+/* $Id: TRPMR0.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* TRPM - The Trap Monitor - HC Ring 0
*/
diff --git a/src/VBox/VMM/VMMR0/TRPMR0A.asm b/src/VBox/VMM/VMMR0/TRPMR0A.asm
index a19de3a5e..fe321b272 100644
--- a/src/VBox/VMM/VMMR0/TRPMR0A.asm
+++ b/src/VBox/VMM/VMMR0/TRPMR0A.asm
@@ -1,4 +1,4 @@
-; $Id: TRPMR0A.asm $
+; $Id: TRPMR0A.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; TRPM - Host Context Ring-0
;
@@ -19,7 +19,7 @@
;* Header Files *
;*******************************************************************************
%include "VBox/asmdefs.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
BEGINCODE
diff --git a/src/VBox/VMM/VMMR0/VMMR0.cpp b/src/VBox/VMM/VMMR0/VMMR0.cpp
index e2a48d784..321558a59 100644
--- a/src/VBox/VMM/VMMR0/VMMR0.cpp
+++ b/src/VBox/VMM/VMMR0/VMMR0.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMMR0.cpp $ */
+/* $Id: VMMR0.cpp 37584 2011-06-22 09:54:26Z vboxsync $ */
/** @file
* VMM - Host Context Ring 0.
*/
@@ -29,6 +29,9 @@
#include <VBox/vmm/tm.h>
#include "VMMInternal.h"
#include <VBox/vmm/vm.h>
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+# include <VBox/vmm/pdmpci.h>
+#endif
#include <VBox/vmm/gvmm.h>
#include <VBox/vmm/gmm.h>
@@ -84,6 +87,12 @@ PFNRT g_VMMGCDeps[] =
NULL
};
+#ifdef RT_OS_SOLARIS
+/* Dependency information for the native solaris loader. */
+extern "C" { char _depends_on[] = "vboxdrv"; }
+#endif
+
+
#if defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)
/* Increase the size of the image to work around the refusal of Win64 to
@@ -126,16 +135,25 @@ VMMR0DECL(int) ModuleInit(void)
rc = IntNetR0Init();
if (RT_SUCCESS(rc))
{
- rc = CPUMR0ModuleInit();
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ rc = PciRawR0Init();
+#endif
if (RT_SUCCESS(rc))
{
- LogFlow(("ModuleInit: returns success.\n"));
- return VINF_SUCCESS;
+ rc = CPUMR0ModuleInit();
+ if (RT_SUCCESS(rc))
+ {
+ LogFlow(("ModuleInit: returns success.\n"));
+ return VINF_SUCCESS;
+ }
+
+ /*
+ * Bail out.
+ */
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ PciRawR0Term();
+#endif
}
-
- /*
- * Bail out.
- */
IntNetR0Term();
}
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
@@ -175,11 +193,14 @@ VMMR0DECL(void) ModuleTerm(void)
IntNetR0Term();
/*
- * PGM (Darwin) and HWACCM global cleanup.
+ * PGM (Darwin), HWACCM and PciRaw global cleanup.
*/
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
PGMR0DynMapTerm();
#endif
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ PciRawR0Term();
+#endif
PGMDeregisterStringFormatTypes();
HWACCMR0Term();
@@ -211,7 +232,7 @@ static int vmmR0InitVM(PVM pVM, uint32_t uSvnRev)
{
LogRel(("VMMR0InitVM: Revision mismatch, r3=%d r0=%d\n", uSvnRev, VMMGetSvnRev()));
SUPR0Printf("VMMR0InitVM: Revision mismatch, r3=%d r0=%d\n", uSvnRev, VMMGetSvnRev());
- return VERR_VERSION_MISMATCH;
+ return VERR_VMM_R0_VERSION_MISMATCH;
}
if ( !VALID_PTR(pVM)
|| pVM->pVMR0 != pVM)
@@ -291,15 +312,26 @@ static int vmmR0InitVM(PVM pVM, uint32_t uSvnRev)
#endif
if (RT_SUCCESS(rc))
{
- GVMMR0DoneInitVM(pVM);
- return rc;
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ rc = PciRawR0InitVM(pVM);
+#endif
+ if (RT_SUCCESS(rc))
+ {
+ GVMMR0DoneInitVM(pVM);
+ return rc;
+ }
}
/* bail out */
}
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ PciRawR0TermVM(pVM);
+#endif
HWACCMR0TermVM(pVM);
}
}
+
+
RTLogSetDefaultInstanceThread(NULL, (uintptr_t)pVM->pSession);
return rc;
}
@@ -320,6 +352,10 @@ static int vmmR0InitVM(PVM pVM, uint32_t uSvnRev)
*/
VMMR0DECL(int) VMMR0TermVM(PVM pVM, PGVM pGVM)
{
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ PciRawR0TermVM(pVM);
+#endif
+
/*
* Tell GVMM what we're up to and check that we only do this once.
*/
@@ -446,26 +482,19 @@ static void vmmR0RecordRC(PVM pVM, PVMCPU pVCpu, int rc)
case VINF_EM_RAW_TO_R3:
if (VM_FF_ISPENDING(pVM, VM_FF_TM_VIRTUAL_SYNC))
STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3TMVirt);
- else
- if (VM_FF_ISPENDING(pVM, VM_FF_PGM_NEED_HANDY_PAGES))
+ else if (VM_FF_ISPENDING(pVM, VM_FF_PGM_NEED_HANDY_PAGES))
STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3HandyPages);
- else
- if (VM_FF_ISPENDING(pVM, VM_FF_PDM_QUEUES))
+ else if (VM_FF_ISPENDING(pVM, VM_FF_PDM_QUEUES))
STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3PDMQueues);
- else
- if (VM_FF_ISPENDING(pVM, VM_FF_EMT_RENDEZVOUS))
+ else if (VM_FF_ISPENDING(pVM, VM_FF_EMT_RENDEZVOUS))
STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3Rendezvous);
- else
- if (VM_FF_ISPENDING(pVM, VM_FF_PDM_DMA))
+ else if (VM_FF_ISPENDING(pVM, VM_FF_PDM_DMA))
STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3DMA);
- else
- if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TIMER))
+ else if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TIMER))
STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3Timer);
- else
- if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PDM_CRITSECT))
+ else if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PDM_CRITSECT))
STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3CritSect);
- else
- if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TO_R3))
+ else if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TO_R3))
STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3);
else
STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3Unknown);
@@ -480,6 +509,9 @@ static void vmmR0RecordRC(PVM pVM, PVMCPU pVCpu, int rc)
case VINF_VMM_CALL_HOST:
switch (pVCpu->vmm.s.enmCallRing3Operation)
{
+ case VMMCALLRING3_PDM_CRIT_SECT_ENTER:
+ STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallPDMCritSectEnter);
+ break;
case VMMCALLRING3_PDM_LOCK:
STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallPDMLock);
break;
@@ -884,12 +916,7 @@ static int vmmR0EntryExWorker(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperatio
* Setup the hardware accelerated session.
*/
case VMMR0_DO_HWACC_SETUP_VM:
- {
- RTCCUINTREG fFlags = ASMIntDisableFlags();
- int rc = HWACCMR0SetupVM(pVM);
- ASMSetFlags(fFlags);
- return rc;
- }
+ return HWACCMR0SetupVM(pVM);
/*
* Switch to RC to execute Hypervisor function.
@@ -944,6 +971,11 @@ static int vmmR0EntryExWorker(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperatio
return VERR_INVALID_CPU_ID;
return PGMR0PhysAllocateLargeHandyPage(pVM, &pVM->aCpus[idCpu]);
+ case VMMR0_DO_PGM_PHYS_SETUP_IOMMU:
+ if (idCpu != 0)
+ return VERR_INVALID_CPU_ID;
+ return PGMR0PhysSetupIommu(pVM);
+
/*
* GMM wrappers.
*/
@@ -1156,6 +1188,15 @@ static int vmmR0EntryExWorker(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperatio
return VERR_INVALID_PARAMETER;
return IntNetR0IfAbortWaitReq(pSession, (PINTNETIFABORTWAITREQ)pReqHdr);
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ /*
+ * Requests to host PCI driver service.
+ */
+ case VMMR0_DO_PCIRAW_REQ:
+ if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PPCIRAWSENDREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
+ return VERR_INVALID_PARAMETER;
+ return PciRawR0ProcessReq(pSession, pVM, (PPCIRAWSENDREQ)pReqHdr);
+#endif
/*
* For profiling.
*/
diff --git a/src/VBox/VMM/VMMR0/VMMR0.def b/src/VBox/VMM/VMMR0/VMMR0.def
index 909110f9f..16a57ab84 100644
--- a/src/VBox/VMM/VMMR0/VMMR0.def
+++ b/src/VBox/VMM/VMMR0/VMMR0.def
@@ -1,4 +1,4 @@
-; $Id: VMMR0.def $
+; $Id: VMMR0.def 37454 2011-06-14 19:18:56Z vboxsync $
;; @file
; VMM Ring 0 DLL - Definition file.
@@ -43,12 +43,17 @@ EXPORTS
RTLogLoggerEx
RTLogLoggerExV
RTTimeMilliTS
+ RTTraceBufAddMsgF
+ RTTraceBufAddPos
+ RTTraceBufAddPosMsgF
TMTimerFromMilli
TMTimerFromMicro
TMTimerFromNano
TMTimerGet
TMTimerGetFreq
TMTimerIsActive
+ TMTimerIsLockOwner
+ TMTimerLock
TMTimerSet
TMTimerSetRelative
TMTimerSetMillies
@@ -56,6 +61,7 @@ EXPORTS
TMTimerSetNano
TMTimerSetFrequencyHint
TMTimerStop
+ TMTimerUnlock
VMMGetSvnRev
vmmR0LoggerFlush
vmmR0LoggerWrapper
@@ -77,7 +83,7 @@ EXPORTS
RTAssertMsg2Weak
RTAssertShouldPanic
RTCrc32
- RTOnce
+ RTOnceSlow
RTTimeNanoTSLegacySync
RTTimeNanoTSLegacyAsync
RTTimeNanoTSLFenceSync
diff --git a/src/VBox/VMM/VMMR0/VMMR0JmpA-amd64.asm b/src/VBox/VMM/VMMR0/VMMR0JmpA-amd64.asm
index f6c0d27f2..31ef955ef 100644
--- a/src/VBox/VMM/VMMR0/VMMR0JmpA-amd64.asm
+++ b/src/VBox/VMM/VMMR0/VMMR0JmpA-amd64.asm
@@ -1,4 +1,4 @@
-; $Id: VMMR0JmpA-amd64.asm $
+; $Id: VMMR0JmpA-amd64.asm 37227 2011-05-26 18:35:59Z vboxsync $
;; @file
; VMM - R0 SetJmp / LongJmp routines for AMD64.
;
@@ -31,9 +31,6 @@
%define STACK_PADDING 0eeeeeeeeeeeeeeeeh
-; For vmmR0LoggerWrapper. (The other architecture(s) use(s) C99 variadic macros.)
-extern NAME(RTLogLogger)
-
BEGINCODE
diff --git a/src/VBox/VMM/VMMR0/VMMR0JmpA-x86.asm b/src/VBox/VMM/VMMR0/VMMR0JmpA-x86.asm
index 76a0cb9ea..1e263d8ba 100644
--- a/src/VBox/VMM/VMMR0/VMMR0JmpA-x86.asm
+++ b/src/VBox/VMM/VMMR0/VMMR0JmpA-x86.asm
@@ -1,4 +1,4 @@
-; $Id: VMMR0JmpA-x86.asm $
+; $Id: VMMR0JmpA-x86.asm 35334 2010-12-27 12:27:46Z vboxsync $
;; @file
; VMM - R0 SetJmp / LongJmp routines for X86.
;
diff --git a/src/VBox/VMM/VMMR3/CFGM.cpp b/src/VBox/VMM/VMMR3/CFGM.cpp
index abdb14194..5a744d16d 100644
--- a/src/VBox/VMM/VMMR3/CFGM.cpp
+++ b/src/VBox/VMM/VMMR3/CFGM.cpp
@@ -1,4 +1,4 @@
-/* $Id: CFGM.cpp $ */
+/* $Id: CFGM.cpp 36819 2011-04-22 19:40:04Z vboxsync $ */
/** @file
* CFGM - Configuration Manager.
*/
@@ -1084,6 +1084,7 @@ VMMR3DECL(int) CFGMR3ConstructDefaultTree(PVM pVM)
*/
static int cfgmR3ResolveNode(PCFGMNODE pNode, const char *pszPath, PCFGMNODE *ppChild)
{
+ *ppChild = NULL;
if (!pNode)
return VERR_CFGM_NO_PARENT;
PCFGMNODE pChild = NULL;
@@ -1143,6 +1144,7 @@ static int cfgmR3ResolveNode(PCFGMNODE pNode, const char *pszPath, PCFGMNODE *pp
*/
static int cfgmR3ResolveLeaf(PCFGMNODE pNode, const char *pszName, PCFGMLEAF *ppLeaf)
{
+ *ppLeaf = NULL;
if (!pNode)
return VERR_CFGM_NO_PARENT;
diff --git a/src/VBox/VMM/VMMR3/CPUM.cpp b/src/VBox/VMM/VMMR3/CPUM.cpp
index 22ca3c3c3..af2df7d86 100644
--- a/src/VBox/VMM/VMMR3/CPUM.cpp
+++ b/src/VBox/VMM/VMMR3/CPUM.cpp
@@ -1,4 +1,4 @@
-/* $Id: CPUM.cpp $ */
+/* $Id: CPUM.cpp 37136 2011-05-18 14:45:47Z vboxsync $ */
/** @file
* CPUM - CPU Monitor / Manager.
*/
@@ -935,6 +935,13 @@ static int cpumR3CpuIdInit(PVM pVM)
CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NXE);
/*
+ * We don't enable the Hypervisor Present bit by default, but it may
+ * be needed by some guests.
+ */
+ rc = CFGMR3QueryBoolDef(pCpumCfg, "EnableHVP", &fEnable, false); AssertRCReturn(rc, rc);
+ if (fEnable)
+ CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_HVP);
+ /*
* Log the cpuid and we're good.
*/
bool fOldBuffered = RTLogRelSetBuffering(true /*fBuffered*/);
@@ -999,7 +1006,8 @@ VMMR3DECL(void) CPUMR3SetHWVirtEx(PVM pVM, bool fHWVirtExEnabled)
*/
if (!fHWVirtExEnabled)
{
- Assert(pVM->cpum.s.aGuestCpuIdStd[4].eax == 0);
+ Assert( pVM->cpum.s.aGuestCpuIdStd[4].eax == 0
+ || pVM->cpum.s.aGuestCpuIdStd[0].eax < 0x4);
pVM->cpum.s.aGuestCpuIdStd[4].eax = 0;
}
}
@@ -1100,7 +1108,7 @@ VMMR3DECL(void) CPUMR3ResetCpu(PVMCPU pVCpu)
pCtx->dr[6] = X86_DR6_INIT_VAL;
pCtx->dr[7] = X86_DR7_INIT_VAL;
- pCtx->fpu.FTW = 0xff; /* All tags are set, i.e. the regs are empty. */
+ pCtx->fpu.FTW = 0x00; /* All empty (abbridged tag reg edition). */
pCtx->fpu.FCW = 0x37f;
/* Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3A, Table 8-1. IA-32 Processor States Following Power-up, Reset, or INIT */
@@ -2488,11 +2496,11 @@ static void cpumR3InfoOne(PVM pVM, PCPUMCTX pCtx, PCCPUMCTXCORE pCtxCore, PCDBGF
pHlp->pfnPrintf(pHlp,
"%sFCW=%04x %sFSW=%04x %sFTW=%04x %sFOP=%04x %sMXCSR=%08x %sMXCSR_MASK=%08x\n"
- "%sFPUIP=%08x %sCS=%04x %sRsvrd1=%04x %sFPUDP=%08x %sDS=%04x %sRsvrd2=%04x\n"
+ "%sFPUIP=%08x %sCS=%04x %sRsrvd1=%04x %sFPUDP=%08x %sDS=%04x %sRsvrd2=%04x\n"
,
pszPrefix, pCtx->fpu.FCW, pszPrefix, pCtx->fpu.FSW, pszPrefix, pCtx->fpu.FTW, pszPrefix, pCtx->fpu.FOP,
pszPrefix, pCtx->fpu.MXCSR, pszPrefix, pCtx->fpu.MXCSR_MASK,
- pszPrefix, pCtx->fpu.FPUIP, pszPrefix, pCtx->fpu.CS, pszPrefix, pCtx->fpu.Rsvrd1,
+ pszPrefix, pCtx->fpu.FPUIP, pszPrefix, pCtx->fpu.CS, pszPrefix, pCtx->fpu.Rsrvd1,
pszPrefix, pCtx->fpu.FPUDP, pszPrefix, pCtx->fpu.DS, pszPrefix, pCtx->fpu.Rsrvd2
);
unsigned iShift = (pCtx->fpu.FSW >> 11) & 7;
@@ -3050,7 +3058,7 @@ static DECLCALLBACK(void) cpumR3CpuIdInfo(PVM pVM, PCDBGFINFOHLP pHlp, const cha
pHlp->pfnPrintf(pHlp, "Supports OSXSAVE = %d (%d)\n", EcxGuest.u1OSXSAVE, EcxHost.u1OSXSAVE);
pHlp->pfnPrintf(pHlp, "AVX instruction extensions = %d (%d)\n", EcxGuest.u1AVX, EcxHost.u1AVX);
pHlp->pfnPrintf(pHlp, "29/30 - Reserved = %#x (%#x)\n",EcxGuest.u2Reserved3, EcxHost.u2Reserved3);
- pHlp->pfnPrintf(pHlp, "31 - Reserved (always 0) = %d (%d)\n", EcxGuest.u1Reserved4, EcxHost.u1Reserved4);
+ pHlp->pfnPrintf(pHlp, "Hypervisor Present (we're a guest) = %d (%d)\n", EcxGuest.u1HVP, EcxHost.u1HVP);
}
}
if (cStdMax >= 2 && iVerbosity)
diff --git a/src/VBox/VMM/VMMR3/CPUMDbg.cpp b/src/VBox/VMM/VMMR3/CPUMDbg.cpp
index 2d43ba114..c2d8dc9f3 100644
--- a/src/VBox/VMM/VMMR3/CPUMDbg.cpp
+++ b/src/VBox/VMM/VMMR3/CPUMDbg.cpp
@@ -1,4 +1,4 @@
-/* $Id: CPUMDbg.cpp $ */
+/* $Id: CPUMDbg.cpp 35625 2011-01-19 11:17:34Z vboxsync $ */
/** @file
* CPUM - CPU Monitor / Manager, Debugger & Debugging APIs.
*/
@@ -1104,22 +1104,22 @@ static DBGFREGDESC const g_aCpumRegGstDescs[] =
CPU_REG_XMM(14),
CPU_REG_XMM(15),
CPU_REG_RW_AS("gdtr_base", GDTR_BASE, U64, gdtr.pGdt, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL ),
- CPU_REG_RW_AS("gdtr_limit", GDTR_LIMIT, U16, gdtr.cbGdt, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL ),
+ CPU_REG_RW_AS("gdtr_lim", GDTR_LIMIT, U16, gdtr.cbGdt, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL ),
CPU_REG_RW_AS("idtr_base", IDTR_BASE, U64, idtr.pIdt, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL ),
- CPU_REG_RW_AS("idtr_limit", IDTR_LIMIT, U16, idtr.cbIdt, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL ),
+ CPU_REG_RW_AS("idtr_lim", IDTR_LIMIT, U16, idtr.cbIdt, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL ),
CPU_REG_SEG(LDTR, ldtr),
CPU_REG_SEG(TR, tr),
- CPU_REG_EX_AS("cr0", CR0, U32, 0, cpumR3RegGstGet_crX, cpumR3RegGstSet_crX, g_aCpumRegAliases_cr0, g_aCpumRegFields_cr0 ),
- CPU_REG_EX_AS("cr2", CR2, U64, 2, cpumR3RegGstGet_crX, cpumR3RegGstSet_crX, NULL, NULL ),
- CPU_REG_EX_AS("cr3", CR3, U64, 3, cpumR3RegGstGet_crX, cpumR3RegGstSet_crX, NULL, g_aCpumRegFields_cr3 ),
- CPU_REG_EX_AS("cr4", CR4, U32, 4, cpumR3RegGstGet_crX, cpumR3RegGstSet_crX, NULL, g_aCpumRegFields_cr4 ),
- CPU_REG_EX_AS("cr8", CR8, U32, 8, cpumR3RegGstGet_crX, cpumR3RegGstSet_crX, NULL, NULL ),
- CPU_REG_EX_AS("dr0", DR0, U64, 0, cpumR3RegGstGet_drX, cpumR3RegGstSet_drX, NULL, NULL ),
- CPU_REG_EX_AS("dr1", DR1, U64, 1, cpumR3RegGstGet_drX, cpumR3RegGstSet_drX, NULL, NULL ),
- CPU_REG_EX_AS("dr2", DR2, U64, 2, cpumR3RegGstGet_drX, cpumR3RegGstSet_drX, NULL, NULL ),
- CPU_REG_EX_AS("dr3", DR3, U64, 3, cpumR3RegGstGet_drX, cpumR3RegGstSet_drX, NULL, NULL ),
- CPU_REG_EX_AS("dr6", DR6, U32, 6, cpumR3RegGstGet_drX, cpumR3RegGstSet_drX, NULL, g_aCpumRegFields_dr6 ),
- CPU_REG_EX_AS("dr7", DR7, U32, 7, cpumR3RegGstGet_drX, cpumR3RegGstSet_drX, NULL, g_aCpumRegFields_dr7 ),
+ CPU_REG_EX_AS("cr0", CR0, U32, 0, cpumR3RegGstGet_crX, cpumR3RegGstSet_crX, g_aCpumRegAliases_cr0, g_aCpumRegFields_cr0 ),
+ CPU_REG_EX_AS("cr2", CR2, U64, 2, cpumR3RegGstGet_crX, cpumR3RegGstSet_crX, NULL, NULL ),
+ CPU_REG_EX_AS("cr3", CR3, U64, 3, cpumR3RegGstGet_crX, cpumR3RegGstSet_crX, NULL, g_aCpumRegFields_cr3 ),
+ CPU_REG_EX_AS("cr4", CR4, U32, 4, cpumR3RegGstGet_crX, cpumR3RegGstSet_crX, NULL, g_aCpumRegFields_cr4 ),
+ CPU_REG_EX_AS("cr8", CR8, U32, 8, cpumR3RegGstGet_crX, cpumR3RegGstSet_crX, NULL, NULL ),
+ CPU_REG_EX_AS("dr0", DR0, U64, 0, cpumR3RegGstGet_drX, cpumR3RegGstSet_drX, NULL, NULL ),
+ CPU_REG_EX_AS("dr1", DR1, U64, 1, cpumR3RegGstGet_drX, cpumR3RegGstSet_drX, NULL, NULL ),
+ CPU_REG_EX_AS("dr2", DR2, U64, 2, cpumR3RegGstGet_drX, cpumR3RegGstSet_drX, NULL, NULL ),
+ CPU_REG_EX_AS("dr3", DR3, U64, 3, cpumR3RegGstGet_drX, cpumR3RegGstSet_drX, NULL, NULL ),
+ CPU_REG_EX_AS("dr6", DR6, U32, 6, cpumR3RegGstGet_drX, cpumR3RegGstSet_drX, NULL, g_aCpumRegFields_dr6 ),
+ CPU_REG_EX_AS("dr7", DR7, U32, 7, cpumR3RegGstGet_drX, cpumR3RegGstSet_drX, NULL, g_aCpumRegFields_dr7 ),
CPU_REG_MSR("apic_base", IA32_APICBASE, U32, g_aCpumRegFields_apic_base ),
CPU_REG_MSR("pat", IA32_CR_PAT, U64, g_aCpumRegFields_cr_pat ),
CPU_REG_MSR("perf_status", IA32_PERF_STATUS, U64, g_aCpumRegFields_perf_status),
@@ -1232,9 +1232,9 @@ static DBGFREGDESC const g_aCpumRegHyperDescs[] =
CPU_REG_XMM(14),
CPU_REG_XMM(15),
CPU_REG_RW_AS("gdtr_base", GDTR_BASE, U64, gdtr.pGdt, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL ),
- CPU_REG_RW_AS("gdtr_limit", GDTR_LIMIT, U16, gdtr.cbGdt, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL ),
+ CPU_REG_RW_AS("gdtr_lim", GDTR_LIMIT, U16, gdtr.cbGdt, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL ),
CPU_REG_RW_AS("idtr_base", IDTR_BASE, U64, idtr.pIdt, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL ),
- CPU_REG_RW_AS("idtr_limit", IDTR_LIMIT, U16, idtr.cbIdt, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL ),
+ CPU_REG_RW_AS("idtr_lim", IDTR_LIMIT, U16, idtr.cbIdt, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL ),
CPU_REG_SEG(LDTR, ldtr),
CPU_REG_SEG(TR, tr),
CPU_REG_EX_AS("cr0", CR0, U32, 0, cpumR3RegHyperGet_crX, cpumR3RegHyperSet_crX, g_aCpumRegAliases_cr0, g_aCpumRegFields_cr0 ),
diff --git a/src/VBox/VMM/VMMR3/CSAM.cpp b/src/VBox/VMM/VMMR3/CSAM.cpp
index c265ce737..9ff6885d4 100644
--- a/src/VBox/VMM/VMMR3/CSAM.cpp
+++ b/src/VBox/VMM/VMMR3/CSAM.cpp
@@ -1,4 +1,4 @@
-/* $Id: CSAM.cpp $ */
+/* $Id: CSAM.cpp 36969 2011-05-05 08:59:43Z vboxsync $ */
/** @file
* CSAM - Guest OS Code Scanning and Analysis Manager
*/
@@ -84,15 +84,15 @@ static bool fInCSAMCodePageInvalidate = false;
* Global Variables *
*******************************************************************************/
#ifdef VBOX_WITH_DEBUGGER
-static DECLCALLBACK(int) csamr3CmdOn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) csamr3CmdOff(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
+static DECLCALLBACK(int) csamr3CmdOn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) csamr3CmdOff(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
/** Command descriptors. */
static const DBGCCMD g_aCmds[] =
{
- /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, pResultDesc, fFlags, pfnHandler pszSyntax, ....pszDescription */
- { "csamon", 0, 0, NULL, 0, NULL, 0, csamr3CmdOn, "", "Enable CSAM code scanning." },
- { "csamoff", 0, 0, NULL, 0, NULL, 0, csamr3CmdOff, "", "Disable CSAM code scanning." },
+ /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, fFlags, pfnHandler pszSyntax, ....pszDescription */
+ { "csamon", 0, 0, NULL, 0, 0, csamr3CmdOn, "", "Enable CSAM code scanning." },
+ { "csamoff", 0, 0, NULL, 0, 0, csamr3CmdOff, "", "Disable CSAM code scanning." },
};
#endif
@@ -2662,6 +2662,7 @@ VMMR3DECL(int) CSAMR3IsEnabled(PVM pVM)
}
#ifdef VBOX_WITH_DEBUGGER
+
/**
* The '.csamoff' command.
*
@@ -2672,16 +2673,14 @@ VMMR3DECL(int) CSAMR3IsEnabled(PVM pVM)
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) csamr3CmdOff(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) csamr3CmdOff(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
- /*
- * Validate input.
- */
- if (!pVM)
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: The command requires VM to be selected.\n");
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
- CSAMDisableScanning(pVM);
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "CSAM Scanning disabled\n");
+ int rc = CSAMDisableScanning(pVM);
+ if (RT_FAILURE(rc))
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "CSAMDisableScanning");
+ return DBGCCmdHlpPrintf(pCmdHlp, "CSAM Scanning disabled\n");
}
/**
@@ -2694,15 +2693,14 @@ static DECLCALLBACK(int) csamr3CmdOff(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM p
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) csamr3CmdOn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) csamr3CmdOn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
- /*
- * Validate input.
- */
- if (!pVM)
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: The command requires VM to be selected.\n");
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
- CSAMEnableScanning(pVM);
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "CSAM Scanning enabled\n");
+ int rc = CSAMEnableScanning(pVM);
+ if (RT_FAILURE(rc))
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "CSAMEnableScanning");
+ return DBGCCmdHlpPrintf(pCmdHlp, "CSAM Scanning enabled\n");
}
-#endif
+
+#endif /* VBOX_WITH_DEBUGGER */
diff --git a/src/VBox/VMM/VMMR3/DBGF.cpp b/src/VBox/VMM/VMMR3/DBGF.cpp
index acc3ae52d..4902a5987 100644
--- a/src/VBox/VMM/VMMR3/DBGF.cpp
+++ b/src/VBox/VMM/VMMR3/DBGF.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGF.cpp $ */
+/* $Id: DBGF.cpp 37410 2011-06-10 15:11:40Z vboxsync $ */
/** @file
* DBGF - Debugger Facility.
*/
@@ -135,6 +135,8 @@ VMMR3DECL(int) DBGFR3Init(PVM pVM)
{
int rc = dbgfR3InfoInit(pVM);
if (RT_SUCCESS(rc))
+ rc = dbgfR3TraceInit(pVM);
+ if (RT_SUCCESS(rc))
rc = dbgfR3RegInit(pVM);
if (RT_SUCCESS(rc))
rc = dbgfR3AsInit(pVM);
@@ -210,6 +212,7 @@ VMMR3DECL(int) DBGFR3Term(PVM pVM)
dbgfR3OSTerm(pVM);
dbgfR3AsTerm(pVM);
dbgfR3RegTerm(pVM);
+ dbgfR3TraceTerm(pVM);
dbgfR3InfoTerm(pVM);
return VINF_SUCCESS;
}
@@ -225,6 +228,7 @@ VMMR3DECL(int) DBGFR3Term(PVM pVM)
*/
VMMR3DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta)
{
+ dbgfR3TraceRelocate(pVM);
dbgfR3AsRelocate(pVM, offDelta);
}
@@ -243,7 +247,7 @@ bool dbgfR3WaitForAttach(PVM pVM, DBGFEVENTTYPE enmEvent)
*/
#ifndef RT_OS_L4
-# if !defined(DEBUG) || defined(DEBUG_sandervl) || defined(DEBUG_frank)
+# if !defined(DEBUG) || defined(DEBUG_sandervl) || defined(DEBUG_frank) || defined(IEM_VERIFICATION_MODE)
int cWait = 10;
# else
int cWait = HWACCMIsEnabled(pVM)
diff --git a/src/VBox/VMM/VMMR3/DBGFAddr.cpp b/src/VBox/VMM/VMMR3/DBGFAddr.cpp
index 7c39093c1..f957e5eea 100644
--- a/src/VBox/VMM/VMMR3/DBGFAddr.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFAddr.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFAddr.cpp $ */
+/* $Id: DBGFAddr.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Mixed Address Methods.
*/
diff --git a/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp b/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp
index b41d5250b..a5f569c36 100644
--- a/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFAddrSpace.cpp $ */
+/* $Id: DBGFAddrSpace.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Address Space Management.
*/
diff --git a/src/VBox/VMM/VMMR3/DBGFBp.cpp b/src/VBox/VMM/VMMR3/DBGFBp.cpp
index a0649d75e..4df1c5b3a 100644
--- a/src/VBox/VMM/VMMR3/DBGFBp.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFBp.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFBp.cpp $ */
+/* $Id: DBGFBp.cpp 35694 2011-01-24 17:35:59Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Breakpoint Management.
*/
@@ -37,12 +37,12 @@
*******************************************************************************/
RT_C_DECLS_BEGIN
static DECLCALLBACK(int) dbgfR3BpSetReg(PVM pVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger, uint64_t *piHitDisable,
- uint8_t u8Type, uint8_t cb, PRTUINT piBp);
-static DECLCALLBACK(int) dbgfR3BpSetInt3(PVM pVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger, uint64_t *piHitDisable, PRTUINT piBp);
-static DECLCALLBACK(int) dbgfR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger, uint64_t *piHitDisable, PRTUINT piBp);
-static DECLCALLBACK(int) dbgfR3BpClear(PVM pVM, RTUINT iBp);
-static DECLCALLBACK(int) dbgfR3BpEnable(PVM pVM, RTUINT iBp);
-static DECLCALLBACK(int) dbgfR3BpDisable(PVM pVM, RTUINT iBp);
+ uint8_t u8Type, uint8_t cb, uint32_t *piBp);
+static DECLCALLBACK(int) dbgfR3BpSetInt3(PVM pVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger, uint64_t *piHitDisable, uint32_t *piBp);
+static DECLCALLBACK(int) dbgfR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger, uint64_t *piHitDisable, uint32_t *piBp);
+static DECLCALLBACK(int) dbgfR3BpClear(PVM pVM, uint32_t iBp);
+static DECLCALLBACK(int) dbgfR3BpEnable(PVM pVM, uint32_t iBp);
+static DECLCALLBACK(int) dbgfR3BpDisable(PVM pVM, uint32_t iBp);
static DECLCALLBACK(int) dbgfR3BpEnum(PVM pVM, PFNDBGFBPENUM pfnCallback, void *pvUser);
static int dbgfR3BpRegArm(PVM pVM, PDBGFBP pBp);
static int dbgfR3BpRegDisarm(PVM pVM, PDBGFBP pBp);
@@ -100,9 +100,9 @@ static PDBGFBP dbgfR3BpAlloc(PVM pVM, DBGFBPTYPE enmType)
/*
* Determine which array to search.
*/
- unsigned cBps;
- PRTUINT pcBpsCur;
- PDBGFBP paBps;
+ unsigned cBps;
+ uint32_t *pcBpsCur;
+ PDBGFBP paBps;
switch (enmType)
{
case DBGFBPTYPE_REG:
@@ -148,7 +148,7 @@ static PDBGFBP dbgfR3BpAlloc(PVM pVM, DBGFBPTYPE enmType)
* @param pVM The VM handle.
* @param iBp The breakpoint id.
*/
-static PDBGFBP dbgfR3BpGet(PVM pVM, RTUINT iBp)
+static PDBGFBP dbgfR3BpGet(PVM pVM, uint32_t iBp)
{
/* Find it. */
PDBGFBP pBp;
@@ -277,7 +277,7 @@ static void dbgfR3BpFree(PVM pVM, PDBGFBP pBp)
* @param piBp Where to store the breakpoint id. (optional)
* @thread Any thread.
*/
-VMMR3DECL(int) DBGFR3BpSet(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, PRTUINT piBp)
+VMMR3DECL(int) DBGFR3BpSet(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp)
{
/*
* This must be done in EMT.
@@ -302,7 +302,7 @@ VMMR3DECL(int) DBGFR3BpSet(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger
* @param piBp Where to store the breakpoint id. (optional)
* @thread Any thread.
*/
-static DECLCALLBACK(int) dbgfR3BpSetInt3(PVM pVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger, uint64_t *piHitDisable, PRTUINT piBp)
+static DECLCALLBACK(int) dbgfR3BpSetInt3(PVM pVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger, uint64_t *piHitDisable, uint32_t *piBp)
{
/*
* Validate input.
@@ -434,7 +434,7 @@ static int dbgfR3BpInt3Disarm(PVM pVM, PDBGFBP pBp)
* @thread Any thread.
*/
VMMR3DECL(int) DBGFR3BpSetReg(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable,
- uint8_t fType, uint8_t cb, PRTUINT piBp)
+ uint8_t fType, uint8_t cb, uint32_t *piBp)
{
/** @todo SMP - broadcast, VT-x/AMD-V. */
/*
@@ -465,7 +465,7 @@ VMMR3DECL(int) DBGFR3BpSetReg(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrig
* @internal
*/
static DECLCALLBACK(int) dbgfR3BpSetReg(PVM pVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger, uint64_t *piHitDisable,
- uint8_t fType, uint8_t cb, PRTUINT piBp)
+ uint8_t fType, uint8_t cb, uint32_t *piBp)
{
/*
* Validate input.
@@ -602,7 +602,7 @@ static int dbgfR3BpRegDisarm(PVM pVM, PDBGFBP pBp)
* @param piBp Where to store the breakpoint id. (optional)
* @thread Any thread.
*/
-VMMR3DECL(int) DBGFR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, PRTUINT piBp)
+VMMR3DECL(int) DBGFR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp)
{
/*
* This must be done in EMT.
@@ -627,7 +627,7 @@ VMMR3DECL(int) DBGFR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrig
* @thread EMT
* @internal
*/
-static DECLCALLBACK(int) dbgfR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger, uint64_t *piHitDisable, PRTUINT piBp)
+static DECLCALLBACK(int) dbgfR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger, uint64_t *piHitDisable, uint32_t *piBp)
{
/*
* Validate input.
@@ -694,7 +694,7 @@ static DECLCALLBACK(int) dbgfR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_
* @param iBp The id of the breakpoint which should be removed (cleared).
* @thread Any thread.
*/
-VMMR3DECL(int) DBGFR3BpClear(PVM pVM, RTUINT iBp)
+VMMR3DECL(int) DBGFR3BpClear(PVM pVM, uint32_t iBp)
{
/*
* This must be done in EMT.
@@ -714,7 +714,7 @@ VMMR3DECL(int) DBGFR3BpClear(PVM pVM, RTUINT iBp)
* @thread EMT
* @internal
*/
-static DECLCALLBACK(int) dbgfR3BpClear(PVM pVM, RTUINT iBp)
+static DECLCALLBACK(int) dbgfR3BpClear(PVM pVM, uint32_t iBp)
{
/*
* Validate input.
@@ -767,7 +767,7 @@ static DECLCALLBACK(int) dbgfR3BpClear(PVM pVM, RTUINT iBp)
* @param iBp The id of the breakpoint which should be enabled.
* @thread Any thread.
*/
-VMMR3DECL(int) DBGFR3BpEnable(PVM pVM, RTUINT iBp)
+VMMR3DECL(int) DBGFR3BpEnable(PVM pVM, uint32_t iBp)
{
/*
* This must be done in EMT.
@@ -787,7 +787,7 @@ VMMR3DECL(int) DBGFR3BpEnable(PVM pVM, RTUINT iBp)
* @thread EMT
* @internal
*/
-static DECLCALLBACK(int) dbgfR3BpEnable(PVM pVM, RTUINT iBp)
+static DECLCALLBACK(int) dbgfR3BpEnable(PVM pVM, uint32_t iBp)
{
/*
* Validate input.
@@ -840,7 +840,7 @@ static DECLCALLBACK(int) dbgfR3BpEnable(PVM pVM, RTUINT iBp)
* @param iBp The id of the breakpoint which should be disabled.
* @thread Any thread.
*/
-VMMR3DECL(int) DBGFR3BpDisable(PVM pVM, RTUINT iBp)
+VMMR3DECL(int) DBGFR3BpDisable(PVM pVM, uint32_t iBp)
{
/*
* This must be done in EMT.
@@ -860,7 +860,7 @@ VMMR3DECL(int) DBGFR3BpDisable(PVM pVM, RTUINT iBp)
* @thread EMT
* @internal
*/
-static DECLCALLBACK(int) dbgfR3BpDisable(PVM pVM, RTUINT iBp)
+static DECLCALLBACK(int) dbgfR3BpDisable(PVM pVM, uint32_t iBp)
{
/*
* Validate input.
diff --git a/src/VBox/VMM/VMMR3/DBGFCoreWrite.cpp b/src/VBox/VMM/VMMR3/DBGFCoreWrite.cpp
index a6c0dfe18..d850599a2 100644
--- a/src/VBox/VMM/VMMR3/DBGFCoreWrite.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFCoreWrite.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFCoreWrite.cpp $ */
+/* $Id: DBGFCoreWrite.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Guest Core Dump.
*/
diff --git a/src/VBox/VMM/VMMR3/DBGFCpu.cpp b/src/VBox/VMM/VMMR3/DBGFCpu.cpp
index 9f8efd6e0..14a235e1f 100644
--- a/src/VBox/VMM/VMMR3/DBGFCpu.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFCpu.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFCpu.cpp $ */
+/* $Id: DBGFCpu.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, CPU State Accessors.
*/
diff --git a/src/VBox/VMM/VMMR3/DBGFDisas.cpp b/src/VBox/VMM/VMMR3/DBGFDisas.cpp
index b7fefac45..c722c320c 100644
--- a/src/VBox/VMM/VMMR3/DBGFDisas.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFDisas.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFDisas.cpp $ */
+/* $Id: DBGFDisas.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Disassembler.
*/
diff --git a/src/VBox/VMM/VMMR3/DBGFInfo.cpp b/src/VBox/VMM/VMMR3/DBGFInfo.cpp
index 0a48ff3cc..aed5b7eec 100644
--- a/src/VBox/VMM/VMMR3/DBGFInfo.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFInfo.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFInfo.cpp $ */
+/* $Id: DBGFInfo.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Info.
*/
diff --git a/src/VBox/VMM/VMMR3/DBGFLog.cpp b/src/VBox/VMM/VMMR3/DBGFLog.cpp
index 3af43f63f..f8162dba1 100644
--- a/src/VBox/VMM/VMMR3/DBGFLog.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFLog.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFLog.cpp $ */
+/* $Id: DBGFLog.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Log Manager.
*/
diff --git a/src/VBox/VMM/VMMR3/DBGFMem.cpp b/src/VBox/VMM/VMMR3/DBGFMem.cpp
index ee6747a9c..ea2eeb90b 100644
--- a/src/VBox/VMM/VMMR3/DBGFMem.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFMem.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFMem.cpp $ */
+/* $Id: DBGFMem.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Memory Methods.
*/
diff --git a/src/VBox/VMM/VMMR3/DBGFModule.cpp b/src/VBox/VMM/VMMR3/DBGFModule.cpp
index d17cbf650..2b3675e2f 100644
--- a/src/VBox/VMM/VMMR3/DBGFModule.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFModule.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFModule.cpp $ */
+/* $Id: DBGFModule.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Module & Segment Management.
*/
diff --git a/src/VBox/VMM/VMMR3/DBGFOS.cpp b/src/VBox/VMM/VMMR3/DBGFOS.cpp
index 103c4e657..4a5407d42 100644
--- a/src/VBox/VMM/VMMR3/DBGFOS.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFOS.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFOS.cpp $ */
+/* $Id: DBGFOS.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Guest OS Diggers.
*/
diff --git a/src/VBox/VMM/VMMR3/DBGFR3Trace.cpp b/src/VBox/VMM/VMMR3/DBGFR3Trace.cpp
new file mode 100644
index 000000000..a52573f57
--- /dev/null
+++ b/src/VBox/VMM/VMMR3/DBGFR3Trace.cpp
@@ -0,0 +1,200 @@
+/* $Id: DBGFR3Trace.cpp 37410 2011-06-10 15:11:40Z vboxsync $ */
+/** @file
+ * DBGF - Debugger Facility, Tracing.
+ */
+
+/*
+ * 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 *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_DBGF
+#include <VBox/vmm/dbgftrace.h>
+#include <VBox/vmm/cfgm.h>
+#include <VBox/vmm/mm.h>
+#include "DBGFInternal.h"
+#include <VBox/vmm/vm.h>
+
+#include <VBox/err.h>
+#include <VBox/log.h>
+#include <VBox/param.h>
+
+#include <iprt/assert.h>
+#include <iprt/trace.h>
+
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+static DECLCALLBACK(void) dbgfR3TraceInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
+
+
+/**
+ * Initializes the tracing.
+ *
+ * @returns VBox status code
+ * @param pVM The VM handle.
+ */
+static int dbgfR3TraceEnable(PVM pVM, uint32_t cbEntry, uint32_t cEntries)
+{
+ /*
+ * Don't enable it twice.
+ */
+ if (pVM->hTraceBufR3 != NIL_RTTRACEBUF)
+ return VERR_ALREADY_EXISTS;
+
+ /*
+ * Resolve default parameter values.
+ */
+ int rc;
+ if (!cbEntry)
+ {
+ rc = CFGMR3QueryU32Def(CFGMR3GetChild(CFGMR3GetRoot(pVM), "DBGF"), "TraceBufEntrySize", &cbEntry, 128);
+ AssertRCReturn(rc, rc);
+ }
+ if (!cEntries)
+ {
+ rc = CFGMR3QueryU32Def(CFGMR3GetChild(CFGMR3GetRoot(pVM), "DBGF"), "TraceBufEntries", &cEntries, 4096);
+ AssertRCReturn(rc, rc);
+ }
+
+ /*
+ * Figure the required size.
+ */
+ RTTRACEBUF hTraceBuf;
+ size_t cbBlock = 0;
+ rc = RTTraceBufCarve(&hTraceBuf, cEntries, cbEntry, 0 /*fFlags*/, NULL, &cbBlock);
+ if (rc != VERR_BUFFER_OVERFLOW)
+ {
+ AssertReturn(!RT_SUCCESS_NP(rc), VERR_INTERNAL_ERROR_4);
+ return rc;
+ }
+
+ /*
+ * Allocate a hyper heap block and carve a trace buffer out of it.
+ *
+ * Note! We ASSUME that the returned trace buffer handle has the same value
+ * as the heap block.
+ */
+ cbBlock = RT_ALIGN_Z(cbBlock, PAGE_SIZE);
+ void *pvBlock;
+ rc = MMR3HyperAllocOnceNoRel(pVM, cbBlock, PAGE_SIZE, MM_TAG_DBGF, &pvBlock);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ rc = RTTraceBufCarve(&hTraceBuf, cEntries, cbEntry, 0 /*fFlags*/, pvBlock, &cbBlock);
+ AssertRCReturn(rc, rc);
+ AssertRelease(hTraceBuf == (RTTRACEBUF)pvBlock && (void *)hTraceBuf == pvBlock);
+
+ pVM->hTraceBufR3 = hTraceBuf;
+ pVM->hTraceBufR0 = MMHyperCCToR0(pVM, hTraceBuf);
+ pVM->hTraceBufRC = MMHyperCCToRC(pVM, hTraceBuf);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Initializes the tracing.
+ *
+ * @returns VBox status code
+ * @param pVM The VM handle.
+ */
+int dbgfR3TraceInit(PVM pVM)
+{
+ /*
+ * Initialize the trace buffer handles.
+ */
+ Assert(NIL_RTTRACEBUF == (RTTRACEBUF)NULL);
+ pVM->hTraceBufR3 = NIL_RTTRACEBUF;
+ pVM->hTraceBufRC = NIL_RTRCPTR;
+ pVM->hTraceBufR0 = NIL_RTR0PTR;
+
+ /*
+ * Check the config and enable tracing if requested.
+ */
+#if defined(DEBUG) || defined(RTTRACE_ENABLED)
+ bool const fDefault = true;
+#else
+ bool const fDefault = false;
+#endif
+ bool fTracingEnabled;
+ int rc = CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "DBGF"), "TracingEnabled",
+ &fTracingEnabled, fDefault);
+ AssertRCReturn(rc, rc);
+ if (fTracingEnabled)
+ rc = dbgfR3TraceEnable(pVM, 0, 0);
+
+ /*
+ * Register a debug info item that will dump the trace buffer content.
+ */
+ if (RT_SUCCESS(rc))
+ rc = DBGFR3InfoRegisterInternal(pVM, "tracebuf", "Display the trace buffer content. No arguments.", dbgfR3TraceInfo);
+
+ return rc;
+}
+
+
+/**
+ * Terminates the tracing.
+ *
+ * @param pVM The VM handle.
+ */
+void dbgfR3TraceTerm(PVM pVM)
+{
+ /* nothing to do */
+ NOREF(pVM);
+}
+
+
+/**
+ * Relocates the trace buffer handle in RC.
+ *
+ * @param pVM The VM handle.
+ */
+void dbgfR3TraceRelocate(PVM pVM)
+{
+ if (pVM->hTraceBufR3 != NIL_RTTRACEBUF)
+ pVM->hTraceBufRC = MMHyperCCToRC(pVM, pVM->hTraceBufR3);
+}
+
+
+/**
+ * @callback_method_impl{FNRTTRACEBUFCALLBACK}
+ */
+static DECLCALLBACK(int)
+dbgfR3TraceInfoDumpEntry(RTTRACEBUF hTraceBuf, uint32_t iEntry, uint64_t NanoTS, RTCPUID idCpu, const char *pszMsg, void *pvUser)
+{
+ PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
+ pHlp->pfnPrintf(pHlp, "#%04u/%'llu/%02x: %s\n", iEntry, NanoTS, idCpu, pszMsg);
+ NOREF(hTraceBuf);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @callback_method_impl{FNDBGFHANDLERINT, Info handler for displaying the trace buffer content.}
+ */
+static DECLCALLBACK(void) dbgfR3TraceInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+ RTTRACEBUF hTraceBuf = pVM->hTraceBufR3;
+ if (hTraceBuf == NIL_RTTRACEBUF)
+ pHlp->pfnPrintf(pHlp, "Tracing is disable\n");
+ else
+ {
+ pHlp->pfnPrintf(pHlp, "Trace buffer %p - %u entries of %u bytes\n",
+ hTraceBuf, RTTraceBufGetEntryCount(hTraceBuf), RTTraceBufGetEntrySize(hTraceBuf));
+ RTTraceBufEnumEntries(hTraceBuf, dbgfR3TraceInfoDumpEntry, (void *)pHlp);
+ }
+}
+
diff --git a/src/VBox/VMM/VMMR3/DBGFReg.cpp b/src/VBox/VMM/VMMR3/DBGFReg.cpp
index b1994e57c..79e595843 100644
--- a/src/VBox/VMM/VMMR3/DBGFReg.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFReg.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFReg.cpp $ */
+/* $Id: DBGFReg.cpp 36826 2011-04-23 23:12:54Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Register Methods.
*/
@@ -168,10 +168,10 @@ typedef DBGFR3REGNMQUERYALLARGS *PDBGFR3REGNMQUERYALLARGS;
/**
- * Argument packet passed by DBGFR3RegNmPrintfV to dbgfR3RegNmPrintfCbOutput
- * and dbgfR3RegNmPrintfCbFormat.
+ * Argument packet passed by DBGFR3RegPrintfV to dbgfR3RegPrintfCbOutput and
+ * dbgfR3RegPrintfCbFormat.
*/
-typedef struct DBGFR3REGNMPRINTFARGS
+typedef struct DBGFR3REGPRINTFARGS
{
/** The VM handle. */
PVM pVM;
@@ -193,9 +193,9 @@ typedef struct DBGFR3REGNMPRINTFARGS
/** The status code of the whole operation. First error is return,
* subsequent ones are suppressed. */
int rc;
-} DBGFR3REGNMPRINTFARGS;
-/** Pointer to a DBGFR3RegNmPrintfV argument packet. */
-typedef DBGFR3REGNMPRINTFARGS *PDBGFR3REGNMPRINTFARGS;
+} DBGFR3REGPRINTFARGS;
+/** Pointer to a DBGFR3RegPrintfV argument packet. */
+typedef DBGFR3REGPRINTFARGS *PDBGFR3REGPRINTFARGS;
@@ -1258,7 +1258,7 @@ static PCDBGFREGLOOKUP dbgfR3RegResolve(PVM pVM, VMCPUID idDefCpu, const char *p
/**
* On CPU worker for the register queries, used by dbgfR3RegNmQueryWorker and
- * dbgfR3RegNmPrintfCbFormatNormal.
+ * dbgfR3RegPrintfCbFormatNormal.
*
* @returns VBox status code.
*
@@ -1839,6 +1839,12 @@ VMMR3DECL(int) DBGFR3RegNmQueryAll(PVM pVM, PDBGFREGENTRYNM paRegs, size_t cRegs
}
+VMMR3DECL(int) DBGFR3RegNmSet(PVM pVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType)
+{
+ return VERR_NOT_IMPLEMENTED;
+}
+
+
/**
* Internal worker for DBGFR3RegFormatValue, cbTmp is sufficent.
*
@@ -1904,7 +1910,7 @@ VMMDECL(ssize_t) DBGFR3RegFormatValueEx(char *pszBuf, size_t cbBuf, PCDBGFREGVAL
unsigned uBase, signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
{
/*
- * Format to temporary buffer using worker shared with dbgfR3RegNmPrintfCbFormatNormal.
+ * Format to temporary buffer using worker shared with dbgfR3RegPrintfCbFormatNormal.
*/
char szTmp[160];
ssize_t cchOutput = dbgfR3RegFormatValueInt(szTmp, sizeof(szTmp), pValue, enmType, uBase, cchWidth, cchPrecision, fFlags);
@@ -1970,8 +1976,8 @@ VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL p
* (the latter isn't implemented yet).
*/
static size_t
-dbgfR3RegNmPrintfCbFormatField(PDBGFR3REGNMPRINTFARGS pThis, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
- PCDBGFREGLOOKUP pLookupRec, int cchWidth, int cchPrecision, unsigned fFlags)
+dbgfR3RegPrintfCbFormatField(PDBGFR3REGPRINTFARGS pThis, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+ PCDBGFREGLOOKUP pLookupRec, int cchWidth, int cchPrecision, unsigned fFlags)
{
char szTmp[160];
@@ -2063,8 +2069,8 @@ dbgfR3RegNmPrintfCbFormatField(PDBGFR3REGNMPRINTFARGS pThis, PFNRTSTROUTPUT pfnO
* Formats a register having parsed up to the register name.
*/
static size_t
-dbgfR3RegNmPrintfCbFormatNormal(PDBGFR3REGNMPRINTFARGS pThis, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
- PCDBGFREGLOOKUP pLookupRec, unsigned uBase, int cchWidth, int cchPrecision, unsigned fFlags)
+dbgfR3RegPrintfCbFormatNormal(PDBGFR3REGPRINTFARGS pThis, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+ PCDBGFREGLOOKUP pLookupRec, unsigned uBase, int cchWidth, int cchPrecision, unsigned fFlags)
{
char szTmp[160];
@@ -2099,14 +2105,14 @@ dbgfR3RegNmPrintfCbFormatNormal(PDBGFR3REGNMPRINTFARGS pThis, PFNRTSTROUTPUT pfn
* @callback_method_impl{FNSTRFORMAT}
*/
static DECLCALLBACK(size_t)
-dbgfR3RegNmPrintfCbFormat(void *pvArg, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
- const char **ppszFormat, va_list *pArgs, int cchWidth,
- int cchPrecision, unsigned fFlags, char chArgSize)
+dbgfR3RegPrintfCbFormat(void *pvArg, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+ const char **ppszFormat, va_list *pArgs, int cchWidth,
+ int cchPrecision, unsigned fFlags, char chArgSize)
{
/*
* Parse the format type and hand the job to the appropriate worker.
*/
- PDBGFR3REGNMPRINTFARGS pThis = (PDBGFR3REGNMPRINTFARGS)pvArg;
+ PDBGFR3REGPRINTFARGS pThis = (PDBGFR3REGPRINTFARGS)pvArg;
const char *pszFormat = *ppszFormat;
if ( pszFormat[0] != 'V'
|| pszFormat[1] != 'R')
@@ -2172,19 +2178,19 @@ dbgfR3RegNmPrintfCbFormat(void *pvArg, PFNRTSTROUTPUT pfnOutput, void *pvArgOutp
{
case 'R': /* %VR{} */
case 'X': /* %VRX{} */
- return dbgfR3RegNmPrintfCbFormatNormal(pThis, pfnOutput, pvArgOutput, pLookupRec,
- 16, cchWidth, cchPrecision, fFlags);
+ return dbgfR3RegPrintfCbFormatNormal(pThis, pfnOutput, pvArgOutput, pLookupRec,
+ 16, cchWidth, cchPrecision, fFlags);
case 'U':
- return dbgfR3RegNmPrintfCbFormatNormal(pThis, pfnOutput, pvArgOutput, pLookupRec,
- 10, cchWidth, cchPrecision, fFlags);
+ return dbgfR3RegPrintfCbFormatNormal(pThis, pfnOutput, pvArgOutput, pLookupRec,
+ 10, cchWidth, cchPrecision, fFlags);
case 'O':
- return dbgfR3RegNmPrintfCbFormatNormal(pThis, pfnOutput, pvArgOutput, pLookupRec,
- 8, cchWidth, cchPrecision, fFlags);
+ return dbgfR3RegPrintfCbFormatNormal(pThis, pfnOutput, pvArgOutput, pLookupRec,
+ 8, cchWidth, cchPrecision, fFlags);
case 'B':
- return dbgfR3RegNmPrintfCbFormatNormal(pThis, pfnOutput, pvArgOutput, pLookupRec,
- 2, cchWidth, cchPrecision, fFlags);
+ return dbgfR3RegPrintfCbFormatNormal(pThis, pfnOutput, pvArgOutput, pLookupRec,
+ 2, cchWidth, cchPrecision, fFlags);
case 'F':
- return dbgfR3RegNmPrintfCbFormatField(pThis, pfnOutput, pvArgOutput, pLookupRec, cchWidth, cchPrecision, fFlags);
+ return dbgfR3RegPrintfCbFormatField(pThis, pfnOutput, pvArgOutput, pLookupRec, cchWidth, cchPrecision, fFlags);
default:
AssertFailed();
return 0;
@@ -2197,9 +2203,9 @@ dbgfR3RegNmPrintfCbFormat(void *pvArg, PFNRTSTROUTPUT pfnOutput, void *pvArgOutp
* @callback_method_impl{FNRTSTROUTPUT}
*/
static DECLCALLBACK(size_t)
-dbgfR3RegNmPrintfCbOutput(void *pvArg, const char *pachChars, size_t cbChars)
+dbgfR3RegPrintfCbOutput(void *pvArg, const char *pachChars, size_t cbChars)
{
- PDBGFR3REGNMPRINTFARGS pArgs = (PDBGFR3REGNMPRINTFARGS)pvArg;
+ PDBGFR3REGPRINTFARGS pArgs = (PDBGFR3REGPRINTFARGS)pvArg;
size_t cbToCopy = cbChars;
if (cbToCopy >= pArgs->cchLeftBuf)
{
@@ -2209,9 +2215,9 @@ dbgfR3RegNmPrintfCbOutput(void *pvArg, const char *pachChars, size_t cbChars)
}
if (cbToCopy > 0)
{
- memcpy(&pArgs->pszBuf[pArgs->offBuf], pachChars, cbChars);
- pArgs->offBuf += cbChars;
- pArgs->cchLeftBuf -= cbChars;
+ memcpy(&pArgs->pszBuf[pArgs->offBuf], pachChars, cbToCopy);
+ pArgs->offBuf += cbToCopy;
+ pArgs->cchLeftBuf -= cbToCopy;
pArgs->pszBuf[pArgs->offBuf] = '\0';
}
return cbToCopy;
@@ -2219,16 +2225,16 @@ dbgfR3RegNmPrintfCbOutput(void *pvArg, const char *pachChars, size_t cbChars)
/**
- * On CPU worker for the register formatting, used by DBGFR3RegNmPrintfV.
+ * On CPU worker for the register formatting, used by DBGFR3RegPrintfV.
*
* @returns VBox status code.
*
* @param pArgs The argument package and state.
*/
-static DECLCALLBACK(int) dbgfR3RegNmPrintfWorkerOnCpu(PDBGFR3REGNMPRINTFARGS pArgs)
+static DECLCALLBACK(int) dbgfR3RegPrintfWorkerOnCpu(PDBGFR3REGPRINTFARGS pArgs)
{
DBGF_REG_DB_LOCK_READ(pArgs->pVM);
- RTStrFormatV(dbgfR3RegNmPrintfCbOutput, pArgs, dbgfR3RegNmPrintfCbFormat, pArgs, pArgs->pszFormat, pArgs->va);
+ RTStrFormatV(dbgfR3RegPrintfCbOutput, pArgs, dbgfR3RegPrintfCbFormat, pArgs, pArgs->pszFormat, pArgs->va);
DBGF_REG_DB_UNLOCK_READ(pArgs->pVM);
return pArgs->rc;
}
@@ -2263,7 +2269,7 @@ VMMR3DECL(int) DBGFR3RegPrintfV(PVM pVM, VMCPUID idCpu, char *pszBuf, size_t cbB
* Set up an argument package and execute the formatting on the
* specified CPU.
*/
- DBGFR3REGNMPRINTFARGS Args;
+ DBGFR3REGPRINTFARGS Args;
Args.pVM = pVM;
Args.idCpu = idCpu != VMCPUID_ANY ? idCpu & ~DBGFREG_HYPER_VMCPUID : idCpu;
Args.fGuestRegs = idCpu != VMCPUID_ANY && !(idCpu & DBGFREG_HYPER_VMCPUID);
@@ -2273,7 +2279,7 @@ VMMR3DECL(int) DBGFR3RegPrintfV(PVM pVM, VMCPUID idCpu, char *pszBuf, size_t cbB
Args.offBuf = 0;
Args.cchLeftBuf = cbBuf - 1;
Args.rc = VINF_SUCCESS;
- int rc = VMR3ReqCallWait(pVM, Args.idCpu, (PFNRT)dbgfR3RegNmPrintfWorkerOnCpu, 1, &Args);
+ int rc = VMR3ReqCallWait(pVM, Args.idCpu, (PFNRT)dbgfR3RegPrintfWorkerOnCpu, 1, &Args);
va_end(Args.va);
return rc;
}
diff --git a/src/VBox/VMM/VMMR3/DBGFStack.cpp b/src/VBox/VMM/VMMR3/DBGFStack.cpp
index 9e64374b5..6faf7cbeb 100644
--- a/src/VBox/VMM/VMMR3/DBGFStack.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFStack.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFStack.cpp $ */
+/* $Id: DBGFStack.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Call Stack Analyser.
*/
diff --git a/src/VBox/VMM/VMMR3/DBGFSym.cpp b/src/VBox/VMM/VMMR3/DBGFSym.cpp
index bfbcd76a3..7299058e4 100644
--- a/src/VBox/VMM/VMMR3/DBGFSym.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFSym.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFSym.cpp $ */
+/* $Id: DBGFSym.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, Symbol Management.
*/
diff --git a/src/VBox/VMM/VMMR3/EM.cpp b/src/VBox/VMM/VMMR3/EM.cpp
index 81e2c9519..897729fe8 100644
--- a/src/VBox/VMM/VMMR3/EM.cpp
+++ b/src/VBox/VMM/VMMR3/EM.cpp
@@ -1,10 +1,10 @@
-/* $Id: EM.cpp $ */
+/* $Id: EM.cpp 36825 2011-04-23 22:41:20Z vboxsync $ */
/** @file
* EM - Execution Monitor / Manager.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -53,6 +53,9 @@
#include <VBox/vmm/pdmqueue.h>
#include <VBox/vmm/hwaccm.h>
#include <VBox/vmm/patm.h>
+#ifdef IEM_VERIFICATION_MODE
+# include <VBox/vmm/iem.h>
+#endif
#include "EMInternal.h"
#include "internal/em.h"
#include <VBox/vmm/vm.h>
@@ -988,9 +991,9 @@ static int emR3RemExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone)
#ifdef VBOX_HIGH_RES_TIMERS_HACK
TMTimerPollVoid(pVM, pVCpu);
#endif
- AssertCompile((VMCPU_FF_ALL_BUT_RAW_MASK & ~(VMCPU_FF_CSAM_PENDING_ACTION | VMCPU_FF_CSAM_SCAN_PAGE)) & VMCPU_FF_TIMER);
- if ( VM_FF_ISPENDING(pVM, VM_FF_ALL_BUT_RAW_MASK)
- || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_BUT_RAW_MASK & ~(VMCPU_FF_CSAM_PENDING_ACTION | VMCPU_FF_CSAM_SCAN_PAGE)))
+ AssertCompile((VMCPU_FF_ALL_REM_MASK & ~(VMCPU_FF_CSAM_PENDING_ACTION | VMCPU_FF_CSAM_SCAN_PAGE)) & VMCPU_FF_TIMER);
+ if ( VM_FF_ISPENDING(pVM, VM_FF_ALL_REM_MASK)
+ || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_REM_MASK & ~(VMCPU_FF_CSAM_PENDING_ACTION | VMCPU_FF_CSAM_SCAN_PAGE)))
{
l_REMDoForcedActions:
if (fInREMState)
@@ -1056,6 +1059,10 @@ int emR3SingleStepExecRem(PVM pVM, PVMCPU pVCpu, uint32_t cIterations)
*/
EMSTATE emR3Reschedule(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
{
+#ifdef IEM_VERIFICATION_MODE
+ return EMSTATE_REM;
+#else
+
/*
* When forcing raw-mode execution, things are simple.
*/
@@ -1101,12 +1108,12 @@ EMSTATE emR3Reschedule(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
return EMSTATE_REM;
}
-#ifndef VBOX_RAW_V86
+# ifndef VBOX_RAW_V86
if (EFlags.u32 & X86_EFL_VM) {
Log2(("raw mode refused: VM_MASK\n"));
return EMSTATE_REM;
}
-#endif
+# endif
/** @todo check up the X86_CR0_AM flag in respect to raw mode!!! We're probably not emulating it right! */
uint32_t u32CR0 = pCtx->cr0;
@@ -1178,14 +1185,14 @@ EMSTATE emR3Reschedule(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
return EMSTATE_RAW;
}
-#if !defined(VBOX_ALLOW_IF0) && !defined(VBOX_RUN_INTERRUPT_GATE_HANDLERS)
+# if !defined(VBOX_ALLOW_IF0) && !defined(VBOX_RUN_INTERRUPT_GATE_HANDLERS)
if (!(EFlags.u32 & X86_EFL_IF))
{
////Log2(("R0: IF=0 VIF=%d %08X\n", eip, pVMeflags));
//Log2(("RR0: Interrupts turned off; fall back to emulation\n"));
return EMSTATE_REM;
}
-#endif
+# endif
/** @todo still necessary??? */
if (EFlags.Bits.u2IOPL != 0)
@@ -1197,6 +1204,8 @@ EMSTATE emR3Reschedule(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
Assert(PGMPhysIsA20Enabled(pVCpu));
return EMSTATE_RAW;
+#endif /* !IEM_VERIFICATION_MODE */
+
}
@@ -1498,8 +1507,8 @@ int emR3ForcedActions(PVM pVM, PVMCPU pVCpu, int rc)
if ( VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
&& !VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY))
{
- Log(("VM_FF_EMULATED_STI at %RGv successor %RGv\n", (RTGCPTR)CPUMGetGuestRIP(pVCpu), EMGetInhibitInterruptsPC(pVCpu)));
- if (CPUMGetGuestEIP(pVCpu) != EMGetInhibitInterruptsPC(pVCpu))
+ Log(("VMCPU_FF_INHIBIT_INTERRUPTS at %RGv successor %RGv\n", (RTGCPTR)CPUMGetGuestRIP(pVCpu), EMGetInhibitInterruptsPC(pVCpu)));
+ if (CPUMGetGuestRIP(pVCpu) != EMGetInhibitInterruptsPC(pVCpu))
{
/* Note: we intentionally don't clear VM_FF_INHIBIT_INTERRUPTS here if the eip is the same as the inhibited instr address.
* Before we are able to execute this instruction in raw mode (iret to guest code) an external interrupt might
@@ -1754,8 +1763,8 @@ VMMR3DECL(int) EMR3ExecuteVM(PVM pVM, PVMCPU pVCpu)
if ( !fFFDone
&& rc != VINF_EM_TERMINATE
&& rc != VINF_EM_OFF
- && ( VM_FF_ISPENDING(pVM, VM_FF_ALL_BUT_RAW_MASK)
- || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_BUT_RAW_MASK)))
+ && ( VM_FF_ISPENDING(pVM, VM_FF_ALL_REM_MASK)
+ || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_REM_MASK)))
{
rc = emR3ForcedActions(pVM, pVCpu, rc);
if ( ( rc == VINF_EM_RESCHEDULE_REM
@@ -1985,21 +1994,35 @@ VMMR3DECL(int) EMR3ExecuteVM(PVM pVM, PVMCPU pVCpu)
* Execute raw.
*/
case EMSTATE_RAW:
+#ifndef IEM_VERIFICATION_MODE /* remove later */
rc = emR3RawExecute(pVM, pVCpu, &fFFDone);
break;
+#endif
/*
* Execute hardware accelerated raw.
*/
case EMSTATE_HWACC:
+#ifndef IEM_VERIFICATION_MODE /* remove later */
rc = emR3HwAccExecute(pVM, pVCpu, &fFFDone);
break;
+#endif
/*
* Execute recompiled.
*/
case EMSTATE_REM:
+#ifdef IEM_VERIFICATION_MODE
+# if 1
+ rc = VBOXSTRICTRC_TODO(IEMExecOne(pVCpu)); fFFDone = false;
+# else
+ rc = VBOXSTRICTRC_TODO(REMR3EmulateInstruction(pVM, pVCpu)); fFFDone = false;
+ if (rc == VINF_EM_RESCHEDULE)
+ rc = VINF_SUCCESS;
+# endif
+#else
rc = emR3RemExecute(pVM, pVCpu, &fFFDone);
+#endif
Log2(("EMR3ExecuteVM: emR3RemExecute -> %Rrc\n", rc));
break;
diff --git a/src/VBox/VMM/VMMR3/EMHwaccm.cpp b/src/VBox/VMM/VMMR3/EMHwaccm.cpp
index 740d6861a..a5122a2bc 100644
--- a/src/VBox/VMM/VMMR3/EMHwaccm.cpp
+++ b/src/VBox/VMM/VMMR3/EMHwaccm.cpp
@@ -1,4 +1,4 @@
-/* $Id: EMHwaccm.cpp $ */
+/* $Id: EMHwaccm.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* EM - Execution Monitor / Manager - hardware virtualization
*/
diff --git a/src/VBox/VMM/VMMR3/EMRaw.cpp b/src/VBox/VMM/VMMR3/EMRaw.cpp
index bd190651a..06a37a4a2 100644
--- a/src/VBox/VMM/VMMR3/EMRaw.cpp
+++ b/src/VBox/VMM/VMMR3/EMRaw.cpp
@@ -1,4 +1,4 @@
-/* $Id: EMRaw.cpp $ */
+/* $Id: EMRaw.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* EM - Execution Monitor / Manager - software virtualization
diff --git a/src/VBox/VMM/VMMR3/FTM.cpp b/src/VBox/VMM/VMMR3/FTM.cpp
index baff39bc7..67c66e0ea 100644
--- a/src/VBox/VMM/VMMR3/FTM.cpp
+++ b/src/VBox/VMM/VMMR3/FTM.cpp
@@ -1,4 +1,4 @@
-/* $Id: FTM.cpp $ */
+/* $Id: FTM.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* FTM - Fault Tolerance Manager
*/
diff --git a/src/VBox/VMM/VMMR3/GMM.cpp b/src/VBox/VMM/VMMR3/GMM.cpp
index 258c49278..db6c073f5 100644
--- a/src/VBox/VMM/VMMR3/GMM.cpp
+++ b/src/VBox/VMM/VMMR3/GMM.cpp
@@ -1,4 +1,4 @@
-/* $Id: GMM.cpp $ */
+/* $Id: GMM.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* GMM - Global Memory Manager, ring-3 request wrappers.
*/
diff --git a/src/VBox/VMM/VMMR3/HWACCM.cpp b/src/VBox/VMM/VMMR3/HWACCM.cpp
index fa2e5daef..a7a9d028e 100644
--- a/src/VBox/VMM/VMMR3/HWACCM.cpp
+++ b/src/VBox/VMM/VMMR3/HWACCM.cpp
@@ -1,4 +1,4 @@
-/* $Id: HWACCM.cpp $ */
+/* $Id: HWACCM.cpp 37323 2011-06-03 16:20:06Z vboxsync $ */
/** @file
* HWACCM - Intel/AMD VM Hardware Support Manager
*/
@@ -271,6 +271,7 @@ static const char * const g_apszAmdVExitReasons[MAX_EXITREASON_STAT] =
static DECLCALLBACK(int) hwaccmR3Save(PVM pVM, PSSMHANDLE pSSM);
static DECLCALLBACK(int) hwaccmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
static int hwaccmR3InitCPU(PVM pVM);
+static int hwaccmR3InitFinalizeR0(PVM pVM);
static int hwaccmR3TermCPU(PVM pVM);
@@ -639,10 +640,12 @@ VMMR3_INT_DECL(int) HWACCMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
{
switch (enmWhat)
{
- case VMINITCOMPLETED_RING3:
- return hwaccmR3InitCPU(pVM);
- default:
- return VINF_SUCCESS;
+ case VMINITCOMPLETED_RING3:
+ return hwaccmR3InitCPU(pVM);
+ case VMINITCOMPLETED_RING0:
+ return hwaccmR3InitFinalizeR0(pVM);
+ default:
+ return VINF_SUCCESS;
}
}
@@ -685,7 +688,7 @@ static void hwaccmR3DisableRawMode(PVM pVM)
* @returns VBox status code.
* @param pVM The VM handle.
*/
-VMMR3DECL(int) HWACCMR3InitFinalizeR0(PVM pVM)
+static int hwaccmR3InitFinalizeR0(PVM pVM)
{
int rc;
@@ -1091,7 +1094,7 @@ VMMR3DECL(int) HWACCMR3InitFinalizeR0(PVM pVM)
for (VMCPUID i = 0; i < pVM->cCpus; i++)
{
LogRel(("HWACCM: VCPU%d: MSR bitmap physaddr = %RHp\n", i, pVM->aCpus[i].hwaccm.s.vmx.pMSRBitmapPhys));
- LogRel(("HWACCM: VCPU%d: VMCS physaddr = %RHp\n", i, pVM->aCpus[i].hwaccm.s.vmx.pVMCSPhys));
+ LogRel(("HWACCM: VCPU%d: VMCS physaddr = %RHp\n", i, pVM->aCpus[i].hwaccm.s.vmx.HCPhysVMCS));
}
#ifdef HWACCM_VTX_WITH_EPT
@@ -1305,19 +1308,33 @@ VMMR3DECL(int) HWACCMR3InitFinalizeR0(PVM pVM)
LogRel(("HWACCM: AMD-V revision = %X\n", pVM->hwaccm.s.svm.u32Rev));
LogRel(("HWACCM: AMD-V max ASID = %d\n", pVM->hwaccm.s.uMaxASID));
LogRel(("HWACCM: AMD-V features = %X\n", pVM->hwaccm.s.svm.u32Features));
-
- if (pVM->hwaccm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)
- LogRel(("HWACCM: AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING\n"));
- if (pVM->hwaccm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_LBR_VIRT)
- LogRel(("HWACCM: AMD_CPUID_SVM_FEATURE_EDX_LBR_VIRT\n"));
- if (pVM->hwaccm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_SVM_LOCK)
- LogRel(("HWACCM: AMD_CPUID_SVM_FEATURE_EDX_SVM_LOCK\n"));
- if (pVM->hwaccm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_NRIP_SAVE)
- LogRel(("HWACCM: AMD_CPUID_SVM_FEATURE_EDX_NRIP_SAVE\n"));
- if (pVM->hwaccm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_SSE_3_5_DISABLE)
- LogRel(("HWACCM: AMD_CPUID_SVM_FEATURE_EDX_SSE_3_5_DISABLE\n"));
- if (pVM->hwaccm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER)
- LogRel(("HWACCM: AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER\n"));
+ static const struct { uint32_t fFlag; const char *pszName; } s_aSvmFeatures[] =
+ {
+#define FLAG_NAME(a_Define) { a_Define, #a_Define }
+ FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING),
+ FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_LBR_VIRT),
+ FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_SVM_LOCK),
+ FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_NRIP_SAVE),
+ FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_TSC_RATE_MSR),
+ FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_VMCB_CLEAN),
+ FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID),
+ FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_DECODE_ASSIST),
+ FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_SSE_3_5_DISABLE),
+ FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER),
+ FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER),
+#undef FLAG_NAME
+ };
+ uint32_t fSvmFeatures = pVM->hwaccm.s.svm.u32Features;
+ for (unsigned i = 0; i < RT_ELEMENTS(s_aSvmFeatures); i++)
+ if (fSvmFeatures & s_aSvmFeatures[i].fFlag)
+ {
+ LogRel(("HWACCM: %s\n", s_aSvmFeatures[i].pszName));
+ fSvmFeatures &= ~s_aSvmFeatures[i].fFlag;
+ }
+ if (fSvmFeatures)
+ for (unsigned iBit = 0; iBit < 32; iBit++)
+ if (RT_BIT_32(iBit) & fSvmFeatures)
+ LogRel(("HWACCM: Reserved bit %u\n", iBit));
/* Only try once. */
pVM->hwaccm.s.fInitialized = true;
@@ -2575,7 +2592,7 @@ VMMR3DECL(void) HWACCMR3CheckError(PVM pVM, int iStatusCode)
break;
case VERR_VMX_INVALID_VMCS_PTR:
- LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Current pointer %RGp vs %RGp\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.u64VMCSPhys, pVM->aCpus[i].hwaccm.s.vmx.pVMCSPhys));
+ LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Current pointer %RGp vs %RGp\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.u64VMCSPhys, pVM->aCpus[i].hwaccm.s.vmx.HCPhysVMCS));
LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Current VMCS version %x\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.ulVMCSRevision));
LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Entered Cpu %d\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.idEnteredCpu));
LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Current Cpu %d\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.idCurrentCpu));
diff --git a/src/VBox/VMM/VMMR3/IEMR3.cpp b/src/VBox/VMM/VMMR3/IEMR3.cpp
new file mode 100644
index 000000000..a244c4241
--- /dev/null
+++ b/src/VBox/VMM/VMMR3/IEMR3.cpp
@@ -0,0 +1,56 @@
+/* $Id: IEMR3.cpp 36788 2011-04-21 09:33:24Z vboxsync $ */
+/** @file
+ * IEM - Interpreted Execution Manager.
+ */
+
+/*
+ * 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 *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_EM
+#include <VBox/vmm/iem.h>
+#include "IEMInternal.h"
+#include <VBox/vmm/vm.h>
+#include <VBox/err.h>
+
+#include <iprt/assert.h>
+
+
+VMMR3DECL(int) IEMR3Init(PVM pVM)
+{
+ for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+ {
+ PVMCPU pVCpu = &pVM->aCpus[idCpu];
+ pVCpu->iem.s.offVM = -RT_OFFSETOF(VM, aCpus[idCpu].iem.s);
+ pVCpu->iem.s.offVMCpu = -RT_OFFSETOF(VMCPU, iem.s);
+ pVCpu->iem.s.pCtxR3 = CPUMQueryGuestCtxPtr(pVCpu);
+ pVCpu->iem.s.pCtxR0 = VM_R0_ADDR(pVM, pVCpu->iem.s.pCtxR3);
+ pVCpu->iem.s.pCtxRC = VM_RC_ADDR(pVM, pVCpu->iem.s.pCtxR3);
+ }
+ return VINF_SUCCESS;
+}
+
+
+VMMR3DECL(int) IEMR3Term(PVM pVM)
+{
+ return VINF_SUCCESS;
+}
+
+
+VMMR3DECL(void) IEMR3Relocate(PVM pVM)
+{
+ for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+ pVM->aCpus[idCpu].iem.s.pCtxRC = VM_RC_ADDR(pVM, pVM->aCpus[idCpu].iem.s.pCtxR3);
+}
+
diff --git a/src/VBox/VMM/VMMR3/IOM.cpp b/src/VBox/VMM/VMMR3/IOM.cpp
index 9a82e2d51..96e1e4857 100644
--- a/src/VBox/VMM/VMMR3/IOM.cpp
+++ b/src/VBox/VMM/VMMR3/IOM.cpp
@@ -1,4 +1,4 @@
-/* $Id: IOM.cpp $ */
+/* $Id: IOM.cpp 37467 2011-06-15 13:08:45Z vboxsync $ */
/** @file
* IOM - Input / Output Monitor.
*/
@@ -112,6 +112,8 @@
#include <VBox/log.h>
#include <VBox/err.h>
+#include "IOMInline.h"
+
/*******************************************************************************
* Internal Functions *
@@ -146,7 +148,7 @@ VMMR3DECL(int) IOMR3Init(PVM pVM)
*/
AssertCompileMemberAlignment(VM, iom.s, 32);
AssertCompile(sizeof(pVM->iom.s) <= sizeof(pVM->iom.padding));
- AssertCompileMemberAlignment(IOM, EmtLock, sizeof(uintptr_t));
+ AssertCompileMemberAlignment(IOM, CritSect, sizeof(uintptr_t));
/*
* Setup any fixed pointers and offsets.
@@ -156,7 +158,7 @@ VMMR3DECL(int) IOMR3Init(PVM pVM)
/*
* Initialize the REM critical section.
*/
- int rc = PDMR3CritSectInit(pVM, &pVM->iom.s.EmtLock, RT_SRC_POS, "IOM EMT Lock");
+ int rc = PDMR3CritSectInit(pVM, &pVM->iom.s.CritSect, RT_SRC_POS, "IOM Lock");
AssertRCReturn(rc, rc);
/*
@@ -224,7 +226,8 @@ VMMR3DECL(int) IOMR3Init(PVM pVM)
*/
static void iomR3FlushCache(PVM pVM)
{
- iomLock(pVM);
+ IOM_LOCK(pVM);
+
/*
* Caching of port and statistics (saves some time in rep outs/ins instruction emulation)
*/
@@ -249,7 +252,7 @@ static void iomR3FlushCache(PVM pVM)
pVM->iom.s.pMMIORangeLastRC = NIL_RTRCPTR;
pVM->iom.s.pMMIOStatsLastRC = NIL_RTRCPTR;
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
}
@@ -452,7 +455,7 @@ PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc
AssertGCPhys32(GCPhys);
#endif
/* check if it already exists. */
- PIOMMMIOSTATS pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pVM->iom.s.pTreesR3->MMIOStatTree, GCPhys);
+ PIOMMMIOSTATS pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pVM->iom.s.pTreesR3->MmioStatTree, GCPhys);
if (pStats)
return pStats;
@@ -463,7 +466,7 @@ PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc
{
/* insert into the tree. */
pStats->Core.Key = GCPhys;
- if (RTAvloGCPhysInsert(&pVM->iom.s.pTreesR3->MMIOStatTree, &pStats->Core))
+ if (RTAvloGCPhysInsert(&pVM->iom.s.pTreesR3->MmioStatTree, &pStats->Core))
{
rc = STAMR3RegisterF(pVM, &pStats->Accesses, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, pszDesc, "/IOM/MMIO/%RGp", GCPhys); AssertRC(rc);
rc = STAMR3RegisterF(pVM, &pStats->ProfReadR3, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, pszDesc, "/IOM/MMIO/%RGp/Read-R3", GCPhys); AssertRC(rc);
@@ -559,17 +562,17 @@ VMMR3DECL(int) IOMR3IOPortRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortS
/*
* Try Insert it.
*/
- iomLock(pVM);
+ IOM_LOCK(pVM);
if (RTAvlroIOPortInsert(&pVM->iom.s.pTreesR3->IOPortTreeR3, &pRange->Core))
{
- #ifdef VBOX_WITH_STATISTICS
+#ifdef VBOX_WITH_STATISTICS
for (unsigned iPort = 0; iPort < cPorts; iPort++)
iomR3IOPortStatsCreate(pVM, PortStart + iPort, pszDesc);
- #endif
- iomUnlock(pVM);
+#endif
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
/* conflict. */
DBGFR3Info(pVM, "ioport", NULL, NULL);
@@ -625,7 +628,7 @@ VMMR3DECL(int) IOMR3IOPortRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
return VERR_INVALID_PARAMETER;
}
- iomLock(pVM);
+ IOM_LOCK(pVM);
/*
* Validate that there are ring-3 ranges for the ports.
@@ -637,7 +640,7 @@ VMMR3DECL(int) IOMR3IOPortRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
if (!pRange)
{
AssertMsgFailed(("No R3! Port=#x %#x-%#x! (%s)\n", Port, PortStart, (unsigned)PortStart + cPorts - 1, pszDesc));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VERR_IOM_NO_HC_IOPORT_RANGE;
}
#ifndef IOM_NO_PDMINS_CHECKS
@@ -648,7 +651,7 @@ VMMR3DECL(int) IOMR3IOPortRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
# endif
{
AssertMsgFailed(("Not owner! Port=%#x %#x-%#x! (%s)\n", Port, PortStart, (unsigned)PortStart + cPorts - 1, pszDesc));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VERR_IOM_NOT_IOPORT_RANGE_OWNER;
}
#endif
@@ -682,7 +685,7 @@ VMMR3DECL(int) IOMR3IOPortRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
*/
if (RTAvlroIOPortInsert(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortTreeRC, &pRange->Core))
{
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
@@ -691,7 +694,7 @@ VMMR3DECL(int) IOMR3IOPortRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
MMHyperFree(pVM, pRange);
rc = VERR_IOM_IOPORT_RANGE_CONFLICT;
}
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return rc;
}
@@ -740,7 +743,7 @@ VMMR3DECL(int) IOMR3IOPortRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
return VERR_INVALID_PARAMETER;
}
- iomLock(pVM);
+ IOM_LOCK(pVM);
/*
* Validate that there are ring-3 ranges for the ports.
*/
@@ -751,7 +754,7 @@ VMMR3DECL(int) IOMR3IOPortRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
if (!pRange)
{
AssertMsgFailed(("No R3! Port=#x %#x-%#x! (%s)\n", Port, PortStart, (unsigned)PortStart + cPorts - 1, pszDesc));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VERR_IOM_NO_HC_IOPORT_RANGE;
}
#ifndef IOM_NO_PDMINS_CHECKS
@@ -762,7 +765,7 @@ VMMR3DECL(int) IOMR3IOPortRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
# endif
{
AssertMsgFailed(("Not owner! Port=%#x %#x-%#x! (%s)\n", Port, PortStart, (unsigned)PortStart + cPorts - 1, pszDesc));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VERR_IOM_NOT_IOPORT_RANGE_OWNER;
}
#endif
@@ -796,7 +799,7 @@ VMMR3DECL(int) IOMR3IOPortRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
*/
if (RTAvlroIOPortInsert(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortTreeR0, &pRange->Core))
{
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
@@ -805,7 +808,7 @@ VMMR3DECL(int) IOMR3IOPortRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
MMHyperFree(pVM, pRange);
rc = VERR_IOM_IOPORT_RANGE_CONFLICT;
}
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return rc;
}
@@ -843,7 +846,7 @@ VMMR3DECL(int) IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
return VERR_IOM_INVALID_IOPORT_RANGE;
}
- iomLock(pVM);
+ IOM_LOCK(pVM);
/* Flush the IO port lookup cache */
iomR3FlushCache(pVM);
@@ -864,7 +867,7 @@ VMMR3DECL(int) IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
{
AssertMsgFailed(("Removal of ports in range %#x-%#x rejected because not owner of %#x-%#x (%s)\n",
PortStart, PortLast, pRange->Core.Key, pRange->Core.KeyLast, pRange->pszDesc));
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VERR_IOM_NOT_IOPORT_RANGE_OWNER;
}
#endif /* !IOM_NO_PDMINS_CHECKS */
@@ -928,7 +931,7 @@ VMMR3DECL(int) IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
int rc2 = MMHyperAlloc(pVM, sizeof(*pRangeNew), 0, MM_TAG_IOM, (void **)&pRangeNew);
if (RT_FAILURE(rc2))
{
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return rc2;
}
*pRangeNew = *pRange;
@@ -1011,7 +1014,7 @@ VMMR3DECL(int) IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
int rc2 = MMHyperAlloc(pVM, sizeof(*pRangeNew), 0, MM_TAG_IOM, (void **)&pRangeNew);
if (RT_FAILURE(rc2))
{
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return rc2;
}
*pRangeNew = *pRange;
@@ -1093,7 +1096,7 @@ VMMR3DECL(int) IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
int rc2 = MMHyperAlloc(pVM, sizeof(*pRangeNew), 0, MM_TAG_IOM, (void **)&pRangeNew);
if (RT_FAILURE(rc2))
{
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return rc2;
}
*pRangeNew = *pRange;
@@ -1122,7 +1125,7 @@ VMMR3DECL(int) IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT Port
} /* for all ports - ring-3. */
/* done */
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return rc;
}
@@ -1392,11 +1395,12 @@ static DECLCALLBACK(void) iomR3IOPortInfo(PVM pVM, PCDBGFINFOHLP pHlp, const cha
* @param pfnFillCallback Pointer to function which is gonna handle Fill/memset operations.
* @param pszDesc Pointer to description string. This must not be freed.
*/
-VMMR3DECL(int) IOMR3MMIORegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,
- R3PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback, R3PTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
- R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback, const char *pszDesc)
+VMMR3_INT_DECL(int)
+IOMR3MmioRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,
+ R3PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback, R3PTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
+ R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback, const char *pszDesc)
{
- LogFlow(("IOMR3MMIORegisterR3: pDevIns=%p GCPhysStart=%RGp cbRange=%#x pvUser=%RHv pfnWriteCallback=%#x pfnReadCallback=%#x pfnFillCallback=%#x pszDesc=%s\n",
+ LogFlow(("IOMR3MmioRegisterR3: pDevIns=%p GCPhysStart=%RGp cbRange=%#x pvUser=%RHv pfnWriteCallback=%#x pfnReadCallback=%#x pfnFillCallback=%#x pszDesc=%s\n",
pDevIns, GCPhysStart, cbRange, pvUser, pfnWriteCallback, pfnReadCallback, pfnFillCallback, pszDesc));
int rc;
@@ -1408,8 +1412,6 @@ VMMR3DECL(int) IOMR3MMIORegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
AssertMsgFailed(("Wrapped! %RGp %#x bytes\n", GCPhysStart, cbRange));
return VERR_IOM_INVALID_MMIO_RANGE;
}
- /** @todo implement per-device locks for MMIO access. */
- AssertReturn(!pDevIns->pCritSectR3, VERR_INTERNAL_ERROR_2);
/*
* Resolve the GC/R0 handler addresses lazily because of init order.
@@ -1445,6 +1447,7 @@ VMMR3DECL(int) IOMR3MMIORegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
pRange->Core.KeyLast = GCPhysStart + (cbRange - 1);
pRange->GCPhys = GCPhysStart;
pRange->cb = cbRange;
+ pRange->cRefs = 1; /* The tree reference. */
pRange->pszDesc = pszDesc;
pRange->pvUserR3 = pvUser;
@@ -1468,7 +1471,7 @@ VMMR3DECL(int) IOMR3MMIORegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
/*
* Try register it with PGM and then insert it into the tree.
*/
- iomLock(pVM);
+ IOM_LOCK(pVM);
iomR3FlushCache(pVM);
rc = PGMR3PhysMMIORegister(pVM, GCPhysStart, cbRange,
IOMR3MMIOHandler, pRange,
@@ -1478,18 +1481,18 @@ VMMR3DECL(int) IOMR3MMIORegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
{
if (RTAvlroGCPhysInsert(&pVM->iom.s.pTreesR3->MMIOTree, &pRange->Core))
{
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
/* bail out */
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
DBGFR3Info(pVM, "mmio", NULL, NULL);
AssertMsgFailed(("This cannot happen!\n"));
rc = VERR_INTERNAL_ERROR;
}
else
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
MMHyperFree(pVM, pRange);
}
@@ -1517,11 +1520,12 @@ VMMR3DECL(int) IOMR3MMIORegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
* @param pfnReadCallback Pointer to function which is gonna handle Read operations.
* @param pfnFillCallback Pointer to function which is gonna handle Fill/memset operations.
*/
-VMMR3DECL(int) IOMR3MMIORegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,
- RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback, RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
- RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallback)
+VMMR3_INT_DECL(int)
+IOMR3MmioRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,
+ RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback, RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
+ RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallback)
{
- LogFlow(("IOMR3MMIORegisterRC: pDevIns=%p GCPhysStart=%RGp cbRange=%#x pvUser=%RGv pfnWriteCallback=%#x pfnReadCallback=%#x pfnFillCallback=%#x\n",
+ LogFlow(("IOMR3MmioRegisterRC: pDevIns=%p GCPhysStart=%RGp cbRange=%#x pvUser=%RGv pfnWriteCallback=%#x pfnReadCallback=%#x pfnFillCallback=%#x\n",
pDevIns, GCPhysStart, cbRange, pvUser, pfnWriteCallback, pfnReadCallback, pfnFillCallback));
/*
@@ -1536,19 +1540,19 @@ VMMR3DECL(int) IOMR3MMIORegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
/*
* Find the MMIO range and check that the input matches.
*/
- iomLock(pVM);
- PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhysStart);
- AssertReturnStmt(pRange, iomUnlock(pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND);
- AssertReturnStmt(pRange->pDevInsR3 == pDevIns, iomUnlock(pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER);
- AssertReturnStmt(pRange->GCPhys == GCPhysStart, iomUnlock(pVM), VERR_IOM_INVALID_MMIO_RANGE);
- AssertReturnStmt(pRange->cb == cbRange, iomUnlock(pVM), VERR_IOM_INVALID_MMIO_RANGE);
+ IOM_LOCK(pVM);
+ PIOMMMIORANGE pRange = iomMmioGetRange(pVM, GCPhysStart);
+ AssertReturnStmt(pRange, IOM_UNLOCK(pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND);
+ AssertReturnStmt(pRange->pDevInsR3 == pDevIns, IOM_UNLOCK(pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER);
+ AssertReturnStmt(pRange->GCPhys == GCPhysStart, IOM_UNLOCK(pVM), VERR_IOM_INVALID_MMIO_RANGE);
+ AssertReturnStmt(pRange->cb == cbRange, IOM_UNLOCK(pVM), VERR_IOM_INVALID_MMIO_RANGE);
pRange->pvUserRC = pvUser;
pRange->pfnReadCallbackRC = pfnReadCallback;
pRange->pfnWriteCallbackRC= pfnWriteCallback;
pRange->pfnFillCallbackRC = pfnFillCallback;
pRange->pDevInsRC = MMHyperCCToRC(pVM, pDevIns);
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
@@ -1572,12 +1576,13 @@ VMMR3DECL(int) IOMR3MMIORegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
* @param pfnReadCallback Pointer to function which is gonna handle Read operations.
* @param pfnFillCallback Pointer to function which is gonna handle Fill/memset operations.
*/
-VMMR3DECL(int) IOMR3MMIORegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,
- R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback,
- R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
- R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback)
+VMMR3_INT_DECL(int)
+IOMR3MmioRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,
+ R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback,
+ R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
+ R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback)
{
- LogFlow(("IOMR3MMIORegisterR0: pDevIns=%p GCPhysStart=%RGp cbRange=%#x pvUser=%RHv pfnWriteCallback=%#x pfnReadCallback=%#x pfnFillCallback=%#x\n",
+ LogFlow(("IOMR3MmioRegisterR0: pDevIns=%p GCPhysStart=%RGp cbRange=%#x pvUser=%RHv pfnWriteCallback=%#x pfnReadCallback=%#x pfnFillCallback=%#x\n",
pDevIns, GCPhysStart, cbRange, pvUser, pfnWriteCallback, pfnReadCallback, pfnFillCallback));
/*
@@ -1592,19 +1597,19 @@ VMMR3DECL(int) IOMR3MMIORegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
/*
* Find the MMIO range and check that the input matches.
*/
- iomLock(pVM);
- PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhysStart);
- AssertReturnStmt(pRange, iomUnlock(pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND);
- AssertReturnStmt(pRange->pDevInsR3 == pDevIns, iomUnlock(pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER);
- AssertReturnStmt(pRange->GCPhys == GCPhysStart, iomUnlock(pVM), VERR_IOM_INVALID_MMIO_RANGE);
- AssertReturnStmt(pRange->cb == cbRange, iomUnlock(pVM), VERR_IOM_INVALID_MMIO_RANGE);
+ IOM_LOCK(pVM);
+ PIOMMMIORANGE pRange = iomMmioGetRange(pVM, GCPhysStart);
+ AssertReturnStmt(pRange, IOM_UNLOCK(pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND);
+ AssertReturnStmt(pRange->pDevInsR3 == pDevIns, IOM_UNLOCK(pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER);
+ AssertReturnStmt(pRange->GCPhys == GCPhysStart, IOM_UNLOCK(pVM), VERR_IOM_INVALID_MMIO_RANGE);
+ AssertReturnStmt(pRange->cb == cbRange, IOM_UNLOCK(pVM), VERR_IOM_INVALID_MMIO_RANGE);
pRange->pvUserR0 = pvUser;
pRange->pfnReadCallbackR0 = pfnReadCallback;
pRange->pfnWriteCallbackR0= pfnWriteCallback;
pRange->pfnFillCallbackR0 = pfnFillCallback;
pRange->pDevInsR0 = MMHyperCCToR0(pVM, pDevIns);
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
@@ -1625,9 +1630,9 @@ VMMR3DECL(int) IOMR3MMIORegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
* @remark This function mainly for PCI PnP Config and will not do
* all the checks you might expect it to do.
*/
-VMMR3DECL(int) IOMR3MMIODeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
+VMMR3_INT_DECL(int) IOMR3MmioDeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
{
- LogFlow(("IOMR3MMIODeregister: pDevIns=%p GCPhysStart=%RGp cbRange=%#x\n", pDevIns, GCPhysStart, cbRange));
+ LogFlow(("IOMR3MmioDeregister: pDevIns=%p GCPhysStart=%RGp cbRange=%#x\n", pDevIns, GCPhysStart, cbRange));
/*
* Validate input.
@@ -1639,7 +1644,7 @@ VMMR3DECL(int) IOMR3MMIODeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
return VERR_IOM_INVALID_MMIO_RANGE;
}
- iomLock(pVM);
+ IOM_LOCK(pVM);
/*
* Check ownership and such for the entire area.
@@ -1647,19 +1652,19 @@ VMMR3DECL(int) IOMR3MMIODeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
RTGCPHYS GCPhys = GCPhysStart;
while (GCPhys <= GCPhysLast && GCPhys >= GCPhysStart)
{
- PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhys);
+ PIOMMMIORANGE pRange = iomMmioGetRange(pVM, GCPhys);
if (!pRange)
{
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VERR_IOM_MMIO_RANGE_NOT_FOUND;
}
AssertMsgReturnStmt(pRange->pDevInsR3 == pDevIns,
("Not owner! GCPhys=%RGp %RGp LB%#x %s\n", GCPhys, GCPhysStart, cbRange, pRange->pszDesc),
- iomUnlock(pVM),
+ IOM_UNLOCK(pVM),
VERR_IOM_NOT_MMIO_RANGE_OWNER);
AssertMsgReturnStmt(pRange->Core.KeyLast <= GCPhysLast,
("Incomplete R3 range! GCPhys=%RGp %RGp LB%#x %s\n", GCPhys, GCPhysStart, cbRange, pRange->pszDesc),
- iomUnlock(pVM),
+ IOM_UNLOCK(pVM),
VERR_IOM_INCOMPLETE_MMIO_RANGE);
/* next */
@@ -1678,39 +1683,30 @@ VMMR3DECL(int) IOMR3MMIODeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
PIOMMMIORANGE pRange = (PIOMMMIORANGE)RTAvlroGCPhysRemove(&pVM->iom.s.pTreesR3->MMIOTree, GCPhys);
Assert(pRange);
Assert(pRange->Core.Key == GCPhys && pRange->Core.KeyLast <= GCPhysLast);
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM); /** @todo r=bird: Why are we leaving the lock here? We don't leave it when registering the range above... */
/* remove it from PGM */
int rc = PGMR3PhysMMIODeregister(pVM, GCPhys, pRange->cb);
AssertRC(rc);
- iomLock(pVM);
+ IOM_LOCK(pVM);
/* advance and free. */
GCPhys = pRange->Core.KeyLast + 1;
if (pDevIns->iInstance > 0)
- MMR3HeapFree((void *)pRange->pszDesc);
- MMHyperFree(pVM, pRange);
+ {
+ void *pvDesc = ASMAtomicXchgPtr((void * volatile *)&pRange->pszDesc, NULL);
+ MMR3HeapFree(pvDesc);
+ }
+ iomMmioReleaseRange(pVM, pRange);
}
- iomUnlock(pVM);
+ IOM_UNLOCK(pVM);
return VINF_SUCCESS;
}
/**
- * For TM only!
- *
- * @returns Pointer to the critical section.
- * @param pVM The VM handle.
- */
-VMMR3DECL(PPDMCRITSECT) IOMR3GetCritSect(PVM pVM)
-{
- return &pVM->iom.s.EmtLock;
-}
-
-
-/**
* Display a single MMIO range.
*
* @returns 0
diff --git a/src/VBox/VMM/VMMR3/MM.cpp b/src/VBox/VMM/VMMR3/MM.cpp
index b33e79581..a05035116 100644
--- a/src/VBox/VMM/VMMR3/MM.cpp
+++ b/src/VBox/VMM/VMMR3/MM.cpp
@@ -1,4 +1,4 @@
-/* $Id: MM.cpp $ */
+/* $Id: MM.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* MM - Memory Manager.
*/
diff --git a/src/VBox/VMM/VMMR3/MMHeap.cpp b/src/VBox/VMM/VMMR3/MMHeap.cpp
index 1162b0c51..69e18acd1 100644
--- a/src/VBox/VMM/VMMR3/MMHeap.cpp
+++ b/src/VBox/VMM/VMMR3/MMHeap.cpp
@@ -1,4 +1,4 @@
-/* $Id: MMHeap.cpp $ */
+/* $Id: MMHeap.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* MM - Memory Manager - Heap.
*/
diff --git a/src/VBox/VMM/VMMR3/MMHyper.cpp b/src/VBox/VMM/VMMR3/MMHyper.cpp
index 00c2002ad..989036c2a 100644
--- a/src/VBox/VMM/VMMR3/MMHyper.cpp
+++ b/src/VBox/VMM/VMMR3/MMHyper.cpp
@@ -1,4 +1,4 @@
-/* $Id: MMHyper.cpp $ */
+/* $Id: MMHyper.cpp 36960 2011-05-04 16:08:29Z vboxsync $ */
/** @file
* MM - Memory Manager - Hypervisor Memory Area.
*/
@@ -44,32 +44,56 @@ static int mmR3HyperHeapMap(PVM pVM, PMMHYPERHEAP pHeap, PRTGCPTR ppHeapGC);
static DECLCALLBACK(void) mmR3HyperInfoHma(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
-DECLINLINE(uint32_t) mmR3ComputeHyperHeapSize(PVM pVM, bool fCanUseLargerHeap)
+/**
+ * Determin the default heap size.
+ *
+ * @returns The heap size in bytes.
+ * @param pVM The VM handle.
+ */
+static uint32_t mmR3ComputeHyperHeapSize(PVM pVM)
{
- bool fHwVirtExtForced = VMMIsHwVirtExtForced(pVM);
+ /*
+ * Gather parameters.
+ */
+ bool const fHwVirtExtForced = VMMIsHwVirtExtForced(pVM)
+ || pVM->cCpus > 1;
+
+ bool fCanUseLargerHeap;
+ int rc = CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "MM"), "CanUseLargerHeap", &fCanUseLargerHeap, false);
+ AssertStmt(RT_SUCCESS(rc), fCanUseLargerHeap = false);
+
+ uint64_t cbRam;
+ rc = CFGMR3QueryU64(CFGMR3GetRoot(pVM), "RamSize", &cbRam);
+ AssertStmt(RT_SUCCESS(rc), cbRam = _1G);
+
+ /*
+ * We need to keep saved state compatibility if raw-mode is an option,
+ * so lets filter out that case first.
+ */
+ if ( !fCanUseLargerHeap
+ && !fHwVirtExtForced
+ && cbRam < 16*_1G64)
+ return 1280 * _1K;
+
+ /*
+ * Calculate the heap size.
+ */
+ uint32_t cbHeap = _1M;
- /* Newer chipset allows for much more devices, putting additional pressure on hyperheap */
- /* @todo: maybe base hyperheap size upon number of devices attached too */
+ /* The newer chipset may have more devices attached, putting additional
+ pressure on the heap. */
if (fCanUseLargerHeap)
- return _2M + pVM->cCpus * 2 * _64K;
+ cbHeap += _1M;
+ /* More CPUs means some extra memory usage. */
if (pVM->cCpus > 1)
- return _1M + pVM->cCpus * 2 * _64K;
+ cbHeap += pVM->cCpus * _64K;
- if (fHwVirtExtForced)
- {
- uint64_t cbRam = 0;
- CFGMR3QueryU64(CFGMR3GetRoot(pVM), "RamSize", &cbRam);
-
- /* Need a bit more space for large memory guests. (@todo: only for shadow paging!) */
- if (cbRam >= _4G)
- return _1M;
- else
- return 640 * _1K;
- }
- else
- /* Size must be kept like this for saved state compatibility (only for raw mode though). */
- return 1280*_1K;
+ /* Lots of memory means extra memory consumption as well (pool). */
+ if (cbRam > 16*_1G64)
+ cbHeap += _2M; /** @todo figure out extactly how much */
+
+ return RT_ALIGN(cbHeap, _256K);
}
@@ -100,10 +124,8 @@ int mmR3HyperInit(PVM pVM)
* precious kernel space on heap for the PATM.
*/
PCFGMNODE pMM = CFGMR3GetChild(CFGMR3GetRoot(pVM), "MM");
- bool fCanUseLargerHeap = false;
- int rc = CFGMR3QueryBoolDef(pMM, "CanUseLargerHeap", &fCanUseLargerHeap, false);
- uint32_t cbHyperHeap = mmR3ComputeHyperHeapSize(pVM, fCanUseLargerHeap);
- rc = CFGMR3QueryU32Def(pMM, "cbHyperHeap", &cbHyperHeap, cbHyperHeap);
+ uint32_t cbHyperHeap;
+ int rc = CFGMR3QueryU32Def(pMM, "cbHyperHeap", &cbHyperHeap, mmR3ComputeHyperHeapSize(pVM));
AssertLogRelRCReturn(rc, rc);
cbHyperHeap = RT_ALIGN_32(cbHyperHeap, PAGE_SIZE);
diff --git a/src/VBox/VMM/VMMR3/MMPagePool.cpp b/src/VBox/VMM/VMMR3/MMPagePool.cpp
index 85e8213ae..0636ce985 100644
--- a/src/VBox/VMM/VMMR3/MMPagePool.cpp
+++ b/src/VBox/VMM/VMMR3/MMPagePool.cpp
@@ -1,4 +1,4 @@
-/* $Id: MMPagePool.cpp $ */
+/* $Id: MMPagePool.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* MM - Memory Manager - Page Pool.
*/
diff --git a/src/VBox/VMM/VMMR3/MMUkHeap.cpp b/src/VBox/VMM/VMMR3/MMUkHeap.cpp
index 0b8761fc8..6f49232ee 100644
--- a/src/VBox/VMM/VMMR3/MMUkHeap.cpp
+++ b/src/VBox/VMM/VMMR3/MMUkHeap.cpp
@@ -1,4 +1,4 @@
-/* $Id: MMUkHeap.cpp $ */
+/* $Id: MMUkHeap.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* MM - Memory Manager - Ring-3 Heap with kernel accessible mapping.
*/
diff --git a/src/VBox/VMM/VMMR3/PATM.cpp b/src/VBox/VMM/VMMR3/PATM.cpp
index 5e01c244e..5198089b4 100644
--- a/src/VBox/VMM/VMMR3/PATM.cpp
+++ b/src/VBox/VMM/VMMR3/PATM.cpp
@@ -1,4 +1,4 @@
-/* $Id: PATM.cpp $ */
+/* $Id: PATM.cpp 36969 2011-05-05 08:59:43Z vboxsync $ */
/** @file
* PATM - Dynamic Guest OS Patching Manager
*
@@ -93,15 +93,15 @@ static DECLCALLBACK(int) RelocatePatches(PAVLOU32NODECORE pNode, void *pParam);
#ifdef VBOX_WITH_DEBUGGER
static DECLCALLBACK(int) DisableAllPatches(PAVLOU32NODECORE pNode, void *pVM);
-static DECLCALLBACK(int) patmr3CmdOn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) patmr3CmdOff(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
+static DECLCALLBACK(int) patmr3CmdOn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) patmr3CmdOff(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
/** Command descriptors. */
static const DBGCCMD g_aCmds[] =
{
- /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, pResultDesc, fFlags, pfnHandler pszSyntax, ....pszDescription */
- { "patmon", 0, 0, NULL, 0, NULL, 0, patmr3CmdOn, "", "Enable patching." },
- { "patmoff", 0, 0, NULL, 0, NULL, 0, patmr3CmdOff, "", "Disable patching." },
+ /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, fFlags, pfnHandler pszSyntax, ....pszDescription */
+ { "patmon", 0, 0, NULL, 0, 0, patmr3CmdOn, "", "Enable patching." },
+ { "patmoff", 0, 0, NULL, 0, 0, patmr3CmdOff, "", "Disable patching." },
};
#endif
@@ -1306,14 +1306,16 @@ static int patmAnalyseBlockCallback(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_
PPATCHINFO pPatch = (PPATCHINFO)pCacheRec->pPatch;
bool fIllegalInstr = false;
- //Preliminary heuristics:
- //- no call instructions without a fixed displacement between cli and sti/popf
- //- no jumps in the instructions following cli (4+ bytes; enough for the replacement jump (5 bytes))
- //- no nested pushf/cli
- //- sti/popf should be the (eventual) target of all branches
- //- no near or far returns; no int xx, no into
- //
- // Note: Later on we can impose less stricter guidelines if the need arises
+ /*
+ * Preliminary heuristics:
+ *- no call instructions without a fixed displacement between cli and sti/popf
+ *- no jumps in the instructions following cli (4+ bytes; enough for the replacement jump (5 bytes))
+ *- no nested pushf/cli
+ *- sti/popf should be the (eventual) target of all branches
+ *- no near or far returns; no int xx, no into
+ *
+ * Note: Later on we can impose less stricter guidelines if the need arises
+ */
/* Bail out if the patch gets too big. */
if (pPatch->cbPatchBlockSize >= MAX_PATCH_SIZE)
@@ -1343,7 +1345,8 @@ static int patmAnalyseBlockCallback(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_
/* An unconditional (short) jump right after a cli is a potential problem; we will overwrite whichever function comes afterwards */
if (pPatch->opcode == OP_CLI && pCpu->pCurInstr->opcode == OP_JMP)
{
- if (pCurInstrGC > pPatch->pPrivInstrGC && pCurInstrGC + pCpu->opsize < pPatch->pPrivInstrGC + SIZEOF_NEARJUMP32) /* hardcoded patch jump size; cbPatchJump is still zero */
+ if ( pCurInstrGC > pPatch->pPrivInstrGC
+ && pCurInstrGC + pCpu->opsize < pPatch->pPrivInstrGC + SIZEOF_NEARJUMP32) /* hardcoded patch jump size; cbPatchJump is still zero */
{
Log(("Dangerous unconditional jump ends in our generated patch jump!! (%x vs %x)\n", pCurInstrGC, pPatch->pPrivInstrGC));
/* We turn this one into a int 3 callable patch. */
@@ -1361,17 +1364,18 @@ static int patmAnalyseBlockCallback(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_
}
}
- // no far returns
+ /* no far returns */
if (pCpu->pCurInstr->opcode == OP_RETF)
{
pPatch->pTempInfo->nrRetInstr++;
fIllegalInstr = true;
patmAddIllegalInstrRecord(pVM, pPatch, pCurInstrGC);
}
- else
- // no int xx or into either
- if (pCpu->pCurInstr->opcode == OP_INT3 || pCpu->pCurInstr->opcode == OP_INT || pCpu->pCurInstr->opcode == OP_INTO)
+ else if ( pCpu->pCurInstr->opcode == OP_INT3
+ || pCpu->pCurInstr->opcode == OP_INT
+ || pCpu->pCurInstr->opcode == OP_INTO)
{
+ /* No int xx or into either. */
fIllegalInstr = true;
patmAddIllegalInstrRecord(pVM, pPatch, pCurInstrGC);
}
@@ -1391,7 +1395,7 @@ static int patmAnalyseBlockCallback(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_
case OP_SYSENTER:
case OP_ILLUD2:
- //This appears to be some kind of kernel panic in Linux 2.4; no point to analyse more
+ /* This appears to be some kind of kernel panic in Linux 2.4; no point to analyse more. */
Log(("Illegal opcode (0xf 0xb) -> return here\n"));
return VINF_SUCCESS;
@@ -1415,9 +1419,9 @@ static int patmAnalyseBlockCallback(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_
Log(("WARNING: End of block reached, but we need to duplicate some extra instruction to avoid a conflict with the patch jump\n"));
pPatch->flags |= PATMFL_CHECK_SIZE;
}
- break; //sti doesn't mark the end of a pushf block; only popf does
+ break; /* sti doesn't mark the end of a pushf block; only popf does. */
}
- //else no break
+ /* else: fall through. */
case OP_RETN: /* exit point for function replacement */
return VINF_SUCCESS;
@@ -1438,10 +1442,10 @@ static int patmAnalyseBlockCallback(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_
break;
}
- // If single instruction patch, we've copied enough instructions *and* the current instruction is not a relative jump
+ /* If single instruction patch, we've copied enough instructions *and* the current instruction is not a relative jump. */
if ((pPatch->flags & PATMFL_CHECK_SIZE) && pPatch->cbPatchBlockSize > SIZEOF_NEARJUMP32 && !(pCpu->pCurInstr->optype & OPTYPE_RELATIVE_CONTROLFLOW))
{
- // The end marker for this kind of patch is any instruction at a location outside our patch jump
+ /* The end marker for this kind of patch is any instruction at a location outside our patch jump. */
Log(("End of block at %RRv size %d\n", pCurInstrGC, pCpu->opsize));
return VINF_SUCCESS;
}
@@ -2666,6 +2670,7 @@ VMMR3DECL(int) PATMR3PatchBlock(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *)
DISCPUSTATE cpu;
uint32_t orgOffsetPatchMem = ~0;
RTRCPTR pInstrStart;
+ bool fInserted;
#ifdef LOG_ENABLED
uint32_t opsize;
char szOutput[256];
@@ -2786,9 +2791,9 @@ VMMR3DECL(int) PATMR3PatchBlock(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *)
*/
LogFlow(("Insert %RRv patch offset %RRv\n", pPatchRec->patch.pPrivInstrGC, pPatch->pPatchBlockOffset));
pPatchRec->CoreOffset.Key = pPatch->pPatchBlockOffset;
- rc = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
- AssertMsg(rc, ("RTAvlULInsert failed for %x\n", pPatchRec->CoreOffset.Key));
- if (!rc)
+ fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
+ AssertMsg(fInserted, ("RTAvlULInsert failed for %x\n", pPatchRec->CoreOffset.Key));
+ if (!fInserted)
{
rc = VERR_PATCHING_REFUSED;
goto failure;
@@ -2933,6 +2938,7 @@ static int patmIdtHandler(PVM pVM, RTRCPTR pInstrGC, uint32_t uOpSize, PPATMPATC
&& (pJmpInstrGC = PATMResolveBranch(&cpuJmp, pCurInstrGC))
)
{
+ bool fInserted;
PPATMPATCHREC pJmpPatch = (PPATMPATCHREC)RTAvloU32Get(&pVM->patm.s.PatchLookupTreeHC->PatchTree, pJmpInstrGC);
if (pJmpPatch == 0)
{
@@ -3001,8 +3007,8 @@ static int patmIdtHandler(PVM pVM, RTRCPTR pInstrGC, uint32_t uOpSize, PPATMPATC
*/
LogFlow(("Insert %RRv patch offset %RRv\n", pPatchRec->patch.pPrivInstrGC, pPatch->pPatchBlockOffset));
pPatchRec->CoreOffset.Key = pPatch->pPatchBlockOffset;
- rc = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
- AssertMsg(rc, ("RTAvlULInsert failed for %x\n", pPatchRec->CoreOffset.Key));
+ fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
+ AssertMsg(fInserted, ("RTAvlULInsert failed for %x\n", pPatchRec->CoreOffset.Key));
pPatch->uState = PATCH_ENABLED;
@@ -3032,6 +3038,7 @@ static int patmInstallTrapTrampoline(PVM pVM, RTRCPTR pInstrGC, PPATMPATCHREC pP
PPATCHINFO pPatch = &pPatchRec->patch;
int rc = VERR_PATCHING_REFUSED;
uint32_t orgOffsetPatchMem = ~0;
+ bool fInserted;
#ifdef LOG_ENABLED
bool disret;
DISCPUSTATE cpu;
@@ -3085,8 +3092,8 @@ static int patmInstallTrapTrampoline(PVM pVM, RTRCPTR pInstrGC, PPATMPATCHREC pP
*/
LogFlow(("Insert %RRv patch offset %RRv\n", pPatchRec->patch.pPrivInstrGC, pPatch->pPatchBlockOffset));
pPatchRec->CoreOffset.Key = pPatch->pPatchBlockOffset;
- rc = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
- AssertMsg(rc, ("RTAvlULInsert failed for %x\n", pPatchRec->CoreOffset.Key));
+ fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
+ AssertMsg(fInserted, ("RTAvlULInsert failed for %x\n", pPatchRec->CoreOffset.Key));
pPatch->uState = PATCH_ENABLED;
return VINF_SUCCESS;
@@ -3143,6 +3150,7 @@ static int patmDuplicateFunction(PVM pVM, RTRCPTR pInstrGC, PPATMPATCHREC pPatch
int rc = VERR_PATCHING_REFUSED;
DISCPUSTATE cpu;
uint32_t orgOffsetPatchMem = ~0;
+ bool fInserted;
Log(("patmDuplicateFunction %RRv\n", pInstrGC));
/* Save original offset (in case of failures later on). */
@@ -3202,9 +3210,9 @@ static int patmDuplicateFunction(PVM pVM, RTRCPTR pInstrGC, PPATMPATCHREC pPatch
*/
LogFlow(("Insert %RRv patch offset %RRv\n", pPatchRec->patch.pPrivInstrGC, pPatch->pPatchBlockOffset));
pPatchRec->CoreOffset.Key = pPatch->pPatchBlockOffset;
- rc = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
- AssertMsg(rc, ("RTAvloU32Insert failed for %x\n", pPatchRec->CoreOffset.Key));
- if (!rc)
+ fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
+ AssertMsg(fInserted, ("RTAvloU32Insert failed for %x\n", pPatchRec->CoreOffset.Key));
+ if (!fInserted)
{
rc = VERR_PATCHING_REFUSED;
goto failure;
@@ -4186,6 +4194,7 @@ VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags)
}
/* Initialize cache record for guest address translations. */
+ bool fInserted;
PATMP2GLOOKUPREC cacheRec;
RT_ZERO(cacheRec);
@@ -4202,8 +4211,8 @@ VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags)
pPatchRec->Core.Key = pInstrGC;
pPatchRec->patch.uState = PATCH_REFUSED; /* default value */
/* Insert patch record into the lookup tree. */
- rc = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pPatchRec->Core);
- Assert(rc);
+ fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pPatchRec->Core);
+ Assert(fInserted);
pPatchRec->patch.pPrivInstrGC = pInstrGC;
pPatchRec->patch.flags = flags;
@@ -4543,6 +4552,8 @@ int patmAddPatchToPage(PVM pVM, RTRCUINTPTR pPage, PPATCHINFO pPatch)
}
else
{
+ bool fInserted;
+
rc = MMHyperAlloc(pVM, sizeof(PATMPATCHPAGE), 0, MM_TAG_PATM_PATCH, (void **)&pPatchPage);
if (RT_FAILURE(rc))
{
@@ -4562,8 +4573,8 @@ int patmAddPatchToPage(PVM pVM, RTRCUINTPTR pPage, PPATCHINFO pPatch)
}
pPatchPage->aPatch[0] = pPatch;
- rc = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPage, &pPatchPage->Core);
- Assert(rc);
+ fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPage, &pPatchPage->Core);
+ Assert(fInserted);
pVM->patm.s.cPageRecords++;
STAM_COUNTER_INC(&pVM->patm.s.StatPatchPageInserted);
@@ -5613,7 +5624,8 @@ int patmR3RefreshPatch(PVM pVM, PPATMPATCHREC pPatchRec)
AssertRC(rc2);
/* Put the new patch back into the tree, because removing the old one kicked this one out. (hack alert) */
- RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pNewPatchRec->Core);
+ bool fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pNewPatchRec->Core);
+ Assert(fInserted);
LogRel(("PATM: patmR3RefreshPatch: succeeded to refresh patch at %RRv \n", pInstrGC));
STAM_COUNTER_INC(&pVM->patm.s.StatPatchRefreshSuccess);
@@ -5664,7 +5676,8 @@ failure:
AssertRC(rc);
/* Put the old patch back into the tree (or else it won't be saved) (hack alert) */
- RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pPatchRec->Core);
+ bool fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pPatchRec->Core);
+ Assert(fInserted);
/* Enable again in case the dirty instruction is near the end and there are safe code paths. */
int rc2 = PATMR3EnablePatch(pVM, pInstrGC);
@@ -6662,7 +6675,7 @@ RTRCPTR patmPatchQueryStatAddress(PVM pVM, PPATCHINFO pPatch)
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) patmr3CmdOff(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) patmr3CmdOff(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate input.
@@ -6685,7 +6698,7 @@ static DECLCALLBACK(int) patmr3CmdOff(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM p
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) patmr3CmdOn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) patmr3CmdOn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate input.
diff --git a/src/VBox/VMM/VMMR3/PATMA.asm b/src/VBox/VMM/VMMR3/PATMA.asm
index d3403bed9..5e30f67d0 100644
--- a/src/VBox/VMM/VMMR3/PATMA.asm
+++ b/src/VBox/VMM/VMMR3/PATMA.asm
@@ -1,4 +1,4 @@
-; $Id: PATMA.asm $
+; $Id: PATMA.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; PATM Assembly Routines.
;
@@ -30,7 +30,7 @@
;*******************************************************************************
%include "VBox/asmdefs.mac"
%include "VBox/err.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "VBox/vmm/vm.mac"
%include "PATMA.mac"
@@ -74,7 +74,7 @@ GLOBALNAME PATMStatsRecord
DD 0
DD PATM_ALLPATCHCALLS
DD 0
- DD PATM_PERPATCHCALLS
+ DD PATM_PERPATCHCALLS
DD 0
DD PATM_INTERRUPTFLAG
DD 0
@@ -123,7 +123,7 @@ GLOBALNAME PATMClearPIFRecord
DD 0
DD 0
DD PATMClearPIF_End - PATMClearPIF_Start
- DD 1
+ DD 1
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
@@ -137,8 +137,8 @@ PATMClearInhibitIRQFaultIF0_Start:
mov dword [ss:PATM_INHIBITIRQADDR], 0
pushf
- test dword [ss:PATM_VMFLAGS], X86_EFL_IF
- jz PATMClearInhibitIRQFaultIF0_Fault
+ test dword [ss:PATM_VMFLAGS], X86_EFL_IF
+ jz PATMClearInhibitIRQFaultIF0_Fault
; if interrupts are pending, then we must go back to the host context to handle them!
test dword [ss:PATM_VM_FORCEDACTIONS], VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_TIMER | VMCPU_FF_REQUEST
@@ -176,7 +176,7 @@ GLOBALNAME PATMClearInhibitIRQFaultIF0Record
DD 0
DD 0
DD PATMClearInhibitIRQFaultIF0_End - PATMClearInhibitIRQFaultIF0_Start
- DD 12
+ DD 12
DD PATM_INTERRUPTFLAG
DD 0
DD PATM_INHIBITIRQADDR
@@ -212,8 +212,8 @@ PATMClearInhibitIRQContIF0_Start:
mov dword [ss:PATM_INHIBITIRQADDR], 0
pushf
- test dword [ss:PATM_VMFLAGS], X86_EFL_IF
- jz PATMClearInhibitIRQContIF0_Continue
+ test dword [ss:PATM_VMFLAGS], X86_EFL_IF
+ jz PATMClearInhibitIRQContIF0_Continue
; if interrupts are pending, then we must go back to the host context to handle them!
test dword [ss:PATM_VM_FORCEDACTIONS], VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_TIMER | VMCPU_FF_REQUEST
@@ -246,7 +246,7 @@ GLOBALNAME PATMClearInhibitIRQContIF0Record
DD 0
DD 0
DD PATMClearInhibitIRQContIF0_End - PATMClearInhibitIRQContIF0_Start
- DD 11
+ DD 11
DD PATM_INTERRUPTFLAG
DD 0
DD PATM_INHIBITIRQADDR
@@ -415,13 +415,13 @@ PATMTrapEntryStart:
and dword [esp+8], dword ~1 ; yasm / nasm dword
PATMTrapNoRing1:
- ; correct EFLAGS on the stack to include the current IOPL
- push eax
- mov eax, dword [ss:PATM_VMFLAGS]
- and eax, X86_EFL_IOPL
- and dword [esp+16], ~X86_EFL_IOPL ; esp+16 = eflags = esp+8+4(efl)+4(eax)
- or dword [esp+16], eax
- pop eax
+ ; correct EFLAGS on the stack to include the current IOPL
+ push eax
+ mov eax, dword [ss:PATM_VMFLAGS]
+ and eax, X86_EFL_IOPL
+ and dword [esp+16], ~X86_EFL_IOPL ; esp+16 = eflags = esp+8+4(efl)+4(eax)
+ or dword [esp+16], eax
+ pop eax
popf
mov dword [ss:PATM_INTERRUPTFLAG], 1
@@ -500,13 +500,13 @@ PATMTrapErrorCodeEntryStart:
and dword [esp+12], dword ~1 ; yasm / nasm dword
PATMTrapErrorCodeNoRing1:
- ; correct EFLAGS on the stack to include the current IOPL
- push eax
- mov eax, dword [ss:PATM_VMFLAGS]
- and eax, X86_EFL_IOPL
- and dword [esp+20], ~X86_EFL_IOPL ; esp+20 = eflags = esp+8+4(efl)+4(error code)+4(eax)
- or dword [esp+20], eax
- pop eax
+ ; correct EFLAGS on the stack to include the current IOPL
+ push eax
+ mov eax, dword [ss:PATM_VMFLAGS]
+ and eax, X86_EFL_IOPL
+ and dword [esp+20], ~X86_EFL_IOPL ; esp+20 = eflags = esp+8+4(efl)+4(error code)+4(eax)
+ or dword [esp+20], eax
+ pop eax
popf
mov dword [ss:PATM_INTERRUPTFLAG], 1
@@ -585,13 +585,13 @@ PATMIntEntryStart:
and dword [esp+8], dword ~1 ; yasm / nasm dword
PATMIntNoRing1:
- ; correct EFLAGS on the stack to include the current IOPL
- push eax
- mov eax, dword [ss:PATM_VMFLAGS]
- and eax, X86_EFL_IOPL
- and dword [esp+16], ~X86_EFL_IOPL ; esp+16 = eflags = esp+8+4(efl)+4(eax)
- or dword [esp+16], eax
- pop eax
+ ; correct EFLAGS on the stack to include the current IOPL
+ push eax
+ mov eax, dword [ss:PATM_VMFLAGS]
+ and eax, X86_EFL_IOPL
+ and dword [esp+16], ~X86_EFL_IOPL ; esp+16 = eflags = esp+8+4(efl)+4(eax)
+ or dword [esp+16], eax
+ pop eax
popf
mov dword [ss:PATM_INTERRUPTFLAG], 1
@@ -667,13 +667,13 @@ PATMIntEntryErrorCodeStart:
and dword [esp+12], dword ~1 ; yasm / nasm dword
PATMIntNoRing1_ErrorCode:
- ; correct EFLAGS on the stack to include the current IOPL
- push eax
- mov eax, dword [ss:PATM_VMFLAGS]
- and eax, X86_EFL_IOPL
- and dword [esp+20], ~X86_EFL_IOPL ; esp+20 = eflags = esp+8+4(efl)+4(eax)+4(error code)
- or dword [esp+20], eax
- pop eax
+ ; correct EFLAGS on the stack to include the current IOPL
+ push eax
+ mov eax, dword [ss:PATM_VMFLAGS]
+ and eax, X86_EFL_IOPL
+ and dword [esp+20], ~X86_EFL_IOPL ; esp+20 = eflags = esp+8+4(efl)+4(eax)+4(error code)
+ or dword [esp+20], eax
+ pop eax
popf
mov dword [ss:PATM_INTERRUPTFLAG], 1
@@ -1251,17 +1251,17 @@ iret_notring0:
; does not return
iret_continue :
- ; This section must *always* be executed (!!)
- ; Extract the IOPL from the return flags, save them to our virtual flags and
- ; put them back to zero
+ ; This section must *always* be executed (!!)
+ ; Extract the IOPL from the return flags, save them to our virtual flags and
+ ; put them back to zero
; @note we assume iretd doesn't fault!!!
- push eax
- mov eax, dword [esp+16]
- and eax, X86_EFL_IOPL
- and dword [ss:PATM_VMFLAGS], ~X86_EFL_IOPL
- or dword [ss:PATM_VMFLAGS], eax
- pop eax
- and dword [esp+12], ~X86_EFL_IOPL
+ push eax
+ mov eax, dword [esp+16]
+ and eax, X86_EFL_IOPL
+ and dword [ss:PATM_VMFLAGS], ~X86_EFL_IOPL
+ or dword [ss:PATM_VMFLAGS], eax
+ pop eax
+ and dword [esp+12], ~X86_EFL_IOPL
; Set IF again; below we make sure this won't cause problems.
or dword [ss:PATM_VMFLAGS], X86_EFL_IF
@@ -1305,16 +1305,16 @@ iret_clearIF:
; always ring 0 return -> change to ring 1 (CS in iret frame)
or dword [esp+8], 1
- ; This section must *always* be executed (!!)
- ; Extract the IOPL from the return flags, save them to our virtual flags and
- ; put them back to zero
- push eax
- mov eax, dword [esp+16]
- and eax, X86_EFL_IOPL
- and dword [ss:PATM_VMFLAGS], ~X86_EFL_IOPL
- or dword [ss:PATM_VMFLAGS], eax
- pop eax
- and dword [esp+12], ~X86_EFL_IOPL
+ ; This section must *always* be executed (!!)
+ ; Extract the IOPL from the return flags, save them to our virtual flags and
+ ; put them back to zero
+ push eax
+ mov eax, dword [esp+16]
+ and eax, X86_EFL_IOPL
+ and dword [ss:PATM_VMFLAGS], ~X86_EFL_IOPL
+ or dword [ss:PATM_VMFLAGS], eax
+ pop eax
+ and dword [esp+12], ~X86_EFL_IOPL
; Clear IF
and dword [ss:PATM_VMFLAGS], ~X86_EFL_IF
@@ -2441,14 +2441,14 @@ BEGINPROC PATMCheckIF
PATMCheckIF_Start:
mov dword [ss:PATM_INTERRUPTFLAG], 0
pushf
- test dword [ss:PATM_VMFLAGS], X86_EFL_IF
- jnz PATMCheckIF_Safe
- nop
+ test dword [ss:PATM_VMFLAGS], X86_EFL_IF
+ jnz PATMCheckIF_Safe
+ nop
- ; IF=0 -> unsafe, so we must call the duplicated function (which we don't do here)
- popf
+ ; IF=0 -> unsafe, so we must call the duplicated function (which we don't do here)
+ popf
mov dword [ss:PATM_INTERRUPTFLAG], 1
- jmp PATMCheckIF_End
+ jmp PATMCheckIF_End
PATMCheckIF_Safe:
; invalidate the PATM stack as we'll jump back to guest code
@@ -2464,9 +2464,9 @@ PATMCheckIF_Safe:
pop ecx
pop eax
%endif
- popf
+ popf
mov dword [ss:PATM_INTERRUPTFLAG], 1
- ; IF=1 -> we can safely jump back to the original instruction
+ ; IF=1 -> we can safely jump back to the original instruction
DB 0xE9
PATMCheckIF_Jump:
DD PATM_JUMPDELTA
@@ -2508,18 +2508,18 @@ BEGINPROC PATMJumpToGuest_IF1
PATMJumpToGuest_IF1_Start:
mov dword [ss:PATM_INTERRUPTFLAG], 0
pushf
- test dword [ss:PATM_VMFLAGS], X86_EFL_IF
- jnz PATMJumpToGuest_IF1_Safe
- nop
+ test dword [ss:PATM_VMFLAGS], X86_EFL_IF
+ jnz PATMJumpToGuest_IF1_Safe
+ nop
- ; IF=0 -> unsafe, so fault
- popf
+ ; IF=0 -> unsafe, so fault
+ popf
mov dword [ss:PATM_INTERRUPTFLAG], 1
- PATM_INT3
+ PATM_INT3
PATMJumpToGuest_IF1_Safe:
- ; IF=1 -> we can safely jump back to the original instruction
- popf
+ ; IF=1 -> we can safely jump back to the original instruction
+ popf
mov dword [ss:PATM_INTERRUPTFLAG], 1
DB 0xE9
PATMJumpToGuest_IF1_Jump:
diff --git a/src/VBox/VMM/VMMR3/PATMA.mac b/src/VBox/VMM/VMMR3/PATMA.mac
index d6e0d3c63..46c50a4d4 100644
--- a/src/VBox/VMM/VMMR3/PATMA.mac
+++ b/src/VBox/VMM/VMMR3/PATMA.mac
@@ -1,4 +1,4 @@
-; $Id: PATMA.mac $
+; $Id: PATMA.mac 35348 2010-12-27 16:35:23Z vboxsync $
;; @file
; PATM macros & definitions (identical to PATMA.h!!)
;
diff --git a/src/VBox/VMM/VMMR3/PATMGuest.cpp b/src/VBox/VMM/VMMR3/PATMGuest.cpp
index 345a828f0..9231aa50d 100644
--- a/src/VBox/VMM/VMMR3/PATMGuest.cpp
+++ b/src/VBox/VMM/VMMR3/PATMGuest.cpp
@@ -1,4 +1,4 @@
-/* $Id: PATMGuest.cpp $ */
+/* $Id: PATMGuest.cpp 35348 2010-12-27 16:35:23Z vboxsync $ */
/** @file
* PATMGuest - Guest OS Patching Manager (non-generic)
*/
diff --git a/src/VBox/VMM/VMMR3/PATMPatch.cpp b/src/VBox/VMM/VMMR3/PATMPatch.cpp
index 3f93c1740..72e775431 100644
--- a/src/VBox/VMM/VMMR3/PATMPatch.cpp
+++ b/src/VBox/VMM/VMMR3/PATMPatch.cpp
@@ -1,4 +1,4 @@
-/* $Id: PATMPatch.cpp $ */
+/* $Id: PATMPatch.cpp 35348 2010-12-27 16:35:23Z vboxsync $ */
/** @file
* PATMPatch - Dynamic Guest OS Instruction patches
*
diff --git a/src/VBox/VMM/VMMR3/PATMPatch.h b/src/VBox/VMM/VMMR3/PATMPatch.h
index eb859ab5a..e3a2f7638 100644
--- a/src/VBox/VMM/VMMR3/PATMPatch.h
+++ b/src/VBox/VMM/VMMR3/PATMPatch.h
@@ -1,4 +1,4 @@
-/* $Id: PATMPatch.h $ */
+/* $Id: PATMPatch.h 35348 2010-12-27 16:35:23Z vboxsync $ */
/** @file
* PATMPatch - Internal header file.
*/
diff --git a/src/VBox/VMM/VMMR3/PATMSSM.cpp b/src/VBox/VMM/VMMR3/PATMSSM.cpp
index 118ac3907..844464f16 100644
--- a/src/VBox/VMM/VMMR3/PATMSSM.cpp
+++ b/src/VBox/VMM/VMMR3/PATMSSM.cpp
@@ -1,4 +1,4 @@
-/* $Id: PATMSSM.cpp $ */
+/* $Id: PATMSSM.cpp 36669 2011-04-14 12:21:43Z vboxsync $ */
/** @file
* PATMSSM - Dynamic Guest OS Patching Manager; Save and load state
*
diff --git a/src/VBox/VMM/VMMR3/PDM.cpp b/src/VBox/VMM/VMMR3/PDM.cpp
index 2b0d20e0a..f4bbd230a 100644
--- a/src/VBox/VMM/VMMR3/PDM.cpp
+++ b/src/VBox/VMM/VMMR3/PDM.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDM.cpp $ */
+/* $Id: PDM.cpp 37466 2011-06-15 12:44:16Z vboxsync $ */
/** @file
* PDM - Pluggable Device Manager.
*/
@@ -352,19 +352,29 @@ VMMR3DECL(int) PDMR3Init(PVM pVM)
AssertRelease(!(RT_OFFSETOF(VM, pdm.s) & 31));
AssertRelease(sizeof(pVM->pdm.s) <= sizeof(pVM->pdm.padding));
AssertCompileMemberAlignment(PDM, CritSect, sizeof(uintptr_t));
+
/*
* Init the structure.
*/
- pVM->pdm.s.offVM = RT_OFFSETOF(VM, pdm.s);
pVM->pdm.s.GCPhysVMMDevHeap = NIL_RTGCPHYS;
/*
- * Initialize sub components.
+ * Initialize critical sections first.
*/
int rc = pdmR3CritSectInitStats(pVM);
if (RT_SUCCESS(rc))
rc = PDMR3CritSectInit(pVM, &pVM->pdm.s.CritSect, RT_SRC_POS, "PDM");
if (RT_SUCCESS(rc))
+ {
+ rc = PDMR3CritSectInit(pVM, &pVM->pdm.s.NopCritSect, RT_SRC_POS, "NOP");
+ if (RT_SUCCESS(rc))
+ pVM->pdm.s.NopCritSect.s.Core.fFlags |= RTCRITSECT_FLAGS_NOP;
+ }
+
+ /*
+ * Initialize sub components.
+ */
+ if (RT_SUCCESS(rc))
rc = pdmR3LdrInitU(pVM->pUVM);
#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
if (RT_SUCCESS(rc))
@@ -494,8 +504,8 @@ VMMR3DECL(void) PDMR3Relocate(PVM pVM, RTGCINTPTR offDelta)
{
pDevIns->pHlpRC = pDevHlpRC;
pDevIns->pvInstanceDataRC = MMHyperR3ToRC(pVM, pDevIns->pvInstanceDataR3);
- if (pDevIns->pCritSectR3)
- pDevIns->pCritSectRC = MMHyperR3ToRC(pVM, pDevIns->pCritSectR3);
+ if (pDevIns->pCritSectRoR3)
+ pDevIns->pCritSectRoRC = MMHyperR3ToRC(pVM, pDevIns->pCritSectRoR3);
pDevIns->Internal.s.pVMRC = pVM->pVMRC;
if (pDevIns->Internal.s.pPciBusR3)
pDevIns->Internal.s.pPciBusRC = MMHyperR3ToRC(pVM, pDevIns->Internal.s.pPciBusR3);
@@ -586,7 +596,7 @@ static void pdmR3TermLuns(PVM pVM, PPDMLUN pLun, const char *pszDevice, unsigned
VMMR3DECL(int) PDMR3Term(PVM pVM)
{
LogFlow(("PDMR3Term:\n"));
- AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
+ AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
/*
* Iterate the device instances and attach drivers, doing
@@ -2086,6 +2096,7 @@ VMMR3DECL(int) PDMR3QueryLun(PVM pVM, const char *pszDevice, unsigned iInstance,
{
LogFlow(("PDMR3QueryLun: pszDevice=%p:{%s} iInstance=%u iLun=%u ppBase=%p\n",
pszDevice, pszDevice, iInstance, iLun, ppBase));
+ VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
/*
* Find the LUN.
diff --git a/src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp b/src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp
index bda55a94f..3b6960592 100644
--- a/src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp
+++ b/src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMAsyncCompletion.cpp $ */
+/* $Id: PDMAsyncCompletion.cpp 36001 2011-02-16 21:21:39Z vboxsync $ */
/** @file
* PDM Async I/O - Transport data asynchronous in R3 using EMT.
*/
@@ -1190,7 +1190,7 @@ VMMR3DECL(int) PDMR3AsyncCompletionEpCreateForFile(PPPDMASYNCCOMPLETIONENDPOINT
AssertReturn(VALID_PTR(pTemplate), VERR_INVALID_POINTER);
/* Check that the flags are valid. */
- AssertReturn(((~(PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_DONT_LOCK) & fFlags) == 0),
+ AssertReturn(((~(PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_DONT_LOCK | PDMACEP_FILE_FLAGS_HOST_CACHE_ENABLED) & fFlags) == 0),
VERR_INVALID_PARAMETER);
PVM pVM = pTemplate->pVM;
diff --git a/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp b/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp
index d18b616b8..4e8c55ccd 100644
--- a/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp
+++ b/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMAsyncCompletionFile.cpp $ */
+/* $Id: PDMAsyncCompletionFile.cpp 37597 2011-06-22 20:54:05Z vboxsync $ */
/** @file
* PDM Async I/O - Transport data asynchronous in R3 using EMT.
*/
@@ -20,6 +20,7 @@
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
+#define RT_STRICT
#include "PDMInternal.h"
#include <VBox/vmm/pdm.h>
#include <VBox/vmm/mm.h>
@@ -73,7 +74,8 @@
* Internal Functions *
*******************************************************************************/
#ifdef VBOX_WITH_DEBUGGER
-static DECLCALLBACK(int) pdmacEpFileErrorInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs, PDBGCVAR pResult);
+static DECLCALLBACK(int) pdmacEpFileErrorInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs);
+static DECLCALLBACK(int) pdmacEpFileDelayInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs);
#endif
/*******************************************************************************
@@ -85,14 +87,27 @@ static const DBGCVARDESC g_aInjectErrorArgs[] =
/* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */
{ 1, 1, DBGCVAR_CAT_STRING, 0, "direction", "write/read." },
{ 1, 1, DBGCVAR_CAT_STRING, 0, "filename", "Filename." },
- { 1, 1, DBGCVAR_CAT_STRING, 0, "errcode", "IPRT error code." },
+ { 1, 1, DBGCVAR_CAT_NUMBER, 0, "errcode", "VBox status code." },
};
+# ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
+static const DBGCVARDESC g_aInjectDelayArgs[] =
+{
+ /* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */
+ { 1, 1, DBGCVAR_CAT_STRING, 0, "direction", "write/read." },
+ { 1, 1, DBGCVAR_CAT_STRING, 0, "filename", "Filename." },
+ { 1, 1, DBGCVAR_CAT_NUMBER, 0, "delay", "Delay in milliseconds." },
+};
+# endif
+
/** Command descriptors. */
static const DBGCCMD g_aCmds[] =
{
- /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, pResultDesc, fFlags, pfnHandler pszSyntax, ....pszDescription */
- { "injecterror", 3, 3, &g_aInjectErrorArgs[0], 3, NULL, 0, pdmacEpFileErrorInject, "", "Inject error into I/O subsystem." },
+ /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, fFlags, pfnHandler pszSyntax, ....pszDescription */
+ { "injecterror", 3, 3, &g_aInjectErrorArgs[0], 3, 0, pdmacEpFileErrorInject, "", "Inject error into I/O subsystem." }
+# ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
+ ,{ "injectdelay", 3, 3, &g_aInjectDelayArgs[0], 3, 0, pdmacEpFileDelayInject, "", "Inject a delay of a request." }
+# endif
};
#endif
@@ -350,7 +365,34 @@ void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc)
if (!(uOld - pTask->DataSeg.cbSeg)
&& !ASMAtomicXchgBool(&pTaskFile->fCompleted, true))
+ {
+#ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
+ PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pTaskFile->Core.pEndpoint;
+
+ /* Check if we should delay completion of the request. */
+ if ( ASMAtomicReadU32(&pEpFile->msDelay) > 0
+ && ASMAtomicCmpXchgPtr(&pEpFile->pReqDelayed, pTaskFile, NULL))
+ {
+ /* Arm the delay. */
+ pEpFile->tsDelayEnd = RTTimeProgramMilliTS() + pEpFile->msDelay;
+ LogRel(("AIOMgr: Delaying request %#p for %u ms\n", pTaskFile, pEpFile->msDelay));
+ return;
+ }
+#endif
pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, pTaskFile->rc, true);
+
+#if PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
+ /* Check for an expired delay. */
+ if ( pEpFile->pReqDelayed != NULL
+ && RTTimeProgramMilliTS() >= pEpFile->tsDelayEnd)
+ {
+ pTaskFile = ASMAtomicXchgPtrT(&pEpFile->pReqDelayed, NULL, PPDMASYNCCOMPLETIONTASKFILE);
+ ASMAtomicXchgU32(&pEpFile->msDelay, 0);
+ LogRel(("AIOMgr: Delayed request %#p completed\n", pTaskFile));
+ pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, pTaskFile->rc, true);
+ }
+#endif
+ }
}
}
@@ -424,6 +466,8 @@ int pdmacFileAioMgrCreate(PPDMASYNCCOMPLETIONEPCLASSFILE pEpClass, PPPDMACEPFILE
else
pAioMgrNew->enmMgrType = pEpClass->enmMgrTypeOverride;
+ pAioMgrNew->msBwLimitExpired = RT_INDEFINITE_WAIT;
+
rc = RTSemEventCreate(&pAioMgrNew->EventSem);
if (RT_SUCCESS(rc))
{
@@ -593,7 +637,7 @@ static int pdmacFileEpNativeGetSize(RTFILE hFile, uint64_t *pcbSize)
#ifdef RT_OS_WINDOWS
DISK_GEOMETRY DriveGeo;
DWORD cbDriveGeo;
- if (DeviceIoControl((HANDLE)hFile,
+ if (DeviceIoControl((HANDLE)RTFileToNative(hFile),
IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
&DriveGeo, sizeof(DriveGeo), &cbDriveGeo, NULL))
{
@@ -607,7 +651,7 @@ static int pdmacFileEpNativeGetSize(RTFILE hFile, uint64_t *pcbSize)
GET_LENGTH_INFORMATION DiskLenInfo;
DWORD junk;
- if (DeviceIoControl((HANDLE)hFile,
+ if (DeviceIoControl((HANDLE)RTFileToNative(hFile),
IOCTL_DISK_GET_LENGTH_INFO, NULL, 0,
&DiskLenInfo, sizeof(DiskLenInfo), &junk, (LPOVERLAPPED)NULL))
{
@@ -623,18 +667,17 @@ static int pdmacFileEpNativeGetSize(RTFILE hFile, uint64_t *pcbSize)
}
}
else
- {
rc = RTErrConvertFromWin32(GetLastError());
- }
+
#elif defined(RT_OS_DARWIN)
struct stat DevStat;
- if (!fstat(hFile, &DevStat) && S_ISBLK(DevStat.st_mode))
+ if (!fstat(RTFileToNative(hFile), &DevStat) && S_ISBLK(DevStat.st_mode))
{
uint64_t cBlocks;
uint32_t cbBlock;
- if (!ioctl(hFile, DKIOCGETBLOCKCOUNT, &cBlocks))
+ if (!ioctl(RTFileToNative(hFile), DKIOCGETBLOCKCOUNT, &cBlocks))
{
- if (!ioctl(hFile, DKIOCGETBLOCKSIZE, &cbBlock))
+ if (!ioctl(RTFileToNative(hFile), DKIOCGETBLOCKSIZE, &cbBlock))
cbSize = cBlocks * cbBlock;
else
rc = RTErrConvertFromErrno(errno);
@@ -644,25 +687,28 @@ static int pdmacFileEpNativeGetSize(RTFILE hFile, uint64_t *pcbSize)
}
else
rc = VERR_INVALID_PARAMETER;
+
#elif defined(RT_OS_SOLARIS)
struct stat DevStat;
- if (!fstat(hFile, &DevStat) && ( S_ISBLK(DevStat.st_mode)
- || S_ISCHR(DevStat.st_mode)))
+ if ( !fstat(RTFileToNative(hFile), &DevStat)
+ && ( S_ISBLK(DevStat.st_mode)
+ || S_ISCHR(DevStat.st_mode)))
{
struct dk_minfo mediainfo;
- if (!ioctl(hFile, DKIOCGMEDIAINFO, &mediainfo))
+ if (!ioctl(RTFileToNative(hFile), DKIOCGMEDIAINFO, &mediainfo))
cbSize = mediainfo.dki_capacity * mediainfo.dki_lbsize;
else
rc = RTErrConvertFromErrno(errno);
}
else
rc = VERR_INVALID_PARAMETER;
+
#elif defined(RT_OS_FREEBSD)
struct stat DevStat;
- if (!fstat(hFile, &DevStat) && S_ISCHR(DevStat.st_mode))
+ if (!fstat(RTFileToNative(hFile), &DevStat) && S_ISCHR(DevStat.st_mode))
{
off_t cbMedia = 0;
- if (!ioctl(hFile, DIOCGMEDIASIZE, &cbMedia))
+ if (!ioctl(RTFileToNative(hFile), DIOCGMEDIASIZE, &cbMedia))
{
cbSize = cbMedia;
}
@@ -689,39 +735,40 @@ static int pdmacFileEpNativeGetSize(RTFILE hFile, uint64_t *pcbSize)
/**
* Error inject callback.
*/
-static DECLCALLBACK(int) pdmacEpFileErrorInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) pdmacEpFileErrorInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs)
{
- bool fWrite;
- PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile;
-
/*
* Validate input.
*/
- if (!pVM)
- return DBGCCmdHlpPrintf(pCmdHlp, "error: The command requires a VM to be selected.\n");
- if ( cArgs != 3
- || pArgs[0].enmType != DBGCVAR_TYPE_STRING
- || pArgs[1].enmType != DBGCVAR_TYPE_STRING
- || pArgs[2].enmType != DBGCVAR_TYPE_STRING)
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: parser error, invalid arguments.\n");
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
+ DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs == 3);
+ DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, pArgs[0].enmType == DBGCVAR_TYPE_STRING);
+ DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, pArgs[1].enmType == DBGCVAR_TYPE_STRING);
+ DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 2, pArgs[2].enmType == DBGCVAR_TYPE_NUMBER);
+ PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile;
pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pVM->pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE];
/* Syntax is "read|write <filename> <status code>" */
+ bool fWrite;
if (!RTStrCmp(pArgs[0].u.pszString, "read"))
fWrite = false;
else if (!RTStrCmp(pArgs[0].u.pszString, "write"))
fWrite = true;
else
- {
- DBGCCmdHlpPrintf(pCmdHlp, "error: invalid transefr direction '%s'.\n", pArgs[0].u.pszString);
- return VINF_SUCCESS;
- }
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "invalid transfer direction '%s'", pArgs[0].u.pszString);
+
+ int32_t rcToInject = (int32_t)pArgs[2].u.u64Number;
+ if ((uint64_t)rcToInject != pArgs[2].u.u64Number)
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "The status code '%lld' is out of range", pArgs[0].u.u64Number);
+
- /* Search for the matching endpoint. */
+ /*
+ * Search for the matching endpoint.
+ */
RTCritSectEnter(&pEpClassFile->Core.CritSect);
- PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead;
+ PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead;
while (pEpFile)
{
if (!RTStrCmp(pArgs[1].u.pszString, RTPathFilename(pEpFile->Core.pszUri)))
@@ -731,23 +778,91 @@ static DECLCALLBACK(int) pdmacEpFileErrorInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmd
if (pEpFile)
{
- int rcToInject = RTStrToInt32(pArgs[2].u.pszString);
-
+ /*
+ * Do the job.
+ */
if (fWrite)
ASMAtomicXchgS32(&pEpFile->rcReqWrite, rcToInject);
else
- ASMAtomicXchgS32(&pEpFile->rcReqRead, rcToInject);
+ ASMAtomicXchgS32(&pEpFile->rcReqRead, rcToInject);
- DBGCCmdHlpPrintf(pCmdHlp, "Injected %Rrc into '%s' for %s\n",
- rcToInject, pArgs[1].u.pszString, pArgs[0].u.pszString);
+ DBGCCmdHlpPrintf(pCmdHlp, "Injected %Rrc into '%s' for %s\n",
+ (int)rcToInject, pArgs[1].u.pszString, pArgs[0].u.pszString);
}
+
+ RTCritSectLeave(&pEpClassFile->Core.CritSect);
+
+ if (!pEpFile)
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "No file with name '%s' found", pArgs[1].u.pszString);
+ return VINF_SUCCESS;
+}
+
+# ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
+/**
+ * Delay inject callback.
+ */
+static DECLCALLBACK(int) pdmacEpFileDelayInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs)
+{
+ /*
+ * Validate input.
+ */
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
+ DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs == 3);
+ DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, pArgs[0].enmType == DBGCVAR_TYPE_STRING);
+ DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, pArgs[1].enmType == DBGCVAR_TYPE_STRING);
+ DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 2, pArgs[2].enmType == DBGCVAR_TYPE_NUMBER);
+
+ PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile;
+ pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pVM->pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE];
+
+ /* Syntax is "read|write <filename> <status code>" */
+ bool fWrite;
+ if (!RTStrCmp(pArgs[0].u.pszString, "read"))
+ fWrite = false;
+ else if (!RTStrCmp(pArgs[0].u.pszString, "write"))
+ fWrite = true;
else
- DBGCCmdHlpPrintf(pCmdHlp, "No file with name '%s' found\n", NULL, pArgs[1].u.pszString);
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "invalid transfer direction '%s'", pArgs[0].u.pszString);
+
+ uint32_t msDelay = (uint32_t)pArgs[2].u.u64Number;
+ if ((uint64_t)msDelay != pArgs[2].u.u64Number)
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "The delay '%lld' is out of range", pArgs[0].u.u64Number);
+
+
+ /*
+ * Search for the matching endpoint.
+ */
+ RTCritSectEnter(&pEpClassFile->Core.CritSect);
+
+ PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead;
+ while (pEpFile)
+ {
+ if (!RTStrCmp(pArgs[1].u.pszString, RTPathFilename(pEpFile->Core.pszUri)))
+ break;
+ pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext;
+ }
+
+ if (pEpFile)
+ {
+ bool fXchg = ASMAtomicCmpXchgU32(&pEpFile->msDelay, msDelay, 0);
+
+ if (fXchg)
+ DBGCCmdHlpPrintf(pCmdHlp, "Injected delay of %u ms into '%s' for %s\n",
+ msDelay, pArgs[1].u.pszString, pArgs[0].u.pszString);
+ else
+ DBGCCmdHlpPrintf(pCmdHlp, "Another delay for '%s' is still active, ignoring\n",
+ pArgs[1].u.pszString);
+ }
RTCritSectLeave(&pEpClassFile->Core.CritSect);
+
+ if (!pEpFile)
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "No file with name '%s' found", pArgs[1].u.pszString);
return VINF_SUCCESS;
}
-#endif
+# endif /* PDM_ASYNC_COMPLETION_FILE_WITH_DELAY */
+
+#endif /* VBOX_WITH_DEBUGGER */
static int pdmacFileInitialize(PPDMASYNCCOMPLETIONEPCLASS pClassGlobals, PCFGMNODE pCfgNode)
{
@@ -822,7 +937,7 @@ static int pdmacFileInitialize(PPDMASYNCCOMPLETIONEPCLASS pClassGlobals, PCFGMNO
/* Install the error injection handler. */
if (RT_SUCCESS(rc))
{
- rc = DBGCRegisterCommands(&g_aCmds[0], 1);
+ rc = DBGCRegisterCommands(&g_aCmds[0], RT_ELEMENTS(g_aCmds));
AssertRC(rc);
}
#endif
@@ -853,11 +968,21 @@ static int pdmacFileEpInitialize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
PDMACEPFILEMGRTYPE enmMgrType = pEpClassFile->enmMgrTypeOverride;
PDMACFILEEPBACKEND enmEpBackend = pEpClassFile->enmEpBackendDefault;
- AssertMsgReturn((fFlags & ~(PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_DONT_LOCK)) == 0,
+ AssertMsgReturn((fFlags & ~(PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_DONT_LOCK | PDMACEP_FILE_FLAGS_HOST_CACHE_ENABLED)) == 0,
("PDMAsyncCompletion: Invalid flag specified\n"), VERR_INVALID_PARAMETER);
unsigned fFileFlags = RTFILE_O_OPEN;
+ /*
+ * Revert to the simple manager and the buffered backend if
+ * the host cache should be enabled.
+ */
+ if (fFlags & PDMACEP_FILE_FLAGS_HOST_CACHE_ENABLED)
+ {
+ enmMgrType = PDMACEPFILEMGRTYPE_SIMPLE;
+ enmEpBackend = PDMACFILEEPBACKEND_BUFFERED;
+ }
+
if (fFlags & PDMACEP_FILE_FLAGS_READ_ONLY)
fFileFlags |= RTFILE_O_READ | RTFILE_O_DENY_NONE;
else
@@ -888,14 +1013,13 @@ static int pdmacFileEpInitialize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
* which will trash the host cache but ensures that the host cache will not
* contain dirty buffers.
*/
- RTFILE File = NIL_RTFILE;
-
- rc = RTFileOpen(&File, pszUri, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+ RTFILE hFile;
+ rc = RTFileOpen(&hFile, pszUri, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (RT_SUCCESS(rc))
{
uint64_t cbSize;
- rc = pdmacFileEpNativeGetSize(File, &cbSize);
+ rc = pdmacFileEpNativeGetSize(hFile, &cbSize);
Assert(RT_FAILURE(rc) || cbSize != 0);
if (RT_SUCCESS(rc) && ((cbSize % 512) == 0))
@@ -910,12 +1034,12 @@ static int pdmacFileEpInitialize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
enmMgrType = PDMACEPFILEMGRTYPE_SIMPLE;
#endif
}
- RTFileClose(File);
+ RTFileClose(hFile);
}
}
/* Open with final flags. */
- rc = RTFileOpen(&pEpFile->File, pszUri, fFileFlags);
+ rc = RTFileOpen(&pEpFile->hFile, pszUri, fFileFlags);
if ((rc == VERR_INVALID_FUNCTION) || (rc == VERR_INVALID_PARAMETER))
{
LogRel(("pdmacFileEpInitialize: RTFileOpen %s / %08x failed with %Rrc\n",
@@ -940,7 +1064,7 @@ static int pdmacFileEpInitialize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
#endif
/* Open again. */
- rc = RTFileOpen(&pEpFile->File, pszUri, fFileFlags);
+ rc = RTFileOpen(&pEpFile->hFile, pszUri, fFileFlags);
if (RT_FAILURE(rc))
{
@@ -953,7 +1077,7 @@ static int pdmacFileEpInitialize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
{
pEpFile->fFlags = fFileFlags;
- rc = pdmacFileEpNativeGetSize(pEpFile->File, (uint64_t *)&pEpFile->cbFile);
+ rc = pdmacFileEpNativeGetSize(pEpFile->hFile, (uint64_t *)&pEpFile->cbFile);
Assert(RT_FAILURE(rc) || pEpFile->cbFile != 0);
if (RT_SUCCESS(rc))
@@ -1023,7 +1147,7 @@ static int pdmacFileEpInitialize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
}
if (RT_FAILURE(rc))
- RTFileClose(pEpFile->File);
+ RTFileClose(pEpFile->hFile);
}
#ifdef VBOX_WITH_STATISTICS
@@ -1083,7 +1207,7 @@ static int pdmacFileEpClose(PPDMASYNCCOMPLETIONENDPOINT pEndpoint)
/* Destroy the locked ranges tree now. */
RTAvlrFileOffsetDestroy(pEpFile->AioMgr.pTreeRangesLocked, pdmacFileEpRangesLockedDestroy, NULL);
- RTFileClose(pEpFile->File);
+ RTFileClose(pEpFile->hFile);
#ifdef VBOX_WITH_STATISTICS
STAMR3Deregister(pEpClassFile->Core.pVM, &pEpFile->StatRead);
@@ -1177,7 +1301,7 @@ static int pdmacFileEpSetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint64_t cb
PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEndpoint;
ASMAtomicWriteU64(&pEpFile->cbFile, cbSize);
- return RTFileSetSize(pEpFile->File, cbSize);
+ return RTFileSetSize(pEpFile->hFile, cbSize);
}
const PDMASYNCCOMPLETIONEPCLASSOPS g_PDMAsyncCompletionEndpointClassFile =
diff --git a/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileFailsafe.cpp b/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileFailsafe.cpp
index 5f6e2e560..60280110c 100644
--- a/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileFailsafe.cpp
+++ b/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileFailsafe.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMAsyncCompletionFileFailsafe.cpp $ */
+/* $Id: PDMAsyncCompletionFileFailsafe.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* PDM Async I/O - Transport data asynchronous in R3 using EMT.
* Simple File I/O manager.
@@ -26,23 +26,58 @@
#include "PDMAsyncCompletionFileInternal.h"
+/**
+ * Put a list of tasks in the pending request list of an endpoint.
+ */
+DECLINLINE(void) pdmacFileAioMgrEpAddTaskList(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMACTASKFILE pTaskHead)
+{
+ /* Add the rest of the tasks to the pending list */
+ if (!pEndpoint->AioMgr.pReqsPendingHead)
+ {
+ Assert(!pEndpoint->AioMgr.pReqsPendingTail);
+ pEndpoint->AioMgr.pReqsPendingHead = pTaskHead;
+ }
+ else
+ {
+ Assert(pEndpoint->AioMgr.pReqsPendingTail);
+ pEndpoint->AioMgr.pReqsPendingTail->pNext = pTaskHead;
+ }
+
+ /* Update the tail. */
+ while (pTaskHead->pNext)
+ pTaskHead = pTaskHead->pNext;
+
+ pEndpoint->AioMgr.pReqsPendingTail = pTaskHead;
+ pTaskHead->pNext = NULL;
+}
-static int pdmacFileAioMgrFailsafeProcessEndpointTaskList(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint,
+/**
+ * Processes a given task list for assigned to the given endpoint.
+ */
+static int pdmacFileAioMgrFailsafeProcessEndpointTaskList(PPDMACEPFILEMGR pAioMgr,
+ PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint,
PPDMACTASKFILE pTasks)
{
int rc = VINF_SUCCESS;
while (pTasks)
{
+ RTMSINTERVAL msWhenNext;
PPDMACTASKFILE pCurr = pTasks;
+ if (!pdmacEpIsTransferAllowed(&pEndpoint->Core, (uint32_t)pCurr->DataSeg.cbSeg, &msWhenNext))
+ {
+ pAioMgr->msBwLimitExpired = RT_MIN(pAioMgr->msBwLimitExpired, msWhenNext);
+ break;
+ }
+
pTasks = pTasks->pNext;
switch (pCurr->enmTransferType)
{
case PDMACTASKFILETRANSFER_FLUSH:
{
- rc = RTFileFlush(pEndpoint->File);
+ rc = RTFileFlush(pEndpoint->hFile);
break;
}
case PDMACTASKFILETRANSFER_READ:
@@ -50,7 +85,7 @@ static int pdmacFileAioMgrFailsafeProcessEndpointTaskList(PPDMASYNCCOMPLETIONEND
{
if (pCurr->enmTransferType == PDMACTASKFILETRANSFER_READ)
{
- rc = RTFileReadAt(pEndpoint->File, pCurr->Off,
+ rc = RTFileReadAt(pEndpoint->hFile, pCurr->Off,
pCurr->DataSeg.pvSeg,
pCurr->DataSeg.cbSeg,
NULL);
@@ -60,10 +95,10 @@ static int pdmacFileAioMgrFailsafeProcessEndpointTaskList(PPDMASYNCCOMPLETIONEND
if (RT_UNLIKELY((uint64_t)pCurr->Off + pCurr->DataSeg.cbSeg > pEndpoint->cbFile))
{
ASMAtomicWriteU64(&pEndpoint->cbFile, pCurr->Off + pCurr->DataSeg.cbSeg);
- RTFileSetSize(pEndpoint->File, pCurr->Off + pCurr->DataSeg.cbSeg);
+ RTFileSetSize(pEndpoint->hFile, pCurr->Off + pCurr->DataSeg.cbSeg);
}
- rc = RTFileWriteAt(pEndpoint->File, pCurr->Off,
+ rc = RTFileWriteAt(pEndpoint->hFile, pCurr->Off,
pCurr->DataSeg.pvSeg,
pCurr->DataSeg.cbSeg,
NULL);
@@ -79,10 +114,17 @@ static int pdmacFileAioMgrFailsafeProcessEndpointTaskList(PPDMASYNCCOMPLETIONEND
pdmacFileTaskFree(pEndpoint, pCurr);
}
+ if (pTasks)
+ {
+ /* Add the rest of the tasks to the pending list */
+ pdmacFileAioMgrEpAddTaskList(pEndpoint, pTasks);
+ }
+
return VINF_SUCCESS;
}
-static int pdmacFileAioMgrFailsafeProcessEndpoint(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint)
+static int pdmacFileAioMgrFailsafeProcessEndpoint(PPDMACEPFILEMGR pAioMgr,
+ PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint)
{
int rc = VINF_SUCCESS;
PPDMACTASKFILE pTasks = pEndpoint->AioMgr.pReqsPendingHead;
@@ -92,14 +134,14 @@ static int pdmacFileAioMgrFailsafeProcessEndpoint(PPDMASYNCCOMPLETIONENDPOINTFIL
/* Process the request pending list first in case the endpoint was migrated due to an error. */
if (pTasks)
- rc = pdmacFileAioMgrFailsafeProcessEndpointTaskList(pEndpoint, pTasks);
+ rc = pdmacFileAioMgrFailsafeProcessEndpointTaskList(pAioMgr, pEndpoint, pTasks);
if (RT_SUCCESS(rc))
{
pTasks = pdmacFileEpGetNewTasks(pEndpoint);
if (pTasks)
- rc = pdmacFileAioMgrFailsafeProcessEndpointTaskList(pEndpoint, pTasks);
+ rc = pdmacFileAioMgrFailsafeProcessEndpointTaskList(pAioMgr, pEndpoint, pTasks);
}
return rc;
@@ -119,9 +161,9 @@ int pdmacFileAioMgrFailsafe(RTTHREAD ThreadSelf, void *pvUser)
{
ASMAtomicWriteBool(&pAioMgr->fWaitingEventSem, true);
if (!ASMAtomicReadBool(&pAioMgr->fWokenUp))
- rc = RTSemEventWait(pAioMgr->EventSem, RT_INDEFINITE_WAIT);
+ rc = RTSemEventWait(pAioMgr->EventSem, pAioMgr->msBwLimitExpired);
ASMAtomicWriteBool(&pAioMgr->fWaitingEventSem, false);
- AssertRC(rc);
+ Assert(RT_SUCCESS(rc) || rc == VERR_TIMEOUT);
LogFlow(("Got woken up\n"));
ASMAtomicWriteBool(&pAioMgr->fWokenUp, false);
@@ -130,7 +172,8 @@ int pdmacFileAioMgrFailsafe(RTTHREAD ThreadSelf, void *pvUser)
PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint = pAioMgr->pEndpointsHead;
while (pEndpoint)
{
- rc = pdmacFileAioMgrFailsafeProcessEndpoint(pEndpoint);
+ pAioMgr->msBwLimitExpired = RT_INDEFINITE_WAIT;
+ rc = pdmacFileAioMgrFailsafeProcessEndpoint(pAioMgr, pEndpoint);
AssertRC(rc);
pEndpoint = pEndpoint->AioMgr.pEndpointNext;
}
@@ -159,7 +202,7 @@ int pdmacFileAioMgrFailsafe(RTTHREAD ThreadSelf, void *pvUser)
* Process the task list the first time. There might be pending requests
* if the endpoint was migrated from another endpoint.
*/
- rc = pdmacFileAioMgrFailsafeProcessEndpoint(pEndpointNew);
+ rc = pdmacFileAioMgrFailsafeProcessEndpoint(pAioMgr, pEndpointNew);
AssertRC(rc);
break;
}
@@ -192,7 +235,7 @@ int pdmacFileAioMgrFailsafe(RTTHREAD ThreadSelf, void *pvUser)
pEndpointClose->enmState = PDMASYNCCOMPLETIONENDPOINTFILESTATE_CLOSING;
/* Make sure all tasks finished. */
- rc = pdmacFileAioMgrFailsafeProcessEndpoint(pEndpointClose);
+ rc = pdmacFileAioMgrFailsafeProcessEndpoint(pAioMgr, pEndpointClose);
AssertRC(rc);
break;
}
diff --git a/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileNormal.cpp b/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileNormal.cpp
index c27774864..d4e45aae5 100644
--- a/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileNormal.cpp
+++ b/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileNormal.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMAsyncCompletionFileNormal.cpp $ */
+/* $Id: PDMAsyncCompletionFileNormal.cpp 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* PDM Async I/O - Transport data asynchronous in R3 using EMT.
* Async File I/O manager.
@@ -16,6 +16,7 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
+#define RT_STRICT
#include <iprt/types.h>
#include <iprt/asm.h>
#include <iprt/file.h>
@@ -61,7 +62,6 @@ int pdmacFileAioMgrNormalInit(PPDMACEPFILEMGR pAioMgr)
pAioMgr->iFreeEntry = 0;
pAioMgr->cReqEntries = pAioMgr->cRequestsActiveMax;
pAioMgr->pahReqsFree = (RTFILEAIOREQ *)RTMemAllocZ(pAioMgr->cReqEntries * sizeof(RTFILEAIOREQ));
- pAioMgr->msBwLimitExpired = RT_INDEFINITE_WAIT;
if (pAioMgr->pahReqsFree)
{
@@ -204,8 +204,8 @@ static bool pdmacFileAioMgrNormalRemoveEndpoint(PPDMASYNCCOMPLETIONENDPOINTFILE
Assert(!pEndpointRemove->pFlushReq);
/* Reopen the file so that the new endpoint can re-associate with the file */
- RTFileClose(pEndpointRemove->File);
- int rc = RTFileOpen(&pEndpointRemove->File, pEndpointRemove->Core.pszUri, pEndpointRemove->fFlags);
+ RTFileClose(pEndpointRemove->hFile);
+ int rc = RTFileOpen(&pEndpointRemove->hFile, pEndpointRemove->Core.pszUri, pEndpointRemove->fFlags);
AssertRC(rc);
return false;
}
@@ -340,8 +340,8 @@ static int pdmacFileAioMgrNormalGrow(PPDMACEPFILEMGR pAioMgr)
while (pCurr)
{
- RTFileClose(pCurr->File);
- rc = RTFileOpen(&pCurr->File, pCurr->Core.pszUri, pCurr->fFlags);
+ RTFileClose(pCurr->hFile);
+ rc = RTFileOpen(&pCurr->hFile, pCurr->Core.pszUri, pCurr->fFlags);
AssertRC(rc);
pCurr = pCurr->AioMgr.pEndpointNext;
@@ -389,7 +389,7 @@ static int pdmacFileAioMgrNormalGrow(PPDMACEPFILEMGR pAioMgr)
while (pCurr)
{
- rc = RTFileAioCtxAssociateWithFile(pAioMgr->hAioCtx, pCurr->File);
+ rc = RTFileAioCtxAssociateWithFile(pAioMgr->hAioCtx, pCurr->hFile);
AssertRC(rc);
pCurr = pCurr->AioMgr.pEndpointNext;
@@ -789,15 +789,15 @@ static int pdmacFileAioMgrNormalTaskPrepareBuffered(PPDMACEPFILEMGR pAioMgr,
if (RT_UNLIKELY((uint64_t)(pTask->Off + pTask->DataSeg.cbSeg) > pEndpoint->cbFile))
{
ASMAtomicWriteU64(&pEndpoint->cbFile, pTask->Off + pTask->DataSeg.cbSeg);
- RTFileSetSize(pEndpoint->File, pTask->Off + pTask->DataSeg.cbSeg);
+ RTFileSetSize(pEndpoint->hFile, pTask->Off + pTask->DataSeg.cbSeg);
}
- rc = RTFileAioReqPrepareWrite(hReq, pEndpoint->File,
+ rc = RTFileAioReqPrepareWrite(hReq, pEndpoint->hFile,
pTask->Off, pTask->DataSeg.pvSeg,
pTask->DataSeg.cbSeg, pTask);
}
else
- rc = RTFileAioReqPrepareRead(hReq, pEndpoint->File,
+ rc = RTFileAioReqPrepareRead(hReq, pEndpoint->hFile,
pTask->Off, pTask->DataSeg.pvSeg,
pTask->DataSeg.cbSeg, pTask);
AssertRC(rc);
@@ -924,14 +924,14 @@ static int pdmacFileAioMgrNormalTaskPrepareNonBuffered(PPDMACEPFILEMGR pAioMgr,
if (RT_UNLIKELY((uint64_t)(pTask->Off + pTask->DataSeg.cbSeg) > pEndpoint->cbFile))
{
ASMAtomicWriteU64(&pEndpoint->cbFile, pTask->Off + pTask->DataSeg.cbSeg);
- RTFileSetSize(pEndpoint->File, pTask->Off + pTask->DataSeg.cbSeg);
+ RTFileSetSize(pEndpoint->hFile, pTask->Off + pTask->DataSeg.cbSeg);
}
- rc = RTFileAioReqPrepareWrite(hReq, pEndpoint->File,
+ rc = RTFileAioReqPrepareWrite(hReq, pEndpoint->hFile,
offStart, pvBuf, cbToTransfer, pTask);
}
else
- rc = RTFileAioReqPrepareRead(hReq, pEndpoint->File,
+ rc = RTFileAioReqPrepareRead(hReq, pEndpoint->hFile,
offStart, pvBuf, cbToTransfer, pTask);
AssertRC(rc);
@@ -1003,7 +1003,7 @@ static int pdmacFileAioMgrNormalProcessTaskList(PPDMACTASKFILE pTaskHead,
LogFlow(("Flush request %#p\n", hReq));
- rc = RTFileAioReqPrepareFlush(hReq, pEndpoint->File, pCurr);
+ rc = RTFileAioReqPrepareFlush(hReq, pEndpoint->hFile, pCurr);
if (RT_FAILURE(rc))
{
pEndpoint->fAsyncFlushSupported = false;
@@ -1188,7 +1188,7 @@ static int pdmacFileAioMgrNormalProcessBlockingEvent(PPDMACEPFILEMGR pAioMgr)
pAioMgr->pEndpointsHead = pEndpointNew;
/* Assign the completion point to this file. */
- rc = RTFileAioCtxAssociateWithFile(pAioMgr->hAioCtx, pEndpointNew->File);
+ rc = RTFileAioCtxAssociateWithFile(pAioMgr->hAioCtx, pEndpointNew->hFile);
fNotifyWaiter = true;
pAioMgr->cEndpoints++;
break;
@@ -1288,8 +1288,8 @@ static int pdmacFileAioMgrNormalCheckEndpoints(PPDMACEPFILEMGR pAioMgr)
&& pEndpoint->enmState != PDMASYNCCOMPLETIONENDPOINTFILESTATE_ACTIVE)
{
/* Reopen the file so that the new endpoint can re-associate with the file */
- RTFileClose(pEndpoint->File);
- rc = RTFileOpen(&pEndpoint->File, pEndpoint->Core.pszUri, pEndpoint->fFlags);
+ RTFileClose(pEndpoint->hFile);
+ rc = RTFileOpen(&pEndpoint->hFile, pEndpoint->Core.pszUri, pEndpoint->fFlags);
AssertRC(rc);
if (pEndpoint->AioMgr.fMoving)
@@ -1471,14 +1471,14 @@ static void pdmacFileAioMgrNormalReqCompleteRc(PPDMACEPFILEMGR pAioMgr, RTFILEAI
if (pTask->fPrefetch || pTask->enmTransferType == PDMACTASKFILETRANSFER_READ)
{
- rc = RTFileAioReqPrepareRead(hReq, pEndpoint->File, offStart,
+ rc = RTFileAioReqPrepareRead(hReq, pEndpoint->hFile, offStart,
pbBuf, cbToTransfer, pTask);
}
else
{
AssertMsg(pTask->enmTransferType == PDMACTASKFILETRANSFER_WRITE,
("Invalid transfer type\n"));
- rc = RTFileAioReqPrepareWrite(hReq, pEndpoint->File, offStart,
+ rc = RTFileAioReqPrepareWrite(hReq, pEndpoint->hFile, offStart,
pbBuf, cbToTransfer, pTask);
}
AssertRC(rc);
@@ -1506,10 +1506,10 @@ static void pdmacFileAioMgrNormalReqCompleteRc(PPDMACEPFILEMGR pAioMgr, RTFILEAI
if (RT_UNLIKELY((uint64_t)(pTask->Off + pTask->DataSeg.cbSeg) > pEndpoint->cbFile))
{
ASMAtomicWriteU64(&pEndpoint->cbFile, pTask->Off + pTask->DataSeg.cbSeg);
- RTFileSetSize(pEndpoint->File, pTask->Off + pTask->DataSeg.cbSeg);
+ RTFileSetSize(pEndpoint->hFile, pTask->Off + pTask->DataSeg.cbSeg);
}
- rc = RTFileAioReqPrepareWrite(hReq, pEndpoint->File,
+ rc = RTFileAioReqPrepareWrite(hReq, pEndpoint->hFile,
offStart, pTask->pvBounceBuffer, cbToTransfer, pTask);
AssertRC(rc);
pTask->hReq = hReq;
diff --git a/src/VBox/VMM/VMMR3/PDMBlkCache.cpp b/src/VBox/VMM/VMMR3/PDMBlkCache.cpp
index 721864370..3a6b7080a 100644
--- a/src/VBox/VMM/VMMR3/PDMBlkCache.cpp
+++ b/src/VBox/VMM/VMMR3/PDMBlkCache.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMBlkCache.cpp $ */
+/* $Id: PDMBlkCache.cpp 37933 2011-07-13 22:57:20Z vboxsync $ */
/** @file
* PDM Block Cache.
*/
@@ -96,7 +96,7 @@ DECLINLINE(void) pdmBlkCacheEntryRef(PPDMBLKCACHEENTRY pEntry)
ASMAtomicIncU32(&pEntry->cRefs);
}
-#ifdef DEBUG
+#ifdef VBOX_STRICT
static void pdmBlkCacheValidate(PPDMBLKCACHEGLOBAL pCache)
{
/* Amount of cached data should never exceed the maximum amount. */
@@ -115,14 +115,14 @@ static void pdmBlkCacheValidate(PPDMBLKCACHEGLOBAL pCache)
DECLINLINE(void) pdmBlkCacheLockEnter(PPDMBLKCACHEGLOBAL pCache)
{
RTCritSectEnter(&pCache->CritSect);
-#ifdef DEBUG
+#ifdef VBOX_STRICT
pdmBlkCacheValidate(pCache);
#endif
}
DECLINLINE(void) pdmBlkCacheLockLeave(PPDMBLKCACHEGLOBAL pCache)
{
-#ifdef DEBUG
+#ifdef VBOX_STRICT
pdmBlkCacheValidate(pCache);
#endif
RTCritSectLeave(&pCache->CritSect);
diff --git a/src/VBox/VMM/VMMR3/PDMCritSect.cpp b/src/VBox/VMM/VMMR3/PDMCritSect.cpp
index 7084e6789..6943726d4 100644
--- a/src/VBox/VMM/VMMR3/PDMCritSect.cpp
+++ b/src/VBox/VMM/VMMR3/PDMCritSect.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMCritSect.cpp $ */
+/* $Id: PDMCritSect.cpp 37466 2011-06-15 12:44:16Z vboxsync $ */
/** @file
* PDM - Critical Sections, Ring-3.
*/
@@ -122,7 +122,8 @@ VMMDECL(int) PDMR3CritSectTerm(PVM pVM)
* statistics and lock validation.
* @param va Arguments for the format string.
*/
-static int pdmR3CritSectInitOne(PVM pVM, PPDMCRITSECTINT pCritSect, void *pvKey, RT_SRC_POS_DECL, const char *pszNameFmt, va_list va)
+static int pdmR3CritSectInitOne(PVM pVM, PPDMCRITSECTINT pCritSect, void *pvKey, RT_SRC_POS_DECL,
+ const char *pszNameFmt, va_list va)
{
VM_ASSERT_EMT(pVM);
@@ -163,6 +164,8 @@ static int pdmR3CritSectInitOne(PVM pVM, PPDMCRITSECTINT pCritSect, void *pvKey,
pCritSect->pVMR0 = pVM->pVMR0;
pCritSect->pVMRC = pVM->pVMRC;
pCritSect->pvKey = pvKey;
+ pCritSect->fAutomaticDefaultCritsect = false;
+ pCritSect->fUsedByTimerOrSimilar = false;
pCritSect->EventToSignal = NIL_RTSEMEVENT;
pCritSect->pNext = pVM->pUVM->pdm.s.pCritSects;
pCritSect->pszName = pszName;
@@ -238,6 +241,27 @@ int pdmR3CritSectInitDevice(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect,
/**
+ * Initializes the automatic default PDM critical section for a device.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM handle.
+ * @param pDevIns Device instance.
+ * @param pCritSect Pointer to the critical section.
+ */
+int pdmR3CritSectInitDeviceAuto(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
+ const char *pszNameFmt, ...)
+{
+ va_list va;
+ va_start(va, pszNameFmt);
+ int rc = pdmR3CritSectInitOne(pVM, &pCritSect->s, pDevIns, RT_SRC_POS_ARGS, pszNameFmt, va);
+ if (RT_SUCCESS(rc))
+ pCritSect->s.fAutomaticDefaultCritsect = true;
+ va_end(va);
+ return rc;
+}
+
+
+/**
* Initializes a PDM critical section for a driver.
*
* @returns VBox status code.
@@ -458,6 +482,7 @@ VMMR3DECL(bool) PDMR3CritSectYield(PPDMCRITSECT pCritSect)
AssertPtrReturn(pCritSect, false);
AssertReturn(pCritSect->s.Core.u32Magic == RTCRITSECT_MAGIC, false);
Assert(pCritSect->s.Core.NativeThreadOwner == RTThreadNativeSelf());
+ Assert(!(pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NOP));
/* No recursion allowed here. */
int32_t const cNestings = pCritSect->s.Core.cNestings;
@@ -515,6 +540,8 @@ VMMR3DECL(bool) PDMR3CritSectYield(PPDMCRITSECT pCritSect)
*/
VMMR3DECL(int) PDMR3CritSectScheduleExitEvent(PPDMCRITSECT pCritSect, RTSEMEVENT EventToSignal)
{
+ AssertPtr(pCritSect);
+ Assert(!(pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NOP));
Assert(EventToSignal != NIL_RTSEMEVENT);
if (RT_UNLIKELY(!RTCritSectIsOwner(&pCritSect->s.Core)))
return VERR_NOT_OWNER;
@@ -617,9 +644,12 @@ VMMR3DECL(uint32_t) PDMR3CritSectCountOwned(PVM pVM, char *pszNames, size_t cbNa
/**
* Leave all critical sections the calling thread owns.
*
+ * This is only used when entering guru meditation in order to prevent other
+ * EMTs and I/O threads from deadlocking.
+ *
* @param pVM The VM handle.
*/
-void PDMR3CritSectLeaveAll(PVM pVM)
+VMMR3DECL(void) PDMR3CritSectLeaveAll(PVM pVM)
{
RTNATIVETHREAD const hNativeSelf = RTThreadNativeSelf();
PUVM pUVM = pVM->pUVM;
@@ -636,3 +666,45 @@ void PDMR3CritSectLeaveAll(PVM pVM)
RTCritSectLeave(&pUVM->pdm.s.ListCritSect);
}
+
+/**
+ * Gets the address of the NOP critical section.
+ *
+ * The NOP critical section will not perform any thread serialization but let
+ * all enter immediately and concurrently.
+ *
+ * @returns The address of the NOP critical section.
+ * @param pVM The VM handle.
+ */
+VMMR3DECL(PPDMCRITSECT) PDMR3CritSectGetNop(PVM pVM)
+{
+ VM_ASSERT_VALID_EXT_RETURN(pVM, NULL);
+ return &pVM->pdm.s.NopCritSect;
+}
+
+
+/**
+ * Gets the ring-0 address of the NOP critical section.
+ *
+ * @returns The ring-0 address of the NOP critical section.
+ * @param pVM The VM handle.
+ */
+VMMR3DECL(R0PTRTYPE(PPDMCRITSECT)) PDMR3CritSectGetNopR0(PVM pVM)
+{
+ VM_ASSERT_VALID_EXT_RETURN(pVM, NIL_RTR0PTR);
+ return MMHyperR3ToR0(pVM, &pVM->pdm.s.NopCritSect);
+}
+
+
+/**
+ * Gets the raw-mode context address of the NOP critical section.
+ *
+ * @returns The raw-mode context address of the NOP critical section.
+ * @param pVM The VM handle.
+ */
+VMMR3DECL(RCPTRTYPE(PPDMCRITSECT)) PDMR3CritSectGetNopRC(PVM pVM)
+{
+ VM_ASSERT_VALID_EXT_RETURN(pVM, NIL_RTRCPTR);
+ return MMHyperR3ToRC(pVM, &pVM->pdm.s.NopCritSect);
+}
+
diff --git a/src/VBox/VMM/VMMR3/PDMDevHlp.cpp b/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
index 9c7eb8bb9..5d7851080 100644
--- a/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
+++ b/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
@@ -1,10 +1,10 @@
-/* $Id: PDMDevHlp.cpp $ */
+/* $Id: PDMDevHlp.cpp 37466 2011-06-15 12:44:16Z vboxsync $ */
/** @file
* PDM - Pluggable Device and Driver Manager, Device Helpers.
*/
/*
- * 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;
@@ -268,7 +268,7 @@ static DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS G
pDevIns->pReg->szName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc, pszDesc));
/** @todo IOMR3MMIORegisterR3 mangles the description, move it here. */
- int rc = IOMR3MMIORegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc);
+ int rc = IOMR3MmioRegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc);
LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
return rc;
@@ -310,7 +310,7 @@ static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterRC(PPDMDEVINS pDevIns, RTGCPHYS
rc3 = pdmR3DevGetSymbolRCLazy(pDevIns, pszFill, &RCPtrFill);
if (RT_SUCCESS(rc) && RT_SUCCESS(rc2) && RT_SUCCESS(rc3))
- rc = IOMR3MMIORegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, RCPtrWrite, RCPtrRead, RCPtrFill);
+ rc = IOMR3MmioRegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, RCPtrWrite, RCPtrRead, RCPtrFill);
else
{
AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pReg->szRCMod, pszWrite));
@@ -364,7 +364,7 @@ static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS
if (pszFill)
rc3 = pdmR3DevGetSymbolR0Lazy(pDevIns, pszFill, &pfnR0PtrFill);
if (RT_SUCCESS(rc) && RT_SUCCESS(rc2) && RT_SUCCESS(rc3))
- rc = IOMR3MMIORegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnR0PtrWrite, pfnR0PtrRead, pfnR0PtrFill);
+ rc = IOMR3MmioRegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnR0PtrWrite, pfnR0PtrRead, pfnR0PtrFill);
else
{
AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pReg->szR0Mod, pszWrite));
@@ -395,7 +395,7 @@ static DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS
LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: GCPhysStart=%RGp cbRange=%#x\n",
pDevIns->pReg->szName, pDevIns->iInstance, GCPhysStart, cbRange));
- int rc = IOMR3MMIODeregister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange);
+ int rc = IOMR3MmioDeregister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange);
LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
return rc;
@@ -1000,6 +1000,16 @@ static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const
}
+/** @interface_method_impl{PDMDEVHLPR3,pfnDBGFTraceBuf} */
+static DECLCALLBACK(RTTRACEBUF) pdmR3DevHlp_DBGFTraceBuf(PPDMDEVINS pDevIns)
+{
+ PDMDEV_ASSERT_DEVINS(pDevIns);
+ RTTRACEBUF hTraceBuf = pDevIns->Internal.s.pVMR3->hTraceBufR3;
+ LogFlow(("pdmR3DevHlp_DBGFTraceBuf: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, hTraceBuf));
+ return hTraceBuf;
+}
+
+
/** @interface_method_impl{PDMDEVHLPR3,pfnSTAMRegister} */
static DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
{
@@ -1205,7 +1215,7 @@ static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int
LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Rrc (iRegion)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
- switch (enmType)
+ switch ((int)enmType)
{
case PCI_ADDRESS_SPACE_IO:
/*
@@ -1218,6 +1228,8 @@ static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int
case PCI_ADDRESS_SPACE_MEM:
case PCI_ADDRESS_SPACE_MEM_PREFETCH:
+ case PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_BAR64:
+ case PCI_ADDRESS_SPACE_MEM_PREFETCH | PCI_ADDRESS_SPACE_BAR64:
/*
* Sanity check: don't allow to register more than 512MB of the PCI MMIO space for
* now. If this limit is increased beyond 2GB, adapt the aligned check below as well!
@@ -1249,7 +1261,7 @@ static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int
/*
* We're currently restricted to page aligned MMIO regions.
*/
- if ( (enmType == PCI_ADDRESS_SPACE_MEM || enmType == PCI_ADDRESS_SPACE_MEM_PREFETCH)
+ if ( ((enmType & ~(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_MEM_PREFETCH)) == PCI_ADDRESS_SPACE_MEM)
&& cbRegion != RT_ALIGN_32(cbRegion, PAGE_SIZE))
{
Log(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: aligning cbRegion %#x -> %#x\n",
@@ -1531,6 +1543,99 @@ static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSE
}
+/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetNop} */
+static DECLCALLBACK(PPDMCRITSECT) pdmR3DevHlp_CritSectGetNop(PPDMDEVINS pDevIns)
+{
+ PDMDEV_ASSERT_DEVINS(pDevIns);
+ PVM pVM = pDevIns->Internal.s.pVMR3;
+ VM_ASSERT_EMT(pVM);
+
+ PPDMCRITSECT pCritSect = PDMR3CritSectGetNop(pVM);
+ LogFlow(("pdmR3DevHlp_CritSectGetNop: caller='%s'/%d: return %p\n",
+ pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
+ return pCritSect;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetNopR0} */
+static DECLCALLBACK(R0PTRTYPE(PPDMCRITSECT)) pdmR3DevHlp_CritSectGetNopR0(PPDMDEVINS pDevIns)
+{
+ PDMDEV_ASSERT_DEVINS(pDevIns);
+ PVM pVM = pDevIns->Internal.s.pVMR3;
+ VM_ASSERT_EMT(pVM);
+
+ R0PTRTYPE(PPDMCRITSECT) pCritSect = PDMR3CritSectGetNopR0(pVM);
+ LogFlow(("pdmR3DevHlp_CritSectGetNopR0: caller='%s'/%d: return %RHv\n",
+ pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
+ return pCritSect;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetNopRC} */
+static DECLCALLBACK(RCPTRTYPE(PPDMCRITSECT)) pdmR3DevHlp_CritSectGetNopRC(PPDMDEVINS pDevIns)
+{
+ PDMDEV_ASSERT_DEVINS(pDevIns);
+ PVM pVM = pDevIns->Internal.s.pVMR3;
+ VM_ASSERT_EMT(pVM);
+
+ RCPTRTYPE(PPDMCRITSECT) pCritSect = PDMR3CritSectGetNopRC(pVM);
+ LogFlow(("pdmR3DevHlp_CritSectGetNopRC: caller='%s'/%d: return %RRv\n",
+ pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
+ return pCritSect;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnSetDeviceCritSect} */
+static DECLCALLBACK(int) pdmR3DevHlp_SetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
+{
+ /*
+ * Validate input.
+ *
+ * Note! We only allow the automatically created default critical section
+ * to be replaced by this API.
+ */
+ PDMDEV_ASSERT_DEVINS(pDevIns);
+ AssertPtrReturn(pCritSect, VERR_INVALID_POINTER);
+ LogFlow(("pdmR3DevHlp_SetDeviceCritSect: caller='%s'/%d: pCritSect=%p (%s)\n",
+ pDevIns->pReg->szName, pDevIns->iInstance, pCritSect, pCritSect->s.pszName));
+ AssertReturn(PDMCritSectIsInitialized(pCritSect), VERR_INVALID_PARAMETER);
+ PVM pVM = pDevIns->Internal.s.pVMR3;
+ AssertReturn(pCritSect->s.pVMR3 == pVM, VERR_INVALID_PARAMETER);
+
+ VM_ASSERT_EMT(pVM);
+ VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
+
+ AssertReturn(pDevIns->pCritSectRoR3, VERR_INTERNAL_ERROR_4);
+ AssertReturn(pDevIns->pCritSectRoR3->s.fAutomaticDefaultCritsect, VERR_WRONG_ORDER);
+ AssertReturn(!pDevIns->pCritSectRoR3->s.fUsedByTimerOrSimilar, VERR_WRONG_ORDER);
+ AssertReturn(pDevIns->pCritSectRoR3 != pCritSect, VERR_INVALID_PARAMETER);
+
+ /*
+ * Replace the critical section and destroy the automatic default section.
+ */
+ PPDMCRITSECT pOldCritSect = pDevIns->pCritSectRoR3;
+ pDevIns->pCritSectRoR3 = pCritSect;
+ if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
+ pDevIns->pCritSectRoR0 = MMHyperCCToR0(pVM, pDevIns->pCritSectRoR3);
+ else
+ Assert(pDevIns->pCritSectRoR0 == NIL_RTRCPTR);
+
+ if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
+ pDevIns->pCritSectRoRC = MMHyperCCToRC(pVM, pDevIns->pCritSectRoR3);
+ else
+ Assert(pDevIns->pCritSectRoRC == NIL_RTRCPTR);
+
+ PDMR3CritSectDelete(pOldCritSect);
+ if (pDevIns->pReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0))
+ MMHyperFree(pVM, pOldCritSect);
+ else
+ MMR3HeapFree(pOldCritSect);
+
+ LogFlow(("pdmR3DevHlp_SetDeviceCritSect: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
+ return VINF_SUCCESS;
+}
+
+
/** @interface_method_impl{PDMDEVHLPR3,pfnThreadCreate} */
static DECLCALLBACK(int) pdmR3DevHlp_ThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
@@ -2812,6 +2917,37 @@ static DECLCALLBACK(int) pdmR3DevHlp_HPETRegister(PPDMDEVINS pDevIns, PPDMHPETRE
}
+/** @interface_method_impl{PDMDEVHLPR3,pfnPciRawRegister} */
+static DECLCALLBACK(int) pdmR3DevHlp_PciRawRegister(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3)
+{
+ PDMDEV_ASSERT_DEVINS(pDevIns);
+ VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
+ LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d:\n"));
+
+ /*
+ * Validate input.
+ */
+ if (pPciRawReg->u32Version != PDM_PCIRAWREG_VERSION)
+ {
+ AssertMsgFailed(("u32Version=%#x expected %#x\n", pPciRawReg->u32Version, PDM_PCIRAWREG_VERSION));
+ LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (version)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ if (!ppPciRawHlpR3)
+ {
+ Assert(ppPciRawHlpR3);
+ LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (ppApicHlpR3)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ /* set the helper pointer and return. */
+ *ppPciRawHlpR3 = &g_pdmR3DevPciRawHlp;
+ LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
+ return VINF_SUCCESS;
+}
+
+
/** @interface_method_impl{PDMDEVHLPR3,pfnDMACRegister} */
static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
{
@@ -3159,6 +3295,7 @@ const PDMDEVHLPR3 g_pdmR3DevHlpTrusted =
pdmR3DevHlp_VMSetRuntimeErrorV,
pdmR3DevHlp_DBGFStopV,
pdmR3DevHlp_DBGFInfoRegister,
+ pdmR3DevHlp_DBGFTraceBuf,
pdmR3DevHlp_STAMRegister,
pdmR3DevHlp_STAMRegisterF,
pdmR3DevHlp_STAMRegisterV,
@@ -3173,6 +3310,10 @@ const PDMDEVHLPR3 g_pdmR3DevHlpTrusted =
pdmR3DevHlp_DriverAttach,
pdmR3DevHlp_QueueCreate,
pdmR3DevHlp_CritSectInit,
+ pdmR3DevHlp_CritSectGetNop,
+ pdmR3DevHlp_CritSectGetNopR0,
+ pdmR3DevHlp_CritSectGetNopRC,
+ pdmR3DevHlp_SetDeviceCritSect,
pdmR3DevHlp_ThreadCreate,
pdmR3DevHlp_SetAsyncNotification,
pdmR3DevHlp_AsyncNotificationCompleted,
@@ -3182,6 +3323,7 @@ const PDMDEVHLPR3 g_pdmR3DevHlpTrusted =
pdmR3DevHlp_APICRegister,
pdmR3DevHlp_IOAPICRegister,
pdmR3DevHlp_HPETRegister,
+ pdmR3DevHlp_PciRawRegister,
pdmR3DevHlp_DMACRegister,
pdmR3DevHlp_DMARegister,
pdmR3DevHlp_DMAReadMemory,
@@ -3369,6 +3511,7 @@ const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted =
pdmR3DevHlp_VMSetRuntimeErrorV,
pdmR3DevHlp_DBGFStopV,
pdmR3DevHlp_DBGFInfoRegister,
+ pdmR3DevHlp_DBGFTraceBuf,
pdmR3DevHlp_STAMRegister,
pdmR3DevHlp_STAMRegisterF,
pdmR3DevHlp_STAMRegisterV,
@@ -3383,6 +3526,10 @@ const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted =
pdmR3DevHlp_DriverAttach,
pdmR3DevHlp_QueueCreate,
pdmR3DevHlp_CritSectInit,
+ pdmR3DevHlp_CritSectGetNop,
+ pdmR3DevHlp_CritSectGetNopR0,
+ pdmR3DevHlp_CritSectGetNopRC,
+ pdmR3DevHlp_SetDeviceCritSect,
pdmR3DevHlp_ThreadCreate,
pdmR3DevHlp_SetAsyncNotification,
pdmR3DevHlp_AsyncNotificationCompleted,
@@ -3392,6 +3539,7 @@ const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted =
pdmR3DevHlp_APICRegister,
pdmR3DevHlp_IOAPICRegister,
pdmR3DevHlp_HPETRegister,
+ pdmR3DevHlp_PciRawRegister,
pdmR3DevHlp_DMACRegister,
pdmR3DevHlp_DMARegister,
pdmR3DevHlp_DMAReadMemory,
diff --git a/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp b/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp
index 9007df9c4..e42599b9d 100644
--- a/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp
+++ b/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp
@@ -1,10 +1,10 @@
-/* $Id: PDMDevMiscHlp.cpp $ */
+/* $Id: PDMDevMiscHlp.cpp 36820 2011-04-22 19:40:29Z vboxsync $ */
/** @file
* PDM - Pluggable Device and Driver Manager, Misc. Device Helpers.
*/
/*
- * 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;
@@ -55,7 +55,7 @@ static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
PVMCPU pVCpu = &pVM->aCpus[0]; /* for PIC we always deliver to CPU 0, MP use APIC */
- LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 1\n",
+ LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_PIC %d -> 1\n",
pDevIns->pReg->szName, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
@@ -81,7 +81,7 @@ static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
return;
}
- LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
+ LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
pDevIns->pReg->szName, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
@@ -168,7 +168,7 @@ static DECLCALLBACK(void) pdmR3ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPI
AssertReturnVoid(idCpu < pVM->cCpus);
- LogFlow(("pdmR3ApicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT(%d) %d -> 1\n",
+ LogFlow(("pdmR3ApicHlp_SetInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_APIC(%d) %d -> 1\n",
pDevIns->pReg->szName, pDevIns->iInstance, idCpu, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
switch (enmType)
@@ -203,7 +203,7 @@ static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMA
AssertReturnVoid(idCpu < pVM->cCpus);
- LogFlow(("pdmR3ApicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT(%d) %d -> 0\n",
+ LogFlow(("pdmR3ApicHlp_ClearInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_APIC(%d) %d -> 0\n",
pDevIns->pReg->szName, pDevIns->iInstance, idCpu, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
/* Note: NMI/SMI can't be cleared. */
@@ -651,6 +651,53 @@ const PDMHPETHLPR3 g_pdmR3DevHpetHlp =
/** @} */
+/** @name Ring-3 Raw PCI Device Helpers
+ * {@
+ */
+
+/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetRCHelpers} */
+static DECLCALLBACK(PCPDMPCIRAWHLPRC) pdmR3PciRawHlp_GetRCHelpers(PPDMDEVINS pDevIns)
+{
+ PDMDEV_ASSERT_DEVINS(pDevIns);
+ VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
+ RTRCPTR pRCHelpers = NIL_RTRCPTR;
+ int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPciRawHlp", &pRCHelpers);
+ AssertReleaseRC(rc);
+ AssertRelease(pRCHelpers);
+ LogFlow(("pdmR3PciRawHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
+ pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
+ return pRCHelpers;
+}
+
+
+/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetR0Helpers} */
+static DECLCALLBACK(PCPDMPCIRAWHLPR0) pdmR3PciRawHlp_GetR0Helpers(PPDMDEVINS pDevIns)
+{
+ PDMDEV_ASSERT_DEVINS(pDevIns);
+ VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
+ PCPDMHPETHLPR0 pR0Helpers = NIL_RTR0PTR;
+ int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PciRawHlp", &pR0Helpers);
+ AssertReleaseRC(rc);
+ AssertRelease(pR0Helpers);
+ LogFlow(("pdmR3PciRawHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
+ pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
+ return pR0Helpers;
+}
+
+
+/**
+ * Raw PCI Device Helpers.
+ */
+const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp =
+{
+ PDM_PCIRAWHLPR3_VERSION,
+ pdmR3PciRawHlp_GetRCHelpers,
+ pdmR3PciRawHlp_GetR0Helpers,
+ PDM_PCIRAWHLPR3_VERSION, /* the end */
+};
+
+/** @} */
+
/* none yet */
diff --git a/src/VBox/VMM/VMMR3/PDMDevice.cpp b/src/VBox/VMM/VMMR3/PDMDevice.cpp
index f7e5dc7cc..8ce97ed28 100644
--- a/src/VBox/VMM/VMMR3/PDMDevice.cpp
+++ b/src/VBox/VMM/VMMR3/PDMDevice.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMDevice.cpp $ */
+/* $Id: PDMDevice.cpp 37812 2011-07-07 09:56:42Z vboxsync $ */
/** @file
* PDM - Pluggable Device and Driver Manager, Device parts.
*/
@@ -191,7 +191,7 @@ int pdmR3DevInit(PVM pVM)
/* Find the device. */
PPDMDEV pDev = pdmR3DevLookup(pVM, szName);
- AssertMsgReturn(pDev, ("Configuration error: device '%s' not found!\n", szName), VERR_PDM_DEVICE_NOT_FOUND);
+ AssertLogRelMsgReturn(pDev, ("Configuration error: device '%s' not found!\n", szName), VERR_PDM_DEVICE_NOT_FOUND);
/* Configured priority or use default based on device class? */
uint32_t u32Order;
@@ -287,7 +287,7 @@ int pdmR3DevInit(PVM pVM)
CFGMR3SetRestrictedRoot(pConfigNode);
/*
- * Allocate the device instance.
+ * Allocate the device instance and critical section.
*/
AssertReturn(paDevs[i].pDev->cInstances < paDevs[i].pDev->pReg->cMaxInstances, VERR_PDM_TOO_MANY_DEVICE_INSTANCES);
size_t cb = RT_OFFSETOF(PDMDEVINS, achInstanceData[paDevs[i].pDev->pReg->cbInstance]);
@@ -297,12 +297,16 @@ int pdmR3DevInit(PVM pVM)
rc = MMR3HyperAllocOnceNoRel(pVM, cb, 0, MM_TAG_PDM_DEVICE, (void **)&pDevIns);
else
rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_DEVICE, cb, (void **)&pDevIns);
- if (RT_FAILURE(rc))
- {
- AssertMsgFailed(("Failed to allocate %d bytes of instance data for device '%s'. rc=%Rrc\n",
- cb, paDevs[i].pDev->pReg->szName, rc));
- return rc;
- }
+ AssertLogRelMsgRCReturn(rc,
+ ("Failed to allocate %d bytes of instance data for device '%s'. rc=%Rrc\n",
+ cb, paDevs[i].pDev->pReg->szName, rc),
+ rc);
+ PPDMCRITSECT pCritSect;
+ if (paDevs[i].pDev->pReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0))
+ rc = MMHyperAlloc(pVM, sizeof(*pCritSect), 0, MM_TAG_PDM_DEVICE, (void **)&pCritSect);
+ else
+ rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_DEVICE, sizeof(*pCritSect), (void **)&pCritSect);
+ AssertLogRelMsgRCReturn(rc, ("Failed to allocate a critical section for the device\n", rc), rc);
/*
* Initialize it.
@@ -334,9 +338,16 @@ int pdmR3DevInit(PVM pVM)
? MMHyperR3ToRC(pVM, pDevIns->pvInstanceDataR3) : NIL_RTRCPTR;
pDevIns->pvInstanceDataR0 = pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0
? MMHyperR3ToR0(pVM, pDevIns->pvInstanceDataR3) : NIL_RTR0PTR;
- //pDevIns->pCritSectR3 = NULL;
- //pDevIns->pCritSectR0 = NIL_RTR0PTR;
- //pDevIns->pCritSectRC = NIL_RTRCPTR;
+
+ pDevIns->pCritSectRoR3 = pCritSect;
+ pDevIns->pCritSectRoRC = pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC
+ ? MMHyperR3ToRC(pVM, pCritSect) : NIL_RTRCPTR;
+ pDevIns->pCritSectRoR0 = pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0
+ ? MMHyperR3ToR0(pVM, pCritSect) : NIL_RTR0PTR;
+
+ rc = pdmR3CritSectInitDeviceAuto(pVM, pDevIns, pCritSect, RT_SRC_POS,
+ "%s#%u Auto", pDevIns->pReg->szName, pDevIns->iInstance);
+ AssertLogRelRCReturn(rc, rc);
/*
* Link it into all the lists.
@@ -369,41 +380,13 @@ int pdmR3DevInit(PVM pVM)
paDevs[i].pDev->cInstances++;
Log(("PDM: Constructing device '%s' instance %d...\n", pDevIns->pReg->szName, pDevIns->iInstance));
rc = pDevIns->pReg->pfnConstruct(pDevIns, pDevIns->iInstance, pDevIns->pCfg);
- if (RT_SUCCESS(rc))
- {
- /*
- * Per-device critsect fun.
- */
- if (pDevIns->pCritSectR3)
- {
- AssertStmt(PDMCritSectIsInitialized(pDevIns->pCritSectR3), rc = VERR_INTERNAL_ERROR_4);
- if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
- {
- pDevIns->pCritSectR0 = MMHyperCCToR0(pVM, pDevIns->pCritSectR3);
- AssertStmt(pDevIns->pCritSectR0 != NIL_RTR0PTR, rc = VERR_INTERNAL_ERROR_3);
- }
- else
- AssertStmt(pDevIns->pCritSectR0 == NIL_RTRCPTR, rc = VERR_INTERNAL_ERROR_2);
-
- if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
- {
- pDevIns->pCritSectRC = MMHyperCCToRC(pVM, pDevIns->pCritSectR3);
- AssertStmt(pDevIns->pCritSectRC != NIL_RTRCPTR, rc = VERR_INTERNAL_ERROR_3);
- }
- else
- AssertStmt(pDevIns->pCritSectRC == NIL_RTRCPTR, rc = VERR_INTERNAL_ERROR_2);
- }
- else
- AssertStmt( pDevIns->pCritSectRC == NIL_RTRCPTR
- && pDevIns->pCritSectR0 == NIL_RTR0PTR,
- rc = VERR_INTERNAL_ERROR_5);
- }
if (RT_FAILURE(rc))
{
LogRel(("PDM: Failed to construct '%s'/%d! %Rra\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
paDevs[i].pDev->cInstances--;
- /* because we're damn lazy right now, we'll say that the destructor will be called even if the constructor fails. */
- return rc;
+ /* Because we're damn lazy, the destructor will be called even if
+ the constructor fails. So, no unlinking. */
+ return rc == VERR_VERSION_MISMATCH ? VERR_PDM_DEVICE_VERSION_MISMATCH : rc;
}
} /* for device instances */
@@ -854,6 +837,30 @@ VMMR3DECL(int) PDMR3DeviceDetach(PVM pVM, const char *pszDevice, unsigned iInsta
/**
+ * References the critical section associated with a device for the use by a
+ * timer or similar created by the device.
+ *
+ * @returns Pointer to the critical section.
+ * @param pVM The VM handle.
+ * @param pDevIns The device instance in question.
+ *
+ * @internal
+ */
+VMMR3_INT_DECL(PPDMCRITSECT) PDMR3DevGetCritSect(PVM pVM, PPDMDEVINS pDevIns)
+{
+ VM_ASSERT_EMT(pVM);
+ VM_ASSERT_STATE(pVM, VMSTATE_CREATING);
+ AssertPtr(pDevIns);
+
+ PPDMCRITSECT pCritSect = pDevIns->pCritSectRoR3;
+ AssertPtr(pCritSect);
+ pCritSect->s.fUsedByTimerOrSimilar = true;
+
+ return pCritSect;
+}
+
+
+/**
* Attaches a preconfigured driver to an existing device or driver instance.
*
* This is used to change drivers and suchlike at runtime. The driver or device
diff --git a/src/VBox/VMM/VMMR3/PDMDriver.cpp b/src/VBox/VMM/VMMR3/PDMDriver.cpp
index 1799be91d..9fa5f4661 100644
--- a/src/VBox/VMM/VMMR3/PDMDriver.cpp
+++ b/src/VBox/VMM/VMMR3/PDMDriver.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMDriver.cpp $ */
+/* $Id: PDMDriver.cpp 37418 2011-06-11 08:22:10Z vboxsync $ */
/** @file
* PDM - Pluggable Device and Driver Manager, Driver parts.
*/
@@ -508,7 +508,11 @@ int pdmR3DrvInstantiate(PVM pVM, PCFGMNODE pNode, PPDMIBASE pBaseInterface, PPDM
pDrvAbove, pDrvAbove ? pDrvAbove->pReg->szName : "", pDrvAbove ? pDrvAbove->iInstance : UINT32_MAX));
}
else
+ {
pdmR3DrvDestroyChain(pNew, PDM_TACH_FLAGS_NO_CALLBACKS);
+ if (rc == VERR_VERSION_MISMATCH)
+ rc = VERR_PDM_DRIVER_VERSION_MISMATCH;
+ }
}
else
{
diff --git a/src/VBox/VMM/VMMR3/PDMLdr.cpp b/src/VBox/VMM/VMMR3/PDMLdr.cpp
index 05ffa326f..d2871e7a6 100644
--- a/src/VBox/VMM/VMMR3/PDMLdr.cpp
+++ b/src/VBox/VMM/VMMR3/PDMLdr.cpp
@@ -1,10 +1,10 @@
-/* $Id: PDMLdr.cpp $ */
+/* $Id: PDMLdr.cpp 37443 2011-06-14 14:34:11Z vboxsync $ */
/** @file
* PDM - Pluggable Device Manager, module loader.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -246,7 +246,7 @@ int pdmR3LoadR3U(PUVM pUVM, const char *pszFilename, const char *pszName)
/*
* Validate input.
*/
- AssertMsg(pUVM->pVM->pdm.s.offVM, ("bad init order!\n"));
+ AssertMsg(PDMCritSectIsInitialized(&pUVM->pVM->pdm.s.CritSect), ("bad init order!\n"));
Assert(pszFilename);
size_t cchFilename = strlen(pszFilename);
Assert(pszName);
@@ -440,7 +440,7 @@ VMMR3DECL(int) PDMR3LdrLoadRC(PVM pVM, const char *pszFilename, const char *pszN
/*
* Validate input.
*/
- AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
+ AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
PUVM pUVM = pVM->pUVM;
RTCritSectEnter(&pUVM->pdm.s.ListCritSect);
PPDMMOD pCur = pUVM->pdm.s.pModules;
@@ -691,7 +691,10 @@ VMMR3DECL(int) PDMR3LdrGetSymbolR3(PVM pVM, const char *pszModule, const char *p
/*
* Validate input.
*/
- AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
+ AssertPtr(pVM);
+ AssertPtr(pszModule);
+ AssertPtr(ppvValue);
+ AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
/*
* Find the module.
@@ -747,7 +750,11 @@ VMMR3DECL(int) PDMR3LdrGetSymbolR0(PVM pVM, const char *pszModule, const char *p
/*
* Validate input.
*/
- AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
+ AssertPtr(pVM);
+ AssertPtrNull(pszModule);
+ AssertPtr(ppvValue);
+ AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
+
if (!pszModule)
pszModule = "VMMR0.r0";
@@ -799,11 +806,15 @@ VMMR3DECL(int) PDMR3LdrGetSymbolR0Lazy(PVM pVM, const char *pszModule, const cha
return VINF_SUCCESS;
#else
+ AssertPtr(pVM);
+ AssertPtrNull(pszModule);
+ AssertPtr(ppvValue);
+ AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
+
/*
* Since we're lazy, we'll only check if the module is present
* and hand it over to PDMR3LdrGetSymbolR0 when that's done.
*/
- AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
if (pszModule)
{
AssertMsgReturn(!strpbrk(pszModule, "/\\:\n\r\t"), ("pszModule=%s\n", pszModule), VERR_INVALID_PARAMETER);
@@ -846,7 +857,11 @@ VMMR3DECL(int) PDMR3LdrGetSymbolRC(PVM pVM, const char *pszModule, const char *p
/*
* Validate input.
*/
- AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
+ AssertPtr(pVM);
+ AssertPtrNull(pszModule);
+ AssertPtr(pRCPtrValue);
+ AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
+
if (!pszModule)
pszModule = "VMMGC.gc";
@@ -906,11 +921,15 @@ VMMR3DECL(int) PDMR3LdrGetSymbolRCLazy(PVM pVM, const char *pszModule, const cha
return VINF_SUCCESS;
#else
+ AssertPtr(pVM);
+ AssertPtrNull(pszModule);
+ AssertPtr(pRCPtrValue);
+ AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
+
/*
* Since we're lazy, we'll only check if the module is present
* and hand it over to PDMR3LdrGetSymbolRC when that's done.
*/
- AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
if (pszModule)
{
AssertMsgReturn(!strpbrk(pszModule, "/\\:\n\r\t"), ("pszModule=%s\n", pszModule), VERR_INVALID_PARAMETER);
diff --git a/src/VBox/VMM/VMMR3/PDMQueue.cpp b/src/VBox/VMM/VMMR3/PDMQueue.cpp
index 7827e0d3e..afb16ca3e 100644
--- a/src/VBox/VMM/VMMR3/PDMQueue.cpp
+++ b/src/VBox/VMM/VMMR3/PDMQueue.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMQueue.cpp $ */
+/* $Id: PDMQueue.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* PDM Queue - Transport data and tasks to EMT and R3.
*/
diff --git a/src/VBox/VMM/VMMR3/PDMThread.cpp b/src/VBox/VMM/VMMR3/PDMThread.cpp
index 02aa7aef0..997e4c2b8 100644
--- a/src/VBox/VMM/VMMR3/PDMThread.cpp
+++ b/src/VBox/VMM/VMMR3/PDMThread.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMThread.cpp $ */
+/* $Id: PDMThread.cpp 36437 2011-03-25 15:36:59Z vboxsync $ */
/** @file
* PDM Thread - VM Thread Management.
*/
diff --git a/src/VBox/VMM/VMMR3/PDMUsb.cpp b/src/VBox/VMM/VMMR3/PDMUsb.cpp
index 968626a16..ad221a2ef 100644
--- a/src/VBox/VMM/VMMR3/PDMUsb.cpp
+++ b/src/VBox/VMM/VMMR3/PDMUsb.cpp
@@ -1,4 +1,4 @@
-/* $Id: PDMUsb.cpp $ */
+/* $Id: PDMUsb.cpp 37879 2011-07-12 04:35:53Z vboxsync $ */
/** @file
* PDM - Pluggable Device and Driver Manager, USB part.
*/
@@ -636,7 +636,11 @@ static int pdmR3UsbCreateDevice(PVM pVM, PPDMUSBHUB pHub, PPDMUSB pUsbDev, int i
pUsbIns->pReg->szName, pUsbIns->iInstance, pHub, rc));
}
else
+ {
AssertMsgFailed(("Failed to construct '%s'/%d! %Rra\n", pUsbIns->pReg->szName, pUsbIns->iInstance, rc));
+ if (rc == VERR_VERSION_MISMATCH)
+ rc = VERR_PDM_DRIVER_VERSION_MISMATCH;
+ }
if (fAtRuntime)
pdmR3UsbDestroyDevice(pVM, pUsbIns);
/* else: destructors are invoked later. */
@@ -1361,6 +1365,22 @@ static DECLCALLBACK(VMSTATE) pdmR3UsbHlp_VMState(PPDMUSBINS pUsbIns)
return enmVMState;
}
+/** @interface_method_impl{PDMUSBHLP,pfnThreadCreate} */
+static DECLCALLBACK(int) pdmR3UsbHlp_ThreadCreate(PPDMUSBINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
+ PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
+{
+ PDMUSB_ASSERT_USBINS(pUsbIns);
+ VM_ASSERT_EMT(pUsbIns->Internal.s.pVM);
+ LogFlow(("pdmR3UsbHlp_ThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n",
+ pUsbIns->pReg->szName, pUsbIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName));
+
+ int rc = pdmR3ThreadCreateUsb(pUsbIns->Internal.s.pVM, pUsbIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
+
+ LogFlow(("pdmR3UsbHlp_ThreadCreate: caller='%s'/%d: returns %Rrc *ppThread=%RTthrd\n", pUsbIns->pReg->szName, pUsbIns->iInstance,
+ rc, *ppThread));
+ return rc;
+}
+
/** @interface_method_impl{PDMUSBHLP,pfnSetAsyncNotification} */
static DECLCALLBACK(int) pdmR3UsbHlp_SetAsyncNotification(PPDMUSBINS pUsbIns, PFNPDMUSBASYNCNOTIFY pfnAsyncNotify)
@@ -1434,6 +1454,7 @@ const PDMUSBHLP g_pdmR3UsbHlp =
pdmR3UsbHlp_VMSetErrorV,
pdmR3UsbHlp_VMSetRuntimeErrorV,
pdmR3UsbHlp_VMState,
+ pdmR3UsbHlp_ThreadCreate,
pdmR3UsbHlp_SetAsyncNotification,
pdmR3UsbHlp_AsyncNotificationCompleted,
PDM_USBHLP_VERSION
diff --git a/src/VBox/VMM/VMMR3/PGM.cpp b/src/VBox/VMM/VMMR3/PGM.cpp
index c27670d73..0c2c5c1f7 100644
--- a/src/VBox/VMM/VMMR3/PGM.cpp
+++ b/src/VBox/VMM/VMMR3/PGM.cpp
@@ -1,10 +1,10 @@
-/* $Id: PGM.cpp $ */
+/* $Id: PGM.cpp 37803 2011-07-06 14:45:27Z vboxsync $ */
/** @file
* PGM - Page Manager and Monitor. (Mixing stuff here, not good?)
*/
/*
- * 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;
@@ -623,14 +623,14 @@ static PGMMODE pgmR3CalcShadowMode(PVM pVM, PGMMODE enmGuestMode, SUP
#ifdef VBOX_WITH_DEBUGGER
/** @todo Convert the first two commands to 'info' items. */
-static DECLCALLBACK(int) pgmR3CmdRam(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) pgmR3CmdError(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) pgmR3CmdSync(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-static DECLCALLBACK(int) pgmR3CmdSyncAlways(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
+static DECLCALLBACK(int) pgmR3CmdRam(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) pgmR3CmdError(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) pgmR3CmdSync(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static DECLCALLBACK(int) pgmR3CmdSyncAlways(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
# ifdef VBOX_STRICT
-static DECLCALLBACK(int) pgmR3CmdAssertCR3(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
+static DECLCALLBACK(int) pgmR3CmdAssertCR3(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
# endif
-static DECLCALLBACK(int) pgmR3CmdPhysToFile(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
+static DECLCALLBACK(int) pgmR3CmdPhysToFile(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
#endif
@@ -664,20 +664,20 @@ static const DBGCVARDESC g_aPgmCountPhysWritesArgs[] =
/** Command descriptors. */
static const DBGCCMD g_aCmds[] =
{
- /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, pResultDesc, fFlags, pfnHandler pszSyntax, ....pszDescription */
- { "pgmram", 0, 0, NULL, 0, NULL, 0, pgmR3CmdRam, "", "Display the ram ranges." },
- { "pgmsync", 0, 0, NULL, 0, NULL, 0, pgmR3CmdSync, "", "Sync the CR3 page." },
- { "pgmerror", 0, 1, &g_aPgmErrorArgs[0], 1, NULL, 0, pgmR3CmdError, "", "Enables inject runtime of errors into parts of PGM." },
- { "pgmerroroff", 0, 1, &g_aPgmErrorArgs[0], 1, NULL, 0, pgmR3CmdError, "", "Disables inject runtime errors into parts of PGM." },
+ /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, fFlags, pfnHandler pszSyntax, ....pszDescription */
+ { "pgmram", 0, 0, NULL, 0, 0, pgmR3CmdRam, "", "Display the ram ranges." },
+ { "pgmsync", 0, 0, NULL, 0, 0, pgmR3CmdSync, "", "Sync the CR3 page." },
+ { "pgmerror", 0, 1, &g_aPgmErrorArgs[0], 1, 0, pgmR3CmdError, "", "Enables inject runtime of errors into parts of PGM." },
+ { "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, NULL, 0, pgmR3CmdAssertCR3, "", "Check the shadow CR3 mapping." },
+ { "pgmassertcr3", 0, 0, NULL, 0, 0, pgmR3CmdAssertCR3, "", "Check the shadow CR3 mapping." },
# if HC_ARCH_BITS == 64
- { "pgmcheckduppages", 0, 0, NULL, 0, NULL, 0, pgmR3CmdCheckDuplicatePages, "", "Check for duplicate pages in all running VMs." },
- { "pgmsharedmodules", 0, 0, NULL, 0, NULL, 0, pgmR3CmdShowSharedModules, "", "Print shared modules info." },
+ { "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
# endif
- { "pgmsyncalways", 0, 0, NULL, 0, NULL, 0, pgmR3CmdSyncAlways, "", "Toggle permanent CR3 syncing." },
- { "pgmphystofile", 1, 2, &g_aPgmPhysToFileArgs[0], 2, NULL, 0, pgmR3CmdPhysToFile, "", "Save the physical memory to file." },
+ { "pgmsyncalways", 0, 0, NULL, 0, 0, pgmR3CmdSyncAlways, "", "Toggle permanent CR3 syncing." },
+ { "pgmphystofile", 1, 2, &g_aPgmPhysToFileArgs[0], 2, 0, pgmR3CmdPhysToFile, "", "Save the physical memory to file." },
};
#endif
@@ -1196,6 +1196,20 @@ VMMR3DECL(int) PGMR3Init(PVM pVM)
pVM->pgm.s.offVM = RT_OFFSETOF(VM, pgm.s);
pVM->pgm.s.offVCpuPGM = RT_OFFSETOF(VMCPU, pgm.s);
+ for (unsigned i = 0; i < RT_ELEMENTS(pVM->pgm.s.aHandyPages); i++)
+ {
+ pVM->pgm.s.aHandyPages[i].HCPhysGCPhys = NIL_RTHCPHYS;
+ pVM->pgm.s.aHandyPages[i].idPage = NIL_GMM_PAGEID;
+ pVM->pgm.s.aHandyPages[i].idSharedPage = NIL_GMM_PAGEID;
+ }
+
+ for (unsigned i = 0; i < RT_ELEMENTS(pVM->pgm.s.aLargeHandyPage); i++)
+ {
+ pVM->pgm.s.aLargeHandyPage[i].HCPhysGCPhys = NIL_RTHCPHYS;
+ pVM->pgm.s.aLargeHandyPage[i].idPage = NIL_GMM_PAGEID;
+ pVM->pgm.s.aLargeHandyPage[i].idSharedPage = NIL_GMM_PAGEID;
+ }
+
/* Init the per-CPU part. */
for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
{
@@ -1276,6 +1290,13 @@ VMMR3DECL(int) PGMR3Init(PVM pVM)
return rc;
}
+ /*
+ * Check for PCI pass-through.
+ */
+ rc = CFGMR3QueryBoolDef(pCfgPGM, "PciPassThrough", &pVM->pgm.s.fPciPassthrough, false);
+ AssertMsgRCReturn(rc, ("Configuration error: Failed to query integer \"PciPassThrough\", rc=%Rrc.\n", rc), rc);
+ AssertLogRelReturn(!pVM->pgm.s.fPciPassthrough || pVM->pgm.s.fRamPreAlloc, VERR_INVALID_PARAMETER);
+
#ifdef VBOX_WITH_STATISTICS
/*
* Allocate memory for the statistics before someone tries to use them.
@@ -1319,7 +1340,7 @@ VMMR3DECL(int) PGMR3Init(PVM pVM)
AssertRCReturn(rc, rc);
PGMR3PhysChunkInvalidateTLB(pVM);
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
/*
* For the time being we sport a full set of handy pages in addition to the base
@@ -1688,6 +1709,11 @@ static int pgmR3InitStats(PVM pVM)
PGM_REG_COUNTER(&pStats->StatPageMapTlbFlushes, "/PGM/R3/Page/MapTlbFlushes", "TLB flushes (all contexts).");
PGM_REG_COUNTER(&pStats->StatPageMapTlbFlushEntry, "/PGM/R3/Page/MapTlbFlushEntry", "TLB entry flushes (all contexts).");
+ PGM_REG_COUNTER(&pStats->StatRZRamRangeTlbHits, "/PGM/RZ/RamRange/TlbHits", "TLB hits.");
+ PGM_REG_COUNTER(&pStats->StatRZRamRangeTlbMisses, "/PGM/RZ/RamRange/TlbMisses", "TLB misses.");
+ PGM_REG_COUNTER(&pStats->StatR3RamRangeTlbHits, "/PGM/R3/RamRange/TlbHits", "TLB hits.");
+ PGM_REG_COUNTER(&pStats->StatR3RamRangeTlbMisses, "/PGM/R3/RamRange/TlbMisses", "TLB misses.");
+
PGM_REG_PROFILE(&pStats->StatRZSyncCR3HandlerVirtualUpdate, "/PGM/RZ/SyncCR3/Handlers/VirtualUpdate", "Profiling of the virtual handler updates.");
PGM_REG_PROFILE(&pStats->StatRZSyncCR3HandlerVirtualReset, "/PGM/RZ/SyncCR3/Handlers/VirtualReset", "Profiling of the virtual handler resets.");
PGM_REG_PROFILE(&pStats->StatR3SyncCR3HandlerVirtualUpdate, "/PGM/R3/SyncCR3/Handlers/VirtualUpdate", "Profiling of the virtual handler updates.");
@@ -2039,8 +2065,6 @@ VMMR3DECL(int) PGMR3InitFinalize(PVM pVM)
pVM->pgm.s.paDynPageMap32BitPTEsGC = pMapping->aPTs[iPT].pPTRC + iPG * sizeof(pMapping->aPTs[0].pPTR3->a[0]);
pVM->pgm.s.paDynPageMapPaePTEsGC = pMapping->aPTs[iPT].paPaePTsRC + iPG * sizeof(pMapping->aPTs[0].paPaePTsR3->a[0]);
- LogFlowFunc(("paDynPageMap32BitPTEsGC=%#p paDynPageMapPaePTEsGC=%#p\n", pVM->pgm.s.paDynPageMap32BitPTEsGC, pVM->pgm.s.paDynPageMapPaePTEsGC));
-
/* init cache area */
RTHCPHYS HCPhysDummy = MMR3PageDummyHCPhys(pVM);
for (uint32_t offDynMap = 0; offDynMap < MM_HYPER_DYNAMIC_SIZE; offDynMap += PAGE_SIZE)
@@ -2136,6 +2160,49 @@ VMMR3DECL(int) PGMR3InitFinalize(PVM pVM)
/**
+ * Init phase completed callback.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM handle.
+ * @param enmWhat What has been completed.
+ * @thread EMT(0)
+ */
+VMMR3_INT_DECL(int) PGMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
+{
+ switch (enmWhat)
+ {
+ case VMINITCOMPLETED_HWACCM:
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ if (pVM->pgm.s.fPciPassthrough)
+ {
+ AssertLogRelReturn(pVM->pgm.s.fRamPreAlloc, VERR_PCI_PASSTHROUGH_NO_RAM_PREALLOC);
+ AssertLogRelReturn(HWACCMIsEnabled(pVM), VERR_PCI_PASSTHROUGH_NO_HWACCM);
+ AssertLogRelReturn(HWACCMIsNestedPagingActive(pVM), VERR_PCI_PASSTHROUGH_NO_NESTED_PAGING);
+
+ /*
+ * Report assignments to the IOMMU (hope that's good enough for now).
+ */
+ if (pVM->pgm.s.fPciPassthrough)
+ {
+ int rc = VMMR3CallR0(pVM, VMMR0_DO_PGM_PHYS_SETUP_IOMMU, 0, NULL);
+ AssertRCReturn(rc, rc);
+ }
+ }
+#else
+ AssertLogRelReturn(!pVM->pgm.s.fPciPassthrough, VERR_INTERNAL_ERROR_5);
+#endif
+ break;
+
+ default:
+ /* shut up gcc */
+ break;
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
* Applies relocations to data and code managed by this component.
*
* This function will be called at init and whenever the VMM need to relocate it
@@ -2175,13 +2242,17 @@ VMMR3DECL(void) PGMR3Relocate(PVM pVM, RTGCINTPTR offDelta)
/*
* Ram ranges.
*/
- if (pVM->pgm.s.pRamRangesR3)
+ if (pVM->pgm.s.pRamRangesXR3)
{
/* Update the pSelfRC pointers and relink them. */
- for (PPGMRAMRANGE pCur = pVM->pgm.s.pRamRangesR3; pCur; pCur = pCur->pNextR3)
+ for (PPGMRAMRANGE pCur = pVM->pgm.s.pRamRangesXR3; pCur; pCur = pCur->pNextR3)
if (!(pCur->fFlags & PGM_RAM_RANGE_FLAGS_FLOATING))
pCur->pSelfRC = MMHyperCCToRC(pVM, pCur);
pgmR3PhysRelinkRamRanges(pVM);
+
+ /* Flush the RC TLB. */
+ for (unsigned i = 0; i < PGM_RAMRANGE_TLB_ENTRIES; i++)
+ pVM->pgm.s.apRamRangesTlbRC[i] = NIL_RTRCPTR;
}
/*
@@ -2558,7 +2629,7 @@ static DECLCALLBACK(void) pgmR3PhysInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char
sizeof(RTGCPHYS) * 4 + 1, "GC Phys Range ",
sizeof(RTHCPTR) * 2, "pvHC ");
- for (PPGMRAMRANGE pCur = pVM->pgm.s.pRamRangesR3; pCur; pCur = pCur->pNextR3)
+ for (PPGMRAMRANGE pCur = pVM->pgm.s.pRamRangesXR3; pCur; pCur = pCur->pNextR3)
pHlp->pfnPrintf(pHlp,
"%RGp-%RGp %RHv %s\n",
pCur->GCPhys,
@@ -2607,7 +2678,7 @@ static DECLCALLBACK(void) pgmR3InfoCr3(PVM pVM, PCDBGFINFOHLP pHlp, const char *
pHlp->pfnPrintf(pHlp,
"%04X - %RGp P=%d U=%d RW=%d G=%d - BIG\n",
iPD,
- pgmGstGet4MBPhysPage(&pVM->pgm.s, PdeSrc),
+ pgmGstGet4MBPhysPage(pVM, PdeSrc),
PdeSrc.b.u1Present, PdeSrc.b.u1User, PdeSrc.b.u1Write, PdeSrc.b.u1Global && fPGE);
else
pHlp->pfnPrintf(pHlp,
@@ -3207,7 +3278,8 @@ VMMR3DECL(int) PGMR3ChangeMode(PVM pVM, PVMCPU pVCpu, PGMMODE enmGuestMode)
* Calc the shadow mode and switcher.
*/
VMMSWITCHER enmSwitcher;
- PGMMODE enmShadowMode = pgmR3CalcShadowMode(pVM, enmGuestMode, pVM->pgm.s.enmHostMode, pVCpu->pgm.s.enmShadowMode, &enmSwitcher);
+ PGMMODE enmShadowMode;
+ enmShadowMode = pgmR3CalcShadowMode(pVM, enmGuestMode, pVM->pgm.s.enmHostMode, pVCpu->pgm.s.enmShadowMode, &enmSwitcher);
#ifdef VBOX_WITH_RAW_MODE
if (enmSwitcher != VMMSWITCHER_INVALID)
@@ -3533,14 +3605,14 @@ int pgmR3ReEnterShadowModeAfterPoolFlush(PVM pVM, PVMCPU pVCpu)
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) pgmR3CmdRam(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) pgmR3CmdRam(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate input.
*/
if (!pVM)
return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: The command requires a VM to be selected.\n");
- if (!pVM->pgm.s.pRamRangesRC)
+ if (!pVM->pgm.s.pRamRangesXR3)
return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Sorry, no Ram is registered.\n");
/*
@@ -3548,7 +3620,7 @@ static DECLCALLBACK(int) pgmR3CmdRam(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pV
*/
int rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "From - To (incl) pvHC\n");
PPGMRAMRANGE pRam;
- for (pRam = pVM->pgm.s.pRamRangesR3; pRam; pRam = pRam->pNextR3)
+ for (pRam = pVM->pgm.s.pRamRangesXR3; pRam; pRam = pRam->pNextR3)
{
rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL,
"%RGp - %RGp %p\n",
@@ -3571,7 +3643,7 @@ static DECLCALLBACK(int) pgmR3CmdRam(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pV
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) pgmR3CmdError(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) pgmR3CmdError(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate input.
@@ -3617,7 +3689,7 @@ static DECLCALLBACK(int) pgmR3CmdError(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) pgmR3CmdSync(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) pgmR3CmdSync(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/** @todo SMP support */
@@ -3653,7 +3725,7 @@ static DECLCALLBACK(int) pgmR3CmdSync(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM p
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) pgmR3CmdAssertCR3(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) pgmR3CmdAssertCR3(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/** @todo SMP support!! */
@@ -3686,7 +3758,7 @@ static DECLCALLBACK(int) pgmR3CmdAssertCR3(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) pgmR3CmdSyncAlways(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) pgmR3CmdSyncAlways(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/** @todo SMP support!! */
PVMCPU pVCpu = &pVM->aCpus[0];
@@ -3724,7 +3796,7 @@ static DECLCALLBACK(int) pgmR3CmdSyncAlways(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) pgmR3CmdPhysToFile(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) pgmR3CmdPhysToFile(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate input.
@@ -3764,9 +3836,9 @@ static DECLCALLBACK(int) pgmR3CmdPhysToFile(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
RT_ZERO(abZeroPg);
pgmLock(pVM);
- for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3;
- pRam && pRam->GCPhys < GCPhysEnd && RT_SUCCESS(rc);
- pRam = pRam->pNextR3)
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3;
+ pRam && pRam->GCPhys < GCPhysEnd && RT_SUCCESS(rc);
+ pRam = pRam->pNextR3)
{
/* fill the gap */
if (pRam->GCPhys > GCPhys && fIncZeroPgs)
diff --git a/src/VBox/VMM/VMMR3/PGMBth.h b/src/VBox/VMM/VMMR3/PGMBth.h
index 7b39c6b94..ac4cb0240 100644
--- a/src/VBox/VMM/VMMR3/PGMBth.h
+++ b/src/VBox/VMM/VMMR3/PGMBth.h
@@ -1,4 +1,4 @@
-/* $Id: PGMBth.h $ */
+/* $Id: PGMBth.h 35333 2010-12-27 12:10:56Z vboxsync $ */
/** @file
* VBox - Page Manager / Monitor, Shadow+Guest Paging Template.
*/
diff --git a/src/VBox/VMM/VMMR3/PGMDbg.cpp b/src/VBox/VMM/VMMR3/PGMDbg.cpp
index 3b395cdfa..fb7b15f8f 100644
--- a/src/VBox/VMM/VMMR3/PGMDbg.cpp
+++ b/src/VBox/VMM/VMMR3/PGMDbg.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMDbg.cpp $ */
+/* $Id: PGMDbg.cpp 37187 2011-05-23 16:11:11Z vboxsync $ */
/** @file
* PGM - Page Manager and Monitor - Debugger & Debugging APIs.
*/
@@ -159,7 +159,7 @@ VMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PVM pVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys
if (HCPhys == 0)
return VERR_INVALID_POINTER;
- for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
pRam;
pRam = pRam->CTX_SUFF(pNext))
{
@@ -621,7 +621,7 @@ VMMR3DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange,
* bother to match across ranges.
*/
pgmLock(pVM);
- for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
pRam;
pRam = pRam->CTX_SUFF(pNext))
{
@@ -792,7 +792,7 @@ VMMR3DECL(int) PGMR3DbgScanVirtual(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, RTGCPTR
int rc = PGMPhysGCPtr2GCPhys(pVCpu, GCPtr, &GCPhys);
if (RT_SUCCESS(rc))
{
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
if ( pPage
&& ( !PGM_PAGE_IS_ZERO(pPage)
|| fAllZero)
@@ -1040,7 +1040,7 @@ static void pgmR3DumpHierarchyShwGuestPageInfo(PPGMR3DUMPHIERARCHYSTATE pState,
if (RT_SUCCESS(rc))
{
pgmLock(pState->pVM);
- PCPGMPAGE pPage = pgmPhysGetPage(&pState->pVM->pgm.s, GCPhys);
+ PCPGMPAGE pPage = pgmPhysGetPage(pState->pVM, GCPhys);
if (pPage)
RTStrPrintf(szPage, sizeof(szPage), "%R[pgmpage]", pPage);
else
@@ -1558,7 +1558,7 @@ static int pgmR3DumpHierarchyShwDoIt(PPGMR3DUMPHIERARCHYSTATE pState, uint64_t c
pState->pHlp->pfnPrintf(pState->pHlp, "cr3=%0*llx", cch, cr3);
if (pState->fDumpPageInfo)
pgmR3DumpHierarchyShwTablePageInfo(pState, cr3 & X86_CR3_AMD64_PAGE_MASK);
- pState->pHlp->pfnPrintf(pState->pHlp, " %s%s\n",
+ pState->pHlp->pfnPrintf(pState->pHlp, " %s%s%s\n",
pszMode,
pState->fNp ? " + Nested Paging" : "",
pState->fNxe ? " + NX" : "");
@@ -1718,7 +1718,7 @@ static void pgmR3DumpHierarchyGstPageInfo(PPGMR3DUMPHIERARCHYSTATE pState, RTGCP
{
char szPage[80];
pgmLock(pState->pVM);
- PCPGMPAGE pPage = pgmPhysGetPage(&pState->pVM->pgm.s, GCPhys);
+ PCPGMPAGE pPage = pgmPhysGetPage(pState->pVM, GCPhys);
if (pPage)
RTStrPrintf(szPage, sizeof(szPage), " %R[pgmpage]", pPage);
else
diff --git a/src/VBox/VMM/VMMR3/PGMGst.h b/src/VBox/VMM/VMMR3/PGMGst.h
index d0b38d85e..cc0773fd1 100644
--- a/src/VBox/VMM/VMMR3/PGMGst.h
+++ b/src/VBox/VMM/VMMR3/PGMGst.h
@@ -1,4 +1,4 @@
-/* $Id: PGMGst.h $ */
+/* $Id: PGMGst.h 35333 2010-12-27 12:10:56Z vboxsync $ */
/** @file
* VBox - Page Manager / Monitor, Guest Paging Template.
*/
diff --git a/src/VBox/VMM/VMMR3/PGMHandler.cpp b/src/VBox/VMM/VMMR3/PGMHandler.cpp
index 9a28be494..b712b17e6 100644
--- a/src/VBox/VMM/VMMR3/PGMHandler.cpp
+++ b/src/VBox/VMM/VMMR3/PGMHandler.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMHandler.cpp $ */
+/* $Id: PGMHandler.cpp 36891 2011-04-29 13:22:57Z vboxsync $ */
/** @file
* PGM - Page Manager / Monitor, Access Handlers.
*/
@@ -159,15 +159,15 @@ void pgmR3HandlerPhysicalUpdateAll(PVM pVM)
*/
static DECLCALLBACK(int) pgmR3HandlerPhysicalOneClear(PAVLROGCPHYSNODECORE pNode, void *pvUser)
{
- PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)pNode;
+ PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)pNode;
PPGMRAMRANGE pRamHint = NULL;
- RTGCPHYS GCPhys = pCur->Core.Key;
- RTUINT cPages = pCur->cPages;
- PPGM pPGM = &((PVM)pvUser)->pgm.s;
+ RTGCPHYS GCPhys = pCur->Core.Key;
+ RTUINT cPages = pCur->cPages;
+ PVM pVM = (PVM)pvUser;
for (;;)
{
PPGMPAGE pPage;
- int rc = pgmPhysGetPageWithHintEx(pPGM, GCPhys, &pPage, &pRamHint);
+ int rc = pgmPhysGetPageWithHintEx(pVM, GCPhys, &pPage, &pRamHint);
if (RT_SUCCESS(rc))
PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, PGM_PAGE_HNDL_PHYS_STATE_NONE);
else
@@ -189,16 +189,16 @@ static DECLCALLBACK(int) pgmR3HandlerPhysicalOneClear(PAVLROGCPHYSNODECORE pNode
*/
static DECLCALLBACK(int) pgmR3HandlerPhysicalOneSet(PAVLROGCPHYSNODECORE pNode, void *pvUser)
{
- PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)pNode;
- unsigned uState = pgmHandlerPhysicalCalcState(pCur);
+ PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)pNode;
+ unsigned uState = pgmHandlerPhysicalCalcState(pCur);
PPGMRAMRANGE pRamHint = NULL;
- RTGCPHYS GCPhys = pCur->Core.Key;
- RTUINT cPages = pCur->cPages;
- PPGM pPGM = &((PVM)pvUser)->pgm.s;
+ RTGCPHYS GCPhys = pCur->Core.Key;
+ RTUINT cPages = pCur->cPages;
+ PVM pVM = (PVM)pvUser;
for (;;)
{
PPGMPAGE pPage;
- int rc = pgmPhysGetPageWithHintEx(pPGM, GCPhys, &pPage, &pRamHint);
+ int rc = pgmPhysGetPageWithHintEx(pVM, GCPhys, &pPage, &pRamHint);
if (RT_SUCCESS(rc))
PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, uState);
else
@@ -470,10 +470,9 @@ VMMDECL(int) PGMHandlerVirtualDeregister(PVM pVM, RTGCPTR GCPtr)
/*
* Reset the flags and remove phys2virt nodes.
*/
- PPGM pPGM = &pVM->pgm.s;
- for (unsigned iPage = 0; iPage < pCur->cPages; iPage++)
+ for (uint32_t iPage = 0; iPage < pCur->cPages; iPage++)
if (pCur->aPhysToVirt[iPage].offNextAlias & PGMPHYS2VIRTHANDLER_IN_TREE)
- pgmHandlerVirtualClearPage(pPGM, pCur, iPage);
+ pgmHandlerVirtualClearPage(pVM, pCur, iPage);
/*
* Schedule CR3 sync.
diff --git a/src/VBox/VMM/VMMR3/PGMMap.cpp b/src/VBox/VMM/VMMR3/PGMMap.cpp
index 6cf537b91..52e249a1b 100644
--- a/src/VBox/VMM/VMMR3/PGMMap.cpp
+++ b/src/VBox/VMM/VMMR3/PGMMap.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMMap.cpp $ */
+/* $Id: PGMMap.cpp 36891 2011-04-29 13:22:57Z vboxsync $ */
/** @file
* PGM - Page Manager, Guest Context Mappings.
*/
@@ -509,7 +509,7 @@ VMMR3DECL(int) PGMR3MappingsFix(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb)
/*
* Ignore the additions mapping fix call if disabled.
*/
- if (!pgmMapAreMappingsEnabled(&pVM->pgm.s))
+ if (!pgmMapAreMappingsEnabled(pVM))
{
Assert(HWACCMIsEnabled(pVM));
return VINF_SUCCESS;
@@ -550,7 +550,7 @@ int pgmR3MappingsFixInternal(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb)
VERR_INVALID_PARAMETER);
AssertMsgReturn(cb && !(cb & X86_PAGE_4M_OFFSET_MASK), ("cb (%#x) is 0 or not aligned on a 4MB address!\n", cb),
VERR_INVALID_PARAMETER);
- AssertReturn(pgmMapAreMappingsEnabled(&pVM->pgm.s), VERR_INTERNAL_ERROR_3);
+ AssertReturn(pgmMapAreMappingsEnabled(pVM), VERR_INTERNAL_ERROR_3);
AssertReturn(pVM->cCpus == 1, VERR_INTERNAL_ERROR_4);
/*
@@ -725,7 +725,7 @@ VMMR3DECL(int) PGMR3MappingsDisable(PVM pVM)
VMMR3DECL(int) PGMR3MappingsUnfix(PVM pVM)
{
Log(("PGMR3MappingsUnfix: fMappingsFixed=%RTbool fMappingsDisabled=%RTbool\n", pVM->pgm.s.fMappingsFixed, pVM->pgm.s.fMappingsDisabled));
- if ( pgmMapAreMappingsEnabled(&pVM->pgm.s)
+ if ( pgmMapAreMappingsEnabled(pVM)
&& ( pVM->pgm.s.fMappingsFixed
|| pVM->pgm.s.fMappingsFixedRestored)
)
@@ -1019,7 +1019,7 @@ static void pgmR3MapSetPDEs(PVM pVM, PPGMMAPPING pMap, unsigned iNewPDE)
PVMCPU pVCpu = VMMGetCpu(pVM);
pgmLock(pVM); /* to avoid assertions */
- Assert(!pgmMapAreMappingsEnabled(&pVM->pgm.s) || PGMGetGuestMode(pVCpu) <= PGMMODE_PAE_NX);
+ Assert(!pgmMapAreMappingsEnabled(pVM) || PGMGetGuestMode(pVCpu) <= PGMMODE_PAE_NX);
pgmMapSetShadowPDEs(pVM, pMap, iNewPDE);
diff --git a/src/VBox/VMM/VMMR3/PGMPhys.cpp b/src/VBox/VMM/VMMR3/PGMPhys.cpp
index 371be9bd1..e720b081d 100644
--- a/src/VBox/VMM/VMMR3/PGMPhys.cpp
+++ b/src/VBox/VMM/VMMR3/PGMPhys.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMPhys.cpp $ */
+/* $Id: PGMPhys.cpp 37942 2011-07-14 09:08:30Z vboxsync $ */
/** @file
* PGM - Page Manager and Monitor, Physical Memory Addressing.
*/
@@ -118,12 +118,9 @@ VMMR3DECL(int) PGMR3PhysReadExternal(PVM pVM, RTGCPHYS GCPhys, void *pvBuf, size
/*
* Copy loop on ram ranges.
*/
- PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+ PPGMRAMRANGE pRam = pgmPhysGetRangeAtOrAbove(pVM, GCPhys);
for (;;)
{
- /* Find range. */
- while (pRam && GCPhys > pRam->GCPhysLast)
- pRam = pRam->CTX_SUFF(pNext);
/* Inside range or not? */
if (pRam && GCPhys >= pRam->GCPhys)
{
@@ -185,9 +182,7 @@ VMMR3DECL(int) PGMR3PhysReadExternal(PVM pVM, RTGCPHYS GCPhys, void *pvBuf, size
/*
* Unassigned address space.
*/
- if (!pRam)
- break;
- size_t cb = pRam->GCPhys - GCPhys;
+ size_t cb = pRam ? pRam->GCPhys - GCPhys : ~(size_t)0;
if (cb >= cbRead)
{
memset(pvBuf, 0xff, cbRead);
@@ -199,6 +194,10 @@ VMMR3DECL(int) PGMR3PhysReadExternal(PVM pVM, RTGCPHYS GCPhys, void *pvBuf, size
pvBuf = (char *)pvBuf + cb;
GCPhys += cb;
}
+
+ /* Advance range if necessary. */
+ while (pRam && GCPhys > pRam->GCPhysLast)
+ pRam = pRam->CTX_SUFF(pNext);
} /* Ram range walk */
pgmUnlock(pVM);
@@ -249,12 +248,9 @@ VMMDECL(int) PGMR3PhysWriteExternal(PVM pVM, RTGCPHYS GCPhys, const void *pvBuf,
/*
* Copy loop on ram ranges, stop when we hit something difficult.
*/
- PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+ PPGMRAMRANGE pRam = pgmPhysGetRangeAtOrAbove(pVM, GCPhys);
for (;;)
{
- /* Find range. */
- while (pRam && GCPhys > pRam->GCPhysLast)
- pRam = pRam->CTX_SUFF(pNext);
/* Inside range or not? */
if (pRam && GCPhys >= pRam->GCPhys)
{
@@ -331,6 +327,10 @@ VMMDECL(int) PGMR3PhysWriteExternal(PVM pVM, RTGCPHYS GCPhys, const void *pvBuf,
pvBuf = (const char *)pvBuf + cb;
GCPhys += cb;
}
+
+ /* Advance range if necessary. */
+ while (pRam && GCPhys > pRam->GCPhysLast)
+ pRam = pRam->CTX_SUFF(pNext);
} /* Ram range walk */
pgmUnlock(pVM);
@@ -360,7 +360,7 @@ static DECLCALLBACK(int) pgmR3PhysGCPhys2CCPtrDelegated(PVM pVM, PRTGCPHYS pGCPh
if (RT_SUCCESS(rc))
{
PPGMPAGEMAPTLBE pTlbe;
- int rc2 = pgmPhysPageQueryTlbe(&pVM->pgm.s, *pGCPhys, &pTlbe);
+ int rc2 = pgmPhysPageQueryTlbe(pVM, *pGCPhys, &pTlbe);
AssertFatalRC(rc2);
PPGMPAGE pPage = pTlbe->pPage;
if (PGM_PAGE_IS_MMIO(pPage))
@@ -430,7 +430,7 @@ VMMR3DECL(int) PGMR3PhysGCPhys2CCPtrExternal(PVM pVM, RTGCPHYS GCPhys, void **pp
* Query the Physical TLB entry for the page (may fail).
*/
PPGMPAGEMAPTLBE pTlbe;
- rc = pgmPhysPageQueryTlbe(&pVM->pgm.s, GCPhys, &pTlbe);
+ rc = pgmPhysPageQueryTlbe(pVM, GCPhys, &pTlbe);
if (RT_SUCCESS(rc))
{
PPGMPAGE pPage = pTlbe->pPage;
@@ -531,7 +531,7 @@ VMMR3DECL(int) PGMR3PhysGCPhys2CCPtrReadOnlyExternal(PVM pVM, RTGCPHYS GCPhys, v
* Query the Physical TLB entry for the page (may fail).
*/
PPGMPAGEMAPTLBE pTlbe;
- rc = pgmPhysPageQueryTlbe(&pVM->pgm.s, GCPhys, &pTlbe);
+ rc = pgmPhysPageQueryTlbe(pVM, GCPhys, &pTlbe);
if (RT_SUCCESS(rc))
{
PPGMPAGE pPage = pTlbe->pPage;
@@ -578,6 +578,147 @@ VMMR3DECL(int) PGMR3PhysGCPhys2CCPtrReadOnlyExternal(PVM pVM, RTGCPHYS GCPhys, v
}
+#define MAKE_LEAF(a_pNode) \
+ do { \
+ (a_pNode)->pLeftR3 = NIL_RTR3PTR; \
+ (a_pNode)->pRightR3 = NIL_RTR3PTR; \
+ (a_pNode)->pLeftR0 = NIL_RTR0PTR; \
+ (a_pNode)->pRightR0 = NIL_RTR0PTR; \
+ (a_pNode)->pLeftRC = NIL_RTRCPTR; \
+ (a_pNode)->pRightRC = NIL_RTRCPTR; \
+ } while (0)
+
+#define INSERT_LEFT(a_pParent, a_pNode) \
+ do { \
+ (a_pParent)->pLeftR3 = (a_pNode); \
+ (a_pParent)->pLeftR0 = (a_pNode)->pSelfR0; \
+ (a_pParent)->pLeftRC = (a_pNode)->pSelfRC; \
+ } while (0)
+#define INSERT_RIGHT(a_pParent, a_pNode) \
+ do { \
+ (a_pParent)->pRightR3 = (a_pNode); \
+ (a_pParent)->pRightR0 = (a_pNode)->pSelfR0; \
+ (a_pParent)->pRightRC = (a_pNode)->pSelfRC; \
+ } while (0)
+
+
+/**
+ * Recursive tree builder.
+ *
+ * @param ppRam Pointer to the iterator variable.
+ * @param iHeight The hight about normal leaf nodes. Inserts a leaf
+ * node if 0.
+ */
+static PPGMRAMRANGE pgmR3PhysRebuildRamRangeSearchTreesRecursively(PPGMRAMRANGE *ppRam, int iDepth)
+{
+ PPGMRAMRANGE pRam;
+ if (iDepth <= 0)
+ {
+ /*
+ * Leaf node.
+ */
+ pRam = *ppRam;
+ if (pRam)
+ {
+ *ppRam = pRam->pNextR3;
+ MAKE_LEAF(pRam);
+ }
+ }
+ else
+ {
+
+ /*
+ * Intermediate node.
+ */
+ PPGMRAMRANGE pLeft = pgmR3PhysRebuildRamRangeSearchTreesRecursively(ppRam, iDepth - 1);
+
+ pRam = *ppRam;
+ if (!pRam)
+ return pLeft;
+ *ppRam = pRam->pNextR3;
+ MAKE_LEAF(pRam);
+ INSERT_LEFT(pRam, pLeft);
+
+ PPGMRAMRANGE pRight = pgmR3PhysRebuildRamRangeSearchTreesRecursively(ppRam, iDepth - 1);
+ if (pRight)
+ INSERT_RIGHT(pRam, pRight);
+ }
+ return pRam;
+}
+
+
+/**
+ * Rebuilds the RAM range search trees.
+ *
+ * @param pVM The VM handle.
+ */
+static void pgmR3PhysRebuildRamRangeSearchTrees(PVM pVM)
+{
+
+ /*
+ * Create the reasonably balanced tree in a sequential fashion.
+ * For simplicity (laziness) we use standard recursion here.
+ */
+ int iDepth = 0;
+ PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3;
+ PPGMRAMRANGE pRoot = pgmR3PhysRebuildRamRangeSearchTreesRecursively(&pRam, 0);
+ while (pRam)
+ {
+ PPGMRAMRANGE pLeft = pRoot;
+
+ pRoot = pRam;
+ pRam = pRam->pNextR3;
+ MAKE_LEAF(pRoot);
+ INSERT_LEFT(pRoot, pLeft);
+
+ PPGMRAMRANGE pRight = pgmR3PhysRebuildRamRangeSearchTreesRecursively(&pRam, iDepth);
+ if (pRight)
+ INSERT_RIGHT(pRoot, pRight);
+ /** @todo else: rotate the tree. */
+
+ iDepth++;
+ }
+
+ pVM->pgm.s.pRamRangeTreeR3 = pRoot;
+ pVM->pgm.s.pRamRangeTreeR0 = pRoot ? pRoot->pSelfR0 : NIL_RTR0PTR;
+ pVM->pgm.s.pRamRangeTreeRC = pRoot ? pRoot->pSelfRC : NIL_RTRCPTR;
+
+#ifdef VBOX_STRICT
+ /*
+ * Verify that the above code works.
+ */
+ unsigned cRanges = 0;
+ for (pRam = pVM->pgm.s.pRamRangesXR3; pRam; pRam = pRam->pNextR3)
+ cRanges++;
+ Assert(cRanges > 0);
+
+ unsigned cMaxDepth = ASMBitLastSetU32(cRanges);
+ if ((1U << cMaxDepth) < cRanges)
+ cMaxDepth++;
+
+ for (pRam = pVM->pgm.s.pRamRangesXR3; pRam; pRam = pRam->pNextR3)
+ {
+ unsigned cDepth = 0;
+ PPGMRAMRANGE pRam2 = pVM->pgm.s.pRamRangeTreeR3;
+ for (;;)
+ {
+ if (pRam == pRam2)
+ break;
+ Assert(pRam2);
+ if (pRam->GCPhys < pRam2->GCPhys)
+ pRam2 = pRam2->pLeftR3;
+ else
+ pRam2 = pRam2->pRightR3;
+ }
+ AssertMsg(cDepth <= cMaxDepth, ("cDepth=%d cMaxDepth=%d\n", cDepth, cMaxDepth));
+ }
+#endif /* VBOX_STRICT */
+}
+
+#undef MAKE_LEAF
+#undef INSERT_LEFT
+#undef INSERT_RIGHT
+
/**
* Relinks the RAM ranges using the pSelfRC and pSelfR0 pointers.
*
@@ -590,7 +731,7 @@ void pgmR3PhysRelinkRamRanges(PVM pVM)
PPGMRAMRANGE pCur;
#ifdef VBOX_STRICT
- for (pCur = pVM->pgm.s.pRamRangesR3; pCur; pCur = pCur->pNextR3)
+ for (pCur = pVM->pgm.s.pRamRangesXR3; pCur; pCur = pCur->pNextR3)
{
Assert((pCur->fFlags & PGM_RAM_RANGE_FLAGS_FLOATING) || pCur->pSelfR0 == MMHyperCCToR0(pVM, pCur));
Assert((pCur->fFlags & PGM_RAM_RANGE_FLAGS_FLOATING) || pCur->pSelfRC == MMHyperCCToRC(pVM, pCur));
@@ -598,17 +739,17 @@ void pgmR3PhysRelinkRamRanges(PVM pVM)
Assert((pCur->GCPhysLast & PAGE_OFFSET_MASK) == PAGE_OFFSET_MASK);
Assert((pCur->cb & PAGE_OFFSET_MASK) == 0);
Assert(pCur->cb == pCur->GCPhysLast - pCur->GCPhys + 1);
- for (PPGMRAMRANGE pCur2 = pVM->pgm.s.pRamRangesR3; pCur2; pCur2 = pCur2->pNextR3)
+ for (PPGMRAMRANGE pCur2 = pVM->pgm.s.pRamRangesXR3; pCur2; pCur2 = pCur2->pNextR3)
Assert( pCur2 == pCur
|| strcmp(pCur2->pszDesc, pCur->pszDesc)); /** @todo fix MMIO ranges!! */
}
#endif
- pCur = pVM->pgm.s.pRamRangesR3;
+ pCur = pVM->pgm.s.pRamRangesXR3;
if (pCur)
{
- pVM->pgm.s.pRamRangesR0 = pCur->pSelfR0;
- pVM->pgm.s.pRamRangesRC = pCur->pSelfRC;
+ pVM->pgm.s.pRamRangesXR0 = pCur->pSelfR0;
+ pVM->pgm.s.pRamRangesXRC = pCur->pSelfRC;
for (; pCur->pNextR3; pCur = pCur->pNextR3)
{
@@ -621,10 +762,12 @@ void pgmR3PhysRelinkRamRanges(PVM pVM)
}
else
{
- Assert(pVM->pgm.s.pRamRangesR0 == NIL_RTR0PTR);
- Assert(pVM->pgm.s.pRamRangesRC == NIL_RTRCPTR);
+ Assert(pVM->pgm.s.pRamRangesXR0 == NIL_RTR0PTR);
+ Assert(pVM->pgm.s.pRamRangesXRC == NIL_RTRCPTR);
}
ASMAtomicIncU32(&pVM->pgm.s.idRamRangesGen);
+
+ pgmR3PhysRebuildRamRangeSearchTrees(pVM);
}
@@ -643,7 +786,7 @@ static void pgmR3PhysLinkRamRange(PVM pVM, PPGMRAMRANGE pNew, PPGMRAMRANGE pPrev
pgmLock(pVM);
- PPGMRAMRANGE pRam = pPrev ? pPrev->pNextR3 : pVM->pgm.s.pRamRangesR3;
+ PPGMRAMRANGE pRam = pPrev ? pPrev->pNextR3 : pVM->pgm.s.pRamRangesXR3;
pNew->pNextR3 = pRam;
pNew->pNextR0 = pRam ? pRam->pSelfR0 : NIL_RTR0PTR;
pNew->pNextRC = pRam ? pRam->pSelfRC : NIL_RTRCPTR;
@@ -656,11 +799,13 @@ static void pgmR3PhysLinkRamRange(PVM pVM, PPGMRAMRANGE pNew, PPGMRAMRANGE pPrev
}
else
{
- pVM->pgm.s.pRamRangesR3 = pNew;
- pVM->pgm.s.pRamRangesR0 = pNew->pSelfR0;
- pVM->pgm.s.pRamRangesRC = pNew->pSelfRC;
+ pVM->pgm.s.pRamRangesXR3 = pNew;
+ pVM->pgm.s.pRamRangesXR0 = pNew->pSelfR0;
+ pVM->pgm.s.pRamRangesXRC = pNew->pSelfRC;
}
ASMAtomicIncU32(&pVM->pgm.s.idRamRangesGen);
+
+ pgmR3PhysRebuildRamRangeSearchTrees(pVM);
pgmUnlock(pVM);
}
@@ -674,7 +819,7 @@ static void pgmR3PhysLinkRamRange(PVM pVM, PPGMRAMRANGE pNew, PPGMRAMRANGE pPrev
*/
static void pgmR3PhysUnlinkRamRange2(PVM pVM, PPGMRAMRANGE pRam, PPGMRAMRANGE pPrev)
{
- Assert(pPrev ? pPrev->pNextR3 == pRam : pVM->pgm.s.pRamRangesR3 == pRam);
+ Assert(pPrev ? pPrev->pNextR3 == pRam : pVM->pgm.s.pRamRangesXR3 == pRam);
Assert((pRam->fFlags & PGM_RAM_RANGE_FLAGS_FLOATING) || pRam->pSelfR0 == MMHyperCCToR0(pVM, pRam));
Assert((pRam->fFlags & PGM_RAM_RANGE_FLAGS_FLOATING) || pRam->pSelfRC == MMHyperCCToRC(pVM, pRam));
@@ -689,12 +834,14 @@ static void pgmR3PhysUnlinkRamRange2(PVM pVM, PPGMRAMRANGE pRam, PPGMRAMRANGE pP
}
else
{
- Assert(pVM->pgm.s.pRamRangesR3 == pRam);
- pVM->pgm.s.pRamRangesR3 = pNext;
- pVM->pgm.s.pRamRangesR0 = pNext ? pNext->pSelfR0 : NIL_RTR0PTR;
- pVM->pgm.s.pRamRangesRC = pNext ? pNext->pSelfRC : NIL_RTRCPTR;
+ Assert(pVM->pgm.s.pRamRangesXR3 == pRam);
+ pVM->pgm.s.pRamRangesXR3 = pNext;
+ pVM->pgm.s.pRamRangesXR0 = pNext ? pNext->pSelfR0 : NIL_RTR0PTR;
+ pVM->pgm.s.pRamRangesXRC = pNext ? pNext->pSelfRC : NIL_RTRCPTR;
}
ASMAtomicIncU32(&pVM->pgm.s.idRamRangesGen);
+
+ pgmR3PhysRebuildRamRangeSearchTrees(pVM);
pgmUnlock(pVM);
}
@@ -711,7 +858,7 @@ static void pgmR3PhysUnlinkRamRange(PVM pVM, PPGMRAMRANGE pRam)
/* find prev. */
PPGMRAMRANGE pPrev = NULL;
- PPGMRAMRANGE pCur = pVM->pgm.s.pRamRangesR3;
+ PPGMRAMRANGE pCur = pVM->pgm.s.pRamRangesXR3;
while (pCur != pRam)
{
pPrev = pCur;
@@ -736,7 +883,7 @@ static void pgmR3PhysUnlinkRamRange(PVM pVM, PPGMRAMRANGE pRam)
*/
static int pgmR3PhysFreePageRange(PVM pVM, PPGMRAMRANGE pRam, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, uint8_t uType)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
uint32_t cPendingPages = 0;
PGMMFREEPAGESREQ pReq;
int rc = GMMR3FreePagesPrepare(pVM, &pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE);
@@ -750,7 +897,7 @@ static int pgmR3PhysFreePageRange(PVM pVM, PPGMRAMRANGE pRam, RTGCPHYS GCPhys, R
rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPageDst, GCPhys);
AssertLogRelRCReturn(rc, rc); /* We're done for if this goes wrong. */
- PGM_PAGE_SET_TYPE(pPageDst, uType);
+ PGM_PAGE_SET_TYPE(pVM, pPageDst, uType);
GCPhys += PAGE_SIZE;
pPageDst++;
@@ -808,11 +955,11 @@ static DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysChangeMemBalloonRendezvous(PVM pVM, P
/* Iterate the pages. */
for (unsigned i = 0; i < cPages; i++)
{
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPhysPage[i]);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, paPhysPage[i]);
if ( pPage == NULL
- || pPage->uTypeY != PGMPAGETYPE_RAM)
+ || PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_RAM)
{
- Log(("pgmR3PhysChangeMemBalloonRendezvous: invalid physical page %RGp pPage->u3Type=%d\n", paPhysPage[i], (pPage) ? pPage->uTypeY : 0));
+ Log(("pgmR3PhysChangeMemBalloonRendezvous: invalid physical page %RGp pPage->u3Type=%d\n", paPhysPage[i], pPage ? PGM_PAGE_GET_TYPE(pPage) : 0));
break;
}
@@ -829,7 +976,7 @@ static DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysChangeMemBalloonRendezvous(PVM pVM, P
return rc;
}
Assert(PGM_PAGE_IS_ZERO(pPage));
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_BALLOONED);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_BALLOONED);
}
if (cPendingPages)
@@ -849,15 +996,15 @@ static DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysChangeMemBalloonRendezvous(PVM pVM, P
/* Iterate the pages. */
for (unsigned i = 0; i < cPages; i++)
{
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPhysPage[i]);
- AssertBreak(pPage && pPage->uTypeY == PGMPAGETYPE_RAM);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, paPhysPage[i]);
+ AssertBreak(pPage && PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_RAM);
LogFlow(("Free ballooned page: %RGp\n", paPhysPage[i]));
Assert(PGM_PAGE_IS_BALLOONED(pPage));
/* Change back to zero page. */
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ZERO);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ZERO);
}
/* Note that we currently do not map any ballooned pages in our shadow page tables, so no need to flush the pgm pool. */
@@ -959,7 +1106,8 @@ VMMR3DECL(int) PGMR3PhysChangeMemBalloon(PVM pVM, bool fInflate, unsigned cPages
}
/**
- * Rendezvous callback used by PGMR3WriteProtectRAM that write protects all physical RAM
+ * Rendezvous callback used by PGMR3WriteProtectRAM that write protects all
+ * physical RAM.
*
* This is only called on one of the EMTs while the other ones are waiting for
* it to complete this function.
@@ -967,11 +1115,12 @@ VMMR3DECL(int) PGMR3PhysChangeMemBalloon(PVM pVM, bool fInflate, unsigned cPages
* @returns VINF_SUCCESS (VBox strict status code).
* @param pVM The VM handle.
* @param pVCpu The VMCPU for the EMT we're being called on. Unused.
- * @param pvUser User parameter
+ * @param pvUser User parameter, unused.
*/
static DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysWriteProtectRAMRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)
{
int rc = VINF_SUCCESS;
+ NOREF(pvUser);
pgmLock(pVM);
#ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT
@@ -980,12 +1129,12 @@ static DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysWriteProtectRAMRendezvous(PVM pVM, PV
/** @todo pointless to write protect the physical page pointed to by RSP. */
- for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
pRam;
pRam = pRam->CTX_SUFF(pNext))
{
- unsigned cPages = pRam->cb >> PAGE_SHIFT;
- for (unsigned iPage = 0; iPage < cPages; iPage++)
+ uint32_t cPages = pRam->cb >> PAGE_SHIFT;
+ for (uint32_t iPage = 0; iPage < cPages; iPage++)
{
PPGMPAGE pPage = &pRam->aPages[iPage];
PGMPAGETYPE enmPageType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage);
@@ -1003,7 +1152,7 @@ static DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysWriteProtectRAMRendezvous(PVM pVM, PV
* monitoring if the page is known to be very busy. */
if (PGM_PAGE_IS_WRITTEN_TO(pPage))
{
- PGM_PAGE_CLEAR_WRITTEN_TO(pPage);
+ PGM_PAGE_CLEAR_WRITTEN_TO(pVM, pPage);
/* Remember this dirty page for the next (memory) sync. */
PGM_PAGE_SET_FT_DIRTY(pPage);
}
@@ -1047,79 +1196,80 @@ VMMR3DECL(int) PGMR3PhysWriteProtectRAM(PVM pVM)
}
/**
- * Enumerate all dirty FT pages
+ * Enumerate all dirty FT pages.
*
* @returns VBox status code.
* @param pVM The VM handle.
- * @param pfnEnum Enumerate callback handler
- * @param pvUser Enumerate callback handler parameter
+ * @param pfnEnum Enumerate callback handler.
+ * @param pvUser Enumerate callback handler parameter.
*/
VMMR3DECL(int) PGMR3PhysEnumDirtyFTPages(PVM pVM, PFNPGMENUMDIRTYFTPAGES pfnEnum, void *pvUser)
{
int rc = VINF_SUCCESS;
pgmLock(pVM);
- for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
pRam;
pRam = pRam->CTX_SUFF(pNext))
{
- unsigned cPages = pRam->cb >> PAGE_SHIFT;
- for (unsigned iPage = 0; iPage < cPages; iPage++)
+ uint32_t cPages = pRam->cb >> PAGE_SHIFT;
+ for (uint32_t iPage = 0; iPage < cPages; iPage++)
{
- PPGMPAGE pPage = &pRam->aPages[iPage];
+ PPGMPAGE pPage = &pRam->aPages[iPage];
PGMPAGETYPE enmPageType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage);
if ( RT_LIKELY(enmPageType == PGMPAGETYPE_RAM)
|| enmPageType == PGMPAGETYPE_MMIO2)
{
/*
- * A RAM page.
- */
+ * A RAM page.
+ */
switch (PGM_PAGE_GET_STATE(pPage))
{
- case PGM_PAGE_STATE_ALLOCATED:
- case PGM_PAGE_STATE_WRITE_MONITORED:
- if ( !PGM_PAGE_IS_WRITTEN_TO(pPage) /* not very recently updated? */
- && PGM_PAGE_IS_FT_DIRTY(pPage))
- {
- unsigned cbPageRange = PAGE_SIZE;
- unsigned iPageClean = iPage + 1;
- RTGCPHYS GCPhysPage = pRam->GCPhys + iPage * PAGE_SIZE;
- uint8_t *pu8Page = NULL;
- PGMPAGEMAPLOCK Lock;
-
- /* Find the next clean page, so we can merge adjacent dirty pages. */
- for (; iPageClean < cPages; iPageClean++)
+ case PGM_PAGE_STATE_ALLOCATED:
+ case PGM_PAGE_STATE_WRITE_MONITORED:
+ if ( !PGM_PAGE_IS_WRITTEN_TO(pPage) /* not very recently updated? */
+ && PGM_PAGE_IS_FT_DIRTY(pPage))
{
- PPGMPAGE pPageNext = &pRam->aPages[iPageClean];
- if ( RT_UNLIKELY(PGM_PAGE_GET_TYPE(pPageNext) != PGMPAGETYPE_RAM)
- || PGM_PAGE_GET_STATE(pPageNext) != PGM_PAGE_STATE_ALLOCATED
- || PGM_PAGE_IS_WRITTEN_TO(pPageNext)
- || !PGM_PAGE_IS_FT_DIRTY(pPageNext)
- /* Crossing a chunk boundary? */
- || (GCPhysPage & GMM_PAGEID_IDX_MASK) != ((GCPhysPage + cbPageRange) & GMM_PAGEID_IDX_MASK)
- )
- break;
-
- cbPageRange += PAGE_SIZE;
- }
+ unsigned cbPageRange = PAGE_SIZE;
+ unsigned iPageClean = iPage + 1;
+ RTGCPHYS GCPhysPage = pRam->GCPhys + iPage * PAGE_SIZE;
+ uint8_t *pu8Page = NULL;
+ PGMPAGEMAPLOCK Lock;
+
+ /* Find the next clean page, so we can merge adjacent dirty pages. */
+ for (; iPageClean < cPages; iPageClean++)
+ {
+ PPGMPAGE pPageNext = &pRam->aPages[iPageClean];
+ if ( RT_UNLIKELY(PGM_PAGE_GET_TYPE(pPageNext) != PGMPAGETYPE_RAM)
+ || PGM_PAGE_GET_STATE(pPageNext) != PGM_PAGE_STATE_ALLOCATED
+ || PGM_PAGE_IS_WRITTEN_TO(pPageNext)
+ || !PGM_PAGE_IS_FT_DIRTY(pPageNext)
+ /* Crossing a chunk boundary? */
+ || (GCPhysPage & GMM_PAGEID_IDX_MASK) != ((GCPhysPage + cbPageRange) & GMM_PAGEID_IDX_MASK)
+ )
+ break;
+
+ cbPageRange += PAGE_SIZE;
+ }
- rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhysPage, (const void **)&pu8Page, &Lock);
- if (RT_SUCCESS(rc))
- {
- /** @todo this is risky; the range might be changed, but little choice as the sync costs a lot of time */
- pgmUnlock(pVM);
- pfnEnum(pVM, GCPhysPage, pu8Page, cbPageRange, pvUser);
- pgmLock(pVM);
- PGMPhysReleasePageMappingLock(pVM, &Lock);
- }
+ rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhysPage, (const void **)&pu8Page, &Lock);
+ if (RT_SUCCESS(rc))
+ {
+ /** @todo this is risky; the range might be changed, but little choice as the sync
+ * costs a lot of time. */
+ pgmUnlock(pVM);
+ pfnEnum(pVM, GCPhysPage, pu8Page, cbPageRange, pvUser);
+ pgmLock(pVM);
+ PGMPhysReleasePageMappingLock(pVM, &Lock);
+ }
- for (iPage; iPage < iPageClean; iPage++)
- PGM_PAGE_CLEAR_FT_DIRTY(&pRam->aPages[iPage]);
+ for (iPage; iPage < iPageClean; iPage++)
+ PGM_PAGE_CLEAR_FT_DIRTY(&pRam->aPages[iPage]);
- iPage = iPageClean - 1;
- }
- break;
+ iPage = iPageClean - 1;
+ }
+ break;
}
}
}
@@ -1141,7 +1291,7 @@ VMMR3DECL(uint32_t) PGMR3PhysGetRamRangeCount(PVM pVM)
pgmLock(pVM);
uint32_t cRamRanges = 0;
- for (PPGMRAMRANGE pCur = pVM->pgm.s.CTX_SUFF(pRamRanges); pCur; pCur = pCur->CTX_SUFF(pNext))
+ for (PPGMRAMRANGE pCur = pVM->pgm.s.CTX_SUFF(pRamRangesX); pCur; pCur = pCur->CTX_SUFF(pNext))
cRamRanges++;
pgmUnlock(pVM);
return cRamRanges;
@@ -1167,7 +1317,7 @@ VMMR3DECL(int) PGMR3PhysGetRange(PVM pVM, uint32_t iRange, PRTGCPHYS pGCPhysStar
pgmLock(pVM);
uint32_t iCurRange = 0;
- for (PPGMRAMRANGE pCur = pVM->pgm.s.CTX_SUFF(pRamRanges); pCur; pCur = pCur->CTX_SUFF(pNext), iCurRange++)
+ for (PPGMRAMRANGE pCur = pVM->pgm.s.CTX_SUFF(pRamRangesX); pCur; pCur = pCur->CTX_SUFF(pNext), iCurRange++)
if (iCurRange == iRange)
{
if (pGCPhysStart)
@@ -1190,63 +1340,91 @@ VMMR3DECL(int) PGMR3PhysGetRange(PVM pVM, uint32_t iRange, PRTGCPHYS pGCPhysStar
*
* @returns VBox status code.
* @param pVM The VM handle.
- * @param puTotalAllocSize Pointer to total allocated memory inside VMMR0 (in bytes)
- * @param puTotalFreeSize Pointer to total free (allocated but not used yet) memory inside VMMR0 (in bytes)
- * @param puTotalBalloonSize Pointer to total ballooned memory inside VMMR0 (in bytes)
- * @param puTotalSharedSize Pointer to total shared memory inside VMMR0 (in bytes)
+ * @param pcbAllocMem Where to return the amount of memory allocated
+ * by VMs.
+ * @param pcbFreeMem Where to return the amount of memory that is
+ * allocated from the host but not currently used
+ * by any VMs.
+ * @param pcbBallonedMem Where to return the sum of memory that is
+ * currently ballooned by the VMs.
+ * @param pcbSharedMem Where to return the amount of memory that is
+ * currently shared.
*/
-VMMR3DECL(int) PGMR3QueryVMMMemoryStats(PVM pVM, uint64_t *puTotalAllocSize, uint64_t *puTotalFreeSize, uint64_t *puTotalBalloonSize, uint64_t *puTotalSharedSize)
+VMMR3DECL(int) PGMR3QueryGlobalMemoryStats(PVM pVM, uint64_t *pcbAllocMem, uint64_t *pcbFreeMem,
+ uint64_t *pcbBallonedMem, uint64_t *pcbSharedMem)
{
- int rc;
-
- uint64_t cAllocPages = 0, cFreePages = 0, cBalloonPages = 0, cSharedPages = 0;
- rc = GMMR3QueryHypervisorMemoryStats(pVM, &cAllocPages, &cFreePages, &cBalloonPages, &cSharedPages);
+ uint64_t cAllocPages = 0;
+ uint64_t cFreePages = 0;
+ uint64_t cBalloonPages = 0;
+ uint64_t cSharedPages = 0;
+ int rc = GMMR3QueryHypervisorMemoryStats(pVM, &cAllocPages, &cFreePages, &cBalloonPages, &cSharedPages);
AssertRCReturn(rc, rc);
- if (puTotalAllocSize)
- *puTotalAllocSize = cAllocPages * _4K;
+ if (pcbAllocMem)
+ *pcbAllocMem = cAllocPages * _4K;
- if (puTotalFreeSize)
- *puTotalFreeSize = cFreePages * _4K;
+ if (pcbFreeMem)
+ *pcbFreeMem = cFreePages * _4K;
- if (puTotalBalloonSize)
- *puTotalBalloonSize = cBalloonPages * _4K;
+ if (pcbBallonedMem)
+ *pcbBallonedMem = cBalloonPages * _4K;
- if (puTotalSharedSize)
- *puTotalSharedSize = cSharedPages * _4K;
+ if (pcbSharedMem)
+ *pcbSharedMem = cSharedPages * _4K;
- Log(("PGMR3QueryVMMMemoryStats: all=%x free=%x ballooned=%x shared=%x\n", cAllocPages, cFreePages, cBalloonPages, cSharedPages));
+ Log(("PGMR3QueryVMMMemoryStats: all=%llx free=%llx ballooned=%llx shared=%llx\n",
+ cAllocPages, cFreePages, cBalloonPages, cSharedPages));
return VINF_SUCCESS;
}
+
/**
- * Query memory stats for the VM
+ * Query memory stats for the VM.
*
* @returns VBox status code.
* @param pVM The VM handle.
- * @param puTotalAllocSize Pointer to total allocated memory inside the VM (in bytes)
- * @param puTotalFreeSize Pointer to total free (allocated but not used yet) memory inside the VM (in bytes)
- * @param puTotalBalloonSize Pointer to total ballooned memory inside the VM (in bytes)
- * @param puTotalSharedSize Pointer to total shared memory inside the VM (in bytes)
+ * @param pcbTotalMem Where to return total amount memory the VM may
+ * possibly use.
+ * @param pcbPrivateMem Where to return the amount of private memory
+ * currently allocated.
+ * @param pcbSharedMem Where to return the amount of actually shared
+ * memory currently used by the VM.
+ * @param pcbZeroMem Where to return the amount of memory backed by
+ * zero pages.
+ *
+ * @remarks The total mem is normally larger than the sum of the three
+ * components. There are two reasons for this, first the amount of
+ * shared memory is what we're sure is shared instead of what could
+ * possibly be shared with someone. Secondly, because the total may
+ * include some pure MMIO pages that doesn't go into any of the three
+ * sub-counts.
+ *
+ * @todo Why do we return reused shared pages instead of anything that could
+ * potentially be shared? Doesn't this mean the first VM gets a much
+ * lower number of shared pages?
*/
-VMMR3DECL(int) PGMR3QueryMemoryStats(PVM pVM, uint64_t *pulTotalMem, uint64_t *pulPrivateMem, uint64_t *puTotalSharedMem, uint64_t *puTotalZeroMem)
+VMMR3DECL(int) PGMR3QueryMemoryStats(PVM pVM, uint64_t *pcbTotalMem, uint64_t *pcbPrivateMem,
+ uint64_t *pcbSharedMem, uint64_t *pcbZeroMem)
{
- if (pulTotalMem)
- *pulTotalMem = (uint64_t)pVM->pgm.s.cAllPages * _4K;
+ VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
+
+ if (pcbTotalMem)
+ *pcbTotalMem = (uint64_t)pVM->pgm.s.cAllPages * PAGE_SIZE;
- if (pulPrivateMem)
- *pulPrivateMem = (uint64_t)pVM->pgm.s.cPrivatePages * _4K;
+ if (pcbPrivateMem)
+ *pcbPrivateMem = (uint64_t)pVM->pgm.s.cPrivatePages * PAGE_SIZE;
- if (puTotalSharedMem)
- *puTotalSharedMem = (uint64_t)pVM->pgm.s.cReusedSharedPages * _4K;
+ if (pcbSharedMem)
+ *pcbSharedMem = (uint64_t)pVM->pgm.s.cReusedSharedPages * PAGE_SIZE;
- if (puTotalZeroMem)
- *puTotalZeroMem = (uint64_t)pVM->pgm.s.cZeroPages * _4K;
+ if (pcbZeroMem)
+ *pcbZeroMem = (uint64_t)pVM->pgm.s.cZeroPages * PAGE_SIZE;
Log(("PGMR3QueryMemoryStats: all=%x private=%x reused=%x zero=%x\n", pVM->pgm.s.cAllPages, pVM->pgm.s.cPrivatePages, pVM->pgm.s.cReusedSharedPages, pVM->pgm.s.cZeroPages));
return VINF_SUCCESS;
}
+
/**
* PGMR3PhysRegisterRam worker that initializes and links a RAM range.
*
@@ -1307,12 +1485,20 @@ static DECLCALLBACK(bool) pgmR3PhysRamRangeRelocate(PVM pVM, RTGCPTR GCPtrOld, R
{
case PGMRELOCATECALL_SUGGEST:
return true;
+
case PGMRELOCATECALL_RELOCATE:
{
- /* Update myself and then relink all the ranges. */
+ /*
+ * Update myself, then relink all the ranges and flush the RC TLB.
+ */
pgmLock(pVM);
+
pRam->pSelfRC = (RTRCPTR)(GCPtrNew + PAGE_SIZE);
+
pgmR3PhysRelinkRamRanges(pVM);
+ for (unsigned i = 0; i < PGM_RAMRANGE_TLB_ENTRIES; i++)
+ pVM->pgm.s.apRamRangesTlbRC[i] = NIL_RTRCPTR;
+
pgmUnlock(pVM);
return true;
}
@@ -1439,7 +1625,7 @@ VMMR3DECL(int) PGMR3PhysRegisterRam(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, const
* (We don't lock here because the locking by EMT is only required on update.)
*/
PPGMRAMRANGE pPrev = NULL;
- PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3;
+ PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3;
while (pRam && GCPhysLast >= pRam->GCPhys)
{
if ( GCPhysLast >= pRam->GCPhys
@@ -1528,7 +1714,7 @@ VMMR3DECL(int) PGMR3PhysRegisterRam(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, const
pgmR3PhysInitAndLinkRamRange(pVM, pNew, GCPhys, GCPhysLast, NIL_RTRCPTR, NIL_RTR0PTR, pszDesc, pPrev);
}
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
pgmUnlock(pVM);
/*
@@ -1562,7 +1748,7 @@ int pgmR3PhysRamPreAllocate(PVM pVM)
uint64_t cPages = 0;
uint64_t NanoTS = RTTimeNanoTS();
pgmLock(pVM);
- for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3; pRam; pRam = pRam->pNextR3)
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3; pRam; pRam = pRam->pNextR3)
{
PPGMPAGE pPage = &pRam->aPages[0];
RTGCPHYS GCPhys = pRam->GCPhys;
@@ -1619,7 +1805,7 @@ int pgmR3PhysRamPreAllocate(PVM pVM)
*/
int pgmR3PhysRamReset(PVM pVM)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/* Reset the memory balloon. */
int rc = GMMR3BalloonedPages(pVM, GMMBALLOONACTION_RESET, 0);
@@ -1646,7 +1832,7 @@ int pgmR3PhysRamReset(PVM pVM)
/*
* Walk the ram ranges.
*/
- for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3; pRam; pRam = pRam->pNextR3)
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3; pRam; pRam = pRam->pNextR3)
{
uint32_t iPage = pRam->cb >> PAGE_SHIFT;
AssertMsg(((RTGCPHYS)iPage << PAGE_SHIFT) == pRam->cb, ("%RGp %RGp\n", (RTGCPHYS)iPage << PAGE_SHIFT, pRam->cb));
@@ -1673,7 +1859,7 @@ int pgmR3PhysRamReset(PVM pVM)
else if (PGM_PAGE_IS_BALLOONED(pPage))
{
/* Turn into a zero page; the balloon status is lost when the VM reboots. */
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ZERO);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ZERO);
}
else if (!PGM_PAGE_IS_ZERO(pPage))
{
@@ -1713,7 +1899,7 @@ int pgmR3PhysRamReset(PVM pVM)
case PGM_PAGE_STATE_BALLOONED:
/* Turn into a zero page; the balloon status is lost when the VM reboots. */
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ZERO);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ZERO);
break;
case PGM_PAGE_STATE_SHARED:
@@ -1775,7 +1961,7 @@ int pgmR3PhysRamReset(PVM pVM)
*/
int pgmR3PhysRamTerm(PVM pVM)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/* Reset the memory balloon. */
int rc = GMMR3BalloonedPages(pVM, GMMBALLOONACTION_RESET, 0);
@@ -1799,7 +1985,7 @@ int pgmR3PhysRamTerm(PVM pVM)
/*
* Walk the ram ranges.
*/
- for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3; pRam; pRam = pRam->pNextR3)
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3; pRam; pRam = pRam->pNextR3)
{
uint32_t iPage = pRam->cb >> PAGE_SHIFT;
AssertMsg(((RTGCPHYS)iPage << PAGE_SHIFT) == pRam->cb, ("%RGp %RGp\n", (RTGCPHYS)iPage << PAGE_SHIFT, pRam->cb));
@@ -1887,36 +2073,32 @@ VMMR3DECL(int) PGMR3PhysMMIORegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb,
RTGCPHYS GCPhysLast = GCPhys + (cb - 1);
bool fRamExists = false;
PPGMRAMRANGE pRamPrev = NULL;
- PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3;
+ PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3;
while (pRam && GCPhysLast >= pRam->GCPhys)
{
if ( GCPhysLast >= pRam->GCPhys
&& GCPhys <= pRam->GCPhysLast)
{
/* Simplification: all within the same range. */
- if (RT_UNLIKELY(!( GCPhys >= pRam->GCPhys
- && GCPhysLast <= pRam->GCPhysLast)))
- {
- AssertLogRelMsgFailed(("%RGp-%RGp (MMIO/%s) falls partly outside %RGp-%RGp (%s)\n",
+ AssertLogRelMsgReturnStmt( GCPhys >= pRam->GCPhys
+ && GCPhysLast <= pRam->GCPhysLast,
+ ("%RGp-%RGp (MMIO/%s) falls partly outside %RGp-%RGp (%s)\n",
GCPhys, GCPhysLast, pszDesc,
- pRam->GCPhys, pRam->GCPhysLast, pRam->pszDesc));
- pgmUnlock(pVM);
- return VERR_PGM_RAM_CONFLICT;
- }
+ pRam->GCPhys, pRam->GCPhysLast, pRam->pszDesc),
+ pgmUnlock(pVM),
+ VERR_PGM_RAM_CONFLICT);
/* Check that it's all RAM or MMIO pages. */
PCPGMPAGE pPage = &pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT];
uint32_t cLeft = cb >> PAGE_SHIFT;
while (cLeft-- > 0)
{
- if (RT_UNLIKELY(!( PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_RAM
- || PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_MMIO)))
- {
- AssertLogRelMsgFailed(("%RGp-%RGp (MMIO/%s): %RGp is not a RAM or MMIO page - type=%d desc=%s\n",
- GCPhys, GCPhysLast, pszDesc, PGM_PAGE_GET_TYPE(pPage), pRam->pszDesc));
- pgmUnlock(pVM);
- return VERR_PGM_RAM_CONFLICT;
- }
+ AssertLogRelMsgReturnStmt( PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_RAM
+ || PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_MMIO,
+ ("%RGp-%RGp (MMIO/%s): %RGp is not a RAM or MMIO page - type=%d desc=%s\n",
+ GCPhys, GCPhysLast, pszDesc, PGM_PAGE_GET_TYPE(pPage), pRam->pszDesc),
+ pgmUnlock(pVM),
+ VERR_PGM_RAM_CONFLICT);
pPage++;
}
@@ -1940,21 +2122,19 @@ VMMR3DECL(int) PGMR3PhysMMIORegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb,
* for PCI memory, but we're doing the same thing for MMIO2 pages.
*/
rc = pgmR3PhysFreePageRange(pVM, pRam, GCPhys, GCPhysLast, PGMPAGETYPE_MMIO);
- if (RT_FAILURE(rc))
- {
- AssertRC(rc);
- pgmUnlock(pVM);
- return rc;
- }
+ AssertRCReturnStmt(rc, pgmUnlock(pVM), rc);
/* Force a PGM pool flush as guest ram references have been changed. */
- /** todo; not entirely SMP safe; assuming for now the guest takes care of this internally (not touch mapped mmio while changing the mapping). */
+ /** @todo not entirely SMP safe; assuming for now the guest takes
+ * care of this internally (not touch mapped mmio while changing the
+ * mapping). */
PVMCPU pVCpu = VMMGetCpu(pVM);
pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_CLEAR_PGM_POOL;
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
}
else
{
+
/*
* No RAM range, insert an ad hoc one.
*
@@ -1966,12 +2146,7 @@ VMMR3DECL(int) PGMR3PhysMMIORegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb,
const uint32_t cPages = cb >> PAGE_SHIFT;
const size_t cbRamRange = RT_OFFSETOF(PGMRAMRANGE, aPages[cPages]);
rc = MMHyperAlloc(pVM, RT_OFFSETOF(PGMRAMRANGE, aPages[cPages]), 16, MM_TAG_PGM_PHYS, (void **)&pNew);
- if (RT_FAILURE(rc))
- {
- AssertLogRelMsgFailed(("cbRamRange=%zu\n", cbRamRange));
- pgmUnlock(pVM);
- return rc;
- }
+ AssertLogRelMsgRCReturnStmt(rc, ("cbRamRange=%zu\n", cbRamRange), pgmUnlock(pVM), rc);
/* Initialize the range. */
pNew->pSelfR0 = MMHyperCCToR0(pVM, pNew);
@@ -2015,7 +2190,7 @@ VMMR3DECL(int) PGMR3PhysMMIORegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb,
pNew->cb = pNew->GCPhys = pNew->GCPhysLast = NIL_RTGCPHYS;
MMHyperFree(pVM, pRam);
}
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
pgmUnlock(pVM);
return rc;
@@ -2048,7 +2223,7 @@ VMMR3DECL(int) PGMR3PhysMMIODeregister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb)
{
RTGCPHYS GCPhysLast = GCPhys + (cb - 1);
PPGMRAMRANGE pRamPrev = NULL;
- PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3;
+ PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3;
while (pRam && GCPhysLast >= pRam->GCPhys)
{
/** @todo We're being a bit too careful here. rewrite. */
@@ -2116,7 +2291,7 @@ VMMR3DECL(int) PGMR3PhysMMIODeregister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb)
AssertMsg(PGM_PAGE_IS_MMIO(pPage), ("%RGp %R[pgmpage]\n", pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT), pPage));
AssertMsg(PGM_PAGE_IS_ZERO(pPage), ("%RGp %R[pgmpage]\n", pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT), pPage));
if (PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_MMIO)
- PGM_PAGE_SET_TYPE(pPage, PGMPAGETYPE_RAM);
+ PGM_PAGE_SET_TYPE(pVM, pPage, PGMPAGETYPE_RAM);
}
break;
}
@@ -2133,7 +2308,8 @@ VMMR3DECL(int) PGMR3PhysMMIODeregister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb)
pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_CLEAR_PGM_POOL;
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidRamRangeTlbs(pVM);
pgmUnlock(pVM);
return rc;
}
@@ -2284,7 +2460,7 @@ VMMR3DECL(int) PGMR3PhysMMIO2Register(PVM pVM, PPDMDEVINS pDevIns, uint32_t iReg
*ppv = pvPages;
RTMemTmpFree(paPages);
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
return VINF_SUCCESS;
}
@@ -2396,7 +2572,7 @@ VMMR3DECL(int) PGMR3PhysMMIO2Deregister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iR
pCur = pCur->pNextR3;
}
}
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
pgmUnlock(pVM);
return !cFound && iRegion != UINT32_MAX ? VERR_NOT_FOUND : rc;
}
@@ -2441,7 +2617,7 @@ VMMR3DECL(int) PGMR3PhysMMIO2Map(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion,
*/
bool fRamExists = false;
PPGMRAMRANGE pRamPrev = NULL;
- PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3;
+ PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3;
while (pRam && GCPhysLast >= pRam->GCPhys)
{
if ( GCPhys <= pRam->GCPhysLast
@@ -2506,12 +2682,12 @@ VMMR3DECL(int) PGMR3PhysMMIO2Map(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion,
AssertLogRelRCReturn(rc, rc); /* We're done for if this goes wrong. */
RTHCPHYS const HCPhys = PGM_PAGE_GET_HCPHYS(pPageSrc);
- PGM_PAGE_SET_HCPHYS(pPageDst, HCPhys);
- PGM_PAGE_SET_TYPE(pPageDst, PGMPAGETYPE_MMIO2);
- PGM_PAGE_SET_STATE(pPageDst, PGM_PAGE_STATE_ALLOCATED);
- PGM_PAGE_SET_PDE_TYPE(pPageDst, PGM_PAGE_PDE_TYPE_DONTCARE);
- PGM_PAGE_SET_PTE_INDEX(pPageDst, 0);
- PGM_PAGE_SET_TRACKING(pPageDst, 0);
+ PGM_PAGE_SET_HCPHYS(pVM, pPageDst, HCPhys);
+ PGM_PAGE_SET_TYPE(pVM, pPageDst, PGMPAGETYPE_MMIO2);
+ PGM_PAGE_SET_STATE(pVM, pPageDst, PGM_PAGE_STATE_ALLOCATED);
+ PGM_PAGE_SET_PDE_TYPE(pVM, pPageDst, PGM_PAGE_PDE_TYPE_DONTCARE);
+ PGM_PAGE_SET_PTE_INDEX(pVM, pPageDst, 0);
+ PGM_PAGE_SET_TRACKING(pVM, pPageDst, 0);
pVM->pgm.s.cZeroPages--;
GCPhys += PAGE_SIZE;
@@ -2520,7 +2696,7 @@ VMMR3DECL(int) PGMR3PhysMMIO2Map(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion,
}
/* Flush physical page map TLB. */
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
if (cPendingPages)
{
@@ -2546,8 +2722,8 @@ VMMR3DECL(int) PGMR3PhysMMIO2Map(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion,
uint32_t cPagesLeft = pCur->RamRange.cb >> PAGE_SHIFT;
while (cPagesLeft-- > 0)
{
- PGM_PAGE_SET_TRACKING(pPageSrc, 0);
- PGM_PAGE_SET_PTE_INDEX(pPageSrc, 0);
+ PGM_PAGE_SET_TRACKING(pVM, pPageSrc, 0);
+ PGM_PAGE_SET_PTE_INDEX(pVM, pPageSrc, 0);
pPageSrc++;
}
@@ -2558,7 +2734,7 @@ VMMR3DECL(int) PGMR3PhysMMIO2Map(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion,
REMR3NotifyPhysRamRegister(pVM, GCPhys, cb, REM_NOTIFY_PHYS_RAM_FLAGS_MMIO2);
}
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
return VINF_SUCCESS;
}
@@ -2602,7 +2778,7 @@ VMMR3DECL(int) PGMR3PhysMMIO2Unmap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion
if (pCur->fOverlapping)
{
/* Restore the RAM pages we've replaced. */
- PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3;
+ PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3;
while (pRam->GCPhys > pCur->RamRange.GCPhysLast)
pRam = pRam->pNextR3;
@@ -2616,7 +2792,7 @@ VMMR3DECL(int) PGMR3PhysMMIO2Unmap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion
}
/* Flush physical page map TLB. */
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
GCPhysRangeREM = NIL_RTGCPHYS; /* shuts up gcc */
cbRangeREM = RTGCPHYS_MAX; /* ditto */
@@ -2637,12 +2813,15 @@ VMMR3DECL(int) PGMR3PhysMMIO2Unmap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion
pCur->fMapped = false;
/* Force a PGM pool flush as guest ram references have been changed. */
- /** todo; not entirely SMP safe; assuming for now the guest takes care of this internally (not touch mapped mmio while changing the mapping). */
+ /** @todo not entirely SMP safe; assuming for now the guest takes care
+ * of this internally (not touch mapped mmio while changing the
+ * mapping). */
PVMCPU pVCpu = VMMGetCpu(pVM);
pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_CLEAR_PGM_POOL;
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidRamRangeTlbs(pVM);
pgmUnlock(pVM);
if (fInformREM)
@@ -2763,17 +2942,11 @@ VMMR3DECL(int) PGMR3PhysMMIO2MapKernel(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRe
/**
- * Registers a ROM image.
+ * Worker for PGMR3PhysRomRegister.
*
- * Shadowed ROM images requires double the amount of backing memory, so,
- * don't use that unless you have to. Shadowing of ROM images is process
- * where we can select where the reads go and where the writes go. On real
- * hardware the chipset provides means to configure this. We provide
- * PGMR3PhysProtectROM() for this purpose.
- *
- * A read-only copy of the ROM image will always be kept around while we
- * will allocate RAM pages for the changes on demand (unless all memory
- * is configured to be preallocated).
+ * This is here to simplify lock management, i.e. the caller does all the
+ * locking and we can simply return without needing to remember to unlock
+ * anything first.
*
* @returns VBox status.
* @param pVM VM Handle.
@@ -2788,17 +2961,10 @@ VMMR3DECL(int) PGMR3PhysMMIO2MapKernel(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRe
* @param fFlags Mask of flags. PGMPHYS_ROM_FLAGS_SHADOWED
* and/or PGMPHYS_ROM_FLAGS_PERMANENT_BINARY.
* @param pszDesc Pointer to description string. This must not be freed.
- *
- * @remark There is no way to remove the rom, automatically on device cleanup or
- * manually from the device yet. This isn't difficult in any way, it's
- * just not something we expect to be necessary for a while.
*/
-VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cb,
- const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)
+static int pgmR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cb,
+ const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)
{
- Log(("PGMR3PhysRomRegister: pDevIns=%p GCPhys=%RGp(-%RGp) cb=%RGp pvBinary=%p cbBinary=%#x fFlags=%#x pszDesc=%s\n",
- pDevIns, GCPhys, GCPhys + cb, cb, pvBinary, cbBinary, fFlags, pszDesc));
-
/*
* Validate input.
*/
@@ -2843,7 +3009,7 @@ VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
*/
bool fRamExists = false;
PPGMRAMRANGE pRamPrev = NULL;
- PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3;
+ PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3;
while (pRam && GCPhysLast >= pRam->GCPhys)
{
if ( GCPhys <= pRam->GCPhysLast
@@ -2906,9 +3072,7 @@ VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
pReq->aPages[iPage].idSharedPage = NIL_GMM_PAGEID;
}
- pgmLock(pVM);
rc = GMMR3AllocatePagesPerform(pVM, pReq);
- pgmUnlock(pVM);
if (RT_FAILURE(rc))
{
GMMR3AllocatePagesCleanup(pReq);
@@ -2927,8 +3091,6 @@ VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
rc = MMHyperAlloc(pVM, RT_OFFSETOF(PGMRAMRANGE, aPages[cPages]), sizeof(PGMPAGE), MM_TAG_PGM_PHYS, (void **)&pRamNew);
if (RT_SUCCESS(rc))
{
- pgmLock(pVM);
-
/*
* Initialize and insert the RAM range (if required).
*/
@@ -2965,13 +3127,13 @@ VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
PPGMPAGE pPage = &pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT];
for (uint32_t iPage = 0; iPage < cPages; iPage++, pPage++, pRomPage++)
{
- PGM_PAGE_SET_TYPE(pPage, PGMPAGETYPE_ROM);
- PGM_PAGE_SET_HCPHYS(pPage, pReq->aPages[iPage].HCPhysGCPhys);
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ALLOCATED);
- PGM_PAGE_SET_PAGEID(pPage, pReq->aPages[iPage].idPage);
- PGM_PAGE_SET_PDE_TYPE(pPage, PGM_PAGE_PDE_TYPE_DONTCARE);
- PGM_PAGE_SET_PTE_INDEX(pPage, 0);
- PGM_PAGE_SET_TRACKING(pPage, 0);
+ PGM_PAGE_SET_TYPE(pVM, pPage, PGMPAGETYPE_ROM);
+ PGM_PAGE_SET_HCPHYS(pVM, pPage, pReq->aPages[iPage].HCPhysGCPhys);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ALLOCATED);
+ PGM_PAGE_SET_PAGEID(pVM, pPage, pReq->aPages[iPage].idPage);
+ PGM_PAGE_SET_PDE_TYPE(pVM, pPage, PGM_PAGE_PDE_TYPE_DONTCARE);
+ PGM_PAGE_SET_PTE_INDEX(pVM, pPage, 0);
+ PGM_PAGE_SET_TRACKING(pVM, pPage, 0);
pRomPage->Virgin = *pPage;
}
@@ -2983,9 +3145,7 @@ VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
pVM->pgm.s.cPrivatePages += cPages;
/* Flush physical page map TLB. */
- PGMPhysInvalidatePageMapTLB(pVM);
-
- pgmUnlock(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
/*
@@ -3023,8 +3183,6 @@ VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
}
if (RT_SUCCESS(rc))
{
- pgmLock(pVM);
-
/*
* Copy the image over to the virgin pages.
* This must be done after linking in the RAM range.
@@ -3109,18 +3267,15 @@ VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
pVM->pgm.s.pRomRangesRC = MMHyperCCToRC(pVM, pRomNew);
}
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
GMMR3AllocatePagesCleanup(pReq);
- pgmUnlock(pVM);
return VINF_SUCCESS;
}
/* bail out */
- pgmUnlock(pVM);
int rc2 = PGMHandlerPhysicalDeregister(pVM, GCPhys);
AssertRC(rc2);
- pgmLock(pVM);
}
if (!fRamExists)
@@ -3135,6 +3290,48 @@ VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys
/** @todo Purge the mapping cache or something... */
GMMR3FreeAllocatedPages(pVM, pReq);
GMMR3AllocatePagesCleanup(pReq);
+ return rc;
+}
+
+
+/**
+ * Registers a ROM image.
+ *
+ * Shadowed ROM images requires double the amount of backing memory, so,
+ * don't use that unless you have to. Shadowing of ROM images is process
+ * where we can select where the reads go and where the writes go. On real
+ * hardware the chipset provides means to configure this. We provide
+ * PGMR3PhysProtectROM() for this purpose.
+ *
+ * A read-only copy of the ROM image will always be kept around while we
+ * will allocate RAM pages for the changes on demand (unless all memory
+ * is configured to be preallocated).
+ *
+ * @returns VBox status.
+ * @param pVM VM Handle.
+ * @param pDevIns The device instance owning the ROM.
+ * @param GCPhys First physical address in the range.
+ * Must be page aligned!
+ * @param cb The size of the range (in bytes).
+ * Must be page aligned!
+ * @param pvBinary Pointer to the binary data backing the ROM image.
+ * @param cbBinary The size of the binary data pvBinary points to.
+ * This must be less or equal to @a cb.
+ * @param fFlags Mask of flags. PGMPHYS_ROM_FLAGS_SHADOWED
+ * and/or PGMPHYS_ROM_FLAGS_PERMANENT_BINARY.
+ * @param pszDesc Pointer to description string. This must not be freed.
+ *
+ * @remark There is no way to remove the rom, automatically on device cleanup or
+ * manually from the device yet. This isn't difficult in any way, it's
+ * just not something we expect to be necessary for a while.
+ */
+VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cb,
+ const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)
+{
+ Log(("PGMR3PhysRomRegister: pDevIns=%p GCPhys=%RGp(-%RGp) cb=%RGp pvBinary=%p cbBinary=%#x fFlags=%#x pszDesc=%s\n",
+ pDevIns, GCPhys, GCPhys + cb, cb, pvBinary, cbBinary, fFlags, pszDesc));
+ pgmLock(pVM);
+ int rc = pgmR3PhysRomRegister(pVM, pDevIns, GCPhys, cb, pvBinary, cbBinary, fFlags, pszDesc);
pgmUnlock(pVM);
return rc;
}
@@ -3215,7 +3412,7 @@ static DECLCALLBACK(int) pgmR3PhysRomWriteHandler(PVM pVM, RTGCPHYS GCPhys, void
PPGMPAGE pShadowPage = &pRomPage->Shadow;
if (!PGMROMPROT_IS_ROM(pRomPage->enmProt))
{
- pShadowPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
+ pShadowPage = pgmPhysGetPage(pVM, GCPhys);
AssertLogRelReturn(pShadowPage, VERR_INTERNAL_ERROR);
}
@@ -3252,7 +3449,7 @@ static DECLCALLBACK(int) pgmR3PhysRomWriteHandler(PVM pVM, RTGCPHYS GCPhys, void
*/
int pgmR3PhysRomReset(PVM pVM)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
for (PPGMROMRANGE pRom = pVM->pgm.s.pRomRangesR3; pRom; pRom = pRom->pNextR3)
{
const uint32_t cPages = pRom->cb >> PAGE_SHIFT;
@@ -3426,7 +3623,7 @@ VMMR3DECL(int) PGMR3PhysRomProtect(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, PGMROM
fChanges = true;
/* flush references to the page. */
- PPGMPAGE pRamPage = pgmPhysGetPage(&pVM->pgm.s, pRom->GCPhys + (iPage << PAGE_SHIFT));
+ PPGMPAGE pRamPage = pgmPhysGetPage(pVM, pRom->GCPhys + (iPage << PAGE_SHIFT));
int rc2 = pgmPoolTrackUpdateGCPhys(pVM, pRom->GCPhys + (iPage << PAGE_SHIFT), pRamPage,
true /*fFlushPTEs*/, &fFlushTLB);
if (rc2 != VINF_SUCCESS && (rc == VINF_SUCCESS || RT_FAILURE(rc2)))
@@ -3489,13 +3686,13 @@ VMMDECL(void) PGMR3PhysSetA20(PVMCPU pVCpu, bool fEnable)
}
#ifdef PGM_WITH_LARGE_ADDRESS_SPACE_ON_32_BIT_HOST
+
/**
* Tree enumeration callback for dealing with age rollover.
* It will perform a simple compression of the current age.
*/
static DECLCALLBACK(int) pgmR3PhysChunkAgeingRolloverCallback(PAVLU32NODECORE pNode, void *pvUser)
{
- Assert(PGMIsLockOwner((PVM)pvUser));
/* Age compression - ASSUMES iNow == 4. */
PPGMCHUNKR3MAP pChunk = (PPGMCHUNKR3MAP)pNode;
if (pChunk->iAge >= UINT32_C(0xffffff00))
@@ -3609,7 +3806,7 @@ static DECLCALLBACK(int) pgmR3PhysChunkUnmapCandidateCallback(PAVLU32NODECORE pN
*/
static int32_t pgmR3PhysChunkFindUnmapCandidate(PVM pVM)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
/*
* Do tree ageing first?
@@ -3740,6 +3937,7 @@ void pgmR3PhysUnmapChunk(PVM pVM)
int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysUnmapChunkRendezvous, NULL);
AssertRC(rc);
}
+
#endif /* PGM_WITH_LARGE_ADDRESS_SPACE_ON_32_BIT_HOST */
/**
@@ -3759,7 +3957,8 @@ int pgmR3PhysChunkMap(PVM pVM, uint32_t idChunk, PPPGMCHUNKR3MAP ppChunk)
{
int rc;
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
+
/*
* Allocate a new tracking structure first.
*/
@@ -3812,6 +4011,8 @@ int pgmR3PhysChunkMap(PVM pVM, uint32_t idChunk, PPPGMCHUNKR3MAP ppChunk)
}
else
{
+ /** @todo this may fail because of /proc/sys/vm/max_map_count, so we
+ * should probably restrict ourselves on linux. */
AssertRC(rc);
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
MMR3HeapFree(pChunk);
@@ -3859,7 +4060,7 @@ VMMR3DECL(void) PGMR3PhysChunkInvalidateTLB(PVM pVM)
pVM->pgm.s.ChunkR3Map.Tlb.aEntries[i].pChunk = NULL;
}
/* The page map TLB references chunks, so invalidate that one too. */
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
pgmUnlock(pVM);
}
@@ -3917,7 +4118,7 @@ VMMR3DECL(int) PGMR3PhysAllocateLargeHandyPage(PVM pVM, RTGCPHYS GCPhys)
ASMMemZeroPage(pv);
PPGMPAGE pPage;
- rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhys, &pPage);
+ rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
AssertRC(rc);
Assert(PGM_PAGE_IS_ZERO(pPage));
@@ -3928,12 +4129,12 @@ VMMR3DECL(int) PGMR3PhysAllocateLargeHandyPage(PVM pVM, RTGCPHYS GCPhys)
* Do the PGMPAGE modifications.
*/
pVM->pgm.s.cPrivatePages++;
- PGM_PAGE_SET_HCPHYS(pPage, HCPhys);
- PGM_PAGE_SET_PAGEID(pPage, idPage);
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ALLOCATED);
- PGM_PAGE_SET_PDE_TYPE(pPage, PGM_PAGE_PDE_TYPE_PDE);
- PGM_PAGE_SET_PTE_INDEX(pPage, 0);
- PGM_PAGE_SET_TRACKING(pPage, 0);
+ PGM_PAGE_SET_HCPHYS(pVM, pPage, HCPhys);
+ PGM_PAGE_SET_PAGEID(pVM, pPage, idPage);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ALLOCATED);
+ PGM_PAGE_SET_PDE_TYPE(pVM, pPage, PGM_PAGE_PDE_TYPE_PDE);
+ PGM_PAGE_SET_PTE_INDEX(pVM, pPage, 0);
+ PGM_PAGE_SET_TRACKING(pVM, pPage, 0);
/* Somewhat dirty assumption that page ids are increasing. */
idPage++;
@@ -3949,7 +4150,7 @@ VMMR3DECL(int) PGMR3PhysAllocateLargeHandyPage(PVM pVM, RTGCPHYS GCPhys)
/* Flush all TLBs. */
PGM_INVL_ALL_VCPU_TLBS(pVM);
- PGMPhysInvalidatePageMapTLB(pVM);
+ pgmPhysInvalidatePageMapTLB(pVM);
}
pVM->pgm.s.cLargeHandyPages = 0;
}
@@ -4054,7 +4255,9 @@ VMMR3DECL(int) PGMR3PhysAllocateHandyPages(PVM pVM)
PGMMPAGEDESC pPage = &pVM->pgm.s.aHandyPages[iClear];
void *pv;
rc = pgmPhysPageMapByPageID(pVM, pPage->idPage, pPage->HCPhysGCPhys, &pv);
- AssertLogRelMsgBreak(RT_SUCCESS(rc), ("idPage=%#x HCPhysGCPhys=%RHp rc=%Rrc\n", pPage->idPage, pPage->HCPhysGCPhys, rc));
+ AssertLogRelMsgBreak(RT_SUCCESS(rc),
+ ("%u/%u: idPage=%#x HCPhysGCPhys=%RHp rc=%Rrc\n",
+ iClear, pVM->pgm.s.cHandyPages, pPage->idPage, pPage->HCPhysGCPhys, rc));
ASMMemZeroPage(pv);
iClear++;
Log3(("PGMR3PhysAllocateHandyPages: idPage=%#x HCPhys=%RGp\n", pPage->idPage, pPage->HCPhysGCPhys));
@@ -4099,7 +4302,7 @@ VMMR3DECL(int) PGMR3PhysAllocateHandyPages(PVM pVM)
uint32_t const idPage = pVM->pgm.s.aHandyPages[i].idPage;
if (idPage != NIL_GMM_PAGEID)
{
- for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3;
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3;
pRam;
pRam = pRam->pNextR3)
{
@@ -4145,7 +4348,7 @@ int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PP
/*
* Assert sanity.
*/
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
if (RT_UNLIKELY( PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_RAM
&& PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_ROM_SHADOW))
{
@@ -4181,22 +4384,22 @@ int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PP
/* Deal with write monitored pages. */
if (PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_WRITE_MONITORED)
{
- PGM_PAGE_SET_WRITTEN_TO(pPage);
+ PGM_PAGE_SET_WRITTEN_TO(pVM, pPage);
pVM->pgm.s.cWrittenToPages++;
}
/*
* pPage = ZERO page.
*/
- PGM_PAGE_SET_HCPHYS(pPage, pVM->pgm.s.HCPhysZeroPg);
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ZERO);
- PGM_PAGE_SET_PAGEID(pPage, NIL_GMM_PAGEID);
- PGM_PAGE_SET_PDE_TYPE(pPage, PGM_PAGE_PDE_TYPE_DONTCARE);
- PGM_PAGE_SET_PTE_INDEX(pPage, 0);
- PGM_PAGE_SET_TRACKING(pPage, 0);
+ PGM_PAGE_SET_HCPHYS(pVM, pPage, pVM->pgm.s.HCPhysZeroPg);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ZERO);
+ PGM_PAGE_SET_PAGEID(pVM, pPage, NIL_GMM_PAGEID);
+ PGM_PAGE_SET_PDE_TYPE(pVM, pPage, PGM_PAGE_PDE_TYPE_DONTCARE);
+ PGM_PAGE_SET_PTE_INDEX(pVM, pPage, 0);
+ PGM_PAGE_SET_TRACKING(pVM, pPage, 0);
/* Flush physical page map TLB entry. */
- PGMPhysInvalidatePageMapTLBEntry(pVM, GCPhys);
+ pgmPhysInvalidatePageMapTLBEntry(pVM, GCPhys);
/*
* Make sure it's not in the handy page array.
@@ -4264,7 +4467,7 @@ VMMR3DECL(int) PGMR3PhysTlbGCPhys2Ptr(PVM pVM, RTGCPHYS GCPhys, bool fWritable,
PPGMRAMRANGE pRam;
PPGMPAGE pPage;
- int rc = pgmPhysGetPageAndRangeEx(&pVM->pgm.s, GCPhys, &pPage, &pRam);
+ int rc = pgmPhysGetPageAndRangeEx(pVM, GCPhys, &pPage, &pRam);
if (RT_SUCCESS(rc))
{
if (PGM_PAGE_IS_BALLOONED(pPage))
@@ -4318,7 +4521,7 @@ VMMR3DECL(int) PGMR3PhysTlbGCPhys2Ptr(PVM pVM, RTGCPHYS GCPhys, bool fWritable,
/* Get a ring-3 mapping of the address. */
PPGMPAGER3MAPTLBE pTlbe;
- rc2 = pgmPhysPageQueryTlbe(&pVM->pgm.s, GCPhys, &pTlbe);
+ rc2 = pgmPhysPageQueryTlbe(pVM, GCPhys, &pTlbe);
AssertLogRelRCReturn(rc2, rc2);
*ppv = (void *)((uintptr_t)pTlbe->pv | (uintptr_t)(GCPhys & PAGE_OFFSET_MASK));
/** @todo mapping/locking hell; this isn't horribly efficient since
diff --git a/src/VBox/VMM/VMMR3/PGMPhysRWTmpl.h b/src/VBox/VMM/VMMR3/PGMPhysRWTmpl.h
index 0078b65e4..d4feb1ed6 100644
--- a/src/VBox/VMM/VMMR3/PGMPhysRWTmpl.h
+++ b/src/VBox/VMM/VMMR3/PGMPhysRWTmpl.h
@@ -1,4 +1,4 @@
-/* $Id: PGMPhysRWTmpl.h $ */
+/* $Id: PGMPhysRWTmpl.h 35333 2010-12-27 12:10:56Z vboxsync $ */
/** @file
* PGM - Page Manager and Monitor, Physical Memory Access Template.
*/
diff --git a/src/VBox/VMM/VMMR3/PGMPool.cpp b/src/VBox/VMM/VMMR3/PGMPool.cpp
index a185e5102..bee61a1f6 100644
--- a/src/VBox/VMM/VMMR3/PGMPool.cpp
+++ b/src/VBox/VMM/VMMR3/PGMPool.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMPool.cpp $ */
+/* $Id: PGMPool.cpp 37354 2011-06-07 15:05:32Z vboxsync $ */
/** @file
* PGM Shadow Page Pool.
*/
@@ -114,15 +114,15 @@
*******************************************************************************/
static DECLCALLBACK(int) pgmR3PoolAccessHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
#ifdef VBOX_WITH_DEBUGGER
-static DECLCALLBACK(int) pgmR3PoolCmdCheck(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
+static DECLCALLBACK(int) pgmR3PoolCmdCheck(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
#endif
#ifdef VBOX_WITH_DEBUGGER
/** Command descriptors. */
static const DBGCCMD g_aCmds[] =
{
- /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, pResultDesc, fFlags, pfnHandler pszSyntax, ....pszDescription */
- { "pgmpoolcheck", 0, 0, NULL, 0, NULL, 0, pgmR3PoolCmdCheck, "", "Check the pgm pool pages." },
+ /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, fFlags, pfnHandler pszSyntax, ....pszDescription */
+ { "pgmpoolcheck", 0, 0, NULL, 0, 0, pgmR3PoolCmdCheck, "", "Check the pgm pool pages." },
};
#endif
@@ -134,6 +134,8 @@ static const DBGCCMD g_aCmds[] =
*/
int pgmR3PoolInit(PVM pVM)
{
+ int rc;
+
AssertCompile(NIL_PGMPOOL_IDX == 0);
/* pPage->cLocked is an unsigned byte. */
AssertCompile(VMM_MAX_CPU_COUNT <= 255);
@@ -143,41 +145,42 @@ int pgmR3PoolInit(PVM pVM)
*/
PCFGMNODE pCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "/PGM/Pool");
- /* Default pgm pool size equals 1024 pages. */
- uint16_t cMaxPages = 4*_1M >> PAGE_SHIFT;
-
-#if HC_ARCH_BITS == 64
- uint64_t cbRam = 0;
- CFGMR3QueryU64Def(CFGMR3GetRoot(pVM), "RamSize", &cbRam, 0);
-
- /* We should increase the pgm pool size for guests with more than 2 GB of ram */
- if (cbRam >= UINT64_C(2) * _1G)
- {
- /* In the nested paging case we require 2 + 513 * (cbRam/1GB) pages to
- * store all page table descriptors.
- */
- uint64_t u64MaxPages = cbRam / (_1G / UINT64_C(512));
- if (u64MaxPages > PGMPOOL_IDX_LAST)
- cMaxPages = PGMPOOL_IDX_LAST;
- else
- cMaxPages = (uint16_t)u64MaxPages;
- }
-#endif
+ /* Default pgm pool size is 1024 pages (4MB). */
+ uint16_t cMaxPages = 1024;
+
+ /* Adjust it up relative to the RAM size, using the nested paging formula. */
+ uint64_t cbRam;
+ rc = CFGMR3QueryU64Def(CFGMR3GetRoot(pVM), "RamSize", &cbRam, 0); AssertRCReturn(rc, rc);
+ uint64_t u64MaxPages = (cbRam >> 9)
+ + (cbRam >> 18)
+ + (cbRam >> 27)
+ + 32 * PAGE_SIZE;
+ u64MaxPages >>= PAGE_SHIFT;
+ if (u64MaxPages > PGMPOOL_IDX_LAST)
+ cMaxPages = PGMPOOL_IDX_LAST;
+ else
+ cMaxPages = (uint16_t)u64MaxPages;
- /** @cfgm{/PGM/Pool/MaxPages, uint16_t, #pages, 16, 0x3fff, 1024}
+ /** @cfgm{/PGM/Pool/MaxPages, uint16_t, #pages, 16, 0x3fff, F(ram-size)}
* The max size of the shadow page pool in pages. The pool will grow dynamically
* up to this limit.
*/
- int rc = CFGMR3QueryU16Def(pCfg, "MaxPages", &cMaxPages, cMaxPages);
+ rc = CFGMR3QueryU16Def(pCfg, "MaxPages", &cMaxPages, cMaxPages);
AssertLogRelRCReturn(rc, rc);
AssertLogRelMsgReturn(cMaxPages <= PGMPOOL_IDX_LAST && cMaxPages >= RT_ALIGN(PGMPOOL_IDX_FIRST, 16),
("cMaxPages=%u (%#x)\n", cMaxPages, cMaxPages), VERR_INVALID_PARAMETER);
cMaxPages = RT_ALIGN(cMaxPages, 16);
+ if (cMaxPages > PGMPOOL_IDX_LAST)
+ cMaxPages = PGMPOOL_IDX_LAST;
+ LogRel(("PGMPool: cMaxPages=%u (u64MaxPages=%llu)\n", cMaxPages, u64MaxPages));
/** todo:
* We need to be much more careful with our allocation strategy here.
- * For nested paging we don't need pool user info nor extents at all, but we can't check for nested paging here (too early during init to get a confirmation it can be used)
- * The default for large memory configs is a bit large for shadow paging, so I've restricted the extent maximum to 2k (2k * 16 = 32k of hyper heap)
+ * For nested paging we don't need pool user info nor extents at all, but
+ * we can't check for nested paging here (too early during init to get a
+ * confirmation it can be used). The default for large memory configs is a
+ * bit large for shadow paging, so I've restricted the extent maximum to 8k
+ * (8k * 16 = 128k of hyper heap).
*
* Also when large page support is enabled, we typically don't need so much,
* although that depends on the availability of 2 MB chunks on the host.
@@ -195,13 +198,14 @@ int pgmR3PoolInit(PVM pVM)
AssertLogRelMsgReturn(cMaxUsers >= cMaxPages && cMaxPages <= _32K,
("cMaxUsers=%u (%#x)\n", cMaxUsers, cMaxUsers), VERR_INVALID_PARAMETER);
- /** @cfgm{/PGM/Pool/MaxPhysExts, uint16_t, #extents, 16, MaxPages * 2, MAX(MaxPages*2,0x3fff)}
+ /** @cfgm{/PGM/Pool/MaxPhysExts, uint16_t, #extents, 16, MaxPages * 2, MIN(MaxPages*2,8192)}
* The max number of extents for tracking aliased guest pages.
*/
uint16_t cMaxPhysExts;
- rc = CFGMR3QueryU16Def(pCfg, "MaxPhysExts", &cMaxPhysExts, RT_MAX(cMaxPages * 2, 2048 /* 2k max as this eat too much hyper heap */));
+ rc = CFGMR3QueryU16Def(pCfg, "MaxPhysExts", &cMaxPhysExts,
+ RT_MIN(cMaxPages * 2, 8192 /* 8Ki max as this eat too much hyper heap */));
AssertLogRelRCReturn(rc, rc);
- AssertLogRelMsgReturn(cMaxPhysExts >= 16 && cMaxPages <= PGMPOOL_IDX_LAST,
+ AssertLogRelMsgReturn(cMaxPhysExts >= 16 && cMaxPhysExts <= PGMPOOL_IDX_LAST,
("cMaxPhysExts=%u (%#x)\n", cMaxPhysExts, cMaxPhysExts), VERR_INVALID_PARAMETER);
/** @cfgm{/PGM/Pool/ChacheEnabled, bool, true}
@@ -593,7 +597,7 @@ static DECLCALLBACK(int) pgmR3PoolAccessHandler(PVM pVM, RTGCPHYS GCPhys, void *
STAM_PROFILE_STOP(&pPool->StatMonitorR3, a);
}
else if ( ( pPage->cModifications < 96 /* it's cheaper here. */
- || pgmPoolIsPageLocked(&pVM->pgm.s, pPage)
+ || pgmPoolIsPageLocked(pPage)
)
&& cbBuf <= 4)
{
@@ -642,7 +646,7 @@ DECLCALLBACK(VBOXSTRICTRC) pgmR3PoolClearAllRendezvous(PVM pVM, PVMCPU pVCpu, vo
*/
unsigned cModifiedPages = 0; NOREF(cModifiedPages);
unsigned cLeft = pPool->cUsedPages;
- unsigned iPage = pPool->cCurPages;
+ uint32_t iPage = pPool->cCurPages;
while (--iPage >= PGMPOOL_IDX_FIRST)
{
PPGMPOOLPAGE pPage = &pPool->aPages[iPage];
@@ -798,13 +802,13 @@ DECLCALLBACK(VBOXSTRICTRC) pgmR3PoolClearAllRendezvous(PVM pVM, PVMCPU pVCpu, vo
/*
* Clear all the GCPhys links and rebuild the phys ext free list.
*/
- for (PPGMRAMRANGE pRam = pPool->CTX_SUFF(pVM)->pgm.s.CTX_SUFF(pRamRanges);
+ for (PPGMRAMRANGE pRam = pPool->CTX_SUFF(pVM)->pgm.s.CTX_SUFF(pRamRangesX);
pRam;
pRam = pRam->CTX_SUFF(pNext))
{
iPage = pRam->cb >> PAGE_SHIFT;
while (iPage-- > 0)
- PGM_PAGE_SET_TRACKING(&pRam->aPages[iPage], 0);
+ PGM_PAGE_SET_TRACKING(pVM, &pRam->aPages[iPage], 0);
}
pPool->iPhysExtFreeHead = 0;
@@ -901,7 +905,7 @@ void pgmR3PoolClearAll(PVM pVM, bool fFlushRemTlb)
*/
void pgmR3PoolWriteProtectPages(PVM pVM)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
unsigned cLeft = pPool->cUsedPages;
unsigned iPage = pPool->cCurPages;
@@ -975,28 +979,25 @@ void pgmR3PoolWriteProtectPages(PVM pVM)
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) pgmR3PoolCmdCheck(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) pgmR3PoolCmdCheck(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
- /*
- * Validate input.
- */
- if (!pVM)
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: The command requires a VM to be selected.\n");
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
+ DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs == 0);
+ uint32_t cErrors = 0;
PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
-
for (unsigned i = 0; i < pPool->cCurPages; i++)
{
- PPGMPOOLPAGE pPage = &pPool->aPages[i];
- bool fFirstMsg = true;
+ PPGMPOOLPAGE pPage = &pPool->aPages[i];
+ bool fFirstMsg = true;
/* Todo: cover other paging modes too. */
if (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT)
{
PPGMSHWPTPAE pShwPT = (PPGMSHWPTPAE)PGMPOOL_PAGE_2_PTR(pPool->CTX_SUFF(pVM), pPage);
{
- PX86PTPAE pGstPT;
- PGMPAGEMAPLOCK LockPage;
+ PX86PTPAE pGstPT;
+ PGMPAGEMAPLOCK LockPage;
int rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, pPage->GCPhys, (const void **)&pGstPT, &LockPage); AssertReleaseRC(rc);
/* Check if any PTEs are out of sync. */
@@ -1011,20 +1012,22 @@ static DECLCALLBACK(int) pgmR3PoolCmdCheck(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
{
if (fFirstMsg)
{
- pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Check pool page %RGp\n", pPage->GCPhys);
+ DBGCCmdHlpPrintf(pCmdHlp, "Check pool page %RGp\n", pPage->GCPhys);
fFirstMsg = false;
}
- pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Mismatch HCPhys: rc=%Rrc idx=%d guest %RX64 shw=%RX64 vs %RHp\n", rc, j, pGstPT->a[j].u, PGMSHWPTEPAE_GET_LOG(pShwPT->a[j]), HCPhys);
+ DBGCCmdHlpPrintf(pCmdHlp, "Mismatch HCPhys: rc=%Rrc idx=%d guest %RX64 shw=%RX64 vs %RHp\n", rc, j, pGstPT->a[j].u, PGMSHWPTEPAE_GET_LOG(pShwPT->a[j]), HCPhys);
+ cErrors++;
}
else if ( PGMSHWPTEPAE_IS_RW(pShwPT->a[j])
&& !pGstPT->a[j].n.u1Write)
{
if (fFirstMsg)
{
- pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Check pool page %RGp\n", pPage->GCPhys);
+ DBGCCmdHlpPrintf(pCmdHlp, "Check pool page %RGp\n", pPage->GCPhys);
fFirstMsg = false;
}
- pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Mismatch r/w gst/shw: idx=%d guest %RX64 shw=%RX64 vs %RHp\n", j, pGstPT->a[j].u, PGMSHWPTEPAE_GET_LOG(pShwPT->a[j]), HCPhys);
+ DBGCCmdHlpPrintf(pCmdHlp, "Mismatch r/w gst/shw: idx=%d guest %RX64 shw=%RX64 vs %RHp\n", j, pGstPT->a[j].u, PGMSHWPTEPAE_GET_LOG(pShwPT->a[j]), HCPhys);
+ cErrors++;
}
}
}
@@ -1055,10 +1058,11 @@ static DECLCALLBACK(int) pgmR3PoolCmdCheck(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
{
if (fFirstMsg)
{
- pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Check pool page %RGp\n", pPage->GCPhys);
+ DBGCCmdHlpPrintf(pCmdHlp, "Check pool page %RGp\n", pPage->GCPhys);
fFirstMsg = false;
}
- pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Mismatch: r/w: GCPhys=%RGp idx=%d shw %RX64 %RX64\n", pTempPage->GCPhys, k, PGMSHWPTEPAE_GET_LOG(pShwPT->a[k]), PGMSHWPTEPAE_GET_LOG(pShwPT2->a[k]));
+ DBGCCmdHlpPrintf(pCmdHlp, "Mismatch: r/w: GCPhys=%RGp idx=%d shw %RX64 %RX64\n", pTempPage->GCPhys, k, PGMSHWPTEPAE_GET_LOG(pShwPT->a[k]), PGMSHWPTEPAE_GET_LOG(pShwPT2->a[k]));
+ cErrors++;
}
}
}
@@ -1066,6 +1070,8 @@ static DECLCALLBACK(int) pgmR3PoolCmdCheck(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp,
}
}
}
+ if (cErrors > 0)
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "Found %#x errors", cErrors);
return VINF_SUCCESS;
}
#endif /* VBOX_WITH_DEBUGGER */
diff --git a/src/VBox/VMM/VMMR3/PGMSavedState.cpp b/src/VBox/VMM/VMMR3/PGMSavedState.cpp
index 36973495e..bf1bae6d8 100644
--- a/src/VBox/VMM/VMMR3/PGMSavedState.cpp
+++ b/src/VBox/VMM/VMMR3/PGMSavedState.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMSavedState.cpp $ */
+/* $Id: PGMSavedState.cpp 37354 2011-06-07 15:05:32Z vboxsync $ */
/** @file
* PGM - Page Manager and Monitor, The Saved State Part.
*/
@@ -222,7 +222,7 @@ static int pgmR3PrepRomPages(PVM pVM)
{
RTGCPHYS GCPhys = pRom->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT);
PPGMPAGE pPage;
- int rc = pgmPhysGetPageWithHintEx(&pVM->pgm.s, GCPhys, &pPage, &pRamHint);
+ int rc = pgmPhysGetPageWithHintEx(pVM, GCPhys, &pPage, &pRamHint);
AssertLogRelMsgRC(rc, ("%Rrc GCPhys=%RGp\n", rc, GCPhys));
if (RT_SUCCESS(rc))
pRom->aPages[iPage].LiveSave.fWrittenTo = !PGM_PAGE_IS_ZERO(pPage) && !PGM_PAGE_IS_BALLOONED(pPage);
@@ -281,7 +281,7 @@ static int pgmR3SaveRomRanges(PVM pVM, PSSMHANDLE pSSM)
*/
static int pgmR3LoadRomRanges(PVM pVM, PSSMHANDLE pSSM)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
for (PPGMROMRANGE pRom = pVM->pgm.s.pRomRangesR3; pRom; pRom = pRom->pNextR3)
pRom->idSavedState = UINT8_MAX;
@@ -418,7 +418,7 @@ static int pgmR3SaveRomVirginPages(PVM pVM, PSSMHANDLE pSSM, bool fLiveSave)
/* Get the virgin page descriptor. */
PPGMPAGE pPage;
if (PGMROMPROT_IS_ROM(enmProt))
- pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
+ pPage = pgmPhysGetPage(pVM, GCPhys);
else
pPage = &pRom->aPages[iPage].Virgin;
@@ -512,7 +512,7 @@ static int pgmR3SaveShadowedRomPages(PVM pVM, PSSMHANDLE pSSM, bool fLiveSave, b
uint8_t abPage[PAGE_SIZE];
PGMROMPROT enmProt = pRomPage->enmProt;
RTGCPHYS GCPhys = pRom->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT);
- PPGMPAGE pPage = PGMROMPROT_IS_ROM(enmProt) ? &pRomPage->Shadow : pgmPhysGetPage(&pVM->pgm.s, GCPhys);
+ PPGMPAGE pPage = PGMROMPROT_IS_ROM(enmProt) ? &pRomPage->Shadow : pgmPhysGetPage(pVM, GCPhys);
bool fZero = PGM_PAGE_IS_ZERO(pPage) || PGM_PAGE_IS_BALLOONED(pPage); Assert(!PGM_PAGE_IS_BALLOONED(pPage)); /* Shouldn't be ballooned. */
int rc = VINF_SUCCESS;
if (!fZero)
@@ -672,7 +672,7 @@ static int pgmR3SaveMmio2Ranges(PVM pVM, PSSMHANDLE pSSM)
*/
static int pgmR3LoadMmio2Ranges(PVM pVM, PSSMHANDLE pSSM)
{
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
for (PPGMMMIO2RANGE pMmio2 = pVM->pgm.s.pMmio2RangesR3; pMmio2; pMmio2 = pMmio2->pNextR3)
pMmio2->idSavedState = UINT8_MAX;
@@ -1047,7 +1047,7 @@ static int pgmR3PrepRamPages(PVM pVM)
pgmLock(pVM);
do
{
- for (pCur = pVM->pgm.s.pRamRangesR3; pCur; pCur = pCur->pNextR3)
+ for (pCur = pVM->pgm.s.pRamRangesXR3; pCur; pCur = pCur->pNextR3)
{
if ( !pCur->paLSPages
&& !PGM_RAM_RANGE_IS_AD_HOC(pCur))
@@ -1303,7 +1303,7 @@ static void pgmR3ScanRamPages(PVM pVM, bool fFinalPass)
do
{
uint32_t const idRamRangesGen = pVM->pgm.s.idRamRangesGen;
- for (pCur = pVM->pgm.s.pRamRangesR3; pCur; pCur = pCur->pNextR3)
+ for (pCur = pVM->pgm.s.pRamRangesXR3; pCur; pCur = pCur->pNextR3)
{
if ( pCur->GCPhysLast > GCPhysCur
&& !PGM_RAM_RANGE_IS_AD_HOC(pCur))
@@ -1343,7 +1343,7 @@ static void pgmR3ScanRamPages(PVM pVM, bool fFinalPass)
if (PGM_PAGE_IS_WRITTEN_TO(&pCur->aPages[iPage]))
{
Assert(paLSPages[iPage].fWriteMonitored);
- PGM_PAGE_CLEAR_WRITTEN_TO(&pCur->aPages[iPage]);
+ PGM_PAGE_CLEAR_WRITTEN_TO(pVM, &pCur->aPages[iPage]);
Assert(pVM->pgm.s.cWrittenToPages > 0);
pVM->pgm.s.cWrittenToPages--;
}
@@ -1471,13 +1471,13 @@ static void pgmR3ScanRamPages(PVM pVM, bool fFinalPass)
if (RT_UNLIKELY(PGM_PAGE_GET_STATE(&pCur->aPages[iPage]) == PGM_PAGE_STATE_WRITE_MONITORED))
{
AssertMsgFailed(("%R[pgmpage]", &pCur->aPages[iPage])); /* shouldn't happen. */
- PGM_PAGE_SET_STATE(&pCur->aPages[iPage], PGM_PAGE_STATE_ALLOCATED);
+ PGM_PAGE_SET_STATE(pVM, &pCur->aPages[iPage], PGM_PAGE_STATE_ALLOCATED);
Assert(pVM->pgm.s.cMonitoredPages > 0);
pVM->pgm.s.cMonitoredPages--;
}
if (PGM_PAGE_IS_WRITTEN_TO(&pCur->aPages[iPage]))
{
- PGM_PAGE_CLEAR_WRITTEN_TO(&pCur->aPages[iPage]);
+ PGM_PAGE_CLEAR_WRITTEN_TO(pVM, &pCur->aPages[iPage]);
Assert(pVM->pgm.s.cWrittenToPages > 0);
pVM->pgm.s.cWrittenToPages--;
}
@@ -1530,7 +1530,7 @@ static int pgmR3SaveRamPages(PVM pVM, PSSMHANDLE pSSM, bool fLiveSave, uint32_t
do
{
uint32_t const idRamRangesGen = pVM->pgm.s.idRamRangesGen;
- for (pCur = pVM->pgm.s.pRamRangesR3; pCur; pCur = pCur->pNextR3)
+ for (pCur = pVM->pgm.s.pRamRangesXR3; pCur; pCur = pCur->pNextR3)
{
if ( pCur->GCPhysLast > GCPhysCur
&& !PGM_RAM_RANGE_IS_AD_HOC(pCur))
@@ -1638,7 +1638,7 @@ static int pgmR3SaveRamPages(PVM pVM, PSSMHANDLE pSSM, bool fLiveSave, uint32_t
SSMR3PutGCPhys(pSSM, GCPhys);
}
rc = SSMR3PutMem(pSSM, abPage, PAGE_SIZE);
- PGM_PAGE_CLEAR_WRITTEN_TO(pCurPage);
+ PGM_PAGE_CLEAR_WRITTEN_TO(pVM, pCurPage);
PGM_PAGE_CLEAR_FT_DIRTY(pCurPage);
}
/* else nothing changed, so skip it. */
@@ -1745,7 +1745,7 @@ static void pgmR3DoneRamPages(PVM pVM)
pgmLock(pVM);
do
{
- for (pCur = pVM->pgm.s.pRamRangesR3; pCur; pCur = pCur->pNextR3)
+ for (pCur = pVM->pgm.s.pRamRangesXR3; pCur; pCur = pCur->pNextR3)
{
if (pCur->paLSPages)
{
@@ -1767,10 +1767,10 @@ static void pgmR3DoneRamPages(PVM pVM)
while (iPage--)
{
PPGMPAGE pPage = &pCur->aPages[iPage];
- PGM_PAGE_CLEAR_WRITTEN_TO(pPage);
+ PGM_PAGE_CLEAR_WRITTEN_TO(pVM, pPage);
if (PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_WRITE_MONITORED)
{
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ALLOCATED);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ALLOCATED);
cMonitoredPages++;
}
}
@@ -2339,7 +2339,7 @@ static int pgmR3LoadMemoryOld(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion)
* Ram range flags and bits.
*/
uint32_t i = 0;
- for (PPGMRAMRANGE pRam = pPGM->pRamRangesR3; ; pRam = pRam->pNextR3, i++)
+ for (PPGMRAMRANGE pRam = pPGM->pRamRangesXR3; ; pRam = pRam->pNextR3, i++)
{
/* Check the sequence number / separator. */
uint32_t u32Sep;
@@ -2646,7 +2646,7 @@ static int pgmR3LoadMemory(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t
AssertLogRelMsgReturn(!(GCPhys & PAGE_OFFSET_MASK), ("%RGp\n", GCPhys), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
PPGMPAGE pPage;
- rc = pgmPhysGetPageWithHintEx(&pVM->pgm.s, GCPhys, &pPage, &pRamHint);
+ rc = pgmPhysGetPageWithHintEx(pVM, GCPhys, &pPage, &pRamHint);
AssertLogRelMsgRCReturn(rc, ("rc=%Rrc %RGp\n", rc, GCPhys), rc);
/*
@@ -2666,7 +2666,7 @@ static int pgmR3LoadMemory(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t
Assert(PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_RAM);
if (uVersion == PGM_SAVED_STATE_VERSION_BALLOON_BROKEN)
break;
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ZERO);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ZERO);
break;
}
@@ -2713,7 +2713,7 @@ static int pgmR3LoadMemory(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t
AssertRCReturn(rc, rc);
}
Assert(PGM_PAGE_IS_ZERO(pPage));
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_BALLOONED);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_BALLOONED);
break;
}
@@ -2863,7 +2863,7 @@ static int pgmR3LoadMemory(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t
}
if (!pRealPage)
{
- rc = pgmPhysGetPageWithHintEx(&pVM->pgm.s, GCPhys, &pRealPage, &pRamHint);
+ rc = pgmPhysGetPageWithHintEx(pVM, GCPhys, &pRealPage, &pRamHint);
AssertLogRelMsgRCReturn(rc, ("rc=%Rrc %RGp\n", rc, GCPhys), rc);
}
@@ -3181,7 +3181,7 @@ static DECLCALLBACK(int) pgmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion,
*/
pVM->pgm.s.fMappingsFixedRestored = false;
if ( pVM->pgm.s.fMappingsFixed
- && pgmMapAreMappingsEnabled(&pVM->pgm.s))
+ && pgmMapAreMappingsEnabled(pVM))
{
RTGCPTR GCPtrFixed = pVM->pgm.s.GCPtrMappingFixed;
uint32_t cbFixed = pVM->pgm.s.cbMappingFixed;
@@ -3218,7 +3218,7 @@ static DECLCALLBACK(int) pgmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion,
* doesn't conflict with guest code / data and thereby cause trouble
* when restoring other components like PATM.
*/
- if (pgmMapAreMappingsFloating(&pVM->pgm.s))
+ if (pgmMapAreMappingsFloating(pVM))
{
PVMCPU pVCpu = &pVM->aCpus[0];
rc = PGMSyncCR3(pVCpu, CPUMGetGuestCR0(pVCpu), CPUMGetGuestCR3(pVCpu), CPUMGetGuestCR4(pVCpu), true);
diff --git a/src/VBox/VMM/VMMR3/PGMSharedPage.cpp b/src/VBox/VMM/VMMR3/PGMSharedPage.cpp
index e91ab36df..e5de60de6 100644
--- a/src/VBox/VMM/VMMR3/PGMSharedPage.cpp
+++ b/src/VBox/VMM/VMMR3/PGMSharedPage.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMSharedPage.cpp $ */
+/* $Id: PGMSharedPage.cpp 36891 2011-04-29 13:22:57Z vboxsync $ */
/** @file
* PGM - Page Manager and Monitor, Shared page handling
*/
@@ -261,7 +261,7 @@ VMMR3DECL(int) PGMR3SharedModuleGetPageState(PVM pVM, RTGCPTR GCPtrPage, bool *p
{
case VINF_SUCCESS:
{
- PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
if (pPage)
{
*pfShared = PGM_PAGE_IS_SHARED(pPage);
@@ -303,7 +303,7 @@ VMMR3DECL(int) PGMR3SharedModuleGetPageState(PVM pVM, RTGCPTR GCPtrPage, bool *p
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-DECLCALLBACK(int) pgmR3CmdCheckDuplicatePages(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+DECLCALLBACK(int) pgmR3CmdCheckDuplicatePages(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
unsigned cBallooned = 0;
unsigned cShared = 0;
@@ -315,7 +315,7 @@ DECLCALLBACK(int) pgmR3CmdCheckDuplicatePages(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdH
pgmLock(pVM);
- for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3; pRam; pRam = pRam->pNextR3)
+ for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3; pRam; pRam = pRam->pNextR3)
{
PPGMPAGE pPage = &pRam->aPages[0];
RTGCPHYS GCPhys = pRam->GCPhys;
@@ -394,7 +394,7 @@ DECLCALLBACK(int) pgmR3CmdCheckDuplicatePages(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdH
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-DECLCALLBACK(int) pgmR3CmdShowSharedModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+DECLCALLBACK(int) pgmR3CmdShowSharedModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
unsigned i = 0;
@@ -408,8 +408,7 @@ DECLCALLBACK(int) pgmR3CmdShowSharedModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp
pCmdHlp->pfnPrintf(pCmdHlp, NULL, "--- Region %d: base %RGv size %x\n", j, g_apSharedModules[i]->aRegions[j].GCRegionAddr, g_apSharedModules[i]->aRegions[j].cbRegion);
}
i++;
- }
- while (i < RT_ELEMENTS(g_apSharedModules));
+ } while (i < RT_ELEMENTS(g_apSharedModules));
pgmUnlock(pVM);
return VINF_SUCCESS;
diff --git a/src/VBox/VMM/VMMR3/PGMShw.h b/src/VBox/VMM/VMMR3/PGMShw.h
index 8b4934f55..769ef0b26 100644
--- a/src/VBox/VMM/VMMR3/PGMShw.h
+++ b/src/VBox/VMM/VMMR3/PGMShw.h
@@ -1,4 +1,4 @@
-/* $Id: PGMShw.h $ */
+/* $Id: PGMShw.h 35333 2010-12-27 12:10:56Z vboxsync $ */
/** @file
* VBox - Page Manager / Monitor, Shadow Paging Template.
*/
diff --git a/src/VBox/VMM/VMMR3/SELM.cpp b/src/VBox/VMM/VMMR3/SELM.cpp
index 538fe290b..68b0b9c63 100644
--- a/src/VBox/VMM/VMMR3/SELM.cpp
+++ b/src/VBox/VMM/VMMR3/SELM.cpp
@@ -1,4 +1,4 @@
-/* $Id: SELM.cpp $ */
+/* $Id: SELM.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* SELM - The Selector Manager.
*/
diff --git a/src/VBox/VMM/VMMR3/SSM.cpp b/src/VBox/VMM/VMMR3/SSM.cpp
index a6034176c..b4369e844 100644
--- a/src/VBox/VMM/VMMR3/SSM.cpp
+++ b/src/VBox/VMM/VMMR3/SSM.cpp
@@ -1,4 +1,4 @@
-/* $Id: SSM.cpp $ */
+/* $Id: SSM.cpp 37026 2011-05-10 12:19:55Z vboxsync $ */
/** @file
* SSM - Saved State Manager.
*/
diff --git a/src/VBox/VMM/VMMR3/STAM.cpp b/src/VBox/VMM/VMMR3/STAM.cpp
index 5e9c86686..825b58d50 100644
--- a/src/VBox/VMM/VMMR3/STAM.cpp
+++ b/src/VBox/VMM/VMMR3/STAM.cpp
@@ -1,4 +1,4 @@
-/* $Id: STAM.cpp $ */
+/* $Id: STAM.cpp 35696 2011-01-24 18:03:33Z vboxsync $ */
/** @file
* STAM - The Statistics Manager.
*/
@@ -150,9 +150,9 @@ static void stamR3Ring0StatsUpdateU(PUVM pUVM, const char *pszPa
static void stamR3Ring0StatsUpdateMultiU(PUVM pUVM, const char * const *papszExpressions, unsigned cExpressions);
#ifdef VBOX_WITH_DEBUGGER
-static DECLCALLBACK(int) stamR3CmdStats(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
+static DECLCALLBACK(int) stamR3CmdStats(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
static DECLCALLBACK(void) stamR3EnumDbgfPrintf(PSTAMR3PRINTONEARGS pArgs, const char *pszFormat, ...);
-static DECLCALLBACK(int) stamR3CmdStatsReset(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
+static DECLCALLBACK(int) stamR3CmdStatsReset(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
#endif
@@ -170,9 +170,9 @@ static const DBGCVARDESC g_aArgPat[] =
/** Command descriptors. */
static const DBGCCMD g_aCmds[] =
{
- /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, pResultDesc, fFlags, pfnHandler pszSyntax, ....pszDescription */
- { "stats", 0, 1, &g_aArgPat[0], RT_ELEMENTS(g_aArgPat), NULL, 0, stamR3CmdStats, "[pattern]", "Display statistics." },
- { "statsreset", 0, 1, &g_aArgPat[0], RT_ELEMENTS(g_aArgPat), NULL, 0, stamR3CmdStatsReset,"[pattern]", "Resets statistics." }
+ /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, fFlags, pfnHandler pszSyntax, ....pszDescription */
+ { "stats", 0, 1, &g_aArgPat[0], RT_ELEMENTS(g_aArgPat), 0, stamR3CmdStats, "[pattern]", "Display statistics." },
+ { "statsreset", 0, 1, &g_aArgPat[0], RT_ELEMENTS(g_aArgPat), 0, stamR3CmdStatsReset,"[pattern]", "Resets statistics." }
};
#endif
@@ -1916,24 +1916,23 @@ VMMR3DECL(const char *) STAMR3GetUnit(STAMUNIT enmUnit)
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) stamR3CmdStats(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) stamR3CmdStats(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate input.
*/
- if (!pVM)
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: The command requires VM to be selected.\n");
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
PUVM pUVM = pVM->pUVM;
if (!pUVM->stam.s.pHead)
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Sorry, no statistics present.\n");
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "No statistics present");
/*
* Do the printing.
*/
STAMR3PRINTONEARGS Args;
- Args.pVM = pVM;
- Args.pvArg = pCmdHlp;
- Args.pfnPrintf = stamR3EnumDbgfPrintf;
+ Args.pVM = pVM;
+ Args.pvArg = pCmdHlp;
+ Args.pfnPrintf = stamR3EnumDbgfPrintf;
return stamR3EnumU(pUVM, cArgs ? paArgs[0].u.pszString : NULL, true /* fUpdateRing0 */, stamR3PrintOne, &Args);
}
@@ -1968,25 +1967,23 @@ static DECLCALLBACK(void) stamR3EnumDbgfPrintf(PSTAMR3PRINTONEARGS pArgs, const
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
*/
-static DECLCALLBACK(int) stamR3CmdStatsReset(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) stamR3CmdStatsReset(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
/*
* Validate input.
*/
- if (!pVM)
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: The command requires VM to be selected.\n");
+ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
PUVM pUVM = pVM->pUVM;
if (!pUVM->stam.s.pHead)
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Sorry, no statistics present.\n");
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "No statistics present");
/*
* Execute reset.
*/
int rc = STAMR3ResetU(pUVM, cArgs ? paArgs[0].u.pszString : NULL);
if (RT_SUCCESS(rc))
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "info: Statistics reset.\n");
-
- return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "Resetting statistics.\n");
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "STAMR3ResetU");
+ return DBGCCmdHlpPrintf(pCmdHlp, "Statistics have been reset.\n");
}
#endif /* VBOX_WITH_DEBUGGER */
diff --git a/src/VBox/VMM/VMMR3/TM.cpp b/src/VBox/VMM/VMMR3/TM.cpp
index 9efc0c434..cdfe3c529 100644
--- a/src/VBox/VMM/VMMR3/TM.cpp
+++ b/src/VBox/VMM/VMMR3/TM.cpp
@@ -1,4 +1,4 @@
-/* $Id: TM.cpp $ */
+/* $Id: TM.cpp 37527 2011-06-17 10:18:02Z vboxsync $ */
/** @file
* TM - Time Manager.
*/
@@ -126,6 +126,7 @@
#include <VBox/vmm/mm.h>
#include <VBox/vmm/ssm.h>
#include <VBox/vmm/dbgf.h>
+#include <VBox/vmm/dbgftrace.h>
#include <VBox/vmm/rem.h>
#include <VBox/vmm/pdmapi.h>
#include <VBox/vmm/iom.h>
@@ -147,6 +148,8 @@
#include <iprt/string.h>
#include <iprt/env.h>
+#include "TMInline.h"
+
/*******************************************************************************
* Defined Constants And Macros *
@@ -616,7 +619,7 @@ VMM_INT_DECL(int) TMR3Init(PVM pVM)
STAM_REG(pVM, &pVM->tm.s.StatScheduleOneRZ, STAMTYPE_PROFILE, "/TM/ScheduleOneRZ", STAMUNIT_TICKS_PER_CALL, "Profiling the scheduling of one queue during a TMTimer* call in EMT.");
STAM_REG(pVM, &pVM->tm.s.StatScheduleSetFF, STAMTYPE_COUNTER, "/TM/ScheduleSetFF", STAMUNIT_OCCURENCES, "The number of times the timer FF was set instead of doing scheduling.");
- STAM_REG(pVM, &pVM->tm.s.StatTimerSet, STAMTYPE_COUNTER, "/TM/TimerSet", STAMUNIT_OCCURENCES, "Calls");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSet, STAMTYPE_COUNTER, "/TM/TimerSet", STAMUNIT_OCCURENCES, "Calls, except virtual sync timers");
STAM_REG(pVM, &pVM->tm.s.StatTimerSetOpt, STAMTYPE_COUNTER, "/TM/TimerSet/Opt", STAMUNIT_OCCURENCES, "Optimized path taken.");
STAM_REG(pVM, &pVM->tm.s.StatTimerSetR3, STAMTYPE_PROFILE, "/TM/TimerSet/R3", STAMUNIT_TICKS_PER_CALL, "Profiling TMTimerSet calls made in ring-3.");
STAM_REG(pVM, &pVM->tm.s.StatTimerSetRZ, STAMTYPE_PROFILE, "/TM/TimerSet/RZ", STAMUNIT_TICKS_PER_CALL, "Profiling TMTimerSet calls made in ring-0 / RC.");
@@ -629,11 +632,17 @@ VMM_INT_DECL(int) TMR3Init(PVM pVM)
STAM_REG(pVM, &pVM->tm.s.StatTimerSetStPendResched, STAMTYPE_COUNTER, "/TM/TimerSet/StPendResched", STAMUNIT_OCCURENCES, "PENDING_RESCHEDULE");
STAM_REG(pVM, &pVM->tm.s.StatTimerSetStStopped, STAMTYPE_COUNTER, "/TM/TimerSet/StStopped", STAMUNIT_OCCURENCES, "STOPPED");
- STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelative, STAMTYPE_COUNTER, "/TM/TimerSetRelative", STAMUNIT_OCCURENCES, "Calls");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetVs, STAMTYPE_COUNTER, "/TM/TimerSetVs", STAMUNIT_OCCURENCES, "TMTimerSet calls on virtual sync timers");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetVsR3, STAMTYPE_PROFILE, "/TM/TimerSetVs/R3", STAMUNIT_TICKS_PER_CALL, "Profiling TMTimerSet calls made in ring-3 on virtual sync timers.");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetVsRZ, STAMTYPE_PROFILE, "/TM/TimerSetVs/RZ", STAMUNIT_TICKS_PER_CALL, "Profiling TMTimerSet calls made in ring-0 / RC on virtual sync timers.");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetVsStActive, STAMTYPE_COUNTER, "/TM/TimerSetVs/StActive", STAMUNIT_OCCURENCES, "ACTIVE");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetVsStExpDeliver, STAMTYPE_COUNTER, "/TM/TimerSetVs/StExpDeliver", STAMUNIT_OCCURENCES, "EXPIRED_DELIVER");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetVsStStopped, STAMTYPE_COUNTER, "/TM/TimerSetVs/StStopped", STAMUNIT_OCCURENCES, "STOPPED");
+
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelative, STAMTYPE_COUNTER, "/TM/TimerSetRelative", STAMUNIT_OCCURENCES, "Calls, except virtual sync timers");
STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeOpt, STAMTYPE_COUNTER, "/TM/TimerSetRelative/Opt", STAMUNIT_OCCURENCES, "Optimized path taken.");
- STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeR3, STAMTYPE_PROFILE, "/TM/TimerSetRelative/R3", STAMUNIT_TICKS_PER_CALL, "Profiling TMTimerSetRelative calls made in ring-3.");
- STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeRZ, STAMTYPE_PROFILE, "/TM/TimerSetRelative/RZ", STAMUNIT_TICKS_PER_CALL, "Profiling TMTimerSetReltaive calls made in ring-0 / RC.");
- STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeRacyVirtSync, STAMTYPE_COUNTER, "/TM/TimerSetRelative/RacyVirtSync", STAMUNIT_OCCURENCES, "Potentially racy virtual sync timer update.");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeR3, STAMTYPE_PROFILE, "/TM/TimerSetRelative/R3", STAMUNIT_TICKS_PER_CALL, "Profiling TMTimerSetRelative calls made in ring-3 (sans virtual sync).");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeRZ, STAMTYPE_PROFILE, "/TM/TimerSetRelative/RZ", STAMUNIT_TICKS_PER_CALL, "Profiling TMTimerSetReltaive calls made in ring-0 / RC (sans virtual sync).");
STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeStActive, STAMTYPE_COUNTER, "/TM/TimerSetRelative/StActive", STAMUNIT_OCCURENCES, "ACTIVE");
STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeStExpDeliver, STAMTYPE_COUNTER, "/TM/TimerSetRelative/StExpDeliver", STAMUNIT_OCCURENCES, "EXPIRED_DELIVER");
STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeStOther, STAMTYPE_COUNTER, "/TM/TimerSetRelative/StOther", STAMUNIT_OCCURENCES, "Other states");
@@ -643,12 +652,20 @@ VMM_INT_DECL(int) TMR3Init(PVM pVM)
STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeStPendResched, STAMTYPE_COUNTER, "/TM/TimerSetRelative/StPendResched", STAMUNIT_OCCURENCES, "PENDING_RESCHEDULE");
STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeStStopped, STAMTYPE_COUNTER, "/TM/TimerSetRelative/StStopped", STAMUNIT_OCCURENCES, "STOPPED");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeVs, STAMTYPE_COUNTER, "/TM/TimerSetRelativeVs", STAMUNIT_OCCURENCES, "TMTimerSetRelative calls on virtual sync timers");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeVsR3, STAMTYPE_PROFILE, "/TM/TimerSetRelativeVs/R3", STAMUNIT_TICKS_PER_CALL, "Profiling TMTimerSetRelative calls made in ring-3 on virtual sync timers.");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeVsRZ, STAMTYPE_PROFILE, "/TM/TimerSetRelativeVs/RZ", STAMUNIT_TICKS_PER_CALL, "Profiling TMTimerSetReltaive calls made in ring-0 / RC on virtual sync timers.");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeVsStActive, STAMTYPE_COUNTER, "/TM/TimerSetRelativeVs/StActive", STAMUNIT_OCCURENCES, "ACTIVE");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeVsStExpDeliver, STAMTYPE_COUNTER, "/TM/TimerSetRelativeVs/StExpDeliver", STAMUNIT_OCCURENCES, "EXPIRED_DELIVER");
+ STAM_REG(pVM, &pVM->tm.s.StatTimerSetRelativeVsStStopped, STAMTYPE_COUNTER, "/TM/TimerSetRelativeVs/StStopped", STAMUNIT_OCCURENCES, "STOPPED");
+
STAM_REG(pVM, &pVM->tm.s.StatTimerStopR3, STAMTYPE_PROFILE, "/TM/TimerStopR3", STAMUNIT_TICKS_PER_CALL, "Profiling TMTimerStop calls made in ring-3.");
STAM_REG(pVM, &pVM->tm.s.StatTimerStopRZ, STAMTYPE_PROFILE, "/TM/TimerStopRZ", STAMUNIT_TICKS_PER_CALL, "Profiling TMTimerStop calls made in ring-0 / RC.");
STAM_REG(pVM, &pVM->tm.s.StatVirtualGet, STAMTYPE_COUNTER, "/TM/VirtualGet", STAMUNIT_OCCURENCES, "The number of times TMTimerGet was called when the clock was running.");
STAM_REG(pVM, &pVM->tm.s.StatVirtualGetSetFF, STAMTYPE_COUNTER, "/TM/VirtualGetSetFF", STAMUNIT_OCCURENCES, "Times we set the FF when calling TMTimerGet.");
STAM_REG(pVM, &pVM->tm.s.StatVirtualSyncGet, STAMTYPE_COUNTER, "/TM/VirtualSyncGet", STAMUNIT_OCCURENCES, "The number of times tmVirtualSyncGetEx was called.");
+ STAM_REG(pVM, &pVM->tm.s.StatVirtualSyncGetAdjLast, STAMTYPE_COUNTER, "/TM/VirtualSyncGet/AdjLast", STAMUNIT_OCCURENCES, "Times we've adjusted against the last returned time stamp .");
STAM_REG(pVM, &pVM->tm.s.StatVirtualSyncGetELoop, STAMTYPE_COUNTER, "/TM/VirtualSyncGet/ELoop", STAMUNIT_OCCURENCES, "Times tmVirtualSyncGetEx has given up getting a consistent virtual sync data set.");
STAM_REG(pVM, &pVM->tm.s.StatVirtualSyncGetExpired, STAMTYPE_COUNTER, "/TM/VirtualSyncGet/Expired", STAMUNIT_OCCURENCES, "Times tmVirtualSyncGetEx encountered an expired timer stopping the clock.");
STAM_REG(pVM, &pVM->tm.s.StatVirtualSyncGetLocked, STAMTYPE_COUNTER, "/TM/VirtualSyncGet/Locked", STAMUNIT_OCCURENCES, "Times we successfully acquired the lock in tmVirtualSyncGetEx.");
@@ -1020,7 +1037,7 @@ VMM_INT_DECL(void) TMR3Reset(PVM pVM)
{
LogFlow(("TMR3Reset:\n"));
VM_ASSERT_EMT(pVM);
- tmTimerLock(pVM);
+ TM_LOCK_TIMERS(pVM);
/*
* Abort any pending catch up.
@@ -1055,7 +1072,7 @@ VMM_INT_DECL(void) TMR3Reset(PVM pVM)
PVMCPU pVCpuDst = &pVM->aCpus[pVM->tm.s.idTimerCpu];
VMCPU_FF_CLEAR(pVCpuDst, VMCPU_FF_TIMER); /** @todo FIXME: this isn't right. */
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
}
@@ -1284,7 +1301,7 @@ static int tmr3TimerCreate(PVM pVM, TMCLOCK enmClock, const char *pszDesc, PPTMT
pTimer->pszDesc = pszDesc;
/* insert into the list of created timers. */
- tmTimerLock(pVM);
+ TM_LOCK_TIMERS(pVM);
pTimer->pBigPrev = NULL;
pTimer->pBigNext = pVM->tm.s.pCreated;
pVM->tm.s.pCreated = pTimer;
@@ -1293,7 +1310,7 @@ static int tmr3TimerCreate(PVM pVM, TMCLOCK enmClock, const char *pszDesc, PPTMT
#ifdef VBOX_STRICT
tmTimerQueuesSanityChecks(pVM, "tmR3TimerCreate");
#endif
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
*ppTimer = pTimer;
return VINF_SUCCESS;
@@ -1314,7 +1331,9 @@ static int tmr3TimerCreate(PVM pVM, TMCLOCK enmClock, const char *pszDesc, PPTMT
* until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
* @param ppTimer Where to store the timer on success.
*/
-VMM_INT_DECL(int) TMR3TimerCreateDevice(PVM pVM, PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
+VMM_INT_DECL(int) TMR3TimerCreateDevice(PVM pVM, PPDMDEVINS pDevIns, TMCLOCK enmClock,
+ PFNTMTIMERDEV pfnCallback, void *pvUser,
+ uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
{
AssertReturn(!(fFlags & ~(TMTIMER_FLAGS_NO_CRIT_SECT)), VERR_INVALID_PARAMETER);
@@ -1328,13 +1347,8 @@ VMM_INT_DECL(int) TMR3TimerCreateDevice(PVM pVM, PPDMDEVINS pDevIns, TMCLOCK enm
(*ppTimer)->u.Dev.pfnTimer = pfnCallback;
(*ppTimer)->u.Dev.pDevIns = pDevIns;
(*ppTimer)->pvUser = pvUser;
- if (fFlags & TMTIMER_FLAGS_DEFAULT_CRIT_SECT)
- {
- if (pDevIns->pCritSectR3)
- (*ppTimer)->pCritSect = pDevIns->pCritSectR3;
- else
- (*ppTimer)->pCritSect = IOMR3GetCritSect(pVM);
- }
+ if (!(fFlags & TMTIMER_FLAGS_NO_CRIT_SECT))
+ (*ppTimer)->pCritSect = PDMR3DevGetCritSect(pVM, pDevIns);
Log(("TM: Created device timer %p clock %d callback %p '%s'\n", (*ppTimer), enmClock, pfnCallback, pszDesc));
}
@@ -1516,7 +1530,7 @@ VMMR3DECL(int) TMR3TimerDestroy(PTMTIMER pTimer)
* The rest of the game happens behind the lock, just
* like create does. All the work is done here.
*/
- tmTimerLock(pVM);
+ TM_LOCK_TIMERS(pVM);
for (int cRetries = 1000;; cRetries--)
{
/*
@@ -1554,12 +1568,12 @@ VMMR3DECL(int) TMR3TimerDestroy(PTMTIMER pTimer)
case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
AssertMsgFailed(("%p:.enmState=%s %s\n", pTimer, tmTimerState(enmState), pTimer->pszDesc));
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
if (!RTThreadYield())
RTThreadSleep(1);
AssertMsgReturn(cRetries > 0, ("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, pTimer->pszDesc),
VERR_TM_UNSTABLE_STATE);
- tmTimerLock(pVM);
+ TM_LOCK_TIMERS(pVM);
continue;
/*
@@ -1567,12 +1581,12 @@ VMMR3DECL(int) TMR3TimerDestroy(PTMTIMER pTimer)
*/
case TMTIMERSTATE_FREE:
case TMTIMERSTATE_DESTROY:
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
AssertLogRelMsgFailedReturn(("pTimer=%p %s\n", pTimer, tmTimerState(enmState)), VERR_TM_INVALID_STATE);
default:
AssertMsgFailed(("Unknown timer state %d (%s)\n", enmState, R3STRING(pTimer->pszDesc)));
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
return VERR_TM_UNKNOWN_STATE;
}
@@ -1585,10 +1599,10 @@ VMMR3DECL(int) TMR3TimerDestroy(PTMTIMER pTimer)
if (fRc)
break;
AssertMsgFailed(("%p:.enmState=%s %s\n", pTimer, tmTimerState(enmState), pTimer->pszDesc));
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
AssertMsgReturn(cRetries > 0, ("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, pTimer->pszDesc),
VERR_TM_UNSTABLE_STATE);
- tmTimerLock(pVM);
+ TM_LOCK_TIMERS(pVM);
}
/*
@@ -1646,7 +1660,7 @@ VMMR3DECL(int) TMR3TimerDestroy(PTMTIMER pTimer)
#ifdef VBOX_STRICT
tmTimerQueuesSanityChecks(pVM, "TMR3TimerDestroy");
#endif
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
return VINF_SUCCESS;
}
@@ -1664,7 +1678,7 @@ VMM_INT_DECL(int) TMR3TimerDestroyDevice(PVM pVM, PPDMDEVINS pDevIns)
if (!pDevIns)
return VERR_INVALID_PARAMETER;
- tmTimerLock(pVM);
+ TM_LOCK_TIMERS(pVM);
PTMTIMER pCur = pVM->tm.s.pCreated;
while (pCur)
{
@@ -1677,7 +1691,7 @@ VMM_INT_DECL(int) TMR3TimerDestroyDevice(PVM pVM, PPDMDEVINS pDevIns)
AssertRC(rc);
}
}
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
LogFlow(("TMR3TimerDestroyDevice: returns VINF_SUCCESS\n"));
return VINF_SUCCESS;
@@ -1697,7 +1711,7 @@ VMM_INT_DECL(int) TMR3TimerDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns)
if (!pUsbIns)
return VERR_INVALID_PARAMETER;
- tmTimerLock(pVM);
+ TM_LOCK_TIMERS(pVM);
PTMTIMER pCur = pVM->tm.s.pCreated;
while (pCur)
{
@@ -1710,7 +1724,7 @@ VMM_INT_DECL(int) TMR3TimerDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns)
AssertRC(rc);
}
}
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
LogFlow(("TMR3TimerDestroyUsb: returns VINF_SUCCESS\n"));
return VINF_SUCCESS;
@@ -1730,7 +1744,7 @@ VMM_INT_DECL(int) TMR3TimerDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns)
if (!pDrvIns)
return VERR_INVALID_PARAMETER;
- tmTimerLock(pVM);
+ TM_LOCK_TIMERS(pVM);
PTMTIMER pCur = pVM->tm.s.pCreated;
while (pCur)
{
@@ -1743,7 +1757,7 @@ VMM_INT_DECL(int) TMR3TimerDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns)
AssertRC(rc);
}
}
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
LogFlow(("TMR3TimerDestroyDriver: returns VINF_SUCCESS\n"));
return VINF_SUCCESS;
@@ -1887,7 +1901,7 @@ VMMR3DECL(void) TMR3TimerQueuesDo(PVM pVM)
Log2(("TMR3TimerQueuesDo:\n"));
Assert(!pVM->tm.s.fRunningQueues);
ASMAtomicWriteBool(&pVM->tm.s.fRunningQueues, true);
- tmTimerLock(pVM);
+ TM_LOCK_TIMERS(pVM);
/*
* Process the queues.
@@ -1896,18 +1910,17 @@ VMMR3DECL(void) TMR3TimerQueuesDo(PVM pVM)
/* TMCLOCK_VIRTUAL_SYNC (see also TMR3VirtualSyncFF) */
STAM_PROFILE_ADV_START(&pVM->tm.s.aStatDoQueues[TMCLOCK_VIRTUAL_SYNC], s1);
- tmVirtualSyncLock(pVM);
+ PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_IGNORED);
ASMAtomicWriteBool(&pVM->tm.s.fRunningVirtualSyncQueue, true);
VMCPU_FF_CLEAR(pVCpuDst, VMCPU_FF_TIMER); /* Clear the FF once we started working for real. */
- if (pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC].offSchedule)
- tmTimerQueueSchedule(pVM, &pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC]);
+ Assert(!pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC].offSchedule);
tmR3TimerQueueRunVirtualSync(pVM);
if (pVM->tm.s.fVirtualSyncTicking) /** @todo move into tmR3TimerQueueRunVirtualSync - FIXME */
VM_FF_CLEAR(pVM, VM_FF_TM_VIRTUAL_SYNC);
ASMAtomicWriteBool(&pVM->tm.s.fRunningVirtualSyncQueue, false);
- tmVirtualSyncUnlock(pVM);
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
STAM_PROFILE_ADV_STOP(&pVM->tm.s.aStatDoQueues[TMCLOCK_VIRTUAL_SYNC], s1);
/* TMCLOCK_VIRTUAL */
@@ -1935,7 +1948,7 @@ VMMR3DECL(void) TMR3TimerQueuesDo(PVM pVM)
/* done */
Log2(("TMR3TimerQueuesDo: returns void\n"));
ASMAtomicWriteBool(&pVM->tm.s.fRunningQueues, false);
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
STAM_PROFILE_STOP(&pVM->tm.s.StatDoQueues, a);
}
@@ -2036,12 +2049,14 @@ static void tmR3TimerQueueRun(PVM pVM, PTMTIMERQUEUE pQueue)
*
* @param pVM The VM to run the timers for.
*
- * @remarks The caller must own both the TM/EMT and the Virtual Sync locks.
+ * @remarks The caller must the Virtual Sync lock. Owning the TM lock is no
+ * longer important.
*/
static void tmR3TimerQueueRunVirtualSync(PVM pVM)
{
PTMTIMERQUEUE const pQueue = &pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC];
VM_ASSERT_EMT(pVM);
+ Assert(PDMCritSectIsOwner(&pVM->tm.s.VirtualSyncLock));
/*
* Any timers?
@@ -2073,9 +2088,7 @@ static void tmR3TimerQueueRunVirtualSync(PVM pVM)
{
STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncRunStoppedAlready);
u64Now = pVM->tm.s.u64VirtualSync;
-#ifdef DEBUG_bird
Assert(u64Now <= pNext->u64Expire);
-#endif
}
else
{
@@ -2105,6 +2118,14 @@ static void tmR3TimerQueueRunVirtualSync(PVM pVM)
}
u64Now = u64VirtualNow - off;
+ /* Adjust against last returned time. */
+ uint64_t u64Last = ASMAtomicUoReadU64(&pVM->tm.s.u64VirtualSync);
+ if (u64Last > u64Now)
+ {
+ u64Now = u64Last + 1;
+ STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGetAdjLast);
+ }
+
/* Check if stopped by expired timer. */
uint64_t u64Expire = pNext->u64Expire;
if (u64Now >= pNext->u64Expire)
@@ -2115,14 +2136,19 @@ static void tmR3TimerQueueRunVirtualSync(PVM pVM)
ASMAtomicWriteBool(&pVM->tm.s.fVirtualSyncTicking, false);
Log4(("TM: %'RU64/-%'8RU64: exp tmr [tmR3TimerQueueRunVirtualSync]\n", u64Now, u64VirtualNow - u64Now - offSyncGivenUp));
}
- else if (fUpdateStuff)
+ else
{
- ASMAtomicWriteU64(&pVM->tm.s.offVirtualSync, off);
- ASMAtomicWriteU64(&pVM->tm.s.u64VirtualSyncCatchUpPrev, u64VirtualNow);
- if (fStopCatchup)
+ ASMAtomicWriteU64(&pVM->tm.s.u64VirtualSync, u64Now);
+ if (fUpdateStuff)
{
- ASMAtomicWriteBool(&pVM->tm.s.fVirtualSyncCatchUp, false);
- Log4(("TM: %'RU64/0: caught up [tmR3TimerQueueRunVirtualSync]\n", u64VirtualNow));
+ ASMAtomicWriteU64(&pVM->tm.s.offVirtualSync, off);
+ ASMAtomicWriteU64(&pVM->tm.s.u64VirtualSyncCatchUpPrev, u64VirtualNow);
+ ASMAtomicWriteU64(&pVM->tm.s.u64VirtualSync, u64Now);
+ if (fStopCatchup)
+ {
+ ASMAtomicWriteBool(&pVM->tm.s.fVirtualSyncCatchUp, false);
+ Log4(("TM: %'RU64/0: caught up [tmR3TimerQueueRunVirtualSync]\n", u64VirtualNow));
+ }
}
}
}
@@ -2133,87 +2159,73 @@ static void tmR3TimerQueueRunVirtualSync(PVM pVM)
u64Max = u64VirtualNow - offSyncGivenUp;
/* assert sanity */
-#ifdef DEBUG_bird
Assert(u64Now <= u64VirtualNow - offSyncGivenUp);
Assert(u64Max <= u64VirtualNow - offSyncGivenUp);
Assert(u64Now <= u64Max);
Assert(offSyncGivenUp == pVM->tm.s.offVirtualSyncGivenUp);
-#endif
/*
* Process the expired timers moving the clock along as we progress.
*/
-#ifdef DEBUG_bird
#ifdef VBOX_STRICT
uint64_t u64Prev = u64Now; NOREF(u64Prev);
#endif
-#endif
while (pNext && pNext->u64Expire <= u64Max)
{
- PTMTIMER pTimer = pNext;
+ /* Advance */
+ PTMTIMER pTimer = pNext;
pNext = TMTIMER_GET_NEXT(pTimer);
- PPDMCRITSECT pCritSect = pTimer->pCritSect;
+
+ /* Take the associated lock. */
+ PPDMCRITSECT pCritSect = pTimer->pCritSect;
if (pCritSect)
PDMCritSectEnter(pCritSect, VERR_INTERNAL_ERROR);
+
Log2(("tmR3TimerQueueRun: %p:{.enmState=%s, .enmClock=%d, .enmType=%d, u64Expire=%llx (now=%llx) .pszDesc=%s}\n",
pTimer, tmTimerState(pTimer->enmState), pTimer->enmClock, pTimer->enmType, pTimer->u64Expire, u64Now, pTimer->pszDesc));
- bool fRc;
- TM_TRY_SET_STATE(pTimer, TMTIMERSTATE_EXPIRED_GET_UNLINK, TMTIMERSTATE_ACTIVE, fRc);
- if (fRc)
- {
- /* unlink */
- const PTMTIMER pPrev = TMTIMER_GET_PREV(pTimer);
- if (pPrev)
- TMTIMER_SET_NEXT(pPrev, pNext);
- else
- {
- TMTIMER_SET_HEAD(pQueue, pNext);
- pQueue->u64Expire = pNext ? pNext->u64Expire : INT64_MAX;
- }
- if (pNext)
- TMTIMER_SET_PREV(pNext, pPrev);
- pTimer->offNext = 0;
- pTimer->offPrev = 0;
- /* advance the clock - don't permit timers to be out of order or armed in the 'past'. */
-#ifdef DEBUG_bird
+ /* Advance the clock - don't permit timers to be out of order or armed
+ in the 'past'. */
#ifdef VBOX_STRICT
- AssertMsg(pTimer->u64Expire >= u64Prev, ("%'RU64 < %'RU64 %s\n", pTimer->u64Expire, u64Prev, pTimer->pszDesc));
- u64Prev = pTimer->u64Expire;
+ AssertMsg(pTimer->u64Expire >= u64Prev, ("%'RU64 < %'RU64 %s\n", pTimer->u64Expire, u64Prev, pTimer->pszDesc));
+ u64Prev = pTimer->u64Expire;
#endif
-#endif
- ASMAtomicWriteU64(&pVM->tm.s.u64VirtualSync, pTimer->u64Expire);
- ASMAtomicWriteBool(&pVM->tm.s.fVirtualSyncTicking, false);
+ ASMAtomicWriteU64(&pVM->tm.s.u64VirtualSync, pTimer->u64Expire);
+ ASMAtomicWriteBool(&pVM->tm.s.fVirtualSyncTicking, false);
- /* fire */
- TM_SET_STATE(pTimer, TMTIMERSTATE_EXPIRED_DELIVER);
- switch (pTimer->enmType)
- {
- case TMTIMERTYPE_DEV: pTimer->u.Dev.pfnTimer(pTimer->u.Dev.pDevIns, pTimer, pTimer->pvUser); break;
- case TMTIMERTYPE_USB: pTimer->u.Usb.pfnTimer(pTimer->u.Usb.pUsbIns, pTimer, pTimer->pvUser); break;
- case TMTIMERTYPE_DRV: pTimer->u.Drv.pfnTimer(pTimer->u.Drv.pDrvIns, pTimer, pTimer->pvUser); break;
- case TMTIMERTYPE_INTERNAL: pTimer->u.Internal.pfnTimer(pVM, pTimer, pTimer->pvUser); break;
- case TMTIMERTYPE_EXTERNAL: pTimer->u.External.pfnTimer(pTimer->pvUser); break;
- default:
- AssertMsgFailed(("Invalid timer type %d (%s)\n", pTimer->enmType, pTimer->pszDesc));
- break;
- }
+ /* Unlink it, change the state and do the callout. */
+ tmTimerQueueUnlinkActive(pQueue, pTimer);
+ TM_SET_STATE(pTimer, TMTIMERSTATE_EXPIRED_DELIVER);
+ switch (pTimer->enmType)
+ {
+ case TMTIMERTYPE_DEV: pTimer->u.Dev.pfnTimer(pTimer->u.Dev.pDevIns, pTimer, pTimer->pvUser); break;
+ case TMTIMERTYPE_USB: pTimer->u.Usb.pfnTimer(pTimer->u.Usb.pUsbIns, pTimer, pTimer->pvUser); break;
+ case TMTIMERTYPE_DRV: pTimer->u.Drv.pfnTimer(pTimer->u.Drv.pDrvIns, pTimer, pTimer->pvUser); break;
+ case TMTIMERTYPE_INTERNAL: pTimer->u.Internal.pfnTimer(pVM, pTimer, pTimer->pvUser); break;
+ case TMTIMERTYPE_EXTERNAL: pTimer->u.External.pfnTimer(pTimer->pvUser); break;
+ default:
+ AssertMsgFailed(("Invalid timer type %d (%s)\n", pTimer->enmType, pTimer->pszDesc));
+ break;
+ }
- /* Change the state if it wasn't changed already in the handler.
- Reset the Hz hint too since this is the same as TMTimerStop. */
- TM_TRY_SET_STATE(pTimer, TMTIMERSTATE_STOPPED, TMTIMERSTATE_EXPIRED_DELIVER, fRc);
- if (fRc && pTimer->uHzHint)
- {
- if (pTimer->uHzHint >= pVM->tm.s.uMaxHzHint)
- ASMAtomicWriteBool(&pVM->tm.s.fHzHintNeedsUpdating, true);
- pTimer->uHzHint = 0;
- }
- Log2(("tmR3TimerQueueRun: new state %s\n", tmTimerState(pTimer->enmState)));
+ /* Change the state if it wasn't changed already in the handler.
+ Reset the Hz hint too since this is the same as TMTimerStop. */
+ bool fRc;
+ TM_TRY_SET_STATE(pTimer, TMTIMERSTATE_STOPPED, TMTIMERSTATE_EXPIRED_DELIVER, fRc);
+ if (fRc && pTimer->uHzHint)
+ {
+ if (pTimer->uHzHint >= pVM->tm.s.uMaxHzHint)
+ ASMAtomicWriteBool(&pVM->tm.s.fHzHintNeedsUpdating, true);
+ pTimer->uHzHint = 0;
}
+ Log2(("tmR3TimerQueueRun: new state %s\n", tmTimerState(pTimer->enmState)));
+
+ /* Leave the associated lock. */
if (pCritSect)
PDMCritSectLeave(pCritSect);
} /* run loop */
+
/*
* Restart the clock if it was stopped to serve any timers,
* and start/adjust catch-up if necessary.
@@ -2226,9 +2238,7 @@ static void tmR3TimerQueueRunVirtualSync(PVM pVM)
/* calc the slack we've handed out. */
const uint64_t u64VirtualNow2 = TMVirtualGetNoCheck(pVM);
Assert(u64VirtualNow2 >= u64VirtualNow);
-#ifdef DEBUG_bird
AssertMsg(pVM->tm.s.u64VirtualSync >= u64Now, ("%'RU64 < %'RU64\n", pVM->tm.s.u64VirtualSync, u64Now));
-#endif
const uint64_t offSlack = pVM->tm.s.u64VirtualSync - u64Now;
STAM_STATS({
if (offSlack)
@@ -2347,7 +2357,7 @@ static void tmR3TimerQueueRunVirtualSync(PVM pVM)
*
* @thread EMTs
*/
-VMM_INT_DECL(void) TMR3VirtualSyncFF(PVM pVM, PVMCPU pVCpu)
+VMMR3_INT_DECL(void) TMR3VirtualSyncFF(PVM pVM, PVMCPU pVCpu)
{
Log2(("TMR3VirtualSyncFF:\n"));
@@ -2368,20 +2378,20 @@ VMM_INT_DECL(void) TMR3VirtualSyncFF(PVM pVM, PVMCPU pVCpu)
else
{
STAM_PROFILE_START(&pVM->tm.s.StatVirtualSyncFF, a);
- tmVirtualSyncLock(pVM);
+ PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_IGNORED);
if (pVM->tm.s.fVirtualSyncTicking)
{
STAM_PROFILE_STOP(&pVM->tm.s.StatVirtualSyncFF, a); /* before the unlock! */
- tmVirtualSyncUnlock(pVM);
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
Log2(("TMR3VirtualSyncFF: ticking\n"));
}
else
{
- tmVirtualSyncUnlock(pVM);
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
/* try run it. */
- tmTimerLock(pVM);
- tmVirtualSyncLock(pVM);
+ TM_LOCK_TIMERS(pVM);
+ PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_IGNORED);
if (pVM->tm.s.fVirtualSyncTicking)
Log2(("TMR3VirtualSyncFF: ticking (2)\n"));
else
@@ -2389,8 +2399,7 @@ VMM_INT_DECL(void) TMR3VirtualSyncFF(PVM pVM, PVMCPU pVCpu)
ASMAtomicWriteBool(&pVM->tm.s.fRunningVirtualSyncQueue, true);
Log2(("TMR3VirtualSyncFF: running queue\n"));
- if (pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC].offSchedule)
- tmTimerQueueSchedule(pVM, &pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC]);
+ Assert(!pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC].offSchedule);
tmR3TimerQueueRunVirtualSync(pVM);
if (pVM->tm.s.fVirtualSyncTicking) /** @todo move into tmR3TimerQueueRunVirtualSync - FIXME */
VM_FF_CLEAR(pVM, VM_FF_TM_VIRTUAL_SYNC);
@@ -2398,8 +2407,8 @@ VMM_INT_DECL(void) TMR3VirtualSyncFF(PVM pVM, PVMCPU pVCpu)
ASMAtomicWriteBool(&pVM->tm.s.fRunningVirtualSyncQueue, false);
}
STAM_PROFILE_STOP(&pVM->tm.s.StatVirtualSyncFF, a); /* before the unlock! */
- tmVirtualSyncUnlock(pVM);
- tmTimerUnlock(pVM);
+ PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
+ TM_UNLOCK_TIMERS(pVM);
}
}
}
@@ -2485,10 +2494,12 @@ VMMR3DECL(int) TMR3TimerLoad(PTMTIMERR3 pTimer, PSSMHANDLE pSSM)
return SSMR3HandleSetStatus(pSSM, VERR_TM_LOAD_STATE);
}
- /* Enter the critical section to make TMTimerSet/Stop happy. */
+ /* Enter the critical sections to make TMTimerSet/Stop happy. */
+ if (pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC)
+ PDMCritSectEnter(&pTimer->pVMR3->tm.s.VirtualSyncLock, VERR_IGNORED);
PPDMCRITSECT pCritSect = pTimer->pCritSect;
if (pCritSect)
- PDMCritSectEnter(pCritSect, VERR_INTERNAL_ERROR);
+ PDMCritSectEnter(pCritSect, VERR_IGNORED);
if (u8State == TMTIMERSTATE_SAVED_PENDING_SCHEDULE)
{
@@ -2517,6 +2528,8 @@ VMMR3DECL(int) TMR3TimerLoad(PTMTIMERR3 pTimer, PSSMHANDLE pSSM)
if (pCritSect)
PDMCritSectLeave(pCritSect);
+ if (pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC)
+ PDMCritSectLeave(&pTimer->pVMR3->tm.s.VirtualSyncLock);
/*
* On failure set SSM status.
@@ -2577,7 +2590,7 @@ VMMR3DECL(int) TMR3TimerSetCritSect(PTMTIMERR3 pTimer, PPDMCRITSECT pCritSect)
* @param pVM The VM instance.
* @param pTime Where to store the time.
*/
-VMM_INT_DECL(PRTTIMESPEC) TMR3UtcNow(PVM pVM, PRTTIMESPEC pTime)
+VMMR3_INT_DECL(PRTTIMESPEC) TMR3UtcNow(PVM pVM, PRTTIMESPEC pTime)
{
RTTimeNow(pTime);
RTTimeSpecSubNano(pTime, ASMAtomicReadU64(&pVM->tm.s.offVirtualSync) - ASMAtomicReadU64((uint64_t volatile *)&pVM->tm.s.offVirtualSyncGivenUp));
@@ -2601,9 +2614,9 @@ VMMR3DECL(int) TMR3NotifySuspend(PVM pVM, PVMCPU pVCpu)
/*
* The shared virtual clock (includes virtual sync which is tied to it).
*/
- tmTimerLock(pVM); /* Paranoia: Exploiting the timer lock here. */
+ TM_LOCK_TIMERS(pVM); /* Paranoia: Exploiting the timer lock here. */
int rc = tmVirtualPauseLocked(pVM);
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
if (RT_FAILURE(rc))
return rc;
@@ -2665,9 +2678,9 @@ VMMR3DECL(int) TMR3NotifyResume(PVM pVM, PVMCPU pVCpu)
/*
* The shared virtual clock (includes virtual sync which is tied to it).
*/
- tmTimerLock(pVM); /* Paranoia: Exploiting the timer lock here. */
+ TM_LOCK_TIMERS(pVM); /* Paranoia: Exploiting the timer lock here. */
rc = tmVirtualResumeLocked(pVM);
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
return rc;
}
@@ -2712,7 +2725,7 @@ static DECLCALLBACK(int) tmR3SetWarpDrive(PVM pVM, uint32_t u32Percent)
* If the time is running we'll have to pause it before we can change
* the warp drive settings.
*/
- tmTimerLock(pVM); /* Paranoia: Exploiting the timer lock here. */
+ TM_LOCK_TIMERS(pVM); /* Paranoia: Exploiting the timer lock here. */
bool fPaused = !!pVM->tm.s.cVirtualTicking;
if (fPaused) /** @todo this isn't really working, but wtf. */
TMR3NotifySuspend(pVM, pVCpu);
@@ -2724,7 +2737,7 @@ static DECLCALLBACK(int) tmR3SetWarpDrive(PVM pVM, uint32_t u32Percent)
if (fPaused)
TMR3NotifyResume(pVM, pVCpu);
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
return VINF_SUCCESS;
}
@@ -2953,7 +2966,7 @@ static DECLCALLBACK(void) tmR3TimerInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char
"Expire",
"HzHint",
"State");
- tmTimerLock(pVM);
+ TM_LOCK_TIMERS(pVM);
for (PTMTIMERR3 pTimer = pVM->tm.s.pCreated; pTimer; pTimer = pTimer->pBigNext)
{
pHlp->pfnPrintf(pHlp,
@@ -2969,7 +2982,7 @@ static DECLCALLBACK(void) tmR3TimerInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char
tmTimerState(pTimer->enmState),
pTimer->pszDesc);
}
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
}
@@ -2997,7 +3010,7 @@ static DECLCALLBACK(void) tmR3TimerInfoActive(PVM pVM, PCDBGFINFOHLP pHlp, const
"State");
for (unsigned iQueue = 0; iQueue < TMCLOCK_MAX; iQueue++)
{
- tmTimerLock(pVM);
+ TM_LOCK_TIMERS(pVM);
for (PTMTIMERR3 pTimer = TMTIMER_GET_HEAD(&pVM->tm.s.paTimerQueuesR3[iQueue]);
pTimer;
pTimer = TMTIMER_GET_NEXT(pTimer))
@@ -3015,7 +3028,7 @@ static DECLCALLBACK(void) tmR3TimerInfoActive(PVM pVM, PCDBGFINFOHLP pHlp, const
tmTimerState(pTimer->enmState),
pTimer->pszDesc);
}
- tmTimerUnlock(pVM);
+ TM_UNLOCK_TIMERS(pVM);
}
}
diff --git a/src/VBox/VMM/VMMR3/TRPM.cpp b/src/VBox/VMM/VMMR3/TRPM.cpp
index 9b7038058..c5a9a063e 100644
--- a/src/VBox/VMM/VMMR3/TRPM.cpp
+++ b/src/VBox/VMM/VMMR3/TRPM.cpp
@@ -1,4 +1,4 @@
-/* $Id: TRPM.cpp $ */
+/* $Id: TRPM.cpp 36823 2011-04-23 22:32:27Z vboxsync $ */
/** @file
* TRPM - The Trap Monitor.
*/
@@ -1467,7 +1467,9 @@ VMMR3DECL(int) TRPMR3InjectEvent(PVM pVM, PVMCPU pVCpu, TRPMEVENT enmEvent)
Log(("TRPMR3InjectEvent: CPU%d u8Interrupt=%d (%#x) rc=%Rrc\n", pVCpu->idCpu, u8Interrupt, u8Interrupt, rc));
if (RT_SUCCESS(rc))
{
+# ifndef IEM_VERIFICATION_MODE
if (HWACCMIsEnabled(pVM))
+# endif
{
rc = TRPMAssertTrap(pVCpu, u8Interrupt, enmEvent);
AssertRC(rc);
diff --git a/src/VBox/VMM/VMMR3/VBoxVMMDeps.cpp b/src/VBox/VMM/VMMR3/VBoxVMMDeps.cpp
index d36136595..54e6a9e83 100644
--- a/src/VBox/VMM/VMMR3/VBoxVMMDeps.cpp
+++ b/src/VBox/VMM/VMMR3/VBoxVMMDeps.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxVMMDeps.cpp $ */
+/* $Id: VBoxVMMDeps.cpp 35410 2011-01-05 17:21:11Z vboxsync $ */
/** @file
* VBoxVMM link dependencies - drag all we want into the link!
*/
diff --git a/src/VBox/VMM/VMMR3/VM.cpp b/src/VBox/VMM/VMMR3/VM.cpp
index 5e9b9dca7..c53d8c239 100644
--- a/src/VBox/VMM/VMMR3/VM.cpp
+++ b/src/VBox/VMM/VMMR3/VM.cpp
@@ -1,4 +1,4 @@
-/* $Id: VM.cpp $ */
+/* $Id: VM.cpp 37794 2011-07-06 10:24:07Z vboxsync $ */
/** @file
* VM - Virtual Machine
*/
@@ -54,6 +54,7 @@
#include <VBox/vmm/pdmapi.h>
#include <VBox/vmm/pdmcritsect.h>
#include <VBox/vmm/em.h>
+#include <VBox/vmm/iem.h>
#include <VBox/vmm/rem.h>
#include <VBox/vmm/tm.h>
#include <VBox/vmm/stam.h>
@@ -80,6 +81,7 @@
#include <iprt/time.h>
#include <iprt/semaphore.h>
#include <iprt/thread.h>
+#include <iprt/uuid.h>
/*******************************************************************************
@@ -272,10 +274,10 @@ VMMR3DECL(int) VMR3Create(uint32_t cCpus, PCVMM2USERMETHODS pVmm2UserMethods,
AssertMsgFailed(("VMR3ReqCallU failed rc=%Rrc\n", rc));
/*
- * An error occurred during VM creation. Set the error message directly
- * using the initial callback, as the callback list doesn't exist yet.
+ * An error occurred during VM creation. Set the error message directly
+ * using the initial callback, as the callback list might not exist yet.
*/
- const char *pszError = NULL;
+ const char *pszError;
switch (rc)
{
case VERR_VMX_IN_VMX_ROOT_MODE:
@@ -303,12 +305,6 @@ VMMR3DECL(int) VMR3Create(uint32_t cCpus, PCVMM2USERMETHODS pVmm2UserMethods,
#endif
break;
- case VERR_VERSION_MISMATCH:
- pszError = N_("VMMR0 driver version mismatch. Please terminate all VMs, make sure that "
- "VBoxNetDHCP is not running and try again. If you still get this error, "
- "re-install VirtualBox");
- break;
-
#ifdef RT_OS_LINUX
case VERR_SUPDRV_COMPONENT_NOT_FOUND:
pszError = N_("One of the kernel modules was not successfully loaded. Make sure "
@@ -347,11 +343,23 @@ VMMR3DECL(int) VMR3Create(uint32_t cCpus, PCVMM2USERMETHODS pVmm2UserMethods,
"pack' which must be downloaded and installed separately");
break;
+ case VERR_PCI_PASSTHROUGH_NO_HWACCM:
+ pszError = N_("PCI passthrough requires VT-x/AMD-V");
+ break;
+
+ case VERR_PCI_PASSTHROUGH_NO_NESTED_PAGING:
+ pszError = N_("PCI passthrough requires nested paging");
+ break;
+
default:
- pszError = N_("Unknown error creating VM");
+ if (VMR3GetErrorCountU(pUVM) == 0)
+ pszError = RTErrGetFull(rc);
+ else
+ pszError = NULL; /* already set. */
break;
}
- vmR3SetErrorU(pUVM, rc, RT_SRC_POS, pszError, rc);
+ if (pszError)
+ vmR3SetErrorU(pUVM, rc, RT_SRC_POS, pszError, rc);
}
else
{
@@ -466,11 +474,13 @@ static int vmR3CreateUVM(uint32_t cCpus, PCVMM2USERMETHODS pVmm2UserMethods, PUV
AssertCompile(sizeof(pUVM->vm.s) <= sizeof(pUVM->vm.padding));
+ pUVM->vm.s.cUvmRefs = 1;
pUVM->vm.s.ppAtStateNext = &pUVM->vm.s.pAtState;
pUVM->vm.s.ppAtErrorNext = &pUVM->vm.s.pAtError;
pUVM->vm.s.ppAtRuntimeErrorNext = &pUVM->vm.s.pAtRuntimeError;
pUVM->vm.s.enmHaltMethod = VMHALTMETHOD_BOOTSTRAP;
+ RTUuidClear(&pUVM->vm.s.Uuid);
/* Initialize the VMCPU array in the UVM. */
for (i = 0; i < cCpus; i++)
@@ -568,12 +578,10 @@ static int vmR3CreateUVM(uint32_t cCpus, PCVMM2USERMETHODS pVmm2UserMethods, PUV
*/
static int vmR3CreateU(PUVM pUVM, uint32_t cCpus, PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM)
{
- int rc = VINF_SUCCESS;
-
/*
* Load the VMMR0.r0 module so that we can call GVMMR0CreateVM.
*/
- rc = PDMR3LdrLoadVMMR0U(pUVM);
+ int rc = PDMR3LdrLoadVMMR0U(pUVM);
if (RT_FAILURE(rc))
{
/** @todo we need a cleaner solution for this (VERR_VMX_IN_VMX_ROOT_MODE).
@@ -603,6 +611,9 @@ static int vmR3CreateU(PUVM pUVM, uint32_t cCpus, PFNCFGMCONSTRUCTOR pfnCFGMCons
AssertRelease(pVM->cCpus == cCpus);
AssertRelease(pVM->uCpuExecutionCap == 100);
AssertRelease(pVM->offVMCPU == RT_UOFFSETOF(VM, aCpus));
+ AssertCompileMemberAlignment(VM, cpum, 64);
+ AssertCompileMemberAlignment(VM, tm, 64);
+ AssertCompileMemberAlignment(VM, aCpus, PAGE_SIZE);
Log(("VMR3Create: Created pUVM=%p pVM=%p pVMR0=%p hSelf=%#x cCpus=%RU32\n",
pUVM, pVM, pVM->pVMR0, pVM->hSelf, pVM->cCpus));
@@ -662,11 +673,33 @@ static int vmR3CreateU(PUVM pUVM, uint32_t cCpus, PFNCFGMCONSTRUCTOR pfnCFGMCons
rc = VERR_INVALID_PARAMETER;
}
}
+
+ /*
+ * Get the CPU execution cap.
+ */
if (RT_SUCCESS(rc))
{
rc = CFGMR3QueryU32Def(pRoot, "CpuExecutionCap", &pVM->uCpuExecutionCap, 100);
AssertLogRelMsgRC(rc, ("Configuration error: Querying \"CpuExecutionCap\" as integer failed, rc=%Rrc\n", rc));
+ }
+
+ /*
+ * Get the VM name and UUID.
+ */
+ if (RT_SUCCESS(rc))
+ {
+ rc = CFGMR3QueryStringAllocDef(pRoot, "Name", &pUVM->vm.s.pszName, "<unknown>");
+ AssertLogRelMsg(RT_SUCCESS(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND, ("Configuration error: Querying \"Name\" failed, rc=%Rrc\n", rc));
+ }
+ if (RT_SUCCESS(rc))
+ {
+ rc = CFGMR3QueryBytes(pRoot, "UUID", &pUVM->vm.s.Uuid, sizeof(pUVM->vm.s.Uuid));
+ AssertLogRelMsg(RT_SUCCESS(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND, ("Configuration error: Querying \"UUID\" failed, rc=%Rrc\n", rc));
+ }
+
+ if (RT_SUCCESS(rc))
+ {
/*
* Init the ring-3 components and ring-3 per cpu data, finishing it off
* by a relocation round (intermediate context finalization will do this).
@@ -904,36 +937,43 @@ static int vmR3InitRing3(PVM pVM, PUVM pUVM)
rc = EMR3Init(pVM);
if (RT_SUCCESS(rc))
{
- rc = DBGFR3Init(pVM);
+ rc = IEMR3Init(pVM);
if (RT_SUCCESS(rc))
{
- rc = PDMR3Init(pVM);
+ rc = DBGFR3Init(pVM);
if (RT_SUCCESS(rc))
{
- rc = PGMR3InitDynMap(pVM);
- if (RT_SUCCESS(rc))
- rc = MMR3HyperInitFinalize(pVM);
- if (RT_SUCCESS(rc))
- rc = PATMR3InitFinalize(pVM);
- if (RT_SUCCESS(rc))
- rc = PGMR3InitFinalize(pVM);
- if (RT_SUCCESS(rc))
- rc = SELMR3InitFinalize(pVM);
- if (RT_SUCCESS(rc))
- rc = TMR3InitFinalize(pVM);
- if (RT_SUCCESS(rc))
- rc = REMR3InitFinalize(pVM);
- if (RT_SUCCESS(rc))
- rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_RING3);
+ rc = PDMR3Init(pVM);
if (RT_SUCCESS(rc))
{
- LogFlow(("vmR3InitRing3: returns %Rrc\n", VINF_SUCCESS));
- return VINF_SUCCESS;
+ rc = PGMR3InitDynMap(pVM);
+ if (RT_SUCCESS(rc))
+ rc = MMR3HyperInitFinalize(pVM);
+ if (RT_SUCCESS(rc))
+ rc = PATMR3InitFinalize(pVM);
+ if (RT_SUCCESS(rc))
+ rc = PGMR3InitFinalize(pVM);
+ if (RT_SUCCESS(rc))
+ rc = SELMR3InitFinalize(pVM);
+ if (RT_SUCCESS(rc))
+ rc = TMR3InitFinalize(pVM);
+ if (RT_SUCCESS(rc))
+ rc = REMR3InitFinalize(pVM);
+ if (RT_SUCCESS(rc))
+ rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_RING3);
+ if (RT_SUCCESS(rc))
+ {
+ LogFlow(("vmR3InitRing3: returns %Rrc\n", VINF_SUCCESS));
+ return VINF_SUCCESS;
+ }
+
+ int rc2 = PDMR3Term(pVM);
+ AssertRC(rc2);
}
- int rc2 = PDMR3Term(pVM);
+ int rc2 = DBGFR3Term(pVM);
AssertRC(rc2);
}
- int rc2 = DBGFR3Term(pVM);
+ int rc2 = IEMR3Term(pVM);
AssertRC(rc2);
}
int rc2 = EMR3Term(pVM);
@@ -1010,13 +1050,12 @@ static int vmR3InitRing0(PVM pVM)
*/
if (RT_SUCCESS(rc))
rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_RING0);
+ if (RT_SUCCESS(rc))
+ rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_HWACCM);
- /** @todo Move this to the VMINITCOMPLETED_RING0 notification handler. */
+ /** @todo Move this to the VMINITCOMPLETED_HWACCM notification handler. */
if (RT_SUCCESS(rc))
- {
- rc = HWACCMR3InitFinalizeR0(pVM);
CPUMR3SetHWVirtEx(pVM, HWACCMIsEnabled(pVM));
- }
LogFlow(("vmR3InitRing0: returns %Rrc\n", rc));
return rc;
@@ -1067,6 +1106,8 @@ static int vmR3InitDoCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
int rc = VMMR3InitCompleted(pVM, enmWhat);
if (RT_SUCCESS(rc))
rc = HWACCMR3InitCompleted(pVM, enmWhat);
+ if (RT_SUCCESS(rc))
+ rc = PGMR3InitCompleted(pVM, enmWhat);
return rc;
}
@@ -1134,6 +1175,7 @@ VMMR3DECL(void) VMR3Relocate(PVM pVM, RTGCINTPTR offDelta)
IOMR3Relocate(pVM, offDelta);
EMR3Relocate(pVM);
TMR3Relocate(pVM, offDelta);
+ IEMR3Relocate(pVM);
DBGFR3Relocate(pVM, offDelta);
PDMR3Relocate(pVM, offDelta);
}
@@ -2268,7 +2310,7 @@ VMMR3DECL(int) VMR3Destroy(PVM pVM)
* Validate input.
*/
if (!pVM)
- return VERR_INVALID_PARAMETER;
+ return VERR_INVALID_VM_HANDLE;
VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
AssertLogRelReturn(!VM_IS_EMT(pVM), VERR_VM_THREAD_IS_EMT);
@@ -2371,6 +2413,8 @@ DECLCALLBACK(int) vmR3Destroy(PVM pVM)
AssertRC(rc);
rc = PDMR3Term(pVM);
AssertRC(rc);
+ rc = IEMR3Term(pVM);
+ AssertRC(rc);
rc = EMR3Term(pVM);
AssertRC(rc);
rc = IOMR3Term(pVM);
@@ -2494,7 +2538,7 @@ static void vmR3DestroyUVM(PUVM pUVM, uint32_t cMilliesEMTWait)
break;
for (PVMREQ pReq = pReqHead; pReq; pReq = pReq->pNext)
{
- ASMAtomicUoWriteSize(&pReq->iStatus, VERR_INTERNAL_ERROR);
+ ASMAtomicUoWriteS32(&pReq->iStatus, VERR_INTERNAL_ERROR);
ASMAtomicWriteSize(&pReq->enmState, VMREQSTATE_INVALID);
RTSemEventSignal(pReq->EventSem);
RTThreadSleep(2);
@@ -2519,7 +2563,7 @@ static void vmR3DestroyUVM(PUVM pUVM, uint32_t cMilliesEMTWait)
break;
for (PVMREQ pReq = pReqHead; pReq; pReq = pReq->pNext)
{
- ASMAtomicUoWriteSize(&pReq->iStatus, VERR_INTERNAL_ERROR);
+ ASMAtomicUoWriteS32(&pReq->iStatus, VERR_INTERNAL_ERROR);
ASMAtomicWriteSize(&pReq->enmState, VMREQSTATE_INVALID);
RTSemEventSignal(pReq->EventSem);
RTThreadSleep(2);
@@ -2546,19 +2590,16 @@ static void vmR3DestroyUVM(PUVM pUVM, uint32_t cMilliesEMTWait)
}
/*
- * Destroy the MM heap and free the UVM structure.
+ * Release the UVM structure reference.
*/
- MMR3TermUVM(pUVM);
- STAMR3TermUVM(pUVM);
+ VMR3ReleaseUVM(pUVM);
+ /*
+ * Clean up and flush logs.
+ */
#ifdef LOG_ENABLED
RTLogSetCustomPrefixCallback(NULL, NULL, NULL);
#endif
- RTTlsFree(pUVM->vm.s.idxTLS);
-
- ASMAtomicUoWriteU32(&pUVM->u32Magic, UINT32_MAX);
- RTMemPageFree(pUVM, RT_OFFSETOF(UVM, aCpus[pUVM->cCpus]));
-
RTLogFlush(NULL);
}
@@ -2857,6 +2898,131 @@ VMMR3DECL(int) VMR3Reset(PVM pVM)
/**
+ * Gets the user mode VM structure pointer given the VM handle.
+ *
+ * @returns Pointer to the user mode VM structure on success. NULL if @a pVM is
+ * invalid (asserted).
+ * @param pVM The VM handle.
+ * @sa VMR3GetVM, VMR3RetainUVM
+ */
+VMMR3DECL(PUVM) VMR3GetUVM(PVM pVM)
+{
+ VM_ASSERT_VALID_EXT_RETURN(pVM, NULL);
+ return pVM->pUVM;
+}
+
+
+/**
+ * Gets the shared VM structure pointer given the pointer to the user mode VM
+ * structure.
+ *
+ * @returns Pointer to the shared VM structure.
+ * NULL if @a pUVM is invalid (asserted) or if no shared VM structure
+ * is currently associated with it.
+ * @param pUVM The user mode VM handle.
+ * @sa VMR3GetUVM
+ */
+VMMR3DECL(PVM) VMR3GetVM(PUVM pUVM)
+{
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
+ return pUVM->pVM;
+}
+
+
+/**
+ * Retain the user mode VM handle.
+ *
+ * @returns Reference count.
+ * UINT32_MAX if @a pUVM is invalid.
+ *
+ * @param pUVM The user mode VM handle.
+ * @sa VMR3ReleaseUVM
+ */
+VMMR3DECL(uint32_t) VMR3RetainUVM(PUVM pUVM)
+{
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, UINT32_MAX);
+ uint32_t cRefs = ASMAtomicIncU32(&pUVM->vm.s.cUvmRefs);
+ AssertMsg(cRefs > 0 && cRefs < _64K, ("%u\n", cRefs));
+ return cRefs;
+}
+
+
+/**
+ * Does the final release of the UVM structure.
+ *
+ * @param pUVM The user mode VM handle.
+ */
+static void vmR3DoReleaseUVM(PUVM pUVM)
+{
+ /*
+ * Free the UVM.
+ */
+ Assert(!pUVM->pVM);
+
+ MMR3TermUVM(pUVM);
+ STAMR3TermUVM(pUVM);
+
+ ASMAtomicUoWriteU32(&pUVM->u32Magic, UINT32_MAX);
+ RTTlsFree(pUVM->vm.s.idxTLS);
+ RTMemPageFree(pUVM, RT_OFFSETOF(UVM, aCpus[pUVM->cCpus]));
+}
+
+
+/**
+ * Releases a refernece to the mode VM handle.
+ *
+ * @returns The new reference count, 0 if destroyed.
+ * UINT32_MAX if @a pUVM is invalid.
+ *
+ * @param pUVM The user mode VM handle.
+ * @sa VMR3RetainUVM
+ */
+VMMR3DECL(uint32_t) VMR3ReleaseUVM(PUVM pUVM)
+{
+ if (!pUVM)
+ return 0;
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, UINT32_MAX);
+ uint32_t cRefs = ASMAtomicDecU32(&pUVM->vm.s.cUvmRefs);
+ if (!cRefs)
+ vmR3DoReleaseUVM(pUVM);
+ else
+ AssertMsg(cRefs < _64K, ("%u\n", cRefs));
+ return cRefs;
+}
+
+
+/**
+ * Gets the VM name.
+ *
+ * @returns Pointer to a read-only string containing the name. NULL if called
+ * too early.
+ * @param pUVM The user mode VM handle.
+ */
+VMMR3DECL(const char *) VMR3GetName(PUVM pUVM)
+{
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
+ return pUVM->vm.s.pszName;
+}
+
+
+/**
+ * Gets the VM UUID.
+ *
+ * @returns pUuid on success, NULL on failure.
+ * @param pUVM The user mode VM handle.
+ * @param pUuid Where to store the UUID.
+ */
+VMMR3DECL(PRTUUID) VMR3GetUuid(PUVM pUVM, PRTUUID pUuid)
+{
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
+ AssertPtrReturn(pUuid, NULL);
+
+ *pUuid = pUVM->vm.s.Uuid;
+ return pUuid;
+}
+
+
+/**
* Gets the current VM state.
*
* @returns The current VM state.
@@ -2865,11 +3031,28 @@ VMMR3DECL(int) VMR3Reset(PVM pVM)
*/
VMMR3DECL(VMSTATE) VMR3GetState(PVM pVM)
{
+ VM_ASSERT_VALID_EXT_RETURN(pVM, VMSTATE_TERMINATED);
return pVM->enmVMState;
}
/**
+ * Gets the current VM state.
+ *
+ * @returns The current VM state.
+ * @param pUVM The user-mode VM handle.
+ * @thread Any
+ */
+VMMR3DECL(VMSTATE) VMR3GetStateU(PUVM pUVM)
+{
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, VMSTATE_TERMINATED);
+ if (RT_UNLIKELY(!pUVM->pVM))
+ return VMSTATE_TERMINATED;
+ return pUVM->pVM->enmVMState;
+}
+
+
+/**
* Gets the state name string for a VM state.
*
* @returns Pointer to the state name. (readonly)
@@ -3464,6 +3647,7 @@ VMMR3DECL(int) VMR3AtStateDeregister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvU
*/
VMMR3DECL(int) VMR3AtErrorRegister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser)
{
+ VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
return VMR3AtErrorRegisterU(pVM->pUVM, pfnAtError, pvUser);
}
@@ -3650,7 +3834,24 @@ VMMR3DECL(void) VMR3SetErrorWorker(PVM pVM)
*/
VMMR3DECL(uint32_t) VMR3GetErrorCount(PVM pVM)
{
- return pVM->pUVM->vm.s.cErrors;
+ AssertPtrReturn(pVM, 0);
+ return VMR3GetErrorCountU(pVM->pUVM);
+}
+
+
+/**
+ * Gets the number of errors raised via VMSetError.
+ *
+ * This can be used avoid double error messages.
+ *
+ * @returns The error count.
+ * @param pVM The VM handle.
+ */
+VMMR3DECL(uint32_t) VMR3GetErrorCountU(PUVM pUVM)
+{
+ AssertPtrReturn(pUVM, 0);
+ AssertReturn(pUVM->u32Magic == UVM_MAGIC, 0);
+ return pUVM->vm.s.cErrors;
}
@@ -4157,9 +4358,18 @@ VMMR3DECL(RTTHREAD) VMR3GetVMCPUThreadU(PUVM pUVM)
*/
VMMR3DECL(int) VMR3GetCpuCoreAndPackageIdFromCpuId(PVM pVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage)
{
+ /*
+ * Validate input.
+ */
+ VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
+ AssertPtrReturn(pidCpuCore, VERR_INVALID_POINTER);
+ AssertPtrReturn(pidCpuPackage, VERR_INVALID_POINTER);
if (idCpu >= pVM->cCpus)
return VERR_INVALID_CPU_ID;
+ /*
+ * Set return values.
+ */
#ifdef VBOX_WITH_MULTI_CORE
*pidCpuCore = idCpu;
*pidCpuPackage = 0;
@@ -4211,6 +4421,7 @@ static DECLCALLBACK(int) vmR3HotUnplugCpu(PVM pVM, VMCPUID idCpu)
*/
VMMR3DECL(int) VMR3HotUnplugCpu(PVM pVM, VMCPUID idCpu)
{
+ VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
/** @todo r=bird: Don't destroy the EMT, it'll break VMMR3EmtRendezvous and
@@ -4230,6 +4441,7 @@ VMMR3DECL(int) VMR3HotUnplugCpu(PVM pVM, VMCPUID idCpu)
*/
VMMR3DECL(int) VMR3HotPlugCpu(PVM pVM, VMCPUID idCpu)
{
+ VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
/** @todo r-bird: Just mark it online and make sure it waits on SPIP. */
@@ -4242,15 +4454,17 @@ VMMR3DECL(int) VMR3HotPlugCpu(PVM pVM, VMCPUID idCpu)
*
* @returns VBox status code.
* @param pVM The VM to operate on.
- * @param ulCpuExecutionCap New CPU execution cap
+ * @param uCpuExecutionCap New CPU execution cap in precent, 1-100. Where
+ * 100 is max performance (default).
*/
-VMMR3DECL(int) VMR3SetCpuExecutionCap(PVM pVM, unsigned ulCpuExecutionCap)
+VMMR3DECL(int) VMR3SetCpuExecutionCap(PVM pVM, uint32_t uCpuExecutionCap)
{
- AssertReturn(ulCpuExecutionCap > 0 && ulCpuExecutionCap <= 100, VERR_INVALID_PARAMETER);
+ VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
+ AssertReturn(uCpuExecutionCap > 0 && uCpuExecutionCap <= 100, VERR_INVALID_PARAMETER);
- Log(("VMR3SetCpuExecutionCap: new priority = %d\n", ulCpuExecutionCap));
+ Log(("VMR3SetCpuExecutionCap: new priority = %d\n", uCpuExecutionCap));
/* Note: not called from EMT. */
- pVM->uCpuExecutionCap = ulCpuExecutionCap;
+ pVM->uCpuExecutionCap = uCpuExecutionCap;
return VINF_SUCCESS;
}
diff --git a/src/VBox/VMM/VMMR3/VMEmt.cpp b/src/VBox/VMM/VMMR3/VMEmt.cpp
index 6465544dd..15d6e289d 100644
--- a/src/VBox/VMM/VMMR3/VMEmt.cpp
+++ b/src/VBox/VMM/VMMR3/VMEmt.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMEmt.cpp $ */
+/* $Id: VMEmt.cpp 36437 2011-03-25 15:36:59Z vboxsync $ */
/** @file
* VM - Virtual Machine, The Emulation Thread.
*/
diff --git a/src/VBox/VMM/VMMR3/VMM.cpp b/src/VBox/VMM/VMMR3/VMM.cpp
index 38accfdb2..f0e8eeec5 100644
--- a/src/VBox/VMM/VMMR3/VMM.cpp
+++ b/src/VBox/VMM/VMMR3/VMM.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMM.cpp $ */
+/* $Id: VMM.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* VMM - The Virtual Machine Monitor Core.
*/
@@ -44,6 +44,30 @@
*
* To be written.
*
+ *
+ * @sections sec_vmm_limits VMM Limits
+ *
+ * There are various resource limits imposed by the VMM and it's
+ * sub-components. We'll list some of them here.
+ *
+ * On 64-bit hosts:
+ * - Max 1023 VMs. Imposed by GVMM's handle allocation
+ * (GVMM_MAX_HANDLES), can be increased up to 64K.
+ * - Max 16TB - 64KB of the host memory can be used for backing VM RAM and
+ * ROM pages. The limit is imposed by the 32-bit page ID used by GMM.
+ * - A VM can be assigned all the memory we can use (16TB), however, the
+ * Main API will restrict this to 2TB (MM_RAM_MAX_IN_MB).
+ * - Max 32 virtual CPUs (VMM_MAX_CPU_COUNT).
+ *
+ * On 32-bit hosts:
+ * - Max 127 VMs. Imposed by GMM's per page structure.
+ * - Max 64GB - 64KB of the host memory can be used for backing VM RAM and
+ * ROM pages. The limit is imposed by the 28-bit page ID used
+ * internally in GMM. It is also limited by PAE.
+ * - A VM can be assigned all the memory GMM can allocate, however, the
+ * Main API will restrict this to 3584MB (MM_RAM_MAX_IN_MB).
+ * - Max 32 virtual CPUs (VMM_MAX_CPU_COUNT).
+ *
*/
/*******************************************************************************
@@ -78,7 +102,6 @@
#include <VBox/err.h>
#include <VBox/param.h>
#include <VBox/version.h>
-#include <VBox/x86.h>
#include <VBox/vmm/hwaccm.h>
#include <iprt/assert.h>
#include <iprt/alloc.h>
@@ -89,6 +112,7 @@
#include <iprt/string.h>
#include <iprt/stdarg.h>
#include <iprt/ctype.h>
+#include <iprt/x86.h>
@@ -314,6 +338,7 @@ static int vmmR3InitStacks(PVM pVM)
static int vmmR3InitLoggers(PVM pVM)
{
int rc;
+#define RTLogCalcSizeForR0(cGroups, fFlags) (RT_OFFSETOF(VMMR0LOGGER, Logger.afGroups[cGroups]) + PAGE_SIZE)
/*
* Allocate RC & R0 Logger instances (they are finalized in the relocator).
@@ -329,18 +354,17 @@ static int vmmR3InitLoggers(PVM pVM)
pVM->vmm.s.pRCLoggerRC = MMHyperR3ToRC(pVM, pVM->vmm.s.pRCLoggerR3);
# ifdef VBOX_WITH_R0_LOGGING
+ size_t const cbLogger = RTLogCalcSizeForR0(pLogger->cGroups, 0);
for (VMCPUID i = 0; i < pVM->cCpus; i++)
{
PVMCPU pVCpu = &pVM->aCpus[i];
-
- rc = MMR3HyperAllocOnceNoRelEx(pVM, RT_OFFSETOF(VMMR0LOGGER, Logger.afGroups[pLogger->cGroups]),
- 0, MM_TAG_VMM, MMHYPER_AONR_FLAGS_KERNEL_MAPPING,
+ rc = MMR3HyperAllocOnceNoRelEx(pVM, cbLogger, PAGE_SIZE, MM_TAG_VMM, MMHYPER_AONR_FLAGS_KERNEL_MAPPING,
(void **)&pVCpu->vmm.s.pR0LoggerR3);
if (RT_FAILURE(rc))
return rc;
- pVCpu->vmm.s.pR0LoggerR3->pVM = pVM->pVMR0;
+ pVCpu->vmm.s.pR0LoggerR3->pVM = pVM->pVMR0;
//pVCpu->vmm.s.pR0LoggerR3->fCreated = false;
- pVCpu->vmm.s.pR0LoggerR3->cbLogger = RT_OFFSETOF(RTLOGGER, afGroups[pLogger->cGroups]);
+ pVCpu->vmm.s.pR0LoggerR3->cbLogger = (uint32_t)cbLogger;
pVCpu->vmm.s.pR0LoggerR0 = MMHyperR3ToR0(pVM, pVCpu->vmm.s.pR0LoggerR3);
}
# endif
@@ -425,6 +449,7 @@ static void vmmR3InitRegisterStats(PVM pVM)
STAM_REG(pVM, &pVM->vmm.s.StatRZRetPatchTPR, STAMTYPE_COUNTER, "/VMM/RZRet/PatchTPR", STAMUNIT_OCCURENCES, "Number of VINF_EM_HWACCM_PATCH_TPR_INSTR returns.");
STAM_REG(pVM, &pVM->vmm.s.StatRZRetCallRing3, STAMTYPE_COUNTER, "/VMM/RZCallR3/Misc", STAMUNIT_OCCURENCES, "Number of Other ring-3 calls.");
STAM_REG(pVM, &pVM->vmm.s.StatRZCallPDMLock, STAMTYPE_COUNTER, "/VMM/RZCallR3/PDMLock", STAMUNIT_OCCURENCES, "Number of VMMCALLRING3_PDM_LOCK calls.");
+ STAM_REG(pVM, &pVM->vmm.s.StatRZCallPDMCritSectEnter, STAMTYPE_COUNTER, "/VMM/RZCallR3/PDMCritSectEnter", STAMUNIT_OCCURENCES, "Number of VMMCALLRING3_PDM_CRITSECT_ENTER calls.");
STAM_REG(pVM, &pVM->vmm.s.StatRZCallPGMLock, STAMTYPE_COUNTER, "/VMM/RZCallR3/PGMLock", STAMUNIT_OCCURENCES, "Number of VMMCALLRING3_PGM_LOCK calls.");
STAM_REG(pVM, &pVM->vmm.s.StatRZCallPGMPoolGrow, STAMTYPE_COUNTER, "/VMM/RZCallR3/PGMPoolGrow", STAMUNIT_OCCURENCES, "Number of VMMCALLRING3_PGM_POOL_GROW calls.");
STAM_REG(pVM, &pVM->vmm.s.StatRZCallPGMMapChunk, STAMTYPE_COUNTER, "/VMM/RZCallR3/PGMMapChunk", STAMUNIT_OCCURENCES, "Number of VMMCALLRING3_PGM_MAP_CHUNK calls.");
@@ -487,7 +512,7 @@ VMMR3_INT_DECL(int) VMMR3InitR0(PVM pVM)
#ifdef LOG_ENABLED
if ( pVCpu->vmm.s.pR0LoggerR3
&& pVCpu->vmm.s.pR0LoggerR3->Logger.offScratch > 0)
- RTLogFlushToLogger(&pVCpu->vmm.s.pR0LoggerR3->Logger, NULL);
+ RTLogFlushR0(NULL, &pVCpu->vmm.s.pR0LoggerR3->Logger);
#endif
if (rc != VINF_VMM_CALL_HOST)
break;
@@ -835,7 +860,7 @@ VMMR3_INT_DECL(int) VMMR3UpdateLoggers(PVM pVM)
pVM->vmm.s.pRCLoggerRC = MMHyperR3ToRC(pVM, pVM->vmm.s.pRCLoggerR3);
rc = RTLogCloneRC(NULL /* default */, pVM->vmm.s.pRCLoggerR3, pVM->vmm.s.cbRCLogger,
- RCPtrLoggerWrapper, RCPtrLoggerFlush, RTLOGFLAGS_BUFFERED);
+ RCPtrLoggerWrapper, RCPtrLoggerFlush, RTLOGFLAGS_BUFFERED);
AssertReleaseMsgRC(rc, ("RTLogCloneRC failed! rc=%Rra\n", rc));
}
@@ -848,7 +873,7 @@ VMMR3_INT_DECL(int) VMMR3UpdateLoggers(PVM pVM)
pVM->vmm.s.pRCRelLoggerRC = MMHyperR3ToRC(pVM, pVM->vmm.s.pRCRelLoggerR3);
rc = RTLogCloneRC(RTLogRelDefaultInstance(), pVM->vmm.s.pRCRelLoggerR3, pVM->vmm.s.cbRCRelLogger,
- RCPtrLoggerWrapper, RCPtrLoggerFlush, RTLOGFLAGS_BUFFERED);
+ RCPtrLoggerWrapper, RCPtrLoggerFlush, RTLOGFLAGS_BUFFERED);
AssertReleaseMsgRC(rc, ("RTLogCloneRC failed! rc=%Rra\n", rc));
}
#endif /* VBOX_WITH_RC_RELEASE_LOGGING */
@@ -858,6 +883,7 @@ VMMR3_INT_DECL(int) VMMR3UpdateLoggers(PVM pVM)
* For the ring-0 EMT logger, we use a per-thread logger instance
* in ring-0. Only initialize it once.
*/
+ PRTLOGGER const pDefault = RTLogDefaultInstance();
for (VMCPUID i = 0; i < pVM->cCpus; i++)
{
PVMCPU pVCpu = &pVM->aCpus[i];
@@ -874,15 +900,15 @@ VMMR3_INT_DECL(int) VMMR3UpdateLoggers(PVM pVM)
rc = PDMR3LdrGetSymbolR0(pVM, VMMR0_MAIN_MODULE_NAME, "vmmR0LoggerFlush", &pfnLoggerFlush);
AssertReleaseMsgRCReturn(rc, ("vmmR0LoggerFlush not found! rc=%Rra\n", rc), rc);
- rc = RTLogCreateForR0(&pR0LoggerR3->Logger, pR0LoggerR3->cbLogger,
- *(PFNRTLOGGER *)&pfnLoggerWrapper, *(PFNRTLOGFLUSH *)&pfnLoggerFlush,
+ rc = RTLogCreateForR0(&pR0LoggerR3->Logger, pR0LoggerR3->cbLogger, pVCpu->vmm.s.pR0LoggerR0 + RT_OFFSETOF(VMMR0LOGGER, Logger),
+ pfnLoggerWrapper, pfnLoggerFlush,
RTLOGFLAGS_BUFFERED, RTLOGDEST_DUMMY);
AssertReleaseMsgRCReturn(rc, ("RTLogCreateForR0 failed! rc=%Rra\n", rc), rc);
RTR0PTR pfnLoggerPrefix = NIL_RTR0PTR;
rc = PDMR3LdrGetSymbolR0(pVM, VMMR0_MAIN_MODULE_NAME, "vmmR0LoggerPrefix", &pfnLoggerPrefix);
AssertReleaseMsgRCReturn(rc, ("vmmR0LoggerPrefix not found! rc=%Rra\n", rc), rc);
- rc = RTLogSetCustomPrefixCallback(&pR0LoggerR3->Logger, *(PFNRTLOGPREFIX *)&pfnLoggerPrefix, NULL);
+ rc = RTLogSetCustomPrefixCallbackForR0(&pR0LoggerR3->Logger, pVCpu->vmm.s.pR0LoggerR0 + RT_OFFSETOF(VMMR0LOGGER, Logger), pfnLoggerPrefix, NIL_RTR0PTR);
AssertReleaseMsgRCReturn(rc, ("RTLogSetCustomPrefixCallback failed! rc=%Rra\n", rc), rc);
pR0LoggerR3->idCpu = i;
@@ -891,7 +917,8 @@ VMMR3_INT_DECL(int) VMMR3UpdateLoggers(PVM pVM)
}
- rc = RTLogCopyGroupsAndFlags(&pR0LoggerR3->Logger, NULL /* default */, pVM->vmm.s.pRCLoggerR3->fFlags, RTLOGFLAGS_BUFFERED);
+ rc = RTLogCopyGroupsAndFlagsForR0(&pR0LoggerR3->Logger, pVCpu->vmm.s.pR0LoggerR0 + RT_OFFSETOF(VMMR0LOGGER, Logger), pDefault,
+ RTLOGFLAGS_BUFFERED, UINT32_MAX);
AssertRC(rc);
}
}
@@ -1265,7 +1292,7 @@ VMMR3_INT_DECL(int) VMMR3HwAccRunGC(PVM pVM, PVMCPU pVCpu)
PVMMR0LOGGER pR0LoggerR3 = pVCpu->vmm.s.pR0LoggerR3;
if ( pR0LoggerR3
&& pR0LoggerR3->Logger.offScratch > 0)
- RTLogFlushToLogger(&pR0LoggerR3->Logger, NULL);
+ RTLogFlushR0(NULL, &pR0LoggerR3->Logger);
#endif /* !LOG_ENABLED */
if (rc != VINF_VMM_CALL_HOST)
{
@@ -1952,7 +1979,7 @@ VMMR3DECL(int) VMMR3CallR0(PVM pVM, uint32_t uOperation, uint64_t u64Arg, PSUPVM
#ifdef LOG_ENABLED
if ( pVCpu->vmm.s.pR0LoggerR3
&& pVCpu->vmm.s.pR0LoggerR3->Logger.offScratch > 0)
- RTLogFlushToLogger(&pVCpu->vmm.s.pR0LoggerR3->Logger, NULL);
+ RTLogFlushR0(NULL, &pVCpu->vmm.s.pR0LoggerR3->Logger);
#endif
if (rc != VINF_VMM_CALL_HOST)
break;
@@ -2048,6 +2075,16 @@ static int vmmR3ServiceCallRing3Request(PVM pVM, PVMCPU pVCpu)
switch (pVCpu->vmm.s.enmCallRing3Operation)
{
/*
+ * Acquire a critical section.
+ */
+ case VMMCALLRING3_PDM_CRIT_SECT_ENTER:
+ {
+ pVCpu->vmm.s.rcCallRing3 = PDMR3CritSectEnterEx((PPDMCRITSECT)(uintptr_t)pVCpu->vmm.s.u64CallRing3Arg,
+ true /*fCallRing3*/);
+ break;
+ }
+
+ /*
* Acquire the PDM lock.
*/
case VMMCALLRING3_PDM_LOCK:
@@ -2257,7 +2294,7 @@ static DECLCALLBACK(void) vmmR3InfoFF(PVM pVM, PCDBGFINFOHLP pHlp, const char *p
PRINT_GROUP(VM_FF_,HIGH_PRIORITY_POST,_MASK);
PRINT_GROUP(VM_FF_,NORMAL_PRIORITY_POST,_MASK);
PRINT_GROUP(VM_FF_,NORMAL_PRIORITY,_MASK);
- PRINT_GROUP(VM_FF_,ALL_BUT_RAW,_MASK);
+ PRINT_GROUP(VM_FF_,ALL_REM,_MASK);
if (c)
pHlp->pfnPrintf(pHlp, "\n");
@@ -2304,7 +2341,7 @@ static DECLCALLBACK(void) vmmR3InfoFF(PVM pVM, PCDBGFINFOHLP pHlp, const char *p
PRINT_GROUP(VMCPU_FF_,NORMAL_PRIORITY,_MASK);
PRINT_GROUP(VMCPU_FF_,RESUME_GUEST,_MASK);
PRINT_GROUP(VMCPU_FF_,HWACCM_TO_R3,_MASK);
- PRINT_GROUP(VMCPU_FF_,ALL_BUT_RAW,_MASK);
+ PRINT_GROUP(VMCPU_FF_,ALL_REM,_MASK);
if (c)
pHlp->pfnPrintf(pHlp, "\n");
}
diff --git a/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp b/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp
index dde2929ff..c6f8e9e0c 100644
--- a/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp
+++ b/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMMGuruMeditation.cpp $ */
+/* $Id: VMMGuruMeditation.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VMM - The Virtual Machine Monitor, Guru Meditation Code.
*/
diff --git a/src/VBox/VMM/VMMR3/VMMR3.def b/src/VBox/VMM/VMMR3/VMMR3.def
index aa9fce504..f5016727e 100644
--- a/src/VBox/VMM/VMMR3/VMMR3.def
+++ b/src/VBox/VMM/VMMR3/VMMR3.def
@@ -1,9 +1,9 @@
-; $Id: VMMR3.def $
+; $Id: VMMR3.def 37529 2011-06-17 11:14:05Z vboxsync $
;; @file
; VMM Ring-3 Context DLL - Definition file.
;
-; 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;
@@ -92,8 +92,6 @@ EXPORTS
CFGMR3QueryString
CFGMR3QueryStringAlloc
- IOMR3GetCritSect
-
MMR3HeapFree
MMR3HeapRealloc
@@ -227,6 +225,8 @@ EXPORTS
TMTimerGetMilli
TMTimerGetNano
TMTimerIsActive
+ TMTimerIsLockOwner
+ TMTimerLock
TMTimerR0Ptr
TMTimerR3Ptr
TMTimerRCPtr
@@ -240,6 +240,8 @@ EXPORTS
TMTimerToMicro
TMTimerToMilli
TMTimerToNano
+ TMTimerUnlock
+
VMMGetSvnRev
VMSetError
VMSetErrorV
diff --git a/src/VBox/VMM/VMMR3/VMMSwitcher.cpp b/src/VBox/VMM/VMMR3/VMMSwitcher.cpp
index 56bce05d3..ef9aac54f 100644
--- a/src/VBox/VMM/VMMR3/VMMSwitcher.cpp
+++ b/src/VBox/VMM/VMMR3/VMMSwitcher.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMMSwitcher.cpp $ */
+/* $Id: VMMSwitcher.cpp 36415 2011-03-24 18:20:04Z vboxsync $ */
/** @file
* VMM - The Virtual Machine Monitor, World Switcher(s).
*/
@@ -930,7 +930,7 @@ DECLCALLBACK(void) vmmR3SwitcherAMD64ToPAE_Relocate(PVM pVM, PVMMSWITCHERDEF pSw
/**
- * Selects the switcher to be used for switching to GC.
+ * Selects the switcher to be used for switching to raw-mode context.
*
* @returns VBox status code.
* @param pVM VM handle.
diff --git a/src/VBox/VMM/VMMR3/VMMTests.cpp b/src/VBox/VMM/VMMR3/VMMTests.cpp
index a0c13740b..78a10f25b 100644
--- a/src/VBox/VMM/VMMR3/VMMTests.cpp
+++ b/src/VBox/VMM/VMMR3/VMMTests.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMMTests.cpp $ */
+/* $Id: VMMTests.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* VMM - The Virtual Machine Monitor Core, Tests.
*/
@@ -33,7 +33,6 @@
#include <VBox/vmm/vm.h>
#include <VBox/err.h>
#include <VBox/param.h>
-#include <VBox/x86.h>
#include <VBox/vmm/hwaccm.h>
#include <iprt/assert.h>
@@ -41,6 +40,7 @@
#include <iprt/time.h>
#include <iprt/stream.h>
#include <iprt/string.h>
+#include <iprt/x86.h>
/**
diff --git a/src/VBox/VMM/VMMR3/VMReq.cpp b/src/VBox/VMM/VMMR3/VMReq.cpp
index d50e24c02..eca0bf4bf 100644
--- a/src/VBox/VMM/VMMR3/VMReq.cpp
+++ b/src/VBox/VMM/VMMR3/VMReq.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMReq.cpp $ */
+/* $Id: VMReq.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VM - Virtual Machine
*/
diff --git a/src/VBox/VMM/VMMRC/CPUMRC.cpp b/src/VBox/VMM/VMMRC/CPUMRC.cpp
index a5a1a1e2f..09cef651f 100644
--- a/src/VBox/VMM/VMMRC/CPUMRC.cpp
+++ b/src/VBox/VMM/VMMRC/CPUMRC.cpp
@@ -1,4 +1,4 @@
-/* $Id: CPUMRC.cpp $ */
+/* $Id: CPUMRC.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* CPUM - Guest Context Code.
*/
diff --git a/src/VBox/VMM/VMMRC/CPUMRCA.asm b/src/VBox/VMM/VMMRC/CPUMRCA.asm
index d0366bed9..7ea458901 100644
--- a/src/VBox/VMM/VMMRC/CPUMRCA.asm
+++ b/src/VBox/VMM/VMMRC/CPUMRCA.asm
@@ -1,4 +1,4 @@
-; $Id: CPUMRCA.asm $
+; $Id: CPUMRCA.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; CPUM - Guest Context Assembly Routines.
;
@@ -22,7 +22,7 @@
%include "VBox/err.mac"
%include "VBox/vmm/stam.mac"
%include "CPUMInternal.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "VBox/vmm/cpum.mac"
diff --git a/src/VBox/VMM/VMMRC/CSAMRC.cpp b/src/VBox/VMM/VMMRC/CSAMRC.cpp
index 6b6b1a9ac..8099b6467 100644
--- a/src/VBox/VMM/VMMRC/CSAMRC.cpp
+++ b/src/VBox/VMM/VMMRC/CSAMRC.cpp
@@ -1,4 +1,4 @@
-/* $Id: CSAMRC.cpp $ */
+/* $Id: CSAMRC.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* CSAM - Guest OS Code Scanning and Analysis Manager - Any Context
*/
diff --git a/src/VBox/VMM/VMMRC/EMRCA.asm b/src/VBox/VMM/VMMRC/EMRCA.asm
index 8a41e5d5b..b7b2ed324 100644
--- a/src/VBox/VMM/VMMRC/EMRCA.asm
+++ b/src/VBox/VMM/VMMRC/EMRCA.asm
@@ -1,4 +1,4 @@
-; $Id: EMRCA.asm $
+; $Id: EMRCA.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; EM Assembly Routines.
;
@@ -20,7 +20,7 @@
;*******************************************************************************
%include "VBox/asmdefs.mac"
%include "VBox/err.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
BEGINCODE
diff --git a/src/VBox/VMM/VMMRC/HWACCMRCA.asm b/src/VBox/VMM/VMMRC/HWACCMRCA.asm
index eacaf3c84..e142ea093 100644
--- a/src/VBox/VMM/VMMRC/HWACCMRCA.asm
+++ b/src/VBox/VMM/VMMRC/HWACCMRCA.asm
@@ -1,4 +1,4 @@
-; $Id: HWACCMRCA.asm $
+; $Id: HWACCMRCA.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; VMXM - GC vmx helpers
;
@@ -24,7 +24,7 @@
%include "VBox/err.mac"
%include "VBox/vmm/hwacc_vmx.mac"
%include "VBox/vmm/cpum.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "HWACCMInternal.mac"
%ifdef RT_OS_OS2 ;; @todo fix OMF support in yasm and kick nasm out completely.
@@ -90,8 +90,8 @@ BITS 64
; * Prepares for and executes VMLAUNCH/VMRESUME (64 bits guest mode)
; *
; * @returns VBox status code
-; * @param pPageCpuPhys VMXON physical address [rsp+8]
-; * @param pVMCSPhys VMCS physical address [rsp+16]
+; * @param HCPhysCpuPage VMXON physical address [rsp+8]
+; * @param HCPhysVMCS VMCS physical address [rsp+16]
; * @param pCache VMCS cache [rsp+24]
; * @param pCtx Guest context (rsi)
; */
@@ -144,10 +144,10 @@ BEGINPROC VMXGCStartVM64
%endif
%ifdef DEBUG
- mov rax, [rbp + 8 + 8] ; pPageCpuPhys
- mov [rbx + VMCSCACHE.TestIn.pPageCpuPhys], rax
- mov rax, [rbp + 16 + 8] ; pVMCSPhys
- mov [rbx + VMCSCACHE.TestIn.pVMCSPhys], rax
+ mov rax, [rbp + 8 + 8] ; HCPhysCpuPage
+ mov [rbx + VMCSCACHE.TestIn.HCPhysCpuPage], rax
+ mov rax, [rbp + 16 + 8] ; HCPhysVMCS
+ mov [rbx + VMCSCACHE.TestIn.HCPhysVMCS], rax
mov [rbx + VMCSCACHE.TestIn.pCache], rbx
mov [rbx + VMCSCACHE.TestIn.pCtx], rsi
%endif
@@ -360,8 +360,8 @@ ALIGN(16)
%ifdef VMX_USE_CACHED_VMCS_ACCESSES
%ifdef DEBUG
- mov rdx, [rsp] ; pVMCSPhys
- mov [rdi + VMCSCACHE.TestOut.pVMCSPhys], rdx
+ mov rdx, [rsp] ; HCPhysVMCS
+ mov [rdi + VMCSCACHE.TestOut.HCPhysVMCS], rdx
%endif
%endif
diff --git a/src/VBox/VMM/VMMRC/IOMRC.cpp b/src/VBox/VMM/VMMRC/IOMRC.cpp
index 22db910ab..eb51a09fb 100644
--- a/src/VBox/VMM/VMMRC/IOMRC.cpp
+++ b/src/VBox/VMM/VMMRC/IOMRC.cpp
@@ -1,4 +1,4 @@
-/* $Id: IOMRC.cpp $ */
+/* $Id: IOMRC.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* IOM - Input / Output Monitor - Guest Context.
*/
diff --git a/src/VBox/VMM/VMMRC/MMRamRC.cpp b/src/VBox/VMM/VMMRC/MMRamRC.cpp
index 7658de497..8d4e33eef 100644
--- a/src/VBox/VMM/VMMRC/MMRamRC.cpp
+++ b/src/VBox/VMM/VMMRC/MMRamRC.cpp
@@ -1,4 +1,4 @@
-/* $Id: MMRamRC.cpp $ */
+/* $Id: MMRamRC.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* MMRamGC - Guest Context Ram access Routines, pair for MMRamGCA.asm.
*/
diff --git a/src/VBox/VMM/VMMRC/MMRamRCA.asm b/src/VBox/VMM/VMMRC/MMRamRCA.asm
index 935910f5a..0e450ccbb 100644
--- a/src/VBox/VMM/VMMRC/MMRamRCA.asm
+++ b/src/VBox/VMM/VMMRC/MMRamRCA.asm
@@ -1,4 +1,4 @@
-; $Id: MMRamRCA.asm $
+; $Id: MMRamRCA.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; MMRamGCA - Guest Context Ram access Assembly Routines.
;
@@ -21,7 +21,7 @@
%include "VBox/asmdefs.mac"
%include "VBox/err.mac"
%include "iprt/err.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
BEGINCODE
diff --git a/src/VBox/VMM/VMMRC/PATMRC.cpp b/src/VBox/VMM/VMMRC/PATMRC.cpp
index 7ef86a3ee..076f30401 100644
--- a/src/VBox/VMM/VMMRC/PATMRC.cpp
+++ b/src/VBox/VMM/VMMRC/PATMRC.cpp
@@ -1,4 +1,4 @@
-/* $Id: PATMRC.cpp $ */
+/* $Id: PATMRC.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* PATM - Dynamic Guest OS Patching Manager - Guest Context
*/
diff --git a/src/VBox/VMM/VMMRC/PDMRCDevice.cpp b/src/VBox/VMM/VMMRC/PDMRCDevice.cpp
index b0e10f88b..a84feea0a 100644
--- a/src/VBox/VMM/VMMRC/PDMRCDevice.cpp
+++ b/src/VBox/VMM/VMMRC/PDMRCDevice.cpp
@@ -1,10 +1,10 @@
-/* $Id: PDMRCDevice.cpp $ */
+/* $Id: PDMRCDevice.cpp 37410 2011-06-10 15:11:40Z vboxsync $ */
/** @file
* PDM - Pluggable Device and Driver Manager, RC Device parts.
*/
/*
- * 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;
@@ -46,6 +46,7 @@ extern DECLEXPORT(const PDMIOAPICHLPRC) g_pdmRCIoApicHlp;
extern DECLEXPORT(const PDMPCIHLPRC) g_pdmRCPciHlp;
extern DECLEXPORT(const PDMHPETHLPRC) g_pdmRCHpetHlp;
extern DECLEXPORT(const PDMDRVHLPRC) g_pdmRCDrvHlp;
+/** @todo missing PDMPCIRAWHLPRC */
RT_C_DECLS_END
@@ -262,6 +263,16 @@ static DECLCALLBACK(uint64_t) pdmRCDevHlp_TMTimeVirtGetNano(PPDMDEVINS pDevIns)
}
+/** @interface_method_impl{PDMDEVHLPRC,pfnDBGFTraceBuf} */
+static DECLCALLBACK(RTTRACEBUF) pdmRCDevHlp_DBGFTraceBuf(PPDMDEVINS pDevIns)
+{
+ PDMDEV_ASSERT_DEVINS(pDevIns);
+ RTTRACEBUF hTraceBuf = pDevIns->Internal.s.pVMRC->hTraceBufRC;
+ LogFlow(("pdmRCDevHlp_DBGFTraceBuf: caller='%p'/%d: returns %p\n", pDevIns, pDevIns->iInstance, hTraceBuf));
+ return hTraceBuf;
+}
+
+
/**
* The Raw-Mode Context Device Helper Callbacks.
*/
@@ -284,6 +295,7 @@ extern DECLEXPORT(const PDMDEVHLPRC) g_pdmRCDevHlp =
pdmRCDevHlp_TMTimeVirtGet,
pdmRCDevHlp_TMTimeVirtGetFreq,
pdmRCDevHlp_TMTimeVirtGetNano,
+ pdmRCDevHlp_DBGFTraceBuf,
PDM_DEVHLPRC_VERSION
};
diff --git a/src/VBox/VMM/VMMRC/PGMRC.cpp b/src/VBox/VMM/VMMRC/PGMRC.cpp
index c90d09712..334558d8f 100644
--- a/src/VBox/VMM/VMMRC/PGMRC.cpp
+++ b/src/VBox/VMM/VMMRC/PGMRC.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMRC.cpp $ */
+/* $Id: PGMRC.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* PGM - Page Monitor, Guest Context.
*/
diff --git a/src/VBox/VMM/VMMRC/PGMRCBth.h b/src/VBox/VMM/VMMRC/PGMRCBth.h
index fd0060354..a4c94ddb5 100644
--- a/src/VBox/VMM/VMMRC/PGMRCBth.h
+++ b/src/VBox/VMM/VMMRC/PGMRCBth.h
@@ -1,4 +1,4 @@
-/* $Id: PGMRCBth.h $ */
+/* $Id: PGMRCBth.h 35335 2010-12-27 12:34:40Z vboxsync $ */
/** @file
* VBox - Page Manager, Shadow+Guest Paging Template - Guest Context.
*/
diff --git a/src/VBox/VMM/VMMRC/PGMRCGst.h b/src/VBox/VMM/VMMRC/PGMRCGst.h
index bf06afd26..476a67c14 100644
--- a/src/VBox/VMM/VMMRC/PGMRCGst.h
+++ b/src/VBox/VMM/VMMRC/PGMRCGst.h
@@ -1,4 +1,4 @@
-/* $Id: PGMRCGst.h $ */
+/* $Id: PGMRCGst.h 35335 2010-12-27 12:34:40Z vboxsync $ */
/** @file
* VBox - Page Manager, Guest Paging Template - Guest Context.
*/
diff --git a/src/VBox/VMM/VMMRC/PGMRCShw.h b/src/VBox/VMM/VMMRC/PGMRCShw.h
index 265f1687d..478754cf1 100644
--- a/src/VBox/VMM/VMMRC/PGMRCShw.h
+++ b/src/VBox/VMM/VMMRC/PGMRCShw.h
@@ -1,4 +1,4 @@
-/* $Id: PGMRCShw.h $ */
+/* $Id: PGMRCShw.h 35335 2010-12-27 12:34:40Z vboxsync $ */
/** @file
* VBox - Page Manager, Shadow Paging Template - Guest Context.
*/
diff --git a/src/VBox/VMM/VMMRC/SELMRC.cpp b/src/VBox/VMM/VMMRC/SELMRC.cpp
index 6f9f2d4d7..670f1d410 100644
--- a/src/VBox/VMM/VMMRC/SELMRC.cpp
+++ b/src/VBox/VMM/VMMRC/SELMRC.cpp
@@ -1,4 +1,4 @@
-/* $Id: SELMRC.cpp $ */
+/* $Id: SELMRC.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* SELM - The Selector Manager, Guest Context.
*/
diff --git a/src/VBox/VMM/VMMRC/TRPMRC.cpp b/src/VBox/VMM/VMMRC/TRPMRC.cpp
index 567ab4328..6d72d7aa7 100644
--- a/src/VBox/VMM/VMMRC/TRPMRC.cpp
+++ b/src/VBox/VMM/VMMRC/TRPMRC.cpp
@@ -1,4 +1,4 @@
-/* $Id: TRPMRC.cpp $ */
+/* $Id: TRPMRC.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* TRPM - The Trap Monitor, Guest Context
*/
@@ -22,15 +22,15 @@
#define LOG_GROUP LOG_GROUP_TRPM
#include <VBox/vmm/trpm.h>
#include <VBox/vmm/cpum.h>
+#include <VBox/vmm/em.h>
#include <VBox/vmm/vmm.h>
#include "TRPMInternal.h"
#include <VBox/vmm/vm.h>
#include <VBox/err.h>
-#include <VBox/x86.h>
-#include <VBox/vmm/em.h>
#include <iprt/assert.h>
#include <iprt/asm.h>
+#include <iprt/x86.h>
#include <VBox/log.h>
#include <VBox/vmm/selm.h>
diff --git a/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp b/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
index 02d92c3b3..977507684 100644
--- a/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
+++ b/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
@@ -1,4 +1,4 @@
-/* $Id: TRPMRCHandlers.cpp $ */
+/* $Id: TRPMRCHandlers.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* TRPM - Guest Context Trap Handlers, CPP part
*/
@@ -38,12 +38,12 @@
#include <VBox/err.h>
#include <VBox/dis.h>
#include <VBox/disopcode.h>
-#include <VBox/x86.h>
#include <VBox/log.h>
#include <VBox/vmm/tm.h>
#include <iprt/asm.h>
#include <iprt/asm-amd64-x86.h>
#include <iprt/assert.h>
+#include <iprt/x86.h>
/*******************************************************************************
@@ -186,7 +186,9 @@ static int trpmGCExitTrap(PVM pVM, PVMCPU pVCpu, int rc, PCPUMCTXCORE pRegFrame)
*/
if ( rc == VINF_SUCCESS
&& ( VM_FF_ISPENDING(pVM, VM_FF_TM_VIRTUAL_SYNC | VM_FF_REQUEST | VM_FF_PGM_NO_MEMORY | VM_FF_PDM_DMA)
- || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TIMER | VMCPU_FF_TO_R3 | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_REQUEST | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL)
+ || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TIMER | VMCPU_FF_TO_R3 | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC
+ | VMCPU_FF_REQUEST | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL
+ | VMCPU_FF_PDM_CRITSECT)
)
)
{
@@ -194,7 +196,7 @@ static int trpmGCExitTrap(PVM pVM, PVMCPU pVCpu, int rc, PCPUMCTXCORE pRegFrame)
if (RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)))
rc = VINF_EM_NO_MEMORY;
/* Pending Ring-3 action. */
- else if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TO_R3))
+ else if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TO_R3 | VMCPU_FF_PDM_CRITSECT))
{
VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
rc = VINF_EM_RAW_TO_R3;
diff --git a/src/VBox/VMM/VMMRC/TRPMRCHandlersA.asm b/src/VBox/VMM/VMMRC/TRPMRCHandlersA.asm
index e9f86cda3..761dbbbde 100644
--- a/src/VBox/VMM/VMMRC/TRPMRCHandlersA.asm
+++ b/src/VBox/VMM/VMMRC/TRPMRCHandlersA.asm
@@ -1,4 +1,4 @@
-; $Id: TRPMRCHandlersA.asm $
+; $Id: TRPMRCHandlersA.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; TRPM - Guest Context Trap Handlers
;
@@ -18,7 +18,7 @@
;* Header Files *
;*******************************************************************************
%include "VMMRC.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "VBox/vmm/cpum.mac"
%include "VBox/vmm/stam.mac"
%include "VBox/vmm/vm.mac"
diff --git a/src/VBox/VMM/VMMRC/VMMRC.cpp b/src/VBox/VMM/VMMRC/VMMRC.cpp
index 4f4bef111..9cc612252 100644
--- a/src/VBox/VMM/VMMRC/VMMRC.cpp
+++ b/src/VBox/VMM/VMMRC/VMMRC.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMMRC.cpp $ */
+/* $Id: VMMRC.cpp 35810 2011-02-01 13:00:24Z vboxsync $ */
/** @file
* VMM - Raw-mode Context.
*/
@@ -72,7 +72,7 @@ VMMRCDECL(int) VMMGCEntry(PVM pVM, unsigned uOperation, unsigned uArg, ...)
* Validate the svn revision (uArg).
*/
if (uArg != VMMGetSvnRev())
- return VERR_VERSION_MISMATCH;
+ return VERR_VMM_RC_VERSION_MISMATCH;
/*
* Initialize the runtime.
diff --git a/src/VBox/VMM/VMMRC/VMMRC.def b/src/VBox/VMM/VMMRC/VMMRC.def
index c5242071f..5e4f3db3a 100644
--- a/src/VBox/VMM/VMMRC/VMMRC.def
+++ b/src/VBox/VMM/VMMRC/VMMRC.def
@@ -1,4 +1,4 @@
-; $Id: VMMRC.def $
+; $Id: VMMRC.def 37454 2011-06-14 19:18:56Z vboxsync $
;; @file
; VMM Raw-mode Context DLL - Definition file.
@@ -38,6 +38,9 @@ EXPORTS
RTLogDefaultInstance
RTLogRelDefaultInstance
RTTimeMilliTS
+ RTTraceBufAddMsgF
+ RTTraceBufAddPos
+ RTTraceBufAddPosMsgF
SELMGetHyperCS
TMTimerFromMilli
TMTimerFromMicro
@@ -45,6 +48,8 @@ EXPORTS
TMTimerGet
TMTimerGetFreq
TMTimerIsActive
+ TMTimerIsLockOwner
+ TMTimerLock
TMTimerSet
TMTimerSetRelative
TMTimerSetMillies
@@ -52,6 +57,7 @@ EXPORTS
TMTimerSetNano
TMTimerSetFrequencyHint
TMTimerStop
+ TMTimerUnlock
TRPMGCHandlerGeneric
TRPMGCHandlerInterupt
TRPMGCHandlerTrap08
diff --git a/src/VBox/VMM/VMMRC/VMMRC.mac b/src/VBox/VMM/VMMRC/VMMRC.mac
index c7f26be27..cdf1cd3e4 100644
--- a/src/VBox/VMM/VMMRC/VMMRC.mac
+++ b/src/VBox/VMM/VMMRC/VMMRC.mac
@@ -1,4 +1,4 @@
-; $Id: VMMRC.mac $
+; $Id: VMMRC.mac 35335 2010-12-27 12:34:40Z vboxsync $
;; @file
; VMMGC - Raw-mode Context Assembly Macros.
;
diff --git a/src/VBox/VMM/VMMRC/VMMRC0.asm b/src/VBox/VMM/VMMRC/VMMRC0.asm
index ce8bb078f..71108d15d 100644
--- a/src/VBox/VMM/VMMRC/VMMRC0.asm
+++ b/src/VBox/VMM/VMMRC/VMMRC0.asm
@@ -1,4 +1,4 @@
-; $Id: VMMRC0.asm $
+; $Id: VMMRC0.asm 35335 2010-12-27 12:34:40Z vboxsync $
;; @file
; VMMGC0 - The first object module in the link.
;
diff --git a/src/VBox/VMM/VMMRC/VMMRC99.asm b/src/VBox/VMM/VMMRC/VMMRC99.asm
index c34479da1..3278fac5b 100644
--- a/src/VBox/VMM/VMMRC/VMMRC99.asm
+++ b/src/VBox/VMM/VMMRC/VMMRC99.asm
@@ -1,4 +1,4 @@
-; $Id: VMMRC99.asm $
+; $Id: VMMRC99.asm 35335 2010-12-27 12:34:40Z vboxsync $
;; @file
; VMMGC99 - The last object module in the link.
;
diff --git a/src/VBox/VMM/VMMRC/VMMRCA.asm b/src/VBox/VMM/VMMRC/VMMRCA.asm
index 88000e817..4c6a9e3b2 100644
--- a/src/VBox/VMM/VMMRC/VMMRCA.asm
+++ b/src/VBox/VMM/VMMRC/VMMRCA.asm
@@ -1,4 +1,4 @@
-; $Id: VMMRCA.asm $
+; $Id: VMMRCA.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; VMMGC - Raw-mode Context Virtual Machine Monitor assembly routines.
;
@@ -18,7 +18,7 @@
;* Header Files *
;*******************************************************************************
%include "VBox/asmdefs.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
;*******************************************************************************
diff --git a/src/VBox/VMM/VMMRC/VMMRCBuiltin.def b/src/VBox/VMM/VMMRC/VMMRCBuiltin.def
index c733ab3b3..40f78fdd7 100644
--- a/src/VBox/VMM/VMMRC/VMMRCBuiltin.def
+++ b/src/VBox/VMM/VMMRC/VMMRCBuiltin.def
@@ -1,4 +1,4 @@
-; $Id: VMMRCBuiltin.def $
+; $Id: VMMRCBuiltin.def 35345 2010-12-27 14:41:49Z vboxsync $
;; @file
; VMM Raw-mode Context Builtin DLL - Definition file for generating import library.
;
diff --git a/src/VBox/VMM/VMMRC/VMMRCDeps.cpp b/src/VBox/VMM/VMMRC/VMMRCDeps.cpp
index 82819207c..1734641f2 100644
--- a/src/VBox/VMM/VMMRC/VMMRCDeps.cpp
+++ b/src/VBox/VMM/VMMRC/VMMRCDeps.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMMRCDeps.cpp $ */
+/* $Id: VMMRCDeps.cpp 35335 2010-12-27 12:34:40Z vboxsync $ */
/** @file
* VMMGC Runtime Dependencies.
*/
diff --git a/src/VBox/VMM/VMMRZ/DBGFRZ.cpp b/src/VBox/VMM/VMMRZ/DBGFRZ.cpp
index 0cf065b8b..558cd823a 100644
--- a/src/VBox/VMM/VMMRZ/DBGFRZ.cpp
+++ b/src/VBox/VMM/VMMRZ/DBGFRZ.cpp
@@ -1,4 +1,4 @@
-/* $Id: DBGFRZ.cpp $ */
+/* $Id: DBGFRZ.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* DBGF - Debugger Facility, RZ part.
*/
diff --git a/src/VBox/VMM/VMMRZ/PGMRZDynMap.cpp b/src/VBox/VMM/VMMRZ/PGMRZDynMap.cpp
index 973799c60..684bd108e 100644
--- a/src/VBox/VMM/VMMRZ/PGMRZDynMap.cpp
+++ b/src/VBox/VMM/VMMRZ/PGMRZDynMap.cpp
@@ -1,4 +1,4 @@
-/* $Id: PGMRZDynMap.cpp $ */
+/* $Id: PGMRZDynMap.cpp 36627 2011-04-08 15:38:47Z vboxsync $ */
/** @file
* PGM - Page Manager and Monitor, dynamic mapping cache.
*/
diff --git a/src/VBox/VMM/VMMRZ/VMMRZ.cpp b/src/VBox/VMM/VMMRZ/VMMRZ.cpp
index a61332c96..d4dcab4ca 100644
--- a/src/VBox/VMM/VMMRZ/VMMRZ.cpp
+++ b/src/VBox/VMM/VMMRZ/VMMRZ.cpp
@@ -1,4 +1,4 @@
-/* $Id: VMMRZ.cpp $ */
+/* $Id: VMMRZ.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VMM - Virtual Machine Monitor, Raw-mode and ring-0 context code.
*/
diff --git a/src/VBox/VMM/VMMSwitcher/32BitTo32Bit.asm b/src/VBox/VMM/VMMSwitcher/32BitTo32Bit.asm
index 5eaf28a59..c88a2f21e 100644
--- a/src/VBox/VMM/VMMSwitcher/32BitTo32Bit.asm
+++ b/src/VBox/VMM/VMMSwitcher/32BitTo32Bit.asm
@@ -1,4 +1,4 @@
-; $Id: 32BitTo32Bit.asm $
+; $Id: 32BitTo32Bit.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VMM - World Switchers, 32-Bit to 32-Bit.
;
diff --git a/src/VBox/VMM/VMMSwitcher/32BitToAMD64.asm b/src/VBox/VMM/VMMSwitcher/32BitToAMD64.asm
index d913f9176..08578140d 100644
--- a/src/VBox/VMM/VMMSwitcher/32BitToAMD64.asm
+++ b/src/VBox/VMM/VMMSwitcher/32BitToAMD64.asm
@@ -1,4 +1,4 @@
-; $Id: 32BitToAMD64.asm $
+; $Id: 32BitToAMD64.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VMM - World Switchers, 32-Bit to AMD64
;
diff --git a/src/VBox/VMM/VMMSwitcher/32BitToPAE.asm b/src/VBox/VMM/VMMSwitcher/32BitToPAE.asm
index 9c9d245e4..7b1730157 100644
--- a/src/VBox/VMM/VMMSwitcher/32BitToPAE.asm
+++ b/src/VBox/VMM/VMMSwitcher/32BitToPAE.asm
@@ -1,4 +1,4 @@
-; $Id: 32BitToPAE.asm $
+; $Id: 32BitToPAE.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VMM - World Switchers, 32-Bit to 32-Bit.
;
diff --git a/src/VBox/VMM/VMMSwitcher/AMD64To32Bit.asm b/src/VBox/VMM/VMMSwitcher/AMD64To32Bit.asm
index ee7bc2636..aad022088 100644
--- a/src/VBox/VMM/VMMSwitcher/AMD64To32Bit.asm
+++ b/src/VBox/VMM/VMMSwitcher/AMD64To32Bit.asm
@@ -1,4 +1,4 @@
-; $Id: AMD64To32Bit.asm $
+; $Id: AMD64To32Bit.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VMM - World Switchers, AMD64 to 32-bit
;
diff --git a/src/VBox/VMM/VMMSwitcher/AMD64ToPAE.asm b/src/VBox/VMM/VMMSwitcher/AMD64ToPAE.asm
index 4878fc122..8c87ec6f5 100644
--- a/src/VBox/VMM/VMMSwitcher/AMD64ToPAE.asm
+++ b/src/VBox/VMM/VMMSwitcher/AMD64ToPAE.asm
@@ -1,4 +1,4 @@
-; $Id: AMD64ToPAE.asm $
+; $Id: AMD64ToPAE.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VMM - World Switchers, PAE to PAE
;
diff --git a/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac b/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac
index 8117f326d..c70f01751 100644
--- a/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac
+++ b/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac
@@ -1,4 +1,4 @@
-; $Id: AMD64andLegacy.mac $
+; $Id: AMD64andLegacy.mac 37969 2011-07-14 14:36:13Z vboxsync $
;; @file
; VMM - World Switchers, template for AMD64 to PAE and 32-bit.
;
@@ -23,7 +23,7 @@
;*******************************************************************************
%include "VBox/asmdefs.mac"
%include "VBox/apic.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "VBox/vmm/cpum.mac"
%include "VBox/vmm/stam.mac"
%include "VBox/vmm/vm.mac"
@@ -1101,7 +1101,18 @@ gth_fpu_no:
; Would've liked to have these higher up in case of crashes, but
; the fpu stuff must be done before we restore cr0.
mov rcx, [rdx + r8 + CPUMCPU.Host.cr4]
+ test rcx, X86_CR4_PCIDE
+ jz gth_no_pcide
+ mov rax, [rdx + r8 + CPUMCPU.Host.cr3]
+ and rax, ~0xfff ; clear the PCID in cr3
+ mov cr3, rax
+ mov cr4, rcx
+ mov rax, [rdx + r8 + CPUMCPU.Host.cr3]
+ mov cr3, rax ; reload it with the right PCID.
+ jmp gth_restored_cr4
+gth_no_pcide:
mov cr4, rcx
+gth_restored_cr4:
mov rcx, [rdx + r8 + CPUMCPU.Host.cr0]
mov cr0, rcx
;mov rcx, [rdx + r8 + CPUMCPU.Host.cr2] ; assumes this is waste of time.
diff --git a/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac b/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
index 609f5c147..648f8438e 100644
--- a/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
+++ b/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
@@ -26,7 +26,7 @@
;*******************************************************************************
%include "VBox/asmdefs.mac"
%include "VBox/apic.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "VBox/vmm/cpum.mac"
%include "VBox/vmm/stam.mac"
%include "VBox/vmm/vm.mac"
diff --git a/src/VBox/VMM/VMMSwitcher/PAETo32Bit.asm b/src/VBox/VMM/VMMSwitcher/PAETo32Bit.asm
index 53913fbed..d2f2520a8 100644
--- a/src/VBox/VMM/VMMSwitcher/PAETo32Bit.asm
+++ b/src/VBox/VMM/VMMSwitcher/PAETo32Bit.asm
@@ -1,4 +1,4 @@
-; $Id: PAETo32Bit.asm $
+; $Id: PAETo32Bit.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VMM - World Switchers, PAE to PAE
;
diff --git a/src/VBox/VMM/VMMSwitcher/PAEToAMD64.asm b/src/VBox/VMM/VMMSwitcher/PAEToAMD64.asm
index 23c96e96b..9f64ac03e 100644
--- a/src/VBox/VMM/VMMSwitcher/PAEToAMD64.asm
+++ b/src/VBox/VMM/VMMSwitcher/PAEToAMD64.asm
@@ -1,4 +1,4 @@
-; $Id: PAEToAMD64.asm $
+; $Id: PAEToAMD64.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VMM - World Switchers, PAE to AMD64
;
diff --git a/src/VBox/VMM/VMMSwitcher/PAEToPAE.asm b/src/VBox/VMM/VMMSwitcher/PAEToPAE.asm
index 3aae14abd..661efa958 100644
--- a/src/VBox/VMM/VMMSwitcher/PAEToPAE.asm
+++ b/src/VBox/VMM/VMMSwitcher/PAEToPAE.asm
@@ -1,4 +1,4 @@
-; $Id: PAEToPAE.asm $
+; $Id: PAEToPAE.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VMM - World Switchers, PAE to PAE
;
diff --git a/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac b/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
index 6b5757cc3..eef0e2393 100644
--- a/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
+++ b/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
@@ -1,4 +1,4 @@
-; $Id: PAEand32Bit.mac $
+; $Id: PAEand32Bit.mac 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; VMM - World Switchers, template for PAE and 32-Bit.
;
@@ -22,7 +22,7 @@
;*******************************************************************************
%include "VBox/asmdefs.mac"
%include "VBox/apic.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "VBox/vmm/cpum.mac"
%include "VBox/vmm/stam.mac"
%include "VBox/vmm/vm.mac"
diff --git a/src/VBox/VMM/include/CFGMInternal.h b/src/VBox/VMM/include/CFGMInternal.h
index 2d33bc6d5..9249ffac9 100644
--- a/src/VBox/VMM/include/CFGMInternal.h
+++ b/src/VBox/VMM/include/CFGMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: CFGMInternal.h $ */
+/* $Id: CFGMInternal.h 35333 2010-12-27 12:10:56Z vboxsync $ */
/** @file
* CFGM - Internal header file.
*/
diff --git a/src/VBox/VMM/include/CPUMInternal.h b/src/VBox/VMM/include/CPUMInternal.h
index 04f4345b6..66c7fe4b9 100644
--- a/src/VBox/VMM/include/CPUMInternal.h
+++ b/src/VBox/VMM/include/CPUMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: CPUMInternal.h $ */
+/* $Id: CPUMInternal.h 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* CPUM - Internal header file.
*/
@@ -20,7 +20,7 @@
#include <VBox/cdefs.h>
#include <VBox/types.h>
-#include <VBox/x86.h>
+#include <iprt/x86.h>
diff --git a/src/VBox/VMM/include/CPUMInternal.mac b/src/VBox/VMM/include/CPUMInternal.mac
index 3e30a88ed..cd927f747 100644
--- a/src/VBox/VMM/include/CPUMInternal.mac
+++ b/src/VBox/VMM/include/CPUMInternal.mac
@@ -1,4 +1,4 @@
-; $Id: CPUMInternal.mac $
+; $Id: CPUMInternal.mac 35333 2010-12-27 12:10:56Z vboxsync $
;; @file
; CPUM - Internal header file (asm).
;
diff --git a/src/VBox/VMM/include/CSAMInternal.h b/src/VBox/VMM/include/CSAMInternal.h
index e34346e99..92d286023 100644
--- a/src/VBox/VMM/include/CSAMInternal.h
+++ b/src/VBox/VMM/include/CSAMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: CSAMInternal.h $ */
+/* $Id: CSAMInternal.h 35348 2010-12-27 16:35:23Z vboxsync $ */
/** @file
* CSAM - Internal header file.
*/
diff --git a/src/VBox/VMM/include/DBGFInternal.h b/src/VBox/VMM/include/DBGFInternal.h
index 23e320c95..704bb129f 100644
--- a/src/VBox/VMM/include/DBGFInternal.h
+++ b/src/VBox/VMM/include/DBGFInternal.h
@@ -1,4 +1,4 @@
-/* $Id: DBGFInternal.h $ */
+/* $Id: DBGFInternal.h 37410 2011-06-10 15:11:40Z vboxsync $ */
/** @file
* DBGF - Internal header file.
*/
@@ -244,12 +244,12 @@ typedef struct DBGF
* This part is initialized in a lazy manner for performance reasons. */
bool fSymInited;
/** Alignment padding. */
- RTUINT uAlignment0;
+ uint32_t uAlignment0;
/** The number of hardware breakpoints. */
- RTUINT cHwBreakpoints;
+ uint32_t cHwBreakpoints;
/** The number of active breakpoints. */
- RTUINT cBreakpoints;
+ uint32_t cBreakpoints;
/** Array of hardware breakpoints. (0..3)
* This is shared among all the CPUs because life is much simpler that way. */
DBGFBP aHwBreakpoints[4];
@@ -332,6 +332,7 @@ typedef DBGFCPU *PDBGFCPU;
int dbgfR3AsInit(PVM pVM);
void dbgfR3AsTerm(PVM pVM);
void dbgfR3AsRelocate(PVM pVM, RTGCUINTPTR offDelta);
+int dbgfR3BpInit(PVM pVM);
int dbgfR3InfoInit(PVM pVM);
int dbgfR3InfoTerm(PVM pVM);
void dbgfR3OSTerm(PVM pVM);
@@ -339,7 +340,9 @@ int dbgfR3RegInit(PVM pVM);
void dbgfR3RegTerm(PVM pVM);
int dbgfR3SymInit(PVM pVM);
int dbgfR3SymTerm(PVM pVM);
-int dbgfR3BpInit(PVM pVM);
+int dbgfR3TraceInit(PVM pVM);
+void dbgfR3TraceRelocate(PVM pVM);
+void dbgfR3TraceTerm(PVM pVM);
diff --git a/src/VBox/VMM/include/EMHandleRCTmpl.h b/src/VBox/VMM/include/EMHandleRCTmpl.h
index 7eb50bedb..2a1af78e7 100644
--- a/src/VBox/VMM/include/EMHandleRCTmpl.h
+++ b/src/VBox/VMM/include/EMHandleRCTmpl.h
@@ -1,4 +1,4 @@
-/* $Id: EMHandleRCTmpl.h $ */
+/* $Id: EMHandleRCTmpl.h 35333 2010-12-27 12:10:56Z vboxsync $ */
/** @file
* EM - emR3[Raw|Hwaccm]HandleRC template.
*/
diff --git a/src/VBox/VMM/include/EMInternal.h b/src/VBox/VMM/include/EMInternal.h
index 8ce4e9d8a..bcdb3a3af 100644
--- a/src/VBox/VMM/include/EMInternal.h
+++ b/src/VBox/VMM/include/EMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: EMInternal.h $ */
+/* $Id: EMInternal.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* EM - Internal header file.
*/
diff --git a/src/VBox/VMM/include/FTMInternal.h b/src/VBox/VMM/include/FTMInternal.h
index 6b442f16a..a67daac0a 100644
--- a/src/VBox/VMM/include/FTMInternal.h
+++ b/src/VBox/VMM/include/FTMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: FTMInternal.h $ */
+/* $Id: FTMInternal.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* FTM - Internal header file.
*/
diff --git a/src/VBox/VMM/include/HWACCMInternal.h b/src/VBox/VMM/include/HWACCMInternal.h
index dceb552a8..82fb37219 100644
--- a/src/VBox/VMM/include/HWACCMInternal.h
+++ b/src/VBox/VMM/include/HWACCMInternal.h
@@ -1,10 +1,10 @@
-/* $Id: HWACCMInternal.h $ */
+/* $Id: HWACCMInternal.h 37386 2011-06-08 15:15:11Z vboxsync $ */
/** @file
- * HWACCM - Internal header file.
+ * HM - Internal header file.
*/
/*
- * Copyright (C) 2006-2007 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;
@@ -139,32 +139,35 @@ RT_C_DECLS_BEGIN
/** Total guest mapped memory needed. */
#define HWACCM_VTX_TOTAL_DEVHEAP_MEM (HWACCM_EPT_IDENTITY_PG_TABLE_SIZE + HWACCM_VTX_TSS_SIZE)
-/* Enable for TPR guest patching. */
+/** Enable for TPR guest patching. */
#define VBOX_HWACCM_WITH_GUEST_PATCHING
/** HWACCM SSM version
*/
#ifdef VBOX_HWACCM_WITH_GUEST_PATCHING
-#define HWACCM_SSM_VERSION 5
-#define HWACCM_SSM_VERSION_NO_PATCHING 4
+# define HWACCM_SSM_VERSION 5
+# define HWACCM_SSM_VERSION_NO_PATCHING 4
#else
-#define HWACCM_SSM_VERSION 4
-#define HWACCM_SSM_VERSION_NO_PATCHING 4
+# define HWACCM_SSM_VERSION 4
+# define HWACCM_SSM_VERSION_NO_PATCHING 4
#endif
#define HWACCM_SSM_VERSION_2_0_X 3
-/* Per-cpu information. (host) */
-typedef struct
+/**
+ * Global per-cpu information. (host)
+ */
+typedef struct HMGLOBLCPUINFO
{
+ /** The CPU ID. */
RTCPUID idCpu;
-
- RTR0MEMOBJ pMemObj;
- /* Current ASID (AMD-V)/VPID (Intel) */
+ /** The memory object */
+ RTR0MEMOBJ hMemObj;
+ /** Current ASID (AMD-V) / VPID (Intel). */
uint32_t uCurrentASID;
- /* TLB flush count */
+ /** TLB flush count. */
uint32_t cTLBFlushes;
- /* Set the first time a cpu is used to make sure we start with a clean TLB. */
+ /** Set the first time a cpu is used to make sure we start with a clean TLB. */
bool fFlushTLB;
/** Configured for VT-x or AMD-V. */
@@ -175,8 +178,9 @@ typedef struct
/** In use by our code. (for power suspend) */
volatile bool fInUse;
-} HWACCM_CPUINFO;
-typedef HWACCM_CPUINFO *PHWACCM_CPUINFO;
+} HMGLOBLCPUINFO;
+/** Pointer to the per-cpu global information. */
+typedef HMGLOBLCPUINFO *PHMGLOBLCPUINFO;
typedef enum
{
@@ -280,7 +284,7 @@ typedef struct HWACCM
uint64_t u64RegisterMask;
/** Maximum ASID allowed. */
- RTUINT uMaxASID;
+ uint32_t uMaxASID;
/** The maximum number of resumes loops allowed in ring-0 (safety precaution).
* This number is set much higher when RTThreadPreemptIsPending is reliable. */
@@ -512,14 +516,14 @@ typedef struct VMCSCACHE
#ifdef DEBUG
struct
{
- RTHCPHYS pPageCpuPhys;
- RTHCPHYS pVMCSPhys;
+ RTHCPHYS HCPhysCpuPage;
+ RTHCPHYS HCPhysVMCS;
RTGCPTR pCache;
RTGCPTR pCtx;
} TestIn;
struct
{
- RTHCPHYS pVMCSPhys;
+ RTHCPHYS HCPhysVMCS;
RTGCPTR pCache;
RTGCPTR pCtx;
uint64_t eflags;
@@ -565,33 +569,34 @@ typedef struct HWACCMCPU
bool fActive;
/** Set when the TLB has been checked until we return from the world switch. */
- volatile uint8_t fCheckedTLBFlush;
+ volatile bool fCheckedTLBFlush;
uint8_t bAlignment[3];
+ /** World switch exit counter. */
+ volatile uint32_t cWorldSwitchExits;
+
/** HWACCM_CHANGED_* flags. */
- RTUINT fContextUseFlags;
+ uint32_t fContextUseFlags;
/** Id of the last cpu we were executing code on (NIL_RTCPUID for the first time) */
RTCPUID idLastCpu;
/** TLB flush count */
- RTUINT cTLBFlushes;
+ uint32_t cTLBFlushes;
/** Current ASID in use by the VM */
- RTUINT uCurrentASID;
+ uint32_t uCurrentASID;
- /** World switch exit counter. */
- volatile uint32_t cWorldSwitchExit;
uint32_t u32Alignment;
struct
{
/** Physical address of the VM control structure (VMCS). */
- RTHCPHYS pVMCSPhys;
+ RTHCPHYS HCPhysVMCS;
/** R0 memory object for the VM control structure (VMCS). */
- RTR0MEMOBJ pMemObjVMCS;
+ RTR0MEMOBJ hMemObjVMCS;
/** Virtual address of the VM control structure (VMCS). */
- R0PTRTYPE(void *) pVMCS;
+ R0PTRTYPE(void *) pvVMCS;
/** Ring 0 handlers for VT-x. */
PFNHWACCMVMXSTARTVM pfnStartVM;
@@ -607,11 +612,11 @@ typedef struct HWACCMCPU
uint64_t proc_ctls2;
/** Physical address of the virtual APIC page for TPR caching. */
- RTHCPHYS pVAPICPhys;
+ RTHCPHYS HCPhysVAPIC;
/** R0 memory object for the virtual APIC page for TPR caching. */
- RTR0MEMOBJ pMemObjVAPIC;
+ RTR0MEMOBJ hMemObjVAPIC;
/** Virtual address of the virtual APIC page for TPR caching. */
- R0PTRTYPE(uint8_t *) pVAPIC;
+ R0PTRTYPE(uint8_t *) pbVAPIC;
/** Current CR0 mask. */
uint64_t cr0_mask;
@@ -771,7 +776,7 @@ typedef struct HWACCMCPU
uint8_t abDisStatePadding[DISCPUSTATE_PADDING_SIZE];
};
- RTUINT padding2[1];
+ uint32_t padding2[1];
STAMPROFILEADV StatEntry;
STAMPROFILEADV StatExit1;
@@ -882,8 +887,8 @@ typedef HWACCMCPU *PHWACCMCPU;
#ifdef IN_RING0
-VMMR0DECL(PHWACCM_CPUINFO) HWACCMR0GetCurrentCpu();
-VMMR0DECL(PHWACCM_CPUINFO) HWACCMR0GetCurrentCpuEx(RTCPUID idCpu);
+VMMR0DECL(PHMGLOBLCPUINFO) HWACCMR0GetCurrentCpu(void);
+VMMR0DECL(PHMGLOBLCPUINFO) HWACCMR0GetCurrentCpuEx(RTCPUID idCpu);
#ifdef VBOX_STRICT
@@ -894,18 +899,6 @@ VMMR0DECL(void) HWACCMR0DumpDescriptor(PCX86DESCHC pDesc, RTSEL Sel, const char
# define HWACCMR0DumpDescriptor(a, b, c) do { } while (0)
#endif
-/* Dummy callback handlers. */
-VMMR0DECL(int) HWACCMR0DummyEnter(PVM pVM, PVMCPU pVCpu, PHWACCM_CPUINFO pCpu);
-VMMR0DECL(int) HWACCMR0DummyLeave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-VMMR0DECL(int) HWACCMR0DummyEnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
-VMMR0DECL(int) HWACCMR0DummyDisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
-VMMR0DECL(int) HWACCMR0DummyInitVM(PVM pVM);
-VMMR0DECL(int) HWACCMR0DummyTermVM(PVM pVM);
-VMMR0DECL(int) HWACCMR0DummySetupVM(PVM pVM);
-VMMR0DECL(int) HWACCMR0DummyRunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-VMMR0DECL(int) HWACCMR0DummySaveHostState(PVM pVM, PVMCPU pVCpu);
-VMMR0DECL(int) HWACCMR0DummyLoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-
# ifdef VBOX_WITH_KERNEL_USING_XMM
DECLASM(int) hwaccmR0VMXStartVMWrapXMM(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu, PFNHWACCMVMXSTARTVM pfnStartVM);
DECLASM(int) hwaccmR0SVMRunWrapXMM(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx, PVM pVM, PVMCPU pVCpu, PFNHWACCMSVMVMRUN pfnVMRun);
diff --git a/src/VBox/VMM/include/HWACCMInternal.mac b/src/VBox/VMM/include/HWACCMInternal.mac
index f6ed71f8b..2b1549dc3 100644
--- a/src/VBox/VMM/include/HWACCMInternal.mac
+++ b/src/VBox/VMM/include/HWACCMInternal.mac
@@ -1,4 +1,4 @@
-;$Id: HWACCMInternal.mac $
+;$Id: HWACCMInternal.mac 37323 2011-06-03 16:20:06Z vboxsync $
;; @file
; HWACCM - Internal header file.
;
@@ -16,10 +16,10 @@
%define VMX_USE_CACHED_VMCS_ACCESSES
-;Maximum number of cached entries.
+;Maximum number of cached entries.
%define VMCSCACHE_MAX_ENTRY 128
-; Structure for storing read and write VMCS actions.
+; Structure for storing read and write VMCS actions.
struc VMCSCACHE
%ifdef VBOX_WITH_CRASHDUMP_MAGIC
.aMagic resb 16
@@ -42,11 +42,11 @@ struc VMCSCACHE
.Read.aField resd VMCSCACHE_MAX_ENTRY
.Read.aFieldVal resq VMCSCACHE_MAX_ENTRY
%ifdef DEBUG
- .TestIn.pPageCpuPhys resq 1
- .TestIn.pVMCSPhys resq 1
+ .TestIn.HCPhysCpuPage resq 1
+ .TestIn.HCPhysVMCS resq 1
.TestIn.pCache resq 1
.TestIn.pCtx resq 1
- .TestOut.pVMCSPhys resq 1
+ .TestOut.HCPhysVMCS resq 1
.TestOut.pCache resq 1
.TestOut.pCtx resq 1
.TestOut.eflags resq 1
diff --git a/src/VBox/VMM/include/IEMInternal.h b/src/VBox/VMM/include/IEMInternal.h
new file mode 100644
index 000000000..e47bf0d6f
--- /dev/null
+++ b/src/VBox/VMM/include/IEMInternal.h
@@ -0,0 +1,1004 @@
+/* $Id: IEMInternal.h 37423 2011-06-12 18:37:56Z vboxsync $ */
+/** @file
+ * IEM - Internal header file.
+ */
+
+/*
+ * 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 ___IEMInternal_h
+#define ___IEMInternal_h
+
+#include <VBox/vmm/stam.h>
+#include <VBox/vmm/cpum.h>
+#include <VBox/param.h>
+
+
+RT_C_DECLS_BEGIN
+
+
+/** @defgroup grp_iem_int Internals
+ * @ingroup grp_iem
+ * @internal
+ * @{
+ */
+
+
+/**
+ * Operand or addressing mode.
+ */
+typedef enum IEMMODE
+{
+ IEMMODE_16BIT = 0,
+ IEMMODE_32BIT,
+ IEMMODE_64BIT
+} IEMMODE;
+AssertCompileSize(IEMMODE, 4);
+
+/**
+ * Extended operand mode that includes a representation of 8-bit.
+ *
+ * This is used for packing down modes when invoking some C instruction
+ * implementations.
+ */
+typedef enum IEMMODEX
+{
+ IEMMODEX_16BIT = IEMMODE_16BIT,
+ IEMMODEX_32BIT = IEMMODE_32BIT,
+ IEMMODEX_64BIT = IEMMODE_64BIT,
+ IEMMODEX_8BIT
+} IEMMODEX;
+AssertCompileSize(IEMMODEX, 4);
+
+
+#ifdef IEM_VERIFICATION_MODE
+
+/**
+ * Verification event type.
+ */
+typedef enum IEMVERIFYEVENT
+{
+ IEMVERIFYEVENT_INVALID = 0,
+ IEMVERIFYEVENT_IOPORT_READ,
+ IEMVERIFYEVENT_IOPORT_WRITE,
+ IEMVERIFYEVENT_RAM_WRITE,
+ IEMVERIFYEVENT_RAM_READ
+} IEMVERIFYEVENT;
+
+/** Checks if the event type is a RAM read or write. */
+# define IEMVERIFYEVENT_IS_RAM(a_enmType) ((a_enmType) == IEMVERIFYEVENT_RAM_WRITE || (a_enmType) == IEMVERIFYEVENT_RAM_READ)
+
+/**
+ * Verification event record.
+ */
+typedef struct IEMVERIFYEVTREC
+{
+ /** Pointer to the next record in the list. */
+ struct IEMVERIFYEVTREC *pNext;
+ /** The event type. */
+ IEMVERIFYEVENT enmEvent;
+ /** The event data. */
+ union
+ {
+ /** IEMVERIFYEVENT_IOPORT_READ */
+ struct
+ {
+ RTIOPORT Port;
+ uint32_t cbValue;
+ } IOPortRead;
+
+ /** IEMVERIFYEVENT_IOPORT_WRITE */
+ struct
+ {
+ RTIOPORT Port;
+ uint32_t cbValue;
+ uint32_t u32Value;
+ } IOPortWrite;
+
+ /** IEMVERIFYEVENT_RAM_READ */
+ struct
+ {
+ RTGCPHYS GCPhys;
+ uint32_t cb;
+ } RamRead;
+
+ /** IEMVERIFYEVENT_RAM_WRITE */
+ struct
+ {
+ RTGCPHYS GCPhys;
+ uint32_t cb;
+ uint8_t ab[32];
+ } RamWrite;
+ } u;
+} IEMVERIFYEVTREC;
+/** Pointer to an IEM event verification records. */
+typedef IEMVERIFYEVTREC *PIEMVERIFYEVTREC;
+
+#endif /* IEM_VERIFICATION_MODE */
+
+
+/**
+ * The per-CPU IEM state.
+ */
+typedef struct IEMCPU
+{
+ /** Pointer to the CPU context - ring-3 contex. */
+ R3PTRTYPE(PCPUMCTX) pCtxR3;
+ /** Pointer to the CPU context - ring-0 contex. */
+ R0PTRTYPE(PCPUMCTX) pCtxR0;
+ /** Pointer to the CPU context - raw-mode contex. */
+ RCPTRTYPE(PCPUMCTX) pCtxRC;
+
+ /** Offset of the VMCPU structure relative to this structure (negative). */
+ int32_t offVMCpu;
+ /** Offset of the VM structure relative to this structure (negative). */
+ int32_t offVM;
+
+ /** Whether to bypass access handlers or not. */
+ bool fByPassHandlers;
+ /** Explicit alignment padding. */
+ bool afAlignment0[3];
+
+ /** The flags of the current exception / interrupt. */
+ uint32_t fCurXcpt;
+ /** The current exception / interrupt. */
+ uint8_t uCurXcpt;
+ /** Exception / interrupt recursion depth. */
+ int8_t cXcptRecursions;
+ /** Explicit alignment padding. */
+ bool afAlignment1[5];
+ /** The CPL. */
+ uint8_t uCpl;
+ /** The current CPU execution mode (CS). */
+ IEMMODE enmCpuMode;
+
+ /** @name Statistics
+ * @{ */
+ /** The number of instructions we've executed. */
+ uint32_t cInstructions;
+ /** The number of potential exits. */
+ uint32_t cPotentialExits;
+#ifdef IEM_VERIFICATION_MODE
+ /** The Number of I/O port reads that has been performed. */
+ uint32_t cIOReads;
+ /** The Number of I/O port writes that has been performed. */
+ uint32_t cIOWrites;
+ /** Set if no comparison to REM is currently performed.
+ * This is used to skip past really slow bits. */
+ bool fNoRem;
+ /** Indicates that RAX and RDX differences should be ignored since RDTSC
+ * and RDTSCP are timing sensitive. */
+ bool fIgnoreRaxRdx;
+ bool afAlignment2[2];
+ /** Mask of undefined eflags.
+ * The verifier will any difference in these flags. */
+ uint32_t fUndefinedEFlags;
+ /** The physical address corresponding to abOpcodes[0]. */
+ RTGCPHYS GCPhysOpcodes;
+#endif
+ /** @} */
+
+ /** @name Decoder state.
+ * @{ */
+
+ /** The default addressing mode . */
+ IEMMODE enmDefAddrMode;
+ /** The effective addressing mode . */
+ IEMMODE enmEffAddrMode;
+ /** The default operand mode . */
+ IEMMODE enmDefOpSize;
+ /** The effective operand mode . */
+ IEMMODE enmEffOpSize;
+
+ /** The prefix mask (IEM_OP_PRF_XXX). */
+ uint32_t fPrefixes;
+ /** The extra REX ModR/M register field bit (REX.R << 3). */
+ uint8_t uRexReg;
+ /** The extra REX ModR/M r/m field, SIB base and opcode reg bit
+ * (REX.B << 3). */
+ uint8_t uRexB;
+ /** The extra REX SIB index field bit (REX.X << 3). */
+ uint8_t uRexIndex;
+ /** The effective segment register (X86_SREG_XXX). */
+ uint8_t iEffSeg;
+
+ /** The current offset into abOpcodes. */
+ uint8_t offOpcode;
+ /** The size of what has currently been fetched into abOpcodes. */
+ uint8_t cbOpcode;
+ /** The opcode bytes. */
+ uint8_t abOpcode[15];
+
+ /** @}*/
+
+ /** Alignment padding for aMemMappings. */
+ uint8_t abAlignment2[5];
+
+ /** The number of active guest memory mappings. */
+ uint8_t cActiveMappings;
+ /** The next unused mapping index. */
+ uint8_t iNextMapping;
+ /** Records for tracking guest memory mappings. */
+ struct
+ {
+ /** The address of the mapped bytes. */
+ void *pv;
+#if defined(IN_RC) && HC_ARCH_BITS == 64
+ uint32_t u32Alignment3; /**< Alignment padding. */
+#endif
+ /** The access flags (IEM_ACCESS_XXX).
+ * IEM_ACCESS_INVALID if the entry is unused. */
+ uint32_t fAccess;
+#if HC_ARCH_BITS == 64
+ uint32_t u32Alignment4; /**< Alignment padding. */
+#endif
+ } aMemMappings[3];
+
+ /** Bounce buffer info.
+ * This runs in parallel to aMemMappings. */
+ struct
+ {
+ /** The physical address of the first byte. */
+ RTGCPHYS GCPhysFirst;
+ /** The physical address of the second page. */
+ RTGCPHYS GCPhysSecond;
+ /** The number of bytes in the first page. */
+ uint16_t cbFirst;
+ /** The number of bytes in the second page. */
+ uint16_t cbSecond;
+ /** Whether it's unassigned memory. */
+ bool fUnassigned;
+ /** Explicit alignment padding. */
+ bool afAlignment5[3];
+ } aMemBbMappings[3];
+
+ /** Bounce buffer storage.
+ * This runs in parallel to aMemMappings and aMemBbMappings. */
+ struct
+ {
+ uint8_t ab[64];
+ } aBounceBuffers[3];
+
+#ifdef IEM_VERIFICATION_MODE
+ /** The event verification records for what IEM did (LIFO). */
+ R3PTRTYPE(PIEMVERIFYEVTREC) pIemEvtRecHead;
+ /** Insertion point for pIemEvtRecHead. */
+ R3PTRTYPE(PIEMVERIFYEVTREC *) ppIemEvtRecNext;
+ /** The event verification records for what the other party did (FIFO). */
+ R3PTRTYPE(PIEMVERIFYEVTREC) pOtherEvtRecHead;
+ /** Insertion point for pOtherEvtRecHead. */
+ R3PTRTYPE(PIEMVERIFYEVTREC *) ppOtherEvtRecNext;
+ /** List of free event records. */
+ R3PTRTYPE(PIEMVERIFYEVTREC) pFreeEvtRec;
+#endif
+} IEMCPU;
+/** Pointer to the per-CPU IEM state. */
+typedef IEMCPU *PIEMCPU;
+
+/** Converts a IEMCPU pointer to a VMCPU pointer.
+ * @returns VMCPU pointer.
+ * @param a_pIemCpu The IEM per CPU instance data.
+ */
+#define IEMCPU_TO_VMCPU(a_pIemCpu) ((PVMCPU)( (uintptr_t)(a_pIemCpu) + a_pIemCpu->offVMCpu ))
+
+/** Converts a IEMCPU pointer to a VM pointer.
+ * @returns VM pointer.
+ * @param a_pIemCpu The IEM per CPU instance data.
+ */
+#define IEMCPU_TO_VM(a_pIemCpu) ((PVM)( (uintptr_t)(a_pIemCpu) + a_pIemCpu->offVM ))
+
+/** @name IEM_ACCESS_XXX - Access details.
+ * @{ */
+#define IEM_ACCESS_INVALID UINT32_C(0x000000ff)
+#define IEM_ACCESS_TYPE_READ UINT32_C(0x00000001)
+#define IEM_ACCESS_TYPE_WRITE UINT32_C(0x00000002)
+#define IEM_ACCESS_TYPE_EXEC UINT32_C(0x00000004)
+#define IEM_ACCESS_TYPE_MASK UINT32_C(0x00000007)
+#define IEM_ACCESS_WHAT_CODE UINT32_C(0x00000010)
+#define IEM_ACCESS_WHAT_DATA UINT32_C(0x00000020)
+#define IEM_ACCESS_WHAT_STACK UINT32_C(0x00000030)
+#define IEM_ACCESS_WHAT_SYS UINT32_C(0x00000040)
+#define IEM_ACCESS_WHAT_MASK UINT32_C(0x00000070)
+/** Used in aMemMappings to indicate that the entry is bounce buffered. */
+#define IEM_ACCESS_BOUNCE_BUFFERED UINT32_C(0x00000100)
+/** Read+write data alias. */
+#define IEM_ACCESS_DATA_RW (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_DATA)
+/** Write data alias. */
+#define IEM_ACCESS_DATA_W (IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_DATA)
+/** Read data alias. */
+#define IEM_ACCESS_DATA_R (IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_DATA)
+/** Instruction fetch alias. */
+#define IEM_ACCESS_INSTRUCTION (IEM_ACCESS_TYPE_EXEC | IEM_ACCESS_WHAT_CODE)
+/** Stack write alias. */
+#define IEM_ACCESS_STACK_W (IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_STACK)
+/** Stack read alias. */
+#define IEM_ACCESS_STACK_R (IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_STACK)
+/** Stack read+write alias. */
+#define IEM_ACCESS_STACK_RW (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_STACK)
+/** @} */
+
+/** @name Prefix constants (IEMCPU::fPrefixes)
+ * @{ */
+#define IEM_OP_PRF_SEG_CS RT_BIT_32(0)
+#define IEM_OP_PRF_SEG_SS RT_BIT_32(1)
+#define IEM_OP_PRF_SEG_DS RT_BIT_32(2)
+#define IEM_OP_PRF_SEG_ES RT_BIT_32(3)
+#define IEM_OP_PRF_SEG_FS RT_BIT_32(4)
+#define IEM_OP_PRF_SEG_GS RT_BIT_32(5)
+#define IEM_OP_PRF_SEG_MASK UINT32_C(0x3f)
+
+#define IEM_OP_PRF_SIZE_OP RT_BIT_32(8)
+#define IEM_OP_PRF_SIZE_REX_W RT_BIT_32(9)
+#define IEM_OP_PRF_SIZE_ADDR RT_BIT_32(10)
+
+#define IEM_OP_PRF_LOCK RT_BIT_32(16)
+#define IEM_OP_PRF_REPNZ RT_BIT_32(17)
+#define IEM_OP_PRF_REPZ RT_BIT_32(18)
+
+#define IEM_OP_PRF_REX RT_BIT_32(24)
+#define IEM_OP_PRF_REX_R RT_BIT_32(25)
+#define IEM_OP_PRF_REX_B RT_BIT_32(26)
+#define IEM_OP_PRF_REX_X RT_BIT_32(27)
+/** @} */
+
+/**
+ * Tests if verification mode is enabled.
+ *
+ * This expands to @c false when IEM_VERIFICATION_MODE is not defined and
+ * should therefore cause the compiler to eliminate the verification branch
+ * of an if statement. */
+#ifdef IEM_VERIFICATION_MODE
+# define IEM_VERIFICATION_ENABLED(a_pIemCpu) (!(a_pIemCpu)->fNoRem)
+#else
+# define IEM_VERIFICATION_ENABLED(a_pIemCpu) (false)
+#endif
+
+/**
+ * Indicates to the verifier that the given flag set is undefined.
+ *
+ * Can be invoked again to add more flags.
+ *
+ * This is a NOOP if the verifier isn't compiled in.
+ */
+#ifdef IEM_VERIFICATION_MODE
+# define IEMOP_VERIFICATION_UNDEFINED_EFLAGS(a_fEfl) do { pIemCpu->fUndefinedEFlags |= (a_fEfl); } while (0)
+#else
+# define IEMOP_VERIFICATION_UNDEFINED_EFLAGS(a_fEfl) do { } while (0)
+#endif
+
+
+/** @def IEM_DECL_IMPL_TYPE
+ * For typedef'ing an instruction implementation function.
+ *
+ * @param a_RetType The return type.
+ * @param a_Name The name of the type.
+ * @param a_ArgList The argument list enclosed in parentheses.
+ */
+
+/** @def IEM_DECL_IMPL_DEF
+ * For defining an instruction implementation function.
+ *
+ * @param a_RetType The return type.
+ * @param a_Name The name of the type.
+ * @param a_ArgList The argument list enclosed in parentheses.
+ */
+
+#if defined(__GNUC__) && defined(RT_ARCH_X86)
+# define IEM_DECL_IMPL_TYPE(a_RetType, a_Name, a_ArgList) \
+ __attribute__((__fastcall__)) a_RetType (a_Name) a_ArgList
+# define IEM_DECL_IMPL_DEF(a_RetType, a_Name, a_ArgList) \
+ __attribute__((__fastcall__, __nothrow__)) a_RetType a_Name a_ArgList
+
+#elif defined(_MSC_VER) && defined(RT_ARCH_X86)
+# define IEM_DECL_IMPL_TYPE(a_RetType, a_Name, a_ArgList) \
+ a_RetType (__fastcall a_Name) a_ArgList
+# define IEM_DECL_IMPL_DEF(a_RetType, a_Name, a_ArgList) \
+ a_RetType __fastcall a_Name a_ArgList
+
+#else
+# define IEM_DECL_IMPL_TYPE(a_RetType, a_Name, a_ArgList) \
+ a_RetType (VBOXCALL a_Name) a_ArgList
+# define IEM_DECL_IMPL_DEF(a_RetType, a_Name, a_ArgList) \
+ a_RetType VBOXCALL a_Name a_ArgList
+
+#endif
+
+/** @name Arithmetic assignment operations on bytes (binary).
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU8, (uint8_t *pu8Dst, uint8_t u8Src, uint32_t *pEFlags));
+typedef FNIEMAIMPLBINU8 *PFNIEMAIMPLBINU8;
+FNIEMAIMPLBINU8 iemAImpl_add_u8, iemAImpl_add_u8_locked;
+FNIEMAIMPLBINU8 iemAImpl_adc_u8, iemAImpl_adc_u8_locked;
+FNIEMAIMPLBINU8 iemAImpl_sub_u8, iemAImpl_sub_u8_locked;
+FNIEMAIMPLBINU8 iemAImpl_sbb_u8, iemAImpl_sbb_u8_locked;
+FNIEMAIMPLBINU8 iemAImpl_or_u8, iemAImpl_or_u8_locked;
+FNIEMAIMPLBINU8 iemAImpl_xor_u8, iemAImpl_xor_u8_locked;
+FNIEMAIMPLBINU8 iemAImpl_and_u8, iemAImpl_and_u8_locked;
+/** @} */
+
+/** @name Arithmetic assignment operations on words (binary).
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU16, (uint16_t *pu16Dst, uint16_t u16Src, uint32_t *pEFlags));
+typedef FNIEMAIMPLBINU16 *PFNIEMAIMPLBINU16;
+FNIEMAIMPLBINU16 iemAImpl_add_u16, iemAImpl_add_u16_locked;
+FNIEMAIMPLBINU16 iemAImpl_adc_u16, iemAImpl_adc_u16_locked;
+FNIEMAIMPLBINU16 iemAImpl_sub_u16, iemAImpl_sub_u16_locked;
+FNIEMAIMPLBINU16 iemAImpl_sbb_u16, iemAImpl_sbb_u16_locked;
+FNIEMAIMPLBINU16 iemAImpl_or_u16, iemAImpl_or_u16_locked;
+FNIEMAIMPLBINU16 iemAImpl_xor_u16, iemAImpl_xor_u16_locked;
+FNIEMAIMPLBINU16 iemAImpl_and_u16, iemAImpl_and_u16_locked;
+/** @} */
+
+/** @name Arithmetic assignment operations on double words (binary).
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU32, (uint32_t *pu32Dst, uint32_t u32Src, uint32_t *pEFlags));
+typedef FNIEMAIMPLBINU32 *PFNIEMAIMPLBINU32;
+FNIEMAIMPLBINU32 iemAImpl_add_u32, iemAImpl_add_u32_locked;
+FNIEMAIMPLBINU32 iemAImpl_adc_u32, iemAImpl_adc_u32_locked;
+FNIEMAIMPLBINU32 iemAImpl_sub_u32, iemAImpl_sub_u32_locked;
+FNIEMAIMPLBINU32 iemAImpl_sbb_u32, iemAImpl_sbb_u32_locked;
+FNIEMAIMPLBINU32 iemAImpl_or_u32, iemAImpl_or_u32_locked;
+FNIEMAIMPLBINU32 iemAImpl_xor_u32, iemAImpl_xor_u32_locked;
+FNIEMAIMPLBINU32 iemAImpl_and_u32, iemAImpl_and_u32_locked;
+/** @} */
+
+/** @name Arithmetic assignment operations on quad words (binary).
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU64, (uint64_t *pu64Dst, uint64_t u64Src, uint32_t *pEFlags));
+typedef FNIEMAIMPLBINU64 *PFNIEMAIMPLBINU64;
+FNIEMAIMPLBINU64 iemAImpl_add_u64, iemAImpl_add_u64_locked;
+FNIEMAIMPLBINU64 iemAImpl_adc_u64, iemAImpl_adc_u64_locked;
+FNIEMAIMPLBINU64 iemAImpl_sub_u64, iemAImpl_sub_u64_locked;
+FNIEMAIMPLBINU64 iemAImpl_sbb_u64, iemAImpl_sbb_u64_locked;
+FNIEMAIMPLBINU64 iemAImpl_or_u64, iemAImpl_or_u64_locked;
+FNIEMAIMPLBINU64 iemAImpl_xor_u64, iemAImpl_xor_u64_locked;
+FNIEMAIMPLBINU64 iemAImpl_and_u64, iemAImpl_and_u64_locked;
+/** @} */
+
+/** @name Compare operations (thrown in with the binary ops).
+ * @{ */
+FNIEMAIMPLBINU8 iemAImpl_cmp_u8;
+FNIEMAIMPLBINU16 iemAImpl_cmp_u16;
+FNIEMAIMPLBINU32 iemAImpl_cmp_u32;
+FNIEMAIMPLBINU64 iemAImpl_cmp_u64;
+/** @} */
+
+/** @name Test operations (thrown in with the binary ops).
+ * @{ */
+FNIEMAIMPLBINU8 iemAImpl_test_u8;
+FNIEMAIMPLBINU16 iemAImpl_test_u16;
+FNIEMAIMPLBINU32 iemAImpl_test_u32;
+FNIEMAIMPLBINU64 iemAImpl_test_u64;
+/** @} */
+
+/** @name Bit operations operations (thrown in with the binary ops).
+ * @{ */
+FNIEMAIMPLBINU16 iemAImpl_bt_u16, iemAImpl_bt_u16_locked;
+FNIEMAIMPLBINU32 iemAImpl_bt_u32, iemAImpl_bt_u32_locked;
+FNIEMAIMPLBINU64 iemAImpl_bt_u64, iemAImpl_bt_u64_locked;
+FNIEMAIMPLBINU16 iemAImpl_btc_u16, iemAImpl_btc_u16_locked;
+FNIEMAIMPLBINU32 iemAImpl_btc_u32, iemAImpl_btc_u32_locked;
+FNIEMAIMPLBINU64 iemAImpl_btc_u64, iemAImpl_btc_u64_locked;
+FNIEMAIMPLBINU16 iemAImpl_btr_u16, iemAImpl_btr_u16_locked;
+FNIEMAIMPLBINU32 iemAImpl_btr_u32, iemAImpl_btr_u32_locked;
+FNIEMAIMPLBINU64 iemAImpl_btr_u64, iemAImpl_btr_u64_locked;
+FNIEMAIMPLBINU16 iemAImpl_bts_u16, iemAImpl_bts_u16_locked;
+FNIEMAIMPLBINU32 iemAImpl_bts_u32, iemAImpl_bts_u32_locked;
+FNIEMAIMPLBINU64 iemAImpl_bts_u64, iemAImpl_bts_u64_locked;
+/** @} */
+
+/** @name Exchange memory with register operations.
+ * @{ */
+IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u8, (uint8_t *pu8Mem, uint8_t *pu8Reg));
+IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u16,(uint16_t *pu16Mem, uint16_t *pu16Reg));
+IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u32,(uint32_t *pu32Mem, uint32_t *pu32Reg));
+IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u64,(uint64_t *pu64Mem, uint64_t *pu64Reg));
+/** @} */
+
+/** @name Exchange and add operations.
+ * @{ */
+IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u8, (uint8_t *pu8Dst, uint8_t *pu8Reg, uint32_t *pEFlags));
+IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u16,(uint16_t *pu16Dst, uint16_t *pu16Reg, uint32_t *pEFlags));
+IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u32,(uint32_t *pu32Dst, uint32_t *pu32Reg, uint32_t *pEFlags));
+IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64,(uint64_t *pu64Dst, uint64_t *pu64Reg, uint32_t *pEFlags));
+IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u8_locked, (uint8_t *pu8Dst, uint8_t *pu8Reg, uint32_t *pEFlags));
+IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u16_locked,(uint16_t *pu16Dst, uint16_t *pu16Reg, uint32_t *pEFlags));
+IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u32_locked,(uint32_t *pu32Dst, uint32_t *pu32Reg, uint32_t *pEFlags));
+IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64_locked,(uint64_t *pu64Dst, uint64_t *pu64Reg, uint32_t *pEFlags));
+/** @} */
+
+/** @name Double precision shifts
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU16,(uint16_t *pu16Dst, uint16_t u16Src, uint8_t cShift, uint32_t *pEFlags));
+typedef FNIEMAIMPLSHIFTDBLU16 *PFNIEMAIMPLSHIFTDBLU16;
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU32,(uint32_t *pu32Dst, uint32_t u32Src, uint8_t cShift, uint32_t *pEFlags));
+typedef FNIEMAIMPLSHIFTDBLU32 *PFNIEMAIMPLSHIFTDBLU32;
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU64,(uint64_t *pu64Dst, uint64_t u64Src, uint8_t cShift, uint32_t *pEFlags));
+typedef FNIEMAIMPLSHIFTDBLU64 *PFNIEMAIMPLSHIFTDBLU64;
+FNIEMAIMPLSHIFTDBLU16 iemAImpl_shld_u16;
+FNIEMAIMPLSHIFTDBLU32 iemAImpl_shld_u32;
+FNIEMAIMPLSHIFTDBLU64 iemAImpl_shld_u64;
+FNIEMAIMPLSHIFTDBLU16 iemAImpl_shrd_u16;
+FNIEMAIMPLSHIFTDBLU32 iemAImpl_shrd_u32;
+FNIEMAIMPLSHIFTDBLU64 iemAImpl_shrd_u64;
+/** @} */
+
+
+/** @name Bit search operations (thrown in with the binary ops).
+ * @{ */
+FNIEMAIMPLBINU16 iemAImpl_bsf_u16;
+FNIEMAIMPLBINU32 iemAImpl_bsf_u32;
+FNIEMAIMPLBINU64 iemAImpl_bsf_u64;
+FNIEMAIMPLBINU16 iemAImpl_bsr_u16;
+FNIEMAIMPLBINU32 iemAImpl_bsr_u32;
+FNIEMAIMPLBINU64 iemAImpl_bsr_u64;
+/** @} */
+
+/** @name Signed multiplication operations (thrown in with the binary ops).
+ * @{ */
+FNIEMAIMPLBINU16 iemAImpl_imul_two_u16;
+FNIEMAIMPLBINU32 iemAImpl_imul_two_u32;
+FNIEMAIMPLBINU64 iemAImpl_imul_two_u64;
+/** @} */
+
+/** @name Arithmetic assignment operations on bytes (unary).
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU8, (uint8_t *pu8Dst, uint32_t *pEFlags));
+typedef FNIEMAIMPLUNARYU8 *PFNIEMAIMPLUNARYU8;
+FNIEMAIMPLUNARYU8 iemAImpl_inc_u8, iemAImpl_inc_u8_locked;
+FNIEMAIMPLUNARYU8 iemAImpl_dec_u8, iemAImpl_dec_u8_locked;
+FNIEMAIMPLUNARYU8 iemAImpl_not_u8, iemAImpl_not_u8_locked;
+FNIEMAIMPLUNARYU8 iemAImpl_neg_u8, iemAImpl_neg_u8_locked;
+/** @} */
+
+/** @name Arithmetic assignment operations on words (unary).
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU16, (uint16_t *pu16Dst, uint32_t *pEFlags));
+typedef FNIEMAIMPLUNARYU16 *PFNIEMAIMPLUNARYU16;
+FNIEMAIMPLUNARYU16 iemAImpl_inc_u16, iemAImpl_inc_u16_locked;
+FNIEMAIMPLUNARYU16 iemAImpl_dec_u16, iemAImpl_dec_u16_locked;
+FNIEMAIMPLUNARYU16 iemAImpl_not_u16, iemAImpl_not_u16_locked;
+FNIEMAIMPLUNARYU16 iemAImpl_neg_u16, iemAImpl_neg_u16_locked;
+/** @} */
+
+/** @name Arithmetic assignment operations on double words (unary).
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU32, (uint32_t *pu32Dst, uint32_t *pEFlags));
+typedef FNIEMAIMPLUNARYU32 *PFNIEMAIMPLUNARYU32;
+FNIEMAIMPLUNARYU32 iemAImpl_inc_u32, iemAImpl_inc_u32_locked;
+FNIEMAIMPLUNARYU32 iemAImpl_dec_u32, iemAImpl_dec_u32_locked;
+FNIEMAIMPLUNARYU32 iemAImpl_not_u32, iemAImpl_not_u32_locked;
+FNIEMAIMPLUNARYU32 iemAImpl_neg_u32, iemAImpl_neg_u32_locked;
+/** @} */
+
+/** @name Arithmetic assignment operations on quad words (unary).
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU64, (uint64_t *pu64Dst, uint32_t *pEFlags));
+typedef FNIEMAIMPLUNARYU64 *PFNIEMAIMPLUNARYU64;
+FNIEMAIMPLUNARYU64 iemAImpl_inc_u64, iemAImpl_inc_u64_locked;
+FNIEMAIMPLUNARYU64 iemAImpl_dec_u64, iemAImpl_dec_u64_locked;
+FNIEMAIMPLUNARYU64 iemAImpl_not_u64, iemAImpl_not_u64_locked;
+FNIEMAIMPLUNARYU64 iemAImpl_neg_u64, iemAImpl_neg_u64_locked;
+/** @} */
+
+
+/** @name Shift operations on bytes (Group 2).
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU8,(uint8_t *pu8Dst, uint8_t cShift, uint32_t *pEFlags));
+typedef FNIEMAIMPLSHIFTU8 *PFNIEMAIMPLSHIFTU8;
+FNIEMAIMPLSHIFTU8 iemAImpl_rol_u8;
+FNIEMAIMPLSHIFTU8 iemAImpl_ror_u8;
+FNIEMAIMPLSHIFTU8 iemAImpl_rcl_u8;
+FNIEMAIMPLSHIFTU8 iemAImpl_rcr_u8;
+FNIEMAIMPLSHIFTU8 iemAImpl_shl_u8;
+FNIEMAIMPLSHIFTU8 iemAImpl_shr_u8;
+FNIEMAIMPLSHIFTU8 iemAImpl_sar_u8;
+/** @} */
+
+/** @name Shift operations on words (Group 2).
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU16,(uint16_t *pu16Dst, uint8_t cShift, uint32_t *pEFlags));
+typedef FNIEMAIMPLSHIFTU16 *PFNIEMAIMPLSHIFTU16;
+FNIEMAIMPLSHIFTU16 iemAImpl_rol_u16;
+FNIEMAIMPLSHIFTU16 iemAImpl_ror_u16;
+FNIEMAIMPLSHIFTU16 iemAImpl_rcl_u16;
+FNIEMAIMPLSHIFTU16 iemAImpl_rcr_u16;
+FNIEMAIMPLSHIFTU16 iemAImpl_shl_u16;
+FNIEMAIMPLSHIFTU16 iemAImpl_shr_u16;
+FNIEMAIMPLSHIFTU16 iemAImpl_sar_u16;
+/** @} */
+
+/** @name Shift operations on double words (Group 2).
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU32,(uint32_t *pu32Dst, uint8_t cShift, uint32_t *pEFlags));
+typedef FNIEMAIMPLSHIFTU32 *PFNIEMAIMPLSHIFTU32;
+FNIEMAIMPLSHIFTU32 iemAImpl_rol_u32;
+FNIEMAIMPLSHIFTU32 iemAImpl_ror_u32;
+FNIEMAIMPLSHIFTU32 iemAImpl_rcl_u32;
+FNIEMAIMPLSHIFTU32 iemAImpl_rcr_u32;
+FNIEMAIMPLSHIFTU32 iemAImpl_shl_u32;
+FNIEMAIMPLSHIFTU32 iemAImpl_shr_u32;
+FNIEMAIMPLSHIFTU32 iemAImpl_sar_u32;
+/** @} */
+
+/** @name Shift operations on words (Group 2).
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU64,(uint64_t *pu64Dst, uint8_t cShift, uint32_t *pEFlags));
+typedef FNIEMAIMPLSHIFTU64 *PFNIEMAIMPLSHIFTU64;
+FNIEMAIMPLSHIFTU64 iemAImpl_rol_u64;
+FNIEMAIMPLSHIFTU64 iemAImpl_ror_u64;
+FNIEMAIMPLSHIFTU64 iemAImpl_rcl_u64;
+FNIEMAIMPLSHIFTU64 iemAImpl_rcr_u64;
+FNIEMAIMPLSHIFTU64 iemAImpl_shl_u64;
+FNIEMAIMPLSHIFTU64 iemAImpl_shr_u64;
+FNIEMAIMPLSHIFTU64 iemAImpl_sar_u64;
+/** @} */
+
+/** @name Multiplication and division operations.
+ * @{ */
+typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU8,(uint16_t *pu16AX, uint8_t u8FactorDivisor, uint32_t *pEFlags));
+typedef FNIEMAIMPLMULDIVU8 *PFNIEMAIMPLMULDIVU8;
+FNIEMAIMPLMULDIVU8 iemAImpl_mul_u8, iemAImpl_imul_u8;
+FNIEMAIMPLMULDIVU8 iemAImpl_div_u8, iemAImpl_idiv_u8;
+
+typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU16,(uint16_t *pu16AX, uint16_t *pu16DX, uint16_t u16FactorDivisor, uint32_t *pEFlags));
+typedef FNIEMAIMPLMULDIVU16 *PFNIEMAIMPLMULDIVU16;
+FNIEMAIMPLMULDIVU16 iemAImpl_mul_u16, iemAImpl_imul_u16;
+FNIEMAIMPLMULDIVU16 iemAImpl_div_u16, iemAImpl_idiv_u16;
+
+typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU32,(uint32_t *pu32EAX, uint32_t *pu32EDX, uint32_t u32FactorDivisor, uint32_t *pEFlags));
+typedef FNIEMAIMPLMULDIVU32 *PFNIEMAIMPLMULDIVU32;
+FNIEMAIMPLMULDIVU32 iemAImpl_mul_u32, iemAImpl_imul_u32;
+FNIEMAIMPLMULDIVU32 iemAImpl_div_u32, iemAImpl_idiv_u32;
+
+typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64FactorDivisor, uint32_t *pEFlags));
+typedef FNIEMAIMPLMULDIVU64 *PFNIEMAIMPLMULDIVU64;
+FNIEMAIMPLMULDIVU64 iemAImpl_mul_u64, iemAImpl_imul_u64;
+FNIEMAIMPLMULDIVU64 iemAImpl_div_u64, iemAImpl_idiv_u64;
+/** @} */
+
+
+/** @name Function tables.
+ * @{
+ */
+
+/**
+ * Function table for a binary operator providing implementation based on
+ * operand size.
+ */
+typedef struct IEMOPBINSIZES
+{
+ PFNIEMAIMPLBINU8 pfnNormalU8, pfnLockedU8;
+ PFNIEMAIMPLBINU16 pfnNormalU16, pfnLockedU16;
+ PFNIEMAIMPLBINU32 pfnNormalU32, pfnLockedU32;
+ PFNIEMAIMPLBINU64 pfnNormalU64, pfnLockedU64;
+} IEMOPBINSIZES;
+/** Pointer to a binary operator function table. */
+typedef IEMOPBINSIZES const *PCIEMOPBINSIZES;
+
+
+/**
+ * Function table for a unary operator providing implementation based on
+ * operand size.
+ */
+typedef struct IEMOPUNARYSIZES
+{
+ PFNIEMAIMPLUNARYU8 pfnNormalU8, pfnLockedU8;
+ PFNIEMAIMPLUNARYU16 pfnNormalU16, pfnLockedU16;
+ PFNIEMAIMPLUNARYU32 pfnNormalU32, pfnLockedU32;
+ PFNIEMAIMPLUNARYU64 pfnNormalU64, pfnLockedU64;
+} IEMOPUNARYSIZES;
+/** Pointer to a unary operator function table. */
+typedef IEMOPUNARYSIZES const *PCIEMOPUNARYSIZES;
+
+
+/**
+ * Function table for a shift operator providing implementation based on
+ * operand size.
+ */
+typedef struct IEMOPSHIFTSIZES
+{
+ PFNIEMAIMPLSHIFTU8 pfnNormalU8;
+ PFNIEMAIMPLSHIFTU16 pfnNormalU16;
+ PFNIEMAIMPLSHIFTU32 pfnNormalU32;
+ PFNIEMAIMPLSHIFTU64 pfnNormalU64;
+} IEMOPSHIFTSIZES;
+/** Pointer to a shift operator function table. */
+typedef IEMOPSHIFTSIZES const *PCIEMOPSHIFTSIZES;
+
+
+/**
+ * Function table for a multiplication or division operation.
+ */
+typedef struct IEMOPMULDIVSIZES
+{
+ PFNIEMAIMPLMULDIVU8 pfnU8;
+ PFNIEMAIMPLMULDIVU16 pfnU16;
+ PFNIEMAIMPLMULDIVU32 pfnU32;
+ PFNIEMAIMPLMULDIVU64 pfnU64;
+} IEMOPMULDIVSIZES;
+/** Pointer to a multiplication or division operation function table. */
+typedef IEMOPMULDIVSIZES const *PCIEMOPMULDIVSIZES;
+
+
+/**
+ * Function table for a double precision shift operator providing implementation
+ * based on operand size.
+ */
+typedef struct IEMOPSHIFTDBLSIZES
+{
+ PFNIEMAIMPLSHIFTDBLU16 pfnNormalU16;
+ PFNIEMAIMPLSHIFTDBLU32 pfnNormalU32;
+ PFNIEMAIMPLSHIFTDBLU64 pfnNormalU64;
+} IEMOPSHIFTDBLSIZES;
+/** Pointer to a double precision shift function table. */
+typedef IEMOPSHIFTDBLSIZES const *PCIEMOPSHIFTDBLSIZES;
+
+
+/** @} */
+
+
+/** @name C instruction implementations for anything slightly complicated.
+ * @{ */
+
+/**
+ * For typedef'ing or declaring a C instruction implementation function taking
+ * no extra arguments.
+ *
+ * @param a_Name The name of the type.
+ */
+# define IEM_CIMPL_DECL_TYPE_0(a_Name) \
+ IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr))
+/**
+ * For defining a C instruction implementation function taking no extra
+ * arguments.
+ *
+ * @param a_Name The name of the function
+ */
+# define IEM_CIMPL_DEF_0(a_Name) \
+ IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr))
+/**
+ * For calling a C instruction implementation function taking no extra
+ * arguments.
+ *
+ * This special call macro adds default arguments to the call and allow us to
+ * change these later.
+ *
+ * @param a_fn The name of the function.
+ */
+# define IEM_CIMPL_CALL_0(a_fn) a_fn(pIemCpu, cbInstr)
+
+/**
+ * For typedef'ing or declaring a C instruction implementation function taking
+ * one extra argument.
+ *
+ * @param a_Name The name of the type.
+ * @param a_Type0 The argument type.
+ * @param a_Arg0 The argument name.
+ */
+# define IEM_CIMPL_DECL_TYPE_1(a_Name, a_Type0, a_Arg0) \
+ IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0))
+/**
+ * For defining a C instruction implementation function taking one extra
+ * argument.
+ *
+ * @param a_Name The name of the function
+ * @param a_Type0 The argument type.
+ * @param a_Arg0 The argument name.
+ */
+# define IEM_CIMPL_DEF_1(a_Name, a_Type0, a_Arg0) \
+ IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0))
+/**
+ * For calling a C instruction implementation function taking one extra
+ * argument.
+ *
+ * This special call macro adds default arguments to the call and allow us to
+ * change these later.
+ *
+ * @param a_fn The name of the function.
+ * @param a0 The name of the 1st argument.
+ */
+# define IEM_CIMPL_CALL_1(a_fn, a0) a_fn(pIemCpu, cbInstr, (a0))
+
+/**
+ * For typedef'ing or declaring a C instruction implementation function taking
+ * two extra arguments.
+ *
+ * @param a_Name The name of the type.
+ * @param a_Type0 The type of the 1st argument
+ * @param a_Arg0 The name of the 1st argument.
+ * @param a_Type1 The type of the 2nd argument.
+ * @param a_Arg1 The name of the 2nd argument.
+ */
+# define IEM_CIMPL_DECL_TYPE_2(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1) \
+ IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1))
+/**
+ * For defining a C instruction implementation function taking two extra
+ * arguments.
+ *
+ * @param a_Name The name of the function.
+ * @param a_Type0 The type of the 1st argument
+ * @param a_Arg0 The name of the 1st argument.
+ * @param a_Type1 The type of the 2nd argument.
+ * @param a_Arg1 The name of the 2nd argument.
+ */
+# define IEM_CIMPL_DEF_2(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1) \
+ IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1))
+/**
+ * For calling a C instruction implementation function taking two extra
+ * arguments.
+ *
+ * This special call macro adds default arguments to the call and allow us to
+ * change these later.
+ *
+ * @param a_fn The name of the function.
+ * @param a0 The name of the 1st argument.
+ * @param a1 The name of the 2nd argument.
+ */
+# define IEM_CIMPL_CALL_2(a_fn, a0, a1) a_fn(pIemCpu, cbInstr, (a0), (a1))
+
+/**
+ * For typedef'ing or declaring a C instruction implementation function taking
+ * three extra arguments.
+ *
+ * @param a_Name The name of the type.
+ * @param a_Type0 The type of the 1st argument
+ * @param a_Arg0 The name of the 1st argument.
+ * @param a_Type1 The type of the 2nd argument.
+ * @param a_Arg1 The name of the 2nd argument.
+ * @param a_Type2 The type of the 3rd argument.
+ * @param a_Arg2 The name of the 3rd argument.
+ */
+# define IEM_CIMPL_DECL_TYPE_3(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2) \
+ IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2))
+/**
+ * For defining a C instruction implementation function taking three extra
+ * arguments.
+ *
+ * @param a_Name The name of the function.
+ * @param a_Type0 The type of the 1st argument
+ * @param a_Arg0 The name of the 1st argument.
+ * @param a_Type1 The type of the 2nd argument.
+ * @param a_Arg1 The name of the 2nd argument.
+ * @param a_Type2 The type of the 3rd argument.
+ * @param a_Arg2 The name of the 3rd argument.
+ */
+# define IEM_CIMPL_DEF_3(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2) \
+ IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2))
+/**
+ * For calling a C instruction implementation function taking three extra
+ * arguments.
+ *
+ * This special call macro adds default arguments to the call and allow us to
+ * change these later.
+ *
+ * @param a_fn The name of the function.
+ * @param a0 The name of the 1st argument.
+ * @param a1 The name of the 2nd argument.
+ * @param a2 The name of the 3rd argument.
+ */
+# define IEM_CIMPL_CALL_3(a_fn, a0, a1, a2) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2))
+
+
+/**
+ * For typedef'ing or declaring a C instruction implementation function taking
+ * four extra arguments.
+ *
+ * @param a_Name The name of the type.
+ * @param a_Type0 The type of the 1st argument
+ * @param a_Arg0 The name of the 1st argument.
+ * @param a_Type1 The type of the 2nd argument.
+ * @param a_Arg1 The name of the 2nd argument.
+ * @param a_Type2 The type of the 3rd argument.
+ * @param a_Arg2 The name of the 3rd argument.
+ * @param a_Type3 The type of the 4th argument.
+ * @param a_Arg3 The name of the 4th argument.
+ */
+# define IEM_CIMPL_DECL_TYPE_4(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3) \
+ IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, a_Type3 a_Arg3))
+/**
+ * For defining a C instruction implementation function taking four extra
+ * arguments.
+ *
+ * @param a_Name The name of the function.
+ * @param a_Type0 The type of the 1st argument
+ * @param a_Arg0 The name of the 1st argument.
+ * @param a_Type1 The type of the 2nd argument.
+ * @param a_Arg1 The name of the 2nd argument.
+ * @param a_Type2 The type of the 3rd argument.
+ * @param a_Arg2 The name of the 3rd argument.
+ * @param a_Type3 The type of the 4th argument.
+ * @param a_Arg3 The name of the 4th argument.
+ */
+# define IEM_CIMPL_DEF_4(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, aArg3) \
+ IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, a_Type3 a_Arg3))
+/**
+ * For calling a C instruction implementation function taking four extra
+ * arguments.
+ *
+ * This special call macro adds default arguments to the call and allow us to
+ * change these later.
+ *
+ * @param a_fn The name of the function.
+ * @param a0 The name of the 1st argument.
+ * @param a1 The name of the 2nd argument.
+ * @param a2 The name of the 3rd argument.
+ * @param a3 The name of the 4th argument.
+ */
+# define IEM_CIMPL_CALL_4(a_fn, a0, a1, a2, a3) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2), (a3))
+
+
+/**
+ * For typedef'ing or declaring a C instruction implementation function taking
+ * five extra arguments.
+ *
+ * @param a_Name The name of the type.
+ * @param a_Type0 The type of the 1st argument
+ * @param a_Arg0 The name of the 1st argument.
+ * @param a_Type1 The type of the 2nd argument.
+ * @param a_Arg1 The name of the 2nd argument.
+ * @param a_Type2 The type of the 3rd argument.
+ * @param a_Arg2 The name of the 3rd argument.
+ * @param a_Type3 The type of the 4th argument.
+ * @param a_Arg3 The name of the 4th argument.
+ * @param a_Type4 The type of the 5th argument.
+ * @param a_Arg4 The name of the 5th argument.
+ */
+# define IEM_CIMPL_DECL_TYPE_5(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3, a_Type4, a_Arg4) \
+ IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, \
+ a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, \
+ a_Type3 a_Arg3, a_Type4 a_Arg4))
+/**
+ * For defining a C instruction implementation function taking five extra
+ * arguments.
+ *
+ * @param a_Name The name of the function.
+ * @param a_Type0 The type of the 1st argument
+ * @param a_Arg0 The name of the 1st argument.
+ * @param a_Type1 The type of the 2nd argument.
+ * @param a_Arg1 The name of the 2nd argument.
+ * @param a_Type2 The type of the 3rd argument.
+ * @param a_Arg2 The name of the 3rd argument.
+ * @param a_Type3 The type of the 4th argument.
+ * @param a_Arg3 The name of the 4th argument.
+ * @param a_Type4 The type of the 5th argument.
+ * @param a_Arg4 The name of the 5th argument.
+ */
+# define IEM_CIMPL_DEF_5(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3, a_Type4, a_Arg4) \
+ IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, \
+ a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, \
+ a_Type3 a_Arg3, a_Type4 a_Arg4))
+/**
+ * For calling a C instruction implementation function taking five extra
+ * arguments.
+ *
+ * This special call macro adds default arguments to the call and allow us to
+ * change these later.
+ *
+ * @param a_fn The name of the function.
+ * @param a0 The name of the 1st argument.
+ * @param a1 The name of the 2nd argument.
+ * @param a2 The name of the 3rd argument.
+ * @param a3 The name of the 4th argument.
+ * @param a4 The name of the 5th argument.
+ */
+# define IEM_CIMPL_CALL_5(a_fn, a0, a1, a2, a3, a4) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2), (a3), (a4))
+
+/** @} */
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/src/VBox/VMM/include/IOMInline.h b/src/VBox/VMM/include/IOMInline.h
new file mode 100644
index 000000000..b6e86b925
--- /dev/null
+++ b/src/VBox/VMM/include/IOMInline.h
@@ -0,0 +1,197 @@
+/* $Id: IOMInline.h 37467 2011-06-15 13:08:45Z vboxsync $ */
+/** @file
+ * IOM - Inlined functions.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef ___IOMInline_h
+#define ___IOMInline_h
+
+/** @addtogroup grp_iom_int Internals
+ * @internal
+ * @{
+ */
+
+/**
+ * Gets the I/O port range for the specified I/O port in the current context.
+ *
+ * @returns Pointer to I/O port range.
+ * @returns NULL if no port registered.
+ *
+ * @param pVM The VM handle.
+ * @param Port The I/O port lookup.
+ */
+DECLINLINE(CTX_SUFF(PIOMIOPORTRANGE)) iomIOPortGetRange(PVM pVM, RTIOPORT Port)
+{
+ Assert(PDMCritSectIsOwner(&pVM->iom.s.CritSect));
+ return (CTX_SUFF(PIOMIOPORTRANGE))RTAvlroIOPortRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->CTX_SUFF(IOPortTree), Port);
+}
+
+
+/**
+ * Gets the I/O port range for the specified I/O port in the HC.
+ *
+ * @returns Pointer to I/O port range.
+ * @returns NULL if no port registered.
+ *
+ * @param pVM The VM handle.
+ * @param Port The I/O port to lookup.
+ */
+DECLINLINE(PIOMIOPORTRANGER3) iomIOPortGetRangeR3(PVM pVM, RTIOPORT Port)
+{
+ Assert(PDMCritSectIsOwner(&pVM->iom.s.CritSect));
+ return (PIOMIOPORTRANGER3)RTAvlroIOPortRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortTreeR3, Port);
+}
+
+
+/**
+ * Gets the MMIO range for the specified physical address in the current context.
+ *
+ * @returns Pointer to MMIO range.
+ * @returns NULL if address not in a MMIO range.
+ *
+ * @param pVM The VM handle.
+ * @param GCPhys Physical address to lookup.
+ */
+DECLINLINE(PIOMMMIORANGE) iomMmioGetRange(PVM pVM, RTGCPHYS GCPhys)
+{
+ Assert(PDMCritSectIsOwner(&pVM->iom.s.CritSect));
+ PIOMMMIORANGE pRange = pVM->iom.s.CTX_SUFF(pMMIORangeLast);
+ if ( !pRange
+ || GCPhys - pRange->GCPhys >= pRange->cb)
+ pVM->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
+ = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOTree, GCPhys);
+ return pRange;
+}
+
+/**
+ * Retain a MMIO range.
+ *
+ * @param pRange The range to release.
+ */
+DECLINLINE(void) iomMmioRetainRange(PIOMMMIORANGE pRange)
+{
+ uint32_t cRefs = ASMAtomicIncU32(&pRange->cRefs);
+ Assert(cRefs > 1);
+ Assert(cRefs < _1M);
+}
+
+
+/**
+ * Gets the referenced MMIO range for the specified physical address in the
+ * current context.
+ *
+ * @returns Pointer to MMIO range.
+ * @returns NULL if address not in a MMIO range.
+ *
+ * @param pVM The VM handle.
+ * @param GCPhys Physical address to lookup.
+ */
+DECLINLINE(PIOMMMIORANGE) iomMmioGetRangeWithRef(PVM pVM, RTGCPHYS GCPhys)
+{
+ int rc = PDMCritSectEnter(&pVM->iom.s.CritSect, VINF_SUCCESS);
+ AssertRCReturn(rc, NULL);
+
+ PIOMMMIORANGE pRange = pVM->iom.s.CTX_SUFF(pMMIORangeLast);
+ if ( !pRange
+ || GCPhys - pRange->GCPhys >= pRange->cb)
+ pVM->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
+ = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOTree, GCPhys);
+ if (pRange)
+ iomMmioRetainRange(pRange);
+
+ PDMCritSectLeave(&pVM->iom.s.CritSect);
+ return pRange;
+}
+
+
+/**
+ * Releases a MMIO range.
+ *
+ * @param pVM The VM handle.
+ * @param pRange The range to release.
+ */
+DECLINLINE(void) iomMmioReleaseRange(PVM pVM, PIOMMMIORANGE pRange)
+{
+ uint32_t cRefs = ASMAtomicDecU32(&pRange->cRefs);
+ if (!cRefs)
+ iomMmioFreeRange(pVM, pRange);
+}
+
+
+#ifdef VBOX_STRICT
+/**
+ * Gets the MMIO range for the specified physical address in the current context.
+ *
+ * @returns Pointer to MMIO range.
+ * @returns NULL if address not in a MMIO range.
+ *
+ * @param pVM The VM handle.
+ * @param GCPhys Physical address to lookup.
+ */
+DECLINLINE(PIOMMMIORANGE) iomMMIOGetRangeUnsafe(PVM pVM, RTGCPHYS GCPhys)
+{
+ PIOMMMIORANGE pRange = pVM->iom.s.CTX_SUFF(pMMIORangeLast);
+ if ( !pRange
+ || GCPhys - pRange->GCPhys >= pRange->cb)
+ pVM->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
+ = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOTree, GCPhys);
+ return pRange;
+}
+#endif /* VBOX_STRICT */
+
+
+#ifdef VBOX_WITH_STATISTICS
+/**
+ * Gets the MMIO statistics record.
+ *
+ * In ring-3 this will lazily create missing records, while in GC/R0 the caller has to
+ * return the appropriate status to defer the operation to ring-3.
+ *
+ * @returns Pointer to MMIO stats.
+ * @returns NULL if not found (R0/GC), or out of memory (R3).
+ *
+ * @param pVM The VM handle.
+ * @param GCPhys Physical address to lookup.
+ * @param pRange The MMIO range.
+ */
+DECLINLINE(PIOMMMIOSTATS) iomMmioGetStats(PVM pVM, RTGCPHYS GCPhys, PIOMMMIORANGE pRange)
+{
+ PDMCritSectEnter(&pVM->iom.s.CritSect, VINF_SUCCESS);
+
+ /* For large ranges, we'll put everything on the first byte. */
+ if (pRange->cb > PAGE_SIZE)
+ GCPhys = pRange->GCPhys;
+
+ PIOMMMIOSTATS pStats = pVM->iom.s.CTX_SUFF(pMMIOStatsLast);
+ if ( !pStats
+ || pStats->Core.Key != GCPhys)
+ {
+ pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pVM->iom.s.CTX_SUFF(pTrees)->MmioStatTree, GCPhys);
+# ifdef IN_RING3
+ if (!pStats)
+ pStats = iomR3MMIOStatsCreate(pVM, GCPhys, pRange->pszDesc);
+# endif
+ }
+
+ PDMCritSectLeave(&pVM->iom.s.CritSect);
+ return pStats;
+}
+#endif /* VBOX_WITH_STATISTICS */
+
+
+/** @} */
+
+#endif
+
diff --git a/src/VBox/VMM/include/IOMInternal.h b/src/VBox/VMM/include/IOMInternal.h
index 9e4fcca60..dcfaa8ad1 100644
--- a/src/VBox/VMM/include/IOMInternal.h
+++ b/src/VBox/VMM/include/IOMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: IOMInternal.h $ */
+/* $Id: IOMInternal.h 37467 2011-06-15 13:08:45Z vboxsync $ */
/** @file
* IOM - Internal header file.
*/
@@ -47,7 +47,8 @@ typedef struct IOMMMIORANGE
RTGCPHYS GCPhys;
/** Size of the range. */
uint32_t cb;
- uint32_t u32Alignment; /**< Alignment padding. */
+ /** The reference counter. */
+ uint32_t volatile cRefs;
/** Pointer to user argument - R3. */
RTR3PTR pvUserR3;
@@ -284,7 +285,7 @@ typedef struct IOMTREES
/** Tree containing I/O port statistics (IOMIOPORTSTATS). */
AVLOIOPORTTREE IOPortStatTree;
/** Tree containing MMIO statistics (IOMMMIOSTATS). */
- AVLOGCPHYSTREE MMIOStatTree;
+ AVLOGCPHYSTREE MmioStatTree;
} IOMTREES;
/** Pointer to the IOM trees. */
typedef IOMTREES *PIOMTREES;
@@ -321,7 +322,7 @@ typedef struct IOM
#endif
/** Lock serializing EMT access to IOM. */
- PDMCRITSECT EmtLock;
+ PDMCRITSECT CritSect;
/** @name Caching of I/O Port and MMIO ranges and statistics.
* (Saves quite some time in rep outs/ins instruction emulation.)
@@ -417,139 +418,23 @@ typedef IOMCPU *PIOMCPU;
RT_C_DECLS_BEGIN
+void iomMmioFreeRange(PVM pVM, PIOMMMIORANGE pRange);
#ifdef IN_RING3
-PIOMIOPORTSTATS iomR3IOPortStatsCreate(PVM pVM, RTIOPORT Port, const char *pszDesc);
-PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc);
+PIOMIOPORTSTATS iomR3IOPortStatsCreate(PVM pVM, RTIOPORT Port, const char *pszDesc);
+PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc);
#endif /* IN_RING3 */
-VMMDECL(int) IOMMMIOHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
+VMMDECL(int) IOMMMIOHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
+ RTGCPHYS GCPhysFault, void *pvUser);
#ifdef IN_RING3
-DECLCALLBACK(int) IOMR3MMIOHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
-#endif
-
-
-/**
- * Gets the I/O port range for the specified I/O port in the current context.
- *
- * @returns Pointer to I/O port range.
- * @returns NULL if no port registered.
- *
- * @param pIOM IOM instance data.
- * @param Port Port to lookup.
- */
-DECLINLINE(CTX_SUFF(PIOMIOPORTRANGE)) iomIOPortGetRange(PIOM pIOM, RTIOPORT Port)
-{
-#ifdef IN_RING3
- if (PDMCritSectIsInitialized(&pIOM->EmtLock))
-#endif
- Assert(IOMIsLockOwner(IOM2VM(pIOM)));
- CTX_SUFF(PIOMIOPORTRANGE) pRange = (CTX_SUFF(PIOMIOPORTRANGE))RTAvlroIOPortRangeGet(&pIOM->CTX_SUFF(pTrees)->CTX_SUFF(IOPortTree), Port);
- return pRange;
-}
-
-
-/**
- * Gets the I/O port range for the specified I/O port in the HC.
- *
- * @returns Pointer to I/O port range.
- * @returns NULL if no port registered.
- *
- * @param pIOM IOM instance data.
- * @param Port Port to lookup.
- */
-DECLINLINE(PIOMIOPORTRANGER3) iomIOPortGetRangeR3(PIOM pIOM, RTIOPORT Port)
-{
-#ifdef IN_RING3
- if (PDMCritSectIsInitialized(&pIOM->EmtLock))
-#endif
- Assert(IOMIsLockOwner(IOM2VM(pIOM)));
- PIOMIOPORTRANGER3 pRange = (PIOMIOPORTRANGER3)RTAvlroIOPortRangeGet(&pIOM->CTX_SUFF(pTrees)->IOPortTreeR3, Port);
- return pRange;
-}
-
-
-/**
- * Gets the MMIO range for the specified physical address in the current context.
- *
- * @returns Pointer to MMIO range.
- * @returns NULL if address not in a MMIO range.
- *
- * @param pIOM IOM instance data.
- * @param GCPhys Physical address to lookup.
- */
-DECLINLINE(PIOMMMIORANGE) iomMMIOGetRange(PIOM pIOM, RTGCPHYS GCPhys)
-{
-#ifdef IN_RING3
- if (PDMCritSectIsInitialized(&pIOM->EmtLock))
-#endif
- Assert(IOMIsLockOwner(IOM2VM(pIOM)));
- PIOMMMIORANGE pRange = pIOM->CTX_SUFF(pMMIORangeLast);
- if ( !pRange
- || GCPhys - pRange->GCPhys >= pRange->cb)
- pIOM->CTX_SUFF(pMMIORangeLast) = pRange = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pIOM->CTX_SUFF(pTrees)->MMIOTree, GCPhys);
- return pRange;
-}
-
-#ifdef VBOX_STRICT
-/**
- * Gets the MMIO range for the specified physical address in the current context.
- *
- * @returns Pointer to MMIO range.
- * @returns NULL if address not in a MMIO range.
- *
- * @param pIOM IOM instance data.
- * @param GCPhys Physical address to lookup.
- */
-DECLINLINE(PIOMMMIORANGE) iomMMIOGetRangeUnsafe(PIOM pIOM, RTGCPHYS GCPhys)
-{
- PIOMMMIORANGE pRange = pIOM->CTX_SUFF(pMMIORangeLast);
- if ( !pRange
- || GCPhys - pRange->GCPhys >= pRange->cb)
- pIOM->CTX_SUFF(pMMIORangeLast) = pRange = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pIOM->CTX_SUFF(pTrees)->MMIOTree, GCPhys);
- return pRange;
-}
-#endif
-
-
-#ifdef VBOX_WITH_STATISTICS
-/**
- * Gets the MMIO statistics record.
- *
- * In ring-3 this will lazily create missing records, while in GC/R0 the caller has to
- * return the appropriate status to defer the operation to ring-3.
- *
- * @returns Pointer to MMIO stats.
- * @returns NULL if not found (R0/GC), or out of memory (R3).
- *
- * @param pIOM IOM instance data.
- * @param GCPhys Physical address to lookup.
- * @param pRange The MMIO range.
- */
-DECLINLINE(PIOMMMIOSTATS) iomMMIOGetStats(PIOM pIOM, RTGCPHYS GCPhys, PIOMMMIORANGE pRange)
-{
- Assert(IOMIsLockOwner(IOM2VM(pIOM)));
- /* For large ranges, we'll put everything on the first byte. */
- if (pRange->cb > PAGE_SIZE)
- GCPhys = pRange->GCPhys;
-
- PIOMMMIOSTATS pStats = pIOM->CTX_SUFF(pMMIOStatsLast);
- if ( !pStats
- || pStats->Core.Key != GCPhys)
- {
- pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pIOM->CTX_SUFF(pTrees)->MMIOStatTree, GCPhys);
-# ifdef IN_RING3
- if (!pStats)
- pStats = iomR3MMIOStatsCreate(IOM2VM(pIOM), GCPhys, pRange->pszDesc);
-# endif
- }
- return pStats;
-}
+DECLCALLBACK(int) IOMR3MMIOHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
+ PGMACCESSTYPE enmAccessType, void *pvUser);
#endif
/* IOM locking helpers. */
-int iomLock(PVM pVM);
-int iomTryLock(PVM pVM);
-void iomUnlock(PVM pVM);
+#define IOM_LOCK(a_pVM) PDMCritSectEnter(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)
+#define IOM_UNLOCK(a_pVM) do { PDMCritSectLeave(&(a_pVM)->iom.s.CritSect); } while (0)
+
/* Disassembly helpers used in IOMAll.cpp & IOMAllMMIO.cpp */
bool iomGetRegImmData(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint64_t *pu64Data, unsigned *pcbSize);
@@ -564,4 +449,5 @@ RT_C_DECLS_END
/** @} */
-#endif /* ___IOMInternal_h */
+#endif /* !___IOMInternal_h */
+
diff --git a/src/VBox/VMM/include/MMInternal.h b/src/VBox/VMM/include/MMInternal.h
index 40bd1b266..832fe8aa0 100644
--- a/src/VBox/VMM/include/MMInternal.h
+++ b/src/VBox/VMM/include/MMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: MMInternal.h $ */
+/* $Id: MMInternal.h 37935 2011-07-13 23:12:42Z vboxsync $ */
/** @file
* MM - Internal header file.
*/
@@ -63,10 +63,8 @@ typedef struct MMHEAPSTAT
/** Pointer to the heap the memory belongs to. */
struct MMHEAP *pHeap;
#ifdef MMR3HEAP_WITH_STATISTICS
-# if HC_ARCH_BITS == 32
- /** Aligning the statistics on an 8 byte boundary (for uint64_t and STAM). */
- void *pvAlignment;
-# endif
+ /** Number of bytes currently allocated. */
+ size_t cbCurAllocated;
/** Number of allocation. */
uint64_t cAllocations;
/** Number of reallocations. */
@@ -79,12 +77,11 @@ typedef struct MMHEAPSTAT
uint64_t cbAllocated;
/** Number of bytes freed. */
uint64_t cbFreed;
- /** Number of bytes currently allocated. */
- size_t cbCurAllocated;
#endif
} MMHEAPSTAT;
#if defined(MMR3HEAP_WITH_STATISTICS) && defined(IN_RING3)
AssertCompileMemberAlignment(MMHEAPSTAT, cAllocations, 8);
+AssertCompileSizeAlignment(MMHEAPSTAT, 8);
#endif
/** Pointer to heap statistics record. */
typedef MMHEAPSTAT *PMMHEAPSTAT;
diff --git a/src/VBox/VMM/include/PATMA.h b/src/VBox/VMM/include/PATMA.h
index 0c5007808..87dc60868 100644
--- a/src/VBox/VMM/include/PATMA.h
+++ b/src/VBox/VMM/include/PATMA.h
@@ -1,4 +1,4 @@
-/* $Id: PATMA.h $ */
+/* $Id: PATMA.h 35348 2010-12-27 16:35:23Z vboxsync $ */
/** @file
* PATM macros & definitions (identical to PATMA.mac!!)
*/
diff --git a/src/VBox/VMM/include/PATMInternal.h b/src/VBox/VMM/include/PATMInternal.h
index e5506675f..fff644010 100644
--- a/src/VBox/VMM/include/PATMInternal.h
+++ b/src/VBox/VMM/include/PATMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: PATMInternal.h $ */
+/* $Id: PATMInternal.h 36801 2011-04-21 18:14:13Z vboxsync $ */
/** @file
* PATM - Internal header file.
*/
@@ -76,7 +76,7 @@
#define MAX_INSTR_SIZE 16
-//Patch states
+/* Patch states */
#define PATCH_REFUSED 1
#define PATCH_DISABLED 2
#define PATCH_ENABLED 4
@@ -139,12 +139,12 @@
typedef struct
{
/** The key is a HC virtual address. */
- AVLPVNODECORE Core;
+ AVLPVNODECORE Core;
- uint32_t uType;
- R3PTRTYPE(uint8_t *) pRelocPos;
- RTRCPTR pSource;
- RTRCPTR pDest;
+ uint32_t uType;
+ R3PTRTYPE(uint8_t *) pRelocPos;
+ RTRCPTR pSource;
+ RTRCPTR pDest;
} RELOCREC, *PRELOCREC;
/* forward decl */
@@ -153,30 +153,30 @@ struct _PATCHINFO;
/* Cache record for guest to host pointer conversions. */
typedef struct
{
- R3PTRTYPE(uint8_t *) pPageLocStartHC;
- RCPTRTYPE(uint8_t *) pGuestLoc;
- R3PTRTYPE(void *) pPatch;
- PGMPAGEMAPLOCK Lock;
+ R3PTRTYPE(uint8_t *) pPageLocStartHC;
+ RCPTRTYPE(uint8_t *) pGuestLoc;
+ R3PTRTYPE(void *) pPatch;
+ PGMPAGEMAPLOCK Lock;
} PATMP2GLOOKUPREC, *PPATMP2GLOOKUPREC;
/* Obsolete; do not use. */
typedef struct
{
- R3PTRTYPE(uint8_t *) pPatchLocStartHC;
- R3PTRTYPE(uint8_t *) pPatchLocEndHC;
- RCPTRTYPE(uint8_t *) pGuestLoc;
- uint32_t opsize;
+ R3PTRTYPE(uint8_t *) pPatchLocStartHC;
+ R3PTRTYPE(uint8_t *) pPatchLocEndHC;
+ RCPTRTYPE(uint8_t *) pGuestLoc;
+ uint32_t opsize;
} PATMP2GLOOKUPREC_OBSOLETE;
typedef struct
{
/** The key is a pointer to a JUMPREC structure. */
- AVLPVNODECORE Core;
+ AVLPVNODECORE Core;
- R3PTRTYPE(uint8_t *) pJumpHC;
- RCPTRTYPE(uint8_t *) pTargetGC;
- uint32_t offDispl;
- uint32_t opcode;
+ R3PTRTYPE(uint8_t *) pJumpHC;
+ RCPTRTYPE(uint8_t *) pTargetGC;
+ uint32_t offDispl;
+ uint32_t opcode;
} JUMPREC, *PJUMPREC;
/**
@@ -184,23 +184,30 @@ typedef struct
*/
typedef enum
{
- PATM_LOOKUP_PATCH2GUEST, /* patch to guest */
- PATM_LOOKUP_BOTHDIR /* guest to patch + patch to guest */
+ /** patch to guest */
+ PATM_LOOKUP_PATCH2GUEST,
+ /** guest to patch + patch to guest */
+ PATM_LOOKUP_BOTHDIR
} PATM_LOOKUP_TYPE;
/**
- * Patch to guest address lookup record
+ * Patch to guest address lookup record.
*/
typedef struct RECPATCHTOGUEST
{
/** The key is an offset inside the patch memory block. */
- AVLU32NODECORE Core;
-
- RTRCPTR pOrgInstrGC;
- PATM_LOOKUP_TYPE enmType;
- bool fDirty;
- bool fJumpTarget;
- uint8_t u8DirtyOpcode; /* original opcode before writing 0xCC there to mark it dirty */
+ AVLU32NODECORE Core;
+ /** GC address of the guest instruction this record is for. */
+ RTRCPTR pOrgInstrGC;
+ /** Patch to guest lookup type. */
+ PATM_LOOKUP_TYPE enmType;
+ /** Flag whether the original instruction was changed by the guest. */
+ bool fDirty;
+ /** Flag whether this guest instruction is a jump target from
+ * a trampoline patch. */
+ bool fJumpTarget;
+ /** Original opcode before writing 0xCC there to mark it dirty. */
+ uint8_t u8DirtyOpcode;
} RECPATCHTOGUEST, *PRECPATCHTOGUEST;
/**
@@ -209,10 +216,9 @@ typedef struct RECPATCHTOGUEST
typedef struct RECGUESTTOPATCH
{
/** The key is a GC virtual address. */
- AVLU32NODECORE Core;
-
+ AVLU32NODECORE Core;
/** Patch offset (relative to PATM::pPatchMemGC / PATM::pPatchMemHC). */
- uint32_t PatchOffset;
+ uint32_t PatchOffset;
} RECGUESTTOPATCH, *PRECGUESTTOPATCH;
/**
@@ -233,92 +239,93 @@ typedef struct
int32_t nrCalls;
/** Last original guest instruction pointer; used for disassembly log. */
- RTRCPTR pLastDisasmInstrGC;
+ RTRCPTR pLastDisasmInstrGC;
/** Keeping track of multiple ret instructions. */
- RTRCPTR pPatchRetInstrGC;
+ RTRCPTR pPatchRetInstrGC;
uint32_t uPatchRetParam1;
} PATCHINFOTEMP, *PPATCHINFOTEMP;
/** Forward declaration for a pointer to a trampoline patch record. */
typedef struct TRAMPREC *PTRAMPREC;
+/**
+ * Patch information.
+ */
typedef struct _PATCHINFO
{
- uint32_t uState;
- uint32_t uOldState;
- DISCPUMODE uOpMode;
-
- /* GC pointer of privileged instruction */
- RCPTRTYPE(uint8_t *) pPrivInstrGC;
- R3PTRTYPE(uint8_t *) unusedHC; /* todo Can't remove due to structure size dependencies in saved states. */
- uint8_t aPrivInstr[MAX_INSTR_SIZE];
- uint32_t cbPrivInstr;
- uint32_t opcode; //opcode for priv instr (OP_*)
- uint32_t cbPatchJump; //patch jump size
-
+ /** Current patch state (enabled, disabled, etc.). */
+ uint32_t uState;
+ /** Previous patch state. Used when enabling a disabled patch. */
+ uint32_t uOldState;
+ /** CPU mode (16bit or 32bit). */
+ DISCPUMODE uOpMode;
+ /** GC pointer of privileged instruction */
+ RCPTRTYPE(uint8_t *) pPrivInstrGC;
+ /** @todo: Can't remove due to structure size dependencies in saved states. */
+ R3PTRTYPE(uint8_t *) unusedHC;
+ /** Original privileged guest instructions overwritten by the jump patch. */
+ uint8_t aPrivInstr[MAX_INSTR_SIZE];
+ /** Number of valid bytes in the instruction buffer. */
+ uint32_t cbPrivInstr;
+ /** Opcode for priv instr (OP_*). */
+ uint32_t opcode;
+ /** Size of the patch jump in the guest code. */
+ uint32_t cbPatchJump;
/* Only valid for PATMFL_JUMP_CONFLICT patches */
- RTRCPTR pPatchJumpDestGC;
-
- RTGCUINTPTR32 pPatchBlockOffset;
- uint32_t cbPatchBlockSize;
- uint32_t uCurPatchOffset;
+ RTRCPTR pPatchJumpDestGC;
+ /** Offset of the patch code from the beginning of the patch memory area. */
+ RTGCUINTPTR32 pPatchBlockOffset;
+ /** Size of the patch code in bytes. */
+ uint32_t cbPatchBlockSize;
+ /** Current offset of the patch starting from pPatchBlockOffset.
+ * Used during patch creation. */
+ uint32_t uCurPatchOffset;
#if HC_ARCH_BITS == 64
- uint32_t Alignment0; /**< Align flags correctly. */
+ uint32_t Alignment0; /**< Align flags correctly. */
#endif
-
- uint64_t flags;
-
+ /** PATM flags (see PATMFL_*). */
+ uint64_t flags;
/**
* Lowest and highest patched GC instruction address. To optimize searches.
*/
- RTRCPTR pInstrGCLowest;
- RTRCPTR pInstrGCHighest;
-
+ RTRCPTR pInstrGCLowest;
+ RTRCPTR pInstrGCHighest;
/* Tree of fixup records for the patch. */
- R3PTRTYPE(PAVLPVNODECORE) FixupTree;
- uint32_t nrFixups;
-
+ R3PTRTYPE(PAVLPVNODECORE) FixupTree;
+ uint32_t nrFixups;
/* Tree of jumps inside the generated patch code. */
- uint32_t nrJumpRecs;
- R3PTRTYPE(PAVLPVNODECORE) JumpTree;
-
+ uint32_t nrJumpRecs;
+ R3PTRTYPE(PAVLPVNODECORE) JumpTree;
/**
* Lookup trees for determining the corresponding guest address of an
* instruction in the patch block.
*/
- R3PTRTYPE(PAVLU32NODECORE) Patch2GuestAddrTree;
- R3PTRTYPE(PAVLU32NODECORE) Guest2PatchAddrTree;
- uint32_t nrPatch2GuestRecs;
+ R3PTRTYPE(PAVLU32NODECORE) Patch2GuestAddrTree;
+ R3PTRTYPE(PAVLU32NODECORE) Guest2PatchAddrTree;
+ uint32_t nrPatch2GuestRecs;
#if HC_ARCH_BITS == 64
- uint32_t Alignment1;
+ uint32_t Alignment1;
#endif
-
- /* Unused, but can't remove due to structure size dependencies in the saved state. */
- PATMP2GLOOKUPREC_OBSOLETE unused;
-
- /* Temporary information during patch creation. Don't waste hypervisor memory for this. */
- R3PTRTYPE(PPATCHINFOTEMP) pTempInfo;
-
- /* List of trampoline patches referencing this patch.
+ /** Unused, but can't remove due to structure size dependencies in the saved state. */
+ PATMP2GLOOKUPREC_OBSOLETE unused;
+ /** Temporary information during patch creation. Don't waste hypervisor memory for this. */
+ R3PTRTYPE(PPATCHINFOTEMP) pTempInfo;
+ /** List of trampoline patches referencing this patch.
* Used when refreshing the patch. (Only for function duplicates) */
- R3PTRTYPE(PTRAMPREC) pTrampolinePatchesHead;
-
- /* Count the number of writes to the corresponding guest code. */
- uint32_t cCodeWrites;
-
- /* Count the number of invalid writes to pages monitored for the patch. */
- //some statistics to determine if we should keep this patch activated
- uint32_t cTraps;
-
- uint32_t cInvalidWrites;
-
- // Index into the uPatchRun and uPatchTrap arrays (0..MAX_PATCHES-1)
- uint32_t uPatchIdx;
-
- /* First opcode byte, that's overwritten when a patch is marked dirty. */
- uint8_t bDirtyOpcode;
- uint8_t Alignment2[HC_ARCH_BITS == 64 ? 7 : 3]; /**< Align the structure size on a 8-byte boundary. */
+ R3PTRTYPE(PTRAMPREC) pTrampolinePatchesHead;
+ /** Count the number of writes to the corresponding guest code. */
+ uint32_t cCodeWrites;
+ /** Some statistics to determine if we should keep this patch activated. */
+ uint32_t cTraps;
+ /** Count the number of invalid writes to pages monitored for the patch. */
+ uint32_t cInvalidWrites;
+ /** Index into the uPatchRun and uPatchTrap arrays (0..MAX_PATCHES-1) */
+ uint32_t uPatchIdx;
+ /** First opcode byte, that's overwritten when a patch is marked dirty. */
+ uint8_t bDirtyOpcode;
+ /** Align the structure size on a 8-byte boundary. */
+ uint8_t Alignment2[HC_ARCH_BITS == 64 ? 7 : 3];
} PATCHINFO, *PPATCHINFO;
#define PATCHCODE_PTR_GC(pPatch) (RTRCPTR) (pVM->patm.s.pPatchMemGC + (pPatch)->pPatchBlockOffset)
@@ -330,11 +337,11 @@ typedef struct _PATCHINFO
typedef struct PATMPATCHREC
{
/** The key is a GC virtual address. */
- AVLOU32NODECORE Core;
+ AVLOU32NODECORE Core;
/** The key is a patch offset. */
- AVLOU32NODECORE CoreOffset;
-
- PATCHINFO patch;
+ AVLOU32NODECORE CoreOffset;
+ /** The patch information. */
+ PATCHINFO patch;
} PATMPATCHREC, *PPATMPATCHREC;
/**
@@ -343,9 +350,9 @@ typedef struct PATMPATCHREC
typedef struct TRAMPREC
{
/** Pointer to the next trampoline patch. */
- struct TRAMPREC *pNext;
+ struct TRAMPREC *pNext;
/** Pointer to the trampoline patch record. */
- PPATMPATCHREC pPatchTrampoline;
+ PPATMPATCHREC pPatchTrampoline;
} TRAMPREC;
/** Increment for allocating room for pointer array */
@@ -357,39 +364,42 @@ typedef struct TRAMPREC
typedef struct PATMPATCHPAGE
{
/** The key is a GC virtual address. */
- AVLOU32NODECORE Core;
+ AVLOU32NODECORE Core;
/** Region to monitor. */
- RTRCPTR pLowestAddrGC;
- RTRCPTR pHighestAddrGC;
+ RTRCPTR pLowestAddrGC;
+ RTRCPTR pHighestAddrGC;
/** Number of patches for this page. */
- uint32_t cCount;
+ uint32_t cCount;
/** Maximum nr of pointers in the array. */
- uint32_t cMaxPatches;
+ uint32_t cMaxPatches;
/** Array of patch pointers for this page. */
- R3PTRTYPE(PPATCHINFO *) aPatch;
+ R3PTRTYPE(PPATCHINFO *) aPatch;
} PATMPATCHPAGE, *PPATMPATCHPAGE;
#define PATM_PATCHREC_FROM_COREOFFSET(a) (PPATMPATCHREC)((uintptr_t)a - RT_OFFSETOF(PATMPATCHREC, CoreOffset))
#define PATM_PATCHREC_FROM_PATCHINFO(a) (PPATMPATCHREC)((uintptr_t)a - RT_OFFSETOF(PATMPATCHREC, patch))
+/**
+ * AVL trees used by PATM.
+ */
typedef struct PATMTREES
{
/**
* AVL tree with all patches (active or disabled) sorted by guest instruction address
*/
- AVLOU32TREE PatchTree;
+ AVLOU32TREE PatchTree;
/**
* AVL tree with all patches sorted by patch address (offset actually)
*/
- AVLOU32TREE PatchTreeByPatchAddr;
+ AVLOU32TREE PatchTreeByPatchAddr;
/**
* AVL tree with all pages which were (partly) patched
*/
- AVLOU32TREE PatchTreeByPage;
+ AVLOU32TREE PatchTreeByPage;
- uint32_t align[1];
+ uint32_t align[1];
} PATMTREES, *PPATMTREES;
/**
@@ -400,148 +410,139 @@ typedef struct PATM
{
/** Offset to the VM structure.
* See PATM2VM(). */
- RTINT offVM;
-
- RCPTRTYPE(uint8_t *) pPatchMemGC;
- R3PTRTYPE(uint8_t *) pPatchMemHC;
- uint32_t cbPatchMem;
- uint32_t offPatchMem;
- bool fOutOfMemory;
-
- int32_t deltaReloc;
-
- /* GC PATM state pointers */
- R3PTRTYPE(PPATMGCSTATE) pGCStateHC;
- RCPTRTYPE(PPATMGCSTATE) pGCStateGC;
-
+ RTINT offVM;
+ /** Pointer to the patch memory area (GC) */
+ RCPTRTYPE(uint8_t *) pPatchMemGC;
+ /** Pointer to the patch memory area (HC) */
+ R3PTRTYPE(uint8_t *) pPatchMemHC;
+ /** Size of the patch memory area in bytes. */
+ uint32_t cbPatchMem;
+ /** Relative offset to the next free byte starting from the start of the region. */
+ uint32_t offPatchMem;
+ /** Flag whether PATM ran out of patch memory. */
+ bool fOutOfMemory;
+ /** Delta to the new relocated HMA area.
+ * Used only during PATMR3Relocate(). */
+ int32_t deltaReloc;
+ /* GC PATM state pointer - HC pointer. */
+ R3PTRTYPE(PPATMGCSTATE) pGCStateHC;
+ /* GC PATM state pointer - GC pointer. */
+ RCPTRTYPE(PPATMGCSTATE) pGCStateGC;
/** PATM stack page for call instruction execution. (2 parts: one for our private stack and one to store the original return address */
- RCPTRTYPE(RTRCPTR *) pGCStackGC;
- R3PTRTYPE(RTRCPTR *) pGCStackHC;
-
+ RCPTRTYPE(RTRCPTR *) pGCStackGC;
+ /** HC pointer of the PATM stack page. */
+ R3PTRTYPE(RTRCPTR *) pGCStackHC;
/** GC pointer to CPUMCTX structure. */
- RCPTRTYPE(PCPUMCTX) pCPUMCtxGC;
-
- /* GC statistics pointers */
- RCPTRTYPE(PSTAMRATIOU32) pStatsGC;
- R3PTRTYPE(PSTAMRATIOU32) pStatsHC;
-
+ RCPTRTYPE(PCPUMCTX) pCPUMCtxGC;
+ /** GC statistics pointer. */
+ RCPTRTYPE(PSTAMRATIOU32) pStatsGC;
+ /** HC statistics pointer. */
+ R3PTRTYPE(PSTAMRATIOU32) pStatsHC;
/* Current free index value (uPatchRun/uPatchTrap arrays). */
- uint32_t uCurrentPatchIdx;
-
+ uint32_t uCurrentPatchIdx;
/* Temporary counter for patch installation call depth. (in order not to go on forever) */
- uint32_t ulCallDepth;
-
+ uint32_t ulCallDepth;
/** Number of page lookup records. */
- uint32_t cPageRecords;
-
- /**
- * Lowest and highest patched GC instruction addresses. To optimize searches.
- */
- RTRCPTR pPatchedInstrGCLowest;
- RTRCPTR pPatchedInstrGCHighest;
-
+ uint32_t cPageRecords;
+ /** Lowest and highest patched GC instruction addresses. To optimize searches. */
+ RTRCPTR pPatchedInstrGCLowest;
+ RTRCPTR pPatchedInstrGCHighest;
/** Pointer to the patch tree for instructions replaced by 'int 3'. */
- RCPTRTYPE(PPATMTREES) PatchLookupTreeGC;
- R3PTRTYPE(PPATMTREES) PatchLookupTreeHC;
-
+ RCPTRTYPE(PPATMTREES) PatchLookupTreeGC;
+ R3PTRTYPE(PPATMTREES) PatchLookupTreeHC;
/** Global PATM lookup and call function (used by call patches). */
- RTRCPTR pfnHelperCallGC;
+ RTRCPTR pfnHelperCallGC;
/** Global PATM return function (used by ret patches). */
- RTRCPTR pfnHelperRetGC;
+ RTRCPTR pfnHelperRetGC;
/** Global PATM jump function (used by indirect jmp patches). */
- RTRCPTR pfnHelperJumpGC;
+ RTRCPTR pfnHelperJumpGC;
/** Global PATM return function (used by iret patches). */
- RTRCPTR pfnHelperIretGC;
-
+ RTRCPTR pfnHelperIretGC;
/** Fake patch record for global functions. */
- R3PTRTYPE(PPATMPATCHREC) pGlobalPatchRec;
-
+ R3PTRTYPE(PPATMPATCHREC) pGlobalPatchRec;
/** Pointer to original sysenter handler */
- RTRCPTR pfnSysEnterGC;
+ RTRCPTR pfnSysEnterGC;
/** Pointer to sysenter handler trampoline */
- RTRCPTR pfnSysEnterPatchGC;
+ RTRCPTR pfnSysEnterPatchGC;
/** Sysenter patch index (for stats only) */
- uint32_t uSysEnterPatchIdx;
-
- // GC address of fault in monitored page (set by PATMGCMonitorPage, used by PATMR3HandleMonitoredPage)
- RTRCPTR pvFaultMonitor;
-
- /* Temporary information for pending MMIO patch. Set in GC or R0 context. */
+ uint32_t uSysEnterPatchIdx;
+ /** GC address of fault in monitored page (set by PATMGCMonitorPage, used by PATMR3HandleMonitoredPage)- */
+ RTRCPTR pvFaultMonitor;
+ /** Temporary information for pending MMIO patch. Set in GC or R0 context. */
struct
{
- RTGCPHYS GCPhys;
- RTRCPTR pCachedData;
- RTRCPTR Alignment0; /**< Align the structure size on a 8-byte boundary. */
+ RTGCPHYS GCPhys;
+ RTRCPTR pCachedData;
+ RTRCPTR Alignment0; /**< Align the structure size on a 8-byte boundary. */
} mmio;
-
- /* Temporary storage during load/save state */
+ /** Temporary storage during load/save state */
struct
{
- R3PTRTYPE(PSSMHANDLE) pSSM;
- uint32_t cPatches;
+ R3PTRTYPE(PSSMHANDLE) pSSM;
+ uint32_t cPatches;
#if HC_ARCH_BITS == 64
- uint32_t Alignment0; /**< Align the structure size on a 8-byte boundary. */
+ uint32_t Alignment0; /**< Align the structure size on a 8-byte boundary. */
#endif
} savedstate;
- STAMCOUNTER StatNrOpcodeRead;
- STAMCOUNTER StatDisabled;
- STAMCOUNTER StatUnusable;
- STAMCOUNTER StatEnabled;
- STAMCOUNTER StatInstalled;
- STAMCOUNTER StatInstalledFunctionPatches;
- STAMCOUNTER StatInstalledTrampoline;
- STAMCOUNTER StatInstalledJump;
- STAMCOUNTER StatInt3Callable;
- STAMCOUNTER StatInt3BlockRun;
- STAMCOUNTER StatOverwritten;
- STAMCOUNTER StatFixedConflicts;
- STAMCOUNTER StatFlushed;
- STAMCOUNTER StatPageBoundaryCrossed;
- STAMCOUNTER StatMonitored;
- STAMPROFILEADV StatHandleTrap;
- STAMCOUNTER StatSwitchBack;
- STAMCOUNTER StatSwitchBackFail;
- STAMCOUNTER StatPATMMemoryUsed;
- STAMCOUNTER StatDuplicateREQSuccess;
- STAMCOUNTER StatDuplicateREQFailed;
- STAMCOUNTER StatDuplicateUseExisting;
- STAMCOUNTER StatFunctionFound;
- STAMCOUNTER StatFunctionNotFound;
- STAMPROFILEADV StatPatchWrite;
- STAMPROFILEADV StatPatchWriteDetect;
- STAMCOUNTER StatDirty;
- STAMCOUNTER StatPushTrap;
- STAMCOUNTER StatPatchWriteInterpreted;
- STAMCOUNTER StatPatchWriteInterpretedFailed;
-
- STAMCOUNTER StatSysEnter;
- STAMCOUNTER StatSysExit;
- STAMCOUNTER StatEmulIret;
- STAMCOUNTER StatEmulIretFailed;
-
- STAMCOUNTER StatInstrDirty;
- STAMCOUNTER StatInstrDirtyGood;
- STAMCOUNTER StatInstrDirtyBad;
-
- STAMCOUNTER StatPatchPageInserted;
- STAMCOUNTER StatPatchPageRemoved;
-
- STAMCOUNTER StatPatchRefreshSuccess;
- STAMCOUNTER StatPatchRefreshFailed;
-
- STAMCOUNTER StatGenRet;
- STAMCOUNTER StatGenRetReused;
- STAMCOUNTER StatGenJump;
- STAMCOUNTER StatGenCall;
- STAMCOUNTER StatGenPopf;
-
- STAMCOUNTER StatCheckPendingIRQ;
-
- STAMCOUNTER StatFunctionLookupReplace;
- STAMCOUNTER StatFunctionLookupInsert;
- uint32_t StatU32FunctionMaxSlotsUsed;
- uint32_t Alignment0; /**< Align the structure size on a 8-byte boundary. */
+ STAMCOUNTER StatNrOpcodeRead;
+ STAMCOUNTER StatDisabled;
+ STAMCOUNTER StatUnusable;
+ STAMCOUNTER StatEnabled;
+ STAMCOUNTER StatInstalled;
+ STAMCOUNTER StatInstalledFunctionPatches;
+ STAMCOUNTER StatInstalledTrampoline;
+ STAMCOUNTER StatInstalledJump;
+ STAMCOUNTER StatInt3Callable;
+ STAMCOUNTER StatInt3BlockRun;
+ STAMCOUNTER StatOverwritten;
+ STAMCOUNTER StatFixedConflicts;
+ STAMCOUNTER StatFlushed;
+ STAMCOUNTER StatPageBoundaryCrossed;
+ STAMCOUNTER StatMonitored;
+ STAMPROFILEADV StatHandleTrap;
+ STAMCOUNTER StatSwitchBack;
+ STAMCOUNTER StatSwitchBackFail;
+ STAMCOUNTER StatPATMMemoryUsed;
+ STAMCOUNTER StatDuplicateREQSuccess;
+ STAMCOUNTER StatDuplicateREQFailed;
+ STAMCOUNTER StatDuplicateUseExisting;
+ STAMCOUNTER StatFunctionFound;
+ STAMCOUNTER StatFunctionNotFound;
+ STAMPROFILEADV StatPatchWrite;
+ STAMPROFILEADV StatPatchWriteDetect;
+ STAMCOUNTER StatDirty;
+ STAMCOUNTER StatPushTrap;
+ STAMCOUNTER StatPatchWriteInterpreted;
+ STAMCOUNTER StatPatchWriteInterpretedFailed;
+
+ STAMCOUNTER StatSysEnter;
+ STAMCOUNTER StatSysExit;
+ STAMCOUNTER StatEmulIret;
+ STAMCOUNTER StatEmulIretFailed;
+
+ STAMCOUNTER StatInstrDirty;
+ STAMCOUNTER StatInstrDirtyGood;
+ STAMCOUNTER StatInstrDirtyBad;
+
+ STAMCOUNTER StatPatchPageInserted;
+ STAMCOUNTER StatPatchPageRemoved;
+
+ STAMCOUNTER StatPatchRefreshSuccess;
+ STAMCOUNTER StatPatchRefreshFailed;
+
+ STAMCOUNTER StatGenRet;
+ STAMCOUNTER StatGenRetReused;
+ STAMCOUNTER StatGenJump;
+ STAMCOUNTER StatGenCall;
+ STAMCOUNTER StatGenPopf;
+
+ STAMCOUNTER StatCheckPendingIRQ;
+
+ STAMCOUNTER StatFunctionLookupReplace;
+ STAMCOUNTER StatFunctionLookupInsert;
+ uint32_t StatU32FunctionMaxSlotsUsed;
+ uint32_t Alignment0; /**< Align the structure size on a 8-byte boundary. */
} PATM, *PPATM;
@@ -697,11 +698,11 @@ int patmReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned size, void *pvUserdat
*/
typedef struct
{
- PVM pVM;
- PPATCHINFO pPatchInfo;
+ PVM pVM;
+ PPATCHINFO pPatchInfo;
R3PTRTYPE(uint8_t *) pInstrHC;
- RTRCPTR pInstrGC;
- uint32_t fReadFlags;
+ RTRCPTR pInstrGC;
+ uint32_t fReadFlags;
} PATMDISASM, *PPATMDISASM;
inline bool PATMR3DISInstr(PVM pVM, PPATCHINFO pPatch, DISCPUSTATE *pCpu, RTRCPTR InstrGC,
diff --git a/src/VBox/VMM/include/PDMAsyncCompletionFileInternal.h b/src/VBox/VMM/include/PDMAsyncCompletionFileInternal.h
index 2fd3811cf..8054b1c6d 100644
--- a/src/VBox/VMM/include/PDMAsyncCompletionFileInternal.h
+++ b/src/VBox/VMM/include/PDMAsyncCompletionFileInternal.h
@@ -1,4 +1,4 @@
-/* $Id: PDMAsyncCompletionFileInternal.h $ */
+/* $Id: PDMAsyncCompletionFileInternal.h 37596 2011-06-22 19:30:06Z vboxsync $ */
/** @file
* PDM Async I/O - Transport data asynchronous in R3 using EMT.
*/
@@ -43,6 +43,11 @@
* instead of managing larger blocks) to have this global for the whole VM.
*/
+/** Enable for delay injection from the debugger. */
+#if 0
+# define PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
+#endif
+
RT_C_DECLS_BEGIN
/**
@@ -321,7 +326,7 @@ typedef struct PDMASYNCCOMPLETIONENDPOINTFILE
/** Flags for opening the file. */
unsigned fFlags;
/** File handle. */
- RTFILE File;
+ RTFILE hFile;
/**
* Real size of the file. Only updated if
* data is appended.
@@ -365,6 +370,14 @@ typedef struct PDMASYNCCOMPLETIONENDPOINTFILE
/** Status code to inject for the next complete write. */
volatile int rcReqWrite;
#endif
+#ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
+ /** Request delay. */
+ volatile uint32_t msDelay;
+ /** The current task which gets delayed. */
+ PPDMASYNCCOMPLETIONTASKFILE pReqDelayed;
+ /** Timestamp when the delay expires. */
+ uint64_t tsDelayEnd;
+#endif
/** Flag whether a blocking event is pending and needs
* processing by the I/O manager. */
bool fBlockingEventPending;
diff --git a/src/VBox/VMM/include/PDMAsyncCompletionInternal.h b/src/VBox/VMM/include/PDMAsyncCompletionInternal.h
index 72867bcba..21e70d2f1 100644
--- a/src/VBox/VMM/include/PDMAsyncCompletionInternal.h
+++ b/src/VBox/VMM/include/PDMAsyncCompletionInternal.h
@@ -1,4 +1,4 @@
-/* $Id: PDMAsyncCompletionInternal.h $ */
+/* $Id: PDMAsyncCompletionInternal.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* PDM - Pluggable Device Manager, Async I/O Completion internal header.
*/
diff --git a/src/VBox/VMM/include/PDMBlkCacheInternal.h b/src/VBox/VMM/include/PDMBlkCacheInternal.h
index 60765df5c..c9155d712 100644
--- a/src/VBox/VMM/include/PDMBlkCacheInternal.h
+++ b/src/VBox/VMM/include/PDMBlkCacheInternal.h
@@ -1,4 +1,4 @@
-/* $Id: PDMBlkCacheInternal.h $ */
+/* $Id: PDMBlkCacheInternal.h 37935 2011-07-13 23:12:42Z vboxsync $ */
/** @file
* PDM Block Cache.
*/
@@ -102,59 +102,59 @@ typedef struct PDMBLKLRULIST
typedef struct PDMBLKCACHEGLOBAL
{
/** Pointer to the owning VM instance. */
- PVM pVM;
+ PVM pVM;
/** Maximum size of the cache in bytes. */
- uint32_t cbMax;
+ uint32_t cbMax;
/** Current size of the cache in bytes. */
- uint32_t cbCached;
+ uint32_t cbCached;
/** Critical section protecting the cache. */
- RTCRITSECT CritSect;
+ RTCRITSECT CritSect;
/** Maximum number of bytes cached. */
- uint32_t cbRecentlyUsedInMax;
+ uint32_t cbRecentlyUsedInMax;
/** Maximum number of bytes in the paged out list .*/
- uint32_t cbRecentlyUsedOutMax;
+ uint32_t cbRecentlyUsedOutMax;
/** Recently used cache entries list */
- PDMBLKLRULIST LruRecentlyUsedIn;
+ PDMBLKLRULIST LruRecentlyUsedIn;
/** Scorecard cache entry list. */
- PDMBLKLRULIST LruRecentlyUsedOut;
+ PDMBLKLRULIST LruRecentlyUsedOut;
/** List of frequently used cache entries */
- PDMBLKLRULIST LruFrequentlyUsed;
+ PDMBLKLRULIST LruFrequentlyUsed;
/** Commit timeout in milli seconds */
- uint32_t u32CommitTimeoutMs;
+ uint32_t u32CommitTimeoutMs;
/** Number of dirty bytes needed to start a commit of the data to the disk. */
- uint32_t cbCommitDirtyThreshold;
+ uint32_t cbCommitDirtyThreshold;
/** Current number of dirty bytes in the cache. */
- volatile uint32_t cbDirty;
+ volatile uint32_t cbDirty;
+ /** Flag whether the VM was suspended becaus of an I/O error. */
+ volatile bool fIoErrorVmSuspended;
/** Flag whether a commit is currently in progress. */
- volatile bool fCommitInProgress;
+ volatile bool fCommitInProgress;
/** Commit interval timer */
- PTMTIMERR3 pTimerCommit;
+ PTMTIMERR3 pTimerCommit;
/** Number of endpoints using the cache. */
- uint32_t cRefs;
+ uint32_t cRefs;
/** List of all users of this cache. */
- RTLISTNODE ListUsers;
+ RTLISTNODE ListUsers;
#ifdef VBOX_WITH_STATISTICS
/** Hit counter. */
- STAMCOUNTER cHits;
+ STAMCOUNTER cHits;
/** Partial hit counter. */
- STAMCOUNTER cPartialHits;
+ STAMCOUNTER cPartialHits;
/** Miss counter. */
- STAMCOUNTER cMisses;
+ STAMCOUNTER cMisses;
/** Bytes read from cache. */
- STAMCOUNTER StatRead;
+ STAMCOUNTER StatRead;
/** Bytes written to the cache. */
- STAMCOUNTER StatWritten;
+ STAMCOUNTER StatWritten;
/** Time spend to get an entry in the AVL tree. */
- STAMPROFILEADV StatTreeGet;
+ STAMPROFILEADV StatTreeGet;
/** Time spend to insert an entry in the AVL tree. */
- STAMPROFILEADV StatTreeInsert;
+ STAMPROFILEADV StatTreeInsert;
/** Time spend to remove an entry in the AVL tree. */
- STAMPROFILEADV StatTreeRemove;
+ STAMPROFILEADV StatTreeRemove;
/** Number of times a buffer could be reused. */
- STAMCOUNTER StatBuffersReused;
+ STAMCOUNTER StatBuffersReused;
#endif
- /** Flag whether the VM was suspended becaus of an I/O error. */
- volatile bool fIoErrorVmSuspended;
} PDMBLKCACHEGLOBAL;
#ifdef VBOX_WITH_STATISTICS
AssertCompileMemberAlignment(PDMBLKCACHEGLOBAL, cHits, sizeof(uint64_t));
diff --git a/src/VBox/VMM/include/PDMInternal.h b/src/VBox/VMM/include/PDMInternal.h
index f73a61668..74bd66a1e 100644
--- a/src/VBox/VMM/include/PDMInternal.h
+++ b/src/VBox/VMM/include/PDMInternal.h
@@ -1,10 +1,10 @@
-/* $Id: PDMInternal.h $ */
+/* $Id: PDMInternal.h 37836 2011-07-08 10:26:19Z vboxsync $ */
/** @file
* PDM - Internal header file.
*/
/*
- * 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;
@@ -49,7 +49,7 @@ RT_C_DECLS_BEGIN
/** @def PDMCRITSECT_STRICT
* Enables/disables PDM critsect strictness like deadlock detection. */
-#if (defined(RT_LOCK_STRICT) && defined(IN_RING3)) || defined(DOXYGEN_RUNNING)
+#if (defined(RT_LOCK_STRICT) && defined(IN_RING3) && !defined(IEM_VERIFICATION_MODE)) || defined(DOXYGEN_RUNNING)
# define PDMCRITSECT_STRICT
#endif
@@ -267,8 +267,14 @@ typedef struct PDMCRITSECTINT
PVMR0 pVMR0;
/** Pointer to the VM - GCPtr. */
PVMRC pVMRC;
+ /** Set if this critical section is the automatically created default
+ * section of a device.. */
+ bool fAutomaticDefaultCritsect;
+ /** Set if the critical section is used by a timer or similar.
+ * See PDMR3DevGetCritSect. */
+ bool fUsedByTimerOrSimilar;
/** Alignment padding. */
- uint32_t padding;
+ bool afPadding[2];
/** Event semaphore that is scheduled to be signaled upon leaving the
* critical section. This is Ring-3 only of course. */
RTSEMEVENT EventToSignal;
@@ -939,13 +945,6 @@ typedef struct PDMCPU
R3PTRTYPE(PPDMCRITSECT) apQueuedCritSectsLeaves[8];
} PDMCPU;
-/**
- * Converts a PDM pointer into a VM pointer.
- * @returns Pointer to the VM structure the PDM is part of.
- * @param pPDM Pointer to PDM instance data.
- */
-#define PDM2VM(pPDM) ( (PVM)((char*)pPDM - pPDM->offVM) )
-
/**
* PDM VM Instance data.
@@ -953,10 +952,15 @@ typedef struct PDMCPU
*/
typedef struct PDM
{
- /** Offset to the VM structure.
- * See PDM2VM(). */
- RTUINT offVM;
- RTUINT uPadding0; /**< Alignment padding.*/
+ /** The PDM lock.
+ * This is used to protect everything that deals with interrupts, i.e.
+ * the PIC, APIC, IOAPIC and PCI devices plus some PDM functions. */
+ PDMCRITSECT CritSect;
+ /** The NOP critical section.
+ * This is a dummy critical section that will not do any thread
+ * serialization but instead let all threads enter immediately and
+ * concurrently. */
+ PDMCRITSECT NopCritSect;
/** List of registered devices. (FIFO) */
R3PTRTYPE(PPDMDEV) pDevs;
@@ -1013,11 +1017,6 @@ typedef struct PDM
RTGCPHYS GCPhysVMMDevHeap;
/** @} */
- /** The PDM lock.
- * This is used to protect everything that deals with interrupts, i.e.
- * the PIC, APIC, IOAPIC and PCI devices plus some PDM functions. */
- PDMCRITSECT CritSect;
-
/** Number of times a critical section leave request needed to be queued for ring-3 execution. */
STAMCOUNTER StatQueuedCritSectLeaves;
} PDM;
@@ -1084,6 +1083,7 @@ extern const PDMPCIHLPR3 g_pdmR3DevPciHlp;
extern const PDMDMACHLP g_pdmR3DevDmacHlp;
extern const PDMRTCHLP g_pdmR3DevRtcHlp;
extern const PDMHPETHLPR3 g_pdmR3DevHpetHlp;
+extern const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp;
#endif
@@ -1126,6 +1126,8 @@ extern const PDMHPETHLPR3 g_pdmR3DevHpetHlp;
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);
+int pdmR3CritSectInitDeviceAuto(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
+ const char *pszNameFmt, ...);
int pdmR3CritSectDeleteDevice(PVM pVM, PPDMDEVINS pDevIns);
int pdmR3CritSectInitDriver(PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...);
int pdmR3CritSectDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns);
@@ -1158,7 +1160,7 @@ void pdmR3QueueRelocate(PVM pVM, RTGCINTPTR offDelta);
int pdmR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
-int pdmR3ThreadCreateUsb(PVM pVM, PPDMDRVINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
+int pdmR3ThreadCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
int pdmR3ThreadCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
diff --git a/src/VBox/VMM/include/PGMGstDefs.h b/src/VBox/VMM/include/PGMGstDefs.h
index 5345b0fd7..6c3302da8 100644
--- a/src/VBox/VMM/include/PGMGstDefs.h
+++ b/src/VBox/VMM/include/PGMGstDefs.h
@@ -1,4 +1,4 @@
-/* $Id: PGMGstDefs.h $ */
+/* $Id: PGMGstDefs.h 36891 2011-04-29 13:22:57Z vboxsync $ */
/** @file
* VBox - Page Manager, Guest Paging Template - All context code.
*/
@@ -139,7 +139,7 @@
# define GST_PDE_BIG_PG_MASK X86_PDE4M_PG_MASK
# define GST_GET_PTE_GCPHYS(Pte) ((Pte).u & GST_PDE_PG_MASK)
# define GST_GET_PDE_GCPHYS(Pde) ((Pde).u & GST_PDE_PG_MASK)
-# define GST_GET_BIG_PDE_GCPHYS(pVM, Pde) pgmGstGet4MBPhysPage(&(pVM)->pgm.s, Pde)
+# define GST_GET_BIG_PDE_GCPHYS(pVM, Pde) pgmGstGet4MBPhysPage((pVM), Pde)
# define GST_GET_PDE_SHW_FLAGS(pVCpu, Pde) ((Pde).u & (X86_PDE_P | X86_PDE_RW | X86_PDE_US | X86_PDE_A))
# define GST_GET_BIG_PDE_SHW_FLAGS(pVCpu, Pde) \
((Pde).u & (X86_PDE4M_P | X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_A))
diff --git a/src/VBox/VMM/include/PGMInline.h b/src/VBox/VMM/include/PGMInline.h
index ab3184583..9f5eace56 100644
--- a/src/VBox/VMM/include/PGMInline.h
+++ b/src/VBox/VMM/include/PGMInline.h
@@ -1,4 +1,4 @@
-/* $Id: PGMInline.h $ */
+/* $Id: PGMInline.h 37354 2011-06-07 15:05:32Z vboxsync $ */
/** @file
* PGM - Inlined functions.
*/
@@ -45,67 +45,64 @@
* @{
*/
-/** @todo Split out all the inline stuff into a separate file. Then we can
- * include it later when VM and VMCPU are defined and so avoid all that
- * &pVM->pgm.s and &pVCpu->pgm.s stuff. It also chops ~1600 lines off
- * this file and will make it somewhat easier to navigate... */
-
/**
* Gets the PGMRAMRANGE structure for a guest page.
*
* @returns Pointer to the RAM range on success.
* @returns NULL on a VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS condition.
*
- * @param pPGM PGM handle.
+ * @param pVM The VM handle.
* @param GCPhys The GC physical address.
*/
-DECLINLINE(PPGMRAMRANGE) pgmPhysGetRange(PPGM pPGM, RTGCPHYS GCPhys)
+DECLINLINE(PPGMRAMRANGE) pgmPhysGetRange(PVM pVM, RTGCPHYS GCPhys)
{
- /*
- * Optimize for the first range.
- */
- PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges);
- RTGCPHYS off = GCPhys - pRam->GCPhys;
- if (RT_UNLIKELY(off >= pRam->cb))
- {
- do
- {
- pRam = pRam->CTX_SUFF(pNext);
- if (RT_UNLIKELY(!pRam))
- break;
- off = GCPhys - pRam->GCPhys;
- } while (off >= pRam->cb);
- }
+ PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+ if (!pRam || GCPhys - pRam->GCPhys >= pRam->cb)
+ pRam = pgmPhysGetRangeSlow(pVM, GCPhys);
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbHits));
return pRam;
}
/**
+ * Gets the PGMRAMRANGE structure for a guest page, if unassigned get the ram
+ * range above it.
+ *
+ * @returns Pointer to the RAM range on success.
+ * @returns NULL if the address is located after the last range.
+ *
+ * @param pVM The VM handle.
+ * @param GCPhys The GC physical address.
+ */
+DECLINLINE(PPGMRAMRANGE) pgmPhysGetRangeAtOrAbove(PVM pVM, RTGCPHYS GCPhys)
+{
+ PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+ if ( !pRam
+ || (GCPhys - pRam->GCPhys) >= pRam->cb)
+ return pgmPhysGetRangeAtOrAboveSlow(pVM, GCPhys);
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbHits));
+ return pRam;
+}
+
+
+
+/**
* Gets the PGMPAGE structure for a guest page.
*
* @returns Pointer to the page on success.
* @returns NULL on a VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS condition.
*
- * @param pPGM PGM handle.
+ * @param pVM The VM handle.
* @param GCPhys The GC physical address.
*/
-DECLINLINE(PPGMPAGE) pgmPhysGetPage(PPGM pPGM, RTGCPHYS GCPhys)
+DECLINLINE(PPGMPAGE) pgmPhysGetPage(PVM pVM, RTGCPHYS GCPhys)
{
- /*
- * Optimize for the first range.
- */
- PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges);
- RTGCPHYS off = GCPhys - pRam->GCPhys;
- if (RT_UNLIKELY(off >= pRam->cb))
- {
- do
- {
- pRam = pRam->CTX_SUFF(pNext);
- if (RT_UNLIKELY(!pRam))
- return NULL;
- off = GCPhys - pRam->GCPhys;
- } while (off >= pRam->cb);
- }
+ PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+ RTGCPHYS off;
+ if ( !pRam
+ || (off = GCPhys - pRam->GCPhys) >= pRam->cb)
+ return pgmPhysGetPageSlow(pVM, GCPhys);
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbHits));
return &pRam->aPages[off >> PAGE_SHIFT];
}
@@ -119,31 +116,19 @@ DECLINLINE(PPGMPAGE) pgmPhysGetPage(PPGM pPGM, RTGCPHYS GCPhys)
* @retval VINF_SUCCESS and a valid *ppPage on success.
* @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if the address isn't valid.
*
- * @param pPGM PGM handle.
+ * @param pVM The VM handle.
* @param GCPhys The GC physical address.
* @param ppPage Where to store the page pointer on success.
*/
-DECLINLINE(int) pgmPhysGetPageEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage)
+DECLINLINE(int) pgmPhysGetPageEx(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage)
{
- /*
- * Optimize for the first range.
- */
- PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges);
- RTGCPHYS off = GCPhys - pRam->GCPhys;
- if (RT_UNLIKELY(off >= pRam->cb))
- {
- do
- {
- pRam = pRam->CTX_SUFF(pNext);
- if (RT_UNLIKELY(!pRam))
- {
- *ppPage = NULL; /* avoid incorrect and very annoying GCC warnings */
- return VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS;
- }
- off = GCPhys - pRam->GCPhys;
- } while (off >= pRam->cb);
- }
- *ppPage = &pRam->aPages[off >> PAGE_SHIFT];
+ PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+ RTGCPHYS off;
+ if ( !pRam
+ || (off = GCPhys - pRam->GCPhys) >= pRam->cb)
+ return pgmPhysGetPageExSlow(pVM, GCPhys, ppPage);
+ *ppPage = &pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT];
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbHits));
return VINF_SUCCESS;
}
@@ -159,34 +144,25 @@ DECLINLINE(int) pgmPhysGetPageEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage)
* @retval VINF_SUCCESS and a valid *ppPage on success.
* @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if the address isn't valid.
*
- * @param pPGM PGM handle.
+ * @param pVM The VM handle.
* @param GCPhys The GC physical address.
* @param ppPage Where to store the page pointer on success.
* @param ppRamHint Where to read and store the ram list hint.
* The caller initializes this to NULL before the call.
*/
-DECLINLINE(int) pgmPhysGetPageWithHintEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRamHint)
+DECLINLINE(int) pgmPhysGetPageWithHintEx(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRamHint)
{
RTGCPHYS off;
PPGMRAMRANGE pRam = *ppRamHint;
if ( !pRam
|| RT_UNLIKELY((off = GCPhys - pRam->GCPhys) >= pRam->cb))
{
- pRam = pPGM->CTX_SUFF(pRamRanges);
- off = GCPhys - pRam->GCPhys;
- if (RT_UNLIKELY(off >= pRam->cb))
- {
- do
- {
- pRam = pRam->CTX_SUFF(pNext);
- if (RT_UNLIKELY(!pRam))
- {
- *ppPage = NULL; /* Kill the incorrect and extremely annoying GCC warnings. */
- return VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS;
- }
- off = GCPhys - pRam->GCPhys;
- } while (off >= pRam->cb);
- }
+ pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+ if ( !pRam
+ || (off = GCPhys - pRam->GCPhys) >= pRam->cb)
+ return pgmPhysGetPageAndRangeExSlow(pVM, GCPhys, ppPage, ppRamHint);
+
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbHits));
*ppRamHint = pRam;
}
*ppPage = &pRam->aPages[off >> PAGE_SHIFT];
@@ -200,64 +176,20 @@ DECLINLINE(int) pgmPhysGetPageWithHintEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE p
* @returns Pointer to the page on success.
* @returns NULL on a VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS condition.
*
- * @param pPGM PGM handle.
- * @param GCPhys The GC physical address.
- * @param ppRam Where to store the pointer to the PGMRAMRANGE.
- */
-DECLINLINE(PPGMPAGE) pgmPhysGetPageAndRange(PPGM pPGM, RTGCPHYS GCPhys, PPGMRAMRANGE *ppRam)
-{
- /*
- * Optimize for the first range.
- */
- PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges);
- RTGCPHYS off = GCPhys - pRam->GCPhys;
- if (RT_UNLIKELY(off >= pRam->cb))
- {
- do
- {
- pRam = pRam->CTX_SUFF(pNext);
- if (RT_UNLIKELY(!pRam))
- return NULL;
- off = GCPhys - pRam->GCPhys;
- } while (off >= pRam->cb);
- }
- *ppRam = pRam;
- return &pRam->aPages[off >> PAGE_SHIFT];
-}
-
-
-/**
- * Gets the PGMPAGE structure for a guest page together with the PGMRAMRANGE.
- *
- * @returns Pointer to the page on success.
- * @returns NULL on a VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS condition.
- *
- * @param pPGM PGM handle.
+ * @param pVM The VM handle.
* @param GCPhys The GC physical address.
* @param ppPage Where to store the pointer to the PGMPAGE structure.
* @param ppRam Where to store the pointer to the PGMRAMRANGE structure.
*/
-DECLINLINE(int) pgmPhysGetPageAndRangeEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRam)
+DECLINLINE(int) pgmPhysGetPageAndRangeEx(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRam)
{
- /*
- * Optimize for the first range.
- */
- PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges);
- RTGCPHYS off = GCPhys - pRam->GCPhys;
- if (RT_UNLIKELY(off >= pRam->cb))
- {
- do
- {
- pRam = pRam->CTX_SUFF(pNext);
- if (RT_UNLIKELY(!pRam))
- {
- *ppRam = NULL; /* Shut up silly GCC warnings. */
- *ppPage = NULL; /* ditto */
- return VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS;
- }
- off = GCPhys - pRam->GCPhys;
- } while (off >= pRam->cb);
- }
+ PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+ RTGCPHYS off;
+ if ( !pRam
+ || (off = GCPhys - pRam->GCPhys) >= pRam->cb)
+ return pgmPhysGetPageAndRangeExSlow(pVM, GCPhys, ppPage, ppRam);
+
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbHits));
*ppRam = pRam;
*ppPage = &pRam->aPages[off >> PAGE_SHIFT];
return VINF_SUCCESS;
@@ -268,17 +200,17 @@ DECLINLINE(int) pgmPhysGetPageAndRangeEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE p
* Convert GC Phys to HC Phys.
*
* @returns VBox status.
- * @param pPGM PGM handle.
+ * @param pVM The VM handle.
* @param GCPhys The GC physical address.
* @param pHCPhys Where to store the corresponding HC physical address.
*
* @deprecated Doesn't deal with zero, shared or write monitored pages.
* Avoid when writing new code!
*/
-DECLINLINE(int) pgmRamGCPhys2HCPhys(PPGM pPGM, RTGCPHYS GCPhys, PRTHCPHYS pHCPhys)
+DECLINLINE(int) pgmRamGCPhys2HCPhys(PVM pVM, RTGCPHYS GCPhys, PRTHCPHYS pHCPhys)
{
PPGMPAGE pPage;
- int rc = pgmPhysGetPageEx(pPGM, GCPhys, &pPage);
+ int rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
if (RT_FAILURE(rc))
return rc;
*pHCPhys = PGM_PAGE_GET_HCPHYS(pPage) | (GCPhys & PAGE_OFFSET_MASK);
@@ -343,10 +275,12 @@ DECLINLINE(int) pgmRZDynMapGCPageV2Inlined(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhy
/*
* Get the ram range.
*/
- PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
- RTGCPHYS off = GCPhys - pRam->GCPhys;
- if (RT_UNLIKELY(off >= pRam->cb
- /** @todo || page state stuff */))
+ PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+ RTGCPHYS off;
+ if ( !pRam
+ || (off = GCPhys - pRam->GCPhys) >= pRam->cb
+ /** @todo || page state stuff */
+ )
{
/* This case is not counted into StatRZDynMapGCPageInl. */
STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZDynMapGCPageInlRamMisses);
@@ -417,10 +351,12 @@ DECLINLINE(int) pgmRZDynMapGCPageOffInlined(PVMCPU pVCpu, RTGCPHYS GCPhys, void
* Get the ram range.
*/
PVM pVM = pVCpu->CTX_SUFF(pVM);
- PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
- RTGCPHYS off = GCPhys - pRam->GCPhys;
- if (RT_UNLIKELY(off >= pRam->cb
- /** @todo || page state stuff */))
+ PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+ RTGCPHYS off;
+ if ( !pRam
+ || (off = GCPhys - pRam->GCPhys) >= pRam->cb
+ /** @todo || page state stuff */
+ )
{
/* This case is not counted into StatRZDynMapGCPageInl. */
STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZDynMapGCPageInlRamMisses);
@@ -512,21 +448,21 @@ DECLINLINE(void *) pgmPoolMapPageV2Inlined(PVM pVM, PVMCPU pVCpu, PPGMPOOLPAGE p
* @retval VINF_SUCCESS on success
* @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
*
- * @param pPGM The PGM instance handle.
+ * @param pVM The VM handle.
* @param GCPhys The address of the guest page.
* @param ppTlbe Where to store the pointer to the TLB entry.
*/
-DECLINLINE(int) pgmPhysPageQueryTlbe(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGEMAPTLBE ppTlbe)
+DECLINLINE(int) pgmPhysPageQueryTlbe(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGEMAPTLBE ppTlbe)
{
int rc;
- PPGMPAGEMAPTLBE pTlbe = &pPGM->CTXSUFF(PhysTlb).aEntries[PGM_PAGEMAPTLB_IDX(GCPhys)];
+ PPGMPAGEMAPTLBE pTlbe = &pVM->pgm.s.CTXSUFF(PhysTlb).aEntries[PGM_PAGEMAPTLB_IDX(GCPhys)];
if (pTlbe->GCPhys == (GCPhys & X86_PTE_PAE_PG_MASK))
{
- STAM_COUNTER_INC(&pPGM->CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbHits));
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbHits));
rc = VINF_SUCCESS;
}
else
- rc = pgmPhysPageLoadIntoTlb(pPGM, GCPhys);
+ rc = pgmPhysPageLoadIntoTlb(pVM, GCPhys);
*ppTlbe = pTlbe;
return rc;
}
@@ -540,23 +476,23 @@ DECLINLINE(int) pgmPhysPageQueryTlbe(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGEMAPTLB
* @retval VINF_SUCCESS on success
* @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
*
- * @param pPGM The PGM instance handle.
+ * @param pVM The VM handle.
* @param pPage Pointer to the PGMPAGE structure corresponding to
* GCPhys.
* @param GCPhys The address of the guest page.
* @param ppTlbe Where to store the pointer to the TLB entry.
*/
-DECLINLINE(int) pgmPhysPageQueryTlbeWithPage(PPGM pPGM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPPGMPAGEMAPTLBE ppTlbe)
+DECLINLINE(int) pgmPhysPageQueryTlbeWithPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPPGMPAGEMAPTLBE ppTlbe)
{
int rc;
- PPGMPAGEMAPTLBE pTlbe = &pPGM->CTXSUFF(PhysTlb).aEntries[PGM_PAGEMAPTLB_IDX(GCPhys)];
+ PPGMPAGEMAPTLBE pTlbe = &pVM->pgm.s.CTXSUFF(PhysTlb).aEntries[PGM_PAGEMAPTLB_IDX(GCPhys)];
if (pTlbe->GCPhys == (GCPhys & X86_PTE_PAE_PG_MASK))
{
- STAM_COUNTER_INC(&pPGM->CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbHits));
+ STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbHits));
rc = VINF_SUCCESS;
}
else
- rc = pgmPhysPageLoadIntoTlbWithPage(pPGM, pPage, GCPhys);
+ rc = pgmPhysPageLoadIntoTlbWithPage(pVM, pPage, GCPhys);
*ppTlbe = pTlbe;
return rc;
}
@@ -566,29 +502,29 @@ DECLINLINE(int) pgmPhysPageQueryTlbeWithPage(PPGM pPGM, PPGMPAGE pPage, RTGCPHYS
/**
* Enables write monitoring for an allocated page.
- *
- * The caller is responsible for updating the shadow page tables.
- *
+ *
+ * The caller is responsible for updating the shadow page tables.
+ *
* @param pVM The VM handle.
- * @param pPage The page to write monitor.
+ * @param pPage The page to write monitor.
* @param GCPhysPage The address of the page.
*/
DECLINLINE(void) pgmPhysPageWriteMonitor(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhysPage)
{
Assert(PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED);
- Assert(PGMIsLockOwner(pVM));
+ PGM_LOCK_ASSERT_OWNER(pVM);
- PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_WRITE_MONITORED);
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_WRITE_MONITORED);
pVM->pgm.s.cMonitoredPages++;
/* Large pages must disabled. */
if (PGM_PAGE_GET_PDE_TYPE(pPage) == PGM_PAGE_PDE_TYPE_PDE)
{
- PPGMPAGE pFirstPage = pgmPhysGetPage(&pVM->pgm.s, GCPhysPage & X86_PDE2M_PAE_PG_MASK);
+ PPGMPAGE pFirstPage = pgmPhysGetPage(pVM, GCPhysPage & X86_PDE2M_PAE_PG_MASK);
AssertFatal(pFirstPage);
if (PGM_PAGE_GET_PDE_TYPE(pFirstPage) == PGM_PAGE_PDE_TYPE_PDE)
{
- PGM_PAGE_SET_PDE_TYPE(pFirstPage, PGM_PAGE_PDE_TYPE_PDE_DISABLED);
+ PGM_PAGE_SET_PDE_TYPE(pVM, pFirstPage, PGM_PAGE_PDE_TYPE_PDE_DISABLED);
pVM->pgm.s.cLargePagesDisabled++;
}
else
@@ -637,15 +573,15 @@ DECL_FORCE_INLINE(bool) pgmGst32BitIsPageSizeExtActive(PVMCPU pVCpu)
* Takes PSE-36 into account.
*
* @returns guest physical address
- * @param pPGM Pointer to the PGM instance data.
+ * @param pVM The VM handle.
* @param Pde Guest Pde
*/
-DECLINLINE(RTGCPHYS) pgmGstGet4MBPhysPage(PPGM pPGM, X86PDE Pde)
+DECLINLINE(RTGCPHYS) pgmGstGet4MBPhysPage(PVM pVM, X86PDE Pde)
{
RTGCPHYS GCPhys = Pde.u & X86_PDE4M_PG_MASK;
GCPhys |= (RTGCPHYS)Pde.b.u8PageNoHigh << 32;
- return GCPhys & pPGM->GCPhys4MBPSEMask;
+ return GCPhys & pVM->pgm.s.GCPhys4MBPSEMask;
}
@@ -1306,16 +1242,16 @@ DECLINLINE(unsigned) pgmHandlerVirtualCalcState(PPGMVIRTHANDLER pCur)
/**
- * Clears one physical page of a virtual handler
+ * Clears one physical page of a virtual handler.
*
- * @param pPGM Pointer to the PGM instance.
- * @param pCur Virtual handler structure
- * @param iPage Physical page index
+ * @param pVM The VM handle.
+ * @param pCur Virtual handler structure.
+ * @param iPage Physical page index.
*
* @remark Only used when PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL is being set, so no
* need to care about other handlers in the same page.
*/
-DECLINLINE(void) pgmHandlerVirtualClearPage(PPGM pPGM, PPGMVIRTHANDLER pCur, unsigned iPage)
+DECLINLINE(void) pgmHandlerVirtualClearPage(PVM pVM, PPGMVIRTHANDLER pCur, unsigned iPage)
{
const PPGMPHYS2VIRTHANDLER pPhys2Virt = &pCur->aPhysToVirt[iPage];
@@ -1330,7 +1266,7 @@ DECLINLINE(void) pgmHandlerVirtualClearPage(PPGM pPGM, PPGMVIRTHANDLER pCur, uns
if (pPhys2Virt->offNextAlias & PGMPHYS2VIRTHANDLER_IS_HEAD)
{
/* We're the head of the alias chain. */
- PPGMPHYS2VIRTHANDLER pRemove = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysRemove(&pPGM->CTX_SUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key); NOREF(pRemove);
+ PPGMPHYS2VIRTHANDLER pRemove = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysRemove(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key); NOREF(pRemove);
#ifdef VBOX_STRICT_PGM_HANDLER_VIRTUAL
AssertReleaseMsg(pRemove != NULL,
("pPhys2Virt=%p:{.Core.Key=%RGp, .Core.KeyLast=%RGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n",
@@ -1351,14 +1287,14 @@ DECLINLINE(void) pgmHandlerVirtualClearPage(PPGM pPGM, PPGMVIRTHANDLER pCur, uns
pNext, pNext->Core.Key, pNext->Core.KeyLast, pNext->offVirtHandler, pNext->offNextAlias));
#endif
pNext->offNextAlias |= PGMPHYS2VIRTHANDLER_IS_HEAD;
- bool fRc = RTAvlroGCPhysInsert(&pPGM->CTX_SUFF(pTrees)->PhysToVirtHandlers, &pNext->Core);
+ bool fRc = RTAvlroGCPhysInsert(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysToVirtHandlers, &pNext->Core);
AssertRelease(fRc);
}
}
else
{
/* Locate the previous node in the alias chain. */
- PPGMPHYS2VIRTHANDLER pPrev = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysGet(&pPGM->CTX_SUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key);
+ PPGMPHYS2VIRTHANDLER pPrev = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key);
#ifdef VBOX_STRICT_PGM_HANDLER_VIRTUAL
AssertReleaseMsg(pPrev != pPhys2Virt,
("pPhys2Virt=%p:{.Core.Key=%RGp, .Core.KeyLast=%RGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32} pPrev=%p\n",
@@ -1404,7 +1340,7 @@ DECLINLINE(void) pgmHandlerVirtualClearPage(PPGM pPGM, PPGMVIRTHANDLER pCur, uns
/*
* Clear the ram flags for this page.
*/
- PPGMPAGE pPage = pgmPhysGetPage(pPGM, pPhys2Virt->Core.Key);
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, pPhys2Virt->Core.Key);
AssertReturnVoid(pPage);
PGM_PAGE_SET_HNDL_VIRT_STATE(pPage, PGM_PAGE_HNDL_VIRT_STATE_NONE);
}
@@ -1437,6 +1373,9 @@ DECLINLINE(void) pgmTrackDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPoolPage, PPG
/*
* Just deal with the simple case here.
*/
+# ifdef VBOX_STRICT
+ PVM pVM = pPool->CTX_SUFF(pVM); NOREF(pVM);
+# endif
# ifdef LOG_ENABLED
const unsigned uOrg = PGM_PAGE_GET_TRACKING(pPhysPage);
# endif
@@ -1446,7 +1385,7 @@ DECLINLINE(void) pgmTrackDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPoolPage, PPG
Assert(pPoolPage->idx == PGM_PAGE_GET_TD_IDX(pPhysPage));
Assert(iPte == PGM_PAGE_GET_PTE_INDEX(pPhysPage));
/* Invalidate the tracking data. */
- PGM_PAGE_SET_TRACKING(pPhysPage, 0);
+ PGM_PAGE_SET_TRACKING(pVM, pPhysPage, 0);
}
else
pgmPoolTrackPhysExtDerefGCPhys(pPool, pPoolPage, pPhysPage, iPte);
@@ -1464,7 +1403,7 @@ DECLINLINE(void) pgmTrackDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPoolPage, PPG
*/
DECLINLINE(void) pgmPoolCacheUsed(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
{
- Assert(PGMIsLockOwner(pPool->CTX_SUFF(pVM)));
+ PGM_LOCK_ASSERT_OWNER(pPool->CTX_SUFF(pVM));
/*
* Move to the head of the age list.
@@ -1495,7 +1434,7 @@ DECLINLINE(void) pgmPoolCacheUsed(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
*/
DECLINLINE(void) pgmPoolLockPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
{
- Assert(PGMIsLockOwner(pPool->CTX_SUFF(pVM)));
+ PGM_LOCK_ASSERT_OWNER(pPool->CTX_SUFF(pVM));
ASMAtomicIncU32(&pPage->cLocked);
}
@@ -1508,7 +1447,7 @@ DECLINLINE(void) pgmPoolLockPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
*/
DECLINLINE(void) pgmPoolUnlockPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
{
- Assert(PGMIsLockOwner(pPool->CTX_SUFF(pVM)));
+ PGM_LOCK_ASSERT_OWNER(pPool->CTX_SUFF(pVM));
Assert(pPage->cLocked);
ASMAtomicDecU32(&pPage->cLocked);
}
@@ -1520,7 +1459,7 @@ DECLINLINE(void) pgmPoolUnlockPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
* @returns VBox status code.
* @param pPage PGM pool page
*/
-DECLINLINE(bool) pgmPoolIsPageLocked(PPGM pPGM, PPGMPOOLPAGE pPage)
+DECLINLINE(bool) pgmPoolIsPageLocked(PPGMPOOLPAGE pPage)
{
if (pPage->cLocked)
{
@@ -1539,14 +1478,14 @@ DECLINLINE(bool) pgmPoolIsPageLocked(PPGM pPGM, PPGMPOOLPAGE pPage)
* @returns boolean result
* @param pVM VM handle.
*/
-DECL_FORCE_INLINE(bool) pgmMapAreMappingsEnabled(PPGM pPGM)
+DECL_FORCE_INLINE(bool) pgmMapAreMappingsEnabled(PVM pVM)
{
#ifdef PGM_WITHOUT_MAPPINGS
/* There are no mappings in VT-x and AMD-V mode. */
- Assert(pPGM->fMappingsDisabled);
+ Assert(pVM->pgm.s.fMappingsDisabled);
return false;
#else
- return !pPGM->fMappingsDisabled;
+ return !pVM->pgm.s.fMappingsDisabled;
#endif
}
@@ -1557,15 +1496,15 @@ DECL_FORCE_INLINE(bool) pgmMapAreMappingsEnabled(PPGM pPGM)
* @returns true / false.
* @param pVM The VM handle.
*/
-DECL_FORCE_INLINE(bool) pgmMapAreMappingsFloating(PPGM pPGM)
+DECL_FORCE_INLINE(bool) pgmMapAreMappingsFloating(PVM pVM)
{
#ifdef PGM_WITHOUT_MAPPINGS
/* There are no mappings in VT-x and AMD-V mode. */
- Assert(pPGM->fMappingsDisabled);
+ Assert(pVM->pgm.s.fMappingsDisabled);
return false;
#else
- return !pPGM->fMappingsDisabled
- && !pPGM->fMappingsFixed;
+ return !pVM->pgm.s.fMappingsDisabled
+ && !pVM->pgm.s.fMappingsFixed;
#endif
}
diff --git a/src/VBox/VMM/include/PGMInternal.h b/src/VBox/VMM/include/PGMInternal.h
index 09e087dbf..51332e021 100644
--- a/src/VBox/VMM/include/PGMInternal.h
+++ b/src/VBox/VMM/include/PGMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: PGMInternal.h $ */
+/* $Id: PGMInternal.h 37370 2011-06-08 08:29:42Z vboxsync $ */
/** @file
* PGM - Internal header file.
*/
@@ -321,7 +321,7 @@
* For best effect only apply this to the page that was mapped most recently.
*
* @param pVCpu The current CPU.
- * @param pPage The pool page.
+ * @param pvPage The pool page.
*/
#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
# ifdef LOG_ENABLED
@@ -340,7 +340,7 @@
* For best effect only apply this to the page that was mapped most recently.
*
* @param pVM The VM handle.
- * @param pPage The pool page.
+ * @param pvPage The pool page.
*/
#define PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvPage) PGM_DYNMAP_UNUSED_HINT(VMMGetCpu(pVM), pvPage)
@@ -688,44 +688,55 @@ typedef PGMVIRTHANDLER *PPGMVIRTHANDLER;
* using PGM_PAGE_GET_*, PGM_PAGE_IS_ and PGM_PAGE_SET_* macros for *all*
* accesses to the structure.
*/
-typedef struct PGMPAGE
+typedef union PGMPAGE
{
- /** The physical address and the Page ID. */
- RTHCPHYS HCPhysAndPageID;
- /** Combination of:
- * - [0-7]: u2HandlerPhysStateY - the physical handler state
- * (PGM_PAGE_HNDL_PHYS_STATE_*).
- * - [8-9]: u2HandlerVirtStateY - the virtual handler state
- * (PGM_PAGE_HNDL_VIRT_STATE_*).
- * - [10]: u1FTDirty - indicator of dirty page for fault tolerance tracking
- * - [13-14]: u2PDEType - paging structure needed to map the page (PGM_PAGE_PDE_TYPE_*)
- * - [15]: fWrittenToY - flag indicating that a write monitored page was
- * written to when set.
- * - [11-13]: 3 unused bits.
- * @remarks Warning! All accesses to the bits are hardcoded.
- *
- * @todo Change this to a union with both bitfields, u8 and u accessors.
- * That'll help deal with some of the hardcoded accesses.
- *
- * @todo Include uStateY and uTypeY as well so it becomes 32-bit. This
- * will make it possible to turn some of the 16-bit accesses into
- * 32-bit ones, which may be efficient (stalls).
- */
- RTUINT16U u16MiscY;
- /** The page state.
- * Only 3 bits are really needed for this. */
- uint16_t uStateY : 3;
- /** The page type (PGMPAGETYPE).
- * Only 3 bits are really needed for this. */
- uint16_t uTypeY : 3;
- /** PTE index for usage tracking (page pool). */
- uint16_t uPteIdx : 10;
- /** Usage tracking (page pool). */
- uint16_t u16TrackingY;
- /** The number of read locks on this page. */
- uint8_t cReadLocksY;
- /** The number of write locks on this page. */
- uint8_t cWriteLocksY;
+ /** Structured view. */
+ struct
+ {
+ /** 1:0 - The physical handler state (PGM_PAGE_HNDL_PHYS_STATE_*). */
+ uint64_t u2HandlerPhysStateY : 2;
+ /** 3:2 - Paging structure needed to map the page
+ * (PGM_PAGE_PDE_TYPE_*). */
+ uint64_t u2PDETypeY : 2;
+ /** 4 - Indicator of dirty page for fault tolerance tracking. */
+ uint64_t fFTDirtyY : 1;
+ /** 5 - Flag indicating that a write monitored page was written to
+ * when set. */
+ uint64_t fWrittenToY : 1;
+ /** 7:6 - Unused. */
+ uint64_t u2Unused0 : 2;
+ /** 9:8 - The physical handler state (PGM_PAGE_HNDL_VIRT_STATE_*). */
+ uint64_t u2HandlerVirtStateY : 2;
+ /** 11:10 - Unused. */
+ uint64_t u2Unused1 : 2;
+ /** 12:48 - The host physical frame number (shift left to get the
+ * address). */
+ uint64_t HCPhysFN : 36;
+ /** 50:48 - The page state. */
+ uint64_t uStateY : 3;
+ /** 51:53 - The page type (PGMPAGETYPE). */
+ uint64_t uTypeY : 3;
+ /** 63:54 - PTE index for usage tracking (page pool). */
+ uint64_t u10PteIdx : 10;
+
+ /** The GMM page ID. */
+ uint32_t idPage;
+ /** Usage tracking (page pool). */
+ uint16_t u16TrackingY;
+ /** The number of read locks on this page. */
+ uint8_t cReadLocksY;
+ /** The number of write locks on this page. */
+ uint8_t cWriteLocksY;
+ } s;
+
+ /** 64-bit integer view. */
+ uint64_t au64[2];
+ /** 16-bit view. */
+ uint32_t au32[4];
+ /** 16-bit view. */
+ uint16_t au16[8];
+ /** 8-bit view. */
+ uint8_t au8[16];
} PGMPAGE;
AssertCompileSize(PGMPAGE, 16);
/** Pointer to a physical guest page. */
@@ -738,46 +749,37 @@ typedef PPGMPAGE *PPPGMPAGE;
/**
* Clears the page structure.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_CLEAR(pPage) \
+#define PGM_PAGE_CLEAR(a_pPage) \
do { \
- (pPage)->HCPhysAndPageID = 0; \
- (pPage)->uStateY = 0; \
- (pPage)->uTypeY = 0; \
- (pPage)->uPteIdx = 0; \
- (pPage)->u16MiscY.u = 0; \
- (pPage)->u16TrackingY = 0; \
- (pPage)->cReadLocksY = 0; \
- (pPage)->cWriteLocksY = 0; \
+ (a_pPage)->au64[0] = 0; \
+ (a_pPage)->au64[1] = 0; \
} while (0)
/**
* Initializes the page structure.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_INIT(pPage, _HCPhys, _idPage, _uType, _uState) \
+#define PGM_PAGE_INIT(a_pPage, a_HCPhys, a_idPage, a_uType, a_uState) \
do { \
- RTHCPHYS SetHCPhysTmp = (_HCPhys); \
+ RTHCPHYS SetHCPhysTmp = (a_HCPhys); \
AssertFatal(!(SetHCPhysTmp & ~UINT64_C(0x0000fffffffff000))); \
- (pPage)->HCPhysAndPageID = (SetHCPhysTmp << (28-12)) | ((_idPage) & UINT32_C(0x0fffffff)); \
- (pPage)->uStateY = (_uState); \
- (pPage)->uTypeY = (_uType); \
- (pPage)->uPteIdx = 0; \
- (pPage)->u16MiscY.u = 0; \
- (pPage)->u16TrackingY = 0; \
- (pPage)->cReadLocksY = 0; \
- (pPage)->cWriteLocksY = 0; \
+ (a_pPage)->au64[0] = SetHCPhysTmp; \
+ (a_pPage)->au64[1] = 0; \
+ (a_pPage)->s.idPage = (a_idPage); \
+ (a_pPage)->s.uStateY = (a_uState); \
+ (a_pPage)->s.uTypeY = (a_uType); \
} while (0)
/**
* Initializes the page structure of a ZERO page.
- * @param pPage Pointer to the physical guest page tracking structure.
- * @param pVM The VM handle (for getting the zero page address).
- * @param uType The page type (PGMPAGETYPE).
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ * @param a_pVM The VM handle (for getting the zero page address).
+ * @param a_uType The page type (PGMPAGETYPE).
*/
-#define PGM_PAGE_INIT_ZERO(pPage, pVM, uType) \
- PGM_PAGE_INIT((pPage), (pVM)->pgm.s.HCPhysZeroPg, NIL_GMM_PAGEID, (uType), PGM_PAGE_STATE_ZERO)
+#define PGM_PAGE_INIT_ZERO(a_pPage, a_pVM, a_uType) \
+ PGM_PAGE_INIT((a_pPage), (a_pVM)->pgm.s.HCPhysZeroPg, NIL_GMM_PAGEID, (a_uType), PGM_PAGE_STATE_ZERO)
/** @name The Page state, PGMPAGE::uStateY.
@@ -803,211 +805,263 @@ typedef PPGMPAGE *PPPGMPAGE;
/** @} */
+/** Asserts lock ownership in some of the PGM_PAGE_XXX macros. */
+#if defined(VBOX_STRICT) && 0 /** @todo triggers in pgmRZDynMapGCPageV2Inlined */
+# define PGM_PAGE_ASSERT_LOCK(a_pVM) PGM_LOCK_ASSERT_OWNER(a_pVM)
+#else
+# define PGM_PAGE_ASSERT_LOCK(a_pVM) do { } while (0)
+#endif
+
/**
* Gets the page state.
* @returns page state (PGM_PAGE_STATE_*).
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ *
+ * @remarks See PGM_PAGE_GET_HCPHYS_NA for remarks about GCC and strict
+ * builds.
*/
-#define PGM_PAGE_GET_STATE(pPage) ( (pPage)->uStateY )
+#define PGM_PAGE_GET_STATE_NA(a_pPage) ( (a_pPage)->s.uStateY )
+#if defined(__GNUC__) && defined(VBOX_STRICT)
+# define PGM_PAGE_GET_STATE(a_pPage) __extension__ ({ PGM_PAGE_ASSERT_LOCK(pVM); PGM_PAGE_GET_STATE_NA(a_pPage); })
+#else
+# define PGM_PAGE_GET_STATE PGM_PAGE_GET_STATE_NA
+#endif
/**
* Sets the page state.
- * @param pPage Pointer to the physical guest page tracking structure.
- * @param _uState The new page state.
+ * @param a_pVM The VM handle, only used for lock ownership assertions.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ * @param a_uState The new page state.
*/
-#define PGM_PAGE_SET_STATE(pPage, _uState) do { (pPage)->uStateY = (_uState); } while (0)
+#define PGM_PAGE_SET_STATE(a_pVM, a_pPage, a_uState) \
+ do { (a_pPage)->s.uStateY = (a_uState); PGM_PAGE_ASSERT_LOCK(a_pVM); } while (0)
/**
* Gets the host physical address of the guest page.
* @returns host physical address (RTHCPHYS).
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ *
+ * @remarks In strict builds on gcc platforms, this macro will make some ugly
+ * assumption about a valid pVM variable/parameter being in the
+ * current context. It will use this pVM variable to assert that the
+ * PGM lock is held. Use the PGM_PAGE_GET_HCPHYS_NA in contexts where
+ * pVM is not around.
*/
-#define PGM_PAGE_GET_HCPHYS(pPage) ( ((pPage)->HCPhysAndPageID >> 28) << 12 )
+#if 0
+# define PGM_PAGE_GET_HCPHYS_NA(a_pPage) ( (a_pPage)->s.HCPhysFN << 12 )
+# define PGM_PAGE_GET_HCPHYS PGM_PAGE_GET_HCPHYS_NA
+#else
+# define PGM_PAGE_GET_HCPHYS_NA(a_pPage) ( (a_pPage)->au64[0] & UINT64_C(0x0000fffffffff000) )
+# if defined(__GNUC__) && defined(VBOX_STRICT)
+# define PGM_PAGE_GET_HCPHYS(a_pPage) __extension__ ({ PGM_PAGE_ASSERT_LOCK(pVM); PGM_PAGE_GET_HCPHYS_NA(a_pPage); })
+# else
+# define PGM_PAGE_GET_HCPHYS PGM_PAGE_GET_HCPHYS_NA
+# endif
+#endif
/**
* Sets the host physical address of the guest page.
- * @param pPage Pointer to the physical guest page tracking structure.
- * @param _HCPhys The new host physical address.
+ *
+ * @param a_pVM The VM handle, only used for lock ownership assertions.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ * @param a_HCPhys The new host physical address.
*/
-#define PGM_PAGE_SET_HCPHYS(pPage, _HCPhys) \
+#define PGM_PAGE_SET_HCPHYS(a_pVM, a_pPage, a_HCPhys) \
do { \
- RTHCPHYS SetHCPhysTmp = (_HCPhys); \
+ RTHCPHYS const SetHCPhysTmp = (a_HCPhys); \
AssertFatal(!(SetHCPhysTmp & ~UINT64_C(0x0000fffffffff000))); \
- (pPage)->HCPhysAndPageID = ((pPage)->HCPhysAndPageID & UINT32_C(0x0fffffff)) \
- | (SetHCPhysTmp << (28-12)); \
+ (a_pPage)->s.HCPhysFN = SetHCPhysTmp >> 12; \
+ PGM_PAGE_ASSERT_LOCK(a_pVM); \
} while (0)
/**
* Get the Page ID.
* @returns The Page ID; NIL_GMM_PAGEID if it's a ZERO page.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_GET_PAGEID(pPage) ( (uint32_t)((pPage)->HCPhysAndPageID & UINT32_C(0x0fffffff)) )
+#define PGM_PAGE_GET_PAGEID(a_pPage) ( (uint32_t)(a_pPage)->s.idPage )
/**
* Sets the Page ID.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pVM The VM handle, only used for lock ownership assertions.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ * @param a_idPage The new page ID.
*/
-#define PGM_PAGE_SET_PAGEID(pPage, _idPage) \
+#define PGM_PAGE_SET_PAGEID(a_pVM, a_pPage, a_idPage) \
do { \
- (pPage)->HCPhysAndPageID = (((pPage)->HCPhysAndPageID) & UINT64_C(0xfffffffff0000000)) \
- | ((_idPage) & UINT32_C(0x0fffffff)); \
+ (a_pPage)->s.idPage = (a_idPage); \
+ PGM_PAGE_ASSERT_LOCK(a_pVM); \
} while (0)
/**
* Get the Chunk ID.
* @returns The Chunk ID; NIL_GMM_CHUNKID if it's a ZERO page.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_GET_CHUNKID(pPage) ( PGM_PAGE_GET_PAGEID(pPage) >> GMM_CHUNKID_SHIFT )
+#define PGM_PAGE_GET_CHUNKID(a_pPage) ( PGM_PAGE_GET_PAGEID(a_pPage) >> GMM_CHUNKID_SHIFT )
/**
* Get the index of the page within the allocation chunk.
* @returns The page index.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_GET_PAGE_IN_CHUNK(pPage) ( (uint32_t)((pPage)->HCPhysAndPageID & GMM_PAGEID_IDX_MASK) )
+#define PGM_PAGE_GET_PAGE_IN_CHUNK(a_pPage) ( PGM_PAGE_GET_PAGEID(a_pPage) & GMM_PAGEID_IDX_MASK )
/**
* Gets the page type.
* @returns The page type.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ *
+ * @remarks See PGM_PAGE_GET_HCPHYS_NA for remarks about GCC and strict
+ * builds.
*/
-#define PGM_PAGE_GET_TYPE(pPage) (pPage)->uTypeY
+#define PGM_PAGE_GET_TYPE_NA(a_pPage) ( (a_pPage)->s.uTypeY )
+#if defined(__GNUC__) && defined(VBOX_STRICT)
+# define PGM_PAGE_GET_TYPE(a_pPage) __extension__ ({ PGM_PAGE_ASSERT_LOCK(pVM); PGM_PAGE_GET_TYPE_NA(a_pPage); })
+#else
+# define PGM_PAGE_GET_TYPE PGM_PAGE_GET_TYPE_NA
+#endif
/**
* Sets the page type.
- * @param pPage Pointer to the physical guest page tracking structure.
- * @param _enmType The new page type (PGMPAGETYPE).
+ *
+ * @param a_pVM The VM handle, only used for lock ownership assertions.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ * @param a_enmType The new page type (PGMPAGETYPE).
*/
-#define PGM_PAGE_SET_TYPE(pPage, _enmType) do { (pPage)->uTypeY = (_enmType); } while (0)
+#define PGM_PAGE_SET_TYPE(a_pVM, a_pPage, a_enmType) \
+ do { (a_pPage)->s.uTypeY = (a_enmType); PGM_PAGE_ASSERT_LOCK(a_pVM); } while (0)
/**
* Gets the page table index
* @returns The page table index.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_GET_PTE_INDEX(pPage) (pPage)->uPteIdx
+#define PGM_PAGE_GET_PTE_INDEX(a_pPage) ( (a_pPage)->s.u10PteIdx )
/**
- * Sets the page table index
- * @param pPage Pointer to the physical guest page tracking structure.
- * @param iPte New page table index.
+ * Sets the page table index.
+ * @param a_pVM The VM handle, only used for lock ownership assertions.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ * @param a_iPte New page table index.
*/
-#define PGM_PAGE_SET_PTE_INDEX(pPage, _iPte) do { (pPage)->uPteIdx = (_iPte); } while (0)
+#define PGM_PAGE_SET_PTE_INDEX(a_pVM, a_pPage, a_iPte) \
+ do { (a_pPage)->s.u10PteIdx = (a_iPte); PGM_PAGE_ASSERT_LOCK(a_pVM); } while (0)
/**
* Checks if the page is marked for MMIO.
* @returns true/false.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_IS_MMIO(pPage) ( (pPage)->uTypeY == PGMPAGETYPE_MMIO )
+#define PGM_PAGE_IS_MMIO(a_pPage) ( (a_pPage)->s.uTypeY == PGMPAGETYPE_MMIO )
/**
* Checks if the page is backed by the ZERO page.
* @returns true/false.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_IS_ZERO(pPage) ( (pPage)->uStateY == PGM_PAGE_STATE_ZERO )
+#define PGM_PAGE_IS_ZERO(a_pPage) ( (a_pPage)->s.uStateY == PGM_PAGE_STATE_ZERO )
/**
* Checks if the page is backed by a SHARED page.
* @returns true/false.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_IS_SHARED(pPage) ( (pPage)->uStateY == PGM_PAGE_STATE_SHARED )
+#define PGM_PAGE_IS_SHARED(a_pPage) ( (a_pPage)->s.uStateY == PGM_PAGE_STATE_SHARED )
/**
* Checks if the page is ballooned.
* @returns true/false.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_IS_BALLOONED(pPage) ( (pPage)->uStateY == PGM_PAGE_STATE_BALLOONED )
+#define PGM_PAGE_IS_BALLOONED(a_pPage) ( (a_pPage)->s.uStateY == PGM_PAGE_STATE_BALLOONED )
/**
* Checks if the page is allocated.
* @returns true/false.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_IS_ALLOCATED(pPage) ( (pPage)->uStateY == PGM_PAGE_STATE_ALLOCATED )
+#define PGM_PAGE_IS_ALLOCATED(a_pPage) ( (a_pPage)->s.uStateY == PGM_PAGE_STATE_ALLOCATED )
/**
* Marks the page as written to (for GMM change monitoring).
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pVM The VM handle, only used for lock ownership assertions.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_SET_WRITTEN_TO(pPage) do { (pPage)->u16MiscY.au8[1] |= UINT8_C(0x80); } while (0)
+#define PGM_PAGE_SET_WRITTEN_TO(a_pVM, a_pPage) \
+ do { (a_pPage)->au8[1] |= UINT8_C(0x80); PGM_PAGE_ASSERT_LOCK(a_pVM); } while (0) /// FIXME FIXME
/**
* Clears the written-to indicator.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pVM The VM handle, only used for lock ownership assertions.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_CLEAR_WRITTEN_TO(pPage) do { (pPage)->u16MiscY.au8[1] &= UINT8_C(0x7f); } while (0)
+#define PGM_PAGE_CLEAR_WRITTEN_TO(a_pVM, a_pPage) \
+ do { (a_pPage)->s.fWrittenToY = 0; PGM_PAGE_ASSERT_LOCK(a_pVM); } while (0)
/**
* Checks if the page was marked as written-to.
* @returns true/false.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_IS_WRITTEN_TO(pPage) ( !!((pPage)->u16MiscY.au8[1] & UINT8_C(0x80)) )
+#define PGM_PAGE_IS_WRITTEN_TO(a_pPage) ( (a_pPage)->s.fWrittenToY )
/**
* Marks the page as dirty for FTM
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_SET_FT_DIRTY(pPage) do { (pPage)->u16MiscY.au8[1] |= UINT8_C(0x04); } while (0)
+#define PGM_PAGE_SET_FT_DIRTY(a_pPage) do { (a_pPage)->s.fFTDirtyY = 1; } while (0)
/**
* Clears the FTM dirty indicator
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_CLEAR_FT_DIRTY(pPage) do { (pPage)->u16MiscY.au8[1] &= UINT8_C(0xfb); } while (0)
+#define PGM_PAGE_CLEAR_FT_DIRTY(a_pPage) do { (a_pPage)->s.fFTDirtyY = 0; } while (0)
/**
* Checks if the page was marked as dirty for FTM
* @returns true/false.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_IS_FT_DIRTY(pPage) ( !!((pPage)->u16MiscY.au8[1] & UINT8_C(0x04)) )
+#define PGM_PAGE_IS_FT_DIRTY(a_pPage) ( (a_pPage)->s.fFTDirtyY )
/** @name PT usage values (PGMPAGE::u2PDEType).
*
* @{ */
/** Either as a PT or PDE. */
-#define PGM_PAGE_PDE_TYPE_DONTCARE 0
+#define PGM_PAGE_PDE_TYPE_DONTCARE 0
/** Must use a page table to map the range. */
-#define PGM_PAGE_PDE_TYPE_PT 1
+#define PGM_PAGE_PDE_TYPE_PT 1
/** Can use a page directory entry to map the continuous range. */
-#define PGM_PAGE_PDE_TYPE_PDE 2
+#define PGM_PAGE_PDE_TYPE_PDE 2
/** Can use a page directory entry to map the continuous range - temporarily disabled (by page monitoring). */
-#define PGM_PAGE_PDE_TYPE_PDE_DISABLED 3
+#define PGM_PAGE_PDE_TYPE_PDE_DISABLED 3
/** @} */
/**
* Set the PDE type of the page
- * @param pPage Pointer to the physical guest page tracking structure.
- * @param uType PGM_PAGE_PDE_TYPE_*
+ * @param a_pVM The VM handle, only used for lock ownership assertions.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ * @param a_uType PGM_PAGE_PDE_TYPE_*.
*/
-#define PGM_PAGE_SET_PDE_TYPE(pPage, uType) \
- do { \
- (pPage)->u16MiscY.au8[1] = ((pPage)->u16MiscY.au8[1] & UINT8_C(0x9f)) \
- | (((uType) & UINT8_C(0x03)) << 5); \
- } while (0)
+#define PGM_PAGE_SET_PDE_TYPE(a_pVM, a_pPage, a_uType) \
+ do { (a_pPage)->s.u2PDETypeY = (a_uType); PGM_PAGE_ASSERT_LOCK(a_pVM); } while (0)
/**
* Checks if the page was marked being part of a large page
* @returns true/false.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_GET_PDE_TYPE(pPage) ( ((pPage)->u16MiscY.au8[1] & UINT8_C(0x60)) >> 5)
+#define PGM_PAGE_GET_PDE_TYPE(a_pPage) ( (a_pPage)->s.u2PDETypeY )
/** Enabled optimized access handler tests.
- * These optimizations makes ASSUMPTIONS about the state values and the u16MiscY
+ * These optimizations makes ASSUMPTIONS about the state values and the s1
* layout. When enabled, the compiler should normally generate more compact
* code.
*/
-#define PGM_PAGE_WITH_OPTIMIZED_HANDLER_ACCESS 1
+#define PGM_PAGE_WITH_OPTIMIZED_HANDLER_ACCESS 1
/** @name Physical Access Handler State values (PGMPAGE::u2HandlerPhysStateY).
*
@@ -1015,46 +1069,45 @@ typedef PPGMPAGE *PPPGMPAGE;
* the correct state for a page with different handlers installed.
* @{ */
/** No handler installed. */
-#define PGM_PAGE_HNDL_PHYS_STATE_NONE 0
+#define PGM_PAGE_HNDL_PHYS_STATE_NONE 0
/** Monitoring is temporarily disabled. */
-#define PGM_PAGE_HNDL_PHYS_STATE_DISABLED 1
+#define PGM_PAGE_HNDL_PHYS_STATE_DISABLED 1
/** Write access is monitored. */
-#define PGM_PAGE_HNDL_PHYS_STATE_WRITE 2
+#define PGM_PAGE_HNDL_PHYS_STATE_WRITE 2
/** All access is monitored. */
-#define PGM_PAGE_HNDL_PHYS_STATE_ALL 3
+#define PGM_PAGE_HNDL_PHYS_STATE_ALL 3
/** @} */
/**
* Gets the physical access handler state of a page.
* @returns PGM_PAGE_HNDL_PHYS_STATE_* value.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) \
- ( (pPage)->u16MiscY.au8[0] )
+#define PGM_PAGE_GET_HNDL_PHYS_STATE(a_pPage) ( (a_pPage)->s.u2HandlerPhysStateY )
/**
* Sets the physical access handler state of a page.
- * @param pPage Pointer to the physical guest page tracking structure.
- * @param _uState The new state value.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ * @param a_uState The new state value.
*/
-#define PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, _uState) \
- do { (pPage)->u16MiscY.au8[0] = (_uState); } while (0)
+#define PGM_PAGE_SET_HNDL_PHYS_STATE(a_pPage, a_uState) \
+ do { (a_pPage)->s.u2HandlerPhysStateY = (a_uState); } while (0)
/**
* Checks if the page has any physical access handlers, including temporarily disabled ones.
* @returns true/false
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_HAS_ANY_PHYSICAL_HANDLERS(pPage) \
- ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) != PGM_PAGE_HNDL_PHYS_STATE_NONE )
+#define PGM_PAGE_HAS_ANY_PHYSICAL_HANDLERS(a_pPage) \
+ ( PGM_PAGE_GET_HNDL_PHYS_STATE(a_pPage) != PGM_PAGE_HNDL_PHYS_STATE_NONE )
/**
* Checks if the page has any active physical access handlers.
* @returns true/false
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_HAS_ACTIVE_PHYSICAL_HANDLERS(pPage) \
- ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) >= PGM_PAGE_HNDL_PHYS_STATE_WRITE )
+#define PGM_PAGE_HAS_ACTIVE_PHYSICAL_HANDLERS(a_pPage) \
+ ( PGM_PAGE_GET_HNDL_PHYS_STATE(a_pPage) >= PGM_PAGE_HNDL_PHYS_STATE_WRITE )
/** @name Virtual Access Handler State values (PGMPAGE::u2HandlerVirtStateY).
@@ -1063,160 +1116,167 @@ typedef PPGMPAGE *PPPGMPAGE;
* the correct state for a page with different handlers installed.
* @{ */
/** No handler installed. */
-#define PGM_PAGE_HNDL_VIRT_STATE_NONE 0
+#define PGM_PAGE_HNDL_VIRT_STATE_NONE 0
/* 1 is reserved so the lineup is identical with the physical ones. */
/** Write access is monitored. */
-#define PGM_PAGE_HNDL_VIRT_STATE_WRITE 2
+#define PGM_PAGE_HNDL_VIRT_STATE_WRITE 2
/** All access is monitored. */
-#define PGM_PAGE_HNDL_VIRT_STATE_ALL 3
+#define PGM_PAGE_HNDL_VIRT_STATE_ALL 3
/** @} */
/**
* Gets the virtual access handler state of a page.
* @returns PGM_PAGE_HNDL_VIRT_STATE_* value.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) ((uint8_t)( (pPage)->u16MiscY.au8[1] & UINT8_C(0x03) ))
+#define PGM_PAGE_GET_HNDL_VIRT_STATE(a_pPage) ( (a_pPage)->s.u2HandlerVirtStateY )
/**
* Sets the virtual access handler state of a page.
- * @param pPage Pointer to the physical guest page tracking structure.
- * @param _uState The new state value.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ * @param a_uState The new state value.
*/
-#define PGM_PAGE_SET_HNDL_VIRT_STATE(pPage, _uState) \
- do { \
- (pPage)->u16MiscY.au8[1] = ((pPage)->u16MiscY.au8[1] & UINT8_C(0xfc)) \
- | ((_uState) & UINT8_C(0x03)); \
- } while (0)
+#define PGM_PAGE_SET_HNDL_VIRT_STATE(a_pPage, a_uState) \
+ do { (a_pPage)->s.u2HandlerVirtStateY = (a_uState); } while (0)
/**
* Checks if the page has any virtual access handlers.
* @returns true/false
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_HAS_ANY_VIRTUAL_HANDLERS(pPage) \
- ( PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) != PGM_PAGE_HNDL_VIRT_STATE_NONE )
+#define PGM_PAGE_HAS_ANY_VIRTUAL_HANDLERS(a_pPage) \
+ ( PGM_PAGE_GET_HNDL_VIRT_STATE(a_pPage) != PGM_PAGE_HNDL_VIRT_STATE_NONE )
/**
* Same as PGM_PAGE_HAS_ANY_VIRTUAL_HANDLERS - can't disable pages in
* virtual handlers.
* @returns true/false
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_HAS_ACTIVE_VIRTUAL_HANDLERS(pPage) \
- PGM_PAGE_HAS_ANY_VIRTUAL_HANDLERS(pPage)
+#define PGM_PAGE_HAS_ACTIVE_VIRTUAL_HANDLERS(a_pPage) \
+ PGM_PAGE_HAS_ANY_VIRTUAL_HANDLERS(a_pPage)
/**
* Checks if the page has any access handlers, including temporarily disabled ones.
* @returns true/false
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
#ifdef PGM_PAGE_WITH_OPTIMIZED_HANDLER_ACCESS
-# define PGM_PAGE_HAS_ANY_HANDLERS(pPage) \
- ( ((pPage)->u16MiscY.u & UINT16_C(0x0303)) != 0 )
+# define PGM_PAGE_HAS_ANY_HANDLERS(a_pPage) \
+ ( ((a_pPage)->au32[0] & UINT16_C(0x0303)) != 0 )
#else
-# define PGM_PAGE_HAS_ANY_HANDLERS(pPage) \
- ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) != PGM_PAGE_HNDL_PHYS_STATE_NONE \
- || PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) != PGM_PAGE_HNDL_VIRT_STATE_NONE )
+# define PGM_PAGE_HAS_ANY_HANDLERS(a_pPage) \
+ ( PGM_PAGE_GET_HNDL_PHYS_STATE(a_pPage) != PGM_PAGE_HNDL_PHYS_STATE_NONE \
+ || PGM_PAGE_GET_HNDL_VIRT_STATE(a_pPage) != PGM_PAGE_HNDL_VIRT_STATE_NONE )
#endif
/**
* Checks if the page has any active access handlers.
* @returns true/false
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
#ifdef PGM_PAGE_WITH_OPTIMIZED_HANDLER_ACCESS
-# define PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage) \
- ( ((pPage)->u16MiscY.u & UINT16_C(0x0202)) != 0 )
+# define PGM_PAGE_HAS_ACTIVE_HANDLERS(a_pPage) \
+ ( ((a_pPage)->au32[0] & UINT16_C(0x0202)) != 0 )
#else
-# define PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage) \
- ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) >= PGM_PAGE_HNDL_PHYS_STATE_WRITE \
- || PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) >= PGM_PAGE_HNDL_VIRT_STATE_WRITE )
+# define PGM_PAGE_HAS_ACTIVE_HANDLERS(a_pPage) \
+ ( PGM_PAGE_GET_HNDL_PHYS_STATE(a_pPage) >= PGM_PAGE_HNDL_PHYS_STATE_WRITE \
+ || PGM_PAGE_GET_HNDL_VIRT_STATE(a_pPage) >= PGM_PAGE_HNDL_VIRT_STATE_WRITE )
#endif
/**
* Checks if the page has any active access handlers catching all accesses.
* @returns true/false
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
#ifdef PGM_PAGE_WITH_OPTIMIZED_HANDLER_ACCESS
-# define PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage) \
- ( ( ((pPage)->u16MiscY.au8[0] | (pPage)->u16MiscY.au8[1]) & UINT8_C(0x3) ) \
+# define PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(a_pPage) \
+ ( ( ((a_pPage)->au8[0] | (a_pPage)->au8[1]) & UINT8_C(0x3) ) \
== PGM_PAGE_HNDL_PHYS_STATE_ALL )
#else
-# define PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage) \
- ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) == PGM_PAGE_HNDL_PHYS_STATE_ALL \
- || PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) == PGM_PAGE_HNDL_VIRT_STATE_ALL )
+# define PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(a_pPage) \
+ ( PGM_PAGE_GET_HNDL_PHYS_STATE(a_pPage) == PGM_PAGE_HNDL_PHYS_STATE_ALL \
+ || PGM_PAGE_GET_HNDL_VIRT_STATE(a_pPage) == PGM_PAGE_HNDL_VIRT_STATE_ALL )
#endif
/** @def PGM_PAGE_GET_TRACKING
* Gets the packed shadow page pool tracking data associated with a guest page.
* @returns uint16_t containing the data.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_GET_TRACKING(pPage) ( (pPage)->u16TrackingY )
+#define PGM_PAGE_GET_TRACKING_NA(a_pPage) ( (a_pPage)->s.u16TrackingY )
+#if defined(__GNUC__) && defined(VBOX_STRICT)
+# define PGM_PAGE_GET_TRACKING(a_pPage) __extension__ ({ PGM_PAGE_ASSERT_LOCK(pVM); PGM_PAGE_GET_TRACKING_NA(a_pPage); })
+#else
+# define PGM_PAGE_GET_TRACKING PGM_PAGE_GET_TRACKING_NA
+#endif
/** @def PGM_PAGE_SET_TRACKING
* Sets the packed shadow page pool tracking data associated with a guest page.
- * @param pPage Pointer to the physical guest page tracking structure.
- * @param u16TrackingData The tracking data to store.
+ * @param a_pVM The VM handle, only used for lock ownership assertions.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
+ * @param a_u16TrackingData The tracking data to store.
*/
-#define PGM_PAGE_SET_TRACKING(pPage, u16TrackingData) \
- do { (pPage)->u16TrackingY = (u16TrackingData); } while (0)
+#define PGM_PAGE_SET_TRACKING(a_pVM, a_pPage, a_u16TrackingData) \
+ do { (a_pPage)->s.u16TrackingY = (a_u16TrackingData); PGM_PAGE_ASSERT_LOCK(a_pVM); } while (0)
/** @def PGM_PAGE_GET_TD_CREFS
* Gets the @a cRefs tracking data member.
* @returns cRefs.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_GET_TD_CREFS(pPage) \
- ((PGM_PAGE_GET_TRACKING(pPage) >> PGMPOOL_TD_CREFS_SHIFT) & PGMPOOL_TD_CREFS_MASK)
+#define PGM_PAGE_GET_TD_CREFS(a_pPage) \
+ ((PGM_PAGE_GET_TRACKING(a_pPage) >> PGMPOOL_TD_CREFS_SHIFT) & PGMPOOL_TD_CREFS_MASK)
+#define PGM_PAGE_GET_TD_CREFS_NA(a_pPage) \
+ ((PGM_PAGE_GET_TRACKING_NA(a_pPage) >> PGMPOOL_TD_CREFS_SHIFT) & PGMPOOL_TD_CREFS_MASK)
/** @def PGM_PAGE_GET_TD_IDX
* Gets the @a idx tracking data member.
* @returns idx.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_GET_TD_IDX(pPage) \
- ((PGM_PAGE_GET_TRACKING(pPage) >> PGMPOOL_TD_IDX_SHIFT) & PGMPOOL_TD_IDX_MASK)
+#define PGM_PAGE_GET_TD_IDX(a_pPage) \
+ ((PGM_PAGE_GET_TRACKING(a_pPage) >> PGMPOOL_TD_IDX_SHIFT) & PGMPOOL_TD_IDX_MASK)
+#define PGM_PAGE_GET_TD_IDX_NA(a_pPage) \
+ ((PGM_PAGE_GET_TRACKING_NA(a_pPage) >> PGMPOOL_TD_IDX_SHIFT) & PGMPOOL_TD_IDX_MASK)
/** Max number of locks on a page. */
-#define PGM_PAGE_MAX_LOCKS UINT8_C(254)
+#define PGM_PAGE_MAX_LOCKS UINT8_C(254)
/** Get the read lock count.
* @returns count.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_GET_READ_LOCKS(pPage) ( (pPage)->cReadLocksY )
+#define PGM_PAGE_GET_READ_LOCKS(a_pPage) ( (a_pPage)->s.cReadLocksY )
/** Get the write lock count.
* @returns count.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_GET_WRITE_LOCKS(pPage) ( (pPage)->cWriteLocksY )
+#define PGM_PAGE_GET_WRITE_LOCKS(a_pPage) ( (a_pPage)->s.cWriteLocksY )
/** Decrement the read lock counter.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_DEC_READ_LOCKS(pPage) do { --(pPage)->cReadLocksY; } while (0)
+#define PGM_PAGE_DEC_READ_LOCKS(a_pPage) do { --(a_pPage)->s.cReadLocksY; } while (0)
/** Decrement the write lock counter.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_DEC_WRITE_LOCKS(pPage) do { --(pPage)->cWriteLocksY; } while (0)
+#define PGM_PAGE_DEC_WRITE_LOCKS(a_pPage) do { --(a_pPage)->s.cWriteLocksY; } while (0)
/** Increment the read lock counter.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_INC_READ_LOCKS(pPage) do { ++(pPage)->cReadLocksY; } while (0)
+#define PGM_PAGE_INC_READ_LOCKS(a_pPage) do { ++(a_pPage)->s.cReadLocksY; } while (0)
/** Increment the write lock counter.
- * @param pPage Pointer to the physical guest page tracking structure.
+ * @param a_pPage Pointer to the physical guest page tracking structure.
*/
-#define PGM_PAGE_INC_WRITE_LOCKS(pPage) do { ++(pPage)->cWriteLocksY; } while (0)
+#define PGM_PAGE_INC_WRITE_LOCKS(a_pPage) do { ++(a_pPage)->s.cWriteLocksY; } while (0)
#if 0
@@ -1266,7 +1326,7 @@ typedef PGMLIVESAVERAMPAGE *PPGMLIVESAVERAMPAGE;
/**
- * Ram range for GC Phys to HC Phys conversion.
+ * RAM range for GC Phys to HC Phys conversion.
*
* Can be used for HC Virt to GC Phys and HC Virt to HC Phys
* conversions too, but we'll let MM handle that for now.
@@ -1299,12 +1359,30 @@ typedef struct PGMRAMRANGE
R0PTRTYPE(struct PGMRAMRANGE *) pSelfR0;
/** Pointer to self - RC pointer. */
RCPTRTYPE(struct PGMRAMRANGE *) pSelfRC;
+
+ /** Alignment padding. */
+ RTRCPTR Alignment0;
+ /** Pointer to the left search three node - ring-3 context. */
+ R3PTRTYPE(struct PGMRAMRANGE *) pLeftR3;
+ /** Pointer to the right search three node - ring-3 context. */
+ R3PTRTYPE(struct PGMRAMRANGE *) pRightR3;
+ /** Pointer to the left search three node - ring-0 context. */
+ R0PTRTYPE(struct PGMRAMRANGE *) pLeftR0;
+ /** Pointer to the right search three node - ring-0 context. */
+ R0PTRTYPE(struct PGMRAMRANGE *) pRightR0;
+ /** Pointer to the left search three node - raw-mode context. */
+ RCPTRTYPE(struct PGMRAMRANGE *) pLeftRC;
+ /** Pointer to the right search three node - raw-mode context. */
+ RCPTRTYPE(struct PGMRAMRANGE *) pRightRC;
+
/** Padding to make aPage aligned on sizeof(PGMPAGE). */
- uint32_t au32Alignment2[HC_ARCH_BITS == 32 ? 1 : 3];
+#if HC_ARCH_BITS == 32
+ uint32_t au32Alignment2[HC_ARCH_BITS == 32 ? 2 : 0];
+#endif
/** Array of physical guest page tracking structures. */
PGMPAGE aPages[1];
} PGMRAMRANGE;
-/** Pointer to Ram range for GC Phys to HC Phys conversion. */
+/** Pointer to RAM range for GC Phys to HC Phys conversion. */
typedef PGMRAMRANGE *PPGMRAMRANGE;
/** @name PGMRAMRANGE::fFlags
@@ -1326,6 +1404,19 @@ typedef PGMRAMRANGE *PPGMRAMRANGE;
#define PGM_RAM_RANGE_IS_AD_HOC(pRam) \
(!!( (pRam)->fFlags & (PGM_RAM_RANGE_FLAGS_AD_HOC_ROM | PGM_RAM_RANGE_FLAGS_AD_HOC_MMIO | PGM_RAM_RANGE_FLAGS_AD_HOC_MMIO2) ) )
+/** The number of entries in the RAM range TLBs (there is one for each
+ * context). Must be a power of two. */
+#define PGM_RAMRANGE_TLB_ENTRIES 8
+
+/**
+ * Calculates the RAM range TLB index for the physical address.
+ *
+ * @returns RAM range TLB index.
+ * @param GCPhys The guest physical address.
+ */
+#define PGM_RAMRANGE_TLB_IDX(a_GCPhys) ( ((a_GCPhys) >> 20) & (PGM_RAMRANGE_TLB_ENTRIES - 1) )
+
+
/**
* Per page tracking structure for ROM image.
@@ -2333,24 +2424,24 @@ AssertCompileMemberAlignment(PGMPOOL, aPages, 8);
* Maps a pool page pool into the current context.
*
* @returns VBox status code.
- * @param pVM The VM handle.
- * @param pPage The pool page.
+ * @param a_pVM The VM handle.
+ * @param a_pPage The pool page.
*
* @remark In RC this uses PGMGCDynMapHCPage(), so it will consume of the
* small page window employeed by that function. Be careful.
* @remark There is no need to assert on the result.
*/
#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
-# define PGMPOOL_PAGE_2_PTR(pVM, pPage) pgmPoolMapPageInlined((pVM), (pPage) RTLOG_COMMA_SRC_POS)
+# define PGMPOOL_PAGE_2_PTR(a_pVM, a_pPage) pgmPoolMapPageInlined((a_pVM), (a_pPage) RTLOG_COMMA_SRC_POS)
#elif defined(VBOX_STRICT)
-# define PGMPOOL_PAGE_2_PTR(pVM, pPage) pgmPoolMapPageStrict(pPage)
-DECLINLINE(void *) pgmPoolMapPageStrict(PPGMPOOLPAGE pPage)
+# define PGMPOOL_PAGE_2_PTR(a_pVM, a_pPage) pgmPoolMapPageStrict(a_pPage)
+DECLINLINE(void *) pgmPoolMapPageStrict(PPGMPOOLPAGE a_pPage)
{
- Assert(pPage && pPage->pvPageR3);
- return pPage->pvPageR3;
+ Assert(a_pPage && a_pPage->pvPageR3);
+ return a_pPage->pvPageR3;
}
#else
-# define PGMPOOL_PAGE_2_PTR(pVM, pPage) ((pPage)->pvPageR3)
+# define PGMPOOL_PAGE_2_PTR(pVM, a_pPage) ((a_pPage)->pvPageR3)
#endif
@@ -2358,18 +2449,18 @@ DECLINLINE(void *) pgmPoolMapPageStrict(PPGMPOOLPAGE pPage)
* Maps a pool page pool into the current context, taking both VM and VMCPU.
*
* @returns VBox status code.
- * @param pVM The VM handle.
- * @param pVCpu The current CPU.
- * @param pPage The pool page.
+ * @param a_pVM The VM handle.
+ * @param a_pVCpu The current CPU.
+ * @param a_pPage The pool page.
*
* @remark In RC this uses PGMGCDynMapHCPage(), so it will consume of the
* small page window employeed by that function. Be careful.
* @remark There is no need to assert on the result.
*/
#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
-# define PGMPOOL_PAGE_2_PTR_V2(pVM, pVCpu, pPage) pgmPoolMapPageV2Inlined((pVM), (pVCpu), (pPage) RTLOG_COMMA_SRC_POS)
+# define PGMPOOL_PAGE_2_PTR_V2(a_pVM, a_pVCpu, a_pPage) pgmPoolMapPageV2Inlined((a_pVM), (a_pVCpu), (a_pPage) RTLOG_COMMA_SRC_POS)
#else
-# define PGMPOOL_PAGE_2_PTR_V2(pVM, pVCpu, pPage) PGMPOOL_PAGE_2_PTR((pVM), (pPage))
+# define PGMPOOL_PAGE_2_PTR_V2(a_pVM, a_pVCpu, a_pPage) PGMPOOL_PAGE_2_PTR((a_pVM), (a_pPage))
#endif
@@ -2791,6 +2882,10 @@ typedef struct PGMSTATS
STAMCOUNTER StatR3ChunkR3MapTlbMisses; /**< R3: Ring-3/0 chunk mapper TLB misses. */
STAMCOUNTER StatR3PageMapTlbHits; /**< R3: Ring-3/0 page mapper TLB hits. */
STAMCOUNTER StatR3PageMapTlbMisses; /**< R3: Ring-3/0 page mapper TLB misses. */
+ STAMCOUNTER StatRZRamRangeTlbHits; /**< RC/R0: RAM range TLB hits. */
+ STAMCOUNTER StatRZRamRangeTlbMisses; /**< RC/R0: RAM range TLB misses. */
+ STAMCOUNTER StatR3RamRangeTlbHits; /**< R3: RAM range TLB hits. */
+ STAMCOUNTER StatR3RamRangeTlbMisses; /**< R3: RAM range TLB misses. */
STAMPROFILE StatRZSyncCR3HandlerVirtualReset; /**< RC/R0: Profiling of the virtual handler resets. */
STAMPROFILE StatRZSyncCR3HandlerVirtualUpdate; /**< RC/R0: Profiling of the virtual handler updates. */
STAMPROFILE StatR3SyncCR3HandlerVirtualReset; /**< R3: Profiling of the virtual handler resets. */
@@ -2907,8 +3002,10 @@ typedef struct PGM
/** We're not in a state which permits writes to guest memory.
* (Only used in strict builds.) */
bool fNoMorePhysWrites;
+ /** Set if PCI passthrough is enabled. */
+ bool fPciPassthrough;
/** Alignment padding that makes the next member start on a 8 byte boundary. */
- bool afAlignment1[3];
+ bool afAlignment1[2];
/** Indicates that PGMR3FinalizeMappings has been called and that further
* PGMR3MapIntermediate calls will be rejected. */
@@ -2941,9 +3038,13 @@ typedef struct PGM
RTGCPHYS GCPhysInvAddrMask;
+ /** RAM range TLB for R3. */
+ R3PTRTYPE(PPGMRAMRANGE) apRamRangesTlbR3[PGM_RAMRANGE_TLB_ENTRIES];
/** Pointer to the list of RAM ranges (Phys GC -> Phys HC conversion) - for R3.
* This is sorted by physical address and contains no overlapping ranges. */
- R3PTRTYPE(PPGMRAMRANGE) pRamRangesR3;
+ R3PTRTYPE(PPGMRAMRANGE) pRamRangesXR3;
+ /** Root of the RAM range search tree for ring-3. */
+ R3PTRTYPE(PPGMRAMRANGE) pRamRangeTreeR3;
/** PGM offset based trees - R3 Ptr. */
R3PTRTYPE(PPGMTREES) pTreesR3;
/** Caching the last physical handler we looked up in R3. */
@@ -2962,11 +3063,14 @@ typedef struct PGM
/** Pointer to SHW+GST mode data (function pointers).
* The index into this table is made up from */
R3PTRTYPE(PPGMMODEDATA) paModeData;
- /*RTR3PTR R3PtrAlignment0;*/
-
-
- /** R0 pointer corresponding to PGM::pRamRangesR3. */
- R0PTRTYPE(PPGMRAMRANGE) pRamRangesR0;
+ RTR3PTR R3PtrAlignment0;
+
+ /** RAM range TLB for R0. */
+ R0PTRTYPE(PPGMRAMRANGE) apRamRangesTlbR0[PGM_RAMRANGE_TLB_ENTRIES];
+ /** R0 pointer corresponding to PGM::pRamRangesXR3. */
+ R0PTRTYPE(PPGMRAMRANGE) pRamRangesXR0;
+ /** Root of the RAM range search tree for ring-0. */
+ R0PTRTYPE(PPGMRAMRANGE) pRamRangeTreeR0;
/** PGM offset based trees - R0 Ptr. */
R0PTRTYPE(PPGMTREES) pTreesR0;
/** Caching the last physical handler we looked up in R0. */
@@ -2978,11 +3082,15 @@ typedef struct PGM
R0PTRTYPE(PPGMMAPPING) pMappingsR0;
/** R0 pointer corresponding to PGM::pRomRangesR3. */
R0PTRTYPE(PPGMROMRANGE) pRomRangesR0;
- /*RTR0PTR R0PtrAlignment0;*/
+ RTR0PTR R0PtrAlignment0;
- /** RC pointer corresponding to PGM::pRamRangesR3. */
- RCPTRTYPE(PPGMRAMRANGE) pRamRangesRC;
+ /** RAM range TLB for RC. */
+ RCPTRTYPE(PPGMRAMRANGE) apRamRangesTlbRC[PGM_RAMRANGE_TLB_ENTRIES];
+ /** RC pointer corresponding to PGM::pRamRangesXR3. */
+ RCPTRTYPE(PPGMRAMRANGE) pRamRangesXRC;
+ /** Root of the RAM range search tree for raw-mode context. */
+ RCPTRTYPE(PPGMRAMRANGE) pRamRangeTreeRC;
/** PGM offset based trees - RC Ptr. */
RCPTRTYPE(PPGMTREES) pTreesRC;
/** Caching the last physical handler we looked up in RC. */
@@ -2994,7 +3102,7 @@ typedef struct PGM
RCPTRTYPE(PPGMMAPPING) pMappingsRC;
/** RC pointer corresponding to PGM::pRomRangesR3. */
RCPTRTYPE(PPGMROMRANGE) pRomRangesRC;
- /*RTRCPTR RCPtrAlignment0;*/
+ RTRCPTR RCPtrAlignment0;
/** Pointer to the page table entries for the dynamic page mapping area - GCPtr. */
RCPTRTYPE(PX86PTE) paDynPageMap32BitPTEsGC;
/** Pointer to the page table entries for the dynamic page mapping area - GCPtr. */
@@ -3744,6 +3852,12 @@ RT_C_DECLS_BEGIN
int pgmLock(PVM pVM);
void pgmUnlock(PVM pVM);
+/**
+ * Asserts that the caller owns the PDM lock.
+ * This is the internal variant of PGMIsLockOwner.
+ * @param a_pVM The VM handle.
+ */
+#define PGM_LOCK_ASSERT_OWNER(a_pVM) Assert(PDMCritSectIsOwner(&(a_pVM)->pgm.s.CritSect))
int pgmR3MappingsFixInternal(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb);
int pgmR3SyncPTResolveConflict(PVM pVM, PPGMMAPPING pMapping, PX86PD pPDSrc, RTGCPTR GCPtrOldMapping);
@@ -3768,8 +3882,8 @@ int pgmR3InitSavedState(PVM pVM, uint64_t cbRam);
int pgmPhysAllocPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys);
int pgmPhysAllocLargePage(PVM pVM, RTGCPHYS GCPhys);
int pgmPhysRecheckLargePage(PVM pVM, RTGCPHYS GCPhys, PPGMPAGE pLargePage);
-int pgmPhysPageLoadIntoTlb(PPGM pPGM, RTGCPHYS GCPhys);
-int pgmPhysPageLoadIntoTlbWithPage(PPGM pPGM, PPGMPAGE pPage, RTGCPHYS GCPhys);
+int pgmPhysPageLoadIntoTlb(PVM pVM, RTGCPHYS GCPhys);
+int pgmPhysPageLoadIntoTlbWithPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys);
void pgmPhysPageMakeWriteMonitoredWritable(PVM pVM, PPGMPAGE pPage);
int pgmPhysPageMakeWritable(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys);
int pgmPhysPageMakeWritableAndMap(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void **ppv);
@@ -3781,6 +3895,14 @@ int pgmPhysGCPhys2CCPtrInternalReadOnly(PVM pVM, PPGMPAGE pPage, RTG
VMMDECL(int) pgmPhysHandlerRedirectToHC(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
VMMDECL(int) pgmPhysRomWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys);
+void pgmPhysInvalidRamRangeTlbs(PVM pVM);
+void pgmPhysInvalidatePageMapTLB(PVM pVM);
+void pgmPhysInvalidatePageMapTLBEntry(PVM pVM, RTGCPHYS GCPhys);
+PPGMRAMRANGE pgmPhysGetRangeSlow(PVM pVM, RTGCPHYS GCPhys);
+PPGMRAMRANGE pgmPhysGetRangeAtOrAboveSlow(PVM pVM, RTGCPHYS GCPhys);
+PPGMPAGE pgmPhysGetPageSlow(PVM pVM, RTGCPHYS GCPhys);
+int pgmPhysGetPageExSlow(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage);
+int pgmPhysGetPageAndRangeExSlow(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRam);
#ifdef IN_RING3
void pgmR3PhysRelinkRamRanges(PVM pVM);
@@ -3856,8 +3978,8 @@ int pgmGstLazyMapPaePD(PVMCPU pVCpu, uint32_t iPdpt, PX86PDPAE *ppPd
int pgmGstLazyMapPml4(PVMCPU pVCpu, PX86PML4 *ppPml4);
# if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
-DECLCALLBACK(int) pgmR3CmdCheckDuplicatePages(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
-DECLCALLBACK(int) pgmR3CmdShowSharedModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
+DECLCALLBACK(int) pgmR3CmdCheckDuplicatePages(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+DECLCALLBACK(int) pgmR3CmdShowSharedModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
# endif
RT_C_DECLS_END
diff --git a/src/VBox/VMM/include/REMInternal.h b/src/VBox/VMM/include/REMInternal.h
index 0f4e6859a..edc9c83fe 100644
--- a/src/VBox/VMM/include/REMInternal.h
+++ b/src/VBox/VMM/include/REMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: REMInternal.h $ */
+/* $Id: REMInternal.h 37702 2011-06-30 10:09:59Z vboxsync $ */
/** @file
* REM - Internal header file.
*/
@@ -237,7 +237,6 @@ void remR3CSAMCheckEIP(CPUState *env, RTGCPTR GCPtrCode);
bool remR3GetOpcode(CPUState *env, RTGCPTR GCPtrInstr, uint8_t *pu8Byte);
bool remR3DisasInstr(CPUState *env, int f32BitCode, char *pszPrefix);
void remR3FlushPage(CPUState *env, RTGCPTR GCPtr);
-void remR3SetPage(CPUState *env, CPUTLBEntry *pRead, CPUTLBEntry *pWrite, int prot, int is_user);
void remR3FlushTLB(CPUState *env, bool fGlobal);
void remR3ProtectCode(CPUState *env, RTGCPTR GCPtr);
void remR3ChangeCpuMode(CPUState *env);
@@ -245,7 +244,6 @@ void remR3DmaRun(CPUState *env);
void remR3TimersRun(CPUState *env);
int remR3NotifyTrap(CPUState *env, uint32_t uTrap, uint32_t uErrorCode, RTGCPTR pvNextEIP);
void remR3TrapStat(CPUState *env, uint32_t uTrap);
-void remR3CpuId(CPUState *env, unsigned uOperator, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX);
void remR3RecordCall(CPUState *env);
#endif /* REM_INCLUDE_CPU_H */
void remR3TrapClear(PVM pVM);
diff --git a/src/VBox/VMM/include/SELMInternal.h b/src/VBox/VMM/include/SELMInternal.h
index fd97c24fb..150cfac59 100644
--- a/src/VBox/VMM/include/SELMInternal.h
+++ b/src/VBox/VMM/include/SELMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: SELMInternal.h $ */
+/* $Id: SELMInternal.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* SELM - Internal header file.
*/
diff --git a/src/VBox/VMM/include/SSMInternal.h b/src/VBox/VMM/include/SSMInternal.h
index d1f8752ad..d00e6ff7e 100644
--- a/src/VBox/VMM/include/SSMInternal.h
+++ b/src/VBox/VMM/include/SSMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: SSMInternal.h $ */
+/* $Id: SSMInternal.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* SSM - Internal header file.
*/
diff --git a/src/VBox/VMM/include/STAMInternal.h b/src/VBox/VMM/include/STAMInternal.h
index eeae65724..8db31b338 100644
--- a/src/VBox/VMM/include/STAMInternal.h
+++ b/src/VBox/VMM/include/STAMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: STAMInternal.h $ */
+/* $Id: STAMInternal.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* STAM Internal Header.
*/
diff --git a/src/VBox/VMM/include/TMInline.h b/src/VBox/VMM/include/TMInline.h
new file mode 100644
index 000000000..82f69031a
--- /dev/null
+++ b/src/VBox/VMM/include/TMInline.h
@@ -0,0 +1,56 @@
+/* $Id: TMInline.h 37517 2011-06-16 19:24:00Z vboxsync $ */
+/** @file
+ * TM - Common Inlined functions.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef ___TMInline_h
+#define ___TMInline_h
+
+
+/**
+ * Used to unlink a timer from the active list.
+ *
+ * @param pQueue The timer queue.
+ * @param pTimer The timer that needs linking.
+ *
+ * @remarks Called while owning the relevant queue lock.
+ */
+DECL_FORCE_INLINE(void) tmTimerQueueUnlinkActive(PTMTIMERQUEUE pQueue, PTMTIMER pTimer)
+{
+#ifdef VBOX_STRICT
+ TMTIMERSTATE const enmState = pTimer->enmState;
+ Assert( pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC
+ ? enmState == TMTIMERSTATE_ACTIVE
+ : enmState == TMTIMERSTATE_PENDING_SCHEDULE || enmState == TMTIMERSTATE_PENDING_STOP_SCHEDULE);
+#endif
+
+ const PTMTIMER pPrev = TMTIMER_GET_PREV(pTimer);
+ const PTMTIMER pNext = TMTIMER_GET_NEXT(pTimer);
+ if (pPrev)
+ TMTIMER_SET_NEXT(pPrev, pNext);
+ else
+ {
+ TMTIMER_SET_HEAD(pQueue, pNext);
+ pQueue->u64Expire = pNext ? pNext->u64Expire : INT64_MAX;
+ DBGFTRACE_U64_TAG(pTimer->CTX_SUFF(pVM), pQueue->u64Expire, "tmTimerQueueUnlinkActive");
+ }
+ if (pNext)
+ TMTIMER_SET_PREV(pNext, pPrev);
+ pTimer->offNext = 0;
+ pTimer->offPrev = 0;
+}
+
+#endif
+
diff --git a/src/VBox/VMM/include/TMInternal.h b/src/VBox/VMM/include/TMInternal.h
index 30434a694..27d88003e 100644
--- a/src/VBox/VMM/include/TMInternal.h
+++ b/src/VBox/VMM/include/TMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: TMInternal.h $ */
+/* $Id: TMInternal.h 37527 2011-06-17 10:18:02Z vboxsync $ */
/** @file
* TM - Internal header file.
*/
@@ -399,7 +399,9 @@ typedef struct TM
RCPTRTYPE(PFNTIMENANOTSINTERNAL) pfnVirtualGetRawRC;
/** Alignment. */
RTRCPTR AlignmentRCPtr;
- /** The guest virtual timer synchronous time when fVirtualSyncTicking is cleared. */
+ /** The guest virtual timer synchronous time when fVirtualSyncTicking is cleared.
+ * When fVirtualSyncTicking is set it holds the last time returned to
+ * the guest (while the lock was held). */
uint64_t volatile u64VirtualSync;
/** The offset of the timer synchronous virtual clock (TMCLOCK_VIRTUAL_SYNC) relative
* to the virtual clock (TMCLOCK_VIRTUAL).
@@ -504,7 +506,8 @@ typedef struct TM
/** Lock serializing access to the timer lists. */
PDMCRITSECT TimerCritSect;
- /** Lock serializing access to the VirtualSync clock. */
+ /** Lock serializing access to the VirtualSync clock and the associated
+ * timer queue. */
PDMCRITSECT VirtualSyncLock;
/** CPU load state for all the virtual CPUs (tmR3CpuLoadTimer). */
@@ -528,6 +531,7 @@ typedef struct TM
STAMCOUNTER StatVirtualGet;
STAMCOUNTER StatVirtualGetSetFF;
STAMCOUNTER StatVirtualSyncGet;
+ STAMCOUNTER StatVirtualSyncGetAdjLast;
STAMCOUNTER StatVirtualSyncGetELoop;
STAMCOUNTER StatVirtualSyncGetExpired;
STAMCOUNTER StatVirtualSyncGetLockless;
@@ -535,7 +539,7 @@ typedef struct TM
STAMCOUNTER StatVirtualSyncGetSetFF;
STAMCOUNTER StatVirtualPause;
STAMCOUNTER StatVirtualResume;
- /* @} */
+ /** @} */
/** TMTimerPoll
* @{ */
STAMCOUNTER StatPoll;
@@ -547,7 +551,7 @@ typedef struct TM
STAMCOUNTER StatPollVirtual;
STAMCOUNTER StatPollVirtualSync;
/** @} */
- /** TMTimerSet
+ /** TMTimerSet sans virtual sync timers.
* @{ */
STAMCOUNTER StatTimerSet;
STAMCOUNTER StatTimerSetOpt;
@@ -561,14 +565,22 @@ typedef struct TM
STAMCOUNTER StatTimerSetStPendSched;
STAMCOUNTER StatTimerSetStPendResched;
STAMCOUNTER StatTimerSetStOther;
+ /** @} */
+ /** TMTimerSet on virtual sync timers.
+ * @{ */
+ STAMCOUNTER StatTimerSetVs;
+ STAMPROFILE StatTimerSetVsRZ;
+ STAMPROFILE StatTimerSetVsR3;
+ STAMCOUNTER StatTimerSetVsStStopped;
+ STAMCOUNTER StatTimerSetVsStExpDeliver;
+ STAMCOUNTER StatTimerSetVsStActive;
/** @} */
- /** TMTimerSetRelative
+ /** TMTimerSetRelative sans virtual sync timers
* @{ */
STAMCOUNTER StatTimerSetRelative;
STAMPROFILE StatTimerSetRelativeRZ;
STAMPROFILE StatTimerSetRelativeR3;
STAMCOUNTER StatTimerSetRelativeOpt;
- STAMCOUNTER StatTimerSetRelativeRacyVirtSync;
STAMCOUNTER StatTimerSetRelativeStStopped;
STAMCOUNTER StatTimerSetRelativeStExpDeliver;
STAMCOUNTER StatTimerSetRelativeStActive;
@@ -578,11 +590,25 @@ typedef struct TM
STAMCOUNTER StatTimerSetRelativeStPendResched;
STAMCOUNTER StatTimerSetRelativeStOther;
/** @} */
- /** TMTimerStop
+ /** TMTimerSetRelative on virtual sync timers.
+ * @{ */
+ STAMCOUNTER StatTimerSetRelativeVs;
+ STAMPROFILE StatTimerSetRelativeVsRZ;
+ STAMPROFILE StatTimerSetRelativeVsR3;
+ STAMCOUNTER StatTimerSetRelativeVsStStopped;
+ STAMCOUNTER StatTimerSetRelativeVsStExpDeliver;
+ STAMCOUNTER StatTimerSetRelativeVsStActive;
+ /** @} */
+ /** TMTimerStop sans virtual sync.
* @{ */
STAMPROFILE StatTimerStopRZ;
STAMPROFILE StatTimerStopR3;
/** @} */
+ /** TMTimerStop on virtual sync timers.
+ * @{ */
+ STAMPROFILE StatTimerStopVsRZ;
+ STAMPROFILE StatTimerStopVsR3;
+ /** @} */
/** VirtualSync - Running and Catching Up
* @{ */
STAMCOUNTER StatVirtualSyncRun;
@@ -695,25 +721,6 @@ typedef struct TMCPU
/** Pointer to TM VMCPU instance data. */
typedef TMCPU *PTMCPU;
-#if 0 /* enable this to rule out locking bugs on single cpu guests. */
-# define tmTimerLock(pVM) VINF_SUCCESS
-# define tmTimerTryLock(pVM) VINF_SUCCESS
-# define tmTimerUnlock(pVM) ((void)0)
-# define tmVirtualSyncLock(pVM) VINF_SUCCESS
-# define tmVirtualSyncTryLock(pVM) VINF_SUCCESS
-# define tmVirtualSyncUnlock(pVM) ((void)0)
-# define TM_ASSERT_LOCK(pVM) VM_ASSERT_EMT(pVM)
-#else
-int tmTimerLock(PVM pVM);
-int tmTimerTryLock(PVM pVM);
-void tmTimerUnlock(PVM pVM);
-/** Checks that the caller owns the timer lock. */
-#define TM_ASSERT_LOCK(pVM) Assert(PDMCritSectIsOwner(&pVM->tm.s.TimerCritSect))
-int tmVirtualSyncLock(PVM pVM);
-int tmVirtualSyncTryLock(PVM pVM);
-void tmVirtualSyncUnlock(PVM pVM);
-#endif
-
const char *tmTimerState(TMTIMERSTATE enmState);
void tmTimerQueueSchedule(PVM pVM, PTMTIMERQUEUE pQueue);
#ifdef VBOX_STRICT
@@ -729,6 +736,38 @@ DECLEXPORT(void) tmVirtualNanoTSBad(PRTTIMENANOTSDATA pData, uint64_t u64
DECLEXPORT(uint64_t) tmVirtualNanoTSRediscover(PRTTIMENANOTSDATA pData);
+/**
+ * Try take the timer lock, wait in ring-3 return VERR_SEM_BUSY in R0/RC.
+ *
+ * @retval VINF_SUCCESS on success (always in ring-3).
+ * @retval VERR_SEM_BUSY in RC and R0 if the semaphore is busy.
+ *
+ * @param a_pVM The VM handle.
+ *
+ * @remarks The virtual sync timer queue requires the virtual sync lock.
+ */
+#define TM_LOCK_TIMERS(a_pVM) PDMCritSectEnter(&(a_pVM)->tm.s.TimerCritSect, VERR_SEM_BUSY)
+
+/**
+ * Try take the timer lock, no waiting.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_BUSY if busy.
+ *
+ * @param a_pVM The VM handle.
+ *
+ * @remarks The virtual sync timer queue requires the virtual sync lock.
+ */
+#define TM_TRY_LOCK_TIMERS(a_pVM) PDMCritSectTryEnter(&(a_pVM)->tm.s.TimerCritSect)
+
+/** Lock the timers (sans the virtual sync queue). */
+#define TM_UNLOCK_TIMERS(a_pVM) do { PDMCritSectLeave(&(a_pVM)->tm.s.TimerCritSect); } while (0)
+
+/** Checks that the caller owns the timer lock. */
+#define TM_ASSERT_TIMER_LOCK_OWNERSHIP(a_pVM) \
+ Assert(PDMCritSectIsOwner(&(a_pVM)->tm.s.TimerCritSect))
+
+
/** @} */
RT_C_DECLS_END
diff --git a/src/VBox/VMM/include/TRPMInternal.h b/src/VBox/VMM/include/TRPMInternal.h
index 0520ca050..c6ecc9e57 100644
--- a/src/VBox/VMM/include/TRPMInternal.h
+++ b/src/VBox/VMM/include/TRPMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: TRPMInternal.h $ */
+/* $Id: TRPMInternal.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* TRPM - Internal header file.
*/
diff --git a/src/VBox/VMM/include/TRPMInternal.mac b/src/VBox/VMM/include/TRPMInternal.mac
index a9c34c805..ae7b97437 100644
--- a/src/VBox/VMM/include/TRPMInternal.mac
+++ b/src/VBox/VMM/include/TRPMInternal.mac
@@ -1,4 +1,4 @@
-; $Id: TRPMInternal.mac $
+; $Id: TRPMInternal.mac 35346 2010-12-27 16:13:13Z vboxsync $
;; @file
; TRPM - Internal header file.
;
diff --git a/src/VBox/VMM/include/VMInternal.h b/src/VBox/VMM/include/VMInternal.h
index 528717dc7..5ea061d2c 100644
--- a/src/VBox/VMM/include/VMInternal.h
+++ b/src/VBox/VMM/include/VMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: VMInternal.h $ */
+/* $Id: VMInternal.h 36041 2011-02-21 16:04:53Z vboxsync $ */
/** @file
* VM - Internal header file.
*/
@@ -180,7 +180,10 @@ 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[9];
+ volatile PVMREQ apReqFree[16-4];
+
+ /** The reference count of the UVM handle. */
+ volatile uint32_t cUvmRefs;
#ifdef VBOX_WITH_STATISTICS
/** Number of VMR3ReqAlloc returning a new packet. */
@@ -293,6 +296,11 @@ typedef struct VMINTUSERPERVM
/** TLS index for the VMINTUSERPERVMCPU pointer. */
RTTLS idxTLS;
+
+ /** The VM name. (Set after the config constructure has been called.) */
+ char *pszName;
+ /** The VM UUID. (Set after the config constructure has been called.) */
+ RTUUID Uuid;
} VMINTUSERPERVM;
/** Pointer to the VM internal data kept in the UVM. */
diff --git a/src/VBox/VMM/include/VMMInternal.h b/src/VBox/VMM/include/VMMInternal.h
index fbc669225..71136d2a5 100644
--- a/src/VBox/VMM/include/VMMInternal.h
+++ b/src/VBox/VMM/include/VMMInternal.h
@@ -1,4 +1,4 @@
-/* $Id: VMMInternal.h $ */
+/* $Id: VMMInternal.h 37452 2011-06-14 18:13:48Z vboxsync $ */
/** @file
* VMM - Internal header file.
*/
@@ -378,6 +378,7 @@ typedef struct VMM
STAMCOUNTER StatRZRetPendingRequest;
STAMCOUNTER StatRZRetPGMFlushPending;
STAMCOUNTER StatRZRetPatchTPR;
+ STAMCOUNTER StatRZCallPDMCritSectEnter;
STAMCOUNTER StatRZCallPDMLock;
STAMCOUNTER StatRZCallLogFlush;
STAMCOUNTER StatRZCallPGMPoolGrow;
diff --git a/src/VBox/VMM/include/VMMInternal.mac b/src/VBox/VMM/include/VMMInternal.mac
index b7899d9a6..4780e380c 100644
--- a/src/VBox/VMM/include/VMMInternal.mac
+++ b/src/VBox/VMM/include/VMMInternal.mac
@@ -1,4 +1,4 @@
-; $Id: VMMInternal.mac $
+; $Id: VMMInternal.mac 35333 2010-12-27 12:10:56Z vboxsync $
;; @file
; VMM - Internal header file.
;
diff --git a/src/VBox/VMM/include/VMMSwitcher.h b/src/VBox/VMM/include/VMMSwitcher.h
index a0d296c89..9762aff33 100644
--- a/src/VBox/VMM/include/VMMSwitcher.h
+++ b/src/VBox/VMM/include/VMMSwitcher.h
@@ -1,4 +1,4 @@
-/* $Id: VMMSwitcher.h $ */
+/* $Id: VMMSwitcher.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VMM - World Switchers.
*/
diff --git a/src/VBox/VMM/include/VMMSwitcher.mac b/src/VBox/VMM/include/VMMSwitcher.mac
index 244ce3337..5685a456d 100644
--- a/src/VBox/VMM/include/VMMSwitcher.mac
+++ b/src/VBox/VMM/include/VMMSwitcher.mac
@@ -1,4 +1,4 @@
-; $Id: VMMSwitcher.mac $
+; $Id: VMMSwitcher.mac 35333 2010-12-27 12:10:56Z vboxsync $
;; @file
; VMM - World Switchers.
;
diff --git a/src/VBox/VMM/include/internal/em.h b/src/VBox/VMM/include/internal/em.h
index 2d63f0b0b..ccadd97b0 100644
--- a/src/VBox/VMM/include/internal/em.h
+++ b/src/VBox/VMM/include/internal/em.h
@@ -1,4 +1,4 @@
-/* $Id: em.h $ */
+/* $Id: em.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* EM - Internal VMM header file.
*/
diff --git a/src/VBox/VMM/include/internal/pgm.h b/src/VBox/VMM/include/internal/pgm.h
index 42f043f6e..aa86631e5 100644
--- a/src/VBox/VMM/include/internal/pgm.h
+++ b/src/VBox/VMM/include/internal/pgm.h
@@ -1,4 +1,4 @@
-/* $Id: pgm.h $ */
+/* $Id: pgm.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* PGM - Internal VMM header file.
*/
diff --git a/src/VBox/VMM/include/internal/vm.h b/src/VBox/VMM/include/internal/vm.h
index a3bc6ce6a..4b5dace98 100644
--- a/src/VBox/VMM/include/internal/vm.h
+++ b/src/VBox/VMM/include/internal/vm.h
@@ -1,4 +1,4 @@
-/* $Id: vm.h $ */
+/* $Id: vm.h 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VM - Internal VMM header file.
*/
diff --git a/src/VBox/VMM/pure_test.sh b/src/VBox/VMM/pure_test.sh
index 1d0a2a433..9542f1ae9 100755
--- a/src/VBox/VMM/pure_test.sh
+++ b/src/VBox/VMM/pure_test.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# $Id: pure_test.sh $
+# $Id: pure_test.sh 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# pure_test.sh - test the effect of __attribute__((pure)) on a set of
# functions.
diff --git a/src/VBox/VMM/testcase/Makefile.kmk b/src/VBox/VMM/testcase/Makefile.kmk
index ed2de9d18..470aa2b11 100644
--- a/src/VBox/VMM/testcase/Makefile.kmk
+++ b/src/VBox/VMM/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37955 2011-07-14 12:23:02Z vboxsync $
## @file
# Sub-Makefile for the VMM testcases.
#
@@ -36,13 +36,17 @@ ifndef VBOX_ONLY_EXTPACKS_USE_IMPLIBS
ifdef VBOX_WITH_TESTCASES
PROGRAMS += \
tstCFGM \
+ tstCompiler \
tstCompressionBenchmark \
- tstSSM \
+ tstIEMCheckMc \
tstMMHyperHeap \
- tstVMREQ \
- tstCompiler \
+ tstSSM \
tstVMMR0CallHost-1 \
- tstVMMR0CallHost-2
+ tstVMMR0CallHost-2 \
+ tstVMREQ
+ ifn1of ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH), solaris.x86 solaris.amd64 win.amd64 ) ## TODO: Fix the code.
+ PROGRAMS += tstX86-1
+ endif
ifneq ($(KBUILD_TARGET),l4)
PROGRAMS += tstAnimate
endif
@@ -187,6 +191,10 @@ tstGlobalConfig_TEMPLATE= VBOXR3TSTEXE
tstGlobalConfig_SOURCES = tstGlobalConfig.cpp
tstGlobalConfig_LIBS = $(LIB_RUNTIME)
+tstIEMCheckMc_TEMPLATE = VBOXR3TSTEXE
+tstIEMCheckMc_SOURCES = tstIEMCheckMc.cpp
+tstIEMCheckMc_LIBS = $(LIB_RUNTIME)
+
tstMMHyperHeap_TEMPLATE = VBOXR3TSTEXE
tstMMHyperHeap_SOURCES = tstMMHyperHeap.cpp
tstMMHyperHeap_LIBS = $(LIB_VMM) $(LIB_REM) $(LIB_RUNTIME)
@@ -232,6 +240,10 @@ tstCompiler_TEMPLATE = VBOXR3TSTEXE
tstCompiler_SOURCES = tstCompiler.cpp
tstCompiler_LIBS = $(LIB_VMM) $(LIB_REM) $(LIB_RUNTIME)
+tstX86-1_TEMPLATE = VBOXR3TSTEXE
+tstX86-1_SOURCES = tstX86-1.cpp tstX86-1A.asm
+tstX86-1_LIBS = $(LIB_RUNTIME)
+
ifdef VBOX_WITH_RAW_MODE
tstVMM_TEMPLATE = VBOXR3EXE
@@ -332,6 +344,7 @@ $(VBOX_VMM_TESTCASE_OUT_DIR)/tstAsmStructsAsm.mac: \
$(DEPTH)/include/VBox/vmm/cpum.mac \
$(DEPTH)/include/VBox/vmm/vm.mac \
$(DEPTH)/include/VBox/sup.mac \
+ $(DEPTH)/include/iprt/x86.mac \
$(VBOX_PATH_VMM_SRC)/include/CPUMInternal.mac \
$(VBOX_PATH_VMM_SRC)/include/TRPMInternal.mac \
$(VBOX_PATH_VMM_SRC)/include/HWACCMInternal.mac \
diff --git a/src/VBox/VMM/testcase/mkdsk.sh b/src/VBox/VMM/testcase/mkdsk.sh
index 0e55746de..0e55746de 100755..100644
--- a/src/VBox/VMM/testcase/mkdsk.sh
+++ b/src/VBox/VMM/testcase/mkdsk.sh
diff --git a/src/VBox/VMM/testcase/tstAnimate.cpp b/src/VBox/VMM/testcase/tstAnimate.cpp
index 4d0616e83..bb6107d5b 100644
--- a/src/VBox/VMM/testcase/tstAnimate.cpp
+++ b/src/VBox/VMM/testcase/tstAnimate.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstAnimate.cpp $ */
+/* $Id: tstAnimate.cpp 36408 2011-03-24 16:25:47Z vboxsync $ */
/** @file
* VBox Animation Testcase / Tool.
*/
diff --git a/src/VBox/VMM/testcase/tstAsmStructs.cpp b/src/VBox/VMM/testcase/tstAsmStructs.cpp
index e74a9a839..b28479dcb 100644
--- a/src/VBox/VMM/testcase/tstAsmStructs.cpp
+++ b/src/VBox/VMM/testcase/tstAsmStructs.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstAsmStructs.cpp $ */
+/* $Id: tstAsmStructs.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* Testcase for checking offsets in the assembly structures shared with C/C++.
*/
diff --git a/src/VBox/VMM/testcase/tstAsmStructsAsm.asm b/src/VBox/VMM/testcase/tstAsmStructsAsm.asm
index 95747e6d7..ce0c4b736 100644
--- a/src/VBox/VMM/testcase/tstAsmStructsAsm.asm
+++ b/src/VBox/VMM/testcase/tstAsmStructsAsm.asm
@@ -1,4 +1,4 @@
-; $Id: tstAsmStructsAsm.asm $
+; $Id: tstAsmStructsAsm.asm 35346 2010-12-27 16:13:13Z vboxsync $
;; @file
; Assembly / C structure layout testcase.
;
diff --git a/src/VBox/VMM/testcase/tstCFGM.cpp b/src/VBox/VMM/testcase/tstCFGM.cpp
index 8a7af1296..792ac9df4 100644
--- a/src/VBox/VMM/testcase/tstCFGM.cpp
+++ b/src/VBox/VMM/testcase/tstCFGM.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstCFGM.cpp $ */
+/* $Id: tstCFGM.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* Testcase for CFGM.
*/
diff --git a/src/VBox/VMM/testcase/tstCompiler.cpp b/src/VBox/VMM/testcase/tstCompiler.cpp
index 54508cdea..ca942f6d5 100644
--- a/src/VBox/VMM/testcase/tstCompiler.cpp
+++ b/src/VBox/VMM/testcase/tstCompiler.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstCompiler.cpp $ */
+/* $Id: tstCompiler.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* Testing how the compiler deals with various things.
*
@@ -26,7 +26,7 @@
#include <VBox/disopcode.h>
#include <iprt/stream.h>
#include <iprt/err.h>
-#include <VBox/x86.h>
+#include <iprt/x86.h>
#include <iprt/string.h>
#include <iprt/message.h>
#include <iprt/initterm.h>
diff --git a/src/VBox/VMM/testcase/tstCompressionBenchmark.cpp b/src/VBox/VMM/testcase/tstCompressionBenchmark.cpp
index 2105764d1..1d2e121dc 100644
--- a/src/VBox/VMM/testcase/tstCompressionBenchmark.cpp
+++ b/src/VBox/VMM/testcase/tstCompressionBenchmark.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstCompressionBenchmark.cpp $ */
+/* $Id: tstCompressionBenchmark.cpp 33550 2010-10-28 10:53:57Z vboxsync $ */
/** @file
* Compression Benchmark for SSM and PGM.
*/
diff --git a/src/VBox/VMM/testcase/tstGlobalConfig.cpp b/src/VBox/VMM/testcase/tstGlobalConfig.cpp
index f87701a14..134873cba 100644
--- a/src/VBox/VMM/testcase/tstGlobalConfig.cpp
+++ b/src/VBox/VMM/testcase/tstGlobalConfig.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstGlobalConfig.cpp $ */
+/* $Id: tstGlobalConfig.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* Ring-3 Management program for the GCFGM mock-up.
*/
diff --git a/src/VBox/VMM/testcase/tstHelp.h b/src/VBox/VMM/testcase/tstHelp.h
index ccc213810..c727a2c52 100644
--- a/src/VBox/VMM/testcase/tstHelp.h
+++ b/src/VBox/VMM/testcase/tstHelp.h
@@ -1,4 +1,4 @@
-/* $Id: tstHelp.h $ */
+/* $Id: tstHelp.h 36931 2011-05-03 13:34:43Z vboxsync $ */
/** @file
* VMM testcase - Helper stuff.
*/
@@ -147,5 +147,18 @@ RT_C_DECLS_END
} \
} while (0)
+/**
+ * Checks that an expression is true.
+ */
+#define CHECK_EXPR(expr) \
+ do \
+ { \
+ if (!(expr)) \
+ { \
+ printf("error! '%s' failed! (line %d)\n", #expr, __LINE__); \
+ rc++; \
+ } \
+ } while (0)
+
#endif
diff --git a/src/VBox/VMM/testcase/tstIEMCheckMc.cpp b/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
new file mode 100644
index 000000000..31f9fb915
--- /dev/null
+++ b/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
@@ -0,0 +1,410 @@
+/* $Id: tstIEMCheckMc.cpp 37008 2011-05-09 08:51:42Z vboxsync $ */
+/** @file
+ * IEM Testcase - Check the "Microcode".
+ */
+
+/*
+ * 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/rand.h>
+#include <iprt/test.h>
+
+#include <VBox/types.h>
+#include <VBox/err.h>
+#include "../include/IEMInternal.h"
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+bool volatile g_fRandom;
+uint8_t volatile g_bRandom;
+
+
+/** For hacks. */
+#define TST_IEM_CHECK_MC
+
+#define CHK_TYPE(a_ExpectedType, a_Param) \
+ do { a_ExpectedType const * pCheckType = &(a_Param); } while (0)
+#define CHK_PTYPE(a_ExpectedType, a_Param) \
+ do { a_ExpectedType pCheckType = (a_Param); } while (0)
+
+#define CHK_CONST(a_ExpectedType, a_Const) \
+ do { \
+ AssertCompile(((a_Const) >> 1) == ((a_Const) >> 1)); \
+ AssertCompile((a_ExpectedType)(a_Const) == (a_Const)); \
+ } while (0)
+
+#define CHK_SINGLE_BIT(a_ExpectedType, a_fBitMask) \
+ do { \
+ CHK_CONST(a_ExpectedType, a_fBitMask); \
+ AssertCompile(RT_IS_POWER_OF_TWO(a_fBitMask)); \
+ } while (0)
+
+#define CHK_GCPTR(a_EffAddr) \
+ CHK_TYPE(RTGCPTR, a_EffAddr)
+
+#define CHK_SEG_IDX(a_iSeg) \
+ do { \
+ uint8_t iMySeg = (a_iSeg); NOREF(iMySeg); /** @todo const or variable. grr. */ \
+ } while (0)
+
+
+/** @name Other stubs.
+ * @{ */
+
+typedef VBOXSTRICTRC (* PFNIEMOP)(PIEMCPU pIemCpu);
+#define FNIEMOP_DEF(a_Name) \
+ static VBOXSTRICTRC a_Name(PIEMCPU pIemCpu) RT_NO_THROW
+#define FNIEMOP_DEF_1(a_Name, a_Type0, a_Name0) \
+ static VBOXSTRICTRC a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0) RT_NO_THROW
+#define FNIEMOP_DEF_2(a_Name, a_Type0, a_Name0, a_Type1, a_Name1) \
+ static VBOXSTRICTRC a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0, a_Type1 a_Name1) RT_NO_THROW
+
+#define IEM_NOT_REACHED_DEFAULT_CASE_RET() default: return VERR_INTERNAL_ERROR_4
+
+#define IEM_OPCODE_GET_NEXT_U8(a_pu8) do { *(a_pu8) = g_bRandom; CHK_PTYPE(uint8_t *, a_pu8); } while (0)
+#define IEM_OPCODE_GET_NEXT_U16(a_pu16) do { *(a_pu16) = g_bRandom; CHK_PTYPE(uint16_t *, a_pu16); } while (0)
+#define IEM_OPCODE_GET_NEXT_U32(a_pu32) do { *(a_pu32) = g_bRandom; CHK_PTYPE(uint32_t *, a_pu32); } while (0)
+#define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) do { *(a_pu64) = g_bRandom; CHK_PTYPE(uint64_t *, a_pu64); } while (0)
+#define IEM_OPCODE_GET_NEXT_U64(a_pu64) do { *(a_pu64) = g_bRandom; CHK_PTYPE(uint64_t *, a_pu64); } while (0)
+#define IEM_OPCODE_GET_NEXT_S8(a_pi8) do { *(a_pi8) = g_bRandom; CHK_PTYPE(int8_t *, a_pi8); } while (0)
+#define IEM_OPCODE_GET_NEXT_S16(a_pi16) do { *(a_pi16) = g_bRandom; CHK_PTYPE(int16_t *, a_pi16); } while (0)
+#define IEM_OPCODE_GET_NEXT_S32(a_pi32) do { *(a_pi32) = g_bRandom; CHK_PTYPE(int32_t *, a_pi32); } while (0)
+#define IEMOP_HLP_NO_LOCK_PREFIX() do { } while (0)
+#define IEMOP_HLP_NO_64BIT() do { } while (0)
+#define IEMOP_HLP_DEFAULT_64BIT_OP_SIZE() do { } while (0)
+#define IEMOP_RAISE_INVALID_OPCODE() VERR_TRPM_ACTIVE_TRAP
+#define IEMOP_RAISE_INVALID_LOCK_PREFIX() VERR_TRPM_ACTIVE_TRAP
+#define IEMOP_MNEMONIC(a_szMnemonic) do { } while (0)
+#define IEMOP_MNEMONIC2(a_szMnemonic, a_szOps) do { } while (0)
+#define FNIEMOP_STUB(a_Name) \
+ FNIEMOP_DEF(a_Name) { return VERR_NOT_IMPLEMENTED; } \
+ typedef int ignore_semicolon
+#define FNIEMOP_STUB_1(a_Name, a_Type0, a_Name0) \
+ FNIEMOP_DEF_1(a_Name, a_Type0, a_Name0) { return VERR_NOT_IMPLEMENTED; } \
+ typedef int ignore_semicolon
+
+
+#define FNIEMOP_CALL(a_pfn) (a_pfn)(pIemCpu)
+#define FNIEMOP_CALL_1(a_pfn, a0) (a_pfn)(pIemCpu, a0)
+#define FNIEMOP_CALL_2(a_pfn, a0, a1) (a_pfn)(pIemCpu, a0, a1)
+
+#define IEM_IS_REAL_OR_V86_MODE(a_pIemCpu) (g_fRandom)
+#define IEM_IS_LONG_MODE(a_pIemCpu) (g_fRandom)
+#define IEM_IS_REAL_MODE(a_pIemCpu) (g_fRandom)
+#define IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(a_fEcx) (g_fRandom)
+#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(a_fEdx) (g_fRandom)
+
+#define iemRecalEffOpSize(a_pIemCpu) do { } while (0)
+
+IEMOPBINSIZES g_iemAImpl_add;
+IEMOPBINSIZES g_iemAImpl_adc;
+IEMOPBINSIZES g_iemAImpl_sub;
+IEMOPBINSIZES g_iemAImpl_sbb;
+IEMOPBINSIZES g_iemAImpl_or;
+IEMOPBINSIZES g_iemAImpl_xor;
+IEMOPBINSIZES g_iemAImpl_and;
+IEMOPBINSIZES g_iemAImpl_cmp;
+IEMOPBINSIZES g_iemAImpl_test;
+IEMOPBINSIZES g_iemAImpl_bt;
+IEMOPBINSIZES g_iemAImpl_btc;
+IEMOPBINSIZES g_iemAImpl_btr;
+IEMOPBINSIZES g_iemAImpl_bts;
+IEMOPBINSIZES g_iemAImpl_bsf;
+IEMOPBINSIZES g_iemAImpl_bsr;
+IEMOPBINSIZES g_iemAImpl_imul_two;
+PCIEMOPBINSIZES g_apIemImplGrp1[8];
+IEMOPUNARYSIZES g_iemAImpl_inc;
+IEMOPUNARYSIZES g_iemAImpl_dec;
+IEMOPUNARYSIZES g_iemAImpl_neg;
+IEMOPUNARYSIZES g_iemAImpl_not;
+IEMOPSHIFTSIZES g_iemAImpl_rol;
+IEMOPSHIFTSIZES g_iemAImpl_ror;
+IEMOPSHIFTSIZES g_iemAImpl_rcl;
+IEMOPSHIFTSIZES g_iemAImpl_rcr;
+IEMOPSHIFTSIZES g_iemAImpl_shl;
+IEMOPSHIFTSIZES g_iemAImpl_shr;
+IEMOPSHIFTSIZES g_iemAImpl_sar;
+IEMOPMULDIVSIZES g_iemAImpl_mul;
+IEMOPMULDIVSIZES g_iemAImpl_imul;
+IEMOPMULDIVSIZES g_iemAImpl_div;
+IEMOPMULDIVSIZES g_iemAImpl_idiv;
+IEMOPSHIFTDBLSIZES g_iemAImpl_shld;
+IEMOPSHIFTDBLSIZES g_iemAImpl_shrd;
+
+
+#define iemAImpl_idiv_u8 ((PFNIEMAIMPLMULDIVU8)0)
+#define iemAImpl_div_u8 ((PFNIEMAIMPLMULDIVU8)0)
+#define iemAImpl_imul_u8 ((PFNIEMAIMPLMULDIVU8)0)
+#define iemAImpl_mul_u8 ((PFNIEMAIMPLMULDIVU8)0)
+
+/** @} */
+
+
+#define IEM_REPEAT_0(a_Callback, a_User) do { } while (0)
+#define IEM_REPEAT_1(a_Callback, a_User) a_Callback##_CALLBACK(0, a_User)
+#define IEM_REPEAT_2(a_Callback, a_User) IEM_REPEAT_1(a_Callback, a_User); a_Callback##_CALLBACK(1, a_User)
+#define IEM_REPEAT_3(a_Callback, a_User) IEM_REPEAT_2(a_Callback, a_User); a_Callback##_CALLBACK(2, a_User)
+#define IEM_REPEAT_4(a_Callback, a_User) IEM_REPEAT_3(a_Callback, a_User); a_Callback##_CALLBACK(3, a_User)
+#define IEM_REPEAT_5(a_Callback, a_User) IEM_REPEAT_4(a_Callback, a_User); a_Callback##_CALLBACK(4, a_User)
+#define IEM_REPEAT_6(a_Callback, a_User) IEM_REPEAT_5(a_Callback, a_User); a_Callback##_CALLBACK(5, a_User)
+#define IEM_REPEAT_7(a_Callback, a_User) IEM_REPEAT_6(a_Callback, a_User); a_Callback##_CALLBACK(6, a_User)
+#define IEM_REPEAT_8(a_Callback, a_User) IEM_REPEAT_7(a_Callback, a_User); a_Callback##_CALLBACK(7, a_User)
+#define IEM_REPEAT_9(a_Callback, a_User) IEM_REPEAT_8(a_Callback, a_User); a_Callback##_CALLBACK(8, a_User)
+#define IEM_REPEAT(a_cTimes, a_Callback, a_User) RT_CONCAT(IEM_REPEAT_,a_cTimes)(a_Callback, a_User)
+
+
+
+/** @name Microcode test stubs
+ * @{ */
+
+#define IEM_ARG_CHECK_CALLBACK(a_idx, a_User) int RT_CONCAT(iArgCheck_,a_idx)
+#define IEM_MC_BEGIN(a_cArgs, a_cLocals) \
+ { \
+ const uint8_t cArgs = (a_cArgs); NOREF(cArgs); \
+ const uint8_t cLocals = (a_cArgs); NOREF(cLocals); \
+ IEM_REPEAT(a_cArgs, IEM_ARG_CHECK, 0); \
+
+#define IEM_MC_END() \
+ }
+
+#define IEM_MC_PAUSE() do {} while (0)
+#define IEM_MC_CONTINUE() do {} while (0)
+#define IEM_MC_ADVANCE_RIP() do {} while (0)
+#define IEM_MC_REL_JMP_S8(a_i8) CHK_TYPE(int8_t, a_i8)
+#define IEM_MC_REL_JMP_S16(a_i16) CHK_TYPE(int16_t, a_i16)
+#define IEM_MC_REL_JMP_S32(a_i32) CHK_TYPE(int32_t, a_i32)
+#define IEM_MC_SET_RIP_U16(a_u16NewIP) CHK_TYPE(uint16_t, a_u16NewIP)
+#define IEM_MC_SET_RIP_U32(a_u32NewIP) CHK_TYPE(uint32_t, a_u32NewIP)
+#define IEM_MC_SET_RIP_U64(a_u64NewIP) CHK_TYPE(uint64_t, a_u64NewIP)
+#define IEM_MC_RAISE_DIVIDE_ERROR() return VERR_TRPM_ACTIVE_TRAP
+#define IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE() do {} while (0)
+#define IEM_MC_MAYBE_RAISE_FPU_XCPT() do {} while (0)
+#define IEM_MC_RAISE_GP0_IF_CPL_NOT_ZERO() do {} while (0)
+
+#define IEM_MC_LOCAL(a_Type, a_Name) \
+ a_Type a_Name; NOREF(a_Name)
+#define IEM_MC_LOCAL_CONST(a_Type, a_Name, a_Value) \
+ a_Type const a_Name = (a_Value); \
+ NOREF(a_Name)
+#define IEM_MC_REF_LOCAL(a_pRefArg, a_Local) \
+ (a_pRefArg) = &(a_Local)
+
+#define IEM_MC_ARG(a_Type, a_Name, a_iArg) \
+ RT_CONCAT(iArgCheck_,a_iArg) = 1; NOREF(RT_CONCAT(iArgCheck_,a_iArg)); \
+ int RT_CONCAT3(iArgCheck_,a_iArg,a_Name); NOREF(RT_CONCAT3(iArgCheck_,a_iArg,a_Name)); \
+ AssertCompile((a_iArg) < cArgs); \
+ a_Type a_Name; \
+ NOREF(a_Name)
+#define IEM_MC_ARG_CONST(a_Type, a_Name, a_Value, a_iArg) \
+ RT_CONCAT(iArgCheck_, a_iArg) = 1; NOREF(RT_CONCAT(iArgCheck_,a_iArg)); \
+ int RT_CONCAT3(iArgCheck_,a_iArg,a_Name); NOREF(RT_CONCAT3(iArgCheck_,a_iArg,a_Name)); \
+ AssertCompile((a_iArg) < cArgs); \
+ a_Type const a_Name = (a_Value); \
+ NOREF(a_Name)
+#define IEM_MC_ARG_LOCAL_EFLAGS(a_pName, a_Name, a_iArg) \
+ RT_CONCAT(iArgCheck_, a_iArg) = 1; NOREF(RT_CONCAT(iArgCheck_,a_iArg)); \
+ int RT_CONCAT3(iArgCheck_,a_iArg,a_Name); NOREF(RT_CONCAT3(iArgCheck_,a_iArg,a_Name)); \
+ AssertCompile((a_iArg) < cArgs); \
+ uint32_t a_Name; \
+ uint32_t *a_pName = &a_Name; \
+ NOREF(a_pName)
+
+#define IEM_MC_COMMIT_EFLAGS(a_EFlags) CHK_TYPE(uint32_t, a_EFlags)
+#define IEM_MC_ASSIGN(a_VarOrArg, a_CVariableOrConst) (a_VarOrArg) = (0)
+#define IEM_MC_ASSIGN_TO_SMALLER IEM_MC_ASSIGN
+
+#define IEM_MC_FETCH_GREG_U8(a_u8Dst, a_iGReg) do { (a_u8Dst) = 0; CHK_TYPE(uint8_t, a_u8Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U8_ZX_U16(a_u16Dst, a_iGReg) do { (a_u16Dst) = 0; CHK_TYPE(uint16_t, a_u16Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U8_ZX_U32(a_u32Dst, a_iGReg) do { (a_u32Dst) = 0; CHK_TYPE(uint32_t, a_u32Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U8_ZX_U64(a_u64Dst, a_iGReg) do { (a_u64Dst) = 0; CHK_TYPE(uint64_t, a_u64Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U8_SX_U16(a_u16Dst, a_iGReg) do { (a_u16Dst) = 0; CHK_TYPE(uint16_t, a_u16Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U8_SX_U32(a_u32Dst, a_iGReg) do { (a_u32Dst) = 0; CHK_TYPE(uint32_t, a_u32Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U8_SX_U64(a_u64Dst, a_iGReg) do { (a_u64Dst) = 0; CHK_TYPE(uint64_t, a_u64Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U16(a_u16Dst, a_iGReg) do { (a_u16Dst) = 0; CHK_TYPE(uint16_t, a_u16Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U16_ZX_U32(a_u32Dst, a_iGReg) do { (a_u32Dst) = 0; CHK_TYPE(uint32_t, a_u32Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U16_ZX_U64(a_u64Dst, a_iGReg) do { (a_u64Dst) = 0; CHK_TYPE(uint64_t, a_u64Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U16_SX_U32(a_u32Dst, a_iGReg) do { (a_u32Dst) = 0; CHK_TYPE(uint32_t, a_u32Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U16_SX_U64(a_u64Dst, a_iGReg) do { (a_u64Dst) = 0; CHK_TYPE(uint64_t, a_u64Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U32(a_u32Dst, a_iGReg) do { (a_u32Dst) = 0; CHK_TYPE(uint32_t, a_u32Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U32_ZX_U64(a_u64Dst, a_iGReg) do { (a_u64Dst) = 0; CHK_TYPE(uint64_t, a_u64Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U32_SX_U64(a_u64Dst, a_iGReg) do { (a_u64Dst) = 0; CHK_TYPE(uint64_t, a_u64Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U64(a_u64Dst, a_iGReg) do { (a_u64Dst) = 0; CHK_TYPE(uint64_t, a_u64Dst); } while (0)
+#define IEM_MC_FETCH_GREG_U64_ZX_U64 IEM_MC_FETCH_GREG_U64
+#define IEM_MC_FETCH_SREG_U16(a_u16Dst, a_iSReg) do { (a_u16Dst) = 0; CHK_TYPE(uint16_t, a_u16Dst); } while (0)
+#define IEM_MC_FETCH_SREG_ZX_U32(a_u32Dst, a_iSReg) do { (a_u32Dst) = 0; CHK_TYPE(uint32_t, a_u32Dst); } while (0)
+#define IEM_MC_FETCH_SREG_ZX_U64(a_u64Dst, a_iSReg) do { (a_u64Dst) = 0; CHK_TYPE(uint64_t, a_u64Dst); } while (0)
+#define IEM_MC_FETCH_CR0_U16(a_u16Dst) do { (a_u16Dst) = 0; CHK_TYPE(uint16_t, a_u16Dst); } while (0)
+#define IEM_MC_FETCH_CR0_U32(a_u32Dst) do { (a_u32Dst) = 0; CHK_TYPE(uint32_t, a_u32Dst); } while (0)
+#define IEM_MC_FETCH_CR0_U64(a_u64Dst) do { (a_u64Dst) = 0; CHK_TYPE(uint64_t, a_u64Dst); } while (0)
+#define IEM_MC_FETCH_EFLAGS(a_EFlags) do { (a_EFlags) = 0; CHK_TYPE(uint32_t, a_EFlags); } while (0)
+#define IEM_MC_FETCH_FSW(a_u16Fsw) do { (a_u16Fsw) = 0; CHK_TYPE(uint16_t, a_u16Fsw); } while (0)
+#define IEM_MC_STORE_GREG_U8(a_iGReg, a_u8Value) do { CHK_TYPE(uint8_t, a_u8Value); } while (0)
+#define IEM_MC_STORE_GREG_U16(a_iGReg, a_u16Value) do { CHK_TYPE(uint16_t, a_u16Value); } while (0)
+#define IEM_MC_STORE_GREG_U32(a_iGReg, a_u32Value) do { } while (0)
+#define IEM_MC_STORE_GREG_U64(a_iGReg, a_u64Value) do { } while (0)
+#define IEM_MC_STORE_GREG_U8_CONST(a_iGReg, a_u8C) do { AssertCompile((uint8_t )(a_u8C) == (a_u8C) ); } while (0)
+#define IEM_MC_STORE_GREG_U16_CONST(a_iGReg, a_u16C) do { AssertCompile((uint16_t)(a_u16C) == (a_u16C)); } while (0)
+#define IEM_MC_STORE_GREG_U32_CONST(a_iGReg, a_u32C) do { AssertCompile((uint32_t)(a_u32C) == (a_u32C)); } while (0)
+#define IEM_MC_STORE_GREG_U64_CONST(a_iGReg, a_u64C) do { AssertCompile((uint64_t)(a_u64C) == (a_u64C)); } while (0)
+#define IEM_MC_CLEAR_HIGH_GREG_U64(a_iGReg) do { } while (0)
+#define IEM_MC_REF_GREG_U8(a_pu8Dst, a_iGReg) do { (a_pu8Dst) = (uint8_t *)((uintptr_t)0); CHK_PTYPE(uint8_t *, a_pu8Dst); } while (0)
+#define IEM_MC_REF_GREG_U16(a_pu16Dst, a_iGReg) do { (a_pu16Dst) = (uint16_t *)((uintptr_t)0); CHK_PTYPE(uint16_t *, a_pu16Dst); } while (0)
+#define IEM_MC_REF_GREG_U32(a_pu32Dst, a_iGReg) do { (a_pu32Dst) = (uint32_t *)((uintptr_t)0); CHK_PTYPE(uint32_t *, a_pu32Dst); } while (0)
+#define IEM_MC_REF_GREG_U64(a_pu64Dst, a_iGReg) do { (a_pu64Dst) = (uint64_t *)((uintptr_t)0); CHK_PTYPE(uint64_t *, a_pu64Dst); } while (0)
+#define IEM_MC_REF_EFLAGS(a_pEFlags) do { (a_pEFlags) = (uint32_t *)((uintptr_t)0); CHK_PTYPE(uint32_t *, a_pEFlags); } while (0)
+
+#define IEM_MC_ADD_GREG_U8(a_iGReg, a_u8Value) do { CHK_CONST(uint8_t, a_u8Value); } while (0)
+#define IEM_MC_ADD_GREG_U16(a_iGReg, a_u16Value) do { CHK_CONST(uint16_t, a_u16Value); } while (0)
+#define IEM_MC_ADD_GREG_U32(a_iGReg, a_u32Value) do { CHK_CONST(uint32_t, a_u32Value); } while (0)
+#define IEM_MC_ADD_GREG_U64(a_iGReg, a_u64Value) do { CHK_CONST(uint64_t, a_u64Value); } while (0)
+#define IEM_MC_SUB_GREG_U8(a_iGReg, a_u8Value) do { CHK_CONST(uint8_t, a_u8Value); } while (0)
+#define IEM_MC_SUB_GREG_U16(a_iGReg, a_u16Value) do { CHK_CONST(uint16_t, a_u16Value); } while (0)
+#define IEM_MC_SUB_GREG_U32(a_iGReg, a_u32Value) do { CHK_CONST(uint32_t, a_u32Value); } while (0)
+#define IEM_MC_SUB_GREG_U64(a_iGReg, a_u64Value) do { CHK_CONST(uint64_t, a_u64Value); } while (0)
+
+#ifdef _MSC_VER
+#define IEM_MC_ADD_GREG_U8_TO_LOCAL(a_u16Value, a_iGReg) do { (a_u8Value) += 1; /*CHK_CONST(uint8_t, a_u8Value); */ } while (0)
+#define IEM_MC_ADD_GREG_U16_TO_LOCAL(a_u16Value, a_iGReg) do { (a_u16Value) += 1; /*CHK_CONST(uint16_t, a_u16Value);*/ } while (0)
+#define IEM_MC_ADD_GREG_U32_TO_LOCAL(a_u32Value, a_iGReg) do { (a_u32Value) += 1; /*CHK_CONST(uint32_t, a_u32Value);*/ } while (0)
+#define IEM_MC_ADD_GREG_U64_TO_LOCAL(a_u64Value, a_iGReg) do { (a_u64Value) += 1; /*CHK_CONST(uint64_t, a_u64Value);*/ } while (0)
+#else
+#define IEM_MC_ADD_GREG_U8_TO_LOCAL(a_u16Value, a_iGReg) do { (a_u8Value) += 1; CHK_CONST(uint8_t, a_u8Value); } while (0)
+#define IEM_MC_ADD_GREG_U16_TO_LOCAL(a_u16Value, a_iGReg) do { (a_u16Value) += 1; CHK_CONST(uint16_t, a_u16Value); } while (0)
+#define IEM_MC_ADD_GREG_U32_TO_LOCAL(a_u32Value, a_iGReg) do { (a_u32Value) += 1; CHK_CONST(uint32_t, a_u32Value); } while (0)
+#define IEM_MC_ADD_GREG_U64_TO_LOCAL(a_u64Value, a_iGReg) do { (a_u64Value) += 1; CHK_CONST(uint64_t, a_u64Value); } while (0)
+#endif
+#define IEM_MC_ADD_LOCAL_S16_TO_EFF_ADDR(a_EffAddr, a_i16) do { (a_EffAddr) += (a_i16); CHK_GCPTR(a_EffAddr); } while (0)
+#define IEM_MC_ADD_LOCAL_S32_TO_EFF_ADDR(a_EffAddr, a_i32) do { (a_EffAddr) += (a_i32); CHK_GCPTR(a_EffAddr); } while (0)
+#define IEM_MC_ADD_LOCAL_S64_TO_EFF_ADDR(a_EffAddr, a_i64) do { (a_EffAddr) += (a_i64); CHK_GCPTR(a_EffAddr); } while (0)
+#define IEM_MC_AND_LOCAL_U16(a_u16Local, a_u16Mask) do { (a_u16Local) &= (a_u16Mask); CHK_TYPE(uint16_t, a_u16Local); CHK_CONST(uint16_t, a_u16Mask); } while (0)
+#define IEM_MC_AND_LOCAL_U32(a_u32Local, a_u32Mask) do { (a_u32Local) &= (a_u32Mask); CHK_TYPE(uint32_t, a_u32Local); CHK_CONST(uint32_t, a_u32Mask); } while (0)
+#define IEM_MC_AND_LOCAL_U64(a_u64Local, a_u64Mask) do { (a_u64Local) &= (a_u64Mask); CHK_TYPE(uint64_t, a_u64Local); CHK_CONST(uint64_t, a_u64Mask); } while (0)
+#define IEM_MC_AND_ARG_U16(a_u16Arg, a_u16Mask) do { (a_u16Arg) &= (a_u16Mask); CHK_TYPE(uint16_t, a_u16Arg); CHK_CONST(uint16_t, a_u16Mask); } while (0)
+#define IEM_MC_AND_ARG_U32(a_u32Arg, a_u32Mask) do { (a_u32Arg) &= (a_u32Mask); CHK_TYPE(uint32_t, a_u32Arg); CHK_CONST(uint32_t, a_u32Mask); } while (0)
+#define IEM_MC_AND_ARG_U64(a_u64Arg, a_u64Mask) do { (a_u64Arg) &= (a_u64Mask); CHK_TYPE(uint64_t, a_u64Arg); CHK_CONST(uint64_t, a_u64Mask); } while (0)
+#define IEM_MC_SAR_LOCAL_S16(a_i16Local, a_cShift) do { (a_i16Local) >>= (a_cShift); CHK_TYPE(int16_t, a_i16Local); CHK_CONST(uint8_t, a_cShift); } while (0)
+#define IEM_MC_SAR_LOCAL_S32(a_i32Local, a_cShift) do { (a_i32Local) >>= (a_cShift); CHK_TYPE(int32_t, a_i32Local); CHK_CONST(uint8_t, a_cShift); } while (0)
+#define IEM_MC_SAR_LOCAL_S64(a_i64Local, a_cShift) do { (a_i64Local) >>= (a_cShift); CHK_TYPE(int64_t, a_i64Local); CHK_CONST(uint8_t, a_cShift); } while (0)
+#define IEM_MC_SHL_LOCAL_S16(a_i16Local, a_cShift) do { (a_i16Local) <<= (a_cShift); CHK_TYPE(int16_t, a_i16Local); CHK_CONST(uint8_t, a_cShift); } while (0)
+#define IEM_MC_SHL_LOCAL_S32(a_i32Local, a_cShift) do { (a_i32Local) <<= (a_cShift); CHK_TYPE(int32_t, a_i32Local); CHK_CONST(uint8_t, a_cShift); } while (0)
+#define IEM_MC_SHL_LOCAL_S64(a_i64Local, a_cShift) do { (a_i64Local) <<= (a_cShift); CHK_TYPE(int64_t, a_i64Local); CHK_CONST(uint8_t, a_cShift); } while (0)
+#define IEM_MC_SET_EFL_BIT(a_fBit) do { CHK_SINGLE_BIT(uint32_t, a_fBit); } while (0)
+#define IEM_MC_CLEAR_EFL_BIT(a_fBit) do { CHK_SINGLE_BIT(uint32_t, a_fBit); } while (0)
+
+#define IEM_MC_FETCH_MEM_U8(a_u8Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM16_U8(a_u8Dst, a_iSeg, a_GCPtrMem16) do { CHK_TYPE(uint16_t, a_GCPtrMem16); } while (0)
+#define IEM_MC_FETCH_MEM32_U8(a_u8Dst, a_iSeg, a_GCPtrMem32) do { CHK_TYPE(uint32_t, a_GCPtrMem32); } while (0)
+#define IEM_MC_FETCH_MEM_U16(a_u16Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U32(a_u32Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_S32_SX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U64(a_u64Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+
+#define IEM_MC_FETCH_MEM_U8_DISP(a_u8Dst, a_iSeg, a_GCPtrMem, a_offDisp) \
+ do { CHK_GCPTR(a_GCPtrMem); CHK_CONST(uint8_t, a_offDisp); CHK_TYPE(uint8_t, a_u8Dst); } while (0)
+#define IEM_MC_FETCH_MEM_U16_DISP(a_u16Dst, a_iSeg, a_GCPtrMem, a_offDisp) \
+ do { CHK_GCPTR(a_GCPtrMem); CHK_CONST(uint8_t, a_offDisp); CHK_TYPE(uint16_t, a_u16Dst); } while (0)
+#define IEM_MC_FETCH_MEM_U32_DISP(a_u32Dst, a_iSeg, a_GCPtrMem, a_offDisp) \
+ do { CHK_GCPTR(a_GCPtrMem); CHK_CONST(uint8_t, a_offDisp); CHK_TYPE(uint32_t, a_u32Dst); } while (0)
+#define IEM_MC_FETCH_MEM_U64_DISP(a_u64Dst, a_iSeg, a_GCPtrMem, a_offDisp) \
+ do { CHK_GCPTR(a_GCPtrMem); CHK_CONST(uint8_t, a_offDisp); CHK_TYPE(uint64_t, a_u64Dst); } while (0)
+
+#define IEM_MC_FETCH_MEM_U8_ZX_U16(a_u16Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U8_ZX_U32(a_u32Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U8_ZX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U16_ZX_U32(a_u32Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U16_ZX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U32_ZX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U8_SX_U16(a_u16Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U8_SX_U32(a_u32Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U8_SX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U16_SX_U32(a_u32Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U16_SX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_FETCH_MEM_U32_SX_U64(a_u64Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); } while (0)
+#define IEM_MC_STORE_MEM_U8(a_iSeg, a_GCPtrMem, a_u8Value) do { CHK_GCPTR(a_GCPtrMem); CHK_TYPE(uint8_t, a_u8Value); CHK_SEG_IDX(a_iSeg); } while (0)
+#define IEM_MC_STORE_MEM_U16(a_iSeg, a_GCPtrMem, a_u16Value) do { CHK_GCPTR(a_GCPtrMem); CHK_TYPE(uint16_t, a_u16Value); } while (0)
+#define IEM_MC_STORE_MEM_U32(a_iSeg, a_GCPtrMem, a_u32Value) do { CHK_GCPTR(a_GCPtrMem); CHK_TYPE(uint32_t, a_u32Value); } while (0)
+#define IEM_MC_STORE_MEM_U64(a_iSeg, a_GCPtrMem, a_u64Value) do { CHK_GCPTR(a_GCPtrMem); CHK_TYPE(uint64_t, a_u64Value); } while (0)
+#define IEM_MC_STORE_MEM_U8_CONST(a_iSeg, a_GCPtrMem, a_u8C) do { CHK_GCPTR(a_GCPtrMem); CHK_CONST(uint8_t, a_u8C); } while (0)
+
+#define IEM_MC_PUSH_U16(a_u16Value) do {} while (0)
+#define IEM_MC_PUSH_U32(a_u32Value) do {} while (0)
+#define IEM_MC_PUSH_U64(a_u64Value) do {} while (0)
+#define IEM_MC_POP_U16(a_pu16Value) do {} while (0)
+#define IEM_MC_POP_U32(a_pu32Value) do {} while (0)
+#define IEM_MC_POP_U64(a_pu64Value) do {} while (0)
+#define IEM_MC_MEM_MAP(a_pMem, a_fAccess, a_iSeg, a_GCPtrMem, a_iArg) do {} while (0)
+#define IEM_MC_MEM_MAP_EX(a_pvMem, a_fAccess, a_cbMem, a_iSeg, a_GCPtrMem, a_iArg) do {} while (0)
+#define IEM_MC_MEM_COMMIT_AND_UNMAP(a_pvMem, a_fAccess) do {} while (0)
+#define IEM_MC_CALC_RM_EFF_ADDR(a_GCPtrEff, bRm) do { (a_GCPtrEff) = 0; CHK_GCPTR(a_GCPtrEff); } while (0)
+#define IEM_MC_CALL_VOID_AIMPL_2(a_pfn, a0, a1) do {} while (0)
+#define IEM_MC_CALL_VOID_AIMPL_3(a_pfn, a0, a1, a2) do {} while (0)
+#define IEM_MC_CALL_VOID_AIMPL_4(a_pfn, a0, a1, a2, a3) do {} while (0)
+#define IEM_MC_CALL_AIMPL_4(a_rc, a_pfn, a0, a1, a2, a3) do { (a_rc) = VINF_SUCCESS; } while (0)
+#define IEM_MC_CALL_CIMPL_0(a_pfnCImpl) return VINF_SUCCESS
+#define IEM_MC_CALL_CIMPL_1(a_pfnCImpl, a0) return VINF_SUCCESS
+#define IEM_MC_CALL_CIMPL_2(a_pfnCImpl, a0, a1) return VINF_SUCCESS
+#define IEM_MC_CALL_CIMPL_3(a_pfnCImpl, a0, a1, a2) return VINF_SUCCESS
+#define IEM_MC_CALL_CIMPL_5(a_pfnCImpl, a0, a1, a2, a3, a4) return VINF_SUCCESS
+#define IEM_MC_DEFER_TO_CIMPL_0(a_pfnCImpl) (VINF_SUCCESS)
+#define IEM_MC_DEFER_TO_CIMPL_1(a_pfnCImpl, a0) (VINF_SUCCESS)
+#define IEM_MC_DEFER_TO_CIMPL_2(a_pfnCImpl, a0, a1) (VINF_SUCCESS)
+#define IEM_MC_DEFER_TO_CIMPL_3(a_pfnCImpl, a0, a1, a2) (VINF_SUCCESS)
+
+#define IEM_MC_IF_EFL_BIT_SET(a_fBit) if (g_fRandom) {
+#define IEM_MC_IF_EFL_BIT_NOT_SET(a_fBit) if (g_fRandom) {
+#define IEM_MC_IF_EFL_ANY_BITS_SET(a_fBits) if (g_fRandom) {
+#define IEM_MC_IF_EFL_NO_BITS_SET(a_fBits) if (g_fRandom) {
+#define IEM_MC_IF_EFL_BITS_NE(a_fBit1, a_fBit2) if (g_fRandom) {
+#define IEM_MC_IF_EFL_BITS_EQ(a_fBit1, a_fBit2) if (g_fRandom) {
+#define IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(a_fBit, a_fBit1, a_fBit2) if (g_fRandom) {
+#define IEM_MC_IF_EFL_BIT_NOT_SET_AND_BITS_EQ(a_fBit, a_fBit1, a_fBit2) if (g_fRandom) {
+#define IEM_MC_IF_CX_IS_NZ() if (g_fRandom) {
+#define IEM_MC_IF_ECX_IS_NZ() if (g_fRandom) {
+#define IEM_MC_IF_RCX_IS_NZ() if (g_fRandom) {
+#define IEM_MC_IF_CX_IS_NZ_AND_EFL_BIT_SET(a_fBit) if (g_fRandom) {
+#define IEM_MC_IF_ECX_IS_NZ_AND_EFL_BIT_SET(a_fBit) if (g_fRandom) {
+#define IEM_MC_IF_RCX_IS_NZ_AND_EFL_BIT_SET(a_fBit) if (g_fRandom) {
+#define IEM_MC_IF_CX_IS_NZ_AND_EFL_BIT_NOT_SET(a_fBit) if (g_fRandom) {
+#define IEM_MC_IF_ECX_IS_NZ_AND_EFL_BIT_NOT_SET(a_fBit) if (g_fRandom) {
+#define IEM_MC_IF_RCX_IS_NZ_AND_EFL_BIT_NOT_SET(a_fBit) if (g_fRandom) {
+#define IEM_MC_IF_LOCAL_IS_Z(a_Local) if ((a_Local) == 0) {
+#define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo) if (g_fRandom) {
+#define IEM_MC_ELSE() } else {
+#define IEM_MC_ENDIF() } do {} while (0)
+
+/** @} */
+
+#include "../VMMAll/IEMAllInstructions.cpp.h"
+
+
+
+/**
+ * Formalities...
+ */
+int main()
+{
+ RTTEST hTest;
+ RTEXITCODE rcExit = RTTestInitAndCreate("tstIEMCheckMc", &hTest);
+ if (rcExit == RTEXITCODE_SUCCESS)
+ {
+ RTTestBanner(hTest);
+ RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "(this is only a compile test.)");
+ rcExit = RTTestSummaryAndDestroy(hTest);
+ }
+ return rcExit;
+}
diff --git a/src/VBox/VMM/testcase/tstInstrEmul.cpp b/src/VBox/VMM/testcase/tstInstrEmul.cpp
index 4e9b9ce69..1caeab2b1 100644
--- a/src/VBox/VMM/testcase/tstInstrEmul.cpp
+++ b/src/VBox/VMM/testcase/tstInstrEmul.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstInstrEmul.cpp $ */
+/* $Id: tstInstrEmul.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* Micro Testcase, checking emulation of certain instructions
*/
diff --git a/src/VBox/VMM/testcase/tstMMHyperHeap.cpp b/src/VBox/VMM/testcase/tstMMHyperHeap.cpp
index 4ba08e835..d119d5dd5 100644
--- a/src/VBox/VMM/testcase/tstMMHyperHeap.cpp
+++ b/src/VBox/VMM/testcase/tstMMHyperHeap.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstMMHyperHeap.cpp $ */
+/* $Id: tstMMHyperHeap.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* MM Hypervisor Heap testcase.
*/
diff --git a/src/VBox/VMM/testcase/tstMicro.cpp b/src/VBox/VMM/testcase/tstMicro.cpp
index f8e0bcd44..abd23771b 100644
--- a/src/VBox/VMM/testcase/tstMicro.cpp
+++ b/src/VBox/VMM/testcase/tstMicro.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstMicro.cpp $ */
+/* $Id: tstMicro.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* Micro Testcase, profiling special CPU operations.
*/
diff --git a/src/VBox/VMM/testcase/tstMicro.h b/src/VBox/VMM/testcase/tstMicro.h
index 3473c365a..5120946cc 100644
--- a/src/VBox/VMM/testcase/tstMicro.h
+++ b/src/VBox/VMM/testcase/tstMicro.h
@@ -1,4 +1,4 @@
-/* $Id: tstMicro.h $ */
+/* $Id: tstMicro.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Micro Testcase, profiling special CPU operations.
*/
diff --git a/src/VBox/VMM/testcase/tstMicro.mac b/src/VBox/VMM/testcase/tstMicro.mac
index 92e50ca31..4b75e41e8 100644
--- a/src/VBox/VMM/testcase/tstMicro.mac
+++ b/src/VBox/VMM/testcase/tstMicro.mac
@@ -1,4 +1,4 @@
-; $Id: tstMicro.mac $
+; $Id: tstMicro.mac 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; Micro Testcase, profiling special CPU operations.
;
diff --git a/src/VBox/VMM/testcase/tstMicroRC.cpp b/src/VBox/VMM/testcase/tstMicroRC.cpp
index a1a719363..a43461c78 100644
--- a/src/VBox/VMM/testcase/tstMicroRC.cpp
+++ b/src/VBox/VMM/testcase/tstMicroRC.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstMicroRC.cpp $ */
+/* $Id: tstMicroRC.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* Micro Testcase, profiling special CPU operations - GC Code (hacks).
*/
diff --git a/src/VBox/VMM/testcase/tstMicroRCA.asm b/src/VBox/VMM/testcase/tstMicroRCA.asm
index 87ace5803..4383af17e 100644
--- a/src/VBox/VMM/testcase/tstMicroRCA.asm
+++ b/src/VBox/VMM/testcase/tstMicroRCA.asm
@@ -1,4 +1,4 @@
-; $Id: tstMicroRCA.asm $
+; $Id: tstMicroRCA.asm 37955 2011-07-14 12:23:02Z vboxsync $
;; @file
; tstMicroRCA
;
@@ -19,7 +19,7 @@
;* Header Files *
;*******************************************************************************
%include "VBox/asmdefs.mac"
-%include "VBox/x86.mac"
+%include "iprt/x86.mac"
%include "VBox/vmm/cpum.mac"
%include "VBox/err.mac"
%include "VBox/vmm/vm.mac"
diff --git a/src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp b/src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp
index e54d0c184..e3513ebbf 100644
--- a/src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp
+++ b/src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstPDMAsyncCompletion.cpp $ */
+/* $Id: tstPDMAsyncCompletion.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* PDM Asynchronous Completion Testcase.
*
diff --git a/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp b/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp
index 25fa67995..fb28df5e9 100644
--- a/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp
+++ b/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstPDMAsyncCompletionStress.cpp $ */
+/* $Id: tstPDMAsyncCompletionStress.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* PDM Asynchronous Completion Stresstest.
*
diff --git a/src/VBox/VMM/testcase/tstSSM.cpp b/src/VBox/VMM/testcase/tstSSM.cpp
index 4908e4fa8..ccebc89ef 100644
--- a/src/VBox/VMM/testcase/tstSSM.cpp
+++ b/src/VBox/VMM/testcase/tstSSM.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstSSM.cpp $ */
+/* $Id: tstSSM.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* Saved State Manager Testcase.
*/
diff --git a/src/VBox/VMM/testcase/tstVMM-HwAccm.cpp b/src/VBox/VMM/testcase/tstVMM-HwAccm.cpp
index b50877027..497a7d0ed 100644
--- a/src/VBox/VMM/testcase/tstVMM-HwAccm.cpp
+++ b/src/VBox/VMM/testcase/tstVMM-HwAccm.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstVMM-HwAccm.cpp $ */
+/* $Id: tstVMM-HwAccm.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VMM Testcase.
*/
diff --git a/src/VBox/VMM/testcase/tstVMM.cpp b/src/VBox/VMM/testcase/tstVMM.cpp
index f1dd26770..88413e5b1 100644
--- a/src/VBox/VMM/testcase/tstVMM.cpp
+++ b/src/VBox/VMM/testcase/tstVMM.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstVMM.cpp $ */
+/* $Id: tstVMM.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VMM Testcase.
*/
diff --git a/src/VBox/VMM/testcase/tstVMMFork.cpp b/src/VBox/VMM/testcase/tstVMMFork.cpp
index 04ed9167e..d30eaea6d 100644
--- a/src/VBox/VMM/testcase/tstVMMFork.cpp
+++ b/src/VBox/VMM/testcase/tstVMMFork.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstVMMFork.cpp $ */
+/* $Id: tstVMMFork.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VMM Fork Test.
*/
diff --git a/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp b/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp
index 7ec223968..2dc2dcf90 100644
--- a/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp
+++ b/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstVMMR0CallHost-1.cpp $ */
+/* $Id: tstVMMR0CallHost-1.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* Testcase for the VMMR0JMPBUF operations.
*/
diff --git a/src/VBox/VMM/testcase/tstVMREQ.cpp b/src/VBox/VMM/testcase/tstVMREQ.cpp
index 34cf1de79..3e6c2c9d6 100644
--- a/src/VBox/VMM/testcase/tstVMREQ.cpp
+++ b/src/VBox/VMM/testcase/tstVMREQ.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstVMREQ.cpp $ */
+/* $Id: tstVMREQ.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
/** @file
* VMM Testcase.
*/
diff --git a/src/VBox/VMM/testcase/tstVMStructRC.cpp b/src/VBox/VMM/testcase/tstVMStructRC.cpp
index e464e3ffe..04df377cb 100644
--- a/src/VBox/VMM/testcase/tstVMStructRC.cpp
+++ b/src/VBox/VMM/testcase/tstVMStructRC.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstVMStructRC.cpp $ */
+/* $Id: tstVMStructRC.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* tstVMMStructRC - Generate structure member and size checks from the
* RC perspective.
@@ -76,10 +76,11 @@ AssertCompileSize(RTHCPHYS, 8);
#include "STAMInternal.h"
#include "CSAMInternal.h"
#include "EMInternal.h"
+#include "IEMInternal.h"
#include "REMInternal.h"
#include <VBox/vmm/vm.h>
#include <VBox/param.h>
-#include <VBox/x86.h>
+#include <iprt/x86.h>
#include <iprt/assert.h>
/* we don't use iprt here because we're pretending to be in GC! */
@@ -150,6 +151,24 @@ int main()
GEN_CHECK_OFF(EMCPU, pStatsRC);
GEN_CHECK_OFF(EMCPU, pCliStatTree);
+ GEN_CHECK_SIZE(IEMCPU);
+ GEN_CHECK_OFF(IEMCPU, pCtxR0);
+ GEN_CHECK_OFF(IEMCPU, pCtxR3);
+ GEN_CHECK_OFF(IEMCPU, pCtxRC);
+ GEN_CHECK_OFF(IEMCPU, offVM);
+ GEN_CHECK_OFF(IEMCPU, offVMCpu);
+ GEN_CHECK_OFF(IEMCPU, enmCpuMode);
+ GEN_CHECK_OFF(IEMCPU, fPrefixes);
+ GEN_CHECK_OFF(IEMCPU, abOpcode);
+ GEN_CHECK_OFF(IEMCPU, cActiveMappings);
+ GEN_CHECK_OFF(IEMCPU, iNextMapping);
+ GEN_CHECK_OFF(IEMCPU, aMemMappings);
+ GEN_CHECK_OFF(IEMCPU, aMemMappings[1]);
+ GEN_CHECK_OFF(IEMCPU, aBounceBuffers);
+ GEN_CHECK_OFF(IEMCPU, aBounceBuffers[1]);
+ GEN_CHECK_OFF(IEMCPU, aMemBbMappings);
+ GEN_CHECK_OFF(IEMCPU, aMemBbMappings[1]);
+
GEN_CHECK_SIZE(IOM);
GEN_CHECK_OFF(IOM, pTreesRC);
GEN_CHECK_OFF(IOM, pTreesR3);
@@ -214,7 +233,7 @@ int main()
GEN_CHECK_OFF(IOMTREES, IOPortTreeRC);
GEN_CHECK_OFF(IOMTREES, MMIOTree);
GEN_CHECK_OFF(IOMTREES, IOPortStatTree);
- GEN_CHECK_OFF(IOMTREES, MMIOStatTree);
+ GEN_CHECK_OFF(IOMTREES, MmioStatTree);
GEN_CHECK_SIZE(MM);
GEN_CHECK_OFF(MM, offVM);
@@ -270,7 +289,8 @@ int main()
GEN_CHECK_OFF(MMLOOKUPHYPER, pszDesc);
GEN_CHECK_SIZE(PDM);
- GEN_CHECK_OFF(PDM, offVM);
+ GEN_CHECK_OFF(PDM, CritSect);
+ GEN_CHECK_OFF(PDM, NopCritSect);
GEN_CHECK_OFF(PDM, pDevs);
GEN_CHECK_OFF(PDM, pDevInstances);
GEN_CHECK_OFF(PDM, pUsbDevs);
@@ -344,7 +364,6 @@ int main()
GEN_CHECK_OFF(PDMCPU, apQueuedCritSectsLeaves);
GEN_CHECK_OFF(PDM, pQueueFlushR0);
GEN_CHECK_OFF(PDM, pQueueFlushRC);
- GEN_CHECK_OFF(PDM, CritSect);
GEN_CHECK_OFF(PDM, StatQueuedCritSectLeaves);
GEN_CHECK_SIZE(PDMDEVINSINT);
@@ -544,9 +563,9 @@ int main()
GEN_CHECK_OFF(PGM, paDynPageMapPaePTEsGC);
GEN_CHECK_OFF(PGM, enmHostMode);
GEN_CHECK_OFF(PGM, GCPhys4MBPSEMask);
- GEN_CHECK_OFF(PGM, pRamRangesR3);
- GEN_CHECK_OFF(PGM, pRamRangesR0);
- GEN_CHECK_OFF(PGM, pRamRangesRC);
+ GEN_CHECK_OFF(PGM, pRamRangesXR3);
+ GEN_CHECK_OFF(PGM, pRamRangesXR0);
+ GEN_CHECK_OFF(PGM, pRamRangesXRC);
GEN_CHECK_OFF(PGM, pRomRangesR3);
GEN_CHECK_OFF(PGM, pRomRangesR0);
GEN_CHECK_OFF(PGM, pRomRangesRC);
@@ -671,10 +690,9 @@ int main()
GEN_CHECK_OFF(PGMVIRTHANDLER, cPages);
GEN_CHECK_OFF(PGMVIRTHANDLER, aPhysToVirt);
GEN_CHECK_SIZE(PGMPAGE);
- GEN_CHECK_OFF(PGMPAGE, HCPhysAndPageID);
- GEN_CHECK_OFF(PGMPAGE, cReadLocksY);
- GEN_CHECK_OFF(PGMPAGE, cWriteLocksY);
- GEN_CHECK_OFF(PGMPAGE, u16TrackingY);
+ GEN_CHECK_OFF(PGMPAGE, s.cReadLocksY);
+ GEN_CHECK_OFF(PGMPAGE, s.cWriteLocksY);
+ GEN_CHECK_OFF(PGMPAGE, s.u16TrackingY);
GEN_CHECK_SIZE(PGMRAMRANGE);
GEN_CHECK_OFF(PGMRAMRANGE, pNextR3);
GEN_CHECK_OFF(PGMRAMRANGE, pNextR0);
diff --git a/src/VBox/VMM/testcase/tstVMStructSize.cpp b/src/VBox/VMM/testcase/tstVMStructSize.cpp
index 4cf672e26..75c93b91a 100644
--- a/src/VBox/VMM/testcase/tstVMStructSize.cpp
+++ b/src/VBox/VMM/testcase/tstVMStructSize.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstVMStructSize.cpp $ */
+/* $Id: tstVMStructSize.cpp 37955 2011-07-14 12:23:02Z vboxsync $ */
/** @file
* tstVMStructSize - testcase for check structure sizes/alignment
* and to verify that HC and GC uses the same
@@ -48,6 +48,7 @@
#include "VMInternal.h"
#include "CSAMInternal.h"
#include "EMInternal.h"
+#include "IEMInternal.h"
#include "REMInternal.h"
#include "../VMMR0/GMMR0Internal.h"
#include "../VMMR0/GVMMR0Internal.h"
@@ -55,7 +56,7 @@
#include <VBox/vmm/uvm.h>
#include <VBox/vmm/gvm.h>
#include <VBox/param.h>
-#include <VBox/x86.h>
+#include <iprt/x86.h>
#include "tstHelp.h"
#include <stdio.h>
@@ -210,6 +211,7 @@ int main()
CHECK_PADDING_VM(64, patm);
CHECK_PADDING_VM(64, csam);
CHECK_PADDING_VM(64, em);
+ /*CHECK_PADDING_VM(64, iem);*/
CHECK_PADDING_VM(64, tm);
CHECK_PADDING_VM(64, dbgf);
CHECK_PADDING_VM(64, ssm);
@@ -221,6 +223,7 @@ int main()
CHECK_PADDING_VMCPU(64, cpum);
CHECK_PADDING_VMCPU(64, hwaccm);
CHECK_PADDING_VMCPU(64, em);
+ CHECK_PADDING_VMCPU(64, iem);
CHECK_PADDING_VMCPU(64, trpm);
CHECK_PADDING_VMCPU(64, tm);
CHECK_PADDING_VMCPU(64, vmm);
@@ -374,7 +377,7 @@ int main()
PRINT_OFFSET(VM, StatGCToQemu);
#endif
- CHECK_MEMBER_ALIGNMENT(IOM, EmtLock, sizeof(uintptr_t));
+ CHECK_MEMBER_ALIGNMENT(IOM, CritSect, sizeof(uintptr_t));
CHECK_MEMBER_ALIGNMENT(EM, CritSectREM, sizeof(uintptr_t));
CHECK_MEMBER_ALIGNMENT(PGM, CritSect, sizeof(uintptr_t));
CHECK_MEMBER_ALIGNMENT(PDM, CritSect, sizeof(uintptr_t));
@@ -386,7 +389,7 @@ int main()
CHECK_MEMBER_ALIGNMENT(HWACCM, vmx.msr.feature_ctrl, 8);
CHECK_MEMBER_ALIGNMENT(HWACCM, StatTPRPatchSuccess, 8);
CHECK_MEMBER_ALIGNMENT(HWACCMCPU, StatEntry, 8);
- CHECK_MEMBER_ALIGNMENT(HWACCMCPU, vmx.pVMCSPhys, sizeof(RTHCPHYS));
+ CHECK_MEMBER_ALIGNMENT(HWACCMCPU, vmx.HCPhysVMCS, sizeof(RTHCPHYS));
CHECK_MEMBER_ALIGNMENT(HWACCMCPU, vmx.proc_ctls, 8);
CHECK_MEMBER_ALIGNMENT(HWACCMCPU, Event.intInfo, 8);
@@ -427,6 +430,94 @@ int main()
CHECK_PADDING_GVMCPU(4, gvmm);
/*
+ * Check that the optimized access macros for PGMPAGE works correctly.
+ */
+ PGMPAGE Page;
+ PGM_PAGE_CLEAR(&Page);
+
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_NONE);
+ CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == false);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == false);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == false);
+
+ PGM_PAGE_SET_HNDL_PHYS_STATE(&Page, PGM_PAGE_HNDL_PHYS_STATE_ALL);
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_ALL);
+ CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == true);
+
+ PGM_PAGE_SET_HNDL_PHYS_STATE(&Page, PGM_PAGE_HNDL_PHYS_STATE_WRITE);
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_WRITE);
+ CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == false);
+
+ PGM_PAGE_CLEAR(&Page);
+ PGM_PAGE_SET_HNDL_VIRT_STATE(&Page, PGM_PAGE_HNDL_VIRT_STATE_ALL);
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_VIRT_STATE(&Page) == PGM_PAGE_HNDL_VIRT_STATE_ALL);
+ CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == true);
+
+ PGM_PAGE_SET_HNDL_VIRT_STATE(&Page, PGM_PAGE_HNDL_VIRT_STATE_WRITE);
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_VIRT_STATE(&Page) == PGM_PAGE_HNDL_VIRT_STATE_WRITE);
+ CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == false);
+
+
+ PGM_PAGE_CLEAR(&Page);
+ PGM_PAGE_SET_HNDL_PHYS_STATE(&Page, PGM_PAGE_HNDL_PHYS_STATE_ALL);
+ PGM_PAGE_SET_HNDL_VIRT_STATE(&Page, PGM_PAGE_HNDL_VIRT_STATE_WRITE);
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_ALL);
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_VIRT_STATE(&Page) == PGM_PAGE_HNDL_VIRT_STATE_WRITE);
+ CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == true);
+
+ PGM_PAGE_SET_HNDL_PHYS_STATE(&Page, PGM_PAGE_HNDL_PHYS_STATE_WRITE);
+ PGM_PAGE_SET_HNDL_VIRT_STATE(&Page, PGM_PAGE_HNDL_VIRT_STATE_ALL);
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_WRITE);
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_VIRT_STATE(&Page) == PGM_PAGE_HNDL_VIRT_STATE_ALL);
+ CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == true);
+
+ PGM_PAGE_SET_HNDL_PHYS_STATE(&Page, PGM_PAGE_HNDL_PHYS_STATE_WRITE);
+ PGM_PAGE_SET_HNDL_VIRT_STATE(&Page, PGM_PAGE_HNDL_VIRT_STATE_WRITE);
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_WRITE);
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_VIRT_STATE(&Page) == PGM_PAGE_HNDL_VIRT_STATE_WRITE);
+ CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == false);
+
+ PGM_PAGE_SET_HNDL_VIRT_STATE(&Page, PGM_PAGE_HNDL_VIRT_STATE_NONE);
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_WRITE);
+ CHECK_EXPR(PGM_PAGE_GET_HNDL_VIRT_STATE(&Page) == PGM_PAGE_HNDL_VIRT_STATE_NONE);
+ CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
+ CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == false);
+
+#undef AssertFatal
+#define AssertFatal(expr) do { } while (0)
+#undef Assert
+#define Assert(expr) do { } while (0)
+
+ PGM_PAGE_CLEAR(&Page);
+ CHECK_EXPR(PGM_PAGE_GET_HCPHYS_NA(&Page) == 0);
+ PGM_PAGE_SET_HCPHYS(NULL, &Page, UINT64_C(0x0000fffeff1ff000));
+ CHECK_EXPR(PGM_PAGE_GET_HCPHYS_NA(&Page) == UINT64_C(0x0000fffeff1ff000));
+ PGM_PAGE_SET_HCPHYS(NULL, &Page, UINT64_C(0x0000000000001000));
+ CHECK_EXPR(PGM_PAGE_GET_HCPHYS_NA(&Page) == UINT64_C(0x0000000000001000));
+
+ PGM_PAGE_INIT(&Page, UINT64_C(0x0000feedfacef000), UINT32_C(0x12345678), PGMPAGETYPE_RAM, PGM_PAGE_STATE_ALLOCATED);
+ CHECK_EXPR(PGM_PAGE_GET_HCPHYS_NA(&Page) == UINT64_C(0x0000feedfacef000));
+ CHECK_EXPR(PGM_PAGE_GET_PAGEID(&Page) == UINT32_C(0x12345678));
+ CHECK_EXPR(PGM_PAGE_GET_TYPE_NA(&Page) == PGMPAGETYPE_RAM);
+ CHECK_EXPR(PGM_PAGE_GET_STATE_NA(&Page) == PGM_PAGE_STATE_ALLOCATED);
+
+
+ /*
* Report result.
*/
if (rc)
diff --git a/src/VBox/VMM/testcase/tstX86-1.cpp b/src/VBox/VMM/testcase/tstX86-1.cpp
new file mode 100644
index 000000000..6904bf4ab
--- /dev/null
+++ b/src/VBox/VMM/testcase/tstX86-1.cpp
@@ -0,0 +1,206 @@
+/* $Id: tstX86-1.cpp 36865 2011-04-28 00:59:50Z vboxsync $ */
+/** @file
+ * X86 instruction set exploration/testcase #1.
+ */
+
+/*
+ * 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/test.h>
+#include <iprt/param.h>
+#include <iprt/mem.h>
+#include <iprt/err.h>
+#include <iprt/assert.h>
+
+#ifdef RT_OS_WINDOWS
+# include <Windows.h>
+#else
+# ifdef RT_OS_DARWIN
+# define _XOPEN_SOURCE
+# endif
+# include <signal.h>
+# include <ucontext.h>
+# define USE_SIGNAL
+#endif
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+typedef struct TRAPINFO
+{
+ uintptr_t uTrapPC;
+ uintptr_t uResumePC;
+ uint8_t u8Trap;
+ uint8_t cbInstr;
+ uint8_t auAlignment[sizeof(uintptr_t) * 2 - 2];
+} TRAPINFO;
+typedef TRAPINFO const *PCTRAPINFO;
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+RT_C_DECLS_BEGIN
+uint8_t *g_pbEfPage = NULL;
+uint8_t *g_pbEfExecPage = NULL;
+extern TRAPINFO g_aTrapInfo[];
+RT_C_DECLS_END
+
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+DECLASM(int32_t) x861_Test1(void);
+
+
+
+static PCTRAPINFO findTrapInfo(uintptr_t uTrapPC, uintptr_t uTrapSP)
+{
+ /* Search by trap program counter. */
+ for (unsigned i = 0; g_aTrapInfo[i].uTrapPC; i++)
+ if (g_aTrapInfo[i].uTrapPC == uTrapPC)
+ return &g_aTrapInfo[i];
+
+ /* Search by return address. */
+ uintptr_t uReturn = *(uintptr_t *)uTrapSP;
+ for (unsigned i = 0; g_aTrapInfo[i].uTrapPC; i++)
+ if (g_aTrapInfo[i].uTrapPC + g_aTrapInfo[i].cbInstr == uReturn)
+ return &g_aTrapInfo[i];
+
+ return NULL;
+}
+
+#ifdef USE_SIGNAL
+static void sigHandler(int iSig, siginfo_t *pSigInfo, void *pvSigCtx)
+{
+ ucontext_t *pCtx = (ucontext_t *)pvSigCtx;
+
+# if defined(RT_ARCH_AMD64) && defined(RT_OS_DARWIN)
+ uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext->__ss.__rip;
+ uintptr_t *puSP = (uintptr_t *)&pCtx->uc_mcontext->__ss.__rsp;
+ uintptr_t uTrapNo = pCtx->uc_mcontext->__es.__trapno;
+ uintptr_t uErr = pCtx->uc_mcontext->__es.__err;
+
+# elif defined(RT_ARCH_AMD64) && defined(RT_OS_FREEBSD)
+ uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext.mc_rip;
+ uintptr_t *puSP = (uintptr_t *)&pCtx->uc_mcontext.mc_rsp;
+ uintptr_t uTrapNo = ~(uintptr_t)0;
+ uintptr_t uErr = ~(uintptr_t)0;
+
+# elif defined(RT_ARCH_AMD64)
+ uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext.gregs[REG_RIP];
+ uintptr_t *puSP = (uintptr_t *)&pCtx->uc_mcontext.gregs[REG_RSP];
+ uintptr_t uTrapNo = pCtx->uc_mcontext.gregs[REG_TRAPNO];
+ uintptr_t uErr = pCtx->uc_mcontext.gregs[REG_ERR];
+
+# elif defined(RT_ARCH_X86) && defined(RT_OS_DARWIN)
+ uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext->__ss.__eip;
+ uintptr_t *puSP = (uintptr_t *)&pCtx->uc_mcontext->__ss.__esp;
+ uintptr_t uTrapNo = pCtx->uc_mcontext->__es.__trapno;
+ uintptr_t uErr = pCtx->uc_mcontext->__es.__err;
+
+# elif defined(RT_ARCH_X86) && defined(RT_OS_FREEBSD)
+ uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext.mc_eip;
+ uintptr_t *puSP = (uintptr_t *)&pCtx->uc_mcontext.mc_esp;
+ uintptr_t uTrapNo = ~(uintptr_t)0;
+ uintptr_t uErr = ~(uintptr_t)0;
+
+# elif defined(RT_ARCH_X86)
+ uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext.gregs[REG_EIP];
+ uintptr_t *puSP = (uintptr_t *)&pCtx->uc_mcontext.gregs[REG_ESP];
+ uintptr_t uTrapNo = pCtx->uc_mcontext.gregs[REG_TRAPNO];
+ uintptr_t uErr = pCtx->uc_mcontext.gregs[REG_ERR];
+
+# else
+ uintptr_t *puPC = NULL;
+ uintptr_t *puSP = NULL;
+ uintptr_t uTrapNo = ~(uintptr_t)0;
+ uintptr_t uErr = ~(uintptr_t)0;
+# endif
+ RTAssertMsg2("tstX86-1: Trap #%#04x err=%#06x at %p\n", uTrapNo, uErr, *puPC);
+
+ PCTRAPINFO pTrapInfo = findTrapInfo(*puPC, *puSP);
+ if (pTrapInfo)
+ {
+ if (pTrapInfo->u8Trap != uTrapNo && uTrapNo != ~(uintptr_t)0)
+ RTAssertMsg2("tstX86-1: Expected #%#04x, got #%#04x\n", pTrapInfo->u8Trap, uTrapNo);
+ else
+ {
+ if (*puPC != pTrapInfo->uTrapPC)
+ *puSP += sizeof(uintptr_t);
+ *puPC = pTrapInfo->uResumePC;
+ return;
+ }
+ }
+ else
+ RTAssertMsg2("tstX86-1: Unexpected trap!\n");
+
+ /* die */
+ signal(iSig, SIG_IGN);
+}
+#else
+
+#endif
+
+int main()
+{
+ /*
+ * Set up the test environment.
+ */
+ RTTEST hTest;
+ RTEXITCODE rcExit = RTTestInitAndCreate("tstX86-1", &hTest);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ RTTestBanner(hTest);
+
+ g_pbEfPage = (uint8_t *)RTTestGuardedAllocTail(hTest, PAGE_SIZE);
+ RTTESTI_CHECK(g_pbEfPage != NULL);
+
+ g_pbEfExecPage = (uint8_t *)RTMemExecAlloc(PAGE_SIZE*2);
+ RTTESTI_CHECK(g_pbEfExecPage != NULL);
+ RTTESTI_CHECK(!((uintptr_t)g_pbEfExecPage & PAGE_OFFSET_MASK));
+ RTTESTI_CHECK_RC(RTMemProtect(g_pbEfExecPage + PAGE_SIZE, PAGE_SIZE, RTMEM_PROT_NONE), VINF_SUCCESS);
+
+#ifdef USE_SIGNAL
+ static int const s_aiSigs[] = { SIGBUS, SIGSEGV, SIGFPE, SIGILL };
+ for (unsigned i = 0; i < RT_ELEMENTS(s_aiSigs); i++)
+ {
+ struct sigaction SigAct;
+ RTTESTI_CHECK_BREAK(sigaction(s_aiSigs[i], NULL, &SigAct) == 0);
+ SigAct.sa_sigaction = sigHandler;
+ SigAct.sa_flags |= SA_SIGINFO;
+ RTTESTI_CHECK(sigaction(s_aiSigs[i], &SigAct, NULL) == 0);
+ }
+#else
+ /** @todo implement me. */
+#endif
+
+
+ if (!RTTestErrorCount(hTest))
+ {
+ /*
+ * Do the testing.
+ */
+ RTTestSub(hTest, "part 1");
+ int32_t rc = x861_Test1();
+ if (rc != 0)
+ RTTestFailed(hTest, "x861_Test1 -> %d", rc);
+ }
+
+ return RTTestSummaryAndDestroy(hTest);
+}
+
diff --git a/src/VBox/VMM/testcase/tstX86-1A.asm b/src/VBox/VMM/testcase/tstX86-1A.asm
new file mode 100644
index 000000000..191a643e9
--- /dev/null
+++ b/src/VBox/VMM/testcase/tstX86-1A.asm
@@ -0,0 +1,588 @@
+; $Id: tstX86-1A.asm 37955 2011-07-14 12:23:02Z vboxsync $
+;; @file
+; X86 instruction set testcase #1.
+;
+
+;
+; 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/asmdefs.mac"
+%include "iprt/x86.mac"
+
+;; @todo Move this to a header?
+struc TRAPINFO
+ .uTrapPC RTCCPTR_RES 1
+ .uResumePC RTCCPTR_RES 1
+ .u8TrapNo resb 1
+ .cbInstr resb 1
+ .au8Padding resb (RTCCPTR_CB*2 - 2)
+endstruc
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Global Variables ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+BEGINDATA
+extern NAME(g_pbEfPage)
+extern NAME(g_pbEfExecPage)
+
+GLOBALNAME g_szAlpha
+ db "abcdefghijklmnopqrstuvwxyz", 0
+g_szAlpha_end:
+%define g_cchAlpha (g_szAlpha_end - NAME(g_szAlpha))
+ db 0, 0, 0,
+
+;;
+; The last global data item. We build this as we write the code.
+GLOBALNAME g_aTrapInfo
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Defined Constants And Macros ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+%define X86_XCPT_UD 6
+%define X86_XCPT_GP 13
+%define X86_XCPT_PF 14
+
+;; Reference a global variable
+%ifdef RT_ARCH_AMD64
+ %define REF_GLOBAL(a_Name) [NAME(a_Name) wrt rip]
+%else
+ %define REF_GLOBAL(a_Name) [NAME(a_Name)]
+%endif
+
+;;
+; Macro for recording a trapping instruction (simple).
+;
+; @param 1 The trap number.
+; @param 2+ The instruction which should trap.
+%macro ShouldTrap 2+
+%%trap:
+ %2
+%%trap_end:
+ mov eax, __LINE__
+ jmp .failed
+BEGINDATA
+%%trapinfo: istruc TRAPINFO
+ at TRAPINFO.uTrapPC, RTCCPTR_DEF %%trap
+ at TRAPINFO.uResumePC, RTCCPTR_DEF %%resume
+ at TRAPINFO.u8TrapNo, db %1
+ at TRAPINFO.cbInstr, db (%%trap_end - %%trap)
+iend
+BEGINCODE
+%%resume:
+%endmacro
+
+
+
+BEGINCODE
+
+;;
+; Loads all general registers except xBP and xSP with unique values.
+;
+x861_LoadUniqueRegValues:
+%ifdef RT_ARCH_AMD64
+ mov rax, 00000000000000000h
+ mov rcx, 01111111111111111h
+ mov rdx, 02222222222222222h
+ mov rbx, 03333333333333333h
+ mov rsi, 06666666666666666h
+ mov rdi, 07777777777777777h
+ mov r8, 08888888888888888h
+ mov r9, 09999999999999999h
+ mov r10, 0aaaaaaaaaaaaaaaah
+ mov r11, 0bbbbbbbbbbbbbbbbh
+ mov r12, 0cccccccccccccccch
+ mov r13, 0ddddddddddddddddh
+ mov r14, 0eeeeeeeeeeeeeeeeh
+ mov r15, 0ffffffffffffffffh
+%else
+ mov eax, 000000000h
+ mov ecx, 011111111h
+ mov edx, 022222222h
+ mov ebx, 033333333h
+ mov esi, 066666666h
+ mov edi, 077777777h
+%endif
+ ret
+; end x861_LoadUniqueRegValues
+
+
+;;
+; Clears all general registers except xBP and xSP.
+;
+x861_ClearRegisters:
+ xor eax, eax
+ xor ebx, ebx
+ xor ecx, ecx
+ xor edx, edx
+ xor esi, esi
+ xor edi, edi
+%ifdef RT_ARCH_AMD64
+ xor r8, r8
+ xor r9, r9
+ xor r10, r10
+ xor r11, r11
+ xor r12, r12
+ xor r13, r13
+ xor r14, r14
+ xor r15, r15
+%endif
+ ret
+; x861_ClearRegisters
+
+
+BEGINPROC x861_Test1
+ push xBP
+ mov xBP, xSP
+ pushf
+ push xBX
+ push xCX
+ push xDX
+ push xSI
+ push xDI
+%ifdef RT_ARCH_AMD64
+ push r8
+ push r9
+ push r10
+ push r11
+ push r12
+ push r13
+ push r14
+ push r15
+%endif
+
+ ;
+ ; Odd push behavior
+ ;
+%if 0 ; Seems to be so on AMD only
+%ifdef RT_ARCH_X86
+ ; upper word of a 'push cs' is cleared.
+ mov eax, __LINE__
+ mov dword [esp - 4], 0f0f0f0fh
+ push cs
+ pop ecx
+ mov bx, cs
+ and ebx, 0000ffffh
+ cmp ecx, ebx
+ jne .failed
+
+ ; upper word of a 'push ds' is cleared.
+ mov eax, __LINE__
+ mov dword [esp - 4], 0f0f0f0fh
+ push ds
+ pop ecx
+ mov bx, ds
+ and ebx, 0000ffffh
+ cmp ecx, ebx
+ jne .failed
+
+ ; upper word of a 'push es' is cleared.
+ mov eax, __LINE__
+ mov dword [esp - 4], 0f0f0f0fh
+ push es
+ pop ecx
+ mov bx, es
+ and ebx, 0000ffffh
+ cmp ecx, ebx
+ jne .failed
+%endif ; RT_ARCH_X86
+
+ ; The upper part of a 'push fs' is cleared.
+ mov eax, __LINE__
+ xor ecx, ecx
+ not xCX
+ push xCX
+ pop xCX
+ push fs
+ pop xCX
+ mov bx, fs
+ and ebx, 0000ffffh
+ cmp xCX, xBX
+ jne .failed
+
+ ; The upper part of a 'push gs' is cleared.
+ mov eax, __LINE__
+ xor ecx, ecx
+ not xCX
+ push xCX
+ pop xCX
+ push gs
+ pop xCX
+ mov bx, gs
+ and ebx, 0000ffffh
+ cmp xCX, xBX
+ jne .failed
+%endif
+
+%ifdef RT_ARCH_AMD64
+ ; REX.B works with 'push r64'.
+ call x861_LoadUniqueRegValues
+ mov eax, __LINE__
+ push rcx
+ pop rdx
+ cmp rdx, rcx
+ jne .failed
+
+ call x861_LoadUniqueRegValues
+ mov eax, __LINE__
+ db 041h ; REX.B
+ push rcx
+ pop rdx
+ cmp rdx, r9
+ jne .failed
+
+ call x861_LoadUniqueRegValues
+ mov eax, __LINE__
+ db 042h ; REX.X
+ push rcx
+ pop rdx
+ cmp rdx, rcx
+ jne .failed
+
+ call x861_LoadUniqueRegValues
+ mov eax, __LINE__
+ db 044h ; REX.R
+ push rcx
+ pop rdx
+ cmp rdx, rcx
+ jne .failed
+
+ call x861_LoadUniqueRegValues
+ mov eax, __LINE__
+ db 048h ; REX.W
+ push rcx
+ pop rdx
+ cmp rdx, rcx
+ jne .failed
+
+ call x861_LoadUniqueRegValues
+ mov eax, __LINE__
+ db 04fh ; REX.*
+ push rcx
+ pop rdx
+ cmp rdx, r9
+ jne .failed
+%endif
+
+ ;
+ ; Zero extening when moving from a segreg as well as memory access sizes.
+ ;
+ call x861_LoadUniqueRegValues
+ mov eax, __LINE__
+ mov ecx, ds
+ shr xCX, 16
+ cmp xCX, 0
+ jnz .failed
+
+%ifdef RT_ARCH_AMD64
+ call x861_LoadUniqueRegValues
+ mov eax, __LINE__
+ mov rcx, ds
+ shr rcx, 16
+ cmp rcx, 0
+ jnz .failed
+%endif
+
+ call x861_LoadUniqueRegValues
+ mov eax, __LINE__
+ mov xDX, xCX
+ mov cx, ds
+ shr xCX, 16
+ shr xDX, 16
+ cmp xCX, xDX
+ jnz .failed
+
+ ; Loading is always a word access.
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfPage)
+ lea xDI, [xDI + 0x1000 - 2]
+ mov xDX, es
+ mov [xDI], dx
+ mov es, [xDI] ; should not crash
+
+ ; Saving is always a word access.
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfPage)
+ mov dword [xDI + 0x1000 - 4], -1
+ mov [xDI + 0x1000 - 2], ss ; Should not crash.
+ mov bx, ss
+ mov cx, [xDI + 0x1000 - 2]
+ cmp cx, bx
+ jne .failed
+
+%ifdef RT_ARCH_AMD64
+ ; Check that the rex.R and rex.W bits don't have any influence over a memory write.
+ call x861_ClearRegisters
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfPage)
+ mov dword [xDI + 0x1000 - 4], -1
+ db 04ah
+ mov [xDI + 0x1000 - 2], ss ; Should not crash.
+ mov bx, ss
+ mov cx, [xDI + 0x1000 - 2]
+ cmp cx, bx
+ jne .failed
+%endif
+
+
+ ;
+ ; Check what happens when both string prefixes are used.
+ ;
+ cld
+ mov dx, ds
+ mov es, dx
+
+ ; check that repne scasb (al=0) behaves like expected.
+ lea xDI, REF_GLOBAL(g_szAlpha)
+ xor eax, eax ; find the end
+ mov ecx, g_cchAlpha + 1
+ repne scasb
+ cmp ecx, 1
+ mov eax, __LINE__
+ jne .failed
+
+ ; check that repe scasb (al=0) behaves like expected.
+ lea xDI, REF_GLOBAL(g_szAlpha)
+ xor eax, eax ; find the end
+ mov ecx, g_cchAlpha + 1
+ repe scasb
+ cmp ecx, g_cchAlpha
+ mov eax, __LINE__
+ jne .failed
+
+ ; repne is last, it wins.
+ lea xDI, REF_GLOBAL(g_szAlpha)
+ xor eax, eax ; find the end
+ mov ecx, g_cchAlpha + 1
+ db 0f3h ; repe - ignored
+ db 0f2h ; repne
+ scasb
+ cmp ecx, 1
+ mov eax, __LINE__
+ jne .failed
+
+ ; repe is last, it wins.
+ lea xDI, REF_GLOBAL(g_szAlpha)
+ xor eax, eax ; find the end
+ mov ecx, g_cchAlpha + 1
+ db 0f2h ; repne - ignored
+ db 0f3h ; repe
+ scasb
+ cmp ecx, g_cchAlpha
+ mov eax, __LINE__
+ jne .failed
+
+ ;
+ ; Check if stosb works with both prefixes.
+ ;
+ cld
+ mov dx, ds
+ mov es, dx
+ mov xDI, REF_GLOBAL(g_pbEfPage)
+ xor eax, eax
+ mov ecx, 01000h
+ rep stosb
+
+ mov xDI, REF_GLOBAL(g_pbEfPage)
+ mov ecx, 4
+ mov eax, 0ffh
+ db 0f2h ; repne
+ stosb
+ mov eax, __LINE__
+ cmp ecx, 0
+ jne .failed
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfPage)
+ cmp dword [xDI], 0ffffffffh
+ jne .failed
+ cmp dword [xDI+4], 0
+ jne .failed
+
+ mov xDI, REF_GLOBAL(g_pbEfPage)
+ mov ecx, 4
+ mov eax, 0feh
+ db 0f3h ; repe
+ stosb
+ mov eax, __LINE__
+ cmp ecx, 0
+ jne .failed
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfPage)
+ cmp dword [xDI], 0fefefefeh
+ jne .failed
+ cmp dword [xDI+4], 0
+ jne .failed
+
+ ;
+ ; String operations shouldn't crash because of an invalid address if rCX is 0.
+ ;
+ mov eax, __LINE__
+ cld
+ mov dx, ds
+ mov es, dx
+ mov xDI, REF_GLOBAL(g_pbEfPage)
+ xor xCX, xCX
+ rep stosb ; no trap
+
+ ;
+ ; INS/OUTS will trap in ring-3 even when rCX is 0. (ASSUMES IOPL < 3)
+ ;
+ mov eax, __LINE__
+ cld
+ mov dx, ss
+ mov ss, dx
+ mov xDI, xSP
+ xor xCX, xCX
+ ShouldTrap X86_XCPT_GP, rep insb
+
+ ;
+ ; SMSW can get to the whole of CR0.
+ ;
+ mov eax, __LINE__
+ xor xBX, xBX
+ smsw xBX
+ test ebx, X86_CR0_PG
+ jz .failed
+ test ebx, X86_CR0_PE
+ jz .failed
+
+ ;
+ ; Will the CPU decode the whole r/m+sib stuff before signalling a lock
+ ; prefix error? Use the EF exec page and a LOCK ADD CL,[rDI + disp32]
+ ; instruction at the very end of it.
+ ;
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfExecPage)
+ add xDI, 1000h - 8h
+ mov byte [xDI+0], 0f0h
+ mov byte [xDI+1], 002h
+ mov byte [xDI+2], 08fh
+ mov dword [xDI+3], 000000000h
+ mov byte [xDI+7], 0cch
+ ShouldTrap X86_XCPT_UD, call xDI
+
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfExecPage)
+ add xDI, 1000h - 7h
+ mov byte [xDI+0], 0f0h
+ mov byte [xDI+1], 002h
+ mov byte [xDI+2], 08Fh
+ mov dword [xDI+3], 000000000h
+ ShouldTrap X86_XCPT_UD, call xDI
+
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfExecPage)
+ add xDI, 1000h - 4h
+ mov byte [xDI+0], 0f0h
+ mov byte [xDI+1], 002h
+ mov byte [xDI+2], 08Fh
+ mov byte [xDI+3], 000h
+ ShouldTrap X86_XCPT_PF, call xDI
+
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfExecPage)
+ add xDI, 1000h - 6h
+ mov byte [xDI+0], 0f0h
+ mov byte [xDI+1], 002h
+ mov byte [xDI+2], 08Fh
+ mov byte [xDI+3], 00h
+ mov byte [xDI+4], 00h
+ mov byte [xDI+5], 00h
+ ShouldTrap X86_XCPT_PF, call xDI
+
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfExecPage)
+ add xDI, 1000h - 5h
+ mov byte [xDI+0], 0f0h
+ mov byte [xDI+1], 002h
+ mov byte [xDI+2], 08Fh
+ mov byte [xDI+3], 00h
+ mov byte [xDI+4], 00h
+ ShouldTrap X86_XCPT_PF, call xDI
+
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfExecPage)
+ add xDI, 1000h - 4h
+ mov byte [xDI+0], 0f0h
+ mov byte [xDI+1], 002h
+ mov byte [xDI+2], 08Fh
+ mov byte [xDI+3], 00h
+ ShouldTrap X86_XCPT_PF, call xDI
+
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfExecPage)
+ add xDI, 1000h - 3h
+ mov byte [xDI+0], 0f0h
+ mov byte [xDI+1], 002h
+ mov byte [xDI+2], 08Fh
+ ShouldTrap X86_XCPT_PF, call xDI
+
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfExecPage)
+ add xDI, 1000h - 2h
+ mov byte [xDI+0], 0f0h
+ mov byte [xDI+1], 002h
+ ShouldTrap X86_XCPT_PF, call xDI
+
+ mov eax, __LINE__
+ mov xDI, REF_GLOBAL(g_pbEfExecPage)
+ add xDI, 1000h - 1h
+ mov byte [xDI+0], 0f0h
+ ShouldTrap X86_XCPT_PF, call xDI
+
+
+
+.success:
+ xor eax, eax
+.return:
+%ifdef RT_ARCH_AMD64
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+%endif
+ pop xDI
+ pop xSI
+ pop xDX
+ pop xCX
+ pop xBX
+ popf
+ leave
+ ret
+
+.failed2:
+ mov eax, -1
+.failed:
+ jmp .return
+ENDPROC x861_Test1
+
+
+;;
+; Terminate the trap info array with a NIL entry.
+BEGINDATA
+GLOBALNAME g_aTrapInfoEnd
+istruc TRAPINFO
+ at TRAPINFO.uTrapPC, RTCCPTR_DEF 0
+ at TRAPINFO.uResumePC, RTCCPTR_DEF 0
+ at TRAPINFO.u8TrapNo, db 0
+ at TRAPINFO.cbInstr, db 0
+iend
+
diff --git a/src/apps/Makefile.kmk b/src/apps/Makefile.kmk
index 9185c0b59..8af2b784e 100644
--- a/src/apps/Makefile.kmk
+++ b/src/apps/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for the external apps.
#
diff --git a/src/apps/adpctl/Makefile.kmk b/src/apps/adpctl/Makefile.kmk
index 27e4d9a3e..2da986505 100644
--- a/src/apps/adpctl/Makefile.kmk
+++ b/src/apps/adpctl/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for VBoxAdpCtl
#
diff --git a/src/apps/adpctl/VBoxNetAdpCtl.cpp b/src/apps/adpctl/VBoxNetAdpCtl.cpp
index b0c2c9d18..f0de042b3 100644
--- a/src/apps/adpctl/VBoxNetAdpCtl.cpp
+++ b/src/apps/adpctl/VBoxNetAdpCtl.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetAdpCtl.cpp $ */
+/* $Id: VBoxNetAdpCtl.cpp 35819 2011-02-01 20:21:53Z vboxsync $ */
/** @file
* Apps - VBoxAdpCtl, Configuration tool for vboxnetX adapters.
*/
@@ -178,18 +178,22 @@ static bool removeAddresses(char *pszAdapterName)
return true;
}
-int doIOCtl(unsigned long uCmd, void *pData)
+static int doIOCtl(unsigned long uCmd, VBOXNETADPREQ *pReq)
{
int fd = open(VBOXNETADP_CTL_DEV_NAME, O_RDWR);
if (fd == -1)
{
- perror("VBoxNetAdpCtl: failed to open " VBOXNETADP_CTL_DEV_NAME);
+ fprintf(stderr, "VBoxNetAdpCtl: Error while %s '%s': ",
+ uCmd == VBOXNETADP_CTL_REMOVE ? "removing" : "adding", pReq->szName);
+ perror("failed to open " VBOXNETADP_CTL_DEV_NAME);
return ADPCTLERR_NO_CTL_DEV;
}
- int rc = ioctl(fd, uCmd, pData);
+ int rc = ioctl(fd, uCmd, pReq);
if (rc == -1)
{
+ fprintf(stderr, "VBoxNetAdpCtl: Error while %s '%s': ",
+ uCmd == VBOXNETADP_CTL_REMOVE ? "removing" : "adding", pReq->szName);
perror("VBoxNetAdpCtl: ioctl failed for " VBOXNETADP_CTL_DEV_NAME);
rc = ADPCTLERR_IOCTL_FAILED;
}
@@ -199,7 +203,7 @@ int doIOCtl(unsigned long uCmd, void *pData)
return rc;
}
-int checkAdapterName(const char *pcszNameIn, char *pszNameOut)
+static int checkAdapterName(const char *pcszNameIn, char *pszNameOut)
{
int iAdapterIndex = -1;
@@ -207,13 +211,13 @@ int checkAdapterName(const char *pcszNameIn, char *pszNameOut)
|| sscanf(pcszNameIn, "vboxnet%d", &iAdapterIndex) != 1
|| iAdapterIndex < 0 || iAdapterIndex > 99 )
{
- fprintf(stderr, "Setting configuration for %s is not supported.\n", pcszNameIn);
+ fprintf(stderr, "VBoxNetAdpCtl: Setting configuration for '%s' is not supported.\n", pcszNameIn);
return ADPCTLERR_BAD_NAME;
}
sprintf(pszNameOut, "vboxnet%d", iAdapterIndex);
if (strcmp(pszNameOut, pcszNameIn))
{
- fprintf(stderr, "Invalid adapter name %s.\n", pcszNameIn);
+ fprintf(stderr, "VBoxNetAdpCtl: Invalid adapter name '%s'.\n", pcszNameIn);
return ADPCTLERR_BAD_NAME;
}
@@ -221,7 +225,6 @@ int checkAdapterName(const char *pcszNameIn, char *pszNameOut)
}
int main(int argc, char *argv[])
-
{
char szAdapterName[VBOXNETADP_MAX_NAME_LEN];
char *pszAdapterName = NULL;
diff --git a/src/apps/svnsync-vbox/Makefile.kmk b/src/apps/svnsync-vbox/Makefile.kmk
index 52d2578aa..1b4b9d595 100644
--- a/src/apps/svnsync-vbox/Makefile.kmk
+++ b/src/apps/svnsync-vbox/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 31666 2010-08-13 15:55:20Z vboxsync $
## @file
# Sub-Makefile for svnsync-vbox.
#
diff --git a/src/apps/svnsync-vbox/main.c b/src/apps/svnsync-vbox/main.c
index e94893e72..968d25d4e 100644
--- a/src/apps/svnsync-vbox/main.c
+++ b/src/apps/svnsync-vbox/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c $ */
+/* $Id: main.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* svnsync tool. Modified by Oracle.
*/
diff --git a/src/apps/svnsync-vbox/svn_private_config.h b/src/apps/svnsync-vbox/svn_private_config.h
index 37128777f..f912682e2 100644
--- a/src/apps/svnsync-vbox/svn_private_config.h
+++ b/src/apps/svnsync-vbox/svn_private_config.h
@@ -1,4 +1,4 @@
-/* $Id: svn_private_config.h $ */
+/* $Id: svn_private_config.h 29684 2010-05-20 11:30:05Z vboxsync $ */
/** @file
*
*/
diff --git a/src/apps/tunctl/Makefile.kmk b/src/apps/tunctl/Makefile.kmk
index 63ff5dda2..dd288b31e 100644
--- a/src/apps/tunctl/Makefile.kmk
+++ b/src/apps/tunctl/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for VBoxTunctl
#
diff --git a/src/bldprogs/Makefile.kmk b/src/bldprogs/Makefile.kmk
index b4fd13932..7811bdafc 100644
--- a/src/bldprogs/Makefile.kmk
+++ b/src/bldprogs/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 34484 2010-11-29 17:45:20Z vboxsync $
## @file
# Sub-Makefile for various generic build tools (there is currently only one of them).
#
diff --git a/src/bldprogs/bin2c.c b/src/bldprogs/bin2c.c
index a0a973ce8..d30fe4fcd 100644
--- a/src/bldprogs/bin2c.c
+++ b/src/bldprogs/bin2c.c
@@ -1,4 +1,4 @@
-/* $Id: bin2c.c $ */
+/* $Id: bin2c.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* bin2c - Binary 2 C Structure Converter.
*/
diff --git a/src/bldprogs/biossums.c b/src/bldprogs/biossums.c
index e179f6493..063d02368 100644
--- a/src/bldprogs/biossums.c
+++ b/src/bldprogs/biossums.c
@@ -1,4 +1,4 @@
-/* $Id: biossums.c $ */
+/* $Id: biossums.c 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Tool for modifying a BIOS image to write the BIOS checksum.
*/
diff --git a/src/bldprogs/checkUndefined.sh b/src/bldprogs/checkUndefined.sh
index 16a5a463e..16a5a463e 100755..100644
--- a/src/bldprogs/checkUndefined.sh
+++ b/src/bldprogs/checkUndefined.sh
diff --git a/src/bldprogs/deftoimp.sed b/src/bldprogs/deftoimp.sed
index 56b4de322..be5fbe268 100644
--- a/src/bldprogs/deftoimp.sed
+++ b/src/bldprogs/deftoimp.sed
@@ -1,4 +1,4 @@
-# $Id: deftoimp.sed $
+# $Id: deftoimp.sed 34662 2010-12-02 21:51:17Z vboxsync $
## @file
# SED script for generating a dummy .c from a windows .def file.
#
diff --git a/src/bldprogs/filesplitter.cpp b/src/bldprogs/filesplitter.cpp
index 65e7450a5..1c54857bf 100644
--- a/src/bldprogs/filesplitter.cpp
+++ b/src/bldprogs/filesplitter.cpp
@@ -78,7 +78,7 @@ int main(int argc, char *argv[])
break;
}
- if (fread(pBuffer, 1, lStat.st_size, pFileIn) != lStat.st_size)
+ if (fread(pBuffer, 1, lStat.st_size, pFileIn) != (size_t)lStat.st_size)
{
fprintf(stderr, "filesplitter: Failed to read %ld bytes from input file.\n", (long)lStat.st_size);
rc = 2;
diff --git a/src/bldprogs/preload.cpp b/src/bldprogs/preload.cpp
index 07def9a04..0ec2e0f29 100644
--- a/src/bldprogs/preload.cpp
+++ b/src/bldprogs/preload.cpp
@@ -1,4 +1,4 @@
-/* $Id: preload.cpp $ */
+/* $Id: preload.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* bin2c - Binary 2 C Structure Converter.
*/
@@ -146,7 +146,7 @@ int main(int argc, char **argv)
if ( !strcmp(argv[i], "--version")
|| !strcmp(argv[i], "-V"))
{
- printf("$Revision: 60692 $\n");
+ printf("$Revision: 28800 $\n");
return 0;
}
fprintf(stderr, "syntax error: unknown option '%s'\n", argv[i]);
diff --git a/src/bldprogs/scm.cpp b/src/bldprogs/scm.cpp
index 261980fbe..fbf2283f6 100644
--- a/src/bldprogs/scm.cpp
+++ b/src/bldprogs/scm.cpp
@@ -1,4 +1,4 @@
-/* $Id: scm.cpp $ */
+/* $Id: scm.cpp 35404 2011-01-05 11:32:29Z vboxsync $ */
/** @file
* IPRT Testcase / Tool - Source Code Massager.
*/
@@ -4090,7 +4090,7 @@ int main(int argc, char **argv)
case 'V':
{
/* The following is assuming that svn does it's job here. */
- static const char s_szRev[] = "$Revision: 69268 $";
+ static const char s_szRev[] = "$Revision: 35404 $";
const char *psz = RTStrStripL(strchr(s_szRev, ' '));
RTPrintf("r%.*s\n", strchr(psz, ' ') - psz, psz);
return 0;
diff --git a/src/libs/Makefile.kmk b/src/libs/Makefile.kmk
index 31d5c9c83..0a7b08c25 100644
--- a/src/libs/Makefile.kmk
+++ b/src/libs/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 36126 2011-03-01 17:26:15Z vboxsync $
## @file
# Top-level makefile for the external libraries.
#
diff --git a/src/libs/kStuff/Makefile.kmk b/src/libs/kStuff/Makefile.kmk
index 93d299500..0ed8fb193 100644
--- a/src/libs/kStuff/Makefile.kmk
+++ b/src/libs/kStuff/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for kStuff, for statically linking into VBoxRT.
#
diff --git a/src/libs/kStuff/iprt/kHlpAlloc-iprt.cpp b/src/libs/kStuff/iprt/kHlpAlloc-iprt.cpp
index 6684bf33e..b4cf74cf9 100644
--- a/src/libs/kStuff/iprt/kHlpAlloc-iprt.cpp
+++ b/src/libs/kStuff/iprt/kHlpAlloc-iprt.cpp
@@ -1,4 +1,4 @@
-/* $Id: kHlpAlloc-iprt.cpp $ */
+/* $Id: kHlpAlloc-iprt.cpp 35288 2010-12-22 09:14:54Z vboxsync $ */
/** @file
* kHlpAlloc - Memory Allocation, IPRT based implementation.
*/
diff --git a/src/libs/kStuff/iprt/kHlpAssert-iprt.cpp b/src/libs/kStuff/iprt/kHlpAssert-iprt.cpp
index 406bc3e85..2faf3b64c 100644
--- a/src/libs/kStuff/iprt/kHlpAssert-iprt.cpp
+++ b/src/libs/kStuff/iprt/kHlpAssert-iprt.cpp
@@ -1,4 +1,4 @@
-/* $Id: kHlpAssert-iprt.cpp $ */
+/* $Id: kHlpAssert-iprt.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* kHlpEnv - Assertions, IPRT based implementation.
*/
diff --git a/src/libs/kStuff/iprt/kHlpEnv-iprt.cpp b/src/libs/kStuff/iprt/kHlpEnv-iprt.cpp
index 17661ca7c..b2119f771 100644
--- a/src/libs/kStuff/iprt/kHlpEnv-iprt.cpp
+++ b/src/libs/kStuff/iprt/kHlpEnv-iprt.cpp
@@ -1,4 +1,4 @@
-/* $Id: kHlpEnv-iprt.cpp $ */
+/* $Id: kHlpEnv-iprt.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* kHlpEnv - Environment Manipulation, IPRT based implementation.
*/
diff --git a/src/libs/kStuff/iprt/kHlpPage-iprt.cpp b/src/libs/kStuff/iprt/kHlpPage-iprt.cpp
index b808d9978..2372d343d 100644
--- a/src/libs/kStuff/iprt/kHlpPage-iprt.cpp
+++ b/src/libs/kStuff/iprt/kHlpPage-iprt.cpp
@@ -1,4 +1,4 @@
-/* $Id: kHlpPage-iprt.cpp $ */
+/* $Id: kHlpPage-iprt.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* kHlpPage - Page Memory Allocation, IPRT based implementation.
*/
diff --git a/src/libs/kStuff/iprt/kHlpString-iprt.cpp b/src/libs/kStuff/iprt/kHlpString-iprt.cpp
index 0c74fa55a..6ecffb6c7 100644
--- a/src/libs/kStuff/iprt/kHlpString-iprt.cpp
+++ b/src/libs/kStuff/iprt/kHlpString-iprt.cpp
@@ -1,4 +1,4 @@
-/* $Id: kHlpString-iprt.cpp $ */
+/* $Id: kHlpString-iprt.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* kHlpString - String And Memory Routines, IPRT based implementation.
*/
diff --git a/src/libs/kStuff/iprt/kRdrFile-iprt.cpp b/src/libs/kStuff/iprt/kRdrFile-iprt.cpp
index 2d8907332..697bf1594 100644
--- a/src/libs/kStuff/iprt/kRdrFile-iprt.cpp
+++ b/src/libs/kStuff/iprt/kRdrFile-iprt.cpp
@@ -1,4 +1,4 @@
-/* $Id: kRdrFile-iprt.cpp $ */
+/* $Id: kRdrFile-iprt.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT - kRdr Backend.
*/
diff --git a/src/libs/liblzf-3.4/Makefile.kmk b/src/libs/liblzf-3.4/Makefile.kmk
index afa08fd25..44088fad0 100644
--- a/src/libs/liblzf-3.4/Makefile.kmk
+++ b/src/libs/liblzf-3.4/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 32382 2010-09-10 09:53:03Z vboxsync $
## @file
# Sub-Makefile for liblzf.
#
diff --git a/src/libs/xpcom18a4/Config.kmk b/src/libs/xpcom18a4/Config.kmk
index a892ebecc..c2e646d0a 100644
--- a/src/libs/xpcom18a4/Config.kmk
+++ b/src/libs/xpcom18a4/Config.kmk
@@ -1,4 +1,4 @@
-# $Id: Config.kmk $
+# $Id: Config.kmk 35440 2011-01-09 23:43:10Z vboxsync $
## @file
# XPCOM kBuild Configuration file.
#
diff --git a/src/libs/xpcom18a4/Makefile.kmk b/src/libs/xpcom18a4/Makefile.kmk
index 1dd0f62ad..97e19efe2 100644
--- a/src/libs/xpcom18a4/Makefile.kmk
+++ b/src/libs/xpcom18a4/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37998 2011-07-18 10:14:13Z vboxsync $
## @file
# Sub-Makefile for XPCOM.
#
@@ -239,7 +239,7 @@ NSPRPUB-PRIV-HEADERS_SOURCES = \
nsprpub/pr/include/private/pprthred.h \
nsprpub/pr/include/private/prpriv.h
-STRING-HEADERS_INST = $(INST_SDK)bindings/xpcom/include/string
+STRING-HEADERS_INST = $(INST_SDK)bindings/xpcom/include/string/
STRING-HEADERS_IFFLAGS = -m 644
STRING-HEADERS_SOURCES = \
xpcom/string/public/nsAString.h \
@@ -273,7 +273,7 @@ STRING-HEADERS_SOURCES = \
xpcom/string/public/string-template-def-unichar.h \
xpcom/string/public/string-template-undef.h
-XPCOM-HEADERS_INST = $(INST_SDK)bindings/xpcom/include/xpcom
+XPCOM-HEADERS_INST = $(INST_SDK)bindings/xpcom/include/xpcom/
XPCOM-HEADERS_IFFLAGS = -m 644
XPCOM-HEADERS_SOURCES = \
xpcom/base/nsAgg.h \
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp b/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp
index 05aa2e909..7763a1c58 100644
--- a/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp
@@ -2221,7 +2221,7 @@ ipcDConnectService::DeserializeException(ipcMessageReader &reader,
DConnectStub::~DConnectStub()
{
#ifdef IPC_LOGGING
- const char *name;
+ const char *name = NULL;
mIInfo->GetNameShared(&name);
LOG(("{%p} DConnectStub::<dtor>(): peer=%d instance=0x%Lx {%s}\n",
this, mPeerID, mInstance, name));
diff --git a/src/libs/xpcom18a4/java/Makefile.kmk b/src/libs/xpcom18a4/java/Makefile.kmk
index c90438344..e27e068a9 100644
--- a/src/libs/xpcom18a4/java/Makefile.kmk
+++ b/src/libs/xpcom18a4/java/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 32229 2010-09-03 07:38:52Z vboxsync $
## @file
# Sub-Makefile for Java bindings
#
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxy.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxy.java
index 9c6c74708..c6485708e 100644
--- a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxy.java
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxy.java
@@ -255,4 +255,3 @@ public class XPCOMJavaProxy implements InvocationHandler {
String aMethodName, Object[] aParams);
}
-
diff --git a/src/libs/xpcom18a4/java/src/org/virtualbox/VBoxObjectBase.java b/src/libs/xpcom18a4/java/src/org/virtualbox/VBoxObjectBase.java
index 7a01dd48d..4e3fda9a5 100644
--- a/src/libs/xpcom18a4/java/src/org/virtualbox/VBoxObjectBase.java
+++ b/src/libs/xpcom18a4/java/src/org/virtualbox/VBoxObjectBase.java
@@ -1,4 +1,4 @@
-/* $Id: VBoxObjectBase.java $ */
+/* $Id: VBoxObjectBase.java 29233 2010-05-07 19:52:15Z vboxsync $ */
/*
* Copyright (C) 2010 Oracle Corporation
*
diff --git a/src/libs/xpcom18a4/java/src/org/virtualbox/VirtualBoxManager.java b/src/libs/xpcom18a4/java/src/org/virtualbox/VirtualBoxManager.java
deleted file mode 100644
index 0db4f020e..000000000
--- a/src/libs/xpcom18a4/java/src/org/virtualbox/VirtualBoxManager.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/* $Id: VirtualBoxManager.java $ */
-/*
- * Copyright (C) 2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-package org.virtualbox;
-
-import java.io.File;
-
-import org.mozilla.xpcom.*;
-import org.mozilla.interfaces.*;
-
-public class VirtualBoxManager
-{
- private Mozilla mozilla;
- private IVirtualBox vbox;
- private nsIComponentManager componentManager;
- private nsIServiceManager servMgr;
-
- private VirtualBoxManager(Mozilla mozilla,nsIServiceManager servMgr)
- {
- this.mozilla = mozilla;
- this.servMgr = servMgr;
- this.componentManager = mozilla.getComponentManager();
- this.vbox = (IVirtualBox) this.componentManager
- .createInstanceByContractID("@virtualbox.org/VirtualBox;1",
- null,
- IVirtualBox.IVIRTUALBOX_IID);
- if (this.vbox == null) {
- throw new RuntimeException("Failed to create IVirtualBox");
- }
- }
-
- public IVirtualBox getVBox()
- {
- return this.vbox;
- }
-
- public ISession makeSession()
- {
- return (ISession) componentManager
- .createInstanceByContractID("@virtualbox.org/Session;1", null,
- ISession.ISESSION_IID);
- }
-
-
- private static VirtualBoxManager mgr;
-
- public static synchronized VirtualBoxManager getInstance(String home)
- {
- if (mgr != null)
- return mgr;
-
- if (home == null)
- home = System.getProperty("vbox.home");
-
- File grePath = new File(home);
- Mozilla mozilla = Mozilla.getInstance();
- mozilla.initialize(grePath);
- nsIServiceManager servMgr = null;
- try {
- servMgr = mozilla.initXPCOM(grePath, null);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
-
- mgr = new VirtualBoxManager(mozilla, servMgr);
- return mgr;
- }
-
- public void cleanup()
- {
- // cleanup
- mozilla.shutdownXPCOM(servMgr);
- mozilla = null;
- }
-
- public boolean progressBar(IProgress p, int wait)
- {
- long end = System.currentTimeMillis() + wait;
- while (!p.getCompleted())
- {
- mozilla.waitForEvents(0);
- p.waitForCompletion(wait);
- if (System.currentTimeMillis() >= end)
- return false;
- }
-
- return true;
- }
-
- public boolean startVm(String name, String type, int timeout)
- {
- IMachine m = vbox.findMachine(name);
- if (m == null)
- return false;
- ISession session = makeSession();
-
-
- if (type == null)
- type = "gui";
- IProgress p = m.openRemoteSession(session, type, "");
- progressBar(p, timeout);
- session.close();
- return true;
- }
-
- public Mozilla getMozilla()
- {
- return mozilla;
- }
-
- public void waitForEvents(long tmo)
- {
- mozilla.waitForEvents(tmo);
- }
-}
diff --git a/src/libs/xpcom18a4/java/tools/gen-nsError.pl b/src/libs/xpcom18a4/java/tools/gen-nsError.pl
index da866b83b..da866b83b 100755..100644
--- a/src/libs/xpcom18a4/java/tools/gen-nsError.pl
+++ b/src/libs/xpcom18a4/java/tools/gen-nsError.pl
diff --git a/src/libs/xpcom18a4/nsprpub/Makefile.in b/src/libs/xpcom18a4/nsprpub/Makefile.in
index 9273b16db..9273b16db 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/Makefile.in
+++ b/src/libs/xpcom18a4/nsprpub/Makefile.in
diff --git a/src/libs/xpcom18a4/nsprpub/admin/explode.pl b/src/libs/xpcom18a4/nsprpub/admin/explode.pl
index 881f21b9b..881f21b9b 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/admin/explode.pl
+++ b/src/libs/xpcom18a4/nsprpub/admin/explode.pl
diff --git a/src/libs/xpcom18a4/nsprpub/admin/makeTargetDirs.sh b/src/libs/xpcom18a4/nsprpub/admin/makeTargetDirs.sh
index 4250ce4a0..4250ce4a0 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/admin/makeTargetDirs.sh
+++ b/src/libs/xpcom18a4/nsprpub/admin/makeTargetDirs.sh
diff --git a/src/libs/xpcom18a4/nsprpub/admin/repackage.sh b/src/libs/xpcom18a4/nsprpub/admin/repackage.sh
index 37ba0e163..37ba0e163 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/admin/repackage.sh
+++ b/src/libs/xpcom18a4/nsprpub/admin/repackage.sh
diff --git a/src/libs/xpcom18a4/nsprpub/admin/symlinks.sh b/src/libs/xpcom18a4/nsprpub/admin/symlinks.sh
index f90582e2d..f90582e2d 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/admin/symlinks.sh
+++ b/src/libs/xpcom18a4/nsprpub/admin/symlinks.sh
diff --git a/src/libs/xpcom18a4/nsprpub/config/Makefile.in b/src/libs/xpcom18a4/nsprpub/config/Makefile.in
index 1b83ffa56..1b83ffa56 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/config/Makefile.in
+++ b/src/libs/xpcom18a4/nsprpub/config/Makefile.in
diff --git a/src/libs/xpcom18a4/nsprpub/config/config.mk b/src/libs/xpcom18a4/nsprpub/config/config.mk
index 697a6015d..697a6015d 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/config/config.mk
+++ b/src/libs/xpcom18a4/nsprpub/config/config.mk
diff --git a/src/libs/xpcom18a4/nsprpub/config/nfspwd.pl b/src/libs/xpcom18a4/nsprpub/config/nfspwd.pl
index 947b822ae..947b822ae 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/config/nfspwd.pl
+++ b/src/libs/xpcom18a4/nsprpub/config/nfspwd.pl
diff --git a/src/libs/xpcom18a4/nsprpub/config/nspr-config.in b/src/libs/xpcom18a4/nsprpub/config/nspr-config.in
index e9e186791..e9e186791 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/config/nspr-config.in
+++ b/src/libs/xpcom18a4/nsprpub/config/nspr-config.in
diff --git a/src/libs/xpcom18a4/nsprpub/config/rules.mk b/src/libs/xpcom18a4/nsprpub/config/rules.mk
index bba50ee75..bba50ee75 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/config/rules.mk
+++ b/src/libs/xpcom18a4/nsprpub/config/rules.mk
diff --git a/src/libs/xpcom18a4/nsprpub/configure b/src/libs/xpcom18a4/nsprpub/configure
index 2046d79f6..2046d79f6 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/configure
+++ b/src/libs/xpcom18a4/nsprpub/configure
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/linux/Makefile.in b/src/libs/xpcom18a4/nsprpub/pkg/linux/Makefile.in
index 630af186b..09edb474b 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/linux/Makefile.in
+++ b/src/libs/xpcom18a4/nsprpub/pkg/linux/Makefile.in
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: Makefile.in $"
+#ident "$Id: Makefile.in 1 vboxsync $"
#
MOD_DEPTH = ../..
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.com b/src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.com
index 32de8a9ba..511e5913b 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.com
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.com
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: Makefile.com $"
+#ident "$Id: Makefile.com 1 vboxsync $"
#
MACH = $(shell mach)
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.in b/src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.in
index 0c2d2e317..53ac721f5 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.in
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.in
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: Makefile.in $"
+#ident "$Id: Makefile.in 1 vboxsync $"
#
MOD_DEPTH = ../..
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.targ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.targ
index 9c49cf206..b5ea1586b 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.targ
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/Makefile.targ
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: Makefile.targ $"
+#ident "$Id: Makefile.targ 1 vboxsync $"
#
pkginfo: pkginfo.tmpl ../awk_pkginfo
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/Makefile.in b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/Makefile.in
index ab54db6fb..66885f029 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/Makefile.in
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/Makefile.in
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: Makefile.in $"
+#ident "$Id: Makefile.in 1 vboxsync $"
#
MOD_DEPTH = ../../..
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/depend b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/depend
index 57bc554e3..47748f629 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/depend
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/depend
@@ -1,7 +1,7 @@
# Copyright 2002 Microsystems, Inc. All Rights Reserved.
# Use is subject to license terms.
#
-# $Id: depend $
+# $Id: depend 1 vboxsync $
#
# This package information file defines software dependencies associated
# with the pkg. You can define three types of pkg dependencies with this file:
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl
index 431ef37a0..d387aa5dc 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: pkginfo.tmpl $"
+#ident "$Id: pkginfo.tmpl 1 vboxsync $"
#
#
# This required package information file describes characteristics of the
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_com b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_com
index e92c4e513..d7c4366ca 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_com
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_com
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: prototype_com $"
+#ident "$Id: prototype_com 1 vboxsync $"
#
# This required package information file contains a list of package contents.
# The 'pkgmk' command uses this file to identify the contents of a package
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_i386 b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_i386
index 76b920168..652e25a1f 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_i386
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_i386
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: prototype_i386 $"
+#ident "$Id: prototype_i386 1 vboxsync $"
#
# This required package information file contains a list of package contents.
# The 'pkgmk' command uses this file to identify the contents of a package
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_sparc b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_sparc
index 4da58b010..ae0a7032e 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_sparc
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWpr/prototype_sparc
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: prototype_sparc $"
+#ident "$Id: prototype_sparc 1 vboxsync $"
#
# This required package information file contains a list of package contents.
# The 'pkgmk' command uses this file to identify the contents of a package
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/Makefile.in b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/Makefile.in
index ab54db6fb..66885f029 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/Makefile.in
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/Makefile.in
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: Makefile.in $"
+#ident "$Id: Makefile.in 1 vboxsync $"
#
MOD_DEPTH = ../../..
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/depend b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/depend
index 5be1ecd98..027675ef6 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/depend
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/depend
@@ -1,7 +1,7 @@
# Copyright 2002 Microsystems, Inc. All Rights Reserved.
# Use is subject to license terms.
#
-# $Id: depend $
+# $Id: depend 1 vboxsync $
#
# This package information file defines software dependencies associated
# with the pkg. You can define three types of pkg dependencies with this file:
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/pkginfo.tmpl b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/pkginfo.tmpl
index 0b13c5be4..f7504a307 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/pkginfo.tmpl
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/pkginfo.tmpl
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: pkginfo.tmpl $"
+#ident "$Id: pkginfo.tmpl 1 vboxsync $"
#
#
# This required package information file describes characteristics of the
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/prototype_com b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/prototype_com
index 700d61ca9..ac92436fd 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/prototype_com
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/prototype_com
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: prototype_com $"
+#ident "$Id: prototype_com 1 vboxsync $"
#
# This required package information file contains a list of package contents.
# The 'pkgmk' command uses this file to identify the contents of a package
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/prototype_sparc b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/prototype_sparc
index cd3da1210..26e6d7d70 100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/prototype_sparc
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/SUNWprx/prototype_sparc
@@ -2,7 +2,7 @@
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "$Id: prototype_sparc $"
+#ident "$Id: prototype_sparc 1 vboxsync $"
#
# This required package information file contains a list of package contents.
# The 'pkgmk' command uses this file to identify the contents of a package
diff --git a/src/libs/xpcom18a4/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh b/src/libs/xpcom18a4/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh
index b01645e47..80d6fab36 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh
+++ b/src/libs/xpcom18a4/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh
@@ -1,6 +1,6 @@
#!/usr/bin/ksh -p
#
-#ident "$Id: bld_awk_pkginfo.ksh $"
+#ident "$Id: bld_awk_pkginfo.ksh 1 vboxsync $"
#
# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
diff --git a/src/libs/xpcom18a4/nsprpub/pr/include/md/_iprt_atomic.h b/src/libs/xpcom18a4/nsprpub/pr/include/md/_iprt_atomic.h
index 949604978..729f3973b 100644
--- a/src/libs/xpcom18a4/nsprpub/pr/include/md/_iprt_atomic.h
+++ b/src/libs/xpcom18a4/nsprpub/pr/include/md/_iprt_atomic.h
@@ -1,4 +1,4 @@
-/* $Id: _iprt_atomic.h $ */
+/* $Id: _iprt_atomic.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* IPRT Atomic Operation, for including into a system config header.
*/
diff --git a/src/libs/xpcom18a4/nsprpub/pr/src/misc/compile-et.pl b/src/libs/xpcom18a4/nsprpub/pr/src/misc/compile-et.pl
index 9f0d90bc1..9f0d90bc1 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/pr/src/misc/compile-et.pl
+++ b/src/libs/xpcom18a4/nsprpub/pr/src/misc/compile-et.pl
diff --git a/src/libs/xpcom18a4/nsprpub/pr/tests/runtests.ksh b/src/libs/xpcom18a4/nsprpub/pr/tests/runtests.ksh
index 3af86d394..3af86d394 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/pr/tests/runtests.ksh
+++ b/src/libs/xpcom18a4/nsprpub/pr/tests/runtests.ksh
diff --git a/src/libs/xpcom18a4/nsprpub/pr/tests/runtests.sh b/src/libs/xpcom18a4/nsprpub/pr/tests/runtests.sh
index bb4a65eba..bb4a65eba 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/pr/tests/runtests.sh
+++ b/src/libs/xpcom18a4/nsprpub/pr/tests/runtests.sh
diff --git a/src/libs/xpcom18a4/nsprpub/pr/tests/runy2ktests.ksh b/src/libs/xpcom18a4/nsprpub/pr/tests/runy2ktests.ksh
index e7a325019..e7a325019 100755..100644
--- a/src/libs/xpcom18a4/nsprpub/pr/tests/runy2ktests.ksh
+++ b/src/libs/xpcom18a4/nsprpub/pr/tests/runy2ktests.ksh
diff --git a/src/libs/xpcom18a4/python/Makefile.kmk b/src/libs/xpcom18a4/python/Makefile.kmk
index 42853d8f5..af23c2942 100644
--- a/src/libs/xpcom18a4/python/Makefile.kmk
+++ b/src/libs/xpcom18a4/python/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37113 2011-05-16 16:20:00Z vboxsync $
## @file
# Sub-Makefile for Python bindings
#
@@ -113,7 +113,8 @@ VBoxPython2_5_INCS = $(VBOX_PYTHON25_INC)
VBoxPython2_5_LIBS = $(VBOX_PYTHON25_LIB)
endif
-if defined(VBOX_PYTHON26_INC)
+if defined(VBOX_PYTHON26_INC) \
+ && ("$(KBUILD_TARGET)" != "darwin" || "$(VBOX_DEF_MACOSX_VERSION_MIN)" <= "10.6")
#
# Python 2.6 version
#
diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/genstubs.pl b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/genstubs.pl
index b8962930d..b8962930d 100755..100644
--- a/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/genstubs.pl
+++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/genstubs.pl
diff --git a/src/libs/xpcom18a4/xpcom/tools/analyze-xpcom-log.pl b/src/libs/xpcom18a4/xpcom/tools/analyze-xpcom-log.pl
index 81ccb2123..81ccb2123 100755..100644
--- a/src/libs/xpcom18a4/xpcom/tools/analyze-xpcom-log.pl
+++ b/src/libs/xpcom18a4/xpcom/tools/analyze-xpcom-log.pl
diff --git a/src/recompiler/COPYING.LIB b/src/recompiler/COPYING.LIB
index 223ede7de..bfd28e23f 100644
--- a/src/recompiler/COPYING.LIB
+++ b/src/recompiler/COPYING.LIB
@@ -2,7 +2,7 @@
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -146,7 +146,7 @@ such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
-
+
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
@@ -485,7 +485,7 @@ convey the exclusion of warranty; and each file should have at least the
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
diff --git a/src/recompiler/Makefile-old.kmk b/src/recompiler/Makefile-old.kmk
deleted file mode 100644
index 62c193a2f..000000000
--- a/src/recompiler/Makefile-old.kmk
+++ /dev/null
@@ -1,314 +0,0 @@
-# $Id: Makefile-old.kmk $
-## @file
-# The OLD Recompiler Sub-Makefile body.
-#
-
-#
-# Copyright (C) 2006-2007 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.
-#
-
-
-
-#
-# Globals
-#
-VBOX_PATH_RECOMPILER_SRC := $(PATH_SUB_CURRENT)
-
-# For 32-bit targets when enabled 64-bit guests we build 2 REM DLLs:
-# with 64-bit support (slow and buggy at the moment) VBOXREM64
-# only 32-bit support (faster, stable, but not suitable for 64-bit guests) VBOXREM32
-# During the runtime, we load appropriate library from VBOXREM, depending on guest settings.
-# 64-bit targets have 64-bit enabled REM by default, so is not part of this mess
-ifeq ($(KBUILD_TARGET_ARCH),x86)
- ifdef VBOX_WITH_64_BITS_GUESTS
- VBOX_USE_REM64 := 1
- endif
-endif
-
-# Workaround for darwin hell.
-ifeq ($(KBUILD_TARGET),darwin)
- VBOX_WITHOUT_REM_LDR_CYCLE = 1
-endif
-
-
-TEMPLATE_DUMMY = dummy template (move to kBuild) ## @todo Will be there in the next update, remove this.
-
-if 0
- #
- # Template useful for forcing a specific gcc version in case it comes in handy.
- #
- TOOL_MYGCC = description
- TOOL_MYGCC_EXTENDS = GCC3
- TOOL_MYGCC_CC = $(firstword $(which gcc-4.2 gcc-4.1 gcc-3.4 gcc-3.4.6 gcc-3.3 gcc-3.3.6 gcc-3.2))
- TOOL_MYGCC_COMPILE_C_DEPEND =
- TOOL_MYGCC_COMPILE_C_DEPORD =
- TOOL_MYGCC_COMPILE_C_OUTPUT =
- define TOOL_MYGCC_COMPILE_C_CMDS
- $(QUIET)$(TOOL_MYGCC_CC) -c\
- $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
- -Wp,-MD,$(dep) -Wp,-MT,$(obj) -Wp,-MP\
- -o $(obj)\
- $(abspath $(source))
- endef
- #Usage: target-i386/op_helper.c_TOOL = MYGCC
-endif
-
-## @todo Note to self (bird): Convert this mess to use NAME (that property didn't exist when the REM_MOD hack was first made I think).
-
-# For 64-bit Windows we currently use gcc (due to MSVC unaware of such a novel
-# thing as C99, a lot of GCC extensions deployed by QEMU and calling convention
-# differences) to cross-compile code to Linux/ELF and dynamically generate invocation wrappers.
-if1of ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH), win.amd64)
- VBOX_USE_REM2 = 1
- REM_MOD := VBoxREM2
-else
- REM_MOD := VBoxREM
-endif
-
-#
-# Target lists (some of them anyways).
-#
-ifdef VBOX_USE_REM2
- SYSMODS += VBoxREM2
-else ifndef VBOX_USE_REM64
- DLLS += VBoxREM
-endif
-
-
-#
-# The VBoxREM.[dll|so|..] or VBoxREM2.rel.
-#
-ifeq ($(KBUILD_TARGET),win)
-$(REM_MOD)_TEMPLATE = DUMMY
-$(REM_MOD)_TOOL.win.x86 = MINGW32
-$(REM_MOD)_TOOL.win.amd64 = XGCCAMD64LINUX
-$(REM_MOD)_SDKS.win.x86 = W32API
-$(REM_MOD)_ASFLAGS = -x assembler-with-cpp
-$(REM_MOD)_CFLAGS = -Wall -g -fno-omit-frame-pointer -fno-strict-aliasing -Wno-shadow
-$(REM_MOD)_CFLAGS.debug = -O0
-$(REM_MOD)_CFLAGS.release += -fno-gcse -O2
-$(REM_MOD)_CFLAGS.profile = $($(REM_MOD)_CFLAGS.release)
-$(REM_MOD)_DEFS += IN_RING3 $(ARCH_BITS_DEFS)
-# workaround the regparm bug in gcc <= 3.3
-$(REM_MOD)_DEFS.win.x86 += GCC_WITH_BUGGY_REGPARM
-else # !win
-$(REM_MOD)_TEMPLATE = VBOXR3NP
-# workaround the regparm bug in gcc <= 3.3
-$(REM_MOD)_DEFS = $(if $(VBOX_GCC_BUGGY_REGPARM),GCC_WITH_BUGGY_REGPARM,)
-endif # !win
-$(REM_MOD)_DEFS += IN_REM_R3 REM_INCLUDE_CPU_H
-#$(REM_MOD)_DEFS += REM_PHYS_ADDR_IN_TLB
-#$(REM_MOD)_DEFS += DEBUG_ALL_LOGGING DEBUG_DISAS DEBUG_PCALL DEBUG_EXEC DEBUG_FLUSH DEBUG_IOPORT DEBUG_SIGNAL DEBUG_TLB_CHECK DEBUG_TB_INVALIDATE DEBUG_TLB # Enables huge amounts of debug logging.
-#$(REM_MOD)_DEFS += DEBUG_TMP_LOGGING # log qemu parts to "/tmp/vbox-qemu.log" - does not work with VBoxREM2.
-$(REM_MOD)_DEFS.linux = _GNU_SOURCE
-ifdef VBOX_SOLARIS_10
- $(REM_MOD)_DEFS.solaris = HOST_SOLARIS=10
-else
- $(REM_MOD)_DEFS.solaris = HOST_SOLARIS=11
-endif
-# Missing fpclassify. Is there a better define or flag for this?
-$(REM_MOD)_DEFS.solaris += __C99FEATURES__
-$(REM_MOD)_DEFS.freebsd += _BSD
-
-$(REM_MOD)_INCS = \
- Sun \
- target-i386 \
- tcg \
- fpu \
- $(PATH_$(REM_MOD)) \
- $(PATH_ROOT)/src/VBox/VMM/include \
- .
-ifn1of ($($(REM_MOD)_DEFS),DEBUG_TMP_LOGGING)
-$(REM_MOD)_DEFS += LOG_USE_C99
-$(REM_MOD)_INCS <= \
- Sun/crt
-endif
-
-$(REM_MOD)_SOURCES = \
- VBoxRecompiler.c \
- cpu-exec.c \
- exec.c \
- translate-all.c \
- host-utils.c \
- cutils.c \
- tcg/tcg.c \
- tcg/tcg-dyngen.c \
- tcg/tcg-runtime.c \
- fpu/softfloat-native.c \
- target-i386/op_helper.c \
- target-i386/helper.c \
- target-i386/translate.c
-
-ifeq ($(KBUILD_TARGET_ARCH),amd64)
- $(REM_MOD)_DEFS += __x86_64__
- $(REM_MOD)_INCS += tcg/x86_64
-else
- $(REM_MOD)_DEFS += __i386__
- $(REM_MOD)_INCS += tcg/i386
-endif
-
-ifneq ($(KBUILD_TARGET),freebsd)
-$(REM_MOD)_SOURCES.debug += \
- Sun/testmath.c
-endif
-$(REM_MOD)_SOURCES.win.x86 = $(PATH_VBoxREMImp)/VBoxREMWin.def
-ifndef VBOX_USE_REM2
- $(REM_MOD)_POST_CMDS = $(VBOX_SIGN_IMAGE_CMDS)
-endif
-ifdef VBOX_USE_REM2
-## @todo spread out where it belongs.
-$(REM_MOD)_TEMPLATE = VBOXNOCRTGAS
-$(REM_MOD)_DEFS += LOG_USE_C99 $(ARCH_BITS_DEFS)
-
-# This doesn't fit in IPRT because it requires GAS and is LGPL.
-$(REM_MOD)_SOURCES += \
- Sun/e_powl-$(KBUILD_TARGET_ARCH).S
-
-$(REM_MOD)_INCS += \
- Sun/crt
-$(REM_MOD)_SYSSUFF = .rel
-endif
-ifdef VBOX_USE_REM2
-$(REM_MOD)_LIBS = \
- $(PATH_LIB)/RuntimeR3NoCRTGCC$(VBOX_SUFF_LIB)
-else
-$(REM_MOD)_LIBS = \
- $(LIB_VMM) \
- $(LIB_RUNTIME)
-$(REM_MOD)_LIBS.darwin = \
- $(TARGET_VBoxREMImp)
-endif
-
-## @todo clean up this, there are some duplicates with the template here I think.
-$(REM_MOD)_LDFLAGS.darwin = -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/$(REM_MOD).dylib
-$(REM_MOD)_LDFLAGS.l4 = -T$(L4_LIBDIR)/../main_rel.ld -nostdlib -Wl,--no-undefined
-$(REM_MOD)_LDFLAGS.linux = $(VBOX_LD_as_needed)
-$(REM_MOD)_LDFLAGS.os2 = -Zomf
-$(REM_MOD)_LDFLAGS.debug = -g
-$(REM_MOD)_LDFLAGS.solaris = -mimpure-text
-
-
-if defined(VBOX_USE_REM2) || defined(VBOX_USE_REM64)
-#
-# The VBoxREM2, VBoxREM32 and VBoxREM64 wrapper.
-#
-DLLS += VBoxREMWrapper
-VBoxREMWrapper_TEMPLATE = VBoxR3DllWarnNoPic
-VBoxREMWrapper_NAME = VBoxREM
-VBoxREMWrapper_DEFS = IN_REM_R3
- ifdef VBOX_USE_REM64
-VBoxREMWrapper_DEFS += VBOX_USE_BITNESS_SELECTOR
- endif
- ifdef VBOX_WITHOUT_REM_LDR_CYCLE
-VBoxREMWrapper_DEFS += VBOX_WITHOUT_REM_LDR_CYCLE
- endif
-VBoxREMWrapper_SOURCES = \
- VBoxREMWrapper.cpp
- ifdef VBOX_USE_REM2
-VBoxREMWrapper_SOURCES += \
- VBoxREMWrapperA.asm
- endif
-VBoxREMWrapper_LIBS = \
- $(LIB_RUNTIME)
- ifndef VBOX_WITHOUT_REM_LDR_CYCLE
-VBoxREMWrapper_LIBS += \
- $(LIB_VMM)
-VBoxREMWrapper_LIBS.darwin += \
- $(TARGET_VBoxREMImp)
- else
-VBoxREMWrapper_LDFLAGS.darwin = -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxREM.dylib
- endif
-endif
-
-
-ifdef VBOX_USE_REM64
- DLLS += VBoxREM32
- VBoxREM32_EXTENDS = VBoxREM
- VBoxREM32_EXTENDS_BY = appending
- VBoxREM32_TEMPLATE = $(VBoxREM_TEMPLATE)
- VBoxREM32_LDFLAGS.darwin = -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxREM32.dylib
- VBoxREM32_LIBS.darwin = $(LIB_REM)
-
- DLLS += VBoxREM64
- VBoxREM64_EXTENDS = VBoxREM
- VBoxREM64_EXTENDS_BY = appending
- VBoxREM64_TEMPLATE = $(VBoxREM_TEMPLATE)
- VBoxREM64_DEFS = VBOX_ENABLE_VBOXREM64
- VBoxREM64_LDFLAGS.darwin = -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxREM64.dylib
- VBoxREM64_LIBS.darwin = $(LIB_REM)
-
-endif # USE_VBOXREM64
-
-
-#
-# The VBoxREM import library.
-#
-# This is a HACK to get around (a) the cyclic dependency between VBoxVMM and
-# VBoxREM during linking and (b) the recursive build ordering which means VBoxREM
-# won't be built until after all the other DLLs.
-#
-IMPORT_LIBS += VBoxREMImp
-VBoxREMImp_TEMPLATE = VBoxR3Dll
- ifn1of ($(KBUILD_TARGET), os2 win)
-VBoxREMImp_NAME = VBoxREM
- endif
-VBoxREMImp_INST = $(INST_LIB)
-VBoxREMImp_SOURCES.win = $(PATH_VBoxREMImp)/VBoxREMWin.def
-VBoxREMImp_CLEAN.win = $(PATH_VBoxREMImp)/VBoxREMWin.def
-VBoxREMImp_SOURCES.os2 = $(PATH_VBoxREMImp)/VBoxREMOS2.def
-VBoxREMImp_CLEAN.os2 = $(PATH_VBoxREMImp)/VBoxREMOS2.def
- ifn1of ($(KBUILD_TARGET), os2 win)
-VBoxREMImp_SOURCES = $(PATH_VBoxREMImp)/VBoxREMImp.c
-VBoxREMImp_CLEAN = $(PATH_VBoxREMImp)/VBoxREMImp.c
- endif
- ifn1of ($(KBUILD_TARGET), darwin os2 win)
-VBoxREMImp_SONAME = VBoxREM$(SUFF_DLL)
- endif
-ifdef VBOX_WITHOUT_REM_LDR_CYCLE
- VBoxREMImp_LDFLAGS.darwin = -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxREM.dylib
-else
- VBoxREMImp_LDFLAGS.darwin = -install_name $(subst @rpath,@executable_path,$(VBOX_DYLD_EXECUTABLE_PATH))/VBoxREM.dylib
-endif
-VBoxREMImp_LDFLAGS.l4 = -T$(L4_LIBDIR)/../main_rel.ld -nostdlib
-
-$$(PATH_VBoxREMImp)/VBoxREMImp.c: $(VBOX_PATH_RECOMPILER_SRC)/VBoxREM.def $(VBOX_PATH_RECOMPILER_SRC)/Sun/deftoimp.sed $(MAKEFILE_CURRENT) | $$(dir $$@)
- $(call MSG_GENERATE,,$@)
- $(QUIET)$(APPEND) -t $@ '#ifdef VBOX_HAVE_VISIBILITY_HIDDEN'
- $(QUIET)$(APPEND) $@ '# define EXPORT __attribute__((visibility("default")))'
- $(QUIET)$(APPEND) $@ '#else'
- $(QUIET)$(APPEND) $@ '# define EXPORT'
- $(QUIET)$(APPEND) $@ '#endif'
- $(QUIET)$(APPEND) $@ ''
- $(QUIET)$(SED) -f $(VBOX_PATH_RECOMPILER_SRC)/Sun/deftoimp.sed --append $@ $<
-
-$$(PATH_VBoxREMImp)/VBoxREMOS2.def: $(VBOX_PATH_RECOMPILER_SRC)/VBoxREM.def $(MAKEFILE_CURRENT) | $$(dir $$@)
- $(SED) \
- -e 's/^[ \t][ \t]*REMR3/ _REMR3/' \
- -e 's/\.[Dd][Ll][Ll]//' \
- -e 's/^LIBRARY .*/LIBRARY VBoxREM INITINSTANCE TERMINSTANCE\nDATA MULTIPLE\n/' \
- --output $@ \
- $<
-
-$$(PATH_VBoxREMImp)/VBoxREMWin.def: $(VBOX_PATH_RECOMPILER_SRC)/VBoxREM.def $(MAKEFILE_CURRENT) | $$(dir $$@)
- $(CP) -f $< $@
-
-
-#
-# The math testcase as a standalone program for testing and debugging purposes.
-#
-## @todo This is a bit messy because of MINGW32.
-testmath_ASFLAGS.amd64 = -m amd64
-testmath_CFLAGS = -Wall -g
-testmath_CFLAGS.release = -O3
-testmath_LDFLAGS = -g
-testmath_DEFS = MATHTEST_STANDALONE
-testmath_SOURCES = Sun/testmath.c
-
diff --git a/src/recompiler/Makefile.kmk b/src/recompiler/Makefile.kmk
index 472b71409..2d7c5566a 100644
--- a/src/recompiler/Makefile.kmk
+++ b/src/recompiler/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 37692 2011-06-29 16:19:17Z vboxsync $
## @file
# The Recompiler Sub-Makefile.
#
@@ -19,10 +19,6 @@
SUB_DEPTH = ../..
include $(KBUILD_PATH)/subheader.kmk
-ifn1of ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH), darwin.x86 darwin.amd64 linux.amd64)
- include $(PATH_SUB_CURRENT)/Makefile-old.kmk
-else # new stuff
-
#
# Globals
#
@@ -60,15 +56,17 @@ else
# Missing fpclassify. Is there a better define or flag for this?
VBoxRemPrimary_DEFS.solaris += __C99FEATURES__
endif # win
-VBoxRemPrimary_DEFS += IN_REM_R3 REM_INCLUDE_CPU_H
+VBoxRemPrimary_DEFS += IN_REM_R3 REM_INCLUDE_CPU_H NEED_CPU_H
#VBoxRemPrimary_DEFS += REM_PHYS_ADDR_IN_TLB
-#VBoxRemPrimary_DEFS += DEBUG_ALL_LOGGING DEBUG_DISAS DEBUG_PCALL DEBUG_EXEC DEBUG_FLUSH DEBUG_IOPORT DEBUG_SIGNAL DEBUG_TLB_CHECK DEBUG_TB_INVALIDATE DEBUG_TLB # Enables huge amounts of debug logging.
-#VBoxRemPrimary_DEFS += DEBUG_TMP_LOGGING # log qemu parts to "/tmp/vbox-qemu.log" - does not work with VBoxREM2.
+#VBoxRemPrimary_DEFS += DEBUG_ALL_LOGGING DEBUG_DISAS DEBUG_PCALL CONFIG_DEBUG_EXEC DEBUG_FLUSH DEBUG_IOPORT DEBUG_SIGNAL DEBUG_TLB_CHECK DEBUG_TB_INVALIDATE DEBUG_TLB # Enables huge amounts of debug logging.
+ifdef IEM_VERIFICATION_MODE
+ VBoxRemPrimary_DEFS += IEM_VERIFICATION_MODE
+endif
VBoxRemPrimary_DEFS.linux = _GNU_SOURCE
ifdef VBOX_SOLARIS_10
- VBoxRemPrimary_DEFS.solaris = HOST_SOLARIS=10
+ VBoxRemPrimary_DEFS.solaris = CONFIG_SOLARIS_VERSION=10
else
- VBoxRemPrimary_DEFS.solaris = HOST_SOLARIS=11
+ VBoxRemPrimary_DEFS.solaris = CONFIG_SOLARIS_VERSION=11
endif
VBoxRemPrimary_DEFS.freebsd += _BSD
VBoxRemPrimary_DEFS.amd64 += __x86_64__
@@ -81,9 +79,8 @@ VBoxRemPrimary_INCS = \
fpu \
$(VBoxRemPrimary_0_OUTDIR) \
$(PATH_ROOT)/src/VBox/VMM/include \
+ tcg/i386 \
.
-VBoxRemPrimary_INCS.amd64 += tcg/x86_64
-VBoxRemPrimary_INCS.x86 += tcg/i386
ifn1of ($(VBoxRemPrimary_DEFS),DEBUG_TMP_LOGGING)
VBoxRemPrimary_DEFS += LOG_USE_C99
VBoxRemPrimary_INCS <= \
@@ -97,9 +94,9 @@ VBoxRemPrimary_SOURCES = \
translate-all.c \
host-utils.c \
cutils.c \
+ tcg-runtime.c \
tcg/tcg.c \
tcg/tcg-dyngen.c \
- tcg/tcg-runtime.c \
fpu/softfloat-native.c \
target-i386/op_helper.c \
target-i386/helper.c \
@@ -269,6 +266,5 @@ testmath_DEFS = MATHTEST_STANDALONE
testmath_SOURCES = Sun/testmath.c
-endif # new stuff
include $(KBUILD_PATH)/subfooter.kmk
diff --git a/src/recompiler/README.vbox b/src/recompiler/README.vbox
new file mode 100644
index 000000000..d478b71e5
--- /dev/null
+++ b/src/recompiler/README.vbox
@@ -0,0 +1,6 @@
+QEMU is based on v0.13.0 (6ed912999d6ef636a5be5ccb266d7d3c0f0310b4)
+from git://git.savannah.nongnu.org/qemu.git.
+
+Modified parts related to calls of external functions, to allow loading
+recompiler library as regular shared object in high memory on 64-bit systems.
+
diff --git a/src/recompiler/REAMDE.vbox b/src/recompiler/REAMDE.vbox
deleted file mode 100644
index cd0c40c12..000000000
--- a/src/recompiler/REAMDE.vbox
+++ /dev/null
@@ -1,3 +0,0 @@
-QEMU is based on r5495 of SVN repository. Modified parts related to calls
-of external functions, to allow loading recompiler library as regular shared object
-in high memory on 64-bit systems and MSVC compilation fixes.
diff --git a/src/recompiler/Sun/config-host.h b/src/recompiler/Sun/config-host.h
index 6093a241d..0c1288404 100644
--- a/src/recompiler/Sun/config-host.h
+++ b/src/recompiler/Sun/config-host.h
@@ -1,4 +1,4 @@
-/* $Id: config-host.h $ */
+/* $Id: config-host.h 37689 2011-06-29 16:01:23Z vboxsync $ */
/** @file
* Sun host config - maintained by hand
*/
@@ -22,6 +22,9 @@
#else
# define HOST_I386 1
# define HOST_LONG_BITS 32
+#endif
+
+#ifndef IPRT_NO_CRT
# ifdef RT_OS_WINDOWS
# define CONFIG_WIN32 1
# elif defined(RT_OS_OS2)
@@ -29,14 +32,15 @@
# elif defined(RT_OS_DARWIN)
# define CONFIG_DARWIN
# elif defined(RT_OS_FREEBSD) || defined(RT_OS_NETBSD) || defined(RT_OS_OPENBSD)
+# define HAVE_MACHINE_BSWAP_H
/*# define CONFIG_BSD*/
# elif defined(RT_OS_SOLARIS)
# define CONFIG_SOLARIS
-# elif !defined(IPRT_NO_CRT)
+# else
# define HAVE_BYTESWAP_H 1
# endif
#endif
-#define QEMU_VERSION "0.8.1"
+#define QEMU_VERSION "0.13.0"
#define CONFIG_UNAME_RELEASE ""
#define CONFIG_QEMU_SHAREDIR "."
diff --git a/src/recompiler/Sun/config.h b/src/recompiler/Sun/config.h
index ee03d21ef..4e95d9148 100644
--- a/src/recompiler/Sun/config.h
+++ b/src/recompiler/Sun/config.h
@@ -1,4 +1,4 @@
-/* $Id: config.h $ */
+/* $Id: config.h 36175 2011-03-04 16:21:09Z vboxsync $ */
/** @file
* Sun config - Maintained by hand
*/
@@ -20,6 +20,7 @@
#define TARGET_ARCH "i386"
#define TARGET_I386 1
#define CONFIG_SOFTMMU 1
+#define TARGET_PHYS_ADDR_BITS 64
#ifdef VBOX_WITH_64_BITS_GUESTS
# if defined(__x86_64__) || defined (VBOX_ENABLE_VBOXREM64)
diff --git a/src/recompiler/Sun/crt/stdio.h b/src/recompiler/Sun/crt/stdio.h
index ae14a4a14..344a41378 100644
--- a/src/recompiler/Sun/crt/stdio.h
+++ b/src/recompiler/Sun/crt/stdio.h
@@ -1,4 +1,4 @@
-/* $Id: stdio.h $ */
+/* $Id: stdio.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Our minimal stdio
*/
diff --git a/src/recompiler/Sun/deftoimp.sed b/src/recompiler/Sun/deftoimp.sed
index 089a0d99b..bbd8707fb 100644
--- a/src/recompiler/Sun/deftoimp.sed
+++ b/src/recompiler/Sun/deftoimp.sed
@@ -1,4 +1,4 @@
-# $Id: deftoimp.sed $
+# $Id: deftoimp.sed 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# SED script for generating a dummy .so from a windows .def file.
#
diff --git a/src/VBox/HostDrivers/VBoxUSB/USBLibInternal.h b/src/recompiler/Sun/kvm.h
index 67ce7243d..dc203a645 100644
--- a/src/VBox/HostDrivers/VBoxUSB/USBLibInternal.h
+++ b/src/recompiler/Sun/kvm.h
@@ -1,10 +1,10 @@
-/* $Id: USBLibInternal.h $ */
+/* $Id: kvm.h 37675 2011-06-29 07:07:14Z vboxsync $ */
/** @file
- * USBLIB - Internal header.
+ * VBox Recompiler - kvm stub header.
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * 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;
@@ -15,19 +15,14 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#ifndef ___USBLibInternal_h
-#define ___USBLibInternal_h
+#ifndef ___kvm_stub_h___
+#define ___kvm_stub_h___
-#include <VBox/cdefs.h>
-#include <VBox/types.h>
-
-RT_C_DECLS_BEGIN
-#ifdef RT_OS_WINDOWS
-char *usblibQueryDeviceName(uint32_t idxDev);
-char *usblibQueryDeviceRegPath(uint32_t idxDev);
-void usbLibEnumerateHostControllers(PUSBDEVICE *ppDevices, uint32_t *DevicesConnected);
-#endif /* RT_OS_WINDOWS */
-RT_C_DECLS_END
+#define kvm_enabled() false
+#define kvm_update_guest_debug(a, b) AssertFailed()
+#define kvm_set_phys_mem(a, b, c) AssertFailed()
+#define kvm_arch_get_registers(a) AssertFailed()
+#define cpu_synchronize_state(a) do { } while (0)
#endif
diff --git a/src/recompiler/Sun/testmath.c b/src/recompiler/Sun/testmath.c
index bc1d36157..83a39af5e 100644
--- a/src/recompiler/Sun/testmath.c
+++ b/src/recompiler/Sun/testmath.c
@@ -1,4 +1,4 @@
-/* $Id: testmath.c $ */
+/* $Id: testmath.c 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* Testcase for the no-crt math stuff.
*/
diff --git a/src/recompiler/VBoxREM.def b/src/recompiler/VBoxREM.def
index 3d6d07b96..e99e28478 100644
--- a/src/recompiler/VBoxREM.def
+++ b/src/recompiler/VBoxREM.def
@@ -1,4 +1,4 @@
-; $Id: VBoxREM.def $
+; $Id: VBoxREM.def 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VBoxREM Definition File.
;
diff --git a/src/recompiler/VBoxREMWrapper.cpp b/src/recompiler/VBoxREMWrapper.cpp
index e0fb5835b..2d7011579 100644
--- a/src/recompiler/VBoxREMWrapper.cpp
+++ b/src/recompiler/VBoxREMWrapper.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxREMWrapper.cpp $ */
+/* $Id: VBoxREMWrapper.cpp 37693 2011-06-29 16:41:39Z vboxsync $ */
/** @file
*
* VBoxREM Win64 DLL Wrapper.
@@ -2003,6 +2003,7 @@ static int remLoadLinuxObj(void)
g_pvREM2 = RTMemExecAlloc(g_cbREM2);
if (g_pvREM2)
{
+ RTPathChangeToUnixSlashes(szPath, true);
# ifdef DEBUG /* How to load the VBoxREM2.rel symbols into the GNU debugger. */
RTPrintf("VBoxREMWrapper: (gdb) add-symbol-file %s 0x%p\n", szPath, g_pvREM2);
# endif
diff --git a/src/recompiler/VBoxREMWrapperA.asm b/src/recompiler/VBoxREMWrapperA.asm
index ba7cc770a..675145b9e 100644
--- a/src/recompiler/VBoxREMWrapperA.asm
+++ b/src/recompiler/VBoxREMWrapperA.asm
@@ -1,4 +1,4 @@
-; $Id: VBoxREMWrapperA.asm $
+; $Id: VBoxREMWrapperA.asm 28800 2010-04-27 08:22:32Z vboxsync $
;; @file
; VBoxREM Wrapper, Assembly routines and wrapper Templates.
;
diff --git a/src/recompiler/VBoxRecompiler.c b/src/recompiler/VBoxRecompiler.c
index bfb87362c..6a9ca4e35 100644
--- a/src/recompiler/VBoxRecompiler.c
+++ b/src/recompiler/VBoxRecompiler.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxRecompiler.c $ */
+/* $Id: VBoxRecompiler.c 37852 2011-07-08 19:18:05Z vboxsync $ */
/** @file
* VBox Recompiler - QEMU.
*/
@@ -20,11 +20,12 @@
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_REM
-#include "vl.h"
+#include <stdio.h> /* FILE */
#include "osdep.h"
-#include "exec-all.h"
#include "config.h"
-#include "cpu-all.h"
+#include "cpu.h"
+#include "exec-all.h"
+#include "ioport.h"
#include <VBox/vmm/rem.h>
#include <VBox/vmm/vmapi.h>
@@ -59,7 +60,7 @@ extern void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
extern void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
extern void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
extern void tlb_flush_page(CPUX86State *env, target_ulong addr);
-extern void tlb_flush(CPUState *env, int flush_global);
+extern void tlb_flush(CPUX86State *env, int flush_global);
extern void sync_seg(CPUX86State *env1, int seg_reg, int selector);
extern void sync_ldtr(CPUX86State *env1, int selector);
@@ -78,6 +79,9 @@ unsigned long get_phys_page_offset(target_ulong addr);
#define REM_COPY_FPU_REG(pDst, pSrc) \
do { *(PX86FPUMMX)(pDst) = *(const X86FPUMMX *)(pSrc); } while (0)
+/** How remR3RunLoggingStep operates. */
+#define REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
+
/*******************************************************************************
* Internal Functions *
@@ -188,7 +192,7 @@ CPUWriteMemoryFunc *g_apfnHandlerWrite[3] =
/*
* Debugger commands.
*/
-static DECLCALLBACK(int) remR3CmdDisasEnableStepping(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
+static DECLCALLBACK(int) remR3CmdDisasEnableStepping(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
/** '.remstep' arguments. */
static const DBGCVARDESC g_aArgRemStep[] =
@@ -206,7 +210,6 @@ static const DBGCCMD g_aCmds[] =
.cArgsMax = 1,
.paArgDescs = &g_aArgRemStep[0],
.cArgDescs = RT_ELEMENTS(g_aArgRemStep),
- .pResultDesc = NULL,
.fFlags = 0,
.pfnHandler = remR3CmdDisasEnableStepping,
.pszSyntax = "[on/off]",
@@ -216,7 +219,9 @@ static const DBGCCMD g_aCmds[] =
};
#endif
-/** Prologue code, must be in lower 4G to simplify jumps to/from generated code. */
+/** Prologue code, must be in lower 4G to simplify jumps to/from generated code.
+ * @todo huh??? That cannot be the case on the mac... So, this
+ * point is probably not valid any longer. */
uint8_t *code_gen_prologue;
@@ -307,12 +312,16 @@ REMR3DECL(int) REMR3Init(PVM pVM)
CPUMGetGuestCpuId(pVCpu, 1, &u32Dummy, &u32Dummy, &pVM->rem.s.Env.cpuid_ext_features, &pVM->rem.s.Env.cpuid_features);
CPUMGetGuestCpuId(pVCpu, 0x80000001, &u32Dummy, &u32Dummy, &pVM->rem.s.Env.cpuid_ext3_features, &pVM->rem.s.Env.cpuid_ext2_features);
+ EMRemLock(pVM);
+ cpu_reset(&pVM->rem.s.Env);
+ EMRemUnlock(pVM);
+
/* allocate code buffer for single instruction emulation. */
pVM->rem.s.Env.cbCodeBuffer = 4096;
pVM->rem.s.Env.pvCodeBuffer = RTMemExecAlloc(pVM->rem.s.Env.cbCodeBuffer);
AssertMsgReturn(pVM->rem.s.Env.pvCodeBuffer, ("Failed to allocate code buffer!\n"), VERR_NO_MEMORY);
- /* finally, set the cpu_single_env global. */
+ /* Finally, set the cpu_single_env global. */
cpu_single_env = &pVM->rem.s.Env;
/* Nothing is pending by default */
@@ -321,9 +330,9 @@ REMR3DECL(int) REMR3Init(PVM pVM)
/*
* Register ram types.
*/
- pVM->rem.s.iMMIOMemType = cpu_register_io_memory(-1, g_apfnMMIORead, g_apfnMMIOWrite, pVM);
+ pVM->rem.s.iMMIOMemType = cpu_register_io_memory(g_apfnMMIORead, g_apfnMMIOWrite, pVM);
AssertReleaseMsg(pVM->rem.s.iMMIOMemType >= 0, ("pVM->rem.s.iMMIOMemType=%d\n", pVM->rem.s.iMMIOMemType));
- pVM->rem.s.iHandlerMemType = cpu_register_io_memory(-1, g_apfnHandlerRead, g_apfnHandlerWrite, pVM);
+ pVM->rem.s.iHandlerMemType = cpu_register_io_memory(g_apfnHandlerRead, g_apfnHandlerWrite, pVM);
AssertReleaseMsg(pVM->rem.s.iHandlerMemType >= 0, ("pVM->rem.s.iHandlerMemType=%d\n", pVM->rem.s.iHandlerMemType));
Log2(("REM: iMMIOMemType=%d iHandlerMemType=%d\n", pVM->rem.s.iMMIOMemType, pVM->rem.s.iHandlerMemType));
@@ -405,6 +414,8 @@ REMR3DECL(int) REMR3Init(PVM pVM)
STAM_REG(pVM, &pVM->rem.s.Env.StatTbFlush, STAMTYPE_PROFILE, "/REM/TbFlush", STAMUNIT_TICKS_PER_CALL, "profiling tb_flush().");
#endif /* VBOX_WITH_STATISTICS */
+ AssertCompileMemberAlignment(CPUX86State, StatTbFlush, 4);
+ AssertCompileMemberAlignment(CPUX86State, StatTbFlush, 8);
STAM_REL_REG(pVM, &tb_flush_count, STAMTYPE_U32_RESET, "/REM/TbFlushCount", STAMUNIT_OCCURENCES, "tb_flush() calls");
STAM_REL_REG(pVM, &tb_phys_invalidate_count, STAMTYPE_U32_RESET, "/REM/TbPhysInvldCount", STAMUNIT_OCCURENCES, "tb_phys_invalidate() calls");
@@ -413,9 +424,6 @@ REMR3DECL(int) REMR3Init(PVM pVM)
#ifdef DEBUG_ALL_LOGGING
loglevel = ~0;
-# ifdef DEBUG_TMP_LOGGING
- logfile = fopen("/tmp/vbox-qemu.log", "w");
-# endif
#endif
/*
@@ -464,9 +472,8 @@ REMR3DECL(int) REMR3InitFinalize(PVM pVM)
return rc;
}
-
/**
- * Initializes phys_ram_size, phys_ram_dirty and phys_ram_dirty_size.
+ * Initializes ram_list.phys_dirty and ram_list.phys_dirty_size.
*
* @returns VBox status code.
* @param pVM The VM handle.
@@ -477,46 +484,48 @@ static int remR3InitPhysRamSizeAndDirtyMap(PVM pVM, bool fGuarded)
int rc = VINF_SUCCESS;
RTGCPHYS cb;
+ AssertLogRelReturn(QLIST_EMPTY(&ram_list.blocks), VERR_INTERNAL_ERROR_2);
+
cb = pVM->rem.s.GCPhysLastRam + 1;
AssertLogRelMsgReturn(cb > pVM->rem.s.GCPhysLastRam,
("GCPhysLastRam=%RGp - out of range\n", pVM->rem.s.GCPhysLastRam),
VERR_OUT_OF_RANGE);
- phys_ram_size = cb;
- phys_ram_dirty_size = cb >> PAGE_SHIFT;
- AssertMsg(((RTGCPHYS)phys_ram_dirty_size << PAGE_SHIFT) == cb, ("%RGp\n", cb));
+
+ ram_list.phys_dirty_size = cb >> PAGE_SHIFT;
+ AssertMsg(((RTGCPHYS)ram_list.phys_dirty_size << PAGE_SHIFT) == cb, ("%RGp\n", cb));
if (!fGuarded)
{
- phys_ram_dirty = MMR3HeapAlloc(pVM, MM_TAG_REM, phys_ram_dirty_size);
- AssertLogRelMsgReturn(phys_ram_dirty, ("Failed to allocate %u bytes of dirty page map bytes\n", phys_ram_dirty_size), VERR_NO_MEMORY);
+ ram_list.phys_dirty = MMR3HeapAlloc(pVM, MM_TAG_REM, ram_list.phys_dirty_size);
+ AssertLogRelMsgReturn(ram_list.phys_dirty, ("Failed to allocate %u bytes of dirty page map bytes\n", ram_list.phys_dirty_size), VERR_NO_MEMORY);
}
else
{
/*
* Fill it up the nearest 4GB RAM and leave at least _64KB of guard after it.
*/
- uint32_t cbBitmapAligned = RT_ALIGN_32(phys_ram_dirty_size, PAGE_SIZE);
- uint32_t cbBitmapFull = RT_ALIGN_32(phys_ram_dirty_size, (_4G >> PAGE_SHIFT));
+ uint32_t cbBitmapAligned = RT_ALIGN_32(ram_list.phys_dirty_size, PAGE_SIZE);
+ uint32_t cbBitmapFull = RT_ALIGN_32(ram_list.phys_dirty_size, (_4G >> PAGE_SHIFT));
if (cbBitmapFull == cbBitmapAligned)
cbBitmapFull += _4G >> PAGE_SHIFT;
else if (cbBitmapFull - cbBitmapAligned < _64K)
cbBitmapFull += _64K;
- phys_ram_dirty = RTMemPageAlloc(cbBitmapFull);
- AssertLogRelMsgReturn(phys_ram_dirty, ("Failed to allocate %u bytes of dirty page map bytes\n", cbBitmapFull), VERR_NO_MEMORY);
+ ram_list.phys_dirty = RTMemPageAlloc(cbBitmapFull);
+ AssertLogRelMsgReturn(ram_list.phys_dirty, ("Failed to allocate %u bytes of dirty page map bytes\n", cbBitmapFull), VERR_NO_MEMORY);
- rc = RTMemProtect(phys_ram_dirty + cbBitmapAligned, cbBitmapFull - cbBitmapAligned, RTMEM_PROT_NONE);
+ rc = RTMemProtect(ram_list.phys_dirty + cbBitmapAligned, cbBitmapFull - cbBitmapAligned, RTMEM_PROT_NONE);
if (RT_FAILURE(rc))
{
- RTMemPageFree(phys_ram_dirty, cbBitmapFull);
+ RTMemPageFree(ram_list.phys_dirty, cbBitmapFull);
AssertLogRelRCReturn(rc, rc);
}
- phys_ram_dirty += cbBitmapAligned - phys_ram_dirty_size;
+ ram_list.phys_dirty += cbBitmapAligned - ram_list.phys_dirty_size;
}
/* initialize it. */
- memset(phys_ram_dirty, 0xff, phys_ram_dirty_size);
+ memset(ram_list.phys_dirty, 0xff, ram_list.phys_dirty_size);
return rc;
}
@@ -603,6 +612,8 @@ REMR3DECL(int) REMR3Term(PVM pVM)
*/
REMR3DECL(void) REMR3Reset(PVM pVM)
{
+ EMRemLock(pVM); /* Only pro forma, we're in a rendezvous. */
+
/*
* Reset the REM cpu.
*/
@@ -618,6 +629,8 @@ REMR3DECL(void) REMR3Reset(PVM pVM)
/* Flush the TBs the next time we execute code here. */
pVM->rem.s.fFlushTBs = true;
+
+ EMRemUnlock(pVM);
}
@@ -760,11 +773,6 @@ static DECLCALLBACK(int) remR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion,
CPUMGetGuestCpuId(pVCpu, 0x80000001, &u32Dummy, &u32Dummy, &u32Dummy, &pVM->rem.s.Env.cpuid_ext2_features);
/*
- * Sync the Load Flush the TLB
- */
- tlb_flush(&pRem->Env, 1);
-
- /*
* Stop ignoring ignorable notifications.
*/
ASMAtomicDecU32(&pVM->rem.s.cIgnoreAll);
@@ -810,7 +818,7 @@ REMR3DECL(int) REMR3Step(PVM pVM, PVMCPU pVCpu)
* pending interrupts and suchlike.
*/
interrupt_request = pVM->rem.s.Env.interrupt_request;
- Assert(!(interrupt_request & ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXIT | CPU_INTERRUPT_EXITTB | CPU_INTERRUPT_TIMER | CPU_INTERRUPT_EXTERNAL_HARD | CPU_INTERRUPT_EXTERNAL_EXIT | CPU_INTERRUPT_EXTERNAL_TIMER)));
+ Assert(!(interrupt_request & ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB | CPU_INTERRUPT_TIMER | CPU_INTERRUPT_EXTERNAL_HARD | CPU_INTERRUPT_EXTERNAL_EXIT | CPU_INTERRUPT_EXTERNAL_FLUSH_TLB | CPU_INTERRUPT_EXTERNAL_TIMER)));
pVM->rem.s.Env.interrupt_request = 0;
cpu_single_step(&pVM->rem.s.Env, 1);
@@ -818,7 +826,7 @@ REMR3DECL(int) REMR3Step(PVM pVM, PVMCPU pVCpu)
* If we're standing at a breakpoint, that have to be disabled before we start stepping.
*/
GCPtrPC = pVM->rem.s.Env.eip + pVM->rem.s.Env.segs[R_CS].base;
- fBp = !cpu_breakpoint_remove(&pVM->rem.s.Env, GCPtrPC);
+ fBp = !cpu_breakpoint_remove(&pVM->rem.s.Env, GCPtrPC, BP_GDB);
/*
* Execute and handle the return code.
@@ -861,7 +869,7 @@ REMR3DECL(int) REMR3Step(PVM pVM, PVMCPU pVCpu)
*/
if (fBp)
{
- int rc2 = cpu_breakpoint_insert(&pVM->rem.s.Env, GCPtrPC);
+ int rc2 = cpu_breakpoint_insert(&pVM->rem.s.Env, GCPtrPC, BP_GDB, NULL);
Assert(rc2 == 0); NOREF(rc2);
}
cpu_single_step(&pVM->rem.s.Env, 0);
@@ -882,7 +890,7 @@ REMR3DECL(int) REMR3Step(PVM pVM, PVMCPU pVCpu)
REMR3DECL(int) REMR3BreakpointSet(PVM pVM, RTGCUINTPTR Address)
{
VM_ASSERT_EMT(pVM);
- if (!cpu_breakpoint_insert(&pVM->rem.s.Env, Address))
+ if (!cpu_breakpoint_insert(&pVM->rem.s.Env, Address, BP_GDB, NULL))
{
LogFlow(("REMR3BreakpointSet: Address=%RGv\n", Address));
return VINF_SUCCESS;
@@ -903,7 +911,7 @@ REMR3DECL(int) REMR3BreakpointSet(PVM pVM, RTGCUINTPTR Address)
REMR3DECL(int) REMR3BreakpointClear(PVM pVM, RTGCUINTPTR Address)
{
VM_ASSERT_EMT(pVM);
- if (!cpu_breakpoint_remove(&pVM->rem.s.Env, Address))
+ if (!cpu_breakpoint_remove(&pVM->rem.s.Env, Address, BP_GDB))
{
LogFlow(("REMR3BreakpointClear: Address=%RGv\n", Address));
return VINF_SUCCESS;
@@ -950,8 +958,12 @@ REMR3DECL(int) REMR3EmulateInstruction(PVM pVM, PVMCPU pVCpu)
if (RT_SUCCESS(rc))
{
int interrupt_request = pVM->rem.s.Env.interrupt_request;
- Assert(!(interrupt_request & ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXIT | CPU_INTERRUPT_EXITTB | CPU_INTERRUPT_TIMER | CPU_INTERRUPT_EXTERNAL_HARD | CPU_INTERRUPT_EXTERNAL_EXIT | CPU_INTERRUPT_EXTERNAL_TIMER)));
+ Assert(!(interrupt_request & ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB | CPU_INTERRUPT_TIMER | CPU_INTERRUPT_EXTERNAL_HARD | CPU_INTERRUPT_EXTERNAL_EXIT | CPU_INTERRUPT_EXTERNAL_FLUSH_TLB | CPU_INTERRUPT_EXTERNAL_TIMER)));
+#ifdef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
+ cpu_single_step(&pVM->rem.s.Env, 0);
+#endif
Assert(!pVM->rem.s.Env.singlestep_enabled);
+
/*
* Now we set the execute single instruction flag and enter the cpu_exec loop.
*/
@@ -983,20 +995,23 @@ REMR3DECL(int) REMR3EmulateInstruction(PVM pVM, PVMCPU pVCpu)
* If there was a breakpoint there we're fucked now.
*/
case EXCP_DEBUG:
- {
- /* breakpoint or single step? */
- RTGCPTR GCPtrPC = pVM->rem.s.Env.eip + pVM->rem.s.Env.segs[R_CS].base;
- int iBP;
- rc = VINF_EM_DBG_STEPPED;
- for (iBP = 0; iBP < pVM->rem.s.Env.nb_breakpoints; iBP++)
- if (pVM->rem.s.Env.breakpoints[iBP] == GCPtrPC)
- {
- rc = VINF_EM_DBG_BREAKPOINT;
- break;
- }
- Log2(("REMR3EmulateInstruction: cpu_exec -> EXCP_DEBUG rc=%Rrc iBP=%d GCPtrPC=%RGv\n", rc, iBP, GCPtrPC));
+ if (pVM->rem.s.Env.watchpoint_hit)
+ {
+ /** @todo deal with watchpoints */
+ Log2(("REMR3EmulateInstruction: cpu_exec -> EXCP_DEBUG rc=%Rrc !watchpoint_hit!\n", rc));
+ rc = VINF_EM_DBG_BREAKPOINT;
+ }
+ else
+ {
+ CPUBreakpoint *pBP;
+ RTGCPTR GCPtrPC = pVM->rem.s.Env.eip + pVM->rem.s.Env.segs[R_CS].base;
+ QTAILQ_FOREACH(pBP, &pVM->rem.s.Env.breakpoints, entry)
+ if (pBP->pc == GCPtrPC)
+ break;
+ rc = pBP ? VINF_EM_DBG_BREAKPOINT : VINF_EM_DBG_STEPPED;
+ Log2(("REMR3EmulateInstruction: cpu_exec -> EXCP_DEBUG rc=%Rrc pBP=%p GCPtrPC=%RGv\n", rc, pBP, GCPtrPC));
+ }
break;
- }
/*
* hlt instruction.
@@ -1064,6 +1079,207 @@ REMR3DECL(int) REMR3EmulateInstruction(PVM pVM, PVMCPU pVCpu)
/**
+ * Used by REMR3Run to handle the case where CPU_EMULATE_SINGLE_STEP is set.
+ *
+ * @returns VBox status code.
+ *
+ * @param pVM The VM handle.
+ * @param pVCpu The Virtual CPU handle.
+ */
+static int remR3RunLoggingStep(PVM pVM, PVMCPU pVCpu)
+{
+ int rc;
+
+ Assert(pVM->rem.s.fInREM);
+#ifdef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
+ cpu_single_step(&pVM->rem.s.Env, 1);
+#else
+ Assert(!pVM->rem.s.Env.singlestep_enabled);
+#endif
+
+ /*
+ * Now we set the execute single instruction flag and enter the cpu_exec loop.
+ */
+ for (;;)
+ {
+ char szBuf[256];
+
+ /*
+ * Log the current registers state and instruction.
+ */
+ remR3StateUpdate(pVM, pVCpu);
+ DBGFR3Info(pVM, "cpumguest", NULL, NULL);
+ szBuf[0] = '\0';
+ rc = DBGFR3DisasInstrEx(pVM,
+ pVCpu->idCpu,
+ 0, /* Sel */
+ 0, /* GCPtr */
+ DBGF_DISAS_FLAGS_CURRENT_GUEST
+ | DBGF_DISAS_FLAGS_DEFAULT_MODE
+ | DBGF_DISAS_FLAGS_HID_SEL_REGS_VALID,
+ szBuf,
+ sizeof(szBuf),
+ NULL);
+ if (RT_FAILURE(rc))
+ RTStrPrintf(szBuf, sizeof(szBuf), "DBGFR3DisasInstrEx failed with rc=%Rrc\n", rc);
+ RTLogPrintf("CPU%d: %s\n", pVCpu->idCpu, szBuf);
+
+ /*
+ * Execute the instruction.
+ */
+ TMNotifyStartOfExecution(pVCpu);
+
+ if ( pVM->rem.s.Env.exception_index < 0
+ || pVM->rem.s.Env.exception_index > 256)
+ pVM->rem.s.Env.exception_index = -1; /** @todo We need to do similar stuff elsewhere, I think. */
+
+#ifdef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
+ pVM->rem.s.Env.interrupt_request = 0;
+#else
+ pVM->rem.s.Env.interrupt_request = CPU_INTERRUPT_SINGLE_INSTR;
+#endif
+ if ( VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
+ || pVM->rem.s.u32PendingInterrupt != REM_NO_PENDING_IRQ)
+ pVM->rem.s.Env.interrupt_request |= CPU_INTERRUPT_HARD;
+ RTLogPrintf("remR3RunLoggingStep: interrupt_request=%#x halted=%d exception_index=%#x\n", rc,
+ pVM->rem.s.Env.interrupt_request,
+ pVM->rem.s.Env.halted,
+ pVM->rem.s.Env.exception_index
+ );
+
+ rc = cpu_exec(&pVM->rem.s.Env);
+
+ RTLogPrintf("remR3RunLoggingStep: cpu_exec -> %#x interrupt_request=%#x halted=%d exception_index=%#x\n", rc,
+ pVM->rem.s.Env.interrupt_request,
+ pVM->rem.s.Env.halted,
+ pVM->rem.s.Env.exception_index
+ );
+
+ TMNotifyEndOfExecution(pVCpu);
+
+ switch (rc)
+ {
+#ifndef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
+ /*
+ * The normal exit.
+ */
+ case EXCP_SINGLE_INSTR:
+ if ( !VM_FF_ISPENDING(pVM, VM_FF_ALL_REM_MASK)
+ && !VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_REM_MASK))
+ continue;
+ RTLogPrintf("remR3RunLoggingStep: rc=VINF_SUCCESS w/ FFs (%#x/%#x)\n",
+ pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions);
+ rc = VINF_SUCCESS;
+ break;
+
+#else
+ /*
+ * The normal exit, check for breakpoints at PC just to be sure.
+ */
+#endif
+ case EXCP_DEBUG:
+ if (pVM->rem.s.Env.watchpoint_hit)
+ {
+ /** @todo deal with watchpoints */
+ Log2(("remR3RunLoggingStep: cpu_exec -> EXCP_DEBUG rc=%Rrc !watchpoint_hit!\n", rc));
+ rc = VINF_EM_DBG_BREAKPOINT;
+ }
+ else
+ {
+ CPUBreakpoint *pBP;
+ RTGCPTR GCPtrPC = pVM->rem.s.Env.eip + pVM->rem.s.Env.segs[R_CS].base;
+ QTAILQ_FOREACH(pBP, &pVM->rem.s.Env.breakpoints, entry)
+ if (pBP->pc == GCPtrPC)
+ break;
+ rc = pBP ? VINF_EM_DBG_BREAKPOINT : VINF_EM_DBG_STEPPED;
+ Log2(("remR3RunLoggingStep: cpu_exec -> EXCP_DEBUG rc=%Rrc pBP=%p GCPtrPC=%RGv\n", rc, pBP, GCPtrPC));
+ }
+#ifdef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
+ if (rc == VINF_EM_DBG_STEPPED)
+ {
+ if ( !VM_FF_ISPENDING(pVM, VM_FF_ALL_REM_MASK)
+ && !VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_REM_MASK))
+ continue;
+
+ RTLogPrintf("remR3RunLoggingStep: rc=VINF_SUCCESS w/ FFs (%#x/%#x)\n",
+ pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions);
+ rc = VINF_SUCCESS;
+ }
+#endif
+ break;
+
+ /*
+ * If we take a trap or start servicing a pending interrupt, we might end up here.
+ * (Timer thread or some other thread wishing EMT's attention.)
+ */
+ case EXCP_INTERRUPT:
+ RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_INTERRUPT rc=VINF_SUCCESS\n");
+ rc = VINF_SUCCESS;
+ break;
+
+ /*
+ * hlt instruction.
+ */
+ case EXCP_HLT:
+ RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_HLT rc=VINF_EM_HALT\n");
+ rc = VINF_EM_HALT;
+ break;
+
+ /*
+ * The VM has halted.
+ */
+ case EXCP_HALTED:
+ RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_HALTED rc=VINF_EM_HALT\n");
+ rc = VINF_EM_HALT;
+ break;
+
+ /*
+ * Switch to RAW-mode.
+ */
+ case EXCP_EXECUTE_RAW:
+ RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_EXECUTE_RAW rc=VINF_EM_RESCHEDULE_RAW\n");
+ rc = VINF_EM_RESCHEDULE_RAW;
+ break;
+
+ /*
+ * Switch to hardware accelerated RAW-mode.
+ */
+ case EXCP_EXECUTE_HWACC:
+ RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_EXECUTE_HWACC rc=VINF_EM_RESCHEDULE_HWACC\n");
+ rc = VINF_EM_RESCHEDULE_HWACC;
+ break;
+
+ /*
+ * An EM RC was raised (VMR3Reset/Suspend/PowerOff/some-fatal-error).
+ */
+ case EXCP_RC:
+ RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_RC rc=%Rrc\n", pVM->rem.s.rc);
+ rc = pVM->rem.s.rc;
+ pVM->rem.s.rc = VERR_INTERNAL_ERROR;
+ break;
+
+ /*
+ * Figure out the rest when they arrive....
+ */
+ default:
+ AssertMsgFailed(("rc=%d\n", rc));
+ RTLogPrintf("remR3RunLoggingStep: cpu_exec -> %d rc=VINF_EM_RESCHEDULE\n", rc);
+ rc = VINF_EM_RESCHEDULE;
+ break;
+ }
+ break;
+ }
+
+#ifdef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
+// cpu_single_step(&pVM->rem.s.Env, 0);
+#else
+ pVM->rem.s.Env.interrupt_request &= ~(CPU_INTERRUPT_SINGLE_INSTR | CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT);
+#endif
+ return rc;
+}
+
+
+/**
* Runs code in recompiled mode.
*
* Before calling this function the REM state needs to be in sync with
@@ -1079,8 +1295,12 @@ REMR3DECL(int) REMR3EmulateInstruction(PVM pVM, PVMCPU pVCpu)
REMR3DECL(int) REMR3Run(PVM pVM, PVMCPU pVCpu)
{
int rc;
- Log2(("REMR3Run: (cs:eip=%04x:%RGv)\n", pVM->rem.s.Env.segs[R_CS].selector, (RTGCPTR)pVM->rem.s.Env.eip));
+
+ if (RT_UNLIKELY(pVM->rem.s.Env.state & CPU_EMULATE_SINGLE_STEP))
+ return remR3RunLoggingStep(pVM, pVCpu);
+
Assert(pVM->rem.s.fInREM);
+ Log2(("REMR3Run: (cs:eip=%04x:%RGv)\n", pVM->rem.s.Env.segs[R_CS].selector, (RTGCPTR)pVM->rem.s.Env.eip));
TMNotifyStartOfExecution(pVCpu);
rc = cpu_exec(&pVM->rem.s.Env);
@@ -1116,41 +1336,23 @@ REMR3DECL(int) REMR3Run(PVM pVM, PVMCPU pVCpu)
* Breakpoint/single step.
*/
case EXCP_DEBUG:
- {
-#if 0//def DEBUG_bird
- static int iBP = 0;
- printf("howdy, breakpoint! iBP=%d\n", iBP);
- switch (iBP)
+ if (pVM->rem.s.Env.watchpoint_hit)
{
- case 0:
- cpu_breakpoint_remove(&pVM->rem.s.Env, pVM->rem.s.Env.eip + pVM->rem.s.Env.segs[R_CS].base);
- pVM->rem.s.Env.state |= CPU_EMULATE_SINGLE_STEP;
- //pVM->rem.s.Env.interrupt_request = 0;
- //pVM->rem.s.Env.exception_index = -1;
- //g_fInterruptDisabled = 1;
- rc = VINF_SUCCESS;
- asm("int3");
- break;
- default:
- asm("int3");
- break;
+ /** @todo deal with watchpoints */
+ Log2(("REMR3Run: cpu_exec -> EXCP_DEBUG rc=%Rrc !watchpoint_hit!\n", rc));
+ rc = VINF_EM_DBG_BREAKPOINT;
+ }
+ else
+ {
+ CPUBreakpoint *pBP;
+ RTGCPTR GCPtrPC = pVM->rem.s.Env.eip + pVM->rem.s.Env.segs[R_CS].base;
+ QTAILQ_FOREACH(pBP, &pVM->rem.s.Env.breakpoints, entry)
+ if (pBP->pc == GCPtrPC)
+ break;
+ rc = pBP ? VINF_EM_DBG_BREAKPOINT : VINF_EM_DBG_STEPPED;
+ Log2(("REMR3Run: cpu_exec -> EXCP_DEBUG rc=%Rrc pBP=%p GCPtrPC=%RGv\n", rc, pBP, GCPtrPC));
}
- iBP++;
-#else
- /* breakpoint or single step? */
- RTGCPTR GCPtrPC = pVM->rem.s.Env.eip + pVM->rem.s.Env.segs[R_CS].base;
- int iBP;
- rc = VINF_EM_DBG_STEPPED;
- for (iBP = 0; iBP < pVM->rem.s.Env.nb_breakpoints; iBP++)
- if (pVM->rem.s.Env.breakpoints[iBP] == GCPtrPC)
- {
- rc = VINF_EM_DBG_BREAKPOINT;
- break;
- }
- Log2(("REMR3Run: cpu_exec -> EXCP_DEBUG rc=%Rrc iBP=%d GCPtrPC=%RGv\n", rc, iBP, GCPtrPC));
-#endif
break;
- }
/*
* Switch to RAW-mode.
@@ -1195,7 +1397,8 @@ REMR3DECL(int) REMR3Run(PVM pVM, PVMCPU pVCpu)
/**
* Check if the cpu state is suitable for Raw execution.
*
- * @returns boolean
+ * @returns true if RAW/HWACC mode is ok, false if we should stay in REM.
+ *
* @param env The CPU env struct.
* @param eip The EIP to check this for (might differ from env->eip).
* @param fFlags hflags OR'ed with IOPL, TF and VM from eflags.
@@ -1203,16 +1406,24 @@ REMR3DECL(int) REMR3Run(PVM pVM, PVMCPU pVCpu)
*
* @remark This function must be kept in perfect sync with the scheduler in EM.cpp!
*/
-bool remR3CanExecuteRaw(CPUState *env, RTGCPTR eip, unsigned fFlags, int *piException)
+bool remR3CanExecuteRaw(CPUX86State *env, RTGCPTR eip, unsigned fFlags, int *piException)
{
/* !!! THIS MUST BE IN SYNC WITH emR3Reschedule !!! */
/* !!! THIS MUST BE IN SYNC WITH emR3Reschedule !!! */
/* !!! THIS MUST BE IN SYNC WITH emR3Reschedule !!! */
uint32_t u32CR0;
+#ifdef IEM_VERIFICATION_MODE
+ return false;
+#endif
+
/* Update counter. */
env->pVM->rem.s.cCanExecuteRaw++;
+ /* Never when single stepping+logging guest code. */
+ if (env->state & CPU_EMULATE_SINGLE_STEP)
+ return false;
+
if (HWACCMIsEnabled(env->pVM))
{
CPUMCTX Ctx;
@@ -1326,12 +1537,18 @@ bool remR3CanExecuteRaw(CPUState *env, RTGCPTR eip, unsigned fFlags, int *piExce
return false;
}
- if (env->nb_breakpoints > 0)
+ if (!QTAILQ_EMPTY(&env->breakpoints))
{
//Log2(("raw mode refused: Breakpoints\n"));
return false;
}
+ if (!QTAILQ_EMPTY(&env->watchpoints))
+ {
+ //Log2(("raw mode refused: Watchpoints\n"));
+ return false;
+ }
+
u32CR0 = env->cr[0];
if ((u32CR0 & (X86_CR0_PG | X86_CR0_PE)) != (X86_CR0_PG | X86_CR0_PE))
{
@@ -1441,7 +1658,7 @@ bool remR3CanExecuteRaw(CPUState *env, RTGCPTR eip, unsigned fFlags, int *piExce
* @param GCPtrInstr Where to fetch code.
* @param pu8Byte Where to store the byte on success
*/
-bool remR3GetOpcode(CPUState *env, RTGCPTR GCPtrInstr, uint8_t *pu8Byte)
+bool remR3GetOpcode(CPUX86State *env, RTGCPTR GCPtrInstr, uint8_t *pu8Byte)
{
int rc = PATMR3QueryOpcode(env->pVM, GCPtrInstr, pu8Byte);
if (RT_SUCCESS(rc))
@@ -1458,12 +1675,14 @@ bool remR3GetOpcode(CPUState *env, RTGCPTR GCPtrInstr, uint8_t *pu8Byte)
* @param env Pointer to cpu environment.
* @param GCPtr The virtual address which page table/dir entry should be invalidated.
*/
-void remR3FlushPage(CPUState *env, RTGCPTR GCPtr)
+void remR3FlushPage(CPUX86State *env, RTGCPTR GCPtr)
{
PVM pVM = env->pVM;
PCPUMCTX pCtx;
int rc;
+ Assert(EMRemIsLockOwner(env->pVM));
+
/*
* When we're replaying invlpg instructions or restoring a saved
* state we disable this path.
@@ -1502,7 +1721,7 @@ void remR3FlushPage(CPUState *env, RTGCPTR GCPtr)
#ifndef REM_PHYS_ADDR_IN_TLB
/** Wrapper for PGMR3PhysTlbGCPhys2Ptr. */
-void *remR3TlbGCPhys2Ptr(CPUState *env1, target_ulong physAddr, int fWritable)
+void *remR3TlbGCPhys2Ptr(CPUX86State *env1, target_ulong physAddr, int fWritable)
{
void *pv;
int rc;
@@ -1530,7 +1749,7 @@ void *remR3TlbGCPhys2Ptr(CPUState *env1, target_ulong physAddr, int fWritable)
* @param env Pointer to the CPU environment.
* @param GCPtr Code page to monitor
*/
-void remR3ProtectCode(CPUState *env, RTGCPTR GCPtr)
+void remR3ProtectCode(CPUX86State *env, RTGCPTR GCPtr)
{
#ifdef VBOX_REM_PROTECT_PAGES_FROM_SMC
Assert(env->pVM->rem.s.fInREM);
@@ -1550,7 +1769,7 @@ void remR3ProtectCode(CPUState *env, RTGCPTR GCPtr)
* @param env Pointer to the CPU environment.
* @param GCPtr Code page to monitor
*/
-void remR3UnprotectCode(CPUState *env, RTGCPTR GCPtr)
+void remR3UnprotectCode(CPUX86State *env, RTGCPTR GCPtr)
{
Assert(env->pVM->rem.s.fInREM);
#ifdef VBOX_REM_PROTECT_PAGES_FROM_SMC
@@ -1571,10 +1790,11 @@ void remR3UnprotectCode(CPUState *env, RTGCPTR GCPtr)
* @param env Pointer to the CPU environment.
* @param fGlobal Set if the flush is global.
*/
-void remR3FlushTLB(CPUState *env, bool fGlobal)
+void remR3FlushTLB(CPUX86State *env, bool fGlobal)
{
- PVM pVM = env->pVM;
+ PVM pVM = env->pVM;
PCPUMCTX pCtx;
+ Assert(EMRemIsLockOwner(pVM));
/*
* When we're replaying invlpg instructions or restoring a saved
@@ -1615,7 +1835,7 @@ void remR3FlushTLB(CPUState *env, bool fGlobal)
*
* @param env Pointer to the CPU environment.
*/
-void remR3ChangeCpuMode(CPUState *env)
+void remR3ChangeCpuMode(CPUX86State *env)
{
PVM pVM = env->pVM;
uint64_t efer;
@@ -1667,7 +1887,7 @@ void remR3ChangeCpuMode(CPUState *env)
*
* @param env Pointer to the CPU environment.
*/
-void remR3DmaRun(CPUState *env)
+void remR3DmaRun(CPUX86State *env)
{
remR3ProfileStop(STATS_QEMU_RUN_EMULATED_CODE);
PDMR3DmaRun(env->pVM);
@@ -1680,7 +1900,7 @@ void remR3DmaRun(CPUState *env)
*
* @param env Pointer to the CPU environment.
*/
-void remR3TimersRun(CPUState *env)
+void remR3TimersRun(CPUX86State *env)
{
LogFlow(("remR3TimersRun:\n"));
LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP_TM, ("remR3TimersRun\n"));
@@ -1701,7 +1921,7 @@ void remR3TimersRun(CPUState *env)
* @param uErrorCode Error code
* @param pvNextEIP Next EIP
*/
-int remR3NotifyTrap(CPUState *env, uint32_t uTrap, uint32_t uErrorCode, RTGCPTR pvNextEIP)
+int remR3NotifyTrap(CPUX86State *env, uint32_t uTrap, uint32_t uErrorCode, RTGCPTR pvNextEIP)
{
PVM pVM = env->pVM;
#ifdef VBOX_WITH_STATISTICS
@@ -1772,7 +1992,7 @@ void remR3TrapClear(PVM pVM)
*
* @param env Pointer to the CPU environment.
*/
-void remR3RecordCall(CPUState *env)
+void remR3RecordCall(CPUX86State *env)
{
CSAMR3RecordCallAddress(env->pVM, env->eip);
}
@@ -1886,26 +2106,35 @@ REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu)
for (i=0;i<8;i++)
pVM->rem.s.Env.dr[i] = pCtx->dr[i];
+#ifdef HF_HALTED_MASK /** @todo remove me when we're up to date again. */
/*
* Clear the halted hidden flag (the interrupt waking up the CPU can
* have been dispatched in raw mode).
*/
pVM->rem.s.Env.hflags &= ~HF_HALTED_MASK;
+#endif
/*
- * Replay invlpg?
+ * Replay invlpg? Only if we're not flushing the TLB.
*/
+ fFlags = CPUMR3RemEnter(pVCpu, &uCpl);
+ LogFlow(("CPUMR3RemEnter %x %x\n", fFlags, uCpl));
if (pVM->rem.s.cInvalidatedPages)
{
- RTUINT i;
-
- pVM->rem.s.fIgnoreInvlPg = true;
- for (i = 0; i < pVM->rem.s.cInvalidatedPages; i++)
+ if (!(fFlags & CPUM_CHANGED_GLOBAL_TLB_FLUSH))
{
- Log2(("REMR3State: invlpg %RGv\n", pVM->rem.s.aGCPtrInvalidatedPages[i]));
- tlb_flush_page(&pVM->rem.s.Env, pVM->rem.s.aGCPtrInvalidatedPages[i]);
+ RTUINT i;
+
+ pVM->rem.s.fIgnoreCR3Load = true;
+ pVM->rem.s.fIgnoreInvlPg = true;
+ for (i = 0; i < pVM->rem.s.cInvalidatedPages; i++)
+ {
+ Log2(("REMR3State: invlpg %RGv\n", pVM->rem.s.aGCPtrInvalidatedPages[i]));
+ tlb_flush_page(&pVM->rem.s.Env, pVM->rem.s.aGCPtrInvalidatedPages[i]);
+ }
+ pVM->rem.s.fIgnoreInvlPg = false;
+ pVM->rem.s.fIgnoreCR3Load = false;
}
- pVM->rem.s.fIgnoreInvlPg = false;
pVM->rem.s.cInvalidatedPages = 0;
}
@@ -1932,8 +2161,6 @@ REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu)
/*
* Registers which are rarely changed and require special handling / order when changed.
*/
- fFlags = CPUMR3RemEnter(pVCpu, &uCpl);
- LogFlow(("CPUMR3RemEnter %x %x\n", fFlags, uCpl));
if (fFlags & ( CPUM_CHANGED_GLOBAL_TLB_FLUSH
| CPUM_CHANGED_CR4
| CPUM_CHANGED_CR0
@@ -2201,20 +2428,25 @@ REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu)
}
/* get error code and cr2 if needed. */
- switch (u8TrapNo)
+ if (enmType == TRPM_TRAP)
{
- case 0x0e:
- pVM->rem.s.Env.cr[2] = TRPMGetFaultAddress(pVCpu);
- /* fallthru */
- case 0x0a: case 0x0b: case 0x0c: case 0x0d:
- pVM->rem.s.Env.error_code = TRPMGetErrorCode(pVCpu);
- break;
+ switch (u8TrapNo)
+ {
+ case 0x0e:
+ pVM->rem.s.Env.cr[2] = TRPMGetFaultAddress(pVCpu);
+ /* fallthru */
+ case 0x0a: case 0x0b: case 0x0c: case 0x0d:
+ pVM->rem.s.Env.error_code = TRPMGetErrorCode(pVCpu);
+ break;
- case 0x11: case 0x08:
- default:
- pVM->rem.s.Env.error_code = 0;
- break;
+ case 0x11: case 0x08:
+ default:
+ pVM->rem.s.Env.error_code = 0;
+ break;
+ }
}
+ else
+ pVM->rem.s.Env.error_code = 0;
/*
* We can now reset the active trap since the recompiler is gonna have a go at it.
@@ -2229,7 +2461,7 @@ REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu)
* Clear old interrupt request flags; Check for pending hardware interrupts.
* (See @remark for why we don't check for other FFs.)
*/
- pVM->rem.s.Env.interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXIT | CPU_INTERRUPT_EXITTB | CPU_INTERRUPT_TIMER);
+ pVM->rem.s.Env.interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB | CPU_INTERRUPT_TIMER);
if ( pVM->rem.s.u32PendingInterrupt != REM_NO_PENDING_IRQ
|| VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
pVM->rem.s.Env.interrupt_request |= CPU_INTERRUPT_HARD;
@@ -2937,7 +3169,7 @@ REMR3DECL(void) REMR3NotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb
ASMAtomicIncU32(&pVM->rem.s.cIgnoreAll);
PDMCritSectEnter(&pVM->rem.s.CritSectRegister, VERR_SEM_BUSY);
- cpu_register_physical_memory(GCPhys, cb, GCPhys);
+ cpu_register_physical_memory_offset(GCPhys, cb, GCPhys, GCPhys);
PDMCritSectLeave(&pVM->rem.s.CritSectRegister);
ASMAtomicDecU32(&pVM->rem.s.cIgnoreAll);
@@ -2973,7 +3205,7 @@ REMR3DECL(void) REMR3NotifyPhysRomRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb,
ASMAtomicIncU32(&pVM->rem.s.cIgnoreAll);
PDMCritSectEnter(&pVM->rem.s.CritSectRegister, VERR_SEM_BUSY);
- cpu_register_physical_memory(GCPhys, cb, GCPhys | (fShadow ? 0 : IO_MEM_ROM));
+ cpu_register_physical_memory_offset(GCPhys, cb, GCPhys | (fShadow ? 0 : IO_MEM_ROM), GCPhys);
PDMCritSectLeave(&pVM->rem.s.CritSectRegister);
ASMAtomicDecU32(&pVM->rem.s.cIgnoreAll);
@@ -3005,7 +3237,7 @@ REMR3DECL(void) REMR3NotifyPhysRamDeregister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb
ASMAtomicIncU32(&pVM->rem.s.cIgnoreAll);
PDMCritSectEnter(&pVM->rem.s.CritSectRegister, VERR_SEM_BUSY);
- cpu_register_physical_memory(GCPhys, cb, IO_MEM_UNASSIGNED);
+ cpu_register_physical_memory_offset(GCPhys, cb, IO_MEM_UNASSIGNED, GCPhys);
PDMCritSectLeave(&pVM->rem.s.CritSectRegister);
ASMAtomicDecU32(&pVM->rem.s.cIgnoreAll);
@@ -3038,9 +3270,9 @@ static void remR3NotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmTy
PDMCritSectEnter(&pVM->rem.s.CritSectRegister, VERR_SEM_BUSY);
if (enmType == PGMPHYSHANDLERTYPE_MMIO)
- cpu_register_physical_memory(GCPhys, cb, pVM->rem.s.iMMIOMemType);
+ cpu_register_physical_memory_offset(GCPhys, cb, pVM->rem.s.iMMIOMemType, GCPhys);
else if (fHasHCHandler)
- cpu_register_physical_memory(GCPhys, cb, pVM->rem.s.iHandlerMemType);
+ cpu_register_physical_memory_offset(GCPhys, cb, pVM->rem.s.iHandlerMemType, GCPhys);
PDMCritSectLeave(&pVM->rem.s.CritSectRegister);
ASMAtomicDecU32(&pVM->rem.s.cIgnoreAll);
@@ -3087,19 +3319,19 @@ static void remR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enm
PDMCritSectEnter(&pVM->rem.s.CritSectRegister, VERR_SEM_BUSY);
/** @todo this isn't right, MMIO can (in theory) be restored as RAM. */
if (enmType == PGMPHYSHANDLERTYPE_MMIO)
- cpu_register_physical_memory(GCPhys, cb, IO_MEM_UNASSIGNED);
+ cpu_register_physical_memory_offset(GCPhys, cb, IO_MEM_UNASSIGNED, GCPhys);
else if (fHasHCHandler)
{
if (!fRestoreAsRAM)
{
Assert(GCPhys > MMR3PhysGetRamSize(pVM));
- cpu_register_physical_memory(GCPhys, cb, IO_MEM_UNASSIGNED);
+ cpu_register_physical_memory_offset(GCPhys, cb, IO_MEM_UNASSIGNED, GCPhys);
}
else
{
Assert(RT_ALIGN_T(GCPhys, PAGE_SIZE, RTGCPHYS) == GCPhys);
Assert(RT_ALIGN_T(cb, PAGE_SIZE, RTGCPHYS) == cb);
- cpu_register_physical_memory(GCPhys, cb, GCPhys);
+ cpu_register_physical_memory_offset(GCPhys, cb, GCPhys, GCPhys);
}
}
PDMCritSectLeave(&pVM->rem.s.CritSectRegister);
@@ -3151,13 +3383,13 @@ static void remR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType
*/
PDMCritSectEnter(&pVM->rem.s.CritSectRegister, VERR_SEM_BUSY);
if (!fRestoreAsRAM)
- cpu_register_physical_memory(GCPhysOld, cb, IO_MEM_UNASSIGNED);
+ cpu_register_physical_memory_offset(GCPhysOld, cb, IO_MEM_UNASSIGNED, GCPhysOld);
else
{
/* This is not perfect, but it'll do for PD monitoring... */
Assert(cb == PAGE_SIZE);
Assert(RT_ALIGN_T(GCPhysOld, PAGE_SIZE, RTGCPHYS) == GCPhysOld);
- cpu_register_physical_memory(GCPhysOld, cb, GCPhysOld);
+ cpu_register_physical_memory_offset(GCPhysOld, cb, GCPhysOld, GCPhysOld);
}
/*
@@ -3165,7 +3397,7 @@ static void remR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType
*/
Assert(RT_ALIGN_T(GCPhysNew, PAGE_SIZE, RTGCPHYS) == GCPhysNew);
Assert(RT_ALIGN_T(cb, PAGE_SIZE, RTGCPHYS) == cb);
- cpu_register_physical_memory(GCPhysNew, cb, pVM->rem.s.iHandlerMemType);
+ cpu_register_physical_memory_offset(GCPhysNew, cb, pVM->rem.s.iHandlerMemType, GCPhysNew);
PDMCritSectLeave(&pVM->rem.s.CritSectRegister);
ASMAtomicDecU32(&pVM->rem.s.cIgnoreAll);
@@ -3227,9 +3459,9 @@ REMR3DECL(bool) REMR3IsPageAccessHandled(PVM pVM, RTGCPHYS GCPhys)
* @param addr The virtual address.
* @param pTLBEntry The TLB entry.
*/
-target_ulong remR3PhysGetPhysicalAddressCode(CPUState* env,
+target_ulong remR3PhysGetPhysicalAddressCode(CPUX86State *env,
target_ulong addr,
- CPUTLBEntry* pTLBEntry,
+ CPUTLBEntry *pTLBEntry,
target_phys_addr_t ioTLBEntry)
{
PVM pVM = env->pVM;
@@ -3646,6 +3878,9 @@ static DECLCALLBACK(int) remR3DisasEnableStepping(PVM pVM, bool fEnable)
pVM->rem.s.Env.state |= CPU_EMULATE_SINGLE_STEP;
else
pVM->rem.s.Env.state &= ~CPU_EMULATE_SINGLE_STEP;
+#ifdef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
+ cpu_single_step(&pVM->rem.s.Env, fEnable);
+#endif
return VINF_SUCCESS;
}
@@ -3675,26 +3910,37 @@ REMR3DECL(int) REMR3DisasEnableStepping(PVM pVM, bool fEnable)
/**
* External Debugger Command: .remstep [on|off|1|0]
*/
-static DECLCALLBACK(int) remR3CmdDisasEnableStepping(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
+static DECLCALLBACK(int) remR3CmdDisasEnableStepping(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
{
- bool fEnable;
int rc;
- /* print status */
if (cArgs == 0)
- return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "DisasStepping is %s\n",
- pVM->rem.s.Env.state & CPU_EMULATE_SINGLE_STEP ? "enabled" : "disabled");
-
- /* convert the argument and change the mode. */
- rc = pCmdHlp->pfnVarToBool(pCmdHlp, &paArgs[0], &fEnable);
- if (RT_FAILURE(rc))
- return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "boolean conversion failed!\n");
- rc = REMR3DisasEnableStepping(pVM, fEnable);
- if (RT_FAILURE(rc))
- return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "REMR3DisasEnableStepping failed!\n");
+ /*
+ * Print the current status.
+ */
+ rc = DBGCCmdHlpPrintf(pCmdHlp, "DisasStepping is %s\n",
+ pVM->rem.s.Env.state & CPU_EMULATE_SINGLE_STEP ? "enabled" : "disabled");
+ else
+ {
+ /*
+ * Convert the argument and change the mode.
+ */
+ bool fEnable;
+ rc = DBGCCmdHlpVarToBool(pCmdHlp, &paArgs[0], &fEnable);
+ if (RT_SUCCESS(rc))
+ {
+ rc = REMR3DisasEnableStepping(pVM, fEnable);
+ if (RT_SUCCESS(rc))
+ rc = DBGCCmdHlpPrintf(pCmdHlp, "DisasStepping was %s\n", fEnable ? "enabled" : "disabled");
+ else
+ rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "REMR3DisasEnableStepping");
+ }
+ else
+ rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGCCmdHlpVarToBool");
+ }
return rc;
}
-#endif
+#endif /* VBOX_WITH_DEBUGGER && !win.amd64 */
/**
@@ -3707,7 +3953,7 @@ static DECLCALLBACK(int) remR3CmdDisasEnableStepping(PCDBGCCMD pCmd, PDBGCCMDHLP
* selector will be inspected.
* @param pszPrefix
*/
-bool remR3DisasInstr(CPUState *env, int f32BitCode, char *pszPrefix)
+bool remR3DisasInstr(CPUX86State *env, int f32BitCode, char *pszPrefix)
{
PVM pVM = env->pVM;
const bool fLog = LogIsEnabled();
@@ -3728,7 +3974,7 @@ bool remR3DisasInstr(CPUState *env, int f32BitCode, char *pszPrefix)
/*
* Log registers if requested.
*/
- if (!fLog2)
+ if (fLog2)
DBGFR3InfoLog(pVM, "cpumguest", pszPrefix);
/*
@@ -3770,12 +4016,7 @@ bool remR3DisasInstr(CPUState *env, int f32BitCode, char *pszPrefix)
*/
void disas(FILE *phFile, void *pvCode, unsigned long cb)
{
-#ifdef DEBUG_TMP_LOGGING
-# define DISAS_PRINTF(x...) fprintf(phFile, x)
-#else
-# define DISAS_PRINTF(x...) RTLogPrintf(x)
if (LogIs2Enabled())
-#endif
{
unsigned off = 0;
char szOutput[256];
@@ -3788,15 +4029,15 @@ void disas(FILE *phFile, void *pvCode, unsigned long cb)
Cpu.mode = CPUMODE_64BIT;
#endif
- DISAS_PRINTF("Recompiled Code: %p %#lx (%ld) bytes\n", pvCode, cb, cb);
+ RTLogPrintf("Recompiled Code: %p %#lx (%ld) bytes\n", pvCode, cb, cb);
while (off < cb)
{
uint32_t cbInstr;
if (RT_SUCCESS(DISInstr(&Cpu, (uintptr_t)pvCode + off, 0, &cbInstr, szOutput)))
- DISAS_PRINTF("%s", szOutput);
+ RTLogPrintf("%s", szOutput);
else
{
- DISAS_PRINTF("disas error\n");
+ RTLogPrintf("disas error\n");
cbInstr = 1;
#ifdef RT_ARCH_AMD64 /** @todo remove when DISInstr starts supporting 64-bit code. */
break;
@@ -3805,8 +4046,6 @@ void disas(FILE *phFile, void *pvCode, unsigned long cb)
off += cbInstr;
}
}
-
-#undef DISAS_PRINTF
}
@@ -3820,12 +4059,7 @@ void disas(FILE *phFile, void *pvCode, unsigned long cb)
*/
void target_disas(FILE *phFile, target_ulong uCode, target_ulong cb, int fFlags)
{
-#ifdef DEBUG_TMP_LOGGING
-# define DISAS_PRINTF(x...) fprintf(phFile, x)
-#else
-# define DISAS_PRINTF(x...) RTLogPrintf(x)
if (LogIs2Enabled())
-#endif
{
PVM pVM = cpu_single_env->pVM;
PVMCPU pVCpu = cpu_single_env->pVCpu;
@@ -3842,7 +4076,7 @@ void target_disas(FILE *phFile, target_ulong uCode, target_ulong cb, int fFlags)
/*
* Do the disassembling.
*/
- DISAS_PRINTF("Guest Code: PC=%llx %llx bytes fFlags=%d\n", (uint64_t)uCode, (uint64_t)cb, fFlags);
+ RTLogPrintf("Guest Code: PC=%llx %llx bytes fFlags=%d\n", (uint64_t)uCode, (uint64_t)cb, fFlags);
cs = cpu_single_env->segs[R_CS].selector;
eip = uCode - cpu_single_env->segs[R_CS].base;
for (;;)
@@ -3857,10 +4091,10 @@ void target_disas(FILE *phFile, target_ulong uCode, target_ulong cb, int fFlags)
szBuf, sizeof(szBuf),
&cbInstr);
if (RT_SUCCESS(rc))
- DISAS_PRINTF("%llx %s\n", (uint64_t)uCode, szBuf);
+ RTLogPrintf("%llx %s\n", (uint64_t)uCode, szBuf);
else
{
- DISAS_PRINTF("%llx %04x:%llx: %s\n", (uint64_t)uCode, cs, (uint64_t)eip, szBuf);
+ RTLogPrintf("%llx %04x:%llx: %s\n", (uint64_t)uCode, cs, (uint64_t)eip, szBuf);
cbInstr = 1;
}
@@ -3872,7 +4106,6 @@ void target_disas(FILE *phFile, target_ulong uCode, target_ulong cb, int fFlags)
eip += cbInstr;
}
}
-#undef DISAS_PRINTF
}
@@ -3948,6 +4181,7 @@ REMR3DECL(uint32_t) REMR3QueryPendingInterrupt(PVM pVM, PVMCPU pVCpu)
*/
REMR3DECL(void) REMR3NotifyInterruptSet(PVM pVM, PVMCPU pVCpu)
{
+#ifndef IEM_VERIFICATION_MODE
LogFlow(("REMR3NotifyInterruptSet: fInRem=%d interrupts %s\n", pVM->rem.s.fInREM,
(pVM->rem.s.Env.eflags & IF_MASK) && !(pVM->rem.s.Env.hflags & HF_INHIBIT_IRQ_MASK) ? "enabled" : "disabled"));
if (pVM->rem.s.fInREM)
@@ -3955,6 +4189,7 @@ REMR3DECL(void) REMR3NotifyInterruptSet(PVM pVM, PVMCPU pVCpu)
ASMAtomicOrS32((int32_t volatile *)&cpu_single_env->interrupt_request,
CPU_INTERRUPT_EXTERNAL_HARD);
}
+#endif
}
@@ -3985,6 +4220,7 @@ REMR3DECL(void) REMR3NotifyInterruptClear(PVM pVM, PVMCPU pVCpu)
*/
REMR3DECL(void) REMR3NotifyTimerPending(PVM pVM, PVMCPU pVCpuDst)
{
+#ifndef IEM_VERIFICATION_MODE
#ifndef DEBUG_bird
LogFlow(("REMR3NotifyTimerPending: fInRem=%d\n", pVM->rem.s.fInREM));
#endif
@@ -4001,6 +4237,7 @@ REMR3DECL(void) REMR3NotifyTimerPending(PVM pVM, PVMCPU pVCpuDst)
}
else
LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP_TM, ("REMR3NotifyTimerPending: !fInREM; cpu state=%d\n", VMCPU_GET_STATE(pVCpuDst)));
+#endif
}
@@ -4012,12 +4249,14 @@ REMR3DECL(void) REMR3NotifyTimerPending(PVM pVM, PVMCPU pVCpuDst)
*/
REMR3DECL(void) REMR3NotifyDmaPending(PVM pVM)
{
+#ifndef IEM_VERIFICATION_MODE
LogFlow(("REMR3NotifyDmaPending: fInRem=%d\n", pVM->rem.s.fInREM));
if (pVM->rem.s.fInREM)
{
ASMAtomicOrS32((int32_t volatile *)&cpu_single_env->interrupt_request,
CPU_INTERRUPT_EXTERNAL_DMA);
}
+#endif
}
@@ -4029,12 +4268,14 @@ REMR3DECL(void) REMR3NotifyDmaPending(PVM pVM)
*/
REMR3DECL(void) REMR3NotifyQueuePending(PVM pVM)
{
+#ifndef IEM_VERIFICATION_MODE
LogFlow(("REMR3NotifyQueuePending: fInRem=%d\n", pVM->rem.s.fInREM));
if (pVM->rem.s.fInREM)
{
ASMAtomicOrS32((int32_t volatile *)&cpu_single_env->interrupt_request,
CPU_INTERRUPT_EXTERNAL_EXIT);
}
+#endif
}
@@ -4046,12 +4287,14 @@ REMR3DECL(void) REMR3NotifyQueuePending(PVM pVM)
*/
REMR3DECL(void) REMR3NotifyFF(PVM pVM)
{
+#ifndef IEM_VERIFICATION_MODE
LogFlow(("REMR3NotifyFF: fInRem=%d\n", pVM->rem.s.fInREM));
if (pVM->rem.s.fInREM)
{
ASMAtomicOrS32((int32_t volatile *)&cpu_single_env->interrupt_request,
CPU_INTERRUPT_EXTERNAL_EXIT);
}
+#endif
}
@@ -4164,7 +4407,7 @@ void cpu_set_ferr(CPUX86State *env)
LogFlow(("cpu_set_ferr: rc=%d\n", rc)); NOREF(rc);
}
-int cpu_get_pic_interrupt(CPUState *env)
+int cpu_get_pic_interrupt(CPUX86State *env)
{
uint8_t u8Interrupt;
int rc;
@@ -4276,7 +4519,7 @@ int cpu_wrmsr(CPUX86State *env, uint32_t idMsr, uint64_t uValue)
#undef LOG_GROUP
#define LOG_GROUP LOG_GROUP_REM_IOPORT
-void cpu_outb(CPUState *env, int addr, int val)
+void cpu_outb(CPUX86State *env, pio_addr_t addr, uint8_t val)
{
int rc;
@@ -4295,7 +4538,7 @@ void cpu_outb(CPUState *env, int addr, int val)
remAbort(rc, __FUNCTION__);
}
-void cpu_outw(CPUState *env, int addr, int val)
+void cpu_outw(CPUX86State *env, pio_addr_t addr, uint16_t val)
{
//Log2(("cpu_outw: addr=%#06x val=%#x\n", addr, val));
int rc = IOMIOPortWrite(env->pVM, (RTIOPORT)addr, val, 2);
@@ -4310,7 +4553,7 @@ void cpu_outw(CPUState *env, int addr, int val)
remAbort(rc, __FUNCTION__);
}
-void cpu_outl(CPUState *env, int addr, int val)
+void cpu_outl(CPUX86State *env, pio_addr_t addr, uint32_t val)
{
int rc;
Log2(("cpu_outl: addr=%#06x val=%#x\n", addr, val));
@@ -4326,7 +4569,7 @@ void cpu_outl(CPUState *env, int addr, int val)
remAbort(rc, __FUNCTION__);
}
-int cpu_inb(CPUState *env, int addr)
+uint8_t cpu_inb(CPUX86State *env, pio_addr_t addr)
{
uint32_t u32 = 0;
int rc = IOMIOPortRead(env->pVM, (RTIOPORT)addr, &u32, 1);
@@ -4334,38 +4577,38 @@ int cpu_inb(CPUState *env, int addr)
{
if (/*addr != 0x61 && */addr != 0x71)
Log2(("cpu_inb: addr=%#06x -> %#x\n", addr, u32));
- return (int)u32;
+ return (uint8_t)u32;
}
if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
{
Log(("cpu_inb: addr=%#06x -> %#x rc=%Rrc\n", addr, u32, rc));
remR3RaiseRC(env->pVM, rc);
- return (int)u32;
+ return (uint8_t)u32;
}
remAbort(rc, __FUNCTION__);
- return 0xff;
+ return UINT8_C(0xff);
}
-int cpu_inw(CPUState *env, int addr)
+uint16_t cpu_inw(CPUX86State *env, pio_addr_t addr)
{
uint32_t u32 = 0;
int rc = IOMIOPortRead(env->pVM, (RTIOPORT)addr, &u32, 2);
if (RT_LIKELY(rc == VINF_SUCCESS))
{
Log2(("cpu_inw: addr=%#06x -> %#x\n", addr, u32));
- return (int)u32;
+ return (uint16_t)u32;
}
if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
{
Log(("cpu_inw: addr=%#06x -> %#x rc=%Rrc\n", addr, u32, rc));
remR3RaiseRC(env->pVM, rc);
- return (int)u32;
+ return (uint16_t)u32;
}
remAbort(rc, __FUNCTION__);
- return 0xffff;
+ return UINT16_C(0xffff);
}
-int cpu_inl(CPUState *env, int addr)
+uint32_t cpu_inl(CPUX86State *env, pio_addr_t addr)
{
uint32_t u32 = 0;
int rc = IOMIOPortRead(env->pVM, (RTIOPORT)addr, &u32, 4);
@@ -4374,16 +4617,16 @@ int cpu_inl(CPUState *env, int addr)
//if (addr==0x01f0 && u32 == 0x6b6d)
// loglevel = ~0;
Log2(("cpu_inl: addr=%#06x -> %#x\n", addr, u32));
- return (int)u32;
+ return u32;
}
if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
{
Log(("cpu_inl: addr=%#06x -> %#x rc=%Rrc\n", addr, u32, rc));
remR3RaiseRC(env->pVM, rc);
- return (int)u32;
+ return u32;
}
remAbort(rc, __FUNCTION__);
- return 0xffffffff;
+ return UINT32_C(0xffffffff);
}
#undef LOG_GROUP
@@ -4395,19 +4638,19 @@ int cpu_inl(CPUState *env, int addr)
/**
* Perform the CPUID instruction.
*
- * ASMCpuId cannot be invoked from some source files where this is used because of global
- * register allocations.
- *
* @param env Pointer to the recompiler CPU structure.
- * @param uOperator CPUID operation (eax).
+ * @param idx The CPUID leaf (eax).
+ * @param idxSub The CPUID sub-leaf (ecx) where applicable.
* @param pvEAX Where to store eax.
* @param pvEBX Where to store ebx.
* @param pvECX Where to store ecx.
* @param pvEDX Where to store edx.
*/
-void remR3CpuId(CPUState *env, unsigned uOperator, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX)
+void cpu_x86_cpuid(CPUX86State *env, uint32_t idx, uint32_t idxSub,
+ uint32_t *pEAX, uint32_t *pEBX, uint32_t *pECX, uint32_t *pEDX)
{
- CPUMGetGuestCpuId(env->pVCpu, uOperator, (uint32_t *)pvEAX, (uint32_t *)pvEBX, (uint32_t *)pvECX, (uint32_t *)pvEDX);
+ NOREF(idxSub);
+ CPUMGetGuestCpuId(env->pVCpu, idx, pEAX, pEBX, pECX, pEDX);
}
@@ -4445,7 +4688,7 @@ void hw_error(const char *pszFormat, ...)
* Interface for the qemu cpu to report unhandled situation
* raising a fatal VM error.
*/
-void cpu_abort(CPUState *env, const char *pszFormat, ...)
+void cpu_abort(CPUX86State *env, const char *pszFormat, ...)
{
va_list va;
PVM pVM;
@@ -5186,6 +5429,6 @@ void *memcpy(void *dst, const void *src, size_t size)
#endif
-void cpu_smm_update(CPUState *env)
+void cpu_smm_update(CPUX86State *env)
{
}
diff --git a/src/recompiler/a.out.h b/src/recompiler/a.out.h
deleted file mode 100644
index 5337044a3..000000000
--- a/src/recompiler/a.out.h
+++ /dev/null
@@ -1,431 +0,0 @@
-/* a.out.h
-
- Copyright 1997, 1998, 1999, 2001 Red Hat, Inc.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#ifndef _A_OUT_H_
-#define _A_OUT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#define COFF_IMAGE_WITH_PE
-#define COFF_LONG_SECTION_NAMES
-
-/*** coff information for Intel 386/486. */
-
-
-/********************** FILE HEADER **********************/
-
-struct external_filehdr {
- short f_magic; /* magic number */
- short f_nscns; /* number of sections */
- unsigned long f_timdat; /* time & date stamp */
- unsigned long f_symptr; /* file pointer to symtab */
- unsigned long f_nsyms; /* number of symtab entries */
- short f_opthdr; /* sizeof(optional hdr) */
- short f_flags; /* flags */
-};
-
-/* Bits for f_flags:
- * F_RELFLG relocation info stripped from file
- * F_EXEC file is executable (no unresolved external references)
- * F_LNNO line numbers stripped from file
- * F_LSYMS local symbols stripped from file
- * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax)
- */
-
-#define F_RELFLG (0x0001)
-#define F_EXEC (0x0002)
-#define F_LNNO (0x0004)
-#define F_LSYMS (0x0008)
-
-
-
-#define I386MAGIC 0x14c
-#define I386PTXMAGIC 0x154
-#define I386AIXMAGIC 0x175
-
-/* This is Lynx's all-platform magic number for executables. */
-
-#define LYNXCOFFMAGIC 0415
-
-#define I386BADMAG(x) (((x).f_magic != I386MAGIC) \
- && (x).f_magic != I386AIXMAGIC \
- && (x).f_magic != I386PTXMAGIC \
- && (x).f_magic != LYNXCOFFMAGIC)
-
-#define FILHDR struct external_filehdr
-#define FILHSZ 20
-
-
-/********************** AOUT "OPTIONAL HEADER"=
- **********************/
-
-
-typedef struct
-{
- unsigned short magic; /* type of file */
- unsigned short vstamp; /* version stamp */
- unsigned long tsize; /* text size in bytes, padded to FW bdry*/
- unsigned long dsize; /* initialized data " " */
- unsigned long bsize; /* uninitialized data " " */
- unsigned long entry; /* entry pt. */
- unsigned long text_start; /* base of text used for this file */
- unsigned long data_start; /* base of data used for this file=
- */
-}
-AOUTHDR;
-
-#define AOUTSZ 28
-#define AOUTHDRSZ 28
-
-#define OMAGIC 0404 /* object files, eg as output */
-#define ZMAGIC 0413 /* demand load format, eg normal ld output */
-#define STMAGIC 0401 /* target shlib */
-#define SHMAGIC 0443 /* host shlib */
-
-
-/* define some NT default values */
-/* #define NT_IMAGE_BASE 0x400000 moved to internal.h */
-#define NT_SECTION_ALIGNMENT 0x1000
-#define NT_FILE_ALIGNMENT 0x200
-#define NT_DEF_RESERVE 0x100000
-#define NT_DEF_COMMIT 0x1000
-
-/********************** SECTION HEADER **********************/
-
-
-struct external_scnhdr {
- char s_name[8]; /* section name */
- unsigned long s_paddr; /* physical address, offset
- of last addr in scn */
- unsigned long s_vaddr; /* virtual address */
- unsigned long s_size; /* section size */
- unsigned long s_scnptr; /* file ptr to raw data for section */
- unsigned long s_relptr; /* file ptr to relocation */
- unsigned long s_lnnoptr; /* file ptr to line numbers */
- unsigned short s_nreloc; /* number of relocation entries */
- unsigned short s_nlnno; /* number of line number entries*/
- unsigned long s_flags; /* flags */
-};
-
-#define SCNHDR struct external_scnhdr
-#define SCNHSZ 40
-
-/*
- * names of "special" sections
- */
-#define _TEXT ".text"
-#define _DATA ".data"
-#define _BSS ".bss"
-#define _COMMENT ".comment"
-#define _LIB ".lib"
-
-/********************** LINE NUMBERS **********************/
-
-/* 1 line number entry for every "breakpointable" source line in a section.
- * Line numbers are grouped on a per function basis; first entry in a function
- * grouping will have l_lnno = 0 and in place of physical address will be the
- * symbol table index of the function name.
- */
-struct external_lineno {
- union {
- unsigned long l_symndx; /* function name symbol index, iff l_lnno 0 */
- unsigned long l_paddr; /* (physical) address of line number */
- } l_addr;
- unsigned short l_lnno; /* line number */
-};
-
-#define LINENO struct external_lineno
-#define LINESZ 6
-
-/********************** SYMBOLS **********************/
-
-#define E_SYMNMLEN 8 /* # characters in a symbol name */
-#define E_FILNMLEN 14 /* # characters in a file name */
-#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
-
-struct __attribute__((packed)) external_syment
-{
- union {
- char e_name[E_SYMNMLEN];
- struct {
- unsigned long e_zeroes;
- unsigned long e_offset;
- } e;
- } e;
- unsigned long e_value;
- unsigned short e_scnum;
- unsigned short e_type;
- char e_sclass[1];
- char e_numaux[1];
-};
-
-#define N_BTMASK (0xf)
-#define N_TMASK (0x30)
-#define N_BTSHFT (4)
-#define N_TSHIFT (2)
-
-union external_auxent {
- struct {
- unsigned long x_tagndx; /* str, un, or enum tag indx */
- union {
- struct {
- unsigned short x_lnno; /* declaration line number */
- unsigned short x_size; /* str/union/array size */
- } x_lnsz;
- unsigned long x_fsize; /* size of function */
- } x_misc;
- union {
- struct { /* if ISFCN, tag, or .bb */
- unsigned long x_lnnoptr;/* ptr to fcn line # */
- unsigned long x_endndx; /* entry ndx past block end */
- } x_fcn;
- struct { /* if ISARY, up to 4 dimen. */
- char x_dimen[E_DIMNUM][2];
- } x_ary;
- } x_fcnary;
- unsigned short x_tvndx; /* tv index */
- } x_sym;
-
- union {
- char x_fname[E_FILNMLEN];
- struct {
- unsigned long x_zeroes;
- unsigned long x_offset;
- } x_n;
- } x_file;
-
- struct {
- unsigned long x_scnlen; /* section length */
- unsigned short x_nreloc; /* # relocation entries */
- unsigned short x_nlinno; /* # line numbers */
- unsigned long x_checksum; /* section COMDAT checksum */
- unsigned short x_associated;/* COMDAT associated section index */
- char x_comdat[1]; /* COMDAT selection number */
- } x_scn;
-
- struct {
- unsigned long x_tvfill; /* tv fill value */
- unsigned short x_tvlen; /* length of .tv */
- char x_tvran[2][2]; /* tv range */
- } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
-
-};
-
-#define SYMENT struct external_syment
-#define SYMESZ 18
-#define AUXENT union external_auxent
-#define AUXESZ 18
-
-#define _ETEXT "etext"
-
-/********************** RELOCATION DIRECTIVES **********************/
-
-struct external_reloc {
- char r_vaddr[4];
- char r_symndx[4];
- char r_type[2];
-};
-
-#define RELOC struct external_reloc
-#define RELSZ 10
-
-/* end of coff/i386.h */
-
-/* PE COFF header information */
-
-#ifndef _PE_H
-#define _PE_H
-
-/* NT specific file attributes */
-#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
-#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
-#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
-#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
-#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
-#define IMAGE_FILE_32BIT_MACHINE 0x0100
-#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
-#define IMAGE_FILE_SYSTEM 0x1000
-#define IMAGE_FILE_DLL 0x2000
-#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
-
-/* additional flags to be set for section headers to allow the NT loader to
- read and write to the section data (to replace the addresses of data in
- dlls for one thing); also to execute the section in .text's case=
- */
-#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
-#define IMAGE_SCN_MEM_EXECUTE 0x20000000
-#define IMAGE_SCN_MEM_READ 0x40000000
-#define IMAGE_SCN_MEM_WRITE 0x80000000
-
-/*
- * Section characteristics added for ppc-nt
- */
-
-#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved. */
-
-#define IMAGE_SCN_CNT_CODE 0x00000020 /* Section contains code. */
-#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* Section contains initialized data. */
-#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* Section contains uninitialized data. */
-
-#define IMAGE_SCN_LNK_OTHER 0x00000100 /* Reserved. */
-#define IMAGE_SCN_LNK_INFO 0x00000200 /* Section contains comments or some other type of information. */
-#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* Section contents will not become part of image. */
-#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* Section contents comdat. */
-
-#define IMAGE_SCN_MEM_FARDATA 0x00008000
-
-#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
-#define IMAGE_SCN_MEM_16BIT 0x00020000
-#define IMAGE_SCN_MEM_LOCKED 0x00040000
-#define IMAGE_SCN_MEM_PRELOAD 0x00080000
-
-#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
-#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
-#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
-#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
-#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default alignment if no others are specified. */
-#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
-#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
-
-
-#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* Section contains extended relocations. */
-#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section is not cacheable. */
-#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* Section is not pageable. */
-#define IMAGE_SCN_MEM_SHARED 0x10000000 /* Section is shareable. */
-
-/* COMDAT selection codes. */
-
-#define IMAGE_COMDAT_SELECT_NODUPLICATES (1) /* Warn if duplicates. */
-#define IMAGE_COMDAT_SELECT_ANY (2) /* No warning. */
-#define IMAGE_COMDAT_SELECT_SAME_SIZE (3) /* Warn if different size. */
-#define IMAGE_COMDAT_SELECT_EXACT_MATCH (4) /* Warn if different. */
-#define IMAGE_COMDAT_SELECT_ASSOCIATIVE (5) /* Base on other section. */
-
-/* Magic values that are true for all dos/nt implementations */
-#define DOSMAGIC 0x5a4d
-#define NT_SIGNATURE 0x00004550
-
-/* NT allows long filenames, we want to accommodate this. This may break
- some of the bfd functions */
-#undef FILNMLEN
-#define FILNMLEN 18 /* # characters in a file name */
-
-
-#ifdef COFF_IMAGE_WITH_PE
-/* The filehdr is only weired in images */
-
-#undef FILHDR
-struct external_PE_filehdr
-{
- /* DOS header fields */
- unsigned short e_magic; /* Magic number, 0x5a4d */
- unsigned short e_cblp; /* Bytes on last page of file, 0x90 */
- unsigned short e_cp; /* Pages in file, 0x3 */
- unsigned short e_crlc; /* Relocations, 0x0 */
- unsigned short e_cparhdr; /* Size of header in paragraphs, 0x4 */
- unsigned short e_minalloc; /* Minimum extra paragraphs needed, 0x0 */
- unsigned short e_maxalloc; /* Maximum extra paragraphs needed, 0xFFFF */
- unsigned short e_ss; /* Initial (relative) SS value, 0x0 */
- unsigned short e_sp; /* Initial SP value, 0xb8 */
- unsigned short e_csum; /* Checksum, 0x0 */
- unsigned short e_ip; /* Initial IP value, 0x0 */
- unsigned short e_cs; /* Initial (relative) CS value, 0x0 */
- unsigned short e_lfarlc; /* File address of relocation table, 0x40 */
- unsigned short e_ovno; /* Overlay number, 0x0 */
- char e_res[4][2]; /* Reserved words, all 0x0 */
- unsigned short e_oemid; /* OEM identifier (for e_oeminfo), 0x0 */
- unsigned short e_oeminfo; /* OEM information; e_oemid specific, 0x0 */
- char e_res2[10][2]; /* Reserved words, all 0x0 */
- unsigned long e_lfanew; /* File address of new exe header, 0x80 */
- char dos_message[16][4]; /* other stuff, always follow DOS header */
- unsigned int nt_signature; /* required NT signature, 0x4550 */
-
- /* From standard header */
-
- unsigned short f_magic; /* magic number */
- unsigned short f_nscns; /* number of sections */
- unsigned long f_timdat; /* time & date stamp */
- unsigned long f_symptr; /* file pointer to symtab */
- unsigned long f_nsyms; /* number of symtab entries */
- unsigned short f_opthdr; /* sizeof(optional hdr) */
- unsigned short f_flags; /* flags */
-};
-
-
-#define FILHDR struct external_PE_filehdr
-#undef FILHSZ
-#define FILHSZ 152
-
-#endif
-
-typedef struct
-{
- unsigned short magic; /* type of file */
- unsigned short vstamp; /* version stamp */
- unsigned long tsize; /* text size in bytes, padded to FW bdry*/
- unsigned long dsize; /* initialized data " " */
- unsigned long bsize; /* uninitialized data " " */
- unsigned long entry; /* entry pt. */
- unsigned long text_start; /* base of text used for this file */
- unsigned long data_start; /* base of all data used for this file */
-
- /* NT extra fields; see internal.h for descriptions */
- unsigned long ImageBase;
- unsigned long SectionAlignment;
- unsigned long FileAlignment;
- unsigned short MajorOperatingSystemVersion;
- unsigned short MinorOperatingSystemVersion;
- unsigned short MajorImageVersion;
- unsigned short MinorImageVersion;
- unsigned short MajorSubsystemVersion;
- unsigned short MinorSubsystemVersion;
- char Reserved1[4];
- unsigned long SizeOfImage;
- unsigned long SizeOfHeaders;
- unsigned long CheckSum;
- unsigned short Subsystem;
- unsigned short DllCharacteristics;
- unsigned long SizeOfStackReserve;
- unsigned long SizeOfStackCommit;
- unsigned long SizeOfHeapReserve;
- unsigned long SizeOfHeapCommit;
- unsigned long LoaderFlags;
- unsigned long NumberOfRvaAndSizes;
- /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
- char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */
-
-} PEAOUTHDR;
-
-
-#undef AOUTSZ
-#define AOUTSZ (AOUTHDRSZ + 196)
-
-#undef E_FILNMLEN
-#define E_FILNMLEN 18 /* # characters in a file name */
-#endif
-
-/* end of coff/pe.h */
-
-#define DT_NON (0) /* no derived type */
-#define DT_PTR (1) /* pointer */
-#define DT_FCN (2) /* function */
-#define DT_ARY (3) /* array */
-
-#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
-#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
-#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _A_OUT_H_ */
-
diff --git a/src/recompiler/bswap.h b/src/recompiler/bswap.h
index 5529bb381..4377c7b0a 100644
--- a/src/recompiler/bswap.h
+++ b/src/recompiler/bswap.h
@@ -3,43 +3,16 @@
#include "config-host.h"
-#ifndef _MSC_VER
#include <inttypes.h>
-#endif
-#ifdef HAVE_BYTESWAP_H
-#include <byteswap.h>
+#ifdef CONFIG_MACHINE_BSWAP_H
+#include <sys/endian.h>
+#include <sys/types.h>
+#include <machine/bswap.h>
#else
-#ifdef _MSC_VER
-static _inline uint16_t bswap_16(register uint16_t x)
-{
- return ((uint16_t)( \
- (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \
- (((uint16_t)(x) & (uint16_t)0xff00U) >> 8) )); \
-}
-
-static _inline uint32_t bswap_32(register uint32_t x) \
-{ \
- return ((uint32_t)( \
- (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) )); \
-}
-
-static _inline uint64_t bswap_64(register uint64_t x) \
-{ \
- return ((uint64_t)( \
- (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
- (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
- (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
- (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
- (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
- (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
- (uint64_t)(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
- (uint64_t)(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
-}
+#ifdef CONFIG_BYTESWAP_H
+#include <byteswap.h>
#else
#define bswap_16(x) __extension__ /* <- VBOX */ \
@@ -73,71 +46,42 @@ static _inline uint64_t bswap_64(register uint64_t x) \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
})
-#endif
-#endif /* !HAVE_BYTESWAP_H */
+#endif /* !CONFIG_BYTESWAP_H */
-#ifndef bswap16 /* BSD endian.h clash */
-#ifndef VBOX
static inline uint16_t bswap16(uint16_t x)
-#else
-DECLINLINE(uint16_t) bswap16(uint16_t x)
-#endif
{
return bswap_16(x);
}
-#endif
-#ifndef bswap32 /* BSD endian.h clash */
-#ifndef VBOX
static inline uint32_t bswap32(uint32_t x)
-#else
-DECLINLINE(uint32_t) bswap32(uint32_t x)
-#endif
{
return bswap_32(x);
}
-#endif
-#ifndef bswap64 /* BSD endian.h clash. */
-#ifndef VBOX
static inline uint64_t bswap64(uint64_t x)
-#else
-DECLINLINE(uint64_t) bswap64(uint64_t x)
-#endif
{
return bswap_64(x);
}
-#endif
-#ifndef VBOX
+#endif /* ! CONFIG_MACHINE_BSWAP_H */
+
static inline void bswap16s(uint16_t *s)
-#else
-DECLINLINE(void) bswap16s(uint16_t *s)
-#endif
{
*s = bswap16(*s);
}
-#ifndef VBOX
static inline void bswap32s(uint32_t *s)
-#else
-DECLINLINE(void) bswap32s(uint32_t *s)
-#endif
{
*s = bswap32(*s);
}
-#ifndef VBOX
static inline void bswap64s(uint64_t *s)
-#else
-DECLINLINE(void) bswap64s(uint64_t *s)
-#endif
{
*s = bswap64(*s);
}
-#if defined(WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
#define be_bswap(v, size) (v)
#define le_bswap(v, size) bswap ## size(v)
#define be_bswaps(v, size)
@@ -149,7 +93,6 @@ DECLINLINE(void) bswap64s(uint64_t *s)
#define be_bswaps(p, size) *p = bswap ## size(*p);
#endif
-#ifndef VBOX
#define CPU_CONVERT(endian, size, type)\
static inline type endian ## size ## _to_cpu(type v)\
{\
@@ -180,38 +123,6 @@ static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
{\
*p = cpu_to_ ## endian ## size(v);\
}
-#else /* VBOX */
-#define CPU_CONVERT(endian, size, type)\
-DECLINLINE(type) endian ## size ## _to_cpu(type v)\
-{\
- return endian ## _bswap(v, size);\
-}\
-\
-DECLINLINE(type) cpu_to_ ## endian ## size(type v)\
-{\
- return endian ## _bswap(v, size);\
-}\
-\
-DECLINLINE(void) endian ## size ## _to_cpus(type *p)\
-{\
- endian ## _bswaps(p, size)\
-}\
-\
-DECLINLINE(void) cpu_to_ ## endian ## size ## s(type *p)\
-{\
- endian ## _bswaps(p, size)\
-}\
-\
-DECLINLINE(type) endian ## size ## _to_cpup(const type *p)\
-{\
- return endian ## size ## _to_cpu(*p);\
-}\
-\
-DECLINLINE(void) cpu_to_ ## endian ## size ## w(type *p, type v)\
-{\
- *p = cpu_to_ ## endian ## size(v);\
-}
-#endif /* VBOX */
CPU_CONVERT(be, 16, uint16_t)
CPU_CONVERT(be, 32, uint32_t)
@@ -223,12 +134,13 @@ CPU_CONVERT(le, 64, uint64_t)
/* unaligned versions (optimized for frequent unaligned accesses)*/
-#if defined(__i386__) || defined(__powerpc__)
+#if defined(__i386__) || defined(_ARCH_PPC)
#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
#define le16_to_cpupu(p) le16_to_cpup(p)
#define le32_to_cpupu(p) le32_to_cpup(p)
+#define be32_to_cpupu(p) be32_to_cpup(p)
#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v)
#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v)
@@ -239,7 +151,7 @@ static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
{
uint8_t *p1 = (uint8_t *)p;
- p1[0] = (uint8_t)v;
+ p1[0] = v & 0xff;
p1[1] = v >> 8;
}
@@ -247,7 +159,7 @@ static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
{
uint8_t *p1 = (uint8_t *)p;
- p1[0] = (uint8_t)v;
+ p1[0] = v & 0xff;
p1[1] = v >> 8;
p1[2] = v >> 16;
p1[3] = v >> 24;
@@ -265,12 +177,18 @@ static inline uint32_t le32_to_cpupu(const uint32_t *p)
return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
}
+static inline uint32_t be32_to_cpupu(const uint32_t *p)
+{
+ const uint8_t *p1 = (const uint8_t *)p;
+ return p1[3] | (p1[2] << 8) | (p1[1] << 16) | (p1[0] << 24);
+}
+
static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
{
uint8_t *p1 = (uint8_t *)p;
p1[0] = v >> 8;
- p1[1] = (uint8_t)v;
+ p1[1] = v & 0xff;
}
static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
@@ -280,15 +198,17 @@ static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
p1[0] = v >> 24;
p1[1] = v >> 16;
p1[2] = v >> 8;
- p1[3] = (uint8_t)v;
+ p1[3] = v & 0xff;
}
#endif
-#ifdef WORDS_BIGENDIAN
+#ifdef HOST_WORDS_BIGENDIAN
#define cpu_to_32wu cpu_to_be32wu
+#define leul_to_cpu(v) glue(glue(le,HOST_LONG_BITS),_to_cpu)(v)
#else
#define cpu_to_32wu cpu_to_le32wu
+#define leul_to_cpu(v) (v)
#endif
#undef le_bswap
@@ -296,4 +216,10 @@ static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
#undef le_bswaps
#undef be_bswaps
+/* len must be one of 1, 2, 4 */
+static inline uint32_t qemu_bswap_len(uint32_t value, int len)
+{
+ return bswap32(value) >> (32 - 8 * len);
+}
+
#endif /* BSWAP_H */
diff --git a/src/recompiler/cache-utils.h b/src/recompiler/cache-utils.h
new file mode 100644
index 000000000..b45fde44e
--- /dev/null
+++ b/src/recompiler/cache-utils.h
@@ -0,0 +1,41 @@
+#ifndef QEMU_CACHE_UTILS_H
+#define QEMU_CACHE_UTILS_H
+
+#if defined(_ARCH_PPC)
+struct qemu_cache_conf {
+ unsigned long dcache_bsize;
+ unsigned long icache_bsize;
+};
+
+extern struct qemu_cache_conf qemu_cache_conf;
+
+extern void qemu_cache_utils_init(char **envp);
+
+/* mildly adjusted code from tcg-dyngen.c */
+static inline void flush_icache_range(unsigned long start, unsigned long stop)
+{
+ unsigned long p, start1, stop1;
+ unsigned long dsize = qemu_cache_conf.dcache_bsize;
+ unsigned long isize = qemu_cache_conf.icache_bsize;
+
+ start1 = start & ~(dsize - 1);
+ stop1 = (stop + dsize - 1) & ~(dsize - 1);
+ for (p = start1; p < stop1; p += dsize) {
+ asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
+ }
+ asm volatile ("sync" : : : "memory");
+
+ start &= start & ~(isize - 1);
+ stop1 = (stop + isize - 1) & ~(isize - 1);
+ for (p = start1; p < stop1; p += isize) {
+ asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
+ }
+ asm volatile ("sync" : : : "memory");
+ asm volatile ("isync" : : : "memory");
+}
+
+#else
+#define qemu_cache_utils_init(envp) do { (void) (envp); } while (0)
+#endif
+
+#endif /* QEMU_CACHE_UTILS_H */
diff --git a/src/recompiler/cpu-all.h b/src/recompiler/cpu-all.h
index 42573fea2..4efa84434 100644
--- a/src/recompiler/cpu-all.h
+++ b/src/recompiler/cpu-all.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -36,18 +35,16 @@
# endif
# include <VBox/log.h>
# include <VBox/vmm/pgm.h> /* PGM_DYNAMIC_RAM_ALLOC */
-#endif
-
-#if defined(__arm__) || defined(__sparc__)
-#define WORDS_ALIGNED
-#endif
+#endif /* VBOX */
+#include "qemu-common.h"
+#include "cpu-common.h"
/* some important defines:
*
* WORDS_ALIGNED : if defined, the host cpu can only make word aligned
* memory accesses.
*
- * WORDS_BIGENDIAN : if defined, the host cpu is big endian and
+ * HOST_WORDS_BIGENDIAN : if defined, the host cpu is big endian and
* otherwise little endian.
*
* (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
@@ -55,9 +52,9 @@
* TARGET_WORDS_BIGENDIAN : same for target cpu
*/
-#include "bswap.h"
+#include "softfloat.h"
-#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
#define BSWAP_NEEDED
#endif
@@ -95,54 +92,30 @@ static inline void tswap64s(uint64_t *s)
#else
-#ifndef VBOX
static inline uint16_t tswap16(uint16_t s)
-#else
-DECLINLINE(uint16_t) tswap16(uint16_t s)
-#endif
{
return s;
}
-#ifndef VBOX
static inline uint32_t tswap32(uint32_t s)
-#else
-DECLINLINE(uint32_t) tswap32(uint32_t s)
-#endif
{
return s;
}
-#ifndef VBOX
static inline uint64_t tswap64(uint64_t s)
-#else
-DECLINLINE(uint64_t) tswap64(uint64_t s)
-#endif
{
return s;
}
-#ifndef VBOX
static inline void tswap16s(uint16_t *s)
-#else
-DECLINLINE(void) tswap16s(uint16_t *s)
-#endif
{
}
-#ifndef VBOX
static inline void tswap32s(uint32_t *s)
-#else
-DECLINLINE(void) tswap32s(uint32_t *s)
-#endif
{
}
-#ifndef VBOX
static inline void tswap64s(uint64_t *s)
-#else
-DECLINLINE(void) tswap64s(uint64_t *s)
-#endif
{
}
@@ -167,7 +140,7 @@ typedef union {
endian ! */
typedef union {
float64 d;
-#if defined(WORDS_BIGENDIAN) \
+#if defined(HOST_WORDS_BIGENDIAN) \
|| (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
struct {
uint32_t upper;
@@ -185,7 +158,7 @@ typedef union {
#ifdef TARGET_SPARC
typedef union {
float128 q;
-#if defined(WORDS_BIGENDIAN) \
+#if defined(HOST_WORDS_BIGENDIAN) \
|| (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
struct {
uint32_t upmost;
@@ -266,21 +239,21 @@ void remR3PhysWriteU16(RTGCPHYS DstGCPhys, uint16_t val);
void remR3PhysWriteU32(RTGCPHYS DstGCPhys, uint32_t val);
void remR3PhysWriteU64(RTGCPHYS DstGCPhys, uint64_t val);
-#ifndef REM_PHYS_ADDR_IN_TLB
+# ifndef REM_PHYS_ADDR_IN_TLB
void *remR3TlbGCPhys2Ptr(CPUState *env1, target_ulong physAddr, int fWritable);
-#endif
+# endif
#endif /* VBOX */
#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
-DECLINLINE(uint8_t) ldub_p(void *ptr)
+DECLINLINE(uint8_t) ldub_p(const void *ptr)
{
VBOX_CHECK_ADDR(ptr);
return remR3PhysReadU8((uintptr_t)ptr);
}
-DECLINLINE(int8_t) ldsb_p(void *ptr)
+DECLINLINE(int8_t) ldsb_p(const void *ptr)
{
VBOX_CHECK_ADDR(ptr);
return remR3PhysReadS8((uintptr_t)ptr);
@@ -292,13 +265,13 @@ DECLINLINE(void) stb_p(void *ptr, int v)
remR3PhysWriteU8((uintptr_t)ptr, v);
}
-DECLINLINE(uint32_t) lduw_le_p(void *ptr)
+DECLINLINE(uint32_t) lduw_le_p(const void *ptr)
{
VBOX_CHECK_ADDR(ptr);
return remR3PhysReadU16((uintptr_t)ptr);
}
-DECLINLINE(int32_t) ldsw_le_p(void *ptr)
+DECLINLINE(int32_t) ldsw_le_p(const void *ptr)
{
VBOX_CHECK_ADDR(ptr);
return remR3PhysReadS16((uintptr_t)ptr);
@@ -310,7 +283,7 @@ DECLINLINE(void) stw_le_p(void *ptr, int v)
remR3PhysWriteU16((uintptr_t)ptr, v);
}
-DECLINLINE(uint32_t) ldl_le_p(void *ptr)
+DECLINLINE(uint32_t) ldl_le_p(const void *ptr)
{
VBOX_CHECK_ADDR(ptr);
return remR3PhysReadU32((uintptr_t)ptr);
@@ -328,17 +301,17 @@ DECLINLINE(void) stq_le_p(void *ptr, uint64_t v)
remR3PhysWriteU64((uintptr_t)ptr, v);
}
-DECLINLINE(uint64_t) ldq_le_p(void *ptr)
+DECLINLINE(uint64_t) ldq_le_p(const void *ptr)
{
VBOX_CHECK_ADDR(ptr);
return remR3PhysReadU64((uintptr_t)ptr);
}
-#undef VBOX_CHECK_ADDR
+# undef VBOX_CHECK_ADDR
/* float access */
-DECLINLINE(float32) ldfl_le_p(void *ptr)
+DECLINLINE(float32) ldfl_le_p(const void *ptr)
{
union {
float32 f;
@@ -358,7 +331,7 @@ DECLINLINE(void) stfl_le_p(void *ptr, float32 v)
stl_le_p(ptr, u.i);
}
-DECLINLINE(float64) ldfq_le_p(void *ptr)
+DECLINLINE(float64) ldfq_le_p(const void *ptr)
{
CPU_DoubleU u;
u.l.lower = ldl_le_p(ptr);
@@ -374,14 +347,14 @@ DECLINLINE(void) stfq_le_p(void *ptr, float64 v)
stl_le_p((uint8_t*)ptr + 4, u.l.upper);
}
-#else /* !(VBOX && REM_PHYS_ADDR_IN_TLB) */
+#else /* !VBOX || !REM_PHYS_ADDR_IN_TLB */
-static inline int ldub_p(void *ptr)
+static inline int ldub_p(const void *ptr)
{
return *(uint8_t *)ptr;
}
-static inline int ldsb_p(void *ptr)
+static inline int ldsb_p(const void *ptr)
{
return *(int8_t *)ptr;
}
@@ -394,48 +367,48 @@ static inline void stb_p(void *ptr, int v)
/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
kernel handles unaligned load/stores may give better results, but
it is a system wide setting : bad */
-#if defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
+#if defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
/* conservative code for little endian unaligned accesses */
-static inline int lduw_le_p(void *ptr)
+static inline int lduw_le_p(const void *ptr)
{
-#ifdef __powerpc__
+#ifdef _ARCH_PPC
int val;
__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
return val;
#else
- uint8_t *p = ptr;
+ const uint8_t *p = ptr;
return p[0] | (p[1] << 8);
#endif
}
-static inline int ldsw_le_p(void *ptr)
+static inline int ldsw_le_p(const void *ptr)
{
-#ifdef __powerpc__
+#ifdef _ARCH_PPC
int val;
__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
return (int16_t)val;
#else
- uint8_t *p = ptr;
+ const uint8_t *p = ptr;
return (int16_t)(p[0] | (p[1] << 8));
#endif
}
-static inline int ldl_le_p(void *ptr)
+static inline int ldl_le_p(const void *ptr)
{
-#ifdef __powerpc__
+#ifdef _ARCH_PPC
int val;
__asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
return val;
#else
- uint8_t *p = ptr;
+ const uint8_t *p = ptr;
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
#endif
}
-static inline uint64_t ldq_le_p(void *ptr)
+static inline uint64_t ldq_le_p(const void *ptr)
{
- uint8_t *p = ptr;
+ const uint8_t *p = ptr;
uint32_t v1, v2;
v1 = ldl_le_p(p);
v2 = ldl_le_p(p + 4);
@@ -444,7 +417,7 @@ static inline uint64_t ldq_le_p(void *ptr)
static inline void stw_le_p(void *ptr, int v)
{
-#ifdef __powerpc__
+#ifdef _ARCH_PPC
__asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
#else
uint8_t *p = ptr;
@@ -455,7 +428,7 @@ static inline void stw_le_p(void *ptr, int v)
static inline void stl_le_p(void *ptr, int v)
{
-#ifdef __powerpc__
+#ifdef _ARCH_PPC
__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
#else
uint8_t *p = ptr;
@@ -475,7 +448,7 @@ static inline void stq_le_p(void *ptr, uint64_t v)
/* float access */
-static inline float32 ldfl_le_p(void *ptr)
+static inline float32 ldfl_le_p(const void *ptr)
{
union {
float32 f;
@@ -495,7 +468,7 @@ static inline void stfl_le_p(void *ptr, float32 v)
stl_le_p(ptr, u.i);
}
-static inline float64 ldfq_le_p(void *ptr)
+static inline float64 ldfq_le_p(const void *ptr)
{
CPU_DoubleU u;
u.l.lower = ldl_le_p(ptr);
@@ -513,22 +486,22 @@ static inline void stfq_le_p(void *ptr, float64 v)
#else
-static inline int lduw_le_p(void *ptr)
+static inline int lduw_le_p(const void *ptr)
{
return *(uint16_t *)ptr;
}
-static inline int ldsw_le_p(void *ptr)
+static inline int ldsw_le_p(const void *ptr)
{
return *(int16_t *)ptr;
}
-static inline int ldl_le_p(void *ptr)
+static inline int ldl_le_p(const void *ptr)
{
return *(uint32_t *)ptr;
}
-static inline uint64_t ldq_le_p(void *ptr)
+static inline uint64_t ldq_le_p(const void *ptr)
{
return *(uint64_t *)ptr;
}
@@ -550,12 +523,12 @@ static inline void stq_le_p(void *ptr, uint64_t v)
/* float access */
-static inline float32 ldfl_le_p(void *ptr)
+static inline float32 ldfl_le_p(const void *ptr)
{
return *(float32 *)ptr;
}
-static inline float64 ldfq_le_p(void *ptr)
+static inline float64 ldfq_le_p(const void *ptr)
{
return *(float64 *)ptr;
}
@@ -570,12 +543,12 @@ static inline void stfq_le_p(void *ptr, float64 v)
*(float64 *)ptr = v;
}
#endif
-#endif /* !VBOX */
-#if !defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
+#endif /* !VBOX || !REM_PHYS_ADDR_IN_TLB */
-#ifndef VBOX
-static inline int lduw_be_p(void *ptr)
+#if !defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
+
+static inline int lduw_be_p(const void *ptr)
{
#if defined(__i386__)
int val;
@@ -585,29 +558,12 @@ static inline int lduw_be_p(void *ptr)
: "m" (*(uint16_t *)ptr));
return val;
#else
- uint8_t *b = (uint8_t *) ptr;
+ const uint8_t *b = ptr;
return ((b[0] << 8) | b[1]);
#endif
}
-#else /* VBOX */
-DECLINLINE(int) lduw_be_p(void *ptr)
-{
-#if defined(__i386__) && !defined(_MSC_VER)
- int val;
- asm volatile ("movzwl %1, %0\n"
- "xchgb %b0, %h0\n"
- : "=q" (val)
- : "m" (*(uint16_t *)ptr));
- return val;
-#else
- uint8_t *b = (uint8_t *) ptr;
- return ((b[0] << 8) | b[1]);
-#endif
-}
-#endif
-#ifndef VBOX
-static inline int ldsw_be_p(void *ptr)
+static inline int ldsw_be_p(const void *ptr)
{
#if defined(__i386__)
int val;
@@ -617,29 +573,12 @@ static inline int ldsw_be_p(void *ptr)
: "m" (*(uint16_t *)ptr));
return (int16_t)val;
#else
- uint8_t *b = (uint8_t *) ptr;
+ const uint8_t *b = ptr;
return (int16_t)((b[0] << 8) | b[1]);
#endif
}
-#else
-DECLINLINE(int) ldsw_be_p(void *ptr)
-{
-#if defined(__i386__) && !defined(_MSC_VER)
- int val;
- asm volatile ("movzwl %1, %0\n"
- "xchgb %b0, %h0\n"
- : "=q" (val)
- : "m" (*(uint16_t *)ptr));
- return (int16_t)val;
-#else
- uint8_t *b = (uint8_t *) ptr;
- return (int16_t)((b[0] << 8) | b[1]);
-#endif
-}
-#endif
-#ifndef VBOX
-static inline int ldl_be_p(void *ptr)
+static inline int ldl_be_p(const void *ptr)
{
#if defined(__i386__) || defined(__x86_64__)
int val;
@@ -649,40 +588,19 @@ static inline int ldl_be_p(void *ptr)
: "m" (*(uint32_t *)ptr));
return val;
#else
- uint8_t *b = (uint8_t *) ptr;
+ const uint8_t *b = ptr;
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
#endif
}
-#else
-DECLINLINE(int) ldl_be_p(void *ptr)
-{
-#if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
- int val;
- asm volatile ("movl %1, %0\n"
- "bswap %0\n"
- : "=r" (val)
- : "m" (*(uint32_t *)ptr));
- return val;
-#else
- uint8_t *b = (uint8_t *) ptr;
- return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
-#endif
-}
-#endif
-#ifndef VBOX
-static inline uint64_t ldq_be_p(void *ptr)
-#else
-DECLINLINE(uint64_t) ldq_be_p(void *ptr)
-#endif
+static inline uint64_t ldq_be_p(const void *ptr)
{
uint32_t a,b;
a = ldl_be_p(ptr);
- b = ldl_be_p((uint8_t*)ptr+4);
+ b = ldl_be_p((uint8_t *)ptr + 4);
return (((uint64_t)a<<32)|b);
}
-#ifndef VBOX
static inline void stw_be_p(void *ptr, int v)
{
#if defined(__i386__)
@@ -696,24 +614,7 @@ static inline void stw_be_p(void *ptr, int v)
d[1] = v;
#endif
}
-#else
-DECLINLINE(void) stw_be_p(void *ptr, int v)
-{
-#if defined(__i386__) && !defined(_MSC_VER)
- asm volatile ("xchgb %b0, %h0\n"
- "movw %w0, %1\n"
- : "=q" (v)
- : "m" (*(uint16_t *)ptr), "0" (v));
-#else
- uint8_t *d = (uint8_t *) ptr;
- d[0] = v >> 8;
- d[1] = v;
-#endif
-}
-
-#endif /* VBOX */
-#ifndef VBOX
static inline void stl_be_p(void *ptr, int v)
{
#if defined(__i386__) || defined(__x86_64__)
@@ -729,40 +630,16 @@ static inline void stl_be_p(void *ptr, int v)
d[3] = v;
#endif
}
-#else
-DECLINLINE(void) stl_be_p(void *ptr, int v)
-{
-#if !defined(_MSC_VER) && (defined(__i386__) || defined(__x86_64__))
- asm volatile ("bswap %0\n"
- "movl %0, %1\n"
- : "=r" (v)
- : "m" (*(uint32_t *)ptr), "0" (v));
-#else
- uint8_t *d = (uint8_t *) ptr;
- d[0] = v >> 24;
- d[1] = v >> 16;
- d[2] = v >> 8;
- d[3] = v;
-#endif
-}
-#endif /* VBOX */
-#ifndef VBOX
static inline void stq_be_p(void *ptr, uint64_t v)
-#else
-DECLINLINE(void) stq_be_p(void *ptr, uint64_t v)
-#endif
{
stl_be_p(ptr, v >> 32);
- stl_be_p((uint8_t*)ptr + 4, v);
+ stl_be_p((uint8_t *)ptr + 4, v);
}
/* float access */
-#ifndef VBOX
-static inline float32 ldfl_be_p(void *ptr)
-#else
-DECLINLINE(float32) ldfl_be_p(void *ptr)
-#endif
+
+static inline float32 ldfl_be_p(const void *ptr)
{
union {
float32 f;
@@ -772,11 +649,7 @@ DECLINLINE(float32) ldfl_be_p(void *ptr)
return u.f;
}
-#ifndef VBOX
static inline void stfl_be_p(void *ptr, float32 v)
-#else
-DECLINLINE(void) stfl_be_p(void *ptr, float32 v)
-#endif
{
union {
float32 f;
@@ -786,48 +659,40 @@ DECLINLINE(void) stfl_be_p(void *ptr, float32 v)
stl_be_p(ptr, u.i);
}
-#ifndef VBOX
-static inline float64 ldfq_be_p(void *ptr)
-#else
-DECLINLINE(float64) ldfq_be_p(void *ptr)
-#endif
+static inline float64 ldfq_be_p(const void *ptr)
{
CPU_DoubleU u;
u.l.upper = ldl_be_p(ptr);
- u.l.lower = ldl_be_p((uint8_t*)ptr + 4);
+ u.l.lower = ldl_be_p((uint8_t *)ptr + 4);
return u.d;
}
-#ifndef VBOX
static inline void stfq_be_p(void *ptr, float64 v)
-#else
-DECLINLINE(void) stfq_be_p(void *ptr, float64 v)
-#endif
{
CPU_DoubleU u;
u.d = v;
stl_be_p(ptr, u.l.upper);
- stl_be_p((uint8_t*)ptr + 4, u.l.lower);
+ stl_be_p((uint8_t *)ptr + 4, u.l.lower);
}
#else
-static inline int lduw_be_p(void *ptr)
+static inline int lduw_be_p(const void *ptr)
{
return *(uint16_t *)ptr;
}
-static inline int ldsw_be_p(void *ptr)
+static inline int ldsw_be_p(const void *ptr)
{
return *(int16_t *)ptr;
}
-static inline int ldl_be_p(void *ptr)
+static inline int ldl_be_p(const void *ptr)
{
return *(uint32_t *)ptr;
}
-static inline uint64_t ldq_be_p(void *ptr)
+static inline uint64_t ldq_be_p(const void *ptr)
{
return *(uint64_t *)ptr;
}
@@ -849,12 +714,12 @@ static inline void stq_be_p(void *ptr, uint64_t v)
/* float access */
-static inline float32 ldfl_be_p(void *ptr)
+static inline float32 ldfl_be_p(const void *ptr)
{
return *(float32 *)ptr;
}
-static inline float64 ldfq_be_p(void *ptr)
+static inline float64 ldfq_be_p(const void *ptr)
{
return *(float64 *)ptr;
}
@@ -901,15 +766,42 @@ static inline void stfq_be_p(void *ptr, float64 v)
/* MMU memory access macros */
#if defined(CONFIG_USER_ONLY)
+#include <assert.h>
+#include "qemu-types.h"
+
/* On some host systems the guest address space is reserved on the host.
* This allows the guest address space to be offset to a convenient location.
*/
-//#define GUEST_BASE 0x20000000
-#define GUEST_BASE 0
+#if defined(CONFIG_USE_GUEST_BASE)
+extern unsigned long guest_base;
+extern int have_guest_base;
+extern unsigned long reserved_va;
+#define GUEST_BASE guest_base
+#define RESERVED_VA reserved_va
+#else
+#define GUEST_BASE 0ul
+#define RESERVED_VA 0ul
+#endif
/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
-#define h2g(x) ((target_ulong)(x - GUEST_BASE))
+
+#if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
+#define h2g_valid(x) 1
+#else
+#define h2g_valid(x) ({ \
+ unsigned long __guest = (unsigned long)(x) - GUEST_BASE; \
+ __guest < (1ul << TARGET_VIRT_ADDR_SPACE_BITS); \
+})
+#endif
+
+#define h2g(x) ({ \
+ unsigned long __ret = (unsigned long)(x) - GUEST_BASE; \
+ /* Check if given address fits target address space */ \
+ assert(h2g_valid(x)); \
+ (abi_ulong)__ret; \
+})
+
#define saddr(x) g2h(x)
#define laddr(x) g2h(x)
@@ -959,12 +851,14 @@ static inline void stfq_be_p(void *ptr, float64 v)
#define lduw_code(p) lduw_raw(p)
#define ldsw_code(p) ldsw_raw(p)
#define ldl_code(p) ldl_raw(p)
+#define ldq_code(p) ldq_raw(p)
#define ldub_kernel(p) ldub_raw(p)
#define ldsb_kernel(p) ldsb_raw(p)
#define lduw_kernel(p) lduw_raw(p)
#define ldsw_kernel(p) ldsw_raw(p)
#define ldl_kernel(p) ldl_raw(p)
+#define ldq_kernel(p) ldq_raw(p)
#define ldfl_kernel(p) ldfl_raw(p)
#define ldfq_kernel(p) ldfq_raw(p)
#define stb_kernel(p, v) stb_raw(p, v)
@@ -999,124 +893,100 @@ extern unsigned long qemu_host_page_mask;
/* original state of the write flag (used when tracking self-modifying
code */
#define PAGE_WRITE_ORG 0x0010
+#if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
+/* FIXME: Code that sets/uses this is broken and needs to go away. */
#define PAGE_RESERVED 0x0020
+#endif
+#if defined(CONFIG_USER_ONLY)
void page_dump(FILE *f);
+
+typedef int (*walk_memory_regions_fn)(void *, abi_ulong,
+ abi_ulong, unsigned long);
+int walk_memory_regions(void *, walk_memory_regions_fn);
+
int page_get_flags(target_ulong address);
void page_set_flags(target_ulong start, target_ulong end, int flags);
int page_check_range(target_ulong start, target_ulong len, int flags);
-void page_unprotect_range(target_ulong data, target_ulong data_size);
-
-#define SINGLE_CPU_DEFINES
-#ifdef SINGLE_CPU_DEFINES
-
-#if defined(TARGET_I386)
-
-#define CPUState CPUX86State
-#define cpu_init cpu_x86_init
-#define cpu_exec cpu_x86_exec
-#define cpu_gen_code cpu_x86_gen_code
-#define cpu_signal_handler cpu_x86_signal_handler
-
-#elif defined(TARGET_ARM)
-
-#define CPUState CPUARMState
-#define cpu_init cpu_arm_init
-#define cpu_exec cpu_arm_exec
-#define cpu_gen_code cpu_arm_gen_code
-#define cpu_signal_handler cpu_arm_signal_handler
-
-#elif defined(TARGET_SPARC)
-
-#define CPUState CPUSPARCState
-#define cpu_init cpu_sparc_init
-#define cpu_exec cpu_sparc_exec
-#define cpu_gen_code cpu_sparc_gen_code
-#define cpu_signal_handler cpu_sparc_signal_handler
-
-#elif defined(TARGET_PPC)
-
-#define CPUState CPUPPCState
-#define cpu_init cpu_ppc_init
-#define cpu_exec cpu_ppc_exec
-#define cpu_gen_code cpu_ppc_gen_code
-#define cpu_signal_handler cpu_ppc_signal_handler
-
-#elif defined(TARGET_M68K)
-#define CPUState CPUM68KState
-#define cpu_init cpu_m68k_init
-#define cpu_exec cpu_m68k_exec
-#define cpu_gen_code cpu_m68k_gen_code
-#define cpu_signal_handler cpu_m68k_signal_handler
-
-#elif defined(TARGET_MIPS)
-#define CPUState CPUMIPSState
-#define cpu_init cpu_mips_init
-#define cpu_exec cpu_mips_exec
-#define cpu_gen_code cpu_mips_gen_code
-#define cpu_signal_handler cpu_mips_signal_handler
-
-#elif defined(TARGET_SH4)
-#define CPUState CPUSH4State
-#define cpu_init cpu_sh4_init
-#define cpu_exec cpu_sh4_exec
-#define cpu_gen_code cpu_sh4_gen_code
-#define cpu_signal_handler cpu_sh4_signal_handler
-
-#else
-
-#error unsupported target CPU
-
#endif
-#endif /* SINGLE_CPU_DEFINES */
+CPUState *cpu_copy(CPUState *env);
+CPUState *qemu_get_cpu(int cpu);
void cpu_dump_state(CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags);
+void cpu_dump_statistics (CPUState *env, FILE *f,
+ int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+ int flags);
-DECLNORETURN(void) cpu_abort(CPUState *env, const char *fmt, ...);
+void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
+#ifndef VBOX
+ __attribute__ ((__format__ (__printf__, 2, 3)));
+#else /* VBOX */
+ ;
+#endif /* VBOX */
extern CPUState *first_cpu;
extern CPUState *cpu_single_env;
-extern int64_t qemu_icount;
-extern int use_icount;
-#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
#define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
#define CPU_INTERRUPT_TIMER 0x08 /* internal timer exception pending */
#define CPU_INTERRUPT_FIQ 0x10 /* Fast interrupt pending. */
#define CPU_INTERRUPT_HALT 0x20 /* CPU halt wanted */
#define CPU_INTERRUPT_SMI 0x40 /* (x86 only) SMI interrupt pending */
-#define CPU_INTERRUPT_DEBUG 0x80 /* Debug event occurred. */
+#define CPU_INTERRUPT_DEBUG 0x80 /* Debug event occured. */
#define CPU_INTERRUPT_VIRQ 0x100 /* virtual interrupt pending. */
#define CPU_INTERRUPT_NMI 0x200 /* NMI pending. */
+#define CPU_INTERRUPT_INIT 0x400 /* INIT pending. */
+#define CPU_INTERRUPT_SIPI 0x800 /* SIPI pending. */
+#define CPU_INTERRUPT_MCE 0x1000 /* (x86 only) MCE pending. */
#ifdef VBOX
/** Executes a single instruction. cpu_exec() will normally return EXCP_SINGLE_INSTR. */
-#define CPU_INTERRUPT_SINGLE_INSTR 0x0400
+# define CPU_INTERRUPT_SINGLE_INSTR 0x01000000
/** Executing a CPU_INTERRUPT_SINGLE_INSTR request, quit the cpu_loop. (for exceptions and suchlike) */
-#define CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT 0x0800
+# define CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT 0x02000000
/** VM execution was interrupted by VMR3Reset, VMR3Suspend or VMR3PowerOff. */
-#define CPU_INTERRUPT_RC 0x1000
-/** Exit current TB to process an external interrupt request (also in op.c!!) */
-#define CPU_INTERRUPT_EXTERNAL_EXIT 0x2000
-/** Exit current TB to process an external interrupt request (also in op.c!!) */
-#define CPU_INTERRUPT_EXTERNAL_HARD 0x4000
-/** Exit current TB to process an external interrupt request (also in op.c!!) */
-#define CPU_INTERRUPT_EXTERNAL_TIMER 0x8000
-/** Exit current TB to process an external interrupt request (also in op.c!!) */
-#define CPU_INTERRUPT_EXTERNAL_DMA 0x10000
+# define CPU_INTERRUPT_RC 0x04000000
+/** Exit current TB to process an external request. */
+# define CPU_INTERRUPT_EXTERNAL_FLUSH_TLB 0x08000000
+/** Exit current TB to process an external request. */
+# define CPU_INTERRUPT_EXTERNAL_EXIT 0x10000000
+/** Exit current TB to process an external interrupt request. */
+# define CPU_INTERRUPT_EXTERNAL_HARD 0x20000000
+/** Exit current TB to process an external timer request. */
+# define CPU_INTERRUPT_EXTERNAL_TIMER 0x40000000
+/** Exit current TB to process an external DMA request. */
+# define CPU_INTERRUPT_EXTERNAL_DMA 0x80000000
#endif /* VBOX */
void cpu_interrupt(CPUState *s, int mask);
void cpu_reset_interrupt(CPUState *env, int mask);
-int cpu_watchpoint_insert(CPUState *env, target_ulong addr, int type);
-int cpu_watchpoint_remove(CPUState *env, target_ulong addr);
-void cpu_watchpoint_remove_all(CPUState *env);
-int cpu_breakpoint_insert(CPUState *env, target_ulong pc);
-int cpu_breakpoint_remove(CPUState *env, target_ulong pc);
-void cpu_breakpoint_remove_all(CPUState *env);
+void cpu_exit(CPUState *s);
+
+int qemu_cpu_has_work(CPUState *env);
+
+/* Breakpoint/watchpoint flags */
+#define BP_MEM_READ 0x01
+#define BP_MEM_WRITE 0x02
+#define BP_MEM_ACCESS (BP_MEM_READ | BP_MEM_WRITE)
+#define BP_STOP_BEFORE_ACCESS 0x04
+#define BP_WATCHPOINT_HIT 0x08
+#define BP_GDB 0x10
+#define BP_CPU 0x20
+
+int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,
+ CPUBreakpoint **breakpoint);
+int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags);
+void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint);
+void cpu_breakpoint_remove_all(CPUState *env, int mask);
+int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
+ int flags, CPUWatchpoint **watchpoint);
+int cpu_watchpoint_remove(CPUState *env, target_ulong addr,
+ target_ulong len, int flags);
+void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint);
+void cpu_watchpoint_remove_all(CPUState *env, int mask);
#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
@@ -1124,11 +994,8 @@ void cpu_breakpoint_remove_all(CPUState *env);
void cpu_single_step(CPUState *env, int enabled);
void cpu_reset(CPUState *s);
-
-/* Return the physical page corresponding to a virtual one. Use it
- only for debugging because no protection checks are done. Return -1
- if no page found. */
-target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
+int cpu_is_stopped(CPUState *env);
+void run_on_cpu(CPUState *env, void (*func)(void *data), void *data);
#define CPU_LOG_TB_OUT_ASM (1 << 0)
#define CPU_LOG_TB_IN_ASM (1 << 1)
@@ -1139,6 +1006,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
#define CPU_LOG_PCALL (1 << 6)
#define CPU_LOG_IOPORT (1 << 7)
#define CPU_LOG_TB_CPU (1 << 8)
+#define CPU_LOG_RESET (1 << 9)
/* define log items */
typedef struct CPULogItem {
@@ -1147,67 +1015,84 @@ typedef struct CPULogItem {
const char *help;
} CPULogItem;
-extern CPULogItem cpu_log_items[];
+extern const CPULogItem cpu_log_items[];
void cpu_set_log(int log_flags);
void cpu_set_log_filename(const char *filename);
int cpu_str_to_log_mask(const char *str);
-/* IO ports API */
-
-/* NOTE: as these functions may be even used when there is an isa
- brige on non x86 targets, we always defined them */
-#ifndef NO_CPU_IO_DEFS
-void cpu_outb(CPUState *env, int addr, int val);
-void cpu_outw(CPUState *env, int addr, int val);
-void cpu_outl(CPUState *env, int addr, int val);
-int cpu_inb(CPUState *env, int addr);
-int cpu_inw(CPUState *env, int addr);
-int cpu_inl(CPUState *env, int addr);
-#endif
+#if !defined(CONFIG_USER_ONLY)
-/* address in the RAM (different from a physical address) */
-#ifdef USE_KQEMU
-typedef uint32_t ram_addr_t;
-#else
-typedef unsigned long ram_addr_t;
-#endif
+/* Return the physical page corresponding to a virtual one. Use it
+ only for debugging because no protection checks are done. Return -1
+ if no page found. */
+target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
/* memory API */
#ifndef VBOX
-extern int phys_ram_size;
extern int phys_ram_fd;
-extern int phys_ram_size;
-#else /* VBOX */
-extern RTGCPHYS phys_ram_size;
-/** This is required for bounds checking the phys_ram_dirty accesses. */
-extern RTGCPHYS phys_ram_dirty_size;
-#endif /* VBOX */
-#if !defined(VBOX)
-extern uint8_t *phys_ram_base;
+extern ram_addr_t ram_size;
+#endif /* !VBOX */
+
+typedef struct RAMBlock {
+ uint8_t *host;
+ ram_addr_t offset;
+ ram_addr_t length;
+ char idstr[256];
+ QLIST_ENTRY(RAMBlock) next;
+#if defined(__linux__) && !defined(TARGET_S390X)
+ int fd;
#endif
-extern uint8_t *phys_ram_dirty;
+} RAMBlock;
+
+typedef struct RAMList {
+ uint8_t *phys_dirty;
+#ifdef VBOX
+ /** This is required for bounds checking the phys_ram_dirty accesses.
+ * We have memory ranges (the high PC-BIOS mapping) which causes some pages
+ * to fall outside the dirty map. */
+ RTGCPHYS phys_dirty_size;
+#if 1
+# define VBOX_RAMLIST_DIRTY_BOUNDS_CHECK_RET(addr,rv) \
+ do { \
+ if (RT_UNLIKELY( ((addr) >> TARGET_PAGE_BITS) >= ram_list.phys_dirty_size)) { \
+ Log(("%s: %RGp\n", __FUNCTION__, (RTGCPHYS)addr)); \
+ return (rv); \
+ } \
+ } while (0)
+# define VBOX_RAMLIST_DIRTY_BOUNDS_CHECK_RETV(addr) \
+ do { \
+ if (RT_UNLIKELY( ((addr) >> TARGET_PAGE_BITS) >= ram_list.phys_dirty_size)) { \
+ Log(("%s: %RGp\n", __FUNCTION__, (RTGCPHYS)addr)); \
+ return; \
+ } \
+ } while (0)
+#else
+# define VBOX_RAMLIST_DIRTY_BOUNDS_CHECK_RET(addr,rv) \
+ AssertMsgReturn(((addr) >> TARGET_PAGE_BITS) < ram_list.phys_dirty_size, ("%#RGp\n", (RTGCPHYS)(addr)), (rv));
+# define VBOX_RAMLIST_DIRTY_BOUNDS_CHECK_RETV(addr) \
+ AssertMsgReturnVoid(((addr) >> TARGET_PAGE_BITS) < ram_list.phys_dirty_size, ("%#RGp\n", (RTGCPHYS)(addr)));
+# endif
+#else
+# define VBOX_RAMLIST_DIRTY_BOUNDS_CHECK_RET(addr,rv) do {} while()
+# define VBOX_RAMLIST_DIRTY_BOUNDS_CHECK_RETV(addr) do {} while()
+#endif /* VBOX */
+ QLIST_HEAD(ram, RAMBlock) blocks;
+} RAMList;
+extern RAMList ram_list;
+
+extern const char *mem_path;
+extern int mem_prealloc;
/* physical memory access */
/* MMIO pages are identified by a combination of an IO device index and
3 flags. The ROMD code stores the page ram offset in iotlb entry,
- so only a limited number of ids are available. */
+ so only a limited number of ids are avaiable. */
-#define IO_MEM_SHIFT 3
#define IO_MEM_NB_ENTRIES (1 << (TARGET_PAGE_BITS - IO_MEM_SHIFT))
-#define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */
-#define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */
-#define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT)
-#define IO_MEM_NOTDIRTY (3 << IO_MEM_SHIFT)
-
-/* Acts like a ROM when read and like a device when written. */
-#define IO_MEM_ROMD (1)
-#define IO_MEM_SUBPAGE (2)
-#define IO_MEM_SUBWIDTH (4)
-
/* Flags stored in the low bits of the TLB virtual address. These are
defined so that fast path ram access is all zeros. */
/* Zero if TLB entry is valid. */
@@ -1218,121 +1103,58 @@ extern uint8_t *phys_ram_dirty;
/* Set if TLB entry is an IO callback. */
#define TLB_MMIO (1 << 5)
-typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
-typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
-
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
- ram_addr_t size,
- ram_addr_t phys_offset);
-uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr);
-ram_addr_t qemu_ram_alloc(ram_addr_t);
-void qemu_ram_free(ram_addr_t addr);
-int cpu_register_io_memory(int io_index,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque);
-CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
-CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
-
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write);
-#ifndef VBOX
-static inline void cpu_physical_memory_read(target_phys_addr_t addr,
- uint8_t *buf, int len)
-#else
-DECLINLINE(void) cpu_physical_memory_read(target_phys_addr_t addr,
- uint8_t *buf, int len)
-#endif
-{
- cpu_physical_memory_rw(addr, buf, len, 0);
-}
-#ifndef VBOX
-static inline void cpu_physical_memory_write(target_phys_addr_t addr,
- const uint8_t *buf, int len)
-#else
-DECLINLINE(void) cpu_physical_memory_write(target_phys_addr_t addr,
- const uint8_t *buf, int len)
-#endif
-{
- cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
-}
-uint32_t ldub_phys(target_phys_addr_t addr);
-uint32_t lduw_phys(target_phys_addr_t addr);
-uint32_t ldl_phys(target_phys_addr_t addr);
-uint64_t ldq_phys(target_phys_addr_t addr);
-void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
-void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val);
-void stb_phys(target_phys_addr_t addr, uint32_t val);
-void stw_phys(target_phys_addr_t addr, uint32_t val);
-void stl_phys(target_phys_addr_t addr, uint32_t val);
-void stq_phys(target_phys_addr_t addr, uint64_t val);
-
-void cpu_physical_memory_write_rom(target_phys_addr_t addr,
- const uint8_t *buf, int len);
-int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
- uint8_t *buf, int len, int is_write);
-
-#define VGA_DIRTY_FLAG 0x01
-#define CODE_DIRTY_FLAG 0x02
-#define KQEMU_DIRTY_FLAG 0x04
+#define VGA_DIRTY_FLAG 0x01
+#define CODE_DIRTY_FLAG 0x02
#define MIGRATION_DIRTY_FLAG 0x08
/* read dirty bit (return 0 or 1) */
-#ifndef VBOX
static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
{
- return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
+ VBOX_RAMLIST_DIRTY_BOUNDS_CHECK_RET(addr, 0);
+ return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
}
-#else
-DECLINLINE(int) cpu_physical_memory_is_dirty(ram_addr_t addr)
+
+static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr)
{
- if (RT_UNLIKELY((addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
- {
- Log(("cpu_physical_memory_is_dirty: %RGp\n", (RTGCPHYS)addr));
- /*AssertMsgFailed(("cpu_physical_memory_is_dirty: %RGp\n", (RTGCPHYS)addr));*/
- return 0;
- }
- return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
+ VBOX_RAMLIST_DIRTY_BOUNDS_CHECK_RET(addr, 0xff);
+ return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS];
}
-#endif
-#ifndef VBOX
static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
int dirty_flags)
{
- return phys_ram_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
-}
-#else
-DECLINLINE(int) cpu_physical_memory_get_dirty(ram_addr_t addr,
- int dirty_flags)
-{
- if (RT_UNLIKELY((addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
- {
- Log(("cpu_physical_memory_is_dirty: %RGp\n", (RTGCPHYS)addr));
- /*AssertMsgFailed(("cpu_physical_memory_is_dirty: %RGp\n", (RTGCPHYS)addr));*/
- return 0xff & dirty_flags; /** @todo I don't think this is the right thing to return, fix! */
- }
- return phys_ram_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
+ VBOX_RAMLIST_DIRTY_BOUNDS_CHECK_RET(addr, 0xff & dirty_flags);
+ return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
}
-#endif
-#ifndef VBOX
static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
{
- phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
+ VBOX_RAMLIST_DIRTY_BOUNDS_CHECK_RETV(addr);
+ ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
}
-#else
-DECLINLINE(void) cpu_physical_memory_set_dirty(ram_addr_t addr)
+
+static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr,
+ int dirty_flags)
{
- if (RT_UNLIKELY((addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
- {
- Log(("cpu_physical_memory_is_dirty: %RGp\n", (RTGCPHYS)addr));
- /*AssertMsgFailed(("cpu_physical_memory_is_dirty: %RGp\n", (RTGCPHYS)addr));*/
- return;
+ VBOX_RAMLIST_DIRTY_BOUNDS_CHECK_RET(addr, 0xff);
+ return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] |= dirty_flags;
+}
+
+static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start,
+ int length,
+ int dirty_flags)
+{
+ int i, mask, len;
+ uint8_t *p;
+
+ VBOX_RAMLIST_DIRTY_BOUNDS_CHECK_RETV(start);
+ len = length >> TARGET_PAGE_BITS;
+ mask = ~dirty_flags;
+ p = ram_list.phys_dirty + (start >> TARGET_PAGE_BITS);
+ for (i = 0; i < len; i++) {
+ p[i] &= mask;
}
- phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
}
-#endif
void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
int dirty_flags);
@@ -1342,137 +1164,18 @@ int cpu_physical_memory_set_dirty_tracking(int enable);
int cpu_physical_memory_get_dirty_tracking(void);
+int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
+ target_phys_addr_t end_addr);
+
void dump_exec_info(FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+#endif /* !CONFIG_USER_ONLY */
-/*******************************************/
-/* host CPU ticks (if available) */
-
-#ifdef VBOX
-# include <iprt/asm-amd64-x86.h>
-
-DECLINLINE(int64_t) cpu_get_real_ticks(void)
-{
- return ASMReadTSC();
-}
-
-#elif defined(__powerpc__)
-
-static inline uint32_t get_tbl(void)
-{
- uint32_t tbl;
- asm volatile("mftb %0" : "=r" (tbl));
- return tbl;
-}
-
-static inline uint32_t get_tbu(void)
-{
- uint32_t tbl;
- asm volatile("mftbu %0" : "=r" (tbl));
- return tbl;
-}
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- uint32_t l, h, h1;
- /* NOTE: we test if wrapping has occurred */
- do {
- h = get_tbu();
- l = get_tbl();
- h1 = get_tbu();
- } while (h != h1);
- return ((int64_t)h << 32) | l;
-}
-
-#elif defined(__i386__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile ("rdtsc" : "=A" (val));
- return val;
-}
-
-#elif defined(__x86_64__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- uint32_t low,high;
- int64_t val;
- asm volatile("rdtsc" : "=a" (low), "=d" (high));
- val = high;
- val <<= 32;
- val |= low;
- return val;
-}
-
-#elif defined(__ia64)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
- return val;
-}
-
-#elif defined(__s390__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
- return val;
-}
-
-#elif defined(__sparc_v9__)
-
-static inline int64_t cpu_get_real_ticks (void)
-{
-#if defined(_LP64)
- uint64_t rval;
- asm volatile("rd %%tick,%0" : "=r"(rval));
- return rval;
-#else
- union {
- uint64_t i64;
- struct {
- uint32_t high;
- uint32_t low;
- } i32;
- } rval;
- asm volatile("rd %%tick,%1; srlx %1,32,%0"
- : "=r"(rval.i32.high), "=r"(rval.i32.low));
- return rval.i64;
-#endif
-}
-#else
-/* The host CPU doesn't have an easily accessible cycle counter.
- Just return a monotonically increasing vlue. This will be totally wrong,
- but hopefully better than nothing. */
-static inline int64_t cpu_get_real_ticks (void)
-{
- static int64_t ticks = 0;
- return ticks++;
-}
-#endif
-
-/* profiling */
-#ifdef CONFIG_PROFILER
-static inline int64_t profile_getclock(void)
-{
- return cpu_get_real_ticks();
-}
-
-extern int64_t kqemu_time, kqemu_time_start;
-extern int64_t qemu_time, qemu_time_start;
-extern int64_t tlb_flush_time;
-extern int64_t kqemu_exec_count;
-extern int64_t dev_time;
-extern int64_t kqemu_ret_int_count;
-extern int64_t kqemu_ret_excp_count;
-extern int64_t kqemu_ret_intr_count;
+int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
+ uint8_t *buf, int len, int is_write);
-#endif
+void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
+ uint64_t mcg_status, uint64_t addr, uint64_t misc);
#ifdef VBOX
void tb_invalidate_virt(CPUState *env, uint32_t eip);
diff --git a/src/recompiler/cpu-common.h b/src/recompiler/cpu-common.h
new file mode 100644
index 000000000..3365de80f
--- /dev/null
+++ b/src/recompiler/cpu-common.h
@@ -0,0 +1,135 @@
+#ifndef CPU_COMMON_H
+#define CPU_COMMON_H 1
+
+/* CPU interfaces that are target indpendent. */
+
+#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__)
+#define WORDS_ALIGNED
+#endif
+
+#ifdef TARGET_PHYS_ADDR_BITS
+#include "targphys.h"
+#endif
+
+#ifndef NEED_CPU_H
+#include "poison.h"
+#endif
+
+#include "bswap.h"
+#include "qemu-queue.h"
+
+#if !defined(CONFIG_USER_ONLY)
+
+/* address in the RAM (different from a physical address) */
+typedef unsigned long ram_addr_t;
+
+/* memory API */
+
+typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
+typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
+
+void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
+ ram_addr_t size,
+ ram_addr_t phys_offset,
+ ram_addr_t region_offset);
+static inline void cpu_register_physical_memory(target_phys_addr_t start_addr,
+ ram_addr_t size,
+ ram_addr_t phys_offset)
+{
+ cpu_register_physical_memory_offset(start_addr, size, phys_offset, 0);
+}
+
+ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr);
+#ifndef VBOX
+ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
+ ram_addr_t size, void *host);
+ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size);
+void qemu_ram_free(ram_addr_t addr);
+/* This should only be used for ram local to a device. */
+void *qemu_get_ram_ptr(ram_addr_t addr);
+/* This should not be used by devices. */
+ram_addr_t qemu_ram_addr_from_host(void *ptr);
+#endif /* !VBOX */
+
+int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,
+ CPUWriteMemoryFunc * const *mem_write,
+ void *opaque);
+void cpu_unregister_io_memory(int table_address);
+
+void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
+ int len, int is_write);
+static inline void cpu_physical_memory_read(target_phys_addr_t addr,
+ uint8_t *buf, int len)
+{
+ cpu_physical_memory_rw(addr, buf, len, 0);
+}
+static inline void cpu_physical_memory_write(target_phys_addr_t addr,
+ const uint8_t *buf, int len)
+{
+ cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
+}
+void *cpu_physical_memory_map(target_phys_addr_t addr,
+ target_phys_addr_t *plen,
+ int is_write);
+void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
+ int is_write, target_phys_addr_t access_len);
+void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque));
+void cpu_unregister_map_client(void *cookie);
+
+struct CPUPhysMemoryClient;
+typedef struct CPUPhysMemoryClient CPUPhysMemoryClient;
+struct CPUPhysMemoryClient {
+ void (*set_memory)(struct CPUPhysMemoryClient *client,
+ target_phys_addr_t start_addr,
+ ram_addr_t size,
+ ram_addr_t phys_offset);
+ int (*sync_dirty_bitmap)(struct CPUPhysMemoryClient *client,
+ target_phys_addr_t start_addr,
+ target_phys_addr_t end_addr);
+ int (*migration_log)(struct CPUPhysMemoryClient *client,
+ int enable);
+ QLIST_ENTRY(CPUPhysMemoryClient) list;
+};
+
+void cpu_register_phys_memory_client(CPUPhysMemoryClient *);
+void cpu_unregister_phys_memory_client(CPUPhysMemoryClient *);
+
+/* Coalesced MMIO regions are areas where write operations can be reordered.
+ * This usually implies that write operations are side-effect free. This allows
+ * batching which can make a major impact on performance when using
+ * virtualization.
+ */
+void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
+
+void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
+
+void qemu_flush_coalesced_mmio_buffer(void);
+
+uint32_t ldub_phys(target_phys_addr_t addr);
+uint32_t lduw_phys(target_phys_addr_t addr);
+uint32_t ldl_phys(target_phys_addr_t addr);
+uint64_t ldq_phys(target_phys_addr_t addr);
+void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
+void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val);
+void stb_phys(target_phys_addr_t addr, uint32_t val);
+void stw_phys(target_phys_addr_t addr, uint32_t val);
+void stl_phys(target_phys_addr_t addr, uint32_t val);
+void stq_phys(target_phys_addr_t addr, uint64_t val);
+
+void cpu_physical_memory_write_rom(target_phys_addr_t addr,
+ const uint8_t *buf, int len);
+
+#define IO_MEM_SHIFT 3
+
+#define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */
+#define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */
+#define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT)
+#define IO_MEM_NOTDIRTY (3 << IO_MEM_SHIFT)
+
+/* Acts like a ROM when read and like a device when written. */
+#define IO_MEM_ROMD (1)
+#define IO_MEM_SUBPAGE (2)
+
+#endif
+
+#endif /* !CPU_COMMON_H */
diff --git a/src/recompiler/cpu-defs.h b/src/recompiler/cpu-defs.h
index da5301c9a..359a1e2b9 100644
--- a/src/recompiler/cpu-defs.h
+++ b/src/recompiler/cpu-defs.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -30,25 +29,26 @@
#ifndef CPU_DEFS_H
#define CPU_DEFS_H
+#ifndef NEED_CPU_H
+#error cpu.h included from common code
+#endif
+
#include "config.h"
#include <setjmp.h>
-#ifndef VBOX
#include <inttypes.h>
-#endif
+#ifndef VBOX
+#include <signal.h>
+#else /* VBOX */
+# define sig_atomic_t int32_t
+#endif /* VBOX */
#include "osdep.h"
+#include "qemu-queue.h"
+#include "targphys.h"
#ifndef TARGET_LONG_BITS
#error TARGET_LONG_BITS must be defined before including this header
#endif
-#ifndef TARGET_PHYS_ADDR_BITS
-#if TARGET_LONG_BITS >= HOST_LONG_BITS
-#define TARGET_PHYS_ADDR_BITS TARGET_LONG_BITS
-#else
-#define TARGET_PHYS_ADDR_BITS HOST_LONG_BITS
-#endif
-#endif
-
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
/* target_ulong is the type of a virtual address */
@@ -68,36 +68,18 @@ typedef uint64_t target_ulong;
#error TARGET_LONG_SIZE undefined
#endif
-/* target_phys_addr_t is the type of a physical address (its size can
- be different from 'target_ulong'). We have sizeof(target_phys_addr)
- = max(sizeof(unsigned long),
- sizeof(size_of_target_physical_address)) because we must pass a
- host pointer to memory operations in some cases */
-
-#if TARGET_PHYS_ADDR_BITS == 32
-typedef uint32_t target_phys_addr_t;
-#define TARGET_FMT_plx "%08x"
-#elif TARGET_PHYS_ADDR_BITS == 64
-typedef uint64_t target_phys_addr_t;
-#define TARGET_FMT_plx "%016" PRIx64
-#else
-#error TARGET_PHYS_ADDR_BITS undefined
-#endif
-
#define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
-#define EXCP_INTERRUPT 0x10000 /* async interruption */
+#define EXCP_INTERRUPT 0x10000 /* async interruption */
#define EXCP_HLT 0x10001 /* hlt instruction reached */
#define EXCP_DEBUG 0x10002 /* cpu stopped after a breakpoint or singlestep */
#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */
-#if defined(VBOX)
-#define EXCP_EXECUTE_RAW 0x11024 /* execute raw mode. */
-#define EXCP_EXECUTE_HWACC 0x11025 /* execute hardware accelerated raw mode. */
-#define EXCP_SINGLE_INSTR 0x11026 /* executed single instruction. */
-#define EXCP_RC 0x11027 /* a EM rc was raised (VMR3Reset/Suspend/PowerOff). */
+#ifdef VBOX
+# define EXCP_EXECUTE_RAW 0x11024 /**< execute raw mode. */
+# define EXCP_EXECUTE_HWACC 0x11025 /**< execute hardware accelerated raw mode. */
+# define EXCP_SINGLE_INSTR 0x11026 /**< executed single instruction. */
+# define EXCP_RC 0x11027 /**< a EM rc was raised (VMR3Reset/Suspend/PowerOff). */
#endif /* VBOX */
-#define MAX_BREAKPOINTS 32
-#define MAX_WATCHPOINTS 32
#define TB_JMP_CACHE_BITS 12
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
@@ -110,10 +92,11 @@ typedef uint64_t target_phys_addr_t;
#define TB_JMP_ADDR_MASK (TB_JMP_PAGE_SIZE - 1)
#define TB_JMP_PAGE_MASK (TB_JMP_CACHE_SIZE - TB_JMP_PAGE_SIZE)
+#if !defined(CONFIG_USER_ONLY)
#define CPU_TLB_BITS 8
#define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
-#if TARGET_PHYS_ADDR_BITS == 32 && TARGET_LONG_BITS == 32
+#if HOST_LONG_BITS == 32 && TARGET_LONG_BITS == 32
#define CPU_TLB_ENTRY_BITS 4
#else
#define CPU_TLB_ENTRY_BITS 5
@@ -129,22 +112,33 @@ typedef struct CPUTLBEntry {
target_ulong addr_read;
target_ulong addr_write;
target_ulong addr_code;
- /* Addend to virtual address to get physical address. IO accesses
+ /* Addend to virtual address to get host address. IO accesses
use the corresponding iotlb value. */
-#if TARGET_PHYS_ADDR_BITS == 64
- /* on i386 Linux make sure it is aligned */
- target_phys_addr_t addend __attribute__((aligned(8)));
-#else
- target_phys_addr_t addend;
-#endif
+ unsigned long addend;
/* padding to get a power of two size */
uint8_t dummy[(1 << CPU_TLB_ENTRY_BITS) -
(sizeof(target_ulong) * 3 +
- ((-sizeof(target_ulong) * 3) & (sizeof(target_phys_addr_t) - 1)) +
- sizeof(target_phys_addr_t))];
+ ((-sizeof(target_ulong) * 3) & (sizeof(unsigned long) - 1)) +
+ sizeof(unsigned long))];
} CPUTLBEntry;
-#ifdef WORDS_BIGENDIAN
+extern int CPUTLBEntry_wrong_size[sizeof(CPUTLBEntry) == (1 << CPU_TLB_ENTRY_BITS) ? 1 : -1];
+
+#define CPU_COMMON_TLB \
+ /* The meaning of the MMU modes is defined in the target code. */ \
+ CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \
+ target_phys_addr_t iotlb[NB_MMU_MODES][CPU_TLB_SIZE]; \
+ target_ulong tlb_flush_addr; \
+ target_ulong tlb_flush_mask;
+
+#else
+
+#define CPU_COMMON_TLB
+
+#endif
+
+
+#ifdef HOST_WORDS_BIGENDIAN
typedef struct icount_decr_u16 {
uint16_t high;
uint16_t low;
@@ -156,9 +150,24 @@ typedef struct icount_decr_u16 {
} icount_decr_u16;
#endif
+struct kvm_run;
+struct KVMState;
+struct qemu_work_item;
-#define CPU_TEMP_BUF_NLONGS 128
+typedef struct CPUBreakpoint {
+ target_ulong pc;
+ int flags; /* BP_* */
+ QTAILQ_ENTRY(CPUBreakpoint) entry;
+} CPUBreakpoint;
+
+typedef struct CPUWatchpoint {
+ target_ulong vaddr;
+ target_ulong len_mask;
+ int flags; /* BP_* */
+ QTAILQ_ENTRY(CPUWatchpoint) entry;
+} CPUWatchpoint;
+#define CPU_TEMP_BUF_NLONGS 128
#define CPU_COMMON \
struct TranslationBlock *current_tb; /* currently executing TB */ \
/* soft mmu support */ \
@@ -171,11 +180,8 @@ typedef struct icount_decr_u16 {
memory was accessed */ \
uint32_t halted; /* Nonzero if the CPU is in suspend state */ \
uint32_t interrupt_request; \
- /* The meaning of the MMU modes is defined in the target code. */ \
- CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \
- target_phys_addr_t iotlb[NB_MMU_MODES][CPU_TLB_SIZE]; \
- /** addends for HVA -> GPA translations */ \
- VBOX_ONLY(target_phys_addr_t phys_addends[NB_MMU_MODES][CPU_TLB_SIZE]); \
+ volatile sig_atomic_t exit_request; \
+ CPU_COMMON_TLB \
struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
/* buffer for temporaries in the code generator */ \
long temp_buf[CPU_TEMP_BUF_NLONGS]; \
@@ -192,29 +198,38 @@ typedef struct icount_decr_u16 {
\
/* from this point: preserved by CPU reset */ \
/* ice debug support */ \
- target_ulong breakpoints[MAX_BREAKPOINTS]; \
- int nb_breakpoints; \
+ QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \
int singlestep_enabled; \
\
- struct { \
- target_ulong vaddr; \
- int type; /* PAGE_READ/PAGE_WRITE */ \
- } watchpoint[MAX_WATCHPOINTS]; \
- int nb_watchpoints; \
- int watchpoint_hit; \
+ QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \
+ CPUWatchpoint *watchpoint_hit; \
+ \
+ struct GDBRegisterState *gdb_regs; \
\
/* Core interrupt code */ \
jmp_buf jmp_env; \
int exception_index; \
\
- int user_mode_only; \
- \
- void *next_cpu; /* next CPU sharing TB cache */ \
+ CPUState *next_cpu; /* next CPU sharing TB cache */ \
int cpu_index; /* CPU index (informative) */ \
+ uint32_t host_tid; /* host thread ID */ \
+ int numa_node; /* NUMA node this cpu is belonging to */ \
+ int nr_cores; /* number of cores within this CPU package */ \
+ int nr_threads;/* number of threads within this CPU */ \
int running; /* Nonzero if cpu is currently running(usermode). */ \
/* user data */ \
void *opaque; \
\
- const char *cpu_model_str;
+ uint32_t created; \
+ uint32_t stop; /* Stop request */ \
+ uint32_t stopped; /* Artificially stopped */ \
+ struct QemuThread *thread; \
+ struct QemuCond *halt_cond; \
+ struct qemu_work_item *queued_work_first, *queued_work_last; \
+ const char *cpu_model_str; \
+ struct KVMState *kvm_state; \
+ struct kvm_run *kvm_run; \
+ int kvm_fd; \
+ int kvm_vcpu_dirty;
#endif
diff --git a/src/recompiler/cpu-exec.c b/src/recompiler/cpu-exec.c
index 47fa445af..d6b8c00cc 100644
--- a/src/recompiler/cpu-exec.c
+++ b/src/recompiler/cpu-exec.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -28,10 +27,11 @@
*/
#include "config.h"
-#define CPU_NO_GLOBAL_REGS
#include "exec.h"
#include "disas.h"
#include "tcg.h"
+#include "kvm.h"
+#include "qemu-barrier.h"
#if !defined(CONFIG_SOFTMMU)
#undef EAX
@@ -44,10 +44,12 @@
#undef EDI
#undef EIP
#include <signal.h>
+#ifdef __linux__
#include <sys/ucontext.h>
#endif
+#endif
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
+#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
// Work around ugly bugs in glibc that mangle global register contents
#undef env
#define env cpu_single_env
@@ -55,29 +57,31 @@
int tb_invalidated_flag;
-//#define DEBUG_EXEC
+//#define CONFIG_DEBUG_EXEC
//#define DEBUG_SIGNAL
+int qemu_cpu_has_work(CPUState *env)
+{
+ return cpu_has_work(env);
+}
void cpu_loop_exit(void)
{
- /* NOTE: the register at this point must be saved by hand because
- longjmp restore them */
- regs_to_env();
+ env->current_tb = NULL;
longjmp(env->jmp_env, 1);
}
-#if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))
-#define reg_T2
-#endif
-
/* exit the current TB from a signal handler. The host registers are
restored in a state compatible with the CPU emulator
*/
void cpu_resume_from_signal(CPUState *env1, void *puc)
{
#if !defined(CONFIG_SOFTMMU)
+#ifdef __linux__
struct ucontext *uc = puc;
+#elif defined(__OpenBSD__)
+ struct sigcontext *uc = puc;
+#endif
#endif
env = env1;
@@ -87,9 +91,18 @@ void cpu_resume_from_signal(CPUState *env1, void *puc)
#if !defined(CONFIG_SOFTMMU)
if (puc) {
/* XXX: use siglongjmp ? */
+#ifdef __linux__
+#ifdef __ia64
+ sigprocmask(SIG_SETMASK, (sigset_t *)&uc->uc_sigmask, NULL);
+#else
sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
+#endif
+#elif defined(__OpenBSD__)
+ sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
+#endif
}
#endif
+ env->exception_index = -1;
longjmp(env->jmp_env, 1);
}
@@ -114,11 +127,12 @@ static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
#else
next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
#endif
+ env->current_tb = NULL;
if ((next_tb & 3) == 2) {
/* Restore PC. This may happen if async event occurs before
the TB starts executing. */
- CPU_PC_FROM_TB(env, tb);
+ cpu_pc_from_tb(env, tb);
}
tb_phys_invalidate(tb, -1);
tb_free(tb);
@@ -130,14 +144,13 @@ static TranslationBlock *tb_find_slow(target_ulong pc,
{
TranslationBlock *tb, **ptb1;
unsigned int h;
- target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
+ tb_page_addr_t phys_pc, phys_page1, phys_page2;
+ target_ulong virt_page2;
tb_invalidated_flag = 0;
- regs_to_env(); /* XXX: do it just before cpu_gen_code() */
-
/* find translated block using physical mappings */
- phys_pc = get_phys_addr_code(env, pc);
+ phys_pc = get_page_addr_code(env, pc);
phys_page1 = phys_pc & TARGET_PAGE_MASK;
phys_page2 = -1;
h = tb_phys_hash_func(phys_pc);
@@ -154,7 +167,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc,
if (tb->page_addr[1] != -1) {
virt_page2 = (pc & TARGET_PAGE_MASK) +
TARGET_PAGE_SIZE;
- phys_page2 = get_phys_addr_code(env, virt_page2);
+ phys_page2 = get_page_addr_code(env, virt_page2);
if (tb->page_addr[1] == phys_page2)
goto found;
} else {
@@ -173,79 +186,16 @@ static TranslationBlock *tb_find_slow(target_ulong pc,
return tb;
}
-#ifndef VBOX
static inline TranslationBlock *tb_find_fast(void)
-#else
-DECLINLINE(TranslationBlock *) tb_find_fast(void)
-#endif
{
TranslationBlock *tb;
target_ulong cs_base, pc;
- uint64_t flags;
+ int flags;
/* we record a subset of the CPU state. It will
always be the same before a given translated block
is executed. */
-#if defined(TARGET_I386)
- flags = env->hflags;
- flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
- cs_base = env->segs[R_CS].base;
- pc = cs_base + env->eip;
-#elif defined(TARGET_ARM)
- flags = env->thumb | (env->vfp.vec_len << 1)
- | (env->vfp.vec_stride << 4);
- if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR)
- flags |= (1 << 6);
- if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
- flags |= (1 << 7);
- flags |= (env->condexec_bits << 8);
- cs_base = 0;
- pc = env->regs[15];
-#elif defined(TARGET_SPARC)
-#ifdef TARGET_SPARC64
- // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
- flags = ((env->pstate & PS_AM) << 2)
- | (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
- | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
-#else
- // FPU enable . Supervisor
- flags = (env->psref << 4) | env->psrs;
-#endif
- cs_base = env->npc;
- pc = env->pc;
-#elif defined(TARGET_PPC)
- flags = env->hflags;
- cs_base = 0;
- pc = env->nip;
-#elif defined(TARGET_MIPS)
- flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
- cs_base = 0;
- pc = env->active_tc.PC;
-#elif defined(TARGET_M68K)
- flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */
- | (env->sr & SR_S) /* Bit 13 */
- | ((env->macsr >> 4) & 0xf); /* Bits 0-3 */
- cs_base = 0;
- pc = env->pc;
-#elif defined(TARGET_SH4)
- flags = (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL
- | DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME)) /* Bits 0- 3 */
- | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR)) /* Bits 19-21 */
- | (env->sr & (SR_MD | SR_RB)); /* Bits 29-30 */
- cs_base = 0;
- pc = env->pc;
-#elif defined(TARGET_ALPHA)
- flags = env->ps;
- cs_base = 0;
- pc = env->pc;
-#elif defined(TARGET_CRIS)
- flags = env->pregs[PR_CCS] & (S_FLAG | P_FLAG | U_FLAG | X_FLAG);
- flags |= env->dslot;
- cs_base = 0;
- pc = env->pc;
-#else
-#error unsupported CPU
-#endif
+ cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
tb->flags != flags)) {
@@ -254,33 +204,71 @@ DECLINLINE(TranslationBlock *) tb_find_fast(void)
return tb;
}
+static CPUDebugExcpHandler *debug_excp_handler;
+
+CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
+{
+ CPUDebugExcpHandler *old_handler = debug_excp_handler;
+
+ debug_excp_handler = handler;
+ return old_handler;
+}
+
+static void cpu_handle_debug_exception(CPUState *env)
+{
+ CPUWatchpoint *wp;
+
+ if (!env->watchpoint_hit)
+ QTAILQ_FOREACH(wp, &env->watchpoints, entry)
+ wp->flags &= ~BP_WATCHPOINT_HIT;
+
+ if (debug_excp_handler)
+ debug_excp_handler(env);
+}
+
/* main execution loop */
-#ifdef VBOX
+volatile sig_atomic_t exit_request;
int cpu_exec(CPUState *env1)
{
-#define DECLARE_HOST_REGS 1
-#include "hostregs_helper.h"
- int ret = 0, interrupt_request;
+ volatile host_reg_t saved_env_reg;
+ int ret VBOX_ONLY(= 0), interrupt_request;
TranslationBlock *tb;
uint8_t *tc_ptr;
+#ifndef VBOX
+ uintptr_t next_tb;
+#else /* VBOX */
unsigned long next_tb;
+#endif /* VBOX */
+
+# ifndef VBOX
+ if (cpu_halted(env1) == EXCP_HALTED)
+ return EXCP_HALTED;
+# endif /* !VBOX */
cpu_single_env = env1;
- /* first we save global registers */
-#define SAVE_HOST_REGS 1
-#include "hostregs_helper.h"
+ /* the access to env below is actually saving the global register's
+ value, so that files not including target-xyz/exec.h are free to
+ use it. */
+ QEMU_BUILD_BUG_ON (sizeof (saved_env_reg) != sizeof (env));
+ saved_env_reg = (host_reg_t) env;
+ barrier();
env = env1;
- env_to_regs();
+ if (unlikely(exit_request)) {
+ env->exit_request = 1;
+ }
+
#if defined(TARGET_I386)
- /* put eflags in CPU temporary format */
- CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- DF = 1 - (2 * ((env->eflags >> 10) & 1));
- CC_OP = CC_OP_EFLAGS;
- env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+ if (!kvm_enabled()) {
+ /* put eflags in CPU temporary format */
+ CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+ DF = 1 - (2 * ((env->eflags >> 10) & 1));
+ CC_OP = CC_OP_EFLAGS;
+ env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+ }
#elif defined(TARGET_SPARC)
#elif defined(TARGET_M68K)
env->cc_op = CC_OP_FLAGS;
@@ -289,22 +277,29 @@ int cpu_exec(CPUState *env1)
#elif defined(TARGET_ALPHA)
#elif defined(TARGET_ARM)
#elif defined(TARGET_PPC)
+#elif defined(TARGET_MICROBLAZE)
#elif defined(TARGET_MIPS)
#elif defined(TARGET_SH4)
#elif defined(TARGET_CRIS)
+#elif defined(TARGET_S390X)
/* XXXXX */
#else
#error unsupported target CPU
#endif
#ifndef VBOX /* VBOX: We need to raise traps and suchlike from the outside. */
env->exception_index = -1;
-#endif
+#endif /* !VBOX */
/* prepare setjmp context for exception handling */
for(;;) {
- if (setjmp(env->jmp_env) == 0)
- {
- env->current_tb = NULL;
+ if (setjmp(env->jmp_env) == 0) {
+#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
+#undef env
+ env = cpu_single_env;
+#define env cpu_single_env
+#endif
+#ifdef VBOX
+ env->current_tb = NULL; /* probably not needed, but whatever... */
/*
* Check for fatal errors first
@@ -315,298 +310,21 @@ int cpu_exec(CPUState *env1)
ret = env->exception_index;
cpu_loop_exit();
}
-
- /* if an exception is pending, we execute it here */
- if (env->exception_index >= 0) {
- Assert(!env->user_mode_only);
- if (env->exception_index >= EXCP_INTERRUPT) {
- /* exit request from the cpu execution loop */
- ret = env->exception_index;
- break;
- } else {
- /* simulate a real cpu exception. On i386, it can
- trigger new exceptions, but we do not handle
- double or triple faults yet. */
- RAWEx_ProfileStart(env, STATS_IRQ_HANDLING);
- Log(("do_interrupt %d %d %RGv\n", env->exception_index, env->exception_is_int, (RTGCPTR)env->exception_next_eip));
- do_interrupt(env->exception_index,
- env->exception_is_int,
- env->error_code,
- env->exception_next_eip, 0);
- /* successfully delivered */
- env->old_exception = -1;
- RAWEx_ProfileStop(env, STATS_IRQ_HANDLING);
- }
- env->exception_index = -1;
- }
-
- next_tb = 0; /* force lookup of first TB */
- for(;;)
- {
- interrupt_request = env->interrupt_request;
-#ifndef VBOX
- if (__builtin_expect(interrupt_request, 0))
-#else
- if (RT_UNLIKELY(interrupt_request != 0))
-#endif
- {
- /** @todo: reconcile with what QEMU really does */
-
- /* Single instruction exec request, we execute it and return (one way or the other).
- The caller will always reschedule after doing this operation! */
- if (interrupt_request & CPU_INTERRUPT_SINGLE_INSTR)
- {
- /* not in flight are we? (if we are, we trapped) */
- if (!(env->interrupt_request & CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT))
- {
- ASMAtomicOrS32((int32_t volatile *)&env->interrupt_request, CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT);
- env->exception_index = EXCP_SINGLE_INSTR;
- if (emulate_single_instr(env) == -1)
- AssertMsgFailed(("REM: emulate_single_instr failed for EIP=%RGv!!\n", (RTGCPTR)env->eip));
-
- /* When we receive an external interrupt during execution of this single
- instruction, then we should stay here. We will leave when we're ready
- for raw-mode or when interrupted by pending EMT requests. */
- interrupt_request = env->interrupt_request; /* reload this! */
- if ( !(interrupt_request & CPU_INTERRUPT_HARD)
- || !(env->eflags & IF_MASK)
- || (env->hflags & HF_INHIBIT_IRQ_MASK)
- || (env->state & CPU_RAW_HWACC)
- )
- {
- env->exception_index = ret = EXCP_SINGLE_INSTR;
- cpu_loop_exit();
- }
- }
- /* Clear CPU_INTERRUPT_SINGLE_INSTR and leave CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT set. */
- ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_SINGLE_INSTR);
- }
-
- RAWEx_ProfileStart(env, STATS_IRQ_HANDLING);
- if ((interrupt_request & CPU_INTERRUPT_SMI) &&
- !(env->hflags & HF_SMM_MASK)) {
- env->interrupt_request &= ~CPU_INTERRUPT_SMI;
- do_smm_enter();
- next_tb = 0;
- }
- else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->eflags & IF_MASK) &&
- !(env->hflags & HF_INHIBIT_IRQ_MASK))
- {
- /* if hardware interrupt pending, we execute it */
- int intno;
- ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_HARD);
- intno = cpu_get_pic_interrupt(env);
- if (intno >= 0)
- {
- Log(("do_interrupt %d\n", intno));
- do_interrupt(intno, 0, 0, 0, 1);
- }
- /* ensure that no TB jump will be modified as
- the program flow was changed */
- next_tb = 0;
- }
- if (env->interrupt_request & CPU_INTERRUPT_EXITTB)
- {
- ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_EXITTB);
- /* ensure that no TB jump will be modified as
- the program flow was changed */
- next_tb = 0;
- }
- RAWEx_ProfileStop(env, STATS_IRQ_HANDLING);
- if (interrupt_request & CPU_INTERRUPT_EXIT)
- {
- env->exception_index = EXCP_INTERRUPT;
- ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_EXIT);
- ret = env->exception_index;
- cpu_loop_exit();
- }
- if (interrupt_request & CPU_INTERRUPT_RC)
- {
- env->exception_index = EXCP_RC;
- ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_RC);
- ret = env->exception_index;
- cpu_loop_exit();
- }
- }
-
- /*
- * Check if we the CPU state allows us to execute the code in raw-mode.
- */
- RAWEx_ProfileStart(env, STATS_RAW_CHECK);
- if (remR3CanExecuteRaw(env,
- env->eip + env->segs[R_CS].base,
- env->hflags | (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK)),
- &env->exception_index))
- {
- RAWEx_ProfileStop(env, STATS_RAW_CHECK);
- ret = env->exception_index;
- cpu_loop_exit();
- }
- RAWEx_ProfileStop(env, STATS_RAW_CHECK);
-
- RAWEx_ProfileStart(env, STATS_TLB_LOOKUP);
- spin_lock(&tb_lock);
- tb = tb_find_fast();
- /* Note: we do it here to avoid a gcc bug on Mac OS X when
- doing it in tb_find_slow */
- if (tb_invalidated_flag) {
- /* as some TB could have been invalidated because
- of memory exceptions while generating the code, we
- must recompute the hash index here */
- next_tb = 0;
- tb_invalidated_flag = 0;
- }
-
- /* see if we can patch the calling TB. When the TB
- spans two pages, we cannot safely do a direct
- jump. */
- if (next_tb != 0
- && !(tb->cflags & CF_RAW_MODE)
- && tb->page_addr[1] == -1)
- {
- tb_add_jump((TranslationBlock *)(long)(next_tb & ~3), next_tb & 3, tb);
- }
- spin_unlock(&tb_lock);
- RAWEx_ProfileStop(env, STATS_TLB_LOOKUP);
-
- env->current_tb = tb;
- while (env->current_tb) {
- tc_ptr = tb->tc_ptr;
- /* execute the generated code */
- RAWEx_ProfileStart(env, STATS_QEMU_RUN_EMULATED_CODE);
-#if defined(VBOX) && defined(GCC_WITH_BUGGY_REGPARM)
- tcg_qemu_tb_exec(tc_ptr, next_tb);
-#else
- next_tb = tcg_qemu_tb_exec(tc_ptr);
-#endif
- RAWEx_ProfileStop(env, STATS_QEMU_RUN_EMULATED_CODE);
- env->current_tb = NULL;
- if ((next_tb & 3) == 2) {
- /* Instruction counter expired. */
- int insns_left;
- tb = (TranslationBlock *)(long)(next_tb & ~3);
- /* Restore PC. */
- CPU_PC_FROM_TB(env, tb);
- insns_left = env->icount_decr.u32;
- if (env->icount_extra && insns_left >= 0) {
- /* Refill decrementer and continue execution. */
- env->icount_extra += insns_left;
- if (env->icount_extra > 0xffff) {
- insns_left = 0xffff;
- } else {
- insns_left = env->icount_extra;
- }
- env->icount_extra -= insns_left;
- env->icount_decr.u16.low = insns_left;
- } else {
- if (insns_left > 0) {
- /* Execute remaining instructions. */
- cpu_exec_nocache(insns_left, tb);
- }
- env->exception_index = EXCP_INTERRUPT;
- next_tb = 0;
- cpu_loop_exit();
- }
- }
- }
-
- /* reset soft MMU for next block (it can currently
- only be set by a memory fault) */
-#if defined(TARGET_I386) && !defined(CONFIG_SOFTMMU)
- if (env->hflags & HF_SOFTMMU_MASK) {
- env->hflags &= ~HF_SOFTMMU_MASK;
- /* do not allow linking to another block */
- next_tb = 0;
- }
-#endif
- } /* for(;;) */
- } else {
- env_to_regs();
- }
-#ifdef VBOX_HIGH_RES_TIMERS_HACK
- /* NULL the current_tb here so cpu_interrupt() doesn't do anything
- unnecessary (like crashing during emulate single instruction).
- Note! Don't use env1->pVM here, the code wouldn't run with
- gcc-4.4/amd64 anymore, see #3883. */
- env->current_tb = NULL;
- if ( !(env->interrupt_request & ( CPU_INTERRUPT_EXIT | CPU_INTERRUPT_DEBUG | CPU_INTERRUPT_EXTERNAL_EXIT | CPU_INTERRUPT_RC
- | CPU_INTERRUPT_SINGLE_INSTR | CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT))
- && ( (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_TIMER)
- || TMTimerPollBool(env->pVM, env->pVCpu)) ) {
- ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_EXTERNAL_TIMER);
- remR3ProfileStart(STATS_QEMU_RUN_TIMERS);
- TMR3TimerQueuesDo(env->pVM);
- remR3ProfileStop(STATS_QEMU_RUN_TIMERS);
- }
-#endif
- } /* for(;;) */
-
-#if defined(TARGET_I386)
- /* restore flags in standard format */
- env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
-#else
-#error unsupported target CPU
-#endif
-#include "hostregs_helper.h"
- return ret;
-}
-
-#else /* !VBOX */
-int cpu_exec(CPUState *env1)
-{
-#define DECLARE_HOST_REGS 1
-#include "hostregs_helper.h"
- int ret, interrupt_request;
- TranslationBlock *tb;
- uint8_t *tc_ptr;
- unsigned long next_tb;
-
- if (cpu_halted(env1) == EXCP_HALTED)
- return EXCP_HALTED;
-
- cpu_single_env = env1;
-
- /* first we save global registers */
-#define SAVE_HOST_REGS 1
-#include "hostregs_helper.h"
- env = env1;
-
- env_to_regs();
-#if defined(TARGET_I386)
- /* put eflags in CPU temporary format */
- CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- DF = 1 - (2 * ((env->eflags >> 10) & 1));
- CC_OP = CC_OP_EFLAGS;
- env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-#elif defined(TARGET_SPARC)
-#elif defined(TARGET_M68K)
- env->cc_op = CC_OP_FLAGS;
- env->cc_dest = env->sr & 0xf;
- env->cc_x = (env->sr >> 4) & 1;
-#elif defined(TARGET_ALPHA)
-#elif defined(TARGET_ARM)
-#elif defined(TARGET_PPC)
-#elif defined(TARGET_MIPS)
-#elif defined(TARGET_SH4)
-#elif defined(TARGET_CRIS)
- /* XXXXX */
-#else
-#error unsupported target CPU
#endif
- env->exception_index = -1;
- /* prepare setjmp context for exception handling */
- for(;;) {
- if (setjmp(env->jmp_env) == 0) {
- env->current_tb = NULL;
/* if an exception is pending, we execute it here */
if (env->exception_index >= 0) {
if (env->exception_index >= EXCP_INTERRUPT) {
/* exit request from the cpu execution loop */
ret = env->exception_index;
+#ifdef VBOX /* because of the above stuff */
+ env->exception_index = -1;
+#endif
+ if (ret == EXCP_DEBUG)
+ cpu_handle_debug_exception(env);
break;
- } else if (env->user_mode_only) {
+ } else {
+#if defined(CONFIG_USER_ONLY)
/* if user mode only, we simulate a fake exception
which will be handled outside the cpu execution
loop */
@@ -620,19 +338,29 @@ int cpu_exec(CPUState *env1)
#endif
ret = env->exception_index;
break;
- } else {
+#else
#if defined(TARGET_I386)
/* simulate a real cpu exception. On i386, it can
trigger new exceptions, but we do not handle
double or triple faults yet. */
+# ifdef VBOX
+ RAWEx_ProfileStart(env, STATS_IRQ_HANDLING);
+ Log(("do_interrupt: vec=%#x int=%d pc=%04x:%RGv\n", env->exception_index, env->exception_is_int,
+ env->segs[R_CS].selector, (RTGCPTR)env->exception_next_eip));
+# endif /* VBOX */
do_interrupt(env->exception_index,
env->exception_is_int,
env->error_code,
env->exception_next_eip, 0);
/* successfully delivered */
env->old_exception = -1;
+# ifdef VBOX
+ RAWEx_ProfileStop(env, STATS_IRQ_HANDLING);
+# endif /* VBOX */
#elif defined(TARGET_PPC)
do_interrupt(env);
+#elif defined(TARGET_MICROBLAZE)
+ do_interrupt(env);
#elif defined(TARGET_MIPS)
do_interrupt(env);
#elif defined(TARGET_SPARC)
@@ -640,7 +368,7 @@ int cpu_exec(CPUState *env1)
#elif defined(TARGET_ARM)
do_interrupt(env);
#elif defined(TARGET_SH4)
- do_interrupt(env);
+ do_interrupt(env);
#elif defined(TARGET_ALPHA)
do_interrupt(env);
#elif defined(TARGET_CRIS)
@@ -648,47 +376,37 @@ int cpu_exec(CPUState *env1)
#elif defined(TARGET_M68K)
do_interrupt(0);
#endif
+ env->exception_index = -1;
+#endif
}
- env->exception_index = -1;
}
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env) && env->interrupt_request == 0) {
- int ret;
- env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
- ret = kqemu_cpu_exec(env);
- /* put eflags in CPU temporary format */
- CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- DF = 1 - (2 * ((env->eflags >> 10) & 1));
- CC_OP = CC_OP_EFLAGS;
- env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- if (ret == 1) {
- /* exception */
- longjmp(env->jmp_env, 1);
- } else if (ret == 2) {
- /* softmmu execution needed */
- } else {
- if (env->interrupt_request != 0) {
- /* hardware interrupt will be executed just after */
- } else {
- /* otherwise, we restart */
- longjmp(env->jmp_env, 1);
- }
- }
+
+# ifndef VBOX
+ if (kvm_enabled()) {
+ kvm_cpu_exec(env);
+ longjmp(env->jmp_env, 1);
}
-#endif
+# endif /* !VBOX */
next_tb = 0; /* force lookup of first TB */
for(;;) {
interrupt_request = env->interrupt_request;
- if (unlikely(interrupt_request) &&
- likely(!(env->singlestep_enabled & SSTEP_NOIRQ))) {
+ if (unlikely(interrupt_request)) {
+ if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
+ /* Mask out external interrupts for this step. */
+ interrupt_request &= ~(CPU_INTERRUPT_HARD |
+ CPU_INTERRUPT_FIQ |
+ CPU_INTERRUPT_SMI |
+ CPU_INTERRUPT_NMI);
+ }
if (interrupt_request & CPU_INTERRUPT_DEBUG) {
env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
env->exception_index = EXCP_DEBUG;
cpu_loop_exit();
}
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
- defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS)
+ defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
+ defined(TARGET_MICROBLAZE)
if (interrupt_request & CPU_INTERRUPT_HALT) {
env->interrupt_request &= ~CPU_INTERRUPT_HALT;
env->halted = 1;
@@ -697,7 +415,56 @@ int cpu_exec(CPUState *env1)
}
#endif
#if defined(TARGET_I386)
- if (env->hflags2 & HF2_GIF_MASK) {
+# ifdef VBOX
+ /* Memory registration may post a tlb flush request, process it ASAP. */
+ if (interrupt_request & (CPU_INTERRUPT_EXTERNAL_FLUSH_TLB)) {
+ tlb_flush(env, true); /* (clears the flush flag) */
+ }
+
+ /* Single instruction exec request, we execute it and return (one way or the other).
+ The caller will always reschedule after doing this operation! */
+ if (interrupt_request & CPU_INTERRUPT_SINGLE_INSTR)
+ {
+ /* not in flight are we? (if we are, we trapped) */
+ if (!(env->interrupt_request & CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT))
+ {
+ ASMAtomicOrS32((int32_t volatile *)&env->interrupt_request, CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT);
+ env->exception_index = EXCP_SINGLE_INSTR;
+ if (emulate_single_instr(env) == -1)
+ AssertMsgFailed(("REM: emulate_single_instr failed for EIP=%RGv!!\n", (RTGCPTR)env->eip));
+
+ /* When we receive an external interrupt during execution of this single
+ instruction, then we should stay here. We will leave when we're ready
+ for raw-mode or when interrupted by pending EMT requests. */
+ interrupt_request = env->interrupt_request; /* reload this! */
+ if ( !(interrupt_request & CPU_INTERRUPT_HARD)
+ || !(env->eflags & IF_MASK)
+ || (env->hflags & HF_INHIBIT_IRQ_MASK)
+ || (env->state & CPU_RAW_HWACC)
+ )
+ {
+ env->exception_index = ret = EXCP_SINGLE_INSTR;
+ cpu_loop_exit();
+ }
+ }
+ /* Clear CPU_INTERRUPT_SINGLE_INSTR and leave CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT set. */
+ ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_SINGLE_INSTR);
+# ifdef IEM_VERIFICATION_MODE
+ env->exception_index = ret = EXCP_SINGLE_INSTR;
+ cpu_loop_exit();
+# endif
+ }
+# endif /* VBOX */
+
+# ifndef VBOX /** @todo reconcile our code with the following... */
+ if (interrupt_request & CPU_INTERRUPT_INIT) {
+ svm_check_intercept(SVM_EXIT_INIT);
+ do_cpu_init(env);
+ env->exception_index = EXCP_HALTED;
+ cpu_loop_exit();
+ } else if (interrupt_request & CPU_INTERRUPT_SIPI) {
+ do_cpu_sipi(env);
+ } else if (env->hflags2 & HF2_GIF_MASK) {
if ((interrupt_request & CPU_INTERRUPT_SMI) &&
!(env->hflags & HF_SMM_MASK)) {
svm_check_intercept(SVM_EXIT_SMI);
@@ -710,6 +477,10 @@ int cpu_exec(CPUState *env1)
env->hflags2 |= HF2_NMI_MASK;
do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
next_tb = 0;
+ } else if (interrupt_request & CPU_INTERRUPT_MCE) {
+ env->interrupt_request &= ~CPU_INTERRUPT_MCE;
+ do_interrupt(EXCP12_MCHK, 0, 0, 0, 0);
+ next_tb = 0;
} else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
(((env->hflags2 & HF2_VINTR_MASK) &&
(env->hflags2 & HF2_HIF_MASK)) ||
@@ -720,9 +491,12 @@ int cpu_exec(CPUState *env1)
svm_check_intercept(SVM_EXIT_INTR);
env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
intno = cpu_get_pic_interrupt(env);
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
- }
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
+#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
+#undef env
+ env = cpu_single_env;
+#define env cpu_single_env
+#endif
do_interrupt(intno, 0, 0, 0, 1);
/* ensure that no TB jump will be modified as
the program flow was changed */
@@ -734,19 +508,44 @@ int cpu_exec(CPUState *env1)
int intno;
/* FIXME: this should respect TPR */
svm_check_intercept(SVM_EXIT_VINTR);
- env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
do_interrupt(intno, 0, 0, 0, 1);
+ env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
next_tb = 0;
#endif
}
}
+# else /* VBOX */
+ RAWEx_ProfileStart(env, STATS_IRQ_HANDLING);
+ if ((interrupt_request & CPU_INTERRUPT_SMI) &&
+ !(env->hflags & HF_SMM_MASK)) {
+ env->interrupt_request &= ~CPU_INTERRUPT_SMI;
+ do_smm_enter();
+ next_tb = 0;
+ }
+ else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->eflags & IF_MASK) &&
+ !(env->hflags & HF_INHIBIT_IRQ_MASK))
+ {
+ /* if hardware interrupt pending, we execute it */
+ int intno;
+ ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_HARD);
+ intno = cpu_get_pic_interrupt(env);
+ if (intno >= 0)
+ {
+ Log(("do_interrupt %d\n", intno));
+ do_interrupt(intno, 0, 0, 0, 1);
+ }
+ /* ensure that no TB jump will be modified as
+ the program flow was changed */
+ next_tb = 0;
+ }
+# endif /* VBOX */
#elif defined(TARGET_PPC)
#if 0
if ((interrupt_request & CPU_INTERRUPT_RESET)) {
- cpu_ppc_reset(env);
+ cpu_reset(env);
}
#endif
if (interrupt_request & CPU_INTERRUPT_HARD) {
@@ -755,6 +554,15 @@ int cpu_exec(CPUState *env1)
env->interrupt_request &= ~CPU_INTERRUPT_HARD;
next_tb = 0;
}
+#elif defined(TARGET_MICROBLAZE)
+ if ((interrupt_request & CPU_INTERRUPT_HARD)
+ && (env->sregs[SR_MSR] & MSR_IE)
+ && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
+ && !(env->iflags & (D_FLAG | IMM_FLAG))) {
+ env->exception_index = EXCP_IRQ;
+ do_interrupt(env);
+ next_tb = 0;
+ }
#elif defined(TARGET_MIPS)
if ((interrupt_request & CPU_INTERRUPT_HARD) &&
(env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
@@ -769,23 +577,20 @@ int cpu_exec(CPUState *env1)
next_tb = 0;
}
#elif defined(TARGET_SPARC)
- if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->psret != 0)) {
- int pil = env->interrupt_index & 15;
- int type = env->interrupt_index & 0xf0;
-
- if (((type == TT_EXTINT) &&
- (pil == 15 || pil > env->psrpil)) ||
- type != TT_EXTINT) {
- env->interrupt_request &= ~CPU_INTERRUPT_HARD;
- env->exception_index = env->interrupt_index;
- do_interrupt(env);
- env->interrupt_index = 0;
-#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
- cpu_check_irqs(env);
-#endif
- next_tb = 0;
- }
+ if (interrupt_request & CPU_INTERRUPT_HARD) {
+ if (cpu_interrupts_enabled(env) &&
+ env->interrupt_index > 0) {
+ int pil = env->interrupt_index & 0xf;
+ int type = env->interrupt_index & 0xf0;
+
+ if (((type == TT_EXTINT) &&
+ cpu_pil_allowed(env, pil)) ||
+ type != TT_EXTINT) {
+ env->exception_index = env->interrupt_index;
+ do_interrupt(env);
+ next_tb = 0;
+ }
+ }
} else if (interrupt_request & CPU_INTERRUPT_TIMER) {
//do_interrupt(0, 0, 0, 0, 0);
env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
@@ -803,7 +608,7 @@ int cpu_exec(CPUState *env1)
jump normally, then does the exception return when the
CPU tries to execute code at the magic address.
This will cause the magic PC value to be pushed to
- the stack if an interrupt occurred at the wrong time.
+ the stack if an interrupt occured at the wrong time.
We avoid this by disabling interrupts when
pc contains a magic address. */
if (interrupt_request & CPU_INTERRUPT_HARD
@@ -825,7 +630,8 @@ int cpu_exec(CPUState *env1)
}
#elif defined(TARGET_CRIS)
if (interrupt_request & CPU_INTERRUPT_HARD
- && (env->pregs[PR_CCS] & I_FLAG)) {
+ && (env->pregs[PR_CCS] & I_FLAG)
+ && !env->locked_irq) {
env->exception_index = EXCP_IRQ;
do_interrupt(env);
next_tb = 0;
@@ -850,53 +656,76 @@ int cpu_exec(CPUState *env1)
next_tb = 0;
}
#endif
- /* Don't use the cached interrupt_request value,
+ /* Don't use the cached interupt_request value,
do_interrupt may have updated the EXITTB flag. */
if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
+#ifndef VBOX
env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
+#else /* VBOX */
+ ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_EXITTB);
+#endif /* VBOX */
/* ensure that no TB jump will be modified as
the program flow was changed */
next_tb = 0;
}
- if (interrupt_request & CPU_INTERRUPT_EXIT) {
- env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
- env->exception_index = EXCP_INTERRUPT;
+#ifdef VBOX
+ RAWEx_ProfileStop(env, STATS_IRQ_HANDLING);
+ if (interrupt_request & CPU_INTERRUPT_RC) {
+ env->exception_index = EXCP_RC;
+ ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_RC);
+ ret = env->exception_index;
cpu_loop_exit();
}
+ if (interrupt_request & (CPU_INTERRUPT_EXTERNAL_EXIT)) {
+ ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~(CPU_INTERRUPT_EXTERNAL_EXIT));
+ env->exit_request = 1;
+ }
+#endif
+ }
+ if (unlikely(env->exit_request)) {
+ env->exit_request = 0;
+ env->exception_index = EXCP_INTERRUPT;
+ cpu_loop_exit();
}
-#ifdef DEBUG_EXEC
- if ((loglevel & CPU_LOG_TB_CPU)) {
+
+#ifdef VBOX
+ /*
+ * Check if we the CPU state allows us to execute the code in raw-mode.
+ */
+ RAWEx_ProfileStart(env, STATS_RAW_CHECK);
+ if (remR3CanExecuteRaw(env,
+ env->eip + env->segs[R_CS].base,
+ env->hflags | (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK)),
+ &env->exception_index))
+ {
+ RAWEx_ProfileStop(env, STATS_RAW_CHECK);
+ ret = env->exception_index;
+ cpu_loop_exit();
+ }
+ RAWEx_ProfileStop(env, STATS_RAW_CHECK);
+#endif /* VBOX */
+
+#if defined(DEBUG_DISAS) || defined(CONFIG_DEBUG_EXEC)
+ if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
/* restore flags in standard format */
- regs_to_env();
#if defined(TARGET_I386)
- env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
+ env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
+ log_cpu_state(env, X86_DUMP_CCOP);
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-#elif defined(TARGET_ARM)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_SPARC)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_PPC)
- cpu_dump_state(env, logfile, fprintf, 0);
#elif defined(TARGET_M68K)
cpu_m68k_flush_flags(env, env->cc_op);
env->cc_op = CC_OP_FLAGS;
env->sr = (env->sr & 0xffe0)
| env->cc_dest | (env->cc_x << 4);
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_MIPS)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_SH4)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_ALPHA)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_CRIS)
- cpu_dump_state(env, logfile, fprintf, 0);
+ log_cpu_state(env, 0);
#else
-#error unsupported target CPU
+ log_cpu_state(env, 0);
#endif
}
-#endif
+#endif /* DEBUG_DISAS || CONFIG_DEBUG_EXEC */
+#ifdef VBOX
+ RAWEx_ProfileStart(env, STATS_TLB_LOOKUP);
+#endif /*VBOX*/
spin_lock(&tb_lock);
tb = tb_find_fast();
/* Note: we do it here to avoid a gcc bug on Mac OS X when
@@ -908,43 +737,57 @@ int cpu_exec(CPUState *env1)
next_tb = 0;
tb_invalidated_flag = 0;
}
-#ifdef DEBUG_EXEC
- if ((loglevel & CPU_LOG_EXEC)) {
- fprintf(logfile, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
- (long)tb->tc_ptr, tb->pc,
- lookup_symbol(tb->pc));
- }
+#ifdef CONFIG_DEBUG_EXEC
+ qemu_log_mask(CPU_LOG_EXEC, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
+ (long)tb->tc_ptr, tb->pc,
+ lookup_symbol(tb->pc));
#endif
/* see if we can patch the calling TB. When the TB
spans two pages, we cannot safely do a direct
jump. */
- {
- if (next_tb != 0 &&
-#ifdef USE_KQEMU
- (env->kqemu_enabled != 2) &&
-#endif
- tb->page_addr[1] == -1) {
+#ifndef VBOX
+ if (next_tb != 0 && tb->page_addr[1] == -1) {
+#else /* VBOX */
+ if (next_tb != 0 && !(tb->cflags & CF_RAW_MODE) && tb->page_addr[1] == -1) {
+#endif /* VBOX */
tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
}
- }
spin_unlock(&tb_lock);
+#ifdef VBOX
+ RAWEx_ProfileStop(env, STATS_TLB_LOOKUP);
+#endif
+
+ /* cpu_interrupt might be called while translating the
+ TB, but before it is linked into a potentially
+ infinite loop and becomes env->current_tb. Avoid
+ starting execution if there is a pending interrupt. */
env->current_tb = tb;
- while (env->current_tb) {
+ barrier();
+ if (likely(!env->exit_request)) {
tc_ptr = tb->tc_ptr;
/* execute the generated code */
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
+#ifdef VBOX
+ RAWEx_ProfileStart(env, STATS_QEMU_RUN_EMULATED_CODE);
+#endif
+#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
#undef env
env = cpu_single_env;
#define env cpu_single_env
#endif
+#if defined(VBOX) && defined(GCC_WITH_BUGGY_REGPARM)
+ tcg_qemu_tb_exec(tc_ptr, next_tb);
+#else
next_tb = tcg_qemu_tb_exec(tc_ptr);
- env->current_tb = NULL;
+#endif
+#ifdef VBOX
+ RAWEx_ProfileStop(env, STATS_QEMU_RUN_EMULATED_CODE);
+#endif
if ((next_tb & 3) == 2) {
/* Instruction counter expired. */
int insns_left;
tb = (TranslationBlock *)(long)(next_tb & ~3);
/* Restore PC. */
- CPU_PC_FROM_TB(env, tb);
+ cpu_pc_from_tb(env, tb);
insns_left = env->icount_decr.u32;
if (env->icount_extra && insns_left >= 0) {
/* Refill decrementer and continue execution. */
@@ -967,25 +810,33 @@ int cpu_exec(CPUState *env1)
}
}
}
+ env->current_tb = NULL;
/* reset soft MMU for next block (it can currently
only be set by a memory fault) */
-#if defined(USE_KQEMU)
-#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
- if (kqemu_is_ok(env) &&
- (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
- cpu_loop_exit();
- }
-#endif
} /* for(;;) */
- } else {
- env_to_regs();
}
+#ifdef VBOX_HIGH_RES_TIMERS_HACK
+ /* NULL the current_tb here so cpu_interrupt() doesn't do anything
+ unnecessary (like crashing during emulate single instruction).
+ Note! Don't use env1->pVM here, the code wouldn't run with
+ gcc-4.4/amd64 anymore, see #3883. */
+ env->current_tb = NULL;
+ if ( !(env->interrupt_request & ( CPU_INTERRUPT_DEBUG | CPU_INTERRUPT_EXTERNAL_EXIT | CPU_INTERRUPT_RC
+ | CPU_INTERRUPT_SINGLE_INSTR | CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT))
+ && ( (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_TIMER)
+ || TMTimerPollBool(env->pVM, env->pVCpu)) ) {
+ ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_EXTERNAL_TIMER);
+ remR3ProfileStart(STATS_QEMU_RUN_TIMERS);
+ TMR3TimerQueuesDo(env->pVM);
+ remR3ProfileStop(STATS_QEMU_RUN_TIMERS);
+ }
+#endif
} /* for(;;) */
#if defined(TARGET_I386)
/* restore flags in standard format */
- env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
+ env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
#elif defined(TARGET_ARM)
/* XXX: Save/restore host fpu exception state?. */
#elif defined(TARGET_SPARC)
@@ -995,23 +846,27 @@ int cpu_exec(CPUState *env1)
env->cc_op = CC_OP_FLAGS;
env->sr = (env->sr & 0xffe0)
| env->cc_dest | (env->cc_x << 4);
+#elif defined(TARGET_MICROBLAZE)
#elif defined(TARGET_MIPS)
#elif defined(TARGET_SH4)
#elif defined(TARGET_ALPHA)
#elif defined(TARGET_CRIS)
+#elif defined(TARGET_S390X)
/* XXXXX */
#else
#error unsupported target CPU
#endif
/* restore global registers */
-#include "hostregs_helper.h"
+ barrier();
+ env = (void *) saved_env_reg;
+# ifndef VBOX /* we might be using elsewhere, we only have one. */
/* fail safe : never use cpu_single_env outside cpu_exec() */
cpu_single_env = NULL;
+# endif
return ret;
}
-#endif /* !VBOX */
/* must only be called from the generated code as an exception can be
generated */
@@ -1039,31 +894,31 @@ void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
cpu_x86_load_seg_cache(env, seg_reg, selector,
(selector << 4), 0xffff, 0);
} else {
- load_seg(seg_reg, selector);
+ helper_load_seg(seg_reg, selector);
}
env = saved_env;
}
-void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32)
+void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
{
CPUX86State *saved_env;
saved_env = env;
env = s;
- helper_fsave((target_ulong)ptr, data32);
+ helper_fsave(ptr, data32);
env = saved_env;
}
-void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32)
+void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
{
CPUX86State *saved_env;
saved_env = env;
env = s;
- helper_frstor((target_ulong)ptr, data32);
+ helper_frstor(ptr, data32);
env = saved_env;
}
@@ -1073,6 +928,10 @@ void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32)
#if !defined(CONFIG_SOFTMMU)
#if defined(TARGET_I386)
+#define EXCEPTION_ACTION raise_exception_err(env->exception_index, env->error_code)
+#else
+#define EXCEPTION_ACTION cpu_loop_exit()
+#endif
/* 'pc' is the host PC at which the exception was raised. 'address' is
the effective address of the memory exception. 'is_write' is 1 if a
@@ -1097,57 +956,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
}
/* see if it is an MMU fault */
- ret = cpu_x86_handle_mmu_fault(env, address, is_write,
- ((env->hflags & HF_CPL_MASK) == 3), 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- if (ret == 1) {
-#if 0
- printf("PF exception: EIP=0x%RGv CR2=0x%RGv error=0x%x\n",
- env->eip, env->cr[2], env->error_code);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- raise_exception_err(env->exception_index, env->error_code);
- } else {
- /* activate soft MMU for this block */
- env->hflags |= HF_SOFTMMU_MASK;
- cpu_resume_from_signal(env, puc);
- }
- /* never comes here */
- return 1;
-}
-
-#elif defined(TARGET_ARM)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
- /* see if it is an MMU fault */
- ret = cpu_arm_handle_mmu_fault(env, address, is_write, 1, 0);
+ ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
if (ret < 0)
return 0; /* not an MMU fault */
if (ret == 0)
@@ -1159,234 +968,16 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
a virtual CPU fault */
cpu_restore_state(tb, env, pc, puc);
}
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
-}
-#elif defined(TARGET_SPARC)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
- /* see if it is an MMU fault */
- ret = cpu_sparc_handle_mmu_fault(env, address, is_write, 1, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
/* we restore the process signal mask as the sigreturn should
do it (XXX: use sigsetjmp) */
sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
-}
-#elif defined (TARGET_PPC)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
+ EXCEPTION_ACTION;
- /* see if it is an MMU fault */
- ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
-
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- if (ret == 1) {
-#if 0
- printf("PF exception: NIP=0x%08x error=0x%x %p\n",
- env->nip, env->error_code, tb);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- do_raise_exception_err(env->exception_index, env->error_code);
- } else {
- /* activate soft MMU for this block */
- cpu_resume_from_signal(env, puc);
- }
/* never comes here */
return 1;
}
-#elif defined(TARGET_M68K)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(address, pc, puc)) {
- return 1;
- }
- /* see if it is an MMU fault */
- ret = cpu_m68k_handle_mmu_fault(env, address, is_write, 1, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
- /* never comes here */
- return 1;
-}
-
-#elif defined (TARGET_MIPS)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
-
- /* see if it is an MMU fault */
- ret = cpu_mips_handle_mmu_fault(env, address, is_write, 1, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
-
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- if (ret == 1) {
-#if 0
- printf("PF exception: NIP=0x%08x error=0x%x %p\n",
- env->nip, env->error_code, tb);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- do_raise_exception_err(env->exception_index, env->error_code);
- } else {
- /* activate soft MMU for this block */
- cpu_resume_from_signal(env, puc);
- }
- /* never comes here */
- return 1;
-}
-
-#elif defined (TARGET_SH4)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
-
- /* see if it is an MMU fault */
- ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
-
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
-#if 0
- printf("PF exception: NIP=0x%08x error=0x%x %p\n",
- env->nip, env->error_code, tb);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
- /* never comes here */
- return 1;
-}
-#else
-#error unsupported target CPU
-#endif
-
#if defined(__i386__)
#if defined(__APPLE__)
@@ -1395,17 +986,44 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
# define EIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext->ss.eip))
# define TRAP_sig(context) ((context)->uc_mcontext->es.trapno)
# define ERROR_sig(context) ((context)->uc_mcontext->es.err)
+# define MASK_sig(context) ((context)->uc_sigmask)
+#elif defined (__NetBSD__)
+# include <ucontext.h>
+
+# define EIP_sig(context) ((context)->uc_mcontext.__gregs[_REG_EIP])
+# define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
+# define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR])
+# define MASK_sig(context) ((context)->uc_sigmask)
+#elif defined (__FreeBSD__) || defined(__DragonFly__)
+# include <ucontext.h>
+
+# define EIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext.mc_eip))
+# define TRAP_sig(context) ((context)->uc_mcontext.mc_trapno)
+# define ERROR_sig(context) ((context)->uc_mcontext.mc_err)
+# define MASK_sig(context) ((context)->uc_sigmask)
+#elif defined(__OpenBSD__)
+# define EIP_sig(context) ((context)->sc_eip)
+# define TRAP_sig(context) ((context)->sc_trapno)
+# define ERROR_sig(context) ((context)->sc_err)
+# define MASK_sig(context) ((context)->sc_mask)
#else
# define EIP_sig(context) ((context)->uc_mcontext.gregs[REG_EIP])
# define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO])
# define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR])
+# define MASK_sig(context) ((context)->uc_sigmask)
#endif
int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
{
siginfo_t *info = pinfo;
+#if defined(__NetBSD__) || defined (__FreeBSD__) || defined(__DragonFly__)
+ ucontext_t *uc = puc;
+#elif defined(__OpenBSD__)
+ struct sigcontext *uc = puc;
+#else
struct ucontext *uc = puc;
+#endif
unsigned long pc;
int trapno;
@@ -1415,38 +1033,61 @@ int cpu_signal_handler(int host_signum, void *pinfo,
#define REG_ERR ERR
#define REG_TRAPNO TRAPNO
#endif
- pc = uc->uc_mcontext.gregs[REG_EIP];
- trapno = uc->uc_mcontext.gregs[REG_TRAPNO];
-#if defined(TARGET_I386) && defined(USE_CODE_COPY)
- if (trapno == 0x00 || trapno == 0x05) {
- /* send division by zero or bound exception */
- cpu_send_trap(pc, trapno, uc);
- return 1;
- } else
-#endif
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- trapno == 0xe ?
- (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
- &uc->uc_sigmask, puc);
+ pc = EIP_sig(uc);
+ trapno = TRAP_sig(uc);
+ return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+ trapno == 0xe ?
+ (ERROR_sig(uc) >> 1) & 1 : 0,
+ &MASK_sig(uc), puc);
}
#elif defined(__x86_64__)
+#ifdef __NetBSD__
+#define PC_sig(context) _UC_MACHINE_PC(context)
+#define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
+#define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR])
+#define MASK_sig(context) ((context)->uc_sigmask)
+#elif defined(__OpenBSD__)
+#define PC_sig(context) ((context)->sc_rip)
+#define TRAP_sig(context) ((context)->sc_trapno)
+#define ERROR_sig(context) ((context)->sc_err)
+#define MASK_sig(context) ((context)->sc_mask)
+#elif defined (__FreeBSD__) || defined(__DragonFly__)
+#include <ucontext.h>
+
+#define PC_sig(context) (*((unsigned long*)&(context)->uc_mcontext.mc_rip))
+#define TRAP_sig(context) ((context)->uc_mcontext.mc_trapno)
+#define ERROR_sig(context) ((context)->uc_mcontext.mc_err)
+#define MASK_sig(context) ((context)->uc_sigmask)
+#else
+#define PC_sig(context) ((context)->uc_mcontext.gregs[REG_RIP])
+#define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO])
+#define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR])
+#define MASK_sig(context) ((context)->uc_sigmask)
+#endif
+
int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
{
siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
unsigned long pc;
+#if defined(__NetBSD__) || defined (__FreeBSD__) || defined(__DragonFly__)
+ ucontext_t *uc = puc;
+#elif defined(__OpenBSD__)
+ struct sigcontext *uc = puc;
+#else
+ struct ucontext *uc = puc;
+#endif
- pc = uc->uc_mcontext.gregs[REG_RIP];
+ pc = PC_sig(uc);
return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?
- (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
- &uc->uc_sigmask, puc);
+ TRAP_sig(uc) == 0xe ?
+ (ERROR_sig(uc) >> 1) & 1 : 0,
+ &MASK_sig(uc), puc);
}
-#elif defined(__powerpc__)
+#elif defined(_ARCH_PPC)
/***********************************************************************
* signal context platform-specific definitions
@@ -1472,6 +1113,20 @@ int cpu_signal_handler(int host_signum, void *pinfo,
# define TRAP_sig(context) REG_sig(trap, context)
#endif /* linux */
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#include <ucontext.h>
+# define IAR_sig(context) ((context)->uc_mcontext.mc_srr0)
+# define MSR_sig(context) ((context)->uc_mcontext.mc_srr1)
+# define CTR_sig(context) ((context)->uc_mcontext.mc_ctr)
+# define XER_sig(context) ((context)->uc_mcontext.mc_xer)
+# define LR_sig(context) ((context)->uc_mcontext.mc_lr)
+# define CR_sig(context) ((context)->uc_mcontext.mc_cr)
+/* Exception Registers access */
+# define DAR_sig(context) ((context)->uc_mcontext.mc_dar)
+# define DSISR_sig(context) ((context)->uc_mcontext.mc_dsisr)
+# define TRAP_sig(context) ((context)->uc_mcontext.mc_exc)
+#endif /* __FreeBSD__|| __FreeBSD_kernel__ */
+
#ifdef __APPLE__
# include <sys/ucontext.h>
typedef struct ucontext SIGCONTEXT;
@@ -1501,7 +1156,11 @@ int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
{
siginfo_t *info = pinfo;
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ ucontext_t *uc = puc;
+#else
struct ucontext *uc = puc;
+#endif
unsigned long pc;
int is_write;
@@ -1555,26 +1214,49 @@ int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
{
siginfo_t *info = pinfo;
- uint32_t *regs = (uint32_t *)(info + 1);
- void *sigmask = (regs + 20);
- unsigned long pc;
int is_write;
uint32_t insn;
-
+#if !defined(__arch64__) || defined(CONFIG_SOLARIS)
+ uint32_t *regs = (uint32_t *)(info + 1);
+ void *sigmask = (regs + 20);
/* XXX: is there a standard glibc define ? */
- pc = regs[1];
+ unsigned long pc = regs[1];
+#else
+#ifdef __linux__
+ struct sigcontext *sc = puc;
+ unsigned long pc = sc->sigc_regs.tpc;
+ void *sigmask = (void *)sc->sigc_mask;
+#elif defined(__OpenBSD__)
+ struct sigcontext *uc = puc;
+ unsigned long pc = uc->sc_pc;
+ void *sigmask = (void *)(long)uc->sc_mask;
+#endif
+#endif
+
/* XXX: need kernel patch to get write flag faster */
is_write = 0;
insn = *(uint32_t *)pc;
if ((insn >> 30) == 3) {
switch((insn >> 19) & 0x3f) {
case 0x05: // stb
+ case 0x15: // stba
case 0x06: // sth
+ case 0x16: // stha
case 0x04: // st
+ case 0x14: // sta
case 0x07: // std
+ case 0x17: // stda
+ case 0x0e: // stx
+ case 0x1e: // stxa
case 0x24: // stf
+ case 0x34: // stfa
case 0x27: // stdf
+ case 0x37: // stdfa
+ case 0x26: // stqf
+ case 0x36: // stqfa
case 0x25: // stfsr
+ case 0x3c: // casa
+ case 0x3e: // casxa
is_write = 1;
break;
}
@@ -1593,7 +1275,11 @@ int cpu_signal_handler(int host_signum, void *pinfo,
unsigned long pc;
int is_write;
+#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
pc = uc->uc_mcontext.gregs[R15];
+#else
+ pc = uc->uc_mcontext.arm_pc;
+#endif
/* XXX: compute is_write */
is_write = 0;
return handle_cpu_signal(pc, (unsigned long)info->si_addr,
@@ -1650,7 +1336,7 @@ int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
}
return handle_cpu_signal(ip, (unsigned long)info->si_addr,
is_write,
- &uc->uc_sigmask, puc);
+ (sigset_t *)&uc->uc_sigmask, puc);
}
#elif defined(__s390__)
@@ -1661,14 +1347,107 @@ int cpu_signal_handler(int host_signum, void *pinfo,
siginfo_t *info = pinfo;
struct ucontext *uc = puc;
unsigned long pc;
- int is_write;
+ uint16_t *pinsn;
+ int is_write = 0;
pc = uc->uc_mcontext.psw.addr;
+
+ /* ??? On linux, the non-rt signal handler has 4 (!) arguments instead
+ of the normal 2 arguments. The 3rd argument contains the "int_code"
+ from the hardware which does in fact contain the is_write value.
+ The rt signal handler, as far as I can tell, does not give this value
+ at all. Not that we could get to it from here even if it were. */
+ /* ??? This is not even close to complete, since it ignores all
+ of the read-modify-write instructions. */
+ pinsn = (uint16_t *)pc;
+ switch (pinsn[0] >> 8) {
+ case 0x50: /* ST */
+ case 0x42: /* STC */
+ case 0x40: /* STH */
+ is_write = 1;
+ break;
+ case 0xc4: /* RIL format insns */
+ switch (pinsn[0] & 0xf) {
+ case 0xf: /* STRL */
+ case 0xb: /* STGRL */
+ case 0x7: /* STHRL */
+ is_write = 1;
+ }
+ break;
+ case 0xe3: /* RXY format insns */
+ switch (pinsn[2] & 0xff) {
+ case 0x50: /* STY */
+ case 0x24: /* STG */
+ case 0x72: /* STCY */
+ case 0x70: /* STHY */
+ case 0x8e: /* STPQ */
+ case 0x3f: /* STRVH */
+ case 0x3e: /* STRV */
+ case 0x2f: /* STRVG */
+ is_write = 1;
+ }
+ break;
+ }
+ return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+ is_write, &uc->uc_sigmask, puc);
+}
+
+#elif defined(__mips__)
+
+int cpu_signal_handler(int host_signum, void *pinfo,
+ void *puc)
+{
+ siginfo_t *info = pinfo;
+ struct ucontext *uc = puc;
+ greg_t pc = uc->uc_mcontext.pc;
+ int is_write;
+
/* XXX: compute is_write */
is_write = 0;
return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write,
- &uc->uc_sigmask, puc);
+ is_write, &uc->uc_sigmask, puc);
+}
+
+#elif defined(__hppa__)
+
+int cpu_signal_handler(int host_signum, void *pinfo,
+ void *puc)
+{
+ struct siginfo *info = pinfo;
+ struct ucontext *uc = puc;
+ unsigned long pc = uc->uc_mcontext.sc_iaoq[0];
+ uint32_t insn = *(uint32_t *)pc;
+ int is_write = 0;
+
+ /* XXX: need kernel patch to get write flag faster. */
+ switch (insn >> 26) {
+ case 0x1a: /* STW */
+ case 0x19: /* STH */
+ case 0x18: /* STB */
+ case 0x1b: /* STWM */
+ is_write = 1;
+ break;
+
+ case 0x09: /* CSTWX, FSTWX, FSTWS */
+ case 0x0b: /* CSTDX, FSTDX, FSTDS */
+ /* Distinguish from coprocessor load ... */
+ is_write = (insn >> 9) & 1;
+ break;
+
+ case 0x03:
+ switch ((insn >> 6) & 15) {
+ case 0xa: /* STWS */
+ case 0x9: /* STHS */
+ case 0x8: /* STBS */
+ case 0xe: /* STWAS */
+ case 0xc: /* STBYS */
+ is_write = 1;
+ }
+ break;
+ }
+
+ return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+ is_write, &uc->uc_sigmask, puc);
}
#else
diff --git a/src/recompiler/cutils.c b/src/recompiler/cutils.c
index 6448fb046..5fbf70bde 100644
--- a/src/recompiler/cutils.c
+++ b/src/recompiler/cutils.c
@@ -22,9 +22,11 @@
* THE SOFTWARE.
*/
#include "qemu-common.h"
+#include "host-utils.h"
#ifdef VBOX
-#include "osdep.h"
+# include "osdep.h"
+
static inline int toupper(int ch) {
if ( (unsigned int)(ch - 'a') < 26u )
@@ -513,7 +515,8 @@ qemu_qsort(
}
}
-#endif
+#endif /* VBOX */
+
void pstrcpy(char *buf, int buf_size, const char *str)
{
int c;
@@ -563,7 +566,7 @@ int stristart(const char *str, const char *val, const char **ptr)
p = str;
q = val;
while (*q != '\0') {
- if (toupper(*p) != toupper(*q))
+ if (qemu_toupper(*p) != qemu_toupper(*q))
return 0;
p++;
q++;
@@ -573,6 +576,19 @@ int stristart(const char *str, const char *val, const char **ptr)
return 1;
}
+/* XXX: use host strnlen if available ? */
+int qemu_strnlen(const char *s, int max_len)
+{
+ int i;
+
+ for(i = 0; i < max_len; i++) {
+ if (s[i] == '\0') {
+ break;
+ }
+ }
+ return i;
+}
+
#ifndef VBOX
time_t mktimegm(struct tm *tm)
{
@@ -587,4 +603,150 @@ time_t mktimegm(struct tm *tm)
t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
return t;
}
+#endif /* !VBOX */
+
+int qemu_fls(int i)
+{
+ return 32 - clz32(i);
+}
+
+#ifndef VBOX
+
+/*
+ * Make sure data goes on disk, but if possible do not bother to
+ * write out the inode just for timestamp updates.
+ *
+ * Unfortunately even in 2009 many operating systems do not support
+ * fdatasync and have to fall back to fsync.
+ */
+int qemu_fdatasync(int fd)
+{
+#ifdef CONFIG_FDATASYNC
+ return fdatasync(fd);
+#else
+ return fsync(fd);
#endif
+}
+
+/* io vectors */
+
+void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint)
+{
+ qiov->iov = qemu_malloc(alloc_hint * sizeof(struct iovec));
+ qiov->niov = 0;
+ qiov->nalloc = alloc_hint;
+ qiov->size = 0;
+}
+
+void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov)
+{
+ int i;
+
+ qiov->iov = iov;
+ qiov->niov = niov;
+ qiov->nalloc = -1;
+ qiov->size = 0;
+ for (i = 0; i < niov; i++)
+ qiov->size += iov[i].iov_len;
+}
+
+void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)
+{
+ assert(qiov->nalloc != -1);
+
+ if (qiov->niov == qiov->nalloc) {
+ qiov->nalloc = 2 * qiov->nalloc + 1;
+ qiov->iov = qemu_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec));
+ }
+ qiov->iov[qiov->niov].iov_base = base;
+ qiov->iov[qiov->niov].iov_len = len;
+ qiov->size += len;
+ ++qiov->niov;
+}
+
+/*
+ * Copies iovecs from src to the end dst until src is completely copied or the
+ * total size of the copied iovec reaches size. The size of the last copied
+ * iovec is changed in order to fit the specified total size if it isn't a
+ * perfect fit already.
+ */
+void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size)
+{
+ int i;
+ size_t done;
+
+ assert(dst->nalloc != -1);
+
+ done = 0;
+ for (i = 0; (i < src->niov) && (done != size); i++) {
+ if (done + src->iov[i].iov_len > size) {
+ qemu_iovec_add(dst, src->iov[i].iov_base, size - done);
+ break;
+ } else {
+ qemu_iovec_add(dst, src->iov[i].iov_base, src->iov[i].iov_len);
+ }
+ done += src->iov[i].iov_len;
+ }
+}
+
+void qemu_iovec_destroy(QEMUIOVector *qiov)
+{
+ assert(qiov->nalloc != -1);
+
+ qemu_free(qiov->iov);
+}
+
+void qemu_iovec_reset(QEMUIOVector *qiov)
+{
+ assert(qiov->nalloc != -1);
+
+ qiov->niov = 0;
+ qiov->size = 0;
+}
+
+void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf)
+{
+ uint8_t *p = (uint8_t *)buf;
+ int i;
+
+ for (i = 0; i < qiov->niov; ++i) {
+ memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
+ p += qiov->iov[i].iov_len;
+ }
+}
+
+void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count)
+{
+ const uint8_t *p = (const uint8_t *)buf;
+ size_t copy;
+ int i;
+
+ for (i = 0; i < qiov->niov && count; ++i) {
+ copy = count;
+ if (copy > qiov->iov[i].iov_len)
+ copy = qiov->iov[i].iov_len;
+ memcpy(qiov->iov[i].iov_base, p, copy);
+ p += copy;
+ count -= copy;
+ }
+}
+
+#ifndef _WIN32
+/* Sets a specific flag */
+int fcntl_setfl(int fd, int flag)
+{
+ int flags;
+
+ flags = fcntl(fd, F_GETFL);
+ if (flags == -1)
+ return -errno;
+
+ if (fcntl(fd, F_SETFL, flags | flag) == -1)
+ return -errno;
+
+ return 0;
+}
+#endif
+
+#endif /* !VBOX */
+
diff --git a/src/recompiler/def-helper.h b/src/recompiler/def-helper.h
new file mode 100644
index 000000000..ad5b94591
--- /dev/null
+++ b/src/recompiler/def-helper.h
@@ -0,0 +1,258 @@
+/* Helper file for declaring TCG helper functions.
+ Should be included at the start and end of target-foo/helper.h.
+
+ Targets should use DEF_HELPER_N and DEF_HELPER_FLAGS_N to declare helper
+ functions. Names should be specified without the helper_ prefix, and
+ the return and argument types specified. 3 basic types are understood
+ (i32, i64 and ptr). Additional aliases are provided for convenience and
+ to match the types used by the C helper implementation.
+
+ The target helper.h should be included in all files that use/define
+ helper functions. THis will ensure that function prototypes are
+ consistent. In addition it should be included an extra two times for
+ helper.c, defining:
+ GEN_HELPER 1 to produce op generation functions (gen_helper_*)
+ GEN_HELPER 2 to do runtime registration helper functions.
+ */
+
+#ifndef DEF_HELPER_H
+#define DEF_HELPER_H 1
+
+#define HELPER(name) glue(helper_, name)
+
+#define GET_TCGV_i32 GET_TCGV_I32
+#define GET_TCGV_i64 GET_TCGV_I64
+#define GET_TCGV_ptr GET_TCGV_PTR
+
+/* Some types that make sense in C, but not for TCG. */
+#define dh_alias_i32 i32
+#define dh_alias_s32 i32
+#define dh_alias_int i32
+#define dh_alias_i64 i64
+#define dh_alias_s64 i64
+#define dh_alias_f32 i32
+#define dh_alias_f64 i64
+#if TARGET_LONG_BITS == 32
+#define dh_alias_tl i32
+#else
+#define dh_alias_tl i64
+#endif
+#define dh_alias_ptr ptr
+#define dh_alias_void void
+#define dh_alias_env ptr
+#ifdef VBOX
+# if ARCH_BITS == 32
+# define dh_alias_RTCCUINTREG i32
+# define dh_alias_RTCCINTREG i32
+# else
+# define dh_alias_RTCCUINTREG i64
+# define dh_alias_RTCCINTREG i64
+# endif
+#endif
+#define dh_alias(t) glue(dh_alias_, t)
+
+#define dh_ctype_i32 uint32_t
+#define dh_ctype_s32 int32_t
+#define dh_ctype_int int
+#define dh_ctype_i64 uint64_t
+#define dh_ctype_s64 int64_t
+#define dh_ctype_f32 float32
+#define dh_ctype_f64 float64
+#define dh_ctype_tl target_ulong
+#define dh_ctype_ptr void *
+#define dh_ctype_void void
+#define dh_ctype_env CPUState *
+#ifdef VBOX
+# if ARCH_BITS == 32
+# define dh_ctype_RTCCUINTREG uint32_t
+# define dh_ctype_RTCCINTREG int32_t
+# else
+# define dh_ctype_RTCCUINTREG uint64_t
+# define dh_ctype_RTCCINTREG int64_t
+# endif
+#endif
+#define dh_ctype(t) dh_ctype_##t
+
+/* We can't use glue() here because it falls foul of C preprocessor
+ recursive expansion rules. */
+#define dh_retvar_decl0_void void
+#define dh_retvar_decl0_i32 TCGv_i32 retval
+#define dh_retvar_decl0_i64 TCGv_i64 retval
+#define dh_retvar_decl0_ptr TCGv_ptr retval
+#define dh_retvar_decl0(t) glue(dh_retvar_decl0_, dh_alias(t))
+
+#define dh_retvar_decl_void
+#define dh_retvar_decl_i32 TCGv_i32 retval,
+#define dh_retvar_decl_i64 TCGv_i64 retval,
+#define dh_retvar_decl_ptr TCGv_ptr retval,
+#define dh_retvar_decl(t) glue(dh_retvar_decl_, dh_alias(t))
+
+#define dh_retvar_void TCG_CALL_DUMMY_ARG
+#define dh_retvar_i32 GET_TCGV_i32(retval)
+#define dh_retvar_i64 GET_TCGV_i64(retval)
+#define dh_retvar_ptr GET_TCGV_ptr(retval)
+#define dh_retvar(t) glue(dh_retvar_, dh_alias(t))
+
+#define dh_is_64bit_void 0
+#define dh_is_64bit_i32 0
+#define dh_is_64bit_i64 1
+#define dh_is_64bit_ptr (TCG_TARGET_REG_BITS == 64)
+#define dh_is_64bit(t) glue(dh_is_64bit_, dh_alias(t))
+
+#define dh_is_signed_void 0
+#define dh_is_signed_i32 0
+#define dh_is_signed_s32 1
+#define dh_is_signed_i64 0
+#define dh_is_signed_s64 1
+#define dh_is_signed_f32 0
+#define dh_is_signed_f64 0
+#define dh_is_signed_tl 0
+#define dh_is_signed_int 1
+/* ??? This is highly specific to the host cpu. There are even special
+ extension instructions that may be required, e.g. ia64's addp4. But
+ for now we don't support any 64-bit targets with 32-bit pointers. */
+#define dh_is_signed_ptr 0
+#define dh_is_signed_env dh_is_signed_ptr
+#define dh_is_signed(t) dh_is_signed_##t
+
+#define dh_sizemask(t, n) \
+ sizemask |= dh_is_64bit(t) << (n*2); \
+ sizemask |= dh_is_signed(t) << (n*2+1)
+
+#define dh_arg(t, n) \
+ args[n - 1] = glue(GET_TCGV_, dh_alias(t))(glue(arg, n)); \
+ dh_sizemask(t, n)
+
+#define dh_arg_decl(t, n) glue(TCGv_, dh_alias(t)) glue(arg, n)
+
+
+#define DEF_HELPER_0(name, ret) \
+ DEF_HELPER_FLAGS_0(name, 0, ret)
+#define DEF_HELPER_1(name, ret, t1) \
+ DEF_HELPER_FLAGS_1(name, 0, ret, t1)
+#define DEF_HELPER_2(name, ret, t1, t2) \
+ DEF_HELPER_FLAGS_2(name, 0, ret, t1, t2)
+#define DEF_HELPER_3(name, ret, t1, t2, t3) \
+ DEF_HELPER_FLAGS_3(name, 0, ret, t1, t2, t3)
+#define DEF_HELPER_4(name, ret, t1, t2, t3, t4) \
+ DEF_HELPER_FLAGS_4(name, 0, ret, t1, t2, t3, t4)
+
+#endif /* DEF_HELPER_H */
+
+#ifndef GEN_HELPER
+/* Function prototypes. */
+
+#define DEF_HELPER_FLAGS_0(name, flags, ret) \
+dh_ctype(ret) HELPER(name) (void);
+
+#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
+dh_ctype(ret) HELPER(name) (dh_ctype(t1));
+
+#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
+
+#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3));
+
+#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
+ dh_ctype(t4));
+
+#undef GEN_HELPER
+#define GEN_HELPER -1
+
+#elif GEN_HELPER == 1
+/* Gen functions. */
+
+#define DEF_HELPER_FLAGS_0(name, flags, ret) \
+static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
+{ \
+ int sizemask; \
+ sizemask = dh_is_64bit(ret); \
+ tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 0, NULL); \
+}
+
+#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1)) \
+{ \
+ TCGArg args[1]; \
+ int sizemask = 0; \
+ dh_sizemask(ret, 0); \
+ dh_arg(t1, 1); \
+ tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 1, args); \
+}
+
+#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
+ dh_arg_decl(t2, 2)) \
+{ \
+ TCGArg args[2]; \
+ int sizemask = 0; \
+ dh_sizemask(ret, 0); \
+ dh_arg(t1, 1); \
+ dh_arg(t2, 2); \
+ tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 2, args); \
+}
+
+#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
+ dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
+{ \
+ TCGArg args[3]; \
+ int sizemask = 0; \
+ dh_sizemask(ret, 0); \
+ dh_arg(t1, 1); \
+ dh_arg(t2, 2); \
+ dh_arg(t3, 3); \
+ tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 3, args); \
+}
+
+#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
+ dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
+{ \
+ TCGArg args[4]; \
+ int sizemask = 0; \
+ dh_sizemask(ret, 0); \
+ dh_arg(t1, 1); \
+ dh_arg(t2, 2); \
+ dh_arg(t3, 3); \
+ dh_arg(t4, 4); \
+ tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 4, args); \
+}
+
+#undef GEN_HELPER
+#define GEN_HELPER -1
+
+#elif GEN_HELPER == 2
+/* Register helpers. */
+
+#define DEF_HELPER_FLAGS_0(name, flags, ret) \
+tcg_register_helper(HELPER(name), #name);
+
+#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
+DEF_HELPER_FLAGS_0(name, flags, ret)
+
+#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
+DEF_HELPER_FLAGS_0(name, flags, ret)
+
+#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
+DEF_HELPER_FLAGS_0(name, flags, ret)
+
+#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
+DEF_HELPER_FLAGS_0(name, flags, ret)
+
+#undef GEN_HELPER
+#define GEN_HELPER -1
+
+#elif GEN_HELPER == -1
+/* Undefine macros. */
+
+#undef DEF_HELPER_FLAGS_0
+#undef DEF_HELPER_FLAGS_1
+#undef DEF_HELPER_FLAGS_2
+#undef DEF_HELPER_FLAGS_3
+#undef DEF_HELPER_FLAGS_4
+#undef GEN_HELPER
+
+#endif
diff --git a/src/recompiler/disas.h b/src/recompiler/disas.h
index ee0a79c25..a20df1278 100644
--- a/src/recompiler/disas.h
+++ b/src/recompiler/disas.h
@@ -1,21 +1,47 @@
#ifndef _QEMU_DISAS_H
#define _QEMU_DISAS_H
+#include "qemu-common.h"
+
+#ifdef NEED_CPU_H
/* Disassemble this for me please... (debugging). */
void disas(FILE *out, void *code, unsigned long size);
void target_disas(FILE *out, target_ulong code, target_ulong size, int flags);
-void monitor_disas(CPUState *env,
+
+#ifndef VBOX
+/* The usual mess... FIXME: Remove this condition once dyngen-exec.h is gone */
+#ifndef __DYNGEN_EXEC_H__
+void monitor_disas(Monitor *mon, CPUState *env,
target_ulong pc, int nb_insn, int is_physical, int flags);
+#endif
+#endif /*!VBOX*/
/* Look up symbol for debugging purpose. Returns "" if unknown. */
const char *lookup_symbol(target_ulong orig_addr);
+#endif
-/* Filled in by elfload.c. Simplistic, but will do for now. */
-extern struct syminfo {
+struct syminfo;
+struct elf32_sym;
+struct elf64_sym;
+
+#if defined(CONFIG_USER_ONLY)
+typedef const char *(*lookup_symbol_t)(struct syminfo *s, target_ulong orig_addr);
+#else
+typedef const char *(*lookup_symbol_t)(struct syminfo *s, target_phys_addr_t orig_addr);
+#endif
+
+struct syminfo {
+ lookup_symbol_t lookup_symbol;
unsigned int disas_num_syms;
- void *disas_symtab;
+ union {
+ struct elf32_sym *elf32;
+ struct elf64_sym *elf64;
+ } disas_symtab;
const char *disas_strtab;
struct syminfo *next;
-} *syminfos;
+};
+
+/* Filled in by elfload.c. Simplistic, but will do for now. */
+extern struct syminfo *syminfos;
#endif /* _QEMU_DISAS_H */
diff --git a/src/recompiler/dyngen-exec.h b/src/recompiler/dyngen-exec.h
index a2ba077c5..4bb2e09a3 100644
--- a/src/recompiler/dyngen-exec.h
+++ b/src/recompiler/dyngen-exec.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -43,56 +42,17 @@
point because host CPU registers are used as global variables. Some
host headers do not allow that. */
#include <stddef.h>
-
#ifndef VBOX
+#include <stdint.h>
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int uint32_t;
-/* Linux/Sparc64 defines uint64_t */
-#if !(defined (__sparc_v9__) && defined(__linux__))
-/* XXX may be done for all 64 bits targets ? */
-#if defined (__x86_64__) || defined(__ia64)
-typedef unsigned long uint64_t;
-#else
-typedef unsigned long long uint64_t;
-#endif
-#endif
-
-/* if Solaris/__sun__, don't typedef int8_t, as it will be typedef'd
- prior to this and will cause an error in compilation, conflicting
- with /usr/include/sys/int_types.h, line 75 */
-#ifndef __sun__
-typedef signed char int8_t;
-#endif
-typedef signed short int16_t;
-typedef signed int int32_t;
-// Linux/Sparc64 defines int64_t
-#if !(defined (__sparc_v9__) && defined(__linux__))
-#if defined (__x86_64__) || defined(__ia64)
-typedef signed long int64_t;
-#else
-typedef signed long long int64_t;
-#endif
+#ifdef __OpenBSD__
+#include <sys/types.h>
#endif
/* XXX: This may be wrong for 64-bit ILP32 hosts. */
typedef void * host_reg_t;
-#define INT8_MIN (-128)
-#define INT16_MIN (-32767-1)
-#define INT32_MIN (-2147483647-1)
-#define INT64_MIN (-(int64_t)(9223372036854775807)-1)
-#define INT8_MAX (127)
-#define INT16_MAX (32767)
-#define INT32_MAX (2147483647)
-#define INT64_MAX ((int64_t)(9223372036854775807))
-#define UINT8_MAX (255)
-#define UINT16_MAX (65535)
-#define UINT32_MAX (4294967295U)
-#define UINT64_MAX ((uint64_t)(18446744073709551615))
-
-#ifdef _BSD
+#ifdef CONFIG_BSD
typedef struct __sFILE FILE;
#else
typedef struct FILE FILE;
@@ -100,8 +60,6 @@ typedef struct FILE FILE;
extern int fprintf(FILE *, const char *, ...);
extern int fputs(const char *, FILE *);
extern int printf(const char *, ...);
-#undef NULL
-#define NULL 0
#else /* VBOX */
@@ -113,125 +71,44 @@ typedef void * host_reg_t;
#endif /* VBOX */
-#ifdef __i386__
-#ifndef VBOX
+#if defined(__i386__)
+# ifndef VBOX
#define AREG0 "ebp"
-#define AREG1 "ebx"
-#define AREG2 "esi"
-#define AREG3 "edi"
-#else
-#define AREG0 "esi"
-#define AREG1 "edi"
-#endif
-#endif
-#ifdef __x86_64__
-#if defined(VBOX)
-/* Must be in sync with TCG register notion, see tcg-target.h */
-#endif
+# else /* VBOX - why are we different? frame-pointer optimizations on mac? */
+# define AREG0 "esi"
+# endif /* VBOX */
+#elif defined(__x86_64__)
#define AREG0 "r14"
-#define AREG1 "r15"
-#define AREG2 "r12"
-#define AREG3 "r13"
-#endif
-#ifdef __powerpc__
+#elif defined(_ARCH_PPC)
#define AREG0 "r27"
-#define AREG1 "r24"
-#define AREG2 "r25"
-#define AREG3 "r26"
-/* XXX: suppress this hack */
-#if defined(CONFIG_USER_ONLY)
-#define AREG4 "r16"
-#define AREG5 "r17"
-#define AREG6 "r18"
-#define AREG7 "r19"
-#define AREG8 "r20"
-#define AREG9 "r21"
-#define AREG10 "r22"
-#define AREG11 "r23"
-#endif
-#define USE_INT_TO_FLOAT_HELPERS
-#define BUGGY_GCC_DIV64
-#endif
-#ifdef __arm__
+#elif defined(__arm__)
#define AREG0 "r7"
-#define AREG1 "r4"
-#define AREG2 "r5"
-#define AREG3 "r6"
-#endif
-#ifdef __mips__
-#define AREG0 "s3"
-#define AREG1 "s0"
-#define AREG2 "s1"
-#define AREG3 "s2"
-#endif
-#ifdef __sparc__
-#ifdef HOST_SOLARIS
+#elif defined(__hppa__)
+#define AREG0 "r17"
+#elif defined(__mips__)
+#define AREG0 "s0"
+#elif defined(__sparc__)
+#ifdef CONFIG_SOLARIS
#define AREG0 "g2"
-#define AREG1 "g3"
-#define AREG2 "g4"
-#define AREG3 "g5"
-#define AREG4 "g6"
#else
#ifdef __sparc_v9__
-#define AREG0 "g1"
-#define AREG1 "g4"
-#define AREG2 "g5"
-#define AREG3 "g7"
+#define AREG0 "g5"
#else
#define AREG0 "g6"
-#define AREG1 "g1"
-#define AREG2 "g2"
-#define AREG3 "g3"
-#define AREG4 "l0"
-#define AREG5 "l1"
-#define AREG6 "l2"
-#define AREG7 "l3"
-#define AREG8 "l4"
-#define AREG9 "l5"
-#define AREG10 "l6"
-#define AREG11 "l7"
#endif
#endif
-#define USE_FP_CONVERT
-#endif
-#ifdef __s390__
+#elif defined(__s390__)
#define AREG0 "r10"
-#define AREG1 "r7"
-#define AREG2 "r8"
-#define AREG3 "r9"
-#endif
-#ifdef __alpha__
+#elif defined(__alpha__)
/* Note $15 is the frame pointer, so anything in op-i386.c that would
require a frame pointer, like alloca, would probably loose. */
#define AREG0 "$15"
-#define AREG1 "$9"
-#define AREG2 "$10"
-#define AREG3 "$11"
-#define AREG4 "$12"
-#define AREG5 "$13"
-#define AREG6 "$14"
-#endif
-#ifdef __mc68000
+#elif defined(__mc68000)
#define AREG0 "%a5"
-#define AREG1 "%a4"
-#define AREG2 "%d7"
-#define AREG3 "%d6"
-#define AREG4 "%d5"
-#endif
-#ifdef __ia64__
+#elif defined(__ia64__)
#define AREG0 "r7"
-#define AREG1 "r4"
-#define AREG2 "r5"
-#define AREG3 "r6"
-#endif
-
-#ifndef VBOX
-/* force GCC to generate only one epilog at the end of the function */
-#define FORCE_RET() __asm__ __volatile__("" : : : "memory");
-#endif
-
-#ifndef OPPROTO
-#define OPPROTO
+#else
+#error unsupported CPU
#endif
#define xglue(x, y) x ## y
@@ -239,49 +116,9 @@ typedef void * host_reg_t;
#define stringify(s) tostring(s)
#define tostring(s) #s
-#if defined(__alpha__) || defined(__s390__)
-/* the symbols are considered non exported so a br immediate is generated */
-#define __hidden __attribute__((visibility("hidden")))
-#else
-#define __hidden
-#endif
-
-#if defined(__alpha__)
-/* Suggested by Richard Henderson. This will result in code like
- ldah $0,__op_param1($29) !gprelhigh
- lda $0,__op_param1($0) !gprellow
- We can then conveniently change $29 to $31 and adapt the offsets to
- emit the appropriate constant. */
-extern int __op_param1 __hidden;
-extern int __op_param2 __hidden;
-extern int __op_param3 __hidden;
-#define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; })
-#define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; })
-#define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; })
-#else
-#if defined(__APPLE__)
-static int __op_param1, __op_param2, __op_param3;
-#else
-extern int __op_param1, __op_param2, __op_param3;
-#endif
-#define PARAM1 ((long)(&__op_param1))
-#define PARAM2 ((long)(&__op_param2))
-#define PARAM3 ((long)(&__op_param3))
-#endif /* !defined(__alpha__) */
-
-extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
-
-#if defined(_WIN32) || defined(__APPLE__) || defined(__OS2__)
-#define ASM_NAME(x) "_" #x
-#else
-#define ASM_NAME(x) #x
-#endif
-
-#ifdef VBOX
-#define GETPC() ASMReturnAddress()
-#elif defined(__s390__)
/* The return address may point to the start of the next instruction.
Subtracting one gets us the call instruction itself. */
+#if defined(__s390__) && !defined(__s390x__)
# define GETPC() ((void*)(((unsigned long)__builtin_return_address(0) & 0x7fffffffUL) - 1))
#elif defined(__arm__)
/* Thumb return addresses have the low bit set, so we need to subtract two.
@@ -290,4 +127,5 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
#else
# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 1))
#endif
+
#endif /* !defined(__DYNGEN_EXEC_H__) */
diff --git a/src/recompiler/elf.h b/src/recompiler/elf.h
index daf93991e..eb9e3bece 100644
--- a/src/recompiler/elf.h
+++ b/src/recompiler/elf.h
@@ -1,6 +1,8 @@
#ifndef _QEMU_ELF_H
#define _QEMU_ELF_H
+#include <inttypes.h>
+
/* 32-bit ELF base types. */
typedef uint32_t Elf32_Addr;
typedef uint16_t Elf32_Half;
@@ -117,6 +119,9 @@ typedef int64_t Elf64_Sxword;
*/
#define EM_S390_OLD 0xA390
+#define EM_MICROBLAZE 189
+#define EM_MICROBLAZE_OLD 0xBAAB
+
/* This is the info that is needed to parse the dynamic section of the file */
#define DT_NULL 0
#define DT_NEEDED 1
@@ -239,6 +244,8 @@ typedef struct {
#define R_386_GOTOFF 9
#define R_386_GOTPC 10
#define R_386_NUM 11
+/* Not a dynamic reloc, so not included in R_386_NUM. Used in TCG. */
+#define R_386_PC8 23
#define R_MIPS_NONE 0
#define R_MIPS_16 1
@@ -326,6 +333,9 @@ typedef struct {
#define R_SPARC_11 31
#define R_SPARC_64 32
#define R_SPARC_OLO10 33
+#define R_SPARC_HH22 34
+#define R_SPARC_HM10 35
+#define R_SPARC_LM22 36
#define R_SPARC_WDISP16 40
#define R_SPARC_WDISP19 41
#define R_SPARC_7 43
@@ -447,7 +457,9 @@ typedef struct {
#define R_PPC_SECTOFF_HI 35
#define R_PPC_SECTOFF_HA 36
/* Keep this the last entry. */
+#ifndef R_PPC_NUM
#define R_PPC_NUM 37
+#endif
/* ARM specific declarations */
@@ -638,9 +650,9 @@ typedef struct {
#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */
#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */
-/* Additional section indices. */
+/* Additional section indeces. */
-#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tentatively declared
+#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared
symbols in ANSI C. */
#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */
@@ -1074,7 +1086,23 @@ typedef struct elf64_shdr {
#define EI_CLASS 4
#define EI_DATA 5
#define EI_VERSION 6
-#define EI_PAD 7
+#define EI_OSABI 7
+#define EI_PAD 8
+
+#define ELFOSABI_NONE 0 /* UNIX System V ABI */
+#define ELFOSABI_SYSV 0 /* Alias. */
+#define ELFOSABI_HPUX 1 /* HP-UX */
+#define ELFOSABI_NETBSD 2 /* NetBSD. */
+#define ELFOSABI_LINUX 3 /* Linux. */
+#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
+#define ELFOSABI_AIX 7 /* IBM AIX. */
+#define ELFOSABI_IRIX 8 /* SGI Irix. */
+#define ELFOSABI_FREEBSD 9 /* FreeBSD. */
+#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
+#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
+#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
+#define ELFOSABI_ARM 97 /* ARM */
+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
#define ELFMAG0 0x7f /* EI_MAG */
#define ELFMAG1 'E'
@@ -1101,6 +1129,7 @@ typedef struct elf64_shdr {
#define NT_PRFPREG 2
#define NT_PRPSINFO 3
#define NT_TASKSTRUCT 4
+#define NT_AUXV 6
#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
@@ -1118,6 +1147,7 @@ typedef struct elf64_note {
Elf64_Word n_type; /* Content type */
} Elf64_Nhdr;
+#ifdef ELF_CLASS
#if ELF_CLASS == ELFCLASS32
#define elfhdr elf32_hdr
@@ -1125,6 +1155,7 @@ typedef struct elf64_note {
#define elf_note elf32_note
#define elf_shdr elf32_shdr
#define elf_sym elf32_sym
+#define elf_addr_t Elf32_Off
#ifdef ELF_USES_RELOCA
# define ELF_RELOC Elf32_Rela
@@ -1139,6 +1170,7 @@ typedef struct elf64_note {
#define elf_note elf64_note
#define elf_shdr elf64_shdr
#define elf_sym elf64_sym
+#define elf_addr_t Elf64_Off
#ifdef ELF_USES_RELOCA
# define ELF_RELOC Elf64_Rela
@@ -1158,5 +1190,7 @@ typedef struct elf64_note {
# endif
#endif
+#endif /* ELF_CLASS */
+
#endif /* _QEMU_ELF_H */
diff --git a/src/recompiler/exec-all.h b/src/recompiler/exec-all.h
index 5e3af3382..c8e4db05d 100644
--- a/src/recompiler/exec-all.h
+++ b/src/recompiler/exec-all.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -27,14 +26,14 @@
* of the LGPL is applied is otherwise unspecified.
*/
-/* allow to see translation results - the slowdown should be negligible, so we leave it */
-#ifndef VBOX
-#define DEBUG_DISAS
-#endif
+#ifndef _EXEC_ALL_H_
+#define _EXEC_ALL_H_
+#include "qemu-common.h"
#ifdef VBOX
# include <VBox/vmm/tm.h>
# include <VBox/vmm/pgm.h> /* PGM_DYNAMIC_RAM_ALLOC */
+# include <VBox/vmm/em.h> /* EMRemIsLockOwner */
# ifndef LOG_GROUP
# define LOG_GROUP LOG_GROUP_REM
# endif
@@ -43,6 +42,20 @@
# include <VBox/vmm/vm.h>
#endif /* VBOX */
+/* allow to see translation results - the slowdown should be negligible, so we leave it */
+#ifndef VBOX
+#define DEBUG_DISAS
+#endif /* !VBOX */
+
+/* Page tracking code uses ram addresses in system mode, and virtual
+ addresses in userspace mode. Define tb_page_addr_t to be an appropriate
+ type. */
+#if defined(CONFIG_USER_ONLY)
+typedef abi_ulong tb_page_addr_t;
+#else
+typedef ram_addr_t tb_page_addr_t;
+#endif
+
/* is_jmp field values */
#define DISAS_NEXT 0 /* next instruction can be analyzed */
#define DISAS_JUMP 1 /* only pc was modified dynamically */
@@ -52,32 +65,35 @@
typedef struct TranslationBlock TranslationBlock;
/* XXX: make safe guess about sizes */
-#define MAX_OP_PER_INSTR 64
-/* A Call op needs up to 6 + 2N parameters (N = number of arguments). */
-#define MAX_OPC_PARAM 10
-#define OPC_BUF_SIZE 512
+#define MAX_OP_PER_INSTR 96
+
+#if HOST_LONG_BITS == 32
+#define MAX_OPC_PARAM_PER_ARG 2
+#else
+#define MAX_OPC_PARAM_PER_ARG 1
+#endif
+#define MAX_OPC_PARAM_IARGS 4
+#define MAX_OPC_PARAM_OARGS 1
+#define MAX_OPC_PARAM_ARGS (MAX_OPC_PARAM_IARGS + MAX_OPC_PARAM_OARGS)
+
+/* A Call op needs up to 4 + 2N parameters on 32-bit archs,
+ * and up to 4 + N parameters on 64-bit archs
+ * (N = number of input arguments + output arguments). */
+#define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS))
+#define OPC_BUF_SIZE 640
#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
/* Maximum size a TCG op can expand to. This is complicated because a
single op may require several host instructions and register reloads.
- For now take a wild guess at 128 bytes, which should allow at least
+ For now take a wild guess at 192 bytes, which should allow at least
a couple of fixup instructions per argument. */
-#define TCG_MAX_OP_SIZE 128
+#define TCG_MAX_OP_SIZE 192
#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM)
extern target_ulong gen_opc_pc[OPC_BUF_SIZE];
-extern target_ulong gen_opc_npc[OPC_BUF_SIZE];
-extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
extern uint16_t gen_opc_icount[OPC_BUF_SIZE];
-extern target_ulong gen_opc_jump_pc[2];
-extern uint32_t gen_opc_hflags[OPC_BUF_SIZE];
-
-typedef void (GenOpFunc)(void);
-typedef void (GenOpFunc1)(long);
-typedef void (GenOpFunc2)(long, long);
-typedef void (GenOpFunc3)(long, long, long);
#include "qemu-log.h"
@@ -86,45 +102,30 @@ void gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
unsigned long searched_pc, int pc_pos, void *puc);
-unsigned long code_gen_max_block_size(void);
void cpu_gen_init(void);
int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
int *gen_code_size_ptr);
int cpu_restore_state(struct TranslationBlock *tb,
CPUState *env, unsigned long searched_pc,
void *puc);
-int cpu_restore_state_copy(struct TranslationBlock *tb,
- CPUState *env, unsigned long searched_pc,
- void *puc);
void cpu_resume_from_signal(CPUState *env1, void *puc);
void cpu_io_recompile(CPUState *env, void *retaddr);
TranslationBlock *tb_gen_code(CPUState *env,
target_ulong pc, target_ulong cs_base, int flags,
int cflags);
void cpu_exec_init(CPUState *env);
+void QEMU_NORETURN cpu_loop_exit(void);
int page_unprotect(target_ulong address, unsigned long pc, void *puc);
-void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end,
+void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
int is_cpu_write_access);
void tb_invalidate_page_range(target_ulong start, target_ulong end);
void tlb_flush_page(CPUState *env, target_ulong addr);
void tlb_flush(CPUState *env, int flush_global);
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int mmu_idx, int is_softmmu);
-#ifndef VBOX
-static inline int tlb_set_page(CPUState *env1, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int mmu_idx, int is_softmmu)
-#else
-DECLINLINE(int) tlb_set_page(CPUState *env1, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int mmu_idx, int is_softmmu)
+#if !defined(CONFIG_USER_ONLY)
+void tlb_set_page(CPUState *env, target_ulong vaddr,
+ target_phys_addr_t paddr, int prot,
+ int mmu_idx, target_ulong size);
#endif
-{
- if (prot & PAGE_READ)
- prot |= PAGE_EXEC;
- return tlb_set_page_exec(env1, vaddr, paddr, prot, mmu_idx, is_softmmu);
-}
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
@@ -142,15 +143,12 @@ DECLINLINE(int) tlb_set_page(CPUState *env1, target_ulong vaddr,
#define CODE_GEN_AVG_BLOCK_SIZE 64
#endif
-#if defined(__powerpc__) || defined(__x86_64__) || defined(__arm__)
-#define USE_DIRECT_JUMP
-#endif
-#if defined(__i386__) && !defined(_WIN32)
+#if defined(_ARCH_PPC) || defined(__x86_64__) || defined(__arm__) || defined(__i386__)
#define USE_DIRECT_JUMP
#endif
#ifdef VBOX /* bird: not safe in next step because of threading & cpu_interrupt. */
-#undef USE_DIRECT_JUMP
+# undef USE_DIRECT_JUMP
#endif /* VBOX */
struct TranslationBlock {
@@ -162,9 +160,8 @@ struct TranslationBlock {
uint16_t cflags; /* compile flags */
#define CF_COUNT_MASK 0x7fff
#define CF_LAST_IO 0x8000 /* Last insn may be an IO access. */
-
#ifdef VBOX
-#define CF_RAW_MODE 0x0010 /* block was generated in raw mode */
+# define CF_RAW_MODE 0x0010 /* block was generated in raw mode */
#endif
uint8_t *tc_ptr; /* pointer to the translated code */
@@ -173,13 +170,13 @@ struct TranslationBlock {
/* first and second physical page containing code. The lower bit
of the pointer tells the index in page_next[] */
struct TranslationBlock *page_next[2];
- target_ulong page_addr[2];
+ tb_page_addr_t page_addr[2];
/* the following data are used to directly call another TB from
the code of this one. */
uint16_t tb_next_offset[2]; /* offset of original jump target */
#ifdef USE_DIRECT_JUMP
- uint16_t tb_jmp_offset[4]; /* offset of jump instruction */
+ uint16_t tb_jmp_offset[2]; /* offset of jump instruction */
#else
unsigned long tb_next[2]; /* address of jump generated code */
#endif
@@ -192,35 +189,22 @@ struct TranslationBlock {
uint32_t icount;
};
-#ifndef VBOX
static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
-#else
-DECLINLINE(unsigned int) tb_jmp_cache_hash_page(target_ulong pc)
-#endif
{
target_ulong tmp;
tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
- return (tmp >> TB_JMP_PAGE_BITS) & TB_JMP_PAGE_MASK;
+ return (tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK;
}
-#ifndef VBOX
static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
-#else
-DECLINLINE(unsigned int) tb_jmp_cache_hash_func(target_ulong pc)
-#endif
-
{
target_ulong tmp;
tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
- return (((tmp >> TB_JMP_PAGE_BITS) & TB_JMP_PAGE_MASK) |
- (tmp & TB_JMP_ADDR_MASK));
+ return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK)
+ | (tmp & TB_JMP_ADDR_MASK));
}
-#ifndef VBOX
-static inline unsigned int tb_phys_hash_func(unsigned long pc)
-#else
-DECLINLINE(unsigned int) tb_phys_hash_func(unsigned long pc)
-#endif
+static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc)
{
return pc & (CODE_GEN_PHYS_HASH_SIZE - 1);
}
@@ -228,40 +212,49 @@ DECLINLINE(unsigned int) tb_phys_hash_func(unsigned long pc)
TranslationBlock *tb_alloc(target_ulong pc);
void tb_free(TranslationBlock *tb);
void tb_flush(CPUState *env);
-void tb_link_phys(TranslationBlock *tb,
- target_ulong phys_pc, target_ulong phys_page2);
-void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr);
+void tb_link_page(TranslationBlock *tb,
+ tb_page_addr_t phys_pc, tb_page_addr_t phys_page2);
+void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
-extern uint8_t *code_gen_ptr;
-extern int code_gen_max_blocks;
-
#if defined(USE_DIRECT_JUMP)
-#if defined(__powerpc__)
+#if defined(_ARCH_PPC)
+extern void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr);
+#define tb_set_jmp_target1 ppc_tb_set_jmp_target
+#elif defined(__i386__) || defined(__x86_64__)
static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
{
- uint32_t val, *ptr;
-
/* patch the branch destination */
- ptr = (uint32_t *)jmp_addr;
- val = *ptr;
- val = (val & ~0x03fffffc) | ((addr - jmp_addr) & 0x03fffffc);
- *ptr = val;
- /* flush icache */
- asm volatile ("dcbst 0,%0" : : "r"(ptr) : "memory");
- asm volatile ("sync" : : : "memory");
- asm volatile ("icbi 0,%0" : : "r"(ptr) : "memory");
- asm volatile ("sync" : : : "memory");
- asm volatile ("isync" : : : "memory");
+ *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
+ /* no need to flush icache explicitly */
}
-#elif defined(__i386__)
+#elif defined(__arm__)
static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
{
- /* patch the branch destination */
- *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
- /* no need to flush icache explicitely */
+#if QEMU_GNUC_PREREQ(4, 1)
+ void __clear_cache(char *beg, char *end);
+#else
+ register unsigned long _beg __asm ("a1");
+ register unsigned long _end __asm ("a2");
+ register unsigned long _flg __asm ("a3");
+#endif
+
+ /* we could use a ldr pc, [pc, #-4] kind of branch and avoid the flush */
+ *(uint32_t *)jmp_addr =
+ (*(uint32_t *)jmp_addr & ~0xffffff)
+ | (((addr - (jmp_addr + 8)) >> 2) & 0xffffff);
+
+#if QEMU_GNUC_PREREQ(4, 1)
+ __clear_cache((char *) jmp_addr, (char *) jmp_addr + 4);
+#else
+ /* flush icache */
+ _beg = jmp_addr;
+ _end = jmp_addr + 4;
+ _flg = 0;
+ __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
+#endif
}
#endif
@@ -272,34 +265,21 @@ static inline void tb_set_jmp_target(TranslationBlock *tb,
offset = tb->tb_jmp_offset[n];
tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
- offset = tb->tb_jmp_offset[n + 2];
- if (offset != 0xffff)
- tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
}
#else
/* set the jump target */
-#ifndef VBOX
static inline void tb_set_jmp_target(TranslationBlock *tb,
int n, unsigned long addr)
-#else
-DECLINLINE(void) tb_set_jmp_target(TranslationBlock *tb,
- int n, unsigned long addr)
-#endif
{
tb->tb_next[n] = addr;
}
#endif
-#ifndef VBOX
static inline void tb_add_jump(TranslationBlock *tb, int n,
TranslationBlock *tb_next)
-#else
-DECLINLINE(void) tb_add_jump(TranslationBlock *tb, int n,
- TranslationBlock *tb_next)
-#endif
{
/* NOTE: this test is only needed for thread safety */
if (!tb->jmp_next[n]) {
@@ -314,28 +294,6 @@ DECLINLINE(void) tb_add_jump(TranslationBlock *tb, int n,
TranslationBlock *tb_find_pc(unsigned long pc_ptr);
-#ifndef offsetof
-#define offsetof(type, field) ((size_t) &((type *)0)->field)
-#endif
-
-#if defined(_WIN32)
-#define ASM_DATA_SECTION ".section \".data\"\n"
-#define ASM_PREVIOUS_SECTION ".section .text\n"
-#elif defined(__APPLE__)
-#define ASM_DATA_SECTION ".data\n"
-#define ASM_PREVIOUS_SECTION ".text\n"
-#else
-#define ASM_DATA_SECTION ".section \".data\"\n"
-#define ASM_PREVIOUS_SECTION ".previous\n"
-#endif
-
-#define ASM_OP_LABEL_NAME(n, opname) \
- ASM_NAME(__op_label) #n "." ASM_NAME(opname)
-
-extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
-extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
-extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-
#include "qemu-lock.h"
extern spinlock_t tb_lock;
@@ -344,6 +302,10 @@ extern int tb_invalidated_flag;
#if !defined(CONFIG_USER_ONLY)
+extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
+extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
+extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
+
void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
void *retaddr);
@@ -372,7 +334,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
#endif
#if defined(CONFIG_USER_ONLY)
-static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
+static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr)
{
return addr;
}
@@ -383,13 +345,10 @@ target_ulong remR3PhysGetPhysicalAddressCode(CPUState *env, target_ulong addr, C
/* NOTE: this function can trigger an exception */
/* NOTE2: the returned address is not exactly the physical address: it
is the offset relative to phys_ram_base */
-#ifndef VBOX
-static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr)
-#else
-DECLINLINE(target_ulong) get_phys_addr_code(CPUState *env1, target_ulong addr)
-#endif
+static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr)
{
int mmu_idx, page_index, pd;
+ void *p;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = cpu_mmu_index(env1);
@@ -410,60 +369,30 @@ DECLINLINE(target_ulong) get_phys_addr_code(CPUState *env1, target_ulong addr)
cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
#endif
}
-
# if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
return addr + env1->tlb_table[mmu_idx][page_index].addend;
# elif defined(VBOX)
Assert(env1->phys_addends[mmu_idx][page_index] != -1);
return addr + env1->phys_addends[mmu_idx][page_index];
# else
- return addr + env1->tlb_table[mmu_idx][page_index].addend - (unsigned long)phys_ram_base;
+ p = (void *)(unsigned long)addr
+ + env1->tlb_table[mmu_idx][page_index].addend;
+ return qemu_ram_addr_from_host(p);
# endif
}
-
-
-/* Deterministic execution requires that IO only be performed on the last
- instruction of a TB so that interrupts take effect immediately. */
-#ifndef VBOX
-static inline int can_do_io(CPUState *env)
-#else
-DECLINLINE(int) can_do_io(CPUState *env)
#endif
-{
- if (!use_icount)
- return 1;
-
- /* If not executing code then assume we are ok. */
- if (!env->current_tb)
- return 1;
- return env->can_do_io != 0;
-}
-#endif
+typedef void (CPUDebugExcpHandler)(CPUState *env);
+CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
-#ifdef USE_KQEMU
-#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
+#ifndef VBOX
+/* vl.c */
+extern int singlestep;
-int kqemu_init(CPUState *env);
-int kqemu_cpu_exec(CPUState *env);
-void kqemu_flush_page(CPUState *env, target_ulong addr);
-void kqemu_flush(CPUState *env, int global);
-void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr);
-void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr);
-void kqemu_cpu_interrupt(CPUState *env);
-void kqemu_record_dump(void);
+/* cpu-exec.c */
+extern volatile sig_atomic_t exit_request;
+#endif /*!VBOX*/
-static inline int kqemu_is_ok(CPUState *env)
-{
- return(env->kqemu_enabled &&
- (env->cr[0] & CR0_PE_MASK) &&
- !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
- (env->eflags & IF_MASK) &&
- !(env->eflags & VM_MASK) &&
- (env->kqemu_enabled == 2 ||
- ((env->hflags & HF_CPL_MASK) == 3 &&
- (env->eflags & IOPL_MASK) != IOPL_MASK)));
-}
#endif
diff --git a/src/recompiler/exec.c b/src/recompiler/exec.c
index 96414248d..567e97a9b 100644
--- a/src/recompiler/exec.c
+++ b/src/recompiler/exec.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -53,8 +52,33 @@
#include "cpu.h"
#include "exec-all.h"
+#include "qemu-common.h"
+#include "tcg.h"
+#ifndef VBOX
+#include "hw/hw.h"
+#include "hw/qdev.h"
+#endif /* !VBOX */
+#include "osdep.h"
+#include "kvm.h"
+#include "qemu-timer.h"
#if defined(CONFIG_USER_ONLY)
#include <qemu.h>
+#include <signal.h>
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#include <sys/param.h>
+#if __FreeBSD_version >= 700104
+#define HAVE_KINFO_GETVMMAP
+#define sigqueue sigqueue_freebsd /* avoid redefinition */
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <machine/profile.h>
+#define _KERNEL
+#include <sys/user.h>
+#undef _KERNEL
+#undef sigqueue
+#include <libutil.h>
+#endif
+#endif
#endif
//#define DEBUG_TB_INVALIDATE
@@ -66,6 +90,9 @@
//#define DEBUG_TB_CHECK
//#define DEBUG_TLB_CHECK
+//#define DEBUG_IOPORT
+//#define DEBUG_SUBPAGE
+
#if !defined(CONFIG_USER_ONLY)
/* TB consistency checks only implemented for usermode emulation. */
#undef DEBUG_TB_CHECK
@@ -73,29 +100,8 @@
#define SMC_BITMAP_USE_THRESHOLD 10
-#define MMAP_AREA_START 0x00000000
-#define MMAP_AREA_END 0xa8000000
-
-#if defined(TARGET_SPARC64)
-#define TARGET_PHYS_ADDR_SPACE_BITS 41
-#elif defined(TARGET_SPARC)
-#define TARGET_PHYS_ADDR_SPACE_BITS 36
-#elif defined(TARGET_ALPHA)
-#define TARGET_PHYS_ADDR_SPACE_BITS 42
-#define TARGET_VIRT_ADDR_SPACE_BITS 42
-#elif defined(TARGET_PPC64)
-#define TARGET_PHYS_ADDR_SPACE_BITS 42
-#elif defined(TARGET_X86_64) && !defined(USE_KQEMU)
-#define TARGET_PHYS_ADDR_SPACE_BITS 42
-#elif defined(TARGET_I386) && !defined(USE_KQEMU)
-#define TARGET_PHYS_ADDR_SPACE_BITS 36
-#else
-/* Note: for compatibility with kqemu, we use 32 bits for x86_64 */
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#endif
-
static TranslationBlock *tbs;
-int code_gen_max_blocks;
+static int code_gen_max_blocks;
TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
static int nb_tbs;
/* any access to the tbs or the page table must use this lock */
@@ -109,41 +115,33 @@ spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
#define code_gen_section \
__attribute__((__section__(".gen_code"))) \
__attribute__((aligned (32)))
+#elif defined(_WIN32)
+/* Maximum alignment for Win32 is 16. */
+#define code_gen_section \
+ __attribute__((aligned (16)))
#else
#define code_gen_section \
__attribute__((aligned (32)))
#endif
-uint8_t code_gen_prologue[1024] code_gen_section;
+uint8_t code_gen_prologue[1024] code_gen_section;
#else /* VBOX */
-extern uint8_t* code_gen_prologue;
+extern uint8_t *code_gen_prologue;
#endif /* VBOX */
-
static uint8_t *code_gen_buffer;
static unsigned long code_gen_buffer_size;
/* threshold to flush the translated code buffer */
static unsigned long code_gen_buffer_max_size;
-uint8_t *code_gen_ptr;
+static uint8_t *code_gen_ptr;
-#ifndef VBOX
#if !defined(CONFIG_USER_ONLY)
-ram_addr_t phys_ram_size;
+# ifndef VBOX
int phys_ram_fd;
-uint8_t *phys_ram_base;
-uint8_t *phys_ram_dirty;
static int in_migration;
-static ram_addr_t phys_ram_alloc_offset = 0;
-#endif
-#else /* VBOX */
-RTGCPHYS phys_ram_size;
-/* we have memory ranges (the high PC-BIOS mapping) which
- causes some pages to fall outside the dirty map here. */
-RTGCPHYS phys_ram_dirty_size;
-#endif /* VBOX */
-#if !defined(VBOX)
-uint8_t *phys_ram_base;
+# endif /* !VBOX */
+
+RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) };
#endif
-uint8_t *phys_ram_dirty;
CPUState *first_cpu;
/* current CPU in the current thread. It is only valid inside
@@ -169,72 +167,96 @@ typedef struct PageDesc {
#endif
} PageDesc;
-typedef struct PhysPageDesc {
- /* offset in host memory of the page + io_index in the low 12 bits */
- ram_addr_t phys_offset;
-} PhysPageDesc;
+/* In system mode we want L1_MAP to be based on ram offsets,
+ while in user mode we want it to be based on virtual addresses. */
+#if !defined(CONFIG_USER_ONLY)
+#if HOST_LONG_BITS < TARGET_PHYS_ADDR_SPACE_BITS
+# define L1_MAP_ADDR_SPACE_BITS HOST_LONG_BITS
+#else
+# define L1_MAP_ADDR_SPACE_BITS TARGET_PHYS_ADDR_SPACE_BITS
+#endif
+#else
+# define L1_MAP_ADDR_SPACE_BITS TARGET_VIRT_ADDR_SPACE_BITS
+#endif
+/* Size of the L2 (and L3, etc) page tables. */
#define L2_BITS 10
-#if defined(CONFIG_USER_ONLY) && defined(TARGET_VIRT_ADDR_SPACE_BITS)
-/* XXX: this is a temporary hack for alpha target.
- * In the future, this is to be replaced by a multi-level table
- * to actually be able to handle the complete 64 bits address space.
- */
-#define L1_BITS (TARGET_VIRT_ADDR_SPACE_BITS - L2_BITS - TARGET_PAGE_BITS)
+#define L2_SIZE (1 << L2_BITS)
+
+/* The bits remaining after N lower levels of page tables. */
+#define P_L1_BITS_REM \
+ ((TARGET_PHYS_ADDR_SPACE_BITS - TARGET_PAGE_BITS) % L2_BITS)
+#define V_L1_BITS_REM \
+ ((L1_MAP_ADDR_SPACE_BITS - TARGET_PAGE_BITS) % L2_BITS)
+
+/* Size of the L1 page table. Avoid silly small sizes. */
+#if P_L1_BITS_REM < 4
+#define P_L1_BITS (P_L1_BITS_REM + L2_BITS)
#else
-#define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
-#endif
-#ifdef VBOX
-#define L0_BITS (TARGET_PHYS_ADDR_SPACE_BITS - 32)
+#define P_L1_BITS P_L1_BITS_REM
#endif
-#ifdef VBOX
-#define L0_SIZE (1 << L0_BITS)
+#if V_L1_BITS_REM < 4
+#define V_L1_BITS (V_L1_BITS_REM + L2_BITS)
+#else
+#define V_L1_BITS V_L1_BITS_REM
#endif
-#define L1_SIZE (1 << L1_BITS)
-#define L2_SIZE (1 << L2_BITS)
-static void io_mem_init(void);
+#define P_L1_SIZE ((target_phys_addr_t)1 << P_L1_BITS)
+#define V_L1_SIZE ((target_ulong)1 << V_L1_BITS)
+
+#define P_L1_SHIFT (TARGET_PHYS_ADDR_SPACE_BITS - TARGET_PAGE_BITS - P_L1_BITS)
+#define V_L1_SHIFT (L1_MAP_ADDR_SPACE_BITS - TARGET_PAGE_BITS - V_L1_BITS)
unsigned long qemu_real_host_page_size;
unsigned long qemu_host_page_bits;
unsigned long qemu_host_page_size;
unsigned long qemu_host_page_mask;
-/* XXX: for system emulation, it could just be an array */
-#ifndef VBOX
-static PageDesc *l1_map[L1_SIZE];
-static PhysPageDesc **l1_phys_map;
-#else
-static unsigned l0_map_max_used = 0;
-static PageDesc **l0_map[L0_SIZE];
-static void **l0_phys_map[L0_SIZE];
-#endif
+/* This is a multi-level map on the virtual address space.
+ The bottom level has pointers to PageDesc. */
+static void *l1_map[V_L1_SIZE];
#if !defined(CONFIG_USER_ONLY)
+typedef struct PhysPageDesc {
+ /* offset in host memory of the page + io_index in the low bits */
+ ram_addr_t phys_offset;
+ ram_addr_t region_offset;
+} PhysPageDesc;
+
+/* This is a multi-level map on the physical address space.
+ The bottom level has pointers to PhysPageDesc. */
+static void *l1_phys_map[P_L1_SIZE];
+
static void io_mem_init(void);
/* io memory support */
CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-static int io_mem_nb;
+static char io_mem_used[IO_MEM_NB_ENTRIES];
static int io_mem_watch;
#endif
#ifndef VBOX
/* log support */
+#ifdef WIN32
+static const char *logfilename = "qemu.log";
+#else
static const char *logfilename = "/tmp/qemu.log";
+#endif
#endif /* !VBOX */
FILE *logfile;
int loglevel;
#ifndef VBOX
static int log_append = 0;
-#endif
+#endif /* !VBOX */
/* statistics */
#ifndef VBOX
+#if !defined(CONFIG_USER_ONLY)
static int tlb_flush_count;
+#endif
static int tb_flush_count;
static int tb_phys_invalidate_count;
#else /* VBOX - Resettable U32 stats, see VBoxRecompiler.c. */
@@ -243,15 +265,6 @@ uint32_t tb_flush_count;
uint32_t tb_phys_invalidate_count;
#endif /* VBOX */
-#define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
-typedef struct subpage_t {
- target_phys_addr_t base;
- CPUReadMemoryFunc **mem_read[TARGET_PAGE_SIZE][4];
- CPUWriteMemoryFunc **mem_write[TARGET_PAGE_SIZE][4];
- void *opaque[TARGET_PAGE_SIZE][2][4];
-} subpage_t;
-
-
#ifndef VBOX
#ifdef _WIN32
static void map_exec(void *addr, long size)
@@ -278,13 +291,13 @@ static void map_exec(void *addr, long size)
PROT_READ | PROT_WRITE | PROT_EXEC);
}
#endif
-#else // VBOX
+#else /* VBOX */
static void map_exec(void *addr, long size)
{
RTMemProtect(addr, size,
RTMEM_PROT_EXEC | RTMEM_PROT_READ | RTMEM_PROT_WRITE);
}
-#endif
+#endif /* VBOX */
static void page_init(void)
{
@@ -298,7 +311,6 @@ static void page_init(void)
#ifdef _WIN32
{
SYSTEM_INFO system_info;
- DWORD old_protect;
GetSystemInfo(&system_info);
qemu_real_host_page_size = system_info.dwPageSize;
@@ -307,205 +319,184 @@ static void page_init(void)
qemu_real_host_page_size = getpagesize();
#endif
#endif /* !VBOX */
-
if (qemu_host_page_size == 0)
qemu_host_page_size = qemu_real_host_page_size;
if (qemu_host_page_size < TARGET_PAGE_SIZE)
qemu_host_page_size = TARGET_PAGE_SIZE;
qemu_host_page_bits = 0;
-#ifndef VBOX
- while ((1 << qemu_host_page_bits) < qemu_host_page_size)
-#else
- while ((1 << qemu_host_page_bits) < (int)qemu_host_page_size)
-#endif
+ while ((1 << qemu_host_page_bits) < VBOX_ONLY((int))qemu_host_page_size)
qemu_host_page_bits++;
qemu_host_page_mask = ~(qemu_host_page_size - 1);
-#ifndef VBOX
- l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(void *));
- memset(l1_phys_map, 0, L1_SIZE * sizeof(void *));
+
+#ifndef VBOX /* We use other means to set reserved bit on our pages */
+#if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
+ {
+#ifdef HAVE_KINFO_GETVMMAP
+ struct kinfo_vmentry *freep;
+ int i, cnt;
+
+ freep = kinfo_getvmmap(getpid(), &cnt);
+ if (freep) {
+ mmap_lock();
+ for (i = 0; i < cnt; i++) {
+ unsigned long startaddr, endaddr;
+
+ startaddr = freep[i].kve_start;
+ endaddr = freep[i].kve_end;
+ if (h2g_valid(startaddr)) {
+ startaddr = h2g(startaddr) & TARGET_PAGE_MASK;
+
+ if (h2g_valid(endaddr)) {
+ endaddr = h2g(endaddr);
+ page_set_flags(startaddr, endaddr, PAGE_RESERVED);
+ } else {
+#if TARGET_ABI_BITS <= L1_MAP_ADDR_SPACE_BITS
+ endaddr = ~0ul;
+ page_set_flags(startaddr, endaddr, PAGE_RESERVED);
#endif
-#ifdef VBOX
- /* We use other means to set reserved bit on our pages */
+ }
+ }
+ }
+ free(freep);
+ mmap_unlock();
+ }
#else
-#if !defined(_WIN32) && defined(CONFIG_USER_ONLY)
- {
- long long startaddr, endaddr;
FILE *f;
- int n;
- mmap_lock();
last_brk = (unsigned long)sbrk(0);
- f = fopen("/proc/self/maps", "r");
+
+ f = fopen("/compat/linux/proc/self/maps", "r");
if (f) {
+ mmap_lock();
+
do {
- n = fscanf (f, "%llx-%llx %*[^\n]\n", &startaddr, &endaddr);
- if (n == 2) {
- startaddr = MIN(startaddr,
- (1ULL << TARGET_PHYS_ADDR_SPACE_BITS) - 1);
- endaddr = MIN(endaddr,
- (1ULL << TARGET_PHYS_ADDR_SPACE_BITS) - 1);
- page_set_flags(startaddr & TARGET_PAGE_MASK,
- TARGET_PAGE_ALIGN(endaddr),
- PAGE_RESERVED);
+ unsigned long startaddr, endaddr;
+ int n;
+
+ n = fscanf (f, "%lx-%lx %*[^\n]\n", &startaddr, &endaddr);
+
+ if (n == 2 && h2g_valid(startaddr)) {
+ startaddr = h2g(startaddr) & TARGET_PAGE_MASK;
+
+ if (h2g_valid(endaddr)) {
+ endaddr = h2g(endaddr);
+ } else {
+ endaddr = ~0ul;
+ }
+ page_set_flags(startaddr, endaddr, PAGE_RESERVED);
}
} while (!feof(f));
+
fclose(f);
+ mmap_unlock();
}
- mmap_unlock();
- }
#endif
+ }
#endif
+#endif /* !VBOX */
}
-#ifndef VBOX
-static inline PageDesc **page_l1_map(target_ulong index)
-#else
-DECLINLINE(PageDesc **) page_l1_map(target_ulong index)
-#endif
+static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
{
-#ifndef VBOX
-#if TARGET_LONG_BITS > 32
- /* Host memory outside guest VM. For 32-bit targets we have already
- excluded high addresses. */
- if (index > ((target_ulong)L2_SIZE * L1_SIZE))
- return NULL;
-#endif
- return &l1_map[index >> L2_BITS];
-#else /* VBOX */
- PageDesc **l1_map;
- AssertMsgReturn(index < (target_ulong)L2_SIZE * L1_SIZE * L0_SIZE,
- ("index=%RGp >= %RGp; L1_SIZE=%#x L2_SIZE=%#x L0_SIZE=%#x\n",
- (RTGCPHYS)index, (RTGCPHYS)L2_SIZE * L1_SIZE, L1_SIZE, L2_SIZE, L0_SIZE),
- NULL);
- l1_map = l0_map[index >> (L1_BITS + L2_BITS)];
- if (RT_UNLIKELY(!l1_map))
- {
- unsigned i0 = index >> (L1_BITS + L2_BITS);
- l0_map[i0] = l1_map = qemu_mallocz(sizeof(PageDesc *) * L1_SIZE);
- if (RT_UNLIKELY(!l1_map))
- return NULL;
- if (i0 >= l0_map_max_used)
- l0_map_max_used = i0 + 1;
- }
- return &l1_map[(index >> L2_BITS) & (L1_SIZE - 1)];
-#endif /* VBOX */
-}
+ PageDesc *pd;
+ void **lp;
+ int i;
-#ifndef VBOX
-static inline PageDesc *page_find_alloc(target_ulong index)
+#if defined(CONFIG_USER_ONLY)
+ /* We can't use qemu_malloc because it may recurse into a locked mutex. */
+# define ALLOC(P, SIZE) \
+ do { \
+ P = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, \
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
+ } while (0)
#else
-DECLINLINE(PageDesc *) page_find_alloc(target_ulong index)
+# define ALLOC(P, SIZE) \
+ do { P = qemu_mallocz(SIZE); } while (0)
#endif
-{
- PageDesc **lp, *p;
- lp = page_l1_map(index);
- if (!lp)
- return NULL;
- p = *lp;
- if (!p) {
- /* allocate if not found */
-#if defined(CONFIG_USER_ONLY)
- unsigned long addr;
- size_t len = sizeof(PageDesc) * L2_SIZE;
- /* Don't use qemu_malloc because it may recurse. */
- p = mmap(0, len, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- *lp = p;
- addr = h2g(p);
- if (addr == (target_ulong)addr) {
- page_set_flags(addr & TARGET_PAGE_MASK,
- TARGET_PAGE_ALIGN(addr + len),
- PAGE_RESERVED);
+ /* Level 1. Always allocated. */
+ lp = l1_map + ((index >> V_L1_SHIFT) & (V_L1_SIZE - 1));
+
+ /* Level 2..N-1. */
+ for (i = V_L1_SHIFT / L2_BITS - 1; i > 0; i--) {
+ void **p = *lp;
+
+ if (p == NULL) {
+ if (!alloc) {
+ return NULL;
+ }
+ ALLOC(p, sizeof(void *) * L2_SIZE);
+ *lp = p;
}
-#else
- p = qemu_mallocz(sizeof(PageDesc) * L2_SIZE);
- *lp = p;
-#endif
+
+ lp = p + ((index >> (i * L2_BITS)) & (L2_SIZE - 1));
}
- return p + (index & (L2_SIZE - 1));
+
+ pd = *lp;
+ if (pd == NULL) {
+ if (!alloc) {
+ return NULL;
+ }
+ ALLOC(pd, sizeof(PageDesc) * L2_SIZE);
+ *lp = pd;
+ }
+
+#undef ALLOC
+
+ return pd + (index & (L2_SIZE - 1));
}
-#ifndef VBOX
-static inline PageDesc *page_find(target_ulong index)
-#else
-DECLINLINE(PageDesc *) page_find(target_ulong index)
-#endif
+static inline PageDesc *page_find(tb_page_addr_t index)
{
- PageDesc **lp, *p;
- lp = page_l1_map(index);
- if (!lp)
- return NULL;
-
- p = *lp;
- if (!p)
- return 0;
- return p + (index & (L2_SIZE - 1));
+ return page_find_alloc(index, 0);
}
+#if !defined(CONFIG_USER_ONLY)
static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
{
- void **lp, **p;
PhysPageDesc *pd;
+ void **lp;
+ int i;
-#ifndef VBOX
- p = (void **)l1_phys_map;
-#if TARGET_PHYS_ADDR_SPACE_BITS > 32
+ /* Level 1. Always allocated. */
+ lp = l1_phys_map + ((index >> P_L1_SHIFT) & (P_L1_SIZE - 1));
-#if TARGET_PHYS_ADDR_SPACE_BITS > (32 + L1_BITS)
-#error unsupported TARGET_PHYS_ADDR_SPACE_BITS
-#endif
- lp = p + ((index >> (L1_BITS + L2_BITS)) & (L1_SIZE - 1));
- p = *lp;
- if (!p) {
- /* allocate if not found */
- if (!alloc)
- return NULL;
- p = qemu_vmalloc(sizeof(void *) * L1_SIZE);
- memset(p, 0, sizeof(void *) * L1_SIZE);
- *lp = p;
- }
-#endif
-#else /* VBOX */
- /* level 0 lookup and lazy allocation of level 1 map. */
- if (RT_UNLIKELY(index >= (target_phys_addr_t)L2_SIZE * L1_SIZE * L0_SIZE))
- return NULL;
- p = l0_phys_map[index >> (L1_BITS + L2_BITS)];
- if (RT_UNLIKELY(!p)) {
- if (!alloc)
- return NULL;
- p = qemu_vmalloc(sizeof(void **) * L1_SIZE);
- memset(p, 0, sizeof(void **) * L1_SIZE);
- l0_phys_map[index >> (L1_BITS + L2_BITS)] = p;
+ /* Level 2..N-1. */
+ for (i = P_L1_SHIFT / L2_BITS - 1; i > 0; i--) {
+ void **p = *lp;
+ if (p == NULL) {
+ if (!alloc) {
+ return NULL;
+ }
+ *lp = p = qemu_mallocz(sizeof(void *) * L2_SIZE);
+ }
+ lp = p + ((index >> (i * L2_BITS)) & (L2_SIZE - 1));
}
- /* level 1 lookup and lazy allocation of level 2 map. */
-#endif /* VBOX */
- lp = p + ((index >> L2_BITS) & (L1_SIZE - 1));
pd = *lp;
- if (!pd) {
+ if (pd == NULL) {
int i;
- /* allocate if not found */
- if (!alloc)
+
+ if (!alloc) {
return NULL;
- pd = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
- *lp = pd;
- for (i = 0; i < L2_SIZE; i++)
- pd[i].phys_offset = IO_MEM_UNASSIGNED;
+ }
+
+ *lp = pd = qemu_malloc(sizeof(PhysPageDesc) * L2_SIZE);
+
+ for (i = 0; i < L2_SIZE; i++) {
+ pd[i].phys_offset = IO_MEM_UNASSIGNED;
+ pd[i].region_offset = (index + i) << TARGET_PAGE_BITS;
+ }
}
- return ((PhysPageDesc *)pd) + (index & (L2_SIZE - 1));
+
+ return pd + (index & (L2_SIZE - 1));
}
-#ifndef VBOX
static inline PhysPageDesc *phys_page_find(target_phys_addr_t index)
-#else
-DECLINLINE(PhysPageDesc *) phys_page_find(target_phys_addr_t index)
-#endif
{
return phys_page_find_alloc(index, 0);
}
-#if !defined(CONFIG_USER_ONLY)
static void tlb_protect_code(ram_addr_t ram_addr);
static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
target_ulong vaddr);
@@ -513,15 +504,12 @@ static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
#define mmap_unlock() do { } while(0)
#endif
-#ifdef VBOX
-/*
- * We don't need such huge codegen buffer size, as execute most of the code
- * in raw or hwacc mode
- */
+#ifdef VBOX /* We don't need such huge codegen buffer size, as execute
+ most of the code in raw or hwacc mode. */
#define DEFAULT_CODE_GEN_BUFFER_SIZE (8 * 1024 * 1024)
-#else
+#else /* !VBOX */
#define DEFAULT_CODE_GEN_BUFFER_SIZE (32 * 1024 * 1024)
-#endif
+#endif /* !VBOX */
#if defined(CONFIG_USER_ONLY)
/* Currently it is not recommended to allocate big chunks of data in
@@ -529,11 +517,13 @@ static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
#define USE_STATIC_CODE_GEN_BUFFER
#endif
-/* VBox allocates codegen buffer dynamically */
-#ifndef VBOX
-#ifdef USE_STATIC_CODE_GEN_BUFFER
-static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE];
+#if defined(VBOX) && defined(USE_STATIC_CODE_GEN_BUFFER)
+# error "VBox allocates codegen buffer dynamically"
#endif
+
+#ifdef USE_STATIC_CODE_GEN_BUFFER
+static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE]
+ __attribute__((aligned (CODE_GEN_ALIGN)));
#endif
static void code_gen_alloc(unsigned long tb_size)
@@ -543,13 +533,13 @@ static void code_gen_alloc(unsigned long tb_size)
code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
map_exec(code_gen_buffer, code_gen_buffer_size);
#else
-#ifdef VBOX
+# ifdef VBOX
/* We cannot use phys_ram_size here, as it's 0 now,
* it only gets initialized once RAM registration callback
* (REMR3NotifyPhysRamRegister()) called.
*/
code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
-#else
+# else /* !VBOX */
code_gen_buffer_size = tb_size;
if (code_gen_buffer_size == 0) {
#if defined(CONFIG_USER_ONLY)
@@ -557,17 +547,15 @@ static void code_gen_alloc(unsigned long tb_size)
code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
#else
/* XXX: needs adjustments */
- code_gen_buffer_size = (unsigned long)(phys_ram_size / 4);
+ code_gen_buffer_size = (unsigned long)(ram_size / 4);
#endif
-
}
if (code_gen_buffer_size < MIN_CODE_GEN_BUFFER_SIZE)
code_gen_buffer_size = MIN_CODE_GEN_BUFFER_SIZE;
-#endif /* VBOX */
-
+# endif /* !VBOX */
/* The code gen buffer location may have constraints depending on
the host cpu and OS */
-#ifdef VBOX
+# ifdef VBOX
code_gen_buffer = RTMemExecAlloc(code_gen_buffer_size);
if (!code_gen_buffer) {
@@ -575,7 +563,7 @@ static void code_gen_alloc(unsigned long tb_size)
code_gen_buffer_size));
return;
}
-#else //!VBOX
+# else /* !VBOX */
#if defined(__linux__)
{
int flags;
@@ -593,6 +581,19 @@ static void code_gen_alloc(unsigned long tb_size)
start = (void *) 0x60000000UL;
if (code_gen_buffer_size > (512 * 1024 * 1024))
code_gen_buffer_size = (512 * 1024 * 1024);
+#elif defined(__arm__)
+ /* Map the buffer below 32M, so we can use direct calls and branches */
+ flags |= MAP_FIXED;
+ start = (void *) 0x01000000UL;
+ if (code_gen_buffer_size > 16 * 1024 * 1024)
+ code_gen_buffer_size = 16 * 1024 * 1024;
+#elif defined(__s390x__)
+ /* Map the buffer so that we can use direct calls and branches. */
+ /* We have a +- 4GB range on the branches; leave some slop. */
+ if (code_gen_buffer_size > (3ul * 1024 * 1024 * 1024)) {
+ code_gen_buffer_size = 3ul * 1024 * 1024 * 1024;
+ }
+ start = (void *)0x90000000UL;
#endif
code_gen_buffer = mmap(start, code_gen_buffer_size,
PROT_WRITE | PROT_READ | PROT_EXEC,
@@ -602,7 +603,7 @@ static void code_gen_alloc(unsigned long tb_size)
exit(1);
}
}
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
{
int flags;
void *addr = NULL;
@@ -626,23 +627,17 @@ static void code_gen_alloc(unsigned long tb_size)
}
#else
code_gen_buffer = qemu_malloc(code_gen_buffer_size);
- if (!code_gen_buffer) {
- fprintf(stderr, "Could not allocate dynamic translator buffer\n");
- exit(1);
- }
map_exec(code_gen_buffer, code_gen_buffer_size);
#endif
- map_exec(code_gen_prologue, sizeof(code_gen_prologue));
-#endif /* !VBOX */
+# endif /* !VBOX */
#endif /* !USE_STATIC_CODE_GEN_BUFFER */
-#ifndef VBOX
+#ifndef VBOX /** @todo r=bird: why are we different? */
map_exec(code_gen_prologue, sizeof(code_gen_prologue));
#else
map_exec(code_gen_prologue, _1K);
#endif
-
code_gen_buffer_max_size = code_gen_buffer_size -
- code_gen_max_block_size();
+ (TCG_MAX_OP_SIZE * OPC_MAX_SIZE);
code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
tbs = qemu_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
}
@@ -659,67 +654,90 @@ void cpu_exec_init_all(unsigned long tb_size)
#if !defined(CONFIG_USER_ONLY)
io_mem_init();
#endif
+#if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE)
+ /* There's no guest base to take into account, so go ahead and
+ initialize the prologue now. */
+ tcg_prologue_init(&tcg_ctx);
+#endif
}
#ifndef VBOX
#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
-#define CPU_COMMON_SAVE_VERSION 1
-
-static void cpu_common_save(QEMUFile *f, void *opaque)
+static int cpu_common_post_load(void *opaque, int version_id)
{
CPUState *env = opaque;
- qemu_put_be32s(f, &env->halted);
- qemu_put_be32s(f, &env->interrupt_request);
+ /* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
+ version_id is increased. */
+ env->interrupt_request &= ~0x01;
+ tlb_flush(env, 1);
+
+ return 0;
}
-static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
-{
- CPUState *env = opaque;
+static const VMStateDescription vmstate_cpu_common = {
+ .name = "cpu_common",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .post_load = cpu_common_post_load,
+ .fields = (VMStateField []) {
+ VMSTATE_UINT32(halted, CPUState),
+ VMSTATE_UINT32(interrupt_request, CPUState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+#endif
- if (version_id != CPU_COMMON_SAVE_VERSION)
- return -EINVAL;
+CPUState *qemu_get_cpu(int cpu)
+{
+ CPUState *env = first_cpu;
- qemu_get_be32s(f, &env->halted);
- qemu_get_be32s(f, &env->interrupt_request);
- tlb_flush(env, 1);
+ while (env) {
+ if (env->cpu_index == cpu)
+ break;
+ env = env->next_cpu;
+ }
- return 0;
+ return env;
}
-#endif
-#endif //!VBOX
+
+#endif /* !VBOX */
void cpu_exec_init(CPUState *env)
{
CPUState **penv;
int cpu_index;
+#if defined(CONFIG_USER_ONLY)
+ cpu_list_lock();
+#endif
env->next_cpu = NULL;
penv = &first_cpu;
cpu_index = 0;
while (*penv != NULL) {
- penv = (CPUState **)&(*penv)->next_cpu;
+ penv = &(*penv)->next_cpu;
cpu_index++;
}
env->cpu_index = cpu_index;
- env->nb_watchpoints = 0;
+ env->numa_node = 0;
+ QTAILQ_INIT(&env->breakpoints);
+ QTAILQ_INIT(&env->watchpoints);
*penv = env;
#ifndef VBOX
+#if defined(CONFIG_USER_ONLY)
+ cpu_list_unlock();
+#endif
#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
- register_savevm("cpu_common", cpu_index, CPU_COMMON_SAVE_VERSION,
- cpu_common_save, cpu_common_load, env);
- register_savevm("cpu", cpu_index, CPU_SAVE_VERSION,
+ vmstate_register(NULL, cpu_index, &vmstate_cpu_common, env);
+ register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
cpu_save, cpu_load, env);
#endif
-#endif // !VBOX
+#endif /* !VBOX */
}
-#ifndef VBOX
static inline void invalidate_page_bitmap(PageDesc *p)
-#else
-DECLINLINE(void) invalidate_page_bitmap(PageDesc *p)
-#endif
{
if (p->code_bitmap) {
qemu_free(p->code_bitmap);
@@ -728,35 +746,35 @@ DECLINLINE(void) invalidate_page_bitmap(PageDesc *p)
p->code_write_count = 0;
}
-/* set to NULL all the 'first_tb' fields in all PageDescs */
-static void page_flush_tb(void)
+/* Set to NULL all the 'first_tb' fields in all PageDescs. */
+
+static void page_flush_tb_1 (int level, void **lp)
{
- int i, j;
- PageDesc *p;
-#ifdef VBOX
- int k;
-#endif
+ int i;
-#ifdef VBOX
- k = l0_map_max_used;
- while (k-- > 0) {
- PageDesc **l1_map = l0_map[k];
- if (l1_map) {
-#endif
- for(i = 0; i < L1_SIZE; i++) {
- p = l1_map[i];
- if (p) {
- for(j = 0; j < L2_SIZE; j++) {
- p->first_tb = NULL;
- invalidate_page_bitmap(p);
- p++;
- }
- }
- }
-#ifdef VBOX
+ if (*lp == NULL) {
+ return;
+ }
+ if (level == 0) {
+ PageDesc *pd = *lp;
+ for (i = 0; i < L2_SIZE; ++i) {
+ pd[i].first_tb = NULL;
+ invalidate_page_bitmap(pd + i);
+ }
+ } else {
+ void **pp = *lp;
+ for (i = 0; i < L2_SIZE; ++i) {
+ page_flush_tb_1 (level - 1, pp + i);
}
}
-#endif
+}
+
+static void page_flush_tb(void)
+{
+ int i;
+ for (i = 0; i < V_L1_SIZE; i++) {
+ page_flush_tb_1(V_L1_SHIFT / L2_BITS - 1, l1_map + i);
+ }
}
/* flush all the translation blocks */
@@ -795,6 +813,7 @@ void tb_flush(CPUState *env1)
}
#ifdef DEBUG_TB_CHECK
+
static void tb_invalidate_check(target_ulong address)
{
TranslationBlock *tb;
@@ -804,7 +823,8 @@ static void tb_invalidate_check(target_ulong address)
for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
address >= tb->pc + tb->size)) {
- printf("ERROR invalidate: address=%08lx PC=%08lx size=%04x\n",
+ printf("ERROR invalidate: address=" TARGET_FMT_lx
+ " PC=%08lx size=%04x\n",
address, (long)tb->pc, tb->size);
}
}
@@ -829,35 +849,11 @@ static void tb_page_check(void)
}
}
-static void tb_jmp_check(TranslationBlock *tb)
-{
- TranslationBlock *tb1;
- unsigned int n1;
-
- /* suppress any remaining jumps to this TB */
- tb1 = tb->jmp_first;
- for(;;) {
- n1 = (long)tb1 & 3;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- if (n1 == 2)
- break;
- tb1 = tb1->jmp_next[n1];
- }
- /* check end of list */
- if (tb1 != tb) {
- printf("ERROR: jmp_list from 0x%08lx\n", (long)tb);
- }
-}
-#endif // DEBUG_TB_CHECK
+#endif
/* invalidate one TB */
-#ifndef VBOX
static inline void tb_remove(TranslationBlock **ptb, TranslationBlock *tb,
int next_offset)
-#else
-DECLINLINE(void) tb_remove(TranslationBlock **ptb, TranslationBlock *tb,
- int next_offset)
-#endif
{
TranslationBlock *tb1;
for(;;) {
@@ -870,11 +866,7 @@ DECLINLINE(void) tb_remove(TranslationBlock **ptb, TranslationBlock *tb,
}
}
-#ifndef VBOX
static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
-#else
-DECLINLINE(void) tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
-#endif
{
TranslationBlock *tb1;
unsigned int n1;
@@ -891,11 +883,7 @@ DECLINLINE(void) tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
}
}
-#ifndef VBOX
static inline void tb_jmp_remove(TranslationBlock *tb, int n)
-#else
-DECLINLINE(void) tb_jmp_remove(TranslationBlock *tb, int n)
-#endif
{
TranslationBlock *tb1, **ptb;
unsigned int n1;
@@ -925,21 +913,17 @@ DECLINLINE(void) tb_jmp_remove(TranslationBlock *tb, int n)
/* reset the jump entry 'n' of a TB so that it is not chained to
another TB */
-#ifndef VBOX
static inline void tb_reset_jump(TranslationBlock *tb, int n)
-#else
-DECLINLINE(void) tb_reset_jump(TranslationBlock *tb, int n)
-#endif
{
tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n]));
}
-void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr)
+void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
{
CPUState *env;
PageDesc *p;
unsigned int h, n1;
- target_phys_addr_t phys_pc;
+ tb_page_addr_t phys_pc;
TranslationBlock *tb1, *tb2;
/* remove the TB from the hash list */
@@ -990,8 +974,8 @@ void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr)
tb_phys_invalidate_count++;
}
-
#ifdef VBOX
+
void tb_invalidate_virt(CPUState *env, uint32_t eip)
{
# if 1
@@ -1034,13 +1018,10 @@ unsigned long get_phys_page_offset(target_ulong addr)
return p ? p->phys_offset : 0;
}
# endif /* VBOX_STRICT */
+
#endif /* VBOX */
-#ifndef VBOX
static inline void set_bits(uint8_t *tab, int start, int len)
-#else
-DECLINLINE(void) set_bits(uint8_t *tab, int start, int len)
-#endif
{
int end, mask, end1;
@@ -1072,10 +1053,7 @@ static void build_page_bitmap(PageDesc *p)
int n, tb_start, tb_end;
TranslationBlock *tb;
- p->code_bitmap = qemu_malloc(TARGET_PAGE_SIZE / 8);
- if (!p->code_bitmap)
- return;
- memset(p->code_bitmap, 0, TARGET_PAGE_SIZE / 8);
+ p->code_bitmap = qemu_mallocz(TARGET_PAGE_SIZE / 8);
tb = p->first_tb;
while (tb != NULL) {
@@ -1104,10 +1082,11 @@ TranslationBlock *tb_gen_code(CPUState *env,
{
TranslationBlock *tb;
uint8_t *tc_ptr;
- target_ulong phys_pc, phys_page2, virt_page2;
+ tb_page_addr_t phys_pc, phys_page2;
+ target_ulong virt_page2;
int code_gen_size;
- phys_pc = get_phys_addr_code(env, pc);
+ phys_pc = get_page_addr_code(env, pc);
tb = tb_alloc(pc);
if (!tb) {
/* flush must be done */
@@ -1129,9 +1108,9 @@ TranslationBlock *tb_gen_code(CPUState *env,
virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
phys_page2 = -1;
if ((pc & TARGET_PAGE_MASK) != virt_page2) {
- phys_page2 = get_phys_addr_code(env, virt_page2);
+ phys_page2 = get_page_addr_code(env, virt_page2);
}
- tb_link_phys(tb, phys_pc, phys_page2);
+ tb_link_page(tb, phys_pc, phys_page2);
return tb;
}
@@ -1140,15 +1119,22 @@ TranslationBlock *tb_gen_code(CPUState *env,
the same physical page. 'is_cpu_write_access' should be true if called
from a real cpu write access: the virtual CPU will exit the current
TB if code is modified inside this TB. */
-void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end,
+void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
int is_cpu_write_access)
{
- int n, current_tb_modified, current_tb_not_found, current_flags;
+ TranslationBlock *tb, *tb_next, *saved_tb;
CPUState *env = cpu_single_env;
+ tb_page_addr_t tb_start, tb_end;
PageDesc *p;
- TranslationBlock *tb, *tb_next, *current_tb, *saved_tb;
- target_ulong tb_start, tb_end;
- target_ulong current_pc, current_cs_base;
+ int n;
+#ifdef TARGET_HAS_PRECISE_SMC
+ int current_tb_not_found = is_cpu_write_access;
+ TranslationBlock *current_tb = NULL;
+ int current_tb_modified = 0;
+ target_ulong current_pc = 0;
+ target_ulong current_cs_base = 0;
+ int current_flags = 0;
+#endif /* TARGET_HAS_PRECISE_SMC */
p = page_find(start >> TARGET_PAGE_BITS);
if (!p)
@@ -1162,12 +1148,6 @@ void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t
/* we remove all the TBs in the range [start, end[ */
/* XXX: see if in some cases it could be faster to invalidate all the code */
- current_tb_not_found = is_cpu_write_access;
- current_tb_modified = 0;
- current_tb = NULL; /* avoid warning */
- current_pc = 0; /* avoid warning */
- current_cs_base = 0; /* avoid warning */
- current_flags = 0; /* avoid warning */
tb = p->first_tb;
while (tb != NULL) {
n = (long)tb & 3;
@@ -1204,14 +1184,8 @@ void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t
current_tb_modified = 1;
cpu_restore_state(current_tb, env,
env->mem_io_pc, NULL);
-#if defined(TARGET_I386)
- current_flags = env->hflags;
- current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
- current_cs_base = (target_ulong)env->segs[R_CS].base;
- current_pc = current_cs_base + env->eip;
-#else
-#error unsupported CPU
-#endif
+ cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
+ &current_flags);
}
#endif /* TARGET_HAS_PRECISE_SMC */
/* we need to do that to handle the case where a signal
@@ -1251,24 +1225,17 @@ void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t
#endif
}
-
/* len must be <= 8 and start must be a multiple of len */
-#ifndef VBOX
-static inline void tb_invalidate_phys_page_fast(target_phys_addr_t start, int len)
-#else
-DECLINLINE(void) tb_invalidate_phys_page_fast(target_phys_addr_t start, int len)
-#endif
+static inline void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
{
PageDesc *p;
int offset, b;
#if 0
if (1) {
- if (loglevel) {
- fprintf(logfile, "modifying code at 0x%x size=%d EIP=%x PC=%08x\n",
- cpu_single_env->mem_io_vaddr, len,
- cpu_single_env->eip,
- cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base);
- }
+ qemu_log("modifying code at 0x%x size=%d EIP=%x PC=%08x\n",
+ cpu_single_env->mem_io_vaddr, len,
+ cpu_single_env->eip,
+ cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base);
}
#endif
p = page_find(start >> TARGET_PAGE_BITS);
@@ -1285,17 +1252,20 @@ DECLINLINE(void) tb_invalidate_phys_page_fast(target_phys_addr_t start, int len)
}
}
-
#if !defined(CONFIG_SOFTMMU)
-static void tb_invalidate_phys_page(target_phys_addr_t addr,
+static void tb_invalidate_phys_page(tb_page_addr_t addr,
unsigned long pc, void *puc)
{
- int n, current_flags, current_tb_modified;
- target_ulong current_pc, current_cs_base;
+ TranslationBlock *tb;
PageDesc *p;
- TranslationBlock *tb, *current_tb;
+ int n;
#ifdef TARGET_HAS_PRECISE_SMC
+ TranslationBlock *current_tb = NULL;
CPUState *env = cpu_single_env;
+ int current_tb_modified = 0;
+ target_ulong current_pc = 0;
+ target_ulong current_cs_base = 0;
+ int current_flags = 0;
#endif
addr &= TARGET_PAGE_MASK;
@@ -1303,11 +1273,6 @@ static void tb_invalidate_phys_page(target_phys_addr_t addr,
if (!p)
return;
tb = p->first_tb;
- current_tb_modified = 0;
- current_tb = NULL;
- current_pc = 0; /* avoid warning */
- current_cs_base = 0; /* avoid warning */
- current_flags = 0; /* avoid warning */
#ifdef TARGET_HAS_PRECISE_SMC
if (tb && pc != 0) {
current_tb = tb_find_pc(pc);
@@ -1327,14 +1292,8 @@ static void tb_invalidate_phys_page(target_phys_addr_t addr,
current_tb_modified = 1;
cpu_restore_state(current_tb, env, pc, puc);
-#if defined(TARGET_I386)
- current_flags = env->hflags;
- current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
- current_cs_base = (target_ulong)env->segs[R_CS].base;
- current_pc = current_cs_base + env->eip;
-#else
-#error unsupported CPU
-#endif
+ cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
+ &current_flags);
}
#endif /* TARGET_HAS_PRECISE_SMC */
tb_phys_invalidate(tb, addr);
@@ -1355,19 +1314,14 @@ static void tb_invalidate_phys_page(target_phys_addr_t addr,
#endif
/* add the tb in the target page and protect it if necessary */
-#ifndef VBOX
static inline void tb_alloc_page(TranslationBlock *tb,
- unsigned int n, target_ulong page_addr)
-#else
-DECLINLINE(void) tb_alloc_page(TranslationBlock *tb,
- unsigned int n, target_ulong page_addr)
-#endif
+ unsigned int n, tb_page_addr_t page_addr)
{
PageDesc *p;
TranslationBlock *last_first_tb;
tb->page_addr[n] = page_addr;
- p = page_find_alloc(page_addr >> TARGET_PAGE_BITS);
+ p = page_find_alloc(page_addr >> TARGET_PAGE_BITS, 1);
tb->page_next[n] = p->first_tb;
last_first_tb = p->first_tb;
p->first_tb = (TranslationBlock *)((long)tb | n);
@@ -1393,7 +1347,6 @@ DECLINLINE(void) tb_alloc_page(TranslationBlock *tb,
continue;
prot |= p2->flags;
p2->flags &= ~PAGE_WRITE;
- page_get_flags(addr);
}
mprotect(g2h(page_addr), qemu_host_page_size,
(prot & PAGE_BITS) & ~PAGE_WRITE);
@@ -1421,11 +1374,7 @@ TranslationBlock *tb_alloc(target_ulong pc)
TranslationBlock *tb;
if (nb_tbs >= code_gen_max_blocks ||
-#ifndef VBOX
- (code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size)
-#else
- (code_gen_ptr - code_gen_buffer) >= (int)code_gen_buffer_max_size)
-#endif
+ (code_gen_ptr - code_gen_buffer) >= VBOX_ONLY((unsigned long))code_gen_buffer_max_size)
return NULL;
tb = &tbs[nb_tbs++];
tb->pc = pc;
@@ -1446,8 +1395,8 @@ void tb_free(TranslationBlock *tb)
/* add a new TB and link it to the physical page tables. phys_page2 is
(-1) to indicate that only one page contains the TB. */
-void tb_link_phys(TranslationBlock *tb,
- target_ulong phys_pc, target_ulong phys_page2)
+void tb_link_page(TranslationBlock *tb,
+ tb_page_addr_t phys_pc, tb_page_addr_t phys_page2)
{
unsigned int h;
TranslationBlock **ptb;
@@ -1517,11 +1466,7 @@ TranslationBlock *tb_find_pc(unsigned long tc_ptr)
static void tb_reset_jump_recursive(TranslationBlock *tb);
-#ifndef VBOX
static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
-#else
-DECLINLINE(void) tb_reset_jump_recursive2(TranslationBlock *tb, int n)
-#endif
{
TranslationBlock *tb1, *tb_next, **ptb;
unsigned int n1;
@@ -1567,9 +1512,16 @@ static void tb_reset_jump_recursive(TranslationBlock *tb)
}
#if defined(TARGET_HAS_ICE)
+#if defined(CONFIG_USER_ONLY)
+static void breakpoint_invalidate(CPUState *env, target_ulong pc)
+{
+ tb_invalidate_phys_page_range(pc, pc + 1, 0);
+}
+#else
static void breakpoint_invalidate(CPUState *env, target_ulong pc)
{
- target_ulong addr, pd;
+ target_phys_addr_t addr;
+ target_ulong pd;
ram_addr_t ram_addr;
PhysPageDesc *p;
@@ -1584,109 +1536,171 @@ static void breakpoint_invalidate(CPUState *env, target_ulong pc)
tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
}
#endif
+#endif /* TARGET_HAS_ICE */
+#if defined(CONFIG_USER_ONLY)
+void cpu_watchpoint_remove_all(CPUState *env, int mask)
+
+{
+}
+
+int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
+ int flags, CPUWatchpoint **watchpoint)
+{
+ return -ENOSYS;
+}
+#else
/* Add a watchpoint. */
-int cpu_watchpoint_insert(CPUState *env, target_ulong addr, int type)
+int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
+ int flags, CPUWatchpoint **watchpoint)
{
- int i;
+ target_ulong len_mask = ~(len - 1);
+ CPUWatchpoint *wp;
- for (i = 0; i < env->nb_watchpoints; i++) {
- if (addr == env->watchpoint[i].vaddr)
- return 0;
+ /* sanity checks: allow power-of-2 lengths, deny unaligned watchpoints */
+ if ((len != 1 && len != 2 && len != 4 && len != 8) || (addr & ~len_mask)) {
+ fprintf(stderr, "qemu: tried to set invalid watchpoint at "
+ TARGET_FMT_lx ", len=" TARGET_FMT_lu "\n", addr, len);
+#ifndef VBOX
+ return -EINVAL;
+#else
+ return VERR_INVALID_PARAMETER;
+#endif
}
- if (env->nb_watchpoints >= MAX_WATCHPOINTS)
- return -1;
+ wp = qemu_malloc(sizeof(*wp));
+
+ wp->vaddr = addr;
+ wp->len_mask = len_mask;
+ wp->flags = flags;
+
+ /* keep all GDB-injected watchpoints in front */
+ if (flags & BP_GDB)
+ QTAILQ_INSERT_HEAD(&env->watchpoints, wp, entry);
+ else
+ QTAILQ_INSERT_TAIL(&env->watchpoints, wp, entry);
- i = env->nb_watchpoints++;
- env->watchpoint[i].vaddr = addr;
- env->watchpoint[i].type = type;
tlb_flush_page(env, addr);
- /* FIXME: This flush is needed because of the hack to make memory ops
- terminate the TB. It can be removed once the proper IO trap and
- re-execute bits are in. */
- tb_flush(env);
- return i;
+
+ if (watchpoint)
+ *watchpoint = wp;
+ return 0;
}
-/* Remove a watchpoint. */
-int cpu_watchpoint_remove(CPUState *env, target_ulong addr)
+/* Remove a specific watchpoint. */
+int cpu_watchpoint_remove(CPUState *env, target_ulong addr, target_ulong len,
+ int flags)
{
- int i;
+ target_ulong len_mask = ~(len - 1);
+ CPUWatchpoint *wp;
- for (i = 0; i < env->nb_watchpoints; i++) {
- if (addr == env->watchpoint[i].vaddr) {
- env->nb_watchpoints--;
- env->watchpoint[i] = env->watchpoint[env->nb_watchpoints];
- tlb_flush_page(env, addr);
+ QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+ if (addr == wp->vaddr && len_mask == wp->len_mask
+ && flags == (wp->flags & ~BP_WATCHPOINT_HIT)) {
+ cpu_watchpoint_remove_by_ref(env, wp);
return 0;
}
}
- return -1;
+#ifndef VBOX
+ return -ENOENT;
+#else
+ return VERR_NOT_FOUND;
+#endif
}
-/* Remove all watchpoints. */
-void cpu_watchpoint_remove_all(CPUState *env) {
- int i;
+/* Remove a specific watchpoint by reference. */
+void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint)
+{
+ QTAILQ_REMOVE(&env->watchpoints, watchpoint, entry);
- for (i = 0; i < env->nb_watchpoints; i++) {
- tlb_flush_page(env, env->watchpoint[i].vaddr);
+ tlb_flush_page(env, watchpoint->vaddr);
+
+ qemu_free(watchpoint);
+}
+
+/* Remove all matching watchpoints. */
+void cpu_watchpoint_remove_all(CPUState *env, int mask)
+{
+ CPUWatchpoint *wp, *next;
+
+ QTAILQ_FOREACH_SAFE(wp, &env->watchpoints, entry, next) {
+ if (wp->flags & mask)
+ cpu_watchpoint_remove_by_ref(env, wp);
}
- env->nb_watchpoints = 0;
}
+#endif
-/* add a breakpoint. EXCP_DEBUG is returned by the CPU loop if a
- breakpoint is reached */
-int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
+/* Add a breakpoint. */
+int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,
+ CPUBreakpoint **breakpoint)
{
#if defined(TARGET_HAS_ICE)
- int i;
+ CPUBreakpoint *bp;
- for(i = 0; i < env->nb_breakpoints; i++) {
- if (env->breakpoints[i] == pc)
- return 0;
- }
+ bp = qemu_malloc(sizeof(*bp));
- if (env->nb_breakpoints >= MAX_BREAKPOINTS)
- return -1;
- env->breakpoints[env->nb_breakpoints++] = pc;
+ bp->pc = pc;
+ bp->flags = flags;
+
+ /* keep all GDB-injected breakpoints in front */
+ if (flags & BP_GDB)
+ QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
+ else
+ QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
breakpoint_invalidate(env, pc);
+
+ if (breakpoint)
+ *breakpoint = bp;
return 0;
#else
- return -1;
+ return -ENOSYS;
#endif
}
-/* remove all breakpoints */
-void cpu_breakpoint_remove_all(CPUState *env) {
+/* Remove a specific breakpoint. */
+int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags)
+{
#if defined(TARGET_HAS_ICE)
- int i;
- for(i = 0; i < env->nb_breakpoints; i++) {
- breakpoint_invalidate(env, env->breakpoints[i]);
+ CPUBreakpoint *bp;
+
+ QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+ if (bp->pc == pc && bp->flags == flags) {
+ cpu_breakpoint_remove_by_ref(env, bp);
+ return 0;
+ }
}
- env->nb_breakpoints = 0;
+# ifndef VBOX
+ return -ENOENT;
+# else
+ return VERR_NOT_FOUND;
+# endif
+#else
+ return -ENOSYS;
#endif
}
-/* remove a breakpoint */
-int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
+/* Remove a specific breakpoint by reference. */
+void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint)
{
#if defined(TARGET_HAS_ICE)
- int i;
- for(i = 0; i < env->nb_breakpoints; i++) {
- if (env->breakpoints[i] == pc)
- goto found;
- }
- return -1;
- found:
- env->nb_breakpoints--;
- if (i < env->nb_breakpoints)
- env->breakpoints[i] = env->breakpoints[env->nb_breakpoints];
+ QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
- breakpoint_invalidate(env, pc);
- return 0;
-#else
- return -1;
+ breakpoint_invalidate(env, breakpoint->pc);
+
+ qemu_free(breakpoint);
+#endif
+}
+
+/* Remove all matching breakpoints. */
+void cpu_breakpoint_remove_all(CPUState *env, int mask)
+{
+#if defined(TARGET_HAS_ICE)
+ CPUBreakpoint *bp, *next;
+
+ QTAILQ_FOREACH_SAFE(bp, &env->breakpoints, entry, next) {
+ if (bp->flags & mask)
+ cpu_breakpoint_remove_by_ref(env, bp);
+ }
#endif
}
@@ -1697,20 +1711,25 @@ void cpu_single_step(CPUState *env, int enabled)
#if defined(TARGET_HAS_ICE)
if (env->singlestep_enabled != enabled) {
env->singlestep_enabled = enabled;
- /* must flush all the translated code to avoid inconsistencies */
- /* XXX: only flush what is necessary */
- tb_flush(env);
+ if (kvm_enabled())
+ kvm_update_guest_debug(env, 0);
+ else {
+ /* must flush all the translated code to avoid inconsistencies */
+ /* XXX: only flush what is necessary */
+ tb_flush(env);
+ }
}
#endif
}
#ifndef VBOX
+
/* enable or disable low levels log */
void cpu_set_log(int log_flags)
{
loglevel = log_flags;
if (loglevel && !logfile) {
- logfile = fopen(logfilename, "w");
+ logfile = fopen(logfilename, log_append ? "a" : "w");
if (!logfile) {
perror(logfilename);
_exit(1);
@@ -1718,66 +1737,90 @@ void cpu_set_log(int log_flags)
#if !defined(CONFIG_SOFTMMU)
/* must avoid mmap() usage of glibc by setting a buffer "by hand" */
{
- static uint8_t logfile_buf[4096];
+ static char logfile_buf[4096];
setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
}
-#else
+#elif !defined(_WIN32)
+ /* Win32 doesn't support line-buffering and requires size >= 2 */
setvbuf(logfile, NULL, _IOLBF, 0);
#endif
+ log_append = 1;
+ }
+ if (!loglevel && logfile) {
+ fclose(logfile);
+ logfile = NULL;
}
}
void cpu_set_log_filename(const char *filename)
{
logfilename = strdup(filename);
+ if (logfile) {
+ fclose(logfile);
+ logfile = NULL;
+ }
+ cpu_set_log(loglevel);
}
+
#endif /* !VBOX */
-/* mask must never be zero, except for A20 change call */
-void cpu_interrupt(CPUState *env, int mask)
+static void cpu_unlink_tb(CPUState *env)
{
-#if !defined(USE_NPTL)
+ /* FIXME: TB unchaining isn't SMP safe. For now just ignore the
+ problem and hope the cpu will stop of its own accord. For userspace
+ emulation this often isn't actually as bad as it sounds. Often
+ signals are used primarily to interrupt blocking syscalls. */
TranslationBlock *tb;
static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED;
-#endif
+
+ spin_lock(&interrupt_lock);
+ tb = env->current_tb;
+ /* if the cpu is currently executing code, we must unlink it and
+ all the potentially executing TB */
+ if (tb) {
+ env->current_tb = NULL;
+ tb_reset_jump_recursive(tb);
+ }
+ spin_unlock(&interrupt_lock);
+}
+
+/* mask must never be zero, except for A20 change call */
+void cpu_interrupt(CPUState *env, int mask)
+{
int old_mask;
old_mask = env->interrupt_request;
-#ifdef VBOX
+#ifndef VBOX
+ env->interrupt_request |= mask;
+#else /* VBOX */
VM_ASSERT_EMT(env->pVM);
ASMAtomicOrS32((int32_t volatile *)&env->interrupt_request, mask);
-#else /* !VBOX */
- /* FIXME: This is probably not threadsafe. A different thread could
- be in the middle of a read-modify-write operation. */
- env->interrupt_request |= mask;
+#endif /* VBOX */
+
+#ifndef VBOX
+#ifndef CONFIG_USER_ONLY
+ /*
+ * If called from iothread context, wake the target cpu in
+ * case its halted.
+ */
+ if (!qemu_cpu_self(env)) {
+ qemu_cpu_kick(env);
+ return;
+ }
+#endif
#endif /* !VBOX */
-#if defined(USE_NPTL)
- /* FIXME: TB unchaining isn't SMP safe. For now just ignore the
- problem and hope the cpu will stop of its own accord. For userspace
- emulation this often isn't actually as bad as it sounds. Often
- signals are used primarily to interrupt blocking syscalls. */
-#else
+
if (use_icount) {
env->icount_decr.u16.high = 0xffff;
#ifndef CONFIG_USER_ONLY
- /* CPU_INTERRUPT_EXIT isn't a real interrupt. It just means
- an async event happened and we need to process it. */
if (!can_do_io(env)
- && (mask & ~(old_mask | CPU_INTERRUPT_EXIT)) != 0) {
+ && (mask & ~old_mask) != 0) {
cpu_abort(env, "Raised interrupt while not in I/O function");
}
#endif
} else {
- tb = env->current_tb;
- /* if the cpu is currently executing code, we must unlink it and
- all the potentially executing TB */
- if (tb && !testandset(&interrupt_lock)) {
- env->current_tb = NULL;
- tb_reset_jump_recursive(tb);
- resetlock(&interrupt_lock);
- }
+ cpu_unlink_tb(env);
}
-#endif
}
void cpu_reset_interrupt(CPUState *env, int mask)
@@ -1793,27 +1836,37 @@ void cpu_reset_interrupt(CPUState *env, int mask)
#endif /* !VBOX */
}
+void cpu_exit(CPUState *env)
+{
+ env->exit_request = 1;
+ cpu_unlink_tb(env);
+}
+
#ifndef VBOX
-CPULogItem cpu_log_items[] = {
+const CPULogItem cpu_log_items[] = {
{ CPU_LOG_TB_OUT_ASM, "out_asm",
"show generated host assembly code for each compiled TB" },
{ CPU_LOG_TB_IN_ASM, "in_asm",
"show target assembly code for each compiled TB" },
{ CPU_LOG_TB_OP, "op",
- "show micro ops for each compiled TB (only usable if 'in_asm' used)" },
-#ifdef TARGET_I386
+ "show micro ops for each compiled TB" },
{ CPU_LOG_TB_OP_OPT, "op_opt",
- "show micro ops after optimization for each compiled TB" },
+ "show micro ops "
+#ifdef TARGET_I386
+ "before eflags optimization and "
#endif
+ "after liveness analysis" },
{ CPU_LOG_INT, "int",
"show interrupts/exceptions in short format" },
{ CPU_LOG_EXEC, "exec",
"show trace before each executed TB (lots of logs)" },
{ CPU_LOG_TB_CPU, "cpu",
- "show CPU state before bloc translation" },
+ "show CPU state before block translation" },
#ifdef TARGET_I386
{ CPU_LOG_PCALL, "pcall",
"show protected mode far calls/returns/exceptions" },
+ { CPU_LOG_RESET, "cpu_reset",
+ "show CPU state before CPU resets" },
#endif
#ifdef DEBUG_IOPORT
{ CPU_LOG_IOPORT, "ioport",
@@ -1822,6 +1875,88 @@ CPULogItem cpu_log_items[] = {
{ 0, NULL, NULL },
};
+#ifndef CONFIG_USER_ONLY
+static QLIST_HEAD(memory_client_list, CPUPhysMemoryClient) memory_client_list
+ = QLIST_HEAD_INITIALIZER(memory_client_list);
+
+static void cpu_notify_set_memory(target_phys_addr_t start_addr,
+ ram_addr_t size,
+ ram_addr_t phys_offset)
+{
+ CPUPhysMemoryClient *client;
+ QLIST_FOREACH(client, &memory_client_list, list) {
+ client->set_memory(client, start_addr, size, phys_offset);
+ }
+}
+
+static int cpu_notify_sync_dirty_bitmap(target_phys_addr_t start,
+ target_phys_addr_t end)
+{
+ CPUPhysMemoryClient *client;
+ QLIST_FOREACH(client, &memory_client_list, list) {
+ int r = client->sync_dirty_bitmap(client, start, end);
+ if (r < 0)
+ return r;
+ }
+ return 0;
+}
+
+static int cpu_notify_migration_log(int enable)
+{
+ CPUPhysMemoryClient *client;
+ QLIST_FOREACH(client, &memory_client_list, list) {
+ int r = client->migration_log(client, enable);
+ if (r < 0)
+ return r;
+ }
+ return 0;
+}
+
+static void phys_page_for_each_1(CPUPhysMemoryClient *client,
+ int level, void **lp)
+{
+ int i;
+
+ if (*lp == NULL) {
+ return;
+ }
+ if (level == 0) {
+ PhysPageDesc *pd = *lp;
+ for (i = 0; i < L2_SIZE; ++i) {
+ if (pd[i].phys_offset != IO_MEM_UNASSIGNED) {
+ client->set_memory(client, pd[i].region_offset,
+ TARGET_PAGE_SIZE, pd[i].phys_offset);
+ }
+ }
+ } else {
+ void **pp = *lp;
+ for (i = 0; i < L2_SIZE; ++i) {
+ phys_page_for_each_1(client, level - 1, pp + i);
+ }
+ }
+}
+
+static void phys_page_for_each(CPUPhysMemoryClient *client)
+{
+ int i;
+ for (i = 0; i < P_L1_SIZE; ++i) {
+ phys_page_for_each_1(client, P_L1_SHIFT / L2_BITS - 1,
+ l1_phys_map + 1);
+ }
+}
+
+void cpu_register_phys_memory_client(CPUPhysMemoryClient *client)
+{
+ QLIST_INSERT_HEAD(&memory_client_list, client, list);
+ phys_page_for_each(client);
+}
+
+void cpu_unregister_phys_memory_client(CPUPhysMemoryClient *client)
+{
+ QLIST_REMOVE(client, list);
+}
+#endif
+
static int cmp1(const char *s1, int n, const char *s2)
{
if (strlen(s2) != n)
@@ -1832,7 +1967,7 @@ static int cmp1(const char *s1, int n, const char *s2)
/* takes a comma separated list of log masks. Return 0 if error. */
int cpu_str_to_log_mask(const char *str)
{
- CPULogItem *item;
+ const CPULogItem *item;
int mask;
const char *p, *p1;
@@ -1861,14 +1996,14 @@ int cpu_str_to_log_mask(const char *str)
}
return mask;
}
-#endif /* !VBOX */
-#ifndef VBOX /* VBOX: we have our own routine. */
void cpu_abort(CPUState *env, const char *fmt, ...)
{
va_list ap;
+ va_list ap2;
va_start(ap, fmt);
+ va_copy(ap2, ap);
fprintf(stderr, "qemu: fatal: ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
@@ -1877,32 +2012,69 @@ void cpu_abort(CPUState *env, const char *fmt, ...)
#else
cpu_dump_state(env, stderr, fprintf, 0);
#endif
+ if (qemu_log_enabled()) {
+ qemu_log("qemu: fatal: ");
+ qemu_log_vprintf(fmt, ap2);
+ qemu_log("\n");
+#ifdef TARGET_I386
+ log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
+#else
+ log_cpu_state(env, 0);
+#endif
+ qemu_log_flush();
+ qemu_log_close();
+ }
+ va_end(ap2);
va_end(ap);
+#if defined(CONFIG_USER_ONLY)
+ {
+ struct sigaction act;
+ sigfillset(&act.sa_mask);
+ act.sa_handler = SIG_DFL;
+ sigaction(SIGABRT, &act, NULL);
+ }
+#endif
abort();
}
-#endif /* !VBOX */
-#ifndef VBOX
CPUState *cpu_copy(CPUState *env)
{
CPUState *new_env = cpu_init(env->cpu_model_str);
- /* preserve chaining and index */
CPUState *next_cpu = new_env->next_cpu;
int cpu_index = new_env->cpu_index;
+#if defined(TARGET_HAS_ICE)
+ CPUBreakpoint *bp;
+ CPUWatchpoint *wp;
+#endif
+
memcpy(new_env, env, sizeof(CPUState));
+
+ /* Preserve chaining and index. */
new_env->next_cpu = next_cpu;
new_env->cpu_index = cpu_index;
+
+ /* Clone all break/watchpoints.
+ Note: Once we support ptrace with hw-debug register access, make sure
+ BP_CPU break/watchpoints are handled correctly on clone. */
+ QTAILQ_INIT(&env->breakpoints);
+ QTAILQ_INIT(&env->watchpoints);
+#if defined(TARGET_HAS_ICE)
+ QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+ cpu_breakpoint_insert(new_env, bp->pc, bp->flags, NULL);
+ }
+ QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+ cpu_watchpoint_insert(new_env, wp->vaddr, (~wp->len_mask) + 1,
+ wp->flags, NULL);
+ }
+#endif
+
return new_env;
}
-#endif
+#endif /* !VBOX */
#if !defined(CONFIG_USER_ONLY)
-#ifndef VBOX
static inline void tlb_flush_jmp_cache(CPUState *env, target_ulong addr)
-#else
-DECLINLINE(void) tlb_flush_jmp_cache(CPUState *env, target_ulong addr)
-#endif
{
unsigned int i;
@@ -1915,18 +2087,31 @@ DECLINLINE(void) tlb_flush_jmp_cache(CPUState *env, target_ulong addr)
i = tb_jmp_cache_hash_page(addr);
memset (&env->tb_jmp_cache[i], 0,
TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
-
#ifdef VBOX
+
/* inform raw mode about TLB page flush */
remR3FlushPage(env, addr);
#endif /* VBOX */
}
+static CPUTLBEntry s_cputlb_empty_entry = {
+ .addr_read = -1,
+ .addr_write = -1,
+ .addr_code = -1,
+ .addend = -1,
+};
+
/* NOTE: if flush_global is true, also flush global entries (not
implemented yet) */
void tlb_flush(CPUState *env, int flush_global)
{
int i;
+
+#ifdef VBOX
+ Assert(EMRemIsLockOwner(env->pVM));
+ ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_EXTERNAL_FLUSH_TLB);
+#endif
+
#if defined(DEBUG_TLB)
printf("tlb_flush:\n");
#endif
@@ -1935,53 +2120,25 @@ void tlb_flush(CPUState *env, int flush_global)
env->current_tb = NULL;
for(i = 0; i < CPU_TLB_SIZE; i++) {
- env->tlb_table[0][i].addr_read = -1;
- env->tlb_table[0][i].addr_write = -1;
- env->tlb_table[0][i].addr_code = -1;
- env->tlb_table[1][i].addr_read = -1;
- env->tlb_table[1][i].addr_write = -1;
- env->tlb_table[1][i].addr_code = -1;
-#if defined(VBOX) && !defined(REM_PHYS_ADDR_IN_TLB)
- env->phys_addends[0][i] = -1;
- env->phys_addends[1][i] = -1;
-#endif
-#if (NB_MMU_MODES >= 3)
- env->tlb_table[2][i].addr_read = -1;
- env->tlb_table[2][i].addr_write = -1;
- env->tlb_table[2][i].addr_code = -1;
-#if defined(VBOX) && !defined(REM_PHYS_ADDR_IN_TLB)
- env->phys_addends[2][i] = -1;
-#endif
-#if (NB_MMU_MODES == 4)
- env->tlb_table[3][i].addr_read = -1;
- env->tlb_table[3][i].addr_write = -1;
- env->tlb_table[3][i].addr_code = -1;
-#if defined(VBOX) && !defined(REM_PHYS_ADDR_IN_TLB)
- env->phys_addends[3][i] = -1;
-#endif
-#endif
-#endif
+ int mmu_idx;
+ for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
+ env->tlb_table[mmu_idx][i] = s_cputlb_empty_entry;
+ }
}
memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
+ env->tlb_flush_addr = -1;
+ env->tlb_flush_mask = 0;
+ tlb_flush_count++;
#ifdef VBOX
+
/* inform raw mode about TLB flush */
remR3FlushTLB(env, flush_global);
-#endif
-#ifdef USE_KQEMU
- if (env->kqemu_enabled) {
- kqemu_flush(env, flush_global);
- }
-#endif
- tlb_flush_count++;
+#endif /* VBOX */
}
-#ifndef VBOX
static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
-#else
-DECLINLINE(void) tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
-#endif
{
if (addr == (tlb_entry->addr_read &
(TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
@@ -1989,41 +2146,39 @@ DECLINLINE(void) tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
(TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
addr == (tlb_entry->addr_code &
(TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- tlb_entry->addr_read = -1;
- tlb_entry->addr_write = -1;
- tlb_entry->addr_code = -1;
+ *tlb_entry = s_cputlb_empty_entry;
}
}
void tlb_flush_page(CPUState *env, target_ulong addr)
{
int i;
+ int mmu_idx;
+ Assert(EMRemIsLockOwner(env->pVM));
#if defined(DEBUG_TLB)
printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr);
#endif
+ /* Check if we need to flush due to large pages. */
+ if ((addr & env->tlb_flush_mask) == env->tlb_flush_addr) {
+#if defined(DEBUG_TLB)
+ printf("tlb_flush_page: forced full flush ("
+ TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
+ env->tlb_flush_addr, env->tlb_flush_mask);
+#endif
+ tlb_flush(env, 1);
+ return;
+ }
/* must reset current TB so that interrupts cannot modify the
links while we are modifying them */
env->current_tb = NULL;
addr &= TARGET_PAGE_MASK;
i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- tlb_flush_entry(&env->tlb_table[0][i], addr);
- tlb_flush_entry(&env->tlb_table[1][i], addr);
-#if (NB_MMU_MODES >= 3)
- tlb_flush_entry(&env->tlb_table[2][i], addr);
-#if (NB_MMU_MODES == 4)
- tlb_flush_entry(&env->tlb_table[3][i], addr);
-#endif
-#endif
+ for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++)
+ tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr);
tlb_flush_jmp_cache(env, addr);
-
-#ifdef USE_KQEMU
- if (env->kqemu_enabled) {
- kqemu_flush_page(env, addr);
- }
-#endif
}
/* update the TLBs so that writes to code in the virtual page 'addr'
@@ -2036,7 +2191,7 @@ static void tlb_protect_code(ram_addr_t ram_addr)
#if defined(VBOX) && defined(REM_MONITOR_CODE_PAGES)
/** @todo Retest this? This function has changed... */
remR3ProtectCode(cpu_single_env, ram_addr);
-#endif
+#endif /* VBOX */
}
/* update the TLB so that writes in physical page 'phys_addr' are no longer
@@ -2044,41 +2199,33 @@ static void tlb_protect_code(ram_addr_t ram_addr)
static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
target_ulong vaddr)
{
-#ifdef VBOX
- if (RT_LIKELY((ram_addr >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
-#endif
- phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] |= CODE_DIRTY_FLAG;
+ cpu_physical_memory_set_dirty_flags(ram_addr, CODE_DIRTY_FLAG);
}
-#ifndef VBOX
static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
unsigned long start, unsigned long length)
-#else
-DECLINLINE(void) tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
- unsigned long start, unsigned long length)
-#endif
{
unsigned long addr;
-
#ifdef VBOX
+
if (start & 3)
return;
-#endif
+#endif /* VBOX */
if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
if ((addr - start) < length) {
- tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
+ tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | TLB_NOTDIRTY;
}
}
}
+/* Note: start and end must be within the same ram block. */
void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
int dirty_flags)
{
CPUState *env;
unsigned long length, start1;
- int i, mask, len;
- uint8_t *p;
+ int i;
start &= TARGET_PAGE_MASK;
end = TARGET_PAGE_ALIGN(end);
@@ -2086,64 +2233,63 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
length = end - start;
if (length == 0)
return;
- len = length >> TARGET_PAGE_BITS;
-#ifdef USE_KQEMU
- /* XXX: should not depend on cpu context */
- env = first_cpu;
- if (env->kqemu_enabled) {
- ram_addr_t addr;
- addr = start;
- for(i = 0; i < len; i++) {
- kqemu_set_notdirty(env, addr);
- addr += TARGET_PAGE_SIZE;
- }
- }
-#endif
- mask = ~dirty_flags;
- p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
-#ifdef VBOX
- if (RT_LIKELY((start >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
-#endif
- for(i = 0; i < len; i++)
- p[i] &= mask;
+ cpu_physical_memory_mask_dirty_range(start, length, dirty_flags);
/* we modify the TLB cache so that the dirty bit will be set again
when accessing the range */
#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
start1 = start;
#elif !defined(VBOX)
- start1 = start + (unsigned long)phys_ram_base;
+ start1 = (unsigned long)qemu_get_ram_ptr(start);
+ /* Chek that we don't span multiple blocks - this breaks the
+ address comparisons below. */
+ if ((unsigned long)qemu_get_ram_ptr(end - 1) - start1
+ != (end - 1) - start) {
+ abort();
+ }
#else
start1 = (unsigned long)remR3TlbGCPhys2Ptr(first_cpu, start, 1 /*fWritable*/); /** @todo page replacing (sharing or read only) may cause trouble, fix interface/whatever. */
#endif
+
for(env = first_cpu; env != NULL; env = env->next_cpu) {
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_reset_dirty_range(&env->tlb_table[0][i], start1, length);
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_reset_dirty_range(&env->tlb_table[1][i], start1, length);
-#if (NB_MMU_MODES >= 3)
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_reset_dirty_range(&env->tlb_table[2][i], start1, length);
-#if (NB_MMU_MODES == 4)
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_reset_dirty_range(&env->tlb_table[3][i], start1, length);
-#endif
-#endif
+ int mmu_idx;
+ for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
+ for(i = 0; i < CPU_TLB_SIZE; i++)
+ tlb_reset_dirty_range(&env->tlb_table[mmu_idx][i],
+ start1, length);
+ }
}
}
#ifndef VBOX
+
int cpu_physical_memory_set_dirty_tracking(int enable)
{
+ int ret = 0;
in_migration = enable;
- return 0;
+ ret = cpu_notify_migration_log(!!enable);
+ return ret;
}
int cpu_physical_memory_get_dirty_tracking(void)
{
return in_migration;
}
-#endif
+
+#endif /* !VBOX */
+
+int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
+ target_phys_addr_t end_addr)
+{
+#ifndef VBOX
+ int ret;
+
+ ret = cpu_notify_sync_dirty_bitmap(start_addr, end_addr);
+ return ret;
+#else /* VBOX */
+ return 0;
+#endif /* VBOX */
+}
#if defined(VBOX) && !defined(REM_PHYS_ADDR_IN_TLB)
DECLINLINE(void) tlb_update_dirty(CPUTLBEntry *tlb_entry, target_phys_addr_t phys_addend)
@@ -2152,14 +2298,15 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
#endif
{
ram_addr_t ram_addr;
+ void *p;
if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
- /* RAM case */
#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
#elif !defined(VBOX)
- ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) +
- tlb_entry->addend - (unsigned long)phys_ram_base;
+ p = (void *)(unsigned long)((tlb_entry->addr_write & TARGET_PAGE_MASK)
+ + tlb_entry->addend);
+ ram_addr = qemu_ram_addr_from_host(p);
#else
Assert(phys_addend != -1);
ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + phys_addend;
@@ -2174,92 +2321,83 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
void cpu_tlb_update_dirty(CPUState *env)
{
int i;
+ int mmu_idx;
+ for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
+ for(i = 0; i < CPU_TLB_SIZE; i++)
#if defined(VBOX) && !defined(REM_PHYS_ADDR_IN_TLB)
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[0][i], env->phys_addends[0][i]);
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[1][i], env->phys_addends[1][i]);
-#if (NB_MMU_MODES >= 3)
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[2][i], env->phys_addends[2][i]);
-#if (NB_MMU_MODES == 4)
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[3][i], env->phys_addends[3][i]);
-#endif
-#endif
-#else /* VBOX */
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[0][i]);
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[1][i]);
-#if (NB_MMU_MODES >= 3)
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[2][i]);
-#if (NB_MMU_MODES == 4)
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[3][i]);
-#endif
+ tlb_update_dirty(&env->tlb_table[mmu_idx][i], env->phys_addends[mmu_idx][i]);
+#else
+ tlb_update_dirty(&env->tlb_table[mmu_idx][i]);
#endif
-#endif /* VBOX */
+ }
}
-#ifndef VBOX
static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr)
-#else
-DECLINLINE(void) tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr)
-#endif
{
if (tlb_entry->addr_write == (vaddr | TLB_NOTDIRTY))
tlb_entry->addr_write = vaddr;
}
-
-/* update the TLB corresponding to virtual page vaddr and phys addr
- addr so that it is no longer dirty */
-#ifndef VBOX
-static inline void tlb_set_dirty(CPUState *env,
- unsigned long addr, target_ulong vaddr)
-#else
-DECLINLINE(void) tlb_set_dirty(CPUState *env,
- unsigned long addr, target_ulong vaddr)
-#endif
+/* update the TLB corresponding to virtual page vaddr
+ so that it is no longer dirty */
+static inline void tlb_set_dirty(CPUState *env, target_ulong vaddr)
{
int i;
+ int mmu_idx;
- addr &= TARGET_PAGE_MASK;
+ vaddr &= TARGET_PAGE_MASK;
i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- tlb_set_dirty1(&env->tlb_table[0][i], addr);
- tlb_set_dirty1(&env->tlb_table[1][i], addr);
-#if (NB_MMU_MODES >= 3)
- tlb_set_dirty1(&env->tlb_table[2][i], vaddr);
-#if (NB_MMU_MODES == 4)
- tlb_set_dirty1(&env->tlb_table[3][i], vaddr);
-#endif
-#endif
+ for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++)
+ tlb_set_dirty1(&env->tlb_table[mmu_idx][i], vaddr);
}
-/* add a new TLB entry. At most one entry for a given virtual address
- is permitted. Return 0 if OK or 2 if the page could not be mapped
- (can only happen in non SOFTMMU mode for I/O pages or pages
- conflicting with the host address space). */
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int mmu_idx, int is_softmmu)
+/* Our TLB does not support large pages, so remember the area covered by
+ large pages and trigger a full TLB flush if these are invalidated. */
+static void tlb_add_large_page(CPUState *env, target_ulong vaddr,
+ target_ulong size)
+{
+ target_ulong mask = ~(size - 1);
+
+ if (env->tlb_flush_addr == (target_ulong)-1) {
+ env->tlb_flush_addr = vaddr & mask;
+ env->tlb_flush_mask = mask;
+ return;
+ }
+ /* Extend the existing region to include the new page.
+ This is a compromise between unnecessary flushes and the cost
+ of maintaining a full variable size TLB. */
+ mask &= env->tlb_flush_mask;
+ while (((env->tlb_flush_addr ^ vaddr) & mask) != 0) {
+ mask <<= 1;
+ }
+ env->tlb_flush_addr &= mask;
+ env->tlb_flush_mask = mask;
+}
+
+/* Add a new TLB entry. At most one entry for a given virtual address
+ is permitted. Only a single TARGET_PAGE_SIZE region is mapped, the
+ supplied size is only used by tlb_flush_page. */
+void tlb_set_page(CPUState *env, target_ulong vaddr,
+ target_phys_addr_t paddr, int prot,
+ int mmu_idx, target_ulong size)
{
PhysPageDesc *p;
unsigned long pd;
unsigned int index;
target_ulong address;
target_ulong code_address;
- target_phys_addr_t addend;
- int ret;
+ unsigned long addend;
CPUTLBEntry *te;
- int i;
+ CPUWatchpoint *wp;
target_phys_addr_t iotlb;
#if defined(VBOX) && !defined(REM_PHYS_ADDR_IN_TLB)
int read_mods = 0, write_mods = 0, code_mods = 0;
#endif
+ assert(size >= TARGET_PAGE_SIZE);
+ if (size != TARGET_PAGE_SIZE) {
+ tlb_add_large_page(env, vaddr, size);
+ }
p = phys_page_find(paddr >> TARGET_PAGE_BITS);
if (!p) {
pd = IO_MEM_UNASSIGNED;
@@ -2267,11 +2405,10 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
pd = p->phys_offset;
}
#if defined(DEBUG_TLB)
- printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n",
- vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd);
+ printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d size=" TARGET_FMT_lx " pd=0x%08lx\n",
+ vaddr, (int)paddr, prot, mmu_idx, size, pd);
#endif
- ret = 0;
address = vaddr;
if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
/* IO memory case (romd handled later) */
@@ -2280,13 +2417,11 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
addend = pd & TARGET_PAGE_MASK;
#elif !defined(VBOX)
- addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK);
+ addend = (unsigned long)qemu_get_ram_ptr(pd & TARGET_PAGE_MASK);
#else
/** @todo this is racing the phys_page_find call above since it may register
* a new chunk of memory... */
- addend = (unsigned long)remR3TlbGCPhys2Ptr(env,
- pd & TARGET_PAGE_MASK,
- !!(prot & PAGE_WRITE));
+ addend = (unsigned long)remR3TlbGCPhys2Ptr(env, pd & TARGET_PAGE_MASK, !!(prot & PAGE_WRITE));
#endif
if ((pd & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) {
@@ -2297,18 +2432,23 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
else
iotlb |= IO_MEM_ROM;
} else {
- /* IO handlers are currently passed a phsical address.
+ /* IO handlers are currently passed a physical address.
It would be nice to pass an offset from the base address
of that region. This would avoid having to special case RAM,
and avoid full address decoding in every device.
We can't use the high bits of pd for this because
IO_MEM_ROMD uses these as a ram address. */
- iotlb = (pd & ~TARGET_PAGE_MASK) + paddr;
+ iotlb = (pd & ~TARGET_PAGE_MASK);
+ if (p) {
+ iotlb += p->region_offset;
+ } else {
+ iotlb += paddr;
+ }
}
code_address = address;
-
#if defined(VBOX) && !defined(REM_PHYS_ADDR_IN_TLB)
+
if (addend & 0x3)
{
if (addend & 0x2)
@@ -2331,16 +2471,18 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
iotlb = env->pVM->rem.s.iHandlerMemType + paddr;
addend &= ~(target_ulong)0x3;
}
-#endif
+#endif
/* Make accesses to pages with watchpoints go via the
watchpoint trap routines. */
- for (i = 0; i < env->nb_watchpoints; i++) {
- if (vaddr == (env->watchpoint[i].vaddr & TARGET_PAGE_MASK)) {
- iotlb = io_mem_watch + paddr;
- /* TODO: The memory case can be optimized by not trapping
- reads of pages with a write breakpoint. */
- address |= TLB_MMIO;
+ QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+ if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) {
+ /* Avoid trapping reads of pages with a write breakpoint. */
+ if ((prot & PAGE_WRITE) || (wp->flags & BP_MEM_READ)) {
+ iotlb = io_mem_watch + paddr;
+ address |= TLB_MMIO;
+ break;
+ }
}
}
@@ -2389,57 +2531,7 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
/* inform raw mode about TLB page change */
remR3FlushPage(env, vaddr);
#endif
- return ret;
-}
-#if 0
-/* called from signal handler: invalidate the code and unprotect the
- page. Return TRUE if the fault was successfully handled. */
-int page_unprotect(target_ulong addr, unsigned long pc, void *puc)
-{
-#if !defined(CONFIG_SOFTMMU)
- VirtPageDesc *vp;
-
-#if defined(DEBUG_TLB)
- printf("page_unprotect: addr=0x%08x\n", addr);
-#endif
- addr &= TARGET_PAGE_MASK;
-
- /* if it is not mapped, no need to worry here */
- if (addr >= MMAP_AREA_END)
- return 0;
- vp = virt_page_find(addr >> TARGET_PAGE_BITS);
- if (!vp)
- return 0;
- /* NOTE: in this case, validate_tag is _not_ tested as it
- validates only the code TLB */
- if (vp->valid_tag != virt_valid_tag)
- return 0;
- if (!(vp->prot & PAGE_WRITE))
- return 0;
-#if defined(DEBUG_TLB)
- printf("page_unprotect: addr=0x%08x phys_addr=0x%08x prot=%x\n",
- addr, vp->phys_addr, vp->prot);
-#endif
- if (mprotect((void *)addr, TARGET_PAGE_SIZE, vp->prot) < 0)
- cpu_abort(cpu_single_env, "error mprotect addr=0x%lx prot=%d\n",
- (unsigned long)addr, vp->prot);
- /* set the dirty bit */
- phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 0xff;
- /* flush the code inside */
- tb_invalidate_phys_page(vp->phys_addr, pc, puc);
- return 1;
-#elif defined(VBOX)
- addr &= TARGET_PAGE_MASK;
-
- /* if it is not mapped, no need to worry here */
- if (addr >= MMAP_AREA_END)
- return 0;
- return 1;
-#else
- return 0;
-#endif
}
-#endif /* 0 */
#else
@@ -2451,57 +2543,116 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
{
}
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int mmu_idx, int is_softmmu)
+/*
+ * Walks guest process memory "regions" one by one
+ * and calls callback function 'fn' for each region.
+ */
+
+struct walk_memory_regions_data
+{
+ walk_memory_regions_fn fn;
+ void *priv;
+ unsigned long start;
+ int prot;
+};
+
+static int walk_memory_regions_end(struct walk_memory_regions_data *data,
+ abi_ulong end, int new_prot)
{
+ if (data->start != -1ul) {
+ int rc = data->fn(data->priv, data->start, end, data->prot);
+ if (rc != 0) {
+ return rc;
+ }
+ }
+
+ data->start = (new_prot ? end : -1ul);
+ data->prot = new_prot;
+
return 0;
}
-#ifndef VBOX
-/* dump memory mappings */
-void page_dump(FILE *f)
+static int walk_memory_regions_1(struct walk_memory_regions_data *data,
+ abi_ulong base, int level, void **lp)
{
- unsigned long start, end;
- int i, j, prot, prot1;
- PageDesc *p;
+ abi_ulong pa;
+ int i, rc;
- fprintf(f, "%-8s %-8s %-8s %s\n",
- "start", "end", "size", "prot");
- start = -1;
- end = -1;
- prot = 0;
- for(i = 0; i <= L1_SIZE; i++) {
- if (i < L1_SIZE)
- p = l1_map[i];
- else
- p = NULL;
- for(j = 0;j < L2_SIZE; j++) {
- if (!p)
- prot1 = 0;
- else
- prot1 = p[j].flags;
- if (prot1 != prot) {
- end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
- if (start != -1) {
- fprintf(f, "%08lx-%08lx %08lx %c%c%c\n",
- start, end, end - start,
- prot & PAGE_READ ? 'r' : '-',
- prot & PAGE_WRITE ? 'w' : '-',
- prot & PAGE_EXEC ? 'x' : '-');
+ if (*lp == NULL) {
+ return walk_memory_regions_end(data, base, 0);
+ }
+
+ if (level == 0) {
+ PageDesc *pd = *lp;
+ for (i = 0; i < L2_SIZE; ++i) {
+ int prot = pd[i].flags;
+
+ pa = base | (i << TARGET_PAGE_BITS);
+ if (prot != data->prot) {
+ rc = walk_memory_regions_end(data, pa, prot);
+ if (rc != 0) {
+ return rc;
}
- if (prot1 != 0)
- start = end;
- else
- start = -1;
- prot = prot1;
}
- if (!p)
- break;
+ }
+ } else {
+ void **pp = *lp;
+ for (i = 0; i < L2_SIZE; ++i) {
+ pa = base | ((abi_ulong)i <<
+ (TARGET_PAGE_BITS + L2_BITS * level));
+ rc = walk_memory_regions_1(data, pa, level - 1, pp + i);
+ if (rc != 0) {
+ return rc;
+ }
}
}
+
+ return 0;
+}
+
+int walk_memory_regions(void *priv, walk_memory_regions_fn fn)
+{
+ struct walk_memory_regions_data data;
+ unsigned long i;
+
+ data.fn = fn;
+ data.priv = priv;
+ data.start = -1ul;
+ data.prot = 0;
+
+ for (i = 0; i < V_L1_SIZE; i++) {
+ int rc = walk_memory_regions_1(&data, (abi_ulong)i << V_L1_SHIFT,
+ V_L1_SHIFT / L2_BITS - 1, l1_map + i);
+ if (rc != 0) {
+ return rc;
+ }
+ }
+
+ return walk_memory_regions_end(&data, 0, 0);
+}
+
+static int dump_region(void *priv, abi_ulong start,
+ abi_ulong end, unsigned long prot)
+{
+ FILE *f = (FILE *)priv;
+
+ (void) fprintf(f, TARGET_ABI_FMT_lx"-"TARGET_ABI_FMT_lx
+ " "TARGET_ABI_FMT_lx" %c%c%c\n",
+ start, end, end - start,
+ ((prot & PAGE_READ) ? 'r' : '-'),
+ ((prot & PAGE_WRITE) ? 'w' : '-'),
+ ((prot & PAGE_EXEC) ? 'x' : '-'));
+
+ return (0);
+}
+
+/* dump memory mappings */
+void page_dump(FILE *f)
+{
+ (void) fprintf(f, "%-8s %-8s %-8s %s\n",
+ "start", "end", "size", "prot");
+ walk_memory_regions(f, dump_region);
}
-#endif /* !VBOX */
int page_get_flags(target_ulong address)
{
@@ -2513,26 +2664,38 @@ int page_get_flags(target_ulong address)
return p->flags;
}
-/* modify the flags of a page and invalidate the code if
- necessary. The flag PAGE_WRITE_ORG is positioned automatically
- depending on PAGE_WRITE */
+/* Modify the flags of a page and invalidate the code if necessary.
+ The flag PAGE_WRITE_ORG is positioned automatically depending
+ on PAGE_WRITE. The mmap_lock should already be held. */
void page_set_flags(target_ulong start, target_ulong end, int flags)
{
- PageDesc *p;
- target_ulong addr;
+ target_ulong addr, len;
+
+ /* This function should never be called with addresses outside the
+ guest address space. If this assert fires, it probably indicates
+ a missing call to h2g_valid. */
+#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
+ assert(end < ((abi_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
+#endif
+ assert(start < end);
start = start & TARGET_PAGE_MASK;
end = TARGET_PAGE_ALIGN(end);
- if (flags & PAGE_WRITE)
+
+ if (flags & PAGE_WRITE) {
flags |= PAGE_WRITE_ORG;
+ }
+
#ifdef VBOX
AssertMsgFailed(("We shouldn't be here, and if we should, we must have an env to do the proper locking!\n"));
#endif
- spin_lock(&tb_lock);
- for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
- p = page_find_alloc(addr >> TARGET_PAGE_BITS);
- /* if the write protection is set, then we invalidate the code
- inside */
+ for (addr = start, len = end - start;
+ len != 0;
+ len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
+ PageDesc *p = page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
+
+ /* If the write protection bit is set, then we invalidate
+ the code inside. */
if (!(p->flags & PAGE_WRITE) &&
(flags & PAGE_WRITE) &&
p->first_tb) {
@@ -2540,7 +2703,6 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
}
p->flags = flags;
}
- spin_unlock(&tb_lock);
}
int page_check_range(target_ulong start, target_ulong len, int flags)
@@ -2549,13 +2711,27 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
target_ulong end;
target_ulong addr;
+ /* This function should never be called with addresses outside the
+ guest address space. If this assert fires, it probably indicates
+ a missing call to h2g_valid. */
+#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
+ assert(start < ((abi_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
+#endif
+
+ if (len == 0) {
+ return 0;
+ }
+ if (start + len - 1 < start) {
+ /* We've wrapped around. */
+ return -1;
+ }
+
end = TARGET_PAGE_ALIGN(start+len); /* must do before we loose bits in the next step */
start = start & TARGET_PAGE_MASK;
- if( end < start )
- /* we've wrapped around */
- return -1;
- for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
+ for (addr = start, len = end - start;
+ len != 0;
+ len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
p = page_find(addr >> TARGET_PAGE_BITS);
if( !p )
return -1;
@@ -2583,8 +2759,8 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
page. Return TRUE if the fault was successfully handled. */
int page_unprotect(target_ulong address, unsigned long pc, void *puc)
{
- unsigned int page_index, prot, pindex;
- PageDesc *p, *p1;
+ unsigned int prot;
+ PageDesc *p;
target_ulong host_start, host_end, addr;
/* Technically this isn't safe inside a signal handler. However we
@@ -2592,37 +2768,36 @@ int page_unprotect(target_ulong address, unsigned long pc, void *puc)
practice it seems to be ok. */
mmap_lock();
- host_start = address & qemu_host_page_mask;
- page_index = host_start >> TARGET_PAGE_BITS;
- p1 = page_find(page_index);
- if (!p1) {
+ p = page_find(address >> TARGET_PAGE_BITS);
+ if (!p) {
mmap_unlock();
return 0;
}
- host_end = host_start + qemu_host_page_size;
- p = p1;
- prot = 0;
- for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) {
- prot |= p->flags;
- p++;
- }
+
/* if the page was really writable, then we change its
protection back to writable */
- if (prot & PAGE_WRITE_ORG) {
- pindex = (address - host_start) >> TARGET_PAGE_BITS;
- if (!(p1[pindex].flags & PAGE_WRITE)) {
- mprotect((void *)g2h(host_start), qemu_host_page_size,
- (prot & PAGE_BITS) | PAGE_WRITE);
- p1[pindex].flags |= PAGE_WRITE;
+ if ((p->flags & PAGE_WRITE_ORG) && !(p->flags & PAGE_WRITE)) {
+ host_start = address & qemu_host_page_mask;
+ host_end = host_start + qemu_host_page_size;
+
+ prot = 0;
+ for (addr = host_start ; addr < host_end ; addr += TARGET_PAGE_SIZE) {
+ p = page_find(addr >> TARGET_PAGE_BITS);
+ p->flags |= PAGE_WRITE;
+ prot |= p->flags;
+
/* and since the content will be modified, we must invalidate
the corresponding translated code. */
- tb_invalidate_phys_page(address, pc, puc);
+ tb_invalidate_phys_page(addr, pc, puc);
#ifdef DEBUG_TB_CHECK
- tb_invalidate_check(address);
+ tb_invalidate_check(addr);
#endif
- mmap_unlock();
- return 1;
}
+ mprotect((void *)g2h(host_start), qemu_host_page_size,
+ prot & PAGE_BITS);
+
+ mmap_unlock();
+ return 1;
}
mmap_unlock();
return 0;
@@ -2635,10 +2810,19 @@ static inline void tlb_set_dirty(CPUState *env,
#endif /* defined(CONFIG_USER_ONLY) */
#if !defined(CONFIG_USER_ONLY)
+
+#define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
+typedef struct subpage_t {
+ target_phys_addr_t base;
+ ram_addr_t sub_io_index[TARGET_PAGE_SIZE];
+ ram_addr_t region_offset[TARGET_PAGE_SIZE];
+} subpage_t;
+
static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
- ram_addr_t memory);
-static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
- ram_addr_t orig_memory);
+ ram_addr_t memory, ram_addr_t region_offset);
+static subpage_t *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
+ ram_addr_t orig_memory,
+ ram_addr_t region_offset);
#define CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, \
need_subpage) \
do { \
@@ -2659,27 +2843,33 @@ static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
} \
} while (0)
-
-/* register physical memory. 'size' must be a multiple of the target
- page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
- io memory page */
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
- unsigned long size,
- unsigned long phys_offset)
+/* register physical memory.
+ For RAM, 'size' must be a multiple of the target page size.
+ If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
+ io memory page. The address used when calling the IO function is
+ the offset from the start of the region, plus region_offset. Both
+ start_addr and region_offset are rounded down to a page boundary
+ before calculating this offset. This should not be a problem unless
+ the low bits of start_addr and region_offset differ. */
+void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
+ ram_addr_t size,
+ ram_addr_t phys_offset,
+ ram_addr_t region_offset)
{
target_phys_addr_t addr, end_addr;
PhysPageDesc *p;
CPUState *env;
ram_addr_t orig_size = size;
- void *subpage;
+ subpage_t *subpage;
-#ifdef USE_KQEMU
- /* XXX: should not depend on cpu context */
- env = first_cpu;
- if (env->kqemu_enabled) {
- kqemu_set_phys_mem(start_addr, size, phys_offset);
+#ifndef VBOX
+ cpu_notify_set_memory(start_addr, size, phys_offset);
+#endif /* !VBOX */
+
+ if (phys_offset == IO_MEM_UNASSIGNED) {
+ region_offset = start_addr;
}
-#endif
+ region_offset &= TARGET_PAGE_MASK;
size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
end_addr = start_addr + (target_phys_addr_t)size;
for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
@@ -2691,53 +2881,72 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2,
need_subpage);
- if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) {
+ if (need_subpage) {
if (!(orig_memory & IO_MEM_SUBPAGE)) {
subpage = subpage_init((addr & TARGET_PAGE_MASK),
- &p->phys_offset, orig_memory);
+ &p->phys_offset, orig_memory,
+ p->region_offset);
} else {
subpage = io_mem_opaque[(orig_memory & ~TARGET_PAGE_MASK)
>> IO_MEM_SHIFT];
}
- subpage_register(subpage, start_addr2, end_addr2, phys_offset);
+ subpage_register(subpage, start_addr2, end_addr2, phys_offset,
+ region_offset);
+ p->region_offset = 0;
} else {
p->phys_offset = phys_offset;
- if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
- (phys_offset & IO_MEM_ROMD))
+ if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
+ (phys_offset & IO_MEM_ROMD))
phys_offset += TARGET_PAGE_SIZE;
}
} else {
p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
p->phys_offset = phys_offset;
- if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
- (phys_offset & IO_MEM_ROMD))
+ p->region_offset = region_offset;
+ if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
+ (phys_offset & IO_MEM_ROMD)) {
phys_offset += TARGET_PAGE_SIZE;
- else {
+ } else {
target_phys_addr_t start_addr2, end_addr2;
int need_subpage = 0;
CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr,
end_addr2, need_subpage);
- if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) {
+ if (need_subpage) {
subpage = subpage_init((addr & TARGET_PAGE_MASK),
- &p->phys_offset, IO_MEM_UNASSIGNED);
+ &p->phys_offset, IO_MEM_UNASSIGNED,
+ addr & TARGET_PAGE_MASK);
subpage_register(subpage, start_addr2, end_addr2,
- phys_offset);
+ phys_offset, region_offset);
+ p->region_offset = 0;
}
}
}
+ region_offset += TARGET_PAGE_SIZE;
}
+
/* since each CPU stores ram addresses in its TLB cache, we must
reset the modified entries */
+#ifndef VBOX
/* XXX: slow ! */
for(env = first_cpu; env != NULL; env = env->next_cpu) {
tlb_flush(env, 1);
}
+#else
+ /* We have one thread per CPU, so, one of the other EMTs might be executing
+ code right now and flushing the TLB may crash it. */
+ env = first_cpu;
+ if (EMRemIsLockOwner(env->pVM))
+ tlb_flush(env, 1);
+ else
+ ASMAtomicOrS32((int32_t volatile *)&env->interrupt_request,
+ CPU_INTERRUPT_EXTERNAL_FLUSH_TLB);
+#endif
}
/* XXX: temporary until new memory mapping API */
-uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr)
+ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr)
{
PhysPageDesc *p;
@@ -2748,32 +2957,350 @@ uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr)
}
#ifndef VBOX
-/* XXX: better than nothing */
-ram_addr_t qemu_ram_alloc(ram_addr_t size)
+
+void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
{
- ram_addr_t addr;
- if ((phys_ram_alloc_offset + size) > phys_ram_size) {
- fprintf(stderr, "Not enough memory (requested_size = %" PRIu64 ", max memory = %" PRIu64 ")\n",
- (uint64_t)size, (uint64_t)phys_ram_size);
- abort();
+ if (kvm_enabled())
+ kvm_coalesce_mmio_region(addr, size);
+}
+
+void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
+{
+ if (kvm_enabled())
+ kvm_uncoalesce_mmio_region(addr, size);
+}
+
+void qemu_flush_coalesced_mmio_buffer(void)
+{
+ if (kvm_enabled())
+ kvm_flush_coalesced_mmio_buffer();
+}
+
+#if defined(__linux__) && !defined(TARGET_S390X)
+
+#include <sys/vfs.h>
+
+#define HUGETLBFS_MAGIC 0x958458f6
+
+static long gethugepagesize(const char *path)
+{
+ struct statfs fs;
+ int ret;
+
+ do {
+ ret = statfs(path, &fs);
+ } while (ret != 0 && errno == EINTR);
+
+ if (ret != 0) {
+ perror(path);
+ return 0;
}
- addr = phys_ram_alloc_offset;
- phys_ram_alloc_offset = TARGET_PAGE_ALIGN(phys_ram_alloc_offset + size);
- return addr;
+
+ if (fs.f_type != HUGETLBFS_MAGIC)
+ fprintf(stderr, "Warning: path not on HugeTLBFS: %s\n", path);
+
+ return fs.f_bsize;
}
-void qemu_ram_free(ram_addr_t addr)
+static void *file_ram_alloc(RAMBlock *block,
+ ram_addr_t memory,
+ const char *path)
{
+ char *filename;
+ void *area;
+ int fd;
+#ifdef MAP_POPULATE
+ int flags;
+#endif
+ unsigned long hpagesize;
+
+ hpagesize = gethugepagesize(path);
+ if (!hpagesize) {
+ return NULL;
+ }
+
+ if (memory < hpagesize) {
+ return NULL;
+ }
+
+ if (kvm_enabled() && !kvm_has_sync_mmu()) {
+ fprintf(stderr, "host lacks kvm mmu notifiers, -mem-path unsupported\n");
+ return NULL;
+ }
+
+ if (asprintf(&filename, "%s/qemu_back_mem.XXXXXX", path) == -1) {
+ return NULL;
+ }
+
+ fd = mkstemp(filename);
+ if (fd < 0) {
+ perror("unable to create backing store for hugepages");
+ free(filename);
+ return NULL;
+ }
+ unlink(filename);
+ free(filename);
+
+ memory = (memory+hpagesize-1) & ~(hpagesize-1);
+
+ /*
+ * ftruncate is not supported by hugetlbfs in older
+ * hosts, so don't bother bailing out on errors.
+ * If anything goes wrong with it under other filesystems,
+ * mmap will fail.
+ */
+ if (ftruncate(fd, memory))
+ perror("ftruncate");
+
+#ifdef MAP_POPULATE
+ /* NB: MAP_POPULATE won't exhaustively alloc all phys pages in the case
+ * MAP_PRIVATE is requested. For mem_prealloc we mmap as MAP_SHARED
+ * to sidestep this quirk.
+ */
+ flags = mem_prealloc ? MAP_POPULATE | MAP_SHARED : MAP_PRIVATE;
+ area = mmap(0, memory, PROT_READ | PROT_WRITE, flags, fd, 0);
+#else
+ area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+#endif
+ if (area == MAP_FAILED) {
+ perror("file_ram_alloc: can't mmap RAM pages");
+ close(fd);
+ return (NULL);
+ }
+ block->fd = fd;
+ return area;
}
#endif
+static ram_addr_t find_ram_offset(ram_addr_t size)
+{
+ RAMBlock *block, *next_block;
+ ram_addr_t offset = 0, mingap = ULONG_MAX;
+
+ if (QLIST_EMPTY(&ram_list.blocks))
+ return 0;
+
+ QLIST_FOREACH(block, &ram_list.blocks, next) {
+ ram_addr_t end, next = ULONG_MAX;
+
+ end = block->offset + block->length;
+
+ QLIST_FOREACH(next_block, &ram_list.blocks, next) {
+ if (next_block->offset >= end) {
+ next = MIN(next, next_block->offset);
+ }
+ }
+ if (next - end >= size && next - end < mingap) {
+ offset = end;
+ mingap = next - end;
+ }
+ }
+ return offset;
+}
+
+static ram_addr_t last_ram_offset(void)
+{
+ RAMBlock *block;
+ ram_addr_t last = 0;
+
+ QLIST_FOREACH(block, &ram_list.blocks, next)
+ last = MAX(last, block->offset + block->length);
+
+ return last;
+}
+
+ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
+ ram_addr_t size, void *host)
+{
+ RAMBlock *new_block, *block;
+
+ size = TARGET_PAGE_ALIGN(size);
+ new_block = qemu_mallocz(sizeof(*new_block));
+
+ if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
+ char *id = dev->parent_bus->info->get_dev_path(dev);
+ if (id) {
+ snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id);
+ qemu_free(id);
+ }
+ }
+ pstrcat(new_block->idstr, sizeof(new_block->idstr), name);
+
+ QLIST_FOREACH(block, &ram_list.blocks, next) {
+ if (!strcmp(block->idstr, new_block->idstr)) {
+ fprintf(stderr, "RAMBlock \"%s\" already registered, abort!\n",
+ new_block->idstr);
+ abort();
+ }
+ }
+
+ new_block->host = host;
+
+ new_block->offset = find_ram_offset(size);
+ new_block->length = size;
+
+ QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
+
+ ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,
+ last_ram_offset() >> TARGET_PAGE_BITS);
+ memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
+ 0xff, size >> TARGET_PAGE_BITS);
+
+ if (kvm_enabled())
+ kvm_setup_guest_memory(new_block->host, size);
+
+ return new_block->offset;
+}
+
+ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size)
+{
+ RAMBlock *new_block, *block;
+
+ size = TARGET_PAGE_ALIGN(size);
+ new_block = qemu_mallocz(sizeof(*new_block));
+
+ if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
+ char *id = dev->parent_bus->info->get_dev_path(dev);
+ if (id) {
+ snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id);
+ qemu_free(id);
+ }
+ }
+ pstrcat(new_block->idstr, sizeof(new_block->idstr), name);
+
+ QLIST_FOREACH(block, &ram_list.blocks, next) {
+ if (!strcmp(block->idstr, new_block->idstr)) {
+ fprintf(stderr, "RAMBlock \"%s\" already registered, abort!\n",
+ new_block->idstr);
+ abort();
+ }
+ }
+
+ if (mem_path) {
+#if defined (__linux__) && !defined(TARGET_S390X)
+ new_block->host = file_ram_alloc(new_block, size, mem_path);
+ if (!new_block->host) {
+ new_block->host = qemu_vmalloc(size);
+#ifdef MADV_MERGEABLE
+ madvise(new_block->host, size, MADV_MERGEABLE);
+#endif
+ }
+#else
+ fprintf(stderr, "-mem-path option unsupported\n");
+ exit(1);
+#endif
+ } else {
+#if defined(TARGET_S390X) && defined(CONFIG_KVM)
+ /* XXX S390 KVM requires the topmost vma of the RAM to be < 256GB */
+ new_block->host = mmap((void*)0x1000000, size,
+ PROT_EXEC|PROT_READ|PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+#else
+ new_block->host = qemu_vmalloc(size);
+#endif
+#ifdef MADV_MERGEABLE
+ madvise(new_block->host, size, MADV_MERGEABLE);
+#endif
+ }
+ new_block->offset = find_ram_offset(size);
+ new_block->length = size;
+
+ QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
+
+ ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,
+ last_ram_offset() >> TARGET_PAGE_BITS);
+ memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
+ 0xff, size >> TARGET_PAGE_BITS);
+
+ if (kvm_enabled())
+ kvm_setup_guest_memory(new_block->host, size);
+
+ return new_block->offset;
+}
+
+void qemu_ram_free(ram_addr_t addr)
+{
+ RAMBlock *block;
+
+ QLIST_FOREACH(block, &ram_list.blocks, next) {
+ if (addr == block->offset) {
+ QLIST_REMOVE(block, next);
+ if (mem_path) {
+#if defined (__linux__) && !defined(TARGET_S390X)
+ if (block->fd) {
+ munmap(block->host, block->length);
+ close(block->fd);
+ } else {
+ qemu_vfree(block->host);
+ }
+#endif
+ } else {
+#if defined(TARGET_S390X) && defined(CONFIG_KVM)
+ munmap(block->host, block->length);
+#else
+ qemu_vfree(block->host);
+#endif
+ }
+ qemu_free(block);
+ return;
+ }
+ }
+
+}
+
+/* Return a host pointer to ram allocated with qemu_ram_alloc.
+ With the exception of the softmmu code in this file, this should
+ only be used for local memory (e.g. video ram) that the device owns,
+ and knows it isn't going to access beyond the end of the block.
+
+ It should not be used for general purpose DMA.
+ Use cpu_physical_memory_map/cpu_physical_memory_rw instead.
+ */
+void *qemu_get_ram_ptr(ram_addr_t addr)
+{
+ RAMBlock *block;
+
+ QLIST_FOREACH(block, &ram_list.blocks, next) {
+ if (addr - block->offset < block->length) {
+ QLIST_REMOVE(block, next);
+ QLIST_INSERT_HEAD(&ram_list.blocks, block, next);
+ return block->host + (addr - block->offset);
+ }
+ }
+
+ fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
+ abort();
+
+ return NULL;
+}
+
+/* Some of the softmmu routines need to translate from a host pointer
+ (typically a TLB entry) back to a ram offset. */
+ram_addr_t qemu_ram_addr_from_host(void *ptr)
+{
+ RAMBlock *block;
+ uint8_t *host = ptr;
+
+ QLIST_FOREACH(block, &ram_list.blocks, next) {
+ if (host - block->host < block->length) {
+ return block->offset + (host - block->host);
+ }
+ }
+
+ fprintf(stderr, "Bad ram pointer %p\n", ptr);
+ abort();
+
+ return 0;
+}
+
+#endif /* !VBOX */
static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
{
#ifdef DEBUG_UNASSIGNED
- printf("Unassigned mem read 0x%08x\n", (int)addr);
+ printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
#endif
-#if defined(TARGET_SPARC) || defined(TARGET_CRIS)
+#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
do_unassigned_access(addr, 0, 0, 0, 1);
#endif
return 0;
@@ -2784,7 +3311,7 @@ static uint32_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr)
#ifdef DEBUG_UNASSIGNED
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
#endif
-#if defined(TARGET_SPARC) || defined(TARGET_CRIS)
+#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
do_unassigned_access(addr, 0, 0, 0, 2);
#endif
return 0;
@@ -2795,7 +3322,7 @@ static uint32_t unassigned_mem_readl(void *opaque, target_phys_addr_t addr)
#ifdef DEBUG_UNASSIGNED
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
#endif
-#if defined(TARGET_SPARC) || defined(TARGET_CRIS)
+#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
do_unassigned_access(addr, 0, 0, 0, 4);
#endif
return 0;
@@ -2804,7 +3331,10 @@ static uint32_t unassigned_mem_readl(void *opaque, target_phys_addr_t addr)
static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
{
#ifdef DEBUG_UNASSIGNED
- printf("Unassigned mem write 0x%08x = 0x%x\n", (int)addr, val);
+ printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
+#endif
+#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+ do_unassigned_access(addr, 1, 0, 0, 1);
#endif
}
@@ -2813,7 +3343,7 @@ static void unassigned_mem_writew(void *opaque, target_phys_addr_t addr, uint32_
#ifdef DEBUG_UNASSIGNED
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
#endif
-#if defined(TARGET_SPARC) || defined(TARGET_CRIS)
+#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
do_unassigned_access(addr, 1, 0, 0, 2);
#endif
}
@@ -2823,191 +3353,148 @@ static void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, uint32_
#ifdef DEBUG_UNASSIGNED
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
#endif
-#if defined(TARGET_SPARC) || defined(TARGET_CRIS)
+#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
do_unassigned_access(addr, 1, 0, 0, 4);
#endif
}
-static CPUReadMemoryFunc *unassigned_mem_read[3] = {
+
+static CPUReadMemoryFunc * const unassigned_mem_read[3] = {
unassigned_mem_readb,
unassigned_mem_readw,
unassigned_mem_readl,
};
-static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
+static CPUWriteMemoryFunc * const unassigned_mem_write[3] = {
unassigned_mem_writeb,
unassigned_mem_writew,
unassigned_mem_writel,
};
-static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr,
+ uint32_t val)
{
- unsigned long ram_addr;
int dirty_flags;
-#if defined(VBOX)
- ram_addr = addr;
-#else
- ram_addr = addr - (unsigned long)phys_ram_base;
-#endif
-#ifdef VBOX
- if (RT_UNLIKELY((ram_addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
- dirty_flags = 0xff;
- else
-#endif /* VBOX */
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+ dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
if (!(dirty_flags & CODE_DIRTY_FLAG)) {
#if !defined(CONFIG_USER_ONLY)
tb_invalidate_phys_page_fast(ram_addr, 1);
-# ifdef VBOX
- if (RT_UNLIKELY((ram_addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
- dirty_flags = 0xff;
- else
-# endif /* VBOX */
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+ dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
#endif
}
#if defined(VBOX) && !defined(REM_PHYS_ADDR_IN_TLB)
- remR3PhysWriteU8(addr, val);
+ remR3PhysWriteU8(ram_addr, val);
#else
- stb_p((uint8_t *)(long)addr, val);
-#endif
-#ifdef USE_KQEMU
- if (cpu_single_env->kqemu_enabled &&
- (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
- kqemu_modify_page(cpu_single_env, ram_addr);
+ stb_p(qemu_get_ram_ptr(ram_addr), val);
#endif
dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
-#ifdef VBOX
- if (RT_LIKELY((ram_addr >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
-#endif /* !VBOX */
- phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
+ cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
/* we remove the notdirty callback only if the code has been
flushed */
if (dirty_flags == 0xff)
- tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_io_vaddr);
+ tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
}
-static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr,
+ uint32_t val)
{
- unsigned long ram_addr;
int dirty_flags;
-#if defined(VBOX)
- ram_addr = addr;
-#else
- ram_addr = addr - (unsigned long)phys_ram_base;
-#endif
-#ifdef VBOX
- if (RT_UNLIKELY((ram_addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
- dirty_flags = 0xff;
- else
-#endif /* VBOX */
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+ dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
if (!(dirty_flags & CODE_DIRTY_FLAG)) {
#if !defined(CONFIG_USER_ONLY)
tb_invalidate_phys_page_fast(ram_addr, 2);
-# ifdef VBOX
- if (RT_UNLIKELY((ram_addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
- dirty_flags = 0xff;
- else
-# endif /* VBOX */
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+ dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
#endif
}
#if defined(VBOX) && !defined(REM_PHYS_ADDR_IN_TLB)
- remR3PhysWriteU16(addr, val);
+ remR3PhysWriteU16(ram_addr, val);
#else
- stw_p((uint8_t *)(long)addr, val);
-#endif
-
-#ifdef USE_KQEMU
- if (cpu_single_env->kqemu_enabled &&
- (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
- kqemu_modify_page(cpu_single_env, ram_addr);
+ stw_p(qemu_get_ram_ptr(ram_addr), val);
#endif
dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
-#ifdef VBOX
- if (RT_LIKELY((ram_addr >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
-#endif
- phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
+ cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
/* we remove the notdirty callback only if the code has been
flushed */
if (dirty_flags == 0xff)
- tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_io_vaddr);
+ tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
}
-static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr,
+ uint32_t val)
{
- unsigned long ram_addr;
int dirty_flags;
-#if defined(VBOX)
- ram_addr = addr;
-#else
- ram_addr = addr - (unsigned long)phys_ram_base;
-#endif
-#ifdef VBOX
- if (RT_UNLIKELY((ram_addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
- dirty_flags = 0xff;
- else
-#endif /* VBOX */
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+ dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
if (!(dirty_flags & CODE_DIRTY_FLAG)) {
#if !defined(CONFIG_USER_ONLY)
tb_invalidate_phys_page_fast(ram_addr, 4);
-# ifdef VBOX
- if (RT_UNLIKELY((ram_addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
- dirty_flags = 0xff;
- else
-# endif /* VBOX */
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+ dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
#endif
}
#if defined(VBOX) && !defined(REM_PHYS_ADDR_IN_TLB)
- remR3PhysWriteU32(addr, val);
+ remR3PhysWriteU32(ram_addr, val);
#else
- stl_p((uint8_t *)(long)addr, val);
-#endif
-#ifdef USE_KQEMU
- if (cpu_single_env->kqemu_enabled &&
- (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
- kqemu_modify_page(cpu_single_env, ram_addr);
+ stl_p(qemu_get_ram_ptr(ram_addr), val);
#endif
dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
-#ifdef VBOX
- if (RT_LIKELY((ram_addr >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
-#endif
- phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
+ cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
/* we remove the notdirty callback only if the code has been
flushed */
if (dirty_flags == 0xff)
- tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_io_vaddr);
+ tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
}
-static CPUReadMemoryFunc *error_mem_read[3] = {
+static CPUReadMemoryFunc * const error_mem_read[3] = {
NULL, /* never used */
NULL, /* never used */
NULL, /* never used */
};
-static CPUWriteMemoryFunc *notdirty_mem_write[3] = {
+static CPUWriteMemoryFunc * const notdirty_mem_write[3] = {
notdirty_mem_writeb,
notdirty_mem_writew,
notdirty_mem_writel,
};
-
/* Generate a debug exception if a watchpoint has been hit. */
-static void check_watchpoint(int offset, int flags)
+static void check_watchpoint(int offset, int len_mask, int flags)
{
CPUState *env = cpu_single_env;
+ target_ulong pc, cs_base;
+ TranslationBlock *tb;
target_ulong vaddr;
- int i;
-
+ CPUWatchpoint *wp;
+ int cpu_flags;
+
+ if (env->watchpoint_hit) {
+ /* We re-entered the check after replacing the TB. Now raise
+ * the debug interrupt so that is will trigger after the
+ * current instruction. */
+ cpu_interrupt(env, CPU_INTERRUPT_DEBUG);
+ return;
+ }
vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
- for (i = 0; i < env->nb_watchpoints; i++) {
- if (vaddr == env->watchpoint[i].vaddr
- && (env->watchpoint[i].type & flags)) {
- env->watchpoint_hit = i + 1;
- cpu_interrupt(env, CPU_INTERRUPT_DEBUG);
- break;
+ QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+ if ((vaddr == (wp->vaddr & len_mask) ||
+ (vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
+ wp->flags |= BP_WATCHPOINT_HIT;
+ if (!env->watchpoint_hit) {
+ env->watchpoint_hit = wp;
+ tb = tb_find_pc(env->mem_io_pc);
+ if (!tb) {
+ cpu_abort(env, "check_watchpoint: could not find TB for "
+ "pc=%p", (void *)env->mem_io_pc);
+ }
+ cpu_restore_state(tb, env, env->mem_io_pc, NULL);
+ tb_phys_invalidate(tb, -1);
+ if (wp->flags & BP_STOP_BEFORE_ACCESS) {
+ env->exception_index = EXCP_DEBUG;
+ } else {
+ cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags);
+ tb_gen_code(env, pc, cs_base, cpu_flags, 1);
+ }
+ cpu_resume_from_signal(env, NULL);
+ }
+ } else {
+ wp->flags &= ~BP_WATCHPOINT_HIT;
}
}
}
@@ -3017,268 +3504,262 @@ static void check_watchpoint(int offset, int flags)
phys routines. */
static uint32_t watch_mem_readb(void *opaque, target_phys_addr_t addr)
{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_READ);
+ check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x0, BP_MEM_READ);
return ldub_phys(addr);
}
static uint32_t watch_mem_readw(void *opaque, target_phys_addr_t addr)
{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_READ);
+ check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x1, BP_MEM_READ);
return lduw_phys(addr);
}
static uint32_t watch_mem_readl(void *opaque, target_phys_addr_t addr)
{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_READ);
+ check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x3, BP_MEM_READ);
return ldl_phys(addr);
}
static void watch_mem_writeb(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_WRITE);
+ check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x0, BP_MEM_WRITE);
stb_phys(addr, val);
}
static void watch_mem_writew(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_WRITE);
+ check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x1, BP_MEM_WRITE);
stw_phys(addr, val);
}
static void watch_mem_writel(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_WRITE);
+ check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x3, BP_MEM_WRITE);
stl_phys(addr, val);
}
-static CPUReadMemoryFunc *watch_mem_read[3] = {
+static CPUReadMemoryFunc * const watch_mem_read[3] = {
watch_mem_readb,
watch_mem_readw,
watch_mem_readl,
};
-static CPUWriteMemoryFunc *watch_mem_write[3] = {
+static CPUWriteMemoryFunc * const watch_mem_write[3] = {
watch_mem_writeb,
watch_mem_writew,
watch_mem_writel,
};
-static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr,
- unsigned int len)
+static inline uint32_t subpage_readlen (subpage_t *mmio,
+ target_phys_addr_t addr,
+ unsigned int len)
{
- uint32_t ret;
- unsigned int idx;
-
- idx = SUBPAGE_IDX(addr - mmio->base);
+ unsigned int idx = SUBPAGE_IDX(addr);
#if defined(DEBUG_SUBPAGE)
printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
mmio, len, addr, idx);
#endif
- ret = (**mmio->mem_read[idx][len])(mmio->opaque[idx][0][len], addr);
- return ret;
+ addr += mmio->region_offset[idx];
+ idx = mmio->sub_io_index[idx];
+ return io_mem_read[idx][len](io_mem_opaque[idx], addr);
}
static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
- uint32_t value, unsigned int len)
+ uint32_t value, unsigned int len)
{
- unsigned int idx;
-
- idx = SUBPAGE_IDX(addr - mmio->base);
+ unsigned int idx = SUBPAGE_IDX(addr);
#if defined(DEBUG_SUBPAGE)
- printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", __func__,
- mmio, len, addr, idx, value);
+ printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n",
+ __func__, mmio, len, addr, idx, value);
#endif
- (**mmio->mem_write[idx][len])(mmio->opaque[idx][1][len], addr, value);
+
+ addr += mmio->region_offset[idx];
+ idx = mmio->sub_io_index[idx];
+ io_mem_write[idx][len](io_mem_opaque[idx], addr, value);
}
static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr)
{
-#if defined(DEBUG_SUBPAGE)
- printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
-#endif
-
return subpage_readlen(opaque, addr, 0);
}
static void subpage_writeb (void *opaque, target_phys_addr_t addr,
uint32_t value)
{
-#if defined(DEBUG_SUBPAGE)
- printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
-#endif
subpage_writelen(opaque, addr, value, 0);
}
static uint32_t subpage_readw (void *opaque, target_phys_addr_t addr)
{
-#if defined(DEBUG_SUBPAGE)
- printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
-#endif
-
return subpage_readlen(opaque, addr, 1);
}
static void subpage_writew (void *opaque, target_phys_addr_t addr,
uint32_t value)
{
-#if defined(DEBUG_SUBPAGE)
- printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
-#endif
subpage_writelen(opaque, addr, value, 1);
}
static uint32_t subpage_readl (void *opaque, target_phys_addr_t addr)
{
-#if defined(DEBUG_SUBPAGE)
- printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
-#endif
-
return subpage_readlen(opaque, addr, 2);
}
-static void subpage_writel (void *opaque,
- target_phys_addr_t addr, uint32_t value)
+static void subpage_writel (void *opaque, target_phys_addr_t addr,
+ uint32_t value)
{
-#if defined(DEBUG_SUBPAGE)
- printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
-#endif
subpage_writelen(opaque, addr, value, 2);
}
-static CPUReadMemoryFunc *subpage_read[] = {
+static CPUReadMemoryFunc * const subpage_read[] = {
&subpage_readb,
&subpage_readw,
&subpage_readl,
};
-static CPUWriteMemoryFunc *subpage_write[] = {
+static CPUWriteMemoryFunc * const subpage_write[] = {
&subpage_writeb,
&subpage_writew,
&subpage_writel,
};
static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
- ram_addr_t memory)
+ ram_addr_t memory, ram_addr_t region_offset)
{
int idx, eidx;
- unsigned int i;
if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE)
return -1;
idx = SUBPAGE_IDX(start);
eidx = SUBPAGE_IDX(end);
#if defined(DEBUG_SUBPAGE)
- printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %d\n", __func__,
+ printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__,
mmio, start, end, idx, eidx, memory);
#endif
- memory >>= IO_MEM_SHIFT;
+ memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
for (; idx <= eidx; idx++) {
- for (i = 0; i < 4; i++) {
- if (io_mem_read[memory][i]) {
- mmio->mem_read[idx][i] = &io_mem_read[memory][i];
- mmio->opaque[idx][0][i] = io_mem_opaque[memory];
- }
- if (io_mem_write[memory][i]) {
- mmio->mem_write[idx][i] = &io_mem_write[memory][i];
- mmio->opaque[idx][1][i] = io_mem_opaque[memory];
- }
- }
+ mmio->sub_io_index[idx] = memory;
+ mmio->region_offset[idx] = region_offset;
}
return 0;
}
-static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
- ram_addr_t orig_memory)
+static subpage_t *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
+ ram_addr_t orig_memory,
+ ram_addr_t region_offset)
{
subpage_t *mmio;
int subpage_memory;
mmio = qemu_mallocz(sizeof(subpage_t));
- if (mmio != NULL) {
- mmio->base = base;
- subpage_memory = cpu_register_io_memory(0, subpage_read, subpage_write, mmio);
+
+ mmio->base = base;
+ subpage_memory = cpu_register_io_memory(subpage_read, subpage_write, mmio);
#if defined(DEBUG_SUBPAGE)
- printf("%s: %p base " TARGET_FMT_plx " len %08x %d\n", __func__,
- mmio, base, TARGET_PAGE_SIZE, subpage_memory);
+ printf("%s: %p base " TARGET_FMT_plx " len %08x %d\n", __func__,
+ mmio, base, TARGET_PAGE_SIZE, subpage_memory);
#endif
- *phys = subpage_memory | IO_MEM_SUBPAGE;
- subpage_register(mmio, 0, TARGET_PAGE_SIZE - 1, orig_memory);
- }
+ *phys = subpage_memory | IO_MEM_SUBPAGE;
+ subpage_register(mmio, 0, TARGET_PAGE_SIZE-1, orig_memory, region_offset);
return mmio;
}
-static void io_mem_init(void)
+static int get_free_io_mem_idx(void)
{
- cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read, unassigned_mem_write, NULL);
- cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
- cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, notdirty_mem_write, NULL);
- io_mem_nb = 5;
-
- io_mem_watch = cpu_register_io_memory(0, watch_mem_read,
- watch_mem_write, NULL);
+ int i;
-#ifndef VBOX /* VBOX: we do this later when the RAM is allocated. */
- /* alloc dirty bits array */
- phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS);
- memset(phys_ram_dirty, 0xff, phys_ram_size >> TARGET_PAGE_BITS);
-#endif /* !VBOX */
+ for (i = 0; i<IO_MEM_NB_ENTRIES; i++)
+ if (!io_mem_used[i]) {
+ io_mem_used[i] = 1;
+ return i;
+ }
+ fprintf(stderr, "RAN out out io_mem_idx, max %d !\n", IO_MEM_NB_ENTRIES);
+ return -1;
}
/* mem_read and mem_write are arrays of functions containing the
function to access byte (index 0), word (index 1) and dword (index
- 2). Functions can be omitted with a NULL function pointer. The
- registered functions may be modified dynamically later.
+ 2). Functions can be omitted with a NULL function pointer.
If io_index is non zero, the corresponding io zone is
modified. If it is zero, a new io zone is allocated. The return
value can be used with cpu_register_physical_memory(). (-1) is
returned if error. */
-int cpu_register_io_memory(int io_index,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque)
+static int cpu_register_io_memory_fixed(int io_index,
+ CPUReadMemoryFunc * const *mem_read,
+ CPUWriteMemoryFunc * const *mem_write,
+ void *opaque)
{
- int i, subwidth = 0;
+ int i;
if (io_index <= 0) {
- if (io_mem_nb >= IO_MEM_NB_ENTRIES)
- return -1;
- io_index = io_mem_nb++;
+ io_index = get_free_io_mem_idx();
+ if (io_index == -1)
+ return io_index;
} else {
+ io_index >>= IO_MEM_SHIFT;
if (io_index >= IO_MEM_NB_ENTRIES)
return -1;
}
- for(i = 0;i < 3; i++) {
- if (!mem_read[i] || !mem_write[i])
- subwidth = IO_MEM_SUBWIDTH;
- io_mem_read[io_index][i] = mem_read[i];
- io_mem_write[io_index][i] = mem_write[i];
+ for (i = 0; i < 3; ++i) {
+ io_mem_read[io_index][i]
+ = (mem_read[i] ? mem_read[i] : unassigned_mem_read[i]);
+ }
+ for (i = 0; i < 3; ++i) {
+ io_mem_write[io_index][i]
+ = (mem_write[i] ? mem_write[i] : unassigned_mem_write[i]);
}
io_mem_opaque[io_index] = opaque;
- return (io_index << IO_MEM_SHIFT) | subwidth;
+
+ return (io_index << IO_MEM_SHIFT);
}
-CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
+int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,
+ CPUWriteMemoryFunc * const *mem_write,
+ void *opaque)
{
- return io_mem_write[io_index >> IO_MEM_SHIFT];
+ return cpu_register_io_memory_fixed(0, mem_read, mem_write, opaque);
}
-CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
+void cpu_unregister_io_memory(int io_table_address)
{
- return io_mem_read[io_index >> IO_MEM_SHIFT];
+ int i;
+ int io_index = io_table_address >> IO_MEM_SHIFT;
+
+ for (i=0;i < 3; i++) {
+ io_mem_read[io_index][i] = unassigned_mem_read[i];
+ io_mem_write[io_index][i] = unassigned_mem_write[i];
+ }
+ io_mem_opaque[io_index] = NULL;
+ io_mem_used[io_index] = 0;
}
+
+static void io_mem_init(void)
+{
+ int i;
+
+ cpu_register_io_memory_fixed(IO_MEM_ROM, error_mem_read, unassigned_mem_write, NULL);
+ cpu_register_io_memory_fixed(IO_MEM_UNASSIGNED, unassigned_mem_read, unassigned_mem_write, NULL);
+ cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, error_mem_read, notdirty_mem_write, NULL);
+ for (i=0; i<5; i++)
+ io_mem_used[i] = 1;
+
+ io_mem_watch = cpu_register_io_memory(watch_mem_read,
+ watch_mem_write, NULL);
+}
+
#endif /* !defined(CONFIG_USER_ONLY) */
/* physical memory access (slow version, mainly for debug) */
#if defined(CONFIG_USER_ONLY)
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write)
+int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
+ uint8_t *buf, int len, int is_write)
{
int l, flags;
target_ulong page;
@@ -3291,29 +3772,29 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
l = len;
flags = page_get_flags(page);
if (!(flags & PAGE_VALID))
- return;
+ return -1;
if (is_write) {
if (!(flags & PAGE_WRITE))
- return;
+ return -1;
/* XXX: this code should not depend on lock_user */
if (!(p = lock_user(VERIFY_WRITE, addr, l, 0)))
- /* FIXME - should this return an error rather than just fail? */
- return;
- memcpy(p, buf, len);
- unlock_user(p, addr, len);
+ return -1;
+ memcpy(p, buf, l);
+ unlock_user(p, addr, l);
} else {
if (!(flags & PAGE_READ))
- return;
+ return -1;
+ /* XXX: this code should not depend on lock_user */
if (!(p = lock_user(VERIFY_READ, addr, l, 1)))
- /* FIXME - should this return an error rather than just fail? */
- return;
- memcpy(buf, p, len);
+ return -1;
+ memcpy(buf, p, l);
unlock_user(p, addr, 0);
}
len -= l;
buf += l;
addr += l;
}
+ return 0;
}
#else
@@ -3341,26 +3822,29 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
if (is_write) {
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
+ target_phys_addr_t addr1 = addr;
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+ if (p)
+ addr1 = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
/* XXX: could force cpu_single_env to NULL to avoid
potential bugs */
- if (l >= 4 && ((addr & 3) == 0)) {
+ if (l >= 4 && ((addr1 & 3) == 0)) {
/* 32 bit write access */
#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
val = ldl_p(buf);
#else
val = *(const uint32_t *)buf;
#endif
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
+ io_mem_write[io_index][2](io_mem_opaque[io_index], addr1, val);
l = 4;
- } else if (l >= 2 && ((addr & 1) == 0)) {
+ } else if (l >= 2 && ((addr1 & 1) == 0)) {
/* 16 bit write access */
#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
val = lduw_p(buf);
#else
val = *(const uint16_t *)buf;
#endif
- io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
+ io_mem_write[io_index][1](io_mem_opaque[io_index], addr1, val);
l = 2;
} else {
/* 8 bit write access */
@@ -3369,7 +3853,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
#else
val = *(const uint8_t *)buf;
#endif
- io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
+ io_mem_write[io_index][0](io_mem_opaque[io_index], addr1, val);
l = 1;
}
} else {
@@ -3379,37 +3863,37 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
#ifdef VBOX
remR3PhysWrite(addr1, buf, l); NOREF(ptr);
#else
- ptr = phys_ram_base + addr1;
+ ptr = qemu_get_ram_ptr(addr1);
memcpy(ptr, buf, l);
#endif
if (!cpu_physical_memory_is_dirty(addr1)) {
/* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
/* set dirty bit */
-#ifdef VBOX
- if (RT_LIKELY((addr1 >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
-#endif
- phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
- (0xff & ~CODE_DIRTY_FLAG);
+ cpu_physical_memory_set_dirty_flags(
+ addr1, (0xff & ~CODE_DIRTY_FLAG));
}
}
} else {
if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
!(pd & IO_MEM_ROMD)) {
+ target_phys_addr_t addr1 = addr;
/* I/O case */
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- if (l >= 4 && ((addr & 3) == 0)) {
+ if (p)
+ addr1 = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+ if (l >= 4 && ((addr1 & 3) == 0)) {
/* 32 bit read access */
- val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
+ val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr1);
#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
stl_p(buf, val);
#else
*(uint32_t *)buf = val;
#endif
l = 4;
- } else if (l >= 2 && ((addr & 1) == 0)) {
+ } else if (l >= 2 && ((addr1 & 1) == 0)) {
/* 16 bit read access */
- val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
+ val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr1);
#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
stw_p(buf, val);
#else
@@ -3418,7 +3902,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
l = 2;
} else {
/* 8 bit read access */
- val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr);
+ val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr1);
#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
stb_p(buf, val);
#else
@@ -3431,7 +3915,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
#ifdef VBOX
remR3PhysRead((pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK), buf, l); NOREF(ptr);
#else
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
+ ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
memcpy(buf, ptr, l);
#endif
@@ -3444,6 +3928,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
}
#ifndef VBOX
+
/* used for ROM loading : can write in RAM and ROM */
void cpu_physical_memory_write_rom(target_phys_addr_t addr,
const uint8_t *buf, int len)
@@ -3474,7 +3959,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
unsigned long addr1;
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
/* ROM/RAM case */
- ptr = phys_ram_base + addr1;
+ ptr = qemu_get_ram_ptr(addr1);
memcpy(ptr, buf, l);
}
len -= l;
@@ -3482,8 +3967,152 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
addr += l;
}
}
-#endif /* !VBOX */
+typedef struct {
+ void *buffer;
+ target_phys_addr_t addr;
+ target_phys_addr_t len;
+} BounceBuffer;
+
+static BounceBuffer bounce;
+
+typedef struct MapClient {
+ void *opaque;
+ void (*callback)(void *opaque);
+ QLIST_ENTRY(MapClient) link;
+} MapClient;
+
+static QLIST_HEAD(map_client_list, MapClient) map_client_list
+ = QLIST_HEAD_INITIALIZER(map_client_list);
+
+void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque))
+{
+ MapClient *client = qemu_malloc(sizeof(*client));
+
+ client->opaque = opaque;
+ client->callback = callback;
+ QLIST_INSERT_HEAD(&map_client_list, client, link);
+ return client;
+}
+
+void cpu_unregister_map_client(void *_client)
+{
+ MapClient *client = (MapClient *)_client;
+
+ QLIST_REMOVE(client, link);
+ qemu_free(client);
+}
+
+static void cpu_notify_map_clients(void)
+{
+ MapClient *client;
+
+ while (!QLIST_EMPTY(&map_client_list)) {
+ client = QLIST_FIRST(&map_client_list);
+ client->callback(client->opaque);
+ cpu_unregister_map_client(client);
+ }
+}
+
+/* Map a physical memory region into a host virtual address.
+ * May map a subset of the requested range, given by and returned in *plen.
+ * May return NULL if resources needed to perform the mapping are exhausted.
+ * Use only for reads OR writes - not for read-modify-write operations.
+ * Use cpu_register_map_client() to know when retrying the map operation is
+ * likely to succeed.
+ */
+void *cpu_physical_memory_map(target_phys_addr_t addr,
+ target_phys_addr_t *plen,
+ int is_write)
+{
+ target_phys_addr_t len = *plen;
+ target_phys_addr_t done = 0;
+ int l;
+ uint8_t *ret = NULL;
+ uint8_t *ptr;
+ target_phys_addr_t page;
+ unsigned long pd;
+ PhysPageDesc *p;
+ unsigned long addr1;
+
+ while (len > 0) {
+ page = addr & TARGET_PAGE_MASK;
+ l = (page + TARGET_PAGE_SIZE) - addr;
+ if (l > len)
+ l = len;
+ p = phys_page_find(page >> TARGET_PAGE_BITS);
+ if (!p) {
+ pd = IO_MEM_UNASSIGNED;
+ } else {
+ pd = p->phys_offset;
+ }
+
+ if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
+ if (done || bounce.buffer) {
+ break;
+ }
+ bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, TARGET_PAGE_SIZE);
+ bounce.addr = addr;
+ bounce.len = l;
+ if (!is_write) {
+ cpu_physical_memory_rw(addr, bounce.buffer, l, 0);
+ }
+ ptr = bounce.buffer;
+ } else {
+ addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
+ ptr = qemu_get_ram_ptr(addr1);
+ }
+ if (!done) {
+ ret = ptr;
+ } else if (ret + done != ptr) {
+ break;
+ }
+
+ len -= l;
+ addr += l;
+ done += l;
+ }
+ *plen = done;
+ return ret;
+}
+
+/* Unmaps a memory region previously mapped by cpu_physical_memory_map().
+ * Will also mark the memory as dirty if is_write == 1. access_len gives
+ * the amount of memory that was actually read or written by the caller.
+ */
+void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
+ int is_write, target_phys_addr_t access_len)
+{
+ if (buffer != bounce.buffer) {
+ if (is_write) {
+ ram_addr_t addr1 = qemu_ram_addr_from_host(buffer);
+ while (access_len) {
+ unsigned l;
+ l = TARGET_PAGE_SIZE;
+ if (l > access_len)
+ l = access_len;
+ if (!cpu_physical_memory_is_dirty(addr1)) {
+ /* invalidate code */
+ tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
+ /* set dirty bit */
+ cpu_physical_memory_set_dirty_flags(
+ addr1, (0xff & ~CODE_DIRTY_FLAG));
+ }
+ addr1 += l;
+ access_len -= l;
+ }
+ }
+ return;
+ }
+ if (is_write) {
+ cpu_physical_memory_write(bounce.addr, bounce.buffer, access_len);
+ }
+ qemu_vfree(bounce.buffer);
+ bounce.buffer = NULL;
+ cpu_notify_map_clients();
+}
+
+#endif /* !VBOX */
/* warning: addr must be aligned */
uint32_t ldl_phys(target_phys_addr_t addr)
@@ -3505,11 +4134,13 @@ uint32_t ldl_phys(target_phys_addr_t addr)
!(pd & IO_MEM_ROMD)) {
/* I/O case */
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+ if (p)
+ addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
} else {
/* RAM case */
#ifndef VBOX
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
+ ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
val = ldl_p(ptr);
#else
@@ -3539,6 +4170,8 @@ uint64_t ldq_phys(target_phys_addr_t addr)
!(pd & IO_MEM_ROMD)) {
/* I/O case */
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+ if (p)
+ addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
#ifdef TARGET_WORDS_BIGENDIAN
val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
@@ -3549,7 +4182,7 @@ uint64_t ldq_phys(target_phys_addr_t addr)
} else {
/* RAM case */
#ifndef VBOX
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
+ ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
val = ldq_p(ptr);
#else
@@ -3567,12 +4200,40 @@ uint32_t ldub_phys(target_phys_addr_t addr)
return val;
}
-/* XXX: optimize */
+/* warning: addr must be aligned */
uint32_t lduw_phys(target_phys_addr_t addr)
{
- uint16_t val;
- cpu_physical_memory_read(addr, (uint8_t *)&val, 2);
- return tswap16(val);
+ int io_index;
+ uint8_t *ptr;
+ uint64_t val;
+ unsigned long pd;
+ PhysPageDesc *p;
+
+ p = phys_page_find(addr >> TARGET_PAGE_BITS);
+ if (!p) {
+ pd = IO_MEM_UNASSIGNED;
+ } else {
+ pd = p->phys_offset;
+ }
+
+ if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
+ !(pd & IO_MEM_ROMD)) {
+ /* I/O case */
+ io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+ if (p)
+ addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+ val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
+ } else {
+ /* RAM case */
+#ifndef VBOX
+ ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
+ (addr & ~TARGET_PAGE_MASK);
+ val = lduw_p(ptr);
+#else
+ val = remR3PhysReadU16((pd & TARGET_PAGE_MASK) | (addr & ~TARGET_PAGE_MASK));
+#endif
+ }
+ return val;
}
/* warning: addr must be aligned. The ram page is not masked as dirty
@@ -3594,26 +4255,29 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+ if (p)
+ addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
} else {
#ifndef VBOX
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
+ unsigned long addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
+ ptr = qemu_get_ram_ptr(addr1);
stl_p(ptr, val);
#else
remR3PhysWriteU32((pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK), val); NOREF(ptr);
#endif
+
#ifndef VBOX
if (unlikely(in_migration)) {
if (!cpu_physical_memory_is_dirty(addr1)) {
/* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
/* set dirty bit */
- phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
- (0xff & ~CODE_DIRTY_FLAG);
+ cpu_physical_memory_set_dirty_flags(
+ addr1, (0xff & ~CODE_DIRTY_FLAG));
}
}
-#endif
+#endif /* !VBOX */
}
}
@@ -3633,6 +4297,8 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+ if (p)
+ addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
#ifdef TARGET_WORDS_BIGENDIAN
io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val >> 32);
io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val);
@@ -3642,7 +4308,7 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
#endif
} else {
#ifndef VBOX
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
+ ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
stq_p(ptr, val);
#else
@@ -3651,7 +4317,6 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
}
}
-
/* warning: addr must be aligned */
void stl_phys(target_phys_addr_t addr, uint32_t val)
{
@@ -3669,13 +4334,15 @@ void stl_phys(target_phys_addr_t addr, uint32_t val)
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+ if (p)
+ addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
} else {
unsigned long addr1;
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
/* RAM case */
#ifndef VBOX
- ptr = phys_ram_base + addr1;
+ ptr = qemu_get_ram_ptr(addr1);
stl_p(ptr, val);
#else
remR3PhysWriteU32((pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK), val); NOREF(ptr);
@@ -3684,11 +4351,8 @@ void stl_phys(target_phys_addr_t addr, uint32_t val)
/* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
/* set dirty bit */
-#ifdef VBOX
- if (RT_LIKELY((addr1 >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
-#endif
- phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
- (0xff & ~CODE_DIRTY_FLAG);
+ cpu_physical_memory_set_dirty_flags(addr1,
+ (0xff & ~CODE_DIRTY_FLAG));
}
}
}
@@ -3700,11 +4364,44 @@ void stb_phys(target_phys_addr_t addr, uint32_t val)
cpu_physical_memory_write(addr, &v, 1);
}
-/* XXX: optimize */
+/* warning: addr must be aligned */
void stw_phys(target_phys_addr_t addr, uint32_t val)
{
- uint16_t v = tswap16(val);
- cpu_physical_memory_write(addr, (const uint8_t *)&v, 2);
+ int io_index;
+ uint8_t *ptr;
+ unsigned long pd;
+ PhysPageDesc *p;
+
+ p = phys_page_find(addr >> TARGET_PAGE_BITS);
+ if (!p) {
+ pd = IO_MEM_UNASSIGNED;
+ } else {
+ pd = p->phys_offset;
+ }
+
+ if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
+ io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+ if (p)
+ addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+ io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
+ } else {
+ unsigned long addr1;
+ addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
+ /* RAM case */
+#ifndef VBOX
+ ptr = qemu_get_ram_ptr(addr1);
+ stw_p(ptr, val);
+#else
+ remR3PhysWriteU16(addr1, val); NOREF(ptr);
+#endif
+ if (!cpu_physical_memory_is_dirty(addr1)) {
+ /* invalidate code */
+ tb_invalidate_phys_page_range(addr1, addr1 + 2, 0);
+ /* set dirty bit */
+ cpu_physical_memory_set_dirty_flags(addr1,
+ (0xff & ~CODE_DIRTY_FLAG));
+ }
+ }
}
/* XXX: optimize */
@@ -3714,14 +4411,14 @@ void stq_phys(target_phys_addr_t addr, uint64_t val)
cpu_physical_memory_write(addr, (const uint8_t *)&val, 8);
}
-#endif
-
-/* virtual memory access for debug */
+#ifndef VBOX
+/* virtual memory access for debug (includes writing to ROM) */
int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
uint8_t *buf, int len, int is_write)
{
int l;
- target_ulong page, phys_addr;
+ target_phys_addr_t phys_addr;
+ target_ulong page;
while (len > 0) {
page = addr & TARGET_PAGE_MASK;
@@ -3732,14 +4429,19 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
l = (page + TARGET_PAGE_SIZE) - addr;
if (l > len)
l = len;
- cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK),
- buf, l, is_write);
+ phys_addr += (addr & ~TARGET_PAGE_MASK);
+ if (is_write)
+ cpu_physical_memory_write_rom(phys_addr, buf, l);
+ else
+ cpu_physical_memory_rw(phys_addr, buf, l, is_write);
len -= l;
buf += l;
addr += l;
}
return 0;
}
+#endif /* !VBOX */
+#endif
/* in deterministic execution mode, instructions doing device I/Os
must be at the end of the TB */
@@ -3800,6 +4502,8 @@ void cpu_io_recompile(CPUState *env, void *retaddr)
cpu_resume_from_signal(env, NULL);
}
+#if !defined(CONFIG_USER_ONLY)
+
#ifndef VBOX
void dump_exec_info(FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
@@ -3855,8 +4559,6 @@ void dump_exec_info(FILE *f,
}
#endif /* !VBOX */
-#if !defined(CONFIG_USER_ONLY)
-
#define MMUSUFFIX _cmmu
#define GETPC() NULL
#define env cpu_single_env
diff --git a/src/recompiler/fpu/softfloat-macros.h b/src/recompiler/fpu/softfloat-macros.h
index 0502fb894..783822820 100644
--- a/src/recompiler/fpu/softfloat-macros.h
+++ b/src/recompiler/fpu/softfloat-macros.h
@@ -590,12 +590,12 @@ static bits32 estimateSqrt32( int16 aExp, bits32 a )
index = ( a>>27 ) & 15;
if ( aExp & 1 ) {
- z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
+ z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ (int)index ];
z = ( ( a / z )<<14 ) + ( z<<15 );
a >>= 1;
}
else {
- z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
+ z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ (int)index ];
z = a / z + z;
z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
diff --git a/src/recompiler/fpu/softfloat-native.c b/src/recompiler/fpu/softfloat-native.c
index 876e78a4d..7c7820abe 100644
--- a/src/recompiler/fpu/softfloat-native.c
+++ b/src/recompiler/fpu/softfloat-native.c
@@ -2,14 +2,16 @@
context is supported */
#include "softfloat.h"
#include <math.h>
+#if defined(CONFIG_SOLARIS)
+#include <fenv.h>
+#endif
void set_float_rounding_mode(int val STATUS_PARAM)
{
STATUS(float_rounding_mode) = val;
-#if defined(_BSD) && !defined(__APPLE__) || (defined(HOST_SOLARIS) && (HOST_SOLARIS < 10 || HOST_SOLARIS == 11))
+#if (defined(CONFIG_BSD) && !defined(__APPLE__) && !defined(__GLIBC__)) || \
+ (defined(CONFIG_SOLARIS) && (CONFIG_SOLARIS_VERSION < 10 || CONFIG_SOLARIS_VERSION == 11)) /* VBOX adds sol 11 */
fpsetround(val);
-#elif defined(__arm__)
- /* nothing to do */
#else
fesetround(val);
#endif
@@ -22,7 +24,8 @@ void set_floatx80_rounding_precision(int val STATUS_PARAM)
}
#endif
-#if defined(_BSD) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
+#if defined(CONFIG_BSD) || \
+ (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
#define lrint(d) ((int32_t)rint(d))
#define llrint(d) ((int64_t)rint(d))
#define lrintf(f) ((int32_t)rint(f))
@@ -30,16 +33,15 @@ void set_floatx80_rounding_precision(int val STATUS_PARAM)
#define sqrtf(f) ((float)sqrt(f))
#define remainderf(fa, fb) ((float)remainder(fa, fb))
#define rintf(f) ((float)rint(f))
-/* Some defines which only apply to *BSD */
-# if defined(VBOX) && defined(_BSD)
+# if defined(VBOX) && defined(HOST_BSD) /* Some defines which only apply to *BSD */
# define lrintl(f) ((int32_t)rint(f))
# define llrintl(f) ((int64_t)rint(f))
# define rintl(d) ((int32_t)rint(d))
# define sqrtl(f) (sqrt(f))
# define remainderl(fa, fb) (remainder(fa, fb))
# endif /* VBOX && _BSD */
-
-#if !defined(__sparc__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
+#if !defined(__sparc__) && \
+ (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
extern long double rintl(long double);
extern long double scalbnl(long double, int);
@@ -354,7 +356,8 @@ uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
/*----------------------------------------------------------------------------
| Software IEC/IEEE double-precision operations.
*----------------------------------------------------------------------------*/
-#if defined(__sun__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
+#if defined(__sun__) && \
+ (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
static inline float64 trunc(float64 x)
{
return x < 0 ? -floor(-x) : floor(x);
@@ -367,25 +370,7 @@ float64 float64_trunc_to_int( float64 a STATUS_PARAM )
float64 float64_round_to_int( float64 a STATUS_PARAM )
{
-#if defined(__arm__)
- switch(STATUS(float_rounding_mode)) {
- default:
- case float_round_nearest_even:
- asm("rndd %0, %1" : "=f" (a) : "f"(a));
- break;
- case float_round_down:
- asm("rnddm %0, %1" : "=f" (a) : "f"(a));
- break;
- case float_round_up:
- asm("rnddp %0, %1" : "=f" (a) : "f"(a));
- break;
- case float_round_to_zero:
- asm("rnddz %0, %1" : "=f" (a) : "f"(a));
- break;
- }
-#else
return rint(a);
-#endif
}
float64 float64_rem( float64 a, float64 b STATUS_PARAM)
diff --git a/src/recompiler/fpu/softfloat-native.h b/src/recompiler/fpu/softfloat-native.h
index a9aab679f..13be732a3 100644
--- a/src/recompiler/fpu/softfloat-native.h
+++ b/src/recompiler/fpu/softfloat-native.h
@@ -1,13 +1,11 @@
/* Native implementation of soft float functions */
+#define __C99FEATURES__
#include <math.h>
-#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
+#if (defined(CONFIG_BSD) && !defined(__APPLE__) && !defined(__GLIBC__) && !defined(__FreeBSD__)) \
+ || defined(CONFIG_SOLARIS) /* VBox: Added __FreeBSD__ */
#include <ieeefp.h>
-#elif defined(_MSC_VER)
-# include <fpieee.h>
-# ifndef fabsf
-# define fabsf(f) ((float)fabs(f))
-# endif
+#define fabsf(f) ((float)fabs(f))
#else
#include <fenv.h>
#endif
@@ -23,8 +21,9 @@
* Solaris 10 with GCC4 does not need these macros as they
* are defined in <iso/math_c99.h> with a compiler directive
*/
-#if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ((HOST_SOLARIS >= 10) \
- && (__GNUC__ <= 4))) \
+#if defined(CONFIG_SOLARIS) && \
+ ((CONFIG_SOLARIS_VERSION <= 9 ) || \
+ ((CONFIG_SOLARIS_VERSION == 10) && (__GNUC__ < 4))) \
|| (defined(__OpenBSD__) && (OpenBSD < 200811))
/*
* C99 7.12.3 classification macros
@@ -63,15 +62,9 @@
#define isless(x, y) ((!unordered(x, y)) && ((x) < (y)))
#define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y)))
#define isunordered(x,y) unordered(x, y)
-#elif defined(_MSC_VER)
-#include <float.h>
-#define unordered(x1, x2) ((_fpclass(x1) <= 2) || (_fpclass(x2) <= 2))
-#define isless(x, y) ((!unordered(x, y)) && ((x) < (y)))
-#define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y)))
-#define isunordered(x,y) unordered(x, y)
#endif
-#if defined(__sun__) && !defined(NEED_LIBSUNMATH)
+#if defined(__sun__) && !defined(CONFIG_NEEDS_LIBSUNMATH)
#ifndef isnan
# define isnan(x) \
@@ -121,7 +114,8 @@ typedef union {
/*----------------------------------------------------------------------------
| Software IEC/IEEE floating-point rounding mode.
*----------------------------------------------------------------------------*/
-#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
+#if (defined(CONFIG_BSD) && !defined(__APPLE__) && !defined(__GLIBC__)) \
+ || defined(CONFIG_SOLARIS)
#if defined(__OpenBSD__)
#define FE_RM FP_RM
#define FE_RP FP_RP
@@ -133,20 +127,6 @@ enum {
float_round_up = FP_RP,
float_round_to_zero = FP_RZ
};
-#elif defined(__arm__)
-enum {
- float_round_nearest_even = 0,
- float_round_down = 1,
- float_round_up = 2,
- float_round_to_zero = 3
-};
-#elif defined(_MSC_VER)
-enum {
- float_round_nearest_even = _FpRoundNearest,
- float_round_down = _FpRoundMinusInfinity,
- float_round_up = _FpRoundPlusInfinity,
- float_round_to_zero = _FpRoundChopped
-};
#else
enum {
float_round_nearest_even = FE_TONEAREST,
diff --git a/src/recompiler/fpu/softfloat-specialize.h b/src/recompiler/fpu/softfloat-specialize.h
index d279210ae..8e6aceb55 100644
--- a/src/recompiler/fpu/softfloat-specialize.h
+++ b/src/recompiler/fpu/softfloat-specialize.h
@@ -61,7 +61,7 @@ typedef struct {
*----------------------------------------------------------------------------*/
#if defined(TARGET_SPARC)
#define float32_default_nan make_float32(0x7FFFFFFF)
-#elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
+#elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
#define float32_default_nan make_float32(0x7FC00000)
#elif defined(TARGET_HPPA)
#define float32_default_nan make_float32(0x7FA00000)
@@ -166,7 +166,7 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
res = bIsNaN ? bv : av;
}
else if ( aIsNaN ) {
- if ( bIsSignalingNaN | ! bIsNaN )
+ if ( bIsSignalingNaN || ! bIsNaN )
res = av;
else {
returnLargerSignificand:
@@ -189,7 +189,7 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
*----------------------------------------------------------------------------*/
#if defined(TARGET_SPARC)
#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
-#elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
+#elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
#elif defined(TARGET_HPPA)
#define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
@@ -301,7 +301,7 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
res = bIsNaN ? bv : av;
}
else if ( aIsNaN ) {
- if ( bIsSignalingNaN | ! bIsNaN )
+ if ( bIsSignalingNaN || ! bIsNaN )
res = av;
else {
returnLargerSignificand:
@@ -441,7 +441,7 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
return bIsNaN ? b : a;
}
else if ( aIsNaN ) {
- if ( bIsSignalingNaN | ! bIsNaN ) return a;
+ if ( bIsSignalingNaN || ! bIsNaN ) return a;
returnLargerSignificand:
if ( a.low < b.low ) return b;
if ( b.low < a.low ) return a;
@@ -567,7 +567,7 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
return bIsNaN ? b : a;
}
else if ( aIsNaN ) {
- if ( bIsSignalingNaN | ! bIsNaN ) return a;
+ if ( bIsSignalingNaN || ! bIsNaN ) return a;
returnLargerSignificand:
if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
diff --git a/src/recompiler/fpu/softfloat.c b/src/recompiler/fpu/softfloat.c
index 4d58744c8..6806ebc27 100644
--- a/src/recompiler/fpu/softfloat.c
+++ b/src/recompiler/fpu/softfloat.c
@@ -1910,7 +1910,7 @@ float32 float32_div( float32 a, float32 b STATUS_PARAM )
float32 float32_rem( float32 a, float32 b STATUS_PARAM )
{
- flag aSign, bSign, zSign;
+ flag aSign, zSign;
int16 aExp, bExp, expDiff;
bits32 aSig, bSig;
bits32 q;
@@ -1923,7 +1923,6 @@ float32 float32_rem( float32 a, float32 b STATUS_PARAM )
aSign = extractFloat32Sign( a );
bSig = extractFloat32Frac( b );
bExp = extractFloat32Exp( b );
- bSign = extractFloat32Sign( b );
if ( aExp == 0xFF ) {
if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
return propagateFloat32NaN( a, b STATUS_VAR );
@@ -2057,6 +2056,85 @@ float32 float32_sqrt( float32 a STATUS_PARAM )
}
/*----------------------------------------------------------------------------
+| Returns the binary exponential of the single-precision floating-point value
+| `a'. The operation is performed according to the IEC/IEEE Standard for
+| Binary Floating-Point Arithmetic.
+|
+| Uses the following identities:
+|
+| 1. -------------------------------------------------------------------------
+| x x*ln(2)
+| 2 = e
+|
+| 2. -------------------------------------------------------------------------
+| 2 3 4 5 n
+| x x x x x x x
+| e = 1 + --- + --- + --- + --- + --- + ... + --- + ...
+| 1! 2! 3! 4! 5! n!
+*----------------------------------------------------------------------------*/
+
+static const float64 float32_exp2_coefficients[15] =
+{
+ make_float64( 0x3ff0000000000000ll ), /* 1 */
+ make_float64( 0x3fe0000000000000ll ), /* 2 */
+ make_float64( 0x3fc5555555555555ll ), /* 3 */
+ make_float64( 0x3fa5555555555555ll ), /* 4 */
+ make_float64( 0x3f81111111111111ll ), /* 5 */
+ make_float64( 0x3f56c16c16c16c17ll ), /* 6 */
+ make_float64( 0x3f2a01a01a01a01all ), /* 7 */
+ make_float64( 0x3efa01a01a01a01all ), /* 8 */
+ make_float64( 0x3ec71de3a556c734ll ), /* 9 */
+ make_float64( 0x3e927e4fb7789f5cll ), /* 10 */
+ make_float64( 0x3e5ae64567f544e4ll ), /* 11 */
+ make_float64( 0x3e21eed8eff8d898ll ), /* 12 */
+ make_float64( 0x3de6124613a86d09ll ), /* 13 */
+ make_float64( 0x3da93974a8c07c9dll ), /* 14 */
+ make_float64( 0x3d6ae7f3e733b81fll ), /* 15 */
+};
+
+float32 float32_exp2( float32 a STATUS_PARAM )
+{
+ flag aSign;
+ int16 aExp;
+ bits32 aSig;
+ float64 r, x, xn;
+ int i;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ aSign = extractFloat32Sign( a );
+
+ if ( aExp == 0xFF) {
+ if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
+ return (aSign) ? float32_zero : a;
+ }
+ if (aExp == 0) {
+ if (aSig == 0) return float32_one;
+ }
+
+ float_raise( float_flag_inexact STATUS_VAR);
+
+ /* ******************************* */
+ /* using float64 for approximation */
+ /* ******************************* */
+ x = float32_to_float64(a STATUS_VAR);
+ x = float64_mul(x, float64_ln2 STATUS_VAR);
+
+ xn = x;
+ r = float64_one;
+ for (i = 0 ; i < 15 ; i++) {
+ float64 f;
+
+ f = float64_mul(xn, float32_exp2_coefficients[i] STATUS_VAR);
+ r = float64_add(r, f STATUS_VAR);
+
+ xn = float64_mul(xn, x STATUS_VAR);
+ }
+
+ return float64_to_float32(r, status);
+}
+
+/*----------------------------------------------------------------------------
| Returns the binary log of the single-precision floating-point value `a'.
| The operation is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
@@ -2457,6 +2535,144 @@ float32 float64_to_float32( float64 a STATUS_PARAM )
}
+
+/*----------------------------------------------------------------------------
+| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
+| half-precision floating-point value, returning the result. After being
+| shifted into the proper positions, the three fields are simply added
+| together to form the result. This means that any integer portion of `zSig'
+| will be added into the exponent. Since a properly normalized significand
+| will have an integer portion equal to 1, the `zExp' input should be 1 less
+| than the desired result exponent whenever `zSig' is a complete, normalized
+| significand.
+*----------------------------------------------------------------------------*/
+static bits16 packFloat16(flag zSign, int16 zExp, bits16 zSig)
+{
+ return (((bits32)zSign) << 15) + (((bits32)zExp) << 10) + zSig;
+}
+
+/* Half precision floats come in two formats: standard IEEE and "ARM" format.
+ The latter gains extra exponent range by omitting the NaN/Inf encodings. */
+
+float32 float16_to_float32( bits16 a, flag ieee STATUS_PARAM )
+{
+ flag aSign;
+ int16 aExp;
+ bits32 aSig;
+
+ aSign = a >> 15;
+ aExp = (a >> 10) & 0x1f;
+ aSig = a & 0x3ff;
+
+ if (aExp == 0x1f && ieee) {
+ if (aSig) {
+ /* Make sure correct exceptions are raised. */
+ float32ToCommonNaN(a STATUS_VAR);
+ aSig |= 0x200;
+ }
+ return packFloat32(aSign, 0xff, aSig << 13);
+ }
+ if (aExp == 0) {
+ int8 shiftCount;
+
+ if (aSig == 0) {
+ return packFloat32(aSign, 0, 0);
+ }
+
+ shiftCount = countLeadingZeros32( aSig ) - 21;
+ aSig = aSig << shiftCount;
+ aExp = -shiftCount;
+ }
+ return packFloat32( aSign, aExp + 0x70, aSig << 13);
+}
+
+bits16 float32_to_float16( float32 a, flag ieee STATUS_PARAM)
+{
+ flag aSign;
+ int16 aExp;
+ bits32 aSig;
+ bits32 mask;
+ bits32 increment;
+ int8 roundingMode;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ aSign = extractFloat32Sign( a );
+ if ( aExp == 0xFF ) {
+ if (aSig) {
+ /* Make sure correct exceptions are raised. */
+ float32ToCommonNaN(a STATUS_VAR);
+ aSig |= 0x00400000;
+ }
+ return packFloat16(aSign, 0x1f, aSig >> 13);
+ }
+ if (aExp == 0 && aSign == 0) {
+ return packFloat16(aSign, 0, 0);
+ }
+ /* Decimal point between bits 22 and 23. */
+ aSig |= 0x00800000;
+ aExp -= 0x7f;
+ if (aExp < -14) {
+ mask = 0x007fffff;
+ if (aExp < -24) {
+ aExp = -25;
+ } else {
+ mask >>= 24 + aExp;
+ }
+ } else {
+ mask = 0x00001fff;
+ }
+ if (aSig & mask) {
+ float_raise( float_flag_underflow STATUS_VAR );
+ roundingMode = STATUS(float_rounding_mode);
+ switch (roundingMode) {
+ case float_round_nearest_even:
+ increment = (mask + 1) >> 1;
+ if ((aSig & mask) == increment) {
+ increment = aSig & (increment << 1);
+ }
+ break;
+ case float_round_up:
+ increment = aSign ? 0 : mask;
+ break;
+ case float_round_down:
+ increment = aSign ? mask : 0;
+ break;
+ default: /* round_to_zero */
+ increment = 0;
+ break;
+ }
+ aSig += increment;
+ if (aSig >= 0x01000000) {
+ aSig >>= 1;
+ aExp++;
+ }
+ } else if (aExp < -14
+ && STATUS(float_detect_tininess) == float_tininess_before_rounding) {
+ float_raise( float_flag_underflow STATUS_VAR);
+ }
+
+ if (ieee) {
+ if (aExp > 15) {
+ float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
+ return packFloat16(aSign, 0x1f, 0);
+ }
+ } else {
+ if (aExp > 16) {
+ float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
+ return packFloat16(aSign, 0x1f, 0x3ff);
+ }
+ }
+ if (aExp < -24) {
+ return packFloat16(aSign, 0, 0);
+ }
+ if (aExp < -14) {
+ aSig >>= -14 - aExp;
+ aExp = -14;
+ }
+ return packFloat16(aSign, aExp + 14, aSig >> 13);
+}
+
#ifdef FLOATX80
/*----------------------------------------------------------------------------
@@ -2924,7 +3140,7 @@ float64 float64_div( float64 a, float64 b STATUS_PARAM )
float64 float64_rem( float64 a, float64 b STATUS_PARAM )
{
- flag aSign, bSign, zSign;
+ flag aSign, zSign;
int16 aExp, bExp, expDiff;
bits64 aSig, bSig;
bits64 q, alternateASig;
@@ -2935,7 +3151,6 @@ float64 float64_rem( float64 a, float64 b STATUS_PARAM )
aSign = extractFloat64Sign( a );
bSig = extractFloat64Frac( b );
bExp = extractFloat64Exp( b );
- bSign = extractFloat64Sign( b );
if ( aExp == 0x7FF ) {
if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
return propagateFloat64NaN( a, b STATUS_VAR );
@@ -3894,7 +4109,7 @@ floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM )
floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM )
{
- flag aSign, bSign, zSign;
+ flag aSign, zSign;
int32 aExp, bExp, expDiff;
bits64 aSig0, aSig1, bSig;
bits64 q, term0, term1, alternateASig0, alternateASig1;
@@ -3905,7 +4120,6 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM )
aSign = extractFloatx80Sign( a );
bSig = extractFloatx80Frac( b );
bExp = extractFloatx80Exp( b );
- bSign = extractFloatx80Sign( b );
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig0<<1 )
|| ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
@@ -5006,7 +5220,7 @@ float128 float128_div( float128 a, float128 b STATUS_PARAM )
float128 float128_rem( float128 a, float128 b STATUS_PARAM )
{
- flag aSign, bSign, zSign;
+ flag aSign, zSign;
int32 aExp, bExp, expDiff;
bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
bits64 allZero, alternateASig0, alternateASig1, sigMean1;
@@ -5020,7 +5234,6 @@ float128 float128_rem( float128 a, float128 b STATUS_PARAM )
bSig1 = extractFloat128Frac1( b );
bSig0 = extractFloat128Frac0( b );
bExp = extractFloat128Exp( b );
- bSign = extractFloat128Sign( b );
if ( aExp == 0x7FFF ) {
if ( ( aSig0 | aSig1 )
|| ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
diff --git a/src/recompiler/fpu/softfloat.h b/src/recompiler/fpu/softfloat.h
index 446bc165d..c209cd97e 100644
--- a/src/recompiler/fpu/softfloat.h
+++ b/src/recompiler/fpu/softfloat.h
@@ -36,7 +36,7 @@ these four paragraphs for those parts of this code that are retained.
#include <VBox/types.h>
#endif
-#if defined(HOST_SOLARIS) && defined(NEEDS_LIBSUNMATH)
+#if defined(CONFIG_SOLARIS) && defined(CONFIG_NEEDS_LIBSUNMATH)
#include <sunmath.h>
#endif
@@ -94,7 +94,7 @@ typedef int64_t sbits64;
#define FLOAT128
#else
/* native float support */
-#if (defined(__i386__) || defined(__x86_64__)) && (!defined(_BSD) || defined(VBOX))
+#if (defined(__i386__) || defined(__x86_64__)) && (!defined(CONFIG_BSD) || defined(VBOX)) /** @todo VBOX: not correct on windows */
#define FLOATX80
#endif
#endif /* !CONFIG_SOFTFLOAT */
@@ -154,7 +154,7 @@ typedef struct {
#endif
#ifdef FLOAT128
typedef struct {
-#ifdef WORDS_BIGENDIAN
+#ifdef HOST_WORDS_BIGENDIAN
uint64_t high, low;
#else
uint64_t low, high;
@@ -251,6 +251,12 @@ float128 int64_to_float128( int64_t STATUS_PARAM );
#endif
/*----------------------------------------------------------------------------
+| Software half-precision conversion routines.
+*----------------------------------------------------------------------------*/
+bits16 float32_to_float16( float32, flag STATUS_PARAM );
+float32 float16_to_float32( bits16, flag STATUS_PARAM );
+
+/*----------------------------------------------------------------------------
| Software IEC/IEEE single-precision conversion routines.
*----------------------------------------------------------------------------*/
int float32_to_int32( float32 STATUS_PARAM );
@@ -277,6 +283,7 @@ float32 float32_mul( float32, float32 STATUS_PARAM );
float32 float32_div( float32, float32 STATUS_PARAM );
float32 float32_rem( float32, float32 STATUS_PARAM );
float32 float32_sqrt( float32 STATUS_PARAM );
+float32 float32_exp2( float32 STATUS_PARAM );
float32 float32_log2( float32 STATUS_PARAM );
int float32_eq( float32, float32 STATUS_PARAM );
int float32_le( float32, float32 STATUS_PARAM );
@@ -317,6 +324,7 @@ INLINE int float32_is_zero(float32 a)
#define float32_zero make_float32(0)
#define float32_one make_float32(0x3f800000)
+#define float32_ln2 make_float32(0x3f317218)
/*----------------------------------------------------------------------------
| Software IEC/IEEE double-precision conversion routines.
@@ -388,6 +396,7 @@ INLINE int float64_is_zero(float64 a)
#define float64_zero make_float64(0)
#define float64_one make_float64(0x3ff0000000000000LL)
+#define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
#ifdef FLOATX80
diff --git a/src/recompiler/gen-icount.h b/src/recompiler/gen-icount.h
index 5beeeb479..8879da633 100644
--- a/src/recompiler/gen-icount.h
+++ b/src/recompiler/gen-icount.h
@@ -1,28 +1,19 @@
+#include "qemu-timer.h"
+
/* Helpers for instruction counting code generation. */
static TCGArg *icount_arg;
static int icount_label;
-#ifndef VBOX
static inline void gen_icount_start(void)
-#else /* VBOX */
-DECLINLINE(void) gen_icount_start(void)
-#endif /* VBOX */
{
- TCGv count;
+ TCGv_i32 count;
if (!use_icount)
return;
icount_label = gen_new_label();
- /* FIXME: This generates lousy code. We can't use tcg_new_temp because
- count needs to live over the conditional branch. To workaround this
- we allow the target to supply a convenient register temporary. */
-#ifndef ICOUNT_TEMP
- count = tcg_temp_local_new(TCG_TYPE_I32);
-#else
- count = ICOUNT_TEMP;
-#endif
+ count = tcg_temp_local_new_i32();
tcg_gen_ld_i32(count, cpu_env, offsetof(CPUState, icount_decr.u32));
/* This is a horrid hack to allow fixing up the value later. */
icount_arg = gen_opparam_ptr + 1;
@@ -30,9 +21,7 @@ DECLINLINE(void) gen_icount_start(void)
tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label);
tcg_gen_st16_i32(count, cpu_env, offsetof(CPUState, icount_decr.u16.low));
-#ifndef ICOUNT_TEMP
- tcg_temp_free(count);
-#endif
+ tcg_temp_free_i32(count);
}
static void gen_icount_end(TranslationBlock *tb, int num_insns)
@@ -44,25 +33,16 @@ static void gen_icount_end(TranslationBlock *tb, int num_insns)
}
}
-#ifndef VBOX
-inline static void gen_io_start(void)
-#else
-DECLINLINE(void) gen_io_start(void)
-#endif
+static inline void gen_io_start(void)
{
- TCGv tmp = tcg_const_i32(1);
+ TCGv_i32 tmp = tcg_const_i32(1);
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, can_do_io));
- tcg_temp_free(tmp);
+ tcg_temp_free_i32(tmp);
}
-#ifndef VBOX
static inline void gen_io_end(void)
-#else /* VBOX */
-DECLINLINE(void) gen_io_end(void)
-#endif /* VBOX */
{
- TCGv tmp = tcg_const_i32(0);
+ TCGv_i32 tmp = tcg_const_i32(0);
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, can_do_io));
- tcg_temp_free(tmp);
+ tcg_temp_free_i32(tmp);
}
-
diff --git a/src/recompiler/host-utils.c b/src/recompiler/host-utils.c
index f92c3396c..4afee79e5 100644
--- a/src/recompiler/host-utils.c
+++ b/src/recompiler/host-utils.c
@@ -23,7 +23,12 @@
* THE SOFTWARE.
*/
-#include "exec.h"
+#include <stdlib.h>
+#ifndef VBOX
+#include <stdint.h>
+#else
+# include <iprt/types.h>
+#endif
#include "host-utils.h"
//#define DEBUG_MULDIV
diff --git a/src/recompiler/host-utils.h b/src/recompiler/host-utils.h
index eb83cd260..0ddc17658 100644
--- a/src/recompiler/host-utils.h
+++ b/src/recompiler/host-utils.h
@@ -27,16 +27,16 @@
#if defined(__x86_64__)
#define __HAVE_FAST_MULU64__
-static always_inline void mulu64 (uint64_t *plow, uint64_t *phigh,
- uint64_t a, uint64_t b)
+static inline void mulu64(uint64_t *plow, uint64_t *phigh,
+ uint64_t a, uint64_t b)
{
__asm__ ("mul %0\n\t"
: "=d" (*phigh), "=a" (*plow)
: "a" (a), "0" (b));
}
#define __HAVE_FAST_MULS64__
-static always_inline void muls64 (uint64_t *plow, uint64_t *phigh,
- int64_t a, int64_t b)
+static inline void muls64(uint64_t *plow, uint64_t *phigh,
+ int64_t a, int64_t b)
{
__asm__ ("imul %0\n\t"
: "=d" (*phigh), "=a" (*plow)
@@ -49,11 +49,7 @@ void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
/* Binary search for leading zeros. */
-#ifndef VBOX
-static always_inline int clz32(uint32_t val)
-#else
-DECLALWAYSINLINE(int) clz32(uint32_t val)
-#endif
+static inline int clz32(uint32_t val)
{
#if QEMU_GNUC_PREREQ(3, 4)
if (val)
@@ -90,20 +86,12 @@ DECLALWAYSINLINE(int) clz32(uint32_t val)
#endif
}
-#ifndef VBOX
-static always_inline int clo32(uint32_t val)
-#else
-DECLALWAYSINLINE(int) clo32(uint32_t val)
-#endif
+static inline int clo32(uint32_t val)
{
return clz32(~val);
}
-#ifndef VBOX
-static always_inline int clz64(uint64_t val)
-#else
-DECLALWAYSINLINE(int) clz64(uint64_t val)
-#endif
+static inline int clz64(uint64_t val)
{
#if QEMU_GNUC_PREREQ(3, 4)
if (val)
@@ -123,20 +111,12 @@ DECLALWAYSINLINE(int) clz64(uint64_t val)
#endif
}
-#ifndef VBOX
-static always_inline int clo64(uint64_t val)
-#else
-DECLALWAYSINLINE(int) clo64(uint64_t val)
-#endif
+static inline int clo64(uint64_t val)
{
return clz64(~val);
}
-#ifndef VBOX
-static always_inline int ctz32 (uint32_t val)
-#else
-DECLALWAYSINLINE(int) ctz32 (uint32_t val)
-#endif
+static inline int ctz32(uint32_t val)
{
#if QEMU_GNUC_PREREQ(3, 4)
if (val)
@@ -148,51 +128,43 @@ DECLALWAYSINLINE(int) ctz32 (uint32_t val)
cnt = 0;
if (!(val & 0x0000FFFFUL)) {
- cnt += 16;
+ cnt += 16;
val >>= 16;
- }
+ }
if (!(val & 0x000000FFUL)) {
- cnt += 8;
+ cnt += 8;
val >>= 8;
- }
+ }
if (!(val & 0x0000000FUL)) {
- cnt += 4;
+ cnt += 4;
val >>= 4;
- }
+ }
if (!(val & 0x00000003UL)) {
- cnt += 2;
+ cnt += 2;
val >>= 2;
- }
+ }
if (!(val & 0x00000001UL)) {
- cnt++;
+ cnt++;
val >>= 1;
- }
+ }
if (!(val & 0x00000001UL)) {
- cnt++;
- }
+ cnt++;
+ }
- return cnt;
+ return cnt;
#endif
- }
+}
-#ifndef VBOX
-static always_inline int cto32 (uint32_t val)
-#else
-DECLALWAYSINLINE(int) cto32 (uint32_t val)
-#endif
+static inline int cto32(uint32_t val)
{
return ctz32(~val);
}
-#ifndef VBOX
-static always_inline int ctz64 (uint64_t val)
-#else
-DECLALWAYSINLINE(int) ctz64 (uint64_t val)
-#endif
+static inline int ctz64(uint64_t val)
{
#if QEMU_GNUC_PREREQ(3, 4)
if (val)
- return __builtin_ctz(val);
+ return __builtin_ctzll(val);
else
return 64;
#else
@@ -208,20 +180,12 @@ DECLALWAYSINLINE(int) ctz64 (uint64_t val)
#endif
}
-#ifndef VBOX
-static always_inline int cto64 (uint64_t val)
-#else
-DECLALWAYSINLINE(int) cto64 (uint64_t val)
-#endif
+static inline int cto64(uint64_t val)
{
return ctz64(~val);
}
-#ifndef VBOX
-static always_inline int ctpop8 (uint8_t val)
-#else
-DECLALWAYSINLINE(int) ctpop8 (uint8_t val)
-#endif
+static inline int ctpop8(uint8_t val)
{
val = (val & 0x55) + ((val >> 1) & 0x55);
val = (val & 0x33) + ((val >> 2) & 0x33);
@@ -230,11 +194,7 @@ DECLALWAYSINLINE(int) ctpop8 (uint8_t val)
return val;
}
-#ifndef VBOX
-static always_inline int ctpop16 (uint16_t val)
-#else
-DECLALWAYSINLINE(int) ctpop16 (uint16_t val)
-#endif
+static inline int ctpop16(uint16_t val)
{
val = (val & 0x5555) + ((val >> 1) & 0x5555);
val = (val & 0x3333) + ((val >> 2) & 0x3333);
@@ -244,11 +204,7 @@ DECLALWAYSINLINE(int) ctpop16 (uint16_t val)
return val;
}
-#ifndef VBOX
-static always_inline int ctpop32 (uint32_t val)
-#else
-DECLALWAYSINLINE(int) ctpop32 (uint32_t val)
-#endif
+static inline int ctpop32(uint32_t val)
{
#if QEMU_GNUC_PREREQ(3, 4)
return __builtin_popcount(val);
@@ -263,11 +219,7 @@ DECLALWAYSINLINE(int) ctpop32 (uint32_t val)
#endif
}
-#ifndef VBOX
-static always_inline int ctpop64 (uint64_t val)
-#else
-DECLALWAYSINLINE(int) ctpop64 (uint64_t val)
-#endif
+static inline int ctpop64(uint64_t val)
{
#if QEMU_GNUC_PREREQ(3, 4)
return __builtin_popcountll(val);
diff --git a/src/recompiler/hostregs_helper.h b/src/recompiler/hostregs_helper.h
index 22ca4892a..c6c1ddb96 100644
--- a/src/recompiler/hostregs_helper.h
+++ b/src/recompiler/hostregs_helper.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -28,47 +27,29 @@
*/
/* The GCC global register variable extension is used to reserve some
- host registers for use by dyngen. However only the core parts of the
- translation engine are compiled with these settings. We must manually
+ host registers for use by generated code. However only the core parts of
+ the translation engine are compiled with these settings. We must manually
save/restore these registers when called from regular code.
It is not sufficient to save/restore T0 et. al. as these may be declared
with a datatype smaller than the actual register. */
#if defined(DECLARE_HOST_REGS)
-#ifndef VBOX
#define DO_REG(REG) \
register host_reg_t reg_AREG##REG asm(AREG##REG); \
volatile host_reg_t saved_AREG##REG;
-#else
-#define DO_REG(REG) \
- REGISTER_BOUND_GLOBAL(host_reg_t, reg_AREG##REG, AREG##REG); \
- volatile host_reg_t saved_AREG##REG;
-#endif
#elif defined(SAVE_HOST_REGS)
-#ifndef VBOX
#define DO_REG(REG) \
__asm__ __volatile__ ("" : "=r" (reg_AREG##REG)); \
saved_AREG##REG = reg_AREG##REG;
-#else /* VBOX */
-#define DO_REG(REG) \
- SAVE_GLOBAL_REGISTER(REG, reg_AREG##REG); \
- saved_AREG##REG = reg_AREG##REG;
-#endif /* VBOX */
#else
-#ifndef VBOX
#define DO_REG(REG) \
reg_AREG##REG = saved_AREG##REG; \
__asm__ __volatile__ ("" : : "r" (reg_AREG##REG));
-#else /* VBOX */
-#define DO_REG(REG) \
- reg_AREG##REG = saved_AREG##REG; \
- RESTORE_GLOBAL_REGISTER(REG, reg_AREG##REG);
-#endif
#endif
@@ -84,42 +65,6 @@ DO_REG(1)
DO_REG(2)
#endif
-#ifdef AREG3
-DO_REG(3)
-#endif
-
-#ifdef AREG4
-DO_REG(4)
-#endif
-
-#ifdef AREG5
-DO_REG(5)
-#endif
-
-#ifdef AREG6
-DO_REG(6)
-#endif
-
-#ifdef AREG7
-DO_REG(7)
-#endif
-
-#ifdef AREG8
-DO_REG(8)
-#endif
-
-#ifdef AREG9
-DO_REG(9)
-#endif
-
-#ifdef AREG10
-DO_REG(10)
-#endif
-
-#ifdef AREG11
-DO_REG(11)
-#endif
-
#undef SAVE_HOST_REGS
#undef DECLARE_HOST_REGS
#undef DO_REG
diff --git a/src/recompiler/ioport.h b/src/recompiler/ioport.h
new file mode 100644
index 000000000..8df11ce01
--- /dev/null
+++ b/src/recompiler/ioport.h
@@ -0,0 +1,71 @@
+/*
+ * defines ioport related functions
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * 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.
+ */
+
+/**************************************************************************
+ * IO ports API
+ */
+
+#ifndef IOPORT_H
+#define IOPORT_H
+
+#include "qemu-common.h"
+
+typedef uint32_t pio_addr_t;
+#define FMT_pioaddr PRIx32
+
+#define MAX_IOPORTS (64 * 1024)
+#define IOPORTS_MASK (MAX_IOPORTS - 1)
+
+/* These should really be in isa.h, but are here to make pc.h happy. */
+typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
+typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
+
+int register_ioport_read(pio_addr_t start, int length, int size,
+ IOPortReadFunc *func, void *opaque);
+int register_ioport_write(pio_addr_t start, int length, int size,
+ IOPortWriteFunc *func, void *opaque);
+void isa_unassign_ioport(pio_addr_t start, int length);
+
+
+#ifndef VBOX
+void cpu_outb(pio_addr_t addr, uint8_t val);
+void cpu_outw(pio_addr_t addr, uint16_t val);
+void cpu_outl(pio_addr_t addr, uint32_t val);
+uint8_t cpu_inb(pio_addr_t addr);
+uint16_t cpu_inw(pio_addr_t addr);
+uint32_t cpu_inl(pio_addr_t addr);
+#else
+void cpu_outb(CPUX86State *env, pio_addr_t addr, uint8_t val);
+void cpu_outw(CPUX86State *env, pio_addr_t addr, uint16_t val);
+void cpu_outl(CPUX86State *env, pio_addr_t addr, uint32_t val);
+uint8_t cpu_inb(CPUX86State *env, pio_addr_t addr);
+uint16_t cpu_inw(CPUX86State *env, pio_addr_t addr);
+uint32_t cpu_inl(CPUX86State *env, pio_addr_t addr);
+#endif
+
+#endif /* IOPORT_H */
diff --git a/src/recompiler/osdep.h b/src/recompiler/osdep.h
index 22c23d4b7..50480ce0a 100644
--- a/src/recompiler/osdep.h
+++ b/src/recompiler/osdep.h
@@ -1,7 +1,7 @@
#ifndef QEMU_OSDEP_H
#define QEMU_OSDEP_H
-#ifdef VBOX
+#ifdef VBOX /** @todo clean up this, it's not fully synched. */
#include <iprt/alloc.h>
#ifndef RT_OS_WINDOWS
@@ -14,30 +14,20 @@
#define VBOX_ONLY(x) x
-#ifndef _MSC_VER
#define qemu_snprintf(pszBuf, cbBuf, ...) RTStrPrintf((pszBuf), (cbBuf), __VA_ARGS__)
-#else
-#define qemu_snprintf RTStrPrintf
-#endif
#define qemu_vsnprintf(pszBuf, cbBuf, pszFormat, args) \
RTStrPrintfV((pszBuf), (cbBuf), (pszFormat), (args))
#define qemu_vprintf(pszFormat, args) \
RTLogPrintfV((pszFormat), (args))
-#define qemu_printf RTLogPrintf
+
+/**@todo the following macros belongs elsewhere */
#define qemu_malloc(cb) RTMemAlloc(cb)
#define qemu_mallocz(cb) RTMemAllocZ(cb)
#define qemu_realloc(ptr, cb) RTMemRealloc(ptr, cb)
-
#define qemu_free(pv) RTMemFree(pv)
#define qemu_strdup(psz) RTStrDup(psz)
-#define qemu_vmalloc(cb) RTMemPageAlloc(cb)
-#define qemu_vfree(pv) RTMemPageFree(pv, missing_size_parameter)
-
-#ifndef NULL
-# define NULL 0
-#endif
-
+/* Misc wrappers */
#define fflush(file) RTLogFlush(NULL)
#define printf(...) LogIt(LOG_INSTANCE, 0, LOG_GROUP_REM_PRINTF, (__VA_ARGS__))
/* If DEBUG_TMP_LOGGING - goes to QEMU log file */
@@ -45,30 +35,18 @@
# define fprintf(logfile, ...) LogIt(LOG_INSTANCE, 0, LOG_GROUP_REM_PRINTF, (__VA_ARGS__))
#endif
-#define assert(cond) Assert(cond)
+#define assert(cond) Assert(cond)
#else /* !VBOX */
#include <stdarg.h>
+#include <stddef.h>
-#define VBOX_ONLY(x)
-
+#define VBOX_ONLY(x) /* nike */
#define qemu_snprintf snprintf /* bird */
#define qemu_vsnprintf vsnprintf /* bird */
#define qemu_vprintf vprintf /* bird */
-#define qemu_printf printf
-
-void *qemu_malloc(size_t size);
-void *qemu_mallocz(size_t size);
-void qemu_free(void *ptr);
-char *qemu_strdup(const char *str);
-
-void *qemu_vmalloc(size_t size);
-void qemu_vfree(void *ptr);
-
-void *get_mmap_addr(unsigned long size);
-
#endif /* !VBOX */
#ifdef __OpenBSD__
@@ -76,6 +54,12 @@ void *get_mmap_addr(unsigned long size);
#include <sys/signal.h>
#endif
+#ifndef VBOX
+#ifndef _WIN32
+#include <sys/time.h>
+#endif
+#endif /* !VBOX */
+
#ifndef glue
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
@@ -84,20 +68,15 @@ void *get_mmap_addr(unsigned long size);
#endif
#ifndef likely
-#ifndef VBOX
#if __GNUC__ < 3
#define __builtin_expect(x, n) (x)
#endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
-#else /* VBOX */
-#define likely(cond) RT_LIKELY(cond)
-#define unlikely(cond) RT_UNLIKELY(cond)
#endif
-#endif /* !likely */
-#ifndef offsetof
+#ifdef CONFIG_NEED_OFFSETOF
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER)
#endif
#ifndef container_of
@@ -106,6 +85,19 @@ void *get_mmap_addr(unsigned long size);
(type *) ((char *) __mptr - offsetof(type, member));})
#endif
+/* Convert from a base type to a parent type, with compile time checking. */
+#ifdef __GNUC__
+#define DO_UPCAST(type, field, dev) ( __extension__ ( { \
+ char __attribute__((unused)) offset_must_be_zero[ \
+ -offsetof(type, field)]; \
+ container_of(dev, type, field);}))
+#else
+#define DO_UPCAST(type, field, dev) container_of(dev, type, field)
+#endif
+
+#define typeof_field(type, field) typeof(((type *)0)->field)
+#define type_check(t1,t2) ((t1*)0 - (t2*)0)
+
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
@@ -118,28 +110,28 @@ void *get_mmap_addr(unsigned long size);
#endif
#ifndef always_inline
-#if (__GNUC__ < 3) || defined(__APPLE__)
-#define always_inline inline
-#else
-#define always_inline __attribute__ (( always_inline )) __inline__
-#define inline always_inline
+#if !((__GNUC__ < 3) || defined(__APPLE__))
+#ifdef __OPTIMIZE__
+#define inline __attribute__ (( always_inline )) __inline__
+#endif
#endif
#else
#define inline always_inline
#endif
#ifdef __i386__
-#ifdef _MSC_VER
-/** @todo: maybe wrong, or slow */
-#define REGPARM
-#else
#define REGPARM __attribute((regparm(3)))
-#endif
#else
#define REGPARM
#endif
-#if defined (__GNUC__) && defined (__GNUC_MINOR_)
+#ifndef VBOX
+#define qemu_printf printf
+#else /*VBOX*/
+#define qemu_printf RTLogPrintf
+#endif /*VBOX*/
+
+#if defined (__GNUC__) && defined (__GNUC_MINOR__)
# define QEMU_GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
#else
@@ -165,28 +157,10 @@ int qemu_gettimeofday(qemu_timeval *tp);
typedef struct timeval qemu_timeval;
#define qemu_gettimeofday(tp) gettimeofday(tp, NULL);
#endif /* !_WIN32 */
-#endif /* !VBOX */
-
-#ifdef VBOX
-#ifdef _MSC_VER
-#define ALIGNED_MEMBER(type, name, bytes) type name
-#define ALIGNED_MEMBER_DEF(type, name) type name
-#define PACKED_STRUCT(name) struct name
-#define REGISTER_BOUND_GLOBAL(type, var, reg) type var
-#define SAVE_GLOBAL_REGISTER(reg, var)
-#define RESTORE_GLOBAL_REGISTER(reg, var)
-#define DECLALWAYSINLINE(type) DECLINLINE(type)
-#define FORCE_RET() ;
-#else /* ! _MSC_VER */
-#define ALIGNED_MEMBER(type, name, bytes) type name __attribute__((aligned(bytes)))
-#define ALIGNED_MEMBER_DEF(type, name) type name __attribute__((aligned()))
-#define PACKED_STRUCT(name) struct __attribute__ ((__packed__)) name
-#define REGISTER_BOUND_GLOBAL(type, var, reg) register type var asm(reg)
-#define SAVE_GLOBAL_REGISTER(reg, var) __asm__ __volatile__ ("" : "=r" (var))
-#define RESTORE_GLOBAL_REGISTER(reg, var) __asm__ __volatile__ ("" : : "r" (var))
-#define DECLALWAYSINLINE(type) static always_inline type
-#define FORCE_RET() ;
-#endif /* !_MSC_VER */
+#else /* VBOX */
+# define qemu_memalign(alignment, size) ( (alignment) <= PAGE_SIZE ? RTMemPageAlloc((size)) : NULL )
+# define qemu_vfree(pv) RTMemPageFree(pv, missing_size_parameter)
+# define qemu_vmalloc(cb) RTMemPageAlloc(cb)
#endif /* VBOX */
#endif
diff --git a/src/recompiler/qemu-barrier.h b/src/recompiler/qemu-barrier.h
new file mode 100644
index 000000000..b77fce23a
--- /dev/null
+++ b/src/recompiler/qemu-barrier.h
@@ -0,0 +1,10 @@
+#ifndef __QEMU_BARRIER_H
+#define __QEMU_BARRIER_H 1
+
+/* FIXME: arch dependant, x86 version */
+#define smp_wmb() asm volatile("" ::: "memory")
+
+/* Compiler barrier */
+#define barrier() asm volatile("" ::: "memory")
+
+#endif
diff --git a/src/recompiler/qemu-common.h b/src/recompiler/qemu-common.h
index b802645d0..ca6e3ce21 100644
--- a/src/recompiler/qemu-common.h
+++ b/src/recompiler/qemu-common.h
@@ -2,40 +2,82 @@
#ifndef QEMU_COMMON_H
#define QEMU_COMMON_H
+#include "config-host.h"
+
#ifdef VBOX
-# include <string.h>
-# if !defined(_MSC_VER)
-# include <inttypes.h>
-# endif
+# include <iprt/string.h>
+# include <iprt/types.h>
+# include <iprt/ctype.h>
void pstrcpy(char *buf, int buf_size, const char *str);
char *pstrcat(char *buf, int buf_size, const char *s);
-# define snprintf RTStrPrintf
-
-# ifdef _MSC_VER
-# define PRId32 "d"
-# define PRIx32 "x"
-# define PRIu32 "u"
-# define PRIo32 "o"
-# ifdef DEBUG_TMP_LOGGING
-# define PRId64 "I64d"
-# define PRIx64 "I64x"
-# define PRIu64 "I64u"
-# define PRIo64 "I64o"
-# else
-# define PRId64 "RI64"
-# define PRIx64 "RX64"
-# define PRIu64 "RU64"
-# endif
-# endif /* _MSC_VER */
+# define snprintf RTStrPrintf
+
+# define qemu_isalnum(c) RT_C_IS_ALNUM((unsigned char)(c))
+# define qemu_isalpha(c) RT_C_IS_ALPHA((unsigned char)(c))
+# define qemu_iscntrl(c) RT_C_IS_CNTRL((unsigned char)(c))
+# define qemu_isdigit(c) RT_C_IS_DIGIT((unsigned char)(c))
+# define qemu_isgraph(c) RT_C_IS_GRAPH((unsigned char)(c))
+# define qemu_islower(c) RT_C_IS_LOWER((unsigned char)(c))
+# define qemu_isprint(c) RT_C_IS_PRINT((unsigned char)(c))
+# define qemu_ispunct(c) RT_C_IS_PUNCT((unsigned char)(c))
+# define qemu_isspace(c) RT_C_IS_SPACE((unsigned char)(c))
+# define qemu_isupper(c) RT_C_IS_UPPER((unsigned char)(c))
+# define qemu_isxdigit(c) RT_C_IS_XDIGIT((unsigned char)(c))
+# define qemu_tolower(c) RT_C_TO_LOWER((unsigned char)(c))
+# define qemu_toupper(c) RT_C_TO_UPPER((unsigned char)(c))
+# define qemu_isascii(c) RT_C_IS_ASCII((unsigned char)(c))
+# define qemu_toascii(c) RT_C_TO_ASCII((unsigned char)(c))
+
+# define qemu_init_vcpu(env) do { } while (0) /* we don't need this :-) */
+
+# define QEMU_NORETURN __attribute__((__noreturn__))
+# ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT
+# define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+# else
+# define QEMU_WARN_UNUSED_RESULT
+# endif
+#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1];
+
+#include <stdio.h>
+#include "cpu.h"
+
#else /* !VBOX */
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#define WINVER 0x0501 /* needed for ipv6 bits */
+#include <windows.h>
+#endif
+
+#define QEMU_NORETURN __attribute__ ((__noreturn__))
+#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT
+#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define QEMU_WARN_UNUSED_RESULT
+#endif
+
+#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1];
+
+typedef struct QEMUTimer QEMUTimer;
+typedef struct QEMUFile QEMUFile;
+typedef struct QEMUBH QEMUBH;
+typedef struct DeviceState DeviceState;
+
+
+/* Hack around the mess dyngen-exec.h causes: We need QEMU_NORETURN in files that
+ cannot include the following headers without conflicts. This condition has
+ to be removed once dyngen is gone. */
+#ifndef __DYNGEN_EXEC_H__
+
/* we put basic includes here to avoid repeating them in device drivers */
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <string.h>
+#include <strings.h>
#include <inttypes.h>
#include <limits.h>
#include <time.h>
@@ -44,6 +86,7 @@ char *pstrcat(char *buf, int buf_size, const char *s);
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
+#include <assert.h>
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
@@ -51,21 +94,36 @@ char *pstrcat(char *buf, int buf_size, const char *s);
#ifndef O_BINARY
#define O_BINARY 0
#endif
-
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
#ifndef ENOMEDIUM
#define ENOMEDIUM ENODEV
#endif
+#if !defined(ENOTSUP)
+#define ENOTSUP 4096
+#endif
+
+#ifndef CONFIG_IOVEC
+#define CONFIG_IOVEC
+struct iovec {
+ void *iov_base;
+ size_t iov_len;
+};
+/*
+ * Use the same value as Linux for now.
+ */
+#define IOV_MAX 1024
+#else
+#include <sys/uio.h>
+#endif
#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
#define fsync _commit
#define lseek _lseeki64
-#define ENOTSUP 4096
extern int qemu_ftruncate64(int, int64_t);
#define ftruncate qemu_ftruncate64
-
static inline char *realpath(const char *path, char *resolved_path)
{
_fullpath(resolved_path, path, _MAX_PATH);
@@ -81,7 +139,6 @@ static inline char *realpath(const char *path, char *resolved_path)
/* FIXME: Remove NEED_CPU_H. */
#ifndef NEED_CPU_H
-#include "config-host.h"
#include <setjmp.h>
#include "osdep.h"
#include "bswap.h"
@@ -93,15 +150,25 @@ static inline char *realpath(const char *path, char *resolved_path)
#endif /* !defined(NEED_CPU_H) */
/* bottom halves */
-typedef struct QEMUBH QEMUBH;
-
typedef void QEMUBHFunc(void *opaque);
+void async_context_push(void);
+void async_context_pop(void);
+int get_async_context_id(void);
+
QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
void qemu_bh_schedule(QEMUBH *bh);
+/* Bottom halfs that are scheduled from a bottom half handler are instantly
+ * invoked. This can create an infinite loop if a bottom half handler
+ * schedules itself. qemu_bh_schedule_idle() avoids this infinite loop by
+ * ensuring that the bottom half isn't executed until the next main loop
+ * iteration.
+ */
+void qemu_bh_schedule_idle(QEMUBH *bh);
void qemu_bh_cancel(QEMUBH *bh);
void qemu_bh_delete(QEMUBH *bh);
int qemu_bh_poll(void);
+void qemu_bh_update_timeout(int *timeout);
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
@@ -113,26 +180,60 @@ void pstrcpy(char *buf, int buf_size, const char *str);
char *pstrcat(char *buf, int buf_size, const char *s);
int strstart(const char *str, const char *val, const char **ptr);
int stristart(const char *str, const char *val, const char **ptr);
+int qemu_strnlen(const char *s, int max_len);
time_t mktimegm(struct tm *tm);
+int qemu_fls(int i);
+int qemu_fdatasync(int fd);
+int fcntl_setfl(int fd, int flag);
+
+/* path.c */
+void init_paths(const char *prefix);
+const char *path(const char *pathname);
+
+#define qemu_isalnum(c) isalnum((unsigned char)(c))
+#define qemu_isalpha(c) isalpha((unsigned char)(c))
+#define qemu_iscntrl(c) iscntrl((unsigned char)(c))
+#define qemu_isdigit(c) isdigit((unsigned char)(c))
+#define qemu_isgraph(c) isgraph((unsigned char)(c))
+#define qemu_islower(c) islower((unsigned char)(c))
+#define qemu_isprint(c) isprint((unsigned char)(c))
+#define qemu_ispunct(c) ispunct((unsigned char)(c))
+#define qemu_isspace(c) isspace((unsigned char)(c))
+#define qemu_isupper(c) isupper((unsigned char)(c))
+#define qemu_isxdigit(c) isxdigit((unsigned char)(c))
+#define qemu_tolower(c) tolower((unsigned char)(c))
+#define qemu_toupper(c) toupper((unsigned char)(c))
+#define qemu_isascii(c) isascii((unsigned char)(c))
+#define qemu_toascii(c) toascii((unsigned char)(c))
void *qemu_malloc(size_t size);
void *qemu_realloc(void *ptr, size_t size);
void *qemu_mallocz(size_t size);
void qemu_free(void *ptr);
char *qemu_strdup(const char *str);
+char *qemu_strndup(const char *str, size_t size);
-void *get_mmap_addr(unsigned long size);
+void qemu_mutex_lock_iothread(void);
+void qemu_mutex_unlock_iothread(void);
+int qemu_open(const char *name, int flags, ...);
+ssize_t qemu_write_full(int fd, const void *buf, size_t count)
+ QEMU_WARN_UNUSED_RESULT;
+void qemu_set_cloexec(int fd);
+
+#ifndef _WIN32
+int qemu_eventfd(int pipefd[2]);
+int qemu_pipe(int pipefd[2]);
+#endif
/* Error handling. */
-void hw_error(const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)))
- __attribute__ ((__noreturn__));
+void QEMU_NORETURN hw_error(const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 1, 2)));
/* IO callbacks. */
typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
-typedef int IOCanRWHandler(void *opaque);
+typedef int IOCanReadHandler(void *opaque);
typedef void IOHandler(void *opaque);
struct ParallelIOArg {
@@ -149,20 +250,36 @@ typedef struct HCIInfo HCIInfo;
typedef struct AudioState AudioState;
typedef struct BlockDriverState BlockDriverState;
typedef struct DisplayState DisplayState;
+typedef struct DisplayChangeListener DisplayChangeListener;
+typedef struct DisplaySurface DisplaySurface;
+typedef struct DisplayAllocator DisplayAllocator;
+typedef struct PixelFormat PixelFormat;
typedef struct TextConsole TextConsole;
typedef TextConsole QEMUConsole;
typedef struct CharDriverState CharDriverState;
+typedef struct MACAddr MACAddr;
typedef struct VLANState VLANState;
-typedef struct QEMUFile QEMUFile;
+typedef struct VLANClientState VLANClientState;
typedef struct i2c_bus i2c_bus;
typedef struct i2c_slave i2c_slave;
typedef struct SMBusDevice SMBusDevice;
-typedef struct QEMUTimer QEMUTimer;
+typedef struct PCIHostState PCIHostState;
+typedef struct PCIExpressHost PCIExpressHost;
typedef struct PCIBus PCIBus;
typedef struct PCIDevice PCIDevice;
typedef struct SerialState SerialState;
typedef struct IRQState *qemu_irq;
-struct pcmcia_card_s;
+typedef struct PCMCIACardState PCMCIACardState;
+typedef struct MouseTransformInfo MouseTransformInfo;
+typedef struct uWireSlave uWireSlave;
+typedef struct I2SCodec I2SCodec;
+typedef struct SSIBus SSIBus;
+typedef struct EventNotifier EventNotifier;
+typedef struct VirtIODevice VirtIODevice;
+
+typedef uint64_t pcibus_t;
+
+void cpu_exec_init_all(unsigned long tb_size);
/* CPU save/load. */
void cpu_save(QEMUFile *f, void *opaque);
@@ -170,6 +287,62 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id);
/* Force QEMU to stop what it's doing and service IO */
void qemu_service_io(void);
+
+/* Force QEMU to process pending events */
+void qemu_notify_event(void);
+
+/* Unblock cpu */
+void qemu_cpu_kick(void *env);
+int qemu_cpu_self(void *env);
+
+/* work queue */
+struct qemu_work_item {
+ struct qemu_work_item *next;
+ void (*func)(void *data);
+ void *data;
+ int done;
+};
+
+#ifdef CONFIG_USER_ONLY
+#define qemu_init_vcpu(env) do { } while (0)
+#else
+void qemu_init_vcpu(void *env);
+#endif
+
+typedef struct QEMUIOVector {
+ struct iovec *iov;
+ int niov;
+ int nalloc;
+ size_t size;
+} QEMUIOVector;
+
+void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint);
+void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov);
+void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len);
+void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size);
+void qemu_iovec_destroy(QEMUIOVector *qiov);
+void qemu_iovec_reset(QEMUIOVector *qiov);
+void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf);
+void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count);
+
+struct Monitor;
+typedef struct Monitor Monitor;
+
+/* Convert a byte between binary and BCD. */
+static inline uint8_t to_bcd(uint8_t val)
+{
+ return ((val / 10) << 4) | (val % 10);
+}
+
+static inline uint8_t from_bcd(uint8_t val)
+{
+ return ((val >> 4) * 10) + (val & 0x0f);
+}
+
+#include "module.h"
+
+#endif /* dyngen-exec.h hack */
+
#endif /* !VBOX */
#endif
diff --git a/src/recompiler/qemu-lock.h b/src/recompiler/qemu-lock.h
index ceceed06c..61e900575 100644
--- a/src/recompiler/qemu-lock.h
+++ b/src/recompiler/qemu-lock.h
@@ -12,8 +12,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>
*/
/*
@@ -29,11 +28,11 @@
system emulation doesn't need/use locking, NPTL userspace uses
pthread mutexes, and non-NPTL userspace isn't threadsafe anyway.
In either case a spinlock is probably the wrong kind of lock.
- Spinlocks are only good if you know another CPU has the lock and is
+ Spinlocks are only good if you know annother CPU has the lock and is
likely to release it soon. In environments where you have more threads
than physical CPUs (the extreme case being a single CPU host) a spinlock
simply wastes CPU until the OS decides to preempt it. */
-#if defined(USE_NPTL)
+#if defined(CONFIG_USE_NPTL)
#include <pthread.h>
#define spin_lock pthread_mutex_lock
@@ -60,11 +59,7 @@ typedef int spinlock_t;
#define SPIN_LOCK_UNLOCKED 0
-#ifndef VBOX
static inline void resetlock (spinlock_t *p)
-#else
-DECLINLINE(void) resetlock (spinlock_t *p)
-#endif
{
*p = SPIN_LOCK_UNLOCKED;
}
@@ -74,20 +69,18 @@ DECLINLINE(void) resetlock (spinlock_t *p)
#ifdef VBOX
DECLINLINE(int) testandset (int *p)
{
-
return ASMAtomicCmpXchgU32((volatile uint32_t *)p, 1, 0) ? 0 : 1;
}
-#elif defined(__powerpc__)
+#elif defined(_ARCH_PPC)
static inline int testandset (int *p)
{
int ret;
__asm__ __volatile__ (
- "0: lwarx %0,0,%1\n"
+ " lwarx %0,0,%1\n"
" xor. %0,%3,%0\n"
- " bne 1f\n"
+ " bne $+12\n"
" stwcx. %2,0,%1\n"
- " bne- 0b\n"
- "1: "
+ " bne- $-16\n"
: "=&r" (ret)
: "r" (p), "r" (1), "r" (0)
: "cr0", "memory");
@@ -251,27 +244,15 @@ static inline int spin_trylock(spinlock_t *lock)
return !testandset(lock);
}
#else
-#ifndef VBOX
static inline void spin_lock(spinlock_t *lock)
-#else
-DECLINLINE(void) spin_lock(spinlock_t *lock)
-#endif
{
}
-#ifndef VBOX
static inline void spin_unlock(spinlock_t *lock)
-#else
-DECLINLINE(void) spin_unlock(spinlock_t *lock)
-#endif
{
}
-#ifndef VBOX
static inline int spin_trylock(spinlock_t *lock)
-#else
-DECLINLINE(int) spin_trylock(spinlock_t *lock)
-#endif
{
return 1;
}
diff --git a/src/recompiler/qemu-log.h b/src/recompiler/qemu-log.h
index 1ebea81c5..ba14794e0 100644
--- a/src/recompiler/qemu-log.h
+++ b/src/recompiler/qemu-log.h
@@ -1,7 +1,135 @@
#ifndef QEMU_LOG_H
#define QEMU_LOG_H
+/* The deprecated global variables: */
extern FILE *logfile;
extern int loglevel;
+
+/*
+ * The new API:
+ *
+ */
+
+/* Log settings checking macros: */
+
+/* Returns true if qemu_log() will really write somewhere
+ */
+#ifndef VBOX
+#define qemu_log_enabled() (logfile != NULL)
+#else
+# define qemu_log_enabled() LogIsEnabled()
+#endif
+
+/* Returns true if a bit is set in the current loglevel mask
+ */
+#define qemu_loglevel_mask(b) ((loglevel & (b)) != 0)
+
+
+/* Logging functions: */
+
+/* main logging function
+ */
+#ifndef VBOX
+#define qemu_log(...) do { \
+ if (logfile) \
+ fprintf(logfile, ## __VA_ARGS__); \
+ } while (0)
+#else
+# define qemu_log(...) Log((__VA_ARGS__))
+#endif
+
+/* vfprintf-like logging function
+ */
+#ifndef VBOX
+#define qemu_log_vprintf(fmt, va) do { \
+ if (logfile) \
+ vfprintf(logfile, fmt, va); \
+ } while (0)
+#else
+# define qemu_log_vprintf(fmt, va) do { \
+ if (LogIsEnabled()) \
+ RTLogLoggerExV(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, fmt, va); \
+ } while (0)
+#endif
+
+/* log only if a bit is set on the current loglevel mask
+ */
+#ifndef VBOX
+#define qemu_log_mask(b, ...) do { \
+ if (loglevel & (b)) \
+ fprintf(logfile, ## __VA_ARGS__); \
+ } while (0)
+#else
+# define qemu_log_mask(b, ...) do { \
+ if (loglevel & (b)) \
+ Log((__VA_ARGS__)); \
+ } while (0)
+#endif
+
+
+
+
+/* Special cases: */
+
+/* cpu_dump_state() logging functions: */
+#ifndef VBOX
+#define log_cpu_state(env, f) cpu_dump_state((env), logfile, fprintf, (f));
+#else
+#define log_cpu_state(env, f) cpu_dump_state((env), NULL, NULL, (f));
+#endif
+#define log_cpu_state_mask(b, env, f) do { \
+ if (loglevel & (b)) log_cpu_state((env), (f)); \
+ } while (0)
+
+/* disas() and target_disas() to logfile: */
+#define log_target_disas(start, len, flags) \
+ target_disas(logfile, (start), (len), (flags))
+#define log_disas(start, len) \
+ disas(logfile, (start), (len))
+
+/* page_dump() output to the log file: */
+#define log_page_dump() page_dump(logfile)
+
+
+
+/* Maintenance: */
+
+/* fflush() the log file */
+#ifndef VBOX
+#define qemu_log_flush() fflush(logfile)
+#else
+# define qemu_log_flush() RTLogFlush(LOG_INSTANCE)
+#endif
+
+/* Close the log file */
+#ifndef VBOX
+#define qemu_log_close() do { \
+ fclose(logfile); \
+ logfile = NULL; \
+ } while (0)
+#else
+# define qemu_log_close() do { } while (0)
+#endif
+
+/* Set up a new log file */
+#ifndef VBOX
+#define qemu_log_set_file(f) do { \
+ logfile = (f); \
+ } while (0)
+#else
+# define qemu_log_set_file(f) do { } while (0)
+#endif
+
+/* Set up a new log file, only if none is set */
+#ifndef VBOX
+#define qemu_log_try_set_file(f) do { \
+ if (!logfile) \
+ logfile = (f); \
+ } while (0)
+#else
+#define qemu_log_try_set_file(f) do { } while (0)
+#endif
+
+
#endif
diff --git a/src/recompiler/qemu-queue.h b/src/recompiler/qemu-queue.h
new file mode 100644
index 000000000..1d077458c
--- /dev/null
+++ b/src/recompiler/qemu-queue.h
@@ -0,0 +1,449 @@
+/* $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
+
+/*
+ * Qemu version: Copy from netbsd, removed debug code, removed some of
+ * the implementations. Left in lists, simple queues, tail queues and
+ * circular queues.
+ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef QEMU_SYS_QUEUE_H_
+#define QEMU_SYS_QUEUE_H_
+
+/*
+ * This file defines four types of data structures:
+ * lists, simple queues, tail queues, and circular queues.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A simple queue is headed by a pair of pointers, one the head of the
+ * list and the other to the tail of the list. The elements are singly
+ * linked to save space, so elements can only be removed from the
+ * head of the list. New elements can be added to the list after
+ * an existing element, at the head of the list, or at the end of the
+ * list. A simple queue may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ */
+
+/*
+ * List definitions.
+ */
+#define QLIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define QLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define QLIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List functions.
+ */
+#define QLIST_INIT(head) do { \
+ (head)->lh_first = NULL; \
+} while (/*CONSTCOND*/0)
+
+#define QLIST_INSERT_AFTER(listelm, elm, field) do { \
+ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
+ (listelm)->field.le_next->field.le_prev = \
+ &(elm)->field.le_next; \
+ (listelm)->field.le_next = (elm); \
+ (elm)->field.le_prev = &(listelm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define QLIST_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ (elm)->field.le_next = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &(elm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define QLIST_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.le_next = (head)->lh_first) != NULL) \
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+ (head)->lh_first = (elm); \
+ (elm)->field.le_prev = &(head)->lh_first; \
+} while (/*CONSTCOND*/0)
+
+#define QLIST_REMOVE(elm, field) do { \
+ if ((elm)->field.le_next != NULL) \
+ (elm)->field.le_next->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = (elm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define QLIST_FOREACH(var, head, field) \
+ for ((var) = ((head)->lh_first); \
+ (var); \
+ (var) = ((var)->field.le_next))
+
+#define QLIST_FOREACH_SAFE(var, head, field, next_var) \
+ for ((var) = ((head)->lh_first); \
+ (var) && ((next_var) = ((var)->field.le_next), 1); \
+ (var) = (next_var))
+
+/*
+ * List access methods.
+ */
+#define QLIST_EMPTY(head) ((head)->lh_first == NULL)
+#define QLIST_FIRST(head) ((head)->lh_first)
+#define QLIST_NEXT(elm, field) ((elm)->field.le_next)
+
+
+/*
+ * Simple queue definitions.
+ */
+#define QSIMPLEQ_HEAD(name, type) \
+struct name { \
+ struct type *sqh_first; /* first element */ \
+ struct type **sqh_last; /* addr of last next element */ \
+}
+
+#define QSIMPLEQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).sqh_first }
+
+#define QSIMPLEQ_ENTRY(type) \
+struct { \
+ struct type *sqe_next; /* next element */ \
+}
+
+/*
+ * Simple queue functions.
+ */
+#define QSIMPLEQ_INIT(head) do { \
+ (head)->sqh_first = NULL; \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define QSIMPLEQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (head)->sqh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define QSIMPLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.sqe_next = NULL; \
+ *(head)->sqh_last = (elm); \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL) \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (listelm)->field.sqe_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define QSIMPLEQ_REMOVE_HEAD(head, field) do { \
+ if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)\
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define QSIMPLEQ_REMOVE(head, elm, type, field) do { \
+ if ((head)->sqh_first == (elm)) { \
+ QSIMPLEQ_REMOVE_HEAD((head), field); \
+ } else { \
+ struct type *curelm = (head)->sqh_first; \
+ while (curelm->field.sqe_next != (elm)) \
+ curelm = curelm->field.sqe_next; \
+ if ((curelm->field.sqe_next = \
+ curelm->field.sqe_next->field.sqe_next) == NULL) \
+ (head)->sqh_last = &(curelm)->field.sqe_next; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define QSIMPLEQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->sqh_first); \
+ (var); \
+ (var) = ((var)->field.sqe_next))
+
+#define QSIMPLEQ_FOREACH_SAFE(var, head, field, next) \
+ for ((var) = ((head)->sqh_first); \
+ (var) && ((next = ((var)->field.sqe_next)), 1); \
+ (var) = (next))
+
+#define QSIMPLEQ_CONCAT(head1, head2) do { \
+ if (!QSIMPLEQ_EMPTY((head2))) { \
+ *(head1)->sqh_last = (head2)->sqh_first; \
+ (head1)->sqh_last = (head2)->sqh_last; \
+ QSIMPLEQ_INIT((head2)); \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define QSIMPLEQ_LAST(head, type, field) \
+ (QSIMPLEQ_EMPTY((head)) ? \
+ NULL : \
+ ((struct type *)(void *) \
+ ((char *)((head)->sqh_last) - offsetof(struct type, field))))
+
+/*
+ * Simple queue access methods.
+ */
+#define QSIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
+#define QSIMPLEQ_FIRST(head) ((head)->sqh_first)
+#define QSIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
+
+
+/*
+ * Tail queue definitions.
+ */
+#define Q_TAILQ_HEAD(name, type, qual) \
+struct name { \
+ qual type *tqh_first; /* first element */ \
+ qual type *qual *tqh_last; /* addr of last next element */ \
+}
+#define QTAILQ_HEAD(name, type) Q_TAILQ_HEAD(name, struct type,)
+
+#define QTAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first }
+
+#define Q_TAILQ_ENTRY(type, qual) \
+struct { \
+ qual type *tqe_next; /* next element */ \
+ qual type *qual *tqe_prev; /* address of previous next element */\
+}
+#define QTAILQ_ENTRY(type) Q_TAILQ_ENTRY(struct type,)
+
+/*
+ * Tail queue functions.
+ */
+#define QTAILQ_INIT(head) do { \
+ (head)->tqh_first = NULL; \
+ (head)->tqh_last = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define QTAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
+ (head)->tqh_first->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define QTAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ (elm)->field.tqe_next = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define QTAILQ_REMOVE(head, elm, field) do { \
+ if (((elm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define QTAILQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->tqh_first); \
+ (var); \
+ (var) = ((var)->field.tqe_next))
+
+#define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \
+ for ((var) = ((head)->tqh_first); \
+ (var) && ((next_var) = ((var)->field.tqe_next), 1); \
+ (var) = (next_var))
+
+#define QTAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
+ (var); \
+ (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+
+/*
+ * Tail queue access methods.
+ */
+#define QTAILQ_EMPTY(head) ((head)->tqh_first == NULL)
+#define QTAILQ_FIRST(head) ((head)->tqh_first)
+#define QTAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define QTAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+#define QTAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+
+/*
+ * Circular queue definitions.
+ */
+#define QCIRCLEQ_HEAD(name, type) \
+struct name { \
+ struct type *cqh_first; /* first element */ \
+ struct type *cqh_last; /* last element */ \
+}
+
+#define QCIRCLEQ_HEAD_INITIALIZER(head) \
+ { (void *)&head, (void *)&head }
+
+#define QCIRCLEQ_ENTRY(type) \
+struct { \
+ struct type *cqe_next; /* next element */ \
+ struct type *cqe_prev; /* previous element */ \
+}
+
+/*
+ * Circular queue functions.
+ */
+#define QCIRCLEQ_INIT(head) do { \
+ (head)->cqh_first = (void *)(head); \
+ (head)->cqh_last = (void *)(head); \
+} while (/*CONSTCOND*/0)
+
+#define QCIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm)->field.cqe_next; \
+ (elm)->field.cqe_prev = (listelm); \
+ if ((listelm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (listelm)->field.cqe_next->field.cqe_prev = (elm); \
+ (listelm)->field.cqe_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define QCIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm); \
+ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
+ if ((listelm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (listelm)->field.cqe_prev->field.cqe_next = (elm); \
+ (listelm)->field.cqe_prev = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define QCIRCLEQ_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.cqe_next = (head)->cqh_first; \
+ (elm)->field.cqe_prev = (void *)(head); \
+ if ((head)->cqh_last == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (head)->cqh_first->field.cqe_prev = (elm); \
+ (head)->cqh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define QCIRCLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.cqe_next = (void *)(head); \
+ (elm)->field.cqe_prev = (head)->cqh_last; \
+ if ((head)->cqh_first == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (head)->cqh_last->field.cqe_next = (elm); \
+ (head)->cqh_last = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define QCIRCLEQ_REMOVE(head, elm, field) do { \
+ if ((elm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm)->field.cqe_prev; \
+ else \
+ (elm)->field.cqe_next->field.cqe_prev = \
+ (elm)->field.cqe_prev; \
+ if ((elm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm)->field.cqe_next; \
+ else \
+ (elm)->field.cqe_prev->field.cqe_next = \
+ (elm)->field.cqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define QCIRCLEQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->cqh_first); \
+ (var) != (const void *)(head); \
+ (var) = ((var)->field.cqe_next))
+
+#define QCIRCLEQ_FOREACH_REVERSE(var, head, field) \
+ for ((var) = ((head)->cqh_last); \
+ (var) != (const void *)(head); \
+ (var) = ((var)->field.cqe_prev))
+
+/*
+ * Circular queue access methods.
+ */
+#define QCIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
+#define QCIRCLEQ_FIRST(head) ((head)->cqh_first)
+#define QCIRCLEQ_LAST(head) ((head)->cqh_last)
+#define QCIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
+#define QCIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
+
+#define QCIRCLEQ_LOOP_NEXT(head, elm, field) \
+ (((elm)->field.cqe_next == (void *)(head)) \
+ ? ((head)->cqh_first) \
+ : (elm->field.cqe_next))
+#define QCIRCLEQ_LOOP_PREV(head, elm, field) \
+ (((elm)->field.cqe_prev == (void *)(head)) \
+ ? ((head)->cqh_last) \
+ : (elm->field.cqe_prev))
+
+#endif /* !QEMU_SYS_QUEUE_H_ */
diff --git a/src/recompiler/qemu-timer.h b/src/recompiler/qemu-timer.h
new file mode 100644
index 000000000..209c4d2c8
--- /dev/null
+++ b/src/recompiler/qemu-timer.h
@@ -0,0 +1,272 @@
+#ifndef QEMU_TIMER_H
+#define QEMU_TIMER_H
+
+#include "qemu-common.h"
+
+/* timers */
+#ifndef VBOX
+
+typedef struct QEMUClock QEMUClock;
+typedef void QEMUTimerCB(void *opaque);
+
+/* The real time clock should be used only for stuff which does not
+ change the virtual machine state, as it is run even if the virtual
+ machine is stopped. The real time clock has a frequency of 1000
+ Hz. */
+extern QEMUClock *rt_clock;
+
+/* The virtual clock is only run during the emulation. It is stopped
+ when the virtual machine is stopped. Virtual timers use a high
+ precision clock, usually cpu cycles (use ticks_per_sec). */
+extern QEMUClock *vm_clock;
+
+/* The host clock should be use for device models that emulate accurate
+ real time sources. It will continue to run when the virtual machine
+ is suspended, and it will reflect system time changes the host may
+ undergo (e.g. due to NTP). The host clock has the same precision as
+ the virtual clock. */
+extern QEMUClock *host_clock;
+
+int64_t qemu_get_clock(QEMUClock *clock);
+int64_t qemu_get_clock_ns(QEMUClock *clock);
+void qemu_clock_enable(QEMUClock *clock, int enabled);
+
+QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque);
+void qemu_free_timer(QEMUTimer *ts);
+void qemu_del_timer(QEMUTimer *ts);
+void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
+int qemu_timer_pending(QEMUTimer *ts);
+int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
+
+void qemu_run_all_timers(void);
+int qemu_alarm_pending(void);
+int64_t qemu_next_deadline(void);
+void configure_alarms(char const *opt);
+void configure_icount(const char *option);
+int qemu_calculate_timeout(void);
+void init_clocks(void);
+int init_timer_alarm(void);
+void quit_timers(void);
+
+static inline int64_t get_ticks_per_sec(void)
+{
+ return 1000000000LL;
+}
+
+
+void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
+void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
+
+/* ptimer.c */
+typedef struct ptimer_state ptimer_state;
+typedef void (*ptimer_cb)(void *opaque);
+
+ptimer_state *ptimer_init(QEMUBH *bh);
+void ptimer_set_period(ptimer_state *s, int64_t period);
+void ptimer_set_freq(ptimer_state *s, uint32_t freq);
+void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
+uint64_t ptimer_get_count(ptimer_state *s);
+void ptimer_set_count(ptimer_state *s, uint64_t count);
+void ptimer_run(ptimer_state *s, int oneshot);
+void ptimer_stop(ptimer_state *s);
+void qemu_put_ptimer(QEMUFile *f, ptimer_state *s);
+void qemu_get_ptimer(QEMUFile *f, ptimer_state *s);
+
+/* icount */
+int64_t qemu_icount_round(int64_t count);
+extern int64_t qemu_icount;
+#endif /* !VBOX */
+extern int use_icount;
+#ifndef VBOX
+extern int icount_time_shift;
+extern int64_t qemu_icount_bias;
+int64_t cpu_get_icount(void);
+
+/*******************************************/
+/* host CPU ticks (if available) */
+
+#if defined(_ARCH_PPC)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+ int64_t retval;
+#ifdef _ARCH_PPC64
+ /* This reads timebase in one 64bit go and includes Cell workaround from:
+ http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html
+ */
+ __asm__ __volatile__ ("mftb %0\n\t"
+ "cmpwi %0,0\n\t"
+ "beq- $-8"
+ : "=r" (retval));
+#else
+ /* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */
+ unsigned long junk;
+ __asm__ __volatile__ ("mfspr %1,269\n\t" /* mftbu */
+ "mfspr %L0,268\n\t" /* mftb */
+ "mfspr %0,269\n\t" /* mftbu */
+ "cmpw %0,%1\n\t"
+ "bne $-16"
+ : "=r" (retval), "=r" (junk));
+#endif
+ return retval;
+}
+
+#elif defined(__i386__)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+ int64_t val;
+ asm volatile ("rdtsc" : "=A" (val));
+ return val;
+}
+
+#elif defined(__x86_64__)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+ uint32_t low,high;
+ int64_t val;
+ asm volatile("rdtsc" : "=a" (low), "=d" (high));
+ val = high;
+ val <<= 32;
+ val |= low;
+ return val;
+}
+
+#elif defined(__hppa__)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+ int val;
+ asm volatile ("mfctl %%cr16, %0" : "=r"(val));
+ return val;
+}
+
+#elif defined(__ia64)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+ int64_t val;
+ asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
+ return val;
+}
+
+#elif defined(__s390__)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+ int64_t val;
+ asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
+ return val;
+}
+
+#elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
+
+static inline int64_t cpu_get_real_ticks (void)
+{
+#if defined(_LP64)
+ uint64_t rval;
+ asm volatile("rd %%tick,%0" : "=r"(rval));
+ return rval;
+#else
+ union {
+ uint64_t i64;
+ struct {
+ uint32_t high;
+ uint32_t low;
+ } i32;
+ } rval;
+ asm volatile("rd %%tick,%1; srlx %1,32,%0"
+ : "=r"(rval.i32.high), "=r"(rval.i32.low));
+ return rval.i64;
+#endif
+}
+
+#elif defined(__mips__) && \
+ ((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
+/*
+ * binutils wants to use rdhwr only on mips32r2
+ * but as linux kernel emulate it, it's fine
+ * to use it.
+ *
+ */
+#define MIPS_RDHWR(rd, value) { \
+ __asm__ __volatile__ (".set push\n\t" \
+ ".set mips32r2\n\t" \
+ "rdhwr %0, "rd"\n\t" \
+ ".set pop" \
+ : "=r" (value)); \
+ }
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+ /* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */
+ uint32_t count;
+ static uint32_t cyc_per_count = 0;
+
+ if (!cyc_per_count) {
+ MIPS_RDHWR("$3", cyc_per_count);
+ }
+
+ MIPS_RDHWR("$2", count);
+ return (int64_t)(count * cyc_per_count);
+}
+
+#elif defined(__alpha__)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+ uint64_t cc;
+ uint32_t cur, ofs;
+
+ asm volatile("rpcc %0" : "=r"(cc));
+ cur = cc;
+ ofs = cc >> 32;
+ return cur - ofs;
+}
+
+#else
+/* The host CPU doesn't have an easily accessible cycle counter.
+ Just return a monotonically increasing value. This will be
+ totally wrong, but hopefully better than nothing. */
+static inline int64_t cpu_get_real_ticks (void)
+{
+ static int64_t ticks = 0;
+ return ticks++;
+}
+#endif
+
+#endif /* !VBOX */
+
+#ifdef NEED_CPU_H
+/* Deterministic execution requires that IO only be performed on the last
+ instruction of a TB so that interrupts take effect immediately. */
+static inline int can_do_io(CPUState *env)
+{
+ if (!use_icount)
+ return 1;
+
+ /* If not executing code then assume we are ok. */
+ if (!env->current_tb)
+ return 1;
+
+ return env->can_do_io != 0;
+}
+#endif
+
+#ifndef VBOX
+
+#ifdef CONFIG_PROFILER
+static inline int64_t profile_getclock(void)
+{
+ return cpu_get_real_ticks();
+}
+
+extern int64_t qemu_time, qemu_time_start;
+extern int64_t tlb_flush_time;
+extern int64_t dev_time;
+#endif
+
+#endif /* !VBOX */
+
+#endif
diff --git a/src/recompiler/softmmu_defs.h b/src/recompiler/softmmu_defs.h
index 96392ece3..e23c3498b 100644
--- a/src/recompiler/softmmu_defs.h
+++ b/src/recompiler/softmmu_defs.h
@@ -19,7 +19,7 @@ uint32_t REGPARM __ldl_cmmu(target_ulong addr, int mmu_idx);
void REGPARM __stl_cmmu(target_ulong addr, uint32_t val, int mmu_idx);
uint64_t REGPARM __ldq_cmmu(target_ulong addr, int mmu_idx);
void REGPARM __stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx);
-#else
+#else /* VBOX */
RTCCUINTREG REGPARM __ldb_mmu(target_ulong addr, int mmu_idx);
void REGPARM __stb_mmu(target_ulong addr, uint8_t val, int mmu_idx);
RTCCUINTREG REGPARM __ldw_mmu(target_ulong addr, int mmu_idx);
@@ -38,7 +38,7 @@ void REGPARM __stl_cmmu(target_ulong addr, uint32_t val, int mmu_idx);
uint64_t REGPARM __ldq_cmmu(target_ulong addr, int mmu_idx);
void REGPARM __stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx);
-#ifdef REM_PHYS_ADDR_IN_TLB
+# ifdef REM_PHYS_ADDR_IN_TLB
RTCCUINTREG REGPARM __ldb_vbox_phys(RTCCUINTREG addr);
RTCCUINTREG REGPARM __ldub_vbox_phys(RTCCUINTREG addr);
void REGPARM __stb_vbox_phys(RTCCUINTREG addr, RTCCUINTREG val);
@@ -50,8 +50,8 @@ RTCCUINTREG REGPARM __ldul_vbox_phys(RTCCUINTREG addr);
void REGPARM __stl_vbox_phys(RTCCUINTREG addr, RTCCUINTREG val);
uint64_t REGPARM __ldq_vbox_phys(RTCCUINTREG addr);
void REGPARM __stq_vbox_phys(RTCCUINTREG addr, uint64_t val);
-#endif
+# endif
-#endif
+#endif /* VBOX */
#endif
diff --git a/src/recompiler/softmmu_exec.h b/src/recompiler/softmmu_exec.h
index 3b789eeb7..28d1d53d6 100644
--- a/src/recompiler/softmmu_exec.h
+++ b/src/recompiler/softmmu_exec.h
@@ -1,10 +1,18 @@
/* Common softmmu definitions and inline routines. */
-#define ldul_user ldl_user
-#define ldul_kernel ldl_kernel
+/* XXX: find something cleaner.
+ * Furthermore, this is false for 64 bits targets
+ */
+#define ldul_user ldl_user
+#define ldul_kernel ldl_kernel
+#define ldul_hypv ldl_hypv
+#define ldul_executive ldl_executive
+#define ldul_supervisor ldl_supervisor
+
+#include "softmmu_defs.h"
#define ACCESS_TYPE 0
-#define MEMSUFFIX _kernel
+#define MEMSUFFIX MMU_MODE0_SUFFIX
#define DATA_SIZE 1
#include "softmmu_header.h"
@@ -20,7 +28,7 @@
#undef MEMSUFFIX
#define ACCESS_TYPE 1
-#define MEMSUFFIX _user
+#define MEMSUFFIX MMU_MODE1_SUFFIX
#define DATA_SIZE 1
#include "softmmu_header.h"
@@ -35,8 +43,88 @@
#undef ACCESS_TYPE
#undef MEMSUFFIX
-/* these access are slower, they must be as rare as possible */
+#if (NB_MMU_MODES >= 3)
+
#define ACCESS_TYPE 2
+#define MEMSUFFIX MMU_MODE2_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+#endif /* (NB_MMU_MODES >= 3) */
+
+#if (NB_MMU_MODES >= 4)
+
+#define ACCESS_TYPE 3
+#define MEMSUFFIX MMU_MODE3_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+#endif /* (NB_MMU_MODES >= 4) */
+
+#if (NB_MMU_MODES >= 5)
+
+#define ACCESS_TYPE 4
+#define MEMSUFFIX MMU_MODE4_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+#endif /* (NB_MMU_MODES >= 5) */
+
+#if (NB_MMU_MODES >= 6)
+
+#define ACCESS_TYPE 5
+#define MEMSUFFIX MMU_MODE5_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+#endif /* (NB_MMU_MODES >= 6) */
+
+#if (NB_MMU_MODES > 6)
+#error "NB_MMU_MODES > 6 is not supported for now"
+#endif /* (NB_MMU_MODES > 6) */
+
+/* these access are slower, they must be as rare as possible */
+#define ACCESS_TYPE (NB_MMU_MODES)
#define MEMSUFFIX _data
#define DATA_SIZE 1
#include "softmmu_header.h"
diff --git a/src/recompiler/softmmu_header.h b/src/recompiler/softmmu_header.h
index c632c8d7e..fd1b5b970 100644
--- a/src/recompiler/softmmu_header.h
+++ b/src/recompiler/softmmu_header.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -71,7 +70,7 @@
#if DATA_SIZE == 8
#define RES_TYPE uint64_t
#else
-#define RES_TYPE int
+#define RES_TYPE uint32_t
#endif
#if ACCESS_TYPE == (NB_MMU_MODES + 1)
@@ -80,158 +79,10 @@
#define ADDR_READ addr_read
#endif
-#if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
- (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU) && !defined(VBOX)
-
-static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
-{
- int res;
-
- asm volatile ("movl %1, %%edx\n"
- "movl %1, %%eax\n"
- "shrl %3, %%edx\n"
- "andl %4, %%eax\n"
- "andl %2, %%edx\n"
- "leal %5(%%edx, %%ebp), %%edx\n"
- "cmpl (%%edx), %%eax\n"
- "movl %1, %%eax\n"
- "je 1f\n"
- "movl %6, %%edx\n"
- "call %7\n"
- "movl %%eax, %0\n"
- "jmp 2f\n"
- "1:\n"
- "addl 12(%%edx), %%eax\n"
-#if DATA_SIZE == 1
- "movzbl (%%eax), %0\n"
-#elif DATA_SIZE == 2
- "movzwl (%%eax), %0\n"
-#elif DATA_SIZE == 4
- "movl (%%eax), %0\n"
-#else
-#error unsupported size
-#endif
- "2:\n"
- : "=r" (res)
- : "r" (ptr),
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
- "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
- "i" (CPU_MMU_INDEX),
- "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
- : "%eax", "%ecx", "%edx", "memory", "cc");
- return res;
-}
-
-#if DATA_SIZE <= 2
-static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
-{
- int res;
-
- asm volatile ("movl %1, %%edx\n"
- "movl %1, %%eax\n"
- "shrl %3, %%edx\n"
- "andl %4, %%eax\n"
- "andl %2, %%edx\n"
- "leal %5(%%edx, %%ebp), %%edx\n"
- "cmpl (%%edx), %%eax\n"
- "movl %1, %%eax\n"
- "je 1f\n"
- "movl %6, %%edx\n"
- "call %7\n"
-#if DATA_SIZE == 1
- "movsbl %%al, %0\n"
-#elif DATA_SIZE == 2
- "movswl %%ax, %0\n"
-#else
-#error unsupported size
-#endif
- "jmp 2f\n"
- "1:\n"
- "addl 12(%%edx), %%eax\n"
-#if DATA_SIZE == 1
- "movsbl (%%eax), %0\n"
-#elif DATA_SIZE == 2
- "movswl (%%eax), %0\n"
-#else
-#error unsupported size
-#endif
- "2:\n"
- : "=r" (res)
- : "r" (ptr),
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
- "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
- "i" (CPU_MMU_INDEX),
- "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
- : "%eax", "%ecx", "%edx", "memory", "cc");
- return res;
-}
-#endif
-
-static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
-{
- asm volatile ("movl %0, %%edx\n"
- "movl %0, %%eax\n"
- "shrl %3, %%edx\n"
- "andl %4, %%eax\n"
- "andl %2, %%edx\n"
- "leal %5(%%edx, %%ebp), %%edx\n"
- "cmpl (%%edx), %%eax\n"
- "movl %0, %%eax\n"
- "je 1f\n"
-#if DATA_SIZE == 1
- "movzbl %b1, %%edx\n"
-#elif DATA_SIZE == 2
- "movzwl %w1, %%edx\n"
-#elif DATA_SIZE == 4
- "movl %1, %%edx\n"
-#else
-#error unsupported size
-#endif
- "movl %6, %%ecx\n"
- "call %7\n"
- "jmp 2f\n"
- "1:\n"
- "addl 8(%%edx), %%eax\n"
-#if DATA_SIZE == 1
- "movb %b1, (%%eax)\n"
-#elif DATA_SIZE == 2
- "movw %w1, (%%eax)\n"
-#elif DATA_SIZE == 4
- "movl %1, (%%eax)\n"
-#else
-#error unsupported size
-#endif
- "2:\n"
- :
- : "r" (ptr),
-#if DATA_SIZE == 1
- "q" (v),
-#else
- "r" (v),
-#endif
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
- "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)),
- "i" (CPU_MMU_INDEX),
- "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
- : "%eax", "%ecx", "%edx", "memory", "cc");
-}
-#else
-
/* generic load/store macros */
-#ifndef VBOX
static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
-#else
-DECLINLINE(RES_TYPE) glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
-#endif
{
-
int page_index;
RES_TYPE res;
target_ulong addr;
@@ -252,11 +103,7 @@ DECLINLINE(RES_TYPE) glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
}
#if DATA_SIZE <= 2
-#ifndef VBOX
static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
-#else
-DECLINLINE(int) glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
-#endif
{
int res, page_index;
target_ulong addr;
@@ -280,11 +127,8 @@ DECLINLINE(int) glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
#if ACCESS_TYPE != (NB_MMU_MODES + 1)
/* generic store macro */
-#ifndef VBOX
+
static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
-#else
-DECLINLINE(void) glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
-#endif
{
int page_index;
target_ulong addr;
@@ -305,16 +149,10 @@ DECLINLINE(void) glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
-#endif /* !asm */
-
#if ACCESS_TYPE != (NB_MMU_MODES + 1)
#if DATA_SIZE == 8
-#ifndef VBOX
static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
-#else
-DECLINLINE(float64) glue(ldfq, MEMSUFFIX)(target_ulong ptr)
-#endif
{
union {
float64 d;
@@ -324,11 +162,7 @@ DECLINLINE(float64) glue(ldfq, MEMSUFFIX)(target_ulong ptr)
return u.d;
}
-#ifndef VBOX
static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
-#else
-DECLINLINE(void) glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
-#endif
{
union {
float64 d;
@@ -340,11 +174,7 @@ DECLINLINE(void) glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
#endif /* DATA_SIZE == 8 */
#if DATA_SIZE == 4
-#ifndef VBOX
static inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr)
-#else
-DECLINLINE(float32) glue(ldfl, MEMSUFFIX)(target_ulong ptr)
-#endif
{
union {
float32 f;
@@ -354,11 +184,7 @@ DECLINLINE(float32) glue(ldfl, MEMSUFFIX)(target_ulong ptr)
return u.f;
}
-#ifndef VBOX
static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
-#else
-DECLINLINE(void) glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
-#endif
{
union {
float32 f;
diff --git a/src/recompiler/softmmu_template.h b/src/recompiler/softmmu_template.h
index d0b735417..c3cd3ce5d 100644
--- a/src/recompiler/softmmu_template.h
+++ b/src/recompiler/softmmu_template.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -27,33 +26,37 @@
* of the LGPL is applied is otherwise unspecified.
*/
+#include "qemu-timer.h"
+
#define DATA_SIZE (1 << SHIFT)
#if DATA_SIZE == 8
#define SUFFIX q
#define USUFFIX q
#define DATA_TYPE uint64_t
-#define DATA_TYPE_PROMOTED uint64_t
+#ifdef VBOX
+# define DATA_TYPE_PROMOTED uint64_t
+#endif
#elif DATA_SIZE == 4
#define SUFFIX l
#define USUFFIX l
#define DATA_TYPE uint32_t
#ifdef VBOX
-#define DATA_TYPE_PROMOTED RTCCUINTREG
+# define DATA_TYPE_PROMOTED RTCCUINTREG
#endif
#elif DATA_SIZE == 2
#define SUFFIX w
#define USUFFIX uw
#define DATA_TYPE uint16_t
#ifdef VBOX
-#define DATA_TYPE_PROMOTED RTCCUINTREG
+# define DATA_TYPE_PROMOTED RTCCUINTREG
#endif
#elif DATA_SIZE == 1
#define SUFFIX b
#define USUFFIX ub
#define DATA_TYPE uint8_t
#ifdef VBOX
-#define DATA_TYPE_PROMOTED RTCCUINTREG
+# define DATA_TYPE_PROMOTED RTCCUINTREG
#endif
#else
#error unsupported data size
@@ -70,15 +73,9 @@
static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
int mmu_idx,
void *retaddr);
-#ifndef VBOX
static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
target_ulong addr,
void *retaddr)
-#else
-DECLINLINE(DATA_TYPE) glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
- target_ulong addr,
- void *retaddr)
-#endif
{
DATA_TYPE res;
int index;
@@ -90,6 +87,7 @@ DECLINLINE(DATA_TYPE) glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
cpu_io_recompile(env, retaddr);
}
+ env->mem_io_vaddr = addr;
#if SHIFT <= 2
res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr);
#else
@@ -101,9 +99,6 @@ DECLINLINE(DATA_TYPE) glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32;
#endif
#endif /* SHIFT > 2 */
-#ifdef USE_KQEMU
- env->last_io_time = cpu_get_time_fast();
-#endif
return res;
}
@@ -123,7 +118,8 @@ glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
DATA_TYPE res;
int index;
target_ulong tlb_addr;
- target_phys_addr_t addend;
+ target_phys_addr_t ioaddr;
+ unsigned long addend;
void *retaddr;
/* test if there is match for unaligned or IO access */
@@ -137,8 +133,8 @@ glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
retaddr = GETPC();
- addend = env->iotlb[mmu_idx][index];
- res = glue(io_read, SUFFIX)(addend, addr, retaddr);
+ ioaddr = env->iotlb[mmu_idx][index];
+ res = glue(io_read, SUFFIX)(ioaddr, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
/* slow unaligned access (it spans two pages or IO) */
do_unaligned_access:
@@ -179,7 +175,8 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
{
DATA_TYPE res, res1, res2;
int index, shift;
- target_phys_addr_t addend;
+ target_phys_addr_t ioaddr;
+ unsigned long addend;
target_ulong tlb_addr, addr1, addr2;
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
@@ -190,9 +187,8 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
/* IO access */
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
- retaddr = GETPC();
- addend = env->iotlb[mmu_idx][index];
- res = glue(io_read, SUFFIX)(addend, addr, retaddr);
+ ioaddr = env->iotlb[mmu_idx][index];
+ res = glue(io_read, SUFFIX)(ioaddr, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
/* slow unaligned access (it spans two pages) */
@@ -229,17 +225,10 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
int mmu_idx,
void *retaddr);
-#ifndef VBOX
static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
DATA_TYPE val,
target_ulong addr,
void *retaddr)
-#else
-DECLINLINE(void) glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
- DATA_TYPE val,
- target_ulong addr,
- void *retaddr)
-#endif
{
int index;
index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
@@ -262,16 +251,14 @@ DECLINLINE(void) glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
#endif
#endif /* SHIFT > 2 */
-#ifdef USE_KQEMU
- env->last_io_time = cpu_get_time_fast();
-#endif
}
void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
DATA_TYPE val,
int mmu_idx)
{
- target_phys_addr_t addend;
+ target_phys_addr_t ioaddr;
+ unsigned long addend;
target_ulong tlb_addr;
void *retaddr;
int index;
@@ -285,8 +272,8 @@ void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
retaddr = GETPC();
- addend = env->iotlb[mmu_idx][index];
- glue(io_write, SUFFIX)(addend, val, addr, retaddr);
+ ioaddr = env->iotlb[mmu_idx][index];
+ glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
retaddr = GETPC();
@@ -324,7 +311,8 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
int mmu_idx,
void *retaddr)
{
- target_phys_addr_t addend;
+ target_phys_addr_t ioaddr;
+ unsigned long addend;
target_ulong tlb_addr;
int index, i;
@@ -336,8 +324,8 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
/* IO access */
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
- addend = env->iotlb[mmu_idx][index];
- glue(io_write, SUFFIX)(addend, val, addr, retaddr);
+ ioaddr = env->iotlb[mmu_idx][index];
+ glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
/* XXX: not efficient, but simple */
@@ -367,7 +355,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
#endif /* !defined(SOFTMMU_CODE_ACCESS) */
#ifdef VBOX
-#undef DATA_TYPE_PROMOTED
+# undef DATA_TYPE_PROMOTED
#endif
#undef READ_ACCESS_TYPE
#undef SHIFT
diff --git a/src/recompiler/target-i386/TODO b/src/recompiler/target-i386/TODO
new file mode 100644
index 000000000..c8ada075d
--- /dev/null
+++ b/src/recompiler/target-i386/TODO
@@ -0,0 +1,32 @@
+Correctness issues:
+
+- some eflags manipulation incorrectly reset the bit 0x2.
+- SVM: test, cpu save/restore, SMM save/restore.
+- x86_64: lcall/ljmp intel/amd differences ?
+- better code fetch (different exception handling + CS.limit support)
+- user/kernel PUSHL/POPL in helper.c
+- add missing cpuid tests
+- return UD exception if LOCK prefix incorrectly used
+- test ldt limit < 7 ?
+- fix some 16 bit sp push/pop overflow (pusha/popa, lcall lret)
+- full support of segment limit/rights
+- full x87 exception support
+- improve x87 bit exactness (use bochs code ?)
+- DRx register support
+- CR0.AC emulation
+- SSE alignment checks
+- fix SSE min/max with nans
+
+Optimizations/Features:
+
+- add SVM nested paging support
+- add VMX support
+- add AVX support
+- add SSE5 support
+- fxsave/fxrstor AMD extensions
+- improve monitor/mwait support
+- faster EFLAGS update: consider SZAP, C, O can be updated separately
+ with a bit field in CC_OP and more state variables.
+- evaluate x87 stack pointer statically
+- find a way to avoid translating several time the same TB if CR0.TS
+ is set or not.
diff --git a/src/recompiler/target-i386/cpu.h b/src/recompiler/target-i386/cpu.h
index 68c817aee..582f88440 100644
--- a/src/recompiler/target-i386/cpu.h
+++ b/src/recompiler/target-i386/cpu.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -52,11 +51,13 @@
#define ELF_MACHINE EM_386
#endif
+#define CPUState struct CPUX86State
+
#include "cpu-defs.h"
#include "softfloat.h"
-#if defined(VBOX)
+#ifdef VBOX
# include <iprt/critsect.h>
# include <iprt/thread.h>
# include <iprt/assert.h>
@@ -99,8 +100,10 @@
#define DESC_AVL_MASK (1 << 20)
#define DESC_P_MASK (1 << 15)
#define DESC_DPL_SHIFT 13
+#define DESC_DPL_MASK (3 << DESC_DPL_SHIFT)
#define DESC_S_MASK (1 << 12)
#define DESC_TYPE_SHIFT 8
+#define DESC_TYPE_MASK (15 << DESC_TYPE_SHIFT)
#define DESC_A_MASK (1 << 8)
#define DESC_CS_MASK (1 << 11) /* 1=code segment 0=data segment */
@@ -113,8 +116,8 @@
#define DESC_TSS_BUSY_MASK (1 << 9)
/* eflags masks */
-#define CC_C 0x0001
-#define CC_P 0x0004
+#define CC_C 0x0001
+#define CC_P 0x0004
#define CC_A 0x0010
#define CC_Z 0x0040
#define CC_S 0x0080
@@ -124,11 +127,11 @@
#define IOPL_SHIFT 12
#define VM_SHIFT 17
-#define TF_MASK 0x00000100
-#define IF_MASK 0x00000200
-#define DF_MASK 0x00000400
+#define TF_MASK 0x00000100
+#define IF_MASK 0x00000200
+#define DF_MASK 0x00000400
#define IOPL_MASK 0x00003000
-#define NT_MASK 0x00004000
+#define NT_MASK 0x00004000
#define RF_MASK 0x00010000
#define VM_MASK 0x00020000
#define AC_MASK 0x00040000
@@ -137,9 +140,9 @@
#define ID_MASK 0x00200000
/* hidden flags - used internally by qemu to represent additional cpu
- states. Only the CPL, INHIBIT_IRQ, SMM and SVMI are not redundant. We avoid
- using the IOPL_MASK, TF_MASK and VM_MASK bit position to ease oring
- with eflags. */
+ states. Only the CPL, INHIBIT_IRQ, SMM and SVMI are not
+ redundant. We avoid using the IOPL_MASK, TF_MASK and VM_MASK bit
+ position to ease oring with eflags. */
/* current cpl */
#define HF_CPL_SHIFT 0
/* true if soft mmu is being used */
@@ -160,12 +163,12 @@
#define HF_IOPL_SHIFT 12 /* must be same as eflags */
#define HF_LMA_SHIFT 14 /* only used on x86_64: long mode active */
#define HF_CS64_SHIFT 15 /* only used on x86_64: 64 bit code segment */
-#define HF_OSFXSR_SHIFT 16 /* CR4.OSFXSR */
+#define HF_RF_SHIFT 16 /* must be same as eflags */
#define HF_VM_SHIFT 17 /* must be same as eflags */
-#define HF_HALTED_SHIFT 18 /* CPU halted */
#define HF_SMM_SHIFT 19 /* CPU in SMM mode */
#define HF_SVME_SHIFT 20 /* SVME enabled (copy of EFER.SVME) */
#define HF_SVMI_SHIFT 21 /* SVM intercepts are active */
+#define HF_OSFXSR_SHIFT 22 /* CR4.OSFXSR */
#define HF_CPL_MASK (3 << HF_CPL_SHIFT)
#define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT)
@@ -178,13 +181,15 @@
#define HF_MP_MASK (1 << HF_MP_SHIFT)
#define HF_EM_MASK (1 << HF_EM_SHIFT)
#define HF_TS_MASK (1 << HF_TS_SHIFT)
+#define HF_IOPL_MASK (3 << HF_IOPL_SHIFT)
#define HF_LMA_MASK (1 << HF_LMA_SHIFT)
#define HF_CS64_MASK (1 << HF_CS64_SHIFT)
-#define HF_OSFXSR_MASK (1 << HF_OSFXSR_SHIFT)
-#define HF_HALTED_MASK (1 << HF_HALTED_SHIFT)
+#define HF_RF_MASK (1 << HF_RF_SHIFT)
+#define HF_VM_MASK (1 << HF_VM_SHIFT)
#define HF_SMM_MASK (1 << HF_SMM_SHIFT)
#define HF_SVME_MASK (1 << HF_SVME_SHIFT)
#define HF_SVMI_MASK (1 << HF_SVMI_SHIFT)
+#define HF_OSFXSR_MASK (1 << HF_OSFXSR_SHIFT)
/* hflags2 */
@@ -198,6 +203,9 @@
#define HF2_NMI_MASK (1 << HF2_NMI_SHIFT)
#define HF2_VINTR_MASK (1 << HF2_VINTR_SHIFT)
+#define CR0_PE_SHIFT 0
+#define CR0_MP_SHIFT 1
+
#define CR0_PE_MASK (1 << 0)
#define CR0_MP_MASK (1 << 1)
#define CR0_EM_MASK (1 << 2)
@@ -214,11 +222,23 @@
#define CR4_DE_MASK (1 << 3)
#define CR4_PSE_MASK (1 << 4)
#define CR4_PAE_MASK (1 << 5)
+#define CR4_MCE_MASK (1 << 6)
#define CR4_PGE_MASK (1 << 7)
#define CR4_PCE_MASK (1 << 8)
-#define CR4_OSFXSR_MASK (1 << 9)
+#define CR4_OSFXSR_SHIFT 9
+#define CR4_OSFXSR_MASK (1 << CR4_OSFXSR_SHIFT)
#define CR4_OSXMMEXCPT_MASK (1 << 10)
+#define DR6_BD (1 << 13)
+#define DR6_BS (1 << 14)
+#define DR6_BT (1 << 15)
+#define DR6_FIXED_1 0xffff0ff0
+
+#define DR7_GD (1 << 13)
+#define DR7_TYPE_SHIFT 16
+#define DR7_LEN_SHIFT 18
+#define DR7_FIXED_1 0x00000400
+
#define PG_PRESENT_BIT 0
#define PG_RW_BIT 1
#define PG_USER_BIT 2
@@ -249,16 +269,27 @@
#define PG_ERROR_RSVD_MASK 0x08
#define PG_ERROR_I_D_MASK 0x10
+#define MCG_CTL_P (1UL<<8) /* MCG_CAP register available */
+
+#define MCE_CAP_DEF MCG_CTL_P
+#define MCE_BANKS_DEF 10
+
+#define MCG_STATUS_MCIP (1ULL<<2) /* machine check in progress */
+
+#define MCI_STATUS_VAL (1ULL<<63) /* valid error */
+#define MCI_STATUS_OVER (1ULL<<62) /* previous errors lost */
+#define MCI_STATUS_UC (1ULL<<61) /* uncorrected error */
+
+#define MSR_IA32_TSC 0x10
#define MSR_IA32_APICBASE 0x1b
#define MSR_IA32_APICBASE_BSP (1<<8)
#define MSR_IA32_APICBASE_ENABLE (1<<11)
#define MSR_IA32_APICBASE_BASE (0xfffff<<12)
-#ifndef MSR_IA32_SYSENTER_CS /* VBox x86.h kludge */
-#define MSR_IA32_SYSENTER_CS 0x174
-#define MSR_IA32_SYSENTER_ESP 0x175
-#define MSR_IA32_SYSENTER_EIP 0x176
-#endif
+#define MSR_MTRRcap 0xfe
+#define MSR_MTRRcap_VCNT 8
+#define MSR_MTRRcap_FIXRANGE_SUPPORT (1 << 8)
+#define MSR_MTRRcap_WC_SUPPORTED (1 << 10)
#define MSR_IA32_SYSENTER_CS 0x174
#define MSR_IA32_SYSENTER_ESP 0x175
@@ -270,8 +301,30 @@
#define MSR_IA32_PERF_STATUS 0x198
+#define MSR_MTRRphysBase(reg) (0x200 + 2 * (reg))
+#define MSR_MTRRphysMask(reg) (0x200 + 2 * (reg) + 1)
+
+#define MSR_MTRRfix64K_00000 0x250
+#define MSR_MTRRfix16K_80000 0x258
+#define MSR_MTRRfix16K_A0000 0x259
+#define MSR_MTRRfix4K_C0000 0x268
+#define MSR_MTRRfix4K_C8000 0x269
+#define MSR_MTRRfix4K_D0000 0x26a
+#define MSR_MTRRfix4K_D8000 0x26b
+#define MSR_MTRRfix4K_E0000 0x26c
+#define MSR_MTRRfix4K_E8000 0x26d
+#define MSR_MTRRfix4K_F0000 0x26e
+#define MSR_MTRRfix4K_F8000 0x26f
+
#define MSR_PAT 0x277
+#define MSR_MTRRdefType 0x2ff
+
+#define MSR_MC0_CTL 0x400
+#define MSR_MC0_STATUS 0x401
+#define MSR_MC0_ADDR 0x402
+#define MSR_MC0_MISC 0x403
+
#define MSR_EFER 0xc0000080
#define MSR_EFER_SCE (1 << 0)
@@ -282,8 +335,8 @@
#define MSR_EFER_FFXSR (1 << 14)
#ifdef VBOX
-#define MSR_APIC_RANGE_START 0x800
-#define MSR_APIC_RANGE_END 0x900
+# define MSR_APIC_RANGE_START 0x800
+# define MSR_APIC_RANGE_END 0x900
#endif
#define MSR_STAR 0xc0000081
@@ -293,6 +346,7 @@
#define MSR_FSBASE 0xc0000100
#define MSR_GSBASE 0xc0000101
#define MSR_KERNELGSBASE 0xc0000102
+#define MSR_TSC_AUX 0xc0000103
#define MSR_VM_HSAVE_PA 0xc0010117
@@ -314,6 +368,7 @@
#define CPUID_CMOV (1 << 15)
#define CPUID_PAT (1 << 16)
#define CPUID_PSE36 (1 << 17)
+#define CPUID_PN (1 << 18)
#define CPUID_CLFLUSH (1 << 19)
#define CPUID_DTS (1 << 21)
#define CPUID_ACPI (1 << 22)
@@ -321,11 +376,11 @@
#define CPUID_FXSR (1 << 24)
#define CPUID_SSE (1 << 25)
#define CPUID_SSE2 (1 << 26)
-#define CPUID_SS (1 << 27)
-#define CPUID_HT (1 << 28)
-#define CPUID_TM (1 << 29)
+#define CPUID_SS (1 << 27)
+#define CPUID_HT (1 << 28)
+#define CPUID_TM (1 << 29)
#define CPUID_IA64 (1 << 30)
-#define CPUID_PBE (1 << 31)
+#define CPUID_PBE (1 << 31)
#define CPUID_EXT_SSE3 (1 << 0)
#define CPUID_EXT_DTES64 (1 << 2)
@@ -348,6 +403,7 @@
#define CPUID_EXT_POPCNT (1 << 23)
#define CPUID_EXT_XSAVE (1 << 26)
#define CPUID_EXT_OSXSAVE (1 << 27)
+#define CPUID_EXT_HYPERVISOR (1 << 31)
#define CPUID_EXT2_SYSCALL (1 << 11)
#define CPUID_EXT2_MP (1 << 19)
@@ -385,7 +441,7 @@
#define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */
#define EXCP00_DIVZ 0
-#define EXCP01_SSTP 1
+#define EXCP01_DB 1
#define EXCP02_NMI 2
#define EXCP03_INT3 3
#define EXCP04_INTO 4
@@ -408,7 +464,7 @@
enum {
CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
- CC_OP_EFLAGS, /* all cc are explicitely computed, CC_SRC = flags */
+ CC_OP_EFLAGS, /* all cc are explicitly computed, CC_SRC = flags */
CC_OP_MULB, /* modify all flags, C, O = (CC_SRC != 0) */
CC_OP_MULW,
@@ -460,7 +516,7 @@ enum {
CC_OP_SARL,
CC_OP_SARQ,
- CC_OP_NB
+ CC_OP_NB,
};
#ifdef FLOATX80
@@ -501,7 +557,7 @@ typedef union {
uint64_t q;
} MMXReg;
-#ifdef WORDS_BIGENDIAN
+#ifdef HOST_WORDS_BIGENDIAN
#define XMM_B(n) _b[15 - (n)]
#define XMM_W(n) _w[7 - (n)]
#define XMM_L(n) _l[3 - (n)]
@@ -528,16 +584,33 @@ typedef union {
#endif
#define MMX_Q(n) q
+typedef union {
+#ifdef USE_X86LDOUBLE
+ CPU86_LDouble d __attribute__((aligned(16)));
+#else
+ CPU86_LDouble d;
+#endif
+ MMXReg mmx;
+} FPReg;
+
+typedef struct {
+ uint64_t base;
+ uint64_t mask;
+} MTRRVar;
+
+#define CPU_NB_REGS64 16
+#define CPU_NB_REGS32 8
+
#ifdef TARGET_X86_64
-#define CPU_NB_REGS 16
+#define CPU_NB_REGS CPU_NB_REGS64
#else
-#define CPU_NB_REGS 8
+#define CPU_NB_REGS CPU_NB_REGS32
#endif
#define NB_MMU_MODES 2
typedef struct CPUX86State {
- /* standard registers */
+ /* standard registers */
target_ulong regs[CPU_NB_REGS];
target_ulong eip;
target_ulong eflags; /* eflags register. During CPU emulation, CC
@@ -549,8 +622,8 @@ typedef struct CPUX86State {
target_ulong cc_dst;
uint32_t cc_op;
int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
- uint32_t hflags; /* TB flags, see HF_xxx constants. These flags
- are known at translation time. */
+ uint32_t hflags; /* TB flags, see HF_xxx constants. These flags
+ are known at translation time. */
uint32_t hflags2; /* various other flags, see HF2_xxx constants. */
/* segments */
@@ -561,25 +634,14 @@ typedef struct CPUX86State {
SegmentCache idt; /* only base and limit are used */
target_ulong cr[5]; /* NOTE: cr1 is unused */
- uint64_t a20_mask;
+ int32_t a20_mask;
/* FPU state */
unsigned int fpstt; /* top of stack index */
- unsigned int fpus;
- unsigned int fpuc;
+ uint16_t fpus;
+ uint16_t fpuc;
uint8_t fptags[8]; /* 0 = valid, 1 = empty */
- union {
-#ifdef USE_X86LDOUBLE
-#ifndef VBOX
- CPU86_LDouble d __attribute__((aligned(16)));
-#else
- ALIGNED_MEMBER(CPU86_LDouble, d, 16);
-#endif
-#else
- CPU86_LDouble d;
-#endif
- MMXReg mmx;
- } fpregs[8];
+ FPReg fpregs[8];
/* emulator internal variables */
float_status fp_status;
@@ -604,8 +666,8 @@ typedef struct CPUX86State {
#ifdef VBOX
uint32_t alignment0;
#endif
- uint64_t sysenter_esp;
- uint64_t sysenter_eip;
+ target_ulong sysenter_esp;
+ target_ulong sysenter_eip;
uint64_t efer;
uint64_t star;
@@ -626,6 +688,10 @@ typedef struct CPUX86State {
target_ulong fmask;
target_ulong kernelgsbase;
#endif
+ uint64_t system_time_msr;
+ uint64_t wall_clock_msr;
+
+ uint64_t tsc;
uint64_t pat;
@@ -634,6 +700,10 @@ typedef struct CPUX86State {
int exception_is_int;
target_ulong exception_next_eip;
target_ulong dr[8]; /* debug registers */
+ union {
+ CPUBreakpoint *cpu_breakpoint[4];
+ CPUWatchpoint *cpu_watchpoint[4];
+ }; /* break/watchpoints for dr[0..3] */
uint32_t smbase;
int old_exception; /* exception in flight */
@@ -669,20 +739,63 @@ typedef struct CPUX86State {
uint32_t cpuid_ext2_features;
uint32_t cpuid_ext3_features;
uint32_t cpuid_apic_id;
-
#ifndef VBOX
-#ifdef USE_KQEMU
- int kqemu_enabled;
- int last_io_time;
-#endif
+ int cpuid_vendor_override;
+
+ /* MTRRs */
+ uint64_t mtrr_fixed[11];
+ uint64_t mtrr_deftype;
+ MTRRVar mtrr_var[8];
+
+ /* For KVM */
+ uint32_t mp_state;
+ int32_t exception_injected;
+ int32_t interrupt_injected;
+ uint8_t soft_interrupt;
+ uint8_t nmi_injected;
+ uint8_t nmi_pending;
+ uint8_t has_error_code;
+ uint32_t sipi_vector;
+
+ uint32_t cpuid_kvm_features;
+
/* in order to simplify APIC support, we leave this pointer to the
user */
- struct APICState *apic_state;
-#else
- uint32_t alignment2[3];
+ struct DeviceState *apic_state;
+
+ uint64 mcg_cap;
+ uint64 mcg_status;
+ uint64 mcg_ctl;
+ uint64 mce_banks[MCE_BANKS_DEF*4];
+
+ uint64_t tsc_aux;
+
+ /* vmstate */
+ uint16_t fpus_vmstate;
+ uint16_t fptag_vmstate;
+ uint16_t fpregs_format_vmstate;
+
+ uint64_t xstate_bv;
+ XMMReg ymmh_regs[CPU_NB_REGS];
+
+ uint64_t xcr0;
+#else /* VBOX */
+
+ /** Alignment padding. */
+# if HC_ARCH_BITS == 64 \
+ || ( HC_ARCH_BITS == 32 \
+ && !defined(RT_OS_WINDOWS) \
+ && ( (!defined(VBOX_ENABLE_VBOXREM64) && !defined(RT_OS_SOLARIS)) \
+ || (defined(VBOX_ENABLE_VBOXREM64) && defined(RT_OS_SOLARIS)) ) )
+ uint32_t alignment2[1];
+# endif
+
/** Profiling tb_flush. */
STAMPROFILE StatTbFlush;
-#endif
+
+ /** Addends for HVA -> GPA translations. */
+ target_phys_addr_t phys_addends[NB_MMU_MODES][CPU_TLB_SIZE];
+#endif /* VBOX */
} CPUX86State;
#ifdef VBOX
@@ -697,14 +810,14 @@ typedef struct SegmentCache_Ver16 {
uint32_t newselector;
} SegmentCache_Ver16;
-#define CPU_NB_REGS_VER16 8
+# define CPU_NB_REGS_VER16 8
/* Version 1.6 structure; just for loading the old saved state */
typedef struct CPUX86State_Ver16 {
-#if TARGET_LONG_BITS > HOST_LONG_BITS
+# if TARGET_LONG_BITS > HOST_LONG_BITS
/* temporaries if we cannot store them in host registers */
uint32_t t0, t1, t2;
-#endif
+# endif
/* standard registers */
uint32_t regs[CPU_NB_REGS_VER16];
@@ -736,27 +849,23 @@ typedef struct CPUX86State_Ver16 {
unsigned int fpuc;
uint8_t fptags[8]; /* 0 = valid, 1 = empty */
union {
-#ifdef USE_X86LDOUBLE
-#ifndef VBOX
+# ifdef USE_X86LDOUBLE
CPU86_LDouble d __attribute__((aligned(16)));
-#else
- ALIGNED_MEMBER(CPU86_LDouble, d, 16);
-#endif
-#else
+# else
CPU86_LDouble d;
-#endif
+# endif
MMXReg mmx;
} fpregs[8];
/* emulator internal variables */
float_status fp_status;
-#ifdef VBOX
+# ifdef VBOX
uint32_t alignment3[3]; /* force the long double to start a 16 byte line. */
-#endif
+# endif
CPU86_LDouble ft0;
-#if defined(VBOX) && defined(RT_ARCH_X86) && !defined(RT_OS_DARWIN)
+# if defined(VBOX) && defined(RT_ARCH_X86) && !defined(RT_OS_DARWIN)
uint32_t alignment4; /* long double is 12 byte, pad it to 16. */
-#endif
+# endif
union {
float f;
double d;
@@ -774,20 +883,20 @@ typedef struct CPUX86State_Ver16 {
uint32_t sysenter_cs;
uint32_t sysenter_esp;
uint32_t sysenter_eip;
-#ifdef VBOX
+# ifdef VBOX
uint32_t alignment0;
-#endif
+# endif
uint64_t efer;
uint64_t star;
uint64_t pat;
/* temporary data for USE_CODE_COPY mode */
-#ifdef USE_CODE_COPY
+# ifdef USE_CODE_COPY
uint32_t tmp0;
uint32_t saved_esp;
int native_fp_regs; /* if true, the FPU state is in the native CPU regs */
-#endif
+# endif
/* exception/interrupt handling */
jmp_buf jmp_env;
@@ -795,10 +904,10 @@ typedef struct CPUX86State_Ver16 {
/** CPUX86State state flags
* @{ */
-#define CPU_RAW_RING0 0x0002 /* Set after first time RawR0 is executed, never cleared. */
-#define CPU_EMULATE_SINGLE_INSTR 0x0040 /* Execute a single instruction in emulation mode */
-#define CPU_EMULATE_SINGLE_STEP 0x0080 /* go into single step mode */
-#define CPU_RAW_HWACC 0x0100 /* Set after first time HWACC is executed, never cleared. */
+# define CPU_RAW_RING0 0x0002 /* Set after first time RawR0 is executed, never cleared. */
+# define CPU_EMULATE_SINGLE_INSTR 0x0040 /* Execute a single instruction in emulation mode */
+# define CPU_EMULATE_SINGLE_STEP 0x0080 /* go into single step mode */
+# define CPU_RAW_HWACC 0x0100 /* Set after first time HWACC is executed, never cleared. */
/** @} */
#endif /* !VBOX */
@@ -809,28 +918,21 @@ CPUX86State *cpu_x86_init(const char *cpu_model);
#endif /* !VBOX */
int cpu_x86_exec(CPUX86State *s);
void cpu_x86_close(CPUX86State *s);
-void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
- ...));
+void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+ const char *optarg);
+void x86_cpudef_setup(void);
+
int cpu_get_pic_interrupt(CPUX86State *s);
/* MSDOS compatibility mode FPU exception support */
void cpu_set_ferr(CPUX86State *s);
/* this function must always be used to load data in the segment
cache: it synchronizes the hflags with the segment cache values */
-#ifndef VBOX
static inline void cpu_x86_load_seg_cache(CPUX86State *env,
int seg_reg, unsigned int selector,
target_ulong base,
unsigned int limit,
unsigned int flags)
-#else
-DECLINLINE(void) cpu_x86_load_seg_cache(CPUX86State *env,
- int seg_reg, unsigned int selector,
- target_ulong base,
- unsigned int limit,
- unsigned int flags)
-
-#endif
{
SegmentCache *sc;
unsigned int new_hflags;
@@ -886,12 +988,23 @@ DECLINLINE(void) cpu_x86_load_seg_cache(CPUX86State *env,
}
}
+static inline void cpu_x86_load_seg_cache_sipi(CPUX86State *env,
+ int sipi_vector)
+{
+ env->eip = 0;
+ cpu_x86_load_seg_cache(env, R_CS, sipi_vector << 8,
+ sipi_vector << 12,
+ env->segs[R_CS].limit,
+ env->segs[R_CS].flags);
+ env->halted = 0;
+}
+
+int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
+ target_ulong *base, unsigned int *limit,
+ unsigned int *flags);
+
/* wrapper, just in case memory mappings must be changed */
-#ifndef VBOX
static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl)
-#else
-DECLINLINE(void) cpu_x86_set_cpl(CPUX86State *s, int cpl)
-#endif
{
#if HF_CPL_MASK == 3
s->hflags = (s->hflags & ~HF_CPL_MASK) | cpl;
@@ -900,54 +1013,73 @@ DECLINLINE(void) cpu_x86_set_cpl(CPUX86State *s, int cpl)
#endif
}
+/* op_helper.c */
/* used for debug or cpu save/restore */
void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f);
CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper);
+/* cpu-exec.c */
/* the following helpers are only usable in user mode simulation as
they can trigger unexpected exceptions */
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector);
-void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32);
-void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32);
+void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32);
+void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32);
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU. */
int cpu_x86_signal_handler(int host_signum, void *pinfo,
void *puc);
+
+/* cpuid.c */
+void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx);
+int cpu_x86_register (CPUX86State *env, const char *cpu_model);
+void cpu_clear_apic_feature(CPUX86State *env);
+
+/* helper.c */
+int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
+ int is_write, int mmu_idx, int is_softmmu);
+#define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault
void cpu_x86_set_a20(CPUX86State *env, int a20_state);
-uint64_t cpu_get_tsc(CPUX86State *env);
+static inline int hw_breakpoint_enabled(unsigned long dr7, int index)
+{
+ return (dr7 >> (index * 2)) & 3;
+}
-void cpu_set_apic_base(CPUX86State *env, uint64_t val);
-uint64_t cpu_get_apic_base(CPUX86State *env);
-void cpu_set_apic_tpr(CPUX86State *env, uint8_t val);
-#ifndef NO_CPU_IO_DEFS
-uint8_t cpu_get_apic_tpr(CPUX86State *env);
-#endif
-#ifdef VBOX
-int cpu_rdmsr(CPUX86State *env, uint32_t idMsr, uint64_t *puValue);
-int cpu_wrmsr(CPUX86State *env, uint32_t idMsr, uint64_t uValue);
-#endif
-void cpu_smm_update(CPUX86State *env);
+static inline int hw_breakpoint_type(unsigned long dr7, int index)
+{
+ return (dr7 >> (DR7_TYPE_SHIFT + (index * 4))) & 3;
+}
+
+static inline int hw_breakpoint_len(unsigned long dr7, int index)
+{
+ int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 4))) & 3);
+ return (len == 2) ? 8 : len + 1;
+}
+
+void hw_breakpoint_insert(CPUX86State *env, int index);
+void hw_breakpoint_remove(CPUX86State *env, int index);
+int check_hw_breakpoints(CPUX86State *env, int force_dr6_update);
/* will be suppressed */
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
+void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
+void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
+
+/* hw/pc.c */
+void cpu_smm_update(CPUX86State *env);
+uint64_t cpu_get_tsc(CPUX86State *env);
/* used to debug */
#define X86_DUMP_FPU 0x0001 /* dump FPU state too */
#define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
-#ifdef USE_KQEMU
-static inline int cpu_get_time_fast(void)
-{
- int low, high;
- asm volatile("rdtsc" : "=a" (low), "=d" (high));
- return low;
-}
-#endif
-
#ifdef VBOX
+int cpu_rdmsr(CPUX86State *env, uint32_t idMsr, uint64_t *puValue);
+int cpu_wrmsr(CPUX86State *env, uint32_t idMsr, uint64_t uValue);
void cpu_trap_raw(CPUX86State *env1);
/* in helper.c */
@@ -963,33 +1095,40 @@ int get_ss_esp_from_tss_raw(CPUX86State *env1, uint32_t *ss_ptr, uint32_t *esp_p
void restore_raw_fp_state(CPUX86State *env, uint8_t *ptr);
void save_raw_fp_state(CPUX86State *env, uint8_t *ptr);
-
-#endif
+#endif /* VBOX */
#define TARGET_PAGE_BITS 12
-#define CPUState CPUX86State
+#ifdef TARGET_X86_64
+#define TARGET_PHYS_ADDR_SPACE_BITS 52
+/* ??? This is really 48 bits, sign-extended, but the only thing
+ accessible to userland with bit 48 set is the VSYSCALL, and that
+ is handled via other mechanisms. */
+#define TARGET_VIRT_ADDR_SPACE_BITS 47
+#else
+#define TARGET_PHYS_ADDR_SPACE_BITS 36
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
+#endif
+
#define cpu_init cpu_x86_init
#define cpu_exec cpu_x86_exec
#define cpu_gen_code cpu_x86_gen_code
#define cpu_signal_handler cpu_x86_signal_handler
-#define cpu_list x86_cpu_list
+#define cpu_list_id x86_cpu_list
+#define cpudef_setup x86_cpudef_setup
-#define CPU_SAVE_VERSION 7
+#define CPU_SAVE_VERSION 12
/* MMU modes definitions */
#define MMU_MODE0_SUFFIX _kernel
#define MMU_MODE1_SUFFIX _user
#define MMU_USER_IDX 1
-#ifndef VBOX
static inline int cpu_mmu_index (CPUState *env)
-#else
-DECLINLINE(int) cpu_mmu_index (CPUState *env)
-#endif
{
return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
}
+/* translate.c */
void optimize_flags_init(void);
typedef struct CCTable {
@@ -997,8 +1136,6 @@ typedef struct CCTable {
int (*compute_c)(void); /* return the C flag */
} CCTable;
-extern CCTable cc_table[];
-
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
@@ -1008,10 +1145,32 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
}
#endif
-#define CPU_PC_FROM_TB(env, tb) env->eip = tb->pc - tb->cs_base
-
#include "cpu-all.h"
-
#include "svm.h"
+#ifndef VBOX
+#if !defined(CONFIG_USER_ONLY)
+#include "hw/apic.h"
+#endif
+#else /* VBOX */
+extern void cpu_set_apic_tpr(CPUX86State *env, uint8_t val);
+extern uint8_t cpu_get_apic_tpr(CPUX86State *env);
+extern uint64_t cpu_get_apic_base(CPUX86State *env);
+#endif /* VBOX */
+
+static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+ target_ulong *cs_base, int *flags)
+{
+ *cs_base = env->segs[R_CS].base;
+ *pc = *cs_base + env->eip;
+ *flags = env->hflags |
+ (env->eflags & (IOPL_MASK | TF_MASK | RF_MASK | VM_MASK));
+}
+
+#ifndef VBOX
+void apic_init_reset(CPUState *env);
+void apic_sipi(CPUState *env);
+void do_cpu_init(CPUState *env);
+void do_cpu_sipi(CPUState *env);
+#endif /* !VBOX */
#endif /* CPU_I386_H */
diff --git a/src/recompiler/target-i386/exec.h b/src/recompiler/target-i386/exec.h
index b78af02ba..567152802 100644
--- a/src/recompiler/target-i386/exec.h
+++ b/src/recompiler/target-i386/exec.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -39,40 +38,29 @@
#include "cpu-defs.h"
-#ifndef VBOX
-/* at least 4 register variables are defined */
register struct CPUX86State *env asm(AREG0);
-#else
-REGISTER_BOUND_GLOBAL(struct CPUX86State*, env, AREG0);
-#endif /* VBOX */
+#include "qemu-common.h"
#include "qemu-log.h"
-#ifndef reg_EAX
+#undef EAX
#define EAX (env->regs[R_EAX])
-#endif
-#ifndef reg_ECX
+#undef ECX
#define ECX (env->regs[R_ECX])
-#endif
-#ifndef reg_EDX
+#undef EDX
#define EDX (env->regs[R_EDX])
-#endif
-#ifndef reg_EBX
+#undef EBX
#define EBX (env->regs[R_EBX])
-#endif
-#ifndef reg_ESP
+#undef ESP
#define ESP (env->regs[R_ESP])
-#endif
-#ifndef reg_EBP
+#undef EBP
#define EBP (env->regs[R_EBP])
-#endif
-#ifndef reg_ESI
+#undef ESI
#define ESI (env->regs[R_ESI])
-#endif
-#ifndef reg_EDI
+#undef EDI
#define EDI (env->regs[R_EDI])
-#endif
-#define EIP (env->eip)
+#undef EIP
+#define EIP (env->eip)
#define DF (env->df)
#define CC_SRC (env->cc_src)
@@ -88,38 +76,18 @@ REGISTER_BOUND_GLOBAL(struct CPUX86State*, env, AREG0);
#include "cpu.h"
#include "exec-all.h"
-void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
-void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
-int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
- int is_write, int mmu_idx, int is_softmmu);
-void __hidden cpu_lock(void);
-void __hidden cpu_unlock(void);
+/* op_helper.c */
void do_interrupt(int intno, int is_int, int error_code,
target_ulong next_eip, int is_hw);
void do_interrupt_user(int intno, int is_int, int error_code,
target_ulong next_eip);
-void raise_interrupt(int intno, int is_int, int error_code,
- int next_eip_addend);
-void raise_exception_err(int exception_index, int error_code);
-void raise_exception(int exception_index);
+void QEMU_NORETURN raise_exception_err(int exception_index, int error_code);
+void QEMU_NORETURN raise_exception(int exception_index);
+void QEMU_NORETURN raise_exception_env(int exception_index, CPUState *nenv);
void do_smm_enter(void);
-void __hidden cpu_loop_exit(void);
-
-void OPPROTO op_movl_eflags_T0(void);
-void OPPROTO op_movl_T0_eflags(void);
-#ifdef VBOX
-void OPPROTO op_movl_T0_eflags_vme(void);
-void OPPROTO op_movw_eflags_T0_vme(void);
-void OPPROTO op_cli_vme(void);
-void OPPROTO op_sti_vme(void);
-#endif
/* n must be a constant to be efficient */
-#ifndef VBOX
static inline target_long lshift(target_long x, int n)
-#else
-DECLINLINE(target_long) lshift(target_long x, int n)
-#endif
{
if (n >= 0)
return x << n;
@@ -129,82 +97,15 @@ DECLINLINE(target_long) lshift(target_long x, int n)
#include "helper.h"
-#ifndef VBOX
static inline void svm_check_intercept(uint32_t type)
-#else
-DECLINLINE(void) svm_check_intercept(uint32_t type)
-#endif
{
helper_svm_check_intercept_param(type, 0);
}
-void check_iob_T0(void);
-void check_iow_T0(void);
-void check_iol_T0(void);
-void check_iob_DX(void);
-void check_iow_DX(void);
-void check_iol_DX(void);
-
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
-#ifndef VBOX
-static inline double ldfq(target_ulong ptr)
-#else
-DECLINLINE(double) ldfq(target_ulong ptr)
-#endif
-{
- union {
- double d;
- uint64_t i;
- } u;
- u.i = ldq(ptr);
- return u.d;
-}
-
-#ifndef VBOX
-static inline void stfq(target_ulong ptr, double v)
-#else
-DECLINLINE(void) stfq(target_ulong ptr, double v)
-#endif
-{
- union {
- double d;
- uint64_t i;
- } u;
- u.d = v;
- stq(ptr, u.i);
-}
-
-#ifndef VBOX
-static inline float ldfl(target_ulong ptr)
-#else
-DECLINLINE(float) ldfl(target_ulong ptr)
-#endif
-{
- union {
- float f;
- uint32_t i;
- } u;
- u.i = ldl(ptr);
- return u.f;
-}
-
-#ifndef VBOX
-static inline void stfl(target_ulong ptr, float v)
-#else
-DECLINLINE(void) stfl(target_ulong ptr, float v)
-#endif
-{
- union {
- float f;
- uint32_t i;
- } u;
- u.f = v;
- stl(ptr, u.i);
-}
-
#endif /* !defined(CONFIG_USER_ONLY) */
#ifdef USE_X86LDOUBLE
@@ -224,30 +125,6 @@ DECLINLINE(void) stfl(target_ulong ptr, float v)
#define floatx_round_to_int floatx80_round_to_int
#define floatx_compare floatx80_compare
#define floatx_compare_quiet floatx80_compare_quiet
-#ifdef VBOX
-#undef sin
-#undef cos
-#undef sqrt
-#undef pow
-#undef log
-#undef tan
-#undef atan2
-#undef floor
-#undef ceil
-#undef ldexp
-#endif /* !VBOX */
-#if !defined(VBOX) || !defined(_MSC_VER)
-#define sin sinl
-#define cos cosl
-#define sqrt sqrtl
-#define pow powl
-#define log logl
-#define tan tanl
-#define atan2 atan2l
-#define floor floorl
-#define ceil ceill
-#define ldexp ldexpl
-#endif
#else
#define floatx_to_int32 float64_to_int32
#define floatx_to_int64 float64_to_int64
@@ -267,32 +144,35 @@ DECLINLINE(void) stfl(target_ulong ptr, float v)
#endif
#ifdef VBOX
-#ifndef _MSC_VER
-extern CPU86_LDouble sin(CPU86_LDouble x);
-extern CPU86_LDouble cos(CPU86_LDouble x);
-extern CPU86_LDouble sqrt(CPU86_LDouble x);
-extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble);
-extern CPU86_LDouble log(CPU86_LDouble x);
-extern CPU86_LDouble tan(CPU86_LDouble x);
-extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble);
-extern CPU86_LDouble floor(CPU86_LDouble x);
-extern CPU86_LDouble ceil(CPU86_LDouble x);
-#endif /* !_MSC_VER */
-#endif /* VBOX */
+# ifdef IPRT_NO_CRT
+# undef sin
+# undef cos
+# undef sqrt
+# undef pow
+# undef log
+# undef tan
+# undef atan2
+# undef floor
+# undef ceil
+# undef ldexp
+# define sin sinl
+# define cos cosl
+# define sqrt sqrtl
+# define pow powl
+# define log logl
+# define tan tanl
+# define atan2 atan2l
+# define floor floorl
+# define ceil ceill
+# define ldexp ldexpl
+# endif
+#endif
#define RC_MASK 0xc00
-#ifndef RC_NEAR
#define RC_NEAR 0x000
-#endif
-#ifndef RC_DOWN
#define RC_DOWN 0x400
-#endif
-#ifndef RC_UP
#define RC_UP 0x800
-#endif
-#ifndef RC_CHOP
#define RC_CHOP 0xc00
-#endif
#define MAXTAN 9223372036854775808.0
@@ -320,7 +200,7 @@ typedef union {
/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
typedef union {
double d;
-#if !defined(WORDS_BIGENDIAN) && !defined(__arm__)
+#if !defined(HOST_WORDS_BIGENDIAN) && !defined(__arm__)
struct {
uint32_t lower;
int32_t upper;
@@ -349,23 +229,15 @@ typedef union {
#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20)
#endif
-#ifndef VBOX
static inline void fpush(void)
-#else
-DECLINLINE(void) fpush(void)
-#endif
{
env->fpstt = (env->fpstt - 1) & 7;
env->fptags[env->fpstt] = 0; /* validate stack entry */
}
-#ifndef VBOX
static inline void fpop(void)
-#else
-DECLINLINE(void) fpop(void)
-#endif
{
- env->fptags[env->fpstt] = 1; /* invalidate stack entry */
+ env->fptags[env->fpstt] = 1; /* invvalidate stack entry */
env->fpstt = (env->fpstt + 1) & 7;
}
@@ -406,29 +278,9 @@ static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
}
#else
-/* XXX: same endianness assumed */
-
-#ifdef CONFIG_USER_ONLY
-
-static inline CPU86_LDouble helper_fldt(target_ulong ptr)
-{
- return *(CPU86_LDouble *)ptr;
-}
-
-static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
-{
- *(CPU86_LDouble *)ptr = f;
-}
-
-#else
-
/* we use memory access macros */
-#ifndef VBOX
static inline CPU86_LDouble helper_fldt(target_ulong ptr)
-#else
-DECLINLINE(CPU86_LDouble) helper_fldt(target_ulong ptr)
-#endif
{
CPU86_LDoubleU temp;
@@ -437,11 +289,7 @@ DECLINLINE(CPU86_LDouble) helper_fldt(target_ulong ptr)
return temp.d;
}
-#ifndef VBOX
static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
-#else
-DECLINLINE(void) helper_fstt(CPU86_LDouble f, target_ulong ptr)
-#endif
{
CPU86_LDoubleU temp;
@@ -450,8 +298,6 @@ DECLINLINE(void) helper_fstt(CPU86_LDouble f, target_ulong ptr)
stw(ptr + 8, temp.l.upper);
}
-#endif /* !CONFIG_USER_ONLY */
-
#endif /* USE_X86LDOUBLE */
#define FPUS_IE (1 << 0)
@@ -466,114 +312,39 @@ DECLINLINE(void) helper_fstt(CPU86_LDouble f, target_ulong ptr)
#define FPUC_EM 0x3f
-extern const CPU86_LDouble f15rk[7];
-
-void fpu_raise_exception(void);
-void restore_native_fp_state(CPUState *env);
-void save_native_fp_state(CPUState *env);
-
-extern const uint8_t parity_table[256];
-extern const uint8_t rclw_table[32];
-extern const uint8_t rclb_table[32];
-
-#ifndef VBOX
static inline uint32_t compute_eflags(void)
-#else
-DECLINLINE(uint32_t) compute_eflags(void)
-#endif
{
- return env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
+ return env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
}
/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */
-#ifndef VBOX
static inline void load_eflags(int eflags, int update_mask)
-#else
-DECLINLINE(void) load_eflags(int eflags, int update_mask)
-#endif
{
CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
DF = 1 - (2 * ((eflags >> 10) & 1));
env->eflags = (env->eflags & ~update_mask) |
- (eflags & update_mask);
+ (eflags & update_mask) | 0x2;
}
-#ifndef VBOX
-static inline void env_to_regs(void)
-#else
-DECLINLINE(void) env_to_regs(void)
-#endif
+static inline int cpu_has_work(CPUState *env)
{
-#ifdef reg_EAX
- EAX = env->regs[R_EAX];
-#endif
-#ifdef reg_ECX
- ECX = env->regs[R_ECX];
-#endif
-#ifdef reg_EDX
- EDX = env->regs[R_EDX];
-#endif
-#ifdef reg_EBX
- EBX = env->regs[R_EBX];
-#endif
-#ifdef reg_ESP
- ESP = env->regs[R_ESP];
-#endif
-#ifdef reg_EBP
- EBP = env->regs[R_EBP];
-#endif
-#ifdef reg_ESI
- ESI = env->regs[R_ESI];
-#endif
-#ifdef reg_EDI
- EDI = env->regs[R_EDI];
-#endif
-}
+ int work;
-#ifndef VBOX
-static inline void regs_to_env(void)
-#else
-DECLINLINE(void) regs_to_env(void)
-#endif
-{
-#ifdef reg_EAX
- env->regs[R_EAX] = EAX;
-#endif
-#ifdef reg_ECX
- env->regs[R_ECX] = ECX;
-#endif
-#ifdef reg_EDX
- env->regs[R_EDX] = EDX;
-#endif
-#ifdef reg_EBX
- env->regs[R_EBX] = EBX;
-#endif
-#ifdef reg_ESP
- env->regs[R_ESP] = ESP;
-#endif
-#ifdef reg_EBP
- env->regs[R_EBP] = EBP;
-#endif
-#ifdef reg_ESI
- env->regs[R_ESI] = ESI;
-#endif
-#ifdef reg_EDI
- env->regs[R_EDI] = EDI;
-#endif
+ work = (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->eflags & IF_MASK);
+ work |= env->interrupt_request & CPU_INTERRUPT_NMI;
+ work |= env->interrupt_request & CPU_INTERRUPT_INIT;
+ work |= env->interrupt_request & CPU_INTERRUPT_SIPI;
+
+ return work;
}
-#ifndef VBOX
static inline int cpu_halted(CPUState *env) {
-#else
-DECLINLINE(int) cpu_halted(CPUState *env) {
-#endif
/* handle exit of HALTED state */
if (!env->halted)
return 0;
/* disable halt condition */
- if (((env->interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->eflags & IF_MASK)) ||
- (env->interrupt_request & CPU_INTERRUPT_NMI)) {
+ if (cpu_has_work(env)) {
env->halted = 0;
return 0;
}
@@ -582,11 +353,7 @@ DECLINLINE(int) cpu_halted(CPUState *env) {
/* load efer and update the corresponding hflags. XXX: do consistency
checks with cpuid bits ? */
-#ifndef VBOX
static inline void cpu_load_efer(CPUState *env, uint64_t val)
-#else
-DECLINLINE(void) cpu_load_efer(CPUState *env, uint64_t val)
-#endif
{
env->efer = val;
env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK);
@@ -595,3 +362,9 @@ DECLINLINE(void) cpu_load_efer(CPUState *env, uint64_t val)
if (env->efer & MSR_EFER_SVME)
env->hflags |= HF_SVME_MASK;
}
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->eip = tb->pc - tb->cs_base;
+}
+
diff --git a/src/recompiler/target-i386/helper.c b/src/recompiler/target-i386/helper.c
index 70fb747b3..f18567959 100644
--- a/src/recompiler/target-i386/helper.c
+++ b/src/recompiler/target-i386/helper.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -34,437 +33,25 @@
#ifndef VBOX
#include <inttypes.h>
#include <signal.h>
-#include <assert.h>
-#endif
+#endif /* !VBOX */
#include "cpu.h"
#include "exec-all.h"
-#include "svm.h"
#include "qemu-common.h"
+#include "kvm.h"
//#define DEBUG_MMU
-static int cpu_x86_register (CPUX86State *env, const char *cpu_model);
-
-#ifndef VBOX
-static void add_flagname_to_bitmaps(char *flagname, uint32_t *features,
- uint32_t *ext_features,
- uint32_t *ext2_features,
- uint32_t *ext3_features)
-{
- int i;
- /* feature flags taken from "Intel Processor Identification and the CPUID
- * Instruction" and AMD's "CPUID Specification". In cases of disagreement
- * about feature names, the Linux name is used. */
- static const char *feature_name[] = {
- "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
- "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
- "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
- "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
- };
- static const char *ext_feature_name[] = {
- "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
- "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
- NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- };
- static const char *ext2_feature_name[] = {
- "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
- "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mttr", "pge", "mca", "cmov",
- "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
- "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
- };
- static const char *ext3_feature_name[] = {
- "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
- "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- };
-
- for ( i = 0 ; i < 32 ; i++ )
- if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
- *features |= 1 << i;
- return;
- }
- for ( i = 0 ; i < 32 ; i++ )
- if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
- *ext_features |= 1 << i;
- return;
- }
- for ( i = 0 ; i < 32 ; i++ )
- if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
- *ext2_features |= 1 << i;
- return;
- }
- for ( i = 0 ; i < 32 ; i++ )
- if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
- *ext3_features |= 1 << i;
- return;
- }
- fprintf(stderr, "CPU feature %s not found\n", flagname);
-}
-#endif /* !VBOX */
-#ifndef VBOX
-CPUX86State *cpu_x86_init(const char *cpu_model)
-{
- CPUX86State *env;
- static int inited;
-
- env = qemu_mallocz(sizeof(CPUX86State));
- if (!env)
- return NULL;
-#else
-CPUX86State *cpu_x86_init(CPUX86State *env, const char *cpu_model)
-{
- static int inited;
-#endif
- cpu_exec_init(env);
- env->cpu_model_str = cpu_model;
-
- /* init various static tables */
- if (!inited) {
- inited = 1;
- optimize_flags_init();
- }
- if (cpu_x86_register(env, cpu_model) < 0) {
- cpu_x86_close(env);
- return NULL;
- }
- cpu_reset(env);
-#ifdef USE_KQEMU
- kqemu_init(env);
-#endif
- return env;
-}
-
-typedef struct x86_def_t {
- const char *name;
- uint32_t level;
- uint32_t vendor1, vendor2, vendor3;
- int family;
- int model;
- int stepping;
- uint32_t features, ext_features, ext2_features, ext3_features;
- uint32_t xlevel;
- char model_id[48];
-} x86_def_t;
-
-#ifndef VBOX
-#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
-#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
- CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX)
-#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
- CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
- CPUID_PSE36 | CPUID_FXSR)
-#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
-#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
- CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
- CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
- CPUID_PAE | CPUID_SEP | CPUID_APIC)
-static x86_def_t x86_defs[] = {
-#ifdef TARGET_X86_64
- {
- .name = "qemu64",
- .level = 2,
- .vendor1 = CPUID_VENDOR_AMD_1,
- .vendor2 = CPUID_VENDOR_AMD_2,
- .vendor3 = CPUID_VENDOR_AMD_3,
- .family = 6,
- .model = 2,
- .stepping = 3,
- .features = PPRO_FEATURES |
- /* these features are needed for Win64 and aren't fully implemented */
- CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
- /* this feature is needed for Solaris and isn't fully implemented */
- CPUID_PSE36,
- .ext_features = CPUID_EXT_SSE3,
- .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
- CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
- CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
- .ext3_features = CPUID_EXT3_SVM,
- .xlevel = 0x8000000A,
- .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
- },
- {
- .name = "core2duo",
- .level = 10,
- .family = 6,
- .model = 15,
- .stepping = 11,
- /* The original CPU also implements these features:
- CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
- CPUID_TM, CPUID_PBE */
- .features = PPRO_FEATURES |
- CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
- CPUID_PSE36,
- /* The original CPU also implements these ext features:
- CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
- CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
- .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
- /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
- .xlevel = 0x80000008,
- .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
- },
-#endif
- {
- .name = "qemu32",
- .level = 2,
- .family = 6,
- .model = 3,
- .stepping = 3,
- .features = PPRO_FEATURES,
- .ext_features = CPUID_EXT_SSE3,
- .xlevel = 0,
- .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
- },
- {
- .name = "coreduo",
- .level = 10,
- .family = 6,
- .model = 14,
- .stepping = 8,
- /* The original CPU also implements these features:
- CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
- CPUID_TM, CPUID_PBE */
- .features = PPRO_FEATURES | CPUID_VME |
- CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
- /* The original CPU also implements these ext features:
- CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
- CPUID_EXT_PDCM */
- .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
- .ext2_features = CPUID_EXT2_NX,
- .xlevel = 0x80000008,
- .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
- },
- {
- .name = "486",
- .level = 0,
- .family = 4,
- .model = 0,
- .stepping = 0,
- .features = I486_FEATURES,
- .xlevel = 0,
- },
- {
- .name = "pentium",
- .level = 1,
- .family = 5,
- .model = 4,
- .stepping = 3,
- .features = PENTIUM_FEATURES,
- .xlevel = 0,
- },
- {
- .name = "pentium2",
- .level = 2,
- .family = 6,
- .model = 5,
- .stepping = 2,
- .features = PENTIUM2_FEATURES,
- .xlevel = 0,
- },
- {
- .name = "pentium3",
- .level = 2,
- .family = 6,
- .model = 7,
- .stepping = 3,
- .features = PENTIUM3_FEATURES,
- .xlevel = 0,
- },
- {
- .name = "athlon",
- .level = 2,
- .vendor1 = 0x68747541, /* "Auth" */
- .vendor2 = 0x69746e65, /* "enti" */
- .vendor3 = 0x444d4163, /* "cAMD" */
- .family = 6,
- .model = 2,
- .stepping = 3,
- .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
- .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
- .xlevel = 0x80000008,
- /* XXX: put another string ? */
- .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
- },
- {
- .name = "n270",
- /* original is on level 10 */
- .level = 5,
- .family = 6,
- .model = 28,
- .stepping = 2,
- .features = PPRO_FEATURES |
- CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
- /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
- * CPUID_HT | CPUID_TM | CPUID_PBE */
- /* Some CPUs got no CPUID_SEP */
- .ext_features = CPUID_EXT_MONITOR |
- CPUID_EXT_SSE3 /* PNI */,
- /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
- * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
- .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
- /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
- .xlevel = 0x8000000A,
- .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
- },
-};
-
-static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
-{
- unsigned int i;
- x86_def_t *def;
-
- char *s = strdup(cpu_model);
- char *featurestr, *name = strtok(s, ",");
- uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
- uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
- int family = -1, model = -1, stepping = -1;
-
- def = NULL;
- for (i = 0; i < sizeof(x86_defs) / sizeof(x86_def_t); i++) {
- if (strcmp(name, x86_defs[i].name) == 0) {
- def = &x86_defs[i];
- break;
- }
- }
- if (!def)
- goto error;
- memcpy(x86_cpu_def, def, sizeof(*def));
-
- featurestr = strtok(NULL, ",");
-
- while (featurestr) {
- char *val;
- if (featurestr[0] == '+') {
- add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
- } else if (featurestr[0] == '-') {
- add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
- } else if ((val = strchr(featurestr, '='))) {
- *val = 0; val++;
- if (!strcmp(featurestr, "family")) {
- char *err;
- family = strtol(val, &err, 10);
- if (!*val || *err || family < 0) {
- fprintf(stderr, "bad numerical value %s\n", val);
- goto error;
- }
- x86_cpu_def->family = family;
- } else if (!strcmp(featurestr, "model")) {
- char *err;
- model = strtol(val, &err, 10);
- if (!*val || *err || model < 0 || model > 0xf) {
- fprintf(stderr, "bad numerical value %s\n", val);
- goto error;
- }
- x86_cpu_def->model = model;
- } else if (!strcmp(featurestr, "stepping")) {
- char *err;
- stepping = strtol(val, &err, 10);
- if (!*val || *err || stepping < 0 || stepping > 0xf) {
- fprintf(stderr, "bad numerical value %s\n", val);
- goto error;
- }
- x86_cpu_def->stepping = stepping;
- } else if (!strcmp(featurestr, "vendor")) {
- if (strlen(val) != 12) {
- fprintf(stderr, "vendor string must be 12 chars long\n");
- goto error;
- }
- x86_cpu_def->vendor1 = 0;
- x86_cpu_def->vendor2 = 0;
- x86_cpu_def->vendor3 = 0;
- for(i = 0; i < 4; i++) {
- x86_cpu_def->vendor1 |= ((uint8_t)val[i ]) << (8 * i);
- x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
- x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
- }
- } else if (!strcmp(featurestr, "model_id")) {
- pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
- val);
- } else {
- fprintf(stderr, "unrecognized feature %s\n", featurestr);
- goto error;
- }
- } else {
- fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
- goto error;
- }
- featurestr = strtok(NULL, ",");
- }
- x86_cpu_def->features |= plus_features;
- x86_cpu_def->ext_features |= plus_ext_features;
- x86_cpu_def->ext2_features |= plus_ext2_features;
- x86_cpu_def->ext3_features |= plus_ext3_features;
- x86_cpu_def->features &= ~minus_features;
- x86_cpu_def->ext_features &= ~minus_ext_features;
- x86_cpu_def->ext2_features &= ~minus_ext2_features;
- x86_cpu_def->ext3_features &= ~minus_ext3_features;
- free(s);
- return 0;
-
-error:
- free(s);
- return -1;
-}
-
-void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
-{
- unsigned int i;
-
- for (i = 0; i < sizeof(x86_defs) / sizeof(x86_def_t); i++)
- (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
-}
-#endif /* !VBOX */
-
-static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
-{
-#ifndef VBOX
- x86_def_t def1, *def = &def1;
-
- if (cpu_x86_find_by_name(def, cpu_model) < 0)
- return -1;
- if (def->vendor1) {
- env->cpuid_vendor1 = def->vendor1;
- env->cpuid_vendor2 = def->vendor2;
- env->cpuid_vendor3 = def->vendor3;
- } else {
- env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
- env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
- env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
- }
- env->cpuid_level = def->level;
- env->cpuid_version = (def->family << 8) | (def->model << 4) | def->stepping;
- env->cpuid_features = def->features;
- env->pat = 0x0007040600070406ULL;
- env->cpuid_ext_features = def->ext_features;
- env->cpuid_ext2_features = def->ext2_features;
- env->cpuid_xlevel = def->xlevel;
- env->cpuid_ext3_features = def->ext3_features;
- {
- const char *model_id = def->model_id;
- int c, len, i;
- if (!model_id)
- model_id = "";
- len = strlen(model_id);
- for(i = 0; i < 48; i++) {
- if (i >= len)
- c = '\0';
- else
- c = (uint8_t)model_id[i];
- env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
- }
- }
-#endif // !VBOX
- return 0;
-}
-
/* NOTE: must be called outside the CPU execute loop */
void cpu_reset(CPUX86State *env)
{
int i;
+ if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+ qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+ log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
+ }
+
memset(env, 0, offsetof(CPUX86State, breakpoints));
tlb_flush(env, 1);
@@ -490,24 +77,27 @@ void cpu_reset(CPUX86State *env)
env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
- DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK | DESC_R_MASK);
+ DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
+ DESC_R_MASK | DESC_A_MASK);
cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
- DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
+ DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+ DESC_A_MASK);
cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
- DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
+ DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+ DESC_A_MASK);
cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
- DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
+ DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+ DESC_A_MASK);
cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
- DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
+ DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+ DESC_A_MASK);
cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
- DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
+ DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+ DESC_A_MASK);
env->eip = 0xfff0;
-#ifndef VBOX
+#ifndef VBOX /* We'll get the right value from CPUM. */
env->regs[R_EDX] = env->cpuid_version;
-#else
- /** @todo: is it right? */
- env->regs[R_EDX] = 0x600; /* indicate P6 processor */
#endif
env->eflags = 0x2;
@@ -518,6 +108,16 @@ void cpu_reset(CPUX86State *env)
env->fpuc = 0x37f;
env->mxcsr = 0x1f80;
+
+ memset(env->dr, 0, sizeof(env->dr));
+ env->dr[6] = DR6_FIXED_1;
+ env->dr[7] = DR7_FIXED_1;
+ cpu_breakpoint_remove_all(env, BP_CPU);
+ cpu_watchpoint_remove_all(env, BP_CPU);
+
+#ifndef VBOX
+ env->mcg_status = 0;
+#endif
}
void cpu_x86_close(CPUX86State *env)
@@ -585,6 +185,68 @@ static const char *cc_op_str[] = {
"SARQ",
};
+static void
+cpu_x86_dump_seg_cache(CPUState *env, FILE *f,
+ int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+ const char *name, struct SegmentCache *sc)
+{
+#ifdef VBOX
+# define cpu_fprintf(f, ...) RTLogPrintf(__VA_ARGS__)
+#endif
+#ifdef TARGET_X86_64
+ if (env->hflags & HF_CS64_MASK) {
+ cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
+ sc->selector, sc->base, sc->limit, sc->flags);
+ } else
+#endif
+ {
+ cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
+ (uint32_t)sc->base, sc->limit, sc->flags);
+ }
+
+ if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
+ goto done;
+
+ cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
+ if (sc->flags & DESC_S_MASK) {
+ if (sc->flags & DESC_CS_MASK) {
+ cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
+ ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
+ cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
+ (sc->flags & DESC_R_MASK) ? 'R' : '-');
+ } else {
+ cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS " : "DS16");
+ cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
+ (sc->flags & DESC_W_MASK) ? 'W' : '-');
+ }
+ cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
+ } else {
+ static const char *sys_type_name[2][16] = {
+ { /* 32 bit mode */
+ "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
+ "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
+ "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
+ "CallGate32", "Reserved", "IntGate32", "TrapGate32"
+ },
+ { /* 64 bit mode */
+ "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
+ "Reserved", "Reserved", "Reserved", "Reserved",
+ "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
+ "Reserved", "IntGate64", "TrapGate64"
+ }
+ };
+ cpu_fprintf(f, "%s",
+ sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
+ [(sc->flags & DESC_TYPE_MASK)
+ >> DESC_TYPE_SHIFT]);
+ }
+done:
+ cpu_fprintf(f, "\n");
+#ifdef VBOX
+# undef cpu_fprintf
+#endif
+}
+
void cpu_dump_state(CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags)
@@ -593,6 +255,11 @@ void cpu_dump_state(CPUState *env, FILE *f,
char cc_op_name[32];
static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
+#ifdef VBOX
+# define cpu_fprintf(f, ...) RTLogPrintf(__VA_ARGS__)
+#endif
+ cpu_synchronize_state(env);
+
eflags = env->eflags;
#ifdef TARGET_X86_64
if (env->hflags & HF_CS64_MASK) {
@@ -628,7 +295,7 @@ void cpu_dump_state(CPUState *env, FILE *f,
eflags & CC_C ? 'C' : '-',
env->hflags & HF_CPL_MASK,
(env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
- (int)(env->a20_mask >> 20) & 1,
+ (env->a20_mask >> 20) & 1,
(env->hflags >> HF_SMM_SHIFT) & 1,
env->halted);
} else
@@ -655,32 +322,20 @@ void cpu_dump_state(CPUState *env, FILE *f,
eflags & CC_C ? 'C' : '-',
env->hflags & HF_CPL_MASK,
(env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
- (int)(env->a20_mask >> 20) & 1,
+ (env->a20_mask >> 20) & 1,
(env->hflags >> HF_SMM_SHIFT) & 1,
env->halted);
}
+ for(i = 0; i < 6; i++) {
+ cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
+ &env->segs[i]);
+ }
+ cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
+ cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
+
#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) {
- for(i = 0; i < 6; i++) {
- SegmentCache *sc = &env->segs[i];
- cpu_fprintf(f, "%s =%04x %016" PRIx64 " %08x %08x\n",
- seg_name[i],
- sc->selector,
- sc->base,
- sc->limit,
- sc->flags);
- }
- cpu_fprintf(f, "LDT=%04x %016" PRIx64 " %08x %08x\n",
- env->ldt.selector,
- env->ldt.base,
- env->ldt.limit,
- env->ldt.flags);
- cpu_fprintf(f, "TR =%04x %016" PRIx64 " %08x %08x\n",
- env->tr.selector,
- env->tr.base,
- env->tr.limit,
- env->tr.flags);
cpu_fprintf(f, "GDT= %016" PRIx64 " %08x\n",
env->gdt.base, env->gdt.limit);
cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
@@ -690,28 +345,13 @@ void cpu_dump_state(CPUState *env, FILE *f,
env->cr[2],
env->cr[3],
(uint32_t)env->cr[4]);
+ for(i = 0; i < 4; i++)
+ cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
+ cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
+ env->dr[6], env->dr[7]);
} else
#endif
{
- for(i = 0; i < 6; i++) {
- SegmentCache *sc = &env->segs[i];
- cpu_fprintf(f, "%s =%04x %08x %08x %08x\n",
- seg_name[i],
- sc->selector,
- (uint32_t)sc->base,
- sc->limit,
- sc->flags);
- }
- cpu_fprintf(f, "LDT=%04x %08x %08x %08x\n",
- env->ldt.selector,
- (uint32_t)env->ldt.base,
- env->ldt.limit,
- env->ldt.flags);
- cpu_fprintf(f, "TR =%04x %08x %08x %08x\n",
- env->tr.selector,
- (uint32_t)env->tr.base,
- env->tr.limit,
- env->tr.flags);
cpu_fprintf(f, "GDT= %08x %08x\n",
(uint32_t)env->gdt.base, env->gdt.limit);
cpu_fprintf(f, "IDT= %08x %08x\n",
@@ -721,6 +361,9 @@ void cpu_dump_state(CPUState *env, FILE *f,
(uint32_t)env->cr[2],
(uint32_t)env->cr[3],
(uint32_t)env->cr[4]);
+ for(i = 0; i < 4; i++)
+ cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]);
+ cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]);
}
if (flags & X86_DUMP_CCOP) {
if ((unsigned)env->cc_op < CC_OP_NB)
@@ -740,6 +383,7 @@ void cpu_dump_state(CPUState *env, FILE *f,
cc_op_name);
}
}
+ cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
if (flags & X86_DUMP_FPU) {
int fptag;
fptag = 0;
@@ -790,6 +434,9 @@ void cpu_dump_state(CPUState *env, FILE *f,
cpu_fprintf(f, " ");
}
}
+#ifdef VBOX
+# undef cpu_fprintf
+#endif
}
/***********************************************************/
@@ -810,7 +457,7 @@ void cpu_x86_set_a20(CPUX86State *env, int a20_state)
/* when a20 is changed, all the MMU mappings are invalid, so
we must flush everything */
tlb_flush(env, 1);
- env->a20_mask = (~0x100000) | (a20_state << 20);
+ env->a20_mask = ~(1 << 20) | (a20_state << 20);
}
}
@@ -853,7 +500,6 @@ void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
/* update FPU flags */
env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
-
#ifdef VBOX
remR3ChangeCpuMode(env);
#endif
@@ -895,12 +541,6 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
#endif
}
-/* XXX: also flush 4MB pages */
-void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr)
-{
- tlb_flush_page(env, addr);
-}
-
#if defined(CONFIG_USER_ONLY)
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
@@ -915,37 +555,27 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
return 1;
}
-target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
-{
- return addr;
-}
-
#else
/* XXX: This value should match the one returned by CPUID
* and in exec.c */
-#if defined(USE_KQEMU)
-#define PHYS_ADDR_MASK 0xfffff000LL
-#else
# if defined(TARGET_X86_64)
# define PHYS_ADDR_MASK 0xfffffff000LL
# else
# define PHYS_ADDR_MASK 0xffffff000LL
# endif
-#endif
/* return value:
-1 = cannot handle fault
0 = nothing more to do
1 = generate PF fault
- 2 = soft MMU activation required for this block
*/
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
int is_write1, int mmu_idx, int is_softmmu)
{
uint64_t ptep, pte;
target_ulong pde_addr, pte_addr;
- int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
+ int error_code, is_dirty, prot, page_size, is_write, is_user;
target_phys_addr_t paddr;
uint32_t page_offset;
target_ulong vaddr, virt_addr;
@@ -1206,8 +836,8 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
paddr = (pte & TARGET_PAGE_MASK) + page_offset;
vaddr = virt_addr + page_offset;
- ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
- return ret;
+ tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
+ return 0;
do_fault_protect:
error_code = PG_ERROR_P_MASK;
do_fault:
@@ -1323,4 +953,270 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
paddr = (pte & TARGET_PAGE_MASK) + page_offset;
return paddr;
}
+
+void hw_breakpoint_insert(CPUState *env, int index)
+{
+ int type, err = 0;
+
+ switch (hw_breakpoint_type(env->dr[7], index)) {
+ case 0:
+ if (hw_breakpoint_enabled(env->dr[7], index))
+ err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
+ &env->cpu_breakpoint[index]);
+ break;
+ case 1:
+ type = BP_CPU | BP_MEM_WRITE;
+ goto insert_wp;
+ case 2:
+ /* No support for I/O watchpoints yet */
+ break;
+ case 3:
+ type = BP_CPU | BP_MEM_ACCESS;
+ insert_wp:
+ err = cpu_watchpoint_insert(env, env->dr[index],
+ hw_breakpoint_len(env->dr[7], index),
+ type, &env->cpu_watchpoint[index]);
+ break;
+ }
+ if (err)
+ env->cpu_breakpoint[index] = NULL;
+}
+
+void hw_breakpoint_remove(CPUState *env, int index)
+{
+ if (!env->cpu_breakpoint[index])
+ return;
+ switch (hw_breakpoint_type(env->dr[7], index)) {
+ case 0:
+ if (hw_breakpoint_enabled(env->dr[7], index))
+ cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
+ break;
+ case 1:
+ case 3:
+ cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
+ break;
+ case 2:
+ /* No support for I/O watchpoints yet */
+ break;
+ }
+}
+
+int check_hw_breakpoints(CPUState *env, int force_dr6_update)
+{
+ target_ulong dr6;
+ int reg, type;
+ int hit_enabled = 0;
+
+ dr6 = env->dr[6] & ~0xf;
+ for (reg = 0; reg < 4; reg++) {
+ type = hw_breakpoint_type(env->dr[7], reg);
+ if ((type == 0 && env->dr[reg] == env->eip) ||
+ ((type & 1) && env->cpu_watchpoint[reg] &&
+ (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
+ dr6 |= 1 << reg;
+ if (hw_breakpoint_enabled(env->dr[7], reg))
+ hit_enabled = 1;
+ }
+ }
+ if (hit_enabled || force_dr6_update)
+ env->dr[6] = dr6;
+ return hit_enabled;
+}
+
+static CPUDebugExcpHandler *prev_debug_excp_handler;
+
+void raise_exception_env(int exception_index, CPUState *env);
+
+static void breakpoint_handler(CPUState *env)
+{
+ CPUBreakpoint *bp;
+
+ if (env->watchpoint_hit) {
+ if (env->watchpoint_hit->flags & BP_CPU) {
+ env->watchpoint_hit = NULL;
+ if (check_hw_breakpoints(env, 0))
+ raise_exception_env(EXCP01_DB, env);
+ else
+ cpu_resume_from_signal(env, NULL);
+ }
+ } else {
+ QTAILQ_FOREACH(bp, &env->breakpoints, entry)
+ if (bp->pc == env->eip) {
+ if (bp->flags & BP_CPU) {
+ check_hw_breakpoints(env, 1);
+ raise_exception_env(EXCP01_DB, env);
+ }
+ break;
+ }
+ }
+ if (prev_debug_excp_handler)
+ prev_debug_excp_handler(env);
+}
+
+#ifndef VBOX
+/* This should come from sysemu.h - if we could include it here... */
+void qemu_system_reset_request(void);
+
+void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
+ uint64_t mcg_status, uint64_t addr, uint64_t misc)
+{
+ uint64_t mcg_cap = cenv->mcg_cap;
+ unsigned bank_num = mcg_cap & 0xff;
+ uint64_t *banks = cenv->mce_banks;
+
+ if (bank >= bank_num || !(status & MCI_STATUS_VAL))
+ return;
+
+ /*
+ * if MSR_MCG_CTL is not all 1s, the uncorrected error
+ * reporting is disabled
+ */
+ if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
+ cenv->mcg_ctl != ~(uint64_t)0)
+ return;
+ banks += 4 * bank;
+ /*
+ * if MSR_MCi_CTL is not all 1s, the uncorrected error
+ * reporting is disabled for the bank
+ */
+ if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0)
+ return;
+ if (status & MCI_STATUS_UC) {
+ if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
+ !(cenv->cr[4] & CR4_MCE_MASK)) {
+ fprintf(stderr, "injects mce exception while previous "
+ "one is in progress!\n");
+ qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
+ qemu_system_reset_request();
+ return;
+ }
+ if (banks[1] & MCI_STATUS_VAL)
+ status |= MCI_STATUS_OVER;
+ banks[2] = addr;
+ banks[3] = misc;
+ cenv->mcg_status = mcg_status;
+ banks[1] = status;
+ cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
+ } else if (!(banks[1] & MCI_STATUS_VAL)
+ || !(banks[1] & MCI_STATUS_UC)) {
+ if (banks[1] & MCI_STATUS_VAL)
+ status |= MCI_STATUS_OVER;
+ banks[2] = addr;
+ banks[3] = misc;
+ banks[1] = status;
+ } else
+ banks[1] |= MCI_STATUS_OVER;
+}
+#endif /* !VBOX */
#endif /* !CONFIG_USER_ONLY */
+
+#ifndef VBOX
+
+static void mce_init(CPUX86State *cenv)
+{
+ unsigned int bank, bank_num;
+
+ if (((cenv->cpuid_version >> 8)&0xf) >= 6
+ && (cenv->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)) {
+ cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
+ cenv->mcg_ctl = ~(uint64_t)0;
+ bank_num = MCE_BANKS_DEF;
+ for (bank = 0; bank < bank_num; bank++)
+ cenv->mce_banks[bank*4] = ~(uint64_t)0;
+ }
+}
+
+int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
+ target_ulong *base, unsigned int *limit,
+ unsigned int *flags)
+{
+ SegmentCache *dt;
+ target_ulong ptr;
+ uint32_t e1, e2;
+ int index;
+
+ if (selector & 0x4)
+ dt = &env->ldt;
+ else
+ dt = &env->gdt;
+ index = selector & ~7;
+ ptr = dt->base + index;
+ if ((index + 7) > dt->limit
+ || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
+ || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
+ return 0;
+
+ *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
+ *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
+ if (e2 & DESC_G_MASK)
+ *limit = (*limit << 12) | 0xfff;
+ *flags = e2;
+
+ return 1;
+}
+
+#endif /* !VBOX */
+
+#ifndef VBOX
+CPUX86State *cpu_x86_init(const char *cpu_model)
+#else
+CPUX86State *cpu_x86_init(CPUX86State *env, const char *cpu_model)
+#endif
+{
+#ifndef VBOX
+ CPUX86State *env;
+#endif
+ static int inited;
+
+#ifndef VBOX
+ env = qemu_mallocz(sizeof(CPUX86State));
+#endif
+ cpu_exec_init(env);
+ env->cpu_model_str = cpu_model;
+
+ /* init various static tables */
+ if (!inited) {
+ inited = 1;
+ optimize_flags_init();
+#ifndef CONFIG_USER_ONLY
+ prev_debug_excp_handler =
+ cpu_set_debug_excp_handler(breakpoint_handler);
+#endif
+ }
+#ifndef VBOX
+ if (cpu_x86_register(env, cpu_model) < 0) {
+ cpu_x86_close(env);
+ return NULL;
+ }
+ mce_init(env);
+#endif
+
+ qemu_init_vcpu(env);
+
+ return env;
+}
+
+#ifndef VBOX
+#if !defined(CONFIG_USER_ONLY)
+void do_cpu_init(CPUState *env)
+{
+ int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
+ cpu_reset(env);
+ env->interrupt_request = sipi;
+ apic_init_reset(env->apic_state);
+ env->halted = !cpu_is_bsp(env);
+}
+
+void do_cpu_sipi(CPUState *env)
+{
+ apic_sipi(env->apic_state);
+}
+#else
+void do_cpu_init(CPUState *env)
+{
+}
+void do_cpu_sipi(CPUState *env)
+{
+}
+#endif
+#endif /* !VBOX */
diff --git a/src/recompiler/target-i386/helper.h b/src/recompiler/target-i386/helper.h
index 27e58c8b4..8307304ac 100644
--- a/src/recompiler/target-i386/helper.h
+++ b/src/recompiler/target-i386/helper.h
@@ -1,262 +1,253 @@
-#ifndef DEF_HELPER
-#define DEF_HELPER(ret, name, params) ret name params;
-#endif
-
-DEF_HELPER(void, helper_lock, (void))
-DEF_HELPER(void, helper_unlock, (void))
-DEF_HELPER(void, helper_write_eflags, (target_ulong t0, uint32_t update_mask))
-DEF_HELPER(target_ulong, helper_read_eflags, (void))
-#ifdef VBOX
-DEF_HELPER(void, helper_write_eflags_vme, (target_ulong t0))
-DEF_HELPER(target_ulong, helper_read_eflags_vme, (void))
-#endif
-DEF_HELPER(void, helper_divb_AL, (target_ulong t0))
-DEF_HELPER(void, helper_idivb_AL, (target_ulong t0))
-DEF_HELPER(void, helper_divw_AX, (target_ulong t0))
-DEF_HELPER(void, helper_idivw_AX, (target_ulong t0))
-DEF_HELPER(void, helper_divl_EAX, (target_ulong t0))
-DEF_HELPER(void, helper_idivl_EAX, (target_ulong t0))
+#include "def-helper.h"
+
+DEF_HELPER_FLAGS_1(cc_compute_all, TCG_CALL_PURE, i32, int)
+DEF_HELPER_FLAGS_1(cc_compute_c, TCG_CALL_PURE, i32, int)
+
+DEF_HELPER_0(lock, void)
+DEF_HELPER_0(unlock, void)
+DEF_HELPER_2(write_eflags, void, tl, i32)
+DEF_HELPER_0(read_eflags, tl)
+DEF_HELPER_1(divb_AL, void, tl)
+DEF_HELPER_1(idivb_AL, void, tl)
+DEF_HELPER_1(divw_AX, void, tl)
+DEF_HELPER_1(idivw_AX, void, tl)
+DEF_HELPER_1(divl_EAX, void, tl)
+DEF_HELPER_1(idivl_EAX, void, tl)
#ifdef TARGET_X86_64
-DEF_HELPER(void, helper_mulq_EAX_T0, (target_ulong t0))
-DEF_HELPER(void, helper_imulq_EAX_T0, (target_ulong t0))
-DEF_HELPER(target_ulong, helper_imulq_T0_T1, (target_ulong t0, target_ulong t1))
-DEF_HELPER(void, helper_divq_EAX, (target_ulong t0))
-DEF_HELPER(void, helper_idivq_EAX, (target_ulong t0))
+DEF_HELPER_1(mulq_EAX_T0, void, tl)
+DEF_HELPER_1(imulq_EAX_T0, void, tl)
+DEF_HELPER_2(imulq_T0_T1, tl, tl, tl)
+DEF_HELPER_1(divq_EAX, void, tl)
+DEF_HELPER_1(idivq_EAX, void, tl)
#endif
-DEF_HELPER(void, helper_aam, (int base))
-DEF_HELPER(void, helper_aad, (int base))
-DEF_HELPER(void, helper_aaa, (void))
-DEF_HELPER(void, helper_aas, (void))
-DEF_HELPER(void, helper_daa, (void))
-DEF_HELPER(void, helper_das, (void))
-
-DEF_HELPER(target_ulong, helper_lsl, (target_ulong selector1))
-DEF_HELPER(target_ulong, helper_lar, (target_ulong selector1))
-DEF_HELPER(void, helper_verr, (target_ulong selector1))
-DEF_HELPER(void, helper_verw, (target_ulong selector1))
-DEF_HELPER(void, helper_lldt, (int selector))
-DEF_HELPER(void, helper_ltr, (int selector))
-DEF_HELPER(void, helper_load_seg, (int seg_reg, int selector))
-DEF_HELPER(void, helper_ljmp_protected, (int new_cs, target_ulong new_eip,
- int next_eip_addend))
-DEF_HELPER(void, helper_lcall_real, (int new_cs, target_ulong new_eip1,
- int shift, int next_eip))
-DEF_HELPER(void, helper_lcall_protected, (int new_cs, target_ulong new_eip,
- int shift, int next_eip_addend))
-DEF_HELPER(void, helper_iret_real, (int shift))
-DEF_HELPER(void, helper_iret_protected, (int shift, int next_eip))
-DEF_HELPER(void, helper_lret_protected, (int shift, int addend))
-DEF_HELPER(target_ulong, helper_read_crN, (int reg))
-DEF_HELPER(void, helper_write_crN, (int reg, target_ulong t0))
-DEF_HELPER(void, helper_lmsw, (target_ulong t0))
-DEF_HELPER(void, helper_clts, (void))
-DEF_HELPER(void, helper_movl_drN_T0, (int reg, target_ulong t0))
-DEF_HELPER(void, helper_invlpg, (target_ulong addr))
-
-DEF_HELPER(void, helper_enter_level, (int level, int data32, target_ulong t1))
+DEF_HELPER_1(aam, void, int)
+DEF_HELPER_1(aad, void, int)
+DEF_HELPER_0(aaa, void)
+DEF_HELPER_0(aas, void)
+DEF_HELPER_0(daa, void)
+DEF_HELPER_0(das, void)
+
+DEF_HELPER_1(lsl, tl, tl)
+DEF_HELPER_1(lar, tl, tl)
+DEF_HELPER_1(verr, void, tl)
+DEF_HELPER_1(verw, void, tl)
+DEF_HELPER_1(lldt, void, int)
+DEF_HELPER_1(ltr, void, int)
+DEF_HELPER_2(load_seg, void, int, int)
+DEF_HELPER_3(ljmp_protected, void, int, tl, int)
+DEF_HELPER_4(lcall_real, void, int, tl, int, int)
+DEF_HELPER_4(lcall_protected, void, int, tl, int, int)
+DEF_HELPER_1(iret_real, void, int)
+DEF_HELPER_2(iret_protected, void, int, int)
+DEF_HELPER_2(lret_protected, void, int, int)
+DEF_HELPER_1(read_crN, tl, int)
+DEF_HELPER_2(write_crN, void, int, tl)
+DEF_HELPER_1(lmsw, void, tl)
+DEF_HELPER_0(clts, void)
+DEF_HELPER_2(movl_drN_T0, void, int, tl)
+DEF_HELPER_1(invlpg, void, tl)
+
+DEF_HELPER_3(enter_level, void, int, int, tl)
#ifdef TARGET_X86_64
-DEF_HELPER(void, helper_enter64_level, (int level, int data64, target_ulong t1))
+DEF_HELPER_3(enter64_level, void, int, int, tl)
#endif
-DEF_HELPER(void, helper_sysenter, (void))
-DEF_HELPER(void, helper_sysexit, (int dflag))
+DEF_HELPER_0(sysenter, void)
+DEF_HELPER_1(sysexit, void, int)
#ifdef TARGET_X86_64
-DEF_HELPER(void, helper_syscall, (int next_eip_addend))
-DEF_HELPER(void, helper_sysret, (int dflag))
-#endif
-DEF_HELPER(void, helper_hlt, (int next_eip_addend))
-DEF_HELPER(void, helper_monitor, (target_ulong ptr))
-DEF_HELPER(void, helper_mwait, (int next_eip_addend))
-DEF_HELPER(void, helper_debug, (void))
-DEF_HELPER(void, helper_raise_interrupt, (int intno, int next_eip_addend))
-DEF_HELPER(void, helper_raise_exception, (int exception_index))
-DEF_HELPER(void, helper_cli, (void))
-DEF_HELPER(void, helper_sti, (void))
-#ifdef VBOX
-DEF_HELPER(void, helper_cli_vme, (void))
-DEF_HELPER(void, helper_sti_vme, (void))
+DEF_HELPER_1(syscall, void, int)
+DEF_HELPER_1(sysret, void, int)
#endif
-DEF_HELPER(void, helper_set_inhibit_irq, (void))
-DEF_HELPER(void, helper_reset_inhibit_irq, (void))
-DEF_HELPER(void, helper_boundw, (target_ulong a0, int v))
-DEF_HELPER(void, helper_boundl, (target_ulong a0, int v))
-DEF_HELPER(void, helper_rsm, (void))
-DEF_HELPER(void, helper_into, (int next_eip_addend))
-DEF_HELPER(void, helper_cmpxchg8b, (target_ulong a0))
+DEF_HELPER_1(hlt, void, int)
+DEF_HELPER_1(monitor, void, tl)
+DEF_HELPER_1(mwait, void, int)
+DEF_HELPER_0(debug, void)
+DEF_HELPER_0(reset_rf, void)
+DEF_HELPER_2(raise_interrupt, void, int, int)
+DEF_HELPER_1(raise_exception, void, int)
+DEF_HELPER_0(cli, void)
+DEF_HELPER_0(sti, void)
+DEF_HELPER_0(set_inhibit_irq, void)
+DEF_HELPER_0(reset_inhibit_irq, void)
+DEF_HELPER_2(boundw, void, tl, int)
+DEF_HELPER_2(boundl, void, tl, int)
+DEF_HELPER_0(rsm, void)
+DEF_HELPER_1(into, void, int)
+DEF_HELPER_1(cmpxchg8b, void, tl)
#ifdef TARGET_X86_64
-DEF_HELPER(void, helper_cmpxchg16b, (target_ulong a0))
-#endif
-DEF_HELPER(void, helper_single_step, (void))
-DEF_HELPER(void, helper_cpuid, (void))
-DEF_HELPER(void, helper_rdtsc, (void))
-DEF_HELPER(void, helper_rdpmc, (void))
-DEF_HELPER(void, helper_rdmsr, (void))
-DEF_HELPER(void, helper_wrmsr, (void))
-#ifdef VBOX
-DEF_HELPER(void, helper_rdtscp, (void))
+DEF_HELPER_1(cmpxchg16b, void, tl)
#endif
-
-DEF_HELPER(void, helper_check_iob, (uint32_t t0))
-DEF_HELPER(void, helper_check_iow, (uint32_t t0))
-DEF_HELPER(void, helper_check_iol, (uint32_t t0))
-#ifdef VBOX
-DEF_HELPER(void, helper_check_external_event, (void))
-DEF_HELPER(void, helper_dump_state, (void))
-DEF_HELPER(void, helper_sync_seg, (uint32_t t0))
-#endif
-DEF_HELPER(void, helper_outb, (uint32_t port, uint32_t data))
-DEF_HELPER(target_ulong, helper_inb, (uint32_t port))
-DEF_HELPER(void, helper_outw, (uint32_t port, uint32_t data))
-DEF_HELPER(target_ulong, helper_inw, (uint32_t port))
-DEF_HELPER(void, helper_outl, (uint32_t port, uint32_t data))
-DEF_HELPER(target_ulong, helper_inl, (uint32_t port))
-
-DEF_HELPER(void, helper_svm_check_intercept_param, (uint32_t type, uint64_t param))
-DEF_HELPER(void, helper_vmexit, (uint32_t exit_code, uint64_t exit_info_1))
-DEF_HELPER(void, helper_svm_check_io, (uint32_t port, uint32_t param,
- uint32_t next_eip_addend))
-DEF_HELPER(void, helper_vmrun, (int aflag, int next_eip_addend))
-DEF_HELPER(void, helper_vmmcall, (void))
-DEF_HELPER(void, helper_vmload, (int aflag))
-DEF_HELPER(void, helper_vmsave, (int aflag))
-DEF_HELPER(void, helper_stgi, (void))
-DEF_HELPER(void, helper_clgi, (void))
-DEF_HELPER(void, helper_skinit, (void))
-DEF_HELPER(void, helper_invlpga, (int aflag))
+DEF_HELPER_0(single_step, void)
+DEF_HELPER_0(cpuid, void)
+DEF_HELPER_0(rdtsc, void)
+DEF_HELPER_0(rdtscp, void)
+DEF_HELPER_0(rdpmc, void)
+DEF_HELPER_0(rdmsr, void)
+DEF_HELPER_0(wrmsr, void)
+
+DEF_HELPER_1(check_iob, void, i32)
+DEF_HELPER_1(check_iow, void, i32)
+DEF_HELPER_1(check_iol, void, i32)
+DEF_HELPER_2(outb, void, i32, i32)
+DEF_HELPER_1(inb, tl, i32)
+DEF_HELPER_2(outw, void, i32, i32)
+DEF_HELPER_1(inw, tl, i32)
+DEF_HELPER_2(outl, void, i32, i32)
+DEF_HELPER_1(inl, tl, i32)
+
+DEF_HELPER_2(svm_check_intercept_param, void, i32, i64)
+DEF_HELPER_2(vmexit, void, i32, i64)
+DEF_HELPER_3(svm_check_io, void, i32, i32, i32)
+DEF_HELPER_2(vmrun, void, int, int)
+DEF_HELPER_0(vmmcall, void)
+DEF_HELPER_1(vmload, void, int)
+DEF_HELPER_1(vmsave, void, int)
+DEF_HELPER_0(stgi, void)
+DEF_HELPER_0(clgi, void)
+DEF_HELPER_0(skinit, void)
+DEF_HELPER_1(invlpga, void, int)
/* x86 FPU */
-DEF_HELPER(void, helper_flds_FT0, (uint32_t val))
-DEF_HELPER(void, helper_fldl_FT0, (uint64_t val))
-DEF_HELPER(void, helper_fildl_FT0, (int32_t val))
-DEF_HELPER(void, helper_flds_ST0, (uint32_t val))
-DEF_HELPER(void, helper_fldl_ST0, (uint64_t val))
-DEF_HELPER(void, helper_fildl_ST0, (int32_t val))
-DEF_HELPER(void, helper_fildll_ST0, (int64_t val))
+DEF_HELPER_1(flds_FT0, void, i32)
+DEF_HELPER_1(fldl_FT0, void, i64)
+DEF_HELPER_1(fildl_FT0, void, s32)
+DEF_HELPER_1(flds_ST0, void, i32)
+DEF_HELPER_1(fldl_ST0, void, i64)
+DEF_HELPER_1(fildl_ST0, void, s32)
+DEF_HELPER_1(fildll_ST0, void, s64)
#ifndef VBOX
-DEF_HELPER(uint32_t, helper_fsts_ST0, (void))
-DEF_HELPER(uint64_t, helper_fstl_ST0, (void))
-DEF_HELPER(int32_t, helper_fist_ST0, (void))
-DEF_HELPER(int32_t, helper_fistl_ST0, (void))
-DEF_HELPER(int64_t, helper_fistll_ST0, (void))
-DEF_HELPER(int32_t, helper_fistt_ST0, (void))
-DEF_HELPER(int32_t, helper_fisttl_ST0, (void))
-DEF_HELPER(int64_t, helper_fisttll_ST0, (void))
-#else
-DEF_HELPER(RTCCUINTREG, helper_fsts_ST0, (void))
-DEF_HELPER(uint64_t, helper_fstl_ST0, (void))
-DEF_HELPER(RTCCINTREG, helper_fist_ST0, (void))
-DEF_HELPER(RTCCINTREG, helper_fistl_ST0, (void))
-DEF_HELPER(int64_t, helper_fistll_ST0, (void))
-DEF_HELPER(RTCCINTREG, helper_fistt_ST0, (void))
-DEF_HELPER(RTCCINTREG, helper_fisttl_ST0, (void))
-DEF_HELPER(int64_t, helper_fisttll_ST0, (void))
-#endif
-DEF_HELPER(void, helper_fldt_ST0, (target_ulong ptr))
-DEF_HELPER(void, helper_fstt_ST0, (target_ulong ptr))
-DEF_HELPER(void, helper_fpush, (void))
-DEF_HELPER(void, helper_fpop, (void))
-DEF_HELPER(void, helper_fdecstp, (void))
-DEF_HELPER(void, helper_fincstp, (void))
-DEF_HELPER(void, helper_ffree_STN, (int st_index))
-DEF_HELPER(void, helper_fmov_ST0_FT0, (void))
-DEF_HELPER(void, helper_fmov_FT0_STN, (int st_index))
-DEF_HELPER(void, helper_fmov_ST0_STN, (int st_index))
-DEF_HELPER(void, helper_fmov_STN_ST0, (int st_index))
-DEF_HELPER(void, helper_fxchg_ST0_STN, (int st_index))
-DEF_HELPER(void, helper_fcom_ST0_FT0, (void))
-DEF_HELPER(void, helper_fucom_ST0_FT0, (void))
-DEF_HELPER(void, helper_fcomi_ST0_FT0, (void))
-DEF_HELPER(void, helper_fucomi_ST0_FT0, (void))
-DEF_HELPER(void, helper_fadd_ST0_FT0, (void))
-DEF_HELPER(void, helper_fmul_ST0_FT0, (void))
-DEF_HELPER(void, helper_fsub_ST0_FT0, (void))
-DEF_HELPER(void, helper_fsubr_ST0_FT0, (void))
-DEF_HELPER(void, helper_fdiv_ST0_FT0, (void))
-DEF_HELPER(void, helper_fdivr_ST0_FT0, (void))
-DEF_HELPER(void, helper_fadd_STN_ST0, (int st_index))
-DEF_HELPER(void, helper_fmul_STN_ST0, (int st_index))
-DEF_HELPER(void, helper_fsub_STN_ST0, (int st_index))
-DEF_HELPER(void, helper_fsubr_STN_ST0, (int st_index))
-DEF_HELPER(void, helper_fdiv_STN_ST0, (int st_index))
-DEF_HELPER(void, helper_fdivr_STN_ST0, (int st_index))
-DEF_HELPER(void, helper_fchs_ST0, (void))
-DEF_HELPER(void, helper_fabs_ST0, (void))
-DEF_HELPER(void, helper_fxam_ST0, (void))
-DEF_HELPER(void, helper_fld1_ST0, (void))
-DEF_HELPER(void, helper_fldl2t_ST0, (void))
-DEF_HELPER(void, helper_fldl2e_ST0, (void))
-DEF_HELPER(void, helper_fldpi_ST0, (void))
-DEF_HELPER(void, helper_fldlg2_ST0, (void))
-DEF_HELPER(void, helper_fldln2_ST0, (void))
-DEF_HELPER(void, helper_fldz_ST0, (void))
-DEF_HELPER(void, helper_fldz_FT0, (void))
+DEF_HELPER_0(fsts_ST0, i32)
+DEF_HELPER_0(fstl_ST0, i64)
+DEF_HELPER_0(fist_ST0, s32)
+DEF_HELPER_0(fistl_ST0, s32)
+DEF_HELPER_0(fistll_ST0, s64)
+DEF_HELPER_0(fistt_ST0, s32)
+DEF_HELPER_0(fisttl_ST0, s32)
+DEF_HELPER_0(fisttll_ST0, s64)
+#else /* VBOX */
+DEF_HELPER_0(fsts_ST0, RTCCUINTREG)
+DEF_HELPER_0(fstl_ST0, i64)
+DEF_HELPER_0(fist_ST0, RTCCINTREG)
+DEF_HELPER_0(fistl_ST0, RTCCINTREG)
+DEF_HELPER_0(fistll_ST0, s64)
+DEF_HELPER_0(fistt_ST0, RTCCINTREG)
+DEF_HELPER_0(fisttl_ST0, RTCCINTREG)
+DEF_HELPER_0(fisttll_ST0, s64)
+#endif /* VBOX */
+DEF_HELPER_1(fldt_ST0, void, tl)
+DEF_HELPER_1(fstt_ST0, void, tl)
+DEF_HELPER_0(fpush, void)
+DEF_HELPER_0(fpop, void)
+DEF_HELPER_0(fdecstp, void)
+DEF_HELPER_0(fincstp, void)
+DEF_HELPER_1(ffree_STN, void, int)
+DEF_HELPER_0(fmov_ST0_FT0, void)
+DEF_HELPER_1(fmov_FT0_STN, void, int)
+DEF_HELPER_1(fmov_ST0_STN, void, int)
+DEF_HELPER_1(fmov_STN_ST0, void, int)
+DEF_HELPER_1(fxchg_ST0_STN, void, int)
+DEF_HELPER_0(fcom_ST0_FT0, void)
+DEF_HELPER_0(fucom_ST0_FT0, void)
+DEF_HELPER_0(fcomi_ST0_FT0, void)
+DEF_HELPER_0(fucomi_ST0_FT0, void)
+DEF_HELPER_0(fadd_ST0_FT0, void)
+DEF_HELPER_0(fmul_ST0_FT0, void)
+DEF_HELPER_0(fsub_ST0_FT0, void)
+DEF_HELPER_0(fsubr_ST0_FT0, void)
+DEF_HELPER_0(fdiv_ST0_FT0, void)
+DEF_HELPER_0(fdivr_ST0_FT0, void)
+DEF_HELPER_1(fadd_STN_ST0, void, int)
+DEF_HELPER_1(fmul_STN_ST0, void, int)
+DEF_HELPER_1(fsub_STN_ST0, void, int)
+DEF_HELPER_1(fsubr_STN_ST0, void, int)
+DEF_HELPER_1(fdiv_STN_ST0, void, int)
+DEF_HELPER_1(fdivr_STN_ST0, void, int)
+DEF_HELPER_0(fchs_ST0, void)
+DEF_HELPER_0(fabs_ST0, void)
+DEF_HELPER_0(fxam_ST0, void)
+DEF_HELPER_0(fld1_ST0, void)
+DEF_HELPER_0(fldl2t_ST0, void)
+DEF_HELPER_0(fldl2e_ST0, void)
+DEF_HELPER_0(fldpi_ST0, void)
+DEF_HELPER_0(fldlg2_ST0, void)
+DEF_HELPER_0(fldln2_ST0, void)
+DEF_HELPER_0(fldz_ST0, void)
+DEF_HELPER_0(fldz_FT0, void)
#ifndef VBOX
-DEF_HELPER(uint32_t, helper_fnstsw, (void))
-DEF_HELPER(uint32_t, helper_fnstcw, (void))
-#else
-DEF_HELPER(RTCCUINTREG, helper_fnstsw, (void))
-DEF_HELPER(RTCCUINTREG, helper_fnstcw, (void))
-#endif
-DEF_HELPER(void, helper_fldcw, (uint32_t val))
-DEF_HELPER(void, helper_fclex, (void))
-DEF_HELPER(void, helper_fwait, (void))
-DEF_HELPER(void, helper_fninit, (void))
-DEF_HELPER(void, helper_fbld_ST0, (target_ulong ptr))
-DEF_HELPER(void, helper_fbst_ST0, (target_ulong ptr))
-DEF_HELPER(void, helper_f2xm1, (void))
-DEF_HELPER(void, helper_fyl2x, (void))
-DEF_HELPER(void, helper_fptan, (void))
-DEF_HELPER(void, helper_fpatan, (void))
-DEF_HELPER(void, helper_fxtract, (void))
-DEF_HELPER(void, helper_fprem1, (void))
-DEF_HELPER(void, helper_fprem, (void))
-DEF_HELPER(void, helper_fyl2xp1, (void))
-DEF_HELPER(void, helper_fsqrt, (void))
-DEF_HELPER(void, helper_fsincos, (void))
-DEF_HELPER(void, helper_frndint, (void))
-DEF_HELPER(void, helper_fscale, (void))
-DEF_HELPER(void, helper_fsin, (void))
-DEF_HELPER(void, helper_fcos, (void))
-DEF_HELPER(void, helper_fstenv, (target_ulong ptr, int data32))
-DEF_HELPER(void, helper_fldenv, (target_ulong ptr, int data32))
-DEF_HELPER(void, helper_fsave, (target_ulong ptr, int data32))
-DEF_HELPER(void, helper_frstor, (target_ulong ptr, int data32))
-DEF_HELPER(void, helper_fxsave, (target_ulong ptr, int data64))
-DEF_HELPER(void, helper_fxrstor, (target_ulong ptr, int data64))
-DEF_HELPER(target_ulong, helper_bsf, (target_ulong t0))
-DEF_HELPER(target_ulong, helper_bsr, (target_ulong t0))
+DEF_HELPER_0(fnstsw, i32)
+DEF_HELPER_0(fnstcw, i32)
+#else /* VBOX */
+DEF_HELPER_0(fnstsw, RTCCUINTREG)
+DEF_HELPER_0(fnstcw, RTCCUINTREG)
+#endif /* VBOX */
+DEF_HELPER_1(fldcw, void, i32)
+DEF_HELPER_0(fclex, void)
+DEF_HELPER_0(fwait, void)
+DEF_HELPER_0(fninit, void)
+DEF_HELPER_1(fbld_ST0, void, tl)
+DEF_HELPER_1(fbst_ST0, void, tl)
+DEF_HELPER_0(f2xm1, void)
+DEF_HELPER_0(fyl2x, void)
+DEF_HELPER_0(fptan, void)
+DEF_HELPER_0(fpatan, void)
+DEF_HELPER_0(fxtract, void)
+DEF_HELPER_0(fprem1, void)
+DEF_HELPER_0(fprem, void)
+DEF_HELPER_0(fyl2xp1, void)
+DEF_HELPER_0(fsqrt, void)
+DEF_HELPER_0(fsincos, void)
+DEF_HELPER_0(frndint, void)
+DEF_HELPER_0(fscale, void)
+DEF_HELPER_0(fsin, void)
+DEF_HELPER_0(fcos, void)
+DEF_HELPER_2(fstenv, void, tl, int)
+DEF_HELPER_2(fldenv, void, tl, int)
+DEF_HELPER_2(fsave, void, tl, int)
+DEF_HELPER_2(frstor, void, tl, int)
+DEF_HELPER_2(fxsave, void, tl, int)
+DEF_HELPER_2(fxrstor, void, tl, int)
+DEF_HELPER_1(bsf, tl, tl)
+DEF_HELPER_1(bsr, tl, tl)
+DEF_HELPER_2(lzcnt, tl, tl, int)
/* MMX/SSE */
-DEF_HELPER(void, helper_enter_mmx, (void))
-DEF_HELPER(void, helper_emms, (void))
-DEF_HELPER(void, helper_movq, (uint64_t *d, uint64_t *s))
+DEF_HELPER_0(enter_mmx, void)
+DEF_HELPER_0(emms, void)
+DEF_HELPER_2(movq, void, ptr, ptr)
#define SHIFT 0
#include "ops_sse_header.h"
#define SHIFT 1
#include "ops_sse_header.h"
-DEF_HELPER(target_ulong, helper_rclb, (target_ulong t0, target_ulong t1))
-DEF_HELPER(target_ulong, helper_rclw, (target_ulong t0, target_ulong t1))
-DEF_HELPER(target_ulong, helper_rcll, (target_ulong t0, target_ulong t1))
-DEF_HELPER(target_ulong, helper_rcrb, (target_ulong t0, target_ulong t1))
-DEF_HELPER(target_ulong, helper_rcrw, (target_ulong t0, target_ulong t1))
-DEF_HELPER(target_ulong, helper_rcrl, (target_ulong t0, target_ulong t1))
+DEF_HELPER_2(rclb, tl, tl, tl)
+DEF_HELPER_2(rclw, tl, tl, tl)
+DEF_HELPER_2(rcll, tl, tl, tl)
+DEF_HELPER_2(rcrb, tl, tl, tl)
+DEF_HELPER_2(rcrw, tl, tl, tl)
+DEF_HELPER_2(rcrl, tl, tl, tl)
#ifdef TARGET_X86_64
-DEF_HELPER(target_ulong, helper_rclq, (target_ulong t0, target_ulong t1))
-DEF_HELPER(target_ulong, helper_rcrq, (target_ulong t0, target_ulong t1))
+DEF_HELPER_2(rclq, tl, tl, tl)
+DEF_HELPER_2(rcrq, tl, tl, tl)
#endif
#ifdef VBOX
+DEF_HELPER_1(write_eflags_vme, void, tl)
+DEF_HELPER_0(read_eflags_vme, tl)
+DEF_HELPER_0(cli_vme, void)
+DEF_HELPER_0(sti_vme, void)
+DEF_HELPER_0(check_external_event, void)
+DEF_HELPER_0(dump_state, void)
+DEF_HELPER_1(sync_seg, void, i32)
+
void helper_external_event(void);
void helper_record_call(void);
/* in op_helper.c */
void sync_seg(CPUX86State *env1, int seg_reg, int selector);
void sync_ldtr(CPUX86State *env1, int selector);
+#endif /* VBOX */
-#endif
-
-#undef DEF_HELPER
+#include "def-helper.h"
diff --git a/src/recompiler/target-i386/helper_template.h b/src/recompiler/target-i386/helper_template.h
index 2b1a33781..193b32740 100644
--- a/src/recompiler/target-i386/helper_template.h
+++ b/src/recompiler/target-i386/helper_template.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -290,7 +289,7 @@ target_ulong glue(helper_rcl, SUFFIX)(target_ulong t0, target_ulong t1)
count = rclb_table[count];
#endif
if (count) {
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
t0 &= DATA_MASK;
src = t0;
res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
@@ -319,7 +318,7 @@ target_ulong glue(helper_rcr, SUFFIX)(target_ulong t0, target_ulong t1)
count = rclb_table[count];
#endif
if (count) {
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
t0 &= DATA_MASK;
src = t0;
res = (t0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
diff --git a/src/recompiler/target-i386/op_helper.c b/src/recompiler/target-i386/op_helper.c
index 67ff06a22..ea0e7f6cf 100644
--- a/src/recompiler/target-i386/op_helper.c
+++ b/src/recompiler/target-i386/op_helper.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -27,27 +26,39 @@
* of the LGPL is applied is otherwise unspecified.
*/
-#define CPU_NO_GLOBAL_REGS
#include "exec.h"
+#include "exec-all.h"
#include "host-utils.h"
+#include "ioport.h"
#ifdef VBOX
-#include "qemu-common.h"
-#include <math.h>
-#include "tcg.h"
-#endif
+# include "qemu-common.h"
+# include <math.h>
+# include "tcg.h"
+#endif /* VBOX */
+
//#define DEBUG_PCALL
+
+#ifdef DEBUG_PCALL
+# define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__)
+# define LOG_PCALL_STATE(env) \
+ log_cpu_state_mask(CPU_LOG_PCALL, (env), X86_DUMP_CCOP)
+#else
+# define LOG_PCALL(...) do { } while (0)
+# define LOG_PCALL_STATE(env) do { } while (0)
+#endif
+
+
#if 0
#define raise_exception_err(a, b)\
do {\
- if (logfile)\
- fprintf(logfile, "raise_exception line=%d\n", __LINE__);\
+ qemu_log("raise_exception line=%d\n", __LINE__);\
(raise_exception_err)(a, b);\
} while (0)
#endif
-const uint8_t parity_table[256] = {
+static const uint8_t parity_table[256] = {
CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
@@ -83,7 +94,7 @@ const uint8_t parity_table[256] = {
};
/* modulo 17 table */
-const uint8_t rclw_table[32] = {
+static const uint8_t rclw_table[32] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 9,10,11,12,13,14,15,
16, 0, 1, 2, 3, 4, 5, 6,
@@ -91,14 +102,14 @@ const uint8_t rclw_table[32] = {
};
/* modulo 9 table */
-const uint8_t rclb_table[32] = {
+static const uint8_t rclb_table[32] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 0, 1, 2, 3, 4, 5, 6,
7, 8, 0, 1, 2, 3, 4, 5,
6, 7, 8, 0, 1, 2, 3, 4,
};
-const CPU86_LDouble f15rk[7] =
+static const CPU86_LDouble f15rk[7] =
{
0.00000000000000000000L,
1.00000000000000000000L,
@@ -111,7 +122,7 @@ const CPU86_LDouble f15rk[7] =
/* broken thread support */
-spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
void helper_lock(void)
{
@@ -131,13 +142,14 @@ void helper_write_eflags(target_ulong t0, uint32_t update_mask)
target_ulong helper_read_eflags(void)
{
uint32_t eflags;
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
eflags |= (DF & DF_MASK);
eflags |= env->eflags & ~(VM_MASK | RF_MASK);
return eflags;
}
#ifdef VBOX
+
void helper_write_eflags_vme(target_ulong t0)
{
unsigned int new_eflags = t0;
@@ -164,7 +176,7 @@ void helper_write_eflags_vme(target_ulong t0)
target_ulong helper_read_eflags_vme(void)
{
uint32_t eflags;
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
eflags |= (DF & DF_MASK);
eflags |= env->eflags & ~(VM_MASK | RF_MASK);
if (env->eflags & VIF_MASK)
@@ -189,14 +201,11 @@ void helper_dump_state()
(uint32_t)env->regs[R_ESP], (uint32_t)env->regs[R_EBP],
(uint32_t)env->regs[R_ESI], (uint32_t)env->regs[R_EDI]));
}
-#endif
+
+#endif /* VBOX */
/* return non zero if error */
-#ifndef VBOX
static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
-#else /* VBOX */
-DECLINLINE(int) load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
-#endif /* VBOX */
int selector)
{
SegmentCache *dt;
@@ -210,7 +219,7 @@ DECLINLINE(int) load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
Log(("RPL 1 -> sel %04X -> %04X\n", selector, selector & 0xfffc));
selector = selector & 0xfffc;
}
-#endif
+#endif /* VBOX */
if (selector & 0x4)
dt = &env->ldt;
@@ -225,11 +234,7 @@ DECLINLINE(int) load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
return 0;
}
-#ifndef VBOX
static inline unsigned int get_seg_limit(uint32_t e1, uint32_t e2)
-#else /* VBOX */
-DECLINLINE(unsigned int) get_seg_limit(uint32_t e1, uint32_t e2)
-#endif /* VBOX */
{
unsigned int limit;
limit = (e1 & 0xffff) | (e2 & 0x000f0000);
@@ -238,20 +243,12 @@ DECLINLINE(unsigned int) get_seg_limit(uint32_t e1, uint32_t e2)
return limit;
}
-#ifndef VBOX
static inline uint32_t get_seg_base(uint32_t e1, uint32_t e2)
-#else /* VBOX */
-DECLINLINE(uint32_t) get_seg_base(uint32_t e1, uint32_t e2)
-#endif /* VBOX */
{
return ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
}
-#ifndef VBOX
static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, uint32_t e2)
-#else /* VBOX */
-DECLINLINE(void) load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, uint32_t e2)
-#endif /* VBOX */
{
sc->base = get_seg_base(e1, e2);
sc->limit = get_seg_limit(e1, e2);
@@ -259,11 +256,7 @@ DECLINLINE(void) load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, uint32_t e
}
/* init the segment cache in vm86 mode. */
-#ifndef VBOX
static inline void load_seg_vm(int seg, int selector)
-#else /* VBOX */
-DECLINLINE(void) load_seg_vm(int seg, int selector)
-#endif /* VBOX */
{
selector &= 0xffff;
#ifdef VBOX
@@ -273,17 +266,13 @@ DECLINLINE(void) load_seg_vm(int seg, int selector)
cpu_x86_load_seg_cache(env, seg, selector,
(selector << 4), 0xffff, flags);
-#else
+#else /* VBOX */
cpu_x86_load_seg_cache(env, seg, selector,
(selector << 4), 0xffff, 0);
-#endif
+#endif /* VBOX */
}
-#ifndef VBOX
static inline void get_ss_esp_from_tss(uint32_t *ss_ptr,
-#else /* VBOX */
-DECLINLINE(void) get_ss_esp_from_tss(uint32_t *ss_ptr,
-#endif /* VBOX */
uint32_t *esp_ptr, int dpl)
{
#ifndef VBOX
@@ -329,7 +318,7 @@ static void tss_load_seg(int seg_reg, int selector)
int rpl, dpl, cpl;
#ifdef VBOX
- e1 = e2 = 0;
+ e1 = e2 = 0; /* gcc warning? */
cpl = env->hflags & HF_CPL_MASK;
/* Trying to load a selector with CPL=1? */
if (cpl == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0))
@@ -337,7 +326,7 @@ static void tss_load_seg(int seg_reg, int selector)
Log(("RPL 1 -> sel %04X -> %04X\n", selector, selector & 0xfffc));
selector = selector & 0xfffc;
}
-#endif
+#endif /* VBOX */
if ((selector & 0xfffc) != 0) {
if (load_segment(&e1, &e2, selector) != 0)
@@ -381,12 +370,11 @@ static void tss_load_seg(int seg_reg, int selector)
if (seg_reg == R_SS || seg_reg == R_CS)
raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
#ifdef VBOX
-#if 0
- /** @todo: now we ignore loading 0 selectors, need to check what is correct once */
+# if 0 /** @todo now we ignore loading 0 selectors, need to check what is correct once */
cpu_x86_load_seg_cache(env, seg_reg, selector,
0, 0, 0);
-#endif
-#endif
+# endif
+#endif /* VBOX */
}
}
@@ -413,14 +401,7 @@ static void switch_tss(int tss_selector,
target_ulong ptr;
type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
-#ifdef DEBUG_PCALL
- if (loglevel & CPU_LOG_PCALL)
- fprintf(logfile, "switch_tss: sel=0x%04x type=%d src=%d\n", tss_selector, type, source);
-#endif
-
-#if defined(VBOX) && defined(DEBUG)
- printf("switch_tss %x %x %x %d %08x\n", tss_selector, e1, e2, source, next_eip);
-#endif
+ LOG_PCALL("switch_tss: sel=0x%04x type=%d src=%d\n", tss_selector, type, source);
/* if task gate, we read the TSS segment and we load it */
if (type == 5) {
@@ -649,20 +630,29 @@ static void switch_tss(int tss_selector,
/* XXX: different exception if CALL ? */
raise_exception_err(EXCP0D_GPF, 0);
}
+
+#ifndef CONFIG_USER_ONLY
+ /* reset local breakpoints */
+ if (env->dr[7] & 0x55) {
+ for (i = 0; i < 4; i++) {
+ if (hw_breakpoint_enabled(env->dr[7], i) == 0x1)
+ hw_breakpoint_remove(env, i);
+ }
+ env->dr[7] &= ~0x55;
+ }
+#endif
}
/* check if Port I/O is allowed in TSS */
-#ifndef VBOX
static inline void check_io(int addr, int size)
{
+#ifndef VBOX
int io_offset, val, mask;
-
-#else /* VBOX */
-DECLINLINE(void) check_io(int addr, int size)
-{
+#else
int val, mask;
unsigned int io_offset;
#endif /* VBOX */
+
/* TSS must be a valid 32 bit one */
if (!(env->tr.flags & DESC_P_MASK) ||
((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 ||
@@ -684,10 +674,12 @@ DECLINLINE(void) check_io(int addr, int size)
}
#ifdef VBOX
+
/* Keep in sync with gen_check_external_event() */
void helper_check_external_event()
{
- if ( (env->interrupt_request & ( CPU_INTERRUPT_EXTERNAL_EXIT
+ if ( (env->interrupt_request & ( CPU_INTERRUPT_EXTERNAL_FLUSH_TLB
+ | CPU_INTERRUPT_EXTERNAL_EXIT
| CPU_INTERRUPT_EXTERNAL_TIMER
| CPU_INTERRUPT_EXTERNAL_DMA))
|| ( (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_HARD)
@@ -704,7 +696,8 @@ void helper_sync_seg(uint32_t reg)
if (env->segs[reg].newselector)
sync_seg(env, reg, env->segs[reg].newselector);
}
-#endif
+
+#endif /* VBOX */
void helper_check_iob(uint32_t t0)
{
@@ -723,39 +716,59 @@ void helper_check_iol(uint32_t t0)
void helper_outb(uint32_t port, uint32_t data)
{
+#ifndef VBOX
+ cpu_outb(port, data & 0xff);
+#else
cpu_outb(env, port, data & 0xff);
+#endif
}
target_ulong helper_inb(uint32_t port)
{
+#ifndef VBOX
+ return cpu_inb(port);
+#else
return cpu_inb(env, port);
+#endif
}
void helper_outw(uint32_t port, uint32_t data)
{
+#ifndef VBOX
+ cpu_outw(port, data & 0xffff);
+#else
cpu_outw(env, port, data & 0xffff);
+#endif
}
target_ulong helper_inw(uint32_t port)
{
+#ifndef VBOX
+ return cpu_inw(port);
+#else
return cpu_inw(env, port);
+#endif
}
void helper_outl(uint32_t port, uint32_t data)
{
+#ifndef VBOX
+ cpu_outl(port, data);
+#else
cpu_outl(env, port, data);
+#endif
}
target_ulong helper_inl(uint32_t port)
{
+#ifndef VBOX
+ return cpu_inl(port);
+#else
return cpu_inl(env, port);
+#endif
}
-#ifndef VBOX
static inline unsigned int get_sp_mask(unsigned int e2)
-#else /* VBOX */
-DECLINLINE(unsigned int) get_sp_mask(unsigned int e2)
-#endif /* VBOX */
{
if (e2 & DESC_B_MASK)
return 0xffffffff;
@@ -763,6 +776,21 @@ DECLINLINE(unsigned int) get_sp_mask(unsigned int e2)
return 0xffff;
}
+static int exeption_has_error_code(int intno)
+{
+ switch(intno) {
+ case 8:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 17:
+ return 1;
+ }
+ return 0;
+}
+
#ifdef TARGET_X86_64
#define SET_ESP(val, sp_mask)\
do {\
@@ -814,29 +842,17 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
target_ulong ptr, ssp;
int type, dpl, selector, ss_dpl, cpl;
int has_error_code, new_stack, shift;
- uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2;
+ uint32_t e1, e2, offset, ss = 0, esp, ss_e1 = 0, ss_e2 = 0;
uint32_t old_eip, sp_mask;
#ifdef VBOX
- ss = ss_e1 = ss_e2 = 0;
if (remR3NotifyTrap(env, intno, error_code, next_eip) != VINF_SUCCESS)
cpu_loop_exit();
#endif
has_error_code = 0;
- if (!is_int && !is_hw) {
- switch(intno) {
- case 8:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 17:
- has_error_code = 1;
- break;
- }
- }
+ if (!is_int && !is_hw)
+ has_error_code = exeption_has_error_code(intno);
if (is_int)
old_eip = next_eip;
else
@@ -1029,13 +1045,14 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
#else
/*
- * We must clear VIP/VIF too on interrupt entry, as otherwise FreeBSD
- * gets confused by seemingly changed EFLAGS. See #3491 and
- * public bug #2341.
- */
+ * We must clear VIP/VIF too on interrupt entry, as otherwise FreeBSD
+ * gets confused by seemingly changed EFLAGS. See #3491 and
+ * public bug #2341.
+ */
env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK | VIF_MASK | VIP_MASK);
#endif
}
+
#ifdef VBOX
/* check if VME interrupt redirection is enabled in TSS */
@@ -1133,6 +1150,7 @@ static void do_soft_interrupt_vme(int intno, int error_code, unsigned int next_e
else
env->eflags &= ~IF_MASK;
}
+
#endif /* VBOX */
#ifdef TARGET_X86_64
@@ -1149,11 +1167,7 @@ static void do_soft_interrupt_vme(int intno, int error_code, unsigned int next_e
sp += 8;\
}
-#ifndef VBOX
static inline target_ulong get_rsp_from_tss(int level)
-#else /* VBOX */
-DECLINLINE(target_ulong) get_rsp_from_tss(int level)
-#endif /* VBOX */
{
int index;
@@ -1187,19 +1201,8 @@ static void do_interrupt64(int intno, int is_int, int error_code,
#endif
has_error_code = 0;
- if (!is_int && !is_hw) {
- switch(intno) {
- case 8:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 17:
- has_error_code = 1;
- break;
- }
- }
+ if (!is_int && !is_hw)
+ has_error_code = exeption_has_error_code(intno);
if (is_int)
old_eip = next_eip;
else
@@ -1300,20 +1303,20 @@ static void do_interrupt64(int intno, int is_int, int error_code,
if ((type & 1) == 0) {
env->eflags &= ~IF_MASK;
}
-
#ifndef VBOX
env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
-#else
+#else /* VBOX */
/*
* We must clear VIP/VIF too on interrupt entry, as otherwise FreeBSD
* gets confused by seemingly changed EFLAGS. See #3491 and
* public bug #2341.
*/
env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK | VIF_MASK | VIP_MASK);
-#endif
+#endif /* VBOX */
}
#endif
+#ifdef TARGET_X86_64
#if defined(CONFIG_USER_ONLY)
void helper_syscall(int next_eip_addend)
{
@@ -1330,7 +1333,6 @@ void helper_syscall(int next_eip_addend)
raise_exception_err(EXCP06_ILLOP, 0);
}
selector = (env->star >> 32) & 0xffff;
-#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) {
int code64;
@@ -1356,9 +1358,7 @@ void helper_syscall(int next_eip_addend)
env->eip = env->lstar;
else
env->eip = env->cstar;
- } else
-#endif
- {
+ } else {
ECX = (uint32_t)(env->eip + next_eip_addend);
cpu_x86_set_cpl(env, 0);
@@ -1377,7 +1377,9 @@ void helper_syscall(int next_eip_addend)
}
}
#endif
+#endif
+#ifdef TARGET_X86_64
void helper_sysret(int dflag)
{
int cpl, selector;
@@ -1390,7 +1392,6 @@ void helper_sysret(int dflag)
raise_exception_err(EXCP0D_GPF, 0);
}
selector = (env->star >> 48) & 0xffff;
-#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) {
if (dflag == 2) {
cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
@@ -1416,9 +1417,7 @@ void helper_sysret(int dflag)
load_eflags((uint32_t)(env->regs[11]), TF_MASK | AC_MASK | ID_MASK |
IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK);
cpu_x86_set_cpl(env, 3);
- } else
-#endif
- {
+ } else {
cpu_x86_load_seg_cache(env, R_CS, selector | 3,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
@@ -1433,32 +1432,26 @@ void helper_sysret(int dflag)
env->eflags |= IF_MASK;
cpu_x86_set_cpl(env, 3);
}
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env)) {
- if (env->hflags & HF_LMA_MASK)
- CC_OP = CC_OP_EFLAGS;
- env->exception_index = -1;
- cpu_loop_exit();
- }
-#endif
}
+#endif
#ifdef VBOX
+
/**
* Checks and processes external VMM events.
* Called by op_check_external_event() when any of the flags is set and can be serviced.
*/
void helper_external_event(void)
{
-#if defined(RT_OS_DARWIN) && defined(VBOX_STRICT)
+# if defined(RT_OS_DARWIN) && defined(VBOX_STRICT)
uintptr_t uSP;
-# ifdef RT_ARCH_AMD64
+# ifdef RT_ARCH_AMD64
__asm__ __volatile__("movq %%rsp, %0" : "=r" (uSP));
-# else
+# else
__asm__ __volatile__("movl %%esp, %0" : "=r" (uSP));
-# endif
+# endif
AssertMsg(!(uSP & 15), ("xSP=%#p\n", uSP));
-#endif
+# endif
/* Keep in sync with flags checked by gen_check_external_event() */
if (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_HARD)
{
@@ -1470,7 +1463,7 @@ void helper_external_event(void)
{
ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request,
~CPU_INTERRUPT_EXTERNAL_EXIT);
- cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+ cpu_exit(env);
}
if (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_DMA)
{
@@ -1484,7 +1477,14 @@ void helper_external_event(void)
~CPU_INTERRUPT_EXTERNAL_TIMER);
remR3TimersRun(env);
}
+ if (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_FLUSH_TLB)
+ {
+ ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request,
+ ~CPU_INTERRUPT_EXTERNAL_HARD);
+ cpu_interrupt(env, CPU_INTERRUPT_HARD);
+ }
}
+
/* helper for recording call instruction addresses for later scanning */
void helper_record_call()
{
@@ -1493,6 +1493,7 @@ void helper_record_call()
&& !(env->eflags & X86_EFL_IF))
remR3RecordCall(env);
}
+
#endif /* VBOX */
/* real mode interrupt */
@@ -1567,6 +1568,27 @@ void do_interrupt_user(int intno, int is_int, int error_code,
EIP = next_eip;
}
+#if !defined(CONFIG_USER_ONLY)
+static void handle_even_inj(int intno, int is_int, int error_code,
+ int is_hw, int rm)
+{
+ uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));
+ if (!(event_inj & SVM_EVTINJ_VALID)) {
+ int type;
+ if (is_int)
+ type = SVM_EVTINJ_TYPE_SOFT;
+ else
+ type = SVM_EVTINJ_TYPE_EXEPT;
+ event_inj = intno | type | SVM_EVTINJ_VALID;
+ if (!rm && exeption_has_error_code(intno)) {
+ event_inj |= SVM_EVTINJ_VALID_ERR;
+ stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err), error_code);
+ }
+ stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj);
+ }
+}
+#endif
+
/*
* Begin execution of an interruption. is_int is TRUE if coming from
* the int instruction. next_eip is the EIP value AFTER the interrupt
@@ -1575,38 +1597,53 @@ void do_interrupt_user(int intno, int is_int, int error_code,
void do_interrupt(int intno, int is_int, int error_code,
target_ulong next_eip, int is_hw)
{
- if (loglevel & CPU_LOG_INT) {
+ if (qemu_loglevel_mask(CPU_LOG_INT)) {
if ((env->cr[0] & CR0_PE_MASK)) {
static int count;
- fprintf(logfile, "%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:" TARGET_FMT_lx " pc=" TARGET_FMT_lx " SP=%04x:" TARGET_FMT_lx,
+ qemu_log("%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:" TARGET_FMT_lx " pc=" TARGET_FMT_lx " SP=%04x:" TARGET_FMT_lx,
count, intno, error_code, is_int,
env->hflags & HF_CPL_MASK,
env->segs[R_CS].selector, EIP,
(int)env->segs[R_CS].base + EIP,
env->segs[R_SS].selector, ESP);
if (intno == 0x0e) {
- fprintf(logfile, " CR2=" TARGET_FMT_lx, env->cr[2]);
+ qemu_log(" CR2=" TARGET_FMT_lx, env->cr[2]);
} else {
- fprintf(logfile, " EAX=" TARGET_FMT_lx, EAX);
+ qemu_log(" EAX=" TARGET_FMT_lx, EAX);
}
- fprintf(logfile, "\n");
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
+ qemu_log("\n");
+ log_cpu_state(env, X86_DUMP_CCOP);
#if 0
{
int i;
uint8_t *ptr;
- fprintf(logfile, " code=");
+ qemu_log(" code=");
ptr = env->segs[R_CS].base + env->eip;
for(i = 0; i < 16; i++) {
- fprintf(logfile, " %02x", ldub(ptr + i));
+ qemu_log(" %02x", ldub(ptr + i));
}
- fprintf(logfile, "\n");
+ qemu_log("\n");
}
#endif
count++;
}
}
+#ifdef VBOX
+ if (RT_UNLIKELY(env->state & CPU_EMULATE_SINGLE_STEP)) {
+ if (is_int) {
+ RTLogPrintf("do_interrupt: %#04x err=%#x pc=%#RGv%s\n",
+ intno, error_code, (RTGCPTR)env->eip, is_hw ? " hw" : "");
+ } else {
+ RTLogPrintf("do_interrupt: %#04x err=%#x pc=%#RGv next=%#RGv%s\n",
+ intno, error_code, (RTGCPTR)env->eip, (RTGCPTR)next_eip, is_hw ? " hw" : "");
+ }
+ }
+#endif
if (env->cr[0] & CR0_PE_MASK) {
+#if !defined(CONFIG_USER_ONLY)
+ if (env->hflags & HF_SVMI_MASK)
+ handle_even_inj(intno, is_int, error_code, is_hw, 0);
+#endif
#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) {
do_interrupt64(intno, is_int, error_code, next_eip, is_hw);
@@ -1627,10 +1664,24 @@ void do_interrupt(int intno, int is_int, int error_code,
do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);
}
} else {
+#if !defined(CONFIG_USER_ONLY)
+ if (env->hflags & HF_SVMI_MASK)
+ handle_even_inj(intno, is_int, error_code, is_hw, 1);
+#endif
do_interrupt_real(intno, is_int, error_code, next_eip);
}
+
+#if !defined(CONFIG_USER_ONLY)
+ if (env->hflags & HF_SVMI_MASK) {
+ uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));
+ stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj & ~SVM_EVTINJ_VALID);
+ }
+#endif
}
+/* This should come from sysemu.h - if we could include it here... */
+void qemu_system_reset_request(void);
+
/*
* Check nested exceptions and change to double or triple fault if
* needed. It should only be called, if this is not an interrupt.
@@ -1644,12 +1695,24 @@ static int check_exception(int intno, int *error_code)
int second_contributory = intno == 0 ||
(intno >= 10 && intno <= 13);
- if (loglevel & CPU_LOG_INT)
- fprintf(logfile, "check_exception old: 0x%x new 0x%x\n",
+ qemu_log_mask(CPU_LOG_INT, "check_exception old: 0x%x new 0x%x\n",
env->old_exception, intno);
- if (env->old_exception == EXCP08_DBLE)
- cpu_abort(env, "triple fault");
+#if !defined(CONFIG_USER_ONLY)
+ if (env->old_exception == EXCP08_DBLE) {
+ if (env->hflags & HF_SVMI_MASK)
+ helper_vmexit(SVM_EXIT_SHUTDOWN, 0); /* does not return */
+
+ qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
+
+# ifndef VBOX
+ qemu_system_reset_request();
+# else
+ remR3RaiseRC(env->pVM, VINF_EM_RESET); /** @todo test + improve tripple fault handling. */
+# endif
+ return EXCP_HLT;
+ }
+#endif
if ((first_contributory && second_contributory)
|| (env->old_exception == EXCP0E_PAGE &&
@@ -1671,8 +1734,8 @@ static int check_exception(int intno, int *error_code)
* EIP value AFTER the interrupt instruction. It is only relevant if
* is_int is TRUE.
*/
-void raise_interrupt(int intno, int is_int, int error_code,
- int next_eip_addend)
+static void QEMU_NORETURN raise_interrupt(int intno, int is_int, int error_code,
+ int next_eip_addend)
{
#if defined(VBOX) && defined(DEBUG)
Log2(("raise_interrupt: %x %x %x %RGv\n", intno, is_int, error_code, (RTGCPTR)env->eip + next_eip_addend));
@@ -1693,7 +1756,7 @@ void raise_interrupt(int intno, int is_int, int error_code,
/* shortcuts to generate exceptions */
-void (raise_exception_err)(int exception_index, int error_code)
+void raise_exception_err(int exception_index, int error_code)
{
raise_interrupt(exception_index, 0, error_code, 0);
}
@@ -1703,6 +1766,11 @@ void raise_exception(int exception_index)
raise_interrupt(exception_index, 0, 0, 0);
}
+void raise_exception_env(int exception_index, CPUState *nenv)
+{
+ env = nenv;
+ raise_exception(exception_index);
+}
/* SMM support */
#if defined(CONFIG_USER_ONLY)
@@ -1729,10 +1797,8 @@ void do_smm_enter(void)
SegmentCache *dt;
int i, offset;
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "SMM: enter\n");
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
- }
+ qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
+ log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP);
env->hflags |= HF_SMM_MASK;
cpu_smm_update(env);
@@ -1863,8 +1929,6 @@ void helper_rsm(void)
#ifdef VBOX
cpu_abort(env, "helper_rsm");
#else /* !VBOX */
- target_ulong sm_
-
target_ulong sm_state;
int i, offset;
uint32_t val;
@@ -1977,10 +2041,8 @@ void helper_rsm(void)
env->hflags &= ~HF_SMM_MASK;
cpu_smm_update(env);
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "SMM: after RSM\n");
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
- }
+ qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n");
+ log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP);
#endif /* !VBOX */
}
@@ -2124,7 +2186,7 @@ void helper_aaa(void)
int al, ah, af;
int eflags;
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
af = eflags & CC_A;
al = EAX & 0xff;
ah = (EAX >> 8) & 0xff;
@@ -2140,7 +2202,6 @@ void helper_aaa(void)
}
EAX = (EAX & ~0xffff) | al | (ah << 8);
CC_SRC = eflags;
- FORCE_RET();
}
void helper_aas(void)
@@ -2149,7 +2210,7 @@ void helper_aas(void)
int al, ah, af;
int eflags;
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
af = eflags & CC_A;
al = EAX & 0xff;
ah = (EAX >> 8) & 0xff;
@@ -2165,7 +2226,6 @@ void helper_aas(void)
}
EAX = (EAX & ~0xffff) | al | (ah << 8);
CC_SRC = eflags;
- FORCE_RET();
}
void helper_daa(void)
@@ -2173,7 +2233,7 @@ void helper_daa(void)
int al, af, cf;
int eflags;
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
cf = eflags & CC_C;
af = eflags & CC_A;
al = EAX & 0xff;
@@ -2193,7 +2253,6 @@ void helper_daa(void)
eflags |= parity_table[al]; /* pf */
eflags |= (al & 0x80); /* sf */
CC_SRC = eflags;
- FORCE_RET();
}
void helper_das(void)
@@ -2201,7 +2260,7 @@ void helper_das(void)
int al, al1, af, cf;
int eflags;
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
cf = eflags & CC_C;
af = eflags & CC_A;
al = EAX & 0xff;
@@ -2224,13 +2283,12 @@ void helper_das(void)
eflags |= parity_table[al]; /* pf */
eflags |= (al & 0x80); /* sf */
CC_SRC = eflags;
- FORCE_RET();
}
void helper_into(int next_eip_addend)
{
int eflags;
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
if (eflags & CC_O) {
raise_interrupt(EXCP04_INTO, 1, 0, next_eip_addend);
}
@@ -2241,7 +2299,7 @@ void helper_cmpxchg8b(target_ulong a0)
uint64_t d;
int eflags;
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
d = ldq(a0);
if (d == (((uint64_t)EDX << 32) | (uint32_t)EAX)) {
stq(a0, ((uint64_t)ECX << 32) | (uint32_t)EBX);
@@ -2264,7 +2322,7 @@ void helper_cmpxchg16b(target_ulong a0)
if ((a0 & 0xf) != 0)
raise_exception(EXCP0D_GPF);
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
d0 = ldq(a0);
d1 = ldq(a0 + 8);
if (d0 == EAX && d1 == EDX) {
@@ -2285,181 +2343,24 @@ void helper_cmpxchg16b(target_ulong a0)
void helper_single_step(void)
{
- env->dr[6] |= 0x4000;
- raise_exception(EXCP01_SSTP);
+#ifndef CONFIG_USER_ONLY
+ check_hw_breakpoints(env, 1);
+ env->dr[6] |= DR6_BS;
+#endif
+ raise_exception(EXCP01_DB);
}
void helper_cpuid(void)
{
-#ifndef VBOX
- uint32_t index;
+ uint32_t eax, ebx, ecx, edx;
helper_svm_check_intercept_param(SVM_EXIT_CPUID, 0);
- index = (uint32_t)EAX;
- /* test if maximum index reached */
- if (index & 0x80000000) {
- if (index > env->cpuid_xlevel)
- index = env->cpuid_level;
- } else {
- if (index > env->cpuid_level)
- index = env->cpuid_level;
- }
-
- switch(index) {
- case 0:
- EAX = env->cpuid_level;
- EBX = env->cpuid_vendor1;
- EDX = env->cpuid_vendor2;
- ECX = env->cpuid_vendor3;
- break;
- case 1:
- EAX = env->cpuid_version;
- EBX = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
- ECX = env->cpuid_ext_features;
- EDX = env->cpuid_features;
- break;
- case 2:
- /* cache info: needed for Pentium Pro compatibility */
- EAX = 1;
- EBX = 0;
- ECX = 0;
- EDX = 0x2c307d;
- break;
- case 4:
- /* cache info: needed for Core compatibility */
- switch (ECX) {
- case 0: /* L1 dcache info */
- EAX = 0x0000121;
- EBX = 0x1c0003f;
- ECX = 0x000003f;
- EDX = 0x0000001;
- break;
- case 1: /* L1 icache info */
- EAX = 0x0000122;
- EBX = 0x1c0003f;
- ECX = 0x000003f;
- EDX = 0x0000001;
- break;
- case 2: /* L2 cache info */
- EAX = 0x0000143;
- EBX = 0x3c0003f;
- ECX = 0x0000fff;
- EDX = 0x0000001;
- break;
- default: /* end of info */
- EAX = 0;
- EBX = 0;
- ECX = 0;
- EDX = 0;
- break;
- }
-
- break;
- case 5:
- /* mwait info: needed for Core compatibility */
- EAX = 0; /* Smallest monitor-line size in bytes */
- EBX = 0; /* Largest monitor-line size in bytes */
- ECX = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
- EDX = 0;
- break;
- case 6:
- /* Thermal and Power Leaf */
- EAX = 0;
- EBX = 0;
- ECX = 0;
- EDX = 0;
- break;
- case 9:
- /* Direct Cache Access Information Leaf */
- EAX = 0; /* Bits 0-31 in DCA_CAP MSR */
- EBX = 0;
- ECX = 0;
- EDX = 0;
- break;
- case 0xA:
- /* Architectural Performance Monitoring Leaf */
- EAX = 0;
- EBX = 0;
- ECX = 0;
- EDX = 0;
- break;
- case 0x80000000:
- EAX = env->cpuid_xlevel;
- EBX = env->cpuid_vendor1;
- EDX = env->cpuid_vendor2;
- ECX = env->cpuid_vendor3;
- break;
- case 0x80000001:
- EAX = env->cpuid_features;
- EBX = 0;
- ECX = env->cpuid_ext3_features;
- EDX = env->cpuid_ext2_features;
- break;
- case 0x80000002:
- case 0x80000003:
- case 0x80000004:
- EAX = env->cpuid_model[(index - 0x80000002) * 4 + 0];
- EBX = env->cpuid_model[(index - 0x80000002) * 4 + 1];
- ECX = env->cpuid_model[(index - 0x80000002) * 4 + 2];
- EDX = env->cpuid_model[(index - 0x80000002) * 4 + 3];
- break;
- case 0x80000005:
- /* cache info (L1 cache) */
- EAX = 0x01ff01ff;
- EBX = 0x01ff01ff;
- ECX = 0x40020140;
- EDX = 0x40020140;
- break;
- case 0x80000006:
- /* cache info (L2 cache) */
- EAX = 0;
- EBX = 0x42004200;
- ECX = 0x02008140;
- EDX = 0;
- break;
- case 0x80000008:
- /* virtual & phys address size in low 2 bytes. */
-/* XXX: This value must match the one used in the MMU code. */
- if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
- /* 64 bit processor */
-#if defined(USE_KQEMU)
- EAX = 0x00003020; /* 48 bits virtual, 32 bits physical */
-#else
-/* XXX: The physical address space is limited to 42 bits in exec.c. */
- EAX = 0x00003028; /* 48 bits virtual, 40 bits physical */
-#endif
- } else {
-#if defined(USE_KQEMU)
- EAX = 0x00000020; /* 32 bits physical */
-#else
- if (env->cpuid_features & CPUID_PSE36)
- EAX = 0x00000024; /* 36 bits physical */
- else
- EAX = 0x00000020; /* 32 bits physical */
-#endif
- }
- EBX = 0;
- ECX = 0;
- EDX = 0;
- break;
- case 0x8000000A:
- EAX = 0x00000001;
- EBX = 0;
- ECX = 0;
- EDX = 0;
- break;
- default:
- /* reserved values: zero */
- EAX = 0;
- EBX = 0;
- ECX = 0;
- EDX = 0;
- break;
- }
-#else /* VBOX */
- remR3CpuId(env, EAX, &EAX, &EBX, &ECX, &EDX);
-#endif /* VBOX */
+ cpu_x86_cpuid(env, (uint32_t)EAX, (uint32_t)ECX, &eax, &ebx, &ecx, &edx);
+ EAX = eax;
+ EBX = ebx;
+ ECX = ecx;
+ EDX = edx;
}
void helper_enter_level(int level, int data32, target_ulong t1)
@@ -2670,15 +2571,15 @@ void helper_load_seg(int seg_reg, int selector)
selector &= 0xffff;
cpl = env->hflags & HF_CPL_MASK;
-
#ifdef VBOX
+
/* Trying to load a selector with CPL=1? */
if (cpl == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0))
{
Log(("RPL 1 -> sel %04X -> %04X\n", selector, selector & 0xfffc));
selector = selector & 0xfffc;
}
-#endif
+#endif /* VBOX */
if ((selector & 0xfffc) == 0) {
/* null selector case */
if (seg_reg == R_SS
@@ -2741,7 +2642,7 @@ void helper_load_seg(int seg_reg, int selector)
get_seg_limit(e1, e2),
e2);
#if 0
- fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx flags=%08x\n",
+ qemu_log("load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx flags=%08x\n",
selector, (unsigned long)sc->base, sc->limit, sc->flags);
#endif
}
@@ -2755,7 +2656,7 @@ void helper_ljmp_protected(int new_cs, target_ulong new_eip,
uint32_t e1, e2, cpl, dpl, rpl, limit;
target_ulong next_eip;
-#ifdef VBOX
+#ifdef VBOX /** @todo Why do we do this? */
e1 = e2 = 0;
#endif
if ((new_cs & 0xfffc) == 0)
@@ -2876,31 +2777,22 @@ void helper_lcall_protected(int new_cs, target_ulong new_eip,
{
int new_stack, i;
uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count;
- uint32_t ss, ss_e1, ss_e2, sp, type, ss_dpl, sp_mask;
+ uint32_t ss = 0, ss_e1 = 0, ss_e2 = 0, sp, type, ss_dpl, sp_mask;
uint32_t val, limit, old_sp_mask;
target_ulong ssp, old_ssp, next_eip;
-#ifdef VBOX
- ss = ss_e1 = ss_e2 = e1 = e2 = 0;
+#ifdef VBOX /** @todo Why do we do this? */
+ e1 = e2 = 0;
#endif
next_eip = env->eip + next_eip_addend;
-#ifdef DEBUG_PCALL
- if (loglevel & CPU_LOG_PCALL) {
- fprintf(logfile, "lcall %04x:%08x s=%d\n",
- new_cs, (uint32_t)new_eip, shift);
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
- }
-#endif
+ LOG_PCALL("lcall %04x:%08x s=%d\n", new_cs, (uint32_t)new_eip, shift);
+ LOG_PCALL_STATE(env);
if ((new_cs & 0xfffc) == 0)
raise_exception_err(EXCP0D_GPF, 0);
if (load_segment(&e1, &e2, new_cs) != 0)
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
cpl = env->hflags & HF_CPL_MASK;
-#ifdef DEBUG_PCALL
- if (loglevel & CPU_LOG_PCALL) {
- fprintf(logfile, "desc=%08x:%08x\n", e1, e2);
- }
-#endif
+ LOG_PCALL("desc=%08x:%08x\n", e1, e2);
if (e2 & DESC_S_MASK) {
if (!(e2 & DESC_CS_MASK))
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
@@ -3004,11 +2896,8 @@ void helper_lcall_protected(int new_cs, target_ulong new_eip,
if (!(e2 & DESC_C_MASK) && dpl < cpl) {
/* to inner privilege */
get_ss_esp_from_tss(&ss, &sp, dpl);
-#ifdef DEBUG_PCALL
- if (loglevel & CPU_LOG_PCALL)
- fprintf(logfile, "new ss:esp=%04x:%08x param_count=%d ESP=" TARGET_FMT_lx "\n",
+ LOG_PCALL("new ss:esp=%04x:%08x param_count=%d ESP=" TARGET_FMT_lx "\n",
ss, sp, param_count, ESP);
-#endif
if ((ss & 0xfffc) == 0)
raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
if ((ss & 3) != dpl)
@@ -3088,12 +2977,6 @@ void helper_lcall_protected(int new_cs, target_ulong new_eip,
SET_ESP(sp, sp_mask);
EIP = offset;
}
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env)) {
- env->exception_index = -1;
- cpu_loop_exit();
- }
-#endif
}
/* real and vm86 mode iret */
@@ -3164,11 +3047,7 @@ void helper_iret_real(int shift)
#endif /* VBOX */
}
-#ifndef VBOX
static inline void validate_seg(int seg_reg, int cpl)
-#else /* VBOX */
-DECLINLINE(void) validate_seg(int seg_reg, int cpl)
-#endif /* VBOX */
{
int dpl;
uint32_t e2;
@@ -3191,11 +3070,7 @@ DECLINLINE(void) validate_seg(int seg_reg, int cpl)
}
/* protected mode iret */
-#ifndef VBOX
static inline void helper_ret_protected(int shift, int is_iret, int addend)
-#else /* VBOX */
-DECLINLINE(void) helper_ret_protected(int shift, int is_iret, int addend)
-#endif /* VBOX */
{
uint32_t new_cs, new_eflags, new_ss;
uint32_t new_es, new_ds, new_fs, new_gs;
@@ -3203,7 +3078,7 @@ DECLINLINE(void) helper_ret_protected(int shift, int is_iret, int addend)
int cpl, dpl, rpl, eflags_mask, iopl;
target_ulong ssp, sp, new_eip, new_esp, sp_mask;
-#ifdef VBOX
+#ifdef VBOX /** @todo Why do we do this? */
ss_e1 = ss_e2 = e1 = e2 = 0;
#endif
@@ -3245,9 +3120,9 @@ DECLINLINE(void) helper_ret_protected(int shift, int is_iret, int addend)
#ifdef VBOX
if ((new_cs & 0x3) == 1 && (env->state & CPU_RAW_RING0))
{
-#ifdef DEBUG
+# ifdef DEBUG
printf("RPL 1 -> new_cs %04X -> %04X\n", new_cs, new_cs & 0xfffc);
-#endif
+# endif
new_cs = new_cs & 0xfffc;
}
#endif
@@ -3258,13 +3133,9 @@ DECLINLINE(void) helper_ret_protected(int shift, int is_iret, int addend)
if (is_iret)
POPW(ssp, sp, sp_mask, new_eflags);
}
-#ifdef DEBUG_PCALL
- if (loglevel & CPU_LOG_PCALL) {
- fprintf(logfile, "lret new %04x:" TARGET_FMT_lx " s=%d addend=0x%x\n",
- new_cs, new_eip, shift, addend);
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
- }
-#endif
+ LOG_PCALL("lret new %04x:" TARGET_FMT_lx " s=%d addend=0x%x\n",
+ new_cs, new_eip, shift, addend);
+ LOG_PCALL_STATE(env);
if ((new_cs & 0xfffc) == 0)
{
#if defined(VBOX) && defined(DEBUG)
@@ -3349,12 +3220,8 @@ DECLINLINE(void) helper_ret_protected(int shift, int is_iret, int addend)
POPW(ssp, sp, sp_mask, new_esp);
POPW(ssp, sp, sp_mask, new_ss);
}
-#ifdef DEBUG_PCALL
- if (loglevel & CPU_LOG_PCALL) {
- fprintf(logfile, "new ss:esp=%04x:" TARGET_FMT_lx "\n",
+ LOG_PCALL("new ss:esp=%04x:" TARGET_FMT_lx "\n",
new_ss, new_esp);
- }
-#endif
if ((new_ss & 0xfffc) == 0) {
#ifdef TARGET_X86_64
/* NULL ss is allowed in long mode if cpl != 3*/
@@ -3461,7 +3328,7 @@ void helper_iret_protected(int shift, int next_eip)
uint32_t e1, e2;
#ifdef VBOX
- e1 = e2 = 0;
+ e1 = e2 = 0; /** @todo Why do we do this? */
remR3TrapClear(env->pVM);
#endif
@@ -3485,24 +3352,11 @@ void helper_iret_protected(int shift, int next_eip)
helper_ret_protected(shift, 1, 0);
}
env->hflags2 &= ~HF2_NMI_MASK;
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env)) {
- CC_OP = CC_OP_EFLAGS;
- env->exception_index = -1;
- cpu_loop_exit();
- }
-#endif
}
void helper_lret_protected(int shift, int addend)
{
helper_ret_protected(shift, 0, addend);
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env)) {
- env->exception_index = -1;
- cpu_loop_exit();
- }
-#endif
}
void helper_sysenter(void)
@@ -3575,12 +3429,6 @@ void helper_sysexit(int dflag)
}
ESP = ECX;
EIP = EDX;
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env)) {
- env->exception_index = -1;
- cpu_loop_exit();
- }
-#endif
}
#if defined(CONFIG_USER_ONLY)
@@ -3592,6 +3440,10 @@ target_ulong helper_read_crN(int reg)
void helper_write_crN(int reg, target_ulong t0)
{
}
+
+void helper_movl_drN_T0(int reg, target_ulong t0)
+{
+}
#else
target_ulong helper_read_crN(int reg)
{
@@ -3604,7 +3456,11 @@ target_ulong helper_read_crN(int reg)
break;
case 8:
if (!(env->hflags2 & HF2_VINTR_MASK)) {
+#ifndef VBOX
+ val = cpu_get_apic_tpr(env->apic_state);
+#else /* VBOX */
val = cpu_get_apic_tpr(env);
+#endif /* VBOX */
} else {
val = env->v_tpr;
}
@@ -3628,7 +3484,11 @@ void helper_write_crN(int reg, target_ulong t0)
break;
case 8:
if (!(env->hflags2 & HF2_VINTR_MASK)) {
+#ifndef VBOX
+ cpu_set_apic_tpr(env->apic_state, t0);
+#else /* VBOX */
cpu_set_apic_tpr(env, t0);
+#endif /* VBOX */
}
env->v_tpr = t0 & 0x0f;
break;
@@ -3637,6 +3497,24 @@ void helper_write_crN(int reg, target_ulong t0)
break;
}
}
+
+void helper_movl_drN_T0(int reg, target_ulong t0)
+{
+ int i;
+
+ if (reg < 4) {
+ hw_breakpoint_remove(env, reg);
+ env->dr[reg] = t0;
+ hw_breakpoint_insert(env, reg);
+ } else if (reg == 7) {
+ for (i = 0; i < 4; i++)
+ hw_breakpoint_remove(env, i);
+ env->dr[7] = t0;
+ for (i = 0; i < 4; i++)
+ hw_breakpoint_insert(env, i);
+ } else
+ env->dr[reg] = t0;
+}
#endif
void helper_lmsw(target_ulong t0)
@@ -3653,12 +3531,6 @@ void helper_clts(void)
env->hflags &= ~HF_TS_MASK;
}
-/* XXX: do more */
-void helper_movl_drN_T0(int reg, target_ulong t0)
-{
- env->dr[reg] = t0;
-}
-
void helper_invlpg(target_ulong addr)
{
helper_svm_check_intercept_param(SVM_EXIT_INVLPG, 0);
@@ -3679,23 +3551,19 @@ void helper_rdtsc(void)
EDX = (uint32_t)(val >> 32);
}
-#ifdef VBOX
void helper_rdtscp(void)
{
+ helper_rdtsc();
+#ifndef VBOX
+ ECX = (uint32_t)(env->tsc_aux);
+#else /* VBOX */
uint64_t val;
- if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
- raise_exception(EXCP0D_GPF);
- }
-
- val = cpu_get_tsc(env);
- EAX = (uint32_t)(val);
- EDX = (uint32_t)(val >> 32);
if (cpu_rdmsr(env, MSR_K8_TSC_AUX, &val) == 0)
ECX = (uint32_t)(val);
else
ECX = 0;
+#endif /* VBOX */
}
-#endif
void helper_rdpmc(void)
{
@@ -3707,7 +3575,7 @@ void helper_rdpmc(void)
/* Just return zero here; rather tricky to properly emulate this, especially as the specs are a mess. */
EAX = 0;
EDX = 0;
-#else
+#else /* !VBOX */
if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
raise_exception(EXCP0D_GPF);
}
@@ -3715,7 +3583,7 @@ void helper_rdpmc(void)
/* currently unimplemented */
raise_exception_err(EXCP06_ILLOP, 0);
-#endif
+#endif /* !VBOX */
}
#if defined(CONFIG_USER_ONLY)
@@ -3746,9 +3614,9 @@ void helper_wrmsr(void)
env->sysenter_eip = val;
break;
case MSR_IA32_APICBASE:
-#ifndef VBOX /* The CPUMSetGuestMsr call below does this now. */
- cpu_set_apic_base(env, val);
-#endif
+# ifndef VBOX /* The CPUMSetGuestMsr call below does this now. */
+ cpu_set_apic_base(env->apic_state, val);
+# endif
break;
case MSR_EFER:
{
@@ -3764,6 +3632,8 @@ void helper_wrmsr(void)
update_mask |= MSR_EFER_NXE;
if (env->cpuid_ext3_features & CPUID_EXT3_SVM)
update_mask |= MSR_EFER_SVME;
+ if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR)
+ update_mask |= MSR_EFER_FFXSR;
cpu_load_efer(env, (env->efer & ~update_mask) |
(val & update_mask));
}
@@ -3797,25 +3667,87 @@ void helper_wrmsr(void)
env->kernelgsbase = val;
break;
#endif
+# ifndef VBOX
+ case MSR_MTRRphysBase(0):
+ case MSR_MTRRphysBase(1):
+ case MSR_MTRRphysBase(2):
+ case MSR_MTRRphysBase(3):
+ case MSR_MTRRphysBase(4):
+ case MSR_MTRRphysBase(5):
+ case MSR_MTRRphysBase(6):
+ case MSR_MTRRphysBase(7):
+ env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysBase(0)) / 2].base = val;
+ break;
+ case MSR_MTRRphysMask(0):
+ case MSR_MTRRphysMask(1):
+ case MSR_MTRRphysMask(2):
+ case MSR_MTRRphysMask(3):
+ case MSR_MTRRphysMask(4):
+ case MSR_MTRRphysMask(5):
+ case MSR_MTRRphysMask(6):
+ case MSR_MTRRphysMask(7):
+ env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysMask(0)) / 2].mask = val;
+ break;
+ case MSR_MTRRfix64K_00000:
+ env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix64K_00000] = val;
+ break;
+ case MSR_MTRRfix16K_80000:
+ case MSR_MTRRfix16K_A0000:
+ env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix16K_80000 + 1] = val;
+ break;
+ case MSR_MTRRfix4K_C0000:
+ case MSR_MTRRfix4K_C8000:
+ case MSR_MTRRfix4K_D0000:
+ case MSR_MTRRfix4K_D8000:
+ case MSR_MTRRfix4K_E0000:
+ case MSR_MTRRfix4K_E8000:
+ case MSR_MTRRfix4K_F0000:
+ case MSR_MTRRfix4K_F8000:
+ env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix4K_C0000 + 3] = val;
+ break;
+ case MSR_MTRRdefType:
+ env->mtrr_deftype = val;
+ break;
+ case MSR_MCG_STATUS:
+ env->mcg_status = val;
+ break;
+ case MSR_MCG_CTL:
+ if ((env->mcg_cap & MCG_CTL_P)
+ && (val == 0 || val == ~(uint64_t)0))
+ env->mcg_ctl = val;
+ break;
+ case MSR_TSC_AUX:
+ env->tsc_aux = val;
+ break;
+# endif /* !VBOX */
default:
-#ifndef VBOX
+# ifndef VBOX
+ if ((uint32_t)ECX >= MSR_MC0_CTL
+ && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
+ uint32_t offset = (uint32_t)ECX - MSR_MC0_CTL;
+ if ((offset & 0x3) != 0
+ || (val == 0 || val == ~(uint64_t)0))
+ env->mce_banks[offset] = val;
+ break;
+ }
/* XXX: exception ? */
-#endif
+# endif
break;
}
-#ifdef VBOX
+# ifdef VBOX
/* call CPUM. */
if (cpu_wrmsr(env, (uint32_t)ECX, val) != 0)
{
/** @todo be a brave man and raise a \#GP(0) here as we should... */
}
-#endif
+# endif
}
void helper_rdmsr(void)
{
uint64_t val;
+
helper_svm_check_intercept_param(SVM_EXIT_MSR, 0);
switch((uint32_t)ECX) {
@@ -3829,7 +3761,11 @@ void helper_rdmsr(void)
val = env->sysenter_eip;
break;
case MSR_IA32_APICBASE:
+#ifndef VBOX
+ val = cpu_get_apic_base(env->apic_state);
+#else /* VBOX */
val = cpu_get_apic_base(env);
+#endif /* VBOX */
break;
case MSR_EFER:
val = env->efer;
@@ -3843,14 +3779,14 @@ void helper_rdmsr(void)
case MSR_VM_HSAVE_PA:
val = env->vm_hsave;
break;
-#ifndef VBOX /* forward to CPUMQueryGuestMsr. */
+# ifndef VBOX /* forward to CPUMQueryGuestMsr. */
case MSR_IA32_PERF_STATUS:
/* tsc_increment_by_tick */
val = 1000ULL;
/* CPU multiplier */
- val |= ((uint64_t)4ULL << 40);
+ val |= (((uint64_t)4ULL) << 40);
break;
-#endif
+# endif /* !VBOX */
#ifdef TARGET_X86_64
case MSR_LSTAR:
val = env->lstar;
@@ -3870,37 +3806,100 @@ void helper_rdmsr(void)
case MSR_KERNELGSBASE:
val = env->kernelgsbase;
break;
-#endif
-#ifdef USE_KQEMU
- case MSR_QPI_COMMBASE:
- if (env->kqemu_enabled) {
- val = kqemu_comm_base;
- } else {
+# ifndef VBOX
+ case MSR_TSC_AUX:
+ val = env->tsc_aux;
+ break;
+# endif /*!VBOX*/
+#endif
+# ifndef VBOX
+ case MSR_MTRRphysBase(0):
+ case MSR_MTRRphysBase(1):
+ case MSR_MTRRphysBase(2):
+ case MSR_MTRRphysBase(3):
+ case MSR_MTRRphysBase(4):
+ case MSR_MTRRphysBase(5):
+ case MSR_MTRRphysBase(6):
+ case MSR_MTRRphysBase(7):
+ val = env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysBase(0)) / 2].base;
+ break;
+ case MSR_MTRRphysMask(0):
+ case MSR_MTRRphysMask(1):
+ case MSR_MTRRphysMask(2):
+ case MSR_MTRRphysMask(3):
+ case MSR_MTRRphysMask(4):
+ case MSR_MTRRphysMask(5):
+ case MSR_MTRRphysMask(6):
+ case MSR_MTRRphysMask(7):
+ val = env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysMask(0)) / 2].mask;
+ break;
+ case MSR_MTRRfix64K_00000:
+ val = env->mtrr_fixed[0];
+ break;
+ case MSR_MTRRfix16K_80000:
+ case MSR_MTRRfix16K_A0000:
+ val = env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix16K_80000 + 1];
+ break;
+ case MSR_MTRRfix4K_C0000:
+ case MSR_MTRRfix4K_C8000:
+ case MSR_MTRRfix4K_D0000:
+ case MSR_MTRRfix4K_D8000:
+ case MSR_MTRRfix4K_E0000:
+ case MSR_MTRRfix4K_E8000:
+ case MSR_MTRRfix4K_F0000:
+ case MSR_MTRRfix4K_F8000:
+ val = env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix4K_C0000 + 3];
+ break;
+ case MSR_MTRRdefType:
+ val = env->mtrr_deftype;
+ break;
+ case MSR_MTRRcap:
+ if (env->cpuid_features & CPUID_MTRR)
+ val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT | MSR_MTRRcap_WC_SUPPORTED;
+ else
+ /* XXX: exception ? */
val = 0;
- }
break;
-#endif
+ case MSR_MCG_CAP:
+ val = env->mcg_cap;
+ break;
+ case MSR_MCG_CTL:
+ if (env->mcg_cap & MCG_CTL_P)
+ val = env->mcg_ctl;
+ else
+ val = 0;
+ break;
+ case MSR_MCG_STATUS:
+ val = env->mcg_status;
+ break;
+# endif /* !VBOX */
default:
-#ifndef VBOX
+# ifndef VBOX
+ if ((uint32_t)ECX >= MSR_MC0_CTL
+ && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
+ uint32_t offset = (uint32_t)ECX - MSR_MC0_CTL;
+ val = env->mce_banks[offset];
+ break;
+ }
/* XXX: exception ? */
val = 0;
-#else /* VBOX */
+# else /* VBOX */
if (cpu_rdmsr(env, (uint32_t)ECX, &val) != 0)
{
/** @todo be a brave man and raise a \#GP(0) here as we should... */
val = 0;
}
-#endif
+# endif /* VBOX */
break;
}
EAX = (uint32_t)(val);
EDX = (uint32_t)(val >> 32);
-#ifdef VBOX_STRICT
+# ifdef VBOX_STRICT
if (cpu_rdmsr(env, (uint32_t)ECX, &val) != 0)
val = 0;
AssertMsg(val == RT_MAKE_U64(EAX, EDX), ("idMsr=%#x val=%#llx eax:edx=%#llx\n", (uint32_t)ECX, val, RT_MAKE_U64(EAX, EDX)));
-#endif
+# endif
}
#endif
@@ -3911,7 +3910,9 @@ target_ulong helper_lsl(target_ulong selector1)
int rpl, dpl, cpl, type;
selector = selector1 & 0xffff;
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
+ if ((selector & 0xfffc) == 0)
+ goto fail;
if (load_segment(&e1, &e2, selector) != 0)
goto fail;
rpl = selector & 3;
@@ -3953,7 +3954,7 @@ target_ulong helper_lar(target_ulong selector1)
int rpl, dpl, cpl, type;
selector = selector1 & 0xffff;
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
if ((selector & 0xfffc) == 0)
goto fail;
if (load_segment(&e1, &e2, selector) != 0)
@@ -3999,7 +4000,7 @@ void helper_verr(target_ulong selector1)
int rpl, dpl, cpl;
selector = selector1 & 0xffff;
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
if ((selector & 0xfffc) == 0)
goto fail;
if (load_segment(&e1, &e2, selector) != 0)
@@ -4032,7 +4033,7 @@ void helper_verw(target_ulong selector1)
int rpl, dpl, cpl;
selector = selector1 & 0xffff;
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
if ((selector & 0xfffc) == 0)
goto fail;
if (load_segment(&e1, &e2, selector) != 0)
@@ -4065,18 +4066,14 @@ static void fpu_set_exception(int mask)
env->fpus |= FPUS_SE | FPUS_B;
}
-#ifndef VBOX
static inline CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b)
-#else /* VBOX */
-DECLINLINE(CPU86_LDouble) helper_fdiv(CPU86_LDouble a, CPU86_LDouble b)
-#endif /* VBOX */
{
if (b == 0.0)
fpu_set_exception(FPUS_ZE);
return a / b;
}
-void fpu_raise_exception(void)
+static void fpu_raise_exception(void)
{
if (env->cr[0] & CR0_NE_MASK) {
raise_exception(EXCP10_COPR);
@@ -4182,6 +4179,7 @@ uint64_t helper_fstl_ST0(void)
u.f = floatx_to_float64(ST0, &env->fp_status);
return u.i;
}
+
#ifndef VBOX
int32_t helper_fist_ST0(void)
#else
@@ -4325,7 +4323,6 @@ void helper_fcom_ST0_FT0(void)
ret = floatx_compare(ST0, FT0, &env->fp_status);
env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1];
- FORCE_RET();
}
void helper_fucom_ST0_FT0(void)
@@ -4334,7 +4331,6 @@ void helper_fucom_ST0_FT0(void)
ret = floatx_compare_quiet(ST0, FT0, &env->fp_status);
env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1];
- FORCE_RET();
}
static const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
@@ -4345,10 +4341,9 @@ void helper_fcomi_ST0_FT0(void)
int ret;
ret = floatx_compare(ST0, FT0, &env->fp_status);
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
CC_SRC = eflags;
- FORCE_RET();
}
void helper_fucomi_ST0_FT0(void)
@@ -4357,10 +4352,9 @@ void helper_fucomi_ST0_FT0(void)
int ret;
ret = floatx_compare_quiet(ST0, FT0, &env->fp_status);
- eflags = cc_table[CC_OP].compute_all();
+ eflags = helper_cc_compute_all(CC_OP);
eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
CC_SRC = eflags;
- FORCE_RET();
}
void helper_fadd_ST0_FT0(void)
@@ -4553,7 +4547,6 @@ void helper_fwait(void)
{
if (env->fpus & FPUS_SE)
fpu_raise_exception();
- FORCE_RET();
}
void helper_fninit(void)
@@ -4680,16 +4673,6 @@ void helper_fxtract(void)
ST0 = temp.d;
}
-#ifdef VBOX
-#ifdef _MSC_VER
-/* MSC cannot divide by zero */
-extern double _Nan;
-#define NaN _Nan
-#else
-#define NaN (0.0 / 0.0)
-#endif
-#endif /* VBOX */
-
void helper_fprem1(void)
{
CPU86_LDouble dblq, fpsrcop, fptemp;
@@ -5041,6 +5024,11 @@ void helper_fxsave(target_ulong ptr, int data64)
CPU86_LDouble tmp;
target_ulong addr;
+ /* The operand must be 16 byte aligned */
+ if (ptr & 0xf) {
+ raise_exception(EXCP0D_GPF);
+ }
+
fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
fptag = 0;
for(i = 0; i < 8; i++) {
@@ -5078,10 +5066,15 @@ void helper_fxsave(target_ulong ptr, int data64)
else
nb_xmm_regs = 8;
addr = ptr + 0xa0;
- for(i = 0; i < nb_xmm_regs; i++) {
- stq(addr, env->xmm_regs[i].XMM_Q(0));
- stq(addr + 8, env->xmm_regs[i].XMM_Q(1));
- addr += 16;
+ /* Fast FXSAVE leaves out the XMM registers */
+ if (!(env->efer & MSR_EFER_FFXSR)
+ || (env->hflags & HF_CPL_MASK)
+ || !(env->hflags & HF_LMA_MASK)) {
+ for(i = 0; i < nb_xmm_regs; i++) {
+ stq(addr, env->xmm_regs[i].XMM_Q(0));
+ stq(addr + 8, env->xmm_regs[i].XMM_Q(1));
+ addr += 16;
+ }
}
}
}
@@ -5092,6 +5085,11 @@ void helper_fxrstor(target_ulong ptr, int data64)
CPU86_LDouble tmp;
target_ulong addr;
+ /* The operand must be 16 byte aligned */
+ if (ptr & 0xf) {
+ raise_exception(EXCP0D_GPF);
+ }
+
env->fpuc = lduw(ptr);
fpus = lduw(ptr + 2);
fptag = lduw(ptr + 4);
@@ -5118,25 +5116,30 @@ void helper_fxrstor(target_ulong ptr, int data64)
else
nb_xmm_regs = 8;
addr = ptr + 0xa0;
- for(i = 0; i < nb_xmm_regs; i++) {
+ /* Fast FXRESTORE leaves out the XMM registers */
+ if (!(env->efer & MSR_EFER_FFXSR)
+ || (env->hflags & HF_CPL_MASK)
+ || !(env->hflags & HF_LMA_MASK)) {
+ for(i = 0; i < nb_xmm_regs; i++) {
#if !defined(VBOX) || __GNUC__ < 4
- env->xmm_regs[i].XMM_Q(0) = ldq(addr);
- env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8);
+ env->xmm_regs[i].XMM_Q(0) = ldq(addr);
+ env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8);
#else /* VBOX + __GNUC__ >= 4: gcc 4.x compiler bug - it runs out of registers for the 64-bit value. */
# if 1
- env->xmm_regs[i].XMM_L(0) = ldl(addr);
- env->xmm_regs[i].XMM_L(1) = ldl(addr + 4);
- env->xmm_regs[i].XMM_L(2) = ldl(addr + 8);
- env->xmm_regs[i].XMM_L(3) = ldl(addr + 12);
+ env->xmm_regs[i].XMM_L(0) = ldl(addr);
+ env->xmm_regs[i].XMM_L(1) = ldl(addr + 4);
+ env->xmm_regs[i].XMM_L(2) = ldl(addr + 8);
+ env->xmm_regs[i].XMM_L(3) = ldl(addr + 12);
# else
- /* this works fine on Mac OS X, gcc 4.0.1 */
- uint64_t u64 = ldq(addr);
- env->xmm_regs[i].XMM_Q(0);
- u64 = ldq(addr + 4);
- env->xmm_regs[i].XMM_Q(1) = u64;
+ /* this works fine on Mac OS X, gcc 4.0.1 */
+ uint64_t u64 = ldq(addr);
+ env->xmm_regs[i].XMM_Q(0);
+ u64 = ldq(addr + 4);
+ env->xmm_regs[i].XMM_Q(1) = u64;
# endif
#endif
- addr += 16;
+ addr += 16;
+ }
}
}
}
@@ -5362,10 +5365,10 @@ void helper_monitor(target_ulong ptr)
#ifdef VBOX
if ((uint32_t)ECX > 1)
raise_exception(EXCP0D_GPF);
-#else
+#else /* !VBOX */
if ((uint32_t)ECX != 0)
raise_exception(EXCP0D_GPF);
-#endif
+#endif /* !VBOX */
/* XXX: store address ? */
helper_svm_check_intercept_param(SVM_EXIT_MONITOR, 0);
}
@@ -5376,7 +5379,7 @@ void helper_mwait(int next_eip_addend)
raise_exception(EXCP0D_GPF);
#ifdef VBOX
helper_hlt(next_eip_addend);
-#else
+#else /* !VBOX */
helper_svm_check_intercept_param(SVM_EXIT_MWAIT, 0);
EIP += next_eip_addend;
@@ -5387,7 +5390,7 @@ void helper_mwait(int next_eip_addend)
} else {
do_hlt();
}
-#endif
+#endif /* !VBOX */
}
void helper_debug(void)
@@ -5396,6 +5399,11 @@ void helper_debug(void)
cpu_loop_exit();
}
+void helper_reset_rf(void)
+{
+ env->eflags &= ~RF_MASK;
+}
+
void helper_raise_interrupt(int intno, int next_eip_addend)
{
raise_interrupt(intno, 1, 0, next_eip_addend);
@@ -5430,7 +5438,7 @@ void helper_sti_vme(void)
}
env->eflags |= VIF_MASK;
}
-#endif
+#endif /* VBOX */
#if 0
/* vm86plus instructions */
@@ -5467,7 +5475,6 @@ void helper_boundw(target_ulong a0, int v)
if (v < low || v > high) {
raise_exception(EXCP05_BOUND);
}
- FORCE_RET();
}
void helper_boundl(target_ulong a0, int v)
@@ -5478,7 +5485,6 @@ void helper_boundl(target_ulong a0, int v)
if (v < low || v > high) {
raise_exception(EXCP05_BOUND);
}
- FORCE_RET();
}
static float approx_rsqrt(float a)
@@ -5556,8 +5562,9 @@ void REGPARM __stq_vbox_phys(RTCCUINTREG addr, uint64_t val)
{
remR3PhysWriteU64(addr, val);
}
-#endif
+#endif /* VBOX */
+#if !defined(CONFIG_USER_ONLY)
/* try to fill the TLB and return an exception if error. If retaddr is
NULL, it means that the function was called in C code (i.e. not
from generated code or from helper.c) */
@@ -5590,6 +5597,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
}
env = saved_env;
}
+#endif
#ifdef VBOX
@@ -5820,7 +5828,7 @@ int emulate_single_instr(CPUX86State *env1)
* eip remains the same for repeated instructions; no idea why qemu doesn't do a jump inside the generated code
* perhaps not a very safe hack
*/
- while(old_eip == env->eip)
+ while (old_eip == env->eip)
{
tc_ptr = tb->tc_ptr;
@@ -5830,16 +5838,21 @@ int emulate_single_instr(CPUX86State *env1)
#else
tcg_qemu_tb_exec(tc_ptr);
#endif
+
/*
* Exit once we detect an external interrupt and interrupts are enabled
*/
- if( (env->interrupt_request & (CPU_INTERRUPT_EXTERNAL_EXIT|CPU_INTERRUPT_EXTERNAL_TIMER)) ||
- ( (env->eflags & IF_MASK) &&
- !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
- (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_HARD) ) )
+ if ( (env->interrupt_request & (CPU_INTERRUPT_EXTERNAL_EXIT | CPU_INTERRUPT_EXTERNAL_TIMER))
+ || ( (env->eflags & IF_MASK)
+ && !(env->hflags & HF_INHIBIT_IRQ_MASK)
+ && (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_HARD) )
+ )
{
break;
}
+ if (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_FLUSH_TLB) {
+ tlb_flush(env, true);
+ }
}
env->current_tb = current;
@@ -5931,20 +5944,12 @@ int get_ss_esp_from_tss_raw(CPUX86State *env1, uint32_t *ss_ptr,
//*****************************************************************************
// Needs to be at the bottom of the file (overriding macros)
-#ifndef VBOX
static inline CPU86_LDouble helper_fldt_raw(uint8_t *ptr)
-#else /* VBOX */
-DECLINLINE(CPU86_LDouble) helper_fldt_raw(uint8_t *ptr)
-#endif /* VBOX */
{
return *(CPU86_LDouble *)ptr;
}
-#ifndef VBOX
static inline void helper_fstt_raw(CPU86_LDouble f, uint8_t *ptr)
-#else /* VBOX */
-DECLINLINE(void) helper_fstt_raw(CPU86_LDouble f, uint8_t *ptr)
-#endif /* VBOX */
{
*(CPU86_LDouble *)ptr = f;
}
@@ -6148,11 +6153,7 @@ void helper_svm_check_io(uint32_t port, uint32_t param,
}
#else
-#ifndef VBOX
static inline void svm_save_seg(target_phys_addr_t addr,
-#else /* VBOX */
-DECLINLINE(void) svm_save_seg(target_phys_addr_t addr,
-#endif /* VBOX */
const SegmentCache *sc)
{
stw_phys(addr + offsetof(struct vmcb_seg, selector),
@@ -6165,11 +6166,7 @@ DECLINLINE(void) svm_save_seg(target_phys_addr_t addr,
((sc->flags >> 8) & 0xff) | ((sc->flags >> 12) & 0x0f00));
}
-#ifndef VBOX
static inline void svm_load_seg(target_phys_addr_t addr, SegmentCache *sc)
-#else /* VBOX */
-DECLINLINE(void) svm_load_seg(target_phys_addr_t addr, SegmentCache *sc)
-#endif /* VBOX */
{
unsigned int flags;
@@ -6180,11 +6177,7 @@ DECLINLINE(void) svm_load_seg(target_phys_addr_t addr, SegmentCache *sc)
sc->flags = ((flags & 0xff) << 8) | ((flags & 0x0f00) << 12);
}
-#ifndef VBOX
static inline void svm_load_seg_cache(target_phys_addr_t addr,
-#else /* VBOX */
-DECLINLINE(void) svm_load_seg_cache(target_phys_addr_t addr,
-#endif /* VBOX */
CPUState *env, int seg_reg)
{
SegmentCache sc1, *sc = &sc1;
@@ -6206,8 +6199,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
else
addr = (uint32_t)EAX;
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile,"vmrun! " TARGET_FMT_lx "\n", addr);
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmrun! " TARGET_FMT_lx "\n", addr);
env->vm_vmcb = addr;
@@ -6325,10 +6317,8 @@ void helper_vmrun(int aflag, int next_eip_addend)
uint8_t vector = event_inj & SVM_EVTINJ_VEC_MASK;
uint16_t valid_err = event_inj & SVM_EVTINJ_VALID_ERR;
uint32_t event_inj_err = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err));
- stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj & ~SVM_EVTINJ_VALID);
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile, "Injecting(%#hx): ", valid_err);
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "Injecting(%#hx): ", valid_err);
/* FIXME: need to implement valid_err */
switch (event_inj & SVM_EVTINJ_TYPE_MASK) {
case SVM_EVTINJ_TYPE_INTR:
@@ -6336,8 +6326,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
env->error_code = event_inj_err;
env->exception_is_int = 0;
env->exception_next_eip = -1;
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile, "INTR");
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "INTR");
/* XXX: is it always correct ? */
do_interrupt(vector, 0, 0, 0, 1);
break;
@@ -6346,8 +6335,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
env->error_code = event_inj_err;
env->exception_is_int = 0;
env->exception_next_eip = EIP;
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile, "NMI");
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "NMI");
cpu_loop_exit();
break;
case SVM_EVTINJ_TYPE_EXEPT:
@@ -6355,8 +6343,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
env->error_code = event_inj_err;
env->exception_is_int = 0;
env->exception_next_eip = -1;
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile, "EXEPT");
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "EXEPT");
cpu_loop_exit();
break;
case SVM_EVTINJ_TYPE_SOFT:
@@ -6364,13 +6351,11 @@ void helper_vmrun(int aflag, int next_eip_addend)
env->error_code = event_inj_err;
env->exception_is_int = 1;
env->exception_next_eip = EIP;
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile, "SOFT");
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "SOFT");
cpu_loop_exit();
break;
}
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile, " %#x %#x\n", env->exception_index, env->error_code);
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", env->exception_index, env->error_code);
}
}
@@ -6390,8 +6375,7 @@ void helper_vmload(int aflag)
else
addr = (uint32_t)EAX;
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile,"vmload! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmload! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)),
env->segs[R_FS].base);
@@ -6426,8 +6410,7 @@ void helper_vmsave(int aflag)
else
addr = (uint32_t)EAX;
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile,"vmsave! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmsave! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)),
env->segs[R_FS].base);
@@ -6492,24 +6475,12 @@ void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
return;
#ifndef VBOX
switch(type) {
-#ifndef VBOX
case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
-#else
- case SVM_EXIT_READ_CR0: case SVM_EXIT_READ_CR0 + 1: case SVM_EXIT_READ_CR0 + 2:
- case SVM_EXIT_READ_CR0 + 3: case SVM_EXIT_READ_CR0 + 4: case SVM_EXIT_READ_CR0 + 5:
- case SVM_EXIT_READ_CR0 + 6: case SVM_EXIT_READ_CR0 + 7: case SVM_EXIT_READ_CR0 + 8:
-#endif
if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) {
helper_vmexit(type, param);
}
break;
-#ifndef VBOX
case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
-#else
- case SVM_EXIT_WRITE_CR0: case SVM_EXIT_WRITE_CR0 + 1: case SVM_EXIT_WRITE_CR0 + 2:
- case SVM_EXIT_WRITE_CR0 + 3: case SVM_EXIT_WRITE_CR0 + 4: case SVM_EXIT_WRITE_CR0 + 5:
- case SVM_EXIT_WRITE_CR0 + 6: case SVM_EXIT_WRITE_CR0 + 7: case SVM_EXIT_WRITE_CR0 + 8:
-#endif
if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) {
helper_vmexit(type, param);
}
@@ -6565,9 +6536,9 @@ void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
}
break;
}
-#else
+#else /* VBOX */
AssertMsgFailed(("We shouldn't be here, HWACCM supported differently!"));
-#endif
+#endif /* VBOX */
}
void helper_svm_check_io(uint32_t port, uint32_t param,
@@ -6591,8 +6562,7 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
{
uint32_t int_ctl;
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile,"vmexit(%08x, %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n",
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n",
exit_code, exit_info_1,
ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)),
EIP);
@@ -6688,6 +6658,12 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_code), exit_code);
stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1), exit_info_1);
+ stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info),
+ ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)));
+ stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info_err),
+ ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err)));
+ stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), 0);
+
env->hflags2 &= ~HF2_GIF_MASK;
/* FIXME: Resets the current ASID register to zero (host ASID). */
@@ -6738,9 +6714,9 @@ void helper_emms(void)
}
/* XXX: suppress */
-void helper_movq(uint64_t *d, uint64_t *s)
+void helper_movq(void *d, void *s)
{
- *d = *s;
+ *(uint64_t *)d = *(uint64_t *)s;
}
#define SHIFT 0
@@ -6784,11 +6760,14 @@ target_ulong helper_bsf(target_ulong t0)
return count;
}
-target_ulong helper_bsr(target_ulong t0)
+target_ulong helper_lzcnt(target_ulong t0, int wordsize)
{
int count;
target_ulong res, mask;
+ if (wordsize > 0 && t0 == 0) {
+ return wordsize;
+ }
res = t0;
count = TARGET_LONG_BITS - 1;
mask = (target_ulong)1 << (TARGET_LONG_BITS - 1);
@@ -6796,9 +6775,16 @@ target_ulong helper_bsr(target_ulong t0)
count--;
res <<= 1;
}
+ if (wordsize > 0) {
+ return wordsize - 1 - count;
+ }
return count;
}
+target_ulong helper_bsr(target_ulong t0)
+{
+ return helper_lzcnt(t0, 0);
+}
static int compute_all_eflags(void)
{
@@ -6810,169 +6796,144 @@ static int compute_c_eflags(void)
return CC_SRC & CC_C;
}
-#ifndef VBOX
-CCTable cc_table[CC_OP_NB] = {
- [CC_OP_DYNAMIC] = { /* should never happen */ },
+uint32_t helper_cc_compute_all(int op)
+{
+ switch (op) {
+ default: /* should never happen */ return 0;
- [CC_OP_EFLAGS] = { compute_all_eflags, compute_c_eflags },
+ case CC_OP_EFLAGS: return compute_all_eflags();
- [CC_OP_MULB] = { compute_all_mulb, compute_c_mull },
- [CC_OP_MULW] = { compute_all_mulw, compute_c_mull },
- [CC_OP_MULL] = { compute_all_mull, compute_c_mull },
+ case CC_OP_MULB: return compute_all_mulb();
+ case CC_OP_MULW: return compute_all_mulw();
+ case CC_OP_MULL: return compute_all_mull();
- [CC_OP_ADDB] = { compute_all_addb, compute_c_addb },
- [CC_OP_ADDW] = { compute_all_addw, compute_c_addw },
- [CC_OP_ADDL] = { compute_all_addl, compute_c_addl },
+ case CC_OP_ADDB: return compute_all_addb();
+ case CC_OP_ADDW: return compute_all_addw();
+ case CC_OP_ADDL: return compute_all_addl();
- [CC_OP_ADCB] = { compute_all_adcb, compute_c_adcb },
- [CC_OP_ADCW] = { compute_all_adcw, compute_c_adcw },
- [CC_OP_ADCL] = { compute_all_adcl, compute_c_adcl },
+ case CC_OP_ADCB: return compute_all_adcb();
+ case CC_OP_ADCW: return compute_all_adcw();
+ case CC_OP_ADCL: return compute_all_adcl();
- [CC_OP_SUBB] = { compute_all_subb, compute_c_subb },
- [CC_OP_SUBW] = { compute_all_subw, compute_c_subw },
- [CC_OP_SUBL] = { compute_all_subl, compute_c_subl },
+ case CC_OP_SUBB: return compute_all_subb();
+ case CC_OP_SUBW: return compute_all_subw();
+ case CC_OP_SUBL: return compute_all_subl();
- [CC_OP_SBBB] = { compute_all_sbbb, compute_c_sbbb },
- [CC_OP_SBBW] = { compute_all_sbbw, compute_c_sbbw },
- [CC_OP_SBBL] = { compute_all_sbbl, compute_c_sbbl },
+ case CC_OP_SBBB: return compute_all_sbbb();
+ case CC_OP_SBBW: return compute_all_sbbw();
+ case CC_OP_SBBL: return compute_all_sbbl();
- [CC_OP_LOGICB] = { compute_all_logicb, compute_c_logicb },
- [CC_OP_LOGICW] = { compute_all_logicw, compute_c_logicw },
- [CC_OP_LOGICL] = { compute_all_logicl, compute_c_logicl },
+ case CC_OP_LOGICB: return compute_all_logicb();
+ case CC_OP_LOGICW: return compute_all_logicw();
+ case CC_OP_LOGICL: return compute_all_logicl();
- [CC_OP_INCB] = { compute_all_incb, compute_c_incl },
- [CC_OP_INCW] = { compute_all_incw, compute_c_incl },
- [CC_OP_INCL] = { compute_all_incl, compute_c_incl },
+ case CC_OP_INCB: return compute_all_incb();
+ case CC_OP_INCW: return compute_all_incw();
+ case CC_OP_INCL: return compute_all_incl();
- [CC_OP_DECB] = { compute_all_decb, compute_c_incl },
- [CC_OP_DECW] = { compute_all_decw, compute_c_incl },
- [CC_OP_DECL] = { compute_all_decl, compute_c_incl },
+ case CC_OP_DECB: return compute_all_decb();
+ case CC_OP_DECW: return compute_all_decw();
+ case CC_OP_DECL: return compute_all_decl();
- [CC_OP_SHLB] = { compute_all_shlb, compute_c_shlb },
- [CC_OP_SHLW] = { compute_all_shlw, compute_c_shlw },
- [CC_OP_SHLL] = { compute_all_shll, compute_c_shll },
+ case CC_OP_SHLB: return compute_all_shlb();
+ case CC_OP_SHLW: return compute_all_shlw();
+ case CC_OP_SHLL: return compute_all_shll();
- [CC_OP_SARB] = { compute_all_sarb, compute_c_sarl },
- [CC_OP_SARW] = { compute_all_sarw, compute_c_sarl },
- [CC_OP_SARL] = { compute_all_sarl, compute_c_sarl },
+ case CC_OP_SARB: return compute_all_sarb();
+ case CC_OP_SARW: return compute_all_sarw();
+ case CC_OP_SARL: return compute_all_sarl();
#ifdef TARGET_X86_64
- [CC_OP_MULQ] = { compute_all_mulq, compute_c_mull },
+ case CC_OP_MULQ: return compute_all_mulq();
- [CC_OP_ADDQ] = { compute_all_addq, compute_c_addq },
+ case CC_OP_ADDQ: return compute_all_addq();
- [CC_OP_ADCQ] = { compute_all_adcq, compute_c_adcq },
+ case CC_OP_ADCQ: return compute_all_adcq();
- [CC_OP_SUBQ] = { compute_all_subq, compute_c_subq },
+ case CC_OP_SUBQ: return compute_all_subq();
- [CC_OP_SBBQ] = { compute_all_sbbq, compute_c_sbbq },
+ case CC_OP_SBBQ: return compute_all_sbbq();
- [CC_OP_LOGICQ] = { compute_all_logicq, compute_c_logicq },
+ case CC_OP_LOGICQ: return compute_all_logicq();
- [CC_OP_INCQ] = { compute_all_incq, compute_c_incl },
+ case CC_OP_INCQ: return compute_all_incq();
- [CC_OP_DECQ] = { compute_all_decq, compute_c_incl },
+ case CC_OP_DECQ: return compute_all_decq();
- [CC_OP_SHLQ] = { compute_all_shlq, compute_c_shlq },
+ case CC_OP_SHLQ: return compute_all_shlq();
- [CC_OP_SARQ] = { compute_all_sarq, compute_c_sarl },
+ case CC_OP_SARQ: return compute_all_sarq();
#endif
-};
-#else /* VBOX */
-/* Sync carefully with cpu.h */
-CCTable cc_table[CC_OP_NB] = {
- /* CC_OP_DYNAMIC */ { 0, 0 },
+ }
+}
- /* CC_OP_EFLAGS */ { compute_all_eflags, compute_c_eflags },
+uint32_t helper_cc_compute_c(int op)
+{
+ switch (op) {
+ default: /* should never happen */ return 0;
- /* CC_OP_MULB */ { compute_all_mulb, compute_c_mull },
- /* CC_OP_MULW */ { compute_all_mulw, compute_c_mull },
- /* CC_OP_MULL */ { compute_all_mull, compute_c_mull },
-#ifdef TARGET_X86_64
- /* CC_OP_MULQ */ { compute_all_mulq, compute_c_mull },
-#else
- /* CC_OP_MULQ */ { 0, 0 },
-#endif
+ case CC_OP_EFLAGS: return compute_c_eflags();
- /* CC_OP_ADDB */ { compute_all_addb, compute_c_addb },
- /* CC_OP_ADDW */ { compute_all_addw, compute_c_addw },
- /* CC_OP_ADDL */ { compute_all_addl, compute_c_addl },
-#ifdef TARGET_X86_64
- /* CC_OP_ADDQ */ { compute_all_addq, compute_c_addq },
-#else
- /* CC_OP_ADDQ */ { 0, 0 },
-#endif
+ case CC_OP_MULB: return compute_c_mull();
+ case CC_OP_MULW: return compute_c_mull();
+ case CC_OP_MULL: return compute_c_mull();
- /* CC_OP_ADCB */ { compute_all_adcb, compute_c_adcb },
- /* CC_OP_ADCW */ { compute_all_adcw, compute_c_adcw },
- /* CC_OP_ADCL */ { compute_all_adcl, compute_c_adcl },
-#ifdef TARGET_X86_64
- /* CC_OP_ADCQ */ { compute_all_adcq, compute_c_adcq },
-#else
- /* CC_OP_ADCQ */ { 0, 0 },
-#endif
+ case CC_OP_ADDB: return compute_c_addb();
+ case CC_OP_ADDW: return compute_c_addw();
+ case CC_OP_ADDL: return compute_c_addl();
- /* CC_OP_SUBB */ { compute_all_subb, compute_c_subb },
- /* CC_OP_SUBW */ { compute_all_subw, compute_c_subw },
- /* CC_OP_SUBL */ { compute_all_subl, compute_c_subl },
-#ifdef TARGET_X86_64
- /* CC_OP_SUBQ */ { compute_all_subq, compute_c_subq },
-#else
- /* CC_OP_SUBQ */ { 0, 0 },
-#endif
+ case CC_OP_ADCB: return compute_c_adcb();
+ case CC_OP_ADCW: return compute_c_adcw();
+ case CC_OP_ADCL: return compute_c_adcl();
- /* CC_OP_SBBB */ { compute_all_sbbb, compute_c_sbbb },
- /* CC_OP_SBBW */ { compute_all_sbbw, compute_c_sbbw },
- /* CC_OP_SBBL */ { compute_all_sbbl, compute_c_sbbl },
-#ifdef TARGET_X86_64
- /* CC_OP_SBBQ */ { compute_all_sbbq, compute_c_sbbq },
-#else
- /* CC_OP_SBBQ */ { 0, 0 },
-#endif
+ case CC_OP_SUBB: return compute_c_subb();
+ case CC_OP_SUBW: return compute_c_subw();
+ case CC_OP_SUBL: return compute_c_subl();
- /* CC_OP_LOGICB */ { compute_all_logicb, compute_c_logicb },
- /* CC_OP_LOGICW */ { compute_all_logicw, compute_c_logicw },
- /* CC_OP_LOGICL */ { compute_all_logicl, compute_c_logicl },
-#ifdef TARGET_X86_64
- /* CC_OP_LOGICQ */ { compute_all_logicq, compute_c_logicq },
-#else
- /* CC_OP_LOGICQ */ { 0, 0 },
-#endif
+ case CC_OP_SBBB: return compute_c_sbbb();
+ case CC_OP_SBBW: return compute_c_sbbw();
+ case CC_OP_SBBL: return compute_c_sbbl();
- /* CC_OP_INCB */ { compute_all_incb, compute_c_incl },
- /* CC_OP_INCW */ { compute_all_incw, compute_c_incl },
- /* CC_OP_INCL */ { compute_all_incl, compute_c_incl },
-#ifdef TARGET_X86_64
- /* CC_OP_INCQ */ { compute_all_incq, compute_c_incl },
-#else
- /* CC_OP_INCQ */ { 0, 0 },
-#endif
+ case CC_OP_LOGICB: return compute_c_logicb();
+ case CC_OP_LOGICW: return compute_c_logicw();
+ case CC_OP_LOGICL: return compute_c_logicl();
- /* CC_OP_DECB */ { compute_all_decb, compute_c_incl },
- /* CC_OP_DECW */ { compute_all_decw, compute_c_incl },
- /* CC_OP_DECL */ { compute_all_decl, compute_c_incl },
-#ifdef TARGET_X86_64
- /* CC_OP_DECQ */ { compute_all_decq, compute_c_incl },
-#else
- /* CC_OP_DECQ */ { 0, 0 },
-#endif
+ case CC_OP_INCB: return compute_c_incl();
+ case CC_OP_INCW: return compute_c_incl();
+ case CC_OP_INCL: return compute_c_incl();
- /* CC_OP_SHLB */ { compute_all_shlb, compute_c_shlb },
- /* CC_OP_SHLW */ { compute_all_shlw, compute_c_shlw },
- /* CC_OP_SHLL */ { compute_all_shll, compute_c_shll },
-#ifdef TARGET_X86_64
- /* CC_OP_SHLQ */ { compute_all_shlq, compute_c_shlq },
-#else
- /* CC_OP_SHLQ */ { 0, 0 },
-#endif
+ case CC_OP_DECB: return compute_c_incl();
+ case CC_OP_DECW: return compute_c_incl();
+ case CC_OP_DECL: return compute_c_incl();
+
+ case CC_OP_SHLB: return compute_c_shlb();
+ case CC_OP_SHLW: return compute_c_shlw();
+ case CC_OP_SHLL: return compute_c_shll();
+
+ case CC_OP_SARB: return compute_c_sarl();
+ case CC_OP_SARW: return compute_c_sarl();
+ case CC_OP_SARL: return compute_c_sarl();
- /* CC_OP_SARB */ { compute_all_sarb, compute_c_sarl },
- /* CC_OP_SARW */ { compute_all_sarw, compute_c_sarl },
- /* CC_OP_SARL */ { compute_all_sarl, compute_c_sarl },
#ifdef TARGET_X86_64
- /* CC_OP_SARQ */ { compute_all_sarq, compute_c_sarl},
-#else
- /* CC_OP_SARQ */ { 0, 0 },
+ case CC_OP_MULQ: return compute_c_mull();
+
+ case CC_OP_ADDQ: return compute_c_addq();
+
+ case CC_OP_ADCQ: return compute_c_adcq();
+
+ case CC_OP_SUBQ: return compute_c_subq();
+
+ case CC_OP_SBBQ: return compute_c_sbbq();
+
+ case CC_OP_LOGICQ: return compute_c_logicq();
+
+ case CC_OP_INCQ: return compute_c_incl();
+
+ case CC_OP_DECQ: return compute_c_incl();
+
+ case CC_OP_SHLQ: return compute_c_shlq();
+
+ case CC_OP_SARQ: return compute_c_sarl();
#endif
-};
-#endif /* VBOX */
+ }
+}
diff --git a/src/recompiler/target-i386/opreg_template.h b/src/recompiler/target-i386/opreg_template.h
deleted file mode 100644
index e48c40571..000000000
--- a/src/recompiler/target-i386/opreg_template.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * i386 micro operations (templates for various register related
- * operations)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * 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.
- */
-
-void OPPROTO glue(op_movl_A0,REGNAME)(void)
-{
- A0 = (uint32_t)REG;
-}
-
-void OPPROTO glue(op_addl_A0,REGNAME)(void)
-{
- A0 = (uint32_t)(A0 + REG);
-}
-
-void OPPROTO glue(glue(op_addl_A0,REGNAME),_s1)(void)
-{
- A0 = (uint32_t)(A0 + (REG << 1));
-}
-
-void OPPROTO glue(glue(op_addl_A0,REGNAME),_s2)(void)
-{
- A0 = (uint32_t)(A0 + (REG << 2));
-}
-
-void OPPROTO glue(glue(op_addl_A0,REGNAME),_s3)(void)
-{
- A0 = (uint32_t)(A0 + (REG << 3));
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO glue(op_movq_A0,REGNAME)(void)
-{
- A0 = REG;
-}
-
-void OPPROTO glue(op_addq_A0,REGNAME)(void)
-{
- A0 = (A0 + REG);
-}
-
-void OPPROTO glue(glue(op_addq_A0,REGNAME),_s1)(void)
-{
- A0 = (A0 + (REG << 1));
-}
-
-void OPPROTO glue(glue(op_addq_A0,REGNAME),_s2)(void)
-{
- A0 = (A0 + (REG << 2));
-}
-
-void OPPROTO glue(glue(op_addq_A0,REGNAME),_s3)(void)
-{
- A0 = (A0 + (REG << 3));
-}
-#endif
-
-void OPPROTO glue(op_movl_T0,REGNAME)(void)
-{
- T0 = REG;
-}
-
-void OPPROTO glue(op_movl_T1,REGNAME)(void)
-{
- T1 = REG;
-}
-
-void OPPROTO glue(op_movh_T0,REGNAME)(void)
-{
- T0 = REG >> 8;
-}
-
-void OPPROTO glue(op_movh_T1,REGNAME)(void)
-{
- T1 = REG >> 8;
-}
-
-void OPPROTO glue(glue(op_movl,REGNAME),_T0)(void)
-{
- REG = (uint32_t)T0;
-}
-
-void OPPROTO glue(glue(op_movl,REGNAME),_T1)(void)
-{
- REG = (uint32_t)T1;
-}
-
-void OPPROTO glue(glue(op_movl,REGNAME),_A0)(void)
-{
- REG = (uint32_t)A0;
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO glue(glue(op_movq,REGNAME),_T0)(void)
-{
- REG = T0;
-}
-
-void OPPROTO glue(glue(op_movq,REGNAME),_T1)(void)
-{
- REG = T1;
-}
-
-void OPPROTO glue(glue(op_movq,REGNAME),_A0)(void)
-{
- REG = A0;
-}
-#endif
-
-/* mov T1 to REG if T0 is true */
-void OPPROTO glue(glue(op_cmovw,REGNAME),_T1_T0)(void)
-{
- if (T0)
- REG = (REG & ~0xffff) | (T1 & 0xffff);
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_cmovl,REGNAME),_T1_T0)(void)
-{
- if (T0)
- REG = (uint32_t)T1;
- FORCE_RET();
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO glue(glue(op_cmovq,REGNAME),_T1_T0)(void)
-{
- if (T0)
- REG = T1;
- FORCE_RET();
-}
-#endif
-
-/* NOTE: T0 high order bits are ignored */
-void OPPROTO glue(glue(op_movw,REGNAME),_T0)(void)
-{
- REG = (REG & ~0xffff) | (T0 & 0xffff);
-}
-
-/* NOTE: T0 high order bits are ignored */
-void OPPROTO glue(glue(op_movw,REGNAME),_T1)(void)
-{
- REG = (REG & ~0xffff) | (T1 & 0xffff);
-}
-
-/* NOTE: A0 high order bits are ignored */
-void OPPROTO glue(glue(op_movw,REGNAME),_A0)(void)
-{
- REG = (REG & ~0xffff) | (A0 & 0xffff);
-}
-
-/* NOTE: T0 high order bits are ignored */
-void OPPROTO glue(glue(op_movb,REGNAME),_T0)(void)
-{
- REG = (REG & ~0xff) | (T0 & 0xff);
-}
-
-/* NOTE: T0 high order bits are ignored */
-void OPPROTO glue(glue(op_movh,REGNAME),_T0)(void)
-{
- REG = (REG & ~0xff00) | ((T0 & 0xff) << 8);
-}
-
-/* NOTE: T1 high order bits are ignored */
-void OPPROTO glue(glue(op_movb,REGNAME),_T1)(void)
-{
- REG = (REG & ~0xff) | (T1 & 0xff);
-}
-
-/* NOTE: T1 high order bits are ignored */
-void OPPROTO glue(glue(op_movh,REGNAME),_T1)(void)
-{
- REG = (REG & ~0xff00) | ((T1 & 0xff) << 8);
-}
-
diff --git a/src/recompiler/target-i386/ops_mem.h b/src/recompiler/target-i386/ops_mem.h
deleted file mode 100644
index 7ec84dde8..000000000
--- a/src/recompiler/target-i386/ops_mem.h
+++ /dev/null
@@ -1,156 +0,0 @@
-void OPPROTO glue(glue(op_ldub, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = glue(ldub, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldsb, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = glue(ldsb, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_lduw, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = glue(lduw, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldsw, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = glue(ldsw, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldl, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = (uint32_t)glue(ldl, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldub, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = glue(ldub, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldsb, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = glue(ldsb, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_lduw, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = glue(lduw, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldsw, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = glue(ldsw, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldl, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = (uint32_t)glue(ldl, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_stb, MEMSUFFIX), _T0_A0)(void)
-{
- glue(stb, MEMSUFFIX)(A0, T0);
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_stw, MEMSUFFIX), _T0_A0)(void)
-{
- glue(stw, MEMSUFFIX)(A0, T0);
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_stl, MEMSUFFIX), _T0_A0)(void)
-{
- glue(stl, MEMSUFFIX)(A0, T0);
- FORCE_RET();
-}
-
-#if 0
-void OPPROTO glue(glue(op_stb, MEMSUFFIX), _T1_A0)(void)
-{
- glue(stb, MEMSUFFIX)(A0, T1);
- FORCE_RET();
-}
-#endif
-
-void OPPROTO glue(glue(op_stw, MEMSUFFIX), _T1_A0)(void)
-{
- glue(stw, MEMSUFFIX)(A0, T1);
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_stl, MEMSUFFIX), _T1_A0)(void)
-{
- glue(stl, MEMSUFFIX)(A0, T1);
- FORCE_RET();
-}
-
-/* SSE/MMX support */
-void OPPROTO glue(glue(op_ldq, MEMSUFFIX), _env_A0)(void)
-{
- uint64_t *p;
- p = (uint64_t *)((char *)env + PARAM1);
- *p = glue(ldq, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_stq, MEMSUFFIX), _env_A0)(void)
-{
- uint64_t *p;
- p = (uint64_t *)((char *)env + PARAM1);
- glue(stq, MEMSUFFIX)(A0, *p);
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_ldo, MEMSUFFIX), _env_A0)(void)
-{
- XMMReg *p;
- p = (XMMReg *)((char *)env + PARAM1);
- p->XMM_Q(0) = glue(ldq, MEMSUFFIX)(A0);
- p->XMM_Q(1) = glue(ldq, MEMSUFFIX)(A0 + 8);
-}
-
-void OPPROTO glue(glue(op_sto, MEMSUFFIX), _env_A0)(void)
-{
- XMMReg *p;
- p = (XMMReg *)((char *)env + PARAM1);
- glue(stq, MEMSUFFIX)(A0, p->XMM_Q(0));
- glue(stq, MEMSUFFIX)(A0 + 8, p->XMM_Q(1));
- FORCE_RET();
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO glue(glue(op_ldsl, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = (int32_t)glue(ldl, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldsl, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = (int32_t)glue(ldl, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldq, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = glue(ldq, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldq, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = glue(ldq, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_stq, MEMSUFFIX), _T0_A0)(void)
-{
- glue(stq, MEMSUFFIX)(A0, T0);
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_stq, MEMSUFFIX), _T1_A0)(void)
-{
- glue(stq, MEMSUFFIX)(A0, T1);
- FORCE_RET();
-}
-#endif
-
-#undef MEMSUFFIX
diff --git a/src/recompiler/target-i386/ops_sse.h b/src/recompiler/target-i386/ops_sse.h
index 1d85be5ff..65078e93f 100644
--- a/src/recompiler/target-i386/ops_sse.h
+++ b/src/recompiler/target-i386/ops_sse.h
@@ -15,8 +15,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -30,11 +29,7 @@
#if SHIFT == 0
#define Reg MMXReg
-#ifndef VBOX
-#define XMM_ONLY(x...)
-#else
-#define XMM_ONLY(x)
-#endif
+#define XMM_ONLY(...)
#define B(n) MMX_B(n)
#define W(n) MMX_W(n)
#define L(n) MMX_L(n)
@@ -42,11 +37,7 @@
#define SUFFIX _mmx
#else
#define Reg XMMReg
-#ifndef VBOX
-#define XMM_ONLY(x...) x
-#else
-#define XMM_ONLY(x) x
-#endif
+#define XMM_ONLY(...) __VA_ARGS__
#define B(n) XMM_B(n)
#define W(n) XMM_W(n)
#define L(n) XMM_L(n)
@@ -303,11 +294,7 @@ void glue(name, SUFFIX) (Reg *d, Reg *s)\
}
#if SHIFT == 0
-#ifndef VBOX
static inline int satub(int x)
-#else /* VBOX */
-DECLINLINE(int) satub(int x)
-#endif /* VBOX */
{
if (x < 0)
return 0;
@@ -317,11 +304,7 @@ DECLINLINE(int) satub(int x)
return x;
}
-#ifndef VBOX
static inline int satuw(int x)
-#else /* VBOX */
-DECLINLINE(int) satuw(int x)
-#endif /* VBOX */
{
if (x < 0)
return 0;
@@ -331,11 +314,7 @@ DECLINLINE(int) satuw(int x)
return x;
}
-#ifndef VBOX
static inline int satsb(int x)
-#else /* VBOX */
-DECLINLINE(int) satsb(int x)
-#endif /* VBOX */
{
if (x < -128)
return -128;
@@ -345,11 +324,7 @@ DECLINLINE(int) satsb(int x)
return x;
}
-#ifndef VBOX
static inline int satsw(int x)
-#else /* VBOX */
-DECLINLINE(int) satsw(int x)
-#endif /* VBOX */
{
if (x < -32768)
return -32768;
@@ -461,11 +436,7 @@ void glue(helper_pmaddwd, SUFFIX) (Reg *d, Reg *s)
}
#if SHIFT == 0
-#ifndef VBOX
static inline int abs1(int a)
-#else /* VBOX */
-DECLINLINE(int) abs1(int a)
-#endif /* VBOX */
{
if (a < 0)
return -a;
@@ -841,6 +812,50 @@ void helper_rcpss(XMMReg *d, XMMReg *s)
d->XMM_S(0) = approx_rcp(s->XMM_S(0));
}
+static inline uint64_t helper_extrq(uint64_t src, int shift, int len)
+{
+ uint64_t mask;
+
+ if (len == 0) {
+ mask = ~0LL;
+ } else {
+ mask = (1ULL << len) - 1;
+ }
+ return (src >> shift) & mask;
+}
+
+void helper_extrq_r(XMMReg *d, XMMReg *s)
+{
+ d->XMM_Q(0) = helper_extrq(d->XMM_Q(0), s->XMM_B(1), s->XMM_B(0));
+}
+
+void helper_extrq_i(XMMReg *d, int index, int length)
+{
+ d->XMM_Q(0) = helper_extrq(d->XMM_Q(0), index, length);
+}
+
+static inline uint64_t helper_insertq(uint64_t src, int shift, int len)
+{
+ uint64_t mask;
+
+ if (len == 0) {
+ mask = ~0ULL;
+ } else {
+ mask = (1ULL << len) - 1;
+ }
+ return (src & ~(mask << shift)) | ((src & mask) << shift);
+}
+
+void helper_insertq_r(XMMReg *d, XMMReg *s)
+{
+ d->XMM_Q(0) = helper_insertq(s->XMM_Q(0), s->XMM_B(9), s->XMM_B(8));
+}
+
+void helper_insertq_i(XMMReg *d, int index, int length)
+{
+ d->XMM_Q(0) = helper_insertq(d->XMM_Q(0), index, length);
+}
+
void helper_haddps(XMMReg *d, XMMReg *s)
{
XMMReg r;
@@ -934,7 +949,7 @@ SSE_HELPER_CMP(cmpnlt, FPU_CMPNLT)
SSE_HELPER_CMP(cmpnle, FPU_CMPNLE)
SSE_HELPER_CMP(cmpord, FPU_CMPORD)
-const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
+static const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
void helper_ucomiss(Reg *d, Reg *s)
{
@@ -1004,23 +1019,23 @@ uint32_t glue(helper_pmovmskb, SUFFIX)(Reg *s)
{
uint32_t val;
val = 0;
- val |= (s->XMM_B(0) >> 7);
- val |= (s->XMM_B(1) >> 6) & 0x02;
- val |= (s->XMM_B(2) >> 5) & 0x04;
- val |= (s->XMM_B(3) >> 4) & 0x08;
- val |= (s->XMM_B(4) >> 3) & 0x10;
- val |= (s->XMM_B(5) >> 2) & 0x20;
- val |= (s->XMM_B(6) >> 1) & 0x40;
- val |= (s->XMM_B(7)) & 0x80;
+ val |= (s->B(0) >> 7);
+ val |= (s->B(1) >> 6) & 0x02;
+ val |= (s->B(2) >> 5) & 0x04;
+ val |= (s->B(3) >> 4) & 0x08;
+ val |= (s->B(4) >> 3) & 0x10;
+ val |= (s->B(5) >> 2) & 0x20;
+ val |= (s->B(6) >> 1) & 0x40;
+ val |= (s->B(7)) & 0x80;
#if SHIFT == 1
- val |= (s->XMM_B(8) << 1) & 0x0100;
- val |= (s->XMM_B(9) << 2) & 0x0200;
- val |= (s->XMM_B(10) << 3) & 0x0400;
- val |= (s->XMM_B(11) << 4) & 0x0800;
- val |= (s->XMM_B(12) << 5) & 0x1000;
- val |= (s->XMM_B(13) << 6) & 0x2000;
- val |= (s->XMM_B(14) << 7) & 0x4000;
- val |= (s->XMM_B(15) << 8) & 0x8000;
+ val |= (s->B(8) << 1) & 0x0100;
+ val |= (s->B(9) << 2) & 0x0200;
+ val |= (s->B(10) << 3) & 0x0400;
+ val |= (s->B(11) << 4) & 0x0800;
+ val |= (s->B(12) << 5) & 0x1000;
+ val |= (s->B(13) << 6) & 0x2000;
+ val |= (s->B(14) << 7) & 0x4000;
+ val |= (s->B(15) << 8) & 0x8000;
#endif
return val;
}
@@ -1816,11 +1831,7 @@ void glue(helper_mpsadbw, SUFFIX) (Reg *d, Reg *s, uint32_t offset)
#define FCMPGTQ(d, s) d > s ? -1 : 0
SSE_HELPER_Q(helper_pcmpgtq, FCMPGTQ)
-#ifndef VBOX
static inline int pcmp_elen(int reg, uint32_t ctrl)
-#else /* VBOX */
-DECLINLINE(int) pcmp_elen(int reg, uint32_t ctrl)
-#endif /* VBOX */
{
int val;
@@ -1840,11 +1851,7 @@ DECLINLINE(int) pcmp_elen(int reg, uint32_t ctrl)
return val;
}
-#ifndef VBOX
static inline int pcmp_ilen(Reg *r, uint8_t ctrl)
-#else /* VBOX */
-DECLINLINE(int) pcmp_ilen(Reg *r, uint8_t ctrl)
-#endif /* VBOX */
{
int val = 0;
@@ -1858,11 +1865,7 @@ DECLINLINE(int) pcmp_ilen(Reg *r, uint8_t ctrl)
return val;
}
-#ifndef VBOX
static inline int pcmp_val(Reg *r, uint8_t ctrl, int i)
-#else /* VBOX */
-DECLINLINE(int) pcmp_val(Reg *r, uint8_t ctrl, int i)
-#endif /* VBOX */
{
switch ((ctrl >> 0) & 3) {
case 0:
@@ -1877,11 +1880,7 @@ DECLINLINE(int) pcmp_val(Reg *r, uint8_t ctrl, int i)
}
}
-#ifndef VBOX
static inline unsigned pcmpxstrx(Reg *d, Reg *s,
-#else /* VBOX */
-DECLINLINE(unsigned) pcmpxstrx(Reg *d, Reg *s,
-#endif /* VBOX */
int8_t ctrl, int valids, int validd)
{
unsigned int res = 0;
@@ -1948,11 +1947,7 @@ DECLINLINE(unsigned) pcmpxstrx(Reg *d, Reg *s,
return res;
}
-#ifndef VBOX
static inline int rffs1(unsigned int val)
-#else /* VBOX */
-DECLINLINE(int) rffs1(unsigned int val)
-#endif /* VBOX */
{
int ret = 1, hi;
@@ -1965,11 +1960,7 @@ DECLINLINE(int) rffs1(unsigned int val)
return ret;
}
-#ifndef VBOX
static inline int ffs1(unsigned int val)
-#else /* VBOX */
-DECLINLINE(int) ffs1(unsigned int val)
-#endif /* VBOX */
{
int ret = 1, hi;
diff --git a/src/recompiler/target-i386/ops_sse_header.h b/src/recompiler/target-i386/ops_sse_header.h
index 5f24942cb..efa3e9052 100644
--- a/src/recompiler/target-i386/ops_sse_header.h
+++ b/src/recompiler/target-i386/ops_sse_header.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -35,99 +34,109 @@
#define SUFFIX _xmm
#endif
-DEF_HELPER(void, glue(helper_psrlw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_psraw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_psllw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_psrld, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_psrad, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pslld, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_psrlq, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_psllq, SUFFIX), (Reg *d, Reg *s))
+#define dh_alias_Reg ptr
+#define dh_alias_XMMReg ptr
+#define dh_alias_MMXReg ptr
+#define dh_ctype_Reg Reg *
+#define dh_ctype_XMMReg XMMReg *
+#define dh_ctype_MMXReg MMXReg *
+#define dh_is_signed_Reg dh_is_signed_ptr
+#define dh_is_signed_XMMReg dh_is_signed_ptr
+#define dh_is_signed_MMXReg dh_is_signed_ptr
+
+DEF_HELPER_2(glue(psrlw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(psraw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(psllw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(psrld, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(psrad, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pslld, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(psrlq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(psllq, SUFFIX), void, Reg, Reg)
#if SHIFT == 1
-DEF_HELPER(void, glue(helper_psrldq, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pslldq, SUFFIX), (Reg *d, Reg *s))
+DEF_HELPER_2(glue(psrldq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pslldq, SUFFIX), void, Reg, Reg)
#endif
#define SSE_HELPER_B(name, F)\
- DEF_HELPER(void, glue(name, SUFFIX), (Reg *d, Reg *s))
+ DEF_HELPER_2(glue(name, SUFFIX), void, Reg, Reg)
#define SSE_HELPER_W(name, F)\
- DEF_HELPER(void, glue(name, SUFFIX), (Reg *d, Reg *s))
+ DEF_HELPER_2(glue(name, SUFFIX), void, Reg, Reg)
#define SSE_HELPER_L(name, F)\
- DEF_HELPER(void, glue(name, SUFFIX), (Reg *d, Reg *s))
+ DEF_HELPER_2(glue(name, SUFFIX), void, Reg, Reg)
#define SSE_HELPER_Q(name, F)\
- DEF_HELPER(void, glue(name, SUFFIX), (Reg *d, Reg *s))
+ DEF_HELPER_2(glue(name, SUFFIX), void, Reg, Reg)
-SSE_HELPER_B(helper_paddb, FADD)
-SSE_HELPER_W(helper_paddw, FADD)
-SSE_HELPER_L(helper_paddl, FADD)
-SSE_HELPER_Q(helper_paddq, FADD)
+SSE_HELPER_B(paddb, FADD)
+SSE_HELPER_W(paddw, FADD)
+SSE_HELPER_L(paddl, FADD)
+SSE_HELPER_Q(paddq, FADD)
-SSE_HELPER_B(helper_psubb, FSUB)
-SSE_HELPER_W(helper_psubw, FSUB)
-SSE_HELPER_L(helper_psubl, FSUB)
-SSE_HELPER_Q(helper_psubq, FSUB)
+SSE_HELPER_B(psubb, FSUB)
+SSE_HELPER_W(psubw, FSUB)
+SSE_HELPER_L(psubl, FSUB)
+SSE_HELPER_Q(psubq, FSUB)
-SSE_HELPER_B(helper_paddusb, FADDUB)
-SSE_HELPER_B(helper_paddsb, FADDSB)
-SSE_HELPER_B(helper_psubusb, FSUBUB)
-SSE_HELPER_B(helper_psubsb, FSUBSB)
+SSE_HELPER_B(paddusb, FADDUB)
+SSE_HELPER_B(paddsb, FADDSB)
+SSE_HELPER_B(psubusb, FSUBUB)
+SSE_HELPER_B(psubsb, FSUBSB)
-SSE_HELPER_W(helper_paddusw, FADDUW)
-SSE_HELPER_W(helper_paddsw, FADDSW)
-SSE_HELPER_W(helper_psubusw, FSUBUW)
-SSE_HELPER_W(helper_psubsw, FSUBSW)
+SSE_HELPER_W(paddusw, FADDUW)
+SSE_HELPER_W(paddsw, FADDSW)
+SSE_HELPER_W(psubusw, FSUBUW)
+SSE_HELPER_W(psubsw, FSUBSW)
-SSE_HELPER_B(helper_pminub, FMINUB)
-SSE_HELPER_B(helper_pmaxub, FMAXUB)
+SSE_HELPER_B(pminub, FMINUB)
+SSE_HELPER_B(pmaxub, FMAXUB)
-SSE_HELPER_W(helper_pminsw, FMINSW)
-SSE_HELPER_W(helper_pmaxsw, FMAXSW)
+SSE_HELPER_W(pminsw, FMINSW)
+SSE_HELPER_W(pmaxsw, FMAXSW)
-SSE_HELPER_Q(helper_pand, FAND)
-SSE_HELPER_Q(helper_pandn, FANDN)
-SSE_HELPER_Q(helper_por, FOR)
-SSE_HELPER_Q(helper_pxor, FXOR)
+SSE_HELPER_Q(pand, FAND)
+SSE_HELPER_Q(pandn, FANDN)
+SSE_HELPER_Q(por, FOR)
+SSE_HELPER_Q(pxor, FXOR)
-SSE_HELPER_B(helper_pcmpgtb, FCMPGTB)
-SSE_HELPER_W(helper_pcmpgtw, FCMPGTW)
-SSE_HELPER_L(helper_pcmpgtl, FCMPGTL)
+SSE_HELPER_B(pcmpgtb, FCMPGTB)
+SSE_HELPER_W(pcmpgtw, FCMPGTW)
+SSE_HELPER_L(pcmpgtl, FCMPGTL)
-SSE_HELPER_B(helper_pcmpeqb, FCMPEQ)
-SSE_HELPER_W(helper_pcmpeqw, FCMPEQ)
-SSE_HELPER_L(helper_pcmpeql, FCMPEQ)
+SSE_HELPER_B(pcmpeqb, FCMPEQ)
+SSE_HELPER_W(pcmpeqw, FCMPEQ)
+SSE_HELPER_L(pcmpeql, FCMPEQ)
-SSE_HELPER_W(helper_pmullw, FMULLW)
+SSE_HELPER_W(pmullw, FMULLW)
#if SHIFT == 0
-SSE_HELPER_W(helper_pmulhrw, FMULHRW)
+SSE_HELPER_W(pmulhrw, FMULHRW)
#endif
-SSE_HELPER_W(helper_pmulhuw, FMULHUW)
-SSE_HELPER_W(helper_pmulhw, FMULHW)
+SSE_HELPER_W(pmulhuw, FMULHUW)
+SSE_HELPER_W(pmulhw, FMULHW)
-SSE_HELPER_B(helper_pavgb, FAVG)
-SSE_HELPER_W(helper_pavgw, FAVG)
+SSE_HELPER_B(pavgb, FAVG)
+SSE_HELPER_W(pavgw, FAVG)
-DEF_HELPER(void, glue(helper_pmuludq, SUFFIX) , (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmaddwd, SUFFIX) , (Reg *d, Reg *s))
+DEF_HELPER_2(glue(pmuludq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmaddwd, SUFFIX), void, Reg, Reg)
-DEF_HELPER(void, glue(helper_psadbw, SUFFIX) , (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_maskmov, SUFFIX) , (Reg *d, Reg *s, target_ulong a0))
-DEF_HELPER(void, glue(helper_movl_mm_T0, SUFFIX) , (Reg *d, uint32_t val))
+DEF_HELPER_2(glue(psadbw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_3(glue(maskmov, SUFFIX), void, Reg, Reg, tl)
+DEF_HELPER_2(glue(movl_mm_T0, SUFFIX), void, Reg, i32)
#ifdef TARGET_X86_64
-DEF_HELPER(void, glue(helper_movq_mm_T0, SUFFIX) , (Reg *d, uint64_t val))
+DEF_HELPER_2(glue(movq_mm_T0, SUFFIX), void, Reg, i64)
#endif
#if SHIFT == 0
-DEF_HELPER(void, glue(helper_pshufw, SUFFIX) , (Reg *d, Reg *s, int order))
+DEF_HELPER_3(glue(pshufw, SUFFIX), void, Reg, Reg, int)
#else
-DEF_HELPER(void, helper_shufps, (Reg *d, Reg *s, int order))
-DEF_HELPER(void, helper_shufpd, (Reg *d, Reg *s, int order))
-DEF_HELPER(void, glue(helper_pshufd, SUFFIX) , (Reg *d, Reg *s, int order))
-DEF_HELPER(void, glue(helper_pshuflw, SUFFIX) , (Reg *d, Reg *s, int order))
-DEF_HELPER(void, glue(helper_pshufhw, SUFFIX) , (Reg *d, Reg *s, int order))
+DEF_HELPER_3(shufps, void, Reg, Reg, int)
+DEF_HELPER_3(shufpd, void, Reg, Reg, int)
+DEF_HELPER_3(glue(pshufd, SUFFIX), void, Reg, Reg, int)
+DEF_HELPER_3(glue(pshuflw, SUFFIX), void, Reg, Reg, int)
+DEF_HELPER_3(glue(pshufhw, SUFFIX), void, Reg, Reg, int)
#endif
#if SHIFT == 1
@@ -135,10 +144,10 @@ DEF_HELPER(void, glue(helper_pshufhw, SUFFIX) , (Reg *d, Reg *s, int order))
/* XXX: not accurate */
#define SSE_HELPER_S(name, F)\
- DEF_HELPER(void, helper_ ## name ## ps , (Reg *d, Reg *s)) \
- DEF_HELPER(void, helper_ ## name ## ss , (Reg *d, Reg *s)) \
- DEF_HELPER(void, helper_ ## name ## pd , (Reg *d, Reg *s)) \
- DEF_HELPER(void, helper_ ## name ## sd , (Reg *d, Reg *s))
+ DEF_HELPER_2(name ## ps , void, Reg, Reg) \
+ DEF_HELPER_2(name ## ss , void, Reg, Reg) \
+ DEF_HELPER_2(name ## pd , void, Reg, Reg) \
+ DEF_HELPER_2(name ## sd , void, Reg, Reg)
SSE_HELPER_S(add, FPU_ADD)
SSE_HELPER_S(sub, FPU_SUB)
@@ -149,60 +158,64 @@ SSE_HELPER_S(max, FPU_MAX)
SSE_HELPER_S(sqrt, FPU_SQRT)
-DEF_HELPER(void, helper_cvtps2pd, (Reg *d, Reg *s))
-DEF_HELPER(void, helper_cvtpd2ps, (Reg *d, Reg *s))
-DEF_HELPER(void, helper_cvtss2sd, (Reg *d, Reg *s))
-DEF_HELPER(void, helper_cvtsd2ss, (Reg *d, Reg *s))
-DEF_HELPER(void, helper_cvtdq2ps, (Reg *d, Reg *s))
-DEF_HELPER(void, helper_cvtdq2pd, (Reg *d, Reg *s))
-DEF_HELPER(void, helper_cvtpi2ps, (XMMReg *d, MMXReg *s))
-DEF_HELPER(void, helper_cvtpi2pd, (XMMReg *d, MMXReg *s))
-DEF_HELPER(void, helper_cvtsi2ss, (XMMReg *d, uint32_t val))
-DEF_HELPER(void, helper_cvtsi2sd, (XMMReg *d, uint32_t val))
+DEF_HELPER_2(cvtps2pd, void, Reg, Reg)
+DEF_HELPER_2(cvtpd2ps, void, Reg, Reg)
+DEF_HELPER_2(cvtss2sd, void, Reg, Reg)
+DEF_HELPER_2(cvtsd2ss, void, Reg, Reg)
+DEF_HELPER_2(cvtdq2ps, void, Reg, Reg)
+DEF_HELPER_2(cvtdq2pd, void, Reg, Reg)
+DEF_HELPER_2(cvtpi2ps, void, XMMReg, MMXReg)
+DEF_HELPER_2(cvtpi2pd, void, XMMReg, MMXReg)
+DEF_HELPER_2(cvtsi2ss, void, XMMReg, i32)
+DEF_HELPER_2(cvtsi2sd, void, XMMReg, i32)
#ifdef TARGET_X86_64
-DEF_HELPER(void, helper_cvtsq2ss, (XMMReg *d, uint64_t val))
-DEF_HELPER(void, helper_cvtsq2sd, (XMMReg *d, uint64_t val))
+DEF_HELPER_2(cvtsq2ss, void, XMMReg, i64)
+DEF_HELPER_2(cvtsq2sd, void, XMMReg, i64)
#endif
-DEF_HELPER(void, helper_cvtps2dq, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_cvtpd2dq, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_cvtps2pi, (MMXReg *d, XMMReg *s))
-DEF_HELPER(void, helper_cvtpd2pi, (MMXReg *d, XMMReg *s))
-DEF_HELPER(int32_t, helper_cvtss2si, (XMMReg *s))
-DEF_HELPER(int32_t, helper_cvtsd2si, (XMMReg *s))
+DEF_HELPER_2(cvtps2dq, void, XMMReg, XMMReg)
+DEF_HELPER_2(cvtpd2dq, void, XMMReg, XMMReg)
+DEF_HELPER_2(cvtps2pi, void, MMXReg, XMMReg)
+DEF_HELPER_2(cvtpd2pi, void, MMXReg, XMMReg)
+DEF_HELPER_1(cvtss2si, s32, XMMReg)
+DEF_HELPER_1(cvtsd2si, s32, XMMReg)
#ifdef TARGET_X86_64
-DEF_HELPER(int64_t, helper_cvtss2sq, (XMMReg *s))
-DEF_HELPER(int64_t, helper_cvtsd2sq, (XMMReg *s))
+DEF_HELPER_1(cvtss2sq, s64, XMMReg)
+DEF_HELPER_1(cvtsd2sq, s64, XMMReg)
#endif
-DEF_HELPER(void, helper_cvttps2dq, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_cvttpd2dq, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_cvttps2pi, (MMXReg *d, XMMReg *s))
-DEF_HELPER(void, helper_cvttpd2pi, (MMXReg *d, XMMReg *s))
-DEF_HELPER(int32_t, helper_cvttss2si, (XMMReg *s))
-DEF_HELPER(int32_t, helper_cvttsd2si, (XMMReg *s))
+DEF_HELPER_2(cvttps2dq, void, XMMReg, XMMReg)
+DEF_HELPER_2(cvttpd2dq, void, XMMReg, XMMReg)
+DEF_HELPER_2(cvttps2pi, void, MMXReg, XMMReg)
+DEF_HELPER_2(cvttpd2pi, void, MMXReg, XMMReg)
+DEF_HELPER_1(cvttss2si, s32, XMMReg)
+DEF_HELPER_1(cvttsd2si, s32, XMMReg)
#ifdef TARGET_X86_64
-DEF_HELPER(int64_t, helper_cvttss2sq, (XMMReg *s))
-DEF_HELPER(int64_t, helper_cvttsd2sq, (XMMReg *s))
+DEF_HELPER_1(cvttss2sq, s64, XMMReg)
+DEF_HELPER_1(cvttsd2sq, s64, XMMReg)
#endif
-DEF_HELPER(void, helper_rsqrtps, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_rsqrtss, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_rcpps, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_rcpss, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_haddps, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_haddpd, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_hsubps, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_hsubpd, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_addsubps, (XMMReg *d, XMMReg *s))
-DEF_HELPER(void, helper_addsubpd, (XMMReg *d, XMMReg *s))
+DEF_HELPER_2(rsqrtps, void, XMMReg, XMMReg)
+DEF_HELPER_2(rsqrtss, void, XMMReg, XMMReg)
+DEF_HELPER_2(rcpps, void, XMMReg, XMMReg)
+DEF_HELPER_2(rcpss, void, XMMReg, XMMReg)
+DEF_HELPER_2(extrq_r, void, XMMReg, XMMReg)
+DEF_HELPER_3(extrq_i, void, XMMReg, int, int)
+DEF_HELPER_2(insertq_r, void, XMMReg, XMMReg)
+DEF_HELPER_3(insertq_i, void, XMMReg, int, int)
+DEF_HELPER_2(haddps, void, XMMReg, XMMReg)
+DEF_HELPER_2(haddpd, void, XMMReg, XMMReg)
+DEF_HELPER_2(hsubps, void, XMMReg, XMMReg)
+DEF_HELPER_2(hsubpd, void, XMMReg, XMMReg)
+DEF_HELPER_2(addsubps, void, XMMReg, XMMReg)
+DEF_HELPER_2(addsubpd, void, XMMReg, XMMReg)
#define SSE_HELPER_CMP(name, F)\
- DEF_HELPER(void, helper_ ## name ## ps , (Reg *d, Reg *s)) \
- DEF_HELPER(void, helper_ ## name ## ss , (Reg *d, Reg *s)) \
- DEF_HELPER(void, helper_ ## name ## pd , (Reg *d, Reg *s)) \
- DEF_HELPER(void, helper_ ## name ## sd , (Reg *d, Reg *s))
+ DEF_HELPER_2( name ## ps , void, Reg, Reg) \
+ DEF_HELPER_2( name ## ss , void, Reg, Reg) \
+ DEF_HELPER_2( name ## pd , void, Reg, Reg) \
+ DEF_HELPER_2( name ## sd , void, Reg, Reg)
SSE_HELPER_CMP(cmpeq, FPU_CMPEQ)
SSE_HELPER_CMP(cmplt, FPU_CMPLT)
@@ -213,125 +226,124 @@ SSE_HELPER_CMP(cmpnlt, FPU_CMPNLT)
SSE_HELPER_CMP(cmpnle, FPU_CMPNLE)
SSE_HELPER_CMP(cmpord, FPU_CMPORD)
-DEF_HELPER(void, helper_ucomiss, (Reg *d, Reg *s))
-DEF_HELPER(void, helper_comiss, (Reg *d, Reg *s))
-DEF_HELPER(void, helper_ucomisd, (Reg *d, Reg *s))
-DEF_HELPER(void, helper_comisd, (Reg *d, Reg *s))
-DEF_HELPER(uint32_t, helper_movmskps, (Reg *s))
-DEF_HELPER(uint32_t, helper_movmskpd, (Reg *s))
+DEF_HELPER_2(ucomiss, void, Reg, Reg)
+DEF_HELPER_2(comiss, void, Reg, Reg)
+DEF_HELPER_2(ucomisd, void, Reg, Reg)
+DEF_HELPER_2(comisd, void, Reg, Reg)
+DEF_HELPER_1(movmskps, i32, Reg)
+DEF_HELPER_1(movmskpd, i32, Reg)
#endif
-DEF_HELPER(uint32_t, glue(helper_pmovmskb, SUFFIX), (Reg *s))
-DEF_HELPER(void, glue(helper_packsswb, SUFFIX) , (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_packuswb, SUFFIX) , (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_packssdw, SUFFIX) , (Reg *d, Reg *s))
+DEF_HELPER_1(glue(pmovmskb, SUFFIX), i32, Reg)
+DEF_HELPER_2(glue(packsswb, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(packuswb, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(packssdw, SUFFIX), void, Reg, Reg)
#define UNPCK_OP(base_name, base) \
- DEF_HELPER(void, glue(helper_punpck ## base_name ## bw, SUFFIX) , (Reg *d, Reg *s)) \
- DEF_HELPER(void, glue(helper_punpck ## base_name ## wd, SUFFIX) , (Reg *d, Reg *s)) \
- DEF_HELPER(void, glue(helper_punpck ## base_name ## dq, SUFFIX) , (Reg *d, Reg *s))
+ DEF_HELPER_2(glue(punpck ## base_name ## bw, SUFFIX) , void, Reg, Reg) \
+ DEF_HELPER_2(glue(punpck ## base_name ## wd, SUFFIX) , void, Reg, Reg) \
+ DEF_HELPER_2(glue(punpck ## base_name ## dq, SUFFIX) , void, Reg, Reg)
UNPCK_OP(l, 0)
UNPCK_OP(h, 1)
#if SHIFT == 1
-DEF_HELPER(void, glue(helper_punpcklqdq, SUFFIX) , (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_punpckhqdq, SUFFIX) , (Reg *d, Reg *s))
+DEF_HELPER_2(glue(punpcklqdq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(punpckhqdq, SUFFIX), void, Reg, Reg)
#endif
/* 3DNow! float ops */
#if SHIFT == 0
-DEF_HELPER(void, helper_pi2fd, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pi2fw, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pf2id, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pf2iw, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfacc, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfadd, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfcmpeq, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfcmpge, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfcmpgt, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfmax, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfmin, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfmul, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfnacc, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfpnacc, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfrcp, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfrsqrt, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfsub, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pfsubr, (MMXReg *d, MMXReg *s))
-DEF_HELPER(void, helper_pswapd, (MMXReg *d, MMXReg *s))
+DEF_HELPER_2(pi2fd, void, MMXReg, MMXReg)
+DEF_HELPER_2(pi2fw, void, MMXReg, MMXReg)
+DEF_HELPER_2(pf2id, void, MMXReg, MMXReg)
+DEF_HELPER_2(pf2iw, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfacc, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfadd, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfcmpeq, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfcmpge, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfcmpgt, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfmax, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfmin, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfmul, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfnacc, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfpnacc, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfrcp, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfrsqrt, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfsub, void, MMXReg, MMXReg)
+DEF_HELPER_2(pfsubr, void, MMXReg, MMXReg)
+DEF_HELPER_2(pswapd, void, MMXReg, MMXReg)
#endif
/* SSSE3 op helpers */
-DEF_HELPER(void, glue(helper_phaddw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_phaddd, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_phaddsw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_phsubw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_phsubd, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_phsubsw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pabsb, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pabsw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pabsd, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmaddubsw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmulhrsw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pshufb, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_psignb, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_psignw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_psignd, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_palignr, SUFFIX), (Reg *d, Reg *s, int32_t shift))
+DEF_HELPER_2(glue(phaddw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(phaddd, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(phaddsw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(phsubw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(phsubd, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(phsubsw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pabsb, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pabsw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pabsd, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmaddubsw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmulhrsw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pshufb, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(psignb, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(psignw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(psignd, SUFFIX), void, Reg, Reg)
+DEF_HELPER_3(glue(palignr, SUFFIX), void, Reg, Reg, s32)
/* SSE4.1 op helpers */
#if SHIFT == 1
-DEF_HELPER(void, glue(helper_pblendvb, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_blendvps, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_blendvpd, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_ptest, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmovsxbw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmovsxbd, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmovsxbq, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmovsxwd, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmovsxwq, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmovsxdq, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmovzxbw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmovzxbd, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmovzxbq, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmovzxwd, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmovzxwq, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmovzxdq, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmuldq, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pcmpeqq, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_packusdw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pminsb, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pminsd, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pminuw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pminud, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmaxsb, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmaxsd, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmaxuw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmaxud, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pmulld, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_phminposuw, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_roundps, SUFFIX), (Reg *d, Reg *s, uint32_t mode))
-DEF_HELPER(void, glue(helper_roundpd, SUFFIX), (Reg *d, Reg *s, uint32_t mode))
-DEF_HELPER(void, glue(helper_roundss, SUFFIX), (Reg *d, Reg *s, uint32_t mode))
-DEF_HELPER(void, glue(helper_roundsd, SUFFIX), (Reg *d, Reg *s, uint32_t mode))
-DEF_HELPER(void, glue(helper_blendps, SUFFIX), (Reg *d, Reg *s, uint32_t imm))
-DEF_HELPER(void, glue(helper_blendpd, SUFFIX), (Reg *d, Reg *s, uint32_t imm))
-DEF_HELPER(void, glue(helper_pblendw, SUFFIX), (Reg *d, Reg *s, uint32_t imm))
-DEF_HELPER(void, glue(helper_dpps, SUFFIX), (Reg *d, Reg *s, uint32_t mask))
-DEF_HELPER(void, glue(helper_dppd, SUFFIX), (Reg *d, Reg *s, uint32_t mask))
-DEF_HELPER(void, glue(helper_mpsadbw, SUFFIX), (Reg *d, Reg *s, uint32_t off))
+DEF_HELPER_2(glue(pblendvb, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(blendvps, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(blendvpd, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(ptest, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmovsxbw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmovsxbd, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmovsxbq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmovsxwd, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmovsxwq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmovsxdq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmovzxbw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmovzxbd, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmovzxbq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmovzxwd, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmovzxwq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmovzxdq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmuldq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pcmpeqq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(packusdw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pminsb, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pminsd, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pminuw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pminud, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmaxsb, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmaxsd, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmaxuw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmaxud, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(pmulld, SUFFIX), void, Reg, Reg)
+DEF_HELPER_2(glue(phminposuw, SUFFIX), void, Reg, Reg)
+DEF_HELPER_3(glue(roundps, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(roundpd, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(roundss, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(roundsd, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(blendps, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(blendpd, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(pblendw, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(dpps, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(dppd, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(mpsadbw, SUFFIX), void, Reg, Reg, i32)
#endif
/* SSE4.2 op helpers */
#if SHIFT == 1
-DEF_HELPER(void, glue(helper_pcmpgtq, SUFFIX), (Reg *d, Reg *s))
-DEF_HELPER(void, glue(helper_pcmpestri, SUFFIX), (Reg *d, Reg *s, uint32_t ctl))
-DEF_HELPER(void, glue(helper_pcmpestrm, SUFFIX), (Reg *d, Reg *s, uint32_t ctl))
-DEF_HELPER(void, glue(helper_pcmpistri, SUFFIX), (Reg *d, Reg *s, uint32_t ctl))
-DEF_HELPER(void, glue(helper_pcmpistrm, SUFFIX), (Reg *d, Reg *s, uint32_t ctl))
-DEF_HELPER(target_ulong, helper_crc32,
- (uint32_t crc1, target_ulong msg, uint32_t len))
-DEF_HELPER(target_ulong, helper_popcnt, (target_ulong n, uint32_t type))
+DEF_HELPER_2(glue(pcmpgtq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_3(glue(pcmpestri, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(pcmpestrm, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(pcmpistri, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(pcmpistrm, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(crc32, tl, i32, tl, i32)
+DEF_HELPER_2(popcnt, tl, tl, i32)
#endif
#undef SHIFT
diff --git a/src/recompiler/target-i386/ops_template.h b/src/recompiler/target-i386/ops_template.h
deleted file mode 100644
index dbabe3433..000000000
--- a/src/recompiler/target-i386/ops_template.h
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- * i386 micro operations (included several times to generate
- * different operand sizes)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * 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.
- */
-
-#define DATA_BITS (1 << (3 + SHIFT))
-#define SHIFT_MASK (DATA_BITS - 1)
-#define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
-#if DATA_BITS <= 32
-#define SHIFT1_MASK 0x1f
-#else
-#define SHIFT1_MASK 0x3f
-#endif
-
-#if DATA_BITS == 8
-#define SUFFIX b
-#define DATA_TYPE uint8_t
-#define DATA_STYPE int8_t
-#define DATA_MASK 0xff
-#elif DATA_BITS == 16
-#define SUFFIX w
-#define DATA_TYPE uint16_t
-#define DATA_STYPE int16_t
-#define DATA_MASK 0xffff
-#elif DATA_BITS == 32
-#define SUFFIX l
-#define DATA_TYPE uint32_t
-#define DATA_STYPE int32_t
-#define DATA_MASK 0xffffffff
-#elif DATA_BITS == 64
-#define SUFFIX q
-#define DATA_TYPE uint64_t
-#define DATA_STYPE int64_t
-#define DATA_MASK 0xffffffffffffffffULL
-#else
-#error unhandled operand size
-#endif
-
-/* dynamic flags computation */
-
-static int glue(compute_all_add, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- target_long src1, src2;
- src1 = CC_SRC;
- src2 = CC_DST - CC_SRC;
- cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
- pf = parity_table[(uint8_t)CC_DST];
- af = (CC_DST ^ src1 ^ src2) & 0x10;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_c_add, SUFFIX)(void)
-{
- int cf;
- target_long src1;
- src1 = CC_SRC;
- cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
- return cf;
-}
-
-static int glue(compute_all_adc, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- target_long src1, src2;
- src1 = CC_SRC;
- src2 = CC_DST - CC_SRC - 1;
- cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
- pf = parity_table[(uint8_t)CC_DST];
- af = (CC_DST ^ src1 ^ src2) & 0x10;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_c_adc, SUFFIX)(void)
-{
- int cf;
- target_long src1;
- src1 = CC_SRC;
- cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
- return cf;
-}
-
-static int glue(compute_all_sub, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
- cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
- pf = parity_table[(uint8_t)CC_DST];
- af = (CC_DST ^ src1 ^ src2) & 0x10;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_c_sub, SUFFIX)(void)
-{
- int cf;
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
- cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
- return cf;
-}
-
-static int glue(compute_all_sbb, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- target_long src1, src2;
- src1 = CC_DST + CC_SRC + 1;
- src2 = CC_SRC;
- cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
- pf = parity_table[(uint8_t)CC_DST];
- af = (CC_DST ^ src1 ^ src2) & 0x10;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_c_sbb, SUFFIX)(void)
-{
- int cf;
- target_long src1, src2;
- src1 = CC_DST + CC_SRC + 1;
- src2 = CC_SRC;
- cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
- return cf;
-}
-
-static int glue(compute_all_logic, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- cf = 0;
- pf = parity_table[(uint8_t)CC_DST];
- af = 0;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = 0;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_c_logic, SUFFIX)(void)
-{
- return 0;
-}
-
-static int glue(compute_all_inc, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- target_long src1, src2;
- src1 = CC_DST - 1;
- src2 = 1;
- cf = CC_SRC;
- pf = parity_table[(uint8_t)CC_DST];
- af = (CC_DST ^ src1 ^ src2) & 0x10;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
- return cf | pf | af | zf | sf | of;
-}
-
-#if DATA_BITS == 32
-static int glue(compute_c_inc, SUFFIX)(void)
-{
- return CC_SRC;
-}
-#endif
-
-static int glue(compute_all_dec, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- target_long src1, src2;
- src1 = CC_DST + 1;
- src2 = 1;
- cf = CC_SRC;
- pf = parity_table[(uint8_t)CC_DST];
- af = (CC_DST ^ src1 ^ src2) & 0x10;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = ((CC_DST & DATA_MASK) == ((target_ulong)SIGN_MASK - 1)) << 11;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_all_shl, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
- pf = parity_table[(uint8_t)CC_DST];
- af = 0; /* undefined */
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- /* of is defined if shift count == 1 */
- of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_c_shl, SUFFIX)(void)
-{
- return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
-}
-
-#if DATA_BITS == 32
-static int glue(compute_c_sar, SUFFIX)(void)
-{
- return CC_SRC & 1;
-}
-#endif
-
-static int glue(compute_all_sar, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- cf = CC_SRC & 1;
- pf = parity_table[(uint8_t)CC_DST];
- af = 0; /* undefined */
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- /* of is defined if shift count == 1 */
- of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
- return cf | pf | af | zf | sf | of;
-}
-
-#if DATA_BITS == 32
-static int glue(compute_c_mul, SUFFIX)(void)
-{
- int cf;
- cf = (CC_SRC != 0);
- return cf;
-}
-#endif
-
-/* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
- CF are modified and it is slower to do that. */
-static int glue(compute_all_mul, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- cf = (CC_SRC != 0);
- pf = parity_table[(uint8_t)CC_DST];
- af = 0; /* undefined */
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = cf << 11;
- return cf | pf | af | zf | sf | of;
-}
-
-/* various optimized jumps cases */
-
-void OPPROTO glue(op_jb_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jz_sub, SUFFIX)(void)
-{
- if ((DATA_TYPE)CC_DST == 0)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jnz_sub, SUFFIX)(void)
-{
- if ((DATA_TYPE)CC_DST != 0)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_js_sub, SUFFIX)(void)
-{
- if (CC_DST & SIGN_MASK)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jl_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jle_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-/* oldies */
-
-#if DATA_BITS >= 16
-
-void OPPROTO glue(op_loopnz, SUFFIX)(void)
-{
- if ((DATA_TYPE)ECX != 0 && !(T0 & CC_Z))
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_loopz, SUFFIX)(void)
-{
- if ((DATA_TYPE)ECX != 0 && (T0 & CC_Z))
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jz_ecx, SUFFIX)(void)
-{
- if ((DATA_TYPE)ECX == 0)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jnz_ecx, SUFFIX)(void)
-{
- if ((DATA_TYPE)ECX != 0)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-#endif
-
-/* various optimized set cases */
-
-void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2);
-}
-
-void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
-{
- T0 = ((DATA_TYPE)CC_DST == 0);
-}
-
-void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2);
-}
-
-void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
-{
- T0 = lshift(CC_DST, -(DATA_BITS - 1)) & 1;
-}
-
-void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2);
-}
-
-void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
-}
-
-/* shifts */
-
-void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
-{
- int count;
- count = T1 & SHIFT1_MASK;
- T0 = T0 << count;
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
-{
- int count;
- count = T1 & SHIFT1_MASK;
- T0 &= DATA_MASK;
- T0 = T0 >> count;
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
-{
- int count;
- target_long src;
-
- count = T1 & SHIFT1_MASK;
- src = (DATA_STYPE)T0;
- T0 = src >> count;
- FORCE_RET();
-}
-
-#undef MEM_WRITE
-#include "ops_template_mem.h"
-
-#define MEM_WRITE 0
-#include "ops_template_mem.h"
-
-#if !defined(CONFIG_USER_ONLY)
-#define MEM_WRITE 1
-#include "ops_template_mem.h"
-
-#define MEM_WRITE 2
-#include "ops_template_mem.h"
-#endif
-
-/* bit operations */
-#if DATA_BITS >= 16
-
-void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- CC_SRC = T0 >> count;
-}
-
-void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- T1 = T0 >> count;
- T0 |= (((target_long)1) << count);
-}
-
-void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- T1 = T0 >> count;
- T0 &= ~(((target_long)1) << count);
-}
-
-void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- T1 = T0 >> count;
- T0 ^= (((target_long)1) << count);
-}
-
-void OPPROTO glue(glue(op_add_bit, SUFFIX), _A0_T1)(void)
-{
- A0 += ((DATA_STYPE)T1 >> (3 + SHIFT)) << SHIFT;
-}
-
-void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
-{
- int count;
- target_long res;
-
- res = T0 & DATA_MASK;
- if (res != 0) {
- count = 0;
- while ((res & 1) == 0) {
- count++;
- res >>= 1;
- }
- T1 = count;
- CC_DST = 1; /* ZF = 0 */
- } else {
- CC_DST = 0; /* ZF = 1 */
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
-{
- int count;
- target_long res;
-
- res = T0 & DATA_MASK;
- if (res != 0) {
- count = DATA_BITS - 1;
- while ((res & SIGN_MASK) == 0) {
- count--;
- res <<= 1;
- }
- T1 = count;
- CC_DST = 1; /* ZF = 0 */
- } else {
- CC_DST = 0; /* ZF = 1 */
- }
- FORCE_RET();
-}
-
-#endif
-
-#if DATA_BITS == 32
-void OPPROTO op_update_bt_cc(void)
-{
- CC_SRC = T1;
-}
-#endif
-
-/* string operations */
-
-void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
-{
- T0 = DF << SHIFT;
-}
-
-/* port I/O */
-#if DATA_BITS <= 32
-void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
-{
- glue(cpu_out, SUFFIX)(env, T0, T1 & DATA_MASK);
-}
-
-void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
-{
- T1 = glue(cpu_in, SUFFIX)(env, T0);
-}
-
-void OPPROTO glue(glue(op_in, SUFFIX), _DX_T0)(void)
-{
- T0 = glue(cpu_in, SUFFIX)(env, EDX & 0xffff);
-}
-
-void OPPROTO glue(glue(op_out, SUFFIX), _DX_T0)(void)
-{
- glue(cpu_out, SUFFIX)(env, EDX & 0xffff, T0);
-}
-
-void OPPROTO glue(glue(op_check_io, SUFFIX), _T0)(void)
-{
- glue(glue(check_io, SUFFIX), _T0)();
-}
-
-void OPPROTO glue(glue(op_check_io, SUFFIX), _DX)(void)
-{
- glue(glue(check_io, SUFFIX), _DX)();
-}
-#endif
-
-#undef DATA_BITS
-#undef SHIFT_MASK
-#undef SHIFT1_MASK
-#undef SIGN_MASK
-#undef DATA_TYPE
-#undef DATA_STYPE
-#undef DATA_MASK
-#undef SUFFIX
diff --git a/src/recompiler/target-i386/ops_template_mem.h b/src/recompiler/target-i386/ops_template_mem.h
deleted file mode 100644
index 35ed40b81..000000000
--- a/src/recompiler/target-i386/ops_template_mem.h
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * i386 micro operations (included several times to generate
- * different operand sizes)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * 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.
- */
-
-#ifdef MEM_WRITE
-
-#if MEM_WRITE == 0
-
-#if DATA_BITS == 8
-#define MEM_SUFFIX b_raw
-#elif DATA_BITS == 16
-#define MEM_SUFFIX w_raw
-#elif DATA_BITS == 32
-#define MEM_SUFFIX l_raw
-#elif DATA_BITS == 64
-#define MEM_SUFFIX q_raw
-#endif
-
-#elif MEM_WRITE == 1
-
-#if DATA_BITS == 8
-#define MEM_SUFFIX b_kernel
-#elif DATA_BITS == 16
-#define MEM_SUFFIX w_kernel
-#elif DATA_BITS == 32
-#define MEM_SUFFIX l_kernel
-#elif DATA_BITS == 64
-#define MEM_SUFFIX q_kernel
-#endif
-
-#elif MEM_WRITE == 2
-
-#if DATA_BITS == 8
-#define MEM_SUFFIX b_user
-#elif DATA_BITS == 16
-#define MEM_SUFFIX w_user
-#elif DATA_BITS == 32
-#define MEM_SUFFIX l_user
-#elif DATA_BITS == 64
-#define MEM_SUFFIX q_user
-#endif
-
-#else
-
-#error invalid MEM_WRITE
-
-#endif
-
-#else
-
-#define MEM_SUFFIX SUFFIX
-
-#endif
-
-void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- target_long src;
-
- if (T1 & SHIFT1_MASK) {
- count = T1 & SHIFT_MASK;
- src = T0;
- T0 &= DATA_MASK;
- T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#else
- /* gcc 3.2 workaround. This is really a bug in gcc. */
- asm volatile("" : : "r" (T0));
-#endif
- CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
- (T0 & CC_C);
- CC_OP = CC_OP_EFLAGS;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- target_long src;
-
- if (T1 & SHIFT1_MASK) {
- count = T1 & SHIFT_MASK;
- src = T0;
- T0 &= DATA_MASK;
- T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#else
- /* gcc 3.2 workaround. This is really a bug in gcc. */
- asm volatile("" : : "r" (T0));
-#endif
- CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
- ((T0 >> (DATA_BITS - 1)) & CC_C);
- CC_OP = CC_OP_EFLAGS;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- if (count) {
- T0 &= DATA_MASK;
- T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- if (count) {
- T0 &= DATA_MASK;
- T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count, eflags;
- target_ulong src;
- target_long res;
-
- count = T1 & SHIFT1_MASK;
-#if DATA_BITS == 16
- count = rclw_table[count];
-#elif DATA_BITS == 8
- count = rclb_table[count];
-#endif
- if (count) {
- eflags = cc_table[CC_OP].compute_all();
- T0 &= DATA_MASK;
- src = T0;
- res = (T0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
- if (count > 1)
- res |= T0 >> (DATA_BITS + 1 - count);
- T0 = res;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = (eflags & ~(CC_C | CC_O)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
- ((src >> (DATA_BITS - count)) & CC_C);
- CC_OP = CC_OP_EFLAGS;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count, eflags;
- target_ulong src;
- target_long res;
-
- count = T1 & SHIFT1_MASK;
-#if DATA_BITS == 16
- count = rclw_table[count];
-#elif DATA_BITS == 8
- count = rclb_table[count];
-#endif
- if (count) {
- eflags = cc_table[CC_OP].compute_all();
- T0 &= DATA_MASK;
- src = T0;
- res = (T0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
- if (count > 1)
- res |= T0 << (DATA_BITS + 1 - count);
- T0 = res;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = (eflags & ~(CC_C | CC_O)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
- ((src >> (count - 1)) & CC_C);
- CC_OP = CC_OP_EFLAGS;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- target_long src;
-
- count = T1 & SHIFT1_MASK;
- if (count) {
- src = (DATA_TYPE)T0 << (count - 1);
- T0 = T0 << count;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = src;
- CC_DST = T0;
- CC_OP = CC_OP_SHLB + SHIFT;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- target_long src;
-
- count = T1 & SHIFT1_MASK;
- if (count) {
- T0 &= DATA_MASK;
- src = T0 >> (count - 1);
- T0 = T0 >> count;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = src;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- target_long src;
-
- count = T1 & SHIFT1_MASK;
- if (count) {
- src = (DATA_STYPE)T0;
- T0 = src >> count;
- src = src >> (count - 1);
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = src;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-
-#if DATA_BITS == 16
-/* XXX: overflow flag might be incorrect in some cases in shldw */
-void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
-{
- int count;
- unsigned int res, tmp;
- count = PARAM1;
- T1 &= 0xffff;
- res = T1 | (T0 << 16);
- tmp = res >> (32 - count);
- res <<= count;
- if (count > 16)
- res |= T1 << (count - 16);
- T0 = res >> 16;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
-}
-
-void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
-{
- int count;
- unsigned int res, tmp;
- count = ECX & 0x1f;
- if (count) {
- T1 &= 0xffff;
- res = T1 | (T0 << 16);
- tmp = res >> (32 - count);
- res <<= count;
- if (count > 16)
- res |= T1 << (count - 16);
- T0 = res >> 16;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
-{
- int count;
- unsigned int res, tmp;
-
- count = PARAM1;
- res = (T0 & 0xffff) | (T1 << 16);
- tmp = res >> (count - 1);
- res >>= count;
- if (count > 16)
- res |= T1 << (32 - count);
- T0 = res;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
-}
-
-
-void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
-{
- int count;
- unsigned int res, tmp;
-
- count = ECX & 0x1f;
- if (count) {
- res = (T0 & 0xffff) | (T1 << 16);
- tmp = res >> (count - 1);
- res >>= count;
- if (count > 16)
- res |= T1 << (32 - count);
- T0 = res;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-#endif
-
-#if DATA_BITS >= 32
-void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
-{
- int count;
- target_long tmp;
-
- count = PARAM1;
- T0 &= DATA_MASK;
- T1 &= DATA_MASK;
- tmp = T0 << (count - 1);
- T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
-}
-
-void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
-{
- int count;
- target_long tmp;
-
- count = ECX & SHIFT1_MASK;
- if (count) {
- T0 &= DATA_MASK;
- T1 &= DATA_MASK;
- tmp = T0 << (count - 1);
- T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
- CC_OP = CC_OP_SHLB + SHIFT;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
-{
- int count;
- target_long tmp;
-
- count = PARAM1;
- T0 &= DATA_MASK;
- T1 &= DATA_MASK;
- tmp = T0 >> (count - 1);
- T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
-}
-
-
-void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
-{
- int count;
- target_long tmp;
-
- count = ECX & SHIFT1_MASK;
- if (count) {
- T0 &= DATA_MASK;
- T1 &= DATA_MASK;
- tmp = T0 >> (count - 1);
- T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-#endif
-
-/* carry add/sub (we only need to set CC_OP differently) */
-
-void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int cf;
- cf = cc_table[CC_OP].compute_c();
- T0 = T0 + T1 + cf;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = T1;
- CC_DST = T0;
- CC_OP = CC_OP_ADDB + SHIFT + cf * 4;
-}
-
-void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int cf;
- cf = cc_table[CC_OP].compute_c();
- T0 = T0 - T1 - cf;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = T1;
- CC_DST = T0;
- CC_OP = CC_OP_SUBB + SHIFT + cf * 4;
-}
-
-void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
-{
- target_ulong src, dst;
-
- src = T0;
- dst = EAX - T0;
- if ((DATA_TYPE)dst == 0) {
- T0 = T1;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- } else {
- EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
- }
- CC_SRC = src;
- CC_DST = dst;
- FORCE_RET();
-}
-
-#undef MEM_SUFFIX
-#undef MEM_WRITE
diff --git a/src/recompiler/target-i386/svm.h b/src/recompiler/target-i386/svm.h
index ef268107d..a224aead1 100644
--- a/src/recompiler/target-i386/svm.h
+++ b/src/recompiler/target-i386/svm.h
@@ -130,11 +130,7 @@
#define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) /* TS and MP */
-#ifndef VBOX
struct __attribute__ ((__packed__)) vmcb_control_area {
-#else
-PACKED_STRUCT(vmcb_control_area) {
-#endif /* VBOX */
uint16_t intercept_cr_read;
uint16_t intercept_cr_write;
uint16_t intercept_dr_read;
@@ -166,22 +162,14 @@ PACKED_STRUCT(vmcb_control_area) {
uint8_t reserved_5[832];
};
-#ifndef VBOX
struct __attribute__ ((__packed__)) vmcb_seg {
-#else
-PACKED_STRUCT(vmcb_seg) {
-#endif
uint16_t selector;
uint16_t attrib;
uint32_t limit;
uint64_t base;
};
-#ifndef VBOX
struct __attribute__ ((__packed__)) vmcb_save_area {
-#else
-PACKED_STRUCT(vmcb_save_area) {
-#endif
struct vmcb_seg es;
struct vmcb_seg cs;
struct vmcb_seg ss;
@@ -226,11 +214,7 @@ PACKED_STRUCT(vmcb_save_area) {
uint64_t last_excp_to;
};
-#ifndef VBOX
struct __attribute__ ((__packed__)) vmcb {
-#else
-PACKED_STRUCT(vmcb) {
-#endif
struct vmcb_control_area control;
struct vmcb_save_area save;
};
diff --git a/src/recompiler/target-i386/translate.c b/src/recompiler/target-i386/translate.c
index 2650a80dc..a0fce56a9 100644
--- a/src/recompiler/target-i386/translate.c
+++ b/src/recompiler/target-i386/translate.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -34,15 +33,17 @@
#ifndef VBOX
#include <inttypes.h>
#include <signal.h>
-#include <assert.h>
#endif /* !VBOX */
#include "cpu.h"
#include "exec-all.h"
#include "disas.h"
-#include "helper.h"
#include "tcg-op.h"
+#include "helper.h"
+#define GEN_HELPER 1
+#include "helper.h"
+
#define PREFIX_REPZ 0x01
#define PREFIX_REPNZ 0x02
#define PREFIX_LOCK 0x04
@@ -51,11 +52,7 @@
#ifdef TARGET_X86_64
#define X86_64_ONLY(x) x
-#ifndef VBOX
-#define X86_64_DEF(x...) x
-#else
-#define X86_64_DEF(x...) x
-#endif
+#define X86_64_DEF(...) __VA_ARGS__
#define CODE64(s) ((s)->code64)
#define REX_X(s) ((s)->rex_x)
#define REX_B(s) ((s)->rex_b)
@@ -65,11 +62,7 @@
#endif
#else
#define X86_64_ONLY(x) NULL
-#ifndef VBOX
-#define X86_64_DEF(x...)
-#else
-#define X86_64_DEF(x)
-#endif
+#define X86_64_DEF(...)
#define CODE64(s) 0
#define REX_X(s) 0
#define REX_B(s) 0
@@ -78,12 +71,20 @@
//#define MACRO_TEST 1
/* global register indexes */
-static TCGv cpu_env, cpu_A0, cpu_cc_op, cpu_cc_src, cpu_cc_dst, cpu_cc_tmp;
+static TCGv_ptr cpu_env;
+static TCGv cpu_A0, cpu_cc_src, cpu_cc_dst, cpu_cc_tmp;
+static TCGv_i32 cpu_cc_op;
+static TCGv cpu_regs[CPU_NB_REGS];
/* local temps */
static TCGv cpu_T[2], cpu_T3;
/* local register indexes (only used inside old micro ops) */
-static TCGv cpu_tmp0, cpu_tmp1_i64, cpu_tmp2_i32, cpu_tmp3_i32, cpu_tmp4, cpu_ptr0, cpu_ptr1;
-static TCGv cpu_tmp5, cpu_tmp6;
+static TCGv cpu_tmp0, cpu_tmp4;
+static TCGv_ptr cpu_ptr0, cpu_ptr1;
+static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
+static TCGv_i64 cpu_tmp1_i64;
+static TCGv cpu_tmp5;
+
+static uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
#include "gen-icount.h"
@@ -120,7 +121,6 @@ uint32_t ldl_code_raw(target_ulong pc)
#endif /* VBOX */
-
typedef struct DisasContext {
/* current insn context */
int override; /* -1 if no override */
@@ -169,7 +169,7 @@ static void gen_jmp(DisasContext *s, target_ulong eip);
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
#ifdef VBOX
-static void gen_check_external_event();
+static void gen_check_external_event(void);
#endif
/* i386 arith/logic operations */
@@ -231,121 +231,69 @@ enum {
OR_A0, /* temporary register used when doing address evaluation */
};
-#ifndef VBOX
static inline void gen_op_movl_T0_0(void)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl_T0_0(void)
-#endif /* VBOX */
{
tcg_gen_movi_tl(cpu_T[0], 0);
}
-#ifndef VBOX
static inline void gen_op_movl_T0_im(int32_t val)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl_T0_im(int32_t val)
-#endif /* VBOX */
{
tcg_gen_movi_tl(cpu_T[0], val);
}
-#ifndef VBOX
static inline void gen_op_movl_T0_imu(uint32_t val)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl_T0_imu(uint32_t val)
-#endif /* VBOX */
{
tcg_gen_movi_tl(cpu_T[0], val);
}
-#ifndef VBOX
static inline void gen_op_movl_T1_im(int32_t val)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl_T1_im(int32_t val)
-#endif /* VBOX */
{
tcg_gen_movi_tl(cpu_T[1], val);
}
-#ifndef VBOX
static inline void gen_op_movl_T1_imu(uint32_t val)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl_T1_imu(uint32_t val)
-#endif /* VBOX */
{
tcg_gen_movi_tl(cpu_T[1], val);
}
-#ifndef VBOX
static inline void gen_op_movl_A0_im(uint32_t val)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl_A0_im(uint32_t val)
-#endif /* VBOX */
{
tcg_gen_movi_tl(cpu_A0, val);
}
#ifdef TARGET_X86_64
-#ifndef VBOX
static inline void gen_op_movq_A0_im(int64_t val)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movq_A0_im(int64_t val)
-#endif /* VBOX */
{
tcg_gen_movi_tl(cpu_A0, val);
}
#endif
-#ifndef VBOX
static inline void gen_movtl_T0_im(target_ulong val)
-#else /* VBOX */
-DECLINLINE(void) gen_movtl_T0_im(target_ulong val)
-#endif /* VBOX */
{
tcg_gen_movi_tl(cpu_T[0], val);
}
-#ifndef VBOX
static inline void gen_movtl_T1_im(target_ulong val)
-#else /* VBOX */
-DECLINLINE(void) gen_movtl_T1_im(target_ulong val)
-#endif /* VBOX */
{
tcg_gen_movi_tl(cpu_T[1], val);
}
-#ifndef VBOX
static inline void gen_op_andl_T0_ffff(void)
-#else /* VBOX */
-DECLINLINE(void) gen_op_andl_T0_ffff(void)
-#endif /* VBOX */
{
tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
}
-#ifndef VBOX
static inline void gen_op_andl_T0_im(uint32_t val)
-#else /* VBOX */
-DECLINLINE(void) gen_op_andl_T0_im(uint32_t val)
-#endif /* VBOX */
{
tcg_gen_andi_tl(cpu_T[0], cpu_T[0], val);
}
-#ifndef VBOX
static inline void gen_op_movl_T0_T1(void)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl_T0_T1(void)
-#endif /* VBOX */
{
tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
}
-#ifndef VBOX
static inline void gen_op_andl_A0_ffff(void)
-#else /* VBOX */
-DECLINLINE(void) gen_op_andl_A0_ffff(void)
-#endif /* VBOX */
{
tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffff);
}
@@ -360,7 +308,7 @@ DECLINLINE(void) gen_op_andl_A0_ffff(void)
#endif /* !TARGET_X86_64 */
-#if defined(WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
#define REG_B_OFFSET (sizeof(target_ulong) - 1)
#define REG_H_OFFSET (sizeof(target_ulong) - 2)
#define REG_W_OFFSET (sizeof(target_ulong) - 2)
@@ -374,141 +322,110 @@ DECLINLINE(void) gen_op_andl_A0_ffff(void)
#define REG_LH_OFFSET 4
#endif
-#ifndef VBOX
static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0)
-#else /* VBOX */
-DECLINLINE(void) gen_op_mov_reg_v(int ot, int reg, TCGv t0)
-#endif /* VBOX */
{
+ TCGv tmp;
+
switch(ot) {
case OT_BYTE:
+ tmp = tcg_temp_new();
+ tcg_gen_ext8u_tl(tmp, t0);
if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
- tcg_gen_st8_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_B_OFFSET);
+ tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xff);
+ tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp);
} else {
- tcg_gen_st8_tl(t0, cpu_env, offsetof(CPUState, regs[reg - 4]) + REG_H_OFFSET);
+ tcg_gen_shli_tl(tmp, tmp, 8);
+ tcg_gen_andi_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], ~0xff00);
+ tcg_gen_or_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], tmp);
}
+ tcg_temp_free(tmp);
break;
case OT_WORD:
- tcg_gen_st16_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
+ tmp = tcg_temp_new();
+ tcg_gen_ext16u_tl(tmp, t0);
+ tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff);
+ tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp);
+ tcg_temp_free(tmp);
break;
-#ifdef TARGET_X86_64
+ default: /* XXX this shouldn't be reached; abort? */
case OT_LONG:
- tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
- /* high part of register set to zero */
- tcg_gen_movi_tl(cpu_tmp0, 0);
- tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
+ /* For x86_64, this sets the higher half of register to zero.
+ For i386, this is equivalent to a mov. */
+ tcg_gen_ext32u_tl(cpu_regs[reg], t0);
break;
- default:
+#ifdef TARGET_X86_64
case OT_QUAD:
- tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, regs[reg]));
- break;
-#else
- default:
- case OT_LONG:
- tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+ tcg_gen_mov_tl(cpu_regs[reg], t0);
break;
#endif
}
}
-#ifndef VBOX
static inline void gen_op_mov_reg_T0(int ot, int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_mov_reg_T0(int ot, int reg)
-#endif /* VBOX */
{
gen_op_mov_reg_v(ot, reg, cpu_T[0]);
}
-#ifndef VBOX
static inline void gen_op_mov_reg_T1(int ot, int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_mov_reg_T1(int ot, int reg)
-#endif /* VBOX */
{
gen_op_mov_reg_v(ot, reg, cpu_T[1]);
}
-#ifndef VBOX
static inline void gen_op_mov_reg_A0(int size, int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_mov_reg_A0(int size, int reg)
-#endif /* VBOX */
{
+ TCGv tmp;
+
switch(size) {
case 0:
- tcg_gen_st16_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
+ tmp = tcg_temp_new();
+ tcg_gen_ext16u_tl(tmp, cpu_A0);
+ tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff);
+ tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp);
+ tcg_temp_free(tmp);
break;
-#ifdef TARGET_X86_64
+ default: /* XXX this shouldn't be reached; abort? */
case 1:
- tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
- /* high part of register set to zero */
- tcg_gen_movi_tl(cpu_tmp0, 0);
- tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
+ /* For x86_64, this sets the higher half of register to zero.
+ For i386, this is equivalent to a mov. */
+ tcg_gen_ext32u_tl(cpu_regs[reg], cpu_A0);
break;
- default:
+#ifdef TARGET_X86_64
case 2:
- tcg_gen_st_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]));
- break;
-#else
- default:
- case 1:
- tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+ tcg_gen_mov_tl(cpu_regs[reg], cpu_A0);
break;
#endif
}
}
-#ifndef VBOX
static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_mov_v_reg(int ot, TCGv t0, int reg)
-#endif /* VBOX */
{
switch(ot) {
case OT_BYTE:
if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
-#ifndef VBOX
goto std_case;
-#else
- tcg_gen_ld8u_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_B_OFFSET);
-#endif
} else {
- tcg_gen_ld8u_tl(t0, cpu_env, offsetof(CPUState, regs[reg - 4]) + REG_H_OFFSET);
+ tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8);
+ tcg_gen_ext8u_tl(t0, t0);
}
break;
default:
-#ifndef VBOX
std_case:
-#endif
- tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, regs[reg]));
+ tcg_gen_mov_tl(t0, cpu_regs[reg]);
break;
}
}
-#ifndef VBOX
static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_mov_TN_reg(int ot, int t_index, int reg)
-#endif /* VBOX */
{
gen_op_mov_v_reg(ot, cpu_T[t_index], reg);
}
-#ifndef VBOX
static inline void gen_op_movl_A0_reg(int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl_A0_reg(int reg)
-#endif /* VBOX */
{
- tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+ tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
}
-#ifndef VBOX
static inline void gen_op_addl_A0_im(int32_t val)
-#else /* VBOX */
-DECLINLINE(void) gen_op_addl_A0_im(int32_t val)
-#endif /* VBOX */
{
tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
#ifdef TARGET_X86_64
@@ -517,11 +434,7 @@ DECLINLINE(void) gen_op_addl_A0_im(int32_t val)
}
#ifdef TARGET_X86_64
-#ifndef VBOX
static inline void gen_op_addq_A0_im(int64_t val)
-#else /* VBOX */
-DECLINLINE(void) gen_op_addq_A0_im(int64_t val)
-#endif /* VBOX */
{
tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
}
@@ -537,113 +450,86 @@ static void gen_add_A0_im(DisasContext *s, int val)
gen_op_addl_A0_im(val);
}
-#ifndef VBOX
static inline void gen_op_addl_T0_T1(void)
-#else /* VBOX */
-DECLINLINE(void) gen_op_addl_T0_T1(void)
-#endif /* VBOX */
{
tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
}
-#ifndef VBOX
static inline void gen_op_jmp_T0(void)
-#else /* VBOX */
-DECLINLINE(void) gen_op_jmp_T0(void)
-#endif /* VBOX */
{
tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, eip));
}
-#ifndef VBOX
static inline void gen_op_add_reg_im(int size, int reg, int32_t val)
-#else /* VBOX */
-DECLINLINE(void) gen_op_add_reg_im(int size, int reg, int32_t val)
-#endif /* VBOX */
{
switch(size) {
case 0:
- tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
- tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
- tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
+ tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
+ tcg_gen_ext16u_tl(cpu_tmp0, cpu_tmp0);
+ tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff);
+ tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0);
break;
case 1:
- tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
- tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
-#ifdef TARGET_X86_64
- tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
-#endif
- tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+ tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
+ /* For x86_64, this sets the higher half of register to zero.
+ For i386, this is equivalent to a nop. */
+ tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0);
+ tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0);
break;
#ifdef TARGET_X86_64
case 2:
- tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
- tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
- tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+ tcg_gen_addi_tl(cpu_regs[reg], cpu_regs[reg], val);
break;
#endif
}
}
-#ifndef VBOX
static inline void gen_op_add_reg_T0(int size, int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_add_reg_T0(int size, int reg)
-#endif /* VBOX */
{
switch(size) {
case 0:
- tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
- tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
- tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
+ tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
+ tcg_gen_ext16u_tl(cpu_tmp0, cpu_tmp0);
+ tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff);
+ tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0);
break;
case 1:
- tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
- tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
-#ifdef TARGET_X86_64
- tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
-#endif
- tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+ tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
+ /* For x86_64, this sets the higher half of register to zero.
+ For i386, this is equivalent to a nop. */
+ tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0);
+ tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0);
break;
#ifdef TARGET_X86_64
case 2:
- tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
- tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
- tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+ tcg_gen_add_tl(cpu_regs[reg], cpu_regs[reg], cpu_T[0]);
break;
#endif
}
}
-#ifndef VBOX
static inline void gen_op_set_cc_op(int32_t val)
-#else /* VBOX */
-DECLINLINE(void) gen_op_set_cc_op(int32_t val)
-#endif /* VBOX */
{
tcg_gen_movi_i32(cpu_cc_op, val);
}
-#ifndef VBOX
static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_addl_A0_reg_sN(int shift, int reg)
-#endif /* VBOX */
{
- tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+ tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
if (shift != 0)
tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
-#ifdef TARGET_X86_64
- tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
-#endif
+ /* For x86_64, this sets the higher half of register to zero.
+ For i386, this is equivalent to a nop. */
+ tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
}
+
#ifdef VBOX
DECLINLINE(void) gen_op_seg_check(int reg, bool keepA0)
{
/* It seems segments doesn't get out of sync - if they do in fact - enable below code. */
-#ifdef FORCE_SEGMENT_SYNC
-#if 1
+# ifdef FORCE_SEGMENT_SYNC
+# if 1
TCGv t0;
/* Considering poor quality of TCG optimizer - better call directly */
@@ -651,7 +537,7 @@ DECLINLINE(void) gen_op_seg_check(int reg, bool keepA0)
tcg_gen_movi_tl(t0, reg);
tcg_gen_helper_0_1(helper_sync_seg, t0);
tcg_temp_free(t0);
-#else
+# else
/* Our segments could be outdated, thus check for newselector field to see if update really needed */
int skip_label;
TCGv t0, a0;
@@ -688,16 +574,12 @@ DECLINLINE(void) gen_op_seg_check(int reg, bool keepA0)
tcg_gen_mov_tl(cpu_A0, a0);
tcg_temp_free(a0);
}
-#endif /* 0 */
-#endif /* FORCE_SEGMENT_SYNC */
+# endif /* 0 */
+# endif /* FORCE_SEGMENT_SYNC */
}
-#endif
+#endif /* VBOX */
-#ifndef VBOX
static inline void gen_op_movl_A0_seg(int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl_A0_seg(int reg)
-#endif /* VBOX */
{
#ifdef VBOX
gen_op_seg_check(reg, false);
@@ -705,11 +587,7 @@ DECLINLINE(void) gen_op_movl_A0_seg(int reg)
tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base) + REG_L_OFFSET);
}
-#ifndef VBOX
static inline void gen_op_addl_A0_seg(int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_addl_A0_seg(int reg)
-#endif /* VBOX */
{
#ifdef VBOX
gen_op_seg_check(reg, true);
@@ -722,11 +600,7 @@ DECLINLINE(void) gen_op_addl_A0_seg(int reg)
}
#ifdef TARGET_X86_64
-#ifndef VBOX
static inline void gen_op_movq_A0_seg(int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movq_A0_seg(int reg)
-#endif /* VBOX */
{
#ifdef VBOX
gen_op_seg_check(reg, false);
@@ -734,11 +608,7 @@ DECLINLINE(void) gen_op_movq_A0_seg(int reg)
tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base));
}
-#ifndef VBOX
static inline void gen_op_addq_A0_seg(int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_addq_A0_seg(int reg)
-#endif /* VBOX */
{
#ifdef VBOX
gen_op_seg_check(reg, true);
@@ -747,33 +617,21 @@ DECLINLINE(void) gen_op_addq_A0_seg(int reg)
tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
}
-#ifndef VBOX
static inline void gen_op_movq_A0_reg(int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movq_A0_reg(int reg)
-#endif /* VBOX */
{
- tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]));
+ tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
}
-#ifndef VBOX
static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_addq_A0_reg_sN(int shift, int reg)
-#endif /* VBOX */
{
- tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+ tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
if (shift != 0)
tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
}
#endif
-#ifndef VBOX
static inline void gen_op_lds_T0_A0(int idx)
-#else /* VBOX */
-DECLINLINE(void) gen_op_lds_T0_A0(int idx)
-#endif /* VBOX */
{
int mem_index = (idx >> 2) - 1;
switch(idx & 3) {
@@ -790,11 +648,7 @@ DECLINLINE(void) gen_op_lds_T0_A0(int idx)
}
}
-#ifndef VBOX
static inline void gen_op_ld_v(int idx, TCGv t0, TCGv a0)
-#else /* VBOX */
-DECLINLINE(void) gen_op_ld_v(int idx, TCGv t0, TCGv a0)
-#endif /* VBOX */
{
int mem_index = (idx >> 2) - 1;
switch(idx & 3) {
@@ -809,44 +663,31 @@ DECLINLINE(void) gen_op_ld_v(int idx, TCGv t0, TCGv a0)
break;
default:
case 3:
+ /* Should never happen on 32-bit targets. */
+#ifdef TARGET_X86_64
tcg_gen_qemu_ld64(t0, a0, mem_index);
+#endif
break;
}
}
/* XXX: always use ldu or lds */
-#ifndef VBOX
static inline void gen_op_ld_T0_A0(int idx)
-#else /* VBOX */
-DECLINLINE(void) gen_op_ld_T0_A0(int idx)
-#endif /* VBOX */
{
gen_op_ld_v(idx, cpu_T[0], cpu_A0);
}
-#ifndef VBOX
static inline void gen_op_ldu_T0_A0(int idx)
-#else /* VBOX */
-DECLINLINE(void) gen_op_ldu_T0_A0(int idx)
-#endif /* VBOX */
{
gen_op_ld_v(idx, cpu_T[0], cpu_A0);
}
-#ifndef VBOX
static inline void gen_op_ld_T1_A0(int idx)
-#else /* VBOX */
-DECLINLINE(void) gen_op_ld_T1_A0(int idx)
-#endif /* VBOX */
{
gen_op_ld_v(idx, cpu_T[1], cpu_A0);
}
-#ifndef VBOX
static inline void gen_op_st_v(int idx, TCGv t0, TCGv a0)
-#else /* VBOX */
-DECLINLINE(void) gen_op_st_v(int idx, TCGv t0, TCGv a0)
-#endif /* VBOX */
{
int mem_index = (idx >> 2) - 1;
switch(idx & 3) {
@@ -861,37 +702,33 @@ DECLINLINE(void) gen_op_st_v(int idx, TCGv t0, TCGv a0)
break;
default:
case 3:
+ /* Should never happen on 32-bit targets. */
+#ifdef TARGET_X86_64
tcg_gen_qemu_st64(t0, a0, mem_index);
+#endif
break;
}
}
-#ifndef VBOX
static inline void gen_op_st_T0_A0(int idx)
-#else /* VBOX */
-DECLINLINE(void) gen_op_st_T0_A0(int idx)
-#endif /* VBOX */
{
gen_op_st_v(idx, cpu_T[0], cpu_A0);
}
-#ifndef VBOX
static inline void gen_op_st_T1_A0(int idx)
-#else /* VBOX */
-DECLINLINE(void) gen_op_st_T1_A0(int idx)
-#endif /* VBOX */
{
gen_op_st_v(idx, cpu_T[1], cpu_A0);
}
#ifdef VBOX
-static void gen_check_external_event()
+
+static void gen_check_external_event(void)
{
-#if 1
+# if 1
/** @todo: once TCG codegen improves, we may want to use version
from else version */
- tcg_gen_helper_0_0(helper_check_external_event);
-#else
+ gen_helper_check_external_event();
+# else
int skip_label;
TCGv t0;
@@ -910,26 +747,15 @@ static void gen_check_external_event()
tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, skip_label);
tcg_temp_free(t0);
- tcg_gen_helper_0_0(helper_check_external_event);
+ gen_helper_check_external_event();
gen_set_label(skip_label);
-#endif
-}
-
-#if 0 /* unused code? */
-static void gen_check_external_event2()
-{
- tcg_gen_helper_0_0(helper_check_external_event);
+# endif
}
-#endif
-#endif
+#endif /* VBOX */
-#ifndef VBOX
static inline void gen_jmp_im(target_ulong pc)
-#else /* VBOX */
-DECLINLINE(void) gen_jmp_im(target_ulong pc)
-#endif /* VBOX */
{
tcg_gen_movi_tl(cpu_tmp0, pc);
tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, eip));
@@ -939,18 +765,13 @@ DECLINLINE(void) gen_jmp_im(target_ulong pc)
DECLINLINE(void) gen_update_eip(target_ulong pc)
{
gen_jmp_im(pc);
-#ifdef VBOX_DUMP_STATE
- tcg_gen_helper_0_0(helper_dump_state);
-#endif
+# ifdef VBOX_DUMP_STATE
+ gen_helper_dump_state();
+# endif
}
+#endif /* VBOX */
-#endif
-
-#ifndef VBOX
static inline void gen_string_movl_A0_ESI(DisasContext *s)
-#else /* VBOX */
-DECLINLINE(void) gen_string_movl_A0_ESI(DisasContext *s)
-#endif /* VBOX */
{
int override;
@@ -985,11 +806,7 @@ DECLINLINE(void) gen_string_movl_A0_ESI(DisasContext *s)
}
}
-#ifndef VBOX
static inline void gen_string_movl_A0_EDI(DisasContext *s)
-#else /* VBOX */
-DECLINLINE(void) gen_string_movl_A0_EDI(DisasContext *s)
-#endif /* VBOX */
{
#ifdef TARGET_X86_64
if (s->aflag == 2) {
@@ -1010,11 +827,7 @@ DECLINLINE(void) gen_string_movl_A0_EDI(DisasContext *s)
}
}
-#ifndef VBOX
static inline void gen_op_movl_T0_Dshift(int ot)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl_T0_Dshift(int ot)
-#endif /* VBOX */
{
tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUState, df));
tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
@@ -1054,45 +867,39 @@ static void gen_exts(int ot, TCGv reg)
}
}
-#ifndef VBOX
static inline void gen_op_jnz_ecx(int size, int label1)
-#else /* VBOX */
-DECLINLINE(void) gen_op_jnz_ecx(int size, int label1)
-#endif /* VBOX */
{
- tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ECX]));
+ tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
gen_extu(size + 1, cpu_tmp0);
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
}
-#ifndef VBOX
static inline void gen_op_jz_ecx(int size, int label1)
-#else /* VBOX */
-DECLINLINE(void) gen_op_jz_ecx(int size, int label1)
-#endif /* VBOX */
{
- tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ECX]));
+ tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
gen_extu(size + 1, cpu_tmp0);
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
}
-static void *helper_in_func[3] = {
- helper_inb,
- helper_inw,
- helper_inl,
-};
+static void gen_helper_in_func(int ot, TCGv v, TCGv_i32 n)
+{
+ switch (ot) {
+ case 0: gen_helper_inb(v, n); break;
+ case 1: gen_helper_inw(v, n); break;
+ case 2: gen_helper_inl(v, n); break;
+ }
-static void *helper_out_func[3] = {
- helper_outb,
- helper_outw,
- helper_outl,
-};
+}
-static void *gen_check_io_func[3] = {
- helper_check_iob,
- helper_check_iow,
- helper_check_iol,
-};
+static void gen_helper_out_func(int ot, TCGv_i32 v, TCGv_i32 n)
+{
+ switch (ot) {
+ case 0: gen_helper_outb(v, n); break;
+ case 1: gen_helper_outw(v, n); break;
+ case 2: gen_helper_outl(v, n); break;
+ }
+
+}
static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
uint32_t svm_flags)
@@ -1107,31 +914,27 @@ static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
gen_jmp_im(cur_eip);
state_saved = 1;
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_1(gen_check_io_func[ot],
- cpu_tmp2_i32);
+ switch (ot) {
+ case 0: gen_helper_check_iob(cpu_tmp2_i32); break;
+ case 1: gen_helper_check_iow(cpu_tmp2_i32); break;
+ case 2: gen_helper_check_iol(cpu_tmp2_i32); break;
+ }
}
if(s->flags & HF_SVMI_MASK) {
if (!state_saved) {
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(cur_eip);
- state_saved = 1;
}
svm_flags |= (1 << (4 + ot));
next_eip = s->pc - s->cs_base;
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_3(helper_svm_check_io,
- cpu_tmp2_i32,
- tcg_const_i32(svm_flags),
- tcg_const_i32(next_eip - cur_eip));
+ gen_helper_svm_check_io(cpu_tmp2_i32, tcg_const_i32(svm_flags),
+ tcg_const_i32(next_eip - cur_eip));
}
}
-#ifndef VBOX
static inline void gen_movs(DisasContext *s, int ot)
-#else /* VBOX */
-DECLINLINE(void) gen_movs(DisasContext *s, int ot)
-#endif /* VBOX */
{
gen_string_movl_A0_ESI(s);
gen_op_ld_T0_A0(ot + s->mem_index);
@@ -1142,11 +945,7 @@ DECLINLINE(void) gen_movs(DisasContext *s, int ot)
gen_op_add_reg_T0(s->aflag, R_EDI);
}
-#ifndef VBOX
static inline void gen_update_cc_op(DisasContext *s)
-#else /* VBOX */
-DECLINLINE(void) gen_update_cc_op(DisasContext *s)
-#endif /* VBOX */
{
if (s->cc_op != CC_OP_DYNAMIC) {
gen_op_set_cc_op(s->cc_op);
@@ -1166,21 +965,13 @@ static void gen_op_update2_cc(void)
tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
}
-#ifndef VBOX
static inline void gen_op_cmpl_T0_T1_cc(void)
-#else /* VBOX */
-DECLINLINE(void) gen_op_cmpl_T0_T1_cc(void)
-#endif /* VBOX */
{
tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
}
-#ifndef VBOX
static inline void gen_op_testl_T0_T1_cc(void)
-#else /* VBOX */
-DECLINLINE(void) gen_op_testl_T0_T1_cc(void)
-#endif /* VBOX */
{
tcg_gen_discard_tl(cpu_cc_src);
tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
@@ -1195,52 +986,18 @@ static void gen_op_update_neg_cc(void)
/* compute eflags.C to reg */
static void gen_compute_eflags_c(TCGv reg)
{
-#if TCG_TARGET_REG_BITS == 32
- tcg_gen_shli_i32(cpu_tmp2_i32, cpu_cc_op, 3);
- tcg_gen_addi_i32(cpu_tmp2_i32, cpu_tmp2_i32,
- (long)cc_table + offsetof(CCTable, compute_c));
- tcg_gen_ld_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0);
- tcg_gen_call(&tcg_ctx, cpu_tmp2_i32, TCG_CALL_PURE,
- 1, &cpu_tmp2_i32, 0, NULL);
-#else
- tcg_gen_extu_i32_tl(cpu_tmp1_i64, cpu_cc_op);
- tcg_gen_shli_i64(cpu_tmp1_i64, cpu_tmp1_i64, 4);
- tcg_gen_addi_i64(cpu_tmp1_i64, cpu_tmp1_i64,
- (long)cc_table + offsetof(CCTable, compute_c));
- tcg_gen_ld_i64(cpu_tmp1_i64, cpu_tmp1_i64, 0);
- tcg_gen_call(&tcg_ctx, cpu_tmp1_i64, TCG_CALL_PURE,
- 1, &cpu_tmp2_i32, 0, NULL);
-#endif
+ gen_helper_cc_compute_c(cpu_tmp2_i32, cpu_cc_op);
tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
}
/* compute all eflags to cc_src */
static void gen_compute_eflags(TCGv reg)
{
-#if TCG_TARGET_REG_BITS == 32
- tcg_gen_shli_i32(cpu_tmp2_i32, cpu_cc_op, 3);
- tcg_gen_addi_i32(cpu_tmp2_i32, cpu_tmp2_i32,
- (long)cc_table + offsetof(CCTable, compute_all));
- tcg_gen_ld_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0);
- tcg_gen_call(&tcg_ctx, cpu_tmp2_i32, TCG_CALL_PURE,
- 1, &cpu_tmp2_i32, 0, NULL);
-#else
- tcg_gen_extu_i32_tl(cpu_tmp1_i64, cpu_cc_op);
- tcg_gen_shli_i64(cpu_tmp1_i64, cpu_tmp1_i64, 4);
- tcg_gen_addi_i64(cpu_tmp1_i64, cpu_tmp1_i64,
- (long)cc_table + offsetof(CCTable, compute_all));
- tcg_gen_ld_i64(cpu_tmp1_i64, cpu_tmp1_i64, 0);
- tcg_gen_call(&tcg_ctx, cpu_tmp1_i64, TCG_CALL_PURE,
- 1, &cpu_tmp2_i32, 0, NULL);
-#endif
+ gen_helper_cc_compute_all(cpu_tmp2_i32, cpu_cc_op);
tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
}
-#ifndef VBOX
static inline void gen_setcc_slow_T0(DisasContext *s, int jcc_op)
-#else /* VBOX */
-DECLINLINE(void) gen_setcc_slow_T0(DisasContext *s, int jcc_op)
-#endif /* VBOX */
{
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
@@ -1346,12 +1103,8 @@ static int is_fast_jcc_case(DisasContext *s, int b)
}
/* generate a conditional jump to label 'l1' according to jump opcode
- value 'b'. In the fast case, T0 is guaranteed not to be used. */
-#ifndef VBOX
+ value 'b'. In the fast case, T0 is guaranted not to be used. */
static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
-#else /* VBOX */
-DECLINLINE(void) gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
-#endif /* VBOX */
{
int inv, jcc_op, size, cond;
TCGv t0;
@@ -1562,11 +1315,7 @@ static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
return l2;
}
-#ifndef VBOX
static inline void gen_stos(DisasContext *s, int ot)
-#else /* VBOX */
-DECLINLINE(void) gen_stos(DisasContext *s, int ot)
-#endif /* VBOX */
{
gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
gen_string_movl_A0_EDI(s);
@@ -1575,11 +1324,7 @@ DECLINLINE(void) gen_stos(DisasContext *s, int ot)
gen_op_add_reg_T0(s->aflag, R_EDI);
}
-#ifndef VBOX
static inline void gen_lods(DisasContext *s, int ot)
-#else /* VBOX */
-DECLINLINE(void) gen_lods(DisasContext *s, int ot)
-#endif /* VBOX */
{
gen_string_movl_A0_ESI(s);
gen_op_ld_T0_A0(ot + s->mem_index);
@@ -1588,11 +1333,7 @@ DECLINLINE(void) gen_lods(DisasContext *s, int ot)
gen_op_add_reg_T0(s->aflag, R_ESI);
}
-#ifndef VBOX
static inline void gen_scas(DisasContext *s, int ot)
-#else /* VBOX */
-DECLINLINE(void) gen_scas(DisasContext *s, int ot)
-#endif /* VBOX */
{
gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
gen_string_movl_A0_EDI(s);
@@ -1602,11 +1343,7 @@ DECLINLINE(void) gen_scas(DisasContext *s, int ot)
gen_op_add_reg_T0(s->aflag, R_EDI);
}
-#ifndef VBOX
static inline void gen_cmps(DisasContext *s, int ot)
-#else /* VBOX */
-DECLINLINE(void) gen_cmps(DisasContext *s, int ot)
-#endif /* VBOX */
{
gen_string_movl_A0_ESI(s);
gen_op_ld_T0_A0(ot + s->mem_index);
@@ -1618,11 +1355,7 @@ DECLINLINE(void) gen_cmps(DisasContext *s, int ot)
gen_op_add_reg_T0(s->aflag, R_EDI);
}
-#ifndef VBOX
static inline void gen_ins(DisasContext *s, int ot)
-#else /* VBOX */
-DECLINLINE(void) gen_ins(DisasContext *s, int ot)
-#endif /* VBOX */
{
if (use_icount)
gen_io_start();
@@ -1634,7 +1367,7 @@ DECLINLINE(void) gen_ins(DisasContext *s, int ot)
gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
- tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[0], cpu_tmp2_i32);
+ gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(ot + s->mem_index);
gen_op_movl_T0_Dshift(ot);
gen_op_add_reg_T0(s->aflag, R_EDI);
@@ -1642,11 +1375,7 @@ DECLINLINE(void) gen_ins(DisasContext *s, int ot)
gen_io_end();
}
-#ifndef VBOX
static inline void gen_outs(DisasContext *s, int ot)
-#else /* VBOX */
-DECLINLINE(void) gen_outs(DisasContext *s, int ot)
-#endif /* VBOX */
{
if (use_icount)
gen_io_start();
@@ -1657,7 +1386,7 @@ DECLINLINE(void) gen_outs(DisasContext *s, int ot)
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
- tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32);
+ gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
gen_op_movl_T0_Dshift(ot);
gen_op_add_reg_T0(s->aflag, R_ESI);
@@ -1667,28 +1396,11 @@ DECLINLINE(void) gen_outs(DisasContext *s, int ot)
/* same method as Valgrind : we generate jumps to current or next
instruction */
-#ifndef VBOX
#define GEN_REPZ(op) \
static inline void gen_repz_ ## op(DisasContext *s, int ot, \
target_ulong cur_eip, target_ulong next_eip) \
{ \
- int l2; \
- gen_update_cc_op(s); \
- l2 = gen_jz_ecx_string(s, next_eip); \
- gen_ ## op(s, ot); \
- gen_op_add_reg_im(s->aflag, R_ECX, -1); \
- /* a loop would cause two single step exceptions if ECX = 1 \
- before rep string_insn */ \
- if (!s->jmp_opt) \
- gen_op_jz_ecx(s->aflag, l2); \
- gen_jmp(s, cur_eip); \
-}
-#else /* VBOX */
-#define GEN_REPZ(op) \
-DECLINLINE(void) gen_repz_ ## op(DisasContext *s, int ot, \
- target_ulong cur_eip, target_ulong next_eip) \
-{ \
- int l2; \
+ int l2;\
gen_update_cc_op(s); \
l2 = gen_jz_ecx_string(s, next_eip); \
gen_ ## op(s, ot); \
@@ -1699,33 +1411,13 @@ DECLINLINE(void) gen_repz_ ## op(DisasContext *s, int ot, \
gen_op_jz_ecx(s->aflag, l2); \
gen_jmp(s, cur_eip); \
}
-#endif /* VBOX */
-#ifndef VBOX
#define GEN_REPZ2(op) \
static inline void gen_repz_ ## op(DisasContext *s, int ot, \
target_ulong cur_eip, \
target_ulong next_eip, \
int nz) \
{ \
- int l2; \
- gen_update_cc_op(s); \
- l2 = gen_jz_ecx_string(s, next_eip); \
- gen_ ## op(s, ot); \
- gen_op_add_reg_im(s->aflag, R_ECX, -1); \
- gen_op_set_cc_op(CC_OP_SUBB + ot); \
- gen_jcc1(s, CC_OP_SUBB + ot, (JCC_Z << 1) | (nz ^ 1), l2); \
- if (!s->jmp_opt) \
- gen_op_jz_ecx(s->aflag, l2); \
- gen_jmp(s, cur_eip); \
-}
-#else /* VBOX */
-#define GEN_REPZ2(op) \
-DECLINLINE(void) gen_repz_ ## op(DisasContext *s, int ot, \
- target_ulong cur_eip, \
- target_ulong next_eip, \
- int nz) \
-{ \
int l2;\
gen_update_cc_op(s); \
l2 = gen_jz_ecx_string(s, next_eip); \
@@ -1737,7 +1429,6 @@ DECLINLINE(void) gen_repz_ ## op(DisasContext *s, int ot, \
gen_op_jz_ecx(s->aflag, l2); \
gen_jmp(s, cur_eip); \
}
-#endif /* VBOX */
GEN_REPZ(movs)
GEN_REPZ(stos)
@@ -1747,28 +1438,33 @@ GEN_REPZ(outs)
GEN_REPZ2(scas)
GEN_REPZ2(cmps)
-static void *helper_fp_arith_ST0_FT0[8] = {
- helper_fadd_ST0_FT0,
- helper_fmul_ST0_FT0,
- helper_fcom_ST0_FT0,
- helper_fcom_ST0_FT0,
- helper_fsub_ST0_FT0,
- helper_fsubr_ST0_FT0,
- helper_fdiv_ST0_FT0,
- helper_fdivr_ST0_FT0,
-};
+static void gen_helper_fp_arith_ST0_FT0(int op)
+{
+ switch (op) {
+ case 0: gen_helper_fadd_ST0_FT0(); break;
+ case 1: gen_helper_fmul_ST0_FT0(); break;
+ case 2: gen_helper_fcom_ST0_FT0(); break;
+ case 3: gen_helper_fcom_ST0_FT0(); break;
+ case 4: gen_helper_fsub_ST0_FT0(); break;
+ case 5: gen_helper_fsubr_ST0_FT0(); break;
+ case 6: gen_helper_fdiv_ST0_FT0(); break;
+ case 7: gen_helper_fdivr_ST0_FT0(); break;
+ }
+}
/* NOTE the exception in "r" op ordering */
-static void *helper_fp_arith_STN_ST0[8] = {
- helper_fadd_STN_ST0,
- helper_fmul_STN_ST0,
- NULL,
- NULL,
- helper_fsubr_STN_ST0,
- helper_fsub_STN_ST0,
- helper_fdivr_STN_ST0,
- helper_fdiv_STN_ST0,
-};
+static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
+{
+ TCGv_i32 tmp = tcg_const_i32(opreg);
+ switch (op) {
+ case 0: gen_helper_fadd_STN_ST0(tmp); break;
+ case 1: gen_helper_fmul_STN_ST0(tmp); break;
+ case 4: gen_helper_fsubr_STN_ST0(tmp); break;
+ case 5: gen_helper_fsub_STN_ST0(tmp); break;
+ case 6: gen_helper_fdivr_STN_ST0(tmp); break;
+ case 7: gen_helper_fdiv_STN_ST0(tmp); break;
+ }
+}
/* if d == OR_TMP0, it means memory operand (address in A0) */
static void gen_op(DisasContext *s1, int op, int ot, int d)
@@ -1938,8 +1634,8 @@ static void gen_shift_rm_T1(DisasContext *s, int ot, int op1,
gen_op_set_cc_op(s->cc_op);
/* XXX: inefficient */
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
- t1 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
+ t1 = tcg_temp_local_new();
tcg_gen_mov_tl(t0, cpu_T[0]);
tcg_gen_mov_tl(t1, cpu_T3);
@@ -2012,11 +1708,7 @@ static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2,
}
}
-#ifndef VBOX
static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2)
-#endif /* VBOX */
{
if (arg2 >= 0)
tcg_gen_shli_tl(ret, arg1, arg2);
@@ -2024,7 +1716,6 @@ DECLINLINE(void) tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2)
tcg_gen_shri_tl(ret, arg1, -arg2);
}
-/* XXX: add faster immediate case */
static void gen_rot_rm_T1(DisasContext *s, int ot, int op1,
int is_right)
{
@@ -2033,10 +1724,10 @@ static void gen_rot_rm_T1(DisasContext *s, int ot, int op1,
TCGv t0, t1, t2, a0;
/* XXX: inefficient, but we must use local temps */
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
- t1 = tcg_temp_local_new(TCG_TYPE_TL);
- t2 = tcg_temp_local_new(TCG_TYPE_TL);
- a0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
+ t1 = tcg_temp_local_new();
+ t2 = tcg_temp_local_new();
+ a0 = tcg_temp_local_new();
if (ot == OT_QUAD)
mask = 0x3f;
@@ -2073,11 +1764,11 @@ static void gen_rot_rm_T1(DisasContext *s, int ot, int op1,
fix TCG definition) */
if (is_right) {
tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp0);
- tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(data_bits), cpu_tmp0);
+ tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
tcg_gen_shl_tl(t0, t0, cpu_tmp0);
} else {
tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp0);
- tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(data_bits), cpu_tmp0);
+ tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
tcg_gen_shr_tl(t0, t0, cpu_tmp0);
}
tcg_gen_or_tl(t0, t0, cpu_tmp4);
@@ -2121,16 +1812,82 @@ static void gen_rot_rm_T1(DisasContext *s, int ot, int op1,
tcg_temp_free(a0);
}
-static void *helper_rotc[8] = {
- helper_rclb,
- helper_rclw,
- helper_rcll,
- X86_64_ONLY(helper_rclq),
- helper_rcrb,
- helper_rcrw,
- helper_rcrl,
- X86_64_ONLY(helper_rcrq),
-};
+static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2,
+ int is_right)
+{
+ int mask;
+ int data_bits;
+ TCGv t0, t1, a0;
+
+ /* XXX: inefficient, but we must use local temps */
+ t0 = tcg_temp_local_new();
+ t1 = tcg_temp_local_new();
+ a0 = tcg_temp_local_new();
+
+ if (ot == OT_QUAD)
+ mask = 0x3f;
+ else
+ mask = 0x1f;
+
+ /* load */
+ if (op1 == OR_TMP0) {
+ tcg_gen_mov_tl(a0, cpu_A0);
+ gen_op_ld_v(ot + s->mem_index, t0, a0);
+ } else {
+ gen_op_mov_v_reg(ot, t0, op1);
+ }
+
+ gen_extu(ot, t0);
+ tcg_gen_mov_tl(t1, t0);
+
+ op2 &= mask;
+ data_bits = 8 << ot;
+ if (op2 != 0) {
+ int shift = op2 & ((1 << (3 + ot)) - 1);
+ if (is_right) {
+ tcg_gen_shri_tl(cpu_tmp4, t0, shift);
+ tcg_gen_shli_tl(t0, t0, data_bits - shift);
+ }
+ else {
+ tcg_gen_shli_tl(cpu_tmp4, t0, shift);
+ tcg_gen_shri_tl(t0, t0, data_bits - shift);
+ }
+ tcg_gen_or_tl(t0, t0, cpu_tmp4);
+ }
+
+ /* store */
+ if (op1 == OR_TMP0) {
+ gen_op_st_v(ot + s->mem_index, t0, a0);
+ } else {
+ gen_op_mov_reg_v(ot, op1, t0);
+ }
+
+ if (op2 != 0) {
+ /* update eflags */
+ if (s->cc_op != CC_OP_DYNAMIC)
+ gen_op_set_cc_op(s->cc_op);
+
+ gen_compute_eflags(cpu_cc_src);
+ tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
+ tcg_gen_xor_tl(cpu_tmp0, t1, t0);
+ tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
+ tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
+ tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
+ if (is_right) {
+ tcg_gen_shri_tl(t0, t0, data_bits - 1);
+ }
+ tcg_gen_andi_tl(t0, t0, CC_C);
+ tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
+
+ tcg_gen_discard_tl(cpu_cc_dst);
+ tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
+ s->cc_op = CC_OP_EFLAGS;
+ }
+
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ tcg_temp_free(a0);
+}
/* XXX: add faster immediate = 1 case */
static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1,
@@ -2147,8 +1904,25 @@ static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1,
else
gen_op_mov_TN_reg(ot, 0, op1);
- tcg_gen_helper_1_2(helper_rotc[ot + (is_right * 4)],
- cpu_T[0], cpu_T[0], cpu_T[1]);
+ if (is_right) {
+ switch (ot) {
+ case 0: gen_helper_rcrb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
+ case 1: gen_helper_rcrw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
+ case 2: gen_helper_rcrl(cpu_T[0], cpu_T[0], cpu_T[1]); break;
+#ifdef TARGET_X86_64
+ case 3: gen_helper_rcrq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
+#endif
+ }
+ } else {
+ switch (ot) {
+ case 0: gen_helper_rclb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
+ case 1: gen_helper_rclw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
+ case 2: gen_helper_rcll(cpu_T[0], cpu_T[0], cpu_T[1]); break;
+#ifdef TARGET_X86_64
+ case 3: gen_helper_rclq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
+#endif
+ }
+ }
/* store */
if (op1 == OR_TMP0)
gen_op_st_T0_A0(ot + s->mem_index);
@@ -2175,10 +1949,10 @@ static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1,
target_ulong mask;
TCGv t0, t1, t2, a0;
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
- t1 = tcg_temp_local_new(TCG_TYPE_TL);
- t2 = tcg_temp_local_new(TCG_TYPE_TL);
- a0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
+ t1 = tcg_temp_local_new();
+ t2 = tcg_temp_local_new();
+ a0 = tcg_temp_local_new();
if (ot == OT_QUAD)
mask = 0x3f;
@@ -2215,7 +1989,7 @@ static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1,
tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
/* only needed if count > 16, but a test would complicate */
- tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(32), t2);
+ tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5);
tcg_gen_shr_tl(t0, t0, t2);
@@ -2229,12 +2003,12 @@ static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1,
tcg_gen_ext32u_tl(t1, t1);
tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
- tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(32), cpu_tmp5);
- tcg_gen_shr_tl(cpu_tmp6, t1, cpu_tmp0);
- tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp6);
+ tcg_gen_subfi_tl(cpu_tmp0, 32, cpu_tmp5);
+ tcg_gen_shr_tl(cpu_tmp5, t1, cpu_tmp0);
+ tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp5);
tcg_gen_shl_tl(t0, t0, t2);
- tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(32), t2);
+ tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
tcg_gen_shr_tl(t1, t1, cpu_tmp5);
tcg_gen_or_tl(t0, t0, t1);
}
@@ -2247,7 +2021,7 @@ static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1,
tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
tcg_gen_shr_tl(t0, t0, t2);
- tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(data_bits), t2);
+ tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
tcg_gen_shl_tl(t1, t1, cpu_tmp5);
tcg_gen_or_tl(t0, t0, t1);
@@ -2258,7 +2032,7 @@ static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1,
tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
tcg_gen_shl_tl(t0, t0, t2);
- tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(data_bits), t2);
+ tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
tcg_gen_shr_tl(t1, t1, cpu_tmp5);
tcg_gen_or_tl(t0, t0, t1);
}
@@ -2329,6 +2103,12 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
{
switch(op) {
+ case OP_ROL:
+ gen_rot_rm_im(s1, ot, d, c, 0);
+ break;
+ case OP_ROR:
+ gen_rot_rm_im(s1, ot, d, c, 1);
+ break;
case OP_SHL:
case OP_SHL1:
gen_shift_rm_im(s1, ot, d, c, 0, 0);
@@ -2594,8 +2374,6 @@ static void gen_add_A0_ds_seg(DisasContext *s)
if (s->override >= 0) {
override = s->override;
must_add_seg = 1;
- } else {
- override = R_DS;
}
if (must_add_seg) {
#ifdef TARGET_X86_64
@@ -2641,11 +2419,7 @@ static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_s
}
}
-#ifndef VBOX
static inline uint32_t insn_get(DisasContext *s, int ot)
-#else /* VBOX */
-DECLINLINE(uint32_t) insn_get(DisasContext *s, int ot)
-#endif /* VBOX */
{
uint32_t ret;
@@ -2667,11 +2441,7 @@ DECLINLINE(uint32_t) insn_get(DisasContext *s, int ot)
return ret;
}
-#ifndef VBOX
static inline int insn_const_size(unsigned int ot)
-#else /* VBOX */
-DECLINLINE(int) insn_const_size(unsigned int ot)
-#endif /* VBOX */
{
if (ot <= OT_LONG)
return 1 << ot;
@@ -2679,11 +2449,7 @@ DECLINLINE(int) insn_const_size(unsigned int ot)
return 4;
}
-#ifndef VBOX
static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
-#else /* VBOX */
-DECLINLINE(void) gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
-#endif /* VBOX */
{
TranslationBlock *tb;
target_ulong pc;
@@ -2694,7 +2460,7 @@ DECLINLINE(void) gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
(pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) {
#ifdef VBOX
- gen_check_external_event(s);
+ gen_check_external_event();
#endif /* VBOX */
/* jump to same page: we can use a direct jump */
tcg_gen_goto_tb(tb_num);
@@ -2707,20 +2473,13 @@ DECLINLINE(void) gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
}
}
-#ifndef VBOX
static inline void gen_jcc(DisasContext *s, int b,
-#else /* VBOX */
-DECLINLINE(void) gen_jcc(DisasContext *s, int b,
-#endif /* VBOX */
target_ulong val, target_ulong next_eip)
{
int l1, l2, cc_op;
cc_op = s->cc_op;
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
+ gen_update_cc_op(s);
if (s->jmp_opt) {
l1 = gen_new_label();
gen_jcc1(s, cc_op, b, l1);
@@ -2729,7 +2488,7 @@ DECLINLINE(void) gen_jcc(DisasContext *s, int b,
gen_set_label(l1);
gen_goto_tb(s, 1, val);
- s->is_jmp = 3;
+ s->is_jmp = DISAS_TB_JUMP;
} else {
l1 = gen_new_label();
@@ -2754,7 +2513,7 @@ static void gen_setcc(DisasContext *s, int b)
if (is_fast_jcc_case(s, b)) {
/* nominal case: we use a jump */
/* XXX: make it faster by adding new instructions in TCG */
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
tcg_gen_movi_tl(t0, 0);
l1 = gen_new_label();
gen_jcc1(s, s->cc_op, b ^ 1, l1);
@@ -2764,7 +2523,7 @@ static void gen_setcc(DisasContext *s, int b)
tcg_temp_free(t0);
} else {
/* slow case: it is more efficient not to generate a jump,
- although it is questionable whether this optimization is
+ although it is questionnable whether this optimization is
worth to */
inv = b & 1;
jcc_op = (b >> 1) & 7;
@@ -2775,21 +2534,13 @@ static void gen_setcc(DisasContext *s, int b)
}
}
-#ifndef VBOX
static inline void gen_op_movl_T0_seg(int seg_reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl_T0_seg(int seg_reg)
-#endif /* VBOX */
{
tcg_gen_ld32u_tl(cpu_T[0], cpu_env,
offsetof(CPUX86State,segs[seg_reg].selector));
}
-#ifndef VBOX
static inline void gen_op_movl_seg_T0_vm(int seg_reg)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl_seg_T0_vm(int seg_reg)
-#endif /* VBOX */
{
tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
tcg_gen_st32_tl(cpu_T[0], cpu_env,
@@ -2820,34 +2571,26 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(cur_eip);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_2(helper_load_seg, tcg_const_i32(seg_reg), cpu_tmp2_i32);
+ gen_helper_load_seg(tcg_const_i32(seg_reg), cpu_tmp2_i32);
/* abort translation because the addseg value may change or
because ss32 may change. For R_SS, translation must always
stop as a special handling must be done to disable hardware
interrupts for the next instruction */
if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
- s->is_jmp = 3;
+ s->is_jmp = DISAS_TB_JUMP;
} else {
gen_op_movl_seg_T0_vm(seg_reg);
if (seg_reg == R_SS)
- s->is_jmp = 3;
+ s->is_jmp = DISAS_TB_JUMP;
}
}
-#ifndef VBOX
static inline int svm_is_rep(int prefixes)
-#else /* VBOX */
-DECLINLINE(int) svm_is_rep(int prefixes)
-#endif /* VBOX */
{
return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
}
-#ifndef VBOX
static inline void
-#else /* VBOX */
-DECLINLINE(void)
-#endif /* VBOX */
gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
uint32_t type, uint64_t param)
{
@@ -2857,25 +2600,17 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_2(helper_svm_check_intercept_param,
- tcg_const_i32(type), tcg_const_i64(param));
+ gen_helper_svm_check_intercept_param(tcg_const_i32(type),
+ tcg_const_i64(param));
}
-#ifndef VBOX
static inline void
-#else /* VBOX */
-DECLINLINE(void)
-#endif
gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
{
gen_svm_check_intercept_param(s, pc_start, type, 0);
}
-#ifndef VBOX
static inline void gen_stack_update(DisasContext *s, int addend)
-#else /* VBOX */
-DECLINLINE(void) gen_stack_update(DisasContext *s, int addend)
-#endif /* VBOX */
{
#ifdef TARGET_X86_64
if (CODE64(s)) {
@@ -3073,10 +2808,9 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
gen_op_st_T0_A0(ot + s->mem_index);
if (level) {
/* XXX: must save state */
- tcg_gen_helper_0_3(helper_enter64_level,
- tcg_const_i32(level),
- tcg_const_i32((ot == OT_QUAD)),
- cpu_T[1]);
+ gen_helper_enter64_level(tcg_const_i32(level),
+ tcg_const_i32((ot == OT_QUAD)),
+ cpu_T[1]);
}
gen_op_mov_reg_T1(ot, R_EBP);
tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
@@ -3099,10 +2833,9 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
gen_op_st_T0_A0(ot + s->mem_index);
if (level) {
/* XXX: must save state */
- tcg_gen_helper_0_3(helper_enter_level,
- tcg_const_i32(level),
- tcg_const_i32(s->dflag),
- cpu_T[1]);
+ gen_helper_enter_level(tcg_const_i32(level),
+ tcg_const_i32(s->dflag),
+ cpu_T[1]);
}
gen_op_mov_reg_T1(ot, R_EBP);
tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
@@ -3115,8 +2848,8 @@ static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(cur_eip);
- tcg_gen_helper_0_1(helper_raise_exception, tcg_const_i32(trapno));
- s->is_jmp = 3;
+ gen_helper_raise_exception(tcg_const_i32(trapno));
+ s->is_jmp = DISAS_TB_JUMP;
}
/* an interrupt is different from an exception because of the
@@ -3127,10 +2860,9 @@ static void gen_interrupt(DisasContext *s, int intno,
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(cur_eip);
- tcg_gen_helper_0_2(helper_raise_interrupt,
- tcg_const_i32(intno),
- tcg_const_i32(next_eip - cur_eip));
- s->is_jmp = 3;
+ gen_helper_raise_interrupt(tcg_const_i32(intno),
+ tcg_const_i32(next_eip - cur_eip));
+ s->is_jmp = DISAS_TB_JUMP;
}
static void gen_debug(DisasContext *s, target_ulong cur_eip)
@@ -3138,8 +2870,8 @@ static void gen_debug(DisasContext *s, target_ulong cur_eip)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(cur_eip);
- tcg_gen_helper_0_0(helper_debug);
- s->is_jmp = 3;
+ gen_helper_debug();
+ s->is_jmp = DISAS_TB_JUMP;
}
/* generate a generic end of block. Trace exception is also generated
@@ -3149,21 +2881,24 @@ static void gen_eob(DisasContext *s)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
- tcg_gen_helper_0_0(helper_reset_inhibit_irq);
+ gen_helper_reset_inhibit_irq();
}
-
+ if (s->tb->flags & HF_RF_MASK) {
+ gen_helper_reset_rf();
+ }
+ if ( s->singlestep_enabled
#ifdef VBOX
- gen_check_external_event(s);
-#endif /* VBOX */
-
- if (s->singlestep_enabled) {
- tcg_gen_helper_0_0(helper_debug);
+ && ( !(cpu_single_env->state & CPU_EMULATE_SINGLE_STEP)
+ || !(s->prefix & (PREFIX_REPNZ | PREFIX_REPZ) ))
+#endif
+ ) {
+ gen_helper_debug();
} else if (s->tf) {
- tcg_gen_helper_0_0(helper_single_step);
+ gen_helper_single_step();
} else {
tcg_gen_exit_tb(0);
}
- s->is_jmp = 3;
+ s->is_jmp = DISAS_TB_JUMP;
}
/* generate a jump to eip. No segment change must happen before as a
@@ -3171,12 +2906,9 @@ static void gen_eob(DisasContext *s)
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
{
if (s->jmp_opt) {
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
+ gen_update_cc_op(s);
gen_goto_tb(s, tb_num, eip);
- s->is_jmp = 3;
+ s->is_jmp = DISAS_TB_JUMP;
} else {
gen_jmp_im(eip);
gen_eob(s);
@@ -3188,33 +2920,21 @@ static void gen_jmp(DisasContext *s, target_ulong eip)
gen_jmp_tb(s, eip, 0);
}
-#ifndef VBOX
static inline void gen_ldq_env_A0(int idx, int offset)
-#else /* VBOX */
-DECLINLINE(void) gen_ldq_env_A0(int idx, int offset)
-#endif /* VBOX */
{
int mem_index = (idx >> 2) - 1;
tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
}
-#ifndef VBOX
static inline void gen_stq_env_A0(int idx, int offset)
-#else /* VBOX */
-DECLINLINE(void) gen_stq_env_A0(int idx, int offset)
-#endif /* VBOX */
{
int mem_index = (idx >> 2) - 1;
tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
}
-#ifndef VBOX
static inline void gen_ldo_env_A0(int idx, int offset)
-#else /* VBOX */
-DECLINLINE(void) gen_ldo_env_A0(int idx, int offset)
-#endif /* VBOX */
{
int mem_index = (idx >> 2) - 1;
tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
@@ -3224,11 +2944,7 @@ DECLINLINE(void) gen_ldo_env_A0(int idx, int offset)
tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
}
-#ifndef VBOX
static inline void gen_sto_env_A0(int idx, int offset)
-#else /* VBOX */
-DECLINLINE(void) gen_sto_env_A0(int idx, int offset)
-#endif /* VBOX */
{
int mem_index = (idx >> 2) - 1;
tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
@@ -3238,11 +2954,7 @@ DECLINLINE(void) gen_sto_env_A0(int idx, int offset)
tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index);
}
-#ifndef VBOX
static inline void gen_op_movo(int d_offset, int s_offset)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movo(int d_offset, int s_offset)
-#endif /* VBOX */
{
tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
@@ -3250,31 +2962,19 @@ DECLINLINE(void) gen_op_movo(int d_offset, int s_offset)
tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
}
-#ifndef VBOX
static inline void gen_op_movq(int d_offset, int s_offset)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movq(int d_offset, int s_offset)
-#endif /* VBOX */
{
tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
}
-#ifndef VBOX
static inline void gen_op_movl(int d_offset, int s_offset)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movl(int d_offset, int s_offset)
-#endif /* VBOX */
{
tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
}
-#ifndef VBOX
static inline void gen_op_movq_env_0(int d_offset)
-#else /* VBOX */
-DECLINLINE(void) gen_op_movq_env_0(int d_offset)
-#endif /* VBOX */
{
tcg_gen_movi_i64(cpu_tmp1_i64, 0);
tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
@@ -3283,9 +2983,9 @@ DECLINLINE(void) gen_op_movq_env_0(int d_offset)
#define SSE_SPECIAL ((void *)1)
#define SSE_DUMMY ((void *)2)
-#define MMX_OP2(x) { helper_ ## x ## _mmx, helper_ ## x ## _xmm }
-#define SSE_FOP(x) { helper_ ## x ## ps, helper_ ## x ## pd, \
- helper_ ## x ## ss, helper_ ## x ## sd, }
+#define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
+#define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
+ gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
static void *sse_op_table1[256][4] = {
/* 3DNow! extensions */
@@ -3296,39 +2996,39 @@ static void *sse_op_table1[256][4] = {
[0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
[0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
[0x13] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */
- [0x14] = { helper_punpckldq_xmm, helper_punpcklqdq_xmm },
- [0x15] = { helper_punpckhdq_xmm, helper_punpckhqdq_xmm },
+ [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
+ [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
[0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd, movshdup */
[0x17] = { SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd */
[0x28] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
[0x29] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
[0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
- [0x2b] = { SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd */
+ [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
[0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
[0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
- [0x2e] = { helper_ucomiss, helper_ucomisd },
- [0x2f] = { helper_comiss, helper_comisd },
+ [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
+ [0x2f] = { gen_helper_comiss, gen_helper_comisd },
[0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
[0x51] = SSE_FOP(sqrt),
- [0x52] = { helper_rsqrtps, NULL, helper_rsqrtss, NULL },
- [0x53] = { helper_rcpps, NULL, helper_rcpss, NULL },
- [0x54] = { helper_pand_xmm, helper_pand_xmm }, /* andps, andpd */
- [0x55] = { helper_pandn_xmm, helper_pandn_xmm }, /* andnps, andnpd */
- [0x56] = { helper_por_xmm, helper_por_xmm }, /* orps, orpd */
- [0x57] = { helper_pxor_xmm, helper_pxor_xmm }, /* xorps, xorpd */
+ [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
+ [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
+ [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
+ [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
+ [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
+ [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
[0x58] = SSE_FOP(add),
[0x59] = SSE_FOP(mul),
- [0x5a] = { helper_cvtps2pd, helper_cvtpd2ps,
- helper_cvtss2sd, helper_cvtsd2ss },
- [0x5b] = { helper_cvtdq2ps, helper_cvtps2dq, helper_cvttps2dq },
+ [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
+ gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
+ [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
[0x5c] = SSE_FOP(sub),
[0x5d] = SSE_FOP(min),
[0x5e] = SSE_FOP(div),
[0x5f] = SSE_FOP(max),
[0xc2] = SSE_FOP(cmpeq),
- [0xc6] = { helper_shufps, helper_shufpd },
+ [0xc6] = { gen_helper_shufps, gen_helper_shufpd },
[0x38] = { SSE_SPECIAL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* SSSE3/SSE4 */
[0x3a] = { SSE_SPECIAL, SSE_SPECIAL }, /* SSSE3/SSE4 */
@@ -3346,14 +3046,14 @@ static void *sse_op_table1[256][4] = {
[0x69] = MMX_OP2(punpckhwd),
[0x6a] = MMX_OP2(punpckhdq),
[0x6b] = MMX_OP2(packssdw),
- [0x6c] = { NULL, helper_punpcklqdq_xmm },
- [0x6d] = { NULL, helper_punpckhqdq_xmm },
+ [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
+ [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
[0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
[0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
- [0x70] = { helper_pshufw_mmx,
- helper_pshufd_xmm,
- helper_pshufhw_xmm,
- helper_pshuflw_xmm },
+ [0x70] = { gen_helper_pshufw_mmx,
+ gen_helper_pshufd_xmm,
+ gen_helper_pshufhw_xmm,
+ gen_helper_pshuflw_xmm },
[0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
[0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
[0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
@@ -3361,13 +3061,15 @@ static void *sse_op_table1[256][4] = {
[0x75] = MMX_OP2(pcmpeqw),
[0x76] = MMX_OP2(pcmpeql),
[0x77] = { SSE_DUMMY }, /* emms */
- [0x7c] = { NULL, helper_haddpd, NULL, helper_haddps },
- [0x7d] = { NULL, helper_hsubpd, NULL, helper_hsubps },
+ [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
+ [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
+ [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
+ [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
[0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
[0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
[0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
[0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
- [0xd0] = { NULL, helper_addsubpd, NULL, helper_addsubps },
+ [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
[0xd1] = MMX_OP2(psrlw),
[0xd2] = MMX_OP2(psrld),
[0xd3] = MMX_OP2(psrlq),
@@ -3389,7 +3091,7 @@ static void *sse_op_table1[256][4] = {
[0xe3] = MMX_OP2(pavgw),
[0xe4] = MMX_OP2(pmulhuw),
[0xe5] = MMX_OP2(pmulhw),
- [0xe6] = { NULL, helper_cvttpd2dq, helper_cvtdq2pd, helper_cvtpd2dq },
+ [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
[0xe7] = { SSE_SPECIAL , SSE_SPECIAL }, /* movntq, movntq */
[0xe8] = MMX_OP2(psubsb),
[0xe9] = MMX_OP2(psubsw),
@@ -3424,26 +3126,26 @@ static void *sse_op_table2[3 * 8][2] = {
[8 + 4] = MMX_OP2(psrad),
[8 + 6] = MMX_OP2(pslld),
[16 + 2] = MMX_OP2(psrlq),
- [16 + 3] = { NULL, helper_psrldq_xmm },
+ [16 + 3] = { NULL, gen_helper_psrldq_xmm },
[16 + 6] = MMX_OP2(psllq),
- [16 + 7] = { NULL, helper_pslldq_xmm },
+ [16 + 7] = { NULL, gen_helper_pslldq_xmm },
};
static void *sse_op_table3[4 * 3] = {
- helper_cvtsi2ss,
- helper_cvtsi2sd,
- X86_64_ONLY(helper_cvtsq2ss),
- X86_64_ONLY(helper_cvtsq2sd),
-
- helper_cvttss2si,
- helper_cvttsd2si,
- X86_64_ONLY(helper_cvttss2sq),
- X86_64_ONLY(helper_cvttsd2sq),
-
- helper_cvtss2si,
- helper_cvtsd2si,
- X86_64_ONLY(helper_cvtss2sq),
- X86_64_ONLY(helper_cvtsd2sq),
+ gen_helper_cvtsi2ss,
+ gen_helper_cvtsi2sd,
+ X86_64_ONLY(gen_helper_cvtsq2ss),
+ X86_64_ONLY(gen_helper_cvtsq2sd),
+
+ gen_helper_cvttss2si,
+ gen_helper_cvttsd2si,
+ X86_64_ONLY(gen_helper_cvttss2sq),
+ X86_64_ONLY(gen_helper_cvttsd2sq),
+
+ gen_helper_cvtss2si,
+ gen_helper_cvtsd2si,
+ X86_64_ONLY(gen_helper_cvtss2sq),
+ X86_64_ONLY(gen_helper_cvtsd2sq),
};
static void *sse_op_table4[8][4] = {
@@ -3458,38 +3160,38 @@ static void *sse_op_table4[8][4] = {
};
static void *sse_op_table5[256] = {
- [0x0c] = helper_pi2fw,
- [0x0d] = helper_pi2fd,
- [0x1c] = helper_pf2iw,
- [0x1d] = helper_pf2id,
- [0x8a] = helper_pfnacc,
- [0x8e] = helper_pfpnacc,
- [0x90] = helper_pfcmpge,
- [0x94] = helper_pfmin,
- [0x96] = helper_pfrcp,
- [0x97] = helper_pfrsqrt,
- [0x9a] = helper_pfsub,
- [0x9e] = helper_pfadd,
- [0xa0] = helper_pfcmpgt,
- [0xa4] = helper_pfmax,
- [0xa6] = helper_movq, /* pfrcpit1; no need to actually increase precision */
- [0xa7] = helper_movq, /* pfrsqit1 */
- [0xaa] = helper_pfsubr,
- [0xae] = helper_pfacc,
- [0xb0] = helper_pfcmpeq,
- [0xb4] = helper_pfmul,
- [0xb6] = helper_movq, /* pfrcpit2 */
- [0xb7] = helper_pmulhrw_mmx,
- [0xbb] = helper_pswapd,
- [0xbf] = helper_pavgb_mmx /* pavgusb */
+ [0x0c] = gen_helper_pi2fw,
+ [0x0d] = gen_helper_pi2fd,
+ [0x1c] = gen_helper_pf2iw,
+ [0x1d] = gen_helper_pf2id,
+ [0x8a] = gen_helper_pfnacc,
+ [0x8e] = gen_helper_pfpnacc,
+ [0x90] = gen_helper_pfcmpge,
+ [0x94] = gen_helper_pfmin,
+ [0x96] = gen_helper_pfrcp,
+ [0x97] = gen_helper_pfrsqrt,
+ [0x9a] = gen_helper_pfsub,
+ [0x9e] = gen_helper_pfadd,
+ [0xa0] = gen_helper_pfcmpgt,
+ [0xa4] = gen_helper_pfmax,
+ [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
+ [0xa7] = gen_helper_movq, /* pfrsqit1 */
+ [0xaa] = gen_helper_pfsubr,
+ [0xae] = gen_helper_pfacc,
+ [0xb0] = gen_helper_pfcmpeq,
+ [0xb4] = gen_helper_pfmul,
+ [0xb6] = gen_helper_movq, /* pfrcpit2 */
+ [0xb7] = gen_helper_pmulhrw_mmx,
+ [0xbb] = gen_helper_pswapd,
+ [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
};
struct sse_op_helper_s {
void *op[2]; uint32_t ext_mask;
};
#define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
-#define SSE41_OP(x) { { NULL, helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
-#define SSE42_OP(x) { { NULL, helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
+#define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
+#define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
#define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
static struct sse_op_helper_s sse_op_table6[256] = {
[0x00] = SSSE3_OP(pshufb),
@@ -3610,18 +3312,18 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
goto illegal_op;
/* femms */
- tcg_gen_helper_0_0(helper_emms);
+ gen_helper_emms();
return;
}
if (b == 0x77) {
/* emms */
- tcg_gen_helper_0_0(helper_emms);
+ gen_helper_emms();
return;
}
/* prepare MMX state (XXX: optimize by storing fptt and fptags in
the static cpu state) */
if (!is_xmm) {
- tcg_gen_helper_0_0(helper_enter_mmx);
+ gen_helper_enter_mmx();
}
modrm = ldub_code(s->pc++);
@@ -3652,6 +3354,20 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
break;
+ case 0x22b: /* movntss */
+ case 0x32b: /* movntsd */
+ if (mod == 3)
+ goto illegal_op;
+ gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
+ if (b1 & 1) {
+ gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,
+ xmm_regs[reg]));
+ } else {
+ tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
+ xmm_regs[reg].XMM_L(0)));
+ gen_op_st_T0_A0(OT_LONG + s->mem_index);
+ }
+ break;
case 0x6e: /* movd mm, ea */
#ifdef TARGET_X86_64
if (s->dflag == 2) {
@@ -3663,7 +3379,8 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
offsetof(CPUX86State,fpregs[reg].mmx));
- tcg_gen_helper_0_2(helper_movl_mm_T0_mmx, cpu_ptr0, cpu_T[0]);
+ tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
+ gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
}
break;
case 0x16e: /* movd xmm, ea */
@@ -3672,7 +3389,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
offsetof(CPUX86State,xmm_regs[reg]));
- tcg_gen_helper_0_2(helper_movq_mm_T0_xmm, cpu_ptr0, cpu_T[0]);
+ gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T[0]);
} else
#endif
{
@@ -3680,7 +3397,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
offsetof(CPUX86State,xmm_regs[reg]));
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_2(helper_movl_mm_T0_xmm, cpu_ptr0, cpu_tmp2_i32);
+ gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
}
break;
case 0x6f: /* movq mm, ea */
@@ -3806,6 +3523,25 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
break;
+ case 0x178:
+ case 0x378:
+ {
+ int bit_index, field_length;
+
+ if (b1 == 1 && reg != 0)
+ goto illegal_op;
+ field_length = ldub_code(s->pc++) & 0x3F;
+ bit_index = ldub_code(s->pc++) & 0x3F;
+ tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
+ offsetof(CPUX86State,xmm_regs[reg]));
+ if (b1 == 1)
+ gen_helper_extrq_i(cpu_ptr0, tcg_const_i32(bit_index),
+ tcg_const_i32(field_length));
+ else
+ gen_helper_insertq_i(cpu_ptr0, tcg_const_i32(bit_index),
+ tcg_const_i32(field_length));
+ }
+ break;
case 0x7e: /* movd ea, mm */
#ifdef TARGET_X86_64
if (s->dflag == 2) {
@@ -3915,6 +3651,9 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
case 0x171: /* shift xmm, im */
case 0x172:
case 0x173:
+ if (b1 >= 2) {
+ goto illegal_op;
+ }
val = ldub_code(s->pc++);
if (is_xmm) {
gen_op_movl_T0_im(val);
@@ -3941,13 +3680,13 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
}
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
- tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_ptr1);
+ ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
break;
case 0x050: /* movmskps */
rm = (modrm & 7) | REX_B(s);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
offsetof(CPUX86State,xmm_regs[rm]));
- tcg_gen_helper_1_1(helper_movmskps, cpu_tmp2_i32, cpu_ptr0);
+ gen_helper_movmskps(cpu_tmp2_i32, cpu_ptr0);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_mov_reg_T0(OT_LONG, reg);
break;
@@ -3955,13 +3694,13 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
rm = (modrm & 7) | REX_B(s);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
offsetof(CPUX86State,xmm_regs[rm]));
- tcg_gen_helper_1_1(helper_movmskpd, cpu_tmp2_i32, cpu_ptr0);
+ gen_helper_movmskpd(cpu_tmp2_i32, cpu_ptr0);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_mov_reg_T0(OT_LONG, reg);
break;
case 0x02a: /* cvtpi2ps */
case 0x12a: /* cvtpi2pd */
- tcg_gen_helper_0_0(helper_enter_mmx);
+ gen_helper_enter_mmx();
if (mod != 3) {
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
op2_offset = offsetof(CPUX86State,mmx_t0);
@@ -3975,11 +3714,11 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
switch(b >> 8) {
case 0x0:
- tcg_gen_helper_0_2(helper_cvtpi2ps, cpu_ptr0, cpu_ptr1);
+ gen_helper_cvtpi2ps(cpu_ptr0, cpu_ptr1);
break;
default:
case 0x1:
- tcg_gen_helper_0_2(helper_cvtpi2pd, cpu_ptr0, cpu_ptr1);
+ gen_helper_cvtpi2pd(cpu_ptr0, cpu_ptr1);
break;
}
break;
@@ -3992,16 +3731,16 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
sse_op2 = sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2)];
if (ot == OT_LONG) {
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_tmp2_i32);
+ ((void (*)(TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_tmp2_i32);
} else {
- tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_T[0]);
+ ((void (*)(TCGv_ptr, TCGv))sse_op2)(cpu_ptr0, cpu_T[0]);
}
break;
case 0x02c: /* cvttps2pi */
case 0x12c: /* cvttpd2pi */
case 0x02d: /* cvtps2pi */
case 0x12d: /* cvtpd2pi */
- tcg_gen_helper_0_0(helper_enter_mmx);
+ gen_helper_enter_mmx();
if (mod != 3) {
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
op2_offset = offsetof(CPUX86State,xmm_t0);
@@ -4015,16 +3754,16 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
switch(b) {
case 0x02c:
- tcg_gen_helper_0_2(helper_cvttps2pi, cpu_ptr0, cpu_ptr1);
+ gen_helper_cvttps2pi(cpu_ptr0, cpu_ptr1);
break;
case 0x12c:
- tcg_gen_helper_0_2(helper_cvttpd2pi, cpu_ptr0, cpu_ptr1);
+ gen_helper_cvttpd2pi(cpu_ptr0, cpu_ptr1);
break;
case 0x02d:
- tcg_gen_helper_0_2(helper_cvtps2pi, cpu_ptr0, cpu_ptr1);
+ gen_helper_cvtps2pi(cpu_ptr0, cpu_ptr1);
break;
case 0x12d:
- tcg_gen_helper_0_2(helper_cvtpd2pi, cpu_ptr0, cpu_ptr1);
+ gen_helper_cvtpd2pi(cpu_ptr0, cpu_ptr1);
break;
}
break;
@@ -4050,10 +3789,10 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
(b & 1) * 4];
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
if (ot == OT_LONG) {
- tcg_gen_helper_1_1(sse_op2, cpu_tmp2_i32, cpu_ptr0);
+ ((void (*)(TCGv_i32, TCGv_ptr))sse_op2)(cpu_tmp2_i32, cpu_ptr0);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
} else {
- tcg_gen_helper_1_1(sse_op2, cpu_T[0], cpu_ptr0);
+ ((void (*)(TCGv, TCGv_ptr))sse_op2)(cpu_T[0], cpu_ptr0);
}
gen_op_mov_reg_T0(ot, reg);
break;
@@ -4104,14 +3843,14 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
}
break;
case 0x2d6: /* movq2dq */
- tcg_gen_helper_0_0(helper_enter_mmx);
+ gen_helper_enter_mmx();
rm = (modrm & 7);
gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
offsetof(CPUX86State,fpregs[rm].mmx));
gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
break;
case 0x3d6: /* movdq2q */
- tcg_gen_helper_0_0(helper_enter_mmx);
+ gen_helper_enter_mmx();
rm = (modrm & 7) | REX_B(s);
gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
@@ -4123,11 +3862,11 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
if (b1) {
rm = (modrm & 7) | REX_B(s);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
- tcg_gen_helper_1_1(helper_pmovmskb_xmm, cpu_tmp2_i32, cpu_ptr0);
+ gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_ptr0);
} else {
rm = (modrm & 7);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
- tcg_gen_helper_1_1(helper_pmovmskb_mmx, cpu_tmp2_i32, cpu_ptr0);
+ gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_ptr0);
}
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
reg = ((modrm >> 3) & 7) | rex_r;
@@ -4142,6 +3881,9 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
rm = modrm & 7;
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
+ if (b1 >= 2) {
+ goto illegal_op;
+ }
sse_op2 = sse_op_table6[b].op[b1];
if (!sse_op2)
@@ -4199,7 +3941,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
- tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_ptr1);
+ ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
if (b == 0x17)
s->cc_op = CC_OP_EFLAGS;
@@ -4228,8 +3970,8 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
gen_op_mov_TN_reg(OT_LONG, 0, reg);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
- tcg_gen_helper_1_3(helper_crc32, cpu_T[0], cpu_tmp2_i32,
- cpu_T[0], tcg_const_i32(8 << ot));
+ gen_helper_crc32(cpu_T[0], cpu_tmp2_i32,
+ cpu_T[0], tcg_const_i32(8 << ot));
ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
gen_op_mov_reg_T0(ot, reg);
@@ -4241,6 +3983,9 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
rm = modrm & 7;
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
+ if (b1 >= 2) {
+ goto illegal_op;
+ }
sse_op2 = sse_op_table7[b].op[b1];
if (!sse_op2)
@@ -4279,12 +4024,14 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
offsetof(CPUX86State,
xmm_regs[reg].XMM_L(val & 3)));
+ tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
if (mod == 3)
- gen_op_mov_reg_v(ot, rm, cpu_tmp2_i32);
+ gen_op_mov_reg_v(ot, rm, cpu_T[0]);
else
- tcg_gen_qemu_st32(cpu_tmp2_i32, cpu_A0,
+ tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
(s->mem_index >> 2) - 1);
} else { /* pextrq */
+#ifdef TARGET_X86_64
tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
offsetof(CPUX86State,
xmm_regs[reg].XMM_Q(val & 1)));
@@ -4293,6 +4040,9 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
else
tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
+#else
+ goto illegal_op;
+#endif
}
break;
case 0x17: /* extractps */
@@ -4308,19 +4058,21 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
if (mod == 3)
gen_op_mov_TN_reg(OT_LONG, 0, rm);
else
- tcg_gen_qemu_ld8u(cpu_T[0], cpu_A0,
+ tcg_gen_qemu_ld8u(cpu_tmp0, cpu_A0,
(s->mem_index >> 2) - 1);
- tcg_gen_st8_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
+ tcg_gen_st8_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State,
xmm_regs[reg].XMM_B(val & 15)));
break;
case 0x21: /* insertps */
- if (mod == 3)
+ if (mod == 3) {
tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
offsetof(CPUX86State,xmm_regs[rm]
.XMM_L((val >> 6) & 3)));
- else
- tcg_gen_qemu_ld32u(cpu_tmp2_i32, cpu_A0,
+ } else {
+ tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
(s->mem_index >> 2) - 1);
+ tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
+ }
tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
offsetof(CPUX86State,xmm_regs[reg]
.XMM_L((val >> 4) & 3)));
@@ -4344,14 +4096,16 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
case 0x22:
if (ot == OT_LONG) { /* pinsrd */
if (mod == 3)
- gen_op_mov_v_reg(ot, cpu_tmp2_i32, rm);
+ gen_op_mov_v_reg(ot, cpu_tmp0, rm);
else
- tcg_gen_qemu_ld32u(cpu_tmp2_i32, cpu_A0,
+ tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
(s->mem_index >> 2) - 1);
+ tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
offsetof(CPUX86State,
xmm_regs[reg].XMM_L(val & 3)));
} else { /* pinsrq */
+#ifdef TARGET_X86_64
if (mod == 3)
gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
else
@@ -4360,6 +4114,9 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
offsetof(CPUX86State,
xmm_regs[reg].XMM_Q(val & 1)));
+#else
+ goto illegal_op;
+#endif
}
break;
}
@@ -4397,7 +4154,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
- tcg_gen_helper_0_3(sse_op2, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
+ ((void (*)(TCGv_ptr, TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
break;
default:
goto illegal_op;
@@ -4457,14 +4214,14 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
goto illegal_op;
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
- tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_ptr1);
+ ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
break;
case 0x70: /* pshufx insn */
case 0xc6: /* pshufx insn */
val = ldub_code(s->pc++);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
- tcg_gen_helper_0_3(sse_op2, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
+ ((void (*)(TCGv_ptr, TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
break;
case 0xc2:
/* compare insns */
@@ -4474,7 +4231,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
sse_op2 = sse_op_table4[val][b1];
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
- tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_ptr1);
+ ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
break;
case 0xf7:
/* maskmov : we must prepare A0 */
@@ -4494,12 +4251,12 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
- tcg_gen_helper_0_3(sse_op2, cpu_ptr0, cpu_ptr1, cpu_A0);
+ ((void (*)(TCGv_ptr, TCGv_ptr, TCGv))sse_op2)(cpu_ptr0, cpu_ptr1, cpu_A0);
break;
default:
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
- tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_ptr1);
+ ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
break;
}
if (b == 0x2e || b == 0x2f) {
@@ -4650,7 +4407,6 @@ static bool is_invalid_lock_sequence(DisasContext *s, target_ulong pc_start, int
}
#endif /* VBOX */
-
/* convert one instruction. s->is_jmp is set if the translation must
be stopped. Return the next pc value */
static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
@@ -4661,9 +4417,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
target_ulong next_eip, tval;
int rex_w, rex_r;
- if (unlikely(loglevel & CPU_LOG_TB_OP))
+ if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
tcg_gen_debug_insn_start(pc_start);
-
s->pc = pc_start;
prefixes = 0;
aflag = s->code32;
@@ -4684,7 +4439,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_update_eip(pc_start - s->cs_base);
# endif
-#endif
+#endif /* VBOX */
next_byte:
b = ldub_code(s->pc);
@@ -4795,14 +4550,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
/* lock generation */
#ifndef VBOX
if (prefixes & PREFIX_LOCK)
- tcg_gen_helper_0_0(helper_lock);
+ gen_helper_lock();
#else /* VBOX */
if (prefixes & PREFIX_LOCK) {
if (is_invalid_lock_sequence(s, pc_start, b)) {
gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
return s->pc;
}
- tcg_gen_helper_0_0(helper_lock);
+ gen_helper_lock();
}
#endif /* VBOX */
@@ -5023,9 +4778,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
#else
{
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I64);
- t1 = tcg_temp_new(TCG_TYPE_I64);
+ TCGv_i64 t0, t1;
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
tcg_gen_extu_i32_i64(t0, cpu_T[0]);
tcg_gen_extu_i32_i64(t1, cpu_T[1]);
@@ -5043,7 +4798,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
break;
#ifdef TARGET_X86_64
case OT_QUAD:
- tcg_gen_helper_0_1(helper_mulq_EAX_T0, cpu_T[0]);
+ gen_helper_mulq_EAX_T0(cpu_T[0]);
s->cc_op = CC_OP_MULQ;
break;
#endif
@@ -5092,9 +4847,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_op_mov_reg_T0(OT_LONG, R_EDX);
#else
{
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I64);
- t1 = tcg_temp_new(TCG_TYPE_I64);
+ TCGv_i64 t0, t1;
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
tcg_gen_ext_i32_i64(t0, cpu_T[0]);
tcg_gen_ext_i32_i64(t1, cpu_T[1]);
@@ -5113,7 +4868,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
break;
#ifdef TARGET_X86_64
case OT_QUAD:
- tcg_gen_helper_0_1(helper_imulq_EAX_T0, cpu_T[0]);
+ gen_helper_imulq_EAX_T0(cpu_T[0]);
s->cc_op = CC_OP_MULQ;
break;
#endif
@@ -5123,21 +4878,21 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
switch(ot) {
case OT_BYTE:
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_divb_AL, cpu_T[0]);
+ gen_helper_divb_AL(cpu_T[0]);
break;
case OT_WORD:
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_divw_AX, cpu_T[0]);
+ gen_helper_divw_AX(cpu_T[0]);
break;
default:
case OT_LONG:
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_divl_EAX, cpu_T[0]);
+ gen_helper_divl_EAX(cpu_T[0]);
break;
#ifdef TARGET_X86_64
case OT_QUAD:
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_divq_EAX, cpu_T[0]);
+ gen_helper_divq_EAX(cpu_T[0]);
break;
#endif
}
@@ -5146,21 +4901,21 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
switch(ot) {
case OT_BYTE:
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_idivb_AL, cpu_T[0]);
+ gen_helper_idivb_AL(cpu_T[0]);
break;
case OT_WORD:
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_idivw_AX, cpu_T[0]);
+ gen_helper_idivw_AX(cpu_T[0]);
break;
default:
case OT_LONG:
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_idivl_EAX, cpu_T[0]);
+ gen_helper_idivl_EAX(cpu_T[0]);
break;
#ifdef TARGET_X86_64
case OT_QUAD:
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_idivq_EAX, cpu_T[0]);
+ gen_helper_idivq_EAX(cpu_T[0]);
break;
#endif
}
@@ -5189,9 +4944,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
/* operand size for jumps is 64 bit */
ot = OT_QUAD;
} else if (op == 3 || op == 5) {
- /* for call calls, the operand is 16 or 32 bit, even
- in long mode */
- ot = dflag ? OT_LONG : OT_WORD;
+ ot = dflag ? OT_LONG + (rex_w == 1) : OT_WORD;
} else if (op == 6) {
/* default push size is 64 bit */
ot = dflag ? OT_QUAD : OT_WORD;
@@ -5244,16 +4997,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_4(helper_lcall_protected,
- cpu_tmp2_i32, cpu_T[1],
- tcg_const_i32(dflag),
- tcg_const_i32(s->pc - pc_start));
+ gen_helper_lcall_protected(cpu_tmp2_i32, cpu_T[1],
+ tcg_const_i32(dflag),
+ tcg_const_i32(s->pc - pc_start));
} else {
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_4(helper_lcall_real,
- cpu_tmp2_i32, cpu_T[1],
- tcg_const_i32(dflag),
- tcg_const_i32(s->pc - s->cs_base));
+ gen_helper_lcall_real(cpu_tmp2_i32, cpu_T[1],
+ tcg_const_i32(dflag),
+ tcg_const_i32(s->pc - s->cs_base));
}
gen_eob(s);
break;
@@ -5273,10 +5024,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_3(helper_ljmp_protected,
- cpu_tmp2_i32,
- cpu_T[1],
- tcg_const_i32(s->pc - pc_start));
+ gen_helper_ljmp_protected(cpu_tmp2_i32, cpu_T[1],
+ tcg_const_i32(s->pc - pc_start));
} else {
gen_op_movl_seg_T0_vm(R_CS);
gen_op_movl_T0_T1();
@@ -5300,8 +5049,6 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
ot = dflag + OT_WORD;
modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- rm = (modrm & 7) | REX_B(s);
reg = ((modrm >> 3) & 7) | rex_r;
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
@@ -5385,7 +5132,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
#ifdef TARGET_X86_64
if (ot == OT_QUAD) {
- tcg_gen_helper_1_2(helper_imulq_T0_T1, cpu_T[0], cpu_T[0], cpu_T[1]);
+ gen_helper_imulq_T0_T1(cpu_T[0], cpu_T[0], cpu_T[1]);
} else
#endif
if (ot == OT_LONG) {
@@ -5398,9 +5145,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
#else
{
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I64);
- t1 = tcg_temp_new(TCG_TYPE_I64);
+ TCGv_i64 t0, t1;
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
tcg_gen_ext_i32_i64(t0, cpu_T[0]);
tcg_gen_ext_i32_i64(t1, cpu_T[1]);
tcg_gen_mul_i64(t0, t0, t1);
@@ -5464,10 +5211,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
modrm = ldub_code(s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
- t1 = tcg_temp_local_new(TCG_TYPE_TL);
- t2 = tcg_temp_local_new(TCG_TYPE_TL);
- a0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
+ t1 = tcg_temp_local_new();
+ t2 = tcg_temp_local_new();
+ a0 = tcg_temp_local_new();
gen_op_mov_v_reg(ot, t1, reg);
if (mod == 3) {
rm = (modrm & 7) | REX_B(s);
@@ -5479,8 +5226,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
rm = 0; /* avoid warning */
}
label1 = gen_new_label();
- tcg_gen_ld_tl(t2, cpu_env, offsetof(CPUState, regs[R_EAX]));
- tcg_gen_sub_tl(t2, t2, t0);
+ tcg_gen_sub_tl(t2, cpu_regs[R_EAX], t0);
gen_extu(ot, t2);
tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
if (mod == 3) {
@@ -5519,7 +5265,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- tcg_gen_helper_0_1(helper_cmpxchg16b, cpu_A0);
+ gen_helper_cmpxchg16b(cpu_A0);
} else
#endif
{
@@ -5529,7 +5275,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- tcg_gen_helper_0_1(helper_cmpxchg8b, cpu_A0);
+ gen_helper_cmpxchg8b(cpu_A0);
}
s->cc_op = CC_OP_EFLAGS;
break;
@@ -5655,7 +5401,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
/* If several instructions disable interrupts, only the
_first_ does it */
if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
- tcg_gen_helper_0_0(helper_set_inhibit_irq);
+ gen_helper_set_inhibit_irq();
s->tf = 0;
}
if (s->is_jmp) {
@@ -5735,7 +5481,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
/* If several instructions disable interrupts, only the
_first_ does it */
if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
- tcg_gen_helper_0_0(helper_set_inhibit_irq);
+ gen_helper_set_inhibit_irq();
s->tf = 0;
}
if (s->is_jmp) {
@@ -5904,6 +5650,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
break;
case 0x91 ... 0x97: /* xchg R, EAX */
+ do_xchg_reg_eax:
ot = dflag + OT_WORD;
reg = (b & 7) | REX_B(s);
rm = R_EAX;
@@ -5929,11 +5676,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_op_mov_TN_reg(ot, 0, reg);
/* for xchg, lock is implicit */
if (!(prefixes & PREFIX_LOCK))
- tcg_gen_helper_0_0(helper_lock);
+ gen_helper_lock();
gen_op_ld_T1_A0(ot + s->mem_index);
gen_op_st_T0_A0(ot + s->mem_index);
if (!(prefixes & PREFIX_LOCK))
- tcg_gen_helper_0_0(helper_unlock);
+ gen_helper_unlock();
gen_op_mov_reg_T1(ot, reg);
}
break;
@@ -6058,7 +5805,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
val = ldub_code(s->pc++);
tcg_gen_movi_tl(cpu_T3, val);
} else {
- tcg_gen_ld_tl(cpu_T3, cpu_env, offsetof(CPUState, regs[R_ECX]));
+ tcg_gen_mov_tl(cpu_T3, cpu_regs[R_ECX]);
}
gen_shiftd_rm_T1_T3(s, ot, opreg, op);
break;
@@ -6092,30 +5839,30 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
case 0:
gen_op_ld_T0_A0(OT_LONG + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_1(helper_flds_FT0, cpu_tmp2_i32);
+ gen_helper_flds_FT0(cpu_tmp2_i32);
break;
case 1:
gen_op_ld_T0_A0(OT_LONG + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_1(helper_fildl_FT0, cpu_tmp2_i32);
+ gen_helper_fildl_FT0(cpu_tmp2_i32);
break;
case 2:
tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
- tcg_gen_helper_0_1(helper_fldl_FT0, cpu_tmp1_i64);
+ gen_helper_fldl_FT0(cpu_tmp1_i64);
break;
case 3:
default:
gen_op_lds_T0_A0(OT_WORD + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_1(helper_fildl_FT0, cpu_tmp2_i32);
+ gen_helper_fildl_FT0(cpu_tmp2_i32);
break;
}
- tcg_gen_helper_0_0(helper_fp_arith_ST0_FT0[op1]);
+ gen_helper_fp_arith_ST0_FT0(op1);
if (op1 == 3) {
/* fcomp needs pop */
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fpop();
}
}
break;
@@ -6131,23 +5878,23 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
case 0:
gen_op_ld_T0_A0(OT_LONG + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_1(helper_flds_ST0, cpu_tmp2_i32);
+ gen_helper_flds_ST0(cpu_tmp2_i32);
break;
case 1:
gen_op_ld_T0_A0(OT_LONG + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_1(helper_fildl_ST0, cpu_tmp2_i32);
+ gen_helper_fildl_ST0(cpu_tmp2_i32);
break;
case 2:
tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
- tcg_gen_helper_0_1(helper_fldl_ST0, cpu_tmp1_i64);
+ gen_helper_fldl_ST0(cpu_tmp1_i64);
break;
case 3:
default:
gen_op_lds_T0_A0(OT_WORD + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_1(helper_fildl_ST0, cpu_tmp2_i32);
+ gen_helper_fildl_ST0(cpu_tmp2_i32);
break;
}
break;
@@ -6155,50 +5902,50 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
/* XXX: the corresponding CPUID bit must be tested ! */
switch(op >> 4) {
case 1:
- tcg_gen_helper_1_0(helper_fisttl_ST0, cpu_tmp2_i32);
+ gen_helper_fisttl_ST0(cpu_tmp2_i32);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_LONG + s->mem_index);
break;
case 2:
- tcg_gen_helper_1_0(helper_fisttll_ST0, cpu_tmp1_i64);
+ gen_helper_fisttll_ST0(cpu_tmp1_i64);
tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
break;
case 3:
default:
- tcg_gen_helper_1_0(helper_fistt_ST0, cpu_tmp2_i32);
+ gen_helper_fistt_ST0(cpu_tmp2_i32);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_WORD + s->mem_index);
break;
}
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fpop();
break;
default:
switch(op >> 4) {
case 0:
- tcg_gen_helper_1_0(helper_fsts_ST0, cpu_tmp2_i32);
+ gen_helper_fsts_ST0(cpu_tmp2_i32);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_LONG + s->mem_index);
break;
case 1:
- tcg_gen_helper_1_0(helper_fistl_ST0, cpu_tmp2_i32);
+ gen_helper_fistl_ST0(cpu_tmp2_i32);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_LONG + s->mem_index);
break;
case 2:
- tcg_gen_helper_1_0(helper_fstl_ST0, cpu_tmp1_i64);
+ gen_helper_fstl_ST0(cpu_tmp1_i64);
tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
break;
case 3:
default:
- tcg_gen_helper_1_0(helper_fist_ST0, cpu_tmp2_i32);
+ gen_helper_fist_ST0(cpu_tmp2_i32);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_WORD + s->mem_index);
break;
}
if ((op & 7) == 3)
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fpop();
break;
}
break;
@@ -6206,23 +5953,22 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_2(helper_fldenv,
+ gen_helper_fldenv(
cpu_A0, tcg_const_i32(s->dflag));
break;
case 0x0d: /* fldcw mem */
gen_op_ld_T0_A0(OT_WORD + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_1(helper_fldcw, cpu_tmp2_i32);
+ gen_helper_fldcw(cpu_tmp2_i32);
break;
case 0x0e: /* fnstenv mem */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_2(helper_fstenv,
- cpu_A0, tcg_const_i32(s->dflag));
+ gen_helper_fstenv(cpu_A0, tcg_const_i32(s->dflag));
break;
case 0x0f: /* fnstcw mem */
- tcg_gen_helper_1_0(helper_fnstcw, cpu_tmp2_i32);
+ gen_helper_fnstcw(cpu_tmp2_i32);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_WORD + s->mem_index);
break;
@@ -6230,31 +5976,29 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_fldt_ST0, cpu_A0);
+ gen_helper_fldt_ST0(cpu_A0);
break;
case 0x1f: /* fstpt mem */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_fstt_ST0, cpu_A0);
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fstt_ST0(cpu_A0);
+ gen_helper_fpop();
break;
case 0x2c: /* frstor mem */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_2(helper_frstor,
- cpu_A0, tcg_const_i32(s->dflag));
+ gen_helper_frstor(cpu_A0, tcg_const_i32(s->dflag));
break;
case 0x2e: /* fnsave mem */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_2(helper_fsave,
- cpu_A0, tcg_const_i32(s->dflag));
+ gen_helper_fsave(cpu_A0, tcg_const_i32(s->dflag));
break;
case 0x2f: /* fnstsw mem */
- tcg_gen_helper_1_0(helper_fnstsw, cpu_tmp2_i32);
+ gen_helper_fnstsw(cpu_tmp2_i32);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_WORD + s->mem_index);
break;
@@ -6262,25 +6006,25 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_fbld_ST0, cpu_A0);
+ gen_helper_fbld_ST0(cpu_A0);
break;
case 0x3e: /* fbstp */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_fbst_ST0, cpu_A0);
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fbst_ST0(cpu_A0);
+ gen_helper_fpop();
break;
case 0x3d: /* fildll */
tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
- tcg_gen_helper_0_1(helper_fildll_ST0, cpu_tmp1_i64);
+ gen_helper_fildll_ST0(cpu_tmp1_i64);
break;
case 0x3f: /* fistpll */
- tcg_gen_helper_1_0(helper_fistll_ST0, cpu_tmp1_i64);
+ gen_helper_fistll_ST0(cpu_tmp1_i64);
tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fpop();
break;
default:
goto illegal_op;
@@ -6291,13 +6035,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
switch(op) {
case 0x08: /* fld sti */
- tcg_gen_helper_0_0(helper_fpush);
- tcg_gen_helper_0_1(helper_fmov_ST0_STN, tcg_const_i32((opreg + 1) & 7));
+ gen_helper_fpush();
+ gen_helper_fmov_ST0_STN(tcg_const_i32((opreg + 1) & 7));
break;
case 0x09: /* fxchg sti */
case 0x29: /* fxchg4 sti, undocumented op */
case 0x39: /* fxchg7 sti, undocumented op */
- tcg_gen_helper_0_1(helper_fxchg_ST0_STN, tcg_const_i32(opreg));
+ gen_helper_fxchg_ST0_STN(tcg_const_i32(opreg));
break;
case 0x0a: /* grp d9/2 */
switch(rm) {
@@ -6306,7 +6050,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_0(helper_fwait);
+ gen_helper_fwait();
break;
default:
goto illegal_op;
@@ -6315,17 +6059,17 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
case 0x0c: /* grp d9/4 */
switch(rm) {
case 0: /* fchs */
- tcg_gen_helper_0_0(helper_fchs_ST0);
+ gen_helper_fchs_ST0();
break;
case 1: /* fabs */
- tcg_gen_helper_0_0(helper_fabs_ST0);
+ gen_helper_fabs_ST0();
break;
case 4: /* ftst */
- tcg_gen_helper_0_0(helper_fldz_FT0);
- tcg_gen_helper_0_0(helper_fcom_ST0_FT0);
+ gen_helper_fldz_FT0();
+ gen_helper_fcom_ST0_FT0();
break;
case 5: /* fxam */
- tcg_gen_helper_0_0(helper_fxam_ST0);
+ gen_helper_fxam_ST0();
break;
default:
goto illegal_op;
@@ -6335,32 +6079,32 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
{
switch(rm) {
case 0:
- tcg_gen_helper_0_0(helper_fpush);
- tcg_gen_helper_0_0(helper_fld1_ST0);
+ gen_helper_fpush();
+ gen_helper_fld1_ST0();
break;
case 1:
- tcg_gen_helper_0_0(helper_fpush);
- tcg_gen_helper_0_0(helper_fldl2t_ST0);
+ gen_helper_fpush();
+ gen_helper_fldl2t_ST0();
break;
case 2:
- tcg_gen_helper_0_0(helper_fpush);
- tcg_gen_helper_0_0(helper_fldl2e_ST0);
+ gen_helper_fpush();
+ gen_helper_fldl2e_ST0();
break;
case 3:
- tcg_gen_helper_0_0(helper_fpush);
- tcg_gen_helper_0_0(helper_fldpi_ST0);
+ gen_helper_fpush();
+ gen_helper_fldpi_ST0();
break;
case 4:
- tcg_gen_helper_0_0(helper_fpush);
- tcg_gen_helper_0_0(helper_fldlg2_ST0);
+ gen_helper_fpush();
+ gen_helper_fldlg2_ST0();
break;
case 5:
- tcg_gen_helper_0_0(helper_fpush);
- tcg_gen_helper_0_0(helper_fldln2_ST0);
+ gen_helper_fpush();
+ gen_helper_fldln2_ST0();
break;
case 6:
- tcg_gen_helper_0_0(helper_fpush);
- tcg_gen_helper_0_0(helper_fldz_ST0);
+ gen_helper_fpush();
+ gen_helper_fldz_ST0();
break;
default:
goto illegal_op;
@@ -6370,58 +6114,58 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
case 0x0e: /* grp d9/6 */
switch(rm) {
case 0: /* f2xm1 */
- tcg_gen_helper_0_0(helper_f2xm1);
+ gen_helper_f2xm1();
break;
case 1: /* fyl2x */
- tcg_gen_helper_0_0(helper_fyl2x);
+ gen_helper_fyl2x();
break;
case 2: /* fptan */
- tcg_gen_helper_0_0(helper_fptan);
+ gen_helper_fptan();
break;
case 3: /* fpatan */
- tcg_gen_helper_0_0(helper_fpatan);
+ gen_helper_fpatan();
break;
case 4: /* fxtract */
- tcg_gen_helper_0_0(helper_fxtract);
+ gen_helper_fxtract();
break;
case 5: /* fprem1 */
- tcg_gen_helper_0_0(helper_fprem1);
+ gen_helper_fprem1();
break;
case 6: /* fdecstp */
- tcg_gen_helper_0_0(helper_fdecstp);
+ gen_helper_fdecstp();
break;
default:
case 7: /* fincstp */
- tcg_gen_helper_0_0(helper_fincstp);
+ gen_helper_fincstp();
break;
}
break;
case 0x0f: /* grp d9/7 */
switch(rm) {
case 0: /* fprem */
- tcg_gen_helper_0_0(helper_fprem);
+ gen_helper_fprem();
break;
case 1: /* fyl2xp1 */
- tcg_gen_helper_0_0(helper_fyl2xp1);
+ gen_helper_fyl2xp1();
break;
case 2: /* fsqrt */
- tcg_gen_helper_0_0(helper_fsqrt);
+ gen_helper_fsqrt();
break;
case 3: /* fsincos */
- tcg_gen_helper_0_0(helper_fsincos);
+ gen_helper_fsincos();
break;
case 5: /* fscale */
- tcg_gen_helper_0_0(helper_fscale);
+ gen_helper_fscale();
break;
case 4: /* frndint */
- tcg_gen_helper_0_0(helper_frndint);
+ gen_helper_frndint();
break;
case 6: /* fsin */
- tcg_gen_helper_0_0(helper_fsin);
+ gen_helper_fsin();
break;
default:
case 7: /* fcos */
- tcg_gen_helper_0_0(helper_fcos);
+ gen_helper_fcos();
break;
}
break;
@@ -6433,34 +6177,34 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
op1 = op & 7;
if (op >= 0x20) {
- tcg_gen_helper_0_1(helper_fp_arith_STN_ST0[op1], tcg_const_i32(opreg));
+ gen_helper_fp_arith_STN_ST0(op1, opreg);
if (op >= 0x30)
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fpop();
} else {
- tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
- tcg_gen_helper_0_0(helper_fp_arith_ST0_FT0[op1]);
+ gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
+ gen_helper_fp_arith_ST0_FT0(op1);
}
}
break;
case 0x02: /* fcom */
case 0x22: /* fcom2, undocumented op */
- tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
- tcg_gen_helper_0_0(helper_fcom_ST0_FT0);
+ gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
+ gen_helper_fcom_ST0_FT0();
break;
case 0x03: /* fcomp */
case 0x23: /* fcomp3, undocumented op */
case 0x32: /* fcomp5, undocumented op */
- tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
- tcg_gen_helper_0_0(helper_fcom_ST0_FT0);
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
+ gen_helper_fcom_ST0_FT0();
+ gen_helper_fpop();
break;
case 0x15: /* da/5 */
switch(rm) {
case 1: /* fucompp */
- tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(1));
- tcg_gen_helper_0_0(helper_fucom_ST0_FT0);
- tcg_gen_helper_0_0(helper_fpop);
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fmov_FT0_STN(tcg_const_i32(1));
+ gen_helper_fucom_ST0_FT0();
+ gen_helper_fpop();
+ gen_helper_fpop();
break;
default:
goto illegal_op;
@@ -6473,10 +6217,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
case 1: /* fdisi (287 only, just do nop here) */
break;
case 2: /* fclex */
- tcg_gen_helper_0_0(helper_fclex);
+ gen_helper_fclex();
break;
case 3: /* fninit */
- tcg_gen_helper_0_0(helper_fninit);
+ gen_helper_fninit();
break;
case 4: /* fsetpm (287 only, just do nop here) */
break;
@@ -6487,59 +6231,59 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
case 0x1d: /* fucomi */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
- tcg_gen_helper_0_0(helper_fucomi_ST0_FT0);
+ gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
+ gen_helper_fucomi_ST0_FT0();
s->cc_op = CC_OP_EFLAGS;
break;
case 0x1e: /* fcomi */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
- tcg_gen_helper_0_0(helper_fcomi_ST0_FT0);
+ gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
+ gen_helper_fcomi_ST0_FT0();
s->cc_op = CC_OP_EFLAGS;
break;
case 0x28: /* ffree sti */
- tcg_gen_helper_0_1(helper_ffree_STN, tcg_const_i32(opreg));
+ gen_helper_ffree_STN(tcg_const_i32(opreg));
break;
case 0x2a: /* fst sti */
- tcg_gen_helper_0_1(helper_fmov_STN_ST0, tcg_const_i32(opreg));
+ gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
break;
case 0x2b: /* fstp sti */
case 0x0b: /* fstp1 sti, undocumented op */
case 0x3a: /* fstp8 sti, undocumented op */
case 0x3b: /* fstp9 sti, undocumented op */
- tcg_gen_helper_0_1(helper_fmov_STN_ST0, tcg_const_i32(opreg));
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
+ gen_helper_fpop();
break;
case 0x2c: /* fucom st(i) */
- tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
- tcg_gen_helper_0_0(helper_fucom_ST0_FT0);
+ gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
+ gen_helper_fucom_ST0_FT0();
break;
case 0x2d: /* fucomp st(i) */
- tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
- tcg_gen_helper_0_0(helper_fucom_ST0_FT0);
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
+ gen_helper_fucom_ST0_FT0();
+ gen_helper_fpop();
break;
case 0x33: /* de/3 */
switch(rm) {
case 1: /* fcompp */
- tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(1));
- tcg_gen_helper_0_0(helper_fcom_ST0_FT0);
- tcg_gen_helper_0_0(helper_fpop);
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fmov_FT0_STN(tcg_const_i32(1));
+ gen_helper_fcom_ST0_FT0();
+ gen_helper_fpop();
+ gen_helper_fpop();
break;
default:
goto illegal_op;
}
break;
case 0x38: /* ffreep sti, undocumented op */
- tcg_gen_helper_0_1(helper_ffree_STN, tcg_const_i32(opreg));
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_ffree_STN(tcg_const_i32(opreg));
+ gen_helper_fpop();
break;
case 0x3c: /* df/4 */
switch(rm) {
case 0:
- tcg_gen_helper_1_0(helper_fnstsw, cpu_tmp2_i32);
+ gen_helper_fnstsw(cpu_tmp2_i32);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_mov_reg_T0(OT_WORD, R_EAX);
break;
@@ -6550,17 +6294,17 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
case 0x3d: /* fucomip */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
- tcg_gen_helper_0_0(helper_fucomi_ST0_FT0);
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
+ gen_helper_fucomi_ST0_FT0();
+ gen_helper_fpop();
s->cc_op = CC_OP_EFLAGS;
break;
case 0x3e: /* fcomip */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
- tcg_gen_helper_0_0(helper_fcomi_ST0_FT0);
- tcg_gen_helper_0_0(helper_fpop);
+ gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
+ gen_helper_fcomi_ST0_FT0();
+ gen_helper_fpop();
s->cc_op = CC_OP_EFLAGS;
break;
case 0x10 ... 0x13: /* fcmovxx */
@@ -6576,7 +6320,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
l1 = gen_new_label();
gen_jcc1(s, s->cc_op, op1, l1);
- tcg_gen_helper_0_1(helper_fmov_ST0_STN, tcg_const_i32(opreg));
+ gen_helper_fmov_ST0_STN(tcg_const_i32(opreg));
gen_set_label(l1);
}
break;
@@ -6713,7 +6457,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (use_icount)
gen_io_start();
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[1], cpu_tmp2_i32);
+ gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
gen_op_mov_reg_T1(ot, R_EAX);
if (use_icount) {
gen_io_end();
@@ -6730,10 +6474,6 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_op_movl_T0_im(val);
gen_check_io(s, ot, pc_start - s->cs_base,
svm_is_rep(prefixes));
-#ifdef VBOX /* bird: linux is writing to this port for delaying I/O. */
- if (val == 0x80)
- break;
-#endif /* VBOX */
gen_op_mov_TN_reg(ot, 1, R_EAX);
if (use_icount)
@@ -6741,7 +6481,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
- tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32);
+ gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
if (use_icount) {
gen_io_end();
gen_jmp(s, s->pc - s->cs_base);
@@ -6760,7 +6500,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (use_icount)
gen_io_start();
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[1], cpu_tmp2_i32);
+ gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
gen_op_mov_reg_T1(ot, R_EAX);
if (use_icount) {
gen_io_end();
@@ -6784,7 +6524,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
- tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32);
+ gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
if (use_icount) {
gen_io_end();
gen_jmp(s, s->pc - s->cs_base);
@@ -6821,9 +6561,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_2(helper_lret_protected,
- tcg_const_i32(s->dflag),
- tcg_const_i32(val));
+ gen_helper_lret_protected(tcg_const_i32(s->dflag),
+ tcg_const_i32(val));
} else {
gen_stack_A0(s);
/* pop offset */
@@ -6849,7 +6588,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
if (!s->pe) {
/* real mode */
- tcg_gen_helper_0_1(helper_iret_real, tcg_const_i32(s->dflag));
+ gen_helper_iret_real(tcg_const_i32(s->dflag));
s->cc_op = CC_OP_EFLAGS;
} else if (s->vm86) {
#ifdef VBOX
@@ -6859,16 +6598,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
#endif
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
- tcg_gen_helper_0_1(helper_iret_real, tcg_const_i32(s->dflag));
+ gen_helper_iret_real(tcg_const_i32(s->dflag));
s->cc_op = CC_OP_EFLAGS;
}
} else {
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_2(helper_iret_protected,
- tcg_const_i32(s->dflag),
- tcg_const_i32(s->pc - s->cs_base));
+ gen_helper_iret_protected(tcg_const_i32(s->dflag),
+ tcg_const_i32(s->pc - s->cs_base));
s->cc_op = CC_OP_EFLAGS;
}
gen_eob(s);
@@ -6883,7 +6621,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
tval += next_eip;
if (s->dflag == 0)
tval &= 0xffff;
- else if (!CODE64(s))
+ else if(!CODE64(s))
tval &= 0xffffffff;
gen_movtl_T0_im(next_eip);
gen_push_T0(s);
@@ -6968,7 +6706,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
modrm = ldub_code(s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
if (mod != 3) {
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
@@ -6981,10 +6719,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
/* XXX: specific Intel behaviour ? */
l1 = gen_new_label();
gen_jcc1(s, s->cc_op, b ^ 1, l1);
- tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+ tcg_gen_mov_tl(cpu_regs[reg], t0);
gen_set_label(l1);
- tcg_gen_movi_tl(cpu_tmp0, 0);
- tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
+ tcg_gen_ext32u_tl(cpu_regs[reg], cpu_regs[reg]);
} else
#endif
{
@@ -7012,10 +6749,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_op_set_cc_op(s->cc_op);
#ifdef VBOX
if (s->vm86 && s->vme && s->iopl != 3)
- tcg_gen_helper_1_0(helper_read_eflags_vme, cpu_T[0]);
+ gen_helper_read_eflags_vme(cpu_T[0]);
else
#endif
- tcg_gen_helper_1_0(helper_read_eflags, cpu_T[0]);
+ gen_helper_read_eflags(cpu_T[0]);
gen_push_T0(s);
}
break;
@@ -7031,32 +6768,32 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_pop_T0(s);
if (s->cpl == 0) {
if (s->dflag) {
- tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
+ gen_helper_write_eflags(cpu_T[0],
tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK)));
} else {
- tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
+ gen_helper_write_eflags(cpu_T[0],
tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff));
}
} else {
if (s->cpl <= s->iopl) {
if (s->dflag) {
- tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
+ gen_helper_write_eflags(cpu_T[0],
tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK)));
} else {
- tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
+ gen_helper_write_eflags(cpu_T[0],
tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff));
}
} else {
if (s->dflag) {
- tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
+ gen_helper_write_eflags(cpu_T[0],
tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK)));
} else {
#ifdef VBOX
if (s->vm86 && s->vme)
- tcg_gen_helper_0_1(helper_write_eflags_vme, cpu_T[0]);
+ gen_helper_write_eflags_vme(cpu_T[0]);
else
#endif
- tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
+ gen_helper_write_eflags(cpu_T[0],
tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff));
}
}
@@ -7218,23 +6955,36 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
ot = dflag + OT_WORD;
modrm = ldub_code(s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
- gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
+ gen_ldst_modrm(s,modrm, ot, OR_TMP0, 0);
gen_extu(ot, cpu_T[0]);
- label1 = gen_new_label();
- tcg_gen_movi_tl(cpu_cc_dst, 0);
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
tcg_gen_mov_tl(t0, cpu_T[0]);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, label1);
- if (b & 1) {
- tcg_gen_helper_1_1(helper_bsr, cpu_T[0], t0);
+ if ((b & 1) && (prefixes & PREFIX_REPZ) &&
+ (s->cpuid_ext3_features & CPUID_EXT3_ABM)) {
+ switch(ot) {
+ case OT_WORD: gen_helper_lzcnt(cpu_T[0], t0,
+ tcg_const_i32(16)); break;
+ case OT_LONG: gen_helper_lzcnt(cpu_T[0], t0,
+ tcg_const_i32(32)); break;
+ case OT_QUAD: gen_helper_lzcnt(cpu_T[0], t0,
+ tcg_const_i32(64)); break;
+ }
+ gen_op_mov_reg_T0(ot, reg);
} else {
- tcg_gen_helper_1_1(helper_bsf, cpu_T[0], t0);
+ label1 = gen_new_label();
+ tcg_gen_movi_tl(cpu_cc_dst, 0);
+ tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, label1);
+ if (b & 1) {
+ gen_helper_bsr(cpu_T[0], t0);
+ } else {
+ gen_helper_bsf(cpu_T[0], t0);
+ }
+ gen_op_mov_reg_T0(ot, reg);
+ tcg_gen_movi_tl(cpu_cc_dst, 1);
+ gen_set_label(label1);
+ tcg_gen_discard_tl(cpu_cc_src);
+ s->cc_op = CC_OP_LOGICB + ot;
}
- gen_op_mov_reg_T0(ot, reg);
- tcg_gen_movi_tl(cpu_cc_dst, 1);
- gen_set_label(label1);
- tcg_gen_discard_tl(cpu_cc_src);
- s->cc_op = CC_OP_LOGICB + ot;
tcg_temp_free(t0);
}
break;
@@ -7245,7 +6995,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
goto illegal_op;
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- tcg_gen_helper_0_0(helper_daa);
+ gen_helper_daa();
s->cc_op = CC_OP_EFLAGS;
break;
case 0x2f: /* das */
@@ -7253,7 +7003,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
goto illegal_op;
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- tcg_gen_helper_0_0(helper_das);
+ gen_helper_das();
s->cc_op = CC_OP_EFLAGS;
break;
case 0x37: /* aaa */
@@ -7261,7 +7011,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
goto illegal_op;
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- tcg_gen_helper_0_0(helper_aaa);
+ gen_helper_aaa();
s->cc_op = CC_OP_EFLAGS;
break;
case 0x3f: /* aas */
@@ -7269,7 +7019,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
goto illegal_op;
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- tcg_gen_helper_0_0(helper_aas);
+ gen_helper_aas();
s->cc_op = CC_OP_EFLAGS;
break;
case 0xd4: /* aam */
@@ -7279,7 +7029,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (val == 0) {
gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
} else {
- tcg_gen_helper_0_1(helper_aam, tcg_const_i32(val));
+ gen_helper_aam(tcg_const_i32(val));
s->cc_op = CC_OP_LOGICB;
}
break;
@@ -7287,16 +7037,20 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (CODE64(s))
goto illegal_op;
val = ldub_code(s->pc++);
- tcg_gen_helper_0_1(helper_aad, tcg_const_i32(val));
+ gen_helper_aad(tcg_const_i32(val));
s->cc_op = CC_OP_LOGICB;
break;
/************************/
/* misc */
case 0x90: /* nop */
- /* XXX: xchg + rex handling */
/* XXX: correct lock test for all insn */
- if (prefixes & PREFIX_LOCK)
+ if (prefixes & PREFIX_LOCK) {
goto illegal_op;
+ }
+ /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
+ if (REX_B(s)) {
+ goto do_xchg_reg_eax;
+ }
if (prefixes & PREFIX_REPZ) {
gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
}
@@ -7309,7 +7063,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_0(helper_fwait);
+ gen_helper_fwait();
}
break;
case 0xcc: /* int3 */
@@ -7338,8 +7092,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_into, tcg_const_i32(s->pc - pc_start));
+ gen_helper_into(tcg_const_i32(s->pc - pc_start));
break;
+#ifdef WANT_ICEBP
case 0xf1: /* icebp (undocumented, exits to external debugger) */
gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
#if 1
@@ -7350,19 +7105,20 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
#endif
break;
+#endif
case 0xfa: /* cli */
if (!s->vm86) {
if (s->cpl <= s->iopl) {
- tcg_gen_helper_0_0(helper_cli);
+ gen_helper_cli();
} else {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
}
} else {
if (s->iopl == 3) {
- tcg_gen_helper_0_0(helper_cli);
+ gen_helper_cli();
#ifdef VBOX
} else if (s->iopl != 3 && s->vme) {
- tcg_gen_helper_0_0(helper_cli_vme);
+ gen_helper_cli_vme();
#endif
} else {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
@@ -7373,12 +7129,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (!s->vm86) {
if (s->cpl <= s->iopl) {
gen_sti:
- tcg_gen_helper_0_0(helper_sti);
+ gen_helper_sti();
/* interruptions are enabled only the first insn after sti */
/* If several instructions disable interrupts, only the
_first_ does it */
if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
- tcg_gen_helper_0_0(helper_set_inhibit_irq);
+ gen_helper_set_inhibit_irq();
/* give a chance to handle pending irqs */
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
@@ -7390,7 +7146,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
goto gen_sti;
#ifdef VBOX
} else if (s->iopl != 3 && s->vme) {
- tcg_gen_helper_0_0(helper_sti_vme);
+ gen_helper_sti_vme();
/* give a chance to handle pending irqs */
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
@@ -7414,35 +7170,25 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_jmp_im(pc_start - s->cs_base);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
if (ot == OT_WORD)
- tcg_gen_helper_0_2(helper_boundw, cpu_A0, cpu_tmp2_i32);
+ gen_helper_boundw(cpu_A0, cpu_tmp2_i32);
else
- tcg_gen_helper_0_2(helper_boundl, cpu_A0, cpu_tmp2_i32);
+ gen_helper_boundl(cpu_A0, cpu_tmp2_i32);
break;
case 0x1c8 ... 0x1cf: /* bswap reg */
reg = (b & 7) | REX_B(s);
#ifdef TARGET_X86_64
if (dflag == 2) {
gen_op_mov_TN_reg(OT_QUAD, 0, reg);
- tcg_gen_bswap_i64(cpu_T[0], cpu_T[0]);
+ tcg_gen_bswap64_i64(cpu_T[0], cpu_T[0]);
gen_op_mov_reg_T0(OT_QUAD, reg);
} else
- {
- TCGv tmp0;
- gen_op_mov_TN_reg(OT_LONG, 0, reg);
-
- tmp0 = tcg_temp_new(TCG_TYPE_I32);
- tcg_gen_trunc_i64_i32(tmp0, cpu_T[0]);
- tcg_gen_bswap_i32(tmp0, tmp0);
- tcg_gen_extu_i32_i64(cpu_T[0], tmp0);
- gen_op_mov_reg_T0(OT_LONG, reg);
- }
-#else
+#endif
{
gen_op_mov_TN_reg(OT_LONG, 0, reg);
- tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]);
+ tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
+ tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]);
gen_op_mov_reg_T0(OT_LONG, reg);
}
-#endif
break;
case 0xd6: /* salc */
if (CODE64(s))
@@ -7514,9 +7260,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
if (b & 2) {
- tcg_gen_helper_0_0(helper_rdmsr);
+ gen_helper_rdmsr();
} else {
- tcg_gen_helper_0_0(helper_wrmsr);
+ gen_helper_wrmsr();
}
}
break;
@@ -7526,7 +7272,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_jmp_im(pc_start - s->cs_base);
if (use_icount)
gen_io_start();
- tcg_gen_helper_0_0(helper_rdtsc);
+ gen_helper_rdtsc();
if (use_icount) {
gen_io_end();
gen_jmp(s, s->pc - s->cs_base);
@@ -7536,7 +7282,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_0(helper_rdpmc);
+ gen_helper_rdpmc();
break;
case 0x134: /* sysenter */
#ifndef VBOX
@@ -7550,12 +7296,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (!s->pe) {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
+ gen_update_cc_op(s);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_0(helper_sysenter);
+ gen_helper_sysenter();
gen_eob(s);
}
break;
@@ -7571,36 +7314,27 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (!s->pe) {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
+ gen_update_cc_op(s);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_sysexit, tcg_const_i32(dflag));
+ gen_helper_sysexit(tcg_const_i32(dflag));
gen_eob(s);
}
break;
#ifdef TARGET_X86_64
case 0x105: /* syscall */
/* XXX: is it usable in real mode ? */
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
+ gen_update_cc_op(s);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_syscall, tcg_const_i32(s->pc - pc_start));
+ gen_helper_syscall(tcg_const_i32(s->pc - pc_start));
gen_eob(s);
break;
case 0x107: /* sysret */
if (!s->pe) {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
+ gen_update_cc_op(s);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_sysret, tcg_const_i32(s->dflag));
+ gen_helper_sysret(tcg_const_i32(s->dflag));
/* condition codes are modified only in long mode */
if (s->lma)
s->cc_op = CC_OP_EFLAGS;
@@ -7612,7 +7346,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_0(helper_cpuid);
+ gen_helper_cpuid();
break;
case 0xf4: /* hlt */
if (s->cpl != 0) {
@@ -7621,8 +7355,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_hlt, tcg_const_i32(s->pc - pc_start));
- s->is_jmp = 3;
+ gen_helper_hlt(tcg_const_i32(s->pc - pc_start));
+ s->is_jmp = DISAS_TB_JUMP;
}
break;
case 0x100:
@@ -7650,7 +7384,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
gen_jmp_im(pc_start - s->cs_base);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_1(helper_lldt, cpu_tmp2_i32);
+ gen_helper_lldt(cpu_tmp2_i32);
}
break;
case 1: /* str */
@@ -7673,7 +7407,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
gen_jmp_im(pc_start - s->cs_base);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- tcg_gen_helper_0_1(helper_ltr, cpu_tmp2_i32);
+ gen_helper_ltr(cpu_tmp2_i32);
}
break;
case 4: /* verr */
@@ -7684,9 +7418,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
if (op == 4)
- tcg_gen_helper_0_1(helper_verr, cpu_T[0]);
+ gen_helper_verr(cpu_T[0]);
else
- tcg_gen_helper_0_1(helper_verw, cpu_T[0]);
+ gen_helper_verw(cpu_T[0]);
s->cc_op = CC_OP_EFLAGS;
break;
default:
@@ -7698,18 +7432,6 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
mod = (modrm >> 6) & 3;
op = (modrm >> 3) & 7;
rm = modrm & 7;
-
-#ifdef VBOX
- /* 0f 01 f9 */
- if (modrm == 0xf9)
- {
- if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
- goto illegal_op;
- gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_0(helper_rdtscp);
- break;
- }
-#endif
switch(op) {
case 0: /* sgdt */
if (mod == 3)
@@ -7745,18 +7467,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_op_andl_A0_ffff();
}
gen_add_A0_ds_seg(s);
- tcg_gen_helper_0_1(helper_monitor, cpu_A0);
+ gen_helper_monitor(cpu_A0);
break;
case 1: /* mwait */
if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
s->cpl != 0)
goto illegal_op;
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
+ gen_update_cc_op(s);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_1(helper_mwait, tcg_const_i32(s->pc - pc_start));
+ gen_helper_mwait(tcg_const_i32(s->pc - pc_start));
gen_eob(s);
break;
default:
@@ -7788,17 +7507,16 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
break;
} else {
- tcg_gen_helper_0_2(helper_vmrun,
- tcg_const_i32(s->aflag),
- tcg_const_i32(s->pc - pc_start));
+ gen_helper_vmrun(tcg_const_i32(s->aflag),
+ tcg_const_i32(s->pc - pc_start));
tcg_gen_exit_tb(0);
- s->is_jmp = 3;
+ s->is_jmp = DISAS_TB_JUMP;
}
break;
case 1: /* VMMCALL */
if (!(s->flags & HF_SVME_MASK))
goto illegal_op;
- tcg_gen_helper_0_0(helper_vmmcall);
+ gen_helper_vmmcall();
break;
case 2: /* VMLOAD */
if (!(s->flags & HF_SVME_MASK) || !s->pe)
@@ -7807,8 +7525,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
break;
} else {
- tcg_gen_helper_0_1(helper_vmload,
- tcg_const_i32(s->aflag));
+ gen_helper_vmload(tcg_const_i32(s->aflag));
}
break;
case 3: /* VMSAVE */
@@ -7818,8 +7535,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
break;
} else {
- tcg_gen_helper_0_1(helper_vmsave,
- tcg_const_i32(s->aflag));
+ gen_helper_vmsave(tcg_const_i32(s->aflag));
}
break;
case 4: /* STGI */
@@ -7831,7 +7547,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
break;
} else {
- tcg_gen_helper_0_0(helper_stgi);
+ gen_helper_stgi();
}
break;
case 5: /* CLGI */
@@ -7841,7 +7557,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
break;
} else {
- tcg_gen_helper_0_0(helper_clgi);
+ gen_helper_clgi();
}
break;
case 6: /* SKINIT */
@@ -7849,7 +7565,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
!(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) ||
!s->pe)
goto illegal_op;
- tcg_gen_helper_0_0(helper_skinit);
+ gen_helper_skinit();
break;
case 7: /* INVLPGA */
if (!(s->flags & HF_SVME_MASK) || !s->pe)
@@ -7858,8 +7574,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
break;
} else {
- tcg_gen_helper_0_1(helper_invlpga,
- tcg_const_i32(s->aflag));
+ gen_helper_invlpga(tcg_const_i32(s->aflag));
}
break;
default:
@@ -7887,7 +7602,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
break;
case 4: /* smsw */
gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
+#if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
+ tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]) + 4);
+#else
tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]));
+#endif
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 1);
break;
case 6: /* lmsw */
@@ -7896,36 +7615,63 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
} else {
gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
- tcg_gen_helper_0_1(helper_lmsw, cpu_T[0]);
+ gen_helper_lmsw(cpu_T[0]);
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
}
break;
- case 7: /* invlpg */
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+ case 7:
+ if (mod != 3) { /* invlpg */
+ if (s->cpl != 0) {
+ gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+ } else {
+ if (s->cc_op != CC_OP_DYNAMIC)
+ gen_op_set_cc_op(s->cc_op);
+ gen_jmp_im(pc_start - s->cs_base);
+ gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
+ gen_helper_invlpg(cpu_A0);
+ gen_jmp_im(s->pc - s->cs_base);
+ gen_eob(s);
+ }
} else {
- if (mod == 3) {
+ switch (rm) {
+ case 0: /* swapgs */
#ifdef TARGET_X86_64
- if (CODE64(s) && rm == 0) {
- /* swapgs */
- tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
- tcg_gen_ld_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,kernelgsbase));
- tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
- tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,kernelgsbase));
+ if (CODE64(s)) {
+ if (s->cpl != 0) {
+ gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+ } else {
+ tcg_gen_ld_tl(cpu_T[0], cpu_env,
+ offsetof(CPUX86State,segs[R_GS].base));
+ tcg_gen_ld_tl(cpu_T[1], cpu_env,
+ offsetof(CPUX86State,kernelgsbase));
+ tcg_gen_st_tl(cpu_T[1], cpu_env,
+ offsetof(CPUX86State,segs[R_GS].base));
+ tcg_gen_st_tl(cpu_T[0], cpu_env,
+ offsetof(CPUX86State,kernelgsbase));
+ }
} else
#endif
{
goto illegal_op;
}
- } else {
+ break;
+ case 1: /* rdtscp */
+ if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
+ goto illegal_op;
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- tcg_gen_helper_0_1(helper_invlpg, cpu_A0);
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
+ if (use_icount)
+ gen_io_start();
+ gen_helper_rdtscp();
+ if (use_icount) {
+ gen_io_end();
+ gen_jmp(s, s->pc - s->cs_base);
+ }
+ break;
+ default:
+ goto illegal_op;
}
}
break;
@@ -7977,13 +7723,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (!s->pe || s->vm86)
goto illegal_op;
-
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
- t1 = tcg_temp_local_new(TCG_TYPE_TL);
- t2 = tcg_temp_local_new(TCG_TYPE_TL);
-#ifdef VBOX
- a0 = tcg_temp_local_new(TCG_TYPE_TL);
-#endif
+ t0 = tcg_temp_local_new();
+ t1 = tcg_temp_local_new();
+ t2 = tcg_temp_local_new();
ot = OT_WORD;
modrm = ldub_code(s->pc++);
reg = (modrm >> 3) & 7;
@@ -7991,12 +7733,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
rm = modrm & 7;
if (mod != 3) {
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-#ifdef VBOX
- tcg_gen_mov_tl(a0, cpu_A0);
-#endif
gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
+ a0 = tcg_temp_local_new();
+ tcg_gen_mov_tl(a0, cpu_A0);
} else {
gen_op_mov_v_reg(ot, t0, rm);
+ TCGV_UNUSED(a0);
}
gen_op_mov_v_reg(ot, t1, reg);
tcg_gen_andi_tl(cpu_tmp0, t0, 3);
@@ -8009,13 +7751,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
tcg_gen_movi_tl(t2, CC_Z);
gen_set_label(label1);
if (mod != 3) {
-#ifdef VBOX
- /* cpu_A0 doesn't survive branch */
gen_op_st_v(ot + s->mem_index, t0, a0);
-#else
- gen_op_st_v(ot + s->mem_index, t0, cpu_A0);
-#endif
- } else {
+ tcg_temp_free(a0);
+ } else {
gen_op_mov_reg_v(ot, rm, t0);
}
if (s->cc_op != CC_OP_DYNAMIC)
@@ -8027,9 +7765,6 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
tcg_temp_free(t0);
tcg_temp_free(t1);
tcg_temp_free(t2);
-#ifdef VBOX
- tcg_temp_free(a0);
-#endif
}
break;
case 0x102: /* lar */
@@ -8043,13 +7778,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
modrm = ldub_code(s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
if (b == 0x102)
- tcg_gen_helper_1_1(helper_lar, t0, cpu_T[0]);
+ gen_helper_lar(t0, cpu_T[0]);
else
- tcg_gen_helper_1_1(helper_lsl, t0, cpu_T[0]);
+ gen_helper_lsl(t0, cpu_T[0]);
tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
label1 = gen_new_label();
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
@@ -8098,6 +7833,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
ot = OT_QUAD;
else
ot = OT_LONG;
+ if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
+ (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
+ reg = 8;
+ }
switch(reg) {
case 0:
case 2:
@@ -8109,13 +7848,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_jmp_im(pc_start - s->cs_base);
if (b & 2) {
gen_op_mov_TN_reg(ot, 0, rm);
- tcg_gen_helper_0_2(helper_write_crN,
- tcg_const_i32(reg), cpu_T[0]);
+ gen_helper_write_crN(tcg_const_i32(reg), cpu_T[0]);
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
} else {
- tcg_gen_helper_1_1(helper_read_crN,
- cpu_T[0], tcg_const_i32(reg));
+ gen_helper_read_crN(cpu_T[0], tcg_const_i32(reg));
gen_op_mov_reg_T0(ot, rm);
}
break;
@@ -8146,8 +7883,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (b & 2) {
gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
gen_op_mov_TN_reg(ot, 0, rm);
- tcg_gen_helper_0_2(helper_movl_drN_T0,
- tcg_const_i32(reg), cpu_T[0]);
+ gen_helper_movl_drN_T0(tcg_const_i32(reg), cpu_T[0]);
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
} else {
@@ -8162,7 +7898,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
- tcg_gen_helper_0_0(helper_clts);
+ gen_helper_clts();
/* abort block because static cpu state changed */
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
@@ -8188,9 +7924,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
switch(op) {
case 0: /* fxsave */
if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
- (s->flags & HF_EM_MASK))
+ (s->prefix & PREFIX_LOCK))
goto illegal_op;
- if (s->flags & HF_TS_MASK) {
+ if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
break;
}
@@ -8198,14 +7934,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_2(helper_fxsave,
- cpu_A0, tcg_const_i32((s->dflag == 2)));
+ gen_helper_fxsave(cpu_A0, tcg_const_i32((s->dflag == 2)));
break;
case 1: /* fxrstor */
if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
- (s->flags & HF_EM_MASK))
+ (s->prefix & PREFIX_LOCK))
goto illegal_op;
- if (s->flags & HF_TS_MASK) {
+ if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
break;
}
@@ -8213,8 +7948,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- tcg_gen_helper_0_2(helper_fxrstor,
- cpu_A0, tcg_const_i32((s->dflag == 2)));
+ gen_helper_fxrstor(cpu_A0, tcg_const_i32((s->dflag == 2)));
break;
case 2: /* ldmxcsr */
case 3: /* stmxcsr */
@@ -8268,12 +8002,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
if (!(s->flags & HF_SMM_MASK))
goto illegal_op;
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
+ gen_update_cc_op(s);
gen_jmp_im(s->pc - s->cs_base);
- tcg_gen_helper_0_0(helper_rsm);
+ gen_helper_rsm();
gen_eob(s);
break;
case 0x1b8: /* SSE4.2 popcnt */
@@ -8294,8 +8025,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
ot = OT_QUAD;
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
- tcg_gen_helper_1_2(helper_popcnt,
- cpu_T[0], cpu_T[0], tcg_const_i32(ot));
+ gen_helper_popcnt(cpu_T[0], cpu_T[0], tcg_const_i32(ot));
gen_op_mov_reg_T0(ot, reg);
s->cc_op = CC_OP_EFLAGS;
@@ -8306,7 +8036,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
case 0x110 ... 0x117:
case 0x128 ... 0x12f:
case 0x138 ... 0x13a:
- case 0x150 ... 0x177:
+ case 0x150 ... 0x179:
case 0x17c ... 0x17f:
case 0x1c2:
case 0x1c4 ... 0x1c6:
@@ -8318,11 +8048,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
}
/* lock generation */
if (s->prefix & PREFIX_LOCK)
- tcg_gen_helper_0_0(helper_unlock);
+ gen_helper_unlock();
return s->pc;
illegal_op:
if (s->prefix & PREFIX_LOCK)
- tcg_gen_helper_0_0(helper_unlock);
+ gen_helper_unlock();
/* XXX: ensure that no lock was generated */
gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
return s->pc;
@@ -8335,48 +8065,98 @@ void optimize_flags_init(void)
#else
assert(sizeof(CCTable) == (1 << 4));
#endif
- cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
- cpu_cc_op = tcg_global_mem_new(TCG_TYPE_I32,
- TCG_AREG0, offsetof(CPUState, cc_op), "cc_op");
- cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
- TCG_AREG0, offsetof(CPUState, cc_src), "cc_src");
- cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
- TCG_AREG0, offsetof(CPUState, cc_dst), "cc_dst");
- cpu_cc_tmp = tcg_global_mem_new(TCG_TYPE_TL,
- TCG_AREG0, offsetof(CPUState, cc_tmp), "cc_tmp");
+ cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+ cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, cc_op), "cc_op");
+ cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_src),
+ "cc_src");
+ cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_dst),
+ "cc_dst");
+ cpu_cc_tmp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_tmp),
+ "cc_tmp");
- /* register helpers */
+#ifdef TARGET_X86_64
+ cpu_regs[R_EAX] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[R_EAX]), "rax");
+ cpu_regs[R_ECX] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[R_ECX]), "rcx");
+ cpu_regs[R_EDX] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[R_EDX]), "rdx");
+ cpu_regs[R_EBX] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[R_EBX]), "rbx");
+ cpu_regs[R_ESP] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[R_ESP]), "rsp");
+ cpu_regs[R_EBP] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[R_EBP]), "rbp");
+ cpu_regs[R_ESI] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[R_ESI]), "rsi");
+ cpu_regs[R_EDI] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[R_EDI]), "rdi");
+ cpu_regs[8] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[8]), "r8");
+ cpu_regs[9] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[9]), "r9");
+ cpu_regs[10] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[10]), "r10");
+ cpu_regs[11] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[11]), "r11");
+ cpu_regs[12] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[12]), "r12");
+ cpu_regs[13] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[13]), "r13");
+ cpu_regs[14] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[14]), "r14");
+ cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, regs[15]), "r15");
+#else
+ cpu_regs[R_EAX] = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, regs[R_EAX]), "eax");
+ cpu_regs[R_ECX] = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, regs[R_ECX]), "ecx");
+ cpu_regs[R_EDX] = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, regs[R_EDX]), "edx");
+ cpu_regs[R_EBX] = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, regs[R_EBX]), "ebx");
+ cpu_regs[R_ESP] = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, regs[R_ESP]), "esp");
+ cpu_regs[R_EBP] = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, regs[R_EBP]), "ebp");
+ cpu_regs[R_ESI] = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, regs[R_ESI]), "esi");
+ cpu_regs[R_EDI] = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, regs[R_EDI]), "edi");
+#endif
-#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
+ /* register helpers */
+#define GEN_HELPER 2
#include "helper.h"
}
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
basic block 'tb'. If search_pc is TRUE, also generate PC
information for each intermediate instruction. */
-#ifndef VBOX
static inline void gen_intermediate_code_internal(CPUState *env,
-#else /* VBOX */
-DECLINLINE(void) gen_intermediate_code_internal(CPUState *env,
-#endif /* VBOX */
TranslationBlock *tb,
int search_pc)
{
DisasContext dc1, *dc = &dc1;
target_ulong pc_ptr;
uint16_t *gen_opc_end;
- int j, lj, cflags;
+ CPUBreakpoint *bp;
+ int j, lj;
uint64_t flags;
target_ulong pc_start;
target_ulong cs_base;
int num_insns;
int max_insns;
+#ifdef VBOX
+ int const singlestep = env->state & CPU_EMULATE_SINGLE_STEP;
+#endif
/* generate intermediate code */
pc_start = tb->pc;
cs_base = tb->cs_base;
flags = tb->flags;
- cflags = tb->cflags;
dc->pe = (flags >> HF_PE_SHIFT) & 1;
dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
@@ -8387,7 +8167,7 @@ DECLINLINE(void) gen_intermediate_code_internal(CPUState *env,
#ifdef VBOX
dc->vme = !!(env->cr[4] & CR4_VME_MASK);
dc->pvi = !!(env->cr[4] & CR4_PVI_MASK);
-#ifdef VBOX_WITH_CALL_RECORD
+# ifdef VBOX_WITH_CALL_RECORD
if ( !(env->state & CPU_RAW_RING0)
&& (env->cr[0] & CR0_PG_MASK)
&& !(env->eflags & X86_EFL_IF)
@@ -8395,8 +8175,8 @@ DECLINLINE(void) gen_intermediate_code_internal(CPUState *env,
dc->record_call = 1;
else
dc->record_call = 0;
-#endif
-#endif
+# endif
+#endif /* VBOX */
dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
dc->iopl = (flags >> IOPL_SHIFT) & 3;
dc->tf = (flags >> TF_SHIFT) & 1;
@@ -8434,20 +8214,19 @@ DECLINLINE(void) gen_intermediate_code_internal(CPUState *env,
printf("ERROR addseg\n");
#endif
- cpu_T[0] = tcg_temp_new(TCG_TYPE_TL);
- cpu_T[1] = tcg_temp_new(TCG_TYPE_TL);
- cpu_A0 = tcg_temp_new(TCG_TYPE_TL);
- cpu_T3 = tcg_temp_new(TCG_TYPE_TL);
-
- cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
- cpu_tmp1_i64 = tcg_temp_new(TCG_TYPE_I64);
- cpu_tmp2_i32 = tcg_temp_new(TCG_TYPE_I32);
- cpu_tmp3_i32 = tcg_temp_new(TCG_TYPE_I32);
- cpu_tmp4 = tcg_temp_new(TCG_TYPE_TL);
- cpu_tmp5 = tcg_temp_new(TCG_TYPE_TL);
- cpu_tmp6 = tcg_temp_new(TCG_TYPE_TL);
- cpu_ptr0 = tcg_temp_new(TCG_TYPE_PTR);
- cpu_ptr1 = tcg_temp_new(TCG_TYPE_PTR);
+ cpu_T[0] = tcg_temp_new();
+ cpu_T[1] = tcg_temp_new();
+ cpu_A0 = tcg_temp_new();
+ cpu_T3 = tcg_temp_new();
+
+ cpu_tmp0 = tcg_temp_new();
+ cpu_tmp1_i64 = tcg_temp_new_i64();
+ cpu_tmp2_i32 = tcg_temp_new_i32();
+ cpu_tmp3_i32 = tcg_temp_new_i32();
+ cpu_tmp4 = tcg_temp_new();
+ cpu_tmp5 = tcg_temp_new();
+ cpu_ptr0 = tcg_temp_new_ptr();
+ cpu_ptr1 = tcg_temp_new_ptr();
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
@@ -8461,9 +8240,10 @@ DECLINLINE(void) gen_intermediate_code_internal(CPUState *env,
gen_icount_start();
for(;;) {
- if (env->nb_breakpoints > 0) {
- for(j = 0; j < env->nb_breakpoints; j++) {
- if (env->breakpoints[j] == pc_ptr) {
+ if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
+ QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+ if (bp->pc == pc_ptr &&
+ !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) {
gen_debug(dc, pc_ptr - dc->cs_base);
break;
}
@@ -8490,7 +8270,7 @@ DECLINLINE(void) gen_intermediate_code_internal(CPUState *env,
if (dc->is_jmp)
break;
#ifdef VBOX
-#ifdef DEBUG
+# ifdef DEBUG
/*
if(cpu_check_code_raw(env, pc_ptr, env->hflags | (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK))) == ERROR_SUCCESS)
{
@@ -8498,7 +8278,7 @@ DECLINLINE(void) gen_intermediate_code_internal(CPUState *env,
dprintf(("QEmu is about to execute instructions in our patch block at %08X!!\n", pc_ptr));
}
*/
-#endif
+# endif /* DEBUG */
if (env->state & CPU_EMULATE_SINGLE_INSTR)
{
env->state &= ~CPU_EMULATE_SINGLE_INSTR;
@@ -8527,6 +8307,11 @@ DECLINLINE(void) gen_intermediate_code_internal(CPUState *env,
gen_eob(dc);
break;
}
+ if (singlestep) {
+ gen_jmp_im(pc_ptr - dc->cs_base);
+ gen_eob(dc);
+ break;
+ }
}
if (tb->cflags & CF_LAST_IO)
gen_io_end();
@@ -8541,21 +8326,18 @@ DECLINLINE(void) gen_intermediate_code_internal(CPUState *env,
}
#ifdef DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_CPU) {
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
- }
- if (loglevel & CPU_LOG_TB_IN_ASM) {
+ if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
int disas_flags;
- fprintf(logfile, "----------------\n");
- fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
+ qemu_log("----------------\n");
+ qemu_log("IN: %s\n", lookup_symbol(pc_start));
#ifdef TARGET_X86_64
if (dc->code64)
disas_flags = 2;
else
#endif
disas_flags = !dc->code32;
- target_disas(logfile, pc_start, pc_ptr - pc_start, disas_flags);
- fprintf(logfile, "\n");
+ log_target_disas(pc_start, pc_ptr - pc_start, disas_flags);
+ qemu_log("\n");
}
#endif
@@ -8580,15 +8362,15 @@ void gen_pc_load(CPUState *env, TranslationBlock *tb,
{
int cc_op;
#ifdef DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_OP) {
+ if (qemu_loglevel_mask(CPU_LOG_TB_OP)) {
int i;
- fprintf(logfile, "RESTORE:\n");
+ qemu_log("RESTORE:\n");
for(i = 0;i <= pc_pos; i++) {
if (gen_opc_instr_start[i]) {
- fprintf(logfile, "0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
+ qemu_log("0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
}
}
- fprintf(logfile, "spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
+ qemu_log("spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
(uint32_t)tb->cs_base);
}
diff --git a/src/recompiler/targphys.h b/src/recompiler/targphys.h
new file mode 100644
index 000000000..95648d688
--- /dev/null
+++ b/src/recompiler/targphys.h
@@ -0,0 +1,21 @@
+/* Define target_phys_addr_t if it exists. */
+
+#ifndef TARGPHYS_H
+#define TARGPHYS_H
+
+#ifdef TARGET_PHYS_ADDR_BITS
+/* target_phys_addr_t is the type of a physical address (its size can
+ be different from 'target_ulong'). */
+
+#if TARGET_PHYS_ADDR_BITS == 32
+typedef uint32_t target_phys_addr_t;
+#define TARGET_PHYS_ADDR_MAX UINT32_MAX
+#define TARGET_FMT_plx "%08x"
+#elif TARGET_PHYS_ADDR_BITS == 64
+typedef uint64_t target_phys_addr_t;
+#define TARGET_PHYS_ADDR_MAX UINT64_MAX
+#define TARGET_FMT_plx "%016" PRIx64
+#endif
+#endif
+
+#endif
diff --git a/src/recompiler/tcg/tcg-runtime.c b/src/recompiler/tcg-runtime.c
index 930691109..ab2df5f02 100644
--- a/src/recompiler/tcg/tcg-runtime.c
+++ b/src/recompiler/tcg-runtime.c
@@ -21,18 +21,37 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
#ifndef VBOX
-#include <inttypes.h>
+#include <stdint.h>
+#else
+# include <VBox/types.h>
#endif
-#include "config.h"
-#include "osdep.h"
-#include "tcg.h"
+#include "tcg/tcg-runtime.h"
+
+/* 32-bit helpers */
+
+int32_t tcg_helper_div_i32(int32_t arg1, int32_t arg2)
+{
+ return arg1 / arg2;
+}
+
+int32_t tcg_helper_rem_i32(int32_t arg1, int32_t arg2)
+{
+ return arg1 % arg2;
+}
+
+uint32_t tcg_helper_divu_i32(uint32_t arg1, uint32_t arg2)
+{
+ return arg1 / arg2;
+}
+
+uint32_t tcg_helper_remu_i32(uint32_t arg1, uint32_t arg2)
+{
+ return arg1 % arg2;
+}
+
+/* 64-bit helpers */
int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2)
{
@@ -68,4 +87,3 @@ uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2)
{
return arg1 % arg2;
}
-
diff --git a/src/recompiler/tcg/README b/src/recompiler/tcg/README
index 89b92a686..68d27ffa6 100644
--- a/src/recompiler/tcg/README
+++ b/src/recompiler/tcg/README
@@ -60,9 +60,8 @@ add_i32 t0, t1, t2 (t0 <- t1 + t2)
- Basic blocks end after branches (e.g. brcond_i32 instruction),
goto_tb and exit_tb instructions.
-- Basic blocks end before legacy dyngen operations.
-- Basic blocks start after the end of a previous basic block, at a
- set_label instruction or after a legacy dyngen operation.
+- Basic blocks start after the end of a previous basic block, or at a
+ set_label instruction.
After the end of a basic block, the content of temporaries is
destroyed, but local temporaries and globals are preserved.
@@ -76,10 +75,13 @@ destroyed, but local temporaries and globals are preserved.
* Helpers:
Using the tcg_gen_helper_x_y it is possible to call any function
-taking i32, i64 or pointer types. Before calling an helper, all
-globals are stored at their canonical location and it is assumed that
-the function can modify them. In the future, function modifiers will
-be allowed to tell that the helper does not read or write some globals.
+taking i32, i64 or pointer types. By default, before calling an helper,
+all globals are stored at their canonical location and it is assumed
+that the function can modify them. This can be overriden by the
+TCG_CALL_CONST function modifier. By default, the helper is allowed to
+modify the CPU state or raise an exception. This can be overriden by
+the TCG_CALL_PURE function modifier, in which case the call to the
+function is removed if the return value is not used.
On some TCG targets (e.g. x86), several calling conventions are
supported.
@@ -205,7 +207,27 @@ t0=t1^t2
t0=~t1
-********* Shifts
+* andc_i32/i64 t0, t1, t2
+
+t0=t1&~t2
+
+* eqv_i32/i64 t0, t1, t2
+
+t0=~(t1^t2), or equivalently, t0=t1^~t2
+
+* nand_i32/i64 t0, t1, t2
+
+t0=~(t1&t2)
+
+* nor_i32/i64 t0, t1, t2
+
+t0=~(t1|t2)
+
+* orc_i32/i64 t0, t1, t2
+
+t0=t1|~t2
+
+********* Shifts/Rotates
* shl_i32/i64 t0, t1, t2
@@ -219,6 +241,14 @@ t0=t1 >> t2 (unsigned). Undefined behavior if t2 < 0 or t2 >= 32 (resp 64)
t0=t1 >> t2 (signed). Undefined behavior if t2 < 0 or t2 >= 32 (resp 64)
+* rotl_i32/i64 t0, t1, t2
+
+Rotation of t2 bits to the left. Undefined behavior if t2 < 0 or t2 >= 32 (resp 64)
+
+* rotr_i32/i64 t0, t1, t2
+
+Rotation of t2 bits to the right. Undefined behavior if t2 < 0 or t2 >= 32 (resp 64)
+
********* Misc
* mov_i32/i64 t0, t1
@@ -236,16 +266,17 @@ ext32u_i64 t0, t1
8, 16 or 32 bit sign/zero extension (both operands must have the same type)
-* bswap16_i32 t0, t1
+* bswap16_i32/i64 t0, t1
-16 bit byte swap on a 32 bit value. The two high order bytes must be set
-to zero.
+16 bit byte swap on a 32/64 bit value. It assumes that the two/six high order
+bytes are set to zero.
-* bswap_i32 t0, t1
+* bswap32_i32/i64 t0, t1
-32 bit byte swap
+32 bit byte swap on a 32/64 bit value. With a 64 bit value, it assumes that
+the four high order bytes are set to zero.
-* bswap_i64 t0, t1
+* bswap64_i64 t0, t1
64 bit byte swap
@@ -254,6 +285,14 @@ to zero.
Indicate that the value of t0 won't be used later. It is useful to
force dead code elimination.
+********* Conditional moves
+
+* setcond_i32/i64 cond, dest, t1, t2
+
+dest = (t1 cond t2)
+
+Set DEST to 1 if (T1 cond T2) is true, otherwise set to 0.
+
********* Type conversions
* ext_i32_i64 t0, t1
@@ -295,6 +334,34 @@ st32_i64 t0, t1, offset
write(t0, t1 + offset)
Write 8, 16, 32 or 64 bits to host memory.
+********* 64-bit target on 32-bit host support
+
+The following opcodes are internal to TCG. Thus they are to be implemented by
+32-bit host code generators, but are not to be emitted by guest translators.
+They are emitted as needed by inline functions within "tcg-op.h".
+
+* brcond2_i32 cond, t0_low, t0_high, t1_low, t1_high, label
+
+Similar to brcond, except that the 64-bit values T0 and T1
+are formed from two 32-bit arguments.
+
+* add2_i32 t0_low, t0_high, t1_low, t1_high, t2_low, t2_high
+* sub2_i32 t0_low, t0_high, t1_low, t1_high, t2_low, t2_high
+
+Similar to add/sub, except that the 64-bit inputs T1 and T2 are
+formed from two 32-bit arguments, and the 64-bit output T0
+is returned in two 32-bit outputs.
+
+* mulu2_i32 t0_low, t0_high, t1, t2
+
+Similar to mul, except two 32-bit (unsigned) inputs T1 and T2 yielding
+the full 64-bit product T0. The later is returned in two 32-bit outputs.
+
+* setcond2_i32 cond, dest, t1_low, t1_high, t2_low, t2_high
+
+Similar to setcond, except that the 64-bit values T1 and T2 are
+formed from two 32-bit arguments. The result is a 32-bit value.
+
********* QEMU specific operations
* tb_exit t0
@@ -307,22 +374,26 @@ Exit the current TB and jump to the TB index 'index' (constant) if the
current TB was linked to this TB. Otherwise execute the next
instructions.
-* qemu_ld_i32/i64 t0, t1, flags
-qemu_ld8u_i32/i64 t0, t1, flags
-qemu_ld8s_i32/i64 t0, t1, flags
-qemu_ld16u_i32/i64 t0, t1, flags
-qemu_ld16s_i32/i64 t0, t1, flags
-qemu_ld32u_i64 t0, t1, flags
-qemu_ld32s_i64 t0, t1, flags
+* qemu_ld8u t0, t1, flags
+qemu_ld8s t0, t1, flags
+qemu_ld16u t0, t1, flags
+qemu_ld16s t0, t1, flags
+qemu_ld32 t0, t1, flags
+qemu_ld32u t0, t1, flags
+qemu_ld32s t0, t1, flags
+qemu_ld64 t0, t1, flags
-Load data at the QEMU CPU address t1 into t0. t1 has the QEMU CPU
-address type. 'flags' contains the QEMU memory index (selects user or
-kernel access) for example.
+Load data at the QEMU CPU address t1 into t0. t1 has the QEMU CPU address
+type. 'flags' contains the QEMU memory index (selects user or kernel access)
+for example.
+
+Note that "qemu_ld32" implies a 32-bit result, while "qemu_ld32u" and
+"qemu_ld32s" imply a 64-bit result appropriately extended from 32 bits.
-* qemu_st_i32/i64 t0, t1, flags
-qemu_st8_i32/i64 t0, t1, flags
-qemu_st16_i32/i64 t0, t1, flags
-qemu_st32_i64 t0, t1, flags
+* qemu_st8 t0, t1, flags
+qemu_st16 t0, t1, flags
+qemu_st32 t0, t1, flags
+qemu_st64 t0, t1, flags
Store the data t0 at the QEMU CPU Address t1. t1 has the QEMU CPU
address type. 'flags' contains the QEMU memory index (selects user or
@@ -362,6 +433,11 @@ GCC like constraints are used to define the constraints of every
instruction. Memory constraints are not supported in this
version. Aliases are specified in the input operands as for GCC.
+The same register may be used for both an input and an output, even when
+they are not explicitly aliased. If an op expands to multiple target
+instructions then care must be taken to avoid clobbering input values.
+GCC style "early clobber" outputs are not currently supported.
+
A target can define specific register or constant constraints. If an
operation uses a constant input constraint which does not allow all
constants, it must also accept registers in order to have a fallback.
@@ -390,18 +466,7 @@ register.
target, functions must be able to return 2 values in registers for
64 bit return type.
-5) Migration from dyngen to TCG
-
-TCG is backward compatible with QEMU "dyngen" operations. It means
-that TCG instructions can be freely mixed with dyngen operations. It
-is expected that QEMU targets will be progressively fully converted to
-TCG. Once a target is fully converted to TCG, it will be possible
-to apply more optimizations because more registers will be free for
-the generated code.
-
-The exception model is the same as the dyngen one.
-
-6) Recommended coding rules for best performance
+5) Recommended coding rules for best performance
- Use globals to represent the parts of the QEMU CPU state which are
often modified, e.g. the integer registers and the condition
@@ -409,8 +474,7 @@ The exception model is the same as the dyngen one.
- Avoid globals stored in fixed registers. They must be used only to
store the pointer to the CPU state and possibly to store a pointer
- to a register window. The other uses are to ensure backward
- compatibility with dyngen during the porting a new target to TCG.
+ to a register window.
- Use temporaries. Use local temporaries only when really needed,
e.g. when you need to use a value after a jump. Local temporaries
@@ -424,7 +488,7 @@ The exception model is the same as the dyngen one.
the speed of the translation.
- Don't hesitate to use helpers for complicated or seldom used target
- instructions. There is little performance advantage in using TCG to
+ intructions. There is little performance advantage in using TCG to
implement target instructions taking more than about twenty TCG
instructions.
diff --git a/src/recompiler/tcg/TODO b/src/recompiler/tcg/TODO
index 5ca35e9f2..074784778 100644
--- a/src/recompiler/tcg/TODO
+++ b/src/recompiler/tcg/TODO
@@ -1,5 +1,4 @@
-- Add new instructions such as: andnot, ror, rol, setcond, clz, ctz,
- popcnt.
+- Add new instructions such as: clz, ctz, popcnt.
- See if it is worth exporting mul2, mulu2, div2, divu2.
diff --git a/src/recompiler/tcg/i386/Makefile.kup b/src/recompiler/tcg/i386/Makefile.kup
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/recompiler/tcg/i386/Makefile.kup
diff --git a/src/recompiler/tcg/i386/tcg-target.c b/src/recompiler/tcg/i386/tcg-target.c
index 62d494efb..d0408fd1f 100644
--- a/src/recompiler/tcg/i386/tcg-target.c
+++ b/src/recompiler/tcg/i386/tcg-target.c
@@ -24,29 +24,62 @@
#ifndef NDEBUG
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
- "%eax",
- "%ecx",
- "%edx",
- "%ebx",
- "%esp",
- "%ebp",
- "%esi",
- "%edi",
+#if TCG_TARGET_REG_BITS == 64
+ "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
+ "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
+#else
+ "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
+#endif
};
#endif
static const int tcg_target_reg_alloc_order[] = {
- TCG_REG_EAX,
- TCG_REG_EDX,
- TCG_REG_ECX,
+#if TCG_TARGET_REG_BITS == 64
+ TCG_REG_RBP,
+ TCG_REG_RBX,
+ TCG_REG_R12,
+ TCG_REG_R13,
+ TCG_REG_R14,
+ TCG_REG_R15,
+ TCG_REG_R10,
+ TCG_REG_R11,
+ TCG_REG_R9,
+ TCG_REG_R8,
+ TCG_REG_RCX,
+ TCG_REG_RDX,
+ TCG_REG_RSI,
+ TCG_REG_RDI,
+ TCG_REG_RAX,
+#else
TCG_REG_EBX,
TCG_REG_ESI,
TCG_REG_EDI,
TCG_REG_EBP,
+ TCG_REG_ECX,
+ TCG_REG_EDX,
+ TCG_REG_EAX,
+#endif
};
-static const int tcg_target_call_iarg_regs[3] = { TCG_REG_EAX, TCG_REG_EDX, TCG_REG_ECX };
-static const int tcg_target_call_oarg_regs[2] = { TCG_REG_EAX, TCG_REG_EDX };
+static const int tcg_target_call_iarg_regs[] = {
+#if TCG_TARGET_REG_BITS == 64
+ TCG_REG_RDI,
+ TCG_REG_RSI,
+ TCG_REG_RDX,
+ TCG_REG_RCX,
+ TCG_REG_R8,
+ TCG_REG_R9,
+#else
+ TCG_REG_EAX,
+ TCG_REG_EDX,
+ TCG_REG_ECX
+#endif
+};
+
+static const int tcg_target_call_oarg_regs[2] = {
+ TCG_REG_EAX,
+ TCG_REG_EDX
+};
static uint8_t *tb_ret_addr;
@@ -55,11 +88,19 @@ static void patch_reloc(uint8_t *code_ptr, int type,
{
value += addend;
switch(type) {
- case R_386_32:
+ case R_386_PC32:
+ value -= (uintptr_t)code_ptr;
+ if (value != (int32_t)value) {
+ tcg_abort();
+ }
*(uint32_t *)code_ptr = value;
break;
- case R_386_PC32:
- *(uint32_t *)code_ptr = value - (long)code_ptr;
+ case R_386_PC8:
+ value -= (uintptr_t)code_ptr;
+ if (value != (int8_t)value) {
+ tcg_abort();
+ }
+ *(uint8_t *)code_ptr = value;
break;
default:
tcg_abort();
@@ -83,12 +124,12 @@ DECLINLINE(void) tcg_gen_stack_alignment_check(TCGContext *s)
#endif /* VBOX */
/* maximum number of register used for input function arguments */
-#ifndef VBOX
static inline int tcg_target_get_call_iarg_regs_count(int flags)
-#else /* VBOX */
-DECLINLINE(int) tcg_target_get_call_iarg_regs_count(int flags)
-#endif /* VBOX */
{
+ if (TCG_TARGET_REG_BITS == 64) {
+ return 6;
+ }
+
flags &= TCG_CALL_TYPE_MASK;
switch(flags) {
case TCG_CALL_TYPE_STD:
@@ -135,20 +176,42 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
break;
case 'q':
ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xf);
+ if (TCG_TARGET_REG_BITS == 64) {
+ tcg_regset_set32(ct->u.regs, 0, 0xffff);
+ } else {
+ tcg_regset_set32(ct->u.regs, 0, 0xf);
+ }
break;
case 'r':
ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xff);
+ if (TCG_TARGET_REG_BITS == 64) {
+ tcg_regset_set32(ct->u.regs, 0, 0xffff);
+ } else {
+ tcg_regset_set32(ct->u.regs, 0, 0xff);
+ }
break;
/* qemu_ld/st address constraint */
case 'L':
ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xff);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_EAX);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_EDX);
+ if (TCG_TARGET_REG_BITS == 64) {
+ tcg_regset_set32(ct->u.regs, 0, 0xffff);
+ tcg_regset_reset_reg(ct->u.regs, TCG_REG_RSI);
+ tcg_regset_reset_reg(ct->u.regs, TCG_REG_RDI);
+ } else {
+ tcg_regset_set32(ct->u.regs, 0, 0xff);
+ tcg_regset_reset_reg(ct->u.regs, TCG_REG_EAX);
+ tcg_regset_reset_reg(ct->u.regs, TCG_REG_EDX);
+ }
+ break;
+
+ case 'e':
+ ct->ct |= TCG_CT_CONST_S32;
+ break;
+ case 'Z':
+ ct->ct |= TCG_CT_CONST_U32;
break;
+
default:
return -1;
}
@@ -158,21 +221,86 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
}
/* test if a constant matches the constraint */
-#ifndef VBOX
static inline int tcg_target_const_match(tcg_target_long val,
-#else /* VBOX */
-DECLINLINE(int) tcg_target_const_match(tcg_target_long val,
-#endif /* VBOX */
const TCGArgConstraint *arg_ct)
{
- int ct;
- ct = arg_ct->ct;
- if (ct & TCG_CT_CONST)
+ int ct = arg_ct->ct;
+ if (ct & TCG_CT_CONST) {
return 1;
- else
- return 0;
+ }
+ if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
+ return 1;
+ }
+ if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
+ return 1;
+ }
+ return 0;
}
+#if TCG_TARGET_REG_BITS == 64
+# define LOWREGMASK(x) ((x) & 7)
+#else
+# define LOWREGMASK(x) (x)
+#endif
+
+#define P_EXT 0x100 /* 0x0f opcode prefix */
+#define P_DATA16 0x200 /* 0x66 opcode prefix */
+#if TCG_TARGET_REG_BITS == 64
+# define P_ADDR32 0x400 /* 0x67 opcode prefix */
+# define P_REXW 0x800 /* Set REX.W = 1 */
+# define P_REXB_R 0x1000 /* REG field as byte register */
+# define P_REXB_RM 0x2000 /* R/M field as byte register */
+#else
+# define P_ADDR32 0
+# define P_REXW 0
+# define P_REXB_R 0
+# define P_REXB_RM 0
+#endif
+
+#define OPC_ARITH_EvIz (0x81)
+#define OPC_ARITH_EvIb (0x83)
+#define OPC_ARITH_GvEv (0x03) /* ... plus (ARITH_FOO << 3) */
+#define OPC_ADD_GvEv (OPC_ARITH_GvEv | (ARITH_ADD << 3))
+#define OPC_BSWAP (0xc8 | P_EXT)
+#define OPC_CALL_Jz (0xe8)
+#define OPC_CMP_GvEv (OPC_ARITH_GvEv | (ARITH_CMP << 3))
+#define OPC_DEC_r32 (0x48)
+#define OPC_IMUL_GvEv (0xaf | P_EXT)
+#define OPC_IMUL_GvEvIb (0x6b)
+#define OPC_IMUL_GvEvIz (0x69)
+#define OPC_INC_r32 (0x40)
+#define OPC_JCC_long (0x80 | P_EXT) /* ... plus condition code */
+#define OPC_JCC_short (0x70) /* ... plus condition code */
+#define OPC_JMP_long (0xe9)
+#define OPC_JMP_short (0xeb)
+#define OPC_LEA (0x8d)
+#define OPC_MOVB_EvGv (0x88) /* stores, more or less */
+#define OPC_MOVL_EvGv (0x89) /* stores, more or less */
+#define OPC_MOVL_GvEv (0x8b) /* loads, more or less */
+#define OPC_MOVL_EvIz (0xc7)
+#define OPC_MOVL_Iv (0xb8)
+#define OPC_MOVSBL (0xbe | P_EXT)
+#define OPC_MOVSWL (0xbf | P_EXT)
+#define OPC_MOVSLQ (0x63 | P_REXW)
+#define OPC_MOVZBL (0xb6 | P_EXT)
+#define OPC_MOVZWL (0xb7 | P_EXT)
+#define OPC_POP_r32 (0x58)
+#define OPC_PUSH_r32 (0x50)
+#define OPC_PUSH_Iv (0x68)
+#define OPC_PUSH_Ib (0x6a)
+#define OPC_RET (0xc3)
+#define OPC_SETCC (0x90 | P_EXT | P_REXB_RM) /* ... plus cc */
+#define OPC_SHIFT_1 (0xd1)
+#define OPC_SHIFT_Ib (0xc1)
+#define OPC_SHIFT_cl (0xd3)
+#define OPC_TESTL (0x85)
+#define OPC_XCHG_ax_r32 (0x90)
+
+#define OPC_GRP3_Ev (0xf7)
+#define OPC_GRP5 (0xff)
+
+/* Group 1 opcode extensions for 0x80-0x83.
+ These are also used as modifiers for OPC_ARITH. */
#define ARITH_ADD 0
#define ARITH_OR 1
#define ARITH_ADC 2
@@ -182,10 +310,28 @@ DECLINLINE(int) tcg_target_const_match(tcg_target_long val,
#define ARITH_XOR 6
#define ARITH_CMP 7
+/* Group 2 opcode extensions for 0xc0, 0xc1, 0xd0-0xd3. */
+#define SHIFT_ROL 0
+#define SHIFT_ROR 1
#define SHIFT_SHL 4
#define SHIFT_SHR 5
#define SHIFT_SAR 7
+/* Group 3 opcode extensions for 0xf6, 0xf7. To be used with OPC_GRP3. */
+#define EXT3_NOT 2
+#define EXT3_NEG 3
+#define EXT3_MUL 4
+#define EXT3_IMUL 5
+#define EXT3_DIV 6
+#define EXT3_IDIV 7
+
+/* Group 5 opcode extensions for 0xff. To be used with OPC_GRP5. */
+#define EXT5_INC_Ev 0
+#define EXT5_DEC_Ev 1
+#define EXT5_CALLN_Ev 2
+#define EXT5_JMPN_Ev 4
+
+/* Condition codes to be added to OPC_JCC_{long,short}. */
#define JCC_JMP (-1)
#define JCC_JO 0x0
#define JCC_JNO 0x1
@@ -204,9 +350,6 @@ DECLINLINE(int) tcg_target_const_match(tcg_target_long val,
#define JCC_JLE 0xe
#define JCC_JG 0xf
-#define P_EXT 0x100 /* 0x0f opcode prefix */
-
-#if !defined(VBOX) || !defined(_MSC_VER)
static const uint8_t tcg_cond_to_jcc[10] = {
[TCG_COND_EQ] = JCC_JE,
[TCG_COND_NE] = JCC_JNE,
@@ -219,177 +362,413 @@ static const uint8_t tcg_cond_to_jcc[10] = {
[TCG_COND_LEU] = JCC_JBE,
[TCG_COND_GTU] = JCC_JA,
};
-#else
-/* Fortunately, ordering is right */
-static const uint8_t tcg_cond_to_jcc[10] = {
- JCC_JE,
- JCC_JNE,
- JCC_JL,
- JCC_JGE,
- JCC_JLE,
- JCC_JG,
- JCC_JB,
- JCC_JAE,
- JCC_JBE,
- JCC_JA,
-};
+
+#if defined(VBOX)
+/* Calc the size of the tcg_out_opc() result. */
+static inline unsigned char tcg_calc_opc_len(TCGContext *s, int opc, int r, int rm, int x)
+{
+ unsigned char len = 1;
+# if TCG_TARGET_REG_BITS == 64
+ unsigned rex;
+ rex = 0;
+ rex |= (opc & P_REXW) >> 8; /* REX.W */
+ rex |= (r & 8) >> 1; /* REX.R */
+ rex |= (x & 8) >> 2; /* REX.X */
+ rex |= (rm & 8) >> 3; /* REX.B */
+ rex |= opc & (r >= 4 ? P_REXB_R : 0);
+ rex |= opc & (rm >= 4 ? P_REXB_RM : 0);
+ if (rex) len++;
+ if (opc & P_ADDR32) len++;
+# endif
+ if (opc & P_DATA16) len++;
+ if (opc & P_EXT) len++;
+
+ return len;
+}
#endif
-#ifndef VBOX
-static inline void tcg_out_opc(TCGContext *s, int opc)
-#else /* VBOX */
-DECLINLINE(void) tcg_out_opc(TCGContext *s, int opc)
-#endif /* VBOX */
+#if TCG_TARGET_REG_BITS == 64
+static void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x)
{
- if (opc & P_EXT)
+ int rex;
+
+ if (opc & P_DATA16) {
+ /* We should never be asking for both 16 and 64-bit operation. */
+ assert((opc & P_REXW) == 0);
+ tcg_out8(s, 0x66);
+ }
+ if (opc & P_ADDR32) {
+ tcg_out8(s, 0x67);
+ }
+
+ rex = 0;
+ rex |= (opc & P_REXW) >> 8; /* REX.W */
+ rex |= (r & 8) >> 1; /* REX.R */
+ rex |= (x & 8) >> 2; /* REX.X */
+ rex |= (rm & 8) >> 3; /* REX.B */
+
+ /* P_REXB_{R,RM} indicates that the given register is the low byte.
+ For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do,
+ as otherwise the encoding indicates %[abcd]h. Note that the values
+ that are ORed in merely indicate that the REX byte must be present;
+ those bits get discarded in output. */
+ rex |= opc & (r >= 4 ? P_REXB_R : 0);
+ rex |= opc & (rm >= 4 ? P_REXB_RM : 0);
+
+ if (rex) {
+ tcg_out8(s, (uint8_t)(rex | 0x40));
+ }
+
+ if (opc & P_EXT) {
tcg_out8(s, 0x0f);
+ }
+ tcg_out8(s, opc);
+}
+#else
+static void tcg_out_opc(TCGContext *s, int opc)
+{
+ if (opc & P_DATA16) {
+ tcg_out8(s, 0x66);
+ }
+ if (opc & P_EXT) {
+ tcg_out8(s, 0x0f);
+ }
tcg_out8(s, opc);
}
+/* Discard the register arguments to tcg_out_opc early, so as not to penalize
+ the 32-bit compilation paths. This method works with all versions of gcc,
+ whereas relying on optimization may not be able to exclude them. */
+#define tcg_out_opc(s, opc, r, rm, x) (tcg_out_opc)(s, opc)
+#endif
-#ifndef VBOX
-static inline void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
-#else /* VBOX */
-DECLINLINE(void) tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
-#endif /* VBOX */
+static void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
{
- tcg_out_opc(s, opc);
- tcg_out8(s, 0xc0 | (r << 3) | rm);
+ tcg_out_opc(s, opc, r, rm, 0);
+ tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
}
-/* rm == -1 means no register index */
-#ifndef VBOX
-static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r, int rm,
-#else /* VBOX */
-DECLINLINE(void) tcg_out_modrm_offset(TCGContext *s, int opc, int r, int rm,
-#endif /* VBOX */
- int32_t offset)
+/* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
+ We handle either RM and INDEX missing with a negative value. In 64-bit
+ mode for absolute addresses, ~RM is the size of the immediate operand
+ that will follow the instruction. */
+
+static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm,
+ int index, int shift,
+ tcg_target_long offset)
{
- tcg_out_opc(s, opc);
- if (rm == -1) {
- tcg_out8(s, 0x05 | (r << 3));
- tcg_out32(s, offset);
- } else if (offset == 0 && rm != TCG_REG_EBP) {
- if (rm == TCG_REG_ESP) {
- tcg_out8(s, 0x04 | (r << 3));
- tcg_out8(s, 0x24);
- } else {
- tcg_out8(s, 0x00 | (r << 3) | rm);
- }
- } else if ((int8_t)offset == offset) {
- if (rm == TCG_REG_ESP) {
- tcg_out8(s, 0x44 | (r << 3));
- tcg_out8(s, 0x24);
+ int mod, len;
+
+ if (index < 0 && rm < 0) {
+ if (TCG_TARGET_REG_BITS == 64) {
+ /* Try for a rip-relative addressing mode. This has replaced
+ the 32-bit-mode absolute addressing encoding. */
+#ifdef VBOX
+ tcg_target_long pc = (tcg_target_long)s->code_ptr
+ + tcg_calc_opc_len(s, opc, r, 0, 0) + 1 + 4;
+#else
+ tcg_target_long pc = (tcg_target_long)s->code_ptr + 5 + ~rm;
+#endif
+ tcg_target_long disp = offset - pc;
+ if (disp == (int32_t)disp) {
+ tcg_out_opc(s, opc, r, 0, 0);
+ tcg_out8(s, (LOWREGMASK(r) << 3) | 5);
+ tcg_out32(s, disp);
+#ifdef VBOX
+ Assert(pc == (tcg_target_long)s->code_ptr);
+#endif
+ return;
+ }
+
+ /* Try for an absolute address encoding. This requires the
+ use of the MODRM+SIB encoding and is therefore larger than
+ rip-relative addressing. */
+ if (offset == (int32_t)offset) {
+ tcg_out_opc(s, opc, r, 0, 0);
+ tcg_out8(s, (LOWREGMASK(r) << 3) | 4);
+ tcg_out8(s, (4 << 3) | 5);
+ tcg_out32(s, offset);
+ return;
+ }
+
+ /* ??? The memory isn't directly addressable. */
+ tcg_abort();
} else {
- tcg_out8(s, 0x40 | (r << 3) | rm);
+ /* Absolute address. */
+ tcg_out_opc(s, opc, r, 0, 0);
+ tcg_out8(s, (r << 3) | 5);
+ tcg_out32(s, offset);
+ return;
}
- tcg_out8(s, offset);
+ }
+
+ /* Find the length of the immediate addend. Note that the encoding
+ that would be used for (%ebp) indicates absolute addressing. */
+ if (rm < 0) {
+ mod = 0, len = 4, rm = 5;
+ } else if (offset == 0 && LOWREGMASK(rm) != TCG_REG_EBP) {
+ mod = 0, len = 0;
+ } else if (offset == (int8_t)offset) {
+ mod = 0x40, len = 1;
+ } else {
+ mod = 0x80, len = 4;
+ }
+
+ /* Use a single byte MODRM format if possible. Note that the encoding
+ that would be used for %esp is the escape to the two byte form. */
+ if (index < 0 && LOWREGMASK(rm) != TCG_REG_ESP) {
+ /* Single byte MODRM format. */
+ tcg_out_opc(s, opc, r, rm, 0);
+ tcg_out8(s, mod | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
} else {
- if (rm == TCG_REG_ESP) {
- tcg_out8(s, 0x84 | (r << 3));
- tcg_out8(s, 0x24);
+ /* Two byte MODRM+SIB format. */
+
+ /* Note that the encoding that would place %esp into the index
+ field indicates no index register. In 64-bit mode, the REX.X
+ bit counts, so %r12 can be used as the index. */
+ if (index < 0) {
+ index = 4;
} else {
- tcg_out8(s, 0x80 | (r << 3) | rm);
+ assert(index != TCG_REG_ESP);
}
+
+ tcg_out_opc(s, opc, r, rm, index);
+ tcg_out8(s, mod | (LOWREGMASK(r) << 3) | 4);
+ tcg_out8(s, (shift << 6) | (LOWREGMASK(index) << 3) | LOWREGMASK(rm));
+ }
+
+ if (len == 1) {
+ tcg_out8(s, offset);
+ } else if (len == 4) {
tcg_out32(s, offset);
}
}
-#ifndef VBOX
-static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_out_mov(TCGContext *s, int ret, int arg)
-#endif /* VBOX */
+/* A simplification of the above with no index or shift. */
+static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r,
+ int rm, tcg_target_long offset)
{
- if (arg != ret)
- tcg_out_modrm(s, 0x8b, ret, arg);
+ tcg_out_modrm_sib_offset(s, opc, r, rm, -1, 0, offset);
}
-#ifndef VBOX
-static inline void tcg_out_movi(TCGContext *s, TCGType type,
-#else /* VBOX */
-DECLINLINE(void) tcg_out_movi(TCGContext *s, TCGType type,
-#endif /* VBOX */
- int ret, int32_t arg)
+/* Generate dest op= src. Uses the same ARITH_* codes as tgen_arithi. */
+static inline void tgen_arithr(TCGContext *s, int subop, int dest, int src)
+{
+ /* Propagate an opcode prefix, such as P_REXW. */
+ int ext = subop & ~0x7;
+ subop &= 0x7;
+
+ tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3) + ext, dest, src);
+}
+
+static inline void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg)
+{
+ if (arg != ret) {
+ int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0);
+ tcg_out_modrm(s, opc, ret, arg);
+ }
+}
+
+static void tcg_out_movi(TCGContext *s, TCGType type,
+ int ret, tcg_target_long arg)
{
if (arg == 0) {
- /* xor r0,r0 */
- tcg_out_modrm(s, 0x01 | (ARITH_XOR << 3), ret, ret);
+ tgen_arithr(s, ARITH_XOR, ret, ret);
+ return;
+ } else if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
+ tcg_out_opc(s, OPC_MOVL_Iv + LOWREGMASK(ret), 0, ret, 0);
+ tcg_out32(s, arg);
+ } else if (arg == (int32_t)arg) {
+ tcg_out_modrm(s, OPC_MOVL_EvIz + P_REXW, 0, ret);
+ tcg_out32(s, arg);
} else {
- tcg_out8(s, 0xb8 + ret);
+ tcg_out_opc(s, OPC_MOVL_Iv + P_REXW + LOWREGMASK(ret), 0, ret, 0);
tcg_out32(s, arg);
+ tcg_out32(s, arg >> 31 >> 1);
+ }
+}
+
+static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
+{
+ if (val == (int8_t)val) {
+ tcg_out_opc(s, OPC_PUSH_Ib, 0, 0, 0);
+ tcg_out8(s, val);
+ } else if (val == (int32_t)val) {
+ tcg_out_opc(s, OPC_PUSH_Iv, 0, 0, 0);
+ tcg_out32(s, val);
+ } else {
+ tcg_abort();
}
}
-#ifndef VBOX
static inline void tcg_out_push(TCGContext *s, int reg)
-#else /* VBOX */
-DECLINLINE(void) tcg_out_push(TCGContext *s, int reg)
-#endif /* VBOX */
{
- tcg_out_opc(s, 0x50 + reg);
+ tcg_out_opc(s, OPC_PUSH_r32 + LOWREGMASK(reg), 0, reg, 0);
}
-#ifndef VBOX
static inline void tcg_out_pop(TCGContext *s, int reg)
-#else /* VBOX */
-DECLINLINE(void) tcg_out_pop(TCGContext *s, int reg)
-#endif /* VBOX */
{
- tcg_out_opc(s, 0x58 + reg);
+ tcg_out_opc(s, OPC_POP_r32 + LOWREGMASK(reg), 0, reg, 0);
}
-#ifndef VBOX
static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
-#else /* VBOX */
-DECLINLINE(void) tcg_out_ld(TCGContext *s, TCGType type, int ret,
-#endif /* VBOX */
int arg1, tcg_target_long arg2)
{
- /* movl */
- tcg_out_modrm_offset(s, 0x8b, ret, arg1, arg2);
+ int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0);
+ tcg_out_modrm_offset(s, opc, ret, arg1, arg2);
}
-#ifndef VBOX
static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
-#else /* VBOX */
-DECLINLINE(void) tcg_out_st(TCGContext *s, TCGType type, int arg,
-#endif /* VBOX */
int arg1, tcg_target_long arg2)
{
- /* movl */
- tcg_out_modrm_offset(s, 0x89, arg, arg1, arg2);
+ int opc = OPC_MOVL_EvGv + (type == TCG_TYPE_I64 ? P_REXW : 0);
+ tcg_out_modrm_offset(s, opc, arg, arg1, arg2);
}
-#ifndef VBOX
-static inline void tgen_arithi(TCGContext *s, int c, int r0, int32_t val)
-#else /* VBOX */
-DECLINLINE(void) tgen_arithi(TCGContext *s, int c, int r0, int32_t val)
-#endif /* VBOX */
+static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
+{
+ /* Propagate an opcode prefix, such as P_DATA16. */
+ int ext = subopc & ~0x7;
+ subopc &= 0x7;
+
+ if (count == 1) {
+ tcg_out_modrm(s, OPC_SHIFT_1 + ext, subopc, reg);
+ } else {
+ tcg_out_modrm(s, OPC_SHIFT_Ib + ext, subopc, reg);
+ tcg_out8(s, count);
+ }
+}
+
+static inline void tcg_out_bswap32(TCGContext *s, int reg)
+{
+ tcg_out_opc(s, OPC_BSWAP + LOWREGMASK(reg), 0, reg, 0);
+}
+
+static inline void tcg_out_rolw_8(TCGContext *s, int reg)
+{
+ tcg_out_shifti(s, SHIFT_ROL + P_DATA16, reg, 8);
+}
+
+static inline void tcg_out_ext8u(TCGContext *s, int dest, int src)
+{
+ /* movzbl */
+ assert(src < 4 || TCG_TARGET_REG_BITS == 64);
+ tcg_out_modrm(s, OPC_MOVZBL + P_REXB_RM, dest, src);
+}
+
+static void tcg_out_ext8s(TCGContext *s, int dest, int src, int rexw)
{
+ /* movsbl */
+ assert(src < 4 || TCG_TARGET_REG_BITS == 64);
+ tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src);
+}
+
+static inline void tcg_out_ext16u(TCGContext *s, int dest, int src)
+{
+ /* movzwl */
+ tcg_out_modrm(s, OPC_MOVZWL, dest, src);
+}
+
+static inline void tcg_out_ext16s(TCGContext *s, int dest, int src, int rexw)
+{
+ /* movsw[lq] */
+ tcg_out_modrm(s, OPC_MOVSWL + rexw, dest, src);
+}
+
+static inline void tcg_out_ext32u(TCGContext *s, int dest, int src)
+{
+ /* 32-bit mov zero extends. */
+ tcg_out_modrm(s, OPC_MOVL_GvEv, dest, src);
+}
+
+static inline void tcg_out_ext32s(TCGContext *s, int dest, int src)
+{
+ tcg_out_modrm(s, OPC_MOVSLQ, dest, src);
+}
+
+static inline void tcg_out_bswap64(TCGContext *s, int reg)
+{
+ tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0);
+}
+
+static void tgen_arithi(TCGContext *s, int c, int r0,
+ tcg_target_long val, int cf)
+{
+ int rexw = 0;
+
+ if (TCG_TARGET_REG_BITS == 64) {
+ rexw = c & -8;
+ c &= 7;
+ }
+
+ /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
+ partial flags update stalls on Pentium4 and are not recommended
+ by current Intel optimization manuals. */
+ if (!cf && (c == ARITH_ADD || c == ARITH_SUB) && (val == 1 || val == -1)) {
+ int is_inc = (c == ARITH_ADD) ^ (val < 0);
+ if (TCG_TARGET_REG_BITS == 64) {
+ /* The single-byte increment encodings are re-tasked as the
+ REX prefixes. Use the MODRM encoding. */
+ tcg_out_modrm(s, OPC_GRP5 + rexw,
+ (is_inc ? EXT5_INC_Ev : EXT5_DEC_Ev), r0);
+ } else {
+ tcg_out8(s, (is_inc ? OPC_INC_r32 : OPC_DEC_r32) + r0);
+ }
+ return;
+ }
+
+ if (c == ARITH_AND) {
+ if (TCG_TARGET_REG_BITS == 64) {
+ if (val == 0xffffffffu) {
+ tcg_out_ext32u(s, r0, r0);
+ return;
+ }
+ if (val == (uint32_t)val) {
+ /* AND with no high bits set can use a 32-bit operation. */
+ rexw = 0;
+ }
+ }
+ if (val == 0xffu && (r0 < 4 || TCG_TARGET_REG_BITS == 64)) {
+ tcg_out_ext8u(s, r0, r0);
+ return;
+ }
+ if (val == 0xffffu) {
+ tcg_out_ext16u(s, r0, r0);
+ return;
+ }
+ }
+
if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x83, c, r0);
+ tcg_out_modrm(s, OPC_ARITH_EvIb + rexw, c, r0);
tcg_out8(s, val);
- } else {
- tcg_out_modrm(s, 0x81, c, r0);
+ return;
+ }
+ if (rexw == 0 || val == (int32_t)val) {
+ tcg_out_modrm(s, OPC_ARITH_EvIz + rexw, c, r0);
tcg_out32(s, val);
+ return;
}
+
+ tcg_abort();
}
-void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
+static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
{
- if (val != 0)
- tgen_arithi(s, ARITH_ADD, reg, val);
+ if (val != 0) {
+ tgen_arithi(s, ARITH_ADD + P_REXW, reg, val, 0);
+ }
}
#ifdef VBOX
-void tcg_out_subi(TCGContext *s, int reg, tcg_target_long val)
+static void tcg_out_subi(TCGContext *s, int reg, tcg_target_long val)
{
- if (val != 0)
- tgen_arithi(s, ARITH_SUB, reg, val);
+ if (val != 0) {
+ tgen_arithi(s, ARITH_SUB + P_REXW, reg, val, 0);
+ }
}
#endif
-static void tcg_out_jxx(TCGContext *s, int opc, int label_index)
+/* Use SMALL != 0 to force a short forward branch. */
+static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
{
int32_t val, val1;
TCGLabel *l = &s->labels[label_index];
@@ -398,133 +777,250 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index)
val = l->u.value - (tcg_target_long)s->code_ptr;
val1 = val - 2;
if ((int8_t)val1 == val1) {
- if (opc == -1)
- tcg_out8(s, 0xeb);
- else
- tcg_out8(s, 0x70 + opc);
+ if (opc == -1) {
+ tcg_out8(s, OPC_JMP_short);
+ } else {
+ tcg_out8(s, OPC_JCC_short + opc);
+ }
tcg_out8(s, val1);
} else {
+ if (small) {
+ tcg_abort();
+ }
if (opc == -1) {
- tcg_out8(s, 0xe9);
+ tcg_out8(s, OPC_JMP_long);
tcg_out32(s, val - 5);
} else {
- tcg_out8(s, 0x0f);
- tcg_out8(s, 0x80 + opc);
+ tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
tcg_out32(s, val - 6);
}
}
+ } else if (small) {
+ if (opc == -1) {
+ tcg_out8(s, OPC_JMP_short);
+ } else {
+ tcg_out8(s, OPC_JCC_short + opc);
+ }
+ tcg_out_reloc(s, s->code_ptr, R_386_PC8, label_index, -1);
+ s->code_ptr += 1;
} else {
if (opc == -1) {
- tcg_out8(s, 0xe9);
+ tcg_out8(s, OPC_JMP_long);
} else {
- tcg_out8(s, 0x0f);
- tcg_out8(s, 0x80 + opc);
+ tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
}
tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
s->code_ptr += 4;
}
}
-static void tcg_out_brcond(TCGContext *s, int cond,
- TCGArg arg1, TCGArg arg2, int const_arg2,
- int label_index)
+static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
+ int const_arg2, int rexw)
{
if (const_arg2) {
if (arg2 == 0) {
/* test r, r */
- tcg_out_modrm(s, 0x85, arg1, arg1);
+ tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg1);
} else {
- tgen_arithi(s, ARITH_CMP, arg1, arg2);
+ tgen_arithi(s, ARITH_CMP + rexw, arg1, arg2, 0);
}
} else {
- tcg_out_modrm(s, 0x01 | (ARITH_CMP << 3), arg2, arg1);
+ tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2);
}
- tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index);
}
-#ifdef VBOX
-DECLINLINE(void)
-tcg_out_long_call(TCGContext *s, void* dst)
+static void tcg_out_brcond32(TCGContext *s, TCGCond cond,
+ TCGArg arg1, TCGArg arg2, int const_arg2,
+ int label_index, int small)
{
- intptr_t disp;
-# ifdef VBOX
- tcg_gen_stack_alignment_check(s);
-# endif
- disp = (uintptr_t)dst - (uintptr_t)s->code_ptr - 5;
- tcg_out8(s, 0xe8); /* call disp32 */
- tcg_out32(s, disp); /* disp32 */
+ tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
+ tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
}
-DECLINLINE(void)
-tcg_out_long_jmp(TCGContext *s, void* dst)
+
+#if TCG_TARGET_REG_BITS == 64
+static void tcg_out_brcond64(TCGContext *s, TCGCond cond,
+ TCGArg arg1, TCGArg arg2, int const_arg2,
+ int label_index, int small)
{
- intptr_t disp = (uintptr_t)dst - (uintptr_t)s->code_ptr - 5;
- tcg_out8(s, 0xe9); /* jmp disp32 */
- tcg_out32(s, disp); /* disp32 */
+ tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
+ tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
}
-#endif /* VBOX */
-
-
+#else
/* XXX: we implement it at the target level to avoid having to
handle cross basic blocks temporaries */
-static void tcg_out_brcond2(TCGContext *s,
- const TCGArg *args, const int *const_args)
+static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
+ const int *const_args, int small)
{
int label_next;
label_next = gen_new_label();
switch(args[4]) {
case TCG_COND_EQ:
- tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], label_next);
- tcg_out_brcond(s, TCG_COND_EQ, args[1], args[3], const_args[3], args[5]);
+ tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
+ label_next, 1);
+ tcg_out_brcond32(s, TCG_COND_EQ, args[1], args[3], const_args[3],
+ args[5], small);
break;
case TCG_COND_NE:
- tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], args[5]);
- tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], args[5]);
+ tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
+ args[5], small);
+ tcg_out_brcond32(s, TCG_COND_NE, args[1], args[3], const_args[3],
+ args[5], small);
break;
case TCG_COND_LT:
- tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], args[5]);
+ tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
+ args[5], small);
+ tcg_out_jxx(s, JCC_JNE, label_next, 1);
+ tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
+ args[5], small);
break;
case TCG_COND_LE:
- tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], args[5]);
+ tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
+ args[5], small);
+ tcg_out_jxx(s, JCC_JNE, label_next, 1);
+ tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
+ args[5], small);
break;
case TCG_COND_GT:
- tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], args[5]);
+ tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
+ args[5], small);
+ tcg_out_jxx(s, JCC_JNE, label_next, 1);
+ tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
+ args[5], small);
break;
case TCG_COND_GE:
- tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], args[5]);
+ tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
+ args[5], small);
+ tcg_out_jxx(s, JCC_JNE, label_next, 1);
+ tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
+ args[5], small);
break;
case TCG_COND_LTU:
- tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], args[5]);
+ tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
+ args[5], small);
+ tcg_out_jxx(s, JCC_JNE, label_next, 1);
+ tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
+ args[5], small);
break;
case TCG_COND_LEU:
- tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], args[5]);
+ tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
+ args[5], small);
+ tcg_out_jxx(s, JCC_JNE, label_next, 1);
+ tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
+ args[5], small);
break;
case TCG_COND_GTU:
- tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], args[5]);
+ tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
+ args[5], small);
+ tcg_out_jxx(s, JCC_JNE, label_next, 1);
+ tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
+ args[5], small);
break;
case TCG_COND_GEU:
- tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], args[5]);
+ tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
+ args[5], small);
+ tcg_out_jxx(s, JCC_JNE, label_next, 1);
+ tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
+ args[5], small);
break;
default:
tcg_abort();
}
tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr);
}
+#endif
+
+static void tcg_out_setcond32(TCGContext *s, TCGCond cond, TCGArg dest,
+ TCGArg arg1, TCGArg arg2, int const_arg2)
+{
+ tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
+ tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
+ tcg_out_ext8u(s, dest, dest);
+}
+
+#if TCG_TARGET_REG_BITS == 64
+static void tcg_out_setcond64(TCGContext *s, TCGCond cond, TCGArg dest,
+ TCGArg arg1, TCGArg arg2, int const_arg2)
+{
+ tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
+ tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
+ tcg_out_ext8u(s, dest, dest);
+}
+#else
+static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
+ const int *const_args)
+{
+ TCGArg new_args[6];
+ int label_true, label_over;
+
+ memcpy(new_args, args+1, 5*sizeof(TCGArg));
+
+ if (args[0] == args[1] || args[0] == args[2]
+ || (!const_args[3] && args[0] == args[3])
+ || (!const_args[4] && args[0] == args[4])) {
+ /* When the destination overlaps with one of the argument
+ registers, don't do anything tricky. */
+ label_true = gen_new_label();
+ label_over = gen_new_label();
+
+ new_args[5] = label_true;
+ tcg_out_brcond2(s, new_args, const_args+1, 1);
+
+ tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
+ tcg_out_jxx(s, JCC_JMP, label_over, 1);
+ tcg_out_label(s, label_true, (tcg_target_long)s->code_ptr);
+
+ tcg_out_movi(s, TCG_TYPE_I32, args[0], 1);
+ tcg_out_label(s, label_over, (tcg_target_long)s->code_ptr);
+ } else {
+ /* When the destination does not overlap one of the arguments,
+ clear the destination first, jump if cond false, and emit an
+ increment in the true case. This results in smaller code. */
+
+ tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
+
+ label_over = gen_new_label();
+ new_args[4] = tcg_invert_cond(new_args[4]);
+ new_args[5] = label_over;
+ tcg_out_brcond2(s, new_args, const_args+1, 1);
+
+ tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
+ tcg_out_label(s, label_over, (tcg_target_long)s->code_ptr);
+ }
+}
+#endif
+
+static void tcg_out_branch(TCGContext *s, int call, tcg_target_long dest)
+{
+#ifdef VBOX
+ tcg_target_long disp = dest - (tcg_target_long)s->code_ptr
+ - tcg_calc_opc_len(s, call ? OPC_CALL_Jz : OPC_JMP_long, 0, 0, 0)
+ - 4;
+#else
+ tcg_target_long disp = dest - (tcg_target_long)s->code_ptr - 5;
+#endif
+
+ if (disp == (int32_t)disp) {
+ tcg_out_opc(s, call ? OPC_CALL_Jz : OPC_JMP_long, 0, 0, 0);
+ tcg_out32(s, disp);
+ } else {
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R10, dest);
+ tcg_out_modrm(s, OPC_GRP5,
+ call ? EXT5_CALLN_Ev : EXT5_JMPN_Ev, TCG_REG_R10);
+ }
+}
+
+static inline void tcg_out_calli(TCGContext *s, tcg_target_long dest)
+{
+#ifdef VBOX
+ tcg_gen_stack_alignment_check(s);
+#endif
+ tcg_out_branch(s, 1, dest);
+}
+
+static void tcg_out_jmp(TCGContext *s, tcg_target_long dest)
+{
+ tcg_out_branch(s, 0, dest);
+}
#if defined(CONFIG_SOFTMMU)
@@ -543,10 +1039,168 @@ static void *qemu_st_helpers[4] = {
__stl_mmu,
__stq_mmu,
};
+
+/* Perform the TLB load and compare.
+
+ Inputs:
+ ADDRLO_IDX contains the index into ARGS of the low part of the
+ address; the high part of the address is at ADDR_LOW_IDX+1.
+
+ MEM_INDEX and S_BITS are the memory context and log2 size of the load.
+
+ WHICH is the offset into the CPUTLBEntry structure of the slot to read.
+ This should be offsetof addr_read or addr_write.
+
+ Outputs:
+ LABEL_PTRS is filled with 1 (32-bit addresses) or 2 (64-bit addresses)
+ positions of the displacements of forward jumps to the TLB miss case.
+
+ First argument register is loaded with the low part of the address.
+ In the TLB hit case, it has been adjusted as indicated by the TLB
+ and so is a host address. In the TLB miss case, it continues to
+ hold a guest address.
+
+ Second argument register is clobbered. */
+
+static inline void tcg_out_tlb_load(TCGContext *s, int addrlo_idx,
+ int mem_index, int s_bits,
+ const TCGArg *args,
+ uint8_t **label_ptr, int which)
+{
+ const int addrlo = args[addrlo_idx];
+ const int r0 = tcg_target_call_iarg_regs[0];
+ const int r1 = tcg_target_call_iarg_regs[1];
+ TCGType type = TCG_TYPE_I32;
+ int rexw = 0;
+
+ if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 64) {
+ type = TCG_TYPE_I64;
+ rexw = P_REXW;
+ }
+
+ tcg_out_mov(s, type, r1, addrlo);
+ tcg_out_mov(s, type, r0, addrlo);
+
+ tcg_out_shifti(s, SHIFT_SHR + rexw, r1,
+ TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
+
+ tgen_arithi(s, ARITH_AND + rexw, r0,
+ TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
+ tgen_arithi(s, ARITH_AND + rexw, r1,
+ (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
+
+ tcg_out_modrm_sib_offset(s, OPC_LEA + P_REXW, r1, TCG_AREG0, r1, 0,
+ offsetof(CPUState, tlb_table[mem_index][0])
+ + which);
+
+ /* cmp 0(r1), r0 */
+ tcg_out_modrm_offset(s, OPC_CMP_GvEv + rexw, r0, r1, 0);
+
+ tcg_out_mov(s, type, r0, addrlo);
+
+ /* jne label1 */
+ tcg_out8(s, OPC_JCC_short + JCC_JNE);
+ label_ptr[0] = s->code_ptr;
+ s->code_ptr++;
+
+ if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
+ /* cmp 4(r1), addrhi */
+ tcg_out_modrm_offset(s, OPC_CMP_GvEv, args[addrlo_idx+1], r1, 4);
+
+ /* jne label1 */
+ tcg_out8(s, OPC_JCC_short + JCC_JNE);
+ label_ptr[1] = s->code_ptr;
+ s->code_ptr++;
+ }
+
+ /* TLB Hit. */
+
+ /* add addend(r1), r0 */
+ tcg_out_modrm_offset(s, OPC_ADD_GvEv + P_REXW, r0, r1,
+ offsetof(CPUTLBEntry, addend) - which);
+}
+#endif
+
+static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi,
+ int base, tcg_target_long ofs, int sizeop)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+ const int bswap = 1;
+#else
+ const int bswap = 0;
+#endif
+ switch (sizeop) {
+ case 0:
+ tcg_out_modrm_offset(s, OPC_MOVZBL, datalo, base, ofs);
+ break;
+ case 0 | 4:
+ tcg_out_modrm_offset(s, OPC_MOVSBL + P_REXW, datalo, base, ofs);
+ break;
+ case 1:
+ tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
+ if (bswap) {
+ tcg_out_rolw_8(s, datalo);
+ }
+ break;
+ case 1 | 4:
+ if (bswap) {
+ tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
+ tcg_out_rolw_8(s, datalo);
+ tcg_out_modrm(s, OPC_MOVSWL + P_REXW, datalo, datalo);
+ } else {
+ tcg_out_modrm_offset(s, OPC_MOVSWL + P_REXW, datalo, base, ofs);
+ }
+ break;
+ case 2:
+ tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
+ if (bswap) {
+ tcg_out_bswap32(s, datalo);
+ }
+ break;
+#if TCG_TARGET_REG_BITS == 64
+ case 2 | 4:
+ if (bswap) {
+ tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
+ tcg_out_bswap32(s, datalo);
+ tcg_out_ext32s(s, datalo, datalo);
+ } else {
+ tcg_out_modrm_offset(s, OPC_MOVSLQ, datalo, base, ofs);
+ }
+ break;
#endif
+ case 3:
+ if (TCG_TARGET_REG_BITS == 64) {
+ tcg_out_ld(s, TCG_TYPE_I64, datalo, base, ofs);
+ if (bswap) {
+ tcg_out_bswap64(s, datalo);
+ }
+ } else {
+ if (bswap) {
+ int t = datalo;
+ datalo = datahi;
+ datahi = t;
+ }
+ if (base != datalo) {
+ tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
+ tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
+ } else {
+ tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
+ tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
+ }
+ if (bswap) {
+ tcg_out_bswap32(s, datalo);
+ tcg_out_bswap32(s, datahi);
+ }
+ }
+ break;
+ default:
+ tcg_abort();
+ }
+}
#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
-static void *vbox_ld_helpers[] = {
+
+static void * const vbox_ld_helpers[] = {
__ldub_vbox_phys,
__lduw_vbox_phys,
__ldul_vbox_phys,
@@ -557,13 +1211,24 @@ static void *vbox_ld_helpers[] = {
__ldq_vbox_phys,
};
-static void *vbox_st_helpers[] = {
+static void * const vbox_st_helpers[] = {
__stb_vbox_phys,
__stw_vbox_phys,
__stl_vbox_phys,
__stq_vbox_phys
};
+DECLINLINE(void) tcg_out_long_call(TCGContext *s, void* dst)
+{
+ intptr_t disp;
+# ifdef VBOX
+ tcg_gen_stack_alignment_check(s);
+# endif
+ disp = (uintptr_t)dst - (uintptr_t)s->code_ptr - 5;
+ tcg_out8(s, 0xe8); /* call disp32 */
+ tcg_out32(s, disp); /* disp32 */
+}
+
static void tcg_out_vbox_phys_read(TCGContext *s, int index,
int addr_reg,
int data_reg, int data_reg2)
@@ -574,13 +1239,13 @@ static void tcg_out_vbox_phys_read(TCGContext *s, int index,
/* out parameter (address), note that phys address is always 64-bit */
AssertMsg(sizeof(RTGCPHYS) == 8, ("Physical address must be 64-bits, update caller\n"));
-#if 0
+# if 0
tcg_out8(s, 0x6a); tcg_out8(s, 0x00); /* push $0 */
tcg_out_push(s, addr_reg);
-#else
+# else
/* mov addr_reg, %eax */
tcg_out_mov(s, TCG_REG_EAX, addr_reg);
-#endif
+# endif
tcg_out_long_call(s, vbox_ld_helpers[index]);
@@ -597,7 +1262,7 @@ static void tcg_out_vbox_phys_write(TCGContext *s, int index,
int val_reg, int val_reg2) {
int useReg2 = ((index & 3) == 3);
-#if 0
+# if 0
/* out parameter (value2) */
if (useReg2)
tcg_out_push(s, val_reg2);
@@ -607,7 +1272,7 @@ static void tcg_out_vbox_phys_write(TCGContext *s, int index,
AssertMsg(sizeof(RTGCPHYS) == 8, ("Physical address must be 64-bits, update caller\n"));
tcg_out8(s, 0x6a); tcg_out8(s, 0x00); /* push $0 */
tcg_out_push(s, addr_reg);
-#else
+# else
Assert(val_reg != TCG_REG_EAX && (!useReg2 || (val_reg2 != TCG_REG_EAX)));
/* mov addr_reg, %eax */
tcg_out_mov(s, TCG_REG_EAX, addr_reg);
@@ -617,12 +1282,12 @@ static void tcg_out_vbox_phys_write(TCGContext *s, int index,
if (useReg2)
tcg_out_mov(s, TCG_REG_ECX, val_reg2);
-#endif
+# endif
/* call it */
tcg_out_long_call(s, vbox_st_helpers[index]);
/* clean stack after us */
-#if 0
+# if 0
tcg_out_addi(s, TCG_REG_ESP, 8 + (useReg2 ? 8 : 4));
# endif
}
@@ -635,674 +1300,535 @@ static void tcg_out_vbox_phys_write(TCGContext *s, int index,
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
int opc)
{
- int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
-#if defined(CONFIG_SOFTMMU)
- uint8_t *label1_ptr, *label2_ptr;
-#endif
-#if TARGET_LONG_BITS == 64
+ int data_reg, data_reg2 = 0;
+ int addrlo_idx;
#if defined(CONFIG_SOFTMMU)
- uint8_t *label3_ptr;
-#endif
- int addr_reg2;
+ int mem_index, s_bits, arg_idx;
+ uint8_t *label_ptr[3];
#endif
- data_reg = *args++;
- if (opc == 3)
- data_reg2 = *args++;
- else
- data_reg2 = 0;
- addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
- addr_reg2 = *args++;
-#endif
- mem_index = *args;
- s_bits = opc & 3;
-
- r0 = TCG_REG_EAX;
- r1 = TCG_REG_EDX;
+ data_reg = args[0];
+ addrlo_idx = 1;
+ if (TCG_TARGET_REG_BITS == 32 && opc == 3) {
+ data_reg2 = args[1];
+ addrlo_idx = 2;
+ }
#if defined(CONFIG_SOFTMMU)
- tcg_out_mov(s, r1, addr_reg);
-
- tcg_out_mov(s, r0, addr_reg);
-
- tcg_out_modrm(s, 0xc1, 5, r1); /* shr $x, r1 */
- tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
-
- tcg_out_modrm(s, 0x81, 4, r0); /* andl $x, r0 */
- tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
-
- tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
- tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-
-#ifndef VBOX
- tcg_out_opc(s, 0x8d); /* lea offset(r1, %ebp), r1 */
- tcg_out8(s, 0x80 | (r1 << 3) | 0x04);
- tcg_out8(s, (5 << 3) | r1);
- tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_read));
-#else
- tcg_out_opc(s, 0x8d); /* lea offset(r1, env), r1 */
- tcg_out8(s, 0x80 | (r1 << 3) | 0x04);
- tcg_out8(s, (TCG_AREG0 << 3) | r1);
- tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_read));
-#endif
+ mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)];
+ s_bits = opc & 3;
- /* cmp 0(r1), r0 */
- tcg_out_modrm_offset(s, 0x3b, r0, r1, 0);
+ tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
+ label_ptr, offsetof(CPUTLBEntry, addr_read));
- tcg_out_mov(s, r0, addr_reg);
+ /* TLB Hit. */
+ tcg_out_qemu_ld_direct(s, data_reg, data_reg2,
+ tcg_target_call_iarg_regs[0], 0, opc);
-#if TARGET_LONG_BITS == 32
- /* je label1 */
- tcg_out8(s, 0x70 + JCC_JE);
- label1_ptr = s->code_ptr;
- s->code_ptr++;
-#else
- /* jne label3 */
- tcg_out8(s, 0x70 + JCC_JNE);
- label3_ptr = s->code_ptr;
+ /* jmp label2 */
+ tcg_out8(s, OPC_JMP_short);
+ label_ptr[2] = s->code_ptr;
s->code_ptr++;
- /* cmp 4(r1), addr_reg2 */
- tcg_out_modrm_offset(s, 0x3b, addr_reg2, r1, 4);
-
- /* je label1 */
- tcg_out8(s, 0x70 + JCC_JE);
- label1_ptr = s->code_ptr;
- s->code_ptr++;
+ /* TLB Miss. */
- /* label3: */
- *label3_ptr = s->code_ptr - label3_ptr - 1;
-#endif
+ /* label1: */
+ *label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
+ if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
+ *label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
+ }
/* XXX: move that code at the end of the TB */
-#if TARGET_LONG_BITS == 32
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EDX, mem_index);
-#else
- tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
-#endif
-#ifdef VBOX
- tcg_gen_stack_alignment_check(s);
-#endif
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_ld_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
+ /* The first argument is already loaded with addrlo. */
+ arg_idx = 1;
+ if (TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 64) {
+ tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx++],
+ args[addrlo_idx + 1]);
+ }
+ tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx],
+ mem_index);
+ tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
switch(opc) {
case 0 | 4:
- /* movsbl */
- tcg_out_modrm(s, 0xbe | P_EXT, data_reg, TCG_REG_EAX);
+ tcg_out_ext8s(s, data_reg, TCG_REG_EAX, P_REXW);
break;
case 1 | 4:
- /* movswl */
- tcg_out_modrm(s, 0xbf | P_EXT, data_reg, TCG_REG_EAX);
+ tcg_out_ext16s(s, data_reg, TCG_REG_EAX, P_REXW);
break;
case 0:
+ tcg_out_ext8u(s, data_reg, TCG_REG_EAX);
+ break;
case 1:
+ tcg_out_ext16u(s, data_reg, TCG_REG_EAX);
+ break;
case 2:
- default:
- tcg_out_mov(s, data_reg, TCG_REG_EAX);
+ tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
break;
+#if TCG_TARGET_REG_BITS == 64
+ case 2 | 4:
+ tcg_out_ext32s(s, data_reg, TCG_REG_EAX);
+ break;
+#endif
case 3:
- if (data_reg == TCG_REG_EDX) {
- tcg_out_opc(s, 0x90 + TCG_REG_EDX); /* xchg %edx, %eax */
- tcg_out_mov(s, data_reg2, TCG_REG_EAX);
+ if (TCG_TARGET_REG_BITS == 64) {
+ tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX);
+ } else if (data_reg == TCG_REG_EDX) {
+ /* xchg %edx, %eax */
+ tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX, 0, 0, 0);
+ tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EAX);
} else {
- tcg_out_mov(s, data_reg, TCG_REG_EAX);
- tcg_out_mov(s, data_reg2, TCG_REG_EDX);
+ tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
+ tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EDX);
}
break;
+ default:
+ tcg_abort();
}
- /* jmp label2 */
- tcg_out8(s, 0xeb);
- label2_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* label1: */
- *label1_ptr = s->code_ptr - label1_ptr - 1;
-
- /* add x(r1), r0 */
- tcg_out_modrm_offset(s, 0x03, r0, r1, offsetof(CPUTLBEntry, addend) -
- offsetof(CPUTLBEntry, addr_read));
+ /* label2: */
+ *label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
#else
- r0 = addr_reg;
+ {
+ int32_t offset = GUEST_BASE;
+ int base = args[addrlo_idx];
+
+ if (TCG_TARGET_REG_BITS == 64) {
+ /* ??? We assume all operations have left us with register
+ contents that are zero extended. So far this appears to
+ be true. If we want to enforce this, we can either do
+ an explicit zero-extension here, or (if GUEST_BASE == 0)
+ use the ADDR32 prefix. For now, do nothing. */
+
+ if (offset != GUEST_BASE) {
+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RDI, GUEST_BASE);
+ tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_RDI, base);
+ base = TCG_REG_RDI, offset = 0;
+ }
+ }
+
+ tcg_out_qemu_ld_direct(s, data_reg, data_reg2, base, offset, opc);
+ }
#endif
+}
+static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi,
+ int base, tcg_target_long ofs, int sizeop)
+{
#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 1;
+ const int bswap = 1;
#else
- bswap = 0;
+ const int bswap = 0;
#endif
- switch(opc) {
+ /* ??? Ideally we wouldn't need a scratch register. For user-only,
+ we could perform the bswap twice to restore the original value
+ instead of moving to the scratch. But as it is, the L constraint
+ means that the second argument reg is definitely free here. */
+ int scratch = tcg_target_call_iarg_regs[1];
+
+ switch (sizeop) {
case 0:
- /* movzbl */
- tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, 0);
- break;
- case 0 | 4:
- /* movsbl */
- tcg_out_modrm_offset(s, 0xbe | P_EXT, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, OPC_MOVB_EvGv + P_REXB_R, datalo, base, ofs);
break;
case 1:
- /* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
- if (bswap) {
- /* rolw $8, data_reg */
- tcg_out8(s, 0x66);
- tcg_out_modrm(s, 0xc1, 0, data_reg);
- tcg_out8(s, 8);
- }
- break;
- case 1 | 4:
- /* movswl */
- tcg_out_modrm_offset(s, 0xbf | P_EXT, data_reg, r0, 0);
if (bswap) {
- /* rolw $8, data_reg */
- tcg_out8(s, 0x66);
- tcg_out_modrm(s, 0xc1, 0, data_reg);
- tcg_out8(s, 8);
-
- /* movswl data_reg, data_reg */
- tcg_out_modrm(s, 0xbf | P_EXT, data_reg, data_reg);
+ tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
+ tcg_out_rolw_8(s, scratch);
+ datalo = scratch;
}
+ tcg_out_modrm_offset(s, OPC_MOVL_EvGv + P_DATA16, datalo, base, ofs);
break;
case 2:
- /* movl (r0), data_reg */
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
if (bswap) {
- /* bswap */
- tcg_out_opc(s, (0xc8 + data_reg) | P_EXT);
+ tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
+ tcg_out_bswap32(s, scratch);
+ datalo = scratch;
}
+ tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
break;
case 3:
- /* XXX: could be nicer */
- if (r0 == data_reg) {
- r1 = TCG_REG_EDX;
- if (r1 == data_reg)
- r1 = TCG_REG_EAX;
- tcg_out_mov(s, r1, r0);
- r0 = r1;
- }
- if (!bswap) {
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
- tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, 4);
+ if (TCG_TARGET_REG_BITS == 64) {
+ if (bswap) {
+ tcg_out_mov(s, TCG_TYPE_I64, scratch, datalo);
+ tcg_out_bswap64(s, scratch);
+ datalo = scratch;
+ }
+ tcg_out_st(s, TCG_TYPE_I64, datalo, base, ofs);
+ } else if (bswap) {
+ tcg_out_mov(s, TCG_TYPE_I32, scratch, datahi);
+ tcg_out_bswap32(s, scratch);
+ tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs);
+ tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
+ tcg_out_bswap32(s, scratch);
+ tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs + 4);
} else {
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 4);
- tcg_out_opc(s, (0xc8 + data_reg) | P_EXT);
-
- tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, 0);
- /* bswap */
- tcg_out_opc(s, (0xc8 + data_reg2) | P_EXT);
+ tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
+ tcg_out_st(s, TCG_TYPE_I32, datahi, base, ofs + 4);
}
break;
default:
tcg_abort();
}
#else /* VBOX */
+# error "broken"
tcg_out_vbox_phys_read(s, opc, r0, data_reg, data_reg2);
#endif
-
-
-#if defined(CONFIG_SOFTMMU)
- /* label2: */
- *label2_ptr = s->code_ptr - label2_ptr - 1;
-# ifdef VBOX
- Assert((unsigned)(s->code_ptr - label2_ptr - 1) <= 127);
-# endif
-#endif
}
-
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
int opc)
{
- int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
+ int data_reg, data_reg2 = 0;
+ int addrlo_idx;
#if defined(CONFIG_SOFTMMU)
- uint8_t *label1_ptr, *label2_ptr;
-#endif
-#if TARGET_LONG_BITS == 64
-#if defined(CONFIG_SOFTMMU)
- uint8_t *label3_ptr;
-#endif
- int addr_reg2;
+ int mem_index, s_bits;
+ int stack_adjust;
+ uint8_t *label_ptr[3];
#endif
-#ifdef VBOX
-# ifdef RT_OS_DARWIN
- int bias1 = 12, bias3 = 4;/** @todo TCG_TARGET_STACK_ALIGN. */
-# else
- int bias1 = 0, bias3 = 0;
-# endif
- NOREF(bias3);
-#endif
-
- data_reg = *args++;
- if (opc == 3)
- data_reg2 = *args++;
- else
- data_reg2 = 0;
- addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
- addr_reg2 = *args++;
-#endif
- mem_index = *args;
-
- s_bits = opc;
- r0 = TCG_REG_EAX;
- r1 = TCG_REG_EDX;
+ data_reg = args[0];
+ addrlo_idx = 1;
+ if (TCG_TARGET_REG_BITS == 32 && opc == 3) {
+ data_reg2 = args[1];
+ addrlo_idx = 2;
+ }
#if defined(CONFIG_SOFTMMU)
- tcg_out_mov(s, r1, addr_reg);
-
- tcg_out_mov(s, r0, addr_reg);
-
- tcg_out_modrm(s, 0xc1, 5, r1); /* shr $x, r1 */
- tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
-
- tcg_out_modrm(s, 0x81, 4, r0); /* andl $x, r0 */
- tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
-
- tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
- tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-
-#ifndef VBOX
- tcg_out_opc(s, 0x8d); /* lea offset(r1, %ebp), r1 */
- tcg_out8(s, 0x80 | (r1 << 3) | 0x04);
- tcg_out8(s, (5 << 3) | r1);
- tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_write));
-#else
- tcg_out_opc(s, 0x8d); /* lea offset(r1, env), r1 */
- tcg_out8(s, 0x80 | (r1 << 3) | 0x04);
- tcg_out8(s, (TCG_AREG0 << 3) | r1);
- tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_write));
-#endif
+ mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)];
+ s_bits = opc;
- /* cmp 0(r1), r0 */
- tcg_out_modrm_offset(s, 0x3b, r0, r1, 0);
+ tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
+ label_ptr, offsetof(CPUTLBEntry, addr_write));
- tcg_out_mov(s, r0, addr_reg);
+ /* TLB Hit. */
+ tcg_out_qemu_st_direct(s, data_reg, data_reg2,
+ tcg_target_call_iarg_regs[0], 0, opc);
-#if TARGET_LONG_BITS == 32
- /* je label1 */
- tcg_out8(s, 0x70 + JCC_JE);
- label1_ptr = s->code_ptr;
- s->code_ptr++;
-#else
- /* jne label3 */
- tcg_out8(s, 0x70 + JCC_JNE);
- label3_ptr = s->code_ptr;
+ /* jmp label2 */
+ tcg_out8(s, OPC_JMP_short);
+ label_ptr[2] = s->code_ptr;
s->code_ptr++;
- /* cmp 4(r1), addr_reg2 */
- tcg_out_modrm_offset(s, 0x3b, addr_reg2, r1, 4);
+ /* TLB Miss. */
- /* je label1 */
- tcg_out8(s, 0x70 + JCC_JE);
- label1_ptr = s->code_ptr;
- s->code_ptr++;
+ /* label1: */
+ *label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
+ if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
+ *label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
+ }
- /* label3: */
- *label3_ptr = s->code_ptr - label3_ptr - 1;
-#endif
+# if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
+# if defined(VBOX) && defined(RT_OS_DARWIN) && ARCH_BITS == 32
+# define VBOX_16_BYTE_STACK_ALIGN
+# endif
/* XXX: move that code at the end of the TB */
-#if TARGET_LONG_BITS == 32
- if (opc == 3) {
- tcg_out_mov(s, TCG_REG_EDX, data_reg);
- tcg_out_mov(s, TCG_REG_ECX, data_reg2);
-#ifdef VBOX
- tcg_out_subi(s, TCG_REG_ESP, bias1);
-#endif
- tcg_out8(s, 0x6a); /* push Ib */
- tcg_out8(s, mem_index);
-# ifdef VBOX
- tcg_gen_stack_alignment_check(s);
-# endif
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
-#ifdef VBOX
- tcg_out_addi(s, TCG_REG_ESP, 4+bias1);
-#else
- tcg_out_addi(s, TCG_REG_ESP, 4);
-#endif
- } else {
- switch(opc) {
- case 0:
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT, TCG_REG_EDX, data_reg);
- break;
- case 1:
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_EDX, data_reg);
- break;
- case 2:
- tcg_out_mov(s, TCG_REG_EDX, data_reg);
- break;
+ if (TCG_TARGET_REG_BITS == 64) {
+ tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
+ TCG_REG_RSI, data_reg);
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index);
+ stack_adjust = 0;
+ } else if (TARGET_LONG_BITS == 32) {
+ tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, data_reg);
+ if (opc == 3) {
+ tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_ECX, data_reg2);
+# ifdef VBOX_16_BYTE_STACK_ALIGN
+ tcg_out_subi(s, TCG_REG_ESP, 12);
+# endif
+ tcg_out_pushi(s, mem_index);
+ stack_adjust = 4;
+ } else {
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
+ stack_adjust = 0;
}
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
-# ifdef VBOX
- tcg_gen_stack_alignment_check(s);
-# endif
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
- }
-#else
- if (opc == 3) {
- tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
-# ifdef VBOX
- tcg_out_subi(s, TCG_REG_ESP, bias3);
-# endif
- tcg_out8(s, 0x6a); /* push Ib */
- tcg_out8(s, mem_index);
- tcg_out_opc(s, 0x50 + data_reg2); /* push */
- tcg_out_opc(s, 0x50 + data_reg); /* push */
-# ifdef VBOX
- tcg_gen_stack_alignment_check(s);
-# endif
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
-#ifdef VBOX
- tcg_out_addi(s, TCG_REG_ESP, 12+bias3);
-#else
- tcg_out_addi(s, TCG_REG_ESP, 12);
-#endif
} else {
- tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
- switch(opc) {
- case 0:
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT, TCG_REG_ECX, data_reg);
- break;
- case 1:
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_ECX, data_reg);
- break;
- case 2:
- tcg_out_mov(s, TCG_REG_ECX, data_reg);
- break;
+ if (opc == 3) {
+ tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, args[addrlo_idx + 1]);
+# ifdef VBOX_16_BYTE_STACK_ALIGN
+ tcg_out_pushi(s, 0);
+# endif
+ tcg_out_pushi(s, mem_index);
+ tcg_out_push(s, data_reg2);
+ tcg_out_push(s, data_reg);
+ stack_adjust = 12;
+ } else {
+ tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, args[addrlo_idx + 1]);
+ switch(opc) {
+ case 0:
+ tcg_out_ext8u(s, TCG_REG_ECX, data_reg);
+ break;
+ case 1:
+ tcg_out_ext16u(s, TCG_REG_ECX, data_reg);
+ break;
+ case 2:
+ tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_ECX, data_reg);
+ break;
+ }
+# ifdef VBOX_16_BYTE_STACK_ALIGN
+ tcg_out_subi(s, TCG_REG_ESP, 12);
+# endif
+ tcg_out_pushi(s, mem_index);
+ stack_adjust = 4;
}
-# ifdef VBOX
- tcg_out_subi(s, TCG_REG_ESP, bias1);
-# endif
- tcg_out8(s, 0x6a); /* push Ib */
- tcg_out8(s, mem_index);
-# ifdef VBOX
- tcg_gen_stack_alignment_check(s);
-# endif
-
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
-# if defined(VBOX)
- tcg_out_addi(s, TCG_REG_ESP, 4 + bias1);
-# else
- tcg_out_addi(s, TCG_REG_ESP, 4);
-# endif
}
-#endif
- /* jmp label2 */
- tcg_out8(s, 0xeb);
- label2_ptr = s->code_ptr;
- s->code_ptr++;
+ tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
- /* label1: */
- *label1_ptr = s->code_ptr - label1_ptr - 1;
+# ifdef VBOX_16_BYTE_STACK_ALIGN
+ if (stack_adjust != 0) {
+ tcg_out_addi(s, TCG_REG_ESP, RT_ALIGN(stack_adjust, 16));
+ }
+# else
+ if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
+ /* Pop and discard. This is 2 bytes smaller than the add. */
+ tcg_out_pop(s, TCG_REG_ECX);
+ } else if (stack_adjust != 0) {
+ tcg_out_addi(s, TCG_REG_ESP, stack_adjust);
+ }
+# endif
- /* add x(r1), r0 */
- tcg_out_modrm_offset(s, 0x03, r0, r1, offsetof(CPUTLBEntry, addend) -
- offsetof(CPUTLBEntry, addr_write));
-#else
- r0 = addr_reg;
-#endif
+# else /* VBOX && REM_PHYS_ADDR_IN_TLB */
+# error Borked
+ tcg_out_vbox_phys_write(s, opc, r0, data_reg, data_reg2);
+# endif /* VBOX && REM_PHYS_ADDR_IN_TLB */
-#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 1;
+ /* label2: */
+ *label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
#else
- bswap = 0;
-#endif
- switch(opc) {
- case 0:
- /* movb */
- tcg_out_modrm_offset(s, 0x88, data_reg, r0, 0);
- break;
- case 1:
- if (bswap) {
- tcg_out_mov(s, r1, data_reg);
- tcg_out8(s, 0x66); /* rolw $8, %ecx */
- tcg_out_modrm(s, 0xc1, 0, r1);
- tcg_out8(s, 8);
- data_reg = r1;
- }
- /* movw */
- tcg_out8(s, 0x66);
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
- break;
- case 2:
- if (bswap) {
- tcg_out_mov(s, r1, data_reg);
- /* bswap data_reg */
- tcg_out_opc(s, (0xc8 + r1) | P_EXT);
- data_reg = r1;
- }
- /* movl */
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
- break;
- case 3:
- if (bswap) {
- tcg_out_mov(s, r1, data_reg2);
- /* bswap data_reg */
- tcg_out_opc(s, (0xc8 + r1) | P_EXT);
- tcg_out_modrm_offset(s, 0x89, r1, r0, 0);
- tcg_out_mov(s, r1, data_reg);
- /* bswap data_reg */
- tcg_out_opc(s, (0xc8 + r1) | P_EXT);
- tcg_out_modrm_offset(s, 0x89, r1, r0, 4);
- } else {
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
- tcg_out_modrm_offset(s, 0x89, data_reg2, r0, 4);
+ {
+ int32_t offset = GUEST_BASE;
+ int base = args[addrlo_idx];
+
+ if (TCG_TARGET_REG_BITS == 64) {
+ /* ??? We assume all operations have left us with register
+ contents that are zero extended. So far this appears to
+ be true. If we want to enforce this, we can either do
+ an explicit zero-extension here, or (if GUEST_BASE == 0)
+ use the ADDR32 prefix. For now, do nothing. */
+
+ if (offset != GUEST_BASE) {
+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RDI, GUEST_BASE);
+ tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_RDI, base);
+ base = TCG_REG_RDI, offset = 0;
+ }
}
- break;
- default:
- tcg_abort();
- }
-#else
- tcg_out_vbox_phys_write(s, opc, r0, data_reg, data_reg2);
-#endif
-#if defined(CONFIG_SOFTMMU)
- /* label2: */
- *label2_ptr = s->code_ptr - label2_ptr - 1;
-# ifdef VBOX
- Assert((unsigned)(s->code_ptr - label2_ptr - 1) <= 127);
-# endif
+ tcg_out_qemu_st_direct(s, data_reg, data_reg2, base, offset, opc);
+ }
#endif
}
-#ifndef VBOX
-static inline void tcg_out_op(TCGContext *s, int opc,
-#else /* VBOX */
-DECLINLINE(void) tcg_out_op(TCGContext *s, int opc,
-#endif /* VBOX */
+static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg *args, const int *const_args)
{
- int c;
+ int c, rexw = 0;
+
+#if TCG_TARGET_REG_BITS == 64
+# define OP_32_64(x) \
+ case glue(glue(INDEX_op_, x), _i64): \
+ rexw = P_REXW; /* FALLTHRU */ \
+ case glue(glue(INDEX_op_, x), _i32)
+#else
+# define OP_32_64(x) \
+ case glue(glue(INDEX_op_, x), _i32)
+#endif
switch(opc) {
case INDEX_op_exit_tb:
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EAX, args[0]);
- tcg_out8(s, 0xe9); /* jmp tb_ret_addr */
- tcg_out32(s, tb_ret_addr - s->code_ptr - 4);
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_EAX, args[0]);
+ tcg_out_jmp(s, (tcg_target_long) tb_ret_addr);
break;
case INDEX_op_goto_tb:
if (s->tb_jmp_offset) {
/* direct jump method */
- tcg_out8(s, 0xe9); /* jmp im */
+ tcg_out8(s, OPC_JMP_long); /* jmp im */
s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
tcg_out32(s, 0);
} else {
/* indirect jump method */
- /* jmp Ev */
- tcg_out_modrm_offset(s, 0xff, 4, -1,
+ tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
(tcg_target_long)(s->tb_next + args[0]));
}
s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
break;
case INDEX_op_call:
-#ifdef VBOX
- tcg_gen_stack_alignment_check(s);
-#endif
if (const_args[0]) {
- tcg_out8(s, 0xe8);
- tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
+ tcg_out_calli(s, args[0]);
} else {
- tcg_out_modrm(s, 0xff, 2, args[0]);
+ /* call *reg */
+ tcg_out_modrm(s, OPC_GRP5, EXT5_CALLN_Ev, args[0]);
}
break;
case INDEX_op_jmp:
if (const_args[0]) {
- tcg_out8(s, 0xe9);
- tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
+ tcg_out_jmp(s, args[0]);
} else {
- tcg_out_modrm(s, 0xff, 4, args[0]);
+ /* jmp *reg */
+ tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, args[0]);
}
break;
case INDEX_op_br:
- tcg_out_jxx(s, JCC_JMP, args[0]);
+ tcg_out_jxx(s, JCC_JMP, args[0], 0);
break;
case INDEX_op_movi_i32:
tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
break;
- case INDEX_op_ld8u_i32:
- /* movzbl */
- tcg_out_modrm_offset(s, 0xb6 | P_EXT, args[0], args[1], args[2]);
+ OP_32_64(ld8u):
+ /* Note that we can ignore REXW for the zero-extend to 64-bit. */
+ tcg_out_modrm_offset(s, OPC_MOVZBL, args[0], args[1], args[2]);
break;
- case INDEX_op_ld8s_i32:
- /* movsbl */
- tcg_out_modrm_offset(s, 0xbe | P_EXT, args[0], args[1], args[2]);
+ OP_32_64(ld8s):
+ tcg_out_modrm_offset(s, OPC_MOVSBL + rexw, args[0], args[1], args[2]);
break;
- case INDEX_op_ld16u_i32:
- /* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, args[0], args[1], args[2]);
+ OP_32_64(ld16u):
+ /* Note that we can ignore REXW for the zero-extend to 64-bit. */
+ tcg_out_modrm_offset(s, OPC_MOVZWL, args[0], args[1], args[2]);
break;
- case INDEX_op_ld16s_i32:
- /* movswl */
- tcg_out_modrm_offset(s, 0xbf | P_EXT, args[0], args[1], args[2]);
+ OP_32_64(ld16s):
+ tcg_out_modrm_offset(s, OPC_MOVSWL + rexw, args[0], args[1], args[2]);
break;
+#if TCG_TARGET_REG_BITS == 64
+ case INDEX_op_ld32u_i64:
+#endif
case INDEX_op_ld_i32:
- /* movl */
- tcg_out_modrm_offset(s, 0x8b, args[0], args[1], args[2]);
+ tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
break;
- case INDEX_op_st8_i32:
- /* movb */
- tcg_out_modrm_offset(s, 0x88, args[0], args[1], args[2]);
+
+ OP_32_64(st8):
+ tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
+ args[0], args[1], args[2]);
break;
- case INDEX_op_st16_i32:
- /* movw */
- tcg_out8(s, 0x66);
- tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]);
+ OP_32_64(st16):
+ tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
+ args[0], args[1], args[2]);
break;
+#if TCG_TARGET_REG_BITS == 64
+ case INDEX_op_st32_i64:
+#endif
case INDEX_op_st_i32:
- /* movl */
- tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]);
+ tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
break;
- case INDEX_op_sub_i32:
+
+ OP_32_64(add):
+ /* For 3-operand addition, use LEA. */
+ if (args[0] != args[1]) {
+ TCGArg a0 = args[0], a1 = args[1], a2 = args[2], c3 = 0;
+
+ if (const_args[2]) {
+ c3 = a2, a2 = -1;
+ } else if (a0 == a2) {
+ /* Watch out for dest = src + dest, since we've removed
+ the matching constraint on the add. */
+ tgen_arithr(s, ARITH_ADD + rexw, a0, a1);
+ break;
+ }
+
+ tcg_out_modrm_sib_offset(s, OPC_LEA + rexw, a0, a1, a2, 0, c3);
+ break;
+ }
+ c = ARITH_ADD;
+ goto gen_arith;
+ OP_32_64(sub):
c = ARITH_SUB;
goto gen_arith;
- case INDEX_op_and_i32:
+ OP_32_64(and):
c = ARITH_AND;
goto gen_arith;
- case INDEX_op_or_i32:
+ OP_32_64(or):
c = ARITH_OR;
goto gen_arith;
- case INDEX_op_xor_i32:
+ OP_32_64(xor):
c = ARITH_XOR;
goto gen_arith;
- case INDEX_op_add_i32:
- c = ARITH_ADD;
gen_arith:
if (const_args[2]) {
- tgen_arithi(s, c, args[0], args[2]);
+ tgen_arithi(s, c + rexw, args[0], args[2], 0);
} else {
- tcg_out_modrm(s, 0x01 | (c << 3), args[2], args[0]);
+ tgen_arithr(s, c + rexw, args[0], args[2]);
}
break;
- case INDEX_op_mul_i32:
+
+ OP_32_64(mul):
if (const_args[2]) {
int32_t val;
val = args[2];
if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x6b, args[0], args[0]);
+ tcg_out_modrm(s, OPC_IMUL_GvEvIb + rexw, args[0], args[0]);
tcg_out8(s, val);
} else {
- tcg_out_modrm(s, 0x69, args[0], args[0]);
+ tcg_out_modrm(s, OPC_IMUL_GvEvIz + rexw, args[0], args[0]);
tcg_out32(s, val);
}
} else {
- tcg_out_modrm(s, 0xaf | P_EXT, args[0], args[2]);
+ tcg_out_modrm(s, OPC_IMUL_GvEv + rexw, args[0], args[2]);
}
break;
- case INDEX_op_mulu2_i32:
- tcg_out_modrm(s, 0xf7, 4, args[3]);
- break;
- case INDEX_op_div2_i32:
- tcg_out_modrm(s, 0xf7, 7, args[4]);
+
+ OP_32_64(div2):
+ tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_IDIV, args[4]);
break;
- case INDEX_op_divu2_i32:
- tcg_out_modrm(s, 0xf7, 6, args[4]);
+ OP_32_64(divu2):
+ tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_DIV, args[4]);
break;
- case INDEX_op_shl_i32:
+
+ OP_32_64(shl):
c = SHIFT_SHL;
- gen_shift32:
+ goto gen_shift;
+ OP_32_64(shr):
+ c = SHIFT_SHR;
+ goto gen_shift;
+ OP_32_64(sar):
+ c = SHIFT_SAR;
+ goto gen_shift;
+ OP_32_64(rotl):
+ c = SHIFT_ROL;
+ goto gen_shift;
+ OP_32_64(rotr):
+ c = SHIFT_ROR;
+ goto gen_shift;
+ gen_shift:
if (const_args[2]) {
- if (args[2] == 1) {
- tcg_out_modrm(s, 0xd1, c, args[0]);
- } else {
- tcg_out_modrm(s, 0xc1, c, args[0]);
- tcg_out8(s, args[2]);
- }
+ tcg_out_shifti(s, c + rexw, args[0], args[2]);
} else {
- tcg_out_modrm(s, 0xd3, c, args[0]);
+ tcg_out_modrm(s, OPC_SHIFT_cl + rexw, c, args[0]);
}
break;
- case INDEX_op_shr_i32:
- c = SHIFT_SHR;
- goto gen_shift32;
- case INDEX_op_sar_i32:
- c = SHIFT_SAR;
- goto gen_shift32;
- case INDEX_op_add2_i32:
- if (const_args[4])
- tgen_arithi(s, ARITH_ADD, args[0], args[4]);
- else
- tcg_out_modrm(s, 0x01 | (ARITH_ADD << 3), args[4], args[0]);
- if (const_args[5])
- tgen_arithi(s, ARITH_ADC, args[1], args[5]);
- else
- tcg_out_modrm(s, 0x01 | (ARITH_ADC << 3), args[5], args[1]);
+ case INDEX_op_brcond_i32:
+ tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1],
+ args[3], 0);
break;
- case INDEX_op_sub2_i32:
- if (const_args[4])
- tgen_arithi(s, ARITH_SUB, args[0], args[4]);
- else
- tcg_out_modrm(s, 0x01 | (ARITH_SUB << 3), args[4], args[0]);
- if (const_args[5])
- tgen_arithi(s, ARITH_SBB, args[1], args[5]);
- else
- tcg_out_modrm(s, 0x01 | (ARITH_SBB << 3), args[5], args[1]);
+ case INDEX_op_setcond_i32:
+ tcg_out_setcond32(s, args[3], args[0], args[1],
+ args[2], const_args[2]);
break;
- case INDEX_op_brcond_i32:
- tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], args[3]);
+
+ OP_32_64(bswap16):
+ tcg_out_rolw_8(s, args[0]);
break;
- case INDEX_op_brcond2_i32:
- tcg_out_brcond2(s, args, const_args);
+ OP_32_64(bswap32):
+ tcg_out_bswap32(s, args[0]);
+ break;
+
+ OP_32_64(neg):
+ tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NEG, args[0]);
+ break;
+ OP_32_64(not):
+ tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, args[0]);
+ break;
+
+ OP_32_64(ext8s):
+ tcg_out_ext8s(s, args[0], args[1], rexw);
+ break;
+ OP_32_64(ext16s):
+ tcg_out_ext16s(s, args[0], args[1], rexw);
+ break;
+ OP_32_64(ext8u):
+ tcg_out_ext8u(s, args[0], args[1]);
+ break;
+ OP_32_64(ext16u):
+ tcg_out_ext16u(s, args[0], args[1]);
break;
case INDEX_op_qemu_ld8u:
@@ -1317,7 +1843,10 @@ DECLINLINE(void) tcg_out_op(TCGContext *s, int opc,
case INDEX_op_qemu_ld16s:
tcg_out_qemu_ld(s, args, 1 | 4);
break;
+#if TCG_TARGET_REG_BITS == 64
case INDEX_op_qemu_ld32u:
+#endif
+ case INDEX_op_qemu_ld32:
tcg_out_qemu_ld(s, args, 2);
break;
case INDEX_op_qemu_ld64:
@@ -1337,17 +1866,90 @@ DECLINLINE(void) tcg_out_op(TCGContext *s, int opc,
tcg_out_qemu_st(s, args, 3);
break;
+#if TCG_TARGET_REG_BITS == 32
+ case INDEX_op_brcond2_i32:
+ tcg_out_brcond2(s, args, const_args, 0);
+ break;
+ case INDEX_op_setcond2_i32:
+ tcg_out_setcond2(s, args, const_args);
+ break;
+ case INDEX_op_mulu2_i32:
+ tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_MUL, args[3]);
+ break;
+ case INDEX_op_add2_i32:
+ if (const_args[4]) {
+ tgen_arithi(s, ARITH_ADD, args[0], args[4], 1);
+ } else {
+ tgen_arithr(s, ARITH_ADD, args[0], args[4]);
+ }
+ if (const_args[5]) {
+ tgen_arithi(s, ARITH_ADC, args[1], args[5], 1);
+ } else {
+ tgen_arithr(s, ARITH_ADC, args[1], args[5]);
+ }
+ break;
+ case INDEX_op_sub2_i32:
+ if (const_args[4]) {
+ tgen_arithi(s, ARITH_SUB, args[0], args[4], 1);
+ } else {
+ tgen_arithr(s, ARITH_SUB, args[0], args[4]);
+ }
+ if (const_args[5]) {
+ tgen_arithi(s, ARITH_SBB, args[1], args[5], 1);
+ } else {
+ tgen_arithr(s, ARITH_SBB, args[1], args[5]);
+ }
+ break;
+#else /* TCG_TARGET_REG_BITS == 64 */
+ case INDEX_op_movi_i64:
+ tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
+ break;
+ case INDEX_op_ld32s_i64:
+ tcg_out_modrm_offset(s, OPC_MOVSLQ, args[0], args[1], args[2]);
+ break;
+ case INDEX_op_ld_i64:
+ tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
+ break;
+ case INDEX_op_st_i64:
+ tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
+ break;
+ case INDEX_op_qemu_ld32s:
+ tcg_out_qemu_ld(s, args, 2 | 4);
+ break;
+
+ case INDEX_op_brcond_i64:
+ tcg_out_brcond64(s, args[2], args[0], args[1], const_args[1],
+ args[3], 0);
+ break;
+ case INDEX_op_setcond_i64:
+ tcg_out_setcond64(s, args[3], args[0], args[1],
+ args[2], const_args[2]);
+ break;
+
+ case INDEX_op_bswap64_i64:
+ tcg_out_bswap64(s, args[0]);
+ break;
+ case INDEX_op_ext32u_i64:
+ tcg_out_ext32u(s, args[0], args[1]);
+ break;
+ case INDEX_op_ext32s_i64:
+ tcg_out_ext32s(s, args[0], args[1]);
+ break;
+#endif
+
default:
tcg_abort();
}
+
+#undef OP_32_64
}
static const TCGTargetOpDef x86_op_defs[] = {
- { INDEX_op_exit_tb, {"", "" } },
- { INDEX_op_goto_tb, {"", "" } },
- { INDEX_op_call, { "ri", "", } },
- { INDEX_op_jmp, { "ri", ""} },
- { INDEX_op_br, {"", "" } },
+ { INDEX_op_exit_tb, { } },
+ { INDEX_op_goto_tb, { } },
+ { INDEX_op_call, { "ri" } },
+ { INDEX_op_jmp, { "ri" } },
+ { INDEX_op_br, { } },
{ INDEX_op_mov_i32, { "r", "r" } },
{ INDEX_op_movi_i32, { "r" } },
{ INDEX_op_ld8u_i32, { "r", "r" } },
@@ -1359,10 +1961,9 @@ static const TCGTargetOpDef x86_op_defs[] = {
{ INDEX_op_st16_i32, { "r", "r" } },
{ INDEX_op_st_i32, { "r", "r" } },
- { INDEX_op_add_i32, { "r", "0", "ri" } },
+ { INDEX_op_add_i32, { "r", "r", "ri" } },
{ INDEX_op_sub_i32, { "r", "0", "ri" } },
{ INDEX_op_mul_i32, { "r", "0", "ri" } },
- { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
{ INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
{ INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
{ INDEX_op_and_i32, { "r", "0", "ri" } },
@@ -1372,19 +1973,98 @@ static const TCGTargetOpDef x86_op_defs[] = {
{ INDEX_op_shl_i32, { "r", "0", "ci" } },
{ INDEX_op_shr_i32, { "r", "0", "ci" } },
{ INDEX_op_sar_i32, { "r", "0", "ci" } },
+ { INDEX_op_rotl_i32, { "r", "0", "ci" } },
+ { INDEX_op_rotr_i32, { "r", "0", "ci" } },
{ INDEX_op_brcond_i32, { "r", "ri" } },
+ { INDEX_op_bswap16_i32, { "r", "0" } },
+ { INDEX_op_bswap32_i32, { "r", "0" } },
+
+ { INDEX_op_neg_i32, { "r", "0" } },
+
+ { INDEX_op_not_i32, { "r", "0" } },
+
+ { INDEX_op_ext8s_i32, { "r", "q" } },
+ { INDEX_op_ext16s_i32, { "r", "r" } },
+ { INDEX_op_ext8u_i32, { "r", "q" } },
+ { INDEX_op_ext16u_i32, { "r", "r" } },
+
+ { INDEX_op_setcond_i32, { "q", "r", "ri" } },
+
+#if TCG_TARGET_REG_BITS == 32
+ { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
{ INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
{ INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
{ INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
+ { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
+#else
+ { INDEX_op_mov_i64, { "r", "r" } },
+ { INDEX_op_movi_i64, { "r" } },
+ { INDEX_op_ld8u_i64, { "r", "r" } },
+ { INDEX_op_ld8s_i64, { "r", "r" } },
+ { INDEX_op_ld16u_i64, { "r", "r" } },
+ { INDEX_op_ld16s_i64, { "r", "r" } },
+ { INDEX_op_ld32u_i64, { "r", "r" } },
+ { INDEX_op_ld32s_i64, { "r", "r" } },
+ { INDEX_op_ld_i64, { "r", "r" } },
+ { INDEX_op_st8_i64, { "r", "r" } },
+ { INDEX_op_st16_i64, { "r", "r" } },
+ { INDEX_op_st32_i64, { "r", "r" } },
+ { INDEX_op_st_i64, { "r", "r" } },
+
+ { INDEX_op_add_i64, { "r", "0", "re" } },
+ { INDEX_op_mul_i64, { "r", "0", "re" } },
+ { INDEX_op_div2_i64, { "a", "d", "0", "1", "r" } },
+ { INDEX_op_divu2_i64, { "a", "d", "0", "1", "r" } },
+ { INDEX_op_sub_i64, { "r", "0", "re" } },
+ { INDEX_op_and_i64, { "r", "0", "reZ" } },
+ { INDEX_op_or_i64, { "r", "0", "re" } },
+ { INDEX_op_xor_i64, { "r", "0", "re" } },
+
+ { INDEX_op_shl_i64, { "r", "0", "ci" } },
+ { INDEX_op_shr_i64, { "r", "0", "ci" } },
+ { INDEX_op_sar_i64, { "r", "0", "ci" } },
+ { INDEX_op_rotl_i64, { "r", "0", "ci" } },
+ { INDEX_op_rotr_i64, { "r", "0", "ci" } },
+
+ { INDEX_op_brcond_i64, { "r", "re" } },
+ { INDEX_op_setcond_i64, { "r", "r", "re" } },
+
+ { INDEX_op_bswap16_i64, { "r", "0" } },
+ { INDEX_op_bswap32_i64, { "r", "0" } },
+ { INDEX_op_bswap64_i64, { "r", "0" } },
+ { INDEX_op_neg_i64, { "r", "0" } },
+ { INDEX_op_not_i64, { "r", "0" } },
+
+ { INDEX_op_ext8s_i64, { "r", "r" } },
+ { INDEX_op_ext16s_i64, { "r", "r" } },
+ { INDEX_op_ext32s_i64, { "r", "r" } },
+ { INDEX_op_ext8u_i64, { "r", "r" } },
+ { INDEX_op_ext16u_i64, { "r", "r" } },
+ { INDEX_op_ext32u_i64, { "r", "r" } },
+#endif
-#if TARGET_LONG_BITS == 32
+#if TCG_TARGET_REG_BITS == 64
{ INDEX_op_qemu_ld8u, { "r", "L" } },
{ INDEX_op_qemu_ld8s, { "r", "L" } },
{ INDEX_op_qemu_ld16u, { "r", "L" } },
{ INDEX_op_qemu_ld16s, { "r", "L" } },
+ { INDEX_op_qemu_ld32, { "r", "L" } },
{ INDEX_op_qemu_ld32u, { "r", "L" } },
+ { INDEX_op_qemu_ld32s, { "r", "L" } },
+ { INDEX_op_qemu_ld64, { "r", "L" } },
+
+ { INDEX_op_qemu_st8, { "L", "L" } },
+ { INDEX_op_qemu_st16, { "L", "L" } },
+ { INDEX_op_qemu_st32, { "L", "L" } },
+ { INDEX_op_qemu_st64, { "L", "L" } },
+#elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
+ { INDEX_op_qemu_ld8u, { "r", "L" } },
+ { INDEX_op_qemu_ld8s, { "r", "L" } },
+ { INDEX_op_qemu_ld16u, { "r", "L" } },
+ { INDEX_op_qemu_ld16s, { "r", "L" } },
+ { INDEX_op_qemu_ld32, { "r", "L" } },
{ INDEX_op_qemu_ld64, { "r", "r", "L" } },
{ INDEX_op_qemu_st8, { "cb", "L" } },
@@ -1396,7 +2076,7 @@ static const TCGTargetOpDef x86_op_defs[] = {
{ INDEX_op_qemu_ld8s, { "r", "L", "L" } },
{ INDEX_op_qemu_ld16u, { "r", "L", "L" } },
{ INDEX_op_qemu_ld16s, { "r", "L", "L" } },
- { INDEX_op_qemu_ld32u, { "r", "L", "L" } },
+ { INDEX_op_qemu_ld32, { "r", "L", "L" } },
{ INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
{ INDEX_op_qemu_st8, { "cb", "L", "L" } },
@@ -1404,46 +2084,60 @@ static const TCGTargetOpDef x86_op_defs[] = {
{ INDEX_op_qemu_st32, { "L", "L", "L" } },
{ INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
#endif
-#ifndef VBOX
{ -1 },
-#else
- { -1, {"", "", "", ""} },
-#endif
};
static int tcg_target_callee_save_regs[] = {
-#ifndef VBOX
- /* TCG_REG_EBP, */ /* currently used for the global env, so no
- need to save */
+#if TCG_TARGET_REG_BITS == 64
+ TCG_REG_RBP,
+ TCG_REG_RBX,
+ TCG_REG_R12,
+ TCG_REG_R13,
+ /* TCG_REG_R14, */ /* Currently used for the global env. */
+ TCG_REG_R15,
+#else
+# ifndef VBOX
+ /* TCG_REG_EBP, */ /* Currently used for the global env. */
TCG_REG_EBX,
TCG_REG_ESI,
TCG_REG_EDI,
-#else
+# else
TCG_REG_EBP,
TCG_REG_EBX,
- /* TCG_REG_ESI, */ /* currently used for the global env, so no
- need to save */
+ /* TCG_REG_ESI, */ /* Currently used for the global env. */
TCG_REG_EDI,
+# endif
#endif
};
/* Generate global QEMU prologue and epilogue code */
-void tcg_target_qemu_prologue(TCGContext *s)
+static void tcg_target_qemu_prologue(TCGContext *s)
{
int i, frame_size, push_size, stack_addend;
/* TB prologue */
- /* save all callee saved registers */
- for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+
+ /* Save all callee saved registers. */
+ for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
tcg_out_push(s, tcg_target_callee_save_regs[i]);
}
- /* reserve some stack space */
- push_size = 4 + ARRAY_SIZE(tcg_target_callee_save_regs) * 4;
+# if defined(VBOX_STRICT) && defined(RT_ARCH_X86)
+ tcg_out8(s, 0x31); /* xor ebp, ebp */
+ tcg_out8(s, 0xed);
+# endif
+
+ /* Reserve some stack space. */
+ push_size = 1 + ARRAY_SIZE(tcg_target_callee_save_regs);
+ push_size *= TCG_TARGET_REG_BITS / 8;
+
frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
~(TCG_TARGET_STACK_ALIGN - 1);
stack_addend = frame_size - push_size;
tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
+
+ /* jmp *tb. */
+ tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[0]);
# ifdef VBOX
tcg_gen_stack_alignment_check(s);
# endif
@@ -1452,24 +2146,42 @@ void tcg_target_qemu_prologue(TCGContext *s)
/* TB epilogue */
tb_ret_addr = s->code_ptr;
+
tcg_out_addi(s, TCG_REG_ESP, stack_addend);
- for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
+
+ for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
tcg_out_pop(s, tcg_target_callee_save_regs[i]);
}
- tcg_out8(s, 0xc3); /* ret */
+ tcg_out_opc(s, OPC_RET, 0, 0, 0);
}
-void tcg_target_init(TCGContext *s)
+static void tcg_target_init(TCGContext *s)
{
+#if !defined(CONFIG_USER_ONLY)
/* fail safe */
if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
tcg_abort();
+#endif
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
- tcg_regset_set32(tcg_target_call_clobber_regs, 0,
- (1 << TCG_REG_EAX) |
- (1 << TCG_REG_EDX) |
- (1 << TCG_REG_ECX));
+ if (TCG_TARGET_REG_BITS == 64) {
+ tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
+ tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
+ } else {
+ tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
+ }
+
+ tcg_regset_clear(tcg_target_call_clobber_regs);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
+ if (TCG_TARGET_REG_BITS == 64) {
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RDI);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RSI);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
+ }
tcg_regset_clear(s->reserved_regs);
tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP);
diff --git a/src/recompiler/tcg/i386/tcg-target.h b/src/recompiler/tcg/i386/tcg-target.h
index 65591ae2e..22c18d626 100644
--- a/src/recompiler/tcg/i386/tcg-target.h
+++ b/src/recompiler/tcg/i386/tcg-target.h
@@ -21,13 +21,20 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-
#define TCG_TARGET_I386 1
-#define TCG_TARGET_REG_BITS 32
+#if defined(__x86_64__)
+# define TCG_TARGET_REG_BITS 64
+#else
+# define TCG_TARGET_REG_BITS 32
+#endif
//#define TCG_TARGET_WORDS_BIGENDIAN
-#define TCG_TARGET_NB_REGS 8
+#if TCG_TARGET_REG_BITS == 64
+# define TCG_TARGET_NB_REGS 16
+#else
+# define TCG_TARGET_NB_REGS 8
+#endif
enum {
TCG_REG_EAX = 0,
@@ -38,28 +45,86 @@ enum {
TCG_REG_EBP,
TCG_REG_ESI,
TCG_REG_EDI,
+
+ /* 64-bit registers; always define the symbols to avoid
+ too much if-deffing. */
+ TCG_REG_R8,
+ TCG_REG_R9,
+ TCG_REG_R10,
+ TCG_REG_R11,
+ TCG_REG_R12,
+ TCG_REG_R13,
+ TCG_REG_R14,
+ TCG_REG_R15,
+ TCG_REG_RAX = TCG_REG_EAX,
+ TCG_REG_RCX = TCG_REG_ECX,
+ TCG_REG_RDX = TCG_REG_EDX,
+ TCG_REG_RBX = TCG_REG_EBX,
+ TCG_REG_RSP = TCG_REG_ESP,
+ TCG_REG_RBP = TCG_REG_EBP,
+ TCG_REG_RSI = TCG_REG_ESI,
+ TCG_REG_RDI = TCG_REG_EDI,
};
+#define TCG_CT_CONST_S32 0x100
+#define TCG_CT_CONST_U32 0x200
+
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_ESP
#define TCG_TARGET_STACK_ALIGN 16
#define TCG_TARGET_CALL_STACK_OFFSET 0
+/* optional instructions */
+#define TCG_TARGET_HAS_div2_i32
+#define TCG_TARGET_HAS_rot_i32
+#define TCG_TARGET_HAS_ext8s_i32
+#define TCG_TARGET_HAS_ext16s_i32
+#define TCG_TARGET_HAS_ext8u_i32
+#define TCG_TARGET_HAS_ext16u_i32
+#define TCG_TARGET_HAS_bswap16_i32
+#define TCG_TARGET_HAS_bswap32_i32
+#define TCG_TARGET_HAS_neg_i32
+#define TCG_TARGET_HAS_not_i32
+// #define TCG_TARGET_HAS_andc_i32
+// #define TCG_TARGET_HAS_orc_i32
+// #define TCG_TARGET_HAS_eqv_i32
+// #define TCG_TARGET_HAS_nand_i32
+// #define TCG_TARGET_HAS_nor_i32
+
+#if TCG_TARGET_REG_BITS == 64
+#define TCG_TARGET_HAS_div2_i64
+#define TCG_TARGET_HAS_rot_i64
+#define TCG_TARGET_HAS_ext8s_i64
+#define TCG_TARGET_HAS_ext16s_i64
+#define TCG_TARGET_HAS_ext32s_i64
+#define TCG_TARGET_HAS_ext8u_i64
+#define TCG_TARGET_HAS_ext16u_i64
+#define TCG_TARGET_HAS_ext32u_i64
+#define TCG_TARGET_HAS_bswap16_i64
+#define TCG_TARGET_HAS_bswap32_i64
+#define TCG_TARGET_HAS_bswap64_i64
+#define TCG_TARGET_HAS_neg_i64
+#define TCG_TARGET_HAS_not_i64
+// #define TCG_TARGET_HAS_andc_i64
+// #define TCG_TARGET_HAS_orc_i64
+// #define TCG_TARGET_HAS_eqv_i64
+// #define TCG_TARGET_HAS_nand_i64
+// #define TCG_TARGET_HAS_nor_i64
+#endif
+
+#define TCG_TARGET_HAS_GUEST_BASE
+
/* Note: must be synced with dyngen-exec.h */
-#ifndef VBOX
-#define TCG_AREG0 TCG_REG_EBP
-#define TCG_AREG1 TCG_REG_EBX
-#define TCG_AREG2 TCG_REG_ESI
-#define TCG_AREG3 TCG_REG_EDI
+#if TCG_TARGET_REG_BITS == 64
+# define TCG_AREG0 TCG_REG_R14
#else
-#define TCG_AREG0 TCG_REG_ESI
-#define TCG_AREG1 TCG_REG_EDI
+# ifndef VBOX /* we're using ESI instead of EBP, probably due to frame pointer opt issues */
+# define TCG_AREG0 TCG_REG_EBP
+# else /* VBOX */
+# define TCG_AREG0 TCG_REG_ESI
+# endif /* VBOX */
#endif
-#ifndef VBOX
static inline void flush_icache_range(unsigned long start, unsigned long stop)
-#else
-DECLINLINE(void) flush_icache_range(unsigned long start, unsigned long stop)
-#endif
{
}
diff --git a/src/recompiler/tcg/tcg-dyngen.c b/src/recompiler/tcg/tcg-dyngen.c
index 3544ea448..db6749984 100644
--- a/src/recompiler/tcg/tcg-dyngen.c
+++ b/src/recompiler/tcg/tcg-dyngen.c
@@ -30,8 +30,8 @@
#include <string.h>
#include <inttypes.h>
#else
-#include <stdio.h>
-#include "osdep.h"
+# include <stdio.h>
+# include "osdep.h"
#endif
#include "config.h"
diff --git a/src/recompiler/tcg/tcg-op.h b/src/recompiler/tcg/tcg-op.h
index 0f233538a..b38908040 100644
--- a/src/recompiler/tcg/tcg-op.h
+++ b/src/recompiler/tcg/tcg-op.h
@@ -21,549 +21,480 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-
#include "tcg.h"
-#ifdef CONFIG_DYNGEN_OP
-/* legacy dyngen operations */
-#include "gen-op.h"
-#endif
-
int gen_new_label(void);
-#ifndef VBOX
-static inline void tcg_gen_op1(int opc, TCGv arg1)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op1(int opc, TCGv arg1)
-#endif /* VBOX */
+static inline void tcg_gen_op1_i32(TCGOpcode opc, TCGv_i32 arg1)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+}
+
+static inline void tcg_gen_op1_i64(TCGOpcode opc, TCGv_i64 arg1)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
}
-#ifndef VBOX
-static inline void tcg_gen_op1i(int opc, TCGArg arg1)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op1i(int opc, TCGArg arg1)
-#endif /* VBOX */
+static inline void tcg_gen_op1i(TCGOpcode opc, TCGArg arg1)
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg1;
}
-#ifndef VBOX
-static inline void tcg_gen_op2(int opc, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op2(int opc, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_op2_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_op2i(int opc, TCGv arg1, TCGArg arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op2i(int opc, TCGv arg1, TCGArg arg2)
-#endif /* VBOX */
+static inline void tcg_gen_op2_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+}
+
+static inline void tcg_gen_op2i_i32(TCGOpcode opc, TCGv_i32 arg1, TCGArg arg2)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
*gen_opparam_ptr++ = arg2;
}
-#ifndef VBOX
-static inline void tcg_gen_op2ii(int opc, TCGArg arg1, TCGArg arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op2ii(int opc, TCGArg arg1, TCGArg arg2)
-#endif /* VBOX */
+static inline void tcg_gen_op2i_i64(TCGOpcode opc, TCGv_i64 arg1, TCGArg arg2)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *gen_opparam_ptr++ = arg2;
+}
+
+static inline void tcg_gen_op2ii(TCGOpcode opc, TCGArg arg1, TCGArg arg2)
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg1;
*gen_opparam_ptr++ = arg2;
}
-#ifndef VBOX
-static inline void tcg_gen_op3(int opc, TCGv arg1, TCGv arg2, TCGv arg3)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op3(int opc, TCGv arg1, TCGv arg2, TCGv arg3)
-#endif /* VBOX */
+static inline void tcg_gen_op3_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
+ TCGv_i32 arg3)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+}
+
+static inline void tcg_gen_op3_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
+ TCGv_i64 arg3)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+}
+
+static inline void tcg_gen_op3i_i32(TCGOpcode opc, TCGv_i32 arg1,
+ TCGv_i32 arg2, TCGArg arg3)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *gen_opparam_ptr++ = arg3;
}
-#ifndef VBOX
-static inline void tcg_gen_op3i(int opc, TCGv arg1, TCGv arg2, TCGArg arg3)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op3i(int opc, TCGv arg1, TCGv arg2, TCGArg arg3)
-#endif /* VBOX */
+static inline void tcg_gen_op3i_i64(TCGOpcode opc, TCGv_i64 arg1,
+ TCGv_i64 arg2, TCGArg arg3)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
*gen_opparam_ptr++ = arg3;
}
-#ifndef VBOX
-static inline void tcg_gen_op4(int opc, TCGv arg1, TCGv arg2, TCGv arg3,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op4(int opc, TCGv arg1, TCGv arg2, TCGv arg3,
-#endif /* VBOX */
- TCGv arg4)
+static inline void tcg_gen_ldst_op_i32(TCGOpcode opc, TCGv_i32 val,
+ TCGv_ptr base, TCGArg offset)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I32(val);
+ *gen_opparam_ptr++ = GET_TCGV_PTR(base);
+ *gen_opparam_ptr++ = offset;
+}
+
+static inline void tcg_gen_ldst_op_i64(TCGOpcode opc, TCGv_i64 val,
+ TCGv_ptr base, TCGArg offset)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I64(val);
+ *gen_opparam_ptr++ = GET_TCGV_PTR(base);
+ *gen_opparam_ptr++ = offset;
+}
+
+static inline void tcg_gen_qemu_ldst_op_i64_i32(TCGOpcode opc, TCGv_i64 val,
+ TCGv_i32 addr, TCGArg mem_index)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I64(val);
+ *gen_opparam_ptr++ = GET_TCGV_I32(addr);
+ *gen_opparam_ptr++ = mem_index;
+}
+
+static inline void tcg_gen_qemu_ldst_op_i64_i64(TCGOpcode opc, TCGv_i64 val,
+ TCGv_i64 addr, TCGArg mem_index)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I64(val);
+ *gen_opparam_ptr++ = GET_TCGV_I64(addr);
+ *gen_opparam_ptr++ = mem_index;
+}
+
+static inline void tcg_gen_op4_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
+ TCGv_i32 arg3, TCGv_i32 arg4)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg4);
+}
+
+static inline void tcg_gen_op4_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
+ TCGv_i64 arg3, TCGv_i64 arg4)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg4);
+}
+
+static inline void tcg_gen_op4i_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
+ TCGv_i32 arg3, TCGArg arg4)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
- *gen_opparam_ptr++ = GET_TCGV(arg4);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *gen_opparam_ptr++ = arg4;
}
-#ifndef VBOX
-static inline void tcg_gen_op4i(int opc, TCGv arg1, TCGv arg2, TCGv arg3,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op4i(int opc, TCGv arg1, TCGv arg2, TCGv arg3,
-#endif /* VBOX */
- TCGArg arg4)
+static inline void tcg_gen_op4i_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
+ TCGv_i64 arg3, TCGArg arg4)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *gen_opparam_ptr++ = arg4;
+}
+
+static inline void tcg_gen_op4ii_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
+ TCGArg arg3, TCGArg arg4)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *gen_opparam_ptr++ = arg3;
*gen_opparam_ptr++ = arg4;
}
-#ifndef VBOX
-static inline void tcg_gen_op4ii(int opc, TCGv arg1, TCGv arg2, TCGArg arg3,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op4ii(int opc, TCGv arg1, TCGv arg2, TCGArg arg3,
-#endif /* VBOX */
- TCGArg arg4)
+static inline void tcg_gen_op4ii_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
+ TCGArg arg3, TCGArg arg4)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
*gen_opparam_ptr++ = arg3;
*gen_opparam_ptr++ = arg4;
}
-#ifndef VBOX
-static inline void tcg_gen_op5(int opc, TCGv arg1, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op5(int opc, TCGv arg1, TCGv arg2,
-#endif /* VBOX */
- TCGv arg3, TCGv arg4,
- TCGv arg5)
+static inline void tcg_gen_op5_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
+ TCGv_i32 arg3, TCGv_i32 arg4, TCGv_i32 arg5)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
- *gen_opparam_ptr++ = GET_TCGV(arg4);
- *gen_opparam_ptr++ = GET_TCGV(arg5);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg4);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg5);
}
-#ifndef VBOX
-static inline void tcg_gen_op5i(int opc, TCGv arg1, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op5i(int opc, TCGv arg1, TCGv arg2,
-#endif /* VBOX */
- TCGv arg3, TCGv arg4,
- TCGArg arg5)
+static inline void tcg_gen_op5_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
+ TCGv_i64 arg3, TCGv_i64 arg4, TCGv_i64 arg5)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
- *gen_opparam_ptr++ = GET_TCGV(arg4);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg4);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg5);
+}
+
+static inline void tcg_gen_op5i_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
+ TCGv_i32 arg3, TCGv_i32 arg4, TCGArg arg5)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg4);
*gen_opparam_ptr++ = arg5;
}
-#ifndef VBOX
-static inline void tcg_gen_op6(int opc, TCGv arg1, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op6(int opc, TCGv arg1, TCGv arg2,
-#endif /* VBOX */
- TCGv arg3, TCGv arg4,
- TCGv arg5, TCGv arg6)
+static inline void tcg_gen_op5i_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
+ TCGv_i64 arg3, TCGv_i64 arg4, TCGArg arg5)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
- *gen_opparam_ptr++ = GET_TCGV(arg4);
- *gen_opparam_ptr++ = GET_TCGV(arg5);
- *gen_opparam_ptr++ = GET_TCGV(arg6);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_op6ii(int opc, TCGv arg1, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_op6ii(int opc, TCGv arg1, TCGv arg2,
-#endif /* VBOX */
- TCGv arg3, TCGv arg4,
- TCGArg arg5, TCGArg arg6)
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg4);
+ *gen_opparam_ptr++ = arg5;
+}
+
+static inline void tcg_gen_op6_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
+ TCGv_i32 arg3, TCGv_i32 arg4, TCGv_i32 arg5,
+ TCGv_i32 arg6)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg4);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg5);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg6);
+}
+
+static inline void tcg_gen_op6_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
+ TCGv_i64 arg3, TCGv_i64 arg4, TCGv_i64 arg5,
+ TCGv_i64 arg6)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg4);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg5);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg6);
+}
+
+static inline void tcg_gen_op6i_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
+ TCGv_i32 arg3, TCGv_i32 arg4,
+ TCGv_i32 arg5, TCGArg arg6)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
- *gen_opparam_ptr++ = GET_TCGV(arg4);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg4);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg5);
+ *gen_opparam_ptr++ = arg6;
+}
+
+static inline void tcg_gen_op6i_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
+ TCGv_i64 arg3, TCGv_i64 arg4,
+ TCGv_i64 arg5, TCGArg arg6)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg4);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg5);
+ *gen_opparam_ptr++ = arg6;
+}
+
+static inline void tcg_gen_op6ii_i32(TCGOpcode opc, TCGv_i32 arg1,
+ TCGv_i32 arg2, TCGv_i32 arg3,
+ TCGv_i32 arg4, TCGArg arg5, TCGArg arg6)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I32(arg4);
+ *gen_opparam_ptr++ = arg5;
+ *gen_opparam_ptr++ = arg6;
+}
+
+static inline void tcg_gen_op6ii_i64(TCGOpcode opc, TCGv_i64 arg1,
+ TCGv_i64 arg2, TCGv_i64 arg3,
+ TCGv_i64 arg4, TCGArg arg5, TCGArg arg6)
+{
+ *gen_opc_ptr++ = opc;
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *gen_opparam_ptr++ = GET_TCGV_I64(arg4);
*gen_opparam_ptr++ = arg5;
*gen_opparam_ptr++ = arg6;
}
-#ifndef VBOX
static inline void gen_set_label(int n)
-#else /* VBOX */
-DECLINLINE(void) gen_set_label(int n)
-#endif /* VBOX */
{
tcg_gen_op1i(INDEX_op_set_label, n);
}
-#ifndef VBOX
static inline void tcg_gen_br(int label)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_br(int label)
-#endif /* VBOX */
{
tcg_gen_op1i(INDEX_op_br, label);
}
-#ifndef VBOX
-static inline void tcg_gen_mov_i32(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_mov_i32(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg)
+{
+ if (!TCGV_EQUAL_I32(ret, arg))
+ tcg_gen_op2_i32(INDEX_op_mov_i32, ret, arg);
+}
+
+static inline void tcg_gen_movi_i32(TCGv_i32 ret, int32_t arg)
{
- if (GET_TCGV(ret) != GET_TCGV(arg))
- tcg_gen_op2(INDEX_op_mov_i32, ret, arg);
+ tcg_gen_op2i_i32(INDEX_op_movi_i32, ret, arg);
}
-#ifndef VBOX
-static inline void tcg_gen_movi_i32(TCGv ret, int32_t arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_movi_i32(TCGv ret, int32_t arg)
-#endif /* VBOX */
+/* A version of dh_sizemask from def-helper.h that doesn't rely on
+ preprocessor magic. */
+static inline int tcg_gen_sizemask(int n, int is_64bit, int is_signed)
{
- tcg_gen_op2i(INDEX_op_movi_i32, ret, arg);
+ return (is_64bit << n*2) | (is_signed << (n*2 + 1));
}
/* helper calls */
-#define TCG_HELPER_CALL_FLAGS 0
-
-#ifndef VBOX
-static inline void tcg_gen_helper_0_0(void *func)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_helper_0_0(void *func)
-#endif /* VBOX */
-{
- TCGv t0;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 0, NULL, 0, NULL);
- tcg_temp_free(t0);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_helper_0_1(void *func, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_helper_0_1(void *func, TCGv arg)
-#endif /* VBOX */
-{
- TCGv t0;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 0, NULL, 1, &arg);
- tcg_temp_free(t0);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_helper_0_2(void *func, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_helper_0_2(void *func, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
-{
- TCGv args[2];
- TCGv t0;
- args[0] = arg1;
- args[1] = arg2;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 0, NULL, 2, args);
- tcg_temp_free(t0);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_helper_0_3(void *func,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_helper_0_3(void *func,
-#endif /* VBOX */
- TCGv arg1, TCGv arg2, TCGv arg3)
-{
- TCGv args[3];
- TCGv t0;
- args[0] = arg1;
- args[1] = arg2;
- args[2] = arg3;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 0, NULL, 3, args);
- tcg_temp_free(t0);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_helper_0_4(void *func, TCGv arg1, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_helper_0_4(void *func, TCGv arg1, TCGv arg2,
-#endif /* VBOX */
- TCGv arg3, TCGv arg4)
-{
- TCGv args[4];
- TCGv t0;
- args[0] = arg1;
- args[1] = arg2;
- args[2] = arg3;
- args[3] = arg4;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 0, NULL, 4, args);
- tcg_temp_free(t0);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_helper_1_0(void *func, TCGv ret)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_helper_1_0(void *func, TCGv ret)
-#endif /* VBOX */
-{
- TCGv t0;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 1, &ret, 0, NULL);
- tcg_temp_free(t0);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_helper_1_1(void *func, TCGv ret, TCGv arg1)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_helper_1_1(void *func, TCGv ret, TCGv arg1)
-#endif /* VBOX */
-{
- TCGv t0;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 1, &ret, 1, &arg1);
- tcg_temp_free(t0);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_helper_1_2(void *func, TCGv ret,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_helper_1_2(void *func, TCGv ret,
-#endif /* VBOX */
- TCGv arg1, TCGv arg2)
-{
- TCGv args[2];
- TCGv t0;
- args[0] = arg1;
- args[1] = arg2;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 1, &ret, 2, args);
- tcg_temp_free(t0);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_helper_1_3(void *func, TCGv ret,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_helper_1_3(void *func, TCGv ret,
-#endif /* VBOX */
- TCGv arg1, TCGv arg2, TCGv arg3)
-{
- TCGv args[3];
- TCGv t0;
- args[0] = arg1;
- args[1] = arg2;
- args[2] = arg3;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 1, &ret, 3, args);
- tcg_temp_free(t0);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_helper_1_4(void *func, TCGv ret,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_helper_1_4(void *func, TCGv ret,
-#endif /* VBOX */
- TCGv arg1, TCGv arg2, TCGv arg3,
- TCGv arg4)
-{
- TCGv args[4];
- TCGv t0;
- args[0] = arg1;
- args[1] = arg2;
- args[2] = arg3;
- args[3] = arg4;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 1, &ret, 4, args);
- tcg_temp_free(t0);
+static inline void tcg_gen_helperN(void *func, int flags, int sizemask,
+ TCGArg ret, int nargs, TCGArg *args)
+{
+ TCGv_ptr fn;
+ fn = tcg_const_ptr((tcg_target_long)func);
+ tcg_gen_callN(&tcg_ctx, fn, flags, sizemask, ret,
+ nargs, args);
+ tcg_temp_free_ptr(fn);
+}
+
+/* Note: Both tcg_gen_helper32() and tcg_gen_helper64() are currently
+ reserved for helpers in tcg-runtime.c. These helpers are all const
+ and pure, hence the call to tcg_gen_callN() with TCG_CALL_CONST |
+ TCG_CALL_PURE. This may need to be adjusted if these functions
+ start to be used with other helpers. */
+static inline void tcg_gen_helper32(void *func, int sizemask, TCGv_i32 ret,
+ TCGv_i32 a, TCGv_i32 b)
+{
+ TCGv_ptr fn;
+ TCGArg args[2];
+ fn = tcg_const_ptr((tcg_target_long)func);
+ args[0] = GET_TCGV_I32(a);
+ args[1] = GET_TCGV_I32(b);
+ tcg_gen_callN(&tcg_ctx, fn, TCG_CALL_CONST | TCG_CALL_PURE, sizemask,
+ GET_TCGV_I32(ret), 2, args);
+ tcg_temp_free_ptr(fn);
+}
+
+static inline void tcg_gen_helper64(void *func, int sizemask, TCGv_i64 ret,
+ TCGv_i64 a, TCGv_i64 b)
+{
+ TCGv_ptr fn;
+ TCGArg args[2];
+ fn = tcg_const_ptr((tcg_target_long)func);
+ args[0] = GET_TCGV_I64(a);
+ args[1] = GET_TCGV_I64(b);
+ tcg_gen_callN(&tcg_ctx, fn, TCG_CALL_CONST | TCG_CALL_PURE, sizemask,
+ GET_TCGV_I64(ret), 2, args);
+ tcg_temp_free_ptr(fn);
}
/* 32 bit ops */
-#ifndef VBOX
-static inline void tcg_gen_ld8u_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld8u_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld8u_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_ld8u_i32, ret, arg2, offset);
+ tcg_gen_ldst_op_i32(INDEX_op_ld8u_i32, ret, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_ld8s_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld8s_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld8s_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_ld8s_i32, ret, arg2, offset);
+ tcg_gen_ldst_op_i32(INDEX_op_ld8s_i32, ret, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_ld16u_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld16u_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld16u_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_ld16u_i32, ret, arg2, offset);
+ tcg_gen_ldst_op_i32(INDEX_op_ld16u_i32, ret, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_ld16s_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld16s_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld16s_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_ld16s_i32, ret, arg2, offset);
+ tcg_gen_ldst_op_i32(INDEX_op_ld16s_i32, ret, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_ld_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_ld_i32, ret, arg2, offset);
+ tcg_gen_ldst_op_i32(INDEX_op_ld_i32, ret, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_st8_i32(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_st8_i32(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_st8_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_st8_i32, arg1, arg2, offset);
+ tcg_gen_ldst_op_i32(INDEX_op_st8_i32, arg1, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_st16_i32(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_st16_i32(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_st16_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_st16_i32, arg1, arg2, offset);
+ tcg_gen_ldst_op_i32(INDEX_op_st16_i32, arg1, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_st_i32(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_st_i32(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_st_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_st_i32, arg1, arg2, offset);
+ tcg_gen_ldst_op_i32(INDEX_op_st_i32, arg1, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_add_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_add_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_add_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- tcg_gen_op3(INDEX_op_add_i32, ret, arg1, arg2);
+ tcg_gen_op3_i32(INDEX_op_add_i32, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_addi_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_addi_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
{
/* some cases can be optimized here */
if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- TCGv t0 = tcg_const_i32(arg2);
+ TCGv_i32 t0 = tcg_const_i32(arg2);
tcg_gen_add_i32(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
}
}
-#ifndef VBOX
-static inline void tcg_gen_sub_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_sub_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_sub_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+ tcg_gen_op3_i32(INDEX_op_sub_i32, ret, arg1, arg2);
+}
+
+static inline void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2)
{
- tcg_gen_op3(INDEX_op_sub_i32, ret, arg1, arg2);
+ TCGv_i32 t0 = tcg_const_i32(arg1);
+ tcg_gen_sub_i32(ret, t0, arg2);
+ tcg_temp_free_i32(t0);
}
-#ifndef VBOX
-static inline void tcg_gen_subi_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_subi_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
{
/* some cases can be optimized here */
if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- TCGv t0 = tcg_const_i32(arg2);
+ TCGv_i32 t0 = tcg_const_i32(arg2);
tcg_gen_sub_i32(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
}
}
-#ifndef VBOX
-static inline void tcg_gen_and_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_and_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_and_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- tcg_gen_op3(INDEX_op_and_i32, ret, arg1, arg2);
+ if (TCGV_EQUAL_I32(arg1, arg2)) {
+ tcg_gen_mov_i32(ret, arg1);
+ } else {
+ tcg_gen_op3_i32(INDEX_op_and_i32, ret, arg1, arg2);
+ }
}
-#ifndef VBOX
-static inline void tcg_gen_andi_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_andi_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
{
/* some cases can be optimized here */
if (arg2 == 0) {
@@ -571,26 +502,22 @@ DECLINLINE(void) tcg_gen_andi_i32(TCGv ret, TCGv arg1, int32_t arg2)
} else if (arg2 == 0xffffffff) {
tcg_gen_mov_i32(ret, arg1);
} else {
- TCGv t0 = tcg_const_i32(arg2);
+ TCGv_i32 t0 = tcg_const_i32(arg2);
tcg_gen_and_i32(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
}
}
-#ifndef VBOX
-static inline void tcg_gen_or_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_or_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_or_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- tcg_gen_op3(INDEX_op_or_i32, ret, arg1, arg2);
+ if (TCGV_EQUAL_I32(arg1, arg2)) {
+ tcg_gen_mov_i32(ret, arg1);
+ } else {
+ tcg_gen_op3_i32(INDEX_op_or_i32, ret, arg1, arg2);
+ }
}
-#ifndef VBOX
-static inline void tcg_gen_ori_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ori_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
{
/* some cases can be optimized here */
if (arg2 == 0xffffffff) {
@@ -598,1145 +525,930 @@ DECLINLINE(void) tcg_gen_ori_i32(TCGv ret, TCGv arg1, int32_t arg2)
} else if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- TCGv t0 = tcg_const_i32(arg2);
+ TCGv_i32 t0 = tcg_const_i32(arg2);
tcg_gen_or_i32(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
}
}
-#ifndef VBOX
-static inline void tcg_gen_xor_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_xor_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_xor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- tcg_gen_op3(INDEX_op_xor_i32, ret, arg1, arg2);
+ if (TCGV_EQUAL_I32(arg1, arg2)) {
+ tcg_gen_movi_i32(ret, 0);
+ } else {
+ tcg_gen_op3_i32(INDEX_op_xor_i32, ret, arg1, arg2);
+ }
}
-#ifndef VBOX
-static inline void tcg_gen_xori_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_xori_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
{
/* some cases can be optimized here */
if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- TCGv t0 = tcg_const_i32(arg2);
+ TCGv_i32 t0 = tcg_const_i32(arg2);
tcg_gen_xor_i32(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
}
}
-#ifndef VBOX
-static inline void tcg_gen_shl_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_shl_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_shl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- tcg_gen_op3(INDEX_op_shl_i32, ret, arg1, arg2);
+ tcg_gen_op3_i32(INDEX_op_shl_i32, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_shli_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_shli_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
{
if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- TCGv t0 = tcg_const_i32(arg2);
+ TCGv_i32 t0 = tcg_const_i32(arg2);
tcg_gen_shl_i32(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
}
}
-#ifndef VBOX
-static inline void tcg_gen_shr_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_shr_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_shr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- tcg_gen_op3(INDEX_op_shr_i32, ret, arg1, arg2);
+ tcg_gen_op3_i32(INDEX_op_shr_i32, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_shri_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_shri_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
{
if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- TCGv t0 = tcg_const_i32(arg2);
+ TCGv_i32 t0 = tcg_const_i32(arg2);
tcg_gen_shr_i32(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
}
}
-#ifndef VBOX
-static inline void tcg_gen_sar_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_sar_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_sar_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- tcg_gen_op3(INDEX_op_sar_i32, ret, arg1, arg2);
+ tcg_gen_op3_i32(INDEX_op_sar_i32, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_sari_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_sari_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
{
if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- TCGv t0 = tcg_const_i32(arg2);
+ TCGv_i32 t0 = tcg_const_i32(arg2);
tcg_gen_sar_i32(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
}
}
-#ifndef VBOX
-static inline void tcg_gen_brcond_i32(int cond, TCGv arg1, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_brcond_i32(int cond, TCGv arg1, TCGv arg2,
-#endif /* VBOX */
- int label_index)
+static inline void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1,
+ TCGv_i32 arg2, int label_index)
{
- tcg_gen_op4ii(INDEX_op_brcond_i32, arg1, arg2, cond, label_index);
+ tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_index);
}
-#ifndef VBOX
-static inline void tcg_gen_brcondi_i32(int cond, TCGv arg1, int32_t arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_brcondi_i32(int cond, TCGv arg1, int32_t arg2,
-#endif /* VBOX */
- int label_index)
+static inline void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1,
+ int32_t arg2, int label_index)
{
- TCGv t0 = tcg_const_i32(arg2);
+ TCGv_i32 t0 = tcg_const_i32(arg2);
tcg_gen_brcond_i32(cond, arg1, t0, label_index);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
+}
+
+static inline void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
+ TCGv_i32 arg1, TCGv_i32 arg2)
+{
+ tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond);
}
-#ifndef VBOX
-static inline void tcg_gen_mul_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_mul_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
+ TCGv_i32 arg1, int32_t arg2)
{
- tcg_gen_op3(INDEX_op_mul_i32, ret, arg1, arg2);
+ TCGv_i32 t0 = tcg_const_i32(arg2);
+ tcg_gen_setcond_i32(cond, ret, arg1, t0);
+ tcg_temp_free_i32(t0);
}
-#ifndef VBOX
-static inline void tcg_gen_muli_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_muli_i32(TCGv ret, TCGv arg1, int32_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_mul_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- TCGv t0 = tcg_const_i32(arg2);
+ tcg_gen_op3_i32(INDEX_op_mul_i32, ret, arg1, arg2);
+}
+
+static inline void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
+{
+ TCGv_i32 t0 = tcg_const_i32(arg2);
tcg_gen_mul_i32(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
}
#ifdef TCG_TARGET_HAS_div_i32
-#ifndef VBOX
-static inline void tcg_gen_div_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_div_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- tcg_gen_op3(INDEX_op_div_i32, ret, arg1, arg2);
+ tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_rem_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_rem_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- tcg_gen_op3(INDEX_op_rem_i32, ret, arg1, arg2);
+ tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_divu_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_divu_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- tcg_gen_op3(INDEX_op_divu_i32, ret, arg1, arg2);
+ tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_remu_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_remu_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- tcg_gen_op3(INDEX_op_remu_i32, ret, arg1, arg2);
+ tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
}
-#else
-#ifndef VBOX
-static inline void tcg_gen_div_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_div_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
-{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I32);
+#elif defined(TCG_TARGET_HAS_div2_i32)
+static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+ TCGv_i32 t0;
+ t0 = tcg_temp_new_i32();
tcg_gen_sari_i32(t0, arg1, 31);
- tcg_gen_op5(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
- tcg_temp_free(t0);
+ tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
+ tcg_temp_free_i32(t0);
}
-#ifndef VBOX
-static inline void tcg_gen_rem_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_rem_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 t0;
+ t0 = tcg_temp_new_i32();
tcg_gen_sari_i32(t0, arg1, 31);
- tcg_gen_op5(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
- tcg_temp_free(t0);
+ tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
+ tcg_temp_free_i32(t0);
}
-#ifndef VBOX
-static inline void tcg_gen_divu_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_divu_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 t0;
+ t0 = tcg_temp_new_i32();
tcg_gen_movi_i32(t0, 0);
- tcg_gen_op5(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
- tcg_temp_free(t0);
+ tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
+ tcg_temp_free_i32(t0);
}
-#ifndef VBOX
-static inline void tcg_gen_remu_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_remu_i32(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 t0;
+ t0 = tcg_temp_new_i32();
tcg_gen_movi_i32(t0, 0);
- tcg_gen_op5(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
- tcg_temp_free(t0);
+ tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
+ tcg_temp_free_i32(t0);
+}
+#else
+static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+ int sizemask = 0;
+ /* Return value and both arguments are 32-bit and signed. */
+ sizemask |= tcg_gen_sizemask(0, 0, 1);
+ sizemask |= tcg_gen_sizemask(1, 0, 1);
+ sizemask |= tcg_gen_sizemask(2, 0, 1);
+
+ tcg_gen_helper32(tcg_helper_div_i32, sizemask, ret, arg1, arg2);
+}
+
+static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+ int sizemask = 0;
+ /* Return value and both arguments are 32-bit and signed. */
+ sizemask |= tcg_gen_sizemask(0, 0, 1);
+ sizemask |= tcg_gen_sizemask(1, 0, 1);
+ sizemask |= tcg_gen_sizemask(2, 0, 1);
+
+ tcg_gen_helper32(tcg_helper_rem_i32, sizemask, ret, arg1, arg2);
+}
+
+static inline void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+ int sizemask = 0;
+ /* Return value and both arguments are 32-bit and unsigned. */
+ sizemask |= tcg_gen_sizemask(0, 0, 0);
+ sizemask |= tcg_gen_sizemask(1, 0, 0);
+ sizemask |= tcg_gen_sizemask(2, 0, 0);
+
+ tcg_gen_helper32(tcg_helper_divu_i32, ret, arg1, arg2, 0);
+}
+
+static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+ int sizemask = 0;
+ /* Return value and both arguments are 32-bit and unsigned. */
+ sizemask |= tcg_gen_sizemask(0, 0, 0);
+ sizemask |= tcg_gen_sizemask(1, 0, 0);
+ sizemask |= tcg_gen_sizemask(2, 0, 0);
+
+ tcg_gen_helper32(tcg_helper_remu_i32, ret, arg1, arg2, 0);
}
#endif
#if TCG_TARGET_REG_BITS == 32
-#ifndef VBOX
-static inline void tcg_gen_mov_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_mov_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
{
- if (GET_TCGV(ret) != GET_TCGV(arg)) {
- tcg_gen_mov_i32(ret, arg);
+ if (!TCGV_EQUAL_I64(ret, arg)) {
+ tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
}
}
-#ifndef VBOX
-static inline void tcg_gen_movi_i64(TCGv ret, int64_t arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_movi_i64(TCGv ret, int64_t arg)
-#endif /* VBOX */
+static inline void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
{
- tcg_gen_movi_i32(ret, arg);
+ tcg_gen_movi_i32(TCGV_LOW(ret), arg);
tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32);
}
-#ifndef VBOX
-static inline void tcg_gen_ld8u_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld8u_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2,
+ tcg_target_long offset)
{
- tcg_gen_ld8u_i32(ret, arg2, offset);
+ tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset);
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
}
-#ifndef VBOX
-static inline void tcg_gen_ld8s_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld8s_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2,
+ tcg_target_long offset)
{
- tcg_gen_ld8s_i32(ret, arg2, offset);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
+ tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset);
+ tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), 31);
}
-#ifndef VBOX
-static inline void tcg_gen_ld16u_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld16u_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2,
+ tcg_target_long offset)
{
- tcg_gen_ld16u_i32(ret, arg2, offset);
+ tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset);
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
}
-#ifndef VBOX
-static inline void tcg_gen_ld16s_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld16s_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2,
+ tcg_target_long offset)
{
- tcg_gen_ld16s_i32(ret, arg2, offset);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
+ tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset);
+ tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
}
-#ifndef VBOX
-static inline void tcg_gen_ld32u_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld32u_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2,
+ tcg_target_long offset)
{
- tcg_gen_ld_i32(ret, arg2, offset);
+ tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
}
-#ifndef VBOX
-static inline void tcg_gen_ld32s_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld32s_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2,
+ tcg_target_long offset)
{
- tcg_gen_ld_i32(ret, arg2, offset);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
+ tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
+ tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
}
-#ifndef VBOX
-static inline void tcg_gen_ld_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2,
+ tcg_target_long offset)
{
/* since arg2 and ret have different types, they cannot be the
same temporary */
#ifdef TCG_TARGET_WORDS_BIGENDIAN
tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset);
- tcg_gen_ld_i32(ret, arg2, offset + 4);
+ tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4);
#else
- tcg_gen_ld_i32(ret, arg2, offset);
+ tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4);
#endif
}
-#ifndef VBOX
-static inline void tcg_gen_st8_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_st8_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2,
+ tcg_target_long offset)
{
- tcg_gen_st8_i32(arg1, arg2, offset);
+ tcg_gen_st8_i32(TCGV_LOW(arg1), arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_st16_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_st16_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2,
+ tcg_target_long offset)
{
- tcg_gen_st16_i32(arg1, arg2, offset);
+ tcg_gen_st16_i32(TCGV_LOW(arg1), arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_st32_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_st32_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2,
+ tcg_target_long offset)
{
- tcg_gen_st_i32(arg1, arg2, offset);
+ tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_st_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_st_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2,
+ tcg_target_long offset)
{
#ifdef TCG_TARGET_WORDS_BIGENDIAN
tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset);
- tcg_gen_st_i32(arg1, arg2, offset + 4);
+ tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4);
#else
- tcg_gen_st_i32(arg1, arg2, offset);
+ tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4);
#endif
}
-#ifndef VBOX
-static inline void tcg_gen_add_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_add_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op6(INDEX_op_add2_i32, ret, TCGV_HIGH(ret),
- arg1, TCGV_HIGH(arg1), arg2, TCGV_HIGH(arg2));
+ tcg_gen_op6_i32(INDEX_op_add2_i32, TCGV_LOW(ret), TCGV_HIGH(ret),
+ TCGV_LOW(arg1), TCGV_HIGH(arg1), TCGV_LOW(arg2),
+ TCGV_HIGH(arg2));
}
-#ifndef VBOX
-static inline void tcg_gen_addi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_addi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_add_i64(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_gen_op6_i32(INDEX_op_sub2_i32, TCGV_LOW(ret), TCGV_HIGH(ret),
+ TCGV_LOW(arg1), TCGV_HIGH(arg1), TCGV_LOW(arg2),
+ TCGV_HIGH(arg2));
}
-#ifndef VBOX
-static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op6(INDEX_op_sub2_i32, ret, TCGV_HIGH(ret),
- arg1, TCGV_HIGH(arg1), arg2, TCGV_HIGH(arg2));
-}
-
-#ifndef VBOX
-static inline void tcg_gen_subi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_subi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
-{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_sub_i64(ret, arg1, t0);
- tcg_temp_free(t0);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
-{
- tcg_gen_and_i32(ret, arg1, arg2);
+ tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
}
-#ifndef VBOX
-static inline void tcg_gen_andi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_andi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
{
- tcg_gen_andi_i32(ret, arg1, arg2);
+ tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
}
-#ifndef VBOX
-static inline void tcg_gen_or_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_or_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_or_i32(ret, arg1, arg2);
+ tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
}
-#ifndef VBOX
-static inline void tcg_gen_ori_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ori_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
{
- tcg_gen_ori_i32(ret, arg1, arg2);
+ tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
}
-#ifndef VBOX
-static inline void tcg_gen_xor_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_xor_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_xor_i32(ret, arg1, arg2);
+ tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
}
-#ifndef VBOX
-static inline void tcg_gen_xori_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_xori_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
{
- tcg_gen_xori_i32(ret, arg1, arg2);
+ tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
}
/* XXX: use generic code when basic block handling is OK or CPU
specific code (x86) */
-#ifndef VBOX
-static inline void tcg_gen_shl_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_shl_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_helper_1_2(tcg_helper_shl_i64, ret, arg1, arg2);
+ int sizemask = 0;
+ /* Return value and both arguments are 64-bit and signed. */
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
+
+ tcg_gen_helper64(tcg_helper_shl_i64, sizemask, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_shli_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_shli_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
{
tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0);
}
-#ifndef VBOX
-static inline void tcg_gen_shr_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_shr_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_helper_1_2(tcg_helper_shr_i64, ret, arg1, arg2);
+ int sizemask = 0;
+ /* Return value and both arguments are 64-bit and signed. */
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
+
+ tcg_gen_helper64(tcg_helper_shr_i64, sizemask, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_shri_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_shri_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
{
tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0);
}
-#ifndef VBOX
-static inline void tcg_gen_sar_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_sar_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_helper_1_2(tcg_helper_sar_i64, ret, arg1, arg2);
+ int sizemask = 0;
+ /* Return value and both arguments are 64-bit and signed. */
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
+
+ tcg_gen_helper64(tcg_helper_sar_i64, sizemask, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_sari_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_sari_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
{
tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1);
}
-#ifndef VBOX
-static inline void tcg_gen_brcond_i64(int cond, TCGv arg1, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_brcond_i64(int cond, TCGv arg1, TCGv arg2,
-#endif /* VBOX */
- int label_index)
+static inline void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1,
+ TCGv_i64 arg2, int label_index)
{
- tcg_gen_op6ii(INDEX_op_brcond2_i32,
- arg1, TCGV_HIGH(arg1), arg2, TCGV_HIGH(arg2),
- cond, label_index);
+ tcg_gen_op6ii_i32(INDEX_op_brcond2_i32,
+ TCGV_LOW(arg1), TCGV_HIGH(arg1), TCGV_LOW(arg2),
+ TCGV_HIGH(arg2), cond, label_index);
}
-#ifndef VBOX
-static inline void tcg_gen_mul_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_mul_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
+ TCGv_i64 arg1, TCGv_i64 arg2)
{
- TCGv t0, t1;
+ tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
+ TCGV_LOW(arg1), TCGV_HIGH(arg1),
+ TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
+ tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
+}
+
+static inline void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+ TCGv_i64 t0;
+ TCGv_i32 t1;
- t0 = tcg_temp_new(TCG_TYPE_I64);
- t1 = tcg_temp_new(TCG_TYPE_I32);
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i32();
- tcg_gen_op4(INDEX_op_mulu2_i32, t0, TCGV_HIGH(t0), arg1, arg2);
+ tcg_gen_op4_i32(INDEX_op_mulu2_i32, TCGV_LOW(t0), TCGV_HIGH(t0),
+ TCGV_LOW(arg1), TCGV_LOW(arg2));
- tcg_gen_mul_i32(t1, arg1, TCGV_HIGH(arg2));
+ tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2));
tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
- tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), arg2);
+ tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2));
tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
tcg_gen_mov_i64(ret, t0);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i32(t1);
}
-#ifndef VBOX
-static inline void tcg_gen_muli_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_muli_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_mul_i64(ret, arg1, t0);
- tcg_temp_free(t0);
-}
+ int sizemask = 0;
+ /* Return value and both arguments are 64-bit and signed. */
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
-#ifndef VBOX
-static inline void tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
-{
- tcg_gen_helper_1_2(tcg_helper_div_i64, ret, arg1, arg2);
+ tcg_gen_helper64(tcg_helper_div_i64, sizemask, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_helper_1_2(tcg_helper_rem_i64, ret, arg1, arg2);
+ int sizemask = 0;
+ /* Return value and both arguments are 64-bit and signed. */
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
+
+ tcg_gen_helper64(tcg_helper_rem_i64, sizemask, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_helper_1_2(tcg_helper_divu_i64, ret, arg1, arg2);
+ int sizemask = 0;
+ /* Return value and both arguments are 64-bit and unsigned. */
+ sizemask |= tcg_gen_sizemask(0, 1, 0);
+ sizemask |= tcg_gen_sizemask(1, 1, 0);
+ sizemask |= tcg_gen_sizemask(2, 1, 0);
+
+ tcg_gen_helper64(tcg_helper_divu_i64, sizemask, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_helper_1_2(tcg_helper_remu_i64, ret, arg1, arg2);
+ int sizemask = 0;
+ /* Return value and both arguments are 64-bit and unsigned. */
+ sizemask |= tcg_gen_sizemask(0, 1, 0);
+ sizemask |= tcg_gen_sizemask(1, 1, 0);
+ sizemask |= tcg_gen_sizemask(2, 1, 0);
+
+ tcg_gen_helper64(tcg_helper_remu_i64, sizemask, ret, arg1, arg2);
}
#else
-#ifndef VBOX
-static inline void tcg_gen_mov_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_mov_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
{
- if (GET_TCGV(ret) != GET_TCGV(arg))
- tcg_gen_op2(INDEX_op_mov_i64, ret, arg);
+ if (!TCGV_EQUAL_I64(ret, arg))
+ tcg_gen_op2_i64(INDEX_op_mov_i64, ret, arg);
}
-#ifndef VBOX
-static inline void tcg_gen_movi_i64(TCGv ret, int64_t arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_movi_i64(TCGv ret, int64_t arg)
-#endif /* VBOX */
+static inline void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
{
- tcg_gen_op2i(INDEX_op_movi_i64, ret, arg);
+ tcg_gen_op2i_i64(INDEX_op_movi_i64, ret, arg);
}
-#ifndef VBOX
-static inline void tcg_gen_ld8u_i64(TCGv ret, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld8u_i64(TCGv ret, TCGv arg2,
-#endif /* VBOX */
+static inline void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_i64 arg2,
tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_ld8u_i64, ret, arg2, offset);
+ tcg_gen_ldst_op_i64(INDEX_op_ld8u_i64, ret, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_ld8s_i64(TCGv ret, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld8s_i64(TCGv ret, TCGv arg2,
-#endif /* VBOX */
+static inline void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_i64 arg2,
tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_ld8s_i64, ret, arg2, offset);
+ tcg_gen_ldst_op_i64(INDEX_op_ld8s_i64, ret, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_ld16u_i64(TCGv ret, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld16u_i64(TCGv ret, TCGv arg2,
-#endif /* VBOX */
+static inline void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_i64 arg2,
tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_ld16u_i64, ret, arg2, offset);
+ tcg_gen_ldst_op_i64(INDEX_op_ld16u_i64, ret, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_ld16s_i64(TCGv ret, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld16s_i64(TCGv ret, TCGv arg2,
-#endif /* VBOX */
+static inline void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_i64 arg2,
tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_ld16s_i64, ret, arg2, offset);
+ tcg_gen_ldst_op_i64(INDEX_op_ld16s_i64, ret, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_ld32u_i64(TCGv ret, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld32u_i64(TCGv ret, TCGv arg2,
-#endif /* VBOX */
+static inline void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_i64 arg2,
tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_ld32u_i64, ret, arg2, offset);
+ tcg_gen_ldst_op_i64(INDEX_op_ld32u_i64, ret, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_ld32s_i64(TCGv ret, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld32s_i64(TCGv ret, TCGv arg2,
-#endif /* VBOX */
+static inline void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_i64 arg2,
tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_ld32s_i64, ret, arg2, offset);
+ tcg_gen_ldst_op_i64(INDEX_op_ld32s_i64, ret, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_ld_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ld_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
+static inline void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_i64 arg2, tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_ld_i64, ret, arg2, offset);
+ tcg_gen_ldst_op_i64(INDEX_op_ld_i64, ret, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_st8_i64(TCGv arg1, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_st8_i64(TCGv arg1, TCGv arg2,
-#endif /* VBOX */
+static inline void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_i64 arg2,
tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_st8_i64, arg1, arg2, offset);
+ tcg_gen_ldst_op_i64(INDEX_op_st8_i64, arg1, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_st16_i64(TCGv arg1, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_st16_i64(TCGv arg1, TCGv arg2,
-#endif /* VBOX */
+static inline void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_i64 arg2,
tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_st16_i64, arg1, arg2, offset);
+ tcg_gen_ldst_op_i64(INDEX_op_st16_i64, arg1, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_st32_i64(TCGv arg1, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_st32_i64(TCGv arg1, TCGv arg2,
-#endif /* VBOX */
+static inline void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_i64 arg2,
tcg_target_long offset)
{
- tcg_gen_op3i(INDEX_op_st32_i64, arg1, arg2, offset);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_st_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_st_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-#endif /* VBOX */
-{
- tcg_gen_op3i(INDEX_op_st_i64, arg1, arg2, offset);
+ tcg_gen_ldst_op_i64(INDEX_op_st32_i64, arg1, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_add_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_add_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_i64 arg2, tcg_target_long offset)
{
- tcg_gen_op3(INDEX_op_add_i64, ret, arg1, arg2);
+ tcg_gen_ldst_op_i64(INDEX_op_st_i64, arg1, arg2, offset);
}
-#ifndef VBOX
-static inline void tcg_gen_addi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_addi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_add_i64(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_gen_op3_i64(INDEX_op_add_i64, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op3(INDEX_op_sub_i64, ret, arg1, arg2);
+ tcg_gen_op3_i64(INDEX_op_sub_i64, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_subi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_subi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_sub_i64(ret, arg1, t0);
- tcg_temp_free(t0);
-}
-
-#ifndef VBOX
-static inline void tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
-{
- tcg_gen_op3(INDEX_op_and_i64, ret, arg1, arg2);
+ if (TCGV_EQUAL_I64(arg1, arg2)) {
+ tcg_gen_mov_i64(ret, arg1);
+ } else {
+ tcg_gen_op3_i64(INDEX_op_and_i64, ret, arg1, arg2);
+ }
}
-#ifndef VBOX
-static inline void tcg_gen_andi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_andi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
{
- TCGv t0 = tcg_const_i64(arg2);
+ TCGv_i64 t0 = tcg_const_i64(arg2);
tcg_gen_and_i64(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i64(t0);
}
-#ifndef VBOX
-static inline void tcg_gen_or_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_or_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op3(INDEX_op_or_i64, ret, arg1, arg2);
+ if (TCGV_EQUAL_I64(arg1, arg2)) {
+ tcg_gen_mov_i64(ret, arg1);
+ } else {
+ tcg_gen_op3_i64(INDEX_op_or_i64, ret, arg1, arg2);
+ }
}
-#ifndef VBOX
-static inline void tcg_gen_ori_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ori_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
{
- TCGv t0 = tcg_const_i64(arg2);
+ TCGv_i64 t0 = tcg_const_i64(arg2);
tcg_gen_or_i64(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i64(t0);
}
-#ifndef VBOX
-static inline void tcg_gen_xor_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_xor_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op3(INDEX_op_xor_i64, ret, arg1, arg2);
+ if (TCGV_EQUAL_I64(arg1, arg2)) {
+ tcg_gen_movi_i64(ret, 0);
+ } else {
+ tcg_gen_op3_i64(INDEX_op_xor_i64, ret, arg1, arg2);
+ }
}
-#ifndef VBOX
-static inline void tcg_gen_xori_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_xori_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
{
- TCGv t0 = tcg_const_i64(arg2);
+ TCGv_i64 t0 = tcg_const_i64(arg2);
tcg_gen_xor_i64(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i64(t0);
}
-#ifndef VBOX
-static inline void tcg_gen_shl_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_shl_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op3(INDEX_op_shl_i64, ret, arg1, arg2);
+ tcg_gen_op3_i64(INDEX_op_shl_i64, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_shli_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_shli_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
{
if (arg2 == 0) {
tcg_gen_mov_i64(ret, arg1);
} else {
- TCGv t0 = tcg_const_i64(arg2);
+ TCGv_i64 t0 = tcg_const_i64(arg2);
tcg_gen_shl_i64(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i64(t0);
}
}
-#ifndef VBOX
-static inline void tcg_gen_shr_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_shr_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op3(INDEX_op_shr_i64, ret, arg1, arg2);
+ tcg_gen_op3_i64(INDEX_op_shr_i64, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_shri_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_shri_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
{
if (arg2 == 0) {
tcg_gen_mov_i64(ret, arg1);
} else {
- TCGv t0 = tcg_const_i64(arg2);
+ TCGv_i64 t0 = tcg_const_i64(arg2);
tcg_gen_shr_i64(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i64(t0);
}
}
-#ifndef VBOX
-static inline void tcg_gen_sar_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_sar_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op3(INDEX_op_sar_i64, ret, arg1, arg2);
+ tcg_gen_op3_i64(INDEX_op_sar_i64, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_sari_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_sari_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
{
if (arg2 == 0) {
tcg_gen_mov_i64(ret, arg1);
} else {
- TCGv t0 = tcg_const_i64(arg2);
+ TCGv_i64 t0 = tcg_const_i64(arg2);
tcg_gen_sar_i64(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i64(t0);
}
}
-#ifndef VBOX
-static inline void tcg_gen_brcond_i64(int cond, TCGv arg1, TCGv arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_brcond_i64(int cond, TCGv arg1, TCGv arg2,
-#endif /* VBOX */
- int label_index)
+static inline void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1,
+ TCGv_i64 arg2, int label_index)
{
- tcg_gen_op4ii(INDEX_op_brcond_i64, arg1, arg2, cond, label_index);
+ tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond, label_index);
}
-#ifndef VBOX
-static inline void tcg_gen_mul_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_mul_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
+ TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op3(INDEX_op_mul_i64, ret, arg1, arg2);
+ tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond);
}
-#ifndef VBOX
-static inline void tcg_gen_muli_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_muli_i64(TCGv ret, TCGv arg1, int64_t arg2)
-#endif /* VBOX */
+static inline void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_mul_i64(ret, arg1, t0);
- tcg_temp_free(t0);
+ tcg_gen_op3_i64(INDEX_op_mul_i64, ret, arg1, arg2);
}
#ifdef TCG_TARGET_HAS_div_i64
-#ifndef VBOX
-static inline void tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op3(INDEX_op_div_i64, ret, arg1, arg2);
+ tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op3(INDEX_op_rem_i64, ret, arg1, arg2);
+ tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op3(INDEX_op_divu_i64, ret, arg1, arg2);
+ tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
}
-#ifndef VBOX
-static inline void tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- tcg_gen_op3(INDEX_op_remu_i64, ret, arg1, arg2);
+ tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
}
-#else
-#ifndef VBOX
-static inline void tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
-{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I64);
+#elif defined(TCG_TARGET_HAS_div2_i64)
+static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+ TCGv_i64 t0;
+ t0 = tcg_temp_new_i64();
tcg_gen_sari_i64(t0, arg1, 63);
- tcg_gen_op5(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
- tcg_temp_free(t0);
+ tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
+ tcg_temp_free_i64(t0);
}
-#ifndef VBOX
-static inline void tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I64);
+ TCGv_i64 t0;
+ t0 = tcg_temp_new_i64();
tcg_gen_sari_i64(t0, arg1, 63);
- tcg_gen_op5(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
- tcg_temp_free(t0);
+ tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
+ tcg_temp_free_i64(t0);
}
-#ifndef VBOX
-static inline void tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I64);
+ TCGv_i64 t0;
+ t0 = tcg_temp_new_i64();
tcg_gen_movi_i64(t0, 0);
- tcg_gen_op5(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
- tcg_temp_free(t0);
+ tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
+ tcg_temp_free_i64(t0);
}
-#ifndef VBOX
-static inline void tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-#endif /* VBOX */
+static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I64);
+ TCGv_i64 t0;
+ t0 = tcg_temp_new_i64();
tcg_gen_movi_i64(t0, 0);
- tcg_gen_op5(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
- tcg_temp_free(t0);
+ tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
+ tcg_temp_free_i64(t0);
+}
+#else
+static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+ int sizemask = 0;
+ /* Return value and both arguments are 64-bit and signed. */
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
+
+ tcg_gen_helper64(tcg_helper_div_i64, sizemask, ret, arg1, arg2);
+}
+
+static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+ int sizemask = 0;
+ /* Return value and both arguments are 64-bit and signed. */
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
+
+ tcg_gen_helper64(tcg_helper_rem_i64, sizemask, ret, arg1, arg2);
+}
+
+static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+ int sizemask = 0;
+ /* Return value and both arguments are 64-bit and unsigned. */
+ sizemask |= tcg_gen_sizemask(0, 1, 0);
+ sizemask |= tcg_gen_sizemask(1, 1, 0);
+ sizemask |= tcg_gen_sizemask(2, 1, 0);
+
+ tcg_gen_helper64(tcg_helper_divu_i64, sizemask, ret, arg1, arg2);
+}
+
+static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+ int sizemask = 0;
+ /* Return value and both arguments are 64-bit and unsigned. */
+ sizemask |= tcg_gen_sizemask(0, 1, 0);
+ sizemask |= tcg_gen_sizemask(1, 1, 0);
+ sizemask |= tcg_gen_sizemask(2, 1, 0);
+
+ tcg_gen_helper64(tcg_helper_remu_i64, sizemask, ret, arg1, arg2);
}
#endif
#endif
-#ifndef VBOX
-static inline void tcg_gen_brcondi_i64(int cond, TCGv arg1, int64_t arg2,
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_brcondi_i64(int cond, TCGv arg1, int64_t arg2,
-#endif /* VBOX */
- int label_index)
+static inline void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
+{
+ /* some cases can be optimized here */
+ if (arg2 == 0) {
+ tcg_gen_mov_i64(ret, arg1);
+ } else {
+ TCGv_i64 t0 = tcg_const_i64(arg2);
+ tcg_gen_add_i64(ret, arg1, t0);
+ tcg_temp_free_i64(t0);
+ }
+}
+
+static inline void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2)
{
- TCGv t0 = tcg_const_i64(arg2);
+ TCGv_i64 t0 = tcg_const_i64(arg1);
+ tcg_gen_sub_i64(ret, t0, arg2);
+ tcg_temp_free_i64(t0);
+}
+
+static inline void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
+{
+ /* some cases can be optimized here */
+ if (arg2 == 0) {
+ tcg_gen_mov_i64(ret, arg1);
+ } else {
+ TCGv_i64 t0 = tcg_const_i64(arg2);
+ tcg_gen_sub_i64(ret, arg1, t0);
+ tcg_temp_free_i64(t0);
+ }
+}
+static inline void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1,
+ int64_t arg2, int label_index)
+{
+ TCGv_i64 t0 = tcg_const_i64(arg2);
tcg_gen_brcond_i64(cond, arg1, t0, label_index);
- tcg_temp_free(t0);
+ tcg_temp_free_i64(t0);
}
+static inline void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
+ TCGv_i64 arg1, int64_t arg2)
+{
+ TCGv_i64 t0 = tcg_const_i64(arg2);
+ tcg_gen_setcond_i64(cond, ret, arg1, t0);
+ tcg_temp_free_i64(t0);
+}
+
+static inline void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
+{
+ TCGv_i64 t0 = tcg_const_i64(arg2);
+ tcg_gen_mul_i64(ret, arg1, t0);
+ tcg_temp_free_i64(t0);
+}
+
+
/***************************************/
/* optional operations */
-#ifndef VBOX
-static inline void tcg_gen_ext8s_i32(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext8s_i32(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg)
{
#ifdef TCG_TARGET_HAS_ext8s_i32
- tcg_gen_op2(INDEX_op_ext8s_i32, ret, arg);
+ tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg);
#else
tcg_gen_shli_i32(ret, arg, 24);
tcg_gen_sari_i32(ret, ret, 24);
#endif
}
-#ifndef VBOX
-static inline void tcg_gen_ext16s_i32(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext16s_i32(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg)
{
#ifdef TCG_TARGET_HAS_ext16s_i32
- tcg_gen_op2(INDEX_op_ext16s_i32, ret, arg);
+ tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg);
#else
tcg_gen_shli_i32(ret, arg, 16);
tcg_gen_sari_i32(ret, ret, 16);
#endif
}
-/* These are currently just for convenience.
- We assume a target will recognise these automatically . */
-#ifndef VBOX
-static inline void tcg_gen_ext8u_i32(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext8u_i32(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg)
{
+#ifdef TCG_TARGET_HAS_ext8u_i32
+ tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg);
+#else
tcg_gen_andi_i32(ret, arg, 0xffu);
+#endif
}
-#ifndef VBOX
-static inline void tcg_gen_ext16u_i32(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext16u_i32(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg)
{
+#ifdef TCG_TARGET_HAS_ext16u_i32
+ tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg);
+#else
tcg_gen_andi_i32(ret, arg, 0xffffu);
+#endif
}
/* Note: we assume the two high bytes are set to zero */
-#ifndef VBOX
-static inline void tcg_gen_bswap16_i32(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_bswap16_i32(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg)
{
#ifdef TCG_TARGET_HAS_bswap16_i32
- tcg_gen_op2(INDEX_op_bswap16_i32, ret, arg);
+ tcg_gen_op2_i32(INDEX_op_bswap16_i32, ret, arg);
#else
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- t1 = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 t0 = tcg_temp_new_i32();
- tcg_gen_shri_i32(t0, arg, 8);
- tcg_gen_andi_i32(t1, arg, 0x000000ff);
- tcg_gen_shli_i32(t1, t1, 8);
- tcg_gen_or_i32(ret, t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
+ tcg_gen_ext8u_i32(t0, arg);
+ tcg_gen_shli_i32(t0, t0, 8);
+ tcg_gen_shri_i32(ret, arg, 8);
+ tcg_gen_or_i32(ret, ret, t0);
+ tcg_temp_free_i32(t0);
#endif
}
-#ifndef VBOX
-static inline void tcg_gen_bswap_i32(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_bswap_i32(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
{
-#ifdef TCG_TARGET_HAS_bswap_i32
- tcg_gen_op2(INDEX_op_bswap_i32, ret, arg);
+#ifdef TCG_TARGET_HAS_bswap32_i32
+ tcg_gen_op2_i32(INDEX_op_bswap32_i32, ret, arg);
#else
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- t1 = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 t0, t1;
+ t0 = tcg_temp_new_i32();
+ t1 = tcg_temp_new_i32();
tcg_gen_shli_i32(t0, arg, 24);
@@ -1750,234 +1462,223 @@ DECLINLINE(void) tcg_gen_bswap_i32(TCGv ret, TCGv arg)
tcg_gen_shri_i32(t1, arg, 24);
tcg_gen_or_i32(ret, t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
#endif
}
#if TCG_TARGET_REG_BITS == 32
-#ifndef VBOX
-static inline void tcg_gen_ext8s_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext8s_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg)
{
- tcg_gen_ext8s_i32(ret, arg);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
+ tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
+ tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
}
-#ifndef VBOX
-static inline void tcg_gen_ext16s_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext16s_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg)
{
- tcg_gen_ext16s_i32(ret, arg);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
+ tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
+ tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
}
-#ifndef VBOX
-static inline void tcg_gen_ext32s_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext32s_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg)
{
- tcg_gen_mov_i32(ret, arg);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
+ tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
+ tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
}
-#ifndef VBOX
-static inline void tcg_gen_ext8u_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext8u_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg)
{
- tcg_gen_ext8u_i32(ret, arg);
+ tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
}
-#ifndef VBOX
-static inline void tcg_gen_ext16u_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext16u_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg)
{
- tcg_gen_ext16u_i32(ret, arg);
+ tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
}
-#ifndef VBOX
-static inline void tcg_gen_ext32u_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext32u_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
{
- tcg_gen_mov_i32(ret, arg);
+ tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
}
-#ifndef VBOX
-static inline void tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_trunc_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
{
- tcg_gen_mov_i32(ret, arg);
+ tcg_gen_mov_i32(ret, TCGV_LOW(arg));
}
-#ifndef VBOX
-static inline void tcg_gen_extu_i32_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_extu_i32_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
{
- tcg_gen_mov_i32(ret, arg);
+ tcg_gen_mov_i32(TCGV_LOW(ret), arg);
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
}
-#ifndef VBOX
-static inline void tcg_gen_ext_i32_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext_i32_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
+{
+ tcg_gen_mov_i32(TCGV_LOW(ret), arg);
+ tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
+}
+
+/* Note: we assume the six high bytes are set to zero */
+static inline void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg)
+{
+ tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
+ tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg));
+}
+
+/* Note: we assume the four high bytes are set to zero */
+static inline void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg)
{
- tcg_gen_mov_i32(ret, arg);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
+ tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
+ tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg));
}
-#ifndef VBOX
-static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_bswap_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
{
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- t1 = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 t0, t1;
+ t0 = tcg_temp_new_i32();
+ t1 = tcg_temp_new_i32();
- tcg_gen_bswap_i32(t0, arg);
- tcg_gen_bswap_i32(t1, TCGV_HIGH(arg));
- tcg_gen_mov_i32(ret, t1);
+ tcg_gen_bswap32_i32(t0, TCGV_LOW(arg));
+ tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg));
+ tcg_gen_mov_i32(TCGV_LOW(ret), t1);
tcg_gen_mov_i32(TCGV_HIGH(ret), t0);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
}
#else
-#ifndef VBOX
-static inline void tcg_gen_ext8s_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext8s_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg)
{
#ifdef TCG_TARGET_HAS_ext8s_i64
- tcg_gen_op2(INDEX_op_ext8s_i64, ret, arg);
+ tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg);
#else
tcg_gen_shli_i64(ret, arg, 56);
tcg_gen_sari_i64(ret, ret, 56);
#endif
}
-#ifndef VBOX
-static inline void tcg_gen_ext16s_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext16s_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg)
{
#ifdef TCG_TARGET_HAS_ext16s_i64
- tcg_gen_op2(INDEX_op_ext16s_i64, ret, arg);
+ tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg);
#else
tcg_gen_shli_i64(ret, arg, 48);
tcg_gen_sari_i64(ret, ret, 48);
#endif
}
-#ifndef VBOX
-static inline void tcg_gen_ext32s_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext32s_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg)
{
#ifdef TCG_TARGET_HAS_ext32s_i64
- tcg_gen_op2(INDEX_op_ext32s_i64, ret, arg);
+ tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg);
#else
tcg_gen_shli_i64(ret, arg, 32);
tcg_gen_sari_i64(ret, ret, 32);
#endif
}
-#ifndef VBOX
-static inline void tcg_gen_ext8u_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext8u_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg)
{
+#ifdef TCG_TARGET_HAS_ext8u_i64
+ tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg);
+#else
tcg_gen_andi_i64(ret, arg, 0xffu);
+#endif
}
-#ifndef VBOX
-static inline void tcg_gen_ext16u_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext16u_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg)
{
+#ifdef TCG_TARGET_HAS_ext16u_i64
+ tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg);
+#else
tcg_gen_andi_i64(ret, arg, 0xffffu);
+#endif
}
-#ifndef VBOX
-static inline void tcg_gen_ext32u_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext32u_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
{
+#ifdef TCG_TARGET_HAS_ext32u_i64
+ tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg);
+#else
tcg_gen_andi_i64(ret, arg, 0xffffffffu);
+#endif
}
/* Note: we assume the target supports move between 32 and 64 bit
registers. This will probably break MIPS64 targets. */
-#ifndef VBOX
-static inline void tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_trunc_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
{
- tcg_gen_mov_i32(ret, arg);
+ tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(arg)));
}
/* Note: we assume the target supports move between 32 and 64 bit
registers */
-#ifndef VBOX
-static inline void tcg_gen_extu_i32_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_extu_i32_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
{
- tcg_gen_andi_i64(ret, arg, 0xffffffffu);
+ tcg_gen_ext32u_i64(ret, MAKE_TCGV_I64(GET_TCGV_I32(arg)));
}
/* Note: we assume the target supports move between 32 and 64 bit
registers */
-#ifndef VBOX
-static inline void tcg_gen_ext_i32_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_ext_i32_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
+{
+ tcg_gen_ext32s_i64(ret, MAKE_TCGV_I64(GET_TCGV_I32(arg)));
+}
+
+/* Note: we assume the six high bytes are set to zero */
+static inline void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg)
+{
+#ifdef TCG_TARGET_HAS_bswap16_i64
+ tcg_gen_op2_i64(INDEX_op_bswap16_i64, ret, arg);
+#else
+ TCGv_i64 t0 = tcg_temp_new_i64();
+
+ tcg_gen_ext8u_i64(t0, arg);
+ tcg_gen_shli_i64(t0, t0, 8);
+ tcg_gen_shri_i64(ret, arg, 8);
+ tcg_gen_or_i64(ret, ret, t0);
+ tcg_temp_free_i64(t0);
+#endif
+}
+
+/* Note: we assume the four high bytes are set to zero */
+static inline void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg)
{
- tcg_gen_ext32s_i64(ret, arg);
+#ifdef TCG_TARGET_HAS_bswap32_i64
+ tcg_gen_op2_i64(INDEX_op_bswap32_i64, ret, arg);
+#else
+ TCGv_i64 t0, t1;
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
+
+ tcg_gen_shli_i64(t0, arg, 24);
+ tcg_gen_ext32u_i64(t0, t0);
+
+ tcg_gen_andi_i64(t1, arg, 0x0000ff00);
+ tcg_gen_shli_i64(t1, t1, 8);
+ tcg_gen_or_i64(t0, t0, t1);
+
+ tcg_gen_shri_i64(t1, arg, 8);
+ tcg_gen_andi_i64(t1, t1, 0x0000ff00);
+ tcg_gen_or_i64(t0, t0, t1);
+
+ tcg_gen_shri_i64(t1, arg, 24);
+ tcg_gen_or_i64(ret, t0, t1);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
+#endif
}
-#ifndef VBOX
-static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_bswap_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
{
-#ifdef TCG_TARGET_HAS_bswap_i64
- tcg_gen_op2(INDEX_op_bswap_i64, ret, arg);
+#ifdef TCG_TARGET_HAS_bswap64_i64
+ tcg_gen_op2_i64(INDEX_op_bswap64_i64, ret, arg);
#else
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- t1 = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_new_i64();
tcg_gen_shli_i64(t0, arg, 56);
@@ -2007,127 +1708,367 @@ DECLINLINE(void) tcg_gen_bswap_i64(TCGv ret, TCGv arg)
tcg_gen_shri_i64(t1, arg, 56);
tcg_gen_or_i64(ret, t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
#endif
}
#endif
-#ifndef VBOX
-static inline void tcg_gen_neg_i32(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_neg_i32(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_neg_i32(TCGv_i32 ret, TCGv_i32 arg)
{
#ifdef TCG_TARGET_HAS_neg_i32
- tcg_gen_op2(INDEX_op_neg_i32, ret, arg);
+ tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg);
#else
- TCGv t0 = tcg_const_i32(0);
+ TCGv_i32 t0 = tcg_const_i32(0);
tcg_gen_sub_i32(ret, t0, arg);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
#endif
}
-#ifndef VBOX
-static inline void tcg_gen_neg_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_neg_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_neg_i64(TCGv_i64 ret, TCGv_i64 arg)
{
#ifdef TCG_TARGET_HAS_neg_i64
- tcg_gen_op2(INDEX_op_neg_i64, ret, arg);
+ tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg);
#else
- TCGv t0 = tcg_const_i64(0);
+ TCGv_i64 t0 = tcg_const_i64(0);
tcg_gen_sub_i64(ret, t0, arg);
- tcg_temp_free(t0);
+ tcg_temp_free_i64(t0);
#endif
}
-#ifndef VBOX
-static inline void tcg_gen_not_i32(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_not_i32(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_not_i32(TCGv_i32 ret, TCGv_i32 arg)
{
+#ifdef TCG_TARGET_HAS_not_i32
+ tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg);
+#else
tcg_gen_xori_i32(ret, arg, -1);
+#endif
}
-#ifndef VBOX
-static inline void tcg_gen_not_i64(TCGv ret, TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_not_i64(TCGv ret, TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg)
{
+#ifdef TCG_TARGET_HAS_not_i64
+ tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg);
+#elif defined(TCG_TARGET_HAS_not_i32) && TCG_TARGET_REG_BITS == 32
+ tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg));
+ tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
+#else
tcg_gen_xori_i64(ret, arg, -1);
+#endif
}
-#ifndef VBOX
-static inline void tcg_gen_discard_i32(TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_discard_i32(TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_discard_i32(TCGv_i32 arg)
{
- tcg_gen_op1(INDEX_op_discard, arg);
+ tcg_gen_op1_i32(INDEX_op_discard, arg);
}
#if TCG_TARGET_REG_BITS == 32
-#ifndef VBOX
-static inline void tcg_gen_discard_i64(TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_discard_i64(TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_discard_i64(TCGv_i64 arg)
{
- tcg_gen_discard_i32(arg);
+ tcg_gen_discard_i32(TCGV_LOW(arg));
tcg_gen_discard_i32(TCGV_HIGH(arg));
}
#else
-#ifndef VBOX
-static inline void tcg_gen_discard_i64(TCGv arg)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_discard_i64(TCGv arg)
-#endif /* VBOX */
+static inline void tcg_gen_discard_i64(TCGv_i64 arg)
{
- tcg_gen_op1(INDEX_op_discard, arg);
+ tcg_gen_op1_i64(INDEX_op_discard, arg);
}
#endif
-#ifndef VBOX
-static inline void tcg_gen_concat_i32_i64(TCGv dest, TCGv low, TCGv high)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_concat_i32_i64(TCGv dest, TCGv low, TCGv high)
-#endif /* VBOX */
+static inline void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
{
#if TCG_TARGET_REG_BITS == 32
- tcg_gen_mov_i32(dest, low);
+ tcg_gen_mov_i32(TCGV_LOW(dest), low);
tcg_gen_mov_i32(TCGV_HIGH(dest), high);
#else
- TCGv tmp = tcg_temp_new (TCG_TYPE_I64);
+ TCGv_i64 tmp = tcg_temp_new_i64();
/* This extension is only needed for type correctness.
We may be able to do better given target specific information. */
tcg_gen_extu_i32_i64(tmp, high);
tcg_gen_shli_i64(tmp, tmp, 32);
tcg_gen_extu_i32_i64(dest, low);
tcg_gen_or_i64(dest, dest, tmp);
- tcg_temp_free(tmp);
+ tcg_temp_free_i64(tmp);
#endif
}
-#ifndef VBOX
-static inline void tcg_gen_concat32_i64(TCGv dest, TCGv low, TCGv high)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_concat32_i64(TCGv dest, TCGv low, TCGv high)
-#endif /* VBOX */
+static inline void tcg_gen_concat32_i64(TCGv_i64 dest, TCGv_i64 low, TCGv_i64 high)
{
#if TCG_TARGET_REG_BITS == 32
- tcg_gen_concat_i32_i64(dest, low, high);
+ tcg_gen_concat_i32_i64(dest, TCGV_LOW(low), TCGV_LOW(high));
#else
- TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+ TCGv_i64 tmp = tcg_temp_new_i64();
tcg_gen_ext32u_i64(dest, low);
tcg_gen_shli_i64(tmp, high, 32);
tcg_gen_or_i64(dest, dest, tmp);
- tcg_temp_free(tmp);
+ tcg_temp_free_i64(tmp);
+#endif
+}
+
+static inline void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+#ifdef TCG_TARGET_HAS_andc_i32
+ tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
+#else
+ TCGv_i32 t0;
+ t0 = tcg_temp_new_i32();
+ tcg_gen_not_i32(t0, arg2);
+ tcg_gen_and_i32(ret, arg1, t0);
+ tcg_temp_free_i32(t0);
+#endif
+}
+
+static inline void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+#ifdef TCG_TARGET_HAS_andc_i64
+ tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
+#elif defined(TCG_TARGET_HAS_andc_i32) && TCG_TARGET_REG_BITS == 32
+ tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
+ tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
+#else
+ TCGv_i64 t0;
+ t0 = tcg_temp_new_i64();
+ tcg_gen_not_i64(t0, arg2);
+ tcg_gen_and_i64(ret, arg1, t0);
+ tcg_temp_free_i64(t0);
+#endif
+}
+
+static inline void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+#ifdef TCG_TARGET_HAS_eqv_i32
+ tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2);
+#else
+ tcg_gen_xor_i32(ret, arg1, arg2);
+ tcg_gen_not_i32(ret, ret);
+#endif
+}
+
+static inline void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+#ifdef TCG_TARGET_HAS_eqv_i64
+ tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2);
+#elif defined(TCG_TARGET_HAS_eqv_i32) && TCG_TARGET_REG_BITS == 32
+ tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
+ tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
+#else
+ tcg_gen_xor_i64(ret, arg1, arg2);
+ tcg_gen_not_i64(ret, ret);
+#endif
+}
+
+static inline void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+#ifdef TCG_TARGET_HAS_nand_i32
+ tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2);
+#else
+ tcg_gen_and_i32(ret, arg1, arg2);
+ tcg_gen_not_i32(ret, ret);
+#endif
+}
+
+static inline void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+#ifdef TCG_TARGET_HAS_nand_i64
+ tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2);
+#elif defined(TCG_TARGET_HAS_nand_i32) && TCG_TARGET_REG_BITS == 32
+ tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
+ tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
+#else
+ tcg_gen_and_i64(ret, arg1, arg2);
+ tcg_gen_not_i64(ret, ret);
+#endif
+}
+
+static inline void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+#ifdef TCG_TARGET_HAS_nor_i32
+ tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2);
+#else
+ tcg_gen_or_i32(ret, arg1, arg2);
+ tcg_gen_not_i32(ret, ret);
+#endif
+}
+
+static inline void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+#ifdef TCG_TARGET_HAS_nor_i64
+ tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2);
+#elif defined(TCG_TARGET_HAS_nor_i32) && TCG_TARGET_REG_BITS == 32
+ tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
+ tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
+#else
+ tcg_gen_or_i64(ret, arg1, arg2);
+ tcg_gen_not_i64(ret, ret);
+#endif
+}
+
+static inline void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+#ifdef TCG_TARGET_HAS_orc_i32
+ tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
+#else
+ TCGv_i32 t0;
+ t0 = tcg_temp_new_i32();
+ tcg_gen_not_i32(t0, arg2);
+ tcg_gen_or_i32(ret, arg1, t0);
+ tcg_temp_free_i32(t0);
+#endif
+}
+
+static inline void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+#ifdef TCG_TARGET_HAS_orc_i64
+ tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
+#elif defined(TCG_TARGET_HAS_orc_i32) && TCG_TARGET_REG_BITS == 32
+ tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
+ tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
+#else
+ TCGv_i64 t0;
+ t0 = tcg_temp_new_i64();
+ tcg_gen_not_i64(t0, arg2);
+ tcg_gen_or_i64(ret, arg1, t0);
+ tcg_temp_free_i64(t0);
+#endif
+}
+
+static inline void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+#ifdef TCG_TARGET_HAS_rot_i32
+ tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2);
+#else
+ TCGv_i32 t0, t1;
+
+ t0 = tcg_temp_new_i32();
+ t1 = tcg_temp_new_i32();
+ tcg_gen_shl_i32(t0, arg1, arg2);
+ tcg_gen_subfi_i32(t1, 32, arg2);
+ tcg_gen_shr_i32(t1, arg1, t1);
+ tcg_gen_or_i32(ret, t0, t1);
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
+#endif
+}
+
+static inline void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+#ifdef TCG_TARGET_HAS_rot_i64
+ tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
+#else
+ TCGv_i64 t0, t1;
+
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
+ tcg_gen_shl_i64(t0, arg1, arg2);
+ tcg_gen_subfi_i64(t1, 64, arg2);
+ tcg_gen_shr_i64(t1, arg1, t1);
+ tcg_gen_or_i64(ret, t0, t1);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
+#endif
+}
+
+static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
+{
+ /* some cases can be optimized here */
+ if (arg2 == 0) {
+ tcg_gen_mov_i32(ret, arg1);
+ } else {
+#ifdef TCG_TARGET_HAS_rot_i32
+ TCGv_i32 t0 = tcg_const_i32(arg2);
+ tcg_gen_rotl_i32(ret, arg1, t0);
+ tcg_temp_free_i32(t0);
+#else
+ TCGv_i32 t0, t1;
+ t0 = tcg_temp_new_i32();
+ t1 = tcg_temp_new_i32();
+ tcg_gen_shli_i32(t0, arg1, arg2);
+ tcg_gen_shri_i32(t1, arg1, 32 - arg2);
+ tcg_gen_or_i32(ret, t0, t1);
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
+#endif
+ }
+}
+
+static inline void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
+{
+ /* some cases can be optimized here */
+ if (arg2 == 0) {
+ tcg_gen_mov_i64(ret, arg1);
+ } else {
+#ifdef TCG_TARGET_HAS_rot_i64
+ TCGv_i64 t0 = tcg_const_i64(arg2);
+ tcg_gen_rotl_i64(ret, arg1, t0);
+ tcg_temp_free_i64(t0);
+#else
+ TCGv_i64 t0, t1;
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
+ tcg_gen_shli_i64(t0, arg1, arg2);
+ tcg_gen_shri_i64(t1, arg1, 64 - arg2);
+ tcg_gen_or_i64(ret, t0, t1);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
#endif
+ }
+}
+
+static inline void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+#ifdef TCG_TARGET_HAS_rot_i32
+ tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2);
+#else
+ TCGv_i32 t0, t1;
+
+ t0 = tcg_temp_new_i32();
+ t1 = tcg_temp_new_i32();
+ tcg_gen_shr_i32(t0, arg1, arg2);
+ tcg_gen_subfi_i32(t1, 32, arg2);
+ tcg_gen_shl_i32(t1, arg1, t1);
+ tcg_gen_or_i32(ret, t0, t1);
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
+#endif
+}
+
+static inline void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
+{
+#ifdef TCG_TARGET_HAS_rot_i64
+ tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
+#else
+ TCGv_i64 t0, t1;
+
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
+ tcg_gen_shr_i64(t0, arg1, arg2);
+ tcg_gen_subfi_i64(t1, 64, arg2);
+ tcg_gen_shl_i64(t1, arg1, t1);
+ tcg_gen_or_i64(ret, t0, t1);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
+#endif
+}
+
+static inline void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
+{
+ /* some cases can be optimized here */
+ if (arg2 == 0) {
+ tcg_gen_mov_i32(ret, arg1);
+ } else {
+ tcg_gen_rotli_i32(ret, arg1, 32 - arg2);
+ }
+}
+
+static inline void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
+{
+ /* some cases can be optimized here */
+ if (arg2 == 0) {
+ tcg_gen_mov_i64(ret, arg1);
+ } else {
+ tcg_gen_rotli_i64(ret, arg1, 64 - arg2);
+ }
}
/***************************************/
@@ -2137,12 +2078,32 @@ DECLINLINE(void) tcg_gen_concat32_i64(TCGv dest, TCGv low, TCGv high)
#error must include QEMU headers
#endif
+#if TARGET_LONG_BITS == 32
+#define TCGv TCGv_i32
+#define tcg_temp_new() tcg_temp_new_i32()
+#define tcg_global_reg_new tcg_global_reg_new_i32
+#define tcg_global_mem_new tcg_global_mem_new_i32
+#define tcg_temp_local_new() tcg_temp_local_new_i32()
+#define tcg_temp_free tcg_temp_free_i32
+#define tcg_gen_qemu_ldst_op tcg_gen_op3i_i32
+#define tcg_gen_qemu_ldst_op_i64 tcg_gen_qemu_ldst_op_i64_i32
+#define TCGV_UNUSED(x) TCGV_UNUSED_I32(x)
+#define TCGV_EQUAL(a, b) TCGV_EQUAL_I32(a, b)
+#else
+#define TCGv TCGv_i64
+#define tcg_temp_new() tcg_temp_new_i64()
+#define tcg_global_reg_new tcg_global_reg_new_i64
+#define tcg_global_mem_new tcg_global_mem_new_i64
+#define tcg_temp_local_new() tcg_temp_local_new_i64()
+#define tcg_temp_free tcg_temp_free_i64
+#define tcg_gen_qemu_ldst_op tcg_gen_op3i_i64
+#define tcg_gen_qemu_ldst_op_i64 tcg_gen_qemu_ldst_op_i64_i64
+#define TCGV_UNUSED(x) TCGV_UNUSED_I64(x)
+#define TCGV_EQUAL(a, b) TCGV_EQUAL_I64(a, b)
+#endif
+
/* debug info: write the PC of the corresponding QEMU CPU instruction */
-#ifndef VBOX
static inline void tcg_gen_debug_insn_start(uint64_t pc)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_debug_insn_start(uint64_t pc)
-#endif /* VBOX */
{
/* XXX: must really use a 32 bit size for TCGArg in all cases */
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
@@ -2153,173 +2114,131 @@ DECLINLINE(void) tcg_gen_debug_insn_start(uint64_t pc)
#endif
}
-#ifndef VBOX
static inline void tcg_gen_exit_tb(tcg_target_long val)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_exit_tb(tcg_target_long val)
-#endif /* VBOX */
{
tcg_gen_op1i(INDEX_op_exit_tb, val);
}
-#ifndef VBOX
static inline void tcg_gen_goto_tb(int idx)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_goto_tb(int idx)
-#endif /* VBOX */
{
tcg_gen_op1i(INDEX_op_goto_tb, idx);
}
#if TCG_TARGET_REG_BITS == 32
-#ifndef VBOX
static inline void tcg_gen_qemu_ld8u(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld8u(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
{
#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_ld8u, ret, addr, mem_index);
+ tcg_gen_op3i_i32(INDEX_op_qemu_ld8u, ret, addr, mem_index);
#else
- tcg_gen_op4i(INDEX_op_qemu_ld8u, ret, addr, TCGV_HIGH(addr), mem_index);
+ tcg_gen_op4i_i32(INDEX_op_qemu_ld8u, TCGV_LOW(ret), TCGV_LOW(addr),
+ TCGV_HIGH(addr), mem_index);
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
#endif
}
-#ifndef VBOX
static inline void tcg_gen_qemu_ld8s(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld8s(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
{
#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_ld8s, ret, addr, mem_index);
+ tcg_gen_op3i_i32(INDEX_op_qemu_ld8s, ret, addr, mem_index);
#else
- tcg_gen_op4i(INDEX_op_qemu_ld8s, ret, addr, TCGV_HIGH(addr), mem_index);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
+ tcg_gen_op4i_i32(INDEX_op_qemu_ld8s, TCGV_LOW(ret), TCGV_LOW(addr),
+ TCGV_HIGH(addr), mem_index);
+ tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
#endif
}
-#ifndef VBOX
static inline void tcg_gen_qemu_ld16u(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld16u(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
{
#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_ld16u, ret, addr, mem_index);
+ tcg_gen_op3i_i32(INDEX_op_qemu_ld16u, ret, addr, mem_index);
#else
- tcg_gen_op4i(INDEX_op_qemu_ld16u, ret, addr, TCGV_HIGH(addr), mem_index);
+ tcg_gen_op4i_i32(INDEX_op_qemu_ld16u, TCGV_LOW(ret), TCGV_LOW(addr),
+ TCGV_HIGH(addr), mem_index);
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
#endif
}
-#ifndef VBOX
static inline void tcg_gen_qemu_ld16s(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld16s(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
{
#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_ld16s, ret, addr, mem_index);
+ tcg_gen_op3i_i32(INDEX_op_qemu_ld16s, ret, addr, mem_index);
#else
- tcg_gen_op4i(INDEX_op_qemu_ld16s, ret, addr, TCGV_HIGH(addr), mem_index);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
+ tcg_gen_op4i_i32(INDEX_op_qemu_ld16s, TCGV_LOW(ret), TCGV_LOW(addr),
+ TCGV_HIGH(addr), mem_index);
+ tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
#endif
}
-#ifndef VBOX
static inline void tcg_gen_qemu_ld32u(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld32u(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
{
#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_ld32u, ret, addr, mem_index);
+ tcg_gen_op3i_i32(INDEX_op_qemu_ld32, ret, addr, mem_index);
#else
- tcg_gen_op4i(INDEX_op_qemu_ld32u, ret, addr, TCGV_HIGH(addr), mem_index);
+ tcg_gen_op4i_i32(INDEX_op_qemu_ld32, TCGV_LOW(ret), TCGV_LOW(addr),
+ TCGV_HIGH(addr), mem_index);
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
#endif
}
-#ifndef VBOX
static inline void tcg_gen_qemu_ld32s(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld32s(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
{
#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_ld32u, ret, addr, mem_index);
+ tcg_gen_op3i_i32(INDEX_op_qemu_ld32, ret, addr, mem_index);
#else
- tcg_gen_op4i(INDEX_op_qemu_ld32u, ret, addr, TCGV_HIGH(addr), mem_index);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
+ tcg_gen_op4i_i32(INDEX_op_qemu_ld32, TCGV_LOW(ret), TCGV_LOW(addr),
+ TCGV_HIGH(addr), mem_index);
+ tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
#endif
}
-#ifndef VBOX
-static inline void tcg_gen_qemu_ld64(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld64(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
+static inline void tcg_gen_qemu_ld64(TCGv_i64 ret, TCGv addr, int mem_index)
{
#if TARGET_LONG_BITS == 32
- tcg_gen_op4i(INDEX_op_qemu_ld64, ret, TCGV_HIGH(ret), addr, mem_index);
+ tcg_gen_op4i_i32(INDEX_op_qemu_ld64, TCGV_LOW(ret), TCGV_HIGH(ret), addr, mem_index);
#else
- tcg_gen_op5i(INDEX_op_qemu_ld64, ret, TCGV_HIGH(ret),
- addr, TCGV_HIGH(addr), mem_index);
+ tcg_gen_op5i_i32(INDEX_op_qemu_ld64, TCGV_LOW(ret), TCGV_HIGH(ret),
+ TCGV_LOW(addr), TCGV_HIGH(addr), mem_index);
#endif
}
-#ifndef VBOX
static inline void tcg_gen_qemu_st8(TCGv arg, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_st8(TCGv arg, TCGv addr, int mem_index)
-#endif /* VBOX */
{
#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_st8, arg, addr, mem_index);
+ tcg_gen_op3i_i32(INDEX_op_qemu_st8, arg, addr, mem_index);
#else
- tcg_gen_op4i(INDEX_op_qemu_st8, arg, addr, TCGV_HIGH(addr), mem_index);
+ tcg_gen_op4i_i32(INDEX_op_qemu_st8, TCGV_LOW(arg), TCGV_LOW(addr),
+ TCGV_HIGH(addr), mem_index);
#endif
}
-#ifndef VBOX
static inline void tcg_gen_qemu_st16(TCGv arg, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_st16(TCGv arg, TCGv addr, int mem_index)
-#endif /* VBOX */
{
#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_st16, arg, addr, mem_index);
+ tcg_gen_op3i_i32(INDEX_op_qemu_st16, arg, addr, mem_index);
#else
- tcg_gen_op4i(INDEX_op_qemu_st16, arg, addr, TCGV_HIGH(addr), mem_index);
+ tcg_gen_op4i_i32(INDEX_op_qemu_st16, TCGV_LOW(arg), TCGV_LOW(addr),
+ TCGV_HIGH(addr), mem_index);
#endif
}
-#ifndef VBOX
static inline void tcg_gen_qemu_st32(TCGv arg, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_st32(TCGv arg, TCGv addr, int mem_index)
-#endif /* VBOX */
{
#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_st32, arg, addr, mem_index);
+ tcg_gen_op3i_i32(INDEX_op_qemu_st32, arg, addr, mem_index);
#else
- tcg_gen_op4i(INDEX_op_qemu_st32, arg, addr, TCGV_HIGH(addr), mem_index);
+ tcg_gen_op4i_i32(INDEX_op_qemu_st32, TCGV_LOW(arg), TCGV_LOW(addr),
+ TCGV_HIGH(addr), mem_index);
#endif
}
-#ifndef VBOX
-static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
-#endif /* VBOX */
+static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index)
{
#if TARGET_LONG_BITS == 32
- tcg_gen_op4i(INDEX_op_qemu_st64, arg, TCGV_HIGH(arg), addr, mem_index);
+ tcg_gen_op4i_i32(INDEX_op_qemu_st64, TCGV_LOW(arg), TCGV_HIGH(arg), addr,
+ mem_index);
#else
- tcg_gen_op5i(INDEX_op_qemu_st64, arg, TCGV_HIGH(arg),
- addr, TCGV_HIGH(addr), mem_index);
+ tcg_gen_op5i_i32(INDEX_op_qemu_st64, TCGV_LOW(arg), TCGV_HIGH(arg),
+ TCGV_LOW(addr), TCGV_HIGH(addr), mem_index);
#endif
}
@@ -2328,103 +2247,67 @@ DECLINLINE(void) tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
#else /* TCG_TARGET_REG_BITS == 32 */
-#ifndef VBOX
static inline void tcg_gen_qemu_ld8u(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld8u(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
{
- tcg_gen_op3i(INDEX_op_qemu_ld8u, ret, addr, mem_index);
+ tcg_gen_qemu_ldst_op(INDEX_op_qemu_ld8u, ret, addr, mem_index);
}
-#ifndef VBOX
static inline void tcg_gen_qemu_ld8s(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld8s(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
{
- tcg_gen_op3i(INDEX_op_qemu_ld8s, ret, addr, mem_index);
+ tcg_gen_qemu_ldst_op(INDEX_op_qemu_ld8s, ret, addr, mem_index);
}
-#ifndef VBOX
static inline void tcg_gen_qemu_ld16u(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld16u(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
{
- tcg_gen_op3i(INDEX_op_qemu_ld16u, ret, addr, mem_index);
+ tcg_gen_qemu_ldst_op(INDEX_op_qemu_ld16u, ret, addr, mem_index);
}
-#ifndef VBOX
static inline void tcg_gen_qemu_ld16s(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld16s(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
{
- tcg_gen_op3i(INDEX_op_qemu_ld16s, ret, addr, mem_index);
+ tcg_gen_qemu_ldst_op(INDEX_op_qemu_ld16s, ret, addr, mem_index);
}
-#ifndef VBOX
static inline void tcg_gen_qemu_ld32u(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld32u(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
{
- tcg_gen_op3i(INDEX_op_qemu_ld32u, ret, addr, mem_index);
+#if TARGET_LONG_BITS == 32
+ tcg_gen_qemu_ldst_op(INDEX_op_qemu_ld32, ret, addr, mem_index);
+#else
+ tcg_gen_qemu_ldst_op(INDEX_op_qemu_ld32u, ret, addr, mem_index);
+#endif
}
-#ifndef VBOX
static inline void tcg_gen_qemu_ld32s(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld32s(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
{
- tcg_gen_op3i(INDEX_op_qemu_ld32s, ret, addr, mem_index);
+#if TARGET_LONG_BITS == 32
+ tcg_gen_qemu_ldst_op(INDEX_op_qemu_ld32, ret, addr, mem_index);
+#else
+ tcg_gen_qemu_ldst_op(INDEX_op_qemu_ld32s, ret, addr, mem_index);
+#endif
}
-#ifndef VBOX
-static inline void tcg_gen_qemu_ld64(TCGv ret, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_ld64(TCGv ret, TCGv addr, int mem_index)
-#endif /* VBOX */
+static inline void tcg_gen_qemu_ld64(TCGv_i64 ret, TCGv addr, int mem_index)
{
- tcg_gen_op3i(INDEX_op_qemu_ld64, ret, addr, mem_index);
+ tcg_gen_qemu_ldst_op_i64(INDEX_op_qemu_ld64, ret, addr, mem_index);
}
-#ifndef VBOX
static inline void tcg_gen_qemu_st8(TCGv arg, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_st8(TCGv arg, TCGv addr, int mem_index)
-#endif /* VBOX */
{
- tcg_gen_op3i(INDEX_op_qemu_st8, arg, addr, mem_index);
+ tcg_gen_qemu_ldst_op(INDEX_op_qemu_st8, arg, addr, mem_index);
}
-#ifndef VBOX
static inline void tcg_gen_qemu_st16(TCGv arg, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_st16(TCGv arg, TCGv addr, int mem_index)
-#endif /* VBOX */
{
- tcg_gen_op3i(INDEX_op_qemu_st16, arg, addr, mem_index);
+ tcg_gen_qemu_ldst_op(INDEX_op_qemu_st16, arg, addr, mem_index);
}
-#ifndef VBOX
static inline void tcg_gen_qemu_st32(TCGv arg, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_st32(TCGv arg, TCGv addr, int mem_index)
-#endif /* VBOX */
{
- tcg_gen_op3i(INDEX_op_qemu_st32, arg, addr, mem_index);
+ tcg_gen_qemu_ldst_op(INDEX_op_qemu_st32, arg, addr, mem_index);
}
-#ifndef VBOX
-static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
-#else /* VBOX */
-DECLINLINE(void) tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
-#endif /* VBOX */
+static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index)
{
- tcg_gen_op3i(INDEX_op_qemu_st64, arg, addr, mem_index);
+ tcg_gen_qemu_ldst_op_i64(INDEX_op_qemu_st64, arg, addr, mem_index);
}
#define tcg_gen_ld_ptr tcg_gen_ld_i64
@@ -2433,7 +2316,6 @@ DECLINLINE(void) tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
#endif /* TCG_TARGET_REG_BITS != 32 */
#if TARGET_LONG_BITS == 64
-#define TCG_TYPE_TL TCG_TYPE_I64
#define tcg_gen_movi_tl tcg_gen_movi_i64
#define tcg_gen_mov_tl tcg_gen_mov_i64
#define tcg_gen_ld8u_tl tcg_gen_ld8u_i64
@@ -2451,6 +2333,7 @@ DECLINLINE(void) tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
#define tcg_gen_addi_tl tcg_gen_addi_i64
#define tcg_gen_sub_tl tcg_gen_sub_i64
#define tcg_gen_neg_tl tcg_gen_neg_i64
+#define tcg_gen_subfi_tl tcg_gen_subfi_i64
#define tcg_gen_subi_tl tcg_gen_subi_i64
#define tcg_gen_and_tl tcg_gen_and_i64
#define tcg_gen_andi_tl tcg_gen_andi_i64
@@ -2467,8 +2350,14 @@ DECLINLINE(void) tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
#define tcg_gen_sari_tl tcg_gen_sari_i64
#define tcg_gen_brcond_tl tcg_gen_brcond_i64
#define tcg_gen_brcondi_tl tcg_gen_brcondi_i64
+#define tcg_gen_setcond_tl tcg_gen_setcond_i64
+#define tcg_gen_setcondi_tl tcg_gen_setcondi_i64
#define tcg_gen_mul_tl tcg_gen_mul_i64
#define tcg_gen_muli_tl tcg_gen_muli_i64
+#define tcg_gen_div_tl tcg_gen_div_i64
+#define tcg_gen_rem_tl tcg_gen_rem_i64
+#define tcg_gen_divu_tl tcg_gen_divu_i64
+#define tcg_gen_remu_tl tcg_gen_remu_i64
#define tcg_gen_discard_tl tcg_gen_discard_i64
#define tcg_gen_trunc_tl_i32 tcg_gen_trunc_i64_i32
#define tcg_gen_trunc_i64_tl tcg_gen_mov_i64
@@ -2482,10 +2371,22 @@ DECLINLINE(void) tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
#define tcg_gen_ext16s_tl tcg_gen_ext16s_i64
#define tcg_gen_ext32u_tl tcg_gen_ext32u_i64
#define tcg_gen_ext32s_tl tcg_gen_ext32s_i64
+#define tcg_gen_bswap16_tl tcg_gen_bswap16_i64
+#define tcg_gen_bswap32_tl tcg_gen_bswap32_i64
+#define tcg_gen_bswap64_tl tcg_gen_bswap64_i64
#define tcg_gen_concat_tl_i64 tcg_gen_concat32_i64
+#define tcg_gen_andc_tl tcg_gen_andc_i64
+#define tcg_gen_eqv_tl tcg_gen_eqv_i64
+#define tcg_gen_nand_tl tcg_gen_nand_i64
+#define tcg_gen_nor_tl tcg_gen_nor_i64
+#define tcg_gen_orc_tl tcg_gen_orc_i64
+#define tcg_gen_rotl_tl tcg_gen_rotl_i64
+#define tcg_gen_rotli_tl tcg_gen_rotli_i64
+#define tcg_gen_rotr_tl tcg_gen_rotr_i64
+#define tcg_gen_rotri_tl tcg_gen_rotri_i64
#define tcg_const_tl tcg_const_i64
+#define tcg_const_local_tl tcg_const_local_i64
#else
-#define TCG_TYPE_TL TCG_TYPE_I32
#define tcg_gen_movi_tl tcg_gen_movi_i32
#define tcg_gen_mov_tl tcg_gen_mov_i32
#define tcg_gen_ld8u_tl tcg_gen_ld8u_i32
@@ -2503,6 +2404,7 @@ DECLINLINE(void) tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
#define tcg_gen_addi_tl tcg_gen_addi_i32
#define tcg_gen_sub_tl tcg_gen_sub_i32
#define tcg_gen_neg_tl tcg_gen_neg_i32
+#define tcg_gen_subfi_tl tcg_gen_subfi_i32
#define tcg_gen_subi_tl tcg_gen_subi_i32
#define tcg_gen_and_tl tcg_gen_and_i32
#define tcg_gen_andi_tl tcg_gen_andi_i32
@@ -2519,8 +2421,14 @@ DECLINLINE(void) tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
#define tcg_gen_sari_tl tcg_gen_sari_i32
#define tcg_gen_brcond_tl tcg_gen_brcond_i32
#define tcg_gen_brcondi_tl tcg_gen_brcondi_i32
+#define tcg_gen_setcond_tl tcg_gen_setcond_i32
+#define tcg_gen_setcondi_tl tcg_gen_setcondi_i32
#define tcg_gen_mul_tl tcg_gen_mul_i32
#define tcg_gen_muli_tl tcg_gen_muli_i32
+#define tcg_gen_div_tl tcg_gen_div_i32
+#define tcg_gen_rem_tl tcg_gen_rem_i32
+#define tcg_gen_divu_tl tcg_gen_divu_i32
+#define tcg_gen_remu_tl tcg_gen_remu_i32
#define tcg_gen_discard_tl tcg_gen_discard_i32
#define tcg_gen_trunc_tl_i32 tcg_gen_mov_i32
#define tcg_gen_trunc_i64_tl tcg_gen_trunc_i64_i32
@@ -2534,8 +2442,20 @@ DECLINLINE(void) tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
#define tcg_gen_ext16s_tl tcg_gen_ext16s_i32
#define tcg_gen_ext32u_tl tcg_gen_mov_i32
#define tcg_gen_ext32s_tl tcg_gen_mov_i32
+#define tcg_gen_bswap16_tl tcg_gen_bswap16_i32
+#define tcg_gen_bswap32_tl tcg_gen_bswap32_i32
#define tcg_gen_concat_tl_i64 tcg_gen_concat_i32_i64
+#define tcg_gen_andc_tl tcg_gen_andc_i32
+#define tcg_gen_eqv_tl tcg_gen_eqv_i32
+#define tcg_gen_nand_tl tcg_gen_nand_i32
+#define tcg_gen_nor_tl tcg_gen_nor_i32
+#define tcg_gen_orc_tl tcg_gen_orc_i32
+#define tcg_gen_rotl_tl tcg_gen_rotl_i32
+#define tcg_gen_rotli_tl tcg_gen_rotli_i32
+#define tcg_gen_rotr_tl tcg_gen_rotr_i32
+#define tcg_gen_rotri_tl tcg_gen_rotri_i32
#define tcg_const_tl tcg_const_i32
+#define tcg_const_local_tl tcg_const_local_i32
#endif
#if TCG_TARGET_REG_BITS == 32
@@ -2547,4 +2467,3 @@ DECLINLINE(void) tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
#define tcg_gen_addi_ptr tcg_gen_addi_i64
#define tcg_gen_ext_i32_ptr tcg_gen_ext_i32_i64
#endif /* TCG_TARGET_REG_BITS != 32 */
-
diff --git a/src/recompiler/tcg/tcg-opc.h b/src/recompiler/tcg/tcg-opc.h
index 2431fb858..2a98fed90 100644
--- a/src/recompiler/tcg/tcg-opc.h
+++ b/src/recompiler/tcg/tcg-opc.h
@@ -22,218 +22,283 @@
* THE SOFTWARE.
*/
-#ifdef CONFIG_DYNGEN_OP
-#include "dyngen-opc.h"
-#endif
-
-#ifndef DEF2
-#define DEF2(name, oargs, iargs, cargs, flags) DEF(name, oargs + iargs + cargs, 0)
-#endif
+/*
+ * DEF(name, oargs, iargs, cargs, flags)
+ */
/* predefined ops */
-DEF2(end, 0, 0, 0, 0) /* must be kept first */
-DEF2(nop, 0, 0, 0, 0)
-DEF2(nop1, 0, 0, 1, 0)
-DEF2(nop2, 0, 0, 2, 0)
-DEF2(nop3, 0, 0, 3, 0)
-DEF2(nopn, 0, 0, 1, 0) /* variable number of parameters */
+DEF(end, 0, 0, 0, 0) /* must be kept first */
+DEF(nop, 0, 0, 0, 0)
+DEF(nop1, 0, 0, 1, 0)
+DEF(nop2, 0, 0, 2, 0)
+DEF(nop3, 0, 0, 3, 0)
+DEF(nopn, 0, 0, 1, 0) /* variable number of parameters */
-DEF2(discard, 1, 0, 0, 0)
+DEF(discard, 1, 0, 0, 0)
-DEF2(set_label, 0, 0, 1, 0)
-DEF2(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */
-DEF2(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-DEF2(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+DEF(set_label, 0, 0, 1, 0)
+DEF(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */
+DEF(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-DEF2(mov_i32, 1, 1, 0, 0)
-DEF2(movi_i32, 1, 0, 1, 0)
+DEF(mov_i32, 1, 1, 0, 0)
+DEF(movi_i32, 1, 0, 1, 0)
+DEF(setcond_i32, 1, 2, 1, 0)
/* load/store */
-DEF2(ld8u_i32, 1, 1, 1, 0)
-DEF2(ld8s_i32, 1, 1, 1, 0)
-DEF2(ld16u_i32, 1, 1, 1, 0)
-DEF2(ld16s_i32, 1, 1, 1, 0)
-DEF2(ld_i32, 1, 1, 1, 0)
-DEF2(st8_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF2(st16_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF2(st_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF(ld8u_i32, 1, 1, 1, 0)
+DEF(ld8s_i32, 1, 1, 1, 0)
+DEF(ld16u_i32, 1, 1, 1, 0)
+DEF(ld16s_i32, 1, 1, 1, 0)
+DEF(ld_i32, 1, 1, 1, 0)
+DEF(st8_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF(st16_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF(st_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
/* arith */
-DEF2(add_i32, 1, 2, 0, 0)
-DEF2(sub_i32, 1, 2, 0, 0)
-DEF2(mul_i32, 1, 2, 0, 0)
+DEF(add_i32, 1, 2, 0, 0)
+DEF(sub_i32, 1, 2, 0, 0)
+DEF(mul_i32, 1, 2, 0, 0)
#ifdef TCG_TARGET_HAS_div_i32
-DEF2(div_i32, 1, 2, 0, 0)
-DEF2(divu_i32, 1, 2, 0, 0)
-DEF2(rem_i32, 1, 2, 0, 0)
-DEF2(remu_i32, 1, 2, 0, 0)
-#else
-DEF2(div2_i32, 2, 3, 0, 0)
-DEF2(divu2_i32, 2, 3, 0, 0)
-#endif
-DEF2(and_i32, 1, 2, 0, 0)
-DEF2(or_i32, 1, 2, 0, 0)
-DEF2(xor_i32, 1, 2, 0, 0)
-/* shifts */
-DEF2(shl_i32, 1, 2, 0, 0)
-DEF2(shr_i32, 1, 2, 0, 0)
-DEF2(sar_i32, 1, 2, 0, 0)
+DEF(div_i32, 1, 2, 0, 0)
+DEF(divu_i32, 1, 2, 0, 0)
+DEF(rem_i32, 1, 2, 0, 0)
+DEF(remu_i32, 1, 2, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_div2_i32
+DEF(div2_i32, 2, 3, 0, 0)
+DEF(divu2_i32, 2, 3, 0, 0)
+#endif
+DEF(and_i32, 1, 2, 0, 0)
+DEF(or_i32, 1, 2, 0, 0)
+DEF(xor_i32, 1, 2, 0, 0)
+/* shifts/rotates */
+DEF(shl_i32, 1, 2, 0, 0)
+DEF(shr_i32, 1, 2, 0, 0)
+DEF(sar_i32, 1, 2, 0, 0)
+#ifdef TCG_TARGET_HAS_rot_i32
+DEF(rotl_i32, 1, 2, 0, 0)
+DEF(rotr_i32, 1, 2, 0, 0)
+#endif
-DEF2(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+DEF(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
#if TCG_TARGET_REG_BITS == 32
-DEF2(add2_i32, 2, 4, 0, 0)
-DEF2(sub2_i32, 2, 4, 0, 0)
-DEF2(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-DEF2(mulu2_i32, 2, 2, 0, 0)
+DEF(add2_i32, 2, 4, 0, 0)
+DEF(sub2_i32, 2, 4, 0, 0)
+DEF(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+DEF(mulu2_i32, 2, 2, 0, 0)
+DEF(setcond2_i32, 1, 4, 1, 0)
#endif
#ifdef TCG_TARGET_HAS_ext8s_i32
-DEF2(ext8s_i32, 1, 1, 0, 0)
+DEF(ext8s_i32, 1, 1, 0, 0)
#endif
#ifdef TCG_TARGET_HAS_ext16s_i32
-DEF2(ext16s_i32, 1, 1, 0, 0)
+DEF(ext16s_i32, 1, 1, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_ext8u_i32
+DEF(ext8u_i32, 1, 1, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_ext16u_i32
+DEF(ext16u_i32, 1, 1, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_bswap16_i32
+DEF(bswap16_i32, 1, 1, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_bswap32_i32
+DEF(bswap32_i32, 1, 1, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_not_i32
+DEF(not_i32, 1, 1, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_neg_i32
+DEF(neg_i32, 1, 1, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_andc_i32
+DEF(andc_i32, 1, 2, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_orc_i32
+DEF(orc_i32, 1, 2, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_eqv_i32
+DEF(eqv_i32, 1, 2, 0, 0)
#endif
-#ifdef TCG_TARGET_HAS_bswap_i32
-DEF2(bswap_i32, 1, 1, 0, 0)
+#ifdef TCG_TARGET_HAS_nand_i32
+DEF(nand_i32, 1, 2, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_nor_i32
+DEF(nor_i32, 1, 2, 0, 0)
#endif
#if TCG_TARGET_REG_BITS == 64
-DEF2(mov_i64, 1, 1, 0, 0)
-DEF2(movi_i64, 1, 0, 1, 0)
+DEF(mov_i64, 1, 1, 0, 0)
+DEF(movi_i64, 1, 0, 1, 0)
+DEF(setcond_i64, 1, 2, 1, 0)
/* load/store */
-DEF2(ld8u_i64, 1, 1, 1, 0)
-DEF2(ld8s_i64, 1, 1, 1, 0)
-DEF2(ld16u_i64, 1, 1, 1, 0)
-DEF2(ld16s_i64, 1, 1, 1, 0)
-DEF2(ld32u_i64, 1, 1, 1, 0)
-DEF2(ld32s_i64, 1, 1, 1, 0)
-DEF2(ld_i64, 1, 1, 1, 0)
-DEF2(st8_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF2(st16_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF2(st32_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF2(st_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF(ld8u_i64, 1, 1, 1, 0)
+DEF(ld8s_i64, 1, 1, 1, 0)
+DEF(ld16u_i64, 1, 1, 1, 0)
+DEF(ld16s_i64, 1, 1, 1, 0)
+DEF(ld32u_i64, 1, 1, 1, 0)
+DEF(ld32s_i64, 1, 1, 1, 0)
+DEF(ld_i64, 1, 1, 1, 0)
+DEF(st8_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF(st16_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF(st32_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF(st_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
/* arith */
-DEF2(add_i64, 1, 2, 0, 0)
-DEF2(sub_i64, 1, 2, 0, 0)
-DEF2(mul_i64, 1, 2, 0, 0)
+DEF(add_i64, 1, 2, 0, 0)
+DEF(sub_i64, 1, 2, 0, 0)
+DEF(mul_i64, 1, 2, 0, 0)
#ifdef TCG_TARGET_HAS_div_i64
-DEF2(div_i64, 1, 2, 0, 0)
-DEF2(divu_i64, 1, 2, 0, 0)
-DEF2(rem_i64, 1, 2, 0, 0)
-DEF2(remu_i64, 1, 2, 0, 0)
-#else
-DEF2(div2_i64, 2, 3, 0, 0)
-DEF2(divu2_i64, 2, 3, 0, 0)
-#endif
-DEF2(and_i64, 1, 2, 0, 0)
-DEF2(or_i64, 1, 2, 0, 0)
-DEF2(xor_i64, 1, 2, 0, 0)
-/* shifts */
-DEF2(shl_i64, 1, 2, 0, 0)
-DEF2(shr_i64, 1, 2, 0, 0)
-DEF2(sar_i64, 1, 2, 0, 0)
+DEF(div_i64, 1, 2, 0, 0)
+DEF(divu_i64, 1, 2, 0, 0)
+DEF(rem_i64, 1, 2, 0, 0)
+DEF(remu_i64, 1, 2, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_div2_i64
+DEF(div2_i64, 2, 3, 0, 0)
+DEF(divu2_i64, 2, 3, 0, 0)
+#endif
+DEF(and_i64, 1, 2, 0, 0)
+DEF(or_i64, 1, 2, 0, 0)
+DEF(xor_i64, 1, 2, 0, 0)
+/* shifts/rotates */
+DEF(shl_i64, 1, 2, 0, 0)
+DEF(shr_i64, 1, 2, 0, 0)
+DEF(sar_i64, 1, 2, 0, 0)
+#ifdef TCG_TARGET_HAS_rot_i64
+DEF(rotl_i64, 1, 2, 0, 0)
+DEF(rotr_i64, 1, 2, 0, 0)
+#endif
-DEF2(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
#ifdef TCG_TARGET_HAS_ext8s_i64
-DEF2(ext8s_i64, 1, 1, 0, 0)
+DEF(ext8s_i64, 1, 1, 0, 0)
#endif
#ifdef TCG_TARGET_HAS_ext16s_i64
-DEF2(ext16s_i64, 1, 1, 0, 0)
+DEF(ext16s_i64, 1, 1, 0, 0)
#endif
#ifdef TCG_TARGET_HAS_ext32s_i64
-DEF2(ext32s_i64, 1, 1, 0, 0)
+DEF(ext32s_i64, 1, 1, 0, 0)
#endif
-#ifdef TCG_TARGET_HAS_bswap_i64
-DEF2(bswap_i64, 1, 1, 0, 0)
+#ifdef TCG_TARGET_HAS_ext8u_i64
+DEF(ext8u_i64, 1, 1, 0, 0)
#endif
+#ifdef TCG_TARGET_HAS_ext16u_i64
+DEF(ext16u_i64, 1, 1, 0, 0)
#endif
-#ifdef TCG_TARGET_HAS_neg_i32
-DEF2(neg_i32, 1, 1, 0, 0)
+#ifdef TCG_TARGET_HAS_ext32u_i64
+DEF(ext32u_i64, 1, 1, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_bswap16_i64
+DEF(bswap16_i64, 1, 1, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_bswap32_i64
+DEF(bswap32_i64, 1, 1, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_bswap64_i64
+DEF(bswap64_i64, 1, 1, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_not_i64
+DEF(not_i64, 1, 1, 0, 0)
#endif
#ifdef TCG_TARGET_HAS_neg_i64
-DEF2(neg_i64, 1, 1, 0, 0)
+DEF(neg_i64, 1, 1, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_andc_i64
+DEF(andc_i64, 1, 2, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_orc_i64
+DEF(orc_i64, 1, 2, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_eqv_i64
+DEF(eqv_i64, 1, 2, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_nand_i64
+DEF(nand_i64, 1, 2, 0, 0)
+#endif
+#ifdef TCG_TARGET_HAS_nor_i64
+DEF(nor_i64, 1, 2, 0, 0)
+#endif
#endif
/* QEMU specific */
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
-DEF2(debug_insn_start, 0, 0, 2, 0)
+DEF(debug_insn_start, 0, 0, 2, 0)
#else
-DEF2(debug_insn_start, 0, 0, 1, 0)
+DEF(debug_insn_start, 0, 0, 1, 0)
#endif
-DEF2(exit_tb, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-DEF2(goto_tb, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
/* Note: even if TARGET_LONG_BITS is not defined, the INDEX_op
constants must be defined */
#if TCG_TARGET_REG_BITS == 32
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#else
-DEF2(qemu_ld8u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#endif
-#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld8s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld8u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld16u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld8s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld16s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld16u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld32u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld16s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld32, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld32s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld32, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld64, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld64, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld64, 2, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld64, 2, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_st8, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_st8, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_st16, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_st16, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_st32, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_st32, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_st64, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_st64, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_st64, 0, 4, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_st64, 0, 4, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#else /* TCG_TARGET_REG_BITS == 32 */
-DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_ld64, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld32, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_ld64, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_st64, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF(qemu_st64, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif /* TCG_TARGET_REG_BITS != 32 */
-#undef DEF2
+#undef DEF
diff --git a/src/recompiler/tcg/tcg-runtime.h b/src/recompiler/tcg/tcg-runtime.h
new file mode 100644
index 000000000..5615b133e
--- /dev/null
+++ b/src/recompiler/tcg/tcg-runtime.h
@@ -0,0 +1,18 @@
+#ifndef TCG_RUNTIME_H
+#define TCG_RUNTIME_H
+
+/* tcg-runtime.c */
+int32_t tcg_helper_div_i32(int32_t arg1, int32_t arg2);
+int32_t tcg_helper_rem_i32(int32_t arg1, int32_t arg2);
+uint32_t tcg_helper_divu_i32(uint32_t arg1, uint32_t arg2);
+uint32_t tcg_helper_remu_i32(uint32_t arg1, uint32_t arg2);
+
+int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2);
+int64_t tcg_helper_shr_i64(int64_t arg1, int64_t arg2);
+int64_t tcg_helper_sar_i64(int64_t arg1, int64_t arg2);
+int64_t tcg_helper_div_i64(int64_t arg1, int64_t arg2);
+int64_t tcg_helper_rem_i64(int64_t arg1, int64_t arg2);
+uint64_t tcg_helper_divu_i64(uint64_t arg1, uint64_t arg2);
+uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2);
+
+#endif
diff --git a/src/recompiler/tcg/tcg.c b/src/recompiler/tcg/tcg.c
index e3d1428b3..ef8b1ee9f 100644
--- a/src/recompiler/tcg/tcg.c
+++ b/src/recompiler/tcg/tcg.c
@@ -22,31 +22,39 @@
* THE SOFTWARE.
*/
-/* define it to suppress various consistency checks (faster) */
-#define NDEBUG
-
/* define it to use liveness analysis (better code) */
#define USE_LIVENESS_ANALYSIS
+#include "config.h"
+
+#if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
+/* define it to suppress various consistency checks (faster) */
+#define NDEBUG
+#endif
+
#ifndef VBOX
-#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
-#else
-#include <stdio.h>
-#include "osdep.h"
-#endif
#ifdef _WIN32
#include <malloc.h>
#endif
+#ifdef _AIX
+#include <alloca.h>
+#endif
+#else /* VBOX */
+# include <stdio.h>
+# include "osdep.h"
+#endif /* VBOX */
-#include "config.h"
#include "qemu-common.h"
+#include "cache-utils.h"
+#include "host-utils.h"
+#include "qemu-timer.h"
-/* Note: the long term plan is to reduce the dependencies on the QEMU
+/* Note: the long term plan is to reduce the dependancies on the QEMU
CPU definitions. Currently they are used for qemu_ld/st
instructions */
#define NO_CPU_IO_DEFS
@@ -56,65 +64,51 @@
#include "tcg-op.h"
#include "elf.h"
+#if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE)
+#error GUEST_BASE not supported on this host.
+#endif
#ifdef VBOX
/*
* Liveness analysis doesn't work well with 32-bit hosts and 64-bit targets,
* second element of the register pair to store 64-bit value is considered
- * dead, it seems.
- * @todo: fix it in compiler
- */
-#if defined(TARGET_X86_64) && (TCG_TARGET_REG_BITS == 32)
-#undef USE_LIVENESS_ANALYSIS
-#endif
-#endif
+ * dead, it seems. */
+ /** @todo re-test this */
+# if defined(TARGET_X86_64) && (TCG_TARGET_REG_BITS == 32)
+# undef USE_LIVENESS_ANALYSIS
+# endif
+#endif /* VBOX */
+static void tcg_target_init(TCGContext *s);
+static void tcg_target_qemu_prologue(TCGContext *s);
static void patch_reloc(uint8_t *code_ptr, int type,
tcg_target_long value, tcg_target_long addend);
-TCGOpDef tcg_op_defs[] = {
-#define DEF(s, n, copy_size) { #s, 0, 0, n, n, 0, copy_size },
-#ifndef VBOX
-#define DEF2(s, iargs, oargs, cargs, flags) { #s, iargs, oargs, cargs, iargs + oargs + cargs, flags, 0 },
-#else
-#define DEF2(s, iargs, oargs, cargs, flags) { #s, iargs, oargs, cargs, iargs + oargs + cargs, flags, 0, 0, 0 },
-#endif
+static TCGOpDef tcg_op_defs[] = {
+#define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
#include "tcg-opc.h"
#undef DEF
-#undef DEF2
};
-TCGRegSet tcg_target_available_regs[2];
-TCGRegSet tcg_target_call_clobber_regs;
+static TCGRegSet tcg_target_available_regs[2];
+static TCGRegSet tcg_target_call_clobber_regs;
/* XXX: move that inside the context */
uint16_t *gen_opc_ptr;
TCGArg *gen_opparam_ptr;
-#ifndef VBOX
static inline void tcg_out8(TCGContext *s, uint8_t v)
-#else /* VBOX */
-DECLINLINE(void) tcg_out8(TCGContext *s, uint8_t v)
-#endif /* VBOX */
{
*s->code_ptr++ = v;
}
-#ifndef VBOX
static inline void tcg_out16(TCGContext *s, uint16_t v)
-#else /* VBOX */
-DECLINLINE(void) tcg_out16(TCGContext *s, uint16_t v)
-#endif /* VBOX */
{
*(uint16_t *)s->code_ptr = v;
s->code_ptr += 2;
}
-#ifndef VBOX
static inline void tcg_out32(TCGContext *s, uint32_t v)
-#else /* VBOX */
-DECLINLINE(void) tcg_out32(TCGContext *s, uint32_t v)
-#endif /* VBOX */
{
*(uint32_t *)s->code_ptr = v;
s->code_ptr += 4;
@@ -122,8 +116,8 @@ DECLINLINE(void) tcg_out32(TCGContext *s, uint32_t v)
/* label relocation processing */
-void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
- int label_index, long addend)
+static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
+ int label_index, long addend)
{
TCGLabel *l;
TCGRelocation *r;
@@ -262,7 +256,10 @@ void tcg_context_init(TCGContext *s)
}
tcg_target_init(s);
+}
+void tcg_prologue_init(TCGContext *s)
+{
/* init global prologue and epilogue */
s->code_buf = code_gen_prologue;
s->code_ptr = s->code_buf;
@@ -294,17 +291,14 @@ void tcg_func_start(TCGContext *s)
gen_opparam_ptr = gen_opparam_buf;
}
-#ifndef VBOX
static inline void tcg_temp_alloc(TCGContext *s, int n)
-#else /* VBOX */
-DECLINLINE(void) tcg_temp_alloc(TCGContext *s, int n)
-#endif /* VBOX */
{
if (n > TCG_MAX_TEMPS)
tcg_abort();
}
-TCGv tcg_global_reg_new(TCGType type, int reg, const char *name)
+static inline int tcg_global_reg_new_internal(TCGType type, int reg,
+ const char *name)
{
TCGContext *s = &tcg_ctx;
TCGTemp *ts;
@@ -326,48 +320,28 @@ TCGv tcg_global_reg_new(TCGType type, int reg, const char *name)
ts->name = name;
s->nb_globals++;
tcg_regset_set_reg(s->reserved_regs, reg);
- return MAKE_TCGV(idx);
+ return idx;
}
-#if TCG_TARGET_REG_BITS == 32
-/* temporary hack to avoid register shortage for tcg_qemu_st64() */
-TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2,
- const char *name)
+TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
{
- TCGContext *s = &tcg_ctx;
- TCGTemp *ts;
int idx;
- char buf[64];
- if (type != TCG_TYPE_I64)
- tcg_abort();
- idx = s->nb_globals;
- tcg_temp_alloc(s, s->nb_globals + 2);
- ts = &s->temps[s->nb_globals];
- ts->base_type = type;
- ts->type = TCG_TYPE_I32;
- ts->fixed_reg = 1;
- ts->reg = reg1;
- pstrcpy(buf, sizeof(buf), name);
- pstrcat(buf, sizeof(buf), "_0");
- ts->name = strdup(buf);
+ idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
+ return MAKE_TCGV_I32(idx);
+}
- ts++;
- ts->base_type = type;
- ts->type = TCG_TYPE_I32;
- ts->fixed_reg = 1;
- ts->reg = reg2;
- pstrcpy(buf, sizeof(buf), name);
- pstrcat(buf, sizeof(buf), "_1");
- ts->name = strdup(buf);
+TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
+{
+ int idx;
- s->nb_globals += 2;
- return MAKE_TCGV(idx);
+ idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
+ return MAKE_TCGV_I64(idx);
}
-#endif
-TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
- const char *name)
+static inline int tcg_global_mem_new_internal(TCGType type, int reg,
+ tcg_target_long offset,
+ const char *name)
{
TCGContext *s = &tcg_ctx;
TCGTemp *ts;
@@ -423,10 +397,28 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
ts->name = name;
s->nb_globals++;
}
- return MAKE_TCGV(idx);
+ return idx;
+}
+
+TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
+ const char *name)
+{
+ int idx;
+
+ idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
+ return MAKE_TCGV_I32(idx);
}
-TCGv tcg_temp_new_internal(TCGType type, int temp_local)
+TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
+ const char *name)
+{
+ int idx;
+
+ idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
+ return MAKE_TCGV_I64(idx);
+}
+
+static inline int tcg_temp_new_internal(TCGType type, int temp_local)
{
TCGContext *s = &tcg_ctx;
TCGTemp *ts;
@@ -474,14 +466,29 @@ TCGv tcg_temp_new_internal(TCGType type, int temp_local)
s->nb_temps++;
}
}
- return MAKE_TCGV(idx);
+ return idx;
+}
+
+TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
+{
+ int idx;
+
+ idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
+ return MAKE_TCGV_I32(idx);
}
-void tcg_temp_free(TCGv arg)
+TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
+{
+ int idx;
+
+ idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
+ return MAKE_TCGV_I64(idx);
+}
+
+static inline void tcg_temp_free_internal(int idx)
{
TCGContext *s = &tcg_ctx;
TCGTemp *ts;
- int idx = GET_TCGV(arg);
int k;
assert(idx >= s->nb_globals && idx < s->nb_temps);
@@ -495,19 +502,44 @@ void tcg_temp_free(TCGv arg)
s->first_free_temp[k] = idx;
}
+void tcg_temp_free_i32(TCGv_i32 arg)
+{
+ tcg_temp_free_internal(GET_TCGV_I32(arg));
+}
-TCGv tcg_const_i32(int32_t val)
+void tcg_temp_free_i64(TCGv_i64 arg)
{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I32);
+ tcg_temp_free_internal(GET_TCGV_I64(arg));
+}
+
+TCGv_i32 tcg_const_i32(int32_t val)
+{
+ TCGv_i32 t0;
+ t0 = tcg_temp_new_i32();
+ tcg_gen_movi_i32(t0, val);
+ return t0;
+}
+
+TCGv_i64 tcg_const_i64(int64_t val)
+{
+ TCGv_i64 t0;
+ t0 = tcg_temp_new_i64();
+ tcg_gen_movi_i64(t0, val);
+ return t0;
+}
+
+TCGv_i32 tcg_const_local_i32(int32_t val)
+{
+ TCGv_i32 t0;
+ t0 = tcg_temp_local_new_i32();
tcg_gen_movi_i32(t0, val);
return t0;
}
-TCGv tcg_const_i64(int64_t val)
+TCGv_i64 tcg_const_local_i64(int64_t val)
{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I64);
+ TCGv_i64 t0;
+ t0 = tcg_temp_local_new_i64();
tcg_gen_movi_i64(t0, val);
return t0;
}
@@ -523,7 +555,6 @@ void tcg_register_helper(void *func, const char *name)
} else {
n *= 2;
}
-
#ifdef VBOX
s->helpers = qemu_realloc(s->helpers, n * sizeof(TCGHelperInfo));
#else
@@ -536,162 +567,177 @@ void tcg_register_helper(void *func, const char *name)
s->nb_helpers++;
}
-#ifndef VBOX
-static inline TCGType tcg_get_base_type(TCGContext *s, TCGv arg)
-#else /* VBOX */
-DECLINLINE(TCGType) tcg_get_base_type(TCGContext *s, TCGv arg)
-#endif /* VBOX */
-{
- return s->temps[GET_TCGV(arg)].base_type;
-}
-
-static void tcg_gen_call_internal(TCGContext *s, TCGv func,
- unsigned int flags,
- unsigned int nb_rets, const TCGv *rets,
- unsigned int nb_params, const TCGv *params)
-{
-#ifndef VBOX
- int i;
-#else
- unsigned int i;
-#endif
- *gen_opc_ptr++ = INDEX_op_call;
- *gen_opparam_ptr++ = (nb_rets << 16) | (nb_params + 1);
- for(i = 0; i < nb_rets; i++) {
- *gen_opparam_ptr++ = GET_TCGV(rets[i]);
- }
- for(i = 0; i < nb_params; i++) {
- *gen_opparam_ptr++ = GET_TCGV(params[i]);
- }
- *gen_opparam_ptr++ = GET_TCGV(func);
-
- *gen_opparam_ptr++ = flags;
- /* total parameters, needed to go backward in the instruction stream */
- *gen_opparam_ptr++ = 1 + nb_rets + nb_params + 3;
-}
-
-
-#if TCG_TARGET_REG_BITS < 64
/* Note: we convert the 64 bit args to 32 bit and do some alignment
and endian swap. Maybe it would be better to do the alignment
and endian swap in tcg_reg_alloc_call(). */
-void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags,
- unsigned int nb_rets, const TCGv *rets,
- unsigned int nb_params, const TCGv *args1)
+void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
+ int sizemask, TCGArg ret, int nargs, TCGArg *args)
{
- TCGv ret, *args2, rets_2[2], arg;
- int j, i, call_type;
+#ifdef TCG_TARGET_I386
+ int call_type;
+#endif
+ int i;
+ int real_args;
+ int nb_rets;
+ TCGArg *nparam;
+
+#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
+ for (i = 0; i < nargs; ++i) {
+ int is_64bit = sizemask & (1 << (i+1)*2);
+ int is_signed = sizemask & (2 << (i+1)*2);
+ if (!is_64bit) {
+ TCGv_i64 temp = tcg_temp_new_i64();
+ TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
+ if (is_signed) {
+ tcg_gen_ext32s_i64(temp, orig);
+ } else {
+ tcg_gen_ext32u_i64(temp, orig);
+ }
+ args[i] = GET_TCGV_I64(temp);
+ }
+ }
+#endif /* TCG_TARGET_EXTEND_ARGS */
- if (nb_rets == 1) {
- ret = rets[0];
- if (tcg_get_base_type(s, ret) == TCG_TYPE_I64) {
- nb_rets = 2;
+ *gen_opc_ptr++ = INDEX_op_call;
+ nparam = gen_opparam_ptr++;
+#ifdef TCG_TARGET_I386
+ call_type = (flags & TCG_CALL_TYPE_MASK);
+#endif
+ if (ret != TCG_CALL_DUMMY_ARG) {
+#if TCG_TARGET_REG_BITS < 64
+ if (sizemask & 1) {
#ifdef TCG_TARGET_WORDS_BIGENDIAN
- rets_2[0] = TCGV_HIGH(ret);
- rets_2[1] = ret;
+ *gen_opparam_ptr++ = ret + 1;
+ *gen_opparam_ptr++ = ret;
#else
- rets_2[0] = ret;
- rets_2[1] = TCGV_HIGH(ret);
+ *gen_opparam_ptr++ = ret;
+ *gen_opparam_ptr++ = ret + 1;
+#endif
+ nb_rets = 2;
+ } else
#endif
- rets = rets_2;
+ {
+ *gen_opparam_ptr++ = ret;
+ nb_rets = 1;
}
+ } else {
+ nb_rets = 0;
}
- args2 = alloca((nb_params * 3) * sizeof(TCGv));
- j = 0;
- call_type = (flags & TCG_CALL_TYPE_MASK);
- for(i = 0; i < nb_params; i++) {
- arg = args1[i];
- if (tcg_get_base_type(s, arg) == TCG_TYPE_I64) {
+ real_args = 0;
+ for (i = 0; i < nargs; i++) {
+#if TCG_TARGET_REG_BITS < 64
+ int is_64bit = sizemask & (1 << (i+1)*2);
+ if (is_64bit) {
#ifdef TCG_TARGET_I386
/* REGPARM case: if the third parameter is 64 bit, it is
allocated on the stack */
- if (j == 2 && call_type == TCG_CALL_TYPE_REGPARM) {
+ if (i == 2 && call_type == TCG_CALL_TYPE_REGPARM) {
call_type = TCG_CALL_TYPE_REGPARM_2;
flags = (flags & ~TCG_CALL_TYPE_MASK) | call_type;
}
- args2[j++] = arg;
- args2[j++] = TCGV_HIGH(arg);
-#else
+#endif
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
/* some targets want aligned 64 bit args */
- if (j & 1) {
- args2[j++] = TCG_CALL_DUMMY_ARG;
+ if (real_args & 1) {
+ *gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
+ real_args++;
}
#endif
-#ifdef TCG_TARGET_WORDS_BIGENDIAN
- args2[j++] = TCGV_HIGH(arg);
- args2[j++] = arg;
+ /* If stack grows up, then we will be placing successive
+ arguments at lower addresses, which means we need to
+ reverse the order compared to how we would normally
+ treat either big or little-endian. For those arguments
+ that will wind up in registers, this still works for
+ HPPA (the only current STACK_GROWSUP target) since the
+ argument registers are *also* allocated in decreasing
+ order. If another such target is added, this logic may
+ have to get more complicated to differentiate between
+ stack arguments and register arguments. */
+#if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
+ *gen_opparam_ptr++ = args[i] + 1;
+ *gen_opparam_ptr++ = args[i];
#else
- args2[j++] = arg;
- args2[j++] = TCGV_HIGH(arg);
+ *gen_opparam_ptr++ = args[i];
+ *gen_opparam_ptr++ = args[i] + 1;
#endif
-#endif
- } else {
- args2[j++] = arg;
+ real_args += 2;
+ continue;
+ }
+#endif /* TCG_TARGET_REG_BITS < 64 */
+
+ *gen_opparam_ptr++ = args[i];
+ real_args++;
+ }
+ *gen_opparam_ptr++ = GET_TCGV_PTR(func);
+
+ *gen_opparam_ptr++ = flags;
+
+ *nparam = (nb_rets << 16) | (real_args + 1);
+
+ /* total parameters, needed to go backward in the instruction stream */
+ *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
+
+#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
+ for (i = 0; i < nargs; ++i) {
+ int is_64bit = sizemask & (1 << (i+1)*2);
+ if (!is_64bit) {
+ TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
+ tcg_temp_free_i64(temp);
}
}
- tcg_gen_call_internal(s, func, flags,
- nb_rets, rets, j, args2);
+#endif /* TCG_TARGET_EXTEND_ARGS */
}
-#else
-void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags,
- unsigned int nb_rets, const TCGv *rets,
- unsigned int nb_params, const TCGv *args1)
-{
- tcg_gen_call_internal(s, func, flags,
- nb_rets, rets, nb_params, args1);
-}
-#endif
#if TCG_TARGET_REG_BITS == 32
-void tcg_gen_shifti_i64(TCGv ret, TCGv arg1,
+void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
int c, int right, int arith)
{
if (c == 0) {
- tcg_gen_mov_i32(ret, arg1);
+ tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
} else if (c >= 32) {
c -= 32;
if (right) {
if (arith) {
- tcg_gen_sari_i32(ret, TCGV_HIGH(arg1), c);
+ tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
} else {
- tcg_gen_shri_i32(ret, TCGV_HIGH(arg1), c);
+ tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
}
} else {
- tcg_gen_shli_i32(TCGV_HIGH(ret), arg1, c);
- tcg_gen_movi_i32(ret, 0);
+ tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
+ tcg_gen_movi_i32(TCGV_LOW(ret), 0);
}
} else {
- TCGv t0, t1;
+ TCGv_i32 t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- t1 = tcg_temp_new(TCG_TYPE_I32);
+ t0 = tcg_temp_new_i32();
+ t1 = tcg_temp_new_i32();
if (right) {
tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
if (arith)
tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
else
tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
- tcg_gen_shri_i32(ret, arg1, c);
- tcg_gen_or_i32(ret, ret, t0);
+ tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
+ tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
} else {
- tcg_gen_shri_i32(t0, arg1, 32 - c);
+ tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
/* Note: ret can be the same as arg1, so we use t1 */
- tcg_gen_shli_i32(t1, arg1, c);
+ tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
- tcg_gen_mov_i32(ret, t1);
+ tcg_gen_mov_i32(TCGV_LOW(ret), t1);
}
- tcg_temp_free(t0);
- tcg_temp_free(t1);
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
}
}
#endif
+
static void tcg_reg_alloc_start(TCGContext *s)
{
int i;
@@ -732,9 +778,14 @@ static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
return buf;
}
-char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg)
+char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
+{
+ return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
+}
+
+char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
{
- return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV(arg));
+ return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
}
static int helper_cmp(const void *p1, const void *p2)
@@ -785,7 +836,6 @@ static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
return NULL;
}
-#ifndef VBOX
static const char * const cond_name[] =
{
[TCG_COND_EQ] = "eq",
@@ -799,28 +849,14 @@ static const char * const cond_name[] =
[TCG_COND_LEU] = "leu",
[TCG_COND_GTU] = "gtu"
};
-#else
-static const char * const cond_name[] =
-{
- "eq",
- "ne",
- "lt",
- "ge",
- "le",
- "gt",
- "ltu",
- "geu",
- "leu",
- "gtu"
-};
-#endif
void tcg_dump_ops(TCGContext *s, FILE *outfile)
{
const uint16_t *opc_ptr;
const TCGArg *args;
TCGArg arg;
- int c, i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
+ TCGOpcode c;
+ int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
const TCGOpDef *def;
char buf[128];
@@ -893,7 +929,7 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
val = args[1];
th = tcg_find_helper(s, val);
if (th) {
- fprintf(outfile, th->name);
+ fprintf(outfile, "%s", th->name);
} else {
if (c == INDEX_op_movi_i32)
fprintf(outfile, "0x%x", (uint32_t)val);
@@ -926,21 +962,29 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
fprintf(outfile, "%s",
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
}
- if (c == INDEX_op_brcond_i32
+ switch (c) {
+ case INDEX_op_brcond_i32:
#if TCG_TARGET_REG_BITS == 32
- || c == INDEX_op_brcond2_i32
+ case INDEX_op_brcond2_i32:
#elif TCG_TARGET_REG_BITS == 64
- || c == INDEX_op_brcond_i64
+ case INDEX_op_brcond_i64:
+#endif
+ case INDEX_op_setcond_i32:
+#if TCG_TARGET_REG_BITS == 32
+ case INDEX_op_setcond2_i32:
+#elif TCG_TARGET_REG_BITS == 64
+ case INDEX_op_setcond_i64:
#endif
- ) {
if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]])
fprintf(outfile, ",%s", cond_name[args[k++]]);
else
fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]);
i = 1;
- }
- else
+ break;
+ default:
i = 0;
+ break;
+ }
for(; i < nb_cargs; i++) {
if (k != 0)
fprintf(outfile, ",");
@@ -999,20 +1043,27 @@ static void sort_constraints(TCGOpDef *def, int start, int n)
void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
{
- int op;
+ TCGOpcode op;
TCGOpDef *def;
const char *ct_str;
int i, nb_args;
for(;;) {
- if (tdefs->op < 0)
+ if (tdefs->op == (TCGOpcode)-1)
break;
op = tdefs->op;
assert(op >= 0 && op < NB_OPS);
def = &tcg_op_defs[op];
+#if defined(CONFIG_DEBUG_TCG)
+ /* Duplicate entry in op definitions? */
+ assert(!def->used);
+ def->used = 1;
+#endif
nb_args = def->nb_iargs + def->nb_oargs;
for(i = 0; i < nb_args; i++) {
ct_str = tdefs->args_ct_str[i];
+ /* Incomplete TCGTargetOpDef entry? */
+ assert(ct_str != NULL);
tcg_regset_clear(def->args_ct[i].u.regs);
def->args_ct[i].ct = 0;
if (ct_str[0] >= '0' && ct_str[0] <= '9') {
@@ -1040,10 +1091,10 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
ct_str, i, def->name);
-#ifdef VBOX
- tcg_exit(1);
-#else
+#ifndef VBOX
exit(1);
+#else
+ tcg_exit(1);
#endif
}
}
@@ -1051,6 +1102,9 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
}
}
+ /* TCGTargetOpDef entry with too much information? */
+ assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
+
/* sort the constraints (XXX: this is just an heuristic) */
sort_constraints(def, 0, def->nb_oargs);
sort_constraints(def, def->nb_oargs, def->nb_iargs);
@@ -1068,16 +1122,35 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
tdefs++;
}
+#if defined(CONFIG_DEBUG_TCG)
+ i = 0;
+ for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
+ if (op < INDEX_op_call || op == INDEX_op_debug_insn_start) {
+ /* Wrong entry in op definitions? */
+ if (tcg_op_defs[op].used) {
+ fprintf(stderr, "Invalid op definition for %s\n",
+ tcg_op_defs[op].name);
+ i = 1;
+ }
+ } else {
+ /* Missing entry in op definitions? */
+ if (!tcg_op_defs[op].used) {
+ fprintf(stderr, "Missing op definition for %s\n",
+ tcg_op_defs[op].name);
+ i = 1;
+ }
+ }
+ }
+ if (i == 1) {
+ tcg_abort();
+ }
+#endif
}
#ifdef USE_LIVENESS_ANALYSIS
/* set a nop for an operation using 'nb_args' */
-#ifndef VBOX
static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
-#else /* VBOX */
-DECLINLINE(void) tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
-#endif /* VBOX */
TCGArg *args, int nb_args)
{
if (nb_args == 0) {
@@ -1093,11 +1166,7 @@ DECLINLINE(void) tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
dead. */
/* XXX: at this stage, not used as there would be little gains because
most TBs end with a conditional jump. */
-#ifndef VBOX
static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
-#else /* VBOX */
-DECLINLINE(void) tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
-#endif /* VBOX */
{
memset(dead_temps, 0, s->nb_globals);
memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals);
@@ -1105,11 +1174,7 @@ DECLINLINE(void) tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
/* liveness analysis: end of basic block: globals are live, temps are
dead, local temps are live. */
-#ifndef VBOX
static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
-#else /* VBOX */
-DECLINLINE(void) tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
-#endif /* VBOX */
{
int i;
TCGTemp *ts;
@@ -1130,7 +1195,8 @@ DECLINLINE(void) tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
temporaries are removed. */
static void tcg_liveness_analysis(TCGContext *s)
{
- int i, op_index, op, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
+ int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
+ TCGOpcode op;
TCGArg *args;
const TCGOpDef *def;
uint8_t *dead_temps;
@@ -1140,8 +1206,7 @@ static void tcg_liveness_analysis(TCGContext *s)
nb_ops = gen_opc_ptr - gen_opc_buf;
- /* XXX: make it really dynamic */
- s->op_dead_iargs = tcg_malloc(OPC_BUF_SIZE * sizeof(uint16_t));
+ s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
dead_temps = tcg_malloc(s->nb_temps);
memset(dead_temps, 1, s->nb_temps);
@@ -1182,8 +1247,10 @@ static void tcg_liveness_analysis(TCGContext *s)
dead_temps[arg] = 1;
}
- /* globals are live (they may be used by the call) */
- memset(dead_temps, 0, s->nb_globals);
+ if (!(call_flags & TCG_CALL_CONST)) {
+ /* globals are live (they may be used by the call) */
+ memset(dead_temps, 0, s->nb_globals);
+ }
/* input args are live */
dead_iargs = 0;
@@ -1222,57 +1289,50 @@ static void tcg_liveness_analysis(TCGContext *s)
break;
/* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
default:
- if (op > INDEX_op_end) {
- args -= def->nb_args;
- nb_iargs = def->nb_iargs;
- nb_oargs = def->nb_oargs;
+ args -= def->nb_args;
+ nb_iargs = def->nb_iargs;
+ nb_oargs = def->nb_oargs;
- /* Test if the operation can be removed because all
- its outputs are dead. We assume that nb_oargs == 0
- implies side effects */
- if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
- for(i = 0; i < nb_oargs; i++) {
- arg = args[i];
- if (!dead_temps[arg])
- goto do_not_remove;
- }
- tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
+ /* Test if the operation can be removed because all
+ its outputs are dead. We assume that nb_oargs == 0
+ implies side effects */
+ if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
+ for(i = 0; i < nb_oargs; i++) {
+ arg = args[i];
+ if (!dead_temps[arg])
+ goto do_not_remove;
+ }
+ tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
#ifdef CONFIG_PROFILER
- s->del_op_count++;
+ s->del_op_count++;
#endif
- } else {
- do_not_remove:
+ } else {
+ do_not_remove:
- /* output args are dead */
- for(i = 0; i < nb_oargs; i++) {
- arg = args[i];
- dead_temps[arg] = 1;
- }
+ /* output args are dead */
+ for(i = 0; i < nb_oargs; i++) {
+ arg = args[i];
+ dead_temps[arg] = 1;
+ }
- /* if end of basic block, update */
- if (def->flags & TCG_OPF_BB_END) {
- tcg_la_bb_end(s, dead_temps);
- } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
- /* globals are live */
- memset(dead_temps, 0, s->nb_globals);
- }
+ /* if end of basic block, update */
+ if (def->flags & TCG_OPF_BB_END) {
+ tcg_la_bb_end(s, dead_temps);
+ } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
+ /* globals are live */
+ memset(dead_temps, 0, s->nb_globals);
+ }
- /* input args are live */
- dead_iargs = 0;
- for(i = 0; i < nb_iargs; i++) {
- arg = args[i + nb_oargs];
- if (dead_temps[arg]) {
- dead_iargs |= (1 << i);
- }
- dead_temps[arg] = 0;
+ /* input args are live */
+ dead_iargs = 0;
+ for(i = 0; i < nb_iargs; i++) {
+ arg = args[i + nb_oargs];
+ if (dead_temps[arg]) {
+ dead_iargs |= (1 << i);
}
- s->op_dead_iargs[op_index] = dead_iargs;
+ dead_temps[arg] = 0;
}
- } else {
- /* legacy dyngen operations */
- args -= def->nb_args;
- /* mark end of basic block */
- tcg_la_bb_end(s, dead_temps);
+ s->op_dead_iargs[op_index] = dead_iargs;
}
break;
}
@@ -1284,7 +1344,7 @@ static void tcg_liveness_analysis(TCGContext *s)
}
#else
/* dummy liveness analysis */
-void tcg_liveness_analysis(TCGContext *s)
+static void tcg_liveness_analysis(TCGContext *s)
{
int nb_ops;
nb_ops = gen_opc_ptr - gen_opc_buf;
@@ -1375,7 +1435,7 @@ static void temp_allocate_frame(TCGContext *s, int temp)
#ifndef VBOX
if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
#else
- if ((unsigned)s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
+ if ((tcg_target_long)s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
#endif
tcg_abort();
ts->mem_offset = s->current_frame_offset;
@@ -1464,7 +1524,7 @@ static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
}
}
-/* save globals to their canonical location and assume they can be
+/* save globals to their cannonical location and assume they can be
modified be the following code. 'allocated_regs' is used in case a
temporary registers needs to be allocated to store a constant. */
static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
@@ -1549,7 +1609,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
}
if (ts->reg != reg) {
- tcg_out_mov(s, reg, ts->reg);
+ tcg_out_mov(s, ots->type, reg, ts->reg);
}
}
} else if (ts->val_type == TEMP_VAL_MEM) {
@@ -1581,7 +1641,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
}
static void tcg_reg_alloc_op(TCGContext *s,
- const TCGOpDef *def, int opc,
+ const TCGOpDef *def, TCGOpcode opc,
const TCGArg *args,
unsigned int dead_iargs)
{
@@ -1654,7 +1714,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
/* allocate a new register matching the constraint
and move the temporary register into it */
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_mov(s, reg, ts->reg);
+ tcg_out_mov(s, ts->type, reg, ts->reg);
}
new_args[i] = reg;
const_args[i] = 0;
@@ -1736,7 +1796,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
ts = &s->temps[args[i]];
reg = new_args[i];
if (ts->fixed_reg && ts->reg != reg) {
- tcg_out_mov(s, ts->reg, reg);
+ tcg_out_mov(s, ts->type, ts->reg, reg);
}
}
}
@@ -1748,7 +1808,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
#endif
static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
- int opc, const TCGArg *args,
+ TCGOpcode opc, const TCGArg *args,
unsigned int dead_iargs)
{
int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
@@ -1822,7 +1882,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
tcg_reg_free(s, reg);
if (ts->val_type == TEMP_VAL_REG) {
if (ts->reg != reg) {
- tcg_out_mov(s, reg, ts->reg);
+ tcg_out_mov(s, ts->type, reg, ts->reg);
}
} else if (ts->val_type == TEMP_VAL_MEM) {
tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
@@ -1851,7 +1911,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
reg = ts->reg;
if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_mov(s, reg, ts->reg);
+ tcg_out_mov(s, ts->type, reg, ts->reg);
}
func_arg = reg;
tcg_regset_set_reg(allocated_regs, reg);
@@ -1892,7 +1952,9 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
/* store globals and free associated registers (we assume the call
can modify any global. */
- save_globals(s, allocated_regs);
+ if (!(flags & TCG_CALL_CONST)) {
+ save_globals(s, allocated_regs);
+ }
tcg_out_op(s, opc, &func_arg, &const_func_arg);
@@ -1908,7 +1970,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
assert(s->reg_to_temp[reg] == -1);
if (ts->fixed_reg) {
if (ts->reg != reg) {
- tcg_out_mov(s, ts->reg, reg);
+ tcg_out_mov(s, ts->type, ts->reg, reg);
}
} else {
if (ts->val_type == TEMP_VAL_REG)
@@ -1925,43 +1987,35 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
#ifdef CONFIG_PROFILER
-static int64_t dyngen_table_op_count[NB_OPS];
+static int64_t tcg_table_op_count[NB_OPS];
-void dump_op_count(void)
+static void dump_op_count(void)
{
int i;
FILE *f;
- f = fopen("/tmp/op1.log", "w");
- for(i = 0; i < INDEX_op_end; i++) {
- fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, dyngen_table_op_count[i]);
- }
- fclose(f);
- f = fopen("/tmp/op2.log", "w");
+ f = fopen("/tmp/op.log", "w");
for(i = INDEX_op_end; i < NB_OPS; i++) {
- fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, dyngen_table_op_count[i]);
+ fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
}
fclose(f);
}
#endif
-#ifndef VBOX
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
-#else /* VBOX */
-DECLINLINE(int) tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
-#endif /* VBOX */
long search_pc)
{
- int opc, op_index;
+ TCGOpcode opc;
+ int op_index;
const TCGOpDef *def;
unsigned int dead_iargs;
const TCGArg *args;
#ifdef DEBUG_DISAS
- if (unlikely(loglevel & CPU_LOG_TB_OP)) {
- fprintf(logfile, "OP:\n");
+ if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
+ qemu_log("OP:\n");
tcg_dump_ops(s, logfile);
- fprintf(logfile, "\n");
+ qemu_log("\n");
}
#endif
@@ -1974,12 +2028,13 @@ DECLINLINE(int) tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
#endif
#ifdef DEBUG_DISAS
- if (unlikely(loglevel & CPU_LOG_TB_OP_OPT)) {
- fprintf(logfile, "OP after la:\n");
+# ifdef USE_LIVENESS_ANALYSIS /* vbox */
+ if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
+ qemu_log("OP after liveness analysis:\n");
tcg_dump_ops(s, logfile);
- fprintf(logfile, "\n");
- fflush(logfile);
+ qemu_log("\n");
}
+# endif /* USE_LIVENESS_ANALYSIS - vbox */
#endif
tcg_reg_alloc_start(s);
@@ -1993,7 +2048,7 @@ DECLINLINE(int) tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
for(;;) {
opc = gen_opc_buf[op_index];
#ifdef CONFIG_PROFILER
- dyngen_table_op_count[opc]++;
+ tcg_table_op_count[opc]++;
#endif
def = &tcg_op_defs[opc];
#if 0
@@ -2048,22 +2103,6 @@ DECLINLINE(int) tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
goto next;
case INDEX_op_end:
goto the_end;
-
-#ifdef CONFIG_DYNGEN_OP
- case 0 ... INDEX_op_end - 1:
- /* legacy dyngen ops */
-#ifdef CONFIG_PROFILER
- s->old_op_count++;
-#endif
- tcg_reg_alloc_bb_end(s, s->reserved_regs);
- if (search_pc >= 0) {
- s->code_ptr += def->copy_size;
- args += def->nb_args;
- } else {
- args = dyngen_op(s, opc, args);
- }
- goto next;
-#endif
default:
/* Note: in order to speed up the code, it would be much
faster to have specialized register allocator functions for
@@ -2086,7 +2125,7 @@ DECLINLINE(int) tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
return -1;
}
-int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
+int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
{
#ifdef CONFIG_PROFILER
{
@@ -2114,7 +2153,7 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
offset bytes from the start of the TB. The contents of gen_code_buf must
not be changed, though writing the same values is ok.
Return -1 if not found. */
-int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
+int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
{
return tcg_gen_code_common(s, gen_code_buf, offset);
}
@@ -2135,8 +2174,6 @@ void tcg_dump_info(FILE *f,
s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
- cpu_fprintf(f, "old ops/total ops %0.1f%%\n",
- s->op_count ? (double)s->old_op_count / s->op_count * 100.0 : 0);
cpu_fprintf(f, "deleted ops/TB %0.2f\n",
s->tb_count ?
(double)s->del_op_count / s->tb_count : 0);
@@ -2163,10 +2200,8 @@ void tcg_dump_info(FILE *f,
s->restore_count);
cpu_fprintf(f, " avg cycles %0.1f\n",
s->restore_count ? (double)s->restore_time / s->restore_count : 0);
- {
- extern void dump_op_count(void);
- dump_op_count();
- }
+
+ dump_op_count();
}
#else
void tcg_dump_info(FILE *f,
diff --git a/src/recompiler/tcg/tcg.h b/src/recompiler/tcg/tcg.h
index bc0d025c4..6008c0df2 100644
--- a/src/recompiler/tcg/tcg.h
+++ b/src/recompiler/tcg/tcg.h
@@ -21,8 +21,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-
+#include "qemu-common.h"
#include "tcg-target.h"
+#include "tcg-runtime.h"
#if TCG_TARGET_REG_BITS == 32
typedef int32_t tcg_target_long;
@@ -46,18 +47,18 @@ typedef uint64_t TCGRegSet;
#error unsupported
#endif
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
+typedef enum TCGOpcode {
+#define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
#include "tcg-opc.h"
#undef DEF
NB_OPS,
-};
+} TCGOpcode;
#define tcg_regset_clear(d) (d) = 0
#define tcg_regset_set(d, s) (d) = (s)
#define tcg_regset_set32(d, reg, val32) (d) |= (val32) << (reg)
-#define tcg_regset_set_reg(d, r) (d) |= 1 << (r)
-#define tcg_regset_reset_reg(d, r) (d) &= ~(1 << (r))
+#define tcg_regset_set_reg(d, r) (d) |= 1L << (r)
+#define tcg_regset_reset_reg(d, r) (d) &= ~(1L << (r))
#define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
#define tcg_regset_or(d, a, b) (d) = (a) | (b)
#define tcg_regset_and(d, a, b) (d) = (a) & (b)
@@ -82,11 +83,7 @@ typedef struct TCGLabel {
typedef struct TCGPool {
struct TCGPool *next;
int size;
-#ifndef VBOX
uint8_t data[0] __attribute__ ((aligned));
-#else
- ALIGNED_MEMBER_DEF(uint8_t, data[0]);
-#endif
} TCGPool;
#define TCG_POOL_CHUNK_SIZE 32768
@@ -99,57 +96,93 @@ typedef struct TCGPool {
this value, they are statically allocated in the TB stack frame */
#define TCG_STATIC_CALL_ARGS_SIZE 128
-typedef int TCGType;
-
-#define TCG_TYPE_I32 0
-#define TCG_TYPE_I64 1
-#define TCG_TYPE_COUNT 2 /* number of different types */
+typedef enum TCGType {
+ TCG_TYPE_I32,
+ TCG_TYPE_I64,
+ TCG_TYPE_COUNT, /* number of different types */
+ /* An alias for the size of the host register. */
#if TCG_TARGET_REG_BITS == 32
-#define TCG_TYPE_PTR TCG_TYPE_I32
+ TCG_TYPE_REG = TCG_TYPE_I32,
+#else
+ TCG_TYPE_REG = TCG_TYPE_I64,
+#endif
+
+ /* An alias for the size of the native pointer. We don't currently
+ support any hosts with 64-bit registers and 32-bit pointers. */
+ TCG_TYPE_PTR = TCG_TYPE_REG,
+
+ /* An alias for the size of the target "long", aka register. */
+#if TARGET_LONG_BITS == 64
+ TCG_TYPE_TL = TCG_TYPE_I64,
#else
-#define TCG_TYPE_PTR TCG_TYPE_I64
+ TCG_TYPE_TL = TCG_TYPE_I32,
#endif
+} TCGType;
typedef tcg_target_ulong TCGArg;
-/* Define a type and accessor macros for variables. Using a struct is
+/* Define a type and accessor macros for varables. Using a struct is
nice because it gives some level of type safely. Ideally the compiler
be able to see through all this. However in practice this is not true,
expecially on targets with braindamaged ABIs (e.g. i386).
We use plain int by default to avoid this runtime overhead.
Users of tcg_gen_* don't need to know about any of this, and should
- treat TCGv as an opaque type. */
+ treat TCGv as an opaque type.
+ In additon we do typechecking for different types of variables. TCGv_i32
+ and TCGv_i64 are 32/64-bit variables respectively. TCGv and TCGv_ptr
+ are aliases for target_ulong and host pointer sized values respectively.
+ */
-//#define DEBUG_TCGV 1
+#ifdef CONFIG_DEBUG_TCG
+#define DEBUG_TCGV 1
+#endif
#ifdef DEBUG_TCGV
typedef struct
{
- int n;
-} TCGv;
+ int i32;
+} TCGv_i32;
-#define MAKE_TCGV(i) __extension__ \
- ({ TCGv make_tcgv_tmp = {i}; make_tcgv_tmp;})
-#define GET_TCGV(t) ((t).n)
+typedef struct
+{
+ int i64;
+} TCGv_i64;
+
+#define MAKE_TCGV_I32(i) __extension__ \
+ ({ TCGv_i32 make_tcgv_tmp = {i}; make_tcgv_tmp;})
+#define MAKE_TCGV_I64(i) __extension__ \
+ ({ TCGv_i64 make_tcgv_tmp = {i}; make_tcgv_tmp;})
+#define GET_TCGV_I32(t) ((t).i32)
+#define GET_TCGV_I64(t) ((t).i64)
#if TCG_TARGET_REG_BITS == 32
-#define TCGV_HIGH(t) MAKE_TCGV(GET_TCGV(t) + 1)
+#define TCGV_LOW(t) MAKE_TCGV_I32(GET_TCGV_I64(t))
+#define TCGV_HIGH(t) MAKE_TCGV_I32(GET_TCGV_I64(t) + 1)
#endif
#else /* !DEBUG_TCGV */
-typedef int TCGv;
-#define MAKE_TCGV(x) (x)
-#define GET_TCGV(t) (t)
+typedef int TCGv_i32;
+typedef int TCGv_i64;
+#define MAKE_TCGV_I32(x) (x)
+#define MAKE_TCGV_I64(x) (x)
+#define GET_TCGV_I32(t) (t)
+#define GET_TCGV_I64(t) (t)
+
#if TCG_TARGET_REG_BITS == 32
+#define TCGV_LOW(t) (t)
#define TCGV_HIGH(t) ((t) + 1)
#endif
#endif /* DEBUG_TCGV */
+#define TCGV_EQUAL_I32(a, b) (GET_TCGV_I32(a) == GET_TCGV_I32(b))
+#define TCGV_EQUAL_I64(a, b) (GET_TCGV_I64(a) == GET_TCGV_I64(b))
+
/* Dummy definition to avoid compiler warnings. */
-#define TCGV_UNUSED(x) x = MAKE_TCGV(-1)
+#define TCGV_UNUSED_I32(x) x = MAKE_TCGV_I32(-1)
+#define TCGV_UNUSED_I64(x) x = MAKE_TCGV_I64(-1)
/* call flags */
#define TCG_CALL_TYPE_MASK 0x000f
@@ -157,13 +190,17 @@ typedef int TCGv;
#define TCG_CALL_TYPE_REGPARM_1 0x0001 /* i386 style regparm call (1 reg) */
#define TCG_CALL_TYPE_REGPARM_2 0x0002 /* i386 style regparm call (2 regs) */
#define TCG_CALL_TYPE_REGPARM 0x0003 /* i386 style regparm call (3 regs) */
-/* A pure function only reads its arguments and globals variables and
- cannot raise exceptions. Hence a call to a pure function can be
+/* A pure function only reads its arguments and TCG global variables
+ and cannot raise exceptions. Hence a call to a pure function can be
safely suppressed if the return value is not used. */
#define TCG_CALL_PURE 0x0010
+/* A const function only reads its arguments and does not use TCG
+ global variables. Hence a call to such a function does not
+ save TCG global variables back to their canonical location. */
+#define TCG_CALL_CONST 0x0020
/* used to align parameters */
-#define TCG_CALL_DUMMY_TCGV MAKE_TCGV(-1)
+#define TCG_CALL_DUMMY_TCGV MAKE_TCGV_I32(-1)
#define TCG_CALL_DUMMY_ARG ((TCGArg)(-1))
typedef enum {
@@ -180,6 +217,24 @@ typedef enum {
TCG_COND_GTU,
} TCGCond;
+/* Invert the sense of the comparison. */
+static inline TCGCond tcg_invert_cond(TCGCond c)
+{
+ return (TCGCond)(c ^ 1);
+}
+
+/* Swap the operands in a comparison. */
+static inline TCGCond tcg_swap_cond(TCGCond c)
+{
+ int mask = (c < TCG_COND_LT ? 0 : c < TCG_COND_LTU ? 7 : 15);
+ return (TCGCond)(c ^ mask);
+}
+
+static inline TCGCond tcg_unsigned_cond(TCGCond c)
+{
+ return (c >= TCG_COND_LT && c <= TCG_COND_GT ? c + 4 : c);
+}
+
#define TEMP_VAL_DEAD 0
#define TEMP_VAL_REG 1
#define TEMP_VAL_MEM 2
@@ -197,9 +252,9 @@ typedef struct TCGTemp {
unsigned int fixed_reg:1;
unsigned int mem_coherent:1;
unsigned int mem_allocated:1;
- unsigned int temp_local:1; /* If true, the temp is saved across
+ unsigned int temp_local:1; /* If true, the temp is saved accross
basic blocks. Otherwise, it is not
- preserved across basic blocks. */
+ preserved accross basic blocks. */
unsigned int temp_allocated:1; /* never used for code gen */
/* index of next free temp of same base type, -1 if end */
int next_free_temp;
@@ -259,7 +314,6 @@ struct TCGContext {
int op_count_max; /* max insn per TB */
int64_t temp_count;
int temp_count_max;
- int64_t old_op_count;
int64_t del_op_count;
int64_t code_in_len;
int64_t code_out_len;
@@ -283,11 +337,7 @@ void *tcg_malloc_internal(TCGContext *s, int size);
void tcg_pool_reset(TCGContext *s);
void tcg_pool_delete(TCGContext *s);
-#ifndef VBOX
static inline void *tcg_malloc(int size)
-#else
-DECLINLINE(void *) tcg_malloc(int size)
-#endif
{
TCGContext *s = &tcg_ctx;
uint8_t *ptr, *ptr_end;
@@ -303,37 +353,45 @@ DECLINLINE(void *) tcg_malloc(int size)
}
void tcg_context_init(TCGContext *s);
+void tcg_prologue_init(TCGContext *s);
void tcg_func_start(TCGContext *s);
-int dyngen_code(TCGContext *s, uint8_t *gen_code_buf);
-int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
+int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf);
+int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
void tcg_set_frame(TCGContext *s, int reg,
tcg_target_long start, tcg_target_long size);
-TCGv tcg_global_reg_new(TCGType type, int reg, const char *name);
-TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2,
- const char *name);
-TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
- const char *name);
-TCGv tcg_temp_new_internal(TCGType type, int temp_local);
-#ifndef VBOX
-static inline TCGv tcg_temp_new(TCGType type)
-#else
-DECLINLINE(TCGv) tcg_temp_new(TCGType type)
-#endif
+
+TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name);
+TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
+ const char *name);
+TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
+static inline TCGv_i32 tcg_temp_new_i32(void)
{
- return tcg_temp_new_internal(type, 0);
+ return tcg_temp_new_internal_i32(0);
}
-#ifndef VBOX
-static inline TCGv tcg_temp_local_new(TCGType type)
-#else
-DECLINLINE(TCGv) tcg_temp_local_new(TCGType type)
-#endif
+static inline TCGv_i32 tcg_temp_local_new_i32(void)
{
- return tcg_temp_new_internal(type, 1);
+ return tcg_temp_new_internal_i32(1);
}
-void tcg_temp_free(TCGv arg);
-char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg);
+void tcg_temp_free_i32(TCGv_i32 arg);
+char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg);
+
+TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name);
+TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
+ const char *name);
+TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
+static inline TCGv_i64 tcg_temp_new_i64(void)
+{
+ return tcg_temp_new_internal_i64(0);
+}
+static inline TCGv_i64 tcg_temp_local_new_i64(void)
+{
+ return tcg_temp_new_internal_i64(1);
+}
+void tcg_temp_free_i64(TCGv_i64 arg);
+char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg);
+
void tcg_dump_info(FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
@@ -364,102 +422,91 @@ typedef struct TCGOpDef {
const char *name;
uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
uint8_t flags;
- uint16_t copy_size;
TCGArgConstraint *args_ct;
int *sorted_args;
+#if defined(CONFIG_DEBUG_TCG)
+ int used;
+#endif
} TCGOpDef;
typedef struct TCGTargetOpDef {
- int op;
+ TCGOpcode op;
const char *args_ct_str[TCG_MAX_OP_ARGS];
} TCGTargetOpDef;
-extern TCGOpDef tcg_op_defs[];
-
-void tcg_target_init(TCGContext *s);
-void tcg_target_qemu_prologue(TCGContext *s);
-
#ifndef VBOX
#define tcg_abort() \
do {\
fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
abort();\
} while (0)
-#else
-#define VBOX_STR(x) #x
-#define VBOX_XSTR(x) VBOX_STR(x)
-#define tcg_abort() \
-do {\
- remAbort(-1, "TCG fatal error: "__FILE__":"VBOX_XSTR(__LINE__)); \
-} while (0)
+#else /* VBOX */
+# define tcg_abort() \
+ do {\
+ remAbort(-1, "TCG fatal error: "__FILE__":" RT_XSTR(__LINE__)); \
+ } while (0)
extern void qemu_qsort(void* base, size_t nmemb, size_t size,
int(*compar)(const void*, const void*));
#define tcg_exit(status) \
-do {\
- remAbort(-1, "TCG exit: "__FILE__":"VBOX_XSTR(__LINE__));\
-} while (0)
-#endif
+ do {\
+ remAbort(-1, "TCG exit: "__FILE__":" RT_XSTR(__LINE__));\
+ } while (0)
+#endif /* VBOX */
void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
-void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags,
- unsigned int nb_rets, const TCGv *rets,
- unsigned int nb_params, const TCGv *args1);
-void tcg_gen_shifti_i64(TCGv ret, TCGv arg1,
- int c, int right, int arith);
-
-/* only used for debugging purposes */
-void tcg_register_helper(void *func, const char *name);
-#define TCG_HELPER(func) tcg_register_helper(func, #func)
-const char *tcg_helper_get_name(TCGContext *s, void *func);
-void tcg_dump_ops(TCGContext *s, FILE *outfile);
-
-void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
-TCGv tcg_const_i32(int32_t val);
-TCGv tcg_const_i64(int64_t val);
-
#if TCG_TARGET_REG_BITS == 32
#define tcg_const_ptr tcg_const_i32
#define tcg_add_ptr tcg_add_i32
#define tcg_sub_ptr tcg_sub_i32
+#define TCGv_ptr TCGv_i32
+#define GET_TCGV_PTR GET_TCGV_I32
+#define tcg_global_reg_new_ptr tcg_global_reg_new_i32
+#define tcg_global_mem_new_ptr tcg_global_mem_new_i32
+#define tcg_temp_new_ptr tcg_temp_new_i32
+#define tcg_temp_free_ptr tcg_temp_free_i32
#else
#define tcg_const_ptr tcg_const_i64
#define tcg_add_ptr tcg_add_i64
#define tcg_sub_ptr tcg_sub_i64
+#define TCGv_ptr TCGv_i64
+#define GET_TCGV_PTR GET_TCGV_I64
+#define tcg_global_reg_new_ptr tcg_global_reg_new_i64
+#define tcg_global_mem_new_ptr tcg_global_mem_new_i64
+#define tcg_temp_new_ptr tcg_temp_new_i64
+#define tcg_temp_free_ptr tcg_temp_free_i64
#endif
-void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
- int label_index, long addend);
-const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1,
- unsigned int dead_iargs);
+void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
+ int sizemask, TCGArg ret, int nargs, TCGArg *args);
-const TCGArg *dyngen_op(TCGContext *s, int opc, const TCGArg *opparam_ptr);
+void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
+ int c, int right, int arith);
-/* tcg-runtime.c */
-int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2);
-int64_t tcg_helper_shr_i64(int64_t arg1, int64_t arg2);
-int64_t tcg_helper_sar_i64(int64_t arg1, int64_t arg2);
-int64_t tcg_helper_div_i64(int64_t arg1, int64_t arg2);
-int64_t tcg_helper_rem_i64(int64_t arg1, int64_t arg2);
-uint64_t tcg_helper_divu_i64(uint64_t arg1, uint64_t arg2);
-uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2);
+/* only used for debugging purposes */
+void tcg_register_helper(void *func, const char *name);
+const char *tcg_helper_get_name(TCGContext *s, void *func);
+void tcg_dump_ops(TCGContext *s, FILE *outfile);
+
+void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
+TCGv_i32 tcg_const_i32(int32_t val);
+TCGv_i64 tcg_const_i64(int64_t val);
+TCGv_i32 tcg_const_local_i32(int32_t val);
+TCGv_i64 tcg_const_local_i64(int64_t val);
#ifndef VBOX
extern uint8_t code_gen_prologue[];
#else
-extern uint8_t* code_gen_prologue;
+extern uint8_t *code_gen_prologue;
#endif
-
-#if defined(__powerpc__) && !defined(__powerpc64__)
+#if defined(_ARCH_PPC) && !defined(_ARCH_PPC64)
#define tcg_qemu_tb_exec(tb_ptr) \
((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr)
#else
-
-#if defined(VBOX) && defined(GCC_WITH_BUGGY_REGPARM)
-#define tcg_qemu_tb_exec(tb_ptr, ret) \
+# if defined(VBOX) && defined(GCC_WITH_BUGGY_REGPARM)
+# define tcg_qemu_tb_exec(tb_ptr, ret) \
__asm__ __volatile__("call *%%ecx" : "=a"(ret) : "a"(tb_ptr), "c" (&code_gen_prologue[0]) : "memory", "%edx", "cc")
-#else
+# else /* !VBOX || !GCC_WITH_BUGGY_REG_PARAM */
#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr)
-#endif
-
+# endif /* !VBOX || !GCC_WITH_BUGGY_REG_PARAM */
#endif
diff --git a/src/recompiler/tcg/x86_64/tcg-target.c b/src/recompiler/tcg/x86_64/tcg-target.c
deleted file mode 100644
index 4531cb2ad..000000000
--- a/src/recompiler/tcg/x86_64/tcg-target.c
+++ /dev/null
@@ -1,1462 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef NDEBUG
-static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
- "%rax",
- "%rcx",
- "%rdx",
- "%rbx",
- "%rsp",
- "%rbp",
- "%rsi",
- "%rdi",
- "%r8",
- "%r9",
- "%r10",
- "%r11",
- "%r12",
- "%r13",
- "%r14",
- "%r15",
-};
-#endif
-
-static const int tcg_target_reg_alloc_order[] = {
- TCG_REG_RDI,
- TCG_REG_RSI,
- TCG_REG_RDX,
- TCG_REG_RCX,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_RAX,
- TCG_REG_R10,
- TCG_REG_R11,
-
- TCG_REG_RBP,
- TCG_REG_RBX,
- TCG_REG_R12,
- TCG_REG_R13,
- TCG_REG_R14,
- TCG_REG_R15,
-};
-
-static const int tcg_target_call_iarg_regs[6] = {
- TCG_REG_RDI,
- TCG_REG_RSI,
- TCG_REG_RDX,
- TCG_REG_RCX,
- TCG_REG_R8,
- TCG_REG_R9,
-};
-
-static const int tcg_target_call_oarg_regs[2] = {
- TCG_REG_RAX,
- TCG_REG_RDX
-};
-
-static uint8_t *tb_ret_addr;
-
-static void patch_reloc(uint8_t *code_ptr, int type,
- tcg_target_long value, tcg_target_long addend)
-{
- value += addend;
- switch(type) {
- case R_X86_64_32:
- if (value != (uint32_t)value)
- tcg_abort();
- *(uint32_t *)code_ptr = value;
- break;
- case R_X86_64_32S:
- if (value != (int32_t)value)
- tcg_abort();
- *(uint32_t *)code_ptr = value;
- break;
- case R_386_PC32:
- value -= (long)code_ptr;
- if (value != (int32_t)value)
- tcg_abort();
- *(uint32_t *)code_ptr = value;
- break;
- default:
- tcg_abort();
- }
-}
-
-/* maximum number of register used for input function arguments */
-static inline int tcg_target_get_call_iarg_regs_count(int flags)
-{
- return 6;
-}
-
-/* parse target specific constraints */
-static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
-{
- const char *ct_str;
-
- ct_str = *pct_str;
- switch(ct_str[0]) {
- case 'a':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_RAX);
- break;
- case 'b':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_RBX);
- break;
- case 'c':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_RCX);
- break;
- case 'd':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_RDX);
- break;
- case 'S':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_RSI);
- break;
- case 'D':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_RDI);
- break;
- case 'q':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xf);
- break;
- case 'r':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffff);
- break;
- case 'L': /* qemu_ld/st constraint */
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffff);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_RSI);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_RDI);
- break;
- case 'e':
- ct->ct |= TCG_CT_CONST_S32;
- break;
- case 'Z':
- ct->ct |= TCG_CT_CONST_U32;
- break;
- default:
- return -1;
- }
- ct_str++;
- *pct_str = ct_str;
- return 0;
-}
-
-/* test if a constant matches the constraint */
-static inline int tcg_target_const_match(tcg_target_long val,
- const TCGArgConstraint *arg_ct)
-{
- int ct;
- ct = arg_ct->ct;
- if (ct & TCG_CT_CONST)
- return 1;
- else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val)
- return 1;
- else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val)
- return 1;
- else
- return 0;
-}
-
-#define ARITH_ADD 0
-#define ARITH_OR 1
-#define ARITH_ADC 2
-#define ARITH_SBB 3
-#define ARITH_AND 4
-#define ARITH_SUB 5
-#define ARITH_XOR 6
-#define ARITH_CMP 7
-
-#define SHIFT_SHL 4
-#define SHIFT_SHR 5
-#define SHIFT_SAR 7
-
-#define JCC_JMP (-1)
-#define JCC_JO 0x0
-#define JCC_JNO 0x1
-#define JCC_JB 0x2
-#define JCC_JAE 0x3
-#define JCC_JE 0x4
-#define JCC_JNE 0x5
-#define JCC_JBE 0x6
-#define JCC_JA 0x7
-#define JCC_JS 0x8
-#define JCC_JNS 0x9
-#define JCC_JP 0xa
-#define JCC_JNP 0xb
-#define JCC_JL 0xc
-#define JCC_JGE 0xd
-#define JCC_JLE 0xe
-#define JCC_JG 0xf
-
-#define P_EXT 0x100 /* 0x0f opcode prefix */
-#define P_REXW 0x200 /* set rex.w = 1 */
-#define P_REXB 0x400 /* force rex use for byte registers */
-
-static const uint8_t tcg_cond_to_jcc[10] = {
- [TCG_COND_EQ] = JCC_JE,
- [TCG_COND_NE] = JCC_JNE,
- [TCG_COND_LT] = JCC_JL,
- [TCG_COND_GE] = JCC_JGE,
- [TCG_COND_LE] = JCC_JLE,
- [TCG_COND_GT] = JCC_JG,
- [TCG_COND_LTU] = JCC_JB,
- [TCG_COND_GEU] = JCC_JAE,
- [TCG_COND_LEU] = JCC_JBE,
- [TCG_COND_GTU] = JCC_JA,
-};
-
-static inline void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x)
-{
- int rex;
- rex = ((opc >> 6) & 0x8) | ((r >> 1) & 0x4) |
- ((x >> 2) & 2) | ((rm >> 3) & 1);
- if (rex || (opc & P_REXB)) {
- tcg_out8(s, rex | 0x40);
- }
- if (opc & P_EXT)
- tcg_out8(s, 0x0f);
- tcg_out8(s, opc);
-}
-
-static inline void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
-{
- tcg_out_opc(s, opc, r, rm, 0);
- tcg_out8(s, 0xc0 | ((r & 7) << 3) | (rm & 7));
-}
-
-static inline void tcg_out_push(TCGContext *s, int reg)
-{
- tcg_out_opc(s, (0x50 + (reg & 7)), 0, reg, 0);
-}
-
-static inline void tcg_out_pop(TCGContext *s, int reg)
-{
- tcg_out_opc(s, (0x58 + (reg & 7)), 0, reg, 0);
-}
-
-
-/* rm < 0 means no register index plus (-rm - 1 immediate bytes) */
-static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r, int rm,
- tcg_target_long offset)
-{
- if (rm < 0) {
- tcg_target_long val;
- tcg_out_opc(s, opc, r, 0, 0);
- val = offset - ((tcg_target_long)s->code_ptr + 5 + (-rm - 1));
- if (val == (int32_t)val) {
- /* eip relative */
- tcg_out8(s, 0x05 | ((r & 7) << 3));
- tcg_out32(s, val);
- } else if (offset == (int32_t)offset) {
- tcg_out8(s, 0x04 | ((r & 7) << 3));
- tcg_out8(s, 0x25); /* sib */
- tcg_out32(s, offset);
- } else {
- tcg_abort();
- }
- } else if (offset == 0 && (rm & 7) != TCG_REG_RBP) {
- tcg_out_opc(s, opc, r, rm, 0);
- if ((rm & 7) == TCG_REG_RSP) {
- tcg_out8(s, 0x04 | ((r & 7) << 3));
- tcg_out8(s, 0x24);
- } else {
- tcg_out8(s, 0x00 | ((r & 7) << 3) | (rm & 7));
- }
- } else if ((int8_t)offset == offset) {
- tcg_out_opc(s, opc, r, rm, 0);
- if ((rm & 7) == TCG_REG_RSP) {
- tcg_out8(s, 0x44 | ((r & 7) << 3));
- tcg_out8(s, 0x24);
- } else {
- tcg_out8(s, 0x40 | ((r & 7) << 3) | (rm & 7));
- }
- tcg_out8(s, offset);
- } else {
- tcg_out_opc(s, opc, r, rm, 0);
- if ((rm & 7) == TCG_REG_RSP) {
- tcg_out8(s, 0x84 | ((r & 7) << 3));
- tcg_out8(s, 0x24);
- } else {
- tcg_out8(s, 0x80 | ((r & 7) << 3) | (rm & 7));
- }
- tcg_out32(s, offset);
- }
-}
-
-#if defined(CONFIG_SOFTMMU)
-/* XXX: incomplete. index must be different from ESP */
-static void tcg_out_modrm_offset2(TCGContext *s, int opc, int r, int rm,
- int index, int shift,
- tcg_target_long offset)
-{
- int mod;
- if (rm == -1)
- tcg_abort();
- if (offset == 0 && (rm & 7) != TCG_REG_RBP) {
- mod = 0;
- } else if (offset == (int8_t)offset) {
- mod = 0x40;
- } else if (offset == (int32_t)offset) {
- mod = 0x80;
- } else {
- tcg_abort();
- }
- if (index == -1) {
- tcg_out_opc(s, opc, r, rm, 0);
- if ((rm & 7) == TCG_REG_RSP) {
- tcg_out8(s, mod | ((r & 7) << 3) | 0x04);
- tcg_out8(s, 0x04 | (rm & 7));
- } else {
- tcg_out8(s, mod | ((r & 7) << 3) | (rm & 7));
- }
- } else {
- tcg_out_opc(s, opc, r, rm, index);
- tcg_out8(s, mod | ((r & 7) << 3) | 0x04);
- tcg_out8(s, (shift << 6) | ((index & 7) << 3) | (rm & 7));
- }
- if (mod == 0x40) {
- tcg_out8(s, offset);
- } else if (mod == 0x80) {
- tcg_out32(s, offset);
- }
-}
-#endif
-
-static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
-{
- tcg_out_modrm(s, 0x8b | P_REXW, ret, arg);
-}
-
-static inline void tcg_out_movi(TCGContext *s, TCGType type,
- int ret, tcg_target_long arg)
-{
- if (arg == 0) {
- tcg_out_modrm(s, 0x01 | (ARITH_XOR << 3), ret, ret); /* xor r0,r0 */
- } else if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
- tcg_out_opc(s, 0xb8 + (ret & 7), 0, ret, 0);
- tcg_out32(s, arg);
- } else if (arg == (int32_t)arg) {
- tcg_out_modrm(s, 0xc7 | P_REXW, 0, ret);
- tcg_out32(s, arg);
- } else {
- tcg_out_opc(s, (0xb8 + (ret & 7)) | P_REXW, 0, ret, 0);
- tcg_out32(s, arg);
- tcg_out32(s, arg >> 32);
- }
-}
-
-static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
- int arg1, tcg_target_long arg2)
-{
- if (type == TCG_TYPE_I32)
- tcg_out_modrm_offset(s, 0x8b, ret, arg1, arg2); /* movl */
- else
- tcg_out_modrm_offset(s, 0x8b | P_REXW, ret, arg1, arg2); /* movq */
-}
-
-static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
- int arg1, tcg_target_long arg2)
-{
- if (type == TCG_TYPE_I32)
- tcg_out_modrm_offset(s, 0x89, arg, arg1, arg2); /* movl */
- else
- tcg_out_modrm_offset(s, 0x89 | P_REXW, arg, arg1, arg2); /* movq */
-}
-
-static inline void tgen_arithi32(TCGContext *s, int c, int r0, int32_t val)
-{
- if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x83, c, r0);
- tcg_out8(s, val);
- } else if (c == ARITH_AND && val == 0xffu) {
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB, r0, r0);
- } else if (c == ARITH_AND && val == 0xffffu) {
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT, r0, r0);
- } else {
- tcg_out_modrm(s, 0x81, c, r0);
- tcg_out32(s, val);
- }
-}
-
-static inline void tgen_arithi64(TCGContext *s, int c, int r0, int64_t val)
-{
- if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x83 | P_REXW, c, r0);
- tcg_out8(s, val);
- } else if (c == ARITH_AND && val == 0xffu) {
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT | P_REXW, r0, r0);
- } else if (c == ARITH_AND && val == 0xffffu) {
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT | P_REXW, r0, r0);
- } else if (c == ARITH_AND && val == 0xffffffffu) {
- /* 32-bit mov zero extends */
- tcg_out_modrm(s, 0x8b, r0, r0);
- } else if (val == (int32_t)val) {
- tcg_out_modrm(s, 0x81 | P_REXW, c, r0);
- tcg_out32(s, val);
- } else if (c == ARITH_AND && val == (uint32_t)val) {
- tcg_out_modrm(s, 0x81, c, r0);
- tcg_out32(s, val);
- } else {
- tcg_abort();
- }
-}
-
-static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
-{
- if (val != 0)
- tgen_arithi64(s, ARITH_ADD, reg, val);
-}
-
-static void tcg_out_jxx(TCGContext *s, int opc, int label_index)
-{
- int32_t val, val1;
- TCGLabel *l = &s->labels[label_index];
-
- if (l->has_value) {
- val = l->u.value - (tcg_target_long)s->code_ptr;
- val1 = val - 2;
- if ((int8_t)val1 == val1) {
- if (opc == -1)
- tcg_out8(s, 0xeb);
- else
- tcg_out8(s, 0x70 + opc);
- tcg_out8(s, val1);
- } else {
- if (opc == -1) {
- tcg_out8(s, 0xe9);
- tcg_out32(s, val - 5);
- } else {
- tcg_out8(s, 0x0f);
- tcg_out8(s, 0x80 + opc);
- tcg_out32(s, val - 6);
- }
- }
- } else {
- if (opc == -1) {
- tcg_out8(s, 0xe9);
- } else {
- tcg_out8(s, 0x0f);
- tcg_out8(s, 0x80 + opc);
- }
- tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
- s->code_ptr += 4;
- }
-}
-
-static void tcg_out_brcond(TCGContext *s, int cond,
- TCGArg arg1, TCGArg arg2, int const_arg2,
- int label_index, int rexw)
-{
- if (const_arg2) {
- if (arg2 == 0) {
- /* test r, r */
- tcg_out_modrm(s, 0x85 | rexw, arg1, arg1);
- } else {
- if (rexw)
- tgen_arithi64(s, ARITH_CMP, arg1, arg2);
- else
- tgen_arithi32(s, ARITH_CMP, arg1, arg2);
- }
- } else {
- tcg_out_modrm(s, 0x01 | (ARITH_CMP << 3) | rexw, arg2, arg1);
- }
- tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index);
-}
-
-#ifdef VBOX
-DECLINLINE(void) tcg_out_pushq(TCGContext *s, tcg_target_long val)
-{
- tcg_out8(s, 0x68); /* push imm32, subs 8 from rsp */
- tcg_out32(s, val); /* imm32 */
- if ((val >> 32) != 0)
- {
- tcg_out8(s, 0xc7); /* mov imm32, 4(%rsp) */
- tcg_out8(s, 0x44);
- tcg_out8(s, 0x24);
- tcg_out8(s, 0x04);
- tcg_out32(s, ((uint64_t)val) >> 32); /* imm32 */
- }
-}
-
-DECLINLINE(void) tcg_out_long_call(TCGContext *s, tcg_target_long dst)
-{
- intptr_t disp = dst - (tcg_target_long)s->code_ptr - 5;
- /* can do normal call */
- if (disp < 2LL * _1G && disp > -2LL * _1G)
- {
- tcg_out8(s, 0xe8); /* call disp32 */
- tcg_out32(s, disp); /* disp32 */
- }
- else
- {
-#if 0
- /* Somewhat tricky, but allows long jump not touching registers */
- int off = 5 /* push imm32 */ + 5 /* push imm32 */ + 1 /* ret */;
- if ((((uint64_t)s->code_ptr) + 32) >> 32)
- off += 8;
- if (dst >> 32)
- off += 8;
- /* return address */
- tcg_out_pushq(s, (tcg_target_long)s->code_ptr+off);
- /* destination */
- tcg_out_pushq(s, dst);
- tcg_out8(s, 0xc3); /* ret, used as call */
-#else
- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RAX, dst);
- tcg_out8(s, 0xff); /* call *%eax */
- tcg_out8(s, 0xd0);
-#endif
- }
-}
-
-DECLINLINE(void) tcg_out_long_jmp(TCGContext *s, tcg_target_long dst)
-{
- intptr_t disp;
-
- disp = dst - (tcg_target_long)s->code_ptr - 2;
- /* can do short relative jump */
- if (disp < 0x7f && disp > -0x7f)
- {
- tcg_out8(s, 0xeb); /* short jmp */
- tcg_out8(s, (int8_t)disp);
- return;
- }
-
- disp = dst - (tcg_target_long)s->code_ptr - 5;
- if (disp < 2LL * _1G && disp > -2LL * _1G)
- {
- tcg_out8(s, 0xe9); /* jmp */
- tcg_out32(s, (int32_t)disp);
- return;
- }
-#if 0
- tcg_out_pushq(s, dst);
- tcg_out8(s, 0xc3); /* ret */
-#else
- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RAX, dst);
- tcg_out8(s, 0xff); /* jmp *%eax */
- tcg_out8(s, 0xe0);
-#endif
-}
-#endif
-
-#if defined(CONFIG_SOFTMMU)
-
-#include "../../softmmu_defs.h"
-
-static void *qemu_ld_helpers[4] = {
- __ldb_mmu,
- __ldw_mmu,
- __ldl_mmu,
- __ldq_mmu,
-};
-
-static void *qemu_st_helpers[4] = {
- __stb_mmu,
- __stw_mmu,
- __stl_mmu,
- __stq_mmu,
-};
-#endif
-
-#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
-static void *vbox_ld_helpers[] = {
- __ldub_vbox_phys,
- __lduw_vbox_phys,
- __ldul_vbox_phys,
- __ldq_vbox_phys,
- __ldb_vbox_phys,
- __ldw_vbox_phys,
- __ldl_vbox_phys,
- __ldq_vbox_phys,
-};
-
-static void *vbox_st_helpers[] = {
- __stb_vbox_phys,
- __stw_vbox_phys,
- __stl_vbox_phys,
- __stq_vbox_phys
-};
-
-static void tcg_out_vbox_phys_read(TCGContext *s, int index, int addr_reg, int data_reg) {
- if (addr_reg != TCG_REG_RDI)
- /* mov addr_reg, %rdi */
- tcg_out_modrm(s, 0x8b | P_REXW, TCG_REG_RDI, addr_reg);
-
- tcg_out_long_call(s, (tcg_target_long)vbox_ld_helpers[index]);
- /* mov %rax, data_reg*/
- tcg_out_modrm(s, 0x8b | P_REXW, data_reg, TCG_REG_RAX);
-}
-
-static void tcg_out_vbox_phys_write(TCGContext *s, int index, int addr_reg, int val_reg) {
- if (addr_reg != TCG_REG_RDI)
- /* mov addr_reg, %rdi */
- tcg_out_modrm(s, 0x8b | P_REXW, TCG_REG_RDI, addr_reg);
- if (val_reg != TCG_REG_RSI)
- /* mov addr_reg, %rsi */
- tcg_out_modrm(s, 0x8b | P_REXW, TCG_REG_RSI, val_reg);
- tcg_out_long_call(s, (tcg_target_long)vbox_st_helpers[index]);
-}
-
-#endif
-
-static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
- int opc)
-{
- int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw;
-#if defined(CONFIG_SOFTMMU)
- uint8_t *label1_ptr, *label2_ptr;
-#endif
-
- data_reg = *args++;
- addr_reg = *args++;
- mem_index = *args;
- s_bits = opc & 3;
-
- r0 = TCG_REG_RDI;
- r1 = TCG_REG_RSI;
-
-#if TARGET_LONG_BITS == 32
- rexw = 0;
-#else
- rexw = P_REXW;
-#endif
-#if defined(CONFIG_SOFTMMU)
- /* mov */
- tcg_out_modrm(s, 0x8b | rexw, r1, addr_reg);
-
- /* mov */
- tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg);
-
- tcg_out_modrm(s, 0xc1 | rexw, 5, r1); /* shr $x, r1 */
- tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
-
- tcg_out_modrm(s, 0x81 | rexw, 4, r0); /* andl $x, r0 */
- tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
-
- tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
- tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-
- /* lea offset(r1, env), r1 */
- tcg_out_modrm_offset2(s, 0x8d | P_REXW, r1, r1, TCG_AREG0, 0,
- offsetof(CPUState, tlb_table[mem_index][0].addr_read));
-
- /* cmp 0(r1), r0 */
- tcg_out_modrm_offset(s, 0x3b | rexw, r0, r1, 0);
-
- /* mov */
- tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg);
-
- /* je label1 */
- tcg_out8(s, 0x70 + JCC_JE);
- label1_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* XXX: move that code at the end of the TB */
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RSI, mem_index);
-#ifndef VBOX
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_ld_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
-#else
- tcg_out_long_call(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
-#endif
-
- switch(opc) {
- case 0 | 4:
- /* movsbq */
- tcg_out_modrm(s, 0xbe | P_EXT | P_REXW, data_reg, TCG_REG_RAX);
- break;
- case 1 | 4:
- /* movswq */
- tcg_out_modrm(s, 0xbf | P_EXT | P_REXW, data_reg, TCG_REG_RAX);
- break;
- case 2 | 4:
- /* movslq */
- tcg_out_modrm(s, 0x63 | P_REXW, data_reg, TCG_REG_RAX);
- break;
- case 0:
- case 1:
- case 2:
- default:
- /* movl */
- tcg_out_modrm(s, 0x8b, data_reg, TCG_REG_RAX);
- break;
- case 3:
- tcg_out_mov(s, data_reg, TCG_REG_RAX);
- break;
- }
-
- /* jmp label2 */
- tcg_out8(s, 0xeb);
- label2_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* label1: */
- *label1_ptr = s->code_ptr - label1_ptr - 1;
-
- /* add x(r1), r0 */
- tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) -
- offsetof(CPUTLBEntry, addr_read));
-#else
- r0 = addr_reg;
-#endif
-
-#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
-
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 1;
-#else
- bswap = 0;
-#endif
-
- switch(opc) {
- case 0:
- /* movzbl */
- tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, 0);
- break;
- case 0 | 4:
- /* movsbX */
- tcg_out_modrm_offset(s, 0xbe | P_EXT | rexw, data_reg, r0, 0);
- break;
- case 1:
- /* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
- if (bswap) {
- /* rolw $8, data_reg */
- tcg_out8(s, 0x66);
- tcg_out_modrm(s, 0xc1, 0, data_reg);
- tcg_out8(s, 8);
- }
- break;
- case 1 | 4:
- if (bswap) {
- /* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
- /* rolw $8, data_reg */
- tcg_out8(s, 0x66);
- tcg_out_modrm(s, 0xc1, 0, data_reg);
- tcg_out8(s, 8);
-
- /* movswX data_reg, data_reg */
- tcg_out_modrm(s, 0xbf | P_EXT | rexw, data_reg, data_reg);
- } else {
- /* movswX */
- tcg_out_modrm_offset(s, 0xbf | P_EXT | rexw, data_reg, r0, 0);
- }
- break;
- case 2:
- /* movl (r0), data_reg */
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
- if (bswap) {
- /* bswap */
- tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0);
- }
- break;
- case 2 | 4:
- if (bswap) {
- /* movl (r0), data_reg */
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
- /* bswap */
- tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0);
- /* movslq */
- tcg_out_modrm(s, 0x63 | P_REXW, data_reg, data_reg);
- } else {
- /* movslq */
- tcg_out_modrm_offset(s, 0x63 | P_REXW, data_reg, r0, 0);
- }
- break;
- case 3:
- /* movq (r0), data_reg */
- tcg_out_modrm_offset(s, 0x8b | P_REXW, data_reg, r0, 0);
- if (bswap) {
- /* bswap */
- tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT | P_REXW, 0, data_reg, 0);
- }
- break;
- default:
- tcg_abort();
- }
-#else /* VBOX */
- tcg_out_vbox_phys_read(s, opc, r0, data_reg);
-#endif /* VBOX */
-
-#if defined(CONFIG_SOFTMMU)
- /* label2: */
- *label2_ptr = s->code_ptr - label2_ptr - 1;
-#endif
-}
-
-static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
- int opc)
-{
- int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw;
-#if defined(CONFIG_SOFTMMU)
- uint8_t *label1_ptr, *label2_ptr;
-#endif
-
- data_reg = *args++;
- addr_reg = *args++;
- mem_index = *args;
-
- s_bits = opc;
-
- r0 = TCG_REG_RDI;
- r1 = TCG_REG_RSI;
-
-#if TARGET_LONG_BITS == 32
- rexw = 0;
-#else
- rexw = P_REXW;
-#endif
-#if defined(CONFIG_SOFTMMU)
- /* mov */
- tcg_out_modrm(s, 0x8b | rexw, r1, addr_reg);
-
- /* mov */
- tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg);
-
- tcg_out_modrm(s, 0xc1 | rexw, 5, r1); /* shr $x, r1 */
- tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
-
- tcg_out_modrm(s, 0x81 | rexw, 4, r0); /* andl $x, r0 */
- tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
-
- tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
- tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-
- /* lea offset(r1, env), r1 */
- tcg_out_modrm_offset2(s, 0x8d | P_REXW, r1, r1, TCG_AREG0, 0,
- offsetof(CPUState, tlb_table[mem_index][0].addr_write));
-
- /* cmp 0(r1), r0 */
- tcg_out_modrm_offset(s, 0x3b | rexw, r0, r1, 0);
-
- /* mov */
- tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg);
-
- /* je label1 */
- tcg_out8(s, 0x70 + JCC_JE);
- label1_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* XXX: move that code at the end of the TB */
- switch(opc) {
- case 0:
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB, TCG_REG_RSI, data_reg);
- break;
- case 1:
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_RSI, data_reg);
- break;
- case 2:
- /* movl */
- tcg_out_modrm(s, 0x8b, TCG_REG_RSI, data_reg);
- break;
- default:
- case 3:
- tcg_out_mov(s, TCG_REG_RSI, data_reg);
- break;
- }
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index);
-#ifndef VBOX
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
-#else
- tcg_out_long_call(s, (tcg_target_long)qemu_st_helpers[s_bits]);
-#endif
-
- /* jmp label2 */
- tcg_out8(s, 0xeb);
- label2_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* label1: */
- *label1_ptr = s->code_ptr - label1_ptr - 1;
-
- /* add x(r1), r0 */
- tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) -
- offsetof(CPUTLBEntry, addr_write));
-#else
- r0 = addr_reg;
-#endif
-
-#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 1;
-#else
- bswap = 0;
-#endif
- switch(opc) {
- case 0:
- /* movb */
- tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, 0);
- break;
- case 1:
- if (bswap) {
- tcg_out_modrm(s, 0x8b, r1, data_reg); /* movl */
- tcg_out8(s, 0x66); /* rolw $8, %ecx */
- tcg_out_modrm(s, 0xc1, 0, r1);
- tcg_out8(s, 8);
- data_reg = r1;
- }
- /* movw */
- tcg_out8(s, 0x66);
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
- break;
- case 2:
- if (bswap) {
- tcg_out_modrm(s, 0x8b, r1, data_reg); /* movl */
- /* bswap data_reg */
- tcg_out_opc(s, (0xc8 + r1) | P_EXT, 0, r1, 0);
- data_reg = r1;
- }
- /* movl */
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
- break;
- case 3:
- if (bswap) {
- tcg_out_mov(s, r1, data_reg);
- /* bswap data_reg */
- tcg_out_opc(s, (0xc8 + r1) | P_EXT | P_REXW, 0, r1, 0);
- data_reg = r1;
- }
- /* movq */
- tcg_out_modrm_offset(s, 0x89 | P_REXW, data_reg, r0, 0);
- break;
- default:
- tcg_abort();
- }
-#else /* VBOX */
- tcg_out_vbox_phys_write(s, opc, r0, data_reg);
-#endif /* VBOX */
-
-#if defined(CONFIG_SOFTMMU)
- /* label2: */
- *label2_ptr = s->code_ptr - label2_ptr - 1;
-#endif
-}
-
-static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
- const int *const_args)
-{
- int c;
-
- switch(opc) {
- case INDEX_op_exit_tb:
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RAX, args[0]);
-#ifndef VBOX
- tcg_out8(s, 0xe9); /* jmp tb_ret_addr */
- tcg_out32(s, tb_ret_addr - s->code_ptr - 4);
-#else
- tcg_out_long_jmp(s, (tcg_target_long)tb_ret_addr);
-#endif
- break;
- case INDEX_op_goto_tb:
- if (s->tb_jmp_offset) {
- /* direct jump method */
- tcg_out8(s, 0xe9); /* jmp im */
- s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
- tcg_out32(s, 0);
- } else {
- /* indirect jump method */
- /* jmp Ev */
-#ifndef VBOX
- tcg_out_modrm_offset(s, 0xff, 4, -1,
- (tcg_target_long)(s->tb_next +
- args[0]));
-#else
- /* @todo: can we clobber RAX here? */
- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RAX,
- (tcg_target_long)&(s->tb_next[args[0]]));
- tcg_out8(s, 0xff); tcg_out8(s, 0x20 | TCG_REG_RAX); /* jmp *(%rax) */
-#endif
- }
- s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
- break;
- case INDEX_op_call:
- if (const_args[0]) {
-#ifndef VBOX
- tcg_out8(s, 0xe8);
- tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
-#else
- tcg_out_long_call(s, args[0]);
-#endif
- } else {
- tcg_out_modrm(s, 0xff, 2, args[0]);
- }
- break;
- case INDEX_op_jmp:
- if (const_args[0]) {
- tcg_out8(s, 0xe9);
- tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
- } else {
- tcg_out_modrm(s, 0xff, 4, args[0]);
- }
- break;
- case INDEX_op_br:
- tcg_out_jxx(s, JCC_JMP, args[0]);
- break;
- case INDEX_op_movi_i32:
- tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
- break;
- case INDEX_op_movi_i64:
- tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
- break;
- case INDEX_op_ld8u_i32:
- case INDEX_op_ld8u_i64:
- /* movzbl */
- tcg_out_modrm_offset(s, 0xb6 | P_EXT, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld8s_i32:
- /* movsbl */
- tcg_out_modrm_offset(s, 0xbe | P_EXT, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld8s_i64:
- /* movsbq */
- tcg_out_modrm_offset(s, 0xbe | P_EXT | P_REXW, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld16u_i32:
- case INDEX_op_ld16u_i64:
- /* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld16s_i32:
- /* movswl */
- tcg_out_modrm_offset(s, 0xbf | P_EXT, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld16s_i64:
- /* movswq */
- tcg_out_modrm_offset(s, 0xbf | P_EXT | P_REXW, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld_i32:
- case INDEX_op_ld32u_i64:
- /* movl */
- tcg_out_modrm_offset(s, 0x8b, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld32s_i64:
- /* movslq */
- tcg_out_modrm_offset(s, 0x63 | P_REXW, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld_i64:
- /* movq */
- tcg_out_modrm_offset(s, 0x8b | P_REXW, args[0], args[1], args[2]);
- break;
-
- case INDEX_op_st8_i32:
- case INDEX_op_st8_i64:
- /* movb */
- tcg_out_modrm_offset(s, 0x88 | P_REXB, args[0], args[1], args[2]);
- break;
- case INDEX_op_st16_i32:
- case INDEX_op_st16_i64:
- /* movw */
- tcg_out8(s, 0x66);
- tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]);
- break;
- case INDEX_op_st_i32:
- case INDEX_op_st32_i64:
- /* movl */
- tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]);
- break;
- case INDEX_op_st_i64:
- /* movq */
- tcg_out_modrm_offset(s, 0x89 | P_REXW, args[0], args[1], args[2]);
- break;
-
- case INDEX_op_sub_i32:
- c = ARITH_SUB;
- goto gen_arith32;
- case INDEX_op_and_i32:
- c = ARITH_AND;
- goto gen_arith32;
- case INDEX_op_or_i32:
- c = ARITH_OR;
- goto gen_arith32;
- case INDEX_op_xor_i32:
- c = ARITH_XOR;
- goto gen_arith32;
- case INDEX_op_add_i32:
- c = ARITH_ADD;
- gen_arith32:
- if (const_args[2]) {
- tgen_arithi32(s, c, args[0], args[2]);
- } else {
- tcg_out_modrm(s, 0x01 | (c << 3), args[2], args[0]);
- }
- break;
-
- case INDEX_op_sub_i64:
- c = ARITH_SUB;
- goto gen_arith64;
- case INDEX_op_and_i64:
- c = ARITH_AND;
- goto gen_arith64;
- case INDEX_op_or_i64:
- c = ARITH_OR;
- goto gen_arith64;
- case INDEX_op_xor_i64:
- c = ARITH_XOR;
- goto gen_arith64;
- case INDEX_op_add_i64:
- c = ARITH_ADD;
- gen_arith64:
- if (const_args[2]) {
- tgen_arithi64(s, c, args[0], args[2]);
- } else {
- tcg_out_modrm(s, 0x01 | (c << 3) | P_REXW, args[2], args[0]);
- }
- break;
-
- case INDEX_op_mul_i32:
- if (const_args[2]) {
- int32_t val;
- val = args[2];
- if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x6b, args[0], args[0]);
- tcg_out8(s, val);
- } else {
- tcg_out_modrm(s, 0x69, args[0], args[0]);
- tcg_out32(s, val);
- }
- } else {
- tcg_out_modrm(s, 0xaf | P_EXT, args[0], args[2]);
- }
- break;
- case INDEX_op_mul_i64:
- if (const_args[2]) {
- int32_t val;
- val = args[2];
- if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x6b | P_REXW, args[0], args[0]);
- tcg_out8(s, val);
- } else {
- tcg_out_modrm(s, 0x69 | P_REXW, args[0], args[0]);
- tcg_out32(s, val);
- }
- } else {
- tcg_out_modrm(s, 0xaf | P_EXT | P_REXW, args[0], args[2]);
- }
- break;
- case INDEX_op_div2_i32:
- tcg_out_modrm(s, 0xf7, 7, args[4]);
- break;
- case INDEX_op_divu2_i32:
- tcg_out_modrm(s, 0xf7, 6, args[4]);
- break;
- case INDEX_op_div2_i64:
- tcg_out_modrm(s, 0xf7 | P_REXW, 7, args[4]);
- break;
- case INDEX_op_divu2_i64:
- tcg_out_modrm(s, 0xf7 | P_REXW, 6, args[4]);
- break;
-
- case INDEX_op_shl_i32:
- c = SHIFT_SHL;
- gen_shift32:
- if (const_args[2]) {
- if (args[2] == 1) {
- tcg_out_modrm(s, 0xd1, c, args[0]);
- } else {
- tcg_out_modrm(s, 0xc1, c, args[0]);
- tcg_out8(s, args[2]);
- }
- } else {
- tcg_out_modrm(s, 0xd3, c, args[0]);
- }
- break;
- case INDEX_op_shr_i32:
- c = SHIFT_SHR;
- goto gen_shift32;
- case INDEX_op_sar_i32:
- c = SHIFT_SAR;
- goto gen_shift32;
-
- case INDEX_op_shl_i64:
- c = SHIFT_SHL;
- gen_shift64:
- if (const_args[2]) {
- if (args[2] == 1) {
- tcg_out_modrm(s, 0xd1 | P_REXW, c, args[0]);
- } else {
- tcg_out_modrm(s, 0xc1 | P_REXW, c, args[0]);
- tcg_out8(s, args[2]);
- }
- } else {
- tcg_out_modrm(s, 0xd3 | P_REXW, c, args[0]);
- }
- break;
- case INDEX_op_shr_i64:
- c = SHIFT_SHR;
- goto gen_shift64;
- case INDEX_op_sar_i64:
- c = SHIFT_SAR;
- goto gen_shift64;
-
- case INDEX_op_brcond_i32:
- tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
- args[3], 0);
- break;
- case INDEX_op_brcond_i64:
- tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
- args[3], P_REXW);
- break;
-
- case INDEX_op_bswap_i32:
- tcg_out_opc(s, (0xc8 + (args[0] & 7)) | P_EXT, 0, args[0], 0);
- break;
- case INDEX_op_bswap_i64:
- tcg_out_opc(s, (0xc8 + (args[0] & 7)) | P_EXT | P_REXW, 0, args[0], 0);
- break;
-
- case INDEX_op_neg_i32:
- tcg_out_modrm(s, 0xf7, 3, args[0]);
- break;
- case INDEX_op_neg_i64:
- tcg_out_modrm(s, 0xf7 | P_REXW, 3, args[0]);
- break;
-
- case INDEX_op_ext8s_i32:
- tcg_out_modrm(s, 0xbe | P_EXT | P_REXB, args[0], args[1]);
- break;
- case INDEX_op_ext16s_i32:
- tcg_out_modrm(s, 0xbf | P_EXT, args[0], args[1]);
- break;
- case INDEX_op_ext8s_i64:
- tcg_out_modrm(s, 0xbe | P_EXT | P_REXW, args[0], args[1]);
- break;
- case INDEX_op_ext16s_i64:
- tcg_out_modrm(s, 0xbf | P_EXT | P_REXW, args[0], args[1]);
- break;
- case INDEX_op_ext32s_i64:
- tcg_out_modrm(s, 0x63 | P_REXW, args[0], args[1]);
- break;
-
- case INDEX_op_qemu_ld8u:
- tcg_out_qemu_ld(s, args, 0);
- break;
- case INDEX_op_qemu_ld8s:
- tcg_out_qemu_ld(s, args, 0 | 4);
- break;
- case INDEX_op_qemu_ld16u:
- tcg_out_qemu_ld(s, args, 1);
- break;
- case INDEX_op_qemu_ld16s:
- tcg_out_qemu_ld(s, args, 1 | 4);
- break;
- case INDEX_op_qemu_ld32u:
- tcg_out_qemu_ld(s, args, 2);
- break;
- case INDEX_op_qemu_ld32s:
- tcg_out_qemu_ld(s, args, 2 | 4);
- break;
- case INDEX_op_qemu_ld64:
- tcg_out_qemu_ld(s, args, 3);
- break;
-
- case INDEX_op_qemu_st8:
- tcg_out_qemu_st(s, args, 0);
- break;
- case INDEX_op_qemu_st16:
- tcg_out_qemu_st(s, args, 1);
- break;
- case INDEX_op_qemu_st32:
- tcg_out_qemu_st(s, args, 2);
- break;
- case INDEX_op_qemu_st64:
- tcg_out_qemu_st(s, args, 3);
- break;
-
- default:
- tcg_abort();
- }
-}
-
-static int tcg_target_callee_save_regs[] = {
- TCG_REG_RBP,
- TCG_REG_RBX,
- TCG_REG_R12,
- TCG_REG_R13,
- /* TCG_REG_R14, */ /* currently used for the global env, so no
- need to save */
- TCG_REG_R15,
-};
-
-/* Generate global QEMU prologue and epilogue code */
-void tcg_target_qemu_prologue(TCGContext *s)
-{
- int i, frame_size, push_size, stack_addend;
-
- /* TB prologue */
- /* save all callee saved registers */
- for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
- tcg_out_push(s, tcg_target_callee_save_regs[i]);
-
- }
- /* reserve some stack space */
- push_size = 8 + ARRAY_SIZE(tcg_target_callee_save_regs) * 8;
- frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
- frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
- ~(TCG_TARGET_STACK_ALIGN - 1);
- stack_addend = frame_size - push_size;
- tcg_out_addi(s, TCG_REG_RSP, -stack_addend);
-
- tcg_out_modrm(s, 0xff, 4, TCG_REG_RDI); /* jmp *%rdi */
-
- /* TB epilogue */
- tb_ret_addr = s->code_ptr;
- tcg_out_addi(s, TCG_REG_RSP, stack_addend);
- for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
- tcg_out_pop(s, tcg_target_callee_save_regs[i]);
- }
- tcg_out8(s, 0xc3); /* ret */
-}
-
-static const TCGTargetOpDef x86_64_op_defs[] = {
- { INDEX_op_exit_tb, { } },
- { INDEX_op_goto_tb, { } },
- { INDEX_op_call, { "ri" } }, /* XXX: might need a specific constant constraint */
- { INDEX_op_jmp, { "ri" } }, /* XXX: might need a specific constant constraint */
- { INDEX_op_br, { } },
-
- { INDEX_op_mov_i32, { "r", "r" } },
- { INDEX_op_movi_i32, { "r" } },
- { INDEX_op_ld8u_i32, { "r", "r" } },
- { INDEX_op_ld8s_i32, { "r", "r" } },
- { INDEX_op_ld16u_i32, { "r", "r" } },
- { INDEX_op_ld16s_i32, { "r", "r" } },
- { INDEX_op_ld_i32, { "r", "r" } },
- { INDEX_op_st8_i32, { "r", "r" } },
- { INDEX_op_st16_i32, { "r", "r" } },
- { INDEX_op_st_i32, { "r", "r" } },
-
- { INDEX_op_add_i32, { "r", "0", "ri" } },
- { INDEX_op_mul_i32, { "r", "0", "ri" } },
- { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
- { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
- { INDEX_op_sub_i32, { "r", "0", "ri" } },
- { INDEX_op_and_i32, { "r", "0", "ri" } },
- { INDEX_op_or_i32, { "r", "0", "ri" } },
- { INDEX_op_xor_i32, { "r", "0", "ri" } },
-
- { INDEX_op_shl_i32, { "r", "0", "ci" } },
- { INDEX_op_shr_i32, { "r", "0", "ci" } },
- { INDEX_op_sar_i32, { "r", "0", "ci" } },
-
- { INDEX_op_brcond_i32, { "r", "ri" } },
-
- { INDEX_op_mov_i64, { "r", "r" } },
- { INDEX_op_movi_i64, { "r" } },
- { INDEX_op_ld8u_i64, { "r", "r" } },
- { INDEX_op_ld8s_i64, { "r", "r" } },
- { INDEX_op_ld16u_i64, { "r", "r" } },
- { INDEX_op_ld16s_i64, { "r", "r" } },
- { INDEX_op_ld32u_i64, { "r", "r" } },
- { INDEX_op_ld32s_i64, { "r", "r" } },
- { INDEX_op_ld_i64, { "r", "r" } },
- { INDEX_op_st8_i64, { "r", "r" } },
- { INDEX_op_st16_i64, { "r", "r" } },
- { INDEX_op_st32_i64, { "r", "r" } },
- { INDEX_op_st_i64, { "r", "r" } },
-
- { INDEX_op_add_i64, { "r", "0", "re" } },
- { INDEX_op_mul_i64, { "r", "0", "re" } },
- { INDEX_op_div2_i64, { "a", "d", "0", "1", "r" } },
- { INDEX_op_divu2_i64, { "a", "d", "0", "1", "r" } },
- { INDEX_op_sub_i64, { "r", "0", "re" } },
- { INDEX_op_and_i64, { "r", "0", "reZ" } },
- { INDEX_op_or_i64, { "r", "0", "re" } },
- { INDEX_op_xor_i64, { "r", "0", "re" } },
-
- { INDEX_op_shl_i64, { "r", "0", "ci" } },
- { INDEX_op_shr_i64, { "r", "0", "ci" } },
- { INDEX_op_sar_i64, { "r", "0", "ci" } },
-
- { INDEX_op_brcond_i64, { "r", "re" } },
-
- { INDEX_op_bswap_i32, { "r", "0" } },
- { INDEX_op_bswap_i64, { "r", "0" } },
-
- { INDEX_op_neg_i32, { "r", "0" } },
- { INDEX_op_neg_i64, { "r", "0" } },
-
- { INDEX_op_ext8s_i32, { "r", "r"} },
- { INDEX_op_ext16s_i32, { "r", "r"} },
- { INDEX_op_ext8s_i64, { "r", "r"} },
- { INDEX_op_ext16s_i64, { "r", "r"} },
- { INDEX_op_ext32s_i64, { "r", "r"} },
-
- { INDEX_op_qemu_ld8u, { "r", "L" } },
- { INDEX_op_qemu_ld8s, { "r", "L" } },
- { INDEX_op_qemu_ld16u, { "r", "L" } },
- { INDEX_op_qemu_ld16s, { "r", "L" } },
- { INDEX_op_qemu_ld32u, { "r", "L" } },
- { INDEX_op_qemu_ld32s, { "r", "L" } },
- { INDEX_op_qemu_ld64, { "r", "L" } },
-
- { INDEX_op_qemu_st8, { "L", "L" } },
- { INDEX_op_qemu_st16, { "L", "L" } },
- { INDEX_op_qemu_st32, { "L", "L" } },
- { INDEX_op_qemu_st64, { "L", "L", "L" } },
-
- { -1 },
-};
-
-void tcg_target_init(TCGContext *s)
-{
- /* fail safe */
- if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
- tcg_abort();
-
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
- tcg_regset_set32(tcg_target_call_clobber_regs, 0,
- (1 << TCG_REG_RDI) |
- (1 << TCG_REG_RSI) |
- (1 << TCG_REG_RDX) |
- (1 << TCG_REG_RCX) |
- (1 << TCG_REG_R8) |
- (1 << TCG_REG_R9) |
- (1 << TCG_REG_RAX) |
- (1 << TCG_REG_R10) |
- (1 << TCG_REG_R11));
-
- tcg_regset_clear(s->reserved_regs);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_RSP);
-
- tcg_add_target_add_op_defs(x86_64_op_defs);
-}
diff --git a/src/recompiler/tcg/x86_64/tcg-target.h b/src/recompiler/tcg/x86_64/tcg-target.h
deleted file mode 100644
index fcc54859e..000000000
--- a/src/recompiler/tcg/x86_64/tcg-target.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#define TCG_TARGET_X86_64 1
-
-#define TCG_TARGET_REG_BITS 64
-//#define TCG_TARGET_WORDS_BIGENDIAN
-
-#define TCG_TARGET_NB_REGS 16
-
-enum {
- TCG_REG_RAX = 0,
- TCG_REG_RCX,
- TCG_REG_RDX,
- TCG_REG_RBX,
- TCG_REG_RSP,
- TCG_REG_RBP,
- TCG_REG_RSI,
- TCG_REG_RDI,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10,
- TCG_REG_R11,
- TCG_REG_R12,
- TCG_REG_R13,
- TCG_REG_R14,
- TCG_REG_R15,
-};
-
-#define TCG_CT_CONST_S32 0x100
-#define TCG_CT_CONST_U32 0x200
-
-/* used for function call generation */
-#define TCG_REG_CALL_STACK TCG_REG_RSP
-#define TCG_TARGET_STACK_ALIGN 16
-#define TCG_TARGET_CALL_STACK_OFFSET 0
-
-/* optional instructions */
-#define TCG_TARGET_HAS_bswap_i32
-#define TCG_TARGET_HAS_bswap_i64
-#define TCG_TARGET_HAS_neg_i32
-#define TCG_TARGET_HAS_neg_i64
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#define TCG_TARGET_HAS_ext8s_i64
-#define TCG_TARGET_HAS_ext16s_i64
-#define TCG_TARGET_HAS_ext32s_i64
-
-/* Must be in sync with dyngen register notion, see dyngen-exec.h */
-#define TCG_AREG0 TCG_REG_R14
-#define TCG_AREG1 TCG_REG_R15
-#define TCG_AREG2 TCG_REG_R12
-#define TCG_AREG3 TCG_REG_R13
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-}
diff --git a/src/recompiler/tests/Makefile b/src/recompiler/tests/Makefile
index f803f6a65..ff7f787a9 100644
--- a/src/recompiler/tests/Makefile
+++ b/src/recompiler/tests/Makefile
@@ -1,19 +1,22 @@
-include ../config-host.mak
-CFLAGS=-Wall -O2 -g
+$(call set-vpath, $(SRC_PATH)/tests)
+
+CFLAGS=-Wall -O2 -g -fno-strict-aliasing
#CFLAGS+=-msse2
LDFLAGS=
ifeq ($(ARCH),i386)
-TESTS=linux-test testthread sha1-i386 test-i386 runcom
+TESTS=linux-test testthread sha1-i386 test-i386
endif
ifeq ($(ARCH),x86_64)
TESTS=test-x86_64
endif
TESTS+=sha1# test_path
#TESTS+=test_path
+#TESTS+=runcom
-QEMU=../i386-user/qemu-i386
+QEMU=../i386-linux-user/qemu-i386
all: $(TESTS)
@@ -31,12 +34,12 @@ test_path: test_path.c
# i386/x86_64 emulation test (test various opcodes) */
test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \
test-i386.h test-i386-shift.h test-i386-muldiv.h
- $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ \
- test-i386.c test-i386-code16.S test-i386-vm86.S -lm
+ $(CC) -m32 $(CFLAGS) $(LDFLAGS) -static -o $@ \
+ $(<D)/test-i386.c $(<D)/test-i386-code16.S $(<D)/test-i386-vm86.S -lm
test-x86_64: test-i386.c \
test-i386.h test-i386-shift.h test-i386-muldiv.h
- $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ test-i386.c -lm
+ $(CC) -m64 $(CFLAGS) $(LDFLAGS) -static -o $@ $(<D)/test-i386.c -lm
ifeq ($(ARCH),i386)
test: test-i386
@@ -46,10 +49,15 @@ test:
endif
$(QEMU) test-i386 > test-i386.out
@if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi
-ifeq ($(ARCH),i386)
- $(QEMU) -no-code-copy test-i386 > test-i386.out
- @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK (no code copy)"; fi
-endif
+
+.PHONY: test-mmap
+test-mmap: test-mmap.c
+ $(CC) $(CFLAGS) -Wall -static -O2 $(LDFLAGS) -o $@ $<
+ -./test-mmap
+ -$(QEMU) ./test-mmap
+ -$(QEMU) -p 8192 ./test-mmap 8192
+ -$(QEMU) -p 16384 ./test-mmap 16384
+ -$(QEMU) -p 32768 ./test-mmap 32768
# generic Linux and CPU test
linux-test: linux-test.c
@@ -71,9 +79,9 @@ runcom: runcom.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
# NOTE: -fomit-frame-pointer is currently needed : this is a bug in libqemu
-qruncom: qruncom.c ../i386-user/libqemu.a
+qruncom: qruncom.c ../ioport-user.c ../i386-user/libqemu.a
$(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../i386-user -I../fpu \
- -o $@ $< -L../i386-user -lqemu -lm
+ -o $@ $(filter %.c, $^) -L../i386-user -lqemu -lm
# arm test
hello-arm: hello-arm.o
@@ -82,6 +90,9 @@ hello-arm: hello-arm.o
hello-arm.o: hello-arm.c
arm-linux-gcc -Wall -g -O2 -c -o $@ $<
+test-arm-iwmmxt: test-arm-iwmmxt.s
+ cpp < $< | arm-linux-gnu-gcc -Wall -static -march=iwmmxt -mabi=aapcs -x assembler - -o $@
+
# MIPS test
hello-mips: hello-mips.c
mips-linux-gnu-gcc -nostdlib -static -mno-abicalls -fno-PIC -mabi=32 -Wall -Wextra -g -O2 -o $@ $<
@@ -89,11 +100,9 @@ hello-mips: hello-mips.c
hello-mipsel: hello-mips.c
mipsel-linux-gnu-gcc -nostdlib -static -mno-abicalls -fno-PIC -mabi=32 -Wall -Wextra -g -O2 -o $@ $<
-# XXX: find a way to compile easily a test for each arch
-test2:
- @for arch in i386 arm armeb sparc ppc mips mipsel; do \
- ../$${arch}-user/qemu-$${arch} $${arch}/ls -l linux-test.c ; \
- done
+# testsuite for the CRIS port.
+test-cris:
+ $(MAKE) -C cris check
clean:
rm -f *~ *.o test-i386.out test-i386.ref \
diff --git a/src/recompiler/tests/linux-test.c b/src/recompiler/tests/linux-test.c
index a6e6dfdb5..cce803735 100644
--- a/src/recompiler/tests/linux-test.c
+++ b/src/recompiler/tests/linux-test.c
@@ -1,6 +1,6 @@
/*
* linux and CPU test
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
@@ -14,8 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -68,13 +67,13 @@ void error1(const char *filename, int line, const char *fmt, ...)
int __chk_error(const char *filename, int line, int ret)
{
if (ret < 0) {
- error1(filename, line, "%m (ret=%d, errno=%d)",
+ error1(filename, line, "%m (ret=%d, errno=%d)",
ret, errno);
}
return ret;
}
-#define error(fmt, args...) error1(__FILE__, __LINE__, fmt, ##args)
+#define error(fmt, ...) error1(__FILE__, __LINE__, fmt, ## __VA_ARGS__)
#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret))
@@ -103,11 +102,11 @@ void test_file(void)
if (getcwd(cur_dir, sizeof(cur_dir)) == NULL)
error("getcwd");
-
+
chk_error(mkdir(TESTPATH, 0755));
-
+
chk_error(chdir(TESTPATH));
-
+
/* open/read/write/close/readv/writev/lseek */
fd = chk_error(open("file1", O_WRONLY | O_TRUNC | O_CREAT, 0644));
@@ -134,7 +133,7 @@ void test_file(void)
error("read");
if (memcmp(buf, buf2, FILE_BUF_SIZE) != 0)
error("memcmp");
-
+
#define FOFFSET 16
ret = chk_error(lseek(fd, FOFFSET, SEEK_SET));
if (ret != 16)
@@ -148,7 +147,7 @@ void test_file(void)
error("readv");
if (memcmp(buf + FOFFSET, buf3, FILE_BUF_SIZE - FOFFSET) != 0)
error("memcmp");
-
+
chk_error(close(fd));
/* access */
@@ -181,18 +180,18 @@ void test_file(void)
chk_error(ftruncate(fd, 50));
chk_error(fstat(fd, &st));
chk_error(close(fd));
-
+
if (st.st_size != 50)
error("stat size");
if (!S_ISREG(st.st_mode))
error("stat mode");
-
+
/* symlink/lstat */
chk_error(symlink("file2", "file3"));
chk_error(lstat("file3", &st));
if (!S_ISLNK(st.st_mode))
error("stat mode");
-
+
/* getdents */
dir = opendir(TESTPATH);
if (!dir)
@@ -251,7 +250,7 @@ void test_time(void)
ti = tv2.tv_sec - tv.tv_sec;
if (ti >= 2)
error("gettimeofday");
-
+
chk_error(getrusage(RUSAGE_SELF, &rusg1));
for(i = 0;i < 10000; i++);
chk_error(getrusage(RUSAGE_SELF, &rusg2));
@@ -282,7 +281,7 @@ char *pstrcat(char *buf, int buf_size, const char *s)
{
int len;
len = strlen(buf);
- if (len < buf_size)
+ if (len < buf_size)
pstrcpy(buf + len, buf_size - len, s);
return buf;
}
@@ -337,7 +336,7 @@ void test_socket(void)
chk_error(getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &val, &len));
if (val != SOCK_STREAM)
error("getsockopt");
-
+
pid = chk_error(fork());
if (pid == 0) {
client_fd = client_socket();
@@ -429,11 +428,11 @@ void test_clone(void)
int pid1, pid2, status1, status2;
stack1 = malloc(STACK_SIZE);
- pid1 = chk_error(clone(thread1_func, stack1 + STACK_SIZE,
+ pid1 = chk_error(clone(thread1_func, stack1 + STACK_SIZE,
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1"));
stack2 = malloc(STACK_SIZE);
- pid2 = chk_error(clone(thread2_func, stack2 + STACK_SIZE,
+ pid2 = chk_error(clone(thread2_func, stack2 + STACK_SIZE,
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2"));
while (waitpid(pid1, &status1, 0) != pid1);
@@ -475,7 +474,7 @@ void test_signal(void)
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
chk_error(sigaction(SIGALRM, &act, NULL));
-
+
it.it_interval.tv_sec = 0;
it.it_interval.tv_usec = 10 * 1000;
it.it_value.tv_sec = 0;
@@ -485,7 +484,7 @@ void test_signal(void)
if (oit.it_value.tv_sec != it.it_value.tv_sec ||
oit.it_value.tv_usec != it.it_value.tv_usec)
error("itimer");
-
+
while (alarm_count < 5) {
usleep(10 * 1000);
}
@@ -508,7 +507,7 @@ void test_signal(void)
if (setjmp(jmp_env) == 0) {
*(uint8_t *)0 = 0;
}
-
+
act.sa_handler = SIG_DFL;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
diff --git a/src/recompiler/tests/qruncom.c b/src/recompiler/tests/qruncom.c
index 6dd13b458..079f7a297 100644
--- a/src/recompiler/tests/qruncom.c
+++ b/src/recompiler/tests/qruncom.c
@@ -16,39 +16,6 @@
//#define SIGTEST
-void cpu_outb(CPUState *env, int addr, int val)
-{
- fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);
-}
-
-void cpu_outw(CPUState *env, int addr, int val)
-{
- fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);
-}
-
-void cpu_outl(CPUState *env, int addr, int val)
-{
- fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
-}
-
-int cpu_inb(CPUState *env, int addr)
-{
- fprintf(stderr, "inb: port=0x%04x\n", addr);
- return 0;
-}
-
-int cpu_inw(CPUState *env, int addr)
-{
- fprintf(stderr, "inw: port=0x%04x\n", addr);
- return 0;
-}
-
-int cpu_inl(CPUState *env, int addr)
-{
- fprintf(stderr, "inl: port=0x%04x\n", addr);
- return 0;
-}
-
int cpu_get_pic_interrupt(CPUState *env)
{
return -1;
@@ -59,7 +26,7 @@ uint64_t cpu_get_tsc(CPUState *env)
return 0;
}
-static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
+static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
unsigned long addr, unsigned int sel)
{
unsigned int e1, e2;
@@ -122,7 +89,7 @@ int errno;
#define COM_BASE_ADDR 0x10100
-void usage(void)
+static void usage(void)
{
printf("qruncom version 0.1 (c) 2003 Fabrice Bellard\n"
"usage: qruncom file.com\n"
@@ -141,7 +108,7 @@ static inline void pushw(CPUState *env, int val)
*(uint16_t *)seg_to_linear(env->segs[R_SS].selector, env->regs[R_ESP]) = val;
}
-static void host_segv_handler(int host_signum, siginfo_t *info,
+static void host_segv_handler(int host_signum, siginfo_t *info,
void *puc)
{
if (cpu_signal_handler(host_signum, info, puc)) {
@@ -160,9 +127,9 @@ int main(int argc, char **argv)
if (argc != 2)
usage();
filename = argv[1];
-
- vm86_mem = mmap((void *)0x00000000, 0x110000,
- PROT_WRITE | PROT_READ | PROT_EXEC,
+
+ vm86_mem = mmap((void *)0x00000000, 0x110000,
+ PROT_WRITE | PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
if (vm86_mem == MAP_FAILED) {
perror("mmap");
@@ -185,7 +152,7 @@ int main(int argc, char **argv)
/* install exception handler for CPU emulator */
{
struct sigaction act;
-
+
sigfillset(&act.sa_mask);
act.sa_flags = SA_SIGINFO;
// act.sa_flags |= SA_ONSTACK;
@@ -193,21 +160,11 @@ int main(int argc, char **argv)
act.sa_sigaction = host_segv_handler;
sigaction(SIGSEGV, &act, NULL);
sigaction(SIGBUS, &act, NULL);
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
- sigaction(SIGFPE, &act, NULL);
-#endif
}
// cpu_set_log(CPU_LOG_TB_IN_ASM | CPU_LOG_TB_OUT_ASM | CPU_LOG_EXEC);
- env = cpu_init();
-
- /* disable code copy to simplify debugging */
- code_copy_enabled = 0;
-
- /* set user mode state (XXX: should be done automatically by
- cpu_init ?) */
- env->user_mode_only = 1;
+ env = cpu_init("qemu32");
cpu_x86_set_cpl(env, 3);
@@ -218,23 +175,23 @@ int main(int argc, char **argv)
/* flags setup : we activate the IRQs by default as in user
mode. We also activate the VM86 flag to run DOS code */
env->eflags |= IF_MASK | VM_MASK;
-
+
/* init basic registers */
env->eip = 0x100;
env->regs[R_ESP] = 0xfffe;
seg = (COM_BASE_ADDR - 0x100) >> 4;
- cpu_x86_load_seg_cache(env, R_CS, seg,
+ cpu_x86_load_seg_cache(env, R_CS, seg,
(seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_SS, seg,
+ cpu_x86_load_seg_cache(env, R_SS, seg,
(seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_DS, seg,
+ cpu_x86_load_seg_cache(env, R_DS, seg,
(seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_ES, seg,
+ cpu_x86_load_seg_cache(env, R_ES, seg,
(seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_FS, seg,
+ cpu_x86_load_seg_cache(env, R_FS, seg,
(seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_GS, seg,
+ cpu_x86_load_seg_cache(env, R_GS, seg,
(seg << 4), 0xffff, 0);
/* exception support */
@@ -260,7 +217,7 @@ int main(int argc, char **argv)
set_idt(17, 0);
set_idt(18, 0);
set_idt(19, 0);
-
+
/* put return code */
*seg_to_linear(env->segs[R_CS].selector, 0) = 0xb4; /* mov ah, $0 */
*seg_to_linear(env->segs[R_CS].selector, 1) = 0x00;
@@ -274,8 +231,8 @@ int main(int argc, char **argv)
env->regs[R_EBP] = 0x0900;
env->regs[R_EDI] = 0xfffe;
- /* inform the emulator of the mapped memory */
- page_set_flags(0x00000000, 0x110000,
+ /* inform the emulator of the mmaped memory */
+ page_set_flags(0x00000000, 0x110000,
PAGE_WRITE | PAGE_READ | PAGE_EXEC | PAGE_VALID);
for(;;) {
diff --git a/src/recompiler/tests/runcom.c b/src/recompiler/tests/runcom.c
index 43deeca09..638056663 100644
--- a/src/recompiler/tests/runcom.c
+++ b/src/recompiler/tests/runcom.c
@@ -25,7 +25,7 @@ _syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)
#define COM_BASE_ADDR 0x10100
-void usage(void)
+static void usage(void)
{
printf("runcom version 0.1 (c) 2003 Fabrice Bellard\n"
"usage: runcom file.com\n"
@@ -51,7 +51,7 @@ static inline void pushw(struct vm86_regs *r, int val)
void dump_regs(struct vm86_regs *r)
{
- fprintf(stderr,
+ fprintf(stderr,
"EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n"
"ESI=%08lx EDI=%08lx EBP=%08lx ESP=%08lx\n"
"EIP=%08lx EFL=%08lx\n"
@@ -80,9 +80,9 @@ int main(int argc, char **argv)
if (argc != 2)
usage();
filename = argv[1];
-
- vm86_mem = mmap((void *)0x00000000, 0x110000,
- PROT_WRITE | PROT_READ | PROT_EXEC,
+
+ vm86_mem = mmap((void *)0x00000000, 0x110000,
+ PROT_WRITE | PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
if (vm86_mem == MAP_FAILED) {
perror("mmap");
@@ -147,7 +147,7 @@ int main(int argc, char **argv)
case VM86_INTx:
{
int int_num, ah;
-
+
int_num = VM86_ARG(ret);
if (int_num != 0x21)
goto unknown_int;
diff --git a/src/recompiler/tests/sha1.c b/src/recompiler/tests/sha1.c
index 31b001920..93b7c8e80 100644
--- a/src/recompiler/tests/sha1.c
+++ b/src/recompiler/tests/sha1.c
@@ -23,7 +23,7 @@ A million repetitions of "a"
#include <stdio.h>
#include <string.h>
-#include <sys/types.h> /* for u_int*_t */
+#include <stdint.h>
/* ================ sha1.h ================ */
/*
@@ -33,14 +33,14 @@ By Steve Reid <steve@edmweb.com>
*/
typedef struct {
- u_int32_t state[5];
- u_int32_t count[2];
+ uint32_t state[5];
+ uint32_t count[2];
unsigned char buffer[64];
} SHA1_CTX;
-void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]);
+void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]);
void SHA1Init(SHA1_CTX* context);
-void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len);
+void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len);
void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
/* ================ end of sha1.h ================ */
#include <endian.h>
@@ -70,12 +70,12 @@ void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
/* Hash a single 512-bit block. This is the core of the algorithm. */
-void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64])
+void SHA1Transform(uint32_t state[5], const unsigned char buffer[64])
{
-u_int32_t a, b, c, d, e;
+uint32_t a, b, c, d, e;
typedef union {
unsigned char c[64];
- u_int32_t l[16];
+ uint32_t l[16];
} CHAR64LONG16;
#ifdef SHA1HANDSOFF
CHAR64LONG16 block[1]; /* use array to appear as a pointer */
@@ -145,10 +145,10 @@ void SHA1Init(SHA1_CTX* context)
/* Run your data through this. */
-void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len)
+void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len)
{
-u_int32_t i;
-u_int32_t j;
+uint32_t i;
+uint32_t j;
j = context->count[0];
if ((context->count[0] += len << 3) < j)
@@ -186,11 +186,11 @@ unsigned char c;
for (i = 0; i < 2; i++)
{
- u_int32_t t = context->count[i];
+ uint32_t t = context->count[i];
int j;
for (j = 0; j < 4; t >>= 8, j++)
- *--fcp = (unsigned char) t
+ *--fcp = (unsigned char) t;
}
#else
for (i = 0; i < 8; i++) {
@@ -238,5 +238,3 @@ main(int argc, char **argv)
printf("\n");
return 0;
}
-
-
diff --git a/src/recompiler/tests/test-i386-code16.S b/src/recompiler/tests/test-i386-code16.S
index e400e73fd..816c24b96 100644
--- a/src/recompiler/tests/test-i386-code16.S
+++ b/src/recompiler/tests/test-i386-code16.S
@@ -7,7 +7,7 @@ CS_SEG = 0xf
code16_start:
.globl code16_func1
-
+
/* basic test */
code16_func1 = . - code16_start
mov $1, %eax
@@ -24,7 +24,7 @@ code16_func2 = . - code16_start
pop %ax
data32 lret
-/* test various jmp opcodes */
+/* test various jmp opcodes */
.globl code16_func3
code16_func3 = . - code16_start
jmp 1f
@@ -36,21 +36,21 @@ code16_func3 = . - code16_start
jz 2f
add $2, %ax
2:
-
+
call myfunc
-
+
lcall $CS_SEG, $(myfunc2 - code16_start)
ljmp $CS_SEG, $(myjmp1 - code16_start)
myjmp1_next:
- cs lcall myfunc2_addr - code16_start
+ cs lcall *myfunc2_addr - code16_start
- cs ljmp myjmp2_addr - code16_start
+ cs ljmp *myjmp2_addr - code16_start
myjmp2_next:
data32 lret
-
+
myfunc2_addr:
.short myfunc2 - code16_start
.short CS_SEG
diff --git a/src/recompiler/tests/test-i386-shift.h b/src/recompiler/tests/test-i386-shift.h
index c1ed489f1..3d8f84bff 100644
--- a/src/recompiler/tests/test-i386-shift.h
+++ b/src/recompiler/tests/test-i386-shift.h
@@ -145,8 +145,7 @@ void exec_op(long s2, long s0, long s1)
#endif
exec_opl(s2, s0, s1, 0);
#ifdef OP_SHIFTD
- if (s1 <= 15)
- exec_opw(s2, s0, s1, 0);
+ exec_opw(s2, s0, s1, 0);
#else
exec_opw(s2, s0, s1, 0);
#endif
@@ -184,4 +183,3 @@ void *glue(_test_, OP) __init_call = glue(test_, OP);
#undef OP_SHIFTD
#undef OP_NOBYTE
#undef EXECSHIFT
-
diff --git a/src/recompiler/tests/test-i386-ssse3.c b/src/recompiler/tests/test-i386-ssse3.c
new file mode 100644
index 000000000..0a42bd03e
--- /dev/null
+++ b/src/recompiler/tests/test-i386-ssse3.c
@@ -0,0 +1,57 @@
+/* See if various MMX/SSE SSSE3 instructions give expected results */
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+int main(int argc, char *argv[]) {
+ char hello[16];
+ const char ehlo[8] = "EHLO ";
+ uint64_t mask = 0x8080800302020001;
+
+ uint64_t a = 0x0000000000090007;
+ uint64_t b = 0x0000000000000000;
+ uint32_t c;
+ uint16_t d;
+
+ const char e[16] = "LLOaaaaaaaaaaaaa";
+ const char f[16] = "aaaaaaaaaaaaaaHE";
+
+ /* pshufb mm1/xmm1, mm2/xmm2 */
+ asm volatile ("movq (%0), %%mm0" : : "r" (ehlo) : "mm0", "mm1");
+ asm volatile ("movq %0, %%mm1" : : "m" (mask));
+ asm volatile ("pshufb %mm1, %mm0");
+ asm volatile ("movq %%mm0, %0" : "=m" (hello));
+ printf("%s\n", hello);
+
+ /* pshufb mm1/xmm1, m64/m128 */
+ asm volatile ("movq (%0), %%mm0" : : "r" (ehlo) : "mm0");
+ asm volatile ("pshufb %0, %%mm0" : : "m" (mask));
+ asm volatile ("movq %%mm0, %0" : "=m" (hello));
+ printf("%s\n", hello);
+
+ /* psubsw mm1/xmm1, m64/m128 */
+ asm volatile ("movq %0, %%mm0" : : "r" (a) : "mm0");
+ asm volatile ("phsubsw %0, %%mm0" : : "m" (b));
+ asm volatile ("movq %%mm0, %0" : "=m" (a));
+ printf("%i - %i = %i\n", 9, 7, -(int16_t) a);
+
+ /* palignr mm1/xmm1, m64/m128, imm8 */
+ asm volatile ("movdqa (%0), %%xmm0" : : "r" (e) : "xmm0");
+ asm volatile ("palignr $14, (%0), %%xmm0" : : "r" (f));
+ asm volatile ("movdqa %%xmm0, (%0)" : : "r" (hello));
+ printf("%5.5s\n", hello);
+
+#if 1 /* SSE4 */
+ /* popcnt r64, r/m64 */
+ asm volatile ("movq $0x8421000010009c63, %%rax" : : : "rax");
+ asm volatile ("popcnt %%ax, %%dx" : : : "dx");
+ asm volatile ("popcnt %%eax, %%ecx" : : : "ecx");
+ asm volatile ("popcnt %rax, %rax");
+ asm volatile ("movq %%rax, %0" : "=m" (a));
+ asm volatile ("movl %%ecx, %0" : "=m" (c));
+ asm volatile ("movw %%dx, %0" : "=m" (d));
+ printf("%i = %i\n%i = %i = %i\n", 13, (int) a, 9, c, d + 1);
+#endif
+
+ return 0;
+}
diff --git a/src/recompiler/tests/test-i386-vm86.S b/src/recompiler/tests/test-i386-vm86.S
index a972f1b81..3bb96c992 100644
--- a/src/recompiler/tests/test-i386-vm86.S
+++ b/src/recompiler/tests/test-i386-vm86.S
@@ -14,7 +14,7 @@ vm86_code_start:
movw %ax, %es
es movw $GET_OFFSET(int90_test), 0x90 * 4
es movw %cs, 0x90 * 4 + 2
-
+
/* launch int 0x90 */
int $0x90
@@ -24,23 +24,23 @@ vm86_code_start:
movb $0x09, %ah
int $0x21
- pushf
+ pushf
popw %dx
movb $0xff, %ah
int $0x21
cli
- pushf
+ pushf
popw %dx
movb $0xff, %ah
int $0x21
- sti
- pushfl
+ sti
+ pushfl
popl %edx
movb $0xff, %ah
int $0x21
-
+
#if 0
movw $GET_OFFSET(IF_msg1), %dx
movb $0x09, %ah
@@ -54,11 +54,11 @@ vm86_code_start:
cli
#endif
- pushf
+ pushf
popw %dx
movb $0xff, %ah
int $0x21
-
+
pushfl
movw %sp, %bx
orw $0x200, (%bx)
@@ -73,7 +73,7 @@ vm86_code_start:
int $0x21
int90_test:
- pushf
+ pushf
pop %dx
movb $0xff, %ah
int $0x21
@@ -82,15 +82,15 @@ int90_test:
movw 4(%bx), %dx
movb $0xff, %ah
int $0x21
-
+
movw $GET_OFFSET(int90_msg), %dx
movb $0x09, %ah
int $0x21
iret
-
+
int90_msg:
.string "INT90 started\n$"
-
+
hello_world:
.string "Hello VM86 world\n$"
@@ -101,4 +101,3 @@ IF_msg1:
.string "If you see a diff here, your Linux kernel is buggy, please update to 2.4.20 kernel\n$"
vm86_code_end:
- \ No newline at end of file
diff --git a/src/recompiler/tests/test-i386.c b/src/recompiler/tests/test-i386.c
index 2fe56dab1..c8f21a957 100644
--- a/src/recompiler/tests/test-i386.c
+++ b/src/recompiler/tests/test-i386.c
@@ -1,6 +1,6 @@
/*
* x86 CPU test
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
@@ -14,8 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -40,19 +39,19 @@
#include <sys/mman.h>
#if !defined(__x86_64__)
-#define TEST_VM86
+//#define TEST_VM86
#define TEST_SEGS
#endif
//#define LINUX_VM86_IOPL_FIX
//#define TEST_P4_FLAGS
-#if defined(__x86_64__)
+#ifdef __SSE__
#define TEST_SSE
#define TEST_CMOV 1
#define TEST_FCOMI 1
#else
-//#define TEST_SSE
-#define TEST_CMOV 0
-#define TEST_FCOMI 0
+#undef TEST_SSE
+#define TEST_CMOV 1
+#define TEST_FCOMI 1
#endif
#if defined(__x86_64__)
@@ -467,6 +466,51 @@ void test_jcc(void)
TEST_JCC("ns", 0, 0);
}
+#define TEST_LOOP(insn) \
+{\
+ for(i = 0; i < sizeof(ecx_vals) / sizeof(long); i++) {\
+ ecx = ecx_vals[i];\
+ for(zf = 0; zf < 2; zf++) {\
+ asm("test %2, %2\n\t"\
+ "movl $1, %0\n\t"\
+ insn " 1f\n\t" \
+ "movl $0, %0\n\t"\
+ "1:\n\t"\
+ : "=a" (res)\
+ : "c" (ecx), "b" (!zf)); \
+ printf("%-10s ECX=" FMTLX " ZF=%ld r=%d\n", insn, ecx, zf, res); \
+ }\
+ }\
+}
+
+void test_loop(void)
+{
+ long ecx, zf;
+ const long ecx_vals[] = {
+ 0,
+ 1,
+ 0x10000,
+ 0x10001,
+#if defined(__x86_64__)
+ 0x100000000L,
+ 0x100000001L,
+#endif
+ };
+ int i, res;
+
+#if !defined(__x86_64__)
+ TEST_LOOP("jcxz");
+ TEST_LOOP("loopw");
+ TEST_LOOP("loopzw");
+ TEST_LOOP("loopnzw");
+#endif
+
+ TEST_LOOP("jecxz");
+ TEST_LOOP("loopl");
+ TEST_LOOP("loopzl");
+ TEST_LOOP("loopnzl");
+}
+
#undef CC_MASK
#ifdef TEST_P4_FLAGS
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
@@ -480,7 +524,7 @@ void test_jcc(void)
#define OP imul
#include "test-i386-muldiv.h"
-void test_imulw2(long op0, long op1)
+void test_imulw2(long op0, long op1)
{
long res, s1, s0, flags;
s0 = op0;
@@ -489,7 +533,7 @@ void test_imulw2(long op0, long op1)
flags = 0;
asm volatile ("push %4\n\t"
"popf\n\t"
- "imulw %w2, %w0\n\t"
+ "imulw %w2, %w0\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=q" (res), "=g" (flags)
@@ -498,7 +542,7 @@ void test_imulw2(long op0, long op1)
"imulw", s0, s1, res, flags & CC_MASK);
}
-void test_imull2(long op0, long op1)
+void test_imull2(long op0, long op1)
{
long res, s1, s0, flags;
s0 = op0;
@@ -507,7 +551,7 @@ void test_imull2(long op0, long op1)
flags = 0;
asm volatile ("push %4\n\t"
"popf\n\t"
- "imull %k2, %k0\n\t"
+ "imull %k2, %k0\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=q" (res), "=g" (flags)
@@ -517,7 +561,7 @@ void test_imull2(long op0, long op1)
}
#if defined(__x86_64__)
-void test_imulq2(long op0, long op1)
+void test_imulq2(long op0, long op1)
{
long res, s1, s0, flags;
s0 = op0;
@@ -526,7 +570,7 @@ void test_imulq2(long op0, long op1)
flags = 0;
asm volatile ("push %4\n\t"
"popf\n\t"
- "imulq %2, %0\n\t"
+ "imulq %2, %0\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=q" (res), "=g" (flags)
@@ -683,8 +727,8 @@ void test_mul(void)
asm("xor %1, %1\n"\
"mov $0x12345678, %0\n"\
#op " %" size "2, %" size "0 ; setz %b1" \
- : "=r" (res), "=q" (resz)\
- : "g" (val));\
+ : "=&r" (res), "=&q" (resz)\
+ : "r" (val));\
printf("%-10s A=" FMTLX " R=" FMTLX " %ld\n", #op, val, res, resz);\
}
@@ -713,8 +757,8 @@ union float64u {
uint64_t l;
};
-union float64u q_nan = { .l = 0xFFF8000000000000 };
-union float64u s_nan = { .l = 0xFFF0000000000000 };
+union float64u q_nan = { .l = 0xFFF8000000000000LL };
+union float64u s_nan = { .l = 0xFFF0000000000000LL };
void test_fops(double a, double b)
{
@@ -749,7 +793,7 @@ void fpu_clear_exceptions(void)
uint32_t ignored[4];
long double fpregs[8];
} float_env32;
-
+
asm volatile ("fnstenv %0\n" : : "m" (float_env32));
float_env32.fpus &= ~0x7f;
asm volatile ("fldenv %0\n" : : "m" (float_env32));
@@ -768,14 +812,14 @@ void test_fcmp(double a, double b)
"fstsw %%ax\n"
: "=a" (fpus)
: "t" (a), "u" (b));
- printf("fcom(%f %f)=%04lx \n",
+ printf("fcom(%f %f)=%04lx \n",
a, b, fpus & (0x4500 | FPUS_EMASK));
fpu_clear_exceptions();
asm("fucom %2\n"
"fstsw %%ax\n"
: "=a" (fpus)
: "t" (a), "u" (b));
- printf("fucom(%f %f)=%04lx\n",
+ printf("fucom(%f %f)=%04lx\n",
a, b, fpus & (0x4500 | FPUS_EMASK));
if (TEST_FCOMI) {
/* test f(u)comi instruction */
@@ -786,7 +830,7 @@ void test_fcmp(double a, double b)
"pop %0\n"
: "=r" (eflags), "=a" (fpus)
: "t" (a), "u" (b));
- printf("fcomi(%f %f)=%04lx %02lx\n",
+ printf("fcomi(%f %f)=%04lx %02lx\n",
a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));
fpu_clear_exceptions();
asm("fucomi %3, %2\n"
@@ -795,7 +839,7 @@ void test_fcmp(double a, double b)
"pop %0\n"
: "=r" (eflags), "=a" (fpus)
: "t" (a), "u" (b));
- printf("fucomi(%f %f)=%04lx %02lx\n",
+ printf("fucomi(%f %f)=%04lx %02lx\n",
a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));
}
fpu_clear_exceptions();
@@ -823,13 +867,15 @@ void test_fcvt(double a)
printf("(float)%f = %f\n", a, fa);
printf("(long double)%f = %Lf\n", a, la);
printf("a=" FMT64X "\n", *(uint64_t *)&a);
- printf("la=" FMT64X " %04x\n", *(uint64_t *)&la,
+ printf("la=" FMT64X " %04x\n", *(uint64_t *)&la,
*(unsigned short *)((char *)(&la) + 8));
/* test all roundings */
asm volatile ("fstcw %0" : "=m" (fpuc));
for(i=0;i<4;i++) {
- asm volatile ("fldcw %0" : : "m" ((fpuc & ~0x0c00) | (i << 10)));
+ uint16_t val16;
+ val16 = (fpuc & ~0x0c00) | (i << 10);
+ asm volatile ("fldcw %0" : : "m" (val16));
asm volatile ("fist %0" : "=m" (wa) : "t" (a));
asm volatile ("fistl %0" : "=m" (ia) : "t" (a));
asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st");
@@ -865,7 +911,7 @@ void test_fbcd(double a)
asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
- printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
+ printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
}
@@ -986,8 +1032,8 @@ void test_floats(void)
test_fcvt(1.0/0.0);
test_fcvt(q_nan.d);
test_fconst();
- test_fbcd(1234567890123456);
- test_fbcd(-123451234567890);
+ test_fbcd(1234567890123456.0);
+ test_fbcd(-123451234567890.0);
test_fenv();
if (TEST_CMOV) {
test_fcmov();
@@ -1051,7 +1097,7 @@ void test_bcd(void)
TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A));
TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A));
TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A));
-
+
TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A));
TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A));
TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A));
@@ -1073,7 +1119,7 @@ void test_bcd(void)
op1 = i2l(0xfbca7654);\
asm(#op " %" size "0, %" size "1" \
: "=q" (op0), opconst (op1) \
- : "0" (op0), "1" (op1));\
+ : "0" (op0));\
printf("%-10s A=" FMTLX " B=" FMTLX "\n",\
#op, op0, op1);\
}
@@ -1086,7 +1132,7 @@ void test_bcd(void)
op2 = i2l(eax);\
asm(#op " %" size "0, %" size "1" \
: "=q" (op0), opconst (op1) \
- : "0" (op0), "1" (op1), "a" (op2));\
+ : "0" (op0), "a" (op2));\
printf("%-10s EAX=" FMTLX " A=" FMTLX " C=" FMTLX "\n",\
#op, op2, op0, op1);\
}
@@ -1094,25 +1140,25 @@ void test_bcd(void)
void test_xchg(void)
{
#if defined(__x86_64__)
- TEST_XCHG(xchgq, "", "=q");
+ TEST_XCHG(xchgq, "", "+q");
#endif
- TEST_XCHG(xchgl, "k", "=q");
- TEST_XCHG(xchgw, "w", "=q");
- TEST_XCHG(xchgb, "b", "=q");
+ TEST_XCHG(xchgl, "k", "+q");
+ TEST_XCHG(xchgw, "w", "+q");
+ TEST_XCHG(xchgb, "b", "+q");
#if defined(__x86_64__)
TEST_XCHG(xchgq, "", "=m");
#endif
- TEST_XCHG(xchgl, "k", "=m");
- TEST_XCHG(xchgw, "w", "=m");
- TEST_XCHG(xchgb, "b", "=m");
+ TEST_XCHG(xchgl, "k", "+m");
+ TEST_XCHG(xchgw, "w", "+m");
+ TEST_XCHG(xchgb, "b", "+m");
#if defined(__x86_64__)
- TEST_XCHG(xaddq, "", "=q");
+ TEST_XCHG(xaddq, "", "+q");
#endif
- TEST_XCHG(xaddl, "k", "=q");
- TEST_XCHG(xaddw, "w", "=q");
- TEST_XCHG(xaddb, "b", "=q");
+ TEST_XCHG(xaddl, "k", "+q");
+ TEST_XCHG(xaddw, "w", "+q");
+ TEST_XCHG(xaddb, "b", "+q");
{
int res;
@@ -1122,58 +1168,61 @@ void test_xchg(void)
}
#if defined(__x86_64__)
- TEST_XCHG(xaddq, "", "=m");
+ TEST_XCHG(xaddq, "", "+m");
#endif
- TEST_XCHG(xaddl, "k", "=m");
- TEST_XCHG(xaddw, "w", "=m");
- TEST_XCHG(xaddb, "b", "=m");
+ TEST_XCHG(xaddl, "k", "+m");
+ TEST_XCHG(xaddw, "w", "+m");
+ TEST_XCHG(xaddb, "b", "+m");
#if defined(__x86_64__)
- TEST_CMPXCHG(cmpxchgq, "", "=q", 0xfbca7654);
+ TEST_CMPXCHG(cmpxchgq, "", "+q", 0xfbca7654);
#endif
- TEST_CMPXCHG(cmpxchgl, "k", "=q", 0xfbca7654);
- TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654);
- TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654);
+ TEST_CMPXCHG(cmpxchgl, "k", "+q", 0xfbca7654);
+ TEST_CMPXCHG(cmpxchgw, "w", "+q", 0xfbca7654);
+ TEST_CMPXCHG(cmpxchgb, "b", "+q", 0xfbca7654);
#if defined(__x86_64__)
- TEST_CMPXCHG(cmpxchgq, "", "=q", 0xfffefdfc);
+ TEST_CMPXCHG(cmpxchgq, "", "+q", 0xfffefdfc);
#endif
- TEST_CMPXCHG(cmpxchgl, "k", "=q", 0xfffefdfc);
- TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc);
- TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc);
+ TEST_CMPXCHG(cmpxchgl, "k", "+q", 0xfffefdfc);
+ TEST_CMPXCHG(cmpxchgw, "w", "+q", 0xfffefdfc);
+ TEST_CMPXCHG(cmpxchgb, "b", "+q", 0xfffefdfc);
#if defined(__x86_64__)
- TEST_CMPXCHG(cmpxchgq, "", "=m", 0xfbca7654);
+ TEST_CMPXCHG(cmpxchgq, "", "+m", 0xfbca7654);
#endif
- TEST_CMPXCHG(cmpxchgl, "k", "=m", 0xfbca7654);
- TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654);
- TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654);
+ TEST_CMPXCHG(cmpxchgl, "k", "+m", 0xfbca7654);
+ TEST_CMPXCHG(cmpxchgw, "w", "+m", 0xfbca7654);
+ TEST_CMPXCHG(cmpxchgb, "b", "+m", 0xfbca7654);
#if defined(__x86_64__)
- TEST_CMPXCHG(cmpxchgq, "", "=m", 0xfffefdfc);
+ TEST_CMPXCHG(cmpxchgq, "", "+m", 0xfffefdfc);
#endif
- TEST_CMPXCHG(cmpxchgl, "k", "=m", 0xfffefdfc);
- TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc);
- TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc);
+ TEST_CMPXCHG(cmpxchgl, "k", "+m", 0xfffefdfc);
+ TEST_CMPXCHG(cmpxchgw, "w", "+m", 0xfffefdfc);
+ TEST_CMPXCHG(cmpxchgb, "b", "+m", 0xfffefdfc);
{
uint64_t op0, op1, op2;
+ long eax, edx;
long i, eflags;
for(i = 0; i < 2; i++) {
- op0 = 0x123456789abcd;
+ op0 = 0x123456789abcdLL;
+ eax = i2l(op0 & 0xffffffff);
+ edx = i2l(op0 >> 32);
if (i == 0)
- op1 = 0xfbca765423456;
+ op1 = 0xfbca765423456LL;
else
op1 = op0;
- op2 = 0x6532432432434;
- asm("cmpxchg8b %1\n"
+ op2 = 0x6532432432434LL;
+ asm("cmpxchg8b %2\n"
"pushf\n"
- "pop %2\n"
- : "=A" (op0), "=m" (op1), "=g" (eflags)
- : "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32)));
- printf("cmpxchg8b: op0=" FMT64X " op1=" FMT64X " CC=%02lx\n",
- op0, op1, eflags & CC_Z);
+ "pop %3\n"
+ : "=a" (eax), "=d" (edx), "=m" (op1), "=g" (eflags)
+ : "0" (eax), "1" (edx), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32)));
+ printf("cmpxchg8b: eax=" FMTLX " edx=" FMTLX " op1=" FMT64X " CC=%02lx\n",
+ eax, edx, op1, eflags & CC_Z);
}
}
}
@@ -1182,11 +1231,15 @@ void test_xchg(void)
/**********************************************/
/* segmentation tests */
+#include <sys/syscall.h>
+#include <unistd.h>
#include <asm/ldt.h>
-#include <linux/unistd.h>
#include <linux/version.h>
-_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
+static inline int modify_ldt(int func, void * ptr, unsigned long bytecount)
+{
+ return syscall(__NR_modify_ldt, func, ptr, bytecount);
+}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
#define modify_ldt_ldt_s user_desc
@@ -1200,16 +1253,32 @@ uint8_t seg_data2[4096];
#define TEST_LR(op, size, seg, mask)\
{\
int res, res2;\
+ uint16_t mseg = seg;\
res = 0x12345678;\
asm (op " %" size "2, %" size "0\n" \
"movl $0, %1\n"\
"jnz 1f\n"\
"movl $1, %1\n"\
"1:\n"\
- : "=r" (res), "=r" (res2) : "m" (seg), "0" (res));\
+ : "=r" (res), "=r" (res2) : "m" (mseg), "0" (res));\
printf(op ": Z=%d %08x\n", res2, res & ~(mask));\
}
+#define TEST_ARPL(op, size, op1, op2)\
+{\
+ long a, b, c; \
+ a = (op1); \
+ b = (op2); \
+ asm volatile(op " %" size "3, %" size "0\n"\
+ "movl $0,%1\n"\
+ "jnz 1f\n"\
+ "movl $1,%1\n"\
+ "1:\n"\
+ : "=r" (a), "=r" (c) : "0" (a), "r" (b)); \
+ printf(op size " A=" FMTLX " B=" FMTLX " R=" FMTLX " z=%ld\n",\
+ (long)(op1), (long)(op2), a, c);\
+}
+
/* NOTE: we use Linux modify_ldt syscall */
void test_segs(void)
{
@@ -1286,9 +1355,9 @@ void test_segs(void)
segoff.seg = MK_SEL(2);
segoff.offset = 0xabcdef12;
- asm volatile("lfs %2, %0\n\t"
+ asm volatile("lfs %2, %0\n\t"
"movl %%fs, %1\n\t"
- : "=r" (res), "=g" (res2)
+ : "=r" (res), "=g" (res2)
: "m" (segoff));
printf("FS:reg = %04x:%08x\n", res2, res);
@@ -1301,6 +1370,10 @@ void test_segs(void)
TEST_LR("larl", "", 0xfff8, 0);
TEST_LR("lslw", "w", 0xfff8, 0);
TEST_LR("lsll", "", 0xfff8, 0);
+
+ TEST_ARPL("arpl", "w", 0x12345678 | 3, 0x762123c | 1);
+ TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 3);
+ TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 1);
}
/* 16 bit code test */
@@ -1327,15 +1400,15 @@ void test_code16(void)
modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
/* call the first function */
- asm volatile ("lcall %1, %2"
+ asm volatile ("lcall %1, %2"
: "=a" (res)
: "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc");
printf("func1() = 0x%08x\n", res);
- asm volatile ("lcall %2, %3"
+ asm volatile ("lcall %2, %3"
: "=a" (res), "=c" (res2)
: "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc");
printf("func2() = 0x%08x spdec=%d\n", res, res2);
- asm volatile ("lcall %1, %2"
+ asm volatile ("lcall %1, %2"
: "=a" (res)
: "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc");
printf("func3() = 0x%08x\n", res);
@@ -1373,9 +1446,13 @@ void test_misc(void)
printf("xlat: EAX=" FMTLX "\n", res);
#if defined(__x86_64__)
+#if 0
{
+ /* XXX: see if Intel Core2 and AMD64 behavior really
+ differ. Here we implemented the Intel way which is not
+ compatible yet with QEMU. */
static struct __attribute__((packed)) {
- uint32_t offset;
+ uint64_t offset;
uint16_t seg;
} desc;
long cs_sel;
@@ -1383,39 +1460,39 @@ void test_misc(void)
asm volatile ("mov %%cs, %0" : "=r" (cs_sel));
asm volatile ("push %1\n"
- "call func_lret\n"
+ "call func_lret\n"
: "=a" (res)
: "r" (cs_sel) : "memory", "cc");
printf("func_lret=" FMTLX "\n", res);
- /* NOTE: we assume that &func_lret < 4GB */
desc.offset = (long)&func_lret;
desc.seg = cs_sel;
-
+
asm volatile ("xor %%rax, %%rax\n"
- "rex64 lcall %1\n"
+ "rex64 lcall *(%%rcx)\n"
: "=a" (res)
- : "m" (desc)
+ : "c" (&desc)
: "memory", "cc");
printf("func_lret2=" FMTLX "\n", res);
asm volatile ("push %2\n"
"mov $ 1f, %%rax\n"
"push %%rax\n"
- "ljmp %1\n"
+ "rex64 ljmp *(%%rcx)\n"
"1:\n"
: "=a" (res)
- : "m" (desc), "b" (cs_sel)
+ : "c" (&desc), "b" (cs_sel)
: "memory", "cc");
printf("func_lret3=" FMTLX "\n", res);
}
+#endif
#else
- asm volatile ("push %%cs ; call %1"
+ asm volatile ("push %%cs ; call %1"
: "=a" (res)
: "m" (func_lret): "memory", "cc");
printf("func_lret=" FMTLX "\n", res);
- asm volatile ("pushf ; push %%cs ; call %1"
+ asm volatile ("pushf ; push %%cs ; call %1"
: "=a" (res)
: "m" (func_iret): "memory", "cc");
printf("func_iret=" FMTLX "\n", res);
@@ -1482,7 +1559,7 @@ void test_string(void)
TEST_STRING(stos, "");
TEST_STRING(stos, "rep ");
TEST_STRING(lods, ""); /* to verify stos */
- TEST_STRING(lods, "rep ");
+ TEST_STRING(lods, "rep ");
TEST_STRING(movs, "");
TEST_STRING(movs, "rep ");
TEST_STRING(lods, ""); /* to verify stos */
@@ -1515,13 +1592,10 @@ static inline void pushw(struct vm86_regs *r, int val)
*(uint16_t *)seg_to_linear(r->ss, r->esp) = val;
}
-#undef __syscall_return
-#define __syscall_return(type, res) \
-do { \
- return (type) (res); \
-} while (0)
-
-_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)
+static inline int vm86(int func, struct vm86plus_struct *v86)
+{
+ return syscall(__NR_vm86, func, v86);
+}
extern char vm86_code_start;
extern char vm86_code_end;
@@ -1536,8 +1610,8 @@ void test_vm86(void)
uint8_t *vm86_mem;
int seg, ret;
- vm86_mem = mmap((void *)0x00000000, 0x110000,
- PROT_WRITE | PROT_READ | PROT_EXEC,
+ vm86_mem = mmap((void *)0x00000000, 0x110000,
+ PROT_WRITE | PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
if (vm86_mem == MAP_FAILED) {
printf("ERROR: could not map vm86 memory");
@@ -1560,7 +1634,7 @@ void test_vm86(void)
/* move code to proper address. We use the same layout as a .com
dos program. */
- memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP,
+ memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP,
&vm86_code_start, &vm86_code_end - &vm86_code_start);
/* mark int 0x21 as being emulated */
@@ -1572,7 +1646,7 @@ void test_vm86(void)
case VM86_INTx:
{
int int_num, ah, v;
-
+
int_num = VM86_ARG(ret);
if (int_num != 0x21)
goto unknown_int;
@@ -1675,7 +1749,7 @@ void test_exceptions(void)
{
struct sigaction act;
volatile int val;
-
+
act.sa_sigaction = sig_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO | SA_NODEFER;
@@ -1728,7 +1802,7 @@ void test_exceptions(void)
ldt.seg_not_present = 1;
ldt.useable = 1;
modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
-
+
if (setjmp(jmp_env) == 0) {
/* segment not present */
asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
@@ -1753,7 +1827,7 @@ void test_exceptions(void)
/* read from an invalid address */
v1 = *(char *)0x1234;
}
-
+
/* test illegal instruction reporting */
printf("UD2 exception:\n");
if (setjmp(jmp_env) == 0) {
@@ -1765,7 +1839,7 @@ void test_exceptions(void)
/* now execute an invalid instruction */
asm volatile("lock nop");
}
-
+
printf("INT exception:\n");
if (setjmp(jmp_env) == 0) {
asm volatile ("int $0xfd");
@@ -1837,7 +1911,7 @@ void test_exceptions(void)
asm volatile ("pushf\n"
"orl $0x00100, (%%esp)\n"
"popf\n"
- "movl $0xabcd, %0\n"
+ "movl $0xabcd, %0\n"
"movl $0x0, %0\n" : "=m" (val) : : "cc", "memory");
}
printf("val=0x%x\n", val);
@@ -1868,7 +1942,7 @@ void test_single_step(void)
asm volatile ("pushf\n"
"orl $0x00100, (%%esp)\n"
"popf\n"
- "movl $0xabcd, %0\n"
+ "movl $0xabcd, %0\n"
/* jmp test */
"movl $3, %%ecx\n"
@@ -1894,13 +1968,13 @@ void test_single_step(void)
"rep cmpsb\n"
"movl $4, %%ecx\n"
"rep cmpsb\n"
-
+
/* getpid() syscall: single step should skip one
instruction */
"movl $20, %%eax\n"
"int $0x80\n"
"movl $0, %%eax\n"
-
+
/* when modifying SS, trace is not done on the next
instruction */
"movl %%ss, %%ecx\n"
@@ -1916,12 +1990,12 @@ void test_single_step(void)
"popl %%ss\n"
"addl $1, %0\n"
"movl $1, %%eax\n"
-
+
"pushf\n"
"andl $~0x00100, (%%esp)\n"
"popf\n"
- : "=m" (val)
- :
+ : "=m" (val)
+ :
: "cc", "memory", "eax", "ecx", "esi", "edi");
printf("val=%d\n", val);
for(i = 0; i < 4; i++)
@@ -1934,7 +2008,8 @@ uint8_t code[] = {
0xc3, /* ret */
};
-asm("smc_code2:\n"
+asm(".section \".data\"\n"
+ "smc_code2:\n"
"movl 4(%esp), %eax\n"
"movl %eax, smc_patch_addr2 + 1\n"
"nop\n"
@@ -1947,14 +2022,15 @@ asm("smc_code2:\n"
"nop\n"
"smc_patch_addr2:\n"
"movl $1, %eax\n"
- "ret\n");
+ "ret\n"
+ ".previous\n"
+ );
typedef int FuncType(void);
extern int smc_code2(int);
void test_self_modifying_code(void)
{
int i;
-
printf("self modifying code:\n");
printf("func1 = 0x%x\n", ((FuncType *)code)());
for(i = 2; i <= 4; i++) {
@@ -2036,7 +2112,7 @@ static void test_enter(void)
#ifdef TEST_SSE
typedef int __m64 __attribute__ ((__mode__ (__V2SI__)));
-typedef int __m128 __attribute__ ((__mode__(__V4SF__)));
+typedef float __m128 __attribute__ ((__mode__(__V4SF__)));
typedef union {
double d[2];
@@ -2210,11 +2286,12 @@ void test_sse_comi(double a1, double b1)
}
/* Force %xmm0 usage to avoid the case where both register index are 0
- to test instruction decoding more extensively */
+ to test intruction decoding more extensively */
#define CVT_OP_XMM2MMX(op)\
{\
asm volatile (#op " %1, %0" : "=y" (r.q[0]) : "x" (a.dq) \
- : "%xmm0");\
+ : "%xmm0"); \
+ asm volatile("emms\n"); \
printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "\n",\
#op,\
a.q[1], a.q[0],\
@@ -2224,6 +2301,7 @@ void test_sse_comi(double a1, double b1)
#define CVT_OP_MMX2XMM(op)\
{\
asm volatile (#op " %1, %0" : "=x" (r.dq) : "y" (a.q[0]));\
+ asm volatile("emms\n"); \
printf("%-9s: a=" FMT64X " r=" FMT64X "" FMT64X "\n",\
#op,\
a.q[0],\
@@ -2292,14 +2370,14 @@ void test_fxsave(void)
" fxrstor %0\n"
" fxsave %1\n"
" fninit\n"
- : "=m" (*(uint32_t *)fp2), "=m" (*(uint32_t *)fp)
+ : "=m" (*(uint32_t *)fp2), "=m" (*(uint32_t *)fp)
: "m" (a), "m" (b));
printf("fpuc=%04x\n", fp->fpuc);
printf("fpus=%04x\n", fp->fpus);
printf("fptag=%04x\n", fp->fptag);
for(i = 0; i < 3; i++) {
printf("ST%d: " FMT64X " %04x\n",
- i,
+ i,
*(uint64_t *)&fp->fpregs1[i * 16],
*(uint16_t *)&fp->fpregs1[i * 16 + 8]);
}
@@ -2311,7 +2389,7 @@ void test_fxsave(void)
#endif
for(i = 0; i < nb_xmm; i++) {
printf("xmm%d: " FMT64X "" FMT64X "\n",
- i,
+ i,
*(uint64_t *)&fp->xmm_regs[i * 16],
*(uint64_t *)&fp->xmm_regs[i * 16 + 8]);
}
@@ -2351,7 +2429,7 @@ void test_sse(void)
MMX_OP2(pmulhuw);
MMX_OP2(pmulhw);
-
+
MMX_OP2(psubsb);
MMX_OP2(psubsw);
MMX_OP2(pminsw);
@@ -2390,7 +2468,7 @@ void test_sse(void)
asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "y" (a.q[0]));
printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
-
+
asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "x" (a.dq));
printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
@@ -2402,21 +2480,21 @@ void test_sse(void)
a.q[1] = test_values[0][1];
b.q[0] = test_values[1][0];
b.q[1] = test_values[1][1];
- asm volatile("maskmovq %1, %0" :
+ asm volatile("maskmovq %1, %0" :
: "y" (a.q[0]), "y" (b.q[0]), "D" (&r)
- : "memory");
- printf("%-9s: r=" FMT64X " a=" FMT64X " b=" FMT64X "\n",
- "maskmov",
- r.q[0],
- a.q[0],
+ : "memory");
+ printf("%-9s: r=" FMT64X " a=" FMT64X " b=" FMT64X "\n",
+ "maskmov",
+ r.q[0],
+ a.q[0],
b.q[0]);
- asm volatile("maskmovdqu %1, %0" :
+ asm volatile("maskmovdqu %1, %0" :
: "x" (a.dq), "x" (b.dq), "D" (&r)
- : "memory");
- printf("%-9s: r=" FMT64X "" FMT64X " a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X "\n",
- "maskmov",
- r.q[1], r.q[0],
- a.q[1], a.q[0],
+ : "memory");
+ printf("%-9s: r=" FMT64X "" FMT64X " a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X "\n",
+ "maskmov",
+ r.q[1], r.q[0],
+ a.q[1], a.q[0],
b.q[1], b.q[0]);
}
@@ -2516,8 +2594,8 @@ void test_sse(void)
SSE_OPS(cmpnlt);
SSE_OPS(cmpnle);
SSE_OPS(cmpord);
-
-
+
+
a.d[0] = 2.7;
a.d[1] = -3.4;
b.d[0] = 45.7;
@@ -2593,6 +2671,56 @@ void test_sse(void)
#endif
+#define TEST_CONV_RAX(op)\
+{\
+ unsigned long a, r;\
+ a = i2l(0x8234a6f8);\
+ r = a;\
+ asm volatile(#op : "=a" (r) : "0" (r));\
+ printf("%-10s A=" FMTLX " R=" FMTLX "\n", #op, a, r);\
+}
+
+#define TEST_CONV_RAX_RDX(op)\
+{\
+ unsigned long a, d, r, rh; \
+ a = i2l(0x8234a6f8);\
+ d = i2l(0x8345a1f2);\
+ r = a;\
+ rh = d;\
+ asm volatile(#op : "=a" (r), "=d" (rh) : "0" (r), "1" (rh)); \
+ printf("%-10s A=" FMTLX " R=" FMTLX ":" FMTLX "\n", #op, a, r, rh); \
+}
+
+void test_conv(void)
+{
+ TEST_CONV_RAX(cbw);
+ TEST_CONV_RAX(cwde);
+#if defined(__x86_64__)
+ TEST_CONV_RAX(cdqe);
+#endif
+
+ TEST_CONV_RAX_RDX(cwd);
+ TEST_CONV_RAX_RDX(cdq);
+#if defined(__x86_64__)
+ TEST_CONV_RAX_RDX(cqo);
+#endif
+
+ {
+ unsigned long a, r;
+ a = i2l(0x12345678);
+ asm volatile("bswapl %k0" : "=r" (r) : "0" (a));
+ printf("%-10s: A=" FMTLX " R=" FMTLX "\n", "bswapl", a, r);
+ }
+#if defined(__x86_64__)
+ {
+ unsigned long a, r;
+ a = i2l(0x12345678);
+ asm volatile("bswapq %0" : "=r" (r) : "0" (a));
+ printf("%-10s: A=" FMTLX " R=" FMTLX "\n", "bswapq", a, r);
+ }
+#endif
+}
+
extern void *__start_initcall;
extern void *__stop_initcall;
@@ -2610,6 +2738,7 @@ int main(int argc, char **argv)
test_bsx();
test_mul();
test_jcc();
+ test_loop();
test_floats();
#if !defined(__x86_64__)
test_bcd();
@@ -2625,12 +2754,13 @@ int main(int argc, char **argv)
#ifdef TEST_VM86
test_vm86();
#endif
- test_exceptions();
#if !defined(__x86_64__)
+ test_exceptions();
test_self_modifying_code();
test_single_step();
#endif
test_enter();
+ test_conv();
#ifdef TEST_SSE
test_sse();
test_fxsave();
diff --git a/src/recompiler/tests/test-mmap.c b/src/recompiler/tests/test-mmap.c
new file mode 100644
index 000000000..5277421b6
--- /dev/null
+++ b/src/recompiler/tests/test-mmap.c
@@ -0,0 +1,485 @@
+/*
+ * Small test program to verify simulated mmap behaviour.
+ *
+ * When running qemu-linux-user with the -p flag, you may need to tell
+ * this test program about the pagesize because getpagesize() will not reflect
+ * the -p choice. Simply pass one argument beeing the pagesize.
+ *
+ * Copyright (c) 2007 AXIS Communications AB
+ * Written by Edgar E. Iglesias.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Oracle GPL 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 General Public License version 2 (GPLv2) at this time for any software where
+ * a choice of GPL license versions is made available with the language indicating
+ * that GPLv2 or any later version may be used, or where a choice of which version
+ * of the GPL is applied is otherwise unspecified.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+
+#define D(x)
+
+#define fail_unless(x) \
+do \
+{ \
+ if (!(x)) { \
+ fprintf (stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \
+ exit (EXIT_FAILURE); \
+ } \
+} while (0);
+
+unsigned char *dummybuf;
+static unsigned int pagesize;
+static unsigned int pagemask;
+int test_fd;
+size_t test_fsize;
+
+void check_aligned_anonymous_unfixed_mmaps(void)
+{
+ void *p1;
+ void *p2;
+ void *p3;
+ void *p4;
+ void *p5;
+ uintptr_t p;
+ int i;
+
+ fprintf (stderr, "%s", __func__);
+ for (i = 0; i < 0x1fff; i++)
+ {
+ size_t len;
+
+ len = pagesize + (pagesize * i & 7);
+ p1 = mmap(NULL, len, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ p2 = mmap(NULL, len, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ p3 = mmap(NULL, len, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ p4 = mmap(NULL, len, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ p5 = mmap(NULL, len, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ /* Make sure we get pages aligned with the pagesize. The
+ target expects this. */
+ fail_unless (p1 != MAP_FAILED);
+ fail_unless (p2 != MAP_FAILED);
+ fail_unless (p3 != MAP_FAILED);
+ fail_unless (p4 != MAP_FAILED);
+ fail_unless (p5 != MAP_FAILED);
+ p = (uintptr_t) p1;
+ D(printf ("p=%x\n", p));
+ fail_unless ((p & pagemask) == 0);
+ p = (uintptr_t) p2;
+ fail_unless ((p & pagemask) == 0);
+ p = (uintptr_t) p3;
+ fail_unless ((p & pagemask) == 0);
+ p = (uintptr_t) p4;
+ fail_unless ((p & pagemask) == 0);
+ p = (uintptr_t) p5;
+ fail_unless ((p & pagemask) == 0);
+
+ /* Make sure we can read from the entire area. */
+ memcpy (dummybuf, p1, pagesize);
+ memcpy (dummybuf, p2, pagesize);
+ memcpy (dummybuf, p3, pagesize);
+ memcpy (dummybuf, p4, pagesize);
+ memcpy (dummybuf, p5, pagesize);
+
+ munmap (p1, len);
+ munmap (p2, len);
+ munmap (p3, len);
+ munmap (p4, len);
+ munmap (p5, len);
+ }
+ fprintf (stderr, " passed\n");
+}
+
+void check_large_anonymous_unfixed_mmap(void)
+{
+ void *p1;
+ uintptr_t p;
+ size_t len;
+
+ fprintf (stderr, "%s", __func__);
+
+ len = 0x02000000;
+ p1 = mmap(NULL, len, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ /* Make sure we get pages aligned with the pagesize. The
+ target expects this. */
+ fail_unless (p1 != MAP_FAILED);
+ p = (uintptr_t) p1;
+ fail_unless ((p & pagemask) == 0);
+
+ /* Make sure we can read from the entire area. */
+ memcpy (dummybuf, p1, pagesize);
+ munmap (p1, len);
+ fprintf (stderr, " passed\n");
+}
+
+void check_aligned_anonymous_unfixed_colliding_mmaps(void)
+{
+ char *p1;
+ char *p2;
+ char *p3;
+ uintptr_t p;
+ int i;
+
+ fprintf (stderr, "%s", __func__);
+ for (i = 0; i < 0x2fff; i++)
+ {
+ int nlen;
+ p1 = mmap(NULL, pagesize, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ fail_unless (p1 != MAP_FAILED);
+ p = (uintptr_t) p1;
+ fail_unless ((p & pagemask) == 0);
+ memcpy (dummybuf, p1, pagesize);
+
+ p2 = mmap(NULL, pagesize, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ fail_unless (p2 != MAP_FAILED);
+ p = (uintptr_t) p2;
+ fail_unless ((p & pagemask) == 0);
+ memcpy (dummybuf, p2, pagesize);
+
+
+ munmap (p1, pagesize);
+ nlen = pagesize * 8;
+ p3 = mmap(NULL, nlen, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ /* Check if the mmaped areas collide. */
+ if (p3 < p2
+ && (p3 + nlen) > p2)
+ fail_unless (0);
+
+ memcpy (dummybuf, p3, pagesize);
+
+ /* Make sure we get pages aligned with the pagesize. The
+ target expects this. */
+ fail_unless (p3 != MAP_FAILED);
+ p = (uintptr_t) p3;
+ fail_unless ((p & pagemask) == 0);
+ munmap (p2, pagesize);
+ munmap (p3, nlen);
+ }
+ fprintf (stderr, " passed\n");
+}
+
+void check_aligned_anonymous_fixed_mmaps(void)
+{
+ char *addr;
+ void *p1;
+ uintptr_t p;
+ int i;
+
+ /* Find a suitable address to start with. */
+ addr = mmap(NULL, pagesize * 40, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1, 0);
+ fprintf (stderr, "%s addr=%p", __func__, addr);
+ fail_unless (addr != MAP_FAILED);
+
+ for (i = 0; i < 40; i++)
+ {
+ /* Create submaps within our unfixed map. */
+ p1 = mmap(addr, pagesize, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
+ -1, 0);
+ /* Make sure we get pages aligned with the pagesize.
+ The target expects this. */
+ p = (uintptr_t) p1;
+ fail_unless (p1 == addr);
+ fail_unless ((p & pagemask) == 0);
+ memcpy (dummybuf, p1, pagesize);
+ munmap (p1, pagesize);
+ addr += pagesize;
+ }
+ fprintf (stderr, " passed\n");
+}
+
+void check_aligned_anonymous_fixed_mmaps_collide_with_host(void)
+{
+ char *addr;
+ void *p1;
+ uintptr_t p;
+ int i;
+
+ /* Find a suitable address to start with. Right were the x86 hosts
+ stack is. */
+ addr = ((void *)0x80000000);
+ fprintf (stderr, "%s addr=%p", __func__, addr);
+ fprintf (stderr, "FIXME: QEMU fails to track pages used by the host.");
+
+ for (i = 0; i < 20; i++)
+ {
+ /* Create submaps within our unfixed map. */
+ p1 = mmap(addr, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
+ -1, 0);
+ /* Make sure we get pages aligned with the pagesize.
+ The target expects this. */
+ p = (uintptr_t) p1;
+ fail_unless (p1 == addr);
+ fail_unless ((p & pagemask) == 0);
+ memcpy (p1, dummybuf, pagesize);
+ munmap (p1, pagesize);
+ addr += pagesize;
+ }
+ fprintf (stderr, " passed\n");
+}
+
+void check_file_unfixed_mmaps(void)
+{
+ unsigned int *p1, *p2, *p3;
+ uintptr_t p;
+ int i;
+
+ fprintf (stderr, "%s", __func__);
+ for (i = 0; i < 0x10; i++)
+ {
+ size_t len;
+
+ len = pagesize;
+ p1 = mmap(NULL, len, PROT_READ,
+ MAP_PRIVATE,
+ test_fd, 0);
+ p2 = mmap(NULL, len, PROT_READ,
+ MAP_PRIVATE,
+ test_fd, pagesize);
+ p3 = mmap(NULL, len, PROT_READ,
+ MAP_PRIVATE,
+ test_fd, pagesize * 2);
+
+ fail_unless (p1 != MAP_FAILED);
+ fail_unless (p2 != MAP_FAILED);
+ fail_unless (p3 != MAP_FAILED);
+
+ /* Make sure we get pages aligned with the pagesize. The
+ target expects this. */
+ p = (uintptr_t) p1;
+ fail_unless ((p & pagemask) == 0);
+ p = (uintptr_t) p2;
+ fail_unless ((p & pagemask) == 0);
+ p = (uintptr_t) p3;
+ fail_unless ((p & pagemask) == 0);
+
+ /* Verify that the file maps was made correctly. */
+ D(printf ("p1=%d p2=%d p3=%d\n", *p1, *p2, *p3));
+ fail_unless (*p1 == 0);
+ fail_unless (*p2 == (pagesize / sizeof *p2));
+ fail_unless (*p3 == ((pagesize * 2) / sizeof *p3));
+
+ memcpy (dummybuf, p1, pagesize);
+ memcpy (dummybuf, p2, pagesize);
+ memcpy (dummybuf, p3, pagesize);
+ munmap (p1, len);
+ munmap (p2, len);
+ munmap (p3, len);
+ }
+ fprintf (stderr, " passed\n");
+}
+
+void check_file_unfixed_eof_mmaps(void)
+{
+ char *cp;
+ unsigned int *p1;
+ uintptr_t p;
+ int i;
+
+ fprintf (stderr, "%s", __func__);
+ for (i = 0; i < 0x10; i++)
+ {
+ p1 = mmap(NULL, pagesize, PROT_READ,
+ MAP_PRIVATE,
+ test_fd,
+ (test_fsize - sizeof *p1) & ~pagemask);
+
+ fail_unless (p1 != MAP_FAILED);
+
+ /* Make sure we get pages aligned with the pagesize. The
+ target expects this. */
+ p = (uintptr_t) p1;
+ fail_unless ((p & pagemask) == 0);
+ /* Verify that the file maps was made correctly. */
+ fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1]
+ == ((test_fsize - sizeof *p1) / sizeof *p1));
+
+ /* Verify that the end of page is accessable and zeroed. */
+ cp = (void *) p1;
+ fail_unless (cp[pagesize - 4] == 0);
+ munmap (p1, pagesize);
+ }
+ fprintf (stderr, " passed\n");
+}
+
+void check_file_fixed_eof_mmaps(void)
+{
+ char *addr;
+ char *cp;
+ unsigned int *p1;
+ uintptr_t p;
+ int i;
+
+ /* Find a suitable address to start with. */
+ addr = mmap(NULL, pagesize * 44, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1, 0);
+
+ fprintf (stderr, "%s addr=%p", __func__, (void *)addr);
+ fail_unless (addr != MAP_FAILED);
+
+ for (i = 0; i < 0x10; i++)
+ {
+ /* Create submaps within our unfixed map. */
+ p1 = mmap(addr, pagesize, PROT_READ,
+ MAP_PRIVATE | MAP_FIXED,
+ test_fd,
+ (test_fsize - sizeof *p1) & ~pagemask);
+
+ fail_unless (p1 != MAP_FAILED);
+
+ /* Make sure we get pages aligned with the pagesize. The
+ target expects this. */
+ p = (uintptr_t) p1;
+ fail_unless ((p & pagemask) == 0);
+
+ /* Verify that the file maps was made correctly. */
+ fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1]
+ == ((test_fsize - sizeof *p1) / sizeof *p1));
+
+ /* Verify that the end of page is accessable and zeroed. */
+ cp = (void *)p1;
+ fail_unless (cp[pagesize - 4] == 0);
+ munmap (p1, pagesize);
+ addr += pagesize;
+ }
+ fprintf (stderr, " passed\n");
+}
+
+void check_file_fixed_mmaps(void)
+{
+ unsigned char *addr;
+ unsigned int *p1, *p2, *p3, *p4;
+ int i;
+
+ /* Find a suitable address to start with. */
+ addr = mmap(NULL, pagesize * 40 * 4, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1, 0);
+ fprintf (stderr, "%s addr=%p", __func__, (void *)addr);
+ fail_unless (addr != MAP_FAILED);
+
+ for (i = 0; i < 40; i++)
+ {
+ p1 = mmap(addr, pagesize, PROT_READ,
+ MAP_PRIVATE | MAP_FIXED,
+ test_fd, 0);
+ p2 = mmap(addr + pagesize, pagesize, PROT_READ,
+ MAP_PRIVATE | MAP_FIXED,
+ test_fd, pagesize);
+ p3 = mmap(addr + pagesize * 2, pagesize, PROT_READ,
+ MAP_PRIVATE | MAP_FIXED,
+ test_fd, pagesize * 2);
+ p4 = mmap(addr + pagesize * 3, pagesize, PROT_READ,
+ MAP_PRIVATE | MAP_FIXED,
+ test_fd, pagesize * 3);
+
+ /* Make sure we get pages aligned with the pagesize.
+ The target expects this. */
+ fail_unless (p1 == (void *)addr);
+ fail_unless (p2 == (void *)addr + pagesize);
+ fail_unless (p3 == (void *)addr + pagesize * 2);
+ fail_unless (p4 == (void *)addr + pagesize * 3);
+
+ /* Verify that the file maps was made correctly. */
+ fail_unless (*p1 == 0);
+ fail_unless (*p2 == (pagesize / sizeof *p2));
+ fail_unless (*p3 == ((pagesize * 2) / sizeof *p3));
+ fail_unless (*p4 == ((pagesize * 3) / sizeof *p4));
+
+ memcpy (dummybuf, p1, pagesize);
+ memcpy (dummybuf, p2, pagesize);
+ memcpy (dummybuf, p3, pagesize);
+ memcpy (dummybuf, p4, pagesize);
+
+ munmap (p1, pagesize);
+ munmap (p2, pagesize);
+ munmap (p3, pagesize);
+ munmap (p4, pagesize);
+ addr += pagesize * 4;
+ }
+ fprintf (stderr, " passed\n");
+}
+
+int main(int argc, char **argv)
+{
+ char tempname[] = "/tmp/.cmmapXXXXXX";
+ unsigned int i;
+
+ /* Trust the first argument, otherwise probe the system for our
+ pagesize. */
+ if (argc > 1)
+ pagesize = strtoul(argv[1], NULL, 0);
+ else
+ pagesize = sysconf(_SC_PAGESIZE);
+
+ /* Assume pagesize is a power of two. */
+ pagemask = pagesize - 1;
+ dummybuf = malloc (pagesize);
+ printf ("pagesize=%u pagemask=%x\n", pagesize, pagemask);
+
+ test_fd = mkstemp(tempname);
+ unlink(tempname);
+
+ /* Fill the file with int's counting from zero and up. */
+ for (i = 0; i < (pagesize * 4) / sizeof i; i++)
+ write (test_fd, &i, sizeof i);
+ /* Append a few extra writes to make the file end at non
+ page boundary. */
+ write (test_fd, &i, sizeof i); i++;
+ write (test_fd, &i, sizeof i); i++;
+ write (test_fd, &i, sizeof i); i++;
+
+ test_fsize = lseek(test_fd, 0, SEEK_CUR);
+
+ /* Run the tests. */
+ check_aligned_anonymous_unfixed_mmaps();
+ check_aligned_anonymous_unfixed_colliding_mmaps();
+ check_aligned_anonymous_fixed_mmaps();
+ check_file_unfixed_mmaps();
+ check_file_fixed_mmaps();
+ check_file_fixed_eof_mmaps();
+ check_file_unfixed_eof_mmaps();
+
+ /* Fails at the moment. */
+ /* check_aligned_anonymous_fixed_mmaps_collide_with_host(); */
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/recompiler/tests/test_path.c b/src/recompiler/tests/test_path.c
index a9b52de37..def7441c8 100644
--- a/src/recompiler/tests/test_path.c
+++ b/src/recompiler/tests/test_path.c
@@ -149,4 +149,3 @@ int main(int argc, char *argv[])
}
return 0;
}
-
diff --git a/src/recompiler/translate-all.c b/src/recompiler/translate-all.c
index 308d468be..c1dbf50ae 100644
--- a/src/recompiler/translate-all.c
+++ b/src/recompiler/translate-all.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -31,6 +30,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <inttypes.h>
#include "config.h"
@@ -39,6 +39,7 @@
#include "exec-all.h"
#include "disas.h"
#include "tcg.h"
+#include "qemu-timer.h"
/* code generation context */
TCGContext tcg_ctx;
@@ -49,37 +50,8 @@ TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE];
target_ulong gen_opc_pc[OPC_BUF_SIZE];
uint16_t gen_opc_icount[OPC_BUF_SIZE];
uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
-#if defined(TARGET_I386)
-uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
-#elif defined(TARGET_SPARC)
-target_ulong gen_opc_npc[OPC_BUF_SIZE];
-target_ulong gen_opc_jump_pc[2];
-#elif defined(TARGET_MIPS)
-uint32_t gen_opc_hflags[OPC_BUF_SIZE];
-#endif
-
-/* XXX: suppress that */
-unsigned long code_gen_max_block_size(void)
-{
-#ifdef VBOX
- /* Just to suppress a lot of dummy warnings */
- static long max;
-#else
- static unsigned long max;
-#endif
-
- if (max == 0) {
- max = TCG_MAX_OP_SIZE;
-#define DEF(s, n, copy_size) max = (copy_size > max) ? copy_size : max;
-#include "tcg-opc.h"
-#undef DEF
- max *= OPC_MAX_SIZE;
- }
-
- return max;
-}
-void cpu_gen_init()
+void cpu_gen_init(void)
{
tcg_context_init(&tcg_ctx);
tcg_set_frame(&tcg_ctx, TCG_AREG0, offsetof(CPUState, temp_buf),
@@ -92,8 +64,7 @@ void cpu_gen_init()
'*gen_code_size_ptr' contains the size of the generated code (host
code).
*/
-int cpu_gen_code(CPUState *env, TranslationBlock *tb,
- int *gen_code_size_ptr)
+int cpu_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr)
{
TCGContext *s = &tcg_ctx;
uint8_t *gen_code_buf;
@@ -110,14 +81,11 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb,
#ifdef VBOX
RAWEx_ProfileStart(env, STATS_QEMU_COMPILATION);
- tcg_func_start(s);
+#endif
- gen_intermediate_code(env, tb);
-#else /* !VBOX */
tcg_func_start(s);
gen_intermediate_code(env, tb);
-#endif /* !VBOX */
/* generate machine code */
gen_code_buf = tb->tc_ptr;
@@ -127,9 +95,6 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb,
#ifdef USE_DIRECT_JUMP
s->tb_jmp_offset = tb->tb_jmp_offset;
s->tb_next = NULL;
- /* the following two entries are optional (only used for string ops) */
- tb->tb_jmp_offset[2] = 0xffff;
- tb->tb_jmp_offset[3] = 0xffff;
#else
s->tb_jmp_offset = NULL;
s->tb_next = tb->tb_next;
@@ -140,8 +105,7 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb,
s->interm_time += profile_getclock() - ti;
s->code_time -= profile_getclock();
#endif
-
- gen_code_size = dyngen_code(s, gen_code_buf);
+ gen_code_size = tcg_gen_code(s, gen_code_buf);
*gen_code_size_ptr = gen_code_size;
#ifdef CONFIG_PROFILER
s->code_time += profile_getclock();
@@ -154,11 +118,11 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb,
#endif
#ifdef DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_OUT_ASM) {
- fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
- disas(logfile, tb->tc_ptr, *gen_code_size_ptr);
- fprintf(logfile, "\n");
- fflush(logfile);
+ if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
+ qemu_log("OUT: [size=%d]\n", *gen_code_size_ptr);
+ log_disas(tb->tc_ptr, *gen_code_size_ptr);
+ qemu_log("\n");
+ qemu_log_flush();
}
#endif
return 0;
@@ -204,7 +168,7 @@ int cpu_restore_state(TranslationBlock *tb,
s->tb_jmp_offset = NULL;
s->tb_next = tb->tb_next;
#endif
- j = dyngen_code_search_pc(s, (uint8_t *)tc_ptr, searched_pc - tc_ptr);
+ j = tcg_gen_code_search_pc(s, (uint8_t *)tc_ptr, searched_pc - tc_ptr);
if (j < 0)
return -1;
/* now find start of instruction before */
diff --git a/src/recompiler/vl.h b/src/recompiler/vl.h
deleted file mode 100644
index 548c26a98..000000000
--- a/src/recompiler/vl.h
+++ /dev/null
@@ -1,1414 +0,0 @@
-/*
- * QEMU System Emulator header
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef VL_H
-#define VL_H
-
-/* we put basic includes here to avoid repeating them in device drivers */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#ifndef VBOX
-#include <inttypes.h>
-#include <limits.h>
-#include <time.h>
-#include <ctype.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include "audio/audio.h"
-#endif /* !VBOX */
-
-#ifndef O_LARGEFILE
-#define O_LARGEFILE 0
-#endif
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-#ifndef ENOMEDIUM
-#define ENOMEDIUM ENODEV
-#endif
-
-#ifdef _WIN32
-#ifndef VBOX
-#include <windows.h>
-#define fsync _commit
-#define lseek _lseeki64
-#define ENOTSUP 4096
-extern int qemu_ftruncate64(int, int64_t);
-#define ftruncate qemu_ftruncate64
-
-
-static inline char *realpath(const char *path, char *resolved_path)
-{
- _fullpath(resolved_path, path, _MAX_PATH);
- return resolved_path;
-}
-
-#define PRId64 "I64d"
-#define PRIx64 "I64x"
-#define PRIu64 "I64u"
-#define PRIo64 "I64o"
-#endif /* !VBOX */
-#endif
-
-#ifdef QEMU_TOOL
-
-/* we use QEMU_TOOL in the command line tools which do not depend on
- the target CPU type */
-#include "config-host.h"
-#include <setjmp.h>
-#include "osdep.h"
-#include "bswap.h"
-
-#else
-
-#ifndef VBOX
-#include "audio/audio.h"
-#endif /* !VBOX */
-#include "cpu.h"
-
-#endif /* !defined(QEMU_TOOL) */
-
-#ifdef VBOX
-# include <VBox/types.h>
-# include "REMInternal.h"
-#endif /* VBOX */
-
-#ifndef glue
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-#define stringify(s) tostring(s)
-#define tostring(s) #s
-#endif
-
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-
-/* cutils.c */
-void pstrcpy(char *buf, int buf_size, const char *str);
-char *pstrcat(char *buf, int buf_size, const char *s);
-int strstart(const char *str, const char *val, const char **ptr);
-int stristart(const char *str, const char *val, const char **ptr);
-
-/* vl.c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
-
-void hw_error(const char *fmt, ...);
-
-extern const char *bios_dir;
-
-extern int vm_running;
-
-typedef struct vm_change_state_entry VMChangeStateEntry;
-typedef void VMChangeStateHandler(void *opaque, int running);
-typedef void VMStopHandler(void *opaque, int reason);
-
-VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
- void *opaque);
-void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
-
-int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque);
-void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque);
-
-void vm_start(void);
-void vm_stop(int reason);
-
-typedef void QEMUResetHandler(void *opaque);
-
-void qemu_register_reset(QEMUResetHandler *func, void *opaque);
-void qemu_system_reset_request(void);
-void qemu_system_shutdown_request(void);
-void qemu_system_powerdown_request(void);
-#if !defined(TARGET_SPARC)
-// Please implement a power failure function to signal the OS
-#define qemu_system_powerdown() do{}while(0)
-#else
-void qemu_system_powerdown(void);
-#endif
-
-void main_loop_wait(int timeout);
-
-extern int ram_size;
-extern int bios_size;
-extern int rtc_utc;
-extern int cirrus_vga_enabled;
-extern int graphic_width;
-extern int graphic_height;
-extern int graphic_depth;
-extern const char *keyboard_layout;
-extern int kqemu_allowed;
-extern int win2k_install_hack;
-extern int usb_enabled;
-extern int smp_cpus;
-extern int no_quit;
-extern int semihosting_enabled;
-extern int autostart;
-
-#ifndef VBOX
-#define MAX_OPTION_ROMS 16
-extern const char *option_rom[MAX_OPTION_ROMS];
-extern int nb_option_roms;
-
-/* XXX: make it dynamic */
-#if defined (TARGET_PPC) || defined (TARGET_SPARC64)
-#define BIOS_SIZE ((512 + 32) * 1024)
-#elif defined(TARGET_MIPS)
-#define BIOS_SIZE (4 * 1024 * 1024)
-#else
-#define BIOS_SIZE ((256 + 64) * 1024)
-#endif
-
-/* keyboard/mouse support */
-
-#define MOUSE_EVENT_LBUTTON 0x01
-#define MOUSE_EVENT_RBUTTON 0x02
-#define MOUSE_EVENT_MBUTTON 0x04
-
-typedef void QEMUPutKBDEvent(void *opaque, int keycode);
-typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
-
-typedef struct QEMUPutMouseEntry {
- QEMUPutMouseEvent *qemu_put_mouse_event;
- void *qemu_put_mouse_event_opaque;
- int qemu_put_mouse_event_absolute;
- char *qemu_put_mouse_event_name;
-
- /* used internally by qemu for handling mice */
- struct QEMUPutMouseEntry *next;
-} QEMUPutMouseEntry;
-
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
-QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
- void *opaque, int absolute,
- const char *name);
-void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry);
-
-void kbd_put_keycode(int keycode);
-void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
-int kbd_mouse_is_absolute(void);
-
-void do_info_mice(void);
-void do_mouse_set(int index);
-
-/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
- constants) */
-#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
-#define QEMU_KEY_BACKSPACE 0x007f
-#define QEMU_KEY_UP QEMU_KEY_ESC1('A')
-#define QEMU_KEY_DOWN QEMU_KEY_ESC1('B')
-#define QEMU_KEY_RIGHT QEMU_KEY_ESC1('C')
-#define QEMU_KEY_LEFT QEMU_KEY_ESC1('D')
-#define QEMU_KEY_HOME QEMU_KEY_ESC1(1)
-#define QEMU_KEY_END QEMU_KEY_ESC1(4)
-#define QEMU_KEY_PAGEUP QEMU_KEY_ESC1(5)
-#define QEMU_KEY_PAGEDOWN QEMU_KEY_ESC1(6)
-#define QEMU_KEY_DELETE QEMU_KEY_ESC1(3)
-
-#define QEMU_KEY_CTRL_UP 0xe400
-#define QEMU_KEY_CTRL_DOWN 0xe401
-#define QEMU_KEY_CTRL_LEFT 0xe402
-#define QEMU_KEY_CTRL_RIGHT 0xe403
-#define QEMU_KEY_CTRL_HOME 0xe404
-#define QEMU_KEY_CTRL_END 0xe405
-#define QEMU_KEY_CTRL_PAGEUP 0xe406
-#define QEMU_KEY_CTRL_PAGEDOWN 0xe407
-
-void kbd_put_keysym(int keysym);
-
-/* async I/O support */
-
-typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
-typedef int IOCanRWHandler(void *opaque);
-typedef void IOHandler(void *opaque);
-
-int qemu_set_fd_handler2(int fd,
- IOCanRWHandler *fd_read_poll,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque);
-int qemu_set_fd_handler(int fd,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque);
-
-/* Polling handling */
-
-/* return TRUE if no sleep should be done afterwards */
-typedef int PollingFunc(void *opaque);
-
-int qemu_add_polling_cb(PollingFunc *func, void *opaque);
-void qemu_del_polling_cb(PollingFunc *func, void *opaque);
-
-#ifdef _WIN32
-/* Wait objects handling */
-typedef void WaitObjectFunc(void *opaque);
-
-int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
-void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
-#endif
-
-typedef struct QEMUBH QEMUBH;
-
-/* character device */
-
-#define CHR_EVENT_BREAK 0 /* serial break char */
-#define CHR_EVENT_FOCUS 1 /* focus to this terminal (modal input needed) */
-#define CHR_EVENT_RESET 2 /* new connection established */
-
-
-#define CHR_IOCTL_SERIAL_SET_PARAMS 1
-typedef struct {
- int speed;
- int parity;
- int data_bits;
- int stop_bits;
-} QEMUSerialSetParams;
-
-#define CHR_IOCTL_SERIAL_SET_BREAK 2
-
-#define CHR_IOCTL_PP_READ_DATA 3
-#define CHR_IOCTL_PP_WRITE_DATA 4
-#define CHR_IOCTL_PP_READ_CONTROL 5
-#define CHR_IOCTL_PP_WRITE_CONTROL 6
-#define CHR_IOCTL_PP_READ_STATUS 7
-
-typedef void IOEventHandler(void *opaque, int event);
-
-typedef struct CharDriverState {
- int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
- void (*chr_update_read_handler)(struct CharDriverState *s);
- int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
- IOEventHandler *chr_event;
- IOCanRWHandler *chr_can_read;
- IOReadHandler *chr_read;
- void *handler_opaque;
- void (*chr_send_event)(struct CharDriverState *chr, int event);
- void (*chr_close)(struct CharDriverState *chr);
- void *opaque;
- QEMUBH *bh;
-} CharDriverState;
-
-CharDriverState *qemu_chr_open(const char *filename);
-void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
-int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
-void qemu_chr_send_event(CharDriverState *s, int event);
-void qemu_chr_add_handlers(CharDriverState *s,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read,
- IOEventHandler *fd_event,
- void *opaque);
-int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
-void qemu_chr_reset(CharDriverState *s);
-int qemu_chr_can_read(CharDriverState *s);
-void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
-
-/* consoles */
-
-typedef struct DisplayState DisplayState;
-typedef struct TextConsole TextConsole;
-
-typedef void (*vga_hw_update_ptr)(void *);
-typedef void (*vga_hw_invalidate_ptr)(void *);
-typedef void (*vga_hw_screen_dump_ptr)(void *, const char *);
-
-TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update,
- vga_hw_invalidate_ptr invalidate,
- vga_hw_screen_dump_ptr screen_dump,
- void *opaque);
-void vga_hw_update(void);
-void vga_hw_invalidate(void);
-void vga_hw_screen_dump(const char *filename);
-
-int is_graphic_console(void);
-CharDriverState *text_console_init(DisplayState *ds);
-void console_select(unsigned int index);
-
-/* serial ports */
-
-#define MAX_SERIAL_PORTS 4
-
-extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
-
-/* parallel ports */
-
-#define MAX_PARALLEL_PORTS 3
-
-extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
-
-/* VLANs support */
-
-typedef struct VLANClientState VLANClientState;
-
-struct VLANClientState {
- IOReadHandler *fd_read;
- /* Packets may still be sent if this returns zero. It's used to
- rate-limit the slirp code. */
- IOCanRWHandler *fd_can_read;
- void *opaque;
- struct VLANClientState *next;
- struct VLANState *vlan;
- char info_str[256];
-};
-
-typedef struct VLANState {
- int id;
- VLANClientState *first_client;
- struct VLANState *next;
-} VLANState;
-
-VLANState *qemu_find_vlan(int id);
-VLANClientState *qemu_new_vlan_client(VLANState *vlan,
- IOReadHandler *fd_read,
- IOCanRWHandler *fd_can_read,
- void *opaque);
-int qemu_can_send_packet(VLANClientState *vc);
-void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
-void qemu_handler_true(void *opaque);
-
-void do_info_network(void);
-
-/* TAP win32 */
-int tap_win32_init(VLANState *vlan, const char *ifname);
-
-/* NIC info */
-
-#define MAX_NICS 8
-
-typedef struct NICInfo {
- uint8_t macaddr[6];
- const char *model;
- VLANState *vlan;
-} NICInfo;
-
-extern int nb_nics;
-extern NICInfo nd_table[MAX_NICS];
-
-/* timers */
-
-typedef struct QEMUClock QEMUClock;
-typedef struct QEMUTimer QEMUTimer;
-typedef void QEMUTimerCB(void *opaque);
-
-/* The real time clock should be used only for stuff which does not
- change the virtual machine state, as it is run even if the virtual
- machine is stopped. The real time clock has a frequency of 1000
- Hz. */
-extern QEMUClock *rt_clock;
-
-/* The virtual clock is only run during the emulation. It is stopped
- when the virtual machine is stopped. Virtual timers use a high
- precision clock, usually cpu cycles (use ticks_per_sec). */
-extern QEMUClock *vm_clock;
-
-int64_t qemu_get_clock(QEMUClock *clock);
-
-QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque);
-void qemu_free_timer(QEMUTimer *ts);
-void qemu_del_timer(QEMUTimer *ts);
-void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
-int qemu_timer_pending(QEMUTimer *ts);
-
-extern int64_t ticks_per_sec;
-extern int pit_min_timer_count;
-
-int64_t cpu_get_ticks(void);
-void cpu_enable_ticks(void);
-void cpu_disable_ticks(void);
-
-/* VM Load/Save */
-
-typedef struct QEMUFile QEMUFile;
-
-QEMUFile *qemu_fopen(const char *filename, const char *mode);
-void qemu_fflush(QEMUFile *f);
-void qemu_fclose(QEMUFile *f);
-void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
-void qemu_put_byte(QEMUFile *f, int v);
-void qemu_put_be16(QEMUFile *f, unsigned int v);
-void qemu_put_be32(QEMUFile *f, unsigned int v);
-void qemu_put_be64(QEMUFile *f, uint64_t v);
-int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
-int qemu_get_byte(QEMUFile *f);
-unsigned int qemu_get_be16(QEMUFile *f);
-unsigned int qemu_get_be32(QEMUFile *f);
-uint64_t qemu_get_be64(QEMUFile *f);
-
-static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
-{
- qemu_put_be64(f, *pv);
-}
-
-static inline void qemu_put_be32s(QEMUFile *f, const uint32_t *pv)
-{
- qemu_put_be32(f, *pv);
-}
-
-static inline void qemu_put_be16s(QEMUFile *f, const uint16_t *pv)
-{
- qemu_put_be16(f, *pv);
-}
-
-static inline void qemu_put_8s(QEMUFile *f, const uint8_t *pv)
-{
- qemu_put_byte(f, *pv);
-}
-
-static inline void qemu_get_be64s(QEMUFile *f, uint64_t *pv)
-{
- *pv = qemu_get_be64(f);
-}
-
-static inline void qemu_get_be32s(QEMUFile *f, uint32_t *pv)
-{
- *pv = qemu_get_be32(f);
-}
-
-static inline void qemu_get_be16s(QEMUFile *f, uint16_t *pv)
-{
- *pv = qemu_get_be16(f);
-}
-
-static inline void qemu_get_8s(QEMUFile *f, uint8_t *pv)
-{
- *pv = qemu_get_byte(f);
-}
-
-#if TARGET_LONG_BITS == 64
-#define qemu_put_betl qemu_put_be64
-#define qemu_get_betl qemu_get_be64
-#define qemu_put_betls qemu_put_be64s
-#define qemu_get_betls qemu_get_be64s
-#else
-#define qemu_put_betl qemu_put_be32
-#define qemu_get_betl qemu_get_be32
-#define qemu_put_betls qemu_put_be32s
-#define qemu_get_betls qemu_get_be32s
-#endif
-
-int64_t qemu_ftell(QEMUFile *f);
-int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence);
-
-typedef void SaveStateHandler(QEMUFile *f, void *opaque);
-typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
-
-int register_savevm(const char *idstr,
- int instance_id,
- int version_id,
- SaveStateHandler *save_state,
- LoadStateHandler *load_state,
- void *opaque);
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
-
-void cpu_save(QEMUFile *f, void *opaque);
-int cpu_load(QEMUFile *f, void *opaque, int version_id);
-
-void do_savevm(const char *name);
-void do_loadvm(const char *name);
-void do_delvm(const char *name);
-void do_info_snapshots(void);
-
-/* bottom halves */
-typedef void QEMUBHFunc(void *opaque);
-
-QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
-void qemu_bh_schedule(QEMUBH *bh);
-void qemu_bh_cancel(QEMUBH *bh);
-void qemu_bh_delete(QEMUBH *bh);
-int qemu_bh_poll(void);
-
-/* block.c */
-typedef struct BlockDriverState BlockDriverState;
-typedef struct BlockDriver BlockDriver;
-
-extern BlockDriver bdrv_raw;
-extern BlockDriver bdrv_host_device;
-extern BlockDriver bdrv_cow;
-extern BlockDriver bdrv_qcow;
-extern BlockDriver bdrv_vmdk;
-extern BlockDriver bdrv_cloop;
-extern BlockDriver bdrv_dmg;
-extern BlockDriver bdrv_bochs;
-extern BlockDriver bdrv_vpc;
-extern BlockDriver bdrv_vvfat;
-extern BlockDriver bdrv_qcow2;
-
-typedef struct BlockDriverInfo {
- /* in bytes, 0 if irrelevant */
- int cluster_size;
- /* offset at which the VM state can be saved (0 if not possible) */
- int64_t vm_state_offset;
-} BlockDriverInfo;
-
-typedef struct QEMUSnapshotInfo {
- char id_str[128]; /* unique snapshot id */
- /* the following fields are informative. They are not needed for
- the consistency of the snapshot */
- char name[256]; /* user chosen name */
- uint32_t vm_state_size; /* VM state info size */
- uint32_t date_sec; /* UTC date of the snapshot */
- uint32_t date_nsec;
- uint64_t vm_clock_nsec; /* VM clock relative to boot */
-} QEMUSnapshotInfo;
-
-#define BDRV_O_RDONLY 0x0000
-#define BDRV_O_RDWR 0x0002
-#define BDRV_O_ACCESS 0x0003
-#define BDRV_O_CREAT 0x0004 /* create an empty file */
-#define BDRV_O_SNAPSHOT 0x0008 /* open the file read only and save writes in a snapshot */
-#define BDRV_O_FILE 0x0010 /* open as a raw file (do not try to
- use a disk image format on top of
- it (default for
- bdrv_file_open()) */
-
-void bdrv_init(void);
-BlockDriver *bdrv_find_format(const char *format_name);
-int bdrv_create(BlockDriver *drv,
- const char *filename, int64_t size_in_sectors,
- const char *backing_file, int flags);
-BlockDriverState *bdrv_new(const char *device_name);
-void bdrv_delete(BlockDriverState *bs);
-int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
-int bdrv_open(BlockDriverState *bs, const char *filename, int flags);
-int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
- BlockDriver *drv);
-void bdrv_close(BlockDriverState *bs);
-int bdrv_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
-int bdrv_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-int bdrv_pread(BlockDriverState *bs, int64_t offset,
- void *buf, int count);
-int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
- const void *buf, int count);
-int bdrv_truncate(BlockDriverState *bs, int64_t offset);
-int64_t bdrv_getlength(BlockDriverState *bs);
-void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr);
-int bdrv_commit(BlockDriverState *bs);
-void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
-/* async block I/O */
-typedef struct BlockDriverAIOCB BlockDriverAIOCB;
-typedef void BlockDriverCompletionFunc(void *opaque, int ret);
-
-BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-void bdrv_aio_cancel(BlockDriverAIOCB *acb);
-
-void qemu_aio_init(void);
-void qemu_aio_poll(void);
-void qemu_aio_flush(void);
-void qemu_aio_wait_start(void);
-void qemu_aio_wait(void);
-void qemu_aio_wait_end(void);
-
-/* Ensure contents are flushed to disk. */
-void bdrv_flush(BlockDriverState *bs);
-
-#define BDRV_TYPE_HD 0
-#define BDRV_TYPE_CDROM 1
-#define BDRV_TYPE_FLOPPY 2
-#define BIOS_ATA_TRANSLATION_AUTO 0
-#define BIOS_ATA_TRANSLATION_NONE 1
-#define BIOS_ATA_TRANSLATION_LBA 2
-#define BIOS_ATA_TRANSLATION_LARGE 3
-#define BIOS_ATA_TRANSLATION_RECHS 4
-
-void bdrv_set_geometry_hint(BlockDriverState *bs,
- int cyls, int heads, int secs);
-void bdrv_set_type_hint(BlockDriverState *bs, int type);
-void bdrv_set_translation_hint(BlockDriverState *bs, int translation);
-void bdrv_get_geometry_hint(BlockDriverState *bs,
- int *pcyls, int *pheads, int *psecs);
-int bdrv_get_type_hint(BlockDriverState *bs);
-int bdrv_get_translation_hint(BlockDriverState *bs);
-int bdrv_is_removable(BlockDriverState *bs);
-int bdrv_is_read_only(BlockDriverState *bs);
-int bdrv_is_inserted(BlockDriverState *bs);
-int bdrv_media_changed(BlockDriverState *bs);
-int bdrv_is_locked(BlockDriverState *bs);
-void bdrv_set_locked(BlockDriverState *bs, int locked);
-void bdrv_eject(BlockDriverState *bs, int eject_flag);
-void bdrv_set_change_cb(BlockDriverState *bs,
- void (*change_cb)(void *opaque), void *opaque);
-void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
-void bdrv_info(void);
-BlockDriverState *bdrv_find(const char *name);
-void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque);
-int bdrv_is_encrypted(BlockDriverState *bs);
-int bdrv_set_key(BlockDriverState *bs, const char *key);
-void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
- void *opaque);
-const char *bdrv_get_device_name(BlockDriverState *bs);
-int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
-
-void bdrv_get_backing_filename(BlockDriverState *bs,
- char *filename, int filename_size);
-int bdrv_snapshot_create(BlockDriverState *bs,
- QEMUSnapshotInfo *sn_info);
-int bdrv_snapshot_goto(BlockDriverState *bs,
- const char *snapshot_id);
-int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
-int bdrv_snapshot_list(BlockDriverState *bs,
- QEMUSnapshotInfo **psn_info);
-char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
-
-char *get_human_readable_size(char *buf, int buf_size, int64_t size);
-int path_is_absolute(const char *path);
-void path_combine(char *dest, int dest_size,
- const char *base_path,
- const char *filename);
-
-#ifndef QEMU_TOOL
-
-typedef void QEMUMachineInitFunc(int ram_size, int vga_ram_size,
- int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename);
-
-typedef struct QEMUMachine {
- const char *name;
- const char *desc;
- QEMUMachineInitFunc *init;
- struct QEMUMachine *next;
-} QEMUMachine;
-
-int qemu_register_machine(QEMUMachine *m);
-
-typedef void SetIRQFunc(void *opaque, int irq_num, int level);
-typedef void IRQRequestFunc(void *opaque, int level);
-
-/* ISA bus */
-
-extern target_phys_addr_t isa_mem_base;
-
-typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
-typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
-
-int register_ioport_read(int start, int length, int size,
- IOPortReadFunc *func, void *opaque);
-int register_ioport_write(int start, int length, int size,
- IOPortWriteFunc *func, void *opaque);
-void isa_unassign_ioport(int start, int length);
-
-void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size);
-
-/* PCI bus */
-
-extern target_phys_addr_t pci_mem_base;
-
-typedef struct PCIBus PCIBus;
-typedef struct PCIDevice PCIDevice;
-
-typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
- uint32_t address, uint32_t data, int len);
-typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
- uint32_t address, int len);
-typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type);
-
-#define PCI_ADDRESS_SPACE_MEM 0x00
-#define PCI_ADDRESS_SPACE_IO 0x01
-#define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08
-
-typedef struct PCIIORegion {
- uint32_t addr; /* current PCI mapping address. -1 means not mapped */
- uint32_t size;
- uint8_t type;
- PCIMapIORegionFunc *map_func;
-} PCIIORegion;
-
-#define PCI_ROM_SLOT 6
-#define PCI_NUM_REGIONS 7
-
-#define PCI_DEVICES_MAX 64
-
-#define PCI_VENDOR_ID 0x00 /* 16 bits */
-#define PCI_DEVICE_ID 0x02 /* 16 bits */
-#define PCI_COMMAND 0x04 /* 16 bits */
-#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
-#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
-#define PCI_CLASS_DEVICE 0x0a /* Device class */
-#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
-#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
-#define PCI_MIN_GNT 0x3e /* 8 bits */
-#define PCI_MAX_LAT 0x3f /* 8 bits */
-
-struct PCIDevice {
- /* PCI config space */
- uint8_t config[256];
-
- /* the following fields are read only */
- PCIBus *bus;
- int devfn;
- char name[64];
- PCIIORegion io_regions[PCI_NUM_REGIONS];
-
- /* do not access the following fields */
- PCIConfigReadFunc *config_read;
- PCIConfigWriteFunc *config_write;
- /* ??? This is a PC-specific hack, and should be removed. */
- int irq_index;
-
- /* Current IRQ levels. Used internally by the generic PCI code. */
- int irq_state[4];
-};
-
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
- int instance_size, int devfn,
- PCIConfigReadFunc *config_read,
- PCIConfigWriteFunc *config_write);
-
-void pci_register_io_region(PCIDevice *pci_dev, int region_num,
- uint32_t size, int type,
- PCIMapIORegionFunc *map_func);
-
-void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level);
-
-uint32_t pci_default_read_config(PCIDevice *d,
- uint32_t address, int len);
-void pci_default_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len);
-void pci_device_save(PCIDevice *s, QEMUFile *f);
-int pci_device_load(PCIDevice *s, QEMUFile *f);
-
-typedef void (*pci_set_irq_fn)(void *pic, int irq_num, int level);
-typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
-PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- void *pic, int devfn_min, int nirq);
-
-void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len);
-uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
-int pci_bus_num(PCIBus *s);
-void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
-
-void pci_info(void);
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
- pci_map_irq_fn map_irq, const char *name);
-
-/* prep_pci.c */
-PCIBus *pci_prep_init(void);
-
-/* grackle_pci.c */
-PCIBus *pci_grackle_init(uint32_t base, void *pic);
-
-/* unin_pci.c */
-PCIBus *pci_pmac_init(void *pic);
-
-/* apb_pci.c */
-PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
- void *pic);
-
-PCIBus *pci_vpb_init(void *pic, int irq, int realview);
-
-/* piix_pci.c */
-PCIBus *i440fx_init(PCIDevice **pi440fx_state);
-void i440fx_set_smm(PCIDevice *d, int val);
-int piix3_init(PCIBus *bus, int devfn);
-void i440fx_init_memory_mappings(PCIDevice *d);
-
-int piix4_init(PCIBus *bus, int devfn);
-
-/* openpic.c */
-typedef struct openpic_t openpic_t;
-void openpic_set_irq(void *opaque, int n_IRQ, int level);
-openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
- CPUState **envp);
-
-/* heathrow_pic.c */
-typedef struct HeathrowPICS HeathrowPICS;
-void heathrow_pic_set_irq(void *opaque, int num, int level);
-HeathrowPICS *heathrow_pic_init(int *pmem_index);
-
-/* gt64xxx.c */
-PCIBus *pci_gt64120_init(void *pic);
-
-#ifdef HAS_AUDIO
-struct soundhw {
- const char *name;
- const char *descr;
- int enabled;
- int isa;
- union {
- int (*init_isa) (AudioState *s);
- int (*init_pci) (PCIBus *bus, AudioState *s);
- } init;
-};
-
-extern struct soundhw soundhw[];
-#endif
-
-/* vga.c */
-
-#define VGA_RAM_SIZE (8192 * 1024)
-
-struct DisplayState {
- uint8_t *data;
- int linesize;
- int depth;
- int bgr; /* BGR color order instead of RGB. Only valid for depth == 32 */
- int width;
- int height;
- void *opaque;
-
- void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
- void (*dpy_resize)(struct DisplayState *s, int w, int h);
- void (*dpy_refresh)(struct DisplayState *s);
- void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y, int dst_x, int dst_y, int w, int h);
-};
-
-static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
-{
- s->dpy_update(s, x, y, w, h);
-}
-
-static inline void dpy_resize(DisplayState *s, int w, int h)
-{
- s->dpy_resize(s, w, h);
-}
-
-int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size,
- unsigned long vga_bios_offset, int vga_bios_size);
-
-/* cirrus_vga.c */
-void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-
-/* sdl.c */
-void sdl_display_init(DisplayState *ds, int full_screen);
-
-/* cocoa.m */
-void cocoa_display_init(DisplayState *ds, int full_screen);
-
-/* vnc.c */
-void vnc_display_init(DisplayState *ds, const char *display);
-
-/* x_keymap.c */
-extern uint8_t _translate_keycode(const int key);
-
-/* ide.c */
-#define MAX_DISKS 4
-
-extern BlockDriverState *bs_table[MAX_DISKS + 1];
-
-void isa_ide_init(int iobase, int iobase2, int irq,
- BlockDriverState *hd0, BlockDriverState *hd1);
-void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
- int secondary_ide_enabled);
-void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn);
-int pmac_ide_init (BlockDriverState **hd_table,
- SetIRQFunc *set_irq, void *irq_opaque, int irq);
-
-/* cdrom.c */
-int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
-int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
-
-/* es1370.c */
-int es1370_init (PCIBus *bus, AudioState *s);
-
-/* sb16.c */
-int SB16_init (AudioState *s);
-
-/* adlib.c */
-int Adlib_init (AudioState *s);
-
-/* gus.c */
-int GUS_init (AudioState *s);
-
-/* dma.c */
-typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size);
-int DMA_get_channel_mode (int nchan);
-int DMA_read_memory (int nchan, void *buf, int pos, int size);
-int DMA_write_memory (int nchan, void *buf, int pos, int size);
-void DMA_hold_DREQ (int nchan);
-void DMA_release_DREQ (int nchan);
-void DMA_schedule(int nchan);
-void DMA_run (void);
-void DMA_init (int high_page_enable);
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque);
-/* fdc.c */
-#define MAX_FD 2
-extern BlockDriverState *fd_table[MAX_FD];
-
-typedef struct fdctrl_t fdctrl_t;
-
-fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
- uint32_t io_base,
- BlockDriverState **fds);
-int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num);
-
-/* ne2000.c */
-
-void isa_ne2000_init(int base, int irq, NICInfo *nd);
-void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* rtl8139.c */
-
-void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* pcnet.c */
-
-void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pcnet_h_reset(void *opaque);
-void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque);
-
-
-/* pckbd.c */
-
-void kbd_init(void);
-
-/* mc146818rtc.c */
-
-typedef struct RTCState RTCState;
-
-RTCState *rtc_init(int base, int irq);
-void rtc_set_memory(RTCState *s, int addr, int val);
-void rtc_set_date(RTCState *s, const struct tm *tm);
-
-/* serial.c */
-
-typedef struct SerialState SerialState;
-SerialState *serial_init(SetIRQFunc *set_irq, void *opaque,
- int base, int irq, CharDriverState *chr);
-SerialState *serial_mm_init (SetIRQFunc *set_irq, void *opaque,
- target_ulong base, int it_shift,
- int irq, CharDriverState *chr);
-
-/* parallel.c */
-
-typedef struct ParallelState ParallelState;
-ParallelState *parallel_init(int base, int irq, CharDriverState *chr);
-
-/* i8259.c */
-
-typedef struct PicState2 PicState2;
-extern PicState2 *isa_pic;
-void pic_set_irq(int irq, int level);
-void pic_set_irq_new(void *opaque, int irq, int level);
-PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque);
-void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
- void *alt_irq_opaque);
-int pic_read_irq(PicState2 *s);
-void pic_update_irq(PicState2 *s);
-uint32_t pic_intack_read(PicState2 *s);
-void pic_info(void);
-void irq_info(void);
-
-/* APIC */
-typedef struct IOAPICState IOAPICState;
-
-int apic_init(CPUState *env);
-int apic_get_interrupt(CPUState *env);
-IOAPICState *ioapic_init(void);
-void ioapic_set_irq(void *opaque, int vector, int level);
-
-/* i8254.c */
-
-#define PIT_FREQ 1193182
-
-typedef struct PITState PITState;
-
-PITState *pit_init(int base, int irq);
-void pit_set_gate(PITState *pit, int channel, int val);
-int pit_get_gate(PITState *pit, int channel);
-int pit_get_initial_count(PITState *pit, int channel);
-int pit_get_mode(PITState *pit, int channel);
-int pit_get_out(PITState *pit, int channel, int64_t current_time);
-
-/* pcspk.c */
-void pcspk_init(PITState *);
-int pcspk_audio_init(AudioState *);
-
-#include "hw/smbus.h"
-
-/* acpi.c */
-extern int acpi_enabled;
-void piix4_pm_init(PCIBus *bus, int devfn);
-void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
-void acpi_bios_init(void);
-
-/* smbus_eeprom.c */
-SMBusDevice *smbus_eeprom_device_init(uint8_t addr, uint8_t *buf);
-
-/* pc.c */
-extern QEMUMachine pc_machine;
-extern QEMUMachine isapc_machine;
-extern int fd_bootchk;
-
-void ioport_set_a20(int enable);
-int ioport_get_a20(void);
-
-/* ppc.c */
-extern QEMUMachine prep_machine;
-extern QEMUMachine core99_machine;
-extern QEMUMachine heathrow_machine;
-
-/* mips_r4k.c */
-extern QEMUMachine mips_machine;
-
-/* mips_malta.c */
-extern QEMUMachine mips_malta_machine;
-
-/* mips_int */
-extern void cpu_mips_irq_request(void *opaque, int irq, int level);
-
-/* mips_timer.c */
-extern void cpu_mips_clock_init(CPUState *);
-extern void cpu_mips_irqctrl_init (void);
-
-/* shix.c */
-extern QEMUMachine shix_machine;
-
-#ifdef TARGET_PPC
-ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq);
-#endif
-void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);
-
-extern CPUWriteMemoryFunc *PPC_io_write[];
-extern CPUReadMemoryFunc *PPC_io_read[];
-void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val);
-
-/* sun4m.c */
-extern QEMUMachine sun4m_machine;
-void pic_set_irq_cpu(int irq, int level, unsigned int cpu);
-
-/* iommu.c */
-void *iommu_init(uint32_t addr);
-void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int is_write);
-static inline void sparc_iommu_memory_read(void *opaque,
- target_phys_addr_t addr,
- uint8_t *buf, int len)
-{
- sparc_iommu_memory_rw(opaque, addr, buf, len, 0);
-}
-
-static inline void sparc_iommu_memory_write(void *opaque,
- target_phys_addr_t addr,
- uint8_t *buf, int len)
-{
- sparc_iommu_memory_rw(opaque, addr, buf, len, 1);
-}
-
-/* tcx.c */
-void tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
- unsigned long vram_offset, int vram_size, int width, int height);
-
-/* slavio_intctl.c */
-void *slavio_intctl_init();
-void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env);
-void slavio_pic_info(void *opaque);
-void slavio_irq_info(void *opaque);
-void slavio_pic_set_irq(void *opaque, int irq, int level);
-void slavio_pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu);
-
-/* loader.c */
-int get_image_size(const char *filename);
-int load_image(const char *filename, uint8_t *addr);
-int load_elf(const char *filename, int64_t virt_to_phys_addend, uint64_t *pentry);
-int load_aout(const char *filename, uint8_t *addr);
-
-/* slavio_timer.c */
-void slavio_timer_init(uint32_t addr, int irq, int mode, unsigned int cpu);
-
-/* slavio_serial.c */
-SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2);
-void slavio_serial_ms_kbd_init(int base, int irq);
-
-/* slavio_misc.c */
-void *slavio_misc_init(uint32_t base, int irq);
-void slavio_set_power_fail(void *opaque, int power_failing);
-
-/* esp.c */
-void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id);
-void *esp_init(BlockDriverState **bd, uint32_t espaddr, void *dma_opaque);
-void esp_reset(void *opaque);
-
-/* sparc32_dma.c */
-void *sparc32_dma_init(uint32_t daddr, int espirq, int leirq, void *iommu,
- void *intctl);
-void ledma_set_irq(void *opaque, int isr);
-void ledma_memory_read(void *opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int do_bswap);
-void ledma_memory_write(void *opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int do_bswap);
-void espdma_raise_irq(void *opaque);
-void espdma_clear_irq(void *opaque);
-void espdma_memory_read(void *opaque, uint8_t *buf, int len);
-void espdma_memory_write(void *opaque, uint8_t *buf, int len);
-void sparc32_dma_set_reset_data(void *opaque, void *esp_opaque,
- void *lance_opaque);
-
-/* cs4231.c */
-void cs_init(target_phys_addr_t base, int irq, void *intctl);
-
-/* sun4u.c */
-extern QEMUMachine sun4u_machine;
-
-/* NVRAM helpers */
-#include "hw/m48t59.h"
-
-void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value);
-uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr);
-void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value);
-uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr);
-void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value);
-uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr);
-void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
- const unsigned char *str, uint32_t max);
-int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max);
-void NVRAM_set_crc (m48t59_t *nvram, uint32_t addr,
- uint32_t start, uint32_t count);
-int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
- const unsigned char *arch,
- uint32_t RAM_size, int boot_device,
- uint32_t kernel_image, uint32_t kernel_size,
- const char *cmdline,
- uint32_t initrd_image, uint32_t initrd_size,
- uint32_t NVRAM_image,
- int width, int height, int depth);
-
-/* adb.c */
-
-#define MAX_ADB_DEVICES 16
-
-#define ADB_MAX_OUT_LEN 16
-
-typedef struct ADBDevice ADBDevice;
-
-/* buf = NULL means polling */
-typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out,
- const uint8_t *buf, int len);
-typedef int ADBDeviceReset(ADBDevice *d);
-
-struct ADBDevice {
- struct ADBBusState *bus;
- int devaddr;
- int handler;
- ADBDeviceRequest *devreq;
- ADBDeviceReset *devreset;
- void *opaque;
-};
-
-typedef struct ADBBusState {
- ADBDevice devices[MAX_ADB_DEVICES];
- int nb_devices;
- int poll_index;
-} ADBBusState;
-
-int adb_request(ADBBusState *s, uint8_t *buf_out,
- const uint8_t *buf, int len);
-int adb_poll(ADBBusState *s, uint8_t *buf_out);
-
-ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
- ADBDeviceRequest *devreq,
- ADBDeviceReset *devreset,
- void *opaque);
-void adb_kbd_init(ADBBusState *bus);
-void adb_mouse_init(ADBBusState *bus);
-
-/* cuda.c */
-
-extern ADBBusState adb_bus;
-int cuda_init(SetIRQFunc *set_irq, void *irq_opaque, int irq);
-
-#include "hw/usb.h"
-
-/* usb ports of the VM */
-
-void qemu_register_usb_port(USBPort *port, void *opaque, int index,
- usb_attachfn attach);
-
-#define VM_USB_HUB_SIZE 8
-
-void do_usb_add(const char *devname);
-void do_usb_del(const char *devname);
-void usb_info(void);
-
-/* scsi-disk.c */
-enum scsi_reason {
- SCSI_REASON_DONE, /* Command complete. */
- SCSI_REASON_DATA /* Transfer complete, more data required. */
-};
-
-typedef struct SCSIDevice SCSIDevice;
-typedef void (*scsi_completionfn)(void *opaque, int reason, uint32_t tag,
- uint32_t arg);
-
-SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
- int tcq,
- scsi_completionfn completion,
- void *opaque);
-void scsi_disk_destroy(SCSIDevice *s);
-
-int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun);
-/* SCSI data transfers are asynchronous. However, unlike the block IO
- layer the completion routine may be called directly by
- scsi_{read,write}_data. */
-void scsi_read_data(SCSIDevice *s, uint32_t tag);
-int scsi_write_data(SCSIDevice *s, uint32_t tag);
-void scsi_cancel_io(SCSIDevice *s, uint32_t tag);
-uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag);
-
-/* lsi53c895a.c */
-void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id);
-void *lsi_scsi_init(PCIBus *bus, int devfn);
-
-/* integratorcp.c */
-extern QEMUMachine integratorcp926_machine;
-extern QEMUMachine integratorcp1026_machine;
-
-/* versatilepb.c */
-extern QEMUMachine versatilepb_machine;
-extern QEMUMachine versatileab_machine;
-
-/* realview.c */
-extern QEMUMachine realview_machine;
-
-/* ps2.c */
-void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg);
-void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg);
-void ps2_write_mouse(void *, int val);
-void ps2_write_keyboard(void *, int val);
-uint32_t ps2_read_data(void *);
-void ps2_queue(void *, int b);
-void ps2_keyboard_set_translation(void *opaque, int mode);
-
-/* smc91c111.c */
-void smc91c111_init(NICInfo *, uint32_t, void *, int);
-
-/* pl110.c */
-void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq, int);
-
-/* pl011.c */
-void pl011_init(uint32_t base, void *pic, int irq, CharDriverState *chr);
-
-/* pl050.c */
-void pl050_init(uint32_t base, void *pic, int irq, int is_mouse);
-
-/* pl080.c */
-void *pl080_init(uint32_t base, void *pic, int irq, int nchannels);
-
-/* pl190.c */
-void *pl190_init(uint32_t base, void *parent, int irq, int fiq);
-
-/* arm-timer.c */
-void sp804_init(uint32_t base, void *pic, int irq);
-void icp_pit_init(uint32_t base, void *pic, int irq);
-
-/* arm_sysctl.c */
-void arm_sysctl_init(uint32_t base, uint32_t sys_id);
-
-/* arm_gic.c */
-void *arm_gic_init(uint32_t base, void *parent, int parent_irq);
-
-/* arm_boot.c */
-
-void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename,
- const char *kernel_cmdline, const char *initrd_filename,
- int board_id);
-
-/* sh7750.c */
-struct SH7750State;
-
-struct SH7750State *sh7750_init(CPUState * cpu);
-
-typedef struct {
- /* The callback will be triggered if any of the designated lines change */
- uint16_t portamask_trigger;
- uint16_t portbmask_trigger;
- /* Return 0 if no action was taken */
- int (*port_change_cb) (uint16_t porta, uint16_t portb,
- uint16_t * periph_pdtra,
- uint16_t * periph_portdira,
- uint16_t * periph_pdtrb,
- uint16_t * periph_portdirb);
-} sh7750_io_device;
-
-int sh7750_register_io_device(struct SH7750State *s,
- sh7750_io_device * device);
-/* tc58128.c */
-int tc58128_init(struct SH7750State *s, char *zone1, char *zone2);
-
-/* NOR flash devices */
-typedef struct pflash_t pflash_t;
-
-pflash_t *pflash_register (target_ulong base, ram_addr_t off,
- BlockDriverState *bs,
- target_ulong sector_len, int nb_blocs, int width,
- uint16_t id0, uint16_t id1,
- uint16_t id2, uint16_t id3);
-
-#include "gdbstub.h"
-
-#endif /* defined(QEMU_TOOL) */
-
-/* monitor.c */
-void monitor_init(CharDriverState *hd, int show_banner);
-void term_puts(const char *str);
-void term_vprintf(const char *fmt, va_list ap);
-void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
-void term_print_filename(const char *filename);
-void term_flush(void);
-void term_print_help(void);
-void monitor_readline(const char *prompt, int is_password,
- char *buf, int buf_size);
-
-/* readline.c */
-typedef void ReadLineFunc(void *opaque, const char *str);
-
-extern int completion_index;
-void add_completion(const char *str);
-void readline_handle_byte(int ch);
-void readline_find_completion(const char *cmdline);
-const char *readline_get_history(unsigned int index);
-void readline_start(const char *prompt, int is_password,
- ReadLineFunc *readline_func, void *opaque);
-
-void kqemu_record_dump(void);
-
-#endif /* !VBOX */
-
-#endif /* VL_H */
diff --git a/src/testcase/Makefile.kmk b/src/testcase/Makefile.kmk
index 128838a07..ea3b0a19d 100644
--- a/src/testcase/Makefile.kmk
+++ b/src/testcase/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Sub-Makefile for misc testcases.
#
diff --git a/src/testcase/tstRunTestcases.cpp b/src/testcase/tstRunTestcases.cpp
index 277b0a1ad..4168b45bd 100644
--- a/src/testcase/tstRunTestcases.cpp
+++ b/src/testcase/tstRunTestcases.cpp
@@ -1,4 +1,4 @@
-/* $Id: tstRunTestcases.cpp $ */
+/* $Id: tstRunTestcases.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* tstRunTestcases - Driver program for running VBox testcase (tst* testcase/tst*).
*/